UEsDBAoAAAgAAOc8qUoAAAAAAAAAAAAAAAAJAAQATUVUQS1JTkYv/soAAFBLAwQKAAAIAADnPKlK49umX0gAAABIAAAAFAAAAE1FVEEtSU5GL01BTklGRVNULk1GTWFuaWZlc3QtVmVyc2lvbjogMS4wDQpDcmVhdGVkLUJ5OiAxLjguMF8xMTItZ29vZ2xlLXY3IChHb29nbGUgSW5jLikNCg0KUEsDBAoAAAgAAAY7qUoAAAAAAAAAAAAAAAASAAAATUVUQS1JTkYvc2VydmljZXMvUEsDBAoAAAgAAAY7qUpnROdFMQAAADEAAAA/AAAATUVUQS1JTkYvc2VydmljZXMvY29tLnN1bi50b29scy5qYXZhYy5wbGF0Zm9ybS5QbGF0Zm9ybVByb3ZpZGVyY29tLnN1bi50b29scy5qYXZhYy5wbGF0Zm9ybS5KREtQbGF0Zm9ybVByb3ZpZGVyClBLAwQKAAAIAAAGO6lKxgEaAA8HAAAPBwAAEAAAAG1vZHVsZS1pbmZvLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTQsIDIwMTYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCiAvKioKICAqIERlZmluZXMgdGhlIExhbmd1YWdlIE1vZGVsLCBBbm5vdGF0aW9uIFByb2Nlc3NpbmcsIGFuZCBKYXZhIENvbXBpbGVyIEFQSXMuCiAgKiA8UD4KICAqIFRoZXNlIEFQSXMgbW9kZWwgZGVjbGFyYXRpb25zIGFuZCB0eXBlcyBvZiB0aGUgSmF2YSBwcm9ncmFtbWluZyBsYW5ndWFnZSwKICAqIGFuZCBkZWZpbmUgaW50ZXJmYWNlcyBmb3IgdG9vbHMgc3VjaCBhcyBjb21waWxlcnMgd2hpY2ggY2FuIGJlIGludm9rZWQKICAqIGZyb20gYSBwcm9ncmFtLgogICoKICAqIEBzaW5jZSA5CiAgKi8KbW9kdWxlIGphdmEuY29tcGlsZXIgewogICAgZXhwb3J0cyBqYXZheC5hbm5vdGF0aW9uLnByb2Nlc3Npbmc7CiAgICBleHBvcnRzIGphdmF4LmxhbmcubW9kZWw7CiAgICBleHBvcnRzIGphdmF4LmxhbmcubW9kZWwuZWxlbWVudDsKICAgIGV4cG9ydHMgamF2YXgubGFuZy5tb2RlbC50eXBlOwogICAgZXhwb3J0cyBqYXZheC5sYW5nLm1vZGVsLnV0aWw7CiAgICBleHBvcnRzIGphdmF4LnRvb2xzOwoKICAgIHVzZXMgamF2YXgudG9vbHMuRG9jdW1lbnRhdGlvblRvb2w7CiAgICB1c2VzIGphdmF4LnRvb2xzLkphdmFDb21waWxlcjsKfQoKUEsDBAoAAAgAAAY7qUoAAAAAAAAAAAAAAAAEAAAAamRrL1BLAwQKAAAIAAAGO6lKAAAAAAAAAAAAAAAADQAAAGpkay9pbnRlcm5hbC9QSwMECgAACAAABjupSgAAAAAAAAAAAAAAABoAAABqZGsvaW50ZXJuYWwvc2hlbGxzdXBwb3J0L1BLAwQKAAAIAAAGO6lKAAAAAAAAAAAAAAAAHgAAAGpkay9pbnRlcm5hbC9zaGVsbHN1cHBvcnQvZG9jL1BLAwQKAAAIAAAGO6lKAAAAAAAAAAAAAAAAKAAAAGpkay9pbnRlcm5hbC9zaGVsbHN1cHBvcnQvZG9jL3Jlc291cmNlcy9QSwMECgAACAAABjupSl9wwBwcBQAAHAUAAEMAAABqZGsvaW50ZXJuYWwvc2hlbGxzdXBwb3J0L2RvYy9yZXNvdXJjZXMvamF2YWRvY2Zvcm1hdHRlci5wcm9wZXJ0aWVzIwojIENvcHlyaWdodCAoYykgMjAxNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KIyBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiMKIyBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAojIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiMgcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAojIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgojCiMgVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiMgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiMgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiMgdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKIyBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgojCiMgWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgojIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKIyBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiMKIyBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQojIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKIyBxdWVzdGlvbnMuCiMKCkNBUF9UeXBlUGFyYW1ldGVycz1UeXBlIFBhcmFtZXRlcnM6CkNBUF9QYXJhbWV0ZXJzPVBhcmFtZXRlcnM6CkNBUF9SZXR1cm5zPVJldHVybnM6CkNBUF9UaHJvd25fRXhjZXB0aW9ucz1UaHJvd24gRXhjZXB0aW9uczoKUEsDBAoAAAgAAAY7qUryQKLFQIYAAECGAAAwAAAAamRrL2ludGVybmFsL3NoZWxsc3VwcG9ydC9kb2MvSmF2YWRvY0hlbHBlci5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDE2LCAyMDE3LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCnBhY2thZ2UgamRrLmludGVybmFsLnNoZWxsc3VwcG9ydC5kb2M7CgppbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKaW1wb3J0IGphdmEubmV0LlVSSTsKaW1wb3J0IGphdmEubmV0LlVSSVN5bnRheEV4Y2VwdGlvbjsKaW1wb3J0IGphdmEubmlvLmZpbGUuUGF0aDsKaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CmltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOwppbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb247CmltcG9ydCBqYXZhLnV0aWwuQ29tcGFyYXRvcjsKaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOwppbXBvcnQgamF2YS51dGlsLkhhc2hTZXQ7CmltcG9ydCBqYXZhLnV0aWwuSWRlbnRpdHlIYXNoTWFwOwppbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOwppbXBvcnQgamF2YS51dGlsLkxpc3Q7CmltcG9ydCBqYXZhLnV0aWwuTWFwOwppbXBvcnQgamF2YS51dGlsLk1hcC5FbnRyeTsKaW1wb3J0IGphdmEudXRpbC5PYmplY3RzOwppbXBvcnQgamF2YS51dGlsLlNldDsKaW1wb3J0IGphdmEudXRpbC5TdGFjazsKaW1wb3J0IGphdmEudXRpbC5UcmVlTWFwOwppbXBvcnQgamF2YS51dGlsLnN0cmVhbS5Db2xsZWN0b3JzOwppbXBvcnQgamF2YS51dGlsLnN0cmVhbS5TdHJlYW07CgppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5lbGVtZW50LkVsZW1lbnQ7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuRWxlbWVudEtpbmQ7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuRXhlY3V0YWJsZUVsZW1lbnQ7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuTW9kdWxlRWxlbWVudDsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC5UeXBlRWxlbWVudDsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC5WYXJpYWJsZUVsZW1lbnQ7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLnR5cGUuRGVjbGFyZWRUeXBlOwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC50eXBlLlR5cGVLaW5kOwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC50eXBlLlR5cGVNaXJyb3I7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLnV0aWwuRWxlbWVudEZpbHRlcjsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwudXRpbC5FbGVtZW50czsKaW1wb3J0IGphdmF4LnRvb2xzLkZvcndhcmRpbmdKYXZhRmlsZU1hbmFnZXI7CmltcG9ydCBqYXZheC50b29scy5KYXZhQ29tcGlsZXI7CmltcG9ydCBqYXZheC50b29scy5KYXZhRmlsZU1hbmFnZXI7CmltcG9ydCBqYXZheC50b29scy5KYXZhRmlsZU9iamVjdDsKaW1wb3J0IGphdmF4LnRvb2xzLlNpbXBsZUphdmFGaWxlT2JqZWN0OwppbXBvcnQgamF2YXgudG9vbHMuU3RhbmRhcmRKYXZhRmlsZU1hbmFnZXI7CmltcG9ydCBqYXZheC50b29scy5TdGFuZGFyZExvY2F0aW9uOwppbXBvcnQgamF2YXgudG9vbHMuVG9vbFByb3ZpZGVyOwoKaW1wb3J0IGNvbS5zdW4uc291cmNlLmRvY3RyZWUuRG9jQ29tbWVudFRyZWU7CmltcG9ydCBjb20uc3VuLnNvdXJjZS5kb2N0cmVlLkRvY1RyZWU7CmltcG9ydCBjb20uc3VuLnNvdXJjZS5kb2N0cmVlLkluaGVyaXREb2NUcmVlOwppbXBvcnQgY29tLnN1bi5zb3VyY2UuZG9jdHJlZS5QYXJhbVRyZWU7CmltcG9ydCBjb20uc3VuLnNvdXJjZS5kb2N0cmVlLlJldHVyblRyZWU7CmltcG9ydCBjb20uc3VuLnNvdXJjZS5kb2N0cmVlLlRocm93c1RyZWU7CmltcG9ydCBjb20uc3VuLnNvdXJjZS50cmVlLkNsYXNzVHJlZTsKaW1wb3J0IGNvbS5zdW4uc291cmNlLnRyZWUuQ29tcGlsYXRpb25Vbml0VHJlZTsKaW1wb3J0IGNvbS5zdW4uc291cmNlLnRyZWUuTWV0aG9kVHJlZTsKaW1wb3J0IGNvbS5zdW4uc291cmNlLnRyZWUuVmFyaWFibGVUcmVlOwppbXBvcnQgY29tLnN1bi5zb3VyY2UudXRpbC5Eb2NUcmVlUGF0aDsKaW1wb3J0IGNvbS5zdW4uc291cmNlLnV0aWwuRG9jVHJlZVNjYW5uZXI7CmltcG9ydCBjb20uc3VuLnNvdXJjZS51dGlsLkRvY1RyZWVzOwppbXBvcnQgY29tLnN1bi5zb3VyY2UudXRpbC5KYXZhY1Rhc2s7CmltcG9ydCBjb20uc3VuLnNvdXJjZS51dGlsLlRyZWVQYXRoOwppbXBvcnQgY29tLnN1bi5zb3VyY2UudXRpbC5UcmVlUGF0aFNjYW5uZXI7CmltcG9ydCBjb20uc3VuLnNvdXJjZS51dGlsLlRyZWVzOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5hcGkuSmF2YWNUYXNrSW1wbDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5EZWZpbmVkQnk7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuRGVmaW5lZEJ5LkFwaTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5QYWlyOwoKLyoqSGVscGVyIHRvIGZpbmQgamF2YWRvYyBhbmQgcmVzb2x2ZSBAaW5oZXJpdERvYy4KICovCnB1YmxpYyBhYnN0cmFjdCBjbGFzcyBKYXZhZG9jSGVscGVyIGltcGxlbWVudHMgQXV0b0Nsb3NlYWJsZSB7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBKYXZhQ29tcGlsZXIgY29tcGlsZXIgPSBUb29sUHJvdmlkZXIuZ2V0U3lzdGVtSmF2YUNvbXBpbGVyKCk7CgogICAgLyoqQ3JlYXRlIHRoZSBoZWxwZXIuCiAgICAgKgogICAgICogQHBhcmFtIG1haW5UYXNrIEphdmFjVGFzayBmcm9tIHdoaWNoIHRoZSBmdXJ0aGVyIEVsZW1lbnRzIG9yaWdpbmF0ZQogICAgICogQHBhcmFtIHNvdXJjZUxvY2F0aW9ucyBwYXRocyB3aGVyZSBzb3VyY2UgZmlsZXMgc2hvdWxkIGJlIHNlYXJjaGVkCiAgICAgKiBAcmV0dXJuIGEgSmF2YWRvY0hlbHBlcgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIEphdmFkb2NIZWxwZXIgY3JlYXRlKEphdmFjVGFzayBtYWluVGFzaywgQ29sbGVjdGlvbjw/IGV4dGVuZHMgUGF0aD4gc291cmNlTG9jYXRpb25zKSB7CiAgICAgICAgU3RhbmRhcmRKYXZhRmlsZU1hbmFnZXIgZm0gPSBjb21waWxlci5nZXRTdGFuZGFyZEZpbGVNYW5hZ2VyKG51bGwsIG51bGwsIG51bGwpOwogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGZtLnNldExvY2F0aW9uRnJvbVBhdGhzKFN0YW5kYXJkTG9jYXRpb24uU09VUkNFX1BBVEgsIHNvdXJjZUxvY2F0aW9ucyk7CiAgICAgICAgICAgIHJldHVybiBuZXcgT25EZW1hbmRKYXZhZG9jSGVscGVyKG1haW5UYXNrLCBmbSk7CiAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIGZtLmNsb3NlKCk7CiAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGNsb3NlRXgpIHsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gbmV3IEphdmFkb2NIZWxwZXIoKSB7CiAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0UmVzb2x2ZWREb2NDb21tZW50KEVsZW1lbnQgZm9yRWxlbWVudCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICAgICAgcHVibGljIEVsZW1lbnQgZ2V0U291cmNlRWxlbWVudChFbGVtZW50IGZvckVsZW1lbnQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZvckVsZW1lbnQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHt9CiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgfQoKICAgIC8qKlJldHVybnMgamF2YWRvYyBmb3IgdGhlIGdpdmVuIGVsZW1lbnQsIGlmIGl0IGNhbiBiZSBmb3VuZCwgb3IgbnVsbCBvdGhlcndpc2UuIFRoZSBqYXZhZG9jCiAgICAgKiB3aWxsIGhhdmUgQGluaGVyaXREb2MgcmVzb2x2ZWQuCiAgICAgKgogICAgICogQHBhcmFtIGZvckVsZW1lbnQgZWxlbWVudCBmb3Igd2hpY2ggdGhlIGphdmFkb2Mgc2hvdWxkIGJlIHNlYXJjaGVkCiAgICAgKiBAcmV0dXJuIGphdmFkb2MgaWYgZm91bmQsIG51bGwgb3RoZXJ3aXNlCiAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIHNvbWV0aGluZyBnb2VzIHdyb25nIGluIHRoZSBzZWFyY2gKICAgICAqLwogICAgcHVibGljIGFic3RyYWN0IFN0cmluZyBnZXRSZXNvbHZlZERvY0NvbW1lbnQoRWxlbWVudCBmb3JFbGVtZW50KSB0aHJvd3MgSU9FeGNlcHRpb247CgogICAgLyoqUmV0dXJucyBhbiBlbGVtZW50IHJlcHJlc2VudGluZyB0aGUgc2FtZSBnaXZlbiBwcm9ncmFtIGVsZW1lbnQsIGJ1dCB0aGUgcmV0dXJuZWQgZWxlbWVudCB3aWxsCiAgICAgKiBiZSByZXNvbHZlZCBmcm9tIHNvdXJjZSwgaWYgaXQgY2FuIGJlIGZvdW5kLiBSZXR1cm5zIHRoZSBvcmlnaW5hbCBlbGVtZW50IGlmIHRoZSBzb3VyY2UgZm9yCiAgICAgKiB0aGUgZ2l2ZW4gZWxlbWVudCBjYW5ub3QgYmUgZm91bmQuCiAgICAgKgogICAgICogQHBhcmFtIGZvckVsZW1lbnQgZWxlbWVudCBmb3Igd2hpY2ggdGhlIHNvdXJjZSBlbGVtZW50IHNob3VsZCBiZSBzZWFyY2hlZAogICAgICogQHJldHVybiBzb3VyY2UgZWxlbWVudCBpZiBmb3VuZCwgdGhlIG9yaWdpbmFsIGVsZW1lbnQgb3RoZXJ3aXNlCiAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIHNvbWV0aGluZyBnb2VzIHdyb25nIGluIHRoZSBzZWFyY2gKICAgICAqLwogICAgcHVibGljIGFic3RyYWN0IEVsZW1lbnQgZ2V0U291cmNlRWxlbWVudChFbGVtZW50IGZvckVsZW1lbnQpIHRocm93cyBJT0V4Y2VwdGlvbjsKCiAgICAvKipDbG9zZXMgdGhlIGhlbHBlci4KICAgICAqCiAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIHNvbWV0aGluZyBmb2VzIHdyb25nIGR1cmluZyB0aGUgY2xvc2UKICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbjsKCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBPbkRlbWFuZEphdmFkb2NIZWxwZXIgZXh0ZW5kcyBKYXZhZG9jSGVscGVyIHsKICAgICAgICBwcml2YXRlIGZpbmFsIEphdmFjVGFzayBtYWluVGFzazsKICAgICAgICBwcml2YXRlIGZpbmFsIEphdmFGaWxlTWFuYWdlciBiYXNlRmlsZU1hbmFnZXI7CiAgICAgICAgcHJpdmF0ZSBmaW5hbCBTdGFuZGFyZEphdmFGaWxlTWFuYWdlciBmbTsKICAgICAgICBwcml2YXRlIGZpbmFsIE1hcDxTdHJpbmcsIFBhaXI8SmF2YWNUYXNrLCBUcmVlUGF0aD4+IHNpZ25hdHVyZTJTb3VyY2UgPSBuZXcgSGFzaE1hcDw+KCk7CgogICAgICAgIHByaXZhdGUgT25EZW1hbmRKYXZhZG9jSGVscGVyKEphdmFjVGFzayBtYWluVGFzaywgU3RhbmRhcmRKYXZhRmlsZU1hbmFnZXIgZm0pIHsKICAgICAgICAgICAgdGhpcy5tYWluVGFzayA9IG1haW5UYXNrOwogICAgICAgICAgICB0aGlzLmJhc2VGaWxlTWFuYWdlciA9ICgoSmF2YWNUYXNrSW1wbCkgbWFpblRhc2spLmdldENvbnRleHQoKS5nZXQoSmF2YUZpbGVNYW5hZ2VyLmNsYXNzKTsKICAgICAgICAgICAgdGhpcy5mbSA9IGZtOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFN0cmluZyBnZXRSZXNvbHZlZERvY0NvbW1lbnQoRWxlbWVudCBmb3JFbGVtZW50KSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgICAgICBQYWlyPEphdmFjVGFzaywgVHJlZVBhdGg+IHNvdXJjZUVsZW1lbnQgPSBnZXRTb3VyY2VFbGVtZW50KG1haW5UYXNrLCBmb3JFbGVtZW50KTsKCiAgICAgICAgICAgIGlmIChzb3VyY2VFbGVtZW50ID09IG51bGwpCiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKCiAgICAgICAgICAgIHJldHVybiBnZXRSZXNvbHZlZERvY0NvbW1lbnQoc291cmNlRWxlbWVudC5mc3QsIHNvdXJjZUVsZW1lbnQuc25kKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBFbGVtZW50IGdldFNvdXJjZUVsZW1lbnQoRWxlbWVudCBmb3JFbGVtZW50KSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgICAgICBQYWlyPEphdmFjVGFzaywgVHJlZVBhdGg+IHNvdXJjZUVsZW1lbnQgPSBnZXRTb3VyY2VFbGVtZW50KG1haW5UYXNrLCBmb3JFbGVtZW50KTsKCiAgICAgICAgICAgIGlmIChzb3VyY2VFbGVtZW50ID09IG51bGwpCiAgICAgICAgICAgICAgICByZXR1cm4gZm9yRWxlbWVudDsKCiAgICAgICAgICAgIEVsZW1lbnQgcmVzdWx0ID0gVHJlZXMuaW5zdGFuY2Uoc291cmNlRWxlbWVudC5mc3QpLmdldEVsZW1lbnQoc291cmNlRWxlbWVudC5zbmQpOwoKICAgICAgICAgICAgaWYgKHJlc3VsdCA9PSBudWxsKQogICAgICAgICAgICAgICAgcmV0dXJuIGZvckVsZW1lbnQ7CgogICAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBTdHJpbmcgZ2V0UmVzb2x2ZWREb2NDb21tZW50KEphdmFjVGFzayB0YXNrLCBUcmVlUGF0aCBlbCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICAgICAgRG9jVHJlZXMgdHJlZXMgPSBEb2NUcmVlcy5pbnN0YW5jZSh0YXNrKTsKICAgICAgICAgICAgRWxlbWVudCBlbGVtZW50ID0gdHJlZXMuZ2V0RWxlbWVudChlbCk7CiAgICAgICAgICAgIFN0cmluZyBkb2NDb21tZW50ID0gdHJlZXMuZ2V0RG9jQ29tbWVudChlbCk7CgogICAgICAgICAgICBpZiAoZG9jQ29tbWVudCA9PSBudWxsICYmIGVsZW1lbnQuZ2V0S2luZCgpID09IEVsZW1lbnRLaW5kLk1FVEhPRCkgewogICAgICAgICAgICAgICAgRXhlY3V0YWJsZUVsZW1lbnQgZXhlY3V0YWJsZUVsZW1lbnQgPSAoRXhlY3V0YWJsZUVsZW1lbnQpIGVsZW1lbnQ7CiAgICAgICAgICAgICAgICBJdGVyYWJsZTxFbGVtZW50PiBzdXBlclR5cGVzID0KICAgICAgICAgICAgICAgICAgICAgICAgKCkgLT4gc3VwZXJUeXBlRm9ySW5oZXJpdERvYyh0YXNrLCBlbGVtZW50LmdldEVuY2xvc2luZ0VsZW1lbnQoKSkuaXRlcmF0b3IoKTsKICAgICAgICAgICAgICAgIGZvciAoRWxlbWVudCBzdXAgOiBzdXBlclR5cGVzKSB7CiAgICAgICAgICAgICAgICAgICBmb3IgKEV4ZWN1dGFibGVFbGVtZW50IHN1cE1ldGhvZCA6IEVsZW1lbnRGaWx0ZXIubWV0aG9kc0luKHN1cC5nZXRFbmNsb3NlZEVsZW1lbnRzKCkpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgVHlwZUVsZW1lbnQgY2xhenogPSAoVHlwZUVsZW1lbnQpIGV4ZWN1dGFibGVFbGVtZW50LmdldEVuY2xvc2luZ0VsZW1lbnQoKTsKICAgICAgICAgICAgICAgICAgICAgICBpZiAodGFzay5nZXRFbGVtZW50cygpLm92ZXJyaWRlcyhleGVjdXRhYmxlRWxlbWVudCwgc3VwTWV0aG9kLCBjbGF6eikpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgUGFpcjxKYXZhY1Rhc2ssIFRyZWVQYXRoPiBzb3VyY2UgPSBnZXRTb3VyY2VFbGVtZW50KHRhc2ssIHN1cE1ldGhvZCk7CgogICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc291cmNlICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBvdmVycmlkZGVuQ29tbWVudCA9IGdldFJlc29sdmVkRG9jQ29tbWVudChzb3VyY2UuZnN0LCBzb3VyY2Uuc25kKTsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAob3ZlcnJpZGRlbkNvbW1lbnQgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBvdmVycmlkZGVuQ29tbWVudDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgRG9jQ29tbWVudFRyZWUgZG9jQ29tbWVudFRyZWUgPSBwYXJzZURvY0NvbW1lbnQodGFzaywgZG9jQ29tbWVudCk7CiAgICAgICAgICAgIElPRXhjZXB0aW9uW10gZXhjZXB0aW9uID0gbmV3IElPRXhjZXB0aW9uWzFdOwogICAgICAgICAgICBNYXA8aW50W10sIFN0cmluZz4gcmVwbGFjZSA9IG5ldyBUcmVlTWFwPD4oKHNwYW4xLCBzcGFuMikgLT4gc3BhbjJbMF0gLSBzcGFuMVswXSk7CgogICAgICAgICAgICBuZXcgRG9jVHJlZVNjYW5uZXI8Vm9pZCwgVm9pZD4oKSB7CiAgICAgICAgICAgICAgICBwcml2YXRlIFN0YWNrPERvY1RyZWU+IGludGVyZXN0aW5nUGFyZW50ID0gbmV3IFN0YWNrPD4oKTsKICAgICAgICAgICAgICAgIHByaXZhdGUgRG9jQ29tbWVudFRyZWUgZGNUcmVlOwogICAgICAgICAgICAgICAgcHJpdmF0ZSBKYXZhY1Rhc2sgaW5oZXJpdGVkSmF2YWNUYXNrOwogICAgICAgICAgICAgICAgcHJpdmF0ZSBUcmVlUGF0aCBpbmhlcml0ZWRUcmVlUGF0aDsKICAgICAgICAgICAgICAgIHByaXZhdGUgU3RyaW5nIGluaGVyaXRlZDsKICAgICAgICAgICAgICAgIHByaXZhdGUgTWFwPERvY1RyZWUsIFN0cmluZz4gc3ludGhldGljVHJlZXMgPSBuZXcgSWRlbnRpdHlIYXNoTWFwPD4oKTsKICAgICAgICAgICAgICAgIHByaXZhdGUgbG9uZyBsYXN0UG9zID0gMDsKICAgICAgICAgICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgICAgICAgICAgcHVibGljIFZvaWQgdmlzaXREb2NDb21tZW50KERvY0NvbW1lbnRUcmVlIG5vZGUsIFZvaWQgcCkgewogICAgICAgICAgICAgICAgICAgIGRjVHJlZSA9IG5vZGU7CiAgICAgICAgICAgICAgICAgICAgaW50ZXJlc3RpbmdQYXJlbnQucHVzaChub2RlKTsKICAgICAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgICAgICBzY2FuKG5vZGUuZ2V0Rmlyc3RTZW50ZW5jZSgpLCBwKTsKICAgICAgICAgICAgICAgICAgICAgICAgc2Nhbihub2RlLmdldEJvZHkoKSwgcCk7CiAgICAgICAgICAgICAgICAgICAgICAgIExpc3Q8RG9jVHJlZT4gYXVnbWVudGVkQmxvY2tUYWdzID0gbmV3IEFycmF5TGlzdDw+KG5vZGUuZ2V0QmxvY2tUYWdzKCkpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoZWxlbWVudC5nZXRLaW5kKCkgPT0gRWxlbWVudEtpbmQuTUVUSE9EKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBFeGVjdXRhYmxlRWxlbWVudCBleGVjdXRhYmxlRWxlbWVudCA9IChFeGVjdXRhYmxlRWxlbWVudCkgZWxlbWVudDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIExpc3Q8U3RyaW5nPiBwYXJhbWV0ZXJzID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhlY3V0YWJsZUVsZW1lbnQuZ2V0UGFyYW1ldGVycygpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnN0cmVhbSgpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLm1hcChwYXJhbSAtPiBwYXJhbS5nZXRTaW1wbGVOYW1lKCkudG9TdHJpbmcoKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY29sbGVjdChDb2xsZWN0b3JzLnRvTGlzdCgpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIExpc3Q8U3RyaW5nPiB0aHJvd3NMaXN0ID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhlY3V0YWJsZUVsZW1lbnQuZ2V0VGhyb3duVHlwZXMoKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5zdHJlYW0oKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5tYXAoVHlwZU1pcnJvcjo6dG9TdHJpbmcpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmNvbGxlY3QoQ29sbGVjdG9ycy50b0xpc3QoKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBTZXQ8U3RyaW5nPiBtaXNzaW5nUGFyYW1zID0gbmV3IEhhc2hTZXQ8PihwYXJhbWV0ZXJzKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNldDxTdHJpbmc+IG1pc3NpbmdUaHJvd3MgPSBuZXcgSGFzaFNldDw+KHRocm93c0xpc3QpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBoYXNSZXR1cm4gPSBmYWxzZTsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKERvY1RyZWUgZHQgOiBhdWdtZW50ZWRCbG9ja1RhZ3MpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKGR0LmdldEtpbmQoKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFBBUkFNOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWlzc2luZ1BhcmFtcy5yZW1vdmUoKChQYXJhbVRyZWUpIGR0KS5nZXROYW1lKCkuZ2V0TmFtZSgpLnRvU3RyaW5nKCkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgVEhST1dTOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWlzc2luZ1Rocm93cy5yZW1vdmUoZ2V0VGhyb3duRXhjZXB0aW9uKHRhc2ssIGVsLCBkb2NDb21tZW50VHJlZSwgKFRocm93c1RyZWUpIGR0KSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBSRVRVUk46CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoYXNSZXR1cm4gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoU3RyaW5nIG1pc3NpbmdQYXJhbSA6IG1pc3NpbmdQYXJhbXMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEb2NUcmVlIHN5bnRoZXRpY1RhZyA9IHBhcnNlQmxvY2tUYWcodGFzaywgIkBwYXJhbSAiICsgbWlzc2luZ1BhcmFtICsgIiB7QGluaGVyaXREb2N9Iik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ludGhldGljVHJlZXMucHV0KHN5bnRoZXRpY1RhZywgIkBwYXJhbSAiICsgbWlzc2luZ1BhcmFtICsgIiAiKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnNlcnRUYWcoYXVnbWVudGVkQmxvY2tUYWdzLCBzeW50aGV0aWNUYWcsIHBhcmFtZXRlcnMsIHRocm93c0xpc3QpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoU3RyaW5nIG1pc3NpbmdUaHJvdyA6IG1pc3NpbmdUaHJvd3MpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEb2NUcmVlIHN5bnRoZXRpY1RhZyA9IHBhcnNlQmxvY2tUYWcodGFzaywgIkB0aHJvd3MgIiArIG1pc3NpbmdUaHJvdyArICIge0Bpbmhlcml0RG9jfSIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5bnRoZXRpY1RyZWVzLnB1dChzeW50aGV0aWNUYWcsICJAdGhyb3dzICIgKyBtaXNzaW5nVGhyb3cgKyAiICIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluc2VydFRhZyhhdWdtZW50ZWRCbG9ja1RhZ3MsIHN5bnRoZXRpY1RhZywgcGFyYW1ldGVycywgdGhyb3dzTGlzdCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFoYXNSZXR1cm4pIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEb2NUcmVlIHN5bnRoZXRpY1RhZyA9IHBhcnNlQmxvY2tUYWcodGFzaywgIkByZXR1cm4ge0Bpbmhlcml0RG9jfSIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5bnRoZXRpY1RyZWVzLnB1dChzeW50aGV0aWNUYWcsICJAcmV0dXJuICIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluc2VydFRhZyhhdWdtZW50ZWRCbG9ja1RhZ3MsIHN5bnRoZXRpY1RhZywgcGFyYW1ldGVycywgdGhyb3dzTGlzdCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgc2NhbihhdWdtZW50ZWRCbG9ja1RhZ3MsIHApOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAgICAgICAgICAgICBpbnRlcmVzdGluZ1BhcmVudC5wb3AoKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICAgICAgICAgIHB1YmxpYyBWb2lkIHZpc2l0UGFyYW0oUGFyYW1UcmVlIG5vZGUsIFZvaWQgcCkgewogICAgICAgICAgICAgICAgICAgIGludGVyZXN0aW5nUGFyZW50LnB1c2gobm9kZSk7CiAgICAgICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHN1cGVyLnZpc2l0UGFyYW0obm9kZSwgcCk7CiAgICAgICAgICAgICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgICAgICAgICAgICAgaW50ZXJlc3RpbmdQYXJlbnQucG9wKCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgICAgICAgICBwdWJsaWMgVm9pZCB2aXNpdFRocm93cyhUaHJvd3NUcmVlIG5vZGUsIFZvaWQgcCkgewogICAgICAgICAgICAgICAgICAgIGludGVyZXN0aW5nUGFyZW50LnB1c2gobm9kZSk7CiAgICAgICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHN1cGVyLnZpc2l0VGhyb3dzKG5vZGUsIHApOwogICAgICAgICAgICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGludGVyZXN0aW5nUGFyZW50LnBvcCgpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgICAgICAgICAgcHVibGljIFZvaWQgdmlzaXRSZXR1cm4oUmV0dXJuVHJlZSBub2RlLCBWb2lkIHApIHsKICAgICAgICAgICAgICAgICAgICBpbnRlcmVzdGluZ1BhcmVudC5wdXNoKG5vZGUpOwogICAgICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzdXBlci52aXNpdFJldHVybihub2RlLCBwKTsKICAgICAgICAgICAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAgICAgICAgICAgICBpbnRlcmVzdGluZ1BhcmVudC5wb3AoKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICAgICAgICAgIHB1YmxpYyBWb2lkIHZpc2l0SW5oZXJpdERvYyhJbmhlcml0RG9jVHJlZSBub2RlLCBWb2lkIHApIHsKICAgICAgICAgICAgICAgICAgICBpZiAoaW5oZXJpdGVkID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlbGVtZW50LmdldEtpbmQoKSA9PSBFbGVtZW50S2luZC5NRVRIT0QpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFeGVjdXRhYmxlRWxlbWVudCBleGVjdXRhYmxlRWxlbWVudCA9IChFeGVjdXRhYmxlRWxlbWVudCkgZWxlbWVudDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJdGVyYWJsZTxFbGVtZW50PiBzdXBlclR5cGVzID0gKCkgLT4gc3VwZXJUeXBlRm9ySW5oZXJpdERvYyh0YXNrLCBlbGVtZW50LmdldEVuY2xvc2luZ0VsZW1lbnQoKSkuaXRlcmF0b3IoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPVVRFUjogZm9yIChFbGVtZW50IHN1cCA6IHN1cGVyVHlwZXMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKEV4ZWN1dGFibGVFbGVtZW50IHN1cE1ldGhvZCA6IEVsZW1lbnRGaWx0ZXIubWV0aG9kc0luKHN1cC5nZXRFbmNsb3NlZEVsZW1lbnRzKCkpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0YXNrLmdldEVsZW1lbnRzKCkub3ZlcnJpZGVzKGV4ZWN1dGFibGVFbGVtZW50LCBzdXBNZXRob2QsIChUeXBlRWxlbWVudCkgZXhlY3V0YWJsZUVsZW1lbnQuZ2V0RW5jbG9zaW5nRWxlbWVudCgpKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUGFpcjxKYXZhY1Rhc2ssIFRyZWVQYXRoPiBzb3VyY2UgPSBnZXRTb3VyY2VFbGVtZW50KHRhc2ssIHN1cE1ldGhvZCk7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNvdXJjZSAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG92ZXJyaWRkZW5Db21tZW50ID0gZ2V0UmVzb2x2ZWREb2NDb21tZW50KHNvdXJjZS5mc3QsIHNvdXJjZS5zbmQpOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAob3ZlcnJpZGRlbkNvbW1lbnQgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmhlcml0ZWRKYXZhY1Rhc2sgPSBzb3VyY2UuZnN0OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmhlcml0ZWRUcmVlUGF0aCA9IHNvdXJjZS5zbmQ7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluaGVyaXRlZCA9IG92ZXJyaWRkZW5Db21tZW50OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhayBPVVRFUjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhjZXB0aW9uWzBdID0gZXg7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoaW5oZXJpdGVkID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIERvY0NvbW1lbnRUcmVlIGluaGVyaXRlZERvY1RyZWUgPSBwYXJzZURvY0NvbW1lbnQoaW5oZXJpdGVkSmF2YWNUYXNrLCBpbmhlcml0ZWQpOwogICAgICAgICAgICAgICAgICAgIExpc3Q8TGlzdDw/IGV4dGVuZHMgRG9jVHJlZT4+IGluaGVyaXRlZFRleHQgPSBuZXcgQXJyYXlMaXN0PD4oKTsKICAgICAgICAgICAgICAgICAgICBEb2NUcmVlIHBhcmVudCA9IGludGVyZXN0aW5nUGFyZW50LnBlZWsoKTsKICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKHBhcmVudC5nZXRLaW5kKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBET0NfQ09NTUVOVDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluaGVyaXRlZFRleHQuYWRkKGluaGVyaXRlZERvY1RyZWUuZ2V0RnVsbEJvZHkoKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBQQVJBTToKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBwYXJhbU5hbWUgPSAoKFBhcmFtVHJlZSkgcGFyZW50KS5nZXROYW1lKCkuZ2V0TmFtZSgpLnRvU3RyaW5nKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgRG9jVHJlZVNjYW5uZXI8Vm9pZCwgVm9pZD4oKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHVibGljIFZvaWQgdmlzaXRQYXJhbShQYXJhbVRyZWUgbm9kZSwgVm9pZCBwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChub2RlLmdldE5hbWUoKS5nZXROYW1lKCkuY29udGVudEVxdWFscyhwYXJhbU5hbWUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmhlcml0ZWRUZXh0LmFkZChub2RlLmdldERlc2NyaXB0aW9uKCkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzdXBlci52aXNpdFBhcmFtKG5vZGUsIHApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0uc2Nhbihpbmhlcml0ZWREb2NUcmVlLCBudWxsKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFRIUk9XUzoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyB0aHJvd25OYW1lID0gZ2V0VGhyb3duRXhjZXB0aW9uKHRhc2ssIGVsLCBkb2NDb21tZW50VHJlZSwgKFRocm93c1RyZWUpIHBhcmVudCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgRG9jVHJlZVNjYW5uZXI8Vm9pZCwgVm9pZD4oKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHVibGljIFZvaWQgdmlzaXRUaHJvd3MoVGhyb3dzVHJlZSBub2RlLCBWb2lkIHApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKE9iamVjdHMuZXF1YWxzKGdldFRocm93bkV4Y2VwdGlvbihpbmhlcml0ZWRKYXZhY1Rhc2ssIGluaGVyaXRlZFRyZWVQYXRoLCBpbmhlcml0ZWREb2NUcmVlLCBub2RlKSwgdGhyb3duTmFtZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluaGVyaXRlZFRleHQuYWRkKG5vZGUuZ2V0RGVzY3JpcHRpb24oKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHN1cGVyLnZpc2l0VGhyb3dzKG5vZGUsIHApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0uc2Nhbihpbmhlcml0ZWREb2NUcmVlLCBudWxsKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFJFVFVSTjoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBEb2NUcmVlU2Nhbm5lcjxWb2lkLCBWb2lkPigpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwdWJsaWMgVm9pZCB2aXNpdFJldHVybihSZXR1cm5UcmVlIG5vZGUsIFZvaWQgcCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmhlcml0ZWRUZXh0LmFkZChub2RlLmdldERlc2NyaXB0aW9uKCkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3VwZXIudmlzaXRSZXR1cm4obm9kZSwgcCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfS5zY2FuKGluaGVyaXRlZERvY1RyZWUsIG51bGwpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmICghaW5oZXJpdGVkVGV4dC5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgbG9uZyBvZmZzZXQgPSB0cmVlcy5nZXRTb3VyY2VQb3NpdGlvbnMoKS5nZXRTdGFydFBvc2l0aW9uKG51bGwsIGluaGVyaXRlZERvY1RyZWUsIGluaGVyaXRlZERvY1RyZWUpOwogICAgICAgICAgICAgICAgICAgICAgICBsb25nIHN0YXJ0ID0gTG9uZy5NQVhfVkFMVUU7CiAgICAgICAgICAgICAgICAgICAgICAgIGxvbmcgZW5kID0gTG9uZy5NSU5fVkFMVUU7CgogICAgICAgICAgICAgICAgICAgICAgICBmb3IgKERvY1RyZWUgdCA6IGluaGVyaXRlZFRleHQuZ2V0KDApKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGFydCA9IE1hdGgubWluKHN0YXJ0LCB0cmVlcy5nZXRTb3VyY2VQb3NpdGlvbnMoKS5nZXRTdGFydFBvc2l0aW9uKG51bGwsIGluaGVyaXRlZERvY1RyZWUsIHQpIC0gb2Zmc2V0KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVuZCAgID0gTWF0aC5tYXgoZW5kLCAgIHRyZWVzLmdldFNvdXJjZVBvc2l0aW9ucygpLmdldEVuZFBvc2l0aW9uKG51bGwsIGluaGVyaXRlZERvY1RyZWUsIHQpIC0gb2Zmc2V0KTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgdGV4dCA9IGluaGVyaXRlZC5zdWJzdHJpbmcoKGludCkgc3RhcnQsIChpbnQpIGVuZCk7CgogICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3ludGhldGljVHJlZXMuY29udGFpbnNLZXkocGFyZW50KSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwbGFjZS5wdXQobmV3IGludFtdIHsoaW50KSBsYXN0UG9zICsgMSwgKGludCkgbGFzdFBvc30sICJcbiIgKyBzeW50aGV0aWNUcmVlcy5nZXQocGFyZW50KSArIHRleHQpOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9uZyBpbmhlcml0ZWRTdGFydCA9IHRyZWVzLmdldFNvdXJjZVBvc2l0aW9ucygpLmdldFN0YXJ0UG9zaXRpb24obnVsbCwgZGNUcmVlLCBub2RlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvbmcgaW5oZXJpdGVkRW5kICAgPSB0cmVlcy5nZXRTb3VyY2VQb3NpdGlvbnMoKS5nZXRFbmRQb3NpdGlvbihudWxsLCBkY1RyZWUsIG5vZGUpOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcGxhY2UucHV0KG5ldyBpbnRbXSB7KGludCkgaW5oZXJpdGVkU3RhcnQsIChpbnQpIGluaGVyaXRlZEVuZH0sIHRleHQpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHJldHVybiBzdXBlci52aXNpdEluaGVyaXREb2Mobm9kZSwgcCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBwcml2YXRlIGJvb2xlYW4gaW5TeW50aGV0aWM7CiAgICAgICAgICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICAgICAgICAgIHB1YmxpYyBWb2lkIHNjYW4oRG9jVHJlZSB0cmVlLCBWb2lkIHApIHsKICAgICAgICAgICAgICAgICAgICBpZiAoZXhjZXB0aW9uWzBdICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gcHJldkluU3ludGhldGljID0gaW5TeW50aGV0aWM7CiAgICAgICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICAgICAgaW5TeW50aGV0aWMgfD0gc3ludGhldGljVHJlZXMuY29udGFpbnNLZXkodHJlZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzdXBlci5zY2FuKHRyZWUsIHApOwogICAgICAgICAgICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghaW5TeW50aGV0aWMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhc3RQb3MgPSB0cmVlcy5nZXRTb3VyY2VQb3NpdGlvbnMoKS5nZXRFbmRQb3NpdGlvbihudWxsLCBkY1RyZWUsIHRyZWUpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGluU3ludGhldGljID0gcHJldkluU3ludGhldGljOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBwcml2YXRlIHZvaWQgaW5zZXJ0VGFnKExpc3Q8RG9jVHJlZT4gdGFncywgRG9jVHJlZSB0b0luc2VydCwgTGlzdDxTdHJpbmc+IHBhcmFtZXRlcnMsIExpc3Q8U3RyaW5nPiB0aHJvd3NUeXBlcykgewogICAgICAgICAgICAgICAgICAgIENvbXBhcmF0b3I8RG9jVHJlZT4gY29tcCA9ICh0YWcxLCB0YWcyKSAtPiB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0YWcxLmdldEtpbmQoKSA9PSB0YWcyLmdldEtpbmQoKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3dpdGNoICh0b0luc2VydC5nZXRLaW5kKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFBBUkFNOiB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBhcmFtVHJlZSBwMSA9IChQYXJhbVRyZWUpIHRhZzE7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBhcmFtVHJlZSBwMiA9IChQYXJhbVRyZWUpIHRhZzI7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBpMSA9IHBhcmFtZXRlcnMuaW5kZXhPZihwMS5nZXROYW1lKCkuZ2V0TmFtZSgpLnRvU3RyaW5nKCkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgaTIgPSBwYXJhbWV0ZXJzLmluZGV4T2YocDIuZ2V0TmFtZSgpLmdldE5hbWUoKS50b1N0cmluZygpKTsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBpMSAtIGkyOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFRIUk9XUzogewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaHJvd3NUcmVlIHQxID0gKFRocm93c1RyZWUpIHRhZzE7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRocm93c1RyZWUgdDIgPSAoVGhyb3dzVHJlZSkgdGFnMjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGkxID0gdGhyb3dzVHlwZXMuaW5kZXhPZihnZXRUaHJvd25FeGNlcHRpb24odGFzaywgZWwsIGRvY0NvbW1lbnRUcmVlLCB0MSkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgaTIgPSB0aHJvd3NUeXBlcy5pbmRleE9mKGdldFRocm93bkV4Y2VwdGlvbih0YXNrLCBlbCwgZG9jQ29tbWVudFRyZWUsIHQyKSk7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaTEgLSBpMjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIGludCBpMSA9IHRhZ09yZGVyLmluZGV4T2YodGFnMS5nZXRLaW5kKCkpOwogICAgICAgICAgICAgICAgICAgICAgICBpbnQgaTIgPSB0YWdPcmRlci5pbmRleE9mKHRhZzIuZ2V0S2luZCgpKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBpMSAtIGkyOwogICAgICAgICAgICAgICAgICAgIH07CgogICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdGFncy5zaXplKCk7IGkrKykgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoY29tcC5jb21wYXJlKHRhZ3MuZ2V0KGkpLCB0b0luc2VydCkgPj0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFncy5hZGQoaSwgdG9JbnNlcnQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB0YWdzLmFkZCh0b0luc2VydCk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcHJpdmF0ZSBmaW5hbCBMaXN0PERvY1RyZWUuS2luZD4gdGFnT3JkZXIgPSBBcnJheXMuYXNMaXN0KERvY1RyZWUuS2luZC5QQVJBTSwgRG9jVHJlZS5LaW5kLlRIUk9XUywgRG9jVHJlZS5LaW5kLlJFVFVSTik7CiAgICAgICAgICAgIH0uc2Nhbihkb2NDb21tZW50VHJlZSwgbnVsbCk7CgogICAgICAgICAgICBpZiAocmVwbGFjZS5pc0VtcHR5KCkpCiAgICAgICAgICAgICAgICByZXR1cm4gZG9jQ29tbWVudDsKCiAgICAgICAgICAgIFN0cmluZ0J1aWxkZXIgcmVwbGFjZWRJbmhlcml0RG9jID0gbmV3IFN0cmluZ0J1aWxkZXIoZG9jQ29tbWVudCk7CiAgICAgICAgICAgIGludCBvZmZzZXQgPSAoaW50KSB0cmVlcy5nZXRTb3VyY2VQb3NpdGlvbnMoKS5nZXRTdGFydFBvc2l0aW9uKG51bGwsIGRvY0NvbW1lbnRUcmVlLCBkb2NDb21tZW50VHJlZSk7CgogICAgICAgICAgICBmb3IgKEVudHJ5PGludFtdLCBTdHJpbmc+IGUgOiByZXBsYWNlLmVudHJ5U2V0KCkpIHsKICAgICAgICAgICAgICAgIHJlcGxhY2VkSW5oZXJpdERvYy5kZWxldGUoZS5nZXRLZXkoKVswXSAtIG9mZnNldCwgZS5nZXRLZXkoKVsxXSAtIG9mZnNldCArIDEpOwogICAgICAgICAgICAgICAgcmVwbGFjZWRJbmhlcml0RG9jLmluc2VydChlLmdldEtleSgpWzBdIC0gb2Zmc2V0LCBlLmdldFZhbHVlKCkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gcmVwbGFjZWRJbmhlcml0RG9jLnRvU3RyaW5nKCk7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIFN0cmVhbTxFbGVtZW50PiBzdXBlclR5cGVGb3JJbmhlcml0RG9jKEphdmFjVGFzayB0YXNrLCBFbGVtZW50IHR5cGUpIHsKICAgICAgICAgICAgVHlwZUVsZW1lbnQgY2xhenogPSAoVHlwZUVsZW1lbnQpIHR5cGU7CiAgICAgICAgICAgIFN0cmVhbTxFbGVtZW50PiByZXN1bHQgPSBpbnRlcmZhY2VzKGNsYXp6KTsKICAgICAgICAgICAgcmVzdWx0ID0gU3RyZWFtLmNvbmNhdChyZXN1bHQsIGludGVyZmFjZXMoY2xhenopLmZsYXRNYXAoZWwgLT4gc3VwZXJUeXBlRm9ySW5oZXJpdERvYyh0YXNrLCBlbCkpKTsKCiAgICAgICAgICAgIGlmIChjbGF6ei5nZXRTdXBlcmNsYXNzKCkuZ2V0S2luZCgpID09IFR5cGVLaW5kLkRFQ0xBUkVEKSB7CiAgICAgICAgICAgICAgICBFbGVtZW50IHN1cGVyQ2xhc3MgPSAoKERlY2xhcmVkVHlwZSkgY2xhenouZ2V0U3VwZXJjbGFzcygpKS5hc0VsZW1lbnQoKTsKICAgICAgICAgICAgICAgIHJlc3VsdCA9IFN0cmVhbS5jb25jYXQocmVzdWx0LCBTdHJlYW0ub2Yoc3VwZXJDbGFzcykpOwogICAgICAgICAgICAgICAgcmVzdWx0ID0gU3RyZWFtLmNvbmNhdChyZXN1bHQsIHN1cGVyVHlwZUZvckluaGVyaXREb2ModGFzaywgc3VwZXJDbGFzcykpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgIH0KICAgICAgICAvL3doZXJlOgogICAgICAgICAgICBwcml2YXRlIFN0cmVhbTxFbGVtZW50PiBpbnRlcmZhY2VzKFR5cGVFbGVtZW50IGNsYXp6KSB7CiAgICAgICAgICAgICAgICByZXR1cm4gY2xhenouZ2V0SW50ZXJmYWNlcygpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuc3RyZWFtKCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5maWx0ZXIodG0gLT4gdG0uZ2V0S2luZCgpID09IFR5cGVLaW5kLkRFQ0xBUkVEKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgLm1hcCh0bSAtPiAoKERlY2xhcmVkVHlwZSkgdG0pLmFzRWxlbWVudCgpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgcHJpdmF0ZSBEb2NUcmVlIHBhcnNlQmxvY2tUYWcoSmF2YWNUYXNrIHRhc2ssIFN0cmluZyBibG9ja1RhZykgewogICAgICAgICAgICBEb2NDb21tZW50VHJlZSBkYyA9IHBhcnNlRG9jQ29tbWVudCh0YXNrLCBibG9ja1RhZyk7CgogICAgICAgICAgICByZXR1cm4gZGMuZ2V0QmxvY2tUYWdzKCkuZ2V0KDApOwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBEb2NDb21tZW50VHJlZSBwYXJzZURvY0NvbW1lbnQoSmF2YWNUYXNrIHRhc2ssIFN0cmluZyBqYXZhZG9jKSB7CiAgICAgICAgICAgIERvY1RyZWVzIHRyZWVzID0gRG9jVHJlZXMuaW5zdGFuY2UodGFzayk7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJlZXMuZ2V0RG9jQ29tbWVudFRyZWUobmV3IFNpbXBsZUphdmFGaWxlT2JqZWN0KG5ldyBVUkkoIm1lbTovL2RvYy5odG1sIiksIGphdmF4LnRvb2xzLkphdmFGaWxlT2JqZWN0LktpbmQuSFRNTCkgewogICAgICAgICAgICAgICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgICAgICAgICAgICAgICAgICBwdWJsaWMgQ2hhclNlcXVlbmNlIGdldENoYXJDb250ZW50KGJvb2xlYW4gaWdub3JlRW5jb2RpbmdFcnJvcnMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAiPGJvZHk+IiArIGphdmFkb2MgKyAiPC9ib2R5PiI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0gY2F0Y2ggKFVSSVN5bnRheEV4Y2VwdGlvbiBleCkgewogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHByaXZhdGUgU3RyaW5nIGdldFRocm93bkV4Y2VwdGlvbihKYXZhY1Rhc2sgdGFzaywgVHJlZVBhdGggcm9vdE9uLCBEb2NDb21tZW50VHJlZSBjb21tZW50LCBUaHJvd3NUcmVlIHR0KSB7CiAgICAgICAgICAgIERvY1RyZWVzIHRyZWVzID0gRG9jVHJlZXMuaW5zdGFuY2UodGFzayk7CiAgICAgICAgICAgIEVsZW1lbnQgZXhjID0gdHJlZXMuZ2V0RWxlbWVudChuZXcgRG9jVHJlZVBhdGgobmV3IERvY1RyZWVQYXRoKHJvb3RPbiwgY29tbWVudCksIHR0LmdldEV4Y2VwdGlvbk5hbWUoKSkpOwogICAgICAgICAgICByZXR1cm4gZXhjICE9IG51bGwgPyBleGMudG9TdHJpbmcoKSA6IG51bGw7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIFBhaXI8SmF2YWNUYXNrLCBUcmVlUGF0aD4gZ2V0U291cmNlRWxlbWVudChKYXZhY1Rhc2sgb3JpZ2luLCBFbGVtZW50IGVsKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgICAgICBTdHJpbmcgaGFuZGxlID0gZWxlbWVudFNpZ25hdHVyZShlbCk7CiAgICAgICAgICAgIFBhaXI8SmF2YWNUYXNrLCBUcmVlUGF0aD4gY2FjaGVkID0gc2lnbmF0dXJlMlNvdXJjZS5nZXQoaGFuZGxlKTsKCiAgICAgICAgICAgIGlmIChjYWNoZWQgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgcmV0dXJuIGNhY2hlZC5mc3QgIT0gbnVsbCA/IGNhY2hlZCA6IG51bGw7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIFR5cGVFbGVtZW50IHR5cGUgPSB0b3BMZXZlbFR5cGUoZWwpOwoKICAgICAgICAgICAgaWYgKHR5cGUgPT0gbnVsbCkKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwoKICAgICAgICAgICAgRWxlbWVudHMgZWxlbWVudHMgPSBvcmlnaW4uZ2V0RWxlbWVudHMoKTsKICAgICAgICAgICAgU3RyaW5nIGJpbmFyeU5hbWUgPSBlbGVtZW50cy5nZXRCaW5hcnlOYW1lKHR5cGUpLnRvU3RyaW5nKCk7CiAgICAgICAgICAgIE1vZHVsZUVsZW1lbnQgbW9kdWxlID0gZWxlbWVudHMuZ2V0TW9kdWxlT2YodHlwZSk7CiAgICAgICAgICAgIFN0cmluZyBtb2R1bGVOYW1lID0gbW9kdWxlID09IG51bGwgfHwgbW9kdWxlLmlzVW5uYW1lZCgpCiAgICAgICAgICAgICAgICAgICAgPyBudWxsCiAgICAgICAgICAgICAgICAgICAgOiBtb2R1bGUuZ2V0UXVhbGlmaWVkTmFtZSgpLnRvU3RyaW5nKCk7CiAgICAgICAgICAgIFBhaXI8SmF2YWNUYXNrLCBDb21waWxhdGlvblVuaXRUcmVlPiBzb3VyY2UgPSBmaW5kU291cmNlKG1vZHVsZU5hbWUsIGJpbmFyeU5hbWUpOwoKICAgICAgICAgICAgaWYgKHNvdXJjZSA9PSBudWxsKQogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CgogICAgICAgICAgICBmaWxsRWxlbWVudENhY2hlKHNvdXJjZS5mc3QsIHNvdXJjZS5zbmQpOwoKICAgICAgICAgICAgY2FjaGVkID0gc2lnbmF0dXJlMlNvdXJjZS5nZXQoaGFuZGxlKTsKCiAgICAgICAgICAgIGlmIChjYWNoZWQgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgcmV0dXJuIGNhY2hlZDsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHNpZ25hdHVyZTJTb3VyY2UucHV0KGhhbmRsZSwgUGFpci5vZihudWxsLCBudWxsKSk7CiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvL3doZXJlOgogICAgICAgICAgICBwcml2YXRlIFN0cmluZyBlbGVtZW50U2lnbmF0dXJlKEVsZW1lbnQgZWwpIHsKICAgICAgICAgICAgICAgIHN3aXRjaCAoZWwuZ2V0S2luZCgpKSB7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBBTk5PVEFUSU9OX1RZUEU6IGNhc2UgQ0xBU1M6IGNhc2UgRU5VTTogY2FzZSBJTlRFUkZBQ0U6CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAoKFR5cGVFbGVtZW50KSBlbCkuZ2V0UXVhbGlmaWVkTmFtZSgpLnRvU3RyaW5nKCk7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBGSUVMRDoKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGVsZW1lbnRTaWduYXR1cmUoZWwuZ2V0RW5jbG9zaW5nRWxlbWVudCgpKSArICIuIiArIGVsLmdldFNpbXBsZU5hbWUoKSArICI6IiArIGVsLmFzVHlwZSgpOwogICAgICAgICAgICAgICAgICAgIGNhc2UgRU5VTV9DT05TVEFOVDoKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGVsZW1lbnRTaWduYXR1cmUoZWwuZ2V0RW5jbG9zaW5nRWxlbWVudCgpKSArICIuIiArIGVsLmdldFNpbXBsZU5hbWUoKTsKICAgICAgICAgICAgICAgICAgICBjYXNlIEVYQ0VQVElPTl9QQVJBTUVURVI6IGNhc2UgTE9DQUxfVkFSSUFCTEU6IGNhc2UgUEFSQU1FVEVSOiBjYXNlIFJFU09VUkNFX1ZBUklBQkxFOgogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZWwuZ2V0U2ltcGxlTmFtZSgpICsgIjoiICsgZWwuYXNUeXBlKCk7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBDT05TVFJVQ1RPUjogY2FzZSBNRVRIT0Q6CiAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZ0J1aWxkZXIgaGVhZGVyID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKICAgICAgICAgICAgICAgICAgICAgICAgaGVhZGVyLmFwcGVuZChlbGVtZW50U2lnbmF0dXJlKGVsLmdldEVuY2xvc2luZ0VsZW1lbnQoKSkpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoZWwuZ2V0S2luZCgpID09IEVsZW1lbnRLaW5kLk1FVEhPRCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVhZGVyLmFwcGVuZCgiLiIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVhZGVyLmFwcGVuZChlbC5nZXRTaW1wbGVOYW1lKCkpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGhlYWRlci5hcHBlbmQoIigiKTsKICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHNlcCA9ICIiOwogICAgICAgICAgICAgICAgICAgICAgICBFeGVjdXRhYmxlRWxlbWVudCBtZXRob2QgPSAoRXhlY3V0YWJsZUVsZW1lbnQpIGVsOwogICAgICAgICAgICAgICAgICAgICAgICBmb3IgKEl0ZXJhdG9yPD8gZXh0ZW5kcyBWYXJpYWJsZUVsZW1lbnQ+IGkgPSBtZXRob2QuZ2V0UGFyYW1ldGVycygpLml0ZXJhdG9yKCk7IGkuaGFzTmV4dCgpOykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgVmFyaWFibGVFbGVtZW50IHAgPSBpLm5leHQoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhlYWRlci5hcHBlbmQoc2VwKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhlYWRlci5hcHBlbmQocC5hc1R5cGUoKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXAgPSAiLCAiOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGhlYWRlci5hcHBlbmQoIikiKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGhlYWRlci50b1N0cmluZygpOwogICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGVsLnRvU3RyaW5nKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHByaXZhdGUgVHlwZUVsZW1lbnQgdG9wTGV2ZWxUeXBlKEVsZW1lbnQgZWwpIHsKICAgICAgICAgICAgICAgIGlmIChlbC5nZXRLaW5kKCkgPT0gRWxlbWVudEtpbmQuUEFDS0FHRSkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKCiAgICAgICAgICAgICAgICB3aGlsZSAoZWwgIT0gbnVsbCAmJiBlbC5nZXRFbmNsb3NpbmdFbGVtZW50KCkuZ2V0S2luZCgpICE9IEVsZW1lbnRLaW5kLlBBQ0tBR0UpIHsKICAgICAgICAgICAgICAgICAgICBlbCA9IGVsLmdldEVuY2xvc2luZ0VsZW1lbnQoKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICByZXR1cm4gZWwgIT0gbnVsbCAmJiAoZWwuZ2V0S2luZCgpLmlzQ2xhc3MoKSB8fCBlbC5nZXRLaW5kKCkuaXNJbnRlcmZhY2UoKSkgPyAoVHlwZUVsZW1lbnQpIGVsIDogbnVsbDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHJpdmF0ZSB2b2lkIGZpbGxFbGVtZW50Q2FjaGUoSmF2YWNUYXNrIHRhc2ssIENvbXBpbGF0aW9uVW5pdFRyZWUgY3V0KSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgICAgICAgICAgVHJlZXMgdHJlZXMgPSBUcmVlcy5pbnN0YW5jZSh0YXNrKTsKCiAgICAgICAgICAgICAgICBuZXcgVHJlZVBhdGhTY2FubmVyPFZvaWQsIFZvaWQ+KCkgewogICAgICAgICAgICAgICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgICAgICAgICAgICAgIHB1YmxpYyBWb2lkIHZpc2l0TWV0aG9kKE1ldGhvZFRyZWUgbm9kZSwgVm9pZCBwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZURlY2xhcmF0aW9uKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgICAgICAgICAgICAgcHVibGljIFZvaWQgdmlzaXRDbGFzcyhDbGFzc1RyZWUgbm9kZSwgVm9pZCBwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZURlY2xhcmF0aW9uKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzdXBlci52aXNpdENsYXNzKG5vZGUsIHApOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgICAgICAgICAgICAgcHVibGljIFZvaWQgdmlzaXRWYXJpYWJsZShWYXJpYWJsZVRyZWUgbm9kZSwgVm9pZCBwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZURlY2xhcmF0aW9uKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzdXBlci52aXNpdFZhcmlhYmxlKG5vZGUsIHApOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgcHJpdmF0ZSB2b2lkIGhhbmRsZURlY2xhcmF0aW9uKCkgewogICAgICAgICAgICAgICAgICAgICAgICBFbGVtZW50IGN1cnJlbnRFbGVtZW50ID0gdHJlZXMuZ2V0RWxlbWVudChnZXRDdXJyZW50UGF0aCgpKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjdXJyZW50RWxlbWVudCAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaWduYXR1cmUyU291cmNlLnB1dChlbGVtZW50U2lnbmF0dXJlKGN1cnJlbnRFbGVtZW50KSwgUGFpci5vZih0YXNrLCBnZXRDdXJyZW50UGF0aCgpKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LnNjYW4oY3V0LCBudWxsKTsKICAgICAgICAgICAgfQoKICAgICAgICBwcml2YXRlIFBhaXI8SmF2YWNUYXNrLCBDb21waWxhdGlvblVuaXRUcmVlPiBmaW5kU291cmNlKFN0cmluZyBtb2R1bGVOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGJpbmFyeU5hbWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgICAgIEphdmFGaWxlT2JqZWN0IGpmbyA9IGZtLmdldEphdmFGaWxlRm9ySW5wdXQoU3RhbmRhcmRMb2NhdGlvbi5TT1VSQ0VfUEFUSCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiaW5hcnlOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEphdmFGaWxlT2JqZWN0LktpbmQuU09VUkNFKTsKCiAgICAgICAgICAgIGlmIChqZm8gPT0gbnVsbCkKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwoKICAgICAgICAgICAgTGlzdDxKYXZhRmlsZU9iamVjdD4gamZvcyA9IEFycmF5cy5hc0xpc3QoamZvKTsKICAgICAgICAgICAgSmF2YUZpbGVNYW5hZ2VyIHBhdGNoRk0gPSBtb2R1bGVOYW1lICE9IG51bGwKICAgICAgICAgICAgICAgICAgICA/IG5ldyBQYXRjaE1vZHVsZUZpbGVNYW5hZ2VyKGJhc2VGaWxlTWFuYWdlciwgamZvLCBtb2R1bGVOYW1lKQogICAgICAgICAgICAgICAgICAgIDogYmFzZUZpbGVNYW5hZ2VyOwogICAgICAgICAgICBKYXZhY1Rhc2tJbXBsIHRhc2sgPSAoSmF2YWNUYXNrSW1wbCkgY29tcGlsZXIuZ2V0VGFzayhudWxsLCBwYXRjaEZNLCBkIC0+IHt9LCBudWxsLCBudWxsLCBqZm9zKTsKICAgICAgICAgICAgSXRlcmFibGU8PyBleHRlbmRzIENvbXBpbGF0aW9uVW5pdFRyZWU+IGN1dHMgPSB0YXNrLnBhcnNlKCk7CgogICAgICAgICAgICB0YXNrLmVudGVyKCk7CgogICAgICAgICAgICByZXR1cm4gUGFpci5vZih0YXNrLCBjdXRzLml0ZXJhdG9yKCkubmV4dCgpKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICAgICAgZm0uY2xvc2UoKTsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIFBhdGNoTW9kdWxlRmlsZU1hbmFnZXIKICAgICAgICAgICAgICAgIGV4dGVuZHMgRm9yd2FyZGluZ0phdmFGaWxlTWFuYWdlcjxKYXZhRmlsZU1hbmFnZXI+IHsKCiAgICAgICAgICAgIHByaXZhdGUgZmluYWwgSmF2YUZpbGVPYmplY3QgZmlsZTsKICAgICAgICAgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgbW9kdWxlTmFtZTsKCiAgICAgICAgICAgIHB1YmxpYyBQYXRjaE1vZHVsZUZpbGVNYW5hZ2VyKEphdmFGaWxlTWFuYWdlciBmaWxlTWFuYWdlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSmF2YUZpbGVPYmplY3QgZmlsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG1vZHVsZU5hbWUpIHsKICAgICAgICAgICAgICAgIHN1cGVyKGZpbGVNYW5hZ2VyKTsKICAgICAgICAgICAgICAgIHRoaXMuZmlsZSA9IGZpbGU7CiAgICAgICAgICAgICAgICB0aGlzLm1vZHVsZU5hbWUgPSBtb2R1bGVOYW1lOwogICAgICAgICAgICB9CgogICAgICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICAgICAgICAgIHB1YmxpYyBMb2NhdGlvbiBnZXRMb2NhdGlvbkZvck1vZHVsZShMb2NhdGlvbiBsb2NhdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEphdmFGaWxlT2JqZWN0IGZvKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgICAgICAgICAgcmV0dXJuIGZvID09IGZpbGUKICAgICAgICAgICAgICAgICAgICAgICAgPyBQQVRDSF9MT0NBVElPTgogICAgICAgICAgICAgICAgICAgICAgICA6IHN1cGVyLmdldExvY2F0aW9uRm9yTW9kdWxlKGxvY2F0aW9uLCBmbyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgICAgICAgICAgcHVibGljIFN0cmluZyBpbmZlck1vZHVsZU5hbWUoTG9jYXRpb24gbG9jYXRpb24pIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgICAgICAgICByZXR1cm4gbG9jYXRpb24gPT0gUEFUQ0hfTE9DQVRJT04KICAgICAgICAgICAgICAgICAgICAgICAgPyBtb2R1bGVOYW1lCiAgICAgICAgICAgICAgICAgICAgICAgIDogc3VwZXIuaW5mZXJNb2R1bGVOYW1lKGxvY2F0aW9uKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSKQogICAgICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb2NhdGlvbihMb2NhdGlvbiBsb2NhdGlvbikgewogICAgICAgICAgICAgICAgcmV0dXJuIGxvY2F0aW9uID09IFN0YW5kYXJkTG9jYXRpb24uUEFUQ0hfTU9EVUxFX1BBVEggfHwKICAgICAgICAgICAgICAgICAgICAgICBzdXBlci5oYXNMb2NhdGlvbihsb2NhdGlvbik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIExvY2F0aW9uIFBBVENIX0xPQ0FUSU9OID0gbmV3IExvY2F0aW9uKCkgewogICAgICAgICAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSKQogICAgICAgICAgICAgICAgcHVibGljIFN0cmluZyBnZXROYW1lKCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAiUEFUQ0hfTE9DQVRJT04iOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgICAgICAgICAgICAgIHB1YmxpYyBib29sZWFuIGlzT3V0cHV0TG9jYXRpb24oKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgICAgICAgICAgICAgIHB1YmxpYyBib29sZWFuIGlzTW9kdWxlT3JpZW50ZWRMb2NhdGlvbigpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICB9OwogICAgICAgIH0KICAgIH0KCn0KUEsDBAoAAAgAAAY7qUoGMAxS3GYAANxmAAAzAAAAamRrL2ludGVybmFsL3NoZWxsc3VwcG9ydC9kb2MvSmF2YWRvY0Zvcm1hdHRlci5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDE2LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCnBhY2thZ2UgamRrLmludGVybmFsLnNoZWxsc3VwcG9ydC5kb2M7CgppbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKaW1wb3J0IGphdmEubmV0LlVSSTsKaW1wb3J0IGphdmEubmV0LlVSSVN5bnRheEV4Y2VwdGlvbjsKaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CmltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOwppbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOwppbXBvcnQgamF2YS51dGlsLklkZW50aXR5SGFzaE1hcDsKaW1wb3J0IGphdmEudXRpbC5MaW5rZWRIYXNoTWFwOwppbXBvcnQgamF2YS51dGlsLkxpc3Q7CmltcG9ydCBqYXZhLnV0aWwuTWFwOwppbXBvcnQgamF2YS51dGlsLlJlc291cmNlQnVuZGxlOwppbXBvcnQgamF2YS51dGlsLlN0YWNrOwoKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC5OYW1lOwppbXBvcnQgamF2YXgudG9vbHMuSmF2YUZpbGVPYmplY3QuS2luZDsKaW1wb3J0IGphdmF4LnRvb2xzLlNpbXBsZUphdmFGaWxlT2JqZWN0OwppbXBvcnQgamF2YXgudG9vbHMuVG9vbFByb3ZpZGVyOwoKaW1wb3J0IGNvbS5zdW4uc291cmNlLmRvY3RyZWUuQXR0cmlidXRlVHJlZTsKaW1wb3J0IGNvbS5zdW4uc291cmNlLmRvY3RyZWUuRG9jQ29tbWVudFRyZWU7CmltcG9ydCBjb20uc3VuLnNvdXJjZS5kb2N0cmVlLkRvY1RyZWU7CmltcG9ydCBjb20uc3VuLnNvdXJjZS5kb2N0cmVlLkVuZEVsZW1lbnRUcmVlOwppbXBvcnQgY29tLnN1bi5zb3VyY2UuZG9jdHJlZS5FbnRpdHlUcmVlOwppbXBvcnQgY29tLnN1bi5zb3VyY2UuZG9jdHJlZS5JbmxpbmVUYWdUcmVlOwppbXBvcnQgY29tLnN1bi5zb3VyY2UuZG9jdHJlZS5MaW5rVHJlZTsKaW1wb3J0IGNvbS5zdW4uc291cmNlLmRvY3RyZWUuTGl0ZXJhbFRyZWU7CmltcG9ydCBjb20uc3VuLnNvdXJjZS5kb2N0cmVlLlBhcmFtVHJlZTsKaW1wb3J0IGNvbS5zdW4uc291cmNlLmRvY3RyZWUuUmV0dXJuVHJlZTsKaW1wb3J0IGNvbS5zdW4uc291cmNlLmRvY3RyZWUuU3RhcnRFbGVtZW50VHJlZTsKaW1wb3J0IGNvbS5zdW4uc291cmNlLmRvY3RyZWUuVGV4dFRyZWU7CmltcG9ydCBjb20uc3VuLnNvdXJjZS5kb2N0cmVlLlRocm93c1RyZWU7CmltcG9ydCBjb20uc3VuLnNvdXJjZS51dGlsLkRvY1RyZWVTY2FubmVyOwppbXBvcnQgY29tLnN1bi5zb3VyY2UudXRpbC5Eb2NUcmVlczsKaW1wb3J0IGNvbS5zdW4uc291cmNlLnV0aWwuSmF2YWNUYXNrOwppbXBvcnQgY29tLnN1bi50b29scy5kb2NsaW50LkVudGl0eTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuZG9jbGludC5IdG1sVGFnOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkRlZmluZWRCeTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5EZWZpbmVkQnkuQXBpOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLlN0cmluZ1V0aWxzOwoKLyoqQSBqYXZhZG9jIHRvIHBsYWluIHRleHQgZm9ybWF0dGVyLgogKgogKi8KcHVibGljIGNsYXNzIEphdmFkb2NGb3JtYXR0ZXIgewoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBDT0RFX1JFU0VUID0gIlwwMzNbMG0iOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIENPREVfSElHSExJR0hUID0gIlwwMzNbMW0iOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIENPREVfVU5ERVJMSU5FID0gIlwwMzNbNG0iOwoKICAgIHByaXZhdGUgZmluYWwgaW50IGxpbmVMaW1pdDsKICAgIHByaXZhdGUgZmluYWwgYm9vbGVhbiBlc2NhcGVTZXF1ZW5jZXNTdXBwb3J0ZWQ7CgogICAgLyoqIENvbnN0cnVjdCB0aGUgZm9ybWF0dGVyLgogICAgICoKICAgICAqIEBwYXJhbSBsaW5lTGltaXQgbWF4aW11bSBsaW5lIGxlbmd0aAogICAgICogQHBhcmFtIGVzY2FwZVNlcXVlbmNlc1N1cHBvcnRlZCB3aGV0aGVyIGVzY2FwZSBzZXF1ZW5jZXMgYXJlIHN1cHBvcnRlZAogICAgICovCiAgICBwdWJsaWMgSmF2YWRvY0Zvcm1hdHRlcihpbnQgbGluZUxpbWl0LCBib29sZWFuIGVzY2FwZVNlcXVlbmNlc1N1cHBvcnRlZCkgewogICAgICAgIHRoaXMubGluZUxpbWl0ID0gbGluZUxpbWl0OwogICAgICAgIHRoaXMuZXNjYXBlU2VxdWVuY2VzU3VwcG9ydGVkID0gZXNjYXBlU2VxdWVuY2VzU3VwcG9ydGVkOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBNQVhfTElORV9MRU5HVEggPSA5NTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBTSE9SVEVTVF9MSU5FID0gMzA7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgSU5ERU5UID0gNDsKCiAgICAvKipGb3JtYXQgamF2YWRvYyB0byBwbGFpbiB0ZXh0LgogICAgICoKICAgICAqIEBwYXJhbSBoZWFkZXIgZWxlbWVudCBjYXB0aW9uIHRoYXQgc2hvdWxkIGJlIHVzZWQKICAgICAqIEBwYXJhbSBqYXZhZG9jIHRvIGZvcm1hdAogICAgICogQHJldHVybiBqYXZhZG9jIGZvcm1hdHRlZCB0byBwbGFpbiB0ZXh0CiAgICAgKi8KICAgIHB1YmxpYyBTdHJpbmcgZm9ybWF0SmF2YWRvYyhTdHJpbmcgaGVhZGVyLCBTdHJpbmcgamF2YWRvYykgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIFN0cmluZ0J1aWxkZXIgcmVzdWx0ID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKCiAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoZXNjYXBlKENPREVfSElHSExJR0hUKSkuYXBwZW5kKGhlYWRlcikuYXBwZW5kKGVzY2FwZShDT0RFX1JFU0VUKSkuYXBwZW5kKCJcbiIpOwoKICAgICAgICAgICAgaWYgKGphdmFkb2MgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdC50b1N0cmluZygpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBKYXZhY1Rhc2sgdGFzayA9IChKYXZhY1Rhc2spIFRvb2xQcm92aWRlci5nZXRTeXN0ZW1KYXZhQ29tcGlsZXIoKS5nZXRUYXNrKG51bGwsIG51bGwsIG51bGwsIG51bGwsIG51bGwsIG51bGwpOwogICAgICAgICAgICBEb2NUcmVlcyB0cmVlcyA9IERvY1RyZWVzLmluc3RhbmNlKHRhc2spOwogICAgICAgICAgICBEb2NDb21tZW50VHJlZSBkb2NDb21tZW50ID0gdHJlZXMuZ2V0RG9jQ29tbWVudFRyZWUobmV3IFNpbXBsZUphdmFGaWxlT2JqZWN0KG5ldyBVUkkoIm1lbTovL2RvYy5odG1sIiksIEtpbmQuSFRNTCkgewogICAgICAgICAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSKQogICAgICAgICAgICAgICAgcHVibGljIENoYXJTZXF1ZW5jZSBnZXRDaGFyQ29udGVudChib29sZWFuIGlnbm9yZUVuY29kaW5nRXJyb3JzKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgICAgICAgICAgICAgIHJldHVybiAiPGJvZHk+IiArIGphdmFkb2MgKyAiPC9ib2R5PiI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgbmV3IEZvcm1hdEphdmFkb2NTY2FubmVyKHJlc3VsdCwgdGFzaykuc2Nhbihkb2NDb21tZW50LCBudWxsKTsKCiAgICAgICAgICAgIGFkZE5ld0xpbmVJZk5lZWRlZChyZXN1bHQpOwoKICAgICAgICAgICAgcmV0dXJuIHJlc3VsdC50b1N0cmluZygpOwogICAgICAgIH0gY2F0Y2ggKFVSSVN5bnRheEV4Y2VwdGlvbiBleCkgewogICAgICAgICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcigiVW5leHBlY3RlZCBleGNlcHRpb24iLCBleCk7CiAgICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgY2xhc3MgRm9ybWF0SmF2YWRvY1NjYW5uZXIgZXh0ZW5kcyBEb2NUcmVlU2Nhbm5lcjxPYmplY3QsIE9iamVjdD4gewogICAgICAgIHByaXZhdGUgZmluYWwgU3RyaW5nQnVpbGRlciByZXN1bHQ7CiAgICAgICAgcHJpdmF0ZSBmaW5hbCBKYXZhY1Rhc2sgdGFzazsKICAgICAgICBwcml2YXRlIGludCByZWZsb3duVG87CiAgICAgICAgcHJpdmF0ZSBpbnQgaW5kZW50OwogICAgICAgIHByaXZhdGUgaW50IGxpbWl0ID0gTWF0aC5taW4obGluZUxpbWl0LCBNQVhfTElORV9MRU5HVEgpOwogICAgICAgIHByaXZhdGUgYm9vbGVhbiBwcmU7CiAgICAgICAgcHJpdmF0ZSBNYXA8U3RhcnRFbGVtZW50VHJlZSwgSW50ZWdlcj4gdGFibGVDb2x1bW5zOwoKICAgICAgICBwdWJsaWMgRm9ybWF0SmF2YWRvY1NjYW5uZXIoU3RyaW5nQnVpbGRlciByZXN1bHQsIEphdmFjVGFzayB0YXNrKSB7CiAgICAgICAgICAgIHRoaXMucmVzdWx0ID0gcmVzdWx0OwogICAgICAgICAgICB0aGlzLnRhc2sgPSB0YXNrOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIE9iamVjdCB2aXNpdERvY0NvbW1lbnQoRG9jQ29tbWVudFRyZWUgbm9kZSwgT2JqZWN0IHApIHsKICAgICAgICAgICAgdGFibGVDb2x1bW5zID0gY291bnRUYWJsZUNvbHVtbnMobm9kZSk7CiAgICAgICAgICAgIHJlZmxvd25UbyA9IHJlc3VsdC5sZW5ndGgoKTsKICAgICAgICAgICAgc2Nhbihub2RlLmdldEZpcnN0U2VudGVuY2UoKSwgcCk7CiAgICAgICAgICAgIHNjYW4obm9kZS5nZXRCb2R5KCksIHApOwogICAgICAgICAgICByZWZsb3cocmVzdWx0LCByZWZsb3duVG8sIGluZGVudCwgbGltaXQpOwogICAgICAgICAgICBmb3IgKFNlY3Rpb25zIGN1cnJlbnQgOiBkb2NTZWN0aW9ucy5rZXlTZXQoKSkgewogICAgICAgICAgICAgICAgYm9vbGVhbiBzZWVuQW55ID0gZmFsc2U7CiAgICAgICAgICAgICAgICBmb3IgKERvY1RyZWUgdCA6IG5vZGUuZ2V0QmxvY2tUYWdzKCkpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoY3VycmVudC5tYXRjaGVzKHQpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghc2VlbkFueSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VlbkFueSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVzdWx0LmNoYXJBdChyZXN1bHQubGVuZ3RoKCkgLSAxKSAhPSAnXG4nKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoIlxuIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQuYXBwZW5kKCJcbiIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0LmFwcGVuZChlc2NhcGUoQ09ERV9VTkRFUkxJTkUpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmFwcGVuZChkb2NTZWN0aW9ucy5nZXQoY3VycmVudCkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuYXBwZW5kKGVzY2FwZShDT0RFX1JFU0VUKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5hcHBlbmQoIlxuIik7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIHNjYW4odCwgbnVsbCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIE9iamVjdCB2aXNpdFRleHQoVGV4dFRyZWUgbm9kZSwgT2JqZWN0IHApIHsKICAgICAgICAgICAgU3RyaW5nIHRleHQgPSBub2RlLmdldEJvZHkoKTsKICAgICAgICAgICAgaWYgKCFwcmUpIHsKICAgICAgICAgICAgICAgIHRleHQgPSB0ZXh0LnJlcGxhY2VBbGwoIlsgXHRcclxuXSsiLCAiICIpLnRyaW0oKTsKICAgICAgICAgICAgICAgIGlmICh0ZXh0LmlzRW1wdHkoKSkgewogICAgICAgICAgICAgICAgICAgIHRleHQgPSAiICI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB0ZXh0ID0gdGV4dC5yZXBsYWNlQWxsKCJcbiIsICJcbiIgKyBpbmRlbnRTdHJpbmcoaW5kZW50KSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmVzdWx0LmFwcGVuZCh0ZXh0KTsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgT2JqZWN0IHZpc2l0TGluayhMaW5rVHJlZSBub2RlLCBPYmplY3QgcCkgewogICAgICAgICAgICBpZiAoIW5vZGUuZ2V0TGFiZWwoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICAgIHNjYW4obm9kZS5nZXRMYWJlbCgpLCBwKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQobm9kZS5nZXRSZWZlcmVuY2UoKS5nZXRTaWduYXR1cmUoKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgT2JqZWN0IHZpc2l0UGFyYW0oUGFyYW1UcmVlIG5vZGUsIE9iamVjdCBwKSB7CiAgICAgICAgICAgIHJldHVybiBmb3JtYXREZWYobm9kZS5nZXROYW1lKCkuZ2V0TmFtZSgpLCBub2RlLmdldERlc2NyaXB0aW9uKCkpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIE9iamVjdCB2aXNpdFRocm93cyhUaHJvd3NUcmVlIG5vZGUsIE9iamVjdCBwKSB7CiAgICAgICAgICAgIHJldHVybiBmb3JtYXREZWYobm9kZS5nZXRFeGNlcHRpb25OYW1lKCkuZ2V0U2lnbmF0dXJlKCksIG5vZGUuZ2V0RGVzY3JpcHRpb24oKSk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgT2JqZWN0IGZvcm1hdERlZihDaGFyU2VxdWVuY2UgbmFtZSwgTGlzdDw/IGV4dGVuZHMgRG9jVHJlZT4gZGVzY3JpcHRpb24pIHsKICAgICAgICAgICAgcmVzdWx0LmFwcGVuZChuYW1lKTsKICAgICAgICAgICAgcmVzdWx0LmFwcGVuZCgiIC0gIik7CiAgICAgICAgICAgIHJlZmxvd25UbyA9IHJlc3VsdC5sZW5ndGgoKTsKICAgICAgICAgICAgaW5kZW50ID0gbmFtZS5sZW5ndGgoKSArIDM7CgogICAgICAgICAgICBpZiAobGltaXQgLSBpbmRlbnQgPCBTSE9SVEVTVF9MSU5FKSB7CiAgICAgICAgICAgICAgICByZXN1bHQuYXBwZW5kKCJcbiIpOwogICAgICAgICAgICAgICAgcmVzdWx0LmFwcGVuZChpbmRlbnRTdHJpbmcoSU5ERU5UKSk7CiAgICAgICAgICAgICAgICBpbmRlbnQgPSBJTkRFTlQ7CiAgICAgICAgICAgICAgICByZWZsb3duVG8gKz0gSU5ERU5UOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICByZXR1cm4gc2NhbihkZXNjcmlwdGlvbiwgbnVsbCk7CiAgICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgICAgICByZWZsb3cocmVzdWx0LCByZWZsb3duVG8sIGluZGVudCwgbGltaXQpOwogICAgICAgICAgICAgICAgcmVzdWx0LmFwcGVuZCgiXG4iKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIE9iamVjdCB2aXNpdExpdGVyYWwoTGl0ZXJhbFRyZWUgbm9kZSwgT2JqZWN0IHApIHsKICAgICAgICAgICAgcmV0dXJuIHNjYW4obm9kZS5nZXRCb2R5KCksIHApOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIE9iamVjdCB2aXNpdFJldHVybihSZXR1cm5UcmVlIG5vZGUsIE9iamVjdCBwKSB7CiAgICAgICAgICAgIHJlZmxvd25UbyA9IHJlc3VsdC5sZW5ndGgoKTsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIHJldHVybiBzdXBlci52aXNpdFJldHVybihub2RlLCBwKTsKICAgICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgICAgIHJlZmxvdyhyZXN1bHQsIHJlZmxvd25UbywgMCwgbGltaXQpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBTdGFjazxJbnRlZ2VyPiBsaXN0U3RhY2sgPSBuZXcgU3RhY2s8PigpOwogICAgICAgIFN0YWNrPEludGVnZXI+IGRlZlN0YWNrID0gbmV3IFN0YWNrPD4oKTsKICAgICAgICBTdGFjazxJbnRlZ2VyPiB0YWJsZVN0YWNrID0gbmV3IFN0YWNrPD4oKTsKICAgICAgICBTdGFjazxMaXN0PEludGVnZXI+PiBjZWxsc1N0YWNrID0gbmV3IFN0YWNrPD4oKTsKICAgICAgICBTdGFjazxMaXN0PEJvb2xlYW4+PiBoZWFkZXJTdGFjayA9IG5ldyBTdGFjazw+KCk7CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBPYmplY3QgdmlzaXRTdGFydEVsZW1lbnQoU3RhcnRFbGVtZW50VHJlZSBub2RlLCBPYmplY3QgcCkgewogICAgICAgICAgICBzd2l0Y2ggKGdldEh0bWxUYWcobm9kZS5nZXROYW1lKCkpKSB7CiAgICAgICAgICAgICAgICBjYXNlIFA6CiAgICAgICAgICAgICAgICAgICAgaWYgKGxhc3ROb2RlIT0gbnVsbCAmJiBsYXN0Tm9kZS5nZXRLaW5kKCkgPT0gRG9jVHJlZS5LaW5kLlNUQVJUX0VMRU1FTlQgJiYKICAgICAgICAgICAgICAgICAgICAgICAgSHRtbFRhZy5nZXQoKChTdGFydEVsZW1lbnRUcmVlKSBsYXN0Tm9kZSkuZ2V0TmFtZSgpKSA9PSBIdG1sVGFnLkxJKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vaWdub3JlCiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICByZWZsb3dUaWxsTm93KCk7CiAgICAgICAgICAgICAgICAgICAgYWRkTmV3TGluZUlmTmVlZGVkKHJlc3VsdCk7CiAgICAgICAgICAgICAgICAgICAgcmVzdWx0LmFwcGVuZChpbmRlbnRTdHJpbmcoaW5kZW50KSk7CiAgICAgICAgICAgICAgICAgICAgcmVmbG93blRvID0gcmVzdWx0Lmxlbmd0aCgpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBCTE9DS1FVT1RFOgogICAgICAgICAgICAgICAgICAgIHJlZmxvd1RpbGxOb3coKTsKICAgICAgICAgICAgICAgICAgICBpbmRlbnQgKz0gSU5ERU5UOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBQUkU6CiAgICAgICAgICAgICAgICAgICAgcmVmbG93VGlsbE5vdygpOwogICAgICAgICAgICAgICAgICAgIHByZSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIFVMOgogICAgICAgICAgICAgICAgICAgIHJlZmxvd1RpbGxOb3coKTsKICAgICAgICAgICAgICAgICAgICBsaXN0U3RhY2sucHVzaCgtMSk7CiAgICAgICAgICAgICAgICAgICAgaW5kZW50ICs9IElOREVOVDsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgT0w6CiAgICAgICAgICAgICAgICAgICAgcmVmbG93VGlsbE5vdygpOwogICAgICAgICAgICAgICAgICAgIGxpc3RTdGFjay5wdXNoKDEpOwogICAgICAgICAgICAgICAgICAgIGluZGVudCArPSBJTkRFTlQ7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIERMOgogICAgICAgICAgICAgICAgICAgIHJlZmxvd1RpbGxOb3coKTsKICAgICAgICAgICAgICAgICAgICBkZWZTdGFjay5wdXNoKGluZGVudCk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIExJOgogICAgICAgICAgICAgICAgICAgIHJlZmxvd1RpbGxOb3coKTsKICAgICAgICAgICAgICAgICAgICBpZiAoIWxpc3RTdGFjay5lbXB0eSgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGFkZE5ld0xpbmVJZk5lZWRlZChyZXN1bHQpOwoKICAgICAgICAgICAgICAgICAgICAgICAgaW50IHRvcCA9IGxpc3RTdGFjay5wb3AoKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0b3AgPT0gKC0xKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0LmFwcGVuZChpbmRlbnRTdHJpbmcoaW5kZW50IC0gMikpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0LmFwcGVuZCgiKiAiKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoaW5kZW50U3RyaW5nKGluZGVudCAtIDMpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoIiIgKyB0b3ArKyArICIuICIpOwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICBsaXN0U3RhY2sucHVzaCh0b3ApOwoKICAgICAgICAgICAgICAgICAgICAgICAgcmVmbG93blRvID0gcmVzdWx0Lmxlbmd0aCgpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgRFQ6CiAgICAgICAgICAgICAgICAgICAgcmVmbG93VGlsbE5vdygpOwogICAgICAgICAgICAgICAgICAgIGlmICghZGVmU3RhY2suaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGFkZE5ld0xpbmVJZk5lZWRlZChyZXN1bHQpOwogICAgICAgICAgICAgICAgICAgICAgICBpbmRlbnQgPSBkZWZTdGFjay5wZWVrKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoZXNjYXBlKENPREVfSElHSExJR0hUKSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBERDoKICAgICAgICAgICAgICAgICAgICByZWZsb3dUaWxsTm93KCk7CiAgICAgICAgICAgICAgICAgICAgaWYgKCFkZWZTdGFjay5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGluZGVudCA9PSBkZWZTdGFjay5wZWVrKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoZXNjYXBlKENPREVfUkVTRVQpKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBhZGROZXdMaW5lSWZOZWVkZWQocmVzdWx0KTsKICAgICAgICAgICAgICAgICAgICAgICAgaW5kZW50ID0gZGVmU3RhY2sucGVlaygpICsgSU5ERU5UOwogICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQuYXBwZW5kKGluZGVudFN0cmluZyhpbmRlbnQpKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIEgxOiBjYXNlIEgyOiBjYXNlIEgzOgogICAgICAgICAgICAgICAgY2FzZSBINDogY2FzZSBINTogY2FzZSBINjoKICAgICAgICAgICAgICAgICAgICByZWZsb3dUaWxsTm93KCk7CiAgICAgICAgICAgICAgICAgICAgYWRkTmV3TGluZUlmTmVlZGVkKHJlc3VsdCk7CiAgICAgICAgICAgICAgICAgICAgcmVzdWx0LmFwcGVuZCgiXG4iKQogICAgICAgICAgICAgICAgICAgICAgICAgIC5hcHBlbmQoZXNjYXBlKENPREVfVU5ERVJMSU5FKSk7CiAgICAgICAgICAgICAgICAgICAgcmVmbG93blRvID0gcmVzdWx0Lmxlbmd0aCgpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBUQUJMRToKICAgICAgICAgICAgICAgICAgICBpbnQgY29sdW1ucyA9IHRhYmxlQ29sdW1ucy5nZXQobm9kZSk7CgogICAgICAgICAgICAgICAgICAgIGlmIChjb2x1bW5zID09IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7IC8vYnJva2VuIGlucHV0CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICByZWZsb3dUaWxsTm93KCk7CiAgICAgICAgICAgICAgICAgICAgYWRkTmV3TGluZUlmTmVlZGVkKHJlc3VsdCk7CiAgICAgICAgICAgICAgICAgICAgcmVmbG93blRvID0gcmVzdWx0Lmxlbmd0aCgpOwoKICAgICAgICAgICAgICAgICAgICB0YWJsZVN0YWNrLnB1c2gobGltaXQpOwoKICAgICAgICAgICAgICAgICAgICBsaW1pdCA9IChsaW1pdCAtIDEpIC8gY29sdW1ucyAtIDM7CgogICAgICAgICAgICAgICAgICAgIGZvciAoaW50IHNlcCA9IDA7IHNlcCA8IChsaW1pdCArIDMpICogY29sdW1ucyArIDE7IHNlcCsrKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoIi0iKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoIlxuIik7CgogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBUUjoKICAgICAgICAgICAgICAgICAgICBpZiAoY2VsbHNTdGFjay5zaXplKCkgPj0gdGFibGVTdGFjay5zaXplKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy91bmNsb3NlZCA8dHI+OgogICAgICAgICAgICAgICAgICAgICAgICBoYW5kbGVFbmRFbGVtZW50KG5vZGUuZ2V0TmFtZSgpKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgY2VsbHNTdGFjay5wdXNoKG5ldyBBcnJheUxpc3Q8PigpKTsKICAgICAgICAgICAgICAgICAgICBoZWFkZXJTdGFjay5wdXNoKG5ldyBBcnJheUxpc3Q8PigpKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgVEg6CiAgICAgICAgICAgICAgICBjYXNlIFREOgogICAgICAgICAgICAgICAgICAgIGlmIChjZWxsc1N0YWNrLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgICAgICAgICAgICAvL2Jyb2tlbiBjb2RlCiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICByZWZsb3dUaWxsTm93KCk7CiAgICAgICAgICAgICAgICAgICAgcmVzdWx0LmFwcGVuZCgiXG4iKTsKICAgICAgICAgICAgICAgICAgICByZWZsb3duVG8gPSByZXN1bHQubGVuZ3RoKCk7CiAgICAgICAgICAgICAgICAgICAgY2VsbHNTdGFjay5wZWVrKCkuYWRkKHJlc3VsdC5sZW5ndGgoKSk7CiAgICAgICAgICAgICAgICAgICAgaGVhZGVyU3RhY2sucGVlaygpLmFkZChIdG1sVGFnLmdldChub2RlLmdldE5hbWUoKSkgPT0gSHRtbFRhZy5USCk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIElNRzoKICAgICAgICAgICAgICAgICAgICBmb3IgKERvY1RyZWUgYXR0ciA6IG5vZGUuZ2V0QXR0cmlidXRlcygpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhdHRyLmdldEtpbmQoKSAhPSBEb2NUcmVlLktpbmQuQVRUUklCVVRFKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBBdHRyaWJ1dGVUcmVlIGF0ID0gKEF0dHJpYnV0ZVRyZWUpIGF0dHI7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgiYWx0Ii5lcXVhbHMoU3RyaW5nVXRpbHMudG9Mb3dlckNhc2UoYXQuZ2V0TmFtZSgpLnRvU3RyaW5nKCkpKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkU3BhY2VJZk5lZWRlZChyZXN1bHQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NhbihhdC5nZXRWYWx1ZSgpLCBudWxsKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZFNwYWNlSWZOZWVkZWQocmVzdWx0KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICBhZGRTcGFjZUlmTmVlZGVkKHJlc3VsdCk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgT2JqZWN0IHZpc2l0RW5kRWxlbWVudChFbmRFbGVtZW50VHJlZSBub2RlLCBPYmplY3QgcCkgewogICAgICAgICAgICBoYW5kbGVFbmRFbGVtZW50KG5vZGUuZ2V0TmFtZSgpKTsKICAgICAgICAgICAgcmV0dXJuIHN1cGVyLnZpc2l0RW5kRWxlbWVudChub2RlLCBwKTsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgdm9pZCBoYW5kbGVFbmRFbGVtZW50KE5hbWUgbmFtZSkgewogICAgICAgICAgICBzd2l0Y2ggKGdldEh0bWxUYWcobmFtZSkpIHsKICAgICAgICAgICAgICAgIGNhc2UgQkxPQ0tRVU9URToKICAgICAgICAgICAgICAgICAgICBpbmRlbnQgLT0gSU5ERU5UOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBQUkU6CiAgICAgICAgICAgICAgICAgICAgcHJlID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgYWRkTmV3TGluZUlmTmVlZGVkKHJlc3VsdCk7CiAgICAgICAgICAgICAgICAgICAgcmVmbG93blRvID0gcmVzdWx0Lmxlbmd0aCgpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBVTDogY2FzZSBPTDoKICAgICAgICAgICAgICAgICAgICBpZiAobGlzdFN0YWNrLmlzRW1wdHkoKSkgeyAvL2lnbm9yZSBzdHJheSBjbG9zaW5nIHRhZwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgcmVmbG93VGlsbE5vdygpOwogICAgICAgICAgICAgICAgICAgIGxpc3RTdGFjay5wb3AoKTsKICAgICAgICAgICAgICAgICAgICBpbmRlbnQgLT0gSU5ERU5UOwogICAgICAgICAgICAgICAgICAgIGFkZE5ld0xpbmVJZk5lZWRlZChyZXN1bHQpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBETDoKICAgICAgICAgICAgICAgICAgICBpZiAoZGVmU3RhY2suaXNFbXB0eSgpKSB7Ly9pZ25vcmUgc3RyYXkgY2xvc2luZyB0YWcKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHJlZmxvd1RpbGxOb3coKTsKICAgICAgICAgICAgICAgICAgICBpZiAoaW5kZW50ID09IGRlZlN0YWNrLnBlZWsoKSkgewogICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQuYXBwZW5kKGVzY2FwZShDT0RFX1JFU0VUKSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGluZGVudCA9IGRlZlN0YWNrLnBvcCgpOwogICAgICAgICAgICAgICAgICAgIGFkZE5ld0xpbmVJZk5lZWRlZChyZXN1bHQpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBIMTogY2FzZSBIMjogY2FzZSBIMzoKICAgICAgICAgICAgICAgIGNhc2UgSDQ6IGNhc2UgSDU6IGNhc2UgSDY6CiAgICAgICAgICAgICAgICAgICAgcmVmbG93VGlsbE5vdygpOwogICAgICAgICAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoZXNjYXBlKENPREVfUkVTRVQpKQogICAgICAgICAgICAgICAgICAgICAgICAgIC5hcHBlbmQoIlxuIik7CiAgICAgICAgICAgICAgICAgICAgcmVmbG93blRvID0gcmVzdWx0Lmxlbmd0aCgpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBUQUJMRToKICAgICAgICAgICAgICAgICAgICBpZiAoY2VsbHNTdGFjay5zaXplKCkgPj0gdGFibGVTdGFjay5zaXplKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy91bmNsb3NlZCA8dHI+OgogICAgICAgICAgICAgICAgICAgICAgICBoYW5kbGVFbmRFbGVtZW50KHRhc2suZ2V0RWxlbWVudHMoKS5nZXROYW1lKCJ0ciIpKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGlmICh0YWJsZVN0YWNrLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGxpbWl0ID0gdGFibGVTdGFjay5wb3AoKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgVFI6CiAgICAgICAgICAgICAgICAgICAgaWYgKGNlbGxzU3RhY2suaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgcmVmbG93VGlsbE5vdygpOwoKICAgICAgICAgICAgICAgICAgICBMaXN0PEludGVnZXI+IGNlbGxzID0gY2VsbHNTdGFjay5wb3AoKTsKICAgICAgICAgICAgICAgICAgICBMaXN0PEJvb2xlYW4+IGhlYWRlckZsYWdzID0gaGVhZGVyU3RhY2sucG9wKCk7CiAgICAgICAgICAgICAgICAgICAgTGlzdDxTdHJpbmdbXT4gY29udGVudCA9IG5ldyBBcnJheUxpc3Q8PigpOwogICAgICAgICAgICAgICAgICAgIGludCBtYXhMaW5lcyA9IDA7CgogICAgICAgICAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoIlxuIik7CgogICAgICAgICAgICAgICAgICAgIHdoaWxlICghY2VsbHMuaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGludCBjdXJyZW50Q2VsbCA9IGNlbGxzLnJlbW92ZShjZWxscy5zaXplKCkgLSAxKTsKICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nW10gbGluZXMgPSByZXN1bHQuc3Vic3RyaW5nKGN1cnJlbnRDZWxsLCByZXN1bHQubGVuZ3RoKCkpLnNwbGl0KCJcbiIpOwoKICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0LmRlbGV0ZShjdXJyZW50Q2VsbCAtIDEsIHJlc3VsdC5sZW5ndGgoKSk7CgogICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50LmFkZChsaW5lcyk7CiAgICAgICAgICAgICAgICAgICAgICAgIG1heExpbmVzID0gTWF0aC5tYXgobWF4TGluZXMsIGxpbmVzLmxlbmd0aCk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBDb2xsZWN0aW9ucy5yZXZlcnNlKGNvbnRlbnQpOwoKICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBsaW5lID0gMDsgbGluZSA8IG1heExpbmVzOyBsaW5lKyspIHsKICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgY29sdW1uID0gMDsgY29sdW1uIDwgY29udGVudC5zaXplKCk7IGNvbHVtbisrKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmdbXSBsaW5lcyA9IGNvbnRlbnQuZ2V0KGNvbHVtbik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgY3VycmVudExpbmUgPSBsaW5lIDwgbGluZXMubGVuZ3RoID8gbGluZXNbbGluZV0gOiAiIjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoInwgIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGhlYWRlciA9IGhlYWRlckZsYWdzLmdldChjb2x1bW4pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGhlYWRlcikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoZXNjYXBlKENPREVfSElHSExJR0hUKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQuYXBwZW5kKGN1cnJlbnRMaW5lKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChoZWFkZXIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQuYXBwZW5kKGVzY2FwZShDT0RFX1JFU0VUKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgcGFkZGluZyA9IGxpbWl0IC0gY3VycmVudExpbmUubGVuZ3RoKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocGFkZGluZyA+IDApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0LmFwcGVuZChpbmRlbnRTdHJpbmcocGFkZGluZykpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0LmFwcGVuZCgiICIpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoInxcbiIpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgc2VwID0gMDsgc2VwIDwgKGxpbWl0ICsgMykgKiBjb250ZW50LnNpemUoKSArIDE7IHNlcCsrKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoIi0iKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoIlxuIik7CgogICAgICAgICAgICAgICAgICAgIHJlZmxvd25UbyA9IHJlc3VsdC5sZW5ndGgoKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgVEQ6CiAgICAgICAgICAgICAgICBjYXNlIFRIOgogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICBhZGRTcGFjZUlmTmVlZGVkKHJlc3VsdCk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBPYmplY3QgdmlzaXRFbnRpdHkoRW50aXR5VHJlZSBub2RlLCBPYmplY3QgcCkgewogICAgICAgICAgICBTdHJpbmcgbmFtZSA9IG5vZGUuZ2V0TmFtZSgpLnRvU3RyaW5nKCk7CiAgICAgICAgICAgIGludCBjb2RlID0gLTE7CiAgICAgICAgICAgIGlmIChuYW1lLnN0YXJ0c1dpdGgoIiMiKSkgewogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICBpbnQgdiA9IFN0cmluZ1V0aWxzLnRvTG93ZXJDYXNlKG5hbWUpLnN0YXJ0c1dpdGgoIiN4IikKICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gSW50ZWdlci5wYXJzZUludChuYW1lLnN1YnN0cmluZygyKSwgMTYpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IEludGVnZXIucGFyc2VJbnQobmFtZS5zdWJzdHJpbmcoMSksIDEwKTsKICAgICAgICAgICAgICAgICAgICBpZiAoRW50aXR5LmlzVmFsaWQodikpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY29kZSA9IHY7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGV4KSB7CiAgICAgICAgICAgICAgICAgICAgLy9pZ25vcmUKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIEVudGl0eSBlbnRpdHkgPSBFbnRpdHkuZ2V0KG5hbWUpOwogICAgICAgICAgICAgICAgaWYgKGVudGl0eSAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgY29kZSA9IGVudGl0eS5jb2RlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChjb2RlICE9ICgtMSkpIHsKICAgICAgICAgICAgICAgIHJlc3VsdC5hcHBlbmRDb2RlUG9pbnQoY29kZSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICByZXN1bHQuYXBwZW5kKG5vZGUudG9TdHJpbmcoKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHN1cGVyLnZpc2l0RW50aXR5KG5vZGUsIHApOwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBEb2NUcmVlIGxhc3ROb2RlOwoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgT2JqZWN0IHNjYW4oRG9jVHJlZSBub2RlLCBPYmplY3QgcCkgewogICAgICAgICAgICBpZiAobm9kZSBpbnN0YW5jZW9mIElubGluZVRhZ1RyZWUpIHsKICAgICAgICAgICAgICAgIGFkZFNwYWNlSWZOZWVkZWQocmVzdWx0KTsKICAgICAgICAgICAgfQogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgcmV0dXJuIHN1cGVyLnNjYW4obm9kZSwgcCk7CiAgICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgICAgICBpZiAobm9kZSBpbnN0YW5jZW9mIElubGluZVRhZ1RyZWUpIHsKICAgICAgICAgICAgICAgICAgICBhZGRTcGFjZUlmTmVlZGVkKHJlc3VsdCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBsYXN0Tm9kZSA9IG5vZGU7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHByaXZhdGUgdm9pZCByZWZsb3dUaWxsTm93KCkgewogICAgICAgICAgICB3aGlsZSAocmVzdWx0Lmxlbmd0aCgpID4gMCAmJiByZXN1bHQuY2hhckF0KHJlc3VsdC5sZW5ndGgoKSAtIDEpID09ICcgJykKICAgICAgICAgICAgICAgIHJlc3VsdC5kZWxldGUocmVzdWx0Lmxlbmd0aCgpIC0gMSwgcmVzdWx0Lmxlbmd0aCgpKTsKICAgICAgICAgICAgcmVmbG93KHJlc3VsdCwgcmVmbG93blRvLCBpbmRlbnQsIGxpbWl0KTsKICAgICAgICAgICAgcmVmbG93blRvID0gcmVzdWx0Lmxlbmd0aCgpOwogICAgICAgIH0KICAgIH07CgogICAgcHJpdmF0ZSBTdHJpbmcgZXNjYXBlKFN0cmluZyBzZXF1ZW5jZSkgewogICAgICAgIHJldHVybiB0aGlzLmVzY2FwZVNlcXVlbmNlc1N1cHBvcnRlZCA/IHNlcXVlbmNlIDogIiI7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgTWFwPFNlY3Rpb25zLCBTdHJpbmc+IGRvY1NlY3Rpb25zID0gbmV3IExpbmtlZEhhc2hNYXA8PigpOwoKICAgIHN0YXRpYyB7CiAgICAgICAgUmVzb3VyY2VCdW5kbGUgYnVuZGxlID0KICAgICAgICAgICAgICAgIFJlc291cmNlQnVuZGxlLmdldEJ1bmRsZSgiamRrLmludGVybmFsLnNoZWxsc3VwcG9ydC5kb2MucmVzb3VyY2VzLmphdmFkb2Nmb3JtYXR0ZXIiKTsKICAgICAgICBkb2NTZWN0aW9ucy5wdXQoU2VjdGlvbnMuVFlQRV9QQVJBTVMsIGJ1bmRsZS5nZXRTdHJpbmcoIkNBUF9UeXBlUGFyYW1ldGVycyIpKTsKICAgICAgICBkb2NTZWN0aW9ucy5wdXQoU2VjdGlvbnMuUEFSQU1TLCBidW5kbGUuZ2V0U3RyaW5nKCJDQVBfUGFyYW1ldGVycyIpKTsKICAgICAgICBkb2NTZWN0aW9ucy5wdXQoU2VjdGlvbnMuUkVUVVJOUywgYnVuZGxlLmdldFN0cmluZygiQ0FQX1JldHVybnMiKSk7CiAgICAgICAgZG9jU2VjdGlvbnMucHV0KFNlY3Rpb25zLlRIUk9XUywgYnVuZGxlLmdldFN0cmluZygiQ0FQX1Rocm93bl9FeGNlcHRpb25zIikpOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBpbmRlbnRTdHJpbmcoaW50IGluZGVudCkgewogICAgICAgIGNoYXJbXSBjb250ZW50ID0gbmV3IGNoYXJbaW5kZW50XTsKICAgICAgICBBcnJheXMuZmlsbChjb250ZW50LCAnICcpOwogICAgICAgIHJldHVybiBuZXcgU3RyaW5nKGNvbnRlbnQpOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIHZvaWQgcmVmbG93KFN0cmluZ0J1aWxkZXIgdGV4dCwgaW50IGZyb20sIGludCBpbmRlbnQsIGludCBsaW1pdCkgewogICAgICAgIGludCBsaW5lU3RhcnQgPSBmcm9tOwoKICAgICAgICB3aGlsZSAobGluZVN0YXJ0ID4gMCAmJiB0ZXh0LmNoYXJBdChsaW5lU3RhcnQgLSAxKSAhPSAnXG4nKSB7CiAgICAgICAgICAgIGxpbmVTdGFydC0tOwogICAgICAgIH0KCiAgICAgICAgaW50IGxpbmVDaGFycyA9IGZyb20gLSBsaW5lU3RhcnQ7CiAgICAgICAgaW50IHBvaW50ZXIgPSBmcm9tOwogICAgICAgIGludCBsYXN0U3BhY2UgPSAtMTsKCiAgICAgICAgd2hpbGUgKHBvaW50ZXIgPCB0ZXh0Lmxlbmd0aCgpKSB7CiAgICAgICAgICAgIGlmICh0ZXh0LmNoYXJBdChwb2ludGVyKSA9PSAnICcpCiAgICAgICAgICAgICAgICBsYXN0U3BhY2UgPSBwb2ludGVyOwogICAgICAgICAgICBpZiAobGluZUNoYXJzID49IGxpbWl0KSB7CiAgICAgICAgICAgICAgICBpZiAobGFzdFNwYWNlICE9ICgtMSkpIHsKICAgICAgICAgICAgICAgICAgICB0ZXh0LnNldENoYXJBdChsYXN0U3BhY2UsICdcbicpOwogICAgICAgICAgICAgICAgICAgIHRleHQuaW5zZXJ0KGxhc3RTcGFjZSArIDEsIGluZGVudFN0cmluZyhpbmRlbnQpKTsKICAgICAgICAgICAgICAgICAgICBsaW5lQ2hhcnMgPSBpbmRlbnQgKyBwb2ludGVyIC0gbGFzdFNwYWNlIC0gMTsKICAgICAgICAgICAgICAgICAgICBwb2ludGVyICs9IGluZGVudDsKICAgICAgICAgICAgICAgICAgICBsYXN0U3BhY2UgPSAtMTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBsaW5lQ2hhcnMrKzsKICAgICAgICAgICAgcG9pbnRlcisrOwogICAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGFkZE5ld0xpbmVJZk5lZWRlZChTdHJpbmdCdWlsZGVyIHRleHQpIHsKICAgICAgICBpZiAodGV4dC5sZW5ndGgoKSA+IDAgJiYgdGV4dC5jaGFyQXQodGV4dC5sZW5ndGgoKSAtIDEpICE9ICdcbicpIHsKICAgICAgICAgICAgdGV4dC5hcHBlbmQoIlxuIik7CiAgICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIHZvaWQgYWRkU3BhY2VJZk5lZWRlZChTdHJpbmdCdWlsZGVyIHRleHQpIHsKICAgICAgICBpZiAodGV4dC5sZW5ndGgoKSA9PSAwKQogICAgICAgICAgICByZXR1cm4gOwoKICAgICAgICBjaGFyIGxhc3QgPSB0ZXh0LmNoYXJBdCh0ZXh0Lmxlbmd0aCgpIC0gMSk7CgogICAgICAgIGlmIChsYXN0ICE9ICcgJyAmJiBsYXN0ICE9ICdcbicpIHsKICAgICAgICAgICAgdGV4dC5hcHBlbmQoIiAiKTsKICAgICAgICB9CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgSHRtbFRhZyBnZXRIdG1sVGFnKE5hbWUgbmFtZSkgewogICAgICAgIEh0bWxUYWcgdGFnID0gSHRtbFRhZy5nZXQobmFtZSk7CgogICAgICAgIHJldHVybiB0YWcgIT0gbnVsbCA/IHRhZyA6IEh0bWxUYWcuSFRNTDsgLy91c2luZyBIdG1sVGFnLkhUTUwgYXMgZGVmYXVsdCBuby1vcCB2YWx1ZQogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIE1hcDxTdGFydEVsZW1lbnRUcmVlLCBJbnRlZ2VyPiBjb3VudFRhYmxlQ29sdW1ucyhEb2NDb21tZW50VHJlZSBkY3QpIHsKICAgICAgICBNYXA8U3RhcnRFbGVtZW50VHJlZSwgSW50ZWdlcj4gcmVzdWx0ID0gbmV3IElkZW50aXR5SGFzaE1hcDw+KCk7CgogICAgICAgIG5ldyBEb2NUcmVlU2Nhbm5lcjxWb2lkLCBWb2lkPigpIHsKICAgICAgICAgICAgcHJpdmF0ZSBTdGFydEVsZW1lbnRUcmVlIGN1cnJlbnRUYWJsZTsKICAgICAgICAgICAgcHJpdmF0ZSBpbnQgY3VycmVudE1heENvbHVtbnM7CiAgICAgICAgICAgIHByaXZhdGUgaW50IGN1cnJlbnRSb3dDb2x1bW5zOwoKICAgICAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgICAgIHB1YmxpYyBWb2lkIHZpc2l0U3RhcnRFbGVtZW50KFN0YXJ0RWxlbWVudFRyZWUgbm9kZSwgVm9pZCBwKSB7CiAgICAgICAgICAgICAgICBzd2l0Y2ggKGdldEh0bWxUYWcobm9kZS5nZXROYW1lKCkpKSB7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBUQUJMRTogY3VycmVudFRhYmxlID0gbm9kZTsgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBUUjoKICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudE1heENvbHVtbnMgPSBNYXRoLm1heChjdXJyZW50TWF4Q29sdW1ucywgY3VycmVudFJvd0NvbHVtbnMpOwogICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50Um93Q29sdW1ucyA9IDA7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgVEQ6CiAgICAgICAgICAgICAgICAgICAgY2FzZSBUSDogY3VycmVudFJvd0NvbHVtbnMrKzsgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gc3VwZXIudmlzaXRTdGFydEVsZW1lbnQobm9kZSwgcCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgICAgICBwdWJsaWMgVm9pZCB2aXNpdEVuZEVsZW1lbnQoRW5kRWxlbWVudFRyZWUgbm9kZSwgVm9pZCBwKSB7CiAgICAgICAgICAgICAgICBpZiAoSHRtbFRhZy5nZXQobm9kZS5nZXROYW1lKCkpID09IEh0bWxUYWcuVEFCTEUpIHsKICAgICAgICAgICAgICAgICAgICBjbG9zZVRhYmxlKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gc3VwZXIudmlzaXRFbmRFbGVtZW50KG5vZGUsIHApOwogICAgICAgICAgICB9CgogICAgICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICAgICAgcHVibGljIFZvaWQgdmlzaXREb2NDb21tZW50KERvY0NvbW1lbnRUcmVlIG5vZGUsIFZvaWQgcCkgewogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3VwZXIudmlzaXREb2NDb21tZW50KG5vZGUsIHApOwogICAgICAgICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgICAgICAgICBjbG9zZVRhYmxlKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHByaXZhdGUgdm9pZCBjbG9zZVRhYmxlKCkgewogICAgICAgICAgICAgICAgaWYgKGN1cnJlbnRUYWJsZSAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgcmVzdWx0LnB1dChjdXJyZW50VGFibGUsIE1hdGgubWF4KGN1cnJlbnRNYXhDb2x1bW5zLCBjdXJyZW50Um93Q29sdW1ucykpOwogICAgICAgICAgICAgICAgICAgIGN1cnJlbnRUYWJsZSA9IG51bGw7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9LnNjYW4oZGN0LCBudWxsKTsKCiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KCiAgICBwcml2YXRlIGVudW0gU2VjdGlvbnMgewogICAgICAgIFRZUEVfUEFSQU1TIHsKICAgICAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIG1hdGNoZXMoRG9jVHJlZSB0KSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdC5nZXRLaW5kKCkgPT0gRG9jVHJlZS5LaW5kLlBBUkFNICYmICgoUGFyYW1UcmVlKSB0KS5pc1R5cGVQYXJhbWV0ZXIoKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgUEFSQU1TIHsKICAgICAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIG1hdGNoZXMoRG9jVHJlZSB0KSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdC5nZXRLaW5kKCkgPT0gRG9jVHJlZS5LaW5kLlBBUkFNICYmICEoKFBhcmFtVHJlZSkgdCkuaXNUeXBlUGFyYW1ldGVyKCk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIFJFVFVSTlMgewogICAgICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gbWF0Y2hlcyhEb2NUcmVlIHQpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0LmdldEtpbmQoKSA9PSBEb2NUcmVlLktpbmQuUkVUVVJOOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBUSFJPV1MgewogICAgICAgICAgICBAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gbWF0Y2hlcyhEb2NUcmVlIHQpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0LmdldEtpbmQoKSA9PSBEb2NUcmVlLktpbmQuVEhST1dTOwogICAgICAgICAgICB9CiAgICAgICAgfTsKCiAgICAgICAgcHVibGljIGFic3RyYWN0IGJvb2xlYW4gbWF0Y2hlcyhEb2NUcmVlIHQpOwogICAgfQp9ClBLAwQKAAAIAADSfU1KAAAAAAAAAAAAAAAABAAAAGNvbS9QSwMECgAACAAA0n1NSgAAAAAAAAAAAAAAAAgAAABjb20vc3VuL1BLAwQKAAAIAADSfU1KAAAAAAAAAAAAAAAADwAAAGNvbS9zdW4vc291cmNlL1BLAwQKAAAIAAAGO6lKAAAAAAAAAAAAAAAAFAAAAGNvbS9zdW4vc291cmNlL3RyZWUvUEsDBAoAAAgAAAY7qUqePtT1nAYAAJwGAAAqAAAAY29tL3N1bi9zb3VyY2UvdHJlZS9QcmltaXRpdmVUeXBlVHJlZS5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDA1LCAyMDE0LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4uc291cmNlLnRyZWU7CgppbXBvcnQgamF2YXgubGFuZy5tb2RlbC50eXBlLlR5cGVLaW5kOwoKLyoqCiAqIEEgdHJlZSBub2RlIGZvciBhIHByaW1pdGl2ZSB0eXBlLgogKgogKiBGb3IgZXhhbXBsZToKICogPHByZT4KICogICA8ZW0+cHJpbWl0aXZlVHlwZUtpbmQ8L2VtPgogKiA8L3ByZT4KICoKICogQGpscyBzZWN0aW9uIDQuMgogKgogKiBAYXV0aG9yIFBldGVyIHZvbiBkZXIgQWgmZWFjdXRlOwogKiBAYXV0aG9yIEpvbmF0aGFuIEdpYmJvbnMKICogQHNpbmNlIDEuNgogKi8KcHVibGljIGludGVyZmFjZSBQcmltaXRpdmVUeXBlVHJlZSBleHRlbmRzIFRyZWUgewogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBraW5kIG9mIHRoaXMgcHJpbWl0aXZlIHR5cGUuCiAgICAgKiBAcmV0dXJuIHRoZSBraW5kIG9mIHRoZSB0eXBlCiAgICAgKi8KICAgIFR5cGVLaW5kIGdldFByaW1pdGl2ZVR5cGVLaW5kKCk7Cn0KUEsDBAoAAAgAAAY7qUoEAOeaHgcAAB4HAAAiAAAAY29tL3N1bi9zb3VyY2UvdHJlZS9VbmFyeVRyZWUuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAxNCwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnNvdXJjZS50cmVlOwoKLyoqCiAqIEEgdHJlZSBub2RlIGZvciBwb3N0Zml4IGFuZCB1bmFyeSBleHByZXNzaW9ucy4KICogVXNlIHtAbGluayAjZ2V0S2luZCBnZXRLaW5kfSB0byBkZXRlcm1pbmUgdGhlIGtpbmQgb2Ygb3BlcmF0b3IuCiAqCiAqIEZvciBleGFtcGxlOgogKiA8cHJlPgogKiAgIDxlbT5vcGVyYXRvcjwvZW0+IDxlbT5leHByZXNzaW9uPC9lbT4KICoKICogICA8ZW0+ZXhwcmVzc2lvbjwvZW0+IDxlbT5vcGVyYXRvcjwvZW0+CiAqIDwvcHJlPgogKgogKiBAamxzIHNlY3Rpb25zIDE1LjE0IGFuZCAxNS4xNQogKgogKiBAYXV0aG9yIFBldGVyIHZvbiBkZXIgQWgmZWFjdXRlOwogKiBAYXV0aG9yIEpvbmF0aGFuIEdpYmJvbnMKICogQHNpbmNlIDEuNgogKi8KcHVibGljIGludGVyZmFjZSBVbmFyeVRyZWUgZXh0ZW5kcyBFeHByZXNzaW9uVHJlZSB7CiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGV4cHJlc3Npb24gdGhhdCBpcyB0aGUgb3BlcmFuZCBvZiB0aGUgdW5hcnkgb3BlcmF0b3IuCiAgICAgKiBAcmV0dXJuIHRoZSBleHByZXNzaW9uCiAgICAgKi8KICAgIEV4cHJlc3Npb25UcmVlIGdldEV4cHJlc3Npb24oKTsKfQpQSwMECgAACAAABjupSlGJWReHCQAAhwkAACAAAABjb20vc3VuL3NvdXJjZS90cmVlL1RyeVRyZWUuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAxNCwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnNvdXJjZS50cmVlOwoKaW1wb3J0IGphdmEudXRpbC5MaXN0OwoKLyoqCiAqIEEgdHJlZSBub2RlIGZvciBhIHtAY29kZSB0cnl9IHN0YXRlbWVudC4KICoKICogRm9yIGV4YW1wbGU6CiAqIDxwcmU+CiAqICAgdHJ5CiAqICAgICAgIDxlbT5ibG9jazwvZW0+CiAqICAgPGVtPmNhdGNoZXM8L2VtPgogKiAgIGZpbmFsbHkKICogICAgICAgPGVtPmZpbmFsbHlCbG9jazwvZW0+CiAqIDwvcHJlPgogKgogKiBAamxzIHNlY3Rpb24gMTQuMjAKICoKICogQGF1dGhvciBQZXRlciB2b24gZGVyIEFoJmVhY3V0ZTsKICogQGF1dGhvciBKb25hdGhhbiBHaWJib25zCiAqIEBzaW5jZSAxLjYKICovCnB1YmxpYyBpbnRlcmZhY2UgVHJ5VHJlZSBleHRlbmRzIFN0YXRlbWVudFRyZWUgewogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBibG9jayBvZiB0aGUge0Bjb2RlIHRyeX0gc3RhdGVtZW50LgogICAgICogQHJldHVybiB0aGUgYmxvY2sKICAgICAqLwogICAgQmxvY2tUcmVlIGdldEJsb2NrKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGFueSBjYXRjaCBibG9ja3MgcHJvdmlkZWQgaW4gdGhlIHtAY29kZSB0cnl9IHN0YXRlbWVudC4KICAgICAqIFRoZSByZXN1bHQgd2lsbCBiZSBhbiBlbXB0eSBsaXN0IGlmIHRoZXJlIGFyZSBubwogICAgICogY2F0Y2ggYmxvY2tzLgogICAgICogQHJldHVybiB0aGUgY2F0Y2ggYmxvY2tzCiAgICAgKi8KICAgIExpc3Q8PyBleHRlbmRzIENhdGNoVHJlZT4gZ2V0Q2F0Y2hlcygpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgZmluYWxseSBibG9jayBwcm92aWRlZCBpbiB0aGUge0Bjb2RlIHRyeX0gc3RhdGVtZW50LAogICAgICogb3Ige0Bjb2RlIG51bGx9IGlmIHRoZXJlIGlzIG5vbmUuCiAgICAgKiBAcmV0dXJuIHRoZSBmaW5hbGx5IGJsb2NrCiAgICAgKi8KICAgIEJsb2NrVHJlZSBnZXRGaW5hbGx5QmxvY2soKTsKCgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGFueSByZXNvdXJjZSBkZWNsYXJhdGlvbnMgcHJvdmlkZWQgaW4gdGhlIHtAY29kZSB0cnl9IHN0YXRlbWVudC4KICAgICAqIFRoZSByZXN1bHQgd2lsbCBiZSBhbiBlbXB0eSBsaXN0IGlmIHRoZXJlIGFyZSBubwogICAgICogcmVzb3VyY2UgZGVjbGFyYXRpb25zLgogICAgICogQHJldHVybiB0aGUgcmVzb3VyY2UgZGVjbGFyYXRpb25zCiAgICAgKi8KICAgIExpc3Q8PyBleHRlbmRzIFRyZWU+IGdldFJlc291cmNlcygpOwp9ClBLAwQKAAAIAAAGO6lK9RVgkOgGAADoBgAAJQAAAGNvbS9zdW4vc291cmNlL3RyZWUvVHlwZUNhc3RUcmVlLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMTQsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi5zb3VyY2UudHJlZTsKCi8qKgogKiBBIHRyZWUgbm9kZSBmb3IgYSB0eXBlIGNhc3QgZXhwcmVzc2lvbi4KICoKICogRm9yIGV4YW1wbGU6CiAqIDxwcmU+CiAqICAgKCA8ZW0+dHlwZTwvZW0+ICkgPGVtPmV4cHJlc3Npb248L2VtPgogKiA8L3ByZT4KICoKICogQGpscyBzZWN0aW9uIDE1LjE2CiAqCiAqIEBhdXRob3IgUGV0ZXIgdm9uIGRlciBBaCZlYWN1dGU7CiAqIEBhdXRob3IgSm9uYXRoYW4gR2liYm9ucwogKiBAc2luY2UgMS42CiAqLwpwdWJsaWMgaW50ZXJmYWNlIFR5cGVDYXN0VHJlZSBleHRlbmRzIEV4cHJlc3Npb25UcmVlIHsKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgdGFyZ2V0IHR5cGUgb2YgdGhlIGNhc3QuCiAgICAgKiBAcmV0dXJuIHRoZSBjYXN0CiAgICAgKi8KICAgIFRyZWUgZ2V0VHlwZSgpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgZXhwcmVzc2lvbiBiZWluZyBjYXN0LgogICAgICogQHJldHVybiB0aGUgZXhwcmVzc2lvbgogICAgICovCiAgICBFeHByZXNzaW9uVHJlZSBnZXRFeHByZXNzaW9uKCk7Cn0KUEsDBAoAAAgAAAY7qUrIEJYRygUAAMoFAAAmAAAAY29tL3N1bi9zb3VyY2UvdHJlZS9TdGF0ZW1lbnRUcmVlLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMTMsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi5zb3VyY2UudHJlZTsKCi8qKgogKiBBIHRyZWUgbm9kZSB1c2VkIGFzIHRoZSBiYXNlIGNsYXNzIGZvciB0aGUgZGlmZmVyZW50IGtpbmRzIG9mCiAqIHN0YXRlbWVudHMuCiAqCiAqIEBqbHMgY2hhcHRlciAxNAogKgogKiBAYXV0aG9yIFBldGVyIHZvbiBkZXIgQWgmZWFjdXRlOwogKiBAYXV0aG9yIEpvbmF0aGFuIEdpYmJvbnMKICogQHNpbmNlIDEuNgogKi8KcHVibGljIGludGVyZmFjZSBTdGF0ZW1lbnRUcmVlIGV4dGVuZHMgVHJlZSB7fQpQSwMECgAACAAABjupSmS/IB+HBQAAhwUAACUAAABjb20vc3VuL3NvdXJjZS90cmVlL3BhY2thZ2UtaW5mby5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDA1LCAyMDEzLCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgovKioKICogUHJvdmlkZXMgaW50ZXJmYWNlcyB0byByZXByZXNlbnQgc291cmNlIGNvZGUgYXMgYWJzdHJhY3Qgc3ludGF4CiAqIHRyZWVzIChBU1QpLgogKgogKiBAYXV0aG9yIFBldGVyIHZvbiBkZXIgQWgmZWFjdXRlOwogKiBAYXV0aG9yIEpvbmF0aGFuIEdpYmJvbnMKICogQHNpbmNlIDEuNgogKi8KcGFja2FnZSBjb20uc3VuLnNvdXJjZS50cmVlOwpQSwMECgAACAAABjupSjgAWPvHBwAAxwcAACIAAABjb20vc3VuL3NvdXJjZS90cmVlL09wZW5zVHJlZS5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDA5LCAyMDE2LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4uc291cmNlLnRyZWU7CgppbXBvcnQgamF2YS51dGlsLkxpc3Q7CgovKioKICogQSB0cmVlIG5vZGUgZm9yIGFuICdvcGVucycgZGlyZWN0aXZlIGluIGEgbW9kdWxlIGRlY2xhcmF0aW9uLgogKgogKiBGb3IgZXhhbXBsZToKICogPHByZT4KICogICAgb3BlbnMgICA8ZW0+cGFja2FnZS1uYW1lPC9lbT47CiAqICAgIG9wZW5zICAgPGVtPnBhY2thZ2UtbmFtZTwvZW0+IHRvIDxlbT5tb2R1bGUtbmFtZTwvZW0+OwogKiA8L3ByZT4KICoKICogQHNpbmNlIDkKICovCnB1YmxpYyBpbnRlcmZhY2UgT3BlbnNUcmVlIGV4dGVuZHMgRGlyZWN0aXZlVHJlZSB7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBuYW1lIG9mIHRoZSBwYWNrYWdlIHRvIGJlIG9wZW5lZC4KICAgICAqIEByZXR1cm4gIHRoZSBuYW1lIG9mIHRoZSBwYWNrYWdlIHRvIGJlIG9wZW5lZAogICAgICovCiAgICBFeHByZXNzaW9uVHJlZSBnZXRQYWNrYWdlTmFtZSgpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgbmFtZXMgb2YgdGhlIG1vZHVsZXMgdG8gd2hpY2ggdGhlIHBhY2thZ2UgaXMgb3BlbmVkLAogICAgICogb3IgbnVsbCwgaWYgdGhlIHBhY2thZ2UgaXMgb3BlbmVkIHRvIGFsbCBtb2R1bGVzLgogICAgICoKICAgICAqIEByZXR1cm4gdGhlIG5hbWVzIG9mIHRoZSBtb2R1bGVzIHRvIHdoaWNoIHRoZSBwYWNrYWdlIGlzIG9wZW5lZCwgb3IgbnVsbAogICAgICovCiAgICBMaXN0PD8gZXh0ZW5kcyBFeHByZXNzaW9uVHJlZT4gZ2V0TW9kdWxlTmFtZXMoKTsKfQpQSwMECgAACAAABjupSqBIOJK9BgAAvQYAACoAAABjb20vc3VuL3NvdXJjZS90cmVlL1BhcmVudGhlc2l6ZWRUcmVlLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMTQsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi5zb3VyY2UudHJlZTsKCi8qKgogKiBBIHRyZWUgbm9kZSBmb3IgYSBwYXJlbnRoZXNpemVkIGV4cHJlc3Npb24uICBOb3RlOiBwYXJlbnRoZXNlcwogKiBub3QgYmUgcHJlc2VydmVkIGJ5IHRoZSBwYXJzZXIuCiAqCiAqIEZvciBleGFtcGxlOgogKiA8cHJlPgogKiAgICggPGVtPmV4cHJlc3Npb248L2VtPiApCiAqIDwvcHJlPgogKgogKiBAamxzIHNlY3Rpb24gMTUuOC41CiAqCiAqIEBhdXRob3IgUGV0ZXIgdm9uIGRlciBBaCZlYWN1dGU7CiAqIEBhdXRob3IgSm9uYXRoYW4gR2liYm9ucwogKiBAc2luY2UgMS42CiAqLwpwdWJsaWMgaW50ZXJmYWNlIFBhcmVudGhlc2l6ZWRUcmVlIGV4dGVuZHMgRXhwcmVzc2lvblRyZWUgewogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBleHByZXNzaW9uIHdpdGhpbiB0aGUgcGFyZW50aGVzZXMuCiAgICAgKiBAcmV0dXJuIHRoZSBleHByZXNzaW9uCiAgICAgKi8KICAgIEV4cHJlc3Npb25UcmVlIGdldEV4cHJlc3Npb24oKTsKfQpQSwMECgAACAAABjupSqt3o3hTBgAAUwYAACYAAABjb20vc3VuL3NvdXJjZS90cmVlL0FycmF5VHlwZVRyZWUuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAxNCwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnNvdXJjZS50cmVlOwoKLyoqCiAqIEEgdHJlZSBub2RlIGZvciBhbiBhcnJheSB0eXBlLgogKgogKiBGb3IgZXhhbXBsZToKICogPHByZT4KICogICA8ZW0+dHlwZTwvZW0+IFtdCiAqIDwvcHJlPgogKgogKiBAamxzIHNlY3Rpb24gMTAuMQogKgogKiBAYXV0aG9yIFBldGVyIHZvbiBkZXIgQWgmZWFjdXRlOwogKiBAYXV0aG9yIEpvbmF0aGFuIEdpYmJvbnMKICogQHNpbmNlIDEuNgogKi8KcHVibGljIGludGVyZmFjZSBBcnJheVR5cGVUcmVlIGV4dGVuZHMgVHJlZSB7CiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGVsZW1lbnQgdHlwZSBvZiB0aGlzIGFycmF5IHR5cGUuCiAgICAgKiBAcmV0dXJuIHRoZSBlbGVtZW50IHR5cGUKICAgICAqLwogICAgVHJlZSBnZXRUeXBlKCk7Cn0KUEsDBAoAAAgAAAY7qUrhgafqDwoAAA8KAAAlAAAAY29tL3N1bi9zb3VyY2UvdHJlZS9OZXdBcnJheVRyZWUuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAxNCwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnNvdXJjZS50cmVlOwoKaW1wb3J0IGphdmEudXRpbC5MaXN0OwoKLyoqCiAqIEEgdHJlZSBub2RlIGZvciBhbiBleHByZXNzaW9uIHRvIGNyZWF0ZSBhIG5ldyBpbnN0YW5jZSBvZiBhbiBhcnJheS4KICoKICogRm9yIGV4YW1wbGU6CiAqIDxwcmU+CiAqICAgbmV3IDxlbT50eXBlPC9lbT4gPGVtPmRpbWVuc2lvbnM8L2VtPiA8ZW0+aW5pdGlhbGl6ZXJzPC9lbT4KICoKICogICBuZXcgPGVtPnR5cGU8L2VtPiA8ZW0+ZGltZW5zaW9uczwvZW0+IFsgXSA8ZW0+aW5pdGlhbGl6ZXJzPC9lbT4KICogPC9wcmU+CiAqCiAqIEBqbHMgc2VjdGlvbiAxNS4xMAogKgogKiBAYXV0aG9yIFBldGVyIHZvbiBkZXIgQWgmZWFjdXRlOwogKiBAYXV0aG9yIEpvbmF0aGFuIEdpYmJvbnMKICogQHNpbmNlIDEuNgogKi8KcHVibGljIGludGVyZmFjZSBOZXdBcnJheVRyZWUgZXh0ZW5kcyBFeHByZXNzaW9uVHJlZSB7CiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGJhc2UgdHlwZSBvZiB0aGUgZXhwcmVzc2lvbi4KICAgICAqIE1heSBiZSB7QGNvZGUgbnVsbH0gZm9yIGFuIGFycmF5IGluaXRpYWxpemVyIGV4cHJlc3Npb24uCiAgICAgKiBAcmV0dXJuIHRoZSBiYXNlIHR5cGUKICAgICAqLwogICAgVHJlZSBnZXRUeXBlKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBkaW1lbnNpb24gZXhwcmVzc2lvbnMgZm9yIHRoZSB0eXBlLgogICAgICoKICAgICAqIEByZXR1cm4gdGhlIGRpbWVuc2lvbiBleHByZXNzaW9ucwogICAgICovCiAgICBMaXN0PD8gZXh0ZW5kcyBFeHByZXNzaW9uVHJlZT4gZ2V0RGltZW5zaW9ucygpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgaW5pdGlhbGl6ZXIgZXhwcmVzc2lvbnMuCiAgICAgKgogICAgICogQHJldHVybiB0aGUgaW5pdGlhbGl6ZXIgZXhwcmVzc2lvbnMKICAgICAqLwogICAgTGlzdDw/IGV4dGVuZHMgRXhwcmVzc2lvblRyZWU+IGdldEluaXRpYWxpemVycygpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgYW5ub3RhdGlvbnMgb24gdGhlIGJhc2UgdHlwZS4KICAgICAqIEByZXR1cm4gdGhlIGFubm90YXRpb25zCiAgICAgKi8KICAgIExpc3Q8PyBleHRlbmRzIEFubm90YXRpb25UcmVlPiBnZXRBbm5vdGF0aW9ucygpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgYW5ub3RhdGlvbnMgb24gZWFjaCBvZiB0aGUgZGltZW5zaW9uCiAgICAgKiBleHByZXNzaW9ucy4KICAgICAqIEByZXR1cm4gdGhlIGFubm90YXRpb25zIG9uIHRoZSBkaW1lbnNpb25zIGV4cHJlc3Npb25zCiAgICAgKi8KICAgIExpc3Q8PyBleHRlbmRzIExpc3Q8PyBleHRlbmRzIEFubm90YXRpb25UcmVlPj4gZ2V0RGltQW5ub3RhdGlvbnMoKTsKfQpQSwMECgAACAAABjupSj/vnZJMBQAATAUAACYAAABjb20vc3VuL3NvdXJjZS90cmVlL0RpcmVjdGl2ZVRyZWUuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAxMSwgMjAxNCwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnNvdXJjZS50cmVlOwoKLyoqCiAqIEEgc3VwZXItdHlwZSBmb3IgYWxsIHRoZSBkaXJlY3RpdmVzIGluIGEgTW9kdWxlVHJlZS4KICovCnB1YmxpYyBpbnRlcmZhY2UgRGlyZWN0aXZlVHJlZSBleHRlbmRzIFRyZWUgeyB9ClBLAwQKAAAIAAAGO6lK4etS0nUGAAB1BgAAIgAAAGNvbS9zdW4vc291cmNlL3RyZWUvVGhyb3dUcmVlLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMTQsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi5zb3VyY2UudHJlZTsKCi8qKgogKiBBIHRyZWUgbm9kZSBmb3IgYSB7QGNvZGUgdGhyb3d9IHN0YXRlbWVudC4KICoKICogRm9yIGV4YW1wbGU6CiAqIDxwcmU+CiAqICAgdGhyb3cgPGVtPmV4cHJlc3Npb248L2VtPjsKICogPC9wcmU+CiAqCiAqIEBqbHMgc2VjdGlvbiAxNC4xOAogKgogKiBAYXV0aG9yIFBldGVyIHZvbiBkZXIgQWgmZWFjdXRlOwogKiBAYXV0aG9yIEpvbmF0aGFuIEdpYmJvbnMKICogQHNpbmNlIDEuNgogKi8KcHVibGljIGludGVyZmFjZSBUaHJvd1RyZWUgZXh0ZW5kcyBTdGF0ZW1lbnRUcmVlIHsKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgZXhwcmVzc2lvbiB0byBiZSB0aHJvd24uCiAgICAgKiBAcmV0dXJuIHRoZSBleHByZXNzaW9uCiAgICAgKi8KICAgIEV4cHJlc3Npb25UcmVlIGdldEV4cHJlc3Npb24oKTsKfQpQSwMECgAACAAABjupSjD0+LGKBgAAigYAADAAAABjb20vc3VuL3NvdXJjZS90cmVlL0V4cHJlc3Npb25TdGF0ZW1lbnRUcmVlLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMTQsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi5zb3VyY2UudHJlZTsKCi8qKgogKiBBIHRyZWUgbm9kZSBmb3IgYW4gZXhwcmVzc2lvbiBzdGF0ZW1lbnQuCiAqCiAqIEZvciBleGFtcGxlOgogKiA8cHJlPgogKiAgIDxlbT5leHByZXNzaW9uPC9lbT4gOwogKiA8L3ByZT4KICoKICogQGpscyBzZWN0aW9uIDE0LjgKICoKICogQGF1dGhvciBQZXRlciB2b24gZGVyIEFoJmVhY3V0ZTsKICogQGF1dGhvciBKb25hdGhhbiBHaWJib25zCiAqIEBzaW5jZSAxLjYKICovCnB1YmxpYyBpbnRlcmZhY2UgRXhwcmVzc2lvblN0YXRlbWVudFRyZWUgZXh0ZW5kcyBTdGF0ZW1lbnRUcmVlIHsKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgZXhwcmVzc2lvbiBjb25zdGl0dXRpbmcgdGhpcyBzdGF0ZW1lbnQuCiAgICAgKiBAcmV0dXJuIHRoZSBleHByZXNzaW9uCiAgICAgKi8KICAgIEV4cHJlc3Npb25UcmVlIGdldEV4cHJlc3Npb24oKTsKfQpQSwMECgAACAAABjupSg1tiLj8CgAA/AoAACAAAABjb20vc3VuL3NvdXJjZS90cmVlL0xpbmVNYXAuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNiwgMjAxNCwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnNvdXJjZS50cmVlOwoKLyoqCiAqIFByb3ZpZGVzIG1ldGhvZHMgdG8gY29udmVydCBiZXR3ZWVuIGNoYXJhY3RlciBwb3NpdGlvbnMgYW5kIGxpbmUgbnVtYmVycwogKiBmb3IgYSBjb21waWxhdGlvbiB1bml0LgogKgogKiBAc2luY2UgMS42CiAqLwpwdWJsaWMgaW50ZXJmYWNlIExpbmVNYXAgewogICAgLyoqCiAgICAgKiBGaW5kcyB0aGUgc3RhcnQgcG9zaXRpb24gb2YgYSBsaW5lLgogICAgICoKICAgICAqIEBwYXJhbSBsaW5lIGxpbmUgbnVtYmVyIChiZWdpbm5pbmcgYXQgMSkKICAgICAqIEByZXR1cm4gICAgIHBvc2l0aW9uIG9mIGZpcnN0IGNoYXJhY3RlciBpbiBsaW5lCiAgICAgKiBAdGhyb3dzICBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uCiAgICAgKiAgICAgICAgICAgaWYge0Bjb2RlIGxpbmVOdW1iZXIgPCAxfQogICAgICogICAgICAgICAgIGlmIHtAY29kZSBsaW5lTnVtYmVyID4gbm8uIG9mIGxpbmVzfQogICAgICovCiAgICBsb25nIGdldFN0YXJ0UG9zaXRpb24obG9uZyBsaW5lKTsKCiAgICAvKioKICAgICAqIEZpbmRzIHRoZSBwb3NpdGlvbiBjb3JyZXNwb25kaW5nIHRvIGEgKGxpbmUsY29sdW1uKS4KICAgICAqCiAgICAgKiBAcGFyYW0gICBsaW5lICAgIGxpbmUgbnVtYmVyIChiZWdpbm5pbmcgYXQgMSkKICAgICAqIEBwYXJhbSAgIGNvbHVtbiAgdGFiLWV4cGFuZGVkIGNvbHVtbiBudW1iZXIgKGJlZ2lubmluZyAxKQogICAgICoKICAgICAqIEByZXR1cm4gIHBvc2l0aW9uIG9mIGNoYXJhY3RlcgogICAgICogQHRocm93cyAgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbgogICAgICogICAgICAgICAgIGlmIHtAY29kZSBsaW5lIDwgMX0KICAgICAqICAgICAgICAgICBpZiB7QGNvZGUgbGluZSA+IG5vLiBvZiBsaW5lc30KICAgICAqLwogICAgbG9uZyBnZXRQb3NpdGlvbihsb25nIGxpbmUsIGxvbmcgY29sdW1uKTsKCiAgICAvKioKICAgICAqIEZpbmRzIHRoZSBsaW5lIGNvbnRhaW5pbmcgYSBwb3NpdGlvbjsgYSBsaW5lIHRlcm1pbmF0aW9uCiAgICAgKiBjaGFyYWN0ZXIgaXMgb24gdGhlIGxpbmUgaXQgdGVybWluYXRlcy4KICAgICAqCiAgICAgKiBAcGFyYW0gICBwb3MgIGNoYXJhY3RlciBvZmZzZXQgb2YgdGhlIHBvc2l0aW9uCiAgICAgKiBAcmV0dXJuIHRoZSBsaW5lIG51bWJlciBvZiBwb3MgKGZpcnN0IGxpbmUgaXMgMSkKICAgICAqLwogICAgbG9uZyBnZXRMaW5lTnVtYmVyKGxvbmcgcG9zKTsKCiAgICAvKioKICAgICAqIEZpbmRzIHRoZSBjb2x1bW4gZm9yIGEgY2hhcmFjdGVyIHBvc2l0aW9uLgogICAgICogVGFiIGNoYXJhY3RlcnMgcHJlY2VkaW5nIHRoZSBwb3NpdGlvbiBvbiB0aGUgc2FtZSBsaW5lCiAgICAgKiB3aWxsIGJlIGV4cGFuZGVkIHdoZW4gY2FsY3VsYXRpbmcgdGhlIGNvbHVtbiBudW1iZXIuCiAgICAgKgogICAgICogQHBhcmFtICBwb3MgICBjaGFyYWN0ZXIgb2Zmc2V0IG9mIHRoZSBwb3NpdGlvbgogICAgICogQHJldHVybiAgICAgICB0aGUgdGFiLWV4cGFuZGVkIGNvbHVtbiBudW1iZXIgb2YgcG9zIChmaXJzdCBjb2x1bW4gaXMgMSkKICAgICAqLwogICAgbG9uZyBnZXRDb2x1bW5OdW1iZXIobG9uZyBwb3MpOwoKfQpQSwMECgAACAAABjupSkaAMtZ0BwAAdAcAACcAAABjb20vc3VuL3NvdXJjZS90cmVlL0Fubm90YXRpb25UcmVlLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMTQsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi5zb3VyY2UudHJlZTsKCmltcG9ydCBqYXZhLnV0aWwuTGlzdDsKCi8qKgogKiBBIHRyZWUgbm9kZSBmb3IgYW4gYW5ub3RhdGlvbi4KICoKICogRm9yIGV4YW1wbGU6CiAqIDxwcmU+CiAqICAgIHtAY29kZSBAfTxlbT5hbm5vdGF0aW9uVHlwZTwvZW0+CiAqICAgIHtAY29kZSBAfTxlbT5hbm5vdGF0aW9uVHlwZTwvZW0+ICggPGVtPmFyZ3VtZW50czwvZW0+ICkKICogPC9wcmU+CiAqCiAqIEBqbHMgc2VjdGlvbiA5LjcKICoKICogQGF1dGhvciBQZXRlciB2b24gZGVyIEFoJmVhY3V0ZTsKICogQGF1dGhvciBKb25hdGhhbiBHaWJib25zCiAqIEBzaW5jZSAxLjYKICovCnB1YmxpYyBpbnRlcmZhY2UgQW5ub3RhdGlvblRyZWUgZXh0ZW5kcyBFeHByZXNzaW9uVHJlZSB7CiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGFubm90YXRpb24gdHlwZS4KICAgICAqIEByZXR1cm4gdGhlIGFubm90YXRpb24gdHlwZQogICAgICovCiAgICBUcmVlIGdldEFubm90YXRpb25UeXBlKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBhcmd1bWVudHMsIGlmIGFueSwgZm9yIHRoZSBhbm5vdGF0aW9uLgogICAgICogQHJldHVybiB0aGUgYXJndW1lbnRzIGZvciB0aGUgYW5ub3RhdGlvbiB0eXBlCiAgICAgKi8KICAgIExpc3Q8PyBleHRlbmRzIEV4cHJlc3Npb25UcmVlPiBnZXRBcmd1bWVudHMoKTsKfQpQSwMECgAACAAABjupSlneffKTCwAAkwsAAB4AAABjb20vc3VuL3NvdXJjZS90cmVlL1Njb3BlLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDYsIDIwMTQsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi5zb3VyY2UudHJlZTsKCmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuRWxlbWVudDsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC5FeGVjdXRhYmxlRWxlbWVudDsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC5UeXBlRWxlbWVudDsKCi8qKgogKiBJbnRlcmZhY2UgZm9yIGRldGVybWluaW5nIGxvY2FsbHkgYXZhaWxhYmxlIHByb2dyYW0gZWxlbWVudHMsIHN1Y2ggYXMKICogbG9jYWwgdmFyaWFibGVzIGFuZCBpbXBvcnRzLgogKiBVcG9uIGNyZWF0aW9uLCBhIFNjb3BlIGlzIGFzc29jaWF0ZWQgd2l0aCBhIGdpdmVuIHByb2dyYW0gcG9zaXRpb247CiAqIGZvciBleGFtcGxlLCBhIHtAbGlua3BsYWluIFRyZWUgdHJlZSBub2RlfS4gVGhpcyBwb3NpdGlvbiBtYXkgYmUgdXNlZCB0bwogKiBpbmZlciBhbiBlbmNsb3NpbmcgbWV0aG9kIGFuZC9vciBjbGFzcy4KICoKICogPHA+QSBTY29wZSBkb2VzIG5vdCBpdHNlbGYgY29udGFpbiB0aGUgZGV0YWlscyBvZiB0aGUgZWxlbWVudHMgY29ycmVzcG9uZGluZwogKiB0byB0aGUgcGFyYW1ldGVycywgbWV0aG9kcyBhbmQgZmllbGRzIG9mIHRoZSBtZXRob2RzIGFuZCBjbGFzc2VzIGNvbnRhaW5pbmcKICogaXRzIHBvc2l0aW9uLiBIb3dldmVyLCB0aGVzZSBlbGVtZW50cyBjYW4gYmUgZGV0ZXJtaW5lZCBmcm9tIHRoZSBlbmNsb3NpbmcKICogZWxlbWVudHMuCiAqCiAqIDxwPlNjb3BlcyBtYXkgYmUgY29udGFpbmVkIGluIGFuIGVuY2xvc2luZyBzY29wZS4gVGhlIG91dGVybW9zdCBzY29wZSBjb250YWlucwogKiB0aG9zZSBlbGVtZW50cyBhdmFpbGFibGUgdmlhICJzdGFyIGltcG9ydCIgZGVjbGFyYXRpb25zOyB0aGUgc2NvcGUgd2l0aGluIHRoYXQKICogY29udGFpbnMgdGhlIHRvcCBsZXZlbCBlbGVtZW50cyBvZiB0aGUgY29tcGlsYXRpb24gdW5pdCwgaW5jbHVkaW5nIGFueSBuYW1lZAogKiBpbXBvcnRzLgogKgogKiBAc2luY2UgMS42CiAqLwpwdWJsaWMgaW50ZXJmYWNlIFNjb3BlIHsKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgZW5jbG9zaW5nIHNjb3BlLgogICAgICogQHJldHVybiB0aGUgZW5jbG9zaW5nIHNjb3BlCiAgICAgKi8KICAgIHB1YmxpYyBTY29wZSBnZXRFbmNsb3NpbmdTY29wZSgpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgaW5uZXJtb3N0IHR5cGUgZWxlbWVudCBjb250YWluaW5nIHRoZSBwb3NpdGlvbiBvZiB0aGlzIHNjb3BlLgogICAgICogQHJldHVybiB0aGUgaW5uZXJtb3N0IGVuY2xvc2luZyB0eXBlIGVsZW1lbnQKICAgICAqLwogICAgcHVibGljIFR5cGVFbGVtZW50IGdldEVuY2xvc2luZ0NsYXNzKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBpbm5lcm1vc3QgZXhlY3V0YWJsZSBlbGVtZW50IGNvbnRhaW5pbmcgdGhlIHBvc2l0aW9uIG9mIHRoaXMgc2NvcGUuCiAgICAgKiBAcmV0dXJuIHRoZSBpbm5lcm1vc3QgZW5jbG9zaW5nIG1ldGhvZCBkZWNsYXJhdGlvbgogICAgICovCiAgICBwdWJsaWMgRXhlY3V0YWJsZUVsZW1lbnQgZ2V0RW5jbG9zaW5nTWV0aG9kKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBlbGVtZW50cyBkaXJlY3RseSBjb250YWluZWQgaW4gdGhpcyBzY29wZS4KICAgICAqIEByZXR1cm4gdGhlIGVsZW1lbnRzIGNvbnRhaW5lZCBpbiB0aGlzIHNjb3BlCiAgICAgKi8KICAgIHB1YmxpYyBJdGVyYWJsZTw/IGV4dGVuZHMgRWxlbWVudD4gZ2V0TG9jYWxFbGVtZW50cygpOwp9ClBLAwQKAAAIAAAGO6lKgivSB+wGAADsBgAAJAAAAGNvbS9zdW4vc291cmNlL3RyZWUvTGl0ZXJhbFRyZWUuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAxNCwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnNvdXJjZS50cmVlOwoKLyoqCiAqIEEgdHJlZSBub2RlIGZvciBhIGxpdGVyYWwgZXhwcmVzc2lvbi4KICogVXNlIHtAbGluayAjZ2V0S2luZCBnZXRLaW5kfSB0byBkZXRlcm1pbmUgdGhlIGtpbmQgb2YgbGl0ZXJhbC4KICoKICogRm9yIGV4YW1wbGU6CiAqIDxwcmU+CiAqICAgPGVtPnZhbHVlPC9lbT4KICogPC9wcmU+CiAqCiAqIEBqbHMgc2VjdGlvbiAxNS4yOAogKgogKiBAYXV0aG9yIFBldGVyIHZvbiBkZXIgQWgmZWFjdXRlOwogKiBAYXV0aG9yIEpvbmF0aGFuIEdpYmJvbnMKICogQHNpbmNlIDEuNgogKi8KcHVibGljIGludGVyZmFjZSBMaXRlcmFsVHJlZSBleHRlbmRzIEV4cHJlc3Npb25UcmVlIHsKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgdGhlIGxpdGVyYWwgZXhwcmVzc2lvbi4KICAgICAqIFRoZSB2YWx1ZSB3aWxsIGJlIGEgYm94ZWQgcHJpbWl0aXZlIHZhbHVlLCBhIFN0cmluZywgb3Ige0Bjb2RlIG51bGx9LgogICAgICogQHJldHVybiB0aGUgdmFsdWUKICAgICAqLwogICAgT2JqZWN0IGdldFZhbHVlKCk7Cn0KUEsDBAoAAAgAAAY7qUoQl4PovwYAAL8GAAAlAAAAY29tL3N1bi9zb3VyY2UvdHJlZS9XaWxkY2FyZFRyZWUuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAxNCwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnNvdXJjZS50cmVlOwoKLyoqCiAqIEEgdHJlZSBub2RlIGZvciBhIHdpbGRjYXJkIHR5cGUgYXJndW1lbnQuCiAqIFVzZSB7QGxpbmsgI2dldEtpbmQgZ2V0S2luZH0gdG8gZGV0ZXJtaW5lIHRoZSBraW5kIG9mIGJvdW5kLgogKgogKiBGb3IgZXhhbXBsZToKICogPHByZT4KICogICA/CiAqCiAqICAgPyBleHRlbmRzIDxlbT5ib3VuZDwvZW0+CiAqCiAqICAgPyBzdXBlciA8ZW0+Ym91bmQ8L2VtPgogKiA8L3ByZT4KICoKICogQGpscyBzZWN0aW9uIDQuNS4xCiAqCiAqIEBhdXRob3IgUGV0ZXIgdm9uIGRlciBBaCZlYWN1dGU7CiAqIEBhdXRob3IgSm9uYXRoYW4gR2liYm9ucwogKiBAc2luY2UgMS42CiAqLwpwdWJsaWMgaW50ZXJmYWNlIFdpbGRjYXJkVHJlZSBleHRlbmRzIFRyZWUgewogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBib3VuZCBvZiB0aGUgd2lsZGNhcmQuCiAgICAgKiBAcmV0dXJuIHRoZSBib3VuZAogICAgICovCiAgICBUcmVlIGdldEJvdW5kKCk7Cn0KUEsDBAoAAAgAAAY7qUrtpIfERQkAAEUJAAAkAAAAY29tL3N1bi9zb3VyY2UvdHJlZS9Gb3JMb29wVHJlZS5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDA1LCAyMDE0LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4uc291cmNlLnRyZWU7CgppbXBvcnQgamF2YS51dGlsLkxpc3Q7CgovKioKICogQSB0cmVlIG5vZGUgZm9yIGEgYmFzaWMge0Bjb2RlIGZvcn0gbG9vcCBzdGF0ZW1lbnQuCiAqCiAqIEZvciBleGFtcGxlOgogKiA8cHJlPgogKiAgIGZvciAoIDxlbT5pbml0aWFsaXplcjwvZW0+IDsgPGVtPmNvbmRpdGlvbjwvZW0+IDsgPGVtPnVwZGF0ZTwvZW0+ICkKICogICAgICAgPGVtPnN0YXRlbWVudDwvZW0+CiAqIDwvcHJlPgogKgogKiBAamxzIHNlY3Rpb24gMTQuMTQuMQogKgogKiBAYXV0aG9yIFBldGVyIHZvbiBkZXIgQWgmZWFjdXRlOwogKiBAYXV0aG9yIEpvbmF0aGFuIEdpYmJvbnMKICogQHNpbmNlIDEuNgogKi8KcHVibGljIGludGVyZmFjZSBGb3JMb29wVHJlZSBleHRlbmRzIFN0YXRlbWVudFRyZWUgewogICAgLyoqCiAgICAgKiBSZXR1cm5zIGFueSBpbml0aWFsaXplcnMgb2YgdGhlIHtAY29kZSBmb3J9IHN0YXRlbWVudC4KICAgICAqIFRoZSByZXN1bHQgd2lsbCBiZSBhbiBlbXB0eSBsaXN0IGlmIHRoZXJlIGFyZQogICAgICogbm8gaW5pdGlhbGl6ZXJzCiAgICAgKiBAcmV0dXJuIHRoZSBpbml0aWFsaXplcnMKICAgICAqLwogICAgTGlzdDw/IGV4dGVuZHMgU3RhdGVtZW50VHJlZT4gZ2V0SW5pdGlhbGl6ZXIoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGNvbmRpdGlvbiBvZiB0aGUge0Bjb2RlIGZvcn0gc3RhdGVtZW50LgogICAgICogTWF5IGJlIHtAY29kZSBudWxsfSBpZiB0aGVyZSBpcyBubyBjb25kaXRpb24uCiAgICAgKiBAcmV0dXJuIHRoZSBjb25kaXRpb24KICAgICAqLwogICAgRXhwcmVzc2lvblRyZWUgZ2V0Q29uZGl0aW9uKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGFueSB1cGRhdGUgZXhwcmVzc2lvbnMgb2YgdGhlIHtAY29kZSBmb3J9IHN0YXRlbWVudC4KICAgICAqIEByZXR1cm4gdGhlIHVwZGF0ZSBleHByZXNzaW9ucwogICAgICovCiAgICBMaXN0PD8gZXh0ZW5kcyBFeHByZXNzaW9uU3RhdGVtZW50VHJlZT4gZ2V0VXBkYXRlKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBib2R5IG9mIHRoZSB7QGNvZGUgZm9yfSBzdGF0ZW1lbnQuCiAgICAgKiBAcmV0dXJuIHRoZSBib2R5CiAgICAgKi8KICAgIFN0YXRlbWVudFRyZWUgZ2V0U3RhdGVtZW50KCk7Cn0KUEsDBAoAAAgAAAY7qUqc5nKCCgcAAAoHAAAoAAAAY29tL3N1bi9zb3VyY2UvdHJlZS9BcnJheUFjY2Vzc1RyZWUuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAxNCwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnNvdXJjZS50cmVlOwoKLyoqCiAqIEEgdHJlZSBub2RlIGZvciBhbiBhcnJheSBhY2Nlc3MgZXhwcmVzc2lvbi4KICoKICogRm9yIGV4YW1wbGU6CiAqIDxwcmU+CiAqICAgPGVtPmV4cHJlc3Npb248L2VtPiBbIDxlbT5pbmRleDwvZW0+IF0KICogPC9wcmU+CiAqCiAqIEBqbHMgc2VjdGlvbiAxNS4xMwogKgogKiBAYXV0aG9yIFBldGVyIHZvbiBkZXIgQWgmZWFjdXRlOwogKiBAYXV0aG9yIEpvbmF0aGFuIEdpYmJvbnMKICogQHNpbmNlIDEuNgogKi8KcHVibGljIGludGVyZmFjZSBBcnJheUFjY2Vzc1RyZWUgZXh0ZW5kcyBFeHByZXNzaW9uVHJlZSB7CiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGV4cHJlc3Npb24gZm9yIHRoZSBhcnJheSBiZWluZyBhY2Nlc3NlZC4KICAgICAqIEByZXR1cm4gdGhlIGFycmF5CiAgICAgKi8KICAgIEV4cHJlc3Npb25UcmVlIGdldEV4cHJlc3Npb24oKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGV4cHJlc3Npb24gZm9yIHRoZSBpbmRleC4KICAgICAqIEByZXR1cm4gdGhlIGluZGV4CiAgICAgKi8KICAgIEV4cHJlc3Npb25UcmVlIGdldEluZGV4KCk7Cn0KUEsDBAoAAAgAAAY7qUpjsMgZPgYAAD4GAAAhAAAAY29tL3N1bi9zb3VyY2UvdHJlZS9Vc2VzVHJlZS5qYXZhCi8qCiAqIENvcHlyaWdodCAoYykgMjAwOSwgMjAxNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnNvdXJjZS50cmVlOwoKLyoqCiAqIEEgdHJlZSBub2RlIGZvciBhICd1c2VzJyBkaXJlY3RpdmUgaW4gYSBtb2R1bGUgZGVjbGFyYXRpb24uCiAqCiAqIEZvciBleGFtcGxlOgogKiA8cHJlPgogKiAgICB1c2VzIDxlbT5zZXJ2aWNlLW5hbWU8L2VtPjsKICogPC9wcmU+CiAqCiAqIEBzaW5jZSA5CiAqLwpwdWJsaWMgaW50ZXJmYWNlIFVzZXNUcmVlIGV4dGVuZHMgRGlyZWN0aXZlVHJlZSB7CiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIG5hbWUgb2YgdGhlIHNlcnZpY2UgdHlwZS4KICAgICAqIEByZXR1cm4gIHRoZSBuYW1lIG9mIHRoZSBzZXJ2aWNlIHR5cGUKICAgICAqLwogICAgRXhwcmVzc2lvblRyZWUgZ2V0U2VydmljZU5hbWUoKTsKfQpQSwMECgAACAAABjupSsvaOTOiBgAAogYAACIAAABjb20vc3VuL3NvdXJjZS90cmVlL0JyZWFrVHJlZS5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDA1LCAyMDE0LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4uc291cmNlLnRyZWU7CgppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5lbGVtZW50Lk5hbWU7CgovKioKICogQSB0cmVlIG5vZGUgZm9yIGEge0Bjb2RlIGJyZWFrfSBzdGF0ZW1lbnQuCiAqCiAqIEZvciBleGFtcGxlOgogKiA8cHJlPgogKiAgIGJyZWFrOwogKgogKiAgIGJyZWFrIDxlbT5sYWJlbDwvZW0+IDsKICogPC9wcmU+CiAqCiAqIEBqbHMgc2VjdGlvbiAxNC4xNQogKgogKiBAYXV0aG9yIFBldGVyIHZvbiBkZXIgQWgmZWFjdXRlOwogKiBAYXV0aG9yIEpvbmF0aGFuIEdpYmJvbnMKICogQHNpbmNlIDEuNgogKi8KcHVibGljIGludGVyZmFjZSBCcmVha1RyZWUgZXh0ZW5kcyBTdGF0ZW1lbnRUcmVlIHsKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgbGFiZWwgZm9yIHRoaXMge0Bjb2RlIGJyZWFrfSBzdGF0ZW1lbnQuCiAgICAgKiBAcmV0dXJuIHRoZSBsYWJlbAogICAgICovCiAgICBOYW1lIGdldExhYmVsKCk7Cn0KUEsDBAoAAAgAAAY7qUpBtLBIOAoAADgKAAAlAAAAY29tL3N1bi9zb3VyY2UvdHJlZS9OZXdDbGFzc1RyZWUuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAxNCwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnNvdXJjZS50cmVlOwoKaW1wb3J0IGphdmEudXRpbC5MaXN0OwoKLyoqCiAqIEEgdHJlZSBub2RlIHRvIGRlY2xhcmUgYSBuZXcgaW5zdGFuY2Ugb2YgYSBjbGFzcy4KICoKICogRm9yIGV4YW1wbGU6CiAqIDxwcmU+CiAqICAgbmV3IDxlbT5pZGVudGlmaWVyPC9lbT4gKCApCiAqCiAqICAgbmV3IDxlbT5pZGVudGlmaWVyPC9lbT4gKCA8ZW0+YXJndW1lbnRzPC9lbT4gKQogKgogKiAgIG5ldyA8ZW0+dHlwZUFyZ3VtZW50czwvZW0+IDxlbT5pZGVudGlmaWVyPC9lbT4gKCA8ZW0+YXJndW1lbnRzPC9lbT4gKQogKiAgICAgICA8ZW0+Y2xhc3NCb2R5PC9lbT4KICoKICogICA8ZW0+ZW5jbG9zaW5nRXhwcmVzc2lvbjwvZW0+Lm5ldyA8ZW0+aWRlbnRpZmllcjwvZW0+ICggPGVtPmFyZ3VtZW50czwvZW0+ICkKICogPC9wcmU+CiAqCiAqIEBqbHMgc2VjdGlvbiAxNS45CiAqCiAqIEBhdXRob3IgUGV0ZXIgdm9uIGRlciBBaCZlYWN1dGU7CiAqIEBhdXRob3IgSm9uYXRoYW4gR2liYm9ucwogKiBAc2luY2UgMS42CiAqLwpwdWJsaWMgaW50ZXJmYWNlIE5ld0NsYXNzVHJlZSBleHRlbmRzIEV4cHJlc3Npb25UcmVlIHsKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgZW5jbG9zaW5nIGV4cHJlc3Npb24sIG9yIHtAY29kZSBudWxsfSBpZiBub25lLgogICAgICogQHJldHVybiB0aGUgZW5jbG9zaW5nIGV4cHJlc3Npb24KICAgICAqLwogICAgRXhwcmVzc2lvblRyZWUgZ2V0RW5jbG9zaW5nRXhwcmVzc2lvbigpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgdHlwZSBhcmd1bWVudHMgZm9yIHRoZSBvYmplY3QgYmVpbmcgY3JlYXRlZC4KICAgICAqIEByZXR1cm4gdGhlIHR5cGUgYXJndW1lbnRzCiAgICAgKi8KICAgIExpc3Q8PyBleHRlbmRzIFRyZWU+IGdldFR5cGVBcmd1bWVudHMoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIG5hbWUgb2YgdGhlIGNsYXNzIGJlaW5nIGluc3RhbnRpYXRlZC4KICAgICAqIEByZXR1cm4gdGhlIG5hbWUKICAgICAqLwogICAgRXhwcmVzc2lvblRyZWUgZ2V0SWRlbnRpZmllcigpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgYXJndW1lbnRzIGZvciB0aGUgY29uc3RydWN0b3IgdG8gYmUgaW52b2tlZC4KICAgICAqIEByZXR1cm4gdGhlIGFyZ3VtZW50cwogICAgICovCiAgICBMaXN0PD8gZXh0ZW5kcyBFeHByZXNzaW9uVHJlZT4gZ2V0QXJndW1lbnRzKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBjbGFzcyBib2R5IGlmIGFuIGFub255bW91cyBjbGFzcyBpcyBiZWluZwogICAgICogaW5zdGFudGlhdGVkLCBhbmQge0Bjb2RlIG51bGx9IG90aGVyd2lzZS4KICAgICAqIEByZXR1cm4gdGhlIGNsYXNzIGJvZHkKICAgICAqLwogICAgQ2xhc3NUcmVlIGdldENsYXNzQm9keSgpOwp9ClBLAwQKAAAIAAAGO6lKnRabwXYHAAB2BwAAIgAAAGNvbS9zdW4vc291cmNlL3RyZWUvQmxvY2tUcmVlLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMTQsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi5zb3VyY2UudHJlZTsKCmltcG9ydCBqYXZhLnV0aWwuTGlzdDsKCi8qKgogKiBBIHRyZWUgbm9kZSBmb3IgYSBzdGF0ZW1lbnQgYmxvY2suCiAqCiAqIEZvciBleGFtcGxlOgogKiA8cHJlPgogKiAgIHsgfQogKgogKiAgIHsgPGVtPnN0YXRlbWVudHM8L2VtPiB9CiAqCiAqICAgc3RhdGljIHsgPGVtPnN0YXRlbWVudHM8L2VtPiB9CiAqIDwvcHJlPgogKgogKiBAamxzIHNlY3Rpb24gMTQuMgogKgogKiBAYXV0aG9yIFBldGVyIHZvbiBkZXIgQWgmZWFjdXRlOwogKiBAYXV0aG9yIEpvbmF0aGFuIEdpYmJvbnMKICogQHNpbmNlIDEuNgogKi8KcHVibGljIGludGVyZmFjZSBCbG9ja1RyZWUgZXh0ZW5kcyBTdGF0ZW1lbnRUcmVlIHsKICAgIC8qKgogICAgICogUmV0dXJucyB0cnVlIGlmIGFuZCBvbmx5IGlmIHRoaXMgaXMgYSBzdGF0aWMgaW5pdGlhbGl6ZXIgYmxvY2suCiAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhpcyBpcyBhIHN0YXRpYyBpbml0aWFsaXplciBibG9jawogICAgICovCiAgICBib29sZWFuIGlzU3RhdGljKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBzdGF0ZW1lbnRzIGNvbXByaXNpbmcgdGhpcyBibG9jay4KICAgICAqIEByZXR1cm4gdGhlIHN0YXRlbWVudHMKICAgICAqLwogICAgTGlzdDw/IGV4dGVuZHMgU3RhdGVtZW50VHJlZT4gZ2V0U3RhdGVtZW50cygpOwp9ClBLAwQKAAAIAAAGO6lKsequExQJAAAUCQAAKgAAAGNvbS9zdW4vc291cmNlL3RyZWUvVHlwZVBhcmFtZXRlclRyZWUuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAxNCwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnNvdXJjZS50cmVlOwoKaW1wb3J0IGphdmEudXRpbC5MaXN0OwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5lbGVtZW50Lk5hbWU7CgovKioKICogQSB0cmVlIG5vZGUgZm9yIGEgdHlwZSBwYXJhbWV0ZXIuCiAqCiAqIEZvciBleGFtcGxlOgogKiA8cHJlPgogKiAgIDxlbT5uYW1lPC9lbT4KICoKICogICA8ZW0+bmFtZTwvZW0+IGV4dGVuZHMgPGVtPmJvdW5kczwvZW0+CiAqCiAqICAgPGVtPmFubm90YXRpb25zPC9lbT4gPGVtPm5hbWU8L2VtPgogKiA8L3ByZT4KICoKICogQGpscyBzZWN0aW9uIDQuNAogKgogKiBAYXV0aG9yIFBldGVyIHZvbiBkZXIgQWgmZWFjdXRlOwogKiBAYXV0aG9yIEpvbmF0aGFuIEdpYmJvbnMKICogQHNpbmNlIDEuNgogKi8KcHVibGljIGludGVyZmFjZSBUeXBlUGFyYW1ldGVyVHJlZSBleHRlbmRzIFRyZWUgewogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBuYW1lIG9mIHRoZSB0eXBlIHBhcmFtZXRlci4KICAgICAqIEByZXR1cm4gdGhlIG5hbWUKICAgICAqLwogICAgTmFtZSBnZXROYW1lKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBib3VuZHMgb2YgdGhlIHR5cGUgcGFyYW1ldGVyLgogICAgICogQHJldHVybiB0aGUgYm91bmRzCiAgICAgKi8KICAgIExpc3Q8PyBleHRlbmRzIFRyZWU+IGdldEJvdW5kcygpOwoKICAgIC8qKgogICAgICogUmV0dXJucyBhbm5vdGF0aW9ucyBvbiB0aGUgdHlwZSBwYXJhbWV0ZXIgZGVjbGFyYXRpb24uCiAgICAgKgogICAgICogQW5ub3RhdGlvbnMgbmVlZCBUYXJnZXQgbWV0YS1hbm5vdGF0aW9ucyBvZgogICAgICoge0BsaW5rIGphdmEubGFuZy5hbm5vdGF0aW9uLkVsZW1lbnRUeXBlI1RZUEVfUEFSQU1FVEVSfSBvcgogICAgICoge0BsaW5rIGphdmEubGFuZy5hbm5vdGF0aW9uLkVsZW1lbnRUeXBlI1RZUEVfVVNFfQogICAgICogdG8gYXBwZWFyIGluIHRoaXMgcG9zaXRpb24uCiAgICAgKgogICAgICogQHJldHVybiBhbm5vdGF0aW9ucyBvbiB0aGUgdHlwZSBwYXJhbWV0ZXIgZGVjbGFyYXRpb24KICAgICAqIEBzaW5jZSAxLjgKICAgICAqLwogICAgTGlzdDw/IGV4dGVuZHMgQW5ub3RhdGlvblRyZWU+IGdldEFubm90YXRpb25zKCk7Cn0KUEsDBAoAAAgAAAY7qUpvrnyU5AcAAOQHAAAsAAAAY29tL3N1bi9zb3VyY2UvdHJlZS9FbmhhbmNlZEZvckxvb3BUcmVlLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMTQsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi5zb3VyY2UudHJlZTsKCi8qKgogKiBBIHRyZWUgbm9kZSBmb3IgYW4gImVuaGFuY2VkIiB7QGNvZGUgZm9yfSBsb29wIHN0YXRlbWVudC4KICoKICogRm9yIGV4YW1wbGU6CiAqIDxwcmU+CiAqICAgZm9yICggPGVtPnZhcmlhYmxlPC9lbT4gOiA8ZW0+ZXhwcmVzc2lvbjwvZW0+ICkKICogICAgICAgPGVtPnN0YXRlbWVudDwvZW0+CiAqIDwvcHJlPgogKgogKiBAamxzIHNlY3Rpb24gMTQuMTQuMgogKgogKiBAYXV0aG9yIFBldGVyIHZvbiBkZXIgQWgmZWFjdXRlOwogKiBAYXV0aG9yIEpvbmF0aGFuIEdpYmJvbnMKICogQHNpbmNlIDEuNgogKi8KcHVibGljIGludGVyZmFjZSBFbmhhbmNlZEZvckxvb3BUcmVlIGV4dGVuZHMgU3RhdGVtZW50VHJlZSB7CiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGNvbnRyb2wgdmFyaWFibGUgZm9yIHRoZSBsb29wLgogICAgICogQHJldHVybiB0aGUgY29udHJvbCB2YXJpYWJsZQogICAgICovCiAgICBWYXJpYWJsZVRyZWUgZ2V0VmFyaWFibGUoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGV4cHJlc3Npb24geWllbGRpbmcgdGhlIHZhbHVlcyBmb3IgdGhlIGNvbnRyb2wgdmFyaWFibGUuCiAgICAgKiBAcmV0dXJuIHRoZSBleHByZXNzaW9uCiAgICAgKi8KICAgIEV4cHJlc3Npb25UcmVlIGdldEV4cHJlc3Npb24oKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGJvZHkgb2YgdGhlIGxvb3AuCiAgICAgKiBAcmV0dXJuIHRoZSBib2R5IG9mIHRoZSBsb29wCiAgICAgKi8KICAgIFN0YXRlbWVudFRyZWUgZ2V0U3RhdGVtZW50KCk7Cn0KUEsDBAoAAAgAAAY7qUopQsFzXwwAAF8MAAAsAAAAY29tL3N1bi9zb3VyY2UvdHJlZS9Db21waWxhdGlvblVuaXRUcmVlLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMTQsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi5zb3VyY2UudHJlZTsKCmltcG9ydCBqYXZhLnV0aWwuTGlzdDsKaW1wb3J0IGphdmF4LnRvb2xzLkphdmFGaWxlT2JqZWN0OwoKLyoqCiAqIFJlcHJlc2VudHMgdGhlIGFic3RyYWN0IHN5bnRheCB0cmVlIGZvciBjb21waWxhdGlvbiB1bml0cyAoc291cmNlCiAqIGZpbGVzKSBhbmQgcGFja2FnZSBkZWNsYXJhdGlvbnMgKHBhY2thZ2UtaW5mby5qYXZhKS4KICoKICogQGpscyBzZWN0aW9ucyA3LjMsIGFuZCA3LjQKICoKICogQGF1dGhvciBQZXRlciB2b24gZGVyIEFoJmVhY3V0ZTsKICogQHNpbmNlIDEuNgogKi8KcHVibGljIGludGVyZmFjZSBDb21waWxhdGlvblVuaXRUcmVlIGV4dGVuZHMgVHJlZSB7CiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGFubm90YXRpb25zIGxpc3RlZCBvbiBhbnkgcGFja2FnZSBkZWNsYXJhdGlvbgogICAgICogYXQgdGhlIGhlYWQgb2YgdGhpcyBjb21waWxhdGlvbiB1bml0LCBvciB7QGNvZGUgbnVsbH0gaWYgdGhlcmUKICAgICAqIGlzIG5vIHBhY2thZ2UgZGVjbGFyYXRpb24uCiAgICAgKiBAcmV0dXJuIHRoZSBwYWNrYWdlIGFubm90YXRpb25zCiAgICAgKi8KICAgIExpc3Q8PyBleHRlbmRzIEFubm90YXRpb25UcmVlPiBnZXRQYWNrYWdlQW5ub3RhdGlvbnMoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIG5hbWUgY29udGFpbmVkIGluIGFueSBwYWNrYWdlIGRlY2xhcmF0aW9uCiAgICAgKiBhdCB0aGUgaGVhZCBvZiB0aGlzIGNvbXBpbGF0aW9uIHVuaXQsIG9yIHtAY29kZSBudWxsfSBpZiB0aGVyZQogICAgICogaXMgbm8gcGFja2FnZSBkZWNsYXJhdGlvbi4KICAgICAqIEByZXR1cm4gdGhlIHBhY2thZ2UgbmFtZQogICAgICovCiAgICBFeHByZXNzaW9uVHJlZSBnZXRQYWNrYWdlTmFtZSgpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgcGFja2FnZSB0cmVlIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGNvbXBpbGF0aW9uIHVuaXQsCiAgICAgKiBvciB7QGNvZGUgbnVsbH0gaWYgdGhlcmUgaXMgbm8gcGFja2FnZSBkZWNsYXJhdGlvbi4KICAgICAqIEByZXR1cm4gdGhlIHBhY2thZ2UgdHJlZQogICAgICogQHNpbmNlIDkKICAgICAqLwogICAgUGFja2FnZVRyZWUgZ2V0UGFja2FnZSgpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgaW1wb3J0IGRlY2xhcmF0aW9ucyBhcHBlYXJpbmcgaW4gdGhpcyBjb21waWxhdGlvbiB1bml0LgogICAgICogQHJldHVybiB0aGUgaW1wb3J0IGRlY2xhcmF0aW9ucwogICAgICovCiAgICBMaXN0PD8gZXh0ZW5kcyBJbXBvcnRUcmVlPiBnZXRJbXBvcnRzKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSB0eXBlIGRlY2xhcmF0aW9ucyBhcHBlYXJpbmcgaW4gdGhpcyBjb21waWxhdGlvbiB1bml0LgogICAgICogVGhlIGxpc3QgbWF5IGFsc28gaW5jbHVkZSBlbXB0eSBzdGF0ZW1lbnRzIHJlc3VsdGluZyBmcm9tCiAgICAgKiBleHRyYW5lb3VzIHNlbWljb2xvbnMuCiAgICAgKiBAcmV0dXJuIHRoZSB0eXBlIGRlY2xhcmF0aW9ucwogICAgICovCiAgICBMaXN0PD8gZXh0ZW5kcyBUcmVlPiBnZXRUeXBlRGVjbHMoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGZpbGUgb2JqZWN0IGNvbnRhaW5pbmcgdGhlIHNvdXJjZSBmb3IgdGhpcyBjb21waWxhdGlvbiB1bml0LgogICAgICogQHJldHVybiB0aGUgZmlsZSBvYmplY3QKICAgICAqLwogICAgSmF2YUZpbGVPYmplY3QgZ2V0U291cmNlRmlsZSgpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgbGluZSBtYXAgZm9yIHRoaXMgY29tcGlsYXRpb24gdW5pdCwgaWYgYXZhaWxhYmxlLgogICAgICogUmV0dXJucyB7QGNvZGUgbnVsbH0gaWYgdGhlIGxpbmUgbWFwIGlzIG5vdCBhdmFpbGFibGUuCiAgICAgKiBAcmV0dXJuIHRoZSBsaW5lIG1hcCBmb3IgdGhpcyBjb21waWxhdGlvbiB1bml0CiAgICAgKi8KICAgIExpbmVNYXAgZ2V0TGluZU1hcCgpOwp9ClBLAwQKAAAIAAAGO6lKS2ltQDkIAAA5CAAAMgAAAGNvbS9zdW4vc291cmNlL3RyZWUvQ29uZGl0aW9uYWxFeHByZXNzaW9uVHJlZS5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDA1LCAyMDE0LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4uc291cmNlLnRyZWU7CgovKioKICogQSB0cmVlIG5vZGUgZm9yIHRoZSBjb25kaXRpb25hbCBvcGVyYXRvciA/IDouCiAqCiAqIEZvciBleGFtcGxlOgogKiA8cHJlPgogKiAgIDxlbT5jb25kaXRpb248L2VtPiA/IDxlbT50cnVlRXhwcmVzc2lvbjwvZW0+IDogPGVtPmZhbHNlRXhwcmVzc2lvbjwvZW0+CiAqIDwvcHJlPgogKgogKiBAamxzIHNlY3Rpb24gMTUuMjUKICoKICogQGF1dGhvciBQZXRlciB2b24gZGVyIEFoJmVhY3V0ZTsKICogQGF1dGhvciBKb25hdGhhbiBHaWJib25zCiAqIEBzaW5jZSAxLjYKICovCnB1YmxpYyBpbnRlcmZhY2UgQ29uZGl0aW9uYWxFeHByZXNzaW9uVHJlZSBleHRlbmRzIEV4cHJlc3Npb25UcmVlIHsKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgY29uZGl0aW9uLgogICAgICogQHJldHVybiB0aGUgY29uZGl0aW9uCiAgICAgKi8KICAgIEV4cHJlc3Npb25UcmVlIGdldENvbmRpdGlvbigpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgZXhwcmVzc2lvbiB0byBiZSBldmFsdWF0ZWQgaWYgdGhlIGNvbmRpdGlvbiBpcyB0cnVlLgogICAgICogQHJldHVybiB0aGUgZXhwcmVzc2lvbiB0byBiZSBldmFsdWF0ZWQgaWYgdGhlIGNvbmRpdGlvbiBpcyB0cnVlCiAgICAgKi8KICAgIEV4cHJlc3Npb25UcmVlIGdldFRydWVFeHByZXNzaW9uKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBleHByZXNzaW9uIHRvIGJlIGV2YWx1YXRlZCBpZiB0aGUgY29uZGl0aW9uIGlzIGZhbHNlLgogICAgICogQHJldHVybiB0aGUgZXhwcmVzc2lvbiB0byBiZSBldmFsdWF0ZWQgaWYgdGhlIGNvbmRpdGlvbiBpcyBmYWxzZQogICAgICovCiAgICBFeHByZXNzaW9uVHJlZSBnZXRGYWxzZUV4cHJlc3Npb24oKTsKfQpQSwMECgAACAAABjupSrTZg8iuBgAArgYAACUAAABjb20vc3VuL3NvdXJjZS90cmVlL0NvbnRpbnVlVHJlZS5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDA1LCAyMDE0LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4uc291cmNlLnRyZWU7CgppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5lbGVtZW50Lk5hbWU7CgovKioKICogQSB0cmVlIG5vZGUgZm9yIGEge0Bjb2RlIGNvbnRpbnVlfSBzdGF0ZW1lbnQuCiAqCiAqIEZvciBleGFtcGxlOgogKiA8cHJlPgogKiAgIGNvbnRpbnVlOwogKiAgIGNvbnRpbnVlIDxlbT5sYWJlbDwvZW0+IDsKICogPC9wcmU+CiAqCiAqIEBqbHMgc2VjdGlvbiAxNC4xNgogKgogKiBAYXV0aG9yIFBldGVyIHZvbiBkZXIgQWgmZWFjdXRlOwogKiBAYXV0aG9yIEpvbmF0aGFuIEdpYmJvbnMKICogQHNpbmNlIDEuNgogKi8KcHVibGljIGludGVyZmFjZSBDb250aW51ZVRyZWUgZXh0ZW5kcyBTdGF0ZW1lbnRUcmVlIHsKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgbGFiZWwgZm9yIHRoaXMge0Bjb2RlIGNvbnRpbnVlfSBzdGF0ZW1lbnQuCiAgICAgKiBAcmV0dXJuIHRoZSBsYWJlbAogICAgICovCiAgICBOYW1lIGdldExhYmVsKCk7Cn0KUEsDBAoAAAgAAAY7qUrsWkRMNAcAADQHAAApAAAAY29tL3N1bi9zb3VyY2UvdHJlZS9TeW5jaHJvbml6ZWRUcmVlLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMTQsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi5zb3VyY2UudHJlZTsKCi8qKgogKiBBIHRyZWUgbm9kZSBmb3IgYSB7QGNvZGUgc3luY2hyb25pemVkfSBzdGF0ZW1lbnQuCiAqCiAqIEZvciBleGFtcGxlOgogKiA8cHJlPgogKiAgIHN5bmNocm9uaXplZCAoIDxlbT5leHByZXNzaW9uPC9lbT4gKQogKiAgICAgICA8ZW0+YmxvY2s8L2VtPgogKiA8L3ByZT4KICoKICogQGpscyBzZWN0aW9uIDE0LjE5CiAqCiAqIEBhdXRob3IgUGV0ZXIgdm9uIGRlciBBaCZlYWN1dGU7CiAqIEBhdXRob3IgSm9uYXRoYW4gR2liYm9ucwogKiBAc2luY2UgMS42CiAqLwpwdWJsaWMgaW50ZXJmYWNlIFN5bmNocm9uaXplZFRyZWUgZXh0ZW5kcyBTdGF0ZW1lbnRUcmVlIHsKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgZXhwcmVzc2lvbiBvbiB3aGljaCB0byBzeW5jaHJvbml6ZS4KICAgICAqIEByZXR1cm4gdGhlIGV4cHJlc3Npb24KICAgICAqLwogICAgRXhwcmVzc2lvblRyZWUgZ2V0RXhwcmVzc2lvbigpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgYmxvY2sgb2YgdGhlIHtAY29kZSBzeW5jaHJvbml6ZWR9IHN0YXRlbWVudC4KICAgICAqIEByZXR1cm4gdGhlIGJsb2NrCiAgICAgKi8KICAgIEJsb2NrVHJlZSBnZXRCbG9jaygpOwp9ClBLAwQKAAAIAAAGO6lKhs0JXxxNAAAcTQAAHQAAAGNvbS9zdW4vc291cmNlL3RyZWUvVHJlZS5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDA1LCAyMDE2LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4uc291cmNlLnRyZWU7CgovKioKICogQ29tbW9uIGludGVyZmFjZSBmb3IgYWxsIG5vZGVzIGluIGFuIGFic3RyYWN0IHN5bnRheCB0cmVlLgogKgogKiA8cD48Yj5XQVJOSU5HOjwvYj4gVGhpcyBpbnRlcmZhY2UgYW5kIGl0cyBzdWItaW50ZXJmYWNlcyBhcmUKICogc3ViamVjdCB0byBjaGFuZ2UgYXMgdGhlIEphdmEmdHJhZGU7IHByb2dyYW1taW5nIGxhbmd1YWdlIGV2b2x2ZXMuCiAqIFRoZXNlIGludGVyZmFjZXMgYXJlIGltcGxlbWVudGVkIGJ5IHRoZSBKREsgSmF2YSBjb21waWxlciAoamF2YWMpCiAqIGFuZCBzaG91bGQgbm90IGJlIGltcGxlbWVudGVkIGVpdGhlciBkaXJlY3RseSBvciBpbmRpcmVjdGx5IGJ5CiAqIG90aGVyIGFwcGxpY2F0aW9ucy4KICoKICogQGF1dGhvciBQZXRlciB2b24gZGVyIEFoJmVhY3V0ZTsKICogQGF1dGhvciBKb25hdGhhbiBHaWJib25zCiAqCiAqIEBzaW5jZSAxLjYKICovCnB1YmxpYyBpbnRlcmZhY2UgVHJlZSB7CgogICAgLyoqCiAgICAgKiBFbnVtZXJhdGVzIGFsbCBraW5kcyBvZiB0cmVlcy4KICAgICAqLwogICAgcHVibGljIGVudW0gS2luZCB7CiAgICAgICAgLyoqCiAgICAgICAgICogVXNlZCBmb3IgaW5zdGFuY2VzIG9mIHtAbGluayBBbm5vdGF0ZWRUeXBlVHJlZX0KICAgICAgICAgKiByZXByZXNlbnRpbmcgYW5ub3RhdGVkIHR5cGVzLgogICAgICAgICAqLwogICAgICAgIEFOTk9UQVRFRF9UWVBFKEFubm90YXRlZFR5cGVUcmVlLmNsYXNzKSwKCiAgICAgICAgLyoqCiAgICAgICAgICogVXNlZCBmb3IgaW5zdGFuY2VzIG9mIHtAbGluayBBbm5vdGF0aW9uVHJlZX0KICAgICAgICAgKiByZXByZXNlbnRpbmcgZGVjbGFyYXRpb24gYW5ub3RhdGlvbnMuCiAgICAgICAgICovCiAgICAgICAgQU5OT1RBVElPTihBbm5vdGF0aW9uVHJlZS5jbGFzcyksCgogICAgICAgIC8qKgogICAgICAgICAqIFVzZWQgZm9yIGluc3RhbmNlcyBvZiB7QGxpbmsgQW5ub3RhdGlvblRyZWV9CiAgICAgICAgICogcmVwcmVzZW50aW5nIHR5cGUgYW5ub3RhdGlvbnMuCiAgICAgICAgICovCiAgICAgICAgVFlQRV9BTk5PVEFUSU9OKEFubm90YXRpb25UcmVlLmNsYXNzKSwKCiAgICAgICAgLyoqCiAgICAgICAgICogVXNlZCBmb3IgaW5zdGFuY2VzIG9mIHtAbGluayBBcnJheUFjY2Vzc1RyZWV9LgogICAgICAgICAqLwogICAgICAgIEFSUkFZX0FDQ0VTUyhBcnJheUFjY2Vzc1RyZWUuY2xhc3MpLAoKICAgICAgICAvKioKICAgICAgICAgKiBVc2VkIGZvciBpbnN0YW5jZXMgb2Yge0BsaW5rIEFycmF5VHlwZVRyZWV9LgogICAgICAgICAqLwogICAgICAgIEFSUkFZX1RZUEUoQXJyYXlUeXBlVHJlZS5jbGFzcyksCgogICAgICAgIC8qKgogICAgICAgICAqIFVzZWQgZm9yIGluc3RhbmNlcyBvZiB7QGxpbmsgQXNzZXJ0VHJlZX0uCiAgICAgICAgICovCiAgICAgICAgQVNTRVJUKEFzc2VydFRyZWUuY2xhc3MpLAoKICAgICAgICAvKioKICAgICAgICAgKiBVc2VkIGZvciBpbnN0YW5jZXMgb2Yge0BsaW5rIEFzc2lnbm1lbnRUcmVlfS4KICAgICAgICAgKi8KICAgICAgICBBU1NJR05NRU5UKEFzc2lnbm1lbnRUcmVlLmNsYXNzKSwKCiAgICAgICAgLyoqCiAgICAgICAgICogVXNlZCBmb3IgaW5zdGFuY2VzIG9mIHtAbGluayBCbG9ja1RyZWV9LgogICAgICAgICAqLwogICAgICAgIEJMT0NLKEJsb2NrVHJlZS5jbGFzcyksCgogICAgICAgIC8qKgogICAgICAgICAqIFVzZWQgZm9yIGluc3RhbmNlcyBvZiB7QGxpbmsgQnJlYWtUcmVlfS4KICAgICAgICAgKi8KICAgICAgICBCUkVBSyhCcmVha1RyZWUuY2xhc3MpLAoKICAgICAgICAvKioKICAgICAgICAgKiBVc2VkIGZvciBpbnN0YW5jZXMgb2Yge0BsaW5rIENhc2VUcmVlfS4KICAgICAgICAgKi8KICAgICAgICBDQVNFKENhc2VUcmVlLmNsYXNzKSwKCiAgICAgICAgLyoqCiAgICAgICAgICogVXNlZCBmb3IgaW5zdGFuY2VzIG9mIHtAbGluayBDYXRjaFRyZWV9LgogICAgICAgICAqLwogICAgICAgIENBVENIKENhdGNoVHJlZS5jbGFzcyksCgogICAgICAgIC8qKgogICAgICAgICAqIFVzZWQgZm9yIGluc3RhbmNlcyBvZiB7QGxpbmsgQ2xhc3NUcmVlfSByZXByZXNlbnRpbmcgY2xhc3Nlcy4KICAgICAgICAgKi8KICAgICAgICBDTEFTUyhDbGFzc1RyZWUuY2xhc3MpLAoKICAgICAgICAvKioKICAgICAgICAgKiBVc2VkIGZvciBpbnN0YW5jZXMgb2Yge0BsaW5rIENvbXBpbGF0aW9uVW5pdFRyZWV9LgogICAgICAgICAqLwogICAgICAgIENPTVBJTEFUSU9OX1VOSVQoQ29tcGlsYXRpb25Vbml0VHJlZS5jbGFzcyksCgogICAgICAgIC8qKgogICAgICAgICAqIFVzZWQgZm9yIGluc3RhbmNlcyBvZiB7QGxpbmsgQ29uZGl0aW9uYWxFeHByZXNzaW9uVHJlZX0uCiAgICAgICAgICovCiAgICAgICAgQ09ORElUSU9OQUxfRVhQUkVTU0lPTihDb25kaXRpb25hbEV4cHJlc3Npb25UcmVlLmNsYXNzKSwKCiAgICAgICAgLyoqCiAgICAgICAgICogVXNlZCBmb3IgaW5zdGFuY2VzIG9mIHtAbGluayBDb250aW51ZVRyZWV9LgogICAgICAgICAqLwogICAgICAgIENPTlRJTlVFKENvbnRpbnVlVHJlZS5jbGFzcyksCgogICAgICAgIC8qKgogICAgICAgICAqIFVzZWQgZm9yIGluc3RhbmNlcyBvZiB7QGxpbmsgRG9XaGlsZUxvb3BUcmVlfS4KICAgICAgICAgKi8KICAgICAgICBET19XSElMRV9MT09QKERvV2hpbGVMb29wVHJlZS5jbGFzcyksCgogICAgICAgIC8qKgogICAgICAgICAqIFVzZWQgZm9yIGluc3RhbmNlcyBvZiB7QGxpbmsgRW5oYW5jZWRGb3JMb29wVHJlZX0uCiAgICAgICAgICovCiAgICAgICAgRU5IQU5DRURfRk9SX0xPT1AoRW5oYW5jZWRGb3JMb29wVHJlZS5jbGFzcyksCgogICAgICAgIC8qKgogICAgICAgICAqIFVzZWQgZm9yIGluc3RhbmNlcyBvZiB7QGxpbmsgRXhwcmVzc2lvblN0YXRlbWVudFRyZWV9LgogICAgICAgICAqLwogICAgICAgIEVYUFJFU1NJT05fU1RBVEVNRU5UKEV4cHJlc3Npb25TdGF0ZW1lbnRUcmVlLmNsYXNzKSwKCiAgICAgICAgLyoqCiAgICAgICAgICogVXNlZCBmb3IgaW5zdGFuY2VzIG9mIHtAbGluayBNZW1iZXJTZWxlY3RUcmVlfS4KICAgICAgICAgKi8KICAgICAgICBNRU1CRVJfU0VMRUNUKE1lbWJlclNlbGVjdFRyZWUuY2xhc3MpLAoKICAgICAgICAvKioKICAgICAgICAgKiBVc2VkIGZvciBpbnN0YW5jZXMgb2Yge0BsaW5rIE1lbWJlclJlZmVyZW5jZVRyZWV9LgogICAgICAgICAqLwogICAgICAgIE1FTUJFUl9SRUZFUkVOQ0UoTWVtYmVyUmVmZXJlbmNlVHJlZS5jbGFzcyksCgogICAgICAgIC8qKgogICAgICAgICAqIFVzZWQgZm9yIGluc3RhbmNlcyBvZiB7QGxpbmsgRm9yTG9vcFRyZWV9LgogICAgICAgICAqLwogICAgICAgIEZPUl9MT09QKEZvckxvb3BUcmVlLmNsYXNzKSwKCiAgICAgICAgLyoqCiAgICAgICAgICogVXNlZCBmb3IgaW5zdGFuY2VzIG9mIHtAbGluayBJZGVudGlmaWVyVHJlZX0uCiAgICAgICAgICovCiAgICAgICAgSURFTlRJRklFUihJZGVudGlmaWVyVHJlZS5jbGFzcyksCgogICAgICAgIC8qKgogICAgICAgICAqIFVzZWQgZm9yIGluc3RhbmNlcyBvZiB7QGxpbmsgSWZUcmVlfS4KICAgICAgICAgKi8KICAgICAgICBJRihJZlRyZWUuY2xhc3MpLAoKICAgICAgICAvKioKICAgICAgICAgKiBVc2VkIGZvciBpbnN0YW5jZXMgb2Yge0BsaW5rIEltcG9ydFRyZWV9LgogICAgICAgICAqLwogICAgICAgIElNUE9SVChJbXBvcnRUcmVlLmNsYXNzKSwKCiAgICAgICAgLyoqCiAgICAgICAgICogVXNlZCBmb3IgaW5zdGFuY2VzIG9mIHtAbGluayBJbnN0YW5jZU9mVHJlZX0uCiAgICAgICAgICovCiAgICAgICAgSU5TVEFOQ0VfT0YoSW5zdGFuY2VPZlRyZWUuY2xhc3MpLAoKICAgICAgICAvKioKICAgICAgICAgKiBVc2VkIGZvciBpbnN0YW5jZXMgb2Yge0BsaW5rIExhYmVsZWRTdGF0ZW1lbnRUcmVlfS4KICAgICAgICAgKi8KICAgICAgICBMQUJFTEVEX1NUQVRFTUVOVChMYWJlbGVkU3RhdGVtZW50VHJlZS5jbGFzcyksCgogICAgICAgIC8qKgogICAgICAgICAqIFVzZWQgZm9yIGluc3RhbmNlcyBvZiB7QGxpbmsgTWV0aG9kVHJlZX0uCiAgICAgICAgICovCiAgICAgICAgTUVUSE9EKE1ldGhvZFRyZWUuY2xhc3MpLAoKICAgICAgICAvKioKICAgICAgICAgKiBVc2VkIGZvciBpbnN0YW5jZXMgb2Yge0BsaW5rIE1ldGhvZEludm9jYXRpb25UcmVlfS4KICAgICAgICAgKi8KICAgICAgICBNRVRIT0RfSU5WT0NBVElPTihNZXRob2RJbnZvY2F0aW9uVHJlZS5jbGFzcyksCgogICAgICAgIC8qKgogICAgICAgICAqIFVzZWQgZm9yIGluc3RhbmNlcyBvZiB7QGxpbmsgTW9kaWZpZXJzVHJlZX0uCiAgICAgICAgICovCiAgICAgICAgTU9ESUZJRVJTKE1vZGlmaWVyc1RyZWUuY2xhc3MpLAoKICAgICAgICAvKioKICAgICAgICAgKiBVc2VkIGZvciBpbnN0YW5jZXMgb2Yge0BsaW5rIE5ld0FycmF5VHJlZX0uCiAgICAgICAgICovCiAgICAgICAgTkVXX0FSUkFZKE5ld0FycmF5VHJlZS5jbGFzcyksCgogICAgICAgIC8qKgogICAgICAgICAqIFVzZWQgZm9yIGluc3RhbmNlcyBvZiB7QGxpbmsgTmV3Q2xhc3NUcmVlfS4KICAgICAgICAgKi8KICAgICAgICBORVdfQ0xBU1MoTmV3Q2xhc3NUcmVlLmNsYXNzKSwKCiAgICAgICAgLyoqCiAgICAgICAgICogVXNlZCBmb3IgaW5zdGFuY2VzIG9mIHtAbGluayBMYW1iZGFFeHByZXNzaW9uVHJlZX0uCiAgICAgICAgICovCiAgICAgICAgTEFNQkRBX0VYUFJFU1NJT04oTGFtYmRhRXhwcmVzc2lvblRyZWUuY2xhc3MpLAoKICAgICAgICAvKioKICAgICAgICAgKiBVc2VkIGZvciBpbnN0YW5jZXMgb2Yge0BsaW5rIFBhY2thZ2VUcmVlfS4KICAgICAgICAgKiBAc2luY2UgOQogICAgICAgICAqLwogICAgICAgIFBBQ0tBR0UoUGFja2FnZVRyZWUuY2xhc3MpLAoKICAgICAgICAvKioKICAgICAgICAgKiBVc2VkIGZvciBpbnN0YW5jZXMgb2Yge0BsaW5rIFBhcmVudGhlc2l6ZWRUcmVlfS4KICAgICAgICAgKi8KICAgICAgICBQQVJFTlRIRVNJWkVEKFBhcmVudGhlc2l6ZWRUcmVlLmNsYXNzKSwKCiAgICAgICAgLyoqCiAgICAgICAgICogVXNlZCBmb3IgaW5zdGFuY2VzIG9mIHtAbGluayBQcmltaXRpdmVUeXBlVHJlZX0uCiAgICAgICAgICovCiAgICAgICAgUFJJTUlUSVZFX1RZUEUoUHJpbWl0aXZlVHlwZVRyZWUuY2xhc3MpLAoKICAgICAgICAvKioKICAgICAgICAgKiBVc2VkIGZvciBpbnN0YW5jZXMgb2Yge0BsaW5rIFJldHVyblRyZWV9LgogICAgICAgICAqLwogICAgICAgIFJFVFVSTihSZXR1cm5UcmVlLmNsYXNzKSwKCiAgICAgICAgLyoqCiAgICAgICAgICogVXNlZCBmb3IgaW5zdGFuY2VzIG9mIHtAbGluayBFbXB0eVN0YXRlbWVudFRyZWV9LgogICAgICAgICAqLwogICAgICAgIEVNUFRZX1NUQVRFTUVOVChFbXB0eVN0YXRlbWVudFRyZWUuY2xhc3MpLAoKICAgICAgICAvKioKICAgICAgICAgKiBVc2VkIGZvciBpbnN0YW5jZXMgb2Yge0BsaW5rIFN3aXRjaFRyZWV9LgogICAgICAgICAqLwogICAgICAgIFNXSVRDSChTd2l0Y2hUcmVlLmNsYXNzKSwKCiAgICAgICAgLyoqCiAgICAgICAgICogVXNlZCBmb3IgaW5zdGFuY2VzIG9mIHtAbGluayBTeW5jaHJvbml6ZWRUcmVlfS4KICAgICAgICAgKi8KICAgICAgICBTWU5DSFJPTklaRUQoU3luY2hyb25pemVkVHJlZS5jbGFzcyksCgogICAgICAgIC8qKgogICAgICAgICAqIFVzZWQgZm9yIGluc3RhbmNlcyBvZiB7QGxpbmsgVGhyb3dUcmVlfS4KICAgICAgICAgKi8KICAgICAgICBUSFJPVyhUaHJvd1RyZWUuY2xhc3MpLAoKICAgICAgICAvKioKICAgICAgICAgKiBVc2VkIGZvciBpbnN0YW5jZXMgb2Yge0BsaW5rIFRyeVRyZWV9LgogICAgICAgICAqLwogICAgICAgIFRSWShUcnlUcmVlLmNsYXNzKSwKCiAgICAgICAgLyoqCiAgICAgICAgICogVXNlZCBmb3IgaW5zdGFuY2VzIG9mIHtAbGluayBQYXJhbWV0ZXJpemVkVHlwZVRyZWV9LgogICAgICAgICAqLwogICAgICAgIFBBUkFNRVRFUklaRURfVFlQRShQYXJhbWV0ZXJpemVkVHlwZVRyZWUuY2xhc3MpLAoKICAgICAgICAvKioKICAgICAgICAgKiBVc2VkIGZvciBpbnN0YW5jZXMgb2Yge0BsaW5rIFVuaW9uVHlwZVRyZWV9LgogICAgICAgICAqLwogICAgICAgIFVOSU9OX1RZUEUoVW5pb25UeXBlVHJlZS5jbGFzcyksCgogICAgICAgIC8qKgogICAgICAgICAqIFVzZWQgZm9yIGluc3RhbmNlcyBvZiB7QGxpbmsgSW50ZXJzZWN0aW9uVHlwZVRyZWV9LgogICAgICAgICAqLwogICAgICAgIElOVEVSU0VDVElPTl9UWVBFKEludGVyc2VjdGlvblR5cGVUcmVlLmNsYXNzKSwKCiAgICAgICAgLyoqCiAgICAgICAgICogVXNlZCBmb3IgaW5zdGFuY2VzIG9mIHtAbGluayBUeXBlQ2FzdFRyZWV9LgogICAgICAgICAqLwogICAgICAgIFRZUEVfQ0FTVChUeXBlQ2FzdFRyZWUuY2xhc3MpLAoKICAgICAgICAvKioKICAgICAgICAgKiBVc2VkIGZvciBpbnN0YW5jZXMgb2Yge0BsaW5rIFR5cGVQYXJhbWV0ZXJUcmVlfS4KICAgICAgICAgKi8KICAgICAgICBUWVBFX1BBUkFNRVRFUihUeXBlUGFyYW1ldGVyVHJlZS5jbGFzcyksCgogICAgICAgIC8qKgogICAgICAgICAqIFVzZWQgZm9yIGluc3RhbmNlcyBvZiB7QGxpbmsgVmFyaWFibGVUcmVlfS4KICAgICAgICAgKi8KICAgICAgICBWQVJJQUJMRShWYXJpYWJsZVRyZWUuY2xhc3MpLAoKICAgICAgICAvKioKICAgICAgICAgKiBVc2VkIGZvciBpbnN0YW5jZXMgb2Yge0BsaW5rIFdoaWxlTG9vcFRyZWV9LgogICAgICAgICAqLwogICAgICAgIFdISUxFX0xPT1AoV2hpbGVMb29wVHJlZS5jbGFzcyksCgogICAgICAgIC8qKgogICAgICAgICAqIFVzZWQgZm9yIGluc3RhbmNlcyBvZiB7QGxpbmsgVW5hcnlUcmVlfSByZXByZXNlbnRpbmcgcG9zdGZpeAogICAgICAgICAqIGluY3JlbWVudCBvcGVyYXRvciB7QGNvZGUgKyt9LgogICAgICAgICAqLwogICAgICAgIFBPU1RGSVhfSU5DUkVNRU5UKFVuYXJ5VHJlZS5jbGFzcyksCgogICAgICAgIC8qKgogICAgICAgICAqIFVzZWQgZm9yIGluc3RhbmNlcyBvZiB7QGxpbmsgVW5hcnlUcmVlfSByZXByZXNlbnRpbmcgcG9zdGZpeAogICAgICAgICAqIGRlY3JlbWVudCBvcGVyYXRvciB7QGNvZGUgLS19LgogICAgICAgICAqLwogICAgICAgIFBPU1RGSVhfREVDUkVNRU5UKFVuYXJ5VHJlZS5jbGFzcyksCgogICAgICAgIC8qKgogICAgICAgICAqIFVzZWQgZm9yIGluc3RhbmNlcyBvZiB7QGxpbmsgVW5hcnlUcmVlfSByZXByZXNlbnRpbmcgcHJlZml4CiAgICAgICAgICogaW5jcmVtZW50IG9wZXJhdG9yIHtAY29kZSArK30uCiAgICAgICAgICovCiAgICAgICAgUFJFRklYX0lOQ1JFTUVOVChVbmFyeVRyZWUuY2xhc3MpLAoKICAgICAgICAvKioKICAgICAgICAgKiBVc2VkIGZvciBpbnN0YW5jZXMgb2Yge0BsaW5rIFVuYXJ5VHJlZX0gcmVwcmVzZW50aW5nIHByZWZpeAogICAgICAgICAqIGRlY3JlbWVudCBvcGVyYXRvciB7QGNvZGUgLS19LgogICAgICAgICAqLwogICAgICAgIFBSRUZJWF9ERUNSRU1FTlQoVW5hcnlUcmVlLmNsYXNzKSwKCiAgICAgICAgLyoqCiAgICAgICAgICogVXNlZCBmb3IgaW5zdGFuY2VzIG9mIHtAbGluayBVbmFyeVRyZWV9IHJlcHJlc2VudGluZyB1bmFyeSBwbHVzCiAgICAgICAgICogb3BlcmF0b3Ige0Bjb2RlICt9LgogICAgICAgICAqLwogICAgICAgIFVOQVJZX1BMVVMoVW5hcnlUcmVlLmNsYXNzKSwKCiAgICAgICAgLyoqCiAgICAgICAgICogVXNlZCBmb3IgaW5zdGFuY2VzIG9mIHtAbGluayBVbmFyeVRyZWV9IHJlcHJlc2VudGluZyB1bmFyeSBtaW51cwogICAgICAgICAqIG9wZXJhdG9yIHtAY29kZSAtfS4KICAgICAgICAgKi8KICAgICAgICBVTkFSWV9NSU5VUyhVbmFyeVRyZWUuY2xhc3MpLAoKICAgICAgICAvKioKICAgICAgICAgKiBVc2VkIGZvciBpbnN0YW5jZXMgb2Yge0BsaW5rIFVuYXJ5VHJlZX0gcmVwcmVzZW50aW5nIGJpdHdpc2UKICAgICAgICAgKiBjb21wbGVtZW50IG9wZXJhdG9yIHtAY29kZSB+fS4KICAgICAgICAgKi8KICAgICAgICBCSVRXSVNFX0NPTVBMRU1FTlQoVW5hcnlUcmVlLmNsYXNzKSwKCiAgICAgICAgLyoqCiAgICAgICAgICogVXNlZCBmb3IgaW5zdGFuY2VzIG9mIHtAbGluayBVbmFyeVRyZWV9IHJlcHJlc2VudGluZyBsb2dpY2FsCiAgICAgICAgICogY29tcGxlbWVudCBvcGVyYXRvciB7QGNvZGUgIX0uCiAgICAgICAgICovCiAgICAgICAgTE9HSUNBTF9DT01QTEVNRU5UKFVuYXJ5VHJlZS5jbGFzcyksCgogICAgICAgIC8qKgogICAgICAgICAqIFVzZWQgZm9yIGluc3RhbmNlcyBvZiB7QGxpbmsgQmluYXJ5VHJlZX0gcmVwcmVzZW50aW5nCiAgICAgICAgICogbXVsdGlwbGljYXRpb24ge0Bjb2RlICp9LgogICAgICAgICAqLwogICAgICAgIE1VTFRJUExZKEJpbmFyeVRyZWUuY2xhc3MpLAoKICAgICAgICAvKioKICAgICAgICAgKiBVc2VkIGZvciBpbnN0YW5jZXMgb2Yge0BsaW5rIEJpbmFyeVRyZWV9IHJlcHJlc2VudGluZwogICAgICAgICAqIGRpdmlzaW9uIHtAY29kZSAvfS4KICAgICAgICAgKi8KICAgICAgICBESVZJREUoQmluYXJ5VHJlZS5jbGFzcyksCgogICAgICAgIC8qKgogICAgICAgICAqIFVzZWQgZm9yIGluc3RhbmNlcyBvZiB7QGxpbmsgQmluYXJ5VHJlZX0gcmVwcmVzZW50aW5nCiAgICAgICAgICogcmVtYWluZGVyIHtAY29kZSAlfS4KICAgICAgICAgKi8KICAgICAgICBSRU1BSU5ERVIoQmluYXJ5VHJlZS5jbGFzcyksCgogICAgICAgIC8qKgogICAgICAgICAqIFVzZWQgZm9yIGluc3RhbmNlcyBvZiB7QGxpbmsgQmluYXJ5VHJlZX0gcmVwcmVzZW50aW5nCiAgICAgICAgICogYWRkaXRpb24gb3Igc3RyaW5nIGNvbmNhdGVuYXRpb24ge0Bjb2RlICt9LgogICAgICAgICAqLwogICAgICAgIFBMVVMoQmluYXJ5VHJlZS5jbGFzcyksCgogICAgICAgIC8qKgogICAgICAgICAqIFVzZWQgZm9yIGluc3RhbmNlcyBvZiB7QGxpbmsgQmluYXJ5VHJlZX0gcmVwcmVzZW50aW5nCiAgICAgICAgICogc3VidHJhY3Rpb24ge0Bjb2RlIC19LgogICAgICAgICAqLwogICAgICAgIE1JTlVTKEJpbmFyeVRyZWUuY2xhc3MpLAoKICAgICAgICAvKioKICAgICAgICAgKiBVc2VkIGZvciBpbnN0YW5jZXMgb2Yge0BsaW5rIEJpbmFyeVRyZWV9IHJlcHJlc2VudGluZwogICAgICAgICAqIGxlZnQgc2hpZnQge0Bjb2RlIDw8fS4KICAgICAgICAgKi8KICAgICAgICBMRUZUX1NISUZUKEJpbmFyeVRyZWUuY2xhc3MpLAoKICAgICAgICAvKioKICAgICAgICAgKiBVc2VkIGZvciBpbnN0YW5jZXMgb2Yge0BsaW5rIEJpbmFyeVRyZWV9IHJlcHJlc2VudGluZwogICAgICAgICAqIHJpZ2h0IHNoaWZ0IHtAY29kZSA+Pn0uCiAgICAgICAgICovCiAgICAgICAgUklHSFRfU0hJRlQoQmluYXJ5VHJlZS5jbGFzcyksCgogICAgICAgIC8qKgogICAgICAgICAqIFVzZWQgZm9yIGluc3RhbmNlcyBvZiB7QGxpbmsgQmluYXJ5VHJlZX0gcmVwcmVzZW50aW5nCiAgICAgICAgICogdW5zaWduZWQgcmlnaHQgc2hpZnQge0Bjb2RlID4+Pn0uCiAgICAgICAgICovCiAgICAgICAgVU5TSUdORURfUklHSFRfU0hJRlQoQmluYXJ5VHJlZS5jbGFzcyksCgogICAgICAgIC8qKgogICAgICAgICAqIFVzZWQgZm9yIGluc3RhbmNlcyBvZiB7QGxpbmsgQmluYXJ5VHJlZX0gcmVwcmVzZW50aW5nCiAgICAgICAgICogbGVzcy10aGFuIHtAY29kZSA8fS4KICAgICAgICAgKi8KICAgICAgICBMRVNTX1RIQU4oQmluYXJ5VHJlZS5jbGFzcyksCgogICAgICAgIC8qKgogICAgICAgICAqIFVzZWQgZm9yIGluc3RhbmNlcyBvZiB7QGxpbmsgQmluYXJ5VHJlZX0gcmVwcmVzZW50aW5nCiAgICAgICAgICogZ3JlYXRlci10aGFuIHtAY29kZSA+fS4KICAgICAgICAgKi8KICAgICAgICBHUkVBVEVSX1RIQU4oQmluYXJ5VHJlZS5jbGFzcyksCgogICAgICAgIC8qKgogICAgICAgICAqIFVzZWQgZm9yIGluc3RhbmNlcyBvZiB7QGxpbmsgQmluYXJ5VHJlZX0gcmVwcmVzZW50aW5nCiAgICAgICAgICogbGVzcy10aGFuLWVxdWFsIHtAY29kZSA8PX0uCiAgICAgICAgICovCiAgICAgICAgTEVTU19USEFOX0VRVUFMKEJpbmFyeVRyZWUuY2xhc3MpLAoKICAgICAgICAvKioKICAgICAgICAgKiBVc2VkIGZvciBpbnN0YW5jZXMgb2Yge0BsaW5rIEJpbmFyeVRyZWV9IHJlcHJlc2VudGluZwogICAgICAgICAqIGdyZWF0ZXItdGhhbi1lcXVhbCB7QGNvZGUgPj19LgogICAgICAgICAqLwogICAgICAgIEdSRUFURVJfVEhBTl9FUVVBTChCaW5hcnlUcmVlLmNsYXNzKSwKCiAgICAgICAgLyoqCiAgICAgICAgICogVXNlZCBmb3IgaW5zdGFuY2VzIG9mIHtAbGluayBCaW5hcnlUcmVlfSByZXByZXNlbnRpbmcKICAgICAgICAgKiBlcXVhbC10byB7QGNvZGUgPT19LgogICAgICAgICAqLwogICAgICAgIEVRVUFMX1RPKEJpbmFyeVRyZWUuY2xhc3MpLAoKICAgICAgICAvKioKICAgICAgICAgKiBVc2VkIGZvciBpbnN0YW5jZXMgb2Yge0BsaW5rIEJpbmFyeVRyZWV9IHJlcHJlc2VudGluZwogICAgICAgICAqIG5vdC1lcXVhbC10byB7QGNvZGUgIT19LgogICAgICAgICAqLwogICAgICAgIE5PVF9FUVVBTF9UTyhCaW5hcnlUcmVlLmNsYXNzKSwKCiAgICAgICAgLyoqCiAgICAgICAgICogVXNlZCBmb3IgaW5zdGFuY2VzIG9mIHtAbGluayBCaW5hcnlUcmVlfSByZXByZXNlbnRpbmcKICAgICAgICAgKiBiaXR3aXNlIGFuZCBsb2dpY2FsICJhbmQiIHtAY29kZSAmfS4KICAgICAgICAgKi8KICAgICAgICBBTkQoQmluYXJ5VHJlZS5jbGFzcyksCgogICAgICAgIC8qKgogICAgICAgICAqIFVzZWQgZm9yIGluc3RhbmNlcyBvZiB7QGxpbmsgQmluYXJ5VHJlZX0gcmVwcmVzZW50aW5nCiAgICAgICAgICogYml0d2lzZSBhbmQgbG9naWNhbCAieG9yIiB7QGNvZGUgXn0uCiAgICAgICAgICovCiAgICAgICAgWE9SKEJpbmFyeVRyZWUuY2xhc3MpLAoKICAgICAgICAvKioKICAgICAgICAgKiBVc2VkIGZvciBpbnN0YW5jZXMgb2Yge0BsaW5rIEJpbmFyeVRyZWV9IHJlcHJlc2VudGluZwogICAgICAgICAqIGJpdHdpc2UgYW5kIGxvZ2ljYWwgIm9yIiB7QGNvZGUgfH0uCiAgICAgICAgICovCiAgICAgICAgT1IoQmluYXJ5VHJlZS5jbGFzcyksCgogICAgICAgIC8qKgogICAgICAgICAqIFVzZWQgZm9yIGluc3RhbmNlcyBvZiB7QGxpbmsgQmluYXJ5VHJlZX0gcmVwcmVzZW50aW5nCiAgICAgICAgICogY29uZGl0aW9uYWwtYW5kIHtAY29kZSAmJn0uCiAgICAgICAgICovCiAgICAgICAgQ09ORElUSU9OQUxfQU5EKEJpbmFyeVRyZWUuY2xhc3MpLAoKICAgICAgICAvKioKICAgICAgICAgKiBVc2VkIGZvciBpbnN0YW5jZXMgb2Yge0BsaW5rIEJpbmFyeVRyZWV9IHJlcHJlc2VudGluZwogICAgICAgICAqIGNvbmRpdGlvbmFsLW9yIHtAY29kZSB8fH0uCiAgICAgICAgICovCiAgICAgICAgQ09ORElUSU9OQUxfT1IoQmluYXJ5VHJlZS5jbGFzcyksCgogICAgICAgIC8qKgogICAgICAgICAqIFVzZWQgZm9yIGluc3RhbmNlcyBvZiB7QGxpbmsgQ29tcG91bmRBc3NpZ25tZW50VHJlZX0gcmVwcmVzZW50aW5nCiAgICAgICAgICogbXVsdGlwbGljYXRpb24gYXNzaWdubWVudCB7QGNvZGUgKj19LgogICAgICAgICAqLwogICAgICAgIE1VTFRJUExZX0FTU0lHTk1FTlQoQ29tcG91bmRBc3NpZ25tZW50VHJlZS5jbGFzcyksCgogICAgICAgIC8qKgogICAgICAgICAqIFVzZWQgZm9yIGluc3RhbmNlcyBvZiB7QGxpbmsgQ29tcG91bmRBc3NpZ25tZW50VHJlZX0gcmVwcmVzZW50aW5nCiAgICAgICAgICogZGl2aXNpb24gYXNzaWdubWVudCB7QGNvZGUgLz19LgogICAgICAgICAqLwogICAgICAgIERJVklERV9BU1NJR05NRU5UKENvbXBvdW5kQXNzaWdubWVudFRyZWUuY2xhc3MpLAoKICAgICAgICAvKioKICAgICAgICAgKiBVc2VkIGZvciBpbnN0YW5jZXMgb2Yge0BsaW5rIENvbXBvdW5kQXNzaWdubWVudFRyZWV9IHJlcHJlc2VudGluZwogICAgICAgICAqIHJlbWFpbmRlciBhc3NpZ25tZW50IHtAY29kZSAlPX0uCiAgICAgICAgICovCiAgICAgICAgUkVNQUlOREVSX0FTU0lHTk1FTlQoQ29tcG91bmRBc3NpZ25tZW50VHJlZS5jbGFzcyksCgogICAgICAgIC8qKgogICAgICAgICAqIFVzZWQgZm9yIGluc3RhbmNlcyBvZiB7QGxpbmsgQ29tcG91bmRBc3NpZ25tZW50VHJlZX0gcmVwcmVzZW50aW5nCiAgICAgICAgICogYWRkaXRpb24gb3Igc3RyaW5nIGNvbmNhdGVuYXRpb24gYXNzaWdubWVudCB7QGNvZGUgKz19LgogICAgICAgICAqLwogICAgICAgIFBMVVNfQVNTSUdOTUVOVChDb21wb3VuZEFzc2lnbm1lbnRUcmVlLmNsYXNzKSwKCiAgICAgICAgLyoqCiAgICAgICAgICogVXNlZCBmb3IgaW5zdGFuY2VzIG9mIHtAbGluayBDb21wb3VuZEFzc2lnbm1lbnRUcmVlfSByZXByZXNlbnRpbmcKICAgICAgICAgKiBzdWJ0cmFjdGlvbiBhc3NpZ25tZW50IHtAY29kZSAtPX0uCiAgICAgICAgICovCiAgICAgICAgTUlOVVNfQVNTSUdOTUVOVChDb21wb3VuZEFzc2lnbm1lbnRUcmVlLmNsYXNzKSwKCiAgICAgICAgLyoqCiAgICAgICAgICogVXNlZCBmb3IgaW5zdGFuY2VzIG9mIHtAbGluayBDb21wb3VuZEFzc2lnbm1lbnRUcmVlfSByZXByZXNlbnRpbmcKICAgICAgICAgKiBsZWZ0IHNoaWZ0IGFzc2lnbm1lbnQge0Bjb2RlIDw8PX0uCiAgICAgICAgICovCiAgICAgICAgTEVGVF9TSElGVF9BU1NJR05NRU5UKENvbXBvdW5kQXNzaWdubWVudFRyZWUuY2xhc3MpLAoKICAgICAgICAvKioKICAgICAgICAgKiBVc2VkIGZvciBpbnN0YW5jZXMgb2Yge0BsaW5rIENvbXBvdW5kQXNzaWdubWVudFRyZWV9IHJlcHJlc2VudGluZwogICAgICAgICAqIHJpZ2h0IHNoaWZ0IGFzc2lnbm1lbnQge0Bjb2RlID4+PX0uCiAgICAgICAgICovCiAgICAgICAgUklHSFRfU0hJRlRfQVNTSUdOTUVOVChDb21wb3VuZEFzc2lnbm1lbnRUcmVlLmNsYXNzKSwKCiAgICAgICAgLyoqCiAgICAgICAgICogVXNlZCBmb3IgaW5zdGFuY2VzIG9mIHtAbGluayBDb21wb3VuZEFzc2lnbm1lbnRUcmVlfSByZXByZXNlbnRpbmcKICAgICAgICAgKiB1bnNpZ25lZCByaWdodCBzaGlmdCBhc3NpZ25tZW50IHtAY29kZSA+Pj49fS4KICAgICAgICAgKi8KICAgICAgICBVTlNJR05FRF9SSUdIVF9TSElGVF9BU1NJR05NRU5UKENvbXBvdW5kQXNzaWdubWVudFRyZWUuY2xhc3MpLAoKICAgICAgICAvKioKICAgICAgICAgKiBVc2VkIGZvciBpbnN0YW5jZXMgb2Yge0BsaW5rIENvbXBvdW5kQXNzaWdubWVudFRyZWV9IHJlcHJlc2VudGluZwogICAgICAgICAqIGJpdHdpc2UgYW5kIGxvZ2ljYWwgImFuZCIgYXNzaWdubWVudCB7QGNvZGUgJj19LgogICAgICAgICAqLwogICAgICAgIEFORF9BU1NJR05NRU5UKENvbXBvdW5kQXNzaWdubWVudFRyZWUuY2xhc3MpLAoKICAgICAgICAvKioKICAgICAgICAgKiBVc2VkIGZvciBpbnN0YW5jZXMgb2Yge0BsaW5rIENvbXBvdW5kQXNzaWdubWVudFRyZWV9IHJlcHJlc2VudGluZwogICAgICAgICAqIGJpdHdpc2UgYW5kIGxvZ2ljYWwgInhvciIgYXNzaWdubWVudCB7QGNvZGUgXj19LgogICAgICAgICAqLwogICAgICAgIFhPUl9BU1NJR05NRU5UKENvbXBvdW5kQXNzaWdubWVudFRyZWUuY2xhc3MpLAoKICAgICAgICAvKioKICAgICAgICAgKiBVc2VkIGZvciBpbnN0YW5jZXMgb2Yge0BsaW5rIENvbXBvdW5kQXNzaWdubWVudFRyZWV9IHJlcHJlc2VudGluZwogICAgICAgICAqIGJpdHdpc2UgYW5kIGxvZ2ljYWwgIm9yIiBhc3NpZ25tZW50IHtAY29kZSB8PX0uCiAgICAgICAgICovCiAgICAgICAgT1JfQVNTSUdOTUVOVChDb21wb3VuZEFzc2lnbm1lbnRUcmVlLmNsYXNzKSwKCiAgICAgICAgLyoqCiAgICAgICAgICogVXNlZCBmb3IgaW5zdGFuY2VzIG9mIHtAbGluayBMaXRlcmFsVHJlZX0gcmVwcmVzZW50aW5nCiAgICAgICAgICogYW4gaW50ZWdyYWwgbGl0ZXJhbCBleHByZXNzaW9uIG9mIHR5cGUge0Bjb2RlIGludH0uCiAgICAgICAgICovCiAgICAgICAgSU5UX0xJVEVSQUwoTGl0ZXJhbFRyZWUuY2xhc3MpLAoKICAgICAgICAvKioKICAgICAgICAgKiBVc2VkIGZvciBpbnN0YW5jZXMgb2Yge0BsaW5rIExpdGVyYWxUcmVlfSByZXByZXNlbnRpbmcKICAgICAgICAgKiBhbiBpbnRlZ3JhbCBsaXRlcmFsIGV4cHJlc3Npb24gb2YgdHlwZSB7QGNvZGUgbG9uZ30uCiAgICAgICAgICovCiAgICAgICAgTE9OR19MSVRFUkFMKExpdGVyYWxUcmVlLmNsYXNzKSwKCiAgICAgICAgLyoqCiAgICAgICAgICogVXNlZCBmb3IgaW5zdGFuY2VzIG9mIHtAbGluayBMaXRlcmFsVHJlZX0gcmVwcmVzZW50aW5nCiAgICAgICAgICogYSBmbG9hdGluZy1wb2ludCBsaXRlcmFsIGV4cHJlc3Npb24gb2YgdHlwZSB7QGNvZGUgZmxvYXR9LgogICAgICAgICAqLwogICAgICAgIEZMT0FUX0xJVEVSQUwoTGl0ZXJhbFRyZWUuY2xhc3MpLAoKICAgICAgICAvKioKICAgICAgICAgKiBVc2VkIGZvciBpbnN0YW5jZXMgb2Yge0BsaW5rIExpdGVyYWxUcmVlfSByZXByZXNlbnRpbmcKICAgICAgICAgKiBhIGZsb2F0aW5nLXBvaW50IGxpdGVyYWwgZXhwcmVzc2lvbiBvZiB0eXBlIHtAY29kZSBkb3VibGV9LgogICAgICAgICAqLwogICAgICAgIERPVUJMRV9MSVRFUkFMKExpdGVyYWxUcmVlLmNsYXNzKSwKCiAgICAgICAgLyoqCiAgICAgICAgICogVXNlZCBmb3IgaW5zdGFuY2VzIG9mIHtAbGluayBMaXRlcmFsVHJlZX0gcmVwcmVzZW50aW5nCiAgICAgICAgICogYSBib29sZWFuIGxpdGVyYWwgZXhwcmVzc2lvbiBvZiB0eXBlIHtAY29kZSBib29sZWFufS4KICAgICAgICAgKi8KICAgICAgICBCT09MRUFOX0xJVEVSQUwoTGl0ZXJhbFRyZWUuY2xhc3MpLAoKICAgICAgICAvKioKICAgICAgICAgKiBVc2VkIGZvciBpbnN0YW5jZXMgb2Yge0BsaW5rIExpdGVyYWxUcmVlfSByZXByZXNlbnRpbmcKICAgICAgICAgKiBhIGNoYXJhY3RlciBsaXRlcmFsIGV4cHJlc3Npb24gb2YgdHlwZSB7QGNvZGUgY2hhcn0uCiAgICAgICAgICovCiAgICAgICAgQ0hBUl9MSVRFUkFMKExpdGVyYWxUcmVlLmNsYXNzKSwKCiAgICAgICAgLyoqCiAgICAgICAgICogVXNlZCBmb3IgaW5zdGFuY2VzIG9mIHtAbGluayBMaXRlcmFsVHJlZX0gcmVwcmVzZW50aW5nCiAgICAgICAgICogYSBzdHJpbmcgbGl0ZXJhbCBleHByZXNzaW9uIG9mIHR5cGUge0BsaW5rIFN0cmluZ30uCiAgICAgICAgICovCiAgICAgICAgU1RSSU5HX0xJVEVSQUwoTGl0ZXJhbFRyZWUuY2xhc3MpLAoKICAgICAgICAvKioKICAgICAgICAgKiBVc2VkIGZvciBpbnN0YW5jZXMgb2Yge0BsaW5rIExpdGVyYWxUcmVlfSByZXByZXNlbnRpbmcKICAgICAgICAgKiB0aGUgdXNlIG9mIHtAY29kZSBudWxsfS4KICAgICAgICAgKi8KICAgICAgICBOVUxMX0xJVEVSQUwoTGl0ZXJhbFRyZWUuY2xhc3MpLAoKICAgICAgICAvKioKICAgICAgICAgKiBVc2VkIGZvciBpbnN0YW5jZXMgb2Yge0BsaW5rIFdpbGRjYXJkVHJlZX0gcmVwcmVzZW50aW5nCiAgICAgICAgICogYW4gdW5ib3VuZGVkIHdpbGRjYXJkIHR5cGUgYXJndW1lbnQuCiAgICAgICAgICovCiAgICAgICAgVU5CT1VOREVEX1dJTERDQVJEKFdpbGRjYXJkVHJlZS5jbGFzcyksCgogICAgICAgIC8qKgogICAgICAgICAqIFVzZWQgZm9yIGluc3RhbmNlcyBvZiB7QGxpbmsgV2lsZGNhcmRUcmVlfSByZXByZXNlbnRpbmcKICAgICAgICAgKiBhbiBleHRlbmRzIGJvdW5kZWQgd2lsZGNhcmQgdHlwZSBhcmd1bWVudC4KICAgICAgICAgKi8KICAgICAgICBFWFRFTkRTX1dJTERDQVJEKFdpbGRjYXJkVHJlZS5jbGFzcyksCgogICAgICAgIC8qKgogICAgICAgICAqIFVzZWQgZm9yIGluc3RhbmNlcyBvZiB7QGxpbmsgV2lsZGNhcmRUcmVlfSByZXByZXNlbnRpbmcKICAgICAgICAgKiBhIHN1cGVyIGJvdW5kZWQgd2lsZGNhcmQgdHlwZSBhcmd1bWVudC4KICAgICAgICAgKi8KICAgICAgICBTVVBFUl9XSUxEQ0FSRChXaWxkY2FyZFRyZWUuY2xhc3MpLAoKICAgICAgICAvKioKICAgICAgICAgKiBVc2VkIGZvciBpbnN0YW5jZXMgb2Yge0BsaW5rIEVycm9uZW91c1RyZWV9LgogICAgICAgICAqLwogICAgICAgIEVSUk9ORU9VUyhFcnJvbmVvdXNUcmVlLmNsYXNzKSwKCiAgICAgICAgLyoqCiAgICAgICAgICogVXNlZCBmb3IgaW5zdGFuY2VzIG9mIHtAbGluayBDbGFzc1RyZWV9IHJlcHJlc2VudGluZyBpbnRlcmZhY2VzLgogICAgICAgICAqLwogICAgICAgIElOVEVSRkFDRShDbGFzc1RyZWUuY2xhc3MpLAoKICAgICAgICAvKioKICAgICAgICAgKiBVc2VkIGZvciBpbnN0YW5jZXMgb2Yge0BsaW5rIENsYXNzVHJlZX0gcmVwcmVzZW50aW5nIGVudW1zLgogICAgICAgICAqLwogICAgICAgIEVOVU0oQ2xhc3NUcmVlLmNsYXNzKSwKCiAgICAgICAgLyoqCiAgICAgICAgICogVXNlZCBmb3IgaW5zdGFuY2VzIG9mIHtAbGluayBDbGFzc1RyZWV9IHJlcHJlc2VudGluZyBhbm5vdGF0aW9uIHR5cGVzLgogICAgICAgICAqLwogICAgICAgIEFOTk9UQVRJT05fVFlQRShDbGFzc1RyZWUuY2xhc3MpLAoKICAgICAgICAvKioKICAgICAgICAgKiBVc2VkIGZvciBpbnN0YW5jZXMgb2Yge0BsaW5rIE1vZHVsZVRyZWV9IHJlcHJlc2VudGluZyBtb2R1bGUgZGVjbGFyYXRpb25zLgogICAgICAgICAqLwogICAgICAgIE1PRFVMRShNb2R1bGVUcmVlLmNsYXNzKSwKCiAgICAgICAgLyoqCiAgICAgICAgICogVXNlZCBmb3IgaW5zdGFuY2VzIG9mIHtAbGluayBFeHBvcnRzVHJlZX0gcmVwcmVzZW50aW5nCiAgICAgICAgICogZXhwb3J0cyBkaXJlY3RpdmVzIGluIGEgbW9kdWxlIGRlY2xhcmF0aW9uLgogICAgICAgICAqLwogICAgICAgIEVYUE9SVFMoRXhwb3J0c1RyZWUuY2xhc3MpLAoKICAgICAgICAvKioKICAgICAgICAgKiBVc2VkIGZvciBpbnN0YW5jZXMgb2Yge0BsaW5rIEV4cG9ydHNUcmVlfSByZXByZXNlbnRpbmcKICAgICAgICAgKiBvcGVucyBkaXJlY3RpdmVzIGluIGEgbW9kdWxlIGRlY2xhcmF0aW9uLgogICAgICAgICAqLwogICAgICAgIE9QRU5TKE9wZW5zVHJlZS5jbGFzcyksCgogICAgICAgIC8qKgogICAgICAgICAqIFVzZWQgZm9yIGluc3RhbmNlcyBvZiB7QGxpbmsgUHJvdmlkZXNUcmVlfSByZXByZXNlbnRpbmcKICAgICAgICAgKiBwcm92aWRlcyBkaXJlY3RpdmVzIGluIGEgbW9kdWxlIGRlY2xhcmF0aW9uLgogICAgICAgICAqLwogICAgICAgIFBST1ZJREVTKFByb3ZpZGVzVHJlZS5jbGFzcyksCgogICAgICAgIC8qKgogICAgICAgICAqIFVzZWQgZm9yIGluc3RhbmNlcyBvZiB7QGxpbmsgUmVxdWlyZXNUcmVlfSByZXByZXNlbnRpbmcKICAgICAgICAgKiByZXF1aXJlcyBkaXJlY3RpdmVzIGluIGEgbW9kdWxlIGRlY2xhcmF0aW9uLgogICAgICAgICAqLwogICAgICAgIFJFUVVJUkVTKFJlcXVpcmVzVHJlZS5jbGFzcyksCgogICAgICAgIC8qKgogICAgICAgICAqIFVzZWQgZm9yIGluc3RhbmNlcyBvZiB7QGxpbmsgVXNlc1RyZWV9IHJlcHJlc2VudGluZwogICAgICAgICAqIHVzZXMgZGlyZWN0aXZlcyBpbiBhIG1vZHVsZSBkZWNsYXJhdGlvbi4KICAgICAgICAgKi8KICAgICAgICBVU0VTKFVzZXNUcmVlLmNsYXNzKSwKCiAgICAgICAgLyoqCiAgICAgICAgICogQW4gaW1wbGVtZW50YXRpb24tcmVzZXJ2ZWQgbm9kZS4gVGhpcyBpcyB0aGUgbm90IHRoZSBub2RlCiAgICAgICAgICogeW91IGFyZSBsb29raW5nIGZvci4KICAgICAgICAgKi8KICAgICAgICBPVEhFUihudWxsKTsKCgogICAgICAgIEtpbmQoQ2xhc3M8PyBleHRlbmRzIFRyZWU+IGludGYpIHsKICAgICAgICAgICAgYXNzb2NpYXRlZEludGVyZmFjZSA9IGludGY7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBSZXR1cm5zIHRoZSBhc3NvY2lhdGVkIGludGVyZmFjZSB0eXBlIHRoYXQgdXNlcyB0aGlzIGtpbmQuCiAgICAgICAgICogQHJldHVybiB0aGUgYXNzb2NpYXRlZCBpbnRlcmZhY2UKICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQ2xhc3M8PyBleHRlbmRzIFRyZWU+IGFzSW50ZXJmYWNlKCkgewogICAgICAgICAgICByZXR1cm4gYXNzb2NpYXRlZEludGVyZmFjZTsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgZmluYWwgQ2xhc3M8PyBleHRlbmRzIFRyZWU+IGFzc29jaWF0ZWRJbnRlcmZhY2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBraW5kIG9mIHRoaXMgdHJlZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIHRoZSBraW5kIG9mIHRoaXMgdHJlZS4KICAgICAqLwogICAgS2luZCBnZXRLaW5kKCk7CgogICAgLyoqCiAgICAgKiBBY2NlcHQgbWV0aG9kIHVzZWQgdG8gaW1wbGVtZW50IHRoZSB2aXNpdG9yIHBhdHRlcm4uICBUaGUKICAgICAqIHZpc2l0b3IgcGF0dGVybiBpcyB1c2VkIHRvIGltcGxlbWVudCBvcGVyYXRpb25zIG9uIHRyZWVzLgogICAgICoKICAgICAqIEBwYXJhbSA8Uj4gcmVzdWx0IHR5cGUgb2YgdGhpcyBvcGVyYXRpb24uCiAgICAgKiBAcGFyYW0gPEQ+IHR5cGUgb2YgYWRkaXRpb25hbCBkYXRhLgogICAgICogQHBhcmFtIHZpc2l0b3IgdGhlIHZpc2l0b3IgdG8gYmUgY2FsbGVkCiAgICAgKiBAcGFyYW0gZGF0YSBhIHZhbHVlIHRvIGJlIHBhc3NlZCB0byB0aGUgdmlzaXRvcgogICAgICogQHJldHVybiB0aGUgcmVzdWx0IHJldHVybmVkIGZyb20gY2FsbGluZyB0aGUgdmlzaXRvcgogICAgICovCiAgICA8UixEPiBSIGFjY2VwdChUcmVlVmlzaXRvcjxSLEQ+IHZpc2l0b3IsIEQgZGF0YSk7Cn0KUEsDBAoAAAgAAAY7qUoDuz6czAUAAMwFAAAnAAAAY29tL3N1bi9zb3VyY2UvdHJlZS9FeHByZXNzaW9uVHJlZS5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDA1LCAyMDEzLCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4uc291cmNlLnRyZWU7CgovKioKICogQSB0cmVlIG5vZGUgdXNlZCBhcyB0aGUgYmFzZSBjbGFzcyBmb3IgdGhlIGRpZmZlcmVudCB0eXBlcyBvZgogKiBleHByZXNzaW9ucy4KICoKICogQGpscyBjaGFwdGVyIDE1CiAqCiAqIEBhdXRob3IgUGV0ZXIgdm9uIGRlciBBaCZlYWN1dGU7CiAqIEBhdXRob3IgSm9uYXRoYW4gR2liYm9ucwogKiBAc2luY2UgMS42CiAqLwpwdWJsaWMgaW50ZXJmYWNlIEV4cHJlc3Npb25UcmVlIGV4dGVuZHMgVHJlZSB7fQpQSwMECgAACAAABjupSgVf6PoZBwAAGQcAACcAAABjb20vc3VuL3NvdXJjZS90cmVlL0Fzc2lnbm1lbnRUcmVlLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMTQsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi5zb3VyY2UudHJlZTsKCi8qKgogKiBBIHRyZWUgbm9kZSBmb3IgYW4gYXNzaWdubWVudCBleHByZXNzaW9uLgogKgogKiBGb3IgZXhhbXBsZToKICogPHByZT4KICogICA8ZW0+dmFyaWFibGU8L2VtPiA9IDxlbT5leHByZXNzaW9uPC9lbT4KICogPC9wcmU+CiAqCiAqIEBqbHMgc2VjdGlvbiAxNS4yNi4xCiAqCiAqIEBhdXRob3IgUGV0ZXIgdm9uIGRlciBBaCZlYWN1dGU7CiAqIEBhdXRob3IgSm9uYXRoYW4gR2liYm9ucwogKiBAc2luY2UgMS42CiAqLwpwdWJsaWMgaW50ZXJmYWNlIEFzc2lnbm1lbnRUcmVlIGV4dGVuZHMgRXhwcmVzc2lvblRyZWUgewogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSB2YXJpYWJsZSBiZWluZyBhc3NpZ25lZCB0by4KICAgICAqIEByZXR1cm4gdGhlIHZhcmlhYmxlCiAgICAgKi8KICAgIEV4cHJlc3Npb25UcmVlIGdldFZhcmlhYmxlKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBleHByZXNzaW9uIGJlaW5nIGFzc2lnbmVkIHRvIHRoZSB2YXJpYWJsZS4KICAgICAqIEByZXR1cm4gdGhlIGV4cHJlc3Npb24KICAgICAqLwogICAgRXhwcmVzc2lvblRyZWUgZ2V0RXhwcmVzc2lvbigpOwp9ClBLAwQKAAAIAAAGO6lK7XU2zngHAAB4BwAAIgAAAGNvbS9zdW4vc291cmNlL3RyZWUvQ2F0Y2hUcmVlLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMTQsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi5zb3VyY2UudHJlZTsKCi8qKgogKiBBIHRyZWUgbm9kZSBmb3IgYSB7QGNvZGUgY2F0Y2h9IGJsb2NrIGluIGEge0Bjb2RlIHRyeX0gc3RhdGVtZW50LgogKgogKiBGb3IgZXhhbXBsZToKICogPHByZT4KICogICBjYXRjaCAoIDxlbT5wYXJhbWV0ZXI8L2VtPiApCiAqICAgICAgIDxlbT5ibG9jazwvZW0+CiAqIDwvcHJlPgogKgogKiBAamxzIHNlY3Rpb24gMTQuMjAKICoKICogQGF1dGhvciBQZXRlciB2b24gZGVyIEFoJmVhY3V0ZTsKICogQGF1dGhvciBKb25hdGhhbiBHaWJib25zCiAqIEBzaW5jZSAxLjYKICovCnB1YmxpYyBpbnRlcmZhY2UgQ2F0Y2hUcmVlIGV4dGVuZHMgVHJlZSB7CiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGNhdGNoIHZhcmlhYmxlLgogICAgICogQSBtdWx0aS1jYXRjaCB2YXJpYWJsZSB3aWxsIGhhdmUgYQogICAgICoge0BsaW5rIFVuaW9uVHlwZVRyZWUgVW5pb25UeXBlVHJlZX0KICAgICAqIGFzIHRoZSB0eXBlIG9mIHRoZSB2YXJpYWJsZS4KICAgICAqIEByZXR1cm4gdGhlIGNhdGNoIHZhcmlhYmxlCiAgICAgKi8KICAgIFZhcmlhYmxlVHJlZSBnZXRQYXJhbWV0ZXIoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGNhdGNoIGJsb2NrLgogICAgICogQHJldHVybiB0aGUgY2F0Y2ggYmxvY2sKICAgICAqLwogICAgQmxvY2tUcmVlIGdldEJsb2NrKCk7Cn0KUEsDBAoAAAgAAAY7qUqQVZU4dQcAAHUHAAAlAAAAY29tL3N1bi9zb3VyY2UvdHJlZS9Qcm92aWRlc1RyZWUuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwOSwgMjAxNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnNvdXJjZS50cmVlOwoKaW1wb3J0IGphdmEudXRpbC5MaXN0OwoKLyoqCiAqIEEgdHJlZSBub2RlIGZvciBhICdwcm92aWRlcycgZGlyZWN0aXZlIGluIGEgbW9kdWxlIGRlY2xhcmF0aW9uLgogKgogKiBGb3IgZXhhbXBsZToKICogPHByZT4KICogICAgcHJvdmlkZXMgPGVtPnNlcnZpY2UtbmFtZTwvZW0+IHdpdGggPGVtPmltcGxlbWVudGF0aW9uLW5hbWU8L2VtPjsKICogPC9wcmU+CgogKiBAc2luY2UgOQogKi8KcHVibGljIGludGVyZmFjZSBQcm92aWRlc1RyZWUgZXh0ZW5kcyBEaXJlY3RpdmVUcmVlIHsKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgbmFtZSBvZiB0aGUgc2VydmljZSB0eXBlIGJlaW5nIHByb3ZpZGVkLgogICAgICogQHJldHVybiB0aGUgbmFtZSBvZiB0aGUgc2VydmljZSB0eXBlIGJlaW5nIHByb3ZpZGVkCiAgICAgKi8KICAgIEV4cHJlc3Npb25UcmVlIGdldFNlcnZpY2VOYW1lKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBuYW1lcyBvZiB0aGUgaW1wbGVtZW50YXRpb24gdHlwZXMgYmVpbmcgcHJvdmlkZWQuCiAgICAgKiBAcmV0dXJuIHRoZSBuYW1lcyBvZiB0aGUgaW1wbGVtZW50YXRpb24gdHlwZXMgYmVpbmcgcHJvdmlkZWQKICAgICAqLwogICAgTGlzdDw/IGV4dGVuZHMgRXhwcmVzc2lvblRyZWU+IGdldEltcGxlbWVudGF0aW9uTmFtZXMoKTsKfQpQSwMECgAACAAABjupSm7zUOlIBgAASAYAACYAAABjb20vc3VuL3NvdXJjZS90cmVlL0Vycm9uZW91c1RyZWUuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAxNCwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnNvdXJjZS50cmVlOwoKaW1wb3J0IGphdmEudXRpbC5MaXN0OwoKLyoqCiAqIEEgdHJlZSBub2RlIHRvIHN0YW5kIGluIGZvciBhIG1hbGZvcm1lZCBleHByZXNzaW9uLgogKgogKiBAYXV0aG9yIFBldGVyIHZvbiBkZXIgQWgmZWFjdXRlOwogKiBAYXV0aG9yIEpvbmF0aGFuIEdpYmJvbnMKICogQHNpbmNlIDEuNgogKi8KcHVibGljIGludGVyZmFjZSBFcnJvbmVvdXNUcmVlIGV4dGVuZHMgRXhwcmVzc2lvblRyZWUgewogICAgLyoqCiAgICAgKiBSZXR1cm5zIGFueSB0cmVlcyB0aGF0IHdlcmUgc2F2ZWQgaW4gdGhpcyBub2RlLgogICAgICogQHJldHVybiB0aGUgdHJlZXMKICAgICAqLwogICAgTGlzdDw/IGV4dGVuZHMgVHJlZT4gZ2V0RXJyb3JUcmVlcygpOwp9ClBLAwQKAAAIAAAGO6lKHJ9UthsGAAAbBgAALQAAAGNvbS9zdW4vc291cmNlL3RyZWUvSW50ZXJzZWN0aW9uVHlwZVRyZWUuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAxMiwgMjAxNCwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnNvdXJjZS50cmVlOwoKaW1wb3J0IGphdmEudXRpbC5MaXN0OwoKLyoqCiAqIEEgdHJlZSBub2RlIGZvciBhbiBpbnRlcnNlY3Rpb24gdHlwZSBpbiBhIGNhc3QgZXhwcmVzc2lvbi4KICoKICogQGF1dGhvciBNYXVyaXppbyBDaW1hZGFtb3JlCiAqCiAqIEBzaW5jZSAxLjgKICovCnB1YmxpYyBpbnRlcmZhY2UgSW50ZXJzZWN0aW9uVHlwZVRyZWUgZXh0ZW5kcyBUcmVlIHsKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgYm91bmRzIG9mIHRoZSB0eXBlLgogICAgICogQHJldHVybiB0aGUgYm91bmRzCiAgICAgKi8KICAgIExpc3Q8PyBleHRlbmRzIFRyZWU+IGdldEJvdW5kcygpOwp9ClBLAwQKAAAIAAAGO6lKXSo+QfoIAAD6CAAALQAAAGNvbS9zdW4vc291cmNlL3RyZWUvTGFtYmRhRXhwcmVzc2lvblRyZWUuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAxMSwgMjAxNCwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnNvdXJjZS50cmVlOwoKaW1wb3J0IGphdmEudXRpbC5MaXN0OwoKLyoqCiAqIEEgdHJlZSBub2RlIGZvciBhIGxhbWJkYSBleHByZXNzaW9uLgogKgogKiBGb3IgZXhhbXBsZToKICogPHByZT57QGNvZGUKICogICAoKS0+e30KICogICAoTGlzdDxTdHJpbmc+IGxzKS0+bHMuc2l6ZSgpCiAqICAgKHgseSktPiB7IHJldHVybiB4ICsgeTsgfQogKiB9PC9wcmU+CiAqLwpwdWJsaWMgaW50ZXJmYWNlIExhbWJkYUV4cHJlc3Npb25UcmVlIGV4dGVuZHMgRXhwcmVzc2lvblRyZWUgewoKICAgIC8qKgogICAgICogTGFtYmRhIGV4cHJlc3Npb25zIGNvbWUgaW4gdHdvIGZvcm1zOgogICAgICogPHVsIGNvbXBhY3Q+CiAgICAgKiA8bGk+IGV4cHJlc3Npb24gbGFtYmRhcywgd2hvc2UgYm9keSBpcyBhbiBleHByZXNzaW9uLCBhbmQKICAgICAqIDxsaT4gc3RhdGVtZW50IGxhbWJkYXMsIHdob3NlIGJvZHkgaXMgYSBibG9jawogICAgICogPC91bD4KICAgICAqLwogICAgcHVibGljIGVudW0gQm9keUtpbmQgewogICAgICAgIC8qKiBlbnVtIGNvbnN0YW50IGZvciBleHByZXNzaW9uIGxhbWJkYXMgKi8KICAgICAgICBFWFBSRVNTSU9OLAogICAgICAgIC8qKiBlbnVtIGNvbnN0YW50IGZvciBzdGF0ZW1lbnQgbGFtYmRhcyAqLwogICAgICAgIFNUQVRFTUVOVAogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgcGFyYW1ldGVycyBvZiB0aGlzIGxhbWJkYSBleHByZXNzaW9uLgogICAgICogQHJldHVybiB0aGUgcGFyYW1ldGVycwogICAgICovCiAgICBMaXN0PD8gZXh0ZW5kcyBWYXJpYWJsZVRyZWU+IGdldFBhcmFtZXRlcnMoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGJvZHkgb2YgdGhlIGxhbWJkYSBleHByZXNzaW9uLgogICAgICogQHJldHVybiB0aGUgYm9keQogICAgICovCiAgICBUcmVlIGdldEJvZHkoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGtpbmQgb2YgdGhlIGJvZHkgb2YgdGhlIGxhbWJkYSBleHByZXNzaW9uLgogICAgICogQHJldHVybiB0aGUga2luZCBvZiB0aGUgYm9keQogICAgICovCiAgICBCb2R5S2luZCBnZXRCb2R5S2luZCgpOwp9ClBLAwQKAAAIAAAGO6lKdGJaXgwIAAAMCAAAJQAAAGNvbS9zdW4vc291cmNlL3RyZWUvUmVxdWlyZXNUcmVlLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDksIDIwMTYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi5zb3VyY2UudHJlZTsKCi8qKgogKiBBIHRyZWUgbm9kZSBmb3IgYSAncmVxdWlyZXMnIGRpcmVjdGl2ZSBpbiBhIG1vZHVsZSBkZWNsYXJhdGlvbi4KICoKICogRm9yIGV4YW1wbGU6CiAqIDxwcmU+CiAqICAgIHJlcXVpcmVzIDxlbT5tb2R1bGUtbmFtZTwvZW0+OwogKiAgICByZXF1aXJlcyBzdGF0aWMgPGVtPm1vZHVsZS1uYW1lPC9lbT47CiAqICAgIHJlcXVpcmVzIHRyYW5zaXRpdmUgPGVtPm1vZHVsZS1uYW1lPC9lbT47CiAqIDwvcHJlPgogKgogKiBAc2luY2UgOQogKi8KcHVibGljIGludGVyZmFjZSBSZXF1aXJlc1RyZWUgZXh0ZW5kcyBEaXJlY3RpdmVUcmVlIHsKICAgIC8qKgogICAgICogUmV0dXJucyB0cnVlIGlmIHRoaXMgaXMgYSAicmVxdWlyZXMgc3RhdGljIiBkaXJlY3RpdmUuCiAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhpcyBpcyBhICJyZXF1aXJlcyBzdGF0aWMiIGRpcmVjdGl2ZQogICAgICovCiAgICBib29sZWFuIGlzU3RhdGljKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhpcyBpcyBhICJyZXF1aXJlcyB0cmFuc2l0aXZlIiBkaXJlY3RpdmUuCiAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhpcyBpcyBhICJyZXF1aXJlcyB0cmFuc2l0aXZlIiBkaXJlY3RpdmUKICAgICAqLwogICAgYm9vbGVhbiBpc1RyYW5zaXRpdmUoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIG5hbWUgb2YgdGhlIG1vZHVsZSB0aGF0IGlzIHJlcXVpcmVkLgogICAgICogQHJldHVybiB0aGUgbmFtZSBvZiB0aGUgbW9kdWxlIHRoYXQgaXMgcmVxdWlyZWQKICAgICAqLwogICAgRXhwcmVzc2lvblRyZWUgZ2V0TW9kdWxlTmFtZSgpOwp9ClBLAwQKAAAIAAAGO6lKLlUaO7gIAAC4CAAAHwAAAGNvbS9zdW4vc291cmNlL3RyZWUvSWZUcmVlLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMTQsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi5zb3VyY2UudHJlZTsKCi8qKgogKiBBIHRyZWUgbm9kZSBmb3IgYW4ge0Bjb2RlIGlmfSBzdGF0ZW1lbnQuCiAqCiAqIEZvciBleGFtcGxlOgogKiA8cHJlPgogKiAgIGlmICggPGVtPmNvbmRpdGlvbjwvZW0+ICkKICogICAgICA8ZW0+dGhlblN0YXRlbWVudDwvZW0+CiAqCiAqICAgaWYgKCA8ZW0+Y29uZGl0aW9uPC9lbT4gKQogKiAgICAgICA8ZW0+dGhlblN0YXRlbWVudDwvZW0+CiAqICAgZWxzZQogKiAgICAgICA8ZW0+ZWxzZVN0YXRlbWVudDwvZW0+CiAqIDwvcHJlPgogKgogKiBAamxzIHNlY3Rpb24gMTQuOQogKgogKiBAYXV0aG9yIFBldGVyIHZvbiBkZXIgQWgmZWFjdXRlOwogKiBAYXV0aG9yIEpvbmF0aGFuIEdpYmJvbnMKICogQHNpbmNlIDEuNgogKi8KcHVibGljIGludGVyZmFjZSBJZlRyZWUgZXh0ZW5kcyBTdGF0ZW1lbnRUcmVlIHsKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgY29uZGl0aW9uIG9mIHRoZSBpZi1zdGF0ZW1lbnQuCiAgICAgKiBAcmV0dXJuIHRoZSBjb25kaXRpb24KICAgICAqLwogICAgRXhwcmVzc2lvblRyZWUgZ2V0Q29uZGl0aW9uKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBzdGF0ZW1lbnQgdG8gYmUgZXhlY3V0ZWQgaWYgdGhlIGNvbmRpdGlvbiBpcyB0cnVlCiAgICAgKiBAcmV0dXJuIHRoZSBzdGF0ZW1lbnQgdG8gYmUgZXhlY3V0ZWQgaWYgdGhlIGNvbmRpdGlvbiBpcyB0cnVlCiAgICAgKi8KICAgIFN0YXRlbWVudFRyZWUgZ2V0VGhlblN0YXRlbWVudCgpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgc3RhdGVtZW50IHRvIGJlIGV4ZWN1dGVkIGlmIHRoZSBjb25kaXRpb24gaXMgZmFsc2UsCiAgICAgKiBvciB7QGNvZGUgbnVsbH0gaWYgdGhlcmUgaXMgbm8gc3VjaCBzdGF0ZW1lbnQuCiAgICAgKiBAcmV0dXJuIHRoZSBzdGF0ZW1lbnQgdG8gYmUgZXhlY3V0ZWQgaWYgdGhlIGNvbmRpdGlvbiBpcyBmYWxzZQogICAgICovCiAgICBTdGF0ZW1lbnRUcmVlIGdldEVsc2VTdGF0ZW1lbnQoKTsKfQpQSwMECgAACAAABjupSoeKjvhUBwAAVAcAACMAAABjb20vc3VuL3NvdXJjZS90cmVlL1N3aXRjaFRyZWUuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAxNCwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnNvdXJjZS50cmVlOwoKaW1wb3J0IGphdmEudXRpbC5MaXN0OwoKLyoqCiAqIEEgdHJlZSBub2RlIGZvciBhIHtAY29kZSBzd2l0Y2h9IHN0YXRlbWVudC4KICoKICogRm9yIGV4YW1wbGU6CiAqIDxwcmU+CiAqICAgc3dpdGNoICggPGVtPmV4cHJlc3Npb248L2VtPiApIHsKICogICAgIDxlbT5jYXNlczwvZW0+CiAqICAgfQogKiA8L3ByZT4KICoKICogQGpscyBzZWN0aW9uIDE0LjExCiAqCiAqIEBhdXRob3IgUGV0ZXIgdm9uIGRlciBBaCZlYWN1dGU7CiAqIEBhdXRob3IgSm9uYXRoYW4gR2liYm9ucwogKiBAc2luY2UgMS42CiAqLwpwdWJsaWMgaW50ZXJmYWNlIFN3aXRjaFRyZWUgZXh0ZW5kcyBTdGF0ZW1lbnRUcmVlIHsKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgZXhwcmVzc2lvbiBmb3IgdGhlIHtAY29kZSBzd2l0Y2h9IHN0YXRlbWVudC4KICAgICAqIEByZXR1cm4gdGhlIGV4cHJlc3Npb24KICAgICAqLwogICAgRXhwcmVzc2lvblRyZWUgZ2V0RXhwcmVzc2lvbigpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgY2FzZXMgZm9yIHRoZSB7QGNvZGUgc3dpdGNofSBzdGF0ZW1lbnQuCiAgICAgKiBAcmV0dXJuIHRoZSBjYXNlcwogICAgICovCiAgICBMaXN0PD8gZXh0ZW5kcyBDYXNlVHJlZT4gZ2V0Q2FzZXMoKTsKfQpQSwMECgAACAAABjupSouOaLwRCAAAEQgAACMAAABjb20vc3VuL3NvdXJjZS90cmVlL0ltcG9ydFRyZWUuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAxNywgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnNvdXJjZS50cmVlOwoKLyoqCiAqIEEgdHJlZSBub2RlIGZvciBhbiBpbXBvcnQgZGVjbGFyYXRpb24uCiAqCiAqIEZvciBleGFtcGxlOgogKiA8cHJlPgogKiAgIGltcG9ydCA8ZW0+cXVhbGlmaWVkSWRlbnRpZmllcjwvZW0+IDsKICoKICogICBzdGF0aWMgaW1wb3J0IDxlbT5xdWFsaWZpZWRJZGVudGlmaWVyPC9lbT4gOwogKiA8L3ByZT4KICoKICogQGpscyBzZWN0aW9uIDcuNQogKgogKiBAYXV0aG9yIFBldGVyIHZvbiBkZXIgQWgmZWFjdXRlOwogKiBAYXV0aG9yIEpvbmF0aGFuIEdpYmJvbnMKICogQHNpbmNlIDEuNgogKi8KcHVibGljIGludGVyZmFjZSBJbXBvcnRUcmVlIGV4dGVuZHMgVHJlZSB7CiAgICAvKioKICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGlzIGlzIGEgc3RhdGljIGltcG9ydCBkZWNsYXJhdGlvbi4KICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGlzIGlzIGEgc3RhdGljIGltcG9ydAogICAgICovCiAgICBib29sZWFuIGlzU3RhdGljKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBxdWFsaWZpZWQgaWRlbnRpZmllciBmb3IgdGhlIGRlY2xhcmF0aW9uKHMpCiAgICAgKiBiZWluZyBpbXBvcnRlZC4KICAgICAqIElmIHRoaXMgaXMgYW4gaW1wb3J0LW9uLWRlbWFuZCBkZWNsYXJhdGlvbiwgdGhlCiAgICAgKiBxdWFsaWZpZWQgaWRlbnRpZmllciB3aWxsIGVuZCBpbiAiKiIuCiAgICAgKiBAcmV0dXJuIGEgcXVhbGlmaWVkIGlkZW50aWZpZXIsIGVuZGluZyBpbiAiKiIgaWYgYW5kIG9ubHkgaWYKICAgICAqIHRoaXMgaXMgYW4gaW1wb3J0LW9uLWRlbWFuZAogICAgICovCiAgICBUcmVlIGdldFF1YWxpZmllZElkZW50aWZpZXIoKTsKfQpQSwMECgAACAAABjupSpOXx7WrBwAAqwcAACoAAABjb20vc3VuL3NvdXJjZS90cmVlL0Fubm90YXRlZFR5cGVUcmVlLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDgsIDIwMTQsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi5zb3VyY2UudHJlZTsKCmltcG9ydCBqYXZhLnV0aWwuTGlzdDsKCi8qKgogKiBBIHRyZWUgbm9kZSBmb3IgYW4gYW5ub3RhdGVkIHR5cGUuCiAqCiAqIEZvciBleGFtcGxlOgogKiA8cHJlPgogKiAgICB7QGNvZGUgQH08ZW0+YW5ub3RhdGlvblR5cGUgU3RyaW5nPC9lbT4KICogICAge0Bjb2RlIEB9PGVtPmFubm90YXRpb25UeXBlPC9lbT4gKCA8ZW0+YXJndW1lbnRzPC9lbT4gKSA8ZW0+RGF0ZTwvZW0+CiAqIDwvcHJlPgogKgogKiBAc2VlICJKU1IgMzA4OiBBbm5vdGF0aW9ucyBvbiBKYXZhIFR5cGVzIgogKgogKiBAYXV0aG9yIE1haG1vb2QgQWxpCiAqIEBzaW5jZSAxLjgKICovCnB1YmxpYyBpbnRlcmZhY2UgQW5ub3RhdGVkVHlwZVRyZWUgZXh0ZW5kcyBFeHByZXNzaW9uVHJlZSB7CiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGFubm90YXRpb25zIGFzc29jaWF0ZWQgd2l0aCB0aGlzIHR5cGUgZXhwcmVzc2lvbi4KICAgICAqIEByZXR1cm4gdGhlIGFubm90YXRpb25zCiAgICAgKi8KICAgIExpc3Q8PyBleHRlbmRzIEFubm90YXRpb25UcmVlPiBnZXRBbm5vdGF0aW9ucygpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgdW5kZXJseWluZyB0eXBlIHdpdGggd2hpY2ggdGhlIGFubm90YXRpb25zIGFyZSBhc3NvY2lhdGVkLgogICAgICogQHJldHVybiB0aGUgdW5kZXJseWluZyB0eXBlCiAgICAgKi8KICAgIEV4cHJlc3Npb25UcmVlIGdldFVuZGVybHlpbmdUeXBlKCk7Cn0KUEsDBAoAAAgAAAY7qUq6Ys91hwYAAIcGAAAjAAAAY29tL3N1bi9zb3VyY2UvdHJlZS9SZXR1cm5UcmVlLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMTQsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi5zb3VyY2UudHJlZTsKCi8qKgogKiBBIHRyZWUgbm9kZSBmb3IgYSB7QGNvZGUgcmV0dXJufSBzdGF0ZW1lbnQuCiAqCiAqIEZvciBleGFtcGxlOgogKiA8cHJlPgogKiAgIHJldHVybjsKICogICByZXR1cm4gPGVtPmV4cHJlc3Npb248L2VtPjsKICogPC9wcmU+CiAqCiAqIEBqbHMgc2VjdGlvbiAxNC4xNwogKgogKiBAYXV0aG9yIFBldGVyIHZvbiBkZXIgQWgmZWFjdXRlOwogKiBAYXV0aG9yIEpvbmF0aGFuIEdpYmJvbnMKICogQHNpbmNlIDEuNgogKi8KcHVibGljIGludGVyZmFjZSBSZXR1cm5UcmVlIGV4dGVuZHMgU3RhdGVtZW50VHJlZSB7CiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGV4cHJlc3Npb24gdG8gYmUgcmV0dXJuZWQuCiAgICAgKiBAcmV0dXJuIHRoZSBleHByZXNzaW9uCiAgICAgKi8KICAgIEV4cHJlc3Npb25UcmVlIGdldEV4cHJlc3Npb24oKTsKfQpQSwMECgAACAAABjupSiEy9Z9UBgAAVAYAACYAAABjb20vc3VuL3NvdXJjZS90cmVlL1VuaW9uVHlwZVRyZWUuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAxMCwgMjAxNCwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnNvdXJjZS50cmVlOwoKaW1wb3J0IGphdmEudXRpbC5MaXN0OwoKLyoqCiAqIEEgdHJlZSBub2RlIGZvciBhIHVuaW9uIHR5cGUgZXhwcmVzc2lvbiBpbiBhIG11bHRpY2F0Y2gKICogdmFyaWFibGUgZGVjbGFyYXRpb24uCiAqCiAqIEBhdXRob3IgTWF1cml6aW8gQ2ltYWRhbW9yZQogKgogKiBAc2luY2UgMS43CiAqLwpwdWJsaWMgaW50ZXJmYWNlIFVuaW9uVHlwZVRyZWUgZXh0ZW5kcyBUcmVlIHsKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgYWx0ZXJuYXRpdmUgdHlwZSBleHByZXNzaW9ucy4KICAgICAqIEByZXR1cm4gdGhlIGFsdGVybmF0aXZlIHR5cGUgZXhwcmVzc2lvbnMKICAgICAqLwogICAgTGlzdDw/IGV4dGVuZHMgVHJlZT4gZ2V0VHlwZUFsdGVybmF0aXZlcygpOwp9ClBLAwQKAAAIAAAGO6lKdQ9EVP8JAAD/CQAAJQAAAGNvbS9zdW4vc291cmNlL3RyZWUvVmFyaWFibGVUcmVlLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMTQsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi5zb3VyY2UudHJlZTsKCmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuTmFtZTsKCi8qKgogKiBBIHRyZWUgbm9kZSBmb3IgYSB2YXJpYWJsZSBkZWNsYXJhdGlvbi4KICoKICogRm9yIGV4YW1wbGU6CiAqIDxwcmU+CiAqICAgPGVtPm1vZGlmaWVyczwvZW0+IDxlbT50eXBlPC9lbT4gPGVtPm5hbWU8L2VtPiA8ZW0+aW5pdGlhbGl6ZXI8L2VtPiA7CiAqICAgPGVtPm1vZGlmaWVyczwvZW0+IDxlbT50eXBlPC9lbT4gPGVtPnF1YWxpZmllZC1uYW1lPC9lbT4udGhpcwogKiA8L3ByZT4KICoKICogQGpscyBzZWN0aW9ucyA4LjMgYW5kIDE0LjQKICoKICogQGF1dGhvciBQZXRlciB2b24gZGVyIEFoJmVhY3V0ZTsKICogQGF1dGhvciBKb25hdGhhbiBHaWJib25zCiAqIEBzaW5jZSAxLjYKICovCnB1YmxpYyBpbnRlcmZhY2UgVmFyaWFibGVUcmVlIGV4dGVuZHMgU3RhdGVtZW50VHJlZSB7CiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIG1vZGlmaWVycywgaW5jbHVkaW5nIGFueSBhbm5vdGF0aW9ucywgb24gdGhlIGRlY2xhcmF0aW9uLgogICAgICogQHJldHVybiB0aGUgbW9kaWZpZXJzCiAgICAgKi8KICAgIE1vZGlmaWVyc1RyZWUgZ2V0TW9kaWZpZXJzKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBuYW1lIG9mIHRoZSB2YXJpYWJsZSBiZWluZyBkZWNsYXJlZC4KICAgICAqIEByZXR1cm4gdGhlIG5hbWUKICAgICAqLwogICAgTmFtZSBnZXROYW1lKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBxdWFsaWZpZWQgaWRlbnRpZmllciBmb3IgdGhlIG5hbWUgYmVpbmcgImRlY2xhcmVkIi4KICAgICAqIFRoaXMgaXMgb25seSB1c2VkIGluIGNlcnRhaW4gY2FzZXMgZm9yIHRoZSByZWNlaXZlciBvZiBhCiAgICAgKiBtZXRob2QgZGVjbGFyYXRpb24uIFJldHVybnMge0Bjb2RlIG51bGx9IGluIGFsbCBvdGhlciBjYXNlcy4KICAgICAqIEByZXR1cm4gdGhlIHF1YWxpZmllZCBpZGVudGlmaWVyIG9mIGEgcmVjZWl2ZXIgZGVjbGFyYXRpb24KICAgICAqLwogICAgRXhwcmVzc2lvblRyZWUgZ2V0TmFtZUV4cHJlc3Npb24oKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHR5cGUgb2YgdGhlIHZhcmlhYmxlIGJlaW5nIGRlY2xhcmVkLgogICAgICogQHJldHVybiB0aGUgdHlwZQogICAgICovCiAgICBUcmVlIGdldFR5cGUoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGluaXRpYWxpemVyIGZvciB0aGUgdmFyaWFibGUsIG9yIHtAY29kZSBudWxsfSBpZiBub25lLgogICAgICogQHJldHVybiB0aGUgaW5pdGlhbGl6ZXIKICAgICAqLwogICAgRXhwcmVzc2lvblRyZWUgZ2V0SW5pdGlhbGl6ZXIoKTsKfQpQSwMECgAACAAABjupShVXWidhCAAAYQgAAC0AAABjb20vc3VuL3NvdXJjZS90cmVlL01ldGhvZEludm9jYXRpb25UcmVlLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMTQsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi5zb3VyY2UudHJlZTsKCmltcG9ydCBqYXZhLnV0aWwuTGlzdDsKCi8qKgogKiBBIHRyZWUgbm9kZSBmb3IgYSBtZXRob2QgaW52b2NhdGlvbiBleHByZXNzaW9uLgogKgogKiBGb3IgZXhhbXBsZToKICogPHByZT4KICogICA8ZW0+aWRlbnRpZmllcjwvZW0+ICggPGVtPmFyZ3VtZW50czwvZW0+ICkKICoKICogICB0aGlzIC4gPGVtPnR5cGVBcmd1bWVudHM8L2VtPiA8ZW0+aWRlbnRpZmllcjwvZW0+ICggPGVtPmFyZ3VtZW50czwvZW0+ICkKICogPC9wcmU+CiAqCiAqIEBqbHMgc2VjdGlvbiAxNS4xMgogKgogKiBAYXV0aG9yIFBldGVyIHZvbiBkZXIgQWgmZWFjdXRlOwogKiBAYXV0aG9yIEpvbmF0aGFuIEdpYmJvbnMKICogQHNpbmNlIDEuNgogKi8KcHVibGljIGludGVyZmFjZSBNZXRob2RJbnZvY2F0aW9uVHJlZSBleHRlbmRzIEV4cHJlc3Npb25UcmVlIHsKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgdHlwZSBhcmd1bWVudHMgZm9yIHRoaXMgbWV0aG9kIGludm9jYXRpb24uCiAgICAgKiBAcmV0dXJuIHRoZSB0eXBlIGFyZ3VtZW50cwogICAgICovCiAgICBMaXN0PD8gZXh0ZW5kcyBUcmVlPiBnZXRUeXBlQXJndW1lbnRzKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBleHByZXNzaW9uIGlkZW50aWZ5aW5nIHRoZSBtZXRob2QgdG8gYmUgaW52b2tlZC4KICAgICAqIEByZXR1cm4gdGhlIG1ldGhvZCBzZWxlY3Rpb24gZXhwcmVzc2lvbgogICAgICovCiAgICBFeHByZXNzaW9uVHJlZSBnZXRNZXRob2RTZWxlY3QoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGFyZ3VtZW50cyBmb3IgdGhlIG1ldGhvZCBpbnZvY2F0aW9uLgogICAgICogQHJldHVybiB0aGUgYXJndW1lbnRzCiAgICAgKi8KICAgIExpc3Q8PyBleHRlbmRzIEV4cHJlc3Npb25UcmVlPiBnZXRBcmd1bWVudHMoKTsKfQpQSwMECgAACAAABjupSm4boGcVBwAAFQcAACYAAABjb20vc3VuL3NvdXJjZS90cmVlL1doaWxlTG9vcFRyZWUuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAxNCwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnNvdXJjZS50cmVlOwoKLyoqCiAqIEEgdHJlZSBub2RlIGZvciBhIHtAY29kZSB3aGlsZX0gbG9vcCBzdGF0ZW1lbnQuCiAqCiAqIEZvciBleGFtcGxlOgogKiA8cHJlPgogKiAgIHdoaWxlICggPGVtPmNvbmRpdGlvbjwvZW0+ICkKICogICAgIDxlbT5zdGF0ZW1lbnQ8L2VtPgogKiA8L3ByZT4KICoKICoKICogQGpscyBzZWN0aW9uIDE0LjEyCiAqCiAqIEBhdXRob3IgUGV0ZXIgdm9uIGRlciBBaCZlYWN1dGU7CiAqIEBhdXRob3IgSm9uYXRoYW4gR2liYm9ucwogKiBAc2luY2UgMS42CiAqLwpwdWJsaWMgaW50ZXJmYWNlIFdoaWxlTG9vcFRyZWUgZXh0ZW5kcyBTdGF0ZW1lbnRUcmVlIHsKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgY29uZGl0aW9uIG9mIHRoZSBsb29wLgogICAgICogQHJldHVybiB0aGUgY29uZGl0aW9uCiAgICAgKi8KICAgIEV4cHJlc3Npb25UcmVlIGdldENvbmRpdGlvbigpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgYm9keSBvZiB0aGUgbG9vcC4KICAgICAqIEByZXR1cm4gdGhlIGJvZHkgb2YgdGhlIGxvb3AKICAgICAqLwogICAgU3RhdGVtZW50VHJlZSBnZXRTdGF0ZW1lbnQoKTsKfQpQSwMECgAACAAABjupSsCXzW2HBwAAhwcAACMAAABjb20vc3VuL3NvdXJjZS90cmVlL0JpbmFyeVRyZWUuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAxNCwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnNvdXJjZS50cmVlOwoKLyoqCiAqIEEgdHJlZSBub2RlIGZvciBhIGJpbmFyeSBleHByZXNzaW9uLgogKiBVc2Uge0BsaW5rICNnZXRLaW5kIGdldEtpbmR9IHRvIGRldGVybWluZSB0aGUga2luZCBvZiBvcGVyYXRvci4KICoKICogRm9yIGV4YW1wbGU6CiAqIDxwcmU+CiAqICAgPGVtPmxlZnRPcGVyYW5kPC9lbT4gPGVtPm9wZXJhdG9yPC9lbT4gPGVtPnJpZ2h0T3BlcmFuZDwvZW0+CiAqIDwvcHJlPgogKgogKiBAamxzIHNlY3Rpb25zIDE1LjE3IHRvIDE1LjI0CiAqCiAqIEBhdXRob3IgUGV0ZXIgdm9uIGRlciBBaCZlYWN1dGU7CiAqIEBhdXRob3IgSm9uYXRoYW4gR2liYm9ucwogKiBAc2luY2UgMS42CiAqLwpwdWJsaWMgaW50ZXJmYWNlIEJpbmFyeVRyZWUgZXh0ZW5kcyBFeHByZXNzaW9uVHJlZSB7CiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGxlZnQgKGZpcnN0KSBvcGVyYW5kIG9mIHRoZSBleHByZXNzaW9uLgogICAgICogQHJldHVybiB0aGUgbGVmdCBvcGVyYW5kCiAgICAgKi8KICAgIEV4cHJlc3Npb25UcmVlIGdldExlZnRPcGVyYW5kKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSByaWdodCAoc2Vjb25kKSBvcGVyYW5kIG9mIHRoZSBleHByZXNzaW9uLgogICAgICogQHJldHVybiB0aGUgcmlnaHQgb3BlcmFuZAogICAgICovCiAgICBFeHByZXNzaW9uVHJlZSBnZXRSaWdodE9wZXJhbmQoKTsKfQpQSwMECgAACAAABjupSpzckyFKCQAASgkAACwAAABjb20vc3VuL3NvdXJjZS90cmVlL01lbWJlclJlZmVyZW5jZVRyZWUuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAxMSwgMjAxNCwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnNvdXJjZS50cmVlOwoKaW1wb3J0IGphdmEudXRpbC5MaXN0OwoKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC5OYW1lOwoKLyoqCiAqIEEgdHJlZSBub2RlIGZvciBhIG1lbWJlciByZWZlcmVuY2UgZXhwcmVzc2lvbi4KICoKICogRm9yIGV4YW1wbGU6CiAqIDxwcmU+CiAqICAgPGVtPmV4cHJlc3Npb248L2VtPiAjIDxlbT5bIGlkZW50aWZpZXIgfCBuZXcgXTwvZW0+CiAqIDwvcHJlPgogKgogKiBAc2luY2UgMS44CiAqLwpwdWJsaWMgaW50ZXJmYWNlIE1lbWJlclJlZmVyZW5jZVRyZWUgZXh0ZW5kcyBFeHByZXNzaW9uVHJlZSB7CgogICAgLyoqCiAgICAgKiBUaGVyZSBhcmUgdHdvIGtpbmRzIG9mIG1lbWJlciByZWZlcmVuY2VzOiAoaSkgbWV0aG9kIHJlZmVyZW5jZXMgYW5kCiAgICAgKiAoaWkpIGNvbnN0cnVjdG9yIHJlZmVyZW5jZXMKICAgICAqLwogICAgcHVibGljIGVudW0gUmVmZXJlbmNlTW9kZSB7CiAgICAgICAgLyoqIGVudW0gY29uc3RhbnQgZm9yIG1ldGhvZCByZWZlcmVuY2VzLiAqLwogICAgICAgIElOVk9LRSwKICAgICAgICAvKiogZW51bSBjb25zdGFudCBmb3IgY29uc3RydWN0b3IgcmVmZXJlbmNlcy4gKi8KICAgICAgICBORVcKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIG1vZGUgb2YgdGhlIHJlZmVyZW5jZS4KICAgICAqIEByZXR1cm4gdGhlIG1vZGUKICAgICAqLwogICAgUmVmZXJlbmNlTW9kZSBnZXRNb2RlKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBxdWFsaWZpZXIgZXhwcmVzc2lvbiBmb3IgdGhlIHJlZmVyZW5jZS4KICAgICAqIEByZXR1cm4gdGhlIHF1YWxpZmllciBleHByZXNzaW9uCiAgICAgKi8KICAgIEV4cHJlc3Npb25UcmVlIGdldFF1YWxpZmllckV4cHJlc3Npb24oKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIG5hbWUgb2YgdGhlIHJlZmVyZW5jZS4KICAgICAqIEByZXR1cm4gdGhlIG5hbWUKICAgICAqLwogICAgTmFtZSBnZXROYW1lKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSB0eXBlIGFyZ3VtZW50cyBmb3IgdGhlIHJlZmVyZW5jZS4KICAgICAqIEByZXR1cm4gdGhlIHR5cGUgYXJndW1lbnRzCiAgICAgKi8KICAgIExpc3Q8PyBleHRlbmRzIEV4cHJlc3Npb25UcmVlPiBnZXRUeXBlQXJndW1lbnRzKCk7Cn0KUEsDBAoAAAgAAAY7qUr2HoyIKgcAACoHAAAjAAAAY29tL3N1bi9zb3VyY2UvdHJlZS9Bc3NlcnRUcmVlLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMTQsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi5zb3VyY2UudHJlZTsKCi8qKgogKiBBIHRyZWUgbm9kZSBmb3IgYW4ge0Bjb2RlIGFzc2VydH0gc3RhdGVtZW50LgogKgogKiBGb3IgZXhhbXBsZToKICogPHByZT4KICogICBhc3NlcnQgPGVtPmNvbmRpdGlvbjwvZW0+IDsKICoKICogICBhc3NlcnQgPGVtPmNvbmRpdGlvbjwvZW0+IDogPGVtPmRldGFpbDwvZW0+IDsKICogPC9wcmU+CiAqCiAqIEBqbHMgc2VjdGlvbiAxNC4xMAogKgogKiBAYXV0aG9yIFBldGVyIHZvbiBkZXIgQWgmZWFjdXRlOwogKiBAYXV0aG9yIEpvbmF0aGFuIEdpYmJvbnMKICogQHNpbmNlIDEuNgogKi8KcHVibGljIGludGVyZmFjZSBBc3NlcnRUcmVlIGV4dGVuZHMgU3RhdGVtZW50VHJlZSB7CiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGNvbmRpdGlvbiBiZWluZyBhc3NlcnRlZC4KICAgICAqIEByZXR1cm4gdGhlIGNvbmRpdGlvbgogICAgICovCiAgICBFeHByZXNzaW9uVHJlZSBnZXRDb25kaXRpb24oKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGRldGFpbCBleHByZXNzaW9uLgogICAgICogQHJldHVybiB0aGUgZGV0YWlsIGV4cHJlc3Npb24KICAgICAqLwogICAgRXhwcmVzc2lvblRyZWUgZ2V0RGV0YWlsKCk7Cn0KUEsDBAoAAAgAAAY7qUoVdTd01QcAANUHAAAhAAAAY29tL3N1bi9zb3VyY2UvdHJlZS9DYXNlVHJlZS5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDA1LCAyMDE0LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4uc291cmNlLnRyZWU7CgppbXBvcnQgamF2YS51dGlsLkxpc3Q7CgovKioKICogQSB0cmVlIG5vZGUgZm9yIGEge0Bjb2RlIGNhc2V9IGluIGEge0Bjb2RlIHN3aXRjaH0gc3RhdGVtZW50LgogKgogKiBGb3IgZXhhbXBsZToKICogPHByZT4KICogICBjYXNlIDxlbT5leHByZXNzaW9uPC9lbT4gOgogKiAgICAgICA8ZW0+c3RhdGVtZW50czwvZW0+CiAqCiAqICAgZGVmYXVsdCA6CiAqICAgICAgIDxlbT5zdGF0ZW1lbnRzPC9lbT4KICogPC9wcmU+CiAqCiAqIEBqbHMgc2VjdGlvbiAxNC4xMQogKgogKiBAYXV0aG9yIFBldGVyIHZvbiBkZXIgQWgmZWFjdXRlOwogKiBAYXV0aG9yIEpvbmF0aGFuIEdpYmJvbnMKICogQHNpbmNlIDEuNgogKi8KcHVibGljIGludGVyZmFjZSBDYXNlVHJlZSBleHRlbmRzIFRyZWUgewogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBleHByZXNzaW9uIGZvciB0aGUgY2FzZSwgb3IKICAgICAqIHtAY29kZSBudWxsfSBpZiB0aGlzIGlzIHRoZSBkZWZhdWx0IGNhc2UuCiAgICAgKiBAcmV0dXJuIHRoZSBleHByZXNzaW9uIGZvciB0aGUgY2FzZSwgb3IgbnVsbAogICAgICovCiAgICBFeHByZXNzaW9uVHJlZSBnZXRFeHByZXNzaW9uKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBzdGF0ZW1lbnRzIGxhYmVsZWQgYnkgdGhlIGNhc2UuCiAgICAgKiBAcmV0dXJuIHRoZSBzdGF0ZW1lbnRzIGxhYmVsZWQgYnkgdGhlIGNhc2UKICAgICAqLwogICAgTGlzdDw/IGV4dGVuZHMgU3RhdGVtZW50VHJlZT4gZ2V0U3RhdGVtZW50cygpOwp9ClBLAwQKAAAIAAAGO6lKIBm0B38GAAB/BgAAJwAAAGNvbS9zdW4vc291cmNlL3RyZWUvSWRlbnRpZmllclRyZWUuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAxNCwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnNvdXJjZS50cmVlOwoKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC5OYW1lOwoKLyoqCiAqIEEgdHJlZSBub2RlIGZvciBhbiBpZGVudGlmaWVyIGV4cHJlc3Npb24uCiAqCiAqIEZvciBleGFtcGxlOgogKiA8cHJlPgogKiAgIDxlbT5uYW1lPC9lbT4KICogPC9wcmU+CiAqCiAqIEBqbHMgc2VjdGlvbiA2LjUuNi4xCiAqCiAqIEBhdXRob3IgUGV0ZXIgdm9uIGRlciBBaCZlYWN1dGU7CiAqIEBhdXRob3IgSm9uYXRoYW4gR2liYm9ucwogKiBAc2luY2UgMS42CiAqLwpwdWJsaWMgaW50ZXJmYWNlIElkZW50aWZpZXJUcmVlIGV4dGVuZHMgRXhwcmVzc2lvblRyZWUgewogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBuYW1lIG9mIHRoZSBpZGVudGlmaWVyLgogICAgICogQHJldHVybiB0aGUgbmFtZQogICAgICovCiAgICBOYW1lIGdldE5hbWUoKTsKfQpQSwMECgAACAAABjupSrjyWLseCQAAHgkAACMAAABjb20vc3VuL3NvdXJjZS90cmVlL01vZHVsZVRyZWUuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwOSwgMjAxNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnNvdXJjZS50cmVlOwoKaW1wb3J0IGphdmEudXRpbC5MaXN0OwoKCi8qKgogKiBBIHRyZWUgbm9kZSBmb3IgYSBtb2R1bGUgZGVjbGFyYXRpb24uCiAqCiAqIEZvciBleGFtcGxlOgogKiA8cHJlPgogKiAgICA8ZW0+YW5ub3RhdGlvbnM8L2VtPgogKiAgICBbb3Blbl0gbW9kdWxlIDxlbT5tb2R1bGUtbmFtZTwvZW0+IHsKICogICAgICAgIDxlbT5kaXJlY3RpdmVzPC9lbT4KICogICAgfQogKiA8L3ByZT4KICoKICogQHNpbmNlIDkKICovCnB1YmxpYyBpbnRlcmZhY2UgTW9kdWxlVHJlZSBleHRlbmRzIFRyZWUgewogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBhbm5vdGF0aW9ucyBhc3NvY2lhdGVkIHdpdGggdGhpcyBtb2R1bGUgZGVjbGFyYXRpb24uCiAgICAgKiBAcmV0dXJuIHRoZSBhbm5vdGF0aW9ucwogICAgICovCiAgICBMaXN0PD8gZXh0ZW5kcyBBbm5vdGF0aW9uVHJlZT4gZ2V0QW5ub3RhdGlvbnMoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHR5cGUgb2YgdGhpcyBtb2R1bGUuCiAgICAgKiBAcmV0dXJuIHRoZSB0eXBlIG9mIHRoaXMgbW9kdWxlCiAgICAgKi8KICAgIE1vZHVsZUtpbmQgZ2V0TW9kdWxlVHlwZSgpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgbmFtZSBvZiB0aGUgbW9kdWxlLgogICAgICogQHJldHVybiB0aGUgbmFtZSBvZiB0aGUgbW9kdWxlCiAgICAgKi8KICAgIEV4cHJlc3Npb25UcmVlIGdldE5hbWUoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGRpcmVjdGl2ZXMgaW4gdGhlIG1vZHVsZSBkZWNsYXJhdGlvbi4KICAgICAqIEByZXR1cm4gdGhlIGRpcmVjdGl2ZXMgaW4gdGhlIG1vZHVsZSBkZWNsYXJhdGlvbgogICAgICovCiAgICBMaXN0PD8gZXh0ZW5kcyBEaXJlY3RpdmVUcmVlPiBnZXREaXJlY3RpdmVzKCk7CgogICAgLyoqCiAgICAgKiBUaGUga2luZCBvZiB0aGUgbW9kdWxlLgogICAgICovCiAgICBlbnVtIE1vZHVsZUtpbmQgewogICAgICAgIC8qKgogICAgICAgICAqIE9wZW4gbW9kdWxlLgogICAgICAgICAqLwogICAgICAgIE9QRU4sCiAgICAgICAgLyoqCiAgICAgICAgICogU3Ryb25nIG1vZHVsZS4KICAgICAgICAgKi8KICAgICAgICBTVFJPTkc7CiAgICB9Cgp9ClBLAwQKAAAIAAAGO6lK83YNPMkHAADJBwAAJgAAAGNvbS9zdW4vc291cmNlL3RyZWUvTW9kaWZpZXJzVHJlZS5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDA1LCAyMDE0LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4uc291cmNlLnRyZWU7CgppbXBvcnQgamF2YS51dGlsLkxpc3Q7CmltcG9ydCBqYXZhLnV0aWwuU2V0OwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5lbGVtZW50Lk1vZGlmaWVyOwoKLyoqCiAqIEEgdHJlZSBub2RlIGZvciB0aGUgbW9kaWZpZXJzLCBpbmNsdWRpbmcgYW5ub3RhdGlvbnMsIGZvciBhIGRlY2xhcmF0aW9uLgogKgogKiBGb3IgZXhhbXBsZToKICogPHByZT4KICogICA8ZW0+ZmxhZ3M8L2VtPgogKgogKiAgIDxlbT5mbGFnczwvZW0+IDxlbT5hbm5vdGF0aW9uczwvZW0+CiAqIDwvcHJlPgogKgogKiBAamxzIHNlY3Rpb25zIDguMS4xLCA4LjMuMSwgOC40LjMsIDguNS4xLCA4LjguMywgOS4xLjEsIGFuZCA5LjcKICoKICogQGF1dGhvciBQZXRlciB2b24gZGVyIEFoJmVhY3V0ZTsKICogQGF1dGhvciBKb25hdGhhbiBHaWJib25zCiAqIEBzaW5jZSAxLjYKICovCnB1YmxpYyBpbnRlcmZhY2UgTW9kaWZpZXJzVHJlZSBleHRlbmRzIFRyZWUgewogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBmbGFncyBpbiB0aGlzIG1vZGlmaWVycyB0cmVlLgogICAgICogQHJldHVybiB0aGUgZmxhZ3MKICAgICAqLwogICAgU2V0PE1vZGlmaWVyPiBnZXRGbGFncygpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgYW5ub3RhdGlvbnMgaW4gdGhpcyBtb2RpZmllcnMgdHJlZS4KICAgICAqIEByZXR1cm4gdGhlIGFubm90YXRpb25zCiAgICAgKi8KICAgIExpc3Q8PyBleHRlbmRzIEFubm90YXRpb25UcmVlPiBnZXRBbm5vdGF0aW9ucygpOwp9ClBLAwQKAAAIAAAGO6lKn/xf9uYFAADmBQAAKwAAAGNvbS9zdW4vc291cmNlL3RyZWUvRW1wdHlTdGF0ZW1lbnRUcmVlLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMTMsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi5zb3VyY2UudHJlZTsKCi8qKgogKiBBIHRyZWUgbm9kZSBmb3IgYW4gZW1wdHkgKHNraXApIHN0YXRlbWVudC4KICoKICogRm9yIGV4YW1wbGU6CiAqIDxwcmU+CiAqICAgIDsKICogPC9wcmU+CiAqCiAqIEBqbHMgc2VjdGlvbiAxNC42CiAqCiAqIEBhdXRob3IgUGV0ZXIgdm9uIGRlciBBaCZlYWN1dGU7CiAqIEBhdXRob3IgSm9uYXRoYW4gR2liYm9ucwogKiBAc2luY2UgMS42CiAqLwpwdWJsaWMgaW50ZXJmYWNlIEVtcHR5U3RhdGVtZW50VHJlZSBleHRlbmRzIFN0YXRlbWVudFRyZWUge30KUEsDBAoAAAgAAAY7qUq/bYkeAQcAAAEHAAAtAAAAY29tL3N1bi9zb3VyY2UvdHJlZS9MYWJlbGVkU3RhdGVtZW50VHJlZS5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDA1LCAyMDE0LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4uc291cmNlLnRyZWU7CgppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5lbGVtZW50Lk5hbWU7CgovKioKICogQSB0cmVlIG5vZGUgZm9yIGEgbGFiZWxlZCBzdGF0ZW1lbnQuCiAqCiAqIEZvciBleGFtcGxlOgogKiA8cHJlPgogKiAgIDxlbT5sYWJlbDwvZW0+IDogPGVtPnN0YXRlbWVudDwvZW0+CiAqIDwvcHJlPgogKgogKiBAamxzIHNlY3Rpb24gMTQuNwogKgogKiBAYXV0aG9yIFBldGVyIHZvbiBkZXIgQWgmZWFjdXRlOwogKiBAYXV0aG9yIEpvbmF0aGFuIEdpYmJvbnMKICogQHNpbmNlIDEuNgogKi8KcHVibGljIGludGVyZmFjZSBMYWJlbGVkU3RhdGVtZW50VHJlZSBleHRlbmRzIFN0YXRlbWVudFRyZWUgewogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBsYWJlbC4KICAgICAqIEByZXR1cm4gdGhlIGxhYmVsCiAgICAgKi8KICAgIE5hbWUgZ2V0TGFiZWwoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHN0YXRlbWVudCB0aGF0IGlzIGxhYmVsZWQuCiAgICAgKiBAcmV0dXJuIHRoZSBzdGF0ZW1lbnQKICAgICAqLwogICAgU3RhdGVtZW50VHJlZSBnZXRTdGF0ZW1lbnQoKTsKfQpQSwMECgAACAAABjupStjcKeVgOwAAYDsAACQAAABjb20vc3VuL3NvdXJjZS90cmVlL1RyZWVWaXNpdG9yLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMTYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi5zb3VyY2UudHJlZTsKCi8qKgogKiBBIHZpc2l0b3Igb2YgdHJlZXMsIGluIHRoZSBzdHlsZSBvZiB0aGUgdmlzaXRvciBkZXNpZ24gcGF0dGVybi4KICogQ2xhc3NlcyBpbXBsZW1lbnRpbmcgdGhpcyBpbnRlcmZhY2UgYXJlIHVzZWQgdG8gb3BlcmF0ZQogKiBvbiBhIHRyZWUgd2hlbiB0aGUga2luZCBvZiB0cmVlIGlzIHVua25vd24gYXQgY29tcGlsZSB0aW1lLgogKiBXaGVuIGEgdmlzaXRvciBpcyBwYXNzZWQgdG8gYW4gdHJlZSdzIHtAbGluayBUcmVlI2FjY2VwdAogKiBhY2NlcHR9IG1ldGhvZCwgdGhlIDx0dD52aXNpdDxpPlhZWjwvaT48L3R0PiBtZXRob2QgbW9zdCBhcHBsaWNhYmxlCiAqIHRvIHRoYXQgdHJlZSBpcyBpbnZva2VkLgogKgogKiA8cD4gQ2xhc3NlcyBpbXBsZW1lbnRpbmcgdGhpcyBpbnRlcmZhY2UgbWF5IG9yIG1heSBub3QgdGhyb3cgYQogKiB7QGNvZGUgTnVsbFBvaW50ZXJFeGNlcHRpb259IGlmIHRoZSBhZGRpdGlvbmFsIHBhcmFtZXRlciB7QGNvZGUgcH0KICogaXMge0Bjb2RlIG51bGx9OyBzZWUgZG9jdW1lbnRhdGlvbiBvZiB0aGUgaW1wbGVtZW50aW5nIGNsYXNzIGZvcgogKiBkZXRhaWxzLgogKgogKiA8cD4gPGI+V0FSTklORzo8L2I+IEl0IGlzIHBvc3NpYmxlIHRoYXQgbWV0aG9kcyB3aWxsIGJlIGFkZGVkIHRvCiAqIHRoaXMgaW50ZXJmYWNlIHRvIGFjY29tbW9kYXRlIG5ldywgY3VycmVudGx5IHVua25vd24sIGxhbmd1YWdlCiAqIHN0cnVjdHVyZXMgYWRkZWQgdG8gZnV0dXJlIHZlcnNpb25zIG9mIHRoZSBKYXZhJnRyYWRlOyBwcm9ncmFtbWluZwogKiBsYW5ndWFnZS4gIFRoZXJlZm9yZSwgdmlzaXRvciBjbGFzc2VzIGRpcmVjdGx5IGltcGxlbWVudGluZyB0aGlzCiAqIGludGVyZmFjZSBtYXkgYmUgc291cmNlIGluY29tcGF0aWJsZSB3aXRoIGZ1dHVyZSB2ZXJzaW9ucyBvZiB0aGUKICogcGxhdGZvcm0uCiAqCiAqIEBwYXJhbSA8Uj4gdGhlIHJldHVybiB0eXBlIG9mIHRoaXMgdmlzaXRvcidzIG1ldGhvZHMuICBVc2Uge0BsaW5rCiAqICAgICAgICAgICAgVm9pZH0gZm9yIHZpc2l0b3JzIHRoYXQgZG8gbm90IG5lZWQgdG8gcmV0dXJuIHJlc3VsdHMuCiAqIEBwYXJhbSA8UD4gdGhlIHR5cGUgb2YgdGhlIGFkZGl0aW9uYWwgcGFyYW1ldGVyIHRvIHRoaXMgdmlzaXRvcidzCiAqICAgICAgICAgICAgbWV0aG9kcy4gIFVzZSB7QGNvZGUgVm9pZH0gZm9yIHZpc2l0b3JzIHRoYXQgZG8gbm90IG5lZWQgYW4KICogICAgICAgICAgICBhZGRpdGlvbmFsIHBhcmFtZXRlci4KICoKICogQGF1dGhvciBQZXRlciB2b24gZGVyIEFoJmVhY3V0ZTsKICogQGF1dGhvciBKb25hdGhhbiBHaWJib25zCiAqCiAqIEBzaW5jZSAxLjYKICovCnB1YmxpYyBpbnRlcmZhY2UgVHJlZVZpc2l0b3I8UixQPiB7CiAgICAvKioKICAgICAqIFZpc2l0cyBhbiBBbm5vdGF0ZWRUeXBlVHJlZSBub2RlLgogICAgICogQHBhcmFtIG5vZGUgdGhlIG5vZGUgYmVpbmcgdmlzaXRlZAogICAgICogQHBhcmFtIHAgYSBwYXJhbWV0ZXIgdmFsdWUKICAgICAqIEByZXR1cm4gYSByZXN1bHQgdmFsdWUKICAgICAqLwogICAgUiB2aXNpdEFubm90YXRlZFR5cGUoQW5ub3RhdGVkVHlwZVRyZWUgbm9kZSwgUCBwKTsKCiAgICAvKioKICAgICAqIFZpc2l0cyBhbiBBbm5vdGF0ZWRUcmVlIG5vZGUuCiAgICAgKiBAcGFyYW0gbm9kZSB0aGUgbm9kZSBiZWluZyB2aXNpdGVkCiAgICAgKiBAcGFyYW0gcCBhIHBhcmFtZXRlciB2YWx1ZQogICAgICogQHJldHVybiBhIHJlc3VsdCB2YWx1ZQogICAgICovCiAgICBSIHZpc2l0QW5ub3RhdGlvbihBbm5vdGF0aW9uVHJlZSBub2RlLCBQIHApOwoKICAgIC8qKgogICAgICogVmlzaXRzIGEgTWV0aG9kSW52b2NhdGlvblRyZWUgbm9kZS4KICAgICAqIEBwYXJhbSBub2RlIHRoZSBub2RlIGJlaW5nIHZpc2l0ZWQKICAgICAqIEBwYXJhbSBwIGEgcGFyYW1ldGVyIHZhbHVlCiAgICAgKiBAcmV0dXJuIGEgcmVzdWx0IHZhbHVlCiAgICAgKi8KICAgIFIgdmlzaXRNZXRob2RJbnZvY2F0aW9uKE1ldGhvZEludm9jYXRpb25UcmVlIG5vZGUsIFAgcCk7CgogICAgLyoqCiAgICAgKiBWaXNpdHMgYW4gQXNzZXJ0VHJlZSBub2RlLgogICAgICogQHBhcmFtIG5vZGUgdGhlIG5vZGUgYmVpbmcgdmlzaXRlZAogICAgICogQHBhcmFtIHAgYSBwYXJhbWV0ZXIgdmFsdWUKICAgICAqIEByZXR1cm4gYSByZXN1bHQgdmFsdWUKICAgICAqLwogICAgUiB2aXNpdEFzc2VydChBc3NlcnRUcmVlIG5vZGUsIFAgcCk7CgogICAgLyoqCiAgICAgKiBWaXNpdHMgYW4gQXNzaWdubWVudFRyZWUgbm9kZS4KICAgICAqIEBwYXJhbSBub2RlIHRoZSBub2RlIGJlaW5nIHZpc2l0ZWQKICAgICAqIEBwYXJhbSBwIGEgcGFyYW1ldGVyIHZhbHVlCiAgICAgKiBAcmV0dXJuIGEgcmVzdWx0IHZhbHVlCiAgICAgKi8KICAgIFIgdmlzaXRBc3NpZ25tZW50KEFzc2lnbm1lbnRUcmVlIG5vZGUsIFAgcCk7CgogICAgLyoqCiAgICAgKiBWaXNpdHMgYSBDb21wb3VuZEFzc2lnbm1lbnRUcmVlIG5vZGUuCiAgICAgKiBAcGFyYW0gbm9kZSB0aGUgbm9kZSBiZWluZyB2aXNpdGVkCiAgICAgKiBAcGFyYW0gcCBhIHBhcmFtZXRlciB2YWx1ZQogICAgICogQHJldHVybiBhIHJlc3VsdCB2YWx1ZQogICAgICovCiAgICBSIHZpc2l0Q29tcG91bmRBc3NpZ25tZW50KENvbXBvdW5kQXNzaWdubWVudFRyZWUgbm9kZSwgUCBwKTsKCiAgICAvKioKICAgICAqIFZpc2l0cyBhIEJpbmFyeVRyZWUgbm9kZS4KICAgICAqIEBwYXJhbSBub2RlIHRoZSBub2RlIGJlaW5nIHZpc2l0ZWQKICAgICAqIEBwYXJhbSBwIGEgcGFyYW1ldGVyIHZhbHVlCiAgICAgKiBAcmV0dXJuIGEgcmVzdWx0IHZhbHVlCiAgICAgKi8KICAgIFIgdmlzaXRCaW5hcnkoQmluYXJ5VHJlZSBub2RlLCBQIHApOwoKICAgIC8qKgogICAgICogVmlzaXRzIGEgQmxvY2tUcmVlIG5vZGUuCiAgICAgKiBAcGFyYW0gbm9kZSB0aGUgbm9kZSBiZWluZyB2aXNpdGVkCiAgICAgKiBAcGFyYW0gcCBhIHBhcmFtZXRlciB2YWx1ZQogICAgICogQHJldHVybiBhIHJlc3VsdCB2YWx1ZQogICAgICovCiAgICBSIHZpc2l0QmxvY2soQmxvY2tUcmVlIG5vZGUsIFAgcCk7CgogICAgLyoqCiAgICAgKiBWaXNpdHMgYSBCcmVha1RyZWUgbm9kZS4KICAgICAqIEBwYXJhbSBub2RlIHRoZSBub2RlIGJlaW5nIHZpc2l0ZWQKICAgICAqIEBwYXJhbSBwIGEgcGFyYW1ldGVyIHZhbHVlCiAgICAgKiBAcmV0dXJuIGEgcmVzdWx0IHZhbHVlCiAgICAgKi8KICAgIFIgdmlzaXRCcmVhayhCcmVha1RyZWUgbm9kZSwgUCBwKTsKCiAgICAvKioKICAgICAqIFZpc2l0cyBhIENhc2VUcmVlIG5vZGUuCiAgICAgKiBAcGFyYW0gbm9kZSB0aGUgbm9kZSBiZWluZyB2aXNpdGVkCiAgICAgKiBAcGFyYW0gcCBhIHBhcmFtZXRlciB2YWx1ZQogICAgICogQHJldHVybiBhIHJlc3VsdCB2YWx1ZQogICAgICovCiAgICBSIHZpc2l0Q2FzZShDYXNlVHJlZSBub2RlLCBQIHApOwoKICAgIC8qKgogICAgICogVmlzaXRzIGEgQ2F0Y2hUcmVlIG5vZGUuCiAgICAgKiBAcGFyYW0gbm9kZSB0aGUgbm9kZSBiZWluZyB2aXNpdGVkCiAgICAgKiBAcGFyYW0gcCBhIHBhcmFtZXRlciB2YWx1ZQogICAgICogQHJldHVybiBhIHJlc3VsdCB2YWx1ZQogICAgICovCiAgICBSIHZpc2l0Q2F0Y2goQ2F0Y2hUcmVlIG5vZGUsIFAgcCk7CgogICAgLyoqCiAgICAgKiBWaXNpdHMgYSBDbGFzc1RyZWUgbm9kZS4KICAgICAqIEBwYXJhbSBub2RlIHRoZSBub2RlIGJlaW5nIHZpc2l0ZWQKICAgICAqIEBwYXJhbSBwIGEgcGFyYW1ldGVyIHZhbHVlCiAgICAgKiBAcmV0dXJuIGEgcmVzdWx0IHZhbHVlCiAgICAgKi8KICAgIFIgdmlzaXRDbGFzcyhDbGFzc1RyZWUgbm9kZSwgUCBwKTsKCiAgICAvKioKICAgICAqIFZpc2l0cyBhIENvbmRpdGlvbmFsRXhwcmVzc2lvblRyZWUgbm9kZS4KICAgICAqIEBwYXJhbSBub2RlIHRoZSBub2RlIGJlaW5nIHZpc2l0ZWQKICAgICAqIEBwYXJhbSBwIGEgcGFyYW1ldGVyIHZhbHVlCiAgICAgKiBAcmV0dXJuIGEgcmVzdWx0IHZhbHVlCiAgICAgKi8KICAgIFIgdmlzaXRDb25kaXRpb25hbEV4cHJlc3Npb24oQ29uZGl0aW9uYWxFeHByZXNzaW9uVHJlZSBub2RlLCBQIHApOwoKICAgIC8qKgogICAgICogVmlzaXRzIGEgQ29udGludWVUcmVlIG5vZGUuCiAgICAgKiBAcGFyYW0gbm9kZSB0aGUgbm9kZSBiZWluZyB2aXNpdGVkCiAgICAgKiBAcGFyYW0gcCBhIHBhcmFtZXRlciB2YWx1ZQogICAgICogQHJldHVybiBhIHJlc3VsdCB2YWx1ZQogICAgICovCiAgICBSIHZpc2l0Q29udGludWUoQ29udGludWVUcmVlIG5vZGUsIFAgcCk7CgogICAgLyoqCiAgICAgKiBWaXNpdHMgYSBEb1doaWxlVHJlZSBub2RlLgogICAgICogQHBhcmFtIG5vZGUgdGhlIG5vZGUgYmVpbmcgdmlzaXRlZAogICAgICogQHBhcmFtIHAgYSBwYXJhbWV0ZXIgdmFsdWUKICAgICAqIEByZXR1cm4gYSByZXN1bHQgdmFsdWUKICAgICAqLwogICAgUiB2aXNpdERvV2hpbGVMb29wKERvV2hpbGVMb29wVHJlZSBub2RlLCBQIHApOwoKICAgIC8qKgogICAgICogVmlzaXRzIGFuIEVycm9uZW91c1RyZWUgbm9kZS4KICAgICAqIEBwYXJhbSBub2RlIHRoZSBub2RlIGJlaW5nIHZpc2l0ZWQKICAgICAqIEBwYXJhbSBwIGEgcGFyYW1ldGVyIHZhbHVlCiAgICAgKiBAcmV0dXJuIGEgcmVzdWx0IHZhbHVlCiAgICAgKi8KICAgIFIgdmlzaXRFcnJvbmVvdXMoRXJyb25lb3VzVHJlZSBub2RlLCBQIHApOwoKICAgIC8qKgogICAgICogVmlzaXRzIGFuIEV4cHJlc3Npb25TdGF0ZW1lbnRUcmVlIG5vZGUuCiAgICAgKiBAcGFyYW0gbm9kZSB0aGUgbm9kZSBiZWluZyB2aXNpdGVkCiAgICAgKiBAcGFyYW0gcCBhIHBhcmFtZXRlciB2YWx1ZQogICAgICogQHJldHVybiBhIHJlc3VsdCB2YWx1ZQogICAgICovCiAgICBSIHZpc2l0RXhwcmVzc2lvblN0YXRlbWVudChFeHByZXNzaW9uU3RhdGVtZW50VHJlZSBub2RlLCBQIHApOwoKICAgIC8qKgogICAgICogVmlzaXRzIGFuIEVuaGFuY2VkRm9yTG9vcFRyZWUgbm9kZS4KICAgICAqIEBwYXJhbSBub2RlIHRoZSBub2RlIGJlaW5nIHZpc2l0ZWQKICAgICAqIEBwYXJhbSBwIGEgcGFyYW1ldGVyIHZhbHVlCiAgICAgKiBAcmV0dXJuIGEgcmVzdWx0IHZhbHVlCiAgICAgKi8KICAgIFIgdmlzaXRFbmhhbmNlZEZvckxvb3AoRW5oYW5jZWRGb3JMb29wVHJlZSBub2RlLCBQIHApOwoKICAgIC8qKgogICAgICogVmlzaXRzIGEgRm9yTG9vcFRyZWUgbm9kZS4KICAgICAqIEBwYXJhbSBub2RlIHRoZSBub2RlIGJlaW5nIHZpc2l0ZWQKICAgICAqIEBwYXJhbSBwIGEgcGFyYW1ldGVyIHZhbHVlCiAgICAgKiBAcmV0dXJuIGEgcmVzdWx0IHZhbHVlCiAgICAgKi8KICAgIFIgdmlzaXRGb3JMb29wKEZvckxvb3BUcmVlIG5vZGUsIFAgcCk7CgogICAgLyoqCiAgICAgKiBWaXNpdHMgYW4gSWRlbnRpZmllclRyZWUgbm9kZS4KICAgICAqIEBwYXJhbSBub2RlIHRoZSBub2RlIGJlaW5nIHZpc2l0ZWQKICAgICAqIEBwYXJhbSBwIGEgcGFyYW1ldGVyIHZhbHVlCiAgICAgKiBAcmV0dXJuIGEgcmVzdWx0IHZhbHVlCiAgICAgKi8KICAgIFIgdmlzaXRJZGVudGlmaWVyKElkZW50aWZpZXJUcmVlIG5vZGUsIFAgcCk7CgogICAgLyoqCiAgICAgKiBWaXNpdHMgYW4gSWZUcmVlIG5vZGUuCiAgICAgKiBAcGFyYW0gbm9kZSB0aGUgbm9kZSBiZWluZyB2aXNpdGVkCiAgICAgKiBAcGFyYW0gcCBhIHBhcmFtZXRlciB2YWx1ZQogICAgICogQHJldHVybiBhIHJlc3VsdCB2YWx1ZQogICAgICovCiAgICBSIHZpc2l0SWYoSWZUcmVlIG5vZGUsIFAgcCk7CgogICAgLyoqCiAgICAgKiBWaXNpdHMgYW4gSW1wb3J0VHJlZSBub2RlLgogICAgICogQHBhcmFtIG5vZGUgdGhlIG5vZGUgYmVpbmcgdmlzaXRlZAogICAgICogQHBhcmFtIHAgYSBwYXJhbWV0ZXIgdmFsdWUKICAgICAqIEByZXR1cm4gYSByZXN1bHQgdmFsdWUKICAgICAqLwogICAgUiB2aXNpdEltcG9ydChJbXBvcnRUcmVlIG5vZGUsIFAgcCk7CgogICAgLyoqCiAgICAgKiBWaXNpdHMgYW4gQXJyYXlBY2Nlc3NUcmVlIG5vZGUuCiAgICAgKiBAcGFyYW0gbm9kZSB0aGUgbm9kZSBiZWluZyB2aXNpdGVkCiAgICAgKiBAcGFyYW0gcCBhIHBhcmFtZXRlciB2YWx1ZQogICAgICogQHJldHVybiBhIHJlc3VsdCB2YWx1ZQogICAgICovCiAgICBSIHZpc2l0QXJyYXlBY2Nlc3MoQXJyYXlBY2Nlc3NUcmVlIG5vZGUsIFAgcCk7CgogICAgLyoqCiAgICAgKiBWaXNpdHMgYSBMYWJlbGVkU3RhdGVtZW50VHJlZSBub2RlLgogICAgICogQHBhcmFtIG5vZGUgdGhlIG5vZGUgYmVpbmcgdmlzaXRlZAogICAgICogQHBhcmFtIHAgYSBwYXJhbWV0ZXIgdmFsdWUKICAgICAqIEByZXR1cm4gYSByZXN1bHQgdmFsdWUKICAgICAqLwogICAgUiB2aXNpdExhYmVsZWRTdGF0ZW1lbnQoTGFiZWxlZFN0YXRlbWVudFRyZWUgbm9kZSwgUCBwKTsKCiAgICAvKioKICAgICAqIFZpc2l0cyBhIExpdGVyYWxUcmVlIG5vZGUuCiAgICAgKiBAcGFyYW0gbm9kZSB0aGUgbm9kZSBiZWluZyB2aXNpdGVkCiAgICAgKiBAcGFyYW0gcCBhIHBhcmFtZXRlciB2YWx1ZQogICAgICogQHJldHVybiBhIHJlc3VsdCB2YWx1ZQogICAgICovCiAgICBSIHZpc2l0TGl0ZXJhbChMaXRlcmFsVHJlZSBub2RlLCBQIHApOwoKICAgIC8qKgogICAgICogVmlzaXRzIGEgTWV0aG9kVHJlZSBub2RlLgogICAgICogQHBhcmFtIG5vZGUgdGhlIG5vZGUgYmVpbmcgdmlzaXRlZAogICAgICogQHBhcmFtIHAgYSBwYXJhbWV0ZXIgdmFsdWUKICAgICAqIEByZXR1cm4gYSByZXN1bHQgdmFsdWUKICAgICAqLwogICAgUiB2aXNpdE1ldGhvZChNZXRob2RUcmVlIG5vZGUsIFAgcCk7CgogICAgLyoqCiAgICAgKiBWaXNpdHMgYSBNb2RpZmllcnNUcmVlIG5vZGUuCiAgICAgKiBAcGFyYW0gbm9kZSB0aGUgbm9kZSBiZWluZyB2aXNpdGVkCiAgICAgKiBAcGFyYW0gcCBhIHBhcmFtZXRlciB2YWx1ZQogICAgICogQHJldHVybiBhIHJlc3VsdCB2YWx1ZQogICAgICovCiAgICBSIHZpc2l0TW9kaWZpZXJzKE1vZGlmaWVyc1RyZWUgbm9kZSwgUCBwKTsKCiAgICAvKioKICAgICAqIFZpc2l0cyBhIE5ld0FycmF5VHJlZSBub2RlLgogICAgICogQHBhcmFtIG5vZGUgdGhlIG5vZGUgYmVpbmcgdmlzaXRlZAogICAgICogQHBhcmFtIHAgYSBwYXJhbWV0ZXIgdmFsdWUKICAgICAqIEByZXR1cm4gYSByZXN1bHQgdmFsdWUKICAgICAqLwogICAgUiB2aXNpdE5ld0FycmF5KE5ld0FycmF5VHJlZSBub2RlLCBQIHApOwoKICAgIC8qKgogICAgICogVmlzaXRzIGEgTmV3Q2xhc3NUcmVlIG5vZGUuCiAgICAgKiBAcGFyYW0gbm9kZSB0aGUgbm9kZSBiZWluZyB2aXNpdGVkCiAgICAgKiBAcGFyYW0gcCBhIHBhcmFtZXRlciB2YWx1ZQogICAgICogQHJldHVybiBhIHJlc3VsdCB2YWx1ZQogICAgICovCiAgICBSIHZpc2l0TmV3Q2xhc3MoTmV3Q2xhc3NUcmVlIG5vZGUsIFAgcCk7CgogICAgLyoqCiAgICAgKiBWaXNpdHMgYSBMYW1iZGFFeHByZXNzaW9uVHJlZSBub2RlLgogICAgICogQHBhcmFtIG5vZGUgdGhlIG5vZGUgYmVpbmcgdmlzaXRlZAogICAgICogQHBhcmFtIHAgYSBwYXJhbWV0ZXIgdmFsdWUKICAgICAqIEByZXR1cm4gYSByZXN1bHQgdmFsdWUKICAgICAqLwogICAgUiB2aXNpdExhbWJkYUV4cHJlc3Npb24oTGFtYmRhRXhwcmVzc2lvblRyZWUgbm9kZSwgUCBwKTsKCiAgICAvKioKICAgICAqIFZpc2l0cyBhIFBhY2thZ2VUcmVlIG5vZGUuCiAgICAgKiBAcGFyYW0gbm9kZSB0aGUgbm9kZSBiZWluZyB2aXNpdGVkCiAgICAgKiBAcGFyYW0gcCBhIHBhcmFtZXRlciB2YWx1ZQogICAgICogQHJldHVybiBhIHJlc3VsdCB2YWx1ZQogICAgICovCiAgICBSIHZpc2l0UGFja2FnZShQYWNrYWdlVHJlZSBub2RlLCBQIHApOwoKICAgIC8qKgogICAgICogVmlzaXRzIGEgUGFyZW50aGVzaXplZFRyZWUgbm9kZS4KICAgICAqIEBwYXJhbSBub2RlIHRoZSBub2RlIGJlaW5nIHZpc2l0ZWQKICAgICAqIEBwYXJhbSBwIGEgcGFyYW1ldGVyIHZhbHVlCiAgICAgKiBAcmV0dXJuIGEgcmVzdWx0IHZhbHVlCiAgICAgKi8KICAgIFIgdmlzaXRQYXJlbnRoZXNpemVkKFBhcmVudGhlc2l6ZWRUcmVlIG5vZGUsIFAgcCk7CgogICAgLyoqCiAgICAgKiBWaXNpdHMgYSBSZXR1cm5UcmVlIG5vZGUuCiAgICAgKiBAcGFyYW0gbm9kZSB0aGUgbm9kZSBiZWluZyB2aXNpdGVkCiAgICAgKiBAcGFyYW0gcCBhIHBhcmFtZXRlciB2YWx1ZQogICAgICogQHJldHVybiBhIHJlc3VsdCB2YWx1ZQogICAgICovCiAgICBSIHZpc2l0UmV0dXJuKFJldHVyblRyZWUgbm9kZSwgUCBwKTsKCiAgICAvKioKICAgICAqIFZpc2l0cyBhIE1lbWJlclNlbGVjdFRyZWUgbm9kZS4KICAgICAqIEBwYXJhbSBub2RlIHRoZSBub2RlIGJlaW5nIHZpc2l0ZWQKICAgICAqIEBwYXJhbSBwIGEgcGFyYW1ldGVyIHZhbHVlCiAgICAgKiBAcmV0dXJuIGEgcmVzdWx0IHZhbHVlCiAgICAgKi8KICAgIFIgdmlzaXRNZW1iZXJTZWxlY3QoTWVtYmVyU2VsZWN0VHJlZSBub2RlLCBQIHApOwoKICAgIC8qKgogICAgICogVmlzaXRzIGEgTWVtYmVyUmVmZXJlbmNlVHJlZSBub2RlLgogICAgICogQHBhcmFtIG5vZGUgdGhlIG5vZGUgYmVpbmcgdmlzaXRlZAogICAgICogQHBhcmFtIHAgYSBwYXJhbWV0ZXIgdmFsdWUKICAgICAqIEByZXR1cm4gYSByZXN1bHQgdmFsdWUKICAgICAqLwogICAgUiB2aXNpdE1lbWJlclJlZmVyZW5jZShNZW1iZXJSZWZlcmVuY2VUcmVlIG5vZGUsIFAgcCk7CgogICAgLyoqCiAgICAgKiBWaXNpdHMgYW4gRW1wdHlTdGF0ZW1lbnRUcmVlIG5vZGUuCiAgICAgKiBAcGFyYW0gbm9kZSB0aGUgbm9kZSBiZWluZyB2aXNpdGVkCiAgICAgKiBAcGFyYW0gcCBhIHBhcmFtZXRlciB2YWx1ZQogICAgICogQHJldHVybiBhIHJlc3VsdCB2YWx1ZQogICAgICovCiAgICBSIHZpc2l0RW1wdHlTdGF0ZW1lbnQoRW1wdHlTdGF0ZW1lbnRUcmVlIG5vZGUsIFAgcCk7CgogICAgLyoqCiAgICAgKiBWaXNpdHMgYSBTd2l0Y2hUcmVlIG5vZGUuCiAgICAgKiBAcGFyYW0gbm9kZSB0aGUgbm9kZSBiZWluZyB2aXNpdGVkCiAgICAgKiBAcGFyYW0gcCBhIHBhcmFtZXRlciB2YWx1ZQogICAgICogQHJldHVybiBhIHJlc3VsdCB2YWx1ZQogICAgICovCiAgICBSIHZpc2l0U3dpdGNoKFN3aXRjaFRyZWUgbm9kZSwgUCBwKTsKCiAgICAvKioKICAgICAqIFZpc2l0cyBhIFN5bmNocm9uaXplZFRyZWUgbm9kZS4KICAgICAqIEBwYXJhbSBub2RlIHRoZSBub2RlIGJlaW5nIHZpc2l0ZWQKICAgICAqIEBwYXJhbSBwIGEgcGFyYW1ldGVyIHZhbHVlCiAgICAgKiBAcmV0dXJuIGEgcmVzdWx0IHZhbHVlCiAgICAgKi8KICAgIFIgdmlzaXRTeW5jaHJvbml6ZWQoU3luY2hyb25pemVkVHJlZSBub2RlLCBQIHApOwoKICAgIC8qKgogICAgICogVmlzaXRzIGEgVGhyb3dUcmVlIG5vZGUuCiAgICAgKiBAcGFyYW0gbm9kZSB0aGUgbm9kZSBiZWluZyB2aXNpdGVkCiAgICAgKiBAcGFyYW0gcCBhIHBhcmFtZXRlciB2YWx1ZQogICAgICogQHJldHVybiBhIHJlc3VsdCB2YWx1ZQogICAgICovCiAgICBSIHZpc2l0VGhyb3coVGhyb3dUcmVlIG5vZGUsIFAgcCk7CgogICAgLyoqCiAgICAgKiBWaXNpdHMgYSBDb21waWxhdGlvblVuaXRUcmVlIG5vZGUuCiAgICAgKiBAcGFyYW0gbm9kZSB0aGUgbm9kZSBiZWluZyB2aXNpdGVkCiAgICAgKiBAcGFyYW0gcCBhIHBhcmFtZXRlciB2YWx1ZQogICAgICogQHJldHVybiBhIHJlc3VsdCB2YWx1ZQogICAgICovCiAgICBSIHZpc2l0Q29tcGlsYXRpb25Vbml0KENvbXBpbGF0aW9uVW5pdFRyZWUgbm9kZSwgUCBwKTsKCiAgICAvKioKICAgICAqIFZpc2l0cyBhIFRyeVRyZWUgbm9kZS4KICAgICAqIEBwYXJhbSBub2RlIHRoZSBub2RlIGJlaW5nIHZpc2l0ZWQKICAgICAqIEBwYXJhbSBwIGEgcGFyYW1ldGVyIHZhbHVlCiAgICAgKiBAcmV0dXJuIGEgcmVzdWx0IHZhbHVlCiAgICAgKi8KICAgIFIgdmlzaXRUcnkoVHJ5VHJlZSBub2RlLCBQIHApOwoKICAgIC8qKgogICAgICogVmlzaXRzIGEgUGFyYW1ldGVyaXplZFR5cGVUcmVlIG5vZGUuCiAgICAgKiBAcGFyYW0gbm9kZSB0aGUgbm9kZSBiZWluZyB2aXNpdGVkCiAgICAgKiBAcGFyYW0gcCBhIHBhcmFtZXRlciB2YWx1ZQogICAgICogQHJldHVybiBhIHJlc3VsdCB2YWx1ZQogICAgICovCiAgICBSIHZpc2l0UGFyYW1ldGVyaXplZFR5cGUoUGFyYW1ldGVyaXplZFR5cGVUcmVlIG5vZGUsIFAgcCk7CgogICAgLyoqCiAgICAgKiBWaXNpdHMgYSBVbmlvblR5cGVUcmVlIG5vZGUuCiAgICAgKiBAcGFyYW0gbm9kZSB0aGUgbm9kZSBiZWluZyB2aXNpdGVkCiAgICAgKiBAcGFyYW0gcCBhIHBhcmFtZXRlciB2YWx1ZQogICAgICogQHJldHVybiBhIHJlc3VsdCB2YWx1ZQogICAgICovCiAgICBSIHZpc2l0VW5pb25UeXBlKFVuaW9uVHlwZVRyZWUgbm9kZSwgUCBwKTsKCiAgICAvKioKICAgICAqIFZpc2l0cyBhbiBJbnRlcnNlY3Rpb25UeXBlVHJlZSBub2RlLgogICAgICogQHBhcmFtIG5vZGUgdGhlIG5vZGUgYmVpbmcgdmlzaXRlZAogICAgICogQHBhcmFtIHAgYSBwYXJhbWV0ZXIgdmFsdWUKICAgICAqIEByZXR1cm4gYSByZXN1bHQgdmFsdWUKICAgICAqLwogICAgUiB2aXNpdEludGVyc2VjdGlvblR5cGUoSW50ZXJzZWN0aW9uVHlwZVRyZWUgbm9kZSwgUCBwKTsKCiAgICAvKioKICAgICAqIFZpc2l0cyBhbiBBcnJheVR5cGVUcmVlIG5vZGUuCiAgICAgKiBAcGFyYW0gbm9kZSB0aGUgbm9kZSBiZWluZyB2aXNpdGVkCiAgICAgKiBAcGFyYW0gcCBhIHBhcmFtZXRlciB2YWx1ZQogICAgICogQHJldHVybiBhIHJlc3VsdCB2YWx1ZQogICAgICovCiAgICBSIHZpc2l0QXJyYXlUeXBlKEFycmF5VHlwZVRyZWUgbm9kZSwgUCBwKTsKCiAgICAvKioKICAgICAqIFZpc2l0cyBhIFR5cGVDYXN0VHJlZSBub2RlLgogICAgICogQHBhcmFtIG5vZGUgdGhlIG5vZGUgYmVpbmcgdmlzaXRlZAogICAgICogQHBhcmFtIHAgYSBwYXJhbWV0ZXIgdmFsdWUKICAgICAqIEByZXR1cm4gYSByZXN1bHQgdmFsdWUKICAgICAqLwogICAgUiB2aXNpdFR5cGVDYXN0KFR5cGVDYXN0VHJlZSBub2RlLCBQIHApOwoKICAgIC8qKgogICAgICogVmlzaXRzIGEgUHJpbWl0aXZlVHlwZVRyZWUgbm9kZS4KICAgICAqIEBwYXJhbSBub2RlIHRoZSBub2RlIGJlaW5nIHZpc2l0ZWQKICAgICAqIEBwYXJhbSBwIGEgcGFyYW1ldGVyIHZhbHVlCiAgICAgKiBAcmV0dXJuIGEgcmVzdWx0IHZhbHVlCiAgICAgKi8KICAgIFIgdmlzaXRQcmltaXRpdmVUeXBlKFByaW1pdGl2ZVR5cGVUcmVlIG5vZGUsIFAgcCk7CgogICAgLyoqCiAgICAgKiBWaXNpdHMgYSBUeXBlUGFyYW1ldGVyVHJlZSBub2RlLgogICAgICogQHBhcmFtIG5vZGUgdGhlIG5vZGUgYmVpbmcgdmlzaXRlZAogICAgICogQHBhcmFtIHAgYSBwYXJhbWV0ZXIgdmFsdWUKICAgICAqIEByZXR1cm4gYSByZXN1bHQgdmFsdWUKICAgICAqLwogICAgUiB2aXNpdFR5cGVQYXJhbWV0ZXIoVHlwZVBhcmFtZXRlclRyZWUgbm9kZSwgUCBwKTsKCiAgICAvKioKICAgICAqIFZpc2l0cyBhbiBJbnN0YW5jZU9mVHJlZSBub2RlLgogICAgICogQHBhcmFtIG5vZGUgdGhlIG5vZGUgYmVpbmcgdmlzaXRlZAogICAgICogQHBhcmFtIHAgYSBwYXJhbWV0ZXIgdmFsdWUKICAgICAqIEByZXR1cm4gYSByZXN1bHQgdmFsdWUKICAgICAqLwogICAgUiB2aXNpdEluc3RhbmNlT2YoSW5zdGFuY2VPZlRyZWUgbm9kZSwgUCBwKTsKCiAgICAvKioKICAgICAqIFZpc2l0cyBhIFVuYXJ5VHJlZSBub2RlLgogICAgICogQHBhcmFtIG5vZGUgdGhlIG5vZGUgYmVpbmcgdmlzaXRlZAogICAgICogQHBhcmFtIHAgYSBwYXJhbWV0ZXIgdmFsdWUKICAgICAqIEByZXR1cm4gYSByZXN1bHQgdmFsdWUKICAgICAqLwogICAgUiB2aXNpdFVuYXJ5KFVuYXJ5VHJlZSBub2RlLCBQIHApOwoKICAgIC8qKgogICAgICogVmlzaXRzIGEgVmFyaWFibGVUcmVlIG5vZGUuCiAgICAgKiBAcGFyYW0gbm9kZSB0aGUgbm9kZSBiZWluZyB2aXNpdGVkCiAgICAgKiBAcGFyYW0gcCBhIHBhcmFtZXRlciB2YWx1ZQogICAgICogQHJldHVybiBhIHJlc3VsdCB2YWx1ZQogICAgICovCiAgICBSIHZpc2l0VmFyaWFibGUoVmFyaWFibGVUcmVlIG5vZGUsIFAgcCk7CgogICAgLyoqCiAgICAgKiBWaXNpdHMgYSBXaGlsZUxvb3BUcmVlIG5vZGUuCiAgICAgKiBAcGFyYW0gbm9kZSB0aGUgbm9kZSBiZWluZyB2aXNpdGVkCiAgICAgKiBAcGFyYW0gcCBhIHBhcmFtZXRlciB2YWx1ZQogICAgICogQHJldHVybiBhIHJlc3VsdCB2YWx1ZQogICAgICovCiAgICBSIHZpc2l0V2hpbGVMb29wKFdoaWxlTG9vcFRyZWUgbm9kZSwgUCBwKTsKCiAgICAvKioKICAgICAqIFZpc2l0cyBhIFdpbGRjYXJkVHlwZVRyZWUgbm9kZS4KICAgICAqIEBwYXJhbSBub2RlIHRoZSBub2RlIGJlaW5nIHZpc2l0ZWQKICAgICAqIEBwYXJhbSBwIGEgcGFyYW1ldGVyIHZhbHVlCiAgICAgKiBAcmV0dXJuIGEgcmVzdWx0IHZhbHVlCiAgICAgKi8KICAgIFIgdmlzaXRXaWxkY2FyZChXaWxkY2FyZFRyZWUgbm9kZSwgUCBwKTsKCiAgICAvKioKICAgICAqIFZpc2l0cyBhIE1vZHVsZVRyZWUgbm9kZS4KICAgICAqIEBwYXJhbSBub2RlIHRoZSBub2RlIGJlaW5nIHZpc2l0ZWQKICAgICAqIEBwYXJhbSBwIGEgcGFyYW1ldGVyIHZhbHVlCiAgICAgKiBAcmV0dXJuIGEgcmVzdWx0IHZhbHVlCiAgICAgKi8KICAgIFIgdmlzaXRNb2R1bGUoTW9kdWxlVHJlZSBub2RlLCBQIHApOwoKICAgIC8qKgogICAgICogVmlzaXRzIGFuIEV4cG9ydHNUcmVlIG5vZGUuCiAgICAgKiBAcGFyYW0gbm9kZSB0aGUgbm9kZSBiZWluZyB2aXNpdGVkCiAgICAgKiBAcGFyYW0gcCBhIHBhcmFtZXRlciB2YWx1ZQogICAgICogQHJldHVybiBhIHJlc3VsdCB2YWx1ZQogICAgICovCiAgICBSIHZpc2l0RXhwb3J0cyhFeHBvcnRzVHJlZSBub2RlLCBQIHApOwoKICAgIC8qKgogICAgICogVmlzaXRzIGFuIE9wZW5zVHJlZSBub2RlLgogICAgICogQHBhcmFtIG5vZGUgdGhlIG5vZGUgYmVpbmcgdmlzaXRlZAogICAgICogQHBhcmFtIHAgYSBwYXJhbWV0ZXIgdmFsdWUKICAgICAqIEByZXR1cm4gYSByZXN1bHQgdmFsdWUKICAgICAqLwogICAgUiB2aXNpdE9wZW5zKE9wZW5zVHJlZSBub2RlLCBQIHApOwoKICAgIC8qKgogICAgICogVmlzaXRzIGEgUHJvdmlkZXNUcmVlIG5vZGUuCiAgICAgKiBAcGFyYW0gbm9kZSB0aGUgbm9kZSBiZWluZyB2aXNpdGVkCiAgICAgKiBAcGFyYW0gcCBhIHBhcmFtZXRlciB2YWx1ZQogICAgICogQHJldHVybiBhIHJlc3VsdCB2YWx1ZQogICAgICovCiAgICBSIHZpc2l0UHJvdmlkZXMoUHJvdmlkZXNUcmVlIG5vZGUsIFAgcCk7CgogICAgLyoqCiAgICAgKiBWaXNpdHMgYSBSZXF1aXJlc1RyZWUgbm9kZS4KICAgICAqIEBwYXJhbSBub2RlIHRoZSBub2RlIGJlaW5nIHZpc2l0ZWQKICAgICAqIEBwYXJhbSBwIGEgcGFyYW1ldGVyIHZhbHVlCiAgICAgKiBAcmV0dXJuIGEgcmVzdWx0IHZhbHVlCiAgICAgKi8KICAgIFIgdmlzaXRSZXF1aXJlcyhSZXF1aXJlc1RyZWUgbm9kZSwgUCBwKTsKCiAgICAvKioKICAgICAqIFZpc2l0cyBhIFVzZXNUcmVlIG5vZGUuCiAgICAgKiBAcGFyYW0gbm9kZSB0aGUgbm9kZSBiZWluZyB2aXNpdGVkCiAgICAgKiBAcGFyYW0gcCBhIHBhcmFtZXRlciB2YWx1ZQogICAgICogQHJldHVybiBhIHJlc3VsdCB2YWx1ZQogICAgICovCiAgICBSIHZpc2l0VXNlcyhVc2VzVHJlZSBub2RlLCBQIHApOwoKICAgIC8qKgogICAgICogVmlzaXRzIGFuIHVua25vd24gdHlwZSBvZiBUcmVlIG5vZGUuCiAgICAgKiBUaGlzIGNhbiBvY2N1ciBpZiB0aGUgbGFuZ3VhZ2UgZXZvbHZlcyBhbmQgbmV3IGtpbmRzCiAgICAgKiBvZiBub2RlcyBhcmUgYWRkZWQgdG8gdGhlIHtAY29kZSBUcmVlfSBoaWVyYXJjaHkuCiAgICAgKiBAcGFyYW0gbm9kZSB0aGUgbm9kZSBiZWluZyB2aXNpdGVkCiAgICAgKiBAcGFyYW0gcCBhIHBhcmFtZXRlciB2YWx1ZQogICAgICogQHJldHVybiBhIHJlc3VsdCB2YWx1ZQogICAgICovCiAgICBSIHZpc2l0T3RoZXIoVHJlZSBub2RlLCBQIHApOwp9ClBLAwQKAAAIAAAGO6lK5jqY0f8GAAD/BgAAJwAAAGNvbS9zdW4vc291cmNlL3RyZWUvSW5zdGFuY2VPZlRyZWUuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAxNCwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnNvdXJjZS50cmVlOwoKLyoqCiAqIEEgdHJlZSBub2RlIGZvciBhbiB7QGNvZGUgaW5zdGFuY2VvZn0gZXhwcmVzc2lvbi4KICoKICogRm9yIGV4YW1wbGU6CiAqIDxwcmU+CiAqICAgPGVtPmV4cHJlc3Npb248L2VtPiBpbnN0YW5jZW9mIDxlbT50eXBlPC9lbT4KICogPC9wcmU+CiAqCiAqIEBqbHMgc2VjdGlvbiAxNS4yMC4yCiAqCiAqIEBhdXRob3IgUGV0ZXIgdm9uIGRlciBBaCZlYWN1dGU7CiAqIEBhdXRob3IgSm9uYXRoYW4gR2liYm9ucwogKiBAc2luY2UgMS42CiAqLwpwdWJsaWMgaW50ZXJmYWNlIEluc3RhbmNlT2ZUcmVlIGV4dGVuZHMgRXhwcmVzc2lvblRyZWUgewogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBleHByZXNzaW9uIHRvIGJlIHRlc3RlZC4KICAgICAqIEByZXR1cm4gdGhlIGV4cHJlc3Npb24KICAgICAqLwogICAgRXhwcmVzc2lvblRyZWUgZ2V0RXhwcmVzc2lvbigpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgdHlwZSBmb3Igd2hpY2ggdG8gY2hlY2suCiAgICAgKiBAcmV0dXJuIHRoZSB0eXBlCiAgICAgKi8KICAgIFRyZWUgZ2V0VHlwZSgpOwp9ClBLAwQKAAAIAAAGO6lKJXjV7RoHAAAaBwAALgAAAGNvbS9zdW4vc291cmNlL3RyZWUvUGFyYW1ldGVyaXplZFR5cGVUcmVlLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMTQsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi5zb3VyY2UudHJlZTsKCmltcG9ydCBqYXZhLnV0aWwuTGlzdDsKCi8qKgogKiBBIHRyZWUgbm9kZSBmb3IgYSB0eXBlIGV4cHJlc3Npb24gaW52b2x2aW5nIHR5cGUgcGFyYW1ldGVycy4KICoKICogRm9yIGV4YW1wbGU6CiAqIDxwcmU+CiAqICAgPGVtPnR5cGU8L2VtPiAmbHQ7IDxlbT50eXBlQXJndW1lbnRzPC9lbT4gJmd0OwogKiA8L3ByZT4KICoKICogQGpscyBzZWN0aW9uIDQuNS4xCiAqCiAqIEBhdXRob3IgUGV0ZXIgdm9uIGRlciBBaCZlYWN1dGU7CiAqIEBhdXRob3IgSm9uYXRoYW4gR2liYm9ucwogKiBAc2luY2UgMS42CiAqLwpwdWJsaWMgaW50ZXJmYWNlIFBhcmFtZXRlcml6ZWRUeXBlVHJlZSBleHRlbmRzIFRyZWUgewogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBiYXNlIHR5cGUuCiAgICAgKiBAcmV0dXJuIHRoZSBiYXNlIHR5cGUKICAgICAqLwogICAgVHJlZSBnZXRUeXBlKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSB0eXBlIGFyZ3VtZW50cy4KICAgICAqIEByZXR1cm4gdGhlIHR5cGUgYXJndW1lbnRzCiAgICAgKi8KICAgIExpc3Q8PyBleHRlbmRzIFRyZWU+IGdldFR5cGVBcmd1bWVudHMoKTsKfQpQSwMECgAACAAABjupSp028ORYBwAAWAcAACkAAABjb20vc3VuL3NvdXJjZS90cmVlL01lbWJlclNlbGVjdFRyZWUuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAxNCwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnNvdXJjZS50cmVlOwoKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC5OYW1lOwoKLyoqCiAqIEEgdHJlZSBub2RlIGZvciBhIG1lbWJlciBhY2Nlc3MgZXhwcmVzc2lvbi4KICoKICogRm9yIGV4YW1wbGU6CiAqIDxwcmU+CiAqICAgPGVtPmV4cHJlc3Npb248L2VtPiAuIDxlbT5pZGVudGlmaWVyPC9lbT4KICogPC9wcmU+CiAqCiAqIEBqbHMgc2VjdGlvbnMgNi41LCAxNS4xMSxhbmQgMTUuMTIKICoKICogQGF1dGhvciBQZXRlciB2b24gZGVyIEFoJmVhY3V0ZTsKICogQGF1dGhvciBKb25hdGhhbiBHaWJib25zCiAqIEBzaW5jZSAxLjYKICovCnB1YmxpYyBpbnRlcmZhY2UgTWVtYmVyU2VsZWN0VHJlZSBleHRlbmRzIEV4cHJlc3Npb25UcmVlIHsKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgZXhwcmVzc2lvbiBmb3Igd2hpY2ggYSBtZW1iZXIgaXMgdG8gYmUgc2VsZWN0ZWQuCiAgICAgKiBAcmV0dXJuIHRoZSBleHByZXNzaW9uLgogICAgICovCiAgICBFeHByZXNzaW9uVHJlZSBnZXRFeHByZXNzaW9uKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBuYW1lIG9mIHRoZSBtZW1iZXIgdG8gYmUgc2VsZWN0ZWQuCiAgICAgKiBAcmV0dXJuIHRoZSBtZW1iZXIKICAgICAqLwogICAgTmFtZSBnZXRJZGVudGlmaWVyKCk7Cn0KUEsDBAoAAAgAAAY7qUrytGxp1QcAANUHAAAkAAAAY29tL3N1bi9zb3VyY2UvdHJlZS9FeHBvcnRzVHJlZS5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDA5LCAyMDE2LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4uc291cmNlLnRyZWU7CgppbXBvcnQgamF2YS51dGlsLkxpc3Q7CgovKioKICogQSB0cmVlIG5vZGUgZm9yIGFuICdleHBvcnRzJyBkaXJlY3RpdmUgaW4gYSBtb2R1bGUgZGVjbGFyYXRpb24uCiAqCiAqIEZvciBleGFtcGxlOgogKiA8cHJlPgogKiAgICBleHBvcnRzIDxlbT5wYWNrYWdlLW5hbWU8L2VtPjsKICogICAgZXhwb3J0cyA8ZW0+cGFja2FnZS1uYW1lPC9lbT4gdG8gPGVtPm1vZHVsZS1uYW1lPC9lbT47CiAqIDwvcHJlPgogKgogKiBAc2luY2UgOQogKi8KcHVibGljIGludGVyZmFjZSBFeHBvcnRzVHJlZSBleHRlbmRzIERpcmVjdGl2ZVRyZWUgewoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgbmFtZSBvZiB0aGUgcGFja2FnZSB0byBiZSBleHBvcnRlZC4KICAgICAqIEByZXR1cm4gIHRoZSBuYW1lIG9mIHRoZSBwYWNrYWdlIHRvIGJlIGV4cG9ydGVkCiAgICAgKi8KICAgIEV4cHJlc3Npb25UcmVlIGdldFBhY2thZ2VOYW1lKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBuYW1lcyBvZiB0aGUgbW9kdWxlcyB0byB3aGljaCB0aGUgcGFja2FnZSBpcyBleHBvcnRlZCwKICAgICAqIG9yIG51bGwsIGlmIHRoZSBwYWNrYWdlIGlzIGV4cG9ydGVkIHRvIGFsbCBtb2R1bGVzLgogICAgICoKICAgICAqIEByZXR1cm4gdGhlIG5hbWVzIG9mIHRoZSBtb2R1bGVzIHRvIHdoaWNoIHRoZSBwYWNrYWdlIGlzIGV4cG9ydGVkLCBvciBudWxsCiAgICAgKi8KICAgIExpc3Q8PyBleHRlbmRzIEV4cHJlc3Npb25UcmVlPiBnZXRNb2R1bGVOYW1lcygpOwp9ClBLAwQKAAAIAAAGO6lKDBLZfaoHAACqBwAALwAAAGNvbS9zdW4vc291cmNlL3RyZWUvQ29tcG91bmRBc3NpZ25tZW50VHJlZS5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDA1LCAyMDE0LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4uc291cmNlLnRyZWU7CgovKioKICogQSB0cmVlIG5vZGUgZm9yIGNvbXBvdW5kIGFzc2lnbm1lbnQgb3BlcmF0b3IuCiAqIFVzZSB7QGxpbmsgI2dldEtpbmQgZ2V0S2luZH0gdG8gZGV0ZXJtaW5lIHRoZSBraW5kIG9mIG9wZXJhdG9yLgogKgogKiBGb3IgZXhhbXBsZToKICogPHByZT4KICogICA8ZW0+dmFyaWFibGU8L2VtPiA8ZW0+b3BlcmF0b3I8L2VtPiA8ZW0+ZXhwcmVzc2lvbjwvZW0+CiAqIDwvcHJlPgogKgogKiBAamxzIHNlY3Rpb24gMTUuMjYuMgogKgogKiBAYXV0aG9yIFBldGVyIHZvbiBkZXIgQWgmZWFjdXRlOwogKiBAYXV0aG9yIEpvbmF0aGFuIEdpYmJvbnMKICogQHNpbmNlIDEuNgogKi8KcHVibGljIGludGVyZmFjZSBDb21wb3VuZEFzc2lnbm1lbnRUcmVlIGV4dGVuZHMgRXhwcmVzc2lvblRyZWUgewogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSB2YXJpYWJsZSBvbiB0aGUgbGVmdCBoYW5kIHNpZGUgb2YgdGhlIGNvbXBvdW5kIGFzc2lnbm1lbnQuCiAgICAgKiBAcmV0dXJuIHRoZSB2YXJpYWJsZQogICAgICovCiAgICBFeHByZXNzaW9uVHJlZSBnZXRWYXJpYWJsZSgpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgZXhwcmVzc2lvbiBvbiB0aGUgcmlnaHQgaGFuZCBzaWRlIG9mIHRoZSBjb21wb3VuZCBhc3NpZ25tZW50LgogICAgICogQHJldHVybiB0aGUgZXhwcmVzc2lvbgogICAgICovCiAgICBFeHByZXNzaW9uVHJlZSBnZXRFeHByZXNzaW9uKCk7Cn0KUEsDBAoAAAgAAAY7qUoTvsZpzAoAAMwKAAAiAAAAY29tL3N1bi9zb3VyY2UvdHJlZS9DbGFzc1RyZWUuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAxNCwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnNvdXJjZS50cmVlOwoKaW1wb3J0IGphdmEudXRpbC5MaXN0OwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5lbGVtZW50Lk5hbWU7CgovKioKICogQSB0cmVlIG5vZGUgZm9yIGEgY2xhc3MsIGludGVyZmFjZSwgZW51bSwgb3IgYW5ub3RhdGlvbgogKiB0eXBlIGRlY2xhcmF0aW9uLgogKgogKiBGb3IgZXhhbXBsZToKICogPHByZT4KICogICA8ZW0+bW9kaWZpZXJzPC9lbT4gY2xhc3MgPGVtPnNpbXBsZU5hbWU8L2VtPiA8ZW0+dHlwZVBhcmFtZXRlcnM8L2VtPgogKiAgICAgICBleHRlbmRzIDxlbT5leHRlbmRzQ2xhdXNlPC9lbT4KICogICAgICAgaW1wbGVtZW50cyA8ZW0+aW1wbGVtZW50c0NsYXVzZTwvZW0+CiAqICAgewogKiAgICAgICA8ZW0+bWVtYmVyczwvZW0+CiAqICAgfQogKiA8L3ByZT4KICoKICogQGpscyBzZWN0aW9ucyA4LjEsIDguOSwgOS4xLCBhbmQgOS42CiAqCiAqIEBhdXRob3IgUGV0ZXIgdm9uIGRlciBBaCZlYWN1dGU7CiAqIEBhdXRob3IgSm9uYXRoYW4gR2liYm9ucwogKiBAc2luY2UgMS42CiAqLwpwdWJsaWMgaW50ZXJmYWNlIENsYXNzVHJlZSBleHRlbmRzIFN0YXRlbWVudFRyZWUgewogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBtb2RpZmllcnMsIGluY2x1ZGluZyBhbnkgYW5ub3RhdGlvbnMsCiAgICAgKiBmb3IgdGhpcyB0eXBlIGRlY2xhcmF0aW9uLgogICAgICogQHJldHVybiB0aGUgbW9kaWZpZXJzCiAgICAgKi8KICAgIE1vZGlmaWVyc1RyZWUgZ2V0TW9kaWZpZXJzKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBzaW1wbGUgbmFtZSBvZiB0aGlzIHR5cGUgZGVjbGFyYXRpb24uCiAgICAgKiBAcmV0dXJuIHRoZSBzaW1wbGUgbmFtZQogICAgICovCiAgICBOYW1lIGdldFNpbXBsZU5hbWUoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgYW55IHR5cGUgcGFyYW1ldGVycyBvZiB0aGlzIHR5cGUgZGVjbGFyYXRpb24uCiAgICAgKiBAcmV0dXJuIHRoZSB0eXBlIHBhcmFtZXRlcnMKICAgICAqLwogICAgTGlzdDw/IGV4dGVuZHMgVHlwZVBhcmFtZXRlclRyZWU+IGdldFR5cGVQYXJhbWV0ZXJzKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBzdXBlcnR5cGUgb2YgdGhpcyB0eXBlIGRlY2xhcmF0aW9uLAogICAgICogb3Ige0Bjb2RlIG51bGx9IGlmIG5vbmUgaXMgcHJvdmlkZWQuCiAgICAgKiBAcmV0dXJuIHRoZSBzdXBlcnR5cGUKICAgICAqLwogICAgVHJlZSBnZXRFeHRlbmRzQ2xhdXNlKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBpbnRlcmZhY2VzIGltcGxlbWVudGVkIGJ5IHRoaXMgdHlwZSBkZWNsYXJhdGlvbi4KICAgICAqIEByZXR1cm4gdGhlIGludGVyZmFjZXMKICAgICAqLwogICAgTGlzdDw/IGV4dGVuZHMgVHJlZT4gZ2V0SW1wbGVtZW50c0NsYXVzZSgpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgbWVtYmVycyBkZWNsYXJlZCBpbiB0aGlzIHR5cGUgZGVjbGFyYXRpb24uCiAgICAgKiBAcmV0dXJuIHRoZSBtZW1iZXJzCiAgICAgKi8KICAgIExpc3Q8PyBleHRlbmRzIFRyZWU+IGdldE1lbWJlcnMoKTsKfQpQSwMECgAACAAABjupSiM5Nk0YBwAAGAcAACgAAABjb20vc3VuL3NvdXJjZS90cmVlL0RvV2hpbGVMb29wVHJlZS5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDA1LCAyMDE0LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4uc291cmNlLnRyZWU7CgovKioKICogQSB0cmVlIG5vZGUgZm9yIGEge0Bjb2RlIGRvfSBzdGF0ZW1lbnQuCiAqCiAqIEZvciBleGFtcGxlOgogKiA8cHJlPgogKiAgIGRvCiAqICAgICAgIDxlbT5zdGF0ZW1lbnQ8L2VtPgogKiAgIHdoaWxlICggPGVtPmV4cHJlc3Npb248L2VtPiApOwogKiA8L3ByZT4KICoKICogQGpscyBzZWN0aW9uIDE0LjEzCiAqCiAqIEBhdXRob3IgUGV0ZXIgdm9uIGRlciBBaCZlYWN1dGU7CiAqIEBhdXRob3IgSm9uYXRoYW4gR2liYm9ucwogKiBAc2luY2UgMS42CiAqLwpwdWJsaWMgaW50ZXJmYWNlIERvV2hpbGVMb29wVHJlZSBleHRlbmRzIFN0YXRlbWVudFRyZWUgewogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBjb25kaXRpb24gb2YgdGhlIGxvb3AuCiAgICAgKiBAcmV0dXJuIHRoZSBjb25kaXRpb24KICAgICAqLwogICAgRXhwcmVzc2lvblRyZWUgZ2V0Q29uZGl0aW9uKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBib2R5IG9mIHRoZSBsb29wLgogICAgICogQHJldHVybiB0aGUgYm9keSBvZiB0aGUgbG9vcAogICAgICovCiAgICBTdGF0ZW1lbnRUcmVlIGdldFN0YXRlbWVudCgpOwp9ClBLAwQKAAAIAAAGO6lKdOPxb14NAABeDQAAIwAAAGNvbS9zdW4vc291cmNlL3RyZWUvTWV0aG9kVHJlZS5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDA1LCAyMDE0LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4uc291cmNlLnRyZWU7CgppbXBvcnQgamF2YS51dGlsLkxpc3Q7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuTmFtZTsKCi8qKgogKiBBIHRyZWUgbm9kZSBmb3IgYSBtZXRob2Qgb3IgYW5ub3RhdGlvbiB0eXBlIGVsZW1lbnQgZGVjbGFyYXRpb24uCiAqCiAqIEZvciBleGFtcGxlOgogKiA8cHJlPgogKiAgIDxlbT5tb2RpZmllcnM8L2VtPiA8ZW0+dHlwZVBhcmFtZXRlcnM8L2VtPiA8ZW0+dHlwZTwvZW0+IDxlbT5uYW1lPC9lbT4KICogICAgICAoIDxlbT5wYXJhbWV0ZXJzPC9lbT4gKQogKiAgICAgIDxlbT5ib2R5PC9lbT4KICoKICogICA8ZW0+bW9kaWZpZXJzPC9lbT4gPGVtPnR5cGU8L2VtPiA8ZW0+bmFtZTwvZW0+ICgpIGRlZmF1bHQgPGVtPmRlZmF1bHRWYWx1ZTwvZW0+CiAqIDwvcHJlPgogKgogKiBAamxzIHNlY3Rpb25zIDguNCwgOC42LCA4LjcsIDkuNCwgYW5kIDkuNgogKgogKiBAYXV0aG9yIFBldGVyIHZvbiBkZXIgQWgmZWFjdXRlOwogKiBAYXV0aG9yIEpvbmF0aGFuIEdpYmJvbnMKICogQHNpbmNlIDEuNgogKi8KcHVibGljIGludGVyZmFjZSBNZXRob2RUcmVlIGV4dGVuZHMgVHJlZSB7CiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIG1vZGlmaWVycywgaW5jbHVkaW5nIGFueSBhbm5vdGF0aW9ucyBmb3IgdGhlIG1ldGhvZCBiZWluZyBkZWNsYXJlZC4KICAgICAqIEByZXR1cm4gdGhlIG1vZGlmaWVycwogICAgICovCiAgICBNb2RpZmllcnNUcmVlIGdldE1vZGlmaWVycygpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgbmFtZSBvZiB0aGUgbWV0aG9kIGJlaW5nIGRlY2xhcmVkLgogICAgICogQHJldHVybiB0aGUgbmFtZQogICAgICovCiAgICBOYW1lIGdldE5hbWUoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHJldHVybiB0eXBlIG9mIHRoZSBtZXRob2QgYmVpbmcgZGVjbGFyZWQuCiAgICAgKiBSZXR1cm5zIHtAY29kZSBudWxsfSBmb3IgYSBjb25zdHJ1Y3Rvci4KICAgICAqIEByZXR1cm4gdGhlIHJldHVybiB0eXBlCiAgICAgKi8KICAgIFRyZWUgZ2V0UmV0dXJuVHlwZSgpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgdHlwZSBwYXJhbWV0ZXJzIG9mIHRoZSBtZXRob2QgYmVpbmcgZGVjbGFyZWQuCiAgICAgKiBAcmV0dXJuIHRoZSB0eXBlIHBhcmFtZXRlcnMKICAgICAqLwogICAgTGlzdDw/IGV4dGVuZHMgVHlwZVBhcmFtZXRlclRyZWU+IGdldFR5cGVQYXJhbWV0ZXJzKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBwYXJhbWV0ZXJzIG9mIHRoZSBtZXRob2QgYmVpbmcgZGVjbGFyZWQuCiAgICAgKiBAcmV0dXJuIHRoZSBwYXJhbWV0ZXJzCiAgICAgKi8KICAgIExpc3Q8PyBleHRlbmRzIFZhcmlhYmxlVHJlZT4gZ2V0UGFyYW1ldGVycygpOwoKICAgIC8qKgogICAgICogUmV0dXJuIGFuIGV4cGxpY2l0IHJlY2VpdmVyIHBhcmFtZXRlciAoInRoaXMiIHBhcmFtZXRlciksCiAgICAgKiBvciB7QGNvZGUgbnVsbH0gaWYgbm9uZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIGFuIGV4cGxpY2l0IHJlY2VpdmVyIHBhcmFtZXRlciAoInRoaXMiIHBhcmFtZXRlcikKICAgICAqIEBzaW5jZSAxLjgKICAgICAqLwogICAgVmFyaWFibGVUcmVlIGdldFJlY2VpdmVyUGFyYW1ldGVyKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBleGNlcHRpb25zIGxpc3RlZCBhcyBiZWluZyB0aHJvd24gYnkgdGhpcyBtZXRob2QuCiAgICAgKiBAcmV0dXJuIHRoZSBleGNlcHRpb25zCiAgICAgKi8KICAgIExpc3Q8PyBleHRlbmRzIEV4cHJlc3Npb25UcmVlPiBnZXRUaHJvd3MoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIG1ldGhvZCBib2R5LCBvciB7QGNvZGUgbnVsbH0gaWYgdGhpcyBpcyBhbiBhYnN0cmFjdCBvciBuYXRpdmUgbWV0aG9kLgogICAgICogQHJldHVybiB0aGUgbWV0aG9kIGJvZHkKICAgICAqLwogICAgQmxvY2tUcmVlIGdldEJvZHkoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGRlZmF1bHQgdmFsdWUsIGlmIHRoaXMgaXMgYW4gZWxlbWVudCB3aXRoaW4KICAgICAqIGFuIGFubm90YXRpb24gdHlwZSBkZWNsYXJhdGlvbi4KICAgICAqIFJldHVybnMge0Bjb2RlIG51bGx9IG90aGVyd2lzZS4KICAgICAqIEByZXR1cm4gdGhlIGRlZmF1bHQgdmFsdWUKICAgICAqLwogICAgVHJlZSBnZXREZWZhdWx0VmFsdWUoKTsgLy8gZm9yIGFubm90YXRpb24gdHlwZXMKfQpQSwMECgAACAAABjupSg5OAb/GBgAAxgYAACQAAABjb20vc3VuL3NvdXJjZS90cmVlL1BhY2thZ2VUcmVlLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTQsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi5zb3VyY2UudHJlZTsKCmltcG9ydCBqYXZhLnV0aWwuTGlzdDsKCi8qKgogKiBSZXByZXNlbnRzIHRoZSBwYWNrYWdlIGRlY2xhcmF0aW9uLgogKgogKiBAamxzIHNlY3Rpb25zIDcuMywgYW5kIDcuNAogKgogKiBAYXV0aG9yIFBhdWwgR292ZXJlYXUKICogQHNpbmNlIDkKICovCnB1YmxpYyBpbnRlcmZhY2UgUGFja2FnZVRyZWUgZXh0ZW5kcyBUcmVlIHsKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgYW5ub3RhdGlvbnMgYXNzb2NpYXRlZCB3aXRoIHRoaXMgcGFja2FnZSBkZWNsYXJhdGlvbi4KICAgICAqIEByZXR1cm4gdGhlIGFubm90YXRpb25zCiAgICAgKi8KICAgIExpc3Q8PyBleHRlbmRzIEFubm90YXRpb25UcmVlPiBnZXRBbm5vdGF0aW9ucygpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgbmFtZSBvZiB0aGUgcGFja2FnZSBiZWluZyBkZWNsYXJlZC4KICAgICAqIEByZXR1cm4gdGhlIG5hbWUKICAgICAqLwogICAgRXhwcmVzc2lvblRyZWUgZ2V0UGFja2FnZU5hbWUoKTsKfQpQSwMECgAACAAABjupSgAAAAAAAAAAAAAAABQAAABjb20vc3VuL3NvdXJjZS91dGlsL1BLAwQKAAAIAAAGO6lK6vTnkR5UAAAeVAAAKgAAAGNvbS9zdW4vc291cmNlL3V0aWwvU2ltcGxlVHJlZVZpc2l0b3IuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAxNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnNvdXJjZS51dGlsOwoKaW1wb3J0IGNvbS5zdW4uc291cmNlLnRyZWUuKjsKCi8qKgogKiBBIHNpbXBsZSB2aXNpdG9yIGZvciB0cmVlIG5vZGVzLgogKgogKiBAcGFyYW0gPFI+IHRoZSByZXR1cm4gdHlwZSBvZiB0aGlzIHZpc2l0b3IncyBtZXRob2RzLiAgVXNlIHtAbGluawogKiAgICAgICAgICAgIFZvaWR9IGZvciB2aXNpdG9ycyB0aGF0IGRvIG5vdCBuZWVkIHRvIHJldHVybiByZXN1bHRzLgogKiBAcGFyYW0gPFA+IHRoZSB0eXBlIG9mIHRoZSBhZGRpdGlvbmFsIHBhcmFtZXRlciB0byB0aGlzIHZpc2l0b3IncwogKiAgICAgICAgICAgIG1ldGhvZHMuICBVc2Uge0Bjb2RlIFZvaWR9IGZvciB2aXNpdG9ycyB0aGF0IGRvIG5vdCBuZWVkIGFuCiAqICAgICAgICAgICAgYWRkaXRpb25hbCBwYXJhbWV0ZXIuCiAqCiAqIEBhdXRob3IgUGV0ZXIgdm9uIGRlciBBaCZlYWN1dGU7CiAqIEBzaW5jZSAxLjYKICovCnB1YmxpYyBjbGFzcyBTaW1wbGVUcmVlVmlzaXRvciA8UixQPiBpbXBsZW1lbnRzIFRyZWVWaXNpdG9yPFIsUD4gewogICAgLyoqCiAgICAgKiBUaGUgZGVmYXVsdCB2YWx1ZSwgcmV0dXJuZWQgYnkgdGhlIHtAbGluayAjZGVmYXVsdEFjdGlvbiBkZWZhdWx0IGFjdGlvbn0uCiAgICAgKi8KICAgIHByb3RlY3RlZCBmaW5hbCBSIERFRkFVTFRfVkFMVUU7CgogICAgLyoqCiAgICAgKiBDcmVhdGVzIGEgdmlzaXRvciwgd2l0aCBhIERFRkFVTFRfVkFMVUUgb2Yge0Bjb2RlIG51bGx9LgogICAgICovCiAgICBwcm90ZWN0ZWQgU2ltcGxlVHJlZVZpc2l0b3IoKSB7CiAgICAgICAgREVGQVVMVF9WQUxVRSA9IG51bGw7CiAgICB9CgogICAgLyoqCiAgICAgKiBDcmVhdGVzIGEgdmlzaXRvciwgd2l0aCBhIHNwZWNpZmllZCBERUZBVUxUX1ZBTFVFLgogICAgICogQHBhcmFtIGRlZmF1bHRWYWx1ZSB0aGUgZGVmYXVsdCB2YWx1ZSB0byBiZSByZXR1cm5lZCBieSB0aGUgZGVmYXVsdCBhY3Rpb24uCiAgICAgKi8KICAgIHByb3RlY3RlZCBTaW1wbGVUcmVlVmlzaXRvcihSIGRlZmF1bHRWYWx1ZSkgewogICAgICAgIERFRkFVTFRfVkFMVUUgPSBkZWZhdWx0VmFsdWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBUaGUgZGVmYXVsdCBhY3Rpb24sIHVzZWQgYnkgYWxsIHZpc2l0IG1ldGhvZHMgdGhhdCBhcmUgbm90IG92ZXJyaWRkZW4uCiAgICAgKiBAcGFyYW0gbm9kZSB0aGUgbm9kZSBiZWluZyB2aXNpdGVkCiAgICAgKiBAcGFyYW0gcCB0aGUgcGFyYW1ldGVyIHZhbHVlIHBhc3NlZCB0byB0aGUgdmlzaXQgbWV0aG9kCiAgICAgKiBAcmV0dXJuIHRoZSByZXN1bHQgdmFsdWUgdG8gYmUgcmV0dXJuZWQgZnJvbSB0aGUgdmlzaXQgbWV0aG9kCiAgICAgKi8KICAgIHByb3RlY3RlZCBSIGRlZmF1bHRBY3Rpb24oVHJlZSBub2RlLCBQIHApIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9WQUxVRTsKICAgIH0KCiAgICAvKioKICAgICAqIEludm9rZXMgdGhlIGFwcHJvcHJpYXRlIHZpc2l0IG1ldGhvZCBzcGVjaWZpYyB0byB0aGUgdHlwZSBvZiB0aGUgbm9kZS4KICAgICAqIEBwYXJhbSBub2RlIHRoZSBub2RlIG9uIHdoaWNoIHRvIGRpc3BhdGNoCiAgICAgKiBAcGFyYW0gcCBhIHBhcmFtZXRlciB0byBiZSBwYXNzZWQgdG8gdGhlIGFwcHJvcHJpYXRlIHZpc2l0IG1ldGhvZAogICAgICogQHJldHVybiB0aGUgdmFsdWUgcmV0dXJucyBmcm9tIHRoZSBhcHByb3ByaWF0ZSB2aXNpdCBtZXRob2QKICAgICAqLwogICAgcHVibGljIGZpbmFsIFIgdmlzaXQoVHJlZSBub2RlLCBQIHApIHsKICAgICAgICByZXR1cm4gKG5vZGUgPT0gbnVsbCkgPyBudWxsIDogbm9kZS5hY2NlcHQodGhpcywgcCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBJbnZva2VzIHRoZSBhcHByb3ByaWF0ZSB2aXNpdCBtZXRob2Qgb24gZWFjaCBvZiBhIHNlcXVlbmNlIG9mIG5vZGVzLgogICAgICogQHBhcmFtIG5vZGVzIHRoZSBub2RlcyBvbiB3aGljaCB0byBkaXNwYXRjaAogICAgICogQHBhcmFtIHAgYSBwYXJhbWV0ZXIgdmFsdWUgdG8gYmUgcGFzc2VkIHRvIGVhY2ggYXBwcm9wcmlhdGUgdmlzaXQgbWV0aG9kCiAgICAgKiBAcmV0dXJuIHRoZSB2YWx1ZSByZXR1cm4gZnJvbSB0aGUgbGFzdCBvZiB0aGUgdmlzaXQgbWV0aG9kcywgb3IgbnVsbAogICAgICogICAgICBpZiBub25lIHdlcmUgY2FsbGVkLgogICAgICovCiAgICBwdWJsaWMgZmluYWwgUiB2aXNpdChJdGVyYWJsZTw/IGV4dGVuZHMgVHJlZT4gbm9kZXMsIFAgcCkgewogICAgICAgIFIgciA9IG51bGw7CiAgICAgICAgaWYgKG5vZGVzICE9IG51bGwpCiAgICAgICAgICAgIGZvciAoVHJlZSBub2RlIDogbm9kZXMpCiAgICAgICAgICAgICAgICByID0gdmlzaXQobm9kZSwgcCk7CiAgICAgICAgcmV0dXJuIHI7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gY2FsbHMge0Bjb2RlIGRlZmF1bHRBY3Rpb259LgogICAgICoKICAgICAqIEBwYXJhbSBub2RlIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gIHRoZSByZXN1bHQgb2Yge0Bjb2RlIGRlZmF1bHRBY3Rpb259CiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRDb21waWxhdGlvblVuaXQoQ29tcGlsYXRpb25Vbml0VHJlZSBub2RlLCBQIHApIHsKICAgICAgICByZXR1cm4gZGVmYXVsdEFjdGlvbihub2RlLCBwKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30gVGhpcyBpbXBsZW1lbnRhdGlvbiBjYWxscyB7QGNvZGUgZGVmYXVsdEFjdGlvbn0uCiAgICAgKgogICAgICogQHBhcmFtIG5vZGUge0Bpbmhlcml0RG9jfQogICAgICogQHBhcmFtIHAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiAgdGhlIHJlc3VsdCBvZiB7QGNvZGUgZGVmYXVsdEFjdGlvbn0KICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgUiB2aXNpdFBhY2thZ2UoUGFja2FnZVRyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIGRlZmF1bHRBY3Rpb24obm9kZSwgcCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gY2FsbHMge0Bjb2RlIGRlZmF1bHRBY3Rpb259LgogICAgICoKICAgICAqIEBwYXJhbSBub2RlIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gIHRoZSByZXN1bHQgb2Yge0Bjb2RlIGRlZmF1bHRBY3Rpb259CiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRJbXBvcnQoSW1wb3J0VHJlZSBub2RlLCBQIHApIHsKICAgICAgICByZXR1cm4gZGVmYXVsdEFjdGlvbihub2RlLCBwKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30gVGhpcyBpbXBsZW1lbnRhdGlvbiBjYWxscyB7QGNvZGUgZGVmYXVsdEFjdGlvbn0uCiAgICAgKgogICAgICogQHBhcmFtIG5vZGUge0Bpbmhlcml0RG9jfQogICAgICogQHBhcmFtIHAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiAgdGhlIHJlc3VsdCBvZiB7QGNvZGUgZGVmYXVsdEFjdGlvbn0KICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgUiB2aXNpdENsYXNzKENsYXNzVHJlZSBub2RlLCBQIHApIHsKICAgICAgICByZXR1cm4gZGVmYXVsdEFjdGlvbihub2RlLCBwKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30gVGhpcyBpbXBsZW1lbnRhdGlvbiBjYWxscyB7QGNvZGUgZGVmYXVsdEFjdGlvbn0uCiAgICAgKgogICAgICogQHBhcmFtIG5vZGUge0Bpbmhlcml0RG9jfQogICAgICogQHBhcmFtIHAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiAgdGhlIHJlc3VsdCBvZiB7QGNvZGUgZGVmYXVsdEFjdGlvbn0KICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgUiB2aXNpdE1ldGhvZChNZXRob2RUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIHJldHVybiBkZWZhdWx0QWN0aW9uKG5vZGUsIHApOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIGNhbGxzIHtAY29kZSBkZWZhdWx0QWN0aW9ufS4KICAgICAqCiAgICAgKiBAcGFyYW0gbm9kZSB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuICB0aGUgcmVzdWx0IG9mIHtAY29kZSBkZWZhdWx0QWN0aW9ufQogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0VmFyaWFibGUoVmFyaWFibGVUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIHJldHVybiBkZWZhdWx0QWN0aW9uKG5vZGUsIHApOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIGNhbGxzIHtAY29kZSBkZWZhdWx0QWN0aW9ufS4KICAgICAqCiAgICAgKiBAcGFyYW0gbm9kZSB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuICB0aGUgcmVzdWx0IG9mIHtAY29kZSBkZWZhdWx0QWN0aW9ufQogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0RW1wdHlTdGF0ZW1lbnQoRW1wdHlTdGF0ZW1lbnRUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIHJldHVybiBkZWZhdWx0QWN0aW9uKG5vZGUsIHApOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIGNhbGxzIHtAY29kZSBkZWZhdWx0QWN0aW9ufS4KICAgICAqCiAgICAgKiBAcGFyYW0gbm9kZSB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuICB0aGUgcmVzdWx0IG9mIHtAY29kZSBkZWZhdWx0QWN0aW9ufQogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0QmxvY2soQmxvY2tUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIHJldHVybiBkZWZhdWx0QWN0aW9uKG5vZGUsIHApOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIGNhbGxzIHtAY29kZSBkZWZhdWx0QWN0aW9ufS4KICAgICAqCiAgICAgKiBAcGFyYW0gbm9kZSB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuICB0aGUgcmVzdWx0IG9mIHtAY29kZSBkZWZhdWx0QWN0aW9ufQogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0RG9XaGlsZUxvb3AoRG9XaGlsZUxvb3BUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIHJldHVybiBkZWZhdWx0QWN0aW9uKG5vZGUsIHApOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIGNhbGxzIHtAY29kZSBkZWZhdWx0QWN0aW9ufS4KICAgICAqCiAgICAgKiBAcGFyYW0gbm9kZSB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuICB0aGUgcmVzdWx0IG9mIHtAY29kZSBkZWZhdWx0QWN0aW9ufQogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0V2hpbGVMb29wKFdoaWxlTG9vcFRyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIGRlZmF1bHRBY3Rpb24obm9kZSwgcCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gY2FsbHMge0Bjb2RlIGRlZmF1bHRBY3Rpb259LgogICAgICoKICAgICAqIEBwYXJhbSBub2RlIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gIHRoZSByZXN1bHQgb2Yge0Bjb2RlIGRlZmF1bHRBY3Rpb259CiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRGb3JMb29wKEZvckxvb3BUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIHJldHVybiBkZWZhdWx0QWN0aW9uKG5vZGUsIHApOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIGNhbGxzIHtAY29kZSBkZWZhdWx0QWN0aW9ufS4KICAgICAqCiAgICAgKiBAcGFyYW0gbm9kZSB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuICB0aGUgcmVzdWx0IG9mIHtAY29kZSBkZWZhdWx0QWN0aW9ufQogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0RW5oYW5jZWRGb3JMb29wKEVuaGFuY2VkRm9yTG9vcFRyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIGRlZmF1bHRBY3Rpb24obm9kZSwgcCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gY2FsbHMge0Bjb2RlIGRlZmF1bHRBY3Rpb259LgogICAgICoKICAgICAqIEBwYXJhbSBub2RlIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gIHRoZSByZXN1bHQgb2Yge0Bjb2RlIGRlZmF1bHRBY3Rpb259CiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRMYWJlbGVkU3RhdGVtZW50KExhYmVsZWRTdGF0ZW1lbnRUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIHJldHVybiBkZWZhdWx0QWN0aW9uKG5vZGUsIHApOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIGNhbGxzIHtAY29kZSBkZWZhdWx0QWN0aW9ufS4KICAgICAqCiAgICAgKiBAcGFyYW0gbm9kZSB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuICB0aGUgcmVzdWx0IG9mIHtAY29kZSBkZWZhdWx0QWN0aW9ufQogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0U3dpdGNoKFN3aXRjaFRyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIGRlZmF1bHRBY3Rpb24obm9kZSwgcCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gY2FsbHMge0Bjb2RlIGRlZmF1bHRBY3Rpb259LgogICAgICoKICAgICAqIEBwYXJhbSBub2RlIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gIHRoZSByZXN1bHQgb2Yge0Bjb2RlIGRlZmF1bHRBY3Rpb259CiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRDYXNlKENhc2VUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIHJldHVybiBkZWZhdWx0QWN0aW9uKG5vZGUsIHApOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIGNhbGxzIHtAY29kZSBkZWZhdWx0QWN0aW9ufS4KICAgICAqCiAgICAgKiBAcGFyYW0gbm9kZSB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuICB0aGUgcmVzdWx0IG9mIHtAY29kZSBkZWZhdWx0QWN0aW9ufQogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0U3luY2hyb25pemVkKFN5bmNocm9uaXplZFRyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIGRlZmF1bHRBY3Rpb24obm9kZSwgcCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gY2FsbHMge0Bjb2RlIGRlZmF1bHRBY3Rpb259LgogICAgICoKICAgICAqIEBwYXJhbSBub2RlIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gIHRoZSByZXN1bHQgb2Yge0Bjb2RlIGRlZmF1bHRBY3Rpb259CiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRUcnkoVHJ5VHJlZSBub2RlLCBQIHApIHsKICAgICAgICByZXR1cm4gZGVmYXVsdEFjdGlvbihub2RlLCBwKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30gVGhpcyBpbXBsZW1lbnRhdGlvbiBjYWxscyB7QGNvZGUgZGVmYXVsdEFjdGlvbn0uCiAgICAgKgogICAgICogQHBhcmFtIG5vZGUge0Bpbmhlcml0RG9jfQogICAgICogQHBhcmFtIHAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiAgdGhlIHJlc3VsdCBvZiB7QGNvZGUgZGVmYXVsdEFjdGlvbn0KICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgUiB2aXNpdENhdGNoKENhdGNoVHJlZSBub2RlLCBQIHApIHsKICAgICAgICByZXR1cm4gZGVmYXVsdEFjdGlvbihub2RlLCBwKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30gVGhpcyBpbXBsZW1lbnRhdGlvbiBjYWxscyB7QGNvZGUgZGVmYXVsdEFjdGlvbn0uCiAgICAgKgogICAgICogQHBhcmFtIG5vZGUge0Bpbmhlcml0RG9jfQogICAgICogQHBhcmFtIHAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiAgdGhlIHJlc3VsdCBvZiB7QGNvZGUgZGVmYXVsdEFjdGlvbn0KICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgUiB2aXNpdENvbmRpdGlvbmFsRXhwcmVzc2lvbihDb25kaXRpb25hbEV4cHJlc3Npb25UcmVlIG5vZGUsIFAgcCkgewogICAgICAgIHJldHVybiBkZWZhdWx0QWN0aW9uKG5vZGUsIHApOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIGNhbGxzIHtAY29kZSBkZWZhdWx0QWN0aW9ufS4KICAgICAqCiAgICAgKiBAcGFyYW0gbm9kZSB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuICB0aGUgcmVzdWx0IG9mIHtAY29kZSBkZWZhdWx0QWN0aW9ufQogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0SWYoSWZUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIHJldHVybiBkZWZhdWx0QWN0aW9uKG5vZGUsIHApOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIGNhbGxzIHtAY29kZSBkZWZhdWx0QWN0aW9ufS4KICAgICAqCiAgICAgKiBAcGFyYW0gbm9kZSB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuICB0aGUgcmVzdWx0IG9mIHtAY29kZSBkZWZhdWx0QWN0aW9ufQogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0RXhwcmVzc2lvblN0YXRlbWVudChFeHByZXNzaW9uU3RhdGVtZW50VHJlZSBub2RlLCBQIHApIHsKICAgICAgICByZXR1cm4gZGVmYXVsdEFjdGlvbihub2RlLCBwKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30gVGhpcyBpbXBsZW1lbnRhdGlvbiBjYWxscyB7QGNvZGUgZGVmYXVsdEFjdGlvbn0uCiAgICAgKgogICAgICogQHBhcmFtIG5vZGUge0Bpbmhlcml0RG9jfQogICAgICogQHBhcmFtIHAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiAgdGhlIHJlc3VsdCBvZiB7QGNvZGUgZGVmYXVsdEFjdGlvbn0KICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgUiB2aXNpdEJyZWFrKEJyZWFrVHJlZSBub2RlLCBQIHApIHsKICAgICAgICByZXR1cm4gZGVmYXVsdEFjdGlvbihub2RlLCBwKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30gVGhpcyBpbXBsZW1lbnRhdGlvbiBjYWxscyB7QGNvZGUgZGVmYXVsdEFjdGlvbn0uCiAgICAgKgogICAgICogQHBhcmFtIG5vZGUge0Bpbmhlcml0RG9jfQogICAgICogQHBhcmFtIHAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiAgdGhlIHJlc3VsdCBvZiB7QGNvZGUgZGVmYXVsdEFjdGlvbn0KICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgUiB2aXNpdENvbnRpbnVlKENvbnRpbnVlVHJlZSBub2RlLCBQIHApIHsKICAgICAgICByZXR1cm4gZGVmYXVsdEFjdGlvbihub2RlLCBwKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30gVGhpcyBpbXBsZW1lbnRhdGlvbiBjYWxscyB7QGNvZGUgZGVmYXVsdEFjdGlvbn0uCiAgICAgKgogICAgICogQHBhcmFtIG5vZGUge0Bpbmhlcml0RG9jfQogICAgICogQHBhcmFtIHAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiAgdGhlIHJlc3VsdCBvZiB7QGNvZGUgZGVmYXVsdEFjdGlvbn0KICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgUiB2aXNpdFJldHVybihSZXR1cm5UcmVlIG5vZGUsIFAgcCkgewogICAgICAgIHJldHVybiBkZWZhdWx0QWN0aW9uKG5vZGUsIHApOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIGNhbGxzIHtAY29kZSBkZWZhdWx0QWN0aW9ufS4KICAgICAqCiAgICAgKiBAcGFyYW0gbm9kZSB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuICB0aGUgcmVzdWx0IG9mIHtAY29kZSBkZWZhdWx0QWN0aW9ufQogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0VGhyb3coVGhyb3dUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIHJldHVybiBkZWZhdWx0QWN0aW9uKG5vZGUsIHApOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIGNhbGxzIHtAY29kZSBkZWZhdWx0QWN0aW9ufS4KICAgICAqCiAgICAgKiBAcGFyYW0gbm9kZSB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuICB0aGUgcmVzdWx0IG9mIHtAY29kZSBkZWZhdWx0QWN0aW9ufQogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0QXNzZXJ0KEFzc2VydFRyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIGRlZmF1bHRBY3Rpb24obm9kZSwgcCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gY2FsbHMge0Bjb2RlIGRlZmF1bHRBY3Rpb259LgogICAgICoKICAgICAqIEBwYXJhbSBub2RlIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gIHRoZSByZXN1bHQgb2Yge0Bjb2RlIGRlZmF1bHRBY3Rpb259CiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRNZXRob2RJbnZvY2F0aW9uKE1ldGhvZEludm9jYXRpb25UcmVlIG5vZGUsIFAgcCkgewogICAgICAgIHJldHVybiBkZWZhdWx0QWN0aW9uKG5vZGUsIHApOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIGNhbGxzIHtAY29kZSBkZWZhdWx0QWN0aW9ufS4KICAgICAqCiAgICAgKiBAcGFyYW0gbm9kZSB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuICB0aGUgcmVzdWx0IG9mIHtAY29kZSBkZWZhdWx0QWN0aW9ufQogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0TmV3Q2xhc3MoTmV3Q2xhc3NUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIHJldHVybiBkZWZhdWx0QWN0aW9uKG5vZGUsIHApOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIGNhbGxzIHtAY29kZSBkZWZhdWx0QWN0aW9ufS4KICAgICAqCiAgICAgKiBAcGFyYW0gbm9kZSB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuICB0aGUgcmVzdWx0IG9mIHtAY29kZSBkZWZhdWx0QWN0aW9ufQogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0TmV3QXJyYXkoTmV3QXJyYXlUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIHJldHVybiBkZWZhdWx0QWN0aW9uKG5vZGUsIHApOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIGNhbGxzIHtAY29kZSBkZWZhdWx0QWN0aW9ufS4KICAgICAqCiAgICAgKiBAcGFyYW0gbm9kZSB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuICB0aGUgcmVzdWx0IG9mIHtAY29kZSBkZWZhdWx0QWN0aW9ufQogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0TGFtYmRhRXhwcmVzc2lvbihMYW1iZGFFeHByZXNzaW9uVHJlZSBub2RlLCBQIHApIHsKICAgICAgICByZXR1cm4gZGVmYXVsdEFjdGlvbihub2RlLCBwKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30gVGhpcyBpbXBsZW1lbnRhdGlvbiBjYWxscyB7QGNvZGUgZGVmYXVsdEFjdGlvbn0uCiAgICAgKgogICAgICogQHBhcmFtIG5vZGUge0Bpbmhlcml0RG9jfQogICAgICogQHBhcmFtIHAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiAgdGhlIHJlc3VsdCBvZiB7QGNvZGUgZGVmYXVsdEFjdGlvbn0KICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgUiB2aXNpdFBhcmVudGhlc2l6ZWQoUGFyZW50aGVzaXplZFRyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIGRlZmF1bHRBY3Rpb24obm9kZSwgcCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gY2FsbHMge0Bjb2RlIGRlZmF1bHRBY3Rpb259LgogICAgICoKICAgICAqIEBwYXJhbSBub2RlIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gIHRoZSByZXN1bHQgb2Yge0Bjb2RlIGRlZmF1bHRBY3Rpb259CiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRBc3NpZ25tZW50KEFzc2lnbm1lbnRUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIHJldHVybiBkZWZhdWx0QWN0aW9uKG5vZGUsIHApOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIGNhbGxzIHtAY29kZSBkZWZhdWx0QWN0aW9ufS4KICAgICAqCiAgICAgKiBAcGFyYW0gbm9kZSB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuICB0aGUgcmVzdWx0IG9mIHtAY29kZSBkZWZhdWx0QWN0aW9ufQogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0Q29tcG91bmRBc3NpZ25tZW50KENvbXBvdW5kQXNzaWdubWVudFRyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIGRlZmF1bHRBY3Rpb24obm9kZSwgcCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gY2FsbHMge0Bjb2RlIGRlZmF1bHRBY3Rpb259LgogICAgICoKICAgICAqIEBwYXJhbSBub2RlIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gIHRoZSByZXN1bHQgb2Yge0Bjb2RlIGRlZmF1bHRBY3Rpb259CiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRVbmFyeShVbmFyeVRyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIGRlZmF1bHRBY3Rpb24obm9kZSwgcCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gY2FsbHMge0Bjb2RlIGRlZmF1bHRBY3Rpb259LgogICAgICoKICAgICAqIEBwYXJhbSBub2RlIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gIHRoZSByZXN1bHQgb2Yge0Bjb2RlIGRlZmF1bHRBY3Rpb259CiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRCaW5hcnkoQmluYXJ5VHJlZSBub2RlLCBQIHApIHsKICAgICAgICByZXR1cm4gZGVmYXVsdEFjdGlvbihub2RlLCBwKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30gVGhpcyBpbXBsZW1lbnRhdGlvbiBjYWxscyB7QGNvZGUgZGVmYXVsdEFjdGlvbn0uCiAgICAgKgogICAgICogQHBhcmFtIG5vZGUge0Bpbmhlcml0RG9jfQogICAgICogQHBhcmFtIHAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiAgdGhlIHJlc3VsdCBvZiB7QGNvZGUgZGVmYXVsdEFjdGlvbn0KICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgUiB2aXNpdFR5cGVDYXN0KFR5cGVDYXN0VHJlZSBub2RlLCBQIHApIHsKICAgICAgICByZXR1cm4gZGVmYXVsdEFjdGlvbihub2RlLCBwKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30gVGhpcyBpbXBsZW1lbnRhdGlvbiBjYWxscyB7QGNvZGUgZGVmYXVsdEFjdGlvbn0uCiAgICAgKgogICAgICogQHBhcmFtIG5vZGUge0Bpbmhlcml0RG9jfQogICAgICogQHBhcmFtIHAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiAgdGhlIHJlc3VsdCBvZiB7QGNvZGUgZGVmYXVsdEFjdGlvbn0KICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgUiB2aXNpdEluc3RhbmNlT2YoSW5zdGFuY2VPZlRyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIGRlZmF1bHRBY3Rpb24obm9kZSwgcCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gY2FsbHMge0Bjb2RlIGRlZmF1bHRBY3Rpb259LgogICAgICoKICAgICAqIEBwYXJhbSBub2RlIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gIHRoZSByZXN1bHQgb2Yge0Bjb2RlIGRlZmF1bHRBY3Rpb259CiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRBcnJheUFjY2VzcyhBcnJheUFjY2Vzc1RyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIGRlZmF1bHRBY3Rpb24obm9kZSwgcCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gY2FsbHMge0Bjb2RlIGRlZmF1bHRBY3Rpb259LgogICAgICoKICAgICAqIEBwYXJhbSBub2RlIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gIHRoZSByZXN1bHQgb2Yge0Bjb2RlIGRlZmF1bHRBY3Rpb259CiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRNZW1iZXJTZWxlY3QoTWVtYmVyU2VsZWN0VHJlZSBub2RlLCBQIHApIHsKICAgICAgICByZXR1cm4gZGVmYXVsdEFjdGlvbihub2RlLCBwKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30gVGhpcyBpbXBsZW1lbnRhdGlvbiBjYWxscyB7QGNvZGUgZGVmYXVsdEFjdGlvbn0uCiAgICAgKgogICAgICogQHBhcmFtIG5vZGUge0Bpbmhlcml0RG9jfQogICAgICogQHBhcmFtIHAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiAgdGhlIHJlc3VsdCBvZiB7QGNvZGUgZGVmYXVsdEFjdGlvbn0KICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgUiB2aXNpdE1lbWJlclJlZmVyZW5jZShNZW1iZXJSZWZlcmVuY2VUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIHJldHVybiBkZWZhdWx0QWN0aW9uKG5vZGUsIHApOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIGNhbGxzIHtAY29kZSBkZWZhdWx0QWN0aW9ufS4KICAgICAqCiAgICAgKiBAcGFyYW0gbm9kZSB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuICB0aGUgcmVzdWx0IG9mIHtAY29kZSBkZWZhdWx0QWN0aW9ufQogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0SWRlbnRpZmllcihJZGVudGlmaWVyVHJlZSBub2RlLCBQIHApIHsKICAgICAgICByZXR1cm4gZGVmYXVsdEFjdGlvbihub2RlLCBwKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30gVGhpcyBpbXBsZW1lbnRhdGlvbiBjYWxscyB7QGNvZGUgZGVmYXVsdEFjdGlvbn0uCiAgICAgKgogICAgICogQHBhcmFtIG5vZGUge0Bpbmhlcml0RG9jfQogICAgICogQHBhcmFtIHAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiAgdGhlIHJlc3VsdCBvZiB7QGNvZGUgZGVmYXVsdEFjdGlvbn0KICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgUiB2aXNpdExpdGVyYWwoTGl0ZXJhbFRyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIGRlZmF1bHRBY3Rpb24obm9kZSwgcCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gY2FsbHMge0Bjb2RlIGRlZmF1bHRBY3Rpb259LgogICAgICoKICAgICAqIEBwYXJhbSBub2RlIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gIHRoZSByZXN1bHQgb2Yge0Bjb2RlIGRlZmF1bHRBY3Rpb259CiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRQcmltaXRpdmVUeXBlKFByaW1pdGl2ZVR5cGVUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIHJldHVybiBkZWZhdWx0QWN0aW9uKG5vZGUsIHApOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIGNhbGxzIHtAY29kZSBkZWZhdWx0QWN0aW9ufS4KICAgICAqCiAgICAgKiBAcGFyYW0gbm9kZSB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuICB0aGUgcmVzdWx0IG9mIHtAY29kZSBkZWZhdWx0QWN0aW9ufQogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0QXJyYXlUeXBlKEFycmF5VHlwZVRyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIGRlZmF1bHRBY3Rpb24obm9kZSwgcCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gY2FsbHMge0Bjb2RlIGRlZmF1bHRBY3Rpb259LgogICAgICoKICAgICAqIEBwYXJhbSBub2RlIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gIHRoZSByZXN1bHQgb2Yge0Bjb2RlIGRlZmF1bHRBY3Rpb259CiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRQYXJhbWV0ZXJpemVkVHlwZShQYXJhbWV0ZXJpemVkVHlwZVRyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIGRlZmF1bHRBY3Rpb24obm9kZSwgcCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gY2FsbHMge0Bjb2RlIGRlZmF1bHRBY3Rpb259LgogICAgICoKICAgICAqIEBwYXJhbSBub2RlIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gIHRoZSByZXN1bHQgb2Yge0Bjb2RlIGRlZmF1bHRBY3Rpb259CiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRVbmlvblR5cGUoVW5pb25UeXBlVHJlZSBub2RlLCBQIHApIHsKICAgICAgICByZXR1cm4gZGVmYXVsdEFjdGlvbihub2RlLCBwKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30gVGhpcyBpbXBsZW1lbnRhdGlvbiBjYWxscyB7QGNvZGUgZGVmYXVsdEFjdGlvbn0uCiAgICAgKgogICAgICogQHBhcmFtIG5vZGUge0Bpbmhlcml0RG9jfQogICAgICogQHBhcmFtIHAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiAgdGhlIHJlc3VsdCBvZiB7QGNvZGUgZGVmYXVsdEFjdGlvbn0KICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgUiB2aXNpdEludGVyc2VjdGlvblR5cGUoSW50ZXJzZWN0aW9uVHlwZVRyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIGRlZmF1bHRBY3Rpb24obm9kZSwgcCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gY2FsbHMge0Bjb2RlIGRlZmF1bHRBY3Rpb259LgogICAgICoKICAgICAqIEBwYXJhbSBub2RlIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gIHRoZSByZXN1bHQgb2Yge0Bjb2RlIGRlZmF1bHRBY3Rpb259CiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRUeXBlUGFyYW1ldGVyKFR5cGVQYXJhbWV0ZXJUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIHJldHVybiBkZWZhdWx0QWN0aW9uKG5vZGUsIHApOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIGNhbGxzIHtAY29kZSBkZWZhdWx0QWN0aW9ufS4KICAgICAqCiAgICAgKiBAcGFyYW0gbm9kZSB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuICB0aGUgcmVzdWx0IG9mIHtAY29kZSBkZWZhdWx0QWN0aW9ufQogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0V2lsZGNhcmQoV2lsZGNhcmRUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIHJldHVybiBkZWZhdWx0QWN0aW9uKG5vZGUsIHApOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIGNhbGxzIHtAY29kZSBkZWZhdWx0QWN0aW9ufS4KICAgICAqCiAgICAgKiBAcGFyYW0gbm9kZSB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuICB0aGUgcmVzdWx0IG9mIHtAY29kZSBkZWZhdWx0QWN0aW9ufQogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0TW9kaWZpZXJzKE1vZGlmaWVyc1RyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIGRlZmF1bHRBY3Rpb24obm9kZSwgcCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gY2FsbHMge0Bjb2RlIGRlZmF1bHRBY3Rpb259LgogICAgICoKICAgICAqIEBwYXJhbSBub2RlIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gIHRoZSByZXN1bHQgb2Yge0Bjb2RlIGRlZmF1bHRBY3Rpb259CiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRBbm5vdGF0aW9uKEFubm90YXRpb25UcmVlIG5vZGUsIFAgcCkgewogICAgICAgIHJldHVybiBkZWZhdWx0QWN0aW9uKG5vZGUsIHApOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIGNhbGxzIHtAY29kZSBkZWZhdWx0QWN0aW9ufS4KICAgICAqCiAgICAgKiBAcGFyYW0gbm9kZSB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuICB0aGUgcmVzdWx0IG9mIHtAY29kZSBkZWZhdWx0QWN0aW9ufQogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0QW5ub3RhdGVkVHlwZShBbm5vdGF0ZWRUeXBlVHJlZSBub2RlLCBQIHApIHsKICAgICAgICByZXR1cm4gZGVmYXVsdEFjdGlvbihub2RlLCBwKTsKICAgIH0KCiAgICBwdWJsaWMgUiB2aXNpdE1vZHVsZShNb2R1bGVUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIHJldHVybiBkZWZhdWx0QWN0aW9uKG5vZGUsIHApOwogICAgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRFeHBvcnRzKEV4cG9ydHNUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIHJldHVybiBkZWZhdWx0QWN0aW9uKG5vZGUsIHApOwogICAgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRPcGVucyhPcGVuc1RyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIGRlZmF1bHRBY3Rpb24obm9kZSwgcCk7CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgUiB2aXNpdFByb3ZpZGVzKFByb3ZpZGVzVHJlZSBub2RlLCBQIHApIHsKICAgICAgICByZXR1cm4gZGVmYXVsdEFjdGlvbihub2RlLCBwKTsKICAgIH0KCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0UmVxdWlyZXMoUmVxdWlyZXNUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIHJldHVybiBkZWZhdWx0QWN0aW9uKG5vZGUsIHApOwogICAgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRVc2VzKFVzZXNUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIHJldHVybiBkZWZhdWx0QWN0aW9uKG5vZGUsIHApOwogICAgfQoKICAgIHB1YmxpYyBSIHZpc2l0RXJyb25lb3VzKEVycm9uZW91c1RyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIGRlZmF1bHRBY3Rpb24obm9kZSwgcCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gY2FsbHMge0Bjb2RlIGRlZmF1bHRBY3Rpb259LgogICAgICoKICAgICAqIEBwYXJhbSBub2RlIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gIHRoZSByZXN1bHQgb2Yge0Bjb2RlIGRlZmF1bHRBY3Rpb259CiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRPdGhlcihUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIHJldHVybiBkZWZhdWx0QWN0aW9uKG5vZGUsIHApOwogICAgfQp9ClBLAwQKAAAIAAAGO6lKH+iRV3kFAAB5BQAAJQAAAGNvbS9zdW4vc291cmNlL3V0aWwvcGFja2FnZS1pbmZvLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMTMsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCi8qKgogKiBQcm92aWRlcyB1dGlsaXRpZXMgZm9yIG9wZXJhdGlvbnMgb24gYWJzdHJhY3Qgc3ludGF4IHRyZWVzIChBU1QpLgogKgogKiBAYXV0aG9yIFBldGVyIHZvbiBkZXIgQWgmZWFjdXRlOwogKiBAYXV0aG9yIEpvbmF0aGFuIEdpYmJvbnMKICogQHNpbmNlIDEuNgogKi8KcGFja2FnZSBjb20uc3VuLnNvdXJjZS51dGlsOwpQSwMECgAACAAABjupSoknMXI4PQAAOD0AACcAAABjb20vc3VuL3NvdXJjZS91dGlsL0RvY1RyZWVTY2FubmVyLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTEsIDIwMTYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi5zb3VyY2UudXRpbDsKCmltcG9ydCBjb20uc3VuLnNvdXJjZS5kb2N0cmVlLio7CgoKLyoqCiAqIEEgVHJlZVZpc2l0b3IgdGhhdCB2aXNpdHMgYWxsIHRoZSBjaGlsZCB0cmVlIG5vZGVzLgogKiBUbyB2aXNpdCBub2RlcyBvZiBhIHBhcnRpY3VsYXIgdHlwZSwganVzdCBvdmVycmlkZSB0aGUKICogY29ycmVzcG9uZGluZyB2aXNpdFhZWiBtZXRob2QuCiAqIEluc2lkZSB5b3VyIG1ldGhvZCwgY2FsbCBzdXBlci52aXNpdFhZWiB0byB2aXNpdCBkZXNjZW5kYW50CiAqIG5vZGVzLgogKgogKiA8cD5UaGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgdmlzaXRYWVogbWV0aG9kcyB3aWxsIGRldGVybWluZQogKiBhIHJlc3VsdCBhcyBmb2xsb3dzOgogKiA8dWw+CiAqIDxsaT5JZiB0aGUgbm9kZSBiZWluZyB2aXNpdGVkIGhhcyBubyBjaGlsZHJlbiwgdGhlIHJlc3VsdCB3aWxsIGJlIHtAY29kZSBudWxsfS4KICogPGxpPklmIHRoZSBub2RlIGJlaW5nIHZpc2l0ZWQgaGFzIG9uZSBjaGlsZCwgdGhlIHJlc3VsdCB3aWxsIGJlIHRoZQogKiByZXN1bHQgb2YgY2FsbGluZyB7QGNvZGUgc2Nhbn0gb24gdGhhdCBjaGlsZC4gVGhlIGNoaWxkIG1heSBiZSBhIHNpbXBsZSBub2RlCiAqIG9yIGl0c2VsZiBhIGxpc3Qgb2Ygbm9kZXMuCiAqIDxsaT4gSWYgdGhlIG5vZGUgYmVpbmcgdmlzaXRlZCBoYXMgbW9yZSB0aGFuIG9uZSBjaGlsZCwgdGhlIHJlc3VsdCB3aWxsCiAqIGJlIGRldGVybWluZWQgYnkgY2FsbGluZyB7QGNvZGUgc2Nhbn0gZWFjaCBjaGlsZCBpbiB0dXJuLCBhbmQgdGhlbiBjb21iaW5pbmcgdGhlCiAqIHJlc3VsdCBvZiBlYWNoIHNjYW4gYWZ0ZXIgdGhlIGZpcnN0IHdpdGggdGhlIGN1bXVsYXRpdmUgcmVzdWx0CiAqIHNvIGZhciwgYXMgZGV0ZXJtaW5lZCBieSB0aGUge0BsaW5rICNyZWR1Y2V9IG1ldGhvZC4gRWFjaCBjaGlsZCBtYXkgYmUgZWl0aGVyCiAqIGEgc2ltcGxlIG5vZGUgb2YgYSBsaXN0IG9mIG5vZGVzLiBUaGUgZGVmYXVsdCBiZWhhdmlvciBvZiB0aGUge0Bjb2RlIHJlZHVjZX0KICogbWV0aG9kIGlzIHN1Y2ggdGhhdCB0aGUgcmVzdWx0IG9mIHRoZSB2aXNpdFhZWiBtZXRob2Qgd2lsbCBiZSB0aGUgcmVzdWx0IG9mCiAqIHRoZSBsYXN0IGNoaWxkIHNjYW5uZWQuCiAqIDwvdWw+CiAqCiAqIDxwPkhlcmUgaXMgYW4gZXhhbXBsZSB0byBjb3VudCB0aGUgbnVtYmVyIG9mIGVycm9uZW91cyBub2RlcyBpbiBhIHRyZWU6CiAqIDxwcmU+CiAqICAgY2xhc3MgQ291bnRFcnJvcnMgZXh0ZW5kcyBEb2NUcmVlU2Nhbm5lciZsdDtJbnRlZ2VyLFZvaWQmZ3Q7IHsKICogICAgICB7QGxpdGVyYWwgQH1PdmVycmlkZQogKiAgICAgIHB1YmxpYyBJbnRlZ2VyIHZpc2l0RXJyb25lb3VzKEVycm9uZW91c1RyZWUgbm9kZSwgVm9pZCBwKSB7CiAqICAgICAgICAgIHJldHVybiAxOwogKiAgICAgIH0KICogICAgICB7QGxpdGVyYWwgQH1PdmVycmlkZQogKiAgICAgIHB1YmxpYyBJbnRlZ2VyIHJlZHVjZShJbnRlZ2VyIHIxLCBJbnRlZ2VyIHIyKSB7CiAqICAgICAgICAgIHJldHVybiAocjEgPT0gbnVsbCA/IDAgOiByMSkgKyAocjIgPT0gbnVsbCA/IDAgOiByMik7CiAqICAgICAgfQogKiAgIH0KICogPC9wcmU+CiAqCiAqIEBzaW5jZSAxLjgKICovCnB1YmxpYyBjbGFzcyBEb2NUcmVlU2Nhbm5lcjxSLFA+IGltcGxlbWVudHMgRG9jVHJlZVZpc2l0b3I8UixQPiB7CgogICAgLyoqCiAgICAgKiBTY2FucyBhIHNpbmdsZSBub2RlLgogICAgICogQHBhcmFtIG5vZGUgdGhlIG5vZGUgdG8gYmUgc2Nhbm5lZAogICAgICogQHBhcmFtIHAgYSBwYXJhbWV0ZXIgdmFsdWUgcGFzc2VkIHRvIHRoZSB2aXNpdCBtZXRob2QKICAgICAqIEByZXR1cm4gdGhlIHJlc3VsdCB2YWx1ZSBmcm9tIHRoZSB2aXNpdCBtZXRob2QKICAgICAqLwogICAgcHVibGljIFIgc2NhbihEb2NUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIHJldHVybiAobm9kZSA9PSBudWxsKSA/IG51bGwgOiBub2RlLmFjY2VwdCh0aGlzLCBwKTsKICAgIH0KCiAgICBwcml2YXRlIFIgc2NhbkFuZFJlZHVjZShEb2NUcmVlIG5vZGUsIFAgcCwgUiByKSB7CiAgICAgICAgcmV0dXJuIHJlZHVjZShzY2FuKG5vZGUsIHApLCByKTsKICAgIH0KCiAgICAvKioKICAgICAqIFNjYW5zIGEgc2VxdWVuY2Ugb2Ygbm9kZXMuCiAgICAgKiBAcGFyYW0gbm9kZXMgdGhlIG5vZGVzIHRvIGJlIHNjYW5uZWQKICAgICAqIEBwYXJhbSBwIGEgcGFyYW1ldGVyIHZhbHVlIHRvIGJlIHBhc3NlZCB0byB0aGUgdmlzaXQgbWV0aG9kIGZvciBlYWNoIG5vZGUKICAgICAqIEByZXR1cm4gdGhlIGNvbWJpbmVkIHJldHVybiB2YWx1ZSBmcm9tIHRoZSB2aXNpdCBtZXRob2RzLgogICAgICogICAgICBUaGUgdmFsdWVzIGFyZSBjb21iaW5lZCB1c2luZyB0aGUge0BsaW5rICNyZWR1Y2UgcmVkdWNlfSBtZXRob2QuCiAgICAgKi8KICAgIHB1YmxpYyBSIHNjYW4oSXRlcmFibGU8PyBleHRlbmRzIERvY1RyZWU+IG5vZGVzLCBQIHApIHsKICAgICAgICBSIHIgPSBudWxsOwogICAgICAgIGlmIChub2RlcyAhPSBudWxsKSB7CiAgICAgICAgICAgIGJvb2xlYW4gZmlyc3QgPSB0cnVlOwogICAgICAgICAgICBmb3IgKERvY1RyZWUgbm9kZSA6IG5vZGVzKSB7CiAgICAgICAgICAgICAgICByID0gKGZpcnN0ID8gc2Nhbihub2RlLCBwKSA6IHNjYW5BbmRSZWR1Y2Uobm9kZSwgcCwgcikpOwogICAgICAgICAgICAgICAgZmlyc3QgPSBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gcjsKICAgIH0KCiAgICBwcml2YXRlIFIgc2NhbkFuZFJlZHVjZShJdGVyYWJsZTw/IGV4dGVuZHMgRG9jVHJlZT4gbm9kZXMsIFAgcCwgUiByKSB7CiAgICAgICAgcmV0dXJuIHJlZHVjZShzY2FuKG5vZGVzLCBwKSwgcik7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZWR1Y2VzIHR3byByZXN1bHRzIGludG8gYSBjb21iaW5lZCByZXN1bHQuCiAgICAgKiBUaGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBpcyB0byByZXR1cm4gdGhlIGZpcnN0IHBhcmFtZXRlci4KICAgICAqIFRoZSBnZW5lcmFsIGNvbnRyYWN0IG9mIHRoZSBtZXRob2QgaXMgdGhhdCBpdCBtYXkgdGFrZSBhbnkgYWN0aW9uIHdoYXRzb2V2ZXIuCiAgICAgKiBAcGFyYW0gcjEgdGhlIGZpcnN0IG9mIHRoZSB2YWx1ZXMgdG8gYmUgY29tYmluZWQKICAgICAqIEBwYXJhbSByMiB0aGUgc2Vjb25kIG9mIHRoZSB2YWx1ZXMgdG8gYmUgY29tYmluZWQKICAgICAqIEByZXR1cm4gdGhlIHJlc3VsdCBvZiBjb21iaW5pbmcgdGhlIHR3byBwYXJhbWV0ZXJzCiAgICAgKi8KICAgIHB1YmxpYyBSIHJlZHVjZShSIHIxLCBSIHIyKSB7CiAgICAgICAgcmV0dXJuIHIxOwogICAgfQoKCi8qICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBWaXNpdG9yIG1ldGhvZHMKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gcmV0dXJucyB7QGNvZGUgbnVsbH0uCiAgICAgKgogICAgICogQHBhcmFtIG5vZGUgIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwICB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuIHRoZSByZXN1bHQgb2Ygc2Nhbm5pbmcKICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgUiB2aXNpdEF0dHJpYnV0ZShBdHRyaWJ1dGVUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIHNjYW5zIHRoZSBjaGlsZHJlbiBpbiBsZWZ0IHRvIHJpZ2h0IG9yZGVyLgogICAgICoKICAgICAqIEBwYXJhbSBub2RlICB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiB0aGUgcmVzdWx0IG9mIHNjYW5uaW5nCiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRBdXRob3IoQXV0aG9yVHJlZSBub2RlLCBQIHApIHsKICAgICAgICByZXR1cm4gc2Nhbihub2RlLmdldE5hbWUoKSwgcCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gcmV0dXJucyB7QGNvZGUgbnVsbH0uCiAgICAgKgogICAgICogQHBhcmFtIG5vZGUgIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwICB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuIHRoZSByZXN1bHQgb2Ygc2Nhbm5pbmcKICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgUiB2aXNpdENvbW1lbnQoQ29tbWVudFRyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gc2NhbnMgdGhlIGNoaWxkcmVuIGluIGxlZnQgdG8gcmlnaHQgb3JkZXIuCiAgICAgKgogICAgICogQHBhcmFtIG5vZGUgIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwICB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuIHRoZSByZXN1bHQgb2Ygc2Nhbm5pbmcKICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgUiB2aXNpdERlcHJlY2F0ZWQoRGVwcmVjYXRlZFRyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIHNjYW4obm9kZS5nZXRCb2R5KCksIHApOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIHNjYW5zIHRoZSBjaGlsZHJlbiBpbiBsZWZ0IHRvIHJpZ2h0IG9yZGVyLgogICAgICoKICAgICAqIEBwYXJhbSBub2RlICB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiB0aGUgcmVzdWx0IG9mIHNjYW5uaW5nCiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXREb2NDb21tZW50KERvY0NvbW1lbnRUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIFIgciA9IHNjYW4obm9kZS5nZXRGaXJzdFNlbnRlbmNlKCksIHApOwogICAgICAgIHIgPSBzY2FuQW5kUmVkdWNlKG5vZGUuZ2V0Qm9keSgpLCBwLCByKTsKICAgICAgICByID0gc2NhbkFuZFJlZHVjZShub2RlLmdldEJsb2NrVGFncygpLCBwLCByKTsKICAgICAgICByZXR1cm4gcjsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30gVGhpcyBpbXBsZW1lbnRhdGlvbiByZXR1cm5zIHtAY29kZSBudWxsfS4KICAgICAqCiAgICAgKiBAcGFyYW0gbm9kZSAge0Bpbmhlcml0RG9jfQogICAgICogQHBhcmFtIHAgIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gdGhlIHJlc3VsdCBvZiBzY2FubmluZwogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0RG9jUm9vdChEb2NSb290VHJlZSBub2RlLCBQIHApIHsKICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30gVGhpcyBpbXBsZW1lbnRhdGlvbiByZXR1cm5zIHtAY29kZSBudWxsfS4KICAgICAqCiAgICAgKiBAcGFyYW0gbm9kZSAge0Bpbmhlcml0RG9jfQogICAgICogQHBhcmFtIHAgIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gdGhlIHJlc3VsdCBvZiBzY2FubmluZwogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0RW5kRWxlbWVudChFbmRFbGVtZW50VHJlZSBub2RlLCBQIHApIHsKICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30gVGhpcyBpbXBsZW1lbnRhdGlvbiByZXR1cm5zIHtAY29kZSBudWxsfS4KICAgICAqCiAgICAgKiBAcGFyYW0gbm9kZSAge0Bpbmhlcml0RG9jfQogICAgICogQHBhcmFtIHAgIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gdGhlIHJlc3VsdCBvZiBzY2FubmluZwogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0RW50aXR5KEVudGl0eVRyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gcmV0dXJucyB7QGNvZGUgbnVsbH0uCiAgICAgKgogICAgICogQHBhcmFtIG5vZGUgIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwICB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuIHRoZSByZXN1bHQgb2Ygc2Nhbm5pbmcKICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgUiB2aXNpdEVycm9uZW91cyhFcnJvbmVvdXNUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIHNjYW5zIHRoZSBjaGlsZHJlbiBpbiBsZWZ0IHRvIHJpZ2h0IG9yZGVyLgogICAgICoKICAgICAqIEBwYXJhbSBub2RlICB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiB0aGUgcmVzdWx0IG9mIHNjYW5uaW5nCiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRIaWRkZW4oSGlkZGVuVHJlZSBub2RlLCBQIHApIHsKICAgICAgICByZXR1cm4gc2Nhbihub2RlLmdldEJvZHkoKSwgcCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gcmV0dXJucyB7QGNvZGUgbnVsbH0uCiAgICAgKgogICAgICogQHBhcmFtIG5vZGUgIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwICB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuIHRoZSByZXN1bHQgb2Ygc2Nhbm5pbmcKICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgUiB2aXNpdElkZW50aWZpZXIoSWRlbnRpZmllclRyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gcmV0dXJucyB7QGNvZGUgbnVsbH0uCiAgICAgKgogICAgICogQHBhcmFtIG5vZGUgIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwICB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuIHRoZSByZXN1bHQgb2Ygc2Nhbm5pbmcKICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgUiB2aXNpdEluZGV4KEluZGV4VHJlZSBub2RlLCBQIHApIHsKICAgICAgICBSIHIgPSBzY2FuKG5vZGUuZ2V0U2VhcmNoVGVybSgpLCBwKTsKICAgICAgICByID0gc2NhbkFuZFJlZHVjZShub2RlLmdldERlc2NyaXB0aW9uKCksIHAsIHIpOwogICAgICAgIHJldHVybiByOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIHJldHVybnMge0Bjb2RlIG51bGx9LgogICAgICoKICAgICAqIEBwYXJhbSBub2RlICB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiB0aGUgcmVzdWx0IG9mIHNjYW5uaW5nCiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRJbmhlcml0RG9jKEluaGVyaXREb2NUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIHNjYW5zIHRoZSBjaGlsZHJlbiBpbiBsZWZ0IHRvIHJpZ2h0IG9yZGVyLgogICAgICoKICAgICAqIEBwYXJhbSBub2RlICB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiB0aGUgcmVzdWx0IG9mIHNjYW5uaW5nCiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRMaW5rKExpbmtUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIFIgciA9IHNjYW4obm9kZS5nZXRSZWZlcmVuY2UoKSwgcCk7CiAgICAgICAgciA9IHNjYW5BbmRSZWR1Y2Uobm9kZS5nZXRMYWJlbCgpLCBwLCByKTsKICAgICAgICByZXR1cm4gcjsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30gVGhpcyBpbXBsZW1lbnRhdGlvbiByZXR1cm5zIHtAY29kZSBudWxsfS4KICAgICAqCiAgICAgKiBAcGFyYW0gbm9kZSAge0Bpbmhlcml0RG9jfQogICAgICogQHBhcmFtIHAgIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gdGhlIHJlc3VsdCBvZiBzY2FubmluZwogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0TGl0ZXJhbChMaXRlcmFsVHJlZSBub2RlLCBQIHApIHsKICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30gVGhpcyBpbXBsZW1lbnRhdGlvbiBzY2FucyB0aGUgY2hpbGRyZW4gaW4gbGVmdCB0byByaWdodCBvcmRlci4KICAgICAqCiAgICAgKiBAcGFyYW0gbm9kZSAge0Bpbmhlcml0RG9jfQogICAgICogQHBhcmFtIHAgIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gdGhlIHJlc3VsdCBvZiBzY2FubmluZwogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0UGFyYW0oUGFyYW1UcmVlIG5vZGUsIFAgcCkgewogICAgICAgIFIgciA9IHNjYW4obm9kZS5nZXROYW1lKCksIHApOwogICAgICAgIHIgPSBzY2FuQW5kUmVkdWNlKG5vZGUuZ2V0RGVzY3JpcHRpb24oKSwgcCwgcik7CiAgICAgICAgcmV0dXJuIHI7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gc2NhbnMgdGhlIGNoaWxkcmVuIGluIGxlZnQgdG8gcmlnaHQgb3JkZXIuCiAgICAgKgogICAgICogQHBhcmFtIG5vZGUgIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwICB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuIHRoZSByZXN1bHQgb2Ygc2Nhbm5pbmcKICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgUiB2aXNpdFByb3ZpZGVzKFByb3ZpZGVzVHJlZSBub2RlLCBQIHApIHsKICAgICAgICBSIHIgPSBzY2FuKG5vZGUuZ2V0U2VydmljZVR5cGUoKSwgcCk7CiAgICAgICAgciA9IHNjYW5BbmRSZWR1Y2Uobm9kZS5nZXREZXNjcmlwdGlvbigpLCBwLCByKTsKICAgICAgICByZXR1cm4gcjsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30gVGhpcyBpbXBsZW1lbnRhdGlvbiByZXR1cm5zIHtAY29kZSBudWxsfS4KICAgICAqCiAgICAgKiBAcGFyYW0gbm9kZSAge0Bpbmhlcml0RG9jfQogICAgICogQHBhcmFtIHAgIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gdGhlIHJlc3VsdCBvZiBzY2FubmluZwogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0UmVmZXJlbmNlKFJlZmVyZW5jZVRyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gc2NhbnMgdGhlIGNoaWxkcmVuIGluIGxlZnQgdG8gcmlnaHQgb3JkZXIuCiAgICAgKgogICAgICogQHBhcmFtIG5vZGUgIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwICB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuIHRoZSByZXN1bHQgb2Ygc2Nhbm5pbmcKICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgUiB2aXNpdFJldHVybihSZXR1cm5UcmVlIG5vZGUsIFAgcCkgewogICAgICAgIHJldHVybiBzY2FuKG5vZGUuZ2V0RGVzY3JpcHRpb24oKSwgcCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gc2NhbnMgdGhlIGNoaWxkcmVuIGluIGxlZnQgdG8gcmlnaHQgb3JkZXIuCiAgICAgKgogICAgICogQHBhcmFtIG5vZGUgIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwICB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuIHRoZSByZXN1bHQgb2Ygc2Nhbm5pbmcKICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgUiB2aXNpdFNlZShTZWVUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIHJldHVybiBzY2FuKG5vZGUuZ2V0UmVmZXJlbmNlKCksIHApOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIHNjYW5zIHRoZSBjaGlsZHJlbiBpbiBsZWZ0IHRvIHJpZ2h0IG9yZGVyLgogICAgICoKICAgICAqIEBwYXJhbSBub2RlICB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiB0aGUgcmVzdWx0IG9mIHNjYW5uaW5nCiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRTZXJpYWwoU2VyaWFsVHJlZSBub2RlLCBQIHApIHsKICAgICAgICByZXR1cm4gc2Nhbihub2RlLmdldERlc2NyaXB0aW9uKCksIHApOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIHNjYW5zIHRoZSBjaGlsZHJlbiBpbiBsZWZ0IHRvIHJpZ2h0IG9yZGVyLgogICAgICoKICAgICAqIEBwYXJhbSBub2RlICB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiB0aGUgcmVzdWx0IG9mIHNjYW5uaW5nCiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRTZXJpYWxEYXRhKFNlcmlhbERhdGFUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIHJldHVybiBzY2FuKG5vZGUuZ2V0RGVzY3JpcHRpb24oKSwgcCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gc2NhbnMgdGhlIGNoaWxkcmVuIGluIGxlZnQgdG8gcmlnaHQgb3JkZXIuCiAgICAgKgogICAgICogQHBhcmFtIG5vZGUgIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwICB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuIHRoZSByZXN1bHQgb2Ygc2Nhbm5pbmcKICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgUiB2aXNpdFNlcmlhbEZpZWxkKFNlcmlhbEZpZWxkVHJlZSBub2RlLCBQIHApIHsKICAgICAgICBSIHIgPSBzY2FuKG5vZGUuZ2V0TmFtZSgpLCBwKTsKICAgICAgICByID0gc2NhbkFuZFJlZHVjZShub2RlLmdldFR5cGUoKSwgcCwgcik7CiAgICAgICAgciA9IHNjYW5BbmRSZWR1Y2Uobm9kZS5nZXREZXNjcmlwdGlvbigpLCBwLCByKTsKICAgICAgICByZXR1cm4gcjsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30gVGhpcyBpbXBsZW1lbnRhdGlvbiBzY2FucyB0aGUgY2hpbGRyZW4gaW4gbGVmdCB0byByaWdodCBvcmRlci4KICAgICAqCiAgICAgKiBAcGFyYW0gbm9kZSAge0Bpbmhlcml0RG9jfQogICAgICogQHBhcmFtIHAgIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gdGhlIHJlc3VsdCBvZiBzY2FubmluZwogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0U2luY2UoU2luY2VUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIHJldHVybiBzY2FuKG5vZGUuZ2V0Qm9keSgpLCBwKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30gVGhpcyBpbXBsZW1lbnRhdGlvbiBzY2FucyB0aGUgY2hpbGRyZW4gaW4gbGVmdCB0byByaWdodCBvcmRlci4KICAgICAqCiAgICAgKiBAcGFyYW0gbm9kZSAge0Bpbmhlcml0RG9jfQogICAgICogQHBhcmFtIHAgIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gdGhlIHJlc3VsdCBvZiBzY2FubmluZwogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0U3RhcnRFbGVtZW50KFN0YXJ0RWxlbWVudFRyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIHNjYW4obm9kZS5nZXRBdHRyaWJ1dGVzKCksIHApOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIHJldHVybnMge0Bjb2RlIG51bGx9LgogICAgICoKICAgICAqIEBwYXJhbSBub2RlICB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiB0aGUgcmVzdWx0IG9mIHNjYW5uaW5nCiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRUZXh0KFRleHRUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIHNjYW5zIHRoZSBjaGlsZHJlbiBpbiBsZWZ0IHRvIHJpZ2h0IG9yZGVyLgogICAgICoKICAgICAqIEBwYXJhbSBub2RlICB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiB0aGUgcmVzdWx0IG9mIHNjYW5uaW5nCiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRUaHJvd3MoVGhyb3dzVHJlZSBub2RlLCBQIHApIHsKICAgICAgICBSIHIgPSBzY2FuKG5vZGUuZ2V0RXhjZXB0aW9uTmFtZSgpLCBwKTsKICAgICAgICByID0gc2NhbkFuZFJlZHVjZShub2RlLmdldERlc2NyaXB0aW9uKCksIHAsIHIpOwogICAgICAgIHJldHVybiByOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIHNjYW5zIHRoZSBjaGlsZHJlbiBpbiBsZWZ0IHRvIHJpZ2h0IG9yZGVyLgogICAgICoKICAgICAqIEBwYXJhbSBub2RlICB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiB0aGUgcmVzdWx0IG9mIHNjYW5uaW5nCiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRVbmtub3duQmxvY2tUYWcoVW5rbm93bkJsb2NrVGFnVHJlZSBub2RlLCBQIHApIHsKICAgICAgICByZXR1cm4gc2Nhbihub2RlLmdldENvbnRlbnQoKSwgcCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gc2NhbnMgdGhlIGNoaWxkcmVuIGluIGxlZnQgdG8gcmlnaHQgb3JkZXIuCiAgICAgKgogICAgICogQHBhcmFtIG5vZGUgIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwICB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuIHRoZSByZXN1bHQgb2Ygc2Nhbm5pbmcKICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgUiB2aXNpdFVua25vd25JbmxpbmVUYWcoVW5rbm93bklubGluZVRhZ1RyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIHNjYW4obm9kZS5nZXRDb250ZW50KCksIHApOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIHNjYW5zIHRoZSBjaGlsZHJlbiBpbiBsZWZ0IHRvIHJpZ2h0IG9yZGVyLgogICAgICoKICAgICAqIEBwYXJhbSBub2RlICB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiB0aGUgcmVzdWx0IG9mIHNjYW5uaW5nCiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRVc2VzKFVzZXNUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIFIgciA9IHNjYW4obm9kZS5nZXRTZXJ2aWNlVHlwZSgpLCBwKTsKICAgICAgICByID0gc2NhbkFuZFJlZHVjZShub2RlLmdldERlc2NyaXB0aW9uKCksIHAsIHIpOwogICAgICAgIHJldHVybiByOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIHNjYW5zIHRoZSBjaGlsZHJlbiBpbiBsZWZ0IHRvIHJpZ2h0IG9yZGVyLgogICAgICoKICAgICAqIEBwYXJhbSBub2RlICB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiB0aGUgcmVzdWx0IG9mIHNjYW5uaW5nCiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRWYWx1ZShWYWx1ZVRyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIHNjYW4obm9kZS5nZXRSZWZlcmVuY2UoKSwgcCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gc2NhbnMgdGhlIGNoaWxkcmVuIGluIGxlZnQgdG8gcmlnaHQgb3JkZXIuCiAgICAgKgogICAgICogQHBhcmFtIG5vZGUgIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwICB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuIHRoZSByZXN1bHQgb2Ygc2Nhbm5pbmcKICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgUiB2aXNpdFZlcnNpb24oVmVyc2lvblRyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIHNjYW4obm9kZS5nZXRCb2R5KCksIHApOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIHJldHVybnMge0Bjb2RlIG51bGx9LgogICAgICoKICAgICAqIEBwYXJhbSBub2RlICB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiB0aGUgcmVzdWx0IG9mIHNjYW5uaW5nCiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRPdGhlcihEb2NUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKfQpQSwMECgAACAAABjupSjI0EvJvDQAAbw0AACgAAABjb20vc3VuL3NvdXJjZS91dGlsL1NvdXJjZVBvc2l0aW9ucy5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDA1LCAyMDE0LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4uc291cmNlLnV0aWw7CgppbXBvcnQgY29tLnN1bi5zb3VyY2UudHJlZS4qOwoKLyoqCiAqIFByb3ZpZGVzIG1ldGhvZHMgdG8gb2J0YWluIHRoZSBwb3NpdGlvbiBvZiBhIFRyZWUgd2l0aGluIGEgQ29tcGlsYXRpb25Vbml0LgogKiBBIHBvc2l0aW9uIGlzIGRlZmluZWQgYXMgYSBzaW1wbGUgY2hhcmFjdGVyIG9mZnNldCBmcm9tIHRoZSBzdGFydCBvZiBhCiAqIENvbXBpbGF0aW9uVW5pdCB3aGVyZSB0aGUgZmlyc3QgY2hhcmFjdGVyIGlzIGF0IG9mZnNldCAwLgogKgogKiBAYXV0aG9yIFBldGVyIHZvbiBkZXIgQWgmZWFjdXRlOwogKiBAc2luY2UgMS42CiAqLwpwdWJsaWMgaW50ZXJmYWNlIFNvdXJjZVBvc2l0aW9ucyB7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBzdGFydGluZyBwb3NpdGlvbiBvZiB0cmVlIHdpdGhpbiBmaWxlLiAgSWYgdHJlZSBpcyBub3QgZm91bmQgd2l0aGluCiAgICAgKiBmaWxlLCBvciBpZiB0aGUgc3RhcnRpbmcgcG9zaXRpb24gaXMgbm90IGF2YWlsYWJsZSwKICAgICAqIHJldHVybiB7QGxpbmsgamF2YXgudG9vbHMuRGlhZ25vc3RpYyNOT1BPU30uCiAgICAgKiBUaGUgcmV0dXJuZWQgcG9zaXRpb24gbXVzdCBiZSBhdCB0aGUgc3RhcnQgb2YgdGhlIHlpZWxkIG9mIHRoaXMgdHJlZSwgdGhhdAogICAgICogaXMgZm9yIGFueSBzdWItdHJlZSBvZiB0aGlzIHRyZWUsIHRoZSBmb2xsb3dpbmcgbXVzdCBob2xkOgogICAgICoKICAgICAqIDxwPgogICAgICoge0Bjb2RlIHRyZWUuZ2V0U3RhcnRQb3NpdGlvbigpIDw9IHN1YnRyZWUuZ2V0U3RhcnRQb3NpdGlvbigpfSBvciA8YnI+CiAgICAgKiB7QGNvZGUgdHJlZS5nZXRTdGFydFBvc2l0aW9uKCkgPT0gTk9QT1N9IG9yIDxicj4KICAgICAqIHtAY29kZSBzdWJ0cmVlLmdldFN0YXJ0UG9zaXRpb24oKSA9PSBOT1BPU30KICAgICAqIDwvcD4KICAgICAqCiAgICAgKiBAcGFyYW0gZmlsZSBDb21waWxhdGlvblVuaXQgaW4gd2hpY2ggdG8gZmluZCB0cmVlLgogICAgICogQHBhcmFtIHRyZWUgdHJlZSBmb3Igd2hpY2ggYSBwb3NpdGlvbiBpcyBzb3VnaHQuCiAgICAgKiBAcmV0dXJuIHRoZSBzdGFydCBwb3NpdGlvbiBvZiB0cmVlLgogICAgICovCiAgICAgbG9uZyBnZXRTdGFydFBvc2l0aW9uKENvbXBpbGF0aW9uVW5pdFRyZWUgZmlsZSwgVHJlZSB0cmVlKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGVuZGluZyBwb3NpdGlvbiBvZiB0cmVlIHdpdGhpbiBmaWxlLiAgSWYgdHJlZSBpcyBub3QgZm91bmQgd2l0aGluCiAgICAgKiBmaWxlLCBvciBpZiB0aGUgZW5kaW5nIHBvc2l0aW9uIGlzIG5vdCBhdmFpbGFibGUsCiAgICAgKiByZXR1cm4ge0BsaW5rIGphdmF4LnRvb2xzLkRpYWdub3N0aWMjTk9QT1N9LgogICAgICogVGhlIHJldHVybmVkIHBvc2l0aW9uIG11c3QgYmUgYXQgdGhlIGVuZCBvZiB0aGUgeWllbGQgb2YgdGhpcyB0cmVlLAogICAgICogdGhhdCBpcyBmb3IgYW55IHN1Yi10cmVlIG9mIHRoaXMgdHJlZSwgdGhlIGZvbGxvd2luZyBtdXN0IGhvbGQ6CiAgICAgKgogICAgICogPHA+CiAgICAgKiB7QGNvZGUgdHJlZS5nZXRFbmRQb3NpdGlvbigpID49IHN1YnRyZWUuZ2V0RW5kUG9zaXRpb24oKX0gb3IgPGJyPgogICAgICoge0Bjb2RlIHRyZWUuZ2V0RW5kUG9zaXRpb24oKSA9PSBOT1BPU30gb3IgPGJyPgogICAgICoge0Bjb2RlIHN1YnRyZWUuZ2V0RW5kUG9zaXRpb24oKSA9PSBOT1BPU30KICAgICAqIDwvcD4KICAgICAqCiAgICAgKiBJbiBhZGRpdGlvbiwgdGhlIGZvbGxvd2luZyBtdXN0IGhvbGQ6CiAgICAgKgogICAgICogPHA+CiAgICAgKiB7QGNvZGUgdHJlZS5nZXRTdGFydFBvc2l0aW9uKCkgPD0gdHJlZS5nZXRFbmRQb3NpdGlvbigpfSAgb3IgPGJyPgogICAgICoge0Bjb2RlIHRyZWUuZ2V0U3RhcnRQb3NpdGlvbigpID09IE5PUE9TfSBvciA8YnI+CiAgICAgKiB7QGNvZGUgdHJlZS5nZXRFbmRQb3NpdGlvbigpID09IE5PUE9TfQogICAgICogPC9wPgogICAgICoKICAgICAqIEBwYXJhbSBmaWxlIENvbXBpbGF0aW9uVW5pdCBpbiB3aGljaCB0byBmaW5kIHRyZWUuCiAgICAgKiBAcGFyYW0gdHJlZSB0cmVlIGZvciB3aGljaCBhIHBvc2l0aW9uIGlzIHNvdWdodC4KICAgICAqIEByZXR1cm4gdGhlIGVuZCBwb3NpdGlvbiBvZiB0cmVlLgogICAgICovCiAgICAgbG9uZyBnZXRFbmRQb3NpdGlvbihDb21waWxhdGlvblVuaXRUcmVlIGZpbGUsIFRyZWUgdHJlZSk7Cgp9ClBLAwQKAAAIAAAGO6lKXoax2TUHAAA1BwAAJQAAAGNvbS9zdW4vc291cmNlL3V0aWwvVGFza0xpc3RlbmVyLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMTQsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi5zb3VyY2UudXRpbDsKCgovKioKICogUHJvdmlkZXMgYSBsaXN0ZW5lciB0byBtb25pdG9yIHRoZSBhY3Rpdml0eSBvZiB0aGUgSkRLIEphdmEgQ29tcGlsZXIsIGphdmFjLgogKgogKiBAYXV0aG9yIEpvbmF0aGFuIEdpYmJvbnMKICogQHNpbmNlIDEuNgogKi8KcHVibGljIGludGVyZmFjZSBUYXNrTGlzdGVuZXIKewogICAgLyoqCiAgICAgKiBJbnZva2VkIHdoZW4gYW4gZXZlbnQgaGFzIGJlZ3VuLgogICAgICoKICAgICAqIEBpbXBsU3BlYyBUaGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGlzIG1ldGhvZCBkb2VzIG5vdGhpbmcuCiAgICAgKgogICAgICogQHBhcmFtIGUgdGhlIGV2ZW50CiAgICAgKi8KICAgIGRlZmF1bHQgdm9pZCBzdGFydGVkKFRhc2tFdmVudCBlKSB7IH0KCiAgICAvKioKICAgICAqIEludm9rZWQgd2hlbiBhbiBldmVudCBoYXMgYmVlbiBjb21wbGV0ZWQuCiAgICAgKgogICAgICogQGltcGxTcGVjIFRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIG9mIHRoaXMgbWV0aG9kIGRvZXMgbm90aGluZy4KICAgICAqCiAgICAgKiBAcGFyYW0gZSB0aGUgZXZlbnQKICAgICAqLwogICAgZGVmYXVsdCB2b2lkIGZpbmlzaGVkKFRhc2tFdmVudCBlKSB7IH0KfQpQSwMECgAACAAABjupSmvUNSoWEQAAFhEAACsAAABjb20vc3VuL3NvdXJjZS91dGlsL0RvY1NvdXJjZVBvc2l0aW9ucy5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDEzLCAyMDE0LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4uc291cmNlLnV0aWw7CgppbXBvcnQgY29tLnN1bi5zb3VyY2UuZG9jdHJlZS5Eb2NDb21tZW50VHJlZTsKaW1wb3J0IGNvbS5zdW4uc291cmNlLmRvY3RyZWUuRG9jVHJlZTsKaW1wb3J0IGNvbS5zdW4uc291cmNlLnRyZWUuQ29tcGlsYXRpb25Vbml0VHJlZTsKCi8qKgogKiBQcm92aWRlcyBtZXRob2RzIHRvIG9idGFpbiB0aGUgcG9zaXRpb24gb2YgYSBEb2NUcmVlIHdpdGhpbiBhIGphdmFkb2MgY29tbWVudC4KICogQSBwb3NpdGlvbiBpcyBkZWZpbmVkIGFzIGEgc2ltcGxlIGNoYXJhY3RlciBvZmZzZXQgZnJvbSB0aGUgc3RhcnQgb2YgYQogKiBDb21waWxhdGlvblVuaXQgd2hlcmUgdGhlIGZpcnN0IGNoYXJhY3RlciBpcyBhdCBvZmZzZXQgMC4KICoKICogQHNpbmNlIDEuOAogKi8KcHVibGljIGludGVyZmFjZSBEb2NTb3VyY2VQb3NpdGlvbnMgZXh0ZW5kcyBTb3VyY2VQb3NpdGlvbnMgewoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgc3RhcnRpbmcgcG9zaXRpb24gb2YgdGhlIHRyZWUgd2l0aGluIHRoZSBjb21tZW50IHdpdGhpbiB0aGUgZmlsZS4gIElmIHRyZWUgaXMgbm90IGZvdW5kIHdpdGhpbgogICAgICogZmlsZSwgb3IgaWYgdGhlIHN0YXJ0aW5nIHBvc2l0aW9uIGlzIG5vdCBhdmFpbGFibGUsCiAgICAgKiByZXR1cm4ge0BsaW5rIGphdmF4LnRvb2xzLkRpYWdub3N0aWMjTk9QT1N9LgogICAgICogVGhlIGdpdmVuIHRyZWUgc2hvdWxkIGJlIHVuZGVyIHRoZSBnaXZlbiBjb21tZW50IHRyZWUsIGFuZCB0aGUgZ2l2ZW4gZG9jdW1lbnRhdGlvbgogICAgICogY29tbWVudCB0cmVlIHNob3VsZCBiZSByZXR1cm5lZCBmcm9tIGEge0BsaW5rIERvY1RyZWVzI2dldERvY0NvbW1lbnRUcmVlKGNvbS5zdW4uc291cmNlLnV0aWwuVHJlZVBhdGgpIH0KICAgICAqIGZvciBhIHRyZWUgdW5kZXIgdGhlIGdpdmVuIGZpbGUuCiAgICAgKiBUaGUgcmV0dXJuZWQgcG9zaXRpb24gbXVzdCBiZSBhdCB0aGUgc3RhcnQgb2YgdGhlIHlpZWxkIG9mIHRoaXMgdHJlZSwgdGhhdAogICAgICogaXMgZm9yIGFueSBzdWItdHJlZSBvZiB0aGlzIHRyZWUsIHRoZSBmb2xsb3dpbmcgbXVzdCBob2xkOgogICAgICoKICAgICAqIDxwPgogICAgICoge0Bjb2RlIHRyZWUuZ2V0U3RhcnRQb3NpdGlvbigpIDw9IHN1YnRyZWUuZ2V0U3RhcnRQb3NpdGlvbigpfSBvciA8YnI+CiAgICAgKiB7QGNvZGUgdHJlZS5nZXRTdGFydFBvc2l0aW9uKCkgPT0gTk9QT1N9IG9yIDxicj4KICAgICAqIHtAY29kZSBzdWJ0cmVlLmdldFN0YXJ0UG9zaXRpb24oKSA9PSBOT1BPU30KICAgICAqIDwvcD4KICAgICAqCiAgICAgKiBAcGFyYW0gZmlsZSBDb21waWxhdGlvblVuaXQgaW4gd2hpY2ggdG8gZmluZCB0cmVlLgogICAgICogQHBhcmFtIGNvbW1lbnQgdGhlIGNvbW1lbnQgdHJlZSB0aGF0IGVuY2xvc2VzIHRoZSB0cmVlIGZvciB3aGljaCB0aGUKICAgICAqICAgICAgICAgICAgICAgIHBvc2l0aW9uIGlzIGJlaW5nIHNvdWdodAogICAgICogQHBhcmFtIHRyZWUgdHJlZSBmb3Igd2hpY2ggYSBwb3NpdGlvbiBpcyBzb3VnaHQuCiAgICAgKiBAcmV0dXJuIHRoZSBzdGFydCBwb3NpdGlvbiBvZiB0cmVlLgogICAgICovCiAgICBsb25nIGdldFN0YXJ0UG9zaXRpb24oQ29tcGlsYXRpb25Vbml0VHJlZSBmaWxlLCBEb2NDb21tZW50VHJlZSBjb21tZW50LCBEb2NUcmVlIHRyZWUpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgZW5kaW5nIHBvc2l0aW9uIG9mIHRoZSB0cmVlIHdpdGhpbiB0aGUgY29tbWVudCB3aXRoaW4gdGhlIGZpbGUuICBJZiB0cmVlIGlzIG5vdCBmb3VuZCB3aXRoaW4KICAgICAqIGZpbGUsIG9yIGlmIHRoZSBlbmRpbmcgcG9zaXRpb24gaXMgbm90IGF2YWlsYWJsZSwKICAgICAqIHJldHVybiB7QGxpbmsgamF2YXgudG9vbHMuRGlhZ25vc3RpYyNOT1BPU30uCiAgICAgKiBUaGUgZ2l2ZW4gdHJlZSBzaG91bGQgYmUgdW5kZXIgdGhlIGdpdmVuIGNvbW1lbnQgdHJlZSwgYW5kIHRoZSBnaXZlbiBkb2N1bWVudGF0aW9uCiAgICAgKiBjb21tZW50IHRyZWUgc2hvdWxkIGJlIHJldHVybmVkIGZyb20gYSB7QGxpbmsgRG9jVHJlZXMjZ2V0RG9jQ29tbWVudFRyZWUoY29tLnN1bi5zb3VyY2UudXRpbC5UcmVlUGF0aCkgfQogICAgICogZm9yIGEgdHJlZSB1bmRlciB0aGUgZ2l2ZW4gZmlsZS4KICAgICAqIFRoZSByZXR1cm5lZCBwb3NpdGlvbiBtdXN0IGJlIGF0IHRoZSBlbmQgb2YgdGhlIHlpZWxkIG9mIHRoaXMgdHJlZSwKICAgICAqIHRoYXQgaXMgZm9yIGFueSBzdWItdHJlZSBvZiB0aGlzIHRyZWUsIHRoZSBmb2xsb3dpbmcgbXVzdCBob2xkOgogICAgICoKICAgICAqIDxwPgogICAgICoge0Bjb2RlIHRyZWUuZ2V0RW5kUG9zaXRpb24oKSA+PSBzdWJ0cmVlLmdldEVuZFBvc2l0aW9uKCl9IG9yIDxicj4KICAgICAqIHtAY29kZSB0cmVlLmdldEVuZFBvc2l0aW9uKCkgPT0gTk9QT1N9IG9yIDxicj4KICAgICAqIHtAY29kZSBzdWJ0cmVlLmdldEVuZFBvc2l0aW9uKCkgPT0gTk9QT1N9CiAgICAgKiA8L3A+CiAgICAgKgogICAgICogSW4gYWRkaXRpb24sIHRoZSBmb2xsb3dpbmcgbXVzdCBob2xkOgogICAgICoKICAgICAqIDxwPgogICAgICoge0Bjb2RlIHRyZWUuZ2V0U3RhcnRQb3NpdGlvbigpIDw9IHRyZWUuZ2V0RW5kUG9zaXRpb24oKX0gIG9yIDxicj4KICAgICAqIHtAY29kZSB0cmVlLmdldFN0YXJ0UG9zaXRpb24oKSA9PSBOT1BPU30gb3IgPGJyPgogICAgICoge0Bjb2RlIHRyZWUuZ2V0RW5kUG9zaXRpb24oKSA9PSBOT1BPU30KICAgICAqIDwvcD4KICAgICAqCiAgICAgKiBAcGFyYW0gZmlsZSBDb21waWxhdGlvblVuaXQgaW4gd2hpY2ggdG8gZmluZCB0cmVlLgogICAgICogQHBhcmFtIGNvbW1lbnQgdGhlIGNvbW1lbnQgdHJlZSB0aGF0IGVuY2xvc2VzIHRoZSB0cmVlIGZvciB3aGljaCB0aGUKICAgICAqICAgICAgICAgICAgICAgIHBvc2l0aW9uIGlzIGJlaW5nIHNvdWdodAogICAgICogQHBhcmFtIHRyZWUgdHJlZSBmb3Igd2hpY2ggYSBwb3NpdGlvbiBpcyBzb3VnaHQuCiAgICAgKiBAcmV0dXJuIHRoZSBzdGFydCBwb3NpdGlvbiBvZiB0cmVlLgogICAgICovCiAgICBsb25nIGdldEVuZFBvc2l0aW9uKENvbXBpbGF0aW9uVW5pdFRyZWUgZmlsZSwgRG9jQ29tbWVudFRyZWUgY29tbWVudCwgRG9jVHJlZSB0cmVlKTsKCn0KUEsDBAoAAAgAAAY7qUoKXhVvKhQAACoUAAAhAAAAY29tL3N1bi9zb3VyY2UvdXRpbC9UcmVlUGF0aC5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDA2LCAyMDE0LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4uc291cmNlLnV0aWw7CgppbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOwppbXBvcnQgamF2YS51dGlsLk9iamVjdHM7CgppbXBvcnQgY29tLnN1bi5zb3VyY2UudHJlZS4qOwoKLyoqCiAqIEEgcGF0aCBvZiB0cmVlIG5vZGVzLCB0eXBpY2FsbHkgdXNlZCB0byByZXByZXNlbnQgdGhlIHNlcXVlbmNlIG9mIGFuY2VzdG9yCiAqIG5vZGVzIG9mIGEgdHJlZSBub2RlIHVwIHRvIHRoZSB0b3AgbGV2ZWwgQ29tcGlsYXRpb25Vbml0VHJlZSBub2RlLgogKgogKiBAYXV0aG9yIEpvbmF0aGFuIEdpYmJvbnMKICogQHNpbmNlIDEuNgogKi8KcHVibGljIGNsYXNzIFRyZWVQYXRoIGltcGxlbWVudHMgSXRlcmFibGU8VHJlZT4gewogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgdHJlZSBwYXRoIGZvciBhIHRyZWUgbm9kZSB3aXRoaW4gYSBjb21waWxhdGlvbiB1bml0LAogICAgICogb3Ige0Bjb2RlIG51bGx9IGlmIHRoZSBub2RlIGlzIG5vdCBmb3VuZC4KICAgICAqIEBwYXJhbSB1bml0IHRoZSBjb21waWxhdGlvbiB1bml0IHRvIHNlYXJjaAogICAgICogQHBhcmFtIHRhcmdldCB0aGUgbm9kZSB0byBsb2NhdGUKICAgICAqIEByZXR1cm4gdGhlIHRyZWUgcGF0aAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIFRyZWVQYXRoIGdldFBhdGgoQ29tcGlsYXRpb25Vbml0VHJlZSB1bml0LCBUcmVlIHRhcmdldCkgewogICAgICAgIHJldHVybiBnZXRQYXRoKG5ldyBUcmVlUGF0aCh1bml0KSwgdGFyZ2V0KTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgYSB0cmVlIHBhdGggZm9yIGEgdHJlZSBub2RlIHdpdGhpbiBhIHN1YnRyZWUgaWRlbnRpZmllZCBieSBhIFRyZWVQYXRoIG9iamVjdC4KICAgICAqIFJldHVybnMge0Bjb2RlIG51bGx9IGlmIHRoZSBub2RlIGlzIG5vdCBmb3VuZC4KICAgICAqIEBwYXJhbSBwYXRoIHRoZSBwYXRoIGluIHdoaWNoIHRvIHNlYXJjaAogICAgICogQHBhcmFtIHRhcmdldCB0aGUgbm9kZSB0byBsb2NhdGUKICAgICAqIEByZXR1cm4gdGhlIHRyZWUgcGF0aCBvZiB0aGUgdGFyZ2V0IG5vZGUKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBUcmVlUGF0aCBnZXRQYXRoKFRyZWVQYXRoIHBhdGgsIFRyZWUgdGFyZ2V0KSB7CiAgICAgICAgT2JqZWN0cy5yZXF1aXJlTm9uTnVsbChwYXRoKTsKICAgICAgICBPYmplY3RzLnJlcXVpcmVOb25OdWxsKHRhcmdldCk7CgogICAgICAgIGNsYXNzIFJlc3VsdCBleHRlbmRzIEVycm9yIHsKICAgICAgICAgICAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC01OTQyMDg4MjM0NTk0OTA1NjI1TDsKICAgICAgICAgICAgVHJlZVBhdGggcGF0aDsKICAgICAgICAgICAgUmVzdWx0KFRyZWVQYXRoIHBhdGgpIHsKICAgICAgICAgICAgICAgIHRoaXMucGF0aCA9IHBhdGg7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGNsYXNzIFBhdGhGaW5kZXIgZXh0ZW5kcyBUcmVlUGF0aFNjYW5uZXI8VHJlZVBhdGgsVHJlZT4gewogICAgICAgICAgICBwdWJsaWMgVHJlZVBhdGggc2NhbihUcmVlIHRyZWUsIFRyZWUgdGFyZ2V0KSB7CiAgICAgICAgICAgICAgICBpZiAodHJlZSA9PSB0YXJnZXQpIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUmVzdWx0KG5ldyBUcmVlUGF0aChnZXRDdXJyZW50UGF0aCgpLCB0YXJnZXQpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBzdXBlci5zY2FuKHRyZWUsIHRhcmdldCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmIChwYXRoLmdldExlYWYoKSA9PSB0YXJnZXQpIHsKICAgICAgICAgICAgcmV0dXJuIHBhdGg7CiAgICAgICAgfQoKICAgICAgICB0cnkgewogICAgICAgICAgICBuZXcgUGF0aEZpbmRlcigpLnNjYW4ocGF0aCwgdGFyZ2V0KTsKICAgICAgICB9IGNhdGNoIChSZXN1bHQgcmVzdWx0KSB7CiAgICAgICAgICAgIHJldHVybiByZXN1bHQucGF0aDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgLyoqCiAgICAgKiBDcmVhdGVzIGEgVHJlZVBhdGggZm9yIGEgcm9vdCBub2RlLgogICAgICogQHBhcmFtIG5vZGUgdGhlIHJvb3Qgbm9kZQogICAgICovCiAgICBwdWJsaWMgVHJlZVBhdGgoQ29tcGlsYXRpb25Vbml0VHJlZSBub2RlKSB7CiAgICAgICAgdGhpcyhudWxsLCBub2RlKTsKICAgIH0KCiAgICAvKioKICAgICAqIENyZWF0ZXMgYSBUcmVlUGF0aCBmb3IgYSBjaGlsZCBub2RlLgogICAgICogQHBhcmFtIHBhdGggdGhlIHBhcmVudCBwYXRoCiAgICAgKiBAcGFyYW0gdHJlZSB0aGUgY2hpbGQgbm9kZQogICAgICovCiAgICBwdWJsaWMgVHJlZVBhdGgoVHJlZVBhdGggcGF0aCwgVHJlZSB0cmVlKSB7CiAgICAgICAgaWYgKHRyZWUuZ2V0S2luZCgpID09IFRyZWUuS2luZC5DT01QSUxBVElPTl9VTklUKSB7CiAgICAgICAgICAgIGNvbXBpbGF0aW9uVW5pdCA9IChDb21waWxhdGlvblVuaXRUcmVlKSB0cmVlOwogICAgICAgICAgICBwYXJlbnQgPSBudWxsOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgY29tcGlsYXRpb25Vbml0ID0gcGF0aC5jb21waWxhdGlvblVuaXQ7CiAgICAgICAgICAgIHBhcmVudCA9IHBhdGg7CiAgICAgICAgfQogICAgICAgIGxlYWYgPSB0cmVlOwogICAgfQogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBjb21waWxhdGlvbiB1bml0IGFzc29jaWF0ZWQgd2l0aCB0aGlzIHBhdGguCiAgICAgKiBAcmV0dXJuIHRoZSBjb21waWxhdGlvbiB1bml0CiAgICAgKi8KICAgIHB1YmxpYyBDb21waWxhdGlvblVuaXRUcmVlIGdldENvbXBpbGF0aW9uVW5pdCgpIHsKICAgICAgICByZXR1cm4gY29tcGlsYXRpb25Vbml0OwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgbGVhZiBub2RlIGZvciB0aGlzIHBhdGguCiAgICAgKiBAcmV0dXJuIHRoZSBsZWFmIG5vZGUKICAgICAqLwogICAgcHVibGljIFRyZWUgZ2V0TGVhZigpIHsKICAgICAgICByZXR1cm4gbGVhZjsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHBhdGggZm9yIHRoZSBlbmNsb3Npbmcgbm9kZSwgb3Ige0Bjb2RlIG51bGx9IGlmIHRoZXJlIGlzIG5vIGVuY2xvc2luZyBub2RlLgogICAgICogQHJldHVybiB0aGUgcGF0aCBmb3IgdGhlIGVuY2xvc2luZyBub2RlCiAgICAgKi8KICAgIHB1YmxpYyBUcmVlUGF0aCBnZXRQYXJlbnRQYXRoKCkgewogICAgICAgIHJldHVybiBwYXJlbnQ7CiAgICB9CgogICAgLyoqCiAgICAgKiAgSXRlcmF0ZXMgZnJvbSBsZWF2ZXMgdG8gcm9vdC4KICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgSXRlcmF0b3I8VHJlZT4gaXRlcmF0b3IoKSB7CiAgICAgICAgcmV0dXJuIG5ldyBJdGVyYXRvcjxUcmVlPigpIHsKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHB1YmxpYyBib29sZWFuIGhhc05leHQoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gbmV4dCAhPSBudWxsOwogICAgICAgICAgICB9CgogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHVibGljIFRyZWUgbmV4dCgpIHsKICAgICAgICAgICAgICAgIFRyZWUgdCA9IG5leHQubGVhZjsKICAgICAgICAgICAgICAgIG5leHQgPSBuZXh0LnBhcmVudDsKICAgICAgICAgICAgICAgIHJldHVybiB0OwogICAgICAgICAgICB9CgogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHVibGljIHZvaWQgcmVtb3ZlKCkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHByaXZhdGUgVHJlZVBhdGggbmV4dCA9IFRyZWVQYXRoLnRoaXM7CiAgICAgICAgfTsKICAgIH0KCiAgICBwcml2YXRlIENvbXBpbGF0aW9uVW5pdFRyZWUgY29tcGlsYXRpb25Vbml0OwogICAgcHJpdmF0ZSBUcmVlIGxlYWY7CiAgICBwcml2YXRlIFRyZWVQYXRoIHBhcmVudDsKfQpQSwMECgAACAAABjupShnJCPdTCgAAUwoAAB8AAABjb20vc3VuL3NvdXJjZS91dGlsL1BsdWdpbi5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDA1LCAyMDE0LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4uc291cmNlLnV0aWw7CgppbXBvcnQgamF2YS51dGlsLlNlcnZpY2VMb2FkZXI7CmltcG9ydCBqYXZheC50b29scy5TdGFuZGFyZExvY2F0aW9uOwoKLyoqCiAqIFRoZSBpbnRlcmZhY2UgZm9yIGEgamF2YWMgcGx1Zy1pbi4KICoKICogPHA+VGhlIGphdmFjIHBsdWctaW4gbWVjaGFuaXNtIGFsbG93cyBhIHVzZXIgdG8gc3BlY2lmeSBvbmUgb3IgbW9yZSBwbHVnLWlucwogKiBvbiB0aGUgamF2YWMgY29tbWFuZCBsaW5lLCB0byBiZSBzdGFydGVkIHNvb24gYWZ0ZXIgdGhlIGNvbXBpbGF0aW9uCiAqIGhhcyBiZWd1bi4gUGx1Zy1pbnMgYXJlIGlkZW50aWZpZWQgYnkgYSB1c2VyLWZyaWVuZGx5IG5hbWUuIEVhY2ggcGx1Zy1pbiB0aGF0CiAqIGlzIHN0YXJ0ZWQgd2lsbCBiZSBwYXNzZWQgYW4gYXJyYXkgb2Ygc3RyaW5ncywgd2hpY2ggbWF5IGJlIHVzZWQgdG8KICogcHJvdmlkZSB0aGUgcGx1Zy1pbiB3aXRoIHZhbHVlcyBmb3IgYW55IGRlc2lyZWQgb3B0aW9ucyBvciBvdGhlciBhcmd1bWVudHMuCiAqCiAqIDxwPlBsdWctaW5zIGFyZSBsb2NhdGVkIHZpYSBhIHtAbGluayBTZXJ2aWNlTG9hZGVyfSwKICogdXNpbmcgdGhlIHNhbWUgY2xhc3MgcGF0aCBhcyBhbm5vdGF0aW9uIHByb2Nlc3NvcnMgKGkuZS4KICoge0BsaW5rIFN0YW5kYXJkTG9jYXRpb24jQU5OT1RBVElPTl9QUk9DRVNTT1JfUEFUSCBBTk5PVEFUSU9OX1BST0NFU1NPUl9QQVRIfSBvcgogKiB7QGNvZGUgLXByb2Nlc3NvcnBhdGh9KS4KICoKICogPHA+SXQgaXMgZXhwZWN0ZWQgdGhhdCBhIHR5cGljYWwgcGx1Zy1pbiB3aWxsIHNpbXBseSByZWdpc3RlciBhCiAqIHtAbGluayBUYXNrTGlzdGVuZXJ9IHRvIGJlIGluZm9ybWVkIG9mIGV2ZW50cyBkdXJpbmcgdGhlIGV4ZWN1dGlvbgogKiBvZiB0aGUgY29tcGlsYXRpb24sIGFuZCB0aGF0IHRoZSByZXN0IG9mIHRoZSB3b3JrIHdpbGwgYmUgZG9uZQogKiBieSB0aGUgdGFzayBsaXN0ZW5lci4KICoKICogQHNpbmNlIDEuOAogKi8KcHVibGljIGludGVyZmFjZSBQbHVnaW4gewogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSB1c2VyLWZyaWVuZGx5IG5hbWUgb2YgdGhpcyBwbHVnLWluLgogICAgICogQHJldHVybiB0aGUgdXNlci1mcmllbmRseSBuYW1lIG9mIHRoZSBwbHVnLWluCiAgICAgKi8KICAgIFN0cmluZyBnZXROYW1lKCk7CgogICAgLyoqCiAgICAgKiBJbml0aWFsaXplcyB0aGUgcGx1Zy1pbiBmb3IgYSBnaXZlbiBjb21waWxhdGlvbiB0YXNrLgogICAgICogQHBhcmFtIHRhc2sgVGhlIGNvbXBpbGF0aW9uIHRhc2sgdGhhdCBoYXMganVzdCBiZWVuIHN0YXJ0ZWQKICAgICAqIEBwYXJhbSBhcmdzIEFyZ3VtZW50cywgaWYgYW55LCBmb3IgdGhlIHBsdWctaW4KICAgICAqLwogICAgdm9pZCBpbml0KEphdmFjVGFzayB0YXNrLCBTdHJpbmcuLi4gYXJncyk7Cn0KUEsDBAoAAAgAAAY7qUpjzSgxzTgAAM04AAAnAAAAY29tL3N1bi9zb3VyY2UvdXRpbC9Eb2NUcmVlRmFjdG9yeS5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDExLCAyMDE2LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4uc291cmNlLnV0aWw7CgppbXBvcnQgamF2YS51dGlsLkxpc3Q7CgppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5lbGVtZW50Lk5hbWU7CmltcG9ydCBqYXZheC50b29scy5EaWFnbm9zdGljOwppbXBvcnQgamF2YXgudG9vbHMuSmF2YUZpbGVPYmplY3Q7CgppbXBvcnQgY29tLnN1bi5zb3VyY2UuZG9jdHJlZS5BdHRyaWJ1dGVUcmVlOwppbXBvcnQgY29tLnN1bi5zb3VyY2UuZG9jdHJlZS5BdHRyaWJ1dGVUcmVlLlZhbHVlS2luZDsKaW1wb3J0IGNvbS5zdW4uc291cmNlLmRvY3RyZWUuQXV0aG9yVHJlZTsKaW1wb3J0IGNvbS5zdW4uc291cmNlLmRvY3RyZWUuQ29tbWVudFRyZWU7CmltcG9ydCBjb20uc3VuLnNvdXJjZS5kb2N0cmVlLkRlcHJlY2F0ZWRUcmVlOwppbXBvcnQgY29tLnN1bi5zb3VyY2UuZG9jdHJlZS5Eb2NDb21tZW50VHJlZTsKaW1wb3J0IGNvbS5zdW4uc291cmNlLmRvY3RyZWUuRG9jUm9vdFRyZWU7CmltcG9ydCBjb20uc3VuLnNvdXJjZS5kb2N0cmVlLkRvY1RyZWU7CmltcG9ydCBjb20uc3VuLnNvdXJjZS5kb2N0cmVlLkVuZEVsZW1lbnRUcmVlOwppbXBvcnQgY29tLnN1bi5zb3VyY2UuZG9jdHJlZS5FbnRpdHlUcmVlOwppbXBvcnQgY29tLnN1bi5zb3VyY2UuZG9jdHJlZS5FcnJvbmVvdXNUcmVlOwppbXBvcnQgY29tLnN1bi5zb3VyY2UuZG9jdHJlZS5IaWRkZW5UcmVlOwppbXBvcnQgY29tLnN1bi5zb3VyY2UuZG9jdHJlZS5JZGVudGlmaWVyVHJlZTsKaW1wb3J0IGNvbS5zdW4uc291cmNlLmRvY3RyZWUuSW5kZXhUcmVlOwppbXBvcnQgY29tLnN1bi5zb3VyY2UuZG9jdHJlZS5Jbmhlcml0RG9jVHJlZTsKaW1wb3J0IGNvbS5zdW4uc291cmNlLmRvY3RyZWUuTGlua1RyZWU7CmltcG9ydCBjb20uc3VuLnNvdXJjZS5kb2N0cmVlLkxpdGVyYWxUcmVlOwppbXBvcnQgY29tLnN1bi5zb3VyY2UuZG9jdHJlZS5QYXJhbVRyZWU7CmltcG9ydCBjb20uc3VuLnNvdXJjZS5kb2N0cmVlLlByb3ZpZGVzVHJlZTsKaW1wb3J0IGNvbS5zdW4uc291cmNlLmRvY3RyZWUuUmVmZXJlbmNlVHJlZTsKaW1wb3J0IGNvbS5zdW4uc291cmNlLmRvY3RyZWUuUmV0dXJuVHJlZTsKaW1wb3J0IGNvbS5zdW4uc291cmNlLmRvY3RyZWUuU2VlVHJlZTsKaW1wb3J0IGNvbS5zdW4uc291cmNlLmRvY3RyZWUuU2VyaWFsRGF0YVRyZWU7CmltcG9ydCBjb20uc3VuLnNvdXJjZS5kb2N0cmVlLlNlcmlhbEZpZWxkVHJlZTsKaW1wb3J0IGNvbS5zdW4uc291cmNlLmRvY3RyZWUuU2VyaWFsVHJlZTsKaW1wb3J0IGNvbS5zdW4uc291cmNlLmRvY3RyZWUuU2luY2VUcmVlOwppbXBvcnQgY29tLnN1bi5zb3VyY2UuZG9jdHJlZS5TdGFydEVsZW1lbnRUcmVlOwppbXBvcnQgY29tLnN1bi5zb3VyY2UuZG9jdHJlZS5UZXh0VHJlZTsKaW1wb3J0IGNvbS5zdW4uc291cmNlLmRvY3RyZWUuVGhyb3dzVHJlZTsKaW1wb3J0IGNvbS5zdW4uc291cmNlLmRvY3RyZWUuVW5rbm93bkJsb2NrVGFnVHJlZTsKaW1wb3J0IGNvbS5zdW4uc291cmNlLmRvY3RyZWUuVW5rbm93bklubGluZVRhZ1RyZWU7CmltcG9ydCBjb20uc3VuLnNvdXJjZS5kb2N0cmVlLlVzZXNUcmVlOwppbXBvcnQgY29tLnN1bi5zb3VyY2UuZG9jdHJlZS5WYWx1ZVRyZWU7CmltcG9ydCBjb20uc3VuLnNvdXJjZS5kb2N0cmVlLlZlcnNpb25UcmVlOwoKLyoqCiAqICBGYWN0b3J5IGZvciBjcmVhdGluZyB7QGNvZGUgRG9jVHJlZX0gbm9kZXMuCiAqCiAqICBAaW1wbE5vdGUgVGhlIG1ldGhvZHMgaW4gYW4gaW1wbGVtZW50YXRpb24gb2YgdGhpcyBpbnRlcmZhY2UgbWF5IG9ubHkgYWNjZXB0IHtAY29kZSBEb2NUcmVlfQogKiAgbm9kZXMgdGhhdCBoYXZlIGJlZW4gY3JlYXRlZCBieSB0aGUgc2FtZSBpbXBsZW1lbnRhdGlvbi4KICoKICogIEBzaW5jZSA5CiAqLwpwdWJsaWMgaW50ZXJmYWNlIERvY1RyZWVGYWN0b3J5IHsKICAgIC8qKgogICAgICogQ3JlYXRlIGEgbmV3IHtAY29kZSBBdHRyaWJ1dGVUcmVlfSBvYmplY3QsIHRvIHJlcHJlc2VudCBhbiBIVE1MIGF0dHJpYnV0ZSBpbiBhbiBIVE1MIHRhZy4KICAgICAqIEBwYXJhbSBuYW1lICB0aGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlCiAgICAgKiBAcGFyYW0gdmtpbmQgdGhlIGtpbmQgb2YgYXR0cmlidXRlIHZhbHVlCiAgICAgKiBAcGFyYW0gdmFsdWUgdGhlIHZhbHVlLCBpZiBhbnksIG9mIHRoZSBhdHRyaWJ1dGUKICAgICAqIEByZXR1cm4gYW4ge0Bjb2RlIEF0dHJpYnV0ZVRyZWV9IG9iamVjdAogICAgICovCiAgICBBdHRyaWJ1dGVUcmVlIG5ld0F0dHJpYnV0ZVRyZWUoTmFtZSBuYW1lLCBWYWx1ZUtpbmQgdmtpbmQsIExpc3Q8PyBleHRlbmRzIERvY1RyZWU+IHZhbHVlKTsKCiAgICAvKioKICAgICAqIENyZWF0ZSBhIG5ldyB7QGNvZGUgQXV0aG9yVHJlZX0gb2JqZWN0LCB0byByZXByZXNlbnQgYW4ge0Bjb2RlIHtAYXV0aG9yIH0gfSB0YWcuCiAgICAgKiBAcGFyYW0gbmFtZSB0aGUgbmFtZSBvZiB0aGUgYXV0aG9yCiAgICAgKiBAcmV0dXJuIGFuIHtAY29kZSBBdXRob3JUcmVlfSBvYmplY3QKICAgICAqLwogICAgQXV0aG9yVHJlZSBuZXdBdXRob3JUcmVlKExpc3Q8PyBleHRlbmRzIERvY1RyZWU+IG5hbWUpOwoKICAgIC8qKgogICAgICogQ3JlYXRlIGEgbmV3IHtAY29kZSBDb2RlVHJlZX0gb2JqZWN0LCB0byByZXByZXNlbnQgYSB7QGNvZGUge0Bjb2RlIH0gfSB0YWcuCiAgICAgKiBAcGFyYW0gdGV4dCB0aGUgY29udGVudCBvZiB0aGUgdGFnCiAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIENvZGVUcmVlfSBvYmplY3QKICAgICAqLwogICAgTGl0ZXJhbFRyZWUgbmV3Q29kZVRyZWUoVGV4dFRyZWUgdGV4dCk7CgogICAgLyoqCiAgICAgKiBDcmVhdGUgYSBuZXcge0Bjb2RlIENvbW1lbnRUcmVlfSwgdG8gcmVwcmVzZW50IGFuIEhUTUwgY29tbWVudC4KICAgICAqIEBwYXJhbSB0ZXh0IHRoZSBjb250ZW50IG9mIHRoZSBjb21tZW50CiAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIENvbW1lbnRUcmVlfSBvYmplY3QKICAgICAqLwogICAgQ29tbWVudFRyZWUgbmV3Q29tbWVudFRyZWUoU3RyaW5nIHRleHQpOwoKICAgIC8qKgogICAgICogQ3JlYXRlIGEgbmV3IHtAY29kZSBEZXByZWNhdGVkVHJlZX0gb2JqZWN0LCB0byByZXByZXNlbnQgYW4ge0Bjb2RlIHtAZGVwcmVjYXRlZCB9IH0gdGFnLgogICAgICogQHBhcmFtIHRleHQgdGhlIGNvbnRlbnQgb2YgdGhlIHRhZwogICAgICogQHJldHVybiBhIHtAY29kZSBEZXByZWNhdGVkVHJlZX0gb2JqZWN0CiAgICAgKi8KICAgIERlcHJlY2F0ZWRUcmVlIG5ld0RlcHJlY2F0ZWRUcmVlKExpc3Q8PyBleHRlbmRzIERvY1RyZWU+IHRleHQpOwoKICAgIC8qKgogICAgICogQ3JlYXRlIGEgbmV3IHtAY29kZSBEb2NDb21tZW50VHJlZX0gb2JqZWN0LCB0byByZXByZXNlbnQgYSBjb21wbGV0ZSBkb2MgY29tbWVudC4KICAgICAqIEBwYXJhbSBmdWxsQm9keSB0aGUgZW50aXJlIGJvZHkgb2YgdGhlIGRvYyBjb21tZW50CiAgICAgKiBAcGFyYW0gdGFncyB0aGUgYmxvY2sgdGFncyBpbiB0aGUgZG9jIGNvbW1lbnQKICAgICAqIEByZXR1cm4gYSB7QGNvZGUgRG9jQ29tbWVudFRyZWV9IG9iamVjdAogICAgICovCiAgICBEb2NDb21tZW50VHJlZSBuZXdEb2NDb21tZW50VHJlZShMaXN0PD8gZXh0ZW5kcyBEb2NUcmVlPiBmdWxsQm9keSwgTGlzdDw/IGV4dGVuZHMgRG9jVHJlZT4gdGFncyk7CgogICAgLyoqCiAgICAgKiBDcmVhdGUgYSBuZXcge0Bjb2RlIERvY1Jvb3RUcmVlfSBvYmplY3QsIHRvIHJlcHJlc2VudCBhbiB7QGNvZGUge0Bkb2Nyb290fSB9IHRhZy4KICAgICAqIEByZXR1cm4gYSB7QGNvZGUgRG9jUm9vdFRyZWV9IG9iamVjdAogICAgICovCiAgICBEb2NSb290VHJlZSBuZXdEb2NSb290VHJlZSgpOwoKICAgIC8qKgogICAgICogQ3JlYXRlIGEgbmV3IHtAY29kZSBFbmRFbGVtZW50fSBvYmplY3QsIHRvIHJlcHJlc2VudCB0aGUgZW5kIG9mIGFuIEhUTUwgZWxlbWVudC4KICAgICAqIEBwYXJhbSBuYW1lIHRoZSBuYW1lIG9mIHRoZSBIVE1MIGVsZW1lbnQKICAgICAqIEByZXR1cm4gYW4ge0Bjb2RlIEVuZEVsZW1lbnRUcmVlfSBvYmplY3QKICAgICAqLwogICAgRW5kRWxlbWVudFRyZWUgbmV3RW5kRWxlbWVudFRyZWUoTmFtZSBuYW1lKTsKCiAgICAvKioKICAgICAqIENyZWF0ZSBhIG5ldyB7QGNvZGUgRW50aXR5VHJlZX0gb2JqZWN0LCB0byByZXByZXNlbnQgYW4gSFRNTCBlbnRpdHkuCiAgICAgKiBAcGFyYW0gbmFtZSB0aGUgbmFtZSBvZiB0aGUgZW50aXR5LCByZXByZXNlbnRpbmcgdGhlIGNoYXJhY3RlcnMgYmV0d2VlbiAnJmx0OycgYW5kICc7JwogICAgICogaW4gdGhlIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBlbnRpdHkgaW4gYW4gSFRNTCBkb2N1bWVudAogICAgICogQHJldHVybiBhbiB7QGNvZGUgRW50aXR5VHJlZX0gb2JqZWN0CiAgICAgKi8KICAgIEVudGl0eVRyZWUgbmV3RW50aXR5VHJlZShOYW1lIG5hbWUpOwoKICAgIC8qKgogICAgICogQ3JlYXRlIGEgbmV3IHtAY29kZSBFcnJvbmVvdXNUcmVlfSBvYmplY3QsIHRvIHJlcHJlc2VudCBzb21lIHVucGFyc2VhYmxlIGlucHV0LgogICAgICogQHBhcmFtIHRleHQgdGhlIHVucGFyc2VhYmxlIHRleHQKICAgICAqIEBwYXJhbSBkaWFnIGEgZGlhZ25vc3RpYyBhc3NvY2lhdGVkIHdpdGggdGhlIHVucGFyc2VhYmxlIHRleHQsIG9yIG51bGwKICAgICAqIEByZXR1cm4gYW4ge0Bjb2RlIEVycm9uZW91c1RyZWV9IG9iamVjdAogICAgICovCiAgICBFcnJvbmVvdXNUcmVlIG5ld0Vycm9uZW91c1RyZWUoU3RyaW5nIHRleHQsIERpYWdub3N0aWM8SmF2YUZpbGVPYmplY3Q+IGRpYWcpOwoKICAgIC8qKgogICAgICogQ3JlYXRlIGEgbmV3IHtAY29kZSBFeGNlcHRpb25UcmVlfSBvYmplY3QsIHRvIHJlcHJlc2VudCBhbiB7QGNvZGUgQGV4Y2VwdGlvbiB9IHRhZy4KICAgICAqIEBwYXJhbSBuYW1lIHRoZSBuYW1lIG9mIHRoZSBleGNlcHRpb24KICAgICAqIEBwYXJhbSBkZXNjcmlwdGlvbiBhIGRlc2NyaXB0aW9uIG9mIHdoeSB0aGUgZXhjZXB0aW9uIG1pZ2h0IGJlIHRocm93bgogICAgICogQHJldHVybiBhbiB7QGNvZGUgRXhjZXB0aW9uVHJlZX0gb2JqZWN0CiAgICAgKi8KICAgIFRocm93c1RyZWUgbmV3RXhjZXB0aW9uVHJlZShSZWZlcmVuY2VUcmVlIG5hbWUsIExpc3Q8PyBleHRlbmRzIERvY1RyZWU+IGRlc2NyaXB0aW9uKTsKCiAgICAvKioKICAgICAqIENyZWF0ZSBhIG5ldyB7QGNvZGUgSGlkZGVuVHJlZX0gb2JqZWN0LCB0byByZXByZXNlbnQgYW4ge0Bjb2RlIHtAaGlkZGVuIH0gfSB0YWcuCiAgICAgKiBAcGFyYW0gdGV4dCB0aGUgY29udGVudCBvZiB0aGUgdGFnCiAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIEhpZGRlblRyZWV9IG9iamVjdAogICAgICovCiAgICBIaWRkZW5UcmVlIG5ld0hpZGRlblRyZWUoTGlzdDw/IGV4dGVuZHMgRG9jVHJlZT4gdGV4dCk7CgogICAgLyoqCiAgICAgKiBDcmVhdGUgYSBuZXcge0Bjb2RlIElkZW50aWZpZXJUcmVlfSBvYmplY3QsIHRvIHJlcHJlc2VudCBhbiBpZGVudGlmaWVyLCBzdWNoIGFzIGluIGEKICAgICAqIHtAY29kZSBAcGFyYW0gfSB0YWcuCiAgICAgKiBAcGFyYW0gbmFtZSB0aGUgbmFtZSBvZiB0aGUgaWRlbnRpZmllcgogICAgICogQHJldHVybiBhbiB7QGNvZGUgSWRlbnRpZmllclRyZWV9IG9iamVjdAogICAgICovCiAgICBJZGVudGlmaWVyVHJlZSBuZXdJZGVudGlmaWVyVHJlZShOYW1lIG5hbWUpOwoKICAgIC8qKgogICAgICogQ3JlYXRlIGEgbmV3IHtAY29kZSBJbmRleFRyZWV9IG9iamVjdCwgdG8gcmVwcmVzZW50IGFuIHtAY29kZSB7QGluZGV4IH0gfSB0YWcuCiAgICAgKiBAcGFyYW0gdGVybSB0aGUgc2VhcmNoIHRlcm0KICAgICAqIEBwYXJhbSBkZXNjcmlwdGlvbiBhbiBvcHRpb25hbCBkZXNjcmlwdGlvbiBvZiB0aGUgc2VhcmNoIHRlcm0KICAgICAqIEByZXR1cm4gYW4ge0Bjb2RlIEluZGV4VHJlZX0gb2JqZWN0CiAgICAgKi8KICAgIEluZGV4VHJlZSBuZXdJbmRleFRyZWUoRG9jVHJlZSB0ZXJtLCBMaXN0PD8gZXh0ZW5kcyBEb2NUcmVlPiBkZXNjcmlwdGlvbik7CgogICAgLyoqCiAgICAgKiBDcmVhdGUgYSBuZXcge0Bjb2RlIEluaGVyaXREb2NUcmVlfSBvYmplY3QsIHRvIHJlcHJlc2VudCBhbiB7QGNvZGUge0Bpbmhlcml0RG9jfSB9IHRhZy4KICAgICAqIEByZXR1cm4gYW4ge0Bjb2RlIEluaGVyaXREb2NUcmVlfSBvYmplY3QKICAgICAqLwogICAgSW5oZXJpdERvY1RyZWUgbmV3SW5oZXJpdERvY1RyZWUoKTsKCiAgICAvKioKICAgICAqIENyZWF0ZSBhIG5ldyB7QGNvZGUgTGlua1RyZWV9IG9iamVjdCwgdG8gcmVwcmVzZW50IGEge0Bjb2RlIHtAbGluayB9IH0gdGFnLgogICAgICogQHBhcmFtIHJlZiB0aGUgQVBJIGVsZW1lbnQgYmVpbmcgcmVmZXJlbmNlZAogICAgICogQHBhcmFtIGxhYmVsIGFuIG9wdGlvbmFsIGxhYmVsIGZvciB0aGUgbGluawogICAgICogQHJldHVybiBhIHtAY29kZSBMaW5rVHJlZX0gb2JqZWN0CiAgICAgKi8KICAgIExpbmtUcmVlIG5ld0xpbmtUcmVlKFJlZmVyZW5jZVRyZWUgcmVmLCBMaXN0PD8gZXh0ZW5kcyBEb2NUcmVlPiBsYWJlbCk7CgogICAgLyoqCiAgICAgKiBDcmVhdGUgYSBuZXcge0Bjb2RlIExpbmtQbGFpblRyZWV9IG9iamVjdCwgdG8gcmVwcmVzZW50IGEge0Bjb2RlIHtAbGlua3BsYWluIH0gfSB0YWcuCiAgICAgKiBAcGFyYW0gcmVmIHRoZSBBUEkgZWxlbWVudCBiZWluZyByZWZlcmVuY2VkCiAgICAgKiBAcGFyYW0gbGFiZWwgYW4gb3B0aW9uYWwgbGFiZWwgZm9yIHRoZSBsaW5rCiAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIExpbmtQbGFpblRyZWV9IG9iamVjdAogICAgICovCiAgICBMaW5rVHJlZSBuZXdMaW5rUGxhaW5UcmVlKFJlZmVyZW5jZVRyZWUgcmVmLCBMaXN0PD8gZXh0ZW5kcyBEb2NUcmVlPiBsYWJlbCk7CgogICAgLyoqCiAgICAgKiBDcmVhdGUgYSBuZXcge0Bjb2RlIExpdGVyYWxUcmVlfSBvYmplY3QsIHRvIHJlcHJlc2VudCBhIHtAY29kZSB7QGxpdGVyYWwgfSB9IHRhZy4KICAgICAqIEBwYXJhbSB0ZXh0IHRoZSBjb250ZW50IG9mIHRoZSB0YWcKICAgICAqIEByZXR1cm4gYSB7QGNvZGUgTGl0ZXJhbFRyZWV9IG9iamVjdAogICAgICovCiAgICBMaXRlcmFsVHJlZSBuZXdMaXRlcmFsVHJlZShUZXh0VHJlZSB0ZXh0KTsKCiAgICAvKioKICAgICAqIENyZWF0ZSBhIG5ldyB7QGNvZGUgUGFyYW1UcmVlfSBvYmplY3QsIHRvIHJlcHJlc2VudCBhIHtAY29kZSBAcGFyYW0gfSB0YWcuCiAgICAgKiBAcGFyYW0gaXNUeXBlUGFyYW1ldGVyIHRydWUgaWYgdGhpcyBpcyBhIHR5cGUgcGFyYW1ldGVyLCBhbmQgZmFsc2Ugb3RoZXJ3aXNlCiAgICAgKiBAcGFyYW0gbmFtZSB0aGUgcGFyYW1ldGVyIGJlaW5nIGRlc2NyaWJlZAogICAgICogQHBhcmFtIGRlc2NyaXB0aW9uIHRoZSBkZXNjcmlwdGlvbiBvZiB0aGUgcGFyYW1ldGVyCiAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIFBhcmFtVHJlZX0gb2JqZWN0CiAgICAgKi8KICAgIFBhcmFtVHJlZSBuZXdQYXJhbVRyZWUoYm9vbGVhbiBpc1R5cGVQYXJhbWV0ZXIsIElkZW50aWZpZXJUcmVlIG5hbWUsIExpc3Q8PyBleHRlbmRzIERvY1RyZWU+IGRlc2NyaXB0aW9uKTsKCiAgICAvKioKICAgICAqIENyZWF0ZSBhIG5ldyB7QGNvZGUgUHJvdmlkZXNUcmVlfSBvYmplY3QsIHRvIHJlcHJlc2VudCBhIHtAY29kZSBAcHJvdmlkZXMgfSB0YWcuCiAgICAgKiBAcGFyYW0gbmFtZSB0aGUgbmFtZSBvZiB0aGUgc2VydmljZSB0eXBlCiAgICAgKiBAcGFyYW0gZGVzY3JpcHRpb24gYSBkZXNjcmlwdGlvbiBvZiB0aGUgc2VydmljZSBiZWluZyBwcm92aWRlZAogICAgICogQHJldHVybiBhIHtAY29kZSBQcm92aWRlc1RyZWV9IG9iamVjdAogICAgICovCiAgICBQcm92aWRlc1RyZWUgbmV3UHJvdmlkZXNUcmVlKFJlZmVyZW5jZVRyZWUgbmFtZSwgTGlzdDw/IGV4dGVuZHMgRG9jVHJlZT4gZGVzY3JpcHRpb24pOwoKICAgIC8qKgogICAgICogQ3JlYXRlIGEgbmV3IHtAY29kZSBSZWZlcmVuY2VUcmVlfSBvYmplY3QsIHRvIHJlcHJlc2VudCBhIHJlZmVyZW5jZSB0byBhbiBBUEkgZWxlbWVudC4KICAgICAqCiAgICAgKiBAcGFyYW0gc2lnbmF0dXJlIHRoZSBkb2MgY29tbWVudCBzaWduYXR1cmUgb2YgdGhlIHJlZmVyZW5jZQogICAgICogQHJldHVybiBhIHtAY29kZSBSZWZlcmVuY2VUcmVlfSBvYmplY3QKICAgICAqLwogICAgUmVmZXJlbmNlVHJlZSBuZXdSZWZlcmVuY2VUcmVlKFN0cmluZyBzaWduYXR1cmUpOwoKICAgIC8qKgogICAgICogQ3JlYXRlIGEgbmV3IHtAY29kZSBSZXR1cm5UcmVlfSBvYmplY3QsIHRvIHJlcHJlc2VudCBhIHtAY29kZSBAcmV0dXJuIH0gdGFnLgogICAgICogQHBhcmFtIGRlc2NyaXB0aW9uIHRoZSBkZXNjcmlwdGlvbiBvZiB0aGUgcmV0dXJuIHZhbHVlIG9mIGEgbWV0aG9kCiAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIFJldHVyblRyZWV9IG9iamVjdAogICAgICovCiAgICBSZXR1cm5UcmVlIG5ld1JldHVyblRyZWUoTGlzdDw/IGV4dGVuZHMgRG9jVHJlZT4gZGVzY3JpcHRpb24pOwoKICAgIC8qKgogICAgICogQ3JlYXRlIGEgbmV3IHtAY29kZSBTZWVUcmVlfSBvYmplY3QsIHRvIHJlcHJlc2VudCBhIHtAY29kZSBAc2VlIH0gdGFnLgogICAgICogQHBhcmFtIHJlZmVyZW5jZSB0aGUgcmVmZXJlbmNlCiAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIFNlZVRyZWV9IG9iamVjdAogICAgICovCiAgICBTZWVUcmVlIG5ld1NlZVRyZWUoTGlzdDw/IGV4dGVuZHMgRG9jVHJlZT4gcmVmZXJlbmNlKTsKCiAgICAvKioKICAgICAqIENyZWF0ZSBhIG5ldyB7QGNvZGUgU2VyaWFsVHJlZX0gb2JqZWN0LCB0byByZXByZXNlbnQgYSB7QGNvZGUgQHNlcmlhbCB9IHRhZy4KICAgICAqIEBwYXJhbSBkZXNjcmlwdGlvbiB0aGUgZGVzY3JpcHRpb24gZm9yIHRoZSB0YWcKICAgICAqIEByZXR1cm4gYSB7QGNvZGUgU2VyaWFsVHJlZX0gb2JqZWN0CiAgICAgKi8KICAgIFNlcmlhbFRyZWUgbmV3U2VyaWFsVHJlZShMaXN0PD8gZXh0ZW5kcyBEb2NUcmVlPiBkZXNjcmlwdGlvbik7CgogICAgLyoqCiAgICAgKiBDcmVhdGUgYSBuZXcge0Bjb2RlIFNlcmlhbERhdGFUcmVlfSBvYmplY3QsIHRvIHJlcHJlc2VudCBhIHtAY29kZSBAc2VyaWFsRGF0YSB9IHRhZy4KICAgICAqIEBwYXJhbSBkZXNjcmlwdGlvbiB0aGUgZGVzY3JpcHRpb24gZm9yIHRoZSB0YWcKICAgICAqIEByZXR1cm4gYSB7QGNvZGUgU2VyaWFsRGF0YVRyZWV9IG9iamVjdAogICAgICovCiAgICBTZXJpYWxEYXRhVHJlZSBuZXdTZXJpYWxEYXRhVHJlZShMaXN0PD8gZXh0ZW5kcyBEb2NUcmVlPiBkZXNjcmlwdGlvbik7CgogICAgLyoqCiAgICAgKiBDcmVhdGUgYSBuZXcge0Bjb2RlIFNlcmlhbEZpZWxkVHJlZX0gb2JqZWN0LCB0byByZXByZXNlbnQgYSB7QGNvZGUgQHNlcmlhbEZpZWxkIH0gdGFnLgogICAgICogQHBhcmFtIG5hbWUgdGhlIG5hbWUgb2YgdGhlIGZpZWxkCiAgICAgKiBAcGFyYW0gdHlwZSB0aGUgdHlwZSBvZiB0aGUgZmllbGQKICAgICAqIEBwYXJhbSBkZXNjcmlwdGlvbiB0aGUgZGVzY3JpcHRpb24gb2YgdGhlIGZpZWxkCiAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIFNlcmlhbEZpZWxkVHJlZX0gb2JqZWN0CiAgICAgKi8KICAgIFNlcmlhbEZpZWxkVHJlZSBuZXdTZXJpYWxGaWVsZFRyZWUoSWRlbnRpZmllclRyZWUgbmFtZSwgUmVmZXJlbmNlVHJlZSB0eXBlLCBMaXN0PD8gZXh0ZW5kcyBEb2NUcmVlPiBkZXNjcmlwdGlvbik7CgogICAgLyoqCiAgICAgKiBDcmVhdGUgYSBuZXcge0Bjb2RlIFNpbmNlVHJlZX0gb2JqZWN0LCB0byByZXByZXNlbnQgYSB7QGNvZGUgQHNpbmNlIH0gdGFnLgogICAgICogQHBhcmFtIHRleHQgdGhlIGNvbnRlbnQgb2YgdGhlIHRhZwogICAgICogQHJldHVybiBhIHtAY29kZSBTaW5jZVRyZWV9IG9iamVjdAogICAgICovCiAgICBTaW5jZVRyZWUgbmV3U2luY2VUcmVlKExpc3Q8PyBleHRlbmRzIERvY1RyZWU+IHRleHQpOwoKICAgIC8qKgogICAgICogQ3JlYXRlIGEgbmV3IHtAY29kZSBTdGFydEVsZW1lbnRUcmVlfSBvYmplY3QsIHRvIHJlcHJlc2VudCB0aGUgc3RhcnQgb2YgYW4gSFRNTCBlbGVtZW50LgogICAgICogQHBhcmFtIG5hbWUgdGhlIG5hbWUgb2YgdGhlIEhUTUwgZWxlbWVudAogICAgICogQHBhcmFtIGF0dHJzIHRoZSBhdHRyaWJ1dGVzCiAgICAgKiBAcGFyYW0gc2VsZkNsb3NpbmcgdHJ1ZSBpZiB0aGUgc3RhcnQgZWxlbWVudCBpcyBtYXJrZWQgYXMgc2VsZi1jbG9zaW5nOyBvdGhlcndpc2UgZmFsc2UKICAgICAqIEByZXR1cm4gYSB7QGNvZGUgU3RhcnRFbGVtZW50VHJlZX0gb2JqZWN0CiAgICAgKi8KICAgIFN0YXJ0RWxlbWVudFRyZWUgbmV3U3RhcnRFbGVtZW50VHJlZShOYW1lIG5hbWUsIExpc3Q8PyBleHRlbmRzIERvY1RyZWU+IGF0dHJzLCBib29sZWFuIHNlbGZDbG9zaW5nKTsKCiAgICAvKioKICAgICAqIENyZWF0ZSBhIG5ldyB7QGNvZGUgVGV4dFRyZWV9IG9iamVjdCwgdG8gcmVwcmVzZW50IHNvbWUgcGxhaW4gdGV4dC4KICAgICAqIEBwYXJhbSB0ZXh0IHRoZSB0ZXh0CiAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIFRleHRUcmVlfSBvYmplY3QKICAgICAqLwogICAgVGV4dFRyZWUgbmV3VGV4dFRyZWUoU3RyaW5nIHRleHQpOwoKICAgIC8qKgogICAgICogQ3JlYXRlIGEgbmV3IHtAY29kZSBUaHJvd3NUcmVlfSBvYmplY3QsIHRvIHJlcHJlc2VudCBhIHtAY29kZSBAdGhyb3dzIH0gdGFnLgogICAgICogQHBhcmFtIG5hbWUgdGhlIG5hbWUgb2YgdGhlIGV4Y2VwdGlvbgogICAgICogQHBhcmFtIGRlc2NyaXB0aW9uIGEgZGVzY3JpcHRpb24gb2Ygd2h5IHRoZSBleGNlcHRpb24gbWlnaHQgYmUgdGhyb3duCiAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIFRocm93c1RyZWV9IG9iamVjdAogICAgICovCiAgICBUaHJvd3NUcmVlIG5ld1Rocm93c1RyZWUoUmVmZXJlbmNlVHJlZSBuYW1lLCBMaXN0PD8gZXh0ZW5kcyBEb2NUcmVlPiBkZXNjcmlwdGlvbik7CgogICAgLyoqCiAgICAgKiBDcmVhdGUgYSBuZXcge0Bjb2RlIFVua25vd25CbG9ja1RhZ1RyZWV9IG9iamVjdCwgdG8gcmVwcmVzZW50IGFuIHVucmVjb2duaXplZCBibG9jayB0YWcuCiAgICAgKiBAcGFyYW0gbmFtZSB0aGUgbmFtZSBvZiB0aGUgYmxvY2sgdGFnCiAgICAgKiBAcGFyYW0gY29udGVudCB0aGUgY29udGVudAogICAgICogQHJldHVybiBhbiB7QGNvZGUgVW5rbm93bkJsb2NrVGFnVHJlZX0gb2JqZWN0CiAgICAgKi8KICAgIFVua25vd25CbG9ja1RhZ1RyZWUgbmV3VW5rbm93bkJsb2NrVGFnVHJlZShOYW1lIG5hbWUsIExpc3Q8PyBleHRlbmRzIERvY1RyZWU+IGNvbnRlbnQpOwoKICAgIC8qKgogICAgICogQ3JlYXRlIGEgbmV3IHtAY29kZSBVbmtub3duSW5saW5lVGFnVHJlZX0gb2JqZWN0LCB0byByZXByZXNlbnQgYW4gdW5yZWNvZ25pemVkIGlubGluZSB0YWcuCiAgICAgKiBAcGFyYW0gbmFtZSB0aGUgbmFtZSBvZiB0aGUgaW5saW5lIHRhZwogICAgICogQHBhcmFtIGNvbnRlbnQgdGhlIGNvbnRlbnQKICAgICAqIEByZXR1cm4gYW4ge0Bjb2RlIFVua25vd25JbmxpbmVUYWdUcmVlfSBvYmplY3QKICAgICAqLwogICAgVW5rbm93bklubGluZVRhZ1RyZWUgbmV3VW5rbm93bklubGluZVRhZ1RyZWUoTmFtZSBuYW1lLCBMaXN0PD8gZXh0ZW5kcyBEb2NUcmVlPiBjb250ZW50KTsKCiAgICAvKioKICAgICAqIENyZWF0ZSBhIG5ldyB7QGNvZGUgVXNlc1RyZWV9IG9iamVjdCwgdG8gcmVwcmVzZW50IGEge0Bjb2RlIEB1c2VzIH0gdGFnLgogICAgICogQHBhcmFtIG5hbWUgdGhlIG5hbWUgb2YgdGhlIHNlcnZpY2UgdHlwZQogICAgICogQHBhcmFtIGRlc2NyaXB0aW9uIGEgZGVzY3JpcHRpb24gb2YgaG93IHRoZSBzZXJ2aWNlIHdpbGwgYmUgdXNlZAogICAgICogQHJldHVybiBhIHtAY29kZSBVc2VzVHJlZX0gb2JqZWN0CiAgICAgKi8KICAgIFVzZXNUcmVlIG5ld1VzZXNUcmVlKFJlZmVyZW5jZVRyZWUgbmFtZSwgTGlzdDw/IGV4dGVuZHMgRG9jVHJlZT4gZGVzY3JpcHRpb24pOwoKICAgIC8qKgogICAgICogQ3JlYXRlIGEgbmV3IHtAY29kZSBWYWx1ZVRyZWV9IG9iamVjdCwgdG8gcmVwcmVzZW50IGEge0Bjb2RlIHtAdmFsdWUgfSB9IHRhZy4KICAgICAqIEBwYXJhbSByZWYgYSByZWZlcmVuY2UgdG8gdGhlIHZhbHVlCiAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIFZhbHVlVHJlZX0gb2JqZWN0CiAgICAgKi8KICAgIFZhbHVlVHJlZSBuZXdWYWx1ZVRyZWUoUmVmZXJlbmNlVHJlZSByZWYpOwoKICAgIC8qKgogICAgICogQ3JlYXRlIGEgbmV3IHtAY29kZSBWZXJzaW9uVHJlZX0gb2JqZWN0LCB0byByZXByZXNlbnQgYSB7QGNvZGUge0B2ZXJzaW9uIH0gfSB0YWcuCiAgICAgKiBAcGFyYW0gdGV4dCB0aGUgY29udGVudCBvZiB0aGUgdGFnCiAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIFZlcnNpb25UcmVlfSBvYmplY3QKICAgICAqLwogICAgVmVyc2lvblRyZWUgbmV3VmVyc2lvblRyZWUoTGlzdDw/IGV4dGVuZHMgRG9jVHJlZT4gdGV4dCk7CgogICAgLyoqCiAgICAgKiBTZXQgdGhlIHBvc2l0aW9uIHRvIGJlIHJlY29yZGVkIGluIHN1YnNlcXVlbnQgdHJlZSBub2RlcyBjcmVhdGVkIGJ5IHRoaXMgZmFjdG9yeS4KICAgICAqIFRoZSBwb3NpdGlvbiBzaG91bGQgYmUgYSBjaGFyYWN0ZXIgb2Zmc2V0IHJlbGF0aXZlIHRvIHRoZSBiZWdpbm5pbmcgb2YgdGhlIHNvdXJjZSBmaWxlCiAgICAgKiBvciB7QGxpbmsgamF2YXgudG9vbHMuRGlhZ25vc3RpYyNOT1BPUyBOT1BPU30uCiAgICAgKiBAcGFyYW0gcG9zIHRoZSBwb3NpdGlvbgogICAgICogQHJldHVybiB0aGlzIG9iamVjdCwgdG8gZmFjaWxpdGF0ZSBtZXRob2QgY2hhaW5pbmcKICAgICAqLwogICAgRG9jVHJlZUZhY3RvcnkgYXQoaW50IHBvcyk7CgogICAgLyoqCiAgICAgKiBHZXQgdGhlIGZpcnN0IHNlbnRlbmNlIGNvbnRhaW5lZCBpbiBhIGxpc3Qgb2YgY29udGVudC4KICAgICAqIFRoZSBkZXRlcm1pbmF0aW9uIG9mIHRoZSBmaXJzdCBzZW50ZW5jZSBpcyBpbXBsZW1lbnRhdGlvbiBzcGVjaWZpYywgYW5kIG1heQogICAgICogaW52b2x2ZSB0aGUgdXNlIG9mIGEgbG9jYWxlLXNwZWNpZmljIHtAbGluayBqYXZhLnRleHQuQnJlYWtJdGVyYXRvciBCcmVha0l0ZXJhdG9yfQogICAgICogYW5kIG90aGVyIGhldXJpc3RpY3MuCiAgICAgKiBUaGUgcmVzdWx0aW5nIGxpc3QgbWF5IHNoYXJlIGEgY29tbW9uIHNldCBvZiBpbml0aWFsIGl0ZW1zIHdpdGggdGhlIGlucHV0IGxpc3QuCiAgICAgKiBAcGFyYW0gbGlzdCB0aGUgbGlzdAogICAgICogQHJldHVybiBhIGxpc3QgY29udGFpbmluZyB0aGUgZmlyc3Qgc2VudGVuY2Ugb2YgdGhlIGxpc3QuCiAgICAgKi8KICAgIExpc3Q8RG9jVHJlZT4gZ2V0Rmlyc3RTZW50ZW5jZShMaXN0PD8gZXh0ZW5kcyBEb2NUcmVlPiBsaXN0KTsKCn0KUEsDBAoAAAgAAAY7qUpS/Qiw7QwAAO0MAAAoAAAAY29tL3N1bi9zb3VyY2UvdXRpbC9UcmVlUGF0aFNjYW5uZXIuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNiwgMjAxNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnNvdXJjZS51dGlsOwoKaW1wb3J0IGNvbS5zdW4uc291cmNlLnRyZWUuKjsKCi8qKgogKiBBIFRyZWVWaXNpdG9yIHRoYXQgdmlzaXRzIGFsbCB0aGUgY2hpbGQgdHJlZSBub2RlcywgYW5kIHByb3ZpZGVzCiAqIHN1cHBvcnQgZm9yIG1haW50YWluaW5nIGEgcGF0aCBmb3IgdGhlIHBhcmVudCBub2Rlcy4KICogVG8gdmlzaXQgbm9kZXMgb2YgYSBwYXJ0aWN1bGFyIHR5cGUsIGp1c3Qgb3ZlcnJpZGUgdGhlCiAqIGNvcnJlc3BvbmRpbmcgdmlzaXRvclhZWiBtZXRob2QuCiAqIEluc2lkZSB5b3VyIG1ldGhvZCwgY2FsbCBzdXBlci52aXNpdFhZWiB0byB2aXNpdCBkZXNjZW5kYW50CiAqIG5vZGVzLgogKgogKiBAYXBpTm90ZQogKiBJbiBvcmRlciB0byBpbml0aWFsaXplIHRoZSAiY3VycmVudCBwYXRoIiwgdGhlIHNjYW4gbXVzdCBiZQogKiBzdGFydGVkIGJ5IGNhbGxpbmcgb25lIG9mIHRoZSB7QGNvZGUgc2Nhbn0gbWV0aG9kcy4KICoKICogQGF1dGhvciBKb25hdGhhbiBHaWJib25zCiAqIEBzaW5jZSAxLjYKICovCnB1YmxpYyBjbGFzcyBUcmVlUGF0aFNjYW5uZXI8UiwgUD4gZXh0ZW5kcyBUcmVlU2Nhbm5lcjxSLCBQPiB7CgogICAgLyoqCiAgICAgKiBTY2FucyBhIHRyZWUgZnJvbSBhIHBvc2l0aW9uIGlkZW50aWZpZWQgYnkgYSBUcmVlUGF0aC4KICAgICAqIEBwYXJhbSBwYXRoIHRoZSBwYXRoIGlkZW50aWZ5aW5nIHRoZSBub2RlIHRvIGJlIHNjYW5uZWQKICAgICAqIEBwYXJhbSBwIGEgcGFyYW1ldGVyIHZhbHVlIHBhc3NlZCB0byB2aXNpdCBtZXRob2RzCiAgICAgKiBAcmV0dXJuIHRoZSByZXN1bHQgdmFsdWUgZnJvbSB0aGUgdmlzaXQgbWV0aG9kCiAgICAgKi8KICAgIHB1YmxpYyBSIHNjYW4oVHJlZVBhdGggcGF0aCwgUCBwKSB7CiAgICAgICAgdGhpcy5wYXRoID0gcGF0aDsKICAgICAgICB0cnkgewogICAgICAgICAgICByZXR1cm4gcGF0aC5nZXRMZWFmKCkuYWNjZXB0KHRoaXMsIHApOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgIHRoaXMucGF0aCA9IG51bGw7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogU2NhbnMgYSBzaW5nbGUgbm9kZS4KICAgICAqIFRoZSBjdXJyZW50IHBhdGggaXMgdXBkYXRlZCBmb3IgdGhlIGR1cmF0aW9uIG9mIHRoZSBzY2FuLgogICAgICoKICAgICAqIEBhcGlOb3RlIFRoaXMgbWV0aG9kIHNob3VsZCBub3JtYWxseSBvbmx5IGJlIGNhbGxlZCBieSB0aGUKICAgICAqIHNjYW5uZXIncyB7QGNvZGUgdmlzaXR9IG1ldGhvZHMsIGFzIHBhcnQgb2YgYW4gb25nb2luZyBzY2FuCiAgICAgKiBpbml0aWF0ZWQgYnkge0BsaW5rICNzY2FuKFRyZWVQYXRoLE9iamVjdCkgc2NhbihUcmVlUGF0aCwgUCl9LgogICAgICogVGhlIG9uZSBleGNlcHRpb24gaXMgdGhhdCBpdCBtYXkgYWxzbyBiZSBjYWxsZWQgdG8gaW5pdGlhdGUKICAgICAqIGEgZnVsbCBzY2FuIG9mIGEge0BsaW5rIENvbXBpbGF0aW9uVW5pdFRyZWV9LgogICAgICoKICAgICAqIEByZXR1cm4gdGhlIHJlc3VsdCB2YWx1ZSBmcm9tIHRoZSB2aXNpdCBtZXRob2QKICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgUiBzY2FuKFRyZWUgdHJlZSwgUCBwKSB7CiAgICAgICAgaWYgKHRyZWUgPT0gbnVsbCkKICAgICAgICAgICAgcmV0dXJuIG51bGw7CgogICAgICAgIFRyZWVQYXRoIHByZXYgPSBwYXRoOwogICAgICAgIHBhdGggPSBuZXcgVHJlZVBhdGgocGF0aCwgdHJlZSk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgcmV0dXJuIHRyZWUuYWNjZXB0KHRoaXMsIHApOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgIHBhdGggPSBwcmV2OwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGN1cnJlbnQgcGF0aCBmb3IgdGhlIG5vZGUsIGFzIGJ1aWx0IHVwIGJ5IHRoZSBjdXJyZW50bHkKICAgICAqIGFjdGl2ZSBzZXQgb2Ygc2NhbiBjYWxscy4KICAgICAqIEByZXR1cm4gdGhlIGN1cnJlbnQgcGF0aAogICAgICovCiAgICBwdWJsaWMgVHJlZVBhdGggZ2V0Q3VycmVudFBhdGgoKSB7CiAgICAgICAgcmV0dXJuIHBhdGg7CiAgICB9CgogICAgcHJpdmF0ZSBUcmVlUGF0aCBwYXRoOwp9ClBLAwQKAAAIAAAGO6lKNpzyYnALAABwCwAAKwAAAGNvbS9zdW4vc291cmNlL3V0aWwvRG9jVHJlZVBhdGhTY2FubmVyLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDYsIDIwMTQsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi5zb3VyY2UudXRpbDsKCmltcG9ydCBjb20uc3VuLnNvdXJjZS5kb2N0cmVlLkRvY1RyZWU7CgovKioKICogQSBEb2NUcmVlVmlzaXRvciB0aGF0IHZpc2l0cyBhbGwgdGhlIGNoaWxkIHRyZWUgbm9kZXMsIGFuZCBwcm92aWRlcwogKiBzdXBwb3J0IGZvciBtYWludGFpbmluZyBhIHBhdGggZm9yIHRoZSBwYXJlbnQgbm9kZXMuCiAqIFRvIHZpc2l0IG5vZGVzIG9mIGEgcGFydGljdWxhciB0eXBlLCBqdXN0IG92ZXJyaWRlIHRoZQogKiBjb3JyZXNwb25kaW5nIHZpc2l0b3JYWVogbWV0aG9kLgogKiBJbnNpZGUgeW91ciBtZXRob2QsIGNhbGwgc3VwZXIudmlzaXRYWVogdG8gdmlzaXQgZGVzY2VuZGFudAogKiBub2Rlcy4KICoKICogQHNpbmNlIDEuOAogKi8KcHVibGljIGNsYXNzIERvY1RyZWVQYXRoU2Nhbm5lcjxSLCBQPiBleHRlbmRzIERvY1RyZWVTY2FubmVyPFIsIFA+IHsKICAgIC8qKgogICAgICogU2NhbnMgYSB0cmVlIGZyb20gYSBwb3NpdGlvbiBpZGVudGlmaWVkIGJ5IGEgdHJlZSBwYXRoLgogICAgICogQHBhcmFtIHBhdGggdGhlIHBhdGgKICAgICAqIEBwYXJhbSBwIGEgdmFsdWUgdG8gYmUgcGFzc2VkIHRvIHZpc2l0b3IgbWV0aG9kcwogICAgICogQHJldHVybiB0aGUgcmVzdWx0IHJldHVybmVkIGZyb20gdGhlIG1haW4gdmlzaXRvciBtZXRob2QKICAgICAqLwogICAgcHVibGljIFIgc2NhbihEb2NUcmVlUGF0aCBwYXRoLCBQIHApIHsKICAgICAgICB0aGlzLnBhdGggPSBwYXRoOwogICAgICAgIHRyeSB7CiAgICAgICAgICAgIHJldHVybiBwYXRoLmdldExlYWYoKS5hY2NlcHQodGhpcywgcCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgdGhpcy5wYXRoID0gbnVsbDsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBTY2FucyBhIHNpbmdsZSBub2RlLgogICAgICogVGhlIGN1cnJlbnQgcGF0aCBpcyB1cGRhdGVkIGZvciB0aGUgZHVyYXRpb24gb2YgdGhlIHNjYW4uCiAgICAgKiBAcGFyYW0gdHJlZSB0aGUgdHJlZSB0byBiZSBzY2FubmVkCiAgICAgKiBAcGFyYW0gcCBhIHZhbHVlIHRvIGJlIHBhc3NlZCB0byB2aXNpdG9yIG1ldGhvZHMKICAgICAqIEByZXR1cm4gdGhlIHJlc3VsdCByZXR1cm5lZCBmcm9tIHRoZSBtYWluIHZpc2l0b3IgbWV0aG9kCiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgc2NhbihEb2NUcmVlIHRyZWUsIFAgcCkgewogICAgICAgIGlmICh0cmVlID09IG51bGwpCiAgICAgICAgICAgIHJldHVybiBudWxsOwoKICAgICAgICBEb2NUcmVlUGF0aCBwcmV2ID0gcGF0aDsKICAgICAgICBwYXRoID0gbmV3IERvY1RyZWVQYXRoKHBhdGgsIHRyZWUpOwogICAgICAgIHRyeSB7CiAgICAgICAgICAgIHJldHVybiB0cmVlLmFjY2VwdCh0aGlzLCBwKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICBwYXRoID0gcHJldjsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBjdXJyZW50IHBhdGggZm9yIHRoZSBub2RlLCBhcyBidWlsdCB1cCBieSB0aGUgY3VycmVudGx5CiAgICAgKiBhY3RpdmUgc2V0IG9mIHNjYW4gY2FsbHMuCiAgICAgKiBAcmV0dXJuIHRoZSBjdXJyZW50IHBhdGgKICAgICAqLwogICAgcHVibGljIERvY1RyZWVQYXRoIGdldEN1cnJlbnRQYXRoKCkgewogICAgICAgIHJldHVybiBwYXRoOwogICAgfQoKICAgIHByaXZhdGUgRG9jVHJlZVBhdGggcGF0aDsKfQpQSwMECgAACAAABjupSpL79UGSFwAAkhcAACQAAABjb20vc3VuL3NvdXJjZS91dGlsL0RvY1RyZWVQYXRoLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDYsIDIwMTYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi5zb3VyY2UudXRpbDsKCmltcG9ydCBjb20uc3VuLnNvdXJjZS5kb2N0cmVlLkRvY0NvbW1lbnRUcmVlOwppbXBvcnQgY29tLnN1bi5zb3VyY2UuZG9jdHJlZS5Eb2NUcmVlOwoKaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKaW1wb3J0IGphdmEudXRpbC5PYmplY3RzOwoKLyoqCiAqIEEgcGF0aCBvZiB0cmVlIG5vZGVzLCB0eXBpY2FsbHkgdXNlZCB0byByZXByZXNlbnQgdGhlIHNlcXVlbmNlIG9mIGFuY2VzdG9yCiAqIG5vZGVzIG9mIGEgdHJlZSBub2RlIHVwIHRvIHRoZSB0b3AgbGV2ZWwgRG9jQ29tbWVudFRyZWUgbm9kZS4KICoKICogQHNpbmNlIDEuOAogKi8KcHVibGljIGNsYXNzIERvY1RyZWVQYXRoIGltcGxlbWVudHMgSXRlcmFibGU8RG9jVHJlZT4gewogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgZG9jdW1lbnRhdGlvbiB0cmVlIHBhdGggZm9yIGEgdHJlZSBub2RlIHdpdGhpbiBhIGNvbXBpbGF0aW9uIHVuaXQsCiAgICAgKiBvciB7QGNvZGUgbnVsbH0gaWYgdGhlIG5vZGUgaXMgbm90IGZvdW5kLgogICAgICogQHBhcmFtIHRyZWVQYXRoIHRoZSBwYXRoIGZvciB0aGUgbm9kZSB3aXRoIHdoaWNoIHRoZSBkb2MgY29tbWVudCBpcyBhc3NvY2lhdGVkCiAgICAgKiBAcGFyYW0gZG9jIHRoZSBkb2MgY29tbWVudCBhc3NvY2lhdGVkIHdpdGggdGhlIG5vZGUKICAgICAqIEBwYXJhbSB0YXJnZXQgYSBub2RlIHdpdGhpbiB0aGUgZG9jIGNvbW1lbnQKICAgICAqIEByZXR1cm4gYSBwYXRoIGlkZW50aWZ5aW5nIHRoZSB0YXJnZXQgd2l0aGluIHRoZSB0cmVlCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgRG9jVHJlZVBhdGggZ2V0UGF0aChUcmVlUGF0aCB0cmVlUGF0aCwgRG9jQ29tbWVudFRyZWUgZG9jLCBEb2NUcmVlIHRhcmdldCkgewogICAgICAgIHJldHVybiBnZXRQYXRoKG5ldyBEb2NUcmVlUGF0aCh0cmVlUGF0aCwgZG9jKSwgdGFyZ2V0KTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgYSBkb2N1bWVudGF0aW9uIHRyZWUgcGF0aCBmb3IgYSB0cmVlIG5vZGUgd2l0aGluIGEgc3VidHJlZQogICAgICogaWRlbnRpZmllZCBieSBhIERvY1RyZWVQYXRoIG9iamVjdCwgb3Ige0Bjb2RlIG51bGx9IGlmIHRoZSBub2RlIGlzIG5vdCBmb3VuZC4KICAgICAqIEBwYXJhbSBwYXRoIGEgcGF0aCBpZGVudGlmeWluZyBhIG5vZGUgd2l0aGluIGEgZG9jIGNvbW1lbnQgdHJlZQogICAgICogQHBhcmFtIHRhcmdldCBhIG5vZGUgdG8gYmUgbG9jYXRlZCB3aXRoaW4gdGhlIGdpdmVuIG5vZGUKICAgICAqIEByZXR1cm4gYSBwYXRoIGlkZW50aWZ5aW5nIHRoZSB0YXJnZXQgbm9kZQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIERvY1RyZWVQYXRoIGdldFBhdGgoRG9jVHJlZVBhdGggcGF0aCwgRG9jVHJlZSB0YXJnZXQpIHsKICAgICAgICBPYmplY3RzLnJlcXVpcmVOb25OdWxsKHBhdGgpOyAvL251bGwgY2hlY2sKICAgICAgICBPYmplY3RzLnJlcXVpcmVOb25OdWxsKHRhcmdldCk7IC8vbnVsbCBjaGVjawoKICAgICAgICBjbGFzcyBSZXN1bHQgZXh0ZW5kcyBFcnJvciB7CiAgICAgICAgICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNTk0MjA4ODIzNDU5NDkwNTYyNUw7CiAgICAgICAgICAgIERvY1RyZWVQYXRoIHBhdGg7CiAgICAgICAgICAgIFJlc3VsdChEb2NUcmVlUGF0aCBwYXRoKSB7CiAgICAgICAgICAgICAgICB0aGlzLnBhdGggPSBwYXRoOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBjbGFzcyBQYXRoRmluZGVyIGV4dGVuZHMgRG9jVHJlZVBhdGhTY2FubmVyPERvY1RyZWVQYXRoLERvY1RyZWU+IHsKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHB1YmxpYyBEb2NUcmVlUGF0aCBzY2FuKERvY1RyZWUgdHJlZSwgRG9jVHJlZSB0YXJnZXQpIHsKICAgICAgICAgICAgICAgIGlmICh0cmVlID09IHRhcmdldCkgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBSZXN1bHQobmV3IERvY1RyZWVQYXRoKGdldEN1cnJlbnRQYXRoKCksIHRhcmdldCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIHN1cGVyLnNjYW4odHJlZSwgdGFyZ2V0KTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKHBhdGguZ2V0TGVhZigpID09IHRhcmdldCkgewogICAgICAgICAgICByZXR1cm4gcGF0aDsKICAgICAgICB9CgogICAgICAgIHRyeSB7CiAgICAgICAgICAgIG5ldyBQYXRoRmluZGVyKCkuc2NhbihwYXRoLCB0YXJnZXQpOwogICAgICAgIH0gY2F0Y2ggKFJlc3VsdCByZXN1bHQpIHsKICAgICAgICAgICAgcmV0dXJuIHJlc3VsdC5wYXRoOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICAvKioKICAgICAqIENyZWF0ZXMgYSBEb2NUcmVlUGF0aCBmb3IgYSByb290IG5vZGUuCiAgICAgKgogICAgICogQHBhcmFtIHRyZWVQYXRoIHRoZSBUcmVlUGF0aCBmcm9tIHdoaWNoIHRoZSByb290IG5vZGUgd2FzIGNyZWF0ZWQuCiAgICAgKiBAcGFyYW0gdCB0aGUgRG9jQ29tbWVudFRyZWUgdG8gY3JlYXRlIHRoZSBwYXRoIGZvci4KICAgICAqLwogICAgcHVibGljIERvY1RyZWVQYXRoKFRyZWVQYXRoIHRyZWVQYXRoLCBEb2NDb21tZW50VHJlZSB0KSB7CiAgICAgICAgdGhpcy50cmVlUGF0aCA9IHRyZWVQYXRoOwogICAgICAgIHRoaXMuZG9jQ29tbWVudCA9IE9iamVjdHMucmVxdWlyZU5vbk51bGwodCk7CiAgICAgICAgdGhpcy5wYXJlbnQgPSBudWxsOwogICAgICAgIHRoaXMubGVhZiA9IHQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBDcmVhdGVzIGEgRG9jVHJlZVBhdGggZm9yIGEgY2hpbGQgbm9kZS4KICAgICAqIEBwYXJhbSBwIHRoZSBwYXJlbnQgbm9kZQogICAgICogQHBhcmFtIHQgdGhlIGNoaWxkIG5vZGUKICAgICAqLwogICAgcHVibGljIERvY1RyZWVQYXRoKERvY1RyZWVQYXRoIHAsIERvY1RyZWUgdCkgewogICAgICAgIGlmICh0LmdldEtpbmQoKSA9PSBEb2NUcmVlLktpbmQuRE9DX0NPTU1FTlQpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiVXNlIERvY1RyZWVQYXRoKFRyZWVQYXRoLCBEb2NDb21tZW50VHJlZSkgdG8gY29uc3RydWN0IERvY1RyZWVQYXRoIGZvciBhIERvY0NvbW1lbnRUcmVlLiIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHRyZWVQYXRoID0gcC50cmVlUGF0aDsKICAgICAgICAgICAgZG9jQ29tbWVudCA9IHAuZG9jQ29tbWVudDsKICAgICAgICAgICAgcGFyZW50ID0gcDsKICAgICAgICB9CiAgICAgICAgbGVhZiA9IHQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBUcmVlUGF0aCBhc3NvY2lhdGVkIHdpdGggdGhpcyBwYXRoLgogICAgICogQHJldHVybiB0aGUgVHJlZVBhdGggZm9yIHRoaXMgRG9jVHJlZVBhdGgKICAgICAqLwogICAgcHVibGljIFRyZWVQYXRoIGdldFRyZWVQYXRoKCkgewogICAgICAgIHJldHVybiB0cmVlUGF0aDsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIERvY0NvbW1lbnRUcmVlIGFzc29jaWF0ZWQgd2l0aCB0aGlzIHBhdGguCiAgICAgKiBAcmV0dXJuIHRoZSBEb2NDb21tZW50VHJlZSBmb3IgdGhpcyBEb2NUcmVlUGF0aAogICAgICovCiAgICBwdWJsaWMgRG9jQ29tbWVudFRyZWUgZ2V0RG9jQ29tbWVudCgpIHsKICAgICAgICByZXR1cm4gZG9jQ29tbWVudDsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGxlYWYgbm9kZSBmb3IgdGhpcyBwYXRoLgogICAgICogQHJldHVybiB0aGUgRG9jVHJlZSBmb3IgdGhpcyBEb2NUcmVlUGF0aAogICAgICovCiAgICBwdWJsaWMgRG9jVHJlZSBnZXRMZWFmKCkgewogICAgICAgIHJldHVybiBsZWFmOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgcGF0aCBmb3IgdGhlIGVuY2xvc2luZyBub2RlLCBvciB7QGNvZGUgbnVsbH0gaWYgdGhlcmUgaXMgbm8gZW5jbG9zaW5nIG5vZGUuCiAgICAgKiBAcmV0dXJuIERvY1RyZWVQYXRoIG9mIHBhcmVudAogICAgICovCiAgICBwdWJsaWMgRG9jVHJlZVBhdGggZ2V0UGFyZW50UGF0aCgpIHsKICAgICAgICByZXR1cm4gcGFyZW50OwogICAgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIEl0ZXJhdG9yPERvY1RyZWU+IGl0ZXJhdG9yKCkgewogICAgICAgIHJldHVybiBuZXcgSXRlcmF0b3I8RG9jVHJlZT4oKSB7CiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNOZXh0KCkgewogICAgICAgICAgICAgICAgcmV0dXJuIG5leHQgIT0gbnVsbDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHB1YmxpYyBEb2NUcmVlIG5leHQoKSB7CiAgICAgICAgICAgICAgICBEb2NUcmVlIHQgPSBuZXh0LmxlYWY7CiAgICAgICAgICAgICAgICBuZXh0ID0gbmV4dC5wYXJlbnQ7CiAgICAgICAgICAgICAgICByZXR1cm4gdDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHB1YmxpYyB2b2lkIHJlbW92ZSgpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBwcml2YXRlIERvY1RyZWVQYXRoIG5leHQgPSBEb2NUcmVlUGF0aC50aGlzOwogICAgICAgIH07CiAgICB9CgogICAgcHJpdmF0ZSBmaW5hbCBUcmVlUGF0aCB0cmVlUGF0aDsKICAgIHByaXZhdGUgZmluYWwgRG9jQ29tbWVudFRyZWUgZG9jQ29tbWVudDsKICAgIHByaXZhdGUgZmluYWwgRG9jVHJlZSBsZWFmOwogICAgcHJpdmF0ZSBmaW5hbCBEb2NUcmVlUGF0aCBwYXJlbnQ7Cn0KUEsDBAoAAAgAAAY7qUqpSKyvCRkAAAkZAAAiAAAAY29tL3N1bi9zb3VyY2UvdXRpbC9KYXZhY1Rhc2suamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAxNCwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnNvdXJjZS51dGlsOwoKaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CgppbXBvcnQgamF2YXguYW5ub3RhdGlvbi5wcm9jZXNzaW5nLlByb2Nlc3NpbmdFbnZpcm9ubWVudDsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC5FbGVtZW50OwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC50eXBlLlR5cGVNaXJyb3I7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLnV0aWwuRWxlbWVudHM7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLnV0aWwuVHlwZXM7CmltcG9ydCBqYXZheC50b29scy5KYXZhQ29tcGlsZXIuQ29tcGlsYXRpb25UYXNrOwppbXBvcnQgamF2YXgudG9vbHMuSmF2YUZpbGVPYmplY3Q7CgppbXBvcnQgY29tLnN1bi5zb3VyY2UudHJlZS5Db21waWxhdGlvblVuaXRUcmVlOwppbXBvcnQgY29tLnN1bi5zb3VyY2UudHJlZS5UcmVlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5hcGkuQmFzaWNKYXZhY1Rhc2s7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnByb2Nlc3NpbmcuSmF2YWNQcm9jZXNzaW5nRW52aXJvbm1lbnQ7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuQ29udGV4dDsKCi8qKgogKiBQcm92aWRlcyBhY2Nlc3MgdG8gZnVuY3Rpb25hbGl0eSBzcGVjaWZpYyB0byB0aGUgSkRLIEphdmEgQ29tcGlsZXIsIGphdmFjLgogKgogKiBAYXV0aG9yIFBldGVyIHZvbiBkZXIgQWgmZWFjdXRlOwogKiBAYXV0aG9yIEpvbmF0aGFuIEdpYmJvbnMKICogQHNpbmNlIDEuNgogKi8KcHVibGljIGFic3RyYWN0IGNsYXNzIEphdmFjVGFzayBpbXBsZW1lbnRzIENvbXBpbGF0aW9uVGFzayB7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSB7QGNvZGUgSmF2YWNUYXNrfSBmb3IgYSB7QGNvZGUgUHJvY2Vzc2luZ0Vudmlyb25tZW50fS4KICAgICAqIElmIHRoZSBjb21waWxlciBpcyBiZWluZyBpbnZva2VkIHVzaW5nIGEKICAgICAqIHtAbGluayBqYXZheC50b29scy5KYXZhQ29tcGlsZXIuQ29tcGlsYXRpb25UYXNrIENvbXBpbGF0aW9uVGFza30sCiAgICAgKiB0aGVuIHRoYXQgdGFzayB3aWxsIGJlIHJldHVybmVkLgogICAgICogQHBhcmFtIHByb2Nlc3NpbmdFbnZpcm9ubWVudCB0aGUgcHJvY2Vzc2luZyBlbnZpcm9ubWVudAogICAgICogQHJldHVybiB0aGUge0Bjb2RlIEphdmFjVGFza30gZm9yIGEge0Bjb2RlIFByb2Nlc3NpbmdFbnZpcm9ubWVudH0KICAgICAqIEBzaW5jZSAxLjgKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBKYXZhY1Rhc2sgaW5zdGFuY2UoUHJvY2Vzc2luZ0Vudmlyb25tZW50IHByb2Nlc3NpbmdFbnZpcm9ubWVudCkgewogICAgICAgIGlmICghcHJvY2Vzc2luZ0Vudmlyb25tZW50LmdldENsYXNzKCkuZ2V0TmFtZSgpLmVxdWFscygKICAgICAgICAgICAgICAgICJjb20uc3VuLnRvb2xzLmphdmFjLnByb2Nlc3NpbmcuSmF2YWNQcm9jZXNzaW5nRW52aXJvbm1lbnQiKSkKICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIENvbnRleHQgYyA9ICgoSmF2YWNQcm9jZXNzaW5nRW52aXJvbm1lbnQpIHByb2Nlc3NpbmdFbnZpcm9ubWVudCkuZ2V0Q29udGV4dCgpOwogICAgICAgIEphdmFjVGFzayB0ID0gYy5nZXQoSmF2YWNUYXNrLmNsYXNzKTsKICAgICAgICByZXR1cm4gKHQgIT0gbnVsbCkgPyB0IDogbmV3IEJhc2ljSmF2YWNUYXNrKGMsIHRydWUpOwogICAgfQoKICAgIC8qKgogICAgICogUGFyc2VzIHRoZSBzcGVjaWZpZWQgZmlsZXMgcmV0dXJuaW5nIGEgbGlzdCBvZiBhYnN0cmFjdCBzeW50YXggdHJlZXMuCiAgICAgKgogICAgICogQHJldHVybiBhIGxpc3Qgb2YgYWJzdHJhY3Qgc3ludGF4IHRyZWVzCiAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIGFuIHVuaGFuZGxlZCBJL08gZXJyb3Igb2NjdXJyZWQgaW4gdGhlIGNvbXBpbGVyLgogICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhlIG9wZXJhdGlvbiBjYW5ub3QgYmUgcGVyZm9ybWVkIGF0IHRoaXMgdGltZS4KICAgICAqLwogICAgcHVibGljIGFic3RyYWN0IEl0ZXJhYmxlPD8gZXh0ZW5kcyBDb21waWxhdGlvblVuaXRUcmVlPiBwYXJzZSgpCiAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uOwoKICAgIC8qKgogICAgICogQ29tcGxldGVzIGFsbCBhbmFseXNpcy4KICAgICAqCiAgICAgKiBAcmV0dXJuIGEgbGlzdCBvZiBlbGVtZW50cyB0aGF0IHdlcmUgYW5hbHl6ZWQKICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgYW4gdW5oYW5kbGVkIEkvTyBlcnJvciBvY2N1cnJlZCBpbiB0aGUgY29tcGlsZXIuCiAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB0aGUgb3BlcmF0aW9uIGNhbm5vdCBiZSBwZXJmb3JtZWQgYXQgdGhpcyB0aW1lLgogICAgICovCiAgICBwdWJsaWMgYWJzdHJhY3QgSXRlcmFibGU8PyBleHRlbmRzIEVsZW1lbnQ+IGFuYWx5emUoKSB0aHJvd3MgSU9FeGNlcHRpb247CgogICAgLyoqCiAgICAgKiBHZW5lcmF0ZXMgY29kZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIGEgbGlzdCBvZiBmaWxlcyB0aGF0IHdlcmUgZ2VuZXJhdGVkCiAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIGFuIHVuaGFuZGxlZCBJL08gZXJyb3Igb2NjdXJyZWQgaW4gdGhlIGNvbXBpbGVyLgogICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhlIG9wZXJhdGlvbiBjYW5ub3QgYmUgcGVyZm9ybWVkIGF0IHRoaXMgdGltZS4KICAgICAqLwogICAgcHVibGljIGFic3RyYWN0IEl0ZXJhYmxlPD8gZXh0ZW5kcyBKYXZhRmlsZU9iamVjdD4gZ2VuZXJhdGUoKSB0aHJvd3MgSU9FeGNlcHRpb247CgogICAgLyoqCiAgICAgKiBTZXRzIGEgc3BlY2lmaWVkIGxpc3RlbmVyIHRvIHJlY2VpdmUgbm90aWZpY2F0aW9uIG9mIGV2ZW50cwogICAgICogZGVzY3JpYmluZyB0aGUgcHJvZ3Jlc3Mgb2YgdGhpcyBjb21waWxhdGlvbiB0YXNrLgogICAgICoKICAgICAqIElmIGFub3RoZXIgbGlzdGVuZXIgaXMgcmVjZWl2aW5nIG5vdGlmaWNhdGlvbnMgYXMgYSByZXN1bHQgb2YgYSBwcmlvcgogICAgICogY2FsbCBvZiB0aGlzIG1ldGhvZCwgdGhlbiB0aGF0IGxpc3RlbmVyIHdpbGwgbm8gbG9uZ2VyIHJlY2VpdmUgbm90aWZpY2F0aW9ucy4KICAgICAqCiAgICAgKiBJbmZvcm1hbGx5LCB0aGlzIG1ldGhvZCBpcyBlcXVpdmFsZW50IHRvIGNhbGxpbmcge0Bjb2RlIHJlbW92ZVRhc2tMaXN0ZW5lcn0gZm9yCiAgICAgKiBhbnkgbGlzdGVuZXIgdGhhdCBoYXMgYmVlbiBwcmV2aW91c2x5IHNldCwgZm9sbG93ZWQgYnkge0Bjb2RlIGFkZFRhc2tMaXN0ZW5lcn0KICAgICAqIGZvciB0aGUgbmV3IGxpc3RlbmVyLgogICAgICoKICAgICAqIEBwYXJhbSB0YXNrTGlzdGVuZXIgdGhlIHRhc2sgbGlzdGVuZXIKICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQgbGlzdGVuZXIgaGFzIGFscmVhZHkgYmVlbiBhZGRlZC4KICAgICAqLwogICAgcHVibGljIGFic3RyYWN0IHZvaWQgc2V0VGFza0xpc3RlbmVyKFRhc2tMaXN0ZW5lciB0YXNrTGlzdGVuZXIpOwoKICAgIC8qKgogICAgICogQWRkcyBhIHNwZWNpZmllZCBsaXN0ZW5lciBzbyB0aGF0IGl0IHJlY2VpdmVzIG5vdGlmaWNhdGlvbiBvZiBldmVudHMKICAgICAqIGRlc2NyaWJpbmcgdGhlIHByb2dyZXNzIG9mIHRoaXMgY29tcGlsYXRpb24gdGFzay4KICAgICAqCiAgICAgKiBUaGlzIG1ldGhvZCBtYXkgYmUgY2FsbGVkIGF0IGFueSB0aW1lIGJlZm9yZSBvciBkdXJpbmcgdGhlIGNvbXBpbGF0aW9uLgogICAgICoKICAgICAqIEBwYXJhbSB0YXNrTGlzdGVuZXIgdGhlIHRhc2sgbGlzdGVuZXIKICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoZSBzcGVjaWZpZWQgbGlzdGVuZXIgaGFzIGFscmVhZHkgYmVlbiBhZGRlZC4KICAgICAqIEBzaW5jZSAxLjgKICAgICAqLwogICAgcHVibGljIGFic3RyYWN0IHZvaWQgYWRkVGFza0xpc3RlbmVyKFRhc2tMaXN0ZW5lciB0YXNrTGlzdGVuZXIpOwoKICAgIC8qKgogICAgICogUmVtb3ZlcyB0aGUgc3BlY2lmaWVkIGxpc3RlbmVyIHNvIHRoYXQgaXQgbm8gbG9uZ2VyIHJlY2VpdmVzCiAgICAgKiBub3RpZmljYXRpb24gb2YgZXZlbnRzIGRlc2NyaWJpbmcgdGhlIHByb2dyZXNzIG9mIHRoaXMKICAgICAqIGNvbXBpbGF0aW9uIHRhc2suCiAgICAgKgogICAgICogVGhpcyBtZXRob2QgbWF5IGJlIGNhbGxlZCBhdCBhbnkgdGltZSBiZWZvcmUgb3IgZHVyaW5nIHRoZSBjb21waWxhdGlvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gdGFza0xpc3RlbmVyIHRoZSB0YXNrIGxpc3RlbmVyCiAgICAgKiBAc2luY2UgMS44CiAgICAgKi8KICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHJlbW92ZVRhc2tMaXN0ZW5lcihUYXNrTGlzdGVuZXIgdGFza0xpc3RlbmVyKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgYSB0eXBlIG1pcnJvciBvZiB0aGUgdHJlZSBub2RlIGRldGVybWluZWQgYnkgdGhlIHNwZWNpZmllZCBwYXRoLgogICAgICogVGhpcyBtZXRob2QgaGFzIGJlZW4gc3VwZXJjZWRlZCBieSBtZXRob2RzIG9uCiAgICAgKiB7QGxpbmsgY29tLnN1bi5zb3VyY2UudXRpbC5UcmVlcyBUcmVlc30uCiAgICAgKgogICAgICogQHBhcmFtIHBhdGggdGhlIHBhdGgKICAgICAqIEByZXR1cm4gdGhlIHR5cGUgbWlycm9yCiAgICAgKiBAc2VlIGNvbS5zdW4uc291cmNlLnV0aWwuVHJlZXMjZ2V0VHlwZU1pcnJvcgogICAgICovCiAgICBwdWJsaWMgYWJzdHJhY3QgVHlwZU1pcnJvciBnZXRUeXBlTWlycm9yKEl0ZXJhYmxlPD8gZXh0ZW5kcyBUcmVlPiBwYXRoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgYSB1dGlsaXR5IG9iamVjdCBmb3IgZGVhbGluZyB3aXRoIHByb2dyYW0gZWxlbWVudHMuCiAgICAgKgogICAgICogQHJldHVybiBhIHV0aWxpdHkgb2JqZWN0IGZvciBkZWFsaW5nIHdpdGggcHJvZ3JhbSBlbGVtZW50cwogICAgICovCiAgICBwdWJsaWMgYWJzdHJhY3QgRWxlbWVudHMgZ2V0RWxlbWVudHMoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgYSB1dGlsaXR5IG9iamVjdCBmb3IgZGVhbGluZyB3aXRoIHR5cGUgbWlycm9ycy4KICAgICAqCiAgICAgKiBAcmV0dXJuIHRoZSB1dGlsaXR5IG9iamVjdCBmb3IgZGVhbGluZyB3aXRoIHR5cGUgbWlycm9ycwogICAgICovCiAgICBwdWJsaWMgYWJzdHJhY3QgVHlwZXMgZ2V0VHlwZXMoKTsKfQpQSwMECgAACAAABjupSsn2ZjmGHwAAhh8AACEAAABjb20vc3VuL3NvdXJjZS91dGlsL0RvY1RyZWVzLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTEsIDIwMTcsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi5zb3VyY2UudXRpbDsKCmltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwppbXBvcnQgamF2YS50ZXh0LkJyZWFrSXRlcmF0b3I7CmltcG9ydCBqYXZhLnV0aWwuTGlzdDsKCmltcG9ydCBqYXZheC5hbm5vdGF0aW9uLnByb2Nlc3NpbmcuUHJvY2Vzc2luZ0Vudmlyb25tZW50OwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5lbGVtZW50LkVsZW1lbnQ7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuUGFja2FnZUVsZW1lbnQ7CmltcG9ydCBqYXZheC50b29scy5EaWFnbm9zdGljOwppbXBvcnQgamF2YXgudG9vbHMuRmlsZU9iamVjdDsKaW1wb3J0IGphdmF4LnRvb2xzLkphdmFDb21waWxlci5Db21waWxhdGlvblRhc2s7CgppbXBvcnQgY29tLnN1bi5zb3VyY2UuZG9jdHJlZS5Eb2NDb21tZW50VHJlZTsKaW1wb3J0IGNvbS5zdW4uc291cmNlLmRvY3RyZWUuRG9jVHJlZTsKCi8qKgogKiBQcm92aWRlcyBhY2Nlc3MgdG8gc3ludGF4IHRyZWVzIGZvciBkb2MgY29tbWVudHMuCiAqCiAqIEBzaW5jZSAxLjgKICovCnB1YmxpYyBhYnN0cmFjdCBjbGFzcyBEb2NUcmVlcyBleHRlbmRzIFRyZWVzIHsKICAgIC8qKgogICAgICogUmV0dXJucyBhIERvY1RyZWVzIG9iamVjdCBmb3IgYSBnaXZlbiBDb21waWxhdGlvblRhc2suCiAgICAgKiBAcGFyYW0gdGFzayB0aGUgY29tcGlsYXRpb24gdGFzayBmb3Igd2hpY2ggdG8gZ2V0IHRoZSBUcmVlcyBvYmplY3QKICAgICAqIEByZXR1cm4gdGhlIERvY1RyZWVzIG9iamVjdAogICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgdGhlIHRhc2sgZG9lcyBub3Qgc3VwcG9ydCB0aGUgVHJlZXMgQVBJLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIERvY1RyZWVzIGluc3RhbmNlKENvbXBpbGF0aW9uVGFzayB0YXNrKSB7CiAgICAgICAgcmV0dXJuIChEb2NUcmVlcykgVHJlZXMuaW5zdGFuY2UodGFzayk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgRG9jVHJlZXMgb2JqZWN0IGZvciBhIGdpdmVuIFByb2Nlc3NpbmdFbnZpcm9ubWVudC4KICAgICAqIEBwYXJhbSBlbnYgdGhlIHByb2Nlc3NpbmcgZW52aXJvbm1lbnQgZm9yIHdoaWNoIHRvIGdldCB0aGUgVHJlZXMgb2JqZWN0CiAgICAgKiBAcmV0dXJuIHRoZSBEb2NUcmVlcyBvYmplY3QKICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHRoZSBlbnYgZG9lcyBub3Qgc3VwcG9ydCB0aGUgVHJlZXMgQVBJLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIERvY1RyZWVzIGluc3RhbmNlKFByb2Nlc3NpbmdFbnZpcm9ubWVudCBlbnYpIHsKICAgICAgICBpZiAoIWVudi5nZXRDbGFzcygpLmdldE5hbWUoKS5lcXVhbHMoImNvbS5zdW4udG9vbHMuamF2YWMucHJvY2Vzc2luZy5KYXZhY1Byb2Nlc3NpbmdFbnZpcm9ubWVudCIpKQogICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgcmV0dXJuIChEb2NUcmVlcykgZ2V0SmF2YWNUcmVlcyhQcm9jZXNzaW5nRW52aXJvbm1lbnQuY2xhc3MsIGVudik7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBicmVhayBpdGVyYXRvciB1c2VkIHRvIGNvbXB1dGUgdGhlIGZpcnN0IHNlbnRlbmNlIG9mCiAgICAgKiBkb2N1bWVudGF0aW9uIGNvbW1lbnRzLgogICAgICogUmV0dXJucyB7QGNvZGUgbnVsbH0gaWYgbm9uZSBoYXMgYmVlbiBzcGVjaWZpZWQuCiAgICAgKiBAcmV0dXJuIHRoZSBicmVhayBpdGVyYXRvcgogICAgICoKICAgICAqIEBzaW5jZSA5CiAgICAgKi8KICAgIHB1YmxpYyBhYnN0cmFjdCBCcmVha0l0ZXJhdG9yIGdldEJyZWFrSXRlcmF0b3IoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGRvYyBjb21tZW50IHRyZWUsIGlmIGFueSwgZm9yIHRoZSBUcmVlIG5vZGUgaWRlbnRpZmllZCBieSBhIGdpdmVuIFRyZWVQYXRoLgogICAgICogUmV0dXJucyB7QGNvZGUgbnVsbH0gaWYgbm8gZG9jIGNvbW1lbnQgd2FzIGZvdW5kLgogICAgICogQHBhcmFtIHBhdGggdGhlIHBhdGggZm9yIHRoZSB0cmVlIG5vZGUKICAgICAqIEByZXR1cm4gdGhlIGRvYyBjb21tZW50IHRyZWUKICAgICAqLwogICAgcHVibGljIGFic3RyYWN0IERvY0NvbW1lbnRUcmVlIGdldERvY0NvbW1lbnRUcmVlKFRyZWVQYXRoIHBhdGgpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgZG9jIGNvbW1lbnQgdHJlZSBvZiB0aGUgZ2l2ZW4gZWxlbWVudC4KICAgICAqIFJldHVybnMge0Bjb2RlIG51bGx9IGlmIG5vIGRvYyBjb21tZW50IHdhcyBmb3VuZC4KICAgICAqIEBwYXJhbSBlIGFuIGVsZW1lbnQgd2hvc2UgZG9jdW1lbnRhdGlvbiBpcyByZXF1aXJlZAogICAgICogQHJldHVybiB0aGUgZG9jIGNvbW1lbnQgdHJlZQogICAgICoKICAgICAqIEBzaW5jZSA5CiAgICAgKi8KICAgIHB1YmxpYyBhYnN0cmFjdCBEb2NDb21tZW50VHJlZSBnZXREb2NDb21tZW50VHJlZShFbGVtZW50IGUpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgZG9jIGNvbW1lbnQgdHJlZSBvZiB0aGUgZ2l2ZW4gZmlsZS4gVGhlIGZpbGUgbXVzdCBiZQogICAgICogYW4gSFRNTCBmaWxlLCBpbiB3aGljaCBjYXNlIHRoZSBkb2MgY29tbWVudCB0cmVlIHJlcHJlc2VudHMgdGhlCiAgICAgKiBjb250ZW50cyBvZiB0aGUgJmx0O2JvZHkmZ3Q7IHRhZywgYW5kIGFueSBlbmNsb3NpbmcgdGFncyBhcmUgaWdub3JlZC4KICAgICAqIFJldHVybnMge0Bjb2RlIG51bGx9IGlmIG5vIGRvYyBjb21tZW50IHdhcyBmb3VuZC4KICAgICAqIEZ1dHVyZSByZWxlYXNlcyBtYXkgc3VwcG9ydCBhZGRpdGlvbmFsIGZpbGUgdHlwZXMuCiAgICAgKgogICAgICogQHBhcmFtIGZpbGVPYmplY3QgdGhlIGNvbnRlbnQgY29udGFpbmVyCiAgICAgKiBAcmV0dXJuIHRoZSBkb2MgY29tbWVudCB0cmVlCiAgICAgKgogICAgICogQHNpbmNlIDkKICAgICAqLwogICAgcHVibGljIGFic3RyYWN0IERvY0NvbW1lbnRUcmVlIGdldERvY0NvbW1lbnRUcmVlKEZpbGVPYmplY3QgZmlsZU9iamVjdCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBkb2MgY29tbWVudCB0cmVlIG9mIHRoZSBnaXZlbiBmaWxlIHdob3NlIHBhdGggaXMKICAgICAqIHNwZWNpZmllZCByZWxhdGl2ZSB0byB0aGUgZ2l2ZW4gZWxlbWVudC4gVGhlIGZpbGUgbXVzdCBiZSBhbiBIVE1MCiAgICAgKiBmaWxlLCBpbiB3aGljaCBjYXNlIHRoZSBkb2MgY29tbWVudCB0cmVlIHJlcHJlc2VudHMgdGhlIGNvbnRlbnRzCiAgICAgKiBvZiB0aGUgJmx0O2JvZHkmZ3Q7IHRhZywgYW5kIGFueSBlbmNsb3NpbmcgdGFncyBhcmUgaWdub3JlZC4KICAgICAqIFJldHVybnMge0Bjb2RlIG51bGx9IGlmIG5vIGRvYyBjb21tZW50IHdhcyBmb3VuZC4KICAgICAqIEZ1dHVyZSByZWxlYXNlcyBtYXkgc3VwcG9ydCBhZGRpdGlvbmFsIGZpbGUgdHlwZXMuCiAgICAgKgogICAgICogQHBhcmFtIGUgYW4gZWxlbWVudCB3aG9zZSBwYXRoIGlzIHVzZWQgYXMgYSByZWZlcmVuY2UKICAgICAqIEBwYXJhbSByZWxhdGl2ZVBhdGggdGhlIHJlbGF0aXZlIHBhdGggZnJvbSB0aGUgRWxlbWVudAogICAgICogQHJldHVybiB0aGUgZG9jIGNvbW1lbnQgdHJlZQogICAgICogQHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIGlmIGFuIGV4Y2VwdGlvbiBvY2N1cnMKICAgICAqCiAgICAgKiBAc2luY2UgOQogICAgICovCiAgICBwdWJsaWMgYWJzdHJhY3QgRG9jQ29tbWVudFRyZWUgZ2V0RG9jQ29tbWVudFRyZWUoRWxlbWVudCBlLCBTdHJpbmcgcmVsYXRpdmVQYXRoKSB0aHJvd3MgSU9FeGNlcHRpb247CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgZG9jIHRyZWUgcGF0aCBjb250YWluaW5nIHRoZSBkb2MgY29tbWVudCB0cmVlIG9mIHRoZSBnaXZlbiBmaWxlLgogICAgICogVGhlIGZpbGUgbXVzdCBiZSBhbiBIVE1MIGZpbGUsIGluIHdoaWNoIGNhc2UgdGhlIGRvYyBjb21tZW50IHRyZWUgcmVwcmVzZW50cwogICAgICogdGhlIGNvbnRlbnRzIG9mIHRoZSB7QGNvZGUgPGJvZHk+fSB0YWcsIGFuZCBhbnkgZW5jbG9zaW5nIHRhZ3MgYXJlIGlnbm9yZWQuCiAgICAgKiBBbnkgcmVmZXJlbmNlcyB0byBzb3VyY2UgY29kZSBlbGVtZW50cyBjb250YWluZWQgaW4ge0Bjb2RlIEBzZWV9IGFuZAogICAgICoge0Bjb2RlIHtAbGlua319IHRhZ3MgaW4gdGhlIGRvYyBjb21tZW50IHRyZWUgd2lsbCBiZSBldmFsdWF0ZWQgaW4gdGhlCiAgICAgKiBjb250ZXh0IG9mIHRoZSBnaXZlbiBwYWNrYWdlIGVsZW1lbnQuCiAgICAgKiBSZXR1cm5zIHtAY29kZSBudWxsfSBpZiBubyBkb2MgY29tbWVudCB3YXMgZm91bmQuCiAgICAgKgogICAgICogQHBhcmFtIGZpbGVPYmplY3QgYSBmaWxlIG9iamVjdCBlbmNhcHN1bGF0aW5nIHRoZSBIVE1MIGNvbnRlbnQKICAgICAqIEBwYXJhbSBwYWNrYWdlRWxlbWVudCBhIHBhY2thZ2UgZWxlbWVudCB0byBhc3NvY2lhdGUgd2l0aCB0aGUgZ2l2ZW4gZmlsZSBvYmplY3QKICAgICAqIHJlcHJlc2VudGluZyBhIGxlZ2FjeSBwYWNrYWdlLmh0bWwsIG51bGwgb3RoZXJ3aXNlCiAgICAgKiBAcmV0dXJuIGEgZG9jIHRyZWUgcGF0aCBjb250YWluaW5nIHRoZSBkb2MgY29tbWVudCBwYXJzZWQgZnJvbSB0aGUgZ2l2ZW4gZmlsZQogICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgdGhlIGZpbGVPYmplY3QgaXMgbm90IGFuIEhUTUwgZmlsZQogICAgICoKICAgICAqIEBzaW5jZSA5CiAgICAgKi8KICAgIHB1YmxpYyBhYnN0cmFjdCBEb2NUcmVlUGF0aCBnZXREb2NUcmVlUGF0aChGaWxlT2JqZWN0IGZpbGVPYmplY3QsIFBhY2thZ2VFbGVtZW50IHBhY2thZ2VFbGVtZW50KTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGxhbmd1YWdlIG1vZGVsIGVsZW1lbnQgcmVmZXJyZWQgdG8gYnkgdGhlIGxlYWYgbm9kZSBvZiB0aGUgZ2l2ZW4KICAgICAqIHtAbGluayBEb2NUcmVlUGF0aH0sIG9yIHtAY29kZSBudWxsfSBpZiB1bmtub3duLgogICAgICogQHBhcmFtIHBhdGggdGhlIHBhdGggZm9yIHRoZSB0cmVlIG5vZGUKICAgICAqIEByZXR1cm4gdGhlIGVsZW1lbnQKICAgICAqLwogICAgcHVibGljIGFic3RyYWN0IEVsZW1lbnQgZ2V0RWxlbWVudChEb2NUcmVlUGF0aCBwYXRoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGxpc3Qgb2Yge0BsaW5rIERvY1RyZWV9IHJlcHJlc2VudGluZyB0aGUgZmlyc3Qgc2VudGVuY2Ugb2YKICAgICAqIGEgY29tbWVudC4KICAgICAqCiAgICAgKiBAcGFyYW0gbGlzdCB0aGUgRG9jVHJlZSBsaXN0IHRvIGludGVycm9nYXRlCiAgICAgKiBAcmV0dXJuIHRoZSBmaXJzdCBzZW50ZW5jZQogICAgICoKICAgICAqIEBzaW5jZSA5CiAgICAgKi8KICAgIHB1YmxpYyBhYnN0cmFjdCBMaXN0PERvY1RyZWU+IGdldEZpcnN0U2VudGVuY2UoTGlzdDw/IGV4dGVuZHMgRG9jVHJlZT4gbGlzdCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgdXRpbGl0eSBvYmplY3QgZm9yIGFjY2Vzc2luZyB0aGUgc291cmNlIHBvc2l0aW9ucwogICAgICogb2YgZG9jdW1lbnRhdGlvbiB0cmVlIG5vZGVzLgogICAgICogQHJldHVybiB0aGUgdXRpbGl0eSBvYmplY3QKICAgICAqLwogICAgcHVibGljIGFic3RyYWN0IERvY1NvdXJjZVBvc2l0aW9ucyBnZXRTb3VyY2VQb3NpdGlvbnMoKTsKCiAgICAvKioKICAgICAqIFByaW50cyBhIG1lc3NhZ2Ugb2YgdGhlIHNwZWNpZmllZCBraW5kIGF0IHRoZSBsb2NhdGlvbiBvZiB0aGUKICAgICAqIHRyZWUgd2l0aGluIHRoZSBwcm92aWRlZCBjb21waWxhdGlvbiB1bml0CiAgICAgKgogICAgICogQHBhcmFtIGtpbmQgdGhlIGtpbmQgb2YgbWVzc2FnZQogICAgICogQHBhcmFtIG1zZyAgdGhlIG1lc3NhZ2UsIG9yIGFuIGVtcHR5IHN0cmluZyBpZiBub25lCiAgICAgKiBAcGFyYW0gdCAgICB0aGUgdHJlZSB0byB1c2UgYXMgYSBwb3NpdGlvbiBoaW50CiAgICAgKiBAcGFyYW0gYyAgICB0aGUgZG9jIGNvbW1lbnQgdHJlZSB0byB1c2UgYXMgYSBwb3NpdGlvbiBoaW50CiAgICAgKiBAcGFyYW0gcm9vdCB0aGUgY29tcGlsYXRpb24gdW5pdCB0aGF0IGNvbnRhaW5zIHRyZWUKICAgICAqLwogICAgcHVibGljIGFic3RyYWN0IHZvaWQgcHJpbnRNZXNzYWdlKERpYWdub3N0aWMuS2luZCBraW5kLCBDaGFyU2VxdWVuY2UgbXNnLAogICAgICAgICAgICBjb20uc3VuLnNvdXJjZS5kb2N0cmVlLkRvY1RyZWUgdCwKICAgICAgICAgICAgY29tLnN1bi5zb3VyY2UuZG9jdHJlZS5Eb2NDb21tZW50VHJlZSBjLAogICAgICAgICAgICBjb20uc3VuLnNvdXJjZS50cmVlLkNvbXBpbGF0aW9uVW5pdFRyZWUgcm9vdCk7CgogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBicmVhayBpdGVyYXRvciB0byBjb21wdXRlIHRoZSBmaXJzdCBzZW50ZW5jZSBvZgogICAgICogZG9jdW1lbnRhdGlvbiBjb21tZW50cy4KICAgICAqIEBwYXJhbSBicmVha2l0ZXJhdG9yIGEgYnJlYWsgaXRlcmF0b3Igb3Ige0Bjb2RlIG51bGx9IHRvIHNwZWNpZnkgdGhlIGRlZmF1bHQKICAgICAqICAgICAgICAgICAgICAgICAgICAgIHNlbnRlbmNlIGJyZWFrZXIKICAgICAqCiAgICAgKiBAc2luY2UgOQogICAgICovCiAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzZXRCcmVha0l0ZXJhdG9yKEJyZWFrSXRlcmF0b3IgYnJlYWtpdGVyYXRvcik7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgdXRpbGl0eSBvYmplY3QgZm9yIGNyZWF0aW5nIHtAY29kZSBEb2NUcmVlfSBvYmplY3RzLgogICAgICogQHJldHVybiAgYSB1dGlsaXR5IG9iamVjdCBmb3IgY3JlYXRpbmcge0Bjb2RlIERvY1RyZWV9IG9iamVjdHMKICAgICAqCiAgICAgKiBAc2luY2UgOQogICAgICovCiAgICBwdWJsaWMgYWJzdHJhY3QgRG9jVHJlZUZhY3RvcnkgZ2V0RG9jVHJlZUZhY3RvcnkoKTsKfQpQSwMECgAACAAABjupStmbKMg+JwAAPicAAB4AAABjb20vc3VuL3NvdXJjZS91dGlsL1RyZWVzLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMTQsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi5zb3VyY2UudXRpbDsKCmltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5NZXRob2Q7CgppbXBvcnQgamF2YXguYW5ub3RhdGlvbi5wcm9jZXNzaW5nLlByb2Nlc3NpbmdFbnZpcm9ubWVudDsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC5Bbm5vdGF0aW9uTWlycm9yOwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5lbGVtZW50LkFubm90YXRpb25WYWx1ZTsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC5FbGVtZW50OwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5lbGVtZW50LkV4ZWN1dGFibGVFbGVtZW50OwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5lbGVtZW50LlR5cGVFbGVtZW50OwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC50eXBlLkRlY2xhcmVkVHlwZTsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwudHlwZS5FcnJvclR5cGU7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLnR5cGUuVHlwZU1pcnJvcjsKaW1wb3J0IGphdmF4LnRvb2xzLkRpYWdub3N0aWM7CmltcG9ydCBqYXZheC50b29scy5KYXZhQ29tcGlsZXIuQ29tcGlsYXRpb25UYXNrOwoKaW1wb3J0IGNvbS5zdW4uc291cmNlLnRyZWUuQ2F0Y2hUcmVlOwppbXBvcnQgY29tLnN1bi5zb3VyY2UudHJlZS5DbGFzc1RyZWU7CmltcG9ydCBjb20uc3VuLnNvdXJjZS50cmVlLkNvbXBpbGF0aW9uVW5pdFRyZWU7CmltcG9ydCBjb20uc3VuLnNvdXJjZS50cmVlLk1ldGhvZFRyZWU7CmltcG9ydCBjb20uc3VuLnNvdXJjZS50cmVlLlNjb3BlOwppbXBvcnQgY29tLnN1bi5zb3VyY2UudHJlZS5UcmVlOwoKLyoqCiAqIEJyaWRnZXMgSlNSIDE5OSwgSlNSIDI2OSwgYW5kIHRoZSBUcmVlIEFQSS4KICoKICogQGF1dGhvciBQZXRlciB2b24gZGVyIEFoJmVhY3V0ZTsKICovCnB1YmxpYyBhYnN0cmFjdCBjbGFzcyBUcmVlcyB7CiAgICAvKioKICAgICAqIFJldHVybnMgYSBUcmVlcyBvYmplY3QgZm9yIGEgZ2l2ZW4gQ29tcGlsYXRpb25UYXNrLgogICAgICogQHBhcmFtIHRhc2sgdGhlIGNvbXBpbGF0aW9uIHRhc2sgZm9yIHdoaWNoIHRvIGdldCB0aGUgVHJlZXMgb2JqZWN0CiAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgdGFzayBkb2VzIG5vdCBzdXBwb3J0IHRoZSBUcmVlcyBBUEkuCiAgICAgKiBAcmV0dXJuIHRoZSBUcmVlcyBvYmplY3QKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBUcmVlcyBpbnN0YW5jZShDb21waWxhdGlvblRhc2sgdGFzaykgewogICAgICAgIFN0cmluZyB0YXNrQ2xhc3NOYW1lID0gdGFzay5nZXRDbGFzcygpLmdldE5hbWUoKTsKICAgICAgICBpZiAoIXRhc2tDbGFzc05hbWUuZXF1YWxzKCJjb20uc3VuLnRvb2xzLmphdmFjLmFwaS5KYXZhY1Rhc2tJbXBsIikKICAgICAgICAgICAgICAgICYmICF0YXNrQ2xhc3NOYW1lLmVxdWFscygiY29tLnN1bi50b29scy5qYXZhYy5hcGkuQmFzaWNKYXZhY1Rhc2siKSkKICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIHJldHVybiBnZXRKYXZhY1RyZWVzKENvbXBpbGF0aW9uVGFzay5jbGFzcywgdGFzayk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgVHJlZXMgb2JqZWN0IGZvciBhIGdpdmVuIFByb2Nlc3NpbmdFbnZpcm9ubWVudC4KICAgICAqIEBwYXJhbSBlbnYgdGhlIHByb2Nlc3NpbmcgZW52aXJvbm1lbnQgZm9yIHdoaWNoIHRvIGdldCB0aGUgVHJlZXMgb2JqZWN0CiAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgZW52IGRvZXMgbm90IHN1cHBvcnQgdGhlIFRyZWVzIEFQSS4KICAgICAqIEByZXR1cm4gdGhlIFRyZWVzIG9iamVjdAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIFRyZWVzIGluc3RhbmNlKFByb2Nlc3NpbmdFbnZpcm9ubWVudCBlbnYpIHsKICAgICAgICBpZiAoIWVudi5nZXRDbGFzcygpLmdldE5hbWUoKS5lcXVhbHMoImNvbS5zdW4udG9vbHMuamF2YWMucHJvY2Vzc2luZy5KYXZhY1Byb2Nlc3NpbmdFbnZpcm9ubWVudCIpKQogICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgcmV0dXJuIGdldEphdmFjVHJlZXMoUHJvY2Vzc2luZ0Vudmlyb25tZW50LmNsYXNzLCBlbnYpOwogICAgfQoKICAgIHN0YXRpYyBUcmVlcyBnZXRKYXZhY1RyZWVzKENsYXNzPD8+IGFyZ1R5cGUsIE9iamVjdCBhcmcpIHsKICAgICAgICB0cnkgewogICAgICAgICAgICBDbGFzc0xvYWRlciBjbCA9IGFyZy5nZXRDbGFzcygpLmdldENsYXNzTG9hZGVyKCk7CiAgICAgICAgICAgIENsYXNzPD8+IGMgPSBDbGFzcy5mb3JOYW1lKCJjb20uc3VuLnRvb2xzLmphdmFjLmFwaS5KYXZhY1RyZWVzIiwgZmFsc2UsIGNsKTsKICAgICAgICAgICAgYXJnVHlwZSA9IENsYXNzLmZvck5hbWUoYXJnVHlwZS5nZXROYW1lKCksIGZhbHNlLCBjbCk7CiAgICAgICAgICAgIE1ldGhvZCBtID0gYy5nZXRNZXRob2QoImluc3RhbmNlIiwgYXJnVHlwZSk7CiAgICAgICAgICAgIHJldHVybiAoVHJlZXMpIG0uaW52b2tlKG51bGwsIGFyZyk7CiAgICAgICAgfSBjYXRjaCAoUmVmbGVjdGl2ZU9wZXJhdGlvbkV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihlKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgdXRpbGl0eSBvYmplY3QgZm9yIG9idGFpbmluZyBzb3VyY2UgcG9zaXRpb25zLgogICAgICogQHJldHVybiB0aGUgdXRpbGl0eSBvYmplY3QgZm9yIG9idGFpbmluZyBzb3VyY2UgcG9zaXRpb25zCiAgICAgKi8KICAgIHB1YmxpYyBhYnN0cmFjdCBTb3VyY2VQb3NpdGlvbnMgZ2V0U291cmNlUG9zaXRpb25zKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBUcmVlIG5vZGUgZm9yIGEgZ2l2ZW4gRWxlbWVudC4KICAgICAqIFJldHVybnMge0Bjb2RlIG51bGx9IGlmIHRoZSBub2RlIGNhbiBub3QgYmUgZm91bmQuCiAgICAgKiBAcGFyYW0gZWxlbWVudCB0aGUgZWxlbWVudAogICAgICogQHJldHVybiB0aGUgdHJlZSBub2RlCiAgICAgKi8KICAgIHB1YmxpYyBhYnN0cmFjdCBUcmVlIGdldFRyZWUoRWxlbWVudCBlbGVtZW50KTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIENsYXNzVHJlZSBub2RlIGZvciBhIGdpdmVuIFR5cGVFbGVtZW50LgogICAgICogUmV0dXJucyB7QGNvZGUgbnVsbH0gaWYgdGhlIG5vZGUgY2FuIG5vdCBiZSBmb3VuZC4KICAgICAqIEBwYXJhbSBlbGVtZW50IHRoZSBlbGVtZW50CiAgICAgKiBAcmV0dXJuIHRoZSBjbGFzcyB0cmVlIG5vZGUKICAgICAqLwogICAgcHVibGljIGFic3RyYWN0IENsYXNzVHJlZSBnZXRUcmVlKFR5cGVFbGVtZW50IGVsZW1lbnQpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgTWV0aG9kVHJlZSBub2RlIGZvciBhIGdpdmVuIEV4ZWN1dGFibGVFbGVtZW50LgogICAgICogUmV0dXJucyB7QGNvZGUgbnVsbH0gaWYgdGhlIG5vZGUgY2FuIG5vdCBiZSBmb3VuZC4KICAgICAqIEBwYXJhbSBtZXRob2QgdGhlIGV4ZWN1dGFibGUgZWxlbWVudAogICAgICogQHJldHVybiB0aGUgbWV0aG9kIHRyZWUgbm9kZQogICAgICovCiAgICBwdWJsaWMgYWJzdHJhY3QgTWV0aG9kVHJlZSBnZXRUcmVlKEV4ZWN1dGFibGVFbGVtZW50IG1ldGhvZCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBUcmVlIG5vZGUgZm9yIGFuIEFubm90YXRpb25NaXJyb3Igb24gYSBnaXZlbiBFbGVtZW50LgogICAgICogUmV0dXJucyB7QGNvZGUgbnVsbH0gaWYgdGhlIG5vZGUgY2FuIG5vdCBiZSBmb3VuZC4KICAgICAqIEBwYXJhbSBlIHRoZSBlbGVtZW50CiAgICAgKiBAcGFyYW0gYSB0aGUgYW5ub3RhdGlvbiBtaXJyb3IKICAgICAqIEByZXR1cm4gdGhlIHRyZWUgbm9kZQogICAgICovCiAgICBwdWJsaWMgYWJzdHJhY3QgVHJlZSBnZXRUcmVlKEVsZW1lbnQgZSwgQW5ub3RhdGlvbk1pcnJvciBhKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIFRyZWUgbm9kZSBmb3IgYW4gQW5ub3RhdGlvblZhbHVlIGZvciBhbiBBbm5vdGF0aW9uTWlycm9yIG9uIGEgZ2l2ZW4gRWxlbWVudC4KICAgICAqIFJldHVybnMge0Bjb2RlIG51bGx9IGlmIHRoZSBub2RlIGNhbiBub3QgYmUgZm91bmQuCiAgICAgKiBAcGFyYW0gZSB0aGUgZWxlbWVudAogICAgICogQHBhcmFtIGEgdGhlIGFubm90YXRpb24gbWlycm9yCiAgICAgKiBAcGFyYW0gdiB0aGUgYW5ub3RhdGlvbiB2YWx1ZQogICAgICogQHJldHVybiB0aGUgdHJlZSBub2RlCiAgICAgKi8KICAgIHB1YmxpYyBhYnN0cmFjdCBUcmVlIGdldFRyZWUoRWxlbWVudCBlLCBBbm5vdGF0aW9uTWlycm9yIGEsIEFubm90YXRpb25WYWx1ZSB2KTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHBhdGggdG8gdHJlZSBub2RlIHdpdGhpbiB0aGUgc3BlY2lmaWVkIGNvbXBpbGF0aW9uIHVuaXQuCiAgICAgKiBAcGFyYW0gdW5pdCB0aGUgY29tcGlsYXRpb24gdW5pdAogICAgICogQHBhcmFtIG5vZGUgdGhlIHRyZWUgbm9kZQogICAgICogQHJldHVybiB0aGUgdHJlZSBwYXRoCiAgICAgKi8KICAgIHB1YmxpYyBhYnN0cmFjdCBUcmVlUGF0aCBnZXRQYXRoKENvbXBpbGF0aW9uVW5pdFRyZWUgdW5pdCwgVHJlZSBub2RlKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIFRyZWVQYXRoIG5vZGUgZm9yIGEgZ2l2ZW4gRWxlbWVudC4KICAgICAqIFJldHVybnMge0Bjb2RlIG51bGx9IGlmIHRoZSBub2RlIGNhbiBub3QgYmUgZm91bmQuCiAgICAgKiBAcGFyYW0gZSB0aGUgZWxlbWVudAogICAgICogQHJldHVybiB0aGUgdHJlZSBwYXRoCiAgICAgKi8KICAgIHB1YmxpYyBhYnN0cmFjdCBUcmVlUGF0aCBnZXRQYXRoKEVsZW1lbnQgZSk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBUcmVlUGF0aCBub2RlIGZvciBhbiBBbm5vdGF0aW9uTWlycm9yIG9uIGEgZ2l2ZW4gRWxlbWVudC4KICAgICAqIFJldHVybnMge0Bjb2RlIG51bGx9IGlmIHRoZSBub2RlIGNhbiBub3QgYmUgZm91bmQuCiAgICAgKiBAcGFyYW0gZSB0aGUgZWxlbWVudAogICAgICogQHBhcmFtIGEgdGhlIGFubm90YXRpb24gbWlycm9yCiAgICAgKiBAcmV0dXJuIHRoZSB0cmVlIHBhdGgKICAgICAqLwogICAgcHVibGljIGFic3RyYWN0IFRyZWVQYXRoIGdldFBhdGgoRWxlbWVudCBlLCBBbm5vdGF0aW9uTWlycm9yIGEpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgVHJlZVBhdGggbm9kZSBmb3IgYW4gQW5ub3RhdGlvblZhbHVlIGZvciBhbiBBbm5vdGF0aW9uTWlycm9yIG9uIGEgZ2l2ZW4gRWxlbWVudC4KICAgICAqIFJldHVybnMge0Bjb2RlIG51bGx9IGlmIHRoZSBub2RlIGNhbiBub3QgYmUgZm91bmQuCiAgICAgKiBAcGFyYW0gZSB0aGUgZWxlbWVudAogICAgICogQHBhcmFtIGEgdGhlIGFubm90YXRpb24gbWlycm9yCiAgICAgKiBAcGFyYW0gdiB0aGUgYW5ub3RhdGlvbiB2YWx1ZQogICAgICogQHJldHVybiB0aGUgdHJlZSBwYXRoCiAgICAgKi8KICAgIHB1YmxpYyBhYnN0cmFjdCBUcmVlUGF0aCBnZXRQYXRoKEVsZW1lbnQgZSwgQW5ub3RhdGlvbk1pcnJvciBhLCBBbm5vdGF0aW9uVmFsdWUgdik7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBFbGVtZW50IGZvciB0aGUgVHJlZSBub2RlIGlkZW50aWZpZWQgYnkgYSBnaXZlbiBUcmVlUGF0aC4KICAgICAqIFJldHVybnMge0Bjb2RlIG51bGx9IGlmIHRoZSBlbGVtZW50IGlzIG5vdCBhdmFpbGFibGUuCiAgICAgKiBAcGFyYW0gcGF0aCB0aGUgdHJlZSBwYXRoCiAgICAgKiBAcmV0dXJuIHRoZSBlbGVtZW50CiAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpcyB0aGUgVHJlZVBhdGggZG9lcyBub3QgaWRlbnRpZnkKICAgICAqIGEgVHJlZSBub2RlIHRoYXQgbWlnaHQgaGF2ZSBhbiBhc3NvY2lhdGVkIEVsZW1lbnQuCiAgICAgKi8KICAgIHB1YmxpYyBhYnN0cmFjdCBFbGVtZW50IGdldEVsZW1lbnQoVHJlZVBhdGggcGF0aCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBUeXBlTWlycm9yIGZvciB0aGUgVHJlZSBub2RlIGlkZW50aWZpZWQgYnkgYSBnaXZlbiBUcmVlUGF0aC4KICAgICAqIFJldHVybnMge0Bjb2RlIG51bGx9IGlmIHRoZSBUeXBlTWlycm9yIGlzIG5vdCBhdmFpbGFibGUuCiAgICAgKiBAcGFyYW0gcGF0aCB0aGUgdHJlZSBwYXRoCiAgICAgKiBAcmV0dXJuIHRoZSB0eXBlIG1pcnJvcgogICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaXMgdGhlIFRyZWVQYXRoIGRvZXMgbm90IGlkZW50aWZ5CiAgICAgKiBhIFRyZWUgbm9kZSB0aGF0IG1pZ2h0IGhhdmUgYW4gYXNzb2NpYXRlZCBUeXBlTWlycm9yLgogICAgICovCiAgICBwdWJsaWMgYWJzdHJhY3QgVHlwZU1pcnJvciBnZXRUeXBlTWlycm9yKFRyZWVQYXRoIHBhdGgpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgU2NvcGUgZm9yIHRoZSBUcmVlIG5vZGUgaWRlbnRpZmllZCBieSBhIGdpdmVuIFRyZWVQYXRoLgogICAgICogUmV0dXJucyB7QGNvZGUgbnVsbH0gaWYgdGhlIFNjb3BlIGlzIG5vdCBhdmFpbGFibGUuCiAgICAgKiBAcGFyYW0gcGF0aCB0aGUgdHJlZSBwYXRoCiAgICAgKiBAcmV0dXJuIHRoZSBzY29wZQogICAgICovCiAgICBwdWJsaWMgYWJzdHJhY3QgU2NvcGUgZ2V0U2NvcGUoVHJlZVBhdGggcGF0aCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBkb2MgY29tbWVudCwgaWYgYW55LCBmb3IgdGhlIFRyZWUgbm9kZSBpZGVudGlmaWVkIGJ5IGEgZ2l2ZW4gVHJlZVBhdGguCiAgICAgKiBSZXR1cm5zIHtAY29kZSBudWxsfSBpZiBubyBkb2MgY29tbWVudCB3YXMgZm91bmQuCiAgICAgKiBAc2VlIERvY1RyZWVzI2dldERvY0NvbW1lbnRUcmVlKFRyZWVQYXRoKQogICAgICogQHBhcmFtIHBhdGggdGhlIHRyZWUgcGF0aAogICAgICogQHJldHVybiB0aGUgZG9jIGNvbW1lbnQKICAgICAqLwogICAgcHVibGljIGFic3RyYWN0IFN0cmluZyBnZXREb2NDb21tZW50KFRyZWVQYXRoIHBhdGgpOwoKICAgIC8qKgogICAgICogQ2hlY2tzIHdoZXRoZXIgYSBnaXZlbiB0eXBlIGlzIGFjY2Vzc2libGUgaW4gYSBnaXZlbiBzY29wZS4KICAgICAqIEBwYXJhbSBzY29wZSB0aGUgc2NvcGUgdG8gYmUgY2hlY2tlZAogICAgICogQHBhcmFtIHR5cGUgdGhlIHR5cGUgdG8gYmUgY2hlY2tlZAogICAgICogQHJldHVybiB0cnVlIGlmIHtAY29kZSB0eXBlfSBpcyBhY2Nlc3NpYmxlCiAgICAgKi8KICAgIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIGlzQWNjZXNzaWJsZShTY29wZSBzY29wZSwgVHlwZUVsZW1lbnQgdHlwZSk7CgogICAgLyoqCiAgICAgKiBDaGVja3Mgd2hldGhlciB0aGUgZ2l2ZW4gZWxlbWVudCBpcyBhY2Nlc3NpYmxlIGFzIGEgbWVtYmVyIG9mIHRoZSBnaXZlbgogICAgICogdHlwZSBpbiBhIGdpdmVuIHNjb3BlLgogICAgICogQHBhcmFtIHNjb3BlIHRoZSBzY29wZSB0byBiZSBjaGVja2VkCiAgICAgKiBAcGFyYW0gbWVtYmVyIHRoZSBtZW1iZXIgdG8gYmUgY2hlY2tlZAogICAgICogQHBhcmFtIHR5cGUgdGhlIHR5cGUgZm9yIHdoaWNoIHRvIGNoZWNrIGlmIHRoZSBtZW1iZXIgaXMgYWNjZXNzaWJsZQogICAgICogQHJldHVybiB0cnVlIGlmIHtAY29kZSBtZW1iZXJ9IGlzIGFjY2Vzc2libGUgaW4ge0Bjb2RlIHR5cGV9CiAgICAgKi8KICAgIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIGlzQWNjZXNzaWJsZShTY29wZSBzY29wZSwgRWxlbWVudCBtZW1iZXIsIERlY2xhcmVkVHlwZSB0eXBlKTsKCiAgICAvKioKICAgICAgKiBSZXR1cm5zIHRoZSBvcmlnaW5hbCB0eXBlIGZyb20gdGhlIEVycm9yVHlwZSBvYmplY3QuCiAgICAgICogQHBhcmFtIGVycm9yVHlwZSBUaGUgZXJyb3JUeXBlIGZvciB3aGljaCB3ZSB3YW50IHRvIGdldCB0aGUgb3JpZ2luYWwgdHlwZS4KICAgICAgKiBAcmV0dXJuIGphdmF4LmxhbmcubW9kZWwudHlwZS5UeXBlTWlycm9yIGNvcnJlc3BvbmRpbmcgdG8gdGhlIG9yaWdpbmFsIHR5cGUsIHJlcGxhY2VkIGJ5IHRoZSBFcnJvclR5cGUuCiAgICAgICovCiAgICBwdWJsaWMgYWJzdHJhY3QgVHlwZU1pcnJvciBnZXRPcmlnaW5hbFR5cGUoRXJyb3JUeXBlIGVycm9yVHlwZSk7CgogICAgLyoqCiAgICAgKiBQcmludHMgYSBtZXNzYWdlIG9mIHRoZSBzcGVjaWZpZWQga2luZCBhdCB0aGUgbG9jYXRpb24gb2YgdGhlCiAgICAgKiB0cmVlIHdpdGhpbiB0aGUgcHJvdmlkZWQgY29tcGlsYXRpb24gdW5pdAogICAgICoKICAgICAqIEBwYXJhbSBraW5kIHRoZSBraW5kIG9mIG1lc3NhZ2UKICAgICAqIEBwYXJhbSBtc2cgIHRoZSBtZXNzYWdlLCBvciBhbiBlbXB0eSBzdHJpbmcgaWYgbm9uZQogICAgICogQHBhcmFtIHQgICAgdGhlIHRyZWUgdG8gdXNlIGFzIGEgcG9zaXRpb24gaGludAogICAgICogQHBhcmFtIHJvb3QgdGhlIGNvbXBpbGF0aW9uIHVuaXQgdGhhdCBjb250YWlucyB0cmVlCiAgICAgKi8KICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHByaW50TWVzc2FnZShEaWFnbm9zdGljLktpbmQga2luZCwgQ2hhclNlcXVlbmNlIG1zZywKICAgICAgICAgICAgY29tLnN1bi5zb3VyY2UudHJlZS5UcmVlIHQsCiAgICAgICAgICAgIGNvbS5zdW4uc291cmNlLnRyZWUuQ29tcGlsYXRpb25Vbml0VHJlZSByb290KTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGx1YiBvZiBhbiBleGNlcHRpb24gcGFyYW1ldGVyIGRlY2xhcmVkIGluIGEgY2F0Y2ggY2xhdXNlLgogICAgICogQHBhcmFtIHRyZWUgdGhlIHRyZWUgZm9yIHRoZSBjYXRjaCBjbGF1c2UKICAgICAqIEByZXR1cm4gVGhlIGx1YiBvZiB0aGUgZXhjZXB0aW9uIHBhcmFtZXRlcgogICAgICovCiAgICBwdWJsaWMgYWJzdHJhY3QgVHlwZU1pcnJvciBnZXRMdWIoQ2F0Y2hUcmVlIHRyZWUpOwp9ClBLAwQKAAAIAAAGO6lKlsNg8+UUAADlFAAAIgAAAGNvbS9zdW4vc291cmNlL3V0aWwvVGFza0V2ZW50LmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMTQsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi5zb3VyY2UudXRpbDsKCmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuVHlwZUVsZW1lbnQ7CmltcG9ydCBqYXZheC50b29scy5KYXZhRmlsZU9iamVjdDsKCmltcG9ydCBjb20uc3VuLnNvdXJjZS50cmVlLkNvbXBpbGF0aW9uVW5pdFRyZWU7CgovKioKICogUHJvdmlkZXMgZGV0YWlscyBhYm91dCB3b3JrIHRoYXQgaGFzIGJlZW4gZG9uZSBieSB0aGUgSkRLIEphdmEgQ29tcGlsZXIsIGphdmFjLgogKgogKiBAYXV0aG9yIEpvbmF0aGFuIEdpYmJvbnMKICogQHNpbmNlIDEuNgogKi8KcHVibGljIGZpbmFsIGNsYXNzIFRhc2tFdmVudAp7CiAgICAvKioKICAgICAqIEtpbmQgb2YgdGFzayBldmVudC4KICAgICAqIEBzaW5jZSAxLjYKICAgICAqLwogICAgcHVibGljIGVudW0gS2luZCB7CiAgICAgICAgLyoqCiAgICAgICAgICogRm9yIGV2ZW50cyByZWxhdGVkIHRvIHRoZSBwYXJzaW5nIG9mIGEgZmlsZS4KICAgICAgICAgKi8KICAgICAgICBQQVJTRSwKICAgICAgICAvKioKICAgICAgICAgKiBGb3IgZXZlbnRzIHJlbGF0aW5nIHRvIGVsZW1lbnRzIGJlaW5nIGVudGVyZWQuCiAgICAgICAgICoqLwogICAgICAgIEVOVEVSLAogICAgICAgIC8qKgogICAgICAgICAqIEZvciBldmVudHMgcmVsYXRpbmcgdG8gZWxlbWVudHMgYmVpbmcgYW5hbHl6ZWQgZm9yIGVycm9ycy4KICAgICAgICAgKiovCiAgICAgICAgQU5BTFlaRSwKICAgICAgICAvKioKICAgICAgICAgKiBGb3IgZXZlbnRzIHJlbGF0aW5nIHRvIGNsYXNzIGZpbGVzIGJlaW5nIGdlbmVyYXRlZC4KICAgICAgICAgKiovCiAgICAgICAgR0VORVJBVEUsCiAgICAgICAgLyoqCiAgICAgICAgICogRm9yIGV2ZW50cyByZWxhdGluZyB0byBvdmVyYWxsIGFubm90YXRpb24gcHJvY2Vzc2luZy4KICAgICAgICAgKiovCiAgICAgICAgQU5OT1RBVElPTl9QUk9DRVNTSU5HLAogICAgICAgIC8qKgogICAgICAgICAqIEZvciBldmVudHMgcmVsYXRpbmcgdG8gYW4gaW5kaXZpZHVhbCBhbm5vdGF0aW9uIHByb2Nlc3Npbmcgcm91bmQuCiAgICAgICAgICoqLwogICAgICAgIEFOTk9UQVRJT05fUFJPQ0VTU0lOR19ST1VORCwKICAgICAgICAvKioKICAgICAgICAgKiBTZW50IGJlZm9yZSBwYXJzaW5nIGZpcnN0IHNvdXJjZSBmaWxlLCBhbmQgYWZ0ZXIgd3JpdGluZyB0aGUgbGFzdCBvdXRwdXQgZmlsZS4KICAgICAgICAgKiBUaGlzIGV2ZW50IGlzIG5vdCBzZW50IHdoZW4gdXNpbmcge0BsaW5rIEphdmFjVGFzayNwYXJzZSgpfSwKICAgICAgICAgKiB7QGxpbmsgSmF2YWNUYXNrI2FuYWx5emUoKX0gb3Ige0BsaW5rIEphdmFjVGFzayNnZW5lcmF0ZSgpfS4KICAgICAgICAgKgogICAgICAgICAqIEBzaW5jZSA5CiAgICAgICAgICovCiAgICAgICAgQ09NUElMQVRJT04sCiAgICB9CgogICAgLyoqCiAgICAgKiBDcmVhdGVzIGEgdGFzayBldmVudCBmb3IgYSBnaXZlbiBraW5kLgogICAgICogVGhlIHNvdXJjZSBmaWxlLCBjb21waWxhdGlvbiB1bml0IGFuZCB0eXBlIGVsZW1lbnQKICAgICAqIGFyZSBhbGwgc2V0IHRvIHtAY29kZSBudWxsfS4KICAgICAqIEBwYXJhbSBraW5kIHRoZSBraW5kIG9mIHRoZSBldmVudAogICAgICovCiAgICBwdWJsaWMgVGFza0V2ZW50KEtpbmQga2luZCkgewogICAgICAgIHRoaXMoa2luZCwgbnVsbCwgbnVsbCwgbnVsbCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDcmVhdGVzIGEgdGFzayBldmVudCBmb3IgYSBnaXZlbiBraW5kIGFuZCBzb3VyY2UgZmlsZS4KICAgICAqIFRoZSBjb21waWxhdGlvbiB1bml0IGFuZCB0eXBlIGVsZW1lbnQgYXJlIGJvdGggc2V0IHRvIHtAY29kZSBudWxsfS4KICAgICAqIEBwYXJhbSBraW5kIHRoZSBraW5kIG9mIHRoZSBldmVudAogICAgICogQHBhcmFtIHNvdXJjZUZpbGUgdGhlIHNvdXJjZSBmaWxlCiAgICAgKi8KICAgIHB1YmxpYyBUYXNrRXZlbnQoS2luZCBraW5kLCBKYXZhRmlsZU9iamVjdCBzb3VyY2VGaWxlKSB7CiAgICAgICAgdGhpcyhraW5kLCBzb3VyY2VGaWxlLCBudWxsLCBudWxsKTsKICAgIH0KCiAgICAvKioKICAgICAqIENyZWF0ZXMgYSB0YXNrIGV2ZW50IGZvciBhIGdpdmVuIGtpbmQgYW5kIGNvbXBpbGF0aW9uIHVuaXQuCiAgICAgKiBUaGUgc291cmNlIGZpbGUgaXMgc2V0IGZyb20gdGhlIGNvbXBpbGF0aW9uIHVuaXQsCiAgICAgKiBhbmQgdGhlIHR5cGUgZWxlbWVudCBpcyBzZXQgdG8ge0Bjb2RlIG51bGx9LgogICAgICogQHBhcmFtIGtpbmQgdGhlIGtpbmQgb2YgdGhlIGV2ZW50CiAgICAgKiBAcGFyYW0gdW5pdCB0aGUgY29tcGlsYXRpb24gdW5pdAogICAgICovCiAgICBwdWJsaWMgVGFza0V2ZW50KEtpbmQga2luZCwgQ29tcGlsYXRpb25Vbml0VHJlZSB1bml0KSB7CiAgICAgICAgdGhpcyhraW5kLCB1bml0LmdldFNvdXJjZUZpbGUoKSwgdW5pdCwgbnVsbCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDcmVhdGVzIGEgdGFzayBldmVudCBmb3IgYSBnaXZlbiBraW5kLCBjb21waWxhdGlvbiB1bml0CiAgICAgKiBhbmQgdHlwZSBlbGVtZW50LgogICAgICogVGhlIHNvdXJjZSBmaWxlIGlzIHNldCBmcm9tIHRoZSBjb21waWxhdGlvbiB1bml0LgogICAgICogQHBhcmFtIGtpbmQgdGhlIGtpbmQgb2YgdGhlIGV2ZW50CiAgICAgKiBAcGFyYW0gdW5pdCB0aGUgY29tcGlsYXRpb24gdW5pdAogICAgICogQHBhcmFtIGNsYXp6IHRoZSB0eXBlIGVsZW1lbnQKICAgICAqLwogICAgcHVibGljIFRhc2tFdmVudChLaW5kIGtpbmQsIENvbXBpbGF0aW9uVW5pdFRyZWUgdW5pdCwgVHlwZUVsZW1lbnQgY2xhenopIHsKICAgICAgICB0aGlzKGtpbmQsIHVuaXQuZ2V0U291cmNlRmlsZSgpLCB1bml0LCBjbGF6eik7CiAgICB9CgogICAgcHJpdmF0ZSBUYXNrRXZlbnQoS2luZCBraW5kLCBKYXZhRmlsZU9iamVjdCBmaWxlLCBDb21waWxhdGlvblVuaXRUcmVlIHVuaXQsIFR5cGVFbGVtZW50IGNsYXp6KSB7CiAgICAgICAgdGhpcy5raW5kID0ga2luZDsKICAgICAgICB0aGlzLmZpbGUgPSBmaWxlOwogICAgICAgIHRoaXMudW5pdCA9IHVuaXQ7CiAgICAgICAgdGhpcy5jbGF6eiA9IGNsYXp6OwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUga2luZCBmb3IgdGhpcyBldmVudC4KICAgICAqIEByZXR1cm4gdGhlIGtpbmQKICAgICAqLwogICAgcHVibGljIEtpbmQgZ2V0S2luZCgpIHsKICAgICAgICByZXR1cm4ga2luZDsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHNvdXJjZSBmaWxlIGZvciB0aGlzIGV2ZW50LgogICAgICogTWF5IGJlIHtAY29kZSBudWxsfS4KICAgICAqIEByZXR1cm4gdGhlIHNvdXJjZSBmaWxlCiAgICAgKi8KICAgIHB1YmxpYyBKYXZhRmlsZU9iamVjdCBnZXRTb3VyY2VGaWxlKCkgewogICAgICAgIHJldHVybiBmaWxlOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgY29tcGlsYXRpb24gdW5pdCBmb3IgdGhpcyBldmVudC4KICAgICAqIE1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICAgKiBAcmV0dXJuIHRoZSBjb21waWxhdGlvbiB1bml0CiAgICAgKi8KICAgIHB1YmxpYyBDb21waWxhdGlvblVuaXRUcmVlIGdldENvbXBpbGF0aW9uVW5pdCgpIHsKICAgICAgICByZXR1cm4gdW5pdDsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHR5cGUgZWxlbWVudCBmb3IgdGhpcyBldmVudC4KICAgICAqIE1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICAgKiBAcmV0dXJuIHRoZSB0eXBlIGVsZW1lbnQKICAgICAqLwogICAgcHVibGljIFR5cGVFbGVtZW50IGdldFR5cGVFbGVtZW50KCkgewogICAgICAgIHJldHVybiBjbGF6ejsKICAgIH0KCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CiAgICAgICAgcmV0dXJuICJUYXNrRXZlbnRbIgogICAgICAgICAgICArIGtpbmQgKyAiLCIKICAgICAgICAgICAgKyBmaWxlICsgIiwiCiAgICAgICAgICAgIC8vIHRoZSBjb21waWxhdGlvbiB1bml0IGlzIGlkZW50aWZpZWQgYnkgdGhlIGZpbGUKICAgICAgICAgICAgKyBjbGF6eiArICJdIjsKICAgIH0KCiAgICBwcml2YXRlIEtpbmQga2luZDsKICAgIHByaXZhdGUgSmF2YUZpbGVPYmplY3QgZmlsZTsKICAgIHByaXZhdGUgQ29tcGlsYXRpb25Vbml0VHJlZSB1bml0OwogICAgcHJpdmF0ZSBUeXBlRWxlbWVudCBjbGF6ejsKfQpQSwMECgAACAAABjupSuffEnVPNwAATzcAAC0AAABjb20vc3VuL3NvdXJjZS91dGlsL1NpbXBsZURvY1RyZWVWaXNpdG9yLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMTYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi5zb3VyY2UudXRpbDsKCmltcG9ydCBjb20uc3VuLnNvdXJjZS5kb2N0cmVlLio7CgovKioKICogQSBzaW1wbGUgdmlzaXRvciBmb3IgdHJlZSBub2Rlcy4KICoKICogQHBhcmFtIDxSPiB0aGUgcmV0dXJuIHR5cGUgb2YgdGhpcyB2aXNpdG9yJ3MgbWV0aG9kcy4gIFVzZSB7QGxpbmsKICogICAgICAgICAgICBWb2lkfSBmb3IgdmlzaXRvcnMgdGhhdCBkbyBub3QgbmVlZCB0byByZXR1cm4gcmVzdWx0cy4KICogQHBhcmFtIDxQPiB0aGUgdHlwZSBvZiB0aGUgYWRkaXRpb25hbCBwYXJhbWV0ZXIgdG8gdGhpcyB2aXNpdG9yJ3MKICogICAgICAgICAgICBtZXRob2RzLiAgVXNlIHtAY29kZSBWb2lkfSBmb3IgdmlzaXRvcnMgdGhhdCBkbyBub3QgbmVlZCBhbgogKiAgICAgICAgICAgIGFkZGl0aW9uYWwgcGFyYW1ldGVyLgogKgogKiBAc2luY2UgMS44CiAqLwpwdWJsaWMgY2xhc3MgU2ltcGxlRG9jVHJlZVZpc2l0b3I8UixQPiBpbXBsZW1lbnRzIERvY1RyZWVWaXNpdG9yPFIsIFA+IHsKICAgIC8qKgogICAgICogVGhlIGRlZmF1bHQgdmFsdWUsIHJldHVybmVkIGJ5IHRoZSB7QGxpbmsgI2RlZmF1bHRBY3Rpb24gZGVmYXVsdCBhY3Rpb259LgogICAgICovCiAgICBwcm90ZWN0ZWQgZmluYWwgUiBERUZBVUxUX1ZBTFVFOwoKICAgIC8qKgogICAgICogQ3JlYXRlcyBhIHZpc2l0b3IsIHdpdGggYSBERUZBVUxUX1ZBTFVFIG9mIHtAY29kZSBudWxsfS4KICAgICAqLwogICAgcHJvdGVjdGVkIFNpbXBsZURvY1RyZWVWaXNpdG9yKCkgewogICAgICAgIERFRkFVTFRfVkFMVUUgPSBudWxsOwogICAgfQoKICAgIC8qKgogICAgICogQ3JlYXRlcyBhIHZpc2l0b3IsIHdpdGggYSBzcGVjaWZpZWQgREVGQVVMVF9WQUxVRS4KICAgICAqIEBwYXJhbSBkZWZhdWx0VmFsdWUgdGhlIGRlZmF1bHQgdmFsdWUgdG8gYmUgcmV0dXJuZWQgYnkgdGhlIGRlZmF1bHQgYWN0aW9uLgogICAgICovCiAgICBwcm90ZWN0ZWQgU2ltcGxlRG9jVHJlZVZpc2l0b3IoUiBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBERUZBVUxUX1ZBTFVFID0gZGVmYXVsdFZhbHVlOwogICAgfQoKICAgIC8qKgogICAgICogVGhlIGRlZmF1bHQgYWN0aW9uLCB1c2VkIGJ5IGFsbCB2aXNpdCBtZXRob2RzIHRoYXQgYXJlIG5vdCBvdmVycmlkZGVuLgogICAgICogQHBhcmFtIG5vZGUgdGhlIG5vZGUgYmVpbmcgdmlzaXRlZAogICAgICogQHBhcmFtIHAgdGhlIHBhcmFtZXRlciB2YWx1ZSBwYXNzZWQgdG8gdGhlIHZpc2l0IG1ldGhvZAogICAgICogQHJldHVybiB0aGUgcmVzdWx0IHZhbHVlIHRvIGJlIHJldHVybmVkIGZyb20gdGhlIHZpc2l0IG1ldGhvZAogICAgICovCiAgICBwcm90ZWN0ZWQgUiBkZWZhdWx0QWN0aW9uKERvY1RyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfVkFMVUU7CiAgICB9CgogICAgLyoqCiAgICAgKiBJbnZva2VzIHRoZSBhcHByb3ByaWF0ZSB2aXNpdCBtZXRob2Qgc3BlY2lmaWMgdG8gdGhlIHR5cGUgb2YgdGhlIG5vZGUuCiAgICAgKiBAcGFyYW0gbm9kZSB0aGUgbm9kZSBvbiB3aGljaCB0byBkaXNwYXRjaAogICAgICogQHBhcmFtIHAgYSBwYXJhbWV0ZXIgdG8gYmUgcGFzc2VkIHRvIHRoZSBhcHByb3ByaWF0ZSB2aXNpdCBtZXRob2QKICAgICAqIEByZXR1cm4gdGhlIHZhbHVlIHJldHVybnMgZnJvbSB0aGUgYXBwcm9wcmlhdGUgdmlzaXQgbWV0aG9kCiAgICAgKi8KICAgIHB1YmxpYyBmaW5hbCBSIHZpc2l0KERvY1RyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIChub2RlID09IG51bGwpID8gbnVsbCA6IG5vZGUuYWNjZXB0KHRoaXMsIHApOwogICAgfQoKICAgIC8qKgogICAgICogSW52b2tlcyB0aGUgYXBwcm9wcmlhdGUgdmlzaXQgbWV0aG9kIG9uIGVhY2ggb2YgYSBzZXF1ZW5jZSBvZiBub2Rlcy4KICAgICAqIEBwYXJhbSBub2RlcyB0aGUgbm9kZXMgb24gd2hpY2ggdG8gZGlzcGF0Y2gKICAgICAqIEBwYXJhbSBwIGEgcGFyYW1ldGVyIHZhbHVlIHRvIGJlIHBhc3NlZCB0byBlYWNoIGFwcHJvcHJpYXRlIHZpc2l0IG1ldGhvZAogICAgICogQHJldHVybiB0aGUgdmFsdWUgcmV0dXJuIGZyb20gdGhlIGxhc3Qgb2YgdGhlIHZpc2l0IG1ldGhvZHMsIG9yIG51bGwKICAgICAqICAgICAgaWYgbm9uZSB3ZXJlIGNhbGxlZC4KICAgICAqLwogICAgcHVibGljIGZpbmFsIFIgdmlzaXQoSXRlcmFibGU8PyBleHRlbmRzIERvY1RyZWU+IG5vZGVzLCBQIHApIHsKICAgICAgICBSIHIgPSBudWxsOwogICAgICAgIGlmIChub2RlcyAhPSBudWxsKSB7CiAgICAgICAgICAgIGZvciAoRG9jVHJlZSBub2RlIDogbm9kZXMpCiAgICAgICAgICAgICAgICByID0gdmlzaXQobm9kZSwgcCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIGNhbGxzIHtAY29kZSBkZWZhdWx0QWN0aW9ufS4KICAgICAqCiAgICAgKiBAcGFyYW0gbm9kZSB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuICB0aGUgcmVzdWx0IG9mIHtAY29kZSBkZWZhdWx0QWN0aW9ufQogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0QXR0cmlidXRlKEF0dHJpYnV0ZVRyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIGRlZmF1bHRBY3Rpb24obm9kZSwgcCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gY2FsbHMge0Bjb2RlIGRlZmF1bHRBY3Rpb259LgogICAgICoKICAgICAqIEBwYXJhbSBub2RlIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gIHRoZSByZXN1bHQgb2Yge0Bjb2RlIGRlZmF1bHRBY3Rpb259CiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRBdXRob3IoQXV0aG9yVHJlZSBub2RlLCBQIHApIHsKICAgICAgICByZXR1cm4gZGVmYXVsdEFjdGlvbihub2RlLCBwKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30gVGhpcyBpbXBsZW1lbnRhdGlvbiBjYWxscyB7QGNvZGUgZGVmYXVsdEFjdGlvbn0uCiAgICAgKgogICAgICogQHBhcmFtIG5vZGUge0Bpbmhlcml0RG9jfQogICAgICogQHBhcmFtIHAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiAgdGhlIHJlc3VsdCBvZiB7QGNvZGUgZGVmYXVsdEFjdGlvbn0KICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgUiB2aXNpdENvbW1lbnQoQ29tbWVudFRyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIGRlZmF1bHRBY3Rpb24obm9kZSwgcCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gY2FsbHMge0Bjb2RlIGRlZmF1bHRBY3Rpb259LgogICAgICoKICAgICAqIEBwYXJhbSBub2RlIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gIHRoZSByZXN1bHQgb2Yge0Bjb2RlIGRlZmF1bHRBY3Rpb259CiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXREZXByZWNhdGVkKERlcHJlY2F0ZWRUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIHJldHVybiBkZWZhdWx0QWN0aW9uKG5vZGUsIHApOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIGNhbGxzIHtAY29kZSBkZWZhdWx0QWN0aW9ufS4KICAgICAqCiAgICAgKiBAcGFyYW0gbm9kZSB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuICB0aGUgcmVzdWx0IG9mIHtAY29kZSBkZWZhdWx0QWN0aW9ufQogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0RG9jQ29tbWVudChEb2NDb21tZW50VHJlZSBub2RlLCBQIHApIHsKICAgICAgICByZXR1cm4gZGVmYXVsdEFjdGlvbihub2RlLCBwKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30gVGhpcyBpbXBsZW1lbnRhdGlvbiBjYWxscyB7QGNvZGUgZGVmYXVsdEFjdGlvbn0uCiAgICAgKgogICAgICogQHBhcmFtIG5vZGUge0Bpbmhlcml0RG9jfQogICAgICogQHBhcmFtIHAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiAgdGhlIHJlc3VsdCBvZiB7QGNvZGUgZGVmYXVsdEFjdGlvbn0KICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgUiB2aXNpdERvY1Jvb3QoRG9jUm9vdFRyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIGRlZmF1bHRBY3Rpb24obm9kZSwgcCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gY2FsbHMge0Bjb2RlIGRlZmF1bHRBY3Rpb259LgogICAgICoKICAgICAqIEBwYXJhbSBub2RlIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gIHRoZSByZXN1bHQgb2Yge0Bjb2RlIGRlZmF1bHRBY3Rpb259CiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRFbmRFbGVtZW50KEVuZEVsZW1lbnRUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIHJldHVybiBkZWZhdWx0QWN0aW9uKG5vZGUsIHApOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIGNhbGxzIHtAY29kZSBkZWZhdWx0QWN0aW9ufS4KICAgICAqCiAgICAgKiBAcGFyYW0gbm9kZSB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuICB0aGUgcmVzdWx0IG9mIHtAY29kZSBkZWZhdWx0QWN0aW9ufQogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0RW50aXR5KEVudGl0eVRyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIGRlZmF1bHRBY3Rpb24obm9kZSwgcCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gY2FsbHMge0Bjb2RlIGRlZmF1bHRBY3Rpb259LgogICAgICoKICAgICAqIEBwYXJhbSBub2RlIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gIHRoZSByZXN1bHQgb2Yge0Bjb2RlIGRlZmF1bHRBY3Rpb259CiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRFcnJvbmVvdXMoRXJyb25lb3VzVHJlZSBub2RlLCBQIHApIHsKICAgICAgICByZXR1cm4gZGVmYXVsdEFjdGlvbihub2RlLCBwKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30gVGhpcyBpbXBsZW1lbnRhdGlvbiBjYWxscyB7QGNvZGUgZGVmYXVsdEFjdGlvbn0uCiAgICAgKgogICAgICogQHBhcmFtIG5vZGUge0Bpbmhlcml0RG9jfQogICAgICogQHBhcmFtIHAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiB0aGUgcmVzdWx0IG9mIHtAY29kZSBkZWZhdWx0QWN0aW9ufQogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0SGlkZGVuKEhpZGRlblRyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIGRlZmF1bHRBY3Rpb24obm9kZSwgcCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gY2FsbHMge0Bjb2RlIGRlZmF1bHRBY3Rpb259LgogICAgICoKICAgICAqIEBwYXJhbSBub2RlIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gIHRoZSByZXN1bHQgb2Yge0Bjb2RlIGRlZmF1bHRBY3Rpb259CiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRJZGVudGlmaWVyKElkZW50aWZpZXJUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIHJldHVybiBkZWZhdWx0QWN0aW9uKG5vZGUsIHApOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIGNhbGxzIHtAY29kZSBkZWZhdWx0QWN0aW9ufS4KICAgICAqCiAgICAgKiBAcGFyYW0gbm9kZSB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuICB0aGUgcmVzdWx0IG9mIHtAY29kZSBkZWZhdWx0QWN0aW9ufQogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0SW5kZXgoSW5kZXhUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIHJldHVybiBkZWZhdWx0QWN0aW9uKG5vZGUsIHApOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIGNhbGxzIHtAY29kZSBkZWZhdWx0QWN0aW9ufS4KICAgICAqCiAgICAgKiBAcGFyYW0gbm9kZSB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuICB0aGUgcmVzdWx0IG9mIHtAY29kZSBkZWZhdWx0QWN0aW9ufQogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0SW5oZXJpdERvYyhJbmhlcml0RG9jVHJlZSBub2RlLCBQIHApIHsKICAgICAgICByZXR1cm4gZGVmYXVsdEFjdGlvbihub2RlLCBwKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30gVGhpcyBpbXBsZW1lbnRhdGlvbiBjYWxscyB7QGNvZGUgZGVmYXVsdEFjdGlvbn0uCiAgICAgKgogICAgICogQHBhcmFtIG5vZGUge0Bpbmhlcml0RG9jfQogICAgICogQHBhcmFtIHAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiAgdGhlIHJlc3VsdCBvZiB7QGNvZGUgZGVmYXVsdEFjdGlvbn0KICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgUiB2aXNpdExpbmsoTGlua1RyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIGRlZmF1bHRBY3Rpb24obm9kZSwgcCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gY2FsbHMge0Bjb2RlIGRlZmF1bHRBY3Rpb259LgogICAgICoKICAgICAqIEBwYXJhbSBub2RlIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gIHRoZSByZXN1bHQgb2Yge0Bjb2RlIGRlZmF1bHRBY3Rpb259CiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRMaXRlcmFsKExpdGVyYWxUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIHJldHVybiBkZWZhdWx0QWN0aW9uKG5vZGUsIHApOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIGNhbGxzIHtAY29kZSBkZWZhdWx0QWN0aW9ufS4KICAgICAqCiAgICAgKiBAcGFyYW0gbm9kZSB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuICB0aGUgcmVzdWx0IG9mIHtAY29kZSBkZWZhdWx0QWN0aW9ufQogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0UGFyYW0oUGFyYW1UcmVlIG5vZGUsIFAgcCkgewogICAgICAgIHJldHVybiBkZWZhdWx0QWN0aW9uKG5vZGUsIHApOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIGNhbGxzIHtAY29kZSBkZWZhdWx0QWN0aW9ufS4KICAgICAqCiAgICAgKiBAcGFyYW0gbm9kZSB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuICB0aGUgcmVzdWx0IG9mIHtAY29kZSBkZWZhdWx0QWN0aW9ufQogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0UHJvdmlkZXMoUHJvdmlkZXNUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIHJldHVybiBkZWZhdWx0QWN0aW9uKG5vZGUsIHApOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIGNhbGxzIHtAY29kZSBkZWZhdWx0QWN0aW9ufS4KICAgICAqCiAgICAgKiBAcGFyYW0gbm9kZSB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuICB0aGUgcmVzdWx0IG9mIHtAY29kZSBkZWZhdWx0QWN0aW9ufQogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0UmVmZXJlbmNlKFJlZmVyZW5jZVRyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIGRlZmF1bHRBY3Rpb24obm9kZSwgcCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gY2FsbHMge0Bjb2RlIGRlZmF1bHRBY3Rpb259LgogICAgICoKICAgICAqIEBwYXJhbSBub2RlIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gIHRoZSByZXN1bHQgb2Yge0Bjb2RlIGRlZmF1bHRBY3Rpb259CiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRSZXR1cm4oUmV0dXJuVHJlZSBub2RlLCBQIHApIHsKICAgICAgICByZXR1cm4gZGVmYXVsdEFjdGlvbihub2RlLCBwKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30gVGhpcyBpbXBsZW1lbnRhdGlvbiBjYWxscyB7QGNvZGUgZGVmYXVsdEFjdGlvbn0uCiAgICAgKgogICAgICogQHBhcmFtIG5vZGUge0Bpbmhlcml0RG9jfQogICAgICogQHBhcmFtIHAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiAgdGhlIHJlc3VsdCBvZiB7QGNvZGUgZGVmYXVsdEFjdGlvbn0KICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgUiB2aXNpdFNlZShTZWVUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIHJldHVybiBkZWZhdWx0QWN0aW9uKG5vZGUsIHApOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIGNhbGxzIHtAY29kZSBkZWZhdWx0QWN0aW9ufS4KICAgICAqCiAgICAgKiBAcGFyYW0gbm9kZSB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuICB0aGUgcmVzdWx0IG9mIHtAY29kZSBkZWZhdWx0QWN0aW9ufQogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0U2VyaWFsKFNlcmlhbFRyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIGRlZmF1bHRBY3Rpb24obm9kZSwgcCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gY2FsbHMge0Bjb2RlIGRlZmF1bHRBY3Rpb259LgogICAgICoKICAgICAqIEBwYXJhbSBub2RlIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gIHRoZSByZXN1bHQgb2Yge0Bjb2RlIGRlZmF1bHRBY3Rpb259CiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRTZXJpYWxEYXRhKFNlcmlhbERhdGFUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIHJldHVybiBkZWZhdWx0QWN0aW9uKG5vZGUsIHApOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIGNhbGxzIHtAY29kZSBkZWZhdWx0QWN0aW9ufS4KICAgICAqCiAgICAgKiBAcGFyYW0gbm9kZSB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuICB0aGUgcmVzdWx0IG9mIHtAY29kZSBkZWZhdWx0QWN0aW9ufQogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0U2VyaWFsRmllbGQoU2VyaWFsRmllbGRUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIHJldHVybiBkZWZhdWx0QWN0aW9uKG5vZGUsIHApOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIGNhbGxzIHtAY29kZSBkZWZhdWx0QWN0aW9ufS4KICAgICAqCiAgICAgKiBAcGFyYW0gbm9kZSB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuICB0aGUgcmVzdWx0IG9mIHtAY29kZSBkZWZhdWx0QWN0aW9ufQogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0U2luY2UoU2luY2VUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIHJldHVybiBkZWZhdWx0QWN0aW9uKG5vZGUsIHApOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIGNhbGxzIHtAY29kZSBkZWZhdWx0QWN0aW9ufS4KICAgICAqCiAgICAgKiBAcGFyYW0gbm9kZSB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuICB0aGUgcmVzdWx0IG9mIHtAY29kZSBkZWZhdWx0QWN0aW9ufQogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0U3RhcnRFbGVtZW50KFN0YXJ0RWxlbWVudFRyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIGRlZmF1bHRBY3Rpb24obm9kZSwgcCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gY2FsbHMge0Bjb2RlIGRlZmF1bHRBY3Rpb259LgogICAgICoKICAgICAqIEBwYXJhbSBub2RlIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gIHRoZSByZXN1bHQgb2Yge0Bjb2RlIGRlZmF1bHRBY3Rpb259CiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRUZXh0KFRleHRUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIHJldHVybiBkZWZhdWx0QWN0aW9uKG5vZGUsIHApOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIGNhbGxzIHtAY29kZSBkZWZhdWx0QWN0aW9ufS4KICAgICAqCiAgICAgKiBAcGFyYW0gbm9kZSB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuICB0aGUgcmVzdWx0IG9mIHtAY29kZSBkZWZhdWx0QWN0aW9ufQogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0VGhyb3dzKFRocm93c1RyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIGRlZmF1bHRBY3Rpb24obm9kZSwgcCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gY2FsbHMge0Bjb2RlIGRlZmF1bHRBY3Rpb259LgogICAgICoKICAgICAqIEBwYXJhbSBub2RlIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gIHRoZSByZXN1bHQgb2Yge0Bjb2RlIGRlZmF1bHRBY3Rpb259CiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRVbmtub3duQmxvY2tUYWcoVW5rbm93bkJsb2NrVGFnVHJlZSBub2RlLCBQIHApIHsKICAgICAgICByZXR1cm4gZGVmYXVsdEFjdGlvbihub2RlLCBwKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30gVGhpcyBpbXBsZW1lbnRhdGlvbiBjYWxscyB7QGNvZGUgZGVmYXVsdEFjdGlvbn0uCiAgICAgKgogICAgICogQHBhcmFtIG5vZGUge0Bpbmhlcml0RG9jfQogICAgICogQHBhcmFtIHAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiAgdGhlIHJlc3VsdCBvZiB7QGNvZGUgZGVmYXVsdEFjdGlvbn0KICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgUiB2aXNpdFVua25vd25JbmxpbmVUYWcoVW5rbm93bklubGluZVRhZ1RyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIGRlZmF1bHRBY3Rpb24obm9kZSwgcCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gY2FsbHMge0Bjb2RlIGRlZmF1bHRBY3Rpb259LgogICAgICoKICAgICAqIEBwYXJhbSBub2RlIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gIHRoZSByZXN1bHQgb2Yge0Bjb2RlIGRlZmF1bHRBY3Rpb259CiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRVc2VzKFVzZXNUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIHJldHVybiBkZWZhdWx0QWN0aW9uKG5vZGUsIHApOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIGNhbGxzIHtAY29kZSBkZWZhdWx0QWN0aW9ufS4KICAgICAqCiAgICAgKiBAcGFyYW0gbm9kZSB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuICB0aGUgcmVzdWx0IG9mIHtAY29kZSBkZWZhdWx0QWN0aW9ufQogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0VmFsdWUoVmFsdWVUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIHJldHVybiBkZWZhdWx0QWN0aW9uKG5vZGUsIHApOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIGNhbGxzIHtAY29kZSBkZWZhdWx0QWN0aW9ufS4KICAgICAqCiAgICAgKiBAcGFyYW0gbm9kZSB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuICB0aGUgcmVzdWx0IG9mIHtAY29kZSBkZWZhdWx0QWN0aW9ufQogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0VmVyc2lvbihWZXJzaW9uVHJlZSBub2RlLCBQIHApIHsKICAgICAgICByZXR1cm4gZGVmYXVsdEFjdGlvbihub2RlLCBwKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30gVGhpcyBpbXBsZW1lbnRhdGlvbiBjYWxscyB7QGNvZGUgZGVmYXVsdEFjdGlvbn0uCiAgICAgKgogICAgICogQHBhcmFtIG5vZGUge0Bpbmhlcml0RG9jfQogICAgICogQHBhcmFtIHAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiAgdGhlIHJlc3VsdCBvZiB7QGNvZGUgZGVmYXVsdEFjdGlvbn0KICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgUiB2aXNpdE90aGVyKERvY1RyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIGRlZmF1bHRBY3Rpb24obm9kZSwgcCk7CiAgICB9Cgp9ClBLAwQKAAAIAAAGO6lKWXQsCMprAADKawAAJAAAAGNvbS9zdW4vc291cmNlL3V0aWwvVHJlZVNjYW5uZXIuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAxNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnNvdXJjZS51dGlsOwoKaW1wb3J0IGNvbS5zdW4uc291cmNlLnRyZWUuKjsKCi8qKgogKiBBIFRyZWVWaXNpdG9yIHRoYXQgdmlzaXRzIGFsbCB0aGUgY2hpbGQgdHJlZSBub2Rlcy4KICogVG8gdmlzaXQgbm9kZXMgb2YgYSBwYXJ0aWN1bGFyIHR5cGUsIGp1c3Qgb3ZlcnJpZGUgdGhlCiAqIGNvcnJlc3BvbmRpbmcgdmlzaXRYWVogbWV0aG9kLgogKiBJbnNpZGUgeW91ciBtZXRob2QsIGNhbGwgc3VwZXIudmlzaXRYWVogdG8gdmlzaXQgZGVzY2VuZGFudAogKiBub2Rlcy4KICoKICogPHA+VGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gb2YgdGhlIHZpc2l0WFlaIG1ldGhvZHMgd2lsbCBkZXRlcm1pbmUKICogYSByZXN1bHQgYXMgZm9sbG93czoKICogPHVsPgogKiA8bGk+SWYgdGhlIG5vZGUgYmVpbmcgdmlzaXRlZCBoYXMgbm8gY2hpbGRyZW4sIHRoZSByZXN1bHQgd2lsbCBiZSB7QGNvZGUgbnVsbH0uCiAqIDxsaT5JZiB0aGUgbm9kZSBiZWluZyB2aXNpdGVkIGhhcyBvbmUgY2hpbGQsIHRoZSByZXN1bHQgd2lsbCBiZSB0aGUKICogcmVzdWx0IG9mIGNhbGxpbmcge0Bjb2RlIHNjYW59IG9uIHRoYXQgY2hpbGQuIFRoZSBjaGlsZCBtYXkgYmUgYSBzaW1wbGUgbm9kZQogKiBvciBpdHNlbGYgYSBsaXN0IG9mIG5vZGVzLgogKiA8bGk+IElmIHRoZSBub2RlIGJlaW5nIHZpc2l0ZWQgaGFzIG1vcmUgdGhhbiBvbmUgY2hpbGQsIHRoZSByZXN1bHQgd2lsbAogKiBiZSBkZXRlcm1pbmVkIGJ5IGNhbGxpbmcge0Bjb2RlIHNjYW59IGVhY2ggY2hpbGQgaW4gdHVybiwgYW5kIHRoZW4gY29tYmluaW5nIHRoZQogKiByZXN1bHQgb2YgZWFjaCBzY2FuIGFmdGVyIHRoZSBmaXJzdCB3aXRoIHRoZSBjdW11bGF0aXZlIHJlc3VsdAogKiBzbyBmYXIsIGFzIGRldGVybWluZWQgYnkgdGhlIHtAbGluayAjcmVkdWNlfSBtZXRob2QuIEVhY2ggY2hpbGQgbWF5IGJlIGVpdGhlcgogKiBhIHNpbXBsZSBub2RlIG9mIGEgbGlzdCBvZiBub2Rlcy4gVGhlIGRlZmF1bHQgYmVoYXZpb3Igb2YgdGhlIHtAY29kZSByZWR1Y2V9CiAqIG1ldGhvZCBpcyBzdWNoIHRoYXQgdGhlIHJlc3VsdCBvZiB0aGUgdmlzaXRYWVogbWV0aG9kIHdpbGwgYmUgdGhlIHJlc3VsdCBvZgogKiB0aGUgbGFzdCBjaGlsZCBzY2FubmVkLgogKiA8L3VsPgogKgogKiA8cD5IZXJlIGlzIGFuIGV4YW1wbGUgdG8gY291bnQgdGhlIG51bWJlciBvZiBpZGVudGlmaWVyIG5vZGVzIGluIGEgdHJlZToKICogPHByZT4KICogICBjbGFzcyBDb3VudElkZW50aWZpZXJzIGV4dGVuZHMgVHJlZVNjYW5uZXImbHQ7SW50ZWdlcixWb2lkJmd0OyB7CiAqICAgICAge0BsaXRlcmFsIEB9T3ZlcnJpZGUKICogICAgICBwdWJsaWMgSW50ZWdlciB2aXNpdElkZW50aWZpZXIoSWRlbnRpZmllclRyZWUgbm9kZSwgVm9pZCBwKSB7CiAqICAgICAgICAgIHJldHVybiAxOwogKiAgICAgIH0KICogICAgICB7QGxpdGVyYWwgQH1PdmVycmlkZQogKiAgICAgIHB1YmxpYyBJbnRlZ2VyIHJlZHVjZShJbnRlZ2VyIHIxLCBJbnRlZ2VyIHIyKSB7CiAqICAgICAgICAgIHJldHVybiAocjEgPT0gbnVsbCA/IDAgOiByMSkgKyAocjIgPT0gbnVsbCA/IDAgOiByMik7CiAqICAgICAgfQogKiAgIH0KICogPC9wcmU+CiAqCiAqIEBwYXJhbSA8Uj4gdGhlIHJldHVybiB0eXBlIG9mIHRoaXMgdmlzaXRvcidzIG1ldGhvZHMuICBVc2Uge0BsaW5rCiAqICAgICAgICAgICAgVm9pZH0gZm9yIHZpc2l0b3JzIHRoYXQgZG8gbm90IG5lZWQgdG8gcmV0dXJuIHJlc3VsdHMuCiAqIEBwYXJhbSA8UD4gdGhlIHR5cGUgb2YgdGhlIGFkZGl0aW9uYWwgcGFyYW1ldGVyIHRvIHRoaXMgdmlzaXRvcidzCiAqICAgICAgICAgICAgbWV0aG9kcy4gIFVzZSB7QGNvZGUgVm9pZH0gZm9yIHZpc2l0b3JzIHRoYXQgZG8gbm90IG5lZWQgYW4KICogICAgICAgICAgICBhZGRpdGlvbmFsIHBhcmFtZXRlci4KICoKICogQGF1dGhvciBQZXRlciB2b24gZGVyIEFoJmVhY3V0ZTsKICogQGF1dGhvciBKb25hdGhhbiBHaWJib25zCiAqIEBzaW5jZSAxLjYKICovCnB1YmxpYyBjbGFzcyBUcmVlU2Nhbm5lcjxSLFA+IGltcGxlbWVudHMgVHJlZVZpc2l0b3I8UixQPiB7CgogICAgLyoqCiAgICAgKiBTY2FucyBhIHNpbmdsZSBub2RlLgogICAgICogQHBhcmFtIHRyZWUgdGhlIG5vZGUgdG8gYmUgc2Nhbm5lZAogICAgICogQHBhcmFtIHAgYSBwYXJhbWV0ZXIgdmFsdWUgcGFzc2VkIHRvIHRoZSB2aXNpdCBtZXRob2QKICAgICAqIEByZXR1cm4gdGhlIHJlc3VsdCB2YWx1ZSBmcm9tIHRoZSB2aXNpdCBtZXRob2QKICAgICAqLwogICAgcHVibGljIFIgc2NhbihUcmVlIHRyZWUsIFAgcCkgewogICAgICAgIHJldHVybiAodHJlZSA9PSBudWxsKSA/IG51bGwgOiB0cmVlLmFjY2VwdCh0aGlzLCBwKTsKICAgIH0KCiAgICBwcml2YXRlIFIgc2NhbkFuZFJlZHVjZShUcmVlIG5vZGUsIFAgcCwgUiByKSB7CiAgICAgICAgcmV0dXJuIHJlZHVjZShzY2FuKG5vZGUsIHApLCByKTsKICAgIH0KCiAgICAvKioKICAgICAqIFNjYW5zIGEgc2VxdWVuY2Ugb2Ygbm9kZXMuCiAgICAgKiBAcGFyYW0gbm9kZXMgdGhlIG5vZGVzIHRvIGJlIHNjYW5uZWQKICAgICAqIEBwYXJhbSBwIGEgcGFyYW1ldGVyIHZhbHVlIHRvIGJlIHBhc3NlZCB0byB0aGUgdmlzaXQgbWV0aG9kIGZvciBlYWNoIG5vZGUKICAgICAqIEByZXR1cm4gdGhlIGNvbWJpbmVkIHJldHVybiB2YWx1ZSBmcm9tIHRoZSB2aXNpdCBtZXRob2RzLgogICAgICogICAgICBUaGUgdmFsdWVzIGFyZSBjb21iaW5lZCB1c2luZyB0aGUge0BsaW5rICNyZWR1Y2UgcmVkdWNlfSBtZXRob2QuCiAgICAgKi8KICAgIHB1YmxpYyBSIHNjYW4oSXRlcmFibGU8PyBleHRlbmRzIFRyZWU+IG5vZGVzLCBQIHApIHsKICAgICAgICBSIHIgPSBudWxsOwogICAgICAgIGlmIChub2RlcyAhPSBudWxsKSB7CiAgICAgICAgICAgIGJvb2xlYW4gZmlyc3QgPSB0cnVlOwogICAgICAgICAgICBmb3IgKFRyZWUgbm9kZSA6IG5vZGVzKSB7CiAgICAgICAgICAgICAgICByID0gKGZpcnN0ID8gc2Nhbihub2RlLCBwKSA6IHNjYW5BbmRSZWR1Y2Uobm9kZSwgcCwgcikpOwogICAgICAgICAgICAgICAgZmlyc3QgPSBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gcjsKICAgIH0KCiAgICBwcml2YXRlIFIgc2NhbkFuZFJlZHVjZShJdGVyYWJsZTw/IGV4dGVuZHMgVHJlZT4gbm9kZXMsIFAgcCwgUiByKSB7CiAgICAgICAgcmV0dXJuIHJlZHVjZShzY2FuKG5vZGVzLCBwKSwgcik7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZWR1Y2VzIHR3byByZXN1bHRzIGludG8gYSBjb21iaW5lZCByZXN1bHQuCiAgICAgKiBUaGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBpcyB0byByZXR1cm4gdGhlIGZpcnN0IHBhcmFtZXRlci4KICAgICAqIFRoZSBnZW5lcmFsIGNvbnRyYWN0IG9mIHRoZSBtZXRob2QgaXMgdGhhdCBpdCBtYXkgdGFrZSBhbnkgYWN0aW9uIHdoYXRzb2V2ZXIuCiAgICAgKiBAcGFyYW0gcjEgdGhlIGZpcnN0IG9mIHRoZSB2YWx1ZXMgdG8gYmUgY29tYmluZWQKICAgICAqIEBwYXJhbSByMiB0aGUgc2Vjb25kIG9mIHRoZSB2YWx1ZXMgdG8gYmUgY29tYmluZWQKICAgICAqIEByZXR1cm4gdGhlIHJlc3VsdCBvZiBjb21iaW5pbmcgdGhlIHR3byBwYXJhbWV0ZXJzCiAgICAgKi8KICAgIHB1YmxpYyBSIHJlZHVjZShSIHIxLCBSIHIyKSB7CiAgICAgICAgcmV0dXJuIHIxOwogICAgfQoKCi8qICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBWaXNpdG9yIG1ldGhvZHMKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gc2NhbnMgdGhlIGNoaWxkcmVuIGluIGxlZnQgdG8gcmlnaHQgb3JkZXIuCiAgICAgKgogICAgICogQHBhcmFtIG5vZGUgIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwICB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuIHRoZSByZXN1bHQgb2Ygc2Nhbm5pbmcKICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgUiB2aXNpdENvbXBpbGF0aW9uVW5pdChDb21waWxhdGlvblVuaXRUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIFIgciA9IHNjYW4obm9kZS5nZXRQYWNrYWdlKCksIHApOwogICAgICAgIHIgPSBzY2FuQW5kUmVkdWNlKG5vZGUuZ2V0SW1wb3J0cygpLCBwLCByKTsKICAgICAgICByID0gc2NhbkFuZFJlZHVjZShub2RlLmdldFR5cGVEZWNscygpLCBwLCByKTsKICAgICAgICByZXR1cm4gcjsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30gVGhpcyBpbXBsZW1lbnRhdGlvbiBzY2FucyB0aGUgY2hpbGRyZW4gaW4gbGVmdCB0byByaWdodCBvcmRlci4KICAgICAqCiAgICAgKiBAcGFyYW0gbm9kZSAge0Bpbmhlcml0RG9jfQogICAgICogQHBhcmFtIHAgIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gdGhlIHJlc3VsdCBvZiBzY2FubmluZwogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0UGFja2FnZShQYWNrYWdlVHJlZSBub2RlLCBQIHApIHsKICAgICAgICBSIHIgPSBzY2FuKG5vZGUuZ2V0QW5ub3RhdGlvbnMoKSwgcCk7CiAgICAgICAgciA9IHNjYW5BbmRSZWR1Y2Uobm9kZS5nZXRQYWNrYWdlTmFtZSgpLCBwLCByKTsKICAgICAgICByZXR1cm4gcjsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30gVGhpcyBpbXBsZW1lbnRhdGlvbiBzY2FucyB0aGUgY2hpbGRyZW4gaW4gbGVmdCB0byByaWdodCBvcmRlci4KICAgICAqCiAgICAgKiBAcGFyYW0gbm9kZSAge0Bpbmhlcml0RG9jfQogICAgICogQHBhcmFtIHAgIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gdGhlIHJlc3VsdCBvZiBzY2FubmluZwogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0SW1wb3J0KEltcG9ydFRyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIHNjYW4obm9kZS5nZXRRdWFsaWZpZWRJZGVudGlmaWVyKCksIHApOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIHNjYW5zIHRoZSBjaGlsZHJlbiBpbiBsZWZ0IHRvIHJpZ2h0IG9yZGVyLgogICAgICoKICAgICAqIEBwYXJhbSBub2RlICB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiB0aGUgcmVzdWx0IG9mIHNjYW5uaW5nCiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRDbGFzcyhDbGFzc1RyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgUiByID0gc2Nhbihub2RlLmdldE1vZGlmaWVycygpLCBwKTsKICAgICAgICByID0gc2NhbkFuZFJlZHVjZShub2RlLmdldFR5cGVQYXJhbWV0ZXJzKCksIHAsIHIpOwogICAgICAgIHIgPSBzY2FuQW5kUmVkdWNlKG5vZGUuZ2V0RXh0ZW5kc0NsYXVzZSgpLCBwLCByKTsKICAgICAgICByID0gc2NhbkFuZFJlZHVjZShub2RlLmdldEltcGxlbWVudHNDbGF1c2UoKSwgcCwgcik7CiAgICAgICAgciA9IHNjYW5BbmRSZWR1Y2Uobm9kZS5nZXRNZW1iZXJzKCksIHAsIHIpOwogICAgICAgIHJldHVybiByOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIHNjYW5zIHRoZSBjaGlsZHJlbiBpbiBsZWZ0IHRvIHJpZ2h0IG9yZGVyLgogICAgICoKICAgICAqIEBwYXJhbSBub2RlICB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiB0aGUgcmVzdWx0IG9mIHNjYW5uaW5nCiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRNZXRob2QoTWV0aG9kVHJlZSBub2RlLCBQIHApIHsKICAgICAgICBSIHIgPSBzY2FuKG5vZGUuZ2V0TW9kaWZpZXJzKCksIHApOwogICAgICAgIHIgPSBzY2FuQW5kUmVkdWNlKG5vZGUuZ2V0UmV0dXJuVHlwZSgpLCBwLCByKTsKICAgICAgICByID0gc2NhbkFuZFJlZHVjZShub2RlLmdldFR5cGVQYXJhbWV0ZXJzKCksIHAsIHIpOwogICAgICAgIHIgPSBzY2FuQW5kUmVkdWNlKG5vZGUuZ2V0UGFyYW1ldGVycygpLCBwLCByKTsKICAgICAgICByID0gc2NhbkFuZFJlZHVjZShub2RlLmdldFJlY2VpdmVyUGFyYW1ldGVyKCksIHAsIHIpOwogICAgICAgIHIgPSBzY2FuQW5kUmVkdWNlKG5vZGUuZ2V0VGhyb3dzKCksIHAsIHIpOwogICAgICAgIHIgPSBzY2FuQW5kUmVkdWNlKG5vZGUuZ2V0Qm9keSgpLCBwLCByKTsKICAgICAgICByID0gc2NhbkFuZFJlZHVjZShub2RlLmdldERlZmF1bHRWYWx1ZSgpLCBwLCByKTsKICAgICAgICByZXR1cm4gcjsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30gVGhpcyBpbXBsZW1lbnRhdGlvbiBzY2FucyB0aGUgY2hpbGRyZW4gaW4gbGVmdCB0byByaWdodCBvcmRlci4KICAgICAqCiAgICAgKiBAcGFyYW0gbm9kZSAge0Bpbmhlcml0RG9jfQogICAgICogQHBhcmFtIHAgIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gdGhlIHJlc3VsdCBvZiBzY2FubmluZwogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0VmFyaWFibGUoVmFyaWFibGVUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIFIgciA9IHNjYW4obm9kZS5nZXRNb2RpZmllcnMoKSwgcCk7CiAgICAgICAgciA9IHNjYW5BbmRSZWR1Y2Uobm9kZS5nZXRUeXBlKCksIHAsIHIpOwogICAgICAgIHIgPSBzY2FuQW5kUmVkdWNlKG5vZGUuZ2V0TmFtZUV4cHJlc3Npb24oKSwgcCwgcik7CiAgICAgICAgciA9IHNjYW5BbmRSZWR1Y2Uobm9kZS5nZXRJbml0aWFsaXplcigpLCBwLCByKTsKICAgICAgICByZXR1cm4gcjsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30gVGhpcyBpbXBsZW1lbnRhdGlvbiByZXR1cm5zIHtAY29kZSBudWxsfS4KICAgICAqCiAgICAgKiBAcGFyYW0gbm9kZSAge0Bpbmhlcml0RG9jfQogICAgICogQHBhcmFtIHAgIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gdGhlIHJlc3VsdCBvZiBzY2FubmluZwogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0RW1wdHlTdGF0ZW1lbnQoRW1wdHlTdGF0ZW1lbnRUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIHNjYW5zIHRoZSBjaGlsZHJlbiBpbiBsZWZ0IHRvIHJpZ2h0IG9yZGVyLgogICAgICoKICAgICAqIEBwYXJhbSBub2RlICB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiB0aGUgcmVzdWx0IG9mIHNjYW5uaW5nCiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRCbG9jayhCbG9ja1RyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIHNjYW4obm9kZS5nZXRTdGF0ZW1lbnRzKCksIHApOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIHNjYW5zIHRoZSBjaGlsZHJlbiBpbiBsZWZ0IHRvIHJpZ2h0IG9yZGVyLgogICAgICoKICAgICAqIEBwYXJhbSBub2RlICB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiB0aGUgcmVzdWx0IG9mIHNjYW5uaW5nCiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXREb1doaWxlTG9vcChEb1doaWxlTG9vcFRyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgUiByID0gc2Nhbihub2RlLmdldFN0YXRlbWVudCgpLCBwKTsKICAgICAgICByID0gc2NhbkFuZFJlZHVjZShub2RlLmdldENvbmRpdGlvbigpLCBwLCByKTsKICAgICAgICByZXR1cm4gcjsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30gVGhpcyBpbXBsZW1lbnRhdGlvbiBzY2FucyB0aGUgY2hpbGRyZW4gaW4gbGVmdCB0byByaWdodCBvcmRlci4KICAgICAqCiAgICAgKiBAcGFyYW0gbm9kZSAge0Bpbmhlcml0RG9jfQogICAgICogQHBhcmFtIHAgIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gdGhlIHJlc3VsdCBvZiBzY2FubmluZwogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0V2hpbGVMb29wKFdoaWxlTG9vcFRyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgUiByID0gc2Nhbihub2RlLmdldENvbmRpdGlvbigpLCBwKTsKICAgICAgICByID0gc2NhbkFuZFJlZHVjZShub2RlLmdldFN0YXRlbWVudCgpLCBwLCByKTsKICAgICAgICByZXR1cm4gcjsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30gVGhpcyBpbXBsZW1lbnRhdGlvbiBzY2FucyB0aGUgY2hpbGRyZW4gaW4gbGVmdCB0byByaWdodCBvcmRlci4KICAgICAqCiAgICAgKiBAcGFyYW0gbm9kZSAge0Bpbmhlcml0RG9jfQogICAgICogQHBhcmFtIHAgIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gdGhlIHJlc3VsdCBvZiBzY2FubmluZwogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0Rm9yTG9vcChGb3JMb29wVHJlZSBub2RlLCBQIHApIHsKICAgICAgICBSIHIgPSBzY2FuKG5vZGUuZ2V0SW5pdGlhbGl6ZXIoKSwgcCk7CiAgICAgICAgciA9IHNjYW5BbmRSZWR1Y2Uobm9kZS5nZXRDb25kaXRpb24oKSwgcCwgcik7CiAgICAgICAgciA9IHNjYW5BbmRSZWR1Y2Uobm9kZS5nZXRVcGRhdGUoKSwgcCwgcik7CiAgICAgICAgciA9IHNjYW5BbmRSZWR1Y2Uobm9kZS5nZXRTdGF0ZW1lbnQoKSwgcCwgcik7CiAgICAgICAgcmV0dXJuIHI7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gc2NhbnMgdGhlIGNoaWxkcmVuIGluIGxlZnQgdG8gcmlnaHQgb3JkZXIuCiAgICAgKgogICAgICogQHBhcmFtIG5vZGUgIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwICB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuIHRoZSByZXN1bHQgb2Ygc2Nhbm5pbmcKICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgUiB2aXNpdEVuaGFuY2VkRm9yTG9vcChFbmhhbmNlZEZvckxvb3BUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIFIgciA9IHNjYW4obm9kZS5nZXRWYXJpYWJsZSgpLCBwKTsKICAgICAgICByID0gc2NhbkFuZFJlZHVjZShub2RlLmdldEV4cHJlc3Npb24oKSwgcCwgcik7CiAgICAgICAgciA9IHNjYW5BbmRSZWR1Y2Uobm9kZS5nZXRTdGF0ZW1lbnQoKSwgcCwgcik7CiAgICAgICAgcmV0dXJuIHI7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gc2NhbnMgdGhlIGNoaWxkcmVuIGluIGxlZnQgdG8gcmlnaHQgb3JkZXIuCiAgICAgKgogICAgICogQHBhcmFtIG5vZGUgIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwICB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuIHRoZSByZXN1bHQgb2Ygc2Nhbm5pbmcKICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgUiB2aXNpdExhYmVsZWRTdGF0ZW1lbnQoTGFiZWxlZFN0YXRlbWVudFRyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIHNjYW4obm9kZS5nZXRTdGF0ZW1lbnQoKSwgcCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gc2NhbnMgdGhlIGNoaWxkcmVuIGluIGxlZnQgdG8gcmlnaHQgb3JkZXIuCiAgICAgKgogICAgICogQHBhcmFtIG5vZGUgIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwICB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuIHRoZSByZXN1bHQgb2Ygc2Nhbm5pbmcKICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgUiB2aXNpdFN3aXRjaChTd2l0Y2hUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIFIgciA9IHNjYW4obm9kZS5nZXRFeHByZXNzaW9uKCksIHApOwogICAgICAgIHIgPSBzY2FuQW5kUmVkdWNlKG5vZGUuZ2V0Q2FzZXMoKSwgcCwgcik7CiAgICAgICAgcmV0dXJuIHI7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gc2NhbnMgdGhlIGNoaWxkcmVuIGluIGxlZnQgdG8gcmlnaHQgb3JkZXIuCiAgICAgKgogICAgICogQHBhcmFtIG5vZGUgIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwICB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuIHRoZSByZXN1bHQgb2Ygc2Nhbm5pbmcKICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgUiB2aXNpdENhc2UoQ2FzZVRyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgUiByID0gc2Nhbihub2RlLmdldEV4cHJlc3Npb24oKSwgcCk7CiAgICAgICAgciA9IHNjYW5BbmRSZWR1Y2Uobm9kZS5nZXRTdGF0ZW1lbnRzKCksIHAsIHIpOwogICAgICAgIHJldHVybiByOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIHNjYW5zIHRoZSBjaGlsZHJlbiBpbiBsZWZ0IHRvIHJpZ2h0IG9yZGVyLgogICAgICoKICAgICAqIEBwYXJhbSBub2RlICB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiB0aGUgcmVzdWx0IG9mIHNjYW5uaW5nCiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRTeW5jaHJvbml6ZWQoU3luY2hyb25pemVkVHJlZSBub2RlLCBQIHApIHsKICAgICAgICBSIHIgPSBzY2FuKG5vZGUuZ2V0RXhwcmVzc2lvbigpLCBwKTsKICAgICAgICByID0gc2NhbkFuZFJlZHVjZShub2RlLmdldEJsb2NrKCksIHAsIHIpOwogICAgICAgIHJldHVybiByOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIHNjYW5zIHRoZSBjaGlsZHJlbiBpbiBsZWZ0IHRvIHJpZ2h0IG9yZGVyLgogICAgICoKICAgICAqIEBwYXJhbSBub2RlICB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiB0aGUgcmVzdWx0IG9mIHNjYW5uaW5nCiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRUcnkoVHJ5VHJlZSBub2RlLCBQIHApIHsKICAgICAgICBSIHIgPSBzY2FuKG5vZGUuZ2V0UmVzb3VyY2VzKCksIHApOwogICAgICAgIHIgPSBzY2FuQW5kUmVkdWNlKG5vZGUuZ2V0QmxvY2soKSwgcCwgcik7CiAgICAgICAgciA9IHNjYW5BbmRSZWR1Y2Uobm9kZS5nZXRDYXRjaGVzKCksIHAsIHIpOwogICAgICAgIHIgPSBzY2FuQW5kUmVkdWNlKG5vZGUuZ2V0RmluYWxseUJsb2NrKCksIHAsIHIpOwogICAgICAgIHJldHVybiByOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIHNjYW5zIHRoZSBjaGlsZHJlbiBpbiBsZWZ0IHRvIHJpZ2h0IG9yZGVyLgogICAgICoKICAgICAqIEBwYXJhbSBub2RlICB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiB0aGUgcmVzdWx0IG9mIHNjYW5uaW5nCiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRDYXRjaChDYXRjaFRyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgUiByID0gc2Nhbihub2RlLmdldFBhcmFtZXRlcigpLCBwKTsKICAgICAgICByID0gc2NhbkFuZFJlZHVjZShub2RlLmdldEJsb2NrKCksIHAsIHIpOwogICAgICAgIHJldHVybiByOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIHNjYW5zIHRoZSBjaGlsZHJlbiBpbiBsZWZ0IHRvIHJpZ2h0IG9yZGVyLgogICAgICoKICAgICAqIEBwYXJhbSBub2RlICB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiB0aGUgcmVzdWx0IG9mIHNjYW5uaW5nCiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRDb25kaXRpb25hbEV4cHJlc3Npb24oQ29uZGl0aW9uYWxFeHByZXNzaW9uVHJlZSBub2RlLCBQIHApIHsKICAgICAgICBSIHIgPSBzY2FuKG5vZGUuZ2V0Q29uZGl0aW9uKCksIHApOwogICAgICAgIHIgPSBzY2FuQW5kUmVkdWNlKG5vZGUuZ2V0VHJ1ZUV4cHJlc3Npb24oKSwgcCwgcik7CiAgICAgICAgciA9IHNjYW5BbmRSZWR1Y2Uobm9kZS5nZXRGYWxzZUV4cHJlc3Npb24oKSwgcCwgcik7CiAgICAgICAgcmV0dXJuIHI7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gc2NhbnMgdGhlIGNoaWxkcmVuIGluIGxlZnQgdG8gcmlnaHQgb3JkZXIuCiAgICAgKgogICAgICogQHBhcmFtIG5vZGUgIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwICB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuIHRoZSByZXN1bHQgb2Ygc2Nhbm5pbmcKICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgUiB2aXNpdElmKElmVHJlZSBub2RlLCBQIHApIHsKICAgICAgICBSIHIgPSBzY2FuKG5vZGUuZ2V0Q29uZGl0aW9uKCksIHApOwogICAgICAgIHIgPSBzY2FuQW5kUmVkdWNlKG5vZGUuZ2V0VGhlblN0YXRlbWVudCgpLCBwLCByKTsKICAgICAgICByID0gc2NhbkFuZFJlZHVjZShub2RlLmdldEVsc2VTdGF0ZW1lbnQoKSwgcCwgcik7CiAgICAgICAgcmV0dXJuIHI7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gc2NhbnMgdGhlIGNoaWxkcmVuIGluIGxlZnQgdG8gcmlnaHQgb3JkZXIuCiAgICAgKgogICAgICogQHBhcmFtIG5vZGUgIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwICB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuIHRoZSByZXN1bHQgb2Ygc2Nhbm5pbmcKICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgUiB2aXNpdEV4cHJlc3Npb25TdGF0ZW1lbnQoRXhwcmVzc2lvblN0YXRlbWVudFRyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIHNjYW4obm9kZS5nZXRFeHByZXNzaW9uKCksIHApOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIHJldHVybnMge0Bjb2RlIG51bGx9LgogICAgICoKICAgICAqIEBwYXJhbSBub2RlICB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiB0aGUgcmVzdWx0IG9mIHNjYW5uaW5nCiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRCcmVhayhCcmVha1RyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gcmV0dXJucyB7QGNvZGUgbnVsbH0uCiAgICAgKgogICAgICogQHBhcmFtIG5vZGUgIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwICB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuIHRoZSByZXN1bHQgb2Ygc2Nhbm5pbmcKICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgUiB2aXNpdENvbnRpbnVlKENvbnRpbnVlVHJlZSBub2RlLCBQIHApIHsKICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30gVGhpcyBpbXBsZW1lbnRhdGlvbiBzY2FucyB0aGUgY2hpbGRyZW4gaW4gbGVmdCB0byByaWdodCBvcmRlci4KICAgICAqCiAgICAgKiBAcGFyYW0gbm9kZSAge0Bpbmhlcml0RG9jfQogICAgICogQHBhcmFtIHAgIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gdGhlIHJlc3VsdCBvZiBzY2FubmluZwogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0UmV0dXJuKFJldHVyblRyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIHNjYW4obm9kZS5nZXRFeHByZXNzaW9uKCksIHApOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIHNjYW5zIHRoZSBjaGlsZHJlbiBpbiBsZWZ0IHRvIHJpZ2h0IG9yZGVyLgogICAgICoKICAgICAqIEBwYXJhbSBub2RlICB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiB0aGUgcmVzdWx0IG9mIHNjYW5uaW5nCiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRUaHJvdyhUaHJvd1RyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIHNjYW4obm9kZS5nZXRFeHByZXNzaW9uKCksIHApOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIHNjYW5zIHRoZSBjaGlsZHJlbiBpbiBsZWZ0IHRvIHJpZ2h0IG9yZGVyLgogICAgICoKICAgICAqIEBwYXJhbSBub2RlICB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiB0aGUgcmVzdWx0IG9mIHNjYW5uaW5nCiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRBc3NlcnQoQXNzZXJ0VHJlZSBub2RlLCBQIHApIHsKICAgICAgICBSIHIgPSBzY2FuKG5vZGUuZ2V0Q29uZGl0aW9uKCksIHApOwogICAgICAgIHIgPSBzY2FuQW5kUmVkdWNlKG5vZGUuZ2V0RGV0YWlsKCksIHAsIHIpOwogICAgICAgIHJldHVybiByOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIHNjYW5zIHRoZSBjaGlsZHJlbiBpbiBsZWZ0IHRvIHJpZ2h0IG9yZGVyLgogICAgICoKICAgICAqIEBwYXJhbSBub2RlICB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiB0aGUgcmVzdWx0IG9mIHNjYW5uaW5nCiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRNZXRob2RJbnZvY2F0aW9uKE1ldGhvZEludm9jYXRpb25UcmVlIG5vZGUsIFAgcCkgewogICAgICAgIFIgciA9IHNjYW4obm9kZS5nZXRUeXBlQXJndW1lbnRzKCksIHApOwogICAgICAgIHIgPSBzY2FuQW5kUmVkdWNlKG5vZGUuZ2V0TWV0aG9kU2VsZWN0KCksIHAsIHIpOwogICAgICAgIHIgPSBzY2FuQW5kUmVkdWNlKG5vZGUuZ2V0QXJndW1lbnRzKCksIHAsIHIpOwogICAgICAgIHJldHVybiByOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIHNjYW5zIHRoZSBjaGlsZHJlbiBpbiBsZWZ0IHRvIHJpZ2h0IG9yZGVyLgogICAgICoKICAgICAqIEBwYXJhbSBub2RlICB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiB0aGUgcmVzdWx0IG9mIHNjYW5uaW5nCiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXROZXdDbGFzcyhOZXdDbGFzc1RyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgUiByID0gc2Nhbihub2RlLmdldEVuY2xvc2luZ0V4cHJlc3Npb24oKSwgcCk7CiAgICAgICAgciA9IHNjYW5BbmRSZWR1Y2Uobm9kZS5nZXRJZGVudGlmaWVyKCksIHAsIHIpOwogICAgICAgIHIgPSBzY2FuQW5kUmVkdWNlKG5vZGUuZ2V0VHlwZUFyZ3VtZW50cygpLCBwLCByKTsKICAgICAgICByID0gc2NhbkFuZFJlZHVjZShub2RlLmdldEFyZ3VtZW50cygpLCBwLCByKTsKICAgICAgICByID0gc2NhbkFuZFJlZHVjZShub2RlLmdldENsYXNzQm9keSgpLCBwLCByKTsKICAgICAgICByZXR1cm4gcjsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30gVGhpcyBpbXBsZW1lbnRhdGlvbiBzY2FucyB0aGUgY2hpbGRyZW4gaW4gbGVmdCB0byByaWdodCBvcmRlci4KICAgICAqCiAgICAgKiBAcGFyYW0gbm9kZSAge0Bpbmhlcml0RG9jfQogICAgICogQHBhcmFtIHAgIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gdGhlIHJlc3VsdCBvZiBzY2FubmluZwogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0TmV3QXJyYXkoTmV3QXJyYXlUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIFIgciA9IHNjYW4obm9kZS5nZXRUeXBlKCksIHApOwogICAgICAgIHIgPSBzY2FuQW5kUmVkdWNlKG5vZGUuZ2V0RGltZW5zaW9ucygpLCBwLCByKTsKICAgICAgICByID0gc2NhbkFuZFJlZHVjZShub2RlLmdldEluaXRpYWxpemVycygpLCBwLCByKTsKICAgICAgICByID0gc2NhbkFuZFJlZHVjZShub2RlLmdldEFubm90YXRpb25zKCksIHAsIHIpOwogICAgICAgIGZvciAoSXRlcmFibGU8ID8gZXh0ZW5kcyBUcmVlPiBkaW1Bbm5vIDogbm9kZS5nZXREaW1Bbm5vdGF0aW9ucygpKSB7CiAgICAgICAgICAgIHIgPSBzY2FuQW5kUmVkdWNlKGRpbUFubm8sIHAsIHIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcjsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30gVGhpcyBpbXBsZW1lbnRhdGlvbiBzY2FucyB0aGUgY2hpbGRyZW4gaW4gbGVmdCB0byByaWdodCBvcmRlci4KICAgICAqCiAgICAgKiBAcGFyYW0gbm9kZSAge0Bpbmhlcml0RG9jfQogICAgICogQHBhcmFtIHAgIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gdGhlIHJlc3VsdCBvZiBzY2FubmluZwogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0TGFtYmRhRXhwcmVzc2lvbihMYW1iZGFFeHByZXNzaW9uVHJlZSBub2RlLCBQIHApIHsKICAgICAgICBSIHIgPSBzY2FuKG5vZGUuZ2V0UGFyYW1ldGVycygpLCBwKTsKICAgICAgICByID0gc2NhbkFuZFJlZHVjZShub2RlLmdldEJvZHkoKSwgcCwgcik7CiAgICAgICAgcmV0dXJuIHI7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gc2NhbnMgdGhlIGNoaWxkcmVuIGluIGxlZnQgdG8gcmlnaHQgb3JkZXIuCiAgICAgKgogICAgICogQHBhcmFtIG5vZGUgIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwICB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuIHRoZSByZXN1bHQgb2Ygc2Nhbm5pbmcKICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgUiB2aXNpdFBhcmVudGhlc2l6ZWQoUGFyZW50aGVzaXplZFRyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIHNjYW4obm9kZS5nZXRFeHByZXNzaW9uKCksIHApOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIHNjYW5zIHRoZSBjaGlsZHJlbiBpbiBsZWZ0IHRvIHJpZ2h0IG9yZGVyLgogICAgICoKICAgICAqIEBwYXJhbSBub2RlICB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiB0aGUgcmVzdWx0IG9mIHNjYW5uaW5nCiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRBc3NpZ25tZW50KEFzc2lnbm1lbnRUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIFIgciA9IHNjYW4obm9kZS5nZXRWYXJpYWJsZSgpLCBwKTsKICAgICAgICByID0gc2NhbkFuZFJlZHVjZShub2RlLmdldEV4cHJlc3Npb24oKSwgcCwgcik7CiAgICAgICAgcmV0dXJuIHI7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gc2NhbnMgdGhlIGNoaWxkcmVuIGluIGxlZnQgdG8gcmlnaHQgb3JkZXIuCiAgICAgKgogICAgICogQHBhcmFtIG5vZGUgIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwICB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuIHRoZSByZXN1bHQgb2Ygc2Nhbm5pbmcKICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgUiB2aXNpdENvbXBvdW5kQXNzaWdubWVudChDb21wb3VuZEFzc2lnbm1lbnRUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIFIgciA9IHNjYW4obm9kZS5nZXRWYXJpYWJsZSgpLCBwKTsKICAgICAgICByID0gc2NhbkFuZFJlZHVjZShub2RlLmdldEV4cHJlc3Npb24oKSwgcCwgcik7CiAgICAgICAgcmV0dXJuIHI7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gc2NhbnMgdGhlIGNoaWxkcmVuIGluIGxlZnQgdG8gcmlnaHQgb3JkZXIuCiAgICAgKgogICAgICogQHBhcmFtIG5vZGUgIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwICB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuIHRoZSByZXN1bHQgb2Ygc2Nhbm5pbmcKICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgUiB2aXNpdFVuYXJ5KFVuYXJ5VHJlZSBub2RlLCBQIHApIHsKICAgICAgICByZXR1cm4gc2Nhbihub2RlLmdldEV4cHJlc3Npb24oKSwgcCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gc2NhbnMgdGhlIGNoaWxkcmVuIGluIGxlZnQgdG8gcmlnaHQgb3JkZXIuCiAgICAgKgogICAgICogQHBhcmFtIG5vZGUgIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwICB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuIHRoZSByZXN1bHQgb2Ygc2Nhbm5pbmcKICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgUiB2aXNpdEJpbmFyeShCaW5hcnlUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIFIgciA9IHNjYW4obm9kZS5nZXRMZWZ0T3BlcmFuZCgpLCBwKTsKICAgICAgICByID0gc2NhbkFuZFJlZHVjZShub2RlLmdldFJpZ2h0T3BlcmFuZCgpLCBwLCByKTsKICAgICAgICByZXR1cm4gcjsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30gVGhpcyBpbXBsZW1lbnRhdGlvbiBzY2FucyB0aGUgY2hpbGRyZW4gaW4gbGVmdCB0byByaWdodCBvcmRlci4KICAgICAqCiAgICAgKiBAcGFyYW0gbm9kZSAge0Bpbmhlcml0RG9jfQogICAgICogQHBhcmFtIHAgIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gdGhlIHJlc3VsdCBvZiBzY2FubmluZwogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0VHlwZUNhc3QoVHlwZUNhc3RUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIFIgciA9IHNjYW4obm9kZS5nZXRUeXBlKCksIHApOwogICAgICAgIHIgPSBzY2FuQW5kUmVkdWNlKG5vZGUuZ2V0RXhwcmVzc2lvbigpLCBwLCByKTsKICAgICAgICByZXR1cm4gcjsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30gVGhpcyBpbXBsZW1lbnRhdGlvbiBzY2FucyB0aGUgY2hpbGRyZW4gaW4gbGVmdCB0byByaWdodCBvcmRlci4KICAgICAqCiAgICAgKiBAcGFyYW0gbm9kZSAge0Bpbmhlcml0RG9jfQogICAgICogQHBhcmFtIHAgIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gdGhlIHJlc3VsdCBvZiBzY2FubmluZwogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0SW5zdGFuY2VPZihJbnN0YW5jZU9mVHJlZSBub2RlLCBQIHApIHsKICAgICAgICBSIHIgPSBzY2FuKG5vZGUuZ2V0RXhwcmVzc2lvbigpLCBwKTsKICAgICAgICByID0gc2NhbkFuZFJlZHVjZShub2RlLmdldFR5cGUoKSwgcCwgcik7CiAgICAgICAgcmV0dXJuIHI7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gc2NhbnMgdGhlIGNoaWxkcmVuIGluIGxlZnQgdG8gcmlnaHQgb3JkZXIuCiAgICAgKgogICAgICogQHBhcmFtIG5vZGUgIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwICB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuIHRoZSByZXN1bHQgb2Ygc2Nhbm5pbmcKICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgUiB2aXNpdEFycmF5QWNjZXNzKEFycmF5QWNjZXNzVHJlZSBub2RlLCBQIHApIHsKICAgICAgICBSIHIgPSBzY2FuKG5vZGUuZ2V0RXhwcmVzc2lvbigpLCBwKTsKICAgICAgICByID0gc2NhbkFuZFJlZHVjZShub2RlLmdldEluZGV4KCksIHAsIHIpOwogICAgICAgIHJldHVybiByOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIHNjYW5zIHRoZSBjaGlsZHJlbiBpbiBsZWZ0IHRvIHJpZ2h0IG9yZGVyLgogICAgICoKICAgICAqIEBwYXJhbSBub2RlICB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiB0aGUgcmVzdWx0IG9mIHNjYW5uaW5nCiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRNZW1iZXJTZWxlY3QoTWVtYmVyU2VsZWN0VHJlZSBub2RlLCBQIHApIHsKICAgICAgICByZXR1cm4gc2Nhbihub2RlLmdldEV4cHJlc3Npb24oKSwgcCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gc2NhbnMgdGhlIGNoaWxkcmVuIGluIGxlZnQgdG8gcmlnaHQgb3JkZXIuCiAgICAgKgogICAgICogQHBhcmFtIG5vZGUgIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwICB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuIHRoZSByZXN1bHQgb2Ygc2Nhbm5pbmcKICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgUiB2aXNpdE1lbWJlclJlZmVyZW5jZShNZW1iZXJSZWZlcmVuY2VUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIFIgciA9IHNjYW4obm9kZS5nZXRRdWFsaWZpZXJFeHByZXNzaW9uKCksIHApOwogICAgICAgIHIgPSBzY2FuQW5kUmVkdWNlKG5vZGUuZ2V0VHlwZUFyZ3VtZW50cygpLCBwLCByKTsKICAgICAgICByZXR1cm4gcjsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30gVGhpcyBpbXBsZW1lbnRhdGlvbiByZXR1cm5zIHtAY29kZSBudWxsfS4KICAgICAqCiAgICAgKiBAcGFyYW0gbm9kZSAge0Bpbmhlcml0RG9jfQogICAgICogQHBhcmFtIHAgIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gdGhlIHJlc3VsdCBvZiBzY2FubmluZwogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0SWRlbnRpZmllcihJZGVudGlmaWVyVHJlZSBub2RlLCBQIHApIHsKICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30gVGhpcyBpbXBsZW1lbnRhdGlvbiByZXR1cm5zIHtAY29kZSBudWxsfS4KICAgICAqCiAgICAgKiBAcGFyYW0gbm9kZSAge0Bpbmhlcml0RG9jfQogICAgICogQHBhcmFtIHAgIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gdGhlIHJlc3VsdCBvZiBzY2FubmluZwogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0TGl0ZXJhbChMaXRlcmFsVHJlZSBub2RlLCBQIHApIHsKICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30gVGhpcyBpbXBsZW1lbnRhdGlvbiByZXR1cm5zIHtAY29kZSBudWxsfS4KICAgICAqCiAgICAgKiBAcGFyYW0gbm9kZSAge0Bpbmhlcml0RG9jfQogICAgICogQHBhcmFtIHAgIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gdGhlIHJlc3VsdCBvZiBzY2FubmluZwogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0UHJpbWl0aXZlVHlwZShQcmltaXRpdmVUeXBlVHJlZSBub2RlLCBQIHApIHsKICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30gVGhpcyBpbXBsZW1lbnRhdGlvbiBzY2FucyB0aGUgY2hpbGRyZW4gaW4gbGVmdCB0byByaWdodCBvcmRlci4KICAgICAqCiAgICAgKiBAcGFyYW0gbm9kZSAge0Bpbmhlcml0RG9jfQogICAgICogQHBhcmFtIHAgIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gdGhlIHJlc3VsdCBvZiBzY2FubmluZwogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0QXJyYXlUeXBlKEFycmF5VHlwZVRyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIHNjYW4obm9kZS5nZXRUeXBlKCksIHApOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIHNjYW5zIHRoZSBjaGlsZHJlbiBpbiBsZWZ0IHRvIHJpZ2h0IG9yZGVyLgogICAgICoKICAgICAqIEBwYXJhbSBub2RlICB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiB0aGUgcmVzdWx0IG9mIHNjYW5uaW5nCiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRQYXJhbWV0ZXJpemVkVHlwZShQYXJhbWV0ZXJpemVkVHlwZVRyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgUiByID0gc2Nhbihub2RlLmdldFR5cGUoKSwgcCk7CiAgICAgICAgciA9IHNjYW5BbmRSZWR1Y2Uobm9kZS5nZXRUeXBlQXJndW1lbnRzKCksIHAsIHIpOwogICAgICAgIHJldHVybiByOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIHNjYW5zIHRoZSBjaGlsZHJlbiBpbiBsZWZ0IHRvIHJpZ2h0IG9yZGVyLgogICAgICoKICAgICAqIEBwYXJhbSBub2RlICB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiB0aGUgcmVzdWx0IG9mIHNjYW5uaW5nCiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRVbmlvblR5cGUoVW5pb25UeXBlVHJlZSBub2RlLCBQIHApIHsKICAgICAgICByZXR1cm4gc2Nhbihub2RlLmdldFR5cGVBbHRlcm5hdGl2ZXMoKSwgcCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gc2NhbnMgdGhlIGNoaWxkcmVuIGluIGxlZnQgdG8gcmlnaHQgb3JkZXIuCiAgICAgKgogICAgICogQHBhcmFtIG5vZGUgIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwICB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuIHRoZSByZXN1bHQgb2Ygc2Nhbm5pbmcKICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgUiB2aXNpdEludGVyc2VjdGlvblR5cGUoSW50ZXJzZWN0aW9uVHlwZVRyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIHNjYW4obm9kZS5nZXRCb3VuZHMoKSwgcCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gc2NhbnMgdGhlIGNoaWxkcmVuIGluIGxlZnQgdG8gcmlnaHQgb3JkZXIuCiAgICAgKgogICAgICogQHBhcmFtIG5vZGUgIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwICB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuIHRoZSByZXN1bHQgb2Ygc2Nhbm5pbmcKICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgUiB2aXNpdFR5cGVQYXJhbWV0ZXIoVHlwZVBhcmFtZXRlclRyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgUiByID0gc2Nhbihub2RlLmdldEFubm90YXRpb25zKCksIHApOwogICAgICAgIHIgPSBzY2FuQW5kUmVkdWNlKG5vZGUuZ2V0Qm91bmRzKCksIHAsIHIpOwogICAgICAgIHJldHVybiByOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIHNjYW5zIHRoZSBjaGlsZHJlbiBpbiBsZWZ0IHRvIHJpZ2h0IG9yZGVyLgogICAgICoKICAgICAqIEBwYXJhbSBub2RlICB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiB0aGUgcmVzdWx0IG9mIHNjYW5uaW5nCiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRXaWxkY2FyZChXaWxkY2FyZFRyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIHNjYW4obm9kZS5nZXRCb3VuZCgpLCBwKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30gVGhpcyBpbXBsZW1lbnRhdGlvbiBzY2FucyB0aGUgY2hpbGRyZW4gaW4gbGVmdCB0byByaWdodCBvcmRlci4KICAgICAqCiAgICAgKiBAcGFyYW0gbm9kZSAge0Bpbmhlcml0RG9jfQogICAgICogQHBhcmFtIHAgIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gdGhlIHJlc3VsdCBvZiBzY2FubmluZwogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0TW9kaWZpZXJzKE1vZGlmaWVyc1RyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIHNjYW4obm9kZS5nZXRBbm5vdGF0aW9ucygpLCBwKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30gVGhpcyBpbXBsZW1lbnRhdGlvbiBzY2FucyB0aGUgY2hpbGRyZW4gaW4gbGVmdCB0byByaWdodCBvcmRlci4KICAgICAqCiAgICAgKiBAcGFyYW0gbm9kZSAge0Bpbmhlcml0RG9jfQogICAgICogQHBhcmFtIHAgIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gdGhlIHJlc3VsdCBvZiBzY2FubmluZwogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0QW5ub3RhdGlvbihBbm5vdGF0aW9uVHJlZSBub2RlLCBQIHApIHsKICAgICAgICBSIHIgPSBzY2FuKG5vZGUuZ2V0QW5ub3RhdGlvblR5cGUoKSwgcCk7CiAgICAgICAgciA9IHNjYW5BbmRSZWR1Y2Uobm9kZS5nZXRBcmd1bWVudHMoKSwgcCwgcik7CiAgICAgICAgcmV0dXJuIHI7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gc2NhbnMgdGhlIGNoaWxkcmVuIGluIGxlZnQgdG8gcmlnaHQgb3JkZXIuCiAgICAgKgogICAgICogQHBhcmFtIG5vZGUgIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwICB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuIHRoZSByZXN1bHQgb2Ygc2Nhbm5pbmcKICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgUiB2aXNpdEFubm90YXRlZFR5cGUoQW5ub3RhdGVkVHlwZVRyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgUiByID0gc2Nhbihub2RlLmdldEFubm90YXRpb25zKCksIHApOwogICAgICAgIHIgPSBzY2FuQW5kUmVkdWNlKG5vZGUuZ2V0VW5kZXJseWluZ1R5cGUoKSwgcCwgcik7CiAgICAgICAgcmV0dXJuIHI7CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgUiB2aXNpdE1vZHVsZShNb2R1bGVUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIFIgciA9IHNjYW4obm9kZS5nZXRBbm5vdGF0aW9ucygpLCBwKTsKICAgICAgICByID0gc2NhbkFuZFJlZHVjZShub2RlLmdldE5hbWUoKSwgcCwgcik7CiAgICAgICAgciA9IHNjYW5BbmRSZWR1Y2Uobm9kZS5nZXREaXJlY3RpdmVzKCksIHAsIHIpOwogICAgICAgIHJldHVybiByOwogICAgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRFeHBvcnRzKEV4cG9ydHNUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIFIgciA9IHNjYW4obm9kZS5nZXRQYWNrYWdlTmFtZSgpLCBwKTsKICAgICAgICByID0gc2NhbkFuZFJlZHVjZShub2RlLmdldE1vZHVsZU5hbWVzKCksIHAsIHIpOwogICAgICAgIHJldHVybiByOwogICAgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRPcGVucyhPcGVuc1RyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgUiByID0gc2Nhbihub2RlLmdldFBhY2thZ2VOYW1lKCksIHApOwogICAgICAgIHIgPSBzY2FuQW5kUmVkdWNlKG5vZGUuZ2V0TW9kdWxlTmFtZXMoKSwgcCwgcik7CiAgICAgICAgcmV0dXJuIHI7CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgUiB2aXNpdFByb3ZpZGVzKFByb3ZpZGVzVHJlZSBub2RlLCBQIHApIHsKICAgICAgICBSIHIgPSBzY2FuKG5vZGUuZ2V0U2VydmljZU5hbWUoKSwgcCk7CiAgICAgICAgciA9IHNjYW5BbmRSZWR1Y2Uobm9kZS5nZXRJbXBsZW1lbnRhdGlvbk5hbWVzKCksIHAsIHIpOwogICAgICAgIHJldHVybiByOwogICAgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRSZXF1aXJlcyhSZXF1aXJlc1RyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIHNjYW4obm9kZS5nZXRNb2R1bGVOYW1lKCksIHApOwogICAgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRVc2VzKFVzZXNUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIHJldHVybiBzY2FuKG5vZGUuZ2V0U2VydmljZU5hbWUoKSwgcCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gcmV0dXJucyB7QGNvZGUgbnVsbH0uCiAgICAgKgogICAgICogQHBhcmFtIG5vZGUgIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwICB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuIHRoZSByZXN1bHQgb2Ygc2Nhbm5pbmcKICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgUiB2aXNpdE90aGVyKFRyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gcmV0dXJucyB7QGNvZGUgbnVsbH0uCiAgICAgKgogICAgICogQHBhcmFtIG5vZGUgIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwICB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuIHRoZSByZXN1bHQgb2Ygc2Nhbm5pbmcKICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgUiB2aXNpdEVycm9uZW91cyhFcnJvbmVvdXNUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIHJldHVybiBudWxsOwogICAgfQp9ClBLAwQKAAAIAAAGO6lKAAAAAAAAAAAAAAAAFwAAAGNvbS9zdW4vc291cmNlL2RvY3RyZWUvUEsDBAoAAAgAAAY7qUpie/LmBAYAAAQGAAAqAAAAY29tL3N1bi9zb3VyY2UvZG9jdHJlZS9FbmRFbGVtZW50VHJlZS5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDExLCAyMDE0LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4uc291cmNlLmRvY3RyZWU7CgppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5lbGVtZW50Lk5hbWU7CgovKioKICogQSB0cmVlIG5vZGUgZm9yIHRoZSBlbmQgb2YgYW4gSFRNTCBlbGVtZW50LgogKgogKiA8cD4KICogJmx0Oy8gbmFtZSAmZ3Q7CiAqCiAqIEBzaW5jZSAxLjgKICovCnB1YmxpYyBpbnRlcmZhY2UgRW5kRWxlbWVudFRyZWUgZXh0ZW5kcyBEb2NUcmVlIHsKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgbmFtZSBvZiB0aGlzIGVsZW1lbnQuCiAgICAgKiBAcmV0dXJuIHRoZSBuYW1lCiAgICAgKi8KICAgIE5hbWUgZ2V0TmFtZSgpOwp9ClBLAwQKAAAIAAAGO6lKtLQLYN4IAADeCAAAKQAAAGNvbS9zdW4vc291cmNlL2RvY3RyZWUvQXR0cmlidXRlVHJlZS5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDExLCAyMDE0LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4uc291cmNlLmRvY3RyZWU7CgppbXBvcnQgamF2YS51dGlsLkxpc3Q7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuTmFtZTsKCi8qKgogKiBBIHRyZWUgbm9kZSBmb3IgYW4gYXR0cmlidXRlIGluIGFuIEhUTUwgZWxlbWVudC4KICoKICogQHNpbmNlIDEuOAogKi8KcHVibGljIGludGVyZmFjZSBBdHRyaWJ1dGVUcmVlIGV4dGVuZHMgRG9jVHJlZSB7CiAgICAvKioKICAgICAqIFRoZSBraW5kIG9mIGFuIGF0dHJpYnV0ZSB2YWx1ZS4KICAgICAqLwogICAgZW51bSBWYWx1ZUtpbmQgewogICAgICAgIC8qKiBUaGUgYXR0cmlidXRlIHZhbHVlIGlzIGVtcHR5LiAqLwogICAgICAgIEVNUFRZLAogICAgICAgIC8qKiBUaGUgYXR0cmlidXRlIHZhbHVlIGlzIG5vdCBlbmNsb3NlZCBpbiBxdW90ZXMuICovCiAgICAgICAgVU5RVU9URUQsCiAgICAgICAgLyoqIFRoZSBhdHRyaWJ1dGUgdmFsdWUgaXMgZW5jbG9zZWQgaW4gc2luZ2xlIHF1b3RhdGlvbiBtYXJrcy4gKi8KICAgICAgICBTSU5HTEUsCiAgICAgICAgLyoqIFRoZSBhdHRyaWJ1dGUgdmFsdWUgaXMgZW5jbG9zZWQgaW4gZG91YmxlIHF1b3RhdGlvbiBtYXJrcy4gKi8KICAgICAgICBET1VCTEUKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZS4KICAgICAqIEByZXR1cm4gdGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZQogICAgICovCiAgICBOYW1lIGdldE5hbWUoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGtpbmQgb2YgdGhlIGF0dHJpYnV0ZS4KICAgICAqIEByZXR1cm4gdGhlIGtpbmQgb2YgdGhlIGF0dHJpYnV0ZS4KICAgICAqLwogICAgVmFsdWVLaW5kIGdldFZhbHVlS2luZCgpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgdGhlIGF0dHJpYnV0ZSwgb3Ige0Bjb2RlIG51bGx9IGlmIHRoZSBraW5kIGlzIEVNUFRZLgogICAgICogQHJldHVybiB0aGUgdmFsdWUgb2YgdGhlIGF0dHJpYnV0ZS4KICAgICAqLwogICAgTGlzdDw/IGV4dGVuZHMgRG9jVHJlZT4gZ2V0VmFsdWUoKTsKfQpQSwMECgAACAAABjupSj/tPoM1BgAANQYAACoAAABjb20vc3VuL3NvdXJjZS9kb2N0cmVlL1NlcmlhbERhdGFUcmVlLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTEsIDIwMTQsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi5zb3VyY2UuZG9jdHJlZTsKCmltcG9ydCBqYXZhLnV0aWwuTGlzdDsKCi8qKgogKiBBIHRyZWUgbm9kZSBmb3IgYW4gQHNlcmlhbERhdGEgYmxvY2sgdGFnLgogKgogKiA8cD4KICogJiMwNjQ7c2VyaWFsRGF0YSBkYXRhLWRlc2NyaXB0aW9uCiAqCiAqIEBzaW5jZSAxLjgKICovCnB1YmxpYyBpbnRlcmZhY2UgU2VyaWFsRGF0YVRyZWUgZXh0ZW5kcyBCbG9ja1RhZ1RyZWUgewogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBkZXNjcmlwdGlvbiBvZiB0aGUgc2VyaWFsIGRhdGEuCiAgICAgKiBAcmV0dXJuIHRoZSBkZXNjcmlwdGlvbgogICAgICovCiAgICBMaXN0PD8gZXh0ZW5kcyBEb2NUcmVlPiBnZXREZXNjcmlwdGlvbigpOwp9ClBLAwQKAAAIAAAGO6lK8+mvc3AGAABwBgAAJgAAAGNvbS9zdW4vc291cmNlL2RvY3RyZWUvU2VyaWFsVHJlZS5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDExLCAyMDE0LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4uc291cmNlLmRvY3RyZWU7CgppbXBvcnQgamF2YS51dGlsLkxpc3Q7CgovKioKICogQSB0cmVlIG5vZGUgZm9yIGFuIEBzZXJpYWwgYmxvY2sgdGFnLgogKgogKiA8cD4KICogJiMwNjQ7c2VyaWFsIGZpZWxkLWRlc2NyaXB0aW9uIHwgaW5jbHVkZSB8IGV4Y2x1ZGUKICoKICogQHNpbmNlIDEuOAogKi8KcHVibGljIGludGVyZmFjZSBTZXJpYWxUcmVlIGV4dGVuZHMgQmxvY2tUYWdUcmVlIHsKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgZGVzY3JpcHRpb24gb2YgdGhlIGZpZWxkLCBvciB0aGUgd29yZAogICAgICogImluY2x1ZGUiIG9yICJleGNsdWRlIi4KICAgICAqIEByZXR1cm4gdGhlIGRlc2NyaXB0aW9uIG9mIHRoZSBmaWVsZAogICAgICovCiAgICBMaXN0PD8gZXh0ZW5kcyBEb2NUcmVlPiBnZXREZXNjcmlwdGlvbigpOwp9ClBLAwQKAAAIAAAGO6lKYHyubZwFAACcBQAAJAAAAGNvbS9zdW4vc291cmNlL2RvY3RyZWUvVGV4dFRyZWUuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAxMSwgMjAxNCwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnNvdXJjZS5kb2N0cmVlOwoKLyoqCiAqIEEgdHJlZSBub2RlIGZvciBwbGFpbiB0ZXh0LgogKgogKiBAc2luY2UgMS44CiAqLwpwdWJsaWMgaW50ZXJmYWNlIFRleHRUcmVlIGV4dGVuZHMgRG9jVHJlZSB7CiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHRleHQuCiAgICAgKiBAcmV0dXJuIHRoZSB0ZXh0CiAgICAgKi8KICAgIFN0cmluZyBnZXRCb2R5KCk7Cn0KUEsDBAoAAAgAAAY7qUpe15GLOwYAADsGAAAoAAAAY29tL3N1bi9zb3VyY2UvZG9jdHJlZS9wYWNrYWdlLWluZm8uamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAxMSwgMjAxMywgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKLyoqCiAqIFByb3ZpZGVzIGludGVyZmFjZXMgdG8gcmVwcmVzZW50IGRvY3VtZW50YXRpb24gY29tbWVudHMgYXMgYWJzdHJhY3Qgc3ludGF4CiAqIHRyZWVzIChBU1QpLgogKgogKiBAYXV0aG9yIEpvbmF0aGFuIEdpYmJvbnMKICogQHNpbmNlIDEuOAogKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly9kb3dubG9hZC5vcmFjbGUuY29tL2phdmFzZS82L2RvY3MvdGVjaG5vdGVzL3Rvb2xzL3NvbGFyaXMvamF2YWRvYy5odG1sI2phdmFkb2N0YWdzIj5odHRwOi8vZG93bmxvYWQub3JhY2xlLmNvbS9qYXZhc2UvNi9kb2NzL3RlY2hub3Rlcy90b29scy9zb2xhcmlzL2phdmFkb2MuaHRtbCNqYXZhZG9jdGFnczwvYT4KICovCnBhY2thZ2UgY29tLnN1bi5zb3VyY2UuZG9jdHJlZTsKUEsDBAoAAAgAAAY7qUoIIWzYWQcAAFkHAAAlAAAAY29tL3N1bi9zb3VyY2UvZG9jdHJlZS9QYXJhbVRyZWUuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAxMSwgMjAxNCwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnNvdXJjZS5kb2N0cmVlOwoKaW1wb3J0IGphdmEudXRpbC5MaXN0OwoKLyoqCiAqIEEgdHJlZSBub2RlIGZvciBhbiBAcGFyYW0gYmxvY2sgdGFnLgogKgogKiA8cD4KICogJiMwNjQ7cGFyYW0gcGFyYW1ldGVyLW5hbWUgZGVzY3JpcHRpb24KICoKICogQHNpbmNlIDEuOAogKi8KcHVibGljIGludGVyZmFjZSBQYXJhbVRyZWUgZXh0ZW5kcyBCbG9ja1RhZ1RyZWUgewogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhpcyBpcyBkb2N1bWVudGluZyBhIHR5cGUgcGFyYW1ldGVyLgogICAgICogQHJldHVybiB0cnVlIGlmIHRoaXMgaXMgZG9jdW1lbnRpbmcgYSB0eXBlIHBhcmFtZXRlcgogICAgICovCiAgICBib29sZWFuIGlzVHlwZVBhcmFtZXRlcigpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgbmFtZSBvZiB0aGUgcGFyYW1ldGVyLgogICAgICogQHJldHVybiB0aGUgbmFtZSBvZiB0aGUgcGFyYW1ldGVyCiAgICAgKi8KICAgIElkZW50aWZpZXJUcmVlIGdldE5hbWUoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGRlc2NyaXB0aW9uIG9mIHRoZSBwYXJhbWV0ZXIuCiAgICAgKiBAcmV0dXJuIHRoZSBkZXNjcmlwdGlvbgogICAgICovCiAgICBMaXN0PD8gZXh0ZW5kcyBEb2NUcmVlPiBnZXREZXNjcmlwdGlvbigpOwp9ClBLAwQKAAAIAAAGO6lKDQCvnlwGAABcBgAAIwAAAGNvbS9zdW4vc291cmNlL2RvY3RyZWUvU2VlVHJlZS5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDExLCAyMDE0LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4uc291cmNlLmRvY3RyZWU7CgppbXBvcnQgamF2YS51dGlsLkxpc3Q7CgovKioKICoKICogQSB0cmVlIG5vZGUgZm9yIGFuIEBzZWUgYmxvY2sgdGFnLgogKgogKiA8cD4KICogJiMwNjQ7c2VlICJzdHJpbmciIDxicj4KICogJiMwNjQ7c2VlICZsdDthIGhyZWY9IlVSTCN2YWx1ZSImZ3Q7IGxhYmVsICZsdDsvYSZndDsgPGJyPgogKiAmIzA2NDtzZWUgcmVmZXJlbmNlCiAqCiAqIEBzaW5jZSAxLjgKICovCnB1YmxpYyBpbnRlcmZhY2UgU2VlVHJlZSBleHRlbmRzIEJsb2NrVGFnVHJlZSB7CiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHJlZmVyZW5jZS4KICAgICAqIEByZXR1cm4gdGhlIHJlZmVyZW5jZQogICAgICovCiAgICBMaXN0PD8gZXh0ZW5kcyBEb2NUcmVlPiBnZXRSZWZlcmVuY2UoKTsKfQpQSwMECgAACAAABjupSoWHx9rcBQAA3AUAACcAAABjb20vc3VuL3NvdXJjZS9kb2N0cmVlL0NvbW1lbnRUcmVlLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTEsIDIwMTQsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi5zb3VyY2UuZG9jdHJlZTsKCi8qKgogKiBBbiBlbWJlZGRlZCBIVE1MIGNvbW1lbnQuCiAqCiAqIDxwPgogKiB7QGxpdGVyYWwgPCEtLSB0ZXh0IC0tPiB9CiAqCiAqIEBzaW5jZSAxLjgKICovCnB1YmxpYyBpbnRlcmZhY2UgQ29tbWVudFRyZWUgZXh0ZW5kcyBEb2NUcmVlIHsKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgdGV4dCBvZiB0aGUgY29tbWVudC4KICAgICAqIEByZXR1cm4gdGhlIGNvbW1lbnQgdGV4dAogICAgICovCiAgICBTdHJpbmcgZ2V0Qm9keSgpOwp9CgpQSwMECgAACAAABjupShWGuYR5BgAAeQYAACkAAABjb20vc3VuL3NvdXJjZS9kb2N0cmVlL1JlZmVyZW5jZVRyZWUuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAxMSwgMjAxNCwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnNvdXJjZS5kb2N0cmVlOwoKLyoqCiAqIEEgdHJlZSBub2RlIGZvciBhIHJlZmVyZW5jZSB0byBhIEphdmEgbGFuZ3VhZ2UgZWxlbWVudC4KICoKICogPHA+CiAqIHBhY2thZ2UuY2xhc3MjZmllbGQKICogcGFja2FnZS5jbGFzcyNtZXRob2QoPGk+YXJnLXR5cGVzPC9pPikKICoKICogQHNpbmNlIDEuOAogKi8KcHVibGljIGludGVyZmFjZSBSZWZlcmVuY2VUcmVlIGV4dGVuZHMgRG9jVHJlZSB7CiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHNpZ25hdHVyZSBvZiB0aGUgSmF2YSBsYW5ndWFnZSBlbGVtZW50IGJlaW5nIHJlZmVyZW5jZWQsCiAgICAgKiBhcyBmb3VuZCBpbiB7QGNvZGUgQHNlZX0gYW5kIHNpbWlsYXIgbm9kZXMuCiAgICAgKiBAcmV0dXJuIHRoZSBzaWduYXR1cmUuCiAgICAgKi8KICAgIFN0cmluZyBnZXRTaWduYXR1cmUoKTsKfQpQSwMECgAACAAABjupSk0bTOHnCQAA5wkAACoAAABjb20vc3VuL3NvdXJjZS9kb2N0cmVlL0RvY0NvbW1lbnRUcmVlLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTEsIDIwMTUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi5zb3VyY2UuZG9jdHJlZTsKCmltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OwppbXBvcnQgamF2YS51dGlsLkxpc3Q7CgovKioKICogVGhlIHRvcCBsZXZlbCByZXByZXNlbnRhdGlvbiBvZiBhIGRvY3VtZW50YXRpb24gY29tbWVudC4KICoKICogPHA+CiAqIGZpcnN0LXNlbnRlbmNlIGJvZHkgYmxvY2stdGFncwogKgogKiBAc2luY2UgMS44CiAqLwpwdWJsaWMgaW50ZXJmYWNlIERvY0NvbW1lbnRUcmVlIGV4dGVuZHMgRG9jVHJlZSB7CiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGZpcnN0IHNlbnRlbmNlIG9mIGEgZG9jdW1lbnRhdGlvbiBjb21tZW50LgogICAgICogQHJldHVybiB0aGUgZmlyc3Qgc2VudGVuY2Ugb2YgYSBkb2N1bWVudGF0aW9uIGNvbW1lbnQKICAgICAqLwogICAgTGlzdDw/IGV4dGVuZHMgRG9jVHJlZT4gZ2V0Rmlyc3RTZW50ZW5jZSgpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgZW50aXJlIGJvZHkgb2YgYSBkb2N1bWVudGF0aW9uIGNvbW1lbnQsIGFwcGVhcmluZwogICAgICogYmVmb3JlIGFueSBibG9jayB0YWdzLCBpbmNsdWRpbmcgdGhlIGZpcnN0IHNlbnRlbmNlLgogICAgICogQHJldHVybiBib2R5IG9mIGEgZG9jdW1lbnRhdGlvbiBjb21tZW50IGZpcnN0IHNlbnRlbmNlIGluY2x1c2l2ZQogICAgICoKICAgICAqIEBzaW5jZSA5CiAgICAgKi8KICAgIGRlZmF1bHQgTGlzdDw/IGV4dGVuZHMgRG9jVHJlZT4gZ2V0RnVsbEJvZHkoKSB7CiAgICAgICAgQXJyYXlMaXN0PERvY1RyZWU+IGJvZHlMaXN0ID0gbmV3IEFycmF5TGlzdDw+KCk7CiAgICAgICAgYm9keUxpc3QuYWRkQWxsKGdldEZpcnN0U2VudGVuY2UoKSk7CiAgICAgICAgYm9keUxpc3QuYWRkQWxsKGdldEJvZHkoKSk7CiAgICAgICAgcmV0dXJuIGJvZHlMaXN0OwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgYm9keSBvZiBhIGRvY3VtZW50YXRpb24gY29tbWVudCwKICAgICAqIGFwcGVhcmluZyBhZnRlciB0aGUgZmlyc3Qgc2VudGVuY2UsIGFuZCBiZWZvcmUgYW55IGJsb2NrIHRhZ3MuCiAgICAgKiBAcmV0dXJuIHRoZSBib2R5IG9mIGEgZG9jdW1lbnRhdGlvbiBjb21tZW50CiAgICAgKi8KICAgIExpc3Q8PyBleHRlbmRzIERvY1RyZWU+IGdldEJvZHkoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGJsb2NrIHRhZ3MgZm9yIGEgZG9jdW1lbnRhdGlvbiBjb21tZW50LgogICAgICogQHJldHVybiB0aGUgYmxvY2sgdGFncyBvZiBhIGRvY3VtZW50YXRpb24gY29tbWVudAogICAgICovCiAgICBMaXN0PD8gZXh0ZW5kcyBEb2NUcmVlPiBnZXRCbG9ja1RhZ3MoKTsKfQpQSwMECgAACAAABjupSjdGofQZBgAAGQYAACcAAABjb20vc3VuL3NvdXJjZS9kb2N0cmVlL0xpdGVyYWxUcmVlLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTEsIDIwMTQsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi5zb3VyY2UuZG9jdHJlZTsKCi8qKgogKgogKiBBIHRyZWUgbm9kZSBmb3IgYW4gQGxpdGVyYWwgb3IgQGNvZGUgaW5saW5lIHRhZy4KICoKICogPHA+CiAqIHsmIzA2NDtsaXRlcmFsIHRleHR9CiAqCiAqIEBzaW5jZSAxLjgKICovCnB1YmxpYyBpbnRlcmZhY2UgTGl0ZXJhbFRyZWUgZXh0ZW5kcyBJbmxpbmVUYWdUcmVlIHsKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgYm9keSBvZiB0aGUge0Bjb2RlIEBjb2RlfSBvciB7QGNvZGUgQGxpdGVyYWx9IHRhZy4KICAgICAqIEByZXR1cm4gdGhlIGJvZHkgb2YgdGhlIHRhZwogICAgICovCiAgICBUZXh0VHJlZSBnZXRCb2R5KCk7Cn0KUEsDBAoAAAgAAAY7qUqeZMF83QYAAN0GAAAkAAAAY29tL3N1bi9zb3VyY2UvZG9jdHJlZS9Vc2VzVHJlZS5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDE2LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4uc291cmNlLmRvY3RyZWU7CgppbXBvcnQgamF2YS51dGlsLkxpc3Q7CgovKioKICoKICogQSB0cmVlIG5vZGUgZm9yIGFuIEB1c2VzIGJsb2NrIHRhZy4KICoKICogPHA+CiAqICYjMDY0O3VzZXMgc2VydmljZS10eXBlIGRlc2NyaXB0aW9uCiAqCiAqIEBzaW5jZSA5CiAqLwpwdWJsaWMgaW50ZXJmYWNlIFVzZXNUcmVlIGV4dGVuZHMgQmxvY2tUYWdUcmVlIHsKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgbmFtZSBvZiB0aGUgc2VydmljZSB0eXBlIGJlaW5nIGRvY3VtZW50ZWQuCiAgICAgKiBAcmV0dXJuIHRoZSBuYW1lIG9mIHRoZSBzZXJ2aWNlIHR5cGUKICAgICAqLwogICAgUmVmZXJlbmNlVHJlZSBnZXRTZXJ2aWNlVHlwZSgpOwoKICAgIC8qKgogICAgICogUmV0dXJucyBhIGRlc2NyaXB0aW9uIG9mIHRoZSB1c2Ugb2Ygc2VydmljZSB0eXBlIHdpdGhpbiB0aGUgbW9kdWxlLgogICAgICogQHJldHVybiB0aGUgZGVzY3JpcHRpb24KICAgICAqLwogICAgTGlzdDw/IGV4dGVuZHMgRG9jVHJlZT4gZ2V0RGVzY3JpcHRpb24oKTsKfQpQSwMECgAACAAABjupSuzORflABgAAQAYAACoAAABjb20vc3VuL3NvdXJjZS9kb2N0cmVlL0RlcHJlY2F0ZWRUcmVlLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTEsIDIwMTQsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi5zb3VyY2UuZG9jdHJlZTsKCmltcG9ydCBqYXZhLnV0aWwuTGlzdDsKCi8qKgogKiBBIHRyZWUgbm9kZSBmb3IgYW4gQGRlcHJlY2F0ZWQgYmxvY2sgdGFnLgogKgogKiA8cD4KICogJiMwNjQ7ZGVwcmVjYXRlZCBkZXByZWNhdGVkIHRleHQuCiAqCiAqIEBzaW5jZSAxLjgKICovCnB1YmxpYyBpbnRlcmZhY2UgRGVwcmVjYXRlZFRyZWUgZXh0ZW5kcyBCbG9ja1RhZ1RyZWUgewogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBkZXNjcmlwdGlvbiBleHBsYWluaW5nIHdoeSBhbiBpdGVtIGlzIGRlcHJlY2F0ZWQuCiAgICAgKiBAcmV0dXJuIHRoZSBkZXNjcmlwdGlvbgogICAgICovCiAgICBMaXN0PD8gZXh0ZW5kcyBEb2NUcmVlPiBnZXRCb2R5KCk7Cn0KUEsDBAoAAAgAAAY7qUo24agFRwYAAEcGAAAmAAAAY29tL3N1bi9zb3VyY2UvZG9jdHJlZS9FbnRpdHlUcmVlLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTEsIDIwMTQsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi5zb3VyY2UuZG9jdHJlZTsKCmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuTmFtZTsKCgovKioKICogQSB0cmVlIG5vZGUgZm9yIGFuIEhUTUwgZW50aXR5LgogKgogKiA8cD4KICogJmFtcDsgbmFtZSA7IDxicj4KICogJmFtcDsgIyBkaWdpdHMgOyA8YnI+CiAqICZhbXA7ICNYIGhleC1kaWdpdHMgOwogKgogKiBAc2luY2UgMS44CiAqLwpwdWJsaWMgaW50ZXJmYWNlIEVudGl0eVRyZWUgZXh0ZW5kcyBEb2NUcmVlIHsKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgbmFtZSBvciB2YWx1ZSBvZiB0aGUgZW50aXR5LgogICAgICogQHJldHVybiB0aGUgbmFtZSBvciB2YWx1ZSBvZiB0aGUgZW50aXR5CiAgICAgKi8KICAgIE5hbWUgZ2V0TmFtZSgpOwp9ClBLAwQKAAAIAAAGO6lKVMQ6aeoFAADqBQAAKAAAAGNvbS9zdW4vc291cmNlL2RvY3RyZWUvQmxvY2tUYWdUcmVlLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTEsIDIwMTQsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi5zb3VyY2UuZG9jdHJlZTsKCi8qKgogKiBBIHRyZWUgbm9kZSB1c2VkIGFzIHRoZSBiYXNlIGNsYXNzIGZvciB0aGUgZGlmZmVyZW50IHR5cGVzIG9mCiAqIGJsb2NrIHRhZ3MuCiAqCiAqIEBzaW5jZSAxLjgKICovCnB1YmxpYyBpbnRlcmZhY2UgQmxvY2tUYWdUcmVlIGV4dGVuZHMgRG9jVHJlZSB7CiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIG5hbWUgb2YgdGhlIHRhZy4KICAgICAqIEByZXR1cm4gdGhlIG5hbWUgb2YgdGhlIHRhZwogICAgICovCiAgICBTdHJpbmcgZ2V0VGFnTmFtZSgpOwp9ClBLAwQKAAAIAAAGO6lKBOicMmIHAABiBwAAJgAAAGNvbS9zdW4vc291cmNlL2RvY3RyZWUvVGhyb3dzVHJlZS5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDExLCAyMDE0LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4uc291cmNlLmRvY3RyZWU7CgppbXBvcnQgamF2YS51dGlsLkxpc3Q7CgovKioKICoKICogQSB0cmVlIG5vZGUgZm9yIGFuIEBleGNlcHRpb24gb3IgJiMwNjQ7dGhyb3dzIGJsb2NrIHRhZy4KICogJiMwNjQ7ZXhjZXB0aW9uIGlzIGEgc3lub255bSBmb3IgJiMwNjQ7dGhyb3dzLgogKgogKiA8cD4KICogJiMwNjQ7ZXhjZXB0aW9uIGNsYXNzLW5hbWUgZGVzY3JpcHRpb24gPGJyPgogKiAmIzA2NDt0aHJvd3MgY2xhc3MtbmFtZSBkZXNjcmlwdGlvbgogKgogKiBAc2luY2UgMS44CiAqLwpwdWJsaWMgaW50ZXJmYWNlIFRocm93c1RyZWUgZXh0ZW5kcyBCbG9ja1RhZ1RyZWUgewogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBuYW1lIG9mIHRoZSBleGNlcHRpb24gYmVpbmcgZG9jdW1lbnRlZC4KICAgICAqIEByZXR1cm4gdGhlIG5hbWUgb2YgdGhlIGV4Y2VwdGlvbgogICAgICovCiAgICBSZWZlcmVuY2VUcmVlIGdldEV4Y2VwdGlvbk5hbWUoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgYSBkZXNjcmlwdGlvbiBvZiB0aGUgcmVhc29ucyB3aHkgdGhlCiAgICAgKiBleGNlcHRpb24gbWF5IGJlIHRocm93bi4KICAgICAqIEByZXR1cm4gdGhlIGRlc2NyaXB0aW9uCiAgICAgKi8KICAgIExpc3Q8PyBleHRlbmRzIERvY1RyZWU+IGdldERlc2NyaXB0aW9uKCk7Cn0KUEsDBAoAAAgAAAY7qUpn0ttizAYAAMwGAAAkAAAAY29tL3N1bi9zb3VyY2UvZG9jdHJlZS9MaW5rVHJlZS5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDExLCAyMDE0LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4uc291cmNlLmRvY3RyZWU7CgppbXBvcnQgamF2YS51dGlsLkxpc3Q7CgovKioKICogQSB0cmVlIG5vZGUgZm9yIGFuIEBsaW5rIG9yICYjMDY0O2xpbmtwbGFpbiBpbmxpbmUgdGFnLgogKgogKiA8cD4KICogeyYjMDY0O2xpbmsgcmVmZXJlbmNlIGxhYmVsfSA8YnI+CiAqIHsmIzA2NDtsaW5rcGxhaW4gcmVmZXJlbmNlIGxhYmVsIH0KICoKICogQHNpbmNlIDEuOAogKi8KcHVibGljIGludGVyZmFjZSBMaW5rVHJlZSBleHRlbmRzIElubGluZVRhZ1RyZWUgewogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSByZWZlcmVuY2Ugb2YgYSBsaW5rLgogICAgICogQHJldHVybiB0aGUgcmVmZXJlbmNlCiAgICAgKi8KICAgIFJlZmVyZW5jZVRyZWUgZ2V0UmVmZXJlbmNlKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBsYWJlbCwgaWYgYW55LCBvZiB0aGUgbGluay4KICAgICAqIEByZXR1cm4gdGhlIGxhYmVsCiAgICAgKi8KICAgIExpc3Q8PyBleHRlbmRzIERvY1RyZWU+IGdldExhYmVsKCk7Cn0KUEsDBAoAAAgAAAY7qUpVHy5UGgYAABoGAAAmAAAAY29tL3N1bi9zb3VyY2UvZG9jdHJlZS9IaWRkZW5UcmVlLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi5zb3VyY2UuZG9jdHJlZTsKCmltcG9ydCBqYXZhLnV0aWwuTGlzdDsKCi8qKgogKgogKiBBIHRyZWUgbm9kZSBmb3IgYW4gQGhpZGRlbiBibG9jayB0YWcuCiAqCiAqIDxwPgogKiAmIzA2NDtoaWRkZW4KICoKICogQHNpbmNlIDkKICovCnB1YmxpYyBpbnRlcmZhY2UgSGlkZGVuVHJlZSBleHRlbmRzIEJsb2NrVGFnVHJlZSB7CiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGRlc2NyaXB0aW9uIGV4cGxhaW5pbmcgd2h5IGFuIGl0ZW0gaXMgaGlkZGVuLgogICAgICogQHJldHVybiB0aGUgZGVzY3JpcHRpb24KICAgICAqLwogICAgTGlzdDw/IGV4dGVuZHMgRG9jVHJlZT4gZ2V0Qm9keSgpOwp9ClBLAwQKAAAIAAAGO6lKZCZfPHcFAAB3BQAAJwAAAGNvbS9zdW4vc291cmNlL2RvY3RyZWUvRG9jUm9vdFRyZWUuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAxMSwgMjAxMywgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnNvdXJjZS5kb2N0cmVlOwoKLyoqCiAqIEEgdHJlZSBub2RlIGZvciBhbiBAZG9jcm9vdCBpbmxpbmUgdGFnLgogKgogKiA8cD4KICogeyYjMDY0O2RvY3Jvb3R9CiAqCiAqIEBzaW5jZSAxLjgKICovCnB1YmxpYyBpbnRlcmZhY2UgRG9jUm9vdFRyZWUgZXh0ZW5kcyBJbmxpbmVUYWdUcmVlIHsgfQpQSwMECgAACAAABjupSpHKr1n3BQAA9wUAACUAAABjb20vc3VuL3NvdXJjZS9kb2N0cmVlL1ZhbHVlVHJlZS5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDExLCAyMDE0LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4uc291cmNlLmRvY3RyZWU7CgovKioKICogQSB0cmVlIG5vZGUgZm9yIGFuIEB2YWx1ZSBpbmxpbmUgdGFnLgogKgogKiA8cD4KICogeyAmIzA2NDt2YWx1ZSByZWZlcmVuY2UgfQogKgogKiBAc2luY2UgMS44CiAqLwpwdWJsaWMgaW50ZXJmYWNlIFZhbHVlVHJlZSBleHRlbmRzIElubGluZVRhZ1RyZWUgewogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSByZWZlcmVuY2UgdG8gdGhlIHZhbHVlLgogICAgICogQHJldHVybiB0aGUgcmVmZXJlbmNlCiAgICAgKi8KICAgIFJlZmVyZW5jZVRyZWUgZ2V0UmVmZXJlbmNlKCk7Cn0KUEsDBAoAAAgAAAY7qUrVpuWtgwUAAIMFAAAqAAAAY29tL3N1bi9zb3VyY2UvZG9jdHJlZS9Jbmhlcml0RG9jVHJlZS5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDExLCAyMDEzLCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4uc291cmNlLmRvY3RyZWU7CgovKioKICoKICogQSB0cmVlIG5vZGUgZm9yIGFuIEBpbmhlcml0RG9jIGlubGluZSB0YWcuCiAqCiAqIDxwPgogKiB7JiMwNjQ7aW5oZXJpdERvY30KICoKICogQHNpbmNlIDEuOAogKi8KcHVibGljIGludGVyZmFjZSBJbmhlcml0RG9jVHJlZSBleHRlbmRzIElubGluZVRhZ1RyZWUgeyB9ClBLAwQKAAAIAAAGO6lKooOdsw4GAAAOBgAAJwAAAGNvbS9zdW4vc291cmNlL2RvY3RyZWUvVmVyc2lvblRyZWUuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAxMSwgMjAxNCwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnNvdXJjZS5kb2N0cmVlOwoKaW1wb3J0IGphdmEudXRpbC5MaXN0OwoKLyoqCiAqCiAqIEEgdHJlZSBub2RlIGZvciBhbiBAdmVyc2lvbiBibG9jayB0YWcuCiAqCiAqIDxwPgogKiAmIzA2NDt2ZXJzaW9uIHZlcnNpb24tdGV4dAogKgogKiBAc2luY2UgMS44CiAqLwpwdWJsaWMgaW50ZXJmYWNlIFZlcnNpb25UcmVlIGV4dGVuZHMgQmxvY2tUYWdUcmVlIHsKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgYm9keSBvZiB0aGUgdGFnLgogICAgICogQHJldHVybiB0aGUgYm9keQogICAgICovCiAgICBMaXN0PD8gZXh0ZW5kcyBEb2NUcmVlPiBnZXRCb2R5KCk7Cn0KUEsDBAoAAAgAAAY7qUraP2RW7AYAAOwGAAAoAAAAY29tL3N1bi9zb3VyY2UvZG9jdHJlZS9Qcm92aWRlc1RyZWUuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAxNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnNvdXJjZS5kb2N0cmVlOwoKaW1wb3J0IGphdmEudXRpbC5MaXN0OwoKLyoqCiAqCiAqIEEgdHJlZSBub2RlIGZvciBhIEBwcm92aWRlcyBibG9jayB0YWcuCiAqCiAqIDxwPgogKiAmIzA2NDtwcm92aWRlcyBzZXJ2aWNlLXR5cGUgZGVzY3JpcHRpb24KICoKICogQHNpbmNlIDkKICovCnB1YmxpYyBpbnRlcmZhY2UgUHJvdmlkZXNUcmVlIGV4dGVuZHMgQmxvY2tUYWdUcmVlIHsKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgbmFtZSBvZiB0aGUgc2VydmljZSB0eXBlIGJlaW5nIGRvY3VtZW50ZWQuCiAgICAgKiBAcmV0dXJuIHRoZSBuYW1lIG9mIHRoZSBzZXJ2aWNlIHR5cGUKICAgICAqLwogICAgUmVmZXJlbmNlVHJlZSBnZXRTZXJ2aWNlVHlwZSgpOwoKICAgIC8qKgogICAgICogUmV0dXJucyBhIGRlc2NyaXB0aW9uIG9mIHRoZSBzZXJ2aWNlIHR5cGUgYmVpbmcgcHJvdmlkZWQgYnkgdGhlIG1vZHVsZS4KICAgICAqIEByZXR1cm4gdGhlIGRlc2NyaXB0aW9uCiAgICAgKi8KICAgIExpc3Q8PyBleHRlbmRzIERvY1RyZWU+IGdldERlc2NyaXB0aW9uKCk7Cn0KUEsDBAoAAAgAAAY7qUrANQ5wZwYAAGcGAAApAAAAY29tL3N1bi9zb3VyY2UvZG9jdHJlZS9FcnJvbmVvdXNUcmVlLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTEsIDIwMTQsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi5zb3VyY2UuZG9jdHJlZTsKCmltcG9ydCBqYXZheC50b29scy5EaWFnbm9zdGljOwppbXBvcnQgamF2YXgudG9vbHMuSmF2YUZpbGVPYmplY3Q7CgovKioKICogQSB0cmVlIG5vZGUgdG8gc3RhbmQgaW4gZm9yIGEgbWFsZm9ybWVkIHRleHQKICoKICogQHNpbmNlIDEuOAogKi8KcHVibGljIGludGVyZmFjZSBFcnJvbmVvdXNUcmVlIGV4dGVuZHMgVGV4dFRyZWUgewogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgZGlhZ25vc3RpYyBvYmplY3QgZ2l2aW5nIGRldGFpbHMgYWJvdXQKICAgICAqIHRoZSByZWFzb24gdGhlIGJvZHkgdGV4dCBpcyBpbiBlcnJvci4KICAgICAqCiAgICAgKiBAcmV0dXJuIGEgZGlhZ25vc3RpYwogICAgICovCiAgICBEaWFnbm9zdGljPEphdmFGaWxlT2JqZWN0PiBnZXREaWFnbm9zdGljKCk7Cn0KUEsDBAoAAAgAAAY7qUpNryN5MwYAADMGAAAwAAAAY29tL3N1bi9zb3VyY2UvZG9jdHJlZS9Vbmtub3duSW5saW5lVGFnVHJlZS5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDExLCAyMDE0LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4uc291cmNlLmRvY3RyZWU7CgppbXBvcnQgamF2YS51dGlsLkxpc3Q7CgovKioKICogQSB0cmVlIG5vZGUgZm9yIGFuIHVucmVjb2duaXplZCBpbmxpbmUgdGFnLgogKgogKiA8cD4KICogeyYjMDY0O25hbWUgY29udGVudH0KICoKICogQHNpbmNlIDEuOAogKgogKi8KcHVibGljIGludGVyZmFjZSBVbmtub3duSW5saW5lVGFnVHJlZSBleHRlbmRzIElubGluZVRhZ1RyZWUgewogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBjb250ZW50IG9mIGFuIHVucmVjb2duaXplZCBpbmxpbmUgdGFnLgogICAgICogQHJldHVybiB0aGUgY29udGVudAogICAgICovCiAgICBMaXN0PD8gZXh0ZW5kcyBEb2NUcmVlPiBnZXRDb250ZW50KCk7Cn0KUEsDBAoAAAgAAAY7qUpBJtNYMQYAADEGAAAmAAAAY29tL3N1bi9zb3VyY2UvZG9jdHJlZS9SZXR1cm5UcmVlLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTEsIDIwMTQsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi5zb3VyY2UuZG9jdHJlZTsKCmltcG9ydCBqYXZhLnV0aWwuTGlzdDsKCi8qKgogKiBBIHRyZWUgbm9kZSBmb3IgYW4gQHJldHVybiBibG9jayB0YWcuCiAqCiAqIDxwPgogKiAmIzA2NDtyZXR1cm4gZGVzY3JpcHRpb24KICoKICogQHNpbmNlIDEuOAogKi8KcHVibGljIGludGVyZmFjZSBSZXR1cm5UcmVlIGV4dGVuZHMgQmxvY2tUYWdUcmVlIHsKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgZGVzY3JpcHRpb24gb2YgdGhlIHJldHVybiB2YWx1ZSBvZiBhIG1ldGhvZC4KICAgICAqIEByZXR1cm4gdGhlIGRlc2NyaXB0aW9uCiAgICAgKi8KICAgIExpc3Q8PyBleHRlbmRzIERvY1RyZWU+IGdldERlc2NyaXB0aW9uKCk7Cn0KUEsDBAoAAAgAAAY7qUpX3or2rgYAAK4GAAAlAAAAY29tL3N1bi9zb3VyY2UvZG9jdHJlZS9JbmRleFRyZWUuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAxNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnNvdXJjZS5kb2N0cmVlOwoKaW1wb3J0IGphdmEudXRpbC5MaXN0OwoKLyoqCiAqIEEgdHJlZSBub2RlIGZvciBhbiBAaW5kZXggb3IgJiMwNjQ7aW5kZXggaW5saW5lIHRhZy4KICoKICogPHA+CiAqIHsmIzA2NDtpbmRleCBrZXl3b3JkIG9wdGlvbmFsIGRlc2NyaXB0aW9ufSA8YnI+CiAqCiAqIEBzaW5jZSA5CiAqLwpwdWJsaWMgaW50ZXJmYWNlIEluZGV4VHJlZSBleHRlbmRzIElubGluZVRhZ1RyZWUgewogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBzcGVjaWZpZWQgc2VhcmNoIHRlcm0uCiAgICAgKiBAcmV0dXJuIHRoZSBzZWFyY2ggdGVybQogICAgICovCiAgICBEb2NUcmVlIGdldFNlYXJjaFRlcm0oKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGRlc2NyaXB0aW9uLCBpZiBhbnkuCiAgICAgKiBAcmV0dXJuIHRoZSBkZXNjcmlwdGlvbgogICAgICovCiAgICBMaXN0PD8gZXh0ZW5kcyBEb2NUcmVlPiBnZXREZXNjcmlwdGlvbigpOwp9ClBLAwQKAAAIAAAGO6lKHD8sqAkGAAAJBgAAJgAAAGNvbS9zdW4vc291cmNlL2RvY3RyZWUvQXV0aG9yVHJlZS5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDExLCAyMDE0LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4uc291cmNlLmRvY3RyZWU7CgppbXBvcnQgamF2YS51dGlsLkxpc3Q7CgovKioKICogQSB0cmVlIG5vZGUgZm9yIGFuIEBhdXRob3IgYmxvY2sgdGFnLgogKgogKiA8cD4KICogJiMwNjQ7YXV0aG9yIG5hbWUtdGV4dC4KICoKICogQHNpbmNlIDEuOAogKi8KcHVibGljIGludGVyZmFjZSBBdXRob3JUcmVlIGV4dGVuZHMgQmxvY2tUYWdUcmVlIHsKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgbmFtZSBvZiB0aGUgYXV0aG9yLgogICAgICogQHJldHVybiB0aGUgbmFtZQogICAgICovCiAgICBMaXN0PD8gZXh0ZW5kcyBEb2NUcmVlPiBnZXROYW1lKCk7Cn0KUEsDBAoAAAgAAAY7qUq7A8yw+QUAAPkFAAAqAAAAY29tL3N1bi9zb3VyY2UvZG9jdHJlZS9JZGVudGlmaWVyVHJlZS5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDExLCAyMDE0LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4uc291cmNlLmRvY3RyZWU7CgppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5lbGVtZW50Lk5hbWU7CgovKioKICogQW4gaWRlbnRpZmllciBpbiBhIGRvY3VtZW50YXRpb24gY29tbWVudC4KICoKICogPHA+CiAqIG5hbWUKICoKICogQHNpbmNlIDEuOAogKi8KcHVibGljIGludGVyZmFjZSBJZGVudGlmaWVyVHJlZSBleHRlbmRzIERvY1RyZWUgewogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBuYW1lIG9mIHRoZSBpZGVudGlmaWVyLgogICAgICogQHJldHVybiB0aGUgbmFtZQogICAgICovCiAgICBOYW1lIGdldE5hbWUoKTsKfQpQSwMECgAACAAABjupSovRCjuTBwAAkwcAACwAAABjb20vc3VuL3NvdXJjZS9kb2N0cmVlL1N0YXJ0RWxlbWVudFRyZWUuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAxMSwgMjAxNCwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnNvdXJjZS5kb2N0cmVlOwoKaW1wb3J0IGphdmEudXRpbC5MaXN0OwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5lbGVtZW50Lk5hbWU7CgovKioKICogQSB0cmVlIG5vZGUgZm9yIHRoZSBzdGFydCBvZiBhbiBIVE1MIGVsZW1lbnQuCiAqCiAqIDxwPgogKiAmbHQ7IG5hbWUgW2F0dHJpYnV0ZXNdIFsvXSZndDsKICoKICogQHNpbmNlIDEuOAogKi8KcHVibGljIGludGVyZmFjZSBTdGFydEVsZW1lbnRUcmVlIGV4dGVuZHMgRG9jVHJlZSB7CiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIG5hbWUgb2YgdGhlIGVsZW1lbnQuCiAgICAgKiBAcmV0dXJuIHRoZSBuYW1lCiAgICAgKi8KICAgIE5hbWUgZ2V0TmFtZSgpOwoKICAgIC8qKgogICAgICogUmV0dXJucyBhbnkgYXR0cmlidXRlcyBkZWZpbmVkIGJ5IHRoaXMgZWxlbWVudC4KICAgICAqIEByZXR1cm4gdGhlIGF0dHJpYnV0ZXMKICAgICAqLwogICAgTGlzdDw/IGV4dGVuZHMgRG9jVHJlZT4gZ2V0QXR0cmlidXRlcygpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0cnVlIGlmIHRoaXMgaXMgYSBzZWxmLWNsb3NpbmcgZWxlbWVudCwKICAgICAqIGFzIGluZGljYXRlZCBieSBhICIvIiBiZWZvcmUgdGhlIGNsb3NpbmcgIiZndDsiLgogICAgICogQHJldHVybiB0cnVlIGlmIHRoaXMgaXMgYSBzZWxmLWNsb3NpbmcgZWxlbWVudAogICAgICovCiAgICBib29sZWFuIGlzU2VsZkNsb3NpbmcoKTsKfQpQSwMECgAACAAABjupSt/qzjExBgAAMQYAACUAAABjb20vc3VuL3NvdXJjZS9kb2N0cmVlL1NpbmNlVHJlZS5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDExLCAyMDE0LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4uc291cmNlLmRvY3RyZWU7CgppbXBvcnQgamF2YS51dGlsLkxpc3Q7CgovKioKICogQSB0cmVlIG5vZGUgZm9yIGFuIEBzaW5jZSBibG9jayB0YWcuCiAqCiAqIDxwPgogKiAmIzA2NDtzaW5jZSBzaW5jZS10ZXh0CiAqCiAqIEBzaW5jZSAxLjgKICovCnB1YmxpYyBpbnRlcmZhY2UgU2luY2VUcmVlIGV4dGVuZHMgQmxvY2tUYWdUcmVlIHsKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgdGV4dCBleHBsYWluaW5nIHRoZSBhdmFpbGFiaWxpdHkgb2YgdGhlIGl0ZW0gYmVpbmcgZG9jdW1lbnRlZC4KICAgICAqIEByZXR1cm4gdGhlIHRleHQKICAgICAqLwogICAgTGlzdDw/IGV4dGVuZHMgRG9jVHJlZT4gZ2V0Qm9keSgpOwp9ClBLAwQKAAAIAAAGO6lKpnaD2y4GAAAuBgAALwAAAGNvbS9zdW4vc291cmNlL2RvY3RyZWUvVW5rbm93bkJsb2NrVGFnVHJlZS5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDExLCAyMDE0LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4uc291cmNlLmRvY3RyZWU7CgppbXBvcnQgamF2YS51dGlsLkxpc3Q7CgovKioKICogQSB0cmVlIG5vZGUgZm9yIGFuIHVucmVjb2duaXplZCBpbmxpbmUgdGFnLgogKgogKiA8cD4KICogJiMwNjQ7bmFtZSBjb250ZW50CiAqCiAqIEBzaW5jZSAxLjgKICoKICovCnB1YmxpYyBpbnRlcmZhY2UgVW5rbm93bkJsb2NrVGFnVHJlZSBleHRlbmRzIEJsb2NrVGFnVHJlZSB7CiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGNvbnRlbnQgb2YgYW4gdW5yZWNvZ25pemVkIGJsb2NrIHRhZy4KICAgICAqIEByZXR1cm4gdGhlIGNvbnRlbnQKICAgICAqLwogICAgTGlzdDw/IGV4dGVuZHMgRG9jVHJlZT4gZ2V0Q29udGVudCgpOwp9ClBLAwQKAAAIAAAGO6lKy2X0IbsdAAC7HQAAIwAAAGNvbS9zdW4vc291cmNlL2RvY3RyZWUvRG9jVHJlZS5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDExLCAyMDE2LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4uc291cmNlLmRvY3RyZWU7CgovKioKICogQ29tbW9uIGludGVyZmFjZSBmb3IgYWxsIG5vZGVzIGluIGEgZG9jdW1lbnRhdGlvbiBzeW50YXggdHJlZS4KICoKICogQHNpbmNlIDEuOAogKi8KcHVibGljIGludGVyZmFjZSBEb2NUcmVlIHsKICAgIC8qKgogICAgICogRW51bWVyYXRlcyBhbGwga2luZHMgb2YgdHJlZXMuCiAgICAgKi8KICAgIGVudW0gS2luZCB7CiAgICAgICAgLyoqCiAgICAgICAgICogVXNlZCBmb3IgaW5zdGFuY2VzIG9mIHtAbGluayBBdHRyaWJ1dGVUcmVlfQogICAgICAgICAqIHJlcHJlc2VudGluZyBhbiBIVE1MIGF0dHJpYnV0ZS4KICAgICAgICAgKi8KICAgICAgICBBVFRSSUJVVEUsCgogICAgICAgIC8qKgogICAgICAgICAqIFVzZWQgZm9yIGluc3RhbmNlcyBvZiB7QGxpbmsgQXV0aG9yVHJlZX0KICAgICAgICAgKiByZXByZXNlbnRpbmcgYW4gQGF1dGhvciB0YWcuCiAgICAgICAgICovCiAgICAgICAgQVVUSE9SKCJhdXRob3IiKSwKCiAgICAgICAgLyoqCiAgICAgICAgICogVXNlZCBmb3IgaW5zdGFuY2VzIG9mIHtAbGluayBMaXRlcmFsVHJlZX0KICAgICAgICAgKiByZXByZXNlbnRpbmcgYW4gQGNvZGUgdGFnLgogICAgICAgICAqLwogICAgICAgIENPREUoImNvZGUiKSwKCiAgICAgICAgLyoqCiAgICAgICAgICogVXNlZCBmb3IgaW5zdGFuY2VzIG9mIHtAbGluayBDb21tZW50VHJlZX0KICAgICAgICAgKiByZXByZXNlbnRpbmcgYW4gSFRNTCBjb21tZW50LgogICAgICAgICAqLwogICAgICAgIENPTU1FTlQsCgogICAgICAgIC8qKgogICAgICAgICAqIFVzZWQgZm9yIGluc3RhbmNlcyBvZiB7QGxpbmsgRGVwcmVjYXRlZFRyZWV9CiAgICAgICAgICogcmVwcmVzZW50aW5nIGFuIEBkZXByZWNhdGVkIHRhZy4KICAgICAgICAgKi8KICAgICAgICBERVBSRUNBVEVEKCJkZXByZWNhdGVkIiksCgogICAgICAgIC8qKgogICAgICAgICAqIFVzZWQgZm9yIGluc3RhbmNlcyBvZiB7QGxpbmsgRG9jQ29tbWVudFRyZWV9CiAgICAgICAgICogcmVwcmVzZW50aW5nIGEgY29tcGxldGUgZG9jIGNvbW1lbnQuCiAgICAgICAgICovCiAgICAgICAgRE9DX0NPTU1FTlQsCgogICAgICAgIC8qKgogICAgICAgICAqIFVzZWQgZm9yIGluc3RhbmNlcyBvZiB7QGxpbmsgRG9jUm9vdFRyZWV9CiAgICAgICAgICogcmVwcmVzZW50aW5nIGFuIEBkb2NSb290IHRhZy4KICAgICAgICAgKi8KICAgICAgICBET0NfUk9PVCgiZG9jUm9vdCIpLAoKICAgICAgICAvKioKICAgICAgICAgKiBVc2VkIGZvciBpbnN0YW5jZXMgb2Yge0BsaW5rIEVuZEVsZW1lbnRUcmVlfQogICAgICAgICAqIHJlcHJlc2VudGluZyB0aGUgZW5kIG9mIGFuIEhUTUwgZWxlbWVudC4KICAgICAgICAgKi8KICAgICAgICBFTkRfRUxFTUVOVCwKCiAgICAgICAgLyoqCiAgICAgICAgICogVXNlZCBmb3IgaW5zdGFuY2VzIG9mIHtAbGluayBFbnRpdHlUcmVlfQogICAgICAgICAqIHJlcHJlc2VudGluZyBhbiBIVE1MIGVudGl0eS4KICAgICAgICAgKi8KICAgICAgICBFTlRJVFksCgogICAgICAgIC8qKgogICAgICAgICAqIFVzZWQgZm9yIGluc3RhbmNlcyBvZiB7QGxpbmsgRXJyb25lb3VzVHJlZX0KICAgICAgICAgKiByZXByZXNlbnRpbmcgc29tZSBpbnZhbGlkIHRleHQuCiAgICAgICAgICovCiAgICAgICAgRVJST05FT1VTLAoKICAgICAgICAvKioKICAgICAgICAgKiBVc2VkIGZvciBpbnN0YW5jZXMgb2Yge0BsaW5rIFRocm93c1RyZWV9CiAgICAgICAgICogcmVwcmVzZW50aW5nIGFuIEBleGNlcHRpb24gdGFnLgogICAgICAgICAqLwogICAgICAgIEVYQ0VQVElPTigiZXhjZXB0aW9uIiksCgogICAgICAgIC8qKgogICAgICAgICAqIFVzZWQgZm9yIGluc3RhbmNlcyBvZiB7QGxpbmsgSGlkZGVuVHJlZX0KICAgICAgICAgKiByZXByZXNlbnRpbmcgYW4gQGhpZGRlbiB0YWcuCiAgICAgICAgICovCiAgICAgICAgSElEREVOKCJoaWRkZW4iKSwKCiAgICAgICAgLyoqCiAgICAgICAgICogVXNlZCBmb3IgaW5zdGFuY2VzIG9mIHtAbGluayBJZGVudGlmaWVyVHJlZX0KICAgICAgICAgKiByZXByZXNlbnRpbmcgYW4gaWRlbnRpZmllci4KICAgICAgICAgKi8KICAgICAgICBJREVOVElGSUVSLAoKICAgICAgICAvKioKICAgICAgICAgKiBVc2VkIGZvciBpbnN0YW5jZXMgb2Yge0BsaW5rIEluZGV4VHJlZX0KICAgICAgICAgKiByZXByZXNlbnRpbmcgYSBzZWFyY2ggdGVybS4KICAgICAgICAgKi8KICAgICAgICBJTkRFWCgiaW5kZXgiKSwKCiAgICAgICAgLyoqCiAgICAgICAgICogVXNlZCBmb3IgaW5zdGFuY2VzIG9mIHtAbGluayBJbmhlcml0RG9jVHJlZX0KICAgICAgICAgKiByZXByZXNlbnRpbmcgYW4gQGluaGVyaXREb2MgdGFnLgogICAgICAgICAqLwogICAgICAgIElOSEVSSVRfRE9DKCJpbmhlcml0RG9jIiksCgogICAgICAgIC8qKgogICAgICAgICAqIFVzZWQgZm9yIGluc3RhbmNlcyBvZiB7QGxpbmsgTGlua1RyZWV9CiAgICAgICAgICogcmVwcmVzZW50aW5nIGFuIEBsaW5rIHRhZy4KICAgICAgICAgKi8KICAgICAgICBMSU5LKCJsaW5rIiksCgogICAgICAgIC8qKgogICAgICAgICAqIFVzZWQgZm9yIGluc3RhbmNlcyBvZiB7QGxpbmsgTGlua1RyZWV9CiAgICAgICAgICogcmVwcmVzZW50aW5nIGFuIEBsaW5rcGxhaW4gdGFnLgogICAgICAgICAqLwogICAgICAgIExJTktfUExBSU4oImxpbmtwbGFpbiIpLAoKICAgICAgICAvKioKICAgICAgICAgKiBVc2VkIGZvciBpbnN0YW5jZXMgb2Yge0BsaW5rIExpdGVyYWxUcmVlfQogICAgICAgICAqIHJlcHJlc2VudGluZyBhbiBAbGl0ZXJhbCB0YWcuCiAgICAgICAgICovCiAgICAgICAgTElURVJBTCgibGl0ZXJhbCIpLAoKICAgICAgICAvKioKICAgICAgICAgKiBVc2VkIGZvciBpbnN0YW5jZXMgb2Yge0BsaW5rIFBhcmFtVHJlZX0KICAgICAgICAgKiByZXByZXNlbnRpbmcgYW4gQHBhcmFtIHRhZy4KICAgICAgICAgKi8KICAgICAgICBQQVJBTSgicGFyYW0iKSwKCiAgICAgICAgLyoqCiAgICAgICAgICogVXNlZCBmb3IgaW5zdGFuY2VzIG9mIHtAbGluayBQcm92aWRlc1RyZWV9CiAgICAgICAgICogcmVwcmVzZW50aW5nIGFuIEBwcm92aWRlcyB0YWcuCiAgICAgICAgICovCiAgICAgICAgUFJPVklERVMoInByb3ZpZGVzIiksCgogICAgICAgIC8qKgogICAgICAgICAqIFVzZWQgZm9yIGluc3RhbmNlcyBvZiB7QGxpbmsgUmVmZXJlbmNlVHJlZX0KICAgICAgICAgKiByZXByZXNlbnRpbmcgYSByZWZlcmVuY2UgdG8gYSBlbGVtZW50IGluIHRoZQogICAgICAgICAqIEphdmEgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2UuCiAgICAgICAgICovCiAgICAgICAgUkVGRVJFTkNFLAoKICAgICAgICAvKioKICAgICAgICAgKiBVc2VkIGZvciBpbnN0YW5jZXMgb2Yge0BsaW5rIFJldHVyblRyZWV9CiAgICAgICAgICogcmVwcmVzZW50aW5nIGFuIEByZXR1cm4gdGFnLgogICAgICAgICAqLwogICAgICAgIFJFVFVSTigicmV0dXJuIiksCgogICAgICAgIC8qKgogICAgICAgICAqIFVzZWQgZm9yIGluc3RhbmNlcyBvZiB7QGxpbmsgU2VlVHJlZX0KICAgICAgICAgKiByZXByZXNlbnRpbmcgYW4gQHNlZSB0YWcuCiAgICAgICAgICovCiAgICAgICAgU0VFKCJzZWUiKSwKCiAgICAgICAgLyoqCiAgICAgICAgICogVXNlZCBmb3IgaW5zdGFuY2VzIG9mIHtAbGluayBTZXJpYWxUcmVlfQogICAgICAgICAqIHJlcHJlc2VudGluZyBhbiBAc2VyaWFsIHRhZy4KICAgICAgICAgKi8KICAgICAgICBTRVJJQUwoInNlcmlhbCIpLAoKICAgICAgICAvKioKICAgICAgICAgKiBVc2VkIGZvciBpbnN0YW5jZXMgb2Yge0BsaW5rIFNlcmlhbERhdGFUcmVlfQogICAgICAgICAqIHJlcHJlc2VudGluZyBhbiBAc2VyaWFsRGF0YSB0YWcuCiAgICAgICAgICovCiAgICAgICAgU0VSSUFMX0RBVEEoInNlcmlhbERhdGEiKSwKCiAgICAgICAgLyoqCiAgICAgICAgICogVXNlZCBmb3IgaW5zdGFuY2VzIG9mIHtAbGluayBTZXJpYWxGaWVsZFRyZWV9CiAgICAgICAgICogcmVwcmVzZW50aW5nIGFuIEBzZXJpYWxGaWVsZCB0YWcuCiAgICAgICAgICovCiAgICAgICAgU0VSSUFMX0ZJRUxEKCJzZXJpYWxGaWVsZCIpLAoKICAgICAgICAvKioKICAgICAgICAgKiBVc2VkIGZvciBpbnN0YW5jZXMgb2Yge0BsaW5rIFNpbmNlVHJlZX0KICAgICAgICAgKiByZXByZXNlbnRpbmcgYW4gQHNpbmNlIHRhZy4KICAgICAgICAgKi8KICAgICAgICBTSU5DRSgic2luY2UiKSwKCiAgICAgICAgLyoqCiAgICAgICAgICogVXNlZCBmb3IgaW5zdGFuY2VzIG9mIHtAbGluayBFbmRFbGVtZW50VHJlZX0KICAgICAgICAgKiByZXByZXNlbnRpbmcgdGhlIHN0YXJ0IG9mIGFuIEhUTUwgZWxlbWVudC4KICAgICAgICAgKi8KICAgICAgICBTVEFSVF9FTEVNRU5ULAoKICAgICAgICAvKioKICAgICAgICAgKiBVc2VkIGZvciBpbnN0YW5jZXMgb2Yge0BsaW5rIFRleHRUcmVlfQogICAgICAgICAqIHJlcHJlc2VudGluZyBzb21lIGRvY3VtZW50YXRpb24gdGV4dC4KICAgICAgICAgKi8KICAgICAgICBURVhULAoKICAgICAgICAvKioKICAgICAgICAgKiBVc2VkIGZvciBpbnN0YW5jZXMgb2Yge0BsaW5rIFRocm93c1RyZWV9CiAgICAgICAgICogcmVwcmVzZW50aW5nIGFuIEB0aHJvd3MgdGFnLgogICAgICAgICAqLwogICAgICAgIFRIUk9XUygidGhyb3dzIiksCgogICAgICAgIC8qKgogICAgICAgICAqIFVzZWQgZm9yIGluc3RhbmNlcyBvZiB7QGxpbmsgVW5rbm93bkJsb2NrVGFnVHJlZX0KICAgICAgICAgKiByZXByZXNlbnRpbmcgYW4gdW5rbm93biBibG9jayB0YWcuCiAgICAgICAgICovCiAgICAgICAgVU5LTk9XTl9CTE9DS19UQUcsCgogICAgICAgIC8qKgogICAgICAgICAqIFVzZWQgZm9yIGluc3RhbmNlcyBvZiB7QGxpbmsgVW5rbm93bklubGluZVRhZ1RyZWV9CiAgICAgICAgICogcmVwcmVzZW50aW5nIGFuIHVua25vd24gaW5saW5lIHRhZy4KICAgICAgICAgKi8KICAgICAgICBVTktOT1dOX0lOTElORV9UQUcsCgogICAgICAgIC8qKgogICAgICAgICAqIFVzZWQgZm9yIGluc3RhbmNlcyBvZiB7QGxpbmsgVXNlc1RyZWV9CiAgICAgICAgICogcmVwcmVzZW50aW5nIGFuIEB1c2VzIHRhZy4KICAgICAgICAgKi8KICAgICAgICBVU0VTKCJ1c2VzIiksCgogICAgICAgIC8qKgogICAgICAgICAqIFVzZWQgZm9yIGluc3RhbmNlcyBvZiB7QGxpbmsgVmFsdWVUcmVlfQogICAgICAgICAqIHJlcHJlc2VudGluZyBhbiBAdmFsdWUgdGFnLgogICAgICAgICAqLwogICAgICAgIFZBTFVFKCJ2YWx1ZSIpLAoKICAgICAgICAvKioKICAgICAgICAgKiBVc2VkIGZvciBpbnN0YW5jZXMgb2Yge0BsaW5rIFZlcnNpb25UcmVlfQogICAgICAgICAqIHJlcHJlc2VudGluZyBhbiBAdmVyc2lvbiB0YWcuCiAgICAgICAgICovCiAgICAgICAgVkVSU0lPTigidmVyc2lvbiIpLAoKICAgICAgICAvKioKICAgICAgICAgKiBBbiBpbXBsZW1lbnRhdGlvbi1yZXNlcnZlZCBub2RlLiBUaGlzIGlzIHRoZSBub3QgdGhlIG5vZGUKICAgICAgICAgKiB5b3UgYXJlIGxvb2tpbmcgZm9yLgogICAgICAgICAqLwogICAgICAgIE9USEVSOwoKICAgICAgICAvKioKICAgICAgICAgKiBUaGUgbmFtZSBvZiB0aGUgdGFnLCBpZiBhbnksIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGtpbmQgb2Ygbm9kZS4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgZmluYWwgU3RyaW5nIHRhZ05hbWU7CgogICAgICAgIEtpbmQoKSB7CiAgICAgICAgICAgIHRhZ05hbWUgPSBudWxsOwogICAgICAgIH0KCiAgICAgICAgS2luZChTdHJpbmcgdGFnTmFtZSkgewogICAgICAgICAgICB0aGlzLnRhZ05hbWUgPSB0YWdOYW1lOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGtpbmQgb2YgdGhpcyB0cmVlLgogICAgICoKICAgICAqIEByZXR1cm4gdGhlIGtpbmQgb2YgdGhpcyB0cmVlLgogICAgICovCiAgICBLaW5kIGdldEtpbmQoKTsKCiAgICAvKioKICAgICAqIEFjY2VwdCBtZXRob2QgdXNlZCB0byBpbXBsZW1lbnQgdGhlIHZpc2l0b3IgcGF0dGVybi4gIFRoZQogICAgICogdmlzaXRvciBwYXR0ZXJuIGlzIHVzZWQgdG8gaW1wbGVtZW50IG9wZXJhdGlvbnMgb24gdHJlZXMuCiAgICAgKgogICAgICogQHBhcmFtIDxSPiByZXN1bHQgdHlwZSBvZiB0aGlzIG9wZXJhdGlvbi4KICAgICAqIEBwYXJhbSA8RD4gdHlwZSBvZiBhZGRpdGlvbmFsIGRhdGEuCiAgICAgKiBAcGFyYW0gdmlzaXRvciB0aGUgdmlzaXRvciB0byBiZSBjYWxsZWQKICAgICAqIEBwYXJhbSBkYXRhIGEgcGFyYW1ldGVyIHZhbHVlIHRvIGJlIHBhc3NlZCB0byB0aGUgdmlzaXRvciBtZXRob2QKICAgICAqIEByZXR1cm4gdGhlIHZhbHVlIHJldHVybmVkIGZyb20gdGhlIHZpc2l0b3IgbWV0aG9kCiAgICAgKi8KICAgIDxSLCBEPiBSIGFjY2VwdChEb2NUcmVlVmlzaXRvcjxSLEQ+IHZpc2l0b3IsIEQgZGF0YSk7Cn0KUEsDBAoAAAgAAAY7qUrD3V5mpCQAAKQkAAAqAAAAY29tL3N1bi9zb3VyY2UvZG9jdHJlZS9Eb2NUcmVlVmlzaXRvci5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDExLCAyMDE2LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4uc291cmNlLmRvY3RyZWU7CgoKLyoqCiAqIEEgdmlzaXRvciBvZiB0cmVlcywgaW4gdGhlIHN0eWxlIG9mIHRoZSB2aXNpdG9yIGRlc2lnbiBwYXR0ZXJuLgogKiBDbGFzc2VzIGltcGxlbWVudGluZyB0aGlzIGludGVyZmFjZSBhcmUgdXNlZCB0byBvcGVyYXRlCiAqIG9uIGEgdHJlZSB3aGVuIHRoZSBraW5kIG9mIHRyZWUgaXMgdW5rbm93biBhdCBjb21waWxlIHRpbWUuCiAqIFdoZW4gYSB2aXNpdG9yIGlzIHBhc3NlZCB0byBhbiB0cmVlJ3Mge0BsaW5rIERvY1RyZWUjYWNjZXB0CiAqIGFjY2VwdH0gbWV0aG9kLCB0aGUgPHR0PnZpc2l0PGk+WFlaPC9pPjwvdHQ+IG1ldGhvZCBtb3N0IGFwcGxpY2FibGUKICogdG8gdGhhdCB0cmVlIGlzIGludm9rZWQuCiAqCiAqIDxwPiBDbGFzc2VzIGltcGxlbWVudGluZyB0aGlzIGludGVyZmFjZSBtYXkgb3IgbWF5IG5vdCB0aHJvdyBhCiAqIHtAY29kZSBOdWxsUG9pbnRlckV4Y2VwdGlvbn0gaWYgdGhlIGFkZGl0aW9uYWwgcGFyYW1ldGVyIHtAY29kZSBwfQogKiBpcyB7QGNvZGUgbnVsbH07IHNlZSBkb2N1bWVudGF0aW9uIG9mIHRoZSBpbXBsZW1lbnRpbmcgY2xhc3MgZm9yCiAqIGRldGFpbHMuCiAqCiAqIDxwPiA8Yj5XQVJOSU5HOjwvYj4gSXQgaXMgcG9zc2libGUgdGhhdCBtZXRob2RzIHdpbGwgYmUgYWRkZWQgdG8KICogdGhpcyBpbnRlcmZhY2UgdG8gYWNjb21tb2RhdGUgbmV3LCBjdXJyZW50bHkgdW5rbm93biwgZG9jIGNvbW1lbnQKICogc3RydWN0dXJlcyBhZGRlZCB0byBmdXR1cmUgdmVyc2lvbnMgb2YgdGhlIEphdmEmdHJhZGU7IHByb2dyYW1taW5nCiAqIGxhbmd1YWdlLiAgVGhlcmVmb3JlLCB2aXNpdG9yIGNsYXNzZXMgZGlyZWN0bHkgaW1wbGVtZW50aW5nIHRoaXMKICogaW50ZXJmYWNlIG1heSBiZSBzb3VyY2UgaW5jb21wYXRpYmxlIHdpdGggZnV0dXJlIHZlcnNpb25zIG9mIHRoZQogKiBwbGF0Zm9ybS4KICoKICogQHBhcmFtIDxSPiB0aGUgcmV0dXJuIHR5cGUgb2YgdGhpcyB2aXNpdG9yJ3MgbWV0aG9kcy4gIFVzZSB7QGxpbmsKICogICAgICAgICAgICBWb2lkfSBmb3IgdmlzaXRvcnMgdGhhdCBkbyBub3QgbmVlZCB0byByZXR1cm4gcmVzdWx0cy4KICogQHBhcmFtIDxQPiB0aGUgdHlwZSBvZiB0aGUgYWRkaXRpb25hbCBwYXJhbWV0ZXIgdG8gdGhpcyB2aXNpdG9yJ3MKICogICAgICAgICAgICBtZXRob2RzLiAgVXNlIHtAY29kZSBWb2lkfSBmb3IgdmlzaXRvcnMgdGhhdCBkbyBub3QgbmVlZCBhbgogKiAgICAgICAgICAgIGFkZGl0aW9uYWwgcGFyYW1ldGVyLgogKgogKiBAc2luY2UgMS44CiAqLwpwdWJsaWMgaW50ZXJmYWNlIERvY1RyZWVWaXNpdG9yPFIsUD4gewoKICAgIC8qKgogICAgICogVmlzaXRzIGFuIEF0dHJpYnV0ZVRyZWUgbm9kZS4KICAgICAqIEBwYXJhbSBub2RlIHRoZSBub2RlIGJlaW5nIHZpc2l0ZWQKICAgICAqIEBwYXJhbSBwIGEgcGFyYW1ldGVyIHZhbHVlCiAgICAgKiBAcmV0dXJuIGEgcmVzdWx0IHZhbHVlCiAgICAgKi8KICAgIFIgdmlzaXRBdHRyaWJ1dGUoQXR0cmlidXRlVHJlZSBub2RlLCBQIHApOwoKICAgIC8qKgogICAgICogVmlzaXRzIGFuIEF1dGhvclRyZWUgbm9kZS4KICAgICAqIEBwYXJhbSBub2RlIHRoZSBub2RlIGJlaW5nIHZpc2l0ZWQKICAgICAqIEBwYXJhbSBwIGEgcGFyYW1ldGVyIHZhbHVlCiAgICAgKiBAcmV0dXJuIGEgcmVzdWx0IHZhbHVlCiAgICAgKi8KICAgIFIgdmlzaXRBdXRob3IoQXV0aG9yVHJlZSBub2RlLCBQIHApOwoKICAgIC8qKgogICAgICogVmlzaXRzIGEgQ29tbWVudFRyZWUgbm9kZS4KICAgICAqIEBwYXJhbSBub2RlIHRoZSBub2RlIGJlaW5nIHZpc2l0ZWQKICAgICAqIEBwYXJhbSBwIGEgcGFyYW1ldGVyIHZhbHVlCiAgICAgKiBAcmV0dXJuIGEgcmVzdWx0IHZhbHVlCiAgICAgKi8KICAgIFIgdmlzaXRDb21tZW50KENvbW1lbnRUcmVlIG5vZGUsIFAgcCk7CgogICAgLyoqCiAgICAgKiBWaXNpdHMgYSBEZXByZWNhdGVkVHJlZSBub2RlLgogICAgICogQHBhcmFtIG5vZGUgdGhlIG5vZGUgYmVpbmcgdmlzaXRlZAogICAgICogQHBhcmFtIHAgYSBwYXJhbWV0ZXIgdmFsdWUKICAgICAqIEByZXR1cm4gYSByZXN1bHQgdmFsdWUKICAgICAqLwogICAgUiB2aXNpdERlcHJlY2F0ZWQoRGVwcmVjYXRlZFRyZWUgbm9kZSwgUCBwKTsKCiAgICAvKioKICAgICAqIFZpc2l0cyBhIERvY0NvbW1lbnRUcmVlIG5vZGUuCiAgICAgKiBAcGFyYW0gbm9kZSB0aGUgbm9kZSBiZWluZyB2aXNpdGVkCiAgICAgKiBAcGFyYW0gcCBhIHBhcmFtZXRlciB2YWx1ZQogICAgICogQHJldHVybiBhIHJlc3VsdCB2YWx1ZQogICAgICovCiAgICBSIHZpc2l0RG9jQ29tbWVudChEb2NDb21tZW50VHJlZSBub2RlLCBQIHApOwoKICAgIC8qKgogICAgICogVmlzaXRzIGEgRG9jUm9vdFRyZWUgbm9kZS4KICAgICAqIEBwYXJhbSBub2RlIHRoZSBub2RlIGJlaW5nIHZpc2l0ZWQKICAgICAqIEBwYXJhbSBwIGEgcGFyYW1ldGVyIHZhbHVlCiAgICAgKiBAcmV0dXJuIGEgcmVzdWx0IHZhbHVlCiAgICAgKi8KICAgIFIgdmlzaXREb2NSb290KERvY1Jvb3RUcmVlIG5vZGUsIFAgcCk7CgogICAgLyoqCiAgICAgKiBWaXNpdHMgYW4gRW5kRWxlbWVudFRyZWUgbm9kZS4KICAgICAqIEBwYXJhbSBub2RlIHRoZSBub2RlIGJlaW5nIHZpc2l0ZWQKICAgICAqIEBwYXJhbSBwIGEgcGFyYW1ldGVyIHZhbHVlCiAgICAgKiBAcmV0dXJuIGEgcmVzdWx0IHZhbHVlCiAgICAgKi8KICAgIFIgdmlzaXRFbmRFbGVtZW50KEVuZEVsZW1lbnRUcmVlIG5vZGUsIFAgcCk7CgogICAgLyoqCiAgICAgKiBWaXNpdHMgYW4gRW50aXR5VHJlZSBub2RlLgogICAgICogQHBhcmFtIG5vZGUgdGhlIG5vZGUgYmVpbmcgdmlzaXRlZAogICAgICogQHBhcmFtIHAgYSBwYXJhbWV0ZXIgdmFsdWUKICAgICAqIEByZXR1cm4gYSByZXN1bHQgdmFsdWUKICAgICAqLwogICAgUiB2aXNpdEVudGl0eShFbnRpdHlUcmVlIG5vZGUsIFAgcCk7CgogICAgLyoqCiAgICAgKiBWaXNpdHMgYW4gRXJyb25lb3VzVHJlZSBub2RlLgogICAgICogQHBhcmFtIG5vZGUgdGhlIG5vZGUgYmVpbmcgdmlzaXRlZAogICAgICogQHBhcmFtIHAgYSBwYXJhbWV0ZXIgdmFsdWUKICAgICAqIEByZXR1cm4gYSByZXN1bHQgdmFsdWUKICAgICAqLwogICAgUiB2aXNpdEVycm9uZW91cyhFcnJvbmVvdXNUcmVlIG5vZGUsIFAgcCk7CgogICAgLyoqCiAgICAgKiBWaXNpdHMgYSBIaWRkZW5UcmVlIG5vZGUuCiAgICAgKiBAcGFyYW0gbm9kZSB0aGUgbm9kZSBiZWluZyB2aXNpdGVkCiAgICAgKiBAcGFyYW0gcCBhIHBhcmFtZXRlciB2YWx1ZQogICAgICogQHJldHVybiBhIHJlc3VsdCB2YWx1ZQogICAgICovCiAgICBSIHZpc2l0SGlkZGVuKEhpZGRlblRyZWUgbm9kZSwgUCBwKTsKCiAgICAvKioKICAgICAqIFZpc2l0cyBhbiBJZGVudGlmaWVyVHJlZSBub2RlLgogICAgICogQHBhcmFtIG5vZGUgdGhlIG5vZGUgYmVpbmcgdmlzaXRlZAogICAgICogQHBhcmFtIHAgYSBwYXJhbWV0ZXIgdmFsdWUKICAgICAqIEByZXR1cm4gYSByZXN1bHQgdmFsdWUKICAgICAqLwogICAgUiB2aXNpdElkZW50aWZpZXIoSWRlbnRpZmllclRyZWUgbm9kZSwgUCBwKTsKCiAgICAvKioKICAgICAqIFZpc2l0cyBhbiBJbmRleFRyZWUgbm9kZS4KICAgICAqIEBwYXJhbSBub2RlIHRoZSBub2RlIGJlaW5nIHZpc2l0ZWQKICAgICAqIEBwYXJhbSBwIGEgcGFyYW1ldGVyIHZhbHVlCiAgICAgKiBAcmV0dXJuIGEgcmVzdWx0IHZhbHVlCiAgICAgKi8KICAgIFIgdmlzaXRJbmRleChJbmRleFRyZWUgbm9kZSwgUCBwKTsKCiAgICAvKioKICAgICAqIFZpc2l0cyBhbiBJbmhlcml0RG9jVHJlZSBub2RlLgogICAgICogQHBhcmFtIG5vZGUgdGhlIG5vZGUgYmVpbmcgdmlzaXRlZAogICAgICogQHBhcmFtIHAgYSBwYXJhbWV0ZXIgdmFsdWUKICAgICAqIEByZXR1cm4gYSByZXN1bHQgdmFsdWUKICAgICAqLwogICAgUiB2aXNpdEluaGVyaXREb2MoSW5oZXJpdERvY1RyZWUgbm9kZSwgUCBwKTsKCiAgICAvKioKICAgICAqIFZpc2l0cyBhIExpbmtUcmVlIG5vZGUuCiAgICAgKiBAcGFyYW0gbm9kZSB0aGUgbm9kZSBiZWluZyB2aXNpdGVkCiAgICAgKiBAcGFyYW0gcCBhIHBhcmFtZXRlciB2YWx1ZQogICAgICogQHJldHVybiBhIHJlc3VsdCB2YWx1ZQogICAgICovCiAgICBSIHZpc2l0TGluayhMaW5rVHJlZSBub2RlLCBQIHApOwoKICAgIC8qKgogICAgICogVmlzaXRzIGFuIExpdGVyYWxUcmVlIG5vZGUuCiAgICAgKiBAcGFyYW0gbm9kZSB0aGUgbm9kZSBiZWluZyB2aXNpdGVkCiAgICAgKiBAcGFyYW0gcCBhIHBhcmFtZXRlciB2YWx1ZQogICAgICogQHJldHVybiBhIHJlc3VsdCB2YWx1ZQogICAgICovCiAgICBSIHZpc2l0TGl0ZXJhbChMaXRlcmFsVHJlZSBub2RlLCBQIHApOwoKICAgIC8qKgogICAgICogVmlzaXRzIGEgUGFyYW1UcmVlIG5vZGUuCiAgICAgKiBAcGFyYW0gbm9kZSB0aGUgbm9kZSBiZWluZyB2aXNpdGVkCiAgICAgKiBAcGFyYW0gcCBhIHBhcmFtZXRlciB2YWx1ZQogICAgICogQHJldHVybiBhIHJlc3VsdCB2YWx1ZQogICAgICovCiAgICBSIHZpc2l0UGFyYW0oUGFyYW1UcmVlIG5vZGUsIFAgcCk7CgogICAgLyoqCiAgICAgKiBWaXNpdHMgYSBQcm92aWRlc1RyZWUgbm9kZS4KICAgICAqIEBwYXJhbSBub2RlIHRoZSBub2RlIGJlaW5nIHZpc2l0ZWQKICAgICAqIEBwYXJhbSBwIGEgcGFyYW1ldGVyIHZhbHVlCiAgICAgKiBAcmV0dXJuIGEgcmVzdWx0IHZhbHVlCiAgICAgKi8KICAgIFIgdmlzaXRQcm92aWRlcyhQcm92aWRlc1RyZWUgbm9kZSwgUCBwKTsKCiAgICAvKioKICAgICAqIFZpc2l0cyBhIFJlZmVyZW5jZVRyZWUgbm9kZS4KICAgICAqIEBwYXJhbSBub2RlIHRoZSBub2RlIGJlaW5nIHZpc2l0ZWQKICAgICAqIEBwYXJhbSBwIGEgcGFyYW1ldGVyIHZhbHVlCiAgICAgKiBAcmV0dXJuIGEgcmVzdWx0IHZhbHVlCiAgICAgKi8KICAgIFIgdmlzaXRSZWZlcmVuY2UoUmVmZXJlbmNlVHJlZSBub2RlLCBQIHApOwoKICAgIC8qKgogICAgICogVmlzaXRzIGEgUmV0dXJuVHJlZSBub2RlLgogICAgICogQHBhcmFtIG5vZGUgdGhlIG5vZGUgYmVpbmcgdmlzaXRlZAogICAgICogQHBhcmFtIHAgYSBwYXJhbWV0ZXIgdmFsdWUKICAgICAqIEByZXR1cm4gYSByZXN1bHQgdmFsdWUKICAgICAqLwogICAgUiB2aXNpdFJldHVybihSZXR1cm5UcmVlIG5vZGUsIFAgcCk7CgogICAgLyoqCiAgICAgKiBWaXNpdHMgYSBTZWVUcmVlIG5vZGUuCiAgICAgKiBAcGFyYW0gbm9kZSB0aGUgbm9kZSBiZWluZyB2aXNpdGVkCiAgICAgKiBAcGFyYW0gcCBhIHBhcmFtZXRlciB2YWx1ZQogICAgICogQHJldHVybiBhIHJlc3VsdCB2YWx1ZQogICAgICovCiAgICBSIHZpc2l0U2VlKFNlZVRyZWUgbm9kZSwgUCBwKTsKCiAgICAvKioKICAgICAqIFZpc2l0cyBhIFNlcmlhbFRyZWUgbm9kZS4KICAgICAqIEBwYXJhbSBub2RlIHRoZSBub2RlIGJlaW5nIHZpc2l0ZWQKICAgICAqIEBwYXJhbSBwIGEgcGFyYW1ldGVyIHZhbHVlCiAgICAgKiBAcmV0dXJuIGEgcmVzdWx0IHZhbHVlCiAgICAgKi8KICAgIFIgdmlzaXRTZXJpYWwoU2VyaWFsVHJlZSBub2RlLCBQIHApOwoKICAgIC8qKgogICAgICogVmlzaXRzIGEgU2VyaWFsRGF0YVRyZWUgbm9kZS4KICAgICAqIEBwYXJhbSBub2RlIHRoZSBub2RlIGJlaW5nIHZpc2l0ZWQKICAgICAqIEBwYXJhbSBwIGEgcGFyYW1ldGVyIHZhbHVlCiAgICAgKiBAcmV0dXJuIGEgcmVzdWx0IHZhbHVlCiAgICAgKi8KICAgIFIgdmlzaXRTZXJpYWxEYXRhKFNlcmlhbERhdGFUcmVlIG5vZGUsIFAgcCk7CgogICAgLyoqCiAgICAgKiBWaXNpdHMgYSBTZXJpYWxGaWVsZFRyZWUgbm9kZS4KICAgICAqIEBwYXJhbSBub2RlIHRoZSBub2RlIGJlaW5nIHZpc2l0ZWQKICAgICAqIEBwYXJhbSBwIGEgcGFyYW1ldGVyIHZhbHVlCiAgICAgKiBAcmV0dXJuIGEgcmVzdWx0IHZhbHVlCiAgICAgKi8KICAgIFIgdmlzaXRTZXJpYWxGaWVsZChTZXJpYWxGaWVsZFRyZWUgbm9kZSwgUCBwKTsKCiAgICAvKioKICAgICAqIFZpc2l0cyBhIFNpbmNlVHJlZSBub2RlLgogICAgICogQHBhcmFtIG5vZGUgdGhlIG5vZGUgYmVpbmcgdmlzaXRlZAogICAgICogQHBhcmFtIHAgYSBwYXJhbWV0ZXIgdmFsdWUKICAgICAqIEByZXR1cm4gYSByZXN1bHQgdmFsdWUKICAgICAqLwogICAgUiB2aXNpdFNpbmNlKFNpbmNlVHJlZSBub2RlLCBQIHApOwoKICAgIC8qKgogICAgICogVmlzaXRzIGEgU3RhcnRFbGVtZW50VHJlZSBub2RlLgogICAgICogQHBhcmFtIG5vZGUgdGhlIG5vZGUgYmVpbmcgdmlzaXRlZAogICAgICogQHBhcmFtIHAgYSBwYXJhbWV0ZXIgdmFsdWUKICAgICAqIEByZXR1cm4gYSByZXN1bHQgdmFsdWUKICAgICAqLwogICAgUiB2aXNpdFN0YXJ0RWxlbWVudChTdGFydEVsZW1lbnRUcmVlIG5vZGUsIFAgcCk7CgogICAgLyoqCiAgICAgKiBWaXNpdHMgYSBUZXh0VHJlZSBub2RlLgogICAgICogQHBhcmFtIG5vZGUgdGhlIG5vZGUgYmVpbmcgdmlzaXRlZAogICAgICogQHBhcmFtIHAgYSBwYXJhbWV0ZXIgdmFsdWUKICAgICAqIEByZXR1cm4gYSByZXN1bHQgdmFsdWUKICAgICAqLwogICAgUiB2aXNpdFRleHQoVGV4dFRyZWUgbm9kZSwgUCBwKTsKCiAgICAvKioKICAgICAqIFZpc2l0cyBhIFRocm93c1RyZWUgbm9kZS4KICAgICAqIEBwYXJhbSBub2RlIHRoZSBub2RlIGJlaW5nIHZpc2l0ZWQKICAgICAqIEBwYXJhbSBwIGEgcGFyYW1ldGVyIHZhbHVlCiAgICAgKiBAcmV0dXJuIGEgcmVzdWx0IHZhbHVlCiAgICAgKi8KICAgIFIgdmlzaXRUaHJvd3MoVGhyb3dzVHJlZSBub2RlLCBQIHApOwoKICAgIC8qKgogICAgICogVmlzaXRzIGFuIFVua25vd25CbG9ja1RhZ1RyZWUgbm9kZS4KICAgICAqIEBwYXJhbSBub2RlIHRoZSBub2RlIGJlaW5nIHZpc2l0ZWQKICAgICAqIEBwYXJhbSBwIGEgcGFyYW1ldGVyIHZhbHVlCiAgICAgKiBAcmV0dXJuIGEgcmVzdWx0IHZhbHVlCiAgICAgKi8KICAgIFIgdmlzaXRVbmtub3duQmxvY2tUYWcoVW5rbm93bkJsb2NrVGFnVHJlZSBub2RlLCBQIHApOwoKICAgIC8qKgogICAgICogVmlzaXRzIGFuIFVua25vd25JbmxpbmVUYWdUcmVlIG5vZGUuCiAgICAgKiBAcGFyYW0gbm9kZSB0aGUgbm9kZSBiZWluZyB2aXNpdGVkCiAgICAgKiBAcGFyYW0gcCBhIHBhcmFtZXRlciB2YWx1ZQogICAgICogQHJldHVybiBhIHJlc3VsdCB2YWx1ZQogICAgICovCiAgICBSIHZpc2l0VW5rbm93bklubGluZVRhZyhVbmtub3duSW5saW5lVGFnVHJlZSBub2RlLCBQIHApOwoKICAgIC8qKgogICAgICogVmlzaXRzIGEgVXNlc1RyZWUgbm9kZS4KICAgICAqIEBwYXJhbSBub2RlIHRoZSBub2RlIGJlaW5nIHZpc2l0ZWQKICAgICAqIEBwYXJhbSBwIGEgcGFyYW1ldGVyIHZhbHVlCiAgICAgKiBAcmV0dXJuIGEgcmVzdWx0IHZhbHVlCiAgICAgKi8KICAgIFIgdmlzaXRVc2VzKFVzZXNUcmVlIG5vZGUsIFAgcCk7CgogICAgLyoqCiAgICAgKiBWaXNpdHMgYSBWYWx1ZVRyZWUgbm9kZS4KICAgICAqIEBwYXJhbSBub2RlIHRoZSBub2RlIGJlaW5nIHZpc2l0ZWQKICAgICAqIEBwYXJhbSBwIGEgcGFyYW1ldGVyIHZhbHVlCiAgICAgKiBAcmV0dXJuIGEgcmVzdWx0IHZhbHVlCiAgICAgKi8KICAgIFIgdmlzaXRWYWx1ZShWYWx1ZVRyZWUgbm9kZSwgUCBwKTsKCiAgICAvKioKICAgICAqIFZpc2l0cyBhIFZlcnNpb25UcmVlVHJlZSBub2RlLgogICAgICogQHBhcmFtIG5vZGUgdGhlIG5vZGUgYmVpbmcgdmlzaXRlZAogICAgICogQHBhcmFtIHAgYSBwYXJhbWV0ZXIgdmFsdWUKICAgICAqIEByZXR1cm4gYSByZXN1bHQgdmFsdWUKICAgICAqLwogICAgUiB2aXNpdFZlcnNpb24oVmVyc2lvblRyZWUgbm9kZSwgUCBwKTsKCiAgICAvKioKICAgICAqIFZpc2l0cyBhbiB1bmtub3duIHR5cGUgb2YgRG9jVHJlZSBub2RlLgogICAgICogVGhpcyBjYW4gb2NjdXIgaWYgdGhlIHNldCBvZiB0YWdzIGV2b2x2ZXMgYW5kIG5ldyBraW5kcwogICAgICogb2Ygbm9kZXMgYXJlIGFkZGVkIHRvIHRoZSB7QGNvZGUgRG9jVHJlZX0gaGllcmFyY2h5LgogICAgICogQHBhcmFtIG5vZGUgdGhlIG5vZGUgYmVpbmcgdmlzaXRlZAogICAgICogQHBhcmFtIHAgYSBwYXJhbWV0ZXIgdmFsdWUKICAgICAqIEByZXR1cm4gYSByZXN1bHQgdmFsdWUKICAgICAqLwogICAgUiB2aXNpdE90aGVyKERvY1RyZWUgbm9kZSwgUCBwKTsKfQpQSwMECgAACAAABjupSmyJHipyBwAAcgcAACsAAABjb20vc3VuL3NvdXJjZS9kb2N0cmVlL1NlcmlhbEZpZWxkVHJlZS5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDExLCAyMDE0LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4uc291cmNlLmRvY3RyZWU7CgppbXBvcnQgamF2YS51dGlsLkxpc3Q7CgovKioKICogQSB0cmVlIG5vZGUgZm9yIGFuIEBzZXJpYWxEYXRhIGJsb2NrIHRhZy4KICoKICogPHA+CiAqICYjMDY0O3NlcmlhbEZpZWxkIGZpZWxkLW5hbWUgZmllbGQtdHlwZSBmaWVsZC1kZXNjcmlwdGlvbgogKgogKiBAc2luY2UgMS44CiAqLwpwdWJsaWMgaW50ZXJmYWNlIFNlcmlhbEZpZWxkVHJlZSBleHRlbmRzIEJsb2NrVGFnVHJlZSB7CiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIG5hbWUgb2YgdGhlIHNlcmlhbCBmaWVsZC4KICAgICAqIEByZXR1cm4gdGhlIG5hbWUgb2YgdGhlIHNlcmlhbCBmaWVsZAogICAgICovCiAgICBJZGVudGlmaWVyVHJlZSBnZXROYW1lKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSB0eXBlIG9mIHRoZSBzZXJpYWwgZmllbGQuCiAgICAgKiBAcmV0dXJuIHRoZSB0eXBlIG9mIHRoZSBzZXJpYWwgZmllbGQKICAgICAqLwogICAgUmVmZXJlbmNlVHJlZSBnZXRUeXBlKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBkZXNjcmlwdGlvbiBvZiB0aGUgc2VyaWFsIGZpZWxkLgogICAgICogQHJldHVybiB0aGUgZGVzY3JpcHRpb24gb2YgdGhlIHNlcmlhbCBmaWVsZAogICAgICovCiAgICBMaXN0PD8gZXh0ZW5kcyBEb2NUcmVlPiBnZXREZXNjcmlwdGlvbigpOwp9ClBLAwQKAAAIAAAGO6lKbmRWe+wFAADsBQAAKQAAAGNvbS9zdW4vc291cmNlL2RvY3RyZWUvSW5saW5lVGFnVHJlZS5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDExLCAyMDE0LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4uc291cmNlLmRvY3RyZWU7CgovKioKICogQSB0cmVlIG5vZGUgdXNlZCBhcyB0aGUgYmFzZSBjbGFzcyBmb3IgdGhlIGRpZmZlcmVudCB0eXBlcyBvZgogKiBpbmxpbmUgdGFncy4KICoKICogQHNpbmNlIDEuOAogKi8KcHVibGljIGludGVyZmFjZSBJbmxpbmVUYWdUcmVlIGV4dGVuZHMgRG9jVHJlZSB7CiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIG5hbWUgb2YgdGhlIHRhZy4KICAgICAqIEByZXR1cm4gdGhlIG5hbWUgb2YgdGhlIHRhZwogICAgICovCiAgICBTdHJpbmcgZ2V0VGFnTmFtZSgpOwp9ClBLAwQKAAAIAAAGO6lKAAAAAAAAAAAAAAAADgAAAGNvbS9zdW4vdG9vbHMvUEsDBAoAAAgAAAY7qUoAAAAAAAAAAAAAAAAVAAAAY29tL3N1bi90b29scy9zamF2YWMvUEsDBAoAAAgAAAY7qUqKZKDcXA8AAFwPAAApAAAAY29tL3N1bi90b29scy9zamF2YWMvUHViQXBpRXh0cmFjdG9yLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTIsIDIwMTQsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5zamF2YWM7CgppbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKaW1wb3J0IGphdmEuaW8uUHJpbnRXcml0ZXI7CmltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOwoKaW1wb3J0IGphdmF4LnRvb2xzLkphdmFDb21waWxlci5Db21waWxhdGlvblRhc2s7CmltcG9ydCBqYXZheC50b29scy5KYXZhRmlsZU1hbmFnZXI7CgppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5hcGkuSmF2YWNUb29sOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLkNsYXNzRmluZGVyOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlN5bWJvbC5DbGFzc1N5bWJvbDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5TeW10YWI7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLm1haW4uSmF2YUNvbXBpbGVyOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkNvbnRleHQ7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuQ29udmVydDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5OYW1lOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLk5hbWVzOwppbXBvcnQgY29tLnN1bi50b29scy5zamF2YWMuY29tcC5QdWJhcGlWaXNpdG9yOwppbXBvcnQgY29tLnN1bi50b29scy5zamF2YWMuY29tcC5TbWFydEZpbGVNYW5hZ2VyOwppbXBvcnQgY29tLnN1bi50b29scy5zamF2YWMub3B0aW9ucy5PcHRpb25zOwppbXBvcnQgY29tLnN1bi50b29scy5zamF2YWMucHViYXBpLlB1YkFwaTsKCnB1YmxpYyBjbGFzcyBQdWJBcGlFeHRyYWN0b3IgewogICAgLy8gU2V0dXAgYSBjb21waWxlciBjb250ZXh0IGZvciBmaW5kaW5nIGNsYXNzZXMgaW4gdGhlIGNsYXNzcGF0aAogICAgLy8gYW5kIHRvIGV4ZWN1dGUgYW5ub3RhdGlvbiBwcm9jZXNzb3JzLgogICAgZmluYWwgQ29udGV4dCBjb250ZXh0OwogICAgZmluYWwgQ29tcGlsYXRpb25UYXNrIHRhc2s7CgogICAgZmluYWwgU21hcnRGaWxlTWFuYWdlciBmaWxlTWFuYWdlcjsKCiAgICAvKioKICAgICAqIFNldHVwIGEgY29tcGlsYXRpb24gY29udGV4dCwgdXNlZCBmb3IgcmVhZGluZyBwdWJsaWMgYXBpcyBvZiBjbGFzc2VzIG9uIHRoZSBjbGFzc3BhdGgKICAgICAqIGFzIHdlbGwgYXMgYW5ub3RhdGlvbiBwcm9jZXNzb3JzLgogICAgICovCiAgICBwdWJsaWMgUHViQXBpRXh0cmFjdG9yKE9wdGlvbnMgb3B0aW9ucykgewogICAgICAgIEphdmFjVG9vbCBjb21waWxlciA9IGNvbS5zdW4udG9vbHMuamF2YWMuYXBpLkphdmFjVG9vbC5jcmVhdGUoKTsKICAgICAgICBmaWxlTWFuYWdlciA9IG5ldyBTbWFydEZpbGVNYW5hZ2VyKGNvbXBpbGVyLmdldFN0YW5kYXJkRmlsZU1hbmFnZXIobnVsbCwgbnVsbCwgbnVsbCkpOwogICAgICAgIGNvbnRleHQgPSBuZXcgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkNvbnRleHQoKTsKICAgICAgICBTdHJpbmdbXSBhcmdzID0gb3B0aW9ucy5wcmVwSmF2YWNBcmdzKCk7CiAgICAgICAgdGFzayA9IGNvbXBpbGVyLmdldFRhc2sobmV3IFByaW50V3JpdGVyKFN5c3RlbS5lcnIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVNYW5hZ2VyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXJyYXlzLmFzTGlzdChhcmdzKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGV4dCk7CiAgICAgICAgLy8gVHJpZ2dlciBhIGNyZWF0aW9uIG9mIHRoZSBKYXZhQ29tcGlsZXIsIG5lY2Vzc2FyeSB0byBnZXQgYSBzb3VyY2VDb21wbGV0ZXIgZm9yIENsYXNzRmluZGVyLgogICAgICAgIC8vIFRoZSBzb3VyY2VDb21wbGV0ZXIgaXMgdXNlZCBmb3IgYnVpbGQgc2l0dWF0aW9ucyB3aGVyZSBhIGNsYXNzcGF0aCBjbGFzcyByZWZlcmVuY2VzIG90aGVyIGNsYXNzZXMKICAgICAgICAvLyB0aGF0IGhhcHBlbnMgdG8gYmUgb24gdGhlIHNvdXJjZXBhdGguCiAgICAgICAgSmF2YUNvbXBpbGVyLmluc3RhbmNlKGNvbnRleHQpOwoKLy8gICAgICAgIGNvbnRleHQucHV0KEphdmFGaWxlTWFuYWdlci5jbGFzcywgZmlsZU1hbmFnZXIpOwogICAgfQoKICAgIHB1YmxpYyBQdWJBcGkgZ2V0UHViQXBpKFN0cmluZyBmdWxseVF1YWxpZmllZENsYXNzTmFtZSkgewogICAgICAgIFN5bXRhYiBzeW1zID0gU3ltdGFiLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIENsYXNzRmluZGVyIGNyID0gQ2xhc3NGaW5kZXIuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgTmFtZXMgbnMgPSBOYW1lcy5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBOYW1lIG4gPSBucy5mcm9tU3RyaW5nKGZ1bGx5UXVhbGlmaWVkQ2xhc3NOYW1lKTsKICAgICAgICBDbGFzc1N5bWJvbCBjcyA9IGNyLmxvYWRDbGFzcyhzeW1zLmluZmVyTW9kdWxlKENvbnZlcnQucGFja2FnZVBhcnQobikpLCBuKTsKICAgICAgICBQdWJhcGlWaXNpdG9yIHYgPSBuZXcgUHViYXBpVmlzaXRvcigpOwogICAgICAgIHYudmlzaXQoY3MpOwogICAgICAgIHJldHVybiB2LmdldENvbGxlY3RlZFB1YkFwaSgpOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICBmaWxlTWFuYWdlci5jbG9zZSgpOwogICAgfQp9ClBLAwQKAAAIAADSfU1K5h8cOMkIAADJCAAAJgAAAGNvbS9zdW4vdG9vbHMvc2phdmFjL0NvbXBpbGVDaHVuay5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDEyLCAyMDE0LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuc2phdmFjOwoKaW1wb3J0IGphdmEubmV0LlVSSTsKaW1wb3J0IGphdmEudXRpbC5IYXNoU2V0OwppbXBvcnQgamF2YS51dGlsLlNldDsKCi8qKgogKiBBIGNvbXBpbGUgY2h1bmsgaXMgYSBsaXN0IG9mIHNvdXJjZXMvcGFja2FnZXMgdG8gYmUgY29tcGlsZWQuIFBvc3NpYmx5IGEgc3Vic2V0IG9mCiAqIHRoZSB0b3RhbCBudW1iZXIgb2Ygc291cmNlcy9wYWNrYWdlcyB0byBiZSBjb21waWxlZCBmb3IgdGhpcyBzamF2YWMgaW52b2NhdGlvbi4KICoKICogIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqICBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqICBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogKiAgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPgogKi8KcHVibGljIGNsYXNzIENvbXBpbGVDaHVuayBpbXBsZW1lbnRzIENvbXBhcmFibGU8Q29tcGlsZUNodW5rPiB7CiAgICBwdWJsaWMgaW50IG51bVBhY2thZ2VzOwogICAgcHVibGljIGludCBudW1EZXBlbmRlbnRzOwogICAgcHVibGljIFNldDxVUkk+IHNyY3MgPSBuZXcgSGFzaFNldDw+KCk7CiAgICBwdWJsaWMgU3RyaW5nQnVpbGRlciBwa2dOYW1lcyA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CiAgICBwdWJsaWMgU3RyaW5nIHBrZ0Zyb21Ub3MgPSAiIjsKCiAgICBwdWJsaWMgaW50IGNvbXBhcmVUbyhDb21waWxlQ2h1bmsgYykgewogICAgICAgIGlmIChudW1EZXBlbmRlbnRzID09IGMubnVtRGVwZW5kZW50cykgcmV0dXJuIDA7CiAgICAgICAgaWYgKG51bURlcGVuZGVudHMgPiBjLm51bURlcGVuZGVudHMpIHJldHVybiAtMTsKICAgICAgICByZXR1cm4gLTE7CiAgICB9CgogICAgYm9vbGVhbiBlcXVhbChDb21waWxlQ2h1bmsgYykgewogICAgICAgIHJldHVybiBudW1EZXBlbmRlbnRzID09IGMubnVtRGVwZW5kZW50czsKICAgIH0KfQpQSwMECgAACAAABjupSn76Y73VKgAA1SoAACEAAABjb20vc3VuL3Rvb2xzL3NqYXZhYy9QYWNrYWdlLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTIsIDIwMTUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5zamF2YWM7CgppbXBvcnQgamF2YS5pby5GaWxlOwppbXBvcnQgamF2YS5uZXQuVVJJOwppbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOwppbXBvcnQgamF2YS51dGlsLkhhc2hTZXQ7CmltcG9ydCBqYXZhLnV0aWwuTGlzdDsKaW1wb3J0IGphdmEudXRpbC5NYXA7CmltcG9ydCBqYXZhLnV0aWwuU2V0OwppbXBvcnQgamF2YS51dGlsLlRyZWVNYXA7CmltcG9ydCBqYXZhLnV0aWwucmVnZXguTWF0Y2hlcjsKaW1wb3J0IGphdmEudXRpbC5yZWdleC5QYXR0ZXJuOwppbXBvcnQgamF2YS51dGlsLnN0cmVhbS5TdHJlYW07CgppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkFzc2VydDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuc2phdmFjLnB1YmFwaS5QdWJBcGk7CgovKioKICogVGhlIFBhY2thZ2UgY2xhc3MgbWFpbnRhaW5zIG1ldGEgaW5mb3JtYXRpb24gYWJvdXQgYSBwYWNrYWdlLgogKiBGb3IgZXhhbXBsZSBpdHMgc291cmNlcywgZGVwZW5kZW50cyxpdHMgcHViYXBpIGFuZCBpdHMgYXJ0aWZhY3RzLgogKgogKiBJdCBtaWdodCBsb29rIG9kZCB0aGF0IHdlIHRyYWNrIGRlcGVuZGVudHMvcHViYXBpL2FydGlmYWN0cyBvbgogKiBhIHBhY2thZ2UgbGV2ZWwsIGJ1dCBpdCBtYWtlcyBzZW5zZSBzaW5jZSByZWNvbXBpbGluZyBhIGZ1bGwgcGFja2FnZQogKiB0YWtlcyBhcyBsb25nIGFzIHJlY29tcGlsaW5nIGEgc2luZ2xlIGphdmEgZmlsZSBpbiB0aGF0IHBhY2thZ2UsCiAqIGlmIHlvdSB0YWtlIGludG8gYWNjb3VudCB0aGUgc3RhcnR1cCB0aW1lIG9mIHRoZSBqdm0uCiAqCiAqIEFsc28gdGhlIGRlcGVuZGVuY3kgaW5mb3JtYXRpb24gd2lsbCBiZSBtdWNoIHNtYWxsZXIgKGdvb2QgZm9yIHRoZSBqYXZhY19zdGF0ZSBmaWxlIHNpemUpCiAqIGFuZCBpdCBzaW1wbGlmaWVzIHRyYWNraW5nIGFydGlmYWN0IGdlbmVyYXRpb24sIHlvdSBkbyBub3QgYWx3YXlzIGtub3cgZnJvbSB3aGljaAogKiBzb3VyY2UgYSBjbGFzcyBmaWxlIHdhcyBnZW5lcmF0ZWQsIGJ1dCB5b3UgYWx3YXlzIGtub3cgd2hpY2ggcGFja2FnZSBpdCBiZWxvbmdzIHRvLgogKgogKiBJdCBpcyBhbHNvIGVkdWNhdGlvbmFsIHRvIHNlZSBwYWNrYWdlIGRlcGVuZGVuY2llcyB0cmlnZ2VyaW5nIHJlY29tcGlsYXRpb24gb2YKICogb3RoZXIgcGFja2FnZXMuIEV2ZW4gdGhvdWdoIHRoZSByZWNvbXBpbGF0aW9uIHdhcyBwZXJoYXBzIG5vdCBuZWNlc3NhcnksCiAqIHRoZSB2aXNpYmxlIHJlY29tcGlsYXRpb24gb2YgdGhlIGRlcGVuZGVudCBwYWNrYWdlcyBpbmRpY2F0ZXMgaG93IG11Y2ggY2lyY3VsYXIKICogZGVwZW5kZW5jaWVzIHlvdXIgY29kZSBoYXMuCiAqCiAqICA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiAgSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93biByaXNrLgogKiAgVGhpcyBjb2RlIGFuZCBpdHMgaW50ZXJuYWwgaW50ZXJmYWNlcyBhcmUgc3ViamVjdCB0byBjaGFuZ2Ugb3IKICogIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj4KICovCnB1YmxpYyBjbGFzcyBQYWNrYWdlIGltcGxlbWVudHMgQ29tcGFyYWJsZTxQYWNrYWdlPiB7CiAgICAvLyBUaGUgbW9kdWxlIHRoaXMgcGFja2FnZSBiZWxvbmdzIHRvLiAoVGhlcmUgaXMgYSBsZWdhY3kgbW9kdWxlIHdpdGggYW4gZW1wdHkgc3RyaW5nIG5hbWUsCiAgICAvLyB1c2VkIGZvciBhbGwgbGVnYWN5IHNvdXJjZXMuKQogICAgcHJpdmF0ZSBNb2R1bGUgbW9kOwogICAgLy8gTmFtZSBvZiB0aGlzIHBhY2thZ2UsIG1vZHVsZTpwa2cKICAgIC8vIGV4MSBqZGsuYmFzZTpqYXZhLmxhbmcKICAgIC8vIGV4MiA6amF2YS5sYW5nICh3aGVuIGluIGxlZ2FjeSBtb2RlKQogICAgcHJpdmF0ZSBTdHJpbmcgbmFtZTsKICAgIC8vIFRoZSBkaXJlY3RvcnkgcGF0aCB0byB0aGUgcGFja2FnZS4gSWYgdGhlIHBhY2thZ2UgYmVsb25ncyB0byBhIG1vZHVsZSwKICAgIC8vIHRoZW4gdGhhdCBtb2R1bGUncyBmaWxlIHN5c3RlbSBuYW1lIGlzIHBhcnQgb2YgdGhlIHBhdGguCiAgICBwcml2YXRlIFN0cmluZyBkaXJuYW1lOwogICAgLy8gVGhpcyBwYWNrYWdlIGhhcyB0aGUgZm9sbG93aW5nIGRlcGVuZGVudHMsIHRoYXQgZGVwZW5kIG9uIHRoaXMgcGFja2FnZS4KICAgIHByaXZhdGUgU2V0PFN0cmluZz4gZGVwZW5kZW50cyA9IG5ldyBIYXNoU2V0PD4oKTsKCiAgICAvLyBGdWxseSBxdWFsaWZpZWQgbmFtZSBvZiBjbGFzcyBpbiB0aGlzIHBhY2thZ2UgLT4gZnVsbHkgcXVhbGlmaWVkIG5hbWUgb2YgZGVwZW5kZW5jeQogICAgcHJpdmF0ZSBNYXA8U3RyaW5nLCBTZXQ8U3RyaW5nPj4gZGVwZW5kZW5jaWVzID0gbmV3IFRyZWVNYXA8PigpOwogICAgLy8gRnVsbHkgcXVhbGlmaWVkIG5hbWUgb2YgY2xhc3MgaW4gdGhpcyBwYWNrYWdlIC0+IGZ1bGx5IHF1YWxpZmllZCBuYW1lIG9mIGRlcGVuZGVuY3kgb24gY2xhc3MgcGF0aAogICAgcHJpdmF0ZSBNYXA8U3RyaW5nLCBTZXQ8U3RyaW5nPj4gY3BEZXBlbmRlbmNpZXMgPSBuZXcgVHJlZU1hcDw+KCk7CgogICAgLy8gVGhpcyBpcyB0aGUgcHVibGljIGFwaSBvZiB0aGlzIHBhY2thZ2UuCiAgICBwcml2YXRlIFB1YkFwaSBwdWJBcGkgPSBuZXcgUHViQXBpKCk7CiAgICAvLyBNYXAgZnJvbSBzb3VyY2UgZmlsZSBuYW1lIHRvIFNvdXJjZSBpbmZvIG9iamVjdC4KICAgIHByaXZhdGUgTWFwPFN0cmluZyxTb3VyY2U+IHNvdXJjZXMgPSBuZXcgSGFzaE1hcDw+KCk7CiAgICAvLyBUaGlzIHBhY2thZ2UgZ2VuZXJhdGVkIHRoZXNlIGFydGlmYWN0cy4KICAgIHByaXZhdGUgTWFwPFN0cmluZyxGaWxlPiBhcnRpZmFjdHMgPSBuZXcgSGFzaE1hcDw+KCk7CgogICAgcHVibGljIFBhY2thZ2UoTW9kdWxlIG0sIFN0cmluZyBuKSB7CiAgICAgICAgaW50IGMgPSBuLmluZGV4T2YoIjoiKTsKICAgICAgICBBc3NlcnQuY2hlY2soYyAhPSAtMSk7CiAgICAgICAgQXNzZXJ0LmNoZWNrKG0ubmFtZSgpLmVxdWFscyhtLm5hbWUoKSkpOwogICAgICAgIG5hbWUgPSBuOwogICAgICAgIGRpcm5hbWUgPSBuLnJlcGxhY2UoJy4nLCBGaWxlLnNlcGFyYXRvckNoYXIpOwogICAgICAgIGlmIChtLm5hbWUoKS5sZW5ndGgoKSA+IDApIHsKICAgICAgICAgICAgLy8gVGhlcmUgaXMgYSBtb2R1bGUgaGVyZSwgcHJlZml4IHRoZSBtb2R1bGUgZGlyIG5hbWUgdG8gdGhlIHBhdGguCiAgICAgICAgICAgIGRpcm5hbWUgPSBtLmRpcm5hbWUoKStGaWxlLnNlcGFyYXRvckNoYXIrZGlybmFtZTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIE1vZHVsZSBtb2QoKSB7IHJldHVybiBtb2Q7IH0KICAgIHB1YmxpYyBTdHJpbmcgbmFtZSgpIHsgcmV0dXJuIG5hbWU7IH0KICAgIHB1YmxpYyBTdHJpbmcgZGlybmFtZSgpIHsgcmV0dXJuIGRpcm5hbWU7IH0KICAgIHB1YmxpYyBNYXA8U3RyaW5nLFNvdXJjZT4gc291cmNlcygpIHsgcmV0dXJuIHNvdXJjZXM7IH0KICAgIHB1YmxpYyBNYXA8U3RyaW5nLEZpbGU+IGFydGlmYWN0cygpIHsgcmV0dXJuIGFydGlmYWN0czsgfQogICAgcHVibGljIFB1YkFwaSBnZXRQdWJBcGkoKSB7IHJldHVybiBwdWJBcGk7IH0KCiAgICBwdWJsaWMgTWFwPFN0cmluZyxTZXQ8U3RyaW5nPj4gdHlwZURlcGVuZGVuY2llcygpIHsgcmV0dXJuIGRlcGVuZGVuY2llczsgfQogICAgcHVibGljIE1hcDxTdHJpbmcsU2V0PFN0cmluZz4+IHR5cGVDbGFzc3BhdGhEZXBlbmRlbmNpZXMoKSB7IHJldHVybiBjcERlcGVuZGVuY2llczsgfQoKICAgIHB1YmxpYyBTZXQ8U3RyaW5nPiBkZXBlbmRlbnRzKCkgeyByZXR1cm4gZGVwZW5kZW50czsgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvKSB7CiAgICAgICAgcmV0dXJuIChvIGluc3RhbmNlb2YgUGFja2FnZSkgJiYgbmFtZS5lcXVhbHMoKChQYWNrYWdlKW8pLm5hbWUpOwogICAgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgICByZXR1cm4gbmFtZS5oYXNoQ29kZSgpOwogICAgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIGludCBjb21wYXJlVG8oUGFja2FnZSBvKSB7CiAgICAgICAgcmV0dXJuIG5hbWUuY29tcGFyZVRvKG8ubmFtZSk7CiAgICB9CgogICAgcHVibGljIHZvaWQgYWRkU291cmNlKFNvdXJjZSBzKSB7CiAgICAgICAgc291cmNlcy5wdXQocy5maWxlKCkuZ2V0UGF0aCgpLCBzKTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBQYXR0ZXJuIERFUF9QQVRURVJOID0gUGF0dGVybi5jb21waWxlKCIoLiopIC0+ICguKikiKTsKICAgIHB1YmxpYyB2b2lkIHBhcnNlQW5kQWRkRGVwZW5kZW5jeShTdHJpbmcgZCwgYm9vbGVhbiBjcCkgewogICAgICAgIE1hdGNoZXIgbSA9IERFUF9QQVRURVJOLm1hdGNoZXIoZCk7CiAgICAgICAgaWYgKCFtLm1hdGNoZXMoKSkKICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiQmFkIGRlcGVuZGVuY3kgc3RyaW5nOiAiICsgZCk7CiAgICAgICAgYWRkRGVwZW5kZW5jeShtLmdyb3VwKDEpLCBtLmdyb3VwKDIpLCBjcCk7CiAgICB9CgogICAgcHVibGljIHZvaWQgYWRkRGVwZW5kZW5jeShTdHJpbmcgZnVsbHlRdWFsaWZpZWRGcm9tLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgZnVsbHlRdWFsaWZpZWRUbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBjcCkgewogICAgICAgIE1hcDxTdHJpbmcsIFNldDxTdHJpbmc+PiBtYXAgPSBjcCA/IGNwRGVwZW5kZW5jaWVzIDogZGVwZW5kZW5jaWVzOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGZ1bGx5UXVhbGlmaWVkRnJvbSkpCiAgICAgICAgICAgIG1hcC5wdXQoZnVsbHlRdWFsaWZpZWRGcm9tLCBuZXcgSGFzaFNldDw+KCkpOwogICAgICAgIG1hcC5nZXQoZnVsbHlRdWFsaWZpZWRGcm9tKS5hZGQoZnVsbHlRdWFsaWZpZWRUbyk7CiAgICB9CgogICAgcHVibGljIHZvaWQgYWRkRGVwZW5kZW50KFN0cmluZyBkKSB7CiAgICAgICAgZGVwZW5kZW50cy5hZGQoZCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDaGVjayBpZiB3ZSBoYXZlIGtub3dsZWRnZSBpbiB0aGUgamF2YWMgc3RhdGUgdGhhdAogICAgICogZGVzY3JpYmUgdGhlIHJlc3VsdHMgb2YgY29tcGlsaW5nIHRoaXMgcGFja2FnZSBiZWZvcmUuCiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGV4aXN0c0luSmF2YWNTdGF0ZSgpIHsKICAgICAgICByZXR1cm4gYXJ0aWZhY3RzLnNpemUoKSA+IDAgfHwgIXB1YkFwaS5pc0VtcHR5KCk7CiAgICB9CgogICAgcHVibGljIGJvb2xlYW4gaGFzUHViQXBpQ2hhbmdlZChQdWJBcGkgbmV3UHViQXBpKSB7CiAgICAgICAgcmV0dXJuICFuZXdQdWJBcGkuaXNCYWNrd2FyZENvbXBhdGlibGVXaXRoKHB1YkFwaSk7CiAgICB9CgogICAgcHVibGljIHZvaWQgc2V0UHViYXBpKFB1YkFwaSBuZXdQdWJBcGkpIHsKICAgICAgICBwdWJBcGkgPSBuZXdQdWJBcGk7CiAgICB9CgogICAgcHVibGljIHZvaWQgc2V0RGVwZW5kZW5jaWVzKE1hcDxTdHJpbmcsIFNldDxTdHJpbmc+PiBkcywgYm9vbGVhbiBjcCkgewogICAgICAgIChjcCA/IGNwRGVwZW5kZW5jaWVzIDogZGVwZW5kZW5jaWVzKS5jbGVhcigpOwogICAgICAgIGZvciAoU3RyaW5nIGZ1bGx5UXVhbGlmaWVkRnJvbSA6IGRzLmtleVNldCgpKQogICAgICAgICAgICBmb3IgKFN0cmluZyBmdWxseVF1YWxpZmllZFRvIDogZHMuZ2V0KGZ1bGx5UXVhbGlmaWVkRnJvbSkpCiAgICAgICAgICAgICAgICBhZGREZXBlbmRlbmN5KGZ1bGx5UXVhbGlmaWVkRnJvbSwgZnVsbHlRdWFsaWZpZWRUbywgY3ApOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHNhdmUoU3RyaW5nQnVpbGRlciBiKSB7CiAgICAgICAgYi5hcHBlbmQoIlAgIikuYXBwZW5kKG5hbWUpLmFwcGVuZCgiXG4iKTsKICAgICAgICBTb3VyY2Uuc2F2ZVNvdXJjZXMoc291cmNlcywgYik7CiAgICAgICAgc2F2ZURlcGVuZGVuY2llcyhiKTsKICAgICAgICBzYXZlUHViYXBpKGIpOwogICAgICAgIHNhdmVBcnRpZmFjdHMoYik7CiAgICB9CgogICAgc3RhdGljIHB1YmxpYyBQYWNrYWdlIGxvYWQoTW9kdWxlIG1vZHVsZSwgU3RyaW5nIGwpIHsKICAgICAgICBTdHJpbmcgbmFtZSA9IGwuc3Vic3RyaW5nKDIpOwogICAgICAgIHJldHVybiBuZXcgUGFja2FnZShtb2R1bGUsIG5hbWUpOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHNhdmVEZXBlbmRlbmNpZXMoU3RyaW5nQnVpbGRlciBiKSB7CgogICAgICAgIC8vIERlcGVuZGVuY2llcyB3aGVyZSAqdG8qIGlzIGFtb25nIHNvdXJjZXMKICAgICAgICBmb3IgKFN0cmluZyBmdWxseVF1YWxpZmllZEZyb20gOiBkZXBlbmRlbmNpZXMua2V5U2V0KCkpIHsKICAgICAgICAgICAgZm9yIChTdHJpbmcgZnVsbHlRdWFsaWZpZWRUbyA6IGRlcGVuZGVuY2llcy5nZXQoZnVsbHlRdWFsaWZpZWRGcm9tKSkgewogICAgICAgICAgICAgICAgYi5hcHBlbmQoU3RyaW5nLmZvcm1hdCgiRCBTICVzIC0+ICVzJW4iLCBmdWxseVF1YWxpZmllZEZyb20sIGZ1bGx5UXVhbGlmaWVkVG8pKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gRGVwZW5kZW5jaWVzIHdoZXJlICp0byogaXMgb24gY2xhc3MgcGF0aAogICAgICAgIGZvciAoU3RyaW5nIGZ1bGx5UXVhbGlmaWVkRnJvbSA6IGNwRGVwZW5kZW5jaWVzLmtleVNldCgpKSB7CiAgICAgICAgICAgIGZvciAoU3RyaW5nIGZ1bGx5UXVhbGlmaWVkVG8gOiBjcERlcGVuZGVuY2llcy5nZXQoZnVsbHlRdWFsaWZpZWRGcm9tKSkgewogICAgICAgICAgICAgICAgYi5hcHBlbmQoU3RyaW5nLmZvcm1hdCgiRCBDICVzIC0+ICVzJW4iLCBmdWxseVF1YWxpZmllZEZyb20sIGZ1bGx5UXVhbGlmaWVkVG8pKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgdm9pZCBzYXZlUHViYXBpKFN0cmluZ0J1aWxkZXIgYikgewogICAgICAgIHB1YkFwaS5hc0xpc3RPZlN0cmluZ3MoKQogICAgICAgICAgICAgIC5zdHJlYW0oKQogICAgICAgICAgICAgIC5mbGF0TWFwKGwgLT4gU3RyZWFtLm9mKCJJICIsIGwsICJcbiIpKQogICAgICAgICAgICAgIC5mb3JFYWNoKGI6OmFwcGVuZCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyB2b2lkIHNhdmVQYWNrYWdlcyhNYXA8U3RyaW5nLFBhY2thZ2U+IHBhY2thZ2VzLCBTdHJpbmdCdWlsZGVyIGIpIHsKICAgICAgICBMaXN0PFN0cmluZz4gc29ydGVkX3BhY2thZ2VzID0gbmV3IEFycmF5TGlzdDw+KCk7CiAgICAgICAgZm9yIChTdHJpbmcga2V5IDogcGFja2FnZXMua2V5U2V0KCkgKSB7CiAgICAgICAgICAgIHNvcnRlZF9wYWNrYWdlcy5hZGQoa2V5KTsKICAgICAgICB9CiAgICAgICAgQ29sbGVjdGlvbnMuc29ydChzb3J0ZWRfcGFja2FnZXMpOwogICAgICAgIGZvciAoU3RyaW5nIHMgOiBzb3J0ZWRfcGFja2FnZXMpIHsKICAgICAgICAgICAgUGFja2FnZSBwID0gcGFja2FnZXMuZ2V0KHMpOwogICAgICAgICAgICBwLnNhdmUoYik7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyB2b2lkIGFkZEFydGlmYWN0KFN0cmluZyBhKSB7CiAgICAgICAgYXJ0aWZhY3RzLnB1dChhLCBuZXcgRmlsZShhKSk7CiAgICB9CgogICAgcHVibGljIHZvaWQgYWRkQXJ0aWZhY3QoRmlsZSBmKSB7CiAgICAgICAgYXJ0aWZhY3RzLnB1dChmLmdldFBhdGgoKSwgZik7CiAgICB9CgogICAgcHVibGljIHZvaWQgYWRkQXJ0aWZhY3RzKFNldDxVUkk+IGFzKSB7CiAgICAgICAgZm9yIChVUkkgdSA6IGFzKSB7CiAgICAgICAgICAgIGFkZEFydGlmYWN0KG5ldyBGaWxlKHUpKTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHZvaWQgc2V0QXJ0aWZhY3RzKFNldDxVUkk+IGFzKSB7CiAgICAgICAgQXNzZXJ0LmNoZWNrKCFhcnRpZmFjdHMuaXNFbXB0eSgpKTsKICAgICAgICBhcnRpZmFjdHMgPSBuZXcgSGFzaE1hcDw+KCk7CiAgICAgICAgYWRkQXJ0aWZhY3RzKGFzKTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCBsb2FkQXJ0aWZhY3QoU3RyaW5nIGwpIHsKICAgICAgICAvLyBGaW5kIG5leHQgc3BhY2UgYWZ0ZXIgIkEgIi4KICAgICAgICBpbnQgZHAgPSBsLmluZGV4T2YoJyAnLDIpOwogICAgICAgIFN0cmluZyBmbiA9IGwuc3Vic3RyaW5nKDIsZHApOwogICAgICAgIGxvbmcgbGFzdF9tb2RpZmllZCA9IExvbmcucGFyc2VMb25nKGwuc3Vic3RyaW5nKGRwKzEpKTsKICAgICAgICBGaWxlIGYgPSBuZXcgRmlsZShmbik7CiAgICAgICAgaWYgKGYuZXhpc3RzKCkgJiYgZi5sYXN0TW9kaWZpZWQoKSAhPSBsYXN0X21vZGlmaWVkKSB7CiAgICAgICAgICAgIC8vIEhtbSwgdGhlIGFydGlmYWN0IG9uIGRpc2sgZG9lcyBub3QgaGF2ZSB0aGUgc2FtZSBsYXN0IG1vZGlmaWVkCiAgICAgICAgICAgIC8vIHRpbWVzdGFtcCBhcyB0aGUgaW5mb3JtYXRpb24gZnJvbSB0aGUgYnVpbGQgZGF0YWJhc2UuCiAgICAgICAgICAgIC8vIFdlIG5vIGxvbmdlciB0cnVzdCB0aGUgYXJ0aWZhY3Qgb24gZGlzay4gRGVsZXRlIGl0LgogICAgICAgICAgICAvLyBUaGUgc21hcnQgamF2YWMgd3JhcHBlciB3aWxsIHRoZW4gcmVidWlsZCB0aGUgYXJ0aWZhY3QuCiAgICAgICAgICAgIExvZy5kZWJ1ZygiUmVtb3ZpbmcgIitmLmdldFBhdGgoKSsiIHNpbmNlIGl0cyB0aW1lc3RhbXAgZG9lcyBub3QgbWF0Y2ggamF2YWNfc3RhdGUuIik7CiAgICAgICAgICAgIGYuZGVsZXRlKCk7CiAgICAgICAgfQogICAgICAgIGFydGlmYWN0cy5wdXQoZi5nZXRQYXRoKCksIGYpOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHNhdmVBcnRpZmFjdHMoU3RyaW5nQnVpbGRlciBiKSB7CiAgICAgICAgTGlzdDxGaWxlPiBzb3J0ZWRfYXJ0aWZhY3RzID0gbmV3IEFycmF5TGlzdDw+KCk7CiAgICAgICAgZm9yIChGaWxlIGYgOiBhcnRpZmFjdHMudmFsdWVzKCkpIHsKICAgICAgICAgICAgc29ydGVkX2FydGlmYWN0cy5hZGQoZik7CiAgICAgICAgfQogICAgICAgIENvbGxlY3Rpb25zLnNvcnQoc29ydGVkX2FydGlmYWN0cyk7CiAgICAgICAgZm9yIChGaWxlIGYgOiBzb3J0ZWRfYXJ0aWZhY3RzKSB7CiAgICAgICAgICAgIC8vIFRoZSBsYXN0IG1vZGlmaWVkIGluZm9ybWF0aW9uIGlzIG9ubHkgdXNlZAogICAgICAgICAgICAvLyB0byBkZXRlY3QgdGFtcGVyaW5nIHdpdGggdGhlIG91dHB1dCBkaXIuCiAgICAgICAgICAgIC8vIElmIHRoZSBvdXRwdXRkaXIgaGFzIGJlZW4gbW9kaWZpZWQsIG5vdCBieSBqYXZhYywKICAgICAgICAgICAgLy8gdGhlbiBhIG1pc21hdGNoIHdpbGwgYmUgZGV0ZWN0ZWQgaW4gdGhlIGxhc3QgbW9kaWZpZWQKICAgICAgICAgICAgLy8gdGltZXN0YW1wcyBzdG9yZWQgaW4gdGhlIGJ1aWxkIGRhdGFiYXNlIGNvbXBhcmVkCiAgICAgICAgICAgIC8vIHRvIHRoZSB0aW1lc3RhbXBzIG9uIGRpc2sgYW5kIHRoZSBhcnRpZmFjdCB3aWxsIGJlIGRlbGV0ZWQuCgogICAgICAgICAgICBiLmFwcGVuZCgiQSAiK2YuZ2V0UGF0aCgpKyIgIitmLmxhc3RNb2RpZmllZCgpKyJcbiIpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEFsd2F5cyBjbGVhbiBvdXQgYSB0YWludGVkIHBhY2thZ2UgYmVmb3JlIGl0IGlzIHJlY29tcGlsZWQuCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIGRlbGV0ZUFydGlmYWN0cygpIHsKICAgICAgICBmb3IgKEZpbGUgYSA6IGFydGlmYWN0cy52YWx1ZXMoKSkgewogICAgICAgICAgICBhLmRlbGV0ZSgpOwogICAgICAgIH0KICAgIH0KfQpQSwMECgAACAAABjupSlZ383maIwAAmiMAACsAAABjb20vc3VuL3Rvb2xzL3NqYXZhYy9Db21waWxlUHJvcGVydGllcy5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDEyLCAyMDE2LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuc2phdmFjOwoKaW1wb3J0IGphdmEuaW8uQnVmZmVyZWRXcml0ZXI7CmltcG9ydCBqYXZhLmlvLkZpbGU7CmltcG9ydCBqYXZhLmlvLkZpbGVJbnB1dFN0cmVhbTsKaW1wb3J0IGphdmEuaW8uRmlsZU91dHB1dFN0cmVhbTsKaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CmltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbVdyaXRlcjsKaW1wb3J0IGphdmEuaW8uUHJpbnRTdHJlYW07CmltcG9ydCBqYXZhLmlvLldyaXRlcjsKaW1wb3J0IGphdmEubmV0LlVSSTsKaW1wb3J0IGphdmEudGV4dC5NZXNzYWdlRm9ybWF0OwppbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKaW1wb3J0IGphdmEudXRpbC5IYXNoU2V0OwppbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOwppbXBvcnQgamF2YS51dGlsLkxpc3Q7CmltcG9ydCBqYXZhLnV0aWwuTWFwOwppbXBvcnQgamF2YS51dGlsLlByb3BlcnRpZXM7CmltcG9ydCBqYXZhLnV0aWwuU2V0OwoKaW1wb3J0IGNvbS5zdW4udG9vbHMuc2phdmFjLmNvbXAuQ29tcGlsYXRpb25TZXJ2aWNlOwppbXBvcnQgY29tLnN1bi50b29scy5zamF2YWMub3B0aW9ucy5PcHRpb25zOwppbXBvcnQgY29tLnN1bi50b29scy5zamF2YWMucHViYXBpLlB1YkFwaTsKCi8qKgogKiBDb21waWxlIHByb3BlcnRpZXMgdHJhbnNmb3JtIGEgcHJvcGVydGllcyBmaWxlIGludG8gYSBKYXZhIHNvdXJjZSBmaWxlLgogKiBKYXZhIGhhcyBidWlsdCBpbiBzdXBwb3J0IGZvciByZWFkaW5nIHByb3BlcnRpZXMgZnJvbSBlaXRoZXIgYSB0ZXh0IGZpbGUKICogaW4gdGhlIHNvdXJjZSBvciBhIGNvbXBpbGVkIGphdmEgc291cmNlIGZpbGUuCiAqCiAqICA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiAgSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93biByaXNrLgogKiAgVGhpcyBjb2RlIGFuZCBpdHMgaW50ZXJuYWwgaW50ZXJmYWNlcyBhcmUgc3ViamVjdCB0byBjaGFuZ2Ugb3IKICogIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj4KICovCnB1YmxpYyBjbGFzcyBDb21waWxlUHJvcGVydGllcyBpbXBsZW1lbnRzIFRyYW5zZm9ybWVyIHsKICAgIC8vIEFueSBleHRyYSBpbmZvcm1hdGlvbiBwYXNzZWQgZnJvbSB0aGUgY29tbWFuZCBsaW5lLCBmb3IgZXhhbXBsZSBpZjoKICAgIC8vIC10ciAucHJvcHBwPWNvbS5zdW4udG9vbHMuamF2YWMuc21hcnQuQ29tcGlsZVByb3BlcnRpZXMsc3VuLnV0aWwucmVzb3VyY2VzLkxvY2FsZU5hbWVzQnVuZGxlCiAgICAvLyB0aGVuIGV4dHJhIHdpbGwgYmUgInN1bi51dGlsLnJlc291cmNlcy5Mb2NhbGVOYW1lc0J1bmRsZSIKICAgIFN0cmluZyBleHRyYTsKCiAgICBwdWJsaWMgdm9pZCBzZXRFeHRyYShTdHJpbmcgZSkgewogICAgICAgIGV4dHJhID0gZTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCBzZXRFeHRyYShPcHRpb25zIGEpIHsKICAgIH0KCiAgICBwdWJsaWMgYm9vbGVhbiB0cmFuc2Zvcm0oQ29tcGlsYXRpb25TZXJ2aWNlIGNvbXBpbGF0aW9uU2VydmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYXA8U3RyaW5nLFNldDxVUkk+PiBwa2dTcmNzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNldDxVUkk+ICAgICAgICAgICAgIHZpc2libGVTcmNzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1hcDxTdHJpbmcsU2V0PFN0cmluZz4+IG9sZFBhY2thZ2VEZXBlbmRlbnRzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVSSSBkZXN0Um9vdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYXA8U3RyaW5nLFNldDxVUkk+PiAgICBwYWNrYWdlQXJ0aWZhY3RzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1hcDxTdHJpbmcsTWFwPFN0cmluZywgU2V0PFN0cmluZz4+PiBwYWNrYWdlRGVwZW5kZW5jaWVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1hcDxTdHJpbmcsTWFwPFN0cmluZywgU2V0PFN0cmluZz4+PiBwYWNrYWdlQ3BEZXBlbmRlbmNpZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWFwPFN0cmluZywgUHViQXBpPiBwYWNrYWdlUHVibGljQXBpcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYXA8U3RyaW5nLCBQdWJBcGk+IGRlcGVuZGVuY3lQdWJsaWNBcGlzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBkZWJ1Z0xldmVsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gaW5jcmVtZW50YWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IG51bUNvcmVzKSB7CiAgICAgICAgYm9vbGVhbiByYyA9IHRydWU7CiAgICAgICAgZm9yIChTdHJpbmcgcGtnTmFtZSA6IHBrZ1NyY3Mua2V5U2V0KCkpIHsKICAgICAgICAgICAgU3RyaW5nIHBrZ05hbWVGID0gVXRpbC50b0ZpbGVTeXN0ZW1QYXRoKHBrZ05hbWUpOwogICAgICAgICAgICBmb3IgKFVSSSB1IDogcGtnU3Jjcy5nZXQocGtnTmFtZSkpIHsKICAgICAgICAgICAgICAgIEZpbGUgc3JjID0gbmV3IEZpbGUodSk7CiAgICAgICAgICAgICAgICBib29sZWFuIHIgPSBjb21waWxlKHBrZ05hbWUsIHBrZ05hbWVGLCBzcmMsIG5ldyBGaWxlKGRlc3RSb290KSwgZGVidWdMZXZlbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2FnZUFydGlmYWN0cyk7CiAgICAgICAgICAgICAgICBpZiAociA9PSBmYWxzZSkgewogICAgICAgICAgICAgICAgICAgIHJjID0gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJjOwogICAgfQoKICAgIGJvb2xlYW4gY29tcGlsZShTdHJpbmcgcGtnTmFtZSwgU3RyaW5nIHBrZ05hbWVGLCBGaWxlIHNyYywgRmlsZSBkZXN0Um9vdCwgaW50IGRlYnVnTGV2ZWwsCiAgICAgICAgICAgICAgICAgICAgTWFwPFN0cmluZyxTZXQ8VVJJPj4gcGFja2FnZUFydGlmYWN0cykKICAgIHsKICAgICAgICBTdHJpbmcgc3VwZXJDbGFzcyA9ICJqYXZhLnV0aWwuTGlzdFJlc291cmNlQnVuZGxlIjsKCiAgICAgICAgaWYgKGV4dHJhICE9IG51bGwpIHsKICAgICAgICAgICAgc3VwZXJDbGFzcyA9IGV4dHJhOwogICAgICAgIH0KICAgICAgICAvLyBMb2FkIHRoZSBwcm9wZXJ0aWVzIGZpbGUuCiAgICAgICAgUHJvcGVydGllcyBwID0gbmV3IFByb3BlcnRpZXMoKTsKICAgICAgICB0cnkgewogICAgICAgICAgICBwLmxvYWQobmV3IEZpbGVJbnB1dFN0cmVhbShzcmMpKTsKICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIExvZy5lcnJvcigiRXJyb3IgcmVhZGluZyBmaWxlICIrc3JjLmdldFBhdGgoKSk7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIC8vIENhbGN1bGF0ZSB0aGUgbmFtZSBvZiB0aGUgSmF2YSBzb3VyY2UgZmlsZSB0byBiZSBnZW5lcmF0ZWQuCiAgICAgICAgaW50IGRwID0gc3JjLmdldE5hbWUoKS5sYXN0SW5kZXhPZigiLiIpOwogICAgICAgIFN0cmluZyBjbGFzc25hbWUgPSBzcmMuZ2V0TmFtZSgpLnN1YnN0cmluZygwLGRwKTsKCiAgICAgICAgLy8gU29ydCB0aGUgcHJvcGVydGllcyBpbiBpbmNyZWFzaW5nIGtleSBvcmRlci4KICAgICAgICBMaXN0PFN0cmluZz4gc29ydGVkS2V5cyA9IG5ldyBBcnJheUxpc3Q8PigpOwogICAgICAgIGZvciAoT2JqZWN0IGtleSA6IHAua2V5U2V0KCkpIHsKICAgICAgICAgICAgc29ydGVkS2V5cy5hZGQoKFN0cmluZylrZXkpOwogICAgICAgIH0KICAgICAgICBDb2xsZWN0aW9ucy5zb3J0KHNvcnRlZEtleXMpOwogICAgICAgIEl0ZXJhdG9yPFN0cmluZz4ga2V5cyA9IHNvcnRlZEtleXMuaXRlcmF0b3IoKTsKCiAgICAgICAgLy8gQ29sbGVjdCB0aGUgcHJvcGVydGllcyBpbnRvIGEgc3RyaW5nIGJ1ZmZlci4KICAgICAgICBTdHJpbmdCdWlsZGVyIGRhdGEgPSBuZXcgU3RyaW5nQnVpbGRlcigpOwogICAgICAgIHdoaWxlIChrZXlzLmhhc05leHQoKSkgewogICAgICAgICAgICBTdHJpbmcga2V5ID0ga2V5cy5uZXh0KCk7CiAgICAgICAgICAgIGRhdGEuYXBwZW5kKCIgICAgICAgICAgICB7IFwiIiArIGVzY2FwZShrZXkpICsgIlwiLCBcIiIgKwogICAgICAgICAgICAgICAgICAgICAgICBlc2NhcGUoKFN0cmluZylwLmdldChrZXkpKSArICJcIiB9LFxuIik7CiAgICAgICAgfQoKICAgICAgICAvLyBDcmVhdGUgZGVzdCBmaWxlIG5hbWUuIEl0IGlzIGRlcml2ZWQgZnJvbSB0aGUgcHJvcGVydGllcyBmaWxlIG5hbWUuCiAgICAgICAgU3RyaW5nIGRlc3RGaWxlbmFtZSA9IGRlc3RSb290LmdldFBhdGgoKStGaWxlLnNlcGFyYXRvcitwa2dOYW1lRitGaWxlLnNlcGFyYXRvcitjbGFzc25hbWUrIi5qYXZhIjsKICAgICAgICBGaWxlIGRlc3QgPSBuZXcgRmlsZShkZXN0RmlsZW5hbWUpOwoKICAgICAgICAvLyBNYWtlIHN1cmUgdGhlIGRlc3QgZGlyZWN0b3JpZXMgZXhpc3QuCiAgICAgICAgaWYgKCFkZXN0LmdldFBhcmVudEZpbGUoKS5pc0RpcmVjdG9yeSgpKSB7CiAgICAgICAgICAgIGlmICghZGVzdC5nZXRQYXJlbnRGaWxlKCkubWtkaXJzKCkpIHsKICAgICAgICAgICAgICAgIExvZy5lcnJvcigiQ291bGQgbm90IGNyZWF0ZSB0aGUgZGlyZWN0b3J5ICIrZGVzdC5nZXRQYXJlbnRGaWxlKCkuZ2V0UGF0aCgpKTsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgU2V0PFVSST4gYXMgPSBwYWNrYWdlQXJ0aWZhY3RzLmdldChwa2dOYW1lKTsKICAgICAgICBpZiAoYXMgPT0gbnVsbCkgewogICAgICAgICAgICBhcyA9IG5ldyBIYXNoU2V0PD4oKTsKICAgICAgICAgICAgcGFja2FnZUFydGlmYWN0cy5wdXQocGtnTmFtZSwgYXMpOwogICAgICAgIH0KICAgICAgICBhcy5hZGQoZGVzdC50b1VSSSgpKTsKCiAgICAgICAgaWYgKGRlc3QuZXhpc3RzKCkgJiYgZGVzdC5sYXN0TW9kaWZpZWQoKSA+IHNyYy5sYXN0TW9kaWZpZWQoKSkgewogICAgICAgICAgICAvLyBBIGdlbmVyYXRlZCBmaWxlIGV4aXN0cywgYW5kIGl0cyB0aW1lc3RhbXAgaXMgbmV3ZXIgdGhhbiB0aGUgc291cmNlLgogICAgICAgICAgICAvLyBBc3N1bWUgdGhhdCB3ZSBkbyBub3QgbmVlZCB0byByZWdlbmVyYXRlIHRoZSBkZXN0IGZpbGUhCiAgICAgICAgICAgIC8vIFRodXMgd2UgYXJlIGRvbmUuCiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgU3RyaW5nIHBhY2thZ2VTdHJpbmcgPSAicGFja2FnZSAiICsgcGtnTmFtZUYucmVwbGFjZShGaWxlLnNlcGFyYXRvckNoYXIsJy4nKSArICI7XG5cbiI7CgogICAgICAgIExvZy5pbmZvKCJDb21waWxpbmcgcHJvcGVydHkgZmlsZSAiK3BrZ05hbWVGK0ZpbGUuc2VwYXJhdG9yK3NyYy5nZXROYW1lKCkpOwogICAgICAgIHRyeSAoV3JpdGVyIHdyaXRlciA9IG5ldyBCdWZmZXJlZFdyaXRlcihuZXcgT3V0cHV0U3RyZWFtV3JpdGVyKG5ldyBGaWxlT3V0cHV0U3RyZWFtKGRlc3QpKSkpIHsKICAgICAgICAgICAgTWVzc2FnZUZvcm1hdCBmb3JtYXQgPSBuZXcgTWVzc2FnZUZvcm1hdChGT1JNQVQpOwogICAgICAgICAgICB3cml0ZXIud3JpdGUoZm9ybWF0LmZvcm1hdChuZXcgT2JqZWN0W10geyBwYWNrYWdlU3RyaW5nLCBjbGFzc25hbWUsIHN1cGVyQ2xhc3MsIGRhdGEgfSkpOwogICAgICAgIH0gY2F0Y2ggKCBJT0V4Y2VwdGlvbiBlICkgewogICAgICAgICAgICBMb2cuZXJyb3IoIkNvdWxkIG5vdCB3cml0ZSBmaWxlICIrZGVzdC5nZXRQYXRoKCkpOwogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBGT1JNQVQgPQogICAgICAgICAgICAiezB9IiArCiAgICAgICAgICAgICJwdWJsaWMgZmluYWwgY2xhc3MgezF9IGV4dGVuZHMgezJ9ICd7J1xuIiArCiAgICAgICAgICAgICIgICAgcHJvdGVjdGVkIGZpbmFsIE9iamVjdFtdW10gZ2V0Q29udGVudHMoKSAneydcbiIgKwogICAgICAgICAgICAiICAgICAgICByZXR1cm4gbmV3IE9iamVjdFtdW10gJ3snXG4iICsKICAgICAgICAgICAgInszfSIgKwogICAgICAgICAgICAiICAgICAgICB9O1xuIiArCiAgICAgICAgICAgICIgICAgfVxuIiArCiAgICAgICAgICAgICJ9XG4iOwoKICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGVzY2FwZShTdHJpbmcgdGhlU3RyaW5nKSB7CiAgICAgICAgaW50IGxlbiA9IHRoZVN0cmluZy5sZW5ndGgoKTsKICAgICAgICBTdHJpbmdCdWlsZGVyIG91dEJ1ZmZlciA9IG5ldyBTdHJpbmdCdWlsZGVyKGxlbioyKTsKCiAgICAgICAgZm9yKGludCB4PTA7IHg8bGVuOyB4KyspIHsKICAgICAgICAgICAgY2hhciBhQ2hhciA9IHRoZVN0cmluZy5jaGFyQXQoeCk7CiAgICAgICAgICAgIHN3aXRjaChhQ2hhcikgewogICAgICAgICAgICAgICAgY2FzZSAnXFwnOm91dEJ1ZmZlci5hcHBlbmQoJ1xcJyk7IG91dEJ1ZmZlci5hcHBlbmQoJ1xcJyk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgJ1x0JzpvdXRCdWZmZXIuYXBwZW5kKCdcXCcpOyBvdXRCdWZmZXIuYXBwZW5kKCd0Jyk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgJ1xuJzpvdXRCdWZmZXIuYXBwZW5kKCdcXCcpOyBvdXRCdWZmZXIuYXBwZW5kKCduJyk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgJ1xyJzpvdXRCdWZmZXIuYXBwZW5kKCdcXCcpOyBvdXRCdWZmZXIuYXBwZW5kKCdyJyk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgJ1xmJzpvdXRCdWZmZXIuYXBwZW5kKCdcXCcpOyBvdXRCdWZmZXIuYXBwZW5kKCdmJyk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgaWYgKChhQ2hhciA8IDB4MDAyMCkgfHwgKGFDaGFyID4gMHgwMDdlKSkgewogICAgICAgICAgICAgICAgICAgICAgICBvdXRCdWZmZXIuYXBwZW5kKCdcXCcpOwogICAgICAgICAgICAgICAgICAgICAgICBvdXRCdWZmZXIuYXBwZW5kKCd1Jyk7CiAgICAgICAgICAgICAgICAgICAgICAgIG91dEJ1ZmZlci5hcHBlbmQodG9IZXgoKGFDaGFyID4+IDEyKSAmIDB4RikpOwogICAgICAgICAgICAgICAgICAgICAgICBvdXRCdWZmZXIuYXBwZW5kKHRvSGV4KChhQ2hhciA+PiAgOCkgJiAweEYpKTsKICAgICAgICAgICAgICAgICAgICAgICAgb3V0QnVmZmVyLmFwcGVuZCh0b0hleCgoYUNoYXIgPj4gIDQpICYgMHhGKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIG91dEJ1ZmZlci5hcHBlbmQodG9IZXgoIGFDaGFyICAgICAgICAmIDB4RikpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhQ2hhciA9PSAnIicpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG91dEJ1ZmZlci5hcHBlbmQoJ1xcJyk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgb3V0QnVmZmVyLmFwcGVuZChhQ2hhcik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBvdXRCdWZmZXIudG9TdHJpbmcoKTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBjaGFyIHRvSGV4KGludCBuaWJibGUpIHsKICAgICAgICByZXR1cm4gaGV4RGlnaXRbKG5pYmJsZSAmIDB4RildOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNoYXJbXSBoZXhEaWdpdCA9IHsKICAgICAgICAnMCcsJzEnLCcyJywnMycsJzQnLCc1JywnNicsJzcnLCc4JywnOScsJ0EnLCdCJywnQycsJ0QnLCdFJywnRicKICAgIH07Cn0KUEsDBAoAAAgAAAY7qUqd2bhUqZ8AAKmfAAAkAAAAY29tL3N1bi90b29scy9zamF2YWMvSmF2YWNTdGF0ZS5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDEyLCAyMDE2LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuc2phdmFjOwoKaW1wb3J0IGphdmEuaW8uQnVmZmVyZWRSZWFkZXI7CmltcG9ydCBqYXZhLmlvLkZpbGU7CmltcG9ydCBqYXZhLmlvLkZpbGVOb3RGb3VuZEV4Y2VwdGlvbjsKaW1wb3J0IGphdmEuaW8uRmlsZVJlYWRlcjsKaW1wb3J0IGphdmEuaW8uRmlsZVdyaXRlcjsKaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CmltcG9ydCBqYXZhLmlvLldyaXRlcjsKaW1wb3J0IGphdmEubmV0LlVSSTsKaW1wb3J0IGphdmEubmlvLmZpbGUuTm9TdWNoRmlsZUV4Y2VwdGlvbjsKaW1wb3J0IGphdmEudGV4dC5TaW1wbGVEYXRlRm9ybWF0OwppbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb247CmltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbnM7CmltcG9ydCBqYXZhLnV0aWwuRGF0ZTsKaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOwppbXBvcnQgamF2YS51dGlsLkhhc2hTZXQ7CmltcG9ydCBqYXZhLnV0aWwuTGlzdDsKaW1wb3J0IGphdmEudXRpbC5NYXA7CmltcG9ydCBqYXZhLnV0aWwuU2V0OwppbXBvcnQgamF2YS51dGlsLnN0cmVhbS5Db2xsZWN0b3JzOwoKaW1wb3J0IGNvbS5zdW4udG9vbHMuc2phdmFjLmNvbXAuQ29tcGlsYXRpb25TZXJ2aWNlOwppbXBvcnQgY29tLnN1bi50b29scy5zamF2YWMub3B0aW9ucy5PcHRpb25zOwppbXBvcnQgY29tLnN1bi50b29scy5zamF2YWMucHViYXBpLlB1YkFwaTsKCi8qKgogKiBUaGUgamF2YWMgc3RhdGUgY2xhc3MgbWFpbnRhaW5zIHRoZSBwcmV2aW91cyAocHJldikgYW5kIHRoZSBjdXJyZW50IChub3cpCiAqIGJ1aWxkIHN0YXRlcyBhbmQgZXZlcnl0aGluZyBlbHNlIHRoYXQgZ29lcyBpbnRvIHRoZSBqYXZhY19zdGF0ZSBmaWxlLgogKgogKiAgPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24gcmlzay4KICogIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yCiAqICBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+CiAqLwpwdWJsaWMgY2xhc3MgSmF2YWNTdGF0ZSB7CiAgICAvLyBUaGUgYXJndW1lbnRzIHRvIHRoZSBjb21waWxlLiBJZiBub3QgaWRlbnRpY2FsLCB0aGVuIGl0IGNhbm5vdAogICAgLy8gYmUgYW4gaW5jcmVtZW50YWwgYnVpbGQhCiAgICBTdHJpbmcgdGhlQXJnczsKICAgIC8vIFRoZSBudW1iZXIgb2YgY29yZXMgbGltaXRzIGhvdyBtYW55IHRocmVhZHMgYXJlIHVzZWQgZm9yIGhlYXZ5IGNvbmN1cnJlbnQgd29yay4KICAgIGludCBudW1Db3JlczsKCiAgICAvLyBUaGUgYmluX2Rpci9qYXZhY19zdGF0ZQogICAgcHJpdmF0ZSBGaWxlIGphdmFjU3RhdGU7CgogICAgLy8gVGhlIHByZXZpb3VzIGJ1aWxkIHN0YXRlIGlzIGxvYWRlZCBmcm9tIGphdmFjX3N0YXRlCiAgICBwcml2YXRlIEJ1aWxkU3RhdGUgcHJldjsKICAgIC8vIFRoZSBjdXJyZW50IGJ1aWxkIHN0YXRlIGlzIGNvbnN0cnVjdGVkIGR1cmluZyB0aGUgYnVpbGQsCiAgICAvLyB0aGVuIHNhdmVkIGFzIHRoZSBuZXcgamF2YWNfc3RhdGUuCiAgICBwcml2YXRlIEJ1aWxkU3RhdGUgbm93OwoKICAgIC8vIFNvbWV0aGluZyBoYXMgY2hhbmdlZCBpbiB0aGUgamF2YWNfc3RhdGUuIEl0IG5lZWRzIHRvIGJlIHNhdmVkIQogICAgcHJpdmF0ZSBib29sZWFuIG5lZWRzU2F2aW5nOwogICAgLy8gSWYgdGhpcyBpcyBhIG5ldyBqYXZhY19zdGF0ZSBmaWxlLCB0aGVuIGRvIG5vdCBwcmludCB1bm5lY2Vzc2FyeSBtZXNzYWdlcy4KICAgIHByaXZhdGUgYm9vbGVhbiBuZXdKYXZhY1N0YXRlOwoKICAgIC8vIFRoZXNlIGFyZSBwYWNrYWdlcyB3aGVyZSBzb21ldGhpbmcgaGFzIGNoYW5nZWQgYW5kIHRoZSBwYWNrYWdlCiAgICAvLyBuZWVkcyB0byBiZSByZWNvbXBpbGVkLiBBY3Rpb25zIHRoYXQgdHJpZ2dlciByZWNvbXBpbGF0aW9uOgogICAgLy8gKiBzb3VyY2UgYmVsb25naW5nIHRvIHRoZSBwYWNrYWdlIGhhcyBjaGFuZ2VkCiAgICAvLyAqIGFydGlmYWN0IGJlbG9uZ2luZyB0byB0aGUgcGFja2FnZSBpcyBsb3N0LCBvciBpdHMgdGltZXN0YW1wIGhhcyBiZWVuIGNoYW5nZWQuCiAgICAvLyAqIGFuIHVua25vd24gYXJ0aWZhY3QgaGFzIGFwcGVhcmVkLCB3ZSBzaW1wbHkgZGVsZXRlIGl0LCBidXQgd2UgYWxzbyB0cmlnZ2VyIGEgcmVjb21waWxhdGlvbi4KICAgIC8vICogYSBwYWNrYWdlIHRoYXQgaXMgdGFpbnRlZCwgdGFpbnRzIGFsbCBwYWNrYWdlcyB0aGF0IGRlcGVuZCBvbiBpdC4KICAgIHByaXZhdGUgU2V0PFN0cmluZz4gdGFpbnRlZFBhY2thZ2VzOwogICAgLy8gQWZ0ZXIgYSBjb21waWxlLCB0aGUgcHViYXBpcyBhcmUgY29tcGFyZWQgd2l0aCB0aGUgcHViYXBpcyBzdG9yZWQgaW4gdGhlIGphdmFjIHN0YXRlIGZpbGUuCiAgICAvLyBBbnkgcGFja2FnZXMgd2hlcmUgdGhlIHB1YmFwaSBkaWZmZXIgYXJlIGFkZGVkIHRvIHRoaXMgc2V0LgogICAgLy8gTGF0ZXIgd2UgdXNlIHRoaXMgc2V0IGFuZCB0aGUgZGVwZW5kZW5jeSBpbmZvcm1hdGlvbiB0byB0YWludCBkZXBlbmRlbnQgcGFja2FnZXMuCiAgICBwcml2YXRlIFNldDxTdHJpbmc+IHBhY2thZ2VzV2l0aENoYW5nZWRQdWJsaWNBcGlzOwogICAgLy8gV2hlbiBhIG1vZHVsZS1pbmZvLmphdmEgZmlsZSBpcyBjaGFuZ2VkLCB0YWludCB0aGUgbW9kdWxlLAogICAgLy8gdGhlbiB0YWludCBhbGwgbW9kdWxlcyB0aGF0IGRlcGVuZCBvbiB0aGF0IHRoYXQgbW9kdWxlLgogICAgLy8gQSBtb2R1bGUgZGVwZW5kZW5jeSBjYW4gb2NjdXIgZGlyZWN0bHkgdGhyb3VnaCBhIHJlcXVpcmUsIG9yCiAgICAvLyBpbmRpcmVjdGx5IHRocm91Z2ggYSBtb2R1bGUgdGhhdCBkb2VzIGEgcHVibGljIGV4cG9ydCBmb3IgdGhlIGZpcnN0IHRhaW50ZWQgbW9kdWxlLgogICAgLy8gV2hlbiBhbGwgbW9kdWxlcyBhcmUgdGFpbnRlZCwgdGhlbiB0YWludCBhbGwgcGFja2FnZXMgYmVsb25naW5nIHRvIHRoZXNlIG1vZHVsZXMuCiAgICAvLyBUaGVuIHJlYnVpbGQuIEl0IGlzIHBlcmhhcHMgcG9zc2libGUgKGFuZCB2YWx1YWJsZT8pIHRvIGRvIGEgbW9yZSBmaW5lZ3JhaW5lZCBleGFtaW5hdGlvbiBvZiB0aGUKICAgIC8vIGNoYW5nZSBpbiBtb2R1bGUtaW5mby5qYXZhLCBidXQgdGhhdCB3aWxsIGhhdmUgdG8gd2FpdC4KICAgIHByaXZhdGUgU2V0PFN0cmluZz4gdGFpbnRlZE1vZHVsZXM7CiAgICAvLyBUaGUgc2V0IG9mIGFsbCBwYWNrYWdlcyB0aGF0IGhhcyBiZWVuIHJlY29tcGlsZWQuCiAgICAvLyBDb3B5IG92ZXIgdGhlIGphdmFjX3N0YXRlIGZvciB0aGUgcGFja2FnZXMgdGhhdCBkaWQgbm90IG5lZWQgcmVjb21waWxhdGlvbiwKICAgIC8vIHZlcmJhdGltIGZyb20gdGhlIHByZXZpb3VzIChwcmV2KSB0byB0aGUgbmV3IChub3cpIGJ1aWxkIHN0YXRlLgogICAgcHJpdmF0ZSBTZXQ8U3RyaW5nPiByZWNvbXBpbGVkUGFja2FnZXM7CgogICAgLy8gVGhlIG91dHB1dCBkaXJlY3RvcmllcyBmaWxsZWQgd2l0aCB0YXN0eSBhcnRpZmFjdHMuCiAgICBwcml2YXRlIEZpbGUgYmluRGlyLCBnZW5zcmNEaXIsIGhlYWRlckRpciwgc3RhdGVEaXI7CgogICAgLy8gVGhlIGN1cnJlbnQgc3RhdHVzIG9mIHRoZSBmaWxlIHN5c3RlbS4KICAgIHByaXZhdGUgU2V0PEZpbGU+IGJpbkFydGlmYWN0czsKICAgIHByaXZhdGUgU2V0PEZpbGU+IGdlbnNyY0FydGlmYWN0czsKICAgIHByaXZhdGUgU2V0PEZpbGU+IGhlYWRlckFydGlmYWN0czsKCiAgICAvLyBUaGUgc3RhdHVzIG9mIHRoZSBzb3VyY2VzLgogICAgU2V0PFNvdXJjZT4gcmVtb3ZlZFNvdXJjZXMgPSBudWxsOwogICAgU2V0PFNvdXJjZT4gYWRkZWRTb3VyY2VzID0gbnVsbDsKICAgIFNldDxTb3VyY2U+IG1vZGlmaWVkU291cmNlcyA9IG51bGw7CgogICAgLy8gVmlzaWJsZSBzb3VyY2VzIGZvciBsaW5raW5nLiBUaGVzZSBhcmUgdGhlIG9ubHkKICAgIC8vIG9uZXMgdGhhdCAtc291cmNlcGF0aCBpcyBhbGxvd2VkIHRvIHNlZS4KICAgIFNldDxVUkk+IHZpc2libGVTcmNzOwoKICAgIC8vIFNldHVwIHRyYW5zZm9ybSB0aGF0IGFsd2F5cyBleGlzdC4KICAgIHByaXZhdGUgQ29tcGlsZUphdmFQYWNrYWdlcyBjb21waWxlSmF2YVBhY2thZ2VzID0gbmV3IENvbXBpbGVKYXZhUGFja2FnZXMoKTsKCiAgICAvLyBDb21tYW5kIGxpbmUgb3B0aW9ucy4KICAgIHByaXZhdGUgT3B0aW9ucyBvcHRpb25zOwoKICAgIEphdmFjU3RhdGUoT3B0aW9ucyBvcCwgYm9vbGVhbiByZW1vdmVKYXZhY1N0YXRlKSB7CiAgICAgICAgb3B0aW9ucyA9IG9wOwogICAgICAgIG51bUNvcmVzID0gb3B0aW9ucy5nZXROdW1Db3JlcygpOwogICAgICAgIHRoZUFyZ3MgPSBvcHRpb25zLmdldFN0YXRlQXJnc1N0cmluZygpOwogICAgICAgIGJpbkRpciA9IFV0aWwucGF0aFRvRmlsZShvcHRpb25zLmdldERlc3REaXIoKSk7CiAgICAgICAgZ2Vuc3JjRGlyID0gVXRpbC5wYXRoVG9GaWxlKG9wdGlvbnMuZ2V0R2VuU3JjRGlyKCkpOwogICAgICAgIGhlYWRlckRpciA9IFV0aWwucGF0aFRvRmlsZShvcHRpb25zLmdldEhlYWRlckRpcigpKTsKICAgICAgICBzdGF0ZURpciA9IFV0aWwucGF0aFRvRmlsZShvcHRpb25zLmdldFN0YXRlRGlyKCkpOwogICAgICAgIGphdmFjU3RhdGUgPSBuZXcgRmlsZShzdGF0ZURpciwgImphdmFjX3N0YXRlIik7CiAgICAgICAgaWYgKHJlbW92ZUphdmFjU3RhdGUgJiYgamF2YWNTdGF0ZS5leGlzdHMoKSkgewogICAgICAgICAgICBqYXZhY1N0YXRlLmRlbGV0ZSgpOwogICAgICAgIH0KICAgICAgICBuZXdKYXZhY1N0YXRlID0gZmFsc2U7CiAgICAgICAgaWYgKCFqYXZhY1N0YXRlLmV4aXN0cygpKSB7CiAgICAgICAgICAgIG5ld0phdmFjU3RhdGUgPSB0cnVlOwogICAgICAgICAgICAvLyBJZiB0aGVyZSBpcyBubyBqYXZhY19zdGF0ZSB0aGVuIGRlbGV0ZSB0aGUgY29udGVudHMgb2YgYWxsIHRoZSBhcnRpZmFjdCBkaXJzIQogICAgICAgICAgICAvLyBXZSBkbyBub3Qgd2FudCB0byByaXNrIGJ1aWxkaW5nIGEgYnJva2VuIGluY3JlbWVudGFsIGJ1aWxkLgogICAgICAgICAgICAvLyBCVVQgc2luY2UgdGhlIG1ha2VmaWxlcyBzdGlsbCBjb3B5IHRoaW5ncyBzdHJhaWdodCBpbnRvIHRoZSBiaW5fZGlyIGV0IGFsLAogICAgICAgICAgICAvLyB3ZSBhdm9pZCBkZWxldGluZyBmaWxlcyBoZXJlLCBpZiB0aGUgb3B0aW9uIC0tcGVybWl0LXVuaWRlbnRpZmllZC1jbGFzc2VzIHdhcyBzdXBwbGllZC4KICAgICAgICAgICAgaWYgKCFvcHRpb25zLmFyZVVuaWRlbnRpZmllZEFydGlmYWN0c1Blcm1pdHRlZCgpKSB7CiAgICAgICAgICAgICAgICBkZWxldGVDb250ZW50cyhiaW5EaXIpOwogICAgICAgICAgICAgICAgZGVsZXRlQ29udGVudHMoZ2Vuc3JjRGlyKTsKICAgICAgICAgICAgICAgIGRlbGV0ZUNvbnRlbnRzKGhlYWRlckRpcik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgbmVlZHNTYXZpbmcgPSB0cnVlOwogICAgICAgIH0KICAgICAgICBwcmV2ID0gbmV3IEJ1aWxkU3RhdGUoKTsKICAgICAgICBub3cgPSBuZXcgQnVpbGRTdGF0ZSgpOwogICAgICAgIHRhaW50ZWRQYWNrYWdlcyA9IG5ldyBIYXNoU2V0PD4oKTsKICAgICAgICByZWNvbXBpbGVkUGFja2FnZXMgPSBuZXcgSGFzaFNldDw+KCk7CiAgICAgICAgcGFja2FnZXNXaXRoQ2hhbmdlZFB1YmxpY0FwaXMgPSBuZXcgSGFzaFNldDw+KCk7CiAgICB9CgogICAgcHVibGljIEJ1aWxkU3RhdGUgcHJldigpIHsgcmV0dXJuIHByZXY7IH0KICAgIHB1YmxpYyBCdWlsZFN0YXRlIG5vdygpIHsgcmV0dXJuIG5vdzsgfQoKICAgIC8qKgogICAgICogUmVtb3ZlIGFyZ3Mgbm90IGFmZmVjdGluZyB0aGUgc3RhdGUuCiAgICAgKi8KICAgIHN0YXRpYyBTdHJpbmdbXSByZW1vdmVBcmdzTm90QWZmZWN0aW5nU3RhdGUoU3RyaW5nW10gYXJncykgewogICAgICAgIFN0cmluZ1tdIG91dCA9IG5ldyBTdHJpbmdbYXJncy5sZW5ndGhdOwogICAgICAgIGludCBqID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaTxhcmdzLmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgIGlmIChhcmdzW2ldLmVxdWFscygiLWoiKSkgewogICAgICAgICAgICAgICAgLy8gSnVzdCBza2lwIGl0IGFuZCBza2lwIGZvbGxvd2luZyB2YWx1ZQogICAgICAgICAgICAgICAgaSsrOwogICAgICAgICAgICB9IGVsc2UgaWYgKGFyZ3NbaV0uc3RhcnRzV2l0aCgiLS1zZXJ2ZXI6IikpIHsKICAgICAgICAgICAgICAgIC8vIEp1c3Qgc2tpcCBpdC4KICAgICAgICAgICAgfSBlbHNlIGlmIChhcmdzW2ldLnN0YXJ0c1dpdGgoIi0tbG9nPSIpKSB7CiAgICAgICAgICAgICAgICAvLyBKdXN0IHNraXAgaXQuCiAgICAgICAgICAgIH0gZWxzZSBpZiAoYXJnc1tpXS5lcXVhbHMoIi0tY29tcGFyZS1mb3VuZC1zb3VyY2VzIikpIHsKICAgICAgICAgICAgICAgIC8vIEp1c3Qgc2tpcCBpdCBhbmQgc2tpcCB2ZXJpZnkgZmlsZSBuYW1lCiAgICAgICAgICAgICAgICBpKys7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvLyBDb3B5IGFyZ3VtZW50LgogICAgICAgICAgICAgICAgb3V0W2pdID0gYXJnc1tpXTsKICAgICAgICAgICAgICAgIGorKzsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBTdHJpbmdbXSByZXQgPSBuZXcgU3RyaW5nW2pdOwogICAgICAgIFN5c3RlbS5hcnJheWNvcHkob3V0LCAwLCByZXQsIDAsIGopOwogICAgICAgIHJldHVybiByZXQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBTcGVjaWZ5IHdoaWNoIHNvdXJjZXMgYXJlIHZpc2libGUgdG8gdGhlIGNvbXBpbGVyIHRocm91Z2ggLXNvdXJjZXBhdGguCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHNldFZpc2libGVTb3VyY2VzKE1hcDxTdHJpbmcsU291cmNlPiB2cykgewogICAgICAgIHZpc2libGVTcmNzID0gbmV3IEhhc2hTZXQ8PigpOwogICAgICAgIGZvciAoU3RyaW5nIHMgOiB2cy5rZXlTZXQoKSkgewogICAgICAgICAgICBTb3VyY2Ugc3JjID0gdnMuZ2V0KHMpOwogICAgICAgICAgICB2aXNpYmxlU3Jjcy5hZGQoc3JjLmZpbGUoKS50b1VSSSgpKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhpcyBpcyBhbiBpbmNyZW1lbnRhbCBidWlsZC4KICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gaXNJbmNyZW1lbnRhbCgpIHsKICAgICAgICByZXR1cm4gIXByZXYuc291cmNlcygpLmlzRW1wdHkoKTsKICAgIH0KCiAgICAvKioKICAgICAqIEZpbmQgYWxsIGFydGlmYWN0cyB0aGF0IGV4aXN0cyBvbiBkaXNrLgogICAgICovCiAgICBwdWJsaWMgdm9pZCBmaW5kQWxsQXJ0aWZhY3RzKCkgewogICAgICAgIGJpbkFydGlmYWN0cyA9IGZpbmRBbGxGaWxlcyhiaW5EaXIpOwogICAgICAgIGdlbnNyY0FydGlmYWN0cyA9IGZpbmRBbGxGaWxlcyhnZW5zcmNEaXIpOwogICAgICAgIGhlYWRlckFydGlmYWN0cyA9IGZpbmRBbGxGaWxlcyhoZWFkZXJEaXIpOwogICAgfQoKICAgIC8qKgogICAgICogTG9va3VwIHRoZSBhcnRpZmFjdHMgZ2VuZXJhdGVkIGZvciB0aGlzIHBhY2thZ2UgaW4gdGhlIHByZXZpb3VzIGJ1aWxkLgogICAgICovCiAgICBwcml2YXRlIE1hcDxTdHJpbmcsRmlsZT4gZmV0Y2hQcmV2QXJ0aWZhY3RzKFN0cmluZyBwa2cpIHsKICAgICAgICBQYWNrYWdlIHAgPSBwcmV2LnBhY2thZ2VzKCkuZ2V0KHBrZyk7CiAgICAgICAgaWYgKHAgIT0gbnVsbCkgewogICAgICAgICAgICByZXR1cm4gcC5hcnRpZmFjdHMoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG5ldyBIYXNoTWFwPD4oKTsKICAgIH0KCiAgICAvKioKICAgICAqIERlbGV0ZSBhbGwgcHJldiBhcnRpZmFjdHMgaW4gdGhlIGN1cnJlbnRseSB0YWludGVkIHBhY2thZ2VzLgogICAgICovCiAgICBwdWJsaWMgdm9pZCBkZWxldGVDbGFzc0FydGlmYWN0c0luVGFpbnRlZFBhY2thZ2VzKCkgewogICAgICAgIGZvciAoU3RyaW5nIHBrZyA6IHRhaW50ZWRQYWNrYWdlcykgewogICAgICAgICAgICBNYXA8U3RyaW5nLEZpbGU+IGFydHMgPSBmZXRjaFByZXZBcnRpZmFjdHMocGtnKTsKICAgICAgICAgICAgZm9yIChGaWxlIGYgOiBhcnRzLnZhbHVlcygpKSB7CiAgICAgICAgICAgICAgICBpZiAoZi5leGlzdHMoKSAmJiBmLmdldE5hbWUoKS5lbmRzV2l0aCgiLmNsYXNzIikpIHsKICAgICAgICAgICAgICAgICAgICBmLmRlbGV0ZSgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogTWFyayB0aGUgamF2YWNfc3RhdGUgZmlsZSB0byBiZSBpbiBuZWVkIG9mIHNhdmluZyBhbmQgYXMgYSBzaWRlIGVmZmVjdCwKICAgICAqIGl0IGdldHMgYSBuZXcgdGltZXN0YW1wLgogICAgICovCiAgICBwcml2YXRlIHZvaWQgbmVlZHNTYXZpbmcoKSB7CiAgICAgICAgbmVlZHNTYXZpbmcgPSB0cnVlOwogICAgfQoKICAgIC8qKgogICAgICogU2F2ZSB0aGUgamF2YWNfc3RhdGUgZmlsZS4KICAgICAqLwogICAgcHVibGljIHZvaWQgc2F2ZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKCFuZWVkc1NhdmluZykKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIHRyeSAoRmlsZVdyaXRlciBvdXQgPSBuZXcgRmlsZVdyaXRlcihqYXZhY1N0YXRlKSkgewogICAgICAgICAgICBTdHJpbmdCdWlsZGVyIGIgPSBuZXcgU3RyaW5nQnVpbGRlcigpOwogICAgICAgICAgICBsb25nIG1pbGxpc05vdyA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOwogICAgICAgICAgICBEYXRlIGQgPSBuZXcgRGF0ZShtaWxsaXNOb3cpOwogICAgICAgICAgICBTaW1wbGVEYXRlRm9ybWF0IGRmID0gbmV3IFNpbXBsZURhdGVGb3JtYXQoInl5eXktTU0tZGQgSEg6bW06c3MgU1NTIik7CiAgICAgICAgICAgIGIuYXBwZW5kKCIjIGphdmFjX3N0YXRlIHZlciAwLjQgZ2VuZXJhdGVkICIrbWlsbGlzTm93KyIgIitkZi5mb3JtYXQoZCkrIlxuIik7CiAgICAgICAgICAgIGIuYXBwZW5kKCIjIFRoaXMgZm9ybWF0IG1pZ2h0IGNoYW5nZSBhdCBhbnkgdGltZS4gUGxlYXNlIGRvIG5vdCBkZXBlbmQgb24gaXQuXG4iKTsKICAgICAgICAgICAgYi5hcHBlbmQoIiMgUiBhcmd1bWVudHNcbiIpOwogICAgICAgICAgICBiLmFwcGVuZCgiIyBNIG1vZHVsZVxuIik7CiAgICAgICAgICAgIGIuYXBwZW5kKCIjIFAgcGFja2FnZVxuIik7CiAgICAgICAgICAgIGIuYXBwZW5kKCIjIFMgQyBzb3VyY2VfdG9iZV9jb21waWxlZCB0aW1lc3RhbXBcbiIpOwogICAgICAgICAgICBiLmFwcGVuZCgiIyBTIEwgbGlua19vbmx5X3NvdXJjZSB0aW1lc3RhbXBcbiIpOwogICAgICAgICAgICBiLmFwcGVuZCgiIyBHIEMgZ2VuZXJhdGVkX3NvdXJjZSB0aW1lc3RhbXBcbiIpOwogICAgICAgICAgICBiLmFwcGVuZCgiIyBBIGFydGlmYWN0IHRpbWVzdGFtcFxuIik7CiAgICAgICAgICAgIGIuYXBwZW5kKCIjIEQgUyBkZXBlbmRhbnQgLT4gc291cmNlIGRlcGVuZGVuY3lcbiIpOwogICAgICAgICAgICBiLmFwcGVuZCgiIyBEIEMgZGVwZW5kYW50IC0+IGNsYXNzcGF0aCBkZXBlbmRlbmN5XG4iKTsKICAgICAgICAgICAgYi5hcHBlbmQoIiMgSSBwdWJhcGlcbiIpOwogICAgICAgICAgICBiLmFwcGVuZCgiUiAiKS5hcHBlbmQodGhlQXJncykuYXBwZW5kKCJcbiIpOwoKICAgICAgICAgICAgLy8gQ29weSBvdmVyIHRoZSBqYXZhY19zdGF0ZSBmb3IgdGhlIHBhY2thZ2VzIHRoYXQgZGlkIG5vdCBuZWVkIHJlY29tcGlsYXRpb24uCiAgICAgICAgICAgIG5vdy5jb3B5UGFja2FnZXNFeGNlcHQocHJldiwgcmVjb21waWxlZFBhY2thZ2VzLCBuZXcgSGFzaFNldDxTdHJpbmc+KCkpOwogICAgICAgICAgICAvLyBTYXZlIHRoZSBwYWNrYWdlcywgaWUgcGFja2FnZSBuYW1lcywgZGVwZW5kZW5jaWVzLCBwdWJhcGlzIGFuZCBhcnRpZmFjdHMhCiAgICAgICAgICAgIC8vIEkuZS4gdGhlIGxvdC4KICAgICAgICAgICAgTW9kdWxlLnNhdmVNb2R1bGVzKG5vdy5tb2R1bGVzKCksIGIpOwoKICAgICAgICAgICAgU3RyaW5nIHMgPSBiLnRvU3RyaW5nKCk7CiAgICAgICAgICAgIG91dC53cml0ZShzLCAwLCBzLmxlbmd0aCgpKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBMb2FkIGEgamF2YWNfc3RhdGUgZmlsZS4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBKYXZhY1N0YXRlIGxvYWQoT3B0aW9ucyBvcHRpb25zKSB7CiAgICAgICAgSmF2YWNTdGF0ZSBkYiA9IG5ldyBKYXZhY1N0YXRlKG9wdGlvbnMsIGZhbHNlKTsKICAgICAgICBNb2R1bGUgIGxhc3RNb2R1bGUgPSBudWxsOwogICAgICAgIFBhY2thZ2UgbGFzdFBhY2thZ2UgPSBudWxsOwogICAgICAgIFNvdXJjZSAgbGFzdFNvdXJjZSA9IG51bGw7CiAgICAgICAgYm9vbGVhbiBub0ZpbGVGb3VuZCA9IGZhbHNlOwogICAgICAgIGJvb2xlYW4gZm91bmRDb3JyZWN0VmVyTnIgPSBmYWxzZTsKICAgICAgICBib29sZWFuIG5ld0NvbW1hbmRMaW5lID0gZmFsc2U7CiAgICAgICAgYm9vbGVhbiBzeW50YXhFcnJvciA9IGZhbHNlOwoKICAgICAgICBMb2cuZGVidWcoIkxvYWRpbmcgamF2YWMgc3RhdGUgZmlsZTogIiArIGRiLmphdmFjU3RhdGUpOwoKICAgICAgICB0cnkgKEJ1ZmZlcmVkUmVhZGVyIGluID0gbmV3IEJ1ZmZlcmVkUmVhZGVyKG5ldyBGaWxlUmVhZGVyKGRiLmphdmFjU3RhdGUpKSkgewogICAgICAgICAgICBmb3IgKDs7KSB7CiAgICAgICAgICAgICAgICBTdHJpbmcgbCA9IGluLnJlYWRMaW5lKCk7CiAgICAgICAgICAgICAgICBpZiAobD09bnVsbCkgYnJlYWs7CiAgICAgICAgICAgICAgICBpZiAobC5sZW5ndGgoKT49MyAmJiBsLmNoYXJBdCgxKSA9PSAnICcpIHsKICAgICAgICAgICAgICAgICAgICBjaGFyIGMgPSBsLmNoYXJBdCgwKTsKICAgICAgICAgICAgICAgICAgICBpZiAoYyA9PSAnTScpIHsKICAgICAgICAgICAgICAgICAgICAgICAgbGFzdE1vZHVsZSA9IGRiLnByZXYubG9hZE1vZHVsZShsKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UKICAgICAgICAgICAgICAgICAgICBpZiAoYyA9PSAnUCcpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGxhc3RNb2R1bGUgPT0gbnVsbCkgeyBzeW50YXhFcnJvciA9IHRydWU7IGJyZWFrOyB9CiAgICAgICAgICAgICAgICAgICAgICAgIGxhc3RQYWNrYWdlID0gZGIucHJldi5sb2FkUGFja2FnZShsYXN0TW9kdWxlLCBsKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UKICAgICAgICAgICAgICAgICAgICBpZiAoYyA9PSAnRCcpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGxhc3RNb2R1bGUgPT0gbnVsbCB8fCBsYXN0UGFja2FnZSA9PSBudWxsKSB7IHN5bnRheEVycm9yID0gdHJ1ZTsgYnJlYWs7IH0KICAgICAgICAgICAgICAgICAgICAgICAgY2hhciBkZXBUeXBlID0gbC5jaGFyQXQoMik7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkZXBUeXBlICE9ICdTJyAmJiBkZXBUeXBlICE9ICdDJykKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJCYWQgZGVwZW5kZW5jeSBzdHJpbmc6ICIgKyBsKTsKICAgICAgICAgICAgICAgICAgICAgICAgbGFzdFBhY2thZ2UucGFyc2VBbmRBZGREZXBlbmRlbmN5KGwuc3Vic3RyaW5nKDQpLCBkZXBUeXBlID09ICdDJyk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlCiAgICAgICAgICAgICAgICAgICAgaWYgKGMgPT0gJ0knKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChsYXN0TW9kdWxlID09IG51bGwgfHwgbGFzdFBhY2thZ2UgPT0gbnVsbCkgeyBzeW50YXhFcnJvciA9IHRydWU7IGJyZWFrOyB9CiAgICAgICAgICAgICAgICAgICAgICAgIGxhc3RQYWNrYWdlLmdldFB1YkFwaSgpLmFwcGVuZEl0ZW0obC5zdWJzdHJpbmcoMikpOyAvLyBTdHJpcCAiSSAiCiAgICAgICAgICAgICAgICAgICAgfSBlbHNlCiAgICAgICAgICAgICAgICAgICAgaWYgKGMgPT0gJ0EnKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChsYXN0TW9kdWxlID09IG51bGwgfHwgbGFzdFBhY2thZ2UgPT0gbnVsbCkgeyBzeW50YXhFcnJvciA9IHRydWU7IGJyZWFrOyB9CiAgICAgICAgICAgICAgICAgICAgICAgIGxhc3RQYWNrYWdlLmxvYWRBcnRpZmFjdChsKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UKICAgICAgICAgICAgICAgICAgICBpZiAoYyA9PSAnUycpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGxhc3RNb2R1bGUgPT0gbnVsbCB8fCBsYXN0UGFja2FnZSA9PSBudWxsKSB7IHN5bnRheEVycm9yID0gdHJ1ZTsgYnJlYWs7IH0KICAgICAgICAgICAgICAgICAgICAgICAgbGFzdFNvdXJjZSA9IGRiLnByZXYubG9hZFNvdXJjZShsYXN0UGFja2FnZSwgbCwgZmFsc2UpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZQogICAgICAgICAgICAgICAgICAgIGlmIChjID09ICdHJykgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAobGFzdE1vZHVsZSA9PSBudWxsIHx8IGxhc3RQYWNrYWdlID09IG51bGwpIHsgc3ludGF4RXJyb3IgPSB0cnVlOyBicmVhazsgfQogICAgICAgICAgICAgICAgICAgICAgICBsYXN0U291cmNlID0gZGIucHJldi5sb2FkU291cmNlKGxhc3RQYWNrYWdlLCBsLCB0cnVlKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UKICAgICAgICAgICAgICAgICAgICBpZiAoYyA9PSAnUicpIHsKICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG5jbWRsID0gIlIgIitkYi50aGVBcmdzOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWwuZXF1YWxzKG5jbWRsKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3Q29tbWFuZExpbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYyA9PSAnIycpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGwuc3RhcnRzV2l0aCgiIyBqYXZhY19zdGF0ZSB2ZXIgIikpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBzcCA9IGwuaW5kZXhPZigiICIsIDE4KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzcCAhPSAtMSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyB2ZXIgPSBsLnN1YnN0cmluZygxOCxzcCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCF2ZXIuZXF1YWxzKCIwLjQiKSkgewogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBmb3VuZENvcnJlY3RWZXJOciA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9IGNhdGNoIChGaWxlTm90Rm91bmRFeGNlcHRpb24gfCBOb1N1Y2hGaWxlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgLy8gU2lsZW50bHkgY3JlYXRlIGEgbmV3IGphdmFjX3N0YXRlIGZpbGUuCiAgICAgICAgICAgIG5vRmlsZUZvdW5kID0gdHJ1ZTsKICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIExvZy53YXJuKCJEcm9wcGluZyBvbGQgamF2YWNfc3RhdGUgYmVjYXVzZSBvZiBlcnJvcnMgd2hlbiByZWFkaW5nIGl0LiIpOwogICAgICAgICAgICBkYiA9IG5ldyBKYXZhY1N0YXRlKG9wdGlvbnMsIHRydWUpOwogICAgICAgICAgICBmb3VuZENvcnJlY3RWZXJOciA9IHRydWU7CiAgICAgICAgICAgIG5ld0NvbW1hbmRMaW5lID0gZmFsc2U7CiAgICAgICAgICAgIHN5bnRheEVycm9yID0gZmFsc2U7CiAgICB9CiAgICAgICAgaWYgKGZvdW5kQ29ycmVjdFZlck5yID09IGZhbHNlICYmICFub0ZpbGVGb3VuZCkgewogICAgICAgICAgICBMb2cuZGVidWcoIkRyb3BwaW5nIG9sZCBqYXZhY19zdGF0ZSBzaW5jZSBpdCBpcyBvZiBhbiBvbGQgdmVyc2lvbi4iKTsKICAgICAgICAgICAgZGIgPSBuZXcgSmF2YWNTdGF0ZShvcHRpb25zLCB0cnVlKTsKICAgICAgICB9IGVsc2UKICAgICAgICBpZiAobmV3Q29tbWFuZExpbmUgPT0gdHJ1ZSAmJiAhbm9GaWxlRm91bmQpIHsKICAgICAgICAgICAgTG9nLmRlYnVnKCJEcm9wcGluZyBvbGQgamF2YWNfc3RhdGUgc2luY2UgYSBuZXcgY29tbWFuZCBsaW5lIGlzIHVzZWQhIik7CiAgICAgICAgICAgIGRiID0gbmV3IEphdmFjU3RhdGUob3B0aW9ucywgdHJ1ZSk7CiAgICAgICAgfSBlbHNlCiAgICAgICAgaWYgKHN5bnRheEVycm9yID09IHRydWUpIHsKICAgICAgICAgICAgTG9nLndhcm4oIkRyb3BwaW5nIG9sZCBqYXZhY19zdGF0ZSBzaW5jZSBpdCBjb250YWlucyBzeW50YXggZXJyb3JzLiIpOwogICAgICAgICAgICBkYiA9IG5ldyBKYXZhY1N0YXRlKG9wdGlvbnMsIHRydWUpOwogICAgICAgIH0KICAgICAgICBkYi5wcmV2LmNhbGN1bGF0ZURlcGVuZGVudHMoKTsKICAgICAgICByZXR1cm4gZGI7CiAgICB9CgogICAgLyoqCiAgICAgKiBNYXJrIGEgamF2YSBwYWNrYWdlIGFzIHRhaW50ZWQsIGllIGl0IG5lZWRzIHJlY29tcGlsYXRpb24uCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHRhaW50UGFja2FnZShTdHJpbmcgbmFtZSwgU3RyaW5nIGJlY2F1c2UpIHsKICAgICAgICBpZiAoIXRhaW50ZWRQYWNrYWdlcy5jb250YWlucyhuYW1lKSkgewogICAgICAgICAgICBpZiAoYmVjYXVzZSAhPSBudWxsKSBMb2cuZGVidWcoIlRhaW50aW5nICIrVXRpbC5qdXN0UGFja2FnZU5hbWUobmFtZSkrIiBiZWNhdXNlICIrYmVjYXVzZSk7CiAgICAgICAgICAgIC8vIEl0IGhhcyBub3QgYmVlbiB0YWludGVkIGJlZm9yZS4KICAgICAgICAgICAgdGFpbnRlZFBhY2thZ2VzLmFkZChuYW1lKTsKICAgICAgICAgICAgbmVlZHNTYXZpbmcoKTsKICAgICAgICAgICAgUGFja2FnZSBub3dwID0gbm93LnBhY2thZ2VzKCkuZ2V0KG5hbWUpOwogICAgICAgICAgICBpZiAobm93cCAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICBmb3IgKFN0cmluZyBkIDogbm93cC5kZXBlbmRlbnRzKCkpIHsKICAgICAgICAgICAgICAgICAgICB0YWludFBhY2thZ2UoZCwgYmVjYXVzZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBUaGlzIHBhY2thZ2VzIG5lZWQgcmVjb21waWxhdGlvbi4KICAgICAqLwogICAgcHVibGljIFNldDxTdHJpbmc+IHRhaW50ZWRQYWNrYWdlcygpIHsKICAgICAgICByZXR1cm4gdGFpbnRlZFBhY2thZ2VzOwogICAgfQoKICAgIC8qKgogICAgICogQ2xlYW4gb3V0IHRoZSB0YWludGVkIHBhY2thZ2Ugc2V0LCB1c2VkIGFmdGVyIHRoZSBmaXJzdCByb3VuZCBvZiBjb21waWxlcywKICAgICAqIHByaW9yIHRvIHByb3BhZ2F0aW5nIGRlcGVuZGVuY2llcy4KICAgICAqLwogICAgcHVibGljIHZvaWQgY2xlYXJUYWludGVkUGFja2FnZXMoKSB7CiAgICAgICAgdGFpbnRlZFBhY2thZ2VzID0gbmV3IEhhc2hTZXQ8PigpOwogICAgfQoKICAgIC8qKgogICAgICogR28gdGhyb3VnaCBhbGwgc291cmNlcyBhbmQgY2hlY2sgd2hpY2ggaGF2ZSBiZWVuIHJlbW92ZWQsIGFkZGVkIG9yIG1vZGlmaWVkCiAgICAgKiBhbmQgdGFpbnQgdGhlIGNvcnJlc3BvbmRpbmcgcGFja2FnZXMuCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIGNoZWNrU291cmNlU3RhdHVzKGJvb2xlYW4gY2hlY2tfZ2Vuc3JjKSB7CiAgICAgICAgcmVtb3ZlZFNvdXJjZXMgPSBjYWxjdWxhdGVSZW1vdmVkU291cmNlcygpOwogICAgICAgIGZvciAoU291cmNlIHMgOiByZW1vdmVkU291cmNlcykgewogICAgICAgICAgICBpZiAoIXMuaXNHZW5lcmF0ZWQoKSB8fCBjaGVja19nZW5zcmMpIHsKICAgICAgICAgICAgICAgIHRhaW50UGFja2FnZShzLnBrZygpLm5hbWUoKSwgInNvdXJjZSAiK3MubmFtZSgpKyIgd2FzIHJlbW92ZWQiKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgYWRkZWRTb3VyY2VzID0gY2FsY3VsYXRlQWRkZWRTb3VyY2VzKCk7CiAgICAgICAgZm9yIChTb3VyY2UgcyA6IGFkZGVkU291cmNlcykgewogICAgICAgICAgICBTdHJpbmcgbXNnID0gbnVsbDsKICAgICAgICAgICAgaWYgKGlzSW5jcmVtZW50YWwoKSkgewogICAgICAgICAgICAgICAgLy8gV2hlbiBidWlsZGluZyBmcm9tIHNjcmF0Y2gsIHRoZXJlIGlzIG5vIHBvaW50CiAgICAgICAgICAgICAgICAvLyBwcmludGluZyAid2FzIGFkZGVkIiBmb3IgZXZlcnkgZmlsZSBzaW5jZSBhbGwgZmlsZXMgYXJlIGFkZGVkLgogICAgICAgICAgICAgICAgLy8gSG93ZXZlciBmb3IgYW4gaW5jcmVtZW50YWwgYnVpbGQgaXQgbWFrZXMgc2Vuc2UuCiAgICAgICAgICAgICAgICBtc2cgPSAic291cmNlICIrcy5uYW1lKCkrIiB3YXMgYWRkZWQiOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICghcy5pc0dlbmVyYXRlZCgpIHx8IGNoZWNrX2dlbnNyYykgewogICAgICAgICAgICAgICAgdGFpbnRQYWNrYWdlKHMucGtnKCkubmFtZSgpLCBtc2cpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBtb2RpZmllZFNvdXJjZXMgPSBjYWxjdWxhdGVNb2RpZmllZFNvdXJjZXMoKTsKICAgICAgICBmb3IgKFNvdXJjZSBzIDogbW9kaWZpZWRTb3VyY2VzKSB7CiAgICAgICAgICAgIGlmICghcy5pc0dlbmVyYXRlZCgpIHx8IGNoZWNrX2dlbnNyYykgewogICAgICAgICAgICAgICAgdGFpbnRQYWNrYWdlKHMucGtnKCkubmFtZSgpLCAic291cmNlICIrcy5uYW1lKCkrIiB3YXMgbW9kaWZpZWQiKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEFjcXVpcmUgdGhlIGNvbXBpbGVfamF2YV9wYWNrYWdlcyBzdWZmaXggcnVsZSBmb3IgLmphdmEgZmlsZXMuCiAgICAgKi8KICAgIHB1YmxpYyBNYXA8U3RyaW5nLFRyYW5zZm9ybWVyPiBnZXRKYXZhU3VmZml4UnVsZSgpIHsKICAgICAgICBNYXA8U3RyaW5nLFRyYW5zZm9ybWVyPiBzciA9IG5ldyBIYXNoTWFwPD4oKTsKICAgICAgICBzci5wdXQoIi5qYXZhIiwgY29tcGlsZUphdmFQYWNrYWdlcyk7CiAgICAgICAgcmV0dXJuIHNyOwogICAgfQoKCiAgICAvKioKICAgICAqIElmIGFydGlmYWN0cyBoYXZlIGdvbmUgbWlzc2luZywgZm9yY2UgYSByZWNvbXBpbGUgb2YgdGhlIHBhY2thZ2VzCiAgICAgKiB0aGV5IGJlbG9uZyB0by4KICAgICAqLwogICAgcHVibGljIHZvaWQgdGFpbnRQYWNrYWdlc1RoYXRNaXNzQXJ0aWZhY3RzKCkgewogICAgICAgIGZvciAoUGFja2FnZSBwa2cgOiBwcmV2LnBhY2thZ2VzKCkudmFsdWVzKCkpIHsKICAgICAgICAgICAgZm9yIChGaWxlIGYgOiBwa2cuYXJ0aWZhY3RzKCkudmFsdWVzKCkpIHsKICAgICAgICAgICAgICAgIGlmICghZi5leGlzdHMoKSkgewogICAgICAgICAgICAgICAgICAgIC8vIEhtbSwgdGhlIGFydGlmYWN0IG9uIGRpc2sgZG9lcyBub3QgZXhpc3QhIFNvbWVvbmUgaGFzIHJlbW92ZWQgaXQuLi4uCiAgICAgICAgICAgICAgICAgICAgLy8gTGV0cyByZWJ1aWxkIHRoZSBwYWNrYWdlLgogICAgICAgICAgICAgICAgICAgIHRhaW50UGFja2FnZShwa2cubmFtZSgpLCAiIitmKyIgaXMgbWlzc2luZy4iKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFByb3BhZ2F0ZSByZWNvbXBpbGF0aW9uIHRocm91Z2ggdGhlIGRlcGVuZGVuY3kgY2hhaW5zLgogICAgICogQXZvaWQgcmUtdGFpbnRpbmcgcGFja2FnZXMgdGhhdCBoYXZlIGFscmVhZHkgYmVlbiBjb21waWxlZC4KICAgICAqLwogICAgcHVibGljIHZvaWQgdGFpbnRQYWNrYWdlc0RlcGVuZGluZ09uQ2hhbmdlZFBhY2thZ2VzKFNldDxTdHJpbmc+IHBrZ3NXaXRoQ2hhbmdlZFB1YkFwaSwgU2V0PFN0cmluZz4gcmVjZW50bHlDb21waWxlZCkgewogICAgICAgIC8vIEZvciBlYWNoIHRvLWJlLXJlY29tcGlsZWQtY2FuZGlkYXRlcy4uLgogICAgICAgIGZvciAoUGFja2FnZSBwa2cgOiBuZXcgSGFzaFNldDw+KHByZXYucGFja2FnZXMoKS52YWx1ZXMoKSkpIHsKICAgICAgICAgICAgLy8gRmluZCBvdXQgd2hhdCBpdCBkZXBlbmRzIHVwb24uLi4KICAgICAgICAgICAgU2V0PFN0cmluZz4gZGVwcyA9IHBrZy50eXBlRGVwZW5kZW5jaWVzKCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC52YWx1ZXMoKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnN0cmVhbSgpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZmxhdE1hcChDb2xsZWN0aW9uOjpzdHJlYW0pCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY29sbGVjdChDb2xsZWN0b3JzLnRvU2V0KCkpOwogICAgICAgICAgICBmb3IgKFN0cmluZyBkZXAgOiBkZXBzKSB7CiAgICAgICAgICAgICAgICBTdHJpbmcgZGVwUGtnID0gIjoiICsgZGVwLnN1YnN0cmluZygwLCBkZXAubGFzdEluZGV4T2YoJy4nKSk7CiAgICAgICAgICAgICAgICBpZiAoZGVwUGtnLmVxdWFscyhwa2cubmFtZSgpKSkKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIC8vIENoZWNraW5nIGlmIHRoYXQgZGVwZW5kZW5jeSBoYXMgY2hhbmdlZAogICAgICAgICAgICAgICAgaWYgKHBrZ3NXaXRoQ2hhbmdlZFB1YkFwaS5jb250YWlucyhkZXBQa2cpICYmICFyZWNlbnRseUNvbXBpbGVkLmNvbnRhaW5zKHBrZy5uYW1lKCkpKSB7CiAgICAgICAgICAgICAgICAgICAgdGFpbnRQYWNrYWdlKHBrZy5uYW1lKCksICJpdHMgZGVwZW5kaW5nIG9uICIgKyBkZXBQa2cpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQ29tcGFyZSB0aGUgamF2YWNfc3RhdGUgcmVjb3JkZWQgcHVibGljIGFwaXMgb2YgcGFja2FnZXMgb24gdGhlIGNsYXNzcGF0aAogICAgICogd2l0aCB0aGUgYWN0dWFsIHB1YmxpYyBhcGlzIG9uIHRoZSBjbGFzc3BhdGguCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHRhaW50UGFja2FnZXNEZXBlbmRpbmdPbkNoYW5nZWRDbGFzc3BhdGhQYWNrYWdlcygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CgogICAgICAgIC8vIDEuIENvbGxlY3QgZnVsbHkgcXVhbGlmaWVkIG5hbWVzIG9mIGFsbCBpbnRlcmVzdGluZyBjbGFzc3BhdGggZGVwZW5kZW5jaWVzCiAgICAgICAgU2V0PFN0cmluZz4gZnFEZXBlbmRlbmNpZXMgPSBuZXcgSGFzaFNldDw+KCk7CiAgICAgICAgZm9yIChQYWNrYWdlIHBrZyA6IHByZXYucGFja2FnZXMoKS52YWx1ZXMoKSkgewogICAgICAgICAgICAvLyBDaGVjayBpZiB0aGlzIHBhY2thZ2Ugd2FzIGNvbXBpbGVkLiBJZiBpdCdzIHByZXNlbmNlIGlzIHJlY29yZGVkCiAgICAgICAgICAgIC8vIGJlY2F1c2UgaXQgd2FzIG9uIHRoZSBjbGFzcyBwYXRoIGFuZCB3ZSBuZWVkZWQgdG8gc2F2ZSBpdCdzCiAgICAgICAgICAgIC8vIHB1YmxpYyBhcGksIGl0J3Mgbm90IGEgY2FuZGlkYXRlIGZvciB0YWludGluZy4KICAgICAgICAgICAgaWYgKHBrZy5zb3VyY2VzKCkuaXNFbXB0eSgpKQogICAgICAgICAgICAgICAgY29udGludWU7CgogICAgICAgICAgICBwa2cudHlwZUNsYXNzcGF0aERlcGVuZGVuY2llcygpLnZhbHVlcygpLmZvckVhY2goZnFEZXBlbmRlbmNpZXM6OmFkZEFsbCk7CiAgICAgICAgfQoKICAgICAgICAvLyAyLiBFeHRyYWN0IHRoZSBwdWJsaWMgQVBJcyBmcm9tIHRoZSBvbiBkaXNrIC5jbGFzcyBmaWxlcwogICAgICAgIC8vIChSZWFzb24gZm9yIGRvaW5nIHN0ZXAgMSBpbiBhIHNlcGFyYXRlIHBoYXNlIGlzIHRvIGF2b2lkIGV4dHJhY3RpbmcKICAgICAgICAvLyBwdWJsaWMgQVBJcyBvZiB0aGUgc2FtZSBjbGFzcyB0d2ljZS4pCiAgICAgICAgUHViQXBpRXh0cmFjdG9yIHB1YkFwaUV4dHJhY3RvciA9IG5ldyBQdWJBcGlFeHRyYWN0b3Iob3B0aW9ucyk7CiAgICAgICAgTWFwPFN0cmluZywgUHViQXBpPiBvbkRpc2tQdWJBcGkgPSBuZXcgSGFzaE1hcDw+KCk7CiAgICAgICAgZm9yIChTdHJpbmcgY3BEZXAgOiBmcURlcGVuZGVuY2llcykgewogICAgICAgICAgICBvbkRpc2tQdWJBcGkucHV0KGNwRGVwLCBwdWJBcGlFeHRyYWN0b3IuZ2V0UHViQXBpKGNwRGVwKSk7CiAgICAgICAgfQogICAgICAgIHB1YkFwaUV4dHJhY3Rvci5jbG9zZSgpOwoKICAgICAgICAvLyAzLiBDb21wYXJlIHRoZW0gd2l0aCB0aGUgcHVibGljIEFQSXMgYXMgb2YgbGFzdCBjb21waWxhdGlvbiAobG9hZGVkIGZyb20gamF2YWNfc3RhdGUpCiAgICAgICAgbmV4dFBrZzoKICAgICAgICBmb3IgKFBhY2thZ2UgcGtnIDogcHJldi5wYWNrYWdlcygpLnZhbHVlcygpKSB7CiAgICAgICAgICAgIC8vIENoZWNrIGlmIHRoaXMgcGFja2FnZSB3YXMgY29tcGlsZWQuIElmIGl0J3MgcHJlc2VuY2UgaXMgcmVjb3JkZWQKICAgICAgICAgICAgLy8gYmVjYXVzZSBpdCB3YXMgb24gdGhlIGNsYXNzIHBhdGggYW5kIHdlIG5lZWRlZCB0byBzYXZlIGl0J3MKICAgICAgICAgICAgLy8gcHVibGljIGFwaSwgaXQncyBub3QgYSBjYW5kaWRhdGUgZm9yIHRhaW50aW5nLgogICAgICAgICAgICBpZiAocGtnLnNvdXJjZXMoKS5pc0VtcHR5KCkpCiAgICAgICAgICAgICAgICBjb250aW51ZTsKCiAgICAgICAgICAgIFNldDxTdHJpbmc+IGNwRGVwc09mVGhpc1BrZyA9IG5ldyBIYXNoU2V0PD4oKTsKICAgICAgICAgICAgZm9yIChTZXQ8U3RyaW5nPiBjcERlcHMgOiBwa2cudHlwZUNsYXNzcGF0aERlcGVuZGVuY2llcygpLnZhbHVlcygpKQogICAgICAgICAgICAgICAgY3BEZXBzT2ZUaGlzUGtnLmFkZEFsbChjcERlcHMpOwoKICAgICAgICAgICAgZm9yIChTdHJpbmcgZnFEZXAgOiBjcERlcHNPZlRoaXNQa2cpIHsKCiAgICAgICAgICAgICAgICBTdHJpbmcgZGVwUGtnID0gIjoiICsgZnFEZXAuc3Vic3RyaW5nKDAsIGZxRGVwLmxhc3RJbmRleE9mKCcuJykpOwogICAgICAgICAgICAgICAgUHViQXBpIHByZXZQa2dBcGkgPSBwcmV2LnBhY2thZ2VzKCkuZ2V0KGRlcFBrZykuZ2V0UHViQXBpKCk7CgogICAgICAgICAgICAgICAgLy8gVGhpcyBQdWJBcGkgZGlyZWN0bHkgbGlzdHMgdGhlIG1lbWJlcnMgb2YgdGhlIGNsYXNzLAogICAgICAgICAgICAgICAgLy8gaS5lLiBbIE1FTUJFUjEsIE1FTUJFUjIsIC4uLiBdCiAgICAgICAgICAgICAgICBQdWJBcGkgcHJldkRlcEFwaSA9IHByZXZQa2dBcGkudHlwZXMuZ2V0KGZxRGVwKS5wdWJBcGk7CgogICAgICAgICAgICAgICAgLy8gSW4gb3JkZXIgdG8gZGl2ZSAqaW50byogdGhlIGNsYXNzLCB3ZSBuZWVkIHRvIGFkZAogICAgICAgICAgICAgICAgLy8gLnR5cGVzLmdldChmcURlcCkucHViQXBpIGJlbG93LgogICAgICAgICAgICAgICAgUHViQXBpIGN1cnJlbnREZXBBcGkgPSBvbkRpc2tQdWJBcGkuZ2V0KGZxRGVwKS50eXBlcy5nZXQoZnFEZXApLnB1YkFwaTsKCiAgICAgICAgICAgICAgICBpZiAoIWN1cnJlbnREZXBBcGkuaXNCYWNrd2FyZENvbXBhdGlibGVXaXRoKHByZXZEZXBBcGkpKSB7CiAgICAgICAgICAgICAgICAgICAgTGlzdDxTdHJpbmc+IGFwaURpZmYgPSBjdXJyZW50RGVwQXBpLmRpZmYocHJldkRlcEFwaSk7CiAgICAgICAgICAgICAgICAgICAgdGFpbnRQYWNrYWdlKHBrZy5uYW1lKCksICJkZXBlbmRzIG9uIGNsYXNzcGF0aCAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAicGFja2FnZSB3aGljaCBoYXMgYW4gdXBkYXRlZCBwYWNrYWdlIGFwaTogIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgU3RyaW5nLmpvaW4oIlxuIiwgYXBpRGlmZikpOwogICAgICAgICAgICAgICAgICAgIC8vTG9nLmRlYnVnKCI9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Iik7CiAgICAgICAgICAgICAgICAgICAgLy9Mb2cuZGVidWcoIi0tLS0tLSBQUkVWIEFQSSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0iKTsKICAgICAgICAgICAgICAgICAgICAvL3ByZXZEZXBBcGkuYXNMaXN0T2ZTdHJpbmdzKCkuZm9yRWFjaChMb2c6OmRlYnVnKTsKICAgICAgICAgICAgICAgICAgICAvL0xvZy5kZWJ1ZygiLS0tLS0tIENVUlJFTlQgQVBJIC0tLS0tLS0tLS0tLS0tLS0tLS0tLSIpOwogICAgICAgICAgICAgICAgICAgIC8vY3VycmVudERlcEFwaS5hc0xpc3RPZlN0cmluZ3MoKS5mb3JFYWNoKExvZzo6ZGVidWcpOwogICAgICAgICAgICAgICAgICAgIC8vTG9nLmRlYnVnKCI9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Iik7CiAgICAgICAgICAgICAgICAgICAgY29udGludWUgbmV4dFBrZzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFNjYW4gYWxsIG91dHB1dCBkaXJzIGZvciBhcnRpZmFjdHMgYW5kIHJlbW92ZSB0aG9zZSBmaWxlcyAoYXJ0aWZhY3RzPykKICAgICAqIHRoYXQgYXJlIG5vdCByZWNvZ25pemVkIGFzIHN1Y2gsIGluIHRoZSBqYXZhY19zdGF0ZSBmaWxlLgogICAgICovCiAgICBwdWJsaWMgdm9pZCByZW1vdmVVbmlkZW50aWZpZWRBcnRpZmFjdHMoKSB7CiAgICAgICAgU2V0PEZpbGU+IGFsbEtub3duQXJ0aWZhY3RzID0gbmV3IEhhc2hTZXQ8PigpOwogICAgICAgIGZvciAoUGFja2FnZSBwa2cgOiBwcmV2LnBhY2thZ2VzKCkudmFsdWVzKCkpIHsKICAgICAgICAgICAgZm9yIChGaWxlIGYgOiBwa2cuYXJ0aWZhY3RzKCkudmFsdWVzKCkpIHsKICAgICAgICAgICAgICAgIGFsbEtub3duQXJ0aWZhY3RzLmFkZChmKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvLyBEbyBub3QgZm9yZ2V0IGFib3V0IGphdmFjX3N0YXRlLi4uLgogICAgICAgIGFsbEtub3duQXJ0aWZhY3RzLmFkZChqYXZhY1N0YXRlKTsKCiAgICAgICAgZm9yIChGaWxlIGYgOiBiaW5BcnRpZmFjdHMpIHsKICAgICAgICAgICAgaWYgKCFhbGxLbm93bkFydGlmYWN0cy5jb250YWlucyhmKSAmJgogICAgICAgICAgICAgICAgIW9wdGlvbnMuaXNVbmlkZW50aWZpZWRBcnRpZmFjdFBlcm1pdHRlZChmLmdldEFic29sdXRlUGF0aCgpKSkgewogICAgICAgICAgICAgICAgTG9nLmRlYnVnKCJSZW1vdmluZyAiK2YuZ2V0UGF0aCgpKyIgc2luY2UgaXQgaXMgdW5rbm93biB0byB0aGUgamF2YWNfc3RhdGUuIik7CiAgICAgICAgICAgICAgICBmLmRlbGV0ZSgpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGZvciAoRmlsZSBmIDogaGVhZGVyQXJ0aWZhY3RzKSB7CiAgICAgICAgICAgIGlmICghYWxsS25vd25BcnRpZmFjdHMuY29udGFpbnMoZikpIHsKICAgICAgICAgICAgICAgIExvZy5kZWJ1ZygiUmVtb3ZpbmcgIitmLmdldFBhdGgoKSsiIHNpbmNlIGl0IGlzIHVua25vd24gdG8gdGhlIGphdmFjX3N0YXRlLiIpOwogICAgICAgICAgICAgICAgZi5kZWxldGUoKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBmb3IgKEZpbGUgZiA6IGdlbnNyY0FydGlmYWN0cykgewogICAgICAgICAgICBpZiAoIWFsbEtub3duQXJ0aWZhY3RzLmNvbnRhaW5zKGYpKSB7CiAgICAgICAgICAgICAgICBMb2cuZGVidWcoIlJlbW92aW5nICIrZi5nZXRQYXRoKCkrIiBzaW5jZSBpdCBpcyB1bmtub3duIHRvIHRoZSBqYXZhY19zdGF0ZS4iKTsKICAgICAgICAgICAgICAgIGYuZGVsZXRlKCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBSZW1vdmUgYXJ0aWZhY3RzIHRoYXQgYXJlIG5vIGxvbmdlciBwcm9kdWNlZCB3aGVuIGNvbXBpbGluZyEKICAgICAqLwogICAgcHVibGljIHZvaWQgcmVtb3ZlU3VwZXJmbHVvdXNBcnRpZmFjdHMoU2V0PFN0cmluZz4gcmVjZW50bHlDb21waWxlZCkgewogICAgICAgIC8vIE5vdGhpbmcgdG8gZG8sIGlmIG5vdGhpbmcgd2FzIHJlY29tcGlsZWQuCiAgICAgICAgaWYgKHJlY2VudGx5Q29tcGlsZWQuc2l6ZSgpID09IDApIHJldHVybjsKCiAgICAgICAgZm9yIChTdHJpbmcgcGtnIDogbm93LnBhY2thZ2VzKCkua2V5U2V0KCkpIHsKICAgICAgICAgICAgLy8gSWYgdGhpcyBwYWNrYWdlIGhhcyBub3QgYmVlbiByZWNvbXBpbGVkLCBza2lwIHRoZSBjaGVjay4KICAgICAgICAgICAgaWYgKCFyZWNlbnRseUNvbXBpbGVkLmNvbnRhaW5zKHBrZykpIGNvbnRpbnVlOwogICAgICAgICAgICBDb2xsZWN0aW9uPEZpbGU+IGFydHMgPSBub3cuYXJ0aWZhY3RzKCkudmFsdWVzKCk7CiAgICAgICAgICAgIGZvciAoRmlsZSBmIDogZmV0Y2hQcmV2QXJ0aWZhY3RzKHBrZykudmFsdWVzKCkpIHsKICAgICAgICAgICAgICAgIGlmICghYXJ0cy5jb250YWlucyhmKSkgewogICAgICAgICAgICAgICAgICAgIExvZy5kZWJ1ZygiUmVtb3ZpbmcgIitmLmdldFBhdGgoKSsiIHNpbmNlIGl0IGlzIG5vdyBzdXBlcmZsdW91cyEiKTsKICAgICAgICAgICAgICAgICAgICBpZiAoZi5leGlzdHMoKSkgZi5kZWxldGUoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybiB0aG9zZSBmaWxlcyBiZWxvbmdpbmcgdG8gcHJldiwgYnV0IG5vdCBub3cuCiAgICAgKi8KICAgIHByaXZhdGUgU2V0PFNvdXJjZT4gY2FsY3VsYXRlUmVtb3ZlZFNvdXJjZXMoKSB7CiAgICAgICAgU2V0PFNvdXJjZT4gcmVtb3ZlZCA9IG5ldyBIYXNoU2V0PD4oKTsKICAgICAgICBmb3IgKFN0cmluZyBzcmMgOiBwcmV2LnNvdXJjZXMoKS5rZXlTZXQoKSkgewogICAgICAgICAgICBpZiAobm93LnNvdXJjZXMoKS5nZXQoc3JjKSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICByZW1vdmVkLmFkZChwcmV2LnNvdXJjZXMoKS5nZXQoc3JjKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlbW92ZWQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm4gdGhvc2UgZmlsZXMgYmVsb25naW5nIHRvIG5vdywgYnV0IG5vdCBwcmV2LgogICAgICovCiAgICBwcml2YXRlIFNldDxTb3VyY2U+IGNhbGN1bGF0ZUFkZGVkU291cmNlcygpIHsKICAgICAgICBTZXQ8U291cmNlPiBhZGRlZCA9IG5ldyBIYXNoU2V0PD4oKTsKICAgICAgICBmb3IgKFN0cmluZyBzcmMgOiBub3cuc291cmNlcygpLmtleVNldCgpKSB7CiAgICAgICAgICAgIGlmIChwcmV2LnNvdXJjZXMoKS5nZXQoc3JjKSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICBhZGRlZC5hZGQobm93LnNvdXJjZXMoKS5nZXQoc3JjKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIGFkZGVkOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJuIHRob3NlIGZpbGVzIHdoZXJlIHRoZSB0aW1lc3RhbXAgaXMgbmV3ZXIuCiAgICAgKiBJZiBhIHNvdXJjZSBmaWxlIHRpbWVzdGFtcCBzdWRkZW5seSBpcyBvbGRlciB0aGFuIHdoYXQgaXMga25vd24KICAgICAqIGFib3V0IGl0IGluIGphdmFjX3N0YXRlLCB0aGVuIGNvbnNpZGVyIGl0IG1vZGlmaWVkLCBidXQgcHJpbnQKICAgICAqIGEgd2FybmluZyEKICAgICAqLwogICAgcHJpdmF0ZSBTZXQ8U291cmNlPiBjYWxjdWxhdGVNb2RpZmllZFNvdXJjZXMoKSB7CiAgICAgICAgU2V0PFNvdXJjZT4gbW9kaWZpZWQgPSBuZXcgSGFzaFNldDw+KCk7CiAgICAgICAgZm9yIChTdHJpbmcgc3JjIDogbm93LnNvdXJjZXMoKS5rZXlTZXQoKSkgewogICAgICAgICAgICBTb3VyY2UgbiA9IG5vdy5zb3VyY2VzKCkuZ2V0KHNyYyk7CiAgICAgICAgICAgIFNvdXJjZSB0ID0gcHJldi5zb3VyY2VzKCkuZ2V0KHNyYyk7CiAgICAgICAgICAgIGlmIChwcmV2LnNvdXJjZXMoKS5nZXQoc3JjKSAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICBpZiAodCAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKG4ubGFzdE1vZGlmaWVkKCkgPiB0Lmxhc3RNb2RpZmllZCgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIG1vZGlmaWVkLmFkZChuKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKG4ubGFzdE1vZGlmaWVkKCkgPCB0Lmxhc3RNb2RpZmllZCgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIG1vZGlmaWVkLmFkZChuKTsKICAgICAgICAgICAgICAgICAgICAgICAgTG9nLndhcm4oIlRoZSBzb3VyY2UgZmlsZSAiK24ubmFtZSgpKyIgdGltZXN0YW1wIGhhcyBtb3ZlZCBiYWNrd2FyZHMgaW4gdGltZS4iKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1vZGlmaWVkOwogICAgfQoKICAgIC8qKgogICAgICogUmVjdXJzaXZlbHkgZGVsZXRlIGEgZGlyZWN0b3J5IGFuZCBhbGwgaXRzIGNvbnRlbnRzLgogICAgICovCiAgICBwcml2YXRlIHZvaWQgZGVsZXRlQ29udGVudHMoRmlsZSBkaXIpIHsKICAgICAgICBpZiAoZGlyICE9IG51bGwgJiYgZGlyLmV4aXN0cygpKSB7CiAgICAgICAgICAgIGZvciAoRmlsZSBmIDogZGlyLmxpc3RGaWxlcygpKSB7CiAgICAgICAgICAgICAgICBpZiAoZi5pc0RpcmVjdG9yeSgpKSB7CiAgICAgICAgICAgICAgICAgICAgZGVsZXRlQ29udGVudHMoZik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoIW9wdGlvbnMuaXNVbmlkZW50aWZpZWRBcnRpZmFjdFBlcm1pdHRlZChmLmdldEFic29sdXRlUGF0aCgpKSkgewogICAgICAgICAgICAgICAgICAgIExvZy5kZWJ1ZygiUmVtb3ZpbmcgIitmLmdldEFic29sdXRlUGF0aCgpKTsKICAgICAgICAgICAgICAgICAgICBmLmRlbGV0ZSgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogUnVuIHRoZSBjb3B5IHRyYW5zbGF0b3Igb25seS4KICAgICAqLwogICAgcHVibGljIHZvaWQgcGVyZm9ybUNvcHlpbmcoRmlsZSBiaW5EaXIsIE1hcDxTdHJpbmcsVHJhbnNmb3JtZXI+IHN1ZmZpeFJ1bGVzKSB7CiAgICAgICAgTWFwPFN0cmluZyxUcmFuc2Zvcm1lcj4gc3IgPSBuZXcgSGFzaE1hcDw+KCk7CiAgICAgICAgZm9yIChNYXAuRW50cnk8U3RyaW5nLFRyYW5zZm9ybWVyPiBlIDogc3VmZml4UnVsZXMuZW50cnlTZXQoKSkgewogICAgICAgICAgICBpZiAoZS5nZXRWYWx1ZSgpLmdldENsYXNzKCkuZXF1YWxzKENvcHlGaWxlLmNsYXNzKSkgewogICAgICAgICAgICAgICAgc3IucHV0KGUuZ2V0S2V5KCksIGUuZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcGVyZm9ybShudWxsLCBiaW5EaXIsIHNyKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJ1biBhbGwgdGhlIHRyYW5zbGF0b3JzIHRoYXQgdHJhbnNsYXRlIGludG8gamF2YSBzb3VyY2UgY29kZS4KICAgICAqIEkuZS4gYWxsIHRyYW5zbGF0b3JzIHRoYXQgYXJlIG5vdCBjb3B5IG5vciBjb21waWxlX2phdmFfc291cmNlLgogICAgICovCiAgICBwdWJsaWMgdm9pZCBwZXJmb3JtVHJhbnNsYXRpb24oRmlsZSBnZW5zcmNEaXIsIE1hcDxTdHJpbmcsVHJhbnNmb3JtZXI+IHN1ZmZpeFJ1bGVzKSB7CiAgICAgICAgTWFwPFN0cmluZyxUcmFuc2Zvcm1lcj4gc3IgPSBuZXcgSGFzaE1hcDw+KCk7CiAgICAgICAgZm9yIChNYXAuRW50cnk8U3RyaW5nLFRyYW5zZm9ybWVyPiBlIDogc3VmZml4UnVsZXMuZW50cnlTZXQoKSkgewogICAgICAgICAgICBDbGFzczw/PiB0ckNsYXNzID0gZS5nZXRWYWx1ZSgpLmdldENsYXNzKCk7CiAgICAgICAgICAgIGlmICh0ckNsYXNzID09IENvbXBpbGVKYXZhUGFja2FnZXMuY2xhc3MgfHwgdHJDbGFzcyA9PSBDb3B5RmlsZS5jbGFzcykKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwoKICAgICAgICAgICAgc3IucHV0KGUuZ2V0S2V5KCksIGUuZ2V0VmFsdWUoKSk7CiAgICAgICAgfQogICAgICAgIHBlcmZvcm0obnVsbCwgZ2Vuc3JjRGlyLCBzcik7CiAgICB9CgogICAgLyoqCiAgICAgKiBDb21waWxlIGFsbCB0aGUgamF2YSBzb3VyY2VzLiBSZXR1cm4gdHJ1ZSwgaWYgaXQgbmVlZHMgdG8gYmUgY2FsbGVkIGFnYWluIQogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBwZXJmb3JtSmF2YUNvbXBpbGF0aW9ucyhDb21waWxhdGlvblNlcnZpY2Ugc2phdmFjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT3B0aW9ucyBhcmdzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU2V0PFN0cmluZz4gcmVjZW50bHlDb21waWxlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW5bXSByY1ZhbHVlKSB7CiAgICAgICAgTWFwPFN0cmluZyxUcmFuc2Zvcm1lcj4gc3VmZml4UnVsZXMgPSBuZXcgSGFzaE1hcDw+KCk7CiAgICAgICAgc3VmZml4UnVsZXMucHV0KCIuamF2YSIsIGNvbXBpbGVKYXZhUGFja2FnZXMpOwogICAgICAgIGNvbXBpbGVKYXZhUGFja2FnZXMuc2V0RXh0cmEoYXJncyk7CiAgICAgICAgcmNWYWx1ZVswXSA9IHBlcmZvcm0oc2phdmFjLCBiaW5EaXIsIHN1ZmZpeFJ1bGVzKTsKICAgICAgICByZWNlbnRseUNvbXBpbGVkLmFkZEFsbCh0YWludGVkUGFja2FnZXMoKSk7CiAgICAgICAgY2xlYXJUYWludGVkUGFja2FnZXMoKTsKICAgICAgICBib29sZWFuIGFnYWluID0gIXBhY2thZ2VzV2l0aENoYW5nZWRQdWJsaWNBcGlzLmlzRW1wdHkoKTsKICAgICAgICB0YWludFBhY2thZ2VzRGVwZW5kaW5nT25DaGFuZ2VkUGFja2FnZXMocGFja2FnZXNXaXRoQ2hhbmdlZFB1YmxpY0FwaXMsIHJlY2VudGx5Q29tcGlsZWQpOwogICAgICAgIHBhY2thZ2VzV2l0aENoYW5nZWRQdWJsaWNBcGlzID0gbmV3IEhhc2hTZXQ8PigpOwogICAgICAgIHJldHVybiBhZ2FpbiAmJiByY1ZhbHVlWzBdOwoKICAgICAgICAvLyBUT0RPOiBGaWd1cmUgb3V0IHdoeSAnYWdhaW4nIGNoZWNrcyBwYWNrYWdlc1dpdGhDaGFuZ2VkUHVibGljQVBpcy4KICAgICAgICAvLyAoSXQgc2hvdWxkbid0IG1hdHRlciBpZiBwYWNrYWdlcyBoYWQgY2hhbmdlZCBwdWIgYXBpcyBhcyBsb25nIGFzIG5vCiAgICAgICAgLy8gb25lIGRlcGVuZHMgb24gdGhlbS4gV291bGRuJ3QgaXQgbWFrZSBtb3JlIHNlbnNlIHRvIGxldCAnYWdhaW4nCiAgICAgICAgLy8gZGVwZW5kIG9uIHRhaW50ZWRQYWNrYWdlcz8pCiAgICB9CgogICAgLyoqCiAgICAgKiBTdG9yZSB0aGUgc291cmNlIGludG8gdGhlIHNldCBvZiBzb3VyY2VzIGJlbG9uZ2luZyB0byB0aGUgZ2l2ZW4gdHJhbnNmb3JtLgogICAgICovCiAgICBwcml2YXRlIHZvaWQgYWRkRmlsZVRvVHJhbnNmb3JtKE1hcDxUcmFuc2Zvcm1lcixNYXA8U3RyaW5nLFNldDxVUkk+Pj4gZ3MsIFRyYW5zZm9ybWVyIHQsIFNvdXJjZSBzKSB7CiAgICAgICAgTWFwPFN0cmluZyxTZXQ8VVJJPj4gZnMgPSBncy5nZXQodCk7CiAgICAgICAgaWYgKGZzID09IG51bGwpIHsKICAgICAgICAgICAgZnMgPSBuZXcgSGFzaE1hcDw+KCk7CiAgICAgICAgICAgIGdzLnB1dCh0LCBmcyk7CiAgICAgICAgfQogICAgICAgIFNldDxVUkk+IHNzID0gZnMuZ2V0KHMucGtnKCkubmFtZSgpKTsKICAgICAgICBpZiAoc3MgPT0gbnVsbCkgewogICAgICAgICAgICBzcyA9IG5ldyBIYXNoU2V0PD4oKTsKICAgICAgICAgICAgZnMucHV0KHMucGtnKCkubmFtZSgpLCBzcyk7CiAgICAgICAgfQogICAgICAgIHNzLmFkZChzLmZpbGUoKS50b1VSSSgpKTsKICAgIH0KCiAgICAvKioKICAgICAqIEZvciBhbGwgcGFja2FnZXMsIGZpbmQgYWxsIHNvdXJjZXMgYmVsb25naW5nIHRvIHRoZSBwYWNrYWdlLCBncm91cCB0aGUgc291cmNlcwogICAgICogYmFzZWQgb24gdGhlaXIgdHJhbnNmb3JtZXJzIGFuZCBhcHBseSB0aGUgdHJhbnNmb3JtZXJzIG9uIGVhY2ggc291cmNlIGNvZGUgZ3JvdXAuCiAgICAgKi8KICAgIHByaXZhdGUgYm9vbGVhbiBwZXJmb3JtKENvbXBpbGF0aW9uU2VydmljZSBzamF2YWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBGaWxlIG91dHB1dERpciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1hcDxTdHJpbmcsVHJhbnNmb3JtZXI+IHN1ZmZpeFJ1bGVzKSB7CiAgICAgICAgYm9vbGVhbiByYyA9IHRydWU7CiAgICAgICAgLy8gR3JvdXAgc291cmNlcyBiYXNlZCBvbiB0cmFuc2Zvcm1zLiBBIHNvdXJjZSBmaWxlIGNhbiBvbmx5IGJlbG9uZyB0byBhIHNpbmdsZSB0cmFuc2Zvcm0uCiAgICAgICAgTWFwPFRyYW5zZm9ybWVyLE1hcDxTdHJpbmcsU2V0PFVSST4+PiBncm91cGVkU291cmNlcyA9IG5ldyBIYXNoTWFwPD4oKTsKICAgICAgICBmb3IgKFNvdXJjZSBzcmMgOiBub3cuc291cmNlcygpLnZhbHVlcygpKSB7CiAgICAgICAgICAgIFRyYW5zZm9ybWVyIHQgPSBzdWZmaXhSdWxlcy5nZXQoc3JjLnN1ZmZpeCgpKTsKICAgICAgICAgICAgaWYgKHQgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgaWYgKHRhaW50ZWRQYWNrYWdlcy5jb250YWlucyhzcmMucGtnKCkubmFtZSgpKSAmJiAhc3JjLmlzTGlua2VkT25seSgpKSB7CiAgICAgICAgICAgICAgICAgICAgYWRkRmlsZVRvVHJhbnNmb3JtKGdyb3VwZWRTb3VyY2VzLCB0LCBzcmMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8vIEdvIHRocm91Z2ggdGhlIHRyYW5zZm9ybXMgYW5kIHRyYW5zZm9ybSB0aGVtLgogICAgICAgIGZvciAoTWFwLkVudHJ5PFRyYW5zZm9ybWVyLCBNYXA8U3RyaW5nLCBTZXQ8VVJJPj4+IGUgOiBncm91cGVkU291cmNlcy5lbnRyeVNldCgpKSB7CiAgICAgICAgICAgIFRyYW5zZm9ybWVyIHQgPSBlLmdldEtleSgpOwogICAgICAgICAgICBNYXA8U3RyaW5nLCBTZXQ8VVJJPj4gc3JjcyA9IGUuZ2V0VmFsdWUoKTsKICAgICAgICAgICAgLy8gVGhlc2UgbWFwcyBuZWVkIHRvIGJlIHN5bmNocm9uaXplZCBzaW5jZSBtdWx0aXBsZSB0aHJlYWRzIHdpbGwgYmUKICAgICAgICAgICAgLy8gd3JpdGluZyByZXN1bHRzIGludG8gdGhlbS4KICAgICAgICAgICAgTWFwPFN0cmluZywgU2V0PFVSST4+IHBhY2thZ2VBcnRpZmFjdHMgPSBDb2xsZWN0aW9ucy5zeW5jaHJvbml6ZWRNYXAobmV3IEhhc2hNYXA8PigpKTsKICAgICAgICAgICAgTWFwPFN0cmluZywgTWFwPFN0cmluZywgU2V0PFN0cmluZz4+PiBwYWNrYWdlRGVwZW5kZW5jaWVzID0gQ29sbGVjdGlvbnMuc3luY2hyb25pemVkTWFwKG5ldyBIYXNoTWFwPD4oKSk7CiAgICAgICAgICAgIE1hcDxTdHJpbmcsIE1hcDxTdHJpbmcsIFNldDxTdHJpbmc+Pj4gcGFja2FnZUNwRGVwZW5kZW5jaWVzID0gQ29sbGVjdGlvbnMuc3luY2hyb25pemVkTWFwKG5ldyBIYXNoTWFwPD4oKSk7CiAgICAgICAgICAgIE1hcDxTdHJpbmcsIFB1YkFwaT4gcGFja2FnZVB1YmxpY0FwaXMgPSBDb2xsZWN0aW9ucy5zeW5jaHJvbml6ZWRNYXAobmV3IEhhc2hNYXA8PigpKTsKICAgICAgICAgICAgTWFwPFN0cmluZywgUHViQXBpPiBkZXBlbmRlbmN5UHVibGljQXBpcyA9IENvbGxlY3Rpb25zLnN5bmNocm9uaXplZE1hcChuZXcgSGFzaE1hcDw+KCkpOwoKICAgICAgICAgICAgYm9vbGVhbiByID0gdC50cmFuc2Zvcm0oc2phdmFjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcmNzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aXNpYmxlU3JjcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJldi5kZXBlbmRlbnRzKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG91dHB1dERpci50b1VSSSgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWNrYWdlQXJ0aWZhY3RzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWNrYWdlRGVwZW5kZW5jaWVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWNrYWdlQ3BEZXBlbmRlbmNpZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhY2thZ2VQdWJsaWNBcGlzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXBlbmRlbmN5UHVibGljQXBpcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNJbmNyZW1lbnRhbCgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudW1Db3Jlcyk7CiAgICAgICAgICAgIGlmICghcikKICAgICAgICAgICAgICAgIHJjID0gZmFsc2U7CgogICAgICAgICAgICBmb3IgKFN0cmluZyBwIDogc3Jjcy5rZXlTZXQoKSkgewogICAgICAgICAgICAgICAgcmVjb21waWxlZFBhY2thZ2VzLmFkZChwKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvLyBUaGUgdHJhbnNmb3JtIGlzIGRvbmUhIEV4dHJhY3QgYWxsIHRoZSBhcnRpZmFjdHMgYW5kIHN0b3JlIHRoZSBpbmZvIGludG8gdGhlIFBhY2thZ2Ugb2JqZWN0cy4KICAgICAgICAgICAgZm9yIChNYXAuRW50cnk8U3RyaW5nLCBTZXQ8VVJJPj4gYSA6IHBhY2thZ2VBcnRpZmFjdHMuZW50cnlTZXQoKSkgewogICAgICAgICAgICAgICAgTW9kdWxlIG1ub3cgPSBub3cuZmluZE1vZHVsZUZyb21QYWNrYWdlTmFtZShhLmdldEtleSgpKTsKICAgICAgICAgICAgICAgIG1ub3cuYWRkQXJ0aWZhY3RzKGEuZ2V0S2V5KCksIGEuZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gRXh0cmFjdCBhbGwgdGhlIGRlcGVuZGVuY2llcyBhbmQgc3RvcmUgdGhlIGluZm8gaW50byB0aGUgUGFja2FnZSBvYmplY3RzLgogICAgICAgICAgICBmb3IgKE1hcC5FbnRyeTxTdHJpbmcsIE1hcDxTdHJpbmcsIFNldDxTdHJpbmc+Pj4gYSA6IHBhY2thZ2VEZXBlbmRlbmNpZXMuZW50cnlTZXQoKSkgewogICAgICAgICAgICAgICAgTWFwPFN0cmluZywgU2V0PFN0cmluZz4+IGRlcHMgPSBhLmdldFZhbHVlKCk7CiAgICAgICAgICAgICAgICBNb2R1bGUgbW5vdyA9IG5vdy5maW5kTW9kdWxlRnJvbVBhY2thZ2VOYW1lKGEuZ2V0S2V5KCkpOwogICAgICAgICAgICAgICAgbW5vdy5zZXREZXBlbmRlbmNpZXMoYS5nZXRLZXkoKSwgZGVwcywgZmFsc2UpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGZvciAoTWFwLkVudHJ5PFN0cmluZywgTWFwPFN0cmluZywgU2V0PFN0cmluZz4+PiBhIDogcGFja2FnZUNwRGVwZW5kZW5jaWVzLmVudHJ5U2V0KCkpIHsKICAgICAgICAgICAgICAgIE1hcDxTdHJpbmcsIFNldDxTdHJpbmc+PiBkZXBzID0gYS5nZXRWYWx1ZSgpOwogICAgICAgICAgICAgICAgTW9kdWxlIG1ub3cgPSBub3cuZmluZE1vZHVsZUZyb21QYWNrYWdlTmFtZShhLmdldEtleSgpKTsKICAgICAgICAgICAgICAgIG1ub3cuc2V0RGVwZW5kZW5jaWVzKGEuZ2V0S2V5KCksIGRlcHMsIHRydWUpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBUaGlzIG1hcCBjb250YWlucyB0aGUgcHVibGljIGFwaSBvZiB0aGUgdHlwZXMgdGhhdCB0aGlzCiAgICAgICAgICAgIC8vIGNvbXBpbGF0aW9uIGRlcGVuZGVkIHVwb24uIFRoaXMgbWVhbnMgdGhhdCBpdCBtYXkgbm90IGNvbnRhaW4KICAgICAgICAgICAgLy8gZnVsbCBwYWNrYWdlcy4gSW4gb3RoZXIgd29yZHMsIHdlIHNob3VsZG4ndCByZW1vdmUga25vd2xlZGdlIG9mCiAgICAgICAgICAgIC8vIHB1YmxpYyBhcGlzIGJ1dCBtZXJnZSB0aGVzZSB3aXRoIHdoYXQgd2UgYWxyZWFkeSBoYXZlLgogICAgICAgICAgICBmb3IgKE1hcC5FbnRyeTxTdHJpbmcsIFB1YkFwaT4gYSA6IGRlcGVuZGVuY3lQdWJsaWNBcGlzLmVudHJ5U2V0KCkpIHsKICAgICAgICAgICAgICAgIFN0cmluZyBwa2cgPSBhLmdldEtleSgpOwogICAgICAgICAgICAgICAgUHViQXBpIHBhY2thZ2VQYXJ0aWFsUHViQXBpID0gYS5nZXRWYWx1ZSgpOwogICAgICAgICAgICAgICAgUGFja2FnZSBwa2dOb3cgPSBub3cuZmluZE1vZHVsZUZyb21QYWNrYWdlTmFtZShwa2cpLmxvb2t1cFBhY2thZ2UocGtnKTsKICAgICAgICAgICAgICAgIFB1YkFwaSBjdXJyZW50UHViQXBpID0gcGtnTm93LmdldFB1YkFwaSgpOwogICAgICAgICAgICAgICAgUHViQXBpIG5ld1B1YkFwaSA9IFB1YkFwaS5tZXJnZVR5cGVzKGN1cnJlbnRQdWJBcGksIHBhY2thZ2VQYXJ0aWFsUHViQXBpKTsKICAgICAgICAgICAgICAgIHBrZ05vdy5zZXRQdWJhcGkobmV3UHViQXBpKTsKCiAgICAgICAgICAgICAgICAvLyBTZWUgSkRLLTgwNzE5MDQKICAgICAgICAgICAgICAgIGlmIChub3cucGFja2FnZXMoKS5jb250YWluc0tleShwa2cpKQogICAgICAgICAgICAgICAgICAgIG5vdy5wYWNrYWdlcygpLmdldChwa2cpLnNldFB1YmFwaShuZXdQdWJBcGkpOwogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIG5vdy5wYWNrYWdlcygpLnB1dChwa2csIHBrZ05vdyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIFRoZSBwYWNrYWdlUHVibGljQXBpcyBjb3ZlciBlbnRpcmUgcGFja2FnZXMgKHNpbmNlIHNqYXZhYyBjb21waWxlcwogICAgICAgICAgICAvLyBzdHVmZiBvbiBwYWNrYWdlIGxldmVsKS4gVGhpcyBtZWFucyB0aGF0IGlmIGEgdHlwZSBpcyBtaXNzaW5nCiAgICAgICAgICAgIC8vIGluIHRoZSBwdWJsaWMgYXBpIG9mIGEgZ2l2ZW4gcGFja2FnZSwgaXQgbWVhbnMgdGhhdCBpdCBoYXMgYmVlbgogICAgICAgICAgICAvLyByZW1vdmVkLiBJbiBvdGhlciB3b3Jkcywgd2Ugc2hvdWxkICpzZXQqIHRoZSBwdWJhcGkgdG8gd2hhdGV2ZXIKICAgICAgICAgICAgLy8gdGhpcyBtYXAgY29udGFpbnMsIGFuZCBub3QgbWVyZ2UgaXQgd2l0aCB3aGF0IHdlIGFscmVhZHkgaGF2ZS4KICAgICAgICAgICAgZm9yIChNYXAuRW50cnk8U3RyaW5nLCBQdWJBcGk+IGEgOiBwYWNrYWdlUHVibGljQXBpcy5lbnRyeVNldCgpKSB7CiAgICAgICAgICAgICAgICBTdHJpbmcgcGtnID0gYS5nZXRLZXkoKTsKICAgICAgICAgICAgICAgIFB1YkFwaSBuZXdQdWJBcGkgPSBhLmdldFZhbHVlKCk7CiAgICAgICAgICAgICAgICBNb2R1bGUgbXByZXYgPSBwcmV2LmZpbmRNb2R1bGVGcm9tUGFja2FnZU5hbWUocGtnKTsKICAgICAgICAgICAgICAgIE1vZHVsZSBtbm93ID0gbm93LmZpbmRNb2R1bGVGcm9tUGFja2FnZU5hbWUocGtnKTsKICAgICAgICAgICAgICAgIG1ub3cuc2V0UHViYXBpKHBrZywgbmV3UHViQXBpKTsKICAgICAgICAgICAgICAgIGlmIChtcHJldi5oYXNQdWJhcGlDaGFuZ2VkKHBrZywgbmV3UHViQXBpKSkgewogICAgICAgICAgICAgICAgICAgIC8vIEFoYSEgVGhlIHB1YmFwaSBvZiB0aGlzIHBhY2thZ2UgaGFzIGNoYW5nZWQhCiAgICAgICAgICAgICAgICAgICAgLy8gSXQgY2FuIGFsc28gYmUgYSBuZXcgY29tcGlsZSBmcm9tIHNjcmF0Y2guCiAgICAgICAgICAgICAgICAgICAgaWYgKG1wcmV2Lmxvb2t1cFBhY2thZ2UocGtnKS5leGlzdHNJbkphdmFjU3RhdGUoKSkgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBUaGlzIGlzIGFuIGluY3JlbWVudGFsIGNvbXBpbGUhIFRoZSBwdWJhcGkKICAgICAgICAgICAgICAgICAgICAgICAgLy8gZGlkIGNoYW5nZS4gVHJpZ2dlciByZWNvbXBpbGF0aW9uIG9mIGRlcGVuZGVudHMuCiAgICAgICAgICAgICAgICAgICAgICAgIHBhY2thZ2VzV2l0aENoYW5nZWRQdWJsaWNBcGlzLmFkZChwa2cpOwogICAgICAgICAgICAgICAgICAgICAgICBMb2cuZGVidWcoIlRoZSBBUEkgb2YgIiArIFV0aWwuanVzdFBhY2thZ2VOYW1lKHBrZykgKyAiIGhhcyBjaGFuZ2VkISIpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gcmM7CiAgICB9CgogICAgLyoqCiAgICAgKiBVdGlsaXR5IG1ldGhvZCB0byByZWN1cnNpdmVseSBmaW5kIGFsbCBmaWxlcyBiZWxvdyBhIGRpcmVjdG9yeS4KICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgU2V0PEZpbGU+IGZpbmRBbGxGaWxlcyhGaWxlIGRpcikgewogICAgICAgIFNldDxGaWxlPiBmb3VuZEZpbGVzID0gbmV3IEhhc2hTZXQ8PigpOwogICAgICAgIGlmIChkaXIgPT0gbnVsbCkgewogICAgICAgICAgICByZXR1cm4gZm91bmRGaWxlczsKICAgICAgICB9CiAgICAgICAgcmVjdXJzZShkaXIsIGZvdW5kRmlsZXMpOwogICAgICAgIHJldHVybiBmb3VuZEZpbGVzOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIHZvaWQgcmVjdXJzZShGaWxlIGRpciwgU2V0PEZpbGU+IGZvdW5kRmlsZXMpIHsKICAgICAgICBmb3IgKEZpbGUgZiA6IGRpci5saXN0RmlsZXMoKSkgewogICAgICAgICAgICBpZiAoZi5pc0ZpbGUoKSkgewogICAgICAgICAgICAgICAgZm91bmRGaWxlcy5hZGQoZik7CiAgICAgICAgICAgIH0gZWxzZSBpZiAoZi5pc0RpcmVjdG9yeSgpKSB7CiAgICAgICAgICAgICAgICByZWN1cnNlKGYsIGZvdW5kRmlsZXMpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQ29tcGFyZSB0aGUgY2FsY3VsYXRlIHNvdXJjZSBsaXN0LCB3aXRoIGFuIGV4cGxpY2l0IGxpc3QsIHVzdWFsbHkKICAgICAqIHN1cHBsaWVkIGZyb20gdGhlIG1ha2VmaWxlLiBVc2VkIHRvIGRldGVjdCBidWdzIHdoZXJlIHRoZSBtYWtlZmlsZSBhbmQKICAgICAqIHNqYXZhYyBoYXZlIGRpZmZlcmVudCBvcGluaW9ucyBvbiB3aGljaCBmaWxlcyBzaG91bGQgYmUgY29tcGlsZWQuCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIGNvbXBhcmVXaXRoTWFrZWZpbGVMaXN0KEZpbGUgbWFrZWZpbGVTb3VyY2VMaXN0KQogICAgICAgICAgICB0aHJvd3MgUHJvYmxlbUV4Y2VwdGlvbiB7CiAgICAgICAgLy8gSWYgd2UgYXJlIGJ1aWxkaW5nIG9uIHdpbjMyIHVzaW5nIGZvciBleGFtcGxlIGN5Z3dpbiB0aGUgcGF0aHMgaW4gdGhlCiAgICAgICAgLy8gbWFrZWZpbGUgc291cmNlIGxpc3QKICAgICAgICAvLyBtaWdodCBiZSAvY3lnZHJpdmUvYy8uLi4uIHdoaWNoIGRvZXMgbm90IG1hdGNoIGM6XC4uLi4KICAgICAgICAvLyBXZSBuZWVkIHRvIGFkanVzdCBvdXIgY2FsY3VsYXRlZCBzb3VyY2VzIHRvIGJlIGlkZW50aWNhbCwgaWYKICAgICAgICAvLyBuZWNlc3NhcnkuCiAgICAgICAgYm9vbGVhbiBtaWdodE5lZWRSZXdyaXRpbmcgPSBGaWxlLnBhdGhTZXBhcmF0b3JDaGFyID09ICc7JzsKCiAgICAgICAgaWYgKG1ha2VmaWxlU291cmNlTGlzdCA9PSBudWxsKQogICAgICAgICAgICByZXR1cm47CgogICAgICAgIFNldDxTdHJpbmc+IGNhbGN1bGF0ZWRTb3VyY2VzID0gbmV3IEhhc2hTZXQ8PigpOwogICAgICAgIFNldDxTdHJpbmc+IGxpc3RlZFNvdXJjZXMgPSBuZXcgSGFzaFNldDw+KCk7CgogICAgICAgIC8vIENyZWF0ZSBhIHNldCBvZiBmaWxlbmFtZXMgd2l0aCBmdWxsIHBhdGhzLgogICAgICAgIGZvciAoU291cmNlIHMgOiBub3cuc291cmNlcygpLnZhbHVlcygpKSB7CiAgICAgICAgICAgIC8vIERvbid0IGluY2x1ZGUgbGluayBvbmx5IHNvdXJjZXMgd2hlbiBjb21wYXJpbmcgc291cmNlcyB0byBjb21waWxlCiAgICAgICAgICAgIGlmICghcy5pc0xpbmtlZE9ubHkoKSkgewogICAgICAgICAgICAgICAgU3RyaW5nIHBhdGggPSBzLmZpbGUoKS5nZXRQYXRoKCk7CiAgICAgICAgICAgICAgICBpZiAobWlnaHROZWVkUmV3cml0aW5nKQogICAgICAgICAgICAgICAgICAgIHBhdGggPSBVdGlsLm5vcm1hbGl6ZURyaXZlTGV0dGVyKHBhdGgpOwogICAgICAgICAgICAgICAgY2FsY3VsYXRlZFNvdXJjZXMuYWRkKHBhdGgpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8vIFJlYWQgaW4gdGhlIGZpbGUgYW5kIGNyZWF0ZSBhbm90aGVyIHNldCBvZiBmaWxlbmFtZXMgd2l0aCBmdWxsIHBhdGhzLgogICAgICAgIHRyeShCdWZmZXJlZFJlYWRlciBpbiA9IG5ldyBCdWZmZXJlZFJlYWRlcihuZXcgRmlsZVJlYWRlcihtYWtlZmlsZVNvdXJjZUxpc3QpKSkgewogICAgICAgICAgICBmb3IgKDs7KSB7CiAgICAgICAgICAgICAgICBTdHJpbmcgbCA9IGluLnJlYWRMaW5lKCk7CiAgICAgICAgICAgICAgICBpZiAobD09bnVsbCkgYnJlYWs7CiAgICAgICAgICAgICAgICBsID0gbC50cmltKCk7CiAgICAgICAgICAgICAgICBpZiAobWlnaHROZWVkUmV3cml0aW5nKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGwuaW5kZXhPZigiOiIpID09IDEgJiYgbC5pbmRleE9mKCJcXCIpID09IDIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gRXZlcnl0aGluZyBhLW9rLCB0aGUgZm9ybWF0IGlzIGFscmVhZHkgQzpcZm9vXGJhcgogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAobC5pbmRleE9mKCI6IikgPT0gMSAmJiBsLmluZGV4T2YoIi8iKSA9PSAyKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoZSBmb3JtYXQgaXMgQzovZm9vL2JhciwgcmV3cml0ZSBpbnRvIHRoZSBhYm92ZSBmb3JtYXQuCiAgICAgICAgICAgICAgICAgICAgICAgIGwgPSBsLnJlcGxhY2VBbGwoIi8iLCJcXFxcIik7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChsLmNoYXJBdCgwKSA9PSAnLycgJiYgbC5pbmRleE9mKCIvIiwxKSAhPSAtMSkgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBUaGUgZm9ybWF0IG1pZ2h0IGJlOiAvY3lnZHJpdmUvYy9mb28vYmFyLCByZXdyaXRlIGludG8gdGhlIGFib3ZlIGZvcm1hdC4KICAgICAgICAgICAgICAgICAgICAgICAgLy8gRG8gbm90IGhhcmRjb2RlIHRoZSBuYW1lIGN5Z2RyaXZlIGhlcmUuCiAgICAgICAgICAgICAgICAgICAgICAgIGludCBzbGFzaCA9IGwuaW5kZXhPZigiLyIsMSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGwgPSBsLnJlcGxhY2VBbGwoIi8iLCJcXFxcIik7CiAgICAgICAgICAgICAgICAgICAgICAgIGwgPSAiIitsLmNoYXJBdChzbGFzaCsxKSsiOiIrbC5zdWJzdHJpbmcoc2xhc2grMik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmIChDaGFyYWN0ZXIuaXNMb3dlckNhc2UobC5jaGFyQXQoMCkpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGwgPSBDaGFyYWN0ZXIudG9VcHBlckNhc2UobC5jaGFyQXQoMCkpK2wuc3Vic3RyaW5nKDEpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGxpc3RlZFNvdXJjZXMuYWRkKGwpOwogICAgICAgICAgICB9CiAgICAgICAgfSBjYXRjaCAoRmlsZU5vdEZvdW5kRXhjZXB0aW9uIHwgTm9TdWNoRmlsZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBQcm9ibGVtRXhjZXB0aW9uKCJDb3VsZCBub3Qgb3BlbiAiK21ha2VmaWxlU291cmNlTGlzdC5nZXRQYXRoKCkrIiBzaW5jZSBpdCBkb2VzIG5vdCBleGlzdCEiKTsKICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBQcm9ibGVtRXhjZXB0aW9uKCJDb3VsZCBub3QgcmVhZCAiK21ha2VmaWxlU291cmNlTGlzdC5nZXRQYXRoKCkpOwogICAgICAgIH0KCiAgICAgICAgZm9yIChTdHJpbmcgcyA6IGxpc3RlZFNvdXJjZXMpIHsKICAgICAgICAgICAgaWYgKCFjYWxjdWxhdGVkU291cmNlcy5jb250YWlucyhzKSkgewogICAgICAgICAgICAgICAgIHRocm93IG5ldyBQcm9ibGVtRXhjZXB0aW9uKCJUaGUgbWFrZWZpbGUgbGlzdGVkIHNvdXJjZSAiK3MrIiB3YXMgbm90IGNhbGN1bGF0ZWQgYnkgdGhlIHNtYXJ0IGphdmFjIHdyYXBwZXIhIik7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGZvciAoU3RyaW5nIHMgOiBjYWxjdWxhdGVkU291cmNlcykgewogICAgICAgICAgICBpZiAoIWxpc3RlZFNvdXJjZXMuY29udGFpbnMocykpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBQcm9ibGVtRXhjZXB0aW9uKCJUaGUgc21hcnQgamF2YWMgd3JhcHBlciBjYWxjdWxhdGVkIHNvdXJjZSAiK3MrIiB3YXMgbm90IGxpc3RlZCBieSB0aGUgbWFrZWZpbGVzISIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQp9ClBLAwQKAAAIAAAGO6lKml8F93RAAAB0QAAALQAAAGNvbS9zdW4vdG9vbHMvc2phdmFjL0NvbXBpbGVKYXZhUGFja2FnZXMuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAxMiwgMjAxNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLnNqYXZhYzsKCmltcG9ydCBqYXZhLmlvLkZpbGU7CmltcG9ydCBqYXZhLm5ldC5VUkk7CmltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OwppbXBvcnQgamF2YS51dGlsLkFycmF5czsKaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOwppbXBvcnQgamF2YS51dGlsLkxpc3Q7CmltcG9ydCBqYXZhLnV0aWwuTWFwOwppbXBvcnQgamF2YS51dGlsLlJhbmRvbTsKaW1wb3J0IGphdmEudXRpbC5TZXQ7CmltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5DYWxsYWJsZTsKaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkV4ZWN1dGlvbkV4Y2VwdGlvbjsKaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkV4ZWN1dG9yU2VydmljZTsKaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkV4ZWN1dG9yczsKaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkZ1dHVyZTsKCmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLm1haW4uTWFpbi5SZXN1bHQ7CmltcG9ydCBjb20uc3VuLnRvb2xzLnNqYXZhYy5jb21wLkNvbXBpbGF0aW9uU2VydmljZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuc2phdmFjLm9wdGlvbnMuT3B0aW9uczsKaW1wb3J0IGNvbS5zdW4udG9vbHMuc2phdmFjLnB1YmFwaS5QdWJBcGk7CmltcG9ydCBjb20uc3VuLnRvb2xzLnNqYXZhYy5zZXJ2ZXIuQ29tcGlsYXRpb25TdWJSZXN1bHQ7CmltcG9ydCBjb20uc3VuLnRvb2xzLnNqYXZhYy5zZXJ2ZXIuU3lzSW5mbzsKCi8qKgogKiBUaGlzIHRyYW5zZm9ybSBjb21waWxlcyBhIHNldCBvZiBwYWNrYWdlcyBjb250YWluaW5nIEphdmEgc291cmNlcy4KICogVGhlIGNvbXBpbGUgcmVxdWVzdCBpcyBkaXZpZGVkIGludG8gc2VwYXJhdGUgc2V0cyBvZiBzb3VyY2UgZmlsZXMuCiAqIEZvciBlYWNoIHNldCBhIHNlcGFyYXRlIHJlcXVlc3QgdGhyZWFkIGlzIGRpc3BhdGNoZWQgdG8gYSBqYXZhYyBzZXJ2ZXIKICogYW5kIHRoZSBtZXRhIGRhdGEgaXMgYWNjdW11bGF0ZWQuIFRoZSBudW1iZXIgb2Ygc2V0cyBjb3JyZXNwb25kIG1vcmUgb3IKICogbGVzcyB0byB0aGUgbnVtYmVyIG9mIGNvcmVzLiBMZXNzIHNvIG5vdywgdGhhbiBpdCB3aWxsIGluIHRoZSBmdXR1cmUuCiAqCiAqIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24KICogcmlzay4gIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlCiAqIG9yIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj48L3A+CiAqLwpwdWJsaWMgY2xhc3MgQ29tcGlsZUphdmFQYWNrYWdlcyBpbXBsZW1lbnRzIFRyYW5zZm9ybWVyIHsKCiAgICAvLyBUaGUgY3VycmVudCBsaW1pdGVkIHNoYXJpbmcgb2YgZGF0YSBiZXR3ZWVuIGNvbmN1cnJlbnQgSmF2YUNvbXBpbGVycwogICAgLy8gaW4gdGhlIHNlcnZlciB3aWxsIG5vdCBnaXZlIHNwZWVkdXBzIGFib3ZlIDMgY29yZXMuIFRodXMgdGhpcyBsaW1pdC4KICAgIC8vIFdlIGhvcGUgdG8gaW1wcm92ZSB0aGlzIGluIHRoZSBmdXR1cmUuCiAgICBmaW5hbCBzdGF0aWMgaW50IGxpbWl0T25Db25jdXJyZW5jeSA9IDM7CgogICAgT3B0aW9ucyBhcmdzOwoKICAgIHB1YmxpYyB2b2lkIHNldEV4dHJhKFN0cmluZyBlKSB7CiAgICB9CgogICAgcHVibGljIHZvaWQgc2V0RXh0cmEoT3B0aW9ucyBhKSB7CiAgICAgICAgYXJncyA9IGE7CiAgICB9CgogICAgcHVibGljIGJvb2xlYW4gdHJhbnNmb3JtKGZpbmFsIENvbXBpbGF0aW9uU2VydmljZSBzamF2YWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWFwPFN0cmluZyxTZXQ8VVJJPj4gcGtnU3JjcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBTZXQ8VVJJPiAgICAgICAgICAgICB2aXNpYmxlU291cmNlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYXA8U3RyaW5nLFNldDxTdHJpbmc+PiBvbGRQYWNrYWdlRGVwZW5kZW50cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVUkkgZGVzdFJvb3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgTWFwPFN0cmluZyxTZXQ8VVJJPj4gICAgcGFja2FnZUFydGlmYWN0cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBNYXA8U3RyaW5nLE1hcDxTdHJpbmcsIFNldDxTdHJpbmc+Pj4gcGFja2FnZURlcGVuZGVuY2llcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBNYXA8U3RyaW5nLE1hcDxTdHJpbmcsIFNldDxTdHJpbmc+Pj4gcGFja2FnZUNwRGVwZW5kZW5jaWVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIE1hcDxTdHJpbmcsIFB1YkFwaT4gcGFja2FnZVB1YmFwaXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgTWFwPFN0cmluZywgUHViQXBpPiBkZXBlbmRlbmN5UHViYXBpcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgZGVidWdMZXZlbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGluY3JlbWVudGFsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBudW1Db3JlcykgewoKICAgICAgICBMb2cuZGVidWcoIlBlcmZvcm1pbmcgQ29tcGlsZUphdmFQYWNrYWdlcyB0cmFuc2Zvcm0uLi4iKTsKCiAgICAgICAgYm9vbGVhbiByYyA9IHRydWU7CiAgICAgICAgYm9vbGVhbiBjb25jdXJyZW50Q29tcGlsZXMgPSB0cnVlOwoKICAgICAgICAvLyBGZXRjaCB0aGUgaWQuCiAgICAgICAgZmluYWwgU3RyaW5nIGlkID0gU3RyaW5nLnZhbHVlT2YobmV3IFJhbmRvbSgpLm5leHRJbnQoKSk7CiAgICAgICAgLy8gT25seSBrZWVwIHBvcnRmaWxlIGFuZCBzamF2YWMgc2V0dGluZ3MuLgogICAgICAgIC8vU3RyaW5nIHBzU2VydmVyU2V0dGluZ3MgPSBVdGlsLmNsZWFuU3ViT3B0aW9ucyhVdGlsLnNldCgicG9ydGZpbGUiLCJzamF2YWMiLCJiYWNrZ3JvdW5kIiwia2VlcGFsaXZlIiksIHNqYXZhYy5zZXJ2ZXJTZXR0aW5ncygpKTsKCiAgICAgICAgU3lzSW5mbyBzeXNpbmZvID0gc2phdmFjLmdldFN5c0luZm8oKTsKICAgICAgICBpbnQgbnVtTUJ5dGVzID0gKGludCkoc3lzaW5mby5tYXhNZW1vcnkgLyAoKGxvbmcpKDEwMjQqMTAyNCkpKTsKICAgICAgICBMb2cuZGVidWcoIlNlcnZlciByZXBvcnRzICIrbnVtTUJ5dGVzKyJNaUIgb2YgbWVtb3J5IGFuZCAiK3N5c2luZm8ubnVtQ29yZXMrIiBjb3JlcyIpOwoKICAgICAgICBpZiAobnVtQ29yZXMgPD0gMCkgewogICAgICAgICAgICAvLyBTZXQgdGhlIHJlcXVlc3RlZCBudW1iZXIgb2YgY29yZXMgdG8gdGhlIG51bWJlciBvZiBjb3JlcyBvbiB0aGUgc2VydmVyLgogICAgICAgICAgICBudW1Db3JlcyA9IHN5c2luZm8ubnVtQ29yZXM7CiAgICAgICAgICAgIExvZy5kZWJ1ZygiTnVtYmVyIG9mIGpvYnMgbm90IGV4cGxpY2l0bHkgc2V0LCBkZWZhdWx0aW5nIHRvICIrc3lzaW5mby5udW1Db3Jlcyk7CiAgICAgICAgfSBlbHNlIGlmIChzeXNpbmZvLm51bUNvcmVzIDwgbnVtQ29yZXMpIHsKICAgICAgICAgICAgLy8gU2V0IHRoZSByZXF1ZXN0ZWQgbnVtYmVyIG9mIGNvcmVzIHRvIHRoZSBudW1iZXIgb2YgY29yZXMgb24gdGhlIHNlcnZlci4KICAgICAgICAgICAgTG9nLmRlYnVnKCJMaW1pdGluZyBqb2JzIGZyb20gZXhwbGljaXRseSBzZXQgIitudW1Db3JlcysiIHRvIGNvcmVzIGF2YWlsYWJsZSBvbiBzZXJ2ZXI6ICIrc3lzaW5mby5udW1Db3Jlcyk7CiAgICAgICAgICAgIG51bUNvcmVzID0gc3lzaW5mby5udW1Db3JlczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBMb2cuZGVidWcoIk51bWJlciBvZiBqb2JzIGV4cGxpY2l0bHkgc2V0IHRvICIrbnVtQ29yZXMpOwogICAgICAgIH0KICAgICAgICAvLyBNb3JlIHRoYW4gdGhyZWUgY29uY3VycmVudCBjb3JlcyBkb2VzIG5vdCBjdXJyZW50bHkgZ2l2ZSBhIHNwZWVkdXAsIGF0IGxlYXN0IGZvciBjb21waWxpbmcgdGhlIGpkawogICAgICAgIC8vIGluIHRoZSBPcGVuSkRLLiBUaGlzIHdpbGwgY2hhbmdlIGluIHRoZSBmdXR1cmUuCiAgICAgICAgaW50IG51bUNvbXBpbGVzID0gbnVtQ29yZXM7CiAgICAgICAgaWYgKG51bUNvcmVzID4gbGltaXRPbkNvbmN1cnJlbmN5KSBudW1Db21waWxlcyA9IGxpbWl0T25Db25jdXJyZW5jeTsKICAgICAgICAvLyBTcGxpdCB0aGUgd29yayB1cCBpbiBjaHVua3MgdG8gY29tcGlsZWQuCgogICAgICAgIGludCBudW1Tb3VyY2VzID0gMDsKICAgICAgICBmb3IgKFN0cmluZyBzIDogcGtnU3Jjcy5rZXlTZXQoKSkgewogICAgICAgICAgICBTZXQ8VVJJPiBzcyA9IHBrZ1NyY3MuZ2V0KHMpOwogICAgICAgICAgICBudW1Tb3VyY2VzICs9IHNzLnNpemUoKTsKICAgICAgICB9CgogICAgICAgIGludCBzb3VyY2VzUGVyQ29tcGlsZSA9IG51bVNvdXJjZXMgLyBudW1Db21waWxlczsKCiAgICAgICAgLy8gRm9yIDY0IGJpdCBKYXZhLCBpdCBzZWVtcyB3ZSBjYW4gY29tcGlsZSB0aGUgT3BlbkpESyA4ODAwIGZpbGVzIHdpdGggYSAxNTAwTSBvZiBoZWFwCiAgICAgICAgLy8gaW4gYSBzaW5nbGUgY2h1bmssIHdpdGggcmVhc29uYWJsZSBwZXJmb3JtYW5jZS4KICAgICAgICAvLyBGb3IgMzIgYml0IGphdmEsIGl0IHNlZW1zIHdlIG5lZWQgMUcgb2YgaGVhcC4KICAgICAgICAvLyBOdW1iZXIgZXhwZXJpbWVudGFsbHkgZGV0ZXJtaW5lZCB3aGVuIGNvbXBpbGluZyB0aGUgT3BlbkpESy4KICAgICAgICAvLyBJbmNsdWRlcyBzcGFjZSBmb3IgcmVhc29uYWJseSBlZmZpY2llbnQgZ2FyYmFnZSBjb2xsZWN0aW9uIGV0YywKICAgICAgICAvLyBDYWxjdWxhdGluZyBiYWNrd2FyZHMgZ2l2ZXMgdXMgYSByZXF1aXJlbWVudCBvZgogICAgICAgIC8vIDE1MDBNLzg4MDAgPSAxNzUgS2lCIGZvciA2NCBiaXQgcGxhdGZvcm1zCiAgICAgICAgLy8gYW5kIDFHLzg4MDAgPSAxMTkgS2lCIGZvciAzMiBiaXQgcGxhdGZvcm0KICAgICAgICAvLyBmb3IgZWFjaCBjb21waWxlLi4uLi4KICAgICAgICBpbnQga2JQZXJGaWxlID0gMTc1OwogICAgICAgIFN0cmluZyBvc2FyY2ggPSBTeXN0ZW0uZ2V0UHJvcGVydHkoIm9zLmFyY2giKTsKICAgICAgICBTdHJpbmcgZGF0YU1vZGVsID0gU3lzdGVtLmdldFByb3BlcnR5KCJzdW4uYXJjaC5kYXRhLm1vZGVsIik7CiAgICAgICAgaWYgKCIzMiIuZXF1YWxzKGRhdGFNb2RlbCkpIHsKICAgICAgICAgICAgLy8gRm9yIDMyIGJpdCBwbGF0Zm9ybXMsIGFzc3VtZSBpdCBpcyBzbGlnaHRseSBzbWFsbGVyCiAgICAgICAgICAgIC8vIGJlY2F1c2Ugb2Ygc21hbGxlciBvYmplY3QgaGVhZGVycyBhbmQgcG9pbnRlcnMuCiAgICAgICAgICAgIGtiUGVyRmlsZSA9IDExOTsKICAgICAgICB9CiAgICAgICAgaW50IG51bVJlcXVpcmVkTUJ5dGVzID0gKGtiUGVyRmlsZSpudW1Tb3VyY2VzKS8xMDI0OwogICAgICAgIExvZy5kZWJ1ZygiRm9yIG9zLmFyY2ggIitvc2FyY2grIiB0aGUgZW1waXJpY2FsbHkgZGV0ZXJtaW5lZCBoZWFwIHJlcXVpcmVkIHBlciBmaWxlIGlzICIra2JQZXJGaWxlKyJLaUIiKTsKICAgICAgICBMb2cuZGVidWcoIlNlcnZlciBoYXMgIitudW1NQnl0ZXMrIk1pQiBvZiBoZWFwLiIpOwogICAgICAgIExvZy5kZWJ1ZygiSGV1cmlzdGljcyBzYXkgdGhhdCB3ZSBuZWVkICIrbnVtUmVxdWlyZWRNQnl0ZXMrIk1pQiBvZiBoZWFwIGZvciBhbGwgc291cmNlIGZpbGVzLiIpOwogICAgICAgIC8vIFBlcmZvcm0gaGV1cmlzdGljcyB0byBzZWUgaG93IG1hbnkgY29yZXMgd2UgY2FuIHVzZSwKICAgICAgICAvLyBvciBpZiB3ZSBoYXZlIHRvIHRoZSB3b3JrIHNlcmlhbGx5IGluIHNtYWxsZXIgY2h1bmtzLgogICAgICAgIGlmIChudW1NQnl0ZXMgPCBudW1SZXF1aXJlZE1CeXRlcykgewogICAgICAgICAgICAvLyBPdWNoLCBjYW5ub3QgZml0IGV2ZW4gYSBzaW5nbGUgY29tcGlsZSBpbnRvIHRoZSBoZWFwLgogICAgICAgICAgICAvLyBTcGxpdCBpdCB1cCBpbnRvIHNldmVyYWwgc2VyaWFsIGNodW5rcy4KICAgICAgICAgICAgY29uY3VycmVudENvbXBpbGVzID0gZmFsc2U7CiAgICAgICAgICAgIC8vIExpbWl0IHRoZSBudW1iZXIgb2Ygc291cmNlcyBmb3IgZWFjaCBjb21waWxlIHRvIDUwMC4KICAgICAgICAgICAgaWYgKG51bVNvdXJjZXMgPCA1MDApIHsKICAgICAgICAgICAgICAgIG51bUNvbXBpbGVzID0gMTsKICAgICAgICAgICAgICAgIHNvdXJjZXNQZXJDb21waWxlID0gbnVtU291cmNlczsKICAgICAgICAgICAgICAgIExvZy5kZWJ1ZygiQ29tcGlsaW5nIGFzIGEgc2luZ2xlIHNvdXJjZSBjb2RlIGNodW5rIHRvIHN0YXkgd2l0aGluIGhlYXAgc2l6ZSBsaW1pdGF0aW9ucyEiKTsKICAgICAgICAgICAgfSBlbHNlIGlmIChzb3VyY2VzUGVyQ29tcGlsZSA+IDUwMCkgewogICAgICAgICAgICAgICAgLy8gVGhpcyBudW1iZXIgaXMgdmVyeSBsb3csIGFuZCB0dW5lZCB0byBkZWFsaW5nIHdpdGggdGhlIE9wZW5KREsKICAgICAgICAgICAgICAgIC8vIHdoZXJlIHRoZSBzb3VyY2UgaXMgPnZlcnk8IGNpcmN1bGFyISBJbiBub3JtYWwgYXBwbGljYXRpb24sCiAgICAgICAgICAgICAgICAvLyB3aXRoIGxlc3MgY2lyY3VsYXJpdHkgdGhlIG51bWJlciBjb3VsZCBwZXJoYXBzIGJlIGluY3JlYXNlZC4KICAgICAgICAgICAgICAgIG51bUNvbXBpbGVzID0gbnVtU291cmNlcyAvIDUwMDsKICAgICAgICAgICAgICAgIHNvdXJjZXNQZXJDb21waWxlID0gbnVtU291cmNlcy9udW1Db21waWxlczsKICAgICAgICAgICAgICAgIExvZy5kZWJ1ZygiQ29tcGlsaW5nIHNvdXJjZSBhcyAiK251bUNvbXBpbGVzKyIgY29kZSBjaHVua3Mgc2VyaWFsbHkgdG8gc3RheSB3aXRoaW4gaGVhcCBzaXplIGxpbWl0YXRpb25zISIpOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgaWYgKG51bUNvbXBpbGVzID4gMSkgewogICAgICAgICAgICAgICAgLy8gT2ssIHdlIGNhbiBmaXQgYXQgbGVhc3Qgb25lIGZ1bGwgY29tcGlsYXRpb24gb24gdGhlIGhlYXAuCiAgICAgICAgICAgICAgICBmbG9hdCB1c2FnZVBlckNvbXBpbGUgPSAoZmxvYXQpbnVtUmVxdWlyZWRNQnl0ZXMgLyAoKGZsb2F0KW51bUNvbXBpbGVzICogKGZsb2F0KTAuNyk7CiAgICAgICAgICAgICAgICBpbnQgdXNhZ2UgPSAoaW50KSh1c2FnZVBlckNvbXBpbGUgKiAoZmxvYXQpbnVtQ29tcGlsZXMpOwogICAgICAgICAgICAgICAgTG9nLmRlYnVnKCJIZXVyaXN0aWNzIHNheSB0aGF0IGZvciAiK251bUNvbXBpbGVzKyIgY29uY3VycmVudCBjb21waWxlcyB3ZSBuZWVkICIrdXNhZ2UrIk1pQiIpOwogICAgICAgICAgICAgICAgaWYgKHVzYWdlID4gbnVtTUJ5dGVzKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gT3VjaCBpdCBkb2VzIG5vdCBmaXQuIFJlZHVjZSB0byBhIHNpbmdsZSBjaHVuay4KICAgICAgICAgICAgICAgICAgICBudW1Db21waWxlcyA9IDE7CiAgICAgICAgICAgICAgICAgICAgc291cmNlc1BlckNvbXBpbGUgPSBudW1Tb3VyY2VzOwogICAgICAgICAgICAgICAgICAgIC8vIFdoYXQgaWYgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVtIG51bWJlciBvZiBjb21waWxlX2NodW5rcyBhbmQgbnVtX3JlcXVpcmVkX21ieXRlcwogICAgICAgICAgICAgICAgICAgIC8vIGlzIG5vdCBsaW5lYXI/IFRoZW4gcGVyaGFwcyAyIGNodW5rcyB3b3VsZCBmaXQgd2hlcmUgMyBkb2VzIG5vdC4gV2VsbCwgdGhpcyBpcwogICAgICAgICAgICAgICAgICAgIC8vIHNvbWV0aGluZyB0byBleHBlcmltZW50IHVwb24gaW4gdGhlIGZ1dHVyZS4KICAgICAgICAgICAgICAgICAgICBMb2cuZGVidWcoIkxpbWl0aW5nIGNvbXBpbGUgdG8gYSBzaW5nbGUgdGhyZWFkIHRvIHN0YXkgd2l0aGluIGhlYXAgc2l6ZSBsaW1pdGF0aW9ucyEiKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgTG9nLmRlYnVnKCJDb21waWxpbmcgc291cmNlcyBpbiAiK251bUNvbXBpbGVzKyIgY2h1bmsocykiKTsKCiAgICAgICAgLy8gQ3JlYXRlIHRoZSBjaHVua3MgdG8gYmUgY29tcGlsZWQuCiAgICAgICAgZmluYWwgQ29tcGlsZUNodW5rW10gY29tcGlsZUNodW5rcyA9IGNyZWF0ZUNvbXBpbGVDaHVua3MocGtnU3Jjcywgb2xkUGFja2FnZURlcGVuZGVudHMsCiAgICAgICAgICAgICAgICBudW1Db21waWxlcywgc291cmNlc1BlckNvbXBpbGUpOwoKICAgICAgICBpZiAoTG9nLmlzRGVidWdnaW5nKCkpIHsKICAgICAgICAgICAgaW50IGNuID0gMTsKICAgICAgICAgICAgZm9yIChDb21waWxlQ2h1bmsgY2MgOiBjb21waWxlQ2h1bmtzKSB7CiAgICAgICAgICAgICAgICBMb2cuZGVidWcoIkNodW5rICIrY24rIiBmb3IgIitpZCsiIC0tLS0tLS0tLS0tLS0tLSIpOwogICAgICAgICAgICAgICAgY24rKzsKICAgICAgICAgICAgICAgIGZvciAoVVJJIHUgOiBjYy5zcmNzKSB7CiAgICAgICAgICAgICAgICAgICAgTG9nLmRlYnVnKCIiK3UpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBsb25nIHN0YXJ0ID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CgogICAgICAgIC8vIFByZXBhcmUgY29tcGlsYXRpb24gY2FsbHMKICAgICAgICBMaXN0PENhbGxhYmxlPENvbXBpbGF0aW9uU3ViUmVzdWx0Pj4gY29tcGlsYXRpb25DYWxscyA9IG5ldyBBcnJheUxpc3Q8PigpOwogICAgICAgIGZpbmFsIE9iamVjdCBsb2NrID0gbmV3IE9iamVjdCgpOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnVtQ29tcGlsZXM7IGkrKykgewogICAgICAgICAgICBDb21waWxlQ2h1bmsgY2MgPSBjb21waWxlQ2h1bmtzW2ldOwogICAgICAgICAgICBpZiAoY2Muc3Jjcy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBTdHJpbmcgY2h1bmtJZCA9IGlkICsgIi0iICsgU3RyaW5nLnZhbHVlT2YoaSk7CiAgICAgICAgICAgIExvZyBsb2cgPSBMb2cuZ2V0KCk7CiAgICAgICAgICAgIGNvbXBpbGF0aW9uQ2FsbHMuYWRkKCgpIC0+IHsKICAgICAgICAgICAgICAgIExvZy5zZXRMb2dGb3JDdXJyZW50VGhyZWFkKGxvZyk7CiAgICAgICAgICAgICAgICBDb21waWxhdGlvblN1YlJlc3VsdCByZXN1bHQgPSBzamF2YWMuY29tcGlsZSgibi9hIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNodW5rSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmdzLnByZXBKYXZhY0FyZ3MoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbGxlY3Rpb25zLmVtcHR5TGlzdCgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2Muc3JjcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpc2libGVTb3VyY2VzKTsKICAgICAgICAgICAgICAgIHN5bmNocm9uaXplZCAobG9jaykgewogICAgICAgICAgICAgICAgICAgIFV0aWwuZ2V0TGluZXMocmVzdWx0LnN0ZG91dCkuZm9yRWFjaChMb2c6OmluZm8pOwogICAgICAgICAgICAgICAgICAgIFV0aWwuZ2V0TGluZXMocmVzdWx0LnN0ZGVycikuZm9yRWFjaChMb2c6OmVycm9yKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KCiAgICAgICAgLy8gUGVyZm9ybSBjb21waWxhdGlvbnMgYW5kIGNvbGxlY3QgcmVzdWx0cwogICAgICAgIExpc3Q8Q29tcGlsYXRpb25TdWJSZXN1bHQ+IHN1YlJlc3VsdHMgPSBuZXcgQXJyYXlMaXN0PD4oKTsKICAgICAgICBMaXN0PEZ1dHVyZTxDb21waWxhdGlvblN1YlJlc3VsdD4+IGZ1dHMgPSBuZXcgQXJyYXlMaXN0PD4oKTsKICAgICAgICBFeGVjdXRvclNlcnZpY2UgZXhlYyA9IEV4ZWN1dG9ycy5uZXdGaXhlZFRocmVhZFBvb2woY29uY3VycmVudENvbXBpbGVzID8gY29tcGlsYXRpb25DYWxscy5zaXplKCkgOiAxKTsKICAgICAgICBmb3IgKENhbGxhYmxlPENvbXBpbGF0aW9uU3ViUmVzdWx0PiBjb21waWxhdGlvbkNhbGwgOiBjb21waWxhdGlvbkNhbGxzKSB7CiAgICAgICAgICAgIGZ1dHMuYWRkKGV4ZWMuc3VibWl0KGNvbXBpbGF0aW9uQ2FsbCkpOwogICAgICAgIH0KICAgICAgICBmb3IgKEZ1dHVyZTxDb21waWxhdGlvblN1YlJlc3VsdD4gZnV0IDogZnV0cykgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgc3ViUmVzdWx0cy5hZGQoZnV0LmdldCgpKTsKICAgICAgICAgICAgfSBjYXRjaCAoRXhlY3V0aW9uRXhjZXB0aW9uIGVlKSB7CiAgICAgICAgICAgICAgICBMb2cuZXJyb3IoIkNvbXBpbGF0aW9uIGZhaWxlZDogIiArIGVlLmdldE1lc3NhZ2UoKSk7CiAgICAgICAgICAgICAgICBMb2cuZXJyb3IoZWUpOwogICAgICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBpZSkgewogICAgICAgICAgICAgICAgTG9nLmVycm9yKCJDb21waWxhdGlvbiBpbnRlcnJ1cHRlZDogIiArIGllLmdldE1lc3NhZ2UoKSk7CiAgICAgICAgICAgICAgICBMb2cuZXJyb3IoaWUpOwogICAgICAgICAgICAgICAgVGhyZWFkLmN1cnJlbnRUaHJlYWQoKS5pbnRlcnJ1cHQoKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBleGVjLnNodXRkb3duTm93KCk7CgogICAgICAgIC8vIFByb2Nlc3MgZWFjaCBzdWIgcmVzdWx0CiAgICAgICAgZm9yIChDb21waWxhdGlvblN1YlJlc3VsdCBzdWJSZXN1bHQgOiBzdWJSZXN1bHRzKSB7CiAgICAgICAgICAgIGZvciAoU3RyaW5nIHBrZyA6IHN1YlJlc3VsdC5wYWNrYWdlQXJ0aWZhY3RzLmtleVNldCgpKSB7CiAgICAgICAgICAgICAgICBTZXQ8VVJJPiBwa2dBcnRpZmFjdHMgPSBzdWJSZXN1bHQucGFja2FnZUFydGlmYWN0cy5nZXQocGtnKTsKICAgICAgICAgICAgICAgIHBhY2thZ2VBcnRpZmFjdHMubWVyZ2UocGtnLCBwa2dBcnRpZmFjdHMsIFV0aWw6OnVuaW9uKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZm9yIChTdHJpbmcgcGtnIDogc3ViUmVzdWx0LnBhY2thZ2VEZXBlbmRlbmNpZXMua2V5U2V0KCkpIHsKICAgICAgICAgICAgICAgIHBhY2thZ2VEZXBlbmRlbmNpZXMucHV0SWZBYnNlbnQocGtnLCBuZXcgSGFzaE1hcDw+KCkpOwogICAgICAgICAgICAgICAgcGFja2FnZURlcGVuZGVuY2llcy5nZXQocGtnKS5wdXRBbGwoc3ViUmVzdWx0LnBhY2thZ2VEZXBlbmRlbmNpZXMuZ2V0KHBrZykpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBmb3IgKFN0cmluZyBwa2cgOiBzdWJSZXN1bHQucGFja2FnZUNwRGVwZW5kZW5jaWVzLmtleVNldCgpKSB7CiAgICAgICAgICAgICAgICBwYWNrYWdlQ3BEZXBlbmRlbmNpZXMucHV0SWZBYnNlbnQocGtnLCBuZXcgSGFzaE1hcDw+KCkpOwogICAgICAgICAgICAgICAgcGFja2FnZUNwRGVwZW5kZW5jaWVzLmdldChwa2cpLnB1dEFsbChzdWJSZXN1bHQucGFja2FnZUNwRGVwZW5kZW5jaWVzLmdldChwa2cpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZm9yIChTdHJpbmcgcGtnIDogc3ViUmVzdWx0LnBhY2thZ2VQdWJhcGlzLmtleVNldCgpKSB7CiAgICAgICAgICAgICAgICBwYWNrYWdlUHViYXBpcy5tZXJnZShwa2csIHN1YlJlc3VsdC5wYWNrYWdlUHViYXBpcy5nZXQocGtnKSwgUHViQXBpOjptZXJnZVR5cGVzKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZm9yIChTdHJpbmcgcGtnIDogc3ViUmVzdWx0LmRlcGVuZGVuY3lQdWJhcGlzLmtleVNldCgpKSB7CiAgICAgICAgICAgICAgICBkZXBlbmRlbmN5UHViYXBpcy5tZXJnZShwa2csIHN1YlJlc3VsdC5kZXBlbmRlbmN5UHViYXBpcy5nZXQocGtnKSwgUHViQXBpOjptZXJnZVR5cGVzKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gQ2hlY2sgdGhlIHJldHVybiB2YWx1ZXMuCiAgICAgICAgICAgIGlmIChzdWJSZXN1bHQucmVzdWx0ICE9IFJlc3VsdC5PSykgewogICAgICAgICAgICAgICAgcmMgPSBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgbG9uZyBkdXJhdGlvbiA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpIC0gc3RhcnQ7CiAgICAgICAgbG9uZyBtaW51dGVzID0gZHVyYXRpb24vNjAwMDA7CiAgICAgICAgbG9uZyBzZWNvbmRzID0gKGR1cmF0aW9uLW1pbnV0ZXMqNjAwMDApLzEwMDA7CiAgICAgICAgTG9nLmRlYnVnKCJDb21waWxhdGlvbiBvZiAiK251bVNvdXJjZXMrIiBzb3VyY2UgZmlsZXMgdG9vayAiK21pbnV0ZXMrIm0gIitzZWNvbmRzKyJzIik7CgogICAgICAgIHJldHVybiByYzsKICAgIH0KCiAgICAvKioKICAgICAqIFNwbGl0IHVwIHRoZSBzb3VyY2VzIGludG8gY29tcGlsZSBjaHVua3MuIElmIG9sZCBwYWNrYWdlIGRlcGVuZGVudHMgaW5mb3JtYXRpb24KICAgICAqIGlzIGF2YWlsYWJsZSwgc29ydCB0aGUgb3JkZXIgb2YgdGhlIGNodW5rcyBpbnRvIHRoZSBtb3N0IGRlcGVuZGVudCBmaXJzdCEKICAgICAqIChUeXBpY2FsbHkgdGhhdCBjaHVuayBjb250YWlucyB0aGUgamF2YS5sYW5nIHBhY2thZ2UuKSBJbiB0aGUgZnV0dXJlCiAgICAgKiB3ZSBjb3VsZCBwZXJoYXBzIGltcHJvdmUgdGhlIGhldXJpc3RpY3MgdG8gcHV0IHRoZSBzb3VyY2VzIGludG8gZXZlbiBtb3JlIHNlbnNpYmxlIGNodW5rcy4KICAgICAqIE5vdyB0aGUgcGFja2FnZSBhcmUgc2ltcGxlIHNvcnRlZCBpbiBhbHBoYWJldGljYWwgb3JkZXIgYW5kIGNodW5rZWQsIHRoZW4gdGhlIGNodW5rcwogICAgICogYXJlIHNvcnRlZCBvbiBob3cgZGVwZW5kZW50IHRoZXkgYXJlLgogICAgICoKICAgICAqIEBwYXJhbSBwa2dTcmNzIFRoZSBzb3VyY2VzIHRvIGNvbXBpbGUuCiAgICAgKiBAcGFyYW0gb2xkUGFja2FnZURlcGVuZGVudHMgT2xkIHBhY2thZ2UgZGVwZW5kZW50cywgaWYgbm9uLWVtcHR5LCB1c2VkIHRvIHNvcnQgdGhlIGNodW5rcy4KICAgICAqIEBwYXJhbSBudW1Db21waWxlcyBUaGUgbnVtYmVyIG9mIGNodW5rcy4KICAgICAqIEBwYXJhbSBzb3VyY2VzUGVyQ29tcGlsZSBUaGUgbnVtYmVyIG9mIHNvdXJjZXMgcGVyIGNodW5rLgogICAgICogQHJldHVybgogICAgICovCiAgICBDb21waWxlQ2h1bmtbXSBjcmVhdGVDb21waWxlQ2h1bmtzKE1hcDxTdHJpbmcsU2V0PFVSST4+IHBrZ1NyY3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1hcDxTdHJpbmcsU2V0PFN0cmluZz4+IG9sZFBhY2thZ2VEZXBlbmRlbnRzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbnVtQ29tcGlsZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBzb3VyY2VzUGVyQ29tcGlsZSkgewoKICAgICAgICBDb21waWxlQ2h1bmtbXSBjb21waWxlQ2h1bmtzID0gbmV3IENvbXBpbGVDaHVua1tudW1Db21waWxlc107CiAgICAgICAgZm9yIChpbnQgaT0wOyBpPGNvbXBpbGVDaHVua3MubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgY29tcGlsZUNodW5rc1tpXSA9IG5ldyBDb21waWxlQ2h1bmsoKTsKICAgICAgICB9CgogICAgICAgIC8vIE5vdyBnbyB0aHJvdWdoIHRoZSBwYWNrYWdlcyBhbmQgc3ByZWFkIG91dCB0aGUgc291cmNlIG9uIHRoZSBkaWZmZXJlbnQgY2h1bmtzLgogICAgICAgIGludCBjaSA9IDA7CiAgICAgICAgLy8gU29ydCB0aGUgcGFja2FnZXMKICAgICAgICBTdHJpbmdbXSBwYWNrYWdlTmFtZXMgPSBwa2dTcmNzLmtleVNldCgpLnRvQXJyYXkobmV3IFN0cmluZ1swXSk7CiAgICAgICAgQXJyYXlzLnNvcnQocGFja2FnZU5hbWVzKTsKICAgICAgICBTdHJpbmcgZnJvbSA9IG51bGw7CiAgICAgICAgZm9yIChTdHJpbmcgcGtnTmFtZSA6IHBhY2thZ2VOYW1lcykgewogICAgICAgICAgICBDb21waWxlQ2h1bmsgY2MgPSBjb21waWxlQ2h1bmtzW2NpXTsKICAgICAgICAgICAgU2V0PFVSST4gcyA9IHBrZ1NyY3MuZ2V0KHBrZ05hbWUpOwogICAgICAgICAgICBpZiAoY2Muc3Jjcy5zaXplKCkrcy5zaXplKCkgPiBzb3VyY2VzUGVyQ29tcGlsZSAmJiBjaSA8IG51bUNvbXBpbGVzLTEpIHsKICAgICAgICAgICAgICAgIGZyb20gPSBudWxsOwogICAgICAgICAgICAgICAgY2krKzsKICAgICAgICAgICAgICAgIGNjID0gY29tcGlsZUNodW5rc1tjaV07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY2MubnVtUGFja2FnZXMrKzsKICAgICAgICAgICAgY2Muc3Jjcy5hZGRBbGwocyk7CgogICAgICAgICAgICAvLyBDYWxjdWxhdGUgbmljZSBwYWNrYWdlIG5hbWVzIHRvIHVzZSBhcyBpbmZvcm1hdGlvbiB3aGVuIGNvbXBpbGluZy4KICAgICAgICAgICAgU3RyaW5nIGp1c3RQa2dOYW1lID0gVXRpbC5qdXN0UGFja2FnZU5hbWUocGtnTmFtZSk7CiAgICAgICAgICAgIC8vIEZldGNoIGhvdyBtYW55IHBhY2thZ2VzIGRlcGVuZCBvbiB0aGlzIHBhY2thZ2UgZnJvbSB0aGUgb2xkIGJ1aWxkIHN0YXRlLgogICAgICAgICAgICBTZXQ8U3RyaW5nPiBzcyA9IG9sZFBhY2thZ2VEZXBlbmRlbnRzLmdldChwa2dOYW1lKTsKICAgICAgICAgICAgaWYgKHNzICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIC8vIEFjY3VtdWxhdGUgdGhpcyBpbmZvcm1hdGlvbiBvbnRvIHRoaXMgY2h1bmsuCiAgICAgICAgICAgICAgICBjYy5udW1EZXBlbmRlbnRzICs9IHNzLnNpemUoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoZnJvbSA9PSBudWxsIHx8IGZyb20udHJpbSgpLmVxdWFscygiIikpIGZyb20gPSBqdXN0UGtnTmFtZTsKICAgICAgICAgICAgY2MucGtnTmFtZXMuYXBwZW5kKGp1c3RQa2dOYW1lKyIoIitzLnNpemUoKSsiKSAiKTsKICAgICAgICAgICAgY2MucGtnRnJvbVRvcyA9IGZyb20rIiB0byAiK2p1c3RQa2dOYW1lOwogICAgICAgIH0KICAgICAgICAvLyBJZiB3ZSBhcmUgY29tcGlsaW5nIHNlcmlhbGx5LCBzb3J0IHRoZSBjaHVua3MsIHNvIHRoYXQgdGhlIGNodW5rICh3aXRoIHRoZSBtb3N0IGRlcGVuZGVudHMpICh1c3VhbGx5IHRoZSBjaHVuawogICAgICAgIC8vIGNvbnRhaW5pbmcgamF2YS5sYW5nLk9iamVjdCwgaXMgdG8gYmUgY29tcGlsZWQgZmlyc3QhCiAgICAgICAgLy8gRm9yIGNvbmN1cnJlbnQgY29tcGlsYXRpb24sIHRoaXMgZG9lcyBub3QgbWF0dGVyLgogICAgICAgIEFycmF5cy5zb3J0KGNvbXBpbGVDaHVua3MpOwogICAgICAgIHJldHVybiBjb21waWxlQ2h1bmtzOwogICAgfQp9ClBLAwQKAAAIAAAGO6lKAAAAAAAAAAAAAAAAGgAAAGNvbS9zdW4vdG9vbHMvc2phdmFjL2NvbXAvUEsDBAoAAAgAAAY7qUq9RRBz2woAANsKAAAqAAAAY29tL3N1bi90b29scy9zamF2YWMvY29tcC9TbWFydFdyaXRlci5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDEyLCAyMDE2LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuc2phdmFjLmNvbXA7CgppbXBvcnQgY29tLnN1bi50b29scy5zamF2YWMuTG9nOwoKaW1wb3J0IGphdmEuaW8uKjsKaW1wb3J0IGphdmF4LnRvb2xzLkphdmFGaWxlT2JqZWN0OwoKLyoqCiAqIFRoZSBTbWFydFdyaXRlciB3aWxsIGNhY2hlIHRoZSB3cml0dGVuIGRhdGEgYW5kIHdoZW4gdGhlIHdyaXRlciBpcyBjbG9zZWQsCiAqIHRoZW4gaXQgd2lsbCBjb21wYXJlIHRoZSBjYWNoZWQgZGF0YSB3aXRoIHRoZSBvbGRfY29udGVudCBzdHJpbmcuCiAqIElmIGRpZmZlcmVudCwgdGhlbiBpdCB3aWxsIHdyaXRlIGFsbCB0aGUgbmV3IGNvbnRlbnQgdG8gdGhlIGZpbGUuCiAqIElmIG5vdCwgdGhlIGZpbGUgaXMgbm90IHRvdWNoZWQuCiAqCiAqICA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiAgSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93biByaXNrLgogKiAgVGhpcyBjb2RlIGFuZCBpdHMgaW50ZXJuYWwgaW50ZXJmYWNlcyBhcmUgc3ViamVjdCB0byBjaGFuZ2Ugb3IKICogIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj4KICovCnB1YmxpYyBjbGFzcyBTbWFydFdyaXRlciBleHRlbmRzIFdyaXRlciB7CgogICAgU3RyaW5nIG5hbWU7CiAgICBKYXZhRmlsZU9iamVjdCBmaWxlOwogICAgU3RyaW5nIG9sZENvbnRlbnQ7CiAgICBTdHJpbmdXcml0ZXIgbmV3Q29udGVudCA9IG5ldyBTdHJpbmdXcml0ZXIoKTsKICAgIGJvb2xlYW4gY2xvc2VkOwoKICAgIHB1YmxpYyBTbWFydFdyaXRlcihKYXZhRmlsZU9iamVjdCBmLCBTdHJpbmcgcywgU3RyaW5nIG4pIHsKICAgICAgICBuYW1lID0gbjsKICAgICAgICBmaWxlID0gZjsKICAgICAgICBvbGRDb250ZW50ID0gczsKICAgICAgICBuZXdDb250ZW50ID0gbmV3IFN0cmluZ1dyaXRlcigpOwogICAgICAgIGNsb3NlZCA9IGZhbHNlOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHdyaXRlKGNoYXJbXSBjaGFycywgaW50IGksIGludCBpMSkgewogICAgICAgIG5ld0NvbnRlbnQud3JpdGUoY2hhcnMsIGksIGkxKTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGNsb3NlZCkgcmV0dXJuOwogICAgICAgIGNsb3NlZCA9IHRydWU7CiAgICAgICAgU3RyaW5nIHMgPSBuZXdDb250ZW50LnRvU3RyaW5nKCk7CiAgICAgICAgaWYgKCFvbGRDb250ZW50LmVxdWFscyhzKSkgewogICAgICAgICAgICBpbnQgcCA9IGZpbGUuZ2V0TmFtZSgpLmxhc3RJbmRleE9mKEZpbGUuc2VwYXJhdG9yQ2hhcik7CiAgICAgICAgICAgIHRyeSAoV3JpdGVyIHdyaXRlciA9IGZpbGUub3BlbldyaXRlcigpKSB7CiAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGUocyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgTG9nLmRlYnVnKCJXcml0aW5nICIgKyBmaWxlLmdldE5hbWUoKS5zdWJzdHJpbmcocCArIDEpKTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHZvaWQgZmx1c2goKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgfQp9ClBLAwQKAAAIAAAGO6lKAAAAAAAAAAAAAAAAJwAAAGNvbS9zdW4vdG9vbHMvc2phdmFjL2NvbXAvZGVwZW5kZW5jaWVzL1BLAwQKAAAIAAAGO6lKbkkWRgkRAAAJEQAAPgAAAGNvbS9zdW4vdG9vbHMvc2phdmFjL2NvbXAvZGVwZW5kZW5jaWVzL1B1YmxpY0FwaUNvbGxlY3Rvci5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDE0LCAyMDE1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuc2phdmFjLmNvbXAuZGVwZW5kZW5jaWVzOwoKaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uOwppbXBvcnQgamF2YS51dGlsLkhhc2hTZXQ7CmltcG9ydCBqYXZhLnV0aWwuTWFwOwppbXBvcnQgamF2YS51dGlsLlNldDsKCmltcG9ydCBqYXZheC50b29scy5KYXZhRmlsZU9iamVjdDsKCmltcG9ydCBjb20uc3VuLnNvdXJjZS50cmVlLlRyZWU7CmltcG9ydCBjb20uc3VuLnNvdXJjZS51dGlsLlRhc2tFdmVudDsKaW1wb3J0IGNvbS5zdW4uc291cmNlLnV0aWwuVGFza0xpc3RlbmVyOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlN5bWJvbC5DbGFzc1N5bWJvbDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5KQ1RyZWUuSkNDbGFzc0RlY2w7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuSkNUcmVlLkpDQ29tcGlsYXRpb25Vbml0OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkNvbnRleHQ7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuRGVmaW5lZEJ5OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkRlZmluZWRCeS5BcGk7CmltcG9ydCBjb20uc3VuLnRvb2xzLnNqYXZhYy5Mb2c7CmltcG9ydCBjb20uc3VuLnRvb2xzLnNqYXZhYy5jb21wLlB1YkFQSXM7CmltcG9ydCBjb20uc3VuLnRvb2xzLnNqYXZhYy5wdWJhcGkuUHViQXBpOwoKCnB1YmxpYyBjbGFzcyBQdWJsaWNBcGlDb2xsZWN0b3IgaW1wbGVtZW50cyBUYXNrTGlzdGVuZXIgewoKICAgIHByaXZhdGUgQ29udGV4dCBjb250ZXh0OwogICAgcHJpdmF0ZSBmaW5hbCBTZXQ8Q2xhc3NTeW1ib2w+IGNsYXNzU3ltYm9scyA9IG5ldyBIYXNoU2V0PD4oKTsKICAgIHByaXZhdGUgZmluYWwgQ29sbGVjdGlvbjxKYXZhRmlsZU9iamVjdD4gZXhwbGljaXRKRk9zOwoKICAgIC8vIFJlc3VsdCBjb2xsZWN0ZWQgdXBvbiBjb21waWxhdGlvbiB0YXNrIGZpbmlzaGVkCiAgICBwcml2YXRlIE1hcDxTdHJpbmcsIFB1YkFwaT4gZXhwbGljaXRQdWJBcGlzOwogICAgcHJpdmF0ZSBNYXA8U3RyaW5nLCBQdWJBcGk+IG5vbkV4cGxpY2l0UHViQXBpczsKCiAgICBwdWJsaWMgUHVibGljQXBpQ29sbGVjdG9yKENvbnRleHQgY29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29sbGVjdGlvbjxKYXZhRmlsZU9iamVjdD4gZXhwbGljaXRKRk9zKSB7CiAgICAgICAgdGhpcy5jb250ZXh0ID0gY29udGV4dDsKICAgICAgICB0aGlzLmV4cGxpY2l0SkZPcyA9IGV4cGxpY2l0SkZPczsKICAgIH0KCiAgICBAT3ZlcnJpZGUKICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICBwdWJsaWMgdm9pZCBmaW5pc2hlZChUYXNrRXZlbnQgZSkgewogICAgICAgIHN3aXRjaCAoZS5nZXRLaW5kKCkpIHsKICAgICAgICBjYXNlIEFOQUxZWkU6CiAgICAgICAgICAgIGNvbGxlY3RDbGFzc1N5bWJvbHMoKEpDQ29tcGlsYXRpb25Vbml0KSBlLmdldENvbXBpbGF0aW9uVW5pdCgpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBDT01QSUxBVElPTjoKICAgICAgICAgICAgTG9nLmRlYnVnKCJDb21waWxhdGlvbiBmaW5pc2hlZCIpOwogICAgICAgICAgICBMb2cuZGVidWcoIkV4dHJhY3RpbmcgcHViIEFQSXMgZm9yIHRoZSBmb2xsb3dpbmcgc3ltYm9sczoiKTsKICAgICAgICAgICAgZm9yIChDbGFzc1N5bWJvbCBjcyA6IGNsYXNzU3ltYm9scykKICAgICAgICAgICAgICAgIExvZy5kZWJ1ZygiICAgICIgKyBjcy5mdWxsbmFtZSk7CiAgICAgICAgICAgIGV4dHJhY3RQdWJBcGlzKCk7CgogICAgICAgICAgICAvLyBTYXZlIHJlc3VsdCBmb3IgbGF0ZXIgcmV0cmlldmFsLiAoSW1wb3J0YW50IHRoYXQgd2UgZG8gdGhpcwogICAgICAgICAgICAvLyBiZWZvcmUgd2UgcmV0dXJuIGZyb20gdGhpcyBtZXRob2QsIGJlY2F1c2Ugd2UgbWF5IG5vdCBhY2Nlc3MKICAgICAgICAgICAgLy8gc3ltYm9scyBhZnRlciBjb21waWxhdGlvbiBpcyBmaW5pc2hlZC4pCiAgICAgICAgICAgIFB1YkFQSXMgcGEgPSBQdWJBUElzLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgICAgICBleHBsaWNpdFB1YkFwaXMgPSBwYS5nZXRQdWJhcGlzKGV4cGxpY2l0SkZPcywgdHJ1ZSk7CiAgICAgICAgICAgIG5vbkV4cGxpY2l0UHViQXBpcyA9IHBhLmdldFB1YmFwaXMoZXhwbGljaXRKRk9zLCBmYWxzZSk7CgogICAgICAgICAgICBMb2cuZGVidWcoImRvbmUiKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgdm9pZCBjb2xsZWN0Q2xhc3NTeW1ib2xzKEpDQ29tcGlsYXRpb25Vbml0IGN1KSB7CiAgICAgICAgZm9yIChUcmVlIHQgOiBjdS5nZXRUeXBlRGVjbHMoKSkgewogICAgICAgICAgICBpZiAodCBpbnN0YW5jZW9mIEpDQ2xhc3NEZWNsKSAgLy8gQ2FuIGFsc28gYmUgYSBKQ1NraXAKICAgICAgICAgICAgICAgIGNsYXNzU3ltYm9scy5hZGQoKChKQ0NsYXNzRGVjbCkgdCkuc3ltKTsKICAgICAgICB9CiAgICB9CgogICAgcHJpdmF0ZSB2b2lkIGV4dHJhY3RQdWJBcGlzKCkgewogICAgICAgIC8vIFRvIGhhbmRsZSBpbmNyZW1lbnRhbCBidWlsZHMgKHN1YnNlcXVlbnQgc2phdmFjIGludm9jYXRpb25zKSB3ZSBuZWVkCiAgICAgICAgLy8gdG8ga2VlcCB0cmFjayBvZiB0aGUgcHVibGljIEFQSSBvZiB3aGF0IHdlIGRlcGVuZCB1cG9uLgogICAgICAgIC8vCiAgICAgICAgLy8gRHVyaW5nIHRoZSByZWNvbXBpbGF0aW9uIGxvb3AgKHdpdGhpbiBhIHNpbmdsZSBzamF2YWMgaW52b2NhdGlvbikgd2UKICAgICAgICAvLyBuZWVkIHRvIGtlZXAgdHJhY2sgb2YgcHVibGljIEFQSSBvZiB3aGF0IHdlJ3JlIGNvbXBpbGluZyB0byBkZWNpZGUgaWYKICAgICAgICAvLyBhbnkgZGVwZW5kYW50cyBuZWVkcyB0byBiZSB0YWludGVkLgogICAgICAgIFB1YkFQSXMgcHViQXBpcyA9IFB1YkFQSXMuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgY2xhc3NTeW1ib2xzLmZvckVhY2gocHViQXBpczo6dmlzaXRQdWJhcGkpOwogICAgfQoKICAgIHB1YmxpYyBNYXA8U3RyaW5nLCBQdWJBcGk+IGdldFB1YkFwaXMoYm9vbGVhbiBleHBsaWNpdCkgewogICAgICAgIHJldHVybiBleHBsaWNpdCA/IGV4cGxpY2l0UHViQXBpcyA6IG5vbkV4cGxpY2l0UHViQXBpczsKICAgIH0KfQpQSwMECgAACAAABjupSsBDB7lLIAAASyAAAEIAAABjb20vc3VuL3Rvb2xzL3NqYXZhYy9jb21wL2RlcGVuZGVuY2llcy9OZXdEZXBlbmRlbmN5Q29sbGVjdG9yLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5zamF2YWMuY29tcC5kZXBlbmRlbmNpZXM7CgppbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb247CmltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbnM7CmltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKaW1wb3J0IGphdmEudXRpbC5IYXNoU2V0OwppbXBvcnQgamF2YS51dGlsLk1hcDsKaW1wb3J0IGphdmEudXRpbC5TZXQ7CmltcG9ydCBqYXZhLnV0aWwuc3RyZWFtLkNvbGxlY3RvcnM7CmltcG9ydCBqYXZhLnV0aWwuc3RyZWFtLlN0cmVhbTsKCmltcG9ydCBqYXZheC50b29scy5KYXZhRmlsZU1hbmFnZXIuTG9jYXRpb247CmltcG9ydCBqYXZheC50b29scy5KYXZhRmlsZU9iamVjdDsKaW1wb3J0IGphdmF4LnRvb2xzLlN0YW5kYXJkTG9jYXRpb247CgppbXBvcnQgY29tLnN1bi5zb3VyY2UudXRpbC5UYXNrRXZlbnQ7CmltcG9ydCBjb20uc3VuLnNvdXJjZS51dGlsLlRhc2tMaXN0ZW5lcjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5LaW5kcy5LaW5kOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlN5bWJvbDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5TeW1ib2wuQ2xhc3NTeW1ib2w7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuU3ltYm9sLlR5cGVTeW1ib2w7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuVHlwZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5Db250ZXh0OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkRlZmluZWRCeTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5EZWZpbmVkQnkuQXBpOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkRlcGVuZGVuY2llcy5HcmFwaERlcGVuZGVuY2llczsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5EZXBlbmRlbmNpZXMuR3JhcGhEZXBlbmRlbmNpZXMuQ29tcGxldGlvbk5vZGU7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuR3JhcGhVdGlscy5Ob2RlOwppbXBvcnQgY29tLnN1bi50b29scy5zamF2YWMuVXRpbDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuc2phdmFjLmNvbXAuSmF2YUZpbGVPYmplY3RXaXRoTG9jYXRpb247CmltcG9ydCBjb20uc3VuLnRvb2xzLnNqYXZhYy5jb21wLlB1YkFQSXM7CgoKcHVibGljIGNsYXNzIE5ld0RlcGVuZGVuY3lDb2xsZWN0b3IgaW1wbGVtZW50cyBUYXNrTGlzdGVuZXIgewoKICAgIHByaXZhdGUgZmluYWwgQ29udGV4dCBjb250ZXh0OwogICAgcHJpdmF0ZSBmaW5hbCBDb2xsZWN0aW9uPEphdmFGaWxlT2JqZWN0PiBleHBsaWNpdEpGT3M7CgogICAgcHJpdmF0ZSBNYXA8U3RyaW5nLCBNYXA8U3RyaW5nLCBTZXQ8U3RyaW5nPj4+IGRlcHM7CiAgICBwcml2YXRlIE1hcDxTdHJpbmcsIE1hcDxTdHJpbmcsIFNldDxTdHJpbmc+Pj4gY3BEZXBzOwoKICAgIHB1YmxpYyBOZXdEZXBlbmRlbmN5Q29sbGVjdG9yKENvbnRleHQgY29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbGxlY3Rpb248SmF2YUZpbGVPYmplY3Q+IGV4cGxpY2l0SkZPcykgewogICAgICAgIHRoaXMuY29udGV4dCA9IGNvbnRleHQ7CiAgICAgICAgdGhpcy5leHBsaWNpdEpGT3MgPSBleHBsaWNpdEpGT3M7CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIHZvaWQgZmluaXNoZWQoVGFza0V2ZW50IGUpIHsKICAgICAgICBpZiAoZS5nZXRLaW5kKCkgPT0gVGFza0V2ZW50LktpbmQuQ09NUElMQVRJT04pIHsKICAgICAgICAgICAgY29sbGVjdFB1YkFwaXNPZkRlcGVuZGVuY2llcyhjb250ZXh0LCBleHBsaWNpdEpGT3MpOwogICAgICAgICAgICBkZXBzID0gZ2V0RGVwZW5kZW5jaWVzKGNvbnRleHQsIGV4cGxpY2l0SkZPcywgZmFsc2UpOwogICAgICAgICAgICBjcERlcHMgPSBnZXREZXBlbmRlbmNpZXMoY29udGV4dCwgZXhwbGljaXRKRk9zLCB0cnVlKTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIE1hcDxTdHJpbmcsIE1hcDxTdHJpbmcsIFNldDxTdHJpbmc+Pj4gZ2V0RGVwZW5kZW5jaWVzKGJvb2xlYW4gY3ApIHsKICAgICAgICByZXR1cm4gY3AgPyBjcERlcHMgOiBkZXBzOwogICAgfQoKICAgIHByaXZhdGUgU2V0PENvbXBsZXRpb25Ob2RlPiBnZXREZXBlbmRlbmN5Tm9kZXMoQ29udGV4dCBjb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb2xsZWN0aW9uPEphdmFGaWxlT2JqZWN0PiBleHBsaWNpdEpGT3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gZXhwbGljaXRzKSB7CiAgICAgICAgR3JhcGhEZXBlbmRlbmNpZXMgZGVwcyA9IChHcmFwaERlcGVuZGVuY2llcykgR3JhcGhEZXBlbmRlbmNpZXMuaW5zdGFuY2UoY29udGV4dCk7CgogICAgICAgIHJldHVybiBkZXBzLmdldE5vZGVzKCkKICAgICAgICAgICAgICAgICAgIC5zdHJlYW0oKQogICAgICAgICAgICAgICAgICAgLm1hcChuIC0+IChDb21wbGV0aW9uTm9kZSkgbikKICAgICAgICAgICAgICAgICAgIC5maWx0ZXIobiAtPiBuLmdldENsYXNzU3ltYm9sKCkuZnVsbG5hbWUgIT0gbnVsbCkKICAgICAgICAgICAgICAgICAgIC5maWx0ZXIobiAtPiBleHBsaWNpdHMgPT0gZXhwbGljaXRKRk9zLmNvbnRhaW5zKG4uZ2V0Q2xhc3NTeW1ib2woKS5jbGFzc2ZpbGUpKQogICAgICAgICAgICAgICAgICAgLmNvbGxlY3QoQ29sbGVjdG9ycy50b1NldCgpKTsKICAgIH0KCiAgICBwcml2YXRlIHZvaWQgY29sbGVjdFB1YkFwaXNPZkRlcGVuZGVuY2llcyhDb250ZXh0IGNvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb2xsZWN0aW9uPEphdmFGaWxlT2JqZWN0PiBleHBsaWNpdEpGT3MpIHsKICAgICAgICBQdWJBUElzIHB1YkFwaXMgPSBQdWJBUElzLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIGZvciAoQ29tcGxldGlvbk5vZGUgY0RlcE5vZGUgOiBnZXREZXBlbmRlbmN5Tm9kZXMoY29udGV4dCwgZXhwbGljaXRKRk9zLCBmYWxzZSkpIHsKICAgICAgICAgICAgQ2xhc3NTeW1ib2wgY3MgPSBjRGVwTm9kZS5nZXRDbGFzc1N5bWJvbCgpLm91dGVybW9zdENsYXNzKCk7CiAgICAgICAgICAgIExvY2F0aW9uIGxvYyA9IGdldExvY2F0aW9uT2YoY3MpOwogICAgICAgICAgICAvLyBXZSdyZSBjb21wbGV0ZWx5IGlnbm9yYW50IG9mIFBMQVRGT1JNX0NMQVNTX1BBVEggY2xhc3NlcwogICAgICAgICAgICBpZiAobG9jID09IFN0YW5kYXJkTG9jYXRpb24uQ0xBU1NfUEFUSCB8fCBsb2MgPT0gU3RhbmRhcmRMb2NhdGlvbi5TT1VSQ0VfUEFUSCkKICAgICAgICAgICAgICAgIHB1YkFwaXMudmlzaXRQdWJhcGkoY3MpOwogICAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIExvY2F0aW9uIGdldExvY2F0aW9uT2YoQ2xhc3NTeW1ib2wgY3MpIHsKICAgICAgICBKYXZhRmlsZU9iamVjdCBqZm8gPSBjcy5vdXRlcm1vc3RDbGFzcygpLmNsYXNzZmlsZTsKICAgICAgICBpZiAoamZvIGluc3RhbmNlb2YgSmF2YUZpbGVPYmplY3RXaXRoTG9jYXRpb24pIHsKICAgICAgICAgICAgcmV0dXJuICgoSmF2YUZpbGVPYmplY3RXaXRoTG9jYXRpb248Pz4pIGpmbykuZ2V0TG9jYXRpb24oKTsKICAgICAgICB9CgogICAgICAgIC8vIGpmbyBpcyBtb3N0IGxpa2VseSBvbiBQTEFURk9STV9DTEFTU19QQVRILgogICAgICAgIC8vIFNlZSBub3RlcyBpbiBTbWFydEZpbGVNYW5hZ2VyOjpsb2NXcmFwCgogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIC8vIDpQYWNrYWdlIC0+IGZ1bGx5IHF1YWxpZmllZCBjbGFzcyBuYW1lIFtmcm9tXSAtPiBzZXQgb2YgZnVsbHkgcXVhbGlmaWVkIGNsYXNzIG5hbWVzIFt0b10KICAgIHByaXZhdGUgTWFwPFN0cmluZywgTWFwPFN0cmluZywgU2V0PFN0cmluZz4+PiBnZXREZXBlbmRlbmNpZXMoQ29udGV4dCBjb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb2xsZWN0aW9uPEphdmFGaWxlT2JqZWN0PiBleHBsaWNpdEpGT3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gY3ApIHsKICAgICAgICBNYXA8U3RyaW5nLCBNYXA8U3RyaW5nLCBTZXQ8U3RyaW5nPj4+IHJlc3VsdCA9IG5ldyBIYXNoTWFwPD4oKTsKCiAgICAgICAgZm9yIChDb21wbGV0aW9uTm9kZSBjbm9kZSA6IGdldERlcGVuZGVuY3lOb2Rlcyhjb250ZXh0LCBleHBsaWNpdEpGT3MsIHRydWUpKSB7CgogICAgICAgICAgICBTdHJpbmcgZnFEZXAgPSBjbm9kZS5nZXRDbGFzc1N5bWJvbCgpLm91dGVybW9zdENsYXNzKCkuZmxhdG5hbWUudG9TdHJpbmcoKTsKICAgICAgICAgICAgU3RyaW5nIGRlcFBrZyA9IFV0aWwucGtnTmFtZU9mQ2xhc3NOYW1lKGZxRGVwKTsKCiAgICAgICAgICAgIE1hcDxTdHJpbmcsIFNldDxTdHJpbmc+PiBkZXBzRm9yVGhpc0NsYXNzID0gcmVzdWx0LmdldChkZXBQa2cpOwogICAgICAgICAgICBpZiAoZGVwc0ZvclRoaXNDbGFzcyA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICByZXN1bHQucHV0KGRlcFBrZywgZGVwc0ZvclRoaXNDbGFzcyA9IG5ldyBIYXNoTWFwPD4oKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIFNldDxTdHJpbmc+IGZxRGVwcyA9IGRlcHNGb3JUaGlzQ2xhc3MuZ2V0KGZxRGVwKTsKICAgICAgICAgICAgaWYgKGZxRGVwcyA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICBkZXBzRm9yVGhpc0NsYXNzLnB1dChmcURlcCwgZnFEZXBzID0gbmV3IEhhc2hTZXQ8PigpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZm9yIChOb2RlPD8sPz4gZGVwTm9kZSA6IGdldEFsbERlcGVuZGVuY2llcyhjbm9kZSkpIHsKICAgICAgICAgICAgICAgIENvbXBsZXRpb25Ob2RlIGNEZXBOb2RlID0gKENvbXBsZXRpb25Ob2RlKSBkZXBOb2RlOwogICAgICAgICAgICAgICAgLy8gU3ltYm9sIGlzIG5vdCByZWdhcmRlZCB0byBkZXBlbmQgb24gaXRzZWxmLgogICAgICAgICAgICAgICAgaWYgKGNEZXBOb2RlID09IGNub2RlKSB7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvLyBTa2lwIGFub255bW91cyBjbGFzc2VzCiAgICAgICAgICAgICAgICBpZiAoY0RlcE5vZGUuZ2V0Q2xhc3NTeW1ib2woKS5mdWxsbmFtZSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoaXNTeW1ib2xSZWxldmFudChjcCwgY0RlcE5vZGUuZ2V0Q2xhc3NTeW1ib2woKSkpIHsKICAgICAgICAgICAgICAgICAgICBmcURlcHMuYWRkKGNEZXBOb2RlLmdldENsYXNzU3ltYm9sKCkub3V0ZXJtb3N0Q2xhc3MoKS5mbGF0bmFtZS50b1N0cmluZygpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gVGhlIGNvbXBsZXRpb24gZGVwZW5kZW5jeSBncmFwaCBpcyBub3QgdHJhbnNpdGl2ZWx5IGNsb3NlZCBmb3IgaW5oZXJpdGFuY2UgcmVsYXRpb25zLgogICAgICAgICAgICAvLyBGb3Igc2phdmFjJ3MgcHVycG9zZXMgaG93ZXZlciwgYSBjbGFzcyBkZXBlbmRzIG9uIGl0J3Mgc3VwZXIgc3VwZXIgdHlwZSwgc28gYmVsb3cgd2UKICAgICAgICAgICAgLy8gbWFrZSBzdXJlIHRoYXQgd2UgaW5jbHVkZSBzdXBlciB0eXBlcy4KICAgICAgICAgICAgZm9yIChDbGFzc1N5bWJvbCBjcyA6IGFsbFN1cGVydHlwZXMoY25vZGUuZ2V0Q2xhc3NTeW1ib2woKSkpIHsKICAgICAgICAgICAgICAgIGlmIChpc1N5bWJvbFJlbGV2YW50KGNwLCBjcykpIHsKICAgICAgICAgICAgICAgICAgICBmcURlcHMuYWRkKGNzLm91dGVybW9zdENsYXNzKCkuZmxhdG5hbWUudG9TdHJpbmcoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9CgogICAgcHVibGljIGJvb2xlYW4gaXNTeW1ib2xSZWxldmFudChib29sZWFuIGNwLCBDbGFzc1N5bWJvbCBjcykgewogICAgICAgIExvY2F0aW9uIGNzTG9jID0gZ2V0TG9jYXRpb25PZihjcyk7CiAgICAgICAgTG9jYXRpb24gcmVsZXZhbnRMb2NhdGlvbiA9IGNwID8gU3RhbmRhcmRMb2NhdGlvbi5DTEFTU19QQVRIIDogU3RhbmRhcmRMb2NhdGlvbi5TT1VSQ0VfUEFUSDsKICAgICAgICByZXR1cm4gY3NMb2MgPT0gcmVsZXZhbnRMb2NhdGlvbjsKICAgIH0KCiAgICBwcml2YXRlIFNldDxDbGFzc1N5bWJvbD4gYWxsU3VwZXJ0eXBlcyhUeXBlU3ltYm9sIHQpIHsKICAgICAgICBpZiAodCA9PSBudWxsIHx8ICEodCBpbnN0YW5jZW9mIENsYXNzU3ltYm9sKSkgewogICAgICAgICAgICByZXR1cm4gQ29sbGVjdGlvbnMuZW1wdHlTZXQoKTsKICAgICAgICB9CiAgICAgICAgU2V0PENsYXNzU3ltYm9sPiByZXN1bHQgPSBuZXcgSGFzaFNldDw+KCk7CiAgICAgICAgQ2xhc3NTeW1ib2wgY3MgPSAoQ2xhc3NTeW1ib2wpIHQ7CiAgICAgICAgcmVzdWx0LmFkZChjcyk7CiAgICAgICAgcmVzdWx0LmFkZEFsbChhbGxTdXBlcnR5cGVzKGNzLmdldFN1cGVyY2xhc3MoKS50c3ltKSk7CiAgICAgICAgZm9yIChUeXBlIGl0IDogY3MuZ2V0SW50ZXJmYWNlcygpKSB7CiAgICAgICAgICAgIHJlc3VsdC5hZGRBbGwoYWxsU3VwZXJ0eXBlcyhpdC50c3ltKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9CgogICAgcHJpdmF0ZSBDb2xsZWN0aW9uPD8gZXh0ZW5kcyBOb2RlPD8sID8+PiBnZXRBbGxEZXBlbmRlbmNpZXMoQ29tcGxldGlvbk5vZGUgY25vZGUpIHsKICAgICAgICByZXR1cm4gU3RyZWFtLm9mKGNub2RlLmdldFN1cHBvcnRlZERlcGVuZGVuY3lLaW5kcygpKQogICAgICAgICAgICAgICAgICAgICAuZmxhdE1hcChkayAtPiBjbm9kZS5nZXREZXBlbmRlbmNpZXNCeUtpbmQoZGspLnN0cmVhbSgpKQogICAgICAgICAgICAgICAgICAgICAuY29sbGVjdChDb2xsZWN0b3JzLnRvU2V0KCkpOwogICAgfQp9ClBLAwQKAAAIAAAGO6lKQDAgSooNAACKDQAAKwAAAGNvbS9zdW4vdG9vbHMvc2phdmFjL2NvbXAvUG9vbGVkU2phdmFjLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTQsIDIwMTYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5zamF2YWMuY29tcDsKCmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLm1haW4uTWFpbi5SZXN1bHQ7CmltcG9ydCBjb20uc3VuLnRvb2xzLnNqYXZhYy5Mb2c7CmltcG9ydCBjb20uc3VuLnRvb2xzLnNqYXZhYy5zZXJ2ZXIuU2phdmFjOwoKaW1wb3J0IGphdmEudXRpbC5PYmplY3RzOwppbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuRXhlY3V0b3JTZXJ2aWNlOwppbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuRXhlY3V0b3JzOwppbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGltZVVuaXQ7CgovKioKICogQW4gc2phdmFjIGltcGxlbWVudGF0aW9uIHRoYXQgbGltaXRzIHRoZSBudW1iZXIgb2YgY29uY3VycmVudCBjYWxscyBieQogKiB3cmFwcGluZyBpbnZvY2F0aW9ucyBpbiBDYWxsYWJsZXMgYW5kIGRlbGVnYXRpbmcgdGhlbSB0byBhIEZpeGVkVGhyZWFkUG9vbC4KICoKICogIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqICBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqICBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogKiAgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPgogKi8KcHVibGljIGNsYXNzIFBvb2xlZFNqYXZhYyBpbXBsZW1lbnRzIFNqYXZhYyB7CgogICAgZmluYWwgU2phdmFjIGRlbGVnYXRlOwogICAgZmluYWwgRXhlY3V0b3JTZXJ2aWNlIHBvb2w7CgogICAgcHVibGljIFBvb2xlZFNqYXZhYyhTamF2YWMgZGVsZWdhdGUsIGludCBwb29sc2l6ZSkgewogICAgICAgIE9iamVjdHMucmVxdWlyZU5vbk51bGwoZGVsZWdhdGUpOwogICAgICAgIHRoaXMuZGVsZWdhdGUgPSBkZWxlZ2F0ZTsKICAgICAgICBwb29sID0gRXhlY3V0b3JzLm5ld0ZpeGVkVGhyZWFkUG9vbChwb29sc2l6ZSk7CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgUmVzdWx0IGNvbXBpbGUoU3RyaW5nW10gYXJncykgewogICAgICAgIExvZyBsb2cgPSBMb2cuZ2V0KCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgcmV0dXJuIHBvb2wuc3VibWl0KCgpIC0+IHsKICAgICAgICAgICAgICAgIExvZy5zZXRMb2dGb3JDdXJyZW50VGhyZWFkKGxvZyk7CiAgICAgICAgICAgICAgICByZXR1cm4gZGVsZWdhdGUuY29tcGlsZShhcmdzKTsKICAgICAgICAgICAgfSkuZ2V0KCk7CiAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIkVycm9yIGR1cmluZyBjb21waWxlIiwgZSk7CiAgICAgICAgfQogICAgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIHZvaWQgc2h1dGRvd24oKSB7CiAgICAgICAgTG9nLmRlYnVnKCJTaHV0dGluZyBkb3duIFBvb2xlZFNqYXZhYyIpOwogICAgICAgIHBvb2wuc2h1dGRvd24oKTsgLy8gRGlzYWJsZSBuZXcgdGFza3MgZnJvbSBiZWluZyBzdWJtaXR0ZWQKICAgICAgICB0cnkgewogICAgICAgICAgICAvLyBXYWl0IGEgd2hpbGUgZm9yIGV4aXN0aW5nIHRhc2tzIHRvIHRlcm1pbmF0ZQogICAgICAgICAgICBpZiAoIXBvb2wuYXdhaXRUZXJtaW5hdGlvbig2MCwgVGltZVVuaXQuU0VDT05EUykpIHsKICAgICAgICAgICAgICAgIHBvb2wuc2h1dGRvd25Ob3coKTsgLy8gQ2FuY2VsIGN1cnJlbnRseSBleGVjdXRpbmcgdGFza3MKICAgICAgICAgICAgICAgIC8vIFdhaXQgYSB3aGlsZSBmb3IgdGFza3MgdG8gcmVzcG9uZCB0byBiZWluZyBjYW5jZWxsZWQKICAgICAgICAgICAgICAgIGlmICghcG9vbC5hd2FpdFRlcm1pbmF0aW9uKDYwLCBUaW1lVW5pdC5TRUNPTkRTKSkKICAgICAgICAgICAgICAgICAgICBMb2cuZXJyb3IoIlRocmVhZFBvb2wgZGlkIG5vdCB0ZXJtaW5hdGUiKTsKICAgICAgICAgICAgfQogICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGllKSB7CiAgICAgICAgICAvLyAoUmUtKUNhbmNlbCBpZiBjdXJyZW50IHRocmVhZCBhbHNvIGludGVycnVwdGVkCiAgICAgICAgICBwb29sLnNodXRkb3duTm93KCk7CiAgICAgICAgICAvLyBQcmVzZXJ2ZSBpbnRlcnJ1cHQgc3RhdHVzCiAgICAgICAgICBUaHJlYWQuY3VycmVudFRocmVhZCgpLmludGVycnVwdCgpOwogICAgICAgIH0KCiAgICAgICAgZGVsZWdhdGUuc2h1dGRvd24oKTsKICAgIH0KCn0KUEsDBAoAAAgAAAY7qUozkAqrAhUAAAIVAAA1AAAAY29tL3N1bi90b29scy9zamF2YWMvY29tcC9QYXRoQW5kUGFja2FnZVZlcmlmaWVyLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTQsIDIwMTUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5zamF2YWMuY29tcDsKCmltcG9ydCBqYXZhLm5pby5maWxlLlBhdGg7CmltcG9ydCBqYXZhLm5pby5maWxlLlBhdGhzOwppbXBvcnQgamF2YS51dGlsLkhhc2hTZXQ7CmltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CmltcG9ydCBqYXZhLnV0aWwuU2V0OwoKaW1wb3J0IGphdmF4LnRvb2xzLkphdmFGaWxlT2JqZWN0OwoKaW1wb3J0IGNvbS5zdW4uc291cmNlLnRyZWUuQ29tcGlsYXRpb25Vbml0VHJlZTsKaW1wb3J0IGNvbS5zdW4uc291cmNlLnV0aWwuVGFza0V2ZW50OwppbXBvcnQgY29tLnN1bi5zb3VyY2UudXRpbC5UYXNrTGlzdGVuZXI7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuSkNUcmVlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkpDVHJlZS5KQ0ZpZWxkQWNjZXNzOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkpDVHJlZS5KQ0lkZW50OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkRlZmluZWRCeTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5EZWZpbmVkQnkuQXBpOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLk5hbWU7CmltcG9ydCBjb20uc3VuLnRvb2xzLnNqYXZhYy5Mb2c7CgpwdWJsaWMgY2xhc3MgUGF0aEFuZFBhY2thZ2VWZXJpZmllciBpbXBsZW1lbnRzIFRhc2tMaXN0ZW5lciB7CgogICAgLy8gU3RvcmVzIHRoZSBzZXQgb2YgY29tcGlsYXRpb24gdW5pdHMgd2hvc2Ugc291cmNlIGZpbGUgcGF0aCBkb2VzIG5vdAogICAgLy8gbWF0Y2ggdGhlIHBhY2thZ2UgZGVjbGFyYXRpb24uCiAgICBTZXQ8Q29tcGlsYXRpb25Vbml0VHJlZT4gbWlzcGxhY2VkQ29tcGlsYXRpb25Vbml0cyA9IG5ldyBIYXNoU2V0PD4oKTsKCiAgICBAT3ZlcnJpZGUKICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICBwdWJsaWMgdm9pZCBmaW5pc2hlZChUYXNrRXZlbnQgZSkgewogICAgICAgIGlmIChlLmdldEtpbmQoKSA9PSBUYXNrRXZlbnQuS2luZC5BTkFMWVpFKSB7CgogICAgICAgICAgICBDb21waWxhdGlvblVuaXRUcmVlIGN1ID0gZS5nZXRDb21waWxhdGlvblVuaXQoKTsKICAgICAgICAgICAgaWYgKGN1ID09IG51bGwpCiAgICAgICAgICAgICAgICByZXR1cm47CgogICAgICAgICAgICBKYXZhRmlsZU9iamVjdCBqZm8gPSBjdS5nZXRTb3VyY2VGaWxlKCk7CiAgICAgICAgICAgIGlmIChqZm8gPT0gbnVsbCkKICAgICAgICAgICAgICAgIHJldHVybjsgLy8gTm8gc291cmNlIGZpbGUgLT4gcGFja2FnZSBkb2Vzbid0IG1hdHRlcgoKICAgICAgICAgICAgSkNUcmVlIHBrZyA9IChKQ1RyZWUpIGN1LmdldFBhY2thZ2VOYW1lKCk7CiAgICAgICAgICAgIGlmIChwa2cgPT0gbnVsbCkKICAgICAgICAgICAgICAgIHJldHVybjsgLy8gRGVmYXVsdCBwYWNrYWdlLiBTZWUgSkRLLTgwNDgxNDQuCgogICAgICAgICAgICBQYXRoIGRpciA9IFBhdGhzLmdldChqZm8udG9VcmkoKSkubm9ybWFsaXplKCkuZ2V0UGFyZW50KCk7CiAgICAgICAgICAgIGlmICghY2hlY2tQYXRoQW5kUGFja2FnZShkaXIsIHBrZykpCiAgICAgICAgICAgICAgICBtaXNwbGFjZWRDb21waWxhdGlvblVuaXRzLmFkZChjdSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoZS5nZXRLaW5kKCkgPT0gVGFza0V2ZW50LktpbmQuQ09NUElMQVRJT04pIHsKICAgICAgICAgICAgZm9yIChDb21waWxhdGlvblVuaXRUcmVlIGN1IDogbWlzcGxhY2VkQ29tcGlsYXRpb25Vbml0cykgewogICAgICAgICAgICAgICAgTG9nLmVycm9yKCJNaXNwbGFjZWQgY29tcGlsYXRpb24gdW5pdC4iKTsKICAgICAgICAgICAgICAgIExvZy5lcnJvcigiICAgIERpcmVjdG9yeTogIiArIFBhdGhzLmdldChjdS5nZXRTb3VyY2VGaWxlKCkudG9VcmkoKSkuZ2V0UGFyZW50KCkpOwogICAgICAgICAgICAgICAgTG9nLmVycm9yKCIgICAgUGFja2FnZTogICAiICsgY3UuZ2V0UGFja2FnZU5hbWUoKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgcHVibGljIGJvb2xlYW4gZXJyb3JzRGlzY292ZXJlZCgpIHsKICAgICAgICByZXR1cm4gbWlzcGxhY2VkQ29tcGlsYXRpb25Vbml0cy5zaXplKCkgPiAwOwogICAgfQoKICAgIC8qIFJldHVybnMgdHJ1ZSBpZiBkaXIgbWF0Y2hlcyBwa2dOYW1lLgogICAgICoKICAgICAqIEV4YW1wbGVzOgogICAgICogICAgIChhL2IvYywgYS5iLmMpIGdpdmVzIHRydWUKICAgICAqICAgICAoaS9qL2ssIGkueC5rKSBnaXZlcyBmYWxzZQogICAgICoKICAgICAqIEN1cnJlbnRseSAoeC9hL2IvYywgYS5iLmMpIGFsc28gZ2l2ZXMgdHJ1ZS4gU2VlIEpESy04MDU5NTk4LgogICAgICovCiAgICBwcml2YXRlIGJvb2xlYW4gY2hlY2tQYXRoQW5kUGFja2FnZShQYXRoIGRpciwgSkNUcmVlIHBrZ05hbWUpIHsKICAgICAgICBJdGVyYXRvcjxTdHJpbmc+IHBhdGhJdGVyID0gbmV3IFBhcmVudEl0ZXJhdG9yKGRpcik7CiAgICAgICAgSXRlcmF0b3I8U3RyaW5nPiBwa2dJdGVyID0gbmV3IEVuY2xvc2luZ1BrZ0l0ZXJhdG9yKHBrZ05hbWUpOwogICAgICAgIHdoaWxlIChwYXRoSXRlci5oYXNOZXh0KCkgJiYgcGtnSXRlci5oYXNOZXh0KCkpIHsKICAgICAgICAgICAgaWYgKCFwYXRoSXRlci5uZXh0KCkuZXF1YWxzKHBrZ0l0ZXIubmV4dCgpKSkKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuICFwa2dJdGVyLmhhc05leHQoKTsgLyomJiAhcGF0aEl0ZXIuaGFzTmV4dCgpIFNlZSBKREstODA1OTU5OCAqLwogICAgfQoKICAgIC8qIEl0ZXJhdGVzIG92ZXIgdGhlIG5hbWVzIG9mIHRoZSBwYXJlbnRzIG9mIHRoZSBnaXZlbiBwYXRoOgogICAgICogRXhhbXBsZTogZGlyMS9kaXIyL2RpcjMgIHJlc3VsdHMgaW4gIGRpcjMgLT4gZGlyMiAtPiBkaXIxCiAgICAgKi8KICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIFBhcmVudEl0ZXJhdG9yIGltcGxlbWVudHMgSXRlcmF0b3I8U3RyaW5nPiB7CiAgICAgICAgUGF0aCBuZXh0OwogICAgICAgIFBhcmVudEl0ZXJhdG9yKFBhdGggaW5pdGlhbCkgewogICAgICAgICAgICBuZXh0ID0gaW5pdGlhbDsKICAgICAgICB9CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzTmV4dCgpIHsKICAgICAgICAgICAgcmV0dXJuIG5leHQgIT0gbnVsbDsKICAgICAgICB9CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFN0cmluZyBuZXh0KCkgewogICAgICAgICAgICBTdHJpbmcgdG1wID0gbmV4dC5nZXRGaWxlTmFtZSgpLnRvU3RyaW5nKCk7CiAgICAgICAgICAgIG5leHQgPSBuZXh0LmdldFBhcmVudCgpOwogICAgICAgICAgICByZXR1cm4gdG1wOwogICAgICAgIH0KICAgIH0KCiAgICAvKiBJdGVyYXRlcyBvdmVyIHRoZSBuYW1lcyBvZiB0aGUgZW5jbG9zaW5nIHBhY2thZ2VzOgogICAgICogRXhhbXBsZTogcGtnMS5wa2cyLnBrZzMgIHJlc3VsdHMgaW4gIHBrZzMgLT4gcGtnMiAtPiBwa2cxCiAgICAgKi8KICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIEVuY2xvc2luZ1BrZ0l0ZXJhdG9yIGltcGxlbWVudHMgSXRlcmF0b3I8U3RyaW5nPiB7CiAgICAgICAgSkNUcmVlIG5leHQ7CiAgICAgICAgRW5jbG9zaW5nUGtnSXRlcmF0b3IoSkNUcmVlIGluaXRpYWwpIHsKICAgICAgICAgICAgbmV4dCA9IGluaXRpYWw7CiAgICAgICAgfQogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBib29sZWFuIGhhc05leHQoKSB7CiAgICAgICAgICAgIHJldHVybiBuZXh0ICE9IG51bGw7CiAgICAgICAgfQogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBTdHJpbmcgbmV4dCgpIHsKICAgICAgICAgICAgTmFtZSBuYW1lOwogICAgICAgICAgICBpZiAobmV4dCBpbnN0YW5jZW9mIEpDSWRlbnQpIHsKICAgICAgICAgICAgICAgIG5hbWUgPSAoKEpDSWRlbnQpIG5leHQpLm5hbWU7CiAgICAgICAgICAgICAgICBuZXh0ID0gbnVsbDsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIEpDRmllbGRBY2Nlc3MgZmEgPSAoSkNGaWVsZEFjY2VzcykgbmV4dDsKICAgICAgICAgICAgICAgIG5hbWUgPSBmYS5uYW1lOwogICAgICAgICAgICAgICAgbmV4dCA9IGZhLnNlbGVjdGVkOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBuYW1lLnRvU3RyaW5nKCk7CiAgICAgICAgfQogICAgfQp9ClBLAwQKAAAIAAAGO6lKCKJuUVUpAABVKQAALwAAAGNvbS9zdW4vdG9vbHMvc2phdmFjL2NvbXAvU21hcnRGaWxlTWFuYWdlci5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDEyLCAyMDE3LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuc2phdmFjLmNvbXA7CgppbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKaW1wb3J0IGphdmEuaW8uUHJpbnRXcml0ZXI7CmltcG9ydCBqYXZhLm5ldC5VUkk7CmltcG9ydCBqYXZhLm5pby5maWxlLlBhdGg7CmltcG9ydCBqYXZhLm5pby5maWxlLlBhdGhzOwppbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CmltcG9ydCBqYXZhLnV0aWwuSGFzaFNldDsKaW1wb3J0IGphdmEudXRpbC5NYXA7CmltcG9ydCBqYXZhLnV0aWwuU2V0OwoKaW1wb3J0IGphdmF4LnRvb2xzLio7CmltcG9ydCBqYXZheC50b29scy5KYXZhRmlsZU9iamVjdC5LaW5kOwoKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuZmlsZS5KYXZhY0ZpbGVNYW5hZ2VyOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkRlZmluZWRCeTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5EZWZpbmVkQnkuQXBpOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkxpc3RCdWZmZXI7CgovKioKICogSW50ZXJjZXB0cyByZWFkcyBhbmQgd3JpdGVzIHRvIHRoZSBmaWxlIHN5c3RlbSB0byBnYXRoZXIKICogaW5mb3JtYXRpb24gYWJvdXQgd2hhdCBhcnRpZmFjdHMgYXJlIGdlbmVyYXRlZC4KICoKICogVHJhcHMgd3JpdGVzIHRvIGNlcnRhaW4gZmlsZXMsIGlmIHRoZSBjb250ZW50IHdyaXR0ZW4gaXMgaWRlbnRpY2FsCiAqIHRvIHRoZSBleGlzdGluZyBmaWxlLgogKgogKiBDYW4gYWxzbyBibGluZCBvdXQgdGhlIGZpbGVtYW5hZ2VyIGZyb20gc2VlaW5nIGNlcnRhaW4gZmlsZXMgaW4gdGhlIGZpbGUgc3lzdGVtLgogKiBOZWNlc3NhcnkgdG8gcHJldmVudCBqYXZhYyBmcm9tIHNlZWluZyBzb21lIHNvdXJjZXMgd2hlcmUgdGhlIHNvdXJjZSBwYXRoIHBvaW50cy4KICoKICogIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqICBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqICBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogKiAgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPgogKi8KQGNvbS5zdW4udG9vbHMuamF2YWMuYXBpLkNsaWVudENvZGVXcmFwcGVyLlRydXN0ZWQKcHVibGljIGNsYXNzIFNtYXJ0RmlsZU1hbmFnZXIgZXh0ZW5kcyBGb3J3YXJkaW5nSmF2YUZpbGVNYW5hZ2VyPEphdmFGaWxlTWFuYWdlcj4gewoKICAgIC8vIFNldCBvZiBzb3VyY2VzIHRoYXQgY2FuIGJlIHNlZW4gYnkgamF2YWMuCiAgICBTZXQ8VVJJPiB2aXNpYmxlU291cmNlcyA9IG5ldyBIYXNoU2V0PD4oKTsKICAgIC8vIE1hcCBmcm9tIG1vZHVsZW5hbWU6cGFja2FnZW5hbWUgdG8gYXJ0aWZhY3RzLgogICAgTWFwPFN0cmluZyxTZXQ8VVJJPj4gcGFja2FnZUFydGlmYWN0cyA9IG5ldyBIYXNoTWFwPD4oKTsKCiAgICBwdWJsaWMgU21hcnRGaWxlTWFuYWdlcihKYXZhRmlsZU1hbmFnZXIgZmlsZU1hbmFnZXIpIHsKICAgICAgICBzdXBlcihmaWxlTWFuYWdlcik7CiAgICB9CgogICAgcHVibGljIHZvaWQgc2V0VmlzaWJsZVNvdXJjZXMoU2V0PFVSST4gcykgewogICAgICAgIHZpc2libGVTb3VyY2VzID0gczsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCBjbGVhbkFydGlmYWN0cygpIHsKICAgICAgICBwYWNrYWdlQXJ0aWZhY3RzID0gbmV3IEhhc2hNYXA8PigpOwogICAgfQoKICAgIC8qKgogICAgICogU2V0IHdoZXRoZXIgb3Igbm90IHRvIHVzZSBjdC5zeW0gYXMgYW4gYWx0ZXJuYXRlIHRvIHJ0Lmphci4KICAgICAqLwogICAgcHVibGljIHZvaWQgc2V0U3ltYm9sRmlsZUVuYWJsZWQoYm9vbGVhbiBiKSB7CiAgICAgICAgaWYgKCEoZmlsZU1hbmFnZXIgaW5zdGFuY2VvZiBKYXZhY0ZpbGVNYW5hZ2VyKSkKICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigpOwogICAgICAgICgoSmF2YWNGaWxlTWFuYWdlcikgZmlsZU1hbmFnZXIpLnNldFN5bWJvbEZpbGVFbmFibGVkKGIpOwogICAgfQoKICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSKQogICAgcHVibGljIFN0cmluZyBpbmZlckJpbmFyeU5hbWUoTG9jYXRpb24gbG9jYXRpb24sIEphdmFGaWxlT2JqZWN0IGZpbGUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuaW5mZXJCaW5hcnlOYW1lKGxvY2F0aW9uLCBsb2NVbndyYXAoZmlsZSkpOwogICAgfQoKCiAgICBwdWJsaWMgTWFwPFN0cmluZyxTZXQ8VVJJPj4gZ2V0UGFja2FnZUFydGlmYWN0cygpIHsKICAgICAgICByZXR1cm4gcGFja2FnZUFydGlmYWN0czsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICBwdWJsaWMgSXRlcmFibGU8SmF2YUZpbGVPYmplY3Q+IGxpc3QoTG9jYXRpb24gbG9jYXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHBhY2thZ2VOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNldDxLaW5kPiBraW5kcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIHJlY3Vyc2UpIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgLy8gVE9ETzogRG8gdGhpcyBsYXppbHkgYnkgcmV0dXJuaW5nIGFuIGl0ZXJhYmxlIHdpdGggYSBmaWx0ZXJpbmcgSXRlcmF0b3IKICAgICAgICAvLyBBY3F1aXJlIHRoZSBsaXN0IG9mIGZpbGVzLgogICAgICAgIEl0ZXJhYmxlPEphdmFGaWxlT2JqZWN0PiBmaWxlcyA9IHN1cGVyLmxpc3QobG9jYXRpb24sIHBhY2thZ2VOYW1lLCBraW5kcywgcmVjdXJzZSk7CiAgICAgICAgaWYgKHZpc2libGVTb3VyY2VzLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXR1cm4gbG9jV3JhcE1hbnkoZmlsZXMsIGxvY2F0aW9uKTsKICAgICAgICB9CiAgICAgICAgLy8gTm93IGZpbHRlciEKICAgICAgICBMaXN0QnVmZmVyPEphdmFGaWxlT2JqZWN0PiBmaWx0ZXJlZEZpbGVzID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgIGZvciAoSmF2YUZpbGVPYmplY3QgZiA6IGZpbGVzKSB7CiAgICAgICAgICAgIFVSSSB1cmkgPSBmLnRvVXJpKCk7CiAgICAgICAgICAgIFN0cmluZyB0ID0gdXJpLnRvU3RyaW5nKCk7CiAgICAgICAgICAgIGlmICh0LnN0YXJ0c1dpdGgoImphcjoiKQogICAgICAgICAgICAgICAgfHwgdC5lbmRzV2l0aCgiLmNsYXNzIikKICAgICAgICAgICAgICAgIHx8IHZpc2libGVTb3VyY2VzLmNvbnRhaW5zKHVyaSkpIHsKICAgICAgICAgICAgICAgIGZpbHRlcmVkRmlsZXMuYWRkKGYpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gbG9jV3JhcE1hbnkoZmlsdGVyZWRGaWxlcywgbG9jYXRpb24pOwogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgIHB1YmxpYyBKYXZhRmlsZU9iamVjdCBnZXRKYXZhRmlsZUZvcklucHV0KExvY2F0aW9uIGxvY2F0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGNsYXNzTmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEtpbmQga2luZCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICBKYXZhRmlsZU9iamVjdCBmaWxlID0gc3VwZXIuZ2V0SmF2YUZpbGVGb3JJbnB1dChsb2NhdGlvbiwgY2xhc3NOYW1lLCBraW5kKTsKICAgICAgICBmaWxlID0gbG9jV3JhcChmaWxlLCBsb2NhdGlvbik7CiAgICAgICAgaWYgKGZpbGUgPT0gbnVsbCB8fCB2aXNpYmxlU291cmNlcy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmV0dXJuIGZpbGU7CiAgICAgICAgfQoKICAgICAgICBpZiAodmlzaWJsZVNvdXJjZXMuY29udGFpbnMoZmlsZS50b1VyaSgpKSB8fCBpc01vZHVsZUluZm8oZmlsZSkpIHsKICAgICAgICAgICAgcmV0dXJuIGZpbGU7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgIHB1YmxpYyBKYXZhRmlsZU9iamVjdCBnZXRKYXZhRmlsZUZvck91dHB1dChMb2NhdGlvbiBsb2NhdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgY2xhc3NOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEtpbmQga2luZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGaWxlT2JqZWN0IHNpYmxpbmcpIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgSmF2YUZpbGVPYmplY3QgZmlsZSA9IHN1cGVyLmdldEphdmFGaWxlRm9yT3V0cHV0KGxvY2F0aW9uLCBjbGFzc05hbWUsIGtpbmQsIHNpYmxpbmcpOwogICAgICAgIGZpbGUgPSBsb2NXcmFwKGZpbGUsIGxvY2F0aW9uKTsKICAgICAgICBpZiAoZmlsZSA9PSBudWxsKSByZXR1cm4gZmlsZTsKICAgICAgICBpbnQgZHAgPSBjbGFzc05hbWUubGFzdEluZGV4T2YoJy4nKTsKICAgICAgICBTdHJpbmcgcGtnX25hbWUgPSAiIjsKICAgICAgICBpZiAoZHAgIT0gLTEpIHsKICAgICAgICAgICAgcGtnX25hbWUgPSBjbGFzc05hbWUuc3Vic3RyaW5nKDAsIGRwKTsKICAgICAgICB9CiAgICAgICAgLy8gV2hlbiBtb2R1bGVzIGFyZSBpbiB1c2UsIHRoZW4gdGhlIG1vZF9uYW1lIG1pZ2h0IGJlIHNvbWV0aGluZyBsaWtlICJqZGtfYmFzZSIKICAgICAgICBTdHJpbmcgbW9kX25hbWUgPSAiIjsKICAgICAgICBhZGRBcnRpZmFjdChtb2RfbmFtZSsiOiIrcGtnX25hbWUsIGZpbGUudG9VcmkoKSk7CiAgICAgICAgcmV0dXJuIGZpbGU7CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSKQogICAgcHVibGljIEZpbGVPYmplY3QgZ2V0RmlsZUZvcklucHV0KExvY2F0aW9uIGxvY2F0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBwYWNrYWdlTmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcmVsYXRpdmVOYW1lKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgIEZpbGVPYmplY3QgZmlsZSA9ICBzdXBlci5nZXRGaWxlRm9ySW5wdXQobG9jYXRpb24sIHBhY2thZ2VOYW1lLCByZWxhdGl2ZU5hbWUpOwogICAgICAgIGZpbGUgPSBsb2NXcmFwKGZpbGUsIGxvY2F0aW9uKTsKICAgICAgICBpZiAoZmlsZSA9PSBudWxsIHx8IHZpc2libGVTb3VyY2VzLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXR1cm4gZmlsZTsKICAgICAgICB9CgogICAgICAgIGlmICh2aXNpYmxlU291cmNlcy5jb250YWlucyhmaWxlLnRvVXJpKCkpIHx8IGlzTW9kdWxlSW5mbyhmaWxlKSkgewogICAgICAgICAgICByZXR1cm4gZmlsZTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgcHJpdmF0ZSBib29sZWFuIGlzTW9kdWxlSW5mbyhGaWxlT2JqZWN0IGZvKSB7CiAgICAgICAgaWYgKGZvIGluc3RhbmNlb2YgSmF2YUZpbGVPYmplY3QpIHsKICAgICAgICAgICAgSmF2YUZpbGVPYmplY3QgamZvID0gKEphdmFGaWxlT2JqZWN0KSBmbzsKICAgICAgICAgICAgcmV0dXJuIGpmby5pc05hbWVDb21wYXRpYmxlKCJtb2R1bGUtaW5mbyIsIEtpbmQuU09VUkNFKQogICAgICAgICAgICAgICAgfHwgamZvLmlzTmFtZUNvbXBhdGlibGUoIm1vZHVsZS1pbmZvIiwgS2luZC5DTEFTUyk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICBwdWJsaWMgRmlsZU9iamVjdCBnZXRGaWxlRm9yT3V0cHV0KExvY2F0aW9uIGxvY2F0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcGFja2FnZU5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyByZWxhdGl2ZU5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZpbGVPYmplY3Qgc2libGluZykgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICBGaWxlT2JqZWN0IHN1cGVyRmlsZSA9IHN1cGVyLmdldEZpbGVGb3JPdXRwdXQobG9jYXRpb24sIHBhY2thZ2VOYW1lLCByZWxhdGl2ZU5hbWUsIHNpYmxpbmcpOwogICAgICAgIEZpbGVPYmplY3QgZmlsZSA9IGxvY1dyYXAoc3VwZXJGaWxlLCBsb2NhdGlvbik7CiAgICAgICAgaWYgKGZpbGUgPT0gbnVsbCkgcmV0dXJuIGZpbGU7CgogICAgICAgIGlmIChsb2NhdGlvbi5lcXVhbHMoU3RhbmRhcmRMb2NhdGlvbi5OQVRJVkVfSEVBREVSX09VVFBVVCkgJiYgc3VwZXJGaWxlIGluc3RhbmNlb2YgSmF2YUZpbGVPYmplY3QpIHsKICAgICAgICAgICBmaWxlID0gbmV3IFNtYXJ0RmlsZU9iamVjdCgoSmF2YUZpbGVPYmplY3QpIGZpbGUpOwogICAgICAgICAgIHBhY2thZ2VOYW1lID0gIjoiICsgcGFja2FnZU5hbWVGcm9tRmlsZU5hbWUocmVsYXRpdmVOYW1lKTsKICAgICAgICB9CiAgICAgICAgaWYgKHBhY2thZ2VOYW1lLmVxdWFscygiIikpIHsKICAgICAgICAgICAgcGFja2FnZU5hbWUgPSAiOiI7CiAgICAgICAgfQogICAgICAgIGFkZEFydGlmYWN0KHBhY2thZ2VOYW1lLCBmaWxlLnRvVXJpKCkpOwogICAgICAgIHJldHVybiBmaWxlOwogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgIHB1YmxpYyBMb2NhdGlvbiBnZXRMb2NhdGlvbkZvck1vZHVsZShMb2NhdGlvbiBsb2NhdGlvbiwgSmF2YUZpbGVPYmplY3QgZm8pIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmdldExvY2F0aW9uRm9yTW9kdWxlKGxvY2F0aW9uLCBsb2NVbndyYXAoZm8pKTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgcGFja2FnZU5hbWVGcm9tRmlsZU5hbWUoU3RyaW5nIGZuKSB7CiAgICAgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CiAgICAgICAgaW50IHAgPSBmbi5pbmRleE9mKCdfJyksIHBwID0gMDsKICAgICAgICB3aGlsZSAocCAhPSAtMSkgewogICAgICAgICAgICBpZiAoc2IubGVuZ3RoKCkgPiAwKSBzYi5hcHBlbmQoJy4nKTsKICAgICAgICAgICAgc2IuYXBwZW5kKGZuLnN1YnN0cmluZyhwcCxwKSk7CiAgICAgICAgICAgIGlmIChwID09IGZuLmxlbmd0aCgpLTEpIGJyZWFrOwogICAgICAgICAgICBwcCA9IHArMTsKICAgICAgICAgICAgcCA9IGZuLmluZGV4T2YoJ18nLHBwKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7CiAgICB9CgogICAgdm9pZCBhZGRBcnRpZmFjdChTdHJpbmcgcGtnTmFtZSwgVVJJIGFydCkgewogICAgICAgIFNldDxVUkk+IHMgPSBwYWNrYWdlQXJ0aWZhY3RzLmdldChwa2dOYW1lKTsKICAgICAgICBpZiAocyA9PSBudWxsKSB7CiAgICAgICAgICAgIHMgPSBuZXcgSGFzaFNldDw+KCk7CiAgICAgICAgICAgIHBhY2thZ2VBcnRpZmFjdHMucHV0KHBrZ05hbWUsIHMpOwogICAgICAgIH0KICAgICAgICBzLmFkZChhcnQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgSmF2YUZpbGVPYmplY3QgbG9jV3JhcChKYXZhRmlsZU9iamVjdCBqZm8sIExvY2F0aW9uIGxvYykgewoKICAgICAgICAvLyBGcm9tIHNqYXZhYydzIHBlcnNwZWN0aXZlIHBsYXRmb3JtIGNsYXNzZXMgYXJlIG5vdCBpbnRlcmVzdGluZyBhbmQKICAgICAgICAvLyB0aGVyZSBpcyBubyBuZWVkIHRvIHRyYWNrIHRoZSBsb2NhdGlvbiBmb3IgdGhlc2UgZmlsZSBvYmplY3RzLgogICAgICAgIC8vIEFsc28sIHRoZXJlIGV4aXN0cyBzb21lIGpmbyBpbnN0YW5jZW9mIGNoZWNrcyB3aGljaCBicmVha3MgaWYKICAgICAgICAvLyB0aGUgamZvcyBmb3IgcGxhdGZvcm0gY2xhc3NlcyBhcmUgd3JhcHBlZC4KICAgICAgICBpZiAobG9jID09IFN0YW5kYXJkTG9jYXRpb24uUExBVEZPUk1fQ0xBU1NfUEFUSCkKICAgICAgICAgICAgcmV0dXJuIGpmbzsKCiAgICAgICAgcmV0dXJuIGpmbyA9PSBudWxsID8gbnVsbCA6IG5ldyBKYXZhRmlsZU9iamVjdFdpdGhMb2NhdGlvbjw+KGpmbywgbG9jKTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBGaWxlT2JqZWN0IGxvY1dyYXAoRmlsZU9iamVjdCBmbywgTG9jYXRpb24gbG9jKSB7CiAgICAgICAgaWYgKGZvIGluc3RhbmNlb2YgSmF2YUZpbGVPYmplY3QpCiAgICAgICAgICAgIHJldHVybiBsb2NXcmFwKChKYXZhRmlsZU9iamVjdCkgZm8sIGxvYyk7CiAgICAgICAgcmV0dXJuIGZvID09IG51bGwgPyBudWxsIDogbmV3IEZpbGVPYmplY3RXaXRoTG9jYXRpb248PihmbywgbG9jKTsKICAgIH0KCiAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgIEBPdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaXNTYW1lRmlsZShGaWxlT2JqZWN0IGEsIEZpbGVPYmplY3QgYikgewogICAgICAgIHJldHVybiBzdXBlci5pc1NhbWVGaWxlKGxvY1Vud3JhcChhKSwgbG9jVW53cmFwKGIpKTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBMaXN0QnVmZmVyPEphdmFGaWxlT2JqZWN0PiBsb2NXcmFwTWFueShJdGVyYWJsZTxKYXZhRmlsZU9iamVjdD4gamZvcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExvY2F0aW9uIGxvYykgewogICAgICAgIExpc3RCdWZmZXI8SmF2YUZpbGVPYmplY3Q+IGxvY1dyYXBwZWQgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgZm9yIChKYXZhRmlsZU9iamVjdCBmIDogamZvcykKICAgICAgICAgICAgbG9jV3JhcHBlZC5hZGQobG9jV3JhcChmLCBsb2MpKTsKICAgICAgICByZXR1cm4gbG9jV3JhcHBlZDsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBGaWxlT2JqZWN0IGxvY1Vud3JhcChGaWxlT2JqZWN0IGZvKSB7CiAgICAgICAgaWYgKGZvIGluc3RhbmNlb2YgRmlsZU9iamVjdFdpdGhMb2NhdGlvbjw/PikKICAgICAgICAgICAgcmV0dXJuICgoRmlsZU9iamVjdFdpdGhMb2NhdGlvbjw/PikgZm8pLmdldERlbGVnYXRlKCk7CiAgICAgICAgaWYgKGZvIGluc3RhbmNlb2YgSmF2YUZpbGVPYmplY3RXaXRoTG9jYXRpb248Pz4pCiAgICAgICAgICAgIHJldHVybiAoKEphdmFGaWxlT2JqZWN0V2l0aExvY2F0aW9uPD8+KSBmbykuZ2V0RGVsZWdhdGUoKTsKICAgICAgICByZXR1cm4gZm87CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgSmF2YUZpbGVPYmplY3QgbG9jVW53cmFwKEphdmFGaWxlT2JqZWN0IGZvKSB7CiAgICAgICAgaWYgKGZvIGluc3RhbmNlb2YgSmF2YUZpbGVPYmplY3RXaXRoTG9jYXRpb248Pz4pCiAgICAgICAgICAgIHJldHVybiAoKEphdmFGaWxlT2JqZWN0V2l0aExvY2F0aW9uPD8+KSBmbykuZ2V0RGVsZWdhdGUoKTsKICAgICAgICByZXR1cm4gZm87CiAgICB9Cn0KUEsDBAoAAAgAAAY7qUrabmjcXRoAAF0aAAAsAAAAY29tL3N1bi90b29scy9zamF2YWMvY29tcC9QdWJhcGlWaXNpdG9yLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTEsIDIwMTUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5zamF2YWMuY29tcDsKCmltcG9ydCBzdGF0aWMgamF2YXgubGFuZy5tb2RlbC5lbGVtZW50Lk1vZGlmaWVyLlBSSVZBVEU7CgppbXBvcnQgamF2YS51dGlsLkxpc3Q7CmltcG9ydCBqYXZhLnV0aWwuc3RyZWFtLkNvbGxlY3RvcnM7CgppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5lbGVtZW50LkVsZW1lbnQ7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuRXhlY3V0YWJsZUVsZW1lbnQ7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuVHlwZUVsZW1lbnQ7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuVHlwZVBhcmFtZXRlckVsZW1lbnQ7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuVmFyaWFibGVFbGVtZW50OwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC50eXBlLlR5cGVNaXJyb3I7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLnV0aWwuRWxlbWVudFNjYW5uZXI5OwoKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5TeW1ib2wuQ2xhc3NTeW1ib2w7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuRGVmaW5lZEJ5OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkRlZmluZWRCeS5BcGk7CmltcG9ydCBjb20uc3VuLnRvb2xzLnNqYXZhYy5wdWJhcGkuUHViQXBpOwppbXBvcnQgY29tLnN1bi50b29scy5zamF2YWMucHViYXBpLlB1YkFwaVR5cGVQYXJhbTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuc2phdmFjLnB1YmFwaS5QdWJNZXRob2Q7CmltcG9ydCBjb20uc3VuLnRvb2xzLnNqYXZhYy5wdWJhcGkuUHViVHlwZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuc2phdmFjLnB1YmFwaS5QdWJWYXI7CmltcG9ydCBjb20uc3VuLnRvb2xzLnNqYXZhYy5wdWJhcGkuVHlwZURlc2M7CgovKiogVXRpbGl0eSBjbGFzcyB0aGF0IGNvbnN0cnVjdHMgYSB0ZXh0dWFsIHJlcHJlc2VudGF0aW9uCiAqIG9mIHRoZSBwdWJsaWMgYXBpIG9mIGEgY2xhc3MuCiAqCiAqICA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiAgSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93biByaXNrLgogKiAgVGhpcyBjb2RlIGFuZCBpdHMgaW50ZXJuYWwgaW50ZXJmYWNlcyBhcmUgc3ViamVjdCB0byBjaGFuZ2Ugb3IKICogIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj4KICovCnB1YmxpYyBjbGFzcyBQdWJhcGlWaXNpdG9yIGV4dGVuZHMgRWxlbWVudFNjYW5uZXI5PFZvaWQsIFZvaWQ+IHsKCiAgICBwcml2YXRlIFB1YkFwaSBjb2xsZWN0ZWRBcGkgPSBuZXcgUHViQXBpKCk7CgogICAgcHJpdmF0ZSBib29sZWFuIGlzTm9uUHJpdmF0ZShFbGVtZW50IGUpIHsKICAgICAgICByZXR1cm4gIWUuZ2V0TW9kaWZpZXJzKCkuY29udGFpbnMoUFJJVkFURSk7CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgcHVibGljIFZvaWQgdmlzaXRUeXBlKFR5cGVFbGVtZW50IGUsIFZvaWQgcCkgewogICAgICAgIGlmIChpc05vblByaXZhdGUoZSkpIHsKICAgICAgICAgICAgUHViQXBpIHByZXZBcGkgPSBjb2xsZWN0ZWRBcGk7CiAgICAgICAgICAgIGNvbGxlY3RlZEFwaSA9IG5ldyBQdWJBcGkoKTsKICAgICAgICAgICAgc3VwZXIudmlzaXRUeXBlKGUsIHApOwogICAgICAgICAgICBpZiAoIWlzQW5vbnltb3VzKGUpKSB7CiAgICAgICAgICAgICAgICBTdHJpbmcgbmFtZSA9ICgoQ2xhc3NTeW1ib2wpIGUpLmZsYXRuYW1lLnRvU3RyaW5nKCk7CiAgICAgICAgICAgICAgICBQdWJUeXBlIHQgPSBuZXcgUHViVHlwZShlLmdldE1vZGlmaWVycygpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vZS5nZXRRdWFsaWZpZWROYW1lKCkudG9TdHJpbmcoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbGxlY3RlZEFwaSk7CiAgICAgICAgICAgICAgICBwcmV2QXBpLnR5cGVzLnB1dCh0LmZxTmFtZSwgdCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY29sbGVjdGVkQXBpID0gcHJldkFwaTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgcHJpdmF0ZSBib29sZWFuIGlzQW5vbnltb3VzKFR5cGVFbGVtZW50IGUpIHsKICAgICAgICByZXR1cm4gZS5nZXRRdWFsaWZpZWROYW1lKCkubGVuZ3RoKCkgPT0gMDsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgZW5jb2RlQ2hhcihpbnQgYykgewogICAgICAgIHJldHVybiBTdHJpbmcuZm9ybWF0KCJcXHUlMDR4IiwgYyk7CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgcHVibGljIFZvaWQgdmlzaXRWYXJpYWJsZShWYXJpYWJsZUVsZW1lbnQgZSwgVm9pZCBwKSB7CiAgICAgICAgaWYgKGlzTm9uUHJpdmF0ZShlKSkgewogICAgICAgICAgICBPYmplY3QgY29uc3RWYWwgPSBlLmdldENvbnN0YW50VmFsdWUoKTsKICAgICAgICAgICAgU3RyaW5nIGNvbnN0VmFsU3RyID0gbnVsbDsKICAgICAgICAgICAgLy8gVE9ETzogVGhpcyBkb2Vzbid0IHNlZW0gdG8gYmUgZW50aXJlbHkgYWNjdXJhdGUuIFdoYXQgaWYgSSBjaGFuZ2UKICAgICAgICAgICAgLy8gZnJvbSwgc2F5LCAwIHRvIDBMPyAoQW5kIHRoZSBmaWVsZCBpcyBwdWJsaWMgZmluYWwgc3RhdGljIHNvIHRoYXQKICAgICAgICAgICAgLy8gaXQgY291bGQgZ2V0IGlubGluZWQuKQogICAgICAgICAgICBpZiAoY29uc3RWYWwgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgaWYgKGUuYXNUeXBlKCkudG9TdHJpbmcoKS5lcXVhbHMoImNoYXIiKSkgewogICAgICAgICAgICAgICAgICAgIC8vIFdoYXQgdHlwZSBpcyAndmFsdWUnPyBJcyBpdCBhbHJlYWR5IGEgY2hhcj8KICAgICAgICAgICAgICAgICAgICBjaGFyIGMgPSBjb25zdFZhbC50b1N0cmluZygpLmNoYXJBdCgwKTsKICAgICAgICAgICAgICAgICAgICBjb25zdFZhbFN0ciA9ICInIiArIGVuY29kZUNoYXIoYykgKyAiJyI7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGNvbnN0VmFsU3RyID0gY29uc3RWYWwudG9TdHJpbmcoKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY2hhcnMoKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAubWFwVG9PYmooUHViYXBpVmlzaXRvcjo6ZW5jb2RlQ2hhcikKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmNvbGxlY3QoQ29sbGVjdG9ycy5qb2luaW5nKCIiLCAiXCIiLCAiXCIiKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIFB1YlZhciB2ID0gbmV3IFB1YlZhcihlLmdldE1vZGlmaWVycygpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVHlwZURlc2MuZnJvbVR5cGUoZS5hc1R5cGUoKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlLnRvU3RyaW5nKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdFZhbFN0cik7CiAgICAgICAgICAgIGNvbGxlY3RlZEFwaS52YXJpYWJsZXMucHV0KHYuaWRlbnRpZmllciwgdik7CiAgICAgICAgfQoKICAgICAgICAvLyBTYWZlIHRvIG5vdCByZWN1cnNlIGhlcmUsIGJlY2F1c2UgdGhlIG9ubHkgdGhpbmcKICAgICAgICAvLyB0byB2aXNpdCBoZXJlIGlzIHRoZSBjb25zdHJ1Y3RvciBvZiBhIHZhcmlhYmxlIGRlY2xhcmF0aW9uLgogICAgICAgIC8vIElmIGl0IGhhcHBlbnMgdG8gY29udGFpbiBhbiBhbm9ueW1vdXMgaW5uZXIgY2xhc3MgKHdoaWNoIGl0IG1pZ2h0KQogICAgICAgIC8vIHRoZW4gdGhpcyBjbGFzcyBpcyBuZXZlciB2aXNpYmxlIG91dHNpZGUgb2YgdGhlIHBhY2thZ2UgYW55d2F5LCBzbwogICAgICAgIC8vIHdlIGFyZSBhbGxvd2VkIHRvIGlnbm9yZSBpdCBoZXJlLgogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgIHB1YmxpYyBWb2lkIHZpc2l0RXhlY3V0YWJsZShFeGVjdXRhYmxlRWxlbWVudCBlLCBWb2lkIHApIHsKICAgICAgICBpZiAoaXNOb25Qcml2YXRlKGUpKSB7CiAgICAgICAgICAgIFB1Yk1ldGhvZCBtID0gbmV3IFB1Yk1ldGhvZChlLmdldE1vZGlmaWVycygpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0VHlwZVBhcmFtZXRlcnMoZS5nZXRUeXBlUGFyYW1ldGVycygpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFR5cGVEZXNjLmZyb21UeXBlKGUuZ2V0UmV0dXJuVHlwZSgpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGUuZ2V0U2ltcGxlTmFtZSgpLnRvU3RyaW5nKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRUeXBlRGVzY3MoZ2V0UGFyYW1UeXBlcyhlKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRUeXBlRGVzY3MoZS5nZXRUaHJvd25UeXBlcygpKSk7CiAgICAgICAgICAgIGNvbGxlY3RlZEFwaS5tZXRob2RzLnB1dChtLmFzU2lnbmF0dXJlU3RyaW5nKCksIG0pOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICBwcml2YXRlIExpc3Q8UHViQXBpVHlwZVBhcmFtPiBnZXRUeXBlUGFyYW1ldGVycyhMaXN0PD8gZXh0ZW5kcyBUeXBlUGFyYW1ldGVyRWxlbWVudD4gZWxlbWVudHMpIHsKICAgICAgICByZXR1cm4gZWxlbWVudHMuc3RyZWFtKCkKICAgICAgICAgICAgICAgICAgICAgICAubWFwKGUgLT4gbmV3IFB1YkFwaVR5cGVQYXJhbShlLmdldFNpbXBsZU5hbWUoKS50b1N0cmluZygpLCBnZXRUeXBlRGVzY3MoZS5nZXRCb3VuZHMoKSkpKQogICAgICAgICAgICAgICAgICAgICAgIC5jb2xsZWN0KENvbGxlY3RvcnMudG9MaXN0KCkpOwogICAgfQoKICAgIHByaXZhdGUgTGlzdDxUeXBlTWlycm9yPiBnZXRQYXJhbVR5cGVzKEV4ZWN1dGFibGVFbGVtZW50IGUpIHsKICAgICAgICByZXR1cm4gZS5nZXRQYXJhbWV0ZXJzKCkKICAgICAgICAgICAgICAgIC5zdHJlYW0oKQogICAgICAgICAgICAgICAgLm1hcChWYXJpYWJsZUVsZW1lbnQ6OmFzVHlwZSkKICAgICAgICAgICAgICAgIC5jb2xsZWN0KENvbGxlY3RvcnMudG9MaXN0KCkpOwogICAgfQoKICAgIHByaXZhdGUgTGlzdDxUeXBlRGVzYz4gZ2V0VHlwZURlc2NzKExpc3Q8PyBleHRlbmRzIFR5cGVNaXJyb3I+IGxpc3QpIHsKICAgICAgICByZXR1cm4gbGlzdC5zdHJlYW0oKQogICAgICAgICAgICAgICAgICAgLm1hcChUeXBlRGVzYzo6ZnJvbVR5cGUpCiAgICAgICAgICAgICAgICAgICAuY29sbGVjdChDb2xsZWN0b3JzLnRvTGlzdCgpKTsKICAgIH0KCiAgICBwdWJsaWMgUHViQXBpIGdldENvbGxlY3RlZFB1YkFwaSgpIHsKICAgICAgICByZXR1cm4gY29sbGVjdGVkQXBpOwogICAgfQp9ClBLAwQKAAAIAAAGO6lKEiKkCHsHAAB7BwAANQAAAGNvbS9zdW4vdG9vbHMvc2phdmFjL2NvbXAvRmlsZU9iamVjdFdpdGhMb2NhdGlvbi5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDE0LCAyMDE1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuc2phdmFjLmNvbXA7CgppbXBvcnQgamF2YXgudG9vbHMuRmlsZU9iamVjdDsKaW1wb3J0IGphdmF4LnRvb2xzLkZvcndhcmRpbmdGaWxlT2JqZWN0OwppbXBvcnQgamF2YXgudG9vbHMuSmF2YUZpbGVNYW5hZ2VyLkxvY2F0aW9uOwoKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuYXBpLkNsaWVudENvZGVXcmFwcGVyLlRydXN0ZWQ7CgpAVHJ1c3RlZApwdWJsaWMgY2xhc3MgRmlsZU9iamVjdFdpdGhMb2NhdGlvbjxGIGV4dGVuZHMgRmlsZU9iamVjdD4gZXh0ZW5kcyBGb3J3YXJkaW5nRmlsZU9iamVjdDxGPiB7CgogICAgcHJpdmF0ZSBmaW5hbCBMb2NhdGlvbiBsb2M7CgogICAgcHVibGljIEZpbGVPYmplY3RXaXRoTG9jYXRpb24oRiBkZWxlZ2F0ZSwgTG9jYXRpb24gbG9jKSB7CiAgICAgICAgc3VwZXIoZGVsZWdhdGUpOwogICAgICAgIHRoaXMubG9jID0gbG9jOwogICAgfQoKICAgIHB1YmxpYyBMb2NhdGlvbiBnZXRMb2NhdGlvbigpIHsKICAgICAgICByZXR1cm4gbG9jOwogICAgfQoKICAgIHB1YmxpYyBGaWxlT2JqZWN0IGdldERlbGVnYXRlKCkgewogICAgICAgIHJldHVybiBmaWxlT2JqZWN0OwogICAgfQoKICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CiAgICAgICAgcmV0dXJuICJGaWxlT2JqZWN0V2l0aExvY2F0aW9uWyIgKyBmaWxlT2JqZWN0ICsgIl0iOwogICAgfQp9ClBLAwQKAAAIAAAGO6lKDjdSJBQRAAAUEQAALgAAAGNvbS9zdW4vdG9vbHMvc2phdmFjL2NvbXAvU21hcnRGaWxlT2JqZWN0LmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTIsIDIwMTYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5zamF2YWMuY29tcDsKCmltcG9ydCBqYXZhLmlvLio7CmltcG9ydCBqYXZhLm5ldC5VUkk7CmltcG9ydCBqYXZhLm5pby5maWxlLk5vU3VjaEZpbGVFeGNlcHRpb247CgppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5lbGVtZW50Lk1vZGlmaWVyOwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5lbGVtZW50Lk5lc3RpbmdLaW5kOwppbXBvcnQgamF2YXgudG9vbHMuSmF2YUZpbGVPYmplY3Q7CgppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkRlZmluZWRCeTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5EZWZpbmVkQnkuQXBpOwoKLyoqCiAqIFRoZSBTbWFydEZpbGVPYmplY3Qgd2lsbCByZXR1cm4gYW4gb3V0cHV0c3RyZWFtIHRoYXQgY2FjaGUgdGhlIHdyaXR0ZW4gZGF0YQogKiBhbmQgY29tcGFyZSB0aGUgbmV3IGNvbnRlbnQgd2l0aCB0aGUgb2xkIGNvbnRlbnQgb24gZGlzay4gT25seSBpZiB0aGV5IGRpZmZlciwKICogd2lsbCB0aGUgZmlsZSBiZSB1cGRhdGVkLgogKgogKiAgPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24gcmlzay4KICogIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yCiAqICBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+CiAqLwpwdWJsaWMgY2xhc3MgU21hcnRGaWxlT2JqZWN0IGltcGxlbWVudHMgSmF2YUZpbGVPYmplY3QgewoKICAgIEphdmFGaWxlT2JqZWN0IGZpbGU7CgogICAgcHVibGljIFNtYXJ0RmlsZU9iamVjdChKYXZhRmlsZU9iamVjdCByKSB7CiAgICAgICAgZmlsZSA9IHI7CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG90aGVyKSB7CiAgICAgICAgcmV0dXJuIGZpbGUuZXF1YWxzKG90aGVyKTsKICAgIH0KCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgICAgcmV0dXJuIGZpbGUuaGFzaENvZGUoKTsKICAgIH0KCiAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgIHB1YmxpYyBLaW5kIGdldEtpbmQoKSB7CiAgICAgICAgcmV0dXJuIGZpbGUuZ2V0S2luZCgpOwogICAgfQoKICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSKQogICAgcHVibGljIGJvb2xlYW4gaXNOYW1lQ29tcGF0aWJsZShTdHJpbmcgc2ltcGxlTmFtZSwgS2luZCBraW5kKSB7CiAgICAgICAgcmV0dXJuIGZpbGUuaXNOYW1lQ29tcGF0aWJsZShzaW1wbGVOYW1lLCBraW5kKTsKICAgIH0KCiAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgIHB1YmxpYyBVUkkgdG9VcmkoKSB7CiAgICAgICAgcmV0dXJuIGZpbGUudG9VcmkoKTsKICAgIH0KCiAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZSgpIHsKICAgICAgICByZXR1cm4gZmlsZS5nZXROYW1lKCk7CiAgICB9CgogICAgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICBwdWJsaWMgSW5wdXRTdHJlYW0gb3BlbklucHV0U3RyZWFtKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gZmlsZS5vcGVuSW5wdXRTdHJlYW0oKTsKICAgIH0KCiAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgIHB1YmxpYyBPdXRwdXRTdHJlYW0gb3Blbk91dHB1dFN0cmVhbSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGZpbGUub3Blbk91dHB1dFN0cmVhbSgpOwogICAgfQoKICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSKQogICAgcHVibGljIENoYXJTZXF1ZW5jZSBnZXRDaGFyQ29udGVudChib29sZWFuIGlnbm9yZUVuY29kaW5nRXJyb3JzKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBmaWxlLmdldENoYXJDb250ZW50KGlnbm9yZUVuY29kaW5nRXJyb3JzKTsKICAgIH0KCiAgICBzdGF0aWMgU3RyaW5nIGxpbmVzZXBhcmF0b3IgPSBTeXN0ZW0uZ2V0UHJvcGVydHkoImxpbmUuc2VwYXJhdG9yIik7CgogICAgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICBwdWJsaWMgV3JpdGVyIG9wZW5Xcml0ZXIoKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgIFN0cmluZ0J1aWxkZXIgcyA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IChCdWZmZXJlZFJlYWRlciByID0gbmV3IEJ1ZmZlcmVkUmVhZGVyKGZpbGUub3BlblJlYWRlcih0cnVlKSkpIHsKICAgICAgICAgICAgd2hpbGUgKHIucmVhZHkoKSkgewogICAgICAgICAgICAgICAgcy5hcHBlbmQoci5yZWFkTGluZSgpK2xpbmVzZXBhcmF0b3IpOwogICAgICAgICAgICB9CiAgICAgICAgfSBjYXRjaCAoRmlsZU5vdEZvdW5kRXhjZXB0aW9uIHwgTm9TdWNoRmlsZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIC8vIFBlcmZlY3RseSBvay4KICAgICAgICB9CiAgICAgICAgcmV0dXJuIG5ldyBTbWFydFdyaXRlcihmaWxlLCBzLnRvU3RyaW5nKCksIGZpbGUuZ2V0TmFtZSgpKTsKICAgIH0KCiAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgIHB1YmxpYyBsb25nIGdldExhc3RNb2RpZmllZCgpIHsKICAgICAgICByZXR1cm4gZmlsZS5nZXRMYXN0TW9kaWZpZWQoKTsKICAgIH0KCiAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgIHB1YmxpYyBib29sZWFuIGRlbGV0ZSgpIHsKICAgICAgICByZXR1cm4gZmlsZS5kZWxldGUoKTsKICAgIH0KCiAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgIHB1YmxpYyBNb2RpZmllciBnZXRBY2Nlc3NMZXZlbCgpIHsKICAgICAgICByZXR1cm4gZmlsZS5nZXRBY2Nlc3NMZXZlbCgpOwogICAgfQoKICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSKQogICAgcHVibGljIE5lc3RpbmdLaW5kIGdldE5lc3RpbmdLaW5kKCkgewogICAgICAgIHJldHVybiBmaWxlLmdldE5lc3RpbmdLaW5kKCk7CiAgICB9CgogICAgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICBwdWJsaWMgUmVhZGVyIG9wZW5SZWFkZXIoYm9vbGVhbiBpZ25vcmVFbmNvZGluZ0Vycm9ycykgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gZmlsZS5vcGVuUmVhZGVyKGlnbm9yZUVuY29kaW5nRXJyb3JzKTsKICAgIH0KCn0KUEsDBAoAAAgAAAY7qUqfKQhjOUQAADlEAAApAAAAY29tL3N1bi90b29scy9zamF2YWMvY29tcC9TamF2YWNJbXBsLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTQsIDIwMTYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5zamF2YWMuY29tcDsKCmltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwppbXBvcnQgamF2YS5pby5QcmludFdyaXRlcjsKaW1wb3J0IGphdmEuaW8uU3RyaW5nV3JpdGVyOwppbXBvcnQgamF2YS5uaW8uZmlsZS5GaWxlczsKaW1wb3J0IGphdmEubmlvLmZpbGUuUGF0aDsKaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CmltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbnM7CmltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKaW1wb3J0IGphdmEudXRpbC5IYXNoU2V0OwppbXBvcnQgamF2YS51dGlsLkxpc3Q7CmltcG9ydCBqYXZhLnV0aWwuTWFwOwppbXBvcnQgamF2YS51dGlsLlNldDsKaW1wb3J0IGphdmEudXRpbC5zdHJlYW0uU3RyZWFtOwoKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuZmlsZS5KYXZhY0ZpbGVNYW5hZ2VyOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5tYWluLk1haW47CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLm1haW4uTWFpbi5SZXN1bHQ7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuQ29udGV4dDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuc2phdmFjLkphdmFjU3RhdGU7CmltcG9ydCBjb20uc3VuLnRvb2xzLnNqYXZhYy5Mb2c7CmltcG9ydCBjb20uc3VuLnRvb2xzLnNqYXZhYy5Nb2R1bGU7CmltcG9ydCBjb20uc3VuLnRvb2xzLnNqYXZhYy5Qcm9ibGVtRXhjZXB0aW9uOwppbXBvcnQgY29tLnN1bi50b29scy5zamF2YWMuU291cmNlOwppbXBvcnQgY29tLnN1bi50b29scy5zamF2YWMuVHJhbnNmb3JtZXI7CmltcG9ydCBjb20uc3VuLnRvb2xzLnNqYXZhYy5VdGlsOwppbXBvcnQgY29tLnN1bi50b29scy5zamF2YWMub3B0aW9ucy5PcHRpb247CmltcG9ydCBjb20uc3VuLnRvb2xzLnNqYXZhYy5vcHRpb25zLk9wdGlvbnM7CmltcG9ydCBjb20uc3VuLnRvb2xzLnNqYXZhYy5vcHRpb25zLlNvdXJjZUxvY2F0aW9uOwppbXBvcnQgY29tLnN1bi50b29scy5zamF2YWMuc2VydmVyLlNqYXZhYzsKaW1wb3J0IGphdmEuaW8uVW5jaGVja2VkSU9FeGNlcHRpb247CgppbXBvcnQgamF2YXgudG9vbHMuSmF2YUZpbGVNYW5hZ2VyOwoKLyoqCiAqIFRoZSBzamF2YWMgaW1wbGVtZW50YXRpb24gdGhhdCBpbnRlcmFjdHMgd2l0aCBqYXZhYyBhbmQgcGVyZm9ybXMgdGhlIGFjdHVhbAogKiBjb21waWxhdGlvbi4KICoKICogIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqICBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqICBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogKiAgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPgogKi8KcHVibGljIGNsYXNzIFNqYXZhY0ltcGwgaW1wbGVtZW50cyBTamF2YWMgewoKICAgIEBPdmVycmlkZQogICAgcHVibGljIFJlc3VsdCBjb21waWxlKFN0cmluZ1tdIGFyZ3MpIHsKICAgICAgICBPcHRpb25zIG9wdGlvbnM7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgb3B0aW9ucyA9IE9wdGlvbnMucGFyc2VBcmdzKGFyZ3MpOwogICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIExvZy5lcnJvcihlLmdldE1lc3NhZ2UoKSk7CiAgICAgICAgICAgIHJldHVybiBSZXN1bHQuQ01ERVJSOwogICAgICAgIH0KCiAgICAgICAgaWYgKCF2YWxpZGF0ZU9wdGlvbnMob3B0aW9ucykpCiAgICAgICAgICAgIHJldHVybiBSZXN1bHQuQ01ERVJSOwoKICAgICAgICBpZiAoc3JjRHN0T3ZlcmxhcChvcHRpb25zLmdldFNvdXJjZXMoKSwgb3B0aW9ucy5nZXREZXN0RGlyKCkpKSB7CiAgICAgICAgICAgIHJldHVybiBSZXN1bHQuQ01ERVJSOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFjcmVhdGVJZk1pc3Npbmcob3B0aW9ucy5nZXREZXN0RGlyKCkpKQogICAgICAgICAgICByZXR1cm4gUmVzdWx0LkVSUk9SOwoKICAgICAgICBQYXRoIHN0YXRlRGlyID0gb3B0aW9ucy5nZXRTdGF0ZURpcigpOwogICAgICAgIGlmIChzdGF0ZURpciAhPSBudWxsICYmICFjcmVhdGVJZk1pc3Npbmcob3B0aW9ucy5nZXRTdGF0ZURpcigpKSkKICAgICAgICAgICAgcmV0dXJuIFJlc3VsdC5FUlJPUjsKCiAgICAgICAgUGF0aCBnZW5zcmMgPSBvcHRpb25zLmdldEdlblNyY0RpcigpOwogICAgICAgIGlmIChnZW5zcmMgIT0gbnVsbCAmJiAhY3JlYXRlSWZNaXNzaW5nKGdlbnNyYykpCiAgICAgICAgICAgIHJldHVybiBSZXN1bHQuRVJST1I7CgogICAgICAgIFBhdGggaGRyZGlyID0gb3B0aW9ucy5nZXRIZWFkZXJEaXIoKTsKICAgICAgICBpZiAoaGRyZGlyICE9IG51bGwgJiYgIWNyZWF0ZUlmTWlzc2luZyhoZHJkaXIpKQogICAgICAgICAgICByZXR1cm4gUmVzdWx0LkVSUk9SOwoKICAgICAgICBpZiAoc3RhdGVEaXIgPT0gbnVsbCkgewogICAgICAgICAgICAvLyBQcmVwYXJlIGNvbnRleHQuIERpcmVjdCBsb2dnaW5nIHRvIG91ciBieXRlIGFycmF5IHN0cmVhbS4KICAgICAgICAgICAgQ29udGV4dCBjb250ZXh0ID0gbmV3IENvbnRleHQoKTsKICAgICAgICAgICAgU3RyaW5nV3JpdGVyIHN0cldyaXRlciA9IG5ldyBTdHJpbmdXcml0ZXIoKTsKICAgICAgICAgICAgUHJpbnRXcml0ZXIgcHJpbnRXcml0ZXIgPSBuZXcgUHJpbnRXcml0ZXIoc3RyV3JpdGVyKTsKICAgICAgICAgICAgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkxvZy5wcmVSZWdpc3Rlcihjb250ZXh0LCBwcmludFdyaXRlcik7CiAgICAgICAgICAgIEphdmFjRmlsZU1hbmFnZXIucHJlUmVnaXN0ZXIoY29udGV4dCk7CgogICAgICAgICAgICAvLyBQcmVwYXJlIGFyZ3VtZW50cwogICAgICAgICAgICBTdHJpbmdbXSBwYXNzVGhyb3VnaEFyZ3MgPSBTdHJlYW0ub2YoYXJncykKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmZpbHRlcihhcmcgLT4gIWFyZy5zdGFydHNXaXRoKE9wdGlvbi5TRVJWRVIuYXJnKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnRvQXJyYXkoU3RyaW5nW106Om5ldyk7CiAgICAgICAgICAgIC8vIENvbXBpbGUKICAgICAgICAgICAgUmVzdWx0IHJlc3VsdCA9IG5ldyBNYWluKCJqYXZhYyIsIHByaW50V3JpdGVyKS5jb21waWxlKHBhc3NUaHJvdWdoQXJncywgY29udGV4dCk7CgogICAgICAgICAgICAvLyBQcm9jZXNzIGNvbXBpbGVyIG91dHB1dCAod2hpY2ggaXMgYWx3YXlzIGVycm9ycykKICAgICAgICAgICAgcHJpbnRXcml0ZXIuZmx1c2goKTsKICAgICAgICAgICAgVXRpbC5nZXRMaW5lcyhzdHJXcml0ZXIudG9TdHJpbmcoKSkuZm9yRWFjaChMb2c6OmVycm9yKTsKCiAgICAgICAgICAgIC8vIENsZWFuIHVwCiAgICAgICAgICAgIEphdmFGaWxlTWFuYWdlciBmaWxlTWFuYWdlciA9IGNvbnRleHQuZ2V0KEphdmFGaWxlTWFuYWdlci5jbGFzcyk7CiAgICAgICAgICAgIGlmIChmaWxlTWFuYWdlciBpbnN0YW5jZW9mIEphdmFjRmlsZU1hbmFnZXIpIHsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgKChKYXZhY0ZpbGVNYW5hZ2VyKSBmaWxlTWFuYWdlcikuY2xvc2UoKTsKICAgICAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGVzKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFVuY2hlY2tlZElPRXhjZXB0aW9uKGVzKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gcmVzdWx0OwoKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvLyBMb2FkIHRoZSBwcmV2IGJ1aWxkIHN0YXRlIGRhdGFiYXNlLgogICAgICAgICAgICBKYXZhY1N0YXRlIGphdmFjX3N0YXRlID0gSmF2YWNTdGF0ZS5sb2FkKG9wdGlvbnMpOwoKICAgICAgICAgICAgLy8gU2V0dXAgdGhlIHN1ZmZpeCBydWxlcyBmcm9tIHRoZSBjb21tYW5kIGxpbmUuCiAgICAgICAgICAgIE1hcDxTdHJpbmcsIFRyYW5zZm9ybWVyPiBzdWZmaXhSdWxlcyA9IG5ldyBIYXNoTWFwPD4oKTsKCiAgICAgICAgICAgIC8vIEhhbmRsaW5nIG9mIC5qYXZhLWNvbXBpbGF0aW9uCiAgICAgICAgICAgIHN1ZmZpeFJ1bGVzLnB1dEFsbChqYXZhY19zdGF0ZS5nZXRKYXZhU3VmZml4UnVsZSgpKTsKCiAgICAgICAgICAgIC8vIEhhbmRsaW5nIG9mIC1jb3B5IGFuZCAtdHIKICAgICAgICAgICAgc3VmZml4UnVsZXMucHV0QWxsKG9wdGlvbnMuZ2V0VHJhbnNsYXRpb25SdWxlcygpKTsKCiAgICAgICAgICAgIC8vIEFsbCBmb3VuZCBtb2R1bGVzIGFyZSBwdXQgaGVyZS4KICAgICAgICAgICAgTWFwPFN0cmluZyxNb2R1bGU+IG1vZHVsZXMgPSBuZXcgSGFzaE1hcDw+KCk7CiAgICAgICAgICAgIC8vIFdlIHN0YXJ0IG91dCBpbiB0aGUgbGVnYWN5IGVtcHR5IG5vLW5hbWUgbW9kdWxlLgogICAgICAgICAgICAvLyBBcyBzb29uIGFzIHdlIHN0dW1ibGUgb24gYSBtb2R1bGUtaW5mby5qYXZhIGZpbGUgd2UgY2hhbmdlIHRvIHRoYXQgbW9kdWxlLgogICAgICAgICAgICBNb2R1bGUgY3VycmVudF9tb2R1bGUgPSBuZXcgTW9kdWxlKCIiLCAiIik7CiAgICAgICAgICAgIG1vZHVsZXMucHV0KCIiLCBjdXJyZW50X21vZHVsZSk7CgogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgLy8gRmluZCBhbGwgc291cmNlcywgdXNlIHRoZSBzdWZmaXggcnVsZXMgdG8ga25vdyB3aGljaCBmaWxlcyBhcmUgc291cmNlcy4KICAgICAgICAgICAgICAgIE1hcDxTdHJpbmcsU291cmNlPiBzb3VyY2VzID0gbmV3IEhhc2hNYXA8PigpOwoKICAgICAgICAgICAgICAgIC8vIEZpbmQgdGhlIGZpbGVzLCB0aGlzIHdpbGwgYXV0b21hdGljYWxseSBwb3B1bGF0ZSB0aGUgZm91bmQgbW9kdWxlcwogICAgICAgICAgICAgICAgLy8gd2l0aCBmb3VuZCBwYWNrYWdlcyB3aGVyZSB0aGUgc291cmNlcyBhcmUgZm91bmQhCiAgICAgICAgICAgICAgICBmaW5kU291cmNlRmlsZXMob3B0aW9ucy5nZXRTb3VyY2VzKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VmZml4UnVsZXMua2V5U2V0KCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc291cmNlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb2R1bGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRfbW9kdWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMuaXNEZWZhdWx0UGFja2FnZVBlcm1pdHRlZCgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbHNlKTsKCiAgICAgICAgICAgICAgICBpZiAoc291cmNlcy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICAgICAgICBMb2cuZXJyb3IoIkZvdW5kIG5vdGhpbmcgdG8gY29tcGlsZSEiKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gUmVzdWx0LkVSUk9SOwogICAgICAgICAgICAgICAgfQoKCiAgICAgICAgICAgICAgICAvLyBDcmVhdGUgYSBtYXAgb2YgYWxsIHNvdXJjZSBmaWxlcyB0aGF0IGFyZSBhdmFpbGFibGUgZm9yIGxpbmtpbmcuIEJvdGggLXNyYyBhbmQKICAgICAgICAgICAgICAgIC8vIC1zb3VyY2VwYXRoIHBvaW50IHRvIHN1Y2ggZmlsZXMuIEl0IGlzIHBvc3NpYmxlIHRvIHNwZWNpZnkgbXVsdGlwbGUKICAgICAgICAgICAgICAgIC8vIC1zb3VyY2VwYXRoIG9wdGlvbnMgdG8gZW5hYmxlIGRpZmZlcmVudCBmaWx0ZXJpbmcgcnVsZXMuIElmIHRoZQogICAgICAgICAgICAgICAgLy8gZmlsdGVycyBhcmUgdGhlIHNhbWUgZm9yIG11bHRpcGxlIHNvdXJjZXBhdGhzLCB0aGV5IG1heSBiZSBjb25jYXRlbmF0ZWQKICAgICAgICAgICAgICAgIC8vIHVzaW5nIDooOykuIEJlZm9yZSBzZW5kaW5nIHRoZSBsaXN0IG9mIHNvdXJjZXBhdGhzIHRvIGphdmFjLCB0aGV5IGFyZQogICAgICAgICAgICAgICAgLy8gYWxsIGNvbmNhdGVuYXRlZC4gVGhlIGxpc3QgY3JlYXRlZCBoZXJlIGlzIHVzZWQgYnkgdGhlIFNtYXJ0RmlsZVdyYXBwZXIgdG8KICAgICAgICAgICAgICAgIC8vIG1ha2Ugc3VyZSBvbmx5IHRoZSBjb3JyZWN0IHNvdXJjZXMgYXJlIGFjdHVhbGx5IGF2YWlsYWJsZS4KICAgICAgICAgICAgICAgIC8vIFdlIG1pZ2h0IGZpbmQgbW9yZSBtb2R1bGVzIGhlcmUgYXMgd2VsbC4KICAgICAgICAgICAgICAgIE1hcDxTdHJpbmcsU291cmNlPiBzb3VyY2VzX3RvX2xpbmtfdG8gPSBuZXcgSGFzaE1hcDw+KCk7CgogICAgICAgICAgICAgICAgTGlzdDxTb3VyY2VMb2NhdGlvbj4gc291cmNlUmVzb2x1dGlvbkxvY2F0aW9ucyA9IG5ldyBBcnJheUxpc3Q8PigpOwogICAgICAgICAgICAgICAgc291cmNlUmVzb2x1dGlvbkxvY2F0aW9ucy5hZGRBbGwob3B0aW9ucy5nZXRTb3VyY2VzKCkpOwogICAgICAgICAgICAgICAgc291cmNlUmVzb2x1dGlvbkxvY2F0aW9ucy5hZGRBbGwob3B0aW9ucy5nZXRTb3VyY2VTZWFyY2hQYXRocygpKTsKICAgICAgICAgICAgICAgIGZpbmRTb3VyY2VGaWxlcyhzb3VyY2VSZXNvbHV0aW9uTG9jYXRpb25zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbGxlY3Rpb25zLnNpbmdsZXRvbigiLmphdmEiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzb3VyY2VzX3RvX2xpbmtfdG8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9kdWxlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50X21vZHVsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zLmlzRGVmYXVsdFBhY2thZ2VQZXJtaXR0ZWQoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnVlKTsKCiAgICAgICAgICAgICAgICAvLyBBZGQgdGhlIHNldCBvZiBzb3VyY2VzIHRvIHRoZSBidWlsZCBkYXRhYmFzZS4KICAgICAgICAgICAgICAgIGphdmFjX3N0YXRlLm5vdygpLmZsYXR0ZW5QYWNrYWdlc1NvdXJjZXNBbmRBcnRpZmFjdHMobW9kdWxlcyk7CiAgICAgICAgICAgICAgICBqYXZhY19zdGF0ZS5ub3coKS5jaGVja0ludGVybmFsU3RhdGUoImNoZWNraW5nIHNvdXJjZXMiLCBmYWxzZSwgc291cmNlcyk7CiAgICAgICAgICAgICAgICBqYXZhY19zdGF0ZS5ub3coKS5jaGVja0ludGVybmFsU3RhdGUoImNoZWNraW5nIGxpbmtlZCBzb3VyY2VzIiwgdHJ1ZSwgc291cmNlc190b19saW5rX3RvKTsKICAgICAgICAgICAgICAgIGphdmFjX3N0YXRlLnNldFZpc2libGVTb3VyY2VzKHNvdXJjZXNfdG9fbGlua190byk7CgogICAgICAgICAgICAgICAgaW50IHJvdW5kID0gMDsKICAgICAgICAgICAgICAgIHByaW50Um91bmQocm91bmQpOwoKICAgICAgICAgICAgICAgIC8vIElmIHRoZXJlIGlzIGFueSBjaGFuZ2UgaW4gdGhlIHNvdXJjZSBmaWxlcywgdGFpbnQgcGFja2FnZXMKICAgICAgICAgICAgICAgIC8vIGFuZCBtYXJrIHRoZSBkYXRhYmFzZSBpbiBuZWVkIG9mIHNhdmluZy4KICAgICAgICAgICAgICAgIGphdmFjX3N0YXRlLmNoZWNrU291cmNlU3RhdHVzKGZhbHNlKTsKCiAgICAgICAgICAgICAgICAvLyBGaW5kIGFsbCBleGlzdGluZyBhcnRpZmFjdHMuIFRoZWlyIHRpbWVzdGFtcCB3aWxsIG1hdGNoIHRoZSBsYXN0IG1vZGlmaWVkIHRpbWVzdGFtcHMgc3RvcmVkCiAgICAgICAgICAgICAgICAvLyBpbiBqYXZhY19zdGF0ZSwgc2ltcGx5IGJlY2F1c2UgbG9hZGluZyBvZiB0aGUgSmF2YWNTdGF0ZSB3aWxsIGNsZWFuIG91dCBhbGwgYXJ0aWZhY3RzCiAgICAgICAgICAgICAgICAvLyB0aGF0IGRvIG5vdCBtYXRjaCB0aGUgamF2YWNfc3RhdGUgZGF0YWJhc2UuCiAgICAgICAgICAgICAgICBqYXZhY19zdGF0ZS5maW5kQWxsQXJ0aWZhY3RzKCk7CgogICAgICAgICAgICAgICAgLy8gUmVtb3ZlIHVuaWRlbnRpZmllZCBhcnRpZmFjdHMgZnJvbSB0aGUgYmluLCBnZW5zcmMgYW5kIGhlYWRlciBkaXJzLgogICAgICAgICAgICAgICAgLy8gKFVubGVzcyB3ZSBhbGxvdyB0aGVtIHRvIGJlIHRoZXJlLikKICAgICAgICAgICAgICAgIC8vIEkuZS4gYXJ0aWZhY3RzIHRoYXQgYXJlIG5vdCBrbm93biBhY2NvcmRpbmcgdG8gdGhlIGJ1aWxkIGRhdGFiYXNlIChqYXZhY19zdGF0ZSkuCiAgICAgICAgICAgICAgICAvLyBGb3IgZXhhbXBsZXMsIGZpbGVzIHRoYXQgaGF2ZSBiZWVuIG1hbnVhbGx5IGNvcGllZCBpbnRvIHRoZXNlIGRpcnMuCiAgICAgICAgICAgICAgICAvLyBBcnRpZmFjdHMgd2l0aCBiYWQgdGltZXN0YW1wcyAoaWUgdGhlIG9uIGRpc2sgdGltZXN0YW1wIGRvZXMgbm90IG1hdGNoIHRoZSB0aW1lc3RhbXAKICAgICAgICAgICAgICAgIC8vIGluIGphdmFjX3N0YXRlKSBoYXZlIGFscmVhZHkgYmVlbiByZW1vdmVkIHdoZW4gdGhlIGphdmFjX3N0YXRlIHdhcyBsb2FkZWQuCiAgICAgICAgICAgICAgICBpZiAoIW9wdGlvbnMuYXJlVW5pZGVudGlmaWVkQXJ0aWZhY3RzUGVybWl0dGVkKCkpIHsKICAgICAgICAgICAgICAgICAgICBqYXZhY19zdGF0ZS5yZW1vdmVVbmlkZW50aWZpZWRBcnRpZmFjdHMoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIC8vIEdvIHRocm91Z2ggYWxsIHNvdXJjZXMgYW5kIHRhaW50IGFsbCBwYWNrYWdlcyB0aGF0IG1pc3MgYXJ0aWZhY3RzLgogICAgICAgICAgICAgICAgamF2YWNfc3RhdGUudGFpbnRQYWNrYWdlc1RoYXRNaXNzQXJ0aWZhY3RzKCk7CgogICAgICAgICAgICAgICAgLy8gQ2hlY2sgcmVjb3JkZWQgY2xhc3NwYXRoIHB1YmxpYyBhcGlzLiBUYWludCBwYWNrYWdlcyB0aGF0IGRlcGVuZCBvbgogICAgICAgICAgICAgICAgLy8gY2xhc3NwYXRoIGNsYXNzZXMgd2hvc2UgcHVibGljIGFwaXMgaGF2ZSBjaGFuZ2VkLgogICAgICAgICAgICAgICAgamF2YWNfc3RhdGUudGFpbnRQYWNrYWdlc0RlcGVuZGluZ09uQ2hhbmdlZENsYXNzcGF0aFBhY2thZ2VzKCk7CgogICAgICAgICAgICAgICAgLy8gTm93IGNsZWFuIG91dCBhbGwga25vd24gYXJ0aWZhY3RzIGJlbG9uZ2luZyB0byB0YWludGVkIHBhY2thZ2VzLgogICAgICAgICAgICAgICAgamF2YWNfc3RhdGUuZGVsZXRlQ2xhc3NBcnRpZmFjdHNJblRhaW50ZWRQYWNrYWdlcygpOwogICAgICAgICAgICAgICAgLy8gQ29weSBmaWxlcywgZm9yIGV4YW1wbGUgcHJvcGVydHkgZmlsZXMsIGltYWdlcyBmaWxlcywgeG1sIGZpbGVzIGV0YyBldGMuCiAgICAgICAgICAgICAgICBqYXZhY19zdGF0ZS5wZXJmb3JtQ29weWluZyhVdGlsLnBhdGhUb0ZpbGUob3B0aW9ucy5nZXREZXN0RGlyKCkpLCBzdWZmaXhSdWxlcyk7CiAgICAgICAgICAgICAgICAvLyBUcmFuc2xhdGUgZmlsZXMsIGZvciBleGFtcGxlIGNvbXBpbGUgcHJvcGVydGllcyBvciBjb21waWxlIGlkbHMuCiAgICAgICAgICAgICAgICBqYXZhY19zdGF0ZS5wZXJmb3JtVHJhbnNsYXRpb24oVXRpbC5wYXRoVG9GaWxlKGdlbnNyYyksIHN1ZmZpeFJ1bGVzKTsKICAgICAgICAgICAgICAgIC8vIEFkZCBhbnkgcG90ZW50aWFsbHkgZ2VuZXJhdGVkIGphdmEgc291cmNlcyB0byB0aGUgdG9iZSBjb21waWxlZCBsaXN0LgogICAgICAgICAgICAgICAgLy8gKEdlbmVyYXRlZCBzb3VyY2VzIG11c3QgYWx3YXlzIGhhdmUgYSBwYWNrYWdlLikKICAgICAgICAgICAgICAgIE1hcDxTdHJpbmcsU291cmNlPiBnZW5lcmF0ZWRfc291cmNlcyA9IG5ldyBIYXNoTWFwPD4oKTsKCiAgICAgICAgICAgICAgICBTb3VyY2Uuc2NhblJvb3QoVXRpbC5wYXRoVG9GaWxlKG9wdGlvbnMuZ2V0R2VuU3JjRGlyKCkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFV0aWwuc2V0KCIuamF2YSIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbGxlY3Rpb25zLmVtcHR5TGlzdCgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbGxlY3Rpb25zLmVtcHR5TGlzdCgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdlbmVyYXRlZF9zb3VyY2VzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vZHVsZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudF9tb2R1bGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFsc2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWxzZSk7CiAgICAgICAgICAgICAgICBqYXZhY19zdGF0ZS5ub3coKS5mbGF0dGVuUGFja2FnZXNTb3VyY2VzQW5kQXJ0aWZhY3RzKG1vZHVsZXMpOwogICAgICAgICAgICAgICAgLy8gUmVjaGVjayB0aGUgdGhlIHNvdXJjZSBmaWxlcyBhbmQgdGhlaXIgdGltZXN0YW1wcyBhZ2Fpbi4KICAgICAgICAgICAgICAgIGphdmFjX3N0YXRlLmNoZWNrU291cmNlU3RhdHVzKHRydWUpOwoKICAgICAgICAgICAgICAgIC8vIE5vdyBkbyBhIHNhZmV0eSBjaGVjayB0aGF0IHRoZSBsaXN0IG9mIHNvdXJjZSBmaWxlcyBpcyBpZGVudGljYWwKICAgICAgICAgICAgICAgIC8vIHRvIHRoZSBsaXN0IE1ha2UgYmVsaWV2ZXMgd2UgYXJlIGNvbXBpbGluZy4gSWYgd2UgZG8gbm90IGdldCB0aGlzCiAgICAgICAgICAgICAgICAvLyByaWdodCwgdGhlbiBpbmNyZW1lbnRhbCBidWlsZHMgd2lsbCBmYWlsIHdpdGggc3VidGlsaXR5LgogICAgICAgICAgICAgICAgLy8gSWYgYW55IGRpZmZlcmVuY2UgaXMgZGV0ZWN0ZWQsIHRoZW4gd2Ugd2lsbCBmYWlsIGhhcmQgaGVyZS4KICAgICAgICAgICAgICAgIC8vIFRoaXMgaXMgYW4gaW1wb3J0YW50IHNhZmV0eSBuZXQuCiAgICAgICAgICAgICAgICBqYXZhY19zdGF0ZS5jb21wYXJlV2l0aE1ha2VmaWxlTGlzdChVdGlsLnBhdGhUb0ZpbGUob3B0aW9ucy5nZXRTb3VyY2VSZWZlcmVuY2VMaXN0KCkpKTsKCiAgICAgICAgICAgICAgICAvLyBEbyB0aGUgY29tcGlsYXRpb25zLCByZXBlYXRlZGx5IHVudGlsIG5vIHRhaW50ZWQgcGFja2FnZXMgZXhpc3QuCiAgICAgICAgICAgICAgICBib29sZWFuIGFnYWluOwogICAgICAgICAgICAgICAgLy8gQ29sbGVjdCB0aGUgbmFtZSBvZiBhbGwgY29tcGlsZWQgcGFja2FnZXMuCiAgICAgICAgICAgICAgICBTZXQ8U3RyaW5nPiByZWNlbnRseV9jb21waWxlZCA9IG5ldyBIYXNoU2V0PD4oKTsKICAgICAgICAgICAgICAgIGJvb2xlYW5bXSByYyA9IG5ldyBib29sZWFuWzFdOwoKICAgICAgICAgICAgICAgIENvbXBpbGF0aW9uU2VydmljZSBjb21waWxhdGlvblNlcnZpY2UgPSBuZXcgQ29tcGlsYXRpb25TZXJ2aWNlKCk7CiAgICAgICAgICAgICAgICBkbyB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHJvdW5kID4gMCkKICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnRSb3VuZChyb3VuZCk7CiAgICAgICAgICAgICAgICAgICAgLy8gQ2xlYW4gb3V0IGFydGlmYWN0cyBpbiB0YWludGVkIHBhY2thZ2VzLgogICAgICAgICAgICAgICAgICAgIGphdmFjX3N0YXRlLmRlbGV0ZUNsYXNzQXJ0aWZhY3RzSW5UYWludGVkUGFja2FnZXMoKTsKICAgICAgICAgICAgICAgICAgICBhZ2FpbiA9IGphdmFjX3N0YXRlLnBlcmZvcm1KYXZhQ29tcGlsYXRpb25zKGNvbXBpbGF0aW9uU2VydmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWNlbnRseV9jb21waWxlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJjKTsKICAgICAgICAgICAgICAgICAgICBpZiAoIXJjWzBdKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIExvZy5kZWJ1ZygiQ29tcGlsYXRpb24gZmFpbGVkLiIpOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKCFhZ2FpbikgewogICAgICAgICAgICAgICAgICAgICAgICBMb2cuZGVidWcoIk5vdGhpbmcgbGVmdCB0byBkby4iKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgcm91bmQrKzsKICAgICAgICAgICAgICAgIH0gd2hpbGUgKGFnYWluKTsKICAgICAgICAgICAgICAgIExvZy5kZWJ1ZygiTm8gbmVlZCB0byBkbyBhbm90aGVyIHJvdW5kLiIpOwoKICAgICAgICAgICAgICAgIC8vIE9ubHkgdXBkYXRlIHRoZSBzdGF0ZSBpZiB0aGUgY29tcGlsZSB3ZW50IHdlbGwuCiAgICAgICAgICAgICAgICBpZiAocmNbMF0pIHsKICAgICAgICAgICAgICAgICAgICBqYXZhY19zdGF0ZS5zYXZlKCk7CiAgICAgICAgICAgICAgICAgICAgLy8gUmVmbGF0dGVuIG9ubHkgdGhlIGFydGlmYWN0cy4KICAgICAgICAgICAgICAgICAgICBqYXZhY19zdGF0ZS5ub3coKS5mbGF0dGVuQXJ0aWZhY3RzKG1vZHVsZXMpOwogICAgICAgICAgICAgICAgICAgIC8vIFJlbW92ZSBhcnRpZmFjdHMgdGhhdCB3ZXJlIGdlbmVyYXRlZCBkdXJpbmcgdGhlIGxhc3QgY29tcGlsZSwgYnV0IG5vdCB0aGlzIG9uZS4KICAgICAgICAgICAgICAgICAgICBqYXZhY19zdGF0ZS5yZW1vdmVTdXBlcmZsdW91c0FydGlmYWN0cyhyZWNlbnRseV9jb21waWxlZCk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmV0dXJuIHJjWzBdID8gUmVzdWx0Lk9LIDogUmVzdWx0LkVSUk9SOwogICAgICAgICAgICB9IGNhdGNoIChQcm9ibGVtRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgICAgIC8vIEZvciBpbnN0YW5jZSBtYWtlIGZpbGUgbGlzdCBtaXNtYXRjaC4KICAgICAgICAgICAgICAgIExvZy5lcnJvcihlLmdldE1lc3NhZ2UoKSk7CiAgICAgICAgICAgICAgICBMb2cuZGVidWcoZSk7CiAgICAgICAgICAgICAgICByZXR1cm4gUmVzdWx0LkVSUk9SOwogICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgewogICAgICAgICAgICAgICAgTG9nLmVycm9yKGUpOwogICAgICAgICAgICAgICAgcmV0dXJuIFJlc3VsdC5FUlJPUjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHNodXRkb3duKCkgewogICAgICAgIC8vIE5vdGhpbmcgdG8gY2xlYW4gdXAKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIHZhbGlkYXRlT3B0aW9ucyhPcHRpb25zIG9wdGlvbnMpIHsKCiAgICAgICAgU3RyaW5nIGVyciA9IG51bGw7CgogICAgICAgIGlmIChvcHRpb25zLmdldERlc3REaXIoKSA9PSBudWxsKSB7CiAgICAgICAgICAgIGVyciA9ICJQbGVhc2Ugc3BlY2lmeSBvdXRwdXQgZGlyZWN0b3J5LiI7CiAgICAgICAgfSBlbHNlIGlmIChvcHRpb25zLmlzSmF2YUZpbGVzQW1vbmdKYXZhY0FyZ3MoKSkgewogICAgICAgICAgICBlcnIgPSAiU2phdmFjIGRvZXMgbm90IGhhbmRsZSBleHBsaWNpdCBjb21waWxhdGlvbiBvZiBzaW5nbGUgLmphdmEgZmlsZXMuIjsKICAgICAgICB9IGVsc2UgaWYgKCFvcHRpb25zLmdldEltcGxpY2l0UG9saWN5KCkuZXF1YWxzKCJub25lIikpIHsKICAgICAgICAgICAgZXJyID0gIlRoZSBvbmx5IGFsbG93ZWQgc2V0dGluZyBmb3Igc2phdmFjIGlzIC1pbXBsaWNpdDpub25lIjsKICAgICAgICB9IGVsc2UgaWYgKG9wdGlvbnMuZ2V0U291cmNlcygpLmlzRW1wdHkoKSAmJiBvcHRpb25zLmdldFN0YXRlRGlyKCkgIT0gbnVsbCkgewogICAgICAgICAgICBlcnIgPSAiWW91IGhhdmUgdG8gc3BlY2lmeSAtc3JjIHdoZW4gdXNpbmcgLS1zdGF0ZS1kaXIuIjsKICAgICAgICB9IGVsc2UgaWYgKG9wdGlvbnMuZ2V0VHJhbnNsYXRpb25SdWxlcygpLnNpemUoKSA+IDEKICAgICAgICAgICAgICAgICYmIG9wdGlvbnMuZ2V0R2VuU3JjRGlyKCkgPT0gbnVsbCkgewogICAgICAgICAgICBlcnIgPSAiWW91IGhhdmUgdHJhbnNsYXRvcnMgYnV0IG5vIGdlbnNyYyBkaXIgKC1zKSBzcGVjaWZpZWQhIjsKICAgICAgICB9CgogICAgICAgIGlmIChlcnIgIT0gbnVsbCkKICAgICAgICAgICAgTG9nLmVycm9yKGVycik7CgogICAgICAgIHJldHVybiBlcnIgPT0gbnVsbDsKCiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBzcmNEc3RPdmVybGFwKExpc3Q8U291cmNlTG9jYXRpb24+IGxvY3MsIFBhdGggZGVzdCkgewogICAgICAgIGZvciAoU291cmNlTG9jYXRpb24gbG9jIDogbG9jcykgewogICAgICAgICAgICBpZiAoaXNPdmVybGFwcGluZyhsb2MuZ2V0UGF0aCgpLCBkZXN0KSkgewogICAgICAgICAgICAgICAgTG9nLmVycm9yKCJTb3VyY2UgbG9jYXRpb24gIiArIGxvYy5nZXRQYXRoKCkgKyAiIG92ZXJsYXBzIHdpdGggZGVzdGluYXRpb24gIiArIGRlc3QpOwogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gaXNPdmVybGFwcGluZyhQYXRoIHAxLCBQYXRoIHAyKSB7CiAgICAgICAgcDEgPSBwMS50b0Fic29sdXRlUGF0aCgpLm5vcm1hbGl6ZSgpOwogICAgICAgIHAyID0gcDIudG9BYnNvbHV0ZVBhdGgoKS5ub3JtYWxpemUoKTsKICAgICAgICByZXR1cm4gcDEuc3RhcnRzV2l0aChwMikgfHwgcDIuc3RhcnRzV2l0aChwMSk7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBjcmVhdGVJZk1pc3NpbmcoUGF0aCBkaXIpIHsKCiAgICAgICAgaWYgKEZpbGVzLmlzRGlyZWN0b3J5KGRpcikpCiAgICAgICAgICAgIHJldHVybiB0cnVlOwoKICAgICAgICBpZiAoRmlsZXMuZXhpc3RzKGRpcikpIHsKICAgICAgICAgICAgTG9nLmVycm9yKGRpciArICIgaXMgbm90IGEgZGlyZWN0b3J5LiIpOwogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICB0cnkgewogICAgICAgICAgICBGaWxlcy5jcmVhdGVEaXJlY3RvcmllcyhkaXIpOwogICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgTG9nLmVycm9yKCJDb3VsZCBub3QgY3JlYXRlIGRpcmVjdG9yeTogIiArIGUuZ2V0TWVzc2FnZSgpKTsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgLyoqIEZpbmQgc291cmNlIGZpbGVzIGluIHRoZSBnaXZlbiBzb3VyY2UgbG9jYXRpb25zLiAqLwogICAgcHVibGljIHN0YXRpYyB2b2lkIGZpbmRTb3VyY2VGaWxlcyhMaXN0PFNvdXJjZUxvY2F0aW9uPiBzb3VyY2VMb2NhdGlvbnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNldDxTdHJpbmc+IHNvdXJjZVR5cGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYXA8U3RyaW5nLFNvdXJjZT4gZm91bmRGaWxlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWFwPFN0cmluZywgTW9kdWxlPiBmb3VuZE1vZHVsZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1vZHVsZSBjdXJyZW50TW9kdWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIHBlcm1pdFNvdXJjZXNJbkRlZmF1bHRQYWNrYWdlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGluTGlua3NyYykKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24gewoKICAgICAgICBmb3IgKFNvdXJjZUxvY2F0aW9uIHNvdXJjZSA6IHNvdXJjZUxvY2F0aW9ucykgewogICAgICAgICAgICBzb3VyY2UuZmluZFNvdXJjZUZpbGVzKHNvdXJjZVR5cGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvdW5kRmlsZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm91bmRNb2R1bGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRNb2R1bGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGVybWl0U291cmNlc0luRGVmYXVsdFBhY2thZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5MaW5rc3JjKTsKICAgICAgICB9CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBwcmludFJvdW5kKGludCByb3VuZCkgewogICAgICAgIExvZy5kZWJ1ZygiKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiIpOwogICAgICAgIExvZy5kZWJ1ZygiKiBSb3VuZCAiICsgcm91bmQgKyAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiIpOwogICAgICAgIExvZy5kZWJ1ZygiKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiIpOwogICAgfQp9ClBLAwQKAAAIAAAGO6lKpdynJT8PAAA/DwAAJgAAAGNvbS9zdW4vdG9vbHMvc2phdmFjL2NvbXAvUHViQVBJcy5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAxOTk5LCAyMDE1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuc2phdmFjLmNvbXA7CgppbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb247CmltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKaW1wb3J0IGphdmEudXRpbC5NYXA7CgppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5lbGVtZW50LkVsZW1lbnQ7CmltcG9ydCBqYXZheC50b29scy5KYXZhRmlsZU9iamVjdDsKCmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuU3ltYm9sLkNsYXNzU3ltYm9sOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkNvbnRleHQ7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuTG9nOwppbXBvcnQgY29tLnN1bi50b29scy5zamF2YWMucHViYXBpLlB1YkFwaTsKCi8qKgogKiBVdGlsaXR5IGNsYXNzIGNvbnRhaW5pbmcgcHVibGljIEFQSSBpbmZvcm1hdGlvbi4KICoKICogIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqICBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqICBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogKiAgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPgogKi8KcHVibGljIGNsYXNzIFB1YkFQSXMgewogICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBDb250ZXh0LktleTxQdWJBUElzPiBwdWJBcGlzS2V5ID0gbmV3IENvbnRleHQuS2V5PD4oKTsKCiAgICAvLyBUaGUgbG9nIHRvIGJlIHVzZWQgZm9yIGVycm9yIHJlcG9ydGluZy4KICAgIHByb3RlY3RlZCBMb2cgbG9nOwoKICAgIC8vIE1hcCBmcm9tIGEgY2xhc3MgbmFtZSB0byBpdHMgcHVibGljIGFwaS4KICAgIC8vIFdpbGwgdGhlIE5hbWUgZW5jb2RlIHRoZSBtb2R1bGUgaW4gdGhlIGZ1dHVyZT8KICAgIC8vIElmIG5vdCwgdGhpcyB3aWxsIGhhdmUgdG8gY2hhbmdlIHRvIG1hcCBmcm9tIE1vZHVsZStOYW1lIHRvIHB1YmxpYyBhcGkuCiAgICBwcm90ZWN0ZWQgTWFwPENsYXNzU3ltYm9sLCBQdWJBcGk+IHB1YmxpY0FwaVBlckNsYXNzID0gbmV3IEhhc2hNYXA8PigpOwoKICAgIHB1YmxpYyBzdGF0aWMgUHViQVBJcyBpbnN0YW5jZShDb250ZXh0IGNvbnRleHQpIHsKICAgICAgICBQdWJBUElzIGluc3RhbmNlID0gY29udGV4dC5nZXQocHViQXBpc0tleSk7CiAgICAgICAgaWYgKGluc3RhbmNlID09IG51bGwpCiAgICAgICAgICAgIGluc3RhbmNlID0gbmV3IFB1YkFQSXMoY29udGV4dCk7CiAgICAgICAgcmV0dXJuIGluc3RhbmNlOwogICAgfQoKICAgIHByaXZhdGUgUHViQVBJcyhDb250ZXh0IGNvbnRleHQpIHsKICAgICAgICBjb250ZXh0LnB1dChwdWJBcGlzS2V5LCB0aGlzKTsKICAgICAgICBsb2cgPSBMb2cuaW5zdGFuY2UoY29udGV4dCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDb252ZXJ0IHRoZSBtYXAgZnJvbSBjbGFzcyBuYW1lcyB0byB0aGVpciBwdWJhcGkgdG8gYSBtYXAKICAgICAqIGZyb20gcGFja2FnZSBuYW1lcyB0byB0aGVpciBwdWJhcGkuCiAgICAgKi8KICAgIHB1YmxpYyBNYXA8U3RyaW5nLCBQdWJBcGk+IGdldFB1YmFwaXMoQ29sbGVjdGlvbjxKYXZhRmlsZU9iamVjdD4gZXhwbGljaXRKRk9zLCBib29sZWFuIGV4cGxpY2l0cykgewoKICAgICAgICAvLyBNYXBzICI6amF2YS5sYW5nIiB0byBhIHBhY2thZ2UgbGV2ZWwgcHViIGFwaSAod2l0aCBvbmx5IHR5cGVzIG9uIHRvcCBsZXZlbCkKICAgICAgICBNYXA8U3RyaW5nLCBQdWJBcGk+IHJlc3VsdCA9IG5ldyBIYXNoTWFwPD4oKTsKICAgICAgICBmb3IgKENsYXNzU3ltYm9sIGNzIDogcHVibGljQXBpUGVyQ2xhc3Mua2V5U2V0KCkpIHsKCiAgICAgICAgICAgIGJvb2xlYW4gYW1vbmdFeHBsaWNpdHMgPSBleHBsaWNpdEpGT3MuY29udGFpbnMoY3Muc291cmNlZmlsZSk7CiAgICAgICAgICAgIGlmIChleHBsaWNpdHMgIT0gYW1vbmdFeHBsaWNpdHMpCiAgICAgICAgICAgICAgICBjb250aW51ZTsKCiAgICAgICAgICAgIFN0cmluZyBwa2cgPSAiOiIgKyBjcy5wYWNrZ2UoKS5mdWxsbmFtZTsKICAgICAgICAgICAgUHViQXBpIGN1cnJlbnRQdWJBcGkgPSByZXN1bHQuZ2V0T3JEZWZhdWx0KHBrZywgbmV3IFB1YkFwaSgpKTsKICAgICAgICAgICAgcmVzdWx0LnB1dChwa2csIFB1YkFwaS5tZXJnZVR5cGVzKGN1cnJlbnRQdWJBcGksIHB1YmxpY0FwaVBlckNsYXNzLmdldChjcykpKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBWaXNpdCB0aGUgYXBpIG9mIGEgY2xhc3MgYW5kIGNvbnN0cnVjdCBhIHB1YmFwaSBhbmQKICAgICAqIHN0b3JlIGl0IGludG8gdGhlIHB1YmFwaV9wZXJjbGFzcyBtYXAuCiAgICAgKi8KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJkZXByZWNhdGlvbiIpCiAgICBwdWJsaWMgdm9pZCB2aXNpdFB1YmFwaShFbGVtZW50IGUpIHsKCiAgICAgICAgLy8gU2tpcCBhbm9ueW1vdXMgY2xhc3NlcyBmb3Igbm93CiAgICAgICAgaWYgKGUgPT0gbnVsbCkKICAgICAgICAgICAgcmV0dXJuOwoKICAgICAgICBQdWJhcGlWaXNpdG9yIHYgPSBuZXcgUHViYXBpVmlzaXRvcigpOwogICAgICAgIHYudmlzaXQoZSk7CiAgICAgICAgcHVibGljQXBpUGVyQ2xhc3MucHV0KChDbGFzc1N5bWJvbCkgZSwgdi5nZXRDb2xsZWN0ZWRQdWJBcGkoKSk7CiAgICB9Cn0KUEsDBAoAAAgAAAY7qUqS2ICKZR0AAGUdAAAxAAAAY29tL3N1bi90b29scy9zamF2YWMvY29tcC9Db21waWxhdGlvblNlcnZpY2UuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAxNSwgMjAxNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLnNqYXZhYy5jb21wOwoKaW1wb3J0IGphdmEuaW8uRmlsZTsKaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CmltcG9ydCBqYXZhLmlvLlByaW50V3JpdGVyOwppbXBvcnQgamF2YS5pby5TdHJpbmdXcml0ZXI7CmltcG9ydCBqYXZhLm5ldC5VUkk7CmltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOwppbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOwppbXBvcnQgamF2YS51dGlsLkxpc3Q7CmltcG9ydCBqYXZhLnV0aWwuU2V0OwoKaW1wb3J0IGphdmF4LnRvb2xzLkphdmFGaWxlT2JqZWN0OwppbXBvcnQgamF2YXgudG9vbHMuU3RhbmRhcmRKYXZhRmlsZU1hbmFnZXI7CmltcG9ydCBqYXZheC50b29scy5TdGFuZGFyZExvY2F0aW9uOwppbXBvcnQgamF2YXgudG9vbHMuVG9vbFByb3ZpZGVyOwoKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuYXBpLkphdmFjVGFza0ltcGw7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmFwaS5KYXZhY1Rvb2w7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLm1haW4uTWFpbjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMubWFpbi5NYWluLlJlc3VsdDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5Db250ZXh0OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkRlcGVuZGVuY2llczsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5MaXN0QnVmZmVyOwppbXBvcnQgY29tLnN1bi50b29scy5zamF2YWMuTG9nOwppbXBvcnQgY29tLnN1bi50b29scy5zamF2YWMuVXRpbDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuc2phdmFjLmNvbXAuZGVwZW5kZW5jaWVzLk5ld0RlcGVuZGVuY3lDb2xsZWN0b3I7CmltcG9ydCBjb20uc3VuLnRvb2xzLnNqYXZhYy5jb21wLmRlcGVuZGVuY2llcy5QdWJsaWNBcGlDb2xsZWN0b3I7CmltcG9ydCBjb20uc3VuLnRvb2xzLnNqYXZhYy5zZXJ2ZXIuQ29tcGlsYXRpb25TdWJSZXN1bHQ7CmltcG9ydCBjb20uc3VuLnRvb2xzLnNqYXZhYy5zZXJ2ZXIuU3lzSW5mbzsKCi8qKgogKiAgPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24gcmlzay4KICogIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yCiAqICBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+CiAqLwpwdWJsaWMgY2xhc3MgQ29tcGlsYXRpb25TZXJ2aWNlIHsKCiAgICBwdWJsaWMgU3lzSW5mbyBnZXRTeXNJbmZvKCkgewogICAgICAgIHJldHVybiBuZXcgU3lzSW5mbyhSdW50aW1lLmdldFJ1bnRpbWUoKS5hdmFpbGFibGVQcm9jZXNzb3JzKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFJ1bnRpbWUuZ2V0UnVudGltZSgpLm1heE1lbW9yeSgpKTsKICAgIH0KCiAgICBwdWJsaWMgQ29tcGlsYXRpb25TdWJSZXN1bHQgY29tcGlsZShTdHJpbmcgcHJvdG9jb2xJZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBpbnZvY2F0aW9uSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmdbXSBhcmdzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTGlzdDxGaWxlPiBleHBsaWNpdFNvdXJjZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTZXQ8VVJJPiBzb3VyY2VzVG9Db21waWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU2V0PFVSST4gdmlzaWJsZVNvdXJjZXMpIHsKCiAgICAgICAgSmF2YWNUb29sIGNvbXBpbGVyID0gKEphdmFjVG9vbCkgVG9vbFByb3ZpZGVyLmdldFN5c3RlbUphdmFDb21waWxlcigpOwogICAgICAgIHRyeSAoU3RhbmRhcmRKYXZhRmlsZU1hbmFnZXIgZm0gPSBjb21waWxlci5nZXRTdGFuZGFyZEZpbGVNYW5hZ2VyKG51bGwsIG51bGwsIG51bGwpKSB7CiAgICAgICAgICAgIFNtYXJ0RmlsZU1hbmFnZXIgc2ZtID0gbmV3IFNtYXJ0RmlsZU1hbmFnZXIoZm0pOwogICAgICAgICAgICBDb250ZXh0IGNvbnRleHQgPSBuZXcgQ29udGV4dCgpOwoKICAgICAgICAgICAgRGVwZW5kZW5jaWVzLkdyYXBoRGVwZW5kZW5jaWVzLnByZVJlZ2lzdGVyKGNvbnRleHQpOwoKICAgICAgICAgICAgLy8gTm93IHNldHVwIHRoZSBhY3R1YWwgY29tcGlsYXRpb24KICAgICAgICAgICAgQ29tcGlsYXRpb25TdWJSZXN1bHQgY29tcGlsYXRpb25SZXN1bHQgPSBuZXcgQ29tcGlsYXRpb25TdWJSZXN1bHQoUmVzdWx0Lk9LKTsKCiAgICAgICAgICAgIC8vIEZpcnN0IGRlYWwgd2l0aCBleHBsaWNpdCBzb3VyY2UgZmlsZXMgb24gY21kbGluZSBhbmQgaW4gYXQgZmlsZQogICAgICAgICAgICBMaXN0QnVmZmVyPEphdmFGaWxlT2JqZWN0PiBleHBsaWNpdEpGT3MgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgIGZvciAoSmF2YUZpbGVPYmplY3QgamZvIDogZm0uZ2V0SmF2YUZpbGVPYmplY3RzRnJvbUZpbGVzKGV4cGxpY2l0U291cmNlcykpIHsKICAgICAgICAgICAgICAgIGV4cGxpY2l0SkZPcy5hcHBlbmQoU21hcnRGaWxlTWFuYWdlci5sb2NXcmFwKGpmbywgU3RhbmRhcmRMb2NhdGlvbi5TT1VSQ0VfUEFUSCkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIE5vdyBkZWFsIHdpdGggc291cmNlcyBzdXBwbGllZCBhcyBzb3VyY2VfdG9fY29tcGlsZQogICAgICAgICAgICBMaXN0QnVmZmVyPEZpbGU+IHNvdXJjZXNUb0NvbXBpbGVGaWxlcyA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICAgICAgZm9yIChVUkkgdSA6IHNvdXJjZXNUb0NvbXBpbGUpCiAgICAgICAgICAgICAgICBzb3VyY2VzVG9Db21waWxlRmlsZXMuYXBwZW5kKG5ldyBGaWxlKHUpKTsKCiAgICAgICAgICAgIGZvciAoSmF2YUZpbGVPYmplY3QgamZvIDogZm0uZ2V0SmF2YUZpbGVPYmplY3RzRnJvbUZpbGVzKHNvdXJjZXNUb0NvbXBpbGVGaWxlcykpCiAgICAgICAgICAgICAgICBleHBsaWNpdEpGT3MuYXBwZW5kKFNtYXJ0RmlsZU1hbmFnZXIubG9jV3JhcChqZm8sIFN0YW5kYXJkTG9jYXRpb24uU09VUkNFX1BBVEgpKTsKCiAgICAgICAgICAgIC8vIENyZWF0ZSBhIGxvZyB0byBjYXB0dXJlIGNvbXBpbGVyIG91dHB1dAogICAgICAgICAgICBTdHJpbmdXcml0ZXIgc3RkZXJyTG9nID0gbmV3IFN0cmluZ1dyaXRlcigpOwogICAgICAgICAgICBSZXN1bHQgcmVzdWx0OwogICAgICAgICAgICBQdWJsaWNBcGlDb2xsZWN0b3IgcHViQXBpQ29sbGVjdG9yID0gbmV3IFB1YmxpY0FwaUNvbGxlY3Rvcihjb250ZXh0LCBleHBsaWNpdEpGT3MpOwogICAgICAgICAgICBQYXRoQW5kUGFja2FnZVZlcmlmaWVyIHBhcFZlcmlmaWVyID0gbmV3IFBhdGhBbmRQYWNrYWdlVmVyaWZpZXIoKTsKICAgICAgICAgICAgTmV3RGVwZW5kZW5jeUNvbGxlY3RvciBkZXBzQ29sbGVjdG9yID0gbmV3IE5ld0RlcGVuZGVuY3lDb2xsZWN0b3IoY29udGV4dCwgZXhwbGljaXRKRk9zKTsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIGlmIChleHBsaWNpdEpGT3Muc2l6ZSgpID4gMCkgewogICAgICAgICAgICAgICAgICAgIHNmbS5zZXRWaXNpYmxlU291cmNlcyh2aXNpYmxlU291cmNlcyk7CiAgICAgICAgICAgICAgICAgICAgc2ZtLmNsZWFuQXJ0aWZhY3RzKCk7CgogICAgICAgICAgICAgICAgICAgIC8vIERvIHRoZSBjb21waWxhdGlvbiEKICAgICAgICAgICAgICAgICAgICBKYXZhY1Rhc2tJbXBsIHRhc2sgPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgKEphdmFjVGFza0ltcGwpIGNvbXBpbGVyLmdldFRhc2sobmV3IFByaW50V3JpdGVyKHN0ZGVyckxvZyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZm0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXJyYXlzLmFzTGlzdChhcmdzKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHBsaWNpdEpGT3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0KTsKICAgICAgICAgICAgICAgICAgICBzZm0uc2V0U3ltYm9sRmlsZUVuYWJsZWQoIWNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5PcHRpb25zLmluc3RhbmNlKGNvbnRleHQpLmlzU2V0KCJpZ25vcmUuc3ltYm9sLmZpbGUiKSk7CiAgICAgICAgICAgICAgICAgICAgdGFzay5hZGRUYXNrTGlzdGVuZXIoZGVwc0NvbGxlY3Rvcik7CiAgICAgICAgICAgICAgICAgICAgdGFzay5hZGRUYXNrTGlzdGVuZXIocHViQXBpQ29sbGVjdG9yKTsKICAgICAgICAgICAgICAgICAgICB0YXNrLmFkZFRhc2tMaXN0ZW5lcihwYXBWZXJpZmllcik7CiAgICAgICAgICAgICAgICAgICAgbG9nSmF2YWNJbnZvY2F0aW9uKGFyZ3MpOwogICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IHRhc2suZG9DYWxsKCk7CiAgICAgICAgICAgICAgICAgICAgTG9nLmRlYnVnKCJqYXZhYyByZXN1bHQ6ICIgKyByZXN1bHQpOwogICAgICAgICAgICAgICAgICAgIHNmbS5mbHVzaCgpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBSZXN1bHQuRVJST1I7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgICBMb2cuZXJyb3IoVXRpbC5nZXRTdGFja1RyYWNlKGUpKTsKICAgICAgICAgICAgICAgIHN0ZGVyckxvZy5hcHBlbmQoVXRpbC5nZXRTdGFja1RyYWNlKGUpKTsKICAgICAgICAgICAgICAgIHJlc3VsdCA9IFJlc3VsdC5FUlJPUjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgY29tcGlsYXRpb25SZXN1bHQucGFja2FnZUFydGlmYWN0cyA9IHNmbS5nZXRQYWNrYWdlQXJ0aWZhY3RzKCk7CgogICAgICAgICAgICBpZiAocGFwVmVyaWZpZXIuZXJyb3JzRGlzY292ZXJlZCgpKSB7CiAgICAgICAgICAgICAgICByZXN1bHQgPSBSZXN1bHQuRVJST1I7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGNvbXBpbGF0aW9uUmVzdWx0LnBhY2thZ2VEZXBlbmRlbmNpZXMgPSBkZXBzQ29sbGVjdG9yLmdldERlcGVuZGVuY2llcyhmYWxzZSk7CiAgICAgICAgICAgIGNvbXBpbGF0aW9uUmVzdWx0LnBhY2thZ2VDcERlcGVuZGVuY2llcyA9IGRlcHNDb2xsZWN0b3IuZ2V0RGVwZW5kZW5jaWVzKHRydWUpOwoKICAgICAgICAgICAgY29tcGlsYXRpb25SZXN1bHQucGFja2FnZVB1YmFwaXMgPSBwdWJBcGlDb2xsZWN0b3IuZ2V0UHViQXBpcyh0cnVlKTsKICAgICAgICAgICAgY29tcGlsYXRpb25SZXN1bHQuZGVwZW5kZW5jeVB1YmFwaXMgPSBwdWJBcGlDb2xsZWN0b3IuZ2V0UHViQXBpcyhmYWxzZSk7CiAgICAgICAgICAgIGNvbXBpbGF0aW9uUmVzdWx0LnN0ZGVyciA9IHN0ZGVyckxvZy50b1N0cmluZygpOwogICAgICAgICAgICBjb21waWxhdGlvblJlc3VsdC5yZXN1bHQgPSByZXN1bHQ7CgogICAgICAgICAgICByZXR1cm4gY29tcGlsYXRpb25SZXN1bHQ7CiAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZSk7CiAgICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgdm9pZCBsb2dKYXZhY0ludm9jYXRpb24oU3RyaW5nW10gYXJncykgewogICAgICAgIExvZy5kZWJ1ZygiSW52b2tpbmcgamF2YWMgd2l0aCBhcmdzIik7CiAgICAgICAgSXRlcmF0b3I8U3RyaW5nPiBhcmdJdGVyID0gQXJyYXlzLmFzTGlzdChhcmdzKS5pdGVyYXRvcigpOwogICAgICAgIHdoaWxlIChhcmdJdGVyLmhhc05leHQoKSkgewogICAgICAgICAgICBTdHJpbmcgYXJnID0gYXJnSXRlci5uZXh0KCk7CiAgICAgICAgICAgIFN0cmluZyBsaW5lID0gIiAgICAiICsgYXJnOwogICAgICAgICAgICBpZiAoYXJnLm1hdGNoZXMoIlxcLShkfGNwfGNsYXNzcGF0aHxzb3VyY2VwYXRofHNvdXJjZXx0YXJnZXQpIikKICAgICAgICAgICAgICAgICAgICAmJiBhcmdJdGVyLmhhc05leHQoKSkgewogICAgICAgICAgICAgICAgbGluZSArPSAiICIgKyBhcmdJdGVyLm5leHQoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBMb2cuZGVidWcobGluZSk7CiAgICAgICAgfQogICAgfQoKfQpQSwMECgAACAAABjupSiisfw45CQAAOQkAADkAAABjb20vc3VuL3Rvb2xzL3NqYXZhYy9jb21wL0phdmFGaWxlT2JqZWN0V2l0aExvY2F0aW9uLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTQsIDIwMTUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5zamF2YWMuY29tcDsKCmltcG9ydCBqYXZheC50b29scy5Gb3J3YXJkaW5nSmF2YUZpbGVPYmplY3Q7CmltcG9ydCBqYXZheC50b29scy5KYXZhRmlsZU1hbmFnZXIuTG9jYXRpb247CmltcG9ydCBqYXZheC50b29scy5KYXZhRmlsZU9iamVjdDsKCmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmFwaS5DbGllbnRDb2RlV3JhcHBlci5UcnVzdGVkOwoKQFRydXN0ZWQKcHVibGljIGNsYXNzIEphdmFGaWxlT2JqZWN0V2l0aExvY2F0aW9uPEYgZXh0ZW5kcyBKYXZhRmlsZU9iamVjdD4gZXh0ZW5kcyBGb3J3YXJkaW5nSmF2YUZpbGVPYmplY3Q8Rj4gewoKICAgIHByaXZhdGUgZmluYWwgTG9jYXRpb24gbG9jOwoKICAgIHB1YmxpYyBKYXZhRmlsZU9iamVjdFdpdGhMb2NhdGlvbihGIGRlbGVnYXRlLCBMb2NhdGlvbiBsb2MpIHsKICAgICAgICBzdXBlcihkZWxlZ2F0ZSk7CiAgICAgICAgdGhpcy5sb2MgPSBsb2M7CiAgICB9CgogICAgcHVibGljIExvY2F0aW9uIGdldExvY2F0aW9uKCkgewogICAgICAgIHJldHVybiBsb2M7CiAgICB9CgogICAgcHVibGljIEYgZ2V0RGVsZWdhdGUoKSB7CiAgICAgICAgcmV0dXJuIGZpbGVPYmplY3Q7CiAgICB9CgogICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKICAgICAgICByZXR1cm4gIkphdmFGaWxlT2JqZWN0V2l0aExvY2F0aW9uW2xvYzogIiArIGxvYyArICIsICIgKyBmaWxlT2JqZWN0ICsgIl0iOwogICAgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgICByZXR1cm4gbG9jLmhhc2hDb2RlKCkgXiBmaWxlT2JqZWN0Lmhhc2hDb2RlKCk7CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iaikgewogICAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIEphdmFGaWxlT2JqZWN0V2l0aExvY2F0aW9uKSkKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIEphdmFGaWxlT2JqZWN0V2l0aExvY2F0aW9uPD8+IG90aGVyID0gKEphdmFGaWxlT2JqZWN0V2l0aExvY2F0aW9uPD8+KSBvYmo7CiAgICAgICAgcmV0dXJuIGxvYy5lcXVhbHMob3RoZXIubG9jKSAmJiBmaWxlT2JqZWN0LmVxdWFscyhvdGhlci5maWxlT2JqZWN0KTsKICAgIH0KfQpQSwMECgAACAAA0n1NSqpGTHuxBgAAsQYAACoAAABjb20vc3VuL3Rvb2xzL3NqYXZhYy9Qcm9ibGVtRXhjZXB0aW9uLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTIsIDIwMTQsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5zamF2YWM7CgovKioKICogVXNlZCB0byBzaWduYWwgc2VyaW91cyBwcm9ibGVtcyB3aGVuIHJ1bm5pbmcgc2phdmFjLgogKgogKiAgPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24gcmlzay4KICogIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yCiAqICBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+CiAqLwpwdWJsaWMgY2xhc3MgUHJvYmxlbUV4Y2VwdGlvbiBleHRlbmRzIEV4Y2VwdGlvbiB7CiAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTMzODc1MTY5OTMxMjQyMjk5NDlMOwogICAgcHVibGljIFByb2JsZW1FeGNlcHRpb24oU3RyaW5nIHMpIHsKICAgICAgICBzdXBlcihzKTsKICAgIH0KfQpQSwMECgAACAAABjupSoG7yex5EQAAeREAACAAAABjb20vc3VuL3Rvb2xzL3NqYXZhYy9Nb2R1bGUuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAxMiwgMjAxNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLnNqYXZhYzsKCmltcG9ydCBqYXZhLmlvLkZpbGU7CmltcG9ydCBqYXZhLm5ldC5VUkk7CmltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKaW1wb3J0IGphdmEudXRpbC5NYXA7CmltcG9ydCBqYXZhLnV0aWwuU2V0OwoKaW1wb3J0IGNvbS5zdW4udG9vbHMuc2phdmFjLnB1YmFwaS5QdWJBcGk7CgovKioKICogVGhlIG1vZHVsZSBpcyB0aGUgcm9vdCBvZiBhIHNldCBvZiBwYWNrYWdlcy9zb3VyY2VzL2FydGlmYWN0cy4KICogQXQgdGhlIG1vbWVudCB0aGVyZSBpcyBvbmx5IG9uZSBtb2R1bGUgaW4gdXNlLCB0aGUgZW1wdHkvbm8tbmFtZS9kZWZhdWx0IG1vZHVsZS4KICoKICogIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqICBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqICBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogKiAgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPgogKi8KcHVibGljIGNsYXNzIE1vZHVsZSBpbXBsZW1lbnRzIENvbXBhcmFibGU8TW9kdWxlPiB7CiAgICBwcml2YXRlIFN0cmluZyBuYW1lOwogICAgcHJpdmF0ZSBTdHJpbmcgZGlybmFtZTsKICAgIHByaXZhdGUgTWFwPFN0cmluZyxQYWNrYWdlPiBwYWNrYWdlcyA9IG5ldyBIYXNoTWFwPD4oKTsKICAgIHByaXZhdGUgTWFwPFN0cmluZyxTb3VyY2U+IHNvdXJjZXMgPSBuZXcgSGFzaE1hcDw+KCk7CiAgICBwcml2YXRlIE1hcDxTdHJpbmcsRmlsZT4gYXJ0aWZhY3RzID0gbmV3IEhhc2hNYXA8PigpOwoKICAgIHB1YmxpYyBNb2R1bGUoU3RyaW5nIG4sIFN0cmluZyBkbikgewogICAgICAgIG5hbWUgPSBuOwogICAgICAgIGRpcm5hbWUgPSBuOwogICAgfQoKICAgIHB1YmxpYyBTdHJpbmcgbmFtZSgpIHsgcmV0dXJuIG5hbWU7IH0KICAgIHB1YmxpYyBTdHJpbmcgZGlybmFtZSgpIHsgcmV0dXJuIGRpcm5hbWU7IH0KICAgIHB1YmxpYyBNYXA8U3RyaW5nLFBhY2thZ2U+IHBhY2thZ2VzKCkgeyByZXR1cm4gcGFja2FnZXM7IH0KICAgIHB1YmxpYyBNYXA8U3RyaW5nLFNvdXJjZT4gc291cmNlcygpIHsgcmV0dXJuIHNvdXJjZXM7IH0KICAgIHB1YmxpYyBNYXA8U3RyaW5nLEZpbGU+IGFydGlmYWN0cygpIHsgcmV0dXJuIGFydGlmYWN0czsgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvKSB7CiAgICAgICAgcmV0dXJuIChvIGluc3RhbmNlb2YgTW9kdWxlKSAmJiBuYW1lLmVxdWFscygoKE1vZHVsZSlvKS5uYW1lKTsKICAgIH0KCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgICAgcmV0dXJuIG5hbWUuaGFzaENvZGUoKTsKICAgIH0KCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgY29tcGFyZVRvKE1vZHVsZSBvKSB7CiAgICAgICAgcmV0dXJuIG5hbWUuY29tcGFyZVRvKG8ubmFtZSk7CiAgICB9CgogICAgcHVibGljIHZvaWQgc2F2ZShTdHJpbmdCdWlsZGVyIGIpIHsKICAgICAgICBiLmFwcGVuZCgiTSAiKS5hcHBlbmQobmFtZSkuYXBwZW5kKCI6IikuYXBwZW5kKCJcbiIpOwogICAgICAgIFBhY2thZ2Uuc2F2ZVBhY2thZ2VzKHBhY2thZ2VzLCBiKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIE1vZHVsZSBsb2FkKFN0cmluZyBsKSB7CiAgICAgICAgaW50IGNwID0gbC5pbmRleE9mKCc6JywyKTsKICAgICAgICBpZiAoY3AgPT0gLTEpIHJldHVybiBudWxsOwogICAgICAgIFN0cmluZyBuYW1lID0gbC5zdWJzdHJpbmcoMixjcCk7CiAgICAgICAgcmV0dXJuIG5ldyBNb2R1bGUobmFtZSwgIiIpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBzYXZlTW9kdWxlcyhNYXA8U3RyaW5nLE1vZHVsZT4gbXMsIFN0cmluZ0J1aWxkZXIgYikgewogICAgICAgIGZvciAoTW9kdWxlIG0gOiBtcy52YWx1ZXMoKSkgewogICAgICAgICAgICBtLnNhdmUoYik7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyB2b2lkIGFkZFBhY2thZ2UoUGFja2FnZSBwKSB7CiAgICAgICAgcGFja2FnZXMucHV0KHAubmFtZSgpLCBwKTsKICAgIH0KCiAgICBwdWJsaWMgUGFja2FnZSBsb29rdXBQYWNrYWdlKFN0cmluZyBwa2cpIHsKICAgICAgICAvLyBTZWUgSkRLLTgwNzE5MDQKICAgICAgICBQYWNrYWdlIHAgPSBwYWNrYWdlcy5nZXQocGtnKTsKICAgICAgICBpZiAocCA9PSBudWxsKSB7CiAgICAgICAgICAgIHAgPSBuZXcgUGFja2FnZSh0aGlzLCBwa2cpOwogICAgICAgICAgICBwYWNrYWdlcy5wdXQocGtnLCBwKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHA7CiAgICB9CgogICAgcHVibGljIHZvaWQgYWRkU291cmNlKFN0cmluZyBwa2csIFNvdXJjZSBzcmMpIHsKICAgICAgICBQYWNrYWdlIHAgPSBsb29rdXBQYWNrYWdlKHBrZyk7CiAgICAgICAgc3JjLnNldFBhY2thZ2UocCk7CiAgICAgICAgcC5hZGRTb3VyY2Uoc3JjKTsKICAgICAgICBzb3VyY2VzLnB1dChzcmMuZmlsZSgpLmdldFBhdGgoKSwgc3JjKTsKICAgIH0KCiAgICBwdWJsaWMgU291cmNlIGxvb2t1cFNvdXJjZShTdHJpbmcgcGF0aCkgewogICAgICAgIHJldHVybiBzb3VyY2VzLmdldChwYXRoKTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCBhZGRBcnRpZmFjdHMoU3RyaW5nIHBrZywgU2V0PFVSST4gYXMpIHsKICAgICAgICBQYWNrYWdlIHAgPSBsb29rdXBQYWNrYWdlKHBrZyk7CiAgICAgICAgZm9yIChVUkkgdSA6IGFzKSB7CiAgICAgICAgICAgIHAuYWRkQXJ0aWZhY3QobmV3IEZpbGUodSkpOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgdm9pZCBzZXREZXBlbmRlbmNpZXMoU3RyaW5nIHBrZywgTWFwPFN0cmluZywgU2V0PFN0cmluZz4+IGRlcHMsIGJvb2xlYW4gY3ApIHsKICAgICAgICBsb29rdXBQYWNrYWdlKHBrZykuc2V0RGVwZW5kZW5jaWVzKGRlcHMsIGNwKTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCBzZXRQdWJhcGkoU3RyaW5nIHBrZywgUHViQXBpIHBzKSB7CiAgICAgICAgUGFja2FnZSBwID0gbG9va3VwUGFja2FnZShwa2cpOwogICAgICAgIHAuc2V0UHViYXBpKHBzKTsKICAgIH0KCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNQdWJhcGlDaGFuZ2VkKFN0cmluZyBwa2csIFB1YkFwaSBuZXdQdWJBcGkpIHsKICAgICAgICBQYWNrYWdlIHAgPSBsb29rdXBQYWNrYWdlKHBrZyk7CiAgICAgICAgcmV0dXJuIHAuaGFzUHViQXBpQ2hhbmdlZChuZXdQdWJBcGkpOwogICAgfQp9ClBLAwQKAAAIAAAGO6lK0Vfowo8TAACPEwAAIgAAAGNvbS9zdW4vdG9vbHMvc2phdmFjL0NvcHlGaWxlLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTIsIDIwMTYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5zamF2YWM7CgppbXBvcnQgamF2YS5pby5GaWxlOwppbXBvcnQgamF2YS5pby5GaWxlSW5wdXRTdHJlYW07CmltcG9ydCBqYXZhLmlvLkZpbGVPdXRwdXRTdHJlYW07CmltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwppbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOwppbXBvcnQgamF2YS5pby5Xcml0ZXI7CmltcG9ydCBqYXZhLm5ldC5VUkk7CmltcG9ydCBqYXZhLnV0aWwuSGFzaFNldDsKaW1wb3J0IGphdmEudXRpbC5NYXA7CmltcG9ydCBqYXZhLnV0aWwuU2V0OwoKaW1wb3J0IGNvbS5zdW4udG9vbHMuc2phdmFjLmNvbXAuQ29tcGlsYXRpb25TZXJ2aWNlOwppbXBvcnQgY29tLnN1bi50b29scy5zamF2YWMub3B0aW9ucy5PcHRpb25zOwppbXBvcnQgY29tLnN1bi50b29scy5zamF2YWMucHViYXBpLlB1YkFwaTsKCi8qKgogKiBUaGUgY29weSBmaWxlIHRyYW5zZm9ybSBzaW1wbHkgY29waWVzIGEgbWF0Y2hpbmcgZmlsZSBmcm9tIC1zcmMgdG8gLWQgLgogKiBTdWNoIGZpbGVzIGFyZSB0eXBpY2FsbHkgaW1hZ2VzLCB4bWwgZG9jdW1lbnRzIGFuZCBvdGhlciBkYXRhIGZpbGVzLgogKgogKiAgPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24gcmlzay4KICogIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yCiAqICBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+CiAqLwpwdWJsaWMgY2xhc3MgQ29weUZpbGUgaW1wbGVtZW50cyBUcmFuc2Zvcm1lciB7CgogICAgcHVibGljIHZvaWQgc2V0RXh0cmEoU3RyaW5nIGUpIHsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCBzZXRFeHRyYShPcHRpb25zIGEpIHsKICAgIH0KCiAgICBwdWJsaWMgYm9vbGVhbiB0cmFuc2Zvcm0oQ29tcGlsYXRpb25TZXJ2aWNlIGNvbXBpbGF0aW9uU2VydmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYXA8U3RyaW5nLFNldDxVUkk+PiBwa2dTcmNzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNldDxVUkk+IHZpc2libGVTcmNzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1hcDxTdHJpbmcsU2V0PFN0cmluZz4+IG9sZFBhY2thZ2VEZXBlbmRlbnRzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVSSSBkZXN0Um9vdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYXA8U3RyaW5nLFNldDxVUkk+PiAgICBwYWNrYWdlQXJ0aWZhY3RzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1hcDxTdHJpbmcsTWFwPFN0cmluZywgU2V0PFN0cmluZz4+PiBwYWNrYWdlRGVwZW5kZW5jaWVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1hcDxTdHJpbmcsTWFwPFN0cmluZywgU2V0PFN0cmluZz4+PiBwYWNrYWdlQ3BEZXBlbmRlbmNpZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWFwPFN0cmluZywgUHViQXBpPiBwYWNrYWdlUHViYXBpcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYXA8U3RyaW5nLCBQdWJBcGk+IGRlcGVuZGVuY3lQdWJhcGlzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBkZWJ1Z0xldmVsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gaW5jcmVtZW50YWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IG51bUNvcmVzKQogICAgewogICAgICAgIGJvb2xlYW4gcmMgPSB0cnVlOwogICAgICAgIFN0cmluZyBkZXN0X2ZpbGVuYW1lOwogICAgICAgIEZpbGUgZGVzdDsKCiAgICAgICAgZm9yIChTdHJpbmcgcGtnTmFtZSA6IHBrZ1NyY3Mua2V5U2V0KCkpIHsKICAgICAgICAgICAgU3RyaW5nIHBrZ05hbWVGID0gVXRpbC50b0ZpbGVTeXN0ZW1QYXRoKHBrZ05hbWUpOwogICAgICAgICAgICBmb3IgKFVSSSB1IDogcGtnU3Jjcy5nZXQocGtnTmFtZSkpIHsKICAgICAgICAgICAgICAgIEZpbGUgc3JjID0gbmV3IEZpbGUodSk7CiAgICAgICAgICAgICAgICBGaWxlIGRlc3REaXI7CiAgICAgICAgICAgICAgICBkZXN0RGlyID0gbmV3IEZpbGUoZGVzdFJvb3QuZ2V0UGF0aCgpK0ZpbGUuc2VwYXJhdG9yK3BrZ05hbWVGKTsKICAgICAgICAgICAgICAgIGRlc3RfZmlsZW5hbWUgPSBkZXN0Um9vdC5nZXRQYXRoKCkrRmlsZS5zZXBhcmF0b3IrcGtnTmFtZUYrRmlsZS5zZXBhcmF0b3Irc3JjLmdldE5hbWUoKTsKICAgICAgICAgICAgICAgIGRlc3QgPSBuZXcgRmlsZShkZXN0X2ZpbGVuYW1lKTsKCiAgICAgICAgICAgICAgICBpZiAoIWRlc3REaXIuaXNEaXJlY3RvcnkoKSkgewogICAgICAgICAgICAgICAgICAgIGlmICghZGVzdERpci5ta2RpcnMoKSkgewogICAgICAgICAgICAgICAgICAgICAgIExvZy5lcnJvcigiRXJyb3I6IFRoZSBjb3BpZXIgY291bGQgbm90IGNyZWF0ZSB0aGUgZGlyZWN0b3J5ICIrCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXN0RGlyLmdldFBhdGgoKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgU2V0PFVSST4gYXMgPSBwYWNrYWdlQXJ0aWZhY3RzLmdldChwa2dOYW1lKTsKICAgICAgICAgICAgICAgIGlmIChhcyA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgYXMgPSBuZXcgSGFzaFNldDw+KCk7CiAgICAgICAgICAgICAgICAgICAgcGFja2FnZUFydGlmYWN0cy5wdXQocGtnTmFtZSwgYXMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYXMuYWRkKGRlc3QudG9VUkkoKSk7CgogICAgICAgICAgICAgICAgaWYgKGRlc3QuZXhpc3RzKCkgJiYgZGVzdC5sYXN0TW9kaWZpZWQoKSA+IHNyYy5sYXN0TW9kaWZpZWQoKSkgewogICAgICAgICAgICAgICAgICAgIC8vIEEgY29waWVkIGZpbGUgZXhpc3RzLCBhbmQgaXRzIHRpbWVzdGFtcCBpcyBuZXdlciB0aGFuIHRoZSBzb3VyY2UuCiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgTG9nLmluZm8oIkNvcHlpbmcgIitwa2dOYW1lRitGaWxlLnNlcGFyYXRvcitzcmMuZ2V0TmFtZSgpKTsKCiAgICAgICAgICAgICAgICB0cnkgKElucHV0U3RyZWFtIGZpbiA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oc3JjKTsKICAgICAgICAgICAgICAgICAgICAgT3V0cHV0U3RyZWFtIGZvdXQgPSBuZXcgRmlsZU91dHB1dFN0cmVhbShkZXN0KSkgewogICAgICAgICAgICAgICAgICAgIGJ5dGVbXSBidWYgPSBuZXcgYnl0ZVsxMDI0XTsKICAgICAgICAgICAgICAgICAgICBpbnQgbGVuOwogICAgICAgICAgICAgICAgICAgIHdoaWxlICgobGVuID0gZmluLnJlYWQoYnVmKSkgPiAwKXsKICAgICAgICAgICAgICAgICAgICAgICAgZm91dC53cml0ZShidWYsIDAsIGxlbik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgY2F0Y2goSU9FeGNlcHRpb24gZSl7CiAgICAgICAgICAgICAgICAgICAgTG9nLmVycm9yKCJDb3VsZCBub3QgY29weSB0aGUgZmlsZSAiK3NyYy5nZXRQYXRoKCkrIiB0byAiK2Rlc3QuZ2V0UGF0aCgpKTsKICAgICAgICAgICAgICAgICAgICByYyA9IGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiByYzsKICAgIH0KfQpQSwMECgAACAAABjupSpZypRguEgAALhIAAB0AAABjb20vc3VuL3Rvb2xzL3NqYXZhYy9Mb2cuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAxMiwgMjAxNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLnNqYXZhYzsKCmltcG9ydCBqYXZhLmlvLlByaW50V3JpdGVyOwppbXBvcnQgamF2YS5pby5TdHJpbmdXcml0ZXI7CmltcG9ydCBqYXZhLmlvLldyaXRlcjsKaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CgovKioKICogVXRpbGl0eSBjbGFzcyBvbmx5IGZvciBzamF2YWMgbG9nZ2luZy4KICoKICogTG9nZ2luZyBpbiBzamF2YWMgaGFzIHNwZWNpYWwgcmVxdWlyZW1lbnRzIHdoZW4gcnVubmluZyBpbiBzZXJ2ZXIvY2xpZW50CiAqIG1vZGUuIE1vc3Qgb2YgdGhlIGxvZyBtZXNzYWdlcyBpcyBnZW5lcmF0ZWQgc2VydmVyLXNpZGUsIGJ1dCB0aGUgc2VydmVyCiAqIGlzIHR5cGljYWxseSBzcGF3bmVkIGJ5IHRoZSBjbGllbnQgaW4gdGhlIGJhY2tncm91bmQsIHNvIHRoZSB1c2VyIHVzdWFsbHkKICogZG9lcyBub3Qgc2VlIHRoZSBzZXJ2ZXIgc3Rkb3V0L3N0ZGVyci4gRm9yIHRoaXMgcmVhc29uIGxvZyBtZXNzYWdlcyBuZWVkcwogKiB0byByZWxheWVkIGJhY2sgdG8gdGhlIGNsaWVudCB0aGF0IHBlcmZvcm1lZCB0aGUgcmVxdWVzdCB0aGF0IGdlbmVyYXRlZCB0aGUKICogbG9nIG1lc3NhZ2UuIFRvIHN1cHBvcnQgdGhpcyB1c2UgY2FzZSB0aGlzIGNsYXNzIG1haW50YWlucyBhIHBlci10aHJlYWQgbG9nCiAqIGluc3RhbmNlIHNvIHRoYXQgZWFjaCBjb25uZWN0ZWQgY2xpZW50IGNhbiBoYXZlIGl0cyBvd24gaW5zdGFuY2UgdGhhdAogKiByZWxheXMgbWVzc2FnZXMgYmFjayB0byB0aGUgcmVxdWVzdGluZyBjbGllbnQuCiAqCiAqIE9uIHRoZSBjbGllbnQtc2lkZSAob3Igd2hlbiBydW5uaW5nIHNqYXZhYyB3aXRob3V0IHNlcnZlci1tb2RlKSB0aGVyZSB3aWxsCiAqIHR5cGljYWxseSBqdXN0IGJlIG9uZSBMb2cgaW5zdGFuY2UuCiAqCiAqICA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiAgSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93biByaXNrLgogKiAgVGhpcyBjb2RlIGFuZCBpdHMgaW50ZXJuYWwgaW50ZXJmYWNlcyBhcmUgc3ViamVjdCB0byBjaGFuZ2Ugb3IKICogIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj4KICovCnB1YmxpYyBjbGFzcyBMb2cgewoKICAgIHB1YmxpYyBlbnVtIExldmVsIHsKICAgICAgICBFUlJPUiwKICAgICAgICBXQVJOLAogICAgICAgIElORk8sCiAgICAgICAgREVCVUcsCiAgICAgICAgVFJBQ0U7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgTG9nIHN0ZE91dEVyciA9IG5ldyBMb2cobmV3IFByaW50V3JpdGVyKFN5c3RlbS5vdXQpLCBuZXcgUHJpbnRXcml0ZXIoU3lzdGVtLmVycikpOwogICAgcHJpdmF0ZSBzdGF0aWMgVGhyZWFkTG9jYWw8TG9nPiBsb2dnZXJzID0gbmV3IFRocmVhZExvY2FsPD4oKTsKCiAgICBwcm90ZWN0ZWQgUHJpbnRXcml0ZXIgZXJyOyAvLyBVc2VkIGZvciBlcnJvciBhbmQgd2FybmluZyBtZXNzYWdlcwogICAgcHJvdGVjdGVkIFByaW50V3JpdGVyIG91dDsgLy8gVXNlZCBmb3Igb3RoZXIgbWVzc2FnZXMKICAgIHByb3RlY3RlZCBMZXZlbCBsZXZlbCA9IExldmVsLklORk87CgogICAgcHVibGljIExvZyhXcml0ZXIgb3V0LCBXcml0ZXIgZXJyKSB7CiAgICAgICAgdGhpcy5vdXQgPSBvdXQgPT0gbnVsbCA/IG51bGwgOiBuZXcgUHJpbnRXcml0ZXIob3V0LCB0cnVlKTsKICAgICAgICB0aGlzLmVyciA9IGVyciA9PSBudWxsID8gbnVsbCA6IG5ldyBQcmludFdyaXRlcihlcnIsIHRydWUpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBzZXRMb2dGb3JDdXJyZW50VGhyZWFkKExvZyBsb2cpIHsKICAgICAgICBsb2dnZXJzLnNldChsb2cpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBzZXRMb2dMZXZlbChTdHJpbmcgbCkgewogICAgICAgIHNldExvZ0xldmVsKExldmVsLnZhbHVlT2YobC50b1VwcGVyQ2FzZShMb2NhbGUuVVMpKSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyB2b2lkIHNldExvZ0xldmVsKExldmVsIGwpIHsKICAgICAgICBnZXQoKS5sZXZlbCA9IGw7CiAgICB9CgogICAgc3RhdGljIHB1YmxpYyB2b2lkIHRyYWNlKFN0cmluZyBtc2cpIHsKICAgICAgICBsb2coTGV2ZWwuVFJBQ0UsIG1zZyk7CiAgICB9CgogICAgc3RhdGljIHB1YmxpYyB2b2lkIGRlYnVnKFN0cmluZyBtc2cpIHsKICAgICAgICBsb2coTGV2ZWwuREVCVUcsIG1zZyk7CiAgICB9CgogICAgc3RhdGljIHB1YmxpYyB2b2lkIGluZm8oU3RyaW5nIG1zZykgewogICAgICAgIGxvZyhMZXZlbC5JTkZPLCBtc2cpOwogICAgfQoKICAgIHN0YXRpYyBwdWJsaWMgdm9pZCB3YXJuKFN0cmluZyBtc2cpIHsKICAgICAgICBsb2coTGV2ZWwuV0FSTiwgbXNnKTsKICAgIH0KCiAgICBzdGF0aWMgcHVibGljIHZvaWQgZXJyb3IoU3RyaW5nIG1zZykgewogICAgICAgIGxvZyhMZXZlbC5FUlJPUiwgbXNnKTsKICAgIH0KCiAgICBzdGF0aWMgcHVibGljIHZvaWQgZXJyb3IoVGhyb3dhYmxlIHQpIHsKICAgICAgICBsb2coTGV2ZWwuRVJST1IsIHQpOwogICAgfQoKICAgIHN0YXRpYyBwdWJsaWMgdm9pZCBsb2coTGV2ZWwgbCwgU3RyaW5nIG1zZykgewogICAgICAgIGdldCgpLnByaW50TG9nTXNnKGwsIG1zZyk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyB2b2lkIGRlYnVnKFRocm93YWJsZSB0KSB7CiAgICAgICAgbG9nKExldmVsLkRFQlVHLCB0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHZvaWQgbG9nKExldmVsIGwsIFRocm93YWJsZSB0KSB7CiAgICAgICAgU3RyaW5nV3JpdGVyIHN3ID0gbmV3IFN0cmluZ1dyaXRlcigpOwogICAgICAgIHQucHJpbnRTdGFja1RyYWNlKG5ldyBQcmludFdyaXRlcihzdywgdHJ1ZSkpOwogICAgICAgIGxvZyhsLCBzdy50b1N0cmluZygpKTsKICAgIH0KCiAgICBzdGF0aWMgcHVibGljIGJvb2xlYW4gaXNEZWJ1Z2dpbmcoKSB7CiAgICAgICAgcmV0dXJuIGdldCgpLmlzTGV2ZWxMb2dnZWQoTGV2ZWwuREVCVUcpOwogICAgfQoKICAgIHByb3RlY3RlZCBib29sZWFuIGlzTGV2ZWxMb2dnZWQoTGV2ZWwgbCkgewogICAgICAgIHJldHVybiBsLm9yZGluYWwoKSA8PSBsZXZlbC5vcmRpbmFsKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBMb2cgZ2V0KCkgewogICAgICAgIExvZyBsb2cgPSBsb2dnZXJzLmdldCgpOwogICAgICAgIHJldHVybiBsb2cgIT0gbnVsbCA/IGxvZyA6IHN0ZE91dEVycjsKICAgIH0KCiAgICBwcm90ZWN0ZWQgdm9pZCBwcmludExvZ01zZyhMZXZlbCBtc2dMZXZlbCwgU3RyaW5nIG1zZykgewogICAgICAgIGlmIChpc0xldmVsTG9nZ2VkKG1zZ0xldmVsKSkgewogICAgICAgICAgICBQcmludFdyaXRlciBwdyA9IG1zZ0xldmVsLm9yZGluYWwoKSA8PSBMZXZlbC5XQVJOLm9yZGluYWwoKSA/IGVyciA6IG91dDsKICAgICAgICAgICAgcHcucHJpbnRsbihtc2cpOwogICAgICAgIH0KICAgIH0KfQpQSwMECgAACAAABjupSgAAAAAAAAAAAAAAABwAAABjb20vc3VuL3Rvb2xzL3NqYXZhYy9wdWJhcGkvUEsDBAoAAAgAAAY7qUpYDB4eLwgAAC8IAAAyAAAAY29tL3N1bi90b29scy9zamF2YWMvcHViYXBpL1JlZmVyZW5jZVR5cGVEZXNjLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTQsIDIwMTUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5zamF2YWMucHViYXBpOwoKaW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOwoKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwudHlwZS5UeXBlS2luZDsKCnB1YmxpYyBjbGFzcyBSZWZlcmVuY2VUeXBlRGVzYyBleHRlbmRzIFR5cGVEZXNjIGltcGxlbWVudHMgU2VyaWFsaXphYmxlIHsKCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAzMzU3NjE2NzU0NTQ0Nzk2MzcyTDsKCiAgICAvLyBFeGFtcGxlOiAiamF2YS51dGlsLlZlY3RvcjxqYXZhLmxhbmcuU3RyaW5nPiIKICAgIFN0cmluZyBqYXZhVHlwZTsKCiAgICBwdWJsaWMgUmVmZXJlbmNlVHlwZURlc2MoU3RyaW5nIGphdmFUeXBlKSB7CiAgICAgICAgc3VwZXIoVHlwZUtpbmQuREVDTEFSRUQpOwogICAgICAgIHRoaXMuamF2YVR5cGUgPSBqYXZhVHlwZTsKICAgIH0KCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqKSB7CiAgICAgICAgaWYgKCFzdXBlci5lcXVhbHMob2JqKSkKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIHJldHVybiBqYXZhVHlwZS5lcXVhbHMoKChSZWZlcmVuY2VUeXBlRGVzYykgb2JqKS5qYXZhVHlwZSk7CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICAgIHJldHVybiBzdXBlci5oYXNoQ29kZSgpIF4gamF2YVR5cGUuaGFzaENvZGUoKTsKICAgIH0KCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CiAgICAgICAgcmV0dXJuIFN0cmluZy5mb3JtYXQoIiVzW3R5cGU6ICVzXSIsIGdldENsYXNzKCkuZ2V0U2ltcGxlTmFtZSgpLCBqYXZhVHlwZSk7CiAgICB9Cn0KUEsDBAoAAAgAAAY7qUo41kaIKxEAACsRAAAqAAAAY29tL3N1bi90b29scy9zamF2YWMvcHViYXBpL1B1Yk1ldGhvZC5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDE0LCAyMDE1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuc2phdmFjLnB1YmFwaTsKCmltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKaW1wb3J0IGphdmEudXRpbC5MaXN0OwppbXBvcnQgamF2YS51dGlsLlNldDsKaW1wb3J0IGphdmEudXRpbC5zdHJlYW0uQ29sbGVjdG9yczsKCmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuTW9kaWZpZXI7CgpwdWJsaWMgY2xhc3MgUHViTWV0aG9kIGltcGxlbWVudHMgU2VyaWFsaXphYmxlIHsKCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNzgxMzA1MDE5NDU1MzQ0NjI0M0w7CgogICAgU2V0PE1vZGlmaWVyPiBtb2RpZmllcnM7CiAgICBMaXN0PFB1YkFwaVR5cGVQYXJhbT4gdHlwZVBhcmFtczsKICAgIFR5cGVEZXNjIHJldHVyblR5cGU7CiAgICBTdHJpbmcgaWRlbnRpZmllcjsKICAgIExpc3Q8VHlwZURlc2M+IHBhcmFtVHlwZXM7CiAgICBMaXN0PFR5cGVEZXNjPiB0aHJvd0RlY2xzOwoKICAgIHB1YmxpYyBQdWJNZXRob2QoU2V0PE1vZGlmaWVyPiBtb2RpZmllcnMsCiAgICAgICAgICAgICAgICAgICAgIExpc3Q8UHViQXBpVHlwZVBhcmFtPiB0eXBlUGFyYW1zLAogICAgICAgICAgICAgICAgICAgICBUeXBlRGVzYyByZXR1cm5UeXBlLAogICAgICAgICAgICAgICAgICAgICBTdHJpbmcgaWRlbnRpZmllciwKICAgICAgICAgICAgICAgICAgICAgTGlzdDxUeXBlRGVzYz4gcGFyYW1UeXBlcywKICAgICAgICAgICAgICAgICAgICAgTGlzdDxUeXBlRGVzYz4gdGhyb3dEZWNscykgewogICAgICAgIHRoaXMubW9kaWZpZXJzID0gbW9kaWZpZXJzOwogICAgICAgIHRoaXMudHlwZVBhcmFtcyA9IHR5cGVQYXJhbXM7CiAgICAgICAgdGhpcy5yZXR1cm5UeXBlID0gcmV0dXJuVHlwZTsKICAgICAgICB0aGlzLmlkZW50aWZpZXIgPSBpZGVudGlmaWVyOwogICAgICAgIHRoaXMucGFyYW1UeXBlcyA9IHBhcmFtVHlwZXM7CiAgICAgICAgdGhpcy50aHJvd0RlY2xzID0gdGhyb3dEZWNsczsKICAgIH0KCiAgICAvLyBXZSBuZWVkIHRvIGluY2x1ZGUgcmV0dXJuIHR5cGUgYW5kIHR5cGUgcGFyYW1ldGVycyB0byBiZSBzdXJlIHRvIGhhdmUKICAgIC8vIGRpZmZlcmVudCB2YWx1ZXMgZm9yIGRpZmZlcmVudCBtZXRob2RzLiAoQSBtZXRob2QgY2FuIGJlIG92ZXJsb2FkZWQgd2l0aAogICAgLy8gdGhlIG9ubHkgZGlmZmVyZW5jZSBiZWluZyB0aGUgdXBwZXIgYm91bmQgb2YgdGhlIHJldHVybiB0eXBlLikKICAgIHB1YmxpYyBTdHJpbmcgYXNTaWduYXR1cmVTdHJpbmcoKSB7CiAgICAgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CgogICAgICAgIC8vIDxBIGV4dGVuZHMgU3RyaW5nLCBTZXJpYWxpemFibGUsIEIgZXh0ZW5kcyBMaXN0PgogICAgICAgIGlmICh0eXBlUGFyYW1zLnNpemUoKSA+IDApIHsKICAgICAgICAgICAgc2IuYXBwZW5kKHR5cGVQYXJhbXMuc3RyZWFtKCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAubWFwKFB1YkFwaVR5cGVQYXJhbTo6YXNTdHJpbmcpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmNvbGxlY3QoQ29sbGVjdG9ycy5qb2luaW5nKCIsIiwgIjwiLCAiPiAiKSkpOwogICAgICAgIH0KICAgICAgICBzYi5hcHBlbmQoVHlwZURlc2MuZW5jb2RlQXNTdHJpbmcocmV0dXJuVHlwZSkpOwogICAgICAgIHNiLmFwcGVuZCgiICIpOwogICAgICAgIHNiLmFwcGVuZChpZGVudGlmaWVyKTsKICAgICAgICBzYi5hcHBlbmQoIigiKTsKICAgICAgICBzYi5hcHBlbmQocGFyYW1UeXBlcy5zdHJlYW0oKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgLm1hcChUeXBlRGVzYzo6ZW5jb2RlQXNTdHJpbmcpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY29sbGVjdChDb2xsZWN0b3JzLmpvaW5pbmcoIiwiKSkpOwogICAgICAgIHNiLmFwcGVuZCgiKSIpOwogICAgICAgIHJldHVybiBzYi50b1N0cmluZygpOwogICAgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmopIHsKICAgICAgICBpZiAoZ2V0Q2xhc3MoKSAhPSBvYmouZ2V0Q2xhc3MoKSkKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIFB1Yk1ldGhvZCBvdGhlciA9IChQdWJNZXRob2QpIG9iajsKICAgICAgICByZXR1cm4gbW9kaWZpZXJzLmVxdWFscyhvdGhlci5tb2RpZmllcnMpCiAgICAgICAgICAgICYmIHR5cGVQYXJhbXMuZXF1YWxzKG90aGVyLnR5cGVQYXJhbXMpCiAgICAgICAgICAgICYmIHJldHVyblR5cGUuZXF1YWxzKG90aGVyLnJldHVyblR5cGUpCiAgICAgICAgICAgICYmIGlkZW50aWZpZXIuZXF1YWxzKG90aGVyLmlkZW50aWZpZXIpCiAgICAgICAgICAgICYmIHBhcmFtVHlwZXMuZXF1YWxzKG90aGVyLnBhcmFtVHlwZXMpCiAgICAgICAgICAgICYmIHRocm93RGVjbHMuZXF1YWxzKG90aGVyLnRocm93RGVjbHMpOwogICAgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgICByZXR1cm4gbW9kaWZpZXJzLmhhc2hDb2RlKCkKICAgICAgICAgICAgIF4gdHlwZVBhcmFtcy5oYXNoQ29kZSgpCiAgICAgICAgICAgICBeIHJldHVyblR5cGUuaGFzaENvZGUoKQogICAgICAgICAgICAgXiBpZGVudGlmaWVyLmhhc2hDb2RlKCkKICAgICAgICAgICAgIF4gcGFyYW1UeXBlcy5oYXNoQ29kZSgpCiAgICAgICAgICAgICBeIHRocm93RGVjbHMuaGFzaENvZGUoKTsKICAgIH0KCiAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewogICAgICAgIHJldHVybiBTdHJpbmcuZm9ybWF0KCIlc1ttb2RpZmllcnM6ICVzLCB0eXBlUGFyYW1zOiAlcywgcmV0VHlwZTogJXMsIGlkZW50aWZpZXI6ICVzLCBwYXJhbXM6ICVzLCB0aHJvd3M6ICVzXSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0Q2xhc3MoKS5nZXRTaW1wbGVOYW1lKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9kaWZpZXJzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVQYXJhbXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZGVudGlmaWVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtVHlwZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dEZWNscyk7CiAgICB9Cn0KUEsDBAoAAAgAAAY7qUpOjHqAhQcAAIUHAAAuAAAAY29tL3N1bi90b29scy9zamF2YWMvcHViYXBpL0FycmF5VHlwZURlc2MuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAxNCwgMjAxNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLnNqYXZhYy5wdWJhcGk7CgppbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGU7CgppbXBvcnQgamF2YXgubGFuZy5tb2RlbC50eXBlLlR5cGVLaW5kOwoKcHVibGljIGNsYXNzIEFycmF5VHlwZURlc2MgZXh0ZW5kcyBUeXBlRGVzYyBpbXBsZW1lbnRzIFNlcmlhbGl6YWJsZSB7CgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTExNzczMjk1NDkxNjMzMTQ5OTZMOwoKICAgIFR5cGVEZXNjIGNvbXBUeXBlRGVzYzsKCiAgICBwdWJsaWMgQXJyYXlUeXBlRGVzYyhUeXBlRGVzYyBjb21wVHlwZURlc2MpIHsKICAgICAgICBzdXBlcihUeXBlS2luZC5BUlJBWSk7CiAgICAgICAgdGhpcy5jb21wVHlwZURlc2MgPSBjb21wVHlwZURlc2M7CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iaikgewogICAgICAgIGlmICghc3VwZXIuZXF1YWxzKG9iaikpCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICByZXR1cm4gY29tcFR5cGVEZXNjLmVxdWFscygoKEFycmF5VHlwZURlc2MpIG9iaikuY29tcFR5cGVEZXNjKTsKICAgIH0KCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmhhc2hDb2RlKCkgXiBjb21wVHlwZURlc2MuaGFzaENvZGUoKTsKICAgIH0KCn0KUEsDBAoAAAgAAAY7qUpY/a4BVwoAAFcKAAAwAAAAY29tL3N1bi90b29scy9zamF2YWMvcHViYXBpL1B1YkFwaVR5cGVQYXJhbS5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDE1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuc2phdmFjLnB1YmFwaTsKCmltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKaW1wb3J0IGphdmEudXRpbC5MaXN0OwppbXBvcnQgamF2YS51dGlsLnN0cmVhbS5Db2xsZWN0b3JzOwoKcHVibGljIGNsYXNzIFB1YkFwaVR5cGVQYXJhbSBpbXBsZW1lbnRzIFNlcmlhbGl6YWJsZSB7CgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gODg5OTIwNDYxMjAxNDMyOTE2Mkw7CgogICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgaWRlbnRpZmllcjsKICAgIHByaXZhdGUgZmluYWwgTGlzdDxUeXBlRGVzYz4gYm91bmRzOwoKICAgIHB1YmxpYyBQdWJBcGlUeXBlUGFyYW0oU3RyaW5nIGlkZW50aWZpZXIsIExpc3Q8VHlwZURlc2M+IGJvdW5kcykgewogICAgICAgIHRoaXMuaWRlbnRpZmllciA9IGlkZW50aWZpZXI7CiAgICAgICAgdGhpcy5ib3VuZHMgPSBib3VuZHM7CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iaikgewogICAgICAgIGlmIChnZXRDbGFzcygpICE9IG9iai5nZXRDbGFzcygpKQogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgUHViQXBpVHlwZVBhcmFtIG90aGVyID0gKFB1YkFwaVR5cGVQYXJhbSkgb2JqOwogICAgICAgIHJldHVybiBpZGVudGlmaWVyLmVxdWFscyhvdGhlci5pZGVudGlmaWVyKQogICAgICAgICAgICAmJiBib3VuZHMuZXF1YWxzKG90aGVyLmJvdW5kcyk7CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICAgIHJldHVybiBpZGVudGlmaWVyLmhhc2hDb2RlKCkgXiBib3VuZHMuaGFzaENvZGUoKTsKICAgIH0KCiAgICBwdWJsaWMgU3RyaW5nIGFzU3RyaW5nKCkgewogICAgICAgIGlmIChib3VuZHMuaXNFbXB0eSgpKQogICAgICAgICAgICByZXR1cm4gaWRlbnRpZmllcjsKICAgICAgICBTdHJpbmcgYm91bmRzU3RyID0gYm91bmRzLnN0cmVhbSgpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5tYXAoVHlwZURlc2M6OmVuY29kZUFzU3RyaW5nKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY29sbGVjdChDb2xsZWN0b3JzLmpvaW5pbmcoIiAmICIpKTsKICAgICAgICByZXR1cm4gaWRlbnRpZmllciArICIgZXh0ZW5kcyAiICsgYm91bmRzU3RyOwogICAgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKICAgICAgICByZXR1cm4gU3RyaW5nLmZvcm1hdCgiJXNbaWQ6ICVzLCBib3VuZHM6ICVzXSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0Q2xhc3MoKS5nZXRTaW1wbGVOYW1lKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWRlbnRpZmllciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib3VuZHMpOwogICAgfQp9ClBLAwQKAAAIAAAGO6lKIFCKKsoLAADKCwAAJwAAAGNvbS9zdW4vdG9vbHMvc2phdmFjL3B1YmFwaS9QdWJWYXIuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAxNCwgMjAxNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLnNqYXZhYy5wdWJhcGk7CgppbXBvcnQgamF2YS5pby5TZXJpYWxpemFibGU7CmltcG9ydCBqYXZhLnV0aWwuT3B0aW9uYWw7CmltcG9ydCBqYXZhLnV0aWwuU2V0OwoKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC5Nb2RpZmllcjsKCnB1YmxpYyBjbGFzcyBQdWJWYXIgaW1wbGVtZW50cyBTZXJpYWxpemFibGUgewoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDU4MDY1MzYwNjExNTMzNzQ1NzVMOwoKICAgIHB1YmxpYyBmaW5hbCBTZXQ8TW9kaWZpZXI+IG1vZGlmaWVyczsKICAgIHB1YmxpYyBmaW5hbCBUeXBlRGVzYyB0eXBlOwogICAgcHVibGljIGZpbmFsIFN0cmluZyBpZGVudGlmaWVyOwogICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgY29uc3RWYWx1ZTsKCiAgICBwdWJsaWMgUHViVmFyKFNldDxNb2RpZmllcj4gbW9kaWZpZXJzLAogICAgICAgICAgICAgICAgICBUeXBlRGVzYyB0eXBlLAogICAgICAgICAgICAgICAgICBTdHJpbmcgaWRlbnRpZmllciwKICAgICAgICAgICAgICAgICAgU3RyaW5nIGNvbnN0VmFsdWUpIHsKICAgICAgICB0aGlzLm1vZGlmaWVycyA9IG1vZGlmaWVyczsKICAgICAgICB0aGlzLnR5cGUgPSB0eXBlOwogICAgICAgIHRoaXMuaWRlbnRpZmllciA9IGlkZW50aWZpZXI7CiAgICAgICAgdGhpcy5jb25zdFZhbHVlID0gY29uc3RWYWx1ZTsKICAgIH0KCiAgICBwdWJsaWMgU3RyaW5nIGdldElkZW50aWZpZXIoKSB7CiAgICAgICAgcmV0dXJuIGlkZW50aWZpZXI7CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iaikgewogICAgICAgIGlmIChnZXRDbGFzcygpICE9IG9iai5nZXRDbGFzcygpKQogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgUHViVmFyIG90aGVyID0gKFB1YlZhcikgb2JqOwogICAgICAgIHJldHVybiBtb2RpZmllcnMuZXF1YWxzKG90aGVyLm1vZGlmaWVycykKICAgICAgICAgICAgJiYgdHlwZS5lcXVhbHMob3RoZXIudHlwZSkKICAgICAgICAgICAgJiYgaWRlbnRpZmllci5lcXVhbHMob3RoZXIuaWRlbnRpZmllcikKICAgICAgICAgICAgJiYgZ2V0Q29uc3RWYWx1ZSgpLmVxdWFscyhvdGhlci5nZXRDb25zdFZhbHVlKCkpOwogICAgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgICByZXR1cm4gbW9kaWZpZXJzLmhhc2hDb2RlKCkKICAgICAgICAgICAgIF4gdHlwZS5oYXNoQ29kZSgpCiAgICAgICAgICAgICBeIGlkZW50aWZpZXIuaGFzaENvZGUoKQogICAgICAgICAgICAgXiBnZXRDb25zdFZhbHVlKCkuaGFzaENvZGUoKTsKICAgIH0KCiAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewogICAgICAgIHJldHVybiBTdHJpbmcuZm9ybWF0KCIlc1ttb2RpZmllcnM6ICVzLCB0eXBlOiAlcywgaWRlbnRpZmllcjogJXMsIGNvbnN0VmFsdWU6ICVzXSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0Q2xhc3MoKS5nZXRTaW1wbGVOYW1lKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9kaWZpZXJzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWRlbnRpZmllciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdFZhbHVlKTsKICAgIH0KCiAgICBwdWJsaWMgT3B0aW9uYWw8U3RyaW5nPiBnZXRDb25zdFZhbHVlKCkgewogICAgICAgIHJldHVybiBPcHRpb25hbC5vZk51bGxhYmxlKGNvbnN0VmFsdWUpOwogICAgfQp9ClBLAwQKAAAIAAAGO6lKD/yk83FFAABxRQAAJwAAAGNvbS9zdW4vdG9vbHMvc2phdmFjL3B1YmFwaS9QdWJBcGkuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAxNCwgMjAxNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLnNqYXZhYy5wdWJhcGk7CgoKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLnNqYXZhYy5VdGlsLnVuaW9uOwoKaW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOwppbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uOwppbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOwppbXBvcnQgamF2YS51dGlsLkNvbXBhcmF0b3I7CmltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKaW1wb3J0IGphdmEudXRpbC5IYXNoU2V0OwppbXBvcnQgamF2YS51dGlsLkxpc3Q7CmltcG9ydCBqYXZhLnV0aWwuTWFwOwppbXBvcnQgamF2YS51dGlsLk9wdGlvbmFsOwppbXBvcnQgamF2YS51dGlsLlNldDsKaW1wb3J0IGphdmEudXRpbC5yZWdleC5NYXRjaGVyOwppbXBvcnQgamF2YS51dGlsLnJlZ2V4LlBhdHRlcm47CmltcG9ydCBqYXZhLnV0aWwuc3RyZWFtLkNvbGxlY3RvcnM7CmltcG9ydCBqYXZhLnV0aWwuc3RyZWFtLlN0cmVhbTsKCmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuTW9kaWZpZXI7CgppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkFzc2VydDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5TdHJpbmdVdGlsczsKCnB1YmxpYyBjbGFzcyBQdWJBcGkgaW1wbGVtZW50cyBTZXJpYWxpemFibGUgewoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDU5MjY2MjczNDc4MDE5ODY4NTBMOwoKICAgIC8vIFVzZWQgdG8gaGF2ZSBTZXQgaGVyZS4gUHJvYmxlbSBpcyB0aGF0IHRoZSBvYmplY3RzIGFyZSBtdXRhdGVkIGR1cmluZwogICAgLy8gamF2YWNfc3RhdGUgbG9hZGluZywgY2F1c2luZyB0aGVtIHRvIGNoYW5nZSBoYXNoIGNvZGVzLiBXZSBjb3VsZCBwcm9iYWJseQogICAgLy8gY2hhbmdlIGJhY2sgdG8gU2V0IG9uY2UgamF2YWNfc3RhdGUgbG9hZGluZyBpcyBjbGVhbmVkIHVwLgogICAgcHVibGljIGZpbmFsIE1hcDxTdHJpbmcsIFB1YlR5cGU+IHR5cGVzID0gbmV3IEhhc2hNYXA8PigpOwogICAgcHVibGljIGZpbmFsIE1hcDxTdHJpbmcsIFB1YlZhcj4gdmFyaWFibGVzID0gbmV3IEhhc2hNYXA8PigpOwogICAgcHVibGljIGZpbmFsIE1hcDxTdHJpbmcsIFB1Yk1ldGhvZD4gbWV0aG9kcyA9IG5ldyBIYXNoTWFwPD4oKTsKCiAgICBwdWJsaWMgUHViQXBpKCkgewogICAgfQoKICAgIHB1YmxpYyBQdWJBcGkoQ29sbGVjdGlvbjxQdWJUeXBlPiB0eXBlcywKICAgICAgICAgICAgICAgICAgQ29sbGVjdGlvbjxQdWJWYXI+IHZhcmlhYmxlcywKICAgICAgICAgICAgICAgICAgQ29sbGVjdGlvbjxQdWJNZXRob2Q+IG1ldGhvZHMpIHsKICAgICAgICB0eXBlcy5mb3JFYWNoKHRoaXM6OmFkZFB1YlR5cGUpOwogICAgICAgIHZhcmlhYmxlcy5mb3JFYWNoKHRoaXM6OmFkZFB1YlZhcik7CiAgICAgICAgbWV0aG9kcy5mb3JFYWNoKHRoaXM6OmFkZFB1Yk1ldGhvZCk7CiAgICB9CgogICAgLy8gQ3VycmVudGx5IHRoaXMgaXMgaW1wbGVtZW50ZWQgYXMgZXF1YWxpdHkuIFRoaXMgaXMgZmFyIGZyb20gb3B0aW1hbC4gSXQKICAgIC8vIHNob3VsZCBwcmVmZXJhYmx5IG1ha2Ugc3VyZSB0aGF0IGFsbCBwcmV2aW91cyBtZXRob2RzIGFyZSBzdGlsbCBhdmFpbGFibGUKICAgIC8vIGFuZCBubyBhYnN0cmFjdCBtZXRob2RzIGFyZSBhZGRlZC4gSXQgc2hvdWxkIGFsc28gYmUgYXdhcmUgb2YgaW5oZXJpdGFuY2UKICAgIC8vIG9mIGNvdXJzZS4KICAgIHB1YmxpYyBib29sZWFuIGlzQmFja3dhcmRDb21wYXRpYmxlV2l0aChQdWJBcGkgb2xkZXIpIHsKICAgICAgICByZXR1cm4gZXF1YWxzKG9sZGVyKTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgdHlwZUxpbmUoUHViVHlwZSB0eXBlKSB7CiAgICAgICAgaWYgKHR5cGUuZnFOYW1lLmlzRW1wdHkoKSkKICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oImVtcHR5IGNsYXNzIG5hbWUgIiArIHR5cGUpOwogICAgICAgIHJldHVybiBTdHJpbmcuZm9ybWF0KCJUWVBFICVzJXMiLCBhc1N0cmluZyh0eXBlLm1vZGlmaWVycyksIHR5cGUuZnFOYW1lKTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgdmFyTGluZShQdWJWYXIgdmFyKSB7CiAgICAgICAgcmV0dXJuIFN0cmluZy5mb3JtYXQoIlZBUiAlcyVzICVzJXMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFzU3RyaW5nKHZhci5tb2RpZmllcnMpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFR5cGVEZXNjLmVuY29kZUFzU3RyaW5nKHZhci50eXBlKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIuaWRlbnRpZmllciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIuZ2V0Q29uc3RWYWx1ZSgpLm1hcCh2IC0+ICIgPSAiICsgdikub3JFbHNlKCIiKSk7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIG1ldGhvZExpbmUoUHViTWV0aG9kIG1ldGhvZCkgewogICAgICAgIHJldHVybiBTdHJpbmcuZm9ybWF0KCJNRVRIT0QgJXMlcyVzICVzKCVzKSVzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhc1N0cmluZyhtZXRob2QubW9kaWZpZXJzKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRob2QudHlwZVBhcmFtcy5pc0VtcHR5KCkgPyAiIiA6ICgiPCIgKyBtZXRob2QudHlwZVBhcmFtcy5zdHJlYW0oKS5tYXAoUHViQXBpVHlwZVBhcmFtOjphc1N0cmluZykuY29sbGVjdChDb2xsZWN0b3JzLmpvaW5pbmcoIiwiKSkgKyAiPiAiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUeXBlRGVzYy5lbmNvZGVBc1N0cmluZyhtZXRob2QucmV0dXJuVHlwZSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kLmlkZW50aWZpZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tbWFTZXBhcmF0ZWQobWV0aG9kLnBhcmFtVHlwZXMpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZC50aHJvd0RlY2xzLmlzRW1wdHkoKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/ICIiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogIiB0aHJvd3MgIiArIGNvbW1hU2VwYXJhdGVkKG1ldGhvZC50aHJvd0RlY2xzKSk7CiAgICB9CgogICAgcHVibGljIExpc3Q8U3RyaW5nPiBhc0xpc3RPZlN0cmluZ3MoKSB7CiAgICAgICAgTGlzdDxTdHJpbmc+IGxpbmVzID0gbmV3IEFycmF5TGlzdDw+KCk7CgogICAgICAgIC8vIFR5cGVzCiAgICAgICAgdHlwZXMudmFsdWVzKCkKICAgICAgICAgICAgIC5zdHJlYW0oKQogICAgICAgICAgICAgLnNvcnRlZChDb21wYXJhdG9yLmNvbXBhcmluZyhQdWJBcGk6OnR5cGVMaW5lKSkKICAgICAgICAgICAgIC5mb3JFYWNoKHR5cGUgLT4gewogICAgICAgICAgICAgICAgIGxpbmVzLmFkZCh0eXBlTGluZSh0eXBlKSk7CiAgICAgICAgICAgICAgICAgZm9yIChTdHJpbmcgc3VibGluZSA6IHR5cGUucHViQXBpLmFzTGlzdE9mU3RyaW5ncygpKQogICAgICAgICAgICAgICAgICAgICBsaW5lcy5hZGQoIiAgIiArIHN1YmxpbmUpOwogICAgICAgICAgICAgfSk7CgogICAgICAgIC8vIFZhcmlhYmxlcwogICAgICAgIHZhcmlhYmxlcy52YWx1ZXMoKQogICAgICAgICAgICAgICAgIC5zdHJlYW0oKQogICAgICAgICAgICAgICAgIC5tYXAoUHViQXBpOjp2YXJMaW5lKQogICAgICAgICAgICAgICAgIC5zb3J0ZWQoKQogICAgICAgICAgICAgICAgIC5mb3JFYWNoKGxpbmVzOjphZGQpOwoKICAgICAgICAvLyBNZXRob2RzCiAgICAgICAgbWV0aG9kcy52YWx1ZXMoKQogICAgICAgICAgICAgICAuc3RyZWFtKCkKICAgICAgICAgICAgICAgLm1hcChQdWJBcGk6Om1ldGhvZExpbmUpCiAgICAgICAgICAgICAgIC5zb3J0ZWQoKQogICAgICAgICAgICAgICAuZm9yRWFjaChsaW5lczo6YWRkKTsKCiAgICAgICAgcmV0dXJuIGxpbmVzOwogICAgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmopIHsKICAgICAgICBpZiAoZ2V0Q2xhc3MoKSAhPSBvYmouZ2V0Q2xhc3MoKSkKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIFB1YkFwaSBvdGhlciA9IChQdWJBcGkpIG9iajsKICAgICAgICByZXR1cm4gdHlwZXMuZXF1YWxzKG90aGVyLnR5cGVzKQogICAgICAgICAgICAmJiB2YXJpYWJsZXMuZXF1YWxzKG90aGVyLnZhcmlhYmxlcykKICAgICAgICAgICAgJiYgbWV0aG9kcy5lcXVhbHMob3RoZXIubWV0aG9kcyk7CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICAgIHJldHVybiB0eXBlcy5rZXlTZXQoKS5oYXNoQ29kZSgpCiAgICAgICAgICAgICBeIHZhcmlhYmxlcy5rZXlTZXQoKS5oYXNoQ29kZSgpCiAgICAgICAgICAgICBeIG1ldGhvZHMua2V5U2V0KCkuaGFzaENvZGUoKTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgY29tbWFTZXBhcmF0ZWQoTGlzdDxUeXBlRGVzYz4gdHlwZURlc2NzKSB7CiAgICAgICAgcmV0dXJuIHR5cGVEZXNjcy5zdHJlYW0oKQogICAgICAgICAgICAgICAgICAgICAgICAubWFwKFR5cGVEZXNjOjplbmNvZGVBc1N0cmluZykKICAgICAgICAgICAgICAgICAgICAgICAgLmNvbGxlY3QoQ29sbGVjdG9ycy5qb2luaW5nKCIsIikpOwogICAgfQoKICAgIC8vIENyZWF0ZSBzcGFjZSBzZXBhcmF0ZWQgbGlzdCBvZiBtb2RpZmllcnMgKHdpdGggYSB0cmFpbGluZyBzcGFjZSkKICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBhc1N0cmluZyhTZXQ8TW9kaWZpZXI+IG1vZGlmaWVycykgewogICAgICAgIHJldHVybiBtb2RpZmllcnMuc3RyZWFtKCkKICAgICAgICAgICAgICAgICAgICAgICAgLm1hcChtb2QgLT4gbW9kICsgIiAiKQogICAgICAgICAgICAgICAgICAgICAgICAuc29ydGVkKCkKICAgICAgICAgICAgICAgICAgICAgICAgLmNvbGxlY3QoQ29sbGVjdG9ycy5qb2luaW5nKCkpOwogICAgfQoKICAgIC8vIFVzZWQgdG8gY29tYmluZSBjbGFzcyBQdWJBcGlzIHRvIHBhY2thZ2UgbGV2ZWwgUHViQXBpcwogICAgcHVibGljIHN0YXRpYyBQdWJBcGkgbWVyZ2VUeXBlcyhQdWJBcGkgYXBpMSwgUHViQXBpIGFwaTIpIHsKICAgICAgICBBc3NlcnQuY2hlY2soYXBpMS5tZXRob2RzLmlzRW1wdHkoKSwgIkNhbiBvbmx5IG1lcmdlIHR5cGVzLiIpOwogICAgICAgIEFzc2VydC5jaGVjayhhcGkyLm1ldGhvZHMuaXNFbXB0eSgpLCAiQ2FuIG9ubHkgbWVyZ2UgdHlwZXMuIik7CiAgICAgICAgQXNzZXJ0LmNoZWNrKGFwaTEudmFyaWFibGVzLmlzRW1wdHkoKSwgIkNhbiBvbmx5IG1lcmdlIHR5cGVzLiIpOwogICAgICAgIEFzc2VydC5jaGVjayhhcGkyLnZhcmlhYmxlcy5pc0VtcHR5KCksICJDYW4gb25seSBtZXJnZSB0eXBlcy4iKTsKICAgICAgICBQdWJBcGkgbWVyZ2VkID0gbmV3IFB1YkFwaSgpOwogICAgICAgIG1lcmdlZC50eXBlcy5wdXRBbGwoYXBpMS50eXBlcyk7CiAgICAgICAgbWVyZ2VkLnR5cGVzLnB1dEFsbChhcGkyLnR5cGVzKTsKICAgICAgICByZXR1cm4gbWVyZ2VkOwogICAgfQoKCiAgICAvLyBVc2VkIGZvciBsaW5lLWJ5LWxpbmUgcGFyc2luZwogICAgcHJpdmF0ZSBQdWJUeXBlIGxhc3RJbnNlcnRlZFR5cGUgPSBudWxsOwoKICAgIHByaXZhdGUgZmluYWwgc3RhdGljIFN0cmluZyBNT0RJRklFUlMgPSBTdHJlYW0ub2YoTW9kaWZpZXIudmFsdWVzKCkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLm1hcChNb2RpZmllcjo6bmFtZSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAubWFwKFN0cmluZ1V0aWxzOjp0b0xvd2VyQ2FzZSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY29sbGVjdChDb2xsZWN0b3JzLmpvaW5pbmcoInwiLCAiKCIsICIpIikpOwoKICAgIHByaXZhdGUgZmluYWwgc3RhdGljIFBhdHRlcm4gTU9EX1BBVFRFUk4gPSBQYXR0ZXJuLmNvbXBpbGUoIigiICsgTU9ESUZJRVJTICsgIiApKiIpOwogICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgUGF0dGVybiBNRVRIT0RfUEFUVEVSTiA9IFBhdHRlcm4uY29tcGlsZSgiKD88cmV0Pi4rPykgKD88bmFtZT5cXFMrKVxcKCg/PHBhcmFtcz4uKilcXCkoIHRocm93cyAoPzx0aHJvd3M+LiopKT8iKTsKICAgIHByaXZhdGUgZmluYWwgc3RhdGljIFBhdHRlcm4gVkFSX1BBVFRFUk4gPSBQYXR0ZXJuLmNvbXBpbGUoIlZBUiAoPzxtb2RpZmllcnM+KCIrTU9ESUZJRVJTKyIgKSopKD88dHlwZT4uKz8pICg/PGlkPlxcUyspKCA9ICg/PHZhbD4uKikpPyIpOwogICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgUGF0dGVybiBUWVBFX1BBVFRFUk4gPSBQYXR0ZXJuLmNvbXBpbGUoIlRZUEUgKD88bW9kaWZpZXJzPigiK01PRElGSUVSUysiICkqKSg/PGZ1bGx5UXVhbGlmaWVkPlxcUyspIik7CgogICAgcHVibGljIHZvaWQgYXBwZW5kSXRlbShTdHJpbmcgbCkgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGlmIChsLnN0YXJ0c1dpdGgoIiAgIikpIHsKICAgICAgICAgICAgICAgIGxhc3RJbnNlcnRlZFR5cGUucHViQXBpLmFwcGVuZEl0ZW0obC5zdWJzdHJpbmcoMikpOwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAobC5zdGFydHNXaXRoKCJNRVRIT0QiKSkgewogICAgICAgICAgICAgICAgbCA9IGwuc3Vic3RyaW5nKCJNRVRIT0QgIi5sZW5ndGgoKSk7CiAgICAgICAgICAgICAgICBTZXQ8TW9kaWZpZXI+IG1vZGlmaWVycyA9IG5ldyBIYXNoU2V0PD4oKTsKICAgICAgICAgICAgICAgIE1hdGNoZXIgbW9kTWF0Y2hlciA9IE1PRF9QQVRURVJOLm1hdGNoZXIobCk7CiAgICAgICAgICAgICAgICBpZiAobW9kTWF0Y2hlci5maW5kKCkpIHsKICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbW9kaWZpZXJzU3RyID0gbW9kTWF0Y2hlci5ncm91cCgpOwogICAgICAgICAgICAgICAgICAgIG1vZGlmaWVycy5hZGRBbGwocGFyc2VNb2RpZmllcnMobW9kaWZpZXJzU3RyKSk7CiAgICAgICAgICAgICAgICAgICAgbCA9IGwuc3Vic3RyaW5nKG1vZGlmaWVyc1N0ci5sZW5ndGgoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBMaXN0PFB1YkFwaVR5cGVQYXJhbT4gdHlwZVBhcmFtcyA9IG5ldyBBcnJheUxpc3Q8PigpOwogICAgICAgICAgICAgICAgaWYgKGwuc3RhcnRzV2l0aCgiPCIpKSB7CiAgICAgICAgICAgICAgICAgICAgaW50IGNsb3NpbmdQb3MgPSBmaW5kQ2xvc2luZ1RhZyhsLCAwKTsKICAgICAgICAgICAgICAgICAgICBTdHJpbmcgc3RyID0gbC5zdWJzdHJpbmcoMSwgY2xvc2luZ1Bvcyk7CiAgICAgICAgICAgICAgICAgICAgbCA9IGwuc3Vic3RyaW5nKGNsb3NpbmdQb3MrMSk7CiAgICAgICAgICAgICAgICAgICAgdHlwZVBhcmFtcy5hZGRBbGwocGFyc2VUeXBlUGFyYW1zKHNwbGl0T25Ub3BMZXZlbENvbW1hcyhzdHIpKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBNYXRjaGVyIG1tID0gTUVUSE9EX1BBVFRFUk4ubWF0Y2hlcihsKTsKICAgICAgICAgICAgICAgIGlmICghbW0ubWF0Y2hlcygpKQogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigiQ291bGQgbm90IHBhcnNlIHJldHVybiB0eXBlLCBpZGVudGlmaWVyLCBwYXJhbWV0ZXIgdHlwZXMgb3IgdGhyb3dzIGRlY2xhcmF0aW9uIG9mIG1ldGhvZDogIiArIGwpOwoKICAgICAgICAgICAgICAgIExpc3Q8U3RyaW5nPiBwYXJhbXMgPSBzcGxpdE9uVG9wTGV2ZWxDb21tYXMobW0uZ3JvdXAoInBhcmFtcyIpKTsKICAgICAgICAgICAgICAgIFN0cmluZyB0aCA9IE9wdGlvbmFsLm9mTnVsbGFibGUobW0uZ3JvdXAoInRocm93cyIpKS5vckVsc2UoIiIpOwogICAgICAgICAgICAgICAgTGlzdDxTdHJpbmc+IHRocm93eiA9IHNwbGl0T25Ub3BMZXZlbENvbW1hcyh0aCk7CiAgICAgICAgICAgICAgICBQdWJNZXRob2QgbSA9IG5ldyBQdWJNZXRob2QobW9kaWZpZXJzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVQYXJhbXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVHlwZURlc2MuZGVjb2RlU3RyaW5nKG1tLmdyb3VwKCJyZXQiKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbW0uZ3JvdXAoIm5hbWUiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJzZVR5cGVEZXNjcyhwYXJhbXMpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcnNlVHlwZURlc2NzKHRocm93eikpOwogICAgICAgICAgICAgICAgYWRkUHViTWV0aG9kKG0pOwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CgogICAgICAgICAgICBNYXRjaGVyIHZtID0gVkFSX1BBVFRFUk4ubWF0Y2hlcihsKTsKICAgICAgICAgICAgaWYgKHZtLm1hdGNoZXMoKSkgewogICAgICAgICAgICAgICAgYWRkUHViVmFyKG5ldyBQdWJWYXIocGFyc2VNb2RpZmllcnModm0uZ3JvdXAoIm1vZGlmaWVycyIpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFR5cGVEZXNjLmRlY29kZVN0cmluZyh2bS5ncm91cCgidHlwZSIpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZtLmdyb3VwKCJpZCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm0uZ3JvdXAoInZhbCIpKSk7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIE1hdGNoZXIgdG0gPSBUWVBFX1BBVFRFUk4ubWF0Y2hlcihsKTsKICAgICAgICAgICAgaWYgKHRtLm1hdGNoZXMoKSkgewogICAgICAgICAgICAgICAgYWRkUHViVHlwZShuZXcgUHViVHlwZShwYXJzZU1vZGlmaWVycyh0bS5ncm91cCgibW9kaWZpZXJzIikpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0bS5ncm91cCgiZnVsbHlRdWFsaWZpZWQiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFB1YkFwaSgpKSk7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigiTm8gbWF0Y2hpbmcgbGluZSBwYXR0ZXJuLiIpOwogICAgICAgIH0gY2F0Y2ggKFRocm93YWJsZSBlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigiQ291bGQgbm90IHBhcnNlIEFQSSBsaW5lOiAiICsgbCwgZSk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyB2b2lkIGFkZFB1YlR5cGUoUHViVHlwZSB0KSB7CiAgICAgICAgdHlwZXMucHV0KHQuZnFOYW1lLCB0KTsKICAgICAgICBsYXN0SW5zZXJ0ZWRUeXBlID0gdDsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCBhZGRQdWJWYXIoUHViVmFyIHYpIHsKICAgICAgICB2YXJpYWJsZXMucHV0KHYuaWRlbnRpZmllciwgdik7CiAgICB9CgogICAgcHVibGljIHZvaWQgYWRkUHViTWV0aG9kKFB1Yk1ldGhvZCBtKSB7CiAgICAgICAgbWV0aG9kcy5wdXQobS5hc1NpZ25hdHVyZVN0cmluZygpLCBtKTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBMaXN0PFR5cGVEZXNjPiBwYXJzZVR5cGVEZXNjcyhMaXN0PFN0cmluZz4gc3RycykgewogICAgICAgIHJldHVybiBzdHJzLnN0cmVhbSgpCiAgICAgICAgICAgICAgICAgICAubWFwKFR5cGVEZXNjOjpkZWNvZGVTdHJpbmcpCiAgICAgICAgICAgICAgICAgICAuY29sbGVjdChDb2xsZWN0b3JzLnRvTGlzdCgpKTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBMaXN0PFB1YkFwaVR5cGVQYXJhbT4gcGFyc2VUeXBlUGFyYW1zKExpc3Q8U3RyaW5nPiBzdHJzKSB7CiAgICAgICAgcmV0dXJuIHN0cnMuc3RyZWFtKCkubWFwKFB1YkFwaTo6cGFyc2VUeXBlUGFyYW0pLmNvbGxlY3QoQ29sbGVjdG9ycy50b0xpc3QoKSk7CiAgICB9CgogICAgLy8gUGFyc2UgYSB0eXBlIHBhcmFtZXRlciBzdHJpbmcuIEV4YW1wbGUgaW5wdXQ6CiAgICAvLyAgICAgaWRlbnRpZmllcgogICAgLy8gICAgIGlkZW50aWZpZXIgZXh0ZW5kcyBUeXBlICgmIFR5cGUpKgogICAgcHJpdmF0ZSBzdGF0aWMgUHViQXBpVHlwZVBhcmFtIHBhcnNlVHlwZVBhcmFtKFN0cmluZyB0eXBlUGFyYW1TdHJpbmcpIHsKICAgICAgICBpbnQgZXh0UG9zID0gdHlwZVBhcmFtU3RyaW5nLmluZGV4T2YoIiBleHRlbmRzICIpOwogICAgICAgIGlmIChleHRQb3MgPT0gLTEpCiAgICAgICAgICAgIHJldHVybiBuZXcgUHViQXBpVHlwZVBhcmFtKHR5cGVQYXJhbVN0cmluZywgQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCkpOwogICAgICAgIFN0cmluZyBpZGVudGlmaWVyID0gdHlwZVBhcmFtU3RyaW5nLnN1YnN0cmluZygwLCBleHRQb3MpOwogICAgICAgIFN0cmluZyByZXN0ID0gdHlwZVBhcmFtU3RyaW5nLnN1YnN0cmluZyhleHRQb3MgKyAiIGV4dGVuZHMgIi5sZW5ndGgoKSk7CiAgICAgICAgTGlzdDxUeXBlRGVzYz4gYm91bmRzID0gcGFyc2VUeXBlRGVzY3Moc3BsaXRPblRvcExldmVsQ2hhcnMocmVzdCwgJyYnKSk7CiAgICAgICAgcmV0dXJuIG5ldyBQdWJBcGlUeXBlUGFyYW0oaWRlbnRpZmllciwgYm91bmRzKTsKICAgIH0KCiAgICBwdWJsaWMgU2V0PE1vZGlmaWVyPiBwYXJzZU1vZGlmaWVycyhTdHJpbmcgbW9kaWZpZXJzKSB7CiAgICAgICAgaWYgKG1vZGlmaWVycyA9PSBudWxsKQogICAgICAgICAgICByZXR1cm4gQ29sbGVjdGlvbnMuZW1wdHlTZXQoKTsKICAgICAgICByZXR1cm4gU3RyZWFtLm9mKG1vZGlmaWVycy5zcGxpdCgiICIpKQogICAgICAgICAgICAgICAgICAgICAubWFwKFN0cmluZzo6dHJpbSkKICAgICAgICAgICAgICAgICAgICAgLm1hcChTdHJpbmdVdGlsczo6dG9VcHBlckNhc2UpCiAgICAgICAgICAgICAgICAgICAgIC5maWx0ZXIocyAtPiAhcy5pc0VtcHR5KCkpCiAgICAgICAgICAgICAgICAgICAgIC5tYXAoTW9kaWZpZXI6OnZhbHVlT2YpCiAgICAgICAgICAgICAgICAgICAgIC5jb2xsZWN0KENvbGxlY3RvcnMudG9TZXQoKSk7CiAgICB9CgogICAgLy8gRmluZCBjbG9zaW5nIHRhZyBvZiB0aGUgb3BlbmluZyB0YWcgYXQgdGhlIGdpdmVuICdwb3MnLgogICAgcHJpdmF0ZSBzdGF0aWMgaW50IGZpbmRDbG9zaW5nVGFnKFN0cmluZyBsLCBpbnQgcG9zKSB7CiAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgICAgcG9zID0gcG9zICsgMTsKICAgICAgICAgICAgaWYgKGwuY2hhckF0KHBvcykgPT0gJz4nKQogICAgICAgICAgICAgICAgcmV0dXJuIHBvczsKICAgICAgICAgICAgaWYgKGwuY2hhckF0KHBvcykgPT0gJzwnKQogICAgICAgICAgICAgICAgcG9zID0gZmluZENsb3NpbmdUYWcobCwgcG9zKTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIExpc3Q8U3RyaW5nPiBzcGxpdE9uVG9wTGV2ZWxDb21tYXMoU3RyaW5nIHMpIHsKICAgICAgICByZXR1cm4gc3BsaXRPblRvcExldmVsQ2hhcnMocywgJywnKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIExpc3Q8U3RyaW5nPiBzcGxpdE9uVG9wTGV2ZWxDaGFycyhTdHJpbmcgcywgY2hhciBzcGxpdCkgewogICAgICAgIGlmIChzLmlzRW1wdHkoKSkKICAgICAgICAgICAgcmV0dXJuIENvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIExpc3Q8U3RyaW5nPiByZXN1bHQgPSBuZXcgQXJyYXlMaXN0PD4oKTsKICAgICAgICBTdHJpbmdCdWlsZGVyIGJ1ZiA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CiAgICAgICAgaW50IGRlcHRoID0gMDsKICAgICAgICBmb3IgKGNoYXIgYyA6IHMudG9DaGFyQXJyYXkoKSkgewogICAgICAgICAgICBpZiAoYyA9PSBzcGxpdCAmJiBkZXB0aCA9PSAwKSB7CiAgICAgICAgICAgICAgICByZXN1bHQuYWRkKGJ1Zi50b1N0cmluZygpLnRyaW0oKSk7CiAgICAgICAgICAgICAgICBidWYgPSBuZXcgU3RyaW5nQnVpbGRlcigpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgaWYgKGMgPT0gJzwnKSBkZXB0aCsrOwogICAgICAgICAgICAgICAgaWYgKGMgPT0gJz4nKSBkZXB0aC0tOwogICAgICAgICAgICAgICAgYnVmLmFwcGVuZChjKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXN1bHQuYWRkKGJ1Zi50b1N0cmluZygpLnRyaW0oKSk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KCiAgICBwdWJsaWMgYm9vbGVhbiBpc0VtcHR5KCkgewogICAgICAgIHJldHVybiB0eXBlcy5pc0VtcHR5KCkgJiYgdmFyaWFibGVzLmlzRW1wdHkoKSAmJiBtZXRob2RzLmlzRW1wdHkoKTsKICAgIH0KCiAgICAvLyBVc2VkIGZvciBkZXNjcmlwdGl2ZSBkZWJ1ZyBtZXNzYWdlcyB3aGVuIGZpZ3VyaW5nIG91dCB3aGF0IHRyaWdnZXJzCiAgICAvLyByZWNvbXBpbGF0aW9uLgogICAgcHVibGljIExpc3Q8U3RyaW5nPiBkaWZmKFB1YkFwaSBwcmV2QXBpKSB7CiAgICAgICAgcmV0dXJuIGRpZmYoIiIsIHByZXZBcGkpOwogICAgfQogICAgcHJpdmF0ZSBMaXN0PFN0cmluZz4gZGlmZihTdHJpbmcgc2NvcGVQcmVmaXgsIFB1YkFwaSBwcmV2QXBpKSB7CgogICAgICAgIExpc3Q8U3RyaW5nPiBkaWZmcyA9IG5ldyBBcnJheUxpc3Q8PigpOwoKICAgICAgICBmb3IgKFN0cmluZyB0eXBlS2V5IDogdW5pb24odHlwZXMua2V5U2V0KCksIHByZXZBcGkudHlwZXMua2V5U2V0KCkpKSB7CiAgICAgICAgICAgIFB1YlR5cGUgdHlwZSA9IHR5cGVzLmdldCh0eXBlS2V5KTsKICAgICAgICAgICAgUHViVHlwZSBwcmV2VHlwZSA9IHByZXZBcGkudHlwZXMuZ2V0KHR5cGVLZXkpOwogICAgICAgICAgICBpZiAocHJldlR5cGUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgZGlmZnMuYWRkKCJUeXBlICIgKyBzY29wZVByZWZpeCArIHR5cGVLZXkgKyAiIHdhcyBhZGRlZCIpOwogICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgZGlmZnMuYWRkKCJUeXBlICIgKyBzY29wZVByZWZpeCArIHR5cGVLZXkgKyAiIHdhcyByZW1vdmVkIik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvLyBDaGVjayBtb2RpZmllcnMKICAgICAgICAgICAgICAgIGlmICghdHlwZS5tb2RpZmllcnMuZXF1YWxzKHByZXZUeXBlLm1vZGlmaWVycykpIHsKICAgICAgICAgICAgICAgICAgICBkaWZmcy5hZGQoIk1vZGlmaWVycyBmb3IgdHlwZSAiICsgc2NvcGVQcmVmaXggKyB0eXBlS2V5CiAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIgY2hhbmdlZCBmcm9tICIgKyBwcmV2VHlwZS5tb2RpZmllcnMgKyAiIHRvICIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgdHlwZS5tb2RpZmllcnMpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIFJlY3Vyc2l2ZWx5IGNoZWNrIHR5cGVzIHB1YiBBUEkKICAgICAgICAgICAgICAgIGRpZmZzLmFkZEFsbCh0eXBlLnB1YkFwaS5kaWZmKHByZXZUeXBlLnB1YkFwaSkpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBmb3IgKFN0cmluZyB2YXJLZXkgOiB1bmlvbih2YXJpYWJsZXMua2V5U2V0KCksIHByZXZBcGkudmFyaWFibGVzLmtleVNldCgpKSkgewogICAgICAgICAgICBQdWJWYXIgdmFyID0gdmFyaWFibGVzLmdldCh2YXJLZXkpOwogICAgICAgICAgICBQdWJWYXIgcHJldlZhciA9IHByZXZBcGkudmFyaWFibGVzLmdldCh2YXJLZXkpOwogICAgICAgICAgICBpZiAocHJldlZhciA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICBkaWZmcy5hZGQoIlZhcmlhYmxlICIgKyBzY29wZVByZWZpeCArIHZhcktleSArICIgd2FzIGFkZGVkIik7CiAgICAgICAgICAgIH0gZWxzZSBpZiAodmFyID09IG51bGwpIHsKICAgICAgICAgICAgICAgIGRpZmZzLmFkZCgiVmFyaWFibGUgIiArIHNjb3BlUHJlZml4ICsgdmFyS2V5ICsgIiB3YXMgcmVtb3ZlZCIpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgaWYgKCF2YXIubW9kaWZpZXJzLmVxdWFscyhwcmV2VmFyLm1vZGlmaWVycykpIHsKICAgICAgICAgICAgICAgICAgICBkaWZmcy5hZGQoIk1vZGlmaWVycyBmb3IgdmFyICIgKyBzY29wZVByZWZpeCArIHZhcktleQogICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiIGNoYW5nZWQgZnJvbSAiICsgcHJldlZhci5tb2RpZmllcnMgKyAiIHRvICIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgdmFyLm1vZGlmaWVycyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoIXZhci50eXBlLmVxdWFscyhwcmV2VmFyLnR5cGUpKSB7CiAgICAgICAgICAgICAgICAgICAgZGlmZnMuYWRkKCJUeXBlIG9mICIgKyBzY29wZVByZWZpeCArIHZhcktleQogICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiIGNoYW5nZWQgZnJvbSAiICsgcHJldlZhci50eXBlICsgIiB0byAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICArIHZhci50eXBlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICghdmFyLmdldENvbnN0VmFsdWUoKS5lcXVhbHMocHJldlZhci5nZXRDb25zdFZhbHVlKCkpKSB7CiAgICAgICAgICAgICAgICAgICAgZGlmZnMuYWRkKCJDb25zdCB2YWx1ZSBvZiAiICsgc2NvcGVQcmVmaXggKyB2YXJLZXkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiBjaGFuZ2VkIGZyb20gIiArIHByZXZWYXIuZ2V0Q29uc3RWYWx1ZSgpLm9yRWxzZSgiPG5vbmU+IikKICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiB0byAiICsgdmFyLmdldENvbnN0VmFsdWUoKS5vckVsc2UoIjxub25lPiIpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgZm9yIChTdHJpbmcgbWV0aG9kS2V5IDogdW5pb24obWV0aG9kcy5rZXlTZXQoKSwgcHJldkFwaS5tZXRob2RzLmtleVNldCgpKSkgewogICAgICAgICAgICBQdWJNZXRob2QgbWV0aG9kID0gbWV0aG9kcy5nZXQobWV0aG9kS2V5KTsKICAgICAgICAgICAgUHViTWV0aG9kIHByZXZNZXRob2QgPSBwcmV2QXBpLm1ldGhvZHMuZ2V0KG1ldGhvZEtleSk7CiAgICAgICAgICAgIGlmIChwcmV2TWV0aG9kID09IG51bGwpIHsKICAgICAgICAgICAgICAgIGRpZmZzLmFkZCgiTWV0aG9kICIgKyBzY29wZVByZWZpeCArIG1ldGhvZEtleSArICIgd2FzIGFkZGVkIik7CiAgICAgICAgICAgIH0gZWxzZSBpZiAobWV0aG9kID09IG51bGwpIHsKICAgICAgICAgICAgICAgIGRpZmZzLmFkZCgiTWV0aG9kICIgKyBzY29wZVByZWZpeCArIG1ldGhvZEtleSArICIgd2FzIHJlbW92ZWQiKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGlmICghbWV0aG9kLm1vZGlmaWVycy5lcXVhbHMocHJldk1ldGhvZC5tb2RpZmllcnMpKSB7CiAgICAgICAgICAgICAgICAgICAgZGlmZnMuYWRkKCJNb2RpZmllcnMgZm9yIG1ldGhvZCAiICsgc2NvcGVQcmVmaXggKyBtZXRob2RLZXkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiBjaGFuZ2VkIGZyb20gIiArIHByZXZNZXRob2QubW9kaWZpZXJzICsgIiB0byAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICArIG1ldGhvZC5tb2RpZmllcnMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCFtZXRob2QudHlwZVBhcmFtcy5lcXVhbHMocHJldk1ldGhvZC50eXBlUGFyYW1zKSkgewogICAgICAgICAgICAgICAgICAgIGRpZmZzLmFkZCgiVHlwZSBwYXJhbWV0ZXJzIGZvciBtZXRob2QgIiArIHNjb3BlUHJlZml4CiAgICAgICAgICAgICAgICAgICAgICAgICAgICArIG1ldGhvZEtleSArICIgY2hhbmdlZCBmcm9tICIgKyBwcmV2TWV0aG9kLnR5cGVQYXJhbXMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiB0byAiICsgbWV0aG9kLnR5cGVQYXJhbXMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCFtZXRob2QudGhyb3dEZWNscy5lcXVhbHMocHJldk1ldGhvZC50aHJvd0RlY2xzKSkgewogICAgICAgICAgICAgICAgICAgIGRpZmZzLmFkZCgiVGhyb3cgZGVjbCBmb3IgbWV0aG9kICIgKyBzY29wZVByZWZpeCArIG1ldGhvZEtleQogICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiIGNoYW5nZWQgZnJvbSAiICsgcHJldk1ldGhvZC50aHJvd0RlY2xzICsgIiB0byAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIgdG8gIiArIG1ldGhvZC50aHJvd0RlY2xzKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGRpZmZzOwogICAgfQoKICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CiAgICAgICAgcmV0dXJuIFN0cmluZy5mb3JtYXQoIiVzW3R5cGVzOiAlcywgdmFyaWFibGVzOiAlcywgbWV0aG9kczogJXNdIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRDbGFzcygpLmdldFNpbXBsZU5hbWUoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlcy52YWx1ZXMoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXJpYWJsZXMudmFsdWVzKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kcy52YWx1ZXMoKSk7CiAgICB9Cn0KUEsDBAoAAAgAAAY7qUo0rvAAnAcAAJwHAAAyAAAAY29tL3N1bi90b29scy9zamF2YWMvcHViYXBpL1ByaW1pdGl2ZVR5cGVEZXNjLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTQsIDIwMTUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5zamF2YWMucHViYXBpOwoKaW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOwoKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwudHlwZS5UeXBlS2luZDsKCmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuU3RyaW5nVXRpbHM7CgpwdWJsaWMgY2xhc3MgUHJpbWl0aXZlVHlwZURlc2MgZXh0ZW5kcyBUeXBlRGVzYyBpbXBsZW1lbnRzIFNlcmlhbGl6YWJsZSB7CgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNjA1MTA2NTU0MzE0OTEyOTEwNkw7CgogICAgcHVibGljIFByaW1pdGl2ZVR5cGVEZXNjKFR5cGVLaW5kIHR5cGVLaW5kKSB7CiAgICAgICAgc3VwZXIodHlwZUtpbmQpOwogICAgICAgIGlmICghdHlwZUtpbmQuaXNQcmltaXRpdmUoKSAmJiB0eXBlS2luZCAhPSBUeXBlS2luZC5WT0lEKQogICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJPbmx5IHByaW1pdGl2ZXMgb3Igdm9pZCBhY2NlcHRlZCIpOwogICAgfQoKICAgIC8vIFRoaXMgY2xhc3MgaGFzIG5vIGZpZWxkcywgc28gdGhlIGluaGVyaXRlZCBoYXNoQ29kZSBhbmQgZXF1YWxzIHNob3VsZCBkbyBmaW5lLgoKICAgIEBPdmVycmlkZQogICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKICAgICAgICByZXR1cm4gU3RyaW5nVXRpbHMudG9Mb3dlckNhc2UodHlwZUtpbmQudG9TdHJpbmcoKSk7CiAgICB9Cn0KUEsDBAoAAAgAAAY7qUojROJ+HRQAAB0UAAApAAAAY29tL3N1bi90b29scy9zamF2YWMvcHViYXBpL1R5cGVEZXNjLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTQsIDIwMTUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5zamF2YWMucHViYXBpOwoKaW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOwoKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwudHlwZS5BcnJheVR5cGU7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLnR5cGUuRGVjbGFyZWRUeXBlOwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC50eXBlLkVycm9yVHlwZTsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwudHlwZS5Ob1R5cGU7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLnR5cGUuUHJpbWl0aXZlVHlwZTsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwudHlwZS5UeXBlS2luZDsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwudHlwZS5UeXBlTWlycm9yOwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC50eXBlLlR5cGVWYXJpYWJsZTsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwudHlwZS5UeXBlVmlzaXRvcjsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwudXRpbC5TaW1wbGVUeXBlVmlzaXRvcjk7CgppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlR5cGUuQ2xhc3NUeXBlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkRlZmluZWRCeTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5EZWZpbmVkQnkuQXBpOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLlN0cmluZ1V0aWxzOwoKcHVibGljIGFic3RyYWN0IGNsYXNzIFR5cGVEZXNjIGltcGxlbWVudHMgU2VyaWFsaXphYmxlIHsKCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtODIwMTYzNDE0MzkxNTUxOTE3Mkw7CgogICAgVHlwZUtpbmQgdHlwZUtpbmQ7CgogICAgcHVibGljIFR5cGVEZXNjKFR5cGVLaW5kIHR5cGVLaW5kKSB7CiAgICAgICAgdGhpcy50eXBlS2luZCA9IHR5cGVLaW5kOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgVHlwZURlc2MgZGVjb2RlU3RyaW5nKFN0cmluZyBzKSB7CiAgICAgICAgcyA9IHMudHJpbSgpOwogICAgICAgIGlmIChzLmVuZHNXaXRoKCJbXSIpKSB7CiAgICAgICAgICAgIFN0cmluZyBjb21wb25lbnRQYXJ0ID0gcy5zdWJzdHJpbmcoMCwgcy5sZW5ndGgoKS0yKTsKICAgICAgICAgICAgcmV0dXJuIG5ldyBBcnJheVR5cGVEZXNjKGRlY29kZVN0cmluZyhjb21wb25lbnRQYXJ0KSk7CiAgICAgICAgfQoKICAgICAgICBpZiAocy5zdGFydHNXaXRoKCIjIikpCiAgICAgICAgICAgIHJldHVybiBuZXcgVHlwZVZhclR5cGVEZXNjKHMuc3Vic3RyaW5nKDEpKTsKCiAgICAgICAgaWYgKHMubWF0Y2hlcygiYm9vbGVhbnxieXRlfGNoYXJ8ZG91YmxlfGZsb2F0fGludHxsb25nfHNob3J0fHZvaWQiKSkgewogICAgICAgICAgICBUeXBlS2luZCB0ayA9IFR5cGVLaW5kLnZhbHVlT2YoU3RyaW5nVXRpbHMudG9VcHBlckNhc2UocykpOwogICAgICAgICAgICByZXR1cm4gbmV3IFByaW1pdGl2ZVR5cGVEZXNjKHRrKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBuZXcgUmVmZXJlbmNlVHlwZURlc2Mocyk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBTdHJpbmcgZW5jb2RlQXNTdHJpbmcoVHlwZURlc2MgdGQpIHsKICAgICAgICBpZiAodGQudHlwZUtpbmQuaXNQcmltaXRpdmUoKSB8fCB0ZC50eXBlS2luZCA9PSBUeXBlS2luZC5WT0lEKQogICAgICAgICAgICByZXR1cm4gU3RyaW5nVXRpbHMudG9Mb3dlckNhc2UodGQudHlwZUtpbmQudG9TdHJpbmcoKSk7CgogICAgICAgIGlmICh0ZC50eXBlS2luZCA9PSBUeXBlS2luZC5BUlJBWSkKICAgICAgICAgICAgcmV0dXJuIGVuY29kZUFzU3RyaW5nKCgoQXJyYXlUeXBlRGVzYykgdGQpLmNvbXBUeXBlRGVzYykgKyAiW10iOwoKICAgICAgICBpZiAodGQudHlwZUtpbmQgPT0gVHlwZUtpbmQuVFlQRVZBUikKICAgICAgICAgICAgcmV0dXJuICIjIiArICgoVHlwZVZhclR5cGVEZXNjKSB0ZCkuaWRlbnRpZmllcjsKCiAgICAgICAgaWYgKHRkLnR5cGVLaW5kID09IFR5cGVLaW5kLkRFQ0xBUkVEKQogICAgICAgICAgICByZXR1cm4gKChSZWZlcmVuY2VUeXBlRGVzYykgdGQpLmphdmFUeXBlLnRvU3RyaW5nKCk7CgogICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigiVW5oYW5kbGVkIHR5cGU6ICIgKyB0ZC50eXBlS2luZCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBUeXBlRGVzYyBmcm9tVHlwZShUeXBlTWlycm9yIHR5cGUpIHsKICAgICAgICBUeXBlVmlzaXRvcjxUeXBlRGVzYywgVm9pZD4gdiA9IG5ldyBTaW1wbGVUeXBlVmlzaXRvcjk8VHlwZURlc2MsIFZvaWQ+KCkgewogICAgICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICAgICAgICAgIHB1YmxpYyBUeXBlRGVzYyB2aXNpdEFycmF5KEFycmF5VHlwZSB0LCBWb2lkIHApIHsKICAgICAgICAgICAgICAgIHJldHVybiBuZXcgQXJyYXlUeXBlRGVzYyh0LmdldENvbXBvbmVudFR5cGUoKS5hY2NlcHQodGhpcywgcCkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICAgICAgICAgIHB1YmxpYyBUeXBlRGVzYyB2aXNpdERlY2xhcmVkKERlY2xhcmVkVHlwZSB0LCBWb2lkIHApIHsKICAgICAgICAgICAgICAgIHJldHVybiBuZXcgUmVmZXJlbmNlVHlwZURlc2MoKChDbGFzc1R5cGUpIHQpLnRzeW0uZmxhdE5hbWUoKS50b1N0cmluZygpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgICAgICBwdWJsaWMgVHlwZURlc2MgdmlzaXROb1R5cGUoTm9UeXBlIHQsIFZvaWQgcCkgewogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBQcmltaXRpdmVUeXBlRGVzYyhUeXBlS2luZC5WT0lEKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgICAgICBwdWJsaWMgVHlwZURlc2MgdmlzaXRUeXBlVmFyaWFibGUoVHlwZVZhcmlhYmxlIHQsIFZvaWQgcCkgewogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBUeXBlVmFyVHlwZURlc2ModC50b1N0cmluZygpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgICAgICBwdWJsaWMgVHlwZURlc2MgdmlzaXRQcmltaXRpdmUoUHJpbWl0aXZlVHlwZSB0LCBWb2lkIHApIHsKICAgICAgICAgICAgICAgIHJldHVybiBuZXcgUHJpbWl0aXZlVHlwZURlc2ModC5nZXRLaW5kKCkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICAgICAgICAgIHB1YmxpYyBUeXBlRGVzYyB2aXNpdEVycm9yKEVycm9yVHlwZSB0LCBWb2lkIHApIHsKICAgICAgICAgICAgICAgIHJldHVybiBuZXcgUmVmZXJlbmNlVHlwZURlc2MoIjxlcnJvciB0eXBlPiIpOwogICAgICAgICAgICB9CiAgICAgICAgfTsKCiAgICAgICAgVHlwZURlc2MgdGQgPSB2LnZpc2l0KHR5cGUpOwogICAgICAgIGlmICh0ZCA9PSBudWxsKQogICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoIlVuaGFuZGxlZCB0eXBlIG1pcnJvcjogIiArIHR5cGUgKyAiICgiICsgdHlwZS5nZXRDbGFzcygpICsgIikiKTsKICAgICAgICByZXR1cm4gdGQ7CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iaikgewogICAgICAgIGlmIChnZXRDbGFzcygpICE9IG9iai5nZXRDbGFzcygpKQogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgcmV0dXJuIHR5cGVLaW5kLmVxdWFscygoKFR5cGVEZXNjKSBvYmopLnR5cGVLaW5kKTsKICAgIH0KCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgICAgcmV0dXJuIHR5cGVLaW5kLmhhc2hDb2RlKCk7CiAgICB9Cn0KUEsDBAoAAAgAAAY7qUoaFOR1UwgAAFMIAAAwAAAAY29tL3N1bi90b29scy9zamF2YWMvcHViYXBpL1R5cGVWYXJUeXBlRGVzYy5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDE0LCAyMDE1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuc2phdmFjLnB1YmFwaTsKCmltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKCmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLnR5cGUuVHlwZUtpbmQ7CgpwdWJsaWMgY2xhc3MgVHlwZVZhclR5cGVEZXNjIGV4dGVuZHMgVHlwZURlc2MgaW1wbGVtZW50cyBTZXJpYWxpemFibGUgewoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDMzNTc2MTY3NTQ1NDQ3OTYzNzNMOwoKICAgIFN0cmluZyBpZGVudGlmaWVyOyAvLyBFeGFtcGxlOiAiVCIKCiAgICBwdWJsaWMgVHlwZVZhclR5cGVEZXNjKFN0cmluZyBpZGVudGlmaWVyKSB7CiAgICAgICAgc3VwZXIoVHlwZUtpbmQuVFlQRVZBUik7CiAgICAgICAgdGhpcy5pZGVudGlmaWVyID0gaWRlbnRpZmllcjsKICAgIH0KCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqKSB7CiAgICAgICAgaWYgKCFzdXBlci5lcXVhbHMob2JqKSkKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIHJldHVybiBpZGVudGlmaWVyLmVxdWFscygoKFR5cGVWYXJUeXBlRGVzYykgb2JqKS5pZGVudGlmaWVyKTsKICAgIH0KCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmhhc2hDb2RlKCkgXiBpZGVudGlmaWVyLmhhc2hDb2RlKCk7CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewogICAgICAgIHJldHVybiBTdHJpbmcuZm9ybWF0KCIlc1tpZGVudGlmaWVyOiAlc10iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldENsYXNzKCkuZ2V0U2ltcGxlTmFtZSgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlkZW50aWZpZXIpOwogICAgfQp9ClBLAwQKAAAIAAAGO6lKPxQbdyIKAAAiCgAAKAAAAGNvbS9zdW4vdG9vbHMvc2phdmFjL3B1YmFwaS9QdWJUeXBlLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTQsIDIwMTUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5zamF2YWMucHViYXBpOwoKaW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOwppbXBvcnQgamF2YS51dGlsLlNldDsKCmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuTW9kaWZpZXI7CgpwdWJsaWMgY2xhc3MgUHViVHlwZSBpbXBsZW1lbnRzIFNlcmlhbGl6YWJsZSB7CgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTc0MjM0MTYwNDkyNTM4ODk3OTNMOwoKICAgIHB1YmxpYyBmaW5hbCBTZXQ8TW9kaWZpZXI+IG1vZGlmaWVyczsKICAgIHB1YmxpYyBmaW5hbCBTdHJpbmcgZnFOYW1lOwogICAgcHVibGljIGZpbmFsIFB1YkFwaSBwdWJBcGk7CgogICAgcHVibGljIFB1YlR5cGUoU2V0PE1vZGlmaWVyPiBtb2RpZmllcnMsCiAgICAgICAgICAgICAgICAgICBTdHJpbmcgZnFOYW1lLAogICAgICAgICAgICAgICAgICAgUHViQXBpIHB1YkFwaSkgewogICAgICAgIHRoaXMubW9kaWZpZXJzID0gbW9kaWZpZXJzOwogICAgICAgIHRoaXMuZnFOYW1lID0gZnFOYW1lOwogICAgICAgIHRoaXMucHViQXBpID0gcHViQXBpOwogICAgfQoKICAgIHB1YmxpYyBTdHJpbmcgZ2V0RnFOYW1lKCkgewogICAgICAgIHJldHVybiBmcU5hbWUudG9TdHJpbmcoKTsKICAgIH0KCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqKSB7CiAgICAgICAgaWYgKGdldENsYXNzKCkgIT0gb2JqLmdldENsYXNzKCkpCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICBQdWJUeXBlIG90aGVyID0gKFB1YlR5cGUpIG9iajsKICAgICAgICByZXR1cm4gbW9kaWZpZXJzLmVxdWFscyhvdGhlci5tb2RpZmllcnMpCiAgICAgICAgICAgICYmIGZxTmFtZS5lcXVhbHMob3RoZXIuZnFOYW1lKQogICAgICAgICAgICAmJiBwdWJBcGkuZXF1YWxzKG90aGVyLnB1YkFwaSk7CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICAgIHJldHVybiBtb2RpZmllcnMuaGFzaENvZGUoKSBeIGZxTmFtZS5oYXNoQ29kZSgpIF4gcHViQXBpLmhhc2hDb2RlKCk7CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewogICAgICAgIHJldHVybiBTdHJpbmcuZm9ybWF0KCIlc1ttb2RpZmllcnM6ICVzLCBmcU5hbWU6ICVzLCBwdWJBcGk6ICVzXSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0Q2xhc3MoKS5nZXRTaW1wbGVOYW1lKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9kaWZpZXJzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZxTmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwdWJBcGkpOwogICAgfQp9ClBLAwQKAAAIAAAGO6lKUCmE7mkUAABpFAAAJQAAAGNvbS9zdW4vdG9vbHMvc2phdmFjL1RyYW5zZm9ybWVyLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTIsIDIwMTYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5zamF2YWM7CgppbXBvcnQgamF2YS5pby5Xcml0ZXI7CmltcG9ydCBqYXZhLm5ldC5VUkk7CmltcG9ydCBqYXZhLnV0aWwuTWFwOwppbXBvcnQgamF2YS51dGlsLlNldDsKCmltcG9ydCBjb20uc3VuLnRvb2xzLnNqYXZhYy5jb21wLkNvbXBpbGF0aW9uU2VydmljZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuc2phdmFjLm9wdGlvbnMuT3B0aW9uczsKaW1wb3J0IGNvbS5zdW4udG9vbHMuc2phdmFjLnB1YmFwaS5QdWJBcGk7CgovKioKICogVGhlIHRyYW5zZm9ybSBpbnRlcmZhY2UgaXMgdXNlZCB0byB0cmFuc2Zvcm0gY29udGVudCBpbnNpZGUgYSBwYWNrYWdlLCBmcm9tIG9uZSBmb3JtIHRvIGFub3RoZXIuCiAqIFVzdWFsbHkgdGhlIG91dHB1dCBmb3JtIGlzIGFuIHVucHJlZGljdGFibGUgbnVtYmVyIG9mIG91dHB1dCBmaWxlcy4gKGVnIGNsYXNzIGZpbGVzKQogKiBidXQgY2FuIGFsc28gYmUgYW4gdW5wcmVkaWN0YWJsZSBudW1iZXIgb2YgZ2VuZXJhdGVkIHNvdXJjZSBmaWxlcyAoZWcgaWRsMmphdmEpCiAqIG9yIGEgc2luZ2xlIHByZWRpY3RhYmxlIG91dHB1dCBmaWxlIChlZyB3aGVuIGNvcHlpbmcsY2xlYW5pbmcgb3IgY29tcGlsaW5nIGEgcHJvcGVydGllcyBmaWxlKS4KICoKICogIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqICBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqICBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogKiAgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPgogKi8KcHVibGljIGludGVyZmFjZSBUcmFuc2Zvcm1lciB7CiAgICAvKioKICAgICAqIFRoZSB0cmFuc2Zvcm0gbWV0aG9kIHRha2VzIGEgc2V0IG9mIHBhY2thZ2UgbmFtZXMsIG1hcHBlZCB0byB0aGVpciBzb3VyY2UgZmlsZXMgYW5kIHRvIHRoZQogICAgICogcHViYXBpcyBvZiB0aGUgcGFja2FnZXMuCiAgICAgKgogICAgICogVGhlIHRyYW5zZm9ybSBpbXBsZW1lbnRhdGlvbiBtdXN0OgogICAgICogICAgc3RvcmUgdGhlIG5hbWVzIG9mIHRoZSBnZW5lcmF0ZWQgYXJ0aWZhY3RzIGZvciBlYWNoIHBhY2thZ2UgaW50byBwYWNrYWdlX2FydGlmYWN0cwogICAgICogICAgc3RvcmUgZm91bmQgZGVwZW5kZW5jaWVzIHRvIG90aGVyIHBhY2thZ2VzIGludG8gdGhlIHN1cHBsaWVkIHNldCBwYWNrYWdlX2RlcGVuZGVuY2llcwogICAgICogICAgc3RvcmUgdGhlIHB1YmxpYyBhcGkgZm9yIGEgcGFja2FnZSBpbnRvIHRoZSBzdXBwbGllZCBzZXQgcGFja2FnZV9wdWJhcGlzCiAgICAgKgogICAgICogQW55IGJlbmlnbiBtZXNzYWdlcyBhcyBhIHJlc3VsdCBvZiBydW5uaW5nIHRoZSB0cmFuc2Zvcm0KICAgICAqIGFyZSB3cml0dGVuIGludG8gc3Rkb3V0LCBhbmQgZXJyb3JzIGFyZSB3cml0dGVuIHRvIHN0ZGVyci4KICAgICAqCiAgICAgKiBUaGUgZGVidWdfbGV2ZWwgY2FuIGJlIDA9c2lsZW50IChvbmx5IHdhcm5pbmdzIGFuZCBlcnJvcnMpIDE9bm9ybWFsIDI9dmVyYm9zZSAzIG9yIGdyZWF0ZXI9ZGVidWcKICAgICAqIHNldEV4dHJhIGlzIHVzZWQgdG8gc2V0IHRoZSBleHRyYSBpbmZvcm1hdGlvbiBpbmZvcm1hdGlvbiB0aGF0IGNhbiBiZSBwYXNzZWQgb24KICAgICAqIHRoZSBjb21tYW5kIGxpbmUgdG8gdGhlIHNtYXJ0IGphdmFjIHdyYXBwZXIuCiAgICAgKgogICAgICogSWYgc2phdmFjIGlzIGJ1aWxkaW5nIGluY3JlbWVudGFsbHkgZnJvbSBhbiBleGlzdGluZyBqYXZhY19zdGF0ZSwgdGhlIHZhciBpbmNyZW1lbnRhbCBpcyB0cnVlLgogICAgICoKICAgICAqIFRoZSB0cmFuc2Zvcm1lciB3aWxsIG9ubHkgYmUgY2FsbGVkIGlmIHNvbWUgc291cmNlIGluIHRoZSBwYWNrYWdlIChvciBkZXBlbmRlbmN5KSBoYXMKICAgICAqIGEgbW9kaWZpZWQgdGltZXN0YW1wLiBUaHVzIHRoZSB0cmFuc2Zvcm1lciBtaWdodCBnZXQgY2FsbGVkIHdpdGggbWFueSBzb3VyY2VzLCBvZiB3aGljaAogICAgICogb25seSBvbmUgaGFzIGNoYW5nZWQuIFRoZSB0cmFuc2Zvcm1lciBpcyBhbGxvd2VkIHRvIHJlZ2VuZXJhdGUgYWxsIGFydGlmYWN0cyBidXQKICAgICAqIGEgYmV0dGVyIHRyYW5zZm9ybWVyIHdpbGwgb25seSB3cml0ZSB0aG9zZSBhcnRpZmFjdHMgdGhhdCBuZWVkIHVwZGF0aW5nLgogICAgICoKICAgICAqIEhvd2V2ZXIgdGhlIHRyYW5zZm9ybWVyIG11c3QgdmVyaWZ5IHRoYXQgdGhlIGV4aXN0aW5nIGFydGlmYWN0cyByZWFsbHkgYXJlIHRoZXJlIQogICAgICogYW5kIGl0IG11c3QgYWx3YXlzIHVwZGF0ZSBwYWNrYWdlX2FydGlmYWN0cywgcGFja2FnZV9kZXBlbmRlbmNpZXMsIGFuZCBwYWNrYWdlX3B1YmFwaXMgY29ycmVjdGx5LgogICAgICogVGhpcyBtZWFucyB0aGF0IGF0IGxlYXN0IGZvciBKYXZhIHNvdXJjZSwgaXQgd2lsbCBhbHdheXMgaGF2ZSB0byByZWNvbXBpbGUgdGhlIHNvdXJjZXMuCiAgICAgKgogICAgICogVGhlIHRyYW5zZm9ybWVyIGlzIGFsbG93ZWQgdG8gcHV0IGZpbGVzIGFueXdoZXJlIGluIHRoZSBkZXN0X3Jvb3QuCiAgICAgKiBBbiBleGFtcGxlIG9mIHRoaXMgaXMsIGNhbiBiZSB0aGUgTUVUQS1JTkYgdHJhbnNmb3JtZXIgdGhhdCBjb3B5IGZpbGVzCiAgICAgKiBiZWxvdyBNRVRBLUlORiBkaXJlY3RvcmllcyB0byB0aGUgc2luZ2xlIE1FVEEtSU5GIGRpcmVjdG9yeSBiZWxvdyBkZXN0X3Jvb3QuCiAgICAgKgogICAgICogRmFsc2UgaXMgcmV0dXJuZWQgaWYgdGhlcmUgd2FzIGFuIGVycm9yIHRoYXQgcHJldmVudGVkIHRoZSB0cmFuc2Zvcm0uCiAgICAgKiBJLmUuIHNvbWV0aGluZyB3YXMgcHJpbnRlZCBvbiBzdGRlcnIuCiAgICAgKgogICAgICogSWYgbnVtX2NvcmVzIGlzIHNldCB0byBhIG5vbi16ZXJvIHZhbHVlLiBUaGUgdHJhbnNmb3JtIHNob3VsZCBhdHRlbXB0IHRvIHVzZSBubyBtb3JlIHRoYW4gdGhlc2UKICAgICAqIG51bWJlciBvZiB0aHJlYWRzIGZvciBoZWF2eSB3b3JrLgogICAgICovCiAgICBib29sZWFuIHRyYW5zZm9ybShDb21waWxhdGlvblNlcnZpY2Ugc2phdmFjLAogICAgICAgICAgICAgICAgICAgICAgTWFwPFN0cmluZyxTZXQ8VVJJPj4gcGtnU3JjcywKICAgICAgICAgICAgICAgICAgICAgIFNldDxVUkk+ICAgICAgICAgICAgIHZpc2libGVTb3VyY2VzLAogICAgICAgICAgICAgICAgICAgICAgTWFwPFN0cmluZyxTZXQ8U3RyaW5nPj4gb2xkUGFja2FnZURlcGVuZGVuY2llcywKICAgICAgICAgICAgICAgICAgICAgIFVSSSBkZXN0Um9vdCwKICAgICAgICAgICAgICAgICAgICAgIE1hcDxTdHJpbmcsU2V0PFVSST4+ICAgIHBhY2thZ2VBcnRpZmFjdHMsCiAgICAgICAgICAgICAgICAgICAgICBNYXA8U3RyaW5nLCBNYXA8U3RyaW5nLCBTZXQ8U3RyaW5nPj4+IHBhY2thZ2VEZXBlbmRlbmNpZXMsICAgLy8gUGFja2FnZSBuYW1lIC0+IEZ1bGx5IFF1YWxpZmllZCBUeXBlIFtmcm9tXSAtPiBTZXQgb2YgZnVsbHkgcXVhbGlmaWVkIHR5cGUgW3RvXQogICAgICAgICAgICAgICAgICAgICAgTWFwPFN0cmluZywgTWFwPFN0cmluZywgU2V0PFN0cmluZz4+PiBwYWNrYWdlQ3BEZXBlbmRlbmNpZXMsIC8vIFBhY2thZ2UgbmFtZSAtPiBGdWxseSBRdWFsaWZpZWQgVHlwZSBbZnJvbV0gLT4gU2V0IG9mIGZ1bGx5IHF1YWxpZmllZCB0eXBlIFt0b10KICAgICAgICAgICAgICAgICAgICAgIE1hcDxTdHJpbmcsIFB1YkFwaT4gICAgIHBhY2thZ2VQdWJsaWNBcGlzLAogICAgICAgICAgICAgICAgICAgICAgTWFwPFN0cmluZywgUHViQXBpPiAgICAgZGVwZW5kZW5jeUFwaXMsCiAgICAgICAgICAgICAgICAgICAgICBpbnQgZGVidWdMZXZlbCwKICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gaW5jcmVtZW50YWwsCiAgICAgICAgICAgICAgICAgICAgICBpbnQgbnVtQ29yZXMpOwoKICAgIHZvaWQgc2V0RXh0cmEoU3RyaW5nIGUpOwogICAgdm9pZCBzZXRFeHRyYShPcHRpb25zIGFyZ3MpOwp9ClBLAwQKAAAIAAAGO6lKAAAAAAAAAAAAAAAAHAAAAGNvbS9zdW4vdG9vbHMvc2phdmFjL3NlcnZlci9QSwMECgAACAAABjupSgAAAAAAAAAAAAAAACAAAABjb20vc3VuL3Rvb2xzL3NqYXZhYy9zZXJ2ZXIvbG9nL1BLAwQKAAAIAAAGO6lKpyVxQiILAAAiCwAANAAAAGNvbS9zdW4vdG9vbHMvc2phdmFjL3NlcnZlci9sb2cvTGF6eUluaXRGaWxlTG9nLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5zamF2YWMuc2VydmVyLmxvZzsKCmltcG9ydCBjb20uc3VuLnRvb2xzLnNqYXZhYy5Mb2c7CgppbXBvcnQgamF2YS5pby5GaWxlV3JpdGVyOwppbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKaW1wb3J0IGphdmEuaW8uUHJpbnRXcml0ZXI7CmltcG9ydCBqYXZhLm5pby5maWxlLkZpbGVzOwppbXBvcnQgamF2YS5uaW8uZmlsZS5QYXRoOwppbXBvcnQgamF2YS5uaW8uZmlsZS5QYXRoczsKCnB1YmxpYyBjbGFzcyBMYXp5SW5pdEZpbGVMb2cgZXh0ZW5kcyBMb2cgewoKICAgIFN0cmluZyBiYXNlRmlsZW5hbWU7CiAgICBQYXRoIGRlc3RpbmF0aW9uID0gbnVsbDsKCiAgICBwdWJsaWMgTGF6eUluaXRGaWxlTG9nKFN0cmluZyBiYXNlRmlsZW5hbWUpIHsKICAgICAgICBzdXBlcihudWxsLCBudWxsKTsKICAgICAgICB0aGlzLmJhc2VGaWxlbmFtZSA9IGJhc2VGaWxlbmFtZTsKICAgIH0KCiAgICBwcm90ZWN0ZWQgdm9pZCBwcmludExvZ01zZyhMZXZlbCBtc2dMZXZlbCwgU3RyaW5nIG1zZykgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIC8vIExhemlseSBpbml0aWFsaXplIG91dC9lcnIKICAgICAgICAgICAgaWYgKG91dCA9PSBudWxsICYmIGlzTGV2ZWxMb2dnZWQobXNnTGV2ZWwpKSB7CiAgICAgICAgICAgICAgICBkZXN0aW5hdGlvbiA9IGdldEF2YWlsYWJsZURlc3RpbmF0aW9uKCk7CiAgICAgICAgICAgICAgICBvdXQgPSBlcnIgPSBuZXcgUHJpbnRXcml0ZXIobmV3IEZpbGVXcml0ZXIoZGVzdGluYXRpb24udG9GaWxlKCkpLCB0cnVlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvLyBQcm9jZWVkIHRvIGxvZyB0aGUgbWVzc2FnZQogICAgICAgICAgICBzdXBlci5wcmludExvZ01zZyhtc2dMZXZlbCwgbXNnKTsKICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIC8vIFRoaXMgY291bGQgYmUgYmFkLiBXZSBtaWdodCBoYXZlIHJ1biBpbnRvIGFuIGVycm9yIGFuZCB3ZSBjYW4ndAogICAgICAgICAgICAvLyBsb2cgaXQuIFJlc29ydCB0byBwcmludGluZyBvbiBzdGRvdXQuCiAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiSU8gZXJyb3Igb2NjdXJyZWQ6ICIgKyBlLmdldE1lc3NhZ2UoKSk7CiAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiT3JpZ2luYWwgbWVzc2FnZTogWyIgKyBtc2dMZXZlbCArICJdICIgKyBtc2cpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gVGhlIGZpcnN0IGF2YWlsYWJsZSBwYXRoIG9mIGJhc2VGaWxlbmFtZSwgYmFzZUZpbGVuYW1lLjEsCiAgICAgKiBiYXNlZmlsZW5hbWUuMiwgLi4uCiAgICAgKi8KICAgIHByaXZhdGUgUGF0aCBnZXRBdmFpbGFibGVEZXN0aW5hdGlvbigpIHsKICAgICAgICBQYXRoIHAgPSBQYXRocy5nZXQoYmFzZUZpbGVuYW1lKTsKICAgICAgICBpbnQgaSA9IDE7CiAgICAgICAgd2hpbGUgKEZpbGVzLmV4aXN0cyhwKSkgewogICAgICAgICAgICBwID0gUGF0aHMuZ2V0KGJhc2VGaWxlbmFtZSArICIuIiArIGkrKyk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBwOwogICAgfQoKICAgIHB1YmxpYyBQYXRoIGdldExvZ0Rlc3RpbmF0aW9uKCkgewogICAgICAgIHJldHVybiBkZXN0aW5hdGlvbjsKICAgIH0KfQpQSwMECgAACAAABjupSnfoKHXUCgAA1AoAADgAAABjb20vc3VuL3Rvb2xzL3NqYXZhYy9zZXJ2ZXIvbG9nL0xvZ2dpbmdPdXRwdXRTdHJlYW0uamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAxNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLnNqYXZhYy5zZXJ2ZXIubG9nOwoKaW1wb3J0IGNvbS5zdW4udG9vbHMuc2phdmFjLkxvZzsKCmltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbTsKaW1wb3J0IGphdmEuaW8uRmlsdGVyT3V0cHV0U3RyZWFtOwppbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOwoKcHVibGljIGNsYXNzIExvZ2dpbmdPdXRwdXRTdHJlYW0gZXh0ZW5kcyBGaWx0ZXJPdXRwdXRTdHJlYW0gewoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGVbXSBMSU5FX1NFUCA9IFN5c3RlbS5saW5lU2VwYXJhdG9yKCkuZ2V0Qnl0ZXMoKTsKCiAgICBwcml2YXRlIGZpbmFsIExvZy5MZXZlbCBsZXZlbDsKICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIGxpbmVQcmVmaXg7CiAgICBwcml2YXRlIEVvbFRyYWNraW5nQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJ1ZiA9IG5ldyBFb2xUcmFja2luZ0J5dGVBcnJheU91dHB1dFN0cmVhbSgpOwoKICAgIHB1YmxpYyBMb2dnaW5nT3V0cHV0U3RyZWFtKE91dHB1dFN0cmVhbSBvdXQsIExvZy5MZXZlbCBsZXZlbCwgU3RyaW5nIGxpbmVQcmVmaXgpIHsKICAgICAgICBzdXBlcihvdXQpOwogICAgICAgIHRoaXMubGV2ZWwgPSBsZXZlbDsKICAgICAgICB0aGlzLmxpbmVQcmVmaXggPSBsaW5lUHJlZml4OwogICAgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGUoaW50IGIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgc3VwZXIud3JpdGUoYik7CiAgICAgICAgYnVmLndyaXRlKGIpOwogICAgICAgIGlmIChidWYuaXNMaW5lQ29tcGxldGUoKSkgewogICAgICAgICAgICBTdHJpbmcgbGluZSA9IG5ldyBTdHJpbmcoYnVmLnRvQnl0ZUFycmF5KCksIDAsIGJ1Zi5zaXplKCkgLSBMSU5FX1NFUC5sZW5ndGgpOwogICAgICAgICAgICBMb2cubG9nKGxldmVsLCBsaW5lUHJlZml4ICsgbGluZSk7CiAgICAgICAgICAgIGJ1ZiA9IG5ldyBFb2xUcmFja2luZ0J5dGVBcnJheU91dHB1dFN0cmVhbSgpOwogICAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBFb2xUcmFja2luZ0J5dGVBcnJheU91dHB1dFN0cmVhbSBleHRlbmRzIEJ5dGVBcnJheU91dHB1dFN0cmVhbSB7CiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZVtdIEVPTCA9IFN5c3RlbS5saW5lU2VwYXJhdG9yKCkuZ2V0Qnl0ZXMoKTsKICAgICAgICBwcml2YXRlIGJvb2xlYW4gaXNMaW5lQ29tcGxldGUoKSB7CiAgICAgICAgICAgIGlmIChjb3VudCA8IEVPTC5sZW5ndGgpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IEVPTC5sZW5ndGg7IGkrKykgewogICAgICAgICAgICAgICAgaWYgKGJ1Zltjb3VudCAtIEVPTC5sZW5ndGggKyBpXSAhPSBFT0xbaV0pIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgfQp9ClBLAwQKAAAIAAAGO6lKinSDrY8JAACPCQAANQAAAGNvbS9zdW4vdG9vbHMvc2phdmFjL3NlcnZlci9Db21waWxhdGlvblN1YlJlc3VsdC5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDE0LCAyMDE2LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuc2phdmFjLnNlcnZlcjsKCmltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKaW1wb3J0IGphdmEubmV0LlVSSTsKaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOwppbXBvcnQgamF2YS51dGlsLk1hcDsKaW1wb3J0IGphdmEudXRpbC5TZXQ7CgppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5tYWluLk1haW4uUmVzdWx0OwppbXBvcnQgY29tLnN1bi50b29scy5zamF2YWMucHViYXBpLlB1YkFwaTsKCi8qKgogKgogKiAgPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24gcmlzay4KICogIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yCiAqICBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+CiAqLwpwdWJsaWMgY2xhc3MgQ29tcGlsYXRpb25TdWJSZXN1bHQgaW1wbGVtZW50cyBTZXJpYWxpemFibGUgewoKICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA0NjczOTE4MTExM0w7CgogICAgcHVibGljIFJlc3VsdCByZXN1bHQ7CiAgICBwdWJsaWMgTWFwPFN0cmluZywgU2V0PFVSST4+IHBhY2thZ2VBcnRpZmFjdHMgPSBuZXcgSGFzaE1hcDw+KCk7CiAgICBwdWJsaWMgTWFwPFN0cmluZywgTWFwPFN0cmluZywgU2V0PFN0cmluZz4+PiBwYWNrYWdlRGVwZW5kZW5jaWVzID0gbmV3IEhhc2hNYXA8PigpOwogICAgcHVibGljIE1hcDxTdHJpbmcsIE1hcDxTdHJpbmcsIFNldDxTdHJpbmc+Pj4gcGFja2FnZUNwRGVwZW5kZW5jaWVzID0gbmV3IEhhc2hNYXA8PigpOwogICAgcHVibGljIE1hcDxTdHJpbmcsIFB1YkFwaT4gcGFja2FnZVB1YmFwaXMgPSBuZXcgSGFzaE1hcDw+KCk7CiAgICBwdWJsaWMgTWFwPFN0cmluZywgUHViQXBpPiBkZXBlbmRlbmN5UHViYXBpcyA9IG5ldyBIYXNoTWFwPD4oKTsKICAgIHB1YmxpYyBTdHJpbmcgc3Rkb3V0ID0gIiI7CiAgICBwdWJsaWMgU3RyaW5nIHN0ZGVyciA9ICIiOwoKICAgIHB1YmxpYyBDb21waWxhdGlvblN1YlJlc3VsdChSZXN1bHQgcmVzdWx0KSB7CiAgICAgICAgdGhpcy5yZXN1bHQgPSByZXN1bHQ7CiAgICB9CgogICAgcHVibGljIHZvaWQgc2V0UmVzdWx0KFJlc3VsdCByZXN1bHQpIHsKICAgICAgICB0aGlzLnJlc3VsdCA9IHJlc3VsdDsKICAgIH0KfQpQSwMECgAACAAABjupSu1x5MFbDwAAWw8AACsAAABjb20vc3VuL3Rvb2xzL3NqYXZhYy9zZXJ2ZXIvU2VydmVyTWFpbi5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDE0LCAyMDE2LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuc2phdmFjLnNlcnZlcjsKCmltcG9ydCBqYXZhLmlvLkZpbGVXcml0ZXI7CmltcG9ydCBqYXZhLmlvLkZpbHRlck91dHB1dFN0cmVhbTsKaW1wb3J0IGphdmEuaW8uRmlsdGVyV3JpdGVyOwppbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKaW1wb3J0IGphdmEuaW8uUHJpbnRTdHJlYW07CmltcG9ydCBqYXZhLmxhbmcuVGhyZWFkLlVuY2F1Z2h0RXhjZXB0aW9uSGFuZGxlcjsKCmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLm1haW4uTWFpbjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMubWFpbi5NYWluLlJlc3VsdDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuc2phdmFjLkxvZzsKaW1wb3J0IGNvbS5zdW4udG9vbHMuc2phdmFjLkxvZy5MZXZlbDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuc2phdmFjLnNlcnZlci5sb2cuTGF6eUluaXRGaWxlTG9nOwppbXBvcnQgY29tLnN1bi50b29scy5zamF2YWMuc2VydmVyLmxvZy5Mb2dnaW5nT3V0cHV0U3RyZWFtOwoKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLnNqYXZhYy5Mb2cuTGV2ZWwuRVJST1I7CmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5zamF2YWMuTG9nLkxldmVsLklORk87CgovKioKICogIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqICBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqICBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogKiAgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPgogKi8KcHVibGljIGNsYXNzIFNlcnZlck1haW4gewoKICAgIC8vIEZvciBsb2dnaW5nIHNlcnZlciBpbnRlcm5hbCAobm9uIHJlcXVlc3Qgc3BlY2lmaWMpIGVycm9ycy4KICAgIHByaXZhdGUgc3RhdGljIExhenlJbml0RmlsZUxvZyBlcnJvckxvZzsKCiAgICBwdWJsaWMgc3RhdGljIGludCBydW4oU3RyaW5nW10gYXJncykgewoKICAgICAgICAvLyBVbmRlciBub3JtYWwgb3BlcmF0aW9uLCBhbGwgbG9nZ2luZyBtZXNzYWdlcyBnZW5lcmF0ZWQgc2VydmVyLXNpZGUKICAgICAgICAvLyBhcmUgZHVlIHRvIGNvbXBpbGF0aW9uIHJlcXVlc3RzLiBUaGVzZSBsb2dnaW5nIG1lc3NhZ2VzIHNob3VsZAogICAgICAgIC8vIGJlIHJlbGF5ZWQgYmFjayB0byB0aGUgcmVxdWVzdGluZyBjbGllbnQgcmF0aGVyIHRoYW4gd3JpdHRlbiB0byB0aGUKICAgICAgICAvLyBzZXJ2ZXIgbG9nLiBUaGUgb25seSBtZXNzYWdlcyB0aGF0IHNob3VsZCBiZSB3cml0dGVuIHRvIHRoZSBzZXJ2ZXIKICAgICAgICAvLyBsb2cgKGluIHByb2R1Y3Rpb24gbW9kZSkgc2hvdWxkIGJlIGVycm9ycywKICAgICAgICBMb2cuc2V0TG9nRm9yQ3VycmVudFRocmVhZChlcnJvckxvZyA9IG5ldyBMYXp5SW5pdEZpbGVMb2coInNlcnZlci5sb2ciKSk7CiAgICAgICAgTG9nLnNldExvZ0xldmVsKEVSUk9SKTsgLy8gc2hvdWxkIGJlIHNldCB0byBFUlJPUi4KCiAgICAgICAgLy8gTWFrZSBzdXJlIG5vIGV4Y2VwdGlvbnMgZ28gdW5kZXIgdGhlIHJhZGFyCiAgICAgICAgVGhyZWFkLnNldERlZmF1bHRVbmNhdWdodEV4Y2VwdGlvbkhhbmRsZXIoKHQsIGUpIC0+IHsKICAgICAgICAgICAgTG9nLnNldExvZ0ZvckN1cnJlbnRUaHJlYWQoZXJyb3JMb2cpOwogICAgICAgICAgICBMb2cuZXJyb3IoZSk7CiAgICAgICAgfSk7CgogICAgICAgIC8vIEluZXZpdGFibHkgc29tZW9uZSB3aWxsIHRyeSB0byBwcmludCBtZXNzYWdlcyB1c2luZyBTeXN0ZW0ue291dCxlcnJ9LgogICAgICAgIC8vIE1ha2Ugc3VyZSB0aGlzIG91dHB1dCBhbHNvIGVuZHMgdXAgaW4gdGhlIGxvZy4KICAgICAgICBTeXN0ZW0uc2V0T3V0KG5ldyBQcmludFN0cmVhbShuZXcgTG9nZ2luZ091dHB1dFN0cmVhbShTeXN0ZW0ub3V0LCBJTkZPLCAiW3N0ZG91dF0gIikpKTsKICAgICAgICBTeXN0ZW0uc2V0RXJyKG5ldyBQcmludFN0cmVhbShuZXcgTG9nZ2luZ091dHB1dFN0cmVhbShTeXN0ZW0uZXJyLCBFUlJPUiwgIltzdGRlcnJdICIpKSk7CgogICAgICAgIC8vIEFueSBvcHRpb25zIG90aGVyIHRoYW4gLS1zdGFydHNlcnZlcj8KICAgICAgICBpZiAoYXJncy5sZW5ndGggPiAxKSB7CiAgICAgICAgICAgIExvZy5lcnJvcigiV2hlbiBzcGF3bmluZyBhIGJhY2tncm91bmQgc2VydmVyLCBvbmx5IGEgc2luZ2xlIC0tc3RhcnRzZXJ2ZXIgYXJndW1lbnQgaXMgYWxsb3dlZC4iKTsKICAgICAgICAgICAgcmV0dXJuIFJlc3VsdC5DTURFUlIuZXhpdENvZGU7CiAgICAgICAgfQoKICAgICAgICBpbnQgZXhpdENvZGU7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgU2phdmFjU2VydmVyIHNlcnZlciA9IG5ldyBTamF2YWNTZXJ2ZXIoYXJnc1swXSk7CiAgICAgICAgICAgIGV4aXRDb2RlID0gc2VydmVyLnN0YXJ0U2VydmVyKCk7CiAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gfCBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBleCkgewogICAgICAgICAgICBleC5wcmludFN0YWNrVHJhY2UoKTsKICAgICAgICAgICAgZXhpdENvZGUgPSBSZXN1bHQuRVJST1IuZXhpdENvZGU7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gZXhpdENvZGU7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBMYXp5SW5pdEZpbGVMb2cgZ2V0RXJyb3JMb2coKSB7CiAgICAgICAgcmV0dXJuIGVycm9yTG9nOwogICAgfQp9ClBLAwQKAAAIAAAGO6lKGMEXWdQmAADUJgAAKQAAAGNvbS9zdW4vdG9vbHMvc2phdmFjL3NlcnZlci9Qb3J0RmlsZS5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDEyLCAyMDE2LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuc2phdmFjLnNlcnZlcjsKCmltcG9ydCBqYXZhLmlvLkZpbGU7CmltcG9ydCBqYXZhLmlvLkZpbGVOb3RGb3VuZEV4Y2VwdGlvbjsKaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CmltcG9ydCBqYXZhLmlvLlJhbmRvbUFjY2Vzc0ZpbGU7CmltcG9ydCBqYXZhLm5pby5jaGFubmVscy5DbG9zZWRDaGFubmVsRXhjZXB0aW9uOwppbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuRmlsZUNoYW5uZWw7CmltcG9ydCBqYXZhLm5pby5jaGFubmVscy5GaWxlTG9jazsKaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLkZpbGVMb2NrSW50ZXJydXB0aW9uRXhjZXB0aW9uOwppbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuU2VtYXBob3JlOwoKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5Bc3NlcnQ7CmltcG9ydCBjb20uc3VuLnRvb2xzLnNqYXZhYy5Mb2c7CmltcG9ydCBjb20uc3VuLnRvb2xzLnNqYXZhYy5jbGllbnQuUG9ydEZpbGVJbmFjY2Vzc2libGVFeGNlcHRpb247CgovKioKICogVGhlIFBvcnRGaWxlIGNsYXNzIG1lZGlhdGVzIGFjY2VzcyB0byBhIHNob3J0IGJpbmFyeSBmaWxlIGNvbnRhaW5pbmcgdGhlIHRjcC9pcCBwb3J0IChmb3IgdGhlIGxvY2FsaG9zdCkKICogYW5kIGEgY29va2llIG5lY2Vzc2FyeSBmb3IgdGhlIHNlcnZlciBhbnN3ZXJpbmcgb24gdGhhdCBwb3J0LiBUaGUgZmlsZSBjYW4gYmUgbG9ja2VkIHVzaW5nIGZpbGUgc3lzdGVtCiAqIHByaW1pdGl2ZXMgdG8gYXZvaWQgcmFjZSBjb25kaXRpb25zIHdoZW4gc2V2ZXJhbCBqYXZhYyBjbGllbnRzIGFyZSBzdGFydGVkIGF0IHRoZSBzYW1lLiBOb3RlIHRoYXQgZmlsZQogKiBzeXN0ZW0gbG9ja2luZyBpcyBub3QgYWx3YXlzIHN1cHBvcnRlZCBvbiBhIGFsbCBvcGVyYXRpbmcgc3lzdGVtcyBhbmQvb3IgZmlsZSBzeXN0ZW1zLgogKgogKiAgPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24gcmlzay4KICogIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yCiAqICBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+CiAqLwpwdWJsaWMgY2xhc3MgUG9ydEZpbGUgewoKICAgIC8vIFBvcnQgZmlsZSBmb3JtYXQ6CiAgICAvLyBieXRlIG9yZGVyaW5nOiBoaWdoIGJ5dGUgZmlyc3QgPSBiaWcgZW5kaWFuCiAgICAvLyBNYWdpYyBuciwgNCBieXRlIGludCwgZmlyc3QgaW4gZmlsZS4KICAgIHByaXZhdGUgZmluYWwgc3RhdGljIGludCBtYWdpY05yID0gMHgxMTc0OwogICAgLy8gRm9sbG93ZWQgYnkgYSA0IGJ5dGUgaW50LCB3aXRoIHRoZSBwb3J0IG5yLgogICAgLy8gRm9sbG93ZWQgYnkgYSA4IGJ5dGUgbG9uZywgd2l0aCBjb29raWUgbnIuCgogICAgcHJpdmF0ZSBTdHJpbmcgZmlsZW5hbWU7CiAgICBwcml2YXRlIEZpbGUgZmlsZTsKICAgIHByaXZhdGUgRmlsZSBzdG9wRmlsZTsKICAgIHByaXZhdGUgUmFuZG9tQWNjZXNzRmlsZSByd2ZpbGU7CiAgICBwcml2YXRlIEZpbGVDaGFubmVsIGNoYW5uZWw7CgogICAgLy8gRmlsZUxvY2sgdXNlZCB0byBzb2x2ZSBpbnRlciBKVk0gc3luY2hyb25pemF0aW9uLCBsb2NrU2VtIHVzZWQgdG8gYXZvaWQKICAgIC8vIEpWTSBpbnRlcm5hbCBPdmVybGFwcGluZ0ZpbGVMb2NrRXhjZXB0aW9ucy4KICAgIC8vIENsYXNzIGludmFyaWFudDogbG9jay5pc1ZhbGlkKCkgPC0+IGxvY2tTZW0uYXZhaWxhYmxlUGVybWl0cygpID09IDAKICAgIHByaXZhdGUgRmlsZUxvY2sgbG9jazsKICAgIHByaXZhdGUgU2VtYXBob3JlIGxvY2tTZW0gPSBuZXcgU2VtYXBob3JlKDEpOwoKICAgIHByaXZhdGUgYm9vbGVhbiBjb250YWluc1BvcnRJbmZvOwogICAgcHJpdmF0ZSBpbnQgc2VydmVyUG9ydDsKICAgIHByaXZhdGUgbG9uZyBzZXJ2ZXJDb29raWU7CiAgICBwcml2YXRlIGludCBteVNlcnZlclBvcnQ7CiAgICBwcml2YXRlIGxvbmcgbXlTZXJ2ZXJDb29raWU7CgogICAgLyoqCiAgICAgKiBDcmVhdGUgYSBuZXcgcG9ydGZpbGUuCiAgICAgKiBAcGFyYW0gZm4gaXMgdGhlIHBhdGggdG8gdGhlIGZpbGUuCiAgICAgKi8KICAgIHB1YmxpYyBQb3J0RmlsZShTdHJpbmcgZm4pIHsKICAgICAgICBmaWxlbmFtZSA9IGZuOwogICAgICAgIGZpbGUgPSBuZXcgRmlsZShmaWxlbmFtZSk7CiAgICAgICAgc3RvcEZpbGUgPSBuZXcgRmlsZShmaWxlbmFtZSsiLnN0b3AiKTsKICAgICAgICBjb250YWluc1BvcnRJbmZvID0gZmFsc2U7CiAgICAgICAgbG9jayA9IG51bGw7CiAgICB9CgogICAgcHJpdmF0ZSB2b2lkIGluaXRpYWxpemVDaGFubmVsKCkgdGhyb3dzIFBvcnRGaWxlSW5hY2Nlc3NpYmxlRXhjZXB0aW9uIHsKICAgICAgICB0cnkgewogICAgICAgICAgICByd2ZpbGUgPSBuZXcgUmFuZG9tQWNjZXNzRmlsZShmaWxlLCAicnciKTsKICAgICAgICB9IGNhdGNoIChGaWxlTm90Rm91bmRFeGNlcHRpb24gZSkgewogICAgICAgICAgICAvLyBSZWFjaGVkIGlmIGZpbGUgZm9yIGluc3RhbmNlIGFscmVhZHkgZXhpc3RzIGFuZCBpcyBhIGRpcmVjdG9yeQogICAgICAgICAgICB0aHJvdyBuZXcgUG9ydEZpbGVJbmFjY2Vzc2libGVFeGNlcHRpb24oZSk7CiAgICAgICAgfQogICAgICAgIC8vIFRoZSByd2ZpbGUgc2hvdWxkIG9ubHkgYmUgcmVhZGFibGUgYnkgdGhlIG93bmVyIG9mIHRoZSBwcm9jZXNzCiAgICAgICAgLy8gYW5kIG5vIG90aGVyISBIb3cgZG8gd2UgZG8gdGhhdCBvbiBhIFJhbmRvbUFjY2Vzc0ZpbGU/CiAgICAgICAgY2hhbm5lbCA9IHJ3ZmlsZS5nZXRDaGFubmVsKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBMb2NrIHRoZSBwb3J0IGZpbGUuCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIGxvY2soKSB0aHJvd3MgSU9FeGNlcHRpb24sIEludGVycnVwdGVkRXhjZXB0aW9uIHsKICAgICAgICBpZiAoY2hhbm5lbCA9PSBudWxsKSB7CiAgICAgICAgICAgIGluaXRpYWxpemVDaGFubmVsKCk7CiAgICAgICAgfQogICAgICAgIGxvY2tTZW0uYWNxdWlyZSgpOwogICAgICAgIGxvY2sgPSBjaGFubmVsLmxvY2soKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJlYWQgdGhlIHZhbHVlcyBmcm9tIHRoZSBwb3J0IGZpbGUgaW4gdGhlIGZpbGUgc3lzdGVtLgogICAgICogRXhwZWN0cyB0aGUgcG9ydCBmaWxlIHRvIGJlIGxvY2tlZC4KICAgICAqLwogICAgcHVibGljIHZvaWQgZ2V0VmFsdWVzKCkgIHsKICAgICAgICBjb250YWluc1BvcnRJbmZvID0gZmFsc2U7CiAgICAgICAgaWYgKGxvY2sgPT0gbnVsbCkgewogICAgICAgICAgICAvLyBOb3QgbG9ja2VkLCByZW1haW4gaWdub3JhbnQgYWJvdXQgcG9ydCBmaWxlIGNvbnRlbnRzLgogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGlmIChyd2ZpbGUubGVuZ3RoKCk+MCkgewogICAgICAgICAgICAgICAgcndmaWxlLnNlZWsoMCk7CiAgICAgICAgICAgICAgICBpbnQgbnIgPSByd2ZpbGUucmVhZEludCgpOwogICAgICAgICAgICAgICAgc2VydmVyUG9ydCA9IHJ3ZmlsZS5yZWFkSW50KCk7CiAgICAgICAgICAgICAgICBzZXJ2ZXJDb29raWUgPSByd2ZpbGUucmVhZExvbmcoKTsKCiAgICAgICAgICAgICAgICBpZiAobnIgPT0gbWFnaWNOcikgewogICAgICAgICAgICAgICAgICAgIGNvbnRhaW5zUG9ydEluZm8gPSB0cnVlOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBjb250YWluc1BvcnRJbmZvID0gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIGNvbnRhaW5zUG9ydEluZm8gPSBmYWxzZTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBEaWQgdGhlIGxvY2tpbmcgYW5kIGdldFZhbHVlcyBzdWNjZWVkPwogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc1BvcnRJbmZvKCkgewogICAgICAgIHJldHVybiBjb250YWluc1BvcnRJbmZvOwogICAgfQoKICAgIC8qKgogICAgICogSWYgc28sIHRoZW4gd2UgY2FuIGFjcXVpcmUgdGhlIHRjcC9pcCBwb3J0IG9uIGxvY2FsaG9zdC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRQb3J0KCkgewogICAgICAgIEFzc2VydC5jaGVjayhjb250YWluc1BvcnRJbmZvKTsKICAgICAgICByZXR1cm4gc2VydmVyUG9ydDsKICAgIH0KCiAgICAvKioKICAgICAqIElmIHNvLCB0aGVuIHdlIGNhbiBhY3F1aXJlIHRoZSBzZXJ2ZXIgY29va2llLgogICAgICovCiAgICBwdWJsaWMgbG9uZyBnZXRDb29raWUoKSB7CiAgICAgICAgQXNzZXJ0LmNoZWNrKGNvbnRhaW5zUG9ydEluZm8pOwogICAgICAgIHJldHVybiBzZXJ2ZXJDb29raWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBTdG9yZSB0aGUgdmFsdWVzIGludG8gdGhlIGxvY2tlZCBwb3J0IGZpbGUuCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHNldFZhbHVlcyhpbnQgcG9ydCwgbG9uZyBjb29raWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgQXNzZXJ0LmNoZWNrKGxvY2sgIT0gbnVsbCk7CiAgICAgICAgcndmaWxlLnNlZWsoMCk7CiAgICAgICAgLy8gV3JpdGUgdGhlIG1hZ2ljIG5yIHRoYXQgaWRlbnRpZmVzIGEgcG9ydCBmaWxlLgogICAgICAgIHJ3ZmlsZS53cml0ZUludChtYWdpY05yKTsKICAgICAgICByd2ZpbGUud3JpdGVJbnQocG9ydCk7CiAgICAgICAgcndmaWxlLndyaXRlTG9uZyhjb29raWUpOwogICAgICAgIG15U2VydmVyUG9ydCA9IHBvcnQ7CiAgICAgICAgbXlTZXJ2ZXJDb29raWUgPSBjb29raWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBEZWxldGUgdGhlIHBvcnQgZmlsZS4KICAgICAqLwogICAgcHVibGljIHZvaWQgZGVsZXRlKCkgdGhyb3dzIElPRXhjZXB0aW9uLCBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CiAgICAgICAgLy8gQWNjZXNzIHRvIGZpbGUgbXVzdCBiZSBjbG9zZWQgYmVmb3JlIGRlbGV0aW5nLgogICAgICAgIHJ3ZmlsZS5jbG9zZSgpOwoKICAgICAgICBmaWxlLmRlbGV0ZSgpOwoKICAgICAgICAvLyBXYWl0IHVudGlsIGZpbGUgaGFzIGJlZW4gZGVsZXRlZCAoZGVsZXRlcyBhcmUgYXN5bmNocm9ub3VzIG9uIFdpbmRvd3MhKSBvdGhlcndpc2Ugd2UKICAgICAgICAvLyBtaWdodCBzaHV0ZG93biB0aGUgc2VydmVyIGFuZCBwcmV2ZW50IGFub3RoZXIgb25lIGZyb20gc3RhcnRpbmcuCiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMCAmJiBmaWxlLmV4aXN0cygpOyBpKyspIHsKICAgICAgICAgICAgVGhyZWFkLnNsZWVwKDEwMDApOwogICAgICAgIH0KICAgICAgICBpZiAoZmlsZS5leGlzdHMoKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkZhaWxlZCB0byBkZWxldGUgZmlsZS4iKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBJcyB0aGUgcG9ydCBmaWxlIHN0aWxsIHRoZXJlPwogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBleGlzdHMoKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBmaWxlLmV4aXN0cygpOwogICAgfQoKICAgIC8qKgogICAgICogSXMgYSBzdG9wIGZpbGUgdGhlcmU/CiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIG1hcmtlZEZvclN0b3AoKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgIGlmIChzdG9wRmlsZS5leGlzdHMoKSkgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgc3RvcEZpbGUuZGVsZXRlKCk7CiAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICAvKioKICAgICAqIFVubG9jayB0aGUgcG9ydCBmaWxlLgogICAgICovCiAgICBwdWJsaWMgdm9pZCB1bmxvY2soKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgIGlmIChsb2NrID09IG51bGwpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICBsb2NrLnJlbGVhc2UoKTsKICAgICAgICBsb2NrID0gbnVsbDsKICAgICAgICBsb2NrU2VtLnJlbGVhc2UoKTsKICAgIH0KCiAgICAvKioKICAgICAqIFdhaXQgZm9yIHRoZSBwb3J0IGZpbGUgdG8gY29udGFpbiB2YWx1ZXMgdGhhdCBsb29rIHZhbGlkLgogICAgICovCiAgICBwdWJsaWMgdm9pZCB3YWl0Rm9yVmFsaWRWYWx1ZXMoKSB0aHJvd3MgSU9FeGNlcHRpb24sIEludGVycnVwdGVkRXhjZXB0aW9uIHsKICAgICAgICBmaW5hbCBpbnQgTVNfQkVUV0VFTl9BVFRFTVBUUyA9IDUwMDsKICAgICAgICBsb25nIHN0YXJ0VGltZSA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOwogICAgICAgIGxvbmcgdGltZW91dCA9IHN0YXJ0VGltZSArIGdldFNlcnZlclN0YXJ0dXBUaW1lb3V0U2Vjb25kcygpICogMTAwMDsKICAgICAgICB3aGlsZSAodHJ1ZSkgewogICAgICAgICAgICBMb2cuZGVidWcoIkxvb2tpbmcgZm9yIHZhbGlkIHBvcnQgZmlsZSB2YWx1ZXMuLi4iKTsKICAgICAgICAgICAgaWYgKGV4aXN0cygpKSB7CiAgICAgICAgICAgICAgICBsb2NrKCk7CiAgICAgICAgICAgICAgICBnZXRWYWx1ZXMoKTsKICAgICAgICAgICAgICAgIHVubG9jaygpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChjb250YWluc1BvcnRJbmZvKSB7CiAgICAgICAgICAgICAgICBMb2cuZGVidWcoIlZhbGlkIHBvcnQgZmlsZSB2YWx1ZXMgZm91bmQgYWZ0ZXIgIiArIChTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSAtIHN0YXJ0VGltZSkgKyAiIG1zIik7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpID4gdGltZW91dCkgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgVGhyZWFkLnNsZWVwKE1TX0JFVFdFRU5fQVRURU1QVFMpOwogICAgICAgIH0KICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIk5vIHBvcnQgZmlsZSB2YWx1ZXMgbWF0ZXJpYWxpemVkLiBHaXZpbmcgdXAgYWZ0ZXIgIiArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpIC0gc3RhcnRUaW1lKSArICIgbXMiKTsKICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrIGlmIHRoZSBwb3J0ZmlsZSBzdGlsbCBjb250YWlucyBteSB2YWx1ZXMsIGFzc3VtaW5nIHRoYXQgSSBhbSB0aGUgc2VydmVyLgogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBzdGlsbE15VmFsdWVzKCkgdGhyb3dzIElPRXhjZXB0aW9uLCBGaWxlTm90Rm91bmRFeGNlcHRpb24sIEludGVycnVwdGVkRXhjZXB0aW9uIHsKICAgICAgICBmb3IgKDs7KSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBsb2NrKCk7CiAgICAgICAgICAgICAgICBnZXRWYWx1ZXMoKTsKICAgICAgICAgICAgICAgIHVubG9jaygpOwogICAgICAgICAgICAgICAgaWYgKGNvbnRhaW5zUG9ydEluZm8pIHsKICAgICAgICAgICAgICAgICAgICBpZiAoc2VydmVyUG9ydCA9PSBteVNlcnZlclBvcnQgJiYKICAgICAgICAgICAgICAgICAgICAgICAgc2VydmVyQ29va2llID09IG15U2VydmVyQ29va2llKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEV2ZXJ5dGhpbmcgaXMgb2suCiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAvLyBTb21lb25lIGhhcyBvdmVyd3JpdHRlbiB0aGUgcG9ydCBmaWxlLgogICAgICAgICAgICAgICAgICAgIC8vIFByb2JhYmx5IGFub3RoZXIgamF2YWMgc2VydmVyLCBsZXRzIHF1aXQuCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgLy8gU29tZXRoaW5nIGVsc2UgaXMgd3Jvbmcgd2l0aCB0aGUgcG9ydGZpbGUuIExldHMgcXVpdC4KICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfSBjYXRjaCAoRmlsZUxvY2tJbnRlcnJ1cHRpb25FeGNlcHRpb24gZSkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY2F0Y2ggKENsb3NlZENoYW5uZWxFeGNlcHRpb24gZSkgewogICAgICAgICAgICAgICAgLy8gVGhlIGNoYW5uZWwgaGFzIGJlZW4gY2xvc2VkIHNpbmNlIHNqYXZhYyBpcyBleGl0aW5nLgogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJuIHRoZSBuYW1lIG9mIHRoZSBwb3J0IGZpbGUuCiAgICAgKi8KICAgIHB1YmxpYyBTdHJpbmcgZ2V0RmlsZW5hbWUoKSB7CiAgICAgICAgcmV0dXJuIGZpbGVuYW1lOwogICAgfQoKICAgIHByaXZhdGUgbG9uZyBnZXRTZXJ2ZXJTdGFydHVwVGltZW91dFNlY29uZHMoKSB7CiAgICAgICAgU3RyaW5nIHN0ciA9IFN5c3RlbS5nZXRQcm9wZXJ0eSgic2VydmVyU3RhcnR1cFRpbWVvdXQiKTsKICAgICAgICBpZiAoc3RyICE9IG51bGwpIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIHJldHVybiBJbnRlZ2VyLnBhcnNlSW50KHN0cik7CiAgICAgICAgICAgIH0gY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIDYwOwogICAgfQp9ClBLAwQKAAAIAAAGO6lKzAhkDQYGAAAGBgAAKwAAAGNvbS9zdW4vdG9vbHMvc2phdmFjL3NlcnZlci9UZXJtaW5hYmxlLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTQsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5zamF2YWMuc2VydmVyOwoKLyoqCiAqICA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiAgSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93biByaXNrLgogKiAgVGhpcyBjb2RlIGFuZCBpdHMgaW50ZXJuYWwgaW50ZXJmYWNlcyBhcmUgc3ViamVjdCB0byBjaGFuZ2Ugb3IKICogIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj4KICovCnB1YmxpYyBpbnRlcmZhY2UgVGVybWluYWJsZSB7CiAgICB2b2lkIHNodXRkb3duKFN0cmluZyBxdWl0TXNnKTsKfQpQSwMECgAACAAABjupSra279rHBgAAxwYAACcAAABjb20vc3VuL3Rvb2xzL3NqYXZhYy9zZXJ2ZXIvU2phdmFjLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTQsIDIwMTYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5zamF2YWMuc2VydmVyOwoKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMubWFpbi5NYWluLlJlc3VsdDsKCmltcG9ydCBqYXZhLmlvLldyaXRlcjsKCgovKioKICogSW50ZXJmYWNlIG9mIHRoZSBTamF2YWNJbXBsLCB0aGUgc2phdmFjIGNsaWVudCBhbmQgYWxsIHdyYXBwZXJzIHN1Y2ggYXMKICogUG9vbGVkU2phdmFjIGV0Yy4KICoKICogIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqICBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqICBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogKiAgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPgogKi8KcHVibGljIGludGVyZmFjZSBTamF2YWMgewogICAgUmVzdWx0IGNvbXBpbGUoU3RyaW5nW10gYXJncyk7CiAgICB2b2lkIHNodXRkb3duKCk7Cn0KUEsDBAoAAAgAANJ9TUofaZDOMggAADIIAAAoAAAAY29tL3N1bi90b29scy9zamF2YWMvc2VydmVyL1N5c0luZm8uamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAxMiwgMjAxNCwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKLyoqCiAqIEEgdXRpbGl0eSBjbGFzcyB1c2VkIHRvIHJlcG9ydCBpbmZvcm1hdGlvbiBhYm91dCB0aGUgc3lzdGVtCiAqIHdoZXJlIHRoZSBqYXZhYyBzZXJ2ZXIgaXMgcnVubmluZy4KICoKICogPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93bgogKiByaXNrLiAgVGhpcyBjb2RlIGFuZCBpdHMgaW50ZXJuYWwgaW50ZXJmYWNlcyBhcmUgc3ViamVjdCB0byBjaGFuZ2UKICogb3IgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPjwvcD4KICovCnBhY2thZ2UgY29tLnN1bi50b29scy5zamF2YWMuc2VydmVyOwoKaW1wb3J0IGphdmEuaW8uU2VyaWFsaXphYmxlOwoKLyoqCiAqICA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiAgSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93biByaXNrLgogKiAgVGhpcyBjb2RlIGFuZCBpdHMgaW50ZXJuYWwgaW50ZXJmYWNlcyBhcmUgc3ViamVjdCB0byBjaGFuZ2Ugb3IKICogIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj4KICovCnB1YmxpYyBjbGFzcyBTeXNJbmZvIGltcGxlbWVudHMgU2VyaWFsaXphYmxlIHsKCiAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTMwOTYzNDY4MDc1NzlMOwoKICAgIHB1YmxpYyBpbnQgbnVtQ29yZXM7CiAgICBwdWJsaWMgbG9uZyBtYXhNZW1vcnk7CgogICAgcHVibGljIFN5c0luZm8oaW50IG5jLCBsb25nIG1tKSB7CiAgICAgICAgbnVtQ29yZXMgPSBuYzsKICAgICAgICBtYXhNZW1vcnkgPSBtbTsKICAgIH0KfQpQSwMECgAACAAABjupSr7q7vROIwAATiMAAC0AAABjb20vc3VuL3Rvb2xzL3NqYXZhYy9zZXJ2ZXIvU2phdmFjU2VydmVyLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTEsIDIwMTYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5zamF2YWMuc2VydmVyOwoKaW1wb3J0IGphdmEuaW8uRmlsZU5vdEZvdW5kRXhjZXB0aW9uOwppbXBvcnQgamF2YS5pby5GaWxlV3JpdGVyOwppbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKaW1wb3J0IGphdmEuaW8uUHJpbnRTdHJlYW07CmltcG9ydCBqYXZhLmlvLlByaW50V3JpdGVyOwppbXBvcnQgamF2YS5uZXQuSW5ldEFkZHJlc3M7CmltcG9ydCBqYXZhLm5ldC5JbmV0U29ja2V0QWRkcmVzczsKaW1wb3J0IGphdmEubmV0LlNlcnZlclNvY2tldDsKaW1wb3J0IGphdmEubmV0LlNvY2tldDsKaW1wb3J0IGphdmEubmV0LlNvY2tldEV4Y2VwdGlvbjsKaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOwppbXBvcnQgamF2YS51dGlsLk1hcDsKaW1wb3J0IGphdmEudXRpbC5SYW5kb207CmltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5hdG9taWMuQXRvbWljQm9vbGVhbjsKCmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLm1haW4uTWFpbjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMubWFpbi5NYWluLlJlc3VsdDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuc2phdmFjLkxvZzsKaW1wb3J0IGNvbS5zdW4udG9vbHMuc2phdmFjLlV0aWw7CmltcG9ydCBjb20uc3VuLnRvb2xzLnNqYXZhYy5jbGllbnQuUG9ydEZpbGVJbmFjY2Vzc2libGVFeGNlcHRpb247CmltcG9ydCBjb20uc3VuLnRvb2xzLnNqYXZhYy5jb21wLlBvb2xlZFNqYXZhYzsKaW1wb3J0IGNvbS5zdW4udG9vbHMuc2phdmFjLmNvbXAuU2phdmFjSW1wbDsKCi8qKgogKiBUaGUgSmF2YWNTZXJ2ZXIgY2xhc3MgY29udGFpbnMgbWV0aG9kcyBib3RoIHRvIHNldHVwIGEgc2VydmVyIHRoYXQgcmVzcG9uZHMgdG8gcmVxdWVzdHMgYW5kIG1ldGhvZHMgdG8gY29ubmVjdCB0byB0aGlzIHNlcnZlci4KICoKICogIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqICBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqICBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogKiAgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPgogKi8KcHVibGljIGNsYXNzIFNqYXZhY1NlcnZlciBpbXBsZW1lbnRzIFRlcm1pbmFibGUgewoKICAgIC8vIFByZWZpeCBvZiBsaW5lIGNvbnRhaW5pbmcgcmV0dXJuIGNvZGUuCiAgICBwdWJsaWMgZmluYWwgc3RhdGljIFN0cmluZyBMSU5FX1RZUEVfUkMgPSAiUkMiOwoKICAgIGZpbmFsIHByaXZhdGUgU3RyaW5nIHBvcnRmaWxlbmFtZTsKICAgIGZpbmFsIHByaXZhdGUgaW50IHBvb2xzaXplOwogICAgZmluYWwgcHJpdmF0ZSBpbnQga2VlcGFsaXZlOwoKICAgIC8vIFRoZSBzZWNyZXQgY29va2llIHNoYXJlZCBiZXR3ZWVuIHNlcnZlciBhbmQgY2xpZW50IHRocm91Z2ggdGhlIHBvcnQgZmlsZS4KICAgIC8vIFVzZWQgdG8gcHJldmVudCBjbGllbnRzIGZyb20gYmVsaWV2aW5nIHRoYXQgdGhleSBhcmUgY29tbXVuaWNhdGluZyB3aXRoCiAgICAvLyBhbiBvbGQgc2VydmVyIHdoZW4gYSBuZXcgc2VydmVyIGhhcyBzdGFydGVkIGFuZCByZXVzZWQgdGhlIHNhbWUgcG9ydCBhcwogICAgLy8gYW4gb2xkIHNlcnZlci4KICAgIHByaXZhdGUgZmluYWwgbG9uZyBteUNvb2tpZTsKCiAgICAvLyBBY2N1bXVsYXRlZCBidWlsZCB0aW1lLCBub3QgY291bnRpbmcgaWRsZSB0aW1lLCB1c2VkIGZvciBsb2dnaW5nIHB1cnBvc2VzCiAgICBwcml2YXRlIGxvbmcgdG90YWxCdWlsZFRpbWU7CgogICAgLy8gVGhlIHNqYXZhYyBpbXBsZW1lbnRhdGlvbiB0byBkZWxlZ2F0ZSByZXF1ZXN0cyB0bwogICAgU2phdmFjIHNqYXZhYzsKCiAgICBwcml2YXRlIFNlcnZlclNvY2tldCBzZXJ2ZXJTb2NrZXQ7CgogICAgcHJpdmF0ZSBQb3J0RmlsZSBwb3J0RmlsZTsKICAgIHByaXZhdGUgUG9ydEZpbGVNb25pdG9yIHBvcnRGaWxlTW9uaXRvcjsKCiAgICAvLyBTZXQgdG8gZmFsc2UgYnJlYWsgYWNjZXB0IGxvb3AKICAgIGZpbmFsIEF0b21pY0Jvb2xlYW4ga2VlcEFjY2VwdGluZ1JlcXVlc3RzID0gbmV3IEF0b21pY0Jvb2xlYW4oKTsKCiAgICAvLyBGb3IgdGhlIGNsaWVudCwgYWxsIHBvcnQgZmlsZXMgZmV0Y2hlZCwgb25lIHBlciBzdGFydGVkIGphdmFjIHNlcnZlci4KICAgIC8vIFRob3VnaCB1c3VhbGx5IG9ubHkgb25lIGphdmFjIHNlcnZlciBpcyBzdGFydGVkIGJ5IGEgY2xpZW50LgogICAgcHJpdmF0ZSBzdGF0aWMgTWFwPFN0cmluZywgUG9ydEZpbGU+IGFsbFBvcnRGaWxlczsKCiAgICBwdWJsaWMgU2phdmFjU2VydmVyKFN0cmluZyBzZXR0aW5ncykgdGhyb3dzIEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiB7CiAgICAgICAgdGhpcyhVdGlsLmV4dHJhY3RTdHJpbmdPcHRpb24oInBvcnRmaWxlIiwgc2V0dGluZ3MpLAogICAgICAgICAgICAgVXRpbC5leHRyYWN0SW50T3B0aW9uKCJwb29sc2l6ZSIsIHNldHRpbmdzLCBSdW50aW1lLmdldFJ1bnRpbWUoKS5hdmFpbGFibGVQcm9jZXNzb3JzKCkpLAogICAgICAgICAgICAgVXRpbC5leHRyYWN0SW50T3B0aW9uKCJrZWVwYWxpdmUiLCBzZXR0aW5ncywgMTIwKSk7CiAgICB9CgogICAgcHVibGljIFNqYXZhY1NlcnZlcihTdHJpbmcgcG9ydGZpbGVuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICBpbnQgcG9vbHNpemUsCiAgICAgICAgICAgICAgICAgICAgICAgIGludCBrZWVwYWxpdmUpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiB7CiAgICAgICAgdGhpcy5wb3J0ZmlsZW5hbWUgPSBwb3J0ZmlsZW5hbWU7CiAgICAgICAgdGhpcy5wb29sc2l6ZSA9IHBvb2xzaXplOwogICAgICAgIHRoaXMua2VlcGFsaXZlID0ga2VlcGFsaXZlOwogICAgICAgIHRoaXMubXlDb29raWUgPSBuZXcgUmFuZG9tKCkubmV4dExvbmcoKTsKICAgIH0KCgogICAgLyoqCiAgICAgKiBBY3F1aXJlIHRoZSBwb3J0IGZpbGUuIFN5bmNocm9uaXplZCBzaW5jZSBzZXZlcmFsIHRocmVhZHMgaW5zaWRlIGFuIHNtYXJ0IGphdmFjIHdyYXBwZXIgY2xpZW50IGFjcXVpcmVzIHRoZSBzYW1lIHBvcnQgZmlsZSBhdCB0aGUgc2FtZSB0aW1lLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIHN5bmNocm9uaXplZCBQb3J0RmlsZSBnZXRQb3J0RmlsZShTdHJpbmcgZmlsZW5hbWUpIHsKICAgICAgICBpZiAoYWxsUG9ydEZpbGVzID09IG51bGwpIHsKICAgICAgICAgICAgYWxsUG9ydEZpbGVzID0gbmV3IEhhc2hNYXA8PigpOwogICAgICAgIH0KICAgICAgICBQb3J0RmlsZSBwZiA9IGFsbFBvcnRGaWxlcy5nZXQoZmlsZW5hbWUpOwoKICAgICAgICAvLyBQb3J0IGZpbGUga25vd24uIERvZXMgaXQgc3RpbGwgZXhpc3Q/CiAgICAgICAgaWYgKHBmICE9IG51bGwpIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIGlmICghcGYuZXhpc3RzKCkpCiAgICAgICAgICAgICAgICAgICAgcGYgPSBudWxsOwogICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBpb2V4KSB7CiAgICAgICAgICAgICAgICBpb2V4LnByaW50U3RhY2tUcmFjZSgpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAocGYgPT0gbnVsbCkgewogICAgICAgICAgICBwZiA9IG5ldyBQb3J0RmlsZShmaWxlbmFtZSk7CiAgICAgICAgICAgIGFsbFBvcnRGaWxlcy5wdXQoZmlsZW5hbWUsIHBmKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHBmOwogICAgfQoKICAgIC8qKgogICAgICogR2V0IHRoZSBjb29raWUgdXNlZCBmb3IgdGhpcyBzZXJ2ZXIuCiAgICAgKi8KICAgIGxvbmcgZ2V0Q29va2llKCkgewogICAgICAgIHJldHVybiBteUNvb2tpZTsKICAgIH0KCiAgICAvKioKICAgICAqIEdldCB0aGUgcG9ydCB1c2VkIGZvciB0aGlzIHNlcnZlci4KICAgICAqLwogICAgaW50IGdldFBvcnQoKSB7CiAgICAgICAgcmV0dXJuIHNlcnZlclNvY2tldC5nZXRMb2NhbFBvcnQoKTsKICAgIH0KCiAgICAvKioKICAgICAqIFN1bSB1cCB0aGUgdG90YWwgYnVpbGQgdGltZSBmb3IgdGhpcyBqYXZhYyBzZXJ2ZXIuCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIGFkZEJ1aWxkVGltZShsb25nIGluYykgewogICAgICAgIHRvdGFsQnVpbGRUaW1lICs9IGluYzsKICAgIH0KCiAgICAvKioKICAgICAqIFN0YXJ0IGEgc2VydmVyIHVzaW5nIGEgc2V0dGluZ3Mgc3RyaW5nLiBUeXBpY2FsbHk6ICItLXN0YXJ0c2VydmVyOnBvcnRmaWxlPS90bXAvbXlzZXJ2ZXIscG9vbHNpemU9MyIgYW5kIHRoZSBzdHJpbmcgInBvcnRmaWxlPS90bXAvbXlzZXJ2ZXIscG9vbHNpemU9MyIKICAgICAqIGlzIHNlbnQgYXMgdGhlIHNldHRpbmdzIHBhcmFtZXRlci4gUmV0dXJucyAwIG9uIHN1Y2Nlc3MsIC0xIG9uIGZhaWx1cmUuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgc3RhcnRTZXJ2ZXIoKSB0aHJvd3MgSU9FeGNlcHRpb24sIEludGVycnVwdGVkRXhjZXB0aW9uIHsKICAgICAgICBsb25nIHNlcnZlclN0YXJ0ID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CgogICAgICAgIC8vIFRoZSBwb3J0IGZpbGUgaXMgbG9ja2VkIGFuZCB0aGUgc2VydmVyIHBvcnQgYW5kIGNvb2tpZSBpcyB3cml0dGVuIGludG8gaXQuCiAgICAgICAgcG9ydEZpbGUgPSBnZXRQb3J0RmlsZShwb3J0ZmlsZW5hbWUpOwoKICAgICAgICBzeW5jaHJvbml6ZWQgKHBvcnRGaWxlKSB7CiAgICAgICAgICAgIHBvcnRGaWxlLmxvY2soKTsKICAgICAgICAgICAgcG9ydEZpbGUuZ2V0VmFsdWVzKCk7CiAgICAgICAgICAgIGlmIChwb3J0RmlsZS5jb250YWluc1BvcnRJbmZvKCkpIHsKICAgICAgICAgICAgICAgIExvZy5kZWJ1ZygiSmF2YWMgc2VydmVyIG5vdCBzdGFydGVkIGJlY2F1c2UgcG9ydGZpbGUgZXhpc3RzISIpOwogICAgICAgICAgICAgICAgcG9ydEZpbGUudW5sb2NrKCk7CiAgICAgICAgICAgICAgICByZXR1cm4gUmVzdWx0LkVSUk9SLmV4aXRDb2RlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyAgICAgICAgICAgLi0tLS0tLS0tLS0tLiAgIC4tLS0tLS0tLS4gICAuLS0tLS0tLgogICAgICAgICAgICAvLyBzb2NrZXQgLS0+fCBJZGxlUmVzZXQgfC0tPnwgUG9vbGVkIHwtLT58IEltcGwgfC0tPiBqYXZhYwogICAgICAgICAgICAvLyAgICAgICAgICAgJy0tLS0tLS0tLS0tJyAgICctLS0tLS0tLScgICAnLS0tLS0tJwogICAgICAgICAgICBzamF2YWMgPSBuZXcgU2phdmFjSW1wbCgpOwogICAgICAgICAgICBzamF2YWMgPSBuZXcgUG9vbGVkU2phdmFjKHNqYXZhYywgcG9vbHNpemUpOwogICAgICAgICAgICBzamF2YWMgPSBuZXcgSWRsZVJlc2V0U2phdmFjKHNqYXZhYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtlZXBhbGl2ZSAqIDEwMDApOwoKICAgICAgICAgICAgc2VydmVyU29ja2V0ID0gbmV3IFNlcnZlclNvY2tldCgpOwogICAgICAgICAgICBJbmV0QWRkcmVzcyBsb2NhbGhvc3QgPSBJbmV0QWRkcmVzcy5nZXRCeU5hbWUobnVsbCk7CiAgICAgICAgICAgIHNlcnZlclNvY2tldC5iaW5kKG5ldyBJbmV0U29ja2V0QWRkcmVzcyhsb2NhbGhvc3QsIDApKTsKCiAgICAgICAgICAgIC8vIEF0IHRoaXMgcG9pbnQgdGhlIHNlcnZlciBhY2NlcHRzIGNvbm5lY3Rpb25zLCBzbyBpdCBpcyAgbm93IHNhZmUKICAgICAgICAgICAgLy8gdG8gcHVibGlzaCB0aGUgcG9ydCAvIGNvb2tpZSBpbmZvcm1hdGlvbgogICAgICAgICAgICBwb3J0RmlsZS5zZXRWYWx1ZXMoZ2V0UG9ydCgpLCBnZXRDb29raWUoKSk7CiAgICAgICAgICAgIHBvcnRGaWxlLnVubG9jaygpOwogICAgICAgIH0KCiAgICAgICAgcG9ydEZpbGVNb25pdG9yID0gbmV3IFBvcnRGaWxlTW9uaXRvcihwb3J0RmlsZSwgdGhpcyk7CiAgICAgICAgcG9ydEZpbGVNb25pdG9yLnN0YXJ0KCk7CgogICAgICAgIExvZy5kZWJ1ZygiU2phdmFjIHNlcnZlciBzdGFydGVkLiBBY2NlcHRpbmcgY29ubmVjdGlvbnMuLi4iKTsKICAgICAgICBMb2cuZGVidWcoIiAgICBwb3J0OiAiICsgZ2V0UG9ydCgpKTsKICAgICAgICBMb2cuZGVidWcoIiAgICB0aW1lOiAiICsgbmV3IGphdmEudXRpbC5EYXRlKCkpOwogICAgICAgIExvZy5kZWJ1ZygiICAgIHBvb2xzaXplOiAiICsgcG9vbHNpemUpOwoKCiAgICAgICAga2VlcEFjY2VwdGluZ1JlcXVlc3RzLnNldCh0cnVlKTsKICAgICAgICBkbyB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBTb2NrZXQgc29ja2V0ID0gc2VydmVyU29ja2V0LmFjY2VwdCgpOwogICAgICAgICAgICAgICAgbmV3IFJlcXVlc3RIYW5kbGVyKHNvY2tldCwgc2phdmFjKS5zdGFydCgpOwogICAgICAgICAgICB9IGNhdGNoIChTb2NrZXRFeGNlcHRpb24gc2UpIHsKICAgICAgICAgICAgICAgIC8vIENhdXNlZCBieSBzZXJ2ZXJTb2NrZXQuY2xvc2UoKSBhbmQgaW5kaWNhdGVzIHNodXRkb3duCiAgICAgICAgICAgIH0KICAgICAgICB9IHdoaWxlIChrZWVwQWNjZXB0aW5nUmVxdWVzdHMuZ2V0KCkpOwoKICAgICAgICBMb2cuZGVidWcoIlNodXR0aW5nIGRvd24uIik7CgogICAgICAgIC8vIE5vIG1vcmUgY29ubmVjdGlvbnMgYWNjZXB0ZWQuIElmIGFueSBjbGllbnQgbWFuYWdlZCB0byBjb25uZWN0IGFmdGVyCiAgICAgICAgLy8gdGhlIGFjY2VwdCgpIHdhcyBpbnRlcnJ1cHRlZCBidXQgYmVmb3JlIHRoZSBzZXJ2ZXIgc29ja2V0IGlzIGNsb3NlZAogICAgICAgIC8vIGhlcmUsIGFueSBhdHRlbXB0IHRvIHJlYWQgb3Igd3JpdGUgdG8gdGhlIHNvY2tldCB3aWxsIHJlc3VsdCBpbiBhbgogICAgICAgIC8vIElPRXhjZXB0aW9uIG9uIHRoZSBjbGllbnQgc2lkZS4KCiAgICAgICAgbG9uZyByZWFsVGltZSA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpIC0gc2VydmVyU3RhcnQ7CiAgICAgICAgTG9nLmRlYnVnKCJUb3RhbCB3YWxsIGNsb2NrIHRpbWUgIiArIHJlYWxUaW1lICsgIm1zIGJ1aWxkIHRpbWUgIiArIHRvdGFsQnVpbGRUaW1lICsgIm1zIik7CgogICAgICAgIC8vIFNodXQgZG93bgogICAgICAgIHNqYXZhYy5zaHV0ZG93bigpOwoKICAgICAgICByZXR1cm4gUmVzdWx0Lk9LLmV4aXRDb2RlOwogICAgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIHZvaWQgc2h1dGRvd24oU3RyaW5nIHF1aXRNc2cpIHsKICAgICAgICBpZiAoIWtlZXBBY2NlcHRpbmdSZXF1ZXN0cy5jb21wYXJlQW5kU2V0KHRydWUsIGZhbHNlKSkgewogICAgICAgICAgICAvLyBBbHJlYWR5IHN0b3BwZWQsIG5vIG5lZWQgdG8gc2h1dCBkb3duIGFnYWluCiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIExvZy5kZWJ1ZygiUXVpdHRpbmc6ICIgKyBxdWl0TXNnKTsKCiAgICAgICAgcG9ydEZpbGVNb25pdG9yLnNodXRkb3duKCk7IC8vIE5vIGxvbmdlciBhbnkgbmVlZCB0byBtb25pdG9yIHBvcnQgZmlsZQoKICAgICAgICAvLyBVbnB1Ymxpc2ggcG9ydCBiZWZvcmUgc2h1dHRpbmcgZG93biBzb2NrZXQgdG8gbWluaW1pemUgdGhlIG51bWJlciBvZgogICAgICAgIC8vIGZhaWxlZCBjb25uZWN0aW9uIGF0dGVtcHRzCiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgcG9ydEZpbGUuZGVsZXRlKCk7CiAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gfCBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIExvZy5lcnJvcihlKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgc2VydmVyU29ja2V0LmNsb3NlKCk7CiAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICBMb2cuZXJyb3IoZSk7CiAgICAgICAgfQogICAgfQp9ClBLAwQKAAAIAAAGO6lKDlJhsGAPAABgDwAAMAAAAGNvbS9zdW4vdG9vbHMvc2phdmFjL3NlcnZlci9Qb3J0RmlsZU1vbml0b3IuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAxNCwgMjAxNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLnNqYXZhYy5zZXJ2ZXI7CgppbXBvcnQgY29tLnN1bi50b29scy5zamF2YWMuTG9nOwoKaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CmltcG9ydCBqYXZhLnV0aWwuVGltZXI7CmltcG9ydCBqYXZhLnV0aWwuVGltZXJUYXNrOwoKLyoqCiAqIE1vbml0b3JzIHRoZSBwcmVzZW5jZSBvZiBhIHBvcnQgZmlsZSBhbmQgc2h1dHMgZG93biB0aGUgZ2l2ZW4gU2phdmFjU2VydmVyCiAqIHdoZW5ldmVyIHRoZSBwb3J0IGZpbGUgaXMgZGVsZXRlZCBvciBpbnZhbGlkYXRlZC4KICoKICogVE9ETzogSkRLLTgwNDY4ODIKICoKICogIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqICBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqICBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogKiAgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPgogKi8KcHVibGljIGNsYXNzIFBvcnRGaWxlTW9uaXRvciB7CgogICAgLy8gQ2hlY2sgaWYgdGhlIHBvcnRmaWxlIGlzIGdvbmUsIGV2ZXJ5IDUgc2Vjb25kcy4KICAgIHByaXZhdGUgZmluYWwgc3RhdGljIGludCBDSEVDS19QT1JURklMRV9JTlRFUlZBTCA9IDUwMDA7CgogICAgZmluYWwgcHJpdmF0ZSBUaW1lciB0aW1lciA9IG5ldyBUaW1lcigpOwogICAgZmluYWwgcHJpdmF0ZSBQb3J0RmlsZSBwb3J0RmlsZTsKICAgIGZpbmFsIHByaXZhdGUgU2phdmFjU2VydmVyIHNlcnZlcjsKCiAgICBwdWJsaWMgUG9ydEZpbGVNb25pdG9yKFBvcnRGaWxlIHBvcnRGaWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICBTamF2YWNTZXJ2ZXIgc2VydmVyKSB7CiAgICAgICAgdGhpcy5wb3J0RmlsZSA9IHBvcnRGaWxlOwogICAgICAgIHRoaXMuc2VydmVyID0gc2VydmVyOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHN0YXJ0KCkgewogICAgICAgIExvZyBsb2cgPSBMb2cuZ2V0KCk7CiAgICAgICAgVGltZXJUYXNrIHNodXRkb3duQ2hlY2sgPSBuZXcgVGltZXJUYXNrKCkgewogICAgICAgICAgICBwdWJsaWMgdm9pZCBydW4oKSB7CiAgICAgICAgICAgICAgICBMb2cuc2V0TG9nRm9yQ3VycmVudFRocmVhZChsb2cpOwogICAgICAgICAgICAgICAgTG9nLmRlYnVnKCJDaGVja2luZyBwb3J0IGZpbGUgc3RhdHVzLi4uIik7CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIGlmICghcG9ydEZpbGUuZXhpc3RzKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gVGltZSB0byBxdWl0IGJlY2F1c2UgdGhlIHBvcnRmaWxlIHdhcyBkZWxldGVkIGJ5IGFub3RoZXIKICAgICAgICAgICAgICAgICAgICAgICAgLy8gcHJvY2VzcywgcHJvYmFibHkgYnkgdGhlIG1ha2VmaWxlIHRoYXQgaXMgZG9uZSBidWlsZGluZy4KICAgICAgICAgICAgICAgICAgICAgICAgc2VydmVyLnNodXRkb3duKCJRdWl0dGluZyBiZWNhdXNlIHBvcnRmaWxlIHdhcyBkZWxldGVkISIpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocG9ydEZpbGUubWFya2VkRm9yU3RvcCgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRpbWUgdG8gcXVpdCBiZWNhdXNlIGFub3RoZXIgcHJvY2VzcyB0b3VjaGVkIHRoZSBmaWxlCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNlcnZlci5wb3J0LnN0b3AgdG8gc2lnbmFsIHRoYXQgdGhlIHNlcnZlciBzaG91bGQgc3RvcC4KICAgICAgICAgICAgICAgICAgICAgICAgLy8gVGhpcyBpcyBuZWNlc3Nhcnkgb24gc29tZSBvcGVyYXRpbmcgc3lzdGVtcyB0aGF0IGxvY2sKICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhlIHBvcnQgZmlsZSBoYXJkIQogICAgICAgICAgICAgICAgICAgICAgICBzZXJ2ZXIuc2h1dGRvd24oIlF1aXR0aW5nIGJlY2F1c2UgYSBwb3J0ZmlsZS5zdG9wIGZpbGUgd2FzIGZvdW5kISIpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoIXBvcnRGaWxlLnN0aWxsTXlWYWx1ZXMoKSkgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBUaW1lIHRvIHF1aXQgYmVjYXVzZSBhbm90aGVyIGJ1aWxkIGhhcyBzdGFydGVkLgogICAgICAgICAgICAgICAgICAgICAgICBzZXJ2ZXIuc2h1dGRvd24oIlF1aXR0aW5nIGJlY2F1c2UgcG9ydGZpbGUgaXMgbm93IG93bmVkIGJ5IGFub3RoZXIgamF2YWMgc2VydmVyISIpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgICAgICAgICBMb2cuZXJyb3IoIklPRXhjZXB0aW9uIGNhdWdodCBpbiBQb3J0RmlsZU1vbml0b3IuIik7CiAgICAgICAgICAgICAgICAgICAgTG9nLmRlYnVnKGUpOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgewogICAgICAgICAgICAgICAgICAgIFRocmVhZC5jdXJyZW50VGhyZWFkKCkuaW50ZXJydXB0KCk7CiAgICAgICAgICAgICAgICAgICAgTG9nLmVycm9yKGUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfTsKCiAgICAgICAgdGltZXIuc2NoZWR1bGUoc2h1dGRvd25DaGVjaywgMCwgQ0hFQ0tfUE9SVEZJTEVfSU5URVJWQUwpOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHNodXRkb3duKCkgewogICAgICAgIHRpbWVyLmNhbmNlbCgpOwogICAgfQp9ClBLAwQKAAAIAAAGO6lKnU3mb4EPAACBDwAAMAAAAGNvbS9zdW4vdG9vbHMvc2phdmFjL3NlcnZlci9JZGxlUmVzZXRTamF2YWMuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAxNCwgMjAxNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLnNqYXZhYy5zZXJ2ZXI7CgppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5tYWluLk1haW4uUmVzdWx0OwppbXBvcnQgY29tLnN1bi50b29scy5zamF2YWMuTG9nOwoKaW1wb3J0IGphdmEudXRpbC5UaW1lcjsKaW1wb3J0IGphdmEudXRpbC5UaW1lclRhc2s7CgovKioKICogQW4gc2phdmFjIGltcGxlbWVudGF0aW9uIHRoYXQga2VlcHMgdHJhY2sgb2YgaWRsZW5lc3MgYW5kIHNodXRzIGRvd24gdGhlCiAqIGdpdmVuIFRlcm1pbmFibGUgdXBvbiBpZGxlbmVzcyB0aW1lb3V0LgogKgogKiBBbiBpZGxlbmVzcyB0aW1lb3V0IGtpY2tzIGluIHtAY29kZSBpZGxlVGltZW91dH0gbWlsbGlzZWNvbmRzIGFmdGVyIHRoZSBsYXN0CiAqIHJlcXVlc3QgaXMgY29tcGxldGVkLgogKgogKiAgPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24gcmlzay4KICogIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yCiAqICBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+CiAqLwpwdWJsaWMgY2xhc3MgSWRsZVJlc2V0U2phdmFjIGltcGxlbWVudHMgU2phdmFjIHsKCiAgICBwcml2YXRlIGZpbmFsIFNqYXZhYyBkZWxlZ2F0ZTsKICAgIHByaXZhdGUgZmluYWwgVGVybWluYWJsZSB0b1NodXRkb3duOwogICAgcHJpdmF0ZSBmaW5hbCBUaW1lciBpZGxlbmVzc1RpbWVyID0gbmV3IFRpbWVyKCk7CiAgICBwcml2YXRlIGZpbmFsIGxvbmcgaWRsZVRpbWVvdXQ7CiAgICBwcml2YXRlIGludCBvdXRzdGFuZGluZ0NhbGxzID0gMDsKCiAgICAvLyBDbGFzcyBpbnZhcmlhbnQ6IGlkbGVuZXNzVGltZXJUYXNrICE9IG51bGwgPC0+IGlkbGVuZXNzVGltZXJUYXNrIGlzIHNjaGVkdWxlZAogICAgcHJpdmF0ZSBUaW1lclRhc2sgaWRsZW5lc3NUaW1lclRhc2s7CgogICAgcHVibGljIElkbGVSZXNldFNqYXZhYyhTamF2YWMgZGVsZWdhdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFRlcm1pbmFibGUgdG9TaHV0ZG93biwKICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9uZyBpZGxlVGltZW91dCkgewogICAgICAgIHRoaXMuZGVsZWdhdGUgPSBkZWxlZ2F0ZTsKICAgICAgICB0aGlzLnRvU2h1dGRvd24gPSB0b1NodXRkb3duOwogICAgICAgIHRoaXMuaWRsZVRpbWVvdXQgPSBpZGxlVGltZW91dDsKICAgICAgICBzY2hlZHVsZVRpbWVvdXQoKTsKICAgIH0KCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSZXN1bHQgY29tcGlsZShTdHJpbmdbXSBhcmdzKSB7CiAgICAgICAgc3RhcnRDYWxsKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgcmV0dXJuIGRlbGVnYXRlLmNvbXBpbGUoYXJncyk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgZW5kQ2FsbCgpOwogICAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIHN5bmNocm9uaXplZCB2b2lkIHN0YXJ0Q2FsbCgpIHsKICAgICAgICAvLyBXYXMgdGhlcmUgbm8gb3V0c3RhbmRpbmcgY2FsbHMgYmVmb3JlIHRoaXMgY2FsbD8KICAgICAgICBpZiAoKytvdXRzdGFuZGluZ0NhbGxzID09IDEpIHsKICAgICAgICAgICAgLy8gVGhlbiB0aGUgdGltZXIgdGFzayBtdXN0IGhhdmUgYmVlbiBzY2hlZHVsZWQKICAgICAgICAgICAgaWYgKGlkbGVuZXNzVGltZXJUYXNrID09IG51bGwpCiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJJZGxlIHRpbWVvdXQgYWxyZWFkeSBjYW5jZWxsZWQiKTsKICAgICAgICAgICAgLy8gQ2FuY2VsIHRpbWVvdXQgdGFzawogICAgICAgICAgICBpZGxlbmVzc1RpbWVyVGFzay5jYW5jZWwoKTsKICAgICAgICAgICAgaWRsZW5lc3NUaW1lclRhc2sgPSBudWxsOwogICAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIHN5bmNocm9uaXplZCB2b2lkIGVuZENhbGwoKSB7CiAgICAgICAgaWYgKC0tb3V0c3RhbmRpbmdDYWxscyA9PSAwKSB7CiAgICAgICAgICAgIC8vIE5vIG1vcmUgb3V0c3RhbmRpbmcgY2FsbHMuIFNjaGVkdWxlIHRpbWVvdXQuCiAgICAgICAgICAgIHNjaGVkdWxlVGltZW91dCgpOwogICAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIHZvaWQgc2NoZWR1bGVUaW1lb3V0KCkgewogICAgICAgIGlmIChpZGxlbmVzc1RpbWVyVGFzayAhPSBudWxsKQogICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJJZGxlIHRpbWVvdXQgYWxyZWFkeSBzY2hlZHVsZWQiKTsKICAgICAgICBpZGxlbmVzc1RpbWVyVGFzayA9IG5ldyBUaW1lclRhc2soKSB7CiAgICAgICAgICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKICAgICAgICAgICAgICAgIExvZy5zZXRMb2dGb3JDdXJyZW50VGhyZWFkKFNlcnZlck1haW4uZ2V0RXJyb3JMb2coKSk7CiAgICAgICAgICAgICAgICB0b1NodXRkb3duLnNodXRkb3duKCJTZXJ2ZXIgaGFzIGJlZW4gaWRsZSBmb3IgIiArIChpZGxlVGltZW91dCAvIDEwMDApICsgIiBzZWNvbmRzLiIpOwogICAgICAgICAgICB9CiAgICAgICAgfTsKICAgICAgICBpZGxlbmVzc1RpbWVyLnNjaGVkdWxlKGlkbGVuZXNzVGltZXJUYXNrLCBpZGxlVGltZW91dCk7CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCBzaHV0ZG93bigpIHsKICAgICAgICBpZGxlbmVzc1RpbWVyLmNhbmNlbCgpOwogICAgICAgIGRlbGVnYXRlLnNodXRkb3duKCk7CiAgICB9Cgp9ClBLAwQKAAAIAAAGO6lKTSmyq2wTAABsEwAALwAAAGNvbS9zdW4vdG9vbHMvc2phdmFjL3NlcnZlci9SZXF1ZXN0SGFuZGxlci5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDE0LCAyMDE2LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuc2phdmFjLnNlcnZlcjsKCmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLm1haW4uTWFpbjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuc2phdmFjLkxvZzsKaW1wb3J0IGNvbS5zdW4udG9vbHMuc2phdmFjLlV0aWw7CgppbXBvcnQgamF2YS5pby5CdWZmZXJlZFJlYWRlcjsKaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW1SZWFkZXI7CmltcG9ydCBqYXZhLmlvLlByaW50V3JpdGVyOwppbXBvcnQgamF2YS5uZXQuU29ja2V0OwppbXBvcnQgamF2YS5uaW8uZmlsZS5QYXRoOwoKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLnNqYXZhYy5zZXJ2ZXIuU2phdmFjU2VydmVyLkxJTkVfVFlQRV9SQzsKCgovKioKICogQSBSZXF1ZXN0SGFuZGxlciBoYW5kbGVzIHJlcXVlc3RzIHBlcmZvcm1lZCBvdmVyIGEgc29ja2V0LiBTcGVjaWZpY2FsbHkgaXQKICogIC0gUmVhZHMgdGhlIGNvbW1hbmQgc3RyaW5nIHNwZWNpZnlpbmcgd2hpY2ggbWV0aG9kIGlzIHRvIGJlIGludm9rZWQKICogIC0gUmVhZHMgdGhlIGFwcHJvcHJpYXRlIGFyZ3VtZW50cwogKiAgLSBEZWxlZ2F0ZXMgdGhlIGFjdHVhbCBpbnZvY2F0aW9uIHRvIHRoZSBnaXZlbiBzamF2YWMgaW1wbGVtZW50YXRpb24KICogIC0gV3JpdGVzIHRoZSByZXN1bHQgYmFjayB0byB0aGUgc29ja2V0IG91dHB1dCBzdHJlYW0KICoKICogTm9uZSBvZiB0aGUgd29yayBwZXJmb3JtZWQgYnkgdGhpcyBjbGFzcyBpcyByZWFsbHkgYm91bmQgYnkgdGhlIENQVS4gSXQKICogc2hvdWxkIGJlIGNvbXBsZXRlbHkgZmluZSB0byBoYXZlIGEgbGFyZ2UgbnVtYmVyIG9mIFJlcXVlc3RIYW5kbGVycyBhY3RpdmUuCiAqIFRvIGxpbWl0IHRoZSBudW1iZXIgb2YgY29uY3VycmVudCBjb21waWxhdGlvbnMsIHVzZSBQb29sZWRTamF2YWMuCiAqCiAqICA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiAgSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93biByaXNrLgogKiAgVGhpcyBjb2RlIGFuZCBpdHMgaW50ZXJuYWwgaW50ZXJmYWNlcyBhcmUgc3ViamVjdCB0byBjaGFuZ2Ugb3IKICogIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj4KICovCnB1YmxpYyBjbGFzcyBSZXF1ZXN0SGFuZGxlciBleHRlbmRzIFRocmVhZCB7CgogICAgcHJpdmF0ZSBmaW5hbCBTb2NrZXQgc29ja2V0OwogICAgcHJpdmF0ZSBmaW5hbCBTamF2YWMgc2phdmFjOwoKICAgIHB1YmxpYyBSZXF1ZXN0SGFuZGxlcihTb2NrZXQgc29ja2V0LCBTamF2YWMgc2phdmFjKSB7CiAgICAgICAgdGhpcy5zb2NrZXQgPSBzb2NrZXQ7CiAgICAgICAgdGhpcy5zamF2YWMgPSBzamF2YWM7CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCBydW4oKSB7CgogICAgICAgIHRyeSAoQnVmZmVyZWRSZWFkZXIgaW4gPSBuZXcgQnVmZmVyZWRSZWFkZXIobmV3IElucHV0U3RyZWFtUmVhZGVyKHNvY2tldC5nZXRJbnB1dFN0cmVhbSgpKSk7CiAgICAgICAgICAgICBQcmludFdyaXRlciBvdXQgPSBuZXcgUHJpbnRXcml0ZXIoc29ja2V0LmdldE91dHB1dFN0cmVhbSgpLCB0cnVlKSkgewoKICAgICAgICAgICAgLy8gU2V0IHVwIGxvZ2dpbmcgZm9yIHRoaXMgdGhyZWFkLiBTdHJlYW0gYmFjayBsb2dnaW5nIG1lc3NhZ2VzIHRvCiAgICAgICAgICAgIC8vIGNsaWVudCBvbiB0aGUgZm9ybWF0IGZvcm1hdCAibGV2ZWw6bXNnIi4KICAgICAgICAgICAgTG9nLnNldExvZ0ZvckN1cnJlbnRUaHJlYWQobmV3IExvZyhvdXQsIG91dCkgewogICAgICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgICAgICBwcm90ZWN0ZWQgYm9vbGVhbiBpc0xldmVsTG9nZ2VkKExldmVsIGwpIHsKICAgICAgICAgICAgICAgICAgICAvLyBNYWtlIHN1cmUgaXQgaXMgdXAgdG8gdGhlIGNsaWVudCB0byBkZWNpZGUgd2hldGhlciBvcgogICAgICAgICAgICAgICAgICAgIC8vIG5vdCB0aGlzIG1lc3NhZ2Ugc2hvdWxkIGJlIGRpc3BsYXllZC4KICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgICAgIHByb3RlY3RlZCB2b2lkIHByaW50TG9nTXNnKExldmVsIG1zZ0xldmVsLCBTdHJpbmcgbXNnKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gRm9sbG93IHNqYXZhYyBzZXJ2ZXIvY2xpZW50IHByb3RvY29sOiBTZW5kIG9uZSBsaW5lCiAgICAgICAgICAgICAgICAgICAgLy8gYXQgYSB0aW1lIGFuZCBwcmVmaXggd2l0aCBtZXNzYWdlIHdpdGggImxldmVsOiIuCiAgICAgICAgICAgICAgICAgICAgVXRpbC5nZXRMaW5lcyhtc2cpCiAgICAgICAgICAgICAgICAgICAgICAgIC5tYXAobGluZSAtPiBtc2dMZXZlbCArICI6IiArIGxpbmUpCiAgICAgICAgICAgICAgICAgICAgICAgIC5mb3JFYWNoKGxpbmUgLT4gc3VwZXIucHJpbnRMb2dNc2cobXNnTGV2ZWwsIGxpbmUpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAvLyBSZWFkIGFyZ3VtZW50IGFycmF5CiAgICAgICAgICAgIGludCBuID0gSW50ZWdlci5wYXJzZUludChpbi5yZWFkTGluZSgpKTsKICAgICAgICAgICAgU3RyaW5nW10gYXJncyA9IG5ldyBTdHJpbmdbbl07CiAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKSB7CiAgICAgICAgICAgICAgICBhcmdzW2ldID0gaW4ucmVhZExpbmUoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gSWYgdGhlcmUgaGFzIGJlZW4gYW55IGludGVybmFsIGVycm9ycywgbm90aWZ5IGNsaWVudAogICAgICAgICAgICBjaGVja0ludGVybmFsRXJyb3JMb2coKTsKCiAgICAgICAgICAgIC8vIFBlcmZvcm0gY29tcGlsYXRpb24KICAgICAgICAgICAgTWFpbi5SZXN1bHQgcmMgPSBzamF2YWMuY29tcGlsZShhcmdzKTsKCiAgICAgICAgICAgIC8vIFNlbmQgcmV0dXJuIGNvZGUgYmFjayB0byBjbGllbnQKICAgICAgICAgICAgb3V0LnByaW50bG4oTElORV9UWVBFX1JDICsgIjoiICsgcmMubmFtZSgpKTsKCiAgICAgICAgICAgIC8vIENoZWNrIGZvciBpbnRlcm5hbCBlcnJvcnMgYWdhaW4uCiAgICAgICAgICAgIGNoZWNrSW50ZXJuYWxFcnJvckxvZygpOwogICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgewogICAgICAgICAgICAvLyBOb3QgbXVjaCB0byBiZSBkb25lIGF0IHRoaXMgcG9pbnQuIFRoZSBjbGllbnQgc2lkZSByZXF1ZXN0CiAgICAgICAgICAgIC8vIGNvZGUgd2lsbCBtb3N0IGxpa2VseSB0aHJvdyBhbiBJT0V4Y2VwdGlvbiBhbmQgdGhlCiAgICAgICAgICAgIC8vIGNvbXBpbGF0aW9uIHdpbGwgZmFpbC4KICAgICAgICAgICAgTG9nLmVycm9yKGV4KTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICBMb2cuc2V0TG9nRm9yQ3VycmVudFRocmVhZChudWxsKTsKICAgICAgICB9CiAgICB9CgogICAgcHJpdmF0ZSB2b2lkIGNoZWNrSW50ZXJuYWxFcnJvckxvZygpIHsKICAgICAgICBQYXRoIGVycm9yTG9nID0gU2VydmVyTWFpbi5nZXRFcnJvckxvZygpLmdldExvZ0Rlc3RpbmF0aW9uKCk7CiAgICAgICAgaWYgKGVycm9yTG9nICE9IG51bGwpIHsKICAgICAgICAgICAgTG9nLmVycm9yKCJTZXJ2ZXIgaGFzIGVuY291bnRlcmVkIGFuIGludGVybmFsIGVycm9yLiBTZWUgIiArIGVycm9yTG9nLnRvQWJzb2x1dGVQYXRoKCkKICAgICAgICAgICAgICAgICAgICArICIgZm9yIGRldGFpbHMuIik7CiAgICAgICAgfQogICAgfQp9ClBLAwQKAAAIAAAGO6lKVIzNuoUuAACFLgAAJAAAAGNvbS9zdW4vdG9vbHMvc2phdmFjL0J1aWxkU3RhdGUuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAxMiwgMjAxNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLnNqYXZhYzsKCmltcG9ydCBqYXZhLmlvLkZpbGU7CmltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbnM7CmltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKaW1wb3J0IGphdmEudXRpbC5NYXA7CmltcG9ydCBqYXZhLnV0aWwuU2V0OwoKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5Bc3NlcnQ7CmltcG9ydCBjb20uc3VuLnRvb2xzLnNqYXZhYy5wdWJhcGkuUHViQXBpOwoKLyoqCiAqIFRoZSBidWlsZCBzdGF0ZSBjbGFzcyBjYXB0dXJlcyB0aGUgc291cmNlIGNvZGUgYW5kIGdlbmVyYXRlZCBhcnRpZmFjdHMKICogZnJvbSBhIGJ1aWxkLiBUaGVyZSBhcmUgdXN1YWxseSB0d28gYnVpbGQgc3RhdGVzLCB0aGUgcHJldmlvdXMgb25lIChwcmV2KSwKICogbG9hZGVkIGZyb20gdGhlIGphdmFjX3N0YXRlIGZpbGUsIGFuZCB0aGUgY3VycmVudCBvbmUgKG5vdykuCiAqCiAqICA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiAgSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93biByaXNrLgogKiAgVGhpcyBjb2RlIGFuZCBpdHMgaW50ZXJuYWwgaW50ZXJmYWNlcyBhcmUgc3ViamVjdCB0byBjaGFuZ2Ugb3IKICogIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj4KICovCnB1YmxpYyBjbGFzcyBCdWlsZFN0YXRlIHsKICAgIHByaXZhdGUgTWFwPFN0cmluZyxNb2R1bGU+IG1vZHVsZXMgPSBuZXcgSGFzaE1hcDw+KCk7CiAgICBwcml2YXRlIE1hcDxTdHJpbmcsUGFja2FnZT4gcGFja2FnZXMgPSBuZXcgSGFzaE1hcDw+KCk7CiAgICBwcml2YXRlIE1hcDxTdHJpbmcsU291cmNlPiBzb3VyY2VzID0gbmV3IEhhc2hNYXA8PigpOwogICAgcHJpdmF0ZSBNYXA8U3RyaW5nLEZpbGU+IGFydGlmYWN0cyA9IG5ldyBIYXNoTWFwPD4oKTsKICAgIC8vIE1hcCBmcm9tIHBhY2thZ2UgdG8gYSBzZXQgb2YgcGFja2FnZXMgdGhhdCBkZXBlbmQgb24gc2FpZCBwYWNrYWdlLgogICAgcHJpdmF0ZSBNYXA8U3RyaW5nLFNldDxTdHJpbmc+PiBkZXBlbmRlbnRzID0gbmV3IEhhc2hNYXA8PigpOwoKICAgIHB1YmxpYyAgTWFwPFN0cmluZyxNb2R1bGU+IG1vZHVsZXMoKSB7IHJldHVybiBtb2R1bGVzOyB9CiAgICBwdWJsaWMgIE1hcDxTdHJpbmcsUGFja2FnZT4gcGFja2FnZXMoKSB7IHJldHVybiBwYWNrYWdlczsgfQogICAgcHVibGljICBNYXA8U3RyaW5nLFNvdXJjZT4gc291cmNlcygpIHsgcmV0dXJuIHNvdXJjZXM7IH0KICAgIHB1YmxpYyAgTWFwPFN0cmluZyxGaWxlPiBhcnRpZmFjdHMoKSB7IHJldHVybiBhcnRpZmFjdHM7IH0KICAgIHB1YmxpYyAgTWFwPFN0cmluZyxTZXQ8U3RyaW5nPj4gZGVwZW5kZW50cygpIHsgcmV0dXJuIGRlcGVuZGVudHM7IH0KCiAgICAvKioKICAgICAqIExvb2t1cCBhIG1vZHVsZSBmcm9tIGEgbmFtZS4gQ3JlYXRlIHRoZSBtb2R1bGUgaWYgaXQgZG9lcwogICAgICogbm90IGV4aXN0IHlldC4KICAgICAqLwogICAgcHVibGljIE1vZHVsZSBsb29rdXBNb2R1bGUoU3RyaW5nIG1vZCkgewogICAgICAgIE1vZHVsZSBtID0gbW9kdWxlcy5nZXQobW9kKTsKICAgICAgICBpZiAobSA9PSBudWxsKSB7CiAgICAgICAgICAgIG0gPSBuZXcgTW9kdWxlKG1vZCwgIj8/PyIpOwogICAgICAgICAgICBtb2R1bGVzLnB1dChtb2QsIG0pOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbTsKICAgIH0KCiAgICAvKioKICAgICAqIEZpbmQgYSBtb2R1bGUgZnJvbSBhIGdpdmVuIHBhY2thZ2UgbmFtZS4gRm9yIGV4YW1wbGU6CiAgICAgKiBUaGUgcGFja2FnZSBuYW1lICJiYXNlOmphdmEubGFuZyIgd2lsbCBmZXRjaCB0aGUgbW9kdWxlIG5hbWVkICJiYXNlIi4KICAgICAqIFRoZSBwYWNrYWdlIG5hbWUgIjpqYXZhLm5ldCIgd2lsbCBmZXRjaCB0aGUgZGVmYXVsdCBtb2R1bGUuCiAgICAgKi8KICAgIE1vZHVsZSBmaW5kTW9kdWxlRnJvbVBhY2thZ2VOYW1lKFN0cmluZyBwa2cpIHsKICAgICAgICBpbnQgY3AgPSBwa2cuaW5kZXhPZignOicpOwogICAgICAgIEFzc2VydC5jaGVjayhjcCAhPSAtMSwgIkNvdWxkIG5vdCBmaW5kIHBhY2thZ2UgbmFtZSIpOwogICAgICAgIFN0cmluZyBtb2QgPSBwa2cuc3Vic3RyaW5nKDAsIGNwKTsKICAgICAgICByZXR1cm4gbG9va3VwTW9kdWxlKG1vZCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBTdG9yZSByZWZlcmVuY2VzIHRvIGFsbCBwYWNrYWdlcywgc291cmNlcyBhbmQgYXJ0aWZhY3RzIGZvciBhbGwgbW9kdWxlcwogICAgICogaW50byB0aGUgYnVpbGQgc3RhdGUuIEkuZS4gZmxhdHRlbiB0aGUgbW9kdWxlIHRyZWUgc3RydWN0dXJlCiAgICAgKiBpbnRvIGdsb2JhbCBtYXBzIHN0b3JlZCBpbiB0aGUgQnVpbGRTdGF0ZSBmb3IgZWFzeSBhY2Nlc3MuCiAgICAgKgogICAgICogQHBhcmFtIG0gVGhlIHNldCBvZiBtb2R1bGVzLgogICAgICovCiAgICBwdWJsaWMgdm9pZCBmbGF0dGVuUGFja2FnZXNTb3VyY2VzQW5kQXJ0aWZhY3RzKE1hcDxTdHJpbmcsTW9kdWxlPiBtKSB7CiAgICAgICAgbW9kdWxlcyA9IG07CiAgICAgICAgLy8gRXh0cmFjdCBhbGwgdGhlIGZvdW5kIHBhY2thZ2VzLgogICAgICAgIGZvciAoTW9kdWxlIGkgOiBtb2R1bGVzLnZhbHVlcygpKSB7CiAgICAgICAgICAgIGZvciAoTWFwLkVudHJ5PFN0cmluZyxQYWNrYWdlPiBqIDogaS5wYWNrYWdlcygpLmVudHJ5U2V0KCkpIHsKICAgICAgICAgICAgICAgIFBhY2thZ2UgcCA9IHBhY2thZ2VzLmdldChqLmdldEtleSgpKTsKICAgICAgICAgICAgICAgIC8vIENoZWNrIHRoYXQgbm8gdHdvIGRpZmZlcmVudCBwYWNrYWdlcyBhcmUgc3RvcmVkIHVuZGVyIHNhbWUgbmFtZS4KICAgICAgICAgICAgICAgIEFzc2VydC5jaGVjayhwID09IG51bGwgfHwgcCA9PSBqLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgaWYgKHAgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIHAgPSBqLmdldFZhbHVlKCk7CiAgICAgICAgICAgICAgICAgICAgcGFja2FnZXMucHV0KGouZ2V0S2V5KCksai5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGZvciAoTWFwLkVudHJ5PFN0cmluZyxTb3VyY2U+IGsgOiBwLnNvdXJjZXMoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgICAgICAgICAgICAgU291cmNlIHMgPSBzb3VyY2VzLmdldChrLmdldEtleSgpKTsKICAgICAgICAgICAgICAgICAgICAvLyBDaGVjayB0aGF0IG5vIHR3byBkaWZmZXJlbnQgc291cmNlcyBhcmUgc3RvcmVkIHVuZGVyIHNhbWUgbmFtZS4KICAgICAgICAgICAgICAgICAgICBBc3NlcnQuY2hlY2socyA9PSBudWxsIHx8IHMgPT0gay5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgICAgICBpZiAocyA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHMgPSBrLmdldFZhbHVlKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHNvdXJjZXMucHV0KGsuZ2V0S2V5KCksIGsuZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZm9yIChNYXAuRW50cnk8U3RyaW5nLEZpbGU+IGcgOiBwLmFydGlmYWN0cygpLmVudHJ5U2V0KCkpIHsKICAgICAgICAgICAgICAgICAgICBGaWxlIGYgPSBhcnRpZmFjdHMuZ2V0KGcuZ2V0S2V5KCkpOwogICAgICAgICAgICAgICAgICAgIC8vIENoZWNrIHRoYXQgbm8gdHdvIGFydGlmYWN0cyBhcmUgc3RvcmVkIHVuZGVyIHRoZSBzYW1lIGZpbGUuCiAgICAgICAgICAgICAgICAgICAgQXNzZXJ0LmNoZWNrKGYgPT0gbnVsbCB8fCBmID09IGcuZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKGYgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICBmID0gZy5nZXRWYWx1ZSgpOwogICAgICAgICAgICAgICAgICAgICAgICBhcnRpZmFjdHMucHV0KGcuZ2V0S2V5KCksIGcuZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogU3RvcmUgcmVmZXJlbmNlcyB0byBhbGwgYXJ0aWZhY3RzIGZvdW5kIGluIHRoZSBtb2R1bGUgdHJlZSBpbnRvIHRoZSBtYXBzCiAgICAgKiBzdG9yZWQgaW4gdGhlIGJ1aWxkIHN0YXRlLgogICAgICoKICAgICAqIEBwYXJhbSBtIFRoZSBzZXQgb2YgbW9kdWxlcy4KICAgICAqLwogICAgcHVibGljIHZvaWQgZmxhdHRlbkFydGlmYWN0cyhNYXA8U3RyaW5nLE1vZHVsZT4gbSkgewogICAgICAgIG1vZHVsZXMgPSBtOwogICAgICAgIC8vIEV4dHJhY3QgYWxsIHRoZSBmb3VuZCBwYWNrYWdlcy4KICAgICAgICBmb3IgKE1vZHVsZSBpIDogbW9kdWxlcy52YWx1ZXMoKSkgewogICAgICAgICAgICBmb3IgKE1hcC5FbnRyeTxTdHJpbmcsUGFja2FnZT4gaiA6IGkucGFja2FnZXMoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgICAgICAgICBQYWNrYWdlIHAgPSBwYWNrYWdlcy5nZXQoai5nZXRLZXkoKSk7CiAgICAgICAgICAgICAgICAvLyBDaGVjayB0aGF0IG5vIHR3byBkaWZmZXJlbnQgcGFja2FnZXMgYXJlIHN0b3JlZCB1bmRlciBzYW1lIG5hbWUuCiAgICAgICAgICAgICAgICBBc3NlcnQuY2hlY2socCA9PSBudWxsIHx8IHAgPT0gai5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIHAgPSBqLmdldFZhbHVlKCk7CiAgICAgICAgICAgICAgICBwYWNrYWdlcy5wdXQoai5nZXRLZXkoKSxqLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgZm9yIChNYXAuRW50cnk8U3RyaW5nLEZpbGU+IGcgOiBwLmFydGlmYWN0cygpLmVudHJ5U2V0KCkpIHsKICAgICAgICAgICAgICAgICAgICBGaWxlIGYgPSBhcnRpZmFjdHMuZ2V0KGcuZ2V0S2V5KCkpOwogICAgICAgICAgICAgICAgICAgIC8vIENoZWNrIHRoYXQgbm8gdHdvIGFydGlmYWN0cyBhcmUgc3RvcmVkIHVuZGVyIHRoZSBzYW1lIGZpbGUuCiAgICAgICAgICAgICAgICAgICAgQXNzZXJ0LmNoZWNrKGYgPT0gbnVsbCB8fCBmID09IGcuZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICAgICAgYXJ0aWZhY3RzLnB1dChnLmdldEtleSgpLCBnLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQ2FsY3VsYXRlIHRoZSBwYWNrYWdlIGRlcGVuZGVudHMgKGllIHRoZSByZXZlcnNlIG9mIHRoZSBkZXBlbmRlbmNpZXMpLgogICAgICovCiAgICBwdWJsaWMgdm9pZCBjYWxjdWxhdGVEZXBlbmRlbnRzKCkgewogICAgICAgIGRlcGVuZGVudHMgPSBuZXcgSGFzaE1hcDw+KCk7CgogICAgICAgIGZvciAoU3RyaW5nIHMgOiBwYWNrYWdlcy5rZXlTZXQoKSkgewogICAgICAgICAgICBQYWNrYWdlIHAgPSBwYWNrYWdlcy5nZXQocyk7CgogICAgICAgICAgICAvLyBDb2xsZWN0IGFsbCBkZXBlbmRlbmNpZXMgb2YgdGhlIGNsYXNzZXMgaW4gdGhpcyBwYWNrYWdlCiAgICAgICAgICAgIFNldDxTdHJpbmc+IGRlcHMgPSBwLnR5cGVEZXBlbmRlbmNpZXMoKSAgLy8gbWFwcyBmcU5hbWUgLT4gc2V0IG9mIGRlcGVuZGVuY2llcwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC52YWx1ZXMoKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5zdHJlYW0oKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5yZWR1Y2UoQ29sbGVjdGlvbnMuZW1wdHlTZXQoKSwgVXRpbDo6dW5pb24pOwoKICAgICAgICAgICAgLy8gTm93IHJldmVyc2UgdGhlIGRpcmVjdGlvbgoKICAgICAgICAgICAgZm9yIChTdHJpbmcgZGVwIDogZGVwcykgewogICAgICAgICAgICAgICAgLy8gQWRkIHRoZSBkZXBlbmRlbnQgaW5mb3JtYXRpb24gdG8gdGhlIGdsb2JhbCBkZXBlbmRlbnQgbWFwLgogICAgICAgICAgICAgICAgU3RyaW5nIGRlcFBrZ1N0ciA9ICI6IiArIGRlcC5zdWJzdHJpbmcoMCwgZGVwLmxhc3RJbmRleE9mKCcuJykpOwogICAgICAgICAgICAgICAgZGVwZW5kZW50cy5tZXJnZShkZXBQa2dTdHIsIENvbGxlY3Rpb25zLnNpbmdsZXRvbihzKSwgVXRpbDo6dW5pb24pOwoKICAgICAgICAgICAgICAgIC8vIEFsc28gYWRkIHRoZSBkZXBlbmRlbnQgaW5mb3JtYXRpb24gdG8gdGhlIHBhY2thZ2Ugc3BlY2lmaWMgbWFwLgogICAgICAgICAgICAgICAgLy8gTm9ybWFsbHksIHlvdSBkbyBub3QgY29tcGlsZSBqYXZhLmxhbmcgZXQgYWwuIFRoZXJlZm9yZQogICAgICAgICAgICAgICAgLy8gdGhlcmUgYXJlIHNldmVyYWwgcGFja2FnZXMgdGhhdCBwIGRlcGVuZHMgdXBvbiB0aGF0IHlvdQogICAgICAgICAgICAgICAgLy8gZG8gbm90IGhhdmUgaW4geW91ciBzdGF0ZSBkYXRhYmFzZS4gVGhpcyBpcyBwZXJmZWN0bHkgZmluZS4KICAgICAgICAgICAgICAgIFBhY2thZ2UgZHAgPSBwYWNrYWdlcy5nZXQoZGVwUGtnU3RyKTsKICAgICAgICAgICAgICAgIGlmIChkcCAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gQnV0IHRoaXMgcGFja2FnZSBkaWQgZXhpc3QgaW4gdGhlIHN0YXRlIGRhdGFiYXNlLgogICAgICAgICAgICAgICAgICAgIGRwLmFkZERlcGVuZGVudChwLm5hbWUoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBWZXJpZnkgdGhhdCB0aGUgc2V0TW9kdWxlcyBtZXRob2QgYWJvdmUgZGlkIHRoZSByaWdodCB0aGluZyB3aGVuCiAgICAgKiBydW5uaW5nIHRocm91Z2ggdGhlIHtAbGl0ZXJhbCBtb2R1bGUtPnBhY2thZ2UtPnNvdXJjZX0gc3RydWN0dXJlLgogICAgICovCiAgICBwdWJsaWMgdm9pZCBjaGVja0ludGVybmFsU3RhdGUoU3RyaW5nIG1zZywgYm9vbGVhbiBsaW5rZWRPbmx5LCBNYXA8U3RyaW5nLFNvdXJjZT4gc3JjcykgewogICAgICAgIGJvb2xlYW4gYmFhZCA9IGZhbHNlOwogICAgICAgIE1hcDxTdHJpbmcsU291cmNlPiBvcmlnaW5hbCA9IG5ldyBIYXNoTWFwPD4oKTsKICAgICAgICBNYXA8U3RyaW5nLFNvdXJjZT4gY2FsY3VsYXRlZCA9IG5ldyBIYXNoTWFwPD4oKTsKCiAgICAgICAgZm9yIChTdHJpbmcgcyA6IHNvdXJjZXMua2V5U2V0KCkpIHsKICAgICAgICAgICAgU291cmNlIHNzID0gc291cmNlcy5nZXQocyk7CiAgICAgICAgICAgIGlmIChzcy5pc0xpbmtlZE9ubHkoKSA9PSBsaW5rZWRPbmx5KSB7CiAgICAgICAgICAgICAgICBjYWxjdWxhdGVkLnB1dChzLHNzKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBmb3IgKFN0cmluZyBzIDogc3Jjcy5rZXlTZXQoKSkgewogICAgICAgICAgICBTb3VyY2Ugc3MgPSBzcmNzLmdldChzKTsKICAgICAgICAgICAgaWYgKHNzLmlzTGlua2VkT25seSgpID09IGxpbmtlZE9ubHkpIHsKICAgICAgICAgICAgICAgIG9yaWdpbmFsLnB1dChzLHNzKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAob3JpZ2luYWwuc2l6ZSgpICE9IGNhbGN1bGF0ZWQuc2l6ZSgpKSB7CiAgICAgICAgICAgIExvZy5lcnJvcigiSU5URVJOQUwgRVJST1IgIittc2crIiBvcmlnaW5hbCBhbmQgY2FsY3VsYXRlZCBhcmUgbm90IHRoZSBzYW1lIHNpemUhIik7CiAgICAgICAgICAgIGJhYWQgPSB0cnVlOwogICAgICAgIH0KICAgICAgICBpZiAoIW9yaWdpbmFsLmtleVNldCgpLmVxdWFscyhjYWxjdWxhdGVkLmtleVNldCgpKSkgewogICAgICAgICAgICBMb2cuZXJyb3IoIklOVEVSTkFMIEVSUk9SICIrbXNnKyIgb3JpZ2luYWwgYW5kIGNhbGN1bGF0ZWQgZG8gbm90IGhhdmUgdGhlIHNhbWUgZG9tYWluISIpOwogICAgICAgICAgICBiYWFkID0gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgaWYgKCFiYWFkKSB7CiAgICAgICAgICAgIGZvciAoU3RyaW5nIHMgOiBvcmlnaW5hbC5rZXlTZXQoKSkgewogICAgICAgICAgICAgICAgU291cmNlIHMxID0gb3JpZ2luYWwuZ2V0KHMpOwogICAgICAgICAgICAgICAgU291cmNlIHMyID0gY2FsY3VsYXRlZC5nZXQocyk7CiAgICAgICAgICAgICAgICBpZiAoczEgPT0gbnVsbCB8fCBzMiA9PSBudWxsIHx8ICFzMS5lcXVhbHMoczIpKSB7CiAgICAgICAgICAgICAgICAgICAgTG9nLmVycm9yKCJJTlRFUk5BTCBFUlJPUiAiK21zZysiIG9yaWdpbmFsIGFuZCBjYWxjdWxhdGVkIGhhdmUgZGlmZmVyaW5nIGVsZW1lbnRzIGZvciAiK3MpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYmFhZCA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKGJhYWQpIHsKICAgICAgICAgICAgZm9yIChTdHJpbmcgcyA6IG9yaWdpbmFsLmtleVNldCgpKSB7CiAgICAgICAgICAgICAgICBTb3VyY2Ugc3MgPSBvcmlnaW5hbC5nZXQocyk7CiAgICAgICAgICAgICAgICBTb3VyY2Ugc3NzID0gY2FsY3VsYXRlZC5nZXQocyk7CiAgICAgICAgICAgICAgICBpZiAoc3NzID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICBMb2cuZXJyb3IoIlRoZSBmaWxlICIrcysiIGRvZXMgbm90IGV4aXN0IGluIGNhbGN1bGF0ZWQgdHJlZSBvZiBzb3VyY2VzLiIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGZvciAoU3RyaW5nIHMgOiBjYWxjdWxhdGVkLmtleVNldCgpKSB7CiAgICAgICAgICAgICAgICBTb3VyY2Ugc3MgPSBjYWxjdWxhdGVkLmdldChzKTsKICAgICAgICAgICAgICAgIFNvdXJjZSBzc3MgPSBvcmlnaW5hbC5nZXQocyk7CiAgICAgICAgICAgICAgICBpZiAoc3NzID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICBMb2cuZXJyb3IoIlRoZSBmaWxlICIrcysiIGRvZXMgbm90IGV4aXN0IGluIG9yaWdpbmFsIHNldCBvZiBmb3VuZCBzb3VyY2VzLiIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogTG9hZCBhIG1vZHVsZSBmcm9tIHRoZSBqYXZhYyBzdGF0ZSBmaWxlLgogICAgICovCiAgICBwdWJsaWMgTW9kdWxlIGxvYWRNb2R1bGUoU3RyaW5nIGwpIHsKICAgICAgICBNb2R1bGUgbSA9IE1vZHVsZS5sb2FkKGwpOwogICAgICAgIG1vZHVsZXMucHV0KG0ubmFtZSgpLCBtKTsKICAgICAgICByZXR1cm4gbTsKICAgIH0KCiAgICAvKioKICAgICAqIExvYWQgYSBwYWNrYWdlIGZyb20gdGhlIGphdmFjIHN0YXRlIGZpbGUuCiAgICAgKi8KICAgIHB1YmxpYyBQYWNrYWdlIGxvYWRQYWNrYWdlKE1vZHVsZSBsYXN0TW9kdWxlLCBTdHJpbmcgbCkgewogICAgICAgIFBhY2thZ2UgcCA9IFBhY2thZ2UubG9hZChsYXN0TW9kdWxlLCBsKTsKICAgICAgICBsYXN0TW9kdWxlLmFkZFBhY2thZ2UocCk7CiAgICAgICAgcGFja2FnZXMucHV0KHAubmFtZSgpLCBwKTsKICAgICAgICByZXR1cm4gcDsKICAgIH0KCiAgICAvKioKICAgICAqIExvYWQgYSBzb3VyY2UgZnJvbSB0aGUgamF2YWMgc3RhdGUgZmlsZS4KICAgICAqLwogICAgcHVibGljIFNvdXJjZSBsb2FkU291cmNlKFBhY2thZ2UgbGFzdFBhY2thZ2UsIFN0cmluZyBsLCBib29sZWFuIGlzX2dlbmVyYXRlZCkgewogICAgICAgIFNvdXJjZSBzID0gU291cmNlLmxvYWQobGFzdFBhY2thZ2UsIGwsIGlzX2dlbmVyYXRlZCk7CiAgICAgICAgbGFzdFBhY2thZ2UuYWRkU291cmNlKHMpOwogICAgICAgIHNvdXJjZXMucHV0KHMubmFtZSgpLCBzKTsKICAgICAgICByZXR1cm4gczsKICAgIH0KCiAgICAvKioKICAgICAqIER1cmluZyBhbiBpbmNyZW1lbnRhbCBjb21waWxlIHdlIG5lZWQgdG8gY29weSB0aGUgb2xkIGphdmFjIHN0YXRlCiAgICAgKiBpbmZvcm1hdGlvbiBhYm91dCBwYWNrYWdlcyB0aGF0IHdlcmUgbm90IHJlY29tcGlsZWQuCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIGNvcHlQYWNrYWdlc0V4Y2VwdChCdWlsZFN0YXRlIHByZXYsIFNldDxTdHJpbmc+IHJlY29tcGlsZWQsIFNldDxTdHJpbmc+IHJlbW92ZWQpIHsKICAgICAgICBmb3IgKFN0cmluZyBwa2cgOiBwcmV2LnBhY2thZ2VzKCkua2V5U2V0KCkpIHsKICAgICAgICAgICAgLy8gRG8gbm90IGNvcHkgcmVjb21waWxlZCBvciByZW1vdmVkIHBhY2thZ2VzLgogICAgICAgICAgICBpZiAocmVjb21waWxlZC5jb250YWlucyhwa2cpIHx8IHJlbW92ZWQuY29udGFpbnMocGtnKSkKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwoKICAgICAgICAgICAgTW9kdWxlIG1uZXcgPSBmaW5kTW9kdWxlRnJvbVBhY2thZ2VOYW1lKHBrZyk7CiAgICAgICAgICAgIFBhY2thZ2UgcHByZXYgPSBwcmV2LnBhY2thZ2VzKCkuZ2V0KHBrZyk7CgogICAgICAgICAgICAvLyBFdmVuIHRob3VnaCB3ZSBoYXZlbid0IHJlY29tcGlsZWQgdGhpcyBwYWNrYWdlLCB3ZSBtYXkgaGF2ZQogICAgICAgICAgICAvLyBpbmZvcm1hdGlvbiBhYm91dCBpdHMgcHVibGljIEFQSTogSXQgbWF5IGJlIGEgY2xhc3NwYXRoIGRlcGVuZGVuY3kKICAgICAgICAgICAgaWYgKHBhY2thZ2VzLmNvbnRhaW5zS2V5KHBrZykpIHsKICAgICAgICAgICAgICAgIHBwcmV2LnNldFB1YmFwaShQdWJBcGkubWVyZ2VUeXBlcyhwcHJldi5nZXRQdWJBcGkoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWNrYWdlcy5nZXQocGtnKS5nZXRQdWJBcGkoKSkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBtbmV3LmFkZFBhY2thZ2UocHByZXYpOwogICAgICAgICAgICAvLyBEbyBub3QgZm9yZ2V0IHRvIHVwZGF0ZSB0aGUgZmxhdHRlbmVkIGRhdGEuIChTZWUgSkRLLTgwNzE5MDQpCiAgICAgICAgICAgIHBhY2thZ2VzLnB1dChwa2csIHBwcmV2KTsKICAgICAgICB9CiAgICB9Cn0KUEsDBAoAAAgAAAY7qUoAAAAAAAAAAAAAAAAcAAAAY29tL3N1bi90b29scy9zamF2YWMvY2xpZW50L1BLAwQKAAAIAAAGO6lKEsYu9McMAADHDAAAKwAAAGNvbS9zdW4vdG9vbHMvc2phdmFjL2NsaWVudC9DbGllbnRNYWluLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTQsIDIwMTYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5zamF2YWMuY2xpZW50OwoKaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtV3JpdGVyOwppbXBvcnQgamF2YS5pby5Xcml0ZXI7CgppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5tYWluLk1haW47CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLm1haW4uTWFpbi5SZXN1bHQ7CmltcG9ydCBjb20uc3VuLnRvb2xzLnNqYXZhYy5BdXRvRmx1c2hXcml0ZXI7CmltcG9ydCBjb20uc3VuLnRvb2xzLnNqYXZhYy5Mb2c7CmltcG9ydCBjb20uc3VuLnRvb2xzLnNqYXZhYy5VdGlsOwppbXBvcnQgY29tLnN1bi50b29scy5zamF2YWMuY29tcC5TamF2YWNJbXBsOwppbXBvcnQgY29tLnN1bi50b29scy5zamF2YWMub3B0aW9ucy5PcHRpb25zOwppbXBvcnQgY29tLnN1bi50b29scy5zamF2YWMuc2VydmVyLlNqYXZhYzsKCi8qKgogKiAgPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24gcmlzay4KICogIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yCiAqICBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+CiAqLwpwdWJsaWMgY2xhc3MgQ2xpZW50TWFpbiB7CgogICAgcHVibGljIHN0YXRpYyBpbnQgcnVuKFN0cmluZ1tdIGFyZ3MpIHsKICAgICAgICByZXR1cm4gcnVuKGFyZ3MsCiAgICAgICAgICAgICAgICAgICBuZXcgQXV0b0ZsdXNoV3JpdGVyKG5ldyBPdXRwdXRTdHJlYW1Xcml0ZXIoU3lzdGVtLm91dCkpLAogICAgICAgICAgICAgICAgICAgbmV3IEF1dG9GbHVzaFdyaXRlcihuZXcgT3V0cHV0U3RyZWFtV3JpdGVyKFN5c3RlbS5lcnIpKSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBpbnQgcnVuKFN0cmluZ1tdIGFyZ3MsIFdyaXRlciBvdXQsIFdyaXRlciBlcnIpIHsKCiAgICAgICAgTG9nLnNldExvZ0ZvckN1cnJlbnRUaHJlYWQobmV3IExvZyhvdXQsIGVycikpOwoKICAgICAgICBPcHRpb25zIG9wdGlvbnM7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgb3B0aW9ucyA9IE9wdGlvbnMucGFyc2VBcmdzKGFyZ3MpOwogICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIExvZy5lcnJvcihlLmdldE1lc3NhZ2UoKSk7CiAgICAgICAgICAgIHJldHVybiBSZXN1bHQuQ01ERVJSLmV4aXRDb2RlOwogICAgICAgIH0KCiAgICAgICAgTG9nLnNldExvZ0xldmVsKG9wdGlvbnMuZ2V0TG9nTGV2ZWwoKSk7CgogICAgICAgIExvZy5kZWJ1ZygiPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSIpOwogICAgICAgIExvZy5kZWJ1ZygiTGF1bmNoaW5nIHNqYXZhYyBjbGllbnQgd2l0aCB0aGUgZm9sbG93aW5nIHBhcmFtZXRlcnM6Iik7CiAgICAgICAgTG9nLmRlYnVnKCIgICAgIiArIG9wdGlvbnMuZ2V0U3RhdGVBcmdzU3RyaW5nKCkpOwogICAgICAgIExvZy5kZWJ1ZygiPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSIpOwoKICAgICAgICAvLyBQcmVwYXJlIHNqYXZhYyBvYmplY3QKICAgICAgICBib29sZWFuIHVzZVNlcnZlciA9IG9wdGlvbnMuZ2V0U2VydmVyQ29uZigpICE9IG51bGw7CiAgICAgICAgU2phdmFjIHNqYXZhYyA9IHVzZVNlcnZlciA/IG5ldyBTamF2YWNDbGllbnQob3B0aW9ucykgOiBuZXcgU2phdmFjSW1wbCgpOwoKICAgICAgICAvLyBQZXJmb3JtIGNvbXBpbGF0aW9uCiAgICAgICAgUmVzdWx0IHJlc3VsdCA9IHNqYXZhYy5jb21waWxlKGFyZ3MpOwoKICAgICAgICAvLyBJZiBzamF2YWMgaXMgcnVubmluZyBpbiB0aGUgZm9yZWdyb3VuZCB3ZSBzaG91bGQgc2h1dCBpdCBkb3duIGF0IHRoaXMgcG9pbnQKICAgICAgICBpZiAoIXVzZVNlcnZlcikgewogICAgICAgICAgICBzamF2YWMuc2h1dGRvd24oKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiByZXN1bHQuZXhpdENvZGU7CiAgICB9Cn0KUEsDBAoAAAgAAAY7qUpBznM74AUAAOAFAAA+AAAAY29tL3N1bi90b29scy9zamF2YWMvY2xpZW50L1BvcnRGaWxlSW5hY2Nlc3NpYmxlRXhjZXB0aW9uLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5zamF2YWMuY2xpZW50OwoKaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CgpwdWJsaWMgY2xhc3MgUG9ydEZpbGVJbmFjY2Vzc2libGVFeGNlcHRpb24gZXh0ZW5kcyBJT0V4Y2VwdGlvbiB7CgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTQ3NTUyNjE4ODE1NDUzOTg5NzNMOwoKICAgIHB1YmxpYyBQb3J0RmlsZUluYWNjZXNzaWJsZUV4Y2VwdGlvbihUaHJvd2FibGUgY2F1c2UpIHsKICAgICAgICBzdXBlcihjYXVzZSk7CiAgICB9Cn0KUEsDBAoAAAgAAAY7qUovWdacRi0AAEYtAAAtAAAAY29tL3N1bi90b29scy9zamF2YWMvY2xpZW50L1NqYXZhY0NsaWVudC5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDE0LCAyMDE2LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuc2phdmFjLmNsaWVudDsKCmltcG9ydCBqYXZhLmlvLkJ1ZmZlcmVkUmVhZGVyOwppbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW1SZWFkZXI7CmltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbVdyaXRlcjsKaW1wb3J0IGphdmEuaW8uUHJpbnRXcml0ZXI7CmltcG9ydCBqYXZhLmlvLlJlYWRlcjsKaW1wb3J0IGphdmEubmV0LkluZXRBZGRyZXNzOwppbXBvcnQgamF2YS5uZXQuSW5ldFNvY2tldEFkZHJlc3M7CmltcG9ydCBqYXZhLm5ldC5Tb2NrZXQ7CmltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OwppbXBvcnQgamF2YS51dGlsLkFycmF5czsKaW1wb3J0IGphdmEudXRpbC5MaXN0OwoKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMubWFpbi5NYWluOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5tYWluLk1haW4uUmVzdWx0OwppbXBvcnQgY29tLnN1bi50b29scy5zamF2YWMuTG9nOwppbXBvcnQgY29tLnN1bi50b29scy5zamF2YWMuVXRpbDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuc2phdmFjLm9wdGlvbnMuT3B0aW9uSGVscGVyOwppbXBvcnQgY29tLnN1bi50b29scy5zamF2YWMub3B0aW9ucy5PcHRpb25zOwppbXBvcnQgY29tLnN1bi50b29scy5zamF2YWMuc2VydmVyLkNvbXBpbGF0aW9uU3ViUmVzdWx0OwppbXBvcnQgY29tLnN1bi50b29scy5zamF2YWMuc2VydmVyLlBvcnRGaWxlOwppbXBvcnQgY29tLnN1bi50b29scy5zamF2YWMuc2VydmVyLlNqYXZhYzsKaW1wb3J0IGNvbS5zdW4udG9vbHMuc2phdmFjLnNlcnZlci5TamF2YWNTZXJ2ZXI7CgppbXBvcnQgc3RhdGljIGphdmEudXRpbC5zdHJlYW0uQ29sbGVjdG9ycy5qb2luaW5nOwoKLyoqCiAqIFNqYXZhYyBpbXBsZW1lbnRhdGlvbiB0aGF0IGRlbGVnYXRlcyByZXF1ZXN0cyB0byBhIFNqYXZhY1NlcnZlci4KICoKICogIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqICBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqICBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogKiAgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPgogKi8KcHVibGljIGNsYXNzIFNqYXZhY0NsaWVudCBpbXBsZW1lbnRzIFNqYXZhYyB7CgogICAgLy8gVGhlIGlkIGNhbiBwZXJoYXBzIGJlIHVzZWQgaW4gdGhlIGZ1dHVyZSBieSB0aGUgamF2YWMgc2VydmVyIHRvIHJldXNlIHRoZQogICAgLy8gSmF2YUNvbXBpbGVyIGluc3RhbmNlIGZvciBzZXZlcmFsIGNvbXBpbGVzIHVzaW5nIHRoZSBzYW1lIGlkLgogICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgaWQ7CiAgICBwcml2YXRlIGZpbmFsIFBvcnRGaWxlIHBvcnRGaWxlOwoKICAgIC8vIERlZmF1bHQga2VlcGFsaXZlIGZvciBzZXJ2ZXIgaXMgMTIwIHNlY29uZHMuCiAgICAvLyBJLmUuIGl0IHdpbGwgYWNjZXB0IDEyMCBzZWNvbmRzIG9mIGluYWN0aXZpdHkgYmVmb3JlIHF1aXR0aW5nLgogICAgcHJpdmF0ZSBmaW5hbCBpbnQga2VlcGFsaXZlOwogICAgcHJpdmF0ZSBmaW5hbCBpbnQgcG9vbHNpemU7CgogICAgLy8gVGhlIHNqYXZhYyBvcHRpb24gc3BlY2lmaWVzIGhvdyB0aGUgc2VydmVyIHBhcnQgb2Ygc2phdmFjIGlzIHNwYXduZWQuCiAgICAvLyBJZiB5b3UgaGF2ZSB0aGUgZXhwZXJpbWVudGFsIHNqYXZhYyBpbiB5b3VyIHBhdGgsIHlvdSBhcmUgZG9uZS4gSWYgbm90LCB5b3UgaGF2ZQogICAgLy8gdG8gcG9pbnQgdG8gYSBjb20uc3VuLnRvb2xzLnNqYXZhYy5NYWluIHRoYXQgc3VwcG9ydHMgLS1zdGFydHNlcnZlcgogICAgLy8gZm9yIGV4YW1wbGUgYnkgc2V0dGluZzogc2phdmFjPWphdmElMjAtamFyJTIwLi4uamF2YWMuamFyJWNvbS5zdW4udG9vbHMuc2phdmFjLk1haW4KICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIHNqYXZhY0ZvcmtDbWQ7CgogICAgLy8gV2FpdCAyIHNlY29uZHMgZm9yIHJlc3BvbnNlLCBiZWZvcmUgZ2l2aW5nIHVwIG9uIGphdmFjIHNlcnZlci4KICAgIHN0YXRpYyBpbnQgQ09OTkVDVElPTl9USU1FT1VUID0gMjAwMDsKICAgIHN0YXRpYyBpbnQgTUFYX0NPTk5FQ1RfQVRURU1QVFMgPSAzOwogICAgc3RhdGljIGludCBXQUlUX0JFVFdFRU5fQ09OTkVDVF9BVFRFTVBUUyA9IDIwMDA7CgogICAgLy8gU3RvcmUgdGhlIHNlcnZlciBjb25mIHNldHRpbmdzIGhlcmUuCiAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBzZXR0aW5nczsKCiAgICBwdWJsaWMgU2phdmFjQ2xpZW50KE9wdGlvbnMgb3B0aW9ucykgewogICAgICAgIFN0cmluZyB0bXBTZXJ2ZXJDb25mID0gb3B0aW9ucy5nZXRTZXJ2ZXJDb25mKCk7CiAgICAgICAgU3RyaW5nIHNlcnZlckNvbmYgPSAodG1wU2VydmVyQ29uZiE9bnVsbCk/IHRtcFNlcnZlckNvbmYgOiAiIjsKICAgICAgICBTdHJpbmcgdG1wSWQgPSBVdGlsLmV4dHJhY3RTdHJpbmdPcHRpb24oImlkIiwgc2VydmVyQ29uZik7CiAgICAgICAgaWQgPSAodG1wSWQhPW51bGwpID8gdG1wSWQgOiAiaWQiKygoKG5ldyBqYXZhLnV0aWwuUmFuZG9tKCkpLm5leHRMb25nKCkpJkxvbmcuTUFYX1ZBTFVFKTsKICAgICAgICBTdHJpbmcgZGVmYXVsdFBvcnRmaWxlID0gb3B0aW9ucy5nZXREZXN0RGlyKCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5yZXNvbHZlKCJqYXZhY19zZXJ2ZXIiKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnRvQWJzb2x1dGVQYXRoKCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC50b1N0cmluZygpOwogICAgICAgIFN0cmluZyBwb3J0ZmlsZU5hbWUgPSBVdGlsLmV4dHJhY3RTdHJpbmdPcHRpb24oInBvcnRmaWxlIiwgc2VydmVyQ29uZiwgZGVmYXVsdFBvcnRmaWxlKTsKICAgICAgICBwb3J0RmlsZSA9IFNqYXZhY1NlcnZlci5nZXRQb3J0RmlsZShwb3J0ZmlsZU5hbWUpOwogICAgICAgIHNqYXZhY0ZvcmtDbWQgPSBVdGlsLmV4dHJhY3RTdHJpbmdPcHRpb24oInNqYXZhYyIsIHNlcnZlckNvbmYsICJzamF2YWMiKTsKICAgICAgICBpbnQgcG9vbHNpemUgPSBVdGlsLmV4dHJhY3RJbnRPcHRpb24oInBvb2xzaXplIiwgc2VydmVyQ29uZik7CiAgICAgICAga2VlcGFsaXZlID0gVXRpbC5leHRyYWN0SW50T3B0aW9uKCJrZWVwYWxpdmUiLCBzZXJ2ZXJDb25mLCAxMjApOwoKICAgICAgICB0aGlzLnBvb2xzaXplID0gcG9vbHNpemUgPiAwID8gcG9vbHNpemUgOiBSdW50aW1lLmdldFJ1bnRpbWUoKS5hdmFpbGFibGVQcm9jZXNzb3JzKCk7CiAgICAgICAgc2V0dGluZ3MgPSAoc2VydmVyQ29uZi5lcXVhbHMoIiIpKSA/ICJpZD0iK2lkKyIscG9ydGZpbGU9Iitwb3J0ZmlsZU5hbWUgOiBzZXJ2ZXJDb25mOwogICAgfQoKICAgIC8qKgogICAgICogSGFuZCBvdXQgdGhlIHNlcnZlciBzZXR0aW5ncy4KICAgICAqIEByZXR1cm4gVGhlIHNlcnZlciBzZXR0aW5ncywgcG9zc2libHkgYSBkZWZhdWx0IHZhbHVlLgogICAgICovCiAgICBwdWJsaWMgU3RyaW5nIHNlcnZlclNldHRpbmdzKCkgewogICAgICAgIHJldHVybiBzZXR0aW5nczsKICAgIH0KCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSZXN1bHQgY29tcGlsZShTdHJpbmdbXSBhcmdzKSB7CiAgICAgICAgUmVzdWx0IHJlc3VsdCA9IG51bGw7CiAgICAgICAgdHJ5IChTb2NrZXQgc29ja2V0ID0gdHJ5Q29ubmVjdCgpKSB7CiAgICAgICAgICAgIFByaW50V3JpdGVyIG91dCA9IG5ldyBQcmludFdyaXRlcihuZXcgT3V0cHV0U3RyZWFtV3JpdGVyKHNvY2tldC5nZXRPdXRwdXRTdHJlYW0oKSkpOwogICAgICAgICAgICBCdWZmZXJlZFJlYWRlciBpbiA9IG5ldyBCdWZmZXJlZFJlYWRlcihuZXcgSW5wdXRTdHJlYW1SZWFkZXIoc29ja2V0LmdldElucHV0U3RyZWFtKCkpKTsKCiAgICAgICAgICAgIC8vIFNlbmQgYXJncyBhcnJheSB0byBzZXJ2ZXIKICAgICAgICAgICAgb3V0LnByaW50bG4oYXJncy5sZW5ndGgpOwogICAgICAgICAgICBmb3IgKFN0cmluZyBhcmcgOiBhcmdzKQogICAgICAgICAgICAgICAgb3V0LnByaW50bG4oYXJnKTsKICAgICAgICAgICAgb3V0LmZsdXNoKCk7CgogICAgICAgICAgICAvLyBSZWFkIHNlcnZlciByZXNwb25zZSBsaW5lIGJ5IGxpbmUKICAgICAgICAgICAgU3RyaW5nIGxpbmU7CiAgICAgICAgICAgIHdoaWxlIChudWxsICE9IChsaW5lID0gaW4ucmVhZExpbmUoKSkpIHsKICAgICAgICAgICAgICAgIGlmICghbGluZS5jb250YWlucygiOiIpKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCJDb3VsZCBub3QgcGFyc2UgcHJvdG9jb2wgbGluZTogPj5cIiIgKyBsaW5lICsgIlwiPDwiKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIFN0cmluZ1tdIHR5cGVBbmRDb250ZW50ID0gbGluZS5zcGxpdCgiOiIsIDIpOwogICAgICAgICAgICAgICAgU3RyaW5nIHR5cGUgPSB0eXBlQW5kQ29udGVudFswXTsKICAgICAgICAgICAgICAgIFN0cmluZyBjb250ZW50ID0gdHlwZUFuZENvbnRlbnRbMV07CgogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICBpZiAoTG9nLmlzRGVidWdnaW5nKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gRGlzdGluZ3Vpc2ggc2VydmVyIGdlbmVyYXRlZCBvdXRwdXQgaWYgZGVidWdnaW5nLgogICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50ID0gIltzamF2YWMtc2VydmVyXSAiICsgY29udGVudDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgTG9nLmxvZyhMb2cuTGV2ZWwudmFsdWVPZih0eXBlKSwgY29udGVudCk7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgewogICAgICAgICAgICAgICAgICAgIC8vIFBhcnNpbmcgb2YgJ3R5cGUnIGFzIGxvZyBsZXZlbCBmYWlsZWQuCiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKHR5cGUuZXF1YWxzKFNqYXZhY1NlcnZlci5MSU5FX1RZUEVfUkMpKSB7CiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gTWFpbi5SZXN1bHQudmFsdWVPZihjb250ZW50KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0gY2F0Y2ggKFBvcnRGaWxlSW5hY2Nlc3NpYmxlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgTG9nLmVycm9yKCJQb3J0IGZpbGUgaW5hY2Nlc3NpYmxlLiIpOwogICAgICAgICAgICByZXN1bHQgPSBSZXN1bHQuRVJST1I7CiAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gaW9lKSB7CiAgICAgICAgICAgIExvZy5lcnJvcigiSU9FeGNlcHRpb24gY2F1Z2h0IGR1cmluZyBjb21waWxhdGlvbjogIiArIGlvZS5nZXRNZXNzYWdlKCkpOwogICAgICAgICAgICBMb2cuZGVidWcoaW9lKTsKICAgICAgICAgICAgcmVzdWx0ID0gUmVzdWx0LkVSUk9SOwogICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGllKSB7CiAgICAgICAgICAgIFRocmVhZC5jdXJyZW50VGhyZWFkKCkuaW50ZXJydXB0KCk7IC8vIFJlc3RvcmUgaW50ZXJydXB0CiAgICAgICAgICAgIExvZy5lcnJvcigiQ29tcGlsYXRpb24gaW50ZXJydXB0ZWQuIik7CiAgICAgICAgICAgIExvZy5kZWJ1ZyhpZSk7CiAgICAgICAgICAgIHJlc3VsdCA9IFJlc3VsdC5FUlJPUjsKICAgICAgICB9CgogICAgICAgIGlmIChyZXN1bHQgPT0gbnVsbCkgewogICAgICAgICAgICAvLyBObyBMSU5FX1RZUEVfUkMgd2FzIGZvdW5kLgogICAgICAgICAgICByZXN1bHQgPSBSZXN1bHQuRVJST1I7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgfQoKICAgIC8qCiAgICAgKiBNYWtlcyBNQVhfQ09OTkVDVF9BVFRFTVBUUyBhdHRlcG10cyB0byBjb25uZWN0IHRvIHNlcnZlci4KICAgICAqLwogICAgcHJpdmF0ZSBTb2NrZXQgdHJ5Q29ubmVjdCgpIHRocm93cyBJT0V4Y2VwdGlvbiwgSW50ZXJydXB0ZWRFeGNlcHRpb24gewogICAgICAgIG1ha2VTdXJlU2VydmVySXNSdW5uaW5nKHBvcnRGaWxlKTsKICAgICAgICBpbnQgYXR0ZW1wdCA9IDA7CiAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgICAgTG9nLmRlYnVnKCJUcnlpbmcgdG8gY29ubmVjdC4gQXR0ZW1wdCAiICsgKCsrYXR0ZW1wdCkgKyAiIG9mICIgKyBNQVhfQ09OTkVDVF9BVFRFTVBUUyk7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICByZXR1cm4gbWFrZUNvbm5lY3Rpb25BdHRlbXB0KCk7CiAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7CiAgICAgICAgICAgICAgICBMb2cuZXJyb3IoIkNvbm5lY3Rpb24gYXR0ZW1wdCBmYWlsZWQ6ICIgKyBleC5nZXRNZXNzYWdlKCkpOwogICAgICAgICAgICAgICAgaWYgKGF0dGVtcHQgPj0gTUFYX0NPTk5FQ1RfQVRURU1QVFMpIHsKICAgICAgICAgICAgICAgICAgICBMb2cuZXJyb3IoIkdpdmluZyB1cCIpOwogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiQ291bGQgbm90IGNvbm5lY3QgdG8gc2VydmVyIiwgZXgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIFRocmVhZC5zbGVlcChXQUlUX0JFVFdFRU5fQ09OTkVDVF9BVFRFTVBUUyk7CiAgICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgU29ja2V0IG1ha2VDb25uZWN0aW9uQXR0ZW1wdCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgU29ja2V0IHNvY2tldCA9IG5ldyBTb2NrZXQoKTsKICAgICAgICBJbmV0QWRkcmVzcyBsb2NhbGhvc3QgPSBJbmV0QWRkcmVzcy5nZXRCeU5hbWUobnVsbCk7CiAgICAgICAgSW5ldFNvY2tldEFkZHJlc3MgYWRkcmVzcyA9IG5ldyBJbmV0U29ja2V0QWRkcmVzcyhsb2NhbGhvc3QsIHBvcnRGaWxlLmdldFBvcnQoKSk7CiAgICAgICAgc29ja2V0LmNvbm5lY3QoYWRkcmVzcywgQ09OTkVDVElPTl9USU1FT1VUKTsKICAgICAgICBMb2cuZGVidWcoIkNvbm5lY3RlZCIpOwogICAgICAgIHJldHVybiBzb2NrZXQ7CiAgICB9CgogICAgLyoKICAgICAqIFdpbGwgcmV0dXJuIGltbWVkaWF0ZWx5IGlmIGEgc2VydmVyIGFscmVhZHkgc2VlbXMgdG8gYmUgcnVubmluZywKICAgICAqIG90aGVyd2lzZSBmb3JrIGEgbmV3IHNlcnZlciBhbmQgYmxvY2sgdW50aWwgaXQgc2VlbXMgdG8gYmUgcnVubmluZy4KICAgICAqLwogICAgcHJpdmF0ZSB2b2lkIG1ha2VTdXJlU2VydmVySXNSdW5uaW5nKFBvcnRGaWxlIHBvcnRGaWxlKQogICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIEludGVycnVwdGVkRXhjZXB0aW9uIHsKCiAgICAgICAgaWYgKHBvcnRGaWxlLmV4aXN0cygpKSB7CiAgICAgICAgICAgIHBvcnRGaWxlLmxvY2soKTsKICAgICAgICAgICAgcG9ydEZpbGUuZ2V0VmFsdWVzKCk7CiAgICAgICAgICAgIHBvcnRGaWxlLnVubG9jaygpOwoKICAgICAgICAgICAgaWYgKHBvcnRGaWxlLmNvbnRhaW5zUG9ydEluZm8oKSkgewogICAgICAgICAgICAgICAgLy8gU2VydmVyIHNlZW1zIHRvIGFscmVhZHkgYmUgcnVubmluZwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBGb3JrIGEgbmV3IHNlcnZlciBhbmQgd2FpdCBmb3IgaXQgdG8gc3RhcnQKICAgICAgICBTamF2YWNDbGllbnQuZm9yayhzamF2YWNGb3JrQ21kLAogICAgICAgICAgICAgICAgICAgICAgICAgIHBvcnRGaWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgIHBvb2xzaXplLAogICAgICAgICAgICAgICAgICAgICAgICAgIGtlZXBhbGl2ZSk7CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCBzaHV0ZG93bigpIHsKICAgICAgICAvLyBOb3RoaW5nIHRvIGNsZWFuIHVwCiAgICB9CgogICAgLyoKICAgICAqIEZvcmsgYSBzZXJ2ZXIgcHJvY2VzcyBwcm9jZXNzIGFuZCB3YWl0IGZvciBzZXJ2ZXIgdG8gY29tZSBhcm91bmQKICAgICAqLwogICAgcHVibGljIHN0YXRpYyB2b2lkIGZvcmsoU3RyaW5nIHNqYXZhY0NtZCwgUG9ydEZpbGUgcG9ydEZpbGUsIGludCBwb29sc2l6ZSwgaW50IGtlZXBhbGl2ZSkKICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CiAgICAgICAgTGlzdDxTdHJpbmc+IGNtZCA9IG5ldyBBcnJheUxpc3Q8PigpOwogICAgICAgIGNtZC5hZGRBbGwoQXJyYXlzLmFzTGlzdChPcHRpb25IZWxwZXIudW5lc2NhcGVDbWRBcmcoc2phdmFjQ21kKS5zcGxpdCgiICIpKSk7CiAgICAgICAgY21kLmFkZCgiLS1zdGFydHNlcnZlcjoiCiAgICAgICAgICAgICAgKyAicG9ydGZpbGU9IiArIHBvcnRGaWxlLmdldEZpbGVuYW1lKCkKICAgICAgICAgICAgICArICIscG9vbHNpemU9IiArIHBvb2xzaXplCiAgICAgICAgICAgICAgKyAiLGtlZXBhbGl2ZT0iKyBrZWVwYWxpdmUpOwoKICAgICAgICBQcm9jZXNzIHNlcnZlclByb2Nlc3M7CiAgICAgICAgTG9nLmRlYnVnKCJTdGFydGluZyBzZXJ2ZXIuIENvbW1hbmQ6ICIgKyBTdHJpbmcuam9pbigiICIsIGNtZCkpOwogICAgICAgIHRyeSB7CiAgICAgICAgICAgIC8vIElmIHRoZSBjbWQgZm9yIHNvbWUgcmVhc29uIGNhbid0IGJlIGV4ZWN1dGVkIChmaWxlIGlzIG5vdCBmb3VuZCwKICAgICAgICAgICAgLy8gb3IgaXMgbm90IGV4ZWN1dGFibGUgZm9yIGluc3RhbmNlKSB0aGlzIHdpbGwgdGhyb3cgYW4KICAgICAgICAgICAgLy8gSU9FeGNlcHRpb24gYW5kIHAgPT0gbnVsbC4KICAgICAgICAgICAgc2VydmVyUHJvY2VzcyA9IG5ldyBQcm9jZXNzQnVpbGRlcihjbWQpCiAgICAgICAgICAgICAgICAgICAgLnJlZGlyZWN0RXJyb3JTdHJlYW0odHJ1ZSkKICAgICAgICAgICAgICAgICAgICAuc3RhcnQoKTsKICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgewogICAgICAgICAgICAvLyBNZXNzYWdlIGlzIHR5cGljYWxseSBzb21ldGhpbmcgbGlrZToKICAgICAgICAgICAgLy8gQ2Fubm90IHJ1biBwcm9ncmFtICJ4eXoiOiBlcnJvcj0yLCBObyBzdWNoIGZpbGUgb3IgZGlyZWN0b3J5CiAgICAgICAgICAgIExvZy5lcnJvcigiRmFpbGVkIHRvIGNyZWF0ZSBzZXJ2ZXIgcHJvY2VzczogIiArIGV4LmdldE1lc3NhZ2UoKSk7CiAgICAgICAgICAgIExvZy5kZWJ1ZyhleCk7CiAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbihleCk7CiAgICAgICAgfQoKICAgICAgICAvLyBzZXJ2ZXJQcm9jZXNzICE9IG51bGwgYXQgdGhpcyBwb2ludC4KICAgICAgICB0cnkgewogICAgICAgICAgICAvLyBUaHJvd3MgYW4gSU9FeGNlcHRpb24gaWYgbm8gdmFsaWQgdmFsdWVzIG1hdGVyaWFsaXplCiAgICAgICAgICAgIHBvcnRGaWxlLndhaXRGb3JWYWxpZFZhbHVlcygpOwogICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7CiAgICAgICAgICAgIC8vIFByb2Nlc3Mgd2FzIHN0YXJ0ZWQsIGJ1dCBzZXJ2ZXIgZmFpbGVkIHRvIGluaXRpYWxpemUuIFRoaXMgY291bGQKICAgICAgICAgICAgLy8gZm9yIGluc3RhbmNlIGJlIGR1ZSB0byB0aGUgSlZNIG5vdCBmaW5kaW5nIHRoZSBzZXJ2ZXIgY2xhc3MsCiAgICAgICAgICAgIC8vIG9yIHRoZSBzZXJ2ZXIgcnVubmluZyBpbiB0byBzb21lIGV4Y2VwdGlvbiBlYXJseSBvbi4KICAgICAgICAgICAgTG9nLmVycm9yKCJTamF2YWMgc2VydmVyIGZhaWxlZCB0byBpbml0aWFsaXplOiAiICsgZXguZ2V0TWVzc2FnZSgpKTsKICAgICAgICAgICAgTG9nLmVycm9yKCJQcm9jZXNzIG91dHB1dDoiKTsKICAgICAgICAgICAgUmVhZGVyIHNlcnZlclN0ZG91dFN0ZGVyciA9IG5ldyBJbnB1dFN0cmVhbVJlYWRlcihzZXJ2ZXJQcm9jZXNzLmdldElucHV0U3RyZWFtKCkpOwogICAgICAgICAgICB0cnkgKEJ1ZmZlcmVkUmVhZGVyIGJyID0gbmV3IEJ1ZmZlcmVkUmVhZGVyKHNlcnZlclN0ZG91dFN0ZGVycikpIHsKICAgICAgICAgICAgICAgIGJyLmxpbmVzKCkuZm9yRWFjaChMb2c6OmVycm9yKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBMb2cuZXJyb3IoIjxFbmQgb2YgcHJvY2VzcyBvdXRwdXQ+Iik7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBMb2cuZXJyb3IoIlByb2Nlc3MgZXhpdCBjb2RlOiAiICsgc2VydmVyUHJvY2Vzcy5leGl0VmFsdWUoKSk7CiAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxUaHJlYWRTdGF0ZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgICAvLyBTZXJ2ZXIgaXMgcHJlc3VtYWJseSBzdGlsbCBydW5uaW5nLgogICAgICAgICAgICB9CiAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiU2VydmVyIGZhaWxlZCB0byBpbml0aWFsaXplOiAiICsgZXguZ2V0TWVzc2FnZSgpLCBleCk7CiAgICAgICAgfQogICAgfQp9ClBLAwQKAAAIAAAGO6lKe/stZ98iAADfIgAAHgAAAGNvbS9zdW4vdG9vbHMvc2phdmFjL1V0aWwuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAxMiwgMjAxNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLnNqYXZhYzsKCmltcG9ydCBqYXZhLmlvLkZpbGU7CmltcG9ydCBqYXZhLmlvLlByaW50V3JpdGVyOwppbXBvcnQgamF2YS5pby5TdHJpbmdXcml0ZXI7CmltcG9ydCBqYXZhLm5pby5maWxlLlBhdGg7CmltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOwppbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb247CmltcG9ydCBqYXZhLnV0aWwuSGFzaFNldDsKaW1wb3J0IGphdmEudXRpbC5NYXA7CmltcG9ydCBqYXZhLnV0aWwuU2V0OwppbXBvcnQgamF2YS51dGlsLlN0cmluZ1Rva2VuaXplcjsKaW1wb3J0IGphdmEudXRpbC5mdW5jdGlvbi5GdW5jdGlvbjsKaW1wb3J0IGphdmEudXRpbC5yZWdleC5QYXR0ZXJuOwppbXBvcnQgamF2YS51dGlsLnN0cmVhbS5Db2xsZWN0b3JzOwppbXBvcnQgamF2YS51dGlsLnN0cmVhbS5TdHJlYW07CgovKioKICogVXRpbGl0aWVzLgogKgogKiAgPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24gcmlzay4KICogIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yCiAqICBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+CiAqLwpwdWJsaWMgY2xhc3MgVXRpbCB7CgogICAgcHVibGljIHN0YXRpYyBTdHJpbmcgdG9GaWxlU3lzdGVtUGF0aChTdHJpbmcgcGtnSWQpIHsKICAgICAgICBpZiAocGtnSWQgPT0gbnVsbCB8fCBwa2dJZC5sZW5ndGgoKT09MCkgcmV0dXJuIG51bGw7CiAgICAgICAgU3RyaW5nIHBuOwogICAgICAgIGlmIChwa2dJZC5jaGFyQXQoMCkgPT0gJzonKSB7CiAgICAgICAgICAgIC8vIFdoZW4gdGhlIG1vZHVsZSBpcyB0aGUgZGVmYXVsdCBlbXB0eSBtb2R1bGUuCiAgICAgICAgICAgIC8vIERvIG5vdCBwcmVwZW5kIHRoZSBtb2R1bGUgZGlyZWN0b3J5LCBiZWNhdXNlIHRoZXJlIGlzIG5vbmUuCiAgICAgICAgICAgIC8vIFRodXMgOmphdmEuZm9vLmJhciB0cmFuc2xhdGVzIHRvIGphdmEvZm9vL2JhciAob3IgXCkKICAgICAgICAgICAgcG4gPSBwa2dJZC5zdWJzdHJpbmcoMSkucmVwbGFjZSgnLicsRmlsZS5zZXBhcmF0b3JDaGFyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvLyBUaGVyZSBpcyBhIG1vZHVsZS4gVGh1cyBqZGsuYmFzZTpqYXZhLmZvby5iYXIgdHJhbnNsYXRlcwogICAgICAgICAgICAvLyBpbnRvIGpkay5iYXNlL2phdmEvZm9vL2JhcgogICAgICAgICAgICBpbnQgY3AgPSBwa2dJZC5pbmRleE9mKCc6Jyk7CiAgICAgICAgICAgIFN0cmluZyBtbiA9IHBrZ0lkLnN1YnN0cmluZygwLGNwKTsKICAgICAgICAgICAgcG4gPSBtbitGaWxlLnNlcGFyYXRvckNoYXIrcGtnSWQuc3Vic3RyaW5nKGNwKzEpLnJlcGxhY2UoJy4nLEZpbGUuc2VwYXJhdG9yQ2hhcik7CiAgICAgICAgfQogICAgICAgIHJldHVybiBwbjsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBqdXN0UGFja2FnZU5hbWUoU3RyaW5nIHBrZ05hbWUpIHsKICAgICAgICBpbnQgYyA9IHBrZ05hbWUuaW5kZXhPZigiOiIpOwogICAgICAgIGlmIChjID09IC0xKQogICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJFeHBlY3RlZCAnOicgaW4gcGFja2FnZSBuYW1lICgiICsgcGtnTmFtZSArICIpIik7CiAgICAgICAgcmV0dXJuIHBrZ05hbWUuc3Vic3RyaW5nKGMrMSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBTdHJpbmcgZXh0cmFjdFN0cmluZ09wdGlvbihTdHJpbmcgb3BOYW1lLCBTdHJpbmcgcykgewogICAgICAgIHJldHVybiBleHRyYWN0U3RyaW5nT3B0aW9uKG9wTmFtZSwgcywgbnVsbCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBTdHJpbmcgZXh0cmFjdFN0cmluZ09wdGlvbihTdHJpbmcgb3BOYW1lLCBTdHJpbmcgcywgU3RyaW5nIGRlZmx0KSB7CiAgICAgICAgaW50IHAgPSBzLmluZGV4T2Yob3BOYW1lKyI9Iik7CiAgICAgICAgaWYgKHAgPT0gLTEpIHJldHVybiBkZWZsdDsKICAgICAgICBwKz1vcE5hbWUubGVuZ3RoKCkrMTsKICAgICAgICBpbnQgcGUgPSBzLmluZGV4T2YoJywnLCBwKTsKICAgICAgICBpZiAocGUgPT0gLTEpIHBlID0gcy5sZW5ndGgoKTsKICAgICAgICByZXR1cm4gcy5zdWJzdHJpbmcocCwgcGUpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBleHRyYWN0Qm9vbGVhbk9wdGlvbihTdHJpbmcgb3BOYW1lLCBTdHJpbmcgcywgYm9vbGVhbiBkZWZsdCkgewogICAgICAgIFN0cmluZyBzdHIgPSBleHRyYWN0U3RyaW5nT3B0aW9uKG9wTmFtZSwgcyk7CiAgICAgICAgcmV0dXJuICJ0cnVlIi5lcXVhbHMoc3RyKSA/IHRydWUKICAgICAgICAgICAgIDogImZhbHNlIi5lcXVhbHMoc3RyKSA/IGZhbHNlCiAgICAgICAgICAgICA6IGRlZmx0OwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgaW50IGV4dHJhY3RJbnRPcHRpb24oU3RyaW5nIG9wTmFtZSwgU3RyaW5nIHMpIHsKICAgICAgICByZXR1cm4gZXh0cmFjdEludE9wdGlvbihvcE5hbWUsIHMsIDApOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgaW50IGV4dHJhY3RJbnRPcHRpb24oU3RyaW5nIG9wTmFtZSwgU3RyaW5nIHMsIGludCBkZWZsdCkgewogICAgICAgIGludCBwID0gcy5pbmRleE9mKG9wTmFtZSsiPSIpOwogICAgICAgIGlmIChwID09IC0xKSByZXR1cm4gZGVmbHQ7CiAgICAgICAgcCs9b3BOYW1lLmxlbmd0aCgpKzE7CiAgICAgICAgaW50IHBlID0gcy5pbmRleE9mKCcsJywgcCk7CiAgICAgICAgaWYgKHBlID09IC0xKSBwZSA9IHMubGVuZ3RoKCk7CiAgICAgICAgaW50IHYgPSAwOwogICAgICAgIHRyeSB7CiAgICAgICAgICAgIHYgPSBJbnRlZ2VyLnBhcnNlSW50KHMuc3Vic3RyaW5nKHAsIHBlKSk7CiAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHt9CiAgICAgICAgcmV0dXJuIHY7CiAgICB9CgogICAgLyoqCiAgICAgKiBFeHRyYWN0IHRoZSBwYWNrYWdlIG5hbWUgZnJvbSBhIGZ1bGx5IHF1YWxpZmllZCBjbGFzcyBuYW1lLgogICAgICoKICAgICAqIEV4YW1wbGU6IEdpdmVuICJwa2cuc3VicGtnLkEiIHRoaXMgbWV0aG9kIHJldHVybnMgIjpwa2cuc3VicGtnIi4KICAgICAqIEdpdmVuICJDIiB0aGlzIG1ldGhvZCByZXR1cm5zICI6Ii4KICAgICAqCiAgICAgKiBAcmV0dXJucyBwYWNrYWdlIG5hbWUgb2YgdGhlIGdpdmVuIGNsYXNzIG5hbWUKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBTdHJpbmcgcGtnTmFtZU9mQ2xhc3NOYW1lKFN0cmluZyBmcUNsYXNzTmFtZSkgewogICAgICAgIGludCBpID0gZnFDbGFzc05hbWUubGFzdEluZGV4T2YoJy4nKTsKICAgICAgICBTdHJpbmcgcGtnID0gaSA9PSAtMSA/ICIiIDogZnFDbGFzc05hbWUuc3Vic3RyaW5nKDAsIGkpOwogICAgICAgIHJldHVybiAiOiIgKyBwa2c7CiAgICB9CgogICAgLyoqCiAgICAgKiBDbGVhbiBvdXQgdW53YW50ZWQgc3ViIG9wdGlvbnMgc3VwcGxpZWQgaW5zaWRlIGEgcHJpbWFyeSBvcHRpb24uCiAgICAgKiBGb3IgZXhhbXBsZSB0byBvbmx5IGhhZCBwb3J0ZmlsZSByZW1haW5pbmcgZnJvbToKICAgICAqICAgIHNldHRpbmdzPSItLXNlcnZlcjppZD1mb28scG9ydGZpbGU9YmFyIgogICAgICogZG8gc2V0dGluZ3MgPSBjbGVhbk9wdGlvbnMoIi0tc2VydmVyOiIsVXRpbC5zZXQoIi1wb3J0ZmlsZSIpLHNldHRpbmdzKTsKICAgICAqICAgIG5vdyBzZXR0aW5ncyBlcXVhbHMgIi0tc2VydmVyOnBvcnRmaWxlPWJhciIKICAgICAqCiAgICAgKiBAcGFyYW0gYWxsb3dlZFN1Yk9wdGlvbnMgQSBzZXQgb2YgdGhlIGFsbG93ZWQgc3ViIG9wdGlvbnMsIGlkIHBvcnRmaWxlIGV0Yy4KICAgICAqIEBwYXJhbSBzIFRoZSBvcHRpb24gc2V0dGluZ3Mgc3RyaW5nLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBjbGVhblN1Yk9wdGlvbnMoU2V0PFN0cmluZz4gYWxsb3dlZFN1Yk9wdGlvbnMsIFN0cmluZyBzKSB7CiAgICAgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CiAgICAgICAgU3RyaW5nVG9rZW5pemVyIHN0ID0gbmV3IFN0cmluZ1Rva2VuaXplcihzLCAiLCIpOwogICAgICAgIHdoaWxlIChzdC5oYXNNb3JlVG9rZW5zKCkpIHsKICAgICAgICAgICAgU3RyaW5nIG8gPSBzdC5uZXh0VG9rZW4oKTsKICAgICAgICAgICAgaW50IHAgPSBvLmluZGV4T2YoJz0nKTsKICAgICAgICAgICAgaWYgKHA+MCkgewogICAgICAgICAgICAgICAgU3RyaW5nIGtleSA9IG8uc3Vic3RyaW5nKDAscCk7CiAgICAgICAgICAgICAgICBTdHJpbmcgdmFsID0gby5zdWJzdHJpbmcocCsxKTsKICAgICAgICAgICAgICAgIGlmIChhbGxvd2VkU3ViT3B0aW9ucy5jb250YWlucyhrZXkpKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHNiLmxlbmd0aCgpID4gMCkgc2IuYXBwZW5kKCcsJyk7CiAgICAgICAgICAgICAgICAgICAgc2IuYXBwZW5kKGtleSsiPSIrdmFsKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gc2IudG9TdHJpbmcoKTsKICAgIH0KCiAgICAvKioKICAgICAqIENvbnZlbmllbmNlIG1ldGhvZCB0byBjcmVhdGUgYSBzZXQgd2l0aCBzdHJpbmdzLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIFNldDxTdHJpbmc+IHNldChTdHJpbmcuLi4gc3MpIHsKICAgICAgICBTZXQ8U3RyaW5nPiBzZXQgPSBuZXcgSGFzaFNldDw+KCk7CiAgICAgICAgc2V0LmFkZEFsbChBcnJheXMuYXNMaXN0KHNzKSk7CiAgICAgICAgcmV0dXJuIHNldDsKICAgIH0KCiAgICAvKioKICAgICAqIE5vcm1hbGl6ZSB3aW5kb3dzIGRyaXZlIGxldHRlciBwYXRocyB0byB1cHBlciBjYXNlIHRvIGVuYWJsZSBzdHJpbmcKICAgICAqIGNvbXBhcmlzb24uCiAgICAgKgogICAgICogQHBhcmFtIGZpbGUgRmlsZSBuYW1lIHRvIG5vcm1hbGl6ZQogICAgICogQHJldHVybiBUaGUgbm9ybWFsaXplZCBzdHJpbmcgaWYgZmlsZSBoYXMgYSBkcml2ZSBsZXR0ZXIgYXQgdGhlIGJlZ2lubmluZywKICAgICAqICAgICAgICAgb3RoZXJ3aXNlIHRoZSBvcmlnaW5hbCBzdHJpbmcuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIG5vcm1hbGl6ZURyaXZlTGV0dGVyKFN0cmluZyBmaWxlKSB7CiAgICAgICAgaWYgKGZpbGUubGVuZ3RoKCkgPiAyICYmIGZpbGUuY2hhckF0KDEpID09ICc6JykgewogICAgICAgICAgICByZXR1cm4gQ2hhcmFjdGVyLnRvVXBwZXJDYXNlKGZpbGUuY2hhckF0KDApKSArIGZpbGUuc3Vic3RyaW5nKDEpOwogICAgICAgIH0gZWxzZSBpZiAoZmlsZS5sZW5ndGgoKSA+IDMgJiYgZmlsZS5jaGFyQXQoMCkgPT0gJyonCiAgICAgICAgICAgICAgICAgICAmJiBmaWxlLmNoYXJBdCgyKSA9PSAnOicpIHsKICAgICAgICAgICAgLy8gSGFuZGxlIGEgd2lsZGNhcmQgKiBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSBzdHJpbmcuCiAgICAgICAgICAgIHJldHVybiBmaWxlLnN1YnN0cmluZygwLCAxKSArIENoYXJhY3Rlci50b1VwcGVyQ2FzZShmaWxlLmNoYXJBdCgxKSkKICAgICAgICAgICAgICAgICAgICsgZmlsZS5zdWJzdHJpbmcoMik7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaWxlOwogICAgfQoKICAgIC8qKgogICAgICogTG9jYXRlIHRoZSBzZXR0aW5nIGZvciB0aGUgc2VydmVyIHByb3BlcnRpZXMuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGZpbmRTZXJ2ZXJTZXR0aW5ncyhTdHJpbmdbXSBhcmdzKSB7CiAgICAgICAgZm9yIChTdHJpbmcgcyA6IGFyZ3MpIHsKICAgICAgICAgICAgaWYgKHMuc3RhcnRzV2l0aCgiLS1zZXJ2ZXI6IikpIHsKICAgICAgICAgICAgICAgIHJldHVybiBzOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgPEU+IFNldDxFPiB1bmlvbihTZXQ8PyBleHRlbmRzIEU+IHMxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNldDw/IGV4dGVuZHMgRT4gczIpIHsKICAgICAgICBTZXQ8RT4gdW5pb24gPSBuZXcgSGFzaFNldDw+KCk7CiAgICAgICAgdW5pb24uYWRkQWxsKHMxKTsKICAgICAgICB1bmlvbi5hZGRBbGwoczIpOwogICAgICAgIHJldHVybiB1bmlvbjsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIDxFPiBTZXQ8RT4gc3VidHJhY3QoU2V0PD8gZXh0ZW5kcyBFPiBvcmlnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNldDw/IGV4dGVuZHMgRT4gdG9TdWJ0cmFjdCkgewogICAgICAgIFNldDxFPiBkaWZmZXJlbmNlID0gbmV3IEhhc2hTZXQ8PihvcmlnKTsKICAgICAgICBkaWZmZXJlbmNlLnJlbW92ZUFsbCh0b1N1YnRyYWN0KTsKICAgICAgICByZXR1cm4gZGlmZmVyZW5jZTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBnZXRTdGFja1RyYWNlKFRocm93YWJsZSB0KSB7CiAgICAgICAgU3RyaW5nV3JpdGVyIHN3ID0gbmV3IFN0cmluZ1dyaXRlcigpOwogICAgICAgIHQucHJpbnRTdGFja1RyYWNlKG5ldyBQcmludFdyaXRlcihzdykpOwogICAgICAgIHJldHVybiBzdy50b1N0cmluZygpOwogICAgfQoKICAgIC8vIFRPRE86IFJlbW92ZSB3aGVuIHJlZmFjdG9yaW5nIGZyb20gamF2YS5pby5GaWxlIHRvIGphdmEubmlvLmZpbGUuUGF0aC4KICAgIHB1YmxpYyBzdGF0aWMgRmlsZSBwYXRoVG9GaWxlKFBhdGggcGF0aCkgewogICAgICAgIHJldHVybiBwYXRoID09IG51bGwgPyBudWxsIDogcGF0aC50b0ZpbGUoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIDxFPiBTZXQ8RT4gaW50ZXJzZWN0aW9uKENvbGxlY3Rpb248PyBleHRlbmRzIEU+IGMxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb2xsZWN0aW9uPD8gZXh0ZW5kcyBFPiBjMikgewogICAgICAgIFNldDxFPiBpbnRlcnNlY3Rpb24gPSBuZXcgSGFzaFNldDxFPihjMSk7CiAgICAgICAgaW50ZXJzZWN0aW9uLnJldGFpbkFsbChjMik7CiAgICAgICAgcmV0dXJuIGludGVyc2VjdGlvbjsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIDxJLCBUPiBNYXA8SSwgVD4gaW5kZXhCeShDb2xsZWN0aW9uPD8gZXh0ZW5kcyBUPiBjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRnVuY3Rpb248PyBzdXBlciBULCA/IGV4dGVuZHMgST4gaW5kZXhGdW5jdGlvbikgewogICAgICAgIHJldHVybiBjLnN0cmVhbSgpLmNvbGxlY3QoQ29sbGVjdG9ycy48VCwgSSwgVD50b01hcChpbmRleEZ1bmN0aW9uLCBvIC0+IG8pKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBmaWxlU3VmZml4KFBhdGggZmlsZSkgewogICAgICAgIFN0cmluZyBmaWxlTmFtZVN0ciA9IGZpbGUuZ2V0RmlsZU5hbWUoKS50b1N0cmluZygpOwogICAgICAgIGludCBkb3RJbmRleCA9IGZpbGVOYW1lU3RyLmluZGV4T2YoJy4nKTsKICAgICAgICByZXR1cm4gZG90SW5kZXggPT0gLTEgPyAiIiA6IGZpbGVOYW1lU3RyLnN1YnN0cmluZyhkb3RJbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBTdHJlYW08U3RyaW5nPiBnZXRMaW5lcyhTdHJpbmcgc3RyKSB7CiAgICAgICAgcmV0dXJuIHN0ci5pc0VtcHR5KCkKICAgICAgICAgICAgICAgID8gU3RyZWFtLmVtcHR5KCkKICAgICAgICAgICAgICAgIDogU3RyZWFtLm9mKHN0ci5zcGxpdChQYXR0ZXJuLnF1b3RlKFN5c3RlbS5saW5lU2VwYXJhdG9yKCkpKSk7CiAgICB9Cn0KUEsDBAoAAAgAAAY7qUrqeR+tGwgAABsIAAApAAAAY29tL3N1bi90b29scy9zamF2YWMvQXV0b0ZsdXNoV3JpdGVyLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5zamF2YWM7CgppbXBvcnQgamF2YS5pby5GaWx0ZXJXcml0ZXI7CmltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwppbXBvcnQgamF2YS5pby5Xcml0ZXI7CgpwdWJsaWMgY2xhc3MgQXV0b0ZsdXNoV3JpdGVyIGV4dGVuZHMgRmlsdGVyV3JpdGVyIHsKCiAgICBwdWJsaWMgQXV0b0ZsdXNoV3JpdGVyKFdyaXRlciBvdXQpIHsKICAgICAgICBzdXBlcihvdXQpOwogICAgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGUoaW50IGMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgc3VwZXIud3JpdGUoYyk7CiAgICAgICAgaWYgKGMgPT0gJ1xuJyB8fCBjID09ICdccicpCiAgICAgICAgICAgIGZsdXNoKCk7CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZShTdHJpbmcgc3RyLCBpbnQgb2ZmLCBpbnQgbGVuKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgIHN1cGVyLndyaXRlKHN0ciwgb2ZmLCBsZW4pOwogICAgICAgIGlmIChzdHIuY29udGFpbnMoIlxuIikgfHwgc3RyLmNvbnRhaW5zKCJcciIpKQogICAgICAgICAgICBmbHVzaCgpOwogICAgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGUoY2hhcltdIGNidWYsIGludCBvZmYsIGludCBsZW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgc3VwZXIud3JpdGUoY2J1Ziwgb2ZmLCBsZW4pOwogICAgICAgIGZvciAoY2hhciBjIDogY2J1ZikgewogICAgICAgICAgICBpZiAoYyA9PSAnXG4nIHx8IGMgPT0gJ1xyJykgewogICAgICAgICAgICAgICAgZmx1c2goKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQp9ClBLAwQKAAAIAADSfU1KYVhCFHsIAAB7CAAAHgAAAGNvbS9zdW4vdG9vbHMvc2phdmFjL01haW4uamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAxMiwgMjAxNCwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLnNqYXZhYzsKCmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5zamF2YWMub3B0aW9ucy5PcHRpb24uU1RBUlRTRVJWRVI7CgppbXBvcnQgamF2YS51dGlsLkFycmF5czsKCmltcG9ydCBjb20uc3VuLnRvb2xzLnNqYXZhYy5jbGllbnQuQ2xpZW50TWFpbjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuc2phdmFjLnNlcnZlci5TZXJ2ZXJNYWluOwoKLyoqCiAqIFRoZSBhcHBsaWNhdGlvbiBlbnRyeSBwb2ludCBvZiB0aGUgc21hcnQgamF2YWMgd3JhcHBlciB0b29sLgogKgogKiAgPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24gcmlzay4KICogIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yCiAqICBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+CiAqLwpwdWJsaWMgY2xhc3MgTWFpbiB7CgogICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nLi4uIGFyZ3MpICB7CiAgICAgICAgU3lzdGVtLmV4aXQoZ28oYXJncykpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgaW50IGdvKFN0cmluZ1tdIGFyZ3MpIHsKCiAgICAgICAgLy8gU2VydmVyIG9yIGNsaWVudCBtb2RlPwogICAgICAgIGJvb2xlYW4gc2VydmVyTW9kZSA9IEFycmF5cy5hc0xpc3QoYXJncykKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuc3RyZWFtKCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuYW55TWF0Y2goYXJnIC0+IGFyZy5zdGFydHNXaXRoKFNUQVJUU0VSVkVSLmFyZykpOwoKICAgICAgICByZXR1cm4gc2VydmVyTW9kZSA/IFNlcnZlck1haW4ucnVuKGFyZ3MpIDogQ2xpZW50TWFpbi5ydW4oYXJncyk7CiAgICB9Cn0KUEsDBAoAAAgAAAY7qUo2zBA6IRgAACEYAAApAAAAY29tL3N1bi90b29scy9zamF2YWMvQ2xlYW5Qcm9wZXJ0aWVzLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDEsIDIwMTYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5zamF2YWM7CgppbXBvcnQgamF2YS5pby5CdWZmZXJlZFdyaXRlcjsKaW1wb3J0IGphdmEuaW8uRmlsZTsKaW1wb3J0IGphdmEuaW8uRmlsZUlucHV0U3RyZWFtOwppbXBvcnQgamF2YS5pby5GaWxlT3V0cHV0U3RyZWFtOwppbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtV3JpdGVyOwppbXBvcnQgamF2YS5pby5Xcml0ZXI7CmltcG9ydCBqYXZhLm5ldC5VUkk7CmltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OwppbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOwppbXBvcnQgamF2YS51dGlsLkhhc2hTZXQ7CmltcG9ydCBqYXZhLnV0aWwuTGlzdDsKaW1wb3J0IGphdmEudXRpbC5NYXA7CmltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKaW1wb3J0IGphdmEudXRpbC5TZXQ7CgppbXBvcnQgY29tLnN1bi50b29scy5zamF2YWMuY29tcC5Db21waWxhdGlvblNlcnZpY2U7CmltcG9ydCBjb20uc3VuLnRvb2xzLnNqYXZhYy5vcHRpb25zLk9wdGlvbnM7CmltcG9ydCBjb20uc3VuLnRvb2xzLnNqYXZhYy5wdWJhcGkuUHViQXBpOwoKLyoqCiAqIFRoZSBjbGVhbiBwcm9wZXJ0aWVzIHRyYW5zZm9ybSBzaG91bGQgbm90IGJlIG5lY2Vzc2FyeS4KICogRXZlbnR1YWxseSB3ZSB3aWxsIGNsZWFudXAgdGhlIHByb3BlcnR5IGZpbGUgc291cmNlcyBpbiB0aGUgT3BlbkpESyBpbnN0ZWFkLgogKgogKiAgPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24gcmlzay4KICogIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yCiAqICBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+CiAqLwpwdWJsaWMgY2xhc3MgQ2xlYW5Qcm9wZXJ0aWVzIGltcGxlbWVudHMgVHJhbnNmb3JtZXIgewogICAgcHVibGljIHZvaWQgc2V0RXh0cmEoU3RyaW5nIGUpIHsKICAgICAgICAvLyBBbnkgZXh0cmEgaW5mb3JtYXRpb24gaXMgaWdub3JlZCBmb3IgY2xlYW4gcHJvcGVydGllcy4KICAgIH0KCiAgICBwdWJsaWMgdm9pZCBzZXRFeHRyYShPcHRpb25zIGEpIHsKICAgICAgICAvLyBBbnkgZXh0cmEgaW5mb3JtYXRpb24gaXMgaWdub3JlZCBmb3IgY2xlYW4gcHJvcGVydGllcy4KICAgIH0KCiAgICBwdWJsaWMgYm9vbGVhbiB0cmFuc2Zvcm0oQ29tcGlsYXRpb25TZXJ2aWNlIHNqYXZhYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYXA8U3RyaW5nLFNldDxVUkk+PiBwa2dTcmNzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNldDxVUkk+ICAgICAgICAgICAgIHZpc2libGVTcmNzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1hcDxTdHJpbmcsU2V0PFN0cmluZz4+IG9sZFBhY2thZ2VEZXBlbmRlbmNpZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVVJJIGRlc3RSb290LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1hcDxTdHJpbmcsU2V0PFVSST4+ICAgIHBhY2thZ2VBcnRpZmFjdHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWFwPFN0cmluZywgTWFwPFN0cmluZywgU2V0PFN0cmluZz4+PiBwYWNrYWdlRGVwZW5kZW5jaWVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1hcDxTdHJpbmcsIE1hcDxTdHJpbmcsIFNldDxTdHJpbmc+Pj4gcGFja2FnZUNwRGVwZW5kZW5jaWVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1hcDxTdHJpbmcsIFB1YkFwaT4gcGFja2FnZVB1YmxpY0FwaXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWFwPFN0cmluZywgUHViQXBpPiBkZXBlbmRlbmN5UHVibGljQXBpcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgZGVidWdMZXZlbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGluY3JlbWVudGFsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBudW1Db3JlcykgewogICAgICAgIGJvb2xlYW4gcmMgPSB0cnVlOwogICAgICAgIGZvciAoU3RyaW5nIHBrZ05hbWUgOiBwa2dTcmNzLmtleVNldCgpKSB7CiAgICAgICAgICAgIFN0cmluZyBwa2dOYW1lRiA9IHBrZ05hbWUucmVwbGFjZSgnLicsRmlsZS5zZXBhcmF0b3JDaGFyKTsKICAgICAgICAgICAgZm9yIChVUkkgdSA6IHBrZ1NyY3MuZ2V0KHBrZ05hbWUpKSB7CiAgICAgICAgICAgICAgICBGaWxlIHNyYyA9IG5ldyBGaWxlKHUpOwogICAgICAgICAgICAgICAgYm9vbGVhbiByID0gY2xlYW4ocGtnTmFtZSwgcGtnTmFtZUYsIHNyYywgbmV3IEZpbGUoZGVzdFJvb3QpLCBkZWJ1Z0xldmVsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2FnZUFydGlmYWN0cyk7CiAgICAgICAgICAgICAgICBpZiAociA9PSBmYWxzZSkgewogICAgICAgICAgICAgICAgICAgIHJjID0gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJjOwogICAgfQoKICAgIGJvb2xlYW4gY2xlYW4oU3RyaW5nIHBrZ05hbWUsCiAgICAgICAgICAgICAgICAgIFN0cmluZyBwa2dOYW1lRiwKICAgICAgICAgICAgICAgICAgRmlsZSBzcmMsCiAgICAgICAgICAgICAgICAgIEZpbGUgZGVzdFJvb3QsCiAgICAgICAgICAgICAgICAgIGludCBkZWJ1Z0xldmVsLAogICAgICAgICAgICAgICAgICBNYXA8U3RyaW5nLFNldDxVUkk+PiBwYWNrYWdlQXJ0aWZhY3RzKSB7CiAgICAgICAgLy8gTG9hZCB0aGUgcHJvcGVydGllcyBmaWxlLgogICAgICAgIFByb3BlcnRpZXMgcCA9IG5ldyBQcm9wZXJ0aWVzKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgcC5sb2FkKG5ldyBGaWxlSW5wdXRTdHJlYW0oc3JjKSk7CiAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICBMb2cuZXJyb3IoIkVycm9yIHJlYWRpbmcgZmlsZSAiK3NyYy5nZXRQYXRoKCkpOwogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICAvLyBTb3J0IHRoZSBwcm9wZXJ0aWVzIGluIGluY3JlYXNpbmcga2V5IG9yZGVyLgogICAgICAgIExpc3Q8U3RyaW5nPiBzb3J0ZWRLZXlzID0gbmV3IEFycmF5TGlzdDw+KCk7CiAgICAgICAgZm9yIChPYmplY3Qga2V5IDogcC5rZXlTZXQoKSkgewogICAgICAgICAgICBzb3J0ZWRLZXlzLmFkZCgoU3RyaW5nKWtleSk7CiAgICAgICAgfQogICAgICAgIENvbGxlY3Rpb25zLnNvcnQoc29ydGVkS2V5cyk7CgogICAgICAgIC8vIENvbGxlY3QgdGhlIHByb3BlcnRpZXMgaW50byBhIHN0cmluZyBidWZmZXIuCiAgICAgICAgU3RyaW5nQnVpbGRlciBkYXRhID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKICAgICAgICBmb3IgKFN0cmluZyBrZXkgOiBzb3J0ZWRLZXlzKSB7CiAgICAgICAgICAgIGRhdGEuYXBwZW5kKENvbXBpbGVQcm9wZXJ0aWVzLmVzY2FwZShrZXkpKQogICAgICAgICAgICAgICAgLmFwcGVuZCgiOiIpCiAgICAgICAgICAgICAgICAuYXBwZW5kKENvbXBpbGVQcm9wZXJ0aWVzLmVzY2FwZSgoU3RyaW5nKSBwLmdldChrZXkpKSkKICAgICAgICAgICAgICAgIC5hcHBlbmQoIlxuIik7CiAgICAgICAgfQoKICAgICAgICBTdHJpbmcgZGVzdEZpbGVuYW1lID0gZGVzdFJvb3QuZ2V0UGF0aCgpK0ZpbGUuc2VwYXJhdG9yK3BrZ05hbWVGK0ZpbGUuc2VwYXJhdG9yK3NyYy5nZXROYW1lKCk7CiAgICAgICAgRmlsZSBkZXN0ID0gbmV3IEZpbGUoZGVzdEZpbGVuYW1lKTsKCiAgICAgICAgLy8gTWFrZSBzdXJlIHRoZSBkZXN0IGRpcmVjdG9yaWVzIGV4aXN0LgogICAgICAgIGlmICghZGVzdC5nZXRQYXJlbnRGaWxlKCkuaXNEaXJlY3RvcnkoKSkgewogICAgICAgICAgICBpZiAoIWRlc3QuZ2V0UGFyZW50RmlsZSgpLm1rZGlycygpKSB7CiAgICAgICAgICAgICAgICBMb2cuZXJyb3IoIkNvdWxkIG5vdCBjcmVhdGUgdGhlIGRpcmVjdG9yeSAiK2Rlc3QuZ2V0UGFyZW50RmlsZSgpLmdldFBhdGgoKSk7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIFNldDxVUkk+IGFzID0gcGFja2FnZUFydGlmYWN0cy5nZXQocGtnTmFtZSk7CiAgICAgICAgaWYgKGFzID09IG51bGwpIHsKICAgICAgICAgICAgYXMgPSBuZXcgSGFzaFNldDw+KCk7CiAgICAgICAgICAgIHBhY2thZ2VBcnRpZmFjdHMucHV0KHBrZ05hbWUsIGFzKTsKICAgICAgICB9CiAgICAgICAgYXMuYWRkKGRlc3QudG9VUkkoKSk7CgogICAgICAgIGlmIChkZXN0LmV4aXN0cygpICYmIGRlc3QubGFzdE1vZGlmaWVkKCkgPiBzcmMubGFzdE1vZGlmaWVkKCkpIHsKICAgICAgICAgICAgLy8gQSBjbGVhbmVkIHByb3BlcnR5IGZpbGUgZXhpc3RzLCBhbmQgaXRzIHRpbWVzdGFtcCBpcyBuZXdlciB0aGFuIHRoZSBzb3VyY2UuCiAgICAgICAgICAgIC8vIEFzc3VtZSB0aGF0IHdlIGRvIG5vdCBuZWVkIHRvIGNsZWFuIQogICAgICAgICAgICAvLyBUaHVzIHdlIGFyZSBkb25lLgogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIExvZy5pbmZvKCJDbGVhbmluZyBwcm9wZXJ0eSBmaWxlICIrcGtnTmFtZUYrRmlsZS5zZXBhcmF0b3Irc3JjLmdldE5hbWUoKSk7CiAgICAgICAgdHJ5IChXcml0ZXIgd3JpdGVyID0gbmV3IEJ1ZmZlcmVkV3JpdGVyKG5ldyBPdXRwdXRTdHJlYW1Xcml0ZXIobmV3IEZpbGVPdXRwdXRTdHJlYW0oZGVzdCkpKSkgewogICAgICAgICAgICB3cml0ZXIud3JpdGUoZGF0YS50b1N0cmluZygpKTsKICAgICAgICB9IGNhdGNoICggSU9FeGNlcHRpb24gZSApIHsKICAgICAgICAgICAgTG9nLmVycm9yKCJDb3VsZCBub3Qgd3JpdGUgZmlsZSAiK2Rlc3QuZ2V0UGF0aCgpKTsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KfQpQSwMECgAACAAABjupSk0iilixLgAAsS4AACAAAABjb20vc3VuL3Rvb2xzL3NqYXZhYy9Tb3VyY2UuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAxMiwgMjAxNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLnNqYXZhYzsKCmltcG9ydCBqYXZhLmlvLkZpbGU7CmltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwppbXBvcnQgamF2YS5uaW8uZmlsZS5GaWxlU3lzdGVtOwppbXBvcnQgamF2YS5uaW8uZmlsZS5GaWxlVmlzaXRSZXN1bHQ7CmltcG9ydCBqYXZhLm5pby5maWxlLkZpbGVzOwppbXBvcnQgamF2YS5uaW8uZmlsZS5QYXRoOwppbXBvcnQgamF2YS5uaW8uZmlsZS5QYXRoTWF0Y2hlcjsKaW1wb3J0IGphdmEubmlvLmZpbGUuU2ltcGxlRmlsZVZpc2l0b3I7CmltcG9ydCBqYXZhLm5pby5maWxlLmF0dHJpYnV0ZS5CYXNpY0ZpbGVBdHRyaWJ1dGVzOwppbXBvcnQgamF2YS51dGlsLlNldDsKaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKaW1wb3J0IGphdmEudXRpbC5MaXN0OwppbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKaW1wb3J0IGphdmEudXRpbC5NYXA7CmltcG9ydCBqYXZhLnV0aWwucmVnZXguUGF0dGVyblN5bnRheEV4Y2VwdGlvbjsKCi8qKiBBIFNvdXJjZSBvYmplY3QgbWFpbnRhaW5zIGluZm9ybWF0aW9uIGFib3V0IGEgc291cmNlIGZpbGUuCiAqIEZvciBleGFtcGxlIHdoaWNoIHBhY2thZ2UgaXQgYmVsb25ncyB0byBhbmQga2luZCBvZiBzb3VyY2UgaXQgaXMuCiAqIFRoZSBjbGFzcyBhbHNvIGtub3dzIGhvdyB0byBmaW5kIHNvdXJjZSBmaWxlcyAoc2NhblJvb3QpIGdpdmVuIGluY2x1ZGUvZXhjbHVkZQogKiBwYXR0ZXJucyBhbmQgYSByb290LgogKgogKiAgPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24gcmlzay4KICogIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yCiAqICBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+CiAqLwpwdWJsaWMgY2xhc3MgU291cmNlIGltcGxlbWVudHMgQ29tcGFyYWJsZTxTb3VyY2U+IHsKICAgIC8vIFRoZSBwYWNrYWdlIHRoZSBzb3VyY2UgYmVsb25ncyB0by4KICAgcHJpdmF0ZSBQYWNrYWdlIHBrZzsKICAgIC8vIE5hbWUgb2YgdGhpcyBzb3VyY2UgZmlsZSwgcmVsYXRpdmUgaXRzIHNvdXJjZSByb290LgogICAgLy8gRm9yIGV4YW1wbGU6IGphdmEvbGFuZy9PYmplY3QuamF2YQogICAgLy8gT3IgaWYgdGhlIHNvdXJjZSBmaWxlIGlzIGluc2lkZSBhIG1vZHVsZToKICAgIC8vIGpkay5iYXNlL2phdmEvbGFuZy9PYmplY3QuamF2YQogICAgcHJpdmF0ZSBTdHJpbmcgbmFtZTsKICAgIC8vIFdoYXQga2luZCBvZiBmaWxlIGlzIHRoaXMuCiAgICBwcml2YXRlIFN0cmluZyBzdWZmaXg7CiAgICAvLyBXaGVuIHRoaXMgc291cmNlIGZpbGUgd2FzIGxhc3RfbW9kaWZpZWQKICAgIHByaXZhdGUgbG9uZyBsYXN0TW9kaWZpZWQ7CiAgICAvLyBUaGUgc291cmNlIEZpbGUuCiAgICBwcml2YXRlIEZpbGUgZmlsZTsKICAgIC8vIElmIHRoZSBzb3VyY2UgaXMgZ2VuZXJhdGVkLgogICAgcHJpdmF0ZSBib29sZWFuIGlzR2VuZXJhdGVkOwogICAgLy8gSWYgdGhlIHNvdXJjZSBpcyBvbmx5IGxpbmtlZCB0bywgbm90IGNvbXBpbGVkLgogICAgcHJpdmF0ZSBib29sZWFuIGxpbmtlZE9ubHk7CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG8pIHsKICAgICAgICByZXR1cm4gKG8gaW5zdGFuY2VvZiBTb3VyY2UpICYmIG5hbWUuZXF1YWxzKCgoU291cmNlKW8pLm5hbWUpOwogICAgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIGludCBjb21wYXJlVG8oU291cmNlIG8pIHsKICAgICAgICByZXR1cm4gbmFtZS5jb21wYXJlVG8oby5uYW1lKTsKICAgIH0KCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgICAgcmV0dXJuIG5hbWUuaGFzaENvZGUoKTsKICAgIH0KCiAgICBwdWJsaWMgU291cmNlKE1vZHVsZSBtLCBTdHJpbmcgbiwgRmlsZSBmKSB7CiAgICAgICAgbmFtZSA9IG47CiAgICAgICAgaW50IGRwID0gbi5sYXN0SW5kZXhPZigiLiIpOwogICAgICAgIGlmIChkcCAhPSAtMSkgewogICAgICAgICAgICBzdWZmaXggPSBuLnN1YnN0cmluZyhkcCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc3VmZml4ID0gIiI7CiAgICAgICAgfQogICAgICAgIGZpbGUgPSBmOwogICAgICAgIGxhc3RNb2RpZmllZCA9IGYubGFzdE1vZGlmaWVkKCk7CiAgICAgICAgbGlua2VkT25seSA9IGZhbHNlOwogICAgfQoKICAgIHB1YmxpYyBTb3VyY2UoUGFja2FnZSBwLCBTdHJpbmcgbiwgbG9uZyBsbSkgewogICAgICAgIHBrZyA9IHA7CiAgICAgICAgbmFtZSA9IG47CiAgICAgICAgaW50IGRwID0gbi5sYXN0SW5kZXhPZigiLiIpOwogICAgICAgIGlmIChkcCAhPSAtMSkgewogICAgICAgICAgICBzdWZmaXggPSBuLnN1YnN0cmluZyhkcCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc3VmZml4ID0gIiI7CiAgICAgICAgfQogICAgICAgIGZpbGUgPSBudWxsOwogICAgICAgIGxhc3RNb2RpZmllZCA9IGxtOwogICAgICAgIGxpbmtlZE9ubHkgPSBmYWxzZTsKICAgICAgICBpbnQgbHMgPSBuLmxhc3RJbmRleE9mKCcvJyk7CiAgICB9CgogICAgcHVibGljIFN0cmluZyBuYW1lKCkgeyByZXR1cm4gbmFtZTsgfQogICAgcHVibGljIFN0cmluZyBzdWZmaXgoKSB7IHJldHVybiBzdWZmaXg7IH0KICAgIHB1YmxpYyBQYWNrYWdlIHBrZygpIHsgcmV0dXJuIHBrZzsgfQogICAgcHVibGljIEZpbGUgICBmaWxlKCkgeyByZXR1cm4gZmlsZTsgfQogICAgcHVibGljIGxvbmcgbGFzdE1vZGlmaWVkKCkgewogICAgICAgIHJldHVybiBsYXN0TW9kaWZpZWQ7CiAgICB9CgogICAgcHVibGljIHZvaWQgc2V0UGFja2FnZShQYWNrYWdlIHApIHsKICAgICAgICBwa2cgPSBwOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIG1hcmtBc0dlbmVyYXRlZCgpIHsKICAgICAgICBpc0dlbmVyYXRlZCA9IHRydWU7CiAgICB9CgogICAgcHVibGljIGJvb2xlYW4gaXNHZW5lcmF0ZWQoKSB7CiAgICAgICAgcmV0dXJuIGlzR2VuZXJhdGVkOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIG1hcmtBc0xpbmtlZE9ubHkoKSB7CiAgICAgICAgbGlua2VkT25seSA9IHRydWU7CiAgICB9CgogICAgcHVibGljIGJvb2xlYW4gaXNMaW5rZWRPbmx5KCkgewogICAgICAgIHJldHVybiBsaW5rZWRPbmx5OwogICAgfQoKICAgIHByaXZhdGUgdm9pZCBzYXZlKFN0cmluZ0J1aWxkZXIgYikgewogICAgICAgIFN0cmluZyBDTCA9IGxpbmtlZE9ubHk/IkwiOiJDIjsKICAgICAgICBTdHJpbmcgR1MgPSBpc0dlbmVyYXRlZD8iRyI6IlMiOwogICAgICAgIGIuYXBwZW5kKEdTKyIgIitDTCsiICIrbmFtZSsiICIrZmlsZS5sYXN0TW9kaWZpZWQoKSsiXG4iKTsKICAgIH0KICAgIC8vIFBhcnNlIGEgbGluZSB0aGF0IGxvb2tzIGxpa2UgdGhpczoKICAgIC8vIFMgQyAvY29kZS9hbGZhL0EuamF2YSAxMzU3NjMxMjI4MDAwCiAgICBzdGF0aWMgcHVibGljIFNvdXJjZSBsb2FkKFBhY2thZ2UgbGFzdFBhY2thZ2UsIFN0cmluZyBsLCBib29sZWFuIGlzR2VuZXJhdGVkKSB7CiAgICAgICAgaW50IHNwID0gbC5pbmRleE9mKCcgJyw0KTsKICAgICAgICBpZiAoc3AgPT0gLTEpIHJldHVybiBudWxsOwogICAgICAgIFN0cmluZyBuYW1lID0gbC5zdWJzdHJpbmcoNCxzcCk7CiAgICAgICAgbG9uZyBsYXN0X21vZGlmaWVkID0gTG9uZy5wYXJzZUxvbmcobC5zdWJzdHJpbmcoc3ArMSkpOwoKICAgICAgICBib29sZWFuIGlzTGlua2VkT25seSA9IGZhbHNlOwogICAgICAgIGlmIChsLmNoYXJBdCgyKSA9PSAnTCcpIHsKICAgICAgICAgICAgaXNMaW5rZWRPbmx5ID0gdHJ1ZTsKICAgICAgICB9IGVsc2UgaWYgKGwuY2hhckF0KDIpID09ICdDJykgewogICAgICAgICAgICBpc0xpbmtlZE9ubHkgPSBmYWxzZTsKICAgICAgICB9IGVsc2UgcmV0dXJuIG51bGw7CgogICAgICAgIFNvdXJjZSBzID0gbmV3IFNvdXJjZShsYXN0UGFja2FnZSwgbmFtZSwgbGFzdF9tb2RpZmllZCk7CiAgICAgICAgcy5maWxlID0gbmV3IEZpbGUobmFtZSk7CiAgICAgICAgaWYgKGlzR2VuZXJhdGVkKSBzLm1hcmtBc0dlbmVyYXRlZCgpOwogICAgICAgIGlmIChpc0xpbmtlZE9ubHkpIHMubWFya0FzTGlua2VkT25seSgpOwogICAgICAgIHJldHVybiBzOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBzYXZlU291cmNlcyhNYXA8U3RyaW5nLFNvdXJjZT4gc291cmNlcywgU3RyaW5nQnVpbGRlciBiKSB7CiAgICAgICAgTGlzdDxTdHJpbmc+IHNvcnRlZF9zb3VyY2VzID0gbmV3IEFycmF5TGlzdDw+KCk7CiAgICAgICAgZm9yIChTdHJpbmcga2V5IDogc291cmNlcy5rZXlTZXQoKSkgewogICAgICAgICAgICBzb3J0ZWRfc291cmNlcy5hZGQoa2V5KTsKICAgICAgICB9CiAgICAgICAgQ29sbGVjdGlvbnMuc29ydChzb3J0ZWRfc291cmNlcyk7CiAgICAgICAgZm9yIChTdHJpbmcga2V5IDogc29ydGVkX3NvdXJjZXMpIHsKICAgICAgICAgICAgU291cmNlIHMgPSBzb3VyY2VzLmdldChrZXkpOwogICAgICAgICAgICBzLnNhdmUoYik7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogUmVjdXJzZSBpbnRvIHRoZSBkaXJlY3Rvcnkgcm9vdCBhbmQgZmluZCBhbGwgZmlsZXMgbWF0Y2hpbmUgdGhlIGV4Y2wvaW5jbC9leGNsZmlsZXMvaW5jbGZpbGVzIHJ1bGVzLgogICAgICogRGV0ZWN0cyB0aGUgZXhpc3RlbmNlIG9mIG1vZHVsZS1pbmZvLmphdmEgZmlsZXMgYW5kIHByZXN1bWVzIHRoYXQgdGhlIGRpcmVjdG9yeSBpdCByZXNpZGVzIGluCiAgICAgKiBpcyB0aGUgbmFtZSBvZiB0aGUgY3VycmVudCBtb2R1bGUuCiAgICAgKi8KICAgIHN0YXRpYyBwdWJsaWMgdm9pZCBzY2FuUm9vdChGaWxlIHJvb3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU2V0PFN0cmluZz4gc3VmZml4ZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTGlzdDxTdHJpbmc+IGV4Y2x1ZGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExpc3Q8U3RyaW5nPiBpbmNsdWRlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYXA8U3RyaW5nLFNvdXJjZT4gZm91bmRGaWxlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYXA8U3RyaW5nLE1vZHVsZT4gZm91bmRNb2R1bGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIE1vZHVsZSBjdXJyZW50TW9kdWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gcGVybWl0U291cmNlc1dpdGhvdXRQYWNrYWdlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gaW5HZW5zcmMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBpbkxpbmtzcmMpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIFByb2JsZW1FeGNlcHRpb24gewoKICAgICAgICBpZiAocm9vdCA9PSBudWxsKQogICAgICAgICAgICByZXR1cm47CgogICAgICAgIEZpbGVTeXN0ZW0gZnMgPSByb290LnRvUGF0aCgpLmdldEZpbGVTeXN0ZW0oKTsKCiAgICAgICAgaWYgKGluY2x1ZGVzLmlzRW1wdHkoKSkgewogICAgICAgICAgICBpbmNsdWRlcyA9IENvbGxlY3Rpb25zLnNpbmdsZXRvbkxpc3QoIioqIik7CiAgICAgICAgfQoKICAgICAgICBMaXN0PFBhdGhNYXRjaGVyPiBpbmNsdWRlTWF0Y2hlcnMgPSBjcmVhdGVQYXRoTWF0Y2hlcnMoZnMsIGluY2x1ZGVzKTsKICAgICAgICBMaXN0PFBhdGhNYXRjaGVyPiBleGNsdWRlTWF0Y2hlcnMgPSBjcmVhdGVQYXRoTWF0Y2hlcnMoZnMsIGV4Y2x1ZGVzKTsKCiAgICAgICAgRmlsZXMud2Fsa0ZpbGVUcmVlKHJvb3QudG9QYXRoKCksIG5ldyBTaW1wbGVGaWxlVmlzaXRvcjxQYXRoPigpIHsKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHB1YmxpYyBGaWxlVmlzaXRSZXN1bHQgdmlzaXRGaWxlKFBhdGggZmlsZSwgQmFzaWNGaWxlQXR0cmlidXRlcyBhdHRycykgdGhyb3dzIElPRXhjZXB0aW9uIHsKCiAgICAgICAgICAgICAgICBQYXRoIHJlbFRvUm9vdCA9IHJvb3QudG9QYXRoKCkucmVsYXRpdml6ZShmaWxlKTsKCiAgICAgICAgICAgICAgICBpZiAoaW5jbHVkZU1hdGNoZXJzLnN0cmVhbSgpLmFueU1hdGNoKGltIC0+IGltLm1hdGNoZXMocmVsVG9Sb290KSkKICAgICAgICAgICAgICAgICAgICAgICAgJiYgZXhjbHVkZU1hdGNoZXJzLnN0cmVhbSgpLm5vbmVNYXRjaChlbSAtPiBlbS5tYXRjaGVzKHJlbFRvUm9vdCkpCiAgICAgICAgICAgICAgICAgICAgICAgICYmIHN1ZmZpeGVzLmNvbnRhaW5zKFV0aWwuZmlsZVN1ZmZpeChmaWxlKSkpIHsKCiAgICAgICAgICAgICAgICAgICAgLy8gVE9ETzogVGVzdCB0aGlzLgogICAgICAgICAgICAgICAgICAgIFNvdXJjZSBleGlzdGluZyA9IGZvdW5kRmlsZXMuZ2V0KGZpbGUpOwogICAgICAgICAgICAgICAgICAgIGlmIChleGlzdGluZyAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiWW91IGhhdmUgYWxyZWFkeSBhZGRlZCB0aGUgZmlsZSAiK2ZpbGUrIiBmcm9tICIrZXhpc3RpbmcuZmlsZSgpLmdldFBhdGgoKSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGV4aXN0aW5nID0gY3VycmVudE1vZHVsZS5sb29rdXBTb3VyY2UoZmlsZS50b1N0cmluZygpKTsKICAgICAgICAgICAgICAgICAgICBpZiAoZXhpc3RpbmcgIT0gbnVsbCkgewoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE91cHMsIHRoZSBzb3VyY2UgaXMgYWxyZWFkeSBhZGRlZCwgY291bGQgYmUgb2ssIGNvdWxkIGJlIG5vdCwgbGV0cyBjaGVjay4KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpbkxpbmtzcmMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTbyB3ZSBhcmUgY29sbGVjdGluZyBzb3VyY2VzIGZvciBsaW5raW5nIG9ubHkuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGV4aXN0aW5nLmlzTGlua2VkT25seSgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE91Y2gsIHRoaXMgb25lIGlzIGFsc28gZm9yIGxpbmtpbmcgb25seS4gQmFkLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIllvdSBoYXZlIGFscmVhZHkgYWRkZWQgdGhlIGxpbmsgb25seSBmaWxlICIgKyBmaWxlICsgIiBmcm9tICIgKyBleGlzdGluZy5maWxlKCkuZ2V0UGF0aCgpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gT2ssIHRoZSBleGlzdGluZyBzb3VyY2UgaXMgdG8gYmUgY29tcGlsZWQuIFRodXMgdGhpcyBsaW5rIG9ubHkgaXMgcmVkdW5kYW50CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc2luY2UgYWxsIGNvbXBpbGVkIGFyZSBhbHNvIGxpbmtlZCB0by4gQ29udGludWUgdG8gdGhlIG5leHQgc291cmNlLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEJ1dCB3ZSBuZWVkIHRvIGFkZCB0aGUgc291cmNlLCBzbyB0aGF0IGl0IHdpbGwgYmUgdmlzaWJsZSB0byBsaW5raW5nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGlmIG5vdCB0aGUgbXVsdGkgY29yZSBjb21waWxlIHdpbGwgZmFpbCBiZWNhdXNlIGEgSmF2YUNvbXBpbGVyIGNhbm5vdAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZpbmQgdGhlIG5lY2Vzc2FyeSBkZXBlbmRlbmNpZXMgZm9yIGl0cyBwYXJ0IG9mIHRoZSBzb3VyY2UuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm91bmRGaWxlcy5wdXQoZmlsZS50b1N0cmluZygpLCBleGlzdGluZyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdlIGFyZSBsb29raW5nIGZvciBzb3VyY2VzIHRvIGNvbXBpbGUsIGlmIHdlIGZpbmQgYW4gZXhpc3RpbmcgdG8gYmUgY29tcGlsZWQKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBzb3VyY2Ugd2l0aCB0aGUgc2FtZSBuYW1lLCBpdCBpcyBhbiBpbnRlcm5hbCBlcnJvciwgc2luY2Ugd2UgbXVzdAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZpbmQgdGhlIHNvdXJjZXMgdG8gYmUgY29tcGlsZWQgYmVmb3JlIHdlIGZpbmQgdGhlIHNvdXJjZXMgdG8gYmUgbGlua2VkIHRvLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiSW50ZXJuYWwgZXJyb3I6IERvdWJsZSBhZGQgb2YgZmlsZSAiICsgZmlsZSArICIgZnJvbSAiICsgZXhpc3RpbmcuZmlsZSgpLmdldFBhdGgoKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CgogICAgICAgICAgICAgICAgICAgICAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwogICAgICAgICAgICAgICAgICAgICAgICAvLyBBZGQgc291cmNlCiAgICAgICAgICAgICAgICAgICAgICAgIFNvdXJjZSBzID0gbmV3IFNvdXJjZShjdXJyZW50TW9kdWxlLCBmaWxlLnRvU3RyaW5nKCksIGZpbGUudG9GaWxlKCkpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW5HZW5zcmMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHMubWFya0FzR2VuZXJhdGVkKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGluTGlua3NyYykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcy5tYXJrQXNMaW5rZWRPbmx5KCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHBrZyA9IHBhY2thZ2VPZkphdmFGaWxlKHJvb3QudG9QYXRoKCksIGZpbGUpOwogICAgICAgICAgICAgICAgICAgICAgICBwa2cgPSBjdXJyZW50TW9kdWxlLm5hbWUoKSArICI6IiArIHBrZzsKICAgICAgICAgICAgICAgICAgICAgICAgZm91bmRGaWxlcy5wdXQoZmlsZS50b1N0cmluZygpLCBzKTsKICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudE1vZHVsZS5hZGRTb3VyY2UocGtnLCBzKTsKICAgICAgICAgICAgICAgICAgICAgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmV0dXJuIEZpbGVWaXNpdFJlc3VsdC5DT05USU5VRTsKICAgICAgICAgICAgfQogICAgICAgIH0pOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIExpc3Q8UGF0aE1hdGNoZXI+IGNyZWF0ZVBhdGhNYXRjaGVycyhGaWxlU3lzdGVtIGZzLCBMaXN0PFN0cmluZz4gcGF0dGVybnMpIHsKICAgICAgICBMaXN0PFBhdGhNYXRjaGVyPiBtYXRjaGVycyA9IG5ldyBBcnJheUxpc3Q8PigpOwogICAgICAgIGZvciAoU3RyaW5nIHBhdHRlcm4gOiBwYXR0ZXJucykgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgbWF0Y2hlcnMuYWRkKGZzLmdldFBhdGhNYXRjaGVyKCJnbG9iOiIgKyBwYXR0ZXJuKSk7CiAgICAgICAgICAgIH0gY2F0Y2ggKFBhdHRlcm5TeW50YXhFeGNlcHRpb24gZSkgewogICAgICAgICAgICAgICAgTG9nLmVycm9yKCJJbnZhbGlkIHBhdHRlcm46ICIgKyBwYXR0ZXJuKTsKICAgICAgICAgICAgICAgIHRocm93IGU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hdGNoZXJzOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBwYWNrYWdlT2ZKYXZhRmlsZShQYXRoIHNvdXJjZVJvb3QsIFBhdGggamF2YUZpbGUpIHsKICAgICAgICBQYXRoIGphdmFGaWxlRGlyID0gamF2YUZpbGUuZ2V0UGFyZW50KCk7CiAgICAgICAgUGF0aCBwYWNrYWdlRGlyID0gc291cmNlUm9vdC5yZWxhdGl2aXplKGphdmFGaWxlRGlyKTsKICAgICAgICBMaXN0PFN0cmluZz4gc2VwYXJhdGVEaXJzID0gbmV3IEFycmF5TGlzdDw+KCk7CiAgICAgICAgZm9yIChQYXRoIHBhdGhFbGVtZW50IDogcGFja2FnZURpcikgewogICAgICAgICAgICBzZXBhcmF0ZURpcnMuYWRkKHBhdGhFbGVtZW50LmdldEZpbGVOYW1lKCkudG9TdHJpbmcoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBTdHJpbmcuam9pbigiLiIsIHNlcGFyYXRlRGlycyk7CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewogICAgICAgIHJldHVybiBTdHJpbmcuZm9ybWF0KCIlc1twa2c6ICVzLCBuYW1lOiAlcywgc3VmZml4OiAlcywgZmlsZTogJXMsIGlzR2VuZXJhdGVkOiAlYiwgbGlua2VkT25seTogJWJdIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRDbGFzcygpLmdldFNpbXBsZU5hbWUoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwa2csCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWZmaXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc0dlbmVyYXRlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaW5rZWRPbmx5KTsKICAgIH0KfQpQSwMECgAACAAABjupSgAAAAAAAAAAAAAAAB0AAABjb20vc3VuL3Rvb2xzL3NqYXZhYy9vcHRpb25zL1BLAwQKAAAIAAAGO6lK0V4Ocns6AAB7OgAAKAAAAGNvbS9zdW4vdG9vbHMvc2phdmFjL29wdGlvbnMvT3B0aW9uLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTQsIDIwMTYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5zamF2YWMub3B0aW9uczsKCmltcG9ydCBqYXZhLmlvLkZpbGU7CmltcG9ydCBqYXZhLm5pby5maWxlLlBhdGg7CmltcG9ydCBqYXZhLm5pby5maWxlLlBhdGhzOwppbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKaW1wb3J0IGphdmEudXRpbC5MaXN0OwppbXBvcnQgamF2YS51dGlsLnJlZ2V4Lk1hdGNoZXI7CmltcG9ydCBqYXZhLnV0aWwucmVnZXguUGF0dGVybjsKCmltcG9ydCBjb20uc3VuLnRvb2xzLnNqYXZhYy5Db3B5RmlsZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuc2phdmFjLlRyYW5zZm9ybWVyOwoKCi8qKgogKiBTamF2YWMgb3B0aW9ucyBjYW4gYmUgY2xhc3NpZmllZCBhczoKICoKICogICgxKSByZWxldmFudCBvbmx5IGZvciBzamF2YWMsIHN1Y2ggYXMgLS1zZXJ2ZXIKICogICgyKSByZWxldmFudCBmb3Igc2phdmFjIGFuZCBqYXZhYywgc3VjaCBhcyAtZCwgb3IKICogICgzKSByZWxldmFudCBvbmx5IGZvciBqYXZhYywgc3VjaCBhcyAtZy4KICoKICogVGhpcyBlbnVtIHJlcHJlc2VudHMgYWxsIG9wdGlvbnMgZnJvbSAoMSkgYW5kICgyKS4gTm90ZSB0aGF0IGluc3RhbmNlcyBvZgogKiB0aGlzIGVudW0gb25seSBlbnRhaWwgc3RhdGljIGluZm9ybWF0aW9uIGFib3V0IHRoZSBvcHRpb24uIEZvciBzdG9yYWdlIG9mCiAqIG9wdGlvbiB2YWx1ZXMsIHJlZmVyIHRvIGNvbS5zdW4udG9vbHMuc2phdmFjLm9wdGlvbnMuT3B0aW9ucy4KICoKICogIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqICBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqICBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogKiAgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPgogKi8KcHVibGljIGVudW0gT3B0aW9uIHsKCiAgICBTUkMoIi1zcmMiLCAiTG9jYXRpb24gb2Ygc291cmNlIGZpbGVzIHRvIGJlIGNvbXBpbGVkIikgewogICAgICAgIEBPdmVycmlkZQogICAgICAgIHByb3RlY3RlZCB2b2lkIHByb2Nlc3NNYXRjaGluZyhBcmd1bWVudEl0ZXJhdG9yIGl0ZXIsIE9wdGlvbkhlbHBlciBoZWxwZXIpIHsKICAgICAgICAgICAgTGlzdDxQYXRoPiBwYXRocyA9IGdldEZpbGVMaXN0QXJnKGl0ZXIsIGhlbHBlcik7CiAgICAgICAgICAgIGlmIChwYXRocyAhPSBudWxsKQogICAgICAgICAgICAgICAgaGVscGVyLnNvdXJjZVJvb3RzKHBhdGhzKTsKICAgICAgICB9CiAgICB9LAogICAgU09VUkNFX1BBVEgoIi0tc291cmNlLXBhdGgiLCAiU3BlY2lmeSBzZWFyY2ggcGF0aCBmb3Igc291cmNlcy4iKSB7CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHJvdGVjdGVkIHZvaWQgcHJvY2Vzc01hdGNoaW5nKEFyZ3VtZW50SXRlcmF0b3IgaXRlciwgT3B0aW9uSGVscGVyIGhlbHBlcikgewogICAgICAgICAgICBMaXN0PFBhdGg+IHBhdGhzID0gZ2V0RmlsZUxpc3RBcmcoaXRlciwgaGVscGVyKTsKICAgICAgICAgICAgaWYgKHBhdGhzICE9IG51bGwpCiAgICAgICAgICAgICAgICBoZWxwZXIuc291cmNlcGF0aChwYXRocyk7CiAgICAgICAgfQogICAgfSwKICAgIFNPVVJDRVBBVEgoIi1zb3VyY2VwYXRoIiwgIkFuIGFsaWFzIGZvciAtc291cmNlcGF0aCIpIHsKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwcm90ZWN0ZWQgdm9pZCBwcm9jZXNzTWF0Y2hpbmcoQXJndW1lbnRJdGVyYXRvciBpdGVyLCBPcHRpb25IZWxwZXIgaGVscGVyKSB7CiAgICAgICAgICAgIFNPVVJDRV9QQVRILnByb2Nlc3NNYXRjaGluZyhpdGVyLCBoZWxwZXIpOwogICAgICAgIH0KICAgIH0sCiAgICBNT0RVTEVfUEFUSCgiLS1tb2R1bGUtcGF0aCIsICJTcGVjaWZ5IHNlYXJjaCBwYXRoIGZvciBtb2R1bGVzLiIpIHsKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwcm90ZWN0ZWQgdm9pZCBwcm9jZXNzTWF0Y2hpbmcoQXJndW1lbnRJdGVyYXRvciBpdGVyLCBPcHRpb25IZWxwZXIgaGVscGVyKSB7CiAgICAgICAgICAgIExpc3Q8UGF0aD4gcGF0aHMgPSBnZXRGaWxlTGlzdEFyZyhpdGVyLCBoZWxwZXIpOwogICAgICAgICAgICBpZiAocGF0aHMgIT0gbnVsbCkKICAgICAgICAgICAgICAgIGhlbHBlci5tb2R1bGVwYXRoKHBhdGhzKTsKICAgICAgICB9CiAgICB9LAogICAgUCgiLXAiLCAiQW4gYWxpYXMgZm9yIC0tbW9kdWxlLXBhdGgiKSB7CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHJvdGVjdGVkIHZvaWQgcHJvY2Vzc01hdGNoaW5nKEFyZ3VtZW50SXRlcmF0b3IgaXRlciwgT3B0aW9uSGVscGVyIGhlbHBlcikgewogICAgICAgICAgICBNT0RVTEVfUEFUSC5wcm9jZXNzTWF0Y2hpbmcoaXRlciwgaGVscGVyKTsKICAgICAgICB9CiAgICB9LAogICAgQ0xBU1NfUEFUSCgiLS1jbGFzcy1wYXRoIiwgIlNwZWNpZnkgc2VhcmNoIHBhdGggZm9yIGNsYXNzZXMuIikgewogICAgICAgIEBPdmVycmlkZQogICAgICAgIHByb3RlY3RlZCB2b2lkIHByb2Nlc3NNYXRjaGluZyhBcmd1bWVudEl0ZXJhdG9yIGl0ZXIsIE9wdGlvbkhlbHBlciBoZWxwZXIpIHsKICAgICAgICAgICAgTGlzdDxQYXRoPiBwYXRocyA9IGdldEZpbGVMaXN0QXJnKGl0ZXIsIGhlbHBlcik7CiAgICAgICAgICAgIGlmIChwYXRocyAhPSBudWxsKQogICAgICAgICAgICAgICAgaGVscGVyLmNsYXNzcGF0aChwYXRocyk7CiAgICAgICAgfQogICAgfSwKICAgIENMQVNTUEFUSCgiLWNsYXNzcGF0aCIsICJBbiBhbGlhcyBmb3IgLWNsYXNzcGF0aC4iKSB7CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHJvdGVjdGVkIHZvaWQgcHJvY2Vzc01hdGNoaW5nKEFyZ3VtZW50SXRlcmF0b3IgaXRlciwgT3B0aW9uSGVscGVyIGhlbHBlcikgewogICAgICAgICAgICBDTEFTU19QQVRILnByb2Nlc3NNYXRjaGluZyhpdGVyLCBoZWxwZXIpOwogICAgICAgIH0KICAgIH0sCiAgICBDUCgiLWNwIiwgIkFuIGFsaWFzIGZvciAtY2xhc3NwYXRoIikgewogICAgICAgIEBPdmVycmlkZQogICAgICAgIHByb3RlY3RlZCB2b2lkIHByb2Nlc3NNYXRjaGluZyhBcmd1bWVudEl0ZXJhdG9yIGl0ZXIsIE9wdGlvbkhlbHBlciBoZWxwZXIpIHsKICAgICAgICAgICAgQ0xBU1NfUEFUSC5wcm9jZXNzTWF0Y2hpbmcoaXRlciwgaGVscGVyKTsKICAgICAgICB9CiAgICB9LAogICAgWCgiLXgiLCAiRXhjbHVkZSBmaWxlcyBtYXRjaGluZyB0aGUgZ2l2ZW4gcGF0dGVybiIpIHsKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwcm90ZWN0ZWQgdm9pZCBwcm9jZXNzTWF0Y2hpbmcoQXJndW1lbnRJdGVyYXRvciBpdGVyLCBPcHRpb25IZWxwZXIgaGVscGVyKSB7CiAgICAgICAgICAgIFN0cmluZyBwYXR0ZXJuID0gZ2V0RmlsZVBhdHRlcm5BcmcoaXRlciwgaGVscGVyKTsKICAgICAgICAgICAgaWYgKHBhdHRlcm4gIT0gbnVsbCkKICAgICAgICAgICAgICAgIGhlbHBlci5leGNsdWRlKHBhdHRlcm4pOwogICAgICAgIH0KICAgIH0sCiAgICBJKCItaSIsICJJbmNsdWRlIG9ubHkgZmlsZXMgbWF0Y2hpbmcgdGhlIGdpdmVuIHBhdHRlcm4iKSB7CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHJvdGVjdGVkIHZvaWQgcHJvY2Vzc01hdGNoaW5nKEFyZ3VtZW50SXRlcmF0b3IgaXRlciwgT3B0aW9uSGVscGVyIGhlbHBlcikgewogICAgICAgICAgICBTdHJpbmcgcGF0dGVybiA9IGdldEZpbGVQYXR0ZXJuQXJnKGl0ZXIsIGhlbHBlcik7CiAgICAgICAgICAgIGlmIChwYXR0ZXJuICE9IG51bGwpCiAgICAgICAgICAgICAgICBoZWxwZXIuaW5jbHVkZShwYXR0ZXJuKTsKICAgICAgICB9CiAgICB9LAogICAgVFIoIi10ciIsICJUcmFuc2xhdGUgcmVzb3VyY2VzIikgewogICAgICAgIEBPdmVycmlkZQogICAgICAgIHByb3RlY3RlZCB2b2lkIHByb2Nlc3NNYXRjaGluZyhBcmd1bWVudEl0ZXJhdG9yIGl0ZXIsIE9wdGlvbkhlbHBlciBoZWxwZXIpIHsKCiAgICAgICAgICAgIGlmICghaXRlci5oYXNOZXh0KCkpIHsKICAgICAgICAgICAgICAgIGhlbHBlci5yZXBvcnRFcnJvcihhcmcgKyAiIG11c3QgYmUgZm9sbG93ZWQgYnkgYSB0cmFuc2xhdGlvbiBydWxlIik7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIFN0cmluZyB0ckFyZyA9IGl0ZXIubmV4dCgpOwoKICAgICAgICAgICAgLy8gVmFsaWRhdGUgYXJndW1lbnQgc3ludGF4LiBFeGFtcGxlczoKICAgICAgICAgICAgLy8gICAucHJvcD1jb20uc3VuLnRvb2xzLmphdmFjLnNtYXJ0LkNvbXBpbGVQcm9wZXJ0aWVzCiAgICAgICAgICAgIC8vICAgLmlkbD1jb20uc3VuLmNvcmJhLkNvbXBpbGVJZGwKICAgICAgICAgICAgLy8gICAuZzM9YW50bHIuQ29tcGlsZUdyYW1tYXIsZGVidWc9dHJ1ZQogICAgICAgICAgICBTdHJpbmcgaWRlbnQgPSAiW2EtekEtWl9dW2EtekEtWjAtOV9dKiI7CiAgICAgICAgICAgIFBhdHRlcm4gcCA9IFBhdHRlcm4uY29tcGlsZSgiKD88c3VmZml4PlxcLiIgKyBpZGVudCArICIpPSIgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIig/PGNsYXNzPiIgKyBpZGVudCArICIoXFwuIiArIGlkZW50ICsgIikqKSIgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIig/PGV4dHJhPiwuKik/Iik7CiAgICAgICAgICAgIC8vIENoZWNrIHN5bnRheAogICAgICAgICAgICBNYXRjaGVyIG0gPSBwLm1hdGNoZXIodHJBcmcpOwogICAgICAgICAgICBpZiAoIW0ubWF0Y2hlcygpKSB7CiAgICAgICAgICAgICAgICBoZWxwZXIucmVwb3J0RXJyb3IoIlRoZSBzdHJpbmcgXCIiICsgdHJBcmcgKyAiXCIgaXMgbm90IGEgIiArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInZhbGlkIHRyYW5zbGF0ZSBwYXR0ZXJuIik7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIEV4dHJhY3QgcmVsZXZhbnQgcGFydHMKICAgICAgICAgICAgU3RyaW5nIHN1ZmZpeCA9IG0uZ3JvdXAoInN1ZmZpeCIpOwogICAgICAgICAgICBTdHJpbmcgY2xhc3NuYW1lID0gbS5ncm91cCgiY2xhc3MiKTsKICAgICAgICAgICAgU3RyaW5nIGV4dHJhID0gbS5ncm91cCgiZXh0cmEiKTsKCiAgICAgICAgICAgIC8vIFZhbGlkIHN1ZmZpeD8KICAgICAgICAgICAgaWYgKHN1ZmZpeC5tYXRjaGVzKCJcXC4oY2xhc3N8amF2YSkiKSkgewogICAgICAgICAgICAgICAgaGVscGVyLnJlcG9ydEVycm9yKCJZb3UgY2Fubm90IGhhdmUgYSB0cmFuc2xhdG9yIGZvciAiICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWZmaXggKyAiIGZpbGVzISIpOwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBDb25zdHJ1Y3QgdHJhbnNmb3JtZXIKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIENsYXNzPD8+IHRyQ2xzID0gQ2xhc3MuZm9yTmFtZShjbGFzc25hbWUpOwogICAgICAgICAgICAgICAgVHJhbnNmb3JtZXIgdHJhbnNmb3JtZXIgPQogICAgICAgICAgICAgICAgICAgIChUcmFuc2Zvcm1lcikgdHJDbHMuZ2V0Q29uc3RydWN0b3IoKS5uZXdJbnN0YW5jZSgpOwogICAgICAgICAgICAgICAgdHJhbnNmb3JtZXIuc2V0RXh0cmEoZXh0cmEpOwogICAgICAgICAgICAgICAgaGVscGVyLmFkZFRyYW5zZm9ybWVyKHN1ZmZpeCwgdHJhbnNmb3JtZXIpOwogICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgewogICAgICAgICAgICAgICAgaGVscGVyLnJlcG9ydEVycm9yKCJDYW5ub3QgdXNlICIgKyBjbGFzc25hbWUgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgYXMgYSB0cmFuc2xhdG9yOiAiICsgZS5nZXRNZXNzYWdlKCkpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSwKICAgIENPUFkoIi1jb3B5IiwgIkNvcHkgcmVzb3VyY2VzIikgewogICAgICAgIEBPdmVycmlkZQogICAgICAgIHByb3RlY3RlZCB2b2lkIHByb2Nlc3NNYXRjaGluZyhBcmd1bWVudEl0ZXJhdG9yIGl0ZXIsIE9wdGlvbkhlbHBlciBoZWxwZXIpIHsKICAgICAgICAgICAgaWYgKCFpdGVyLmhhc05leHQoKSkgewogICAgICAgICAgICAgICAgaGVscGVyLnJlcG9ydEVycm9yKGFyZyArICIgbXVzdCBiZSBmb2xsb3dlZCBieSBhIHJlc291cmNlIHR5cGUiKTsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgU3RyaW5nIGNvcHlBcmcgPSBpdGVyLm5leHQoKTsKCiAgICAgICAgICAgIC8vIFZhbGlkYXRlIGFyZ3VtZW50IHN5bnRheC4gRXhhbXBsZXM6IC5naWYsIC5odG1sCiAgICAgICAgICAgIGlmICghY29weUFyZy5tYXRjaGVzKCJcXC5bYS16QS1aX11bYS16QS1aMC05X10qIikpIHsKICAgICAgICAgICAgICAgIGhlbHBlci5yZXBvcnRFcnJvcigiVGhlIHN0cmluZyBcIiIgKyBjb3B5QXJnICsgIlwiIGlzIG5vdCBhICIgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ2YWxpZCByZXNvdXJjZSB0eXBlLiIpOwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CgogICAgICAgICAgICBoZWxwZXIuYWRkVHJhbnNmb3JtZXIoY29weUFyZywgbmV3IENvcHlGaWxlKCkpOwogICAgICAgIH0KICAgIH0sCiAgICBKKCItaiIsICJOdW1iZXIgb2YgY29yZXMiKSB7CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHJvdGVjdGVkIHZvaWQgcHJvY2Vzc01hdGNoaW5nKEFyZ3VtZW50SXRlcmF0b3IgaXRlciwgT3B0aW9uSGVscGVyIGhlbHBlcikgewogICAgICAgICAgICBpZiAoIWl0ZXIuaGFzTmV4dCgpIHx8ICFpdGVyLnBlZWsoKS5tYXRjaGVzKCJcXGQrIikpIHsKICAgICAgICAgICAgICAgIGhlbHBlci5yZXBvcnRFcnJvcihhcmcgKyAiIG11c3QgYmUgZm9sbG93ZWQgYnkgYW4gaW50ZWdlciIpOwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGhlbHBlci5udW1Db3JlcyhJbnRlZ2VyLnBhcnNlSW50KGl0ZXIubmV4dCgpKSk7CiAgICAgICAgfQogICAgfSwKICAgIFNFUlZFUigiLS1zZXJ2ZXI6IiwgIlNwZWNpZnkgc2VydmVyIGNvbmZpZ3VyYXRpb24gZmlsZSBvZiBydW5uaW5nIHNlcnZlciIpIHsKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwcm90ZWN0ZWQgdm9pZCBwcm9jZXNzTWF0Y2hpbmcoQXJndW1lbnRJdGVyYXRvciBpdGVyLCBPcHRpb25IZWxwZXIgaGVscGVyKSB7CiAgICAgICAgICAgIGhlbHBlci5zZXJ2ZXJDb25mKGl0ZXIuY3VycmVudCgpLnN1YnN0cmluZyhhcmcubGVuZ3RoKCkpKTsKICAgICAgICB9CiAgICB9LAogICAgU1RBUlRTRVJWRVIoIi0tc3RhcnRzZXJ2ZXI6IiwgIlN0YXJ0IHNlcnZlciBhbmQgdXNlIHRoZSBnaXZlbiBjb25maWd1cmF0aW9uIGZpbGUiKSB7CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHJvdGVjdGVkIHZvaWQgcHJvY2Vzc01hdGNoaW5nKEFyZ3VtZW50SXRlcmF0b3IgaXRlciwgT3B0aW9uSGVscGVyIGhlbHBlcikgewogICAgICAgICAgICBoZWxwZXIuc3RhcnRTZXJ2ZXJDb25mKGl0ZXIuY3VycmVudCgpLnN1YnN0cmluZyhhcmcubGVuZ3RoKCkpKTsKICAgICAgICB9CiAgICB9LAogICAgSU1QTElDSVQoIi1pbXBsaWNpdDoiLCAiU3BlY2lmeSBob3cgdG8gdHJlYXQgaW1wbGljaXRseSByZWZlcmVuY2VkIHNvdXJjZSBjb2RlIikgewogICAgICAgIEBPdmVycmlkZQogICAgICAgIHByb3RlY3RlZCB2b2lkIHByb2Nlc3NNYXRjaGluZyhBcmd1bWVudEl0ZXJhdG9yIGl0ZXIsIE9wdGlvbkhlbHBlciBoZWxwZXIpIHsKICAgICAgICAgICAgaGVscGVyLmltcGxpY2l0KGl0ZXIuY3VycmVudCgpLnN1YnN0cmluZyhhcmcubGVuZ3RoKCkpKTsKICAgICAgICB9CiAgICB9LAogICAgTE9HKCItLWxvZz0iLCAiU3BlY2lmeSBsb2dnaW5nIGxldmVsIikgewogICAgICAgIEBPdmVycmlkZQogICAgICAgIHByb3RlY3RlZCB2b2lkIHByb2Nlc3NNYXRjaGluZyhBcmd1bWVudEl0ZXJhdG9yIGl0ZXIsIE9wdGlvbkhlbHBlciBoZWxwZXIpIHsKICAgICAgICAgICAgaGVscGVyLmxvZ0xldmVsKGl0ZXIuY3VycmVudCgpLnN1YnN0cmluZyhhcmcubGVuZ3RoKCkpKTsKICAgICAgICB9CiAgICB9LAogICAgVkVSQk9TRSgiLXZlcmJvc2UiLCAiU2V0IHZlcmJvc2l0eSBsZXZlbCB0byBcImluZm9cIiIpIHsKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwcm90ZWN0ZWQgdm9pZCBwcm9jZXNzTWF0Y2hpbmcoQXJndW1lbnRJdGVyYXRvciBpdGVyLCBPcHRpb25IZWxwZXIgaGVscGVyKSB7CiAgICAgICAgICAgIGhlbHBlci5sb2dMZXZlbCgiaW5mbyIpOwogICAgICAgIH0KICAgIH0sCiAgICBQRVJNSVRfQVJUSUZBQ1QoIi0tcGVybWl0LWFydGlmYWN0PSIsICJBbGxvdyB0aGlzIGFydGlmYWN0IGluIGRlc3RpbmF0aW9uIGRpcmVjdG9yeSIpIHsKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwcm90ZWN0ZWQgdm9pZCBwcm9jZXNzTWF0Y2hpbmcoQXJndW1lbnRJdGVyYXRvciBpdGVyLCBPcHRpb25IZWxwZXIgaGVscGVyKSB7CiAgICAgICAgICAgIFN0cmluZyBhID0gaXRlci5jdXJyZW50KCkuc3Vic3RyaW5nKGFyZy5sZW5ndGgoKSk7CiAgICAgICAgICAgIGhlbHBlci5wZXJtaXRBcnRpZmFjdChQYXRocy5nZXQoYSkudG9GaWxlKCkuZ2V0QWJzb2x1dGVQYXRoKCkpOwogICAgICAgIH0KICAgIH0sCiAgICBQRVJNSVRfVU5JREVOVElGSUVEX0FSVElGQUNUUygiLS1wZXJtaXQtdW5pZGVudGlmaWVkLWFydGlmYWN0cyIsICJBbGxvdyB1bmlkZW50aWZpZWQgYXJ0aWZhY3RzIGluIGRlc3RpbmF0aW9uIGRpcmVjdG9yeSIpIHsKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwcm90ZWN0ZWQgdm9pZCBwcm9jZXNzTWF0Y2hpbmcoQXJndW1lbnRJdGVyYXRvciBpdGVyLCBPcHRpb25IZWxwZXIgaGVscGVyKSB7CiAgICAgICAgICAgIGhlbHBlci5wZXJtaXRVbmlkZW50aWZpZWRBcnRpZmFjdHMoKTsKICAgICAgICB9CiAgICB9LAogICAgUEVSTUlUX1NPVVJDRVNfV0lUSE9VVF9QQUNLQUdFKCItLXBlcm1pdC1zb3VyY2VzLXdpdGhvdXQtcGFja2FnZSIsICJQZXJtaXQgc291cmNlcyBpbiB0aGUgZGVmYXVsdCBwYWNrYWdlIikgewogICAgICAgIEBPdmVycmlkZQogICAgICAgIHByb3RlY3RlZCB2b2lkIHByb2Nlc3NNYXRjaGluZyhBcmd1bWVudEl0ZXJhdG9yIGl0ZXIsIE9wdGlvbkhlbHBlciBoZWxwZXIpIHsKICAgICAgICAgICAgaGVscGVyLnBlcm1pdERlZmF1bHRQYWNrYWdlKCk7CiAgICAgICAgfQogICAgfSwKICAgIENPTVBBUkVfRk9VTkRfU09VUkNFUygiLS1jb21wYXJlLWZvdW5kLXNvdXJjZXMiLCAiQ29tcGFyZSBmb3VuZCBzb3VyY2VzIHdpdGggZ2l2ZW4gc291cmNlcyIpIHsKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwcm90ZWN0ZWQgdm9pZCBwcm9jZXNzTWF0Y2hpbmcoQXJndW1lbnRJdGVyYXRvciBpdGVyLCBPcHRpb25IZWxwZXIgaGVscGVyKSB7CiAgICAgICAgICAgIFBhdGggcmVmZXJlbmNlU291cmNlTGlzdCA9IGdldEZpbGVBcmcoaXRlciwgaGVscGVyLCB0cnVlLCBmYWxzZSk7CiAgICAgICAgICAgIGlmIChyZWZlcmVuY2VTb3VyY2VMaXN0ICE9IG51bGwpCiAgICAgICAgICAgICAgICBoZWxwZXIuY29tcGFyZUZvdW5kU291cmNlcyhyZWZlcmVuY2VTb3VyY2VMaXN0KTsKICAgICAgICB9CiAgICB9LAogICAgRCgiLWQiLCAiT3V0cHV0IGRlc3RpbmF0aW9uIGRpcmVjdG9yeSIpIHsKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwcm90ZWN0ZWQgdm9pZCBwcm9jZXNzTWF0Y2hpbmcoQXJndW1lbnRJdGVyYXRvciBpdGVyLCBPcHRpb25IZWxwZXIgaGVscGVyKSB7CiAgICAgICAgICAgIFBhdGggZGlyID0gZ2V0RmlsZUFyZyhpdGVyLCBoZWxwZXIsIGZhbHNlLCB0cnVlKTsKICAgICAgICAgICAgaWYgKGRpciAhPSBudWxsKQogICAgICAgICAgICAgICAgaGVscGVyLmRlc3REaXIoZGlyKTsKICAgICAgICB9CiAgICB9LAogICAgUygiLXMiLCAiRGlyZWN0b3J5IGZvciBnZW5lcmF0ZWQgc291cmNlcyIpIHsKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwcm90ZWN0ZWQgdm9pZCBwcm9jZXNzTWF0Y2hpbmcoQXJndW1lbnRJdGVyYXRvciBpdGVyLCBPcHRpb25IZWxwZXIgaGVscGVyKSB7CiAgICAgICAgICAgIFBhdGggZGlyID0gZ2V0RmlsZUFyZyhpdGVyLCBoZWxwZXIsIGZhbHNlLCB0cnVlKTsKICAgICAgICAgICAgaWYgKGRpciAhPSBudWxsKQogICAgICAgICAgICAgICAgaGVscGVyLmdlbmVyYXRlZFNvdXJjZXNEaXIoZGlyKTsKICAgICAgICB9CiAgICB9LAogICAgSCgiLWgiLCAiRGlyZWN0b3J5IGZvciBoZWFkZXIgZmlsZXMiKSB7CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHJvdGVjdGVkIHZvaWQgcHJvY2Vzc01hdGNoaW5nKEFyZ3VtZW50SXRlcmF0b3IgaXRlciwgT3B0aW9uSGVscGVyIGhlbHBlcikgewogICAgICAgICAgICBQYXRoIGRpciA9IGdldEZpbGVBcmcoaXRlciwgaGVscGVyLCBmYWxzZSwgdHJ1ZSk7CiAgICAgICAgICAgIGlmIChkaXIgIT0gbnVsbCkKICAgICAgICAgICAgICAgIGhlbHBlci5oZWFkZXJEaXIoZGlyKTsKICAgICAgICB9CiAgICB9LAogICAgU1RBVEVfRElSKCItLXN0YXRlLWRpcj0iLCAiRGlyZWN0b3J5IHVzZWQgdG8gc3RvcmUgc2phdmFjIHN0YXRlIGFuZCBsb2cgZmlsZXMuIikgewogICAgICAgIEBPdmVycmlkZQogICAgICAgIHByb3RlY3RlZCB2b2lkIHByb2Nlc3NNYXRjaGluZyhBcmd1bWVudEl0ZXJhdG9yIGl0ZXIsIE9wdGlvbkhlbHBlciBoZWxwZXIpIHsKICAgICAgICAgICAgU3RyaW5nIHAgPSBpdGVyLmN1cnJlbnQoKS5zdWJzdHJpbmcoYXJnLmxlbmd0aCgpKTsKICAgICAgICAgICAgaGVscGVyLnN0YXRlRGlyKFBhdGhzLmdldChwKSk7CiAgICAgICAgfQogICAgfTsKCgogICAgcHVibGljIGZpbmFsIFN0cmluZyBhcmc7CgogICAgZmluYWwgU3RyaW5nIGRlc2NyaXB0aW9uOwoKICAgIHByaXZhdGUgT3B0aW9uKFN0cmluZyBhcmcsIFN0cmluZyBkZXNjcmlwdGlvbikgewogICAgICAgIHRoaXMuYXJnID0gYXJnOwogICAgICAgIHRoaXMuZGVzY3JpcHRpb24gPSBkZXNjcmlwdGlvbjsKICAgIH0KCiAgICAvKiogUmV0cmlldmUgYW5kIHZlcmlmeSBzeW50YXggb2YgZmlsZSBsaXN0IGFyZ3VtZW50LiAqLwogICAgTGlzdDxQYXRoPiBnZXRGaWxlTGlzdEFyZyhBcmd1bWVudEl0ZXJhdG9yIGl0ZXIsIE9wdGlvbkhlbHBlciBoZWxwZXIpIHsKICAgICAgICBpZiAoIWl0ZXIuaGFzTmV4dCgpKSB7CiAgICAgICAgICAgIGhlbHBlci5yZXBvcnRFcnJvcihhcmcgKyAiIG11c3QgYmUgZm9sbG93ZWQgYnkgYSBsaXN0IG9mIGZpbGVzICIgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAic2VwYXJhdGVkIGJ5ICIgKyBGaWxlLnBhdGhTZXBhcmF0b3IpOwogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICAgICAgTGlzdDxQYXRoPiByZXN1bHQgPSBuZXcgQXJyYXlMaXN0PD4oKTsKICAgICAgICBmb3IgKFN0cmluZyBwYXRoU3RyIDogaXRlci5uZXh0KCkuc3BsaXQoRmlsZS5wYXRoU2VwYXJhdG9yKSkKICAgICAgICAgICAgcmVzdWx0LmFkZChQYXRocy5nZXQocGF0aFN0cikpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9CgogICAgLyoqIFJldHJpZXZlIGFuZCB2ZXJpZnkgc3ludGF4IG9mIGZpbGUgYXJndW1lbnQuICovCiAgICBQYXRoIGdldEZpbGVBcmcoQXJndW1lbnRJdGVyYXRvciBpdGVyLCBPcHRpb25IZWxwZXIgaGVscGVyLCBib29sZWFuIGZpbGVBY2NlcHRhYmxlLCBib29sZWFuIGRpckFjY2VwdGFibGUpIHsKCiAgICAgICAgaWYgKCFpdGVyLmhhc05leHQoKSkgewogICAgICAgICAgICBTdHJpbmcgZXJybXNnID0gYXJnICsgIiBtdXN0IGJlIGZvbGxvd2VkIGJ5ICI7CiAgICAgICAgICAgIGlmIChmaWxlQWNjZXB0YWJsZSAmJiBkaXJBY2NlcHRhYmxlKSBlcnJtc2cgKz0gImEgZmlsZSBvciBkaXJlY3RvcnkuIjsKICAgICAgICAgICAgZWxzZSBpZiAoZmlsZUFjY2VwdGFibGUpIGVycm1zZyArPSAiYSBmaWxlLiI7CiAgICAgICAgICAgIGVsc2UgaWYgKGRpckFjY2VwdGFibGUpICBlcnJtc2cgKz0gImEgZGlyZWN0b3J5LiI7CiAgICAgICAgICAgIGVsc2UgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRmlsZSBvciBkaXJlY3RvcnkgbXVzdCBiZSBhY2NlcHRhYmxlLiIpOwogICAgICAgICAgICBoZWxwZXIucmVwb3J0RXJyb3IoZXJybXNnKTsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gUGF0aHMuZ2V0KGl0ZXIubmV4dCgpKTsKICAgIH0KCiAgICAvKiogUmV0cmlldmUgdGhlIG5leHQgZmlsZSBvciBwYWNrYWdlIGFyZ3VtZW50LiAqLwogICAgU3RyaW5nIGdldEZpbGVQYXR0ZXJuQXJnKEFyZ3VtZW50SXRlcmF0b3IgaXRlciwgT3B0aW9uSGVscGVyIGhlbHBlcikgewoKICAgICAgICBpZiAoIWl0ZXIuaGFzTmV4dCgpKSB7CiAgICAgICAgICAgIGhlbHBlci5yZXBvcnRFcnJvcihhcmcgKyAiIG11c3QgYmUgZm9sbG93ZWQgYnkgYSBnbG9iIHBhdHRlcm4uIik7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGl0ZXIubmV4dCgpOwogICAgfQoKICAgIC8vIEZ1dHVyZSBjbGVhbnVwOiBDaGFuZ2UgdGhlICI9IiBzeW50YXggdG8gIjoiIHN5bnRheCB0byBiZSBjb25zaXN0ZW50IGFuZAogICAgLy8gdG8gZm9sbG93IHRoZSBqYXZhYy1vcHRpb24gc3R5bGUuCgogICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uKCkgewogICAgICAgIHJldHVybiBhcmcuZW5kc1dpdGgoIjoiKSB8fCBhcmcuZW5kc1dpdGgoIj0iKTsKICAgIH0KCgogICAgLyoqCiAgICAgKiBQcm9jZXNzIGN1cnJlbnQgYXJndW1lbnQgb2YgYXJnSXRlci4KICAgICAqCiAgICAgKiBJdCdzIGZpbmFsLCBzaW5jZSB0aGUgb3B0aW9uIGN1c3RvbWl6YXRpb24gaXMgdHlwaWNhbGx5IGRvbmUgaW4KICAgICAqIHByb2Nlc3NNYXRjaGluZy4KICAgICAqCiAgICAgKiBAcGFyYW0gYXJnSXRlciBJdGVyYXRvciB0byByZWFkIGN1cnJlbnQgYW5kIHN1Y2NlZWRpbmcgYXJndW1lbnRzIGZyb20uCiAgICAgKiBAcGFyYW0gaGVscGVyIFRoZSBoZWxwZXIgdG8gcmVwb3J0IGJhY2sgdG8uCiAgICAgKiBAcmV0dXJuIHRydWUgaWZmIHRoZSBhcmd1bWVudCB3YXMgcHJvY2Vzc2VkIGJ5IHRoaXMgb3B0aW9uLgogICAgICovCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBwcm9jZXNzQ3VycmVudChBcmd1bWVudEl0ZXJhdG9yIGFyZ0l0ZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPcHRpb25IZWxwZXIgaGVscGVyKSB7CiAgICAgICAgU3RyaW5nIGZ1bGxBcmcgPSBhcmdJdGVyLmN1cnJlbnQoKTsgLy8gIi10ciIgb3IgIi1sb2c9bGV2ZWwiCiAgICAgICAgaWYgKGhhc09wdGlvbigpID8gZnVsbEFyZy5zdGFydHNXaXRoKGFyZykgOiBmdWxsQXJnLmVxdWFscyhhcmcpKSB7CiAgICAgICAgICAgIHByb2Nlc3NNYXRjaGluZyhhcmdJdGVyLCBoZWxwZXIpOwogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgLy8gRGlkIG5vdCBtYXRjaAogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICAvKiogQ2FsbGVkIGJ5IHByb2Nlc3MgaWYgdGhlIGN1cnJlbnQgYXJndW1lbnQgbWF0Y2hlcyB0aGlzIG9wdGlvbi4gKi8KICAgIHByb3RlY3RlZCBhYnN0cmFjdCB2b2lkIHByb2Nlc3NNYXRjaGluZyhBcmd1bWVudEl0ZXJhdG9yIGFyZ0l0ZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT3B0aW9uSGVscGVyIGhlbHBlcik7Cn0KUEsDBAoAAAgAAAY7qUockvdvCBEAAAgRAAAwAAAAY29tL3N1bi90b29scy9zamF2YWMvb3B0aW9ucy9Tb3VyY2VMb2NhdGlvbi5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDE0LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuc2phdmFjLm9wdGlvbnM7CgppbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKaW1wb3J0IGphdmEubmlvLmZpbGUuUGF0aDsKaW1wb3J0IGphdmEudXRpbC5MaXN0OwppbXBvcnQgamF2YS51dGlsLk1hcDsKaW1wb3J0IGphdmEudXRpbC5TZXQ7CgppbXBvcnQgY29tLnN1bi50b29scy5zamF2YWMuTG9nOwppbXBvcnQgY29tLnN1bi50b29scy5zamF2YWMuTW9kdWxlOwppbXBvcnQgY29tLnN1bi50b29scy5zamF2YWMuUHJvYmxlbUV4Y2VwdGlvbjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuc2phdmFjLlNvdXJjZTsKCi8qKgogKiBSZXByZXNlbnRzIGEgZGlyZWN0b3J5IHRvIGJlIHVzZWQgZm9yIGlucHV0IHRvIHNqYXZhYy4gKEZvciBpbnN0YW5jZSBhCiAqIHNvdXJjZXBhdGggb3IgY2xhc3NwYXRoLikKICoKICogIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqICBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqICBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogKiAgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPgogKi8KcHVibGljIGNsYXNzIFNvdXJjZUxvY2F0aW9uIHsKCiAgICAvLyBQYXRoIHRvIHRoZSByb290IGRpcmVjdG9yeQogICAgcHJpdmF0ZSBQYXRoIHBhdGg7CgogICAgLy8gUGFja2FnZSBpbmNsdWRlIC8gZXhjbHVkZSBwYXR0ZXJucyBhbmQgZmlsZSBpbmNsdWRlcyAvIGV4Y2x1ZGVzLgogICAgTGlzdDxTdHJpbmc+IGluY2x1ZGVzLCBleGNsdWRlczsKCiAgICBwdWJsaWMgU291cmNlTG9jYXRpb24oUGF0aCBwYXRoLAogICAgICAgICAgICAgICAgICAgICAgICAgIExpc3Q8U3RyaW5nPiBpbmNsdWRlcywKICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0PFN0cmluZz4gZXhjbHVkZXMpIHsKICAgICAgICB0aGlzLnBhdGggPSBwYXRoOwogICAgICAgIHRoaXMuaW5jbHVkZXMgPSBpbmNsdWRlczsKICAgICAgICB0aGlzLmV4Y2x1ZGVzID0gZXhjbHVkZXM7CiAgICB9CgoKICAgIC8qKgogICAgICogRmluZHMgYWxsIGZpbGVzIHdpdGggdGhlIGdpdmVuIHN1ZmZpeCB0aGF0IHBhc3MgdGhlIGluY2x1ZGUgLyBleGNsdWRlCiAgICAgKiBmaWx0ZXJzIGluIHRoaXMgc291cmNlIGxvY2F0aW9uLgogICAgICoKICAgICAqIEBwYXJhbSBzdWZmaXhlcyBUaGUgc2V0IG9mIHN1ZmZpeGVzIHRvIHNlYXJjaCBmb3IKICAgICAqIEBwYXJhbSBmb3VuZEZpbGVzIFRoZSBtYXAgaW4gd2hpY2ggdG8gc3RvcmUgdGhlIGZvdW5kIGZpbGVzCiAgICAgKiBAcGFyYW0gZm91bmRNb2R1bGVzIFRoZSBtYXAgaW4gd2hpY2ggdG8gc3RvcmUgdGhlIGZvdW5kIG1vZHVsZXMKICAgICAqIEBwYXJhbSBjdXJyZW50TW9kdWxlIFRoZSBjdXJyZW50IG1vZHVsZQogICAgICogQHBhcmFtIHBlcm1pdFNvdXJjZXNJbkRlZmF1bHRQYWNrYWdlIHRydWUgaWYgc291cmNlcyBpbiBkZWZhdWx0IHBhY2thZ2UKICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmUgdG8gYmUgcGVybWl0dGVkCiAgICAgKiBAcGFyYW0gaW5MaW5rc3JjIHRydWUgaWYgaW4gbGluayBzb3VyY2UKICAgICAqLwogICAgcHVibGljIHZvaWQgZmluZFNvdXJjZUZpbGVzKFNldDxTdHJpbmc+IHN1ZmZpeGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1hcDxTdHJpbmcsIFNvdXJjZT4gZm91bmRGaWxlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYXA8U3RyaW5nLCBNb2R1bGU+IGZvdW5kTW9kdWxlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNb2R1bGUgY3VycmVudE1vZHVsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIHBlcm1pdFNvdXJjZXNJbkRlZmF1bHRQYWNrYWdlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gaW5MaW5rc3JjKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICB0cnkgewogICAgICAgICAgICBTb3VyY2Uuc2NhblJvb3QocGF0aC50b0ZpbGUoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1ZmZpeGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhjbHVkZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmNsdWRlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvdW5kRmlsZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3VuZE1vZHVsZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50TW9kdWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcGVybWl0U291cmNlc0luRGVmYXVsdFBhY2thZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWxzZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluTGlua3NyYyk7CiAgICAgICAgfSBjYXRjaCAoUHJvYmxlbUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CiAgICAgICAgfQogICAgfQogICAgLyoqIEdldCB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgbG9jYXRpb24gKi8KICAgIHB1YmxpYyBQYXRoIGdldFBhdGgoKSB7CiAgICAgICAgcmV0dXJuIHBhdGg7CiAgICB9CgogICAgLyoqIEdldCB0aGUgcGFja2FnZSBpbmNsdWRlIHBhdHRlcm5zICovCiAgICBwdWJsaWMgTGlzdDxTdHJpbmc+IGdldEluY2x1ZGVzKCkgewogICAgICAgIHJldHVybiBpbmNsdWRlczsKICAgIH0KCiAgICAvKiogR2V0IHRoZSBwYWNrYWdlIGV4Y2x1ZGUgcGF0dGVybnMgKi8KICAgIHB1YmxpYyBMaXN0PFN0cmluZz4gZ2V0RXhjbHVkZXMoKSB7CiAgICAgICAgcmV0dXJuIGV4Y2x1ZGVzOwogICAgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKICAgICAgICByZXR1cm4gU3RyaW5nLmZvcm1hdCgiJXNbXCIlc1wiLCBpbmNsdWRlczogJXMsIGV4Y2x1ZGVzOiAlc10iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldENsYXNzKCkuZ2V0U2ltcGxlTmFtZSgpLCBwYXRoLCBpbmNsdWRlcywgZXhjbHVkZXMpOwogICAgfQp9ClBLAwQKAAAIAADSfU1KXCjd6tYKAADWCgAAMgAAAGNvbS9zdW4vdG9vbHMvc2phdmFjL29wdGlvbnMvQXJndW1lbnRJdGVyYXRvci5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDE0LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuc2phdmFjLm9wdGlvbnM7CgppbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOwoKLyoqCiAqICA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiAgSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93biByaXNrLgogKiAgVGhpcyBjb2RlIGFuZCBpdHMgaW50ZXJuYWwgaW50ZXJmYWNlcyBhcmUgc3ViamVjdCB0byBjaGFuZ2Ugb3IKICogIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj4KICovCnB1YmxpYyBjbGFzcyBBcmd1bWVudEl0ZXJhdG9yIGltcGxlbWVudHMgSXRlcmF0b3I8U3RyaW5nPiB7CgogICAgLyoqIFRoZSB1bmRlcmx5aW5nIGFyZ3VtZW50IGl0ZXJhdG9yICovCiAgICBwcml2YXRlIEl0ZXJhdG9yPFN0cmluZz4gaXRlcjsKCiAgICAvKiogRXh0cmEgc3RhdGUgdXNlZCB0byBpbXBsZW1lbnQgcGVlayBhbmQgY3VycmVudCAqLwogICAgcHJpdmF0ZSBTdHJpbmcgY3VycmVudDsKICAgIHByaXZhdGUgU3RyaW5nIGJ1ZmZlcmVkOwoKICAgIHB1YmxpYyBBcmd1bWVudEl0ZXJhdG9yKEl0ZXJhYmxlPFN0cmluZz4gaXRlcikgewogICAgICAgIHRoaXMuaXRlciA9IGl0ZXIuaXRlcmF0b3IoKTsKICAgIH0KCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc05leHQoKSB7CiAgICAgICAgcmV0dXJuIGJ1ZmZlcmVkICE9IG51bGwgfHwgaXRlci5oYXNOZXh0KCk7CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgU3RyaW5nIG5leHQoKSB7CiAgICAgICAgZmlsbEJ1ZmZlcigpOwogICAgICAgIGN1cnJlbnQgPSBidWZmZXJlZDsKICAgICAgICBidWZmZXJlZCA9IG51bGw7CiAgICAgICAgcmV0dXJuIGN1cnJlbnQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIHRoZSBsYXN0IGVsZW1lbnQgcmV0dXJuZWQgYnkgbmV4dCgpIChvciB7QGNvZGUgbnVsbH0gaWYgbmV4dCBoYXMKICAgICAqIG5ldmVyIGJlZW4gaW52b2tlZCBvbiB0aGlzIGl0ZXJhdG9yKS4KICAgICAqLwogICAgcHVibGljIFN0cmluZyBjdXJyZW50KCkgewogICAgICAgIHJldHVybiBjdXJyZW50OwogICAgfQoKICAgIC8qKiBDYW4ndCByZW1vdmUgY3VycmVudCBlbGVtZW50LCBzaW5jZSB3ZSBtYXkgaGF2ZSBidWZmZXJlZCBpdC4gKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIHZvaWQgcmVtb3ZlKCkgewogICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBSZXR1cm5zIHRoZSBuZXh0IGVsZW1lbnQgd2l0aG91dCBhZHZhbmNpbmcgdGhlIGl0ZXJhdG9yCiAgICAgKi8KICAgIHB1YmxpYyBTdHJpbmcgcGVlaygpIHsKICAgICAgICBmaWxsQnVmZmVyKCk7CiAgICAgICAgcmV0dXJuIGJ1ZmZlcmVkOwogICAgfQoKICAgIHByaXZhdGUgdm9pZCBmaWxsQnVmZmVyKCkgewogICAgICAgIGlmIChidWZmZXJlZCA9PSBudWxsICYmIGl0ZXIuaGFzTmV4dCgpKQogICAgICAgICAgICBidWZmZXJlZCA9IGl0ZXIubmV4dCgpOwogICAgfQoKfQpQSwMECgAACAAABjupSjb3nP5QPwAAUD8AACkAAABjb20vc3VuL3Rvb2xzL3NqYXZhYy9vcHRpb25zL09wdGlvbnMuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAxNCwgMjAxNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLnNqYXZhYy5vcHRpb25zOwoKaW1wb3J0IGphdmEubmlvLmZpbGUuUGF0aDsKaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CmltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOwppbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb247CmltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKaW1wb3J0IGphdmEudXRpbC5MaXN0OwppbXBvcnQgamF2YS51dGlsLk1hcDsKaW1wb3J0IGphdmEudXRpbC5TZXQ7CmltcG9ydCBqYXZhLnV0aWwuSGFzaFNldDsKaW1wb3J0IGphdmEudXRpbC5TdHJpbmdKb2luZXI7CgppbXBvcnQgY29tLnN1bi50b29scy5zamF2YWMuVHJhbnNmb3JtZXI7CmltcG9ydCBjb20uc3VuLnRvb2xzLnNqYXZhYy5VdGlsOwoKLyoqCiAqIEluc3RhbmNlcyBvZiB0aGlzIGNsYXNzIHJlcHJlc2VudCB2YWx1ZXMgZm9yIHNqYXZhYyBjb21tYW5kIGxpbmUgb3B0aW9ucy4KICoKICogIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqICBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqICBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogKiAgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPgogKi8KcHVibGljIGNsYXNzIE9wdGlvbnMgewoKICAgIC8vIE91dHB1dCBkaXJlY3RvcmllcwogICAgcHJpdmF0ZSBQYXRoIGRlc3REaXIsIGdlblNyY0RpciwgaGVhZGVyRGlyLCBzdGF0ZURpcjsKCiAgICAvLyBJbnB1dCBkaXJlY3RvcmllcwogICAgcHJpdmF0ZSBMaXN0PFNvdXJjZUxvY2F0aW9uPiBzb3VyY2VzID0gbmV3IEFycmF5TGlzdDw+KCk7CiAgICBwcml2YXRlIExpc3Q8U291cmNlTG9jYXRpb24+IHNvdXJjZVNlYXJjaFBhdGhzID0gbmV3IEFycmF5TGlzdDw+KCk7CiAgICBwcml2YXRlIExpc3Q8U291cmNlTG9jYXRpb24+IGNsYXNzU2VhcmNoUGF0aHMgPSBuZXcgQXJyYXlMaXN0PD4oKTsKICAgIHByaXZhdGUgTGlzdDxTb3VyY2VMb2NhdGlvbj4gbW9kdWxlU2VhcmNoUGF0aHMgPSBuZXcgQXJyYXlMaXN0PD4oKTsKCiAgICBwcml2YXRlIFN0cmluZyBsb2dMZXZlbCA9ICJpbmZvIjsKCiAgICBwcml2YXRlIFNldDxTdHJpbmc+IHBlcm1pdHRlZF9hcnRpZmFjdHMgPSBuZXcgSGFzaFNldDw+KCk7CiAgICBwcml2YXRlIGJvb2xlYW4gcGVybWl0VW5pZGVudGlmaWVkQXJ0aWZhY3RzID0gZmFsc2U7CiAgICBwcml2YXRlIGJvb2xlYW4gcGVybWl0U291cmNlc0luRGVmYXVsdFBhY2thZ2UgPSBmYWxzZTsKCiAgICBwcml2YXRlIFBhdGggc291cmNlUmVmZXJlbmNlTGlzdDsKICAgIHByaXZhdGUgaW50IG51bUNvcmVzID0gNDsKICAgIHByaXZhdGUgU3RyaW5nIGltcGxpY2l0UG9saWN5ID0gIm5vbmUiOwogICAgcHJpdmF0ZSBMaXN0PFN0cmluZz4gamF2YWNBcmdzID0gbmV3IEFycmF5TGlzdDw+KCk7CgogICAgcHJpdmF0ZSBNYXA8U3RyaW5nLCBUcmFuc2Zvcm1lcj4gdHJSdWxlcyA9IG5ldyBIYXNoTWFwPD4oKTsKCiAgICBwcml2YXRlIGJvb2xlYW4gc3RhcnRTZXJ2ZXIgPSBmYWxzZTsKCiAgICAvLyBTZXJ2ZXIgY29uZmlndXJhdGlvbiBzdHJpbmcKICAgIHByaXZhdGUgU3RyaW5nIHNlcnZlckNvbmY7CgogICAgLyoqIEdldCB0aGUgcG9saWN5IGZvciBpbXBsaWNpdCBjbGFzc2VzICovCiAgICBwdWJsaWMgU3RyaW5nIGdldEltcGxpY2l0UG9saWN5KCkgewogICAgICAgIHJldHVybiBpbXBsaWNpdFBvbGljeTsKICAgIH0KCiAgICAvKiogR2V0IHRoZSBwYXRoIGZvciBnZW5lcmF0ZWQgc291cmNlcyAob3IgbnVsbCBpZiBubyBzdWNoIHBhdGggaXMgc2V0KSAqLwogICAgcHVibGljIFBhdGggZ2V0R2VuU3JjRGlyKCkgewogICAgICAgIHJldHVybiBnZW5TcmNEaXI7CiAgICB9CgogICAgLyoqIEdldCB0aGUgcGF0aCBmb3IgdGhlIGRlc3RpbmF0aW9uIGRpcmVjdG9yeSAqLwogICAgcHVibGljIFBhdGggZ2V0RGVzdERpcigpIHsKICAgICAgICByZXR1cm4gZGVzdERpcjsKICAgIH0KCiAgICAvKiogR2V0IHRoZSBwYXRoIGZvciB0aGUgaGVhZGVyIGRpcmVjdG9yeSAob3IgbnVsbCBpZiBubyBzdWNoIHBhdGggaXMgc2V0KSAqLwogICAgcHVibGljIFBhdGggZ2V0SGVhZGVyRGlyKCkgewogICAgICAgIHJldHVybiBoZWFkZXJEaXI7CiAgICB9CgogICAgLyoqIEdldCB0aGUgcGF0aCBmb3IgdGhlIHN0YXRlIGRpcmVjdG9yeSwgZGVmYXVsdHMgdG8gZGVzdERpci4gKi8KICAgIHB1YmxpYyBQYXRoIGdldFN0YXRlRGlyKCkgewogICAgICAgIHJldHVybiBzdGF0ZURpcjsKICAgIH0KCiAgICAvKiogR2V0IGFsbCBzb3VyY2UgbG9jYXRpb25zIGZvciBmaWxlcyB0byBiZSBjb21waWxlZCAqLwogICAgcHVibGljIExpc3Q8U291cmNlTG9jYXRpb24+IGdldFNvdXJjZXMoKSB7CiAgICAgICAgcmV0dXJuIHNvdXJjZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXQgYWxsIHBhdGhzIHRvIHNlYXJjaCBmb3IgY2xhc3NlcyBpbiAuamF2YSBmb3JtYXQuIChKYXZhLWZpbGVzIGluCiAgICAgKiBmb3VuZCBoZXJlIHNob3VsZCBub3QgYmUgY29tcGlsZWQuCiAgICAgKi8KICAgIHB1YmxpYyBMaXN0PFNvdXJjZUxvY2F0aW9uPiBnZXRTb3VyY2VTZWFyY2hQYXRocygpIHsKICAgICAgICByZXR1cm4gc291cmNlU2VhcmNoUGF0aHM7CiAgICB9CgogICAgLyoqIEdldCBhbGwgcGF0aHMgdG8gc2VhcmNoIGZvciBjbGFzc2VzIGluLiAqLwogICAgcHVibGljIExpc3Q8U291cmNlTG9jYXRpb24+IGdldENsYXNzU2VhcmNoUGF0aCgpIHsKICAgICAgICByZXR1cm4gY2xhc3NTZWFyY2hQYXRoczsKICAgIH0KCiAgICAvKiogR2V0IGFsbCBwYXRocyB0byBzZWFyY2ggZm9yIG1vZHVsZXMgaW4uICovCiAgICBwdWJsaWMgTGlzdDxTb3VyY2VMb2NhdGlvbj4gZ2V0TW9kdWxlU2VhcmNoUGF0aHMoKSB7CiAgICAgICAgcmV0dXJuIG1vZHVsZVNlYXJjaFBhdGhzOwogICAgfQoKICAgIC8qKiBHZXQgdGhlIGxvZyBsZXZlbC4gKi8KICAgIHB1YmxpYyBTdHJpbmcgZ2V0TG9nTGV2ZWwoKSB7CiAgICAgICAgcmV0dXJuIGxvZ0xldmVsOwogICAgfQoKICAgIC8qKiBSZXR1cm5zIHRydWUgaWZmIHRoZSBhcnRpZmFjdCBpcyBwZXJtaXR0ZWQgaW4gdGhlIG91dHB1dCBkaXIuICovCiAgICBwdWJsaWMgYm9vbGVhbiBpc1VuaWRlbnRpZmllZEFydGlmYWN0UGVybWl0dGVkKFN0cmluZyBmKSB7CiAgICAgICAgcmV0dXJuIHBlcm1pdHRlZF9hcnRpZmFjdHMuY29udGFpbnMoZik7CiAgICB9CgogICAgLyoqIFJldHVybnMgdHJ1ZSBpZmYgYXJ0aWZhY3RzIGluIHRoZSBvdXRwdXQgZGlyZWN0b3JpZXMgc2hvdWxkIGJlIGtlcHQsCiAgICAgKiBldmVuIGlmIHRoZXkgd291bGQgbm90IGJlIGdlbmVyYXRlZCBpbiBhIGNsZWFuIGJ1aWxkLiAqLwogICAgcHVibGljIGJvb2xlYW4gYXJlVW5pZGVudGlmaWVkQXJ0aWZhY3RzUGVybWl0dGVkKCkgewogICAgICAgIHJldHVybiBwZXJtaXRVbmlkZW50aWZpZWRBcnRpZmFjdHM7CiAgICB9CgogICAgLyoqIFJldHVybnMgdHJ1ZSBpZmYgc291cmNlcyBpbiB0aGUgZGVmYXVsdCBwYWNrYWdlIHNob3VsZCBiZSBwZXJtaXR0ZWQuICovCiAgICBwdWJsaWMgYm9vbGVhbiBpc0RlZmF1bHRQYWNrYWdlUGVybWl0dGVkKCkgewogICAgICAgIHJldHVybiBwZXJtaXRTb3VyY2VzSW5EZWZhdWx0UGFja2FnZTsKICAgIH0KCiAgICAvKiogR2V0IHRoZSBwYXRoIHRvIHRoZSBsaXN0IG9mIHJlZmVyZW5jZSBzb3VyY2VzIChvciBudWxsIGlmIG5vbmUgaXMgc2V0KSAqLwogICAgcHVibGljIFBhdGggZ2V0U291cmNlUmVmZXJlbmNlTGlzdCgpIHsKICAgICAgICByZXR1cm4gc291cmNlUmVmZXJlbmNlTGlzdDsKICAgIH0KCiAgICAvKiogR2V0IHRoZSBudW1iZXIgb2YgY29yZXMgdG8gYmUgdXNlZCBieSBzamF2YWMgKi8KICAgIHB1YmxpYyBpbnQgZ2V0TnVtQ29yZXMoKSB7CiAgICAgICAgcmV0dXJuIG51bUNvcmVzOwogICAgfQoKICAgIC8qKiBSZXR1cm5zIGFsbCBhcmd1bWVudHMgcmVsZXZhbnQgdG8gamF2YWMgYnV0IGlycmVsZXZhbnQgdG8gc2phdmFjLiAqLwogICAgcHVibGljIExpc3Q8U3RyaW5nPiBnZXRKYXZhY0FyZ3MoKSB7CiAgICAgICAgcmV0dXJuIGphdmFjQXJnczsKICAgIH0KCiAgICAvKioKICAgICAqIEdldCBhIG1hcCB3aGljaCBtYXBzIHN1ZmZpeGVzIHRvIHRyYW5zZm9ybWVycyAoZm9yIGV4YW1wbGUKICAgICAqICIuamF2YSIge0BsaXRlcmFsIC0+fSBDb21waWxlSmF2YVBhY2thZ2VzKQogICAgICovCiAgICBwdWJsaWMgTWFwPFN0cmluZywgVHJhbnNmb3JtZXI+IGdldFRyYW5zbGF0aW9uUnVsZXMoKSB7CiAgICAgICAgcmV0dXJuIHRyUnVsZXM7CiAgICB9CgogICAgLyoqIFJldHVybiB0cnVlIGlmZiBhIG5ldyBzZXJ2ZXIgc2hvdWxkIGJlIHN0YXJ0ZWQgKi8KICAgIHB1YmxpYyBib29sZWFuIHN0YXJ0U2VydmVyRmxhZygpIHsKICAgICAgICByZXR1cm4gc3RhcnRTZXJ2ZXI7CiAgICB9CgogICAgLyoqIFJldHVybiB0aGUgc2VydmVyIGNvbmZpZ3VyYXRpb24gc3RyaW5nLiAqLwogICAgcHVibGljIFN0cmluZyBnZXRTZXJ2ZXJDb25mKCkgewogICAgICAgIHJldHVybiBzZXJ2ZXJDb25mOwogICAgfQoKICAgIC8qKgogICAgICogUGFyc2VzIHRoZSBnaXZlbiBhcmd1bWVudCBhcnJheSBhbmQgcmV0dXJucyBhIGNvcnJlc3BvbmRpbmcgT3B0aW9ucwogICAgICogaW5zdGFuY2UuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgT3B0aW9ucyBwYXJzZUFyZ3MoU3RyaW5nLi4uIGFyZ3MpIHsKICAgICAgICBPcHRpb25zIG9wdGlvbnMgPSBuZXcgT3B0aW9ucygpOwogICAgICAgIG9wdGlvbnMubmV3IEFyZ0RlY29kZXJPcHRpb25IZWxwZXIoKS50cmF2ZXJzZShhcmdzKTsKICAgICAgICByZXR1cm4gb3B0aW9uczsKICAgIH0KCiAgICAvKiogUmV0dXJucyB0cnVlIGlmZiBhIC5qYXZhIGZpbGUgaXMgYW1vbmcgdGhlIGphdmFjIGFyZ3VtZW50cyAqLwogICAgcHVibGljIGJvb2xlYW4gaXNKYXZhRmlsZXNBbW9uZ0phdmFjQXJncygpIHsKICAgICAgICBmb3IgKFN0cmluZyBqYXZhY0FyZyA6IGphdmFjQXJncykKICAgICAgICAgICAgaWYgKGphdmFjQXJnLmVuZHNXaXRoKCIuamF2YSIpKQogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgb3B0aW9ucyB0aGF0IGFmZmVjdCB0aGUgcmVzdWx0IG9mCiAgICAgKiB0aGUgY29tcGlsYXRpb24uIChVc2VkIGZvciBzYXZpbmcgdGhlIHN0YXRlIG9mIHRoZSBvcHRpb25zIHVzZWQgaW4gYQogICAgICogcHJldmlvdXMgY29tcGlsZS4pCiAgICAgKi8KICAgIHB1YmxpYyBTdHJpbmcgZ2V0U3RhdGVBcmdzU3RyaW5nKCkgewoKICAgICAgICAvLyBMb2NhbCB1dGlsaXR5IGNsYXNzIGZvciBjb2xsZWN0aW5nIHRoZSBhcmd1bWVudHMKICAgICAgICBjbGFzcyBTdGF0ZUFyZ3MgewoKICAgICAgICAgICAgcHJpdmF0ZSBMaXN0PFN0cmluZz4gYXJncyA9IG5ldyBBcnJheUxpc3Q8PigpOwoKICAgICAgICAgICAgdm9pZCBhZGRBcmcoT3B0aW9uIG9wdCkgewogICAgICAgICAgICAgICAgYXJncy5hZGQob3B0LmFyZyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHZvaWQgYWRkQXJnKE9wdGlvbiBvcHQsIE9iamVjdCB2YWwpIHsKICAgICAgICAgICAgICAgIGFkZEFyZyhvcHQpOwogICAgICAgICAgICAgICAgYXJncy5hZGQodmFsLnRvU3RyaW5nKCkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2b2lkIGFkZFNvdXJjZUxvY2F0aW9ucyhPcHRpb24gb3B0LCBMaXN0PFNvdXJjZUxvY2F0aW9uPiBsb2NzKSB7CiAgICAgICAgICAgICAgICBmb3IgKFNvdXJjZUxvY2F0aW9uIHNsIDogbG9jcykgewogICAgICAgICAgICAgICAgICAgIGZvciAoU3RyaW5nIHBrZyA6IHNsLmluY2x1ZGVzKSBhZGRBcmcoT3B0aW9uLkksIHBrZyk7CiAgICAgICAgICAgICAgICAgICAgZm9yIChTdHJpbmcgcGtnIDogc2wuZXhjbHVkZXMpIGFkZEFyZyhPcHRpb24uWCwgcGtnKTsKICAgICAgICAgICAgICAgICAgICBhZGRBcmcob3B0LCBzbC5nZXRQYXRoKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBTdHJpbmcgZ2V0UmVzdWx0KCkgewogICAgICAgICAgICAgICAgcmV0dXJuIFN0cmluZy5qb2luKCIgIiwgYXJncyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHB1YmxpYyB2b2lkIGFkZEFsbChDb2xsZWN0aW9uPFN0cmluZz4gdG9BZGQpIHsKICAgICAgICAgICAgICAgIGFyZ3MuYWRkQWxsKHRvQWRkKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgU3RhdGVBcmdzIGFyZ3MgPSBuZXcgU3RhdGVBcmdzKCk7CgogICAgICAgIC8vIERpcmVjdG9yaWVzCiAgICAgICAgaWYgKGdlblNyY0RpciAhPSBudWxsKQogICAgICAgICAgICBhcmdzLmFkZEFyZyhPcHRpb24uUywgZ2VuU3JjRGlyLm5vcm1hbGl6ZSgpKTsKCiAgICAgICAgaWYgKGhlYWRlckRpciAhPSBudWxsKQogICAgICAgICAgICBhcmdzLmFkZEFyZyhPcHRpb24uSCwgaGVhZGVyRGlyLm5vcm1hbGl6ZSgpKTsKCiAgICAgICAgaWYgKGRlc3REaXIgIT0gbnVsbCkKICAgICAgICAgICAgYXJncy5hZGRBcmcoT3B0aW9uLkQsIGRlc3REaXIubm9ybWFsaXplKCkpOwoKICAgICAgICBpZiAoc3RhdGVEaXIgIT0gbnVsbCkKICAgICAgICAgICAgYXJncy5hZGRBcmcoT3B0aW9uLlNUQVRFX0RJUiwgc3RhdGVEaXIubm9ybWFsaXplKCkpOwoKICAgICAgICAvLyBTb3VyY2Ugcm9vdHMKICAgICAgICBhcmdzLmFkZFNvdXJjZUxvY2F0aW9ucyhPcHRpb24uU1JDLCBzb3VyY2VzKTsKICAgICAgICBhcmdzLmFkZFNvdXJjZUxvY2F0aW9ucyhPcHRpb24uU09VUkNFX1BBVEgsIHNvdXJjZVNlYXJjaFBhdGhzKTsKICAgICAgICBhcmdzLmFkZFNvdXJjZUxvY2F0aW9ucyhPcHRpb24uQ0xBU1NfUEFUSCwgIGNsYXNzU2VhcmNoUGF0aHMpOwogICAgICAgIGFyZ3MuYWRkU291cmNlTG9jYXRpb25zKE9wdGlvbi5NT0RVTEVfUEFUSCwgbW9kdWxlU2VhcmNoUGF0aHMpOwoKICAgICAgICAvLyBCb29sZWFuIG9wdGlvbnMKICAgICAgICBpZiAocGVybWl0U291cmNlc0luRGVmYXVsdFBhY2thZ2UpCiAgICAgICAgICAgIGFyZ3MuYWRkQXJnKE9wdGlvbi5QRVJNSVRfU09VUkNFU19XSVRIT1VUX1BBQ0tBR0UpOwoKICAgICAgICBmb3IgKFN0cmluZyBmIDogcGVybWl0dGVkX2FydGlmYWN0cykgewogICAgICAgICAgICBhcmdzLmFkZEFyZyhPcHRpb24uUEVSTUlUX0FSVElGQUNULCBmKTsKICAgICAgICB9CgogICAgICAgIGlmIChwZXJtaXRVbmlkZW50aWZpZWRBcnRpZmFjdHMpCiAgICAgICAgICAgIGFyZ3MuYWRkQXJnKE9wdGlvbi5QRVJNSVRfVU5JREVOVElGSUVEX0FSVElGQUNUUyk7CgogICAgICAgIC8vIFRyYW5zbGF0aW9uIHJ1bGVzCiAgICAgICAgZm9yIChNYXAuRW50cnk8U3RyaW5nLCBUcmFuc2Zvcm1lcj4gdHIgOiB0clJ1bGVzLmVudHJ5U2V0KCkpIHsKICAgICAgICAgICAgU3RyaW5nIHZhbCA9IHRyLmdldEtleSgpICsgIj0iICsgdHIuZ2V0VmFsdWUoKS5nZXRDbGFzcygpLmdldE5hbWUoKTsKICAgICAgICAgICAgYXJncy5hZGRBcmcoT3B0aW9uLlRSLCB2YWwpOwogICAgICAgIH0KCiAgICAgICAgLy8gSmF2YWMgYXJncwogICAgICAgIGFyZ3MuYWRkQWxsKGphdmFjQXJncyk7CgogICAgICAgIHJldHVybiBhcmdzLmdldFJlc3VsdCgpOwogICAgfQoKCiAgICAvKiogRXh0cmFjdCB0aGUgYXJndW1lbnRzIHRvIGJlIHBhc3NlZCBvbiB0byBqYXZhYy4gKi8KICAgIHB1YmxpYyBTdHJpbmdbXSBwcmVwSmF2YWNBcmdzKCkgewogICAgICAgIExpc3Q8U3RyaW5nPiBhcmdzID0gbmV3IEFycmF5TGlzdDw+KCk7CgogICAgICAgIC8vIE91dHB1dCBkaXJlY3RvcmllcwogICAgICAgIGFyZ3MuYWRkKCItZCIpOwogICAgICAgIGFyZ3MuYWRkKGRlc3REaXIudG9TdHJpbmcoKSk7CgogICAgICAgIGlmIChnZXRHZW5TcmNEaXIoKSAhPSBudWxsKSB7CiAgICAgICAgICAgIGFyZ3MuYWRkKCItcyIpOwogICAgICAgICAgICBhcmdzLmFkZChnZW5TcmNEaXIudG9TdHJpbmcoKSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoaGVhZGVyRGlyICE9IG51bGwpIHsKICAgICAgICAgICAgYXJncy5hZGQoIi1oIik7CiAgICAgICAgICAgIGFyZ3MuYWRkKGhlYWRlckRpci50b1N0cmluZygpKTsKICAgICAgICB9CgogICAgICAgIC8vIFByZXAgc291cmNlcGF0aAogICAgICAgIExpc3Q8U291cmNlTG9jYXRpb24+IHNvdXJjZXBhdGggPSBuZXcgQXJyYXlMaXN0PD4oKTsKICAgICAgICBzb3VyY2VwYXRoLmFkZEFsbChzb3VyY2VzKTsKICAgICAgICBzb3VyY2VwYXRoLmFkZEFsbChzb3VyY2VTZWFyY2hQYXRocyk7CiAgICAgICAgaWYgKHNvdXJjZXBhdGguc2l6ZSgpID4gMCkgewogICAgICAgICAgICBhcmdzLmFkZCgiLXNvdXJjZXBhdGgiKTsKICAgICAgICAgICAgYXJncy5hZGQoY29uY2F0ZW5hdGVTb3VyY2VMb2NhdGlvbnMoc291cmNlcGF0aCkpOwogICAgICAgIH0KCiAgICAgICAgLy8gUHJlcCBjbGFzc3BhdGgKICAgICAgICBpZiAoY2xhc3NTZWFyY2hQYXRocy5zaXplKCkgPiAwKSB7CiAgICAgICAgICAgIGFyZ3MuYWRkKCItY2xhc3NwYXRoIik7CiAgICAgICAgICAgIGFyZ3MuYWRkKGNvbmNhdGVuYXRlU291cmNlTG9jYXRpb25zKGNsYXNzU2VhcmNoUGF0aHMpKTsKICAgICAgICB9CgogICAgICAgIC8vIEVuYWJsZSBkZXBlbmRlbmN5IGdlbmVyYXRpb24KICAgICAgICBhcmdzLmFkZCgiLS1kZWJ1Zzpjb21wbGV0aW9uRGVwcz1zb3VyY2UsY2xhc3MiKTsKCiAgICAgICAgLy8gVGhpcyBjYW4ndCBiZSBhbnl0aGluZyBidXQgJ25vbmUnLiBFbmZvcmNlZCBieSBzamF2YWMgbWFpbiBtZXRob2QuCiAgICAgICAgYXJncy5hZGQoIi1pbXBsaWNpdDoiICsgaW1wbGljaXRQb2xpY3kpOwoKICAgICAgICAvLyBJZiB0aGlzIG9wdGlvbiBpcyBub3QgdXNlZCwgT2JqZWN0IGZvciBpbnN0YW5jZSBpcyBlcnJvbmVvdXNseQogICAgICAgIC8vIHBpY2tlZCB1cCBmcm9tIFBMQVRGT1JNX0NMQVNTX1BBVEggaW5zdGVhZCBvZiBDTEFTU19QQVRILgogICAgICAgIC8vCiAgICAgICAgLy8gRGlzY3Vzc2luZyB0aGlzIGZ1cnRoZXIgbGVkIHRvIHRoZSBkZWNpc2lvbiBvZiBsZXR0aW5nIGJvb3RjbGFzc3BhdGgKICAgICAgICAvLyBiZSBhIGR1bW15IChlbXB0eSkgZGlyZWN0b3J5IHdoZW4gYnVpbGRpbmcgdGhlIEpESy4KICAgICAgICAvL2FyZ3MuYWRkKCItWFh1c2VyUGF0aHNGaXJzdCIpOwoKICAgICAgICAvLyBBcHBlbmQgamF2YWMtb3B0aW9ucyAoaS5lLiBwYXNzIHRocm91Z2ggb3B0aW9ucyBub3QgcmVjb2duaXplZCBieQogICAgICAgIC8vIHNqYXZhYyB0byBqYXZhYy4pCiAgICAgICAgYXJncy5hZGRBbGwoamF2YWNBcmdzKTsKCiAgICAgICAgcmV0dXJuIGFyZ3MudG9BcnJheShuZXcgU3RyaW5nW2FyZ3Muc2l6ZSgpXSk7CiAgICB9CgogICAgLy8gSGVscGVyIG1ldGhvZCB0byBqb2luIGEgbGlzdCBvZiBzb3VyY2UgbG9jYXRpb25zIHNlcGFyYXRlZCBieQogICAgLy8gRmlsZS5wYXRoU2VwYXJhdG9yCiAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgY29uY2F0ZW5hdGVTb3VyY2VMb2NhdGlvbnMoTGlzdDxTb3VyY2VMb2NhdGlvbj4gbG9jcykgewogICAgICAgIFN0cmluZ0pvaW5lciBqb2luZXIgPSBuZXcgU3RyaW5nSm9pbmVyKGphdmEuaW8uRmlsZS5wYXRoU2VwYXJhdG9yKTsKICAgICAgICBmb3IgKFNvdXJjZUxvY2F0aW9uIGxvYyA6IGxvY3MpIHsKICAgICAgICAgICAgam9pbmVyLmFkZChsb2MuZ2V0UGF0aCgpLnRvU3RyaW5nKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gam9pbmVyLnRvU3RyaW5nKCk7CiAgICB9CgogICAgLy8gT3B0aW9uSGVscGVyIHRoYXQgcmVjb3JkcyB0aGUgdHJhdmVyc2VkIG9wdGlvbnMgaW4gdGhpcyBPcHRpb25zIGluc3RhbmNlLgogICAgcHJpdmF0ZSBjbGFzcyBBcmdEZWNvZGVyT3B0aW9uSGVscGVyIGV4dGVuZHMgT3B0aW9uSGVscGVyIHsKCiAgICAgICAgTGlzdDxTdHJpbmc+IGluY2x1ZGVzLCBleGNsdWRlcywgaW5jbHVkZUZpbGVzLCBleGNsdWRlRmlsZXM7CiAgICAgICAgewogICAgICAgICAgICByZXNldEZpbHRlcnMoKTsKICAgICAgICB9CgogICAgICAgIGJvb2xlYW4gaGVhZGVyUHJvdmlkZWQgPSBmYWxzZTsKICAgICAgICBib29sZWFuIGdlblNyY1Byb3ZpZGVkID0gZmFsc2U7CiAgICAgICAgYm9vbGVhbiBzdGF0ZVByb3ZpZGVkID0gZmFsc2U7CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHJlcG9ydEVycm9yKFN0cmluZyBtc2cpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihtc2cpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgc291cmNlUm9vdHMoTGlzdDxQYXRoPiBwYXRocykgewogICAgICAgICAgICBzb3VyY2VzLmFkZEFsbChjcmVhdGVTb3VyY2VMb2NhdGlvbnMocGF0aHMpKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIGV4Y2x1ZGUoU3RyaW5nIGV4Y2xQYXR0ZXJuKSB7CiAgICAgICAgICAgIGV4Y2xQYXR0ZXJuID0gVXRpbC5ub3JtYWxpemVEcml2ZUxldHRlcihleGNsUGF0dGVybik7CiAgICAgICAgICAgIGV4Y2x1ZGVzLmFkZChleGNsUGF0dGVybik7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCBpbmNsdWRlKFN0cmluZyBpbmNsUGF0dGVybikgewogICAgICAgICAgICBpbmNsUGF0dGVybiA9IFV0aWwubm9ybWFsaXplRHJpdmVMZXR0ZXIoaW5jbFBhdHRlcm4pOwogICAgICAgICAgICBpbmNsdWRlcy5hZGQoaW5jbFBhdHRlcm4pOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgYWRkVHJhbnNmb3JtZXIoU3RyaW5nIHN1ZmZpeCwgVHJhbnNmb3JtZXIgdHIpIHsKICAgICAgICAgICAgaWYgKHRyUnVsZXMuY29udGFpbnNLZXkoc3VmZml4KSkgewogICAgICAgICAgICAgICAgcmVwb3J0RXJyb3IoIk1vcmUgdGhhbiBvbmUgdHJhbnNmb3JtZXIgc3BlY2lmaWVkIGZvciAiICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJzdWZmaXggIiArIHN1ZmZpeCArICIuIik7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdHJSdWxlcy5wdXQoc3VmZml4LCB0cik7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCBzb3VyY2VwYXRoKExpc3Q8UGF0aD4gcGF0aHMpIHsKICAgICAgICAgICAgc291cmNlU2VhcmNoUGF0aHMuYWRkQWxsKGNyZWF0ZVNvdXJjZUxvY2F0aW9ucyhwYXRocykpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgbW9kdWxlcGF0aChMaXN0PFBhdGg+IHBhdGhzKSB7CiAgICAgICAgICAgIG1vZHVsZVNlYXJjaFBhdGhzLmFkZEFsbChjcmVhdGVTb3VyY2VMb2NhdGlvbnMocGF0aHMpKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIGNsYXNzcGF0aChMaXN0PFBhdGg+IHBhdGhzKSB7CiAgICAgICAgICAgIGNsYXNzU2VhcmNoUGF0aHMuYWRkQWxsKGNyZWF0ZVNvdXJjZUxvY2F0aW9ucyhwYXRocykpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgbnVtQ29yZXMoaW50IG4pIHsKICAgICAgICAgICAgbnVtQ29yZXMgPSBuOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgbG9nTGV2ZWwoU3RyaW5nIGxldmVsKSB7CiAgICAgICAgICAgIGxvZ0xldmVsID0gbGV2ZWw7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCBjb21wYXJlRm91bmRTb3VyY2VzKFBhdGggcmVmZXJlbmNlTGlzdCkgewogICAgICAgICAgICBzb3VyY2VSZWZlcmVuY2VMaXN0ID0gcmVmZXJlbmNlTGlzdDsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHBlcm1pdEFydGlmYWN0KFN0cmluZyBmKSB7CiAgICAgICAgICAgIHBlcm1pdHRlZF9hcnRpZmFjdHMuYWRkKGYpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgcGVybWl0VW5pZGVudGlmaWVkQXJ0aWZhY3RzKCkgewogICAgICAgICAgICBwZXJtaXRVbmlkZW50aWZpZWRBcnRpZmFjdHMgPSB0cnVlOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgcGVybWl0RGVmYXVsdFBhY2thZ2UoKSB7CiAgICAgICAgICAgIHBlcm1pdFNvdXJjZXNJbkRlZmF1bHRQYWNrYWdlID0gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHNlcnZlckNvbmYoU3RyaW5nIGNvbmYpIHsKICAgICAgICAgICAgaWYgKHNlcnZlckNvbmYgIT0gbnVsbCkKICAgICAgICAgICAgICAgIHJlcG9ydEVycm9yKCJDYW4gbm90IHNwZWNpZnkgbW9yZSB0aGFuIG9uZSBzZXJ2ZXIgY29uZmlndXJhdGlvbi4iKTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgc2VydmVyQ29uZiA9IGNvbmY7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCBpbXBsaWNpdChTdHJpbmcgcG9saWN5KSB7CiAgICAgICAgICAgIGltcGxpY2l0UG9saWN5ID0gcG9saWN5OwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgc3RhcnRTZXJ2ZXJDb25mKFN0cmluZyBjb25mKSB7CiAgICAgICAgICAgIGlmIChzZXJ2ZXJDb25mICE9IG51bGwpCiAgICAgICAgICAgICAgICByZXBvcnRFcnJvcigiQ2FuIG5vdCBzcGVjaWZ5IG1vcmUgdGhhbiBvbmUgc2VydmVyIGNvbmZpZ3VyYXRpb24uIik7CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgc3RhcnRTZXJ2ZXIgPSB0cnVlOwogICAgICAgICAgICAgICAgc2VydmVyQ29uZiA9IGNvbmY7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIGphdmFjQXJnKFN0cmluZy4uLiBhcmcpIHsKICAgICAgICAgICAgamF2YWNBcmdzLmFkZEFsbChBcnJheXMuYXNMaXN0KGFyZykpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgZGVzdERpcihQYXRoIGRpcikgewogICAgICAgICAgICBpZiAoZGVzdERpciAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICByZXBvcnRFcnJvcigiRGVzdGluYXRpb24gZGlyZWN0b3J5IGFscmVhZHkgc3BlY2lmaWVkLiIpOwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGRlc3REaXIgPSBkaXIudG9BYnNvbHV0ZVBhdGgoKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIGdlbmVyYXRlZFNvdXJjZXNEaXIoUGF0aCBkaXIpIHsKICAgICAgICAgICAgaWYgKGdlblNyY1Byb3ZpZGVkKSB7CiAgICAgICAgICAgICAgICByZXBvcnRFcnJvcigiRGlyZWN0b3J5IGZvciBnZW5lcmF0ZWQgc291cmNlcyBhbHJlYWR5IHNwZWNpZmllZC4iKTsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgICAgICBnZW5TcmNQcm92aWRlZCA9IHRydWU7CiAgICAgICAgICAgIGdlblNyY0RpciA9IGRpci50b0Fic29sdXRlUGF0aCgpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgaGVhZGVyRGlyKFBhdGggZGlyKSB7CiAgICAgICAgICAgIGlmIChoZWFkZXJQcm92aWRlZCkgewogICAgICAgICAgICAgICAgcmVwb3J0RXJyb3IoIkhlYWRlciBkaXJlY3RvcnkgYWxyZWFkeSBzcGVjaWZpZWQuIik7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaGVhZGVyUHJvdmlkZWQgPSB0cnVlOwogICAgICAgICAgICBoZWFkZXJEaXIgPSBkaXIudG9BYnNvbHV0ZVBhdGgoKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHN0YXRlRGlyKFBhdGggZGlyKSB7CiAgICAgICAgICAgIGlmIChzdGF0ZVByb3ZpZGVkKSB7CiAgICAgICAgICAgICAgICByZXBvcnRFcnJvcigiU3RhdGUgZGlyZWN0b3J5IGFscmVhZHkgc3BlY2lmaWVkLiIpOwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHN0YXRlUHJvdmlkZWQgPSB0cnVlOwogICAgICAgICAgICBzdGF0ZURpciA9IGRpci50b0Fic29sdXRlUGF0aCgpOwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBMaXN0PFNvdXJjZUxvY2F0aW9uPiBjcmVhdGVTb3VyY2VMb2NhdGlvbnMoTGlzdDxQYXRoPiBwYXRocykgewogICAgICAgICAgICBMaXN0PFNvdXJjZUxvY2F0aW9uPiByZXN1bHQgPSBuZXcgQXJyYXlMaXN0PD4oKTsKICAgICAgICAgICAgZm9yIChQYXRoIHBhdGggOiBwYXRocykgewogICAgICAgICAgICAgICAgcmVzdWx0LmFkZChuZXcgU291cmNlTG9jYXRpb24oCiAgICAgICAgICAgICAgICAgICAgICAgIHBhdGgsCiAgICAgICAgICAgICAgICAgICAgICAgIGluY2x1ZGVzLAogICAgICAgICAgICAgICAgICAgICAgICBleGNsdWRlcykpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJlc2V0RmlsdGVycygpOwogICAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSB2b2lkIHJlc2V0RmlsdGVycygpIHsKICAgICAgICAgICAgaW5jbHVkZXMgPSBuZXcgQXJyYXlMaXN0PD4oKTsKICAgICAgICAgICAgZXhjbHVkZXMgPSBuZXcgQXJyYXlMaXN0PD4oKTsKICAgICAgICAgICAgaW5jbHVkZUZpbGVzID0gbmV3IEFycmF5TGlzdDw+KCk7CiAgICAgICAgICAgIGV4Y2x1ZGVGaWxlcyA9IG5ldyBBcnJheUxpc3Q8PigpOwogICAgICAgIH0KICAgIH0KCn0KUEsDBAoAAAgAAAY7qUrTcDgXthYAALYWAAAuAAAAY29tL3N1bi90b29scy9zamF2YWMvb3B0aW9ucy9PcHRpb25IZWxwZXIuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAxNCwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLnNqYXZhYy5vcHRpb25zOwoKaW1wb3J0IGphdmEubmlvLmZpbGUuUGF0aDsKaW1wb3J0IGphdmEubmlvLmZpbGUuUGF0aHM7CmltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOwppbXBvcnQgamF2YS51dGlsLkxpc3Q7CgppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5tYWluLkNvbW1hbmRMaW5lOwppbXBvcnQgY29tLnN1bi50b29scy5zamF2YWMuVHJhbnNmb3JtZXI7CgovKioKICogVGhpcyBjbGFzcyBpcyB1c2VkIHRvIGRlY29kZSBzamF2YWMgb3B0aW9ucy4KICogU2VlIGNvbS5zdW4udG9vbHMuc2phdmFjLm9wdGlvbnMuT3B0aW9ucyBmb3IgZXhhbXBsZSB1c2FnZS4KICoKICogIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqICBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqICBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogKiAgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPgogKi8KcHVibGljIGFic3RyYWN0IGNsYXNzIE9wdGlvbkhlbHBlciB7CgogICAgLyoqIEhhbmRsZSBlcnJvciAqLwogICAgcHVibGljIGFic3RyYWN0IHZvaWQgcmVwb3J0RXJyb3IoU3RyaW5nIG1zZyk7CgogICAgLyoqIFJlY29yZCBhIHBhY2thZ2UgZXhjbHVzaW9uIHBhdHRlcm4gKi8KICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIGV4Y2x1ZGUoU3RyaW5nIGV4Y2wpOwoKICAgIC8qKiBSZWNvcmQgYSBwYWNrYWdlIGluY2x1c2lvbiBwYXR0ZXJuICovCiAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBpbmNsdWRlKFN0cmluZyBpbmNsKTsKCiAgICAvKiogUmVjb3JkIGEgcm9vdCBvZiBzb3VyY2VzIHRvIGJlIGNvbXBpbGVkICovCiAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzb3VyY2VSb290cyhMaXN0PFBhdGg+IHBhdGgpOwoKICAgIC8qKiBSZWNvcmQgYSBzdWZmaXggKyB0cmFuc2Zvcm1lciAqLwogICAgcHVibGljIGFic3RyYWN0IHZvaWQgYWRkVHJhbnNmb3JtZXIoU3RyaW5nIHN1ZmZpeCwgVHJhbnNmb3JtZXIgdHIpOwoKICAgIC8qKiBSZWNvcmQgYSBzb3VyY2VwYXRoIHRvIGJlIHVzZWQgKi8KICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHNvdXJjZXBhdGgoTGlzdDxQYXRoPiBwYXRoKTsKCiAgICAvKiogUmVjb3JkIGEgbW9kdWxlcGF0aCB0byBiZSB1c2VkICovCiAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBtb2R1bGVwYXRoKExpc3Q8UGF0aD4gcGF0aCk7CgogICAgLyoqIFJlY29yZCBhIGNsYXNzcGF0aCB0byBiZSB1c2VkICovCiAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBjbGFzc3BhdGgoTGlzdDxQYXRoPiBwYXRoKTsKCiAgICAvKiogUmVjb3JkIHRoZSBudW1iZXIgb2YgY29yZXMgKi8KICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIG51bUNvcmVzKGludCBwYXJzZUludCk7CgogICAgLyoqIFJlY29yZCBkZXNpcmVkIGxvZyBsZXZlbCAqLwogICAgcHVibGljIGFic3RyYWN0IHZvaWQgbG9nTGV2ZWwoU3RyaW5nIGxldmVsKTsKCiAgICAvKiogUmVjb3JkIHBhdGggZm9yIHJlZmVyZW5jZSBzb3VyY2UgbGlzdCAqLwogICAgcHVibGljIGFic3RyYWN0IHZvaWQgY29tcGFyZUZvdW5kU291cmNlcyhQYXRoIHJlZmVyZW5jZUxpc3QpOwoKICAgIC8qKiBSZWNvcmQgYSBzaW5nbGUgcGVybWl0dGVkIGFydGlmYWN0ICovCiAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBwZXJtaXRBcnRpZmFjdChTdHJpbmcgZik7CgogICAgLyoqIFJlY29yZCB0aGUgZmFjdCB0aGF0IHVuaWRlbnRpZmllZCBhcnRpZmFjdHMgYXJlIHBlcm1pdHRlZCAqLwogICAgcHVibGljIGFic3RyYWN0IHZvaWQgcGVybWl0VW5pZGVudGlmaWVkQXJ0aWZhY3RzKCk7CgogICAgLyoqIFJlY29yZCB0aGUgZmFjdCB0aGF0IHNvdXJjZXMgaW4gdGhlIGRlZmF1bHQgcGFja2FnZSBhcmUgcGVybWl0dGVkICovCiAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBwZXJtaXREZWZhdWx0UGFja2FnZSgpOwoKICAgIC8qKiBSZWNvcmQgc2VydmVyIGNvbmZpZ3VyYXRpb24gcGFyYW1ldGVycyAqLwogICAgcHVibGljIGFic3RyYWN0IHZvaWQgc2VydmVyQ29uZihTdHJpbmcgc2VydmVyQ29uZik7CgogICAgLyoqIFJlY29yZCBzZXJ2ZXIgbGF1bmNoIGNvbmZpZ3VyYXRpb24gcGFyYW1ldGVycyAqLwogICAgcHVibGljIGFic3RyYWN0IHZvaWQgc3RhcnRTZXJ2ZXJDb25mKFN0cmluZyBzZXJ2ZXJDb25mKTsKCiAgICAvKiogUmVjb3JkIHNvbWUgYXJndW1lbnRzIHRvIGJlIHBhc3NlZCBvbiB0byBqYXZhYyAqLwogICAgcHVibGljIGFic3RyYWN0IHZvaWQgamF2YWNBcmcoU3RyaW5nLi4uIGFyZyk7CgogICAgLyoqIFNldHMgdGhlIGRlc3RpbmF0aW9uIGRpcmVjdG9yeSBmb3IgdGhlIGNvbXBpbGF0aW9uICovCiAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBkZXN0RGlyKFBhdGggZGlyKTsKCiAgICAvKiogU2V0cyB0aGUgZGlyZWN0b3J5IGZvciBnZW5lcmF0ZWQgc291cmNlcyAqLwogICAgcHVibGljIGFic3RyYWN0IHZvaWQgZ2VuZXJhdGVkU291cmNlc0RpcihQYXRoIGdlblNyY0Rpcik7CgogICAgLyoqIFNldHMgdGhlIGRpcmVjdG9yeSBmb3IgZ2VuZXJhdGVkIGhlYWRlcnMgKi8KICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIGhlYWRlckRpcihQYXRoIGRpcik7CgogICAgLyoqIFNldHMgdGhlIGRpcmVjdG9yeSBmb3Igc3RhdGUgYW5kIGxvZyBmaWxlcyBnZW5lcmF0ZWQgYnkgc2phdmFjICovCiAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzdGF0ZURpcihQYXRoIGRpcik7CgogICAgLyoqIFNldHMgdGhlIGltcGxpY2l0IHBvbGljeSAqLwogICAgcHVibGljIGFic3RyYWN0IHZvaWQgaW1wbGljaXQoU3RyaW5nIHBvbGljeSk7CgoKICAgIC8qKgogICAgICogVHJhdmVyc2VzIGFuIGFycmF5IG9mIGFyZ3VtZW50cyBhbmQgcGVyZm9ybXMgdGhlIGFwcHJvcHJpYXRlIGNhbGxiYWNrcy4KICAgICAqCiAgICAgKiBAcGFyYW0gYXJncyB0aGUgYXJndW1lbnRzIHRvIHRyYXZlcnNlLgogICAgICovCiAgICB2b2lkIHRyYXZlcnNlKFN0cmluZ1tdIGFyZ3MpIHsKICAgICAgICB0cnkgewogICAgICAgICAgICBhcmdzID0gQ29tbWFuZExpbmUucGFyc2UoYXJncyk7IC8vIERldGVjdCBAZmlsZSBhbmQgbG9hZCBpdCBhcyBhIGNvbW1hbmQgbGluZS4KICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiUHJvYmxlbSByZWFkaW5nIEAiK2UuZ2V0TWVzc2FnZSgpKTsKICAgICAgICB9CiAgICAgICAgQXJndW1lbnRJdGVyYXRvciBhcmdJdGVyID0gbmV3IEFyZ3VtZW50SXRlcmF0b3IoQXJyYXlzLmFzTGlzdChhcmdzKSk7CgogICAgICAgIG5leHRBcmc6CiAgICAgICAgd2hpbGUgKGFyZ0l0ZXIuaGFzTmV4dCgpKSB7CgogICAgICAgICAgICBTdHJpbmcgYXJnID0gYXJnSXRlci5uZXh0KCk7CgogICAgICAgICAgICBpZiAoYXJnLnN0YXJ0c1dpdGgoIi0iKSkgewogICAgICAgICAgICAgICAgZm9yIChPcHRpb24gb3B0IDogT3B0aW9uLnZhbHVlcygpKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKG9wdC5wcm9jZXNzQ3VycmVudChhcmdJdGVyLCB0aGlzKSkKICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWUgbmV4dEFyZzsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBqYXZhY0FyZyhhcmcpOwoKICAgICAgICAgICAgICAgIC8vIERvZXMgdGhpcyBqYXZhYyBhcmd1bWVudCB0YWtlIGFuIGFyZ3VtZW50PyBJZiBzbywgZG9uJ3QKICAgICAgICAgICAgICAgIC8vIGxldCBpdCBwYXNzIG9uIHRvIHNqYXZhYyBhcyBhIHNvdXJjZSByb290IGRpcmVjdG9yeS4KICAgICAgICAgICAgICAgIGZvciAoY29tLnN1bi50b29scy5qYXZhYy5tYWluLk9wdGlvbiBqYXZhY09wdCA6IGNvbS5zdW4udG9vbHMuamF2YWMubWFpbi5PcHRpb24udmFsdWVzKCkpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoamF2YWNPcHQubWF0Y2hlcyhhcmcpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gdGFrZXNBcmd1bWVudCA9IGphdmFjT3B0Lmhhc0FyZygpOwogICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIHNlcGFyYXRlVG9rZW4gPSAhYXJnLmNvbnRhaW5zKCI6IikgJiYgIWFyZy5jb250YWlucygiPSIpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAodGFrZXNBcmd1bWVudCAmJiBzZXBhcmF0ZVRva2VuKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgamF2YWNBcmcoYXJnSXRlci5uZXh0KCkpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHNvdXJjZVJvb3RzKEFycmF5cy5hc0xpc3QoUGF0aHMuZ2V0KGFyZykpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIFN0cmluZyB1bmVzY2FwZUNtZEFyZyhTdHJpbmcgYXJnKSB7CiAgICAgICAgcmV0dXJuIGFyZy5yZXBsYWNlQWxsKCIlMjAiLCAiICIpCiAgICAgICAgICAgICAgICAgIC5yZXBsYWNlQWxsKCIlMkMiLCAiLCIpOwogICAgfQp9ClBLAwQKAAAIAAAGO6lKAAAAAAAAAAAAAAAAFAAAAGNvbS9zdW4vdG9vbHMvamF2YWgvUEsDBAoAAAgAAAY7qUoAAAAAAAAAAAAAAAAeAAAAY29tL3N1bi90b29scy9qYXZhaC9yZXNvdXJjZXMvUEsDBAoAAAgAAAY7qUpYeGNDOR0AADkdAAAzAAAAY29tL3N1bi90b29scy9qYXZhaC9yZXNvdXJjZXMvbDEwbl96aF9DTi5wcm9wZXJ0aWVzIwojIENvcHlyaWdodCAoYykgMTk5OCwgMjAxNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KIyBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiMKIyBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAojIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiMgcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAojIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgojCiMgVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiMgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiMgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiMgdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKIyBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgojCiMgWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgojIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKIyBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiMKIyBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQojIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKIyBxdWVzdGlvbnMuCiMKCiMKIyBVc2VyIGVycm9ycywgY29tbWFuZCBsaW5lIGVycm9ycy4KIwpjYW50LmNyZWF0ZS5kaXI9XHU2NUUwXHU2Q0Q1XHU0RTNBXHU4RjkzXHU1MUZBXHU1MjFCXHU1RUZBXHU3NkVFXHU1RjU1IHswfVx1MzAwMgphdC5hcmdzLmNhbnQucmVhZD1cdTY1RTBcdTZDRDVcdTRFQ0VcdTY1ODdcdTRFRjZ7MX1cdTRFMkRcdThCRkJcdTUzRDZcdTU0N0RcdTRFRTRcdTg4NENcdTUzQzJcdTY1NzBcdTMwMDIKYXQuYXJncy5maWxlLm5vdC5mb3VuZD1cdTYyN0VcdTRFMERcdTUyMzBcdTY1ODdcdTRFRjZ7MH1cdTMwMDIKYXQuYXJncy5pby5leGNlcHRpb249XHU1OTA0XHU3NDA2XHU1NDdEXHU0RUU0XHU4ODRDXHU0RTJEXHU3Njg0IEAgXHU1M0MyXHU2NTcwXHU2NUY2LCBcdTkwNDdcdTUyMzBcdTRFRTVcdTRFMEIgSS9PIFx1OTVFRVx1OTg5ODogezB9XHUzMDAyCmJhZC5hcmc9XHU5NTE5XHU4QkVGXHU1M0MyXHU2NTcwOiB7MH0Kb2xkLmpuaS5taXhlZD1cdTRFMERcdTgwRkRcdTZERjdcdTc1MjhcdTkwMDlcdTk4NzkgLWpuaSBcdTU0OEMgLW9sZFx1MzAwMlx1OEJGN1x1NUMxRFx1OEJENVx1NEY3Rlx1NzUyOCAtaGVscFx1MzAwMgpvbGQubGxuaS5taXhlZD1cdTRFMERcdTgwRkRcdTZERjdcdTc1MjhcdTkwMDlcdTk4NzkgLW9sZCBcdTU0OEMgLWxsbmlcdTMwMDJcdThCRjdcdTVDMURcdThCRDVcdTRGN0ZcdTc1MjggLWhlbHBcdTMwMDIKb2xkLm5vdC5zdXBwb3J0ZWQ9XHU2QjY0XHU3MjQ4XHU2NzJDXHU3Njg0IGphdmFoIFx1NEUwRFx1NjUyRlx1NjMwMVx1OTAwOVx1OTg3OSAtb2xkXHUzMDAyCmludmFsaWQubWV0aG9kLnNpZ25hdHVyZT1cdTY1RTBcdTY1NDhcdTc2ODRcdTY1QjlcdTZDRDVcdTdCN0VcdTU0MEQ6IHswfQpqbmkubGxuaS5taXhlZD1cdTRFMERcdTgwRkRcdTZERjdcdTc1MjhcdTkwMDlcdTk4NzkgLWpuaSBcdTU0OEMgLWxsbmlcdTMwMDJcdThCRjdcdTVDMURcdThCRDVcdTRGN0ZcdTc1MjggLWhlbHBcdTMwMDIKam5pLm5vLnN0dWJzPUpOSSBcdTRFMERcdTk3MDBcdTg5ODFcdTVCNThcdTY4MzksIFx1OEJGN1x1NTNDMlx1OTYwNSBKTkkgXHU2NTg3XHU2ODYzXHUzMDAyCmpuaS5zaWdlcnJvcj1cdTY1RTBcdTZDRDVcdTc4NkVcdTVCOUF7MH1cdTc2ODRcdTdCN0VcdTU0MEQKZGlyLmZpbGUubWl4ZWQ9XHU0RTBEXHU4MEZEXHU2REY3XHU3NTI4XHU5MDA5XHU5ODc5IC1kIFx1NTQ4QyAtb1x1MzAwMlx1OEJGN1x1NUMxRFx1OEJENVx1NEY3Rlx1NzUyOCAtaGVscFx1MzAwMgpuby5jbGFzc2VzLnNwZWNpZmllZD1cdTY3MkFcdTU3MjhcdTU0N0RcdTRFRTRcdTg4NENcdTRFMkRcdTYzMDdcdTVCOUFcdTRFRkJcdTRGNTVcdTdDN0JcdTMwMDJcdThCRjdcdTVDMURcdThCRDVcdTRGN0ZcdTc1MjggLWhlbHBcdTMwMDIKbm8ub3V0cHV0ZmlsZS5zcGVjaWZpZWQ9XHU2NzJBXHU1NzI4XHU1NDdEXHU0RUU0XHU4ODRDXHU0RTJEXHU2MzA3XHU1QjlBXHU0RUZCXHU0RjU1XHU4RjkzXHU1MUZBXHU2NTg3XHU0RUY2XHUzMDAyXHU4QkY3XHU1QzFEXHU4QkQ1XHU0RjdGXHU3NTI4IC1oZWxwXHUzMDAyCm5vLm91dHB1dGRpci5zcGVjaWZpZWQ9XHU2NzJBXHU1NzI4XHU1NDdEXHU0RUU0XHU4ODRDXHU0RTJEXHU2MzA3XHU1QjlBXHU0RUZCXHU0RjU1XHU4RjkzXHU1MUZBXHU3NkVFXHU1RjU1XHUzMDAyXHU4QkY3XHU1QzFEXHU4QkQ1XHU0RjdGXHU3NTI4IC1oZWxwXHUzMDAyCm5vLmNsYXNzcGF0aC5zcGVjaWZpZWQ9XHU2NzJBXHU1NzI4XHU1NDdEXHU0RUU0XHU4ODRDXHU0RTJEXHU2MzA3XHU1QjlBXHU0RUZCXHU0RjU1XHU3QzdCXHU4REVGXHU1Rjg0XHUzMDAyXHU4QkY3XHU1QzFEXHU4QkQ1XHU0RjdGXHU3NTI4IC1oZWxwXHUzMDAyCm5vLmJvb3RjbGFzc3BhdGguc3BlY2lmaWVkPVx1NjcyQVx1NTcyOFx1NTQ3RFx1NEVFNFx1ODg0Q1x1NEUyRFx1NjMwN1x1NUI5QVx1NEVGQlx1NEY1NVx1NUYxNVx1NUJGQ1x1N0M3Qlx1OERFRlx1NUY4NFx1MzAwMlx1OEJGN1x1NUMxRFx1OEJENVx1NEY3Rlx1NzUyOCAtaGVscFx1MzAwMgp1bmtub3duLm9wdGlvbj17MH1cdTY2MkZcdTk3NUVcdTZDRDVcdTUzQzJcdTY1NzBcbgp0cmFjaW5nLm5vdC5zdXBwb3J0ZWQ9XHU4QjY2XHU1NDRBOiBcdTRFMERcdTUxOERcdTY1MkZcdTYzMDFcdThEREZcdThFMkFcdTMwMDJcdThCRjdcdTRGN0ZcdTc1MjhcdTg2NUFcdTYyREZcdTY3M0FcdTc2ODQgLXZlcmJvc2U6am5pIFx1OTAwOVx1OTg3OVx1MzAwMgoKbWFpbi51c2FnZT1cdTc1MjhcdTZDRDU6IFxuICBqYXZhaCBbb3B0aW9uc10gPGNsYXNzZXM+XG5cdTUxNzZcdTRFMkQsIFtvcHRpb25zXSBcdTUzMDVcdTYyRUM6CgptYWluLm9wdC5vPVwgIC1vIDxmaWxlPiAgICAgICAgICAgICAgICAgICAgXHU4RjkzXHU1MUZBXHU2NTg3XHU0RUY2IChcdTUzRUFcdTgwRkRcdTRGN0ZcdTc1MjggLWQgXHU2MjE2IC1vIFx1NEU0Qlx1NEUwMCkKCm1haW4ub3B0LmQ9XCAgLWQgPGRpcj4gICAgICAgICAgICAgICAgICAgICBcdThGOTNcdTUxRkFcdTc2RUVcdTVGNTUKCm1haW4ub3B0LnY9XCAgLXYgIC12ZXJib3NlICAgICAgICAgICAgICAgICBcdTU0MkZcdTc1MjhcdThCRTZcdTdFQzZcdThGOTNcdTUxRkEKCm1haW4ub3B0Lmg9XCAgLWggIC0taGVscCAgLT8gICAgICAgICAgICAgICBcdThGOTNcdTUxRkFcdTZCNjRcdTZEODhcdTYwNkYKCm1haW4ub3B0LnZlcnNpb249XCAgLXZlcnNpb24gICAgICAgICAgICAgICAgICAgICBcdThGOTNcdTUxRkFcdTcyNDhcdTY3MkNcdTRGRTFcdTYwNkYKCm1haW4ub3B0LmpuaT1cICAtam5pICAgICAgICAgICAgICAgICAgICAgICAgIFx1NzUxRlx1NjIxMCBKTkkgXHU2ODM3XHU1RjBGXHU3Njg0XHU2ODA3XHU1OTM0XHU2NTg3XHU0RUY2IChcdTlFRDhcdThCQTRcdTUwM0MpCgptYWluLm9wdC5mb3JjZT1cICAtZm9yY2UgICAgICAgICAgICAgICAgICAgICAgIFx1NTlDQlx1N0VDOFx1NTE5OVx1NTE2NVx1OEY5M1x1NTFGQVx1NjU4N1x1NEVGNgoKbWFpbi5vcHQubW9kdWxlX3BhdGg9XCAgLS1tb2R1bGUtcGF0aCA8XHU4REVGXHU1Rjg0PiAgICAgICAgIFx1NEVDRVx1NEUyRFx1NTJBMFx1OEY3RFx1NUU5NFx1NzUyOFx1N0EwQlx1NUU4Rlx1NkEyMVx1NTc1N1x1NzY4NFx1OERFRlx1NUY4NAoKbWFpbi5vcHQudXBncmFkZV9tb2R1bGVfcGF0aD1cICAtLXVwZ3JhZGVfbW9kdWxlLXBhdGggPFx1OERFRlx1NUY4ND4gXHU0RUNFXHU0RTJEXHU1MkEwXHU4RjdEXHU1RTk0XHU3NTI4XHU3QTBCXHU1RThGXHU2QTIxXHU1NzU3XHU3Njg0XHU4REVGXHU1Rjg0CgptYWluLm9wdC5jbGFzc3BhdGg9XCAgLWNsYXNzcGF0aCA8cGF0aD4gICAgICAgICAgICBcdTRFQ0VcdTRFMkRcdTUyQTBcdThGN0RcdTdDN0JcdTc2ODRcdThERUZcdTVGODQKCm1haW4ub3B0LmNsYXNzX3BhdGg9XCAgLS1jbGFzcy1wYXRoIDxcdThERUZcdTVGODQ+ICAgICAgICAgIFx1NEVDRVx1NEUyRFx1NTJBMFx1OEY3RFx1N0M3Qlx1NzY4NFx1OERFRlx1NUY4NAoKbWFpbi5vcHQuY3A9XCAgLWNwIDxwYXRoPiAgICAgICAgICAgICAgICAgICBcdTRFQ0VcdTRFMkRcdTUyQTBcdThGN0RcdTdDN0JcdTc2ODRcdThERUZcdTVGODQKCm1haW4ub3B0LmJvb3RjbGFzc3BhdGg9XCAgLWJvb3RjbGFzc3BhdGggPHBhdGg+ICAgICAgICBcdTRFQ0VcdTRFMkRcdTUyQTBcdThGN0RcdTVGMTVcdTVCRkNcdTdDN0JcdTc2ODRcdThERUZcdTVGODQKCm1haW4ub3B0LnN5c3RlbT1cICAtLXN5c3RlbSA8amRrPiAgICAgICAgICAgICAgIFx1NjMwN1x1NUI5QVx1NjdFNVx1NjI3RVx1N0NGQlx1N0VERlx1NkEyMVx1NTc1N1x1NzY4NFx1NEY0RFx1N0Y2RQoKbWFpbi51c2FnZS5mb290PVxuR05VIFx1NjgzN1x1NUYwRlx1NzY4NFx1OTAwOVx1OTg3OVx1NTNFRlx1NEY3Rlx1NzUyOCAnPScgKFx1ODAwQ1x1OTc1RVx1N0E3QVx1NzY3RCkgXHU2NzY1XHU1MjA2XHU5Njk0XHU5MDA5XHU5ODc5XHU1NDBEXHU3OUYwXG5cdTUzQ0FcdTUxNzZcdTUwM0NcdTMwMDJcblxuXHU2QkNGXHU0RTJBXHU3QzdCXHU1RkM1XHU5ODdCXHU3NTMxXHU1MTc2XHU1MTY4XHU5NjUwXHU1QjlBXHU1NDBEXHU3OUYwXHU2MzA3XHU1QjlBLCBcblx1NTNFRlx1NEVFNVx1OTAwOVx1NjJFOVx1NjAyN1x1NTczMFx1NEY3Rlx1NzUyOFx1NkEyMVx1NTc1N1x1NTQwRFx1NTQwRVx1OERERiAnLycgXHU0RjVDXHU0RTNBXHU1MjREXHU3RjAwXHUzMDAyXHU3OTNBXHU0RjhCOlxuICAgIGphdmEubGFuZy5PYmplY3RcbiAgICBqYXZhLmJhc2UvamF2YS5pby5GaWxlXG4KIwojIFZlcnNpb24gc3RyaW5nLgojCmphdmFoLnZlcnNpb249ezB9XHU3MjQ4XHU2NzJDICJ7MX0iCmphdmFoLmZ1bGxWZXJzaW9uPXswfVx1NUI4Q1x1NjU3NFx1NzI0OFx1NjcyQyAiezF9IgoKIwojIFRoZXNlIHNob3VsZCBoYXZlIGJldHRlciBkaWFnbm9zdGljcy4KIwpzdXBlci5jbGFzcy5ub3QuZm91bmQ9XHU2MjdFXHU0RTBEXHU1MjMwXHU2MjQwXHU5NzAwXHU3Njg0XHU4RDg1XHU3QzdCezB9XHUzMDAyCmNsYXNzLm5vdC5mb3VuZD1cdTYyN0VcdTRFMERcdTUyMzBcdTdDN0J7MH1cdTMwMDIKaW8uZXhjZXB0aW9uPVx1NjVFMFx1NkNENVx1NEVDRSBJL08gXHU5NTE5XHU4QkVGXHU0RTJEXHU2MDYyXHU1OTBELCBcdTZEODhcdTYwNkZcdTRFM0E6IHswfVx1MzAwMgoKIwojIFByb2JsZW1zIGluIHRoZSBndXRzIG9mIGphdmFoLgojCmVuY29kaW5nLmlzbzg4NTlfMS5ub3QuZm91bmQ9XHU2MjdFXHU0RTBEXHU1MjMwXHU3NTI4XHU0RThFXHU4RjkzXHU1MUZBXHU3Njg0IElTTzg4NTlfMSBcdThGNkNcdTYzNjJcdTU2NjhcdTMwMDJcdThGRDlcdTUzRUZcdTgwRkRcdTY2MkZcdTU2RTBcdTRFM0FcdTVCODlcdTg4QzVcdThGQzdcdTdBMEJcdTRFMkRcdTUxRkFcdTczQjBcdTRFODZcdTk1MTlcdThCRUZcdTMwMDIKdHJpZWQudG8uZGVmaW5lLm5vbi5zdGF0aWM9XHU1QzFEXHU4QkQ1XHU0RTNBXHU5NzVFXHU5NzU5XHU2MDAxXHU1QjU3XHU2QkI1XHU3NTFGXHU2MjEwICNkZWZpbmVcdTMwMDIKam5pLnVua25vd24udHlwZT1cdTkwNDdcdTUyMzBcdTY3MkFcdTc3RTVcdTdDN0JcdTU3OEIgKEpOSSlcdTMwMDIKdW5rbm93bi5hcnJheS50eXBlPVx1NzUxRlx1NjIxMFx1NjVFN1x1NjgzN1x1NUYwRlx1NzY4NFx1NjgwN1x1NTkzNFx1NjVGNlx1OTA0N1x1NTIzMFx1NjcyQVx1NzdFNVx1NzY4NFx1NjU3MFx1N0VDNFx1N0M3Qlx1NTc4Qlx1MzAwMgp1bmtub3duLnR5cGUuZm9yLmZpZWxkPVx1NzUxRlx1NjIxMFx1NjVFN1x1NjgzN1x1NUYwRlx1NzY4NFx1NjgwN1x1NTkzNFx1NjVGNlx1OTA0N1x1NTIzMFx1NjcyQVx1NzdFNVx1NzY4NFx1N0M3Qlx1NTc4Qlx1MzAwMgp1bmtub3duLnR5cGUuaW4ubWV0aG9kLnNpZ25hdHVyZT1cdTc1MUZcdTYyMTBcdTY1RTdcdTY4MzdcdTVGMEZcdTc2ODRcdTVCNThcdTY4MzlcdTY1RjZcdTkwNDdcdTUyMzBcdTY3MkFcdTc3RTVcdTc2ODRcdTdDN0JcdTU3OEJcdTMwMDIKCgplcnIucHJlZml4PVx1OTUxOVx1OEJFRjoKZXJyLmNhbnQudXNlLm9wdGlvbi5mb3IuZm09XHU0RTBEXHU4MEZEXHU1QzA2ezB9XHU5MDA5XHU5ODc5XHU0RTBFXHU3RUQ5XHU1QjlBXHU3Njg0XHU2NTg3XHU0RUY2XHU3QkExXHU3NDA2XHU1NjY4XHU0RTAwXHU4RDc3XHU0RjdGXHU3NTI4CmVyci5pbnRlcm5hbC5lcnJvcj1cdTUxODVcdTkwRThcdTk1MTlcdThCRUY6IHswfQplcnIuaW9lcnJvcj1JTyBcdTk1MTlcdThCRUY6IHswfQplcnIubWlzc2luZy5hcmc9ezB9XHU3RjNBXHU1QzExXHU1MDNDCmVyci5uby5jbGFzc2VzLnNwZWNpZmllZD1cdTY3MkFcdTYzMDdcdTVCOUFcdTdDN0IKZXJyLnVua25vd24ub3B0aW9uPVx1NjcyQVx1NzdFNVx1OTAwOVx1OTg3OTogezB9CgojCiMgbWlzY2VsbGFuZW91cyBzdHJpbmdzCiMKamF2YWgubWlzYy5EZXByZWNhdGlvbj1cblx1OEI2Nlx1NTQ0QTogXHU1REYyXHU4QkExXHU1MjEyXHU1NzI4XHU0RTBCXHU0RTAwXHU0RTJBIEpESyBcdTRFM0JcdTUzRDFcdTg4NENcdTcyNDhcdTRFMkRcdTUyMjBcdTk2NjQgamF2YWhcblx1NURFNVx1NTE3N1x1MzAwMlx1OEJFNVx1NURFNVx1NTE3N1x1NTcyOCBKREsgOCBcdTRFMkRcdTVERjJcdTc1MzFcdTZERkJcdTUyQTBcdTUyMzAgamF2YWMgXHU3Njg0XG4nJy1oJycgXHU5MDA5XHU5ODc5XHU1M0Q2XHU0RUUzXHUzMDAyXHU1RUZBXHU4QkFFXHU3NTI4XHU2MjM3XHU2NTM5XHU0RTNBXHU0RjdGXHU3NTI4IGphdmFjICcnLWgnJ1xuXHU5MDA5XHU5ODc5OyBcdTY3MDlcdTUxNzNcdThCRTZcdTdFQzZcdTRGRTFcdTYwNkYsIFx1OEJGN1x1NjdFNVx1NzcwQiBqYXZhYyBcdTVFMkVcdTUyQTlcdTk4NzVcdTMwMDJcbgpQSwMECgAACAAA0n1NSnT3G93gBAAA4AQAADkAAABjb20vc3VuL3Rvb2xzL2phdmFoL3Jlc291cmNlcy92ZXJzaW9uLnByb3BlcnRpZXMtdGVtcGxhdGUjCiMgQ29weXJpZ2h0IChjKSAyMDA1LCAyMDEwLCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgojIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KIwojIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiMgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKIyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKIyBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiMgYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiMKIyBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKIyBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKIyBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKIyB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAojIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiMKIyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiMgMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAojIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KIwojIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiMgb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQojIHF1ZXN0aW9ucy4KIwoKamRrPSQoSkRLX1ZFUlNJT04pCmZ1bGw9JChGVUxMX1ZFUlNJT04pCnJlbGVhc2U9JChSRUxFQVNFKQpQSwMECgAACAAABjupSpO2MQzNFwAAzRcAAC0AAABjb20vc3VuL3Rvb2xzL2phdmFoL3Jlc291cmNlcy9sMTBuLnByb3BlcnRpZXMjCiMgQ29weXJpZ2h0IChjKSAxOTk4LCAyMDE2LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgojIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KIwojIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiMgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKIyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKIyBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiMgYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiMKIyBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKIyBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKIyBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKIyB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAojIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiMKIyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiMgMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAojIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KIwojIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiMgb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQojIHF1ZXN0aW9ucy4KIwoKIwojIFVzZXIgZXJyb3JzLCBjb21tYW5kIGxpbmUgZXJyb3JzLgojCmNhbnQuY3JlYXRlLmRpcj1cCiAgICAgICAgVGhlIGRpcmVjdG9yeSB7MH0gY291bGQgbm90IGJlIGNyZWF0ZSBmb3Igb3V0cHV0LgphdC5hcmdzLmNhbnQucmVhZD1cCiAgICAgICAgQ2FuJyd0IHJlYWQgY29tbWFuZCBsaW5lIGFyZ3VtZW50cyBmcm9tIGZpbGUgezF9LgphdC5hcmdzLmZpbGUubm90LmZvdW5kPVwKICAgICAgICBDYW4nJ3QgZmluZCBmaWxlIHswfS4KYXQuYXJncy5pby5leGNlcHRpb249XAogICAgICAgIFRoZSBmb2xsb3dpbmcgSS9PIHByb2JsZW0gd2FzIGVuY291bnRlcmVkIHdoZW4gcHJvY2Vzc2luZyBhbiBAIFwKICAgICAgICBhcmd1bWVudCBvbiB0aGUgY29tbWFuZCBsaW5lOiB7MH0uCmJhZC5hcmc9XAogICAgICAgIEJhZCBhcmd1bWVudDogezB9Cm9sZC5qbmkubWl4ZWQ9XAogICAgICAgIENhbicndCBtaXggb3B0aW9ucyAtam5pIGFuZCAtb2xkLiAgVHJ5IC1oZWxwLgpvbGQubGxuaS5taXhlZD1cCiAgICAgICAgQ2FuJyd0IG1peCBvcHRpb25zIC1vbGQgYW5kIC1sbG5pLiAgVHJ5IC1oZWxwLgpvbGQubm90LnN1cHBvcnRlZD1cCiAgICAgICAgT3B0aW9uIC1vbGQgbm90IHN1cHBvcnRlZCBieSB0aGlzIHZlcnNpb24gb2YgamF2YWguCmludmFsaWQubWV0aG9kLnNpZ25hdHVyZT1cCiAgICAgICAgSW52YWxpZCBtZXRob2Qgc2lnbmF0dXJlOiB7MH0Kam5pLmxsbmkubWl4ZWQ9XAogICAgICAgIENhbicndCBtaXggb3B0aW9ucyAtam5pIGFuZCAtbGxuaS4gIFRyeSAtaGVscC4Kam5pLm5vLnN0dWJzPVwKICAgICAgICBKTkkgZG9lcyBub3QgcmVxdWlyZSBzdHVicywgcGxlYXNlIHJlZmVyIHRvIHRoZSBKTkkgZG9jdW1lbnRhdGlvbi4Kam5pLnNpZ2Vycm9yPVwKICAgICAgICBDYW5ub3QgZGV0ZXJtaW5lIHNpZ25hdHVyZSBmb3IgezB9CmRpci5maWxlLm1peGVkPVwKICAgICAgICBDYW4nJ3QgbWl4IG9wdGlvbnMgLWQgYW5kIC1vLiAgVHJ5IC1oZWxwLgpuby5jbGFzc2VzLnNwZWNpZmllZD1cCiAgICAgICAgTm8gY2xhc3NlcyB3ZXJlIHNwZWNpZmllZCBvbiB0aGUgY29tbWFuZCBsaW5lLiAgVHJ5IC1oZWxwLgpuby5vdXRwdXRmaWxlLnNwZWNpZmllZD1cCiAgICAgICAgTm8gb3V0cHV0ZmlsZSB3YXMgc3BlY2lmaWVkIG9uIHRoZSBjb21tYW5kIGxpbmUuICBUcnkgLWhlbHAuCm5vLm91dHB1dGRpci5zcGVjaWZpZWQ9XAogICAgICAgIE5vIG91dHB1dCBkaXJlY3Rvcnkgd2FzIHNwZWNpZmllZCBvbiB0aGUgY29tbWFuZCBsaW5lLiAgVHJ5IC1oZWxwLgpuby5jbGFzc3BhdGguc3BlY2lmaWVkPVwKICAgICAgICBObyBjbGFzc3BhdGggd2FzIHNwZWNpZmllZCBvbiB0aGUgY29tbWFuZCBsaW5lLiAgVHJ5IC1oZWxwLgpuby5ib290Y2xhc3NwYXRoLnNwZWNpZmllZD1cCiAgICAgICAgTm8gYm9vdGNsYXNzcGF0aCB3YXMgc3BlY2lmaWVkIG9uIHRoZSBjb21tYW5kIGxpbmUuICBUcnkgLWhlbHAuCnVua25vd24ub3B0aW9uPVwKICAgICAgICB7MH0gaXMgYW4gaWxsZWdhbCBhcmd1bWVudFxuCnRyYWNpbmcubm90LnN1cHBvcnRlZD1cCiAgICAgICAgV2FybmluZzogVHJhY2luZyBpcyBubyBsb25nZXIgc3VwcG9ydGVkLiAgSW5zdGVhZCwgdXNlXAogICAgICAgIC12ZXJib3NlOmpuaSBvcHRpb24gb2YgdGhlIHZpcnR1YWwgbWFjaGluZS4KCm1haW4udXNhZ2U9XApVc2FnZTogXG5cClwgIGphdmFoIFtvcHRpb25zXSA8Y2xhc3Nlcz5cblwKd2hlcmUgW29wdGlvbnNdIGluY2x1ZGU6CgptYWluLm9wdC5vPVwKXCAgLW8gPGZpbGU+ICAgICAgICAgICAgICAgICAgICBPdXRwdXQgZmlsZSAob25seSBvbmUgb2YgLWQgb3IgLW8gbWF5IGJlIHVzZWQpCgptYWluLm9wdC5kPVwKXCAgLWQgPGRpcj4gICAgICAgICAgICAgICAgICAgICBPdXRwdXQgZGlyZWN0b3J5CgptYWluLm9wdC52PVwKXCAgLXYgIC12ZXJib3NlICAgICAgICAgICAgICAgICBFbmFibGUgdmVyYm9zZSBvdXRwdXQKCm1haW4ub3B0Lmg9XApcICAtaCAgLS1oZWxwICAtPyAgICAgICAgICAgICAgIFByaW50IHRoaXMgbWVzc2FnZQoKbWFpbi5vcHQudmVyc2lvbj1cClwgIC12ZXJzaW9uICAgICAgICAgICAgICAgICAgICAgUHJpbnQgdmVyc2lvbiBpbmZvcm1hdGlvbgoKbWFpbi5vcHQuam5pPVwKXCAgLWpuaSAgICAgICAgICAgICAgICAgICAgICAgICBHZW5lcmF0ZSBKTkktc3R5bGUgaGVhZGVyIGZpbGUgKGRlZmF1bHQpCgptYWluLm9wdC5mb3JjZT1cClwgIC1mb3JjZSAgICAgICAgICAgICAgICAgICAgICAgQWx3YXlzIHdyaXRlIG91dHB1dCBmaWxlcwoKbWFpbi5vcHQubW9kdWxlX3BhdGg9XApcICAtLW1vZHVsZS1wYXRoIDxwYXRoPiAgICAgICAgIFBhdGggZnJvbSB3aGljaCB0byBsb2FkIGFwcGxpY2F0aW9uIG1vZHVsZXMKCm1haW4ub3B0LnVwZ3JhZGVfbW9kdWxlX3BhdGg9XApcICAtLXVwZ3JhZGVfbW9kdWxlLXBhdGggPHBhdGg+IFBhdGggZnJvbSB3aGljaCB0byBsb2FkIGFwcGxpY2F0aW9uIG1vZHVsZXMKCm1haW4ub3B0LmNsYXNzcGF0aD1cClwgIC1jbGFzc3BhdGggPHBhdGg+ICAgICAgICAgICAgUGF0aCBmcm9tIHdoaWNoIHRvIGxvYWQgY2xhc3NlcwoKbWFpbi5vcHQuY2xhc3NfcGF0aD1cClwgIC0tY2xhc3MtcGF0aCA8cGF0aD4gICAgICAgICAgUGF0aCBmcm9tIHdoaWNoIHRvIGxvYWQgY2xhc3NlcwoKbWFpbi5vcHQuY3A9XApcICAtY3AgPHBhdGg+ICAgICAgICAgICAgICAgICAgIFBhdGggZnJvbSB3aGljaCB0byBsb2FkIGNsYXNzZXMKCm1haW4ub3B0LmJvb3RjbGFzc3BhdGg9XApcICAtYm9vdGNsYXNzcGF0aCA8cGF0aD4gICAgICAgIFBhdGggZnJvbSB3aGljaCB0byBsb2FkIGJvb3RzdHJhcCBjbGFzc2VzCgptYWluLm9wdC5zeXN0ZW09XApcICAtLXN5c3RlbSA8amRrPiAgICAgICAgICAgICAgIFNwZWNpZnkgd2hlcmUgdG8gZmluZCBzeXN0ZW0gbW9kdWxlcwoKbWFpbi51c2FnZS5mb290PVxuXApHTlUtc3R5bGUgb3B0aW9ucyBtYXkgdXNlICc9JyBpbnN0ZWFkIHdoaXRlc3BhY2UgdG8gc2VwYXJhdGUgdGhlIG5hbWUgb2YgYW4gb3B0aW9uXG5cCmZyb20gaXRzIHZhbHVlLlxuXApcblwKRWFjaCBjbGFzcyBtdXN0IGJlIHNwZWNpZmllZCBieSBpdHMgZnVsbHkgcXVhbGlmaWVkIG5hbWVzLCBvcHRpb25hbGx5XG5cCnByZWZpeGVkIGJ5IGEgbW9kdWxlIG5hbWUgZm9sbG93ZWQgYnkgJy8nLiBFeGFtcGxlczpcblwKXCAgICBqYXZhLmxhbmcuT2JqZWN0XG5cClwgICAgamF2YS5iYXNlL2phdmEuaW8uRmlsZVxuXAoKIwojIFZlcnNpb24gc3RyaW5nLgojCmphdmFoLnZlcnNpb249ezB9IHZlcnNpb24gInsxfSIKamF2YWguZnVsbFZlcnNpb249ezB9IGZ1bGwgdmVyc2lvbiAiezF9IgoKIwojIFRoZXNlIHNob3VsZCBoYXZlIGJldHRlciBkaWFnbm9zdGljcy4KIwpzdXBlci5jbGFzcy5ub3QuZm91bmQ9XAogICAgICAgIEEgcmVxdWlyZWQgc3VwZXIgY2xhc3MgezB9IGNvdWxkIG5vdCBiZSBmb3VuZC4KY2xhc3Mubm90LmZvdW5kPVwKICAgICAgICBDbGFzcyB7MH0gY291bGQgbm90IGJlIGZvdW5kLgppby5leGNlcHRpb249XAogICAgICAgIENhbicndCByZWNvdmVyIGZyb20gYW4gSS9PIGVycm9yIHdpdGggdGhlIGZvbGxvd2luZyBtZXNzYWdlOiBcCiAgICAgICAgezB9LgoKIwojIFByb2JsZW1zIGluIHRoZSBndXRzIG9mIGphdmFoLgojCmVuY29kaW5nLmlzbzg4NTlfMS5ub3QuZm91bmQ9XAogICAgICAgIElTTzg4NTlfMSBjb252ZXJ0ZXIgd2FzIG5vdCBmb3VuZCBmb3Igb3V0cHV0LiAgVGhpcyBpcyBcCiAgICAgICAgcHJvYmFibHkgZHVlIHRvIGFuIGVycm9yIGluIHRoZSBpbnN0YWxsYXRpb24gaW5zdGFsbGF0aW9uLgp0cmllZC50by5kZWZpbmUubm9uLnN0YXRpYz1cCiAgICAgICAgVHJpZWQgdG8gZ2VuZXJhdGUgI2RlZmluZSBmb3Igbm9uLXN0YXRpYyBmaWVsZC4Kam5pLnVua25vd24udHlwZT1cCiAgICAgICAgQW4gdW5rbm93biB0eXBlIGVuY291bnRlcmVkIChKTkkpLgp1bmtub3duLmFycmF5LnR5cGU9XAogICAgICAgIEFuIHVua25vd24gYXJyYXkgdHlwZSBlbmNvdW50ZXJlZCB3aGVuIGdlbmVyYXRpbmcgb2xkIHN0eWxlIGhlYWRlcnMuCnVua25vd24udHlwZS5mb3IuZmllbGQ9XAogICAgICAgIEFuIHVua25vd24gdHlwZSBlbmNvdW50ZXJlZCB3aGVuIGdlbmVyYXRpbmcgb2xkIHN0eWxlIGhlYWRlcnMuCnVua25vd24udHlwZS5pbi5tZXRob2Quc2lnbmF0dXJlPVwKICAgICAgICBBbiB1bmtub3duIHR5cGUgZWNjb3VudGVyZWQgd2hlbiBnZW5lcmF0aW5nIG9sZCBzdHlsZSBzdHVicy4KCgplcnIucHJlZml4PUVycm9yOgplcnIuY2FudC51c2Uub3B0aW9uLmZvci5mbT1DYW4ndCB1c2UgezB9IG9wdGlvbiB3aXRoIGdpdmVuIGZpbGUgbWFuYWdlcgplcnIuaW50ZXJuYWwuZXJyb3I9SW50ZXJuYWwgZXJyb3I6IHswfQplcnIuaW9lcnJvcj1JTyBlcnJvcjogezB9CmVyci5taXNzaW5nLmFyZz12YWx1ZSBtaXNzaW5nIGZvciB7MH0KZXJyLm5vLmNsYXNzZXMuc3BlY2lmaWVkPW5vIGNsYXNzZXMgc3BlY2lmaWVkCmVyci51bmtub3duLm9wdGlvbj11bmtub3duIG9wdGlvbjogezB9CgojCiMgbWlzY2VsbGFuZW91cyBzdHJpbmdzCiMKamF2YWgubWlzYy5EZXByZWNhdGlvbj1cCiAgICBcbldhcm5pbmc6XHUwMDIwVGhlIGphdmFoIHRvb2wgaXMgcGxhbm5lZCB0byBiZSByZW1vdmVkIGluIHRoZSBuZXh0IG1ham9yXG5cCiAgICBKREsgcmVsZWFzZS4gVGhlIHRvb2wgaGFzIGJlZW4gc3VwZXJzZWRlZCBieSB0aGUgJyctaCcnIG9wdGlvbiBhZGRlZFxuXAogICAgdG8gamF2YWMgaW4gSkRLIDguIFVzZXJzIGFyZSByZWNvbW1lbmRlZCB0byBtaWdyYXRlIHRvIHVzaW5nIHRoZVxuXAogICAgamF2YWMgJyctaCcnIG9wdGlvbjsgc2VlIHRoZSBqYXZhYyBtYW4gcGFnZSBmb3IgbW9yZSBpbmZvcm1hdGlvbi5cbgpQSwMECgAACAAABjupSudcj2wCKwAAAisAADAAAABjb20vc3VuL3Rvb2xzL2phdmFoL3Jlc291cmNlcy9sMTBuX2phLnByb3BlcnRpZXMjCiMgQ29weXJpZ2h0IChjKSAxOTk4LCAyMDE2LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgojIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KIwojIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiMgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKIyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKIyBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiMgYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiMKIyBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKIyBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKIyBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKIyB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAojIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiMKIyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiMgMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAojIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KIwojIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiMgb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQojIHF1ZXN0aW9ucy4KIwoKIwojIFVzZXIgZXJyb3JzLCBjb21tYW5kIGxpbmUgZXJyb3JzLgojCmNhbnQuY3JlYXRlLmRpcj1cdTUxRkFcdTUyOUJcdTc1MjhcdTMwNkVcdTMwQzdcdTMwQTNcdTMwRUNcdTMwQUZcdTMwQzhcdTMwRUF7MH1cdTMwOTJcdTRGNUNcdTYyMTBcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKYXQuYXJncy5jYW50LnJlYWQ9XHUzMEQ1XHUzMEExXHUzMEE0XHUzMEVCezF9XHUzMDRCXHUzMDg5XHUzMEIzXHUzMERFXHUzMEYzXHUzMEM5XHUzMEU5XHUzMEE0XHUzMEYzXHU1RjE1XHU2NTcwXHUzMDkyXHU4QUFEXHUzMDdGXHU4RkJDXHUzMDgxXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCmF0LmFyZ3MuZmlsZS5ub3QuZm91bmQ9XHUzMEQ1XHUzMEExXHUzMEE0XHUzMEVCezB9XHUzMDRDXHU4OThCXHUzMDY0XHUzMDRCXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCmF0LmFyZ3MuaW8uZXhjZXB0aW9uPVx1MzBCM1x1MzBERVx1MzBGM1x1MzBDOVx1MzBFOVx1MzBBNFx1MzBGM1x1MzA2RUBcdTVGMTVcdTY1NzBcdTMwNkVcdTUxRTZcdTc0MDZcdTRFMkRcdTMwNkJcdTMwMDFcdTZCMjFcdTMwNkVcdTUxNjVcdTUxRkFcdTUyOUJcdTMwNkVcdTU1NEZcdTk4NENcdTMwNENcdTc2N0FcdTc1MUZcdTMwNTdcdTMwN0VcdTMwNTdcdTMwNUY6IHswfVx1MzAwMgpiYWQuYXJnPVx1NzEyMVx1NTJCOVx1MzA2QVx1NUYxNVx1NjU3MDogezB9Cm9sZC5qbmkubWl4ZWQ9XHUzMEFBXHUzMEQ3XHUzMEI3XHUzMEU3XHUzMEYzLWpuaVx1MzA2OC1vbGRcdTMwOTJcdTU0MENcdTY2NDJcdTMwNkJcdTRGN0ZcdTc1MjhcdTMwNTlcdTMwOEJcdTMwNTNcdTMwNjhcdTMwNkZcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDItaGVscFx1MzA2N1x1NzhCQVx1OEE4RFx1MzA1N1x1MzA2Nlx1MzA0Rlx1MzA2MFx1MzA1NVx1MzA0NFx1MzAwMgpvbGQubGxuaS5taXhlZD1cdTMwQUFcdTMwRDdcdTMwQjdcdTMwRTdcdTMwRjMtb2xkXHUzMDY4LWxsbmlcdTMwOTJcdTU0MENcdTY2NDJcdTMwNkJcdTRGN0ZcdTc1MjhcdTMwNTlcdTMwOEJcdTMwNTNcdTMwNjhcdTMwNkZcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDItaGVscFx1MzA2N1x1NzhCQVx1OEE4RFx1MzA1N1x1MzA2Nlx1MzA0Rlx1MzA2MFx1MzA1NVx1MzA0NFx1MzAwMgpvbGQubm90LnN1cHBvcnRlZD1cdTMwNTNcdTMwNkVcdTMwRDBcdTMwRkNcdTMwQjhcdTMwRTdcdTMwRjNcdTMwNkVqYXZhaFx1MzA2N1x1MzA2Rlx1MzBBQVx1MzBEN1x1MzBCN1x1MzBFN1x1MzBGMy1vbGRcdTMwNkZcdTMwQjVcdTMwRERcdTMwRkNcdTMwQzhcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKaW52YWxpZC5tZXRob2Quc2lnbmF0dXJlPVx1NzEyMVx1NTJCOVx1MzA2QVx1MzBFMVx1MzBCRFx1MzBDM1x1MzBDOVx1MzBGQlx1MzBCN1x1MzBCMFx1MzBDQlx1MzBDMVx1MzBFMzogezB9CmpuaS5sbG5pLm1peGVkPVx1MzBBQVx1MzBEN1x1MzBCN1x1MzBFN1x1MzBGMy1qbmlcdTMwNjgtbGxuaVx1MzA5Mlx1NTQwQ1x1NjY0Mlx1MzA2Qlx1NEY3Rlx1NzUyOFx1MzA1OVx1MzA4Qlx1MzA1M1x1MzA2OFx1MzA2Rlx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMi1oZWxwXHUzMDY3XHU3OEJBXHU4QThEXHUzMDU3XHUzMDY2XHUzMDRGXHUzMDYwXHUzMDU1XHUzMDQ0XHUzMDAyCmpuaS5uby5zdHVicz1KTklcdTMwNkZcdTMwQjlcdTMwQkZcdTMwRDZcdTMwOTJcdTVGQzVcdTg5ODFcdTMwNjhcdTMwNTdcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDJKTklcdTMwNkVcdTMwQzlcdTMwQURcdTMwRTVcdTMwRTFcdTMwRjNcdTMwQzhcdTMwOTJcdTUzQzJcdTcxNjdcdTMwNTdcdTMwNjZcdTMwNEZcdTMwNjBcdTMwNTVcdTMwNDRcdTMwMDIKam5pLnNpZ2Vycm9yPXswfVx1MzA2RVx1N0Y3Mlx1NTQwRFx1MzA5Mlx1NTIyNFx1NUI5QVx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5MwpkaXIuZmlsZS5taXhlZD1cdTMwQUFcdTMwRDdcdTMwQjdcdTMwRTdcdTMwRjMtZFx1MzA2OC1vXHUzMDkyXHU1NDBDXHU2NjQyXHUzMDZCXHU0RjdGXHU3NTI4XHUzMDU5XHUzMDhCXHUzMDUzXHUzMDY4XHUzMDZGXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyLWhlbHBcdTMwNjdcdTc4QkFcdThBOERcdTMwNTdcdTMwNjZcdTMwNEZcdTMwNjBcdTMwNTVcdTMwNDRcdTMwMDIKbm8uY2xhc3Nlcy5zcGVjaWZpZWQ9XHUzMEIzXHUzMERFXHUzMEYzXHUzMEM5XHUzMEU5XHUzMEE0XHUzMEYzXHUzMDY3XHUzMEFGXHUzMEU5XHUzMEI5XHUzMDRDXHU2MzA3XHU1QjlBXHUzMDU1XHUzMDhDXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDY3XHUzMDU3XHUzMDVGXHUzMDAyLWhlbHBcdTMwNjdcdTc4QkFcdThBOERcdTMwNTdcdTMwNjZcdTMwNEZcdTMwNjBcdTMwNTVcdTMwNDRcdTMwMDIKbm8ub3V0cHV0ZmlsZS5zcGVjaWZpZWQ9XHUzMEIzXHUzMERFXHUzMEYzXHUzMEM5XHUzMEU5XHUzMEE0XHUzMEYzXHUzMDY3XHU1MUZBXHU1MjlCXHUzMEQ1XHUzMEExXHUzMEE0XHUzMEVCXHUzMDRDXHU2MzA3XHU1QjlBXHUzMDU1XHUzMDhDXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDY3XHUzMDU3XHUzMDVGXHUzMDAyLWhlbHBcdTMwNjdcdTc4QkFcdThBOERcdTMwNTdcdTMwNjZcdTMwNEZcdTMwNjBcdTMwNTVcdTMwNDRcdTMwMDIKbm8ub3V0cHV0ZGlyLnNwZWNpZmllZD1cdTMwQjNcdTMwREVcdTMwRjNcdTMwQzlcdTMwRTlcdTMwQTRcdTMwRjNcdTMwNjdcdTUxRkFcdTUyOUJcdTMwQzdcdTMwQTNcdTMwRUNcdTMwQUZcdTMwQzhcdTMwRUFcdTMwNENcdTYzMDdcdTVCOUFcdTMwNTVcdTMwOENcdTMwN0VcdTMwNUJcdTMwOTNcdTMwNjdcdTMwNTdcdTMwNUZcdTMwMDItaGVscFx1MzA2N1x1NzhCQVx1OEE4RFx1MzA1N1x1MzA2Nlx1MzA0Rlx1MzA2MFx1MzA1NVx1MzA0NFx1MzAwMgpuby5jbGFzc3BhdGguc3BlY2lmaWVkPVx1MzBCM1x1MzBERVx1MzBGM1x1MzBDOVx1MzBFOVx1MzBBNFx1MzBGM1x1MzA2N1x1MzBBRlx1MzBFOVx1MzBCOVx1MzBEMVx1MzBCOVx1MzA0Q1x1NjMwN1x1NUI5QVx1MzA1NVx1MzA4Q1x1MzA3RVx1MzA1Qlx1MzA5M1x1MzA2N1x1MzA1N1x1MzA1Rlx1MzAwMi1oZWxwXHUzMDY3XHU3OEJBXHU4QThEXHUzMDU3XHUzMDY2XHUzMDRGXHUzMDYwXHUzMDU1XHUzMDQ0XHUzMDAyCm5vLmJvb3RjbGFzc3BhdGguc3BlY2lmaWVkPVx1MzBCM1x1MzBERVx1MzBGM1x1MzBDOVx1MzBFOVx1MzBBNFx1MzBGM1x1MzA2N1x1MzBENlx1MzBGQ1x1MzBDOFx1MzBGQlx1MzBBRlx1MzBFOVx1MzBCOVx1MzBEMVx1MzBCOVx1MzA0Q1x1NjMwN1x1NUI5QVx1MzA1NVx1MzA4Q1x1MzA3RVx1MzA1Qlx1MzA5M1x1MzA2N1x1MzA1N1x1MzA1Rlx1MzAwMi1oZWxwXHUzMDY3XHU3OEJBXHU4QThEXHUzMDU3XHUzMDY2XHUzMDRGXHUzMDYwXHUzMDU1XHUzMDQ0XHUzMDAyCnVua25vd24ub3B0aW9uPXswfVx1MzA2Rlx1NEUwRFx1NkI2M1x1MzA2QVx1NUYxNVx1NjU3MFx1MzA2N1x1MzA1OVxuCnRyYWNpbmcubm90LnN1cHBvcnRlZD1cdThCNjZcdTU0NEE6IFx1MzBDOFx1MzBFQ1x1MzBGQ1x1MzBCOVx1MzA2Rlx1NzNGRVx1NTcyOFx1MzA2Rlx1MzBCNVx1MzBERFx1MzBGQ1x1MzBDOFx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMlx1MzA0Qlx1MzA4Rlx1MzA4QVx1MzA2Qlx1MzAwMVZpcnR1YWwgTWFjaGluZVx1MzA2RS12ZXJib3NlOmpuaVx1MzBBQVx1MzBEN1x1MzBCN1x1MzBFN1x1MzBGM1x1MzA5Mlx1NEY3Rlx1NzUyOFx1MzA1N1x1MzA2Nlx1MzA0Rlx1MzA2MFx1MzA1NVx1MzA0NFx1MzAwMgoKbWFpbi51c2FnZT1cdTRGN0ZcdTc1MjhcdTY1QjlcdTZDRDU6IFxuICBqYXZhaCBbb3B0aW9uc10gPGNsYXNzZXM+XG5bb3B0aW9uc11cdTMwNkJcdTMwNkZcdTZCMjFcdTMwNkVcdTMwODJcdTMwNkVcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlcdTMwMDIKCm1haW4ub3B0Lm89XCAgLW8gPGZpbGU+ICAgICAgICAgICAgICAgICAgICBcdTUxRkFcdTUyOUJcdTMwRDVcdTMwQTFcdTMwQTRcdTMwRUIoLWRcdTMwNEItb1x1MzA2RVx1MzA2OVx1MzA2MVx1MzA4OVx1MzA0Qlx1NEUwMFx1NjVCOVx1MzA5Mlx1NEY3Rlx1NzUyOFx1MzA1OVx1MzA4QikKCm1haW4ub3B0LmQ9XCAgLWQgPGRpcj4gICAgICAgICAgICAgICAgICAgICBcdTUxRkFcdTUyOUJcdTMwQzdcdTMwQTNcdTMwRUNcdTMwQUZcdTMwQzhcdTMwRUEKCm1haW4ub3B0LnY9XCAgLXYgIC12ZXJib3NlICAgICAgICAgICAgICAgICBcdThBNzNcdTdEMzBcdTMwNkFcdTUxRkFcdTUyOUJcdTMwOTJcdTg4NENcdTMwNDYKCm1haW4ub3B0Lmg9XCAgLWggIC0taGVscCAgLT8gICAgICAgICAgICAgICBcdTMwNTNcdTMwNkVcdTMwRTFcdTMwQzNcdTMwQkJcdTMwRkNcdTMwQjhcdTMwOTJcdTg4NjhcdTc5M0FcdTMwNTlcdTMwOEIKCm1haW4ub3B0LnZlcnNpb249XCAgLXZlcnNpb24gICAgICAgICAgICAgICAgICAgICBcdTMwRDBcdTMwRkNcdTMwQjhcdTMwRTdcdTMwRjNcdTYwQzVcdTU4MzFcdTMwOTJcdTg4NjhcdTc5M0FcdTMwNTlcdTMwOEIKCm1haW4ub3B0LmpuaT1cICAtam5pICAgICAgICAgICAgICAgICAgICAgICAgIEpOSVx1NUY2Mlx1NUYwRlx1MzA2RVx1MzBEOFx1MzBDM1x1MzBDMFx1MzBGQ1x1MzBGQlx1MzBENVx1MzBBMVx1MzBBNFx1MzBFQlx1MzA5Mlx1NzUxRlx1NjIxMFx1MzA1OVx1MzA4QihcdTMwQzdcdTMwRDVcdTMwQTlcdTMwRUJcdTMwQzgpCgptYWluLm9wdC5mb3JjZT1cICAtZm9yY2UgICAgICAgICAgICAgICAgICAgICAgIFx1NUUzOFx1MzA2Qlx1NTFGQVx1NTI5Qlx1MzBENVx1MzBBMVx1MzBBNFx1MzBFQlx1MzA5Mlx1NjZGOFx1MzA0RFx1OEZCQ1x1MzA4MAoKbWFpbi5vcHQubW9kdWxlX3BhdGg9XCAgLS1tb2R1bGUtcGF0aCA8cGF0aD4gICAgICAgICBcdTMwQTJcdTMwRDdcdTMwRUFcdTMwQjFcdTMwRkNcdTMwQjdcdTMwRTdcdTMwRjNcdTMwRkJcdTMwRTJcdTMwQjhcdTMwRTVcdTMwRkNcdTMwRUJcdTMwOTJcdTMwRURcdTMwRkNcdTMwQzlcdTMwNTlcdTMwOEJcdTMwRDFcdTMwQjkKCm1haW4ub3B0LnVwZ3JhZGVfbW9kdWxlX3BhdGg9XCAgLS11cGdyYWRlX21vZHVsZS1wYXRoIDxwYXRoPiBcdTMwQTJcdTMwRDdcdTMwRUFcdTMwQjFcdTMwRkNcdTMwQjdcdTMwRTdcdTMwRjNcdTMwRkJcdTMwRTJcdTMwQjhcdTMwRTVcdTMwRkNcdTMwRUJcdTMwOTJcdTMwRURcdTMwRkNcdTMwQzlcdTMwNTlcdTMwOEJcdTMwRDFcdTMwQjkKCm1haW4ub3B0LmNsYXNzcGF0aD1cICAtY2xhc3NwYXRoIDxwYXRoPiAgICAgICAgICAgIFx1MzBBRlx1MzBFOVx1MzBCOVx1MzA5Mlx1MzBFRFx1MzBGQ1x1MzBDOVx1MzA1OVx1MzA4Qlx1MzBEMVx1MzBCOQoKbWFpbi5vcHQuY2xhc3NfcGF0aD1cICAtLWNsYXNzLXBhdGggPHBhdGg+ICAgICAgICAgIFx1MzBBRlx1MzBFOVx1MzBCOVx1MzA5Mlx1MzBFRFx1MzBGQ1x1MzBDOVx1MzA1OVx1MzA4Qlx1MzBEMVx1MzBCOQoKbWFpbi5vcHQuY3A9XCAgLWNwIDxwYXRoPiAgICAgICAgICAgICAgICAgICBcdTMwQUZcdTMwRTlcdTMwQjlcdTMwOTJcdTMwRURcdTMwRkNcdTMwQzlcdTMwNTlcdTMwOEJcdTMwRDFcdTMwQjkKCm1haW4ub3B0LmJvb3RjbGFzc3BhdGg9XCAgLWJvb3RjbGFzc3BhdGggPHBhdGg+ICAgICAgICBcdTMwRDZcdTMwRkNcdTMwQzhcdTMwQjlcdTMwQzhcdTMwRTlcdTMwQzNcdTMwRDdcdTMwRkJcdTMwQUZcdTMwRTlcdTMwQjlcdTMwOTJcdTMwRURcdTMwRkNcdTMwQzlcdTMwNTlcdTMwOEJcdTMwRDFcdTMwQjkKCm1haW4ub3B0LnN5c3RlbT1cICAtLXN5c3RlbSA8amRrPiAgICAgICAgICAgICAgIFx1MzBCN1x1MzBCOVx1MzBDNlx1MzBFMFx1MzBGQlx1MzBFMlx1MzBCOFx1MzBFNVx1MzBGQ1x1MzBFQlx1MzA5Mlx1NjkxQ1x1N0QyMlx1MzA1OVx1MzA4Qlx1NTgzNFx1NjI0MFx1MzA5Mlx1NjMwN1x1NUI5QVx1MzA1OVx1MzA4QgoKbWFpbi51c2FnZS5mb290PVxuR05VXHUzMEI5XHUzMEJGXHUzMEE0XHUzMEVCXHUzMEZCXHUzMEFBXHUzMEQ3XHUzMEI3XHUzMEU3XHUzMEYzXHUzMDY3XHUzMDZGXHUzMDAxXHUzMEFBXHUzMEQ3XHUzMEI3XHUzMEU3XHUzMEYzXHUzMDZFXHU1NDBEXHU1MjREXHUzMDY4XHUzMDVEXHUzMDZFXHU1MDI0XHUzMDkyXHU1MzNBXHU1MjA3XHUzMDhCXHUzMDVGXHUzMDgxXHUzMDZCXHU3QTdBXHU3NjdEXHUzMDY3XHUzMDZGXHUzMDZBXHUzMDRGJz0nXHUzMDkyXG5cdTRGN0ZcdTc1MjhcdTMwNjdcdTMwNERcdTMwN0VcdTMwNTlcdTMwMDJcblxuXHU1NDA0XHUzMEFGXHUzMEU5XHUzMEI5XHUzMDZGXHUzMDAxXHUzMDVEXHUzMDZFXHU1QjhDXHU1MTY4XHU0RkVFXHU5OEZFXHU1NDBEXHUzMDY3XHU2MzA3XHU1QjlBXHUzMDU5XHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDAxXHUzMEFBXHUzMEQ3XHUzMEI3XHUzMEU3XHUzMEYzXHUzMDY3XHUzMEUyXHUzMEI4XHUzMEU1XHUzMEZDXHUzMEVCXHU1NDBEXHUzMDZFXG5cdTYzQTVcdTk4MkRcdThGOUVcdTMwNkJcdTdEOUFcdTMwNTFcdTMwNjYnLydcdTMwOTJcdTYzMDdcdTVCOUFcdTMwNTdcdTMwN0VcdTMwNTlcdTMwMDJcdTRGOEI6XG4gICAgamF2YS5sYW5nLk9iamVjdFxuICAgIGphdmEuYmFzZS9qYXZhLmlvLkZpbGVcbgojCiMgVmVyc2lvbiBzdHJpbmcuCiMKamF2YWgudmVyc2lvbj17MH1cdTMwRDBcdTMwRkNcdTMwQjhcdTMwRTdcdTMwRjMiezF9IgpqYXZhaC5mdWxsVmVyc2lvbj17MH1cdTMwRDVcdTMwRUJcdTMwRkJcdTMwRDBcdTMwRkNcdTMwQjhcdTMwRTdcdTMwRjMiezF9IgoKIwojIFRoZXNlIHNob3VsZCBoYXZlIGJldHRlciBkaWFnbm9zdGljcy4KIwpzdXBlci5jbGFzcy5ub3QuZm91bmQ9XHU4OTgxXHU2QzQyXHUzMDU1XHUzMDhDXHUzMDVGXHUzMEI5XHUzMEZDXHUzMEQxXHUzMEZDXHUzMEZCXHUzMEFGXHUzMEU5XHUzMEI5ezB9XHUzMDRDXHU4OThCXHUzMDY0XHUzMDRCXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCmNsYXNzLm5vdC5mb3VuZD1cdTMwQUZcdTMwRTlcdTMwQjl7MH1cdTMwNENcdTg5OEJcdTMwNjRcdTMwNEJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKaW8uZXhjZXB0aW9uPVx1MzBFMVx1MzBDM1x1MzBCQlx1MzBGQ1x1MzBCOHswfVx1MzA2RVx1NTE2NVx1NTFGQVx1NTI5Qlx1MzBBOFx1MzBFOVx1MzBGQ1x1MzA0Qlx1MzA4OVx1NTZERVx1NUZBOVx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgoKIwojIFByb2JsZW1zIGluIHRoZSBndXRzIG9mIGphdmFoLgojCmVuY29kaW5nLmlzbzg4NTlfMS5ub3QuZm91bmQ9XHU1MUZBXHU1MjlCXHU3NTI4XHUzMDZFSVNPODg1OV8xXHUzMEIzXHUzMEYzXHUzMEQwXHUzMEZDXHUzMEJGXHUzMDRDXHU4OThCXHUzMDY0XHUzMDRCXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyXHUzMEE0XHUzMEYzXHUzMEI5XHUzMEM4XHUzMEZDXHUzMEVCXHUzMDZCXHUzMEE4XHUzMEU5XHUzMEZDXHUzMDRDXHUzMDQyXHUzMDhCXHU1M0VGXHU4MEZEXHU2MDI3XHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyCnRyaWVkLnRvLmRlZmluZS5ub24uc3RhdGljPXN0YXRpY1x1MzA2N1x1MzA2QVx1MzA0NFx1MzBENVx1MzBBM1x1MzBGQ1x1MzBFQlx1MzBDOVx1MzA2QiNkZWZpbmVcdTMwOTJcdTc1MUZcdTYyMTBcdTMwNTdcdTMwODhcdTMwNDZcdTMwNjhcdTMwNTdcdTMwN0VcdTMwNTdcdTMwNUZcdTMwMDIKam5pLnVua25vd24udHlwZT1cdTRFMERcdTY2MEVcdTMwNkFcdTU3OEJcdTMwNENcdTY5MUNcdTUxRkFcdTMwNTVcdTMwOENcdTMwN0VcdTMwNTdcdTMwNUYoSk5JKVx1MzAwMgp1bmtub3duLmFycmF5LnR5cGU9XHU1M0U0XHUzMDQ0XHU1RjYyXHU1RjBGXHUzMDZFXHUzMEQ4XHUzMEMzXHUzMEMwXHUzMEZDXHUzMDkyXHU3NTFGXHU2MjEwXHUzMDU3XHUzMDY2XHUzMDQ0XHUzMDhCXHUzMDY4XHUzMDREXHUzMDZCXHU0RTBEXHU2NjBFXHUzMDZBXHU5MTREXHU1MjE3XHUzMDZFXHU1NzhCXHUzMDRDXHU2OTFDXHU1MUZBXHUzMDU1XHUzMDhDXHUzMDdFXHUzMDU3XHUzMDVGXHUzMDAyCnVua25vd24udHlwZS5mb3IuZmllbGQ9XHU1M0U0XHUzMDQ0XHU1RjYyXHU1RjBGXHUzMDZFXHUzMEQ4XHUzMEMzXHUzMEMwXHUzMEZDXHUzMDkyXHU3NTFGXHU2MjEwXHUzMDU3XHUzMDY2XHUzMDQ0XHUzMDhCXHUzMDY4XHUzMDREXHUzMDZCXHU0RTBEXHU2NjBFXHUzMDZBXHU1NzhCXHUzMDRDXHU2OTFDXHU1MUZBXHUzMDU1XHUzMDhDXHUzMDdFXHUzMDU3XHUzMDVGXHUzMDAyCnVua25vd24udHlwZS5pbi5tZXRob2Quc2lnbmF0dXJlPVx1NTNFNFx1MzA0NFx1NUY2Mlx1NUYwRlx1MzA2RVx1MzBCOVx1MzBCRlx1MzBENlx1MzA5Mlx1NzUxRlx1NjIxMFx1MzA1N1x1MzA2Nlx1MzA0NFx1MzA4Qlx1MzA2OFx1MzA0RFx1MzA2Qlx1NEUwRFx1NjYwRVx1MzA2QVx1NTc4Qlx1MzA0Q1x1NjkxQ1x1NTFGQVx1MzA1NVx1MzA4Q1x1MzA3RVx1MzA1N1x1MzA1Rlx1MzAwMgoKCmVyci5wcmVmaXg9XHUzMEE4XHUzMEU5XHUzMEZDOgplcnIuY2FudC51c2Uub3B0aW9uLmZvci5mbT1cdTYzMDdcdTVCOUFcdTMwNTVcdTMwOENcdTMwNUZcdTMwRDVcdTMwQTFcdTMwQTRcdTMwRUJcdTMwRkJcdTMwREVcdTMwQ0RcdTMwRkNcdTMwQjhcdTMwRTNcdTMwNjd7MH1cdTMwQUFcdTMwRDdcdTMwQjdcdTMwRTdcdTMwRjNcdTMwOTJcdTRGN0ZcdTc1MjhcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTMKZXJyLmludGVybmFsLmVycm9yPVx1NTE4NVx1OTBFOFx1MzBBOFx1MzBFOVx1MzBGQzogezB9CmVyci5pb2Vycm9yPVx1NTE2NVx1NTFGQVx1NTI5Qlx1MzBBOFx1MzBFOVx1MzBGQzogezB9CmVyci5taXNzaW5nLmFyZz17MH1cdTMwNkVcdTUwMjRcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTMKZXJyLm5vLmNsYXNzZXMuc3BlY2lmaWVkPVx1MzBBRlx1MzBFOVx1MzBCOVx1MzA0Q1x1NjMwN1x1NUI5QVx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1Qlx1MzA5MwplcnIudW5rbm93bi5vcHRpb249XHU0RTBEXHU2NjBFXHUzMDZBXHUzMEFBXHUzMEQ3XHUzMEI3XHUzMEU3XHUzMEYzOiB7MH0KCiMKIyBtaXNjZWxsYW5lb3VzIHN0cmluZ3MKIwpqYXZhaC5taXNjLkRlcHJlY2F0aW9uPVxuXHU4QjY2XHU1NDRBOiBqYXZhaFx1MzBDNFx1MzBGQ1x1MzBFQlx1MzA2Rlx1NkIyMVx1NTZERVx1MzA2RUpES1x1MzBFMVx1MzBCOFx1MzBFM1x1MzBGQ1x1MzBGQlx1MzBFQVx1MzBFQVx1MzBGQ1x1MzBCOVx1MzA2N1x1NTI0QVx1OTY2NFx1MzA1NVx1MzA4Q1x1MzA4Qlx1NEU4OFx1NUI5QVx1MzA2N1x1MzA1OVx1MzAwMlxuXHUzMDUzXHUzMDZFXHUzMEM0XHUzMEZDXHUzMEVCXHUzMDZGSkRLIDhcdTMwNjdqYXZhY1x1MzA2Qlx1OEZGRFx1NTJBMFx1MzA1NVx1MzA4Q1x1MzA1RicnLWgnJ1x1MzBBQVx1MzBEN1x1MzBCN1x1MzBFN1x1MzBGM1x1MzA2Qlx1MzA4OFx1MzA2M1x1MzA2Nlx1N0Y2RVx1MzA0RFx1NjNEQlx1MzA0OFx1MzA4OVx1MzA4Q1x1MzA3RVx1MzA1N1x1MzA1Rlx1MzAwMlxuXHUzMEU2XHUzMEZDXHUzMEI2XHUzMEZDXHUzMDZGamF2YWMgJyctaCcnXHUzMEFBXHUzMEQ3XHUzMEI3XHUzMEU3XHUzMEYzXHUzMDZFXHU0RjdGXHU3NTI4XHUzMDZCXHU3OUZCXHU4ODRDXHUzMDU5XHUzMDhCXHUzMDUzXHUzMDY4XHUzMDkyXHUzMDRBXHU4NUE2XHUzMDgxXHUzMDU3XHUzMDdFXHUzMDU5XHUzMDAyXG5cdThBNzNcdTdEMzBcdTMwNkZcdTMwMDFqYXZhYyBtYW5cdTMwREFcdTMwRkNcdTMwQjhcdTMwOTJcdTUzQzJcdTcxNjdcdTMwNTdcdTMwNjZcdTMwNEZcdTMwNjBcdTMwNTVcdTMwNDRcdTMwMDJcbgpQSwMECgAACAAA0n1NShd7Mm07GAAAOxgAACkAAABjb20vc3VuL3Rvb2xzL2phdmFoL05hdGl2ZUhlYWRlclRvb2wuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAxNCwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLmphdmFoOyAvL2phdmF4LnRvb2xzOwoKaW1wb3J0IGphdmEuaW8uV3JpdGVyOwppbXBvcnQgamF2YS5uaW8uY2hhcnNldC5DaGFyc2V0OwppbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkNhbGxhYmxlOwppbXBvcnQgamF2YXgudG9vbHMuRGlhZ25vc3RpYzsKaW1wb3J0IGphdmF4LnRvb2xzLkRpYWdub3N0aWNMaXN0ZW5lcjsKaW1wb3J0IGphdmF4LnRvb2xzLkphdmFGaWxlTWFuYWdlcjsKaW1wb3J0IGphdmF4LnRvb2xzLkphdmFGaWxlT2JqZWN0OwppbXBvcnQgamF2YXgudG9vbHMuT3B0aW9uQ2hlY2tlcjsKaW1wb3J0IGphdmF4LnRvb2xzLlN0YW5kYXJkSmF2YUZpbGVNYW5hZ2VyOwppbXBvcnQgamF2YXgudG9vbHMuU3RhbmRhcmRMb2NhdGlvbjsKaW1wb3J0IGphdmF4LnRvb2xzLlRvb2w7CgovKioKICogVGhpcyBjbGFzcyBpcyBpbnRlbmRlZCB0byBiZSBwdXQgaW4gamF2YXgudG9vbHMuCiAqCiAqIEBzZWUgRGlhZ25vc3RpY0xpc3RlbmVyCiAqIEBzZWUgRGlhZ25vc3RpYwogKiBAc2VlIEphdmFGaWxlTWFuYWdlcgogKiBAc2luY2UgMS43CiAqCiAqICA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiAgSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93biByaXNrLgogKiAgVGhpcyBjb2RlIGFuZCBpdHMgaW50ZXJuYWwgaW50ZXJmYWNlcyBhcmUgc3ViamVjdCB0byBjaGFuZ2Ugb3IKICogIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj4KICovCnB1YmxpYyBpbnRlcmZhY2UgTmF0aXZlSGVhZGVyVG9vbCBleHRlbmRzIFRvb2wsIE9wdGlvbkNoZWNrZXIgewoKICAgIC8qKgogICAgICogQ3JlYXRlcyBhIGZ1dHVyZSBmb3IgYSBuYXRpdmUgaGVhZGVyIHRhc2sgd2l0aCB0aGUgZ2l2ZW4KICAgICAqIGNvbXBvbmVudHMgYW5kIGFyZ3VtZW50cy4gIFRoZSB0YXNrIG1pZ2h0IG5vdCBoYXZlCiAgICAgKiBjb21wbGV0ZWQgYXMgZGVzY3JpYmVkIGluIHRoZSBOYXRpdmVIZWFkZXJUYXNrIGludGVyZmFjZS4KICAgICAqCiAgICAgKiA8cD5JZiBhIGZpbGUgbWFuYWdlciBpcyBwcm92aWRlZCwgaXQgbXVzdCBiZSBhYmxlIHRvIGhhbmRsZSBhbGwKICAgICAqIGxvY2F0aW9ucyBkZWZpbmVkIGluIHtAbGluayBTdGFuZGFyZExvY2F0aW9ufS4KICAgICAqCiAgICAgKiBAcGFyYW0gb3V0IGEgV3JpdGVyIGZvciBhZGRpdGlvbmFsIG91dHB1dCBmcm9tIHRoZSB0YXNrOwogICAgICogdXNlIHtAY29kZSBTeXN0ZW0uZXJyfSBpZiB7QGNvZGUgbnVsbH0KICAgICAqIEBwYXJhbSBmaWxlTWFuYWdlciBhIGZpbGUgbWFuYWdlcjsgaWYge0Bjb2RlIG51bGx9IHVzZSB0aGUKICAgICAqIHRhc2sncyBzdGFuZGFyZCBmaWxlbWFuYWdlcgogICAgICogQHBhcmFtIGRpYWdub3N0aWNMaXN0ZW5lciBhIGRpYWdub3N0aWMgbGlzdGVuZXI7IGlmIHtAY29kZQogICAgICogbnVsbH0gdXNlIHRoZSBjb21waWxlcidzIGRlZmF1bHQgbWV0aG9kIGZvciByZXBvcnRpbmcKICAgICAqIGRpYWdub3N0aWNzCiAgICAgKiBAcGFyYW0gb3B0aW9ucyB0YXNrIG9wdGlvbnMsIHtAY29kZSBudWxsfSBtZWFucyBubyBvcHRpb25zCiAgICAgKiBAcGFyYW0gY2xhc3NlcyBjbGFzcyBuYW1lcyBmb3Igd2hpY2ggbmF0aXZlIGhlYWRlcnMgc2hvdWxkIGJlIGdlbmVyYXRlZAogICAgICogQHJldHVybiBhbiBvYmplY3QgcmVwcmVzZW50aW5nIHRoZSB0YXNrIHRvIGJlIGRvbmUKICAgICAqIEB0aHJvd3MgUnVudGltZUV4Y2VwdGlvbiBpZiBhbiB1bnJlY292ZXJhYmxlIGVycm9yCiAgICAgKiBvY2N1cnJlZCBpbiBhIHVzZXIgc3VwcGxpZWQgY29tcG9uZW50LiAgVGhlCiAgICAgKiB7QGxpbmtwbGFpbiBUaHJvd2FibGUjZ2V0Q2F1c2UoKSBjYXVzZX0gd2lsbCBiZSB0aGUgZXJyb3IgaW4KICAgICAqIHVzZXIgY29kZS4KICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIGFueSBvZiB0aGUgZ2l2ZW4KICAgICAqIGNvbXBpbGF0aW9uIHVuaXRzIGFyZSBvZiBvdGhlciBraW5kIHRoYW4KICAgICAqIHtAbGlua3BsYWluIEphdmFGaWxlT2JqZWN0LktpbmQjU09VUkNFIHNvdXJjZX0KICAgICAqLwogICAgTmF0aXZlSGVhZGVyVGFzayBnZXRUYXNrKFdyaXRlciBvdXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBKYXZhRmlsZU1hbmFnZXIgZmlsZU1hbmFnZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBEaWFnbm9zdGljTGlzdGVuZXI8PyBzdXBlciBKYXZhRmlsZU9iamVjdD4gZGlhZ25vc3RpY0xpc3RlbmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgSXRlcmFibGU8U3RyaW5nPiBvcHRpb25zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgSXRlcmFibGU8U3RyaW5nPiBjbGFzc2VzKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgYSBuZXcgaW5zdGFuY2Ugb2YgdGhlIHN0YW5kYXJkIGZpbGUgbWFuYWdlciBpbXBsZW1lbnRhdGlvbgogICAgICogZm9yIHRoaXMgdG9vbC4gIFRoZSBmaWxlIG1hbmFnZXIgd2lsbCB1c2UgdGhlIGdpdmVuIGRpYWdub3N0aWMKICAgICAqIGxpc3RlbmVyIGZvciBwcm9kdWNpbmcgYW55IG5vbi1mYXRhbCBkaWFnbm9zdGljcy4gIEZhdGFsIGVycm9ycwogICAgICogd2lsbCBiZSBzaWduYWxsZWQgd2l0aCB0aGUgYXBwcm9wcmlhdGUgZXhjZXB0aW9ucy4KICAgICAqCiAgICAgKiA8cD5UaGUgc3RhbmRhcmQgZmlsZSBtYW5hZ2VyIHdpbGwgYmUgYXV0b21hdGljYWxseSByZW9wZW5lZCBpZgogICAgICogaXQgaXMgYWNjZXNzZWQgYWZ0ZXIgY2FsbHMgdG8ge0Bjb2RlIGZsdXNofSBvciB7QGNvZGUgY2xvc2V9LgogICAgICogVGhlIHN0YW5kYXJkIGZpbGUgbWFuYWdlciBtdXN0IGJlIHVzYWJsZSB3aXRoIG90aGVyIHRvb2xzLgogICAgICoKICAgICAqIEBwYXJhbSBkaWFnbm9zdGljTGlzdGVuZXIgYSBkaWFnbm9zdGljIGxpc3RlbmVyIGZvciBub24tZmF0YWwKICAgICAqIGRpYWdub3N0aWNzOyBpZiB7QGNvZGUgbnVsbH0gdXNlIHRoZSB0b29sJ3MgZGVmYXVsdCBtZXRob2QKICAgICAqIGZvciByZXBvcnRpbmcgZGlhZ25vc3RpY3MKICAgICAqIEBwYXJhbSBsb2NhbGUgdGhlIGxvY2FsZSB0byBhcHBseSB3aGVuIGZvcm1hdHRpbmcgZGlhZ25vc3RpY3M7CiAgICAgKiB7QGNvZGUgbnVsbH0gbWVhbnMgdGhlIHtAbGlua3BsYWluIExvY2FsZSNnZXREZWZhdWx0KCkgZGVmYXVsdCBsb2NhbGV9LgogICAgICogQHBhcmFtIGNoYXJzZXQgdGhlIGNoYXJhY3RlciBzZXQgdXNlZCBmb3IgZGVjb2RpbmcgYnl0ZXM7IGlmCiAgICAgKiB7QGNvZGUgbnVsbH0gdXNlIHRoZSBwbGF0Zm9ybSBkZWZhdWx0CiAgICAgKiBAcmV0dXJuIHRoZSBzdGFuZGFyZCBmaWxlIG1hbmFnZXIKICAgICAqLwogICAgU3RhbmRhcmRKYXZhRmlsZU1hbmFnZXIgZ2V0U3RhbmRhcmRGaWxlTWFuYWdlcigKICAgICAgICBEaWFnbm9zdGljTGlzdGVuZXI8PyBzdXBlciBKYXZhRmlsZU9iamVjdD4gZGlhZ25vc3RpY0xpc3RlbmVyLAogICAgICAgIExvY2FsZSBsb2NhbGUsCiAgICAgICAgQ2hhcnNldCBjaGFyc2V0KTsKCiAgICAvKioKICAgICAqIEludGVyZmFjZSByZXByZXNlbnRpbmcgYSBmdXR1cmUgZm9yIGEgbmF0aXZlIGhlYWRlciB0YXNrLiAgVGhlCiAgICAgKiB0YXNrIGhhcyBub3QgeWV0IHN0YXJ0ZWQuICBUbyBzdGFydCB0aGUgdGFzaywgY2FsbAogICAgICogdGhlIHtAbGlua3BsYWluICNjYWxsIGNhbGx9IG1ldGhvZC4KICAgICAqCiAgICAgKiA8cD5CZWZvcmUgY2FsbGluZyB0aGUgY2FsbCBtZXRob2QsIGFkZGl0aW9uYWwgYXNwZWN0cyBvZiB0aGUKICAgICAqIHRhc2sgY2FuIGJlIGNvbmZpZ3VyZWQsIGZvciBleGFtcGxlLCBieSBjYWxsaW5nIHRoZQogICAgICoge0BsaW5rcGxhaW4gI3NldExvY2FsZSBzZXRMb2NhbGV9IG1ldGhvZC4KICAgICAqLwogICAgaW50ZXJmYWNlIE5hdGl2ZUhlYWRlclRhc2sgZXh0ZW5kcyBDYWxsYWJsZTxCb29sZWFuPiB7CgogICAgICAgIC8qKgogICAgICAgICAqIFNldCB0aGUgbG9jYWxlIHRvIGJlIGFwcGxpZWQgd2hlbiBmb3JtYXR0aW5nIGRpYWdub3N0aWNzIGFuZAogICAgICAgICAqIG90aGVyIGxvY2FsaXplZCBkYXRhLgogICAgICAgICAqCiAgICAgICAgICogQHBhcmFtIGxvY2FsZSB0aGUgbG9jYWxlIHRvIGFwcGx5OyB7QGNvZGUgbnVsbH0gbWVhbnMgYXBwbHkgbm8KICAgICAgICAgKiBsb2NhbGUKICAgICAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB0aGUgdGFzayBoYXMgc3RhcnRlZAogICAgICAgICAqLwogICAgICAgIHZvaWQgc2V0TG9jYWxlKExvY2FsZSBsb2NhbGUpOwoKICAgICAgICAvKioKICAgICAgICAgKiBQZXJmb3JtcyB0aGlzIG5hdGl2ZSBoZWFkZXIgdGFzay4gIFRoZSB0YXNrIG1heSBvbmx5CiAgICAgICAgICogYmUgcGVyZm9ybWVkIG9uY2UuICBTdWJzZXF1ZW50IGNhbGxzIHRvIHRoaXMgbWV0aG9kIHRocm93CiAgICAgICAgICogSWxsZWdhbFN0YXRlRXhjZXB0aW9uLgogICAgICAgICAqCiAgICAgICAgICogQHJldHVybiB0cnVlIGlmIGFuZCBvbmx5IGFsbCB0aGUgZmlsZXMgd2VyZSBwcm9jZXNzZWQgd2l0aG91dCBlcnJvcnM7CiAgICAgICAgICogZmFsc2Ugb3RoZXJ3aXNlCiAgICAgICAgICoKICAgICAgICAgKiBAdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24gaWYgYW4gdW5yZWNvdmVyYWJsZSBlcnJvciBvY2N1cnJlZAogICAgICAgICAqIGluIGEgdXNlci1zdXBwbGllZCBjb21wb25lbnQuICBUaGUKICAgICAgICAgKiB7QGxpbmtwbGFpbiBUaHJvd2FibGUjZ2V0Q2F1c2UoKSBjYXVzZX0gd2lsbCBiZSB0aGUgZXJyb3IKICAgICAgICAgKiBpbiB1c2VyIGNvZGUuCiAgICAgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgY2FsbGVkIG1vcmUgdGhhbiBvbmNlCiAgICAgICAgICovCiAgICAgICAgQm9vbGVhbiBjYWxsKCk7CiAgICB9Cn0KUEsDBAoAAAgAANJ9TUqAyVYXrwYAAK8GAAAmAAAAY29tL3N1bi90b29scy9qYXZhaC9JbnRlcm5hbEVycm9yLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDcsIDIwMDgsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhaDsKCi8qKgogKiAgPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24gcmlzay4KICogIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yCiAqICBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+CiAqLwpwdWJsaWMgY2xhc3MgSW50ZXJuYWxFcnJvciBleHRlbmRzIEVycm9yIHsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDg0MTE4NjE1NjI0OTcxNjUwMjJMOwogICAgSW50ZXJuYWxFcnJvcihTdHJpbmcgbXNnLCBUaHJvd2FibGUgY2F1c2UpIHsKICAgICAgICBzdXBlcigiSW50ZXJuYWwgZXJyb3I6ICIgKyBtc2cpOwogICAgICAgIGluaXRDYXVzZShjYXVzZSk7CiAgICB9Cn0KUEsDBAoAAAgAAAY7qUojH6Ih2jIAANoyAAAcAAAAY29tL3N1bi90b29scy9qYXZhaC9HZW4uamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwMiwgMjAxNCwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLmphdmFoOwoKaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtOwppbXBvcnQgamF2YS5pby5GaWxlTm90Rm91bmRFeGNlcHRpb247CmltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwppbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOwppbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW1Xcml0ZXI7CmltcG9ydCBqYXZhLmlvLlByaW50V3JpdGVyOwppbXBvcnQgamF2YS5pby5VbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uOwppbXBvcnQgamF2YS5uaW8uZmlsZS5Ob1N1Y2hGaWxlRXhjZXB0aW9uOwppbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CmltcG9ydCBqYXZhLnV0aWwuTGlzdDsKaW1wb3J0IGphdmEudXRpbC5TZXQ7CmltcG9ydCBqYXZhLnV0aWwuU3RhY2s7CgppbXBvcnQgamF2YXguYW5ub3RhdGlvbi5wcm9jZXNzaW5nLlByb2Nlc3NpbmdFbnZpcm9ubWVudDsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC5FeGVjdXRhYmxlRWxlbWVudDsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC5Nb2RpZmllcjsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC5UeXBlRWxlbWVudDsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC5WYXJpYWJsZUVsZW1lbnQ7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLnV0aWwuRWxlbWVudEZpbHRlcjsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwudXRpbC5FbGVtZW50czsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwudXRpbC5UeXBlczsKaW1wb3J0IGphdmF4LnRvb2xzLkZpbGVPYmplY3Q7CmltcG9ydCBqYXZheC50b29scy5KYXZhRmlsZU1hbmFnZXI7CmltcG9ydCBqYXZheC50b29scy5KYXZhRmlsZU9iamVjdDsKaW1wb3J0IGphdmF4LnRvb2xzLlN0YW5kYXJkTG9jYXRpb247CgovKioKICogQW4gYWJzdHJhY3Rpb24gZm9yIGdlbmVyYXRpbmcgc3VwcG9ydCBmaWxlcyByZXF1aXJlZCBieSBuYXRpdmUgbWV0aG9kcy4KICogU3ViY2xhc3NlcyBhcmUgZm9yIHNwZWNpZmljIG5hdGl2ZSBpbnRlcmZhY2VzLiBBdCB0aGUgdGltZSBvZiBpdHMKICogb3JpZ2luYWwgd3JpdGluZywgdGhpcyBpbnRlcmZhY2UgaXMgcmljaCBlbm91Z2ggdG8gc3VwcG9ydCBKTkkgYW5kIHRoZQogKiBvbGQgMS4wLXN0eWxlIG5hdGl2ZSBtZXRob2QgaW50ZXJmYWNlLgogKgogKiA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duCiAqIHJpc2suICBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZQogKiBvciBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+PC9wPgogKgogKiBAYXV0aG9yICBTdWNoZXRhIERhbWJhbGthcihSZXZpc2VkKQogKi8KcHVibGljIGFic3RyYWN0IGNsYXNzIEdlbiB7CiAgICBwcm90ZWN0ZWQgU3RyaW5nIGxpbmVTZXAgPSBTeXN0ZW0uZ2V0UHJvcGVydHkoImxpbmUuc2VwYXJhdG9yIik7CgogICAgcHJvdGVjdGVkIFByb2Nlc3NpbmdFbnZpcm9ubWVudCBwcm9jZXNzaW5nRW52aXJvbm1lbnQ7CiAgICBwcm90ZWN0ZWQgVHlwZXMgdHlwZXM7CiAgICBwcm90ZWN0ZWQgRWxlbWVudHMgZWxlbXM7CiAgICBwcm90ZWN0ZWQgTWFuZ2xlIG1hbmdsZXI7CiAgICBwcm90ZWN0ZWQgVXRpbCB1dGlsOwoKICAgIHByb3RlY3RlZCBHZW4oVXRpbCB1dGlsKSB7CiAgICAgICAgdGhpcy51dGlsID0gdXRpbDsKICAgIH0KCiAgICAvKgogICAgICogTGlzdCBvZiBjbGFzc2VzIGZvciB3aGljaCB3ZSBtdXN0IGdlbmVyYXRlIG91dHB1dC4KICAgICAqLwogICAgcHJvdGVjdGVkIFNldDxUeXBlRWxlbWVudD4gY2xhc3NlczsKICAgIHN0YXRpYyBwcml2YXRlIGZpbmFsIGJvb2xlYW4gaXNXaW5kb3dzID0KICAgICAgICBTeXN0ZW0uZ2V0UHJvcGVydHkoIm9zLm5hbWUiKS5zdGFydHNXaXRoKCJXaW5kb3dzIik7CgoKICAgIC8qKgogICAgICogT3ZlcnJpZGUgdGhpcyBhYnN0cmFjdCBtZXRob2QsIGdlbmVyYXRpbmcgY29udGVudCBmb3IgdGhlIG5hbWVkCiAgICAgKiBjbGFzcyBpbnRvIHRoZSBvdXRwdXRzdHJlYW0uCiAgICAgKi8KICAgIHByb3RlY3RlZCBhYnN0cmFjdCB2b2lkIHdyaXRlKE91dHB1dFN0cmVhbSBvLCBUeXBlRWxlbWVudCBjbGF6eikgdGhyb3dzIFV0aWwuRXhpdDsKCiAgICAvKioKICAgICAqIE92ZXJyaWRlIHRoaXMgbWV0aG9kIHRvIHByb3ZpZGUgYSBsaXN0IG9mICNpbmNsdWRlIHN0YXRlbWVudHMKICAgICAqIHJlcXVpcmVkIGJ5IHRoZSBuYXRpdmUgaW50ZXJmYWNlLgogICAgICovCiAgICBwcm90ZWN0ZWQgYWJzdHJhY3QgU3RyaW5nIGdldEluY2x1ZGVzKCk7CgogICAgLyoKICAgICAqIE91dHB1dCBsb2NhdGlvbi4KICAgICAqLwogICAgcHJvdGVjdGVkIEphdmFGaWxlTWFuYWdlciBmaWxlTWFuYWdlcjsKICAgIHByb3RlY3RlZCBKYXZhRmlsZU9iamVjdCBvdXRGaWxlOwoKICAgIHB1YmxpYyB2b2lkIHNldEZpbGVNYW5hZ2VyKEphdmFGaWxlTWFuYWdlciBmbSkgewogICAgICAgIGZpbGVNYW5hZ2VyID0gZm07CiAgICB9CgogICAgcHVibGljIHZvaWQgc2V0T3V0RmlsZShKYXZhRmlsZU9iamVjdCBvdXRGaWxlKSB7CiAgICAgICAgdGhpcy5vdXRGaWxlID0gb3V0RmlsZTsKICAgIH0KCgogICAgcHVibGljIHZvaWQgc2V0Q2xhc3NlcyhTZXQ8VHlwZUVsZW1lbnQ+IGNsYXNzZXMpIHsKICAgICAgICB0aGlzLmNsYXNzZXMgPSBjbGFzc2VzOwogICAgfQoKICAgIHZvaWQgc2V0UHJvY2Vzc2luZ0Vudmlyb25tZW50KFByb2Nlc3NpbmdFbnZpcm9ubWVudCBwRW52KSB7CiAgICAgICAgcHJvY2Vzc2luZ0Vudmlyb25tZW50ID0gcEVudjsKICAgICAgICBlbGVtcyA9IHBFbnYuZ2V0RWxlbWVudFV0aWxzKCk7CiAgICAgICAgdHlwZXMgPSBwRW52LmdldFR5cGVVdGlscygpOwogICAgICAgIG1hbmdsZXIgPSBuZXcgTWFuZ2xlKGVsZW1zLCB0eXBlcyk7CiAgICB9CgogICAgLyoKICAgICAqIFNtYXJ0bmVzcyB3aXRoIGdlbmVyYXRlZCBmaWxlcy4KICAgICAqLwogICAgcHJvdGVjdGVkIGJvb2xlYW4gZm9yY2UgPSBmYWxzZTsKCiAgICBwdWJsaWMgdm9pZCBzZXRGb3JjZShib29sZWFuIHN0YXRlKSB7CiAgICAgICAgZm9yY2UgPSBzdGF0ZTsKICAgIH0KCiAgICAvKioKICAgICAqIFdlIGV4cGxpY2l0bHkgbmVlZCB0byB3cml0ZSBBU0NJSSBmaWxlcyBiZWNhdXNlIHRoYXQgaXMgd2hhdCBDCiAgICAgKiBjb21waWxlcnMgdW5kZXJzdGFuZC4KICAgICAqLwogICAgcHJvdGVjdGVkIFByaW50V3JpdGVyIHdyYXBXcml0ZXIoT3V0cHV0U3RyZWFtIG8pIHRocm93cyBVdGlsLkV4aXQgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIHJldHVybiBuZXcgUHJpbnRXcml0ZXIobmV3IE91dHB1dFN0cmVhbVdyaXRlcihvLCAiSVNPODg1OV8xIiksIHRydWUpOwogICAgICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24gdXNlKSB7CiAgICAgICAgICAgIHV0aWwuYnVnKCJlbmNvZGluZy5pc284ODU5XzEubm90LmZvdW5kIik7CiAgICAgICAgICAgIHJldHVybiBudWxsOyAvKiBkZWFkIGNvZGUgKi8KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBBZnRlciBpbml0aWFsaXppbmcgc3RhdGUgb2YgYW4gaW5zdGFuY2UsIHVzZSB0aGlzIG1ldGhvZCB0byBzdGFydAogICAgICogcHJvY2Vzc2luZy4KICAgICAqCiAgICAgKiBCdWZmZXIgc2l6ZSBjaG9zZW4gYXMgYW4gYXBwcm94aW1hdGlvbiBmcm9tIGEgc2luZ2xlIHNhbXBsaW5nIG9mOgogICAgICogICAgICAgICBleHByIGBkdSAtc2tgIC8gYGxzICouaCB8IHdjIC1sYAogICAgICovCiAgICBwdWJsaWMgdm9pZCBydW4oKSB0aHJvd3MgSU9FeGNlcHRpb24sIENsYXNzTm90Rm91bmRFeGNlcHRpb24sIFV0aWwuRXhpdCB7CiAgICAgICAgaW50IGkgPSAwOwogICAgICAgIGlmIChvdXRGaWxlICE9IG51bGwpIHsKICAgICAgICAgICAgLyogRXZlcnl0aGluZyBnb2VzIHRvIG9uZSBiaWcgZmlsZS4uLiAqLwogICAgICAgICAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYm91dCA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oODE5Mik7CiAgICAgICAgICAgIHdyaXRlRmlsZVRvcChib3V0KTsgLyogb25seSBvbmNlICovCgogICAgICAgICAgICBmb3IgKFR5cGVFbGVtZW50IHQ6IGNsYXNzZXMpIHsKICAgICAgICAgICAgICAgIHdyaXRlKGJvdXQsIHQpOwogICAgICAgICAgICB9CgogICAgICAgICAgICB3cml0ZUlmQ2hhbmdlZChib3V0LnRvQnl0ZUFycmF5KCksIG91dEZpbGUpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8qIEVhY2ggY2xhc3MgZ29lcyB0byBpdHMgb3duIGZpbGUuLi4gKi8KICAgICAgICAgICAgZm9yIChUeXBlRWxlbWVudCB0OiBjbGFzc2VzKSB7CiAgICAgICAgICAgICAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYm91dCA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oODE5Mik7CiAgICAgICAgICAgICAgICB3cml0ZUZpbGVUb3AoYm91dCk7CiAgICAgICAgICAgICAgICB3cml0ZShib3V0LCB0KTsKICAgICAgICAgICAgICAgIHdyaXRlSWZDaGFuZ2VkKGJvdXQudG9CeXRlQXJyYXkoKSwgZ2V0RmlsZU9iamVjdCh0LmdldFF1YWxpZmllZE5hbWUoKSkpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qCiAgICAgKiBXcml0ZSB0aGUgY29udGVudHMgb2YgYnl0ZVtdIGIgdG8gYSBmaWxlIG5hbWVkIGZpbGUuICBXcml0aW5nCiAgICAgKiBpcyBkb25lIGlmIGVpdGhlciB0aGUgZmlsZSBkb2Vzbid0IGV4aXN0IG9yIGlmIHRoZSBjb250ZW50cyBhcmUKICAgICAqIGRpZmZlcmVudC4KICAgICAqLwogICAgcHJpdmF0ZSB2b2lkIHdyaXRlSWZDaGFuZ2VkKGJ5dGVbXSBiLCBGaWxlT2JqZWN0IGZpbGUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgYm9vbGVhbiBtdXN0V3JpdGUgPSBmYWxzZTsKICAgICAgICBTdHJpbmcgZXZlbnQgPSAiW05vIG5lZWQgdG8gdXBkYXRlIGZpbGUgIjsKCiAgICAgICAgaWYgKGZvcmNlKSB7CiAgICAgICAgICAgIG11c3RXcml0ZSA9IHRydWU7CiAgICAgICAgICAgIGV2ZW50ID0gIltGb3JjZWZ1bGx5IHdyaXRpbmcgZmlsZSAiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIElucHV0U3RyZWFtIGluOwogICAgICAgICAgICBieXRlW10gYTsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIC8vIHJlZ3JldHRhYmx5LCB0aGVyZSdzIG5vIEFQSSB0byBnZXQgdGhlIGxlbmd0aCBpbiBieXRlcwogICAgICAgICAgICAgICAgLy8gZm9yIGEgRmlsZU9iamVjdCwgc28gd2UgY2FuJ3Qgc2hvcnQtY2lyY3VpdCByZWFkaW5nIHRoZQogICAgICAgICAgICAgICAgLy8gZmlsZSBoZXJlCiAgICAgICAgICAgICAgICBpbiA9IGZpbGUub3BlbklucHV0U3RyZWFtKCk7CiAgICAgICAgICAgICAgICBhID0gcmVhZEJ5dGVzKGluKTsKICAgICAgICAgICAgICAgIGlmICghQXJyYXlzLmVxdWFscyhhLCBiKSkgewogICAgICAgICAgICAgICAgICAgIG11c3RXcml0ZSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgZXZlbnQgPSAiW092ZXJ3cml0aW5nIGZpbGUgIjsKCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gY2F0Y2ggKEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiB8IE5vU3VjaEZpbGVFeGNlcHRpb24gZSkgewogICAgICAgICAgICAgICAgbXVzdFdyaXRlID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGV2ZW50ID0gIltDcmVhdGluZyBmaWxlICI7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICh1dGlsLnZlcmJvc2UpCiAgICAgICAgICAgIHV0aWwubG9nKGV2ZW50ICsgZmlsZSArICJdIik7CgogICAgICAgIGlmIChtdXN0V3JpdGUpIHsKICAgICAgICAgICAgT3V0cHV0U3RyZWFtIG91dCA9IGZpbGUub3Blbk91dHB1dFN0cmVhbSgpOwogICAgICAgICAgICBvdXQud3JpdGUoYik7IC8qIE5vIGJ1ZmZlcmluZywganVzdCBvbmUgYmlnIHdyaXRlISAqLwogICAgICAgICAgICBvdXQuY2xvc2UoKTsKICAgICAgICB9CiAgICB9CgogICAgcHJvdGVjdGVkIGJ5dGVbXSByZWFkQnl0ZXMoSW5wdXRTdHJlYW0gaW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgYnl0ZVtdIGFycmF5ID0gbmV3IGJ5dGVbaW4uYXZhaWxhYmxlKCkgKyAxXTsKICAgICAgICAgICAgaW50IG9mZnNldCA9IDA7CiAgICAgICAgICAgIGludCBuOwogICAgICAgICAgICB3aGlsZSAoKG4gPSBpbi5yZWFkKGFycmF5LCBvZmZzZXQsIGFycmF5Lmxlbmd0aCAtIG9mZnNldCkpICE9IC0xKSB7CiAgICAgICAgICAgICAgICBvZmZzZXQgKz0gbjsKICAgICAgICAgICAgICAgIGlmIChvZmZzZXQgPT0gYXJyYXkubGVuZ3RoKQogICAgICAgICAgICAgICAgICAgIGFycmF5ID0gQXJyYXlzLmNvcHlPZihhcnJheSwgYXJyYXkubGVuZ3RoICogMik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBBcnJheXMuY29weU9mKGFycmF5LCBvZmZzZXQpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgIGluLmNsb3NlKCk7CiAgICAgICAgfQogICAgfQoKICAgIHByb3RlY3RlZCBTdHJpbmcgZGVmaW5lRm9yU3RhdGljKFR5cGVFbGVtZW50IGMsIFZhcmlhYmxlRWxlbWVudCBmKQogICAgICAgICAgICB0aHJvd3MgVXRpbC5FeGl0IHsKICAgICAgICBDaGFyU2VxdWVuY2UgY25hbWVkb2MgPSBjLmdldFF1YWxpZmllZE5hbWUoKTsKICAgICAgICBDaGFyU2VxdWVuY2UgZm5hbWVkb2MgPSBmLmdldFNpbXBsZU5hbWUoKTsKCiAgICAgICAgU3RyaW5nIGNuYW1lID0gbWFuZ2xlci5tYW5nbGUoY25hbWVkb2MsIE1hbmdsZS5UeXBlLkNMQVNTKTsKICAgICAgICBTdHJpbmcgZm5hbWUgPSBtYW5nbGVyLm1hbmdsZShmbmFtZWRvYywgTWFuZ2xlLlR5cGUuRklFTERTVFVCKTsKCiAgICAgICAgaWYgKCFmLmdldE1vZGlmaWVycygpLmNvbnRhaW5zKE1vZGlmaWVyLlNUQVRJQykpCiAgICAgICAgICAgIHV0aWwuYnVnKCJ0cmllZC50by5kZWZpbmUubm9uLnN0YXRpYyIpOwoKICAgICAgICBpZiAoZi5nZXRNb2RpZmllcnMoKS5jb250YWlucyhNb2RpZmllci5GSU5BTCkpIHsKICAgICAgICAgICAgT2JqZWN0IHZhbHVlID0gbnVsbDsKCiAgICAgICAgICAgIHZhbHVlID0gZi5nZXRDb25zdGFudFZhbHVlKCk7CgogICAgICAgICAgICBpZiAodmFsdWUgIT0gbnVsbCkgeyAvKiBzbyBpdCBpcyBhIENvbnN0YW50RXhwcmVzc2lvbiAqLwogICAgICAgICAgICAgICAgU3RyaW5nIGNvbnN0U3RyaW5nID0gbnVsbDsKICAgICAgICAgICAgICAgIGlmICgodmFsdWUgaW5zdGFuY2VvZiBJbnRlZ2VyKQogICAgICAgICAgICAgICAgICAgIHx8ICh2YWx1ZSBpbnN0YW5jZW9mIEJ5dGUpCiAgICAgICAgICAgICAgICAgICAgfHwgKHZhbHVlIGluc3RhbmNlb2YgU2hvcnQpKSB7CiAgICAgICAgICAgICAgICAgICAgLyogY292ZXJzIGJ5dGUsIHNob3J0LCBpbnQgKi8KICAgICAgICAgICAgICAgICAgICBjb25zdFN0cmluZyA9IHZhbHVlLnRvU3RyaW5nKCkgKyAiTCI7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHZhbHVlIGluc3RhbmNlb2YgQm9vbGVhbikgewogICAgICAgICAgICAgICAgICAgIGNvbnN0U3RyaW5nID0gKChCb29sZWFuKSB2YWx1ZSkgPyAiMUwiIDogIjBMIjsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodmFsdWUgaW5zdGFuY2VvZiBDaGFyYWN0ZXIpIHsKICAgICAgICAgICAgICAgICAgICBDaGFyYWN0ZXIgY2ggPSAoQ2hhcmFjdGVyKSB2YWx1ZTsKICAgICAgICAgICAgICAgICAgICBjb25zdFN0cmluZyA9IFN0cmluZy52YWx1ZU9mKCgoaW50KSBjaCkgJiAweGZmZmYpICsgIkwiOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmICh2YWx1ZSBpbnN0YW5jZW9mIExvbmcpIHsKICAgICAgICAgICAgICAgICAgICAvLyBWaXN1YWwgQysrIHN1cHBvcnRzIHRoZSBpNjQgc3VmZml4LCBub3QgTEwuCiAgICAgICAgICAgICAgICAgICAgaWYgKGlzV2luZG93cykKICAgICAgICAgICAgICAgICAgICAgICAgY29uc3RTdHJpbmcgPSB2YWx1ZS50b1N0cmluZygpICsgImk2NCI7CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICBjb25zdFN0cmluZyA9IHZhbHVlLnRvU3RyaW5nKCkgKyAiTEwiOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmICh2YWx1ZSBpbnN0YW5jZW9mIEZsb2F0KSB7CiAgICAgICAgICAgICAgICAgICAgLyogYnVnIGZvciBidWcgKi8KICAgICAgICAgICAgICAgICAgICBmbG9hdCBmdiA9ICgoRmxvYXQpdmFsdWUpLmZsb2F0VmFsdWUoKTsKICAgICAgICAgICAgICAgICAgICBpZiAoRmxvYXQuaXNJbmZpbml0ZShmdikpCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0U3RyaW5nID0gKChmdiA8IDApID8gIi0iIDogIiIpICsgIkluZmYiOwogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgY29uc3RTdHJpbmcgPSB2YWx1ZS50b1N0cmluZygpICsgImYiOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmICh2YWx1ZSBpbnN0YW5jZW9mIERvdWJsZSkgewogICAgICAgICAgICAgICAgICAgIC8qIGJ1ZyBmb3IgYnVnICovCiAgICAgICAgICAgICAgICAgICAgZG91YmxlIGQgPSAoKERvdWJsZSl2YWx1ZSkuZG91YmxlVmFsdWUoKTsKICAgICAgICAgICAgICAgICAgICBpZiAoRG91YmxlLmlzSW5maW5pdGUoZCkpCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0U3RyaW5nID0gKChkIDwgMCkgPyAiLSIgOiAiIikgKyAiSW5mRCI7CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICBjb25zdFN0cmluZyA9IHZhbHVlLnRvU3RyaW5nKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoY29uc3RTdHJpbmcgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIFN0cmluZ0J1aWxkZXIgcyA9IG5ldyBTdHJpbmdCdWlsZGVyKCIjdW5kZWYgIik7CiAgICAgICAgICAgICAgICAgICAgcy5hcHBlbmQoY25hbWUpOyBzLmFwcGVuZCgiXyIpOyBzLmFwcGVuZChmbmFtZSk7IHMuYXBwZW5kKGxpbmVTZXApOwogICAgICAgICAgICAgICAgICAgIHMuYXBwZW5kKCIjZGVmaW5lICIpOyBzLmFwcGVuZChjbmFtZSk7IHMuYXBwZW5kKCJfIik7CiAgICAgICAgICAgICAgICAgICAgcy5hcHBlbmQoZm5hbWUpOyBzLmFwcGVuZCgiICIpOyBzLmFwcGVuZChjb25zdFN0cmluZyk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHMudG9TdHJpbmcoKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgLyoKICAgICAqIERlYWwgd2l0aCB0aGUgQyBwcmUtcHJvY2Vzc29yLgogICAgICovCiAgICBwcm90ZWN0ZWQgU3RyaW5nIGNwcEd1YXJkQmVnaW4oKSB7CiAgICAgICAgcmV0dXJuICIjaWZkZWYgX19jcGx1c3BsdXMiICsgbGluZVNlcCArICJleHRlcm4gXCJDXCIgeyIgKyBsaW5lU2VwICsgIiNlbmRpZiI7CiAgICB9CgogICAgcHJvdGVjdGVkIFN0cmluZyBjcHBHdWFyZEVuZCgpIHsKICAgICAgICByZXR1cm4gIiNpZmRlZiBfX2NwbHVzcGx1cyIgKyBsaW5lU2VwICsgIn0iICsgbGluZVNlcCArICIjZW5kaWYiOwogICAgfQoKICAgIHByb3RlY3RlZCBTdHJpbmcgZ3VhcmRCZWdpbihTdHJpbmcgY25hbWUpIHsKICAgICAgICByZXR1cm4gIi8qIEhlYWRlciBmb3IgY2xhc3MgIiArIGNuYW1lICsgIiAqLyIgKyBsaW5lU2VwICsgbGluZVNlcCArCiAgICAgICAgICAgICIjaWZuZGVmIF9JbmNsdWRlZF8iICsgY25hbWUgKyBsaW5lU2VwICsKICAgICAgICAgICAgIiNkZWZpbmUgX0luY2x1ZGVkXyIgKyBjbmFtZTsKICAgIH0KCiAgICBwcm90ZWN0ZWQgU3RyaW5nIGd1YXJkRW5kKFN0cmluZyBjbmFtZSkgewogICAgICAgIHJldHVybiAiI2VuZGlmIjsKICAgIH0KCiAgICAvKgogICAgICogRmlsZSBuYW1lIGFuZCBmaWxlIHByZWFtYmxlIHJlbGF0ZWQgb3BlcmF0aW9ucy4KICAgICAqLwogICAgcHJvdGVjdGVkIHZvaWQgd3JpdGVGaWxlVG9wKE91dHB1dFN0cmVhbSBvKSB0aHJvd3MgVXRpbC5FeGl0IHsKICAgICAgICBQcmludFdyaXRlciBwdyA9IHdyYXBXcml0ZXIobyk7CiAgICAgICAgcHcucHJpbnRsbigiLyogRE8gTk9UIEVESVQgVEhJUyBGSUxFIC0gaXQgaXMgbWFjaGluZSBnZW5lcmF0ZWQgKi8iICsgbGluZVNlcCArCiAgICAgICAgICAgICAgICAgICBnZXRJbmNsdWRlcygpKTsKICAgIH0KCiAgICBwcm90ZWN0ZWQgU3RyaW5nIGJhc2VGaWxlTmFtZShDaGFyU2VxdWVuY2UgY2xhc3NOYW1lKSB7CiAgICAgICAgcmV0dXJuIG1hbmdsZXIubWFuZ2xlKGNsYXNzTmFtZSwgTWFuZ2xlLlR5cGUuQ0xBU1MpOwogICAgfQoKICAgIHByb3RlY3RlZCBGaWxlT2JqZWN0IGdldEZpbGVPYmplY3QoQ2hhclNlcXVlbmNlIGNsYXNzTmFtZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICBTdHJpbmcgbmFtZSA9IGJhc2VGaWxlTmFtZShjbGFzc05hbWUpICsgZ2V0RmlsZVN1ZmZpeCgpOwogICAgICAgIHJldHVybiBmaWxlTWFuYWdlci5nZXRGaWxlRm9yT3V0cHV0KFN0YW5kYXJkTG9jYXRpb24uU09VUkNFX09VVFBVVCwgIiIsIG5hbWUsIG51bGwpOwogICAgfQoKICAgIHByb3RlY3RlZCBTdHJpbmcgZ2V0RmlsZVN1ZmZpeCgpIHsKICAgICAgICByZXR1cm4gIi5oIjsKICAgIH0KCiAgICAvKioKICAgICAqIEluY2x1ZGluZyBzdXBlciBjbGFzc2VzJyBmaWVsZHMuCiAgICAgKi8KCiAgICBMaXN0PFZhcmlhYmxlRWxlbWVudD4gZ2V0QWxsRmllbGRzKFR5cGVFbGVtZW50IHN1YmNsYXp6KSB7CiAgICAgICAgTGlzdDxWYXJpYWJsZUVsZW1lbnQ+IGZpZWxkcyA9IG5ldyBBcnJheUxpc3Q8PigpOwogICAgICAgIFR5cGVFbGVtZW50IGNkID0gbnVsbDsKICAgICAgICBTdGFjazxUeXBlRWxlbWVudD4gcyA9IG5ldyBTdGFjazw+KCk7CgogICAgICAgIGNkID0gc3ViY2xheno7CiAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgICAgcy5wdXNoKGNkKTsKICAgICAgICAgICAgVHlwZUVsZW1lbnQgYyA9IChUeXBlRWxlbWVudCkgKHR5cGVzLmFzRWxlbWVudChjZC5nZXRTdXBlcmNsYXNzKCkpKTsKICAgICAgICAgICAgaWYgKGMgPT0gbnVsbCkKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjZCA9IGM7CiAgICAgICAgfQoKICAgICAgICB3aGlsZSAoIXMuZW1wdHkoKSkgewogICAgICAgICAgICBjZCA9IHMucG9wKCk7CiAgICAgICAgICAgIGZpZWxkcy5hZGRBbGwoRWxlbWVudEZpbHRlci5maWVsZHNJbihjZC5nZXRFbmNsb3NlZEVsZW1lbnRzKCkpKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBmaWVsZHM7CiAgICB9CgogICAgLy8gYy5mLiBNZXRob2REb2Muc2lnbmF0dXJlCiAgICBTdHJpbmcgc2lnbmF0dXJlKEV4ZWN1dGFibGVFbGVtZW50IGUpIHsKICAgICAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoIigiKTsKICAgICAgICBTdHJpbmcgc2VwID0gIiI7CiAgICAgICAgZm9yIChWYXJpYWJsZUVsZW1lbnQgcDogZS5nZXRQYXJhbWV0ZXJzKCkpIHsKICAgICAgICAgICAgc2IuYXBwZW5kKHNlcCk7CiAgICAgICAgICAgIHNiLmFwcGVuZCh0eXBlcy5lcmFzdXJlKHAuYXNUeXBlKCkpLnRvU3RyaW5nKCkpOwogICAgICAgICAgICBzZXAgPSAiLCI7CiAgICAgICAgfQogICAgICAgIHNiLmFwcGVuZCgiKSIpOwogICAgICAgIHJldHVybiBzYi50b1N0cmluZygpOwogICAgfQp9CgpQSwMECgAACAAABjupSmGOvw82ZAAANmQAACIAAABjb20vc3VuL3Rvb2xzL2phdmFoL0phdmFoVGFzay5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDAyLCAyMDE2LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuamF2YWg7CgppbXBvcnQgamF2YS5pby5GaWxlOwppbXBvcnQgamF2YS5pby5GaWxlTm90Rm91bmRFeGNlcHRpb247CmltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwppbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CmltcG9ydCBqYXZhLmlvLlByaW50V3JpdGVyOwppbXBvcnQgamF2YS5pby5Xcml0ZXI7CmltcG9ydCBqYXZhLm5pby5maWxlLk5vU3VjaEZpbGVFeGNlcHRpb247CmltcG9ydCBqYXZhLnRleHQuTWVzc2FnZUZvcm1hdDsKaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CmltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOwppbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOwppbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CmltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CmltcG9ydCBqYXZhLnV0aWwuTGlua2VkSGFzaFNldDsKaW1wb3J0IGphdmEudXRpbC5MaXN0OwppbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKaW1wb3J0IGphdmEudXRpbC5NYXA7CmltcG9ydCBqYXZhLnV0aWwuTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uOwppbXBvcnQgamF2YS51dGlsLk9iamVjdHM7CmltcG9ydCBqYXZhLnV0aWwuUmVzb3VyY2VCdW5kbGU7CmltcG9ydCBqYXZhLnV0aWwuU2V0OwoKaW1wb3J0IGphdmF4LmFubm90YXRpb24ucHJvY2Vzc2luZy5BYnN0cmFjdFByb2Nlc3NvcjsKaW1wb3J0IGphdmF4LmFubm90YXRpb24ucHJvY2Vzc2luZy5NZXNzYWdlcjsKaW1wb3J0IGphdmF4LmFubm90YXRpb24ucHJvY2Vzc2luZy5Qcm9jZXNzaW5nRW52aXJvbm1lbnQ7CmltcG9ydCBqYXZheC5hbm5vdGF0aW9uLnByb2Nlc3NpbmcuUm91bmRFbnZpcm9ubWVudDsKaW1wb3J0IGphdmF4LmFubm90YXRpb24ucHJvY2Vzc2luZy5TdXBwb3J0ZWRBbm5vdGF0aW9uVHlwZXM7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLlNvdXJjZVZlcnNpb247CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuRXhlY3V0YWJsZUVsZW1lbnQ7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuVHlwZUVsZW1lbnQ7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuVmFyaWFibGVFbGVtZW50OwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC50eXBlLkFycmF5VHlwZTsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwudHlwZS5EZWNsYXJlZFR5cGU7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLnR5cGUuVHlwZU1pcnJvcjsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwudHlwZS5UeXBlVmlzaXRvcjsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwudXRpbC5FbGVtZW50RmlsdGVyOwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC51dGlsLlNpbXBsZVR5cGVWaXNpdG9yOTsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwudXRpbC5UeXBlczsKaW1wb3J0IGphdmF4LnRvb2xzLkRpYWdub3N0aWM7CmltcG9ydCBqYXZheC50b29scy5EaWFnbm9zdGljTGlzdGVuZXI7CmltcG9ydCBqYXZheC50b29scy5KYXZhQ29tcGlsZXI7CmltcG9ydCBqYXZheC50b29scy5KYXZhQ29tcGlsZXIuQ29tcGlsYXRpb25UYXNrOwppbXBvcnQgamF2YXgudG9vbHMuSmF2YUZpbGVNYW5hZ2VyOwppbXBvcnQgamF2YXgudG9vbHMuSmF2YUZpbGVPYmplY3Q7CmltcG9ydCBqYXZheC50b29scy5TdGFuZGFyZEphdmFGaWxlTWFuYWdlcjsKaW1wb3J0IGphdmF4LnRvb2xzLlN0YW5kYXJkTG9jYXRpb247CmltcG9ydCBqYXZheC50b29scy5Ub29sUHJvdmlkZXI7CgppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlN5bWJvbC5Db21wbGV0aW9uRmFpbHVyZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMubWFpbi5Db21tYW5kTGluZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5EZWZpbmVkQnk7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuRGVmaW5lZEJ5LkFwaTsKCmltcG9ydCBzdGF0aWMgamF2YXgudG9vbHMuRGlhZ25vc3RpYy5LaW5kLio7CgoKLyoqCiAqIEphdmFoIGdlbmVyYXRlcyBzdXBwb3J0IGZpbGVzIGZvciBuYXRpdmUgbWV0aG9kcy4KICogUGFyc2UgY29tbWFuZGxpbmUgb3B0aW9ucyBhbmQgaW52b2tlcyBqYXZhZG9jIHRvIGV4ZWN1dGUgdGhvc2UgY29tbWFuZHMuCiAqCiAqIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24KICogcmlzay4gIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlCiAqIG9yIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj48L3A+CiAqCiAqIEBhdXRob3IgU3VjaGV0YSBEYW1iYWxrYXIKICogQGF1dGhvciBKb25hdGhhbiBHaWJib25zCiAqLwpwdWJsaWMgY2xhc3MgSmF2YWhUYXNrIGltcGxlbWVudHMgTmF0aXZlSGVhZGVyVG9vbC5OYXRpdmVIZWFkZXJUYXNrIHsKICAgIHB1YmxpYyBjbGFzcyBCYWRBcmdzIGV4dGVuZHMgRXhjZXB0aW9uIHsKICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxNDc5MzYxMjcwODc0Nzg5MDQ1TDsKICAgICAgICBCYWRBcmdzKFN0cmluZyBrZXksIE9iamVjdC4uLiBhcmdzKSB7CiAgICAgICAgICAgIHN1cGVyKEphdmFoVGFzay50aGlzLmdldE1lc3NhZ2Uoa2V5LCBhcmdzKSk7CiAgICAgICAgICAgIHRoaXMua2V5ID0ga2V5OwogICAgICAgICAgICB0aGlzLmFyZ3MgPSBhcmdzOwogICAgICAgIH0KCiAgICAgICAgQmFkQXJncyBzaG93VXNhZ2UoYm9vbGVhbiBiKSB7CiAgICAgICAgICAgIHNob3dVc2FnZSA9IGI7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgZmluYWwgU3RyaW5nIGtleTsKICAgICAgICBmaW5hbCBPYmplY3RbXSBhcmdzOwogICAgICAgIGJvb2xlYW4gc2hvd1VzYWdlOwogICAgfQoKICAgIHN0YXRpYyBhYnN0cmFjdCBjbGFzcyBPcHRpb24gewogICAgICAgIE9wdGlvbihib29sZWFuIGhhc0FyZywgU3RyaW5nLi4uIGFsaWFzZXMpIHsKICAgICAgICAgICAgdGhpcy5oYXNBcmcgPSBoYXNBcmc7CiAgICAgICAgICAgIHRoaXMuYWxpYXNlcyA9IGFsaWFzZXM7CiAgICAgICAgfQoKICAgICAgICBib29sZWFuIGlzSGlkZGVuKCkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICBib29sZWFuIG1hdGNoZXMoU3RyaW5nIG9wdCkgewogICAgICAgICAgICBmb3IgKFN0cmluZyBhOiBhbGlhc2VzKSB7CiAgICAgICAgICAgICAgICBpZiAoYS5lcXVhbHMob3B0KSkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICBib29sZWFuIGlnbm9yZVJlc3QoKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIGFic3RyYWN0IHZvaWQgcHJvY2VzcyhKYXZhaFRhc2sgdGFzaywgU3RyaW5nIG9wdCwgU3RyaW5nIGFyZykgdGhyb3dzIEJhZEFyZ3M7CgogICAgICAgIGZpbmFsIGJvb2xlYW4gaGFzQXJnOwogICAgICAgIGZpbmFsIFN0cmluZ1tdIGFsaWFzZXM7CiAgICB9CgogICAgc3RhdGljIGFic3RyYWN0IGNsYXNzIEhpZGRlbk9wdGlvbiBleHRlbmRzIE9wdGlvbiB7CiAgICAgICAgSGlkZGVuT3B0aW9uKGJvb2xlYW4gaGFzQXJnLCBTdHJpbmcuLi4gYWxpYXNlcykgewogICAgICAgICAgICBzdXBlcihoYXNBcmcsIGFsaWFzZXMpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgYm9vbGVhbiBpc0hpZGRlbigpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgfQoKICAgIHN0YXRpYyBmaW5hbCBPcHRpb25bXSByZWNvZ25pemVkT3B0aW9ucyA9IHsKICAgICAgICBuZXcgT3B0aW9uKHRydWUsICItbyIpIHsKICAgICAgICAgICAgdm9pZCBwcm9jZXNzKEphdmFoVGFzayB0YXNrLCBTdHJpbmcgb3B0LCBTdHJpbmcgYXJnKSB7CiAgICAgICAgICAgICAgICB0YXNrLm9maWxlID0gbmV3IEZpbGUoYXJnKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIG5ldyBPcHRpb24odHJ1ZSwgIi1kIikgewogICAgICAgICAgICB2b2lkIHByb2Nlc3MoSmF2YWhUYXNrIHRhc2ssIFN0cmluZyBvcHQsIFN0cmluZyBhcmcpIHsKICAgICAgICAgICAgICAgIHRhc2sub2RpciA9IG5ldyBGaWxlKGFyZyk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBuZXcgSGlkZGVuT3B0aW9uKHRydWUsICItdGQiKSB7CiAgICAgICAgICAgIHZvaWQgcHJvY2VzcyhKYXZhaFRhc2sgdGFzaywgU3RyaW5nIG9wdCwgU3RyaW5nIGFyZykgewogICAgICAgICAgICAgICAgIC8vIGlnbm9yZWQ7IGZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eQogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgbmV3IE9wdGlvbihmYWxzZSwgIi12IiwgIi12ZXJib3NlIikgewogICAgICAgICAgICB2b2lkIHByb2Nlc3MoSmF2YWhUYXNrIHRhc2ssIFN0cmluZyBvcHQsIFN0cmluZyBhcmcpIHsKICAgICAgICAgICAgICAgIHRhc2sudmVyYm9zZSA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBuZXcgT3B0aW9uKGZhbHNlLCAiLWgiLCAiLWhlbHAiLCAiLS1oZWxwIiwgIi0/IikgewogICAgICAgICAgICB2b2lkIHByb2Nlc3MoSmF2YWhUYXNrIHRhc2ssIFN0cmluZyBvcHQsIFN0cmluZyBhcmcpIHsKICAgICAgICAgICAgICAgIHRhc2suaGVscCA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBuZXcgSGlkZGVuT3B0aW9uKGZhbHNlLCAiLXRyYWNlIikgewogICAgICAgICAgICB2b2lkIHByb2Nlc3MoSmF2YWhUYXNrIHRhc2ssIFN0cmluZyBvcHQsIFN0cmluZyBhcmcpIHsKICAgICAgICAgICAgICAgIHRhc2sudHJhY2UgPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgbmV3IE9wdGlvbihmYWxzZSwgIi12ZXJzaW9uIikgewogICAgICAgICAgICB2b2lkIHByb2Nlc3MoSmF2YWhUYXNrIHRhc2ssIFN0cmluZyBvcHQsIFN0cmluZyBhcmcpIHsKICAgICAgICAgICAgICAgIHRhc2sudmVyc2lvbiA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBuZXcgSGlkZGVuT3B0aW9uKGZhbHNlLCAiLWZ1bGx2ZXJzaW9uIikgewogICAgICAgICAgICB2b2lkIHByb2Nlc3MoSmF2YWhUYXNrIHRhc2ssIFN0cmluZyBvcHQsIFN0cmluZyBhcmcpIHsKICAgICAgICAgICAgICAgIHRhc2suZnVsbFZlcnNpb24gPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgbmV3IE9wdGlvbihmYWxzZSwgIi1qbmkiKSB7CiAgICAgICAgICAgIHZvaWQgcHJvY2VzcyhKYXZhaFRhc2sgdGFzaywgU3RyaW5nIG9wdCwgU3RyaW5nIGFyZykgewogICAgICAgICAgICAgICAgdGFzay5qbmkgPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgbmV3IE9wdGlvbihmYWxzZSwgIi1mb3JjZSIpIHsKICAgICAgICAgICAgdm9pZCBwcm9jZXNzKEphdmFoVGFzayB0YXNrLCBTdHJpbmcgb3B0LCBTdHJpbmcgYXJnKSB7CiAgICAgICAgICAgICAgICB0YXNrLmZvcmNlID0gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIG5ldyBIaWRkZW5PcHRpb24oZmFsc2UsICItWG5ldyIpIHsKICAgICAgICAgICAgdm9pZCBwcm9jZXNzKEphdmFoVGFzayB0YXNrLCBTdHJpbmcgb3B0LCBTdHJpbmcgYXJnKSB7CiAgICAgICAgICAgICAgICAvLyB3ZSdyZSBhbHJlYWR5IHVzaW5nIHRoZSBuZXcgamF2YWgKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIG5ldyBIaWRkZW5PcHRpb24oZmFsc2UsICItbGxuaSIsICItWGxsbmkiKSB7CiAgICAgICAgICAgIHZvaWQgcHJvY2VzcyhKYXZhaFRhc2sgdGFzaywgU3RyaW5nIG9wdCwgU3RyaW5nIGFyZykgewogICAgICAgICAgICAgICAgdGFzay5sbG5pID0gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIG5ldyBIaWRkZW5PcHRpb24oZmFsc2UsICItbGxuaWRvdWJsZSIpIHsKICAgICAgICAgICAgdm9pZCBwcm9jZXNzKEphdmFoVGFzayB0YXNrLCBTdHJpbmcgb3B0LCBTdHJpbmcgYXJnKSB7CiAgICAgICAgICAgICAgICB0YXNrLmxsbmkgPSB0cnVlOwogICAgICAgICAgICAgICAgdGFzay5kb3VibGVBbGlnbiA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBuZXcgSGlkZGVuT3B0aW9uKGZhbHNlKSB7CiAgICAgICAgICAgIGJvb2xlYW4gbWF0Y2hlcyhTdHJpbmcgb3B0KSB7CiAgICAgICAgICAgICAgICByZXR1cm4gb3B0LnN0YXJ0c1dpdGgoIi1YRCIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHZvaWQgcHJvY2VzcyhKYXZhaFRhc2sgdGFzaywgU3RyaW5nIG9wdCwgU3RyaW5nIGFyZykgewogICAgICAgICAgICAgICAgdGFzay5qYXZhY19leHRyYXMuYWRkKG9wdCk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgfTsKCiAgICBKYXZhaFRhc2soKSB7CiAgICB9CgogICAgSmF2YWhUYXNrKFdyaXRlciBvdXQsCiAgICAgICAgICAgIEphdmFGaWxlTWFuYWdlciBmaWxlTWFuYWdlciwKICAgICAgICAgICAgRGlhZ25vc3RpY0xpc3RlbmVyPD8gc3VwZXIgSmF2YUZpbGVPYmplY3Q+IGRpYWdub3N0aWNMaXN0ZW5lciwKICAgICAgICAgICAgSXRlcmFibGU8U3RyaW5nPiBvcHRpb25zLAogICAgICAgICAgICBJdGVyYWJsZTxTdHJpbmc+IGNsYXNzZXMpIHsKICAgICAgICB0aGlzKCk7CiAgICAgICAgdGhpcy5sb2cgPSBnZXRQcmludFdyaXRlckZvcldyaXRlcihvdXQpOwogICAgICAgIHRoaXMuZmlsZU1hbmFnZXIgPSBmaWxlTWFuYWdlcjsKICAgICAgICB0aGlzLmRpYWdub3N0aWNMaXN0ZW5lciA9IGRpYWdub3N0aWNMaXN0ZW5lcjsKCiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgaGFuZGxlT3B0aW9ucyhvcHRpb25zLCBmYWxzZSk7CiAgICAgICAgfSBjYXRjaCAoQmFkQXJncyBlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oZS5nZXRNZXNzYWdlKCkpOwogICAgICAgIH0KCiAgICAgICAgdGhpcy5jbGFzc2VzID0gbmV3IEFycmF5TGlzdDw+KCk7CiAgICAgICAgaWYgKGNsYXNzZXMgIT0gbnVsbCkgewogICAgICAgICAgICBmb3IgKFN0cmluZyBjbGFzc25hbWU6IGNsYXNzZXMpIHsKICAgICAgICAgICAgICAgIE9iamVjdHMucmVxdWlyZU5vbk51bGwoY2xhc3NuYW1lKTsKICAgICAgICAgICAgICAgIHRoaXMuY2xhc3Nlcy5hZGQoY2xhc3NuYW1lKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgdm9pZCBzZXRMb2NhbGUoTG9jYWxlIGxvY2FsZSkgewogICAgICAgIGlmIChsb2NhbGUgPT0gbnVsbCkKICAgICAgICAgICAgbG9jYWxlID0gTG9jYWxlLmdldERlZmF1bHQoKTsKICAgICAgICB0YXNrX2xvY2FsZSA9IGxvY2FsZTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCBzZXRMb2coUHJpbnRXcml0ZXIgbG9nKSB7CiAgICAgICAgdGhpcy5sb2cgPSBsb2c7CiAgICB9CgogICAgcHVibGljIHZvaWQgc2V0TG9nKE91dHB1dFN0cmVhbSBzKSB7CiAgICAgICAgc2V0TG9nKGdldFByaW50V3JpdGVyRm9yU3RyZWFtKHMpKTsKICAgIH0KCiAgICBzdGF0aWMgUHJpbnRXcml0ZXIgZ2V0UHJpbnRXcml0ZXJGb3JTdHJlYW0oT3V0cHV0U3RyZWFtIHMpIHsKICAgICAgICByZXR1cm4gbmV3IFByaW50V3JpdGVyKHMsIHRydWUpOwogICAgfQoKICAgIHN0YXRpYyBQcmludFdyaXRlciBnZXRQcmludFdyaXRlckZvcldyaXRlcihXcml0ZXIgdykgewogICAgICAgIGlmICh3ID09IG51bGwpCiAgICAgICAgICAgIHJldHVybiBnZXRQcmludFdyaXRlckZvclN0cmVhbShudWxsKTsKICAgICAgICBlbHNlIGlmICh3IGluc3RhbmNlb2YgUHJpbnRXcml0ZXIpCiAgICAgICAgICAgIHJldHVybiAoUHJpbnRXcml0ZXIpIHc7CiAgICAgICAgZWxzZQogICAgICAgICAgICByZXR1cm4gbmV3IFByaW50V3JpdGVyKHcsIHRydWUpOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHNldERpYWdub3N0aWNMaXN0ZW5lcihEaWFnbm9zdGljTGlzdGVuZXI8PyBzdXBlciBKYXZhRmlsZU9iamVjdD4gZGwpIHsKICAgICAgICBkaWFnbm9zdGljTGlzdGVuZXIgPSBkbDsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCBzZXREaWFnbm9zdGljTGlzdGVuZXIoT3V0cHV0U3RyZWFtIHMpIHsKICAgICAgICBzZXREaWFnbm9zdGljTGlzdGVuZXIoZ2V0RGlhZ25vc3RpY0xpc3RlbmVyRm9yU3RyZWFtKHMpKTsKICAgIH0KCiAgICBwcml2YXRlIERpYWdub3N0aWNMaXN0ZW5lcjxKYXZhRmlsZU9iamVjdD4gZ2V0RGlhZ25vc3RpY0xpc3RlbmVyRm9yU3RyZWFtKE91dHB1dFN0cmVhbSBzKSB7CiAgICAgICAgcmV0dXJuIGdldERpYWdub3N0aWNMaXN0ZW5lckZvcldyaXRlcihnZXRQcmludFdyaXRlckZvclN0cmVhbShzKSk7CiAgICB9CgogICAgcHJpdmF0ZSBEaWFnbm9zdGljTGlzdGVuZXI8SmF2YUZpbGVPYmplY3Q+IGdldERpYWdub3N0aWNMaXN0ZW5lckZvcldyaXRlcihXcml0ZXIgdykgewogICAgICAgIGZpbmFsIFByaW50V3JpdGVyIHB3ID0gZ2V0UHJpbnRXcml0ZXJGb3JXcml0ZXIodyk7CiAgICAgICAgcmV0dXJuIGRpYWdub3N0aWMgLT4gewogICAgICAgICAgICBpZiAoZGlhZ25vc3RpYy5nZXRLaW5kKCkgPT0gRGlhZ25vc3RpYy5LaW5kLkVSUk9SKSB7CiAgICAgICAgICAgICAgICBwdy5wcmludChnZXRNZXNzYWdlKCJlcnIucHJlZml4IikpOwogICAgICAgICAgICAgICAgcHcucHJpbnQoIiAiKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBwdy5wcmludGxuKGRpYWdub3N0aWMuZ2V0TWVzc2FnZShudWxsKSk7CiAgICAgICAgfTsKICAgIH0KCiAgICBpbnQgcnVuKFN0cmluZ1tdIGFyZ3MpIHsKICAgICAgICB0cnkgewogICAgICAgICAgICBoYW5kbGVPcHRpb25zKGFyZ3MpOwogICAgICAgICAgICBib29sZWFuIG9rID0gcnVuKCk7CiAgICAgICAgICAgIHJldHVybiBvayA/IDAgOiAxOwogICAgICAgIH0gY2F0Y2ggKEJhZEFyZ3MgZSkgewogICAgICAgICAgICBkaWFnbm9zdGljTGlzdGVuZXIucmVwb3J0KGNyZWF0ZURpYWdub3N0aWMoZS5rZXksIGUuYXJncykpOwogICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICB9IGNhdGNoIChJbnRlcm5hbEVycm9yIGUpIHsKICAgICAgICAgICAgZGlhZ25vc3RpY0xpc3RlbmVyLnJlcG9ydChjcmVhdGVEaWFnbm9zdGljKCJlcnIuaW50ZXJuYWwuZXJyb3IiLCBlLmdldE1lc3NhZ2UoKSkpOwogICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICB9IGNhdGNoIChVdGlsLkV4aXQgZSkgewogICAgICAgICAgICByZXR1cm4gZS5leGl0VmFsdWU7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgbG9nLmZsdXNoKCk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyB2b2lkIGhhbmRsZU9wdGlvbnMoU3RyaW5nW10gYXJncykgdGhyb3dzIEJhZEFyZ3MgewogICAgICAgIGhhbmRsZU9wdGlvbnMoQXJyYXlzLmFzTGlzdChhcmdzKSwgdHJ1ZSk7CiAgICB9CgogICAgcHJpdmF0ZSB2b2lkIGhhbmRsZU9wdGlvbnMoSXRlcmFibGU8U3RyaW5nPiBhcmdzLCBib29sZWFuIGFsbG93Q2xhc3NlcykgdGhyb3dzIEJhZEFyZ3MgewogICAgICAgIGlmIChsb2cgPT0gbnVsbCkgewogICAgICAgICAgICBsb2cgPSBnZXRQcmludFdyaXRlckZvclN0cmVhbShTeXN0ZW0ub3V0KTsKICAgICAgICAgICAgaWYgKGRpYWdub3N0aWNMaXN0ZW5lciA9PSBudWxsKQogICAgICAgICAgICAgIGRpYWdub3N0aWNMaXN0ZW5lciA9IGdldERpYWdub3N0aWNMaXN0ZW5lckZvclN0cmVhbShTeXN0ZW0uZXJyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBpZiAoZGlhZ25vc3RpY0xpc3RlbmVyID09IG51bGwpCiAgICAgICAgICAgICAgZGlhZ25vc3RpY0xpc3RlbmVyID0gZ2V0RGlhZ25vc3RpY0xpc3RlbmVyRm9yV3JpdGVyKGxvZyk7CiAgICAgICAgfQoKICAgICAgICBpZiAoZmlsZU1hbmFnZXIgPT0gbnVsbCkKICAgICAgICAgICAgZmlsZU1hbmFnZXIgPSBnZXREZWZhdWx0RmlsZU1hbmFnZXIoZGlhZ25vc3RpY0xpc3RlbmVyLCBsb2cpOwoKICAgICAgICBJdGVyYXRvcjxTdHJpbmc+IGl0ZXIgPSBleHBhbmRBdEFyZ3MoYXJncykuaXRlcmF0b3IoKTsKICAgICAgICBub0FyZ3MgPSAhaXRlci5oYXNOZXh0KCk7CgogICAgICAgIHdoaWxlIChpdGVyLmhhc05leHQoKSkgewogICAgICAgICAgICBTdHJpbmcgYXJnID0gaXRlci5uZXh0KCk7CiAgICAgICAgICAgIGlmIChhcmcuc3RhcnRzV2l0aCgiLSIpKQogICAgICAgICAgICAgICAgaGFuZGxlT3B0aW9uKGFyZywgaXRlcik7CiAgICAgICAgICAgIGVsc2UgaWYgKGFsbG93Q2xhc3NlcykgewogICAgICAgICAgICAgICAgaWYgKGNsYXNzZXMgPT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICBjbGFzc2VzID0gbmV3IEFycmF5TGlzdDw+KCk7CiAgICAgICAgICAgICAgICBjbGFzc2VzLmFkZChhcmcpOwogICAgICAgICAgICAgICAgd2hpbGUgKGl0ZXIuaGFzTmV4dCgpKQogICAgICAgICAgICAgICAgICAgIGNsYXNzZXMuYWRkKGl0ZXIubmV4dCgpKTsKICAgICAgICAgICAgfSBlbHNlCiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQmFkQXJncygiZXJyLnVua25vd24ub3B0aW9uIiwgYXJnKS5zaG93VXNhZ2UodHJ1ZSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoKGNsYXNzZXMgPT0gbnVsbCB8fCBjbGFzc2VzLnNpemUoKSA9PSAwKSAmJgogICAgICAgICAgICAgICAgIShub0FyZ3MgfHwgaGVscCB8fCB2ZXJzaW9uIHx8IGZ1bGxWZXJzaW9uKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgQmFkQXJncygiZXJyLm5vLmNsYXNzZXMuc3BlY2lmaWVkIik7CiAgICAgICAgfQoKICAgICAgICBpZiAoam5pICYmIGxsbmkpCiAgICAgICAgICAgIHRocm93IG5ldyBCYWRBcmdzKCJqbmkubGxuaS5taXhlZCIpOwoKICAgICAgICBpZiAob2RpciAhPSBudWxsICYmIG9maWxlICE9IG51bGwpCiAgICAgICAgICAgIHRocm93IG5ldyBCYWRBcmdzKCJkaXIuZmlsZS5taXhlZCIpOwogICAgfQoKICAgIHByaXZhdGUgdm9pZCBoYW5kbGVPcHRpb24oU3RyaW5nIG5hbWUsIEl0ZXJhdG9yPFN0cmluZz4gcmVzdCkgdGhyb3dzIEJhZEFyZ3MgewogICAgICAgIGZvciAoT3B0aW9uIG86IHJlY29nbml6ZWRPcHRpb25zKSB7CiAgICAgICAgICAgIGlmIChvLm1hdGNoZXMobmFtZSkpIHsKICAgICAgICAgICAgICAgIGlmIChvLmhhc0FyZykgewogICAgICAgICAgICAgICAgICAgIGlmIChyZXN0Lmhhc05leHQoKSkKICAgICAgICAgICAgICAgICAgICAgICAgby5wcm9jZXNzKHRoaXMsIG5hbWUsIHJlc3QubmV4dCgpKTsKICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBCYWRBcmdzKCJlcnIubWlzc2luZy5hcmciLCBuYW1lKS5zaG93VXNhZ2UodHJ1ZSk7CiAgICAgICAgICAgICAgICB9IGVsc2UKICAgICAgICAgICAgICAgICAgICBvLnByb2Nlc3ModGhpcywgbmFtZSwgbnVsbCk7CgogICAgICAgICAgICAgICAgaWYgKG8uaWdub3JlUmVzdCgpKSB7CiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHJlc3QuaGFzTmV4dCgpKQogICAgICAgICAgICAgICAgICAgICAgICByZXN0Lm5leHQoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKGZpbGVNYW5hZ2VyLmhhbmRsZU9wdGlvbihuYW1lLCByZXN0KSkKICAgICAgICAgICAgcmV0dXJuOwoKICAgICAgICB0aHJvdyBuZXcgQmFkQXJncygiZXJyLnVua25vd24ub3B0aW9uIiwgbmFtZSkuc2hvd1VzYWdlKHRydWUpOwogICAgfQoKICAgIHByaXZhdGUgSXRlcmFibGU8U3RyaW5nPiBleHBhbmRBdEFyZ3MoSXRlcmFibGU8U3RyaW5nPiBhcmdzKSB0aHJvd3MgQmFkQXJncyB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgTGlzdDxTdHJpbmc+IGwgPSBuZXcgQXJyYXlMaXN0PD4oKTsKICAgICAgICAgICAgZm9yIChTdHJpbmcgYXJnOiBhcmdzKSBsLmFkZChhcmcpOwogICAgICAgICAgICByZXR1cm4gQXJyYXlzLmFzTGlzdChDb21tYW5kTGluZS5wYXJzZShsLnRvQXJyYXkobmV3IFN0cmluZ1tsLnNpemUoKV0pKSk7CiAgICAgICAgfSBjYXRjaCAoRmlsZU5vdEZvdW5kRXhjZXB0aW9uIHwgTm9TdWNoRmlsZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBCYWRBcmdzKCJhdC5hcmdzLmZpbGUubm90LmZvdW5kIiwgZS5nZXRMb2NhbGl6ZWRNZXNzYWdlKCkpOwogICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEJhZEFyZ3MoImF0LmFyZ3MuaW8uZXhjZXB0aW9uIiwgZS5nZXRMb2NhbGl6ZWRNZXNzYWdlKCkpOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgQm9vbGVhbiBjYWxsKCkgewogICAgICAgIHJldHVybiBydW4oKTsKICAgIH0KCiAgICBwdWJsaWMgYm9vbGVhbiBydW4oKSB0aHJvd3MgVXRpbC5FeGl0IHsKCiAgICAgICAgaWYgKCFqYXZhY19leHRyYXMuY29udGFpbnMoIi1YRHN1cHByZXNzLXRvb2wtcmVtb3ZhbC1tZXNzYWdlIikpIHsKICAgICAgICAgICAgbG9nLnByaW50bG4oZ2V0TWVzc2FnZSgiamF2YWgubWlzYy5EZXByZWNhdGlvbiIpKTsKICAgICAgICB9CgogICAgICAgIFV0aWwgdXRpbCA9IG5ldyBVdGlsKGxvZywgZGlhZ25vc3RpY0xpc3RlbmVyKTsKCiAgICAgICAgaWYgKG5vQXJncyB8fCBoZWxwKSB7CiAgICAgICAgICAgIHNob3dIZWxwKCk7CiAgICAgICAgICAgIHJldHVybiBoZWxwOyAvLyB0cmVhdCBub0FyZ3MgYXMgYW4gZXJyb3IgZm9yIHB1cnBvc2VzIG9mIGV4aXQgY29kZQogICAgICAgIH0KCiAgICAgICAgaWYgKHZlcnNpb24gfHwgZnVsbFZlcnNpb24pIHsKICAgICAgICAgICAgc2hvd1ZlcnNpb24oZnVsbFZlcnNpb24pOwogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIHV0aWwudmVyYm9zZSA9IHZlcmJvc2U7CgogICAgICAgIEdlbiBnOwoKICAgICAgICBpZiAobGxuaSkKICAgICAgICAgICAgZyA9IG5ldyBMTE5JKGRvdWJsZUFsaWduLCB1dGlsKTsKICAgICAgICBlbHNlIHsKICAgICAgICAgICAgZyA9IG5ldyBKTkkodXRpbCk7CiAgICAgICAgfQoKICAgICAgICBpZiAob2ZpbGUgIT0gbnVsbCkgewogICAgICAgICAgICBpZiAoIShmaWxlTWFuYWdlciBpbnN0YW5jZW9mIFN0YW5kYXJkSmF2YUZpbGVNYW5hZ2VyKSkgewogICAgICAgICAgICAgICAgZGlhZ25vc3RpY0xpc3RlbmVyLnJlcG9ydChjcmVhdGVEaWFnbm9zdGljKCJlcnIuY2FudC51c2Uub3B0aW9uLmZvci5mbSIsICItbyIpKTsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBJdGVyYWJsZTw/IGV4dGVuZHMgSmF2YUZpbGVPYmplY3Q+IGl0ZXIgPQogICAgICAgICAgICAgICAgICAgICgoU3RhbmRhcmRKYXZhRmlsZU1hbmFnZXIpIGZpbGVNYW5hZ2VyKS5nZXRKYXZhRmlsZU9iamVjdHNGcm9tRmlsZXMoQ29sbGVjdGlvbnMuc2luZ2xldG9uKG9maWxlKSk7CiAgICAgICAgICAgIEphdmFGaWxlT2JqZWN0IGZvID0gaXRlci5pdGVyYXRvcigpLm5leHQoKTsKICAgICAgICAgICAgZy5zZXRPdXRGaWxlKGZvKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBpZiAob2RpciAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICBpZiAoIShmaWxlTWFuYWdlciBpbnN0YW5jZW9mIFN0YW5kYXJkSmF2YUZpbGVNYW5hZ2VyKSkgewogICAgICAgICAgICAgICAgICAgIGRpYWdub3N0aWNMaXN0ZW5lci5yZXBvcnQoY3JlYXRlRGlhZ25vc3RpYygiZXJyLmNhbnQudXNlLm9wdGlvbi5mb3IuZm0iLCAiLWQiKSk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmICghb2Rpci5leGlzdHMoKSkKICAgICAgICAgICAgICAgICAgICBpZiAoIW9kaXIubWtkaXJzKCkpCiAgICAgICAgICAgICAgICAgICAgICAgIHV0aWwuZXJyb3IoImNhbnQuY3JlYXRlLmRpciIsIG9kaXIudG9TdHJpbmcoKSk7CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgICgoU3RhbmRhcmRKYXZhRmlsZU1hbmFnZXIpIGZpbGVNYW5hZ2VyKS5zZXRMb2NhdGlvbihTdGFuZGFyZExvY2F0aW9uLkNMQVNTX09VVFBVVCwgQ29sbGVjdGlvbnMuc2luZ2xldG9uKG9kaXIpKTsKICAgICAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgICAgICAgICBPYmplY3QgbXNnID0gZS5nZXRMb2NhbGl6ZWRNZXNzYWdlKCk7CiAgICAgICAgICAgICAgICAgICAgaWYgKG1zZyA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIG1zZyA9IGU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGRpYWdub3N0aWNMaXN0ZW5lci5yZXBvcnQoY3JlYXRlRGlhZ25vc3RpYygiZXJyLmlvZXJyb3IiLCBvZGlyLCBtc2cpKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZy5zZXRGaWxlTWFuYWdlcihmaWxlTWFuYWdlcik7CiAgICAgICAgfQoKICAgICAgICAvKgogICAgICAgICAqIEZvcmNlIHNldCB0byBmYWxzZSB3aWxsIHR1cm4gb2ZmIHNtYXJ0cyBhYm91dCBjaGVja2luZyBmaWxlCiAgICAgICAgICogY29udGVudCBiZWZvcmUgd3JpdGluZy4KICAgICAgICAgKi8KICAgICAgICBnLnNldEZvcmNlKGZvcmNlKTsKCiAgICAgICAgaWYgKGZpbGVNYW5hZ2VyIGluc3RhbmNlb2YgSmF2YWhGaWxlTWFuYWdlcikKICAgICAgICAgICAgKChKYXZhaEZpbGVNYW5hZ2VyKSBmaWxlTWFuYWdlcikuc2V0U3ltYm9sRmlsZUVuYWJsZWQoZmFsc2UpOwoKICAgICAgICBKYXZhQ29tcGlsZXIgYyA9IFRvb2xQcm92aWRlci5nZXRTeXN0ZW1KYXZhQ29tcGlsZXIoKTsKICAgICAgICBMaXN0PFN0cmluZz4gb3B0cyA9IG5ldyBBcnJheUxpc3Q8PigpOwogICAgICAgIG9wdHMuYWRkKCItcHJvYzpvbmx5Iik7CiAgICAgICAgb3B0cy5hZGRBbGwoamF2YWNfZXh0cmFzKTsKCiAgICAgICAgQ29tcGlsYXRpb25UYXNrIHQ7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgdCA9IGMuZ2V0VGFzayhsb2csIGZpbGVNYW5hZ2VyLCBkaWFnbm9zdGljTGlzdGVuZXIsIG9wdHMsIGNsYXNzZXMsIG51bGwpOwogICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHV0aWwuZXJyb3IoImJhZC5hcmciLCBlLmdldE1lc3NhZ2UoKSk7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIEphdmFoUHJvY2Vzc29yIHAgPSBuZXcgSmF2YWhQcm9jZXNzb3IoZyk7CiAgICAgICAgdC5zZXRQcm9jZXNzb3JzKENvbGxlY3Rpb25zLnNpbmdsZXRvbihwKSk7CgogICAgICAgIGJvb2xlYW4gb2sgPSB0LmNhbGwoKTsKICAgICAgICBpZiAocC5leGl0ICE9IG51bGwpCiAgICAgICAgICAgIHRocm93IG5ldyBVdGlsLkV4aXQocC5leGl0KTsKICAgICAgICByZXR1cm4gb2s7CgogICAgfQoKICAgIHN0YXRpYyBTdGFuZGFyZEphdmFGaWxlTWFuYWdlciBnZXREZWZhdWx0RmlsZU1hbmFnZXIoZmluYWwgRGlhZ25vc3RpY0xpc3RlbmVyPD8gc3VwZXIgSmF2YUZpbGVPYmplY3Q+IGRsLCBQcmludFdyaXRlciBsb2cpIHsKICAgICAgICByZXR1cm4gSmF2YWhGaWxlTWFuYWdlci5jcmVhdGUoZGwsIGxvZyk7CiAgICB9CgogICAgcHJpdmF0ZSB2b2lkIHNob3dIZWxwKCkgewogICAgICAgIGxvZy5wcmludGxuKGdldE1lc3NhZ2UoIm1haW4udXNhZ2UiLCBwcm9nbmFtZSkpOwoKICAgICAgICBmb3IgKE9wdGlvbiBvOiByZWNvZ25pemVkT3B0aW9ucykgewogICAgICAgICAgICBpZiAoby5pc0hpZGRlbigpKQogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIFN0cmluZyBuYW1lID0gby5hbGlhc2VzWzBdLnN1YnN0cmluZygxKTsgLy8gdGhlcmUgbXVzdCBhbHdheXMgYmUgYXQgbGVhc3Qgb25lIG5hbWUKICAgICAgICAgICAgbG9nLnByaW50bG4oZ2V0TWVzc2FnZSgibWFpbi5vcHQuIiArIG5hbWUpKTsKICAgICAgICB9CgogICAgICAgIFN0cmluZ1tdIGZtT3B0aW9ucyA9IHsKICAgICAgICAgICAgIi0tbW9kdWxlLXBhdGgiLCAiLS1zeXN0ZW0iLAogICAgICAgICAgICAiLS1jbGFzcy1wYXRoIiwgIi1jbGFzc3BhdGgiLCAiLWNwIiwKICAgICAgICAgICAgIi1ib290Y2xhc3NwYXRoIgogICAgICAgIH07CgogICAgICAgIGZvciAoU3RyaW5nIG86IGZtT3B0aW9ucykgewogICAgICAgICAgICBpZiAoZmlsZU1hbmFnZXIuaXNTdXBwb3J0ZWRPcHRpb24obykgPT0gLTEpCiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgU3RyaW5nIG5hbWUgPSBvLnJlcGxhY2VBbGwoIl4tKyIsICIiKS5yZXBsYWNlQWxsKCItKyIsICJfIik7CiAgICAgICAgICAgIGxvZy5wcmludGxuKGdldE1lc3NhZ2UoIm1haW4ub3B0LiIgKyBuYW1lKSk7CiAgICAgICAgfQoKICAgICAgICBsb2cucHJpbnRsbihnZXRNZXNzYWdlKCJtYWluLnVzYWdlLmZvb3QiKSk7CiAgICB9CgogICAgcHJpdmF0ZSB2b2lkIHNob3dWZXJzaW9uKGJvb2xlYW4gZnVsbCkgewogICAgICAgIGxvZy5wcmludGxuKHZlcnNpb24oZnVsbCkpOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyB2ZXJzaW9uUkJOYW1lID0gImNvbS5zdW4udG9vbHMuamF2YWgucmVzb3VyY2VzLnZlcnNpb24iOwogICAgcHJpdmF0ZSBzdGF0aWMgUmVzb3VyY2VCdW5kbGUgdmVyc2lvblJCOwoKICAgIHByaXZhdGUgU3RyaW5nIHZlcnNpb24oYm9vbGVhbiBmdWxsKSB7CiAgICAgICAgU3RyaW5nIG1zZ0tleSA9IChmdWxsID8gImphdmFoLmZ1bGxWZXJzaW9uIiA6ICJqYXZhaC52ZXJzaW9uIik7CiAgICAgICAgU3RyaW5nIHZlcnNpb25LZXkgPSAoZnVsbCA/ICJmdWxsIiA6ICJyZWxlYXNlIik7CiAgICAgICAgLy8gdmVyc2lvbktleT1wcm9kdWN0OiAgbW0ubm4ub29bLW1pbGVzdG9uZV0KICAgICAgICAvLyB2ZXJzaW9uS2V5PWZ1bGw6ICAgICBtbS5tbS5vb1stbWlsZXN0b25lXS1idWlsZAogICAgICAgIGlmICh2ZXJzaW9uUkIgPT0gbnVsbCkgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgdmVyc2lvblJCID0gUmVzb3VyY2VCdW5kbGUuZ2V0QnVuZGxlKHZlcnNpb25SQk5hbWUpOwogICAgICAgICAgICB9IGNhdGNoIChNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24gZSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGdldE1lc3NhZ2UoInZlcnNpb24ucmVzb3VyY2UubWlzc2luZyIsIFN5c3RlbS5nZXRQcm9wZXJ0eSgiamF2YS52ZXJzaW9uIikpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICAgIHJldHVybiBnZXRNZXNzYWdlKG1zZ0tleSwgImphdmFoIiwgdmVyc2lvblJCLmdldFN0cmluZyh2ZXJzaW9uS2V5KSk7CiAgICAgICAgfQogICAgICAgIGNhdGNoIChNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24gZSkgewogICAgICAgICAgICByZXR1cm4gZ2V0TWVzc2FnZSgidmVyc2lvbi51bmtub3duIiwgU3lzdGVtLmdldFByb3BlcnR5KCJqYXZhLnZlcnNpb24iKSk7CiAgICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgRGlhZ25vc3RpYzxKYXZhRmlsZU9iamVjdD4gY3JlYXRlRGlhZ25vc3RpYyhmaW5hbCBTdHJpbmcga2V5LCBmaW5hbCBPYmplY3QuLi4gYXJncykgewogICAgICAgIHJldHVybiBuZXcgRGlhZ25vc3RpYzxKYXZhRmlsZU9iamVjdD4oKSB7CiAgICAgICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSKQogICAgICAgICAgICBwdWJsaWMgS2luZCBnZXRLaW5kKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIERpYWdub3N0aWMuS2luZC5FUlJPUjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICAgICAgICAgIHB1YmxpYyBKYXZhRmlsZU9iamVjdCBnZXRTb3VyY2UoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICAgICAgICAgIHB1YmxpYyBsb25nIGdldFBvc2l0aW9uKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIERpYWdub3N0aWMuTk9QT1M7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSKQogICAgICAgICAgICBwdWJsaWMgbG9uZyBnZXRTdGFydFBvc2l0aW9uKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIERpYWdub3N0aWMuTk9QT1M7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSKQogICAgICAgICAgICBwdWJsaWMgbG9uZyBnZXRFbmRQb3NpdGlvbigpIHsKICAgICAgICAgICAgICAgIHJldHVybiBEaWFnbm9zdGljLk5PUE9TOwogICAgICAgICAgICB9CgogICAgICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgICAgICAgICAgcHVibGljIGxvbmcgZ2V0TGluZU51bWJlcigpIHsKICAgICAgICAgICAgICAgIHJldHVybiBEaWFnbm9zdGljLk5PUE9TOwogICAgICAgICAgICB9CgogICAgICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgICAgICAgICAgcHVibGljIGxvbmcgZ2V0Q29sdW1uTnVtYmVyKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIERpYWdub3N0aWMuTk9QT1M7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSKQogICAgICAgICAgICBwdWJsaWMgU3RyaW5nIGdldENvZGUoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4ga2V5OwogICAgICAgICAgICB9CgogICAgICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgICAgICAgICAgcHVibGljIFN0cmluZyBnZXRNZXNzYWdlKExvY2FsZSBsb2NhbGUpIHsKICAgICAgICAgICAgICAgIHJldHVybiBKYXZhaFRhc2sudGhpcy5nZXRNZXNzYWdlKGxvY2FsZSwga2V5LCBhcmdzKTsKICAgICAgICAgICAgfQoKICAgICAgICB9OwogICAgfQoKICAgIHByaXZhdGUgU3RyaW5nIGdldE1lc3NhZ2UoU3RyaW5nIGtleSwgT2JqZWN0Li4uIGFyZ3MpIHsKICAgICAgICByZXR1cm4gZ2V0TWVzc2FnZSh0YXNrX2xvY2FsZSwga2V5LCBhcmdzKTsKICAgIH0KCiAgICBwcml2YXRlIFN0cmluZyBnZXRNZXNzYWdlKExvY2FsZSBsb2NhbGUsIFN0cmluZyBrZXksIE9iamVjdC4uLiBhcmdzKSB7CiAgICAgICAgaWYgKGJ1bmRsZXMgPT0gbnVsbCkgewogICAgICAgICAgICAvLyBjb3VsZCBtYWtlIHRoaXMgYSBIYXNoTWFwPExvY2FsZSxTb2Z0UmVmZXJlbmNlPFJlc291cmNlQnVuZGxlPj4KICAgICAgICAgICAgLy8gYW5kIGZvciBlZmZpY2llbmN5LCBrZWVwIGEgaGFyZCByZWZlcmVuY2UgdG8gdGhlIGJ1bmRsZSBmb3IgdGhlIHRhc2sKICAgICAgICAgICAgLy8gbG9jYWxlCiAgICAgICAgICAgIGJ1bmRsZXMgPSBuZXcgSGFzaE1hcDw+KCk7CiAgICAgICAgfQoKICAgICAgICBpZiAobG9jYWxlID09IG51bGwpCiAgICAgICAgICAgIGxvY2FsZSA9IExvY2FsZS5nZXREZWZhdWx0KCk7CgogICAgICAgIFJlc291cmNlQnVuZGxlIGIgPSBidW5kbGVzLmdldChsb2NhbGUpOwogICAgICAgIGlmIChiID09IG51bGwpIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIGIgPSBSZXNvdXJjZUJ1bmRsZS5nZXRCdW5kbGUoImNvbS5zdW4udG9vbHMuamF2YWgucmVzb3VyY2VzLmwxMG4iLCBsb2NhbGUpOwogICAgICAgICAgICAgICAgYnVuZGxlcy5wdXQobG9jYWxlLCBiKTsKICAgICAgICAgICAgfSBjYXRjaCAoTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKCJDYW5ub3QgZmluZCBqYXZhaCByZXNvdXJjZSBidW5kbGUgZm9yIGxvY2FsZSAiICsgbG9jYWxlLCBlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgcmV0dXJuIE1lc3NhZ2VGb3JtYXQuZm9ybWF0KGIuZ2V0U3RyaW5nKGtleSksIGFyZ3MpOwogICAgICAgIH0gY2F0Y2ggKE1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHJldHVybiBrZXk7CiAgICAgICAgICAgIC8vdGhyb3cgbmV3IEludGVybmFsRXJyb3IoZSwga2V5KTsKICAgICAgICB9CiAgICB9CgogICAgRmlsZSBvZmlsZTsKICAgIEZpbGUgb2RpcjsKICAgIFN0cmluZyBib290Y3A7CiAgICBTdHJpbmcgdXNlcmNwOwogICAgTGlzdDxTdHJpbmc+IGNsYXNzZXM7CiAgICBib29sZWFuIHZlcmJvc2U7CiAgICBib29sZWFuIG5vQXJnczsKICAgIGJvb2xlYW4gaGVscDsKICAgIGJvb2xlYW4gdHJhY2U7CiAgICBib29sZWFuIHZlcnNpb247CiAgICBib29sZWFuIGZ1bGxWZXJzaW9uOwogICAgYm9vbGVhbiBqbmk7CiAgICBib29sZWFuIGxsbmk7CiAgICBib29sZWFuIGRvdWJsZUFsaWduOwogICAgYm9vbGVhbiBmb3JjZTsKICAgIFNldDxTdHJpbmc+IGphdmFjX2V4dHJhcyA9IG5ldyBMaW5rZWRIYXNoU2V0PD4oKTsKCiAgICBQcmludFdyaXRlciBsb2c7CiAgICBKYXZhRmlsZU1hbmFnZXIgZmlsZU1hbmFnZXI7CiAgICBEaWFnbm9zdGljTGlzdGVuZXI8PyBzdXBlciBKYXZhRmlsZU9iamVjdD4gZGlhZ25vc3RpY0xpc3RlbmVyOwogICAgTG9jYWxlIHRhc2tfbG9jYWxlOwogICAgTWFwPExvY2FsZSwgUmVzb3VyY2VCdW5kbGU+IGJ1bmRsZXM7CgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIHByb2duYW1lID0gImphdmFoIjsKCiAgICBAU3VwcG9ydGVkQW5ub3RhdGlvblR5cGVzKCIqIikKICAgIGNsYXNzIEphdmFoUHJvY2Vzc29yIGV4dGVuZHMgQWJzdHJhY3RQcm9jZXNzb3IgewogICAgICAgIHByaXZhdGUgTWVzc2FnZXIgbWVzc2FnZXI7CgogICAgICAgIEphdmFoUHJvY2Vzc29yKEdlbiBnKSB7CiAgICAgICAgICAgIHRoaXMuZyA9IGc7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQU5OT1RBVElPTl9QUk9DRVNTSU5HKQogICAgICAgIHB1YmxpYyBTb3VyY2VWZXJzaW9uIGdldFN1cHBvcnRlZFNvdXJjZVZlcnNpb24oKSB7CiAgICAgICAgICAgIC8vIHNpbmNlIHRoaXMgaXMgY28tYnVuZGxlZCB3aXRoIGphdmFjLCB3ZSBjYW4gYXNzdW1lIGl0IHN1cHBvcnRzCiAgICAgICAgICAgIC8vIHRoZSBsYXRlc3Qgc291cmNlIHZlcnNpb24KICAgICAgICAgICAgcmV0dXJuIFNvdXJjZVZlcnNpb24ubGF0ZXN0KCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQU5OT1RBVElPTl9QUk9DRVNTSU5HKQogICAgICAgIHB1YmxpYyB2b2lkIGluaXQoUHJvY2Vzc2luZ0Vudmlyb25tZW50IHBFbnYpIHsKICAgICAgICAgICAgc3VwZXIuaW5pdChwRW52KTsKICAgICAgICAgICAgbWVzc2FnZXIgID0gcHJvY2Vzc2luZ0Vudi5nZXRNZXNzYWdlcigpOwogICAgICAgIH0KCiAgICAgICAgQERlZmluZWRCeShBcGkuQU5OT1RBVElPTl9QUk9DRVNTSU5HKQogICAgICAgIHB1YmxpYyBib29sZWFuIHByb2Nlc3MoU2V0PD8gZXh0ZW5kcyBUeXBlRWxlbWVudD4gYW5ub3RhdGlvbnMsIFJvdW5kRW52aXJvbm1lbnQgcm91bmRFbnYpIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIFNldDxUeXBlRWxlbWVudD4gY2xhc3NlcyA9IGdldEFsbENsYXNzZXMoRWxlbWVudEZpbHRlci50eXBlc0luKHJvdW5kRW52LmdldFJvb3RFbGVtZW50cygpKSk7CiAgICAgICAgICAgICAgICBpZiAoY2xhc3Nlcy5zaXplKCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgY2hlY2tNZXRob2RQYXJhbWV0ZXJzKGNsYXNzZXMpOwogICAgICAgICAgICAgICAgICAgIGcuc2V0UHJvY2Vzc2luZ0Vudmlyb25tZW50KHByb2Nlc3NpbmdFbnYpOwogICAgICAgICAgICAgICAgICAgIGcuc2V0Q2xhc3NlcyhjbGFzc2VzKTsKICAgICAgICAgICAgICAgICAgICBnLnJ1bigpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGNhdGNoIChDb21wbGV0aW9uRmFpbHVyZSBjZikgewogICAgICAgICAgICAgICAgbWVzc2FnZXIucHJpbnRNZXNzYWdlKEVSUk9SLCBnZXRNZXNzYWdlKCJjbGFzcy5ub3QuZm91bmQiLCBjZi5zeW0uZ2V0UXVhbGlmaWVkTmFtZSgpLnRvU3RyaW5nKCkpKTsKICAgICAgICAgICAgfSBjYXRjaCAoQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiBjbmZlKSB7CiAgICAgICAgICAgICAgICBtZXNzYWdlci5wcmludE1lc3NhZ2UoRVJST1IsIGdldE1lc3NhZ2UoImNsYXNzLm5vdC5mb3VuZCIsIGNuZmUuZ2V0TWVzc2FnZSgpKSk7CiAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGlvZSkgewogICAgICAgICAgICAgICAgbWVzc2FnZXIucHJpbnRNZXNzYWdlKEVSUk9SLCBnZXRNZXNzYWdlKCJpby5leGNlcHRpb24iLCBpb2UuZ2V0TWVzc2FnZSgpKSk7CiAgICAgICAgICAgIH0gY2F0Y2ggKFV0aWwuRXhpdCBlKSB7CiAgICAgICAgICAgICAgICBleGl0ID0gZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIFNldDxUeXBlRWxlbWVudD4gZ2V0QWxsQ2xhc3NlcyhTZXQ8PyBleHRlbmRzIFR5cGVFbGVtZW50PiBjbGFzc2VzKSB7CiAgICAgICAgICAgIFNldDxUeXBlRWxlbWVudD4gYWxsQ2xhc3NlcyA9IG5ldyBMaW5rZWRIYXNoU2V0PD4oKTsKICAgICAgICAgICAgZ2V0QWxsQ2xhc3NlczAoY2xhc3NlcywgYWxsQ2xhc3Nlcyk7CiAgICAgICAgICAgIHJldHVybiBhbGxDbGFzc2VzOwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSB2b2lkIGdldEFsbENsYXNzZXMwKEl0ZXJhYmxlPD8gZXh0ZW5kcyBUeXBlRWxlbWVudD4gY2xhc3NlcywgU2V0PFR5cGVFbGVtZW50PiBhbGxDbGFzc2VzKSB7CiAgICAgICAgICAgIGZvciAoVHlwZUVsZW1lbnQgYzogY2xhc3NlcykgewogICAgICAgICAgICAgICAgYWxsQ2xhc3Nlcy5hZGQoYyk7CiAgICAgICAgICAgICAgICBnZXRBbGxDbGFzc2VzMChFbGVtZW50RmlsdGVyLnR5cGVzSW4oYy5nZXRFbmNsb3NlZEVsZW1lbnRzKCkpLCBhbGxDbGFzc2VzKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gNDk0MjIzMjoKICAgICAgICAvLyBjaGVjayB0aGF0IGNsYXNzZXMgZXhpc3QgZm9yIGFsbCB0aGUgcGFyYW1ldGVycyBvZiBuYXRpdmUgbWV0aG9kcwogICAgICAgIHByaXZhdGUgdm9pZCBjaGVja01ldGhvZFBhcmFtZXRlcnMoU2V0PFR5cGVFbGVtZW50PiBjbGFzc2VzKSB7CiAgICAgICAgICAgIFR5cGVzIHR5cGVzID0gcHJvY2Vzc2luZ0Vudi5nZXRUeXBlVXRpbHMoKTsKICAgICAgICAgICAgZm9yIChUeXBlRWxlbWVudCB0ZTogY2xhc3NlcykgewogICAgICAgICAgICAgICAgZm9yIChFeGVjdXRhYmxlRWxlbWVudCBlZTogRWxlbWVudEZpbHRlci5tZXRob2RzSW4odGUuZ2V0RW5jbG9zZWRFbGVtZW50cygpKSkgewogICAgICAgICAgICAgICAgICAgIGZvciAoVmFyaWFibGVFbGVtZW50IHZlOiBlZS5nZXRQYXJhbWV0ZXJzKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgVHlwZU1pcnJvciB0bSA9IHZlLmFzVHlwZSgpOwogICAgICAgICAgICAgICAgICAgICAgICBjaGVja01ldGhvZFBhcmFtZXRlcnNWaXNpdG9yLnZpc2l0KHRtLCB0eXBlcyk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIFR5cGVWaXNpdG9yPFZvaWQsVHlwZXM+IGNoZWNrTWV0aG9kUGFyYW1ldGVyc1Zpc2l0b3IgPQogICAgICAgICAgICAgICAgbmV3IFNpbXBsZVR5cGVWaXNpdG9yOTxWb2lkLFR5cGVzPigpIHsKICAgICAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgICAgICBwdWJsaWMgVm9pZCB2aXNpdEFycmF5KEFycmF5VHlwZSB0LCBUeXBlcyB0eXBlcykgewogICAgICAgICAgICAgICAgdmlzaXQodC5nZXRDb21wb25lbnRUeXBlKCksIHR5cGVzKTsKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICB9CiAgICAgICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgICAgICAgICAgcHVibGljIFZvaWQgdmlzaXREZWNsYXJlZChEZWNsYXJlZFR5cGUgdCwgVHlwZXMgdHlwZXMpIHsKICAgICAgICAgICAgICAgIHQuYXNFbGVtZW50KCkuZ2V0S2luZCgpOyAvLyBlbnN1cmUgY2xhc3MgZXhpc3RzCiAgICAgICAgICAgICAgICBmb3IgKFR5cGVNaXJyb3Igc3Q6IHR5cGVzLmRpcmVjdFN1cGVydHlwZXModCkpCiAgICAgICAgICAgICAgICAgICAgdmlzaXQoc3QsIHR5cGVzKTsKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICB9CiAgICAgICAgfTsKCiAgICAgICAgcHJpdmF0ZSBHZW4gZzsKICAgICAgICBwcml2YXRlIFV0aWwuRXhpdCBleGl0OwogICAgfQp9ClBLAwQKAAAIAAAGO6lKHe4JshUJAAAVCQAAKQAAAGNvbS9zdW4vdG9vbHMvamF2YWgvSmF2YWhGaWxlTWFuYWdlci5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDA3LCAyMDE2LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuamF2YWg7CgppbXBvcnQgamF2YS5pby5QcmludFdyaXRlcjsKaW1wb3J0IGphdmEubmlvLmNoYXJzZXQuQ2hhcnNldDsKaW1wb3J0IGphdmF4LnRvb2xzLkRpYWdub3N0aWNMaXN0ZW5lcjsKaW1wb3J0IGphdmF4LnRvb2xzLkphdmFGaWxlT2JqZWN0OwoKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuZmlsZS5KYXZhY0ZpbGVNYW5hZ2VyOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkNvbnRleHQ7CgovKioKICogIGphdmFoJ3MgaW1wbGVtZW50YXRpb24gb2YgSmF2YUZpbGVNYW5hZ2VyLgogKgogKiAgPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24gcmlzay4KICogIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yCiAqICBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+CiAqLwpjbGFzcyBKYXZhaEZpbGVNYW5hZ2VyIGV4dGVuZHMgSmF2YWNGaWxlTWFuYWdlciB7CiAgICBwcml2YXRlIEphdmFoRmlsZU1hbmFnZXIoQ29udGV4dCBjb250ZXh0LCBDaGFyc2V0IGNoYXJzZXQpIHsKICAgICAgICBzdXBlcihjb250ZXh0LCB0cnVlLCBjaGFyc2V0KTsKICAgICAgICBzZXRTeW1ib2xGaWxlRW5hYmxlZChmYWxzZSk7CiAgICB9CgogICAgc3RhdGljIEphdmFoRmlsZU1hbmFnZXIgY3JlYXRlKGZpbmFsIERpYWdub3N0aWNMaXN0ZW5lcjw/IHN1cGVyIEphdmFGaWxlT2JqZWN0PiBkbCwgUHJpbnRXcml0ZXIgbG9nKSB7CiAgICAgICAgQ29udGV4dCBqYXZhY19jb250ZXh0ID0gbmV3IENvbnRleHQoKTsKCiAgICAgICAgaWYgKGRsICE9IG51bGwpCiAgICAgICAgICAgIGphdmFjX2NvbnRleHQucHV0KERpYWdub3N0aWNMaXN0ZW5lci5jbGFzcywgZGwpOwogICAgICAgIGphdmFjX2NvbnRleHQucHV0KGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5Mb2cuZXJyS2V5LCBsb2cpOwoKICAgICAgICByZXR1cm4gbmV3IEphdmFoRmlsZU1hbmFnZXIoamF2YWNfY29udGV4dCwgbnVsbCk7CiAgICB9Cn0KUEsDBAoAAAgAAAY7qUpa/74fGBsAABgbAAAfAAAAY29tL3N1bi90b29scy9qYXZhaC9NYW5nbGUuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwMiwgMjAxMiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLmphdmFoOwoKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC5FeGVjdXRhYmxlRWxlbWVudDsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC5UeXBlRWxlbWVudDsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC5WYXJpYWJsZUVsZW1lbnQ7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLnV0aWwuRWxlbWVudHM7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLnV0aWwuVHlwZXM7CgovKioKICogQSB1dGlsaXR5IGZvciBtYW5nbGluZyBqYXZhIGlkZW50aWZpZXJzIGludG8gQyBuYW1lcy4gIFNob3VsZCBtYWtlCiAqIHRoaXMgbW9yZSBmaW5lIGdyYWluZWQgYW5kIGRpc3RyaWJ1dGUgdGhlIGZ1bmN0aW9uYWxpdHkgdG8gdGhlCiAqIGdlbmVyYXRvcnMuCiAqCiAqIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24KICogcmlzay4gIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlCiAqIG9yIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj48L3A+CiAqCiAqIEBhdXRob3IgIFN1Y2hldGEgRGFtYmFsa2FyKFJldmlzZWQpCiAqLwpwdWJsaWMgY2xhc3MgTWFuZ2xlIHsKCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIFR5cGUgewogICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENMQVNTICAgICAgICAgICAgPSAxOwogICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEU1RVQiAgICAgICAgPSAyOwogICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEICAgICAgICAgICAgPSAzOwogICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEpOSSAgICAgICAgICAgICAgPSA0OwogICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNJR05BVFVSRSAgICAgICAgPSA1OwogICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1FVEhPRF9KREtfMSAgICAgPSA2OwogICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1FVEhPRF9KTklfU0hPUlQgPSA3OwogICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1FVEhPRF9KTklfTE9ORyAgPSA4OwogICAgfQoKICAgIHByaXZhdGUgRWxlbWVudHMgZWxlbXM7CiAgICBwcml2YXRlIFR5cGVzIHR5cGVzOwoKICAgIE1hbmdsZShFbGVtZW50cyBlbGVtcywgVHlwZXMgdHlwZXMpIHsKICAgICAgICB0aGlzLmVsZW1zID0gZWxlbXM7CiAgICAgICAgdGhpcy50eXBlcyA9IHR5cGVzOwogICAgfQoKICAgIHB1YmxpYyBmaW5hbCBTdHJpbmcgbWFuZ2xlKENoYXJTZXF1ZW5jZSBuYW1lLCBpbnQgbXR5cGUpIHsKICAgICAgICBTdHJpbmdCdWlsZGVyIHJlc3VsdCA9IG5ldyBTdHJpbmdCdWlsZGVyKDEwMCk7CiAgICAgICAgaW50IGxlbmd0aCA9IG5hbWUubGVuZ3RoKCk7CgogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgY2hhciBjaCA9IG5hbWUuY2hhckF0KGkpOwogICAgICAgICAgICBpZiAoaXNhbG51bShjaCkpIHsKICAgICAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoY2gpOwogICAgICAgICAgICB9IGVsc2UgaWYgKChjaCA9PSAnLicpICYmCiAgICAgICAgICAgICAgICAgICAgICAgbXR5cGUgPT0gTWFuZ2xlLlR5cGUuQ0xBU1MpIHsKICAgICAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoJ18nKTsKICAgICAgICAgICAgfSBlbHNlIGlmICgoIGNoID09ICckJykgJiYKICAgICAgICAgICAgICAgICAgICAgICBtdHlwZSA9PSBNYW5nbGUuVHlwZS5DTEFTUykgewogICAgICAgICAgICAgICAgcmVzdWx0LmFwcGVuZCgnXycpOwogICAgICAgICAgICAgICAgcmVzdWx0LmFwcGVuZCgnXycpOwogICAgICAgICAgICB9IGVsc2UgaWYgKGNoID09ICdfJyAmJiBtdHlwZSA9PSBNYW5nbGUuVHlwZS5GSUVMRFNUVUIpIHsKICAgICAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoJ18nKTsKICAgICAgICAgICAgfSBlbHNlIGlmIChjaCA9PSAnXycgJiYgbXR5cGUgPT0gTWFuZ2xlLlR5cGUuQ0xBU1MpIHsKICAgICAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoJ18nKTsKICAgICAgICAgICAgfSBlbHNlIGlmIChtdHlwZSA9PSBNYW5nbGUuVHlwZS5KTkkpIHsKICAgICAgICAgICAgICAgIFN0cmluZyBlc2MgPSBudWxsOwogICAgICAgICAgICAgICAgaWYgKGNoID09ICdfJykKICAgICAgICAgICAgICAgICAgICBlc2MgPSAiXzEiOwogICAgICAgICAgICAgICAgZWxzZSBpZiAoY2ggPT0gJy4nKQogICAgICAgICAgICAgICAgICAgIGVzYyA9ICJfIjsKICAgICAgICAgICAgICAgIGVsc2UgaWYgKGNoID09ICc7JykKICAgICAgICAgICAgICAgICAgICBlc2MgPSAiXzIiOwogICAgICAgICAgICAgICAgZWxzZSBpZiAoY2ggPT0gJ1snKQogICAgICAgICAgICAgICAgICAgIGVzYyA9ICJfMyI7CiAgICAgICAgICAgICAgICBpZiAoZXNjICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICByZXN1bHQuYXBwZW5kKGVzYyk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQobWFuZ2xlQ2hhcihjaCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgaWYgKG10eXBlID09IE1hbmdsZS5UeXBlLlNJR05BVFVSRSkgewogICAgICAgICAgICAgICAgaWYgKGlzcHJpbnQoY2gpKSB7CiAgICAgICAgICAgICAgICAgICAgcmVzdWx0LmFwcGVuZChjaCk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQobWFuZ2xlQ2hhcihjaCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcmVzdWx0LmFwcGVuZChtYW5nbGVDaGFyKGNoKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiByZXN1bHQudG9TdHJpbmcoKTsKICAgIH0KCiAgICBwdWJsaWMgU3RyaW5nIG1hbmdsZU1ldGhvZChFeGVjdXRhYmxlRWxlbWVudCBtZXRob2QsIFR5cGVFbGVtZW50IGNsYXp6LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBtdHlwZSkgdGhyb3dzIFR5cGVTaWduYXR1cmUuU2lnbmF0dXJlRXhjZXB0aW9uIHsKICAgICAgICBTdHJpbmdCdWlsZGVyIHJlc3VsdCA9IG5ldyBTdHJpbmdCdWlsZGVyKDEwMCk7CiAgICAgICAgcmVzdWx0LmFwcGVuZCgiSmF2YV8iKTsKCiAgICAgICAgaWYgKG10eXBlID09IE1hbmdsZS5UeXBlLk1FVEhPRF9KREtfMSkgewogICAgICAgICAgICByZXN1bHQuYXBwZW5kKG1hbmdsZShjbGF6ei5nZXRRdWFsaWZpZWROYW1lKCksIE1hbmdsZS5UeXBlLkNMQVNTKSk7CiAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoJ18nKTsKICAgICAgICAgICAgcmVzdWx0LmFwcGVuZChtYW5nbGUobWV0aG9kLmdldFNpbXBsZU5hbWUoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWFuZ2xlLlR5cGUuRklFTEQpKTsKICAgICAgICAgICAgcmVzdWx0LmFwcGVuZCgiX3N0dWIiKTsKICAgICAgICAgICAgcmV0dXJuIHJlc3VsdC50b1N0cmluZygpOwogICAgICAgIH0KCiAgICAgICAgLyogSk5JICovCiAgICAgICAgcmVzdWx0LmFwcGVuZChtYW5nbGUoZ2V0SW5uZXJRdWFsaWZpZWROYW1lKGNsYXp6KSwgTWFuZ2xlLlR5cGUuSk5JKSk7CiAgICAgICAgcmVzdWx0LmFwcGVuZCgnXycpOwogICAgICAgIHJlc3VsdC5hcHBlbmQobWFuZ2xlKG1ldGhvZC5nZXRTaW1wbGVOYW1lKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWFuZ2xlLlR5cGUuSk5JKSk7CiAgICAgICAgaWYgKG10eXBlID09IE1hbmdsZS5UeXBlLk1FVEhPRF9KTklfTE9ORykgewogICAgICAgICAgICByZXN1bHQuYXBwZW5kKCJfXyIpOwogICAgICAgICAgICBTdHJpbmcgdHlwZXNpZyA9IHNpZ25hdHVyZShtZXRob2QpOwogICAgICAgICAgICBUeXBlU2lnbmF0dXJlIG5ld1R5cGVTaWcgPSBuZXcgVHlwZVNpZ25hdHVyZShlbGVtcyk7CiAgICAgICAgICAgIFN0cmluZyBzaWcgPSBuZXdUeXBlU2lnLmdldFR5cGVTaWduYXR1cmUodHlwZXNpZywgIG1ldGhvZC5nZXRSZXR1cm5UeXBlKCkpOwogICAgICAgICAgICBzaWcgPSBzaWcuc3Vic3RyaW5nKDEpOwogICAgICAgICAgICBzaWcgPSBzaWcuc3Vic3RyaW5nKDAsIHNpZy5sYXN0SW5kZXhPZignKScpKTsKICAgICAgICAgICAgc2lnID0gc2lnLnJlcGxhY2UoJy8nLCAnLicpOwogICAgICAgICAgICByZXN1bHQuYXBwZW5kKG1hbmdsZShzaWcsIE1hbmdsZS5UeXBlLkpOSSkpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHJlc3VsdC50b1N0cmluZygpOwogICAgfQogICAgLy93aGVyZQogICAgICAgIHByaXZhdGUgU3RyaW5nIGdldElubmVyUXVhbGlmaWVkTmFtZShUeXBlRWxlbWVudCBjbGF6eikgewogICAgICAgICAgICByZXR1cm4gZWxlbXMuZ2V0QmluYXJ5TmFtZShjbGF6eikudG9TdHJpbmcoKTsKICAgICAgICB9CgogICAgcHVibGljIGZpbmFsIFN0cmluZyBtYW5nbGVDaGFyKGNoYXIgY2gpIHsKICAgICAgICBTdHJpbmcgcyA9IEludGVnZXIudG9IZXhTdHJpbmcoY2gpOwogICAgICAgIGludCBuemVyb3MgPSA1IC0gcy5sZW5ndGgoKTsKICAgICAgICBjaGFyW10gcmVzdWx0ID0gbmV3IGNoYXJbNl07CiAgICAgICAgcmVzdWx0WzBdID0gJ18nOwogICAgICAgIGZvciAoaW50IGkgPSAxOyBpIDw9IG56ZXJvczsgaSsrKQogICAgICAgICAgICByZXN1bHRbaV0gPSAnMCc7CiAgICAgICAgZm9yIChpbnQgaSA9IG56ZXJvcysxLCBqID0gMDsgaSA8IDY7IGkrKywgaisrKQogICAgICAgICAgICByZXN1bHRbaV0gPSBzLmNoYXJBdChqKTsKICAgICAgICByZXR1cm4gbmV3IFN0cmluZyhyZXN1bHQpOwogICAgfQoKICAgIC8vIFdhcm5pbmc6IGR1cGxpY2F0ZWQgaW4gR2VuCiAgICBwcml2YXRlIFN0cmluZyBzaWduYXR1cmUoRXhlY3V0YWJsZUVsZW1lbnQgZSkgewogICAgICAgIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigpOwogICAgICAgIFN0cmluZyBzZXAgPSAiKCI7CiAgICAgICAgZm9yIChWYXJpYWJsZUVsZW1lbnQgcDogZS5nZXRQYXJhbWV0ZXJzKCkpIHsKICAgICAgICAgICAgc2IuYXBwZW5kKHNlcCk7CiAgICAgICAgICAgIHNiLmFwcGVuZCh0eXBlcy5lcmFzdXJlKHAuYXNUeXBlKCkpLnRvU3RyaW5nKCkpOwogICAgICAgICAgICBzZXAgPSAiLCI7CiAgICAgICAgfQogICAgICAgIHNiLmFwcGVuZCgiKSIpOwogICAgICAgIHJldHVybiBzYi50b1N0cmluZygpOwogICAgfQoKICAgIC8qIFdhcm5pbmc6IEludGVudGlvbmFsIEFTQ0lJIG9wZXJhdGlvbi4gKi8KICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gaXNhbG51bShjaGFyIGNoKSB7CiAgICAgICAgcmV0dXJuIGNoIDw9IDB4N2YgJiYgLyogcXVpY2sgdGVzdCAqLwogICAgICAgICAgICAoKGNoID49ICdBJyAmJiBjaCA8PSAnWicpIHx8CiAgICAgICAgICAgICAoY2ggPj0gJ2EnICYmIGNoIDw9ICd6JykgfHwKICAgICAgICAgICAgIChjaCA+PSAnMCcgJiYgY2ggPD0gJzknKSk7CiAgICB9CgogICAgLyogV2FybmluZzogSW50ZW50aW9uYWwgQVNDSUkgb3BlcmF0aW9uLiAqLwogICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBpc3ByaW50KGNoYXIgY2gpIHsKICAgICAgICByZXR1cm4gY2ggPj0gMzIgJiYgY2ggPD0gMTI2OwogICAgfQp9ClBLAwQKAAAIAADSfU1K6vbThHYdAAB2HQAAHAAAAGNvbS9zdW4vdG9vbHMvamF2YWgvSk5JLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDIsIDIwMTAsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhaDsKCmltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKaW1wb3J0IGphdmEuaW8uUHJpbnRXcml0ZXI7CmltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OwppbXBvcnQgamF2YS51dGlsLkxpc3Q7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuRWxlbWVudDsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC5FeGVjdXRhYmxlRWxlbWVudDsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC5Nb2RpZmllcjsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC5UeXBlRWxlbWVudDsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC5WYXJpYWJsZUVsZW1lbnQ7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLnR5cGUuQXJyYXlUeXBlOwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC50eXBlLlR5cGVNaXJyb3I7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLnV0aWwuRWxlbWVudEZpbHRlcjsKCgovKioKICogSGVhZGVyIGZpbGUgZ2VuZXJhdG9yIGZvciBKTkkuCiAqCiAqIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24KICogcmlzay4gIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlCiAqIG9yIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj48L3A+CiAqCiAqIEBhdXRob3IgIFN1Y2hldGEgRGFtYmFsa2FyKFJldmlzZWQpCiAqLwpwdWJsaWMgY2xhc3MgSk5JIGV4dGVuZHMgR2VuIHsKICAgIEpOSShVdGlsIHV0aWwpIHsKICAgICAgICBzdXBlcih1dGlsKTsKICAgIH0KCiAgICBwdWJsaWMgU3RyaW5nIGdldEluY2x1ZGVzKCkgewogICAgICAgIHJldHVybiAiI2luY2x1ZGUgPGpuaS5oPiI7CiAgICB9CgogICAgcHVibGljIHZvaWQgd3JpdGUoT3V0cHV0U3RyZWFtIG8sIFR5cGVFbGVtZW50IGNsYXp6KSB0aHJvd3MgVXRpbC5FeGl0IHsKICAgICAgICB0cnkgewogICAgICAgICAgICBTdHJpbmcgY25hbWUgPSBtYW5nbGVyLm1hbmdsZShjbGF6ei5nZXRRdWFsaWZpZWROYW1lKCksIE1hbmdsZS5UeXBlLkNMQVNTKTsKICAgICAgICAgICAgUHJpbnRXcml0ZXIgcHcgPSB3cmFwV3JpdGVyKG8pOwogICAgICAgICAgICBwdy5wcmludGxuKGd1YXJkQmVnaW4oY25hbWUpKTsKICAgICAgICAgICAgcHcucHJpbnRsbihjcHBHdWFyZEJlZ2luKCkpOwoKICAgICAgICAgICAgLyogV3JpdGUgc3RhdGljcy4gKi8KICAgICAgICAgICAgTGlzdDxWYXJpYWJsZUVsZW1lbnQ+IGNsYXNzZmllbGRzID0gZ2V0QWxsRmllbGRzKGNsYXp6KTsKCiAgICAgICAgICAgIGZvciAoVmFyaWFibGVFbGVtZW50IHY6IGNsYXNzZmllbGRzKSB7CiAgICAgICAgICAgICAgICBpZiAoIXYuZ2V0TW9kaWZpZXJzKCkuY29udGFpbnMoTW9kaWZpZXIuU1RBVElDKSkKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIFN0cmluZyBzID0gbnVsbDsKICAgICAgICAgICAgICAgIHMgPSBkZWZpbmVGb3JTdGF0aWMoY2xhenosIHYpOwogICAgICAgICAgICAgICAgaWYgKHMgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIHB3LnByaW50bG4ocyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qIFdyaXRlIG1ldGhvZHMuICovCiAgICAgICAgICAgIExpc3Q8RXhlY3V0YWJsZUVsZW1lbnQ+IGNsYXNzbWV0aG9kcyA9IEVsZW1lbnRGaWx0ZXIubWV0aG9kc0luKGNsYXp6LmdldEVuY2xvc2VkRWxlbWVudHMoKSk7CiAgICAgICAgICAgIGZvciAoRXhlY3V0YWJsZUVsZW1lbnQgbWQ6IGNsYXNzbWV0aG9kcykgewogICAgICAgICAgICAgICAgaWYobWQuZ2V0TW9kaWZpZXJzKCkuY29udGFpbnMoTW9kaWZpZXIuTkFUSVZFKSl7CiAgICAgICAgICAgICAgICAgICAgVHlwZU1pcnJvciBtdHIgPSB0eXBlcy5lcmFzdXJlKG1kLmdldFJldHVyblR5cGUoKSk7CiAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHNpZyA9IHNpZ25hdHVyZShtZCk7CiAgICAgICAgICAgICAgICAgICAgVHlwZVNpZ25hdHVyZSBuZXd0eXBlc2lnID0gbmV3IFR5cGVTaWduYXR1cmUoZWxlbXMpOwogICAgICAgICAgICAgICAgICAgIENoYXJTZXF1ZW5jZSBtZXRob2ROYW1lID0gbWQuZ2V0U2ltcGxlTmFtZSgpOwogICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gbG9uZ05hbWUgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICBmb3IgKEV4ZWN1dGFibGVFbGVtZW50IG1kMjogY2xhc3NtZXRob2RzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgobWQyICE9IG1kKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgKG1ldGhvZE5hbWUuZXF1YWxzKG1kMi5nZXRTaW1wbGVOYW1lKCkpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgKG1kMi5nZXRNb2RpZmllcnMoKS5jb250YWlucyhNb2RpZmllci5OQVRJVkUpKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvbmdOYW1lID0gdHJ1ZTsKCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHB3LnByaW50bG4oIi8qIik7CiAgICAgICAgICAgICAgICAgICAgcHcucHJpbnRsbigiICogQ2xhc3M6ICAgICAiICsgY25hbWUpOwogICAgICAgICAgICAgICAgICAgIHB3LnByaW50bG4oIiAqIE1ldGhvZDogICAgIiArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYW5nbGVyLm1hbmdsZShtZXRob2ROYW1lLCBNYW5nbGUuVHlwZS5GSUVMRFNUVUIpKTsKICAgICAgICAgICAgICAgICAgICBwdy5wcmludGxuKCIgKiBTaWduYXR1cmU6ICIgKyBuZXd0eXBlc2lnLmdldFR5cGVTaWduYXR1cmUoc2lnLCBtdHIpKTsKICAgICAgICAgICAgICAgICAgICBwdy5wcmludGxuKCIgKi8iKTsKICAgICAgICAgICAgICAgICAgICBwdy5wcmludGxuKCJKTklFWFBPUlQgIiArIGpuaVR5cGUobXRyKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiIEpOSUNBTEwgIiArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYW5nbGVyLm1hbmdsZU1ldGhvZChtZCwgY2xhenosCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChsb25nTmFtZSkgPwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYW5nbGUuVHlwZS5NRVRIT0RfSk5JX0xPTkcgOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYW5nbGUuVHlwZS5NRVRIT0RfSk5JX1NIT1JUKSk7CiAgICAgICAgICAgICAgICAgICAgcHcucHJpbnQoIiAgKEpOSUVudiAqLCAiKTsKICAgICAgICAgICAgICAgICAgICBMaXN0PD8gZXh0ZW5kcyBWYXJpYWJsZUVsZW1lbnQ+IHBhcmFtYXJncyA9IG1kLmdldFBhcmFtZXRlcnMoKTsKICAgICAgICAgICAgICAgICAgICBMaXN0PFR5cGVNaXJyb3I+IGFyZ3MgPSBuZXcgQXJyYXlMaXN0PD4oKTsKICAgICAgICAgICAgICAgICAgICBmb3IgKFZhcmlhYmxlRWxlbWVudCBwOiBwYXJhbWFyZ3MpIHsKICAgICAgICAgICAgICAgICAgICAgICAgYXJncy5hZGQodHlwZXMuZXJhc3VyZShwLmFzVHlwZSgpKSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmIChtZC5nZXRNb2RpZmllcnMoKS5jb250YWlucyhNb2RpZmllci5TVEFUSUMpKQogICAgICAgICAgICAgICAgICAgICAgICBwdy5wcmludCgiamNsYXNzIik7CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICBwdy5wcmludCgiam9iamVjdCIpOwoKICAgICAgICAgICAgICAgICAgICBmb3IgKFR5cGVNaXJyb3IgYXJnOiBhcmdzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHB3LnByaW50KCIsICIpOwogICAgICAgICAgICAgICAgICAgICAgICBwdy5wcmludChqbmlUeXBlKGFyZykpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBwdy5wcmludGxuKCIpOyIgKyBsaW5lU2VwKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBwdy5wcmludGxuKGNwcEd1YXJkRW5kKCkpOwogICAgICAgICAgICBwdy5wcmludGxuKGd1YXJkRW5kKGNuYW1lKSk7CiAgICAgICAgfSBjYXRjaCAoVHlwZVNpZ25hdHVyZS5TaWduYXR1cmVFeGNlcHRpb24gZSkgewogICAgICAgICAgICB1dGlsLmVycm9yKCJqbmkuc2lnZXJyb3IiLCBlLmdldE1lc3NhZ2UoKSk7CiAgICAgICAgfQogICAgfQoKCiAgICBwcm90ZWN0ZWQgZmluYWwgU3RyaW5nIGpuaVR5cGUoVHlwZU1pcnJvciB0KSB0aHJvd3MgVXRpbC5FeGl0IHsKICAgICAgICBUeXBlRWxlbWVudCB0aHJvd2FibGUgPSBlbGVtcy5nZXRUeXBlRWxlbWVudCgiamF2YS5sYW5nLlRocm93YWJsZSIpOwogICAgICAgIFR5cGVFbGVtZW50IGpDbGFzcyA9IGVsZW1zLmdldFR5cGVFbGVtZW50KCJqYXZhLmxhbmcuQ2xhc3MiKTsKICAgICAgICBUeXBlRWxlbWVudCBqU3RyaW5nID0gZWxlbXMuZ2V0VHlwZUVsZW1lbnQoImphdmEubGFuZy5TdHJpbmciKTsKICAgICAgICBFbGVtZW50IHRjbGFzc0RvYyA9IHR5cGVzLmFzRWxlbWVudCh0KTsKCgogICAgICAgIHN3aXRjaCAodC5nZXRLaW5kKCkpIHsKICAgICAgICAgICAgY2FzZSBBUlJBWTogewogICAgICAgICAgICAgICAgVHlwZU1pcnJvciBjdCA9ICgoQXJyYXlUeXBlKSB0KS5nZXRDb21wb25lbnRUeXBlKCk7CiAgICAgICAgICAgICAgICBzd2l0Y2ggKGN0LmdldEtpbmQoKSkgewogICAgICAgICAgICAgICAgICAgIGNhc2UgQk9PTEVBTjogIHJldHVybiAiamJvb2xlYW5BcnJheSI7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBCWVRFOiAgICAgcmV0dXJuICJqYnl0ZUFycmF5IjsKICAgICAgICAgICAgICAgICAgICBjYXNlIENIQVI6ICAgICByZXR1cm4gImpjaGFyQXJyYXkiOwogICAgICAgICAgICAgICAgICAgIGNhc2UgU0hPUlQ6ICAgIHJldHVybiAianNob3J0QXJyYXkiOwogICAgICAgICAgICAgICAgICAgIGNhc2UgSU5UOiAgICAgIHJldHVybiAiamludEFycmF5IjsKICAgICAgICAgICAgICAgICAgICBjYXNlIExPTkc6ICAgICByZXR1cm4gImpsb25nQXJyYXkiOwogICAgICAgICAgICAgICAgICAgIGNhc2UgRkxPQVQ6ICAgIHJldHVybiAiamZsb2F0QXJyYXkiOwogICAgICAgICAgICAgICAgICAgIGNhc2UgRE9VQkxFOiAgIHJldHVybiAiamRvdWJsZUFycmF5IjsKICAgICAgICAgICAgICAgICAgICBjYXNlIEFSUkFZOgogICAgICAgICAgICAgICAgICAgIGNhc2UgREVDTEFSRUQ6IHJldHVybiAiam9iamVjdEFycmF5IjsKICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OiB0aHJvdyBuZXcgRXJyb3IoY3QudG9TdHJpbmcoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGNhc2UgVk9JRDogICAgIHJldHVybiAidm9pZCI7CiAgICAgICAgICAgIGNhc2UgQk9PTEVBTjogIHJldHVybiAiamJvb2xlYW4iOwogICAgICAgICAgICBjYXNlIEJZVEU6ICAgICByZXR1cm4gImpieXRlIjsKICAgICAgICAgICAgY2FzZSBDSEFSOiAgICAgcmV0dXJuICJqY2hhciI7CiAgICAgICAgICAgIGNhc2UgU0hPUlQ6ICAgIHJldHVybiAianNob3J0IjsKICAgICAgICAgICAgY2FzZSBJTlQ6ICAgICAgcmV0dXJuICJqaW50IjsKICAgICAgICAgICAgY2FzZSBMT05HOiAgICAgcmV0dXJuICJqbG9uZyI7CiAgICAgICAgICAgIGNhc2UgRkxPQVQ6ICAgIHJldHVybiAiamZsb2F0IjsKICAgICAgICAgICAgY2FzZSBET1VCTEU6ICAgcmV0dXJuICJqZG91YmxlIjsKCiAgICAgICAgICAgIGNhc2UgREVDTEFSRUQ6IHsKICAgICAgICAgICAgICAgIGlmICh0Y2xhc3NEb2MuZXF1YWxzKGpTdHJpbmcpKQogICAgICAgICAgICAgICAgICAgIHJldHVybiAianN0cmluZyI7CiAgICAgICAgICAgICAgICBlbHNlIGlmICh0eXBlcy5pc0Fzc2lnbmFibGUodCwgdGhyb3dhYmxlLmFzVHlwZSgpKSkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gImp0aHJvd2FibGUiOwogICAgICAgICAgICAgICAgZWxzZSBpZiAodHlwZXMuaXNBc3NpZ25hYmxlKHQsIGpDbGFzcy5hc1R5cGUoKSkpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICJqY2xhc3MiOwogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHJldHVybiAiam9iamVjdCI7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHV0aWwuYnVnKCJqbmkudW5rbm93bi50eXBlIik7CiAgICAgICAgcmV0dXJuIG51bGw7IC8qIGRlYWQgY29kZS4gKi8KICAgIH0KfQpQSwMECgAACAAABjupSuHJAy5+FwAAfhcAAB0AAABjb20vc3VuL3Rvb2xzL2phdmFoL1V0aWwuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwMiwgMjAxNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLmphdmFoOwoKaW1wb3J0IGphdmEuaW8uUHJpbnRXcml0ZXI7CmltcG9ydCBqYXZhLnRleHQuTWVzc2FnZUZvcm1hdDsKaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CmltcG9ydCBqYXZhLnV0aWwuUmVzb3VyY2VCdW5kbGU7CmltcG9ydCBqYXZhLnV0aWwuTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uOwppbXBvcnQgamF2YXgudG9vbHMuRGlhZ25vc3RpYzsKaW1wb3J0IGphdmF4LnRvb2xzLkRpYWdub3N0aWMuS2luZDsKaW1wb3J0IGphdmF4LnRvb2xzLkRpYWdub3N0aWNMaXN0ZW5lcjsKaW1wb3J0IGphdmF4LnRvb2xzLkphdmFGaWxlT2JqZWN0OwoKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5EZWZpbmVkQnk7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuRGVmaW5lZEJ5LkFwaTsKCi8qKgogKiBNZXNzYWdlcywgdmVyYm9zZSBhbmQgZXJyb3IgaGFuZGxpbmcgc3VwcG9ydC4KICoKICogRm9yIGVycm9ycywgdGhlIGZhaWx1cmUgbW9kZXMgYXJlOgogKiAgICAgIGVycm9yIC0tIFVzZXIgZGlkIHNvbWV0aGluZyB3cm9uZwogKiAgICAgIGJ1ZyAgIC0tIEJ1ZyBoYXMgb2NjdXJyZWQgaW4gamF2YWgKICogICAgICBmYXRhbCAtLSBXZSBjYW4ndCBldmVuIGZpbmQgcmVzb3VyY2VzLCBzbyBiYWlsIGZhc3QsIGRvbid0IGxvY2FsaXplCiAqCiAqIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24KICogcmlzay4gIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlCiAqIG9yIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj48L3A+CiAqLwpwdWJsaWMgY2xhc3MgVXRpbCB7CiAgICAvKiogRXhpdCBpcyB1c2VkIHRvIHJlcGxhY2UgdGhlIHVzZSBvZiBTeXN0ZW0uZXhpdCBpbiB0aGUgb3JpZ2luYWwgamF2YWguCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgRXhpdCBleHRlbmRzIEVycm9yIHsKICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSA0MzA4MjA5NzgxMTQwNjcyMjFMOwogICAgICAgIEV4aXQoaW50IGV4aXRWYWx1ZSkgewogICAgICAgICAgICB0aGlzKGV4aXRWYWx1ZSwgbnVsbCk7CiAgICAgICAgfQoKICAgICAgICBFeGl0KGludCBleGl0VmFsdWUsIFRocm93YWJsZSBjYXVzZSkgewogICAgICAgICAgICBzdXBlcihjYXVzZSk7CiAgICAgICAgICAgIHRoaXMuZXhpdFZhbHVlID0gZXhpdFZhbHVlOwogICAgICAgICAgICB0aGlzLmNhdXNlID0gY2F1c2U7CiAgICAgICAgfQoKICAgICAgICBFeGl0KEV4aXQgZSkgewogICAgICAgICAgICB0aGlzKGUuZXhpdFZhbHVlLCBlLmNhdXNlKTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBmaW5hbCBpbnQgZXhpdFZhbHVlOwogICAgICAgIHB1YmxpYyBmaW5hbCBUaHJvd2FibGUgY2F1c2U7CiAgICB9CgogICAgLyoKICAgICAqIEhlbHAgZm9yIHZlcmJvc2l0eS4KICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gdmVyYm9zZSA9IGZhbHNlOwoKICAgIHB1YmxpYyBQcmludFdyaXRlciBsb2c7CiAgICBwdWJsaWMgRGlhZ25vc3RpY0xpc3RlbmVyPD8gc3VwZXIgSmF2YUZpbGVPYmplY3Q+IGRsOwoKICAgIFV0aWwoUHJpbnRXcml0ZXIgbG9nLCBEaWFnbm9zdGljTGlzdGVuZXI8PyBzdXBlciBKYXZhRmlsZU9iamVjdD4gZGwpIHsKICAgICAgICB0aGlzLmxvZyA9IGxvZzsKICAgICAgICB0aGlzLmRsID0gZGw7CiAgICB9CgogICAgcHVibGljIHZvaWQgbG9nKFN0cmluZyBzKSB7CiAgICAgICAgbG9nLnByaW50bG4ocyk7CiAgICB9CgogICAgLyoKICAgICAqIEhlbHAgZm9yIGxvYWRpbmcgbG9jYWxpemVkIG1lc3NhZ2VzLgogICAgICovCiAgICBwcml2YXRlIFJlc291cmNlQnVuZGxlIG07CgogICAgcHJpdmF0ZSB2b2lkIGluaXRNZXNzYWdlcygpIHRocm93cyBFeGl0IHsKICAgICAgICB0cnkgewogICAgICAgICAgICBtID0gUmVzb3VyY2VCdW5kbGUuZ2V0QnVuZGxlKCJjb20uc3VuLnRvb2xzLmphdmFoLnJlc291cmNlcy5sMTBuIik7CiAgICAgICAgfSBjYXRjaCAoTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uIG1yZSkgewogICAgICAgICAgICBmYXRhbCgiRXJyb3IgbG9hZGluZyByZXNvdXJjZXMuICBQbGVhc2UgZmlsZSBhIGJ1ZyByZXBvcnQuIiwgbXJlKTsKICAgICAgICB9CiAgICB9CgogICAgcHJpdmF0ZSBTdHJpbmcgZ2V0VGV4dChTdHJpbmcga2V5LCBPYmplY3QuLi4gYXJncykgdGhyb3dzIEV4aXQgewogICAgICAgIGlmIChtID09IG51bGwpCiAgICAgICAgICAgIGluaXRNZXNzYWdlcygpOwogICAgICAgIHRyeSB7CiAgICAgICAgICAgIHJldHVybiBNZXNzYWdlRm9ybWF0LmZvcm1hdChtLmdldFN0cmluZyhrZXkpLCBhcmdzKTsKICAgICAgICB9IGNhdGNoIChNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24gZSkgewogICAgICAgICAgICBmYXRhbCgiS2V5ICIgKyBrZXkgKyAiIG5vdCBmb3VuZCBpbiByZXNvdXJjZXMuIiwgZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOyAvKiBkZWFkIGNvZGUgKi8KICAgIH0KCiAgICAvKgogICAgICogRmFpbHVyZSBtb2Rlcy4KICAgICAqLwogICAgcHVibGljIHZvaWQgYnVnKFN0cmluZyBrZXkpIHRocm93cyBFeGl0IHsKICAgICAgICBidWcoa2V5LCBudWxsKTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCBidWcoU3RyaW5nIGtleSwgRXhjZXB0aW9uIGUpIHRocm93cyBFeGl0IHsKICAgICAgICBkbC5yZXBvcnQoY3JlYXRlRGlhZ25vc3RpYyhEaWFnbm9zdGljLktpbmQuRVJST1IsIGtleSkpOwogICAgICAgIGRsLnJlcG9ydChjcmVhdGVEaWFnbm9zdGljKERpYWdub3N0aWMuS2luZC5OT1RFLCAiYnVnLnJlcG9ydCIpKTsKICAgICAgICB0aHJvdyBuZXcgRXhpdCgxMSwgZSk7CiAgICB9CgogICAgcHVibGljIHZvaWQgZXJyb3IoU3RyaW5nIGtleSwgT2JqZWN0Li4uIGFyZ3MpIHRocm93cyBFeGl0IHsKICAgICAgICBkbC5yZXBvcnQoY3JlYXRlRGlhZ25vc3RpYyhEaWFnbm9zdGljLktpbmQuRVJST1IsIGtleSwgYXJncykpOwogICAgICAgIHRocm93IG5ldyBFeGl0KDE1KTsKICAgIH0KCiAgICBwcml2YXRlIHZvaWQgZmF0YWwoU3RyaW5nIG1zZywgRXhjZXB0aW9uIGUpIHRocm93cyBFeGl0IHsKICAgICAgICBkbC5yZXBvcnQoY3JlYXRlRGlhZ25vc3RpYyhEaWFnbm9zdGljLktpbmQuRVJST1IsICIiLCBtc2cpKTsKICAgICAgICB0aHJvdyBuZXcgRXhpdCgxMCwgZSk7CiAgICB9CgogICAgcHJpdmF0ZSBEaWFnbm9zdGljPEphdmFGaWxlT2JqZWN0PiBjcmVhdGVEaWFnbm9zdGljKAogICAgICAgICAgICBmaW5hbCBEaWFnbm9zdGljLktpbmQga2luZCwgZmluYWwgU3RyaW5nIGNvZGUsIGZpbmFsIE9iamVjdC4uLiBhcmdzKSB7CiAgICAgICAgcmV0dXJuIG5ldyBEaWFnbm9zdGljPEphdmFGaWxlT2JqZWN0PigpIHsKICAgICAgICAgICAgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICAgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0Q29kZSgpIHsKICAgICAgICAgICAgICAgIHJldHVybiBjb2RlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSKQogICAgICAgICAgICBwdWJsaWMgbG9uZyBnZXRDb2x1bW5OdW1iZXIoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gRGlhZ25vc3RpYy5OT1BPUzsKICAgICAgICAgICAgfQogICAgICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgICAgICAgICAgcHVibGljIGxvbmcgZ2V0RW5kUG9zaXRpb24oKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gRGlhZ25vc3RpYy5OT1BPUzsKICAgICAgICAgICAgfQogICAgICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgICAgICAgICAgcHVibGljIEtpbmQgZ2V0S2luZCgpIHsKICAgICAgICAgICAgICAgIHJldHVybiBraW5kOwogICAgICAgICAgICB9CiAgICAgICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSKQogICAgICAgICAgICBwdWJsaWMgbG9uZyBnZXRMaW5lTnVtYmVyKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIERpYWdub3N0aWMuTk9QT1M7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICAgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0TWVzc2FnZShMb2NhbGUgbG9jYWxlKSB7CiAgICAgICAgICAgICAgICBpZiAoY29kZS5sZW5ndGgoKSA9PSAwKQogICAgICAgICAgICAgICAgICAgIHJldHVybiAoU3RyaW5nKSBhcmdzWzBdOwogICAgICAgICAgICAgICAgcmV0dXJuIGdldFRleHQoY29kZSwgYXJncyk7IC8vIEZJWE1FIGxvY2FsZQogICAgICAgICAgICB9CiAgICAgICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSKQogICAgICAgICAgICBwdWJsaWMgbG9uZyBnZXRQb3NpdGlvbigpIHsKICAgICAgICAgICAgICAgIHJldHVybiBEaWFnbm9zdGljLk5PUE9TOwogICAgICAgICAgICB9CiAgICAgICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSKQogICAgICAgICAgICBwdWJsaWMgSmF2YUZpbGVPYmplY3QgZ2V0U291cmNlKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICAgICAgICAgIHB1YmxpYyBsb25nIGdldFN0YXJ0UG9zaXRpb24oKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gRGlhZ25vc3RpYy5OT1BPUzsKICAgICAgICAgICAgfQogICAgICAgIH07CiAgICB9Cn0KUEsDBAoAAAgAANJ9TUoyfS2frwgAAK8IAAAdAAAAY29tL3N1bi90b29scy9qYXZhaC9NYWluLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDcsIDIwMDgsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhaDsKCmltcG9ydCBqYXZhLmlvLlByaW50V3JpdGVyOwoKLyoqCiAqICBNYWluIGVudHJ5IHBvaW50LgogKgogKiAgPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24gcmlzay4KICogIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yCiAqICBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+CiAqLwpwdWJsaWMgY2xhc3MgTWFpbiB7CiAgICAvKioKICAgICAqIE1haW4gZW50cnkgcG9pbnQgZm9yIHRoZSBsYXVuY2hlci4KICAgICAqIE5vdGU6IFRoaXMgbWV0aG9kIGNhbGxzIFN5c3RlbS5leGl0LgogICAgICogQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmdbXSBhcmdzKSB7CiAgICAgICAgSmF2YWhUYXNrIHQgPSBuZXcgSmF2YWhUYXNrKCk7CiAgICAgICAgaW50IHJjID0gdC5ydW4oYXJncyk7CiAgICAgICAgU3lzdGVtLmV4aXQocmMpOwogICAgfQoKICAgIC8qKgogICAgICogRW50cnkgcG9pbnQgdGhhdCBkb2VzIDxpPm5vdDwvaT4gY2FsbCBTeXN0ZW0uZXhpdC4KICAgICAqIEBwYXJhbSBhcmdzIGNvbW1hbmQgbGluZSBhcmd1bWVudHMKICAgICAqIEBwYXJhbSBvdXQgb3V0cHV0IHN0cmVhbQogICAgICogQHJldHVybiBhbiBleGl0IGNvZGUuIDAgbWVhbnMgc3VjY2Vzcywgbm9uLXplcm8gbWVhbnMgYW4gZXJyb3Igb2NjdXJyZWQuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgaW50IHJ1bihTdHJpbmdbXSBhcmdzLCBQcmludFdyaXRlciBvdXQpIHsKICAgICAgICBKYXZhaFRhc2sgdCA9IG5ldyBKYXZhaFRhc2soKTsKICAgICAgICB0LnNldExvZyhvdXQpOwogICAgICAgIHJldHVybiB0LnJ1bihhcmdzKTsKICAgIH0KfQpQSwMECgAACAAA0n1NSo36MOIeDQAAHg0AACIAAABjb20vc3VuL3Rvb2xzL2phdmFoL0phdmFoVG9vbC5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDA5LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuamF2YWg7CgppbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOwppbXBvcnQgamF2YS5pby5Xcml0ZXI7CmltcG9ydCBqYXZhLm5pby5jaGFyc2V0LkNoYXJzZXQ7CmltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOwppbXBvcnQgamF2YS51dGlsLkVudW1TZXQ7CmltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOwppbXBvcnQgamF2YS51dGlsLlNldDsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuU291cmNlVmVyc2lvbjsKaW1wb3J0IGphdmF4LnRvb2xzLkRpYWdub3N0aWNMaXN0ZW5lcjsKaW1wb3J0IGphdmF4LnRvb2xzLkphdmFGaWxlTWFuYWdlcjsKaW1wb3J0IGphdmF4LnRvb2xzLkphdmFGaWxlT2JqZWN0OwppbXBvcnQgamF2YXgudG9vbHMuU3RhbmRhcmRKYXZhRmlsZU1hbmFnZXI7CgppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkRlZmluZWRCeTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5EZWZpbmVkQnkuQXBpOwoKLyoKICogPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93bgogKiByaXNrLiAgVGhpcyBjb2RlIGFuZCBpdHMgaW50ZXJuYWwgaW50ZXJmYWNlcyBhcmUgc3ViamVjdCB0byBjaGFuZ2UKICogb3IgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPjwvcD4KICovCnB1YmxpYyBjbGFzcyBKYXZhaFRvb2wgaW1wbGVtZW50cyBOYXRpdmVIZWFkZXJUb29sIHsKCiAgICBwdWJsaWMgTmF0aXZlSGVhZGVyVGFzayBnZXRUYXNrKFdyaXRlciBvdXQsCiAgICAgICAgICAgIEphdmFGaWxlTWFuYWdlciBmaWxlTWFuYWdlciwKICAgICAgICAgICAgRGlhZ25vc3RpY0xpc3RlbmVyPD8gc3VwZXIgSmF2YUZpbGVPYmplY3Q+IGRpYWdub3N0aWNMaXN0ZW5lciwKICAgICAgICAgICAgSXRlcmFibGU8U3RyaW5nPiBvcHRpb25zLAogICAgICAgICAgICBJdGVyYWJsZTxTdHJpbmc+IGNsYXNzZXMpIHsKICAgICAgICByZXR1cm4gbmV3IEphdmFoVGFzayhvdXQsIGZpbGVNYW5hZ2VyLCBkaWFnbm9zdGljTGlzdGVuZXIsIG9wdGlvbnMsIGNsYXNzZXMpOwogICAgfQoKICAgIHB1YmxpYyBTdGFuZGFyZEphdmFGaWxlTWFuYWdlciBnZXRTdGFuZGFyZEZpbGVNYW5hZ2VyKERpYWdub3N0aWNMaXN0ZW5lcjw/IHN1cGVyIEphdmFGaWxlT2JqZWN0PiBkaWFnbm9zdGljTGlzdGVuZXIsIExvY2FsZSBsb2NhbGUsIENoYXJzZXQgY2hhcnNldCkgewogICAgICAgIHJldHVybiBKYXZhaFRhc2suZ2V0RGVmYXVsdEZpbGVNYW5hZ2VyKGRpYWdub3N0aWNMaXN0ZW5lciwgbnVsbCk7CiAgICB9CgogICAgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICBwdWJsaWMgaW50IHJ1bihJbnB1dFN0cmVhbSBpbiwgT3V0cHV0U3RyZWFtIG91dCwgT3V0cHV0U3RyZWFtIGVyciwgU3RyaW5nLi4uIGFyZ3VtZW50cykgewogICAgICAgIEphdmFoVGFzayB0ID0gbmV3IEphdmFoVGFzaygKICAgICAgICAgICAgICAgIEphdmFoVGFzay5nZXRQcmludFdyaXRlckZvclN0cmVhbShvdXQpLAogICAgICAgICAgICAgICAgbnVsbCwKICAgICAgICAgICAgICAgIG51bGwsCiAgICAgICAgICAgICAgICBBcnJheXMuYXNMaXN0KGFyZ3VtZW50cyksCiAgICAgICAgICAgICAgICBudWxsKTsKICAgICAgICByZXR1cm4gKHQucnVuKCkgPyAwIDogMSk7CiAgICB9CgogICAgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICBwdWJsaWMgU2V0PFNvdXJjZVZlcnNpb24+IGdldFNvdXJjZVZlcnNpb25zKCkgewogICAgICAgIHJldHVybiBFbnVtU2V0LmFsbE9mKFNvdXJjZVZlcnNpb24uY2xhc3MpOwogICAgfQoKICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSKQogICAgcHVibGljIGludCBpc1N1cHBvcnRlZE9wdGlvbihTdHJpbmcgb3B0aW9uKSB7CiAgICAgICAgZm9yIChKYXZhaFRhc2suT3B0aW9uIG9wdCA6IEphdmFoVGFzay5yZWNvZ25pemVkT3B0aW9ucykgewogICAgICAgICAgICBpZiAob3B0Lm1hdGNoZXMob3B0aW9uKSkKICAgICAgICAgICAgICAgIHJldHVybiAob3B0Lmhhc0FyZyA/IDEgOiAwKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIC0xOwogICAgfQp9ClBLAwQKAAAIAAAGO6lKKawjHXQoAAB0KAAAJgAAAGNvbS9zdW4vdG9vbHMvamF2YWgvVHlwZVNpZ25hdHVyZS5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDAyLCAyMDE0LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuamF2YWg7CgppbXBvcnQgamF2YS51dGlsLio7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuTmFtZTsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC5UeXBlRWxlbWVudDsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwudHlwZS5BcnJheVR5cGU7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLnR5cGUuRGVjbGFyZWRUeXBlOwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC50eXBlLk5vVHlwZTsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwudHlwZS5QcmltaXRpdmVUeXBlOwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC50eXBlLlR5cGVLaW5kOwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC50eXBlLlR5cGVNaXJyb3I7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLnR5cGUuVHlwZVZhcmlhYmxlOwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC50eXBlLlR5cGVWaXNpdG9yOwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC51dGlsLkVsZW1lbnRzOwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC51dGlsLlNpbXBsZVR5cGVWaXNpdG9yOTsKCmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuRGVmaW5lZEJ5OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkRlZmluZWRCeS5BcGk7CgovKioKICogUmV0dXJucyBpbnRlcm5hbCB0eXBlIHNpZ25hdHVyZS4KICoKICogPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93bgogKiByaXNrLiAgVGhpcyBjb2RlIGFuZCBpdHMgaW50ZXJuYWwgaW50ZXJmYWNlcyBhcmUgc3ViamVjdCB0byBjaGFuZ2UKICogb3IgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPjwvcD4KICoKICogQGF1dGhvciBTdWNoZXRhIERhbWJhbGthcgogKi8KCnB1YmxpYyBjbGFzcyBUeXBlU2lnbmF0dXJlIHsKICAgIHN0YXRpYyBjbGFzcyBTaWduYXR1cmVFeGNlcHRpb24gZXh0ZW5kcyBFeGNlcHRpb24gewogICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDFMOwogICAgICAgIFNpZ25hdHVyZUV4Y2VwdGlvbihTdHJpbmcgcmVhc29uKSB7CiAgICAgICAgICAgIHN1cGVyKHJlYXNvbik7CiAgICAgICAgfQogICAgfQoKICAgIEVsZW1lbnRzIGVsZW1zOwoKICAgIC8qIFNpZ25hdHVyZSBDaGFyYWN0ZXJzICovCgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFNJR19WT0lEICAgICAgICAgICAgICAgICAgID0gIlYiOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFNJR19CT09MRUFOICAgICAgICAgICAgICAgID0gIloiOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFNJR19CWVRFICAgICAgICAgICAgICAgICAgID0gIkIiOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFNJR19DSEFSICAgICAgICAgICAgICAgICAgID0gIkMiOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFNJR19TSE9SVCAgICAgICAgICAgICAgICAgID0gIlMiOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFNJR19JTlQgICAgICAgICAgICAgICAgICAgID0gIkkiOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFNJR19MT05HICAgICAgICAgICAgICAgICAgID0gIkoiOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFNJR19GTE9BVCAgICAgICAgICAgICAgICAgID0gIkYiOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFNJR19ET1VCTEUgICAgICAgICAgICAgICAgID0gIkQiOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFNJR19BUlJBWSAgICAgICAgICAgICAgICAgID0gIlsiOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFNJR19DTEFTUyAgICAgICAgICAgICAgICAgID0gIkwiOwoKCgogICAgcHVibGljIFR5cGVTaWduYXR1cmUoRWxlbWVudHMgZWxlbXMpewogICAgICAgIHRoaXMuZWxlbXMgPSBlbGVtczsKICAgIH0KCiAgICAvKgogICAgICogUmV0dXJucyB0aGUgdHlwZSBzaWduYXR1cmUgb2YgYSBmaWVsZCBhY2NvcmRpbmcgdG8gSlZNIHNwZWNzCiAgICAgKi8KICAgIHB1YmxpYyBTdHJpbmcgZ2V0VHlwZVNpZ25hdHVyZShTdHJpbmcgamF2YXNpZ25hdHVyZSkgdGhyb3dzIFNpZ25hdHVyZUV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGdldFBhcmFtSlZNU2lnbmF0dXJlKGphdmFzaWduYXR1cmUpOwogICAgfQoKICAgIC8qCiAgICAgKiBSZXR1cm5zIHRoZSB0eXBlIHNpZ25hdHVyZSBvZiBhIG1ldGhvZCBhY2NvcmRpbmcgdG8gSlZNIHNwZWNzCiAgICAgKi8KICAgIHB1YmxpYyBTdHJpbmcgZ2V0VHlwZVNpZ25hdHVyZShTdHJpbmcgamF2YXNpZ25hdHVyZSwgVHlwZU1pcnJvciByZXR1cm5UeXBlKQogICAgICAgICAgICB0aHJvd3MgU2lnbmF0dXJlRXhjZXB0aW9uIHsKICAgICAgICBTdHJpbmcgc2lnbmF0dXJlID0gbnVsbDsgLy9KYXZhIHR5cGUgc2lnbmF0dXJlLgogICAgICAgIFN0cmluZyB0eXBlU2lnbmF0dXJlID0gbnVsbDsgLy9JbnRlcm5hbCB0eXBlIHNpZ25hdHVyZS4KICAgICAgICBMaXN0PFN0cmluZz4gcGFyYW1zID0gbmV3IEFycmF5TGlzdDw+KCk7IC8vTGlzdCBvZiBwYXJhbWV0ZXJzLgogICAgICAgIFN0cmluZyBwYXJhbXNpZyA9IG51bGw7IC8vSmF2YSBwYXJhbWV0ZXIgc2lnbmF0dXJlLgogICAgICAgIFN0cmluZyBwYXJhbUpWTVNpZyA9IG51bGw7IC8vSW50ZXJuYWwgcGFyYW1ldGVyIHNpZ25hdHVyZS4KICAgICAgICBTdHJpbmcgcmV0dXJuU2lnID0gbnVsbDsgLy9KYXZhIHJldHVybiB0eXBlIHNpZ25hdHVyZS4KICAgICAgICBTdHJpbmcgcmV0dXJuSlZNVHlwZSA9IG51bGw7IC8vSW50ZXJuYWwgcmV0dXJuIHR5cGUgc2lnbmF0dXJlLgogICAgICAgIGludCBkaW1lbnNpb25zID0gMDsgLy9BcnJheSBkaW1lbnNpb24uCgogICAgICAgIGludCBzdGFydEluZGV4ID0gLTE7CiAgICAgICAgaW50IGVuZEluZGV4ID0gLTE7CiAgICAgICAgU3RyaW5nVG9rZW5pemVyIHN0ID0gbnVsbDsKICAgICAgICBpbnQgaSA9IDA7CgogICAgICAgIC8vIEdldHMgdGhlIGFjdHVhbCBqYXZhIHNpZ25hdHVyZSB3aXRob3V0IHBhcmVudGhlc2VzLgogICAgICAgIGlmIChqYXZhc2lnbmF0dXJlICE9IG51bGwpIHsKICAgICAgICAgICAgc3RhcnRJbmRleCA9IGphdmFzaWduYXR1cmUuaW5kZXhPZigiKCIpOwogICAgICAgICAgICBlbmRJbmRleCA9IGphdmFzaWduYXR1cmUuaW5kZXhPZigiKSIpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCgoc3RhcnRJbmRleCAhPSAtMSkgJiYgKGVuZEluZGV4ICE9IC0xKSkKICAgICAgICAgICAgJiYoc3RhcnRJbmRleCsxIDwgamF2YXNpZ25hdHVyZS5sZW5ndGgoKSkKICAgICAgICAgICAgJiYoZW5kSW5kZXggPCBqYXZhc2lnbmF0dXJlLmxlbmd0aCgpKSkgewogICAgICAgICAgICBzaWduYXR1cmUgPSBqYXZhc2lnbmF0dXJlLnN1YnN0cmluZyhzdGFydEluZGV4KzEsIGVuZEluZGV4KTsKICAgICAgICB9CgogICAgICAgIC8vIFNlcGFyYXRlcyBwYXJhbWV0ZXJzLgogICAgICAgIGlmIChzaWduYXR1cmUgIT0gbnVsbCkgewogICAgICAgICAgICBpZiAoc2lnbmF0dXJlLmNvbnRhaW5zKCIsIikpIHsKICAgICAgICAgICAgICAgIHN0ID0gbmV3IFN0cmluZ1Rva2VuaXplcihzaWduYXR1cmUsICIsIik7CiAgICAgICAgICAgICAgICBpZiAoc3QgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIHdoaWxlIChzdC5oYXNNb3JlVG9rZW5zKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcGFyYW1zLmFkZChzdC5uZXh0VG9rZW4oKSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcGFyYW1zLmFkZChzaWduYXR1cmUpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvKiBKVk0gdHlwZSBzaWduYXR1cmUuICovCiAgICAgICAgdHlwZVNpZ25hdHVyZSA9ICIoIjsKCiAgICAgICAgLy8gR2V0cyBpbmRpdmlzdWFsIGludGVybmFsIHBhcmFtZXRlciBzaWduYXR1cmUuCiAgICAgICAgd2hpbGUgKHBhcmFtcy5pc0VtcHR5KCkgIT0gdHJ1ZSkgewogICAgICAgICAgICBwYXJhbXNpZyA9IHBhcmFtcy5yZW1vdmUoaSkudHJpbSgpOwogICAgICAgICAgICBwYXJhbUpWTVNpZyAgPSBnZXRQYXJhbUpWTVNpZ25hdHVyZShwYXJhbXNpZyk7CiAgICAgICAgICAgIGlmIChwYXJhbUpWTVNpZyAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICB0eXBlU2lnbmF0dXJlICs9IHBhcmFtSlZNU2lnOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICB0eXBlU2lnbmF0dXJlICs9ICIpIjsKCiAgICAgICAgLy8gR2V0IGludGVybmFsIHJldHVybiB0eXBlIHNpZ25hdHVyZS4KCiAgICAgICAgcmV0dXJuSlZNVHlwZSA9ICIiOwogICAgICAgIGlmIChyZXR1cm5UeXBlICE9IG51bGwpIHsKICAgICAgICAgICAgZGltZW5zaW9ucyA9IGRpbWVuc2lvbnMocmV0dXJuVHlwZSk7CiAgICAgICAgfQoKICAgICAgICAvL0dldHMgYXJyYXkgZGltZW5zaW9uIG9mIHJldHVybiB0eXBlLgogICAgICAgIHdoaWxlIChkaW1lbnNpb25zLS0gPiAwKSB7CiAgICAgICAgICAgIHJldHVybkpWTVR5cGUgKz0gIlsiOwogICAgICAgIH0KICAgICAgICBpZiAocmV0dXJuVHlwZSAhPSBudWxsKSB7CiAgICAgICAgICAgIHJldHVyblNpZyA9IHF1YWxpZmllZFR5cGVOYW1lKHJldHVyblR5cGUpOwogICAgICAgICAgICByZXR1cm5KVk1UeXBlICs9IGdldENvbXBvbmVudFR5cGUocmV0dXJuU2lnKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkludmFsaWQgcmV0dXJuIHR5cGUuIik7CiAgICAgICAgfQoKICAgICAgICB0eXBlU2lnbmF0dXJlICs9IHJldHVybkpWTVR5cGU7CgogICAgICAgIHJldHVybiB0eXBlU2lnbmF0dXJlOwogICAgfQoKICAgIC8qCiAgICAgKiBSZXR1cm5zIGludGVybmFsIHNpZ25hdHVyZSBvZiBhIHBhcmFtZXRlci4KICAgICAqLwogICAgcHJpdmF0ZSBTdHJpbmcgZ2V0UGFyYW1KVk1TaWduYXR1cmUoU3RyaW5nIHBhcmFtc2lnKSB0aHJvd3MgU2lnbmF0dXJlRXhjZXB0aW9uIHsKICAgICAgICBTdHJpbmcgcGFyYW1KVk1TaWcgPSAiIjsKICAgICAgICBTdHJpbmcgY29tcG9uZW50VHlwZSA9IiI7CgogICAgICAgIGlmKHBhcmFtc2lnICE9IG51bGwpewoKICAgICAgICAgICAgaWYocGFyYW1zaWcuY29udGFpbnMoIltdIikpIHsKICAgICAgICAgICAgICAgIC8vIEdldHMgYXJyYXkgZGltZW5zaW9uLgogICAgICAgICAgICAgICAgaW50IGVuZGluZGV4ID0gcGFyYW1zaWcuaW5kZXhPZigiW10iKTsKICAgICAgICAgICAgICAgIGNvbXBvbmVudFR5cGUgPSBwYXJhbXNpZy5zdWJzdHJpbmcoMCwgZW5kaW5kZXgpOwogICAgICAgICAgICAgICAgU3RyaW5nIGRpbWVuc2lvblN0cmluZyA9ICBwYXJhbXNpZy5zdWJzdHJpbmcoZW5kaW5kZXgpOwogICAgICAgICAgICAgICAgaWYoZGltZW5zaW9uU3RyaW5nICE9IG51bGwpewogICAgICAgICAgICAgICAgICAgIHdoaWxlKGRpbWVuc2lvblN0cmluZy5jb250YWlucygiW10iKSl7CiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtSlZNU2lnICs9ICJbIjsKICAgICAgICAgICAgICAgICAgICAgICAgaW50IGJlZ2luaW5kZXggPSBkaW1lbnNpb25TdHJpbmcuaW5kZXhPZigiXSIpICsgMTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYoYmVnaW5pbmRleCA8IGRpbWVuc2lvblN0cmluZy5sZW5ndGgoKSl7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaW1lbnNpb25TdHJpbmcgPSBkaW1lbnNpb25TdHJpbmcuc3Vic3RyaW5nKGJlZ2luaW5kZXgpOwogICAgICAgICAgICAgICAgICAgICAgICB9ZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGltZW5zaW9uU3RyaW5nID0gIiI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgY29tcG9uZW50VHlwZSA9IHBhcmFtc2lnOwoKICAgICAgICAgICAgcGFyYW1KVk1TaWcgKz0gZ2V0Q29tcG9uZW50VHlwZShjb21wb25lbnRUeXBlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHBhcmFtSlZNU2lnOwogICAgfQoKICAgIC8qCiAgICAgKiBSZXR1cm5zIGludGVybmFsIHNpZ25hdHVyZSBvZiBhIGNvbXBvbmVudC4KICAgICAqLwogICAgcHJpdmF0ZSBTdHJpbmcgZ2V0Q29tcG9uZW50VHlwZShTdHJpbmcgY29tcG9uZW50VHlwZSkgdGhyb3dzIFNpZ25hdHVyZUV4Y2VwdGlvbiB7CgogICAgICAgIFN0cmluZyBKVk1TaWcgPSAiIjsKCiAgICAgICAgaWYoY29tcG9uZW50VHlwZSAhPSBudWxsKXsKICAgICAgICAgICAgc3dpdGNoIChjb21wb25lbnRUeXBlKSB7CiAgICAgICAgICAgICAgICBjYXNlICJ2b2lkIjogICAgSlZNU2lnICs9IFNJR19WT0lEOyAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgImJvb2xlYW4iOiBKVk1TaWcgKz0gU0lHX0JPT0xFQU47IGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAiYnl0ZSI6ICAgIEpWTVNpZyArPSBTSUdfQllURTsgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICJjaGFyIjogICAgSlZNU2lnICs9IFNJR19DSEFSOyAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgInNob3J0IjogICBKVk1TaWcgKz0gU0lHX1NIT1JUOyAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAiaW50IjogICAgIEpWTVNpZyArPSBTSUdfSU5UOyAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICJsb25nIjogICAgSlZNU2lnICs9IFNJR19MT05HOyAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgImZsb2F0IjogICBKVk1TaWcgKz0gU0lHX0ZMT0FUOyAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAiZG91YmxlIjogIEpWTVNpZyArPSBTSUdfRE9VQkxFOyAgYnJlYWs7CiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgIGlmICghY29tcG9uZW50VHlwZS5lcXVhbHMoIiIpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIFR5cGVFbGVtZW50IGNsYXNzTmFtZURvYyA9IGVsZW1zLmdldFR5cGVFbGVtZW50KGNvbXBvbmVudFR5cGUpOwoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNsYXNzTmFtZURvYyA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU2lnbmF0dXJlRXhjZXB0aW9uKGNvbXBvbmVudFR5cGUpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGNsYXNzbmFtZSA9IGNsYXNzTmFtZURvYy5nZXRRdWFsaWZpZWROYW1lKCkudG9TdHJpbmcoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBuZXdjbGFzc25hbWUgPSBjbGFzc25hbWUucmVwbGFjZSgnLicsICcvJyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBKVk1TaWcgKz0gIkwiOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgSlZNU2lnICs9IG5ld2NsYXNzbmFtZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEpWTVNpZyArPSAiOyI7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIEpWTVNpZzsKICAgIH0KCiAgICBpbnQgZGltZW5zaW9ucyhUeXBlTWlycm9yIHQpIHsKICAgICAgICBpZiAodC5nZXRLaW5kKCkgIT0gVHlwZUtpbmQuQVJSQVkpCiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIHJldHVybiAxICsgZGltZW5zaW9ucygoKEFycmF5VHlwZSkgdCkuZ2V0Q29tcG9uZW50VHlwZSgpKTsKICAgIH0KCgogICAgU3RyaW5nIHF1YWxpZmllZFR5cGVOYW1lKFR5cGVNaXJyb3IgdHlwZSkgewogICAgICAgIFR5cGVWaXNpdG9yPE5hbWUsIFZvaWQ+IHYgPSBuZXcgU2ltcGxlVHlwZVZpc2l0b3I5PE5hbWUsIFZvaWQ+KCkgewogICAgICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICAgICAgICAgIHB1YmxpYyBOYW1lIHZpc2l0QXJyYXkoQXJyYXlUeXBlIHQsIFZvaWQgcCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHQuZ2V0Q29tcG9uZW50VHlwZSgpLmFjY2VwdCh0aGlzLCBwKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgICAgICBwdWJsaWMgTmFtZSB2aXNpdERlY2xhcmVkKERlY2xhcmVkVHlwZSB0LCBWb2lkIHApIHsKICAgICAgICAgICAgICAgIHJldHVybiAoKFR5cGVFbGVtZW50KSB0LmFzRWxlbWVudCgpKS5nZXRRdWFsaWZpZWROYW1lKCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgICAgICAgICAgcHVibGljIE5hbWUgdmlzaXRQcmltaXRpdmUoUHJpbWl0aXZlVHlwZSB0LCBWb2lkIHApIHsKICAgICAgICAgICAgICAgIHJldHVybiBlbGVtcy5nZXROYW1lKHQudG9TdHJpbmcoKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgICAgICAgICAgcHVibGljIE5hbWUgdmlzaXROb1R5cGUoTm9UeXBlIHQsIFZvaWQgcCkgewogICAgICAgICAgICAgICAgaWYgKHQuZ2V0S2luZCgpID09IFR5cGVLaW5kLlZPSUQpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGVsZW1zLmdldE5hbWUoInZvaWQiKTsKICAgICAgICAgICAgICAgIHJldHVybiBkZWZhdWx0QWN0aW9uKHQsIHApOwogICAgICAgICAgICB9CgogICAgICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICAgICAgICAgIHB1YmxpYyBOYW1lIHZpc2l0VHlwZVZhcmlhYmxlKFR5cGVWYXJpYWJsZSB0LCBWb2lkIHApIHsKICAgICAgICAgICAgICAgIHJldHVybiB0LmdldFVwcGVyQm91bmQoKS5hY2NlcHQodGhpcywgcCk7CiAgICAgICAgICAgIH0KICAgICAgICB9OwogICAgICAgIHJldHVybiB2LnZpc2l0KHR5cGUpLnRvU3RyaW5nKCk7CiAgICB9Cn0KUEsDBAoAAAgAAAY7qUr3g6MEwWQAAMFkAAAdAAAAY29tL3N1bi90b29scy9qYXZhaC9MTE5JLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDIsIDIwMTQsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhaDsKCmltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKaW1wb3J0IGphdmEuaW8uUHJpbnRXcml0ZXI7CmltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OwppbXBvcnQgamF2YS51dGlsLkhhc2hTZXQ7CmltcG9ydCBqYXZhLnV0aWwuTGlzdDsKCmltcG9ydCBqYXZhLnV0aWwuU2V0OwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5lbGVtZW50LkVsZW1lbnQ7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuRXhlY3V0YWJsZUVsZW1lbnQ7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuTW9kaWZpZXI7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuTmFtZTsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC5UeXBlRWxlbWVudDsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC5WYXJpYWJsZUVsZW1lbnQ7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLnR5cGUuQXJyYXlUeXBlOwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC50eXBlLlByaW1pdGl2ZVR5cGU7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLnR5cGUuVHlwZUtpbmQ7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLnR5cGUuVHlwZU1pcnJvcjsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwudHlwZS5UeXBlVmlzaXRvcjsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwudXRpbC5FbGVtZW50RmlsdGVyOwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC51dGlsLlNpbXBsZVR5cGVWaXNpdG9yOTsKCmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuRGVmaW5lZEJ5OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkRlZmluZWRCeS5BcGk7CgovKgogKiA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duCiAqIHJpc2suICBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZQogKiBvciBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+PC9wPgogKgogKiBAYXV0aG9yICBTdWNoZXRhIERhbWJhbGthcihSZXZpc2VkKQogKi8KcHVibGljIGNsYXNzIExMTkkgZXh0ZW5kcyBHZW4gewoKICAgIHByb3RlY3RlZCBmaW5hbCBjaGFyICBpbm5lckRlbGltID0gJyQnOyAgICAgLyogRm9yIGlubmVyIGNsYXNzZXMgKi8KICAgIHByb3RlY3RlZCBTZXQ8U3RyaW5nPiAgZG9uZUhhbmRsZVR5cGVzOwogICAgTGlzdDxWYXJpYWJsZUVsZW1lbnQ+IGZpZWxkczsKICAgIExpc3Q8RXhlY3V0YWJsZUVsZW1lbnQ+IG1ldGhvZHM7CiAgICBwcml2YXRlIGJvb2xlYW4gICAgICAgZG91YmxlQWxpZ247CiAgICBwcml2YXRlIGludCAgICAgICAgICAgcGFkRmllbGROdW0gPSAwOwoKICAgIExMTkkoYm9vbGVhbiBkb3VibGVBbGlnbiwgVXRpbCB1dGlsKSB7CiAgICAgICAgc3VwZXIodXRpbCk7CiAgICAgICAgdGhpcy5kb3VibGVBbGlnbiA9IGRvdWJsZUFsaWduOwogICAgfQoKICAgIHByb3RlY3RlZCBTdHJpbmcgZ2V0SW5jbHVkZXMoKSB7CiAgICAgICAgcmV0dXJuICIiOwogICAgfQoKICAgIHByb3RlY3RlZCB2b2lkIHdyaXRlKE91dHB1dFN0cmVhbSBvLCBUeXBlRWxlbWVudCBjbGF6eikgdGhyb3dzIFV0aWwuRXhpdCB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgU3RyaW5nIGNuYW1lICAgICA9IG1hbmdsZUNsYXNzTmFtZShjbGF6ei5nZXRRdWFsaWZpZWROYW1lKCkudG9TdHJpbmcoKSk7CiAgICAgICAgICAgIFByaW50V3JpdGVyIHB3ICAgPSB3cmFwV3JpdGVyKG8pOwogICAgICAgICAgICBmaWVsZHMgPSBFbGVtZW50RmlsdGVyLmZpZWxkc0luKGNsYXp6LmdldEVuY2xvc2VkRWxlbWVudHMoKSk7CiAgICAgICAgICAgIG1ldGhvZHMgPSBFbGVtZW50RmlsdGVyLm1ldGhvZHNJbihjbGF6ei5nZXRFbmNsb3NlZEVsZW1lbnRzKCkpOwogICAgICAgICAgICBnZW5lcmF0ZURlY2xzRm9yQ2xhc3MocHcsIGNsYXp6LCBjbmFtZSk7CiAgICAgICAgICAgIC8vIEZJWE1FIGNoZWNrIGlmIGVycm9ycyBvY2N1cnJlZCBvbiB0aGUgUHJpbnRXcml0ZXIgYW5kIHRocm93IGV4Y2VwdGlvbiBpZiBzbwogICAgICAgIH0gY2F0Y2ggKFR5cGVTaWduYXR1cmUuU2lnbmF0dXJlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdXRpbC5lcnJvcigibGxuaS5zaWdlcnJvciIsIGUuZ2V0TWVzc2FnZSgpKTsKICAgICAgICB9CiAgICB9CgogICAgcHJvdGVjdGVkIHZvaWQgZ2VuZXJhdGVEZWNsc0ZvckNsYXNzKFByaW50V3JpdGVyIHB3LAogICAgICAgICAgICBUeXBlRWxlbWVudCBjbGF6eiwgU3RyaW5nIGNuYW1lKQogICAgICAgICAgICB0aHJvd3MgVHlwZVNpZ25hdHVyZS5TaWduYXR1cmVFeGNlcHRpb24sIFV0aWwuRXhpdCB7CiAgICAgICAgZG9uZUhhbmRsZVR5cGVzICA9IG5ldyBIYXNoU2V0PD4oKTsKICAgICAgICAvKiBUaGUgZm9sbG93aW5nIGhhbmRsZSB0eXBlcyBhcmUgcHJlZGVmaW5lZCBpbiAidHlwZWRlZnMuaCIuIFN1cHByZXNzCiAgICAgICAgICAgaW5jbHVzaW9uIGluIHRoZSBvdXRwdXQgYnkgZ2VuZXJhdGluZyB0aGVtICJpbnRvIHRoZSBibHVlIiBoZXJlLiAqLwogICAgICAgIGdlbkhhbmRsZVR5cGUobnVsbCwgImphdmEubGFuZy5DbGFzcyIpOwogICAgICAgIGdlbkhhbmRsZVR5cGUobnVsbCwgImphdmEubGFuZy5DbGFzc0xvYWRlciIpOwogICAgICAgIGdlbkhhbmRsZVR5cGUobnVsbCwgImphdmEubGFuZy5PYmplY3QiKTsKICAgICAgICBnZW5IYW5kbGVUeXBlKG51bGwsICJqYXZhLmxhbmcuU3RyaW5nIik7CiAgICAgICAgZ2VuSGFuZGxlVHlwZShudWxsLCAiamF2YS5sYW5nLlRocmVhZCIpOwogICAgICAgIGdlbkhhbmRsZVR5cGUobnVsbCwgImphdmEubGFuZy5UaHJlYWRHcm91cCIpOwogICAgICAgIGdlbkhhbmRsZVR5cGUobnVsbCwgImphdmEubGFuZy5UaHJvd2FibGUiKTsKCiAgICAgICAgcHcucHJpbnRsbigiLyogTExOSSBIZWFkZXIgZm9yIGNsYXNzICIgKyBjbGF6ei5nZXRRdWFsaWZpZWROYW1lKCkgKyAiICovIiArIGxpbmVTZXApOwogICAgICAgIHB3LnByaW50bG4oIiNpZm5kZWYgX0luY2x1ZGVkXyIgKyBjbmFtZSk7CiAgICAgICAgcHcucHJpbnRsbigiI2RlZmluZSBfSW5jbHVkZWRfIiArIGNuYW1lKTsKICAgICAgICBwdy5wcmludGxuKCIjaW5jbHVkZSBcInR5cGVkZWZzLmhcIiIpOwogICAgICAgIHB3LnByaW50bG4oIiNpbmNsdWRlIFwibGxuaS5oXCIiKTsKICAgICAgICBwdy5wcmludGxuKCIjaW5jbHVkZSBcImpuaS5oXCIiICsgbGluZVNlcCk7CgogICAgICAgIGZvcndhcmREZWNscyhwdywgY2xhenopOwogICAgICAgIHN0cnVjdFNlY3Rpb25Gb3JDbGFzcyhwdywgY2xhenosIGNuYW1lKTsKICAgICAgICBtZXRob2RTZWN0aW9uRm9yQ2xhc3MocHcsIGNsYXp6LCBjbmFtZSk7CiAgICAgICAgcHcucHJpbnRsbigiI2VuZGlmIik7CiAgICB9CgogICAgcHJvdGVjdGVkIHZvaWQgZ2VuSGFuZGxlVHlwZShQcmludFdyaXRlciBwdywgU3RyaW5nIGNsYXp6bmFtZSkgewogICAgICAgIFN0cmluZyBjbmFtZSA9IG1hbmdsZUNsYXNzTmFtZShjbGF6em5hbWUpOwogICAgICAgIGlmICghZG9uZUhhbmRsZVR5cGVzLmNvbnRhaW5zKGNuYW1lKSkgewogICAgICAgICAgICBkb25lSGFuZGxlVHlwZXMuYWRkKGNuYW1lKTsKICAgICAgICAgICAgaWYgKHB3ICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIHB3LnByaW50bG4oIiNpZm5kZWYgREVGSU5FRF8iICsgY25hbWUpOwogICAgICAgICAgICAgICAgcHcucHJpbnRsbigiICAgICNkZWZpbmUgREVGSU5FRF8iICsgY25hbWUpOwogICAgICAgICAgICAgICAgcHcucHJpbnRsbigiICAgIEdFTl9IQU5ETEVfVFlQRVMoIiArIGNuYW1lICsgIik7Iik7CiAgICAgICAgICAgICAgICBwdy5wcmludGxuKCIjZW5kaWYiICsgbGluZVNlcCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgcHJvdGVjdGVkIFN0cmluZyBtYW5nbGVDbGFzc05hbWUoU3RyaW5nIHMpIHsKICAgICAgICByZXR1cm4gcy5yZXBsYWNlKCcuJywgJ18nKQogICAgICAgICAgICAucmVwbGFjZSgnLycsICdfJykKICAgICAgICAgICAgLnJlcGxhY2UoaW5uZXJEZWxpbSwgJ18nKTsKICAgIH0KCiAgICBwcm90ZWN0ZWQgdm9pZCBmb3J3YXJkRGVjbHMoUHJpbnRXcml0ZXIgcHcsIFR5cGVFbGVtZW50IGNsYXp6KQogICAgICAgICAgICB0aHJvd3MgVHlwZVNpZ25hdHVyZS5TaWduYXR1cmVFeGNlcHRpb24gewogICAgICAgIFR5cGVFbGVtZW50IG9iamVjdCA9IGVsZW1zLmdldFR5cGVFbGVtZW50KCJqYXZhLmxhbmcuT2JqZWN0Iik7CiAgICAgICAgaWYgKGNsYXp6LmVxdWFscyhvYmplY3QpKQogICAgICAgICAgICByZXR1cm47CgogICAgICAgIGdlbkhhbmRsZVR5cGUocHcsIGNsYXp6LmdldFF1YWxpZmllZE5hbWUoKS50b1N0cmluZygpKTsKICAgICAgICBUeXBlRWxlbWVudCBzdXBlckNsYXNzID0gKFR5cGVFbGVtZW50KSAodHlwZXMuYXNFbGVtZW50KGNsYXp6LmdldFN1cGVyY2xhc3MoKSkpOwoKICAgICAgICBpZiAoc3VwZXJDbGFzcyAhPSBudWxsKSB7CiAgICAgICAgICAgIFN0cmluZyBzdXBlckNsYXNzTmFtZSA9IHN1cGVyQ2xhc3MuZ2V0UXVhbGlmaWVkTmFtZSgpLnRvU3RyaW5nKCk7CiAgICAgICAgICAgIGZvcndhcmREZWNscyhwdywgc3VwZXJDbGFzcyk7CiAgICAgICAgfQoKICAgICAgICBmb3IgKFZhcmlhYmxlRWxlbWVudCBmaWVsZDogZmllbGRzKSB7CgogICAgICAgICAgICBpZiAoIWZpZWxkLmdldE1vZGlmaWVycygpLmNvbnRhaW5zKE1vZGlmaWVyLlNUQVRJQykpIHsKICAgICAgICAgICAgICAgIFR5cGVNaXJyb3IgdCA9IHR5cGVzLmVyYXN1cmUoZmllbGQuYXNUeXBlKCkpOwogICAgICAgICAgICAgICAgVHlwZVNpZ25hdHVyZSBuZXdUeXBlU2lnID0gbmV3IFR5cGVTaWduYXR1cmUoZWxlbXMpOwogICAgICAgICAgICAgICAgU3RyaW5nIHRuYW1lID0gbmV3VHlwZVNpZy5xdWFsaWZpZWRUeXBlTmFtZSh0KTsKICAgICAgICAgICAgICAgIFN0cmluZyBzaWcgPSBuZXdUeXBlU2lnLmdldFR5cGVTaWduYXR1cmUodG5hbWUpOwoKICAgICAgICAgICAgICAgIGlmIChzaWcuY2hhckF0KDApICE9ICdbJykKICAgICAgICAgICAgICAgICAgICBmb3J3YXJkRGVjbHNGcm9tU2lnKHB3LCBzaWcpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBmb3IgKEV4ZWN1dGFibGVFbGVtZW50IG1ldGhvZDogbWV0aG9kcykgewoKICAgICAgICAgICAgaWYgKG1ldGhvZC5nZXRNb2RpZmllcnMoKS5jb250YWlucyhNb2RpZmllci5OQVRJVkUpKSB7CiAgICAgICAgICAgICAgICBUeXBlTWlycm9yIHJldFR5cGUgPSB0eXBlcy5lcmFzdXJlKG1ldGhvZC5nZXRSZXR1cm5UeXBlKCkpOwogICAgICAgICAgICAgICAgU3RyaW5nIHR5cGVzaWcgPSBzaWduYXR1cmUobWV0aG9kKTsKICAgICAgICAgICAgICAgIFR5cGVTaWduYXR1cmUgbmV3VHlwZVNpZyA9IG5ldyBUeXBlU2lnbmF0dXJlKGVsZW1zKTsKICAgICAgICAgICAgICAgIFN0cmluZyBzaWcgPSBuZXdUeXBlU2lnLmdldFR5cGVTaWduYXR1cmUodHlwZXNpZywgcmV0VHlwZSk7CgogICAgICAgICAgICAgICAgaWYgKHNpZy5jaGFyQXQoMCkgIT0gJ1snKQogICAgICAgICAgICAgICAgICAgIGZvcndhcmREZWNsc0Zyb21TaWcocHcsIHNpZyk7CgogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIHByb3RlY3RlZCB2b2lkIGZvcndhcmREZWNsc0Zyb21TaWcoUHJpbnRXcml0ZXIgcHcsIFN0cmluZyBzaWcpIHsKICAgICAgICBpbnQgICAgbGVuID0gc2lnLmxlbmd0aCgpOwogICAgICAgIGludCAgICBpICAgPSBzaWcuY2hhckF0KDApID09ICcoJyA/IDEgOiAwOwoKICAgICAgICAvKiBTa2lwIHRoZSBpbml0aWFsICIoIi4gKi8KICAgICAgICB3aGlsZSAoaSA8IGxlbikgewogICAgICAgICAgICBpZiAoc2lnLmNoYXJBdChpKSA9PSAnTCcpIHsKICAgICAgICAgICAgICAgIGludCBqID0gaSArIDE7CiAgICAgICAgICAgICAgICB3aGlsZSAoc2lnLmNoYXJBdChqKSAhPSAnOycpIGorKzsKICAgICAgICAgICAgICAgIGdlbkhhbmRsZVR5cGUocHcsIHNpZy5zdWJzdHJpbmcoaSArIDEsIGopKTsKICAgICAgICAgICAgICAgIGkgPSBqICsgMTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGkrKzsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBwcm90ZWN0ZWQgdm9pZCBzdHJ1Y3RTZWN0aW9uRm9yQ2xhc3MoUHJpbnRXcml0ZXIgcHcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVHlwZUVsZW1lbnQgamNsYXp6LCBTdHJpbmcgY25hbWUpIHsKCiAgICAgICAgU3RyaW5nIGpuYW1lID0gamNsYXp6LmdldFF1YWxpZmllZE5hbWUoKS50b1N0cmluZygpOwoKICAgICAgICBpZiAoY25hbWUuZXF1YWxzKCJqYXZhX2xhbmdfT2JqZWN0IikpIHsKICAgICAgICAgICAgcHcucHJpbnRsbigiLyogc3RydWN0IGphdmFfbGFuZ19PYmplY3QgaXMgZGVmaW5lZCBpbiB0eXBlZGVmcy5oLiAqLyIpOwogICAgICAgICAgICBwdy5wcmludGxuKCk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgcHcucHJpbnRsbigiI2lmICFkZWZpbmVkKF9faTM4NikiKTsKICAgICAgICBwdy5wcmludGxuKCIjcHJhZ21hIHBhY2soNCkiKTsKICAgICAgICBwdy5wcmludGxuKCIjZW5kaWYiKTsKICAgICAgICBwdy5wcmludGxuKCk7CiAgICAgICAgcHcucHJpbnRsbigic3RydWN0ICIgKyBjbmFtZSArICIgeyIpOwogICAgICAgIHB3LnByaW50bG4oIiAgICBPYmpIZWFkZXIgaDsiKTsKICAgICAgICBwdy5wcmludChmaWVsZERlZnMoamNsYXp6LCBjbmFtZSkpOwoKICAgICAgICBpZiAoam5hbWUuZXF1YWxzKCJqYXZhLmxhbmcuQ2xhc3MiKSkKICAgICAgICAgICAgcHcucHJpbnRsbigiICAgIENsYXNzICpMTE5JX21hc2soY0NsYXNzKTsiICsKICAgICAgICAgICAgICAgICAgICAgICAiICAvKiBGYWtlIGZpZWxkOyBkb24ndCBhY2Nlc3MgKHNlZSBvb2JqLmgpICovIik7CiAgICAgICAgcHcucHJpbnRsbigifTsiICsgbGluZVNlcCArIGxpbmVTZXAgKyAiI3ByYWdtYSBwYWNrKCkiKTsKICAgICAgICBwdy5wcmludGxuKCk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIEZpZWxkRGVmc1JlcyB7CiAgICAgICAgcHVibGljIFN0cmluZyBjbGFzc05hbWU7ICAgICAgICAvKiBOYW1lIG9mIHRoZSBjdXJyZW50IGNsYXNzLiAqLwogICAgICAgIHB1YmxpYyBGaWVsZERlZnNSZXMgcGFyZW50OwogICAgICAgIHB1YmxpYyBTdHJpbmcgczsKICAgICAgICBwdWJsaWMgaW50IGJ5dGVTaXplOwogICAgICAgIHB1YmxpYyBib29sZWFuIGJvdHRvbU1vc3Q7CiAgICAgICAgcHVibGljIGJvb2xlYW4gcHJpbnRlZE9uZSA9IGZhbHNlOwoKICAgICAgICBGaWVsZERlZnNSZXMoVHlwZUVsZW1lbnQgY2xhenosIEZpZWxkRGVmc1JlcyBwYXJlbnQsIGJvb2xlYW4gYm90dG9tTW9zdCkgewogICAgICAgICAgICB0aGlzLmNsYXNzTmFtZSA9IGNsYXp6LmdldFF1YWxpZmllZE5hbWUoKS50b1N0cmluZygpOwogICAgICAgICAgICB0aGlzLnBhcmVudCA9IHBhcmVudDsKICAgICAgICAgICAgdGhpcy5ib3R0b21Nb3N0ID0gYm90dG9tTW9zdDsKICAgICAgICAgICAgaW50IGJ5dGVTaXplID0gMDsKICAgICAgICAgICAgaWYgKHBhcmVudCA9PSBudWxsKSB0aGlzLnMgPSAiIjsKICAgICAgICAgICAgZWxzZSB0aGlzLnMgPSBwYXJlbnQuczsKICAgICAgICB9CiAgICB9CgogICAgLyogUmV0dXJucyAidHJ1ZSIgaWZmIGFkZGVkIGEgZmllbGQuICovCiAgICBwcml2YXRlIGJvb2xlYW4gZG9GaWVsZChGaWVsZERlZnNSZXMgcmVzLCBWYXJpYWJsZUVsZW1lbnQgZmllbGQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgY25hbWUsIGJvb2xlYW4gcGFkV29yZCkgewoKICAgICAgICBTdHJpbmcgZmllbGREZWYgPSBhZGRTdHJ1Y3RNZW1iZXIoZmllbGQsIGNuYW1lLCBwYWRXb3JkKTsKICAgICAgICBpZiAoZmllbGREZWYgIT0gbnVsbCkgewogICAgICAgICAgICBpZiAoIXJlcy5wcmludGVkT25lKSB7IC8qIGFkZCBzZXBhcmF0b3IgKi8KICAgICAgICAgICAgICAgIGlmIChyZXMuYm90dG9tTW9zdCkgewogICAgICAgICAgICAgICAgICAgIGlmIChyZXMucy5sZW5ndGgoKSAhPSAwKQogICAgICAgICAgICAgICAgICAgICAgICByZXMucyA9IHJlcy5zICsgIiAgICAvKiBsb2NhbCBtZW1iZXJzOiAqLyIgKyBsaW5lU2VwOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICByZXMucyA9IHJlcy5zICsgIiAgICAvKiBpbmhlcml0ZWQgbWVtYmVycyBmcm9tICIgKwogICAgICAgICAgICAgICAgICAgICAgICByZXMuY2xhc3NOYW1lICsgIjogKi8iICsgbGluZVNlcDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJlcy5wcmludGVkT25lID0gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXMucyA9IHJlcy5zICsgZmllbGREZWY7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgLy8gT3RoZXJ3aXNlLgogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICBwcml2YXRlIGludCBkb1R3b1dvcmRGaWVsZHMoRmllbGREZWZzUmVzIHJlcywgVHlwZUVsZW1lbnQgY2xhenosCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IG9mZnNldCwgU3RyaW5nIGNuYW1lLCBib29sZWFuIHBhZFdvcmQpIHsKICAgICAgICBib29sZWFuIGZpcnN0ID0gdHJ1ZTsKICAgICAgICBMaXN0PFZhcmlhYmxlRWxlbWVudD4gZmllbGRzID0gRWxlbWVudEZpbHRlci5maWVsZHNJbihjbGF6ei5nZXRFbmNsb3NlZEVsZW1lbnRzKCkpOwoKICAgICAgICBmb3IgKFZhcmlhYmxlRWxlbWVudCBmaWVsZDogZmllbGRzKSB7CiAgICAgICAgICAgIFR5cGVLaW5kIHRrID0gZmllbGQuYXNUeXBlKCkuZ2V0S2luZCgpOwogICAgICAgICAgICBib29sZWFuIHR3b1dvcmRzID0gKHRrID09IFR5cGVLaW5kLkxPTkcgfHwgdGsgPT0gVHlwZUtpbmQuRE9VQkxFKTsKICAgICAgICAgICAgaWYgKHR3b1dvcmRzICYmIGRvRmllbGQocmVzLCBmaWVsZCwgY25hbWUsIGZpcnN0ICYmIHBhZFdvcmQpKSB7CiAgICAgICAgICAgICAgICBvZmZzZXQgKz0gODsgZmlyc3QgPSBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gb2Zmc2V0OwogICAgfQoKICAgIFN0cmluZyBmaWVsZERlZnMoVHlwZUVsZW1lbnQgY2xhenosIFN0cmluZyBjbmFtZSkgewogICAgICAgIEZpZWxkRGVmc1JlcyByZXMgPSBmaWVsZERlZnMoY2xhenosIGNuYW1lLCB0cnVlKTsKICAgICAgICByZXR1cm4gcmVzLnM7CiAgICB9CgogICAgRmllbGREZWZzUmVzIGZpZWxkRGVmcyhUeXBlRWxlbWVudCBjbGF6eiwgU3RyaW5nIGNuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBib3R0b21Nb3N0KXsKICAgICAgICBGaWVsZERlZnNSZXMgcmVzOwogICAgICAgIGludCBvZmZzZXQ7CiAgICAgICAgYm9vbGVhbiBkaWRUd29Xb3JkRmllbGRzID0gZmFsc2U7CgogICAgICAgIFR5cGVFbGVtZW50IHN1cGVyY2xhenogPSAoVHlwZUVsZW1lbnQpIHR5cGVzLmFzRWxlbWVudChjbGF6ei5nZXRTdXBlcmNsYXNzKCkpOwoKICAgICAgICBpZiAoc3VwZXJjbGF6eiAhPSBudWxsKSB7CiAgICAgICAgICAgIFN0cmluZyBzdXBlcm5hbWUgPSBzdXBlcmNsYXp6LmdldFF1YWxpZmllZE5hbWUoKS50b1N0cmluZygpOwogICAgICAgICAgICByZXMgPSBuZXcgRmllbGREZWZzUmVzKGNsYXp6LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkRGVmcyhzdXBlcmNsYXp6LCBjbmFtZSwgZmFsc2UpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvdHRvbU1vc3QpOwogICAgICAgICAgICBvZmZzZXQgPSByZXMucGFyZW50LmJ5dGVTaXplOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJlcyA9IG5ldyBGaWVsZERlZnNSZXMoY2xhenosIG51bGwsIGJvdHRvbU1vc3QpOwogICAgICAgICAgICBvZmZzZXQgPSAwOwogICAgICAgIH0KCiAgICAgICAgTGlzdDxWYXJpYWJsZUVsZW1lbnQ+IGZpZWxkcyA9IEVsZW1lbnRGaWx0ZXIuZmllbGRzSW4oY2xhenouZ2V0RW5jbG9zZWRFbGVtZW50cygpKTsKCiAgICAgICAgZm9yIChWYXJpYWJsZUVsZW1lbnQgZmllbGQ6IGZpZWxkcykgewoKICAgICAgICAgICAgaWYgKGRvdWJsZUFsaWduICYmICFkaWRUd29Xb3JkRmllbGRzICYmIChvZmZzZXQgJSA4KSA9PSAwKSB7CiAgICAgICAgICAgICAgICBvZmZzZXQgPSBkb1R3b1dvcmRGaWVsZHMocmVzLCBjbGF6eiwgb2Zmc2V0LCBjbmFtZSwgZmFsc2UpOwogICAgICAgICAgICAgICAgZGlkVHdvV29yZEZpZWxkcyA9IHRydWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIFR5cGVLaW5kIHRrID0gZmllbGQuYXNUeXBlKCkuZ2V0S2luZCgpOwogICAgICAgICAgICBib29sZWFuIHR3b1dvcmRzID0gKHRrID09IFR5cGVLaW5kLkxPTkcgfHwgdGsgPT0gVHlwZUtpbmQuRE9VQkxFKTsKCiAgICAgICAgICAgIGlmICghZG91YmxlQWxpZ24gfHwgIXR3b1dvcmRzKSB7CiAgICAgICAgICAgICAgICBpZiAoZG9GaWVsZChyZXMsIGZpZWxkLCBjbmFtZSwgZmFsc2UpKSBvZmZzZXQgKz0gNDsKICAgICAgICAgICAgfQoKICAgICAgICB9CgogICAgICAgIGlmIChkb3VibGVBbGlnbiAmJiAhZGlkVHdvV29yZEZpZWxkcykgewogICAgICAgICAgICBpZiAoKG9mZnNldCAlIDgpICE9IDApIG9mZnNldCArPSA0OwogICAgICAgICAgICBvZmZzZXQgPSBkb1R3b1dvcmRGaWVsZHMocmVzLCBjbGF6eiwgb2Zmc2V0LCBjbmFtZSwgdHJ1ZSk7CiAgICAgICAgfQoKICAgICAgICByZXMuYnl0ZVNpemUgPSBvZmZzZXQ7CiAgICAgICAgcmV0dXJuIHJlczsKICAgIH0KCiAgICAvKiBPVkVSUklERTogVGhpcyBtZXRob2QgaGFuZGxlcyBpbnN0YW5jZSBmaWVsZHMgKi8KICAgIHByb3RlY3RlZCBTdHJpbmcgYWRkU3RydWN0TWVtYmVyKFZhcmlhYmxlRWxlbWVudCBtZW1iZXIsIFN0cmluZyBjbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gcGFkV29yZCkgewogICAgICAgIFN0cmluZyByZXMgPSBudWxsOwoKICAgICAgICBpZiAobWVtYmVyLmdldE1vZGlmaWVycygpLmNvbnRhaW5zKE1vZGlmaWVyLlNUQVRJQykpIHsKICAgICAgICAgICAgcmVzID0gYWRkU3RhdGljU3RydWN0TWVtYmVyKG1lbWJlciwgY25hbWUpOwogICAgICAgICAgICAvLyAgIGlmIChyZXMgPT0gbnVsbCkgLyogSk5JIGRpZG4ndCBoYW5kbGUgaXQsIHByaW50IGNvbW1lbnQuICovCiAgICAgICAgICAgIC8vICByZXMgPSAiICAgIC8qIEluYWNjZXNzaWJsZSBzdGF0aWM6ICIgKyBtZW1iZXIgKyAiICovIiArIGxpbmVTZXA7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgVHlwZU1pcnJvciBtdCA9IHR5cGVzLmVyYXN1cmUobWVtYmVyLmFzVHlwZSgpKTsKICAgICAgICAgICAgaWYgKHBhZFdvcmQpIHJlcyA9ICIgICAgamF2YV9pbnQgcGFkV29yZCIgKyBwYWRGaWVsZE51bSsrICsgIjsiICsgbGluZVNlcDsKICAgICAgICAgICAgcmVzID0gIiAgICAiICsgbGxuaVR5cGUobXQsIGZhbHNlLCBmYWxzZSkgKyAiICIgKyBsbG5pRmllbGROYW1lKG1lbWJlcik7CiAgICAgICAgICAgIGlmIChpc0xvbmdPckRvdWJsZShtdCkpIHJlcyA9IHJlcyArICJbMl0iOwogICAgICAgICAgICByZXMgPSByZXMgKyAiOyIgKyBsaW5lU2VwOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzOwogICAgfQoKICAgIHN0YXRpYyBwcml2YXRlIGZpbmFsIGJvb2xlYW4gaXNXaW5kb3dzID0KICAgICAgICBTeXN0ZW0uZ2V0UHJvcGVydHkoIm9zLm5hbWUiKS5zdGFydHNXaXRoKCJXaW5kb3dzIik7CgogICAgLyoKICAgICAqIFRoaXMgbWV0aG9kIG9ubHkgaGFuZGxlcyBzdGF0aWMgZmluYWwgZmllbGRzLgogICAgICovCiAgICBwcm90ZWN0ZWQgU3RyaW5nIGFkZFN0YXRpY1N0cnVjdE1lbWJlcihWYXJpYWJsZUVsZW1lbnQgZmllbGQsIFN0cmluZyBjbmFtZSkgewogICAgICAgIFN0cmluZyByZXMgPSBudWxsOwogICAgICAgIE9iamVjdCBleHAgPSBudWxsOwoKICAgICAgICBpZiAoIWZpZWxkLmdldE1vZGlmaWVycygpLmNvbnRhaW5zKE1vZGlmaWVyLlNUQVRJQykpCiAgICAgICAgICAgIHJldHVybiByZXM7CiAgICAgICAgaWYgKCFmaWVsZC5nZXRNb2RpZmllcnMoKS5jb250YWlucyhNb2RpZmllci5GSU5BTCkpCiAgICAgICAgICAgIHJldHVybiByZXM7CgogICAgICAgIGV4cCA9IGZpZWxkLmdldENvbnN0YW50VmFsdWUoKTsKCiAgICAgICAgaWYgKGV4cCAhPSBudWxsKSB7CiAgICAgICAgICAgIC8qIENvbnN0YW50LiAqLwoKICAgICAgICAgICAgU3RyaW5nICAgICBjbiAgICAgPSBjbmFtZSArICJfIiArIGZpZWxkLmdldFNpbXBsZU5hbWUoKTsKICAgICAgICAgICAgU3RyaW5nICAgICBzdWZmaXggPSBudWxsOwogICAgICAgICAgICBsb25nICAgICAgICAgICB2YWwgPSAwOwogICAgICAgICAgICAvKiBDYW4gb25seSBoYW5kbGUgaW50LCBsb25nLCBmbG9hdCwgYW5kIGRvdWJsZSBmaWVsZHMuICovCiAgICAgICAgICAgIGlmIChleHAgaW5zdGFuY2VvZiBCeXRlCiAgICAgICAgICAgICAgICB8fCBleHAgaW5zdGFuY2VvZiBTaG9ydAogICAgICAgICAgICAgICAgfHwgZXhwIGluc3RhbmNlb2YgSW50ZWdlcikgewogICAgICAgICAgICAgICAgc3VmZml4ID0gIkwiOwogICAgICAgICAgICAgICAgdmFsID0gKChOdW1iZXIpZXhwKS5pbnRWYWx1ZSgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKGV4cCBpbnN0YW5jZW9mIExvbmcpIHsKICAgICAgICAgICAgICAgIC8vIFZpc3VhbCBDKysgc3VwcG9ydHMgdGhlIGk2NCBzdWZmaXgsIG5vdCBMTAogICAgICAgICAgICAgICAgc3VmZml4ID0gaXNXaW5kb3dzID8gImk2NCIgOiAiTEwiOwogICAgICAgICAgICAgICAgdmFsID0gKChMb25nKWV4cCkubG9uZ1ZhbHVlKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAoZXhwIGluc3RhbmNlb2YgRmxvYXQpICBzdWZmaXggPSAiZiI7CiAgICAgICAgICAgIGVsc2UgaWYgKGV4cCBpbnN0YW5jZW9mIERvdWJsZSkgc3VmZml4ID0gIiI7CiAgICAgICAgICAgIGVsc2UgaWYgKGV4cCBpbnN0YW5jZW9mIENoYXJhY3RlcikgewogICAgICAgICAgICAgICAgc3VmZml4ID0gIkwiOwogICAgICAgICAgICAgICAgQ2hhcmFjdGVyIGNoID0gKENoYXJhY3RlcikgZXhwOwogICAgICAgICAgICAgICAgdmFsID0gKChpbnQpIGNoKSAmIDB4ZmZmZjsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoc3VmZml4ICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIC8vIFNvbWUgY29tcGlsZXJzIHdpbGwgZ2VuZXJhdGUgYSBzcHVyaW91cyB3YXJuaW5nCiAgICAgICAgICAgICAgICAvLyBmb3IgdGhlIGludGVnZXIgY29uc3RhbnRzIGZvciBJbnRlZ2VyLk1JTl9WQUxVRQogICAgICAgICAgICAgICAgLy8gYW5kIExvbmcuTUlOX1ZBTFVFIHNvIHdlIGhhbmRsZSB0aGVtIHNwZWNpYWxseS4KICAgICAgICAgICAgICAgIGlmICgoc3VmZml4LmVxdWFscygiTCIpICYmICh2YWwgPT0gSW50ZWdlci5NSU5fVkFMVUUpKSB8fAogICAgICAgICAgICAgICAgICAgIChzdWZmaXguZXF1YWxzKCJMTCIpICYmICh2YWwgPT0gTG9uZy5NSU5fVkFMVUUpKSkgewogICAgICAgICAgICAgICAgICAgIHJlcyA9ICIgICAgI3VuZGVmICAiICsgY24gKyBsaW5lU2VwCiAgICAgICAgICAgICAgICAgICAgICAgICsgIiAgICAjZGVmaW5lICIgKyBjbgogICAgICAgICAgICAgICAgICAgICAgICArICIgKCIgKyAodmFsICsgMSkgKyBzdWZmaXggKyAiLTEpIiArIGxpbmVTZXA7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHN1ZmZpeC5lcXVhbHMoIkwiKSB8fCBzdWZmaXguZW5kc1dpdGgoIkxMIikpIHsKICAgICAgICAgICAgICAgICAgICByZXMgPSAiICAgICN1bmRlZiAgIiArIGNuICsgbGluZVNlcAogICAgICAgICAgICAgICAgICAgICAgICArICIgICAgI2RlZmluZSAiICsgY24gKyAiICIgKyB2YWwgKyBzdWZmaXggKyBsaW5lU2VwOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICByZXMgPSAiICAgICN1bmRlZiAgIiArIGNuICsgbGluZVNlcAogICAgICAgICAgICAgICAgICAgICAgICArICIgICAgI2RlZmluZSAiICsgY24gKyAiICIgKyBleHAgKyBzdWZmaXggKyBsaW5lU2VwOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXM7CiAgICB9CgogICAgcHJvdGVjdGVkIHZvaWQgbWV0aG9kU2VjdGlvbkZvckNsYXNzKFByaW50V3JpdGVyIHB3LAogICAgICAgICAgICBUeXBlRWxlbWVudCBjbGF6eiwgU3RyaW5nIGNuYW1lKQogICAgICAgICAgICB0aHJvd3MgVHlwZVNpZ25hdHVyZS5TaWduYXR1cmVFeGNlcHRpb24sIFV0aWwuRXhpdCB7CiAgICAgICAgU3RyaW5nIG1ldGhvZHMgPSBtZXRob2REZWNscyhjbGF6eiwgY25hbWUpOwoKICAgICAgICBpZiAobWV0aG9kcy5sZW5ndGgoKSAhPSAwKSB7CiAgICAgICAgICAgIHB3LnByaW50bG4oIi8qIE5hdGl2ZSBtZXRob2QgZGVjbGFyYXRpb25zOiAqLyIgKyBsaW5lU2VwKTsKICAgICAgICAgICAgcHcucHJpbnRsbigiI2lmZGVmIF9fY3BsdXNwbHVzIik7CiAgICAgICAgICAgIHB3LnByaW50bG4oImV4dGVybiBcIkNcIiB7Iik7CiAgICAgICAgICAgIHB3LnByaW50bG4oIiNlbmRpZiIgKyBsaW5lU2VwKTsKICAgICAgICAgICAgcHcucHJpbnRsbihtZXRob2RzKTsKICAgICAgICAgICAgcHcucHJpbnRsbigiI2lmZGVmIF9fY3BsdXNwbHVzIik7CiAgICAgICAgICAgIHB3LnByaW50bG4oIn0iKTsKICAgICAgICAgICAgcHcucHJpbnRsbigiI2VuZGlmIik7CiAgICAgICAgfQogICAgfQoKICAgIHByb3RlY3RlZCBTdHJpbmcgbWV0aG9kRGVjbHMoVHlwZUVsZW1lbnQgY2xhenosIFN0cmluZyBjbmFtZSkKICAgICAgICAgICAgdGhyb3dzIFR5cGVTaWduYXR1cmUuU2lnbmF0dXJlRXhjZXB0aW9uLCBVdGlsLkV4aXQgewoKICAgICAgICBTdHJpbmcgcmVzID0gIiI7CiAgICAgICAgZm9yIChFeGVjdXRhYmxlRWxlbWVudCBtZXRob2Q6IG1ldGhvZHMpIHsKICAgICAgICAgICAgaWYgKG1ldGhvZC5nZXRNb2RpZmllcnMoKS5jb250YWlucyhNb2RpZmllci5OQVRJVkUpKQogICAgICAgICAgICAgICAgcmVzID0gcmVzICsgbWV0aG9kRGVjbChtZXRob2QsIGNsYXp6LCBjbmFtZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXM7CiAgICB9CgogICAgcHJvdGVjdGVkIFN0cmluZyBtZXRob2REZWNsKEV4ZWN1dGFibGVFbGVtZW50IG1ldGhvZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUeXBlRWxlbWVudCBjbGF6eiwgU3RyaW5nIGNuYW1lKQogICAgICAgICAgICB0aHJvd3MgVHlwZVNpZ25hdHVyZS5TaWduYXR1cmVFeGNlcHRpb24sIFV0aWwuRXhpdCB7CiAgICAgICAgU3RyaW5nIHJlcyA9IG51bGw7CgogICAgICAgIFR5cGVNaXJyb3IgcmV0VHlwZSA9IHR5cGVzLmVyYXN1cmUobWV0aG9kLmdldFJldHVyblR5cGUoKSk7CiAgICAgICAgU3RyaW5nIHR5cGVzaWcgPSBzaWduYXR1cmUobWV0aG9kKTsKICAgICAgICBUeXBlU2lnbmF0dXJlIG5ld1R5cGVTaWcgPSBuZXcgVHlwZVNpZ25hdHVyZShlbGVtcyk7CiAgICAgICAgU3RyaW5nIHNpZyA9IG5ld1R5cGVTaWcuZ2V0VHlwZVNpZ25hdHVyZSh0eXBlc2lnLCByZXRUeXBlKTsKICAgICAgICBib29sZWFuIGxvbmdOYW1lID0gbmVlZExvbmdOYW1lKG1ldGhvZCwgY2xhenopOwoKICAgICAgICBpZiAoc2lnLmNoYXJBdCgwKSAhPSAnKCcpCiAgICAgICAgICAgIHV0aWwuZXJyb3IoImludmFsaWQubWV0aG9kLnNpZ25hdHVyZSIsIHNpZyk7CgoKICAgICAgICByZXMgPSAiSk5JRVhQT1JUICIgKyBqbmlUeXBlKHJldFR5cGUpICsgIiBKTklDQUxMIiArIGxpbmVTZXAgKyBqbmlNZXRob2ROYW1lKG1ldGhvZCwgY25hbWUsIGxvbmdOYW1lKQogICAgICAgICAgICArICIoSk5JRW52ICosICIgKyBjUmN2ckRlY2wobWV0aG9kLCBjbmFtZSk7CiAgICAgICAgTGlzdDw/IGV4dGVuZHMgVmFyaWFibGVFbGVtZW50PiBwYXJhbXMgPSBtZXRob2QuZ2V0UGFyYW1ldGVycygpOwogICAgICAgIExpc3Q8VHlwZU1pcnJvcj4gYXJnVHlwZXMgPSBuZXcgQXJyYXlMaXN0PD4oKTsKICAgICAgICBmb3IgKFZhcmlhYmxlRWxlbWVudCBwOiBwYXJhbXMpewogICAgICAgICAgICBhcmdUeXBlcy5hZGQodHlwZXMuZXJhc3VyZShwLmFzVHlwZSgpKSk7CiAgICAgICAgfQoKICAgICAgICAvKiBJdCB3b3VsZCBoYXZlIGJlZW4gbmljZSB0byBpbmNsdWRlIHRoZSBhcmd1bWVudCBuYW1lcyBpbiB0aGUKICAgICAgICAgICBkZWNsYXJhdGlvbiwgYnV0IHRoZXJlIHNlZW1zIHRvIGJlIGEgYnVnIGluIHRoZSAiQmluYXJ5RmllbGQiCiAgICAgICAgICAgY2xhc3MsIGNhdXNpbmcgdGhlIGdldEFyZ3VtZW50cygpIG1ldGhvZCB0byByZXR1cm4gIm51bGwiIGZvcgogICAgICAgICAgIG1vc3QgKG5vbi1jb25zdHJ1Y3RvcikgbWV0aG9kcy4gKi8KICAgICAgICBmb3IgKFR5cGVNaXJyb3IgYXJnVHlwZTogYXJnVHlwZXMpCiAgICAgICAgICAgIHJlcyA9IHJlcyArICIsICIgKyBqbmlUeXBlKGFyZ1R5cGUpOwogICAgICAgIHJlcyA9IHJlcyArICIpOyIgKyBsaW5lU2VwOwogICAgICAgIHJldHVybiByZXM7CiAgICB9CgogICAgcHJvdGVjdGVkIGZpbmFsIGJvb2xlYW4gbmVlZExvbmdOYW1lKEV4ZWN1dGFibGVFbGVtZW50IG1ldGhvZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUeXBlRWxlbWVudCBjbGF6eikgewogICAgICAgIE5hbWUgbWV0aG9kTmFtZSA9IG1ldGhvZC5nZXRTaW1wbGVOYW1lKCk7CiAgICAgICAgZm9yIChFeGVjdXRhYmxlRWxlbWVudCBtZW1iZXJNZXRob2Q6IG1ldGhvZHMpIHsKICAgICAgICAgICAgaWYgKChtZW1iZXJNZXRob2QgIT0gbWV0aG9kKSAmJgogICAgICAgICAgICAgICAgbWVtYmVyTWV0aG9kLmdldE1vZGlmaWVycygpLmNvbnRhaW5zKE1vZGlmaWVyLk5BVElWRSkgJiYKICAgICAgICAgICAgICAgICAgICAobWV0aG9kTmFtZS5lcXVhbHMobWVtYmVyTWV0aG9kLmdldFNpbXBsZU5hbWUoKSkpKQogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICBwcm90ZWN0ZWQgZmluYWwgU3RyaW5nIGpuaU1ldGhvZE5hbWUoRXhlY3V0YWJsZUVsZW1lbnQgbWV0aG9kLCBTdHJpbmcgY25hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBsb25nTmFtZSkKICAgICAgICAgICAgICAgIHRocm93cyBUeXBlU2lnbmF0dXJlLlNpZ25hdHVyZUV4Y2VwdGlvbiB7CiAgICAgICAgU3RyaW5nIHJlcyA9ICJKYXZhXyIgKyBjbmFtZSArICJfIiArIG1ldGhvZC5nZXRTaW1wbGVOYW1lKCk7CgogICAgICAgIGlmIChsb25nTmFtZSkgewogICAgICAgICAgICBUeXBlTWlycm9yIG1UeXBlID0gIHR5cGVzLmVyYXN1cmUobWV0aG9kLmdldFJldHVyblR5cGUoKSk7CiAgICAgICAgICAgIExpc3Q8PyBleHRlbmRzIFZhcmlhYmxlRWxlbWVudD4gcGFyYW1zID0gbWV0aG9kLmdldFBhcmFtZXRlcnMoKTsKICAgICAgICAgICAgTGlzdDxUeXBlTWlycm9yPiBhcmdUeXBlcyA9IG5ldyBBcnJheUxpc3Q8PigpOwogICAgICAgICAgICBmb3IgKFZhcmlhYmxlRWxlbWVudCBwYXJhbTogcGFyYW1zKSB7CiAgICAgICAgICAgICAgICBhcmdUeXBlcy5hZGQodHlwZXMuZXJhc3VyZShwYXJhbS5hc1R5cGUoKSkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXMgPSByZXMgKyAiX18iOwogICAgICAgICAgICBmb3IgKFR5cGVNaXJyb3IgdDogYXJnVHlwZXMpIHsKICAgICAgICAgICAgICAgIFN0cmluZyB0bmFtZSA9IHQudG9TdHJpbmcoKTsKICAgICAgICAgICAgICAgIFR5cGVTaWduYXR1cmUgbmV3VHlwZVNpZyA9IG5ldyBUeXBlU2lnbmF0dXJlKGVsZW1zKTsKICAgICAgICAgICAgICAgIFN0cmluZyBzaWcgPSBuZXdUeXBlU2lnLmdldFR5cGVTaWduYXR1cmUodG5hbWUpOwogICAgICAgICAgICAgICAgcmVzID0gcmVzICsgbmFtZVRvSWRlbnRpZmllcihzaWcpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXM7CiAgICB9CgogICAgLy8gY29waWVkIGZyb20gSk5JLmphdmEKICAgIHByb3RlY3RlZCBmaW5hbCBTdHJpbmcgam5pVHlwZShUeXBlTWlycm9yIHQpIHRocm93cyBVdGlsLkV4aXQgewogICAgICAgIFR5cGVFbGVtZW50IHRocm93YWJsZSA9IGVsZW1zLmdldFR5cGVFbGVtZW50KCJqYXZhLmxhbmcuVGhyb3dhYmxlIik7CiAgICAgICAgVHlwZUVsZW1lbnQgakNsYXNzID0gZWxlbXMuZ2V0VHlwZUVsZW1lbnQoImphdmEubGFuZy5DbGFzcyIpOwogICAgICAgIFR5cGVFbGVtZW50IGpTdHJpbmcgPSBlbGVtcy5nZXRUeXBlRWxlbWVudCgiamF2YS5sYW5nLlN0cmluZyIpOwogICAgICAgIEVsZW1lbnQgdGNsYXNzRG9jID0gdHlwZXMuYXNFbGVtZW50KHQpOwoKICAgICAgICBzd2l0Y2ggKHQuZ2V0S2luZCgpKSB7CiAgICAgICAgICAgIGNhc2UgQVJSQVk6IHsKICAgICAgICAgICAgICAgIFR5cGVNaXJyb3IgY3QgPSAoKEFycmF5VHlwZSkgdCkuZ2V0Q29tcG9uZW50VHlwZSgpOwogICAgICAgICAgICAgICAgc3dpdGNoIChjdC5nZXRLaW5kKCkpIHsKICAgICAgICAgICAgICAgICAgICBjYXNlIEJPT0xFQU46ICByZXR1cm4gImpib29sZWFuQXJyYXkiOwogICAgICAgICAgICAgICAgICAgIGNhc2UgQllURTogICAgIHJldHVybiAiamJ5dGVBcnJheSI7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBDSEFSOiAgICAgcmV0dXJuICJqY2hhckFycmF5IjsKICAgICAgICAgICAgICAgICAgICBjYXNlIFNIT1JUOiAgICByZXR1cm4gImpzaG9ydEFycmF5IjsKICAgICAgICAgICAgICAgICAgICBjYXNlIElOVDogICAgICByZXR1cm4gImppbnRBcnJheSI7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBMT05HOiAgICAgcmV0dXJuICJqbG9uZ0FycmF5IjsKICAgICAgICAgICAgICAgICAgICBjYXNlIEZMT0FUOiAgICByZXR1cm4gImpmbG9hdEFycmF5IjsKICAgICAgICAgICAgICAgICAgICBjYXNlIERPVUJMRTogICByZXR1cm4gImpkb3VibGVBcnJheSI7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBBUlJBWToKICAgICAgICAgICAgICAgICAgICBjYXNlIERFQ0xBUkVEOiByZXR1cm4gImpvYmplY3RBcnJheSI7CiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDogdGhyb3cgbmV3IEVycm9yKGN0LnRvU3RyaW5nKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBjYXNlIFZPSUQ6ICAgICByZXR1cm4gInZvaWQiOwogICAgICAgICAgICBjYXNlIEJPT0xFQU46ICByZXR1cm4gImpib29sZWFuIjsKICAgICAgICAgICAgY2FzZSBCWVRFOiAgICAgcmV0dXJuICJqYnl0ZSI7CiAgICAgICAgICAgIGNhc2UgQ0hBUjogICAgIHJldHVybiAiamNoYXIiOwogICAgICAgICAgICBjYXNlIFNIT1JUOiAgICByZXR1cm4gImpzaG9ydCI7CiAgICAgICAgICAgIGNhc2UgSU5UOiAgICAgIHJldHVybiAiamludCI7CiAgICAgICAgICAgIGNhc2UgTE9ORzogICAgIHJldHVybiAiamxvbmciOwogICAgICAgICAgICBjYXNlIEZMT0FUOiAgICByZXR1cm4gImpmbG9hdCI7CiAgICAgICAgICAgIGNhc2UgRE9VQkxFOiAgIHJldHVybiAiamRvdWJsZSI7CgogICAgICAgICAgICBjYXNlIERFQ0xBUkVEOiB7CiAgICAgICAgICAgICAgICBpZiAodGNsYXNzRG9jLmVxdWFscyhqU3RyaW5nKSkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gImpzdHJpbmciOwogICAgICAgICAgICAgICAgZWxzZSBpZiAodHlwZXMuaXNBc3NpZ25hYmxlKHQsIHRocm93YWJsZS5hc1R5cGUoKSkpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICJqdGhyb3dhYmxlIjsKICAgICAgICAgICAgICAgIGVsc2UgaWYgKHR5cGVzLmlzQXNzaWduYWJsZSh0LCBqQ2xhc3MuYXNUeXBlKCkpKQogICAgICAgICAgICAgICAgICAgIHJldHVybiAiamNsYXNzIjsKICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICByZXR1cm4gImpvYmplY3QiOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICB1dGlsLmJ1Zygiam5pLnVua25vd24udHlwZSIpOwogICAgICAgIHJldHVybiBudWxsOyAvKiBkZWFkIGNvZGUuICovCiAgICB9CgogICAgcHJvdGVjdGVkIFN0cmluZyBsbG5pVHlwZShUeXBlTWlycm9yIHQsIGJvb2xlYW4gaGFuZGxlaXplLCBib29sZWFuIGxvbmdEb3VibGVPSykgewogICAgICAgIFN0cmluZyByZXMgPSBudWxsOwoKICAgICAgICBzd2l0Y2ggKHQuZ2V0S2luZCgpKSB7CiAgICAgICAgICAgIGNhc2UgQVJSQVk6IHsKICAgICAgICAgICAgICAgIFR5cGVNaXJyb3IgY3QgPSAoKEFycmF5VHlwZSkgdCkuZ2V0Q29tcG9uZW50VHlwZSgpOwogICAgICAgICAgICAgICAgc3dpdGNoIChjdC5nZXRLaW5kKCkpIHsKICAgICAgICAgICAgICAgICAgICBjYXNlIEJPT0xFQU46ICByZXMgPSAiSUFycmF5T2ZCb29sZWFuIjsgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBCWVRFOiAgICAgcmVzID0gIklBcnJheU9mQnl0ZSI7ICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgQ0hBUjogICAgIHJlcyA9ICJJQXJyYXlPZkNoYXIiOyAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICBjYXNlIFNIT1JUOiAgICByZXMgPSAiSUFycmF5T2ZTaG9ydCI7ICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBJTlQ6ICAgICAgcmVzID0gIklBcnJheU9mSW50IjsgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgTE9ORzogICAgIHJlcyA9ICJJQXJyYXlPZkxvbmciOyAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICBjYXNlIEZMT0FUOiAgICByZXMgPSAiSUFycmF5T2ZGbG9hdCI7ICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBET1VCTEU6ICAgcmVzID0gIklBcnJheU9mRG91YmxlIjsgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgQVJSQVk6CiAgICAgICAgICAgICAgICAgICAgY2FzZSBERUNMQVJFRDogcmVzID0gIklBcnJheU9mUmVmIjsgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHRocm93IG5ldyBFcnJvcihjdC5nZXRLaW5kKCkgKyAiICIgKyBjdCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoIWhhbmRsZWl6ZSkgcmVzID0gIkRFUkVGRVJFTkNFRF8iICsgcmVzOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGNhc2UgVk9JRDoKICAgICAgICAgICAgICAgIHJlcyA9ICJ2b2lkIjsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBCT09MRUFOOgogICAgICAgICAgICBjYXNlIEJZVEU6CiAgICAgICAgICAgIGNhc2UgQ0hBUjoKICAgICAgICAgICAgY2FzZSBTSE9SVDoKICAgICAgICAgICAgY2FzZSBJTlQ6CiAgICAgICAgICAgICAgICByZXMgPSAiamF2YV9pbnQiIDsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBMT05HOgogICAgICAgICAgICAgICAgcmVzID0gbG9uZ0RvdWJsZU9LID8gImphdmFfbG9uZyIgOiAidmFsMzIgLyogamF2YV9sb25nICovIjsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBGTE9BVDoKICAgICAgICAgICAgICAgIHJlcyA9ICAiamF2YV9mbG9hdCI7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgRE9VQkxFOgogICAgICAgICAgICAgICAgcmVzID0gbG9uZ0RvdWJsZU9LID8gImphdmFfZG91YmxlIiA6ICJ2YWwzMiAvKiBqYXZhX2RvdWJsZSAqLyI7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgREVDTEFSRUQ6CiAgICAgICAgICAgICAgICBUeXBlRWxlbWVudCBlICA9IChUeXBlRWxlbWVudCkgdHlwZXMuYXNFbGVtZW50KHQpOwogICAgICAgICAgICAgICAgcmVzID0gIkkiICsgIG1hbmdsZUNsYXNzTmFtZShlLmdldFF1YWxpZmllZE5hbWUoKS50b1N0cmluZygpKTsKICAgICAgICAgICAgICAgIGlmICghaGFuZGxlaXplKSByZXMgPSAiREVSRUZFUkVOQ0VEXyIgKyByZXM7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IodC5nZXRLaW5kKCkgKyAiICIgKyB0KTsgLy8gRklYTUUKICAgICAgICB9CgogICAgICAgIHJldHVybiByZXM7CiAgICB9CgogICAgcHJvdGVjdGVkIGZpbmFsIFN0cmluZyBjUmN2ckRlY2woRWxlbWVudCBmaWVsZCwgU3RyaW5nIGNuYW1lKSB7CiAgICAgICAgcmV0dXJuIChmaWVsZC5nZXRNb2RpZmllcnMoKS5jb250YWlucyhNb2RpZmllci5TVEFUSUMpID8gImpjbGFzcyIgOiAiam9iamVjdCIpOwogICAgfQoKICAgIHByb3RlY3RlZCBTdHJpbmcgbWFza05hbWUoU3RyaW5nIHMpIHsKICAgICAgICByZXR1cm4gIkxMTklfbWFzaygiICsgcyArICIpIjsKICAgIH0KCiAgICBwcm90ZWN0ZWQgU3RyaW5nIGxsbmlGaWVsZE5hbWUoVmFyaWFibGVFbGVtZW50IGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIG1hc2tOYW1lKGZpZWxkLmdldFNpbXBsZU5hbWUoKS50b1N0cmluZygpKTsKICAgIH0KCiAgICBwcm90ZWN0ZWQgZmluYWwgYm9vbGVhbiBpc0xvbmdPckRvdWJsZShUeXBlTWlycm9yIHQpIHsKICAgICAgICBUeXBlVmlzaXRvcjxCb29sZWFuLFZvaWQ+IHYgPSBuZXcgU2ltcGxlVHlwZVZpc2l0b3I5PEJvb2xlYW4sVm9pZD4oKSB7CiAgICAgICAgICAgIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgICAgICBwdWJsaWMgQm9vbGVhbiBkZWZhdWx0QWN0aW9uKFR5cGVNaXJyb3IgdCwgVm9pZCBwKXsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgICAgICAgICAgcHVibGljIEJvb2xlYW4gdmlzaXRBcnJheShBcnJheVR5cGUgdCwgVm9pZCBwKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdmlzaXQodC5nZXRDb21wb25lbnRUeXBlKCksIHApOwogICAgICAgICAgICB9CiAgICAgICAgICAgIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgICAgICBwdWJsaWMgQm9vbGVhbiB2aXNpdFByaW1pdGl2ZShQcmltaXRpdmVUeXBlIHQsIFZvaWQgcCkgewogICAgICAgICAgICAgICAgVHlwZUtpbmQgdGsgPSB0LmdldEtpbmQoKTsKICAgICAgICAgICAgICAgIHJldHVybiAodGsgPT0gVHlwZUtpbmQuTE9ORyB8fCB0ayA9PSBUeXBlS2luZC5ET1VCTEUpOwogICAgICAgICAgICB9CiAgICAgICAgfTsKICAgICAgICByZXR1cm4gdi52aXNpdCh0LCBudWxsKTsKICAgIH0KCiAgICAvKiBEbyB1bmljb2RlIHRvIGFuc2kgQyBpZGVudGlmaWVyIGNvbnZlcnNpb24uCiAgICAgICAlJSUgVGhpcyBtYXkgbm90IGJlIHJpZ2h0LCBidXQgc2hvdWxkIGJlIGNhbGxlZCBtb3JlIG9mdGVuLiAqLwogICAgcHJvdGVjdGVkIGZpbmFsIFN0cmluZyBuYW1lVG9JZGVudGlmaWVyKFN0cmluZyBuYW1lKSB7CiAgICAgICAgaW50IGxlbiA9IG5hbWUubGVuZ3RoKCk7CiAgICAgICAgU3RyaW5nQnVpbGRlciBidWYgPSBuZXcgU3RyaW5nQnVpbGRlcihsZW4pOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKICAgICAgICAgICAgY2hhciBjID0gbmFtZS5jaGFyQXQoaSk7CiAgICAgICAgICAgIGlmIChpc0FTQ0lJTGV0dGVyT3JEaWdpdChjKSkKICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQoYyk7CiAgICAgICAgICAgIGVsc2UgaWYgKGMgPT0gJy8nKQogICAgICAgICAgICAgICAgYnVmLmFwcGVuZCgnXycpOwogICAgICAgICAgICBlbHNlIGlmIChjID09ICcuJykKICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQoJ18nKTsKICAgICAgICAgICAgZWxzZSBpZiAoYyA9PSAnXycpCiAgICAgICAgICAgICAgICBidWYuYXBwZW5kKCJfMSIpOwogICAgICAgICAgICBlbHNlIGlmIChjID09ICc7JykKICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQoIl8yIik7CiAgICAgICAgICAgIGVsc2UgaWYgKGMgPT0gJ1snKQogICAgICAgICAgICAgICAgYnVmLmFwcGVuZCgiXzMiKTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgYnVmLmFwcGVuZCgiXzAiICsgKChpbnQpYykpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbmV3IFN0cmluZyhidWYpOwogICAgfQoKICAgIHByb3RlY3RlZCBmaW5hbCBib29sZWFuIGlzQVNDSUlMZXR0ZXJPckRpZ2l0KGNoYXIgYykgewogICAgICAgIGlmICgoKGMgPj0gJ0EnKSAmJiAoYyA8PSAnWicpKSB8fAogICAgICAgICAgICAoKGMgPj0gJ2EnKSAmJiAoYyA8PSAneicpKSB8fAogICAgICAgICAgICAoKGMgPj0gJzAnKSAmJiAoYyA8PSAnOScpKSkKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgZWxzZQogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9Cn0KClBLAwQKAAAIAAAGO6lKAAAAAAAAAAAAAAAAFAAAAGNvbS9zdW4vdG9vbHMvamF2YWMvUEsDBAoAAAgAAAY7qUoAAAAAAAAAAAAAAAAeAAAAY29tL3N1bi90b29scy9qYXZhYy9yZXNvdXJjZXMvUEsDBAoAAAgAAAY7qUr0dwl61TgAANU4AAAuAAAAY29tL3N1bi90b29scy9qYXZhYy9yZXNvdXJjZXMvamF2YWMucHJvcGVydGllcyMKIyBDb3B5cmlnaHQgKGMpIDE5OTksIDIwMTcsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiMgRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgojCiMgVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKIyB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwojIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwojIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKIyBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KIwojIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAojIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgojIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQojIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiMgYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KIwojIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KIyAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiMgSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgojCiMgUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKIyBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiMgcXVlc3Rpb25zLgojCgojIyBzdGFuZGFyZCBvcHRpb25zCgpqYXZhYy5vcHQuZz1cCiAgICBHZW5lcmF0ZSBhbGwgZGVidWdnaW5nIGluZm8KamF2YWMub3B0Lmcubm9uZT1cCiAgICBHZW5lcmF0ZSBubyBkZWJ1Z2dpbmcgaW5mbwpqYXZhYy5vcHQuZy5saW5lcy52YXJzLnNvdXJjZT1cCiAgICBHZW5lcmF0ZSBvbmx5IHNvbWUgZGVidWdnaW5nIGluZm8KamF2YWMub3B0Lm5vd2Fybj1cCiAgICBHZW5lcmF0ZSBubyB3YXJuaW5ncwpqYXZhYy5vcHQudmVyYm9zZT1cCiAgICBPdXRwdXQgbWVzc2FnZXMgYWJvdXQgd2hhdCB0aGUgY29tcGlsZXIgaXMgZG9pbmcKamF2YWMub3B0LmRlcHJlY2F0aW9uPVwKICAgIE91dHB1dCBzb3VyY2UgbG9jYXRpb25zIHdoZXJlIGRlcHJlY2F0ZWQgQVBJcyBhcmUgdXNlZApqYXZhYy5vcHQuY2xhc3NwYXRoPVwKICAgIFNwZWNpZnkgd2hlcmUgdG8gZmluZCB1c2VyIGNsYXNzIGZpbGVzIGFuZCBhbm5vdGF0aW9uIHByb2Nlc3NvcnMKamF2YWMub3B0Lm1vZHVsZXBhdGg9XAogICAgU3BlY2lmeSB3aGVyZSB0byBmaW5kIGFwcGxpY2F0aW9uIG1vZHVsZXMKamF2YWMub3B0LnNvdXJjZXBhdGg9XAogICAgU3BlY2lmeSB3aGVyZSB0byBmaW5kIGlucHV0IHNvdXJjZSBmaWxlcwpqYXZhYy5vcHQubT1cCiAgICBDb21waWxlIG9ubHkgdGhlIHNwZWNpZmllZCBtb2R1bGUsIGNoZWNrIHRpbWVzdGFtcHMKamF2YWMub3B0Lm1vZHVsZXNvdXJjZXBhdGg9XAogICAgU3BlY2lmeSB3aGVyZSB0byBmaW5kIGlucHV0IHNvdXJjZSBmaWxlcyBmb3IgbXVsdGlwbGUgbW9kdWxlcwpqYXZhYy5vcHQuYm9vdGNsYXNzcGF0aD1cCiAgICBPdmVycmlkZSBsb2NhdGlvbiBvZiBib290c3RyYXAgY2xhc3MgZmlsZXMKamF2YWMub3B0LnN5c3RlbT1cCiAgICBPdmVycmlkZSBsb2NhdGlvbiBvZiBzeXN0ZW0gbW9kdWxlcwpqYXZhYy5vcHQudXBncmFkZW1vZHVsZXBhdGg9XAogICAgT3ZlcnJpZGUgbG9jYXRpb24gb2YgdXBncmFkZWFibGUgbW9kdWxlcwpqYXZhYy5vcHQuZW5kb3JzZWRkaXJzPVwKICAgIE92ZXJyaWRlIGxvY2F0aW9uIG9mIGVuZG9yc2VkIHN0YW5kYXJkcyBwYXRoCmphdmFjLm9wdC5leHRkaXJzPVwKICAgIE92ZXJyaWRlIGxvY2F0aW9uIG9mIGluc3RhbGxlZCBleHRlbnNpb25zCmphdmFjLm9wdC5wcm9jZXNzb3JwYXRoPVwKICAgIFNwZWNpZnkgd2hlcmUgdG8gZmluZCBhbm5vdGF0aW9uIHByb2Nlc3NvcnMKamF2YWMub3B0LnByb2Nlc3Nvcm1vZHVsZXBhdGg9XAogICAgU3BlY2lmeSBhIG1vZHVsZSBwYXRoIHdoZXJlIHRvIGZpbmQgYW5ub3RhdGlvbiBwcm9jZXNzb3JzCmphdmFjLm9wdC5wcm9jZXNzb3I9XAogICAgTmFtZXMgb2YgdGhlIGFubm90YXRpb24gcHJvY2Vzc29ycyB0byBydW47IGJ5cGFzc2VzIGRlZmF1bHQgZGlzY292ZXJ5IHByb2Nlc3MKamF2YWMub3B0LnBhcmFtZXRlcnM9XAogICAgR2VuZXJhdGUgbWV0YWRhdGEgZm9yIHJlZmxlY3Rpb24gb24gbWV0aG9kIHBhcmFtZXRlcnMKamF2YWMub3B0LnByb2Mubm9uZS5vbmx5PVwKICAgIENvbnRyb2wgd2hldGhlciBhbm5vdGF0aW9uIHByb2Nlc3NpbmcgYW5kL29yIGNvbXBpbGF0aW9uIGlzIGRvbmUuCmphdmFjLm9wdC5kPVwKICAgIFNwZWNpZnkgd2hlcmUgdG8gcGxhY2UgZ2VuZXJhdGVkIGNsYXNzIGZpbGVzCmphdmFjLm9wdC5zb3VyY2VEZXN0PVwKICAgIFNwZWNpZnkgd2hlcmUgdG8gcGxhY2UgZ2VuZXJhdGVkIHNvdXJjZSBmaWxlcwpqYXZhYy5vcHQuaGVhZGVyRGVzdD1cCiAgICBTcGVjaWZ5IHdoZXJlIHRvIHBsYWNlIGdlbmVyYXRlZCBuYXRpdmUgaGVhZGVyIGZpbGVzCmphdmFjLm9wdC5KPVwKICAgIFBhc3MgPGZsYWc+IGRpcmVjdGx5IHRvIHRoZSBydW50aW1lIHN5c3RlbQpqYXZhYy5vcHQuZW5jb2Rpbmc9XAogICAgU3BlY2lmeSBjaGFyYWN0ZXIgZW5jb2RpbmcgdXNlZCBieSBzb3VyY2UgZmlsZXMKamF2YWMub3B0LnByb2ZpbGU9XAogICAgQ2hlY2sgdGhhdCBBUEkgdXNlZCBpcyBhdmFpbGFibGUgaW4gdGhlIHNwZWNpZmllZCBwcm9maWxlCmphdmFjLm9wdC50YXJnZXQ9XAogICAgR2VuZXJhdGUgY2xhc3MgZmlsZXMgZm9yIHNwZWNpZmljIFZNIHZlcnNpb24KamF2YWMub3B0LnJlbGVhc2U9XAogICAgQ29tcGlsZSBmb3IgYSBzcGVjaWZpYyBWTSB2ZXJzaW9uLiBTdXBwb3J0ZWQgdGFyZ2V0czogezB9CmphdmFjLm9wdC5zb3VyY2U9XAogICAgUHJvdmlkZSBzb3VyY2UgY29tcGF0aWJpbGl0eSB3aXRoIHNwZWNpZmllZCByZWxlYXNlCmphdmFjLm9wdC5XZXJyb3I9XAogICAgVGVybWluYXRlIGNvbXBpbGF0aW9uIGlmIHdhcm5pbmdzIG9jY3VyCmphdmFjLm9wdC5BPVwKICAgIE9wdGlvbnMgdG8gcGFzcyB0byBhbm5vdGF0aW9uIHByb2Nlc3NvcnMKamF2YWMub3B0LmltcGxpY2l0PVwKICAgIFNwZWNpZnkgd2hldGhlciBvciBub3QgdG8gZ2VuZXJhdGUgY2xhc3MgZmlsZXMgZm9yIGltcGxpY2l0bHkgcmVmZXJlbmNlZCBmaWxlcwpqYXZhYy5vcHQucGtnaW5mbz1cCiAgICBTcGVjaWZ5IGhhbmRsaW5nIG9mIHBhY2thZ2UtaW5mbyBmaWxlcwpqYXZhYy5vcHQubXVsdGktcmVsZWFzZT1cCiAgICBTcGVjaWZ5IHdoaWNoIHJlbGVhc2UgdG8gdXNlIGluIG11bHRpLXJlbGVhc2UgamFycwpqYXZhYy5vcHQuYXJnLmNsYXNzPVwKICAgIDxjbGFzcz4KamF2YWMub3B0LmFyZy5jbGFzcy5saXN0PVwKICAgIDxjbGFzczE+Wyw8Y2xhc3MyPiw8Y2xhc3MzPi4uLl0KamF2YWMub3B0LmFyZy5mbGFnPVwKICAgIDxmbGFnPgpqYXZhYy5vcHQuYXJnLmtleS5lcXVhbHMudmFsdWU9XAogICAga2V5Wz12YWx1ZV0KamF2YWMub3B0LmFyZy5wYXRoPVwKICAgIDxwYXRoPgpqYXZhYy5vcHQuYXJnLm1zcGF0aD1cCiAgICA8bW9kdWxlLXNvdXJjZS1wYXRoPgpqYXZhYy5vcHQuYXJnLm09XAogICAgPG1vZHVsZS1uYW1lPgpqYXZhYy5vcHQuYXJnLmpkaz1cCiAgICA8amRrPnxub25lCmphdmFjLm9wdC5hcmcuZGlycz1cCiAgICA8ZGlycz4KamF2YWMub3B0LmFyZy5kaXJlY3Rvcnk9XAogICAgPGRpcmVjdG9yeT4KamF2YWMub3B0LmFyZy5lbmNvZGluZz1cCiAgICA8ZW5jb2Rpbmc+CmphdmFjLm9wdC5hcmcucHJvZmlsZT1cCiAgICA8cHJvZmlsZT4KamF2YWMub3B0LmFyZy5yZWxlYXNlPVwKICAgIDxyZWxlYXNlPgpqYXZhYy5vcHQuYXJnLnJlbGVhc2U9XAogICAgPHJlbGVhc2U+CmphdmFjLm9wdC5hcmcubnVtYmVyPVwKICAgIDxudW1iZXI+CmphdmFjLm9wdC5wbHVnaW49XAogICAgTmFtZSBhbmQgb3B0aW9uYWwgYXJndW1lbnRzIGZvciBhIHBsdWctaW4gdG8gYmUgcnVuCmphdmFjLm9wdC5hcmcucGx1Z2luPVwKICAgICJuYW1lIGFyZ3MiCmphdmFjLm9wdC5hcmcubXVsdGktcmVsZWFzZT1cCiAgICA8cmVsZWFzZT4KCiMjIGV4dGVuZGVkIG9wdGlvbnMKCmphdmFjLm9wdC5tYXhlcnJzPVwKICAgIFNldCB0aGUgbWF4aW11bSBudW1iZXIgb2YgZXJyb3JzIHRvIHByaW50CmphdmFjLm9wdC5tYXh3YXJucz1cCiAgICBTZXQgdGhlIG1heGltdW0gbnVtYmVyIG9mIHdhcm5pbmdzIHRvIHByaW50CmphdmFjLm9wdC5ub2dqPVwKICAgIERvbid0IGFjY2VwdCBnZW5lcmljcyBpbiB0aGUgbGFuZ3VhZ2UKamF2YWMub3B0Lm1vcmVpbmZvPVwKICAgIFByaW50IGV4dGVuZGVkIGluZm9ybWF0aW9uIGZvciB0eXBlIHZhcmlhYmxlcwpqYXZhYy5vcHQucHJpbnRzZWFyY2g9XAogICAgUHJpbnQgaW5mb3JtYXRpb24gd2hlcmUgY2xhc3NmaWxlcyBhcmUgc2VhcmNoZWQKamF2YWMub3B0LnByb21wdD1cCiAgICBTdG9wIGFmdGVyIGVhY2ggZXJyb3IKamF2YWMub3B0LnM9XAogICAgRW1pdCBqYXZhIHNvdXJjZXMgaW5zdGVhZCBvZiBjbGFzc2ZpbGVzCmphdmFjLm9wdC52ZXJzaW9uPVwKICAgIFZlcnNpb24gaW5mb3JtYXRpb24KamF2YWMub3B0LmFyZy5wYXRobmFtZT1cCiAgICA8cGF0aG5hbWU+CmphdmFjLm9wdC5hcmcuZmlsZT1cCiAgICA8ZmlsZW5hbWU+CmphdmFjLm9wdC5YYm9vdGNsYXNzcGF0aC5wPVwKICAgIFByZXBlbmQgdG8gdGhlIGJvb3RzdHJhcCBjbGFzcyBwYXRoCmphdmFjLm9wdC5YYm9vdGNsYXNzcGF0aC5hPVwKICAgIEFwcGVuZCB0byB0aGUgYm9vdHN0cmFwIGNsYXNzIHBhdGgKamF2YWMub3B0LlhsaW50PVwKICAgIEVuYWJsZSByZWNvbW1lbmRlZCB3YXJuaW5ncwpqYXZhYy5vcHQuWGxpbnQuYWxsPVwKICAgIEVuYWJsZSBhbGwgd2FybmluZ3MKamF2YWMub3B0LlhsaW50Lm5vbmU9XAogICAgRGlzYWJsZSBhbGwgd2FybmluZ3MKI0wxME46IGRvIG5vdCBsb2NhbGl6ZTogLVhsaW50CmphdmFjLm9wdC5hcmcuWGxpbnQ9XAogICAgPGtleT4oLDxrZXk+KSoKamF2YWMub3B0LlhsaW50LmN1c3RvbT1cCiAgICBXYXJuaW5ncyB0byBlbmFibGUgb3IgZGlzYWJsZSwgc2VwYXJhdGVkIGJ5IGNvbW1hLlxuXAogICAgUHJlY2VkZSBhIGtleSBieSAnLScgdG8gZGlzYWJsZSB0aGUgc3BlY2lmaWVkIHdhcm5pbmcuXG5cCiAgICBTdXBwb3J0ZWQga2V5cyBhcmU6CmphdmFjLm9wdC5YbGludC5kZXNjLmF1eGlsaWFyeWNsYXNzPVwKICAgIFdhcm4gYWJvdXQgYW4gYXV4aWxpYXJ5IGNsYXNzIHRoYXQgaXMgaGlkZGVuIGluIGEgc291cmNlIGZpbGUsIGFuZCBpcyB1c2VkIGZyb20gb3RoZXIgZmlsZXMuCgpqYXZhYy5vcHQuWGxpbnQuZGVzYy5jYXN0PVwKICAgIFdhcm4gYWJvdXQgdXNlIG9mIHVubmVjZXNzYXJ5IGNhc3RzLgoKamF2YWMub3B0LlhsaW50LmRlc2MuY2xhc3NmaWxlPVwKICAgIFdhcm4gYWJvdXQgaXNzdWVzIHJlbGF0ZWQgdG8gY2xhc3NmaWxlIGNvbnRlbnRzLgoKamF2YWMub3B0LlhsaW50LmRlc2MuZGVwcmVjYXRpb249XAogICAgV2FybiBhYm91dCB1c2Ugb2YgZGVwcmVjYXRlZCBpdGVtcy4KCmphdmFjLm9wdC5YbGludC5kZXNjLmRlcC1hbm49XAogICAgV2FybiBhYm91dCBpdGVtcyBtYXJrZWQgYXMgZGVwcmVjYXRlZCBpbiBKYXZhRG9jIGJ1dCBub3QgdXNpbmcgdGhlIEBEZXByZWNhdGVkIGFubm90YXRpb24uCgpqYXZhYy5vcHQuWGxpbnQuZGVzYy5kaXZ6ZXJvPVwKICAgIFdhcm4gYWJvdXQgZGl2aXNpb24gYnkgY29uc3RhbnQgaW50ZWdlciAwLgoKamF2YWMub3B0LlhsaW50LmRlc2MuZW1wdHk9XAogICAgV2FybiBhYm91dCBlbXB0eSBzdGF0ZW1lbnQgYWZ0ZXIgaWYuCgpqYXZhYy5vcHQuWGxpbnQuZGVzYy5leHBvcnRzPVwKICAgIFdhcm4gYWJvdXQgaXNzdWVzIHJlZ2FyZGluZyBtb2R1bGUgZXhwb3J0cy4KCmphdmFjLm9wdC5YbGludC5kZXNjLmZhbGx0aHJvdWdoPVwKICAgIFdhcm4gYWJvdXQgZmFsbGluZyB0aHJvdWdoIGZyb20gb25lIGNhc2Ugb2YgYSBzd2l0Y2ggc3RhdGVtZW50IHRvIHRoZSBuZXh0LgoKamF2YWMub3B0LlhsaW50LmRlc2MuZmluYWxseT1cCiAgICBXYXJuIGFib3V0IGZpbmFsbHkgY2xhdXNlcyB0aGF0IGRvIG5vdCB0ZXJtaW5hdGUgbm9ybWFsbHkuCgpqYXZhYy5vcHQuWGxpbnQuZGVzYy5tb2R1bGU9XAogICAgV2FybiBhYm91dCBtb2R1bGUgc3lzdGVtIHJlbGF0ZWQgaXNzdWVzLgoKamF2YWMub3B0LlhsaW50LmRlc2Mub3BlbnM9XAogICAgV2FybiBhYm91dCBpc3N1ZXMgcmVnYXJkaW5nIG1vZHVsZSBvcGVucy4KCmphdmFjLm9wdC5YbGludC5kZXNjLm9wdGlvbnM9XAogICAgV2FybiBhYm91dCBpc3N1ZXMgcmVsYXRpbmcgdG8gdXNlIG9mIGNvbW1hbmQgbGluZSBvcHRpb25zLgoKamF2YWMub3B0LlhsaW50LmRlc2Mub3ZlcmxvYWRzPVwKICAgIFdhcm4gYWJvdXQgaXNzdWVzIHJlZ2FyZGluZyBtZXRob2Qgb3ZlcmxvYWRzLgoKamF2YWMub3B0LlhsaW50LmRlc2Mub3ZlcnJpZGVzPVwKICAgIFdhcm4gYWJvdXQgaXNzdWVzIHJlZ2FyZGluZyBtZXRob2Qgb3ZlcnJpZGVzLgoKamF2YWMub3B0LlhsaW50LmRlc2MucGF0aD1cCiAgICBXYXJuIGFib3V0IGludmFsaWQgcGF0aCBlbGVtZW50cyBvbiB0aGUgY29tbWFuZCBsaW5lLgoKamF2YWMub3B0LlhsaW50LmRlc2MucHJvY2Vzc2luZz1cCiAgICBXYXJuIGFib3V0IGlzc3VlcyByZWdhcmRpbmcgYW5ub3RhdGlvbiBwcm9jZXNzaW5nLgoKamF2YWMub3B0LlhsaW50LmRlc2MucmF3dHlwZXM9XAogICAgV2FybiBhYm91dCB1c2Ugb2YgcmF3IHR5cGVzLgoKamF2YWMub3B0LlhsaW50LmRlc2MucmVtb3ZhbD1cCiAgICBXYXJuIGFib3V0IHVzZSBvZiBBUEkgdGhhdCBoYXMgYmVlbiBtYXJrZWQgZm9yIHJlbW92YWwuCgpqYXZhYy5vcHQuWGxpbnQuZGVzYy5zZXJpYWw9XAogICAgV2FybiBhYm91dCBTZXJpYWxpemFibGUgY2xhc3NlcyB0aGF0IGRvIG5vdCBwcm92aWRlIGEgc2VyaWFsIHZlcnNpb24gSUQuIFxuXApcICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBbHNvIHdhcm4gYWJvdXQgYWNjZXNzIHRvIG5vbi1wdWJsaWMgbWVtYmVycyBmcm9tIGEgc2VyaWFsaXphYmxlIGVsZW1lbnQuCgpqYXZhYy5vcHQuWGxpbnQuZGVzYy5zdGF0aWM9XAogICAgV2FybiBhYm91dCBhY2Nlc3NpbmcgYSBzdGF0aWMgbWVtYmVyIHVzaW5nIGFuIGluc3RhbmNlLgoKamF2YWMub3B0LlhsaW50LmRlc2MudHJ5PVwKICAgIFdhcm4gYWJvdXQgaXNzdWVzIHJlbGF0aW5nIHRvIHVzZSBvZiB0cnkgYmxvY2tzIChpLmUuIHRyeS13aXRoLXJlc291cmNlcykuCgpqYXZhYy5vcHQuWGxpbnQuZGVzYy51bmNoZWNrZWQ9XAogICAgV2FybiBhYm91dCB1bmNoZWNrZWQgb3BlcmF0aW9ucy4KCmphdmFjLm9wdC5YbGludC5kZXNjLnZhcmFyZ3M9XAogICAgV2FybiBhYm91dCBwb3RlbnRpYWxseSB1bnNhZmUgdmFyYXJnIG1ldGhvZHMKCmphdmFjLm9wdC5YZG9jbGludD1cCiAgICBFbmFibGUgcmVjb21tZW5kZWQgY2hlY2tzIGZvciBwcm9ibGVtcyBpbiBqYXZhZG9jIGNvbW1lbnRzCiMgTDEwTjogZG8gbm90IGxvY2FsaXplOiBhbGwgbm9uZQpqYXZhYy5vcHQuWGRvY2xpbnQuc3Vib3B0cyA9IFwKICAgIChhbGx8bm9uZXxbLV08Z3JvdXA+KVsvPGFjY2Vzcz5dCgojIEwxME46IGRvIG5vdCBsb2NhbGl6ZTogYWNjZXNzaWJpbGl0eSBodG1sIG1pc3NpbmcgcmVmZXJlbmNlIHN5bnRheAojIEwxME46IGRvIG5vdCBsb2NhbGl6ZTogcHVibGljIHByb3RlY3RlZCBwYWNrYWdlIHByaXZhdGUKamF2YWMub3B0Llhkb2NsaW50LmN1c3RvbT1cCiAgICBFbmFibGUgb3IgZGlzYWJsZSBzcGVjaWZpYyBjaGVja3MgZm9yIHByb2JsZW1zIGluIGphdmFkb2MgY29tbWVudHMsXG5cCiAgICB3aGVyZSA8Z3JvdXA+IGlzIG9uZSBvZiBhY2Nlc3NpYmlsaXR5LCBodG1sLCBtaXNzaW5nLCByZWZlcmVuY2UsIG9yIHN5bnRheCxcblwKICAgIGFuZCA8YWNjZXNzPiBpcyBvbmUgb2YgcHVibGljLCBwcm90ZWN0ZWQsIHBhY2thZ2UsIG9yIHByaXZhdGUuCgpqYXZhYy5vcHQuWGRvY2xpbnQucGFja2FnZS5hcmdzID0gXAogICAgWy1dPHBhY2thZ2VzPigsWy1dPHBhY2thZ2U+KSoKCmphdmFjLm9wdC5YZG9jbGludC5wYWNrYWdlLmRlc2M9XAogICAgRW5hYmxlIG9yIGRpc2FibGUgY2hlY2tzIGluIHNwZWNpZmljIHBhY2thZ2VzLiBFYWNoIDxwYWNrYWdlPiBpcyBlaXRoZXIgdGhlXG5cCiAgICBxdWFsaWZpZWQgbmFtZSBvZiBhIHBhY2thZ2Ugb3IgYSBwYWNrYWdlIG5hbWUgcHJlZml4IGZvbGxvd2VkIGJ5ICcuKicsIHdoaWNoXG5cCiAgICBleHBhbmRzIHRvIGFsbCBzdWItcGFja2FnZXMgb2YgdGhlIGdpdmVuIHBhY2thZ2UuIEVhY2ggPHBhY2thZ2U+IGNhbiBiZSBwcmVmaXhlZFxuXAogICAgd2l0aCAnLScgdG8gZGlzYWJsZSBjaGVja3MgZm9yIHRoZSBzcGVjaWZpZWQgcGFja2FnZSBvciBwYWNrYWdlcy4KCmphdmFjLm9wdC5kb2NsaW50LmZvcm1hdD1cCiAgICBTcGVjaWZ5IHRoZSBmb3JtYXQgZm9yIGRvY3VtZW50YXRpb24gY29tbWVudHMKCmphdmFjLm9wdC5Yc3Rkb3V0PVwKICAgIFJlZGlyZWN0IHN0YW5kYXJkIG91dHB1dApqYXZhYy5vcHQuWD1cCiAgICBQcmludCBoZWxwIG9uIGV4dHJhIG9wdGlvbnMKamF2YWMub3B0LmhlbHA9XAogICAgUHJpbnQgdGhpcyBoZWxwIG1lc3NhZ2UKamF2YWMub3B0LnByaW50PVwKICAgIFByaW50IG91dCBhIHRleHR1YWwgcmVwcmVzZW50YXRpb24gb2Ygc3BlY2lmaWVkIHR5cGVzCmphdmFjLm9wdC5wcmludFJvdW5kcz1cCiAgICBQcmludCBpbmZvcm1hdGlvbiBhYm91dCByb3VuZHMgb2YgYW5ub3RhdGlvbiBwcm9jZXNzaW5nCmphdmFjLm9wdC5wcmludFByb2Nlc3NvckluZm89XAogICAgUHJpbnQgaW5mb3JtYXRpb24gYWJvdXQgd2hpY2ggYW5ub3RhdGlvbnMgYSBwcm9jZXNzb3IgaXMgYXNrZWQgdG8gcHJvY2VzcwpqYXZhYy5vcHQudXNlcnBhdGhzZmlyc3Q9XAogICAgU2VhcmNoIGNsYXNzcGF0aCBhbmQgc291cmNlcGF0aCBmb3IgY2xhc3NlcyBiZWZvcmUgdGhlIGJvb3RjbGFzc3BhdGggaW5zdGVhZCBvZiBhZnRlcgpqYXZhYy5vcHQucHJlZmVyPVwKICAgIFNwZWNpZnkgd2hpY2ggZmlsZSB0byByZWFkIHdoZW4gYm90aCBhIHNvdXJjZSBmaWxlIGFuZCBjbGFzcyBmaWxlIGFyZSBmb3VuZCBmb3IgYW4gaW1wbGljaXRseSBjb21waWxlZCBjbGFzcwpqYXZhYy5vcHQuQVQ9XAogICAgUmVhZCBvcHRpb25zIGFuZCBmaWxlbmFtZXMgZnJvbSBmaWxlCmphdmFjLm9wdC5kaWFncz1cCiAgICBTZWxlY3QgYSBkaWFnbm9zdGljIG1vZGUKamF2YWMub3B0LmFkZEV4cG9ydHM9XAogICAgU3BlY2lmeSBhIHBhY2thZ2UgdG8gYmUgY29uc2lkZXJlZCBhcyBleHBvcnRlZCBmcm9tIGl0cyBkZWZpbmluZyBtb2R1bGVcblwKICAgIHRvIGFkZGl0aW9uYWwgbW9kdWxlcywgb3IgdG8gYWxsIHVubmFtZWQgbW9kdWxlcyBpZiA8b3RoZXItbW9kdWxlPiBpcyBBTEwtVU5OQU1FRC4KamF2YWMub3B0LmFyZy5hZGRFeHBvcnRzPVwKICAgIDxtb2R1bGU+LzxwYWNrYWdlPj08b3RoZXItbW9kdWxlPigsPG90aGVyLW1vZHVsZT4pKgpqYXZhYy5vcHQuYWRkUmVhZHM9XAogICAgU3BlY2lmeSBhZGRpdGlvbmFsIG1vZHVsZXMgdG8gYmUgY29uc2lkZXJlZCBhcyByZXF1aXJlZCBieSBhIGdpdmVuIG1vZHVsZS5cblwKICAgIDxvdGhlci1tb2R1bGU+IG1heSBiZSBBTEwtVU5OQU1FRCB0byByZXF1aXJlIHRoZSB1bm5hbWVkIG1vZHVsZS4KamF2YWMub3B0LmFyZy5hZGRSZWFkcz1cCiAgICA8bW9kdWxlPj08b3RoZXItbW9kdWxlPigsPG90aGVyLW1vZHVsZT4pKgpqYXZhYy5vcHQucGF0Y2g9XAogICAgT3ZlcnJpZGUgb3IgYXVnbWVudCBhIG1vZHVsZSB3aXRoIGNsYXNzZXMgYW5kIHJlc291cmNlc1xuXAogICAgaW4gSkFSIGZpbGVzIG9yIGRpcmVjdG9yaWVzCmphdmFjLm9wdC5hcmcucGF0Y2g9XAogICAgPG1vZHVsZT49PGZpbGU+KDo8ZmlsZT4pKgpqYXZhYy5vcHQubW9kdWxlPVwKICAgIFNwZWNpZnkgYSBtb2R1bGUgdG8gd2hpY2ggdGhlIGNsYXNzZXMgYmVpbmcgY29tcGlsZWQgYmVsb25nLgpqYXZhYy5vcHQuYXJnLm1vZHVsZT1cCiAgICA8bW9kdWxlPgpqYXZhYy5vcHQuYWRkbW9kcz1cCiAgICBSb290IG1vZHVsZXMgdG8gcmVzb2x2ZSBpbiBhZGRpdGlvbiB0byB0aGUgaW5pdGlhbCBtb2R1bGVzLCBvciBhbGwgbW9kdWxlc1xuXAogICAgb24gdGhlIG1vZHVsZSBwYXRoIGlmIDxtb2R1bGU+IGlzIEFMTC1NT0RVTEUtUEFUSC4KamF2YWMub3B0LmFyZy5hZGRtb2RzPVwKICAgIDxtb2R1bGU+KCw8bW9kdWxlPikqCmphdmFjLm9wdC5saW1pdG1vZHM9XAogICAgTGltaXQgdGhlIHVuaXZlcnNlIG9mIG9ic2VydmFibGUgbW9kdWxlcwpqYXZhYy5vcHQuYXJnLmxpbWl0bW9kcz1cCiAgICA8bW9kdWxlPigsPG1vZHVsZT4pKgpqYXZhYy5vcHQubW9kdWxlLnZlcnNpb249XAogICAgU3BlY2lmeSB2ZXJzaW9uIG9mIG1vZHVsZXMgdGhhdCBhcmUgYmVpbmcgY29tcGlsZWQKamF2YWMub3B0LmFyZy5tb2R1bGUudmVyc2lvbj1cCiAgICA8dmVyc2lvbj4KamF2YWMub3B0LmluaGVyaXRfcnVudGltZV9lbnZpcm9ubWVudD1cCiAgICBJbmhlcml0IG1vZHVsZSBzeXN0ZW0gY29uZmlndXJhdGlvbiBvcHRpb25zIGZyb20gdGhlIHJ1bnRpbWUgZW52aXJvbm1lbnQuCgojIyBlcnJvcnMKCmphdmFjLmVyci5lbXB0eS5BLmFyZ3VtZW50PVwKICAgIC1BIHJlcXVpcmVzIGFuIGFyZ3VtZW50OyB1c2UgJyctQWtleScnIG9yICcnLUFrZXk9dmFsdWUnJwpqYXZhYy5lcnIuaW52YWxpZC5hcmc9XAogICAgaW52YWxpZCBhcmd1bWVudDogezB9CmphdmFjLmVyci5pbnZhbGlkLkEua2V5PVwKICAgICBrZXkgaW4gYW5ub3RhdGlvbiBwcm9jZXNzb3Igb3B0aW9uICcnezB9JycgaXMgbm90IGEgZG90LXNlcGFyYXRlZCBzZXF1ZW5jZSBvZiBpZGVudGlmaWVycwpqYXZhYy5lcnIuaW52YWxpZC5mbGFnPVwKICAgIGludmFsaWQgZmxhZzogezB9CmphdmFjLmVyci5wcm9maWxlLmJvb3RjbGFzc3BhdGguY29uZmxpY3Q9XAogICAgcHJvZmlsZSBhbmQgYm9vdGNsYXNzcGF0aCBvcHRpb25zIGNhbm5vdCBiZSB1c2VkIHRvZ2V0aGVyCmphdmFjLmVyci5pbnZhbGlkLnByb2ZpbGU9XAogICAgaW52YWxpZCBwcm9maWxlOiB7MH0KamF2YWMuZXJyLmludmFsaWQudGFyZ2V0PVwKICAgIGludmFsaWQgdGFyZ2V0IHJlbGVhc2U6IHswfQpqYXZhYy5lcnIub3B0aW9uLm5vdC5hbGxvd2VkLndpdGgudGFyZ2V0PVwKICAgIG9wdGlvbiB7MH0gbm90IGFsbG93ZWQgd2l0aCB0YXJnZXQgezF9CmphdmFjLmVyci5vcHRpb24udG9vLm1hbnk9XAogICAgb3B0aW9uIHswfSBjYW4gb25seSBiZSBzcGVjaWZpZWQgb25jZQpqYXZhYy5lcnIubm8uc291cmNlLmZpbGVzPVwKICAgIG5vIHNvdXJjZSBmaWxlcwpqYXZhYy5lcnIubm8uc291cmNlLmZpbGVzLmNsYXNzZXM9XAogICAgbm8gc291cmNlIGZpbGVzIG9yIGNsYXNzIG5hbWVzCmphdmFjLmVyci5yZXEuYXJnPVwKICAgIHswfSByZXF1aXJlcyBhbiBhcmd1bWVudApqYXZhYy5lcnIuaW52YWxpZC5zb3VyY2U9XAogICAgaW52YWxpZCBzb3VyY2UgcmVsZWFzZTogezB9CmphdmFjLmVyci5lcnJvci53cml0aW5nLmZpbGU9XAogICAgZXJyb3Igd3JpdGluZyB7MH07IHsxfQpqYXZhYy5lcnIuc291cmNlcGF0aC5tb2R1bGVzb3VyY2VwYXRoLmNvbmZsaWN0PVwKICAgIGNhbm5vdCBzcGVjaWZ5IGJvdGggLS1zb3VyY2UtcGF0aCBhbmQgLS1tb2R1bGUtc291cmNlLXBhdGgKamF2YWMud2Fybi5zb3VyY2UudGFyZ2V0LmNvbmZsaWN0PVwKICAgIHNvdXJjZSByZWxlYXNlIHswfSByZXF1aXJlcyB0YXJnZXQgcmVsZWFzZSB7MX0KamF2YWMud2Fybi50YXJnZXQuZGVmYXVsdC5zb3VyY2UuY29uZmxpY3Q9XAogICAgdGFyZ2V0IHJlbGVhc2UgezB9IGNvbmZsaWN0cyB3aXRoIGRlZmF1bHQgc291cmNlIHJlbGVhc2UgezF9CmphdmFjLndhcm4ucHJvZmlsZS50YXJnZXQuY29uZmxpY3Q9XAogICAgcHJvZmlsZSB7MH0gaXMgbm90IHZhbGlkIGZvciB0YXJnZXQgcmVsZWFzZSB7MX0KamF2YWMuZXJyLmZpbGUubm90LmZvdW5kPVwKICAgIGZpbGUgbm90IGZvdW5kOiB7MH0KamF2YWMuZXJyLmZpbGUubm90LmRpcmVjdG9yeT1cCiAgICBub3QgYSBkaXJlY3Rvcnk6IHswfQpqYXZhYy5lcnIuZmlsZS5ub3QuZmlsZT1cCiAgICBub3QgYSBmaWxlOiB7MH0KamF2YWMuZXJyLmNhbm5vdC5hY2Nlc3MucnVudGltZS5lbnY9XAogICAgY2Fubm90IGFjY2VzcyBydW50aW1lIGVudmlyb25tZW50CmphdmFjLmVyci5iYWQudmFsdWUuZm9yLm9wdGlvbj1cCiAgICBiYWQgdmFsdWUgZm9yIHswfSBvcHRpb246ICcnezF9JycKamF2YWMuZXJyLm5vLnZhbHVlLmZvci5vcHRpb249XAogICAgbm8gdmFsdWUgZm9yIHswfSBvcHRpb24KamF2YWMuZXJyLnJlcGVhdGVkLnZhbHVlLmZvci5wYXRjaC5tb2R1bGU9XAogICAgLS1wYXRjaC1tb2R1bGUgc3BlY2lmaWVkIG1vcmUgdGhhbiBvbmNlIGZvciB7MH0KCmphdmFjLmVyci51bm1hdGNoZWQucXVvdGU9XAogICAgdW5tYXRjaGVkIHF1b3RlIGluIGVudmlyb25tZW50IHZhcmlhYmxlICVzCgojIyBtZXNzYWdlcwoKamF2YWMubXNnLnVzYWdlLmhlYWRlcj1cClVzYWdlOiB7MH0gPG9wdGlvbnM+IDxzb3VyY2UgZmlsZXM+XG5cCndoZXJlIHBvc3NpYmxlIG9wdGlvbnMgaW5jbHVkZToKCmphdmFjLm1zZy51c2FnZT1cCiAgICBVc2FnZTogezB9IDxvcHRpb25zPiA8c291cmNlIGZpbGVzPlxuXAogICAgdXNlIC0taGVscCBmb3IgYSBsaXN0IG9mIHBvc3NpYmxlIG9wdGlvbnMKCmphdmFjLm1zZy51c2FnZS5ub25zdGFuZGFyZC5mb290ZXI9XApUaGVzZSBleHRyYSBvcHRpb25zIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSB3aXRob3V0IG5vdGljZS4KCmphdmFjLm1zZy5idWc9XApBbiBleGNlcHRpb24gaGFzIG9jY3VycmVkIGluIHRoZSBjb21waWxlciAoezB9KS4gXApQbGVhc2UgZmlsZSBhIGJ1ZyBhZ2FpbnN0IHRoZSBKYXZhIGNvbXBpbGVyIHZpYSB0aGUgSmF2YSBidWcgcmVwb3J0aW5nIHBhZ2UgKGh0dHA6Ly9idWdyZXBvcnQuamF2YS5jb20pIFwKYWZ0ZXIgY2hlY2tpbmcgdGhlIEJ1ZyBEYXRhYmFzZSAoaHR0cDovL2J1Z3MuamF2YS5jb20pIGZvciBkdXBsaWNhdGVzLiBcCkluY2x1ZGUgeW91ciBwcm9ncmFtIGFuZCB0aGUgZm9sbG93aW5nIGRpYWdub3N0aWMgaW4geW91ciByZXBvcnQuIFRoYW5rIHlvdS4KCmphdmFjLm1zZy5pbz1cClxuXG5BbiBpbnB1dC9vdXRwdXQgZXJyb3Igb2NjdXJyZWQuXG5cCkNvbnN1bHQgdGhlIGZvbGxvd2luZyBzdGFjayB0cmFjZSBmb3IgZGV0YWlscy5cbgoKamF2YWMubXNnLnByb2MuYW5ub3RhdGlvbi51bmNhdWdodC5leGNlcHRpb249XApcblxuQW4gYW5ub3RhdGlvbiBwcm9jZXNzb3IgdGhyZXcgYW4gdW5jYXVnaHQgZXhjZXB0aW9uLlxuXApDb25zdWx0IHRoZSBmb2xsb3dpbmcgc3RhY2sgdHJhY2UgZm9yIGRldGFpbHMuXG4KCmphdmFjLm1zZy5wbHVnaW4udW5jYXVnaHQuZXhjZXB0aW9uPVwKXG5cbkEgcGx1Z2luIHRocmV3IGFuIHVuY2F1Z2h0IGV4Y2VwdGlvbi5cblwKQ29uc3VsdCB0aGUgZm9sbG93aW5nIHN0YWNrIHRyYWNlIGZvciBkZXRhaWxzLlxuCgpqYXZhYy5tc2cucmVzb3VyY2U9XApcblxuVGhlIHN5c3RlbSBpcyBvdXQgb2YgcmVzb3VyY2VzLlxuXApDb25zdWx0IHRoZSBmb2xsb3dpbmcgc3RhY2sgdHJhY2UgZm9yIGRldGFpbHMuXG4KCmphdmFjLnZlcnNpb249ezB9IHsxfQpqYXZhYy5mdWxsVmVyc2lvbj17MH0gZnVsbCB2ZXJzaW9uICJ7MX0iCgpqYXZhYy5lcnIucmVsZWFzZS5ib290Y2xhc3NwYXRoLmNvbmZsaWN0PVwKICAgIG9wdGlvbiB7MH0gY2Fubm90IGJlIHVzZWQgdG9nZXRoZXIgd2l0aCAtLXJlbGVhc2UKCmphdmFjLmVyci51bnN1cHBvcnRlZC5yZWxlYXNlLnZlcnNpb249XAogICAgcmVsZWFzZSB2ZXJzaW9uIHswfSBub3Qgc3VwcG9ydGVkCgpqYXZhYy5lcnIucmVsZWFzZS5ub3Quc3RhbmRhcmQuZmlsZS5tYW5hZ2VyPVwKICAgIC0tcmVsZWFzZSBvcHRpb24gc3BlY2lmaWVkLCBidXQgdGhlIHByb3ZpZGVkIEphdmFGaWxlTWFuYWdlciBpcyBub3QgYSBTdGFuZGFyZEphdmFGaWxlTWFuYWdlci4KUEsDBAoAAAgAAAY7qUpTpX0MTz0CAE89AgA0AAAAY29tL3N1bi90b29scy9qYXZhYy9yZXNvdXJjZXMvY29tcGlsZXJfamEucHJvcGVydGllcyMKIyBDb3B5cmlnaHQgKGMpIDE5OTksIDIwMTcsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiMgRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgojCiMgVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKIyB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwojIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwojIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKIyBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KIwojIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAojIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgojIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQojIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiMgYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KIwojIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KIyAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiMgSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgojCiMgUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKIyBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiMgcXVlc3Rpb25zLgojCgojIE1lc3NhZ2VzIGluIHRoaXMgZmlsZSB3aGljaCB1c2UgInBsYWNlaG9sZGVycyIgZm9yIHZhbHVlcyAoZS5nLiB7MH0sIHsxfSkKIyBhcmUgcHJlY2VkZWQgYnkgYSBzdHlsaXplZCBjb21tZW50IGRlc2NyaWJpbmcgdGhlIHR5cGUgb2YgdGhlIGNvcnJlc3BvbmRpbmcKIyB2YWx1ZXMuCiMgVGhlIHNpbXBsZSB0eXBlcyBjdXJyZW50bHkgaW4gdXNlIGFyZToKIwojIGJvb2xlYW4gICAgICAgICAgIHRydWUgb3IgZmFsc2UKIyBkaWFnbm9zdGljICAgICAgICBhIHN1Yi1tZXNzYWdlOyBzZWUgY29tcGlsZXIubWlzYy4qCiMgZnJhZ21lbnQgICAgICAgICAgc2ltaWxhciB0byAnbWVzc2FnZSBzZWdtZW50JywgYnV0IHdpdGggbW9yZSBzcGVjaWZpYyB0eXBlCiMgbW9kaWZpZXIgICAgICAgICAgYSBKYXZhIG1vZGlmaWVyOyBlLmcuIHB1YmxpYywgcHJpdmF0ZSwgcHJvdGVjdGVkCiMgZmlsZSAgICAgICAgICAgICAgYSBmaWxlIFVSTAojIGZpbGUgb2JqZWN0ICAgICAgIGEgZmlsZSBVUkwgLSBzaW1pbGFyIHRvICdmaWxlJyBidXQgdHlwaWNhbGx5IHVzZWQgZm9yIHNvdXJjZS9jbGFzcyBmaWxlcywgaGVuY2UgbW9yZSBzcGVjaWZpYwojIG5hbWUgICAgICAgICAgICAgIGEgbmFtZSwgdHlwaWNhbGx5IGEgSmF2YSBpZGVudGlmaWVyCiMgbnVtYmVyICAgICAgICAgICAgYW4gaW50ZWdlcgojIG9wdGlvbiBuYW1lICAgICAgIHRoZSBuYW1lIG9mIGEgY29tbWFuZCBsaW5lIG9wdGlvbgojIHNvdXJjZSB2ZXJzaW9uICAgIGEgc291cmNlIHZlcnNpb24gbnVtYmVyLCBzdWNoIGFzIDEuNSwgMS42LCAxLjcKIyBzdHJpbmcgICAgICAgICAgICBhIGdlbmVyYWwgc3RyaW5nCiMgc3ltYm9sICAgICAgICAgICAgdGhlIG5hbWUgb2YgYSBkZWNsYXJlZCB0eXBlCiMgc3ltYm9sIGtpbmQgICAgICAgdGhlIGtpbmQgb2YgYSBzeW1ib2wgKGkuZS4gbWV0aG9kLCB2YXJpYWJsZSkKIyBraW5kIG5hbWUgICAgICAgICBhbiBpbmZvcm1hdGl2ZSBkZXNjcmlwdGlvbiBvZiB0aGUga2luZCBvZiBhIGRlY2xhcmF0aW9uOyBzZWUgY29tcGlsZXIubWlzYy5raW5kbmFtZS4qCiMgdG9rZW4gICAgICAgICAgICAgdGhlIG5hbWUgb2YgYSBub24tdGVybWluYWwgaW4gc291cmNlIGNvZGU7IHNlZSBjb21waWxlci5taXNjLnRva2VuLioKIyB0eXBlICAgICAgICAgICAgICBhIEphdmEgdHlwZTsgZS5nLiBpbnQsIFgsIFg8VD4KIyBvYmplY3QgICAgICAgICAgICBhIEphdmEgb2JqZWN0ICh1bnNwZWNpZmllZCkKIyB1bnVzZWQgICAgICAgICAgICB0aGUgdmFsdWUgaXMgbm90IHVzZWQgaW4gdGhpcyBtZXNzYWdlCiMKIyBUaGUgZm9sbG93aW5nIGNvbXBvdW5kIHR5cGVzIGFyZSBhbHNvIHVzZWQ6CiMKIyBsaXN0IG9mIFggICAgICAgICBhIGNvbW1hLXNlcGFyYXRlZCBsaXN0IG9mIGl0ZW1zOyBlLmcuIGxpc3Qgb2YgdHlwZQojIHNldCBvZiBYICAgICAgICAgIGEgY29tbWEtc2VwYXJhdGVkIGNvbGxlY3Rpb24gb2YgaXRlbXM7IGUuZy4gc2V0IG9mIG1vZGlmaWVyCiMKIyBUaGVzZSBtYXkgYmUgY29tcG9zZWQ6CiMKIyBsaXN0IG9mIHR5cGUgb3IgbWVzc2FnZSBzZWdtZW50CiMKIyBUaGUgZm9sbG93aW5nIHR5cGUgYWxpYXNlcyBhcmUgc3VwcG9ydGVkOgojCiMgbWVzc2FnZSBzZWdtZW50IC0tPiBkaWFnbm9zdGljIG9yIGZyYWdtZW50CiMgZmlsZSBuYW1lIC0tPiBmaWxlIG9yIGZpbGUgb2JqZWN0CiMKIyBDdXN0b20gY29tbWVudHMgYXJlIHN1cHBvcnRlZCBpbiBwYXJlbnRoZXNpcyBpLmUuCiMKIyBudW1iZXIgKGNsYXNzZmlsZSBtYWpvciB2ZXJzaW9uKQojCiMgVGhlc2UgY29tbWVudHMgYXJlIHVzZWQgaW50ZXJuYWxseSBpbiBvcmRlciB0byBnZW5lcmF0ZSBhbiBlbnVtLWxpa2UgY2xhc3MgZGVjbGFyYXRpb24gY29udGFpbmluZwojIGEgbWV0aG9kL2ZpZWxkIGZvciBlYWNoIG9mIHRoZSBkaWFnbm9zdGljIGtleXMgbGlzdGVkIGhlcmUuIFRob3NlIG1ldGhvZHMvZmllbGRzIGNhbiB0aGVuIGJlIHVzZWQKIyBieSBqYXZhYyBjb2RlIHRvIGJ1aWxkIGRpYWdub3N0aWNzIGluIGEgdHlwZS1zYWZlIGZhc2hpb24uCiMKIyBJbiBhZGRpdGlvbiwgdGhlc2UgY29tbWVudHMgYXJlIHZlcmlmaWVkIGJ5IHRoZSBqdHJlZyB0ZXN0IHRlc3QvdG9vbHMvamF2YWMvZGlhZ3MvTWVzc2FnZUluZm8sCiMgdXNpbmcgaW5mbyBkZXJpdmVkIGZyb20gdGhlIGNvbGxlY3RlZCBzZXQgb2YgZXhhbXBsZXMgaW4gdGVzdC90b29scy9qYXZhYy9kaWFncy9leGFtcGxlcy4KIyBNZXNzYWdlSW5mbyBjYW4gYWxzbyBiZSBydW4gYXMgYSBzdGFuZGFsb25lIHV0aWxpdHkgcHJvdmlkaW5nIG1vcmUgZmFjaWxpdGllcwojIGZvciBtYW5pcHVsYXRpbmcgdGhpcyBmaWxlLiBGb3IgbW9yZSBkZXRhaWxzLCBzZWUgTWVzc2FnZUluZm8uamF2YS4KCiMjCiMjIGVycm9ycwojIwoKIyAwOiBzeW1ib2wKY29tcGlsZXIuZXJyLmFic3RyYWN0LmNhbnQuYmUuaW5zdGFudGlhdGVkPXswfVx1MzA2RmFic3RyYWN0XHUzMDY3XHUzMDU5XHUzMDAyXHUzMEE0XHUzMEYzXHUzMEI5XHUzMEJGXHUzMEYzXHUzMEI5XHUzMDkyXHU3NTFGXHU2MjEwXHUzMDU5XHUzMDhCXHUzMDUzXHUzMDY4XHUzMDZGXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzCgpjb21waWxlci5lcnIuYWJzdHJhY3QubWV0aC5jYW50LmhhdmUuYm9keT1hYnN0cmFjdFx1MzBFMVx1MzBCRFx1MzBDM1x1MzBDOVx1MzA0Q1x1NjcyQ1x1NEY1M1x1MzA5Mlx1NjMwMVx1MzA2NFx1MzA1M1x1MzA2OFx1MzA2Rlx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5MwoKY29tcGlsZXIuZXJyLmFscmVhZHkuYW5ub3RhdGVkPXswfSB7MX1cdTMwNkZcdTZDRThcdTkxQzhcdTMwNENcdTRFRDhcdTMwNDRcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNTkKCiMgMDogc3ltYm9sIGtpbmQsIDE6IHN5bWJvbCwgMjogc3ltYm9sIGtpbmQsIDM6IHN5bWJvbApjb21waWxlci5lcnIuYWxyZWFkeS5kZWZpbmVkPXswfSB7MX1cdTMwNkZcdTMwNTlcdTMwNjdcdTMwNkJ7Mn0gezN9XHUzMDY3XHU1QjlBXHU3RkE5XHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5CgojIDA6IHN5bWJvbCBraW5kLCAxOiBzeW1ib2wsIDI6IHN5bWJvbCBraW5kLCAzOiBzeW1ib2wga2luZCwgNDogc3ltYm9sCmNvbXBpbGVyLmVyci5hbHJlYWR5LmRlZmluZWQuaW4uY2xpbml0PXswfSB7MX1cdTMwNkZcdTMwNTlcdTMwNjdcdTMwNkJ7M30gezR9XHUzMDZFezJ9XHUzMDY3XHU1QjlBXHU3RkE5XHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5CgojIDA6IHN0cmluZwpjb21waWxlci5lcnIuYWxyZWFkeS5kZWZpbmVkLnNpbmdsZS5pbXBvcnQ9XHU1NDBDXHUzMDU4XHU1MzU4XHU3RDE0XHU1NDBEXHUzMDZFXHU1NzhCXHUzMDRDezB9XHUzMDZFXHU1MzU4XHU0RTAwXHU1NzhCXHUzMEE0XHUzMEYzXHUzMEREXHUzMEZDXHUzMEM4XHUzMDZCXHUzMDg4XHUzMDYzXHUzMDY2XHUzMDU5XHUzMDY3XHUzMDZCXHU1QjlBXHU3RkE5XHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5CgojIDA6IHN0cmluZwpjb21waWxlci5lcnIuYWxyZWFkeS5kZWZpbmVkLnN0YXRpYy5zaW5nbGUuaW1wb3J0PVx1NTQwQ1x1MzA1OFx1NTM1OFx1N0QxNFx1NTQwRFx1MzA2RVx1NTc4Qlx1MzA0Q3swfVx1MzA2RXN0YXRpY1x1NTM1OFx1NEUwMFx1NTc4Qlx1MzBBNFx1MzBGM1x1MzBERFx1MzBGQ1x1MzBDOFx1MzA2Qlx1MzA4OFx1MzA2M1x1MzA2Nlx1MzA1OVx1MzA2N1x1MzA2Qlx1NUI5QVx1N0ZBOVx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1OQoKY29tcGlsZXIuZXJyLmFscmVhZHkuZGVmaW5lZC50aGlzLnVuaXQ9ezB9XHUzMDZGXHUzMEIzXHUzMEYzXHUzMEQxXHUzMEE0XHUzMEVCXHU1MzU4XHU0RjREXHUzMDY3XHU1QjlBXHU3RkE5XHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5CgojIDA6IHR5cGUsIDE6IGxpc3Qgb2YgbmFtZQpjb21waWxlci5lcnIuYW5ub3RhdGlvbi5taXNzaW5nLmRlZmF1bHQudmFsdWU9XHU2Q0U4XHU5MUM4QHswfVx1MzA2Qlx1MzA2Rlx1ODk4MVx1N0QyMCcnezF9JydcdTMwNkVcdTMwQzdcdTMwRDVcdTMwQTlcdTMwRUJcdTMwQzhcdTUwMjRcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTMKCiMgMDogdHlwZSwgMTogbGlzdCBvZiBuYW1lCmNvbXBpbGVyLmVyci5hbm5vdGF0aW9uLm1pc3NpbmcuZGVmYXVsdC52YWx1ZS4xPVx1NkNFOFx1OTFDOEB7MH1cdTMwNkJcdTMwNkZcdTg5ODFcdTdEMjB7MX1cdTMwNkVcdTMwQzdcdTMwRDVcdTMwQTlcdTMwRUJcdTMwQzhcdTUwMjRcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTMKCiMgMDogdHlwZQpjb21waWxlci5lcnIuYW5ub3RhdGlvbi5ub3QudmFsaWQuZm9yLnR5cGU9XHU2Q0U4XHU5MUM4XHUzMDZGXHU1NzhCezB9XHUzMDZFXHU4OTgxXHU3RDIwXHUzMDZCXHU1QkZFXHUzMDU3XHUzMDY2XHU2NzA5XHU1MkI5XHUzMDY3XHUzMDZGXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzCgpjb21waWxlci5lcnIuYW5ub3RhdGlvbi50eXBlLm5vdC5hcHBsaWNhYmxlPVx1NkNFOFx1OTFDOFx1NTc4Qlx1MzA2Rlx1MzA1M1x1MzA2RVx1N0EyRVx1OTg1RVx1MzA2RVx1NUJBM1x1OEEwMFx1MzA2Qlx1NEY3Rlx1NzUyOFx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5MwoKIyAwOiB0eXBlCmNvbXBpbGVyLmVyci5hbm5vdGF0aW9uLnR5cGUubm90LmFwcGxpY2FibGUudG8udHlwZT1cdTZDRThcdTkxQzhAezB9XHUzMDZGXHUzMDUzXHUzMDZFXHU1NzhCXHUzMDZFXHUzMEIzXHUzMEYzXHUzMEM2XHUzMEFEXHUzMEI5XHUzMEM4XHUzMDZCXHU0RjdGXHU3NTI4XHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzCgpjb21waWxlci5lcnIuYW5ub3RhdGlvbi52YWx1ZS5tdXN0LmJlLmFubm90YXRpb249XHU2Q0U4XHU5MUM4XHUzMDZFXHU1MDI0XHUzMDZGXHU2Q0U4XHU5MUM4XHUzMDY3XHUzMDQyXHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5Cgpjb21waWxlci5lcnIuYW5ub3RhdGlvbi52YWx1ZS5tdXN0LmJlLmNsYXNzLmxpdGVyYWw9XHU2Q0U4XHU5MUM4XHUzMDZFXHU1MDI0XHUzMDZGXHUzMEFGXHUzMEU5XHUzMEI5XHUzMEZCXHUzMEVBXHUzMEM2XHUzMEU5XHUzMEVCXHUzMDY3XHUzMDQyXHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5Cgpjb21waWxlci5lcnIuYW5ub3RhdGlvbi52YWx1ZS5tdXN0LmJlLm5hbWUudmFsdWU9XHU2Q0U4XHU5MUM4XHUzMDZFXHU1MDI0XHUzMDZGJyduYW1lPXZhbHVlJydcdTMwNjhcdTMwNDRcdTMwNDZcdTVGNjJcdTVGMEZcdTMwNjdcdTMwNDJcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTkKCmNvbXBpbGVyLmVyci5hbm5vdGF0aW9uLnZhbHVlLm5vdC5hbGxvd2FibGUudHlwZT1cdTRGN0ZcdTc1MjhcdTMwNjdcdTMwNERcdTMwNkFcdTMwNDRcdTU3OEJcdTMwNkVcdTZDRThcdTkxQzhcdTMwNkVcdTUwMjRcdTMwNjdcdTMwNTkKCmNvbXBpbGVyLmVyci5hbm9uLmNsYXNzLmltcGwuaW50Zi5uby5hcmdzPVx1NTQwRFx1NTI0RFx1MzA2RVx1MzA2QVx1MzA0NFx1MzBBRlx1MzBFOVx1MzBCOVx1MzA0Q1x1MzBBNFx1MzBGM1x1MzBCRlx1MzBENVx1MzBBN1x1MzBGQ1x1MzBCOVx1MzA5Mlx1NUI5Rlx1ODhDNVx1MzA1N1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1OVx1MzAwMlx1NUYxNVx1NjU3MFx1MzA5Mlx1NjMwMVx1MzA2NFx1MzA1M1x1MzA2OFx1MzA2Rlx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5MwoKY29tcGlsZXIuZXJyLmFub24uY2xhc3MuaW1wbC5pbnRmLm5vLnR5cGVhcmdzPVx1NTQwRFx1NTI0RFx1MzA2RVx1MzA2QVx1MzA0NFx1MzBBRlx1MzBFOVx1MzBCOVx1MzA0Q1x1MzBBNFx1MzBGM1x1MzBCRlx1MzBENVx1MzBBN1x1MzBGQ1x1MzBCOVx1MzA5Mlx1NUI5Rlx1ODhDNVx1MzA1N1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1OVx1MzAwMlx1NTc4Qlx1NUYxNVx1NjU3MFx1MzA5Mlx1NjMwMVx1MzA2NFx1MzA1M1x1MzA2OFx1MzA2Rlx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5MwoKY29tcGlsZXIuZXJyLmFub24uY2xhc3MuaW1wbC5pbnRmLm5vLnF1YWwuZm9yLm5ldz1cdTU0MERcdTUyNERcdTMwNkVcdTMwNkFcdTMwNDRcdTMwQUZcdTMwRTlcdTMwQjlcdTMwNENcdTMwQTRcdTMwRjNcdTMwQkZcdTMwRDVcdTMwQTdcdTMwRkNcdTMwQjlcdTMwOTJcdTVCOUZcdTg4QzVcdTMwNTdcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNTlcdTMwMDJuZXdcdTMwNkJcdTRGRUVcdTk4RkVcdTVCNTBcdTMwOTJcdTYzMDFcdTMwNjRcdTMwNTNcdTMwNjhcdTMwNkZcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKCmNvbXBpbGVyLmVyci5jYW50LmluaGVyaXQuZnJvbS5hbm9uPVx1NTMzRlx1NTQwRFx1MzBBRlx1MzBFOVx1MzBCOVx1MzA0Qlx1MzA4OVx1N0Q5OVx1NjI3Rlx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5MwoKIyAwOiBzeW1ib2wsIDE6IHN5bWJvbCwgMjogc3ltYm9sCmNvbXBpbGVyLmVyci5hcnJheS5hbmQudmFyYXJncz17Mn1cdTMwNjd7MH1cdTMwNjh7MX1cdTMwNkVcdTRFMjFcdTY1QjlcdTMwOTJcdTVCQTNcdThBMDBcdTMwNTlcdTMwOEJcdTMwNTNcdTMwNjhcdTMwNkZcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTMKCmNvbXBpbGVyLmVyci5hcnJheS5kaW1lbnNpb24ubWlzc2luZz1cdTkxNERcdTUyMTdcdTMwNkVcdTU5MjdcdTMwNERcdTMwNTVcdTMwNENcdTYzMDdcdTVCOUFcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNUJcdTMwOTMKCiMgMDogdHlwZQpjb21waWxlci5lcnIuYXJyYXkucmVxLmJ1dC5mb3VuZD1cdTkxNERcdTUyMTdcdTMwNENcdTg5ODFcdTZDNDJcdTMwNTVcdTMwOENcdTMwN0VcdTMwNTdcdTMwNUZcdTMwNENcdTMwMDF7MH1cdTMwNENcdTg5OEJcdTMwNjRcdTMwNEJcdTMwOEFcdTMwN0VcdTMwNTdcdTMwNUYKCmNvbXBpbGVyLmVyci5hdHRyaWJ1dGUudmFsdWUubXVzdC5iZS5jb25zdGFudD1cdTg5ODFcdTdEMjBcdTUwMjRcdTMwNkZcdTVCOUFcdTY1NzBcdTVGMEZcdTMwNjdcdTMwNDJcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTkKCiMgMDogc3RyaW5nIChzdGF0ZW1lbnQgdHlwZSkKY29tcGlsZXIuZXJyLmJhZC5pbml0aWFsaXplcj17MH1cdTMwNkVcdTRFMERcdTZCNjNcdTMwNkFcdTUyMURcdTY3MUZcdTUzMTZcdTVCNTAKCmNvbXBpbGVyLmVyci5icmVhay5vdXRzaWRlLnN3aXRjaC5sb29wPWJyZWFrXHUzMDRDc3dpdGNoXHU2NTg3XHUzMDdFXHUzMDVGXHUzMDZGXHUzMEVCXHUzMEZDXHUzMEQ3XHUzMDZFXHU1OTE2XHUzMDZCXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5CgojIDA6IG5hbWUKY29tcGlsZXIuZXJyLmNhbGwubXVzdC5iZS5maXJzdC5zdG10LmluLmN0b3I9ezB9XHUzMDZFXHU1NDdDXHU1MUZBXHUzMDU3XHUzMDZGXHUzMEIzXHUzMEYzXHUzMEI5XHUzMEM4XHUzMEU5XHUzMEFGXHUzMEJGXHUzMDZFXHU1MTQ4XHU5ODJEXHU2NTg3XHUzMDY3XHUzMDQyXHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5CgojIDA6IHN5bWJvbCBraW5kLCAxOiBuYW1lLCAyOiBsaXN0IG9mIHR5cGUgb3IgbWVzc2FnZSBzZWdtZW50LCAzOiBsaXN0IG9mIHR5cGUgb3IgbWVzc2FnZSBzZWdtZW50LCA0OiBzeW1ib2wga2luZCwgNTogdHlwZSwgNjogbWVzc2FnZSBzZWdtZW50CmNvbXBpbGVyLmVyci5jYW50LmFwcGx5LnN5bWJvbD17NH0gezV9XHUzMDZFezB9IHsxfVx1MzA2Rlx1NjMwN1x1NUI5QVx1MzA1NVx1MzA4Q1x1MzA1Rlx1NTc4Qlx1MzA2Qlx1OTA2OVx1NzUyOFx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMlxuXHU2NzFGXHU1Rjg1XHU1MDI0OiB7Mn1cblx1NjkxQ1x1NTFGQVx1NTAyNDogezN9XG5cdTc0MDZcdTc1MzE6IHs2fQoKIyAwOiBzeW1ib2wga2luZCwgMTogbmFtZSwgMjogbGlzdCBvZiB0eXBlCmNvbXBpbGVyLmVyci5jYW50LmFwcGx5LnN5bWJvbHM9ezF9XHUzMDZCXHU5MDY5XHU1MjA3XHUzMDZBezB9XHUzMDRDXHU4OThCXHUzMDY0XHUzMDRCXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzKHsyfSkKCiMgMDogc3ltYm9sIGtpbmQsIDE6IG5hbWUsIDI6IGxpc3Qgb2YgdHlwZSBvciBtZXNzYWdlIHNlZ21lbnQsIDM6IGxpc3Qgb2YgdHlwZSBvciBtZXNzYWdlIHNlZ21lbnQsIDQ6IHN5bWJvbCBraW5kLCA1OiB0eXBlLCA2OiBtZXNzYWdlIHNlZ21lbnQKY29tcGlsZXIubWlzYy5jYW50LmFwcGx5LnN5bWJvbD17NH0gezV9XHUzMDZFezB9IHsxfVx1MzA2Rlx1NjMwN1x1NUI5QVx1MzA1NVx1MzA4Q1x1MzA1Rlx1NTc4Qlx1MzA2Qlx1OTA2OVx1NzUyOFx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1xuXHU2NzFGXHU1Rjg1XHU1MDI0OiB7Mn1cblx1NjkxQ1x1NTFGQVx1NTAyNDogezN9XG5cdTc0MDZcdTc1MzE6IHs2fQoKIyAwOiBzeW1ib2wga2luZCwgMTogbmFtZSwgMjogbGlzdCBvZiB0eXBlCmNvbXBpbGVyLm1pc2MuY2FudC5hcHBseS5zeW1ib2xzPXsxfVx1MzA2Qlx1OTA2OVx1NTIwN1x1MzA2QXswfVx1MzA0Q1x1ODk4Qlx1MzA2NFx1MzA0Qlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5Myh7Mn0pCgojIDA6IHN5bWJvbCBraW5kLCAxOiBzeW1ib2wKY29tcGlsZXIubWlzYy5uby5hYnN0cmFjdHM9ezB9IHsxfVx1MzA2N1x1NjJCRFx1OEM2MVx1MzBFMVx1MzBCRFx1MzBDM1x1MzBDOVx1MzA0Q1x1ODk4Qlx1MzA2NFx1MzA0Qlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5MwoKIyAwOiBzeW1ib2wga2luZCwgMTogc3ltYm9sCmNvbXBpbGVyLm1pc2MuaW5jb21wYXRpYmxlLmFic3RyYWN0cz17MH0gezF9XHUzMDY3XHU4OTA3XHU2NTcwXHUzMDZFXHUzMEFBXHUzMEZDXHUzMEQwXHUzMEZDXHUzMEU5XHUzMEE0XHUzMEM5XHUzMDU3XHUzMDZBXHUzMDQ0XHU2MkJEXHU4QzYxXHUzMEUxXHUzMEJEXHUzMEMzXHUzMEM5XHUzMDRDXHU4OThCXHUzMDY0XHUzMDRCXHUzMDhBXHUzMDdFXHUzMDU3XHUzMDVGCgpjb21waWxlci5lcnIuYmFkLmZ1bmN0aW9uYWwuaW50Zi5hbm5vPVx1NEU4OFx1NjcxRlx1MzA1N1x1MzA2QVx1MzA0NEBGdW5jdGlvbmFsSW50ZXJmYWNlXHU2Q0U4XHU5MUM4CgojIDA6IG1lc3NhZ2Ugc2VnbWVudApjb21waWxlci5lcnIuYmFkLmZ1bmN0aW9uYWwuaW50Zi5hbm5vLjE9XHU0RTg4XHU2NzFGXHUzMDU3XHUzMDZBXHUzMDQ0QEZ1bmN0aW9uYWxJbnRlcmZhY2VcdTZDRThcdTkxQzhcbnswfQoKIyAwOiBtZXNzYWdlIHNlZ21lbnQKY29tcGlsZXIuZXJyLmFub255bW91cy5kaWFtb25kLm1ldGhvZC5kb2VzLm5vdC5vdmVycmlkZS5zdXBlcmNsYXNzPVx1MzBFMVx1MzBCRFx1MzBDM1x1MzBDOVx1MzA2Rlx1MzBCOVx1MzBGQ1x1MzBEMVx1MzBGQ1x1MzBCRlx1MzBBNFx1MzBEN1x1MzA2RVx1MzBFMVx1MzBCRFx1MzBDM1x1MzBDOVx1MzA5Mlx1MzBBQVx1MzBGQ1x1MzBEMFx1MzBGQ1x1MzBFOVx1MzBBNFx1MzBDOVx1MzA3RVx1MzA1Rlx1MzA2Rlx1NUI5Rlx1ODhDNVx1MzA1N1x1MzA3RVx1MzA1Qlx1MzA5M1xuezB9CgojIDA6IHN5bWJvbApjb21waWxlci5taXNjLm5vdC5hLmZ1bmN0aW9uYWwuaW50Zj17MH1cdTMwNkZcdTZBNUZcdTgwRkRcdTMwQTRcdTMwRjNcdTMwQkZcdTMwRDVcdTMwQTdcdTMwRkNcdTMwQjlcdTMwNjdcdTMwNkZcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTMKCiMgMDogc3ltYm9sLCAxOiBtZXNzYWdlIHNlZ21lbnQKY29tcGlsZXIubWlzYy5ub3QuYS5mdW5jdGlvbmFsLmludGYuMT17MH1cdTMwNkZcdTZBNUZcdTgwRkRcdTMwQTRcdTMwRjNcdTMwQkZcdTMwRDVcdTMwQTdcdTMwRkNcdTMwQjlcdTMwNjdcdTMwNkZcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTNcbnsxfQoKIyAwOiBzeW1ib2wsIDE6IHN5bWJvbCBraW5kLCAyOiBzeW1ib2wKY29tcGlsZXIubWlzYy5pbnZhbGlkLmdlbmVyaWMubGFtYmRhLnRhcmdldD1cdTMwRTlcdTMwRTBcdTMwQzBcdTVGMEZcdTMwNkVcdTZBNUZcdTgwRkRcdTMwQzdcdTMwQTNcdTMwQjlcdTMwQUZcdTMwRUFcdTMwRDdcdTMwQkZcdTMwNENcdTcxMjFcdTUyQjlcdTMwNjdcdTMwNTlcbnsxfSB7Mn1cdTMwNkVcdTMwRTFcdTMwQkRcdTMwQzNcdTMwQzl7MH1cdTMwNkZcdTZDNEVcdTc1MjhcdTMwNjdcdTMwNTkKCiMgMDogc3ltYm9sIGtpbmQsIDE6IHN5bWJvbApjb21waWxlci5taXNjLmluY29tcGF0aWJsZS5kZXNjcy5pbi5mdW5jdGlvbmFsLmludGY9ezB9IHsxfVx1MzA2N1x1NEUwRFx1OTA2OVx1NTQwOFx1MzA2QVx1NkE1Rlx1ODBGRFx1MzBDN1x1MzBBM1x1MzBCOVx1MzBBRlx1MzBFQVx1MzBEN1x1MzBCRlx1MzA0Q1x1ODk4Qlx1MzA2NFx1MzA0Qlx1MzA4QVx1MzA3RVx1MzA1N1x1MzA1RgoKIyAwOiBuYW1lLCAxOiBsaXN0IG9mIHR5cGUsIDI6IHR5cGUsIDM6IGxpc3Qgb2YgdHlwZQpjb21waWxlci5taXNjLmRlc2NyaXB0b3I9XHUzMEM3XHUzMEEzXHUzMEI5XHUzMEFGXHUzMEVBXHUzMEQ3XHUzMEJGOiB7Mn0gezB9KHsxfSkKCiMgMDogbmFtZSwgMTogbGlzdCBvZiB0eXBlLCAyOiB0eXBlLCAzOiBsaXN0IG9mIHR5cGUKY29tcGlsZXIubWlzYy5kZXNjcmlwdG9yLnRocm93cz1cdTMwQzdcdTMwQTNcdTMwQjlcdTMwQUZcdTMwRUFcdTMwRDdcdTMwQkY6IHsyfSB7MH0oezF9KVx1MzA2N3szfVx1MzA0Q1x1MzBCOVx1MzBFRFx1MzBGQ1x1MzA1NVx1MzA4Q1x1MzA3RVx1MzA1OQoKIyAwOiB0eXBlCmNvbXBpbGVyLm1pc2Mubm8uc3VpdGFibGUuZnVuY3Rpb25hbC5pbnRmLmluc3Q9ezB9XHUzMDZFXHU2QTVGXHU4MEZEXHUzMEE0XHUzMEYzXHUzMEJGXHUzMEQ1XHUzMEE3XHUzMEZDXHUzMEI5XHUzMEZCXHUzMEM3XHUzMEEzXHUzMEI5XHUzMEFGXHUzMEVBXHUzMEQ3XHUzMEJGXHUzMDkyXHU2M0E4XHU4QUQ2XHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzCgojIDA6IG1lc3NhZ2Ugc2VnbWVudApjb21waWxlci5taXNjLmJhZC5pbnRlcnNlY3Rpb24udGFyZ2V0LmZvci5mdW5jdGlvbmFsLmV4cHI9XHUzMEU5XHUzMEUwXHUzMEMwXHUzMDdFXHUzMDVGXHUzMDZGXHUzMEUxXHUzMEJEXHUzMEMzXHUzMEM5XHU1M0MyXHU3MTY3XHUzMDZFXHU0RUE0XHU1REVFXHUzMEJGXHUzMEE0XHUzMEQ3XHUzMEZCXHUzMEJGXHUzMEZDXHUzMEIyXHUzMEMzXHUzMEM4XHUzMDRDXHU0RTBEXHU2QjYzXHUzMDY3XHUzMDU5XG57MH0KCiMgMDogc3ltYm9sIG9yIHR5cGUKY29tcGlsZXIubWlzYy5ub3QuYW4uaW50Zi5jb21wb25lbnQ9XHUzMEIzXHUzMEYzXHUzMEREXHUzMEZDXHUzMENEXHUzMEYzXHUzMEM4XHUzMEZCXHUzMEJGXHUzMEE0XHUzMEQ3ezB9XHUzMDZGXHUzMEE0XHUzMEYzXHUzMEJGXHUzMEQ1XHUzMEE3XHUzMEZDXHUzMEI5XHUzMDY3XHUzMDZGXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzCgojIDA6IHN5bWJvbCBraW5kLCAxOiBtZXNzYWdlIHNlZ21lbnQKY29tcGlsZXIuZXJyLmludmFsaWQubXJlZj17MH1cdTUzQzJcdTcxNjdcdTMwNENcdTcxMjFcdTUyQjlcdTMwNjdcdTMwNTlcbnsxfQoKIyAwOiBzeW1ib2wga2luZCwgMTogbWVzc2FnZSBzZWdtZW50CmNvbXBpbGVyLm1pc2MuaW52YWxpZC5tcmVmPXswfVx1NTNDMlx1NzE2N1x1MzA0Q1x1NzEyMVx1NTJCOVx1MzA2N1x1MzA1OVxuezF9Cgpjb21waWxlci5taXNjLnN0YXRpYy5tcmVmLndpdGgudGFyZ3M9c3RhdGljXHUzMEUxXHUzMEJEXHUzMEMzXHUzMEM5XHU1M0MyXHU3MTY3XHUzMDZFXHUzMEQxXHUzMEU5XHUzMEUxXHUzMEZDXHUzMEJGXHU1MzE2XHUzMDU1XHUzMDhDXHUzMDVGXHU0RkVFXHU5OEZFXHU1QjUwCgojIDA6IHN5bWJvbApjb21waWxlci5lcnIuY2FudC5hc3NpZ24udmFsLnRvLmZpbmFsLnZhcj1maW5hbFx1NTkwOVx1NjU3MHswfVx1MzA2Qlx1NTAyNFx1MzA5Mlx1NEVFM1x1NTE2NVx1MzA1OVx1MzA4Qlx1MzA1M1x1MzA2OFx1MzA2Rlx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5MwoKY29tcGlsZXIuZXJyLmNhbnQuYXNzaWduLnZhbC50by50aGlzPScnXHUzMDUzXHUzMDhDJydcdTMwNkJcdTUyNzJcdTMwOEFcdTVGNTNcdTMwNjZcdTMwOEJcdTMwNTNcdTMwNjhcdTMwNkZcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTMKCiMgMDogc3ltYm9sLCAxOiBtZXNzYWdlIHNlZ21lbnQKY29tcGlsZXIuZXJyLmNhbnQucmVmLm5vbi5lZmZlY3RpdmVseS5maW5hbC52YXI9ezF9XHUzMDRCXHUzMDg5XHU1M0MyXHU3MTY3XHUzMDU1XHUzMDhDXHUzMDhCXHUzMEVEXHUzMEZDXHUzMEFCXHUzMEVCXHU1OTA5XHU2NTcwXHUzMDZGXHUzMDAxZmluYWxcdTMwN0VcdTMwNUZcdTMwNkZcdTRFOEJcdTVCOUZcdTRFMEFcdTMwNkVmaW5hbFx1MzA2N1x1MzA0Mlx1MzA4Qlx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OQoKY29tcGlsZXIuZXJyLnRyeS53aXRoLnJlc291cmNlcy5leHByLm5lZWRzLnZhcj10cnktd2l0aC1yZXNvdXJjZXNcdTMwRUFcdTMwQkRcdTMwRkNcdTMwQjlcdTMwNkZcdTMwMDFmaW5hbFx1NTkwOVx1NjU3MFx1MzA3RVx1MzA1Rlx1MzA2Rlx1NEU4Qlx1NUI5Rlx1NEUwQVx1MzA2RWZpbmFsXHU1OTA5XHU2NTcwXHUzMDc4XHUzMDZFXHU1M0MyXHU3MTY3XHUzMDkyXHU3OTNBXHUzMDU5XHU1OTA5XHU2NTcwXHU1QkEzXHU4QTAwXHUzMDdFXHUzMDVGXHUzMDZGXHU1RjBGXHUzMDY3XHUzMDQyXHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5CgojIDA6IHN5bWJvbApjb21waWxlci5lcnIudHJ5LndpdGgucmVzb3VyY2VzLmV4cHIuZWZmZWN0aXZlbHkuZmluYWwudmFyPXRyeS13aXRoLXJlc291cmNlc1x1MzBFQVx1MzBCRFx1MzBGQ1x1MzBCOVx1MzA2OFx1MzA1N1x1MzA2Nlx1NEY3Rlx1NzUyOFx1MzA1NVx1MzA4Q1x1MzA4Qlx1NTkwOVx1NjU3MHswfVx1MzA0Q1x1MzAwMWZpbmFsXHUzMDY3XHUzMDgyXHU0RThCXHU1QjlGXHU0RTBBXHUzMDZFZmluYWxcdTMwNjdcdTMwODJcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTMKCgpjb21waWxlci5taXNjLmxhbWJkYT1cdTMwRTlcdTMwRTBcdTMwQzBcdTVGMEYKCmNvbXBpbGVyLm1pc2MuaW5uZXIuY2xzPVx1NTE4NVx1OTBFOFx1MzBBRlx1MzBFOVx1MzBCOQoKIyAwOiB0eXBlCmNvbXBpbGVyLmVyci5jYW50LmRlcmVmPXswfVx1MzA2Rlx1OTU5M1x1NjNBNVx1NTNDMlx1NzE2N1x1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5MwoKY29tcGlsZXIuZXJyLmNhbnQuZXh0ZW5kLmludGYuYW5ub3RhdGlvbj1AaW50ZXJmYWNlc1x1MzA2N1x1MzA2RicnZXh0ZW5kcycnXHUzMDZGXHU4QTMxXHU1M0VGXHUzMDU1XHUzMDhDXHUzMDdFXHUzMDVCXHUzMDkzCgojIDA6IHN5bWJvbApjb21waWxlci5lcnIuY2FudC5pbmhlcml0LmZyb20uZmluYWw9ZmluYWwgezB9XHUzMDRCXHUzMDg5XHUzMDZGXHU3RDk5XHU2MjdGXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzCgojIDA6IHN5bWJvbApjb21waWxlci5lcnIuY2FudC5yZWYuYmVmb3JlLmN0b3IuY2FsbGVkPVx1MzBCOVx1MzBGQ1x1MzBEMVx1MzBGQ1x1MzBCRlx1MzBBNFx1MzBEN1x1MzA2RVx1MzBCM1x1MzBGM1x1MzBCOVx1MzBDOFx1MzBFOVx1MzBBRlx1MzBCRlx1MzA2RVx1NTQ3Q1x1NTFGQVx1MzA1N1x1NTI0RFx1MzA2RnswfVx1MzA5Mlx1NTNDMlx1NzE2N1x1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5MwoKY29tcGlsZXIuZXJyLmNhbnQuc2VsZWN0LnN0YXRpYy5jbGFzcy5mcm9tLnBhcmFtLnR5cGU9XHUzMEQxXHUzMEU5XHUzMEUxXHUzMEZDXHUzMEJGXHUzMDZCXHUzMDU1XHUzMDhDXHUzMDVGXHU1NzhCXHUzMDRCXHUzMDg5c3RhdGljXHUzMEFGXHUzMEU5XHUzMEI5XHUzMDkyXHU5MDc4XHU2MjlFXHUzMDU5XHUzMDhCXHUzMDUzXHUzMDY4XHUzMDZGXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzCgojIDA6IHN5bWJvbCwgMTogc3RyaW5nLCAyOiBzdHJpbmcKY29tcGlsZXIuZXJyLmNhbnQuaW5oZXJpdC5kaWZmLmFyZz17MH1cdTMwOTJcdTc1NzBcdTMwNkFcdTMwOEJcdTVGMTVcdTY1NzA8ezF9Plx1MzA2ODx7Mn0+XHUzMDY3XHU3RDk5XHU2MjdGXHUzMDU5XHUzMDhCXHUzMDUzXHUzMDY4XHUzMDZGXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzCgpjb21waWxlci5lcnIuY2F0Y2gud2l0aG91dC50cnk9JydjYXRjaCcnXHUzMDc4XHUzMDZFJyd0cnknJ1x1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5MwoKIyAwOiBzeW1ib2wga2luZCwgMTogc3ltYm9sCmNvbXBpbGVyLmVyci5jbGFzaC53aXRoLnBrZy5vZi5zYW1lLm5hbWU9ezB9IHsxfVx1MzA2Rlx1NTQwQ1x1NTQwRFx1MzA2RVx1MzBEMVx1MzBDM1x1MzBCMVx1MzBGQ1x1MzBCOFx1MzA2OFx1N0FGNlx1NTQwOFx1MzA1N1x1MzA3RVx1MzA1OQoKY29tcGlsZXIuZXJyLmNsYXNzLm5vdC5hbGxvd2VkPVx1MzBBRlx1MzBFOVx1MzBCOVx1MzAwMVx1MzBBNFx1MzBGM1x1MzBCRlx1MzBENVx1MzBBN1x1MzBGQ1x1MzBCOVx1MzA3RVx1MzA1Rlx1MzA2Rlx1NTIxN1x1NjMxOVx1NTc4Qlx1MzA2RVx1NUJBM1x1OEEwMFx1MzA5Mlx1MzA1M1x1MzA1M1x1MzA2N1x1NEY3Rlx1NzUyOFx1MzA1OVx1MzA4Qlx1MzA1M1x1MzA2OFx1MzA2Rlx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5MwoKY29tcGlsZXIuZXJyLmNvbnN0LmV4cHIucmVxPVx1NUI5QVx1NjU3MFx1NUYwRlx1MzA0Q1x1NUZDNVx1ODk4MVx1MzA2N1x1MzA1OQoKY29tcGlsZXIuZXJyLmNvbnQub3V0c2lkZS5sb29wPWNvbnRpbnVlXHUzMDRDXHUzMEVCXHUzMEZDXHUzMEQ3XHUzMDZFXHU1OTE2XHUzMDZCXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5CgojIDA6IHN5bWJvbApjb21waWxlci5lcnIuY3ljbGljLmluaGVyaXRhbmNlPXswfVx1MzA5Mlx1NTQyQlx1MzA4MFx1N0Q5OVx1NjI3Rlx1MzA0Q1x1MzBFQlx1MzBGQ1x1MzBEN1x1MzA1N1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1OQoKIyAwOiBzeW1ib2wKY29tcGlsZXIuZXJyLmN5Y2xpYy5hbm5vdGF0aW9uLmVsZW1lbnQ9XHU4OTgxXHU3RDIwezB9XHUzMDZFXHU1NzhCXHUzMDRDXHUzMEVCXHUzMEZDXHUzMEQ3XHUzMDU3XHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5CgojIDA6IHVudXNlZApjb21waWxlci5lcnIuY2FsbC50by5zdXBlci5ub3QuYWxsb3dlZC5pbi5lbnVtLmN0b3I9XHU1MjE3XHU2MzE5XHU1NzhCXHUzMEIzXHUzMEYzXHUzMEI5XHUzMEM4XHUzMEU5XHUzMEFGXHUzMEJGXHUzMDY3XHUzMDZGXHUzMDAxXHUzMEI5XHUzMEZDXHUzMEQxXHUzMEZDXHUzMEFGXHUzMEU5XHUzMEI5XHUzMDZFXHU1NDdDXHU1MUZBXHUzMDU3XHUzMDZGXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzCgojIDA6IHR5cGUKY29tcGlsZXIuZXJyLm5vLnN1cGVyY2xhc3M9ezB9XHUzMDZCXHUzMDZGXHUzMEI5XHUzMEZDXHUzMEQxXHUzMEZDXHUzMEFGXHUzMEU5XHUzMEI5XHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyCgojIDA6IHN5bWJvbCwgMTogdHlwZSwgMjogc3ltYm9sLCAzOiB0eXBlLCA0OiB1bnVzZWQKY29tcGlsZXIuZXJyLmNvbmNyZXRlLmluaGVyaXRhbmNlLmNvbmZsaWN0PXsxfVx1MzA2RVx1MzBFMVx1MzBCRFx1MzBDM1x1MzBDOXswfVx1MzA2OHszfVx1MzA2RXsyfVx1MzA2Rlx1NTQwQ1x1MzA1OFx1MzBCN1x1MzBCMFx1MzBDQlx1MzBDMVx1MzBFM1x1MzA0Qlx1MzA4OVx1N0Q5OVx1NjI3Rlx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1OQoKY29tcGlsZXIuZXJyLmRlZmF1bHQuYWxsb3dlZC5pbi5pbnRmLmFubm90YXRpb24ubWVtYmVyPVx1MzBDN1x1MzBENVx1MzBBOVx1MzBFQlx1MzBDOFx1NTAyNFx1MzA2Rlx1NkNFOFx1OTFDOFx1NTc4Qlx1MzA2RVx1NUJBM1x1OEEwMFx1MzA2N1x1MzA2RVx1MzA3Rlx1NEY3Rlx1NzUyOFx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1OQoKIyAwOiBzeW1ib2wKY29tcGlsZXIuZXJyLmRvZXNudC5leGlzdD1cdTMwRDFcdTMwQzNcdTMwQjFcdTMwRkNcdTMwQjh7MH1cdTMwNkZcdTVCNThcdTU3MjhcdTMwNTdcdTMwN0VcdTMwNUJcdTMwOTMKCiMgMDogdHlwZQpjb21waWxlci5lcnIuZHVwbGljYXRlLmFubm90YXRpb24uaW52YWxpZC5yZXBlYXRlZD1cdTZDRThcdTkxQzh7MH1cdTMwNkZcdTY3MDlcdTUyQjlcdTMwNkFcdTdFNzBcdThGRDRcdTMwNTdcdTUzRUZcdTgwRkRcdTMwNkFcdTZDRThcdTkxQzhcdTMwNjdcdTMwNkZcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTMKCiMgMDogbmFtZSwgMTogdHlwZQpjb21waWxlci5lcnIuZHVwbGljYXRlLmFubm90YXRpb24ubWVtYmVyLnZhbHVlPVx1NkNFOFx1OTFDOEB7MX1cdTMwNkJcdTkxQ0RcdTg5MDdcdTMwNTdcdTMwNUZcdTg5ODFcdTdEMjAnJ3swfScnXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XHUzMDAyCgojIDA6IG5hbWUsIDE6IHVudXNlZApjb21waWxlci5lcnIuZHVwbGljYXRlLmFubm90YXRpb24ubWlzc2luZy5jb250YWluZXI9ezB9XHUzMDZGXHU3RTcwXHU4RkQ0XHUzMDU3XHU1M0VGXHU4MEZEXHUzMDZBXHU2Q0U4XHU5MUM4XHU1NzhCXHUzMDY3XHUzMDZGXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzCgojIDA6IHR5cGUsIDE6IHVudXNlZApjb21waWxlci5lcnIuaW52YWxpZC5yZXBlYXRhYmxlLmFubm90YXRpb249XHU2Q0U4XHU5MUM4XHUzMDRDXHU5MUNEXHU4OTA3XHUzMDU3XHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5OiB7MH1cdTMwNkZcdTcxMjFcdTUyQjlcdTMwNkFAUmVwZWF0YWJsZVx1NkNFOFx1OTFDOFx1MzA2N1x1NkNFOFx1OTFDOFx1NEVEOFx1MzA1MVx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1OQoKIyAwOiBzeW1ib2wgb3IgdHlwZQpjb21waWxlci5lcnIuaW52YWxpZC5yZXBlYXRhYmxlLmFubm90YXRpb24ubm8udmFsdWU9ezB9XHUzMDZGXHU2NzA5XHU1MkI5XHUzMDZBQFJlcGVhdGFibGVcdTMwNjdcdTMwNkZcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDJcdTUwMjRcdTg5ODFcdTdEMjBcdTMwRTFcdTMwQkRcdTMwQzNcdTMwQzlcdTMwNENcdTVCQTNcdThBMDBcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNUJcdTMwOTMKCiMgMDogdHlwZSwgMTogbnVtYmVyCmNvbXBpbGVyLmVyci5pbnZhbGlkLnJlcGVhdGFibGUuYW5ub3RhdGlvbi5tdWx0aXBsZS52YWx1ZXM9ezB9XHUzMDZGXHU2NzA5XHU1MkI5XHUzMDZBQFJlcGVhdGFibGVcdTMwNjdcdTMwNkZcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDJ7MX1cdTg5ODFcdTdEMjBcdTMwRTFcdTMwQkRcdTMwQzNcdTMwQzknJ3ZhbHVlJydcdTMwNENcdTVCQTNcdThBMDBcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNTkKCiMgMDogdHlwZQpjb21waWxlci5lcnIuaW52YWxpZC5yZXBlYXRhYmxlLmFubm90YXRpb24uaW52YWxpZC52YWx1ZT17MH1cdTMwNkZcdTY3MDlcdTUyQjlcdTMwNkFAUmVwZWF0YWJsZVx1MzA2N1x1MzA2Rlx1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5MzogXHU1MDI0XHU4OTgxXHU3RDIwXHUzMDRDXHU3MTIxXHU1MkI5XHUzMDY3XHUzMDU5CgojIDA6IHN5bWJvbCBvciB0eXBlLCAxOiB1bnVzZWQsIDI6IHR5cGUKY29tcGlsZXIuZXJyLmludmFsaWQucmVwZWF0YWJsZS5hbm5vdGF0aW9uLnZhbHVlLnJldHVybj1cdTUzMDVcdTU0MkJcdTMwNTlcdTMwOEJcdTZDRThcdTkxQzhcdTU3OEIoezB9KVx1MzA2Rlx1NTc4QnsyfVx1MzA2RVx1ODk4MVx1N0QyMCcndmFsdWUnJ1x1MzA5Mlx1NUJBM1x1OEEwMFx1MzA1OVx1MzA4Qlx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OQoKIyAwOiBzeW1ib2wgb3IgdHlwZSwgMTogc3ltYm9sCmNvbXBpbGVyLmVyci5pbnZhbGlkLnJlcGVhdGFibGUuYW5ub3RhdGlvbi5lbGVtLm5vbmRlZmF1bHQ9XHU1MzA1XHU1NDJCXHUzMDU5XHUzMDhCXHU2Q0U4XHU5MUM4XHU1NzhCezB9XHUzMDZCXHUzMDZGXHU4OTgxXHU3RDIwezF9XHUzMDZFXHUzMEM3XHUzMEQ1XHUzMEE5XHUzMEVCXHUzMEM4XHU1MDI0XHUzMDRDXHU2MzA3XHU1QjlBXHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDVCXHUzMDkzCgojIDA6IHN5bWJvbCwgMTogdW51c2VkLCAyOiBzeW1ib2wsIDM6IHVudXNlZApjb21waWxlci5lcnIuaW52YWxpZC5yZXBlYXRhYmxlLmFubm90YXRpb24ucmV0ZW50aW9uPVx1NTMwNVx1NTQyQlx1MzA1OVx1MzA4Qlx1NkNFOFx1OTFDOFx1NTc4Qih7MH0pXHUzMDZFXHU0RkREXHU2NzA5XHUzMDRDXHUzMDAxXHU3RTcwXHU4RkQ0XHUzMDU3XHU1M0VGXHU4MEZEXHUzMDZBXHU2Q0U4XHU5MUM4XHU1NzhCKHsyfSlcdTMwNkVcdTRGRERcdTY3MDlcdTMwODhcdTMwOEFcdTc3RURcdTMwNEZcdTMwNkFcdTMwNjNcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNTkKCiMgMDogc3ltYm9sLCAxOiBzeW1ib2wKY29tcGlsZXIuZXJyLmludmFsaWQucmVwZWF0YWJsZS5hbm5vdGF0aW9uLm5vdC5kb2N1bWVudGVkPVx1N0U3MFx1OEZENFx1MzA1N1x1NTNFRlx1ODBGRFx1MzA2QVx1NkNFOFx1OTFDOFx1NTc4Qih7MX0pXHUzMDZGQERvY3VtZW50ZWRcdTMwNjdcdTMwNTlcdTMwNENcdTMwMDFcdTUzMDVcdTU0MkJcdTMwNTlcdTMwOEJcdTZDRThcdTkxQzhcdTU3OEIoezB9KVx1MzA2Rlx1OTA1NVx1MzA0NFx1MzA3RVx1MzA1OQoKIyAwOiBzeW1ib2wsIDE6IHN5bWJvbApjb21waWxlci5lcnIuaW52YWxpZC5yZXBlYXRhYmxlLmFubm90YXRpb24ubm90LmluaGVyaXRlZD1cdTdFNzBcdThGRDRcdTMwNTdcdTUzRUZcdTgwRkRcdTMwNkFcdTZDRThcdTkxQzhcdTU3OEIoezF9KVx1MzA2RkBJbmhlcml0ZWRcdTMwNjdcdTMwNTlcdTMwNENcdTMwMDFcdTUzMDVcdTU0MkJcdTMwNTlcdTMwOEJcdTZDRThcdTkxQzhcdTU3OEIoezB9KVx1MzA2Rlx1OTA1NVx1MzA0NFx1MzA3RVx1MzA1OQoKIyAwOiBzeW1ib2wsIDE6IHN5bWJvbApjb21waWxlci5lcnIuaW52YWxpZC5yZXBlYXRhYmxlLmFubm90YXRpb24uaW5jb21wYXRpYmxlLnRhcmdldD1cdTUzMDVcdTU0MkJcdTMwNTlcdTMwOEJcdTZDRThcdTkxQzhcdTU3OEIoezB9KVx1MzA2Rlx1MzAwMVx1N0U3MFx1OEZENFx1MzA1N1x1NTNFRlx1ODBGRFx1MzA2QVx1NkNFOFx1OTFDOFx1NTc4Qih7MX0pXHUzMDg4XHUzMDhBXHU1OTFBXHUzMDRGXHUzMDZFXHUzMEJGXHUzMEZDXHUzMEIyXHUzMEMzXHUzMEM4XHUzMDZCXHU5MDY5XHU3NTI4XHUzMDU1XHUzMDhDXHUzMDdFXHUzMDU5CgojIDA6IHN5bWJvbApjb21waWxlci5lcnIuaW52YWxpZC5yZXBlYXRhYmxlLmFubm90YXRpb24ucmVwZWF0ZWQuYW5kLmNvbnRhaW5lci5wcmVzZW50PVx1MzBCM1x1MzBGM1x1MzBDNlx1MzBDQXswfVx1MzA2Rlx1NTQyQlx1MzA3RVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA4Qlx1ODk4MVx1N0QyMFx1MzA2OFx1NTQwQ1x1NjY0Mlx1MzA2Qlx1NjMwN1x1NUI5QVx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5MwoKIyAwOiB0eXBlLCAxOiBzeW1ib2wKY29tcGlsZXIuZXJyLmludmFsaWQucmVwZWF0YWJsZS5hbm5vdGF0aW9uLm5vdC5hcHBsaWNhYmxlPVx1MzBCM1x1MzBGM1x1MzBDNlx1MzBDQXswfVx1MzA2Rlx1ODk4MVx1N0QyMHsxfVx1MzA2Qlx1NEY3Rlx1NzUyOFx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5MwoKIyAwOiB0eXBlCmNvbXBpbGVyLmVyci5pbnZhbGlkLnJlcGVhdGFibGUuYW5ub3RhdGlvbi5ub3QuYXBwbGljYWJsZS5pbi5jb250ZXh0PVx1MzBCM1x1MzBGM1x1MzBDNlx1MzBDQXswfVx1MzA2Rlx1MzA1M1x1MzA2RVx1NTc4Qlx1MzA2RVx1MzBCM1x1MzBGM1x1MzBDNlx1MzBBRFx1MzBCOVx1MzBDOFx1MzA2Qlx1NEY3Rlx1NzUyOFx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5MwoKIyAwOiBuYW1lCmNvbXBpbGVyLmVyci5kdXBsaWNhdGUuY2xhc3M9XHUzMEFGXHUzMEU5XHUzMEI5ezB9XHUzMDRDXHU5MUNEXHU4OTA3XHUzMDU3XHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5Cgpjb21waWxlci5lcnIuZHVwbGljYXRlLmNhc2UubGFiZWw9Y2FzZVx1MzBFOVx1MzBEOVx1MzBFQlx1MzA0Q1x1OTFDRFx1ODkwN1x1MzA1N1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1OQoKY29tcGlsZXIuZXJyLmR1cGxpY2F0ZS5kZWZhdWx0LmxhYmVsPWRlZmF1bHRcdTMwRTlcdTMwRDlcdTMwRUJcdTMwNENcdTkxQ0RcdTg5MDdcdTMwNTdcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNTkKCmNvbXBpbGVyLmVyci5lbHNlLndpdGhvdXQuaWY9JydlbHNlJydcdTMwNzhcdTMwNkUnJ2lmJydcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTMKCmNvbXBpbGVyLmVyci5lbXB0eS5jaGFyLmxpdD1cdTdBN0FcdTMwNkVcdTY1ODdcdTVCNTdcdTMwRUFcdTMwQzZcdTMwRTlcdTMwRUJcdTMwNjdcdTMwNTkKCiMgMDogc3ltYm9sCmNvbXBpbGVyLmVyci5lbmNsLmNsYXNzLnJlcXVpcmVkPXswfVx1MzA5Mlx1NTQyQlx1MzA4MFx1NTZGMlx1MzA0Nlx1MzBBNFx1MzBGM1x1MzBCOVx1MzBCRlx1MzBGM1x1MzBCOVx1MzA0Q1x1NUZDNVx1ODk4MVx1MzA2N1x1MzA1OQoKY29tcGlsZXIuZXJyLmVudW0uYW5ub3RhdGlvbi5tdXN0LmJlLmVudW0uY29uc3RhbnQ9XHU1MjE3XHU2MzE5XHU1NzhCXHU2Q0U4XHU5MUM4XHU1MDI0XHUzMDZGXHUzMDAxXHU1MjE3XHU2MzE5XHU1NzhCXHU1QjlBXHU2NTcwXHUzMDY3XHUzMDQyXHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5Cgpjb21waWxlci5lcnIuZW51bS5jYW50LmJlLmluc3RhbnRpYXRlZD1cdTUyMTdcdTYzMTlcdTU3OEJcdTMwNkZcdTMwQTRcdTMwRjNcdTMwQjlcdTMwQkZcdTMwRjNcdTMwQjlcdTUzMTZcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTMKCmNvbXBpbGVyLmVyci5lbnVtLmxhYmVsLm11c3QuYmUudW5xdWFsaWZpZWQuZW51bT1cdTUyMTdcdTYzMTlcdTU3OEJcdTMwNkVzd2l0Y2ggY2FzZVx1MzBFOVx1MzBEOVx1MzBFQlx1MzA2Rlx1NTIxN1x1NjMxOVx1NTc4Qlx1NUI5QVx1NjU3MFx1MzA2RVx1OTc1RVx1NEZFRVx1OThGRVx1NTQwRFx1MzA2N1x1MzA0Mlx1MzA4Qlx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OQoKY29tcGlsZXIuZXJyLmVudW0ubm8uc3ViY2xhc3Npbmc9XHUzMEFGXHUzMEU5XHUzMEI5XHUzMDZGXHU3NkY0XHU2M0E1amF2YS5sYW5nLkVudW1cdTMwOTJcdTYyRTFcdTVGMzVcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTMKCmNvbXBpbGVyLmVyci5lbnVtLnR5cGVzLm5vdC5leHRlbnNpYmxlPVx1NTIxN1x1NjMxOVx1NTc4Qlx1MzA2Rlx1NjJFMVx1NUYzNVx1NTNFRlx1ODBGRFx1MzA2N1x1MzA2Rlx1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5MwoKY29tcGlsZXIuZXJyLmVudW0ubm8uZmluYWxpemU9XHU1MjE3XHU2MzE5XHU1NzhCXHUzMDZGZmluYWxpemVcdTMwRTFcdTMwQkRcdTMwQzNcdTMwQzlcdTMwOTJcdTYzMDFcdTMwNjRcdTMwNTNcdTMwNjhcdTMwNkZcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTMKCiMgMDogZmlsZSBuYW1lLCAxOiBzdHJpbmcKY29tcGlsZXIuZXJyLmVycm9yLnJlYWRpbmcuZmlsZT17MH1cdTMwNkVcdThBQURcdThGQkNcdTMwN0ZcdTMwQThcdTMwRTlcdTMwRkNcdTMwNjdcdTMwNTlcdTMwMDJ7MX0KCiMgMDogdHlwZQpjb21waWxlci5lcnIuZXhjZXB0LmFscmVhZHkuY2F1Z2h0PVx1NEY4Qlx1NTkxNnswfVx1MzA2Rlx1MzA1OVx1MzA2N1x1MzA2Qlx1NjM1NVx1NjM0OVx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1OQoKIyAwOiB0eXBlCmNvbXBpbGVyLmVyci5leGNlcHQubmV2ZXIudGhyb3duLmluLnRyeT1cdTRGOEJcdTU5MTZ7MH1cdTMwNkZcdTVCRkVcdTVGRENcdTMwNTlcdTMwOEJ0cnlcdTY1ODdcdTMwNkVcdTY3MkNcdTRGNTNcdTMwNjdcdTMwNkZcdTMwQjlcdTMwRURcdTMwRkNcdTMwNTVcdTMwOENcdTMwN0VcdTMwNUJcdTMwOTMKCiMgMDogc3ltYm9sCmNvbXBpbGVyLmVyci5maW5hbC5wYXJhbWV0ZXIubWF5Lm5vdC5iZS5hc3NpZ25lZD1maW5hbFx1MzBEMVx1MzBFOVx1MzBFMVx1MzBGQ1x1MzBCRnswfVx1MzA2Qlx1NTAyNFx1MzA5Mlx1NEVFM1x1NTE2NVx1MzA1OVx1MzA4Qlx1MzA1M1x1MzA2OFx1MzA2Rlx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5MwoKIyAwOiBzeW1ib2wKY29tcGlsZXIuZXJyLnRyeS5yZXNvdXJjZS5tYXkubm90LmJlLmFzc2lnbmVkPVx1ODFFQVx1NTJENVx1MzBBRlx1MzBFRFx1MzBGQ1x1MzBCQVx1NTNFRlx1ODBGRFx1MzA2QVx1MzBFQVx1MzBCRFx1MzBGQ1x1MzBCOXswfVx1MzA2Qlx1NTAyNFx1MzA5Mlx1NEVFM1x1NTE2NVx1MzA1OVx1MzA4Qlx1MzA1M1x1MzA2OFx1MzA2Rlx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5MwoKIyAwOiBzeW1ib2wKY29tcGlsZXIuZXJyLm11bHRpY2F0Y2gucGFyYW1ldGVyLm1heS5ub3QuYmUuYXNzaWduZWQ9XHU4OTA3XHU2NTcwY2F0Y2hcdTMwRDFcdTMwRTlcdTMwRTFcdTMwRkNcdTMwQkZ7MH1cdTMwNkJcdTUwMjRcdTMwOTJcdTRFRTNcdTUxNjVcdTMwNTlcdTMwOEJcdTMwNTNcdTMwNjhcdTMwNkZcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTMKCiMgMDogdHlwZSwgMTogdHlwZQpjb21waWxlci5lcnIubXVsdGljYXRjaC50eXBlcy5tdXN0LmJlLmRpc2pvaW50PVx1ODkwN1x1NjU3MGNhdGNoXHU2NTg3XHUzMDZFXHU0RUUzXHU2NkZGXHUzMDkyXHUzMEI1XHUzMEQ2XHUzMEFGXHUzMEU5XHUzMEI5XHU1MzE2XHUzMDZCXHUzMDg4XHUzMDYzXHUzMDY2XHU5NUEyXHU5MDIzXHU0RUQ4XHUzMDUxXHUzMDhCXHUzMDUzXHUzMDY4XHUzMDZGXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzXG5cdTRFRTNcdTY2RkZ7MH1cdTMwNkZcdTRFRTNcdTY2RkZ7MX1cdTMwNkVcdTMwQjVcdTMwRDZcdTMwQUZcdTMwRTlcdTMwQjlcdTMwNjdcdTMwNTkKCmNvbXBpbGVyLmVyci5maW5hbGx5LndpdGhvdXQudHJ5PScnZmluYWxseScnXHUzMDc4XHUzMDZFJyd0cnknJ1x1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5MwoKIyAwOiB0eXBlLCAxOiBtZXNzYWdlIHNlZ21lbnQKY29tcGlsZXIuZXJyLmZvcmVhY2gubm90LmFwcGxpY2FibGUudG8udHlwZT1mb3ItZWFjaFx1MzA2Rlx1NUYwRlx1MzA2RVx1MzBCRlx1MzBBNFx1MzBEN1x1MzA2Qlx1NEY3Rlx1NzUyOFx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1xuXHU2NzFGXHU1Rjg1XHU1MDI0OiB7MX1cblx1NjkxQ1x1NTFGQVx1NTAyNDogezB9Cgpjb21waWxlci5lcnIuZnAubnVtYmVyLnRvby5sYXJnZT1cdTZENkVcdTUyRDVcdTVDMEZcdTY1NzBcdTcwQjlcdTY1NzBcdTMwNENcdTU5MjdcdTMwNERcdTMwNTlcdTMwNEVcdTMwN0VcdTMwNTkKCmNvbXBpbGVyLmVyci5mcC5udW1iZXIudG9vLnNtYWxsPVx1NkQ2RVx1NTJENVx1NUMwRlx1NjU3MFx1NzBCOVx1NjU3MFx1MzA0Q1x1NUMwRlx1MzA1NVx1MzA1OVx1MzA0RVx1MzA3RVx1MzA1OQoKY29tcGlsZXIuZXJyLmdlbmVyaWMuYXJyYXkuY3JlYXRpb249XHU2QzRFXHU3NTI4XHU5MTREXHU1MjE3XHUzMDkyXHU0RjVDXHU2MjEwXHUzMDU3XHUzMDdFXHUzMDU5Cgpjb21waWxlci5lcnIuZ2VuZXJpYy50aHJvd2FibGU9XHU2QzRFXHU3NTI4XHUzMEFGXHUzMEU5XHUzMEI5XHUzMDZGamF2YS5sYW5nLlRocm93YWJsZVx1MzA5Mlx1NjJFMVx1NUYzNVx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5MwoKIyAwOiBzeW1ib2wKY29tcGlsZXIuZXJyLmljbHMuY2FudC5oYXZlLnN0YXRpYy5kZWNsPVx1NTE4NVx1OTBFOFx1MzBBRlx1MzBFOVx1MzBCOXswfVx1MzA2RVx1OTc1OVx1NzY4NFx1NUJBM1x1OEEwMFx1MzA0Q1x1NEUwRFx1NkI2M1x1MzA2N1x1MzA1OVxuXHU0RkVFXHU5OEZFXHU1QjUwJydzdGF0aWMnJ1x1MzA2Rlx1NUI5QVx1NjU3MFx1MzA0QVx1MzA4OFx1MzA3M1x1NTkwOVx1NjU3MFx1MzA2RVx1NUJBM1x1OEEwMFx1MzA2N1x1MzA2RVx1MzA3Rlx1NEY3Rlx1NzUyOFx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1OQoKIyAwOiBzdHJpbmcKY29tcGlsZXIuZXJyLmlsbGVnYWwuY2hhcj0nJ3swfScnXHUzMDZGXHU0RTBEXHU2QjYzXHUzMDZBXHU2NTg3XHU1QjU3XHUzMDY3XHUzMDU5CgojIDA6IHN0cmluZywgMTogc3RyaW5nCmNvbXBpbGVyLmVyci5pbGxlZ2FsLmNoYXIuZm9yLmVuY29kaW5nPVx1MzA1M1x1MzA2RVx1NjU4N1x1NUI1NygweHswfSlcdTMwNkZcdTMwMDFcdTMwQThcdTMwRjNcdTMwQjNcdTMwRkNcdTMwQzdcdTMwQTNcdTMwRjNcdTMwQjB7MX1cdTMwNkJcdTMwREVcdTMwQzNcdTMwRDdcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTMKCiMgMDogc2V0IG9mIG1vZGlmaWVyLCAxOiBzZXQgb2YgbW9kaWZpZXIKY29tcGlsZXIuZXJyLmlsbGVnYWwuY29tYmluYXRpb24ub2YubW9kaWZpZXJzPVx1NEZFRVx1OThGRVx1NUI1MHswfVx1MzA2OHsxfVx1MzA2RVx1N0Q0NFx1NTQwOFx1MzA1Qlx1MzA2Rlx1NEUwRFx1NkI2M1x1MzA2N1x1MzA1OQoKY29tcGlsZXIuZXJyLmlsbGVnYWwuZW51bS5zdGF0aWMucmVmPVx1NTIxRFx1NjcxRlx1NTMxNlx1NUI1MFx1MzA0Qlx1MzA4OXN0YXRpY1x1MzBENVx1MzBBM1x1MzBGQ1x1MzBFQlx1MzBDOVx1MzA3OFx1MzA2RVx1NTNDMlx1NzE2N1x1MzA0Q1x1NEUwRFx1NkI2M1x1MzA2N1x1MzA1OQoKY29tcGlsZXIuZXJyLmlsbGVnYWwuZXNjLmNoYXI9XHUzMEE4XHUzMEI5XHUzMEIxXHUzMEZDXHUzMEQ3XHU2NTg3XHU1QjU3XHUzMDRDXHU0RTBEXHU2QjYzXHUzMDY3XHUzMDU5Cgpjb21waWxlci5lcnIuaWxsZWdhbC5mb3J3YXJkLnJlZj1cdTUyNERcdTY1QjlcdTUzQzJcdTcxNjdcdTMwNENcdTRFMERcdTZCNjNcdTMwNjdcdTMwNTkKCiMgMDogc3ltYm9sLCAxOiBzdHJpbmcKY29tcGlsZXIuZXJyLm5vdC5pbi5wcm9maWxlPXswfVx1MzA2Rlx1MzBEN1x1MzBFRFx1MzBENVx1MzBBMVx1MzBBNFx1MzBFQicnezF9JydcdTMwNjdcdTRGN0ZcdTc1MjhcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTMKCiMgMDogc3ltYm9sCmNvbXBpbGVyLndhcm4uZm9yd2FyZC5yZWY9XHU1MjFEXHU2NzFGXHU1MzE2XHUzMDU1XHUzMDhDXHUzMDhCXHU1MjREXHUzMDZFXHU1OTA5XHU2NTcwJyd7MH0nJ1x1MzA5Mlx1NTNDMlx1NzE2N1x1MzA1N1x1MzA4OFx1MzA0Nlx1MzA2OFx1MzA1N1x1MzA3RVx1MzA1N1x1MzA1RgoKY29tcGlsZXIuZXJyLmlsbGVnYWwuc2VsZi5yZWY9XHU1MjFEXHU2NzFGXHU1MzE2XHU1QjUwXHU1MTg1XHUzMDZFXHU4MUVBXHU1REYxXHU1M0MyXHU3MTY3CgojIDA6IHN5bWJvbApjb21waWxlci53YXJuLnNlbGYucmVmPVx1NTIxRFx1NjcxRlx1NTMxNlx1NUI1MFx1NTE4NVx1MzA2RVx1NTkwOVx1NjU3MCcnezB9JydcdTMwNkVcdTgxRUFcdTVERjFcdTUzQzJcdTcxNjcKCmNvbXBpbGVyLmVyci5pbGxlZ2FsLmdlbmVyaWMudHlwZS5mb3IuaW5zdG9mPWluc3RhbmNlb2ZcdTMwNkVcdTdEQ0ZcdTc5RjBcdTU3OEJcdTMwNENcdTRFMERcdTZCNjNcdTMwNjdcdTMwNTkKCiMgMDogdHlwZQpjb21waWxlci5lcnIuaWxsZWdhbC5pbml0aWFsaXplci5mb3IudHlwZT17MH1cdTMwNkVcdTUyMURcdTY3MUZcdTUzMTZcdTVCNTBcdTMwNENcdTRFMERcdTZCNjNcdTMwNjdcdTMwNTkKCmNvbXBpbGVyLmVyci5pbGxlZ2FsLmxpbmUuZW5kLmluLmNoYXIubGl0PVx1NjU4N1x1NUI1N1x1MzBFQVx1MzBDNlx1MzBFOVx1MzBFQlx1MzA2RVx1ODg0Q1x1NjcyQlx1MzA0Q1x1NEUwRFx1NkI2M1x1MzA2N1x1MzA1OQoKY29tcGlsZXIuZXJyLmlsbGVnYWwubm9uYXNjaWkuZGlnaXQ9XHU0RTBEXHU2QjYzXHUzMDZBXHU5NzVFQVNDSUlcdTY1NzBcdTVCNTdcdTMwNjdcdTMwNTkKCmNvbXBpbGVyLmVyci5pbGxlZ2FsLnVuZGVyc2NvcmU9XHU0RTBEXHU2QjYzXHUzMDZBXHUzMEEyXHUzMEYzXHUzMEMwXHUzMEZDXHUzMEI5XHUzMEIzXHUzMEEyXHUzMDY3XHUzMDU5Cgpjb21waWxlci5lcnIuaWxsZWdhbC5kb3Q9XHU0RTBEXHU2QjYzXHUzMDZBJycuJydcdTMwNjdcdTMwNTkKCiMgMDogc3ltYm9sCmNvbXBpbGVyLmVyci5pbGxlZ2FsLnF1YWwubm90LmljbHM9XHU0RkVFXHU5OEZFXHU1QjUwXHUzMDRDXHU0RTBEXHU2QjYzXHUzMDY3XHUzMDU5XHUzMDAyezB9XHUzMDZGXHU1MTg1XHU5MEU4XHUzMEFGXHUzMEU5XHUzMEI5XHUzMDY3XHUzMDZGXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzCgpjb21waWxlci5lcnIuaWxsZWdhbC5zdGFydC5vZi5leHByPVx1NUYwRlx1MzA2RVx1OTU4Qlx1NTlDQlx1MzA0Q1x1NEUwRFx1NkI2M1x1MzA2N1x1MzA1OQoKY29tcGlsZXIuZXJyLmlsbGVnYWwuc3RhcnQub2Yuc3RtdD1cdTY1ODdcdTMwNkVcdTk1OEJcdTU5Q0JcdTMwNENcdTRFMERcdTZCNjNcdTMwNjdcdTMwNTkKCmNvbXBpbGVyLmVyci5pbGxlZ2FsLnN0YXJ0Lm9mLnR5cGU9XHU1NzhCXHUzMDZFXHU5NThCXHU1OUNCXHUzMDRDXHU0RTBEXHU2QjYzXHUzMDY3XHUzMDU5Cgpjb21waWxlci5lcnIuaWxsZWdhbC51bmljb2RlLmVzYz1Vbmljb2RlXHUzMEE4XHUzMEI5XHUzMEIxXHUzMEZDXHUzMEQ3XHUzMDRDXHU0RTBEXHU2QjYzXHUzMDY3XHUzMDU5CgojIDA6IHN5bWJvbApjb21waWxlci5lcnIuaW1wb3J0LnJlcXVpcmVzLmNhbm9uaWNhbD1cdTMwQTRcdTMwRjNcdTMwRERcdTMwRkNcdTMwQzhcdTMwNkJcdTMwNkZ7MH1cdTMwNkVcdTZBMTlcdTZFOTZcdTU0MERcdTMwNENcdTVGQzVcdTg5ODFcdTMwNjdcdTMwNTkKCmNvbXBpbGVyLmVyci5pbXByb3Blcmx5LmZvcm1lZC50eXBlLnBhcmFtLm1pc3Npbmc9XHU1NzhCXHUzMDZFXHU1RjYyXHU1RjBGXHUzMDRDXHU0RTBEXHU5MDY5XHU1MjA3XHUzMDY3XHUzMDU5XHUzMDAyXHUzMEQxXHUzMEU5XHUzMEUxXHUzMEZDXHUzMEJGXHUzMDRDXHU0RTBEXHU4REIzXHUzMDU3XHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5Cgpjb21waWxlci5lcnIuaW1wcm9wZXJseS5mb3JtZWQudHlwZS5pbm5lci5yYXcucGFyYW09XHU1NzhCXHUzMDZFXHU1RjYyXHU1RjBGXHUzMDRDXHU0RTBEXHU5MDY5XHU1MjA3XHUzMDY3XHUzMDU5XHUzMDAycmF3XHU1NzhCXHUzMDZCXHU2MzA3XHU1QjlBXHUzMDU1XHUzMDhDXHUzMDVGXHU1NzhCXHU1RjE1XHU2NTcwXHUzMDY3XHUzMDU5CgojIDA6IHR5cGUsIDE6IHR5cGUKY29tcGlsZXIuZXJyLmluY29tcGFyYWJsZS50eXBlcz1cdTU3OEJ7MH1cdTMwNjh7MX1cdTMwNkZcdTZCRDRcdThGMDNcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTMKCiMgMDogbnVtYmVyCmNvbXBpbGVyLmVyci5pbnQubnVtYmVyLnRvby5sYXJnZT1cdTY1NzRcdTY1NzB7MH1cdTMwNENcdTU5MjdcdTMwNERcdTMwNTlcdTMwNEVcdTMwN0VcdTMwNTkKCmNvbXBpbGVyLmVyci5pbnRmLmFubm90YXRpb24ubWVtYmVycy5jYW50LmhhdmUucGFyYW1zPVx1NkNFOFx1OTFDOFx1NTc4Qlx1NUJBM1x1OEEwMFx1NTE4NVx1MzA2RVx1ODk4MVx1N0QyMFx1MzA0Q1x1NEVFRVx1MzBEMVx1MzBFOVx1MzBFMVx1MzBGQ1x1MzBCRlx1MzA5Mlx1NUJBM1x1OEEwMFx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5MwoKIyAwOiBzeW1ib2wKY29tcGlsZXIuZXJyLmludGYuYW5ub3RhdGlvbi5jYW50LmhhdmUudHlwZS5wYXJhbXM9XHU2Q0U4XHU5MUM4XHU1NzhCezB9XHUzMDZGXHU2QzRFXHU3NTI4XHUzMDZCXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzCgpjb21waWxlci5lcnIuaW50Zi5hbm5vdGF0aW9uLm1lbWJlcnMuY2FudC5oYXZlLnR5cGUucGFyYW1zPVx1NkNFOFx1OTFDOFx1NTc4Qlx1NUJBM1x1OEEwMFx1NTE4NVx1MzA2RVx1ODk4MVx1N0QyMFx1MzA2Rlx1NkM0RVx1NzUyOFx1MzBFMVx1MzBCRFx1MzBDM1x1MzBDOVx1MzA2Qlx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5MwoKIyAwOiBzeW1ib2wsIDE6IHR5cGUKY29tcGlsZXIuZXJyLmludGYuYW5ub3RhdGlvbi5tZW1iZXIuY2xhc2g9XHU2Q0U4XHU5MUM4XHU1NzhCezF9XHUzMDY3XHUzMEUxXHUzMEJEXHUzMEMzXHUzMEM5ezB9XHUzMDY4XHU1NDBDXHUzMDU4XHU1NDBEXHU1MjREXHUzMDZFXHU4OTgxXHU3RDIwXHUzMDRDXHU1QkEzXHU4QTAwXHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5Cgpjb21waWxlci5lcnIuaW50Zi5leHBlY3RlZC5oZXJlPVx1MzA1M1x1MzA1M1x1MzA2Qlx1MzBBNFx1MzBGM1x1MzBCRlx1MzBENVx1MzBBN1x1MzBGQ1x1MzBCOVx1MzA0Q1x1NUZDNVx1ODk4MVx1MzA2N1x1MzA1OQoKY29tcGlsZXIuZXJyLmludGYubWV0aC5jYW50LmhhdmUuYm9keT1cdTMwQTRcdTMwRjNcdTMwQkZcdTMwRDVcdTMwQTdcdTMwRkNcdTMwQjlcdTYyQkRcdThDNjFcdTMwRTFcdTMwQkRcdTMwQzNcdTMwQzlcdTMwNENcdTY3MkNcdTRGNTNcdTMwOTJcdTYzMDFcdTMwNjRcdTMwNTNcdTMwNjhcdTMwNkZcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTMKCiMgMDogc3ltYm9sCmNvbXBpbGVyLmVyci5pbnZhbGlkLmFubm90YXRpb24ubWVtYmVyLnR5cGU9XHU2Q0U4XHU5MUM4XHU1NzhCXHUzMDZFXHU4OTgxXHU3RDIwezB9XHUzMDZFXHU1NzhCXHUzMDRDXHU3MTIxXHU1MkI5XHUzMDY3XHUzMDU5Cgpjb21waWxlci5lcnIuaW52YWxpZC5iaW5hcnkubnVtYmVyPTJcdTkwMzJcdTY1NzBcdTVCNTdcdTMwNkZcdTVDMTFcdTMwNkFcdTMwNEZcdTMwNjhcdTMwODIxXHU2ODQxXHUzMDZFMlx1OTAzMlx1NjU3MFx1MzA5Mlx1NTQyQlx1MzA4MFx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OQoKY29tcGlsZXIuZXJyLmludmFsaWQuaGV4Lm51bWJlcj0xNlx1OTAzMlx1NjU3MFx1NUI1N1x1MzA2Rlx1NUMxMVx1MzA2QVx1MzA0Rlx1MzA2OFx1MzA4MjFcdTY4NDFcdTMwNkUxNlx1OTAzMlx1NjU3MFx1MzA5Mlx1NTQyQlx1MzA4MFx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OQoKY29tcGlsZXIuZXJyLmludmFsaWQubWV0aC5kZWNsLnJldC50eXBlLnJlcT1cdTcxMjFcdTUyQjlcdTMwNkFcdTMwRTFcdTMwQkRcdTMwQzNcdTMwQzlcdTVCQTNcdThBMDBcdTMwNjdcdTMwNTlcdTMwMDJcdTYyM0JcdTMwOEFcdTUwMjRcdTMwNkVcdTU3OEJcdTMwNENcdTVGQzVcdTg5ODFcdTMwNjdcdTMwNTlcdTMwMDIKCmNvbXBpbGVyLmVyci52YXJhcmdzLmFuZC5vbGQuYXJyYXkuc3ludGF4PVx1NjVFN1x1NUYwRlx1MzA2RVx1OTE0RFx1NTIxN1x1ODg2OFx1OEExOFx1NkNENVx1MzA2Rlx1NTNFRlx1NTkwOVx1NUYxNVx1NjU3MFx1MzBEMVx1MzBFOVx1MzBFMVx1MzBGQ1x1MzBCRlx1MzA2N1x1MzA2Rlx1NEY3Rlx1NzUyOFx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5MwoKY29tcGlsZXIuZXJyLnZhcmFyZ3MuYW5kLnJlY2VpdmVyID12YXJhcmdzXHU4ODY4XHU4QTE4XHUzMDZGXHU1M0Q3XHU1M0Q2XHUzMDhBXHU1MDc0XHUzMEQxXHUzMEU5XHUzMEUxXHUzMEZDXHUzMEJGXHUzMDY3XHU0RjdGXHU3NTI4XHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzCgpjb21waWxlci5lcnIudmFyYXJncy5tdXN0LmJlLmxhc3QgPVx1NTNFRlx1NTkwOVx1NUYxNVx1NjU3MFx1MzBEMVx1MzBFOVx1MzBFMVx1MzBGQ1x1MzBCRlx1MzA2Rlx1NjcwMFx1NUY4Q1x1MzA2RVx1MzBEMVx1MzBFOVx1MzBFMVx1MzBGQ1x1MzBCRlx1MzA2Qlx1MzA1OVx1MzA4Qlx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OQoKY29tcGlsZXIuZXJyLmFycmF5LmFuZC5yZWNlaXZlciA9XHU2NUU3XHU1RjBGXHUzMDZFXHU5MTREXHU1MjE3XHU4ODY4XHU4QTE4XHU2Q0Q1XHUzMDZGXHU1M0Q3XHU1M0Q2XHUzMDhBXHU1MDc0XHUzMEQxXHUzMEU5XHUzMEUxXHUzMEZDXHUzMEJGXHUzMDY3XHUzMDZGXHU0RjdGXHU3NTI4XHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzCgpjb21waWxlci5lcnIudmFyaWFibGUubm90LmFsbG93ZWQ9XHU1OTA5XHU2NTcwXHUzMDZFXHU1QkEzXHU4QTAwXHUzMDkyXHUzMDUzXHUzMDUzXHUzMDY3XHU0RjdGXHU3NTI4XHUzMDU5XHUzMDhCXHUzMDUzXHUzMDY4XHUzMDZGXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzCgojIDA6IG5hbWUKY29tcGlsZXIuZXJyLmxhYmVsLmFscmVhZHkuaW4udXNlPVx1MzBFOVx1MzBEOVx1MzBFQnswfVx1MzA2Rlx1MzA1OVx1MzA2N1x1MzA2Qlx1NEY3Rlx1NzUyOFx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1OQoKIyAwOiBzeW1ib2wKY29tcGlsZXIuZXJyLmxvY2FsLnZhci5hY2Nlc3NlZC5mcm9tLmljbHMubmVlZHMuZmluYWw9XHUzMEVEXHUzMEZDXHUzMEFCXHUzMEVCXHU1OTA5XHU2NTcwezB9XHUzMDZGXHU1MTg1XHU5MEU4XHUzMEFGXHUzMEU5XHUzMEI5XHUzMDRCXHUzMDg5XHUzMEEyXHUzMEFGXHUzMEJCXHUzMEI5XHUzMDU1XHUzMDhDXHUzMDdFXHUzMDU5XHUzMDAyZmluYWxcdTMwNjdcdTVCQTNcdThBMDBcdTMwNTVcdTMwOENcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTkKCmNvbXBpbGVyLmVyci5sb2NhbC5lbnVtPVx1NTIxN1x1NjMxOVx1NTc4Qlx1MzA2Rlx1MzBFRFx1MzBGQ1x1MzBBQlx1MzBFQlx1MzA2Qlx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5MwoKY29tcGlsZXIuZXJyLmNhbm5vdC5jcmVhdGUuYXJyYXkud2l0aC50eXBlLmFyZ3VtZW50cz1cdTU3OEJcdTVGMTVcdTY1NzBcdTMwOTJcdTYzMDFcdTMwNjRcdTkxNERcdTUyMTdcdTMwOTJcdTRGNUNcdTYyMTBcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTMKCmNvbXBpbGVyLmVyci5jYW5ub3QuY3JlYXRlLmFycmF5LndpdGguZGlhbW9uZD0nJzw+JydcdTMwOTJcdTYzMDFcdTMwNjRcdTkxNERcdTUyMTdcdTMwNkZcdTRGNUNcdTYyMTBcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTMKCmNvbXBpbGVyLmVyci5pbnZhbGlkLm1vZHVsZS5kaXJlY3RpdmU9XHUzMEUyXHUzMEI4XHUzMEU1XHUzMEZDXHUzMEVCXHUzMEZCXHUzMEM3XHUzMEEzXHUzMEVDXHUzMEFGXHUzMEM2XHUzMEEzXHUzMEQ2XHUzMEZCXHUzMEFEXHUzMEZDXHUzMEVGXHUzMEZDXHUzMEM5XHUzMDdFXHUzMDVGXHUzMDZGJyd9JydcdTMwNENcdTVGQzVcdTg5ODFcdTMwNjdcdTMwNTkKCiMKIyBsaW1pdHMuICBXZSBkb24ndCBnaXZlIHRoZSBsaW1pdHMgaW4gdGhlIGRpYWdub3N0aWMgYmVjYXVzZSB3ZSBleHBlY3QKIyB0aGVtIHRvIGNoYW5nZSwgeWV0IHdlIHdhbnQgdG8gdXNlIHRoZSBzYW1lIGRpYWdub3N0aWMuICBUaGVzZSBhcmUgYWxsCiMgZGV0ZWN0ZWQgZHVyaW5nIGNvZGUgZ2VuZXJhdGlvbi4KIwpjb21waWxlci5lcnIubGltaXQuY29kZT1cdTMwQjNcdTMwRkNcdTMwQzlcdTMwNENcdTU5MjdcdTMwNERcdTMwNTlcdTMwNEVcdTMwN0VcdTMwNTkKCmNvbXBpbGVyLmVyci5saW1pdC5jb2RlLnRvby5sYXJnZS5mb3IudHJ5LnN0bXQ9dHJ5XHU2NTg3XHUzMDZFXHUzMEIzXHUzMEZDXHUzMEM5XHUzMDRDXHU1OTI3XHUzMDREXHUzMDU5XHUzMDRFXHUzMDdFXHUzMDU5Cgpjb21waWxlci5lcnIubGltaXQuZGltZW5zaW9ucz1cdTkxNERcdTUyMTdcdTU3OEJcdTMwNkVcdTZCMjFcdTUxNDNcdTMwNENcdTU5MUFcdTMwNTlcdTMwNEVcdTMwN0VcdTMwNTkKCmNvbXBpbGVyLmVyci5saW1pdC5sb2NhbHM9XHUzMEVEXHUzMEZDXHUzMEFCXHUzMEVCXHU1OTA5XHU2NTcwXHUzMDRDXHU1OTFBXHUzMDU5XHUzMDRFXHUzMDdFXHUzMDU5Cgpjb21waWxlci5lcnIubGltaXQucGFyYW1ldGVycz1cdTMwRDFcdTMwRTlcdTMwRTFcdTMwRkNcdTMwQkZcdTMwNENcdTU5MUFcdTMwNTlcdTMwNEVcdTMwN0VcdTMwNTkKCmNvbXBpbGVyLmVyci5saW1pdC5wb29sPVx1NUI5QVx1NjU3MFx1MzA0Q1x1NTkxQVx1MzA1OVx1MzA0RVx1MzA3RVx1MzA1OQoKY29tcGlsZXIuZXJyLmxpbWl0LnBvb2wuaW4uY2xhc3M9XHUzMEFGXHUzMEU5XHUzMEI5ezB9XHU1MTg1XHUzMDZFXHU1QjlBXHU2NTcwXHUzMDRDXHU1OTFBXHUzMDU5XHUzMDRFXHUzMDdFXHUzMDU5Cgpjb21waWxlci5lcnIubGltaXQuc3RhY2s9XHUzMEIzXHUzMEZDXHUzMEM5XHUzMDRDXHU4OTgxXHU2QzQyXHUzMDU5XHUzMDhCXHUzMEI5XHUzMEJGXHUzMEMzXHUzMEFGXHUzMDRDXHU1OTFBXHUzMDU5XHUzMDRFXHUzMDdFXHUzMDU5Cgpjb21waWxlci5lcnIubGltaXQuc3RyaW5nPVx1NUI5QVx1NjU3MFx1NjU4N1x1NUI1N1x1NTIxN1x1MzA0Q1x1OTU3N1x1MzA1OVx1MzA0RVx1MzA3RVx1MzA1OQoKY29tcGlsZXIuZXJyLmxpbWl0LnN0cmluZy5vdmVyZmxvdz1cdTY1ODdcdTVCNTdcdTUyMTciezB9Li4uIlx1MzA2RVVURjhcdTg4NjhcdTczRkVcdTMwNENcdTMwMDFcdTVCOUFcdTY1NzBcdTMwRDdcdTMwRkNcdTMwRUJcdTMwNkJcdTVCRkVcdTMwNTdcdTMwNjZcdTk1NzdcdTMwNTlcdTMwNEVcdTMwN0VcdTMwNTkKCmNvbXBpbGVyLmVyci5tYWxmb3JtZWQuZnAubGl0PVx1NkQ2RVx1NTJENVx1NUMwRlx1NjU3MFx1NzBCOVx1MzBFQVx1MzBDNlx1MzBFOVx1MzBFQlx1MzA0Q1x1NEUwRFx1NkI2M1x1MzA2N1x1MzA1OQoKY29tcGlsZXIuZXJyLm1ldGhvZC5kb2VzLm5vdC5vdmVycmlkZS5zdXBlcmNsYXNzPVx1MzBFMVx1MzBCRFx1MzBDM1x1MzBDOVx1MzA2Rlx1MzBCOVx1MzBGQ1x1MzBEMVx1MzBGQ1x1MzBCRlx1MzBBNFx1MzBEN1x1MzA2RVx1MzBFMVx1MzBCRFx1MzBDM1x1MzBDOVx1MzA5Mlx1MzBBQVx1MzBGQ1x1MzBEMFx1MzBGQ1x1MzBFOVx1MzBBNFx1MzBDOVx1MzA3RVx1MzA1Rlx1MzA2Rlx1NUI5Rlx1ODhDNVx1MzA1N1x1MzA3RVx1MzA1Qlx1MzA5MwoKY29tcGlsZXIuZXJyLm1pc3NpbmcubWV0aC5ib2R5Lm9yLmRlY2wuYWJzdHJhY3Q9XHUzMEUxXHUzMEJEXHUzMEMzXHUzMEM5XHU2NzJDXHU0RjUzXHUzMDRDXHUzMDZBXHUzMDQ0XHUzMDRCXHUzMDAxYWJzdHJhY3RcdTMwNjhcdTMwNTdcdTMwNjZcdTVCQTNcdThBMDBcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNTkKCmNvbXBpbGVyLmVyci5taXNzaW5nLnJldC5zdG10PXJldHVyblx1NjU4N1x1MzA0Q1x1NjMwN1x1NUI5QVx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1Qlx1MzA5MwoKIyAwOiB1bnVzZWQKY29tcGlsZXIubWlzYy5taXNzaW5nLnJldC52YWw9XHU2MjNCXHUzMDhBXHU1MDI0XHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzCgpjb21waWxlci5taXNjLnVuZXhwZWN0ZWQucmV0LnZhbD1cdTRFODhcdTY3MUZcdTMwNTdcdTMwNkFcdTMwNDRcdTYyM0JcdTMwOEFcdTUwMjQKCiMgMDogc2V0IG9mIG1vZGlmaWVyCmNvbXBpbGVyLmVyci5tb2Qubm90LmFsbG93ZWQuaGVyZT1cdTRGRUVcdTk4RkVcdTVCNTB7MH1cdTMwOTJcdTMwNTNcdTMwNTNcdTMwNjdcdTRGN0ZcdTc1MjhcdTMwNTlcdTMwOEJcdTMwNTNcdTMwNjhcdTMwNkZcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTMKCmNvbXBpbGVyLmVyci5pbnRmLm5vdC5hbGxvd2VkLmhlcmU9XHUzMDUzXHUzMDUzXHUzMDY3XHUzMDZGXHUzMEE0XHUzMEYzXHUzMEJGXHUzMEQ1XHUzMEE3XHUzMEZDXHUzMEI5XHUzMDZGXHU4QTMxXHU1M0VGXHUzMDU1XHUzMDhDXHUzMDdFXHUzMDVCXHUzMDkzCgpjb21waWxlci5lcnIuZW51bXMubXVzdC5iZS5zdGF0aWM9XHU1MjE3XHU2MzE5XHU1NzhCXHUzMDZFXHU1QkEzXHU4QTAwXHUzMDZGc3RhdGljXHUzMEIzXHUzMEYzXHUzMEM2XHUzMEFEXHUzMEI5XHUzMEM4XHUzMDY3XHUzMDZFXHUzMDdGXHU0RjdGXHU3NTI4XHUzMDY3XHUzMDREXHUzMDdFXHUzMDU5CgojIDA6IHN5bWJvbCwgMTogc3ltYm9sCmNvbXBpbGVyLmVyci5uYW1lLmNsYXNoLnNhbWUuZXJhc3VyZT1cdTU0MERcdTUyNERcdTMwNENcdTdBRjZcdTU0MDhcdTMwNTdcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNTlcdTMwMDJ7MH1cdTMwNjh7MX1cdTMwNkZcdTUyNEFcdTk2NjRcdTVGOENcdTMwNkVcdTU0MERcdTUyNERcdTMwNENcdTU0MENcdTMwNThcdTMwNjdcdTMwNTkKCiMgMDogc3ltYm9sLCAxOiBzeW1ib2wsIDI6IHN5bWJvbCwgMzogc3ltYm9sLCA0OiB1bnVzZWQsIDU6IHVudXNlZApjb21waWxlci5lcnIubmFtZS5jbGFzaC5zYW1lLmVyYXN1cmUubm8ub3ZlcnJpZGU9XHU1NDBEXHU1MjREXHUzMDRDXHU3QUY2XHU1NDA4XHUzMDU3XHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5XHUzMDAyezF9XHUzMDZFezB9XHUzMDY4ezN9XHUzMDZFezJ9XHUzMDZGXHUzMDdFXHUzMDYwXHU0RUQ2XHU2NUI5XHUzMDkyXHUzMEFBXHUzMEZDXHUzMEQwXHUzMEZDXHUzMEU5XHUzMEE0XHUzMEM5XHUzMDU3XHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDVCXHUzMDkzXHUzMDRDXHUzMDAxXHU1MjRBXHU5NjY0XHU1RjhDXHUzMDZFXHU1NDBEXHU1MjREXHUzMDRDXHU1NDBDXHUzMDU4XHUzMDY3XHUzMDU5CgojIDA6IHN5bWJvbCwgMTogc3ltYm9sLCAyOiBzeW1ib2wsIDM6IHN5bWJvbCwgNDogc3ltYm9sLCA1OiBzeW1ib2wKY29tcGlsZXIuZXJyLm5hbWUuY2xhc2guc2FtZS5lcmFzdXJlLm5vLm92ZXJyaWRlLjE9XHU1NDBEXHU1MjREXHUzMDRDXHU3QUY2XHU1NDA4XHUzMDU3XHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5XHUzMDAyezF9XHUzMDZFezB9XHUzMDZFXHUzMDY5XHUzMDYxXHUzMDg5XHUzMDgyXHUzMDAxXHU0RUQ2XHU2NUI5XHUzMDZFXHU2NzAwXHU1MjFEXHUzMDZFXHUzMEUxXHUzMEJEXHUzMEMzXHUzMEM5XHUzMDkyXHUzMDdFXHUzMDYwXHUzMEFBXHUzMEZDXHUzMEQwXHUzMEZDXHUzMEU5XHUzMEE0XHUzMEM5XHUzMDU3XHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDVCXHUzMDkzXHUzMDRDXHUzMDAxXHU1MjRBXHU5NjY0XHU1RjhDXHUzMDZFXHU1NDBEXHU1MjREXHUzMDRDXHU1MjI1XHUzMDZFXHUzMEUxXHUzMEJEXHUzMEMzXHUzMEM5XHUzMDY4XHU1NDBDXHUzMDU4XHUzMEUxXHUzMEJEXHUzMEMzXHUzMEM5XHUzMDkyXG5cdTMwQUFcdTMwRkNcdTMwRDBcdTMwRkNcdTMwRTlcdTMwQTRcdTMwQzlcdTMwNTdcdTMwN0VcdTMwNTlcdTMwMDJcdTY3MDBcdTUyMURcdTMwNkVcdTMwRTFcdTMwQkRcdTMwQzNcdTMwQzk6IHszfVx1MzA2RXsyfVxuMlx1NzU2QVx1NzZFRVx1MzA2RVx1MzBFMVx1MzBCRFx1MzBDM1x1MzBDOTogezV9XHUzMDZFezR9CgojIDA6IHN5bWJvbCwgMTogc3ltYm9sLCAyOiBzeW1ib2wsIDM6IHN5bWJvbApjb21waWxlci5lcnIubmFtZS5jbGFzaC5zYW1lLmVyYXN1cmUubm8uaGlkZT1cdTU0MERcdTUyNERcdTMwNENcdTdBRjZcdTU0MDhcdTMwNTdcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNTlcdTMwMDJ7MX1cdTMwNkV7MH1cdTMwNjh7M31cdTMwNkV7Mn1cdTMwNkZcdTMwN0VcdTMwNjBcdTRFRDZcdTY1QjlcdTMwOTJcdTk3NUVcdTg4NjhcdTc5M0FcdTMwNkJcdTMwNTdcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNUJcdTMwOTNcdTMwNENcdTMwMDFcdTUyNEFcdTk2NjRcdTVGOENcdTMwNkVcdTU0MERcdTUyNERcdTMwNENcdTU0MENcdTMwNThcdTMwNjdcdTMwNTkKCmNvbXBpbGVyLmVyci5uYW1lLnJlc2VydmVkLmZvci5pbnRlcm5hbC51c2U9ezB9XHUzMDZGXHU1MTg1XHU5MEU4XHUzMDY3XHUzMDZFXHU0RjdGXHU3NTI4XHUzMDZFXHUzMDVGXHUzMDgxXHU0RTg4XHU3RDA0XHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5Cgpjb21waWxlci5lcnIubmF0aXZlLm1ldGguY2FudC5oYXZlLmJvZHk9bmF0aXZlXHUzMEUxXHUzMEJEXHUzMEMzXHUzMEM5XHUzMDRDXHU2NzJDXHU0RjUzXHUzMDkyXHU2MzAxXHUzMDY0XHUzMDUzXHUzMDY4XHUzMDZGXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzCgojIDA6IHR5cGUsIDE6IHR5cGUKY29tcGlsZXIuZXJyLm5laXRoZXIuY29uZGl0aW9uYWwuc3VidHlwZT0/XHUzMDZCXHU1QkZFXHUzMDU5XHUzMDhCXHU0RTkyXHU2M0RCXHU2MDI3XHUzMDZFXHUzMDZBXHUzMDQ0XHU1NzhCIDogXHUzMDY5XHUzMDYxXHUzMDg5XHUzMDgyXHU0RUQ2XHU2NUI5XHUzMDZFXHUzMEI1XHUzMEQ2XHUzMEJGXHUzMEE0XHUzMEQ3XHUzMDY3XHUzMDZGXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyXG4yXHU3NTZBXHU3NkVFXHUzMDZFXHUzMEFBXHUzMERBXHUzMEU5XHUzMEYzXHUzMEM5IDogezB9XG4zXHU3NTZBXHU3NkVFXHUzMDZFXHUzMEFBXHUzMERBXHUzMEU5XHUzMEYzXHUzMEM5IDogezF9CgoKIyAwOiBtZXNzYWdlIHNlZ21lbnQKY29tcGlsZXIubWlzYy5pbmNvbXBhdGlibGUudHlwZS5pbi5jb25kaXRpb25hbD1cdTY3NjFcdTRFRjZcdTVGMEZcdTMwNkVcdTU3OEJcdTMwNENcdTRFMERcdTZCNjNcdTMwNjdcdTMwNTlcbnswfQoKY29tcGlsZXIubWlzYy5jb25kaXRpb25hbC50YXJnZXQuY2FudC5iZS52b2lkPVx1Njc2MVx1NEVGNlx1NUYwRlx1MzA2RVx1MzBCRlx1MzBGQ1x1MzBCMlx1MzBDM1x1MzBDOFx1NTc4Qlx1MzA2RnZvaWRcdTMwNkJcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTMKCiMgMDogdHlwZQpjb21waWxlci5taXNjLmluY29tcGF0aWJsZS5yZXQudHlwZS5pbi5sYW1iZGE9XHUzMEU5XHUzMEUwXHUzMEMwXHU1RjBGXHUzMDZFXHU2MjNCXHUzMDhBXHU1NzhCXHUzMDRDXHU0RTBEXHU2QjYzXHUzMDY3XHUzMDU5XG57MH0KCmNvbXBpbGVyLm1pc2Muc3RhdC5leHByLmV4cGVjdGVkPVx1MzBFOVx1MzBFMFx1MzBDMFx1MzBGQlx1MzBEQ1x1MzBDN1x1MzBBM1x1MzA0Q3ZvaWRcdTZBNUZcdTgwRkRcdTMwQTRcdTMwRjNcdTMwQkZcdTMwRDVcdTMwQTdcdTMwRkNcdTMwQjlcdTMwNjhcdTRFOTJcdTYzREJcdTYwMjdcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTNcbihcdTMwRDZcdTMwRURcdTMwQzNcdTMwQUZcdTMwNkVcdTMwRTlcdTMwRTBcdTMwQzBcdTMwRkJcdTMwRENcdTMwQzdcdTMwQTNcdTMwNkVcdTRGN0ZcdTc1MjhcdTMwOTJcdTY5MUNcdThBMEVcdTMwNTlcdTMwOEJcdTMwNEJcdTMwMDFcdTMwNEJcdTMwOEZcdTMwOEFcdTMwNkJcdTY1ODdcdTMwNkVcdTVGMEZcdTMwOTJcdTRGN0ZcdTc1MjhcdTMwNTdcdTMwNjZcdTMwNEZcdTMwNjBcdTMwNTVcdTMwNDQpCgojIDA6IHR5cGUKY29tcGlsZXIubWlzYy5pbmNvbXBhdGlibGUucmV0LnR5cGUuaW4ubXJlZj1cdTMwRTFcdTMwQkRcdTMwQzNcdTMwQzlcdTUzQzJcdTcxNjdcdTMwNkVcdTYyM0JcdTMwOEFcdTU3OEJcdTMwNENcdTRFMERcdTZCNjNcdTMwNjdcdTMwNTlcbnswfQoKY29tcGlsZXIuZXJyLmxhbWJkYS5ib2R5Lm5laXRoZXIudmFsdWUubm9yLnZvaWQuY29tcGF0aWJsZT1cdTMwRTlcdTMwRTBcdTMwQzBcdTMwRkJcdTMwRENcdTMwQzdcdTMwQTNcdTMwNkZcdTUwMjRcdTRFOTJcdTYzREJcdTMwNjdcdTMwODJ2b2lkXHU0RTkyXHU2M0RCXHUzMDY3XHUzMDgyXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzCgojIDA6IGxpc3Qgb2YgdHlwZQpjb21waWxlci5lcnIuaW5jb21wYXRpYmxlLnRocm93bi50eXBlcy5pbi5tcmVmPVx1MzBFMVx1MzBCRFx1MzBDM1x1MzBDOVx1NTNDMlx1NzE2N1x1MzA2RVx1MzBCOVx1MzBFRFx1MzBGQ1x1MzA1NVx1MzA4Q1x1MzA1Rlx1MzBCRlx1MzBBNFx1MzBEN3swfVx1MzA2Rlx1NEUwRFx1OTA2OVx1NTQwOFx1MzA2N1x1MzA1OQoKY29tcGlsZXIubWlzYy5pbmNvbXBhdGlibGUuYXJnLnR5cGVzLmluLmxhbWJkYT1cdTMwRTlcdTMwRTBcdTMwQzBcdTVGMEZcdTMwNkVcdTMwRDFcdTMwRTlcdTMwRTFcdTMwRkNcdTMwQkZcdTU3OEJcdTMwNkZcdTRFMERcdTkwNjlcdTU0MDhcdTMwNjdcdTMwNTkKCmNvbXBpbGVyLm1pc2MuaW5jb21wYXRpYmxlLmFyZy50eXBlcy5pbi5tcmVmPVx1MzBFMVx1MzBCRFx1MzBDM1x1MzBDOVx1NTNDMlx1NzE2N1x1MzA2RVx1MzBEMVx1MzBFOVx1MzBFMVx1MzBGQ1x1MzBCRlx1NTc4Qlx1MzA2Rlx1NEUwRFx1OTA2OVx1NTQwOFx1MzA2N1x1MzA1OQoKY29tcGlsZXIuZXJyLm5ldy5ub3QuYWxsb3dlZC5pbi5hbm5vdGF0aW9uPScnbmV3JydcdTMwNkZcdTZDRThcdTkxQzhcdTMwNkJcdTRGN0ZcdTc1MjhcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTMKCmNvbXBpbGVyLmVyci5uby5hbm5vdGF0aW9uLm1lbWJlcj17MX1cdTMwNkVcdTZDRThcdTkxQzhcdTMwRTFcdTMwRjNcdTMwRDBcdTMwRkN7MH1cdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTMKCmNvbXBpbGVyLmVyci5uby5lbmNsLmluc3RhbmNlLm9mLnR5cGUuaW4uc2NvcGU9XHU1NzhCezB9XHUzMDZFXHU1MTg1XHU5MEU4XHUzMEFGXHUzMEU5XHUzMEI5XHUzMDkyXHU1NkYyXHUzMDgwXHUzMEE0XHUzMEYzXHUzMEI5XHUzMEJGXHUzMEYzXHUzMEI5XHUzMDRDXHUzMEI5XHUzMEIzXHUzMEZDXHUzMEQ3XHU1MTg1XHUzMDZCXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzCgpjb21waWxlci5lcnIubm8uaW50Zi5leHBlY3RlZC5oZXJlPVx1MzA1M1x1MzA1M1x1MzA2Qlx1MzBBNFx1MzBGM1x1MzBCRlx1MzBENVx1MzBBN1x1MzBGQ1x1MzBCOVx1MzA2Rlx1NUZDNVx1ODk4MVx1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5MwoKY29tcGlsZXIuZXJyLm5vLm1hdGNoLmVudHJ5PXswfVx1MzA2RnsxfVx1MzA2RVx1MzBBOFx1MzBGM1x1MzBDOFx1MzBFQVx1MzA2Qlx1OTA2OVx1NTQwOFx1MzA1N1x1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMnsyfVx1MzA0Q1x1NUZDNVx1ODk4MVx1MzA2N1x1MzA1OQoKY29tcGlsZXIuZXJyLm5vdC5hbm5vdGF0aW9uLnR5cGU9ezB9XHUzMDZGXHU2Q0U4XHU5MUM4XHU1NzhCXHUzMDY3XHUzMDZGXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzCgojIDA6IHN5bWJvbCwgMTogc3ltYm9sLCAyOiBtZXNzYWdlIHNlZ21lbnQKY29tcGlsZXIuZXJyLm5vdC5kZWYuYWNjZXNzLnBhY2thZ2UuY2FudC5hY2Nlc3M9ezB9IFx1MzA2Rlx1ODg2OFx1NzkzQVx1NEUwRFx1NTNFRlx1MzA2N1x1MzA1OVxuKHsyfSkKCiMgMDogc3ltYm9sLCAxOiBzeW1ib2wsIDI6IG1lc3NhZ2Ugc2VnbWVudApjb21waWxlci5taXNjLm5vdC5kZWYuYWNjZXNzLnBhY2thZ2UuY2FudC5hY2Nlc3M9ezB9IFx1MzA2Rlx1ODg2OFx1NzkzQVx1NEUwRFx1NTNFRlx1MzA2N1x1MzA1OVxuKHsyfSkKCiMgMDogc3ltYm9sLCAxOiBtZXNzYWdlIHNlZ21lbnQKY29tcGlsZXIuZXJyLnBhY2thZ2Uubm90LnZpc2libGU9XHUzMEQxXHUzMEMzXHUzMEIxXHUzMEZDXHUzMEI4ezB9XHUzMDZGXHU4ODY4XHU3OTNBXHU0RTBEXHU1M0VGXHUzMDY3XHUzMDU5XG4oezF9KQoKIyAwOiBzeW1ib2wsIDE6IG1lc3NhZ2Ugc2VnbWVudApjb21waWxlci5taXNjLnBhY2thZ2Uubm90LnZpc2libGU9XHUzMEQxXHUzMEMzXHUzMEIxXHUzMEZDXHUzMEI4ezB9XHUzMDZGXHU4ODY4XHU3OTNBXHU0RTBEXHU1M0VGXHUzMDY3XHUzMDU5XG4oezF9KQoKIyB7MH0gLSBjdXJyZW50IG1vZHVsZQojIHsxfSAtIHBhY2thZ2UgaW4gd2hpY2ggdGhlIGludmlzaWJsZSBjbGFzcyBpcyBkZWNsYXJlZAojIHsyfSAtIG1vZHVsZSBpbiB3aGljaCB7MX0gaXMgZGVjbGFyZWQKIyAwOiBzeW1ib2wsIDE6IHN5bWJvbCwgMjogc3ltYm9sCmNvbXBpbGVyLm1pc2Mubm90LmRlZi5hY2Nlc3MuZG9lcy5ub3QucmVhZD1cdTMwRDFcdTMwQzNcdTMwQjFcdTMwRkNcdTMwQjh7MX1cdTMwNkZcdTMwRTJcdTMwQjhcdTMwRTVcdTMwRkNcdTMwRUJ7Mn1cdTMwNjdcdTVCQTNcdThBMDBcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNTlcdTMwNENcdTMwMDFcdTMwRTJcdTMwQjhcdTMwRTVcdTMwRkNcdTMwRUJ7MH1cdTMwNkJcdThBQURcdTMwN0ZcdThGQkNcdTMwN0VcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNUJcdTMwOTMKCiMgezB9IC0gcGFja2FnZSBpbiB3aGljaCB0aGUgaW52aXNpYmxlIGNsYXNzIGlzIGRlY2xhcmVkCiMgezF9IC0gbW9kdWxlIGluIHdoaWNoIHswfSBpcyBkZWNsYXJlZAojIDA6IHN5bWJvbCwgMTogc3ltYm9sCmNvbXBpbGVyLm1pc2Mubm90LmRlZi5hY2Nlc3MuZG9lcy5ub3QucmVhZC5mcm9tLnVubmFtZWQ9XHUzMEQxXHUzMEMzXHUzMEIxXHUzMEZDXHUzMEI4ezB9XHUzMDZGXHUzMEUyXHUzMEI4XHUzMEU1XHUzMEZDXHUzMEVCezF9XHUzMDY3XHU1QkEzXHU4QTAwXHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5XHUzMDRDXHUzMDAxXHUzMEUyXHUzMEI4XHUzMEU1XHUzMEZDXHUzMEVCXHUzMEZCXHUzMEIwXHUzMEU5XHUzMEQ1XHUzMDZCXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzCgojIHswfSAtIHBhY2thZ2UgaW4gd2hpY2ggdGhlIGludmlzaWJsZSBjbGFzcyBpcyBkZWNsYXJlZAojIHsxfSAtIGN1cnJlbnQgbW9kdWxlCiMgMDogc3ltYm9sLCAxOiBzeW1ib2wKY29tcGlsZXIubWlzYy5ub3QuZGVmLmFjY2Vzcy5kb2VzLm5vdC5yZWFkLnVubmFtZWQ9XHUzMEQxXHUzMEMzXHUzMEIxXHUzMEZDXHUzMEI4ezB9XHUzMDZGXHU1NDBEXHU1MjREXHUzMDZFXHUzMDZBXHUzMDQ0XHUzMEUyXHUzMEI4XHUzMEU1XHUzMEZDXHUzMEVCXHUzMDY3XHU1QkEzXHU4QTAwXHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5XHUzMDRDXHUzMDAxXHUzMEUyXHUzMEI4XHUzMEU1XHUzMEZDXHUzMEVCezB9XHUzMDZCXHU4QUFEXHUzMDdGXHU4RkJDXHUzMDdFXHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDVCXHUzMDkzCgojIHswfSAtIHBhY2thZ2UgaW4gd2hpY2ggdGhlIGludmlzaWJsZSBjbGFzcyBpcyBkZWNsYXJlZAojIHsxfSAtIG1vZHVsZSBpbiB3aGljaCB7MH0gaXMgZGVjbGFyZWQKIyAwOiBzeW1ib2wsIDE6IHN5bWJvbApjb21waWxlci5taXNjLm5vdC5kZWYuYWNjZXNzLm5vdC5leHBvcnRlZD1cdTMwRDFcdTMwQzNcdTMwQjFcdTMwRkNcdTMwQjh7MH1cdTMwNkZcdTMwRTJcdTMwQjhcdTMwRTVcdTMwRkNcdTMwRUJ7MX1cdTMwNjdcdTVCQTNcdThBMDBcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNTlcdTMwNENcdTMwMDFcdTMwQThcdTMwQUZcdTMwQjlcdTMwRERcdTMwRkNcdTMwQzhcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNUJcdTMwOTMKCiMgezB9IC0gcGFja2FnZSBpbiB3aGljaCB0aGUgaW52aXNpYmxlIGNsYXNzIGlzIGRlY2xhcmVkCiMgezF9IC0gbW9kdWxlIGluIHdoaWNoIHswfSBpcyBkZWNsYXJlZAojIDA6IHN5bWJvbCwgMTogc3ltYm9sCmNvbXBpbGVyLm1pc2Mubm90LmRlZi5hY2Nlc3Mubm90LmV4cG9ydGVkLmZyb20udW5uYW1lZD1cdTMwRDFcdTMwQzNcdTMwQjFcdTMwRkNcdTMwQjh7MH1cdTMwNkZcdTMwRTJcdTMwQjhcdTMwRTVcdTMwRkNcdTMwRUJ7MX1cdTMwNjdcdTVCQTNcdThBMDBcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNTlcdTMwNENcdTMwMDFcdTMwQThcdTMwQUZcdTMwQjlcdTMwRERcdTMwRkNcdTMwQzhcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNUJcdTMwOTMKCiMgezB9IC0gcGFja2FnZSBpbiB3aGljaCB0aGUgaW52aXNpYmxlIGNsYXNzIGlzIGRlY2xhcmVkCiMgezF9IC0gbW9kdWxlIGluIHdoaWNoIHswfSBpcyBkZWNsYXJlZAojIHsyfSAtIGN1cnJlbnQgbW9kdWxlCiMgMDogc3ltYm9sLCAxOiBzeW1ib2wsIDI6IHN5bWJvbApjb21waWxlci5taXNjLm5vdC5kZWYuYWNjZXNzLm5vdC5leHBvcnRlZC50by5tb2R1bGU9XHUzMEQxXHUzMEMzXHUzMEIxXHUzMEZDXHUzMEI4ezB9XHUzMDZGXHUzMEUyXHUzMEI4XHUzMEU1XHUzMEZDXHUzMEVCezF9XHUzMDY3XHU1QkEzXHU4QTAwXHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5XHUzMDRDXHUzMDAxXHUzMEUyXHUzMEI4XHUzMEU1XHUzMEZDXHUzMEVCezJ9XHUzMDZCXHUzMEE4XHUzMEFGXHUzMEI5XHUzMEREXHUzMEZDXHUzMEM4XHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDVCXHUzMDkzCgojIHswfSAtIHBhY2thZ2UgaW4gd2hpY2ggdGhlIGludmlzaWJsZSBjbGFzcyBpcyBkZWNsYXJlZAojIHsxfSAtIG1vZHVsZSBpbiB3aGljaCB7MH0gaXMgZGVjbGFyZWQKIyAwOiBzeW1ib2wsIDE6IHN5bWJvbApjb21waWxlci5taXNjLm5vdC5kZWYuYWNjZXNzLm5vdC5leHBvcnRlZC50by5tb2R1bGUuZnJvbS51bm5hbWVkPVx1MzBEMVx1MzBDM1x1MzBCMVx1MzBGQ1x1MzBCOHswfVx1MzA2Rlx1MzBFMlx1MzBCOFx1MzBFNVx1MzBGQ1x1MzBFQnsxfVx1MzA2N1x1NUJBM1x1OEEwMFx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1OVx1MzA0Q1x1MzAwMVx1NTQwRFx1NTI0RFx1MzA2RVx1MzA2QVx1MzA0NFx1MzBFMlx1MzBCOFx1MzBFNVx1MzBGQ1x1MzBFQlx1MzA2Qlx1MzBBOFx1MzBBRlx1MzBCOVx1MzBERFx1MzBGQ1x1MzBDOFx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1Qlx1MzA5MwoKIyAwOiBzeW1ib2wsIDE6IHN5bWJvbApjb21waWxlci5lcnIubm90LmRlZi5hY2Nlc3MuY2xhc3MuaW50Zi5jYW50LmFjY2Vzcz17MX0uezB9XHUzMDZGXHUzMEEyXHUzMEFGXHUzMEJCXHUzMEI5XHUzMDY3XHUzMDREXHUzMDZBXHUzMDQ0XHUzMEFGXHUzMEU5XHUzMEI5XHUzMDdFXHUzMDVGXHUzMDZGXHUzMEE0XHUzMEYzXHUzMEJGXHUzMEQ1XHUzMEE3XHUzMEZDXHUzMEI5XHUzMDZCXHU1QjlBXHU3RkE5XHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5CgojIDA6IHN5bWJvbCwgMTogc3ltYm9sCmNvbXBpbGVyLm1pc2Mubm90LmRlZi5hY2Nlc3MuY2xhc3MuaW50Zi5jYW50LmFjY2Vzcz17MX0uezB9XHUzMDZGXHUzMEEyXHUzMEFGXHUzMEJCXHUzMEI5XHUzMDY3XHUzMDREXHUzMDZBXHUzMDQ0XHUzMEFGXHUzMEU5XHUzMEI5XHUzMDdFXHUzMDVGXHUzMDZGXHUzMEE0XHUzMEYzXHUzMEJGXHUzMEQ1XHUzMEE3XHUzMEZDXHUzMEI5XHUzMDZCXHU1QjlBXHU3RkE5XHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5CgojIDA6IHN5bWJvbCwgMTogc3ltYm9sLCAyOiBzeW1ib2wsIDM6IG1lc3NhZ2Ugc2VnbWVudApjb21waWxlci5lcnIubm90LmRlZi5hY2Nlc3MuY2xhc3MuaW50Zi5jYW50LmFjY2Vzcy5yZWFzb249XHUzMEQxXHUzMEMzXHUzMEIxXHUzMEZDXHUzMEI4ezJ9XHUzMDZFezF9LnswfVx1MzA2Qlx1MzA2Rlx1MzBBMlx1MzBBRlx1MzBCQlx1MzBCOVx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1xuKHszfSkKCiMgMDogc3ltYm9sLCAxOiBzeW1ib2wsIDI6IHN5bWJvbCwgMzogbWVzc2FnZSBzZWdtZW50CmNvbXBpbGVyLm1pc2Mubm90LmRlZi5hY2Nlc3MuY2xhc3MuaW50Zi5jYW50LmFjY2Vzcy5yZWFzb249XHUzMEQxXHUzMEMzXHUzMEIxXHUzMEZDXHUzMEI4ezJ9XHUzMDZFezF9LnswfVx1MzA2Qlx1MzA2Rlx1MzBBMlx1MzBBRlx1MzBCQlx1MzBCOVx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1xuKHszfSkKCiMgMDogc3ltYm9sLCAxOiBsaXN0IG9mIHR5cGUsIDI6IHR5cGUKY29tcGlsZXIubWlzYy5jYW50LmFjY2Vzcy5pbm5lci5jbHMuY29uc3RyPVx1MzBCM1x1MzBGM1x1MzBCOVx1MzBDOFx1MzBFOVx1MzBBRlx1MzBCRnswfSh7MX0pXHUzMDZCXHUzMEEyXHUzMEFGXHUzMEJCXHUzMEI5XHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzXG5cdTUxODVcdTkwRThcdTMwQUZcdTMwRTlcdTMwQjlcdTMwOTJcdTU2RjJcdTMwODBcdTU3OEJ7Mn1cdTMwNkVcdTMwQTRcdTMwRjNcdTMwQjlcdTMwQkZcdTMwRjNcdTMwQjlcdTMwNENcdTMwQjlcdTMwQjNcdTMwRkNcdTMwRDdcdTUxODVcdTMwNkJcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTMKCiMgMDogc3ltYm9sLCAxOiBzeW1ib2wKY29tcGlsZXIuZXJyLm5vdC5kZWYucHVibGljLmNhbnQuYWNjZXNzPXsxfVx1MzA2RXswfVx1MzA2RnB1YmxpY1x1MzA2N1x1MzA2Rlx1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMlx1MzBEMVx1MzBDM1x1MzBCMVx1MzBGQ1x1MzBCOFx1NTkxNlx1MzA0Qlx1MzA4OVx1MzA2Rlx1MzBBMlx1MzBBRlx1MzBCQlx1MzBCOVx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5MwoKIyAwOiBzeW1ib2wsIDE6IHN5bWJvbApjb21waWxlci5taXNjLm5vdC5kZWYucHVibGljLmNhbnQuYWNjZXNzPXsxfVx1MzA2RXswfVx1MzA2RnB1YmxpY1x1MzA2N1x1MzA2Rlx1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMlx1MzBEMVx1MzBDM1x1MzBCMVx1MzBGQ1x1MzBCOFx1NTkxNlx1MzA0Qlx1MzA4OVx1MzA2Rlx1MzBBMlx1MzBBRlx1MzBCQlx1MzBCOVx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5MwoKIyAwOiBuYW1lCmNvbXBpbGVyLmVyci5ub3QubG9vcC5sYWJlbD17MH1cdTMwNkZcdTMwRUJcdTMwRkNcdTMwRDdcdTMwRkJcdTMwRTlcdTMwRDlcdTMwRUJcdTMwNjdcdTMwNkZcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTMKCmNvbXBpbGVyLmVyci5ub3Quc3RtdD1cdTY1ODdcdTMwNjdcdTMwNkZcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTMKCiMgMDogc3ltYm9sCmNvbXBpbGVyLmVyci5ub3QuZW5jbC5jbGFzcz17MH1cdTMwNkZcdTUxODVcdTkwRThcdTMwQUZcdTMwRTlcdTMwQjlcdTMwOTJcdTU2RjJcdTMwN0ZcdTMwN0VcdTMwNUJcdTMwOTMKCiMgMDogbmFtZSwgMTogdHlwZQpjb21waWxlci5lcnIub3BlcmF0b3IuY2FudC5iZS5hcHBsaWVkPVx1NTM1OFx1OTgwNVx1NkYxNFx1N0I5N1x1NUI1MCcnezB9JydcdTMwNkVcdTMwQUFcdTMwREFcdTMwRTlcdTMwRjNcdTMwQzlcdTU3OEJ7MX1cdTMwNENcdTRFMERcdTZCNjNcdTMwNjdcdTMwNTkKCiMgMDogbmFtZSwgMTogdHlwZSwgMjogdHlwZQpjb21waWxlci5lcnIub3BlcmF0b3IuY2FudC5iZS5hcHBsaWVkLjE9XHU0RThDXHU5ODA1XHU2RjE0XHU3Qjk3XHU1QjUwJyd7MH0nJ1x1MzA2RVx1MzBBQVx1MzBEQVx1MzBFOVx1MzBGM1x1MzBDOVx1NTc4Qlx1MzA0Q1x1NEUwRFx1NkI2M1x1MzA2N1x1MzA1OVxuXHU2NzAwXHU1MjFEXHUzMDZFXHU1NzhCOiB7MX1cbjJcdTc1NkFcdTc2RUVcdTMwNkVcdTU3OEI6IHsyfQoKY29tcGlsZXIuZXJyLnBrZy5hbm5vdGF0aW9ucy5zYi5pbi5wYWNrYWdlLWluZm8uamF2YT1cdTMwRDFcdTMwQzNcdTMwQjFcdTMwRkNcdTMwQjhcdTMwNkVcdTZDRThcdTkxQzhcdTMwNkZcdTMwRDVcdTMwQTFcdTMwQTRcdTMwRUJwYWNrYWdlLWluZm8uamF2YVx1NTE4NVx1MzA2Qlx1MzA0Mlx1MzA4Qlx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OQoKY29tcGlsZXIuZXJyLm5vLnBrZy5pbi5tb2R1bGUtaW5mby5qYXZhPXBhY2thZ2VcdTUzRTVcdTMwNENcdTMwRDVcdTMwQTFcdTMwQTRcdTMwRUJtb2R1bGUtaW5mby5qYXZhXHUzMDZCXHUzMDQyXHUzMDYzXHUzMDY2XHUzMDZGXHUzMDZBXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzCgojIDA6IHN5bWJvbApjb21waWxlci5lcnIucGtnLmNsYXNoZXMud2l0aC5jbGFzcy5vZi5zYW1lLm5hbWU9XHUzMEQxXHUzMEMzXHUzMEIxXHUzMEZDXHUzMEI4ezB9XHUzMDZGXHU1NDBDXHU1NDBEXHUzMDZFXHUzMEFGXHUzMEU5XHUzMEI5XHUzMDY4XHU3QUY2XHU1NDA4XHUzMDU3XHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5Cgpjb21waWxlci5lcnIud2FybmluZ3MuYW5kLndlcnJvcj1cdThCNjZcdTU0NEFcdTMwNENcdTg5OEJcdTMwNjRcdTMwNEJcdTMwOEEtV2Vycm9yXHUzMDRDXHU2MzA3XHU1QjlBXHUzMDU1XHUzMDhDXHUzMDdFXHUzMDU3XHUzMDVGCgojIEVycm9ycyByZWxhdGVkIHRvIGFubm90YXRpb24gcHJvY2Vzc2luZwoKIyAwOiBzeW1ib2wsIDE6IHN0cmluZywgMjogc3RyaW5nIChzdGFjay10cmFjZSkKY29tcGlsZXIuZXJyLnByb2MuY2FudC5hY2Nlc3M9ezB9XHUzMDZCXHUzMEEyXHUzMEFGXHUzMEJCXHUzMEI5XHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzXG57MX1cblx1OEE3M1x1N0QzMFx1MzA2Rlx1NkIyMVx1MzA2RVx1MzBCOVx1MzBCRlx1MzBDM1x1MzBBRlx1MzBDOFx1MzBFQ1x1MzBGQ1x1MzBCOVx1MzA2N1x1OEFCRlx1NjdGQlx1MzA1N1x1MzA2Nlx1MzA0Rlx1MzA2MFx1MzA1NVx1MzA0NFx1MzAwMlxuezJ9CgojIDA6IHN5bWJvbCwgMTogc3RyaW5nCmNvbXBpbGVyLmVyci5wcm9jLmNhbnQuYWNjZXNzLjE9ezB9XHUzMDZCXHUzMEEyXHUzMEFGXHUzMEJCXHUzMEI5XHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzXG57MX0KCiMgMDogc3RyaW5nCmNvbXBpbGVyLmVyci5wcm9jLmNhbnQuZmluZC5jbGFzcz0nJ3swfScnXHUzMDZFXHUzMEFGXHUzMEU5XHUzMEI5XHUzMEZCXHUzMEQ1XHUzMEExXHUzMEE0XHUzMEVCXHUzMDRDXHU4OThCXHUzMDY0XHUzMDRCXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDY3XHUzMDU3XHUzMDVGXHUzMDAyCgojIFByaW50IGEgY2xpZW50LWdlbmVyYXRlZCBlcnJvciBtZXNzYWdlOyBhc3N1bWVkIHRvIGJlIGxvY2FsaXplZCwgbm8gdHJhbnNsYXRpb24gcmVxdWlyZWQKIyAwOiBzdHJpbmcKY29tcGlsZXIuZXJyLnByb2MubWVzc2FnZXI9ezB9CgojIDA6IGxpc3Qgb2Ygc3RyaW5nCmNvbXBpbGVyLmVyci5wcm9jLm5vLmV4cGxpY2l0LmFubm90YXRpb24ucHJvY2Vzc2luZy5yZXF1ZXN0ZWQ9XHUzMEFGXHUzMEU5XHUzMEI5XHU1NDBEJyd7MH0nJ1x1MzA0Q1x1NTNEN1x1MzA1MVx1NTE2NVx1MzA4Q1x1MzA4OVx1MzA4Q1x1MzA4Qlx1MzA2RVx1MzA2Rlx1MzAwMVx1NkNFOFx1OTFDOFx1NTFFNlx1NzQwNlx1MzA0Q1x1NjYwRVx1NzkzQVx1NzY4NFx1MzA2Qlx1MzBFQVx1MzBBRlx1MzBBOFx1MzBCOVx1MzBDOFx1MzA1NVx1MzA4Q1x1MzA1Rlx1NTgzNFx1NTQwOFx1MzA2RVx1MzA3Rlx1MzA2N1x1MzA1OQoKY29tcGlsZXIuZXJyLnByb2Mubm8uc2VydmljZT1cdTMwQjVcdTMwRkNcdTMwRDNcdTMwQjlcdTMwRkJcdTMwRURcdTMwRkNcdTMwQzBcdTMwRkNcdTMwNENcdTRGN0ZcdTc1MjhcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcdTMwNjdcdTMwNTdcdTMwNUZcdTMwNENcdTMwMDFcdTZDRThcdTkxQzhcdTUxRTZcdTc0MDZcdTMwNkJcdTVGQzVcdTg5ODFcdTMwNjdcdTMwNTlcdTMwMDIKCmNvbXBpbGVyLmVyci5wcm9jLnByb2Nlc3Nvci5iYWQub3B0aW9uLm5hbWU9XHUzMEQ3XHUzMEVEXHUzMEJCXHUzMEMzXHUzMEI1Jyd7MX0nJ1x1MzA2Qlx1MzA4OFx1MzA2M1x1MzA2Nlx1NjMwN1x1NUI5QVx1MzA1NVx1MzA4Q1x1MzA1Rlx1MzBBQVx1MzBEN1x1MzBCN1x1MzBFN1x1MzBGM1x1NTQwRCcnezB9JydcdTMwNENcdTRFMERcdTZCNjNcdTMwNjdcdTMwNTkKCiMgMDogc3RyaW5nCmNvbXBpbGVyLmVyci5wcm9jLnByb2Nlc3Nvci5jYW50Lmluc3RhbnRpYXRlPVx1MzBEN1x1MzBFRFx1MzBCQlx1MzBDM1x1MzBCNScnezB9JydcdTMwNkVcdTMwQTRcdTMwRjNcdTMwQjlcdTMwQkZcdTMwRjNcdTMwQjlcdTMwOTJcdTMwQTRcdTMwRjNcdTMwQjlcdTMwQkZcdTMwRjNcdTMwQjlcdTUzMTZcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcdTMwNjdcdTMwNTdcdTMwNUYKCiMgMDogc3RyaW5nCmNvbXBpbGVyLmVyci5wcm9jLnByb2Nlc3Nvci5ub3QuZm91bmQ9XHU2Q0U4XHU5MUM4XHUzMEQ3XHUzMEVEXHUzMEJCXHUzMEMzXHUzMEI1Jyd7MH0nJ1x1MzA0Q1x1ODk4Qlx1MzA2NFx1MzA0Qlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5MwoKIyAwOiBzdHJpbmcKY29tcGlsZXIuZXJyLnByb2MucHJvY2Vzc29yLndyb25nLnR5cGU9XHU2Q0U4XHU5MUM4XHUzMEQ3XHUzMEVEXHUzMEJCXHUzMEMzXHUzMEI1Jyd7MH0nJ1x1MzA0Q2phdmF4LmFubm90YXRpb24ucHJvY2Vzc2luZy5Qcm9jZXNzb3JcdTMwOTJcdTVCOUZcdTg4QzVcdTMwNTdcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNUJcdTMwOTMKCmNvbXBpbGVyLmVyci5wcm9jLnNlcnZpY2UucHJvYmxlbT1cdTMwRDdcdTMwRURcdTMwQkJcdTMwQzNcdTMwQjVcdTMwOTJcdTMwRURcdTMwRkNcdTMwQzlcdTMwNTlcdTMwOEJcdTMwNUZcdTMwODFcdTMwNkVcdTMwQjVcdTMwRkNcdTMwRDNcdTMwQjlcdTMwRkJcdTMwRURcdTMwRkNcdTMwQzBcdTMwRkNcdTMwOTJcdTRGNUNcdTYyMTBcdTRFMkRcdTMwNkJcdTMwQThcdTMwRTlcdTMwRkNcdTMwNENcdTc2N0FcdTc1MUZcdTMwNTdcdTMwN0VcdTMwNTdcdTMwNUZcdTMwMDIKCmNvbXBpbGVyLmVyci5wcm9jLmJhZC5jb25maWcuZmlsZT1cdTMwQjVcdTMwRkNcdTMwRDNcdTMwQjlcdTY5Q0JcdTYyMTBcdTMwRDVcdTMwQTFcdTMwQTRcdTMwRUJcdTMwNENcdTRFMERcdTZCNjNcdTMwNjdcdTMwNDJcdTMwOEJcdTMwNEJcdTMwMDFcdTMwRDdcdTMwRURcdTMwQkJcdTMwQzNcdTMwQjVcdTMwRkJcdTMwQUFcdTMwRDZcdTMwQjhcdTMwQTdcdTMwQUZcdTMwQzhcdTMwNkVcdTY5Q0JcdTdCQzlcdTRFMkRcdTMwNkJcdTRGOEJcdTU5MTZcdTMwNENcdTMwQjlcdTMwRURcdTMwRkNcdTMwNTVcdTMwOENcdTMwN0VcdTMwNTdcdTMwNUY6IHswfQoKY29tcGlsZXIuZXJyLnByb2MuY2FudC5jcmVhdGUubG9hZGVyPVx1NkNFOFx1OTFDOFx1MzBEN1x1MzBFRFx1MzBCQlx1MzBDM1x1MzBCNVx1MzA2RVx1MzBBRlx1MzBFOVx1MzBCOVx1MzBGQlx1MzBFRFx1MzBGQ1x1MzBDMFx1MzBGQ1x1MzA5Mlx1NEY1Q1x1NjIxMFx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzA2N1x1MzA1N1x1MzA1RjogezB9CgojIDA6IHVudXNlZApjb21waWxlci5lcnIucXVhbGlmaWVkLm5ldy5vZi5zdGF0aWMuY2xhc3M9c3RhdGljXHUzMEFGXHUzMEU5XHUzMEI5XHUzMDZFbmV3XHUzMDRDXHU0RkVFXHU5OEZFXHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5Cgpjb21waWxlci5lcnIucmVjdXJzaXZlLmN0b3IuaW52b2NhdGlvbj1cdTMwQjNcdTMwRjNcdTMwQjlcdTMwQzhcdTMwRTlcdTMwQUZcdTMwQkZcdTMwNkVcdTU0N0NcdTUxRkFcdTMwNTdcdTMwNENcdTUxOERcdTVFMzBcdTc2ODRcdTMwNjdcdTMwNTkKCiMgMDogbmFtZSwgMTogc3ltYm9sIGtpbmQsIDI6IHN5bWJvbCwgMzogc3ltYm9sLCA0OiBzeW1ib2wga2luZCwgNTogc3ltYm9sLCA2OiBzeW1ib2wKY29tcGlsZXIuZXJyLnJlZi5hbWJpZ3VvdXM9ezB9XHUzMDZFXHU1M0MyXHU3MTY3XHUzMDZGXHUzMDQyXHUzMDQ0XHUzMDdFXHUzMDQ0XHUzMDY3XHUzMDU5XG57M31cdTMwNkV7MX0gezJ9XHUzMDY4ezZ9XHUzMDZFezR9IHs1fVx1MzA2RVx1NEUyMVx1NjVCOVx1MzA0Q1x1NEUwMFx1ODFGNFx1MzA1N1x1MzA3RVx1MzA1OQoKIyAwOiBuYW1lLCAxOiBzeW1ib2wga2luZCwgMjogc3ltYm9sLCAzOiBzeW1ib2wsIDQ6IHN5bWJvbCBraW5kLCA1OiBzeW1ib2wsIDY6IHN5bWJvbApjb21waWxlci5taXNjLnJlZi5hbWJpZ3VvdXM9ezB9XHUzMDZFXHU1M0MyXHU3MTY3XHUzMDZGXHUzMDQyXHUzMDQ0XHUzMDdFXHUzMDQ0XHUzMDY3XHUzMDU5XG57M31cdTMwNkV7MX0gezJ9XHUzMDY4ezZ9XHUzMDZFezR9IHs1fVx1MzA2RVx1NEUyMVx1NjVCOVx1MzA0Q1x1NEUwMFx1ODFGNFx1MzA1N1x1MzA3RVx1MzA1OQoKY29tcGlsZXIuZXJyLnJlcGVhdGVkLmFubm90YXRpb24udGFyZ2V0PVx1NkNFOFx1OTFDOFx1MzBCRlx1MzBGQ1x1MzBCMlx1MzBDM1x1MzBDOFx1MzA0Q1x1N0U3MFx1MzA4QVx1OEZENFx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1OQoKY29tcGlsZXIuZXJyLnJlcGVhdGVkLmludGVyZmFjZT1cdTMwQTRcdTMwRjNcdTMwQkZcdTMwRDVcdTMwQTdcdTMwRkNcdTMwQjlcdTMwNENcdTdFNzBcdTMwOEFcdThGRDRcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNTkKCmNvbXBpbGVyLmVyci5yZXBlYXRlZC5tb2RpZmllcj1cdTRGRUVcdTk4RkVcdTVCNTBcdTMwNENcdTdFNzBcdTMwOEFcdThGRDRcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNTkKCiMgMDogc3ltYm9sLCAxOiBzZXQgb2YgbW9kaWZpZXIsIDI6IHN5bWJvbApjb21waWxlci5lcnIucmVwb3J0LmFjY2Vzcz17MH1cdTMwNkZ7Mn1cdTMwNjd7MX1cdTMwQTJcdTMwQUZcdTMwQkJcdTMwQjlcdTMwNTVcdTMwOENcdTMwN0VcdTMwNTkKCiMgMDogc3ltYm9sLCAxOiBzZXQgb2YgbW9kaWZpZXIsIDI6IHN5bWJvbApjb21waWxlci5taXNjLnJlcG9ydC5hY2Nlc3M9ezB9XHUzMDZGezJ9XHUzMDY3ezF9XHUzMEEyXHUzMEFGXHUzMEJCXHUzMEI5XHUzMDU1XHUzMDhDXHUzMDdFXHUzMDU5Cgpjb21waWxlci5lcnIucmV0Lm91dHNpZGUubWV0aD1cdTMwRTFcdTMwQkRcdTMwQzNcdTMwQzlcdTMwNkVcdTU5MTZcdTMwNkVyZXR1cm5cdTY1ODdcdTMwNjdcdTMwNTkKCmNvbXBpbGVyLmVyci5zaWduYXR1cmUuZG9lc250Lm1hdGNoLnN1cGVydHlwZT1cdTMwQjdcdTMwQjBcdTMwQ0JcdTMwQzFcdTMwRTNcdTMwNEN7MH1cdTMwNkJcdTkwNjlcdTU0MDhcdTMwNTdcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDJcdTRFOTJcdTYzREJcdTYwMjdcdTMwNkVcdTMwNkFcdTMwNDRcdTMwQjlcdTMwRkNcdTMwRDFcdTMwRkNcdTMwQkZcdTMwQTRcdTMwRDdcdTMwNjdcdTMwNTkKCmNvbXBpbGVyLmVyci5zaWduYXR1cmUuZG9lc250Lm1hdGNoLmludGY9XHUzMEI3XHUzMEIwXHUzMENCXHUzMEMxXHUzMEUzXHUzMDRDezB9XHUzMDZCXHU5MDY5XHU1NDA4XHUzMDU3XHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyXHU0RTkyXHU2M0RCXHU2MDI3XHUzMDZFXHUzMDZBXHUzMDQ0XHUzMEE0XHUzMEYzXHUzMEJGXHUzMEQ1XHUzMEE3XHUzMEZDXHUzMEI5XHUzMDY3XHUzMDU5CgojIDA6IG51bWJlciwgMTogbnVtYmVyCmNvbXBpbGVyLmVyci5tZXRob2QuaW52b2tlZC53aXRoLmluY29ycmVjdC5udW1iZXIuYXJndW1lbnRzPVx1MzBFMVx1MzBCRFx1MzBDM1x1MzBDOVx1MzA5Mlx1OEQ3N1x1NTJENVx1MzA1N1x1MzA1Rlx1NUYxNVx1NjU3MFx1MzA2RVx1NjU3MFx1MzA0Q1x1NkI2M1x1MzA1N1x1MzA0Rlx1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMlx1NEU4OFx1NjcxRlx1MzA1NVx1MzA4Q1x1MzA4Qlx1NjU3MFx1MzA2RnswfVx1MzA2N1x1MzA1OVx1MzA0Q1x1MzAwMXsxfVx1MzA0Q1x1ODk4Qlx1MzA2NFx1MzA0Qlx1MzA4QVx1MzA3RVx1MzA1N1x1MzA1RgoKIyAwOiBzeW1ib2wsIDE6IHN5bWJvbCwgMjogc3ltYm9sCmNvbXBpbGVyLmVyci5kb2VzLm5vdC5vdmVycmlkZS5hYnN0cmFjdD17MH1cdTMwNkZhYnN0cmFjdFx1MzA2N1x1MzA2QVx1MzA0Rlx1MzAwMXsyfVx1NTE4NVx1MzA2RWFic3RyYWN0XHUzMEUxXHUzMEJEXHUzMEMzXHUzMEM5ezF9XHUzMDkyXHUzMEFBXHUzMEZDXHUzMEQwXHUzMEZDXHUzMEU5XHUzMEE0XHUzMEM5XHUzMDU3XHUzMDdFXHUzMDVCXHUzMDkzCgpjb21waWxlci5lcnIuc291cmNlLmNhbnQub3ZlcndyaXRlLmlucHV0LmZpbGU9XHUzMEJEXHUzMEZDXHUzMEI5XHUzMDZFXHU2NkY4XHU4RkJDXHUzMDdGXHUzMEE4XHUzMEU5XHUzMEZDXHUzMDY3XHUzMDU5XHUzMDAyXHU1MTY1XHU1MjlCXHUzMEQ1XHUzMEExXHUzMEE0XHUzMEVCezB9XHUzMDkyXHU0RTBBXHU2NkY4XHUzMDREXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzCgpjb21waWxlci5lcnIuc3RhY2suc2ltLmVycm9yPVx1NTE4NVx1OTBFOFx1MzBBOFx1MzBFOVx1MzBGQzogezB9XHUzMDY3XHUzMDZFXHUzMEI5XHUzMEJGXHUzMEMzXHUzMEFGXHUzMEZCXHUzMEI3XHUzMERGXHUzMEU1XHUzMEVDXHUzMEZDXHUzMEI3XHUzMEU3XHUzMEYzXHUzMEZCXHUzMEE4XHUzMEU5XHUzMEZDCgpjb21waWxlci5lcnIuc3RhdGljLmltcC5vbmx5LmNsYXNzZXMuYW5kLmludGVyZmFjZXM9c3RhdGljIGltcG9ydFx1MzA2Rlx1MzBBRlx1MzBFOVx1MzBCOVx1MzA2OFx1MzBBNFx1MzBGM1x1MzBCRlx1MzBENVx1MzBBN1x1MzBGQ1x1MzBCOVx1MzA0Qlx1MzA4OVx1MzA2RVx1MzA3Rlx1MzA2OFx1MzA2QVx1MzA4QVx1MzA3RVx1MzA1OQoKY29tcGlsZXIuZXJyLnN0cmluZy5jb25zdC5yZXE9XHU1QjlBXHU2NTcwXHUzMDZFXHU2NTg3XHU1QjU3XHU1MjE3XHU1RjBGXHUzMDRDXHU1RkM1XHU4OTgxXHUzMDY3XHUzMDU5CgojIDA6IHN5bWJvbCwgMTogc3ltYm9sCmNvbXBpbGVyLmVyci5zeW50aGV0aWMubmFtZS5jb25mbGljdD1cdTMwQjdcdTMwRjNcdTMwRENcdTMwRUJ7MH1cdTMwNENcdTMwMDF7MX1cdTMwNjdcdTMwQjNcdTMwRjNcdTMwRDFcdTMwQTRcdTMwRTlcdTMwNENcdTU0MDhcdTYyMTBcdTMwNTdcdTMwNUZcdTMwQjdcdTMwRjNcdTMwRENcdTMwRUJcdTMwNjhcdTdBRjZcdTU0MDhcdTMwNTdcdTMwN0VcdTMwNTkKCmNvbXBpbGVyLmVyci50aHJvd3Mubm90LmFsbG93ZWQuaW4uaW50Zi5hbm5vdGF0aW9uPXRocm93c1x1N0JDMFx1MzA5MkBpbnRlcmZhY2VcdTMwRTFcdTMwRjNcdTMwRDBcdTMwRkNcdTMwNjdcdTRGN0ZcdTc1MjhcdTMwNTlcdTMwOEJcdTMwNTNcdTMwNjhcdTMwNkZcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTMKCmNvbXBpbGVyLmVyci50cnkud2l0aG91dC5jYXRjaC5vci5maW5hbGx5PScndHJ5JydcdTMwNzhcdTMwNkUnJ2NhdGNoJydcdTMwN0VcdTMwNUZcdTMwNkYnJ2ZpbmFsbHknJ1x1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5MwoKY29tcGlsZXIuZXJyLnRyeS53aXRob3V0LmNhdGNoLmZpbmFsbHkub3IucmVzb3VyY2UuZGVjbHM9Jyd0cnknJ1x1MzA3OFx1MzA2RScnY2F0Y2gnJ1x1MzAwMScnZmluYWxseScnXHUzMDdFXHUzMDVGXHUzMDZGXHUzMEVBXHUzMEJEXHUzMEZDXHUzMEI5XHU1QkEzXHU4QTAwXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzCgojIDA6IHN5bWJvbApjb21waWxlci5lcnIudHlwZS5kb2VzbnQudGFrZS5wYXJhbXM9XHU1NzhCezB9XHUzMDZGXHUzMEQxXHUzMEU5XHUzMEUxXHUzMEZDXHUzMEJGXHUzMDkyXHUzMDY4XHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzCgpjb21waWxlci5lcnIudHlwZS52YXIuY2FudC5iZS5kZXJlZj1cdTU3OEJcdTU5MDlcdTY1NzBcdTMwNEJcdTMwODlcdTkwNzhcdTYyOUVcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTMKCmNvbXBpbGVyLmVyci50eXBlLnZhci5tYXkubm90LmJlLmZvbGxvd2VkLmJ5Lm90aGVyLmJvdW5kcz1cdTMwNTNcdTMwNkVcdTU3OEJcdTU5MDlcdTY1NzBcdTMwNkVcdTVGOENcdTMwOERcdTMwNkJcdTRFRDZcdTMwNkVcdTU4ODNcdTc1NENcdTMwOTJcdTkxNERcdTdGNkVcdTMwNTlcdTMwOEJcdTMwNTNcdTMwNjhcdTMwNkZcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTMKCmNvbXBpbGVyLmVyci50eXBlLnZhci5tb3JlLnRoYW4ub25jZT1cdTU3OEJcdTU5MDlcdTY1NzB7MH1cdTMwNkZ7MX1cdTMwNkVcdTYyM0JcdTMwOEFcdTUwMjRcdTMwNkVcdTU3OEJcdTMwNjcyXHU1NkRFXHU0RUU1XHU0RTBBXHU1MUZBXHU3M0ZFXHUzMDU3XHUzMDdFXHUzMDU5XHUzMDAyXHUzMEE0XHUzMEYzXHUzMEI5XHUzMEJGXHUzMEYzXHUzMEI5XHU3NTFGXHU2MjEwXHUzMDU1XHUzMDhDXHUzMDZBXHUzMDQ0XHUzMDdFXHUzMDdFXHUzMDZCXHUzMDZGXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzCgpjb21waWxlci5lcnIudHlwZS52YXIubW9yZS50aGFuLm9uY2UuaW4ucmVzdWx0PVx1NTc4Qlx1NTkwOVx1NjU3MHswfVx1MzA2RnsxfVx1MzA2RVx1NTc4Qlx1MzA2NzJcdTU2REVcdTRFRTVcdTRFMEFcdTUxRkFcdTczRkVcdTMwNTdcdTMwN0VcdTMwNTlcdTMwMDJcdTMwQTRcdTMwRjNcdTMwQjlcdTMwQkZcdTMwRjNcdTMwQjlcdTc1MUZcdTYyMTBcdTMwNTVcdTMwOENcdTMwNkFcdTMwNDRcdTMwN0VcdTMwN0VcdTMwNkJcdTMwNkZcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTMKCiMgMDogdHlwZSwgMTogdHlwZSwgMjogc3RyaW5nCmNvbXBpbGVyLmVyci50eXBlcy5pbmNvbXBhdGlibGUuZGlmZi5yZXQ9XHU1NzhCezB9XHUzMDY4XHU1NzhCezF9XHUzMDZFXHU0RTkyXHU2M0RCXHU2MDI3XHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDAyXHU0RTIxXHU2NUI5XHUzMDY4XHUzMDgyezJ9XHUzMDkyXHU1QjlBXHU3RkE5XHUzMDU3XHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5XHUzMDRDXHUzMDAxXHU2MjNCXHUzMDhBXHU1MDI0XHUzMDZFXHU1NzhCXHUzMDRDXHU3MTIxXHU5NUEyXHU0RkMyXHUzMDY3XHUzMDU5CgojIDA6IGtpbmQgbmFtZSwgMTogdHlwZSwgMjogbmFtZSwgMzogbGlzdCBvZiB0eXBlLCA0OiBzeW1ib2wsIDU6IHN5bWJvbApjb21waWxlci5lcnIudHlwZXMuaW5jb21wYXRpYmxlLnVucmVsYXRlZC5kZWZhdWx0cz17MH0gezF9XHUzMDZGXHU1NzhCezR9XHUzMDY4ezV9XHUzMDRCXHUzMDg5ezJ9KHszfSlcdTMwNkVcdTk1QTJcdTkwMjNcdTMwNTdcdTMwNkFcdTMwNDRcdTMwQzdcdTMwRDVcdTMwQTlcdTMwRUJcdTMwQzhcdTMwOTJcdTdEOTlcdTYyN0ZcdTMwNTdcdTMwN0VcdTMwNTkKCiMgMDoga2luZCBuYW1lLCAxOiB0eXBlLCAyOiBuYW1lLCAzOiBsaXN0IG9mIHR5cGUsIDQ6IHN5bWJvbCwgNTogc3ltYm9sCmNvbXBpbGVyLmVyci50eXBlcy5pbmNvbXBhdGlibGUuYWJzdHJhY3QuZGVmYXVsdD17MH0gezF9XHUzMDZGXHU1NzhCezR9XHUzMDY4ezV9XHUzMDRCXHUzMDg5ezJ9KHszfSlcdTMwNkVcdTYyQkRcdThDNjFcdTMwNjhcdTMwQzdcdTMwRDVcdTMwQTlcdTMwRUJcdTMwQzhcdTMwOTJcdTdEOTlcdTYyN0ZcdTMwNTdcdTMwN0VcdTMwNTkKCiMgMDogbmFtZSwgMToga2luZCBuYW1lLCAyOiBzeW1ib2wKY29tcGlsZXIuZXJyLmRlZmF1bHQub3ZlcnJpZGVzLm9iamVjdC5tZW1iZXI9ezF9IHsyfVx1MzA2RVx1MzBDN1x1MzBENVx1MzBBOVx1MzBFQlx1MzBDOFx1MzBGQlx1MzBFMVx1MzBCRFx1MzBDM1x1MzBDOXswfVx1MzA2RmphdmEubGFuZy5PYmplY3RcdTMwNkVcdTMwRTFcdTMwRjNcdTMwRDBcdTMwRkNcdTMwOTJcdTMwQUFcdTMwRkNcdTMwRDBcdTMwRkNcdTMwRTlcdTMwQTRcdTMwQzlcdTMwNTdcdTMwN0VcdTMwNTkKCiMgMDogdHlwZQpjb21waWxlci5lcnIuaWxsZWdhbC5zdGF0aWMuaW50Zi5tZXRoLmNhbGw9c3RhdGljXHUzMEE0XHUzMEYzXHUzMEJGXHUzMEQ1XHUzMEE3XHUzMEZDXHUzMEI5XHUzMEZCXHUzMEUxXHUzMEJEXHUzMEMzXHUzMEM5XHUzMEZCXHUzMEIzXHUzMEZDXHUzMEVCXHUzMDRDXHU0RTBEXHU2QjYzXHUzMDY3XHUzMDU5XG5cdTUzRDdcdTRGRTFcdTVGMEZcdTMwNkZcdTU3OEJcdTRGRUVcdTk4RkVcdTVCNTAnJ3swfScnXHUzMDY3XHU3RjZFXHU2M0RCXHUzMDU1XHUzMDhDXHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5CgojIDA6IHR5cGUsIDE6IG1lc3NhZ2Ugc2VnbWVudApjb21waWxlci5lcnIuaWxsZWdhbC5kZWZhdWx0LnN1cGVyLmNhbGw9XHUzMEM3XHUzMEQ1XHUzMEE5XHUzMEVCXHUzMEM4XHUzMDZFXHUzMEI5XHUzMEZDXHUzMEQxXHUzMEZDXHUzMEZCXHUzMEIzXHUzMEZDXHUzMEVCXHUzMDZFXHU1NzhCXHU0RkVFXHU5OEZFXHU1QjUwezB9XHUzMDRDXHU0RTBEXHU2QjYzXHUzMDY3XHUzMDU5XG57MX0KCiMgMDogc3ltYm9sLCAxOiB0eXBlCmNvbXBpbGVyLm1pc2Mub3ZlcnJpZGRlbi5kZWZhdWx0PXsxfVx1MzA2RVx1MzBFMVx1MzBCRFx1MzBDM1x1MzBDOXswfVx1MzA2Rlx1MzBBQVx1MzBGQ1x1MzBEMFx1MzBGQ1x1MzBFOVx1MzBBNFx1MzBDOVx1MzA1NVx1MzA4Q1x1MzA3RVx1MzA1OQoKIyAwOiBzeW1ib2wsIDE6IHR5cGUgb3Igc3ltYm9sCmNvbXBpbGVyLm1pc2MucmVkdW5kYW50LnN1cGVydHlwZT1cdTUxOTdcdTk1NzdcdTMwNkFcdTMwQTRcdTMwRjNcdTMwQkZcdTMwRDVcdTMwQTdcdTMwRkNcdTMwQjl7MH1cdTMwNkZ7MX1cdTMwNkJcdTMwODhcdTMwNjNcdTMwNjZcdTYyRTFcdTVGMzVcdTMwNTVcdTMwOENcdTMwN0VcdTMwNTdcdTMwNUYKCmNvbXBpbGVyLmVyci51bmNsb3NlZC5jaGFyLmxpdD1cdTY1ODdcdTVCNTdcdTMwRUFcdTMwQzZcdTMwRTlcdTMwRUJcdTMwNENcdTk1ODlcdTMwNThcdTMwODlcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNUJcdTMwOTMKCmNvbXBpbGVyLmVyci51bmNsb3NlZC5jb21tZW50PVx1MzBCM1x1MzBFMVx1MzBGM1x1MzBDOFx1MzA0Q1x1OTU4OVx1MzA1OFx1MzA4OVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1Qlx1MzA5MwoKY29tcGlsZXIuZXJyLnVuY2xvc2VkLnN0ci5saXQ9XHU2NTg3XHU1QjU3XHU1MjE3XHUzMEVBXHUzMEM2XHUzMEU5XHUzMEVCXHUzMDRDXHU5NTg5XHUzMDU4XHUzMDg5XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDVCXHUzMDkzCgojIDA6IG5hbWUKY29tcGlsZXIuZXJyLnVuc3VwcG9ydGVkLmVuY29kaW5nPVx1MzBCNVx1MzBERFx1MzBGQ1x1MzBDOFx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA2QVx1MzA0NFx1MzBBOFx1MzBGM1x1MzBCM1x1MzBGQ1x1MzBDN1x1MzBBM1x1MzBGM1x1MzBCMFx1MzA2N1x1MzA1OTogezB9Cgpjb21waWxlci5lcnIuaW8uZXhjZXB0aW9uPVx1MzBCRFx1MzBGQ1x1MzBCOVx1MzBGQlx1MzBENVx1MzBBMVx1MzBBNFx1MzBFQlx1MzA2RVx1OEFBRFx1NTNENlx1MzA4QVx1MzBBOFx1MzBFOVx1MzBGQ1x1MzA2N1x1MzA1OTogezB9CgojIDA6IG5hbWUKY29tcGlsZXIuZXJyLnVuZGVmLmxhYmVsPVx1MzBFOVx1MzBEOVx1MzBFQnswfVx1MzA2Rlx1NjcyQVx1NUI5QVx1N0ZBOVx1MzA2N1x1MzA1OQoKIyAwOiBtZXNzYWdlIHNlZ21lbnQsIDE6IHVudXNlZApjb21waWxlci5lcnIuY2FudC5hcHBseS5kaWFtb25kPXswfVx1MzA2RVx1NTc4Qlx1NUYxNVx1NjU3MFx1MzA5Mlx1NjNBOFx1NUI5QVx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5MwoKIyAwOiBtZXNzYWdlIHNlZ21lbnQgb3IgdHlwZSwgMTogbWVzc2FnZSBzZWdtZW50CmNvbXBpbGVyLmVyci5jYW50LmFwcGx5LmRpYW1vbmQuMT17MH1cdTMwNkVcdTU3OEJcdTVGMTVcdTY1NzBcdTMwOTJcdTYzQThcdThBRDZcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcblx1NzQwNlx1NzUzMTogezF9CgojIDA6IG1lc3NhZ2Ugc2VnbWVudCBvciB0eXBlLCAxOiBtZXNzYWdlIHNlZ21lbnQKY29tcGlsZXIubWlzYy5jYW50LmFwcGx5LmRpYW1vbmQuMT17MH1cdTMwNkVcdTU3OEJcdTVGMTVcdTY1NzBcdTMwOTJcdTYzQThcdThBRDZcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcblx1NzQwNlx1NzUzMTogezF9Cgpjb21waWxlci5lcnIudW5yZWFjaGFibGUuc3RtdD1cdTMwNTNcdTMwNkVcdTY1ODdcdTMwNkJcdTUyMzZcdTVGQTFcdTMwNENcdTc5RkJcdTMwOEJcdTMwNTNcdTMwNjhcdTMwNkZcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTMKCmNvbXBpbGVyLmVyci5pbml0aWFsaXplci5tdXN0LmJlLmFibGUudG8uY29tcGxldGUubm9ybWFsbHk9XHU1MjFEXHU2NzFGXHU1MzE2XHU1QjUwXHUzMDZGXHU2QjYzXHU1RTM4XHUzMDZCXHU1QjhDXHU0RTg2XHUzMDY3XHUzMDREXHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5Cgpjb21waWxlci5lcnIuaW5pdGlhbGl6ZXIubm90LmFsbG93ZWQ9XHUzMEE0XHUzMENCXHUzMEI3XHUzMEUzXHUzMEU5XHUzMEE0XHUzMEI2XHUzMDZGaW50ZXJmYWNlc1x1MzA2N1x1MzA2Rlx1OEEzMVx1NTNFRlx1MzA1NVx1MzA4Q1x1MzA3RVx1MzA1Qlx1MzA5MwoKIyAwOiB0eXBlCmNvbXBpbGVyLmVyci51bnJlcG9ydGVkLmV4Y2VwdGlvbi5uZWVkLnRvLmNhdGNoLm9yLnRocm93PVx1NEY4Qlx1NTkxNnswfVx1MzA2Rlx1NTgzMVx1NTQ0QVx1MzA1NVx1MzA4Q1x1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMlx1MzBCOVx1MzBFRFx1MzBGQ1x1MzA1OVx1MzA4Qlx1MzA2Qlx1MzA2Rlx1MzAwMVx1NjM1NVx1NjM0OVx1MzA3RVx1MzA1Rlx1MzA2Rlx1NUJBM1x1OEEwMFx1MzA1OVx1MzA4Qlx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OQoKIyAwOiB0eXBlCmNvbXBpbGVyLmVyci51bnJlcG9ydGVkLmV4Y2VwdGlvbi5kZWZhdWx0LmNvbnN0cnVjdG9yPVx1MzBDN1x1MzBENVx1MzBBOVx1MzBFQlx1MzBDOFx1MzA2RVx1MzBCM1x1MzBGM1x1MzBCOVx1MzBDOFx1MzBFOVx1MzBBRlx1MzBCRlx1NTE4NVx1MzA2Qlx1NTgzMVx1NTQ0QVx1MzA1NVx1MzA4Q1x1MzA2QVx1MzA0NFx1NEY4Qlx1NTkxNnswfVx1MzA0Q1x1NUI1OFx1NTcyOFx1MzA1N1x1MzA3RVx1MzA1OQoKIyAwOiB0eXBlLCAxOiBuYW1lCmNvbXBpbGVyLmVyci51bnJlcG9ydGVkLmV4Y2VwdGlvbi5pbXBsaWNpdC5jbG9zZT1cdTU4MzFcdTU0NEFcdTMwNTVcdTMwOENcdTMwNkFcdTMwNDRcdTRGOEJcdTU5MTZ7MH1cdTMwNkZcdTMwMDFcdTMwQjlcdTMwRURcdTMwRkNcdTMwNTlcdTMwOEJcdTMwNkJcdTMwNkZcdTYzNTVcdTYzNDlcdTMwN0VcdTMwNUZcdTMwNkZcdTVCQTNcdThBMDBcdTMwNTlcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlcblx1MzBFQVx1MzBCRFx1MzBGQ1x1MzBCOVx1NTkwOVx1NjU3MCcnezF9JydcdTMwNjdcdTMwNkVjbG9zZSgpXHUzMDZFXHU2Njk3XHU5RUQ5XHU3Njg0XHUzMDZBXHUzMEIzXHUzMEZDXHUzMEVCXHUzMDRCXHUzMDg5XHU0RjhCXHU1OTE2XHUzMDRDXHUzMEI5XHUzMEVEXHUzMEZDXHUzMDU1XHUzMDhDXHUzMDdFXHUzMDU3XHUzMDVGCgpjb21waWxlci5lcnIudW5zdXBwb3J0ZWQuY3Jvc3MuZnAubGl0PTE2XHU5MDMyXHU2RDZFXHU1MkQ1XHU1QzBGXHU2NTcwXHU3MEI5XHUzMEVBXHUzMEM2XHUzMEU5XHUzMEVCXHUzMDZGXHUzMDUzXHUzMDZFVk1cdTMwNjdcdTMwNkZcdTMwQjVcdTMwRERcdTMwRkNcdTMwQzhcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNUJcdTMwOTMKCmNvbXBpbGVyLmVyci52b2lkLm5vdC5hbGxvd2VkLmhlcmU9XHUzMDUzXHUzMDUzXHUzMDY3Jyd2b2lkJydcdTU3OEJcdTMwOTJcdTRGN0ZcdTc1MjhcdTMwNTlcdTMwOEJcdTMwNTNcdTMwNjhcdTMwNkZcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTMKCiMgMDogc3RyaW5nCmNvbXBpbGVyLmVyci53cm9uZy5udW1iZXIudHlwZS5hcmdzPVx1NTc4Qlx1NUYxNVx1NjU3MFx1MzA2RVx1NjU3MFx1MzA0Q1x1NEUwRFx1NkI2M1x1MzA2N1x1MzA1OVx1MzAwMnswfVx1NTAwQlx1NUZDNVx1ODk4MVx1MzA2N1x1MzA1OQoKIyAwOiBzeW1ib2wKY29tcGlsZXIuZXJyLnZhci5taWdodC5hbHJlYWR5LmJlLmFzc2lnbmVkPVx1NTkwOVx1NjU3MHswfVx1MzA2Rlx1MzA1OVx1MzA2N1x1MzA2Qlx1NEVFM1x1NTE2NVx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA4Qlx1NTNFRlx1ODBGRFx1NjAyN1x1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OQoKIyAwOiBzeW1ib2wKY29tcGlsZXIuZXJyLnZhci5taWdodC5ub3QuaGF2ZS5iZWVuLmluaXRpYWxpemVkPVx1NTkwOVx1NjU3MHswfVx1MzA2Rlx1NTIxRFx1NjcxRlx1NTMxNlx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA2QVx1MzA0NFx1NTNFRlx1ODBGRFx1NjAyN1x1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OQoKIyAwOiBzeW1ib2wKY29tcGlsZXIuZXJyLnZhci5ub3QuaW5pdGlhbGl6ZWQuaW4uZGVmYXVsdC5jb25zdHJ1Y3Rvcj1cdTU5MDlcdTY1NzB7MH1cdTMwNkZcdTMwMDFcdTMwQzdcdTMwRDVcdTMwQTlcdTMwRUJcdTMwQzhcdTMwRkJcdTMwQjNcdTMwRjNcdTMwQjlcdTMwQzhcdTMwRTlcdTMwQUZcdTMwQkZcdTMwNjdcdTUyMURcdTY3MUZcdTUzMTZcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNUJcdTMwOTMKCiMgMDogc3ltYm9sCmNvbXBpbGVyLmVyci52YXIubWlnaHQuYmUuYXNzaWduZWQuaW4ubG9vcD1cdTU5MDlcdTY1NzB7MH1cdTMwNkZcdTMwRUJcdTMwRkNcdTMwRDdcdTUxODVcdTMwNjdcdTRFRTNcdTUxNjVcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwOEJcdTUzRUZcdTgwRkRcdTYwMjdcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTkKCiMgMDogc3ltYm9sLCAxOiBtZXNzYWdlIHNlZ21lbnQKY29tcGlsZXIuZXJyLnZhcmFyZ3MuaW52YWxpZC50cnVzdG1lLmFubm89ezB9XHU2Q0U4XHU5MUM4XHUzMDRDXHU3MTIxXHU1MkI5XHUzMDY3XHUzMDU5XHUzMDAyezF9CgojIDA6IHR5cGUKY29tcGlsZXIubWlzYy52YXJhcmdzLnRydXN0bWUub24ucmVpZmlhYmxlLnZhcmFyZ3M9XHU1M0VGXHU1OTA5XHU1RjE1XHU2NTcwXHU4OTgxXHU3RDIwXHU1NzhCezB9XHUzMDZGcmVpZmlhYmxlXHU1NzhCXHUzMDY3XHUzMDU5XHUzMDAyCgojIDA6IHN5bWJvbApjb21waWxlci5taXNjLnZhcmFyZ3MudHJ1c3RtZS5vbi5ub24udmFyYXJncy5tZXRoPVx1MzBFMVx1MzBCRFx1MzBDM1x1MzBDOXswfVx1MzA2Rlx1NTNFRlx1NTkwOVx1NUYxNVx1NjU3MFx1MzBFMVx1MzBCRFx1MzBDM1x1MzBDOVx1MzA2N1x1MzA2Rlx1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgoKIyAwOiBzeW1ib2wKY29tcGlsZXIubWlzYy52YXJhcmdzLnRydXN0bWUub24udmlydHVhbC52YXJhcmdzPVx1MzBBNFx1MzBGM1x1MzBCOVx1MzBCRlx1MzBGM1x1MzBCOVx1MzBGQlx1MzBFMVx1MzBCRFx1MzBDM1x1MzBDOXswfVx1MzA2RmZpbmFsXHUzMDY3XHUzMDgycHJpdmF0ZVx1MzA2N1x1MzA4Mlx1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgoKIyAwOiBzeW1ib2wKY29tcGlsZXIubWlzYy52YXJhcmdzLnRydXN0bWUub24udmlydHVhbC52YXJhcmdzLmZpbmFsLm9ubHk9XHUzMEE0XHUzMEYzXHUzMEI5XHUzMEJGXHUzMEYzXHUzMEI5XHUzMEZCXHUzMEUxXHUzMEJEXHUzMEMzXHUzMEM5ezB9XHUzMDZGZmluYWxcdTMwNjdcdTMwNkZcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKCiMgMDogdHlwZSwgMTogc3ltYm9sIGtpbmQsIDI6IHN5bWJvbApjb21waWxlci5taXNjLmluYWNjZXNzaWJsZS52YXJhcmdzLnR5cGU9XHU0RUVFXHU1M0VGXHU1OTA5XHU1RjE1XHU2NTcwXHU4OTgxXHU3RDIwXHU1NzhCezB9XHUzMDZGezF9IHsyfVx1MzA0Qlx1MzA4OVx1MzBBMlx1MzBBRlx1MzBCQlx1MzBCOVx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5MwoKIyBJbiB0aGUgZm9sbG93aW5nIHN0cmluZywgezF9IHdpbGwgYWx3YXlzIGJlIHRoZSBkZXRhaWwgbWVzc2FnZSBmcm9tCiMgamF2YS5pby5JT0V4Y2VwdGlvbi4KIyAwOiBzeW1ib2wsIDE6IHN0cmluZwpjb21waWxlci5lcnIuY2xhc3MuY2FudC53cml0ZT17MH1cdTMwNkVcdTY2RjhcdThGQkNcdTMwN0ZcdTRFMkRcdTMwNkJcdTMwQThcdTMwRTlcdTMwRkNcdTMwNENcdTc2N0FcdTc1MUZcdTMwNTdcdTMwN0VcdTMwNTdcdTMwNUY6IHsxfQoKIyBJbiB0aGUgZm9sbG93aW5nIHN0cmluZywgezB9IGlzIHRoZSBuYW1lIG9mIHRoZSBjbGFzcyBpbiB0aGUgSmF2YSBzb3VyY2UuCiMgSXQgcmVhbGx5IHNob3VsZCBiZSB1c2VkIHR3byB0aW1lcy4uCiMgMDogbmFtZQpjb21waWxlci5lcnIuY2xhc3MucHVibGljLnNob3VsZC5iZS5pbi5maWxlPVx1MzBBRlx1MzBFOVx1MzBCOXswfVx1MzA2RnB1YmxpY1x1MzA2N1x1MzA0Mlx1MzA4QVx1MzAwMVx1MzBENVx1MzBBMVx1MzBBNFx1MzBFQnswfS5qYXZhXHUzMDY3XHU1QkEzXHU4QTAwXHUzMDU5XHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5CgojIyBBbGwgZXJyb3JzIHdoaWNoIGRvIG5vdCByZWZlciB0byBhIHBhcnRpY3VsYXIgbGluZSBpbiB0aGUgc291cmNlIGNvZGUgYXJlCiMjIHByZWNlZGVkIGJ5IHRoaXMgc3RyaW5nLgpjb21waWxlci5lcnIuZXJyb3I9XHUzMEE4XHUzMEU5XHUzMEZDOiAKCiMgVGhlIGZvbGxvd2luZyBlcnJvciBtZXNzYWdlcyBkbyBub3QgcmVmZXIgdG8gYSBsaW5lIGluIHRoZSBzb3VyY2UgY29kZS4KY29tcGlsZXIuZXJyLmNhbnQucmVhZC5maWxlPXswfVx1MzA5Mlx1OEFBRFx1MzA3Rlx1OEZCQ1x1MzA4MVx1MzA3RVx1MzA1Qlx1MzA5MwoKIyAwOiBzdHJpbmcKY29tcGlsZXIuZXJyLnBsdWdpbi5ub3QuZm91bmQ9XHUzMEQ3XHUzMEU5XHUzMEIwXHUzMEE0XHUzMEYzXHUzMDRDXHU4OThCXHUzMDY0XHUzMDRCXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzOiB7MH0KCiMgMDogcGF0aApjb21waWxlci53YXJuLmxvY24udW5rbm93bi5maWxlLm9uLm1vZHVsZS5wYXRoPVx1MzBFMlx1MzBCOFx1MzBFNVx1MzBGQ1x1MzBFQlx1MzBGQlx1MzBEMVx1MzBCOVx1MzA2RVx1MzBENVx1MzBBMVx1MzBBNFx1MzBFQlx1MzA0Q1x1NEUwRFx1NjYwRVx1MzA2N1x1MzA1OTogezB9CgoKIyAwOiBwYXRoCmNvbXBpbGVyLmVyci5sb2NuLmJhZC5tb2R1bGUtaW5mbz17MH1cdTMwNkVtb2R1bGUtaW5mby5jbGFzc1x1MzA5Mlx1OEFBRFx1NTNENlx1MzA4QVx1NEUyRFx1MzA2Qlx1NTU0Rlx1OTg0Q1x1MzA0Q1x1NzY3QVx1NzUxRlx1MzA1N1x1MzA3RVx1MzA1N1x1MzA1RgoKIyAwOiBwYXRoCmNvbXBpbGVyLmVyci5sb2NuLmNhbnQucmVhZC5kaXJlY3Rvcnk9XHUzMEM3XHUzMEEzXHUzMEVDXHUzMEFGXHUzMEM4XHUzMEVBezB9XHUzMDkyXHU4QUFEXHUzMDdGXHU1M0Q2XHUzMDhDXHUzMDdFXHUzMDVCXHUzMDkzCgojIDA6IHBhdGgKY29tcGlsZXIuZXJyLmxvY24uY2FudC5yZWFkLmZpbGU9XHUzMEQ1XHUzMEExXHUzMEE0XHUzMEVCezB9XHUzMDkyXHU4QUFEXHUzMDdGXHU1M0Q2XHUzMDhDXHUzMDdFXHUzMDVCXHUzMDkzCgojIDA6IHBhdGgKY29tcGlsZXIuZXJyLmxvY24uY2FudC5nZXQubW9kdWxlLm5hbWUuZm9yLmphcj17MH1cdTMwNkVcdTMwRTJcdTMwQjhcdTMwRTVcdTMwRkNcdTMwRUJcdTU0MERcdTMwOTJcdTUyMjRcdTUyMjVcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTMKCiMgMDogcGF0aApjb21waWxlci5lcnIubXVsdGktbW9kdWxlLm91dGRpci5jYW5ub3QuYmUuZXhwbG9kZWQubW9kdWxlPVx1ODkwN1x1NjU3MFx1MzBFMlx1MzBCOFx1MzBFNVx1MzBGQ1x1MzBFQlx1MzBGQlx1MzBFMlx1MzBGQ1x1MzBDOVx1MzA2N1x1MzAwMVx1NTFGQVx1NTI5Qlx1MzBDN1x1MzBBM1x1MzBFQ1x1MzBBRlx1MzBDOFx1MzBFQVx1MzA2Rlx1NUM1NVx1OTU4Qlx1MzA1N1x1MzA1Rlx1MzBFMlx1MzBCOFx1MzBFNVx1MzBGQ1x1MzBFQlx1MzA2Qlx1MzA1OVx1MzA4Qlx1MzA1M1x1MzA2OFx1MzA2Rlx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5MzogezB9CgojIDA6IHBhdGgKY29tcGlsZXIud2Fybi5vdXRkaXIuaXMuaW4uZXhwbG9kZWQubW9kdWxlPVx1NTFGQVx1NTI5Qlx1MzBDN1x1MzBBM1x1MzBFQ1x1MzBBRlx1MzBDOFx1MzBFQVx1MzA2Rlx1NUM1NVx1OTU4Qlx1MzA1N1x1MzA1Rlx1MzBFMlx1MzBCOFx1MzBFNVx1MzBGQ1x1MzBFQlx1NTE4NVx1MzA2N1x1MzA1OTogezB9CgojIDA6IHBhdGgKY29tcGlsZXIuZXJyLmxvY24ubW9kdWxlLWluZm8ubm90LmFsbG93ZWQub24ucGF0Y2gucGF0aD1tb2R1bGUtaW5mby5jbGFzc1x1MzA2Rlx1MzBEMVx1MzBDM1x1MzBDMVx1MzBGQlx1MzBEMVx1MzBCOVx1MzA2N1x1MzA2Rlx1OEEzMVx1NTNFRlx1MzA1NVx1MzA4Q1x1MzA3RVx1MzA1Qlx1MzA5MzogezB9CgojIDA6IHN0cmluZwpjb21waWxlci5lcnIubG9jbi5pbnZhbGlkLmFyZy5mb3IueHBhdGNoPS0tcGF0Y2gtbW9kdWxlXHUzMEFBXHUzMEQ3XHUzMEI3XHUzMEU3XHUzMEYzXHUzMDZFXHU1RjE1XHU2NTcwXHUzMDRDXHU3MTIxXHU1MkI5XHUzMDY3XHUzMDU5OiB7MH0KCiMjIyMjCgojIEZhdGFsIEVycm9ycwoKY29tcGlsZXIubWlzYy5mYXRhbC5lcnIubm8uamF2YS5sYW5nPVx1ODFGNFx1NTQ3RFx1NzY4NFx1MzBBOFx1MzBFOVx1MzBGQzogXHUzMEFGXHUzMEU5XHUzMEI5XHUzMEQxXHUzMEI5XHUzMDdFXHUzMDVGXHUzMDZGXHUzMEQ2XHUzMEZDXHUzMEM4XHUzMEZCXHUzMEFGXHUzMEU5XHUzMEI5XHUzMEQxXHUzMEI5XHUzMDY3XHUzMEQxXHUzMEMzXHUzMEIxXHUzMEZDXHUzMEI4amF2YS5sYW5nXHUzMDkyXHU2OTFDXHU1MUZBXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzCgpjb21waWxlci5taXNjLmZhdGFsLmVyci5jYW50LmxvY2F0ZS5tZXRoPVx1ODFGNFx1NTQ3RFx1NzY4NFx1MzBBOFx1MzBFOVx1MzBGQzogXHUzMEUxXHUzMEJEXHUzMEMzXHUzMEM5ezB9XHUzMDkyXHU2OTFDXHU1MUZBXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzCgpjb21waWxlci5taXNjLmZhdGFsLmVyci5jYW50LmxvY2F0ZS5maWVsZD1cdTgxRjRcdTU0N0RcdTc2ODRcdTMwQThcdTMwRTlcdTMwRkM6IFx1MzBENVx1MzBBM1x1MzBGQ1x1MzBFQlx1MzBDOXswfVx1MzA5Mlx1NjkxQ1x1NTFGQVx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5MwoKY29tcGlsZXIubWlzYy5mYXRhbC5lcnIuY2FudC5sb2NhdGUuY3Rvcj1cdTgxRjRcdTU0N0RcdTc2ODRcdTMwQThcdTMwRTlcdTMwRkM6IHswfVx1MzA2RVx1MzBCM1x1MzBGM1x1MzBCOVx1MzBDOFx1MzBFOVx1MzBBRlx1MzBCRlx1MzA5Mlx1NjkxQ1x1NTFGQVx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5MwoKY29tcGlsZXIubWlzYy5mYXRhbC5lcnIuY2FudC5jbG9zZT1cdTgxRjRcdTU0N0RcdTc2ODRcdTMwQThcdTMwRTlcdTMwRkM6IFx1MzBCM1x1MzBGM1x1MzBEMVx1MzBBNFx1MzBFOVx1MzBGQlx1MzBFQVx1MzBCRFx1MzBGQ1x1MzBCOVx1MzA5Mlx1OTU4OVx1MzA1OFx1MzA4Qlx1MzA1M1x1MzA2OFx1MzA0Q1x1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5MwoKIyMjIyMKCiMjCiMjIG1pc2NlbGxhbmVvdXMgc3RyaW5ncwojIwoKY29tcGlsZXIubWlzYy5kaWFtb25kLmFub255bW91cy5tZXRob2RzLmltcGxpY2l0bHkub3ZlcnJpZGU9KDw+XHUzMDZFXHUzMDVGXHUzMDgxXHUzMDAxXHUzMDUzXHUzMDZFXHU1MzNGXHU1NDBEXHUzMEFGXHUzMEU5XHUzMEI5XHUzMDZCXHU1QkEzXHU4QTAwXHUzMDU1XHUzMDhDXHUzMDVGXHUzMDU5XHUzMDc5XHUzMDY2XHUzMDZFXHU5NzVFcHJpdmF0ZVx1MzBFMVx1MzBCRFx1MzBDM1x1MzBDOVx1MzA2Rlx1MzBCOVx1MzBGQ1x1MzBEMVx1MzBGQ1x1MzBCRlx1MzBBNFx1MzBEN1x1MzA2RVx1MzBFMVx1MzBCRFx1MzBDM1x1MzBDOVx1MzA5Mlx1MzBBQVx1MzBGQ1x1MzBEMFx1MzBGQ1x1MzBFOVx1MzBBNFx1MzBDOVx1MzA3RVx1MzA1Rlx1MzA2Rlx1NUI5Rlx1ODhDNVx1MzA1N1x1MzA3RVx1MzA1Qlx1MzA5MykKCmNvbXBpbGVyLm1pc2Muc291cmNlLnVuYXZhaWxhYmxlPShcdTMwQkRcdTMwRkNcdTMwQjlcdTMwNENcdTUyMjlcdTc1MjhcdTRFMERcdTUzRUYpCgpjb21waWxlci5taXNjLmJhc2UubWVtYmVyc2hpcD1cdTMwNTlcdTMwNzlcdTMwNjZcdTMwNkVcdTMwRDlcdTMwRkNcdTMwQjlcdTMwRkJcdTMwQUZcdTMwRTlcdTMwQjlcdTMwNENcdTMwRTFcdTMwRjNcdTMwRDBcdTMwRkNcdTMwNjdcdTMwNTkKCiMgMDogc3RyaW5nLCAxOiBzdHJpbmcsIDI6IGJvb2xlYW4KY29tcGlsZXIubWlzYy54LnByaW50LnByb2Nlc3Nvci5pbmZvPVx1MzBEN1x1MzBFRFx1MzBCQlx1MzBDM1x1MzBCNXswfVx1MzA2RnsxfVx1MzA2Qlx1NEUwMFx1ODFGNFx1MzA1N1x1MzAwMXsyfVx1MzA5Mlx1OEZENFx1MzA1N1x1MzA3RVx1MzA1OVx1MzAwMgoKIyAwOiBudW1iZXIsIDE6IHN0cmluZywgMjogc2V0IG9mIHN5bWJvbCwgMzogYm9vbGVhbgpjb21waWxlci5taXNjLngucHJpbnQucm91bmRzPVx1NUY4MFx1NUZBOXswfTpcblx0XHU1MTY1XHU1MjlCXHUzMEQ1XHUzMEExXHUzMEE0XHUzMEVCOiB7MX1cblx0XHU2Q0U4XHU5MUM4OiB7Mn1cblx0XHU2NzAwXHU1RjhDXHUzMDZFXHU1RjgwXHU1RkE5OiB7M30KCiMgMDogZmlsZSBuYW1lCmNvbXBpbGVyLndhcm4uZmlsZS5mcm9tLmZ1dHVyZT1cdTMwRDVcdTMwQTFcdTMwQTRcdTMwRUJ7MH1cdTMwNkVcdTU5MDlcdTY2RjRcdTY1RTVcdTMwNENcdTVDMDZcdTY3NjVcdTMwNkVcdTY1RTVcdTRFRDhcdTMwNjdcdTMwNTkKCiMjIyMjCgojIyBUaGUgZm9sbG93aW5nIHN0cmluZyB3aWxsIGFwcGVhciBiZWZvcmUgYWxsIG1lc3NhZ2VzIGtleWVkIGFzOgojIyAiY29tcGlsZXIubm90ZSIuCgpjb21waWxlci5ub3RlLmNvbXByZXNzZWQuZGlhZ3M9XHU0RTAwXHU5MEU4XHUzMDZFXHUzMEUxXHUzMEMzXHUzMEJCXHUzMEZDXHUzMEI4XHUzMDZGXHU3QzIxXHU3NTY1XHU1MzE2XHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5XHUzMDAyLVhkaWFnczp2ZXJib3NlXHUzMDY3XHU1MThEXHUzMEIzXHUzMEYzXHUzMEQxXHUzMEE0XHUzMEVCXHUzMDU3XHUzMDY2XHU1QjhDXHU1MTY4XHUzMDZBXHU1MUZBXHU1MjlCXHUzMDkyXHU1M0Q2XHU1Rjk3XHUzMDU3XHUzMDY2XHUzMDRGXHUzMDYwXHUzMDU1XHUzMDQ0CgojIDA6IGJvb2xlYW4sIDE6IHN5bWJvbApjb21waWxlci5ub3RlLmxhbWJkYS5zdGF0PVx1MzBFOVx1MzBFMFx1MzBDMFx1NUYwRlx1MzA5Mlx1NTkwOVx1NjNEQlx1MzA1N1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1OVxuXHU0RUUzXHU2NkZGbWV0YWZhY3RvcnkgPSB7MH1cblx1NTQwOFx1NjIxMFx1MzBFMVx1MzBCRFx1MzBDM1x1MzBDOSA9IHsxfQoKIyAwOiBib29sZWFuLCAxOiB1bnVzZWQKY29tcGlsZXIubm90ZS5tcmVmLnN0YXQ9XHUzMEUxXHUzMEJEXHUzMEMzXHUzMEM5XHU1M0MyXHU3MTY3XHUzMDkyXHU1OTA5XHU2M0RCXHUzMDU3XHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5XG5cdTRFRTNcdTY2RkZtZXRhZmFjdG9yeSA9IHswfVxuCiMgMDogYm9vbGVhbiwgMTogc3ltYm9sCmNvbXBpbGVyLm5vdGUubXJlZi5zdGF0LjE9XHUzMEUxXHUzMEJEXHUzMEMzXHUzMEM5XHU1M0MyXHU3MTY3XHUzMDkyXHU1OTA5XHU2M0RCXHUzMDU3XHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5XG5cdTRFRTNcdTY2RkZtZXRhZmFjdG9yeSA9IHswfVxuXHUzMEQ2XHUzMEVBXHUzMEMzXHUzMEI4XHUzMEZCXHUzMEUxXHUzMEJEXHUzMEMzXHUzMEM5ID0gezF9Cgpjb21waWxlci5ub3RlLm5vdGU9XHU2Q0U4XHU2MTBGOgoKIyAwOiBmaWxlIG5hbWUKY29tcGlsZXIubm90ZS5kZXByZWNhdGVkLmZpbGVuYW1lPXswfVx1MzA2Rlx1NjNBOFx1NTk2OFx1MzA1NVx1MzA4Q1x1MzA2QVx1MzA0NEFQSVx1MzA5Mlx1NEY3Rlx1NzUyOFx1MzA3RVx1MzA1Rlx1MzA2Rlx1MzBBQVx1MzBGQ1x1MzBEMFx1MzBGQ1x1MzBFOVx1MzBBNFx1MzBDOVx1MzA1N1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1OVx1MzAwMgoKY29tcGlsZXIubm90ZS5kZXByZWNhdGVkLnBsdXJhbD1cdTRFMDBcdTkwRThcdTMwNkVcdTUxNjVcdTUyOUJcdTMwRDVcdTMwQTFcdTMwQTRcdTMwRUJcdTMwNkZcdTYzQThcdTU5NjhcdTMwNTVcdTMwOENcdTMwNkFcdTMwNDRBUElcdTMwOTJcdTRGN0ZcdTc1MjhcdTMwN0VcdTMwNUZcdTMwNkZcdTMwQUFcdTMwRkNcdTMwRDBcdTMwRkNcdTMwRTlcdTMwQTRcdTMwQzlcdTMwNTdcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNTlcdTMwMDIKCiMgVGhlIGZvbGxvd2luZyBzdHJpbmcgbWF5IGFwcGVhciBhZnRlciBvbmUgb2YgdGhlIGFib3ZlIGRlcHJlY2F0aW9uCiMgbWVzc2FnZXMuCmNvbXBpbGVyLm5vdGUuZGVwcmVjYXRlZC5yZWNvbXBpbGU9XHU4QTczXHU3RDMwXHUzMDZGXHUzMDAxLVhsaW50OmRlcHJlY2F0aW9uXHUzMEFBXHUzMEQ3XHUzMEI3XHUzMEU3XHUzMEYzXHUzMDkyXHU2MzA3XHU1QjlBXHUzMDU3XHUzMDY2XHU1MThEXHUzMEIzXHUzMEYzXHUzMEQxXHUzMEE0XHUzMEVCXHUzMDU3XHUzMDY2XHUzMDRGXHUzMDYwXHUzMDU1XHUzMDQ0XHUzMDAyCgojIDA6IGZpbGUgbmFtZQpjb21waWxlci5ub3RlLmRlcHJlY2F0ZWQuZmlsZW5hbWUuYWRkaXRpb25hbD17MH1cdTMwNkJcdTYzQThcdTU5NjhcdTMwNTVcdTMwOENcdTMwNkFcdTMwNDRBUElcdTMwNkVcdThGRkRcdTUyQTBcdTRGN0ZcdTc1MjhcdTMwN0VcdTMwNUZcdTMwNkZcdTMwQUFcdTMwRkNcdTMwRDBcdTMwRkNcdTMwRTlcdTMwQTRcdTMwQzlcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlcdTMwMDIKCmNvbXBpbGVyLm5vdGUuZGVwcmVjYXRlZC5wbHVyYWwuYWRkaXRpb25hbD1cdTRFMDBcdTkwRThcdTMwNkVcdTUxNjVcdTUyOUJcdTMwRDVcdTMwQTFcdTMwQTRcdTMwRUJcdTMwNkZcdTYzQThcdTU5NjhcdTMwNTVcdTMwOENcdTMwNkFcdTMwNDRBUElcdTMwOTJcdThGRkRcdTUyQTBcdTRGN0ZcdTc1MjhcdTMwN0VcdTMwNUZcdTMwNkZcdTMwQUFcdTMwRkNcdTMwRDBcdTMwRkNcdTMwRTlcdTMwQTRcdTMwQzlcdTMwNTdcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNTlcdTMwMDIKCiMgMDogZmlsZSBuYW1lCmNvbXBpbGVyLm5vdGUucmVtb3ZhbC5maWxlbmFtZT17MH1cdTMwNkZcdTMwMDFcdTUyNEFcdTk2NjRcdTc1MjhcdTMwNkJcdTMwREVcdTMwRkNcdTMwQUZcdTMwNTVcdTMwOENcdTMwNUZcdTYzQThcdTU5NjhcdTMwNTVcdTMwOENcdTMwNkFcdTMwNDRBUElcdTMwOTJcdTRGN0ZcdTc1MjhcdTMwN0VcdTMwNUZcdTMwNkZcdTMwQUFcdTMwRkNcdTMwRDBcdTMwRkNcdTMwRTlcdTMwQTRcdTMwQzlcdTMwNTdcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNTlcdTMwMDIKCmNvbXBpbGVyLm5vdGUucmVtb3ZhbC5wbHVyYWw9XHU0RTAwXHU5MEU4XHUzMDZFXHU1MTY1XHU1MjlCXHUzMEQ1XHUzMEExXHUzMEE0XHUzMEVCXHUzMDZGXHUzMDAxXHU1MjRBXHU5NjY0XHU3NTI4XHUzMDZCXHUzMERFXHUzMEZDXHUzMEFGXHUzMDU1XHUzMDhDXHUzMDVGXHU2M0E4XHU1OTY4XHUzMDU1XHUzMDhDXHUzMDZBXHUzMDQ0QVBJXHUzMDkyXHU0RjdGXHU3NTI4XHUzMDdFXHUzMDVGXHUzMDZGXHUzMEFBXHUzMEZDXHUzMEQwXHUzMEZDXHUzMEU5XHUzMEE0XHUzMEM5XHUzMDU3XHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5XHUzMDAyCgojIFRoZSBmb2xsb3dpbmcgc3RyaW5nIG1heSBhcHBlYXIgYWZ0ZXIgb25lIG9mIHRoZSBhYm92ZSByZW1vdmFsIG1lc3NhZ2VzLgpjb21waWxlci5ub3RlLnJlbW92YWwucmVjb21waWxlPVx1OEE3M1x1N0QzMFx1MzA2Rlx1MzAwMS1YbGludDpyZW1vdmFsXHUzMEFBXHUzMEQ3XHUzMEI3XHUzMEU3XHUzMEYzXHUzMDkyXHU2MzA3XHU1QjlBXHUzMDU3XHUzMDY2XHU1MThEXHUzMEIzXHUzMEYzXHUzMEQxXHUzMEE0XHUzMEVCXHUzMDU3XHUzMDY2XHUzMDRGXHUzMDYwXHUzMDU1XHUzMDQ0XHUzMDAyCgojIDA6IGZpbGUgbmFtZQpjb21waWxlci5ub3RlLnJlbW92YWwuZmlsZW5hbWUuYWRkaXRpb25hbD17MH1cdTMwNkJcdTMwMDFcdTUyNEFcdTk2NjRcdTc1MjhcdTMwNkJcdTMwREVcdTMwRkNcdTMwQUZcdTMwNTVcdTMwOENcdTMwNUZcdTYzQThcdTU5NjhcdTMwNTVcdTMwOENcdTMwNkFcdTMwNDRBUElcdTMwNkVcdThGRkRcdTUyQTBcdTRGN0ZcdTc1MjhcdTMwN0VcdTMwNUZcdTMwNkZcdTMwQUFcdTMwRkNcdTMwRDBcdTMwRkNcdTMwRTlcdTMwQTRcdTMwQzlcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlcdTMwMDIKCmNvbXBpbGVyLm5vdGUucmVtb3ZhbC5wbHVyYWwuYWRkaXRpb25hbD1cdTRFMDBcdTkwRThcdTMwNkVcdTUxNjVcdTUyOUJcdTMwRDVcdTMwQTFcdTMwQTRcdTMwRUJcdTMwNkZcdTMwMDFcdTUyNEFcdTk2NjRcdTc1MjhcdTMwNkJcdTMwREVcdTMwRkNcdTMwQUZcdTMwNTVcdTMwOENcdTMwNUZcdTYzQThcdTU5NjhcdTMwNTVcdTMwOENcdTMwNkFcdTMwNDRBUElcdTMwOTJcdThGRkRcdTUyQTBcdTRGN0ZcdTc1MjhcdTMwN0VcdTMwNUZcdTMwNkZcdTMwQUFcdTMwRkNcdTMwRDBcdTMwRkNcdTMwRTlcdTMwQTRcdTMwQzlcdTMwNTdcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNTlcdTMwMDIKCiMgMDogZmlsZSBuYW1lCmNvbXBpbGVyLm5vdGUudW5jaGVja2VkLmZpbGVuYW1lPXswfVx1MzA2RVx1NjRDRFx1NEY1Q1x1MzA2Rlx1MzAwMVx1NjcyQVx1MzBDMVx1MzBBN1x1MzBDM1x1MzBBRlx1MzA3RVx1MzA1Rlx1MzA2Rlx1NUI4OVx1NTE2OFx1MzA2N1x1MzA2Rlx1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgoKY29tcGlsZXIubm90ZS51bmNoZWNrZWQucGx1cmFsPVx1NTE2NVx1NTI5Qlx1MzBENVx1MzBBMVx1MzBBNFx1MzBFQlx1MzA2RVx1NjRDRFx1NEY1Q1x1MzA2RVx1MzA0Nlx1MzA2MVx1MzAwMVx1NjcyQVx1MzBDMVx1MzBBN1x1MzBDM1x1MzBBRlx1MzA3RVx1MzA1Rlx1MzA2Rlx1NUI4OVx1NTE2OFx1MzA2N1x1MzA2Rlx1MzA2QVx1MzA0NFx1MzA4Mlx1MzA2RVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMgoKIyBUaGUgZm9sbG93aW5nIHN0cmluZyBtYXkgYXBwZWFyIGFmdGVyIG9uZSBvZiB0aGUgYWJvdmUgdW5jaGVja2VkIG1lc3NhZ2VzLgpjb21waWxlci5ub3RlLnVuY2hlY2tlZC5yZWNvbXBpbGU9XHU4QTczXHU3RDMwXHUzMDZGXHUzMDAxLVhsaW50OnVuY2hlY2tlZFx1MzBBQVx1MzBEN1x1MzBCN1x1MzBFN1x1MzBGM1x1MzA5Mlx1NjMwN1x1NUI5QVx1MzA1N1x1MzA2Nlx1NTE4RFx1MzBCM1x1MzBGM1x1MzBEMVx1MzBBNFx1MzBFQlx1MzA1N1x1MzA2Nlx1MzA0Rlx1MzA2MFx1MzA1NVx1MzA0NFx1MzAwMgoKIyAwOiBmaWxlIG5hbWUKY29tcGlsZXIubm90ZS51bmNoZWNrZWQuZmlsZW5hbWUuYWRkaXRpb25hbD17MH1cdTMwNkJcdTY3MkFcdTMwQzFcdTMwQTdcdTMwQzNcdTMwQUZcdTMwN0VcdTMwNUZcdTMwNkZcdTVCODlcdTUxNjhcdTMwNjdcdTMwNkZcdTMwNkFcdTMwNDRcdTY0Q0RcdTRGNUNcdTMwNENcdTMwNTVcdTMwODlcdTMwNkJcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlcdTMwMDIKCmNvbXBpbGVyLm5vdGUudW5jaGVja2VkLnBsdXJhbC5hZGRpdGlvbmFsPVx1NTE2NVx1NTI5Qlx1MzBENVx1MzBBMVx1MzBBNFx1MzBFQlx1MzA2RVx1NjRDRFx1NEY1Q1x1MzA2RVx1MzA0Nlx1MzA2MVx1MzAwMVx1NjcyQVx1MzBDMVx1MzBBN1x1MzBDM1x1MzBBRlx1MzA3RVx1MzA1Rlx1MzA2Rlx1NUI4OVx1NTE2OFx1MzA2N1x1MzA2Rlx1MzA2QVx1MzA0NFx1MzA4Mlx1MzA2RVx1MzA0Q1x1MzA1NVx1MzA4OVx1MzA2Qlx1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVx1MzAwMgoKIyBOb3RlcyByZWxhdGVkIHRvIGFubm90YXRpb24gcHJvY2Vzc2luZwoKIyBQcmludCBhIGNsaWVudC1nZW5lcmF0ZWQgbm90ZTsgYXNzdW1lZCB0byBiZSBsb2NhbGl6ZWQsIG5vIHRyYW5zbGF0aW9uIHJlcXVpcmVkCiMgMDogc3RyaW5nCmNvbXBpbGVyLm5vdGUucHJvYy5tZXNzYWdlcj17MH0KCiMjIyMjCgojIDA6IG51bWJlcgpjb21waWxlci5taXNjLmNvdW50LmVycm9yPVx1MzBBOFx1MzBFOVx1MzBGQ3swfVx1NTAwQgoKIyAwOiBudW1iZXIKY29tcGlsZXIubWlzYy5jb3VudC5lcnJvci5wbHVyYWw9XHUzMEE4XHUzMEU5XHUzMEZDezB9XHU1MDBCCgojIDA6IG51bWJlcgpjb21waWxlci5taXNjLmNvdW50Lndhcm49XHU4QjY2XHU1NDRBezB9XHU1MDBCCgojIDA6IG51bWJlcgpjb21waWxlci5taXNjLmNvdW50Lndhcm4ucGx1cmFsPVx1OEI2Nlx1NTQ0QXswfVx1NTAwQgoKY29tcGlsZXIubWlzYy52ZXJzaW9uLm5vdC5hdmFpbGFibGU9KFx1MzBEMFx1MzBGQ1x1MzBCOFx1MzBFN1x1MzBGM1x1NjBDNVx1NTgzMVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5MykKCiMjIGV4dHJhIG91dHB1dCB3aGVuIHVzaW5nIC12ZXJib3NlIChKYXZhQ29tcGlsZXIpCgojIDA6IHN5bWJvbApjb21waWxlci5taXNjLnZlcmJvc2UuY2hlY2tpbmcuYXR0cmlidXRpb249W3swfVx1MzA5Mlx1NzhCQVx1OEE4RFx1NEUyRF0KCiMgMDogc3RyaW5nCmNvbXBpbGVyLm1pc2MudmVyYm9zZS5wYXJzaW5nLmRvbmU9W3swfVx1MzBERlx1MzBFQVx1NzlEMlx1MzA2N1x1NjlDQlx1NjU4N1x1ODlFM1x1Njc5MFx1NUI4Q1x1NEU4Nl0KCiMgMDogZmlsZSBuYW1lCmNvbXBpbGVyLm1pc2MudmVyYm9zZS5wYXJzaW5nLnN0YXJ0ZWQ9W3swfVx1MzA5Mlx1NjlDQlx1NjU4N1x1ODlFM1x1Njc5MFx1OTU4Qlx1NTlDQl0KCiMgMDogc3RyaW5nCmNvbXBpbGVyLm1pc2MudmVyYm9zZS50b3RhbD1bXHU1NDA4XHU4QTA4ezB9XHUzMERGXHUzMEVBXHU3OUQyXQoKIyAwOiBmaWxlIG5hbWUKY29tcGlsZXIubWlzYy52ZXJib3NlLndyb3RlLmZpbGU9W3swfVx1MzA5Mlx1NjZGOFx1OEZCQ1x1MzA3Rlx1NUI4Q1x1NEU4Nl0KCiMjIGV4dHJhIG91dHB1dCB3aGVuIHVzaW5nIC12ZXJib3NlIChjb2RlL0NsYXNzUmVhZGVyKQojIDA6IHN0cmluZwpjb21waWxlci5taXNjLnZlcmJvc2UubG9hZGluZz1bezB9XHUzMDkyXHU4QUFEXHU4RkJDXHUzMDdGXHU0RTJEXQoKIyAwOiBzdHJpbmcKY29tcGlsZXIubWlzYy52ZXJib3NlLnNvdXJjZXBhdGg9W1x1MzBCRFx1MzBGQ1x1MzBCOVx1MzBGQlx1MzBENVx1MzBBMVx1MzBBNFx1MzBFQlx1MzA2RVx1NjkxQ1x1N0QyMlx1MzBEMVx1MzBCOTogezB9XQoKIyAwOiBzdHJpbmcKY29tcGlsZXIubWlzYy52ZXJib3NlLmNsYXNzcGF0aD1bXHUzMEFGXHUzMEU5XHUzMEI5XHUzMEZCXHUzMEQ1XHUzMEExXHUzMEE0XHUzMEVCXHUzMDZFXHU2OTFDXHU3RDIyXHUzMEQxXHUzMEI5OiB7MH1dCgojIyBleHRyYSBvdXRwdXQgd2hlbiB1c2luZyAtcHJvbXB0ICh1dGlsL0xvZykKY29tcGlsZXIubWlzYy5yZXN1bWUuYWJvcnQ9UilcdTUxOERcdTk1OEIsQSlcdTRFMkRcdTZCNjI+CgojIyMjIwoKIyMKIyMgd2FybmluZ3MKIyMKCiMjIEFsbCB3YXJuaW5nIG1lc3NhZ2VzIGFyZSBwcmVjZWRlZCBieSB0aGUgZm9sbG93aW5nIHN0cmluZy4KY29tcGlsZXIud2Fybi53YXJuaW5nPVx1OEI2Nlx1NTQ0QToKCiMjIFdhcm5pbmcgbWVzc2FnZXMgbWF5IGFsc28gaW5jbHVkZSB0aGUgZm9sbG93aW5nIHByZWZpeCB0byBpZGVudGlmeSBhCiMjIGxpbnQgb3B0aW9uCiMgMDogb3B0aW9uIG5hbWUKY29tcGlsZXIud2Fybi5saW50T3B0aW9uPVt7MH1dIAoKIyAwOiBzeW1ib2wKY29tcGlsZXIud2Fybi5jb25zdGFudC5TVlVJRD1zZXJpYWxWZXJzaW9uVUlEXHUzMDZGXHUzMEFGXHUzMEU5XHUzMEI5ezB9XHUzMDZFXHU1QjlBXHU2NTcwXHUzMDY3XHUzMDQyXHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5CgojIDA6IGZpbGUgbmFtZQpjb21waWxlci53YXJuLmRpci5wYXRoLmVsZW1lbnQubm90LmZvdW5kPVx1NEUwRFx1NkI2M1x1MzA2QVx1MzBEMVx1MzBCOVx1ODk4MVx1N0QyMCJ7MH0iOiBcdTMwNURcdTMwNkVcdTMwQzdcdTMwQTNcdTMwRUNcdTMwQUZcdTMwQzhcdTMwRUFcdTMwNkZcdTVCNThcdTU3MjhcdTMwNTdcdTMwN0VcdTMwNUJcdTMwOTMKCiMgMDogZmlsZSBuYW1lCmNvbXBpbGVyLndhcm4uZGlyLnBhdGguZWxlbWVudC5ub3QuZGlyZWN0b3J5PVx1NEUwRFx1NkI2M1x1MzA2QVx1MzBEMVx1MzBCOVx1ODk4MVx1N0QyMCJ7MH0iOiBcdTMwQzdcdTMwQTNcdTMwRUNcdTMwQUZcdTMwQzhcdTMwRUFcdTMwNkZcdTVCNThcdTU3MjhcdTMwNTdcdTMwN0VcdTMwNUJcdTMwOTMKCmNvbXBpbGVyLndhcm4uZmluYWxseS5jYW5ub3QuY29tcGxldGU9ZmluYWxseVx1N0JDMFx1MzA0Q1x1NkI2M1x1NUUzOFx1MzA2Qlx1NUI4Q1x1NEU4Nlx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5MwoKIyAwOiBuYW1lCmNvbXBpbGVyLndhcm4ucG9vci5jaG9pY2UuZm9yLm1vZHVsZS5uYW1lPVx1MzBFMlx1MzBCOFx1MzBFNVx1MzBGQ1x1MzBFQlx1NTQwRHswfVx1MzA2RVx1NjcyQlx1NUMzRVx1MzA2Rlx1NjU3MFx1NUI1N1x1MzA2Qlx1MzA1N1x1MzA2QVx1MzA0NFx1MzA2N1x1MzA0Rlx1MzA2MFx1MzA1NVx1MzA0NAoKIyAwOiBzeW1ib2wsIDE6IHN5bWJvbApjb21waWxlci53YXJuLmhhcy5iZWVuLmRlcHJlY2F0ZWQ9ezF9XHUzMDZFezB9XHUzMDZGXHU2M0E4XHU1OTY4XHUzMDU1XHUzMDhDXHUzMDdFXHUzMDVCXHUzMDkzCgojIDA6IHN5bWJvbCwgMTogc3ltYm9sCmNvbXBpbGVyLndhcm4uaGFzLmJlZW4uZGVwcmVjYXRlZC5mb3IucmVtb3ZhbD17MX1cdTMwNkV7MH1cdTMwNkZcdTYzQThcdTU5NjhcdTMwNTVcdTMwOENcdTMwNjZcdTMwNEFcdTMwODlcdTMwNUFcdTMwMDFcdTUyNEFcdTk2NjRcdTc1MjhcdTMwNkJcdTMwREVcdTMwRkNcdTMwQUZcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNTkKCiMgMDogc3ltYm9sCmNvbXBpbGVyLndhcm4uaGFzLmJlZW4uZGVwcmVjYXRlZC5tb2R1bGU9XHUzMEUyXHUzMEI4XHUzMEU1XHUzMEZDXHUzMEVCezB9XHUzMDZGXHU2M0E4XHU1OTY4XHUzMDU1XHUzMDhDXHUzMDdFXHUzMDVCXHUzMDkzCgojIDA6IHN5bWJvbApjb21waWxlci53YXJuLmhhcy5iZWVuLmRlcHJlY2F0ZWQuZm9yLnJlbW92YWwubW9kdWxlPVx1MzBFMlx1MzBCOFx1MzBFNVx1MzBGQ1x1MzBFQnswfVx1MzA2Rlx1NjNBOFx1NTk2OFx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0QVx1MzA4OVx1MzA1QVx1MzAwMVx1NTI0QVx1OTY2NFx1NzUyOFx1MzA2Qlx1MzBERVx1MzBGQ1x1MzBBRlx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1OQoKIyAwOiBzeW1ib2wKY29tcGlsZXIud2Fybi5zdW4ucHJvcHJpZXRhcnk9ezB9XHUzMDZGXHU1MTg1XHU5MEU4XHU2MjQwXHU2NzA5XHUzMDZFQVBJXHUzMDY3XHUzMDQyXHUzMDhBXHUzMDAxXHU0RUNBXHU1RjhDXHUzMDZFXHUzMEVBXHUzMEVBXHUzMEZDXHUzMEI5XHUzMDY3XHU1MjRBXHU5NjY0XHUzMDU1XHUzMDhDXHUzMDhCXHU1M0VGXHU4MEZEXHU2MDI3XHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5Cgpjb21waWxlci53YXJuLmlsbGVnYWwuY2hhci5mb3IuZW5jb2Rpbmc9XHUzMDUzXHUzMDZFXHU2NTg3XHU1QjU3XHUzMDZGXHUzMDAxXHUzMEE4XHUzMEYzXHUzMEIzXHUzMEZDXHUzMEM3XHUzMEEzXHUzMEYzXHUzMEIwezB9XHUzMDZCXHUzMERFXHUzMEMzXHUzMEQ3XHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzCgojIDA6IHN5bWJvbApjb21waWxlci53YXJuLmltcHJvcGVyLlNWVUlEPXNlcmlhbFZlcnNpb25VSURcdTMwNkZcdTMwMDFcdTMwQUZcdTMwRTlcdTMwQjl7MH1cdTMwNkJzdGF0aWMgZmluYWxcdTMwOTJcdTVCQTNcdThBMDBcdTMwNTlcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTkKCiMgMDogdHlwZSwgMTogdHlwZQpjb21waWxlci53YXJuLmluZXhhY3Qubm9uLXZhcmFyZ3MuY2FsbD1cdTY3MDBcdTdENDJcdTMwRDFcdTMwRTlcdTMwRTFcdTMwRkNcdTMwQkZcdTMwNkVcdTRFMERcdTZCNjNcdTc4QkFcdTMwNkFcdTVGMTVcdTY1NzBcdTU3OEJcdTMwOTJcdTYzMDFcdTMwNjNcdTMwNUZcdTUzRUZcdTU5MDlcdTVGMTVcdTY1NzBcdTMwRTFcdTMwQkRcdTMwQzNcdTMwQzlcdTMwNkVcdTk3NUVcdTUzRUZcdTU5MDlcdTVGMTVcdTY1NzBcdTU0N0NcdTUxRkFcdTMwNTdcdTMwMDJcblx1NTNFRlx1NTkwOVx1NUYxNVx1NjU3MFx1NTQ3Q1x1NTFGQVx1MzA1N1x1MzA2Qlx1OTVBMlx1MzA1N1x1MzA2Nlx1MzA2RnswfVx1MzA2Qlx1MzBBRFx1MzBFM1x1MzBCOVx1MzBDOFx1MzA1N1x1MzA3RVx1MzA1OVx1MzAwMlxuXHU5NzVFXHU1M0VGXHU1OTA5XHU1RjE1XHU2NTcwXHU1NDdDXHU1MUZBXHUzMDU3XHUzMDZCXHU5NUEyXHUzMDU3XHUzMDY2XHUzMDZGezF9XHUzMDZCXHUzMEFEXHUzMEUzXHUzMEI5XHUzMEM4XHUzMDU3XHUzMDY2XHUzMDUzXHUzMDZFXHU4QjY2XHU1NDRBXHUzMDkyXHU1MUZBXHUzMDU1XHUzMDZBXHUzMDQ0XHUzMDg4XHUzMDQ2XHUzMDZCXHUzMDU3XHUzMDdFXHUzMDU5CgojIDA6IGxpc3Qgb2YgdHlwZQpjb21waWxlci53YXJuLnVucmVhY2hhYmxlLmNhdGNoPWNhdGNoXHU1M0U1XHUzMDZCXHU3OUZCXHUzMDU5XHUzMDUzXHUzMDY4XHUzMDRDXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzXG5cdTMwQjlcdTMwRURcdTMwRkNcdTMwNTVcdTMwOENcdTMwNUZcdTMwQkZcdTMwQTRcdTMwRDd7MH1cdTMwNkZcdTMwNTlcdTMwNjdcdTMwNkJcdTYzNTVcdTYzNDlcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNTkKCiMgMDogbGlzdCBvZiB0eXBlCmNvbXBpbGVyLndhcm4udW5yZWFjaGFibGUuY2F0Y2guMT1jYXRjaFx1NTNFNVx1MzA2Qlx1NzlGQlx1MzA1OVx1MzA1M1x1MzA2OFx1MzA0Q1x1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1xuXHUzMEI5XHUzMEVEXHUzMEZDXHUzMDU1XHUzMDhDXHUzMDVGXHUzMEJGXHUzMEE0XHUzMEQ3ezB9XHUzMDZGXHUzMDU5XHUzMDY3XHUzMDZCXHU2MzU1XHU2MzQ5XHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5CgojIDA6IHN5bWJvbApjb21waWxlci53YXJuLmxvbmcuU1ZVSUQ9c2VyaWFsVmVyc2lvblVJRFx1MzA2Rlx1MzAwMVx1MzBBRlx1MzBFOVx1MzBCOXswfVx1MzA2RWxvbmdcdTU3OEJcdTMwNjdcdTMwNDJcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTkKCiMgMDogc3ltYm9sCmNvbXBpbGVyLndhcm4ubWlzc2luZy5TVlVJRD1cdTc2RjRcdTUyMTdcdTUzMTZcdTUzRUZcdTgwRkRcdTMwNkFcdTMwQUZcdTMwRTlcdTMwQjl7MH1cdTMwNkJcdTMwNkZcdTMwMDFzZXJpYWxWZXJzaW9uVUlEXHUzMDRDXHU1QjlBXHU3RkE5XHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDVCXHUzMDkzCgojIDA6IHN5bWJvbCwgMTogc3ltYm9sLCAyOiBzeW1ib2wsIDM6IHN5bWJvbApjb21waWxlci53YXJuLnBvdGVudGlhbGx5LmFtYmlndW91cy5vdmVybG9hZD17MX1cdTUxODVcdTMwNkV7MH1cdTMwNkZ7M31cdTUxODVcdTMwNkV7Mn1cdTMwNjhcdTc3REJcdTc2RkVcdTMwNTlcdTMwOEJcdTUzRUZcdTgwRkRcdTYwMjdcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTkKCiMgMDogbWVzc2FnZSBzZWdtZW50CmNvbXBpbGVyLndhcm4ub3ZlcnJpZGUudmFyYXJncy5taXNzaW5nPXswfVx1MzAwMlx1MzBBQVx1MzBGQ1x1MzBEMFx1MzBGQ1x1MzBFOVx1MzBBNFx1MzBDOVx1MzA1NVx1MzA4Q1x1MzA1Rlx1MzBFMVx1MzBCRFx1MzBDM1x1MzBDOVx1MzA2Qlx1MzA2RicnLi4uJydcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTMKCiMgMDogbWVzc2FnZSBzZWdtZW50CmNvbXBpbGVyLndhcm4ub3ZlcnJpZGUudmFyYXJncy5leHRyYT17MH1cdTMwMDJcdTMwQUFcdTMwRkNcdTMwRDBcdTMwRkNcdTMwRTlcdTMwQTRcdTMwQzlcdTMwNTdcdTMwNjZcdTMwNDRcdTMwOEJcdTMwRTFcdTMwQkRcdTMwQzNcdTMwQzlcdTMwNkJcdTMwNkYnJy4uLicnXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzCgpjb21waWxlci53YXJuLm92ZXJyaWRlLmJyaWRnZT17MH1cdTMwMDJcdTMwQUFcdTMwRkNcdTMwRDBcdTMwRkNcdTMwRTlcdTMwQTRcdTMwQzlcdTMwNTVcdTMwOENcdTMwNUZcdTMwRTFcdTMwQkRcdTMwQzNcdTMwQzlcdTMwNkZcdTMwRDZcdTMwRUFcdTMwQzNcdTMwQjhcdTMwRkJcdTMwRTFcdTMwQkRcdTMwQzNcdTMwQzlcdTMwNjdcdTMwNTkKCiMgMDogc3ltYm9sCmNvbXBpbGVyLndhcm4ucGtnLWluZm8uYWxyZWFkeS5zZWVuPXBhY2thZ2UtaW5mby5qYXZhXHUzMEQ1XHUzMEExXHUzMEE0XHUzMEVCXHUzMDRDXHUzMDU5XHUzMDY3XHUzMDZCXHUzMEQxXHUzMEMzXHUzMEIxXHUzMEZDXHUzMEI4ezB9XHU3NTI4XHUzMDZCXHU4ODY4XHU3OTNBXHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5CgojIDA6IGZpbGUgbmFtZQpjb21waWxlci53YXJuLnBhdGguZWxlbWVudC5ub3QuZm91bmQ9XHU0RTBEXHU2QjYzXHUzMDZBXHUzMEQxXHUzMEI5XHU4OTgxXHU3RDIwInswfSI6IFx1MzA1RFx1MzA2RVx1MzBENVx1MzBBMVx1MzBBNFx1MzBFQlx1MzA3RVx1MzA1Rlx1MzA2Rlx1MzBDN1x1MzBBM1x1MzBFQ1x1MzBBRlx1MzBDOFx1MzBFQVx1MzA2Rlx1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5MwoKY29tcGlsZXIud2Fybi5wb3NzaWJsZS5mYWxsLXRocm91Z2guaW50by5jYXNlPWNhc2VcdTMwNkJmYWxsLXRocm91Z2hcdTMwNTlcdTMwOEJcdTUzRUZcdTgwRkRcdTYwMjdcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTkKCiMgMDogdHlwZQpjb21waWxlci53YXJuLnJlZHVuZGFudC5jYXN0PXswfVx1MzA3OFx1MzA2RVx1NTE5N1x1OTU3N1x1MzA2QVx1MzBBRFx1MzBFM1x1MzBCOVx1MzBDOFx1MzA2N1x1MzA1OQoKIyAwOiBudW1iZXIKY29tcGlsZXIud2Fybi5wb3NpdGlvbi5vdmVyZmxvdz1cdTRGNERcdTdGNkVcdTMwQThcdTMwRjNcdTMwQjNcdTMwRkNcdTMwQzdcdTMwQTNcdTMwRjNcdTMwQjBcdTMwNENcdTg4NEN7MH1cdTMwNjdcdTMwQUFcdTMwRkNcdTMwRDBcdTMwRkNcdTMwRDVcdTMwRURcdTMwRkNcdTMwNTdcdTMwN0VcdTMwNTkKCiMgMDogZmlsZSBuYW1lLCAxOiBudW1iZXIsIDI6IG51bWJlcgpjb21waWxlci53YXJuLmJpZy5tYWpvci52ZXJzaW9uPXswfTogXHUzMEUxXHUzMEI4XHUzMEUzXHUzMEZDXHUzMEZCXHUzMEQwXHUzMEZDXHUzMEI4XHUzMEU3XHUzMEYzezF9XHUzMDZGXHUzMDAxXHUzMDUzXHUzMDZFXHUzMEIzXHUzMEYzXHUzMEQxXHUzMEE0XHUzMEU5XHUzMDY3XHUzMEI1XHUzMEREXHUzMEZDXHUzMEM4XHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDhCXHU2NzAwXHU2NUIwXHUzMDZFXHUzMEUxXHUzMEI4XHUzMEUzXHUzMEZDXHUzMEZCXHUzMEQwXHUzMEZDXHUzMEI4XHUzMEU3XHUzMEYzezJ9XHUzMDg4XHUzMDhBXHU2NUIwXHUzMDU3XHUzMDQ0XHUzMDY3XHUzMDU5XHUzMDAyXG5cdTMwQjNcdTMwRjNcdTMwRDFcdTMwQTRcdTMwRTlcdTMwNkVcdTMwQTJcdTMwQzNcdTMwRDdcdTMwQjBcdTMwRUNcdTMwRkNcdTMwQzlcdTMwOTJcdTMwNEFcdTg1QTZcdTMwODFcdTMwNTdcdTMwN0VcdTMwNTlcdTMwMDIKCiMgMDogc3ltYm9sIGtpbmQsIDE6IHN5bWJvbApjb21waWxlci53YXJuLnN0YXRpYy5ub3QucXVhbGlmaWVkLmJ5LnR5cGU9c3RhdGljIHswfVx1MzA2Rlx1NUYwRlx1MzA2N1x1MzA2Rlx1MzA2QVx1MzA0Rlx1NTc4Qlx1NTQwRHsxfVx1MzA2N1x1NEZFRVx1OThGRVx1MzA1OVx1MzA4Qlx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OQoKIyAwOiBzdHJpbmcKY29tcGlsZXIud2Fybi5zb3VyY2Uubm8uYm9vdGNsYXNzcGF0aD1cdTMwRDZcdTMwRkNcdTMwQzhcdTMwQjlcdTMwQzhcdTMwRTlcdTMwQzNcdTMwRDdcdTMwRkJcdTMwQUZcdTMwRTlcdTMwQjlcdTMwRDFcdTMwQjlcdTMwNEMtc291cmNlIHswfVx1MzA2OFx1NEUwMFx1N0REMlx1MzA2Qlx1OEEyRFx1NUI5QVx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1Qlx1MzA5MwoKIyAwOiBzdHJpbmcKY29tcGlsZXIud2Fybi5vcHRpb24ub2Jzb2xldGUuc291cmNlPVx1MzBCRFx1MzBGQ1x1MzBCOVx1NTAyNHswfVx1MzA2Rlx1NUVDM1x1NkI2Mlx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA2Nlx1MzAwMVx1NEVDQVx1NUY4Q1x1MzA2RVx1MzBFQVx1MzBFQVx1MzBGQ1x1MzBCOVx1MzA2N1x1NTI0QVx1OTY2NFx1MzA1NVx1MzA4Q1x1MzA4Qlx1NEU4OFx1NUI5QVx1MzA2N1x1MzA1OQoKIyAwOiBzdHJpbmcKY29tcGlsZXIud2Fybi5vcHRpb24ub2Jzb2xldGUudGFyZ2V0PVx1MzBCRlx1MzBGQ1x1MzBCMlx1MzBDM1x1MzBDOFx1NTAyNHswfVx1MzA2Rlx1NUVDM1x1NkI2Mlx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA2Nlx1MzAwMVx1NEVDQVx1NUY4Q1x1MzA2RVx1MzBFQVx1MzBFQVx1MzBGQ1x1MzBCOVx1MzA2N1x1NTI0QVx1OTY2NFx1MzA1NVx1MzA4Q1x1MzA4Qlx1NEU4OFx1NUI5QVx1MzA2N1x1MzA1OQoKIyAwOiBzdHJpbmcsIDE6IHN0cmluZwpjb21waWxlci5lcnIub3B0aW9uLnJlbW92ZWQuc291cmNlPVx1MzBCRFx1MzBGQ1x1MzBCOVx1MzBGQlx1MzBBQVx1MzBEN1x1MzBCN1x1MzBFN1x1MzBGM3swfVx1MzA2Rlx1NzNGRVx1NTcyOFx1MzBCNVx1MzBERFx1MzBGQ1x1MzBDOFx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMnsxfVx1NEVFNVx1OTY0RFx1MzA5Mlx1NEY3Rlx1NzUyOFx1MzA1N1x1MzA2Nlx1MzA0Rlx1MzA2MFx1MzA1NVx1MzA0NFx1MzAwMgoKIyAwOiBzdHJpbmcsIDE6IHN0cmluZwpjb21waWxlci5lcnIub3B0aW9uLnJlbW92ZWQudGFyZ2V0PVx1MzBCRlx1MzBGQ1x1MzBCMlx1MzBDM1x1MzBDOFx1MzBGQlx1MzBBQVx1MzBEN1x1MzBCN1x1MzBFN1x1MzBGM3swfVx1MzA2Rlx1NzNGRVx1NTcyOFx1MzBCNVx1MzBERFx1MzBGQ1x1MzBDOFx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMnsxfVx1NEVFNVx1OTY0RFx1MzA5Mlx1NEY3Rlx1NzUyOFx1MzA1N1x1MzA2Nlx1MzA0Rlx1MzA2MFx1MzA1NVx1MzA0NFx1MzAwMgoKY29tcGlsZXIud2Fybi5vcHRpb24ub2Jzb2xldGUuc3VwcHJlc3Npb249XHU1RUMzXHU2QjYyXHUzMDU1XHUzMDhDXHUzMDVGXHUzMEFBXHUzMEQ3XHUzMEI3XHUzMEU3XHUzMEYzXHUzMDZCXHUzMDY0XHUzMDQ0XHUzMDY2XHUzMDZFXHU4QjY2XHU1NDRBXHUzMDkyXHU4ODY4XHU3OTNBXHUzMDU3XHUzMDZBXHUzMDQ0XHUzMDg4XHUzMDQ2XHUzMDZCXHUzMDU5XHUzMDhCXHUzMDZCXHUzMDZGXHUzMDAxLVhsaW50Olx1MzBBQVx1MzBEN1x1MzBCN1x1MzBFN1x1MzBGM1x1MzA5Mlx1NEY3Rlx1NzUyOFx1MzA1N1x1MzA3RVx1MzA1OVx1MzAwMgoKIyAwOiBuYW1lLCAxOiBudW1iZXIsIDI6IG51bWJlciwgMzogbnVtYmVyLCA0OiBudW1iZXIKY29tcGlsZXIud2Fybi5mdXR1cmUuYXR0cj1cdTMwRDBcdTMwRkNcdTMwQjhcdTMwRTdcdTMwRjN7MX0uezJ9XHUzMDZFXHUzMEFGXHUzMEU5XHUzMEI5XHUzMEZCXHUzMEQ1XHUzMEExXHUzMEE0XHUzMEVCXHUzMDY3XHU1QzBFXHU1MTY1XHUzMDU1XHUzMDhDXHUzMDVGezB9XHU1QzVFXHU2MDI3XHUzMDZGXHUzMDAxXHUzMEQwXHUzMEZDXHUzMEI4XHUzMEU3XHUzMEYzezN9Lns0fVx1MzA2RVx1MzBBRlx1MzBFOVx1MzBCOVx1MzBGQlx1MzBENVx1MzBBMVx1MzBBNFx1MzBFQlx1MzA2N1x1MzA2Rlx1NzEyMVx1ODk5Nlx1MzA1NVx1MzA4Q1x1MzA3RVx1MzA1OQoKIyBXYXJuaW5ncyByZWxhdGVkIHRvIGFubm90YXRpb24gcHJvY2Vzc2luZwojIDA6IHN0cmluZwpjb21waWxlci53YXJuLnByb2MucGFja2FnZS5kb2VzLm5vdC5leGlzdD1cdTMwRDFcdTMwQzNcdTMwQjFcdTMwRkNcdTMwQjh7MH1cdTMwNkZcdTVCNThcdTU3MjhcdTMwNTdcdTMwN0VcdTMwNUJcdTMwOTMKCiMgMDogbmFtZQpjb21waWxlci53YXJuLnByb2MuZmlsZS5yZW9wZW5pbmc9Jyd7MH0nJ1x1NzUyOFx1MzA2RVx1MzBENVx1MzBBMVx1MzBBNFx1MzBFQlx1MzA5Mlx1ODkwN1x1NjU3MFx1NTZERVx1NEY1Q1x1NjIxMFx1MzA1N1x1MzA4OFx1MzA0Nlx1MzA2OFx1MzA1N1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1OQoKIyAwOiBuYW1lCmNvbXBpbGVyLndhcm4ucHJvYy50eXBlLmFscmVhZHkuZXhpc3RzPVx1MzBCRlx1MzBBNFx1MzBENycnezB9JydcdTMwNkVcdTMwRDVcdTMwQTFcdTMwQTRcdTMwRUJcdTMwNkZcdTMwNTlcdTMwNjdcdTMwNkJcdTMwQkRcdTMwRkNcdTMwQjlcdTMwRkJcdTMwRDFcdTMwQjlcdTMwN0VcdTMwNUZcdTMwNkZcdTMwQUZcdTMwRTlcdTMwQjlcdTMwRDFcdTMwQjlcdTMwNkJcdTVCNThcdTU3MjhcdTMwNTdcdTMwN0VcdTMwNTkKCiMgMDogbmFtZQpjb21waWxlci53YXJuLnByb2MudHlwZS5yZWNyZWF0ZT1cdTMwQkZcdTMwQTRcdTMwRDcnJ3swfScnXHUzMDZFXHUzMEQ1XHUzMEExXHUzMEE0XHUzMEVCXHUzMDkyXHU4OTA3XHU2NTcwXHU1NkRFXHU0RjVDXHU2MjEwXHUzMDU3XHUzMDg4XHUzMDQ2XHUzMDY4XHUzMDU3XHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5CgojIDA6IHN0cmluZwpjb21waWxlci53YXJuLnByb2MuaWxsZWdhbC5maWxlLm5hbWU9XHU3MTIxXHU1MkI5XHUzMDZBXHU1NDBEXHU1MjREJyd7MH0nJ1x1MzA2RVx1MzBENVx1MzBBMVx1MzBBNFx1MzBFQlx1MzA2Rlx1NEY1Q1x1NjIxMFx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMgoKIyAwOiBzdHJpbmcsIDE6IHN0cmluZwpjb21waWxlci53YXJuLnByb2Muc3VzcGljaW91cy5jbGFzcy5uYW1lPVx1NTQwRFx1NTI0RFx1MzA0Q3sxfVx1MzA2N1x1N0Q0Mlx1MzA4Rlx1MzA4Qlx1NTc4Qlx1MzA2RVx1MzBENVx1MzBBMVx1MzBBNFx1MzBFQlx1MzA5Mlx1NEY1Q1x1NjIxMFx1MzA1N1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1OTogJyd7MH0nJwoKIyAwOiBuYW1lCmNvbXBpbGVyLndhcm4ucHJvYy5maWxlLmNyZWF0ZS5sYXN0LnJvdW5kPVx1NjcwMFx1NUY4Q1x1MzA2Qlx1NEY1Q1x1NjIxMFx1MzA1NVx1MzA4Q1x1MzA1Rlx1MzBCRlx1MzBBNFx1MzBENycnezB9JydcdTMwNkVcdTMwRDVcdTMwQTFcdTMwQTRcdTMwRUJcdTMwNkZcdTZDRThcdTkxQzhcdTUxRTZcdTc0MDZcdTMwNkJcdTZFMjFcdTMwNTVcdTMwOENcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKCiMgMDogc3RyaW5nLCAxOiBzdHJpbmcKY29tcGlsZXIud2Fybi5wcm9jLm1hbGZvcm1lZC5zdXBwb3J0ZWQuc3RyaW5nPVx1MzBEN1x1MzBFRFx1MzBCQlx1MzBDM1x1MzBCNScnezF9JydcdTMwNENcdThGRDRcdTMwNTdcdTMwNUZcdTMwQjVcdTMwRERcdTMwRkNcdTMwQzhcdTMwNTVcdTMwOENcdTMwOEJcdTZDRThcdTkxQzhcdTU3OEJcdTMwNkVcdTY1ODdcdTVCNTdcdTUyMTcnJ3swfScnXHUzMDRDXHU0RTBEXHU2QjYzXHUzMDY3XHUzMDU5CgojIDA6IHNldCBvZiBzdHJpbmcKY29tcGlsZXIud2Fybi5wcm9jLmFubm90YXRpb25zLndpdGhvdXQucHJvY2Vzc29ycz1cdTMwNTNcdTMwOENcdTMwODlcdTMwNkVcdTZDRThcdTkxQzhcdTMwOTJcdTg5ODFcdTZDNDJcdTMwNTlcdTMwOEJcdTMwRDdcdTMwRURcdTMwQkJcdTMwQzNcdTMwQjVcdTMwNkZcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTNcdTMwNjdcdTMwNTdcdTMwNUY6IHswfQoKIyAwOiBzb3VyY2UgdmVyc2lvbiwgMTogc3RyaW5nLCAyOiBzdHJpbmcKY29tcGlsZXIud2Fybi5wcm9jLnByb2Nlc3Nvci5pbmNvbXBhdGlibGUuc291cmNlLnZlcnNpb249XHU2Q0U4XHU5MUM4XHUzMEQ3XHUzMEVEXHUzMEJCXHUzMEMzXHUzMEI1Jyd7MX0nJ1x1MzA0Qlx1MzA4OS1zb3VyY2UgJyd7Mn0nJ1x1MzA4OFx1MzA4QVx1NUMwRlx1MzA1NVx1MzA0NFx1MzBCRFx1MzBGQ1x1MzBCOVx1MzBGQlx1MzBEMFx1MzBGQ1x1MzBCOFx1MzBFN1x1MzBGMycnezB9JydcdTMwNENcdTMwQjVcdTMwRERcdTMwRkNcdTMwQzhcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNTkKCmNvbXBpbGVyLndhcm4ucHJvYy5wcm9jLW9ubHkucmVxdWVzdGVkLm5vLnByb2NzPVx1MzBCM1x1MzBGM1x1MzBEMVx1MzBBNFx1MzBFQlx1MzA2QVx1MzA1N1x1MzA2RVx1NkNFOFx1OTFDOFx1NTFFNlx1NzQwNlx1MzA0Q1x1MzBFQVx1MzBBRlx1MzBBOFx1MzBCOVx1MzBDOFx1MzA1NVx1MzA4Q1x1MzA3RVx1MzA1N1x1MzA1Rlx1MzA0Q1x1MzAwMVx1MzBEN1x1MzBFRFx1MzBCQlx1MzBDM1x1MzBCNVx1MzA0Q1x1ODk4Qlx1MzA2NFx1MzA0Qlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5M1x1MzA2N1x1MzA1N1x1MzA1Rlx1MzAwMgoKY29tcGlsZXIud2Fybi5wcm9jLnVzZS5pbXBsaWNpdD1cdTY2OTdcdTlFRDlcdTc2ODRcdTMwNkJcdTMwQjNcdTMwRjNcdTMwRDFcdTMwQTRcdTMwRUJcdTMwNTVcdTMwOENcdTMwNUZcdTMwRDVcdTMwQTFcdTMwQTRcdTMwRUJcdTMwNkZcdTZDRThcdTkxQzhcdTUxRTZcdTc0MDZcdTMwNkJcdTZFMjFcdTMwNTVcdTMwOENcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDJcbi1pbXBsaWNpdFx1MzA5Mlx1NEY3Rlx1NzUyOFx1MzA1N1x1NjY5N1x1OUVEOVx1NzY4NFx1MzBCM1x1MzBGM1x1MzBEMVx1MzBBNFx1MzBFQlx1MzA2RVx1MzBERFx1MzBFQVx1MzBCN1x1MzBGQ1x1MzA5Mlx1NjMwN1x1NUI5QVx1MzA1N1x1MzA2Nlx1MzA0Rlx1MzA2MFx1MzA1NVx1MzA0NFx1MzAwMgoKY29tcGlsZXIud2Fybi5wcm9jLnVzZS5wcm9jLm9yLmltcGxpY2l0PVx1NjY5N1x1OUVEOVx1NzY4NFx1MzA2Qlx1MzBCM1x1MzBGM1x1MzBEMVx1MzBBNFx1MzBFQlx1MzA1NVx1MzA4Q1x1MzA1Rlx1MzBENVx1MzBBMVx1MzBBNFx1MzBFQlx1MzA2Rlx1NkNFOFx1OTFDOFx1NTFFNlx1NzQwNlx1MzA2Qlx1NkUyMVx1MzA1NVx1MzA4Q1x1MzA3RVx1MzA1Qlx1MzA5M1x1MzAwMlxuLXByb2M6bm9uZVx1MzA5Mlx1NEY3Rlx1NzUyOFx1MzA1N1x1NkNFOFx1OTFDOFx1NTFFNlx1NzQwNlx1MzA5Mlx1NzEyMVx1NTJCOVx1MzA2Qlx1MzA1OVx1MzA4Qlx1MzA0QiAtaW1wbGljaXRcdTMwOTJcdTRGN0ZcdTc1MjhcdTMwNTdcdTY2OTdcdTlFRDlcdTc2ODRcdTMwQjNcdTMwRjNcdTMwRDFcdTMwQTRcdTMwRUJcdTMwNkVcdTMwRERcdTMwRUFcdTMwQjdcdTMwRkNcdTMwOTJcdTYzMDdcdTVCOUFcdTMwNTdcdTMwNjZcdTMwNEZcdTMwNjBcdTMwNTVcdTMwNDRcdTMwMDIKCiMgUHJpbnQgYSBjbGllbnQtZ2VuZXJhdGVkIHdhcm5pbmc7IGFzc3VtZWQgdG8gYmUgbG9jYWxpemVkLCBubyB0cmFuc2xhdGlvbiByZXF1aXJlZAojIDA6IHN0cmluZwpjb21waWxlci53YXJuLnByb2MubWVzc2FnZXI9ezB9CgojIDA6IHNldCBvZiBuYW1lCmNvbXBpbGVyLndhcm4ucHJvYy51bmNsb3NlZC50eXBlLmZpbGVzPVx1MzBCRlx1MzBBNFx1MzBENycnezB9JydcdTMwNkVcdTMwRDVcdTMwQTFcdTMwQTRcdTMwRUJcdTMwNENcdTk1ODlcdTMwNThcdTMwODlcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDJcdTMwNTNcdTMwOENcdTMwODlcdTMwNkVcdTMwQkZcdTMwQTRcdTMwRDdcdTMwNkZcdTZDRThcdTkxQzhcdTUxRTZcdTc0MDZcdTMwNTVcdTMwOENcdTMwN0VcdTMwNUJcdTMwOTMKCiMgMDogc3RyaW5nCmNvbXBpbGVyLndhcm4ucHJvYy51bm1hdGNoZWQucHJvY2Vzc29yLm9wdGlvbnM9XHU2QjIxXHUzMDZFXHUzMEFBXHUzMEQ3XHUzMEI3XHUzMEU3XHUzMEYzXHUzMDZGXHUzMDY5XHUzMDZFXHUzMEQ3XHUzMEVEXHUzMEJCXHUzMEMzXHUzMEI1XHUzMDY3XHUzMDgyXHU4QThEXHU4QjU4XHUzMDU1XHUzMDhDXHUzMDdFXHUzMDVCXHUzMDkzXHUzMDY3XHUzMDU3XHUzMDVGOiAnJ3swfScnCgpjb21waWxlci53YXJuLnRyeS5leHBsaWNpdC5jbG9zZS5jYWxsPVx1ODFFQVx1NTJENVx1MzBBRlx1MzBFRFx1MzBGQ1x1MzBCQVx1NTNFRlx1ODBGRFx1MzA2QVx1MzBFQVx1MzBCRFx1MzBGQ1x1MzBCOVx1MzA2Qlx1MzA0QVx1MzA1MVx1MzA4QmNsb3NlKClcdTMwNkVcdTY2MEVcdTc5M0FcdTc2ODRcdTU0N0NcdTUxRkFcdTMwNTcKCiMgMDogc3ltYm9sCmNvbXBpbGVyLndhcm4udHJ5LnJlc291cmNlLm5vdC5yZWZlcmVuY2VkPVx1ODFFQVx1NTJENVx1MzBBRlx1MzBFRFx1MzBGQ1x1MzBCQVx1NTNFRlx1ODBGRFx1MzA2QVx1MzBFQVx1MzBCRFx1MzBGQ1x1MzBCOXswfVx1MzA2Rlx1NUJGRVx1NUZEQ1x1MzA1OVx1MzA4QnRyeVx1NjU4N1x1MzA2RVx1NjcyQ1x1NEY1M1x1MzA2N1x1MzA2Rlx1NTNDMlx1NzE2N1x1MzA1NVx1MzA4Q1x1MzA3RVx1MzA1Qlx1MzA5MwoKIyAwOiB0eXBlCmNvbXBpbGVyLndhcm4udHJ5LnJlc291cmNlLnRocm93cy5pbnRlcnJ1cHRlZC5leGM9XHU4MUVBXHU1MkQ1XHUzMEFGXHUzMEVEXHUzMEZDXHUzMEJBXHU1M0VGXHU4MEZEXHUzMDZBXHUzMEVBXHUzMEJEXHUzMEZDXHUzMEI5ezB9XHUzMDZCXHUzMDAxSW50ZXJydXB0ZWRFeGNlcHRpb25cdTMwOTJcdTMwQjlcdTMwRURcdTMwRkNcdTMwNTlcdTMwOEJcdTUzRUZcdTgwRkRcdTYwMjdcdTMwNENcdTMwNDJcdTMwOEJcdTMwRTFcdTMwRjNcdTMwRDBcdTMwRkNcdTMwRkJcdTMwRTFcdTMwQkRcdTMwQzNcdTMwQzljbG9zZSgpXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5Cgpjb21waWxlci53YXJuLnVuY2hlY2tlZC5hc3NpZ249ezB9XHUzMDRCXHUzMDg5ezF9XHUzMDc4XHUzMDZFXHU3MTIxXHU2OTFDXHU2N0ZCXHU0RUUzXHU1MTY1XHUzMDY3XHUzMDU5CgojIDA6IHN5bWJvbCwgMTogdHlwZQpjb21waWxlci53YXJuLnVuY2hlY2tlZC5hc3NpZ24udG8udmFyPXJhd1x1NTc4QnsxfVx1MzA2RVx1MzBFMVx1MzBGM1x1MzBEMFx1MzBGQ1x1MzA2OFx1MzA1N1x1MzA2Nlx1NTkwOVx1NjU3MHswfVx1MzA3OFx1MzA2RVx1NzEyMVx1NjkxQ1x1NjdGQlx1NEVFM1x1NTE2NVx1MzA2N1x1MzA1OQoKIyAwOiBzeW1ib2wsIDE6IHR5cGUKY29tcGlsZXIud2Fybi51bmNoZWNrZWQuY2FsbC5tYnIub2YucmF3LnR5cGU9cmF3XHU1NzhCezF9XHUzMDZFXHUzMEUxXHUzMEYzXHUzMEQwXHUzMEZDXHUzMDY4XHUzMDU3XHUzMDY2XHUzMDZFezB9XHUzMDc4XHUzMDZFXHU3MTIxXHU2OTFDXHU2N0ZCXHU1NDdDXHU1MUZBXHUzMDU3XHUzMDY3XHUzMDU5Cgpjb21waWxlci53YXJuLnVuY2hlY2tlZC5jYXN0LnRvLnR5cGU9XHU1NzhCezB9XHUzMDc4XHUzMDZFXHU3MTIxXHU2OTFDXHU2N0ZCXHUzMEFEXHUzMEUzXHUzMEI5XHUzMEM4XHUzMDY3XHUzMDU5CgojIDA6IHN5bWJvbCBraW5kLCAxOiBuYW1lLCAyOiBsaXN0IG9mIHR5cGUsIDM6IGxpc3Qgb2YgdHlwZSwgNDogc3ltYm9sIGtpbmQsIDU6IHN5bWJvbApjb21waWxlci53YXJuLnVuY2hlY2tlZC5tZXRoLmludm9jYXRpb24uYXBwbGllZD1cdTcxMjFcdTY5MUNcdTY3RkJcdTMwRTFcdTMwQkRcdTMwQzNcdTMwQzlcdTU0N0NcdTUxRkFcdTMwNTc6IHs0fSB7NX1cdTMwNkV7MH0gezF9XHUzMDZGXHU2MzA3XHU1QjlBXHUzMDU1XHUzMDhDXHUzMDVGXHU1NzhCXHUzMDZCXHU5MDY5XHU3NTI4XHUzMDU1XHUzMDhDXHUzMDdFXHUzMDU5XG5cdTY3MUZcdTVGODVcdTUwMjQ6IHsyfVxuXHU2OTFDXHU1MUZBXHU1MDI0OiB7M30KCiMgMDogdHlwZQpjb21waWxlci53YXJuLnVuY2hlY2tlZC5nZW5lcmljLmFycmF5LmNyZWF0aW9uPVx1NTc4QnswfVx1MzA2RVx1NTNFRlx1NTkwOVx1NUYxNVx1NjU3MFx1MzBEMVx1MzBFOVx1MzBFMVx1MzBGQ1x1MzBCRlx1MzA2Qlx1NUJGRVx1MzA1OVx1MzA4Qlx1N0RDRlx1NzlGMFx1NTc4Qlx1OTE0RFx1NTIxN1x1MzA2RVx1NzEyMVx1NjkxQ1x1NjdGQlx1NEY1Q1x1NjIxMFx1MzA2N1x1MzA1OQoKIyAwOiB0eXBlCmNvbXBpbGVyLndhcm4udW5jaGVja2VkLnZhcmFyZ3Mubm9uLnJlaWZpYWJsZS50eXBlPVx1MzBEMVx1MzBFOVx1MzBFMVx1MzBGQ1x1MzBCRlx1NTMxNlx1MzA1NVx1MzA4Q1x1MzA1Rlx1NTNFRlx1NTkwOVx1NUYxNVx1NjU3MFx1NTc4QnswfVx1MzA0Qlx1MzA4OVx1MzA2RVx1MzBEMlx1MzBGQ1x1MzBEN1x1NkM1QVx1NjdEM1x1MzA2RVx1NTNFRlx1ODBGRFx1NjAyN1x1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OQoKIyAwOiBzeW1ib2wKY29tcGlsZXIud2Fybi52YXJhcmdzLnVuc2FmZS51c2UudmFyYXJncy5wYXJhbT1cdTUzRUZcdTU5MDlcdTVGMTVcdTY1NzBcdTMwRTFcdTMwQkRcdTMwQzNcdTMwQzlcdTMwNkZcdTMwMDFcdTU3OEJcdTYwQzVcdTU4MzFcdTRGRERcdTYzMDFcdTUzRUZcdTgwRkRcdTMwNjdcdTMwNkFcdTMwNDRcdTUzRUZcdTU5MDlcdTVGMTVcdTY1NzBcdTMwRDFcdTMwRTlcdTMwRTFcdTMwRkNcdTMwQkZ7MH1cdTMwNEJcdTMwODlcdTMwNkVcdTMwRDJcdTMwRkNcdTMwRDdcdTZDNUFcdTY3RDNcdTMwNkVcdTUzOUZcdTU2RTBcdTMwNjhcdTMwNkFcdTMwOEJcdTUzRUZcdTgwRkRcdTYwMjdcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTkKCmNvbXBpbGVyLndhcm4ubWlzc2luZy5kZXByZWNhdGVkLmFubm90YXRpb249XHU2M0E4XHU1OTY4XHUzMDU1XHUzMDhDXHUzMDZBXHUzMDQ0XHU5ODA1XHU3NkVFXHUzMDZGQERlcHJlY2F0ZWRcdTMwNjdcdTZDRThcdTkxQzhcdTMwNENcdTRFRDhcdTMwNTFcdTMwODlcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNUJcdTMwOTMKCiMgMDogc3ltYm9sIGtpbmQKY29tcGlsZXIud2Fybi5kZXByZWNhdGVkLmFubm90YXRpb24uaGFzLm5vLmVmZmVjdD1ARGVwcmVjYXRlZFx1NkNFOFx1OTFDOFx1MzA2Rlx1MzAwMVx1MzA1M1x1MzA2RXswfVx1NUJBM1x1OEEwMFx1MzA2Qlx1MzA2Rlx1NUY3MVx1OTdGRlx1MzA1N1x1MzA3RVx1MzA1Qlx1MzA5MwoKY29tcGlsZXIud2Fybi5pbnZhbGlkLnBhdGg9XHUzMEQ1XHUzMEExXHUzMEE0XHUzMEVCXHU1NDBEXHUzMDRDXHU3MTIxXHU1MkI5XHUzMDY3XHUzMDU5OiB7MH0KCmNvbXBpbGVyLndhcm4uaW52YWxpZC5hcmNoaXZlLmZpbGU9XHUzMEQxXHUzMEI5XHU0RTBBXHUzMDZFXHU0RTg4XHU2NzFGXHUzMDU3XHUzMDZBXHUzMDQ0XHUzMEQ1XHUzMEExXHUzMEE0XHUzMEVCOiB7MH0KCmNvbXBpbGVyLndhcm4udW5leHBlY3RlZC5hcmNoaXZlLmZpbGU9XHUzMEEyXHUzMEZDXHUzMEFCXHUzMEE0XHUzMEQ2XHUzMEZCXHUzMEQ1XHUzMEExXHUzMEE0XHUzMEVCXHUzMDZFXHU0RTg4XHU2NzFGXHUzMDU3XHUzMDZBXHUzMDQ0XHU2MkUxXHU1RjM1XHU1QjUwOiB7MH0KCiMgMDogcGF0aApjb21waWxlci5lcnIubm8uemlwZnMuZm9yLmFyY2hpdmU9XHUzMDUzXHUzMDZFXHUzMEQ1XHUzMEExXHUzMEE0XHUzMEVCXHUzMDZFXHU1MUU2XHU3NDA2XHUzMDZCXHU0RjdGXHU3NTI4XHUzMDY3XHUzMDREXHUzMDhCXHUzMEQ1XHUzMEExXHUzMEE0XHUzMEVCXHUzMEZCXHUzMEI3XHUzMEI5XHUzMEM2XHUzMEUwXHUzMEZCXHUzMEQ3XHUzMEVEXHUzMEQwXHUzMEE0XHUzMEMwXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzOiB7MH0KCmNvbXBpbGVyLndhcm4uZGl2Lnplcm89XHUzMEJDXHUzMEVEXHUzMDY3XHU5NjY0XHU3Qjk3Cgpjb21waWxlci53YXJuLmVtcHR5LmlmPWlmXHU0RUU1XHU5NjREXHUzMDRDXHU3QTdBXHUzMDZFXHU2NTg3XHUzMDY3XHUzMDU5Cgpjb21waWxlci53YXJuLmFubm90YXRpb24ubWV0aG9kLm5vdC5mb3VuZD1cdTMwQkZcdTMwQTRcdTMwRDcnJ3swfScnXHU1MTg1XHUzMDZCXHU2Q0U4XHU5MUM4XHUzMEUxXHUzMEJEXHUzMEMzXHUzMEM5Jyd7MX0oKScnXHUzMDRDXHU4OThCXHUzMDY0XHUzMDRCXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzCgpjb21waWxlci53YXJuLmFubm90YXRpb24ubWV0aG9kLm5vdC5mb3VuZC5yZWFzb249XHUzMEJGXHUzMEE0XHUzMEQ3Jyd7MH0nJ1x1NTE4NVx1MzA2Qlx1NkNFOFx1OTFDOFx1MzBFMVx1MzBCRFx1MzBDM1x1MzBDOScnezF9KCknJ1x1MzA0Q1x1ODk4Qlx1MzA2NFx1MzA0Qlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5MzogezJ9CgojIDA6IHN5bWJvbCwgMTogbmFtZQpjb21waWxlci53YXJuLnVua25vd24uZW51bS5jb25zdGFudD1cdTRFMERcdTY2MEVcdTMwNkFcdTUyMTdcdTYzMTlcdTU3OEJcdTVCOUFcdTY1NzBcdTMwNjdcdTMwNTl7MX0uezJ9CgojIDA6IHN5bWJvbCwgMTogbmFtZSwgMjogbWVzc2FnZSBzZWdtZW50CmNvbXBpbGVyLndhcm4udW5rbm93bi5lbnVtLmNvbnN0YW50LnJlYXNvbj1cdTRFMERcdTY2MEVcdTMwNkFcdTUyMTdcdTYzMTlcdTU3OEJcdTVCOUFcdTY1NzBcdTMwNjdcdTMwNTl7MX0uezJ9XG5cdTc0MDZcdTc1MzE6IHszfQoKIyAwOiB0eXBlLCAxOiB0eXBlCmNvbXBpbGVyLndhcm4ucmF3LmNsYXNzLnVzZT1yYXdcdTU3OEJcdTMwNENcdTg5OEJcdTMwNjRcdTMwNEJcdTMwOEFcdTMwN0VcdTMwNTdcdTMwNUY6IHswfVxuXHU2QzRFXHU3NTI4XHUzMEFGXHUzMEU5XHUzMEI5ezF9XHUzMDZFXHU1NzhCXHU1RjE1XHU2NTcwXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzCgojIDA6IHVudXNlZCwgMTogdW51c2VkCmNvbXBpbGVyLndhcm4uZGlhbW9uZC5yZWR1bmRhbnQuYXJncz1cdTY1QjBcdTMwNTdcdTMwNDRcdTVGMEZcdTMwNkVcdTU3OEJcdTVGMTVcdTY1NzBcdTMwNENcdTkxQ0RcdTg5MDdcdTMwNTdcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNTkoXHUzMDRCXHUzMDhGXHUzMDhBXHUzMDZCXHUzMEMwXHUzMEE0XHUzMEU0XHUzMEUyXHUzMEYzXHUzMEM5XHU2RjE0XHU3Qjk3XHU1QjUwXHUzMDkyXHU0RjdGXHU3NTI4XHUzMDU3XHUzMDdFXHUzMDU5KVx1MzAwMgoKY29tcGlsZXIud2Fybi5wb3RlbnRpYWwubGFtYmRhLmZvdW5kPVx1MzA1M1x1MzA2RVx1NTMzRlx1NTQwRFx1NTE4NVx1OTBFOFx1MzBBRlx1MzBFOVx1MzBCOVx1MzA5Mlx1MzBFOVx1MzBFMFx1MzBDMFx1NUYwRlx1MzA2Qlx1NTkwOVx1NjNEQlx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1OVx1MzAwMgoKY29tcGlsZXIud2Fybi5tZXRob2QucmVkdW5kYW50LnR5cGVhcmdzPVx1MzBFMVx1MzBCRFx1MzBDM1x1MzBDOVx1NTQ3Q1x1NTFGQVx1MzA1N1x1MzA2RVx1NTc4Qlx1NUYxNVx1NjU3MFx1MzA0Q1x1OTFDRFx1ODkwN1x1MzA1N1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1OVx1MzAwMgoKIyAwOiBzeW1ib2wsIDE6IG1lc3NhZ2Ugc2VnbWVudApjb21waWxlci53YXJuLnZhcmFyZ3MucmVkdW5kYW50LnRydXN0bWUuYW5ubz17MH1cdTZDRThcdTkxQzhcdTMwNENcdTUxOTdcdTk1NzdcdTMwNjdcdTMwNTlcdTMwMDJ7MX0KCiMgMDogc3ltYm9sCmNvbXBpbGVyLndhcm4uYWNjZXNzLnRvLm1lbWJlci5mcm9tLnNlcmlhbGl6YWJsZS5lbGVtZW50PVx1NzZGNFx1NTIxN1x1NTMxNlx1NTNFRlx1ODBGRFx1ODk4MVx1N0QyMFx1MzA0Qlx1MzA4OVx1MzBFMVx1MzBGM1x1MzBEMFx1MzBGQ3swfVx1MzA3OFx1MzA2RVx1MzBBMlx1MzBBRlx1MzBCQlx1MzBCOVx1MzA2Rlx1MzAwMVx1NEZFMVx1OTgzQ1x1MzA2N1x1MzA0RFx1MzA2QVx1MzA0NFx1MzBCM1x1MzBGQ1x1MzBDOVx1MzA0Qlx1MzA4OVx1MzBEMVx1MzBENlx1MzBFQVx1MzBDM1x1MzBBRlx1MzA2Qlx1MzBBMlx1MzBBRlx1MzBCQlx1MzBCOVx1NTNFRlx1ODBGRFx1MzA2N1x1MzA0Mlx1MzA4Qlx1NTNFRlx1ODBGRFx1NjAyN1x1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OQoKIyAwOiBzeW1ib2wKY29tcGlsZXIud2Fybi5hY2Nlc3MudG8ubWVtYmVyLmZyb20uc2VyaWFsaXphYmxlLmxhbWJkYT1cdTc2RjRcdTUyMTdcdTUzMTZcdTUzRUZcdTgwRkRcdTMwRTlcdTMwRTBcdTMwQzBcdTMwNEJcdTMwODlcdTMwRTFcdTMwRjNcdTMwRDBcdTMwRkN7MH1cdTMwNzhcdTMwNkVcdTMwQTJcdTMwQUZcdTMwQkJcdTMwQjlcdTMwNkZcdTMwMDFcdTRGRTFcdTk4M0NcdTMwNjdcdTMwNERcdTMwNkFcdTMwNDRcdTMwQjNcdTMwRkNcdTMwQzlcdTMwNEJcdTMwODlcdTMwRDFcdTMwRDZcdTMwRUFcdTMwQzNcdTMwQUZcdTMwNkJcdTMwQTJcdTMwQUZcdTMwQkJcdTMwQjlcdTUzRUZcdTgwRkRcdTMwNjdcdTMwNDJcdTMwOEJcdTUzRUZcdTgwRkRcdTYwMjdcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTkKCiMjIyMjCgojIyBUaGUgZm9sbG93aW5nIGFyZSB0b2tlbnMgd2hpY2ggYXJlIG5vbi10ZXJtaW5hbHMgaW4gdGhlIGxhbmd1YWdlLiBUaGV5IHNob3VsZAojIyBiZSBuYW1lZCBhcyBKTFMzIGNhbGxzIHRoZW0gd2hlbiB0cmFuc2xhdGVkIHRvIHRoZSBhcHByb3ByaWF0ZSBsYW5ndWFnZS4KY29tcGlsZXIubWlzYy50b2tlbi5pZGVudGlmaWVyPTxpZGVudGlmaWVyPgoKY29tcGlsZXIubWlzYy50b2tlbi5jaGFyYWN0ZXI9PGNoYXJhY3Rlcj4KCmNvbXBpbGVyLm1pc2MudG9rZW4uc3RyaW5nPTxzdHJpbmc+Cgpjb21waWxlci5taXNjLnRva2VuLmludGVnZXI9PGludGVnZXI+Cgpjb21waWxlci5taXNjLnRva2VuLmxvbmctaW50ZWdlcj08bG9uZyBpbnRlZ2VyPgoKY29tcGlsZXIubWlzYy50b2tlbi5mbG9hdD08ZmxvYXQ+Cgpjb21waWxlci5taXNjLnRva2VuLmRvdWJsZT08ZG91YmxlPgoKY29tcGlsZXIubWlzYy50b2tlbi5iYWQtc3ltYm9sPTxiYWQgc3ltYm9sPgoKY29tcGlsZXIubWlzYy50b2tlbi5lbmQtb2YtaW5wdXQ9PGVuZCBvZiBpbnB1dD4KCiMjIFRoZSBhcmd1bWVudCB0byB0aGUgZm9sbG93aW5nIHN0cmluZyB3aWxsIGFsd2F5cyBiZSBvbmUgb2YgdGhlIGZvbGxvd2luZzoKIyMgMS4gb25lIG9mIHRoZSBhYm92ZSBub24tdGVybWluYWxzCiMjIDIuIGEga2V5d29yZCAoSkxTMS44KQojIyAzLiBhIGJvb2xlYW4gbGl0ZXJhbCAoSkxTMy4xMC4zKQojIyA0LiB0aGUgbnVsbCBsaXRlcmFsIChKTFMzLjEwLjcpCiMjIDUuIGEgSmF2YSBzZXBhcmF0b3IgKEpMUzMuMTEpCiMjIDYuIGFuIG9wZXJhdG9yIChKTFMzLjEyKQojIwojIyBUaGlzIGlzIHRoZSBvbmx5IHBsYWNlIHRoZXNlIHRva2VucyB3aWxsIGJlIHVzZWQuCiMgMDogdG9rZW4KY29tcGlsZXIuZXJyLmV4cGVjdGVkPXswfVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5MwoKIyAwOiB0b2tlbiwgMTogdG9rZW4KY29tcGlsZXIuZXJyLmV4cGVjdGVkMj17MH1cdTMwN0VcdTMwNUZcdTMwNkZ7MX1cdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTMKCiMgMDogdG9rZW4sIDE6IHRva2VuLCAyOiB0b2tlbgpjb21waWxlci5lcnIuZXhwZWN0ZWQzPXswfVx1MzAwMXsxfVx1MzA3RVx1MzA1Rlx1MzA2RnsyfVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5MwoKY29tcGlsZXIuZXJyLnByZW1hdHVyZS5lb2Y9XHU2OUNCXHU2NTg3XHU4OUUzXHU2NzkwXHU0RTJEXHUzMDZCXHUzMEQ1XHUzMEExXHUzMEE0XHUzMEVCXHUzMDZFXHU3RDQyXHUzMDhGXHUzMDhBXHUzMDZCXHU3OUZCXHUzMDhBXHUzMDdFXHUzMDU3XHUzMDVGCgojIyBUaGUgZm9sbG93aW5nIGFyZSByZWxhdGVkIGluIGZvcm0sIGJ1dCBkbyBub3QgZWFzaWx5IGZpdCB0aGUgYWJvdmUgcGFyYWRpZ20uCmNvbXBpbGVyLmVyci5leHBlY3RlZC5tb2R1bGU9JydcdTMwRTJcdTMwQjhcdTMwRTVcdTMwRkNcdTMwRUInJ1x1MzA0Q1x1NUZDNVx1ODk4MVx1MzA2N1x1MzA1OQoKY29tcGlsZXIuZXJyLmRvdC5jbGFzcy5leHBlY3RlZD0nJy5jbGFzcycnXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzCgojIyBUaGUgYXJndW1lbnQgdG8gdGhpcyBzdHJpbmcgd2lsbCBhbHdheXMgYmUgZWl0aGVyICdjYXNlJyBvciAnZGVmYXVsdCcuCiMgMDogdG9rZW4KY29tcGlsZXIuZXJyLm9ycGhhbmVkPXswfVx1MzA2Qlx1MzA2Rlx1ODlBQVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5MwoKIyAwOiBuYW1lCmNvbXBpbGVyLm1pc2MuYW5vbnltb3VzLmNsYXNzPTxhbm9ueW1vdXMgezB9PgoKIyAwOiBuYW1lLCAxOiB0eXBlCmNvbXBpbGVyLm1pc2MudHlwZS5jYXB0dXJlb2Y9ezF9XHUzMDZFXHUzMEFEXHUzMEUzXHUzMEQ3XHUzMEMxXHUzMEUzI3swfQoKY29tcGlsZXIubWlzYy50eXBlLmNhcHR1cmVvZi4xPVx1MzBBRFx1MzBFM1x1MzBEN1x1MzBDMVx1MzBFMyN7MH0KCmNvbXBpbGVyLm1pc2MudHlwZS5ub25lPTxub25lPgoKY29tcGlsZXIubWlzYy51bm5hbWVkLnBhY2thZ2U9XHU1NDBEXHU1MjREXHUzMDZFXHUzMDZBXHUzMDQ0XHUzMEQxXHUzMEMzXHUzMEIxXHUzMEZDXHUzMEI4Cgpjb21waWxlci5taXNjLnVubmFtZWQubW9kdWxlPVx1NTQwRFx1NTI0RFx1MzA2RVx1MzA2QVx1MzA0NFx1MzBFMlx1MzBCOFx1MzBFNVx1MzBGQ1x1MzBFQgoKIyMjIyMKCiMgMDogc3ltYm9sLCAxOiBtZXNzYWdlIHNlZ21lbnQKY29tcGlsZXIuZXJyLmNhbnQuYWNjZXNzPXswfVx1MzA2Qlx1MzBBMlx1MzBBRlx1MzBCQlx1MzBCOVx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1xuezF9CgojIDA6IG5hbWUKY29tcGlsZXIubWlzYy5iYWQuY2xhc3MuZmlsZT1cdTMwQUZcdTMwRTlcdTMwQjl7MH1cdTMwNkVcdTMwQUZcdTMwRTlcdTMwQjlcdTMwRkJcdTMwRDVcdTMwQTFcdTMwQTRcdTMwRUJcdTMwNENcdTcxMjFcdTUyQjlcdTMwNjdcdTMwNTkKCiMgMDogZmlsZSBuYW1lLCAxOiBzdHJpbmcgKGV4cGVjdGVkIGNvbnN0YW50IHBvb2wgZW50cnkgdHlwZSksIDI6IG51bWJlciAoY29uc3RhbnQgcG9vbCBpbmRleCkKY29tcGlsZXIubWlzYy5iYWQuY29uc3QucG9vbC5lbnRyeT17MH1cdTMwNkVcdTVCOUFcdTY1NzBcdTMwRDdcdTMwRkNcdTMwRUJcdTMwRkJcdTMwQThcdTMwRjNcdTMwQzhcdTMwRUFcdTMwNENcdTRFMERcdTZCNjNcdTMwNjdcdTMwNTlcblx1N0QyMlx1NUYxNXsyfVx1MzA2N1x1MzA2RnsxfVx1MzA0Q1x1NUZDNVx1ODk4MVx1MzA2N1x1MzA1OQoKIyAwOiBmaWxlIG5hbWUsIDE6IG1lc3NhZ2Ugc2VnbWVudApjb21waWxlci5taXNjLmJhZC5jbGFzcy5maWxlLmhlYWRlcj1cdTMwQUZcdTMwRTlcdTMwQjlcdTMwRkJcdTMwRDVcdTMwQTFcdTMwQTRcdTMwRUJ7MH1cdTMwNkZcdTRFMERcdTZCNjNcdTMwNjdcdTMwNTlcbnsxfVxuXHU1MjRBXHU5NjY0XHUzMDU5XHUzMDhCXHUzMDRCXHUzMDAxXHUzMEFGXHUzMEU5XHUzMEI5XHUzMEQxXHUzMEI5XHUzMDZFXHU2QjYzXHUzMDU3XHUzMDQ0XHUzMEI1XHUzMEQ2XHUzMEM3XHUzMEEzXHUzMEVDXHUzMEFGXHUzMEM4XHUzMEVBXHUzMDZCXHUzMDQyXHUzMDhCXHUzMDRCXHUzMDkyXHU3OEJBXHU4QThEXHUzMDU3XHUzMDY2XHUzMDRGXHUzMDYwXHUzMDU1XHUzMDQ0XHUzMDAyCgojIDA6IGZpbGUgbmFtZSwgMTogbWVzc2FnZSBzZWdtZW50CmNvbXBpbGVyLm1pc2MuYmFkLnNvdXJjZS5maWxlLmhlYWRlcj1cdTMwQkRcdTMwRkNcdTMwQjlcdTMwRkJcdTMwRDVcdTMwQTFcdTMwQTRcdTMwRUJ7MH1cdTMwNkZcdTRFMERcdTZCNjNcdTMwNjdcdTMwNTlcbnsxfVxuXHU1MjRBXHU5NjY0XHUzMDU5XHUzMDhCXHUzMDRCXHUzMDAxXHUzMEJEXHUzMEZDXHUzMEI5XHUzMEZCXHUzMEQxXHUzMEI5XHUzMDZFXHU2QjYzXHUzMDU3XHUzMDQ0XHUzMEI1XHUzMEQ2XHUzMEM3XHUzMEEzXHUzMEVDXHUzMEFGXHUzMEM4XHUzMEVBXHUzMDZCXHUzMDQyXHUzMDhCXHUzMDRCXHUzMDkyXHU3OEJBXHU4QThEXHUzMDU3XHUzMDY2XHUzMDRGXHUzMDYwXHUzMDU1XHUzMDQ0XHUzMDAyCgojIyBUaGUgZm9sbG93aW5nIGFyZSBhbGwgcG9zc2libGUgc3RyaW5ncyBmb3IgdGhlIHNlY29uZCBhcmd1bWVudCAoezF9KSBvZiB0aGUKIyMgYWJvdmUgc3RyaW5ncy4KY29tcGlsZXIubWlzYy5iYWQuY2xhc3Muc2lnbmF0dXJlPVx1MzBBRlx1MzBFOVx1MzBCOXswfVx1MzA2RVx1MzBCN1x1MzBCMFx1MzBDQlx1MzBDMVx1MzBFM1x1MzA0Q1x1NEUwRFx1NkI2M1x1MzA2N1x1MzA1OQoKIzA6IHN5bWJvbCwgMTogc3ltYm9sCmNvbXBpbGVyLm1pc2MuYmFkLmVuY2xvc2luZy5jbGFzcz17MH1cdTMwNkVcdTUxODVcdTkwRThcdTMwQUZcdTMwRTlcdTMwQjlcdTMwNENcdTRFMERcdTZCNjNcdTMwNjdcdTMwNTk6IHsxfQoKIyAwOiBzeW1ib2wKY29tcGlsZXIubWlzYy5iYWQuZW5jbG9zaW5nLm1ldGhvZD1cdTMwQUZcdTMwRTlcdTMwQjl7MH1cdTMwNkVcdTU2RjJcdTMwOTNcdTMwNjdcdTMwNDRcdTMwOEJcdTMwRTFcdTMwQkRcdTMwQzNcdTMwQzlcdTVDNUVcdTYwMjdcdTMwNENcdTRFMERcdTZCNjNcdTMwNjdcdTMwNTkKCmNvbXBpbGVyLm1pc2MuYmFkLnJ1bnRpbWUuaW52aXNpYmxlLnBhcmFtLmFubm90YXRpb25zPVJ1bnRpbWVJbnZpc2libGVQYXJhbWV0ZXJBbm5vdGF0aW9uc1x1NUM1RVx1NjAyN1x1MzA0Q1x1NEUwRFx1NkI2M1x1MzA2N1x1MzA1OTogezB9Cgpjb21waWxlci5taXNjLmJhZC5jb25zdC5wb29sLnRhZz1cdTVCOUFcdTY1NzBcdTMwRDdcdTMwRkNcdTMwRUJcdTMwRkJcdTMwQkZcdTMwQjB7MH1cdTMwNENcdTRFMERcdTZCNjNcdTMwNjdcdTMwNTkKCmNvbXBpbGVyLm1pc2MuYmFkLmNvbnN0LnBvb2wudGFnLmF0PVx1NUI5QVx1NjU3MFx1MzBEN1x1MzBGQ1x1MzBFQlx1MzBGQlx1MzBCRlx1MzBCMHsxfVx1MzA2N1x1MzA2RXswfVx1MzA0Q1x1NEUwRFx1NkI2M1x1MzA2N1x1MzA1OQoKY29tcGlsZXIubWlzYy5iYWQuc2lnbmF0dXJlPVx1MzBCN1x1MzBCMFx1MzBDQlx1MzBDMVx1MzBFM3swfVx1MzA0Q1x1NEUwRFx1NkI2M1x1MzA2N1x1MzA1OQoKY29tcGlsZXIubWlzYy5iYWQudHlwZS5hbm5vdGF0aW9uLnZhbHVlPVx1NkNFOFx1OTFDOFx1MzBCRlx1MzBGQ1x1MzBCMlx1MzBDM1x1MzBDOFx1NTc4Qlx1MzA2RVx1NTAyNFx1MzA2RVx1NTc4Qlx1MzA0Q1x1NEUwRFx1NkI2M1x1MzA2N1x1MzA1OTogezB9Cgpjb21waWxlci5taXNjLmJhZC5tb2R1bGUtaW5mby5uYW1lPVx1MzBBRlx1MzBFOVx1MzBCOVx1NTQwRFx1MzA0Q1x1NEUwRFx1NkI2M1x1MzA2N1x1MzA1OQoKY29tcGlsZXIubWlzYy5jbGFzcy5maWxlLndyb25nLmNsYXNzPVx1MzBBRlx1MzBFOVx1MzBCOVx1MzBGQlx1MzBENVx1MzBBMVx1MzBBNFx1MzBFQnswfVx1MzA2Qlx1NEUwRFx1NkI2M1x1MzA2QVx1MzBBRlx1MzBFOVx1MzBCOVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OQoKY29tcGlsZXIubWlzYy5tb2R1bGUuaW5mby5pbnZhbGlkLnN1cGVyLmNsYXNzPVx1NzEyMVx1NTJCOVx1MzA2QVx1MzBCOVx1MzBGQ1x1MzBEMVx1MzBGQ1x1MzBGQlx1MzBBRlx1MzBFOVx1MzBCOVx1MzA5Mlx1NTQyQlx1MzA4MG1vZHVsZS1pbmZvCgpjb21waWxlci5taXNjLmNsYXNzLmZpbGUubm90LmZvdW5kPXswfVx1MzA2RVx1MzBBRlx1MzBFOVx1MzBCOVx1MzBGQlx1MzBENVx1MzBBMVx1MzBBNFx1MzBFQlx1MzA0Q1x1ODk4Qlx1MzA2NFx1MzA0Qlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5MwoKIyAwOiBzdHJpbmcgKGNvbnN0YW50IHZhbHVlKSwgMTogc3ltYm9sIChjb25zdGFudCBmaWVsZCksIDI6IHR5cGUgKGZpZWxkIHR5cGUpCmNvbXBpbGVyLm1pc2MuYmFkLmNvbnN0YW50LnJhbmdlPXsxfVx1MzA2RVx1NUI5QVx1NjU3MFx1NTAyNCcnezB9JydcdTMwNkZ7Mn1cdTMwNkVcdTYwRjNcdTVCOUFcdTdCQzRcdTU2RjJcdTU5MTZcdTMwNjdcdTMwNTkKCiMgMDogc3RyaW5nIChjb25zdGFudCB2YWx1ZSksIDE6IHN5bWJvbCAoY29uc3RhbnQgZmllbGQpLCAyOiBzdHJpbmcgKGV4cGVjdGVkIGNsYXNzKQpjb21waWxlci5taXNjLmJhZC5jb25zdGFudC52YWx1ZT17MX1cdTMwNkVcdTVCOUFcdTY1NzBcdTUwMjQnJ3swfScnXHUzMDZGXHU0RTBEXHU2QjYzXHUzMDY3XHUzMDU5XHUzMDAyezJ9XHUzMDRDXHU1RkM1XHU4OTgxXHUzMDY3XHUzMDU5CgojIDA6IHN0cmluZyAoY2xhc3NmaWxlIG1ham9yIHZlcnNpb24pLCAxOiBzdHJpbmcgKGNsYXNzZmlsZSBtaW5vciB2ZXJzaW9uKQpjb21waWxlci5taXNjLmludmFsaWQuZGVmYXVsdC5pbnRlcmZhY2U9XHUzMEQwXHUzMEZDXHUzMEI4XHUzMEU3XHUzMEYzezB9LnsxfVx1MzA2RVx1MzBBRlx1MzBFOVx1MzBCOVx1MzBGQlx1MzBENVx1MzBBMVx1MzBBNFx1MzBFQlx1MzA2Qlx1MzBDN1x1MzBENVx1MzBBOVx1MzBFQlx1MzBDOFx1MzBGQlx1MzBFMVx1MzBCRFx1MzBDM1x1MzBDOVx1MzA0Q1x1ODk4Qlx1MzA2NFx1MzA0Qlx1MzA4QVx1MzA3RVx1MzA1N1x1MzA1RgoKIyAwOiBzdHJpbmcgKGNsYXNzZmlsZSBtYWpvciB2ZXJzaW9uKSwgMTogc3RyaW5nIChjbGFzc2ZpbGUgbWlub3IgdmVyc2lvbikKY29tcGlsZXIubWlzYy5pbnZhbGlkLnN0YXRpYy5pbnRlcmZhY2U9XHUzMEQwXHUzMEZDXHUzMEI4XHUzMEU3XHUzMEYzezB9LnsxfVx1MzA2RVx1MzBBRlx1MzBFOVx1MzBCOVx1MzBGQlx1MzBENVx1MzBBMVx1MzBBNFx1MzBFQlx1MzA2QnN0YXRpY1x1MzBFMVx1MzBCRFx1MzBDM1x1MzBDOVx1MzA0Q1x1ODk4Qlx1MzA2NFx1MzA0Qlx1MzA4QVx1MzA3RVx1MzA1N1x1MzA1RgoKIyAwOiBzdHJpbmcgKGNsYXNzZmlsZSBtYWpvciB2ZXJzaW9uKSwgMTogc3RyaW5nIChjbGFzc2ZpbGUgbWlub3IgdmVyc2lvbikKY29tcGlsZXIubWlzYy5hbmFjaHJvbmlzdGljLm1vZHVsZS5pbmZvPVx1MzBEMFx1MzBGQ1x1MzBCOFx1MzBFN1x1MzBGM3swfS57MX1cdTMwNkVcdTMwQUZcdTMwRTlcdTMwQjlcdTMwRkJcdTMwRDVcdTMwQTFcdTMwQTRcdTMwRUJcdTMwNkJcdTMwRTJcdTMwQjhcdTMwRTVcdTMwRkNcdTMwRUJcdTVCQTNcdThBMDBcdTMwNENcdTg5OEJcdTMwNjRcdTMwNEJcdTMwOEFcdTMwN0VcdTMwNTdcdTMwNUYKCiMgMDogbmFtZQpjb21waWxlci5taXNjLmZpbGUuZG9lc250LmNvbnRhaW4uY2xhc3M9XHUzMEQ1XHUzMEExXHUzMEE0XHUzMEVCXHUzMDZCXHUzMEFGXHUzMEU5XHUzMEI5ezB9XHUzMDRDXHU1NDJCXHUzMDdFXHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDVCXHUzMDkzCgpjb21waWxlci5taXNjLmZpbGUuZG9lcy5ub3QuY29udGFpbi5wYWNrYWdlPVx1MzBENVx1MzBBMVx1MzBBNFx1MzBFQlx1MzA2Qlx1MzBEMVx1MzBDM1x1MzBCMVx1MzBGQ1x1MzBCOHswfVx1MzA0Q1x1NTQyQlx1MzA3RVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1Qlx1MzA5MwoKY29tcGlsZXIubWlzYy5maWxlLmRvZXMubm90LmNvbnRhaW4ubW9kdWxlPVx1MzBENVx1MzBBMVx1MzBBNFx1MzBFQlx1MzA2Qlx1MzBFMlx1MzBCOFx1MzBFNVx1MzBGQ1x1MzBFQlx1NUJBM1x1OEEwMFx1MzA0Q1x1NTQyQlx1MzA3RVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1Qlx1MzA5MwoKY29tcGlsZXIubWlzYy5pbGxlZ2FsLnN0YXJ0Lm9mLmNsYXNzLmZpbGU9XHUzMEFGXHUzMEU5XHUzMEI5XHUzMEZCXHUzMEQ1XHUzMEExXHUzMEE0XHUzMEVCXHUzMDZFXHU5NThCXHU1OUNCXHUzMDRDXHU0RTBEXHU2QjYzXHUzMDY3XHUzMDU5Cgpjb21waWxlci5taXNjLnVuYWJsZS50by5hY2Nlc3MuZmlsZT1cdTMwRDVcdTMwQTFcdTMwQTRcdTMwRUJ7MH1cdTMwNkJcdTMwQTJcdTMwQUZcdTMwQkJcdTMwQjlcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTMKCmNvbXBpbGVyLm1pc2MudW5pY29kZS5zdHIubm90LnN1cHBvcnRlZD1cdTMwQUZcdTMwRTlcdTMwQjlcdTMwRkJcdTMwRDVcdTMwQTFcdTMwQTRcdTMwRUJcdTUxODVcdTMwNkVVbmljb2RlXHU2NTg3XHU1QjU3XHU1MjE3XHUzMDZGXHUzMEI1XHUzMEREXHUzMEZDXHUzMEM4XHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDVCXHUzMDkzCgpjb21waWxlci5taXNjLnVuZGVjbC50eXBlLnZhcj1cdTU3OEJcdTU5MDlcdTY1NzB7MH1cdTMwNkZcdTVCQTNcdThBMDBcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNUJcdTMwOTMKCmNvbXBpbGVyLm1pc2MubWFsZm9ybWVkLnZhcmFyZy5tZXRob2Q9XHUzMEFGXHUzMEU5XHUzMEI5XHUzMEZCXHUzMEQ1XHUzMEExXHUzMEE0XHUzMEVCXHUzMDZCXHU0RTBEXHU2QjYzXHUzMDZBXHU1M0VGXHU1OTA5XHU1RjE1XHU2NTcwXHUzMEUxXHUzMEJEXHUzMEMzXHUzMEM5XHUzMDRDXHU1NDJCXHUzMDdFXHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5OiB7MH0KCmNvbXBpbGVyLm1pc2Mud3JvbmcudmVyc2lvbj1cdTMwQUZcdTMwRTlcdTMwQjlcdTMwRkJcdTMwRDVcdTMwQTFcdTMwQTRcdTMwRUJcdTMwNkVcdTMwRDBcdTMwRkNcdTMwQjhcdTMwRTdcdTMwRjN7MH0uezF9XHUzMDZGXHU0RTBEXHU2QjYzXHUzMDY3XHUzMDU5XHUzMDAyezJ9LnszfVx1MzA2N1x1MzA0Mlx1MzA4Qlx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OQoKIyMjIyMKCiMgMDogdHlwZSwgMTogdHlwZSBvciBzeW1ib2wKY29tcGlsZXIuZXJyLm5vdC53aXRoaW4uYm91bmRzPVx1NTc4Qlx1NUYxNVx1NjU3MHswfVx1MzA2Rlx1NTc4Qlx1NTkwOVx1NjU3MHsxfVx1MzA2RVx1NTg4M1x1NzU0Q1x1NTE4NVx1MzA2Qlx1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5MwoKIyMgVGhlIGZvbGxvd2luZyBhcmUgYWxsIHBvc3NpYmxlIHN0cmluZ3MgZm9yIHRoZSBzZWNvbmQgYXJndW1lbnQgKHsxfSkgb2YgdGhlCiMjIGFib3ZlIHN0cmluZy4KCiMjIG5vbmUgeWV0Li4uCgojIyMjIwoKIyAwOiBtZXNzYWdlIHNlZ21lbnQKY29tcGlsZXIuZXJyLnByb2IuZm91bmQucmVxPVx1NEUwRFx1OTA2OVx1NTQwOFx1MzA2QVx1NTc4QjogezB9CgojIDA6IG1lc3NhZ2Ugc2VnbWVudApjb21waWxlci5taXNjLnByb2IuZm91bmQucmVxPVx1NEUwRFx1OTA2OVx1NTQwOFx1MzA2QVx1NTc4QjogezB9CgojIDA6IG1lc3NhZ2Ugc2VnbWVudCwgMTogdHlwZSwgMjogdHlwZQpjb21waWxlci53YXJuLnByb2IuZm91bmQucmVxPXswfVxuXHU2NzFGXHU1Rjg1XHU1MDI0OiB7Mn1cblx1NjkxQ1x1NTFGQVx1NTAyNDogICAgezF9CgojIDA6IHR5cGUsIDE6IHR5cGUKY29tcGlsZXIubWlzYy5pbmNvbnZlcnRpYmxlLnR5cGVzPXswfVx1MzA5MnsxfVx1MzA2Qlx1NTkwOVx1NjNEQlx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5MzoKCiMgMDogdHlwZSwgMTogdHlwZQpjb21waWxlci5taXNjLnBvc3NpYmxlLmxvc3Mub2YucHJlY2lzaW9uPVx1N0NCRVx1NUVBNlx1MzA0Q1x1NTkzMVx1MzA4Rlx1MzA4Q1x1MzA4Qlx1NTNFRlx1ODBGRFx1NjAyN1x1MzA0Q1x1MzA0Mlx1MzA4QnswfVx1MzA0Qlx1MzA4OXsxfVx1MzA3OFx1MzA2RVx1NTkwOVx1NjNEQgoKY29tcGlsZXIubWlzYy51bmNoZWNrZWQuYXNzaWduPVx1NzEyMVx1NjkxQ1x1NjdGQlx1NTkwOVx1NjNEQgoKIyBjb21waWxlci5taXNjLnN0b3JlY2hlY2s9XAojICAgICBhc3NpZ25tZW50IG1pZ2h0IGNhdXNlIGxhdGVyIHN0b3JlIGNoZWNrcyB0byBmYWlsCiMgY29tcGlsZXIubWlzYy51bmNoZWNrZWQ9XAojICAgICBhc3NpZ25lZCBhcnJheSBjYW5ub3QgZHluYW1pY2FsbHkgY2hlY2sgaXRzIHN0b3Jlcwpjb21waWxlci5taXNjLnVuY2hlY2tlZC5jYXN0LnRvLnR5cGU9XHU3MTIxXHU2OTFDXHU2N0ZCXHUzMEFEXHUzMEUzXHUzMEI5XHUzMEM4CgojIGNvbXBpbGVyLmVyci5zdGFyLmV4cGVjdGVkPVwKIyAgICAgJycqJycgZXhwZWN0ZWQKIyBjb21waWxlci5lcnIubm8uZWxlbS50eXBlPVwKIyAgICAgXFtcKlxdIGNhbm5vdCBoYXZlIGEgdHlwZQoKIyAwOiB0eXBlCmNvbXBpbGVyLm1pc2MudHJ5Lm5vdC5hcHBsaWNhYmxlLnRvLnR5cGU9dHJ5LXdpdGgtcmVzb3VyY2VcdTMwNkZcdTU5MDlcdTY1NzBcdTU3OEJcdTMwNkJcdTRGN0ZcdTc1MjhcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcbih7MH0pCgojIyMjIwoKIyAwOiBtZXNzYWdlIHNlZ21lbnQgb3IgdHlwZSwgMTogbWVzc2FnZSBzZWdtZW50CmNvbXBpbGVyLmVyci50eXBlLmZvdW5kLnJlcT1cdTRFODhcdTY3MUZcdTMwNTdcdTMwNkFcdTMwNDRcdTU3OEJcblx1NjcxRlx1NUY4NVx1NTAyNDogezF9XG5cdTY5MUNcdTUxRkFcdTUwMjQ6ICAgIHswfQoKIyMgVGhlIGZvbGxvd2luZyBhcmUgYWxsIHBvc3NpYmxlIHN0cmluZ3MgZm9yIHRoZSBmaXJzdCBhcmd1bWVudCAoezB9KSBvZiB0aGUKIyMgYWJvdmUgc3RyaW5nLgpjb21waWxlci5taXNjLnR5cGUucmVxLmNsYXNzPVx1MzBBRlx1MzBFOVx1MzBCOQoKY29tcGlsZXIubWlzYy50eXBlLnJlcS5jbGFzcy5hcnJheT1cdTMwQUZcdTMwRTlcdTMwQjlcdTMwN0VcdTMwNUZcdTMwNkZcdTkxNERcdTUyMTcKCmNvbXBpbGVyLm1pc2MudHlwZS5yZXEuYXJyYXkub3IuaXRlcmFibGU9XHU5MTREXHU1MjE3XHUzMDdFXHUzMDVGXHUzMDZGamF2YS5sYW5nLkl0ZXJhYmxlCgpjb21waWxlci5taXNjLnR5cGUucmVxLnJlZj1cdTUzQzJcdTcxNjcKCmNvbXBpbGVyLm1pc2MudHlwZS5yZXEuZXhhY3Q9XHU1ODgzXHU3NTRDXHUzMDZFXHUzMDZBXHUzMDQ0XHUzMEFGXHUzMEU5XHUzMEI5XHUzMDdFXHUzMDVGXHUzMDZGXHUzMEE0XHUzMEYzXHUzMEJGXHUzMEQ1XHUzMEE3XHUzMEZDXHUzMEI5CgojIDA6IHR5cGUKY29tcGlsZXIubWlzYy50eXBlLnBhcmFtZXRlcj1cdTU3OEJcdTMwRDFcdTMwRTlcdTMwRTFcdTMwRkNcdTMwQkZ7MH0KCiMjIyMjCgojIyBUaGUgZm9sbG93aW5nIGFyZSBhbGwgcG9zc2libGUgc3RyaW5ncyBmb3IgdGhlIGxhc3QgYXJndW1lbnQgb2YgYWxsIHRob3NlCiMjIGRpYWdub3N0aWNzIHdob3NlIGtleSBlbmRzIGluICIuMSIKCiMgMDogdHlwZSwgMTogbGlzdCBvZiB0eXBlCmNvbXBpbGVyLm1pc2Mubm8udW5pcXVlLm1heGltYWwuaW5zdGFuY2UuZXhpc3RzPVx1NTc4Qlx1NTkwOVx1NjU3MHswfShcdTRFMEFcdTk2NTB7MX0pXHUzMDZFXHU1NkZBXHU2NzA5XHUzMDZFXHU2NzAwXHU1OTI3XHUzMEE0XHUzMEYzXHUzMEI5XHUzMEJGXHUzMEYzXHUzMEI5XHUzMDRDXHU1QjU4XHU1NzI4XHUzMDU3XHUzMDdFXHUzMDVCXHUzMDkzCgpjb21waWxlci5taXNjLm5vLnVuaXF1ZS5taW5pbWFsLmluc3RhbmNlLmV4aXN0cz1cdTU3OEJcdTU5MDlcdTY1NzB7MH0oXHU0RTBCXHU5NjUwezF9KVx1MzA2RVx1NTZGQVx1NjcwOVx1MzA2RVx1NjcwMFx1NUMwRlx1MzBBNFx1MzBGM1x1MzBCOVx1MzBCRlx1MzBGM1x1MzBCOVx1MzA0Q1x1NUI1OFx1NTcyOFx1MzA1N1x1MzA3RVx1MzA1Qlx1MzA5MwoKIyAwOiB0eXBlLCAxOiBsaXN0IG9mIHR5cGUKY29tcGlsZXIubWlzYy5pbmNvbXBhdGlibGUudXBwZXIuYm91bmRzPVx1NjNBOFx1NkUyQ1x1MzA2RVx1NTkwOVx1NjU3MHswfVx1MzA2Qlx1MzA2Rlx1MzAwMVx1OTA2OVx1NTQwOFx1MzA1N1x1MzA2QVx1MzA0NFx1NEUwQVx1OTY1MHsxfVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OQoKIyAwOiB0eXBlLCAxOiBsaXN0IG9mIHR5cGUKY29tcGlsZXIubWlzYy5pbmNvbXBhdGlibGUuZXEuYm91bmRzPVx1NjNBOFx1OEFENlx1NTkwOVx1NjU3MHswfVx1MzA2Qlx1MzA2Rlx1MzAwMVx1NEUwRFx1OTA2OVx1NTQwOFx1MzA2QVx1N0I0OVx1NEZBMVx1NTIzNlx1N0QwNHsxfVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OQoKIyAwOiB0eXBlLCAxOiBsaXN0IG9mIHR5cGUsIDI6IGxpc3Qgb2YgdHlwZQpjb21waWxlci5taXNjLmluY29tcGF0aWJsZS5lcS51cHBlci5ib3VuZHM9XHU2M0E4XHU4QUQ2XHU1OTA5XHU2NTcwezB9XHUzMDZCXHUzMDZGXHUzMDAxXHU0RTBEXHU5MDY5XHU1NDA4XHUzMDZBXHU1ODgzXHU3NTRDXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5XG5cdTdCNDlcdTRGQTFcdTUyMzZcdTdEMDQ6IHsxfVxuXHU0RTBBXHU5NjUwOiB7Mn0KCiMgMDogdHlwZSwgMTogbGlzdCBvZiB0eXBlLCAyOiBsaXN0IG9mIHR5cGUKY29tcGlsZXIubWlzYy5pbmNvbXBhdGlibGUudXBwZXIubG93ZXIuYm91bmRzPVx1NjNBOFx1OEFENlx1NTkwOVx1NjU3MHswfVx1MzA2Qlx1MzA2Rlx1MzAwMVx1NEUwRFx1OTA2OVx1NTQwOFx1MzA2QVx1NTg4M1x1NzU0Q1x1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OVxuXHU0RTBBXHU5NjUwOiB7MX1cblx1NEUwQlx1OTY1MDogezJ9CgojIDA6IHR5cGUsIDE6IGxpc3Qgb2YgdHlwZSwgMjogbGlzdCBvZiB0eXBlCmNvbXBpbGVyLm1pc2MuaW5jb21wYXRpYmxlLmVxLmxvd2VyLmJvdW5kcz1cdTYzQThcdThBRDZcdTU5MDlcdTY1NzB7MH1cdTMwNkJcdTMwNkZcdTMwMDFcdTRFMERcdTkwNjlcdTU0MDhcdTMwNkFcdTU4ODNcdTc1NENcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlcblx1N0I0OVx1NEZBMVx1NTIzNlx1N0QwNDogezF9XG5cdTRFMEJcdTk2NTA6IHsyfQoKIyAwOiBsaXN0IG9mIHR5cGUsIDE6IHR5cGUsIDI6IHR5cGUKY29tcGlsZXIubWlzYy5pbmZlci5uby5jb25mb3JtaW5nLmluc3RhbmNlLmV4aXN0cz1cdTU3OEJcdTU5MDlcdTY1NzB7MH1cdTMwNkVcdTMwQTRcdTMwRjNcdTMwQjlcdTMwQkZcdTMwRjNcdTMwQjlcdTMwNENcdTVCNThcdTU3MjhcdTMwNTdcdTMwNkFcdTMwNDRcdTMwNkVcdTMwNjdcdTMwMDF7MX1cdTMwNkZ7Mn1cdTMwNkJcdTkwNjlcdTU0MDhcdTMwNTdcdTMwN0VcdTMwNUJcdTMwOTMKCiMgMDogbGlzdCBvZiB0eXBlLCAxOiBtZXNzYWdlIHNlZ21lbnQKY29tcGlsZXIubWlzYy5pbmZlci5uby5jb25mb3JtaW5nLmFzc2lnbm1lbnQuZXhpc3RzPVx1NTc4Qlx1NTkwOVx1NjU3MHswfVx1MzA5Mlx1NjNBOFx1OEFENlx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1xuKFx1NUYxNVx1NjU3MFx1MzA2RVx1NEUwRFx1NEUwMFx1ODFGNDogezF9KQoKIyAwOiBsaXN0IG9mIHR5cGUKY29tcGlsZXIubWlzYy5pbmZlci5hcmcubGVuZ3RoLm1pc21hdGNoPVx1NTc4Qlx1NTkwOVx1NjU3MHswfVx1MzA5Mlx1NjNBOFx1OEFENlx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1xuKFx1NUI5Rlx1NUYxNVx1NjU3MFx1MzBFQVx1MzBCOVx1MzBDOFx1MzA2OFx1NEVFRVx1NUYxNVx1NjU3MFx1MzBFQVx1MzBCOVx1MzBDOFx1MzA2RVx1OTU3N1x1MzA1NVx1MzA0Q1x1NzU3MFx1MzA2QVx1MzA4QVx1MzA3RVx1MzA1OSkKCiMgMDogbGlzdCBvZiB0eXBlLCAxOiBtZXNzYWdlIHNlZ21lbnQKY29tcGlsZXIubWlzYy5pbmZlci52YXJhcmdzLmFyZ3VtZW50Lm1pc21hdGNoPVx1NTc4Qlx1NTkwOVx1NjU3MHswfVx1MzA5Mlx1NjNBOFx1OEFENlx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5M1xuKFx1NTNFRlx1NTkwOVx1NUYxNVx1NjU3MFx1MzA2RVx1NEUwRFx1NEUwMFx1ODFGNDogezF9KQoKIyAwOiB0eXBlLCAxOiBsaXN0IG9mIHR5cGUKY29tcGlsZXIubWlzYy5pbmZlcnJlZC5kby5ub3QuY29uZm9ybS50by51cHBlci5ib3VuZHM9XHU2M0E4XHU4QUQ2XHU1NzhCXHUzMDRDXHU0RTBBXHU5NjUwXHUzMDZCXHU5MDY5XHU1NDA4XHUzMDU3XHUzMDdFXHUzMDVCXHUzMDkzXG5cdTYzQThcdThBRDY6IHswfVxuXHU0RTBBXHU5NjUwOiB7MX0KCiMgMDogdHlwZSwgMTogbGlzdCBvZiB0eXBlCmNvbXBpbGVyLm1pc2MuaW5mZXJyZWQuZG8ubm90LmNvbmZvcm0udG8ubG93ZXIuYm91bmRzPVx1NjNBOFx1OEFENlx1NTc4Qlx1MzA0Q1x1NEUwQlx1OTY1MFx1MzA2Qlx1OTA2OVx1NTQwOFx1MzA1N1x1MzA3RVx1MzA1Qlx1MzA5M1xuXHU2M0E4XHU4QUQ2OiB7MH1cblx1NEUwQlx1OTY1MDogezF9CgojIDA6IHR5cGUsIDE6IGxpc3Qgb2YgdHlwZQpjb21waWxlci5taXNjLmluZmVycmVkLmRvLm5vdC5jb25mb3JtLnRvLmVxLmJvdW5kcz1cdTYzQThcdThBRDZcdTU3OEJcdTMwNENcdTdCNDlcdTRGQTFcdTUyMzZcdTdEMDRcdTMwNkJcdTkwNjlcdTU0MDhcdTMwNTdcdTMwN0VcdTMwNUJcdTMwOTNcblx1NjNBOFx1OEFENjogezB9XG5cdTdCNDlcdTRGQTFcdTUyMzZcdTdEMDQ6IHsxfQoKIyAwOiBzeW1ib2wKY29tcGlsZXIubWlzYy5kaWFtb25kPXswfTw+CgojIDA6IHR5cGUKY29tcGlsZXIubWlzYy5kaWFtb25kLm5vbi5nZW5lcmljPVx1OTc1RVx1NkM0RVx1NzUyOFx1MzBBRlx1MzBFOVx1MzBCOXswfVx1MzA2NycnPD4nJ1x1MzA5Mlx1NEY3Rlx1NzUyOFx1MzA1OVx1MzA4Qlx1MzA1M1x1MzA2OFx1MzA2Rlx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5MwoKIyAwOiBsaXN0IG9mIHR5cGUsIDE6IG1lc3NhZ2Ugc2VnbWVudApjb21waWxlci5taXNjLmRpYW1vbmQuaW52YWxpZC5hcmc9ezF9XHUzMDZCXHUzMDY0XHUzMDQ0XHUzMDY2XHU2M0E4XHU1QjlBXHUzMDU1XHUzMDhDXHUzMDVGXHU1NzhCXHU1RjE1XHU2NTcwezB9XHUzMDZGXHUzMDUzXHUzMDZFXHUzMEIzXHUzMEYzXHUzMEM2XHUzMEFEXHUzMEI5XHUzMEM4XHUzMDY3XHUzMDZGXHU4QTMxXHU1M0VGXHUzMDU1XHUzMDhDXHUzMDdFXHUzMDVCXHUzMDkzXG5cdTYzQThcdThBRDZcdTVGMTVcdTY1NzBcdTMwNkZcdTdGNzJcdTU0MERcdTVDNUVcdTYwMjdcdTMwNkJcdTg4NjhcdTczRkVcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTMKCiMgMDogbGlzdCBvZiB0eXBlLCAxOiBtZXNzYWdlIHNlZ21lbnQKY29tcGlsZXIubWlzYy5kaWFtb25kLmludmFsaWQuYXJncz17MX1cdTMwNkJcdTMwNjRcdTMwNDRcdTMwNjZcdTYzQThcdTVCOUFcdTMwNTVcdTMwOENcdTMwNUZcdTU3OEJcdTVGMTVcdTY1NzB7MH1cdTMwNkZcdTMwNTNcdTMwNkVcdTMwQjNcdTMwRjNcdTMwQzZcdTMwQURcdTMwQjlcdTMwQzhcdTMwNjdcdTMwNkZcdThBMzFcdTUzRUZcdTMwNTVcdTMwOENcdTMwN0VcdTMwNUJcdTMwOTNcblx1NjNBOFx1OEFENlx1NUYxNVx1NjU3MFx1MzA2Rlx1N0Y3Mlx1NTQwRFx1NUM1RVx1NjAyN1x1MzA2Qlx1ODg2OFx1NzNGRVx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5MwoKIyAwOiB1bnVzZWQKY29tcGlsZXIubWlzYy5kaWFtb25kLmFuZC5leHBsaWNpdC5wYXJhbXM9XHUzMEIzXHUzMEYzXHUzMEI5XHUzMEM4XHUzMEU5XHUzMEFGXHUzMEJGXHUzMDZFXHU2NjBFXHU3OTNBXHU3Njg0XHUzMDZBXHU1NzhCXHUzMEQxXHUzMEU5XHUzMEUxXHUzMEZDXHUzMEJGXHUzMDY3XHUzMDZGJyc8PicnXHUzMDkyXHU0RjdGXHU3NTI4XHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzCgojIDA6IHVudXNlZApjb21waWxlci5taXNjLm1yZWYuaW5mZXIuYW5kLmV4cGxpY2l0LnBhcmFtcz1cdTMwQjNcdTMwRjNcdTMwQjlcdTMwQzhcdTMwRTlcdTMwQUZcdTMwQkZcdTMwNkVcdTY2MEVcdTc5M0FcdTc2ODRcdTMwNkFcdTU3OEJcdTMwRDFcdTMwRTlcdTMwRTFcdTMwRkNcdTMwQkZcdTMwNjdcdTMwNkZyYXdcdTMwQjNcdTMwRjNcdTMwQjlcdTMwQzhcdTMwRTlcdTMwQUZcdTMwQkZcdTUzQzJcdTcxNjdcdTMwOTJcdTRGN0ZcdTc1MjhcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTMKCiMgMDogdHlwZSwgMTogbGlzdCBvZiB0eXBlCmNvbXBpbGVyLm1pc2MuZXhwbGljaXQucGFyYW0uZG8ubm90LmNvbmZvcm0udG8uYm91bmRzPVx1NjYwRVx1NzkzQVx1NzY4NFx1MzA2QVx1NTc4Qlx1NUYxNVx1NjU3MHswfVx1MzA2Rlx1MzAwMVx1NUJBM1x1OEEwMFx1MzA1NVx1MzA4Q1x1MzA1Rlx1NTg4M1x1NzU0Q3sxfVx1MzA2Qlx1OTA2OVx1NTQwOFx1MzA1N1x1MzA3RVx1MzA1Qlx1MzA5MwoKY29tcGlsZXIubWlzYy5hcmcubGVuZ3RoLm1pc21hdGNoPVx1NUI5Rlx1NUYxNVx1NjU3MFx1MzBFQVx1MzBCOVx1MzBDOFx1MzA2OFx1NEVFRVx1NUYxNVx1NjU3MFx1MzBFQVx1MzBCOVx1MzBDOFx1MzA2RVx1OTU3N1x1MzA1NVx1MzA0Q1x1NzU3MFx1MzA2QVx1MzA4QVx1MzA3RVx1MzA1OQoKIyAwOiBzdHJpbmcKY29tcGlsZXIubWlzYy53cm9uZy5udW1iZXIudHlwZS5hcmdzPVx1NTc4Qlx1NUYxNVx1NjU3MFx1MzA2RVx1NjU3MFx1MzA0Q1x1NEUwRFx1NkI2M1x1MzA2N1x1MzA1OVx1MzAwMnswfVx1NTAwQlx1NUZDNVx1ODk4MVx1MzA2N1x1MzA1OQoKIyAwOiBtZXNzYWdlIHNlZ21lbnQKY29tcGlsZXIubWlzYy5uby5jb25mb3JtaW5nLmFzc2lnbm1lbnQuZXhpc3RzPVx1NUYxNVx1NjU3MFx1MzA2RVx1NEUwRFx1NEUwMFx1ODFGNDogezB9CgojIDA6IG1lc3NhZ2Ugc2VnbWVudApjb21waWxlci5taXNjLnZhcmFyZ3MuYXJndW1lbnQubWlzbWF0Y2g9XHU1M0VGXHU1OTA5XHU1RjE1XHU2NTcwXHUzMDZFXHU0RTBEXHU0RTAwXHU4MUY0OiB7MH0KCiMjIyMjCgojIDA6IHN5bWJvbCBvciB0eXBlLCAxOiBmaWxlIG5hbWUKY29tcGlsZXIud2Fybi5hdXhpbGlhcnkuY2xhc3MuYWNjZXNzZWQuZnJvbS5vdXRzaWRlLm9mLml0cy5zb3VyY2UuZmlsZT17MX1cdTMwNkVcdTg4RENcdTUyQTlcdTMwQUZcdTMwRTlcdTMwQjl7MH1cdTMwNkJcdTMwQkRcdTMwRkNcdTMwQjlcdTMwRkJcdTMwRDVcdTMwQTFcdTMwQTRcdTMwRUJcdTU5MTZcdTMwNEJcdTMwODlcdTMwQTJcdTMwQUZcdTMwQkJcdTMwQjlcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTMKCiMjIFRoZSBmaXJzdCBhcmd1bWVudCAoezB9KSBpcyBhICJraW5kbmFtZSIuCiMgMDogc3ltYm9sIGtpbmQsIDE6IHN5bWJvbCwgMjogc3ltYm9sCmNvbXBpbGVyLmVyci5hYnN0cmFjdC5jYW50LmJlLmFjY2Vzc2VkLmRpcmVjdGx5PVx1NjJCRFx1OEM2MXswfVx1MzA2N1x1MzA0Mlx1MzA4QnsxfSh7Mn1cdTUxODUpXHUzMDZCXHU3NkY0XHU2M0E1XHUzMEEyXHUzMEFGXHUzMEJCXHUzMEI5XHUzMDU5XHUzMDhCXHUzMDUzXHUzMDY4XHUzMDZGXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzCgojIyBUaGUgZmlyc3QgYXJndW1lbnQgKHswfSkgaXMgYSAia2luZG5hbWUiLgojIDA6IHN5bWJvbCBraW5kLCAxOiBzeW1ib2wKY29tcGlsZXIuZXJyLm5vbi1zdGF0aWMuY2FudC5iZS5yZWY9c3RhdGljXHUzMDY3XHUzMDZBXHUzMDQ0ezB9IHsxfVx1MzA5MnN0YXRpY1x1MzBCM1x1MzBGM1x1MzBDNlx1MzBBRFx1MzBCOVx1MzBDOFx1MzA0Qlx1MzA4OVx1NTNDMlx1NzE2N1x1MzA1OVx1MzA4Qlx1MzA1M1x1MzA2OFx1MzA2Rlx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5MwoKIyAwOiBzeW1ib2wga2luZCwgMTogc3ltYm9sCmNvbXBpbGVyLm1pc2MuYmFkLnN0YXRpYy5tZXRob2QuaW4udW5ib3VuZC5sb29rdXA9XHU5NzVFXHUzMEQwXHUzMEE0XHUzMEYzXHUzMEM5XHU2OTFDXHU3RDIyXHUzMDY3XHU0RTg4XHU2NzFGXHUzMDU3XHUzMDZBXHUzMDQ0XHU5NzU5XHU3Njg0XHUzMDZBezB9IHsxfVx1MzA0Q1x1ODk4Qlx1MzA2NFx1MzA0Qlx1MzA4QVx1MzA3RVx1MzA1N1x1MzA1RgoKIyAwOiBzeW1ib2wga2luZCwgMTogc3ltYm9sCmNvbXBpbGVyLm1pc2MuYmFkLmluc3RhbmNlLm1ldGhvZC5pbi51bmJvdW5kLmxvb2t1cD1cdTk3NUVcdTMwRDBcdTMwQTRcdTMwRjNcdTMwQzlcdTY5MUNcdTdEMjJcdTMwNjdcdTRFODhcdTY3MUZcdTMwNTdcdTMwNkFcdTMwNDRcdTMwQTRcdTMwRjNcdTMwQjlcdTMwQkZcdTMwRjNcdTMwQjl7MH0gezF9XHUzMDRDXHU4OThCXHUzMDY0XHUzMDRCXHUzMDhBXHUzMDdFXHUzMDU3XHUzMDVGCgojIDA6IHN5bWJvbCBraW5kLCAxOiBzeW1ib2wKY29tcGlsZXIubWlzYy5iYWQuc3RhdGljLm1ldGhvZC5pbi5ib3VuZC5sb29rdXA9XHUzMEQwXHUzMEE0XHUzMEYzXHUzMEM5XHU2OTFDXHU3RDIyXHUzMDY3XHU0RTg4XHU2NzFGXHUzMDU3XHUzMDZBXHUzMDQ0XHU5NzU5XHU3Njg0XHUzMDZBezB9IHsxfVx1MzA0Q1x1ODk4Qlx1MzA2NFx1MzA0Qlx1MzA4QVx1MzA3RVx1MzA1N1x1MzA1RgoKIyMgQm90aCBhcmd1bWVudHMgKHswfSwgezF9KSBhcmUgImtpbmRuYW1lInMuICB7MH0gaXMgYSBjb21tYS1zZXBhcmF0ZWQgbGlzdAojIyBvZiBraW5kbmFtZXMgKHRoZSBsaXN0IHNob3VsZCBiZSBpZGVudGljYWwgdG8gdGhhdCBwcm92aWRlZCBpbiBzb3VyY2UuCmNvbXBpbGVyLmVyci51bmV4cGVjdGVkLnR5cGU9XHU0RTg4XHU2NzFGXHUzMDU3XHUzMDZBXHUzMDQ0XHU1NzhCXG5cdTY3MUZcdTVGODVcdTUwMjQ6IHswfVxuXHU2OTFDXHU1MUZBXHU1MDI0OiAgICB7MX0KCmNvbXBpbGVyLmVyci51bmV4cGVjdGVkLmxhbWJkYT1cdTMwNTNcdTMwNTNcdTMwNjdcdTMwNkZcdTMwRTlcdTMwRTBcdTMwQzBcdTVGMEZcdTMwNkZcdTRFODhcdTY3MUZcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNUJcdTMwOTMKCmNvbXBpbGVyLmVyci51bmV4cGVjdGVkLm1yZWY9XHUzMDUzXHUzMDUzXHUzMDY3XHUzMDZGXHUzMEUxXHUzMEJEXHUzMEMzXHUzMEM5XHU1M0MyXHU3MTY3XHUzMDZGXHU0RTg4XHU2NzFGXHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDVCXHUzMDkzCgojIyBUaGUgZmlyc3QgYXJndW1lbnQgezB9IGlzIGEgImtpbmRuYW1lIiAoZS5nLiAnY29uc3RydWN0b3InLCAnZmllbGQnLCBldGMuKQojIyBUaGUgc2Vjb25kIGFyZ3VtZW50IHsxfSBpcyB0aGUgbm9uLXJlc29sdmVkIHN5bWJvbAojIyBUaGUgdGhpcmQgYXJndW1lbnQgezJ9IGlzIGEgbGlzdCBvZiB0eXBlIHBhcmFtZXRlcnMgKG5vbi1lbXB0eSBpZiB7MX0gaXMgYSBtZXRob2QpCiMjIFRoZSBmb3VydGggYXJndW1lbnQgezN9IGlzIGEgbGlzdCBvZiBhcmd1bWVudCB0eXBlcyAobm9uLWVtcHR5IGlmIHsxfSBpcyBhIG1ldGhvZCkKIyAwOiBzeW1ib2wga2luZCwgMTogbmFtZSwgMjogdW51c2VkLCAzOiB1bnVzZWQKY29tcGlsZXIuZXJyLmNhbnQucmVzb2x2ZT1cdTMwQjdcdTMwRjNcdTMwRENcdTMwRUJcdTMwOTJcdTg5OEJcdTMwNjRcdTMwNTFcdTMwODlcdTMwOENcdTMwN0VcdTMwNUJcdTMwOTNcblx1MzBCN1x1MzBGM1x1MzBEQ1x1MzBFQjogezB9IHsxfQoKIyAwOiBzeW1ib2wga2luZCwgMTogbmFtZSwgMjogdW51c2VkLCAzOiBsaXN0IG9mIHR5cGUKY29tcGlsZXIuZXJyLmNhbnQucmVzb2x2ZS5hcmdzPVx1MzBCN1x1MzBGM1x1MzBEQ1x1MzBFQlx1MzA5Mlx1ODk4Qlx1MzA2NFx1MzA1MVx1MzA4OVx1MzA4Q1x1MzA3RVx1MzA1Qlx1MzA5M1xuXHUzMEI3XHUzMEYzXHUzMERDXHUzMEVCOiB7MH0gezF9KHszfSkKCiMgMDogc3ltYm9sIGtpbmQsIDE6IG5hbWUsIDI6IGxpc3Qgb2YgdHlwZSwgMzogbGlzdCBvZiB0eXBlCmNvbXBpbGVyLmVyci5jYW50LnJlc29sdmUuYXJncy5wYXJhbXM9XHUzMEI3XHUzMEYzXHUzMERDXHUzMEVCXHUzMDkyXHU4OThCXHUzMDY0XHUzMDUxXHUzMDg5XHUzMDhDXHUzMDdFXHUzMDVCXHUzMDkzXG5cdTMwQjdcdTMwRjNcdTMwRENcdTMwRUI6IHswfSA8ezJ9PnsxfSh7M30pCgojIyBhcmd1bWVudHMgZnJvbSB7MH0gdG8gezN9IGhhdmUgdGhlIHNhbWUgbWVhbmluZyBhcyBhYm92ZQojIyBUaGUgZmlmdGggYXJndW1lbnQgezR9IGlzIGEgbG9jYXRpb24gc3ViZGlhZ25vc3RpYyAoc2VlIGJlbG93KQojIDA6IHN5bWJvbCBraW5kLCAxOiBuYW1lLCAyOiB1bnVzZWQsIDM6IHVudXNlZCwgNDogbWVzc2FnZSBzZWdtZW50CmNvbXBpbGVyLmVyci5jYW50LnJlc29sdmUubG9jYXRpb249XHUzMEI3XHUzMEYzXHUzMERDXHUzMEVCXHUzMDkyXHU4OThCXHUzMDY0XHUzMDUxXHUzMDg5XHUzMDhDXHUzMDdFXHUzMDVCXHUzMDkzXG5cdTMwQjdcdTMwRjNcdTMwRENcdTMwRUI6ICAgezB9IHsxfVxuXHU1ODM0XHU2MjQwOiB7NH0KCiMgMDogc3ltYm9sIGtpbmQsIDE6IG5hbWUsIDI6IHVudXNlZCwgMzogbGlzdCBvZiB0eXBlLCA0OiBtZXNzYWdlIHNlZ21lbnQKY29tcGlsZXIuZXJyLmNhbnQucmVzb2x2ZS5sb2NhdGlvbi5hcmdzPVx1MzBCN1x1MzBGM1x1MzBEQ1x1MzBFQlx1MzA5Mlx1ODk4Qlx1MzA2NFx1MzA1MVx1MzA4OVx1MzA4Q1x1MzA3RVx1MzA1Qlx1MzA5M1xuXHUzMEI3XHUzMEYzXHUzMERDXHUzMEVCOiAgIHswfSB7MX0oezN9KVxuXHU1ODM0XHU2MjQwOiB7NH0KCiMgMDogc3ltYm9sIGtpbmQsIDE6IG5hbWUsIDI6IGxpc3Qgb2YgdHlwZSwgMzogbGlzdCwgNDogbWVzc2FnZSBzZWdtZW50CmNvbXBpbGVyLmVyci5jYW50LnJlc29sdmUubG9jYXRpb24uYXJncy5wYXJhbXM9XHUzMEI3XHUzMEYzXHUzMERDXHUzMEVCXHUzMDkyXHU4OThCXHUzMDY0XHUzMDUxXHUzMDg5XHUzMDhDXHUzMDdFXHUzMDVCXHUzMDkzXG5cdTMwQjdcdTMwRjNcdTMwRENcdTMwRUI6ICAgezB9IDx7Mn0+ezF9KHszfSlcblx1NTgzNFx1NjI0MDogezR9CgojIyMgRm9sbG93aW5nIGFyZSByZXBsaWNhdGVkL3VzZWQgZm9yIG1ldGhvZCByZWZlcmVuY2UgZGlhZ25vc3RpY3MKCiMgMDogc3ltYm9sIGtpbmQsIDE6IG5hbWUsIDI6IHVudXNlZCwgMzogbGlzdCBvZiB0eXBlLCA0OiBtZXNzYWdlIHNlZ21lbnQKY29tcGlsZXIubWlzYy5jYW50LnJlc29sdmUubG9jYXRpb24uYXJncz1cdTMwQjdcdTMwRjNcdTMwRENcdTMwRUJcdTMwOTJcdTg5OEJcdTMwNjRcdTMwNTFcdTMwODlcdTMwOENcdTMwN0VcdTMwNUJcdTMwOTNcblx1MzBCN1x1MzBGM1x1MzBEQ1x1MzBFQjogICB7MH0gezF9KHszfSlcblx1NTgzNFx1NjI0MDogezR9CgojIDA6IHN5bWJvbCBraW5kLCAxOiBuYW1lLCAyOiBsaXN0IG9mIHR5cGUsIDM6IGxpc3QsIDQ6IG1lc3NhZ2Ugc2VnbWVudApjb21waWxlci5taXNjLmNhbnQucmVzb2x2ZS5sb2NhdGlvbi5hcmdzLnBhcmFtcz1cdTMwQjdcdTMwRjNcdTMwRENcdTMwRUJcdTMwOTJcdTg5OEJcdTMwNjRcdTMwNTFcdTMwODlcdTMwOENcdTMwN0VcdTMwNUJcdTMwOTNcblx1MzBCN1x1MzBGM1x1MzBEQ1x1MzBFQjogICB7MH0gPHsyfT57MX0oezN9KVxuXHU1ODM0XHU2MjQwOiB7NH0KCiMjYSBsb2NhdGlvbiBzdWJkaWFnbm9zdGljIGlzIGNvbXBvc2VkIGFzIGZvbGxvd3M6CiMjIFRoZSBmaXJzdCBhcmd1bWVudCB7MH0gaXMgdGhlIGxvY2F0aW9uICJraW5kbmFtZSIgKGUuZy4gJ2NvbnN0cnVjdG9yJywgJ2ZpZWxkJywgZXRjLikKIyMgVGhlIHNlY29uZCBhcmd1bWVudCB7MX0gaXMgdGhlIGxvY2F0aW9uIG5hbWUKIyMgVGhlIHRoaXJkIGFyZ3VtZW50IHsyfSBpcyB0aGUgbG9jYXRpb24gdHlwZSAob25seSB3aGVuIHsxfSBpcyBhIHZhcmlhYmxlIG5hbWUpCgojIDA6IHN5bWJvbCBraW5kLCAxOiB0eXBlIG9yIHN5bWJvbCwgMjogdW51c2VkCmNvbXBpbGVyLm1pc2MubG9jYXRpb249ezB9IHsxfQoKIyAwOiBzeW1ib2wga2luZCwgMTogc3ltYm9sLCAyOiB0eXBlCmNvbXBpbGVyLm1pc2MubG9jYXRpb24uMT1cdTMwQkZcdTMwQTRcdTMwRDd7Mn1cdTMwNkV7MH0gezF9CgojIyBUaGUgZm9sbG93aW5nIGFyZSBhbGwgcG9zc2libGUgc3RyaW5nIGZvciAia2luZG5hbWUiLgojIyBUaGV5IHNob3VsZCBiZSBjYWxsZWQgd2hhdGV2ZXIgdGhlIEpMUyBjYWxscyB0aGVtIGFmdGVyIGl0IGJlZW4gdHJhbnNsYXRlZAojIyB0byB0aGUgYXBwcm9wcmlhdGUgbGFuZ3VhZ2UuCiMgY29tcGlsZXIubWlzYy5raW5kbmFtZS5jb25zdHJ1Y3Rvcj1cCiMgICAgIHN0YXRpYyBtZW1iZXIKY29tcGlsZXIubWlzYy5raW5kbmFtZS5hbm5vdGF0aW9uPUBpbnRlcmZhY2UKCmNvbXBpbGVyLm1pc2Mua2luZG5hbWUuY29uc3RydWN0b3I9XHUzMEIzXHUzMEYzXHUzMEI5XHUzMEM4XHUzMEU5XHUzMEFGXHUzMEJGCgpjb21waWxlci5taXNjLmtpbmRuYW1lLmVudW09XHU1MjE3XHU2MzE5Cgpjb21waWxlci5taXNjLmtpbmRuYW1lLmludGVyZmFjZT1cdTMwQTRcdTMwRjNcdTMwQkZcdTMwRDVcdTMwQTdcdTMwRkNcdTMwQjkKCmNvbXBpbGVyLm1pc2Mua2luZG5hbWUuc3RhdGljPXN0YXRpYwoKY29tcGlsZXIubWlzYy5raW5kbmFtZS50eXBlLnZhcmlhYmxlPVx1NTc4Qlx1NTkwOVx1NjU3MAoKY29tcGlsZXIubWlzYy5raW5kbmFtZS50eXBlLnZhcmlhYmxlLmJvdW5kPVx1NTc4Qlx1NTkwOVx1NjU3MFx1MzA2RVx1NTg4M1x1NzU0QwoKY29tcGlsZXIubWlzYy5raW5kbmFtZS52YXJpYWJsZT1cdTU5MDlcdTY1NzAKCmNvbXBpbGVyLm1pc2Mua2luZG5hbWUudmFsdWU9XHU1MDI0Cgpjb21waWxlci5taXNjLmtpbmRuYW1lLm1ldGhvZD1cdTMwRTFcdTMwQkRcdTMwQzNcdTMwQzkKCmNvbXBpbGVyLm1pc2Mua2luZG5hbWUuY2xhc3M9XHUzMEFGXHUzMEU5XHUzMEI5Cgpjb21waWxlci5taXNjLmtpbmRuYW1lLnBhY2thZ2U9XHUzMEQxXHUzMEMzXHUzMEIxXHUzMEZDXHUzMEI4Cgpjb21waWxlci5taXNjLmtpbmRuYW1lLm1vZHVsZT1cdTMwRTJcdTMwQjhcdTMwRTVcdTMwRkNcdTMwRUIKCmNvbXBpbGVyLm1pc2Mua2luZG5hbWUuc3RhdGljLmluaXQ9c3RhdGljXHU1MjFEXHU2NzFGXHU1MzE2XHU1QjUwCgpjb21waWxlci5taXNjLmtpbmRuYW1lLmluc3RhbmNlLmluaXQ9XHUzMEE0XHUzMEYzXHUzMEI5XHUzMEJGXHUzMEYzXHUzMEI5XHU1MjFEXHU2NzFGXHU1MzE2XHU1QjUwCgojIyMjIwoKY29tcGlsZXIubWlzYy5uby5hcmdzPVx1NUYxNVx1NjU3MFx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5MwoKIyAwOiBtZXNzYWdlIHNlZ21lbnQKY29tcGlsZXIuZXJyLm92ZXJyaWRlLnN0YXRpYz17MH1cblx1MzBBQVx1MzBGQ1x1MzBEMFx1MzBGQ1x1MzBFOVx1MzBBNFx1MzBDOVx1MzA1OVx1MzA4Qlx1MzBFMVx1MzBCRFx1MzBDM1x1MzBDOVx1MzA0Q3N0YXRpY1x1MzA2N1x1MzA1OQoKIyAwOiBtZXNzYWdlIHNlZ21lbnQsIDE6IHNldCBvZiBtb2RpZmllcgpjb21waWxlci5lcnIub3ZlcnJpZGUubWV0aD17MH1cblx1MzBBQVx1MzBGQ1x1MzBEMFx1MzBGQ1x1MzBFOVx1MzBBNFx1MzBDOVx1MzA1NVx1MzA4Q1x1MzA1Rlx1MzBFMVx1MzBCRFx1MzBDM1x1MzBDOVx1MzA2RnsxfVx1MzA2N1x1MzA1OQoKIyAwOiBtZXNzYWdlIHNlZ21lbnQsIDE6IHR5cGUKY29tcGlsZXIuZXJyLm92ZXJyaWRlLm1ldGguZG9lc250LnRocm93PXswfVxuXHUzMEFBXHUzMEZDXHUzMEQwXHUzMEZDXHUzMEU5XHUzMEE0XHUzMEM5XHUzMDU1XHUzMDhDXHUzMDVGXHUzMEUxXHUzMEJEXHUzMEMzXHUzMEM5XHUzMDZGezF9XHUzMDkyXHUzMEI5XHUzMEVEXHUzMEZDXHUzMDU3XHUzMDdFXHUzMDVCXHUzMDkzCgojIEluIHRoZSBmb2xsb3dpbmcgc3RyaW5nIHsxfSBpcyBhIHNwYWNlIHNlcGFyYXRlZCBsaXN0IG9mIEphdmEgS2V5d29yZHMsIGFzCiMgdGhleSB3b3VsZCBoYXZlIGJlZW4gZGVjbGFyZWQgaW4gdGhlIHNvdXJjZSBjb2RlCiMgMDogbWVzc2FnZSBzZWdtZW50LCAxOiBzZXQgb2YgbW9kaWZpZXIKY29tcGlsZXIuZXJyLm92ZXJyaWRlLndlYWtlci5hY2Nlc3M9ezB9XG4oezF9KVx1MzA4OFx1MzA4QVx1NUYzMVx1MzA0NFx1MzBBMlx1MzBBRlx1MzBCQlx1MzBCOVx1NkEyOVx1OTY1MFx1MzA5Mlx1NTI3Mlx1MzA4QVx1NUY1M1x1MzA2Nlx1MzA4OFx1MzA0Nlx1MzA2OFx1MzA1N1x1MzA3RVx1MzA1N1x1MzA1RgoKIyAwOiBtZXNzYWdlIHNlZ21lbnQsIDE6IHR5cGUsIDI6IHR5cGUKY29tcGlsZXIuZXJyLm92ZXJyaWRlLmluY29tcGF0aWJsZS5yZXQ9ezB9XG5cdTYyM0JcdTMwOEFcdTUwMjRcdTMwNkVcdTU3OEJ7MX1cdTMwNkZ7Mn1cdTMwNjhcdTRFOTJcdTYzREJcdTYwMjdcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTMKCiMgMDogbWVzc2FnZSBzZWdtZW50LCAxOiB0eXBlLCAyOiB0eXBlCmNvbXBpbGVyLndhcm4ub3ZlcnJpZGUudW5jaGVja2VkLnJldD17MH1cblx1NjIzQlx1MzA4QVx1NTAyNFx1MzA2RVx1NTc4Qlx1MzA2RnsxfVx1MzA0Qlx1MzA4OXsyfVx1MzA3OFx1MzA2RVx1NzEyMVx1NjkxQ1x1NjdGQlx1NTkwOVx1NjNEQlx1MzA0Q1x1NUZDNVx1ODk4MVx1MzA2N1x1MzA1OQoKIyAwOiBtZXNzYWdlIHNlZ21lbnQsIDE6IHR5cGUKY29tcGlsZXIud2Fybi5vdmVycmlkZS51bmNoZWNrZWQudGhyb3duPXswfVxuXHUzMEFBXHUzMEZDXHUzMEQwXHUzMEZDXHUzMEU5XHUzMEE0XHUzMEM5XHUzMDU1XHUzMDhDXHUzMDVGXHUzMEUxXHUzMEJEXHUzMEMzXHUzMEM5XHUzMDZGezF9XHUzMDkyXHUzMEI5XHUzMEVEXHUzMEZDXHUzMDU3XHUzMDdFXHUzMDVCXHUzMDkzCgojIDA6IHN5bWJvbApjb21waWxlci53YXJuLm92ZXJyaWRlLmVxdWFscy5idXQubm90Lmhhc2hjb2RlPVx1MzBBRlx1MzBFOVx1MzBCOXswfVx1MzA2RmVxdWFsc1x1MzA5Mlx1MzBBQVx1MzBGQ1x1MzBEMFx1MzBGQ1x1MzBFOVx1MzBBNFx1MzBDOVx1MzA1N1x1MzA3RVx1MzA1OVx1MzA0Q1x1MzAwMVx1MzA1M1x1MzA2RVx1MzBBRlx1MzBFOVx1MzBCOVx1MzA4Mlx1MzAwMVx1MzA3RVx1MzA1Rlx1MzAwMVx1MzA0NFx1MzA0Qlx1MzA2QVx1MzA4Qlx1MzBCOVx1MzBGQ1x1MzBEMVx1MzBGQ1x1MzBBRlx1MzBFOVx1MzBCOVx1MzA4Mlx1MzAwMWhhc2hDb2RlXHUzMEUxXHUzMEJEXHUzMEMzXHUzMEM5XHUzMDkyXHUzMEFBXHUzMEZDXHUzMEQwXHUzMEZDXHUzMEU5XHUzMEE0XHUzMEM5XHUzMDU3XHUzMDdFXHUzMDVCXHUzMDkzCgojIyBUaGUgZm9sbG93aW5nIGFyZSBhbGwgcG9zc2libGUgc3RyaW5ncyBmb3IgdGhlIGZpcnN0IGFyZ3VtZW50ICh7MH0pIG9mIHRoZQojIyBhYm92ZSBzdHJpbmdzLgojIDA6IHN5bWJvbCwgMTogc3ltYm9sLCAyOiBzeW1ib2wsIDM6IHN5bWJvbApjb21waWxlci5taXNjLmNhbnQub3ZlcnJpZGU9ezF9XHUzMDZFezB9XHUzMDZGezN9XHUzMDZFezJ9XHUzMDkyXHUzMEFBXHUzMEZDXHUzMEQwXHUzMEZDXHUzMEU5XHUzMEE0XHUzMEM5XHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzCgojIDA6IHN5bWJvbCwgMTogc3ltYm9sLCAyOiBzeW1ib2wsIDM6IHN5bWJvbApjb21waWxlci5taXNjLmNhbnQuaGlkZT17MX1cdTMwNkV7MH1cdTMwNkZ7M31cdTMwNkV7Mn1cdTMwOTJcdTk2QTBcdTMwNTlcdTMwNTNcdTMwNjhcdTMwNkZcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTMKCiMgMDogc3ltYm9sLCAxOiBzeW1ib2wsIDI6IHN5bWJvbCwgMzogc3ltYm9sCmNvbXBpbGVyLm1pc2MuY2FudC5pbXBsZW1lbnQ9ezF9XHUzMDZFezB9XHUzMDZGezN9XHUzMDZFezJ9XHUzMDkyXHU1QjlGXHU4OEM1XHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzCgojIDA6IHN5bWJvbCwgMTogc3ltYm9sLCAyOiBzeW1ib2wsIDM6IHN5bWJvbApjb21waWxlci5taXNjLmNsYXNoZXMud2l0aD17MX1cdTMwNkV7MH1cdTMwNkZ7M31cdTMwNkV7Mn1cdTMwNjhcdTdBRjZcdTU0MDhcdTMwNTdcdTMwN0VcdTMwNTkKCiMgMDogc3ltYm9sLCAxOiBzeW1ib2wsIDI6IHN5bWJvbCwgMzogc3ltYm9sCmNvbXBpbGVyLm1pc2MudW5jaGVja2VkLm92ZXJyaWRlPXsxfVx1MzA2RXswfVx1MzA2RnszfVx1MzA2RXsyfVx1MzA5Mlx1MzBBQVx1MzBGQ1x1MzBEMFx1MzBGQ1x1MzBFOVx1MzBBNFx1MzBDOVx1MzA1N1x1MzA3RVx1MzA1OQoKIyAwOiBzeW1ib2wsIDE6IHN5bWJvbCwgMjogc3ltYm9sLCAzOiBzeW1ib2wKY29tcGlsZXIubWlzYy51bmNoZWNrZWQuaW1wbGVtZW50PXsxfVx1MzA2RXswfVx1MzA2RnszfVx1MzA2RXsyfVx1MzA5Mlx1NUI5Rlx1ODhDNVx1MzA1N1x1MzA3RVx1MzA1OQoKIyAwOiBzeW1ib2wsIDE6IHN5bWJvbCwgMjogc3ltYm9sLCAzOiBzeW1ib2wKY29tcGlsZXIubWlzYy51bmNoZWNrZWQuY2xhc2gud2l0aD17MX1cdTMwNkV7MH1cdTMwNkZ7M31cdTMwNkV7Mn1cdTMwOTJcdTMwQUFcdTMwRkNcdTMwRDBcdTMwRkNcdTMwRTlcdTMwQTRcdTMwQzlcdTMwNTdcdTMwN0VcdTMwNTkKCiMgMDogc3ltYm9sLCAxOiBzeW1ib2wsIDI6IHN5bWJvbCwgMzogc3ltYm9sCmNvbXBpbGVyLm1pc2MudmFyYXJncy5vdmVycmlkZT17MX1cdTMwNkV7MH1cdTMwNkZ7M31cdTMwNkV7Mn1cdTMwOTJcdTMwQUFcdTMwRkNcdTMwRDBcdTMwRkNcdTMwRTlcdTMwQTRcdTMwQzlcdTMwNTdcdTMwN0VcdTMwNTkKCiMgMDogc3ltYm9sLCAxOiBzeW1ib2wsIDI6IHN5bWJvbCwgMzogc3ltYm9sCmNvbXBpbGVyLm1pc2MudmFyYXJncy5pbXBsZW1lbnQ9ezF9XHUzMDZFezB9XHUzMDZGezN9XHUzMDZFezJ9XHUzMDkyXHU1QjlGXHU4OEM1XHUzMDU3XHUzMDdFXHUzMDU5CgojIDA6IHN5bWJvbCwgMTogc3ltYm9sLCAyOiBzeW1ib2wsIDM6IHN5bWJvbApjb21waWxlci5taXNjLnZhcmFyZ3MuY2xhc2gud2l0aD17MX1cdTMwNkV7MH1cdTMwNkZ7M31cdTMwNkV7Mn1cdTMwOTJcdTMwQUFcdTMwRkNcdTMwRDBcdTMwRkNcdTMwRTlcdTMwQTRcdTMwQzlcdTMwNTdcdTMwN0VcdTMwNTkKCiMgMDogc3ltYm9sIGtpbmQsIDE6IHN5bWJvbCwgMjogc3ltYm9sLCAzOiBtZXNzYWdlIHNlZ21lbnQKY29tcGlsZXIubWlzYy5pbmFwcGxpY2FibGUubWV0aG9kPXswfSB7MX0uezJ9XHUzMDZGXHU0RjdGXHU3NTI4XHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzXG4oezN9KQoKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwojIERpYWdub3N0aWNzIGZvciBsYW5ndWFnZSBmZWF0dXJlIGNoYW5nZXMKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwoKIyAwOiBzdHJpbmcKY29tcGlsZXIuZXJyLm1vZHVsZXMubm90LnN1cHBvcnRlZC5pbi5zb3VyY2U9XHUzMEUyXHUzMEI4XHUzMEU1XHUzMEZDXHUzMEVCXHUzMDZGLXNvdXJjZSB7MH1cdTMwNjdcdTMwQjVcdTMwRERcdTMwRkNcdTMwQzhcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNUJcdTMwOTNcbihcdTMwRTJcdTMwQjhcdTMwRTVcdTMwRkNcdTMwRUJcdTMwOTJcdTRGN0ZcdTc1MjhcdTUzRUZcdTgwRkRcdTMwNkJcdTMwNTlcdTMwOEJcdTMwNkJcdTMwNkZcdTMwMDEtc291cmNlIDlcdTRFRTVcdTk2NERcdTMwOTJcdTRGN0ZcdTc1MjhcdTMwNTdcdTMwNjZcdTMwNEZcdTMwNjBcdTMwNTVcdTMwNDQpCgojIDA6IHN0cmluZwpjb21waWxlci5taXNjLmRpYW1vbmQuYW5kLmFub24uY2xhc3Mubm90LnN1cHBvcnRlZC5pbi5zb3VyY2U9LXNvdXJjZSB7MH1cdTMwNjdcdTMwNkZcdTUzM0ZcdTU0MERcdTUxODVcdTkwRThcdTMwQUZcdTMwRTlcdTMwQjlcdTMwNjcnJzw+JydcdTMwOTJcdTRGN0ZcdTc1MjhcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTNcbihcdTUzM0ZcdTU0MERcdTUxODVcdTkwRThcdTMwQUZcdTMwRTlcdTMwQjlcdTMwNjcnJzw+JydcdTMwOTJcdTRGN0ZcdTc1MjhcdTUzRUZcdTgwRkRcdTMwNkJcdTMwNTlcdTMwOEJcdTMwNkJcdTMwNkZcdTMwMDEtc291cmNlIDlcdTRFRTVcdTk2NERcdTMwOTJcdTRGN0ZcdTc1MjhcdTMwNTdcdTMwNjZcdTMwNEZcdTMwNjBcdTMwNTVcdTMwNDQpCgojIDA6IHN0cmluZwpjb21waWxlci5lcnIudW5zdXBwb3J0ZWQuYmluYXJ5LmxpdD0yXHU5MDMyXHU2NTcwXHUzMEVBXHUzMEM2XHUzMEU5XHUzMEVCXHUzMDZGLXNvdXJjZSB7MH1cdTMwNjdcdTMwQjVcdTMwRERcdTMwRkNcdTMwQzhcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNUJcdTMwOTNcbigyXHU5MDMyXHU2NTcwXHUzMEVBXHUzMEM2XHUzMEU5XHUzMEVCXHUzMDkyXHU0RjdGXHU3NTI4XHU1M0VGXHU4MEZEXHUzMDZCXHUzMDU5XHUzMDhCXHUzMDZCXHUzMDZGLXNvdXJjZSA3XHU0RUU1XHU5NjREXHUzMDkyXHU0RjdGXHU3NTI4XHUzMDU3XHUzMDY2XHUzMDRGXHUzMDYwXHUzMDU1XHUzMDQ0KQoKIyAwOiBzdHJpbmcKY29tcGlsZXIuZXJyLnVuc3VwcG9ydGVkLnVuZGVyc2NvcmUubGl0PVx1MzBFQVx1MzBDNlx1MzBFOVx1MzBFQlx1NTE4NVx1MzA2RVx1MzBBMlx1MzBGM1x1MzBDMFx1MzBGQ1x1MzBCOVx1MzBCM1x1MzBBMlx1MzA2Ri1zb3VyY2UgezB9XHUzMDY3XHUzMEI1XHUzMEREXHUzMEZDXHUzMEM4XHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDVCXHUzMDkzXG4oXHUzMEVBXHUzMEM2XHUzMEU5XHUzMEVCXHU1MTg1XHUzMDZFXHUzMEEyXHUzMEYzXHUzMEMwXHUzMEZDXHUzMEI5XHUzMEIzXHUzMEEyXHUzMDkyXHU0RjdGXHU3NTI4XHU1M0VGXHU4MEZEXHUzMDZCXHUzMDU5XHUzMDhCXHUzMDZCXHUzMDZGXHUzMDAxLXNvdXJjZSA3XHU0RUU1XHU5NjREXHUzMDkyXHU0RjdGXHU3NTI4XHUzMDU3XHUzMDY2XHUzMDRGXHUzMDYwXHUzMDU1XHUzMDQ0KQoKIyAwOiBzdHJpbmcKY29tcGlsZXIuZXJyLnRyeS53aXRoLnJlc291cmNlcy5ub3Quc3VwcG9ydGVkLmluLnNvdXJjZT10cnktd2l0aC1yZXNvdXJjZVx1MzA2Ri1zb3VyY2UgezB9XHUzMDY3XHUzMEI1XHUzMEREXHUzMEZDXHUzMEM4XHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDVCXHUzMDkzXG4odHJ5LXdpdGgtcmVzb3VyY2VcdTMwOTJcdTRGN0ZcdTc1MjhcdTUzRUZcdTgwRkRcdTMwNkJcdTMwNTlcdTMwOEJcdTMwNkJcdTMwNkZcdTMwMDEtc291cmNlIDdcdTRFRTVcdTk2NERcdTMwOTJcdTRGN0ZcdTc1MjhcdTMwNTdcdTMwNjZcdTMwNEZcdTMwNjBcdTMwNTVcdTMwNDQpCgojIDA6IHN0cmluZwpjb21waWxlci5lcnIudmFyLmluLnRyeS53aXRoLnJlc291cmNlcy5ub3Quc3VwcG9ydGVkLmluLnNvdXJjZT10cnktd2l0aC1yZXNvdXJjZVx1NTE4NVx1MzA2RVx1NTkwOVx1NjU3MFx1MzA2Ri1zb3VyY2UgezB9XHUzMDY3XHUzMEI1XHUzMEREXHUzMEZDXHUzMEM4XHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDVCXHUzMDkzXG4odHJ5LXdpdGgtcmVzb3VyY2VcdTMwNjdcdTU5MDlcdTY1NzBcdTMwOTJcdTRGN0ZcdTc1MjhcdTUzRUZcdTgwRkRcdTMwNkJcdTMwNTlcdTMwOEJcdTMwNkJcdTMwNkZcdTMwMDEtc291cmNlIDlcdTRFRTVcdTk2NERcdTMwOTJcdTRGN0ZcdTc1MjhcdTMwNTdcdTMwNjZcdTMwNEZcdTMwNjBcdTMwNTVcdTMwNDQpCgpjb21waWxlci53YXJuLnVuZGVyc2NvcmUuYXMuaWRlbnRpZmllcj1cdTMwRUFcdTMwRUFcdTMwRkNcdTMwQjk5XHUzMDRCXHUzMDg5JydfJydcdTMwNkZcdTMwQURcdTMwRkNcdTMwRUZcdTMwRkNcdTMwQzlcdTMwNkFcdTMwNkVcdTMwNjdcdThCNThcdTUyMjVcdTVCNTBcdTMwNjhcdTMwNTdcdTMwNjZcdTRGN0ZcdTc1MjhcdTMwNTlcdTMwOEJcdTMwNTNcdTMwNjhcdTMwNkZcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTMKCmNvbXBpbGVyLmVyci51bmRlcnNjb3JlLmFzLmlkZW50aWZpZXI9XHUzMEVBXHUzMEVBXHUzMEZDXHUzMEI5OVx1MzA0Qlx1MzA4OScnXycnXHUzMDZGXHUzMEFEXHUzMEZDXHUzMEVGXHUzMEZDXHUzMEM5XHUzMDZBXHUzMDZFXHUzMDY3XHU4QjU4XHU1MjI1XHU1QjUwXHUzMDY4XHUzMDU3XHUzMDY2XHU0RjdGXHU3NTI4XHUzMDU5XHUzMDhCXHUzMDUzXHUzMDY4XHUzMDZGXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzCgpjb21waWxlci5lcnIudW5kZXJzY29yZS5hcy5pZGVudGlmaWVyLmluLmxhbWJkYT0nJ18nJ1x1MzA0Q1x1OEI1OFx1NTIyNVx1NUI1MFx1MzA2OFx1MzA1N1x1MzA2Nlx1NEY3Rlx1NzUyOFx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1OVxuKFx1MzBFOVx1MzBFMFx1MzBDMFx1MzBGQlx1MzBEMVx1MzBFOVx1MzBFMVx1MzBGQ1x1MzBCRlx1MzA2N1x1MzA2RicnXycnXHUzMDkyXHU4QjU4XHU1MjI1XHU1QjUwXHUzMDY4XHUzMDU3XHUzMDY2XHU0RjdGXHU3NTI4XHUzMDU5XHUzMDhCXHUzMDUzXHUzMDY4XHUzMDZGXHU3OTgxXHU2QjYyXHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5KQoKY29tcGlsZXIuZXJyLmVudW0uYXMuaWRlbnRpZmllcj1cdTMwRUFcdTMwRUFcdTMwRkNcdTMwQjk1XHUzMDRCXHUzMDg5JydlbnVtJ1x1MzA2Rlx1MzBBRFx1MzBGQ1x1MzBFRlx1MzBGQ1x1MzBDOVx1MzA2QVx1MzA2RVx1MzA2N1x1OEI1OFx1NTIyNVx1NUI1MFx1MzA2OFx1MzA1N1x1MzA2Nlx1NEY3Rlx1NzUyOFx1MzA1OVx1MzA4Qlx1MzA1M1x1MzA2OFx1MzA2Rlx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5MwoKY29tcGlsZXIuZXJyLmFzc2VydC5hcy5pZGVudGlmaWVyPVx1MzBFQVx1MzBFQVx1MzBGQ1x1MzBCOTEuNFx1MzA0Qlx1MzA4OScnYXNzZXJ0JydcdTMwNkZcdTMwQURcdTMwRkNcdTMwRUZcdTMwRkNcdTMwQzlcdTMwNkFcdTMwNkVcdTMwNjdcdThCNThcdTUyMjVcdTVCNTBcdTMwNjhcdTMwNTdcdTMwNjZcdTRGN0ZcdTc1MjhcdTMwNTlcdTMwOEJcdTMwNTNcdTMwNjhcdTMwNkZcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTMKCiMgVE9ETyAzMDg6IG1ha2UgYSBiZXR0ZXIgZXJyb3IgbWVzc2FnZQpjb21waWxlci5lcnIudGhpcy5hcy5pZGVudGlmaWVyPVx1MzBFQVx1MzBFQVx1MzBGQ1x1MzBCOThcdTMwNEJcdTMwODknJ3RoaXMnJ1x1MzA2Rlx1NTNEN1x1NEZFMVx1MzBCRlx1MzBBNFx1MzBEN1x1MzA2RVx1MzBEMVx1MzBFOVx1MzBFMVx1MzBGQ1x1MzBCRlx1NTQwRFx1MzA2OFx1MzA1N1x1MzA2Nlx1MzA2RVx1MzA3Rlx1OEEzMVx1NTNFRlx1MzA1NVx1MzA4Q1x1MzAwMVx1NjcwMFx1NTIxRFx1MzA2RVx1MzBEMVx1MzBFOVx1MzBFMVx1MzBGQ1x1MzBCRlx1MzA2Qlx1MzA1OVx1MzA4Qlx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OQoKIyAwOiBzeW1ib2wKY29tcGlsZXIuZXJyLnJlY2VpdmVyLnBhcmFtZXRlci5ub3QuYXBwbGljYWJsZS5jb25zdHJ1Y3Rvci50b3BsZXZlbC5jbGFzcz1cdTUzRDdcdTUzRDZcdTMwOEFcdTUwNzRcdTMwRDFcdTMwRTlcdTMwRTFcdTMwRkNcdTMwQkZcdTMwNkZcdTY3MDBcdTRFMEFcdTRGNERcdTMwRUNcdTMwRDlcdTMwRUJcdTMwRkJcdTMwQUZcdTMwRTlcdTMwQjlcdTMwNkVcdTMwQjNcdTMwRjNcdTMwQjlcdTMwQzhcdTMwRTlcdTMwQUZcdTMwQkZcdTMwNkJcdTkwNjlcdTc1MjhcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTMKCiMgVE9ETyAzMDg6IG1ha2UgYSBiZXR0ZXIgZXJyb3IgbWVzc2FnZQojIDA6IHN5bWJvbApjb21waWxlci5lcnIuY2FudC50eXBlLmFubm90YXRlLnNjb3BpbmcuMT1cdTMwQjlcdTMwQjNcdTMwRkNcdTMwRDdcdTMwRkJcdTMwQjNcdTMwRjNcdTMwQjlcdTMwQzhcdTMwRTlcdTMwQUZcdTMwQzhcdTMwOTJcdTU3OEJcdTRGN0ZcdTc1MjhcdTZDRThcdTkxQzhcdTMwNjdcdTZDRThcdTkxQzhcdTRFRDhcdTMwNTFcdTMwNTlcdTMwOEJcdTMwNTNcdTMwNjhcdTMwNkZcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTM6IHswfQoKIyBUT0RPIDMwODogbWFrZSBhIGJldHRlciBlcnJvciBtZXNzYWdlCiMgMDogbGlzdCBvZiBzeW1ib2wKY29tcGlsZXIuZXJyLmNhbnQudHlwZS5hbm5vdGF0ZS5zY29waW5nPVx1MzBCOVx1MzBCM1x1MzBGQ1x1MzBEN1x1MzBGQlx1MzBCM1x1MzBGM1x1MzBCOVx1MzBDOFx1MzBFOVx1MzBBRlx1MzBDOFx1MzA5Mlx1NTc4Qlx1NEY3Rlx1NzUyOFx1NkNFOFx1OTFDOFx1MzA2N1x1NkNFOFx1OTFDOFx1NEVEOFx1MzA1MVx1MzA1OVx1MzA4Qlx1MzA1M1x1MzA2OFx1MzA2Rlx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5MzogezB9CgojIDA6IHR5cGUsIDE6IHR5cGUKY29tcGlsZXIuZXJyLmluY29ycmVjdC5yZWNlaXZlci5uYW1lPVx1NTNEN1x1NTNENlx1MzA4QVx1NTA3NFx1MzA2RVx1NTQwRFx1NTI0RFx1MzA0Q1x1MzAwMVx1NTMwNVx1NTQyQlx1MzA1OVx1MzA4Qlx1MzBBRlx1MzBFOVx1MzBCOVx1MzBGQlx1MzBCRlx1MzBBNFx1MzBEN1x1MzA2OFx1NEUwMFx1ODFGNFx1MzA1N1x1MzA3RVx1MzA1Qlx1MzA5M1xuXHU1RkM1XHU5ODA4OiB7MH1cblx1NjkxQ1x1NTFGQTogezF9CgojIDA6IHR5cGUsIDE6IHR5cGUKY29tcGlsZXIuZXJyLmluY29ycmVjdC5yZWNlaXZlci50eXBlPVx1NTNEN1x1NTNENlx1MzA4QVx1NTA3NFx1MzA2RVx1MzBCRlx1MzBBNFx1MzBEN1x1MzA0Q1x1MzAwMVx1NTMwNVx1NTQyQlx1MzA1OVx1MzA4Qlx1MzBBRlx1MzBFOVx1MzBCOVx1MzBGQlx1MzBCRlx1MzBBNFx1MzBEN1x1MzA2OFx1NEUwMFx1ODFGNFx1MzA1N1x1MzA3RVx1MzA1Qlx1MzA5M1xuXHU1RkM1XHU5ODA4OiB7MH1cblx1NjkxQ1x1NTFGQTogezF9CgojIDA6IHR5cGUsIDE6IHR5cGUKY29tcGlsZXIuZXJyLmluY29ycmVjdC5jb25zdHJ1Y3Rvci5yZWNlaXZlci50eXBlPVx1NTNEN1x1NTNENlx1MzA4QVx1NTA3NFx1MzA2RVx1MzBCRlx1MzBBNFx1MzBEN1x1MzA0Q1x1MzAwMVx1NTMwNVx1NTQyQlx1MzA1OVx1MzA4Qlx1NTkxNlx1OTBFOFx1MzBBRlx1MzBFOVx1MzBCOVx1MzBGQlx1MzBCRlx1MzBBNFx1MzBEN1x1MzA2OFx1NEUwMFx1ODFGNFx1MzA1N1x1MzA3RVx1MzA1Qlx1MzA5M1xuXHU1RkM1XHU5ODA4OiB7MH1cblx1NjkxQ1x1NTFGQTogezF9CgojIDA6IHR5cGUsIDE6IHR5cGUKY29tcGlsZXIuZXJyLmluY29ycmVjdC5jb25zdHJ1Y3Rvci5yZWNlaXZlci5uYW1lPVx1NTNEN1x1NTNENlx1MzA4QVx1NTA3NFx1MzA2RVx1NTQwRFx1NTI0RFx1MzA0Q1x1MzAwMVx1NTMwNVx1NTQyQlx1MzA1OVx1MzA4Qlx1NTkxNlx1OTBFOFx1MzBBRlx1MzBFOVx1MzBCOVx1MzBGQlx1MzBCRlx1MzBBNFx1MzBEN1x1MzA2OFx1NEUwMFx1ODFGNFx1MzA1N1x1MzA3RVx1MzA1Qlx1MzA5M1xuXHU1RkM1XHU5ODA4OiB7MH1cblx1NjkxQ1x1NTFGQTogezF9Cgpjb21waWxlci5lcnIubm8uYW5ub3RhdGlvbnMub24uZG90LmNsYXNzPVx1NkNFOFx1OTFDOFx1MzA2Rlx1MzBBRlx1MzBFOVx1MzBCOVx1MzBGQlx1MzBFQVx1MzBDNlx1MzBFOVx1MzBFQlx1MzA2RVx1MzBCRlx1MzBBNFx1MzBEN1x1MzA2N1x1OEEzMVx1NTNFRlx1MzA1NVx1MzA4Q1x1MzA3RVx1MzA1Qlx1MzA5MwoKIyAwOiBzdHJpbmcKY29tcGlsZXIuZXJyLnR5cGUuYW5ub3RhdGlvbnMubm90LnN1cHBvcnRlZC5pbi5zb3VyY2U9XHUzMEJGXHUzMEE0XHUzMEQ3XHU2Q0U4XHU5MUM4XHUzMDZGLXNvdXJjZSB7MH1cdTMwNjdcdTMwQjVcdTMwRERcdTMwRkNcdTMwQzhcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNUJcdTMwOTNcbihcdTMwQkZcdTMwQTRcdTMwRDdcdTZDRThcdTkxQzhcdTMwOTJcdTRGN0ZcdTc1MjhcdTUzRUZcdTgwRkRcdTMwNkJcdTMwNTlcdTMwOEJcdTMwNkJcdTMwNkZcdTMwMDEtc291cmNlIDhcdTRFRTVcdTRFMEFcdTMwOTJcdTRGN0ZcdTc1MjhcdTMwNTdcdTMwNjZcdTMwNEZcdTMwNjBcdTMwNTVcdTMwNDQpCgojIDA6IHN0cmluZwpjb21waWxlci5lcnIuYW5ub3RhdGlvbnMuYWZ0ZXIudHlwZS5wYXJhbXMubm90LnN1cHBvcnRlZC5pbi5zb3VyY2U9XHUzMEUxXHUzMEJEXHUzMEMzXHUzMEM5XHUzMEZCXHUzMEJGXHUzMEE0XHUzMEQ3XHUzMEZCXHUzMEQxXHUzMEU5XHUzMEUxXHUzMEZDXHUzMEJGXHUzMDZFXHU1RjhDXHUzMDZFXHU2Q0U4XHU5MUM4XHUzMDZGLXNvdXJjZSB7MH1cdTMwNjdcdTMwQjVcdTMwRERcdTMwRkNcdTMwQzhcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNUJcdTMwOTNcbihcdTMwRTFcdTMwQkRcdTMwQzNcdTMwQzlcdTMwRkJcdTMwQkZcdTMwQTRcdTMwRDdcdTMwRkJcdTMwRDFcdTMwRTlcdTMwRTFcdTMwRkNcdTMwQkZcdTMwNkVcdTVGOENcdTMwNkVcdTZDRThcdTkxQzhcdTMwOTJcdTRGN0ZcdTc1MjhcdTUzRUZcdTgwRkRcdTMwNkJcdTMwNTlcdTMwOEJcdTMwNkJcdTMwNkZcdTMwMDEtc291cmNlIDhcdTRFRTVcdTRFMEFcdTMwOTJcdTRGN0ZcdTc1MjhcdTMwNTdcdTMwNjZcdTMwNEZcdTMwNjBcdTMwNTVcdTMwNDQpCgojIDA6IHN0cmluZwpjb21waWxlci5lcnIucmVwZWF0YWJsZS5hbm5vdGF0aW9ucy5ub3Quc3VwcG9ydGVkLmluLnNvdXJjZT1cdTdFNzBcdThGRDRcdTMwNTdcdTZDRThcdTkxQzhcdTMwNkYtc291cmNlIHswfVx1MzA2N1x1MzBCNVx1MzBERFx1MzBGQ1x1MzBDOFx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1Qlx1MzA5M1xuKFx1N0U3MFx1OEZENFx1MzA1N1x1NkNFOFx1OTFDOFx1MzA5Mlx1NEY3Rlx1NzUyOFx1NTNFRlx1ODBGRFx1MzA2Qlx1MzA1OVx1MzA4Qlx1MzA2Qlx1MzA2Rlx1MzAwMS1zb3VyY2UgOFx1NEVFNVx1NEUwQVx1MzA5Mlx1NEY3Rlx1NzUyOFx1MzA1N1x1MzA2Nlx1MzA0Rlx1MzA2MFx1MzA1NVx1MzA0NCkKCiMgMDogc3RyaW5nCmNvbXBpbGVyLmVyci5kaWFtb25kLm5vdC5zdXBwb3J0ZWQuaW4uc291cmNlPVx1MzBDMFx1MzBBNFx1MzBFNFx1MzBFMlx1MzBGM1x1MzBDOVx1NkYxNFx1N0I5N1x1NUI1MFx1MzA2Ri1zb3VyY2UgezB9XHUzMDY3XHUzMEI1XHUzMEREXHUzMEZDXHUzMEM4XHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDVCXHUzMDkzXG4oXHUzMEMwXHUzMEE0XHUzMEU0XHUzMEUyXHUzMEYzXHUzMEM5XHU2RjE0XHU3Qjk3XHU1QjUwXHUzMDkyXHU0RjdGXHU3NTI4XHU1M0VGXHU4MEZEXHUzMDZCXHUzMDU5XHUzMDhCXHUzMDZCXHUzMDZGXHUzMDAxLXNvdXJjZSA3XHU0RUU1XHU5NjREXHUzMDkyXHU0RjdGXHU3NTI4XHUzMDU3XHUzMDY2XHUzMDRGXHUzMDYwXHUzMDU1XHUzMDQ0KQoKIyAwOiBzdHJpbmcKY29tcGlsZXIuZXJyLm11bHRpY2F0Y2gubm90LnN1cHBvcnRlZC5pbi5zb3VyY2U9XHU4OTA3XHU2NTcwY2F0Y2hcdTY1ODdcdTMwNkYtc291cmNlIHswfVx1MzA2N1x1MzBCNVx1MzBERFx1MzBGQ1x1MzBDOFx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1Qlx1MzA5M1xuKFx1ODkwN1x1NjU3MGNhdGNoXHU2NTg3XHUzMDkyXHU0RjdGXHU3NTI4XHU1M0VGXHU4MEZEXHUzMDZCXHUzMDU5XHUzMDhCXHUzMDZCXHUzMDZGXHUzMDAxLXNvdXJjZSA3XHU0RUU1XHU5NjREXHUzMDkyXHU0RjdGXHU3NTI4XHUzMDU3XHUzMDY2XHUzMDRGXHUzMDYwXHUzMDU1XHUzMDQ0KQoKIyAwOiBzdHJpbmcKY29tcGlsZXIuZXJyLnN0cmluZy5zd2l0Y2gubm90LnN1cHBvcnRlZC5pbi5zb3VyY2U9c3dpdGNoXHU1MTg1XHUzMDZFXHU2NTg3XHU1QjU3XHU1MjE3XHUzMDZGLXNvdXJjZSB7MH1cdTMwNjdcdTMwQjVcdTMwRERcdTMwRkNcdTMwQzhcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNUJcdTMwOTNcbihzd2l0Y2hcdTUxODVcdTMwNkVcdTY1ODdcdTVCNTdcdTUyMTdcdTMwOTJcdTRGN0ZcdTc1MjhcdTUzRUZcdTgwRkRcdTMwNkJcdTMwNTlcdTMwOEJcdTMwNkJcdTMwNkZcdTMwMDEtc291cmNlIDdcdTRFRTVcdTk2NERcdTMwOTJcdTRGN0ZcdTc1MjhcdTMwNTdcdTMwNjZcdTMwNEZcdTMwNjBcdTMwNTVcdTMwNDQpCgojIDA6IHN0cmluZwpjb21waWxlci5lcnIubGFtYmRhLm5vdC5zdXBwb3J0ZWQuaW4uc291cmNlPVx1MzBFOVx1MzBFMFx1MzBDMFx1NUYwRlx1MzA2Ri1zb3VyY2UgezB9XHUzMDY3XHUzMEI1XHUzMEREXHUzMEZDXHUzMEM4XHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDVCXHUzMDkzXG4oXHUzMEU5XHUzMEUwXHUzMEMwXHU1RjBGXHUzMDkyXHU0RjdGXHU3NTI4XHU1M0VGXHU4MEZEXHUzMDZCXHUzMDU5XHUzMDhCXHUzMDZCXHUzMDZGXHUzMDAxLXNvdXJjZSA4XHU0RUU1XHU0RTBBXHUzMDkyXHU0RjdGXHU3NTI4XHUzMDU3XHUzMDY2XHUzMDRGXHUzMDYwXHUzMDU1XHUzMDQ0KQoKIyAwOiBzdHJpbmcKY29tcGlsZXIuZXJyLm1ldGhvZC5yZWZlcmVuY2VzLm5vdC5zdXBwb3J0ZWQuaW4uc291cmNlPVx1MzBFMVx1MzBCRFx1MzBDM1x1MzBDOVx1NTNDMlx1NzE2N1x1MzA2Ri1zb3VyY2UgezB9XHUzMDY3XHUzMEI1XHUzMEREXHUzMEZDXHUzMEM4XHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDVCXHUzMDkzXG4oXHUzMEUxXHUzMEJEXHUzMEMzXHUzMEM5XHU1M0MyXHU3MTY3XHUzMDkyXHU0RjdGXHU3NTI4XHU1M0VGXHU4MEZEXHUzMDZCXHUzMDU5XHUzMDhCXHUzMDZCXHUzMDZGXHUzMDAxLXNvdXJjZSA4XHU0RUU1XHU0RTBBXHUzMDkyXHU0RjdGXHU3NTI4XHUzMDU3XHUzMDY2XHUzMDRGXHUzMDYwXHUzMDU1XHUzMDQ0KQoKIyAwOiBzdHJpbmcKY29tcGlsZXIuZXJyLmRlZmF1bHQubWV0aG9kcy5ub3Quc3VwcG9ydGVkLmluLnNvdXJjZT1cdTMwQzdcdTMwRDVcdTMwQTlcdTMwRUJcdTMwQzhcdTMwRkJcdTMwRTFcdTMwQkRcdTMwQzNcdTMwQzlcdTMwNkYtc291cmNlIHswfVx1MzA2N1x1MzBCNVx1MzBERFx1MzBGQ1x1MzBDOFx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1Qlx1MzA5M1xuKFx1MzBDN1x1MzBENVx1MzBBOVx1MzBFQlx1MzBDOFx1MzBGQlx1MzBFMVx1MzBCRFx1MzBDM1x1MzBDOVx1MzA5Mlx1NEY3Rlx1NzUyOFx1NTNFRlx1ODBGRFx1MzA2Qlx1MzA1OVx1MzA4Qlx1MzA2Qlx1MzA2Rlx1MzAwMS1zb3VyY2UgOFx1NEVFNVx1NEUwQVx1MzA5Mlx1NEY3Rlx1NzUyOFx1MzA1N1x1MzA2Nlx1MzA0Rlx1MzA2MFx1MzA1NVx1MzA0NCkKCiMgMDogc3RyaW5nCmNvbXBpbGVyLmVyci5pbnRlcnNlY3Rpb24udHlwZXMuaW4uY2FzdC5ub3Quc3VwcG9ydGVkLmluLnNvdXJjZT1cdTMwQURcdTMwRTNcdTMwQjlcdTMwQzhcdTUxODVcdTMwNkVpbnRlcnNlY3Rpb25cdTU3OEJcdTMwNkYtc291cmNlIHswfVx1MzA2N1x1MzBCNVx1MzBERFx1MzBGQ1x1MzBDOFx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1Qlx1MzA5M1xuKFx1MzBBRFx1MzBFM1x1MzBCOVx1MzBDOFx1NTE4NVx1MzA2RWludGVyc2VjdGlvblx1NTc4Qlx1MzA5Mlx1NEY3Rlx1NzUyOFx1NTNFRlx1ODBGRFx1MzA2Qlx1MzA1OVx1MzA4Qlx1MzA2Qlx1MzA2Rlx1MzAwMS1zb3VyY2UgOFx1NEVFNVx1NEUwQVx1MzA5Mlx1NEY3Rlx1NzUyOFx1MzA1N1x1MzA2Nlx1MzA0Rlx1MzA2MFx1MzA1NVx1MzA0NCkKCiMgMDogc3RyaW5nCmNvbXBpbGVyLmVyci5zdGF0aWMuaW50Zi5tZXRob2RzLm5vdC5zdXBwb3J0ZWQuaW4uc291cmNlPXN0YXRpY1x1MzBBNFx1MzBGM1x1MzBCRlx1MzBENVx1MzBBN1x1MzBGQ1x1MzBCOVx1MzA2Ri1zb3VyY2UgezB9XHUzMDY3XHUzMEI1XHUzMEREXHUzMEZDXHUzMEM4XHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDVCXHUzMDkzXG4oc3RhdGljXHUzMEE0XHUzMEYzXHUzMEJGXHUzMEQ1XHUzMEE3XHUzMEZDXHUzMEI5XHUzMDkyXHU0RjdGXHU3NTI4XHU1M0VGXHU4MEZEXHUzMDZCXHUzMDU5XHUzMDhCXHUzMDZCXHUzMDZGXHUzMDAxLXNvdXJjZSA4XHU0RUU1XHU0RTBBXHUzMDkyXHU0RjdGXHU3NTI4XHUzMDU3XHUzMDY2XHUzMDRGXHUzMDYwXHUzMDU1XHUzMDQ0KQoKIyAwOiBzdHJpbmcKY29tcGlsZXIuZXJyLnN0YXRpYy5pbnRmLm1ldGhvZC5pbnZva2Uubm90LnN1cHBvcnRlZC5pbi5zb3VyY2U9c3RhdGljXHUzMEE0XHUzMEYzXHUzMEJGXHUzMEQ1XHUzMEE3XHUzMEZDXHUzMEI5XHUzMEZCXHUzMEUxXHUzMEJEXHUzMEMzXHUzMEM5XHU1NDdDXHU1MUZBXHUzMDU3XHUzMDZGLXNvdXJjZSB7MH1cdTMwNjdcdTMwQjVcdTMwRERcdTMwRkNcdTMwQzhcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNUJcdTMwOTNcbihzdGF0aWNcdTMwQTRcdTMwRjNcdTMwQkZcdTMwRDVcdTMwQTdcdTMwRkNcdTMwQjlcdTMwRkJcdTMwRTFcdTMwQkRcdTMwQzNcdTMwQzlcdTU0N0NcdTUxRkFcdTMwNTdcdTMwOTJcdTRGN0ZcdTc1MjhcdTUzRUZcdTgwRkRcdTMwNkJcdTMwNTlcdTMwOEJcdTMwNkJcdTMwNkZcdTMwMDEtc291cmNlIDhcdTRFRTVcdTRFMEFcdTMwOTJcdTRGN0ZcdTc1MjhcdTMwNTdcdTMwNjZcdTMwNEZcdTMwNjBcdTMwNTVcdTMwNDQpCgojIDA6IHN0cmluZwpjb21waWxlci5lcnIucHJpdmF0ZS5pbnRmLm1ldGhvZHMubm90LnN1cHBvcnRlZC5pbi5zb3VyY2U9cHJpdmF0ZVx1MzBBNFx1MzBGM1x1MzBCRlx1MzBENVx1MzBBN1x1MzBGQ1x1MzBCOVx1MzBGQlx1MzBFMVx1MzBCRFx1MzBDM1x1MzBDOVx1MzA2Ri1zb3VyY2UgezB9XHUzMDY3XHUzMEI1XHUzMEREXHUzMEZDXHUzMEM4XHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDVCXHUzMDkzXG4ocHJpdmF0ZVx1MzBBNFx1MzBGM1x1MzBCRlx1MzBENVx1MzBBN1x1MzBGQ1x1MzBCOVx1MzBGQlx1MzBFMVx1MzBCRFx1MzBDM1x1MzBDOVx1MzA5Mlx1NEY3Rlx1NzUyOFx1NTNFRlx1ODBGRFx1MzA2Qlx1MzA1OVx1MzA4Qlx1MzA2Qlx1MzA2Rlx1MzAwMS1zb3VyY2UgOVx1NEVFNVx1NEUwQVx1MzA5Mlx1NEY3Rlx1NzUyOFx1MzA1N1x1MzA2Nlx1MzA0Rlx1MzA2MFx1MzA1NVx1MzA0NCkKCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKIyBEaWFnbm9zdGljcyBmb3IgdmVyYm9zZSByZXNvbHV0aW9uCiMgdXNlZCBieSBSZXNvbHZlIChkZWJ1ZyBvbmx5KQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCgojIDA6IG51bWJlciwgMTogc3ltYm9sLCAyOiB1bnVzZWQKY29tcGlsZXIubWlzYy5hcHBsaWNhYmxlLm1ldGhvZC5mb3VuZD0jezB9XHU1MDBCXHUzMDZFXHU0RjdGXHU3NTI4XHU1M0VGXHU4MEZEXHUzMEUxXHUzMEJEXHUzMEMzXHUzMEM5XHUzMDRDXHU4OThCXHUzMDY0XHUzMDRCXHUzMDhBXHUzMDdFXHUzMDU3XHUzMDVGOiB7MX0KCiMgMDogbnVtYmVyLCAxOiBzeW1ib2wsIDI6IG1lc3NhZ2Ugc2VnbWVudApjb21waWxlci5taXNjLmFwcGxpY2FibGUubWV0aG9kLmZvdW5kLjE9I3swfVx1NTAwQlx1MzA2RVx1NEY3Rlx1NzUyOFx1NTNFRlx1ODBGRFx1MzBFMVx1MzBCRFx1MzBDM1x1MzBDOVx1MzA0Q1x1ODk4Qlx1MzA2NFx1MzA0Qlx1MzA4QVx1MzA3RVx1MzA1N1x1MzA1RjogezF9XG4oezJ9KQoKIyAwOiBudW1iZXIsIDE6IHN5bWJvbCwgMjogbWVzc2FnZSBzZWdtZW50CmNvbXBpbGVyLm1pc2Mubm90LmFwcGxpY2FibGUubWV0aG9kLmZvdW5kPSN7MH1cdTUwMEJcdTMwNkVcdTRGN0ZcdTc1MjhcdTMwNjdcdTMwNERcdTMwNkFcdTMwNDRcdTMwRTFcdTMwQkRcdTMwQzNcdTMwQzlcdTMwNENcdTg5OEJcdTMwNjRcdTMwNEJcdTMwOEFcdTMwN0VcdTMwNTdcdTMwNUY6IHsxfVxuKHsyfSkKCiMgMDogdHlwZQpjb21waWxlci5taXNjLnBhcnRpYWwuaW5zdC5zaWc9XHU5MEU4XHU1MjA2XHU3Njg0XHUzMDZCXHUzMEE0XHUzMEYzXHUzMEI5XHUzMEJGXHUzMEYzXHUzMEI5XHU1MzE2XHUzMDU1XHUzMDhDXHUzMDdFXHUzMDU3XHUzMDVGOiB7MH0KCiMgMDogbmFtZSwgMTogc3ltYm9sLCAyOiBudW1iZXIsIDM6IHN0cmluZyAobWV0aG9kIHJlc29sdXRpb24gcGhhc2UpLCA0OiBsaXN0IG9mIHR5cGUgb3IgbWVzc2FnZSBzZWdtZW50LCA1OiBsaXN0IG9mIHR5cGUgb3IgbWVzc2FnZSBzZWdtZW50CmNvbXBpbGVyLm5vdGUudmVyYm9zZS5yZXNvbHZlLm11bHRpPVx1NTc4QnsxfVx1MzA2RVx1MzBFMVx1MzBCRFx1MzBDM1x1MzBDOXswfVx1MzA5Mlx1NTAxOVx1ODhEQ3syfVx1MzA2Qlx1ODlFM1x1NkM3QVx1MzA1N1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1OVxuXHUzMEQ1XHUzMEE3XHUzMEZDXHUzMEJBOiB7M31cblx1NUI5Rlx1OTY5Qlx1MzA2RVx1NTc4QjogezR9XG5cdTU3OEJcdTVGMTVcdTY1NzA6IHs1fVxuXHU1MDE5XHU4OERDOgoKIyAwOiBuYW1lLCAxOiBzeW1ib2wsIDI6IHVudXNlZCwgMzogc3RyaW5nIChtZXRob2QgcmVzb2x1dGlvbiBwaGFzZSksIDQ6IGxpc3Qgb2YgdHlwZSBvciBtZXNzYWdlIHNlZ21lbnQsIDU6IGxpc3Qgb2YgdHlwZSBvciBtZXNzYWdlIHNlZ21lbnQKY29tcGlsZXIubm90ZS52ZXJib3NlLnJlc29sdmUubXVsdGkuMT1cdTU3OEJ7MX1cdTMwNkVcdTMwRTFcdTMwQkRcdTMwQzNcdTMwQzl7MH1cdTMwNkVcdTg5RTNcdTZDN0FcdTMwNkJcdTMwQThcdTMwRTlcdTMwRkNcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlcblx1MzBENVx1MzBBN1x1MzBGQ1x1MzBCQTogezN9XG5cdTVCOUZcdTk2OUJcdTMwNkVcdTU3OEI6IHs0fVxuXHU1NzhCXHU1RjE1XHU2NTcwOiB7NX1cblx1NTAxOVx1ODhEQzoKCiMgMDogc3ltYm9sLCAxOiB0eXBlLCAyOiB0eXBlCmNvbXBpbGVyLm5vdGUuZGVmZXJyZWQubWV0aG9kLmluc3Q9XHUzMEUxXHUzMEJEXHUzMEMzXHUzMEM5ezB9XHUzMDZFXHU5MDQ1XHU1RUY2XHUzMEE0XHUzMEYzXHUzMEI5XHUzMEJGXHUzMEYzXHUzMEI5XHU1MzE2XG5cdTMwQTRcdTMwRjNcdTMwQjlcdTMwQkZcdTMwRjNcdTMwQjlcdTUzMTZcdTMwNTVcdTMwOENcdTMwNUZcdTMwQjdcdTMwQjBcdTMwQ0RcdTMwQzFcdTMwRTM6IHsxfVxuXHUzMEJGXHUzMEZDXHUzMEIyXHUzMEMzXHUzMEM4XHU1NzhCOiB7Mn0KCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKIyBEaWFnbm9zdGljcyBmb3Igd2hlcmUgY2xhdXNlIGltcGxlbWVudGF0aW9uCiMgdXNlZCBieSB0aGUgUmljaERpYWdub3N0aWNGb3JtYXR0ZXIuCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKCmNvbXBpbGVyLm1pc2MudHlwZS5udWxsPTxudWxsPgoKIyBYI24gKHdoZXJlIG4gaXMgYW4gaW50IGlkKSBpcyBkaXNhbWJpZ3VhdGVkIHR2YXIgbmFtZQojIDA6IG5hbWUsIDE6IG51bWJlcgpjb21waWxlci5taXNjLnR5cGUudmFyPXswfSN7MX0KCiMgQ0FQI24gKHdoZXJlIG4gaXMgYW4gaW50IGlkKSBpcyBhbiBhYmJyZXZpYXRpb24gZm9yICdjYXB0dXJlZCB0eXBlJwojIDA6IG51bWJlcgpjb21waWxlci5taXNjLmNhcHR1cmVkLnR5cGU9Q0FQI3swfQoKIyA8SU5UI24+ICh3aGVyZSBuIGlzIGFuIGludCBpZCkgaXMgYW4gYWJicmV2aWF0aW9uIGZvciAnaW50ZXJzZWN0aW9uIHR5cGUnCiMgMDogbnVtYmVyCmNvbXBpbGVyLm1pc2MuaW50ZXJzZWN0aW9uLnR5cGU9SU5UI3swfQoKIyB3aGVyZSBjbGF1c2UgZm9yIGNhcHR1cmVkIHR5cGU6IGNvbnRhaW5zIHVwcGVyICgnZXh0ZW5kcyB7MX0nKSBhbmQgbG93ZXIKIyAoJ3N1cGVyIHsyfScpIGJvdW5kIGFsb25nIHdpdGggdGhlIHdpbGRjYXJkIHRoYXQgZ2VuZXJhdGVkIHRoaXMgY2FwdHVyZWQgdHlwZSAoezN9KQojIDA6IHR5cGUsIDE6IHR5cGUsIDI6IHR5cGUsIDM6IHR5cGUKY29tcGlsZXIubWlzYy53aGVyZS5jYXB0dXJlZD17M31cdTMwNkVcdTMwQURcdTMwRTNcdTMwRDdcdTMwQzFcdTMwRTNcdTMwNEJcdTMwODlcdTMwNkV7MH0gZXh0ZW5kcyB7MX0gc3VwZXI6IHsyfQoKIyBjb21wYWN0IHdoZXJlIGNsYXVzZSBmb3IgY2FwdHVyZWQgdHlwZTogY29udGFpbnMgdXBwZXIgKCdleHRlbmRzIHsxfScpIGFsb25nCiMgd2l0aCB0aGUgd2lsZGNhcmQgdGhhdCBnZW5lcmF0ZWQgdGhpcyBjYXB0dXJlZCB0eXBlICh7M30pCiMgMDogdHlwZSwgMTogdHlwZSwgMjogdW51c2VkLCAzOiB0eXBlCmNvbXBpbGVyLm1pc2Mud2hlcmUuY2FwdHVyZWQuMT17M31cdTMwNkVcdTMwQURcdTMwRTNcdTMwRDdcdTMwQzFcdTMwRTNcdTMwNEJcdTMwODlcdTMwNkV7MH0gZXh0ZW5kcyB7MX0KCiMgd2hlcmUgY2xhdXNlIGZvciB0eXBlIHZhcmlhYmxlOiBjb250YWlucyB1cHBlciBib3VuZChzKSAoJ2V4dGVuZHMgezF9JykgYWxvbmcgd2l0aAojIHRoZSBraW5kbmFtZSAoezJ9KSBhbmQgbG9jYXRpb24gKHszfSkgaW4gd2hpY2ggdGhlIHR5cGV2YXIgaGFzIGJlZW4gZGVjbGFyZWQKIyAwOiB0eXBlLCAxOiBsaXN0IG9mIHR5cGUsIDI6IHN5bWJvbCBraW5kLCAzOiBzeW1ib2wKY29tcGlsZXIubWlzYy53aGVyZS50eXBldmFyPXsyfSB7M31cdTMwNjdcdTVCQTNcdThBMDBcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwOEJ7MH0gZXh0ZW5kcyB7MX0KCiMgY29tcGFjdCB3aGVyZSBjbGF1c2UgZm9yIHR5cGUgdmFyaWFibGU6IGNvbnRhaW5zIHRoZSBraW5kbmFtZSAoezJ9KSBhbmQgbG9jYXRpb24gKHszfSkKIyBpbiB3aGljaCB0aGUgdHlwZXZhciBoYXMgYmVlbiBkZWNsYXJlZAojIDA6IHR5cGUsIDE6IGxpc3Qgb2YgdHlwZSwgMjogc3ltYm9sIGtpbmQsIDM6IHN5bWJvbApjb21waWxlci5taXNjLndoZXJlLnR5cGV2YXIuMT17Mn0gezN9XHUzMDY3XHU1QkEzXHU4QTAwXHUzMDU1XHUzMDhDXHUzMDVGezB9CgojIHdoZXJlIGNsYXVzZSBmb3IgZnJlc2ggdHlwZSB2YXJpYWJsZTogY29udGFpbnMgdXBwZXIgYm91bmQocykgKCdleHRlbmRzIHsxfScpLgojIFNpbmNlIGEgZnJlc2ggdHlwZS12YXJpYWJsZSBpcyBzeW50aGV0aWMgLSB0aGVyZSdzIG5vIGxvY2F0aW9uL2tpbmRuYW1lIGhlcmUuCiMgMDogdHlwZSwgMTogbGlzdCBvZiB0eXBlCmNvbXBpbGVyLm1pc2Mud2hlcmUuZnJlc2gudHlwZXZhcj17MH1cdTMwNkZ7MX1cdTMwOTJcdTYyRTFcdTVGMzVcdTMwNTdcdTMwN0VcdTMwNTkKCiMgd2hlcmUgY2xhdXNlIGZvciB0eXBlIHZhcmlhYmxlOiBjb250YWlucyBhbGwgdGhlIHVwcGVyIGJvdW5kKHMpICgnZXh0ZW5kcyB7MX0nKQojIG9mIHRoaXMgaW50ZXJzZWN0aW9uIHR5cGUKIyAwOiB0eXBlLCAxOiBsaXN0IG9mIHR5cGUKY29tcGlsZXIubWlzYy53aGVyZS5pbnRlcnNlY3Rpb249ezB9IGV4dGVuZHMgezF9CgojIyMgV2hlcmUgY2xhdXNlIGhlYWRlcnMgIyMjCmNvbXBpbGVyLm1pc2Mud2hlcmUuZGVzY3JpcHRpb24uY2FwdHVyZWQ9ezB9XHUzMDRDXHU2NUIwXHUzMDU3XHUzMDQ0XHU1NzhCXHU1OTA5XHU2NTcwXHUzMDZFXHU1ODM0XHU1NDA4OgoKIyAwOiBzZXQgb2YgdHlwZQpjb21waWxlci5taXNjLndoZXJlLmRlc2NyaXB0aW9uLnR5cGV2YXI9ezB9XHUzMDRDXHU1NzhCXHU1OTA5XHU2NTcwXHUzMDZFXHU1ODM0XHU1NDA4OgoKIyAwOiBzZXQgb2YgdHlwZQpjb21waWxlci5taXNjLndoZXJlLmRlc2NyaXB0aW9uLmludGVyc2VjdGlvbj17MH1cdTMwNENpbnRlcnNlY3Rpb25cdTU3OEJcdTMwNkVcdTU4MzRcdTU0MDg6CgojIDA6IHNldCBvZiB0eXBlCmNvbXBpbGVyLm1pc2Mud2hlcmUuZGVzY3JpcHRpb24uY2FwdHVyZWQuMT17MH1cdTMwNENcdTY1QjBcdTMwNTdcdTMwNDRcdTU3OEJcdTU5MDlcdTY1NzBcdTMwNkVcdTU4MzRcdTU0MDg6CgojIDA6IHNldCBvZiB0eXBlCmNvbXBpbGVyLm1pc2Mud2hlcmUuZGVzY3JpcHRpb24udHlwZXZhci4xPXswfVx1MzA0Q1x1NTc4Qlx1NTkwOVx1NjU3MFx1MzA2RVx1NTgzNFx1NTQwODoKCiMgMDogc2V0IG9mIHR5cGUKY29tcGlsZXIubWlzYy53aGVyZS5kZXNjcmlwdGlvbi5pbnRlcnNlY3Rpb24uMT17MH1cdTMwNENpbnRlcnNlY3Rpb25cdTU3OEJcdTMwNkVcdTU4MzRcdTU0MDg6CgojIyMKIyBlcnJvcnMgcmVsYXRlZCB0byBkb2MgY29tbWVudHMKCmNvbXBpbGVyLmVyci5kYy5iYWQuZW50aXR5PUhUTUxcdTMwQThcdTMwRjNcdTMwQzZcdTMwQTNcdTMwQzZcdTMwQTNcdTMwNENcdTRFMERcdTZCNjNcdTMwNjdcdTMwNTkKCmNvbXBpbGVyLmVyci5kYy5iYWQuZ3Q9Jyc+JydcdTMwNkVcdTRGN0ZcdTc1MjhcdTMwNENcdTRFMERcdTZCNjNcdTMwNjdcdTMwNTkKCmNvbXBpbGVyLmVyci5kYy5iYWQuaW5saW5lLnRhZz1cdTMwQTRcdTMwRjNcdTMwRTlcdTMwQTRcdTMwRjNcdTMwRkJcdTMwQkZcdTMwQjBcdTMwNkVcdTRGN0ZcdTc1MjhcdTMwNENcdTZCNjNcdTMwNTdcdTMwNEZcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTMKCmNvbXBpbGVyLmVyci5kYy5pZGVudGlmaWVyLmV4cGVjdGVkPVx1OEI1OFx1NTIyNVx1NUI1MFx1MzA0Q1x1NUZDNVx1ODk4MVx1MzA2N1x1MzA1OQoKY29tcGlsZXIuZXJyLmRjLm1hbGZvcm1lZC5odG1sPUhUTUxcdTMwNENcdTRFMERcdTZCNjNcdTMwNjdcdTMwNTkKCmNvbXBpbGVyLmVyci5kYy5taXNzaW5nLnNlbWljb2xvbj1cdTMwQkJcdTMwREZcdTMwQjNcdTMwRURcdTMwRjNcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTMKCmNvbXBpbGVyLmVyci5kYy5uby5jb250ZW50PVx1MzBCM1x1MzBGM1x1MzBDNlx1MzBGM1x1MzBDNFx1MzA2QVx1MzA1NwoKY29tcGlsZXIuZXJyLmRjLm5vLnRhZy5uYW1lPSdAJ1x1MzA2RVx1NUY4Q1x1MzA2Qlx1MzBCRlx1MzBCMFx1NTQwRFx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5MwoKY29tcGlsZXIuZXJyLmRjLmd0LmV4cGVjdGVkPScnPicnXHUzMDRDXHU1RkM1XHU4OTgxXHUzMDY3XHUzMDU5Cgpjb21waWxlci5lcnIuZGMucmVmLmJhZC5wYXJlbnM9XHU1M0MyXHU3MTY3XHUzMDZCJycpJydcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTMKCmNvbXBpbGVyLmVyci5kYy5yZWYuc3ludGF4LmVycm9yPVx1NTNDMlx1NzE2N1x1MzA2Qlx1NjlDQlx1NjU4N1x1MzBBOFx1MzBFOVx1MzBGQ1x1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OQoKY29tcGlsZXIuZXJyLmRjLnJlZi51bmV4cGVjdGVkLmlucHV0PVx1NEU4OFx1NjcxRlx1MzA1N1x1MzA2QVx1MzA0NFx1MzBDNlx1MzBBRFx1MzBCOVx1MzBDOFx1MzA2N1x1MzA1OQoKY29tcGlsZXIuZXJyLmRjLnVuZXhwZWN0ZWQuY29udGVudD1cdTRFODhcdTY3MUZcdTMwNTdcdTMwNkFcdTMwNDRcdTMwQjNcdTMwRjNcdTMwQzZcdTMwRjNcdTMwQzRcdTMwNjdcdTMwNTkKCmNvbXBpbGVyLmVyci5kYy51bnRlcm1pbmF0ZWQuaW5saW5lLnRhZz1cdTMwQTRcdTMwRjNcdTMwRTlcdTMwQTRcdTMwRjNcdTMwRkJcdTMwQkZcdTMwQjBcdTMwNENcdTdENDJcdTRFODZcdTMwNTdcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNUJcdTMwOTMKCmNvbXBpbGVyLmVyci5kYy51bnRlcm1pbmF0ZWQuc2lnbmF0dXJlPVx1MzBCN1x1MzBCMFx1MzBDRFx1MzBDMVx1MzBFM1x1MzA0Q1x1N0Q0Mlx1NEU4Nlx1MzA1N1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1Qlx1MzA5MwoKY29tcGlsZXIuZXJyLmRjLnVudGVybWluYXRlZC5zdHJpbmc9XHU2NTg3XHU1QjU3XHU1MjE3XHUzMDRDXHU3RDQyXHU0RTg2XHUzMDU3XHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDVCXHUzMDkzCgojIyMKIyBlcnJvcnMgcmVsYXRlZCB0byBtb2R1bGVzCgpjb21waWxlci5lcnIuZXhwZWN0ZWQubW9kdWxlPScnXHUzMEUyXHUzMEI4XHUzMEU1XHUzMEZDXHUzMEVCJydcdTMwNENcdTVGQzVcdTg5ODFcdTMwNjdcdTMwNTkKCiMgMDogc3ltYm9sCmNvbXBpbGVyLmVyci5tb2R1bGUubm90LmZvdW5kPVx1MzBFMlx1MzBCOFx1MzBFNVx1MzBGQ1x1MzBFQlx1MzA0Q1x1ODk4Qlx1MzA2NFx1MzA0Qlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5MzogezB9CgojIDA6IHN5bWJvbApjb21waWxlci53YXJuLm1vZHVsZS5ub3QuZm91bmQ9XHUzMEUyXHUzMEI4XHUzMEU1XHUzMEZDXHUzMEVCXHUzMDRDXHU4OThCXHUzMDY0XHUzMDRCXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzOiB7MH0KCmNvbXBpbGVyLmVyci50b28ubWFueS5tb2R1bGVzPVx1NjkxQ1x1NTFGQVx1MzA1NVx1MzA4Q1x1MzA1Rlx1MzBFMlx1MzBCOFx1MzBFNVx1MzBGQ1x1MzBFQlx1NUJBM1x1OEEwMFx1MzA0Q1x1NTkxQVx1MzA1OVx1MzA0RVx1MzA3RVx1MzA1OQoKIyAwOiBzeW1ib2wKY29tcGlsZXIuZXJyLmR1cGxpY2F0ZS5tb2R1bGU9XHUzMEUyXHUzMEI4XHUzMEU1XHUzMEZDXHUzMEVCXHUzMDRDXHU5MUNEXHU4OTA3XHUzMDU3XHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5OiB7MH0KCiMgMDogc3ltYm9sCmNvbXBpbGVyLmVyci5kdXBsaWNhdGUucmVxdWlyZXM9XHU1RkM1XHU5ODA4XHUzMDRDXHU5MUNEXHU4OTA3XHUzMDU3XHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5OiB7MH0KCiMgMDogc3ltYm9sCmNvbXBpbGVyLmVyci5jb25mbGljdGluZy5leHBvcnRzPVx1MzBBOFx1MzBBRlx1MzBCOVx1MzBERFx1MzBGQ1x1MzBDOFx1MzA0Q1x1OTFDRFx1ODkwN1x1MzA3RVx1MzA1Rlx1MzA2Rlx1N0FGNlx1NTQwOFx1MzA1N1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1OTogezB9CgojIDA6IHN5bWJvbApjb21waWxlci5lcnIuY29uZmxpY3Rpbmcub3BlbnM9XHUzMEFBXHUzMEZDXHUzMEQ3XHUzMEYzXHUzMDRDXHU5MUNEXHU4OTA3XHUzMDdFXHUzMDVGXHUzMDZGXHU3QUY2XHU1NDA4XHUzMDU3XHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5OiB7MH0KCiMgMDogc3ltYm9sCmNvbXBpbGVyLmVyci5jb25mbGljdGluZy5leHBvcnRzLnRvLm1vZHVsZT1cdTMwRTJcdTMwQjhcdTMwRTVcdTMwRkNcdTMwRUJcdTMwNzhcdTMwNkVcdTMwQThcdTMwQUZcdTMwQjlcdTMwRERcdTMwRkNcdTMwQzhcdTMwNENcdTkxQ0RcdTg5MDdcdTMwN0VcdTMwNUZcdTMwNkZcdTdBRjZcdTU0MDhcdTMwNTdcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNTk6IHswfQoKIyAwOiBzeW1ib2wKY29tcGlsZXIuZXJyLmNvbmZsaWN0aW5nLm9wZW5zLnRvLm1vZHVsZT1cdTMwRTJcdTMwQjhcdTMwRTVcdTMwRkNcdTMwRUJcdTMwNzhcdTMwNkVcdTMwQUFcdTMwRkNcdTMwRDdcdTMwRjNcdTMwNENcdTkxQ0RcdTg5MDdcdTMwN0VcdTMwNUZcdTMwNkZcdTdBRjZcdTU0MDhcdTMwNTdcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNTk6IHswfQoKY29tcGlsZXIuZXJyLm5vLm9wZW5zLnVubGVzcy5zdHJvbmc9JydvcGVucycnXHUzMDZGXHU1RjM3XHU1NkZBXHUzMDZBXHUzMEUyXHUzMEI4XHUzMEU1XHUzMEZDXHUzMEVCXHUzMDY3XHUzMDZFXHUzMDdGXHU4QTMxXHU1M0VGXHUzMDU1XHUzMDhDXHUzMDdFXHUzMDU5CgojIDA6IHN5bWJvbCwgMTogc3ltYm9sCmNvbXBpbGVyLmVyci5kdXBsaWNhdGUucHJvdmlkZXM9XHU2MzA3XHU1QjlBXHUzMDRDXHU5MUNEXHU4OTA3XHUzMDU3XHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5OiBcdTMwQjVcdTMwRkNcdTMwRDNcdTMwQjl7MH1cdTMwMDFcdTVCOUZcdTg4QzV7MX0KCiMgMDogc3ltYm9sCmNvbXBpbGVyLmVyci5kdXBsaWNhdGUudXNlcz1cdTRGN0ZcdTc1MjhcdTMwNENcdTkxQ0RcdTg5MDdcdTMwNTdcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNTk6IHswfQoKIyAwOiBzeW1ib2wKY29tcGlsZXIuZXJyLnNlcnZpY2UuaW1wbGVtZW50YXRpb24uaXMuYWJzdHJhY3Q9XHUzMEI1XHUzMEZDXHUzMEQzXHUzMEI5XHU1QjlGXHU4OEM1XHUzMDRDXHU2MkJEXHU4QzYxXHUzMEFGXHUzMEU5XHUzMEI5XHUzMDY3XHUzMDU5OiB7MH0KCmNvbXBpbGVyLmVyci5zZXJ2aWNlLmltcGxlbWVudGF0aW9uLm11c3QuYmUuc3VidHlwZS5vZi5zZXJ2aWNlLmludGVyZmFjZT1cdTMwQjVcdTMwRkNcdTMwRDNcdTMwQjlcdTVCOUZcdTg4QzVcdTMwQkZcdTMwQTRcdTMwRDdcdTMwNkZcdTMwMDFcdTMwQjVcdTMwRkNcdTMwRDNcdTMwQjlcdTMwRkJcdTMwQTRcdTMwRjNcdTMwQkZcdTMwRDVcdTMwQTdcdTMwRkNcdTMwQjlcdTMwRkJcdTMwQkZcdTMwQTRcdTMwRDdcdTMwNkVcdTMwQjVcdTMwRDZcdTMwQkZcdTMwQTRcdTMwRDdcdTMwNjdcdTMwNDJcdTMwOEJcdTMwNEJcdTMwMDFcdTMwQjVcdTMwRkNcdTMwRDNcdTMwQjlcdTVCOUZcdTg4QzVcdTMwOTJcdTYyM0JcdTMwNTdcdTMwMDFcdTVGMTVcdTY1NzBcdTMwOTJcdTYzMDFcdTMwNUZcdTMwNkFcdTMwNDRcdTMwMDEicHJvdmlkZXIiXHUzMDY4XHUzMDQ0XHUzMDQ2XHU1NDBEXHU1MjREXHUzMDZFcHVibGljIHN0YXRpY1x1MzBFMVx1MzBCRFx1MzBDM1x1MzBDOVx1MzA5Mlx1NjMwMVx1MzA2NFx1NUZDNVx1ODk4MVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1OQoKY29tcGlsZXIuZXJyLnNlcnZpY2UuaW1wbGVtZW50YXRpb24ucHJvdmlkZXIucmV0dXJuLm11c3QuYmUuc3VidHlwZS5vZi5zZXJ2aWNlLmludGVyZmFjZT0icHJvdmlkZXIiXHUzMEUxXHUzMEJEXHUzMEMzXHUzMEM5XHUzMDZFXHU2MjNCXHUzMDhBXHUzMEJGXHUzMEE0XHUzMEQ3XHUzMDZGXHUzMDAxXHUzMEI1XHUzMEZDXHUzMEQzXHUzMEI5XHUzMEZCXHUzMEE0XHUzMEYzXHUzMEJGXHUzMEQ1XHUzMEE3XHUzMEZDXHUzMEI5XHUzMEZCXHUzMEJGXHUzMEE0XHUzMEQ3XHUzMDZFXHUzMEI1XHUzMEQ2XHUzMEJGXHUzMEE0XHUzMEQ3XHUzMDY3XHUzMDQyXHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5CgojIDA6IHN5bWJvbApjb21waWxlci5lcnIuc2VydmljZS5pbXBsZW1lbnRhdGlvbi5pcy5pbm5lcj1cdTMwQjVcdTMwRkNcdTMwRDNcdTMwQjlcdTVCOUZcdTg4QzVcdTMwNENcdTUxODVcdTkwRThcdTMwQUZcdTMwRTlcdTMwQjlcdTMwNjdcdTMwNTk6IHswfQoKIyAwOiBzeW1ib2wKY29tcGlsZXIuZXJyLnNlcnZpY2UuZGVmaW5pdGlvbi5pcy5lbnVtPVx1MzBCNVx1MzBGQ1x1MzBEM1x1MzBCOVx1NUI5QVx1N0ZBOVx1MzA0Q1x1NTIxN1x1NjMxOVx1NTc4Qlx1MzA2N1x1MzA1OTogezB9CgojIDA6IHN5bWJvbApjb21waWxlci5lcnIuc2VydmljZS5pbXBsZW1lbnRhdGlvbi5kb2VzbnQuaGF2ZS5hLm5vLmFyZ3MuY29uc3RydWN0b3I9XHUzMEI1XHUzMEZDXHUzMEQzXHUzMEI5XHU1QjlGXHU4OEM1XHUzMDZFXHUzMEM3XHUzMEQ1XHUzMEE5XHUzMEVCXHUzMEM4XHUzMEZCXHUzMEIzXHUzMEYzXHUzMEI5XHUzMEM4XHUzMEU5XHUzMEFGXHUzMEJGXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzOiB7MH0KCiMgMDogc3ltYm9sCmNvbXBpbGVyLmVyci5zZXJ2aWNlLmltcGxlbWVudGF0aW9uLm5vLmFyZ3MuY29uc3RydWN0b3Iubm90LnB1YmxpYz1cdTMwQjVcdTMwRkNcdTMwRDNcdTMwQjlcdTVCOUZcdTg4QzVcdTMwNkVcdTVGMTVcdTY1NzBcdTMwNkFcdTMwNTdcdTMwNkVcdTMwQjNcdTMwRjNcdTMwQjlcdTMwQzhcdTMwRTlcdTMwQUZcdTMwQkZcdTMwNENcdTMwRDFcdTMwRDZcdTMwRUFcdTMwQzNcdTMwQUZcdTMwNjdcdTMwNkZcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTM6IHswfQoKIyAwOiBzeW1ib2wKY29tcGlsZXIuZXJyLnBhY2thZ2UuZW1wdHkub3Iubm90LmZvdW5kPVx1MzBEMVx1MzBDM1x1MzBCMVx1MzBGQ1x1MzBCOFx1MzA2Rlx1N0E3QVx1MzA2N1x1MzA0Mlx1MzA4Qlx1MzA0Qlx1MzAwMVx1MzA3RVx1MzA1Rlx1MzA2Rlx1NUI1OFx1NTcyOFx1MzA1N1x1MzA3RVx1MzA1Qlx1MzA5MyB7MH0KCmNvbXBpbGVyLmVyci5uby5vdXRwdXQuZGlyPVx1MzBBRlx1MzBFOVx1MzBCOVx1NTFGQVx1NTI5Qlx1MzBDN1x1MzBBM1x1MzBFQ1x1MzBBRlx1MzBDOFx1MzBFQVx1MzA0Q1x1NjMwN1x1NUI5QVx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1Qlx1MzA5MwoKY29tcGlsZXIuZXJyLnVubmFtZWQucGtnLm5vdC5hbGxvd2VkLm5hbWVkLm1vZHVsZXM9XHU1NDBEXHU1MjREXHUzMDZFXHUzMDZBXHUzMDQ0XHUzMEQxXHUzMEMzXHUzMEIxXHUzMEZDXHUzMEI4XHUzMDZGXHU1NDBEXHU1MjREXHU0RUQ4XHUzMDREXHUzMEUyXHUzMEI4XHUzMEU1XHUzMEZDXHUzMEVCXHUzMDY3XHUzMDZGXHU4QTMxXHU1M0VGXHUzMDU1XHUzMDhDXHUzMDdFXHUzMDVCXHUzMDkzCgojIDA6IG5hbWUsIDE6IG5hbWUKY29tcGlsZXIuZXJyLm1vZHVsZS5uYW1lLm1pc21hdGNoPVx1MzBFMlx1MzBCOFx1MzBFNVx1MzBGQ1x1MzBFQlx1NTQwRHswfVx1MzA2Rlx1NUZDNVx1ODk4MVx1MzA2QVx1NTQwRFx1NTI0RHsxfVx1MzA2OFx1NEUwMFx1ODFGNFx1MzA1N1x1MzA3RVx1MzA1Qlx1MzA5MwoKIyAwOiBuYW1lLCAxOiBuYW1lCmNvbXBpbGVyLm1pc2MubW9kdWxlLm5hbWUubWlzbWF0Y2g9XHUzMEUyXHUzMEI4XHUzMEU1XHUzMEZDXHUzMEVCXHU1NDBEezB9XHUzMDZGXHU1RkM1XHU4OTgxXHUzMDZBXHU1NDBEXHU1MjREezF9XHUzMDY4XHU0RTAwXHU4MUY0XHUzMDU3XHUzMDdFXHUzMDVCXHUzMDkzCgojIDA6IG5hbWUKY29tcGlsZXIuZXJyLm1vZHVsZS5ub24uemVyby5vcGVucz1cdTMwQUFcdTMwRkNcdTMwRDdcdTMwRjNcdTMwRkJcdTMwRTJcdTMwQjhcdTMwRTVcdTMwRkNcdTMwRUJ7MH1cdTMwNkZcdTMwQkNcdTMwRURcdTMwNjdcdTMwNkFcdTMwNDRvcGVuc19jb3VudFx1MzA5Mlx1NjMwMVx1MzA2MVx1MzA3RVx1MzA1OQoKIyAwOiBuYW1lCmNvbXBpbGVyLm1pc2MubW9kdWxlLm5vbi56ZXJvLm9wZW5zPVx1MzBBQVx1MzBGQ1x1MzBEN1x1MzBGM1x1MzBGQlx1MzBFMlx1MzBCOFx1MzBFNVx1MzBGQ1x1MzBFQnswfVx1MzA2Rlx1MzBCQ1x1MzBFRFx1MzA2N1x1MzA2QVx1MzA0NG9wZW5zX2NvdW50XHUzMDkyXHU2MzAxXHUzMDYxXHUzMDdFXHUzMDU5Cgpjb21waWxlci5lcnIubW9kdWxlLmRlY2wuc2IuaW4ubW9kdWxlLWluZm8uamF2YT1cdTMwRTJcdTMwQjhcdTMwRTVcdTMwRkNcdTMwRUJcdTVCQTNcdThBMDBcdTMwNkZtb2R1bGUtaW5mby5qYXZhXHUzMDY4XHUzMDQ0XHUzMDQ2XHU1NDBEXHU1MjREXHUzMDZFXHUzMEQ1XHUzMEExXHUzMEE0XHUzMEVCXHUzMDZCXHUzMDQyXHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5Cgpjb21waWxlci5lcnIubW9kdWxlLWluZm8ud2l0aC54bW9kdWxlLnNvdXJjZXBhdGg9XHUzMEJEXHUzMEZDXHUzMEI5XHUzMEQxXHUzMEI5XHUzMDZFLVhtb2R1bGVcdTMwNjhtb2R1bGUtaW5mb1x1MzA2RVx1N0Q0NFx1NTQwOFx1MzA1Qlx1MzA0Q1x1NEUwRFx1NkI2M1x1MzA2N1x1MzA1OQoKY29tcGlsZXIuZXJyLm1vZHVsZS1pbmZvLndpdGgueG1vZHVsZS5jbGFzc3BhdGg9XHUzMEFGXHUzMEU5XHUzMEI5XHUzMEQxXHUzMEI5XHUzMDZFLVhtb2R1bGVcdTMwNjhtb2R1bGUtaW5mb1x1MzA2RVx1N0Q0NFx1NTQwOFx1MzA1Qlx1MzA0Q1x1NEUwRFx1NkI2M1x1MzA2N1x1MzA1OQoKY29tcGlsZXIuZXJyLnhtb2R1bGUubm8ubW9kdWxlLnNvdXJjZXBhdGg9LVhtb2R1bGVcdTMwNjgtLW1vZHVsZS1zb3VyY2UtcGF0aFx1MzA2RVx1N0Q0NFx1NTQwOFx1MzA1Qlx1MzA0Q1x1NEUwRFx1NkI2M1x1MzA2N1x1MzA1OQoKY29tcGlsZXIuZXJyLnByb2Nlc3NvcnBhdGgubm8ucHJvY2Vzc29ybW9kdWxlcGF0aD0tcHJvY2Vzc29ycGF0aFx1MzA2OC0tcHJvY2Vzc29yLW1vZHVsZS1wYXRoXHUzMDZFXHU3RDQ0XHU1NDA4XHUzMDVCXHUzMDRDXHU0RTBEXHU2QjYzXHUzMDY3XHUzMDU5CgojIDA6IHN5bWJvbApjb21waWxlci5lcnIucGFja2FnZS5pbi5vdGhlci5tb2R1bGU9XHUzMEQxXHUzMEMzXHUzMEIxXHUzMEZDXHUzMEI4XHUzMDRDXHU1MjI1XHUzMDZFXHUzMEUyXHUzMEI4XHUzMEU1XHUzMEZDXHUzMEVCXHUzMDZCXHU1QjU4XHU1NzI4XHUzMDU3XHUzMDdFXHUzMDU5OiB7MH0KCiMgMDogc3ltYm9sLCAxOiBuYW1lLCAyOiBzeW1ib2wsIDM6IHN5bWJvbApjb21waWxlci5lcnIucGFja2FnZS5jbGFzaC5mcm9tLnJlcXVpcmVzPVx1MzBFMlx1MzBCOFx1MzBFNVx1MzBGQ1x1MzBFQnswfVx1MzA2RnsyfVx1MzA2OHszfVx1MzA2RVx1NEUyMVx1NjVCOVx1MzA0Qlx1MzA4OVx1MzBEMVx1MzBDM1x1MzBCMVx1MzBGQ1x1MzBCOHsxfVx1MzA5Mlx1OEFBRFx1MzA3Rlx1NTNENlx1MzA4QVx1MzA3RVx1MzA1OQoKIyAwOiBzdHJpbmcKY29tcGlsZXIuZXJyLm1vZHVsZS5ub3QuZm91bmQuaW4ubW9kdWxlLnNvdXJjZS5wYXRoPVx1MzBFMlx1MzBCOFx1MzBFNVx1MzBGQ1x1MzBFQlx1MzBGQlx1MzBCRFx1MzBGQ1x1MzBCOVx1MzBGQlx1MzBEMVx1MzBCOVx1MzA2Qlx1MzBFMlx1MzBCOFx1MzBFNVx1MzBGQ1x1MzBFQnswfVx1MzA0Q1x1ODk4Qlx1MzA2NFx1MzA0Qlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5MwoKY29tcGlsZXIuZXJyLm91dHB1dC5kaXIubXVzdC5iZS5zcGVjaWZpZWQud2l0aC5kYXNoLm0ub3B0aW9uPS1tXHUzMEFBXHUzMEQ3XHUzMEI3XHUzMEU3XHUzMEYzXHUzMDkyXHU0RjdGXHU3NTI4XHUzMDU5XHUzMDhCXHU1ODM0XHU1NDA4XHUzMDAxXHUzMEFGXHUzMEU5XHUzMEI5XHU1MUZBXHU1MjlCXHUzMEM3XHUzMEEzXHUzMEVDXHUzMEFGXHUzMEM4XHUzMEVBXHUzMDkyXHU2MzA3XHU1QjlBXHUzMDU5XHUzMDhCXHU1RkM1XHU4OTgxXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDU5Cgpjb21waWxlci5lcnIubW9kdWxlc291cmNlcGF0aC5tdXN0LmJlLnNwZWNpZmllZC53aXRoLmRhc2gubS5vcHRpb249LW1cdTMwQUFcdTMwRDdcdTMwQjdcdTMwRTdcdTMwRjNcdTMwOTJcdTRGN0ZcdTc1MjhcdTMwNTlcdTMwOEJcdTU4MzRcdTU0MDhcdTMwMDFcdTMwRTJcdTMwQjhcdTMwRTVcdTMwRkNcdTMwRUJcdTMwRkJcdTMwQkRcdTMwRkNcdTMwQjlcdTMwRkJcdTMwRDFcdTMwQjlcdTMwOTJcdTYzMDdcdTVCOUFcdTMwNTlcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTkKCiMgMDogc3ltYm9sCmNvbXBpbGVyLmVyci5zZXJ2aWNlLmltcGxlbWVudGF0aW9uLm5vdC5pbi5yaWdodC5tb2R1bGU9XHUzMEI1XHUzMEZDXHUzMEQzXHUzMEI5XHU1QjlGXHU4OEM1XHUzMDkycHJvdmlkZXNcdTMwQzdcdTMwQTNcdTMwRUNcdTMwQUZcdTMwQzZcdTMwQTNcdTMwRDZcdTMwNjhcdTMwNTdcdTMwNjZcdTU0MENcdTMwNThcdTMwRTJcdTMwQjhcdTMwRTVcdTMwRkNcdTMwRUJcdTMwNkJcdTVCOUFcdTdGQTlcdTMwNTlcdTMwOEJcdTVGQzVcdTg5ODFcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTkKCiMgMDogc3ltYm9sCmNvbXBpbGVyLmVyci5jeWNsaWMucmVxdWlyZXM9ezB9XHUzMDkyXHU1NDJCXHUzMDgwXHU0RjlEXHU1QjU4XHU2MDI3XHUzMDRDXHUzMEVCXHUzMEZDXHUzMEQ3XHUzMDU3XHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5CgojIDA6IGZyYWdtZW50LCAxOiBuYW1lCmNvbXBpbGVyLmVyci5kdXBsaWNhdGUubW9kdWxlLm9uLnBhdGg9ezB9XHUzMDY3XHUzMEUyXHUzMEI4XHUzMEU1XHUzMEZDXHUzMEVCXHUzMDRDXHU5MUNEXHU4OTA3XHUzMDU3XHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5XG57MX1cdTMwNkVcdTMwRTJcdTMwQjhcdTMwRTVcdTMwRkNcdTMwRUIKCiMgMDogb3B0aW9uIG5hbWUsIDE6IHN0cmluZwpjb21waWxlci53YXJuLmJhZC5uYW1lLmZvci5vcHRpb249ezB9XHUzMEFBXHUzMEQ3XHUzMEI3XHUzMEU3XHUzMEYzXHUzMDZFXHU1MDI0XHUzMDZCXHU1NDJCXHUzMDdFXHUzMDhDXHUzMDhCXHU1NDBEXHU1MjREXHUzMDRDXHU0RTBEXHU2QjYzXHUzMDY3XHUzMDU5OiAnJ3sxfScnCgojIDA6IG9wdGlvbiBuYW1lLCAxOiBzdHJpbmcKY29tcGlsZXIuZXJyLmJhZC5uYW1lLmZvci5vcHRpb249ezB9XHUzMEFBXHUzMEQ3XHUzMEI3XHUzMEU3XHUzMEYzXHUzMDZFXHU1MDI0XHUzMDZCXHU1NDJCXHUzMDdFXHUzMDhDXHUzMDhCXHU1NDBEXHU1MjREXHUzMDRDXHU0RTBEXHU2QjYzXHUzMDY3XHUzMDU5OiAnJ3sxfScnCgojIDA6IG9wdGlvbiBuYW1lLCAxOiBzeW1ib2wKY29tcGlsZXIud2Fybi5tb2R1bGUuZm9yLm9wdGlvbi5ub3QuZm91bmQ9ezB9XHUzMEFBXHUzMEQ3XHUzMEI3XHUzMEU3XHUzMEYzXHU1MTg1XHUzMDZCXHUzMEUyXHUzMEI4XHUzMEU1XHUzMEZDXHUzMEVCXHU1NDBEXHUzMDRDXHU4OThCXHUzMDY0XHUzMDRCXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzOiB7MX0KCmNvbXBpbGVyLmVyci5hZGRtb2RzLmFsbC5tb2R1bGUucGF0aC5pbnZhbGlkPS0tYWRkLW1vZHVsZXMgQUxMLU1PRFVMRS1QQVRIXHUzMDZGXHUzMDAxXHU1NDBEXHU1MjREXHUzMDZFXHUzMDZBXHUzMDQ0XHUzMEUyXHUzMEI4XHUzMEU1XHUzMEZDXHUzMEVCXHUzMDZFXHUzMEIzXHUzMEYzXHUzMEQxXHUzMEE0XHUzMEVCXHU2NjQyXHUzMDZFXHUzMDdGXHU0RjdGXHU3NTI4XHUzMDY3XHUzMDREXHUzMDdFXHUzMDU5Cgpjb21waWxlci53YXJuLmFkZG9wZW5zLmlnbm9yZWQ9LS1hZGQtb3BlbnNcdTMwNkZcdTMwMDFcdTMwQjNcdTMwRjNcdTMwRDFcdTMwQTRcdTMwRUJcdTY2NDJcdTMwNkJcdTMwNkZcdTcxMjFcdTUyQjlcdTMwNjdcdTMwNTkKCmNvbXBpbGVyLm1pc2MubG9jbi5tb2R1bGVfc291cmNlX3BhdGg9XHUzMEUyXHUzMEI4XHUzMEU1XHUzMEZDXHUzMEVCXHUzMEZCXHUzMEJEXHUzMEZDXHUzMEI5XHUzMEZCXHUzMEQxXHUzMEI5Cgpjb21waWxlci5taXNjLmxvY24udXBncmFkZV9tb2R1bGVfcGF0aD1cdTMwQTJcdTMwQzNcdTMwRDdcdTMwQjBcdTMwRUNcdTMwRkNcdTMwQzlcdTMwRkJcdTMwRTJcdTMwQjhcdTMwRTVcdTMwRkNcdTMwRUJcdTMwRkJcdTMwRDFcdTMwQjkKCmNvbXBpbGVyLm1pc2MubG9jbi5zeXN0ZW1fbW9kdWxlcz1cdTMwQjdcdTMwQjlcdTMwQzZcdTMwRTBcdTMwRkJcdTMwRTJcdTMwQjhcdTMwRTVcdTMwRkNcdTMwRUIKCmNvbXBpbGVyLm1pc2MubG9jbi5tb2R1bGVfcGF0aD1cdTMwQTJcdTMwRDdcdTMwRUFcdTMwQjFcdTMwRkNcdTMwQjdcdTMwRTdcdTMwRjNcdTMwRkJcdTMwRTJcdTMwQjhcdTMwRTVcdTMwRkNcdTMwRUJcdTMwRkJcdTMwRDFcdTMwQjkKCmNvbXBpbGVyLm1pc2MuY2FudC5yZXNvbHZlLm1vZHVsZXM9XHUzMEUyXHUzMEI4XHUzMEU1XHUzMEZDXHUzMEVCXHUzMDkyXHU4OUUzXHU2QzdBXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzCgojIDA6IHN0cmluZwpjb21waWxlci5lcnIuaW52YWxpZC5tb2R1bGUuc3BlY2lmaWVyPVx1MzBFMlx1MzBCOFx1MzBFNVx1MzBGQ1x1MzBFQlx1NjMwN1x1NUI5QVx1NUI1MFx1MzA2Rlx1OEEzMVx1NTNFRlx1MzA1NVx1MzA4Q1x1MzA3RVx1MzA1Qlx1MzA5MzogezB9CgojIDA6IHN5bWJvbApjb21waWxlci53YXJuLnNlcnZpY2UucHJvdmlkZWQuYnV0Lm5vdC5leHBvcnRlZC5vci51c2VkPVx1MzBCNVx1MzBGQ1x1MzBEM1x1MzBCOVx1MzBGQlx1MzBBNFx1MzBGM1x1MzBCRlx1MzBENVx1MzBBN1x1MzBGQ1x1MzBCOVx1MzA0Q1x1NjMwN1x1NUI5QVx1MzA1NVx1MzA4Q1x1MzA3RVx1MzA1N1x1MzA1Rlx1MzA0Q1x1MzAwMVx1MzBBOFx1MzBBRlx1MzBCOVx1MzBERFx1MzBGQ1x1MzBDOFx1MzA3RVx1MzA1Rlx1MzA2Rlx1NEY3Rlx1NzUyOFx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1Qlx1MzA5MwoKIyAwOiBraW5kIG5hbWUsIDE6IHN5bWJvbCwgMjogc3ltYm9sCmNvbXBpbGVyLndhcm4ubGVha3Mubm90LmFjY2Vzc2libGU9XHUzMEUyXHUzMEI4XHUzMEU1XHUzMEZDXHUzMEVCezJ9XHUzMDZFezB9IHsxfVx1MzA2Rlx1MzAwMVx1MzA1M1x1MzA2RVx1MzBFMlx1MzBCOFx1MzBFNVx1MzBGQ1x1MzBFQlx1MzA5Mlx1NUZDNVx1ODk4MVx1MzA2OFx1MzA1OVx1MzA4Qlx1MzBBRlx1MzBFOVx1MzBBNFx1MzBBMlx1MzBGM1x1MzBDOFx1MzA0Qlx1MzA4OVx1MzBBMlx1MzBBRlx1MzBCQlx1MzBCOVx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5MwojIDA6IGtpbmQgbmFtZSwgMTogc3ltYm9sLCAyOiBzeW1ib2wKY29tcGlsZXIud2Fybi5sZWFrcy5ub3QuYWNjZXNzaWJsZS51bmV4cG9ydGVkPVx1MzBFMlx1MzBCOFx1MzBFNVx1MzBGQ1x1MzBFQnsyfVx1MzA2RXswfSB7MX1cdTMwNkZcdTMwQThcdTMwQUZcdTMwQjlcdTMwRERcdTMwRkNcdTMwQzhcdTMwNTVcdTMwOENcdTMwN0VcdTMwNUJcdTMwOTMKIyAwOiBraW5kIG5hbWUsIDE6IHN5bWJvbCwgMjogc3ltYm9sCmNvbXBpbGVyLndhcm4ubGVha3Mubm90LmFjY2Vzc2libGUubm90LnJlcXVpcmVkLnRyYW5zaXRpdmU9XHUzMEUyXHUzMEI4XHUzMEU1XHUzMEZDXHUzMEVCezJ9XHUzMDZFezB9IHsxfVx1MzA2Rlx1MzAwMScncmVxdWlyZXMgdHJhbnNpdGl2ZScnXHUzMDkyXHU0RjdGXHU3NTI4XHUzMDU3XHUzMDY2XHU5NTkzXHU2M0E1XHU3Njg0XHUzMDZCXHUzMEE4XHUzMEFGXHUzMEI5XHUzMEREXHUzMEZDXHUzMEM4XHUzMDU1XHUzMDhDXHUzMDdFXHUzMDVCXHUzMDkzCiMgMDoga2luZCBuYW1lLCAxOiBzeW1ib2wsIDI6IHN5bWJvbApjb21waWxlci53YXJuLmxlYWtzLm5vdC5hY2Nlc3NpYmxlLnVuZXhwb3J0ZWQucXVhbGlmaWVkPVx1MzBFMlx1MzBCOFx1MzBFNVx1MzBGQ1x1MzBFQnsyfVx1MzA2RXswfSB7MX1cdTMwNkZcdTMwMDFcdTMwNTNcdTMwNkVcdTMwRTJcdTMwQjhcdTMwRTVcdTMwRkNcdTMwRUJcdTMwOTJcdTVGQzVcdTg5ODFcdTMwNjhcdTMwNTlcdTMwOEJcdTMwNTlcdTMwNzlcdTMwNjZcdTMwNkVcdTMwQUZcdTMwRTlcdTMwQTRcdTMwQTJcdTMwRjNcdTMwQzhcdTMwNkJcdTg4NjhcdTc5M0FcdTMwNTVcdTMwOENcdTMwNkFcdTMwNDRcdTUzRUZcdTgwRkRcdTYwMjdcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTkKCiMjIwojIGVycm9ycyByZWxhdGVkIHRvIG9wdGlvbnMKCiMgMDogc3RyaW5nLCAxOiBzdHJpbmcKY29tcGlsZXIuZXJyLmlsbGVnYWwuYXJndW1lbnQuZm9yLm9wdGlvbj17MH1cdTMwNkVcdTVGMTVcdTY1NzBcdTMwNENcdTRFMERcdTZCNjNcdTMwNjdcdTMwNTk6IHsxfQpQSwMECgAACAAA0n1NShIWqdXaBAAA2gQAADkAAABjb20vc3VuL3Rvb2xzL2phdmFjL3Jlc291cmNlcy92ZXJzaW9uLnByb3BlcnRpZXMtdGVtcGxhdGUjCiMgQ29weXJpZ2h0IChjKSAyMDA1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgojIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KIwojIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiMgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKIyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKIyBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiMgYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiMKIyBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKIyBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKIyBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKIyB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAojIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiMKIyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiMgMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAojIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KIwojIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiMgb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQojIHF1ZXN0aW9ucy4KIwoKamRrPSQoSkRLX1ZFUlNJT04pCmZ1bGw9JChGVUxMX1ZFUlNJT04pCnJlbGVhc2U9JChSRUxFQVNFKQpQSwMECgAACAAABjupSnyS8I0iawAAImsAADEAAABjb20vc3VuL3Rvb2xzL2phdmFjL3Jlc291cmNlcy9qYXZhY19qYS5wcm9wZXJ0aWVzIwojIENvcHlyaWdodCAoYykgMTk5OSwgMjAxNywgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KIyBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiMKIyBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAojIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiMgcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAojIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgojCiMgVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiMgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiMgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiMgdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKIyBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgojCiMgWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgojIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKIyBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiMKIyBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQojIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKIyBxdWVzdGlvbnMuCiMKCiMjIHN0YW5kYXJkIG9wdGlvbnMKCmphdmFjLm9wdC5nPVx1MzA1OVx1MzA3OVx1MzA2Nlx1MzA2RVx1MzBDN1x1MzBEMFx1MzBDM1x1MzBCMFx1NjBDNVx1NTgzMVx1MzA5Mlx1NzUxRlx1NjIxMFx1MzA1OVx1MzA4QgpqYXZhYy5vcHQuZy5ub25lPVx1MzBDN1x1MzBEMFx1MzBDM1x1MzBCMFx1NjBDNVx1NTgzMVx1MzA5Mlx1NzUxRlx1NjIxMFx1MzA1N1x1MzA2QVx1MzA0NApqYXZhYy5vcHQuZy5saW5lcy52YXJzLnNvdXJjZT1cdTMwNDRcdTMwNEZcdTMwNjRcdTMwNEJcdTMwNkVcdTMwQzdcdTMwRDBcdTMwQzNcdTMwQjBcdTYwQzVcdTU4MzFcdTMwNkVcdTMwN0ZcdTMwOTJcdTc1MUZcdTYyMTBcdTMwNTlcdTMwOEIKamF2YWMub3B0Lm5vd2Fybj1cdThCNjZcdTU0NEFcdTMwOTJcdTc2N0FcdTc1MUZcdTMwNTVcdTMwNUJcdTMwNkFcdTMwNDQKamF2YWMub3B0LnZlcmJvc2U9XHUzMEIzXHUzMEYzXHUzMEQxXHUzMEE0XHUzMEU5XHUzMDZFXHU1MkQ1XHU0RjVDXHUzMDZCXHUzMDY0XHUzMDQ0XHUzMDY2XHUzMEUxXHUzMEMzXHUzMEJCXHUzMEZDXHUzMEI4XHUzMDkyXHU1MUZBXHU1MjlCXHUzMDU5XHUzMDhCCmphdmFjLm9wdC5kZXByZWNhdGlvbj1cdTYzQThcdTU5NjhcdTMwNTVcdTMwOENcdTMwNkFcdTMwNDRBUElcdTMwNENcdTRGN0ZcdTc1MjhcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwOEJcdTMwQkRcdTMwRkNcdTMwQjlcdTMwNkVcdTRGNERcdTdGNkVcdTMwOTJcdTUxRkFcdTUyOUJcdTMwNTlcdTMwOEIKamF2YWMub3B0LmNsYXNzcGF0aD1cdTMwRTZcdTMwRkNcdTMwQjZcdTMwRkNcdTMwRkJcdTMwQUZcdTMwRTlcdTMwQjlcdTMwRkJcdTMwRDVcdTMwQTFcdTMwQTRcdTMwRUJcdTMwNEFcdTMwODhcdTMwNzNcdTZDRThcdTkxQzhcdTMwRDdcdTMwRURcdTMwQkJcdTMwQzNcdTMwQjVcdTMwOTJcdTY5MUNcdTdEMjJcdTMwNTlcdTMwOEJcdTRGNERcdTdGNkVcdTMwOTJcdTYzMDdcdTVCOUFcdTMwNTlcdTMwOEIKamF2YWMub3B0Lm1vZHVsZXBhdGg9XHUzMEEyXHUzMEQ3XHUzMEVBXHUzMEIxXHUzMEZDXHUzMEI3XHUzMEU3XHUzMEYzXHUzMEZCXHUzMEUyXHUzMEI4XHUzMEU1XHUzMEZDXHUzMEVCXHUzMDkyXHU2OTFDXHU3RDIyXHUzMDU5XHUzMDhCXHU0RjREXHU3RjZFXHUzMDkyXHU2MzA3XHU1QjlBXHUzMDU5XHUzMDhCCmphdmFjLm9wdC5zb3VyY2VwYXRoPVx1NTE2NVx1NTI5Qlx1MzBCRFx1MzBGQ1x1MzBCOVx1MzBGQlx1MzBENVx1MzBBMVx1MzBBNFx1MzBFQlx1MzA5Mlx1NjkxQ1x1N0QyMlx1MzA1OVx1MzA4Qlx1NEY0RFx1N0Y2RVx1MzA5Mlx1NjMwN1x1NUI5QVx1MzA1OVx1MzA4QgpqYXZhYy5vcHQubT1cdTYzMDdcdTVCOUFcdTMwNTdcdTMwNUZcdTMwRTJcdTMwQjhcdTMwRTVcdTMwRkNcdTMwRUJcdTMwNkVcdTMwN0ZcdTMwQjNcdTMwRjNcdTMwRDFcdTMwQTRcdTMwRUJcdTMwNTdcdTMwMDFcdTMwQkZcdTMwQTRcdTMwRTBcdTMwQjlcdTMwQkZcdTMwRjNcdTMwRDdcdTMwOTJcdTc4QkFcdThBOERcdTMwNTlcdTMwOEIKamF2YWMub3B0Lm1vZHVsZXNvdXJjZXBhdGg9XHU4OTA3XHU2NTcwXHUzMEUyXHUzMEI4XHUzMEU1XHUzMEZDXHUzMEVCXHUzMDZFXHU1MTY1XHU1MjlCXHUzMEJEXHUzMEZDXHUzMEI5XHUzMEZCXHUzMEQ1XHUzMEExXHUzMEE0XHUzMEVCXHUzMDkyXHU2OTFDXHU3RDIyXHUzMDU5XHUzMDhCXHU0RjREXHU3RjZFXHUzMDkyXHU2MzA3XHU1QjlBXHUzMDU5XHUzMDhCCmphdmFjLm9wdC5ib290Y2xhc3NwYXRoPVx1MzBENlx1MzBGQ1x1MzBDOFx1MzBCOVx1MzBDOFx1MzBFOVx1MzBDM1x1MzBEN1x1MzBGQlx1MzBBRlx1MzBFOVx1MzBCOVx1MzBGQlx1MzBEMVx1MzBCOVx1MzA2RVx1NEY0RFx1N0Y2RVx1MzA5Mlx1MzBBQVx1MzBGQ1x1MzBEMFx1MzBGQ1x1MzBFOVx1MzBBNFx1MzBDOVx1MzA1OVx1MzA4QgpqYXZhYy5vcHQuc3lzdGVtPVx1MzBCN1x1MzBCOVx1MzBDNlx1MzBFMFx1MzBGQlx1MzBFMlx1MzBCOFx1MzBFNVx1MzBGQ1x1MzBFQlx1MzA2RVx1NEY0RFx1N0Y2RVx1MzA5Mlx1MzBBQVx1MzBGQ1x1MzBEMFx1MzBGQ1x1MzBFOVx1MzBBNFx1MzBDOVx1MzA1OVx1MzA4QgpqYXZhYy5vcHQudXBncmFkZW1vZHVsZXBhdGg9XHUzMEEyXHUzMEMzXHUzMEQ3XHUzMEIwXHUzMEVDXHUzMEZDXHUzMEM5XHU1M0VGXHU4MEZEXHUzMDZBXHUzMEUyXHUzMEI4XHUzMEU1XHUzMEZDXHUzMEVCXHUzMDZFXHU0RjREXHU3RjZFXHUzMDkyXHUzMEFBXHUzMEZDXHUzMEQwXHUzMEZDXHUzMEU5XHUzMEE0XHUzMEM5XHUzMDU5XHUzMDhCCmphdmFjLm9wdC5lbmRvcnNlZGRpcnM9XHU2M0E4XHU1OTY4XHU4OThGXHU2ODNDXHUzMEQxXHUzMEI5XHUzMDZFXHU0RjREXHU3RjZFXHUzMDkyXHUzMEFBXHUzMEZDXHUzMEQwXHUzMEZDXHUzMEU5XHUzMEE0XHUzMEM5XHUzMDU5XHUzMDhCCmphdmFjLm9wdC5leHRkaXJzPVx1MzBBNFx1MzBGM1x1MzBCOVx1MzBDOFx1MzBGQ1x1MzBFQlx1NkUwOFx1MzA3Rlx1NjJFMVx1NUYzNVx1NkE1Rlx1ODBGRFx1MzA2RVx1NEY0RFx1N0Y2RVx1MzA5Mlx1MzBBQVx1MzBGQ1x1MzBEMFx1MzBGQ1x1MzBFOVx1MzBBNFx1MzBDOVx1MzA1OVx1MzA4QgpqYXZhYy5vcHQucHJvY2Vzc29ycGF0aD1cdTZDRThcdTkxQzhcdTMwRDdcdTMwRURcdTMwQkJcdTMwQzNcdTMwQjVcdTMwOTJcdTY5MUNcdTdEMjJcdTMwNTlcdTMwOEJcdTRGNERcdTdGNkVcdTMwOTJcdTYzMDdcdTVCOUFcdTMwNTlcdTMwOEIKamF2YWMub3B0LnByb2Nlc3Nvcm1vZHVsZXBhdGg9XHU2Q0U4XHU5MUM4XHUzMEQ3XHUzMEVEXHUzMEJCXHUzMEMzXHUzMEI1XHUzMDkyXHU2OTFDXHU3RDIyXHUzMDU5XHUzMDhCXHUzMEUyXHUzMEI4XHUzMEU1XHUzMEZDXHUzMEVCXHUzMEZCXHUzMEQxXHUzMEI5XHUzMDkyXHU2MzA3XHU1QjlBXHUzMDU5XHUzMDhCCmphdmFjLm9wdC5wcm9jZXNzb3I9XHU1QjlGXHU4ODRDXHUzMDU5XHUzMDhCXHU2Q0U4XHU5MUM4XHUzMEQ3XHUzMEVEXHUzMEJCXHUzMEMzXHUzMEI1XHUzMDZFXHU1NDBEXHU1MjREXHUzMDAyXHUzMEM3XHUzMEQ1XHUzMEE5XHUzMEVCXHUzMEM4XHUzMDZFXHU2OTFDXHU1MUZBXHU1MUU2XHU3NDA2XHUzMDkyXHUzMEQwXHUzMEE0XHUzMEQxXHUzMEI5CmphdmFjLm9wdC5wYXJhbWV0ZXJzPVx1MzBFMVx1MzBCRFx1MzBDM1x1MzBDOVx1MzBGQlx1MzBEMVx1MzBFOVx1MzBFMVx1MzBGQ1x1MzBCRlx1MzA2Qlx1MzBFQVx1MzBENVx1MzBFQ1x1MzBBRlx1MzBCN1x1MzBFN1x1MzBGM1x1NzUyOFx1MzA2RVx1MzBFMVx1MzBCRlx1MzBDN1x1MzBGQ1x1MzBCRlx1MzA5Mlx1NzUxRlx1NjIxMFx1MzA1N1x1MzA3RVx1MzA1OQpqYXZhYy5vcHQucHJvYy5ub25lLm9ubHk9XHU2Q0U4XHU5MUM4XHU1MUU2XHU3NDA2XHUzMDg0XHUzMEIzXHUzMEYzXHUzMEQxXHUzMEE0XHUzMEVCXHUzMDkyXHU1QjlGXHU4ODRDXHUzMDU5XHUzMDhCXHUzMDRCXHUzMDY5XHUzMDQ2XHUzMDRCXHUzMDkyXHU1MjM2XHU1RkExXHUzMDU3XHUzMDdFXHUzMDU5XHUzMDAyCmphdmFjLm9wdC5kPVx1NzUxRlx1NjIxMFx1MzA1NVx1MzA4Q1x1MzA1Rlx1MzBBRlx1MzBFOVx1MzBCOVx1MzBGQlx1MzBENVx1MzBBMVx1MzBBNFx1MzBFQlx1MzA5Mlx1NjgzQ1x1N0QwRFx1MzA1OVx1MzA4Qlx1NEY0RFx1N0Y2RVx1MzA5Mlx1NjMwN1x1NUI5QVx1MzA1OVx1MzA4QgpqYXZhYy5vcHQuc291cmNlRGVzdD1cdTc1MUZcdTYyMTBcdTMwNTVcdTMwOENcdTMwNUZcdTMwQkRcdTMwRkNcdTMwQjlcdTMwRkJcdTMwRDVcdTMwQTFcdTMwQTRcdTMwRUJcdTMwOTJcdTY4M0NcdTdEMERcdTMwNTlcdTMwOEJcdTU4MzRcdTYyNDBcdTMwOTJcdTYzMDdcdTVCOUFcdTMwNTlcdTMwOEIKamF2YWMub3B0LmhlYWRlckRlc3Q9XHU3NTFGXHU2MjEwXHUzMDU1XHUzMDhDXHUzMDVGXHUzMENEXHUzMEE0XHUzMEM2XHUzMEEzXHUzMEQ2XHUzMEZCXHUzMEQ4XHUzMEMzXHUzMEMwXHUzMEZDXHUzMEZCXHUzMEQ1XHUzMEExXHUzMEE0XHUzMEVCXHUzMDkyXHU2ODNDXHU3RDBEXHUzMDU5XHUzMDhCXHU1ODM0XHU2MjQwXHUzMDkyXHU2MzA3XHU1QjlBXHUzMDU5XHUzMDhCCmphdmFjLm9wdC5KPTxmbGFnPlx1MzA5Mlx1NUI5Rlx1ODg0Q1x1MzBCN1x1MzBCOVx1MzBDNlx1MzBFMFx1MzA2Qlx1NzZGNFx1NjNBNVx1NkUyMVx1MzA1OQpqYXZhYy5vcHQuZW5jb2Rpbmc9XHUzMEJEXHUzMEZDXHUzMEI5XHUzMEZCXHUzMEQ1XHUzMEExXHUzMEE0XHUzMEVCXHUzMDRDXHU0RjdGXHU3NTI4XHUzMDU5XHUzMDhCXHU2NTg3XHU1QjU3XHUzMEE4XHUzMEYzXHUzMEIzXHUzMEZDXHUzMEM3XHUzMEEzXHUzMEYzXHUzMEIwXHUzMDkyXHU2MzA3XHU1QjlBXHUzMDU5XHUzMDhCCmphdmFjLm9wdC5wcm9maWxlPVx1NEY3Rlx1NzUyOFx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA4QkFQSVx1MzA0Q1x1NjMwN1x1NUI5QVx1MzA1N1x1MzA1Rlx1MzBEN1x1MzBFRFx1MzBENVx1MzBBMVx1MzBBNFx1MzBFQlx1MzA2N1x1NEY3Rlx1NzUyOFx1NTNFRlx1ODBGRFx1MzA0Qlx1MzA2OVx1MzA0Nlx1MzA0Qlx1MzA5Mlx1NzhCQVx1OEE4RFx1MzA1N1x1MzA3RVx1MzA1OQpqYXZhYy5vcHQudGFyZ2V0PVx1NzI3OVx1NUI5QVx1MzA2RVZNXHUzMEQwXHUzMEZDXHUzMEI4XHUzMEU3XHUzMEYzXHU3NTI4XHUzMDZFXHUzMEFGXHUzMEU5XHUzMEI5XHUzMEZCXHUzMEQ1XHUzMEExXHUzMEE0XHUzMEVCXHUzMDkyXHU3NTFGXHU2MjEwXHUzMDU5XHUzMDhCCmphdmFjLm9wdC5yZWxlYXNlPVx1NzI3OVx1NUI5QVx1MzA2RVZNXHUzMEQwXHUzMEZDXHUzMEI4XHUzMEU3XHUzMEYzXHU3NTI4XHUzMDZCXHUzMEIzXHUzMEYzXHUzMEQxXHUzMEE0XHUzMEVCXHUzMDU3XHUzMDdFXHUzMDU5XHUzMDAyXHUzMEI1XHUzMEREXHUzMEZDXHUzMEM4XHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDhCXHUzMEJGXHUzMEZDXHUzMEIyXHUzMEMzXHUzMEM4OiB7MH0KamF2YWMub3B0LnNvdXJjZT1cdTYzMDdcdTVCOUFcdTMwNTVcdTMwOENcdTMwNUZcdTMwRUFcdTMwRUFcdTMwRkNcdTMwQjlcdTMwNjhcdTMwQkRcdTMwRkNcdTMwQjlcdTMwNkVcdTRFOTJcdTYzREJcdTYwMjdcdTMwOTJcdTRGRERcdTMwNjQKamF2YWMub3B0LldlcnJvcj1cdThCNjZcdTU0NEFcdTMwNENcdTc2N0FcdTc1MUZcdTMwNTdcdTMwNUZcdTU4MzRcdTU0MDhcdTMwNkJcdTMwQjNcdTMwRjNcdTMwRDFcdTMwQTRcdTMwRUJcdTMwOTJcdTdENDJcdTRFODZcdTMwNTlcdTMwOEIKamF2YWMub3B0LkE9XHU2Q0U4XHU5MUM4XHUzMEQ3XHUzMEVEXHUzMEJCXHUzMEMzXHUzMEI1XHUzMDZCXHU2RTIxXHUzMDU1XHUzMDhDXHUzMDhCXHUzMEFBXHUzMEQ3XHUzMEI3XHUzMEU3XHUzMEYzCmphdmFjLm9wdC5pbXBsaWNpdD1cdTY2OTdcdTlFRDlcdTc2ODRcdTMwNkJcdTUzQzJcdTcxNjdcdTMwNTVcdTMwOENcdTMwOEJcdTMwRDVcdTMwQTFcdTMwQTRcdTMwRUJcdTMwNkJcdTMwNjRcdTMwNDRcdTMwNjZcdTMwQUZcdTMwRTlcdTMwQjlcdTMwRkJcdTMwRDVcdTMwQTFcdTMwQTRcdTMwRUJcdTMwOTJcdTc1MUZcdTYyMTBcdTMwNTlcdTMwOEJcdTMwNEJcdTMwNjlcdTMwNDZcdTMwNEJcdTMwOTJcdTYzMDdcdTVCOUFcdTMwNTlcdTMwOEIKamF2YWMub3B0LnBrZ2luZm89cGFja2FnZS1pbmZvXHUzMEQ1XHUzMEExXHUzMEE0XHUzMEVCXHUzMDZFXHU1MUU2XHU3NDA2XHUzMDkyXHU2MzA3XHU1QjlBXHUzMDU5XHUzMDhCCmphdmFjLm9wdC5tdWx0aS1yZWxlYXNlPVx1MzBERVx1MzBFQlx1MzBDMVx1MzBFQVx1MzBFQVx1MzBGQ1x1MzBCOWphclx1MzA2RVx1NEY3Rlx1NzUyOFx1MzA1OVx1MzA4Qlx1MzBFQVx1MzBFQVx1MzBGQ1x1MzBCOVx1MzA5Mlx1NjMwN1x1NUI5QVx1MzA1OVx1MzA4QgpqYXZhYy5vcHQuYXJnLmNsYXNzPTxjbGFzcz4KamF2YWMub3B0LmFyZy5jbGFzcy5saXN0PTxjbGFzczE+Wyw8Y2xhc3MyPiw8Y2xhc3MzPi4uLl0KamF2YWMub3B0LmFyZy5mbGFnPTxmbGFnPgpqYXZhYy5vcHQuYXJnLmtleS5lcXVhbHMudmFsdWU9a2V5Wz12YWx1ZV0KamF2YWMub3B0LmFyZy5wYXRoPTxwYXRoPgpqYXZhYy5vcHQuYXJnLm1zcGF0aD08bW9kdWxlLXNvdXJjZS1wYXRoPgpqYXZhYy5vcHQuYXJnLm09PG1vZHVsZS1uYW1lPgpqYXZhYy5vcHQuYXJnLmpkaz08amRrPnxub25lCmphdmFjLm9wdC5hcmcuZGlycz08ZGlycz4KamF2YWMub3B0LmFyZy5kaXJlY3Rvcnk9PGRpcmVjdG9yeT4KamF2YWMub3B0LmFyZy5lbmNvZGluZz08ZW5jb2Rpbmc+CmphdmFjLm9wdC5hcmcucHJvZmlsZT08cHJvZmlsZT4KamF2YWMub3B0LmFyZy5yZWxlYXNlPTxyZWxlYXNlPgpqYXZhYy5vcHQuYXJnLnJlbGVhc2U9PHJlbGVhc2U+CmphdmFjLm9wdC5hcmcubnVtYmVyPTxudW1iZXI+CmphdmFjLm9wdC5wbHVnaW49XHU1QjlGXHU4ODRDXHUzMDU1XHUzMDhDXHUzMDhCXHUzMEQ3XHUzMEU5XHUzMEIwXHUzMEE0XHUzMEYzXHUzMDZFXHU1NDBEXHU1MjREXHUzMDY4XHUzMEFBXHUzMEQ3XHUzMEI3XHUzMEU3XHUzMEYzXHU1RjE1XHU2NTcwCmphdmFjLm9wdC5hcmcucGx1Z2luPSJuYW1lIGFyZ3MiCmphdmFjLm9wdC5hcmcubXVsdGktcmVsZWFzZT08cmVsZWFzZT4KCiMjIGV4dGVuZGVkIG9wdGlvbnMKCmphdmFjLm9wdC5tYXhlcnJzPVx1NTFGQVx1NTI5Qlx1MzA1OVx1MzA4Qlx1MzBBOFx1MzBFOVx1MzBGQ1x1MzA2RVx1NjcwMFx1NTkyN1x1NjU3MFx1MzA5Mlx1OEEyRFx1NUI5QVx1MzA1OVx1MzA4QgpqYXZhYy5vcHQubWF4d2FybnM9XHU1MUZBXHU1MjlCXHUzMDU5XHUzMDhCXHU4QjY2XHU1NDRBXHUzMDZFXHU2NzAwXHU1OTI3XHU2NTcwXHUzMDkyXHU4QTJEXHU1QjlBXHUzMDU5XHUzMDhCCmphdmFjLm9wdC5ub2dqPVx1OEEwMFx1OEE5RVx1MzA2RVx1NkM0RVx1NzUyOFx1NjAyN1x1MzA5Mlx1NTNEN1x1MzA1MVx1NEVEOFx1MzA1MVx1MzA2QVx1MzA0NApqYXZhYy5vcHQubW9yZWluZm89XHU1NzhCXHU1OTA5XHU2NTcwXHUzMDZFXHU2MkUxXHU1RjM1XHU2MEM1XHU1ODMxXHUzMDkyXHU1MUZBXHU1MjlCXHUzMDU5XHUzMDhCCmphdmFjLm9wdC5wcmludHNlYXJjaD1cdTMwQUZcdTMwRTlcdTMwQjlcdTMwRkJcdTMwRDVcdTMwQTFcdTMwQTRcdTMwRUJcdTMwNkVcdTY5MUNcdTdEMjJcdTRGNERcdTdGNkVcdTYwQzVcdTU4MzFcdTMwOTJcdTUxRkFcdTUyOUJcdTMwNTlcdTMwOEIKamF2YWMub3B0LnByb21wdD1cdTU0MDRcdTMwQThcdTMwRTlcdTMwRkNcdTMwNjdcdTUwNUNcdTZCNjJcdTMwNTlcdTMwOEIKamF2YWMub3B0LnM9XHUzMEFGXHUzMEU5XHUzMEI5XHUzMEZCXHUzMEQ1XHUzMEExXHUzMEE0XHUzMEVCXHUzMDZFXHUzMDRCXHUzMDhGXHUzMDhBXHUzMDZCamF2YVx1MzBCRFx1MzBGQ1x1MzBCOVx1MzA5Mlx1NzY3QVx1ODg0Q1x1MzA1OVx1MzA4QgpqYXZhYy5vcHQudmVyc2lvbj1cdTMwRDBcdTMwRkNcdTMwQjhcdTMwRTdcdTMwRjNcdTYwQzVcdTU4MzEKamF2YWMub3B0LmFyZy5wYXRobmFtZT08cGF0aG5hbWU+CmphdmFjLm9wdC5hcmcuZmlsZT08ZmlsZW5hbWU+CmphdmFjLm9wdC5YYm9vdGNsYXNzcGF0aC5wPVx1MzBENlx1MzBGQ1x1MzBDOFx1MzBCOVx1MzBDOFx1MzBFOVx1MzBDM1x1MzBEN1x1MzBGQlx1MzBBRlx1MzBFOVx1MzBCOVx1MzBGQlx1MzBEMVx1MzBCOVx1MzA2RVx1NTE0OFx1OTgyRFx1MzA2Qlx1NEVEOFx1NTJBMFx1MzA1OVx1MzA4QgpqYXZhYy5vcHQuWGJvb3RjbGFzc3BhdGguYT1cdTMwRDZcdTMwRkNcdTMwQzhcdTMwQjlcdTMwQzhcdTMwRTlcdTMwQzNcdTMwRDdcdTMwRkJcdTMwQUZcdTMwRTlcdTMwQjlcdTMwRkJcdTMwRDFcdTMwQjlcdTMwNkJcdThGRkRcdTUyQTBcdTMwNTlcdTMwOEIKamF2YWMub3B0LlhsaW50PVx1NjNBOFx1NTk2OFx1MzA2RVx1OEI2Nlx1NTQ0QVx1MzA5Mlx1NjcwOVx1NTJCOVx1MzA2Qlx1MzA1OVx1MzA4QgpqYXZhYy5vcHQuWGxpbnQuYWxsPVx1MzA1OVx1MzA3OVx1MzA2Nlx1MzA2RVx1OEI2Nlx1NTQ0QVx1MzA5Mlx1NjcwOVx1NTJCOVx1MzA2Qlx1MzA1N1x1MzA3RVx1MzA1OQpqYXZhYy5vcHQuWGxpbnQubm9uZT1cdTMwNTlcdTMwNzlcdTMwNjZcdTMwNkVcdThCNjZcdTU0NEFcdTMwOTJcdTcxMjFcdTUyQjlcdTMwNkJcdTMwNTdcdTMwN0VcdTMwNTkKI0wxME46IGRvIG5vdCBsb2NhbGl6ZTogLVhsaW50CmphdmFjLm9wdC5hcmcuWGxpbnQ9PGtleT4oLDxrZXk+KSoKamF2YWMub3B0LlhsaW50LmN1c3RvbT1cdTY3MDlcdTUyQjlcdTMwN0VcdTMwNUZcdTMwNkZcdTcxMjFcdTUyQjlcdTMwNkJcdTMwNTlcdTMwOEJcdThCNjZcdTU0NEEoXHUzMEFCXHUzMEYzXHUzMERFXHU1MzNBXHU1MjA3XHUzMDhBKVx1MzAwMlxuICAgICAgICBcdTYzMDdcdTVCOUFcdTMwNTdcdTMwNUZcdThCNjZcdTU0NEFcdTMwOTJcdTcxMjFcdTUyQjlcdTMwNkJcdTMwNTlcdTMwOEJcdTMwNkJcdTMwNkZcdTMwMDFcdTMwQURcdTMwRkNcdTMwNkVcdTUyNERcdTMwNkInLSdcdTMwOTJcdTYzMDdcdTVCOUFcdTMwNTdcdTMwN0VcdTMwNTlcdTMwMDJcbiAgICAgICAgXHUzMEI1XHUzMEREXHUzMEZDXHUzMEM4XHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDhCXHUzMEFEXHUzMEZDXHUzMDZGXHU2QjIxXHUzMDZFXHUzMDY4XHUzMDRBXHUzMDhBXHUzMDY3XHUzMDU5OgpqYXZhYy5vcHQuWGxpbnQuZGVzYy5hdXhpbGlhcnljbGFzcz1cdTMwQkRcdTMwRkNcdTMwQjlcdTMwRkJcdTMwRDVcdTMwQTFcdTMwQTRcdTMwRUJcdTMwNjdcdTk3NUVcdTg4NjhcdTc5M0FcdTMwNkJcdTMwNkFcdTMwNjNcdTMwNjZcdTMwNDRcdTMwOEJcdTMwNENcdTRFRDZcdTMwNkVcdTMwRDVcdTMwQTFcdTMwQTRcdTMwRUJcdTMwNEJcdTMwODlcdTRGN0ZcdTc1MjhcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwOEJcdTg4RENcdTUyQTlcdTMwQUZcdTMwRTlcdTMwQjlcdTMwNkJcdTMwNjRcdTMwNDRcdTMwNjZcdThCNjZcdTU0NEFcdTMwNTdcdTMwN0VcdTMwNTlcdTMwMDIKCmphdmFjLm9wdC5YbGludC5kZXNjLmNhc3Q9XHU0RTBEXHU4OTgxXHUzMDZBXHUzMEFEXHUzMEUzXHUzMEI5XHUzMEM4XHUzMDZFXHU0RjdGXHU3NTI4XHUzMDZCXHUzMDY0XHUzMDQ0XHUzMDY2XHU4QjY2XHU1NDRBXHUzMDU3XHUzMDdFXHUzMDU5XHUzMDAyCgpqYXZhYy5vcHQuWGxpbnQuZGVzYy5jbGFzc2ZpbGU9XHUzMEFGXHUzMEU5XHUzMEI5XHUzMEZCXHUzMEQ1XHUzMEExXHUzMEE0XHUzMEVCXHUzMDZFXHU1MTg1XHU1QkI5XHUzMDZCXHU5NUEyXHU5MDIzXHUzMDU3XHUzMDVGXHU1NTRGXHU5ODRDXHUzMDZCXHUzMDY0XHUzMDQ0XHUzMDY2XHU4QjY2XHU1NDRBXHUzMDU3XHUzMDdFXHUzMDU5XHUzMDAyCgpqYXZhYy5vcHQuWGxpbnQuZGVzYy5kZXByZWNhdGlvbj1cdTk3NUVcdTYzQThcdTU5NjhcdTk4MDVcdTc2RUVcdTMwNkVcdTRGN0ZcdTc1MjhcdTMwNkJcdTMwNjRcdTMwNDRcdTMwNjZcdThCNjZcdTU0NEFcdTMwNTdcdTMwN0VcdTMwNTlcdTMwMDIKCmphdmFjLm9wdC5YbGludC5kZXNjLmRlcC1hbm49SmF2YURvY1x1MzA2N1x1OTc1RVx1NjNBOFx1NTk2OFx1MzA2OFx1MzA1N1x1MzA2Nlx1MzBERVx1MzBGQ1x1MzBBRlx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA4Qlx1MzA0Q0BcdTk3NUVcdTYzQThcdTU5NjhcdTMwNkVcdTZDRThcdTkxQzhcdTMwOTJcdTRGN0ZcdTc1MjhcdTMwNTdcdTMwNjZcdTMwNDRcdTMwNkFcdTMwNDRcdTk4MDVcdTc2RUVcdTMwNkJcdTMwNjRcdTMwNDRcdTMwNjZcdThCNjZcdTU0NEFcdTMwNTdcdTMwN0VcdTMwNTlcdTMwMDIKCmphdmFjLm9wdC5YbGludC5kZXNjLmRpdnplcm89XHU1QjlBXHU2NTc0XHU2NTcwMFx1MzA2N1x1OTY2NFx1N0I5N1x1MzA1NVx1MzA4Q1x1MzA4Qlx1MzA1M1x1MzA2OFx1MzA2Qlx1MzA2NFx1MzA0NFx1MzA2Nlx1OEI2Nlx1NTQ0QVx1MzA1N1x1MzA3RVx1MzA1OVx1MzAwMgoKamF2YWMub3B0LlhsaW50LmRlc2MuZW1wdHk9aWZcdTRFRTVcdTk2NERcdTMwNENcdTdBN0FcdTMwNkVcdTY1ODdcdTMwNjdcdTMwNDJcdTMwOEJcdTMwNTNcdTMwNjhcdTMwNkJcdTMwNjRcdTMwNDRcdTMwNjZcdThCNjZcdTU0NEFcdTMwNTdcdTMwN0VcdTMwNTlcdTMwMDIKCmphdmFjLm9wdC5YbGludC5kZXNjLmV4cG9ydHM9XHUzMEUyXHUzMEI4XHUzMEU1XHUzMEZDXHUzMEVCXHUzMDZFXHUzMEE4XHUzMEFGXHUzMEI5XHUzMEREXHUzMEZDXHUzMEM4XHUzMDZCXHU5NUEyXHUzMDU5XHUzMDhCXHU1NTRGXHU5ODRDXHUzMDZCXHUzMDY0XHUzMDQ0XHUzMDY2XHU4QjY2XHU1NDRBXHUzMDU3XHUzMDdFXHUzMDU5XHUzMDAyCgpqYXZhYy5vcHQuWGxpbnQuZGVzYy5mYWxsdGhyb3VnaD1zd2l0Y2hcdTY1ODdcdTMwNkUxXHUzMDY0XHUzMDZFY2FzZVx1MzA0Qlx1MzA4OVx1NkIyMVx1MzA3OFx1MzA2RVx1MzBENVx1MzBBOVx1MzBGQ1x1MzBFQlx1MzBGQlx1MzBCOVx1MzBFQlx1MzBGQ1x1MzA2Qlx1MzA2NFx1MzA0NFx1MzA2Nlx1OEI2Nlx1NTQ0QVx1MzA1N1x1MzA3RVx1MzA1OVx1MzAwMgoKamF2YWMub3B0LlhsaW50LmRlc2MuZmluYWxseT1cdTZCNjNcdTVFMzhcdTMwNkJcdTVCOENcdTRFODZcdTMwNTdcdTMwNkFcdTMwNDRmaW5hbGx5XHU3QkMwXHUzMDZCXHUzMDY0XHUzMDQ0XHUzMDY2XHU4QjY2XHU1NDRBXHUzMDU3XHUzMDdFXHUzMDU5XHUzMDAyCgpqYXZhYy5vcHQuWGxpbnQuZGVzYy5tb2R1bGU9XHUzMEUyXHUzMEI4XHUzMEU1XHUzMEZDXHUzMEVCXHUzMEZCXHUzMEI3XHUzMEI5XHUzMEM2XHUzMEUwXHU5NUEyXHU5MDIzXHUzMDZFXHU1NTRGXHU5ODRDXHUzMDZCXHUzMDY0XHUzMDQ0XHUzMDY2XHU4QjY2XHU1NDRBXHUzMDU3XHUzMDdFXHUzMDU5XHUzMDAyCgpqYXZhYy5vcHQuWGxpbnQuZGVzYy5vcHRpb25zPVx1MzBCM1x1MzBERVx1MzBGM1x1MzBDOVx1ODg0Q1x1MzBBQVx1MzBEN1x1MzBCN1x1MzBFN1x1MzBGM1x1MzA2RVx1NEY3Rlx1NzUyOFx1MzA2Qlx1OTVBMlx1MzA1OVx1MzA4Qlx1NTU0Rlx1OTg0Q1x1MzA2Qlx1MzA2NFx1MzA0NFx1MzA2Nlx1OEI2Nlx1NTQ0QVx1MzA1N1x1MzA3RVx1MzA1OVx1MzAwMgoKamF2YWMub3B0LlhsaW50LmRlc2Mub3ZlcmxvYWRzPVx1MzBFMVx1MzBCRFx1MzBDM1x1MzBDOVx1MzA2RVx1MzBBQVx1MzBGQ1x1MzBEMFx1MzBGQ1x1MzBFRFx1MzBGQ1x1MzBDOVx1MzA2Qlx1OTVBMlx1MzA1OVx1MzA4Qlx1NTU0Rlx1OTg0Q1x1MzA2Qlx1MzA2NFx1MzA0NFx1MzA2Nlx1OEI2Nlx1NTQ0QVx1MzA1N1x1MzA3RVx1MzA1OVx1MzAwMgoKamF2YWMub3B0LlhsaW50LmRlc2Mub3ZlcnJpZGVzPVx1MzBFMVx1MzBCRFx1MzBDM1x1MzBDOVx1MzA2RVx1MzBBQVx1MzBGQ1x1MzBEMFx1MzBGQ1x1MzBFOVx1MzBBNFx1MzBDOVx1MzA2Qlx1OTVBMlx1MzA1OVx1MzA4Qlx1NTU0Rlx1OTg0Q1x1MzA2Qlx1MzA2NFx1MzA0NFx1MzA2Nlx1OEI2Nlx1NTQ0QVx1MzA1N1x1MzA3RVx1MzA1OVx1MzAwMgoKamF2YWMub3B0LlhsaW50LmRlc2MucGF0aD1cdTMwQjNcdTMwREVcdTMwRjNcdTMwQzlcdTg4NENcdTMwNkVcdTcxMjFcdTUyQjlcdTMwNkFcdTMwRDFcdTMwQjlcdTg5ODFcdTdEMjBcdTMwNkJcdTMwNjRcdTMwNDRcdTMwNjZcdThCNjZcdTU0NEFcdTMwNTdcdTMwN0VcdTMwNTlcdTMwMDIKCmphdmFjLm9wdC5YbGludC5kZXNjLnByb2Nlc3Npbmc9XHU2Q0U4XHU5MUM4XHU1MUU2XHU3NDA2XHUzMDZCXHU5NUEyXHUzMDU5XHUzMDhCXHU1NTRGXHU5ODRDXHUzMDZCXHUzMDY0XHUzMDQ0XHUzMDY2XHU4QjY2XHU1NDRBXHUzMDU3XHUzMDdFXHUzMDU5XHUzMDAyCgpqYXZhYy5vcHQuWGxpbnQuZGVzYy5yYXd0eXBlcz1yYXdcdTU3OEJcdTMwNkVcdTRGN0ZcdTc1MjhcdTMwNkJcdTMwNjRcdTMwNDRcdTMwNjZcdThCNjZcdTU0NEFcdTMwNTdcdTMwN0VcdTMwNTlcdTMwMDIKCmphdmFjLm9wdC5YbGludC5kZXNjLnJlbW92YWw9XHU1MjRBXHU5NjY0XHU3NTI4XHUzMDZCXHUzMERFXHUzMEZDXHUzMEFGXHUzMDU1XHUzMDhDXHUzMDVGQVBJXHUzMDZFXHU0RjdGXHU3NTI4XHUzMDZCXHUzMDY0XHUzMDQ0XHUzMDY2XHU4QjY2XHU1NDRBXHUzMDU3XHUzMDdFXHUzMDU5XHUzMDAyCgpqYXZhYy5vcHQuWGxpbnQuZGVzYy5zZXJpYWw9XHUzMEI3XHUzMEVBXHUzMEEyXHUzMEVCXHUzMEZCXHUzMEQwXHUzMEZDXHUzMEI4XHUzMEU3XHUzMEYzSURcdTMwOTJcdTYzMDdcdTVCOUFcdTMwNTdcdTMwNkFcdTMwNDRcdTc2RjRcdTUyMTdcdTUzMTZcdTUzRUZcdTgwRkRcdTMwNkFcdTMwQUZcdTMwRTlcdTMwQjlcdTMwNkJcdTMwNjRcdTMwNDRcdTMwNjZcdThCNjZcdTU0NEFcdTMwNTdcdTMwN0VcdTMwNTlcdTMwMDIgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIFx1MzA3RVx1MzA1Rlx1MzAwMVx1NzZGNFx1NTIxN1x1NTMxNlx1NTNFRlx1ODBGRFx1ODk4MVx1N0QyMFx1MzA0Qlx1MzA4OXB1YmxpY1x1NEVFNVx1NTkxNlx1MzA2RVx1MzBFMVx1MzBGM1x1MzBEMFx1MzBGQ1x1MzA3OFx1MzA2RVx1MzBBMlx1MzBBRlx1MzBCQlx1MzBCOVx1MzA2Qlx1MzA2NFx1MzA0NFx1MzA2Nlx1OEI2Nlx1NTQ0QVx1MzA1N1x1MzA3RVx1MzA1OVx1MzAwMgoKamF2YWMub3B0LlhsaW50LmRlc2Muc3RhdGljPVx1MzBBNFx1MzBGM1x1MzBCOVx1MzBCRlx1MzBGM1x1MzBCOVx1MzA5Mlx1NEY3Rlx1NzUyOFx1MzA1N1x1MzA1RnN0YXRpY1x1MzBFMVx1MzBGM1x1MzBEMFx1MzBGQ1x1MzA3OFx1MzA2RVx1MzBBMlx1MzBBRlx1MzBCQlx1MzBCOVx1MzA2Qlx1MzA2NFx1MzA0NFx1MzA2Nlx1OEI2Nlx1NTQ0QVx1MzA1N1x1MzA3RVx1MzA1OVx1MzAwMgoKamF2YWMub3B0LlhsaW50LmRlc2MudHJ5PXRyeVx1MzBENlx1MzBFRFx1MzBDM1x1MzBBRih0cnktd2l0aC1yZXNvdXJjZXNcdTMwNkFcdTMwNjkpXHUzMDZFXHU0RjdGXHU3NTI4XHUzMDZCXHU5NUEyXHUzMDU5XHUzMDhCXHU1NTRGXHU5ODRDXHUzMDZCXHUzMDY0XHUzMDQ0XHUzMDY2XHU4QjY2XHU1NDRBXHUzMDU3XHUzMDdFXHUzMDU5XHUzMDAyCgpqYXZhYy5vcHQuWGxpbnQuZGVzYy51bmNoZWNrZWQ9XHU3MTIxXHU2OTFDXHU2N0ZCXHU2NENEXHU0RjVDXHUzMDZCXHUzMDY0XHUzMDQ0XHUzMDY2XHU4QjY2XHU1NDRBXHUzMDU3XHUzMDdFXHUzMDU5XHUzMDAyCgpqYXZhYy5vcHQuWGxpbnQuZGVzYy52YXJhcmdzPVx1NUI4OVx1NTE2OFx1MzA2N1x1MzA2Rlx1MzA2QVx1MzA0NFx1NTNFRlx1ODBGRFx1NjAyN1x1MzA0Q1x1MzA0Mlx1MzA4Qlx1NTNFRlx1NTkwOVx1NUYxNVx1NjU3MFx1MzBFMVx1MzBCRFx1MzBDM1x1MzBDOVx1MzA2Qlx1MzA2NFx1MzA0NFx1MzA2Nlx1OEI2Nlx1NTQ0QVx1MzA1N1x1MzA3RVx1MzA1OQoKamF2YWMub3B0Llhkb2NsaW50PWphdmFkb2NcdTMwQjNcdTMwRTFcdTMwRjNcdTMwQzhcdTMwNkVcdTU1NEZcdTk4NENcdTMwNkJcdTk1QTJcdTMwNTlcdTMwOEJcdTYzQThcdTU5NjhcdTMwQzFcdTMwQTdcdTMwQzNcdTMwQUZcdTMwOTJcdTY3MDlcdTUyQjlcdTMwNkJcdTMwNTdcdTMwN0VcdTMwNTkKIyBMMTBOOiBkbyBub3QgbG9jYWxpemU6IGFsbCBub25lCmphdmFjLm9wdC5YZG9jbGludC5zdWJvcHRzID0gKGFsbHxub25lfFstXTxncm91cD4pWy88YWNjZXNzPl0KCiMgTDEwTjogZG8gbm90IGxvY2FsaXplOiBhY2Nlc3NpYmlsaXR5IGh0bWwgbWlzc2luZyByZWZlcmVuY2Ugc3ludGF4CiMgTDEwTjogZG8gbm90IGxvY2FsaXplOiBwdWJsaWMgcHJvdGVjdGVkIHBhY2thZ2UgcHJpdmF0ZQpqYXZhYy5vcHQuWGRvY2xpbnQuY3VzdG9tPWphdmFkb2NcdTMwQjNcdTMwRTFcdTMwRjNcdTMwQzhcdTMwNkVcdTU1NEZcdTk4NENcdTMwNkJcdTk1QTJcdTMwNTlcdTMwOEJcdTcyNzlcdTVCOUFcdTMwNkVcdTMwQzFcdTMwQTdcdTMwQzNcdTMwQUZcdTMwOTJcdTY3MDlcdTUyQjlcdTMwN0VcdTMwNUZcdTMwNkZcdTcxMjFcdTUyQjlcdTMwNkJcdTMwNTdcdTMwN0VcdTMwNTlcdTMwMDJcbiAgICAgICAgXHUzMDUzXHUzMDUzXHUzMDY3XHUzMDAxPGdyb3VwPlx1MzA2RmFjY2Vzc2liaWxpdHlcdTMwMDFodG1sXHUzMDAxbWlzc2luZ1x1MzAwMXJlZmVyZW5jZVx1MzA3RVx1MzA1Rlx1MzA2RnN5bnRheFx1MzA2RVx1MzA0NFx1MzA1QVx1MzA4Q1x1MzA0Qlx1MzA2N1x1MzAwMVxuICAgICAgICA8YWNjZXNzPlx1MzA2RnB1YmxpY1x1MzAwMXByb3RlY3RlZFx1MzAwMXBhY2thZ2VcdTMwN0VcdTMwNUZcdTMwNkZwcml2YXRlXHUzMDZFXHUzMDQ0XHUzMDVBXHUzMDhDXHUzMDRCXHUzMDY3XHUzMDU5XHUzMDAyCgpqYXZhYy5vcHQuWGRvY2xpbnQucGFja2FnZS5hcmdzID0gWy1dPHBhY2thZ2VzPigsWy1dPHBhY2thZ2U+KSoKCmphdmFjLm9wdC5YZG9jbGludC5wYWNrYWdlLmRlc2M9XHU3Mjc5XHU1QjlBXHUzMDZFXHUzMEQxXHUzMEMzXHUzMEIxXHUzMEZDXHUzMEI4XHUzMDZFXHUzMEMxXHUzMEE3XHUzMEMzXHUzMEFGXHUzMDkyXHU2NzA5XHU1MkI5XHUzMDdFXHUzMDVGXHUzMDZGXHU3MTIxXHU1MkI5XHUzMDZCXHUzMDU3XHUzMDdFXHUzMDU5XHUzMDAyXHU1NDA0PHBhY2thZ2U+XHUzMDZGXHUzMDAxXG5cdTMwRDFcdTMwQzNcdTMwQjFcdTMwRkNcdTMwQjhcdTMwNkVcdTRGRUVcdTk4RkVcdTMwNTVcdTMwOENcdTMwNUZcdTU0MERcdTUyNERcdTMwMDFcdTMwN0VcdTMwNUZcdTMwNkZcdTMwRDFcdTMwQzNcdTMwQjFcdTMwRkNcdTMwQjhcdTU0MERcdTMwNkVcdTYzQTVcdTk4MkRcdThGOUVcdTMwNkVcdTVGOENcdTMwNkInJy4qJydcdTMwOTJcdTYzMDdcdTVCOUFcbihcdTYzMDdcdTVCOUFcdTMwNTdcdTMwNUZcdTMwRDFcdTMwQzNcdTMwQjFcdTMwRkNcdTMwQjhcdTMwNkVcdTMwNTlcdTMwNzlcdTMwNjZcdTMwNkVcdTMwQjVcdTMwRDZcdTMwRDFcdTMwQzNcdTMwQjFcdTMwRkNcdTMwQjhcdTMwNkJcdTYyRTFcdTVGMzUpXHUzMDU3XHUzMDVGXHUzMDgyXHUzMDZFXHUzMDY3XHUzMDU5XHUzMDAyXHU1NDA0PHBhY2thZ2U+XHUzMDZFXHU1MjREXHUzMDZCXG4nLSdcdTMwOTJcdTYzMDdcdTVCOUFcdTMwNTlcdTMwOEJcdTMwNjhcdTMwMDFcdTYzMDdcdTVCOUFcdTMwNTdcdTMwNUYxXHUzMDY0XHU0RUU1XHU0RTBBXHUzMDZFXHUzMEQxXHUzMEMzXHUzMEIxXHUzMEZDXHUzMEI4XHUzMDZCXHU5NUEyXHUzMDU5XHUzMDhCXHUzMEMxXHUzMEE3XHUzMEMzXHUzMEFGXHUzMDkyXHU3MTIxXHU1MkI5XHUzMDZCXHUzMDY3XHUzMDREXHUzMDdFXHUzMDU5XHUzMDAyCgpqYXZhYy5vcHQuWHN0ZG91dD1cdTZBMTlcdTZFOTZcdTUxRkFcdTUyOUJcdTMwOTJcdTMwRUFcdTMwQzBcdTMwQTRcdTMwRUNcdTMwQUZcdTMwQzhcdTMwNTlcdTMwOEIKamF2YWMub3B0Llg9XHU4RkZEXHU1MkEwXHUzMEFBXHUzMEQ3XHUzMEI3XHUzMEU3XHUzMEYzXHUzMDZFXHUzMEQ4XHUzMEVCXHUzMEQ3XHUzMDkyXHU1MUZBXHU1MjlCXHUzMDU3XHUzMDdFXHUzMDU5CmphdmFjLm9wdC5oZWxwPVx1MzA1M1x1MzA2RVx1MzBEOFx1MzBFQlx1MzBEN1x1MzBGQlx1MzBFMVx1MzBDM1x1MzBCQlx1MzBGQ1x1MzBCOFx1MzA5Mlx1NTFGQVx1NTI5Qlx1MzA1N1x1MzA3RVx1MzA1OQpqYXZhYy5vcHQucHJpbnQ9XHU2MzA3XHU1QjlBXHUzMDU3XHUzMDVGXHU1NzhCXHUzMDZFXHUzMEM2XHUzMEFEXHUzMEI5XHUzMEM4XHU4ODY4XHU3OTNBXHUzMDkyXHU1MUZBXHU1MjlCXHUzMDU5XHUzMDhCCmphdmFjLm9wdC5wcmludFJvdW5kcz1cdTZDRThcdTkxQzhcdTUxRTZcdTc0MDZcdTMwNkVcdTVGODBcdTVGQTlcdTMwNkJcdTMwNjRcdTMwNDRcdTMwNjZcdTMwNkVcdTYwQzVcdTU4MzFcdTMwOTJcdTUzNzBcdTUyMzdcdTMwNTlcdTMwOEIKamF2YWMub3B0LnByaW50UHJvY2Vzc29ySW5mbz1cdTMwRDdcdTMwRURcdTMwQkJcdTMwQzNcdTMwQjVcdTMwNENcdTUxRTZcdTc0MDZcdTMwOTJcdTRGOURcdTk4M0NcdTMwNTVcdTMwOENcdTMwOEJcdTZDRThcdTkxQzhcdTMwNkJcdTMwNjRcdTMwNDRcdTMwNjZcdTMwNkVcdTYwQzVcdTU4MzFcdTMwOTJcdTUzNzBcdTUyMzdcdTMwNTlcdTMwOEIKamF2YWMub3B0LnVzZXJwYXRoc2ZpcnN0PVx1MzBENlx1MzBGQ1x1MzBDOFx1MzBGQlx1MzBBRlx1MzBFOVx1MzBCOVx1MzBEMVx1MzBCOVx1MzA2RVx1NUY4Q1x1MzA2N1x1MzA2Rlx1MzA2QVx1MzA0Rlx1MzAwMVx1MzBENlx1MzBGQ1x1MzBDOFx1MzBGQlx1MzBBRlx1MzBFOVx1MzBCOVx1MzBEMVx1MzBCOVx1MzA2RVx1NTI0RFx1MzA2Qlx1MzBBRlx1MzBFOVx1MzBCOVx1MzA2RVx1MzBBRlx1MzBFOVx1MzBCOVx1MzBEMVx1MzBCOVx1MzA0QVx1MzA4OFx1MzA3M1x1MzBCRFx1MzBGQ1x1MzBCOVx1MzBGQlx1MzBEMVx1MzBCOVx1MzA5Mlx1NjkxQ1x1N0QyMlx1MzA1OVx1MzA4QgpqYXZhYy5vcHQucHJlZmVyPVx1NjY5N1x1OUVEOVx1NzY4NFx1MzA2Qlx1MzBCM1x1MzBGM1x1MzBEMVx1MzBBNFx1MzBFQlx1MzA1NVx1MzA4Q1x1MzA4Qlx1MzBBRlx1MzBFOVx1MzBCOVx1MzA2Qlx1MzA2NFx1MzA0NFx1MzA2Nlx1MzAwMVx1MzBCRFx1MzBGQ1x1MzBCOVx1MzBGQlx1MzBENVx1MzBBMVx1MzBBNFx1MzBFQlx1MzA2OFx1MzBBRlx1MzBFOVx1MzBCOVx1MzBGQlx1MzBENVx1MzBBMVx1MzBBNFx1MzBFQlx1MzA2RVx1NEUyMVx1NjVCOVx1MzA0Q1x1ODk4Qlx1MzA2NFx1MzA0Qlx1MzA2M1x1MzA1Rlx1OTY5Qlx1MzA2OVx1MzA2MVx1MzA4OVx1MzA5Mlx1OEFBRFx1MzA3Rlx1OEZCQ1x1MzA4MFx1MzA0Qlx1NjMwN1x1NUI5QVx1MzA1OVx1MzA4QgpqYXZhYy5vcHQuQVQ9XHUzMEQ1XHUzMEExXHUzMEE0XHUzMEVCXHUzMDRCXHUzMDg5XHUzMDZFXHU4QUFEXHU1M0Q2XHUzMDhBXHUzMEFBXHUzMEQ3XHUzMEI3XHUzMEU3XHUzMEYzXHUzMDRBXHUzMDg4XHUzMDczXHUzMEQ1XHUzMEExXHUzMEE0XHUzMEVCXHU1NDBECmphdmFjLm9wdC5kaWFncz1cdThBM0FcdTY1QURcdTMwRTJcdTMwRkNcdTMwQzlcdTMwNkVcdTkwNzhcdTYyOUUKamF2YWMub3B0LmFkZEV4cG9ydHM9PG90aGVyLW1vZHVsZT5cdTMwNENBTEwtVU5OQU1FRFx1MzA2N1x1MzA0Mlx1MzA4Qlx1NTgzNFx1NTQwOFx1MzAwMVx1MzA1RFx1MzA2RVx1NUI5QVx1N0ZBOVx1MzBFMlx1MzBCOFx1MzBFNVx1MzBGQ1x1MzBFQlx1MzA0Qlx1MzA4OVx1MzAwMVx1OEZGRFx1NTJBMFx1MzBFMlx1MzBCOFx1MzBFNVx1MzBGQ1x1MzBFQlx1MzA3RVx1MzA1Rlx1MzA2RlxuICAgICAgICBcdTMwNTlcdTMwNzlcdTMwNjZcdTMwNkVcdTU0MERcdTUyNERcdTMwNkVcdTMwNkFcdTMwNDRcdTMwRTJcdTMwQjhcdTMwRTVcdTMwRkNcdTMwRUJcdTMwNkJcdTMwQThcdTMwQUZcdTMwQjlcdTMwRERcdTMwRkNcdTMwQzhcdTZFMDhcdTMwNjhcdTMwN0ZcdTMwNkFcdTMwNTVcdTMwOENcdTMwOEJcdTMwODhcdTMwNDZcdTMwNkJcdTMwRDFcdTMwQzNcdTMwQjFcdTMwRkNcdTMwQjhcdTMwOTJcdTYzMDdcdTVCOUFcdTMwNTdcdTMwN0VcdTMwNTlcdTMwMDIKamF2YWMub3B0LmFyZy5hZGRFeHBvcnRzPTxtb2R1bGU+LzxwYWNrYWdlPj08b3RoZXItbW9kdWxlPigsPG90aGVyLW1vZHVsZT4pKgpqYXZhYy5vcHQuYWRkUmVhZHM9XHU2MzA3XHU1QjlBXHUzMDZFXHUzMEUyXHUzMEI4XHUzMEU1XHUzMEZDXHUzMEVCXHUzMDY3XHU1RkM1XHU5ODA4XHUzMDY4XHUzMDdGXHUzMDZBXHUzMDU1XHUzMDhDXHUzMDhCXHUzMDg4XHUzMDQ2XHUzMDZCXHU4RkZEXHU1MkEwXHUzMEUyXHUzMEI4XHUzMEU1XHUzMEZDXHUzMEVCXHUzMDkyXHU2MzA3XHU1QjlBXHUzMDU3XHUzMDdFXHUzMDU5XHUzMDAyXG4gICAgICAgIFx1NTQwRFx1NTI0RFx1MzA2RVx1MzA2QVx1MzA0NFx1MzBFMlx1MzBCOFx1MzBFNVx1MzBGQ1x1MzBFQlx1MzA5Mlx1NUZDNVx1ODk4MVx1MzA2OFx1MzA1OVx1MzA4Qlx1NTgzNFx1NTQwOFx1MzAwMTxvdGhlci1tb2R1bGU+XHUzMDZGQUxMLVVOTkFNRURcdTMwNkJcdTMwNTdcdTMwN0VcdTMwNTlcdTMwMDIKamF2YWMub3B0LmFyZy5hZGRSZWFkcz08bW9kdWxlPj08b3RoZXItbW9kdWxlPigsPG90aGVyLW1vZHVsZT4pKgpqYXZhYy5vcHQucGF0Y2g9SkFSXHUzMEQ1XHUzMEExXHUzMEE0XHUzMEVCXHUzMDdFXHUzMDVGXHUzMDZGXHUzMEM3XHUzMEEzXHUzMEVDXHUzMEFGXHUzMEM4XHUzMEVBXHUzMDZFXHUzMEFGXHUzMEU5XHUzMEI5XHUzMDRBXHUzMDg4XHUzMDczXHUzMEVBXHUzMEJEXHUzMEZDXHUzMEI5XHUzMDY3XHUzMEUyXHUzMEI4XHUzMEU1XHUzMEZDXHUzMEVCXHUzMDkyXG4gICAgICAgIFx1MzBBQVx1MzBGQ1x1MzBEMFx1MzBGQ1x1MzBFOVx1MzBBNFx1MzBDOVx1MzA3RVx1MzA1Rlx1MzA2Rlx1NjJFMVx1NUYzNVx1MzA1N1x1MzA3RVx1MzA1OQpqYXZhYy5vcHQuYXJnLnBhdGNoPTxtb2R1bGU+PTxmaWxlPig6PGZpbGU+KSoKamF2YWMub3B0Lm1vZHVsZT1cdTMwQjNcdTMwRjNcdTMwRDFcdTMwQTRcdTMwRUJcdTMwNTVcdTMwOENcdTMwOEJcdTMwQUZcdTMwRTlcdTMwQjlcdTMwNENcdTVDNUVcdTMwNTlcdTMwOEJcdTMwRTJcdTMwQjhcdTMwRTVcdTMwRkNcdTMwRUJcdTMwOTJcdTYzMDdcdTVCOUFcdTMwNTdcdTMwN0VcdTMwNTlcdTMwMDIKamF2YWMub3B0LmFyZy5tb2R1bGU9PG1vZHVsZT4KamF2YWMub3B0LmFkZG1vZHM9XHU1MjFEXHU2NzFGXHUzMEUyXHUzMEI4XHUzMEU1XHUzMEZDXHUzMEVCXHUzMDZCXHU1MkEwXHUzMDQ4XHUzMDY2XHU4OUUzXHU2QzdBXHUzMDU5XHUzMDhCXHUzMEVCXHUzMEZDXHUzMEM4XHUzMEZCXHUzMEUyXHUzMEI4XHUzMEU1XHUzMEZDXHUzMEVCXHUzMDAxXHUzMDdFXHUzMDVGXHUzMDZGPG1vZHVsZT5cdTMwNENcbiAgICAgICAgQUxMLU1PRFVMRS1QQVRIXHUzMDY3XHUzMDQyXHUzMDhCXHU1ODM0XHU1NDA4XHUzMDZGXHUzMEUyXHUzMEI4XHUzMEU1XHUzMEZDXHUzMEVCXHUzMEZCXHUzMEQxXHUzMEI5XHUzMDZFXHUzMDU5XHUzMDc5XHUzMDY2XHUzMDZFXHUzMEUyXHUzMEI4XHUzMEU1XHUzMEZDXHUzMEVCXHUzMDAyCmphdmFjLm9wdC5hcmcuYWRkbW9kcz08bW9kdWxlPigsPG1vZHVsZT4pKgpqYXZhYy5vcHQubGltaXRtb2RzPVx1NTNDMlx1NzE2N1x1NTNFRlx1ODBGRFx1MzA2QVx1MzBFMlx1MzBCOFx1MzBFNVx1MzBGQ1x1MzBFQlx1MzA2RVx1OTgxOFx1NTdERlx1MzA5Mlx1NTIzNlx1OTY1MFx1MzA1N1x1MzA3RVx1MzA1OQpqYXZhYy5vcHQuYXJnLmxpbWl0bW9kcz08bW9kdWxlPigsPG1vZHVsZT4pKgpqYXZhYy5vcHQubW9kdWxlLnZlcnNpb249XHUzMEIzXHUzMEYzXHUzMEQxXHUzMEE0XHUzMEVCXHUzMDU5XHUzMDhCXHUzMEUyXHUzMEI4XHUzMEU1XHUzMEZDXHUzMEVCXHUzMDZFXHUzMEQwXHUzMEZDXHUzMEI4XHUzMEU3XHUzMEYzXHUzMDkyXHU2MzA3XHU1QjlBXHUzMDU3XHUzMDdFXHUzMDU5CmphdmFjLm9wdC5hcmcubW9kdWxlLnZlcnNpb249PFx1MzBEMFx1MzBGQ1x1MzBCOFx1MzBFN1x1MzBGMz4KamF2YWMub3B0LmluaGVyaXRfcnVudGltZV9lbnZpcm9ubWVudD1cdTVCOUZcdTg4NENcdTY2NDJcdTc0QjBcdTU4ODNcdTMwNEJcdTMwODlcdTMwRTJcdTMwQjhcdTMwRTVcdTMwRkNcdTMwRUJcdTMwRkJcdTMwQjdcdTMwQjlcdTMwQzZcdTMwRTBcdTY5Q0JcdTYyMTBcdTMwQUFcdTMwRDdcdTMwQjdcdTMwRTdcdTMwRjNcdTMwOTJcdTdEOTlcdTYyN0ZcdTMwNTdcdTMwN0VcdTMwNTlcdTMwMDIKCiMjIGVycm9ycwoKamF2YWMuZXJyLmVtcHR5LkEuYXJndW1lbnQ9LUFcdTMwNkJcdTMwNkZcdTVGMTVcdTY1NzBcdTMwNENcdTVGQzVcdTg5ODFcdTMwNjdcdTMwNTlcdTMwMDInJy1Ba2V5JydcdTMwN0VcdTMwNUZcdTMwNkYnJy1Ba2V5PXZhbHVlJydcdTMwOTJcdTRGN0ZcdTc1MjhcdTMwNTdcdTMwNjZcdTMwNEZcdTMwNjBcdTMwNTVcdTMwNDQKamF2YWMuZXJyLmludmFsaWQuYXJnPXswfVx1MzA2Rlx1NzEyMVx1NTJCOVx1MzA2QVx1NUYxNVx1NjU3MFx1MzA2N1x1MzA1OQpqYXZhYy5lcnIuaW52YWxpZC5BLmtleT1cdTZDRThcdTkxQzhcdTMwRDdcdTMwRURcdTMwQkJcdTMwQzNcdTMwQjVcdTMwRkJcdTMwQUFcdTMwRDdcdTMwQjdcdTMwRTdcdTMwRjMnJ3swfScnXHUzMDZFXHUzMEFEXHUzMEZDXHUzMDZCXHU2MzA3XHU1QjlBXHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDhCXHU0RTAwXHU5MDIzXHUzMDZFXHU4QjU4XHU1MjI1XHU1QjUwXHUzMDRDXHUzMDAxXHUzMEM5XHUzMEMzXHUzMEM4XHUzMDY3XHU1MzNBXHU1MjA3XHUzMDg5XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDVCXHUzMDkzCmphdmFjLmVyci5pbnZhbGlkLmZsYWc9ezB9XHUzMDZGXHU3MTIxXHU1MkI5XHUzMDZBXHUzMEQ1XHUzMEU5XHUzMEIwXHUzMDY3XHUzMDU5CmphdmFjLmVyci5wcm9maWxlLmJvb3RjbGFzc3BhdGguY29uZmxpY3Q9cHJvZmlsZVx1MzA2OGJvb3RjbGFzc3BhdGhcdTMwQUFcdTMwRDdcdTMwQjdcdTMwRTdcdTMwRjNcdTMwNkZcdTU0MENcdTY2NDJcdTMwNkJcdTRGN0ZcdTc1MjhcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTMKamF2YWMuZXJyLmludmFsaWQucHJvZmlsZT1cdTcxMjFcdTUyQjlcdTMwNkFcdTMwRDdcdTMwRURcdTMwRDVcdTMwQTFcdTMwQTRcdTMwRUI6IHswfQpqYXZhYy5lcnIuaW52YWxpZC50YXJnZXQ9ezB9XHUzMDZGXHU3MTIxXHU1MkI5XHUzMDZBXHUzMEJGXHUzMEZDXHUzMEIyXHUzMEMzXHUzMEM4XHUzMEZCXHUzMEVBXHUzMEVBXHUzMEZDXHUzMEI5XHUzMDY3XHUzMDU5CmphdmFjLmVyci5vcHRpb24ubm90LmFsbG93ZWQud2l0aC50YXJnZXQ9XHUzMEFBXHUzMEQ3XHUzMEI3XHUzMEU3XHUzMEYzezB9XHUzMDZGXHUzMEJGXHUzMEZDXHUzMEIyXHUzMEMzXHUzMEM4ezF9XHUzMDY4XHUzMDY4XHUzMDgyXHUzMDZCXHU2MzA3XHU1QjlBXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzCmphdmFjLmVyci5vcHRpb24udG9vLm1hbnk9XHUzMEFBXHUzMEQ3XHUzMEI3XHUzMEU3XHUzMEYzezB9XHUzMDkyXHU2MzA3XHU1QjlBXHUzMDY3XHUzMDREXHUzMDhCXHUzMDZFXHUzMDZGMVx1NTZERVx1MzA2RVx1MzA3Rlx1MzA2N1x1MzA1OQpqYXZhYy5lcnIubm8uc291cmNlLmZpbGVzPVx1MzBCRFx1MzBGQ1x1MzBCOVx1MzBGQlx1MzBENVx1MzBBMVx1MzBBNFx1MzBFQlx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5MwpqYXZhYy5lcnIubm8uc291cmNlLmZpbGVzLmNsYXNzZXM9XHUzMEJEXHUzMEZDXHUzMEI5XHUzMEZCXHUzMEQ1XHUzMEExXHUzMEE0XHUzMEVCXHUzMDdFXHUzMDVGXHUzMDZGXHUzMEFGXHUzMEU5XHUzMEI5XHU1NDBEXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzCmphdmFjLmVyci5yZXEuYXJnPXswfVx1MzA2Qlx1MzA2Rlx1NUYxNVx1NjU3MFx1MzA0Q1x1NUZDNVx1ODk4MVx1MzA2N1x1MzA1OQpqYXZhYy5lcnIuaW52YWxpZC5zb3VyY2U9ezB9XHUzMDZGXHU3MTIxXHU1MkI5XHUzMDZBXHUzMEJEXHUzMEZDXHUzMEI5XHUzMEZCXHUzMEVBXHUzMEVBXHUzMEZDXHUzMEI5XHUzMDY3XHUzMDU5CmphdmFjLmVyci5lcnJvci53cml0aW5nLmZpbGU9ezB9XHUzMDZFXHU2NkY4XHU4RkJDXHUzMDdGXHUzMEE4XHUzMEU5XHUzMEZDXHUzMDY3XHUzMDU5XHUzMDAyezF9CmphdmFjLmVyci5zb3VyY2VwYXRoLm1vZHVsZXNvdXJjZXBhdGguY29uZmxpY3Q9LS1zb3VyY2UtcGF0aFx1MzA2OC0tbW9kdWxlLXNvdXJjZS1wYXRoXHUzMDZFXHU0RTIxXHU2NUI5XHUzMDkyXHU2MzA3XHU1QjlBXHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzCmphdmFjLndhcm4uc291cmNlLnRhcmdldC5jb25mbGljdD1cdTMwQkRcdTMwRkNcdTMwQjlcdTMwRkJcdTMwRUFcdTMwRUFcdTMwRkNcdTMwQjl7MH1cdTMwNkJcdTMwNkZcdTMwQkZcdTMwRkNcdTMwQjJcdTMwQzNcdTMwQzhcdTMwRkJcdTMwRUFcdTMwRUFcdTMwRkNcdTMwQjl7MX1cdTMwNENcdTVGQzVcdTg5ODFcdTMwNjdcdTMwNTkKamF2YWMud2Fybi50YXJnZXQuZGVmYXVsdC5zb3VyY2UuY29uZmxpY3Q9XHUzMEJGXHUzMEZDXHUzMEIyXHUzMEMzXHUzMEM4XHUzMEZCXHUzMEVBXHUzMEVBXHUzMEZDXHUzMEI5ezB9XHUzMDRDXHUzMEM3XHUzMEQ1XHUzMEE5XHUzMEVCXHUzMEM4XHUzMDZFXHUzMEJEXHUzMEZDXHUzMEI5XHUzMEZCXHUzMEVBXHUzMEVBXHUzMEZDXHUzMEI5ezF9XHUzMDY4XHU3QUY2XHU1NDA4XHUzMDU3XHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5CmphdmFjLndhcm4ucHJvZmlsZS50YXJnZXQuY29uZmxpY3Q9XHUzMEQ3XHUzMEVEXHUzMEQ1XHUzMEExXHUzMEE0XHUzMEVCezB9XHUzMDZGXHUzMEJGXHUzMEZDXHUzMEIyXHUzMEMzXHUzMEM4XHUzMEZCXHUzMEVBXHUzMEVBXHUzMEZDXHUzMEI5ezF9XHUzMDZCXHU1QkZFXHUzMDU3XHUzMDY2XHU2NzA5XHU1MkI5XHUzMDY3XHUzMDZGXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzCmphdmFjLmVyci5maWxlLm5vdC5mb3VuZD1cdTMwRDVcdTMwQTFcdTMwQTRcdTMwRUJcdTMwNENcdTg5OEJcdTMwNjRcdTMwNEJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTM6IHswfQpqYXZhYy5lcnIuZmlsZS5ub3QuZGlyZWN0b3J5PVx1MzBDN1x1MzBBM1x1MzBFQ1x1MzBBRlx1MzBDOFx1MzBFQVx1MzA2N1x1MzA2Rlx1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5MzogezB9CmphdmFjLmVyci5maWxlLm5vdC5maWxlPVx1MzBENVx1MzBBMVx1MzBBNFx1MzBFQlx1MzA2N1x1MzA2Rlx1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5MzogezB9CmphdmFjLmVyci5jYW5ub3QuYWNjZXNzLnJ1bnRpbWUuZW52PVx1NUI5Rlx1ODg0Q1x1NjY0Mlx1NzRCMFx1NTg4M1x1MzA2Qlx1MzBBMlx1MzBBRlx1MzBCQlx1MzBCOVx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5MwpqYXZhYy5lcnIuYmFkLnZhbHVlLmZvci5vcHRpb249ezB9XHUzMEFBXHUzMEQ3XHUzMEI3XHUzMEU3XHUzMEYzXHUzMDZFXHU1MDI0XHUzMDRDXHU0RTBEXHU2QjYzXHUzMDY3XHUzMDU5OiAnJ3sxfScnCmphdmFjLmVyci5uby52YWx1ZS5mb3Iub3B0aW9uPXswfVx1MzBBQVx1MzBEN1x1MzBCN1x1MzBFN1x1MzBGM1x1MzA2RVx1NTAyNFx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5MwpqYXZhYy5lcnIucmVwZWF0ZWQudmFsdWUuZm9yLnBhdGNoLm1vZHVsZT17MH1cdTMwNkJcdTVCRkVcdTMwNTdcdTMwNjYtLXBhdGNoLW1vZHVsZVx1MzA0Q1x1ODkwN1x1NjU3MFx1NTZERVx1NjMwN1x1NUI5QVx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1OQoKIyMgbWVzc2FnZXMKCmphdmFjLm1zZy51c2FnZS5oZWFkZXI9XHU0RjdGXHU3NTI4XHU2NUI5XHU2Q0Q1OiB7MH0gPG9wdGlvbnM+IDxzb3VyY2UgZmlsZXM+XG5cdTRGN0ZcdTc1MjhcdTUzRUZcdTgwRkRcdTMwNkFcdTMwQUFcdTMwRDdcdTMwQjdcdTMwRTdcdTMwRjNcdTMwNkJcdTMwNkZcdTZCMjFcdTMwNkVcdTMwODJcdTMwNkVcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlcdTMwMDIKCmphdmFjLm1zZy51c2FnZT1cdTRGN0ZcdTc1MjhcdTY1QjlcdTZDRDU6IHswfSA8b3B0aW9ucz4gPHNvdXJjZSBmaWxlcz5cblx1NEY3Rlx1NzUyOFx1NTNFRlx1ODBGRFx1MzA2QVx1MzBBQVx1MzBEN1x1MzBCN1x1MzBFN1x1MzBGM1x1MzA2RVx1MzBFQVx1MzBCOVx1MzBDOFx1MzA2Qlx1MzA2NFx1MzA0NFx1MzA2Nlx1MzA2Rlx1MzAwMS0taGVscFx1MzA5Mlx1NEY3Rlx1NzUyOFx1MzA1N1x1MzA3RVx1MzA1OQoKamF2YWMubXNnLnVzYWdlLm5vbnN0YW5kYXJkLmZvb3Rlcj1cdTMwNTNcdTMwNkVcdThGRkRcdTUyQTBcdTMwQUFcdTMwRDdcdTMwQjdcdTMwRTdcdTMwRjNcdTMwNkZcdTRFODhcdTU0NEFcdTMwNkFcdTMwNTdcdTMwNkJcdTU5MDlcdTY2RjRcdTMwNTVcdTMwOENcdTMwOEJcdTMwNTNcdTMwNjhcdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNTlcdTMwMDIKCmphdmFjLm1zZy5idWc9XHUzMEIzXHUzMEYzXHUzMEQxXHUzMEE0XHUzMEU5XHUzMDY3XHU0RjhCXHU1OTE2XHUzMDRDXHU3NjdBXHU3NTFGXHUzMDU3XHUzMDdFXHUzMDU3XHUzMDVGKHswfSlcdTMwMDJCdWcgRGF0YWJhc2UgKGh0dHA6Ly9idWdzLmphdmEuY29tKVx1MzA2N1x1OTFDRFx1ODkwN1x1MzA0Q1x1MzA2QVx1MzA0NFx1MzA0Qlx1MzA5Mlx1MzA1NFx1NzhCQVx1OEE4RFx1MzA2RVx1MzA0Nlx1MzA0OFx1MzAwMUphdmEgYnVnXHUzMEVDXHUzMEREXHUzMEZDXHUzMEM4XHUzMEZCXHUzMERBXHUzMEZDXHUzMEI4KGh0dHA6Ly9idWdyZXBvcnQuamF2YS5jb20pXHUzMDY3SmF2YVx1MzBCM1x1MzBGM1x1MzBEMVx1MzBBNFx1MzBFOVx1MzA2Qlx1NUJGRVx1MzA1OVx1MzA4QmJ1Z1x1MzA2RVx1NzY3Qlx1OTMzMlx1MzA5Mlx1MzA0QVx1OTg1OFx1MzA0NFx1MzA0NFx1MzA1Rlx1MzA1N1x1MzA3RVx1MzA1OVx1MzAwMlx1MzBFQ1x1MzBERFx1MzBGQ1x1MzBDOFx1MzA2Qlx1MzA2Rlx1MzAwMVx1MzA1RFx1MzA2RVx1MzBEN1x1MzBFRFx1MzBCMFx1MzBFOVx1MzBFMFx1MzA2OFx1NEUwQlx1OEExOFx1MzA2RVx1OEEzQVx1NjVBRFx1NTE4NVx1NUJCOVx1MzA5Mlx1NTQyQlx1MzA4MVx1MzA2Nlx1MzA0Rlx1MzA2MFx1MzA1NVx1MzA0NFx1MzAwMlx1MzA1NFx1NTM1NFx1NTI5Qlx1MzA0Mlx1MzA4QVx1MzA0Q1x1MzA2OFx1MzA0Nlx1MzA1NFx1MzA1Nlx1MzA0NFx1MzA3RVx1MzA1OVx1MzAwMgoKamF2YWMubXNnLmlvPVxuXG5cdTUxNjVcdTUxRkFcdTUyOUJcdTMwQThcdTMwRTlcdTMwRkNcdTMwNENcdTc2N0FcdTc1MUZcdTMwNTdcdTMwN0VcdTMwNTdcdTMwNUZcdTMwMDJcblx1OEE3M1x1N0QzMFx1MzA2Rlx1NkIyMVx1MzA2RVx1MzBCOVx1MzBCRlx1MzBDM1x1MzBBRlx1MzBDOFx1MzBFQ1x1MzBGQ1x1MzBCOVx1MzA2N1x1OEFCRlx1NjdGQlx1MzA1N1x1MzA2Nlx1MzA0Rlx1MzA2MFx1MzA1NVx1MzA0NFx1MzAwMlxuCgpqYXZhYy5tc2cucHJvYy5hbm5vdGF0aW9uLnVuY2F1Z2h0LmV4Y2VwdGlvbj1cblxuXHU2Q0U4XHU5MUM4XHU1MUU2XHU3NDA2XHUzMDY3XHU2MzU1XHU2MzQ5XHUzMDU1XHUzMDhDXHUzMDZBXHUzMDQ0XHU0RjhCXHU1OTE2XHUzMDRDXHUzMEI5XHUzMEVEXHUzMEZDXHUzMDU1XHUzMDhDXHUzMDdFXHUzMDU3XHUzMDVGXHUzMDAyXG5cdThBNzNcdTdEMzBcdTMwNkZcdTZCMjFcdTMwNkVcdTMwQjlcdTMwQkZcdTMwQzNcdTMwQUZcdTMwQzhcdTMwRUNcdTMwRkNcdTMwQjlcdTMwNjdcdThBQkZcdTY3RkJcdTMwNTdcdTMwNjZcdTMwNEZcdTMwNjBcdTMwNTVcdTMwNDRcdTMwMDJcbgoKamF2YWMubXNnLnBsdWdpbi51bmNhdWdodC5leGNlcHRpb249XG5cblx1MzBEN1x1MzBFOVx1MzBCMFx1MzBBNFx1MzBGM1x1MzA2N1x1NjM1NVx1NjM0OVx1MzA1NVx1MzA4Q1x1MzA2QVx1MzA0NFx1NEY4Qlx1NTkxNlx1MzA0Q1x1MzBCOVx1MzBFRFx1MzBGQ1x1MzA1NVx1MzA4Q1x1MzA3RVx1MzA1N1x1MzA1Rlx1MzAwMlxuXHU4QTczXHU3RDMwXHUzMDZGXHU2QjIxXHUzMDZFXHUzMEI5XHUzMEJGXHUzMEMzXHUzMEFGXHUzMEZCXHUzMEM4XHUzMEVDXHUzMEZDXHUzMEI5XHUzMDY3XHU4QUJGXHU2N0ZCXHUzMDU3XHUzMDY2XHUzMDRGXHUzMDYwXHUzMDU1XHUzMDQ0XHUzMDAyXG4KCmphdmFjLm1zZy5yZXNvdXJjZT1cblxuXHUzMEI3XHUzMEI5XHUzMEM2XHUzMEUwXHUzMEZCXHUzMEVBXHUzMEJEXHUzMEZDXHUzMEI5XHUzMDRDXHU0RTBEXHU4REIzXHUzMDU3XHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5XHUzMDAyXG5cdThBNzNcdTdEMzBcdTMwNkZcdTZCMjFcdTMwNkVcdTMwQjlcdTMwQkZcdTMwQzNcdTMwQUZcdTMwQzhcdTMwRUNcdTMwRkNcdTMwQjlcdTMwNjdcdThBQkZcdTY3RkJcdTMwNTdcdTMwNjZcdTMwNEZcdTMwNjBcdTMwNTVcdTMwNDRcdTMwMDJcbgoKamF2YWMudmVyc2lvbj17MH0gezF9CmphdmFjLmZ1bGxWZXJzaW9uPXswfVx1MzBENVx1MzBFQlx1MzBGQlx1MzBEMFx1MzBGQ1x1MzBCOFx1MzBFN1x1MzBGMyJ7MX0iCgpqYXZhYy5lcnIucmVsZWFzZS5ib290Y2xhc3NwYXRoLmNvbmZsaWN0PVx1MzBBQVx1MzBEN1x1MzBCN1x1MzBFN1x1MzBGM3swfVx1MzA2Ri0tcmVsZWFzZVx1MzA2OFx1NEUwMFx1N0REMlx1MzA2Qlx1NEY3Rlx1NzUyOFx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5MwoKamF2YWMuZXJyLnVuc3VwcG9ydGVkLnJlbGVhc2UudmVyc2lvbj1cdTMwRUFcdTMwRUFcdTMwRkNcdTMwQjlcdTMwRkJcdTMwRDBcdTMwRkNcdTMwQjhcdTMwRTdcdTMwRjN7MH1cdTMwNkZcdTMwQjVcdTMwRERcdTMwRkNcdTMwQzhcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNUJcdTMwOTMKCmphdmFjLmVyci5yZWxlYXNlLm5vdC5zdGFuZGFyZC5maWxlLm1hbmFnZXI9LS1yZWxlYXNlXHUzMEFBXHUzMEQ3XHUzMEI3XHUzMEU3XHUzMEYzXHUzMDRDXHU2MzA3XHU1QjlBXHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5XHUzMDRDXHUzMDAxXHU2MzA3XHU1QjlBXHUzMDU1XHUzMDhDXHUzMDVGSmF2YUZpbGVNYW5hZ2VyXHUzMDZGU3RhbmRhcmRKYXZhRmlsZU1hbmFnZXJcdTMwNjdcdTMwNkZcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTNcdTMwMDIKUEsDBAoAAAgAAAY7qUo6BHIJfV0AAH1dAAAvAAAAY29tL3N1bi90b29scy9qYXZhYy9yZXNvdXJjZXMvbGVnYWN5LnByb3BlcnRpZXMjCiMgQ29weXJpZ2h0IChjKSAyMDA2LCAyMDEwLCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgojIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KIwojIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiMgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKIyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKIyBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiMgYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiMKIyBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKIyBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKIyBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKIyB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAojIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiMKIyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiMgMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAojIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KIwojIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiMgb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQojIHF1ZXN0aW9ucy4KIwoKY29tLnN1bi5hY2Nlc3NpYmlsaXR5LmludGVybmFsLnJlc291cmNlcyA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLmF3dCA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLmJlYW5zID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4uY29yYmEuc2UuaW1wbC5hY3RpdmF0aW9uID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4uY29yYmEuc2UuaW1wbC5jb3B5b2JqZWN0ID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4uY29yYmEuc2UuaW1wbC5jb3JiYSA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLmNvcmJhLnNlLmltcGwuZHluYW1pY2FueSA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLmNvcmJhLnNlLmltcGwuZW5jb2RpbmcgPSB0aWdlciBsZWdhY3kKY29tLnN1bi5jb3JiYS5zZS5pbXBsLmludGVyY2VwdG9ycyA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLmNvcmJhLnNlLmltcGwuaW8gPSB0aWdlciBsZWdhY3kKY29tLnN1bi5jb3JiYS5zZS5pbXBsLmlvciA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLmNvcmJhLnNlLmltcGwuaW9yLmlpb3AgPSB0aWdlciBsZWdhY3kKY29tLnN1bi5jb3JiYS5zZS5pbXBsLmphdmF4LnJtaSA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLmNvcmJhLnNlLmltcGwuamF2YXgucm1pLkNPUkJBID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4uY29yYmEuc2UuaW1wbC5sZWdhY3kuY29ubmVjdGlvbiA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLmNvcmJhLnNlLmltcGwubG9nZ2luZyA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLmNvcmJhLnNlLmltcGwubW9uaXRvcmluZyA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLmNvcmJhLnNlLmltcGwubmFtaW5nLmNvc25hbWluZyA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLmNvcmJhLnNlLmltcGwubmFtaW5nLm5hbWluZ3V0aWwgPSB0aWdlciBsZWdhY3kKY29tLnN1bi5jb3JiYS5zZS5pbXBsLm5hbWluZy5wY29zbmFtaW5nID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4uY29yYmEuc2UuaW1wbC5vYSA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLmNvcmJhLnNlLmltcGwub2EucG9hID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4uY29yYmEuc2UuaW1wbC5vYS50b2EgPSB0aWdlciBsZWdhY3kKY29tLnN1bi5jb3JiYS5zZS5pbXBsLm9yYiA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLmNvcmJhLnNlLmltcGwub3JidXRpbCA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLmNvcmJhLnNlLmltcGwub3JidXRpbC5jbG9zdXJlID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4uY29yYmEuc2UuaW1wbC5vcmJ1dGlsLmNvbmN1cnJlbnQgPSB0aWdlciBsZWdhY3kKY29tLnN1bi5jb3JiYS5zZS5pbXBsLm9yYnV0aWwuZnNtID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4uY29yYmEuc2UuaW1wbC5vcmJ1dGlsLmdyYXBoID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4uY29yYmEuc2UuaW1wbC5vcmJ1dGlsLnJlc291cmNlcyA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLmNvcmJhLnNlLmltcGwub3JidXRpbC50aHJlYWRwb29sID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4uY29yYmEuc2UuaW1wbC5wcmVzZW50YXRpb24ucm1pID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4uY29yYmEuc2UuaW1wbC5wcm90b2NvbCA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLmNvcmJhLnNlLmltcGwucHJvdG9jb2wuZ2lvcG1zZ2hlYWRlcnMgPSB0aWdlciBsZWdhY3kKY29tLnN1bi5jb3JiYS5zZS5pbXBsLnJlc29sdmVyID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4uY29yYmEuc2UuaW1wbC50cmFuc3BvcnQgPSB0aWdlciBsZWdhY3kKY29tLnN1bi5jb3JiYS5zZS5pbXBsLnV0aWwgPSB0aWdlciBsZWdhY3kKY29tLnN1bi5jb3JiYS5zZS5pbnRlcm5hbC5Db3NOYW1pbmcgPSB0aWdlciBsZWdhY3kKY29tLnN1bi5jb3JiYS5zZS5pbnRlcm5hbC5JbnRlcmNlcHRvcnMgPSB0aWdlciBsZWdhY3kKY29tLnN1bi5jb3JiYS5zZS5pbnRlcm5hbC5QT0EgPSB0aWdlciBsZWdhY3kKY29tLnN1bi5jb3JiYS5zZS5pbnRlcm5hbC5jb3JiYSA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLmNvcmJhLnNlLmludGVybmFsLmlpb3AgPSB0aWdlciBsZWdhY3kKY29tLnN1bi5jb3JiYS5zZS5vcmcub21nLkNPUkJBID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4uY29yYmEuc2UucGVwdC5icm9rZXIgPSB0aWdlciBsZWdhY3kKY29tLnN1bi5jb3JiYS5zZS5wZXB0LmVuY29kaW5nID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4uY29yYmEuc2UucGVwdC5wcm90b2NvbCA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLmNvcmJhLnNlLnBlcHQudHJhbnNwb3J0ID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4uY29yYmEuc2Uuc3BpLmFjdGl2YXRpb24gPSB0aWdlciBsZWdhY3kKY29tLnN1bi5jb3JiYS5zZS5zcGkuYWN0aXZhdGlvbi5Jbml0aWFsTmFtZVNlcnZpY2VQYWNrYWdlID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4uY29yYmEuc2Uuc3BpLmFjdGl2YXRpb24uTG9jYXRvclBhY2thZ2UgPSB0aWdlciBsZWdhY3kKY29tLnN1bi5jb3JiYS5zZS5zcGkuYWN0aXZhdGlvbi5SZXBvc2l0b3J5UGFja2FnZSA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLmNvcmJhLnNlLnNwaS5jb3B5b2JqZWN0ID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4uY29yYmEuc2Uuc3BpLmVuY29kaW5nID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4uY29yYmEuc2Uuc3BpLmV4dGVuc2lvbiA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLmNvcmJhLnNlLnNwaS5pb3IgPSB0aWdlciBsZWdhY3kKY29tLnN1bi5jb3JiYS5zZS5zcGkuaW9yLmlpb3AgPSB0aWdlciBsZWdhY3kKY29tLnN1bi5jb3JiYS5zZS5zcGkubGVnYWN5LmNvbm5lY3Rpb24gPSB0aWdlciBsZWdhY3kKY29tLnN1bi5jb3JiYS5zZS5zcGkubGVnYWN5LmludGVyY2VwdG9yID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4uY29yYmEuc2Uuc3BpLmxvZ2dpbmcgPSB0aWdlciBsZWdhY3kKY29tLnN1bi5jb3JiYS5zZS5zcGkubW9uaXRvcmluZyA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLmNvcmJhLnNlLnNwaS5vYSA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLmNvcmJhLnNlLnNwaS5vcmIgPSB0aWdlciBsZWdhY3kKY29tLnN1bi5jb3JiYS5zZS5zcGkub3JidXRpbC5jbG9zdXJlID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4uY29yYmEuc2Uuc3BpLm9yYnV0aWwuZnNtID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4uY29yYmEuc2Uuc3BpLm9yYnV0aWwucHJveHkgPSB0aWdlciBsZWdhY3kKY29tLnN1bi5jb3JiYS5zZS5zcGkub3JidXRpbC50aHJlYWRwb29sID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4uY29yYmEuc2Uuc3BpLnByZXNlbnRhdGlvbi5ybWkgPSB0aWdlciBsZWdhY3kKY29tLnN1bi5jb3JiYS5zZS5zcGkucHJvdG9jb2wgPSB0aWdlciBsZWdhY3kKY29tLnN1bi5jb3JiYS5zZS5zcGkucmVzb2x2ZXIgPSB0aWdlciBsZWdhY3kKY29tLnN1bi5jb3JiYS5zZS5zcGkuc2VydmljZWNvbnRleHQgPSB0aWdlciBsZWdhY3kKY29tLnN1bi5jb3JiYS5zZS5zcGkudHJhbnNwb3J0ID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4uaW1hZ2Vpby5tZXRhZGF0YSA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLmltYWdlaW8ucGx1Z2lucy5ibXAgPSB0aWdlciBsZWdhY3kKY29tLnN1bi5pbWFnZWlvLnBsdWdpbnMuY29tbW9uID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4uaW1hZ2Vpby5wbHVnaW5zLmdpZiA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLmltYWdlaW8ucGx1Z2lucy5qcGVnID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4uaW1hZ2Vpby5wbHVnaW5zLnBuZyA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLmltYWdlaW8ucGx1Z2lucy53Ym1wID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4uaW1hZ2Vpby5zcGkgPSB0aWdlciBsZWdhY3kKY29tLnN1bi5qYXZhLnN3aW5nID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4uamF2YS5zd2luZy5wbGFmLmd0ayA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLmphdmEuc3dpbmcucGxhZi5ndGsuaWNvbnMgPSB0aWdlciBsZWdhY3kKY29tLnN1bi5qYXZhLnN3aW5nLnBsYWYuZ3RrLnJlc291cmNlcyA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLmphdmEuc3dpbmcucGxhZi5ndGsucmVzb3VyY2VzLm1ldGFjaXR5LlN3aW5nRmFsbGJhY2tUaGVtZS5tZXRhY2l0eS0xID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4uamF2YS5zd2luZy5wbGFmLm1vdGlmID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4uamF2YS5zd2luZy5wbGFmLm1vdGlmLmljb25zID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4uamF2YS5zd2luZy5wbGFmLm1vdGlmLnJlc291cmNlcyA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLmphdmEuc3dpbmcucGxhZi5uaW1idXMgPSB0aWdlciBsZWdhY3kKY29tLnN1bi5qYXZhLnN3aW5nLnBsYWYud2luZG93cyA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLmphdmEuc3dpbmcucGxhZi53aW5kb3dzLmljb25zID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4uamF2YS5zd2luZy5wbGFmLndpbmRvd3MucmVzb3VyY2VzID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4uamF2YS51dGlsLmphci5wYWNrID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwgPSB0aWdlciBsZWdhY3kKY29tLnN1bi5qYXZhX2N1cC5pbnRlcm5hbC5ydW50aW1lID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4uamxleC5pbnRlcm5hbCA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLmpteC5kZWZhdWx0cyA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLmpteC5pbnRlcmNlcHRvciA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLmpteC5tYmVhbnNlcnZlciA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLmpteC5yZW1vdGUuaW50ZXJuYWwgPSB0aWdlciBsZWdhY3kKY29tLnN1bi5qbXgucmVtb3RlLnByb3RvY29sLmlpb3AgPSB0aWdlciBsZWdhY3kKY29tLnN1bi5qbXgucmVtb3RlLnByb3RvY29sLnJtaSA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLmpteC5yZW1vdGUuc2VjdXJpdHkgPSB0aWdlciBsZWdhY3kKY29tLnN1bi5qbXgucmVtb3RlLnV0aWwgPSB0aWdlciBsZWdhY3kKY29tLnN1bi5qbXguc25tcCA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLmpteC5zbm1wLklQQWNsID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4uam14LnNubXAuYWdlbnQgPSB0aWdlciBsZWdhY3kKY29tLnN1bi5qbXguc25tcC5kYWVtb24gPSB0aWdlciBsZWdhY3kKY29tLnN1bi5qbXguc25tcC5kZWZhdWx0cyA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLmpteC5zbm1wLmludGVybmFsID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4uam14LnNubXAubXBtID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4uam14LnNubXAudGFza3MgPSB0aWdlciBsZWdhY3kKY29tLnN1bi5qbXgudHJhY2UgPSB0aWdlciBsZWdhY3kKY29tLnN1bi5qbmRpLmNvc25hbWluZyA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLmpuZGkuZG5zID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4uam5kaS5sZGFwID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4uam5kaS5sZGFwLmV4dCA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLmpuZGkubGRhcC5wb29sID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4uam5kaS5sZGFwLnNhc2wgPSB0aWdlciBsZWdhY3kKY29tLnN1bi5qbmRpLnJtaS5yZWdpc3RyeSA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLmpuZGkudG9vbGtpdC5jb3JiYSA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLmpuZGkudG9vbGtpdC5jdHggPSB0aWdlciBsZWdhY3kKY29tLnN1bi5qbmRpLnRvb2xraXQuZGlyID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4uam5kaS50b29sa2l0LnVybCA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLmpuZGkudXJsLmNvcmJhbmFtZSA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLmpuZGkudXJsLmRucyA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLmpuZGkudXJsLmlpb3AgPSB0aWdlciBsZWdhY3kKY29tLnN1bi5qbmRpLnVybC5paW9wbmFtZSA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLmpuZGkudXJsLmxkYXAgPSB0aWdlciBsZWdhY3kKY29tLnN1bi5qbmRpLnVybC5sZGFwcyA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLmpuZGkudXJsLnJtaSA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLm1hbmFnZW1lbnQgPSB0aWdlciBsZWdhY3kKY29tLnN1bi5tYW5hZ2VtZW50LmpteCA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLm1lZGlhLnNvdW5kID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4ubmFtaW5nLmludGVybmFsID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4ubmV0LnNzbCA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLm5ldC5zc2wuaW50ZXJuYWwuc3NsID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4ubmV0LnNzbC5pbnRlcm5hbC53d3cucHJvdG9jb2wuaHR0cHMgPSB0aWdlciBsZWdhY3kKY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwgPSB0aWdlciBsZWdhY3kKY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuY2xhc3NmaWxlID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4ub3JnLmFwYWNoZS5iY2VsLmludGVybmFsLmdlbmVyaWMgPSB0aWdlciBsZWdhY3kKY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwudXRpbCA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC52ZXJpZmllciA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC52ZXJpZmllci5leGMgPSB0aWdlciBsZWdhY3kKY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwudmVyaWZpZXIuc3RhdGljcyA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC52ZXJpZmllci5zdHJ1Y3R1cmFscyA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLm9yZy5hcGFjaGUuaHRtbC5pbnRlcm5hbC5kb20gPSB0aWdlciBsZWdhY3kKY29tLnN1bi5vcmcuYXBhY2hlLnJlZ2V4cC5pbnRlcm5hbCA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLm9yZy5hcGFjaGUud21sLmludGVybmFsID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4ub3JnLmFwYWNoZS53bWwuaW50ZXJuYWwuZG9tID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbCA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwuY2xpZW50ID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC5leHRlbnNpb25zID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC5saWIgPSB0aWdlciBsZWdhY3kKY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnJlcyA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwudGVtcGxhdGVzID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0ID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0YyA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY21kbGluZSA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY21kbGluZS5nZXRvcHQgPSB0aWdlciBsZWdhY3kKY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jb21waWxlci51dGlsID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5kb20gPSB0aWdlciBsZWdhY3kKY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLnJ1bnRpbWUgPSB0aWdlciBsZWdhY3kKY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLnJ1bnRpbWUub3V0cHV0ID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy50cmF4ID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy51dGlsID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuZG9tID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuZG9tLmV2ZW50cyA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmRvbTMuYXMgPSB0aWdlciBsZWdhY3kKY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdGQgPSB0aWdlciBsZWdhY3kKY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR0ZC5tb2RlbHMgPSB0aWdlciBsZWdhY3kKY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2ID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi5kdGQgPSB0aWdlciBsZWdhY3kKY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LnV0aWwgPSB0aWdlciBsZWdhY3kKY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLmR2LnhzID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5pbyA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwubXNnID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC52YWxpZGF0aW9uID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cGF0aCA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHBhdGgucmVnZXggPSB0aWdlciBsZWdhY3kKY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy5kb20gPSB0aWdlciBsZWdhY3kKY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLmlkZW50aXR5ID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy5tb2RlbHMgPSB0aWdlciBsZWdhY3kKY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLm9wdGkgPSB0aWdlciBsZWdhY3kKY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLnRyYXZlcnNlcnMgPSB0aWdlciBsZWdhY3kKY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLnV0aWwgPSB0aWdlciBsZWdhY3kKY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5qYXhwID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuamF4cC5kYXRhdHlwZSA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmpheHAudmFsaWRhdGlvbiA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmpheHAudmFsaWRhdGlvbi54cyA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnBhcnNlcnMgPSB0aWdlciBsZWdhY3kKY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlsID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueGluY2x1ZGUgPSB0aWdlciBsZWdhY3kKY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkgPSB0aWdlciBsZWdhY3kKY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkuZ3JhbW1hcnMgPSB0aWdlciBsZWdhY3kKY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54bmkucGFyc2VyID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwueHMgPSB0aWdlciBsZWdhY3kKY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0gPSB0aWdlciBsZWdhY3kKY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0ucmVmID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLnJlZi5kb20yZHRtID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLnJlZi5zYXgyZHRtID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwucmVzID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplciA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMucmVzID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuc3ludGhldGljID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwudXRpbHMuc3ludGhldGljLnJlZmxlY3Rpb24gPSB0aWdlciBsZWdhY3kKY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5heGVzID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5jb21waWxlciA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuZnVuY3Rpb25zID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5qYXhwID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vYmplY3RzID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5vcGVyYXRpb25zID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5wYXR0ZXJucyA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwucmVzID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4ub3JnLm9tZy5DT1JCQSA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLm9yZy5vbWcuQ09SQkEuVmFsdWVEZWZQYWNrYWdlID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4ub3JnLm9tZy5DT1JCQS5wb3J0YWJsZSA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLm9yZy5vbWcuU2VuZGluZ0NvbnRleHQgPSB0aWdlciBsZWdhY3kKY29tLnN1bi5vcmcub21nLlNlbmRpbmdDb250ZXh0LkNvZGVCYXNlUGFja2FnZSA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLnJtaS5ybWlkID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4ucm93c2V0ID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4ucm93c2V0LmludGVybmFsID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4ucm93c2V0LnByb3ZpZGVycyA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLnNlY3VyaXR5LmF1dGggPSB0aWdlciBsZWdhY3kKY29tLnN1bi5zZWN1cml0eS5hdXRoLmNhbGxiYWNrID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4uc2VjdXJpdHkuYXV0aC5sb2dpbiA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLnNlY3VyaXR5LmF1dGgubW9kdWxlID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4uc2VjdXJpdHkuY2VydC5pbnRlcm5hbC54NTA5ID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4uc2VjdXJpdHkuamdzcyA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLnNlY3VyaXR5LnNhc2wgPSB0aWdlciBsZWdhY3kKY29tLnN1bi5zZWN1cml0eS5zYXNsLmRpZ2VzdCA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLnNlY3VyaXR5LnNhc2wuZ3Nza2VyYiA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLnNlY3VyaXR5LnNhc2wudXRpbCA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLnN3aW5nLmludGVybmFsLnBsYWYuYmFzaWMucmVzb3VyY2VzID0gdGlnZXIgbGVnYWN5CmNvbS5zdW4uc3dpbmcuaW50ZXJuYWwucGxhZi5tZXRhbC5yZXNvdXJjZXMgPSB0aWdlciBsZWdhY3kKY29tLnN1bi5zd2luZy5pbnRlcm5hbC5wbGFmLnN5bnRoLnJlc291cmNlcyA9IHRpZ2VyIGxlZ2FjeQpjb20uc3VuLnRyYWNpbmcgPSB0aWdlciBsZWdhY3kKY29tLnN1bi50cmFjaW5nLmR0cmFjZSA9IHRpZ2VyIGxlZ2FjeQpqYXZhLmFwcGxldCA9IHRpZ2VyIGxlZ2FjeQpqYXZhLmF3dCA9IHRpZ2VyIGxlZ2FjeQpqYXZhLmF3dC5jb2xvciA9IHRpZ2VyIGxlZ2FjeQpqYXZhLmF3dC5kYXRhdHJhbnNmZXIgPSB0aWdlciBsZWdhY3kKamF2YS5hd3QuZG5kID0gdGlnZXIgbGVnYWN5CmphdmEuYXd0LmRuZC5wZWVyID0gdGlnZXIgbGVnYWN5CmphdmEuYXd0LmV2ZW50ID0gdGlnZXIgbGVnYWN5CmphdmEuYXd0LmZvbnQgPSB0aWdlciBsZWdhY3kKamF2YS5hd3QuZ2VvbSA9IHRpZ2VyIGxlZ2FjeQpqYXZhLmF3dC5pbSA9IHRpZ2VyIGxlZ2FjeQpqYXZhLmF3dC5pbS5zcGkgPSB0aWdlciBsZWdhY3kKamF2YS5hd3QuaW1hZ2UgPSB0aWdlciBsZWdhY3kKamF2YS5hd3QuaW1hZ2UucmVuZGVyYWJsZSA9IHRpZ2VyIGxlZ2FjeQpqYXZhLmF3dC5wZWVyID0gdGlnZXIgbGVnYWN5CmphdmEuYXd0LnByaW50ID0gdGlnZXIgbGVnYWN5CmphdmEuYmVhbnMgPSB0aWdlciBsZWdhY3kKamF2YS5iZWFucy5iZWFuY29udGV4dCA9IHRpZ2VyIGxlZ2FjeQpqYXZhLmlvID0gdGlnZXIgbGVnYWN5CmphdmEubGFuZyA9IHRpZ2VyIGxlZ2FjeQpqYXZhLmxhbmcuYW5ub3RhdGlvbiA9IHRpZ2VyIGxlZ2FjeQpqYXZhLmxhbmcuaW5zdHJ1bWVudCA9IHRpZ2VyIGxlZ2FjeQpqYXZhLmxhbmcubWFuYWdlbWVudCA9IHRpZ2VyIGxlZ2FjeQpqYXZhLmxhbmcucmVmID0gdGlnZXIgbGVnYWN5CmphdmEubGFuZy5yZWZsZWN0ID0gdGlnZXIgbGVnYWN5CmphdmEubWF0aCA9IHRpZ2VyIGxlZ2FjeQpqYXZhLm5ldCA9IHRpZ2VyIGxlZ2FjeQpqYXZhLm5pbyA9IHRpZ2VyIGxlZ2FjeQpqYXZhLm5pby5jaGFubmVscyA9IHRpZ2VyIGxlZ2FjeQpqYXZhLm5pby5jaGFubmVscy5zcGkgPSB0aWdlciBsZWdhY3kKamF2YS5uaW8uY2hhcnNldCA9IHRpZ2VyIGxlZ2FjeQpqYXZhLm5pby5jaGFyc2V0LnNwaSA9IHRpZ2VyIGxlZ2FjeQpqYXZhLnJtaSA9IHRpZ2VyIGxlZ2FjeQpqYXZhLnJtaS5hY3RpdmF0aW9uID0gdGlnZXIgbGVnYWN5CmphdmEucm1pLmRnYyA9IHRpZ2VyIGxlZ2FjeQpqYXZhLnJtaS5yZWdpc3RyeSA9IHRpZ2VyIGxlZ2FjeQpqYXZhLnJtaS5zZXJ2ZXIgPSB0aWdlciBsZWdhY3kKamF2YS5zZWN1cml0eSA9IHRpZ2VyIGxlZ2FjeQpqYXZhLnNlY3VyaXR5LmFjbCA9IHRpZ2VyIGxlZ2FjeQpqYXZhLnNlY3VyaXR5LmNlcnQgPSB0aWdlciBsZWdhY3kKamF2YS5zZWN1cml0eS5pbnRlcmZhY2VzID0gdGlnZXIgbGVnYWN5CmphdmEuc2VjdXJpdHkuc3BlYyA9IHRpZ2VyIGxlZ2FjeQpqYXZhLnNxbCA9IHRpZ2VyIGxlZ2FjeQpqYXZhLnRleHQgPSB0aWdlciBsZWdhY3kKamF2YS51dGlsID0gdGlnZXIgbGVnYWN5CmphdmEudXRpbC5jb25jdXJyZW50ID0gdGlnZXIgbGVnYWN5CmphdmEudXRpbC5jb25jdXJyZW50LmF0b21pYyA9IHRpZ2VyIGxlZ2FjeQpqYXZhLnV0aWwuY29uY3VycmVudC5sb2NrcyA9IHRpZ2VyIGxlZ2FjeQpqYXZhLnV0aWwuamFyID0gdGlnZXIgbGVnYWN5CmphdmEudXRpbC5sb2dnaW5nID0gdGlnZXIgbGVnYWN5CmphdmEudXRpbC5wcmVmcyA9IHRpZ2VyIGxlZ2FjeQpqYXZhLnV0aWwucmVnZXggPSB0aWdlciBsZWdhY3kKamF2YS51dGlsLnppcCA9IHRpZ2VyIGxlZ2FjeQpqYXZheC5hY2Nlc3NpYmlsaXR5ID0gdGlnZXIgbGVnYWN5CmphdmF4LmFjdGl2aXR5ID0gdGlnZXIgbGVnYWN5CmphdmF4LmltYWdlaW8gPSB0aWdlciBsZWdhY3kKamF2YXguaW1hZ2Vpby5ldmVudCA9IHRpZ2VyIGxlZ2FjeQpqYXZheC5pbWFnZWlvLm1ldGFkYXRhID0gdGlnZXIgbGVnYWN5CmphdmF4LmltYWdlaW8ucGx1Z2lucy5ibXAgPSB0aWdlciBsZWdhY3kKamF2YXguaW1hZ2Vpby5wbHVnaW5zLmpwZWcgPSB0aWdlciBsZWdhY3kKamF2YXguaW1hZ2Vpby5zcGkgPSB0aWdlciBsZWdhY3kKamF2YXguaW1hZ2Vpby5zdHJlYW0gPSB0aWdlciBsZWdhY3kKamF2YXgubWFuYWdlbWVudCA9IHRpZ2VyIGxlZ2FjeQpqYXZheC5tYW5hZ2VtZW50LmxvYWRpbmcgPSB0aWdlciBsZWdhY3kKamF2YXgubWFuYWdlbWVudC5tb2RlbG1iZWFuID0gdGlnZXIgbGVnYWN5CmphdmF4Lm1hbmFnZW1lbnQubW9uaXRvciA9IHRpZ2VyIGxlZ2FjeQpqYXZheC5tYW5hZ2VtZW50Lm9wZW5tYmVhbiA9IHRpZ2VyIGxlZ2FjeQpqYXZheC5tYW5hZ2VtZW50LnJlbGF0aW9uID0gdGlnZXIgbGVnYWN5CmphdmF4Lm1hbmFnZW1lbnQucmVtb3RlID0gdGlnZXIgbGVnYWN5CmphdmF4Lm1hbmFnZW1lbnQucmVtb3RlLnJtaSA9IHRpZ2VyIGxlZ2FjeQpqYXZheC5tYW5hZ2VtZW50LnRpbWVyID0gdGlnZXIgbGVnYWN5CmphdmF4Lm5hbWluZyA9IHRpZ2VyIGxlZ2FjeQpqYXZheC5uYW1pbmcuZGlyZWN0b3J5ID0gdGlnZXIgbGVnYWN5CmphdmF4Lm5hbWluZy5ldmVudCA9IHRpZ2VyIGxlZ2FjeQpqYXZheC5uYW1pbmcubGRhcCA9IHRpZ2VyIGxlZ2FjeQpqYXZheC5uYW1pbmcuc3BpID0gdGlnZXIgbGVnYWN5CmphdmF4Lm5ldCA9IHRpZ2VyIGxlZ2FjeQpqYXZheC5uZXQuc3NsID0gdGlnZXIgbGVnYWN5CmphdmF4LnByaW50ID0gdGlnZXIgbGVnYWN5CmphdmF4LnByaW50LmF0dHJpYnV0ZSA9IHRpZ2VyIGxlZ2FjeQpqYXZheC5wcmludC5hdHRyaWJ1dGUuc3RhbmRhcmQgPSB0aWdlciBsZWdhY3kKamF2YXgucHJpbnQuZXZlbnQgPSB0aWdlciBsZWdhY3kKamF2YXgucm1pID0gdGlnZXIgbGVnYWN5CmphdmF4LnJtaS5DT1JCQSA9IHRpZ2VyIGxlZ2FjeQpqYXZheC5ybWkuc3NsID0gdGlnZXIgbGVnYWN5CmphdmF4LnNlY3VyaXR5LmF1dGggPSB0aWdlciBsZWdhY3kKamF2YXguc2VjdXJpdHkuYXV0aC5jYWxsYmFjayA9IHRpZ2VyIGxlZ2FjeQpqYXZheC5zZWN1cml0eS5hdXRoLmtlcmJlcm9zID0gdGlnZXIgbGVnYWN5CmphdmF4LnNlY3VyaXR5LmF1dGgubG9naW4gPSB0aWdlciBsZWdhY3kKamF2YXguc2VjdXJpdHkuYXV0aC5zcGkgPSB0aWdlciBsZWdhY3kKamF2YXguc2VjdXJpdHkuYXV0aC54NTAwID0gdGlnZXIgbGVnYWN5CmphdmF4LnNlY3VyaXR5LmNlcnQgPSB0aWdlciBsZWdhY3kKamF2YXguc2VjdXJpdHkuc2FzbCA9IHRpZ2VyIGxlZ2FjeQpqYXZheC5zb3VuZC5taWRpID0gdGlnZXIgbGVnYWN5CmphdmF4LnNvdW5kLm1pZGkuc3BpID0gdGlnZXIgbGVnYWN5CmphdmF4LnNvdW5kLnNhbXBsZWQgPSB0aWdlciBsZWdhY3kKamF2YXguc291bmQuc2FtcGxlZC5zcGkgPSB0aWdlciBsZWdhY3kKamF2YXguc3FsID0gdGlnZXIgbGVnYWN5CmphdmF4LnNxbC5yb3dzZXQgPSB0aWdlciBsZWdhY3kKamF2YXguc3FsLnJvd3NldC5zZXJpYWwgPSB0aWdlciBsZWdhY3kKamF2YXguc3FsLnJvd3NldC5zcGkgPSB0aWdlciBsZWdhY3kKamF2YXguc3dpbmcgPSB0aWdlciBsZWdhY3kKamF2YXguc3dpbmcuYm9yZGVyID0gdGlnZXIgbGVnYWN5CmphdmF4LnN3aW5nLmNvbG9yY2hvb3NlciA9IHRpZ2VyIGxlZ2FjeQpqYXZheC5zd2luZy5ldmVudCA9IHRpZ2VyIGxlZ2FjeQpqYXZheC5zd2luZy5maWxlY2hvb3NlciA9IHRpZ2VyIGxlZ2FjeQpqYXZheC5zd2luZy5wbGFmID0gdGlnZXIgbGVnYWN5CmphdmF4LnN3aW5nLnBsYWYuYmFzaWMgPSB0aWdlciBsZWdhY3kKamF2YXguc3dpbmcucGxhZi5iYXNpYy5pY29ucyA9IHRpZ2VyIGxlZ2FjeQpqYXZheC5zd2luZy5wbGFmLm1ldGFsID0gdGlnZXIgbGVnYWN5CmphdmF4LnN3aW5nLnBsYWYubWV0YWwuaWNvbnMgPSB0aWdlciBsZWdhY3kKamF2YXguc3dpbmcucGxhZi5tZXRhbC5pY29ucy5vY2VhbiA9IHRpZ2VyIGxlZ2FjeQpqYXZheC5zd2luZy5wbGFmLm1ldGFsLnNvdW5kcyA9IHRpZ2VyIGxlZ2FjeQpqYXZheC5zd2luZy5wbGFmLm11bHRpID0gdGlnZXIgbGVnYWN5CmphdmF4LnN3aW5nLnBsYWYubmltYnVzID0gdGlnZXIgbGVnYWN5CmphdmF4LnN3aW5nLnBsYWYuc3ludGggPSB0aWdlciBsZWdhY3kKamF2YXguc3dpbmcudGFibGUgPSB0aWdlciBsZWdhY3kKamF2YXguc3dpbmcudGV4dCA9IHRpZ2VyIGxlZ2FjeQpqYXZheC5zd2luZy50ZXh0Lmh0bWwgPSB0aWdlciBsZWdhY3kKamF2YXguc3dpbmcudGV4dC5odG1sLmljb25zID0gdGlnZXIgbGVnYWN5CmphdmF4LnN3aW5nLnRleHQuaHRtbC5wYXJzZXIgPSB0aWdlciBsZWdhY3kKamF2YXguc3dpbmcudGV4dC5ydGYgPSB0aWdlciBsZWdhY3kKamF2YXguc3dpbmcudGV4dC5ydGYuY2hhcnNldHMgPSB0aWdlciBsZWdhY3kKamF2YXguc3dpbmcudHJlZSA9IHRpZ2VyIGxlZ2FjeQpqYXZheC5zd2luZy51bmRvID0gdGlnZXIgbGVnYWN5CmphdmF4LnRyYW5zYWN0aW9uID0gdGlnZXIgbGVnYWN5CmphdmF4LnRyYW5zYWN0aW9uLnhhID0gdGlnZXIgbGVnYWN5CmphdmF4LnhtbCA9IHRpZ2VyIGxlZ2FjeQpqYXZheC54bWwuZGF0YXR5cGUgPSB0aWdlciBsZWdhY3kKamF2YXgueG1sLm5hbWVzcGFjZSA9IHRpZ2VyIGxlZ2FjeQpqYXZheC54bWwucGFyc2VycyA9IHRpZ2VyIGxlZ2FjeQpqYXZheC54bWwudHJhbnNmb3JtID0gdGlnZXIgbGVnYWN5CmphdmF4LnhtbC50cmFuc2Zvcm0uZG9tID0gdGlnZXIgbGVnYWN5CmphdmF4LnhtbC50cmFuc2Zvcm0uc2F4ID0gdGlnZXIgbGVnYWN5CmphdmF4LnhtbC50cmFuc2Zvcm0uc3RyZWFtID0gdGlnZXIgbGVnYWN5CmphdmF4LnhtbC52YWxpZGF0aW9uID0gdGlnZXIgbGVnYWN5CmphdmF4LnhtbC54cGF0aCA9IHRpZ2VyIGxlZ2FjeQpvcmcuaWV0Zi5qZ3NzID0gdGlnZXIgbGVnYWN5Cm9yZy5vbWcuQ09SQkEgPSB0aWdlciBsZWdhY3kKb3JnLm9tZy5DT1JCQS5EeW5BbnlQYWNrYWdlID0gdGlnZXIgbGVnYWN5Cm9yZy5vbWcuQ09SQkEuT1JCUGFja2FnZSA9IHRpZ2VyIGxlZ2FjeQpvcmcub21nLkNPUkJBLlR5cGVDb2RlUGFja2FnZSA9IHRpZ2VyIGxlZ2FjeQpvcmcub21nLkNPUkJBLnBvcnRhYmxlID0gdGlnZXIgbGVnYWN5Cm9yZy5vbWcuQ09SQkFfMl8zID0gdGlnZXIgbGVnYWN5Cm9yZy5vbWcuQ09SQkFfMl8zLnBvcnRhYmxlID0gdGlnZXIgbGVnYWN5Cm9yZy5vbWcuQ29zTmFtaW5nID0gdGlnZXIgbGVnYWN5Cm9yZy5vbWcuQ29zTmFtaW5nLk5hbWluZ0NvbnRleHRFeHRQYWNrYWdlID0gdGlnZXIgbGVnYWN5Cm9yZy5vbWcuQ29zTmFtaW5nLk5hbWluZ0NvbnRleHRQYWNrYWdlID0gdGlnZXIgbGVnYWN5Cm9yZy5vbWcuRHluYW1pYyA9IHRpZ2VyIGxlZ2FjeQpvcmcub21nLkR5bmFtaWNBbnkgPSB0aWdlciBsZWdhY3kKb3JnLm9tZy5EeW5hbWljQW55LkR5bkFueUZhY3RvcnlQYWNrYWdlID0gdGlnZXIgbGVnYWN5Cm9yZy5vbWcuRHluYW1pY0FueS5EeW5BbnlQYWNrYWdlID0gdGlnZXIgbGVnYWN5Cm9yZy5vbWcuSU9QID0gdGlnZXIgbGVnYWN5Cm9yZy5vbWcuSU9QLkNvZGVjRmFjdG9yeVBhY2thZ2UgPSB0aWdlciBsZWdhY3kKb3JnLm9tZy5JT1AuQ29kZWNQYWNrYWdlID0gdGlnZXIgbGVnYWN5Cm9yZy5vbWcuTWVzc2FnaW5nID0gdGlnZXIgbGVnYWN5Cm9yZy5vbWcuUG9ydGFibGVJbnRlcmNlcHRvciA9IHRpZ2VyIGxlZ2FjeQpvcmcub21nLlBvcnRhYmxlSW50ZXJjZXB0b3IuT1JCSW5pdEluZm9QYWNrYWdlID0gdGlnZXIgbGVnYWN5Cm9yZy5vbWcuUG9ydGFibGVTZXJ2ZXIgPSB0aWdlciBsZWdhY3kKb3JnLm9tZy5Qb3J0YWJsZVNlcnZlci5DdXJyZW50UGFja2FnZSA9IHRpZ2VyIGxlZ2FjeQpvcmcub21nLlBvcnRhYmxlU2VydmVyLlBPQU1hbmFnZXJQYWNrYWdlID0gdGlnZXIgbGVnYWN5Cm9yZy5vbWcuUG9ydGFibGVTZXJ2ZXIuUE9BUGFja2FnZSA9IHRpZ2VyIGxlZ2FjeQpvcmcub21nLlBvcnRhYmxlU2VydmVyLlNlcnZhbnRMb2NhdG9yUGFja2FnZSA9IHRpZ2VyIGxlZ2FjeQpvcmcub21nLlBvcnRhYmxlU2VydmVyLnBvcnRhYmxlID0gdGlnZXIgbGVnYWN5Cm9yZy5vbWcuU2VuZGluZ0NvbnRleHQgPSB0aWdlciBsZWdhY3kKb3JnLm9tZy5zdHViLmphdmEucm1pID0gdGlnZXIgbGVnYWN5Cm9yZy5vbWcuc3R1Yi5qYXZheC5tYW5hZ2VtZW50LnJlbW90ZS5ybWkgPSB0aWdlciBsZWdhY3kKb3JnLnczYy5kb20gPSB0aWdlciBsZWdhY3kKb3JnLnczYy5kb20uYm9vdHN0cmFwID0gdGlnZXIgbGVnYWN5Cm9yZy53M2MuZG9tLmNzcyA9IHRpZ2VyIGxlZ2FjeQpvcmcudzNjLmRvbS5ldmVudHMgPSB0aWdlciBsZWdhY3kKb3JnLnczYy5kb20uaHRtbCA9IHRpZ2VyIGxlZ2FjeQpvcmcudzNjLmRvbS5scyA9IHRpZ2VyIGxlZ2FjeQpvcmcudzNjLmRvbS5yYW5nZXMgPSB0aWdlciBsZWdhY3kKb3JnLnczYy5kb20uc3R5bGVzaGVldHMgPSB0aWdlciBsZWdhY3kKb3JnLnczYy5kb20udHJhdmVyc2FsID0gdGlnZXIgbGVnYWN5Cm9yZy53M2MuZG9tLnZpZXdzID0gdGlnZXIgbGVnYWN5Cm9yZy54bWwuc2F4ID0gdGlnZXIgbGVnYWN5Cm9yZy54bWwuc2F4LmV4dCA9IHRpZ2VyIGxlZ2FjeQpvcmcueG1sLnNheC5oZWxwZXJzID0gdGlnZXIgbGVnYWN5CnN1bi5hcHBsZXQgPSB0aWdlciBsZWdhY3kKc3VuLmFwcGxldC5yZXNvdXJjZXMgPSB0aWdlciBsZWdhY3kKc3VuLmF1ZGlvID0gdGlnZXIgbGVnYWN5CnN1bi5hd3QgPSB0aWdlciBsZWdhY3kKc3VuLmF3dC5YMTEgPSB0aWdlciBsZWdhY3kKc3VuLmF3dC5jb2xvciA9IHRpZ2VyIGxlZ2FjeQpzdW4uYXd0LmRhdGF0cmFuc2ZlciA9IHRpZ2VyIGxlZ2FjeQpzdW4uYXd0LmRuZCA9IHRpZ2VyIGxlZ2FjeQpzdW4uYXd0Lmdlb20gPSB0aWdlciBsZWdhY3kKc3VuLmF3dC5pbSA9IHRpZ2VyIGxlZ2FjeQpzdW4uYXd0LmltYWdlID0gdGlnZXIgbGVnYWN5CnN1bi5hd3QuaW1hZ2UuY29kZWMgPSB0aWdlciBsZWdhY3kKc3VuLmF3dC5tb3RpZiA9IHRpZ2VyIGxlZ2FjeQpzdW4uYXd0LnJlc291cmNlcyA9IHRpZ2VyIGxlZ2FjeQpzdW4uYXd0LnNoZWxsID0gdGlnZXIgbGVnYWN5CnN1bi5hd3Qud2luZG93cyA9IHRpZ2VyIGxlZ2FjeQpzdW4uYmVhbnMuZWRpdG9ycyA9IHRpZ2VyIGxlZ2FjeQpzdW4uYmVhbnMuaW5mb3MgPSB0aWdlciBsZWdhY3kKc3VuLmNvcmJhID0gdGlnZXIgbGVnYWN5CnN1bi5kYy5wYXRoID0gdGlnZXIgbGVnYWN5CnN1bi5kYy5wciA9IHRpZ2VyIGxlZ2FjeQpzdW4uZm9udCA9IHRpZ2VyIGxlZ2FjeQpzdW4uaW5zdHJ1bWVudCA9IHRpZ2VyIGxlZ2FjeQpzdW4uaW8gPSB0aWdlciBsZWdhY3kKc3VuLmphdmEyZCA9IHRpZ2VyIGxlZ2FjeQpzdW4uamF2YTJkLmxvb3BzID0gdGlnZXIgbGVnYWN5CnN1bi5qYXZhMmQub3BlbmdsID0gdGlnZXIgbGVnYWN5CnN1bi5qYXZhMmQucGlwZSA9IHRpZ2VyIGxlZ2FjeQpzdW4uamRiYy5vZGJjID0gdGlnZXIgbGVnYWN5CnN1bi5qZGJjLm9kYmMuZWUgPSB0aWdlciBsZWdhY3kKc3VuLm1hbmFnZW1lbnQgPSB0aWdlciBsZWdhY3kKc3VuLm1hbmFnZW1lbnQuY291bnRlciA9IHRpZ2VyIGxlZ2FjeQpzdW4ubWFuYWdlbWVudC5jb3VudGVyLnBlcmYgPSB0aWdlciBsZWdhY3kKc3VuLm1hbmFnZW1lbnQuam14cmVtb3RlID0gdGlnZXIgbGVnYWN5CnN1bi5tYW5hZ2VtZW50LnJlc291cmNlcyA9IHRpZ2VyIGxlZ2FjeQpzdW4ubWFuYWdlbWVudC5zbm1wID0gdGlnZXIgbGVnYWN5CnN1bi5tYW5hZ2VtZW50LnNubXAuanZtaW5zdHIgPSB0aWdlciBsZWdhY3kKc3VuLm1hbmFnZW1lbnQuc25tcC5qdm1taWIgPSB0aWdlciBsZWdhY3kKc3VuLm1hbmFnZW1lbnQuc25tcC51dGlsID0gdGlnZXIgbGVnYWN5CnN1bi5taXNjID0gdGlnZXIgbGVnYWN5CnN1bi5taXNjLnJlc291cmNlcyA9IHRpZ2VyIGxlZ2FjeQpzdW4ubmV0ID0gdGlnZXIgbGVnYWN5CnN1bi5uZXQuZG5zID0gdGlnZXIgbGVnYWN5CnN1bi5uZXQuZnRwID0gdGlnZXIgbGVnYWN5CnN1bi5uZXQuc210cCA9IHRpZ2VyIGxlZ2FjeQpzdW4ubmV0LnNwaSA9IHRpZ2VyIGxlZ2FjeQpzdW4ubmV0LnNwaS5uYW1lc2VydmljZSA9IHRpZ2VyIGxlZ2FjeQpzdW4ubmV0LnV0aWwgPSB0aWdlciBsZWdhY3kKc3VuLm5ldC53d3cgPSB0aWdlciBsZWdhY3kKc3VuLm5ldC53d3cuY29udGVudC5hdWRpbyA9IHRpZ2VyIGxlZ2FjeQpzdW4ubmV0Lnd3dy5jb250ZW50LmltYWdlID0gdGlnZXIgbGVnYWN5CnN1bi5uZXQud3d3LmNvbnRlbnQudGV4dCA9IHRpZ2VyIGxlZ2FjeQpzdW4ubmV0Lnd3dy5odHRwID0gdGlnZXIgbGVnYWN5CnN1bi5uZXQud3d3LnByb3RvY29sLmRvYyA9IHRpZ2VyIGxlZ2FjeQpzdW4ubmV0Lnd3dy5wcm90b2NvbC5maWxlID0gdGlnZXIgbGVnYWN5CnN1bi5uZXQud3d3LnByb3RvY29sLmZ0cCA9IHRpZ2VyIGxlZ2FjeQpzdW4ubmV0Lnd3dy5wcm90b2NvbC5nb3BoZXIgPSB0aWdlciBsZWdhY3kKc3VuLm5ldC53d3cucHJvdG9jb2wuaHR0cCA9IHRpZ2VyIGxlZ2FjeQpzdW4ubmV0Lnd3dy5wcm90b2NvbC5odHRwcyA9IHRpZ2VyIGxlZ2FjeQpzdW4ubmV0Lnd3dy5wcm90b2NvbC5qYXIgPSB0aWdlciBsZWdhY3kKc3VuLm5ldC53d3cucHJvdG9jb2wubWFpbHRvID0gdGlnZXIgbGVnYWN5CnN1bi5uZXQud3d3LnByb3RvY29sLm5ldGRvYyA9IHRpZ2VyIGxlZ2FjeQpzdW4ubmV0Lnd3dy5wcm90b2NvbC5zeXN0ZW1yZXNvdXJjZSA9IHRpZ2VyIGxlZ2FjeQpzdW4ubmV0Lnd3dy5wcm90b2NvbC52ZXJiYXRpbSA9IHRpZ2VyIGxlZ2FjeQpzdW4ubmlvID0gdGlnZXIgbGVnYWN5CnN1bi5uaW8uY2ggPSB0aWdlciBsZWdhY3kKc3VuLm5pby5jcyA9IHRpZ2VyIGxlZ2FjeQpzdW4ucHJpbnQgPSB0aWdlciBsZWdhY3kKc3VuLnByaW50LnJlc291cmNlcyA9IHRpZ2VyIGxlZ2FjeQpzdW4ucmVmbGVjdCA9IHRpZ2VyIGxlZ2FjeQpzdW4ucmVmbGVjdC5hbm5vdGF0aW9uID0gdGlnZXIgbGVnYWN5CnN1bi5yZWZsZWN0LmdlbmVyaWNzLmZhY3RvcnkgPSB0aWdlciBsZWdhY3kKc3VuLnJlZmxlY3QuZ2VuZXJpY3MucGFyc2VyID0gdGlnZXIgbGVnYWN5CnN1bi5yZWZsZWN0LmdlbmVyaWNzLnJlZmxlY3RpdmVPYmplY3RzID0gdGlnZXIgbGVnYWN5CnN1bi5yZWZsZWN0LmdlbmVyaWNzLnJlcG9zaXRvcnkgPSB0aWdlciBsZWdhY3kKc3VuLnJlZmxlY3QuZ2VuZXJpY3Muc2NvcGUgPSB0aWdlciBsZWdhY3kKc3VuLnJlZmxlY3QuZ2VuZXJpY3MudHJlZSA9IHRpZ2VyIGxlZ2FjeQpzdW4ucmVmbGVjdC5nZW5lcmljcy52aXNpdG9yID0gdGlnZXIgbGVnYWN5CnN1bi5ybWkubG9nID0gdGlnZXIgbGVnYWN5CnN1bi5ybWkucmVnaXN0cnkgPSB0aWdlciBsZWdhY3kKc3VuLnJtaS5yZWdpc3RyeS5yZXNvdXJjZXMgPSB0aWdlciBsZWdhY3kKc3VuLnJtaS5ybWlkLnJlc291cmNlcyA9IHRpZ2VyIGxlZ2FjeQpzdW4ucm1pLnJ1bnRpbWUgPSB0aWdlciBsZWdhY3kKc3VuLnJtaS5zZXJ2ZXIgPSB0aWdlciBsZWdhY3kKc3VuLnJtaS50cmFuc3BvcnQgPSB0aWdlciBsZWdhY3kKc3VuLnJtaS50cmFuc3BvcnQucHJveHkgPSB0aWdlciBsZWdhY3kKc3VuLnJtaS50cmFuc3BvcnQudGNwID0gdGlnZXIgbGVnYWN5CnN1bi5zZWN1cml0eS5hY3Rpb24gPSB0aWdlciBsZWdhY3kKc3VuLnNlY3VyaXR5LmpjYSA9IHRpZ2VyIGxlZ2FjeQpzdW4uc2VjdXJpdHkuamdzcyA9IHRpZ2VyIGxlZ2FjeQpzdW4uc2VjdXJpdHkuamdzcy5rcmI1ID0gdGlnZXIgbGVnYWN5CnN1bi5zZWN1cml0eS5qZ3NzLnNwaSA9IHRpZ2VyIGxlZ2FjeQpzdW4uc2VjdXJpdHkua3JiNSA9IHRpZ2VyIGxlZ2FjeQpzdW4uc2VjdXJpdHkua3JiNS5pbnRlcm5hbCA9IHRpZ2VyIGxlZ2FjeQpzdW4uc2VjdXJpdHkua3JiNS5pbnRlcm5hbC5jY2FjaGUgPSB0aWdlciBsZWdhY3kKc3VuLnNlY3VyaXR5LmtyYjUuaW50ZXJuYWwuY3J5cHRvID0gdGlnZXIgbGVnYWN5CnN1bi5zZWN1cml0eS5rcmI1LmludGVybmFsLmNyeXB0by5kayA9IHRpZ2VyIGxlZ2FjeQpzdW4uc2VjdXJpdHkua3JiNS5pbnRlcm5hbC5rdGFiID0gdGlnZXIgbGVnYWN5CnN1bi5zZWN1cml0eS5rcmI1LmludGVybmFsLnJjYWNoZSA9IHRpZ2VyIGxlZ2FjeQpzdW4uc2VjdXJpdHkua3JiNS5pbnRlcm5hbC50b29scyA9IHRpZ2VyIGxlZ2FjeQpzdW4uc2VjdXJpdHkua3JiNS5pbnRlcm5hbC51dGlsID0gdGlnZXIgbGVnYWN5CnN1bi5zZWN1cml0eS5wa2NzID0gdGlnZXIgbGVnYWN5CnN1bi5zZWN1cml0eS5wcm92aWRlciA9IHRpZ2VyIGxlZ2FjeQpzdW4uc2VjdXJpdHkucHJvdmlkZXIuY2VydHBhdGggPSB0aWdlciBsZWdhY3kKc3VuLnNlY3VyaXR5LnJzYSA9IHRpZ2VyIGxlZ2FjeQpzdW4uc2VjdXJpdHkudGltZXN0YW1wID0gdGlnZXIgbGVnYWN5CnN1bi5zZWN1cml0eS50b29scyA9IHRpZ2VyIGxlZ2FjeQpzdW4uc2VjdXJpdHkudXRpbCA9IHRpZ2VyIGxlZ2FjeQpzdW4uc2VjdXJpdHkudmFsaWRhdG9yID0gdGlnZXIgbGVnYWN5CnN1bi5zZWN1cml0eS54NTA5ID0gdGlnZXIgbGVnYWN5CnN1bi5zd2luZyA9IHRpZ2VyIGxlZ2FjeQpzdW4uc3dpbmcucGxhZi5zeW50aCA9IHRpZ2VyIGxlZ2FjeQpzdW4udGV4dCA9IHRpZ2VyIGxlZ2FjeQpzdW4udGV4dC5yZXNvdXJjZXMgPSB0aWdlciBsZWdhY3kKc3VuLnRvb2xzLmhwcm9mID0gdGlnZXIgbGVnYWN5CnN1bi50b29scy5qYXIgPSB0aWdlciBsZWdhY3kKc3VuLnRvb2xzLmphci5yZXNvdXJjZXMgPSB0aWdlciBsZWdhY3kKc3VuLnV0aWwgPSB0aWdlciBsZWdhY3kKc3VuLnV0aWwuY2FsZW5kYXIgPSB0aWdlciBsZWdhY3kKc3VuLnV0aWwubG9jYWxlID0gdGlnZXIgbGVnYWN5CnN1bi51dGlsLmxvZ2dpbmcucmVzb3VyY2VzID0gdGlnZXIgbGVnYWN5CnN1bncuaW8gPSB0aWdlciBsZWdhY3kKc3Vudy51dGlsID0gdGlnZXIgbGVnYWN5ClBLAwQKAAAIAAAGO6lKO/TrF0JIAABCSAAANAAAAGNvbS9zdW4vdG9vbHMvamF2YWMvcmVzb3VyY2VzL2phdmFjX3poX0NOLnByb3BlcnRpZXMjCiMgQ29weXJpZ2h0IChjKSAxOTk5LCAyMDE3LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgojIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KIwojIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiMgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKIyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKIyBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiMgYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiMKIyBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKIyBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKIyBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKIyB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAojIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiMKIyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiMgMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAojIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KIwojIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiMgb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQojIHF1ZXN0aW9ucy4KIwoKIyMgc3RhbmRhcmQgb3B0aW9ucwoKamF2YWMub3B0Lmc9XHU3NTFGXHU2MjEwXHU2MjQwXHU2NzA5XHU4QzAzXHU4QkQ1XHU0RkUxXHU2MDZGCmphdmFjLm9wdC5nLm5vbmU9XHU0RTBEXHU3NTFGXHU2MjEwXHU0RUZCXHU0RjU1XHU4QzAzXHU4QkQ1XHU0RkUxXHU2MDZGCmphdmFjLm9wdC5nLmxpbmVzLnZhcnMuc291cmNlPVx1NTNFQVx1NzUxRlx1NjIxMFx1NjdEMFx1NEU5Qlx1OEMwM1x1OEJENVx1NEZFMVx1NjA2RgpqYXZhYy5vcHQubm93YXJuPVx1NEUwRFx1NzUxRlx1NjIxMFx1NEVGQlx1NEY1NVx1OEI2Nlx1NTQ0QQpqYXZhYy5vcHQudmVyYm9zZT1cdThGOTNcdTUxRkFcdTY3MDlcdTUxNzNcdTdGMTZcdThCRDFcdTU2NjhcdTZCNjNcdTU3MjhcdTYyNjdcdTg4NENcdTc2ODRcdTY0Q0RcdTRGNUNcdTc2ODRcdTZEODhcdTYwNkYKamF2YWMub3B0LmRlcHJlY2F0aW9uPVx1OEY5M1x1NTFGQVx1NEY3Rlx1NzUyOFx1NURGMlx1OEZDN1x1NjVGNlx1NzY4NCBBUEkgXHU3Njg0XHU2RTkwXHU0RjREXHU3RjZFCmphdmFjLm9wdC5jbGFzc3BhdGg9XHU2MzA3XHU1QjlBXHU2N0U1XHU2MjdFXHU3NTI4XHU2MjM3XHU3QzdCXHU2NTg3XHU0RUY2XHU1NDhDXHU2Q0U4XHU5MUNBXHU1OTA0XHU3NDA2XHU3QTBCXHU1RThGXHU3Njg0XHU0RjREXHU3RjZFCmphdmFjLm9wdC5tb2R1bGVwYXRoPVx1NjMwN1x1NUI5QVx1NjdFNVx1NjI3RVx1NUU5NFx1NzUyOFx1N0EwQlx1NUU4Rlx1NkEyMVx1NTc1N1x1NzY4NFx1NEY0RFx1N0Y2RQpqYXZhYy5vcHQuc291cmNlcGF0aD1cdTYzMDdcdTVCOUFcdTY3RTVcdTYyN0VcdThGOTNcdTUxNjVcdTZFOTBcdTY1ODdcdTRFRjZcdTc2ODRcdTRGNERcdTdGNkUKamF2YWMub3B0Lm09XHU1M0VBXHU3RjE2XHU4QkQxXHU2MzA3XHU1QjlBXHU3Njg0XHU2QTIxXHU1NzU3LCBcdThCRjdcdTY4QzBcdTY3RTVcdTY1RjZcdTk1RjRcdTYyMzMKamF2YWMub3B0Lm1vZHVsZXNvdXJjZXBhdGg9XHU2MzA3XHU1QjlBXHU2N0U1XHU2MjdFXHU1OTFBXHU0RTJBXHU2QTIxXHU1NzU3XHU3Njg0XHU4RjkzXHU1MTY1XHU2RTkwXHU2NTg3XHU0RUY2XHU3Njg0XHU0RjREXHU3RjZFCmphdmFjLm9wdC5ib290Y2xhc3NwYXRoPVx1ODk4Nlx1NzZENlx1NUYxNVx1NUJGQ1x1N0M3Qlx1NjU4N1x1NEVGNlx1NzY4NFx1NEY0RFx1N0Y2RQpqYXZhYy5vcHQuc3lzdGVtPVx1ODk4Nlx1NzZENlx1N0NGQlx1N0VERlx1NkEyMVx1NTc1N1x1NEY0RFx1N0Y2RQpqYXZhYy5vcHQudXBncmFkZW1vZHVsZXBhdGg9XHU4OTg2XHU3NkQ2XHU1M0VGXHU1MzQ3XHU3RUE3XHU2QTIxXHU1NzU3XHU0RjREXHU3RjZFCmphdmFjLm9wdC5lbmRvcnNlZGRpcnM9XHU4OTg2XHU3NkQ2XHU3QjdFXHU1NDBEXHU3Njg0XHU2ODA3XHU1MUM2XHU4REVGXHU1Rjg0XHU3Njg0XHU0RjREXHU3RjZFCmphdmFjLm9wdC5leHRkaXJzPVx1ODk4Nlx1NzZENlx1NjI0MFx1NUI4OVx1ODhDNVx1NjI2OVx1NUM1NVx1NzY4NFx1NEY0RFx1N0Y2RQpqYXZhYy5vcHQucHJvY2Vzc29ycGF0aD1cdTYzMDdcdTVCOUFcdTY3RTVcdTYyN0VcdTZDRThcdTkxQ0FcdTU5MDRcdTc0MDZcdTdBMEJcdTVFOEZcdTc2ODRcdTRGNERcdTdGNkUKamF2YWMub3B0LnByb2Nlc3Nvcm1vZHVsZXBhdGg9XHU2MzA3XHU1QjlBXHU2N0U1XHU2MjdFXHU2Q0U4XHU5MUNBXHU1OTA0XHU3NDA2XHU3QTBCXHU1RThGXHU3Njg0XHU2QTIxXHU1NzU3XHU4REVGXHU1Rjg0CmphdmFjLm9wdC5wcm9jZXNzb3I9XHU4OTgxXHU4RkQwXHU4ODRDXHU3Njg0XHU2Q0U4XHU5MUNBXHU1OTA0XHU3NDA2XHU3QTBCXHU1RThGXHU3Njg0XHU1NDBEXHU3OUYwOyBcdTdFRDVcdThGQzdcdTlFRDhcdThCQTRcdTc2ODRcdTY0MUNcdTdEMjJcdThGREJcdTdBMEIKamF2YWMub3B0LnBhcmFtZXRlcnM9XHU3NTFGXHU2MjEwXHU1MTQzXHU2NTcwXHU2MzZFXHU0RUU1XHU3NTI4XHU0RThFXHU2NUI5XHU2Q0Q1XHU1M0MyXHU2NTcwXHU3Njg0XHU1M0NEXHU1QzA0CmphdmFjLm9wdC5wcm9jLm5vbmUub25seT1cdTYzQTdcdTUyMzZcdTY2MkZcdTU0MjZcdTYyNjdcdTg4NENcdTZDRThcdTkxQ0FcdTU5MDRcdTc0MDZcdTU0OEMvXHU2MjE2XHU3RjE2XHU4QkQxXHUzMDAyCmphdmFjLm9wdC5kPVx1NjMwN1x1NUI5QVx1NjUzRVx1N0Y2RVx1NzUxRlx1NjIxMFx1NzY4NFx1N0M3Qlx1NjU4N1x1NEVGNlx1NzY4NFx1NEY0RFx1N0Y2RQpqYXZhYy5vcHQuc291cmNlRGVzdD1cdTYzMDdcdTVCOUFcdTY1M0VcdTdGNkVcdTc1MUZcdTYyMTBcdTc2ODRcdTZFOTBcdTY1ODdcdTRFRjZcdTc2ODRcdTRGNERcdTdGNkUKamF2YWMub3B0LmhlYWRlckRlc3Q9XHU2MzA3XHU1QjlBXHU2NTNFXHU3RjZFXHU3NTFGXHU2MjEwXHU3Njg0XHU2NzJDXHU2NzNBXHU2ODA3XHU1OTM0XHU2NTg3XHU0RUY2XHU3Njg0XHU0RjREXHU3RjZFCmphdmFjLm9wdC5KPVx1NzZGNFx1NjNBNVx1NUMwNiA8XHU2ODA3XHU4QkIwPiBcdTRGMjBcdTkwMTJcdTdFRDlcdThGRDBcdTg4NENcdTY1RjZcdTdDRkJcdTdFREYKamF2YWMub3B0LmVuY29kaW5nPVx1NjMwN1x1NUI5QVx1NkU5MFx1NjU4N1x1NEVGNlx1NEY3Rlx1NzUyOFx1NzY4NFx1NUI1N1x1N0IyNlx1N0YxNlx1NzgwMQpqYXZhYy5vcHQucHJvZmlsZT1cdThCRjdcdTc4NkVcdTRGRERcdTRGN0ZcdTc1MjhcdTc2ODQgQVBJIFx1NTcyOFx1NjMwN1x1NUI5QVx1NzY4NFx1OTE0RFx1N0Y2RVx1NjU4N1x1NEVGNlx1NEUyRFx1NTNFRlx1NzUyOApqYXZhYy5vcHQudGFyZ2V0PVx1NzUxRlx1NjIxMFx1NzI3OVx1NUI5QSBWTSBcdTcyNDhcdTY3MkNcdTc2ODRcdTdDN0JcdTY1ODdcdTRFRjYKamF2YWMub3B0LnJlbGVhc2U9XHU5NDg4XHU1QkY5XHU3Mjc5XHU1QjlBIFZNIFx1NzI0OFx1NjcyQ1x1OEZEQlx1ODg0Q1x1N0YxNlx1OEJEMVx1MzAwMlx1NjUyRlx1NjMwMVx1NzY4NFx1NzZFRVx1NjgwNzogezB9CmphdmFjLm9wdC5zb3VyY2U9XHU2M0QwXHU0RjlCXHU0RTBFXHU2MzA3XHU1QjlBXHU1M0QxXHU4ODRDXHU3MjQ4XHU3Njg0XHU2RTkwXHU1MTdDXHU1QkI5XHU2MDI3CmphdmFjLm9wdC5XZXJyb3I9XHU1MUZBXHU3M0IwXHU4QjY2XHU1NDRBXHU2NUY2XHU3RUM4XHU2QjYyXHU3RjE2XHU4QkQxCmphdmFjLm9wdC5BPVx1NEYyMFx1OTAxMlx1N0VEOVx1NkNFOFx1OTFDQVx1NTkwNFx1NzQwNlx1N0EwQlx1NUU4Rlx1NzY4NFx1OTAwOVx1OTg3OQpqYXZhYy5vcHQuaW1wbGljaXQ9XHU2MzA3XHU1QjlBXHU2NjJGXHU1NDI2XHU0RTNBXHU5NjkwXHU1RjBGXHU1RjE1XHU3NTI4XHU2NTg3XHU0RUY2XHU3NTFGXHU2MjEwXHU3QzdCXHU2NTg3XHU0RUY2CmphdmFjLm9wdC5wa2dpbmZvPVx1NjMwN1x1NUI5QSBwYWNrYWdlLWluZm8gXHU2NTg3XHU0RUY2XHU3Njg0XHU1OTA0XHU3NDA2CmphdmFjLm9wdC5tdWx0aS1yZWxlYXNlPVx1NjMwN1x1NUI5QVx1NTcyOFx1NTkxQVx1NTNEMVx1ODg0Q1x1NzI0OCBqYXIgXHU0RTJEXHU0RjdGXHU3NTI4XHU1NEVBXHU0RTJBXHU1M0QxXHU4ODRDXHU3MjQ4CmphdmFjLm9wdC5hcmcuY2xhc3M9PGNsYXNzPgpqYXZhYy5vcHQuYXJnLmNsYXNzLmxpc3Q9PGNsYXNzMT5bLDxjbGFzczI+LDxjbGFzczM+Li4uXQpqYXZhYy5vcHQuYXJnLmZsYWc9PGZsYWc+CmphdmFjLm9wdC5hcmcua2V5LmVxdWFscy52YWx1ZT1rZXlbPXZhbHVlXQpqYXZhYy5vcHQuYXJnLnBhdGg9PHBhdGg+CmphdmFjLm9wdC5hcmcubXNwYXRoPTxtb2R1bGUtc291cmNlLXBhdGg+CmphdmFjLm9wdC5hcmcubT08bW9kdWxlLW5hbWU+CmphdmFjLm9wdC5hcmcuamRrPTxqZGs+fG5vbmUKamF2YWMub3B0LmFyZy5kaXJzPTxkaXJzPgpqYXZhYy5vcHQuYXJnLmRpcmVjdG9yeT08ZGlyZWN0b3J5PgpqYXZhYy5vcHQuYXJnLmVuY29kaW5nPTxlbmNvZGluZz4KamF2YWMub3B0LmFyZy5wcm9maWxlPTxwcm9maWxlPgpqYXZhYy5vcHQuYXJnLnJlbGVhc2U9PHJlbGVhc2U+CmphdmFjLm9wdC5hcmcucmVsZWFzZT08cmVsZWFzZT4KamF2YWMub3B0LmFyZy5udW1iZXI9PG51bWJlcj4KamF2YWMub3B0LnBsdWdpbj1cdTg5ODFcdThGRDBcdTg4NENcdTc2ODRcdTYzRDJcdTRFRjZcdTc2ODRcdTU0MERcdTc5RjBcdTU0OENcdTUzRUZcdTkwMDlcdTUzQzJcdTY1NzAKamF2YWMub3B0LmFyZy5wbHVnaW49Ilx1NTQwRFx1NzlGMFx1NTNDMlx1NjU3MCIKamF2YWMub3B0LmFyZy5tdWx0aS1yZWxlYXNlPTxyZWxlYXNlPgoKIyMgZXh0ZW5kZWQgb3B0aW9ucwoKamF2YWMub3B0Lm1heGVycnM9XHU4QkJFXHU3RjZFXHU4OTgxXHU4RjkzXHU1MUZBXHU3Njg0XHU5NTE5XHU4QkVGXHU3Njg0XHU2NzAwXHU1OTI3XHU2NTcwXHU3NkVFCmphdmFjLm9wdC5tYXh3YXJucz1cdThCQkVcdTdGNkVcdTg5ODFcdThGOTNcdTUxRkFcdTc2ODRcdThCNjZcdTU0NEFcdTc2ODRcdTY3MDBcdTU5MjdcdTY1NzBcdTc2RUUKamF2YWMub3B0Lm5vZ2o9XHU4QkVEXHU4QTAwXHU0RTJEXHU0RTBEXHU2M0E1XHU1M0Q3XHU2Q0RCXHU1NzhCCmphdmFjLm9wdC5tb3JlaW5mbz1cdThGOTNcdTUxRkFcdTdDN0JcdTU3OEJcdTUzRDhcdTkxQ0ZcdTc2ODRcdTYyNjlcdTVDNTVcdTRGRTFcdTYwNkYKamF2YWMub3B0LnByaW50c2VhcmNoPVx1OEY5M1x1NTFGQVx1NjcwOVx1NTE3M1x1NjQxQ1x1N0QyMlx1N0M3Qlx1NjU4N1x1NEVGNlx1NzY4NFx1NEY0RFx1N0Y2RVx1NzY4NFx1NEZFMVx1NjA2RgpqYXZhYy5vcHQucHJvbXB0PVx1NTcyOFx1NkJDRlx1NkIyMVx1NTFGQVx1OTUxOVx1NTQwRVx1NTA1Q1x1NkI2MgpqYXZhYy5vcHQucz1cdTUzRDFcdTUxRkEgamF2YSBcdTZFOTBcdTgwMENcdTRFMERcdTY2MkZcdTdDN0JcdTY1ODdcdTRFRjYKamF2YWMub3B0LnZlcnNpb249XHU3MjQ4XHU2NzJDXHU0RkUxXHU2MDZGCmphdmFjLm9wdC5hcmcucGF0aG5hbWU9PHBhdGhuYW1lPgpqYXZhYy5vcHQuYXJnLmZpbGU9PGZpbGVuYW1lPgpqYXZhYy5vcHQuWGJvb3RjbGFzc3BhdGgucD1cdTdGNkVcdTRFOEVcdTVGMTVcdTVCRkNcdTdDN0JcdThERUZcdTVGODRcdTRFNEJcdTUyNEQKamF2YWMub3B0Llhib290Y2xhc3NwYXRoLmE9XHU3RjZFXHU0RThFXHU1RjE1XHU1QkZDXHU3QzdCXHU4REVGXHU1Rjg0XHU0RTRCXHU1NDBFCmphdmFjLm9wdC5YbGludD1cdTU0MkZcdTc1MjhcdTVFRkFcdThCQUVcdTc2ODRcdThCNjZcdTU0NEEKamF2YWMub3B0LlhsaW50LmFsbD1cdTU0MkZcdTc1MjhcdTYyNDBcdTY3MDlcdThCNjZcdTU0NEEKamF2YWMub3B0LlhsaW50Lm5vbmU9XHU3OTgxXHU3NTI4XHU2MjQwXHU2NzA5XHU4QjY2XHU1NDRBCiNMMTBOOiBkbyBub3QgbG9jYWxpemU6IC1YbGludApqYXZhYy5vcHQuYXJnLlhsaW50PTxcdTVCQzZcdTk0QTU+KCw8XHU1QkM2XHU5NEE1PikqCmphdmFjLm9wdC5YbGludC5jdXN0b209XHU4OTgxXHU1NDJGXHU3NTI4XHU2MjE2XHU3OTgxXHU3NTI4XHU3Njg0XHU4QjY2XHU1NDRBLCBcdTRGN0ZcdTc1MjhcdTkwMTdcdTUzRjdcdTUyMDZcdTk2OTRcdTMwMDJcbiAgICAgICAgXHU1NzI4XHU1MTczXHU5NTJFXHU1QjU3XHU1MjREXHU5NzYyXHU1MkEwXHU0RTBBICctJyBcdTUzRUZcdTc5ODFcdTc1MjhcdTYzMDdcdTVCOUFcdTc2ODRcdThCNjZcdTU0NEFcdTMwMDJcbiAgICAgICAgXHU2NTJGXHU2MzAxXHU3Njg0XHU1MTczXHU5NTJFXHU1QjU3XHU1MzA1XHU2MkVDOgpqYXZhYy5vcHQuWGxpbnQuZGVzYy5hdXhpbGlhcnljbGFzcz1cdTY3MDlcdTUxNzNcdThGODVcdTUyQTlcdTdDN0JcdTU3MjhcdTZFOTBcdTY1ODdcdTRFRjZcdTRFMkRcdTk2OTBcdTg1Q0YsIFx1NEY0Nlx1NTcyOFx1NTE3Nlx1NEVENlx1NjU4N1x1NEVGNlx1NEUyRFx1NEY3Rlx1NzUyOFx1NzY4NFx1OEI2Nlx1NTQ0QVx1MzAwMgoKamF2YWMub3B0LlhsaW50LmRlc2MuY2FzdD1cdTY3MDlcdTUxNzNcdTRGN0ZcdTc1MjhcdTRFODZcdTRFMERcdTVGQzVcdTg5ODFcdThGNkNcdTYzNjJcdTc2ODRcdThCNjZcdTU0NEFcdTMwMDIKCmphdmFjLm9wdC5YbGludC5kZXNjLmNsYXNzZmlsZT1cdTY3MDlcdTUxNzNcdTRFMEVcdTdDN0JcdTY1ODdcdTRFRjZcdTUxODVcdTVCQjlcdTc2RjhcdTUxNzNcdTc2ODRcdTk1RUVcdTk4OThcdTc2ODRcdThCNjZcdTU0NEFcdTMwMDIKCmphdmFjLm9wdC5YbGludC5kZXNjLmRlcHJlY2F0aW9uPVx1NjcwOVx1NTE3M1x1NEY3Rlx1NzUyOFx1NEU4Nlx1NURGMlx1OEZDN1x1NjVGNlx1OTg3OVx1NzY4NFx1OEI2Nlx1NTQ0QVx1MzAwMgoKamF2YWMub3B0LlhsaW50LmRlc2MuZGVwLWFubj1cdTY3MDlcdTUxNzNcdTk4NzlcdTU3MjggSmF2YURvYyBcdTRFMkRcdTY4MDdcdThCQjBcdTRFM0FcdTVERjJcdThGQzdcdTY1RjZcdTRGNDZcdTY3MkFcdTRGN0ZcdTc1MjggQERlcHJlY2F0ZWQgXHU2Q0U4XHU5MUNBXHU3Njg0XHU4QjY2XHU1NDRBXHUzMDAyCgpqYXZhYy5vcHQuWGxpbnQuZGVzYy5kaXZ6ZXJvPVx1NjcwOVx1NTE3M1x1OTY2NFx1NEVFNVx1NUUzOFx1OTFDRlx1NjU3NFx1NjU3MCAwIFx1NzY4NFx1OEI2Nlx1NTQ0QVx1MzAwMgoKamF2YWMub3B0LlhsaW50LmRlc2MuZW1wdHk9XHU2NzA5XHU1MTczIGlmIFx1NEU0Qlx1NTQwRVx1NkNBMVx1NjcwOVx1OEJFRFx1NTNFNVx1NzY4NFx1OEI2Nlx1NTQ0QVx1MzAwMgoKamF2YWMub3B0LlhsaW50LmRlc2MuZXhwb3J0cz1cdTY3MDlcdTUxNzNcdTRFMEVcdTZBMjFcdTU3NTdcdTVCRkNcdTUxRkFcdTc2RjhcdTUxNzNcdTc2ODRcdTk1RUVcdTk4OThcdTc2ODRcdThCNjZcdTU0NEFcdTMwMDIKCmphdmFjLm9wdC5YbGludC5kZXNjLmZhbGx0aHJvdWdoPVx1NjcwOVx1NTE3M1x1NEVDRSBzd2l0Y2ggXHU4QkVEXHU1M0U1XHU3Njg0XHU0RTAwXHU0RTJBIGNhc2UgXHU1NDExXHU0RTBCXHU5ODdBXHU1RThGXHU2MjY3XHU4ODRDXHU1MjMwXHU0RTBCXHU0RTAwXHU0RTJBIGNhc2UgXHU3Njg0XHU4QjY2XHU1NDRBXHUzMDAyCgpqYXZhYy5vcHQuWGxpbnQuZGVzYy5maW5hbGx5PVx1NjcwOVx1NTE3MyBmaW5hbGx5IFx1NUI1MFx1NTNFNVx1NjcyQVx1NkI2M1x1NUUzOFx1N0VDOFx1NkI2Mlx1NzY4NFx1OEI2Nlx1NTQ0QVx1MzAwMgoKamF2YWMub3B0LlhsaW50LmRlc2MubW9kdWxlPVx1NjcwOVx1NTE3M1x1NkEyMVx1NTc1N1x1N0NGQlx1N0VERlx1NzZGOFx1NTE3M1x1OTVFRVx1OTg5OFx1NzY4NFx1OEI2Nlx1NTQ0QVx1MzAwMgoKamF2YWMub3B0LlhsaW50LmRlc2Mub3B0aW9ucz1cdTY3MDlcdTUxNzNcdTRFMEVcdTRGN0ZcdTc1MjhcdTU0N0RcdTRFRTRcdTg4NENcdTkwMDlcdTk4NzlcdTc2RjhcdTUxNzNcdTc2ODRcdTk1RUVcdTk4OThcdTc2ODRcdThCNjZcdTU0NEFcdTMwMDIKCmphdmFjLm9wdC5YbGludC5kZXNjLm92ZXJsb2Fkcz1cdTY3MDlcdTUxNzNcdTRFMEVcdTY1QjlcdTZDRDVcdTkxQ0RcdThGN0RcdTc2RjhcdTUxNzNcdTc2ODRcdTk1RUVcdTk4OThcdTc2ODRcdThCNjZcdTU0NEFcdTMwMDIKCmphdmFjLm9wdC5YbGludC5kZXNjLm92ZXJyaWRlcz1cdTY3MDlcdTUxNzNcdTRFMEVcdTY1QjlcdTZDRDVcdTg5ODZcdTc2RDZcdTc2RjhcdTUxNzNcdTc2ODRcdTk1RUVcdTk4OThcdTc2ODRcdThCNjZcdTU0NEFcdTMwMDIKCmphdmFjLm9wdC5YbGludC5kZXNjLnBhdGg9XHU2NzA5XHU1MTczXHU1NDdEXHU0RUU0XHU4ODRDXHU0RTBBXHU3Njg0XHU4REVGXHU1Rjg0XHU1MTQzXHU3RDIwXHU2NUUwXHU2NTQ4XHU3Njg0XHU4QjY2XHU1NDRBXHUzMDAyCgpqYXZhYy5vcHQuWGxpbnQuZGVzYy5wcm9jZXNzaW5nPVx1NjcwOVx1NTE3M1x1NEUwRVx1NkNFOFx1OTFDQVx1NTkwNFx1NzQwNlx1NzZGOFx1NTE3M1x1NzY4NFx1OTVFRVx1OTg5OFx1NzY4NFx1OEI2Nlx1NTQ0QVx1MzAwMgoKamF2YWMub3B0LlhsaW50LmRlc2MucmF3dHlwZXM9XHU2NzA5XHU1MTczXHU0RjdGXHU3NTI4XHU0RTg2XHU1MzlGXHU1OUNCXHU3QzdCXHU1NzhCXHU3Njg0XHU4QjY2XHU1NDRBXHUzMDAyCgpqYXZhYy5vcHQuWGxpbnQuZGVzYy5yZW1vdmFsPVx1NjcwOVx1NTE3M1x1NEY3Rlx1NzUyOFx1NEU4Nlx1NjgwN1x1OEJCMFx1NEUzQVx1NUY4NVx1NTIyMFx1OTY2NFx1NzY4NCBBUEkgXHU3Njg0XHU4QjY2XHU1NDRBXHUzMDAyCgpqYXZhYy5vcHQuWGxpbnQuZGVzYy5zZXJpYWw9XHU2NzA5XHU1MTczXHU2NzJBXHU2M0QwXHU0RjlCXHU1RThGXHU1MjE3XHU3MjQ4XHU2NzJDIElEIFx1NzY4NFx1NTNFRlx1NUU4Rlx1NTIxN1x1NTMxNlx1N0M3Qlx1NzY4NFx1OEI2Nlx1NTQ0QVx1MzAwMlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcdTZCNjRcdTU5MTZcdThGRDhcdThCNjZcdTU0NEFcdTY3MDlcdTUxNzNcdTUzRUZcdTRFMzJcdTg4NENcdTUzMTZcdTUxNDNcdTdEMjBcdTVCRjlcdTk3NUVcdTUxNkNcdTUxNzFcdTYyMTBcdTU0NThcdTc2ODRcdThCQkZcdTk1RUVcdTMwMDIKCmphdmFjLm9wdC5YbGludC5kZXNjLnN0YXRpYz1cdTY3MDlcdTUxNzNcdTRGN0ZcdTc1MjhcdTVCOUVcdTRGOEJcdTY3NjVcdThCQkZcdTk1RUVcdTk3NTlcdTYwMDFcdTYyMTBcdTU0NThcdTc2ODRcdThCNjZcdTU0NEFcdTMwMDIKCmphdmFjLm9wdC5YbGludC5kZXNjLnRyeT1cdTY3MDlcdTUxNzNcdTRFMEVcdTRGN0ZcdTc1MjggdHJ5IFx1NTc1NyAoXHU0RjhCXHU1OTgyIHRyeS13aXRoLXJlc291cmNlcykgXHU3NkY4XHU1MTczXHU3Njg0XHU5NUVFXHU5ODk4XHU3Njg0XHU4QjY2XHU1NDRBXHUzMDAyCgpqYXZhYy5vcHQuWGxpbnQuZGVzYy51bmNoZWNrZWQ9XHU2NzA5XHU1MTczXHU2NzJBXHU2OEMwXHU2N0U1XHU2NENEXHU0RjVDXHU3Njg0XHU4QjY2XHU1NDRBXHUzMDAyCgpqYXZhYy5vcHQuWGxpbnQuZGVzYy52YXJhcmdzPVx1NjcwOVx1NTE3M1x1NkY1Q1x1NTcyOFx1NEUwRFx1NUI4OVx1NTE2OFx1NzY4NCB2YXJhcmcgXHU2NUI5XHU2Q0Q1XHU3Njg0XHU4QjY2XHU1NDRBCgpqYXZhYy5vcHQuWGRvY2xpbnQ9XHU0RTNBIGphdmFkb2MgXHU2Q0U4XHU5MUNBXHU0RTJEXHU3Njg0XHU5NUVFXHU5ODk4XHU1NDJGXHU3NTI4XHU1RUZBXHU4QkFFXHU3Njg0XHU2OEMwXHU2N0U1CiMgTDEwTjogZG8gbm90IGxvY2FsaXplOiBhbGwgbm9uZQpqYXZhYy5vcHQuWGRvY2xpbnQuc3Vib3B0cyA9IChhbGx8bm9uZXxbLV08Z3JvdXA+KVsvPGFjY2Vzcz5dCgojIEwxME46IGRvIG5vdCBsb2NhbGl6ZTogYWNjZXNzaWJpbGl0eSBodG1sIG1pc3NpbmcgcmVmZXJlbmNlIHN5bnRheAojIEwxME46IGRvIG5vdCBsb2NhbGl6ZTogcHVibGljIHByb3RlY3RlZCBwYWNrYWdlIHByaXZhdGUKamF2YWMub3B0Llhkb2NsaW50LmN1c3RvbT1cdTRFM0EgamF2YWRvYyBcdTZDRThcdTkxQ0FcdTRFMkRcdTc2ODRcdTk1RUVcdTk4OThcdTU0MkZcdTc1MjhcdTYyMTZcdTc5ODFcdTc1MjhcdTcyNzlcdTVCOUFcdTY4QzBcdTY3RTUsXG4gICAgICAgIFx1NTE3Nlx1NEUyRCA8Z3JvdXA+IFx1NEUzQSBhY2Nlc3NpYmlsaXR5LCBodG1sLCBtaXNzaW5nLCByZWZlcmVuY2UgXHU2MjE2IHN5bnRheCBcdTRFNEJcdTRFMDBcdTMwMDJcbiAgICAgICAgPGFjY2Vzcz4gXHU0RTNBIHB1YmxpYywgcHJvdGVjdGVkLCBwYWNrYWdlIFx1NjIxNiBwcml2YXRlIFx1NEU0Qlx1NEUwMFx1MzAwMgoKamF2YWMub3B0Llhkb2NsaW50LnBhY2thZ2UuYXJncyA9IFstXTxcdTdBMEJcdTVFOEZcdTUzMDU+KCxbLV08XHU3QTBCXHU1RThGXHU1MzA1PikqCgpqYXZhYy5vcHQuWGRvY2xpbnQucGFja2FnZS5kZXNjPVx1NTcyOFx1NzI3OVx1NUI5QVx1NzY4NFx1N0EwQlx1NUU4Rlx1NTMwNVx1NEUyRFx1NTQyRlx1NzUyOFx1NjIxNlx1Nzk4MVx1NzUyOFx1NjhDMFx1NjdFNVx1MzAwMlx1NkJDRlx1NEUyQSA8XHU3QTBCXHU1RThGXHU1MzA1PiBcdTY2MkZcblx1N0EwQlx1NUU4Rlx1NTMwNVx1NzY4NFx1OTY1MFx1NUI5QVx1NTQwRFx1NzlGMCwgXHU2MjE2XHU3QTBCXHU1RThGXHU1MzA1XHU1NDBEXHU3OUYwXHU1MjREXHU3RjAwXHU1NDBFXHU4RERGICcuKicsIFxuXHU1QjgzXHU2MjY5XHU1QzU1XHU1MjMwXHU3RUQ5XHU1QjlBXHU3QTBCXHU1RThGXHU1MzA1XHU3Njg0XHU2MjQwXHU2NzA5XHU1QjUwXHU3QTBCXHU1RThGXHU1MzA1XHUzMDAyXHU1NzI4XHU2QkNGXHU0RTJBIDxcdTdBMEJcdTVFOEZcdTUzMDU+XG5cdTUyNERcdTk3NjJcdTUyQTBcdTRFMEEgJy0nIFx1NTNFRlx1NEVFNVx1NEUzQVx1NjMwN1x1NUI5QVx1N0EwQlx1NUU4Rlx1NTMwNVx1Nzk4MVx1NzUyOFx1NjhDMFx1NjdFNVx1MzAwMgoKamF2YWMub3B0LlhzdGRvdXQ9XHU5MUNEXHU1QjlBXHU1NDExXHU2ODA3XHU1MUM2XHU4RjkzXHU1MUZBCmphdmFjLm9wdC5YPVx1OEY5M1x1NTFGQVx1OTg5RFx1NTkxNlx1OTAwOVx1OTg3OVx1NzY4NFx1NUUyRVx1NTJBOQpqYXZhYy5vcHQuaGVscD1cdThGOTNcdTUxRkFcdTZCNjRcdTVFMkVcdTUyQTlcdTZEODhcdTYwNkYKamF2YWMub3B0LnByaW50PVx1OEY5M1x1NTFGQVx1NjMwN1x1NUI5QVx1N0M3Qlx1NTc4Qlx1NzY4NFx1NjU4N1x1NjcyQ1x1ODg2OFx1NzkzQQpqYXZhYy5vcHQucHJpbnRSb3VuZHM9XHU4RjkzXHU1MUZBXHU2NzA5XHU1MTczXHU2Q0U4XHU5MUNBXHU1OTA0XHU3NDA2XHU1RkFBXHU3M0FGXHU3Njg0XHU0RkUxXHU2MDZGCmphdmFjLm9wdC5wcmludFByb2Nlc3NvckluZm89XHU4RjkzXHU1MUZBXHU2NzA5XHU1MTczXHU4QkY3XHU2QzQyXHU1OTA0XHU3NDA2XHU3QTBCXHU1RThGXHU1OTA0XHU3NDA2XHU1NEVBXHU0RTlCXHU2Q0U4XHU5MUNBXHU3Njg0XHU0RkUxXHU2MDZGCmphdmFjLm9wdC51c2VycGF0aHNmaXJzdD1cdTU3MjhcdTVGMTVcdTVCRkNcdTdDN0JcdThERUZcdTVGODRcdTRFNEJcdTUyNERcdTgwMENcdTRFMERcdTY2MkZcdTRFNEJcdTU0MEVcdTY0MUNcdTdEMjJcdTdDN0JcdTc2ODRcdTdDN0JcdThERUZcdTVGODRcdTU0OENcdTZFOTBcdThERUZcdTVGODQKamF2YWMub3B0LnByZWZlcj1cdTYzMDdcdTVCOUFcdThCRkJcdTUzRDZcdTY1ODdcdTRFRjYsIFx1NUY1M1x1NTQwQ1x1NjVGNlx1NjI3RVx1NTIzMFx1OTY5MFx1NUYwRlx1N0YxNlx1OEJEMVx1N0M3Qlx1NzY4NFx1NkU5MFx1NjU4N1x1NEVGNlx1NTQ4Q1x1N0M3Qlx1NjU4N1x1NEVGNlx1NjVGNgpqYXZhYy5vcHQuQVQ9XHU0RUNFXHU2NTg3XHU0RUY2XHU4QkZCXHU1M0Q2XHU5MDA5XHU5ODc5XHU1NDhDXHU2NTg3XHU0RUY2XHU1NDBECmphdmFjLm9wdC5kaWFncz1cdTkwMDlcdTYyRTlcdThCQ0FcdTY1QURcdTZBMjFcdTVGMEYKamF2YWMub3B0LmFkZEV4cG9ydHM9XHU2MzA3XHU1QjlBXHU4OEFCXHU4OUM2XHU0RTNBXHU1REYyXHU0RUNFXHU1MTc2XHU1QjlBXHU0RTQ5XHU2QTIxXHU1NzU3XHU1QkZDXHU1MUZBXHU1MjMwXHU1MTc2XHU0RUQ2XHU2QTIxXHU1NzU3XHU2MjE2XHU4MDA1XHU1QkZDXHU1MUZBXHU1MjMwXHU2MjQwXHU2NzA5XG4gICAgICAgIFx1NjcyQVx1NTQ3RFx1NTQwRFx1NkEyMVx1NTc1NyAoXHU1OTgyXHU2NzlDIDxvdGhlci1tb2R1bGU+IFx1NEUzQSBBTEwtVU5OQU1FRCkgXHU3Njg0XHU3QTBCXHU1RThGXHU1MzA1XHUzMDAyCmphdmFjLm9wdC5hcmcuYWRkRXhwb3J0cz08XHU2QTIxXHU1NzU3Pi88XHU3QTBCXHU1RThGXHU1MzA1Pj08XHU1MTc2XHU0RUQ2XHU2QTIxXHU1NzU3PigsPFx1NTE3Nlx1NEVENlx1NkEyMVx1NTc1Nz4pKgpqYXZhYy5vcHQuYWRkUmVhZHM9XHU2MzA3XHU1QjlBXHU4OEFCXHU4OUM2XHU0RTNBXHU3RUQ5XHU1QjlBXHU2QTIxXHU1NzU3XHU5NzAwXHU4OTgxXHU3Njg0XHU1MTc2XHU0RUQ2XHU2QTIxXHU1NzU3XHUzMDAyXG48b3RoZXItbW9kdWxlPiBcdTUzRUZcdTgwRkRcdTk3MDBcdTg5ODFcdTRFM0EgQUxMLVVOTkFNRUQsIFx1NEVFNVx1NEZCRlx1ODk4MVx1NkM0Mlx1NjcyQVx1NTQ3RFx1NTQwRFx1NkEyMVx1NTc1N1x1MzAwMgpqYXZhYy5vcHQuYXJnLmFkZFJlYWRzPTxcdTZBMjFcdTU3NTc+PTxcdTUxNzZcdTRFRDZcdTZBMjFcdTU3NTc+KCw8XHU1MTc2XHU0RUQ2XHU2QTIxXHU1NzU3PikqCmphdmFjLm9wdC5wYXRjaD1cdTRGN0ZcdTc1MjggSkFSIFx1NjU4N1x1NEVGNlx1NjIxNlx1NzZFRVx1NUY1NVx1NEUyRFx1NzY4NFx1N0M3Qlx1NTQ4Q1x1OEQ0NFx1NkU5MFx1ODk4Nlx1NzZENlxuICAgICAgICBcdTYyMTZcdTU4OUVcdTVGM0FcdTZBMjFcdTU3NTcKamF2YWMub3B0LmFyZy5wYXRjaD08XHU2QTIxXHU1NzU3Pj08XHU2NTg3XHU0RUY2Pig6PFx1NjU4N1x1NEVGNj4pKgpqYXZhYy5vcHQubW9kdWxlPVx1NjMwN1x1NUI5QVx1NkI2M1x1NTcyOFx1N0YxNlx1OEJEMVx1NzY4NFx1N0M3Qlx1NjI0MFx1NUM1RVx1NzY4NFx1NkEyMVx1NTc1N1x1MzAwMgpqYXZhYy5vcHQuYXJnLm1vZHVsZT08XHU2QTIxXHU1NzU3PgpqYXZhYy5vcHQuYWRkbW9kcz1cdTk2NjRcdTRFODZcdTUyMURcdTU5Q0JcdTZBMjFcdTU3NTdcdTRFNEJcdTU5MTZcdTg5ODFcdTg5RTNcdTY3OTBcdTc2ODRcdTY4MzlcdTZBMjFcdTU3NTc7IFx1NTk4Mlx1Njc5QyA8bW9kdWxlPlxuICAgICAgICBcdTRFM0EgQUxMLU1PRFVMRS1QQVRILCBcdTUyMTlcdTRFM0FcdTZBMjFcdTU3NTdcdThERUZcdTVGODRcdTRFMkRcdTc2ODRcdTYyNDBcdTY3MDlcdTZBMjFcdTU3NTdcdTMwMDIKamF2YWMub3B0LmFyZy5hZGRtb2RzPTxcdTZBMjFcdTU3NTc+KCw8XHU2QTIxXHU1NzU3PikqCmphdmFjLm9wdC5saW1pdG1vZHM9XHU5NjUwXHU1MjM2XHU1M0VGXHU4OUMyXHU1QkRGXHU2QTIxXHU1NzU3XHU3Njg0XHU5ODg2XHU1N0RGCmphdmFjLm9wdC5hcmcubGltaXRtb2RzPTxcdTZBMjFcdTU3NTc+KCw8XHU2QTIxXHU1NzU3PikqCmphdmFjLm9wdC5tb2R1bGUudmVyc2lvbj1cdTYzMDdcdTVCOUFcdTZCNjNcdTU3MjhcdTdGMTZcdThCRDFcdTc2ODRcdTZBMjFcdTU3NTdcdTcyNDhcdTY3MkMKamF2YWMub3B0LmFyZy5tb2R1bGUudmVyc2lvbj08XHU3MjQ4XHU2NzJDPgpqYXZhYy5vcHQuaW5oZXJpdF9ydW50aW1lX2Vudmlyb25tZW50PVx1NEVDRVx1OEZEMFx1ODg0Q1x1NjVGNlx1NzNBRlx1NTg4M1x1N0VFN1x1NjI3Rlx1NkEyMVx1NTc1N1x1N0NGQlx1N0VERlx1OTE0RFx1N0Y2RVx1OTAwOVx1OTg3OVx1MzAwMgoKIyMgZXJyb3JzCgpqYXZhYy5lcnIuZW1wdHkuQS5hcmd1bWVudD0tQSBcdTk3MDBcdTg5ODFcdTRFMDBcdTRFMkFcdTUzQzJcdTY1NzA7IFx1NEY3Rlx1NzUyOCAnJy1Ba2V5JycgXHU2MjE2ICcnLUFrZXk9dmFsdWUnJwpqYXZhYy5lcnIuaW52YWxpZC5hcmc9XHU2NUUwXHU2NTQ4XHU3Njg0XHU1M0MyXHU2NTcwOiB7MH0KamF2YWMuZXJyLmludmFsaWQuQS5rZXk9XHU2Q0U4XHU5MUNBXHU1OTA0XHU3NDA2XHU3QTBCXHU1RThGXHU5MDA5XHU5ODc5ICcnezB9JycgXHU0RTJEXHU3Njg0XHU1MTczXHU5NTJFXHU1QjU3XHU0RTBEXHU2NjJGXHU0RUU1XHU3MEI5XHU1MjA2XHU5Njk0XHU3Njg0XHU2ODA3XHU4QkM2XHU3QjI2XHU1RThGXHU1MjE3CmphdmFjLmVyci5pbnZhbGlkLmZsYWc9XHU2NUUwXHU2NTQ4XHU3Njg0XHU2ODA3XHU4QkIwOiB7MH0KamF2YWMuZXJyLnByb2ZpbGUuYm9vdGNsYXNzcGF0aC5jb25mbGljdD1cdTY5ODJcdTg5ODFcdTRGRTFcdTYwNkZcdTU0OENcdTVGMTVcdTVCRkNcdTdDN0JcdThERUZcdTVGODRcdTkwMDlcdTk4NzlcdTRFMERcdTgwRkRcdTU0MENcdTY1RjZcdTRGN0ZcdTc1MjgKamF2YWMuZXJyLmludmFsaWQucHJvZmlsZT1cdTkxNERcdTdGNkVcdTY1ODdcdTRFRjZcdTY1RTBcdTY1NDg6IHswfQpqYXZhYy5lcnIuaW52YWxpZC50YXJnZXQ9XHU2NUUwXHU2NTQ4XHU3Njg0XHU3NkVFXHU2ODA3XHU1M0QxXHU4ODRDXHU3MjQ4OiB7MH0KamF2YWMuZXJyLm9wdGlvbi5ub3QuYWxsb3dlZC53aXRoLnRhcmdldD1cdTc2RUVcdTY4MDcgezF9IFx1NEUwRFx1NTE0MVx1OEJCOFx1OTAwOVx1OTg3OSB7MH0KamF2YWMuZXJyLm9wdGlvbi50b28ubWFueT1cdTkwMDlcdTk4NzkgezB9IFx1NTNFQVx1ODBGRFx1NjMwN1x1NUI5QVx1NEUwMFx1NkIyMQpqYXZhYy5lcnIubm8uc291cmNlLmZpbGVzPVx1NjVFMFx1NkU5MFx1NjU4N1x1NEVGNgpqYXZhYy5lcnIubm8uc291cmNlLmZpbGVzLmNsYXNzZXM9XHU2NUUwXHU2RTkwXHU2NTg3XHU0RUY2XHU2MjE2XHU3QzdCXHU1NDBECmphdmFjLmVyci5yZXEuYXJnPXswfVx1OTcwMFx1ODk4MVx1NTNDMlx1NjU3MApqYXZhYy5lcnIuaW52YWxpZC5zb3VyY2U9XHU2NUUwXHU2NTQ4XHU3Njg0XHU2RTkwXHU1M0QxXHU4ODRDXHU3MjQ4OiB7MH0KamF2YWMuZXJyLmVycm9yLndyaXRpbmcuZmlsZT1cdTUxOTlcdTUxNjV7MH1cdTY1RjZcdTUxRkFcdTk1MTk7IHsxfQpqYXZhYy5lcnIuc291cmNlcGF0aC5tb2R1bGVzb3VyY2VwYXRoLmNvbmZsaWN0PVx1NjVFMFx1NkNENVx1NTQwQ1x1NjVGNlx1NjMwN1x1NUI5QSAtLXNvdXJjZS1wYXRoIFx1NEUwRSAtLW1vZHVsZS1zb3VyY2UtcGF0aApqYXZhYy53YXJuLnNvdXJjZS50YXJnZXQuY29uZmxpY3Q9XHU2RTkwXHU1M0QxXHU4ODRDXHU3MjQ4IHswfSBcdTk3MDBcdTg5ODFcdTc2RUVcdTY4MDdcdTUzRDFcdTg4NENcdTcyNDggezF9CmphdmFjLndhcm4udGFyZ2V0LmRlZmF1bHQuc291cmNlLmNvbmZsaWN0PVx1NzZFRVx1NjgwN1x1NTNEMVx1ODg0Q1x1NzI0OCB7MH0gXHU0RTBFXHU5RUQ4XHU4QkE0XHU3Njg0XHU2RTkwXHU1M0QxXHU4ODRDXHU3MjQ4IHsxfSBcdTUxQjJcdTdBODEKamF2YWMud2Fybi5wcm9maWxlLnRhcmdldC5jb25mbGljdD1cdTkxNERcdTdGNkVcdTY1ODdcdTRFRjZ7MH1cdTVCRjlcdTRFOEVcdTc2RUVcdTY4MDdcdTUzRDFcdTg4NENcdTcyNDggezF9IFx1NjVFMFx1NjU0OApqYXZhYy5lcnIuZmlsZS5ub3QuZm91bmQ9XHU2MjdFXHU0RTBEXHU1MjMwXHU2NTg3XHU0RUY2OiB7MH0KamF2YWMuZXJyLmZpbGUubm90LmRpcmVjdG9yeT1cdTRFMERcdTY2MkZcdTc2RUVcdTVGNTU6IHswfQpqYXZhYy5lcnIuZmlsZS5ub3QuZmlsZT1cdTRFMERcdTY2MkZcdTY1ODdcdTRFRjY6IHswfQpqYXZhYy5lcnIuY2Fubm90LmFjY2Vzcy5ydW50aW1lLmVudj1cdTY1RTBcdTZDRDVcdThCQkZcdTk1RUVcdThGRDBcdTg4NENcdTY1RjZcdTczQUZcdTU4ODMKamF2YWMuZXJyLmJhZC52YWx1ZS5mb3Iub3B0aW9uPXswfSBcdTkwMDlcdTk4NzlcdTc2ODRcdTUwM0NcdTk1MTlcdThCRUY6ICcnezF9JycKamF2YWMuZXJyLm5vLnZhbHVlLmZvci5vcHRpb249ezB9IFx1OTAwOVx1OTg3OVx1NkNBMVx1NjcwOVx1NTAzQwpqYXZhYy5lcnIucmVwZWF0ZWQudmFsdWUuZm9yLnBhdGNoLm1vZHVsZT1cdTRFM0EgezB9IFx1NTkxQVx1NkIyMVx1NjMwN1x1NUI5QVx1NEU4NiAtLXBhdGNoLW1vZHVsZQoKIyMgbWVzc2FnZXMKCmphdmFjLm1zZy51c2FnZS5oZWFkZXI9XHU3NTI4XHU2Q0Q1OiB7MH0gPG9wdGlvbnM+IDxzb3VyY2UgZmlsZXM+XG5cdTUxNzZcdTRFMkQsIFx1NTNFRlx1ODBGRFx1NzY4NFx1OTAwOVx1OTg3OVx1NTMwNVx1NjJFQzoKCmphdmFjLm1zZy51c2FnZT1cdTc1MjhcdTZDRDU6IHswfSA8XHU5MDA5XHU5ODc5PiA8XHU2RTkwXHU2NTg3XHU0RUY2PlxuXHU0RjdGXHU3NTI4IC0taGVscCBcdTUzRUZcdTUyMTdcdTUxRkFcdTUzRUZcdTgwRkRcdTc2ODRcdTkwMDlcdTk4NzkKCmphdmFjLm1zZy51c2FnZS5ub25zdGFuZGFyZC5mb290ZXI9XHU4RkQ5XHU0RTlCXHU5ODlEXHU1OTE2XHU5MDA5XHU5ODc5XHU1OTgyXHU2NzA5XHU2NkY0XHU2NTM5LCBcdTYwNTVcdTRFMERcdTUzRTZcdTg4NENcdTkwMUFcdTc3RTVcdTMwMDIKCmphdmFjLm1zZy5idWc9XHU3RjE2XHU4QkQxXHU1NjY4ICh7MH0pIFx1NEUyRFx1NTFGQVx1NzNCMFx1NUYwMlx1NUUzOFx1OTUxOVx1OEJFRlx1MzAwMlx1NTk4Mlx1Njc5Q1x1NTcyOCBCdWcgRGF0YWJhc2UgKGh0dHA6Ly9idWdzLmphdmEuY29tKSBcdTRFMkRcdTZDQTFcdTY3MDlcdTYyN0VcdTUyMzBcdThCRTVcdTk1MTlcdThCRUYsIFx1OEJGN1x1OTAxQVx1OEZDNyBKYXZhIEJ1ZyBcdTYyQTVcdTU0NEFcdTk4NzUgKGh0dHA6Ly9idWdyZXBvcnQuamF2YS5jb20pIFx1NUVGQVx1N0FDQlx1OEJFNSBKYXZhIFx1N0YxNlx1OEJEMVx1NTY2OCBCdWdcdTMwMDJcdThCRjdcdTU3MjhcdTYyQTVcdTU0NEFcdTRFMkRcdTk2NDRcdTRFMEFcdTYwQThcdTc2ODRcdTdBMEJcdTVFOEZcdTU0OENcdTRFRTVcdTRFMEJcdThCQ0FcdTY1QURcdTRGRTFcdTYwNkZcdTMwMDJcdThDMjJcdThDMjJcdTMwMDIKCmphdmFjLm1zZy5pbz1cblxuXHU1M0QxXHU3NTFGXHU4RjkzXHU1MTY1L1x1OEY5M1x1NTFGQVx1OTUxOVx1OEJFRlx1MzAwMlxuXHU2NzA5XHU1MTczXHU4QkU2XHU3RUM2XHU0RkUxXHU2MDZGLCBcdThCRjdcdTUzQzJcdTk2MDVcdTRFRTVcdTRFMEJcdTU4MDZcdTY4MDhcdThEREZcdThFMkFcdTMwMDJcbgoKamF2YWMubXNnLnByb2MuYW5ub3RhdGlvbi51bmNhdWdodC5leGNlcHRpb249XG5cblx1NkNFOFx1OTFDQVx1NTkwNFx1NzQwNlx1N0EwQlx1NUU4Rlx1NjI5Qlx1NTFGQVx1NjcyQVx1NjM1NVx1ODNCN1x1NzY4NFx1NUYwMlx1NUUzOFx1OTUxOVx1OEJFRlx1MzAwMlxuXHU2NzA5XHU1MTczXHU4QkU2XHU3RUM2XHU0RkUxXHU2MDZGLCBcdThCRjdcdTUzQzJcdTk2MDVcdTRFRTVcdTRFMEJcdTU4MDZcdTY4MDhcdThEREZcdThFMkFcdTMwMDJcbgoKamF2YWMubXNnLnBsdWdpbi51bmNhdWdodC5leGNlcHRpb249XG5cblx1NjNEMlx1NEVGNlx1NjI5Qlx1NTFGQVx1NjcyQVx1NjM1NVx1ODNCN1x1NzY4NFx1NUYwMlx1NUUzOFx1OTUxOVx1OEJFRlx1MzAwMlxuXHU2NzA5XHU1MTczXHU4QkU2XHU3RUM2XHU0RkUxXHU2MDZGLCBcdThCRjdcdTUzQzJcdTk2MDVcdTRFRTVcdTRFMEJcdTU4MDZcdTY4MDhcdThEREZcdThFMkFcdTMwMDJcbgoKamF2YWMubXNnLnJlc291cmNlPVxuXG5cdTdDRkJcdTdFREZcdThENDRcdTZFOTBcdTRFMERcdThEQjNcdTMwMDJcblx1NjcwOVx1NTE3M1x1OEJFNlx1N0VDNlx1NEZFMVx1NjA2RiwgXHU4QkY3XHU1M0MyXHU5NjA1XHU0RUU1XHU0RTBCXHU1ODA2XHU2ODA4XHU4RERGXHU4RTJBXHUzMDAyXG4KCmphdmFjLnZlcnNpb249ezB9IHsxfQpqYXZhYy5mdWxsVmVyc2lvbj17MH1cdTVCOENcdTY1NzRcdTcyNDhcdTY3MkMgInsxfSIKCmphdmFjLmVyci5yZWxlYXNlLmJvb3RjbGFzc3BhdGguY29uZmxpY3Q9XHU5MDA5XHU5ODc5IHswfSBcdTRFMERcdTgwRkRcdTRFMEUgLS1yZWxlYXNlIFx1NEUwMFx1OEQ3N1x1NEY3Rlx1NzUyOAoKamF2YWMuZXJyLnVuc3VwcG9ydGVkLnJlbGVhc2UudmVyc2lvbj1cdTRFMERcdTY1MkZcdTYzMDFcdTUzRDFcdTg4NENcdTcyNDhcdTY3MkMgezB9CgpqYXZhYy5lcnIucmVsZWFzZS5ub3Quc3RhbmRhcmQuZmlsZS5tYW5hZ2VyPVx1NjMwN1x1NUI5QVx1NEU4NiAtLXJlbGVhc2UgXHU5MDA5XHU5ODc5LCBcdTRGNDZcdTYzRDBcdTRGOUJcdTc2ODQgSmF2YUZpbGVNYW5hZ2VyIFx1NEUwRFx1NjYyRiBTdGFuZGFyZEphdmFGaWxlTWFuYWdlclx1MzAwMgpQSwMECgAACAAABjupSjUGMv9vpQEAb6UBADcAAABjb20vc3VuL3Rvb2xzL2phdmFjL3Jlc291cmNlcy9jb21waWxlcl96aF9DTi5wcm9wZXJ0aWVzIwojIENvcHlyaWdodCAoYykgMTk5OSwgMjAxNywgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KIyBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiMKIyBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAojIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiMgcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAojIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgojCiMgVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiMgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiMgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiMgdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKIyBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgojCiMgWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgojIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKIyBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiMKIyBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQojIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKIyBxdWVzdGlvbnMuCiMKCiMgTWVzc2FnZXMgaW4gdGhpcyBmaWxlIHdoaWNoIHVzZSAicGxhY2Vob2xkZXJzIiBmb3IgdmFsdWVzIChlLmcuIHswfSwgezF9KQojIGFyZSBwcmVjZWRlZCBieSBhIHN0eWxpemVkIGNvbW1lbnQgZGVzY3JpYmluZyB0aGUgdHlwZSBvZiB0aGUgY29ycmVzcG9uZGluZwojIHZhbHVlcy4KIyBUaGUgc2ltcGxlIHR5cGVzIGN1cnJlbnRseSBpbiB1c2UgYXJlOgojCiMgYm9vbGVhbiAgICAgICAgICAgdHJ1ZSBvciBmYWxzZQojIGRpYWdub3N0aWMgICAgICAgIGEgc3ViLW1lc3NhZ2U7IHNlZSBjb21waWxlci5taXNjLioKIyBmcmFnbWVudCAgICAgICAgICBzaW1pbGFyIHRvICdtZXNzYWdlIHNlZ21lbnQnLCBidXQgd2l0aCBtb3JlIHNwZWNpZmljIHR5cGUKIyBtb2RpZmllciAgICAgICAgICBhIEphdmEgbW9kaWZpZXI7IGUuZy4gcHVibGljLCBwcml2YXRlLCBwcm90ZWN0ZWQKIyBmaWxlICAgICAgICAgICAgICBhIGZpbGUgVVJMCiMgZmlsZSBvYmplY3QgICAgICAgYSBmaWxlIFVSTCAtIHNpbWlsYXIgdG8gJ2ZpbGUnIGJ1dCB0eXBpY2FsbHkgdXNlZCBmb3Igc291cmNlL2NsYXNzIGZpbGVzLCBoZW5jZSBtb3JlIHNwZWNpZmljCiMgbmFtZSAgICAgICAgICAgICAgYSBuYW1lLCB0eXBpY2FsbHkgYSBKYXZhIGlkZW50aWZpZXIKIyBudW1iZXIgICAgICAgICAgICBhbiBpbnRlZ2VyCiMgb3B0aW9uIG5hbWUgICAgICAgdGhlIG5hbWUgb2YgYSBjb21tYW5kIGxpbmUgb3B0aW9uCiMgc291cmNlIHZlcnNpb24gICAgYSBzb3VyY2UgdmVyc2lvbiBudW1iZXIsIHN1Y2ggYXMgMS41LCAxLjYsIDEuNwojIHN0cmluZyAgICAgICAgICAgIGEgZ2VuZXJhbCBzdHJpbmcKIyBzeW1ib2wgICAgICAgICAgICB0aGUgbmFtZSBvZiBhIGRlY2xhcmVkIHR5cGUKIyBzeW1ib2wga2luZCAgICAgICB0aGUga2luZCBvZiBhIHN5bWJvbCAoaS5lLiBtZXRob2QsIHZhcmlhYmxlKQojIGtpbmQgbmFtZSAgICAgICAgIGFuIGluZm9ybWF0aXZlIGRlc2NyaXB0aW9uIG9mIHRoZSBraW5kIG9mIGEgZGVjbGFyYXRpb247IHNlZSBjb21waWxlci5taXNjLmtpbmRuYW1lLioKIyB0b2tlbiAgICAgICAgICAgICB0aGUgbmFtZSBvZiBhIG5vbi10ZXJtaW5hbCBpbiBzb3VyY2UgY29kZTsgc2VlIGNvbXBpbGVyLm1pc2MudG9rZW4uKgojIHR5cGUgICAgICAgICAgICAgIGEgSmF2YSB0eXBlOyBlLmcuIGludCwgWCwgWDxUPgojIG9iamVjdCAgICAgICAgICAgIGEgSmF2YSBvYmplY3QgKHVuc3BlY2lmaWVkKQojIHVudXNlZCAgICAgICAgICAgIHRoZSB2YWx1ZSBpcyBub3QgdXNlZCBpbiB0aGlzIG1lc3NhZ2UKIwojIFRoZSBmb2xsb3dpbmcgY29tcG91bmQgdHlwZXMgYXJlIGFsc28gdXNlZDoKIwojIGxpc3Qgb2YgWCAgICAgICAgIGEgY29tbWEtc2VwYXJhdGVkIGxpc3Qgb2YgaXRlbXM7IGUuZy4gbGlzdCBvZiB0eXBlCiMgc2V0IG9mIFggICAgICAgICAgYSBjb21tYS1zZXBhcmF0ZWQgY29sbGVjdGlvbiBvZiBpdGVtczsgZS5nLiBzZXQgb2YgbW9kaWZpZXIKIwojIFRoZXNlIG1heSBiZSBjb21wb3NlZDoKIwojIGxpc3Qgb2YgdHlwZSBvciBtZXNzYWdlIHNlZ21lbnQKIwojIFRoZSBmb2xsb3dpbmcgdHlwZSBhbGlhc2VzIGFyZSBzdXBwb3J0ZWQ6CiMKIyBtZXNzYWdlIHNlZ21lbnQgLS0+IGRpYWdub3N0aWMgb3IgZnJhZ21lbnQKIyBmaWxlIG5hbWUgLS0+IGZpbGUgb3IgZmlsZSBvYmplY3QKIwojIEN1c3RvbSBjb21tZW50cyBhcmUgc3VwcG9ydGVkIGluIHBhcmVudGhlc2lzIGkuZS4KIwojIG51bWJlciAoY2xhc3NmaWxlIG1ham9yIHZlcnNpb24pCiMKIyBUaGVzZSBjb21tZW50cyBhcmUgdXNlZCBpbnRlcm5hbGx5IGluIG9yZGVyIHRvIGdlbmVyYXRlIGFuIGVudW0tbGlrZSBjbGFzcyBkZWNsYXJhdGlvbiBjb250YWluaW5nCiMgYSBtZXRob2QvZmllbGQgZm9yIGVhY2ggb2YgdGhlIGRpYWdub3N0aWMga2V5cyBsaXN0ZWQgaGVyZS4gVGhvc2UgbWV0aG9kcy9maWVsZHMgY2FuIHRoZW4gYmUgdXNlZAojIGJ5IGphdmFjIGNvZGUgdG8gYnVpbGQgZGlhZ25vc3RpY3MgaW4gYSB0eXBlLXNhZmUgZmFzaGlvbi4KIwojIEluIGFkZGl0aW9uLCB0aGVzZSBjb21tZW50cyBhcmUgdmVyaWZpZWQgYnkgdGhlIGp0cmVnIHRlc3QgdGVzdC90b29scy9qYXZhYy9kaWFncy9NZXNzYWdlSW5mbywKIyB1c2luZyBpbmZvIGRlcml2ZWQgZnJvbSB0aGUgY29sbGVjdGVkIHNldCBvZiBleGFtcGxlcyBpbiB0ZXN0L3Rvb2xzL2phdmFjL2RpYWdzL2V4YW1wbGVzLgojIE1lc3NhZ2VJbmZvIGNhbiBhbHNvIGJlIHJ1biBhcyBhIHN0YW5kYWxvbmUgdXRpbGl0eSBwcm92aWRpbmcgbW9yZSBmYWNpbGl0aWVzCiMgZm9yIG1hbmlwdWxhdGluZyB0aGlzIGZpbGUuIEZvciBtb3JlIGRldGFpbHMsIHNlZSBNZXNzYWdlSW5mby5qYXZhLgoKIyMKIyMgZXJyb3JzCiMjCgojIDA6IHN5bWJvbApjb21waWxlci5lcnIuYWJzdHJhY3QuY2FudC5iZS5pbnN0YW50aWF0ZWQ9ezB9XHU2NjJGXHU2MkJEXHU4QzYxXHU3Njg0OyBcdTY1RTBcdTZDRDVcdTVCOUVcdTRGOEJcdTUzMTYKCmNvbXBpbGVyLmVyci5hYnN0cmFjdC5tZXRoLmNhbnQuaGF2ZS5ib2R5PVx1NjJCRFx1OEM2MVx1NjVCOVx1NkNENVx1NEUwRFx1ODBGRFx1NjcwOVx1NEUzQlx1NEY1MwoKY29tcGlsZXIuZXJyLmFscmVhZHkuYW5ub3RhdGVkPXswfSB7MX1cdTVERjJcdThGREJcdTg4NENcdTZDRThcdTkxQ0EKCiMgMDogc3ltYm9sIGtpbmQsIDE6IHN5bWJvbCwgMjogc3ltYm9sIGtpbmQsIDM6IHN5bWJvbApjb21waWxlci5lcnIuYWxyZWFkeS5kZWZpbmVkPVx1NURGMlx1NTcyOHsyfSB7M31cdTRFMkRcdTVCOUFcdTRFNDlcdTRFODZ7MH0gezF9CgojIDA6IHN5bWJvbCBraW5kLCAxOiBzeW1ib2wsIDI6IHN5bWJvbCBraW5kLCAzOiBzeW1ib2wga2luZCwgNDogc3ltYm9sCmNvbXBpbGVyLmVyci5hbHJlYWR5LmRlZmluZWQuaW4uY2xpbml0PVx1NURGMlx1NTcyOHszfSB7NH1cdTc2ODR7Mn1cdTRFMkRcdTVCOUFcdTRFNDlcdTRFODZ7MH0gezF9CgojIDA6IHN0cmluZwpjb21waWxlci5lcnIuYWxyZWFkeS5kZWZpbmVkLnNpbmdsZS5pbXBvcnQ9ezB9XHU3Njg0IHNpbmdsZS10eXBlLWltcG9ydCBcdTVERjJcdTVCOUFcdTRFNDlcdTUxNzdcdTY3MDlcdTc2RjhcdTU0MENcdTdCODBcdTU0MERcdTc2ODRcdTdDN0JcdTU3OEIKCiMgMDogc3RyaW5nCmNvbXBpbGVyLmVyci5hbHJlYWR5LmRlZmluZWQuc3RhdGljLnNpbmdsZS5pbXBvcnQ9ezB9XHU3Njg0XHU5NzU5XHU2MDAxIHNpbmdsZS10eXBlLWltcG9ydCBcdTVERjJcdTVCOUFcdTRFNDlcdTUxNzdcdTY3MDlcdTc2RjhcdTU0MENcdTdCODBcdTU0MERcdTc2ODRcdTdDN0JcdTU3OEIKCmNvbXBpbGVyLmVyci5hbHJlYWR5LmRlZmluZWQudGhpcy51bml0PVx1NURGMlx1NTcyOFx1OEJFNVx1N0YxNlx1OEJEMVx1NTM1NVx1NTE0M1x1NEUyRFx1NUI5QVx1NEU0OXswfQoKIyAwOiB0eXBlLCAxOiBsaXN0IG9mIG5hbWUKY29tcGlsZXIuZXJyLmFubm90YXRpb24ubWlzc2luZy5kZWZhdWx0LnZhbHVlPVx1NUJGOVx1NEU4RVx1NTE0M1x1N0QyMCAnJ3sxfScnLCBcdTZDRThcdTkxQ0EgQHswfSBcdTdGM0FcdTVDMTFcdTlFRDhcdThCQTRcdTUwM0MKCiMgMDogdHlwZSwgMTogbGlzdCBvZiBuYW1lCmNvbXBpbGVyLmVyci5hbm5vdGF0aW9uLm1pc3NpbmcuZGVmYXVsdC52YWx1ZS4xPVx1NUJGOVx1NEU4RVx1NTE0M1x1N0QyMHsxfSwgXHU2Q0U4XHU5MUNBIEB7MH0gXHU3RjNBXHU1QzExXHU5RUQ4XHU4QkE0XHU1MDNDCgojIDA6IHR5cGUKY29tcGlsZXIuZXJyLmFubm90YXRpb24ubm90LnZhbGlkLmZvci50eXBlPVx1NkNFOFx1OTFDQVx1NUJGOVx1NEU4RVx1N0M3Qlx1NTc4QnswfVx1NzY4NFx1NTE0M1x1N0QyMFx1NjVFMFx1NjU0OAoKY29tcGlsZXIuZXJyLmFubm90YXRpb24udHlwZS5ub3QuYXBwbGljYWJsZT1cdTZDRThcdTkxQ0FcdTdDN0JcdTU3OEJcdTRFMERcdTkwMDJcdTc1MjhcdTRFOEVcdThCRTVcdTdDN0JcdTU3OEJcdTc2ODRcdTU4RjBcdTY2MEUKCiMgMDogdHlwZQpjb21waWxlci5lcnIuYW5ub3RhdGlvbi50eXBlLm5vdC5hcHBsaWNhYmxlLnRvLnR5cGU9XHU2Q0U4XHU5MUNBIEB7MH0gXHU1NzI4XHU2QjY0XHU3QzdCXHU1NzhCXHU0RTBBXHU0RTBCXHU2NTg3XHU0RTJEXHU0RTBEXHU5MDAyXHU3NTI4Cgpjb21waWxlci5lcnIuYW5ub3RhdGlvbi52YWx1ZS5tdXN0LmJlLmFubm90YXRpb249XHU2Q0U4XHU5MUNBXHU1MDNDXHU1RkM1XHU5ODdCXHU0RTNBXHU2Q0U4XHU5MUNBCgpjb21waWxlci5lcnIuYW5ub3RhdGlvbi52YWx1ZS5tdXN0LmJlLmNsYXNzLmxpdGVyYWw9XHU2Q0U4XHU5MUNBXHU1MDNDXHU1RkM1XHU5ODdCXHU0RTNBXHU3QzdCXHU2NTg3XHU1QjU3Cgpjb21waWxlci5lcnIuYW5ub3RhdGlvbi52YWx1ZS5tdXN0LmJlLm5hbWUudmFsdWU9XHU2Q0U4XHU5MUNBXHU1MDNDXHU1RkM1XHU5ODdCXHU5MUM3XHU3NTI4ICcnbmFtZT12YWx1ZScnIFx1NjgzQ1x1NUYwRgoKY29tcGlsZXIuZXJyLmFubm90YXRpb24udmFsdWUubm90LmFsbG93YWJsZS50eXBlPVx1NkNFOFx1OTFDQVx1NTAzQ1x1NEUwRFx1NjYyRlx1NTE0MVx1OEJCOFx1NzY4NFx1N0M3Qlx1NTc4QgoKY29tcGlsZXIuZXJyLmFub24uY2xhc3MuaW1wbC5pbnRmLm5vLmFyZ3M9XHU1MzNGXHU1NDBEXHU3QzdCXHU1QjlFXHU3M0IwXHU2M0E1XHU1M0UzOyBcdTRFMERcdTgwRkRcdTY3MDlcdTUzQzJcdTY1NzAKCmNvbXBpbGVyLmVyci5hbm9uLmNsYXNzLmltcGwuaW50Zi5uby50eXBlYXJncz1cdTUzM0ZcdTU0MERcdTdDN0JcdTVCOUVcdTczQjBcdTYzQTVcdTUzRTM7IFx1NEUwRFx1ODBGRFx1NTE3N1x1NjcwOVx1N0M3Qlx1NTc4Qlx1NTNDMlx1NjU3MAoKY29tcGlsZXIuZXJyLmFub24uY2xhc3MuaW1wbC5pbnRmLm5vLnF1YWwuZm9yLm5ldz1cdTUzM0ZcdTU0MERcdTdDN0JcdTVCOUVcdTczQjBcdTYzQTVcdTUzRTM7IFx1NEUwRFx1ODBGRFx1NjcwOVx1OTY1MFx1NUI5QVx1N0IyNiAtIFx1NUJGOVx1NEU4RVx1NjVCMAoKY29tcGlsZXIuZXJyLmNhbnQuaW5oZXJpdC5mcm9tLmFub249XHU2NUUwXHU2Q0Q1XHU0RUNFXHU1MzNGXHU1NDBEXHU3QzdCXHU3RUU3XHU2MjdGCgojIDA6IHN5bWJvbCwgMTogc3ltYm9sLCAyOiBzeW1ib2wKY29tcGlsZXIuZXJyLmFycmF5LmFuZC52YXJhcmdzPVx1NjVFMFx1NkNENVx1NTcyOHsyfVx1NEUyRFx1NTQwQ1x1NjVGNlx1NThGMFx1NjYwRXswfVx1NTQ4Q3sxfQoKY29tcGlsZXIuZXJyLmFycmF5LmRpbWVuc2lvbi5taXNzaW5nPVx1N0YzQVx1NUMxMVx1NjU3MFx1N0VDNFx1N0VGNAoKIyAwOiB0eXBlCmNvbXBpbGVyLmVyci5hcnJheS5yZXEuYnV0LmZvdW5kPVx1OTcwMFx1ODk4MVx1NjU3MFx1N0VDNCwgXHU0RjQ2XHU2MjdFXHU1MjMwezB9Cgpjb21waWxlci5lcnIuYXR0cmlidXRlLnZhbHVlLm11c3QuYmUuY29uc3RhbnQ9XHU1MTQzXHU3RDIwXHU1MDNDXHU1RkM1XHU5ODdCXHU0RTNBXHU1RTM4XHU5MUNGXHU4ODY4XHU4RkJFXHU1RjBGCgojIDA6IHN0cmluZyAoc3RhdGVtZW50IHR5cGUpCmNvbXBpbGVyLmVyci5iYWQuaW5pdGlhbGl6ZXI9ezB9XHU3Njg0XHU1MjFEXHU1OUNCXHU1MzE2XHU3QTBCXHU1RThGXHU5NTE5XHU4QkVGCgpjb21waWxlci5lcnIuYnJlYWsub3V0c2lkZS5zd2l0Y2gubG9vcD1cdTU3Mjggc3dpdGNoIFx1NjIxNiBsb29wIFx1NTkxNlx1OTBFOFx1NEUyRFx1NjVBRAoKIyAwOiBuYW1lCmNvbXBpbGVyLmVyci5jYWxsLm11c3QuYmUuZmlyc3Quc3RtdC5pbi5jdG9yPVx1NUJGOXswfVx1NzY4NFx1OEMwM1x1NzUyOFx1NUZDNVx1OTg3Qlx1NjYyRlx1Njc4NFx1OTAyMFx1NTY2OFx1NEUyRFx1NzY4NFx1N0IyQ1x1NEUwMFx1NEUyQVx1OEJFRFx1NTNFNQoKIyAwOiBzeW1ib2wga2luZCwgMTogbmFtZSwgMjogbGlzdCBvZiB0eXBlIG9yIG1lc3NhZ2Ugc2VnbWVudCwgMzogbGlzdCBvZiB0eXBlIG9yIG1lc3NhZ2Ugc2VnbWVudCwgNDogc3ltYm9sIGtpbmQsIDU6IHR5cGUsIDY6IG1lc3NhZ2Ugc2VnbWVudApjb21waWxlci5lcnIuY2FudC5hcHBseS5zeW1ib2w9XHU2NUUwXHU2Q0Q1XHU1QzA2ezR9IHs1fVx1NEUyRFx1NzY4NHswfSB7MX1cdTVFOTRcdTc1MjhcdTUyMzBcdTdFRDlcdTVCOUFcdTdDN0JcdTU3OEI7XG5cdTk3MDBcdTg5ODE6IHsyfVxuXHU2MjdFXHU1MjMwOiB7M31cblx1NTM5Rlx1NTZFMDogezZ9CgojIDA6IHN5bWJvbCBraW5kLCAxOiBuYW1lLCAyOiBsaXN0IG9mIHR5cGUKY29tcGlsZXIuZXJyLmNhbnQuYXBwbHkuc3ltYm9scz1cdTVCRjlcdTRFOEV7MX0oezJ9KSwgXHU2MjdFXHU0RTBEXHU1MjMwXHU1NDA4XHU5MDAyXHU3Njg0ezB9CgojIDA6IHN5bWJvbCBraW5kLCAxOiBuYW1lLCAyOiBsaXN0IG9mIHR5cGUgb3IgbWVzc2FnZSBzZWdtZW50LCAzOiBsaXN0IG9mIHR5cGUgb3IgbWVzc2FnZSBzZWdtZW50LCA0OiBzeW1ib2wga2luZCwgNTogdHlwZSwgNjogbWVzc2FnZSBzZWdtZW50CmNvbXBpbGVyLm1pc2MuY2FudC5hcHBseS5zeW1ib2w9XHU2NUUwXHU2Q0Q1XHU1QzA2IHs0fSB7NX1cdTRFMkRcdTc2ODQgezB9IHsxfVx1NUU5NFx1NzUyOFx1NTIzMFx1N0VEOVx1NUI5QVx1N0M3Qlx1NTc4QlxuXHU5NzAwXHU4OTgxOiB7Mn1cblx1NjI3RVx1NTIzMDogezN9XG5cdTUzOUZcdTU2RTA6IHs2fQoKIyAwOiBzeW1ib2wga2luZCwgMTogbmFtZSwgMjogbGlzdCBvZiB0eXBlCmNvbXBpbGVyLm1pc2MuY2FudC5hcHBseS5zeW1ib2xzPVx1NUJGOVx1NEU4RXsxfSh7Mn0pLCBcdTYyN0VcdTRFMERcdTUyMzBcdTU0MDhcdTkwMDJcdTc2ODR7MH0KCiMgMDogc3ltYm9sIGtpbmQsIDE6IHN5bWJvbApjb21waWxlci5taXNjLm5vLmFic3RyYWN0cz1cdTU3MjggezB9IHsxfSBcdTRFMkRcdTYyN0VcdTRFMERcdTUyMzBcdTYyQkRcdThDNjFcdTY1QjlcdTZDRDUKCiMgMDogc3ltYm9sIGtpbmQsIDE6IHN5bWJvbApjb21waWxlci5taXNjLmluY29tcGF0aWJsZS5hYnN0cmFjdHM9XHU1NzI4IHswfSB7MX0gXHU0RTJEXHU2MjdFXHU1MjMwXHU1OTFBXHU0RTJBXHU5NzVFXHU4OTg2XHU3NkQ2XHU2MkJEXHU4QzYxXHU2NUI5XHU2Q0Q1Cgpjb21waWxlci5lcnIuYmFkLmZ1bmN0aW9uYWwuaW50Zi5hbm5vPVx1NjEwRlx1NTkxNlx1NzY4NCBARnVuY3Rpb25hbEludGVyZmFjZSBcdTZDRThcdTkxQ0EKCiMgMDogbWVzc2FnZSBzZWdtZW50CmNvbXBpbGVyLmVyci5iYWQuZnVuY3Rpb25hbC5pbnRmLmFubm8uMT1cdTYxMEZcdTU5MTZcdTc2ODQgQEZ1bmN0aW9uYWxJbnRlcmZhY2UgXHU2Q0U4XHU5MUNBXG57MH0KCiMgMDogbWVzc2FnZSBzZWdtZW50CmNvbXBpbGVyLmVyci5hbm9ueW1vdXMuZGlhbW9uZC5tZXRob2QuZG9lcy5ub3Qub3ZlcnJpZGUuc3VwZXJjbGFzcz1cdTY1QjlcdTZDRDVcdTRFMERcdTRGMUFcdTg5ODZcdTc2RDZcdTYyMTZcdTVCOUVcdTczQjBcdThEODVcdTdDN0JcdTU3OEJcdTRFMkRcdTc2ODRcdTY1QjlcdTZDRDVcbnswfQoKIyAwOiBzeW1ib2wKY29tcGlsZXIubWlzYy5ub3QuYS5mdW5jdGlvbmFsLmludGY9ezB9IFx1NEUwRFx1NjYyRlx1NTFGRFx1NjU3MFx1NjNBNVx1NTNFMwoKIyAwOiBzeW1ib2wsIDE6IG1lc3NhZ2Ugc2VnbWVudApjb21waWxlci5taXNjLm5vdC5hLmZ1bmN0aW9uYWwuaW50Zi4xPXswfSBcdTRFMERcdTY2MkZcdTUxRkRcdTY1NzBcdTYzQTVcdTUzRTNcbnsxfQoKIyAwOiBzeW1ib2wsIDE6IHN5bWJvbCBraW5kLCAyOiBzeW1ib2wKY29tcGlsZXIubWlzYy5pbnZhbGlkLmdlbmVyaWMubGFtYmRhLnRhcmdldD1sYW1iZGEgXHU4ODY4XHU4RkJFXHU1RjBGXHU3Njg0XHU1MUZEXHU2NTcwXHU2M0NGXHU4RkYwXHU3QjI2XHU2NUUwXHU2NTQ4XG57MX0gezJ9IFx1NEUyRFx1NzY4NFx1NjVCOVx1NkNENSB7MH0gXHU0RTNBXHU2Q0RCXHU1NzhCXHU2NUI5XHU2Q0Q1CgojIDA6IHN5bWJvbCBraW5kLCAxOiBzeW1ib2wKY29tcGlsZXIubWlzYy5pbmNvbXBhdGlibGUuZGVzY3MuaW4uZnVuY3Rpb25hbC5pbnRmPVx1NTcyOCB7MH0gezF9IFx1NEUyRFx1NjI3RVx1NTIzMFx1NEUwRFx1NTE3Q1x1NUJCOVx1NzY4NFx1NTFGRFx1NjU3MFx1NjNDRlx1OEZGMFx1N0IyNgoKIyAwOiBuYW1lLCAxOiBsaXN0IG9mIHR5cGUsIDI6IHR5cGUsIDM6IGxpc3Qgb2YgdHlwZQpjb21waWxlci5taXNjLmRlc2NyaXB0b3I9XHU2M0NGXHU4RkYwXHU3QjI2OiB7Mn0gezB9KHsxfSkKCiMgMDogbmFtZSwgMTogbGlzdCBvZiB0eXBlLCAyOiB0eXBlLCAzOiBsaXN0IG9mIHR5cGUKY29tcGlsZXIubWlzYy5kZXNjcmlwdG9yLnRocm93cz1cdTYzQ0ZcdThGRjBcdTdCMjY6IHsyfSB7MH0oezF9KSBcdTYyOUJcdTUxRkF7M30KCiMgMDogdHlwZQpjb21waWxlci5taXNjLm5vLnN1aXRhYmxlLmZ1bmN0aW9uYWwuaW50Zi5pbnN0PVx1NjVFMFx1NkNENVx1NjNBOFx1NjVBRHswfVx1NzY4NFx1NTFGRFx1NjU3MFx1NjNBNVx1NTNFM1x1NjNDRlx1OEZGMFx1N0IyNgoKIyAwOiBtZXNzYWdlIHNlZ21lbnQKY29tcGlsZXIubWlzYy5iYWQuaW50ZXJzZWN0aW9uLnRhcmdldC5mb3IuZnVuY3Rpb25hbC5leHByPWxhbWJkYSBcdTYyMTZcdTY1QjlcdTZDRDVcdTVGMTVcdTc1MjhcdTc2ODRcdTRFQTRcdTUzQzlcdTdDN0JcdTU3OEJcdTc2RUVcdTY4MDdcdTk1MTlcdThCRUZcbnswfQoKIyAwOiBzeW1ib2wgb3IgdHlwZQpjb21waWxlci5taXNjLm5vdC5hbi5pbnRmLmNvbXBvbmVudD1cdTdFQzRcdTRFRjZcdTdDN0JcdTU3OEJ7MH1cdTRFMERcdTY2MkZcdTYzQTVcdTUzRTMKCiMgMDogc3ltYm9sIGtpbmQsIDE6IG1lc3NhZ2Ugc2VnbWVudApjb21waWxlci5lcnIuaW52YWxpZC5tcmVmPXswfVx1NUYxNVx1NzUyOFx1NjVFMFx1NjU0OFxuezF9CgojIDA6IHN5bWJvbCBraW5kLCAxOiBtZXNzYWdlIHNlZ21lbnQKY29tcGlsZXIubWlzYy5pbnZhbGlkLm1yZWY9ezB9XHU1RjE1XHU3NTI4XHU2NUUwXHU2NTQ4XG57MX0KCmNvbXBpbGVyLm1pc2Muc3RhdGljLm1yZWYud2l0aC50YXJncz1cdTY3MDlcdTUxNzNcdTk3NTlcdTYwMDFcdTY1QjlcdTZDRDVcdTVGMTVcdTc1MjhcdTc2ODRcdTUzQzJcdTY1NzBcdTUzMTZcdTk2NTBcdTVCOUFcdTdCMjYKCiMgMDogc3ltYm9sCmNvbXBpbGVyLmVyci5jYW50LmFzc2lnbi52YWwudG8uZmluYWwudmFyPVx1NjVFMFx1NkNENVx1NEUzQVx1NjcwMFx1N0VDOFx1NTNEOFx1OTFDRnswfVx1NTIwNlx1OTE0RFx1NTAzQwoKY29tcGlsZXIuZXJyLmNhbnQuYXNzaWduLnZhbC50by50aGlzPVx1NjVFMFx1NkNENVx1NTIwNlx1OTE0RFx1N0VEOSAnJ3RoaXMnJwoKIyAwOiBzeW1ib2wsIDE6IG1lc3NhZ2Ugc2VnbWVudApjb21waWxlci5lcnIuY2FudC5yZWYubm9uLmVmZmVjdGl2ZWx5LmZpbmFsLnZhcj1cdTRFQ0V7MX1cdTVGMTVcdTc1MjhcdTc2ODRcdTY3MkNcdTU3MzBcdTUzRDhcdTkxQ0ZcdTVGQzVcdTk4N0JcdTY2MkZcdTY3MDBcdTdFQzhcdTUzRDhcdTkxQ0ZcdTYyMTZcdTVCOUVcdTk2NDVcdTRFMEFcdTc2ODRcdTY3MDBcdTdFQzhcdTUzRDhcdTkxQ0YKCmNvbXBpbGVyLmVyci50cnkud2l0aC5yZXNvdXJjZXMuZXhwci5uZWVkcy52YXI9dHJ5LXdpdGgtcmVzb3VyY2VzIFx1OEQ0NFx1NkU5MFx1NUZDNVx1OTg3Qlx1NjYyRlx1NTNEOFx1OTFDRlx1NThGMFx1NjYwRSwgXHU2MjE2XHU4MDA1XHU2NjJGXHU2MzA3XHU3OTNBXHU1QkY5XHU2NzAwXHU3RUM4XHU1M0Q4XHU5MUNGXHU2MjE2XHU1QjlFXHU5NjQ1XHU0RTBBXHU3Njg0XHU2NzAwXHU3RUM4XHU1M0Q4XHU5MUNGXHU3Njg0XHU1RjE1XHU3NTI4XHU3Njg0XHU4ODY4XHU4RkJFXHU1RjBGCgojIDA6IHN5bWJvbApjb21waWxlci5lcnIudHJ5LndpdGgucmVzb3VyY2VzLmV4cHIuZWZmZWN0aXZlbHkuZmluYWwudmFyPVx1NzUyOFx1NEY1QyB0cnktd2l0aC1yZXNvdXJjZXMgXHU4RDQ0XHU2RTkwXHU3Njg0XHU1M0Q4XHU5MUNGIHswfSBcdTY1RTJcdTRFMERcdTY2MkZcdTY3MDBcdTdFQzhcdTUzRDhcdTkxQ0YsIFx1NEU1Rlx1NEUwRFx1NjYyRlx1NUI5RVx1OTY0NVx1NEUwQVx1NzY4NFx1NjcwMFx1N0VDOFx1NTNEOFx1OTFDRgoKCmNvbXBpbGVyLm1pc2MubGFtYmRhPWxhbWJkYSBcdTg4NjhcdThGQkVcdTVGMEYKCmNvbXBpbGVyLm1pc2MuaW5uZXIuY2xzPVx1NTE4NVx1OTBFOFx1N0M3QgoKIyAwOiB0eXBlCmNvbXBpbGVyLmVyci5jYW50LmRlcmVmPVx1NjVFMFx1NkNENVx1NTNENlx1NkQ4OFx1NUYxNVx1NzUyOHswfQoKY29tcGlsZXIuZXJyLmNhbnQuZXh0ZW5kLmludGYuYW5ub3RhdGlvbj1cdTVCRjlcdTRFOEUgQGludGVyZmFjZXMsIFx1NEUwRFx1NTE0MVx1OEJCOCAnJ2V4dGVuZHMnJwoKIyAwOiBzeW1ib2wKY29tcGlsZXIuZXJyLmNhbnQuaW5oZXJpdC5mcm9tLmZpbmFsPVx1NjVFMFx1NkNENVx1NEVDRVx1NjcwMFx1N0VDOHswfVx1OEZEQlx1ODg0Q1x1N0VFN1x1NjI3RgoKIyAwOiBzeW1ib2wKY29tcGlsZXIuZXJyLmNhbnQucmVmLmJlZm9yZS5jdG9yLmNhbGxlZD1cdTY1RTBcdTZDRDVcdTU3MjhcdThDMDNcdTc1MjhcdThEODVcdTdDN0JcdTU3OEJcdTY3ODRcdTkwMjBcdTU2NjhcdTRFNEJcdTUyNERcdTVGMTVcdTc1Mjh7MH0KCmNvbXBpbGVyLmVyci5jYW50LnNlbGVjdC5zdGF0aWMuY2xhc3MuZnJvbS5wYXJhbS50eXBlPVx1NjVFMFx1NkNENVx1NEVDRVx1NTNDMlx1NjU3MFx1NTMxNlx1NzY4NFx1N0M3Qlx1NTc4Qlx1NEUyRFx1OTAwOVx1NjJFOVx1OTc1OVx1NjAwMVx1N0M3QgoKIyAwOiBzeW1ib2wsIDE6IHN0cmluZywgMjogc3RyaW5nCmNvbXBpbGVyLmVyci5jYW50LmluaGVyaXQuZGlmZi5hcmc9XHU2NUUwXHU2Q0Q1XHU0RjdGXHU3NTI4XHU0RUU1XHU0RTBCXHU0RTBEXHU1NDBDXHU3Njg0XHU1M0MyXHU2NTcwXHU3RUU3XHU2MjdGezB9OiA8ezF9PiBcdTU0OEMgPHsyfT4KCmNvbXBpbGVyLmVyci5jYXRjaC53aXRob3V0LnRyeT1cdTY3MDkgJydjYXRjaCcnLCBcdTRGNDZcdTY2MkZcdTZDQTFcdTY3MDkgJyd0cnknJwoKIyAwOiBzeW1ib2wga2luZCwgMTogc3ltYm9sCmNvbXBpbGVyLmVyci5jbGFzaC53aXRoLnBrZy5vZi5zYW1lLm5hbWU9ezB9IHsxfVx1NEUwRVx1NUUyNlx1NjcwOVx1NzZGOFx1NTQwQ1x1NTQwRFx1NzlGMFx1NzY4NFx1N0EwQlx1NUU4Rlx1NTMwNVx1NTFCMlx1N0E4MQoKY29tcGlsZXIuZXJyLmNsYXNzLm5vdC5hbGxvd2VkPVx1NkI2NFx1NTkwNFx1NEUwRFx1NTE0MVx1OEJCOFx1NEY3Rlx1NzUyOFx1N0M3QiwgXHU2M0E1XHU1M0UzXHU2MjE2XHU2NzlBXHU0RTNFXHU1OEYwXHU2NjBFCgpjb21waWxlci5lcnIuY29uc3QuZXhwci5yZXE9XHU5NzAwXHU4OTgxXHU1RTM4XHU5MUNGXHU4ODY4XHU4RkJFXHU1RjBGCgpjb21waWxlci5lcnIuY29udC5vdXRzaWRlLmxvb3A9Y29udGludWUgXHU1NzI4IGxvb3AgXHU1OTE2XHU5MEU4CgojIDA6IHN5bWJvbApjb21waWxlci5lcnIuY3ljbGljLmluaGVyaXRhbmNlPVx1NkQ4OVx1NTNDQXswfVx1NzY4NFx1NUZBQVx1NzNBRlx1N0VFN1x1NjI3RgoKIyAwOiBzeW1ib2wKY29tcGlsZXIuZXJyLmN5Y2xpYy5hbm5vdGF0aW9uLmVsZW1lbnQ9XHU1MTQzXHU3RDIwIHswfSBcdTc2ODRcdTdDN0JcdTU3OEJcdTRFM0FcdTVGQUFcdTczQUYKCiMgMDogdW51c2VkCmNvbXBpbGVyLmVyci5jYWxsLnRvLnN1cGVyLm5vdC5hbGxvd2VkLmluLmVudW0uY3Rvcj1cdTU3MjhcdTY3OUFcdTRFM0VcdTY3ODRcdTkwMjBcdTU2NjhcdTRFMkRcdTRFMERcdTUxNDFcdThCQjhcdThDMDNcdTc1MjhcdThEODVcdTdDN0IKCiMgMDogdHlwZQpjb21waWxlci5lcnIubm8uc3VwZXJjbGFzcz17MH1cdTRFMERcdTUxNzdcdTY3MDlcdThEODVcdTdDN0JcdTMwMDIKCiMgMDogc3ltYm9sLCAxOiB0eXBlLCAyOiBzeW1ib2wsIDM6IHR5cGUsIDQ6IHVudXNlZApjb21waWxlci5lcnIuY29uY3JldGUuaW5oZXJpdGFuY2UuY29uZmxpY3Q9ezF9XHU0RTJEXHU3Njg0XHU2NUI5XHU2Q0Q1ezB9XHU1NDhDezN9XHU0RTJEXHU3Njg0XHU2NUI5XHU2Q0Q1ezJ9XHU2NjJGXHU0RjdGXHU3NTI4XHU3NkY4XHU1NDBDXHU3Njg0XHU3QjdFXHU1NDBEXHU3RUU3XHU2MjdGXHU3Njg0Cgpjb21waWxlci5lcnIuZGVmYXVsdC5hbGxvd2VkLmluLmludGYuYW5ub3RhdGlvbi5tZW1iZXI9XHU2Q0U4XHU5MUNBXHU3QzdCXHU1NzhCXHU1OEYwXHU2NjBFXHU0RTJEXHU0RUM1XHU1MTQxXHU4QkI4XHU5RUQ4XHU4QkE0XHU1MDNDCgojIDA6IHN5bWJvbApjb21waWxlci5lcnIuZG9lc250LmV4aXN0PVx1N0EwQlx1NUU4Rlx1NTMwNXswfVx1NEUwRFx1NUI1OFx1NTcyOAoKIyAwOiB0eXBlCmNvbXBpbGVyLmVyci5kdXBsaWNhdGUuYW5ub3RhdGlvbi5pbnZhbGlkLnJlcGVhdGVkPVx1NkNFOFx1OTFDQXswfVx1NEUwRFx1NjYyRlx1NjcwOVx1NjU0OFx1NzY4NFx1NTNFRlx1OTFDRFx1NTkwRFx1NkNFOFx1OTFDQQoKIyAwOiBuYW1lLCAxOiB0eXBlCmNvbXBpbGVyLmVyci5kdXBsaWNhdGUuYW5ub3RhdGlvbi5tZW1iZXIudmFsdWU9XHU2Q0U4XHU5MUNBQHsxfVx1NEUyRFx1NzY4NFx1NTE0M1x1N0QyMCAnJ3swfScnIFx1OTFDRFx1NTkwRFx1MzAwMgoKIyAwOiBuYW1lLCAxOiB1bnVzZWQKY29tcGlsZXIuZXJyLmR1cGxpY2F0ZS5hbm5vdGF0aW9uLm1pc3NpbmcuY29udGFpbmVyPXswfSBcdTRFMERcdTY2MkZcdTUzRUZcdTkxQ0RcdTU5MERcdTc2ODRcdTZDRThcdTkxQ0FcdTdDN0JcdTU3OEIKCiMgMDogdHlwZSwgMTogdW51c2VkCmNvbXBpbGVyLmVyci5pbnZhbGlkLnJlcGVhdGFibGUuYW5ub3RhdGlvbj1cdTZDRThcdTkxQ0FcdTkxQ0RcdTU5MEQ6IFx1NEY3Rlx1NzUyOFx1NjVFMFx1NjU0OFx1NzY4NCBAUmVwZWF0YWJsZSBcdTZDRThcdTkxQ0FcdTVCRjl7MH1cdThGREJcdTg4NENcdTRFODZcdTZDRThcdTkxQ0EKCiMgMDogc3ltYm9sIG9yIHR5cGUKY29tcGlsZXIuZXJyLmludmFsaWQucmVwZWF0YWJsZS5hbm5vdGF0aW9uLm5vLnZhbHVlPXswfVx1NEUwRFx1NjYyRlx1NjcwOVx1NjU0OFx1NzY4NCBAUmVwZWF0YWJsZSwgXHU2NzJBXHU1OEYwXHU2NjBFXHU0RUZCXHU0RjU1XHU1MDNDXHU1MTQzXHU3RDIwXHU2NUI5XHU2Q0Q1CgojIDA6IHR5cGUsIDE6IG51bWJlcgpjb21waWxlci5lcnIuaW52YWxpZC5yZXBlYXRhYmxlLmFubm90YXRpb24ubXVsdGlwbGUudmFsdWVzPXswfVx1NEUwRFx1NjYyRlx1NjcwOVx1NjU0OFx1NzY4NCBAUmVwZWF0YWJsZSwgXHU1REYyXHU1OEYwXHU2NjBFIHsxfSBcdTRFMkFcdTU0MERcdTRFM0EgJyd2YWx1ZScnIFx1NzY4NFx1NTE0M1x1N0QyMFx1NjVCOVx1NkNENQoKIyAwOiB0eXBlCmNvbXBpbGVyLmVyci5pbnZhbGlkLnJlcGVhdGFibGUuYW5ub3RhdGlvbi5pbnZhbGlkLnZhbHVlPXswfVx1NEUwRFx1NjYyRlx1NjcwOVx1NjU0OFx1NzY4NCBAUmVwZWF0YWJsZTogXHU1MDNDXHU1MTQzXHU3RDIwXHU2NUUwXHU2NTQ4CgojIDA6IHN5bWJvbCBvciB0eXBlLCAxOiB1bnVzZWQsIDI6IHR5cGUKY29tcGlsZXIuZXJyLmludmFsaWQucmVwZWF0YWJsZS5hbm5vdGF0aW9uLnZhbHVlLnJldHVybj1cdTUzMDVcdTU0MkJcdTZDRThcdTkxQ0FcdTdDN0JcdTU3OEIgKHswfSkgXHU1RkM1XHU5ODdCXHU1OEYwXHU2NjBFXHU3QzdCXHU1NzhCezJ9XHU3Njg0XHU1NDBEXHU0RTNBICcndmFsdWUnJyBcdTc2ODRcdTUxNDNcdTdEMjAKCiMgMDogc3ltYm9sIG9yIHR5cGUsIDE6IHN5bWJvbApjb21waWxlci5lcnIuaW52YWxpZC5yZXBlYXRhYmxlLmFubm90YXRpb24uZWxlbS5ub25kZWZhdWx0PVx1NUJGOVx1NEU4RVx1NTE0M1x1N0QyMCB7MX0sIFx1NTMwNVx1NTQyQlx1NkNFOFx1OTFDQVx1N0M3Qlx1NTc4QiAoezB9KSBcdTZDQTFcdTY3MDlcdTlFRDhcdThCQTRcdTUwM0MKCiMgMDogc3ltYm9sLCAxOiB1bnVzZWQsIDI6IHN5bWJvbCwgMzogdW51c2VkCmNvbXBpbGVyLmVyci5pbnZhbGlkLnJlcGVhdGFibGUuYW5ub3RhdGlvbi5yZXRlbnRpb249XHU1MzA1XHU1NDJCXHU2Q0U4XHU5MUNBXHU3QzdCXHU1NzhCICh7MH0pIFx1NzY4NFx1NEZERFx1NzU1OVx1NjcxRlx1NzdFRFx1NEU4RVx1NTNFRlx1OTFDRFx1NTkwRFx1NkNFOFx1OTFDQVx1N0M3Qlx1NTc4QiAoezJ9KSBcdTc2ODRcdTRGRERcdTc1NTlcdTY3MUYKCiMgMDogc3ltYm9sLCAxOiBzeW1ib2wKY29tcGlsZXIuZXJyLmludmFsaWQucmVwZWF0YWJsZS5hbm5vdGF0aW9uLm5vdC5kb2N1bWVudGVkPVx1NTNFRlx1OTFDRFx1NTkwRFx1NkNFOFx1OTFDQVx1N0M3Qlx1NTc4QiAoezF9KSBcdTY2MkYgQERvY3VtZW50ZWQsIFx1ODAwQ1x1NTMwNVx1NTQyQlx1NkNFOFx1OTFDQVx1N0M3Qlx1NTc4QiAoezB9KSBcdTUyMTlcdTRFMERcdTY2MkYKCiMgMDogc3ltYm9sLCAxOiBzeW1ib2wKY29tcGlsZXIuZXJyLmludmFsaWQucmVwZWF0YWJsZS5hbm5vdGF0aW9uLm5vdC5pbmhlcml0ZWQ9XHU1M0VGXHU5MUNEXHU1OTBEXHU2Q0U4XHU5MUNBXHU3QzdCXHU1NzhCICh7MX0pIFx1NjYyRiBASW5oZXJpdGVkLCBcdTgwMENcdTUzMDVcdTU0MkJcdTZDRThcdTkxQ0FcdTdDN0JcdTU3OEIgKHswfSkgXHU1MjE5XHU0RTBEXHU2NjJGCgojIDA6IHN5bWJvbCwgMTogc3ltYm9sCmNvbXBpbGVyLmVyci5pbnZhbGlkLnJlcGVhdGFibGUuYW5ub3RhdGlvbi5pbmNvbXBhdGlibGUudGFyZ2V0PVx1NTMwNVx1NTQyQlx1NkNFOFx1OTFDQVx1N0M3Qlx1NTc4QiAoezB9KSBcdTkwMDJcdTc1MjhcdTc2ODRcdTc2RUVcdTY4MDdcdTU5MUFcdTRFOEVcdTUzRUZcdTkxQ0RcdTU5MERcdTZDRThcdTkxQ0FcdTdDN0JcdTU3OEIgKHsxfSkKCiMgMDogc3ltYm9sCmNvbXBpbGVyLmVyci5pbnZhbGlkLnJlcGVhdGFibGUuYW5ub3RhdGlvbi5yZXBlYXRlZC5hbmQuY29udGFpbmVyLnByZXNlbnQ9XHU1QkI5XHU1NjY4IHswfSBcdTRFMERcdTVGOTdcdTRFMEVcdTUxNzZcdTUzMDVcdTU0MkJcdTc2ODRcdTUxNDNcdTdEMjBcdTU0MENcdTY1RjZcdTVCNThcdTU3MjgKCiMgMDogdHlwZSwgMTogc3ltYm9sCmNvbXBpbGVyLmVyci5pbnZhbGlkLnJlcGVhdGFibGUuYW5ub3RhdGlvbi5ub3QuYXBwbGljYWJsZT1cdTVCQjlcdTU2Njh7MH1cdTRFMERcdTkwMDJcdTc1MjhcdTRFOEVcdTUxNDNcdTdEMjAgezF9CgojIDA6IHR5cGUKY29tcGlsZXIuZXJyLmludmFsaWQucmVwZWF0YWJsZS5hbm5vdGF0aW9uLm5vdC5hcHBsaWNhYmxlLmluLmNvbnRleHQ9XHU1QkI5XHU1NjY4ezB9XHU1NzI4XHU2QjY0XHU3QzdCXHU1NzhCXHU0RTBBXHU0RTBCXHU2NTg3XHU0RTJEXHU0RTBEXHU5MDAyXHU3NTI4CgojIDA6IG5hbWUKY29tcGlsZXIuZXJyLmR1cGxpY2F0ZS5jbGFzcz1cdTdDN0JcdTkxQ0RcdTU5MEQ6IHswfQoKY29tcGlsZXIuZXJyLmR1cGxpY2F0ZS5jYXNlLmxhYmVsPWNhc2UgXHU2ODA3XHU3QjdFXHU5MUNEXHU1OTBECgpjb21waWxlci5lcnIuZHVwbGljYXRlLmRlZmF1bHQubGFiZWw9ZGVmYXVsdCBcdTY4MDdcdTdCN0VcdTkxQ0RcdTU5MEQKCmNvbXBpbGVyLmVyci5lbHNlLndpdGhvdXQuaWY9XHU2NzA5ICcnaWYnJywgXHU0RjQ2XHU2NjJGXHU2Q0ExXHU2NzA5ICcnZWxzZScnCgpjb21waWxlci5lcnIuZW1wdHkuY2hhci5saXQ9XHU3QTdBXHU1QjU3XHU3QjI2XHU2NTg3XHU1QjU3CgojIDA6IHN5bWJvbApjb21waWxlci5lcnIuZW5jbC5jbGFzcy5yZXF1aXJlZD1cdTk3MDBcdTg5ODFcdTUzMDVcdTU0MkJ7MH1cdTc2ODRcdTVDMDFcdTk1RURcdTVCOUVcdTRGOEIKCmNvbXBpbGVyLmVyci5lbnVtLmFubm90YXRpb24ubXVzdC5iZS5lbnVtLmNvbnN0YW50PVx1Njc5QVx1NEUzRVx1NkNFOFx1OTFDQVx1NTAzQ1x1NUZDNVx1OTg3Qlx1NjYyRlx1Njc5QVx1NEUzRVx1NUUzOFx1OTFDRgoKY29tcGlsZXIuZXJyLmVudW0uY2FudC5iZS5pbnN0YW50aWF0ZWQ9XHU2NUUwXHU2Q0Q1XHU1QjlFXHU0RjhCXHU1MzE2XHU2NzlBXHU0RTNFXHU3QzdCXHU1NzhCCgpjb21waWxlci5lcnIuZW51bS5sYWJlbC5tdXN0LmJlLnVucXVhbGlmaWVkLmVudW09XHU2NzlBXHU0RTNFIHN3aXRjaCBjYXNlIFx1NjgwN1x1N0I3RVx1NUZDNVx1OTg3Qlx1NEUzQVx1Njc5QVx1NEUzRVx1NUUzOFx1OTFDRlx1NzY4NFx1OTc1RVx1OTY1MFx1NUI5QVx1NTQwRFx1NzlGMAoKY29tcGlsZXIuZXJyLmVudW0ubm8uc3ViY2xhc3Npbmc9XHU3QzdCXHU2NUUwXHU2Q0Q1XHU3NkY0XHU2M0E1XHU2MjY5XHU1QzU1IGphdmEubGFuZy5FbnVtCgpjb21waWxlci5lcnIuZW51bS50eXBlcy5ub3QuZXh0ZW5zaWJsZT1cdTY3OUFcdTRFM0VcdTdDN0JcdTU3OEJcdTRFMERcdTUzRUZcdTdFRTdcdTYyN0YKCmNvbXBpbGVyLmVyci5lbnVtLm5vLmZpbmFsaXplPVx1Njc5QVx1NEUzRVx1NEUwRFx1ODBGRFx1NjcwOSBmaW5hbGl6ZSBcdTY1QjlcdTZDRDUKCiMgMDogZmlsZSBuYW1lLCAxOiBzdHJpbmcKY29tcGlsZXIuZXJyLmVycm9yLnJlYWRpbmcuZmlsZT1cdThCRkJcdTUzRDZ7MH1cdTY1RjZcdTUxRkFcdTk1MTk7IHsxfQoKIyAwOiB0eXBlCmNvbXBpbGVyLmVyci5leGNlcHQuYWxyZWFkeS5jYXVnaHQ9XHU1REYyXHU2MzU1XHU4M0I3XHU1MjMwXHU1RjAyXHU1RTM4XHU5NTE5XHU4QkVGezB9CgojIDA6IHR5cGUKY29tcGlsZXIuZXJyLmV4Y2VwdC5uZXZlci50aHJvd24uaW4udHJ5PVx1NTcyOFx1NzZGOFx1NUU5NFx1NzY4NCB0cnkgXHU4QkVEXHU1M0U1XHU0RTNCXHU0RjUzXHU0RTJEXHU0RTBEXHU4MEZEXHU2MjlCXHU1MUZBXHU1RjAyXHU1RTM4XHU5NTE5XHU4QkVGezB9CgojIDA6IHN5bWJvbApjb21waWxlci5lcnIuZmluYWwucGFyYW1ldGVyLm1heS5ub3QuYmUuYXNzaWduZWQ9XHU0RTBEXHU4MEZEXHU1MjA2XHU5MTREXHU2NzAwXHU3RUM4XHU1M0MyXHU2NTcwezB9CgojIDA6IHN5bWJvbApjb21waWxlci5lcnIudHJ5LnJlc291cmNlLm1heS5ub3QuYmUuYXNzaWduZWQ9XHU1M0VGXHU4MEZEXHU2NzJBXHU1MjA2XHU5MTREXHU1M0VGXHU4MUVBXHU1MkE4XHU1MTczXHU5NUVEXHU3Njg0XHU4RDQ0XHU2RTkwezB9CgojIDA6IHN5bWJvbApjb21waWxlci5lcnIubXVsdGljYXRjaC5wYXJhbWV0ZXIubWF5Lm5vdC5iZS5hc3NpZ25lZD1cdTUzRUZcdTgwRkRcdTY3MkFcdTUyMDZcdTkxNEQgbXVsdGktY2F0Y2ggXHU1M0MyXHU2NTcwezB9CgojIDA6IHR5cGUsIDE6IHR5cGUKY29tcGlsZXIuZXJyLm11bHRpY2F0Y2gudHlwZXMubXVzdC5iZS5kaXNqb2ludD1tdWx0aS1jYXRjaCBcdThCRURcdTUzRTVcdTRFMkRcdTc2ODRcdTY2RkZcdTRFRTNcdTY1RTBcdTZDRDVcdTkwMUFcdThGQzdcdTVCNTBcdTdDN0JcdTUzMTZcdTUxNzNcdTgwNTRcblx1NjZGRlx1NEVFM3swfVx1NjYyRlx1NjZGRlx1NEVFM3sxfVx1NzY4NFx1NUI1MFx1N0M3QgoKY29tcGlsZXIuZXJyLmZpbmFsbHkud2l0aG91dC50cnk9XHU2NzA5ICcnZmluYWxseScnLCBcdTRGNDZcdTY2MkZcdTZDQTFcdTY3MDkgJyd0cnknJwoKIyAwOiB0eXBlLCAxOiBtZXNzYWdlIHNlZ21lbnQKY29tcGlsZXIuZXJyLmZvcmVhY2gubm90LmFwcGxpY2FibGUudG8udHlwZT1mb3ItZWFjaCBcdTRFMERcdTkwMDJcdTc1MjhcdTRFOEVcdTg4NjhcdThGQkVcdTVGMEZcdTdDN0JcdTU3OEJcblx1ODk4MVx1NkM0MjogezF9XG5cdTYyN0VcdTUyMzA6ICAgIHswfQoKY29tcGlsZXIuZXJyLmZwLm51bWJlci50b28ubGFyZ2U9XHU2RDZFXHU3MEI5XHU2NTcwXHU4RkM3XHU1OTI3Cgpjb21waWxlci5lcnIuZnAubnVtYmVyLnRvby5zbWFsbD1cdTZENkVcdTcwQjlcdTY1NzBcdThGQzdcdTVDMEYKCmNvbXBpbGVyLmVyci5nZW5lcmljLmFycmF5LmNyZWF0aW9uPVx1NTIxQlx1NUVGQVx1NkNEQlx1NTc4Qlx1NjU3MFx1N0VDNAoKY29tcGlsZXIuZXJyLmdlbmVyaWMudGhyb3dhYmxlPVx1NkNEQlx1NTc4Qlx1N0M3Qlx1NEUwRFx1ODBGRFx1NjI2OVx1NUM1NSBqYXZhLmxhbmcuVGhyb3dhYmxlCgojIDA6IHN5bWJvbApjb21waWxlci5lcnIuaWNscy5jYW50LmhhdmUuc3RhdGljLmRlY2w9XHU1MTg1XHU5MEU4XHU3QzdCezB9XHU0RTJEXHU3Njg0XHU5NzU5XHU2MDAxXHU1OEYwXHU2NjBFXHU5NzVFXHU2Q0Q1XG5cdTRGRUVcdTk5NzBcdTdCMjYgJydzdGF0aWMnJyBcdTRFQzVcdTUxNDFcdThCQjhcdTU3MjhcdTVFMzhcdTkxQ0ZcdTUzRDhcdTkxQ0ZcdTU4RjBcdTY2MEVcdTRFMkRcdTRGN0ZcdTc1MjgKCiMgMDogc3RyaW5nCmNvbXBpbGVyLmVyci5pbGxlZ2FsLmNoYXI9XHU5NzVFXHU2Q0Q1XHU1QjU3XHU3QjI2OiAnJ3swfScnCgojIDA6IHN0cmluZywgMTogc3RyaW5nCmNvbXBpbGVyLmVyci5pbGxlZ2FsLmNoYXIuZm9yLmVuY29kaW5nPVx1N0YxNlx1NzgwMSB7MX0gXHU3Njg0XHU0RTBEXHU1M0VGXHU2NjIwXHU1QzA0XHU1QjU3XHU3QjI2ICgweHswfSkKCiMgMDogc2V0IG9mIG1vZGlmaWVyLCAxOiBzZXQgb2YgbW9kaWZpZXIKY29tcGlsZXIuZXJyLmlsbGVnYWwuY29tYmluYXRpb24ub2YubW9kaWZpZXJzPVx1OTc1RVx1NkNENVx1NzY4NFx1NEZFRVx1OTk3MFx1N0IyNlx1N0VDNFx1NTQwODogezB9XHU1NDhDezF9Cgpjb21waWxlci5lcnIuaWxsZWdhbC5lbnVtLnN0YXRpYy5yZWY9XHU1MjFEXHU1OUNCXHU1MzE2XHU3QTBCXHU1RThGXHU0RTJEXHU1QkY5XHU5NzU5XHU2MDAxXHU1QjU3XHU2QkI1XHU3Njg0XHU1RjE1XHU3NTI4XHU0RTBEXHU1NDA4XHU2Q0Q1Cgpjb21waWxlci5lcnIuaWxsZWdhbC5lc2MuY2hhcj1cdTk3NUVcdTZDRDVcdThGNkNcdTRFNDlcdTdCMjYKCmNvbXBpbGVyLmVyci5pbGxlZ2FsLmZvcndhcmQucmVmPVx1OTc1RVx1NkNENVx1NTI0RFx1NTQxMVx1NUYxNVx1NzUyOAoKIyAwOiBzeW1ib2wsIDE6IHN0cmluZwpjb21waWxlci5lcnIubm90LmluLnByb2ZpbGU9ezB9XHU1NzI4XHU5MTREXHU3RjZFXHU2NTg3XHU0RUY2ICcnezF9JycgXHU0RTJEXHU0RTBEXHU1M0VGXHU3NTI4CgojIDA6IHN5bWJvbApjb21waWxlci53YXJuLmZvcndhcmQucmVmPVx1NTE0OFx1NUYxNVx1NzUyOFx1NTNEOFx1OTFDRiAnJ3swfScnLCBcdTcxMzZcdTU0MEVcdTUxOERcdTVCRjlcdTUxNzZcdTUyMURcdTU5Q0JcdTUzMTYKCmNvbXBpbGVyLmVyci5pbGxlZ2FsLnNlbGYucmVmPVx1NTIxRFx1NTlDQlx1NTMxNlx1N0EwQlx1NUU4Rlx1NEUyRFx1NUI1OFx1NTcyOFx1ODFFQVx1NUYxNVx1NzUyOAoKIyAwOiBzeW1ib2wKY29tcGlsZXIud2Fybi5zZWxmLnJlZj1cdTUzRDhcdTkxQ0YgJyd7MH0nJyBcdTc2ODRcdTUyMURcdTU5Q0JcdTUzMTZcdTdBMEJcdTVFOEZcdTRFMkRcdTVCNThcdTU3MjhcdTgxRUFcdTVGMTVcdTc1MjgKCmNvbXBpbGVyLmVyci5pbGxlZ2FsLmdlbmVyaWMudHlwZS5mb3IuaW5zdG9mPWluc3RhbmNlb2YgXHU3Njg0XHU2Q0RCXHU1NzhCXHU3QzdCXHU1NzhCXHU0RTBEXHU1NDA4XHU2Q0Q1CgojIDA6IHR5cGUKY29tcGlsZXIuZXJyLmlsbGVnYWwuaW5pdGlhbGl6ZXIuZm9yLnR5cGU9ezB9XHU3Njg0XHU1MjFEXHU1OUNCXHU1MzE2XHU3QTBCXHU1RThGXHU0RTBEXHU1NDA4XHU2Q0Q1Cgpjb21waWxlci5lcnIuaWxsZWdhbC5saW5lLmVuZC5pbi5jaGFyLmxpdD1cdTVCNTdcdTdCMjZcdTY1ODdcdTVCNTdcdTc2ODRcdTg4NENcdTdFRDNcdTVDM0VcdTRFMERcdTU0MDhcdTZDRDUKCmNvbXBpbGVyLmVyci5pbGxlZ2FsLm5vbmFzY2lpLmRpZ2l0PVx1OTc1RVx1NkNENVx1NzY4NFx1OTc1RSBBU0NJSSBcdTY1NzBcdTVCNTcKCmNvbXBpbGVyLmVyci5pbGxlZ2FsLnVuZGVyc2NvcmU9XHU5NzVFXHU2Q0Q1XHU0RTBCXHU1MjEyXHU3RUJGCgpjb21waWxlci5lcnIuaWxsZWdhbC5kb3Q9XHU5NzVFXHU2Q0Q1ICcnLicnCgojIDA6IHN5bWJvbApjb21waWxlci5lcnIuaWxsZWdhbC5xdWFsLm5vdC5pY2xzPVx1OTc1RVx1NkNENVx1OTY1MFx1NUI5QVx1N0IyNjsgezB9XHU0RTBEXHU2NjJGXHU1MTg1XHU5MEU4XHU3QzdCCgpjb21waWxlci5lcnIuaWxsZWdhbC5zdGFydC5vZi5leHByPVx1OTc1RVx1NkNENVx1NzY4NFx1ODg2OFx1OEZCRVx1NUYwRlx1NUYwMFx1NTlDQgoKY29tcGlsZXIuZXJyLmlsbGVnYWwuc3RhcnQub2Yuc3RtdD1cdTk3NUVcdTZDRDVcdTc2ODRcdThCRURcdTUzRTVcdTVGMDBcdTU5Q0IKCmNvbXBpbGVyLmVyci5pbGxlZ2FsLnN0YXJ0Lm9mLnR5cGU9XHU5NzVFXHU2Q0Q1XHU3Njg0XHU3QzdCXHU1NzhCXHU1RjAwXHU1OUNCCgpjb21waWxlci5lcnIuaWxsZWdhbC51bmljb2RlLmVzYz1cdTk3NUVcdTZDRDVcdTc2ODQgVW5pY29kZSBcdThGNkNcdTRFNDkKCiMgMDogc3ltYm9sCmNvbXBpbGVyLmVyci5pbXBvcnQucmVxdWlyZXMuY2Fub25pY2FsPVx1NUJGQ1x1NTE2NVx1OTcwMFx1ODk4MXswfVx1NzY4NFx1ODlDNFx1ODMwM1x1NTQwRFx1NzlGMAoKY29tcGlsZXIuZXJyLmltcHJvcGVybHkuZm9ybWVkLnR5cGUucGFyYW0ubWlzc2luZz1cdTdDN0JcdTU3OEJcdTc2ODRcdTY4M0NcdTVGMEZcdTRFMERcdTZCNjNcdTc4NkUsIFx1N0YzQVx1NUMxMVx1NjdEMFx1NEU5Qlx1NTNDMlx1NjU3MAoKY29tcGlsZXIuZXJyLmltcHJvcGVybHkuZm9ybWVkLnR5cGUuaW5uZXIucmF3LnBhcmFtPVx1N0M3Qlx1NTc4Qlx1NzY4NFx1NjgzQ1x1NUYwRlx1NEUwRFx1NkI2M1x1Nzg2RSwgXHU3RUQ5XHU1MUZBXHU0RTg2XHU1MzlGXHU1OUNCXHU3QzdCXHU1NzhCXHU3Njg0XHU3QzdCXHU1NzhCXHU1M0MyXHU2NTcwCgojIDA6IHR5cGUsIDE6IHR5cGUKY29tcGlsZXIuZXJyLmluY29tcGFyYWJsZS50eXBlcz1cdTRFMERcdTUzRUZcdTZCRDRcdThGODNcdTc2ODRcdTdDN0JcdTU3OEI6IHswfVx1NTQ4Q3sxfQoKIyAwOiBudW1iZXIKY29tcGlsZXIuZXJyLmludC5udW1iZXIudG9vLmxhcmdlPVx1OEZDN1x1NTkyN1x1NzY4NFx1NjU3NFx1NjU3MDogezB9Cgpjb21waWxlci5lcnIuaW50Zi5hbm5vdGF0aW9uLm1lbWJlcnMuY2FudC5oYXZlLnBhcmFtcz1cdTZDRThcdTkxQ0FcdTdDN0JcdTU3OEJcdTU4RjBcdTY2MEVcdTRFMkRcdTc2ODRcdTUxNDNcdTdEMjBcdTY1RTBcdTZDRDVcdTU4RjBcdTY2MEVcdTVGNjJcdTUzQzIKCiMgMDogc3ltYm9sCmNvbXBpbGVyLmVyci5pbnRmLmFubm90YXRpb24uY2FudC5oYXZlLnR5cGUucGFyYW1zPVx1NkNFOFx1OTFDQVx1N0M3Qlx1NTc4QiB7MH0gXHU0RTBEXHU4MEZEXHU0RTNBXHU2Q0RCXHU1NzhCCgpjb21waWxlci5lcnIuaW50Zi5hbm5vdGF0aW9uLm1lbWJlcnMuY2FudC5oYXZlLnR5cGUucGFyYW1zPVx1NkNFOFx1OTFDQVx1N0M3Qlx1NTc4Qlx1NThGMFx1NjYwRVx1NEUyRFx1NzY4NFx1NTE0M1x1N0QyMFx1NEUwRFx1ODBGRFx1NEUzQVx1NkNEQlx1NTc4Qlx1NjVCOVx1NkNENQoKIyAwOiBzeW1ib2wsIDE6IHR5cGUKY29tcGlsZXIuZXJyLmludGYuYW5ub3RhdGlvbi5tZW1iZXIuY2xhc2g9XHU2Q0U4XHU5MUNBXHU3QzdCXHU1NzhCezF9XHU1OEYwXHU2NjBFXHU0RTBFXHU2NUI5XHU2Q0Q1IHswfSBcdTU0MENcdTU0MERcdTc2ODRcdTUxNDNcdTdEMjAKCmNvbXBpbGVyLmVyci5pbnRmLmV4cGVjdGVkLmhlcmU9XHU2QjY0XHU1OTA0XHU5NzAwXHU4OTgxXHU2M0E1XHU1M0UzCgpjb21waWxlci5lcnIuaW50Zi5tZXRoLmNhbnQuaGF2ZS5ib2R5PVx1NjNBNVx1NTNFM1x1NjJCRFx1OEM2MVx1NjVCOVx1NkNENVx1NEUwRFx1ODBGRFx1NUUyNlx1NjcwOVx1NEUzQlx1NEY1MwoKIyAwOiBzeW1ib2wKY29tcGlsZXIuZXJyLmludmFsaWQuYW5ub3RhdGlvbi5tZW1iZXIudHlwZT1cdTZDRThcdTkxQ0FcdTdDN0JcdTU3OEJcdTUxNDNcdTdEMjAgezB9IFx1NzY4NFx1N0M3Qlx1NTc4Qlx1NjVFMFx1NjU0OAoKY29tcGlsZXIuZXJyLmludmFsaWQuYmluYXJ5Lm51bWJlcj1cdTRFOENcdThGREJcdTUyMzZcdTY1NzBcdTVCNTdcdTRFMkRcdTVGQzVcdTk4N0JcdTUzMDVcdTU0MkJcdTgxRjNcdTVDMTFcdTRFMDBcdTRFMkFcdTRFOENcdThGREJcdTUyMzZcdTY1NzAKCmNvbXBpbGVyLmVyci5pbnZhbGlkLmhleC5udW1iZXI9XHU1MzQxXHU1MTZEXHU4RkRCXHU1MjM2XHU2NTcwXHU1QjU3XHU1RkM1XHU5ODdCXHU1MzA1XHU1NDJCXHU4MUYzXHU1QzExXHU0RTAwXHU0RjREXHU1MzQxXHU1MTZEXHU4RkRCXHU1MjM2XHU2NTcwCgpjb21waWxlci5lcnIuaW52YWxpZC5tZXRoLmRlY2wucmV0LnR5cGUucmVxPVx1NjVCOVx1NkNENVx1NThGMFx1NjYwRVx1NjVFMFx1NjU0ODsgXHU5NzAwXHU4OTgxXHU4RkQ0XHU1NkRFXHU3QzdCXHU1NzhCCgpjb21waWxlci5lcnIudmFyYXJncy5hbmQub2xkLmFycmF5LnN5bnRheD12YXJpYWJsZS1hcml0eSBcdTUzQzJcdTY1NzBcdTRFMkRcdTRFMERcdTUxNDFcdThCQjhcdTRGN0ZcdTc1MjhcdTRGMjBcdTdFREZcdTY1NzBcdTdFQzRcdThCQjBcdTUzRjcKCmNvbXBpbGVyLmVyci52YXJhcmdzLmFuZC5yZWNlaXZlciA9XHU2M0E1XHU2NTM2XHU2NUI5XHU1M0MyXHU2NTcwXHU0RTBEXHU1MTQxXHU4QkI4XHU0RjdGXHU3NTI4IHZhcmFyZ3MgXHU4QkIwXHU1M0Y3Cgpjb21waWxlci5lcnIudmFyYXJncy5tdXN0LmJlLmxhc3QgPXZhcmFyZ3MgXHU1M0MyXHU2NTcwXHU1RkM1XHU5ODdCXHU2NjJGXHU2NzAwXHU1NDBFXHU0RTAwXHU0RTJBXHU1M0MyXHU2NTcwCgpjb21waWxlci5lcnIuYXJyYXkuYW5kLnJlY2VpdmVyID1cdTYzQTVcdTY1MzZcdTY1QjlcdTUzQzJcdTY1NzBcdTRFMERcdTUxNDFcdThCQjhcdTRGN0ZcdTc1MjhcdTRGMjBcdTdFREZcdTY1NzBcdTdFQzRcdThCQjBcdTUzRjcKCmNvbXBpbGVyLmVyci52YXJpYWJsZS5ub3QuYWxsb3dlZD1cdTZCNjRcdTU5MDRcdTRFMERcdTUxNDFcdThCQjhcdTRGN0ZcdTc1MjhcdTUzRDhcdTkxQ0ZcdTU4RjBcdTY2MEUKCiMgMDogbmFtZQpjb21waWxlci5lcnIubGFiZWwuYWxyZWFkeS5pbi51c2U9XHU2ODA3XHU3QjdFezB9XHU1REYyXHU0RjdGXHU3NTI4CgojIDA6IHN5bWJvbApjb21waWxlci5lcnIubG9jYWwudmFyLmFjY2Vzc2VkLmZyb20uaWNscy5uZWVkcy5maW5hbD1cdTRFQ0VcdTUxODVcdTkwRThcdTdDN0JcdTRFMkRcdThCQkZcdTk1RUVcdTY3MkNcdTU3MzBcdTUzRDhcdTkxQ0Z7MH07IFx1OTcwMFx1ODk4MVx1ODhBQlx1NThGMFx1NjYwRVx1NEUzQVx1NjcwMFx1N0VDOFx1N0M3Qlx1NTc4QgoKY29tcGlsZXIuZXJyLmxvY2FsLmVudW09XHU2NzlBXHU0RTNFXHU3QzdCXHU1NzhCXHU0RTBEXHU4MEZEXHU0RTNBXHU2NzJDXHU1NzMwXHU3QzdCXHU1NzhCCgpjb21waWxlci5lcnIuY2Fubm90LmNyZWF0ZS5hcnJheS53aXRoLnR5cGUuYXJndW1lbnRzPVx1NjVFMFx1NkNENVx1NTIxQlx1NUVGQVx1NTE3N1x1NjcwOVx1N0M3Qlx1NTc4Qlx1NTNEOFx1OTFDRlx1NzY4NFx1NjU3MFx1N0VDNAoKY29tcGlsZXIuZXJyLmNhbm5vdC5jcmVhdGUuYXJyYXkud2l0aC5kaWFtb25kPVx1NjVFMFx1NkNENVx1NTIxQlx1NUVGQVx1NTE3N1x1NjcwOSAnJzw+JycgXHU3Njg0XHU2NTcwXHU3RUM0Cgpjb21waWxlci5lcnIuaW52YWxpZC5tb2R1bGUuZGlyZWN0aXZlPVx1OTg4NFx1NjcxRlx1NEUzQVx1NkEyMVx1NTc1N1x1NjMwN1x1NEVFNFx1NTE3M1x1OTUyRVx1NUI1N1x1NjIxNiAnJ30nJwoKIwojIGxpbWl0cy4gIFdlIGRvbid0IGdpdmUgdGhlIGxpbWl0cyBpbiB0aGUgZGlhZ25vc3RpYyBiZWNhdXNlIHdlIGV4cGVjdAojIHRoZW0gdG8gY2hhbmdlLCB5ZXQgd2Ugd2FudCB0byB1c2UgdGhlIHNhbWUgZGlhZ25vc3RpYy4gIFRoZXNlIGFyZSBhbGwKIyBkZXRlY3RlZCBkdXJpbmcgY29kZSBnZW5lcmF0aW9uLgojCmNvbXBpbGVyLmVyci5saW1pdC5jb2RlPVx1NEVFM1x1NzgwMVx1OEZDN1x1OTU3RgoKY29tcGlsZXIuZXJyLmxpbWl0LmNvZGUudG9vLmxhcmdlLmZvci50cnkuc3RtdD10cnkgXHU4QkVEXHU1M0U1XHU3Njg0XHU0RUUzXHU3ODAxXHU4RkM3XHU5NTdGCgpjb21waWxlci5lcnIubGltaXQuZGltZW5zaW9ucz1cdTY1NzBcdTdFQzRcdTdDN0JcdTU3OEJcdTdFRjRcdThGQzdcdTU5MUEKCmNvbXBpbGVyLmVyci5saW1pdC5sb2NhbHM9XHU2NzJDXHU1NzMwXHU1M0Q4XHU5MUNGXHU4RkM3XHU1OTFBCgpjb21waWxlci5lcnIubGltaXQucGFyYW1ldGVycz1cdTUzQzJcdTY1NzBcdThGQzdcdTU5MUEKCmNvbXBpbGVyLmVyci5saW1pdC5wb29sPVx1NUUzOFx1OTFDRlx1OEZDN1x1NTkxQQoKY29tcGlsZXIuZXJyLmxpbWl0LnBvb2wuaW4uY2xhc3M9XHU3QzdCezB9XHU0RTJEXHU3Njg0XHU1RTM4XHU5MUNGXHU4RkM3XHU1OTFBCgpjb21waWxlci5lcnIubGltaXQuc3RhY2s9XHU0RUUzXHU3ODAxXHU5NzAwXHU4OTgxXHU4RkM3XHU1OTFBXHU1ODA2XHU2ODA4Cgpjb21waWxlci5lcnIubGltaXQuc3RyaW5nPVx1NUUzOFx1OTFDRlx1NUI1N1x1N0IyNlx1NEUzMlx1OEZDN1x1OTU3RgoKY29tcGlsZXIuZXJyLmxpbWl0LnN0cmluZy5vdmVyZmxvdz1cdTVCRjlcdTRFOEVcdTVFMzhcdTkxQ0ZcdTZDNjBcdTY3NjVcdThCRjQsIFx1NUI1N1x1N0IyNlx1NEUzMiAiezB9Li4uIiBcdTc2ODQgVVRGOCBcdTg4NjhcdTc5M0FcdThGQzdcdTk1N0YKCmNvbXBpbGVyLmVyci5tYWxmb3JtZWQuZnAubGl0PVx1NkQ2RVx1NzBCOVx1NjU4N1x1NUI1N1x1NzY4NFx1NjgzQ1x1NUYwRlx1OTUxOVx1OEJFRgoKY29tcGlsZXIuZXJyLm1ldGhvZC5kb2VzLm5vdC5vdmVycmlkZS5zdXBlcmNsYXNzPVx1NjVCOVx1NkNENVx1NEUwRFx1NEYxQVx1ODk4Nlx1NzZENlx1NjIxNlx1NUI5RVx1NzNCMFx1OEQ4NVx1N0M3Qlx1NTc4Qlx1NzY4NFx1NjVCOVx1NkNENQoKY29tcGlsZXIuZXJyLm1pc3NpbmcubWV0aC5ib2R5Lm9yLmRlY2wuYWJzdHJhY3Q9XHU3RjNBXHU1QzExXHU2NUI5XHU2Q0Q1XHU0RTNCXHU0RjUzLCBcdTYyMTZcdTU4RjBcdTY2MEVcdTYyQkRcdThDNjEKCmNvbXBpbGVyLmVyci5taXNzaW5nLnJldC5zdG10PVx1N0YzQVx1NUMxMVx1OEZENFx1NTZERVx1OEJFRFx1NTNFNQoKIyAwOiB1bnVzZWQKY29tcGlsZXIubWlzYy5taXNzaW5nLnJldC52YWw9XHU3RjNBXHU1QzExXHU4RkQ0XHU1NkRFXHU1MDNDCgpjb21waWxlci5taXNjLnVuZXhwZWN0ZWQucmV0LnZhbD1cdTYxMEZcdTU5MTZcdTc2ODRcdThGRDRcdTU2REVcdTUwM0MKCiMgMDogc2V0IG9mIG1vZGlmaWVyCmNvbXBpbGVyLmVyci5tb2Qubm90LmFsbG93ZWQuaGVyZT1cdTZCNjRcdTU5MDRcdTRFMERcdTUxNDFcdThCQjhcdTRGN0ZcdTc1MjhcdTRGRUVcdTk5NzBcdTdCMjZ7MH0KCmNvbXBpbGVyLmVyci5pbnRmLm5vdC5hbGxvd2VkLmhlcmU9XHU2QjY0XHU1OTA0XHU0RTBEXHU1MTQxXHU4QkI4XHU0RjdGXHU3NTI4XHU2M0E1XHU1M0UzCgpjb21waWxlci5lcnIuZW51bXMubXVzdC5iZS5zdGF0aWM9XHU1M0VBXHU2NzA5XHU1NzI4XHU5NzU5XHU2MDAxXHU0RTBBXHU0RTBCXHU2NTg3XHU0RTJEXHU2MjREXHU1MTQxXHU4QkI4XHU0RjdGXHU3NTI4XHU2NzlBXHU0RTNFXHU1OEYwXHU2NjBFCgojIDA6IHN5bWJvbCwgMTogc3ltYm9sCmNvbXBpbGVyLmVyci5uYW1lLmNsYXNoLnNhbWUuZXJhc3VyZT1cdTU0MERcdTc5RjBcdTUxQjJcdTdBODE6IHswfVx1NTQ4Q3sxfVx1NTE3N1x1NjcwOVx1NzZGOFx1NTQwQ1x1NzU5MVx1N0IyNgoKIyAwOiBzeW1ib2wsIDE6IHN5bWJvbCwgMjogc3ltYm9sLCAzOiBzeW1ib2wsIDQ6IHVudXNlZCwgNTogdW51c2VkCmNvbXBpbGVyLmVyci5uYW1lLmNsYXNoLnNhbWUuZXJhc3VyZS5uby5vdmVycmlkZT1cdTU0MERcdTc5RjBcdTUxQjJcdTdBODE6IHsxfVx1NEUyRFx1NzY4NHswfVx1NTQ4Q3szfVx1NEUyRFx1NzY4NHsyfVx1NTE3N1x1NjcwOVx1NzZGOFx1NTQwQ1x1NzU5MVx1N0IyNiwgXHU0RjQ2XHU0RTI0XHU4MDA1XHU1NzQ3XHU0RTBEXHU4OTg2XHU3NkQ2XHU1QkY5XHU2NUI5CgojIDA6IHN5bWJvbCwgMTogc3ltYm9sLCAyOiBzeW1ib2wsIDM6IHN5bWJvbCwgNDogc3ltYm9sLCA1OiBzeW1ib2wKY29tcGlsZXIuZXJyLm5hbWUuY2xhc2guc2FtZS5lcmFzdXJlLm5vLm92ZXJyaWRlLjE9XHU1NDBEXHU3OUYwXHU1MUIyXHU3QTgxOiB7MX0gXHU0RTJEXHU3Njg0IHswfSBcdTg5ODZcdTc2RDZcdTc2ODRcdTY1QjlcdTZDRDVcdTc2ODRcdTc1OTFcdTdCMjZcdTRFMEVcdTUzRTZcdTRFMDBcdTRFMkFcdTY1QjlcdTZDRDVcdTc2ODRcdTc2RjhcdTU0MEMsIFx1NEY0Nlx1NEUyNFx1ODAwNVx1NTc0N1x1NEUwRFx1ODk4Nlx1NzZENlx1NUJGOVx1NjVCOVxuXHU3QjJDXHU0RTAwXHU0RTJBXHU2NUI5XHU2Q0Q1OiAgezN9IFx1NEUyRFx1NzY4NCB7Mn1cblx1N0IyQ1x1NEU4Q1x1NEUyQVx1NjVCOVx1NkNENTogezV9IFx1NEUyRFx1NzY4NCB7NH0KCiMgMDogc3ltYm9sLCAxOiBzeW1ib2wsIDI6IHN5bWJvbCwgMzogc3ltYm9sCmNvbXBpbGVyLmVyci5uYW1lLmNsYXNoLnNhbWUuZXJhc3VyZS5uby5oaWRlPVx1NTQwRFx1NzlGMFx1NTFCMlx1N0E4MTogezF9IFx1NEUyRFx1NzY4NCB7MH0gXHU1NDhDIHszfSBcdTRFMkRcdTc2ODQgezJ9IFx1NTE3N1x1NjcwOVx1NzZGOFx1NTQwQ1x1NzU5MVx1N0IyNiwgXHU0RjQ2XHU0RTI0XHU4MDA1XHU1NzQ3XHU0RTBEXHU5NjkwXHU4NUNGXHU1QkY5XHU2NUI5Cgpjb21waWxlci5lcnIubmFtZS5yZXNlcnZlZC5mb3IuaW50ZXJuYWwudXNlPXswfVx1NEUzQVx1NTE4NVx1OTBFOFx1NEY3Rlx1NzUyOFx1NEZERFx1NzU1OQoKY29tcGlsZXIuZXJyLm5hdGl2ZS5tZXRoLmNhbnQuaGF2ZS5ib2R5PVx1NjcyQ1x1NjczQVx1NjVCOVx1NkNENVx1NEUwRFx1ODBGRFx1NUUyNlx1NjcwOVx1NEUzQlx1NEY1MwoKIyAwOiB0eXBlLCAxOiB0eXBlCmNvbXBpbGVyLmVyci5uZWl0aGVyLmNvbmRpdGlvbmFsLnN1YnR5cGU9PyBcdTc2ODRcdTRFMERcdTUxN0NcdTVCQjlcdTdDN0JcdTU3OEI6IFx1NEUyNFx1ODAwNVx1OTBGRFx1NEUwRFx1NjYyRlx1NUJGOVx1NjVCOVx1NzY4NFx1NUI1MFx1N0M3Qlx1NTc4QlxuXHU3QjJDXHU0RThDXHU0RTJBXHU2NENEXHU0RjVDXHU2NTcwOiB7MH1cblx1N0IyQ1x1NEUwOVx1NEUyQVx1NjRDRFx1NEY1Q1x1NjU3MDogezF9CgoKIyAwOiBtZXNzYWdlIHNlZ21lbnQKY29tcGlsZXIubWlzYy5pbmNvbXBhdGlibGUudHlwZS5pbi5jb25kaXRpb25hbD1cdTY3NjFcdTRFRjZcdTg4NjhcdThGQkVcdTVGMEZcdTRFMkRcdTc2ODRcdTdDN0JcdTU3OEJcdTk1MTlcdThCRUZcbnswfQoKY29tcGlsZXIubWlzYy5jb25kaXRpb25hbC50YXJnZXQuY2FudC5iZS52b2lkPVx1Njc2MVx1NEVGNlx1ODg2OFx1OEZCRVx1NUYwRlx1NzY4NFx1NzZFRVx1NjgwN1x1N0M3Qlx1NTc4Qlx1NEUwRFx1ODBGRFx1NEUzQVx1N0E3QQoKIyAwOiB0eXBlCmNvbXBpbGVyLm1pc2MuaW5jb21wYXRpYmxlLnJldC50eXBlLmluLmxhbWJkYT1sYW1iZGEgXHU4ODY4XHU4RkJFXHU1RjBGXHU0RTJEXHU3Njg0XHU4RkQ0XHU1NkRFXHU3QzdCXHU1NzhCXHU5NTE5XHU4QkVGXG57MH0KCmNvbXBpbGVyLm1pc2Muc3RhdC5leHByLmV4cGVjdGVkPWxhbWJkYSBcdTRFM0JcdTRGNTNcdTRFMEUgdm9pZCBcdTUxRkRcdTY1NzBcdTYzQTVcdTUzRTNcdTRFMERcdTUxN0NcdTVCQjlcbihcdThCRjdcdTgwMDNcdTg2NTFcdTRGN0ZcdTc1MjhcdTU3NTcgbGFtYmRhIFx1NEUzQlx1NEY1MywgXHU2MjE2XHU4MDA1XHU2NTM5XHU0RTNBXHU0RjdGXHU3NTI4XHU4QkVEXHU1M0U1XHU4ODY4XHU4RkJFXHU1RjBGKQoKIyAwOiB0eXBlCmNvbXBpbGVyLm1pc2MuaW5jb21wYXRpYmxlLnJldC50eXBlLmluLm1yZWY9XHU2NUI5XHU2Q0Q1XHU1RjE1XHU3NTI4XHU0RTJEXHU3Njg0XHU4RkQ0XHU1NkRFXHU3QzdCXHU1NzhCXHU5NTE5XHU4QkVGXG57MH0KCmNvbXBpbGVyLmVyci5sYW1iZGEuYm9keS5uZWl0aGVyLnZhbHVlLm5vci52b2lkLmNvbXBhdGlibGU9bGFtYmRhIFx1NEUzQlx1NEY1M1x1NEUwRFx1NjYyRlx1NTAzQywgXHU0RTVGXHU0RTBEXHU0RTBFIHZvaWQgXHU1MTdDXHU1QkI5CgojIDA6IGxpc3Qgb2YgdHlwZQpjb21waWxlci5lcnIuaW5jb21wYXRpYmxlLnRocm93bi50eXBlcy5pbi5tcmVmPVx1NjVCOVx1NkNENVx1NUYxNVx1NzUyOFx1NEUyRFx1NjI5Qlx1NTFGQVx1NzY4NFx1N0M3Qlx1NTc4QnswfVx1NEUwRFx1NTE3Q1x1NUJCOQoKY29tcGlsZXIubWlzYy5pbmNvbXBhdGlibGUuYXJnLnR5cGVzLmluLmxhbWJkYT1sYW1iZGEgXHU4ODY4XHU4RkJFXHU1RjBGXHU0RTJEXHU3Njg0XHU1M0MyXHU2NTcwXHU3QzdCXHU1NzhCXHU0RTBEXHU1MTdDXHU1QkI5Cgpjb21waWxlci5taXNjLmluY29tcGF0aWJsZS5hcmcudHlwZXMuaW4ubXJlZj1cdTY1QjlcdTZDRDVcdTVGMTVcdTc1MjhcdTRFMkRcdTc2ODRcdTUzQzJcdTY1NzBcdTdDN0JcdTU3OEJcdTRFMERcdTUxN0NcdTVCQjkKCmNvbXBpbGVyLmVyci5uZXcubm90LmFsbG93ZWQuaW4uYW5ub3RhdGlvbj1cdTZDRThcdTkxQ0FcdTRFMkRcdTRFMERcdTUxNDFcdThCQjhcdTRGN0ZcdTc1MjggJyduZXcnJwoKY29tcGlsZXIuZXJyLm5vLmFubm90YXRpb24ubWVtYmVyPXsxfVx1NEUyRFx1NkNBMVx1NjcwOVx1NkNFOFx1OTFDQVx1NjIxMFx1NTQ1OHswfQoKY29tcGlsZXIuZXJyLm5vLmVuY2wuaW5zdGFuY2Uub2YudHlwZS5pbi5zY29wZT1cdTRGNUNcdTc1MjhcdTU3REZcdTRFMkRcdTZDQTFcdTY3MDlcdTdDN0JcdTU3OEJcdTRFM0F7MH1cdTc2ODRcdTVDMDFcdTk1RURcdTVCOUVcdTRGOEIKCmNvbXBpbGVyLmVyci5uby5pbnRmLmV4cGVjdGVkLmhlcmU9XHU2QjY0XHU1OTA0XHU0RTBEXHU5NzAwXHU4OTgxXHU2M0E1XHU1M0UzCgpjb21waWxlci5lcnIubm8ubWF0Y2guZW50cnk9ezB9XHU1NzI4ezF9XHU3Njg0XHU2NzYxXHU3NkVFXHU0RTJEXHU2Q0ExXHU2NzA5XHU1MzM5XHU5MTREXHU5ODc5OyBcdTk3MDBcdTg5ODF7Mn0KCmNvbXBpbGVyLmVyci5ub3QuYW5ub3RhdGlvbi50eXBlPXswfVx1NEUwRFx1NjYyRlx1NkNFOFx1OTFDQVx1N0M3Qlx1NTc4QgoKIyAwOiBzeW1ib2wsIDE6IHN5bWJvbCwgMjogbWVzc2FnZSBzZWdtZW50CmNvbXBpbGVyLmVyci5ub3QuZGVmLmFjY2Vzcy5wYWNrYWdlLmNhbnQuYWNjZXNzPXswfSBcdTRFMERcdTUzRUZcdTg5QzFcbih7Mn0pCgojIDA6IHN5bWJvbCwgMTogc3ltYm9sLCAyOiBtZXNzYWdlIHNlZ21lbnQKY29tcGlsZXIubWlzYy5ub3QuZGVmLmFjY2Vzcy5wYWNrYWdlLmNhbnQuYWNjZXNzPXswfSBcdTRFMERcdTUzRUZcdTg5QzFcbih7Mn0pCgojIDA6IHN5bWJvbCwgMTogbWVzc2FnZSBzZWdtZW50CmNvbXBpbGVyLmVyci5wYWNrYWdlLm5vdC52aXNpYmxlPVx1N0EwQlx1NUU4Rlx1NTMwNSB7MH0gXHU0RTBEXHU1M0VGXHU4OUMxXG4oezF9KQoKIyAwOiBzeW1ib2wsIDE6IG1lc3NhZ2Ugc2VnbWVudApjb21waWxlci5taXNjLnBhY2thZ2Uubm90LnZpc2libGU9XHU3QTBCXHU1RThGXHU1MzA1IHswfSBcdTRFMERcdTUzRUZcdTg5QzFcbih7MX0pCgojIHswfSAtIGN1cnJlbnQgbW9kdWxlCiMgezF9IC0gcGFja2FnZSBpbiB3aGljaCB0aGUgaW52aXNpYmxlIGNsYXNzIGlzIGRlY2xhcmVkCiMgezJ9IC0gbW9kdWxlIGluIHdoaWNoIHsxfSBpcyBkZWNsYXJlZAojIDA6IHN5bWJvbCwgMTogc3ltYm9sLCAyOiBzeW1ib2wKY29tcGlsZXIubWlzYy5ub3QuZGVmLmFjY2Vzcy5kb2VzLm5vdC5yZWFkPVx1N0EwQlx1NUU4Rlx1NTMwNSB7MX0gXHU1REYyXHU1NzI4XHU2QTIxXHU1NzU3IHsyfSBcdTRFMkRcdTU4RjBcdTY2MEUsIFx1NEY0Nlx1NkEyMVx1NTc1NyB7MH0gXHU2NzJBXHU4QkZCXHU1M0Q2XHU1QjgzCgojIHswfSAtIHBhY2thZ2UgaW4gd2hpY2ggdGhlIGludmlzaWJsZSBjbGFzcyBpcyBkZWNsYXJlZAojIHsxfSAtIG1vZHVsZSBpbiB3aGljaCB7MH0gaXMgZGVjbGFyZWQKIyAwOiBzeW1ib2wsIDE6IHN5bWJvbApjb21waWxlci5taXNjLm5vdC5kZWYuYWNjZXNzLmRvZXMubm90LnJlYWQuZnJvbS51bm5hbWVkPVx1N0EwQlx1NUU4Rlx1NTMwNSB7MH0gXHU1REYyXHU1NzI4XHU2QTIxXHU1NzU3IHsxfSBcdTRFMkRcdTU4RjBcdTY2MEUsIFx1NEY0Nlx1OEJFNVx1NkEyMVx1NTc1N1x1NEUwRFx1NTcyOFx1NkEyMVx1NTc1N1x1NTZGRVx1NEUyRAoKIyB7MH0gLSBwYWNrYWdlIGluIHdoaWNoIHRoZSBpbnZpc2libGUgY2xhc3MgaXMgZGVjbGFyZWQKIyB7MX0gLSBjdXJyZW50IG1vZHVsZQojIDA6IHN5bWJvbCwgMTogc3ltYm9sCmNvbXBpbGVyLm1pc2Mubm90LmRlZi5hY2Nlc3MuZG9lcy5ub3QucmVhZC51bm5hbWVkPVx1N0EwQlx1NUU4Rlx1NTMwNSB7MH0gXHU1REYyXHU1NzI4XHU2NzJBXHU1NDdEXHU1NDBEXHU2QTIxXHU1NzU3XHU0RTJEXHU1OEYwXHU2NjBFLCBcdTRGNDZcdTZBMjFcdTU3NTcgezB9IFx1NjcyQVx1OEJGQlx1NTNENlx1NUI4MwoKIyB7MH0gLSBwYWNrYWdlIGluIHdoaWNoIHRoZSBpbnZpc2libGUgY2xhc3MgaXMgZGVjbGFyZWQKIyB7MX0gLSBtb2R1bGUgaW4gd2hpY2ggezB9IGlzIGRlY2xhcmVkCiMgMDogc3ltYm9sLCAxOiBzeW1ib2wKY29tcGlsZXIubWlzYy5ub3QuZGVmLmFjY2Vzcy5ub3QuZXhwb3J0ZWQ9XHU3QTBCXHU1RThGXHU1MzA1IHswfSBcdTVERjJcdTU3MjhcdTZBMjFcdTU3NTcgezF9IFx1NEUyRFx1NThGMFx1NjYwRSwgXHU0RjQ2XHU4QkU1XHU2QTIxXHU1NzU3XHU2NzJBXHU1QkZDXHU1MUZBXHU1QjgzCgojIHswfSAtIHBhY2thZ2UgaW4gd2hpY2ggdGhlIGludmlzaWJsZSBjbGFzcyBpcyBkZWNsYXJlZAojIHsxfSAtIG1vZHVsZSBpbiB3aGljaCB7MH0gaXMgZGVjbGFyZWQKIyAwOiBzeW1ib2wsIDE6IHN5bWJvbApjb21waWxlci5taXNjLm5vdC5kZWYuYWNjZXNzLm5vdC5leHBvcnRlZC5mcm9tLnVubmFtZWQ9XHU3QTBCXHU1RThGXHU1MzA1IHswfSBcdTVERjJcdTU3MjhcdTZBMjFcdTU3NTcgezF9IFx1NEUyRFx1NThGMFx1NjYwRSwgXHU0RjQ2XHU4QkU1XHU2QTIxXHU1NzU3XHU2NzJBXHU1QkZDXHU1MUZBXHU1QjgzCgojIHswfSAtIHBhY2thZ2UgaW4gd2hpY2ggdGhlIGludmlzaWJsZSBjbGFzcyBpcyBkZWNsYXJlZAojIHsxfSAtIG1vZHVsZSBpbiB3aGljaCB7MH0gaXMgZGVjbGFyZWQKIyB7Mn0gLSBjdXJyZW50IG1vZHVsZQojIDA6IHN5bWJvbCwgMTogc3ltYm9sLCAyOiBzeW1ib2wKY29tcGlsZXIubWlzYy5ub3QuZGVmLmFjY2Vzcy5ub3QuZXhwb3J0ZWQudG8ubW9kdWxlPVx1N0EwQlx1NUU4Rlx1NTMwNSB7MH0gXHU1REYyXHU1NzI4XHU2QTIxXHU1NzU3IHsxfSBcdTRFMkRcdTU4RjBcdTY2MEUsIFx1NEY0Nlx1OEJFNVx1NkEyMVx1NTc1N1x1NjcyQVx1NUMwNlx1NUI4M1x1NUJGQ1x1NTFGQVx1NTIzMFx1NkEyMVx1NTc1NyB7Mn0KCiMgezB9IC0gcGFja2FnZSBpbiB3aGljaCB0aGUgaW52aXNpYmxlIGNsYXNzIGlzIGRlY2xhcmVkCiMgezF9IC0gbW9kdWxlIGluIHdoaWNoIHswfSBpcyBkZWNsYXJlZAojIDA6IHN5bWJvbCwgMTogc3ltYm9sCmNvbXBpbGVyLm1pc2Mubm90LmRlZi5hY2Nlc3Mubm90LmV4cG9ydGVkLnRvLm1vZHVsZS5mcm9tLnVubmFtZWQ9XHU3QTBCXHU1RThGXHU1MzA1IHswfSBcdTVERjJcdTU3MjhcdTZBMjFcdTU3NTcgezF9IFx1NEUyRFx1NThGMFx1NjYwRSwgXHU0RjQ2XHU4QkU1XHU2QTIxXHU1NzU3XHU2NzJBXHU1QzA2XHU1QjgzXHU1QkZDXHU1MUZBXHU1MjMwXHU2NzJBXHU1NDdEXHU1NDBEXHU2QTIxXHU1NzU3CgojIDA6IHN5bWJvbCwgMTogc3ltYm9sCmNvbXBpbGVyLmVyci5ub3QuZGVmLmFjY2Vzcy5jbGFzcy5pbnRmLmNhbnQuYWNjZXNzPXsxfS57MH0gXHU2NjJGXHU1NzI4XHU0RTBEXHU1M0VGXHU4QkJGXHU5NUVFXHU3Njg0XHU3QzdCXHU2MjE2XHU2M0E1XHU1M0UzXHU0RTJEXHU1QjlBXHU0RTQ5XHU3Njg0CgojIDA6IHN5bWJvbCwgMTogc3ltYm9sCmNvbXBpbGVyLm1pc2Mubm90LmRlZi5hY2Nlc3MuY2xhc3MuaW50Zi5jYW50LmFjY2Vzcz17MX0uezB9IFx1NjYyRlx1NTcyOFx1NEUwRFx1NTNFRlx1OEJCRlx1OTVFRVx1NzY4NFx1N0M3Qlx1NjIxNlx1NjNBNVx1NTNFM1x1NEUyRFx1NUI5QVx1NEU0OVx1NzY4NAoKIyAwOiBzeW1ib2wsIDE6IHN5bWJvbCwgMjogc3ltYm9sLCAzOiBtZXNzYWdlIHNlZ21lbnQKY29tcGlsZXIuZXJyLm5vdC5kZWYuYWNjZXNzLmNsYXNzLmludGYuY2FudC5hY2Nlc3MucmVhc29uPVx1N0EwQlx1NUU4Rlx1NTMwNSB7Mn0gXHU0RTJEXHU3Njg0IHsxfS57MH0gXHU0RTBEXHU1M0VGXHU4QkJGXHU5NUVFXG4oezN9KQoKIyAwOiBzeW1ib2wsIDE6IHN5bWJvbCwgMjogc3ltYm9sLCAzOiBtZXNzYWdlIHNlZ21lbnQKY29tcGlsZXIubWlzYy5ub3QuZGVmLmFjY2Vzcy5jbGFzcy5pbnRmLmNhbnQuYWNjZXNzLnJlYXNvbj1cdTdBMEJcdTVFOEZcdTUzMDUgezJ9IFx1NEUyRFx1NzY4NCB7MX0uezB9IFx1NEUwRFx1NTNFRlx1OEJCRlx1OTVFRVxuKHszfSkKCiMgMDogc3ltYm9sLCAxOiBsaXN0IG9mIHR5cGUsIDI6IHR5cGUKY29tcGlsZXIubWlzYy5jYW50LmFjY2Vzcy5pbm5lci5jbHMuY29uc3RyPVx1NjVFMFx1NkNENVx1OEJCRlx1OTVFRVx1Njc4NFx1OTAyMFx1NTY2OCB7MH0oezF9KVxuXHU0RjVDXHU3NTI4XHU1N0RGXHU0RTJEXHU2Q0ExXHU2NzA5XHU3QzdCXHU1NzhCXHU0RTNBezJ9XHU3Njg0XHU1QzAxXHU5NUVEXHU1QjlFXHU0RjhCCgojIDA6IHN5bWJvbCwgMTogc3ltYm9sCmNvbXBpbGVyLmVyci5ub3QuZGVmLnB1YmxpYy5jYW50LmFjY2Vzcz17MH1cdTU3Mjh7MX1cdTRFMkRcdTRFMERcdTY2MkZcdTUxNkNcdTUxNzFcdTc2ODQ7IFx1NjVFMFx1NkNENVx1NEVDRVx1NTkxNlx1OTBFOFx1N0EwQlx1NUU4Rlx1NTMwNVx1NEUyRFx1NUJGOVx1NTE3Nlx1OEZEQlx1ODg0Q1x1OEJCRlx1OTVFRQoKIyAwOiBzeW1ib2wsIDE6IHN5bWJvbApjb21waWxlci5taXNjLm5vdC5kZWYucHVibGljLmNhbnQuYWNjZXNzPXswfVx1NTcyOHsxfVx1NEUyRFx1NEUwRFx1NjYyRlx1NTE2Q1x1NTE3MVx1NzY4NDsgXHU2NUUwXHU2Q0Q1XHU0RUNFXHU1OTE2XHU5MEU4XHU3QTBCXHU1RThGXHU1MzA1XHU0RTJEXHU1QkY5XHU1MTc2XHU4RkRCXHU4ODRDXHU4QkJGXHU5NUVFCgojIDA6IG5hbWUKY29tcGlsZXIuZXJyLm5vdC5sb29wLmxhYmVsPVx1NEUwRFx1NjYyRiBsb29wIFx1NjgwN1x1N0I3RTogezB9Cgpjb21waWxlci5lcnIubm90LnN0bXQ9XHU0RTBEXHU2NjJGXHU4QkVEXHU1M0U1CgojIDA6IHN5bWJvbApjb21waWxlci5lcnIubm90LmVuY2wuY2xhc3M9XHU0RTBEXHU2NjJGXHU1QzAxXHU5NUVEXHU3QzdCOiB7MH0KCiMgMDogbmFtZSwgMTogdHlwZQpjb21waWxlci5lcnIub3BlcmF0b3IuY2FudC5iZS5hcHBsaWVkPVx1NEUwMFx1NTE0M1x1OEZEMFx1N0I5N1x1N0IyNiAnJ3swfScnIFx1NzY4NFx1NjRDRFx1NEY1Q1x1NjU3MFx1N0M3Qlx1NTc4QnsxfVx1OTUxOVx1OEJFRgoKIyAwOiBuYW1lLCAxOiB0eXBlLCAyOiB0eXBlCmNvbXBpbGVyLmVyci5vcGVyYXRvci5jYW50LmJlLmFwcGxpZWQuMT1cdTRFOENcdTUxNDNcdThGRDBcdTdCOTdcdTdCMjYgJyd7MH0nJyBcdTc2ODRcdTY0Q0RcdTRGNUNcdTY1NzBcdTdDN0JcdTU3OEJcdTk1MTlcdThCRUZcblx1N0IyQ1x1NEUwMFx1NEUyQVx1N0M3Qlx1NTc4QjogIHsxfVxuXHU3QjJDXHU0RThDXHU0RTJBXHU3QzdCXHU1NzhCOiB7Mn0KCmNvbXBpbGVyLmVyci5wa2cuYW5ub3RhdGlvbnMuc2IuaW4ucGFja2FnZS1pbmZvLmphdmE9XHU3QTBCXHU1RThGXHU1MzA1XHU2Q0U4XHU5MUNBXHU1RTk0XHU1NzI4XHU2NTg3XHU0RUY2IHBhY2thZ2UtaW5mby5qYXZhIFx1NEUyRAoKY29tcGlsZXIuZXJyLm5vLnBrZy5pbi5tb2R1bGUtaW5mby5qYXZhPVx1N0EwQlx1NUU4Rlx1NTMwNVx1NUI1MFx1NTNFNVx1NEUwRFx1NUU5NFx1NTcyOFx1NjU4N1x1NEVGNiBtb2R1bGUtaW5mby5qYXZhIFx1NEUyRAoKIyAwOiBzeW1ib2wKY29tcGlsZXIuZXJyLnBrZy5jbGFzaGVzLndpdGguY2xhc3Mub2Yuc2FtZS5uYW1lPVx1N0EwQlx1NUU4Rlx1NTMwNXswfVx1NEUwRVx1NUUyNlx1NjcwOVx1NzZGOFx1NTQwQ1x1NTQwRFx1NzlGMFx1NzY4NFx1N0M3Qlx1NTFCMlx1N0E4MQoKY29tcGlsZXIuZXJyLndhcm5pbmdzLmFuZC53ZXJyb3I9XHU1M0QxXHU3M0IwXHU4QjY2XHU1NDRBLCBcdTRGNDZcdTYzMDdcdTVCOUFcdTRFODYgLVdlcnJvcgoKIyBFcnJvcnMgcmVsYXRlZCB0byBhbm5vdGF0aW9uIHByb2Nlc3NpbmcKCiMgMDogc3ltYm9sLCAxOiBzdHJpbmcsIDI6IHN0cmluZyAoc3RhY2stdHJhY2UpCmNvbXBpbGVyLmVyci5wcm9jLmNhbnQuYWNjZXNzPVx1NjVFMFx1NkNENVx1OEJCRlx1OTVFRXswfVxuezF9XG5cdTY3MDlcdTUxNzNcdThCRTZcdTdFQzZcdTRGRTFcdTYwNkYsIFx1OEJGN1x1NTNDMlx1OTYwNVx1NEVFNVx1NEUwQlx1NTgwNlx1NjgwOFx1OERERlx1OEUyQVx1MzAwMlxuezJ9CgojIDA6IHN5bWJvbCwgMTogc3RyaW5nCmNvbXBpbGVyLmVyci5wcm9jLmNhbnQuYWNjZXNzLjE9XHU2NUUwXHU2Q0Q1XHU4QkJGXHU5NUVFezB9XG57MX0KCiMgMDogc3RyaW5nCmNvbXBpbGVyLmVyci5wcm9jLmNhbnQuZmluZC5jbGFzcz1cdTYyN0VcdTRFMERcdTUyMzAgJyd7MH0nJyBcdTc2ODRcdTdDN0JcdTY1ODdcdTRFRjZcdTMwMDIKCiMgUHJpbnQgYSBjbGllbnQtZ2VuZXJhdGVkIGVycm9yIG1lc3NhZ2U7IGFzc3VtZWQgdG8gYmUgbG9jYWxpemVkLCBubyB0cmFuc2xhdGlvbiByZXF1aXJlZAojIDA6IHN0cmluZwpjb21waWxlci5lcnIucHJvYy5tZXNzYWdlcj17MH0KCiMgMDogbGlzdCBvZiBzdHJpbmcKY29tcGlsZXIuZXJyLnByb2Mubm8uZXhwbGljaXQuYW5ub3RhdGlvbi5wcm9jZXNzaW5nLnJlcXVlc3RlZD1cdTRFQzVcdTVGNTNcdTY2M0VcdTVGMEZcdThCRjdcdTZDNDJcdTZDRThcdTkxQ0FcdTU5MDRcdTc0MDZcdTY1RjZcdTYyNERcdTYzQTVcdTUzRDdcdTdDN0JcdTU0MERcdTc5RjAgJyd7MH0nJwoKY29tcGlsZXIuZXJyLnByb2Mubm8uc2VydmljZT1TZXJ2aWNlTG9hZGVyIFx1NEUwRFx1NTNFRlx1NzUyOCwgXHU0RjQ2XHU1QjgzXHU2NjJGXHU2Q0U4XHU5MUNBXHU1OTA0XHU3NDA2XHU2MjQwXHU1RkM1XHU5NzAwXHU3Njg0XHUzMDAyCgpjb21waWxlci5lcnIucHJvYy5wcm9jZXNzb3IuYmFkLm9wdGlvbi5uYW1lPVx1NTkwNFx1NzQwNlx1N0EwQlx1NUU4RiAnJ3sxfScnIFx1NjNEMFx1NEY5Qlx1NzY4NFx1OTAwOVx1OTg3OVx1NTQwRFx1NzlGMCAnJ3swfScnIFx1OTUxOVx1OEJFRgoKIyAwOiBzdHJpbmcKY29tcGlsZXIuZXJyLnByb2MucHJvY2Vzc29yLmNhbnQuaW5zdGFudGlhdGU9XHU2NUUwXHU2Q0Q1XHU1QjlFXHU0RjhCXHU1MzE2XHU1OTA0XHU3NDA2XHU3QTBCXHU1RThGICcnezB9JycgXHU3Njg0XHU1QjlFXHU0RjhCCgojIDA6IHN0cmluZwpjb21waWxlci5lcnIucHJvYy5wcm9jZXNzb3Iubm90LmZvdW5kPVx1NjI3RVx1NEUwRFx1NTIzMFx1NkNFOFx1OTFDQVx1NTkwNFx1NzQwNlx1N0EwQlx1NUU4RiAnJ3swfScnCgojIDA6IHN0cmluZwpjb21waWxlci5lcnIucHJvYy5wcm9jZXNzb3Iud3JvbmcudHlwZT1cdTZDRThcdTkxQ0FcdTU5MDRcdTc0MDZcdTdBMEJcdTVFOEYgJyd7MH0nJyBcdTY3MkFcdTVCOUVcdTczQjAgamF2YXguYW5ub3RhdGlvbi5wcm9jZXNzaW5nLlByb2Nlc3NvcgoKY29tcGlsZXIuZXJyLnByb2Muc2VydmljZS5wcm9ibGVtPVx1NTIxQlx1NUVGQVx1NjcwRFx1NTJBMVx1NTJBMFx1OEY3RFx1NTY2OFx1NEVFNVx1NTJBMFx1OEY3RFx1NTkwNFx1NzQwNlx1N0EwQlx1NUU4Rlx1NjVGNlx1NTFGQVx1OTUxOVx1MzAwMgoKY29tcGlsZXIuZXJyLnByb2MuYmFkLmNvbmZpZy5maWxlPVx1NjcwRFx1NTJBMVx1OTE0RFx1N0Y2RVx1NjU4N1x1NEVGNlx1NEUwRFx1NkI2M1x1Nzg2RSwgXHU2MjE2XHU2Nzg0XHU5MDIwXHU1OTA0XHU3NDA2XHU3QTBCXHU1RThGXHU1QkY5XHU4QzYxezB9XHU2NUY2XHU2MjlCXHU1MUZBXHU1RjAyXHU1RTM4XHU5NTE5XHU4QkVGCgpjb21waWxlci5lcnIucHJvYy5jYW50LmNyZWF0ZS5sb2FkZXI9XHU2NUUwXHU2Q0Q1XHU0RTNBXHU2Q0U4XHU5MUNBXHU1OTA0XHU3NDA2XHU3QTBCXHU1RThGezB9XHU1MjFCXHU1RUZBXHU3QzdCXHU1MkEwXHU4RjdEXHU1NjY4CgojIDA6IHVudXNlZApjb21waWxlci5lcnIucXVhbGlmaWVkLm5ldy5vZi5zdGF0aWMuY2xhc3M9XHU5NjUwXHU1QjlBXHU3Njg0XHU2NUIwXHU5NzU5XHU2MDAxXHU3QzdCCgpjb21waWxlci5lcnIucmVjdXJzaXZlLmN0b3IuaW52b2NhdGlvbj1cdTkwMTJcdTVGNTJcdTY3ODRcdTkwMjBcdTU2NjhcdThDMDNcdTc1MjgKCiMgMDogbmFtZSwgMTogc3ltYm9sIGtpbmQsIDI6IHN5bWJvbCwgMzogc3ltYm9sLCA0OiBzeW1ib2wga2luZCwgNTogc3ltYm9sLCA2OiBzeW1ib2wKY29tcGlsZXIuZXJyLnJlZi5hbWJpZ3VvdXM9XHU1QkY5ezB9XHU3Njg0XHU1RjE1XHU3NTI4XHU0RTBEXHU2NjBFXHU3ODZFXG57M30gXHU0RTJEXHU3Njg0ezF9IHsyfSBcdTU0OEMgezZ9IFx1NEUyRFx1NzY4NHs0fSB7NX0gXHU5MEZEXHU1MzM5XHU5MTRECgojIDA6IG5hbWUsIDE6IHN5bWJvbCBraW5kLCAyOiBzeW1ib2wsIDM6IHN5bWJvbCwgNDogc3ltYm9sIGtpbmQsIDU6IHN5bWJvbCwgNjogc3ltYm9sCmNvbXBpbGVyLm1pc2MucmVmLmFtYmlndW91cz1cdTVCRjl7MH1cdTc2ODRcdTVGMTVcdTc1MjhcdTRFMERcdTY2MEVcdTc4NkVcbnszfSBcdTRFMkRcdTc2ODR7MX0gezJ9IFx1NTQ4QyB7Nn0gXHU0RTJEXHU3Njg0ezR9IHs1fSBcdTkwRkRcdTUzMzlcdTkxNEQKCmNvbXBpbGVyLmVyci5yZXBlYXRlZC5hbm5vdGF0aW9uLnRhcmdldD1cdTZDRThcdTkxQ0FcdTc2RUVcdTY4MDdcdTkxQ0RcdTU5MEQKCmNvbXBpbGVyLmVyci5yZXBlYXRlZC5pbnRlcmZhY2U9XHU2M0E1XHU1M0UzXHU5MUNEXHU1OTBECgpjb21waWxlci5lcnIucmVwZWF0ZWQubW9kaWZpZXI9XHU0RkVFXHU5OTcwXHU3QjI2XHU5MUNEXHU1OTBECgojIDA6IHN5bWJvbCwgMTogc2V0IG9mIG1vZGlmaWVyLCAyOiBzeW1ib2wKY29tcGlsZXIuZXJyLnJlcG9ydC5hY2Nlc3M9ezB9XHU1M0VGXHU0RUU1XHU1NzI4ezJ9XHU0RTJEXHU4QkJGXHU5NUVFezF9CgojIDA6IHN5bWJvbCwgMTogc2V0IG9mIG1vZGlmaWVyLCAyOiBzeW1ib2wKY29tcGlsZXIubWlzYy5yZXBvcnQuYWNjZXNzPXswfVx1NTNFRlx1NEVFNVx1NTcyOHsyfVx1NEUyRFx1OEJCRlx1OTVFRXsxfQoKY29tcGlsZXIuZXJyLnJldC5vdXRzaWRlLm1ldGg9XHU4RkQ0XHU1NkRFXHU1OTE2XHU5MEU4XHU2NUI5XHU2Q0Q1Cgpjb21waWxlci5lcnIuc2lnbmF0dXJlLmRvZXNudC5tYXRjaC5zdXBlcnR5cGU9XHU3QjdFXHU1NDBEXHU0RTBFezB9XHU0RTBEXHU1MzM5XHU5MTREOyBcdTRFMERcdTUxN0NcdTVCQjlcdTc2ODRcdThEODVcdTdDN0JcdTU3OEIKCmNvbXBpbGVyLmVyci5zaWduYXR1cmUuZG9lc250Lm1hdGNoLmludGY9XHU3QjdFXHU1NDBEXHU0RTBFezB9XHU0RTBEXHU1MzM5XHU5MTREOyBcdTRFMERcdTUxN0NcdTVCQjlcdTc2ODRcdTYzQTVcdTUzRTMKCiMgMDogbnVtYmVyLCAxOiBudW1iZXIKY29tcGlsZXIuZXJyLm1ldGhvZC5pbnZva2VkLndpdGguaW5jb3JyZWN0Lm51bWJlci5hcmd1bWVudHM9XHU0RjdGXHU3NTI4XHU0RTBEXHU2QjYzXHU3ODZFXHU2NTcwXHU5MUNGXHU3Njg0XHU1M0MyXHU2NTcwXHU4QzAzXHU3NTI4XHU0RTg2XHU2NUI5XHU2Q0Q1OyBcdTk4ODRcdTY3MUZcdTRFM0EgezB9IFx1NEUyQSwgXHU2MjdFXHU1MjMwIHsxfSBcdTRFMkEKCiMgMDogc3ltYm9sLCAxOiBzeW1ib2wsIDI6IHN5bWJvbApjb21waWxlci5lcnIuZG9lcy5ub3Qub3ZlcnJpZGUuYWJzdHJhY3Q9ezB9XHU0RTBEXHU2NjJGXHU2MkJEXHU4QzYxXHU3Njg0LCBcdTVFNzZcdTRFMTRcdTY3MkFcdTg5ODZcdTc2RDZ7Mn1cdTRFMkRcdTc2ODRcdTYyQkRcdThDNjFcdTY1QjlcdTZDRDV7MX0KCmNvbXBpbGVyLmVyci5zb3VyY2UuY2FudC5vdmVyd3JpdGUuaW5wdXQuZmlsZT1cdTUxOTlcdTUxNjVcdTZFOTBcdTY1RjZcdTUxRkFcdTk1MTk7IFx1NjVFMFx1NkNENVx1ODk4Nlx1NzZENlx1OEY5M1x1NTE2NVx1NjU4N1x1NEVGNnswfQoKY29tcGlsZXIuZXJyLnN0YWNrLnNpbS5lcnJvcj1cdTUxODVcdTkwRThcdTk1MTlcdThCRUY6IHswfVx1NEUyRFx1NzY4NFx1NTgwNlx1NjgwOCBzaW0gXHU5NTE5XHU4QkVGCgpjb21waWxlci5lcnIuc3RhdGljLmltcC5vbmx5LmNsYXNzZXMuYW5kLmludGVyZmFjZXM9XHU0RUM1XHU0RUNFXHU3QzdCXHU1NDhDXHU2M0E1XHU1M0UzXHU5NzU5XHU2MDAxXHU1QkZDXHU1MTY1Cgpjb21waWxlci5lcnIuc3RyaW5nLmNvbnN0LnJlcT1cdTk3MDBcdTg5ODFcdTVFMzhcdTkxQ0ZcdTVCNTdcdTdCMjZcdTRFMzJcdTg4NjhcdThGQkVcdTVGMEYKCiMgMDogc3ltYm9sLCAxOiBzeW1ib2wKY29tcGlsZXIuZXJyLnN5bnRoZXRpYy5uYW1lLmNvbmZsaWN0PVx1N0IyNlx1NTNGN3swfVx1NEUwRXsxfVx1NEUyRFx1NzY4NCBjb21waWxlci1zeW50aGVzaXplZCBcdTdCMjZcdTUzRjdcdTUxQjJcdTdBODEKCmNvbXBpbGVyLmVyci50aHJvd3Mubm90LmFsbG93ZWQuaW4uaW50Zi5hbm5vdGF0aW9uPUBpbnRlcmZhY2UgXHU2MjEwXHU1NDU4XHU0RTJEXHU0RTBEXHU1MTQxXHU4QkI4XHU0RjdGXHU3NTI4IHRocm93cyBcdTVCNTBcdTUzRTUKCmNvbXBpbGVyLmVyci50cnkud2l0aG91dC5jYXRjaC5vci5maW5hbGx5PVx1NjcwOSAnJ3RyeScnLCBcdTRGNDZcdTY2MkZcdTZDQTFcdTY3MDkgJydjYXRjaCcnIFx1NjIxNiAnJ2ZpbmFsbHknJwoKY29tcGlsZXIuZXJyLnRyeS53aXRob3V0LmNhdGNoLmZpbmFsbHkub3IucmVzb3VyY2UuZGVjbHM9Jyd0cnknJyBcdTRFMERcdTVFMjZcdTY3MDkgJydjYXRjaCcnLCAnJ2ZpbmFsbHknJyBcdTYyMTZcdThENDRcdTZFOTBcdTU4RjBcdTY2MEUKCiMgMDogc3ltYm9sCmNvbXBpbGVyLmVyci50eXBlLmRvZXNudC50YWtlLnBhcmFtcz1cdTdDN0JcdTU3OEJ7MH1cdTRFMERcdTVFMjZcdTY3MDlcdTUzQzJcdTY1NzAKCmNvbXBpbGVyLmVyci50eXBlLnZhci5jYW50LmJlLmRlcmVmPVx1NjVFMFx1NkNENVx1NEVDRVx1N0M3Qlx1NTc4Qlx1NTNEOFx1OTFDRlx1NEUyRFx1OEZEQlx1ODg0Q1x1OTAwOVx1NjJFOQoKY29tcGlsZXIuZXJyLnR5cGUudmFyLm1heS5ub3QuYmUuZm9sbG93ZWQuYnkub3RoZXIuYm91bmRzPVx1N0M3Qlx1NTc4Qlx1NTNEOFx1OTFDRlx1NTQwRVx1OTc2Mlx1NEUwRFx1ODBGRFx1NUUyNlx1NjcwOVx1NTE3Nlx1NEVENlx1OTY1MFx1NTIzNlx1ODMwM1x1NTZGNAoKY29tcGlsZXIuZXJyLnR5cGUudmFyLm1vcmUudGhhbi5vbmNlPVx1N0M3Qlx1NTc4Qlx1NTNEOFx1OTFDRnswfVx1NTcyOHsxfVx1NzY4NFx1N0VEM1x1Njc5Q1x1N0M3Qlx1NTc4Qlx1NEUyRFx1NTkxQVx1NkIyMVx1NTFGQVx1NzNCMDsgXHU1RkM1XHU5ODdCXHU1QkY5XHU1MTc2XHU4RkRCXHU4ODRDXHU1QjlFXHU0RjhCXHU1MzE2Cgpjb21waWxlci5lcnIudHlwZS52YXIubW9yZS50aGFuLm9uY2UuaW4ucmVzdWx0PVx1N0M3Qlx1NTc4Qlx1NTNEOFx1OTFDRnswfVx1NTcyOHsxfVx1NzY4NFx1N0M3Qlx1NTc4Qlx1NEUyRFx1NTkxQVx1NkIyMVx1NTFGQVx1NzNCMDsgXHU1RkM1XHU5ODdCXHU1QkY5XHU1MTc2XHU4RkRCXHU4ODRDXHU1QjlFXHU0RjhCXHU1MzE2CgojIDA6IHR5cGUsIDE6IHR5cGUsIDI6IHN0cmluZwpjb21waWxlci5lcnIudHlwZXMuaW5jb21wYXRpYmxlLmRpZmYucmV0PVx1N0M3Qlx1NTc4QnswfVx1NTQ4Q3sxfVx1NEUwRFx1NTE3Q1x1NUJCOTsgXHU0RTI0XHU4MDA1XHU5MEZEXHU1QjlBXHU0RTQ5XHU0RTg2ezJ9LCBcdTRGNDZcdTUzNzRcdTVFMjZcdTY3MDlcdTRFMERcdTc2RjhcdTUxNzNcdTc2ODRcdThGRDRcdTU2REVcdTdDN0JcdTU3OEIKCiMgMDoga2luZCBuYW1lLCAxOiB0eXBlLCAyOiBuYW1lLCAzOiBsaXN0IG9mIHR5cGUsIDQ6IHN5bWJvbCwgNTogc3ltYm9sCmNvbXBpbGVyLmVyci50eXBlcy5pbmNvbXBhdGlibGUudW5yZWxhdGVkLmRlZmF1bHRzPXswfSB7MX1cdTRFQ0VcdTdDN0JcdTU3OEIgezR9IFx1NTQ4QyB7NX0gXHU0RTJEXHU3RUU3XHU2MjdGXHU0RTg2ezJ9KHszfSkgXHU3Njg0XHU0RTBEXHU3NkY4XHU1MTczXHU5RUQ4XHU4QkE0XHU1MDNDCgojIDA6IGtpbmQgbmFtZSwgMTogdHlwZSwgMjogbmFtZSwgMzogbGlzdCBvZiB0eXBlLCA0OiBzeW1ib2wsIDU6IHN5bWJvbApjb21waWxlci5lcnIudHlwZXMuaW5jb21wYXRpYmxlLmFic3RyYWN0LmRlZmF1bHQ9ezB9IHsxfVx1NEVDRVx1N0M3Qlx1NTc4QiB7NH0gXHU1NDhDIHs1fSBcdTRFMkRcdTdFRTdcdTYyN0ZcdTRFODZ7Mn0oezN9KSBcdTc2ODRcdTYyQkRcdThDNjFcdTU0OENcdTlFRDhcdThCQTRcdTUwM0MKCiMgMDogbmFtZSwgMToga2luZCBuYW1lLCAyOiBzeW1ib2wKY29tcGlsZXIuZXJyLmRlZmF1bHQub3ZlcnJpZGVzLm9iamVjdC5tZW1iZXI9ezF9IHsyfSBcdTRFMkRcdTc2ODRcdTlFRDhcdThCQTRcdTY1QjlcdTZDRDV7MH1cdTg5ODZcdTc2RDZcdTRFODYgamF2YS5sYW5nLk9iamVjdCBcdTc2ODRcdTYyMTBcdTU0NTgKCiMgMDogdHlwZQpjb21waWxlci5lcnIuaWxsZWdhbC5zdGF0aWMuaW50Zi5tZXRoLmNhbGw9XHU5NzU5XHU2MDAxXHU2M0E1XHU1M0UzXHU2NUI5XHU2Q0Q1XHU4QzAzXHU3NTI4XHU5NzVFXHU2Q0Q1XG5cdTVFOTRcdTVDMDZcdTYzQTVcdTY1MzZcdTY1QjlcdTg4NjhcdThGQkVcdTVGMEZcdTY2RkZcdTYzNjJcdTRFM0FcdTdDN0JcdTU3OEJcdTk2NTBcdTVCOUFcdTdCMjYgJyd7MH0nJwoKIyAwOiB0eXBlLCAxOiBtZXNzYWdlIHNlZ21lbnQKY29tcGlsZXIuZXJyLmlsbGVnYWwuZGVmYXVsdC5zdXBlci5jYWxsPVx1OUVEOFx1OEJBNFx1OEQ4NVx1N0VBN1x1OEMwM1x1NzUyOFx1NEUyRFx1NzY4NFx1N0M3Qlx1NTc4Qlx1OTY1MFx1NUI5QVx1N0IyNnswfVx1OTUxOVx1OEJFRlxuezF9CgojIDA6IHN5bWJvbCwgMTogdHlwZQpjb21waWxlci5taXNjLm92ZXJyaWRkZW4uZGVmYXVsdD1cdTg5ODZcdTc2RDZcdTRFODZ7MX1cdTRFMkRcdTc2ODRcdTY1QjlcdTZDRDUgezB9CgojIDA6IHN5bWJvbCwgMTogdHlwZSBvciBzeW1ib2wKY29tcGlsZXIubWlzYy5yZWR1bmRhbnQuc3VwZXJ0eXBlPVx1NTE5N1x1NEY1OVx1NjNBNVx1NTNFMyB7MH0gXHU1REYyXHU3NTMxIHsxfSBcdTYyNjlcdTVDNTUKCmNvbXBpbGVyLmVyci51bmNsb3NlZC5jaGFyLmxpdD1cdTY3MkFcdTdFRDNcdTY3NUZcdTc2ODRcdTVCNTdcdTdCMjZcdTY1ODdcdTVCNTcKCmNvbXBpbGVyLmVyci51bmNsb3NlZC5jb21tZW50PVx1NjcyQVx1N0VEM1x1Njc1Rlx1NzY4NFx1NkNFOFx1OTFDQQoKY29tcGlsZXIuZXJyLnVuY2xvc2VkLnN0ci5saXQ9XHU2NzJBXHU3RUQzXHU2NzVGXHU3Njg0XHU1QjU3XHU3QjI2XHU0RTMyXHU2NTg3XHU1QjU3CgojIDA6IG5hbWUKY29tcGlsZXIuZXJyLnVuc3VwcG9ydGVkLmVuY29kaW5nPVx1NEUwRFx1NjUyRlx1NjMwMVx1NzY4NFx1N0YxNlx1NzgwMTogezB9Cgpjb21waWxlci5lcnIuaW8uZXhjZXB0aW9uPVx1OEJGQlx1NTNENlx1NkU5MFx1NjU4N1x1NEVGNlx1NjVGNlx1NTFGQVx1OTUxOTogezB9CgojIDA6IG5hbWUKY29tcGlsZXIuZXJyLnVuZGVmLmxhYmVsPVx1NjcyQVx1NUI5QVx1NEU0OVx1NzY4NFx1NjgwN1x1N0I3RTogezB9CgojIDA6IG1lc3NhZ2Ugc2VnbWVudCwgMTogdW51c2VkCmNvbXBpbGVyLmVyci5jYW50LmFwcGx5LmRpYW1vbmQ9XHU2NUUwXHU2Q0Q1XHU2M0E4XHU2NUFEezB9XHU3Njg0XHU3QzdCXHU1NzhCXHU1M0MyXHU2NTcwCgojIDA6IG1lc3NhZ2Ugc2VnbWVudCBvciB0eXBlLCAxOiBtZXNzYWdlIHNlZ21lbnQKY29tcGlsZXIuZXJyLmNhbnQuYXBwbHkuZGlhbW9uZC4xPVx1NjVFMFx1NkNENVx1NjNBOFx1NjVBRHswfVx1NzY4NFx1N0M3Qlx1NTc4Qlx1NTNDMlx1NjU3MFxuXHU1MzlGXHU1NkUwOiB7MX0KCiMgMDogbWVzc2FnZSBzZWdtZW50IG9yIHR5cGUsIDE6IG1lc3NhZ2Ugc2VnbWVudApjb21waWxlci5taXNjLmNhbnQuYXBwbHkuZGlhbW9uZC4xPVx1NjVFMFx1NkNENVx1NjNBOFx1NjVBRHswfVx1NzY4NFx1N0M3Qlx1NTc4Qlx1NTNDMlx1NjU3MFxuXHU1MzlGXHU1NkUwOiB7MX0KCmNvbXBpbGVyLmVyci51bnJlYWNoYWJsZS5zdG10PVx1NjVFMFx1NkNENVx1OEJCRlx1OTVFRVx1NzY4NFx1OEJFRFx1NTNFNQoKY29tcGlsZXIuZXJyLmluaXRpYWxpemVyLm11c3QuYmUuYWJsZS50by5jb21wbGV0ZS5ub3JtYWxseT1cdTUyMURcdTU5Q0JcdTUzMTZcdTdBMEJcdTVFOEZcdTVGQzVcdTk4N0JcdTgwRkRcdTU5MUZcdTZCNjNcdTVFMzhcdTVCOENcdTYyMTAKCmNvbXBpbGVyLmVyci5pbml0aWFsaXplci5ub3QuYWxsb3dlZD1cdTYzQTVcdTUzRTNcdTRFMkRcdTRFMERcdTUxNDFcdThCQjhcdTY3MDlcdTUyMURcdTU5Q0JcdTUzMTZcdTdBMEJcdTVFOEYKCiMgMDogdHlwZQpjb21waWxlci5lcnIudW5yZXBvcnRlZC5leGNlcHRpb24ubmVlZC50by5jYXRjaC5vci50aHJvdz1cdTY3MkFcdTYyQTVcdTU0NEFcdTc2ODRcdTVGMDJcdTVFMzhcdTk1MTlcdThCRUZ7MH07IFx1NUZDNVx1OTg3Qlx1NUJGOVx1NTE3Nlx1OEZEQlx1ODg0Q1x1NjM1NVx1ODNCN1x1NjIxNlx1NThGMFx1NjYwRVx1NEVFNVx1NEZCRlx1NjI5Qlx1NTFGQQoKIyAwOiB0eXBlCmNvbXBpbGVyLmVyci51bnJlcG9ydGVkLmV4Y2VwdGlvbi5kZWZhdWx0LmNvbnN0cnVjdG9yPVx1OUVEOFx1OEJBNFx1Njc4NFx1OTAyMFx1NTY2OFx1NEUyRFx1NjcyQVx1NjJBNVx1NTQ0QVx1NzY4NFx1NUYwMlx1NUUzOFx1OTUxOVx1OEJFRnswfQoKIyAwOiB0eXBlLCAxOiBuYW1lCmNvbXBpbGVyLmVyci51bnJlcG9ydGVkLmV4Y2VwdGlvbi5pbXBsaWNpdC5jbG9zZT1cdTY3MkFcdTYyQTVcdTU0NEFcdTc2ODRcdTVGMDJcdTVFMzhcdTk1MTlcdThCRUZ7MH07IFx1NUZDNVx1OTg3Qlx1NUJGOVx1NTE3Nlx1OEZEQlx1ODg0Q1x1NjM1NVx1ODNCN1x1NjIxNlx1NThGMFx1NjYwRVx1NEVFNVx1NEZCRlx1NjI5Qlx1NTFGQVxuXHU1QkY5XHU4RDQ0XHU2RTkwXHU1M0Q4XHU5MUNGICcnezF9JycgXHU5NjkwXHU1RjBGXHU4QzAzXHU3NTI4IGNsb3NlKCkgXHU2NUY2XHU2MjlCXHU1MUZBXHU0RTg2XHU1RjAyXHU1RTM4XHU5NTE5XHU4QkVGCgpjb21waWxlci5lcnIudW5zdXBwb3J0ZWQuY3Jvc3MuZnAubGl0PVx1OEJFNSBWTSBcdTRFMERcdTY1MkZcdTYzMDFcdTUzNDFcdTUxNkRcdThGREJcdTUyMzZcdTZENkVcdTcwQjlcdTY1ODdcdTVCNTcKCmNvbXBpbGVyLmVyci52b2lkLm5vdC5hbGxvd2VkLmhlcmU9XHU2QjY0XHU1OTA0XHU0RTBEXHU1MTQxXHU4QkI4XHU0RjdGXHU3NTI4ICcnXHU3QTdBJycgXHU3QzdCXHU1NzhCCgojIDA6IHN0cmluZwpjb21waWxlci5lcnIud3JvbmcubnVtYmVyLnR5cGUuYXJncz1cdTdDN0JcdTU3OEJcdTUzRDhcdTkxQ0ZcdTY1NzBcdTc2RUVcdTk1MTlcdThCRUY7IFx1OTcwMFx1ODk4MXswfQoKIyAwOiBzeW1ib2wKY29tcGlsZXIuZXJyLnZhci5taWdodC5hbHJlYWR5LmJlLmFzc2lnbmVkPVx1NTNFRlx1ODBGRFx1NURGMlx1NTIwNlx1OTE0RFx1NTNEOFx1OTFDRnswfQoKIyAwOiBzeW1ib2wKY29tcGlsZXIuZXJyLnZhci5taWdodC5ub3QuaGF2ZS5iZWVuLmluaXRpYWxpemVkPVx1NTNFRlx1ODBGRFx1NUMxQVx1NjcyQVx1NTIxRFx1NTlDQlx1NTMxNlx1NTNEOFx1OTFDRnswfQoKIyAwOiBzeW1ib2wKY29tcGlsZXIuZXJyLnZhci5ub3QuaW5pdGlhbGl6ZWQuaW4uZGVmYXVsdC5jb25zdHJ1Y3Rvcj1cdTUzRDhcdTkxQ0YgezB9IFx1NjcyQVx1NTcyOFx1OUVEOFx1OEJBNFx1Njc4NFx1OTAyMFx1NTY2OFx1NEUyRFx1NTIxRFx1NTlDQlx1NTMxNgoKIyAwOiBzeW1ib2wKY29tcGlsZXIuZXJyLnZhci5taWdodC5iZS5hc3NpZ25lZC5pbi5sb29wPVx1NTNFRlx1ODBGRFx1NTcyOCBsb29wIFx1NEUyRFx1NTIwNlx1OTE0RFx1NEU4Nlx1NTNEOFx1OTFDRnswfQoKIyAwOiBzeW1ib2wsIDE6IG1lc3NhZ2Ugc2VnbWVudApjb21waWxlci5lcnIudmFyYXJncy5pbnZhbGlkLnRydXN0bWUuYW5ubz17MH0gXHU2Q0U4XHU5MUNBXHU2NUUwXHU2NTQ4XHUzMDAyezF9CgojIDA6IHR5cGUKY29tcGlsZXIubWlzYy52YXJhcmdzLnRydXN0bWUub24ucmVpZmlhYmxlLnZhcmFyZ3M9VmFyYXJncyBcdTUxNDNcdTdEMjBcdTdDN0JcdTU3OEJ7MH1cdTUzRUZcdTUxNzdcdTRGNTNcdTUzMTZcdTMwMDIKCiMgMDogc3ltYm9sCmNvbXBpbGVyLm1pc2MudmFyYXJncy50cnVzdG1lLm9uLm5vbi52YXJhcmdzLm1ldGg9XHU2NUI5XHU2Q0Q1IHswfSBcdTRFMERcdTY2MkYgdmFyYXJncyBcdTY1QjlcdTZDRDVcdTMwMDIKCiMgMDogc3ltYm9sCmNvbXBpbGVyLm1pc2MudmFyYXJncy50cnVzdG1lLm9uLnZpcnR1YWwudmFyYXJncz1cdTVCOUVcdTRGOEJcdTY1QjlcdTZDRDUgezB9IFx1NjVFMlx1NEUwRFx1NjYyRlx1NjcwMFx1N0VDOFx1NzY4NCwgXHU0RTVGXHU0RTBEXHU2NjJGXHU3OUMxXHU2NzA5XHU3Njg0XHUzMDAyCgojIDA6IHN5bWJvbApjb21waWxlci5taXNjLnZhcmFyZ3MudHJ1c3RtZS5vbi52aXJ0dWFsLnZhcmFyZ3MuZmluYWwub25seT1cdTVCOUVcdTRGOEJcdTY1QjlcdTZDRDUgezB9IFx1NEUwRFx1NjYyRlx1NjcwMFx1N0VDOFx1NzY4NFx1MzAwMgoKIyAwOiB0eXBlLCAxOiBzeW1ib2wga2luZCwgMjogc3ltYm9sCmNvbXBpbGVyLm1pc2MuaW5hY2Nlc3NpYmxlLnZhcmFyZ3MudHlwZT1cdTVGNjJcdTVGMEYgdmFyYXJncyBcdTUxNDNcdTdEMjBcdTdDN0JcdTU3OEJ7MH1cdTY1RTBcdTZDRDVcdTRFQ0UgezF9IHsyfSBcdThGREJcdTg4NENcdThCQkZcdTk1RUUKCiMgSW4gdGhlIGZvbGxvd2luZyBzdHJpbmcsIHsxfSB3aWxsIGFsd2F5cyBiZSB0aGUgZGV0YWlsIG1lc3NhZ2UgZnJvbQojIGphdmEuaW8uSU9FeGNlcHRpb24uCiMgMDogc3ltYm9sLCAxOiBzdHJpbmcKY29tcGlsZXIuZXJyLmNsYXNzLmNhbnQud3JpdGU9XHU1MTk5XHU1MTY1ezB9XHU2NUY2XHU1MUZBXHU5NTE5OiB7MX0KCiMgSW4gdGhlIGZvbGxvd2luZyBzdHJpbmcsIHswfSBpcyB0aGUgbmFtZSBvZiB0aGUgY2xhc3MgaW4gdGhlIEphdmEgc291cmNlLgojIEl0IHJlYWxseSBzaG91bGQgYmUgdXNlZCB0d28gdGltZXMuLgojIDA6IG5hbWUKY29tcGlsZXIuZXJyLmNsYXNzLnB1YmxpYy5zaG91bGQuYmUuaW4uZmlsZT1cdTdDN0J7MH1cdTY2MkZcdTUxNkNcdTUxNzFcdTc2ODQsIFx1NUU5NFx1NTcyOFx1NTQwRFx1NEUzQSB7MH0uamF2YSBcdTc2ODRcdTY1ODdcdTRFRjZcdTRFMkRcdTU4RjBcdTY2MEUKCiMjIEFsbCBlcnJvcnMgd2hpY2ggZG8gbm90IHJlZmVyIHRvIGEgcGFydGljdWxhciBsaW5lIGluIHRoZSBzb3VyY2UgY29kZSBhcmUKIyMgcHJlY2VkZWQgYnkgdGhpcyBzdHJpbmcuCmNvbXBpbGVyLmVyci5lcnJvcj1cdTk1MTlcdThCRUY6IAoKIyBUaGUgZm9sbG93aW5nIGVycm9yIG1lc3NhZ2VzIGRvIG5vdCByZWZlciB0byBhIGxpbmUgaW4gdGhlIHNvdXJjZSBjb2RlLgpjb21waWxlci5lcnIuY2FudC5yZWFkLmZpbGU9XHU2NUUwXHU2Q0Q1XHU4QkZCXHU1M0Q2OiB7MH0KCiMgMDogc3RyaW5nCmNvbXBpbGVyLmVyci5wbHVnaW4ubm90LmZvdW5kPVx1NjI3RVx1NEUwRFx1NTIzMFx1NjNEMlx1NEVGNjogezB9CgojIDA6IHBhdGgKY29tcGlsZXIud2Fybi5sb2NuLnVua25vd24uZmlsZS5vbi5tb2R1bGUucGF0aD1cdTZBMjFcdTU3NTdcdThERUZcdTVGODRcdTRFMkRcdTc2ODRcdTY3MkFcdTc3RTVcdTY1ODdcdTRFRjY6IHswfQoKCiMgMDogcGF0aApjb21waWxlci5lcnIubG9jbi5iYWQubW9kdWxlLWluZm89XHU4QkZCXHU1M0Q2IHswfSBcdTRFMkRcdTc2ODQgbW9kdWxlLWluZm8uY2xhc3MgXHU2NUY2XHU1MUZBXHU3M0IwXHU5NUVFXHU5ODk4CgojIDA6IHBhdGgKY29tcGlsZXIuZXJyLmxvY24uY2FudC5yZWFkLmRpcmVjdG9yeT1cdTY1RTBcdTZDRDVcdThCRkJcdTUzRDZcdTc2RUVcdTVGNTUgezB9CgojIDA6IHBhdGgKY29tcGlsZXIuZXJyLmxvY24uY2FudC5yZWFkLmZpbGU9XHU2NUUwXHU2Q0Q1XHU4QkZCXHU1M0Q2XHU2NTg3XHU0RUY2IHswfQoKIyAwOiBwYXRoCmNvbXBpbGVyLmVyci5sb2NuLmNhbnQuZ2V0Lm1vZHVsZS5uYW1lLmZvci5qYXI9XHU2NUUwXHU2Q0Q1XHU3ODZFXHU1QjlBIHswfSBcdTc2ODRcdTZBMjFcdTU3NTdcdTU0MERcdTc5RjAKCiMgMDogcGF0aApjb21waWxlci5lcnIubXVsdGktbW9kdWxlLm91dGRpci5jYW5ub3QuYmUuZXhwbG9kZWQubW9kdWxlPVx1NTcyOFx1NTkxQVx1NkEyMVx1NTc1N1x1NkEyMVx1NUYwRlx1NEUwQiwgXHU4RjkzXHU1MUZBXHU3NkVFXHU1RjU1XHU0RTBEXHU4MEZEXHU2NjJGXHU1QzU1XHU1RjAwXHU3Njg0XHU2QTIxXHU1NzU3OiB7MH0KCiMgMDogcGF0aApjb21waWxlci53YXJuLm91dGRpci5pcy5pbi5leHBsb2RlZC5tb2R1bGU9XHU4RjkzXHU1MUZBXHU3NkVFXHU1RjU1XHU0RjREXHU0RThFXHU1QzU1XHU1RjAwXHU3Njg0XHU2QTIxXHU1NzU3XHU0RTJEOiB7MH0KCiMgMDogcGF0aApjb21waWxlci5lcnIubG9jbi5tb2R1bGUtaW5mby5ub3QuYWxsb3dlZC5vbi5wYXRjaC5wYXRoPVx1NTcyOFx1ODg2NVx1NEUwMVx1N0EwQlx1NUU4Rlx1OERFRlx1NUY4NFx1NEUyRFx1NEUwRFx1NTE0MVx1OEJCOCBtb2R1bGUtaW5mby5jbGFzczogezB9CgojIDA6IHN0cmluZwpjb21waWxlci5lcnIubG9jbi5pbnZhbGlkLmFyZy5mb3IueHBhdGNoPS0tcGF0Y2gtbW9kdWxlIFx1OTAwOVx1OTg3OVx1NzY4NFx1NTNDMlx1NjU3MFx1NjVFMFx1NjU0ODogezB9CgojIyMjIwoKIyBGYXRhbCBFcnJvcnMKCmNvbXBpbGVyLm1pc2MuZmF0YWwuZXJyLm5vLmphdmEubGFuZz1cdTgxRjRcdTU0N0RcdTk1MTlcdThCRUY6IFx1NTcyOFx1N0M3Qlx1OERFRlx1NUY4NFx1NjIxNlx1NUYxNVx1NUJGQ1x1N0M3Qlx1OERFRlx1NUY4NFx1NEUyRFx1NjI3RVx1NEUwRFx1NTIzMFx1N0EwQlx1NUU4Rlx1NTMwNSBqYXZhLmxhbmcKCmNvbXBpbGVyLm1pc2MuZmF0YWwuZXJyLmNhbnQubG9jYXRlLm1ldGg9XHU4MUY0XHU1NDdEXHU5NTE5XHU4QkVGOiBcdTYyN0VcdTRFMERcdTUyMzBcdTY1QjlcdTZDRDV7MH0KCmNvbXBpbGVyLm1pc2MuZmF0YWwuZXJyLmNhbnQubG9jYXRlLmZpZWxkPVx1ODFGNFx1NTQ3RFx1OTUxOVx1OEJFRjogXHU2MjdFXHU0RTBEXHU1MjMwXHU1QjU3XHU2QkI1ezB9Cgpjb21waWxlci5taXNjLmZhdGFsLmVyci5jYW50LmxvY2F0ZS5jdG9yPVx1ODFGNFx1NTQ3RFx1OTUxOVx1OEJFRjogXHU2MjdFXHU0RTBEXHU1MjMwezB9XHU3Njg0XHU2Nzg0XHU5MDIwXHU1NjY4Cgpjb21waWxlci5taXNjLmZhdGFsLmVyci5jYW50LmNsb3NlPVx1ODFGNFx1NTQ3RFx1OTUxOVx1OEJFRjogXHU2NUUwXHU2Q0Q1XHU1MTczXHU5NUVEXHU3RjE2XHU4QkQxXHU1NjY4XHU4RDQ0XHU2RTkwCgojIyMjIwoKIyMKIyMgbWlzY2VsbGFuZW91cyBzdHJpbmdzCiMjCgpjb21waWxlci5taXNjLmRpYW1vbmQuYW5vbnltb3VzLm1ldGhvZHMuaW1wbGljaXRseS5vdmVycmlkZT0oXHU3NTMxXHU0RThFIDw+LCBcdTUzM0ZcdTU0MERcdTdDN0JcdTRFMkRcdTU4RjBcdTY2MEVcdTc2ODRcdTZCQ0ZcdTRFMkFcdTk3NUVcdTc5QzFcdTY3MDlcdTY1QjlcdTZDRDVcdTVGQzVcdTk4N0JcdTg5ODZcdTc2RDZcdTYyMTZcdTVCOUVcdTczQjBcdThEODVcdTdDN0JcdTU3OEJcdTRFMkRcdTc2ODRcdTY1QjlcdTZDRDUpCgpjb21waWxlci5taXNjLnNvdXJjZS51bmF2YWlsYWJsZT0oXHU2RTkwXHU0RTBEXHU1M0VGXHU3NTI4KQoKY29tcGlsZXIubWlzYy5iYXNlLm1lbWJlcnNoaXA9XHU2MEE4XHU3Njg0XHU2MjQwXHU2NzA5XHU1N0ZBXHU3QzdCXHU5MEZEXHU1QzVFXHU0RThFXHU2MjExXHU0RUVDCgojIDA6IHN0cmluZywgMTogc3RyaW5nLCAyOiBib29sZWFuCmNvbXBpbGVyLm1pc2MueC5wcmludC5wcm9jZXNzb3IuaW5mbz1cdTU5MDRcdTc0MDZcdTdBMEJcdTVFOEZ7MH1cdTRFMEV7MX1cdTUzMzlcdTkxNERcdTVFNzZcdThGRDRcdTU2REV7Mn1cdTMwMDIKCiMgMDogbnVtYmVyLCAxOiBzdHJpbmcsIDI6IHNldCBvZiBzeW1ib2wsIDM6IGJvb2xlYW4KY29tcGlsZXIubWlzYy54LnByaW50LnJvdW5kcz1cdTVGQUFcdTczQUYgezB9OlxuXHRcdThGOTNcdTUxNjVcdTY1ODdcdTRFRjY6IHsxfVxuXHRcdTZDRThcdTkxQ0E6IHsyfVxuXHRcdTY3MDBcdTU0MEVcdTRFMDBcdTRFMkFcdTVGQUFcdTczQUY6IHszfQoKIyAwOiBmaWxlIG5hbWUKY29tcGlsZXIud2Fybi5maWxlLmZyb20uZnV0dXJlPVx1NjU4N1x1NEVGNiB7MH0gXHU3Njg0XHU0RkVFXHU2NTM5XHU2NUU1XHU2NzFGXHU2NjJGXHU2NzJBXHU2NzY1XHU3Njg0XHU2NUU1XHU2NzFGCgojIyMjIwoKIyMgVGhlIGZvbGxvd2luZyBzdHJpbmcgd2lsbCBhcHBlYXIgYmVmb3JlIGFsbCBtZXNzYWdlcyBrZXllZCBhczoKIyMgImNvbXBpbGVyLm5vdGUiLgoKY29tcGlsZXIubm90ZS5jb21wcmVzc2VkLmRpYWdzPVx1NjdEMFx1NEU5Qlx1NkQ4OFx1NjA2Rlx1NURGMlx1N0VDRlx1OEZDN1x1N0I4MFx1NTMxNjsgXHU4QkY3XHU0RjdGXHU3NTI4IC1YZGlhZ3M6dmVyYm9zZSBcdTkxQ0RcdTY1QjBcdTdGMTZcdThCRDFcdTRFRTVcdTgzQjdcdTVGOTdcdTVCOENcdTY1NzRcdThGOTNcdTUxRkEKCiMgMDogYm9vbGVhbiwgMTogc3ltYm9sCmNvbXBpbGVyLm5vdGUubGFtYmRhLnN0YXQ9XHU4RjZDXHU2MzYyIGxhbWJkYSBcdTg4NjhcdThGQkVcdTVGMEZcblx1NjZGRlx1NEVFMyBtZXRhZmFjdG9yeSA9IHswfVxuXHU1NDA4XHU2MjEwXHU2NUI5XHU2Q0Q1ID0gezF9CgojIDA6IGJvb2xlYW4sIDE6IHVudXNlZApjb21waWxlci5ub3RlLm1yZWYuc3RhdD1cdThGNkNcdTYzNjJcdTY1QjlcdTZDRDVcdTVGMTVcdTc1Mjhcblx1NjZGRlx1NEVFMyBtZXRhZmFjdG9yeSA9IHswfVxuCiMgMDogYm9vbGVhbiwgMTogc3ltYm9sCmNvbXBpbGVyLm5vdGUubXJlZi5zdGF0LjE9XHU4RjZDXHU2MzYyXHU2NUI5XHU2Q0Q1XHU1RjE1XHU3NTI4XG5cdTY2RkZcdTRFRTMgbWV0YWZhY3RvcnkgPSB7MH1cbmJyaWRnZSBcdTY1QjlcdTZDRDUgPSB7MX0KCmNvbXBpbGVyLm5vdGUubm90ZT1cdTZDRTg6IAoKIyAwOiBmaWxlIG5hbWUKY29tcGlsZXIubm90ZS5kZXByZWNhdGVkLmZpbGVuYW1lPXswfVx1NEY3Rlx1NzUyOFx1NjIxNlx1ODk4Nlx1NzZENlx1NEU4Nlx1NURGMlx1OEZDN1x1NjVGNlx1NzY4NCBBUElcdTMwMDIKCmNvbXBpbGVyLm5vdGUuZGVwcmVjYXRlZC5wbHVyYWw9XHU2N0QwXHU0RTlCXHU4RjkzXHU1MTY1XHU2NTg3XHU0RUY2XHU0RjdGXHU3NTI4XHU2MjE2XHU4OTg2XHU3NkQ2XHU0RTg2XHU1REYyXHU4RkM3XHU2NUY2XHU3Njg0IEFQSVx1MzAwMgoKIyBUaGUgZm9sbG93aW5nIHN0cmluZyBtYXkgYXBwZWFyIGFmdGVyIG9uZSBvZiB0aGUgYWJvdmUgZGVwcmVjYXRpb24KIyBtZXNzYWdlcy4KY29tcGlsZXIubm90ZS5kZXByZWNhdGVkLnJlY29tcGlsZT1cdTY3MDlcdTUxNzNcdThCRTZcdTdFQzZcdTRGRTFcdTYwNkYsIFx1OEJGN1x1NEY3Rlx1NzUyOCAtWGxpbnQ6ZGVwcmVjYXRpb24gXHU5MUNEXHU2NUIwXHU3RjE2XHU4QkQxXHUzMDAyCgojIDA6IGZpbGUgbmFtZQpjb21waWxlci5ub3RlLmRlcHJlY2F0ZWQuZmlsZW5hbWUuYWRkaXRpb25hbD17MH1cdThGRDhcdTRGN0ZcdTc1MjhcdTYyMTZcdTg5ODZcdTc2RDZcdTRFODZcdTVERjJcdThGQzdcdTY1RjZcdTc2ODQgQVBJXHUzMDAyCgpjb21waWxlci5ub3RlLmRlcHJlY2F0ZWQucGx1cmFsLmFkZGl0aW9uYWw9XHU2N0QwXHU0RTlCXHU4RjkzXHU1MTY1XHU2NTg3XHU0RUY2XHU4RkQ4XHU0RjdGXHU3NTI4XHU2MjE2XHU4OTg2XHU3NkQ2XHU0RTg2XHU1REYyXHU4RkM3XHU2NUY2XHU3Njg0IEFQSVx1MzAwMgoKIyAwOiBmaWxlIG5hbWUKY29tcGlsZXIubm90ZS5yZW1vdmFsLmZpbGVuYW1lPXswfSBcdTRGN0ZcdTc1MjhcdTYyMTZcdTg5ODZcdTc2RDZcdTRFODZcdTY4MDdcdThCQjBcdTRFM0FcdTVGODVcdTUyMjBcdTk2NjRcdTc2ODRcdTVERjJcdThGQzdcdTY1RjYgQVBJXHUzMDAyCgpjb21waWxlci5ub3RlLnJlbW92YWwucGx1cmFsPVx1NjdEMFx1NEU5Qlx1OEY5M1x1NTE2NVx1NjU4N1x1NEVGNlx1NEY3Rlx1NzUyOFx1NjIxNlx1ODk4Nlx1NzZENlx1NEU4Nlx1NjgwN1x1OEJCMFx1NEUzQVx1NUY4NVx1NTIyMFx1OTY2NFx1NzY4NFx1NURGMlx1OEZDN1x1NjVGNiBBUElcdTMwMDIKCiMgVGhlIGZvbGxvd2luZyBzdHJpbmcgbWF5IGFwcGVhciBhZnRlciBvbmUgb2YgdGhlIGFib3ZlIHJlbW92YWwgbWVzc2FnZXMuCmNvbXBpbGVyLm5vdGUucmVtb3ZhbC5yZWNvbXBpbGU9XHU2NzA5XHU1MTczXHU4QkU2XHU3RUM2XHU0RkUxXHU2MDZGLCBcdThCRjdcdTRGN0ZcdTc1MjggLVhsaW50OnJlbW92YWwgXHU5MUNEXHU2NUIwXHU3RjE2XHU4QkQxXHUzMDAyCgojIDA6IGZpbGUgbmFtZQpjb21waWxlci5ub3RlLnJlbW92YWwuZmlsZW5hbWUuYWRkaXRpb25hbD17MH0gXHU5ODlEXHU1OTE2XHU0RjdGXHU3NTI4XHU2MjE2XHU4OTg2XHU3NkQ2XHU0RTg2XHU2ODA3XHU4QkIwXHU0RTNBXHU1Rjg1XHU1MjIwXHU5NjY0XHU3Njg0XHU1REYyXHU4RkM3XHU2NUY2IEFQSVx1MzAwMgoKY29tcGlsZXIubm90ZS5yZW1vdmFsLnBsdXJhbC5hZGRpdGlvbmFsPVx1NjdEMFx1NEU5Qlx1OEY5M1x1NTE2NVx1NjU4N1x1NEVGNlx1OTg5RFx1NTkxNlx1NEY3Rlx1NzUyOFx1NjIxNlx1ODk4Nlx1NzZENlx1NEU4Nlx1NjgwN1x1OEJCMFx1NEUzQVx1NUY4NVx1NTIyMFx1OTY2NFx1NzY4NFx1NURGMlx1OEZDN1x1NjVGNiBBUElcdTMwMDIKCiMgMDogZmlsZSBuYW1lCmNvbXBpbGVyLm5vdGUudW5jaGVja2VkLmZpbGVuYW1lPXswfVx1NEY3Rlx1NzUyOFx1NEU4Nlx1NjcyQVx1N0VDRlx1NjhDMFx1NjdFNVx1NjIxNlx1NEUwRFx1NUI4OVx1NTE2OFx1NzY4NFx1NjRDRFx1NEY1Q1x1MzAwMgoKY29tcGlsZXIubm90ZS51bmNoZWNrZWQucGx1cmFsPVx1NjdEMFx1NEU5Qlx1OEY5M1x1NTE2NVx1NjU4N1x1NEVGNlx1NEY3Rlx1NzUyOFx1NEU4Nlx1NjcyQVx1N0VDRlx1NjhDMFx1NjdFNVx1NjIxNlx1NEUwRFx1NUI4OVx1NTE2OFx1NzY4NFx1NjRDRFx1NEY1Q1x1MzAwMgoKIyBUaGUgZm9sbG93aW5nIHN0cmluZyBtYXkgYXBwZWFyIGFmdGVyIG9uZSBvZiB0aGUgYWJvdmUgdW5jaGVja2VkIG1lc3NhZ2VzLgpjb21waWxlci5ub3RlLnVuY2hlY2tlZC5yZWNvbXBpbGU9XHU2NzA5XHU1MTczXHU4QkU2XHU3RUM2XHU0RkUxXHU2MDZGLCBcdThCRjdcdTRGN0ZcdTc1MjggLVhsaW50OnVuY2hlY2tlZCBcdTkxQ0RcdTY1QjBcdTdGMTZcdThCRDFcdTMwMDIKCiMgMDogZmlsZSBuYW1lCmNvbXBpbGVyLm5vdGUudW5jaGVja2VkLmZpbGVuYW1lLmFkZGl0aW9uYWw9ezB9XHU4RkQ4XHU2NzA5XHU2NzJBXHU3RUNGXHU2OEMwXHU2N0U1XHU2MjE2XHU0RTBEXHU1Qjg5XHU1MTY4XHU3Njg0XHU2NENEXHU0RjVDXHUzMDAyCgpjb21waWxlci5ub3RlLnVuY2hlY2tlZC5wbHVyYWwuYWRkaXRpb25hbD1cdTY3RDBcdTRFOUJcdThGOTNcdTUxNjVcdTY1ODdcdTRFRjZcdThGRDhcdTRGN0ZcdTc1MjhcdTRFODZcdTY3MkFcdTdFQ0ZcdTY4QzBcdTY3RTVcdTYyMTZcdTRFMERcdTVCODlcdTUxNjhcdTc2ODRcdTY0Q0RcdTRGNUNcdTMwMDIKCiMgTm90ZXMgcmVsYXRlZCB0byBhbm5vdGF0aW9uIHByb2Nlc3NpbmcKCiMgUHJpbnQgYSBjbGllbnQtZ2VuZXJhdGVkIG5vdGU7IGFzc3VtZWQgdG8gYmUgbG9jYWxpemVkLCBubyB0cmFuc2xhdGlvbiByZXF1aXJlZAojIDA6IHN0cmluZwpjb21waWxlci5ub3RlLnByb2MubWVzc2FnZXI9ezB9CgojIyMjIwoKIyAwOiBudW1iZXIKY29tcGlsZXIubWlzYy5jb3VudC5lcnJvcj17MH0gXHU0RTJBXHU5NTE5XHU4QkVGCgojIDA6IG51bWJlcgpjb21waWxlci5taXNjLmNvdW50LmVycm9yLnBsdXJhbD17MH0gXHU0RTJBXHU5NTE5XHU4QkVGCgojIDA6IG51bWJlcgpjb21waWxlci5taXNjLmNvdW50Lndhcm49ezB9IFx1NEUyQVx1OEI2Nlx1NTQ0QQoKIyAwOiBudW1iZXIKY29tcGlsZXIubWlzYy5jb3VudC53YXJuLnBsdXJhbD17MH0gXHU0RTJBXHU4QjY2XHU1NDRBCgpjb21waWxlci5taXNjLnZlcnNpb24ubm90LmF2YWlsYWJsZT0oXHU3MjQ4XHU2NzJDXHU0RkUxXHU2MDZGXHU0RTBEXHU1M0VGXHU3NTI4KQoKIyMgZXh0cmEgb3V0cHV0IHdoZW4gdXNpbmcgLXZlcmJvc2UgKEphdmFDb21waWxlcikKCiMgMDogc3ltYm9sCmNvbXBpbGVyLm1pc2MudmVyYm9zZS5jaGVja2luZy5hdHRyaWJ1dGlvbj1bXHU2QjYzXHU1NzI4XHU2OEMwXHU2N0U1ezB9XQoKIyAwOiBzdHJpbmcKY29tcGlsZXIubWlzYy52ZXJib3NlLnBhcnNpbmcuZG9uZT1bXHU4OUUzXHU2NzkwXHU1REYyXHU1QjhDXHU2MjEwLCBcdTc1MjhcdTY1RjYgezB9IFx1NkJFQlx1NzlEMl0KCiMgMDogZmlsZSBuYW1lCmNvbXBpbGVyLm1pc2MudmVyYm9zZS5wYXJzaW5nLnN0YXJ0ZWQ9W1x1ODlFM1x1Njc5MFx1NUYwMFx1NTlDQlx1NjVGNlx1OTVGNCB7MH1dCgojIDA6IHN0cmluZwpjb21waWxlci5taXNjLnZlcmJvc2UudG90YWw9W1x1NTE3MSB7MH0gXHU2QkVCXHU3OUQyXQoKIyAwOiBmaWxlIG5hbWUKY29tcGlsZXIubWlzYy52ZXJib3NlLndyb3RlLmZpbGU9W1x1NURGMlx1NTE5OVx1NTE2NXswfV0KCiMjIGV4dHJhIG91dHB1dCB3aGVuIHVzaW5nIC12ZXJib3NlIChjb2RlL0NsYXNzUmVhZGVyKQojIDA6IHN0cmluZwpjb21waWxlci5taXNjLnZlcmJvc2UubG9hZGluZz1bXHU2QjYzXHU1NzI4XHU1MkEwXHU4RjdEezB9XQoKIyAwOiBzdHJpbmcKY29tcGlsZXIubWlzYy52ZXJib3NlLnNvdXJjZXBhdGg9W1x1NkU5MFx1NjU4N1x1NEVGNlx1NzY4NFx1NjQxQ1x1N0QyMlx1OERFRlx1NUY4NDogezB9XQoKIyAwOiBzdHJpbmcKY29tcGlsZXIubWlzYy52ZXJib3NlLmNsYXNzcGF0aD1bXHU3QzdCXHU2NTg3XHU0RUY2XHU3Njg0XHU2NDFDXHU3RDIyXHU4REVGXHU1Rjg0OiB7MH1dCgojIyBleHRyYSBvdXRwdXQgd2hlbiB1c2luZyAtcHJvbXB0ICh1dGlsL0xvZykKY29tcGlsZXIubWlzYy5yZXN1bWUuYWJvcnQ9XHU3RUU3XHU3RUVEKFIpLCBcdTY1M0VcdTVGMDMoQSk+CgojIyMjIwoKIyMKIyMgd2FybmluZ3MKIyMKCiMjIEFsbCB3YXJuaW5nIG1lc3NhZ2VzIGFyZSBwcmVjZWRlZCBieSB0aGUgZm9sbG93aW5nIHN0cmluZy4KY29tcGlsZXIud2Fybi53YXJuaW5nPVx1OEI2Nlx1NTQ0QTogCgojIyBXYXJuaW5nIG1lc3NhZ2VzIG1heSBhbHNvIGluY2x1ZGUgdGhlIGZvbGxvd2luZyBwcmVmaXggdG8gaWRlbnRpZnkgYQojIyBsaW50IG9wdGlvbgojIDA6IG9wdGlvbiBuYW1lCmNvbXBpbGVyLndhcm4ubGludE9wdGlvbj1bezB9XSAKCiMgMDogc3ltYm9sCmNvbXBpbGVyLndhcm4uY29uc3RhbnQuU1ZVSUQ9c2VyaWFsVmVyc2lvblVJRCBcdTU3MjhcdTdDN0J7MH1cdTRFMkRcdTVGQzVcdTk4N0JcdTY2MkZcdTVFMzhcdTkxQ0YKCiMgMDogZmlsZSBuYW1lCmNvbXBpbGVyLndhcm4uZGlyLnBhdGguZWxlbWVudC5ub3QuZm91bmQ9XHU5NTE5XHU4QkVGXHU3Njg0XHU4REVGXHU1Rjg0XHU1MTQzXHU3RDIwICJ7MH0iOiBcdTZDQTFcdTY3MDlcdThGRDlcdTc5Q0RcdTc2RUVcdTVGNTUKCiMgMDogZmlsZSBuYW1lCmNvbXBpbGVyLndhcm4uZGlyLnBhdGguZWxlbWVudC5ub3QuZGlyZWN0b3J5PVx1OTUxOVx1OEJFRlx1NzY4NFx1OERFRlx1NUY4NFx1NTE0M1x1N0QyMCAiezB9IjogXHU0RTBEXHU2NjJGXHU3NkVFXHU1RjU1Cgpjb21waWxlci53YXJuLmZpbmFsbHkuY2Fubm90LmNvbXBsZXRlPWZpbmFsbHkgXHU1QjUwXHU1M0U1XHU2NUUwXHU2Q0Q1XHU2QjYzXHU1RTM4XHU1QjhDXHU2MjEwCgojIDA6IG5hbWUKY29tcGlsZXIud2Fybi5wb29yLmNob2ljZS5mb3IubW9kdWxlLm5hbWU9XHU2QTIxXHU1NzU3XHU1NDBEXHU3OUYwIHswfSBcdTVFOTRcdTkwN0ZcdTUxNERcdTRFRTVcdTY1NzBcdTVCNTdcdTdFRDNcdTVDM0UKCiMgMDogc3ltYm9sLCAxOiBzeW1ib2wKY29tcGlsZXIud2Fybi5oYXMuYmVlbi5kZXByZWNhdGVkPXsxfVx1NEUyRFx1NzY4NHswfVx1NURGMlx1OEZDN1x1NjVGNgoKIyAwOiBzeW1ib2wsIDE6IHN5bWJvbApjb21waWxlci53YXJuLmhhcy5iZWVuLmRlcHJlY2F0ZWQuZm9yLnJlbW92YWw9ezF9IFx1NEUyRFx1NzY4NCB7MH0gXHU1REYyXHU4RkM3XHU2NUY2LCBcdTRFMTRcdTY4MDdcdThCQjBcdTRFM0FcdTVGODVcdTUyMjBcdTk2NjQKCiMgMDogc3ltYm9sCmNvbXBpbGVyLndhcm4uaGFzLmJlZW4uZGVwcmVjYXRlZC5tb2R1bGU9XHU2QTIxXHU1NzU3IHswfSBcdTVERjJcdThGQzdcdTY1RjYKCiMgMDogc3ltYm9sCmNvbXBpbGVyLndhcm4uaGFzLmJlZW4uZGVwcmVjYXRlZC5mb3IucmVtb3ZhbC5tb2R1bGU9XHU2QTIxXHU1NzU3IHswfSBcdTVERjJcdThGQzdcdTY1RjYsIFx1NEUxNFx1NjgwN1x1OEJCMFx1NEUzQVx1NUY4NVx1NTIyMFx1OTY2NAoKIyAwOiBzeW1ib2wKY29tcGlsZXIud2Fybi5zdW4ucHJvcHJpZXRhcnk9ezB9XHU2NjJGXHU1MTg1XHU5MEU4XHU0RTEzXHU3NTI4IEFQSSwgXHU1M0VGXHU4MEZEXHU0RjFBXHU1NzI4XHU2NzJBXHU2NzY1XHU1M0QxXHU4ODRDXHU3MjQ4XHU0RTJEXHU1MjIwXHU5NjY0Cgpjb21waWxlci53YXJuLmlsbGVnYWwuY2hhci5mb3IuZW5jb2Rpbmc9XHU3RjE2XHU3ODAxezB9XHU3Njg0XHU0RTBEXHU1M0VGXHU2NjIwXHU1QzA0XHU1QjU3XHU3QjI2CgojIDA6IHN5bWJvbApjb21waWxlci53YXJuLmltcHJvcGVyLlNWVUlEPVx1NUZDNVx1OTg3Qlx1NTcyOFx1N0M3QnswfVx1NEUyRFx1NUMwNiBzZXJpYWxWZXJzaW9uVUlEIFx1NThGMFx1NjYwRVx1NEUzQSBzdGF0aWMgZmluYWwKCiMgMDogdHlwZSwgMTogdHlwZQpjb21waWxlci53YXJuLmluZXhhY3Qubm9uLXZhcmFyZ3MuY2FsbD1cdTY3MDBcdTU0MEVcdTRFMDBcdTRFMkFcdTUzQzJcdTY1NzBcdTRGN0ZcdTc1MjhcdTRFODZcdTRFMERcdTUxQzZcdTc4NkVcdTc2ODRcdTUzRDhcdTkxQ0ZcdTdDN0JcdTU3OEJcdTc2ODQgdmFyYXJncyBcdTY1QjlcdTZDRDVcdTc2ODRcdTk3NUUgdmFyYXJncyBcdThDMDNcdTc1Mjg7IFxuXHU1QkY5XHU0RThFIHZhcmFyZ3MgXHU4QzAzXHU3NTI4LCBcdTVFOTRcdTRGN0ZcdTc1MjggezB9XG5cdTVCRjlcdTRFOEVcdTk3NUUgdmFyYXJncyBcdThDMDNcdTc1MjgsIFx1NUU5NFx1NEY3Rlx1NzUyOCB7MX0sIFx1OEZEOVx1NjgzN1x1NEU1Rlx1NTNFRlx1NEVFNVx1NjI5MVx1NTIzNlx1NkI2NFx1OEI2Nlx1NTQ0QQoKIyAwOiBsaXN0IG9mIHR5cGUKY29tcGlsZXIud2Fybi51bnJlYWNoYWJsZS5jYXRjaD1jYXRjaCBcdTVCNTBcdTUzRTVcdTY1RTBcdTZDRDVcdThCQkZcdTk1RUVcblx1NURGMlx1NjM1NVx1ODNCN1x1NTIzMFx1NjI5Qlx1NTFGQVx1NzY4NFx1N0M3Qlx1NTc4QnswfQoKIyAwOiBsaXN0IG9mIHR5cGUKY29tcGlsZXIud2Fybi51bnJlYWNoYWJsZS5jYXRjaC4xPWNhdGNoIFx1NUI1MFx1NTNFNVx1NjVFMFx1NkNENVx1OEJCRlx1OTVFRVxuXHU1REYyXHU2MzU1XHU4M0I3XHU1MjMwXHU2MjlCXHU1MUZBXHU3Njg0XHU3QzdCXHU1NzhCezB9CgojIDA6IHN5bWJvbApjb21waWxlci53YXJuLmxvbmcuU1ZVSUQ9c2VyaWFsVmVyc2lvblVJRCBcdTU3MjhcdTdDN0J7MH1cdTRFMkRcdTVGQzVcdTk4N0JcdTY2MkYgbG9uZyBcdTdDN0JcdTU3OEIKCiMgMDogc3ltYm9sCmNvbXBpbGVyLndhcm4ubWlzc2luZy5TVlVJRD1cdTUzRUZcdTVFOEZcdTUyMTdcdTUzMTZcdTdDN0J7MH1cdTZDQTFcdTY3MDkgc2VyaWFsVmVyc2lvblVJRCBcdTc2ODRcdTVCOUFcdTRFNDkKCiMgMDogc3ltYm9sLCAxOiBzeW1ib2wsIDI6IHN5bWJvbCwgMzogc3ltYm9sCmNvbXBpbGVyLndhcm4ucG90ZW50aWFsbHkuYW1iaWd1b3VzLm92ZXJsb2FkPXsxfSBcdTRFMkRcdTc2ODQgezB9IFx1NTNFRlx1ODBGRFx1NEUwRSB7M30gXHU0RTJEXHU3Njg0IHsyfSBcdTZERjdcdTZEQzYKCiMgMDogbWVzc2FnZSBzZWdtZW50CmNvbXBpbGVyLndhcm4ub3ZlcnJpZGUudmFyYXJncy5taXNzaW5nPXswfTsgXHU4OEFCXHU4OTg2XHU3NkQ2XHU3Njg0XHU2NUI5XHU2Q0Q1XHU2Q0ExXHU2NzA5ICcnLi4uJycKCiMgMDogbWVzc2FnZSBzZWdtZW50CmNvbXBpbGVyLndhcm4ub3ZlcnJpZGUudmFyYXJncy5leHRyYT17MH07IFx1ODk4Nlx1NzZENlx1NzY4NFx1NjVCOVx1NkNENVx1N0YzQVx1NUMxMSAnJy4uLicnCgpjb21waWxlci53YXJuLm92ZXJyaWRlLmJyaWRnZT17MH07IFx1ODhBQlx1ODk4Nlx1NzZENlx1NzY4NFx1NjVCOVx1NkNENVx1NEUzQSBicmlkZ2UgXHU2NUI5XHU2Q0Q1CgojIDA6IHN5bWJvbApjb21waWxlci53YXJuLnBrZy1pbmZvLmFscmVhZHkuc2Vlbj1cdTVERjJcdTYyN0VcdTUyMzBcdTdBMEJcdTVFOEZcdTUzMDV7MH1cdTc2ODQgcGFja2FnZS1pbmZvLmphdmEgXHU2NTg3XHU0RUY2CgojIDA6IGZpbGUgbmFtZQpjb21waWxlci53YXJuLnBhdGguZWxlbWVudC5ub3QuZm91bmQ9XHU5NTE5XHU4QkVGXHU3Njg0XHU4REVGXHU1Rjg0XHU1MTQzXHU3RDIwICJ7MH0iOiBcdTZDQTFcdTY3MDlcdThGRDlcdTc5Q0RcdTY1ODdcdTRFRjZcdTYyMTZcdTc2RUVcdTVGNTUKCmNvbXBpbGVyLndhcm4ucG9zc2libGUuZmFsbC10aHJvdWdoLmludG8uY2FzZT1cdTUzRUZcdTgwRkRcdTY1RTBcdTZDRDVcdTVCOUVcdTczQjAgY2FzZQoKIyAwOiB0eXBlCmNvbXBpbGVyLndhcm4ucmVkdW5kYW50LmNhc3Q9XHU1MUZBXHU3M0IwXHU1MTk3XHU0RjU5XHU3Njg0XHU1MjMwezB9XHU3Njg0XHU4RjZDXHU2MzYyCgojIDA6IG51bWJlcgpjb21waWxlci53YXJuLnBvc2l0aW9uLm92ZXJmbG93PVx1ODg0QyB7MH0gXHU1OTA0XHU3Njg0XHU0RjREXHU3RjZFXHU3RjE2XHU3ODAxXHU2RUEyXHU1MUZBCgojIDA6IGZpbGUgbmFtZSwgMTogbnVtYmVyLCAyOiBudW1iZXIKY29tcGlsZXIud2Fybi5iaWcubWFqb3IudmVyc2lvbj17MH06IFx1NEUzQlx1NzI0OFx1NjcyQyB7MX0gXHU2QkQ0IHsyfSBcdTY1QjAsIFx1NkI2NFx1N0YxNlx1OEJEMVx1NTY2OFx1NjUyRlx1NjMwMVx1NjcwMFx1NjVCMFx1NzY4NFx1NEUzQlx1NzI0OFx1NjcyQ1x1MzAwMlxuXHU1RUZBXHU4QkFFXHU1MzQ3XHU3RUE3XHU2QjY0XHU3RjE2XHU4QkQxXHU1NjY4XHUzMDAyCgojIDA6IHN5bWJvbCBraW5kLCAxOiBzeW1ib2wKY29tcGlsZXIud2Fybi5zdGF0aWMubm90LnF1YWxpZmllZC5ieS50eXBlPXN0YXRpYyB7MH1cdTVFOTRcdTc1MzFcdTdDN0JcdTU3OEJcdTU0MERcdTc5RjB7MX1cdTgwMENcdTRFMERcdTY2MkZcdTg4NjhcdThGQkVcdTVGMEZcdTk2NTBcdTVCOUEKCiMgMDogc3RyaW5nCmNvbXBpbGVyLndhcm4uc291cmNlLm5vLmJvb3RjbGFzc3BhdGg9XHU2NzJBXHU0RTBFIC1zb3VyY2UgezB9IFx1NEUwMFx1OEQ3N1x1OEJCRVx1N0Y2RVx1NUYxNVx1NUJGQ1x1N0M3Qlx1OERFRlx1NUY4NAoKIyAwOiBzdHJpbmcKY29tcGlsZXIud2Fybi5vcHRpb24ub2Jzb2xldGUuc291cmNlPVx1NkU5MFx1NTAzQ3swfVx1NURGMlx1OEZDN1x1NjVGNiwgXHU1QzA2XHU1NzI4XHU2NzJBXHU2NzY1XHU2MjQwXHU2NzA5XHU1M0QxXHU4ODRDXHU3MjQ4XHU0RTJEXHU1MjIwXHU5NjY0CgojIDA6IHN0cmluZwpjb21waWxlci53YXJuLm9wdGlvbi5vYnNvbGV0ZS50YXJnZXQ9XHU3NkVFXHU2ODA3XHU1MDNDezB9XHU1REYyXHU4RkM3XHU2NUY2LCBcdTVDMDZcdTU3MjhcdTY3MkFcdTY3NjVcdTYyNDBcdTY3MDlcdTUzRDFcdTg4NENcdTcyNDhcdTRFMkRcdTUyMjBcdTk2NjQKCiMgMDogc3RyaW5nLCAxOiBzdHJpbmcKY29tcGlsZXIuZXJyLm9wdGlvbi5yZW1vdmVkLnNvdXJjZT1cdTRFMERcdTUxOERcdTY1MkZcdTYzMDFcdTZFOTBcdTkwMDlcdTk4NzkgezB9XHUzMDAyXHU4QkY3XHU0RjdGXHU3NTI4IHsxfSBcdTYyMTZcdTY2RjRcdTlBRDhcdTcyNDhcdTY3MkNcdTMwMDIKCiMgMDogc3RyaW5nLCAxOiBzdHJpbmcKY29tcGlsZXIuZXJyLm9wdGlvbi5yZW1vdmVkLnRhcmdldD1cdTRFMERcdTUxOERcdTY1MkZcdTYzMDFcdTc2RUVcdTY4MDdcdTkwMDlcdTk4NzkgezB9XHUzMDAyXHU4QkY3XHU0RjdGXHU3NTI4IHsxfSBcdTYyMTZcdTY2RjRcdTlBRDhcdTcyNDhcdTY3MkNcdTMwMDIKCmNvbXBpbGVyLndhcm4ub3B0aW9uLm9ic29sZXRlLnN1cHByZXNzaW9uPVx1ODk4MVx1OTY5MFx1ODVDRlx1NjcwOVx1NTE3M1x1NURGMlx1OEZDN1x1NjVGNlx1OTAwOVx1OTg3OVx1NzY4NFx1OEI2Nlx1NTQ0QSwgXHU4QkY3XHU0RjdGXHU3NTI4IC1YbGludDotb3B0aW9uc1x1MzAwMgoKIyAwOiBuYW1lLCAxOiBudW1iZXIsIDI6IG51bWJlciwgMzogbnVtYmVyLCA0OiBudW1iZXIKY29tcGlsZXIud2Fybi5mdXR1cmUuYXR0cj17MX0uezJ9IFx1NzI0OFx1N0M3Qlx1NjU4N1x1NEVGNlx1NEUyRFx1NUYxNVx1NTE2NVx1NzY4NCB7MH0gXHU1QzVFXHU2MDI3XHU1NzI4IHszfS57NH0gXHU3MjQ4XHU3QzdCXHU2NTg3XHU0RUY2XHU0RTJEXHU4OEFCXHU1RkZEXHU3NTY1CgojIFdhcm5pbmdzIHJlbGF0ZWQgdG8gYW5ub3RhdGlvbiBwcm9jZXNzaW5nCiMgMDogc3RyaW5nCmNvbXBpbGVyLndhcm4ucHJvYy5wYWNrYWdlLmRvZXMubm90LmV4aXN0PVx1N0EwQlx1NUU4Rlx1NTMwNXswfVx1NEUwRFx1NUI1OFx1NTcyOAoKIyAwOiBuYW1lCmNvbXBpbGVyLndhcm4ucHJvYy5maWxlLnJlb3BlbmluZz1cdTVDMURcdThCRDVcdTU5MUFcdTZCMjFcdTRFM0EgJyd7MH0nJyBcdTUyMUJcdTVFRkFcdTY1ODdcdTRFRjYKCiMgMDogbmFtZQpjb21waWxlci53YXJuLnByb2MudHlwZS5hbHJlYWR5LmV4aXN0cz1cdTdDN0JcdTU3OEIgJyd7MH0nJyBcdTc2ODRcdTY1ODdcdTRFRjZcdTVERjJcdTdFQ0ZcdTVCNThcdTU3MjhcdTRFOEVcdTZFOTBcdThERUZcdTVGODRcdTYyMTZcdTdDN0JcdThERUZcdTVGODRcdTRFMkQKCiMgMDogbmFtZQpjb21waWxlci53YXJuLnByb2MudHlwZS5yZWNyZWF0ZT1cdTVDMURcdThCRDVcdTU5MUFcdTZCMjFcdTUyMUJcdTVFRkFcdTdDN0JcdTU3OEIgJyd7MH0nJyBcdTc2ODRcdTY1ODdcdTRFRjYKCiMgMDogc3RyaW5nCmNvbXBpbGVyLndhcm4ucHJvYy5pbGxlZ2FsLmZpbGUubmFtZT1cdTY1RTBcdTZDRDVcdTUyMUJcdTVFRkFcdTVFMjZcdTY3MDlcdTk3NUVcdTZDRDVcdTU0MERcdTc5RjAgJyd7MH0nJyBcdTc2ODRcdTY1ODdcdTRFRjZcdTMwMDIKCiMgMDogc3RyaW5nLCAxOiBzdHJpbmcKY29tcGlsZXIud2Fybi5wcm9jLnN1c3BpY2lvdXMuY2xhc3MubmFtZT1cdTZCNjNcdTU3MjhcdTRFM0FcdTU0MERcdTc5RjBcdTRFRTV7MX1cdTdFRDNcdTVDM0VcdTc2ODRcdTdDN0JcdTU3OEJcdTUyMUJcdTVFRkFcdTY1ODdcdTRFRjY6ICcnezB9JycKCiMgMDogbmFtZQpjb21waWxlci53YXJuLnByb2MuZmlsZS5jcmVhdGUubGFzdC5yb3VuZD1cdTVDMDZcdTRFMERcdTVCRjlcdTU3MjhcdTY3MDBcdTU0MEVcdTRFMDBcdTRFMkFcdTVGQUFcdTczQUZcdTRFMkRcdTUyMUJcdTVFRkFcdTc2ODRcdTdDN0JcdTU3OEJcdTRFM0EgJyd7MH0nJyBcdTc2ODRcdTY1ODdcdTRFRjZcdThGREJcdTg4NENcdTZDRThcdTkxQ0FcdTU5MDRcdTc0MDZcdTMwMDIKCiMgMDogc3RyaW5nLCAxOiBzdHJpbmcKY29tcGlsZXIud2Fybi5wcm9jLm1hbGZvcm1lZC5zdXBwb3J0ZWQuc3RyaW5nPVx1NTkwNFx1NzQwNlx1N0EwQlx1NUU4RiAnJ3sxfScnIFx1NEUzQVx1NjUyRlx1NjMwMVx1NzY4NFx1NkNFOFx1OTFDQVx1N0M3Qlx1NTc4Qlx1OEZENFx1NTZERVx1NjgzQ1x1NUYwRlx1OTUxOVx1OEJFRlx1NzY4NFx1NUI1N1x1N0IyNlx1NEUzMiAnJ3swfScnCgojIDA6IHNldCBvZiBzdHJpbmcKY29tcGlsZXIud2Fybi5wcm9jLmFubm90YXRpb25zLndpdGhvdXQucHJvY2Vzc29ycz1cdTZDQTFcdTY3MDlcdTU5MDRcdTc0MDZcdTdBMEJcdTVFOEZcdTg5ODFcdTRGN0ZcdTc1MjhcdTRFRTVcdTRFMEJcdTRFRkJcdTRGNTVcdTZDRThcdTkxQ0E6IHswfQoKIyAwOiBzb3VyY2UgdmVyc2lvbiwgMTogc3RyaW5nLCAyOiBzdHJpbmcKY29tcGlsZXIud2Fybi5wcm9jLnByb2Nlc3Nvci5pbmNvbXBhdGlibGUuc291cmNlLnZlcnNpb249XHU2NzY1XHU4MUVBXHU2Q0U4XHU5MUNBXHU1OTA0XHU3NDA2XHU3QTBCXHU1RThGICcnezF9JycgXHU3Njg0XHU1M0Q3XHU2NTJGXHU2MzAxIHNvdXJjZSBcdTcyNDhcdTY3MkMgJyd7MH0nJyBcdTRGNEVcdTRFOEUgLXNvdXJjZSAnJ3syfScnCgpjb21waWxlci53YXJuLnByb2MucHJvYy1vbmx5LnJlcXVlc3RlZC5uby5wcm9jcz1cdTU3MjhcdTY3MkFcdThCRjdcdTZDNDJcdTdGMTZcdThCRDFcdTc2ODRcdTYwQzVcdTUxQjVcdTRFMEJcdThGREJcdTg4NENcdTZDRThcdTkxQ0FcdTU5MDRcdTc0MDYsIFx1NEY0Nlx1NjI3RVx1NEUwRFx1NTIzMFx1NTkwNFx1NzQwNlx1N0EwQlx1NUU4Rlx1MzAwMgoKY29tcGlsZXIud2Fybi5wcm9jLnVzZS5pbXBsaWNpdD1cdTZDRThcdTkxQ0FcdTU5MDRcdTc0MDZcdTRFMERcdTkwMDJcdTc1MjhcdTRFOEVcdTk2OTBcdTVGMEZcdTdGMTZcdThCRDFcdTc2ODRcdTY1ODdcdTRFRjZcdTMwMDJcblx1NEY3Rlx1NzUyOCAtaW1wbGljaXQgXHU2MzA3XHU1QjlBXHU3NTI4XHU0RThFXHU5NjkwXHU1RjBGXHU3RjE2XHU4QkQxXHU3Njg0XHU3QjU2XHU3NTY1XHUzMDAyCgpjb21waWxlci53YXJuLnByb2MudXNlLnByb2Mub3IuaW1wbGljaXQ9XHU2Q0U4XHU5MUNBXHU1OTA0XHU3NDA2XHU0RTBEXHU5MDAyXHU3NTI4XHU0RThFXHU5NjkwXHU1RjBGXHU3RjE2XHU4QkQxXHU3Njg0XHU2NTg3XHU0RUY2XHUzMDAyXG5cdTRGN0ZcdTc1MjggLXByb2M6bm9uZSBcdTc5ODFcdTc1MjhcdTZDRThcdTkxQ0FcdTU5MDRcdTc0MDZcdTYyMTZcdTRGN0ZcdTc1MjggLWltcGxpY2l0IFx1NjMwN1x1NUI5QVx1NzUyOFx1NEU4RVx1OTY5MFx1NUYwRlx1N0YxNlx1OEJEMVx1NzY4NFx1N0I1Nlx1NzU2NVx1MzAwMgoKIyBQcmludCBhIGNsaWVudC1nZW5lcmF0ZWQgd2FybmluZzsgYXNzdW1lZCB0byBiZSBsb2NhbGl6ZWQsIG5vIHRyYW5zbGF0aW9uIHJlcXVpcmVkCiMgMDogc3RyaW5nCmNvbXBpbGVyLndhcm4ucHJvYy5tZXNzYWdlcj17MH0KCiMgMDogc2V0IG9mIG5hbWUKY29tcGlsZXIud2Fybi5wcm9jLnVuY2xvc2VkLnR5cGUuZmlsZXM9XHU3QzdCXHU1NzhCICcnezB9JycgXHU3Njg0XHU2NTg3XHU0RUY2XHU2NzJBXHU1MTczXHU5NUVEOyBcdTVDMDZcdTRFMERcdTk0ODhcdTVCRjlcdThGRDlcdTRFOUJcdTdDN0JcdTU3OEJcdThGREJcdTg4NENcdTZDRThcdTkxQ0FcdTU5MDRcdTc0MDYKCiMgMDogc3RyaW5nCmNvbXBpbGVyLndhcm4ucHJvYy51bm1hdGNoZWQucHJvY2Vzc29yLm9wdGlvbnM9XHU0RUU1XHU0RTBCXHU5MDA5XHU5ODc5XHU2NzJBXHU4OEFCXHU0RUZCXHU0RjU1XHU1OTA0XHU3NDA2XHU3QTBCXHU1RThGXHU4QkM2XHU1MjJCOiAnJ3swfScnCgpjb21waWxlci53YXJuLnRyeS5leHBsaWNpdC5jbG9zZS5jYWxsPVx1NTcyOFx1NTNFRlx1ODFFQVx1NTJBOFx1N0VEM1x1Njc1Rlx1NzY4NFx1OEQ0NFx1NkU5MFx1NEUwQVx1NjYzRVx1NUYwRlx1OEMwM1x1NzUyOCBjbG9zZSgpCgojIDA6IHN5bWJvbApjb21waWxlci53YXJuLnRyeS5yZXNvdXJjZS5ub3QucmVmZXJlbmNlZD1cdTRFMERcdTgwRkRcdTU3MjhcdTc2RjhcdTVFOTRcdTc2ODQgdHJ5IFx1OEJFRFx1NTNFNVx1NzY4NFx1NkI2M1x1NjU4N1x1NEUyRFx1NUYxNVx1NzUyOFx1NTNFRlx1ODFFQVx1NTJBOFx1N0VEM1x1Njc1Rlx1NzY4NFx1OEQ0NFx1NkU5MHswfQoKIyAwOiB0eXBlCmNvbXBpbGVyLndhcm4udHJ5LnJlc291cmNlLnRocm93cy5pbnRlcnJ1cHRlZC5leGM9XHU1M0VGXHU4MUVBXHU1MkE4XHU1MTczXHU5NUVEXHU3Njg0XHU4RDQ0XHU2RTkwezB9XHU1MzA1XHU1NDJCXHU3Njg0XHU2MjEwXHU1NDU4XHU2NUI5XHU2Q0Q1IGNsb3NlKCkgXHU1M0VGXHU4MEZEXHU2MjlCXHU1MUZBIEludGVycnVwdGVkRXhjZXB0aW9uCgpjb21waWxlci53YXJuLnVuY2hlY2tlZC5hc3NpZ249XHU2NzJBXHU3RUNGXHU2OEMwXHU2N0U1XHU3Njg0XHU1MjA2XHU5MTREOiBcdTVDMDZ7MH1cdTUyMDZcdTkxNERcdTdFRDl7MX0KCiMgMDogc3ltYm9sLCAxOiB0eXBlCmNvbXBpbGVyLndhcm4udW5jaGVja2VkLmFzc2lnbi50by52YXI9XHU1QkY5XHU0RjVDXHU0RTNBXHU1MzlGXHU1OUNCXHU3QzdCXHU1NzhCezF9XHU3Njg0XHU2MjEwXHU1NDU4XHU3Njg0XHU1M0Q4XHU5MUNGezB9XHU3Njg0XHU1MjA2XHU5MTREXHU2NzJBXHU3RUNGXHU4RkM3XHU2OEMwXHU2N0U1CgojIDA6IHN5bWJvbCwgMTogdHlwZQpjb21waWxlci53YXJuLnVuY2hlY2tlZC5jYWxsLm1ici5vZi5yYXcudHlwZT1cdTVCRjlcdTRGNUNcdTRFM0FcdTUzOUZcdTU5Q0JcdTdDN0JcdTU3OEJ7MX1cdTc2ODRcdTYyMTBcdTU0NThcdTc2ODR7MH1cdTc2ODRcdThDMDNcdTc1MjhcdTY3MkFcdTdFQ0ZcdThGQzdcdTY4QzBcdTY3RTUKCmNvbXBpbGVyLndhcm4udW5jaGVja2VkLmNhc3QudG8udHlwZT1cdTU0MTFcdTdDN0JcdTU3OEJ7MH1cdTc2ODRcdThGNkNcdTYzNjJcdTY3MkFcdTdFQ0ZcdThGQzdcdTY4QzBcdTY3RTUKCiMgMDogc3ltYm9sIGtpbmQsIDE6IG5hbWUsIDI6IGxpc3Qgb2YgdHlwZSwgMzogbGlzdCBvZiB0eXBlLCA0OiBzeW1ib2wga2luZCwgNTogc3ltYm9sCmNvbXBpbGVyLndhcm4udW5jaGVja2VkLm1ldGguaW52b2NhdGlvbi5hcHBsaWVkPVx1NjVCOVx1NkNENVx1OEMwM1x1NzUyOFx1NjcyQVx1N0VDRlx1OEZDN1x1NjhDMFx1NjdFNTogXHU1QzA2ezR9IHs1fVx1NEUyRFx1NzY4NHswfSB7MX1cdTVFOTRcdTc1MjhcdTUyMzBcdTdFRDlcdTVCOUFcdTc2ODRcdTdDN0JcdTU3OEJcblx1OTcwMFx1ODk4MTogezJ9XG5cdTYyN0VcdTUyMzA6IHszfQoKIyAwOiB0eXBlCmNvbXBpbGVyLndhcm4udW5jaGVja2VkLmdlbmVyaWMuYXJyYXkuY3JlYXRpb249XHU1QkY5XHU0RThFXHU3QzdCXHU1NzhCXHU0RTNBezB9XHU3Njg0IHZhcmFyZ3MgXHU1M0MyXHU2NTcwLCBcdTZDREJcdTU3OEJcdTY1NzBcdTdFQzRcdTUyMUJcdTVFRkFcdTY3MkFcdTdFQ0ZcdThGQzdcdTY4QzBcdTY3RTUKCiMgMDogdHlwZQpjb21waWxlci53YXJuLnVuY2hlY2tlZC52YXJhcmdzLm5vbi5yZWlmaWFibGUudHlwZT1cdTUzQzJcdTY1NzBcdTUzMTYgdmFyYXJnIFx1N0M3Qlx1NTc4QnswfVx1NzY4NFx1NTgwNlx1NTNFRlx1ODBGRFx1NURGMlx1NTNEN1x1NkM2MVx1NjdEMwoKIyAwOiBzeW1ib2wKY29tcGlsZXIud2Fybi52YXJhcmdzLnVuc2FmZS51c2UudmFyYXJncy5wYXJhbT1WYXJhcmdzIFx1NjVCOVx1NkNENVx1NTNFRlx1ODBGRFx1NUJGQ1x1ODFGNFx1Njc2NVx1ODFFQVx1NEUwRFx1NTNFRlx1NTE3N1x1NEY1M1x1NTMxNiB2YXJhcmdzIFx1NTNDMlx1NjU3MCB7MH0gXHU3Njg0XHU1ODA2XHU2QzYxXHU2N0QzCgpjb21waWxlci53YXJuLm1pc3NpbmcuZGVwcmVjYXRlZC5hbm5vdGF0aW9uPVx1NjcyQVx1NEY3Rlx1NzUyOCBARGVwcmVjYXRlZCBcdTVCRjlcdTVERjJcdThGQzdcdTY1RjZcdTc2ODRcdTk4NzlcdTc2RUVcdThGREJcdTg4NENcdTZDRThcdTkxQ0EKCiMgMDogc3ltYm9sIGtpbmQKY29tcGlsZXIud2Fybi5kZXByZWNhdGVkLmFubm90YXRpb24uaGFzLm5vLmVmZmVjdD1ARGVwcmVjYXRlZCBcdTZDRThcdTkxQ0FcdTVCRjlcdTZCNjQgezB9IFx1NThGMFx1NjYwRVx1NkNBMVx1NjcwOVx1NEVGQlx1NEY1NVx1NjU0OFx1Njc5QwoKY29tcGlsZXIud2Fybi5pbnZhbGlkLnBhdGg9XHU2NUUwXHU2NTQ4XHU2NTg3XHU0RUY2XHU1NDBEOiB7MH0KCmNvbXBpbGVyLndhcm4uaW52YWxpZC5hcmNoaXZlLmZpbGU9XHU0RUU1XHU0RTBCXHU4REVGXHU1Rjg0XHU0RTJEXHU1QjU4XHU1NzI4XHU2MTBGXHU1OTE2XHU3Njg0XHU2NTg3XHU0RUY2OiB7MH0KCmNvbXBpbGVyLndhcm4udW5leHBlY3RlZC5hcmNoaXZlLmZpbGU9XHU0RUU1XHU0RTBCXHU2ODYzXHU2ODQ4XHU2NTg3XHU0RUY2XHU1QjU4XHU1NzI4XHU2MTBGXHU1OTE2XHU3Njg0XHU2MjY5XHU1QzU1XHU1NDBEOiB7MH0KCiMgMDogcGF0aApjb21waWxlci5lcnIubm8uemlwZnMuZm9yLmFyY2hpdmU9XHU2Q0ExXHU2NzA5XHU0RUZCXHU0RjU1XHU2NTg3XHU0RUY2XHU3Q0ZCXHU3RURGXHU2M0QwXHU0RjlCXHU2NUI5XHU1M0VGXHU1OTA0XHU3NDA2XHU2QjY0XHU2NTg3XHU0RUY2OiB7MH0KCmNvbXBpbGVyLndhcm4uZGl2Lnplcm89XHU5NjY0XHU2NTcwXHU0RTNBXHU5NkY2Cgpjb21waWxlci53YXJuLmVtcHR5LmlmPWlmIFx1NEU0Qlx1NTQwRVx1NkNBMVx1NjcwOVx1OEJFRFx1NTNFNQoKY29tcGlsZXIud2Fybi5hbm5vdGF0aW9uLm1ldGhvZC5ub3QuZm91bmQ9XHU2NUUwXHU2Q0Q1XHU2MjdFXHU1MjMwXHU3QzdCXHU1NzhCICcnezB9JycgXHU3Njg0XHU2Q0U4XHU5MUNBXHU2NUI5XHU2Q0Q1ICcnezF9KCknJwoKY29tcGlsZXIud2Fybi5hbm5vdGF0aW9uLm1ldGhvZC5ub3QuZm91bmQucmVhc29uPVx1NjVFMFx1NkNENVx1NjI3RVx1NTIzMFx1N0M3Qlx1NTc4QiAnJ3swfScnIFx1NzY4NFx1NkNFOFx1OTFDQVx1NjVCOVx1NkNENSAnJ3sxfSgpJyc6IHsyfQoKIyAwOiBzeW1ib2wsIDE6IG5hbWUKY29tcGlsZXIud2Fybi51bmtub3duLmVudW0uY29uc3RhbnQ9XHU2NzJBXHU3N0U1XHU3Njg0XHU2NzlBXHU0RTNFXHU1RTM4XHU5MUNGIHsxfS57Mn0KCiMgMDogc3ltYm9sLCAxOiBuYW1lLCAyOiBtZXNzYWdlIHNlZ21lbnQKY29tcGlsZXIud2Fybi51bmtub3duLmVudW0uY29uc3RhbnQucmVhc29uPVx1NjcyQVx1NzdFNVx1NzY4NFx1Njc5QVx1NEUzRVx1NUUzOFx1OTFDRiB7MX0uezJ9XG5cdTUzOUZcdTU2RTA6IHszfQoKIyAwOiB0eXBlLCAxOiB0eXBlCmNvbXBpbGVyLndhcm4ucmF3LmNsYXNzLnVzZT1cdTYyN0VcdTUyMzBcdTUzOUZcdTU5Q0JcdTdDN0JcdTU3OEI6IHswfVxuXHU3RjNBXHU1QzExXHU2Q0RCXHU1NzhCXHU3QzdCezF9XHU3Njg0XHU3QzdCXHU1NzhCXHU1M0MyXHU2NTcwCgojIDA6IHVudXNlZCwgMTogdW51c2VkCmNvbXBpbGVyLndhcm4uZGlhbW9uZC5yZWR1bmRhbnQuYXJncz1cdTY1QjBcdTg4NjhcdThGQkVcdTVGMEZcdTRFMkRcdTVCNThcdTU3MjhcdTUxOTdcdTRGNTlcdTdDN0JcdTU3OEJcdTUzQzJcdTY1NzAgKFx1NjUzOVx1NzUyOCBkaWFtb25kIFx1OEZEMFx1N0I5N1x1N0IyNilcdTMwMDIKCmNvbXBpbGVyLndhcm4ucG90ZW50aWFsLmxhbWJkYS5mb3VuZD1cdTUzRUZcdTVDMDZcdTZCNjRcdTUzM0ZcdTU0MERcdTUxODVcdTkwRThcdTdDN0JcdTUyMUJcdTVFRkFcdThGNkNcdTYzNjJcdTRFM0EgbGFtYmRhIFx1ODg2OFx1OEZCRVx1NUYwRlx1MzAwMgoKY29tcGlsZXIud2Fybi5tZXRob2QucmVkdW5kYW50LnR5cGVhcmdzPVx1NjVCOVx1NkNENVx1OEMwM1x1NzUyOFx1NEUyRFx1NUI1OFx1NTcyOFx1NTE5N1x1NEY1OVx1N0M3Qlx1NTc4Qlx1NTNDMlx1NjU3MFx1MzAwMgoKIyAwOiBzeW1ib2wsIDE6IG1lc3NhZ2Ugc2VnbWVudApjb21waWxlci53YXJuLnZhcmFyZ3MucmVkdW5kYW50LnRydXN0bWUuYW5ubz1cdTUxOTdcdTRGNTlcdTc2ODQgezB9IFx1NkNFOFx1OTFDQVx1MzAwMnsxfQoKIyAwOiBzeW1ib2wKY29tcGlsZXIud2Fybi5hY2Nlc3MudG8ubWVtYmVyLmZyb20uc2VyaWFsaXphYmxlLmVsZW1lbnQ9XHU1M0VGXHU0RTMyXHU4ODRDXHU1MzE2XHU1MTQzXHU3RDIwXHU1QkY5XHU2MjEwXHU1NDU4IHswfSBcdTc2ODRcdThCQkZcdTk1RUVcdTUzRUZcdTRFRTVcdTc1MzFcdTRFMERcdTUzRDdcdTRGRTFcdTRFRkJcdTc2ODRcdTRFRTNcdTc4MDFcdTUxNkNcdTVGMDBcdTYyNjdcdTg4NEMKCiMgMDogc3ltYm9sCmNvbXBpbGVyLndhcm4uYWNjZXNzLnRvLm1lbWJlci5mcm9tLnNlcmlhbGl6YWJsZS5sYW1iZGE9XHU1M0VGXHU0RTMyXHU4ODRDXHU1MzE2IGxhbWJkYSBcdTVCRjlcdTYyMTBcdTU0NTggezB9IFx1NzY4NFx1OEJCRlx1OTVFRVx1NTNFRlx1NEVFNVx1NzUzMVx1NEUwRFx1NTNEN1x1NEZFMVx1NEVGQlx1NzY4NFx1NEVFM1x1NzgwMVx1NTE2Q1x1NUYwMFx1NjI2N1x1ODg0QwoKIyMjIyMKCiMjIFRoZSBmb2xsb3dpbmcgYXJlIHRva2VucyB3aGljaCBhcmUgbm9uLXRlcm1pbmFscyBpbiB0aGUgbGFuZ3VhZ2UuIFRoZXkgc2hvdWxkCiMjIGJlIG5hbWVkIGFzIEpMUzMgY2FsbHMgdGhlbSB3aGVuIHRyYW5zbGF0ZWQgdG8gdGhlIGFwcHJvcHJpYXRlIGxhbmd1YWdlLgpjb21waWxlci5taXNjLnRva2VuLmlkZW50aWZpZXI9PFx1NjgwN1x1OEJDNlx1N0IyNj4KCmNvbXBpbGVyLm1pc2MudG9rZW4uY2hhcmFjdGVyPTxcdTVCNTdcdTdCMjY+Cgpjb21waWxlci5taXNjLnRva2VuLnN0cmluZz08XHU1QjU3XHU3QjI2XHU0RTMyPgoKY29tcGlsZXIubWlzYy50b2tlbi5pbnRlZ2VyPTxcdTY1NzRcdTU3OEI+Cgpjb21waWxlci5taXNjLnRva2VuLmxvbmctaW50ZWdlcj08XHU5NTdGXHU2NTc0XHU1NzhCPgoKY29tcGlsZXIubWlzYy50b2tlbi5mbG9hdD08XHU2RDZFXHU3MEI5XHU1NzhCPgoKY29tcGlsZXIubWlzYy50b2tlbi5kb3VibGU9PFx1NTNDQ1x1N0NCRVx1NUVBNlx1NTc4Qj4KCmNvbXBpbGVyLm1pc2MudG9rZW4uYmFkLXN5bWJvbD08XHU5NTE5XHU4QkVGXHU3QjI2XHU1M0Y3PgoKY29tcGlsZXIubWlzYy50b2tlbi5lbmQtb2YtaW5wdXQ9PFx1OEY5M1x1NTE2NVx1N0VEM1x1Njc1Rj4KCiMjIFRoZSBhcmd1bWVudCB0byB0aGUgZm9sbG93aW5nIHN0cmluZyB3aWxsIGFsd2F5cyBiZSBvbmUgb2YgdGhlIGZvbGxvd2luZzoKIyMgMS4gb25lIG9mIHRoZSBhYm92ZSBub24tdGVybWluYWxzCiMjIDIuIGEga2V5d29yZCAoSkxTMS44KQojIyAzLiBhIGJvb2xlYW4gbGl0ZXJhbCAoSkxTMy4xMC4zKQojIyA0LiB0aGUgbnVsbCBsaXRlcmFsIChKTFMzLjEwLjcpCiMjIDUuIGEgSmF2YSBzZXBhcmF0b3IgKEpMUzMuMTEpCiMjIDYuIGFuIG9wZXJhdG9yIChKTFMzLjEyKQojIwojIyBUaGlzIGlzIHRoZSBvbmx5IHBsYWNlIHRoZXNlIHRva2VucyB3aWxsIGJlIHVzZWQuCiMgMDogdG9rZW4KY29tcGlsZXIuZXJyLmV4cGVjdGVkPVx1OTcwMFx1ODk4MXswfQoKIyAwOiB0b2tlbiwgMTogdG9rZW4KY29tcGlsZXIuZXJyLmV4cGVjdGVkMj1cdTk3MDBcdTg5ODF7MH1cdTYyMTZ7MX0KCiMgMDogdG9rZW4sIDE6IHRva2VuLCAyOiB0b2tlbgpjb21waWxlci5lcnIuZXhwZWN0ZWQzPVx1OTcwMFx1ODk4MXswfSwgezF9XHU2MjE2ezJ9Cgpjb21waWxlci5lcnIucHJlbWF0dXJlLmVvZj1cdThGREJcdTg4NENcdTg5RTNcdTY3OTBcdTY1RjZcdTVERjJcdTUyMzBcdThGQkVcdTY1ODdcdTRFRjZcdTdFRDNcdTVDM0UKCiMjIFRoZSBmb2xsb3dpbmcgYXJlIHJlbGF0ZWQgaW4gZm9ybSwgYnV0IGRvIG5vdCBlYXNpbHkgZml0IHRoZSBhYm92ZSBwYXJhZGlnbS4KY29tcGlsZXIuZXJyLmV4cGVjdGVkLm1vZHVsZT1cdTk3MDBcdTg5ODEgJydtb2R1bGUnJwoKY29tcGlsZXIuZXJyLmRvdC5jbGFzcy5leHBlY3RlZD1cdTk3MDBcdTg5ODEgJycuY2xhc3MnJwoKIyMgVGhlIGFyZ3VtZW50IHRvIHRoaXMgc3RyaW5nIHdpbGwgYWx3YXlzIGJlIGVpdGhlciAnY2FzZScgb3IgJ2RlZmF1bHQnLgojIDA6IHRva2VuCmNvbXBpbGVyLmVyci5vcnBoYW5lZD1cdTVCNjRcdTdBQ0JcdTc2ODR7MH0KCiMgMDogbmFtZQpjb21waWxlci5taXNjLmFub255bW91cy5jbGFzcz08XHU1MzNGXHU1NDBEezB9PgoKIyAwOiBuYW1lLCAxOiB0eXBlCmNvbXBpbGVyLm1pc2MudHlwZS5jYXB0dXJlb2Y9Y2FwdHVyZSN7MH0sIFx1NTE3MSB7MX0KCmNvbXBpbGVyLm1pc2MudHlwZS5jYXB0dXJlb2YuMT1jYXB0dXJlI3swfQoKY29tcGlsZXIubWlzYy50eXBlLm5vbmU9PFx1NjVFMD4KCmNvbXBpbGVyLm1pc2MudW5uYW1lZC5wYWNrYWdlPVx1NjcyQVx1NTQ3RFx1NTQwRFx1N0EwQlx1NUU4Rlx1NTMwNQoKY29tcGlsZXIubWlzYy51bm5hbWVkLm1vZHVsZT1cdTY3MkFcdTU0N0RcdTU0MERcdTZBMjFcdTU3NTcKCiMjIyMjCgojIDA6IHN5bWJvbCwgMTogbWVzc2FnZSBzZWdtZW50CmNvbXBpbGVyLmVyci5jYW50LmFjY2Vzcz1cdTY1RTBcdTZDRDVcdThCQkZcdTk1RUV7MH1cbnsxfQoKIyAwOiBuYW1lCmNvbXBpbGVyLm1pc2MuYmFkLmNsYXNzLmZpbGU9XHU3QzdCXHU2NTg3XHU0RUY2XHU1QkY5XHU0RThFXHU3QzdCIHswfSBcdTY1RTBcdTY1NDgKCiMgMDogZmlsZSBuYW1lLCAxOiBzdHJpbmcgKGV4cGVjdGVkIGNvbnN0YW50IHBvb2wgZW50cnkgdHlwZSksIDI6IG51bWJlciAoY29uc3RhbnQgcG9vbCBpbmRleCkKY29tcGlsZXIubWlzYy5iYWQuY29uc3QucG9vbC5lbnRyeT17MH0gXHU0RTJEXHU5NTE5XHU4QkVGXHU3Njg0XHU1RTM4XHU5MUNGXHU2QzYwXHU2NzYxXHU3NkVFXG5cdTk4ODRcdTY3MUZcdTRFM0FcdTdEMjJcdTVGMTUgezJ9IFx1NTkwNFx1NzY4NCB7MX0KCiMgMDogZmlsZSBuYW1lLCAxOiBtZXNzYWdlIHNlZ21lbnQKY29tcGlsZXIubWlzYy5iYWQuY2xhc3MuZmlsZS5oZWFkZXI9XHU5NTE5XHU4QkVGXHU3Njg0XHU3QzdCXHU2NTg3XHU0RUY2OiB7MH1cbnsxfVxuXHU4QkY3XHU1MjIwXHU5NjY0XHU4QkU1XHU2NTg3XHU0RUY2XHU2MjE2XHU3ODZFXHU0RkREXHU4QkU1XHU2NTg3XHU0RUY2XHU0RjREXHU0RThFXHU2QjYzXHU3ODZFXHU3Njg0XHU3QzdCXHU4REVGXHU1Rjg0XHU1QjUwXHU3NkVFXHU1RjU1XHU0RTJEXHUzMDAyCgojIDA6IGZpbGUgbmFtZSwgMTogbWVzc2FnZSBzZWdtZW50CmNvbXBpbGVyLm1pc2MuYmFkLnNvdXJjZS5maWxlLmhlYWRlcj1cdTk1MTlcdThCRUZcdTc2ODRcdTZFOTBcdTY1ODdcdTRFRjY6IHswfVxuezF9XG5cdThCRjdcdTUyMjBcdTk2NjRcdThCRTVcdTY1ODdcdTRFRjZcdTYyMTZcdTc4NkVcdTRGRERcdThCRTVcdTY1ODdcdTRFRjZcdTRGNERcdTRFOEVcdTZCNjNcdTc4NkVcdTc2ODRcdTZFOTBcdThERUZcdTVGODRcdTVCNTBcdTc2RUVcdTVGNTVcdTRFMkRcdTMwMDIKCiMjIFRoZSBmb2xsb3dpbmcgYXJlIGFsbCBwb3NzaWJsZSBzdHJpbmdzIGZvciB0aGUgc2Vjb25kIGFyZ3VtZW50ICh7MX0pIG9mIHRoZQojIyBhYm92ZSBzdHJpbmdzLgpjb21waWxlci5taXNjLmJhZC5jbGFzcy5zaWduYXR1cmU9XHU5NTE5XHU4QkVGXHU3Njg0XHU3QzdCXHU3QjdFXHU1NDBEOiB7MH0KCiMwOiBzeW1ib2wsIDE6IHN5bWJvbApjb21waWxlci5taXNjLmJhZC5lbmNsb3NpbmcuY2xhc3M9ezB9XHU3Njg0XHU1QzAxXHU5NUVEXHU3QzdCXHU5NTE5XHU4QkVGOiB7MX0KCiMgMDogc3ltYm9sCmNvbXBpbGVyLm1pc2MuYmFkLmVuY2xvc2luZy5tZXRob2Q9XHU3QzdCIHswfSBcdTc2ODRcdTVDMDFcdTk1RURcdTY1QjlcdTZDRDVcdTVDNUVcdTYwMjdcdTk1MTlcdThCRUYKCmNvbXBpbGVyLm1pc2MuYmFkLnJ1bnRpbWUuaW52aXNpYmxlLnBhcmFtLmFubm90YXRpb25zPVx1OTUxOVx1OEJFRlx1NzY4NCBSdW50aW1lSW52aXNpYmxlUGFyYW1ldGVyQW5ub3RhdGlvbnMgXHU1QzVFXHU2MDI3OiB7MH0KCmNvbXBpbGVyLm1pc2MuYmFkLmNvbnN0LnBvb2wudGFnPVx1OTUxOVx1OEJFRlx1NzY4NFx1NUUzOFx1OTFDRlx1NkM2MFx1NjgwN1x1OEJCMDogezB9Cgpjb21waWxlci5taXNjLmJhZC5jb25zdC5wb29sLnRhZy5hdD1cdTk1MTlcdThCRUZcdTc2ODRcdTVFMzhcdTkxQ0ZcdTZDNjBcdTY4MDdcdThCQjA6IHswfSwgXHU0RjREXHU0RThFezF9Cgpjb21waWxlci5taXNjLmJhZC5zaWduYXR1cmU9XHU5NTE5XHU4QkVGXHU3Njg0XHU3QjdFXHU1NDBEOiB7MH0KCmNvbXBpbGVyLm1pc2MuYmFkLnR5cGUuYW5ub3RhdGlvbi52YWx1ZT1cdTk1MTlcdThCRUZcdTc2ODRcdTdDN0JcdTU3OEJcdTZDRThcdTkxQ0FcdTc2RUVcdTY4MDdcdTdDN0JcdTU3OEJcdTUwM0M6IHswfQoKY29tcGlsZXIubWlzYy5iYWQubW9kdWxlLWluZm8ubmFtZT1cdTk1MTlcdThCRUZcdTc2ODRcdTdDN0JcdTU0MEQKCmNvbXBpbGVyLm1pc2MuY2xhc3MuZmlsZS53cm9uZy5jbGFzcz1cdTdDN0JcdTY1ODdcdTRFRjZcdTUzMDVcdTU0MkJcdTk1MTlcdThCRUZcdTc2ODRcdTdDN0I6IHswfQoKY29tcGlsZXIubWlzYy5tb2R1bGUuaW5mby5pbnZhbGlkLnN1cGVyLmNsYXNzPVx1NUUyNlx1NjcwOVx1NjVFMFx1NjU0OFx1OEQ4NVx1N0M3Qlx1NzY4NCBtb2R1bGUtaW5mbwoKY29tcGlsZXIubWlzYy5jbGFzcy5maWxlLm5vdC5mb3VuZD1cdTYyN0VcdTRFMERcdTUyMzB7MH1cdTc2ODRcdTdDN0JcdTY1ODdcdTRFRjYKCiMgMDogc3RyaW5nIChjb25zdGFudCB2YWx1ZSksIDE6IHN5bWJvbCAoY29uc3RhbnQgZmllbGQpLCAyOiB0eXBlIChmaWVsZCB0eXBlKQpjb21waWxlci5taXNjLmJhZC5jb25zdGFudC5yYW5nZT17MX0gXHU3Njg0XHU1RTM4XHU5MUNGXHU1MDNDICcnezB9JycgXHU4RDg1XHU1MUZBXHU0RTg2IHsyfSBcdTc2ODRcdTk4ODRcdTY3MUZcdTgzMDNcdTU2RjQKCiMgMDogc3RyaW5nIChjb25zdGFudCB2YWx1ZSksIDE6IHN5bWJvbCAoY29uc3RhbnQgZmllbGQpLCAyOiBzdHJpbmcgKGV4cGVjdGVkIGNsYXNzKQpjb21waWxlci5taXNjLmJhZC5jb25zdGFudC52YWx1ZT17MX0gXHU3Njg0XHU1RTM4XHU5MUNGXHU1MDNDICcnezB9JycgXHU5NTE5XHU4QkVGLCBcdTk4ODRcdTY3MUZcdTRFM0EgezJ9CgojIDA6IHN0cmluZyAoY2xhc3NmaWxlIG1ham9yIHZlcnNpb24pLCAxOiBzdHJpbmcgKGNsYXNzZmlsZSBtaW5vciB2ZXJzaW9uKQpjb21waWxlci5taXNjLmludmFsaWQuZGVmYXVsdC5pbnRlcmZhY2U9XHU1NzI4IHswfS57MX0gXHU3MjQ4XHU3QzdCXHU2NTg3XHU0RUY2XHU0RTJEXHU2MjdFXHU1MjMwXHU5RUQ4XHU4QkE0XHU2NUI5XHU2Q0Q1CgojIDA6IHN0cmluZyAoY2xhc3NmaWxlIG1ham9yIHZlcnNpb24pLCAxOiBzdHJpbmcgKGNsYXNzZmlsZSBtaW5vciB2ZXJzaW9uKQpjb21waWxlci5taXNjLmludmFsaWQuc3RhdGljLmludGVyZmFjZT1cdTU3MjggezB9LnsxfSBcdTcyNDhcdTdDN0JcdTY1ODdcdTRFRjZcdTRFMkRcdTYyN0VcdTUyMzBcdTk3NTlcdTYwMDFcdTY1QjlcdTZDRDUKCiMgMDogc3RyaW5nIChjbGFzc2ZpbGUgbWFqb3IgdmVyc2lvbiksIDE6IHN0cmluZyAoY2xhc3NmaWxlIG1pbm9yIHZlcnNpb24pCmNvbXBpbGVyLm1pc2MuYW5hY2hyb25pc3RpYy5tb2R1bGUuaW5mbz1cdTU3MjggezB9LnsxfSBcdTcyNDhcdTdDN0JcdTY1ODdcdTRFRjZcdTRFMkRcdTYyN0VcdTUyMzBcdTZBMjFcdTU3NTdcdTU4RjBcdTY2MEUKCiMgMDogbmFtZQpjb21waWxlci5taXNjLmZpbGUuZG9lc250LmNvbnRhaW4uY2xhc3M9XHU2NTg3XHU0RUY2XHU0RTBEXHU1MzA1XHU1NDJCXHU3QzdCezB9Cgpjb21waWxlci5taXNjLmZpbGUuZG9lcy5ub3QuY29udGFpbi5wYWNrYWdlPVx1NjU4N1x1NEVGNlx1NEUwRFx1NTMwNVx1NTQyQlx1N0EwQlx1NUU4Rlx1NTMwNXswfQoKY29tcGlsZXIubWlzYy5maWxlLmRvZXMubm90LmNvbnRhaW4ubW9kdWxlPVx1NjU4N1x1NEVGNlx1NEUwRFx1NTMwNVx1NTQyQlx1NkEyMVx1NTc1N1x1NThGMFx1NjYwRQoKY29tcGlsZXIubWlzYy5pbGxlZ2FsLnN0YXJ0Lm9mLmNsYXNzLmZpbGU9XHU5NzVFXHU2Q0Q1XHU3Njg0XHU3QzdCXHU2NTg3XHU0RUY2XHU1RjAwXHU1OUNCCgpjb21waWxlci5taXNjLnVuYWJsZS50by5hY2Nlc3MuZmlsZT1cdTY1RTBcdTZDRDVcdThCQkZcdTk1RUVcdTY1ODdcdTRFRjY6IHswfQoKY29tcGlsZXIubWlzYy51bmljb2RlLnN0ci5ub3Quc3VwcG9ydGVkPVx1NEUwRFx1NjUyRlx1NjMwMVx1N0M3Qlx1NjU4N1x1NEVGNlx1NEUyRFx1NzY4NCBVbmljb2RlIFx1NUI1N1x1N0IyNlx1NEUzMgoKY29tcGlsZXIubWlzYy51bmRlY2wudHlwZS52YXI9XHU2NzJBXHU1OEYwXHU2NjBFXHU3Njg0XHU3QzdCXHU1NzhCXHU1M0Q4XHU5MUNGOiB7MH0KCmNvbXBpbGVyLm1pc2MubWFsZm9ybWVkLnZhcmFyZy5tZXRob2Q9XHU3QzdCXHU2NTg3XHU0RUY2XHU1MzA1XHU1NDJCXHU2ODNDXHU1RjBGXHU5NTE5XHU4QkVGXHU3Njg0XHU1M0Q4XHU5MUNGXHU1MTQzXHU2NTcwXHU2NUI5XHU2Q0Q1OiB7MH0KCmNvbXBpbGVyLm1pc2Mud3JvbmcudmVyc2lvbj1cdTdDN0JcdTY1ODdcdTRFRjZcdTUxNzdcdTY3MDlcdTk1MTlcdThCRUZcdTc2ODRcdTcyNDhcdTY3MkMgezB9LnsxfSwgXHU1RTk0XHU0RTNBIHsyfS57M30KCiMjIyMjCgojIDA6IHR5cGUsIDE6IHR5cGUgb3Igc3ltYm9sCmNvbXBpbGVyLmVyci5ub3Qud2l0aGluLmJvdW5kcz1cdTdDN0JcdTU3OEJcdTUzQzJcdTY1NzB7MH1cdTRFMERcdTU3MjhcdTdDN0JcdTU3OEJcdTUzRDhcdTkxQ0Z7MX1cdTc2ODRcdTgzMDNcdTU2RjRcdTUxODUKCiMjIFRoZSBmb2xsb3dpbmcgYXJlIGFsbCBwb3NzaWJsZSBzdHJpbmdzIGZvciB0aGUgc2Vjb25kIGFyZ3VtZW50ICh7MX0pIG9mIHRoZQojIyBhYm92ZSBzdHJpbmcuCgojIyBub25lIHlldC4uLgoKIyMjIyMKCiMgMDogbWVzc2FnZSBzZWdtZW50CmNvbXBpbGVyLmVyci5wcm9iLmZvdW5kLnJlcT1cdTRFMERcdTUxN0NcdTVCQjlcdTc2ODRcdTdDN0JcdTU3OEI6IHswfQoKIyAwOiBtZXNzYWdlIHNlZ21lbnQKY29tcGlsZXIubWlzYy5wcm9iLmZvdW5kLnJlcT1cdTRFMERcdTUxN0NcdTVCQjlcdTc2ODRcdTdDN0JcdTU3OEI6IHswfQoKIyAwOiBtZXNzYWdlIHNlZ21lbnQsIDE6IHR5cGUsIDI6IHR5cGUKY29tcGlsZXIud2Fybi5wcm9iLmZvdW5kLnJlcT17MH1cblx1OTcwMFx1ODk4MTogezJ9XG5cdTYyN0VcdTUyMzA6ICAgIHsxfQoKIyAwOiB0eXBlLCAxOiB0eXBlCmNvbXBpbGVyLm1pc2MuaW5jb252ZXJ0aWJsZS50eXBlcz17MH1cdTY1RTBcdTZDRDVcdThGNkNcdTYzNjJcdTRFM0F7MX0KCiMgMDogdHlwZSwgMTogdHlwZQpjb21waWxlci5taXNjLnBvc3NpYmxlLmxvc3Mub2YucHJlY2lzaW9uPVx1NEVDRXswfVx1OEY2Q1x1NjM2Mlx1NTIzMHsxfVx1NTNFRlx1ODBGRFx1NEYxQVx1NjcwOVx1NjM1Rlx1NTkzMQoKY29tcGlsZXIubWlzYy51bmNoZWNrZWQuYXNzaWduPVx1NjcyQVx1N0VDRlx1NjhDMFx1NjdFNVx1NzY4NFx1OEY2Q1x1NjM2MgoKIyBjb21waWxlci5taXNjLnN0b3JlY2hlY2s9XAojICAgICBhc3NpZ25tZW50IG1pZ2h0IGNhdXNlIGxhdGVyIHN0b3JlIGNoZWNrcyB0byBmYWlsCiMgY29tcGlsZXIubWlzYy51bmNoZWNrZWQ9XAojICAgICBhc3NpZ25lZCBhcnJheSBjYW5ub3QgZHluYW1pY2FsbHkgY2hlY2sgaXRzIHN0b3Jlcwpjb21waWxlci5taXNjLnVuY2hlY2tlZC5jYXN0LnRvLnR5cGU9XHU2NzJBXHU3RUNGXHU2OEMwXHU2N0U1XHU3Njg0XHU4RjZDXHU2MzYyCgojIGNvbXBpbGVyLmVyci5zdGFyLmV4cGVjdGVkPVwKIyAgICAgJycqJycgZXhwZWN0ZWQKIyBjb21waWxlci5lcnIubm8uZWxlbS50eXBlPVwKIyAgICAgXFtcKlxdIGNhbm5vdCBoYXZlIGEgdHlwZQoKIyAwOiB0eXBlCmNvbXBpbGVyLm1pc2MudHJ5Lm5vdC5hcHBsaWNhYmxlLnRvLnR5cGU9dHJ5LXdpdGgtcmVzb3VyY2VzIFx1NEUwRFx1OTAwMlx1NzUyOFx1NEU4RVx1NTNEOFx1OTFDRlx1N0M3Qlx1NTc4QlxuKHswfSkKCiMjIyMjCgojIDA6IG1lc3NhZ2Ugc2VnbWVudCBvciB0eXBlLCAxOiBtZXNzYWdlIHNlZ21lbnQKY29tcGlsZXIuZXJyLnR5cGUuZm91bmQucmVxPVx1NjEwRlx1NTkxNlx1NzY4NFx1N0M3Qlx1NTc4QlxuXHU5NzAwXHU4OTgxOiB7MX1cblx1NjI3RVx1NTIzMDogICAgezB9CgojIyBUaGUgZm9sbG93aW5nIGFyZSBhbGwgcG9zc2libGUgc3RyaW5ncyBmb3IgdGhlIGZpcnN0IGFyZ3VtZW50ICh7MH0pIG9mIHRoZQojIyBhYm92ZSBzdHJpbmcuCmNvbXBpbGVyLm1pc2MudHlwZS5yZXEuY2xhc3M9XHU3QzdCCgpjb21waWxlci5taXNjLnR5cGUucmVxLmNsYXNzLmFycmF5PVx1N0M3Qlx1NjIxNlx1NjU3MFx1N0VDNAoKY29tcGlsZXIubWlzYy50eXBlLnJlcS5hcnJheS5vci5pdGVyYWJsZT1cdTY1NzBcdTdFQzRcdTYyMTYgamF2YS5sYW5nLkl0ZXJhYmxlCgpjb21waWxlci5taXNjLnR5cGUucmVxLnJlZj1cdTVGMTVcdTc1MjgKCmNvbXBpbGVyLm1pc2MudHlwZS5yZXEuZXhhY3Q9XHU0RTBEXHU1RTI2XHU5NjUwXHU1MjM2XHU4MzAzXHU1NkY0XHU3Njg0XHU3QzdCXHU2MjE2XHU2M0E1XHU1M0UzCgojIDA6IHR5cGUKY29tcGlsZXIubWlzYy50eXBlLnBhcmFtZXRlcj1cdTdDN0JcdTU3OEJcdTUzQzJcdTY1NzB7MH0KCiMjIyMjCgojIyBUaGUgZm9sbG93aW5nIGFyZSBhbGwgcG9zc2libGUgc3RyaW5ncyBmb3IgdGhlIGxhc3QgYXJndW1lbnQgb2YgYWxsIHRob3NlCiMjIGRpYWdub3N0aWNzIHdob3NlIGtleSBlbmRzIGluICIuMSIKCiMgMDogdHlwZSwgMTogbGlzdCBvZiB0eXBlCmNvbXBpbGVyLm1pc2Mubm8udW5pcXVlLm1heGltYWwuaW5zdGFuY2UuZXhpc3RzPVx1NUJGOVx1NEU4RVx1NEUwQVx1OTY1MFx1NEUzQXsxfVx1NzY4NFx1N0M3Qlx1NTc4Qlx1NTNEOFx1OTFDRnswfSwgXHU0RTBEXHU1QjU4XHU1NzI4XHU1NTJGXHU0RTAwXHU2NzAwXHU1OTI3XHU1QjlFXHU0RjhCCgpjb21waWxlci5taXNjLm5vLnVuaXF1ZS5taW5pbWFsLmluc3RhbmNlLmV4aXN0cz1cdTVCRjlcdTRFOEVcdTRFMEJcdTk2NTBcdTRFM0F7MX1cdTc2ODRcdTdDN0JcdTU3OEJcdTUzRDhcdTkxQ0Z7MH0sIFx1NEUwRFx1NUI1OFx1NTcyOFx1NTUyRlx1NEUwMFx1NjcwMFx1NUMwRlx1NUI5RVx1NEY4QgoKIyAwOiB0eXBlLCAxOiBsaXN0IG9mIHR5cGUKY29tcGlsZXIubWlzYy5pbmNvbXBhdGlibGUudXBwZXIuYm91bmRzPVx1NjNBOFx1OEJCQVx1NTNEOFx1OTFDRiB7MH0gXHU1MTc3XHU2NzA5XHU0RTBEXHU1MTdDXHU1QkI5XHU3Njg0XHU0RTBBXHU5NjUwIHsxfQoKIyAwOiB0eXBlLCAxOiBsaXN0IG9mIHR5cGUKY29tcGlsZXIubWlzYy5pbmNvbXBhdGlibGUuZXEuYm91bmRzPVx1NjNBOFx1OEJCQVx1NTNEOFx1OTFDRnswfVx1NTE3N1x1NjcwOVx1NEUwRFx1NTE3Q1x1NUJCOVx1NzY4NFx1N0I0OVx1NUYwRlx1N0VBNlx1Njc1Rlx1Njc2MVx1NEVGNnsxfQoKIyAwOiB0eXBlLCAxOiBsaXN0IG9mIHR5cGUsIDI6IGxpc3Qgb2YgdHlwZQpjb21waWxlci5taXNjLmluY29tcGF0aWJsZS5lcS51cHBlci5ib3VuZHM9XHU2M0E4XHU4QkJBXHU1M0Q4XHU5MUNGIHswfSBcdTUxNzdcdTY3MDlcdTRFMERcdTUxN0NcdTVCQjlcdTc2ODRcdTk2NTBcdTUyMzZcdTgzMDNcdTU2RjRcblx1N0I0OVx1NUYwRlx1N0VBNlx1Njc1Rlx1Njc2MVx1NEVGNjogezF9XG5cdTRFMEFcdTk2NTA6IHsyfQoKIyAwOiB0eXBlLCAxOiBsaXN0IG9mIHR5cGUsIDI6IGxpc3Qgb2YgdHlwZQpjb21waWxlci5taXNjLmluY29tcGF0aWJsZS51cHBlci5sb3dlci5ib3VuZHM9XHU2M0E4XHU4QkJBXHU1M0Q4XHU5MUNGezB9XHU1MTc3XHU2NzA5XHU0RTBEXHU1MTdDXHU1QkI5XHU3Njg0XHU4RkI5XHU3NTRDXG5cdTRFMEFcdTk2NTA6IHsxfVxuXHU0RTBCXHU5NjUwOiB7Mn0KCiMgMDogdHlwZSwgMTogbGlzdCBvZiB0eXBlLCAyOiBsaXN0IG9mIHR5cGUKY29tcGlsZXIubWlzYy5pbmNvbXBhdGlibGUuZXEubG93ZXIuYm91bmRzPVx1NjNBOFx1OEJCQVx1NTNEOFx1OTFDRnswfVx1NTE3N1x1NjcwOVx1NEUwRFx1NTE3Q1x1NUJCOVx1NzY4NFx1OTY1MFx1NTIzNlx1ODMwM1x1NTZGNFxuXHU3QjQ5XHU1RjBGXHU3RUE2XHU2NzVGXHU2NzYxXHU0RUY2OiB7MX1cblx1NEUwQlx1OTY1MDogezJ9CgojIDA6IGxpc3Qgb2YgdHlwZSwgMTogdHlwZSwgMjogdHlwZQpjb21waWxlci5taXNjLmluZmVyLm5vLmNvbmZvcm1pbmcuaW5zdGFuY2UuZXhpc3RzPVx1NEUwRFx1NUI1OFx1NTcyOFx1N0M3Qlx1NTc4Qlx1NTNEOFx1OTFDRnswfVx1NzY4NFx1NUI5RVx1NEY4QiwgXHU0RUU1XHU0RjdGezF9XHU0RTBFezJ9XHU0RTAwXHU4MUY0CgojIDA6IGxpc3Qgb2YgdHlwZSwgMTogbWVzc2FnZSBzZWdtZW50CmNvbXBpbGVyLm1pc2MuaW5mZXIubm8uY29uZm9ybWluZy5hc3NpZ25tZW50LmV4aXN0cz1cdTY1RTBcdTZDRDVcdTYzQThcdTY1QURcdTdDN0JcdTU3OEJcdTUzRDhcdTkxQ0YgezB9XG4oXHU1M0MyXHU2NTcwXHU0RTBEXHU1MzM5XHU5MTREOyB7MX0pCgojIDA6IGxpc3Qgb2YgdHlwZQpjb21waWxlci5taXNjLmluZmVyLmFyZy5sZW5ndGgubWlzbWF0Y2g9XHU2NUUwXHU2Q0Q1XHU2M0E4XHU2NUFEXHU3QzdCXHU1NzhCXHU1M0Q4XHU5MUNGIHswfVxuKFx1NUI5RVx1OTY0NVx1NTNDMlx1NjU3MFx1NTIxN1x1ODg2OFx1NTQ4Q1x1NUY2Mlx1NUYwRlx1NTNDMlx1NjU3MFx1NTIxN1x1ODg2OFx1OTU3Rlx1NUVBNlx1NEUwRFx1NTQwQykKCiMgMDogbGlzdCBvZiB0eXBlLCAxOiBtZXNzYWdlIHNlZ21lbnQKY29tcGlsZXIubWlzYy5pbmZlci52YXJhcmdzLmFyZ3VtZW50Lm1pc21hdGNoPVx1NjVFMFx1NkNENVx1NjNBOFx1NjVBRFx1N0M3Qlx1NTc4Qlx1NTNEOFx1OTFDRiB7MH1cbih2YXJhcmdzIFx1NEUwRFx1NTMzOVx1OTE0RDsgezF9KQoKIyAwOiB0eXBlLCAxOiBsaXN0IG9mIHR5cGUKY29tcGlsZXIubWlzYy5pbmZlcnJlZC5kby5ub3QuY29uZm9ybS50by51cHBlci5ib3VuZHM9XHU2M0E4XHU2NUFEXHU3QzdCXHU1NzhCXHU0RTBEXHU3QjI2XHU1NDA4XHU0RTBBXHU5NjUwXG5cdTYzQThcdTY1QUQ6IHswfVxuXHU0RTBBXHU5NjUwOiB7MX0KCiMgMDogdHlwZSwgMTogbGlzdCBvZiB0eXBlCmNvbXBpbGVyLm1pc2MuaW5mZXJyZWQuZG8ubm90LmNvbmZvcm0udG8ubG93ZXIuYm91bmRzPVx1NjNBOFx1NjVBRFx1N0M3Qlx1NTc4Qlx1NEUwRFx1N0IyNlx1NTQwOFx1NEUwQlx1OTY1MFxuXHU2M0E4XHU2NUFEOiB7MH1cblx1NEUwQlx1OTY1MDogezF9CgojIDA6IHR5cGUsIDE6IGxpc3Qgb2YgdHlwZQpjb21waWxlci5taXNjLmluZmVycmVkLmRvLm5vdC5jb25mb3JtLnRvLmVxLmJvdW5kcz1cdTYzQThcdTY1QURcdTdDN0JcdTU3OEJcdTRFMERcdTdCMjZcdTU0MDhcdTdCNDlcdTVGMEZcdTdFQTZcdTY3NUZcdTY3NjFcdTRFRjZcblx1NjNBOFx1NjVBRDogezB9XG5cdTdCNDlcdTVGMEZcdTdFQTZcdTY3NUZcdTY3NjFcdTRFRjY6IHsxfQoKIyAwOiBzeW1ib2wKY29tcGlsZXIubWlzYy5kaWFtb25kPXswfTw+CgojIDA6IHR5cGUKY29tcGlsZXIubWlzYy5kaWFtb25kLm5vbi5nZW5lcmljPVx1NjVFMFx1NkNENVx1NUMwNiAnJzw+JycgXHU0RTBFXHU5NzVFXHU2Q0RCXHU1NzhCXHU3QzdCezB9XHU0RTAwXHU4RDc3XHU0RjdGXHU3NTI4CgojIDA6IGxpc3Qgb2YgdHlwZSwgMTogbWVzc2FnZSBzZWdtZW50CmNvbXBpbGVyLm1pc2MuZGlhbW9uZC5pbnZhbGlkLmFyZz1cdTZCNjRcdTRFMEFcdTRFMEJcdTY1ODdcdTRFMkRcdTRFMERcdTUxNDFcdThCQjhcdTRGN0ZcdTc1MjhcdTRFM0F7MX1cdTYzQThcdTY1QURcdTc2ODRcdTdDN0JcdTU3OEJcdTUzQzJcdTY1NzB7MH1cblx1NjNBOFx1NjVBRFx1NTNDMlx1NjU3MFx1NTcyOFx1N0I3RVx1NTQwRFx1NUM1RVx1NjAyN1x1NEUyRFx1NjVFMFx1NkNENVx1ODg2OFx1OEZCRQoKIyAwOiBsaXN0IG9mIHR5cGUsIDE6IG1lc3NhZ2Ugc2VnbWVudApjb21waWxlci5taXNjLmRpYW1vbmQuaW52YWxpZC5hcmdzPVx1NkI2NFx1NEUwQVx1NEUwQlx1NjU4N1x1NEUyRFx1NEUwRFx1NTE0MVx1OEJCOFx1NEY3Rlx1NzUyOFx1NEUzQXsxfVx1NjNBOFx1NjVBRFx1NzY4NFx1N0M3Qlx1NTc4Qlx1NTNDMlx1NjU3MHswfVxuXHU2M0E4XHU2NUFEXHU1M0MyXHU2NTcwXHU1NzI4XHU3QjdFXHU1NDBEXHU1QzVFXHU2MDI3XHU0RTJEXHU2NUUwXHU2Q0Q1XHU4ODY4XHU4RkJFCgojIDA6IHVudXNlZApjb21waWxlci5taXNjLmRpYW1vbmQuYW5kLmV4cGxpY2l0LnBhcmFtcz1cdTRFMERcdTgwRkRcdTVDMDYgJyc8PicnIFx1NEUwRVx1Njc4NFx1OTAyMFx1NTY2OFx1NzY4NFx1NjYzRVx1NUYwRlx1N0M3Qlx1NTc4Qlx1NTNDMlx1NjU3MFx1NEUwMFx1OEQ3N1x1NEY3Rlx1NzUyOAoKIyAwOiB1bnVzZWQKY29tcGlsZXIubWlzYy5tcmVmLmluZmVyLmFuZC5leHBsaWNpdC5wYXJhbXM9XHU0RTBEXHU4MEZEXHU1QzA2XHU1MzlGXHU1OUNCXHU2Nzg0XHU5MDIwXHU1NjY4XHU1RjE1XHU3NTI4XHU0RTBFXHU2Nzg0XHU5MDIwXHU1NjY4XHU3Njg0XHU2NjNFXHU1RjBGXHU3QzdCXHU1NzhCXHU1M0MyXHU2NTcwXHU0RTAwXHU4RDc3XHU0RjdGXHU3NTI4CgojIDA6IHR5cGUsIDE6IGxpc3Qgb2YgdHlwZQpjb21waWxlci5taXNjLmV4cGxpY2l0LnBhcmFtLmRvLm5vdC5jb25mb3JtLnRvLmJvdW5kcz1cdTY2M0VcdTVGMEZcdTdDN0JcdTU3OEJcdTUzQzJcdTY1NzB7MH1cdTRFMERcdTdCMjZcdTU0MDhcdTU4RjBcdTY2MEVcdTc2ODRcdTgzMDNcdTU2RjR7MX0KCmNvbXBpbGVyLm1pc2MuYXJnLmxlbmd0aC5taXNtYXRjaD1cdTVCOUVcdTk2NDVcdTUzQzJcdTY1NzBcdTUyMTdcdTg4NjhcdTU0OENcdTVGNjJcdTVGMEZcdTUzQzJcdTY1NzBcdTUyMTdcdTg4NjhcdTk1N0ZcdTVFQTZcdTRFMERcdTU0MEMKCiMgMDogc3RyaW5nCmNvbXBpbGVyLm1pc2Mud3JvbmcubnVtYmVyLnR5cGUuYXJncz1cdTdDN0JcdTU3OEJcdTUzRDhcdTkxQ0ZcdTY1NzBcdTc2RUVcdTk1MTlcdThCRUY7IFx1OTcwMFx1ODk4MXswfQoKIyAwOiBtZXNzYWdlIHNlZ21lbnQKY29tcGlsZXIubWlzYy5uby5jb25mb3JtaW5nLmFzc2lnbm1lbnQuZXhpc3RzPVx1NTNDMlx1NjU3MFx1NEUwRFx1NTMzOVx1OTE0RDsgezB9CgojIDA6IG1lc3NhZ2Ugc2VnbWVudApjb21waWxlci5taXNjLnZhcmFyZ3MuYXJndW1lbnQubWlzbWF0Y2g9dmFyYXJncyBcdTRFMERcdTUzMzlcdTkxNEQ7IHswfQoKIyMjIyMKCiMgMDogc3ltYm9sIG9yIHR5cGUsIDE6IGZpbGUgbmFtZQpjb21waWxlci53YXJuLmF1eGlsaWFyeS5jbGFzcy5hY2Nlc3NlZC5mcm9tLm91dHNpZGUub2YuaXRzLnNvdXJjZS5maWxlPXsxfSBcdTRFMkRcdTc2ODRcdThGODVcdTUyQTlcdTdDN0J7MH1cdTRFMERcdTVFOTRcdTRFQ0VcdTUxNzZcdTgxRUFcdThFQUJcdTc2ODRcdTZFOTBcdTY1ODdcdTRFRjZcdTRFRTVcdTU5MTZcdThCQkZcdTk1RUUKCiMjIFRoZSBmaXJzdCBhcmd1bWVudCAoezB9KSBpcyBhICJraW5kbmFtZSIuCiMgMDogc3ltYm9sIGtpbmQsIDE6IHN5bWJvbCwgMjogc3ltYm9sCmNvbXBpbGVyLmVyci5hYnN0cmFjdC5jYW50LmJlLmFjY2Vzc2VkLmRpcmVjdGx5PVx1NjVFMFx1NkNENVx1NzZGNFx1NjNBNVx1OEJCRlx1OTVFRXsyfVx1NEUyRFx1NzY4NFx1NjJCRFx1OEM2MXswfSB7MX0KCiMjIFRoZSBmaXJzdCBhcmd1bWVudCAoezB9KSBpcyBhICJraW5kbmFtZSIuCiMgMDogc3ltYm9sIGtpbmQsIDE6IHN5bWJvbApjb21waWxlci5lcnIubm9uLXN0YXRpYy5jYW50LmJlLnJlZj1cdTY1RTBcdTZDRDVcdTRFQ0VcdTk3NTlcdTYwMDFcdTRFMEFcdTRFMEJcdTY1ODdcdTRFMkRcdTVGMTVcdTc1MjhcdTk3NUVcdTk3NTlcdTYwMDEgezB9IHsxfQoKIyAwOiBzeW1ib2wga2luZCwgMTogc3ltYm9sCmNvbXBpbGVyLm1pc2MuYmFkLnN0YXRpYy5tZXRob2QuaW4udW5ib3VuZC5sb29rdXA9XHU1NzI4XHU2NzJBXHU3RUQxXHU1QjlBXHU2N0U1XHU2MjdFXHU0RTJEXHU2MjdFXHU1MjMwXHU2MTBGXHU1OTE2XHU3Njg0XHU5NzU5XHU2MDAxIHswfSB7MX0KCiMgMDogc3ltYm9sIGtpbmQsIDE6IHN5bWJvbApjb21waWxlci5taXNjLmJhZC5pbnN0YW5jZS5tZXRob2QuaW4udW5ib3VuZC5sb29rdXA9XHU1NzI4XHU2NzJBXHU3RUQxXHU1QjlBXHU2N0U1XHU2MjdFXHU0RTJEXHU2MjdFXHU1MjMwXHU2MTBGXHU1OTE2XHU3Njg0XHU1QjlFXHU0RjhCIHswfSB7MX0KCiMgMDogc3ltYm9sIGtpbmQsIDE6IHN5bWJvbApjb21waWxlci5taXNjLmJhZC5zdGF0aWMubWV0aG9kLmluLmJvdW5kLmxvb2t1cD1cdTU3MjhcdTdFRDFcdTVCOUFcdTY3RTVcdTYyN0VcdTRFMkRcdTYyN0VcdTUyMzBcdTYxMEZcdTU5MTZcdTc2ODRcdTk3NTlcdTYwMDEgezB9IHsxfQoKIyMgQm90aCBhcmd1bWVudHMgKHswfSwgezF9KSBhcmUgImtpbmRuYW1lInMuICB7MH0gaXMgYSBjb21tYS1zZXBhcmF0ZWQgbGlzdAojIyBvZiBraW5kbmFtZXMgKHRoZSBsaXN0IHNob3VsZCBiZSBpZGVudGljYWwgdG8gdGhhdCBwcm92aWRlZCBpbiBzb3VyY2UuCmNvbXBpbGVyLmVyci51bmV4cGVjdGVkLnR5cGU9XHU2MTBGXHU1OTE2XHU3Njg0XHU3QzdCXHU1NzhCXG5cdTk3MDBcdTg5ODE6IHswfVxuXHU2MjdFXHU1MjMwOiAgICB7MX0KCmNvbXBpbGVyLmVyci51bmV4cGVjdGVkLmxhbWJkYT1cdTZCNjRcdTU5MDRcdTRFMERcdTVFOTRcdTRFM0EgbGFtYmRhIFx1ODg2OFx1OEZCRVx1NUYwRgoKY29tcGlsZXIuZXJyLnVuZXhwZWN0ZWQubXJlZj1cdTZCNjRcdTU5MDRcdTRFMERcdTVFOTRcdTRFM0FcdTY1QjlcdTZDRDVcdTVGMTVcdTc1MjgKCiMjIFRoZSBmaXJzdCBhcmd1bWVudCB7MH0gaXMgYSAia2luZG5hbWUiIChlLmcuICdjb25zdHJ1Y3RvcicsICdmaWVsZCcsIGV0Yy4pCiMjIFRoZSBzZWNvbmQgYXJndW1lbnQgezF9IGlzIHRoZSBub24tcmVzb2x2ZWQgc3ltYm9sCiMjIFRoZSB0aGlyZCBhcmd1bWVudCB7Mn0gaXMgYSBsaXN0IG9mIHR5cGUgcGFyYW1ldGVycyAobm9uLWVtcHR5IGlmIHsxfSBpcyBhIG1ldGhvZCkKIyMgVGhlIGZvdXJ0aCBhcmd1bWVudCB7M30gaXMgYSBsaXN0IG9mIGFyZ3VtZW50IHR5cGVzIChub24tZW1wdHkgaWYgezF9IGlzIGEgbWV0aG9kKQojIDA6IHN5bWJvbCBraW5kLCAxOiBuYW1lLCAyOiB1bnVzZWQsIDM6IHVudXNlZApjb21waWxlci5lcnIuY2FudC5yZXNvbHZlPVx1NjI3RVx1NEUwRFx1NTIzMFx1N0IyNlx1NTNGN1xuXHU3QjI2XHU1M0Y3OiB7MH0gezF9CgojIDA6IHN5bWJvbCBraW5kLCAxOiBuYW1lLCAyOiB1bnVzZWQsIDM6IGxpc3Qgb2YgdHlwZQpjb21waWxlci5lcnIuY2FudC5yZXNvbHZlLmFyZ3M9XHU2MjdFXHU0RTBEXHU1MjMwXHU3QjI2XHU1M0Y3XG5cdTdCMjZcdTUzRjc6IHswfSB7MX0oezN9KQoKIyAwOiBzeW1ib2wga2luZCwgMTogbmFtZSwgMjogbGlzdCBvZiB0eXBlLCAzOiBsaXN0IG9mIHR5cGUKY29tcGlsZXIuZXJyLmNhbnQucmVzb2x2ZS5hcmdzLnBhcmFtcz1cdTYyN0VcdTRFMERcdTUyMzBcdTdCMjZcdTUzRjdcblx1N0IyNlx1NTNGNzogezB9IDx7Mn0+ezF9KHszfSkKCiMjIGFyZ3VtZW50cyBmcm9tIHswfSB0byB7M30gaGF2ZSB0aGUgc2FtZSBtZWFuaW5nIGFzIGFib3ZlCiMjIFRoZSBmaWZ0aCBhcmd1bWVudCB7NH0gaXMgYSBsb2NhdGlvbiBzdWJkaWFnbm9zdGljIChzZWUgYmVsb3cpCiMgMDogc3ltYm9sIGtpbmQsIDE6IG5hbWUsIDI6IHVudXNlZCwgMzogdW51c2VkLCA0OiBtZXNzYWdlIHNlZ21lbnQKY29tcGlsZXIuZXJyLmNhbnQucmVzb2x2ZS5sb2NhdGlvbj1cdTYyN0VcdTRFMERcdTUyMzBcdTdCMjZcdTUzRjdcblx1N0IyNlx1NTNGNzogICB7MH0gezF9XG5cdTRGNERcdTdGNkU6IHs0fQoKIyAwOiBzeW1ib2wga2luZCwgMTogbmFtZSwgMjogdW51c2VkLCAzOiBsaXN0IG9mIHR5cGUsIDQ6IG1lc3NhZ2Ugc2VnbWVudApjb21waWxlci5lcnIuY2FudC5yZXNvbHZlLmxvY2F0aW9uLmFyZ3M9XHU2MjdFXHU0RTBEXHU1MjMwXHU3QjI2XHU1M0Y3XG5cdTdCMjZcdTUzRjc6ICAgezB9IHsxfSh7M30pXG5cdTRGNERcdTdGNkU6IHs0fQoKIyAwOiBzeW1ib2wga2luZCwgMTogbmFtZSwgMjogbGlzdCBvZiB0eXBlLCAzOiBsaXN0LCA0OiBtZXNzYWdlIHNlZ21lbnQKY29tcGlsZXIuZXJyLmNhbnQucmVzb2x2ZS5sb2NhdGlvbi5hcmdzLnBhcmFtcz1cdTYyN0VcdTRFMERcdTUyMzBcdTdCMjZcdTUzRjdcblx1N0IyNlx1NTNGNzogICB7MH0gPHsyfT57MX0oezN9KVxuXHU0RjREXHU3RjZFOiB7NH0KCiMjIyBGb2xsb3dpbmcgYXJlIHJlcGxpY2F0ZWQvdXNlZCBmb3IgbWV0aG9kIHJlZmVyZW5jZSBkaWFnbm9zdGljcwoKIyAwOiBzeW1ib2wga2luZCwgMTogbmFtZSwgMjogdW51c2VkLCAzOiBsaXN0IG9mIHR5cGUsIDQ6IG1lc3NhZ2Ugc2VnbWVudApjb21waWxlci5taXNjLmNhbnQucmVzb2x2ZS5sb2NhdGlvbi5hcmdzPVx1NjI3RVx1NEUwRFx1NTIzMFx1N0IyNlx1NTNGN1xuXHU3QjI2XHU1M0Y3OiAgIHswfSB7MX0oezN9KVxuXHU0RjREXHU3RjZFOiB7NH0KCiMgMDogc3ltYm9sIGtpbmQsIDE6IG5hbWUsIDI6IGxpc3Qgb2YgdHlwZSwgMzogbGlzdCwgNDogbWVzc2FnZSBzZWdtZW50CmNvbXBpbGVyLm1pc2MuY2FudC5yZXNvbHZlLmxvY2F0aW9uLmFyZ3MucGFyYW1zPVx1NjI3RVx1NEUwRFx1NTIzMFx1N0IyNlx1NTNGN1xuXHU3QjI2XHU1M0Y3OiAgIHswfSA8ezJ9PnsxfSh7M30pXG5cdTRGNERcdTdGNkU6IHs0fQoKIyNhIGxvY2F0aW9uIHN1YmRpYWdub3N0aWMgaXMgY29tcG9zZWQgYXMgZm9sbG93czoKIyMgVGhlIGZpcnN0IGFyZ3VtZW50IHswfSBpcyB0aGUgbG9jYXRpb24gImtpbmRuYW1lIiAoZS5nLiAnY29uc3RydWN0b3InLCAnZmllbGQnLCBldGMuKQojIyBUaGUgc2Vjb25kIGFyZ3VtZW50IHsxfSBpcyB0aGUgbG9jYXRpb24gbmFtZQojIyBUaGUgdGhpcmQgYXJndW1lbnQgezJ9IGlzIHRoZSBsb2NhdGlvbiB0eXBlIChvbmx5IHdoZW4gezF9IGlzIGEgdmFyaWFibGUgbmFtZSkKCiMgMDogc3ltYm9sIGtpbmQsIDE6IHR5cGUgb3Igc3ltYm9sLCAyOiB1bnVzZWQKY29tcGlsZXIubWlzYy5sb2NhdGlvbj17MH0gezF9CgojIDA6IHN5bWJvbCBraW5kLCAxOiBzeW1ib2wsIDI6IHR5cGUKY29tcGlsZXIubWlzYy5sb2NhdGlvbi4xPVx1N0M3Qlx1NTc4Qlx1NEUzQXsyfVx1NzY4NHswfSB7MX0KCiMjIFRoZSBmb2xsb3dpbmcgYXJlIGFsbCBwb3NzaWJsZSBzdHJpbmcgZm9yICJraW5kbmFtZSIuCiMjIFRoZXkgc2hvdWxkIGJlIGNhbGxlZCB3aGF0ZXZlciB0aGUgSkxTIGNhbGxzIHRoZW0gYWZ0ZXIgaXQgYmVlbiB0cmFuc2xhdGVkCiMjIHRvIHRoZSBhcHByb3ByaWF0ZSBsYW5ndWFnZS4KIyBjb21waWxlci5taXNjLmtpbmRuYW1lLmNvbnN0cnVjdG9yPVwKIyAgICAgc3RhdGljIG1lbWJlcgpjb21waWxlci5taXNjLmtpbmRuYW1lLmFubm90YXRpb249QGludGVyZmFjZQoKY29tcGlsZXIubWlzYy5raW5kbmFtZS5jb25zdHJ1Y3Rvcj1cdTY3ODRcdTkwMjBcdTU2NjgKCmNvbXBpbGVyLm1pc2Mua2luZG5hbWUuZW51bT1cdTY3OUFcdTRFM0UKCmNvbXBpbGVyLm1pc2Mua2luZG5hbWUuaW50ZXJmYWNlPVx1NjNBNVx1NTNFMwoKY29tcGlsZXIubWlzYy5raW5kbmFtZS5zdGF0aWM9XHU5NzU5XHU2MDAxCgpjb21waWxlci5taXNjLmtpbmRuYW1lLnR5cGUudmFyaWFibGU9XHU3QzdCXHU1NzhCXHU1M0Q4XHU5MUNGCgpjb21waWxlci5taXNjLmtpbmRuYW1lLnR5cGUudmFyaWFibGUuYm91bmQ9XHU3QzdCXHU1NzhCXHU1M0Q4XHU5MUNGXHU3Njg0XHU5NjUwXHU1MjM2XHU4MzAzXHU1NkY0Cgpjb21waWxlci5taXNjLmtpbmRuYW1lLnZhcmlhYmxlPVx1NTNEOFx1OTFDRgoKY29tcGlsZXIubWlzYy5raW5kbmFtZS52YWx1ZT1cdTUwM0MKCmNvbXBpbGVyLm1pc2Mua2luZG5hbWUubWV0aG9kPVx1NjVCOVx1NkNENQoKY29tcGlsZXIubWlzYy5raW5kbmFtZS5jbGFzcz1cdTdDN0IKCmNvbXBpbGVyLm1pc2Mua2luZG5hbWUucGFja2FnZT1cdTdBMEJcdTVFOEZcdTUzMDUKCmNvbXBpbGVyLm1pc2Mua2luZG5hbWUubW9kdWxlPVx1NkEyMVx1NTc1NwoKY29tcGlsZXIubWlzYy5raW5kbmFtZS5zdGF0aWMuaW5pdD1cdTk3NTlcdTYwMDFcdTUyMURcdTU5Q0JcdTUzMTZcdTdBMEJcdTVFOEYKCmNvbXBpbGVyLm1pc2Mua2luZG5hbWUuaW5zdGFuY2UuaW5pdD1cdTVCOUVcdTRGOEJcdTUyMURcdTU5Q0JcdTUzMTZcdTdBMEJcdTVFOEYKCiMjIyMjCgpjb21waWxlci5taXNjLm5vLmFyZ3M9XHU2Q0ExXHU2NzA5XHU1M0MyXHU2NTcwCgojIDA6IG1lc3NhZ2Ugc2VnbWVudApjb21waWxlci5lcnIub3ZlcnJpZGUuc3RhdGljPXswfVxuXHU4OTg2XHU3NkQ2XHU3Njg0XHU2NUI5XHU2Q0Q1XHU0RTNBIHN0YXRpYwoKIyAwOiBtZXNzYWdlIHNlZ21lbnQsIDE6IHNldCBvZiBtb2RpZmllcgpjb21waWxlci5lcnIub3ZlcnJpZGUubWV0aD17MH1cblx1ODhBQlx1ODk4Nlx1NzZENlx1NzY4NFx1NjVCOVx1NkNENVx1NEUzQXsxfQoKIyAwOiBtZXNzYWdlIHNlZ21lbnQsIDE6IHR5cGUKY29tcGlsZXIuZXJyLm92ZXJyaWRlLm1ldGguZG9lc250LnRocm93PXswfVxuXHU4OEFCXHU4OTg2XHU3NkQ2XHU3Njg0XHU2NUI5XHU2Q0Q1XHU2NzJBXHU2MjlCXHU1MUZBezF9CgojIEluIHRoZSBmb2xsb3dpbmcgc3RyaW5nIHsxfSBpcyBhIHNwYWNlIHNlcGFyYXRlZCBsaXN0IG9mIEphdmEgS2V5d29yZHMsIGFzCiMgdGhleSB3b3VsZCBoYXZlIGJlZW4gZGVjbGFyZWQgaW4gdGhlIHNvdXJjZSBjb2RlCiMgMDogbWVzc2FnZSBzZWdtZW50LCAxOiBzZXQgb2YgbW9kaWZpZXIKY29tcGlsZXIuZXJyLm92ZXJyaWRlLndlYWtlci5hY2Nlc3M9ezB9XG5cdTZCNjNcdTU3MjhcdTVDMURcdThCRDVcdTUyMDZcdTkxNERcdTY2RjRcdTRGNEVcdTc2ODRcdThCQkZcdTk1RUVcdTY3NDNcdTk2NTA7IFx1NEVFNVx1NTI0RFx1NEUzQXsxfQoKIyAwOiBtZXNzYWdlIHNlZ21lbnQsIDE6IHR5cGUsIDI6IHR5cGUKY29tcGlsZXIuZXJyLm92ZXJyaWRlLmluY29tcGF0aWJsZS5yZXQ9ezB9XG5cdThGRDRcdTU2REVcdTdDN0JcdTU3OEJ7MX1cdTRFMEV7Mn1cdTRFMERcdTUxN0NcdTVCQjkKCiMgMDogbWVzc2FnZSBzZWdtZW50LCAxOiB0eXBlLCAyOiB0eXBlCmNvbXBpbGVyLndhcm4ub3ZlcnJpZGUudW5jaGVja2VkLnJldD17MH1cblx1OEZENFx1NTZERVx1N0M3Qlx1NTc4Qlx1OTcwMFx1ODk4MVx1NEVDRXsxfVx1NTIzMHsyfVx1NzY4NFx1NjcyQVx1N0VDRlx1NjhDMFx1NjdFNVx1NzY4NFx1OEY2Q1x1NjM2MgoKIyAwOiBtZXNzYWdlIHNlZ21lbnQsIDE6IHR5cGUKY29tcGlsZXIud2Fybi5vdmVycmlkZS51bmNoZWNrZWQudGhyb3duPXswfVxuXHU4OEFCXHU4OTg2XHU3NkQ2XHU3Njg0XHU2NUI5XHU2Q0Q1XHU2NzJBXHU2MjlCXHU1MUZBezF9CgojIDA6IHN5bWJvbApjb21waWxlci53YXJuLm92ZXJyaWRlLmVxdWFscy5idXQubm90Lmhhc2hjb2RlPVx1N0M3QnswfVx1ODk4Nlx1NzZENlx1NEU4NiBlcXVhbHMsIFx1NEY0Nlx1OEJFNVx1N0M3Qlx1NjIxNlx1NEVGQlx1NEY1NVx1OEQ4NVx1N0M3Qlx1OTBGRFx1NjcyQVx1ODk4Nlx1NzZENiBoYXNoQ29kZSBcdTY1QjlcdTZDRDUKCiMjIFRoZSBmb2xsb3dpbmcgYXJlIGFsbCBwb3NzaWJsZSBzdHJpbmdzIGZvciB0aGUgZmlyc3QgYXJndW1lbnQgKHswfSkgb2YgdGhlCiMjIGFib3ZlIHN0cmluZ3MuCiMgMDogc3ltYm9sLCAxOiBzeW1ib2wsIDI6IHN5bWJvbCwgMzogc3ltYm9sCmNvbXBpbGVyLm1pc2MuY2FudC5vdmVycmlkZT17MX1cdTRFMkRcdTc2ODR7MH1cdTY1RTBcdTZDRDVcdTg5ODZcdTc2RDZ7M31cdTRFMkRcdTc2ODR7Mn0KCiMgMDogc3ltYm9sLCAxOiBzeW1ib2wsIDI6IHN5bWJvbCwgMzogc3ltYm9sCmNvbXBpbGVyLm1pc2MuY2FudC5oaWRlPXsxfSBcdTRFMkRcdTc2ODQgezB9IFx1NjVFMFx1NkNENVx1OTY5MFx1ODVDRiB7M30gXHU0RTJEXHU3Njg0IHsyfQoKIyAwOiBzeW1ib2wsIDE6IHN5bWJvbCwgMjogc3ltYm9sLCAzOiBzeW1ib2wKY29tcGlsZXIubWlzYy5jYW50LmltcGxlbWVudD17MX1cdTRFMkRcdTc2ODR7MH1cdTY1RTBcdTZDRDVcdTVCOUVcdTczQjB7M31cdTRFMkRcdTc2ODR7Mn0KCiMgMDogc3ltYm9sLCAxOiBzeW1ib2wsIDI6IHN5bWJvbCwgMzogc3ltYm9sCmNvbXBpbGVyLm1pc2MuY2xhc2hlcy53aXRoPXsxfVx1NEUyRFx1NzY4NHswfVx1NEUwRXszfVx1NEUyRFx1NzY4NHsyfVx1NTFCMlx1N0E4MQoKIyAwOiBzeW1ib2wsIDE6IHN5bWJvbCwgMjogc3ltYm9sLCAzOiBzeW1ib2wKY29tcGlsZXIubWlzYy51bmNoZWNrZWQub3ZlcnJpZGU9ezF9XHU0RTJEXHU3Njg0ezB9XHU4OTg2XHU3NkQ2XHU0RTg2ezN9XHU0RTJEXHU3Njg0ezJ9CgojIDA6IHN5bWJvbCwgMTogc3ltYm9sLCAyOiBzeW1ib2wsIDM6IHN5bWJvbApjb21waWxlci5taXNjLnVuY2hlY2tlZC5pbXBsZW1lbnQ9ezF9XHU0RTJEXHU3Njg0ezB9XHU1QjlFXHU3M0IwXHU0RTg2ezN9XHU0RTJEXHU3Njg0ezJ9CgojIDA6IHN5bWJvbCwgMTogc3ltYm9sLCAyOiBzeW1ib2wsIDM6IHN5bWJvbApjb21waWxlci5taXNjLnVuY2hlY2tlZC5jbGFzaC53aXRoPXsxfVx1NEUyRFx1NzY4NHswfVx1ODk4Nlx1NzZENlx1NEU4NnszfVx1NEUyRFx1NzY4NHsyfQoKIyAwOiBzeW1ib2wsIDE6IHN5bWJvbCwgMjogc3ltYm9sLCAzOiBzeW1ib2wKY29tcGlsZXIubWlzYy52YXJhcmdzLm92ZXJyaWRlPXsxfVx1NEUyRFx1NzY4NHswfVx1ODk4Nlx1NzZENlx1NEU4NnszfVx1NEUyRFx1NzY4NHsyfQoKIyAwOiBzeW1ib2wsIDE6IHN5bWJvbCwgMjogc3ltYm9sLCAzOiBzeW1ib2wKY29tcGlsZXIubWlzYy52YXJhcmdzLmltcGxlbWVudD17MX1cdTRFMkRcdTc2ODR7MH1cdTVCOUVcdTczQjBcdTRFODZ7M31cdTRFMkRcdTc2ODR7Mn0KCiMgMDogc3ltYm9sLCAxOiBzeW1ib2wsIDI6IHN5bWJvbCwgMzogc3ltYm9sCmNvbXBpbGVyLm1pc2MudmFyYXJncy5jbGFzaC53aXRoPXsxfVx1NEUyRFx1NzY4NHswfVx1ODk4Nlx1NzZENlx1NEU4NnszfVx1NEUyRFx1NzY4NHsyfQoKIyAwOiBzeW1ib2wga2luZCwgMTogc3ltYm9sLCAyOiBzeW1ib2wsIDM6IG1lc3NhZ2Ugc2VnbWVudApjb21waWxlci5taXNjLmluYXBwbGljYWJsZS5tZXRob2Q9ezB9IHsxfS57Mn1cdTRFMERcdTkwMDJcdTc1Mjhcbih7M30pCgojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCiMgRGlhZ25vc3RpY3MgZm9yIGxhbmd1YWdlIGZlYXR1cmUgY2hhbmdlcwojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCgojIDA6IHN0cmluZwpjb21waWxlci5lcnIubW9kdWxlcy5ub3Quc3VwcG9ydGVkLmluLnNvdXJjZT0tc291cmNlIHswfSBcdTRFMkRcdTRFMERcdTY1MkZcdTYzMDFcdTZBMjFcdTU3NTdcbihcdThCRjdcdTRGN0ZcdTc1MjggLXNvdXJjZSA5IFx1NjIxNlx1NjZGNFx1OUFEOFx1NzI0OFx1NjcyQ1x1NEVFNVx1NTQyRlx1NzUyOFx1NkEyMVx1NTc1NykKCiMgMDogc3RyaW5nCmNvbXBpbGVyLm1pc2MuZGlhbW9uZC5hbmQuYW5vbi5jbGFzcy5ub3Quc3VwcG9ydGVkLmluLnNvdXJjZT1cdTU3MjggLXNvdXJjZSB7MH0gXHU0RTJEXHU2NUUwXHU2Q0Q1XHU0RjdGXHU3NTI4XHU1RTI2XHU2NzA5XHU1MzNGXHU1NDBEXHU1MTg1XHU5MEU4XHU3QzdCXHU3Njg0ICcnPD4nJ1xuKFx1OEJGN1x1NEY3Rlx1NzUyOCAtc291cmNlIDkgXHU2MjE2XHU2NkY0XHU5QUQ4XHU3MjQ4XHU2NzJDXHU0RUU1XHU1MTQxXHU4QkI4XHU1RTI2XHU2NzA5XHU1MzNGXHU1NDBEXHU1MTg1XHU5MEU4XHU3QzdCXHU3Njg0ICcnPD4nJykKCiMgMDogc3RyaW5nCmNvbXBpbGVyLmVyci51bnN1cHBvcnRlZC5iaW5hcnkubGl0PS1zb3VyY2UgezB9IFx1NEUyRFx1NEUwRFx1NjUyRlx1NjMwMVx1NEU4Q1x1OEZEQlx1NTIzNlx1NjU4N1x1NUI1N1xuKFx1OEJGN1x1NEY3Rlx1NzUyOCAtc291cmNlIDcgXHU2MjE2XHU2NkY0XHU5QUQ4XHU3MjQ4XHU2NzJDXHU0RUU1XHU1NDJGXHU3NTI4XHU0RThDXHU4RkRCXHU1MjM2XHU2NTg3XHU1QjU3KQoKIyAwOiBzdHJpbmcKY29tcGlsZXIuZXJyLnVuc3VwcG9ydGVkLnVuZGVyc2NvcmUubGl0PS1zb3VyY2UgezB9IFx1NEUyRFx1NEUwRFx1NjUyRlx1NjMwMVx1NjU4N1x1NUI1N1x1NEUyRFx1NUI1OFx1NTcyOFx1NEUwQlx1NTIxMlx1N0VCRlxuKFx1OEJGN1x1NEY3Rlx1NzUyOCAtc291cmNlIDcgXHU2MjE2XHU2NkY0XHU5QUQ4XHU3MjQ4XHU2NzJDXHU0RUU1XHU1MTQxXHU4QkI4XHU2NTg3XHU1QjU3XHU0RTJEXHU1QjU4XHU1NzI4XHU0RTBCXHU1MjEyXHU3RUJGKQoKIyAwOiBzdHJpbmcKY29tcGlsZXIuZXJyLnRyeS53aXRoLnJlc291cmNlcy5ub3Quc3VwcG9ydGVkLmluLnNvdXJjZT0tc291cmNlIHswfSBcdTRFMkRcdTRFMERcdTY1MkZcdTYzMDEgdHJ5LXdpdGgtcmVzb3VyY2VzXG4oXHU4QkY3XHU0RjdGXHU3NTI4IC1zb3VyY2UgNyBcdTYyMTZcdTY2RjRcdTlBRDhcdTcyNDhcdTY3MkNcdTRFRTVcdTU0MkZcdTc1MjggdHJ5LXdpdGgtcmVzb3VyY2VzKQoKIyAwOiBzdHJpbmcKY29tcGlsZXIuZXJyLnZhci5pbi50cnkud2l0aC5yZXNvdXJjZXMubm90LnN1cHBvcnRlZC5pbi5zb3VyY2U9LXNvdXJjZSB7MH0gXHU0RTJEXHU0RTBEXHU2NTJGXHU2MzAxXHU1NzI4IHRyeS13aXRoLXJlc291cmNlcyBcdTRGN0ZcdTc1MjhcdTUzRDhcdTkxQ0ZcbihcdThCRjdcdTRGN0ZcdTc1MjggLXNvdXJjZSA5IFx1NjIxNlx1NjZGNFx1OUFEOFx1NzI0OFx1NjcyQ1x1NEVFNVx1NTE0MVx1OEJCOFx1NTcyOCB0cnktd2l0aC1yZXNvdXJjZXMgXHU0RTJEXHU0RjdGXHU3NTI4XHU1M0Q4XHU5MUNGKQoKY29tcGlsZXIud2Fybi51bmRlcnNjb3JlLmFzLmlkZW50aWZpZXI9XHU0RUNFXHU1M0QxXHU4ODRDXHU3MjQ4IDkgXHU1RjAwXHU1OUNCLCAnJ18nJyBcdTRFM0FcdTUxNzNcdTk1MkVcdTVCNTcsIFx1NEUwRFx1ODBGRFx1NzUyOFx1NEY1Q1x1NjgwN1x1OEJDNlx1N0IyNgoKY29tcGlsZXIuZXJyLnVuZGVyc2NvcmUuYXMuaWRlbnRpZmllcj1cdTRFQ0VcdTUzRDFcdTg4NENcdTcyNDggOSBcdTVGMDBcdTU5Q0IsICcnXycnIFx1NEUzQVx1NTE3M1x1OTUyRVx1NUI1NywgXHU0RTBEXHU4MEZEXHU3NTI4XHU0RjVDXHU2ODA3XHU4QkM2XHU3QjI2Cgpjb21waWxlci5lcnIudW5kZXJzY29yZS5hcy5pZGVudGlmaWVyLmluLmxhbWJkYT0nJ18nJyBcdTc1MjhcdTRGNUNcdTY4MDdcdThCQzZcdTdCMjZcbihcdTVCRjlcdTRFOEUgbGFtYmRhIFx1NTNDMlx1NjU3MCwgXHU3OTgxXHU2QjYyXHU1QzA2ICcnXycnIFx1NzUyOFx1NEY1Q1x1NjgwN1x1OEJDNlx1N0IyNikKCmNvbXBpbGVyLmVyci5lbnVtLmFzLmlkZW50aWZpZXI9XHU0RUNFXHU1M0QxXHU4ODRDXHU3MjQ4IDUgXHU1RjAwXHU1OUNCLCAnJ2VudW0nJyBcdTRFM0FcdTUxNzNcdTk1MkVcdTVCNTcsIFx1NEUwRFx1ODBGRFx1NzUyOFx1NEY1Q1x1NjgwN1x1OEJDNlx1N0IyNgoKY29tcGlsZXIuZXJyLmFzc2VydC5hcy5pZGVudGlmaWVyPVx1NEVDRVx1NTNEMVx1ODg0Q1x1NzI0OCAxLjQgXHU1RjAwXHU1OUNCLCAnJ2Fzc2VydCcnIFx1NEUzQVx1NTE3M1x1OTUyRVx1NUI1NywgXHU0RTBEXHU4MEZEXHU3NTI4XHU0RjVDXHU2ODA3XHU4QkM2XHU3QjI2CgojIFRPRE8gMzA4OiBtYWtlIGEgYmV0dGVyIGVycm9yIG1lc3NhZ2UKY29tcGlsZXIuZXJyLnRoaXMuYXMuaWRlbnRpZmllcj1cdTRFQ0VcdTUzRDFcdTg4NENcdTcyNDggOCBcdTVGMDBcdTU5Q0IsICcndGhpcycnIFx1NTNFQVx1ODBGRFx1NEY1Q1x1NEUzQVx1NjNBNVx1NjUzNlx1NjVCOVx1N0M3Qlx1NTc4Qlx1NzY4NFx1NTNDMlx1NjU3MFx1NTQwRCwgXHU4QkU1XHU1M0MyXHU2NTcwXHU1RkM1XHU5ODdCXHU0RTNBXHU3QjJDXHU0RTAwXHU0RTJBXHU1M0MyXHU2NTcwCgojIDA6IHN5bWJvbApjb21waWxlci5lcnIucmVjZWl2ZXIucGFyYW1ldGVyLm5vdC5hcHBsaWNhYmxlLmNvbnN0cnVjdG9yLnRvcGxldmVsLmNsYXNzPVx1NjNBNVx1NjUzNlx1NjVCOVx1NTNDMlx1NjU3MFx1NEUwRFx1OTAwMlx1NzUyOFx1NEU4RVx1OTg3Nlx1NUM0Mlx1N0M3Qlx1NzY4NFx1Njc4NFx1OTAyMFx1NTY2OAoKIyBUT0RPIDMwODogbWFrZSBhIGJldHRlciBlcnJvciBtZXNzYWdlCiMgMDogc3ltYm9sCmNvbXBpbGVyLmVyci5jYW50LnR5cGUuYW5ub3RhdGUuc2NvcGluZy4xPVx1NjVFMFx1NkNENVx1NEY3Rlx1NzUyOCB0eXBlLXVzZSBcdTZDRThcdTkxQ0EgezB9IFx1Njc2NVx1NkNFOFx1OTFDQVx1Nzg2RVx1NUI5QVx1NEY1Q1x1NzUyOFx1NTdERlx1N0VEM1x1Njc4NAoKIyBUT0RPIDMwODogbWFrZSBhIGJldHRlciBlcnJvciBtZXNzYWdlCiMgMDogbGlzdCBvZiBzeW1ib2wKY29tcGlsZXIuZXJyLmNhbnQudHlwZS5hbm5vdGF0ZS5zY29waW5nPVx1NjVFMFx1NkNENVx1NEY3Rlx1NzUyOCB0eXBlLXVzZSBcdTZDRThcdTkxQ0EgezB9IFx1Njc2NVx1NkNFOFx1OTFDQVx1Nzg2RVx1NUI5QVx1NEY1Q1x1NzUyOFx1NTdERlx1N0VEM1x1Njc4NAoKIyAwOiB0eXBlLCAxOiB0eXBlCmNvbXBpbGVyLmVyci5pbmNvcnJlY3QucmVjZWl2ZXIubmFtZT1cdTYzQTVcdTY1MzZcdTY1QjlcdTU0MERcdTc5RjBcdTRFMEVcdTVDMDFcdTk1RURcdTdDN0JcdTdDN0JcdTU3OEJcdTRFMERcdTUzMzlcdTkxNERcblx1OTcwMFx1ODk4MTogezB9XG5cdTYyN0VcdTUyMzA6IHsxfQoKIyAwOiB0eXBlLCAxOiB0eXBlCmNvbXBpbGVyLmVyci5pbmNvcnJlY3QucmVjZWl2ZXIudHlwZT1cdTYzQTVcdTY1MzZcdTY1QjlcdTdDN0JcdTU3OEJcdTRFMEVcdTVDMDFcdTk1RURcdTdDN0JcdTdDN0JcdTU3OEJcdTRFMERcdTUzMzlcdTkxNERcblx1OTcwMFx1ODk4MTogezB9XG5cdTYyN0VcdTUyMzA6IHsxfQoKIyAwOiB0eXBlLCAxOiB0eXBlCmNvbXBpbGVyLmVyci5pbmNvcnJlY3QuY29uc3RydWN0b3IucmVjZWl2ZXIudHlwZT1cdTYzQTVcdTY1MzZcdTY1QjlcdTdDN0JcdTU3OEJcdTRFMEVcdTU5MTZcdTkwRThcdTVDMDFcdTk1RURcdTdDN0JcdTdDN0JcdTU3OEJcdTRFMERcdTUzMzlcdTkxNERcblx1OTcwMFx1ODk4MTogezB9XG5cdTYyN0VcdTUyMzA6IHsxfQoKIyAwOiB0eXBlLCAxOiB0eXBlCmNvbXBpbGVyLmVyci5pbmNvcnJlY3QuY29uc3RydWN0b3IucmVjZWl2ZXIubmFtZT1cdTYzQTVcdTY1MzZcdTY1QjlcdTU0MERcdTc5RjBcdTRFMEVcdTU5MTZcdTkwRThcdTVDMDFcdTk1RURcdTdDN0JcdTdDN0JcdTU3OEJcdTRFMERcdTUzMzlcdTkxNERcblx1OTcwMFx1ODk4MTogezB9XG5cdTYyN0VcdTUyMzA6IHsxfQoKY29tcGlsZXIuZXJyLm5vLmFubm90YXRpb25zLm9uLmRvdC5jbGFzcz1cdTdDN0JcdTY1ODdcdTVCNTdcdTdDN0JcdTU3OEJcdTRFMkRcdTRFMERcdTUxNDFcdThCQjhcdTRGN0ZcdTc1MjhcdTRFRkJcdTRGNTVcdTZDRThcdTkxQ0EKCiMgMDogc3RyaW5nCmNvbXBpbGVyLmVyci50eXBlLmFubm90YXRpb25zLm5vdC5zdXBwb3J0ZWQuaW4uc291cmNlPS1zb3VyY2UgezB9IFx1NEUyRFx1NEUwRFx1NjUyRlx1NjMwMVx1N0M3Qlx1NTc4Qlx1NkNFOFx1OTFDQVxuKFx1OEJGN1x1NEY3Rlx1NzUyOCAtc291cmNlIDggXHU2MjE2XHU2NkY0XHU5QUQ4XHU3MjQ4XHU2NzJDXHU0RUU1XHU1NDJGXHU3NTI4XHU3QzdCXHU1NzhCXHU2Q0U4XHU5MUNBKQoKIyAwOiBzdHJpbmcKY29tcGlsZXIuZXJyLmFubm90YXRpb25zLmFmdGVyLnR5cGUucGFyYW1zLm5vdC5zdXBwb3J0ZWQuaW4uc291cmNlPS1zb3VyY2UgezB9IFx1NEUyRFx1NEUwRFx1NjUyRlx1NjMwMVx1NjVCOVx1NkNENVx1N0M3Qlx1NTc4Qlx1NTNDMlx1NjU3MFx1NTQwRVx1NzY4NFx1NkNFOFx1OTFDQVxuKFx1OEJGN1x1NEY3Rlx1NzUyOCAtc291cmNlIDggXHU2MjE2XHU2NkY0XHU5QUQ4XHU3MjQ4XHU2NzJDXHU0RUU1XHU1NDJGXHU3NTI4XHU2NUI5XHU2Q0Q1XHU3QzdCXHU1NzhCXHU1M0MyXHU2NTcwXHU1NDBFXHU3Njg0XHU2Q0U4XHU5MUNBKQoKIyAwOiBzdHJpbmcKY29tcGlsZXIuZXJyLnJlcGVhdGFibGUuYW5ub3RhdGlvbnMubm90LnN1cHBvcnRlZC5pbi5zb3VyY2U9LXNvdXJjZSB7MH1cdTRFMkRcdTRFMERcdTY1MkZcdTYzMDFcdTkxQ0RcdTU5MERcdTZDRThcdTkxQ0FcbihcdThCRjdcdTRGN0ZcdTc1MjggLXNvdXJjZSA4IFx1NjIxNlx1NjZGNFx1OUFEOFx1NzI0OFx1NjcyQ1x1NEVFNVx1NTQyRlx1NzUyOFx1OTFDRFx1NTkwRFx1NkNFOFx1OTFDQSkKCiMgMDogc3RyaW5nCmNvbXBpbGVyLmVyci5kaWFtb25kLm5vdC5zdXBwb3J0ZWQuaW4uc291cmNlPS1zb3VyY2UgezB9IFx1NEUyRFx1NEUwRFx1NjUyRlx1NjMwMSBkaWFtb25kIFx1OEZEMFx1N0I5N1x1N0IyNlxuKFx1OEJGN1x1NEY3Rlx1NzUyOCAtc291cmNlIDcgXHU2MjE2XHU2NkY0XHU5QUQ4XHU3MjQ4XHU2NzJDXHU0RUU1XHU1NDJGXHU3NTI4IGRpYW1vbmQgXHU4RkQwXHU3Qjk3XHU3QjI2KQoKIyAwOiBzdHJpbmcKY29tcGlsZXIuZXJyLm11bHRpY2F0Y2gubm90LnN1cHBvcnRlZC5pbi5zb3VyY2U9LXNvdXJjZSB7MH0gXHU0RTJEXHU0RTBEXHU2NTJGXHU2MzAxIG11bHRpLWNhdGNoIFx1OEJFRFx1NTNFNVxuKFx1OEJGN1x1NEY3Rlx1NzUyOCAtc291cmNlIDcgXHU2MjE2XHU2NkY0XHU5QUQ4XHU3MjQ4XHU2NzJDXHU0RUU1XHU1NDJGXHU3NTI4IG11bHRpLWNhdGNoIFx1OEJFRFx1NTNFNSkKCiMgMDogc3RyaW5nCmNvbXBpbGVyLmVyci5zdHJpbmcuc3dpdGNoLm5vdC5zdXBwb3J0ZWQuaW4uc291cmNlPS1zb3VyY2UgezB9IFx1NEUyRFx1NEUwRFx1NjUyRlx1NjMwMSBzd2l0Y2ggXHU0RTJEXHU1QjU4XHU1NzI4XHU1QjU3XHU3QjI2XHU0RTMyXG4oXHU4QkY3XHU0RjdGXHU3NTI4IC1zb3VyY2UgNyBcdTYyMTZcdTY2RjRcdTlBRDhcdTcyNDhcdTY3MkNcdTRFRTVcdTUxNDFcdThCQjggc3dpdGNoIFx1NEUyRFx1NUI1OFx1NTcyOFx1NUI1N1x1N0IyNlx1NEUzMikKCiMgMDogc3RyaW5nCmNvbXBpbGVyLmVyci5sYW1iZGEubm90LnN1cHBvcnRlZC5pbi5zb3VyY2U9LXNvdXJjZSB7MH0gXHU0RTJEXHU0RTBEXHU2NTJGXHU2MzAxIGxhbWJkYSBcdTg4NjhcdThGQkVcdTVGMEZcbihcdThCRjdcdTRGN0ZcdTc1MjggLXNvdXJjZSA4IFx1NjIxNlx1NjZGNFx1OUFEOFx1NzI0OFx1NjcyQ1x1NEVFNVx1NTQyRlx1NzUyOCBsYW1iZGEgXHU4ODY4XHU4RkJFXHU1RjBGKQoKIyAwOiBzdHJpbmcKY29tcGlsZXIuZXJyLm1ldGhvZC5yZWZlcmVuY2VzLm5vdC5zdXBwb3J0ZWQuaW4uc291cmNlPS1zb3VyY2UgezB9IFx1NEUyRFx1NEUwRFx1NjUyRlx1NjMwMVx1NjVCOVx1NkNENVx1NUYxNVx1NzUyOFxuKFx1OEJGN1x1NEY3Rlx1NzUyOCAtc291cmNlIDggXHU2MjE2XHU2NkY0XHU5QUQ4XHU3MjQ4XHU2NzJDXHU0RUU1XHU1NDJGXHU3NTI4XHU2NUI5XHU2Q0Q1XHU1RjE1XHU3NTI4KQoKIyAwOiBzdHJpbmcKY29tcGlsZXIuZXJyLmRlZmF1bHQubWV0aG9kcy5ub3Quc3VwcG9ydGVkLmluLnNvdXJjZT0tc291cmNlIHswfSBcdTRFMkRcdTRFMERcdTY1MkZcdTYzMDFcdTlFRDhcdThCQTRcdTY1QjlcdTZDRDVcbihcdThCRjdcdTRGN0ZcdTc1MjggLXNvdXJjZSA4IFx1NjIxNlx1NjZGNFx1OUFEOFx1NzI0OFx1NjcyQ1x1NEVFNVx1NTQyRlx1NzUyOFx1OUVEOFx1OEJBNFx1NjVCOVx1NkNENSkKCiMgMDogc3RyaW5nCmNvbXBpbGVyLmVyci5pbnRlcnNlY3Rpb24udHlwZXMuaW4uY2FzdC5ub3Quc3VwcG9ydGVkLmluLnNvdXJjZT0tc291cmNlIHswfSBcdTRFMkRcdTRFMERcdTY1MkZcdTYzMDFcdThGNkNcdTYzNjJcdTRFMkRcdTc2ODRcdTRFQTRcdTUzQzlcdTdDN0JcdTU3OEJcbihcdThCRjdcdTRGN0ZcdTc1MjggLXNvdXJjZSA4IFx1NjIxNlx1NjZGNFx1OUFEOFx1NzI0OFx1NjcyQ1x1NEVFNVx1NTQyRlx1NzUyOFx1OEY2Q1x1NjM2Mlx1NEUyRFx1NzY4NFx1NEVBNFx1NTNDOVx1N0M3Qlx1NTc4QikKCiMgMDogc3RyaW5nCmNvbXBpbGVyLmVyci5zdGF0aWMuaW50Zi5tZXRob2RzLm5vdC5zdXBwb3J0ZWQuaW4uc291cmNlPS1zb3VyY2UgezB9IFx1NEUyRFx1NEUwRFx1NjUyRlx1NjMwMVx1OTc1OVx1NjAwMVx1NjNBNVx1NTNFM1x1NjVCOVx1NkNENVxuKFx1OEJGN1x1NEY3Rlx1NzUyOCAtc291cmNlIDggXHU2MjE2XHU2NkY0XHU5QUQ4XHU3MjQ4XHU2NzJDXHU0RUU1XHU1NDJGXHU3NTI4XHU5NzU5XHU2MDAxXHU2M0E1XHU1M0UzXHU2NUI5XHU2Q0Q1KQoKIyAwOiBzdHJpbmcKY29tcGlsZXIuZXJyLnN0YXRpYy5pbnRmLm1ldGhvZC5pbnZva2Uubm90LnN1cHBvcnRlZC5pbi5zb3VyY2U9LXNvdXJjZSB7MH0gXHU0RTJEXHU0RTBEXHU2NTJGXHU2MzAxXHU5NzU5XHU2MDAxXHU2M0E1XHU1M0UzXHU2NUI5XHU2Q0Q1XHU4QzAzXHU3NTI4XG4oXHU4QkY3XHU0RjdGXHU3NTI4IC1zb3VyY2UgOCBcdTYyMTZcdTY2RjRcdTlBRDhcdTcyNDhcdTY3MkNcdTRFRTVcdTU0MkZcdTc1MjhcdTk3NTlcdTYwMDFcdTYzQTVcdTUzRTNcdTY1QjlcdTZDRDVcdThDMDNcdTc1MjgpCgojIDA6IHN0cmluZwpjb21waWxlci5lcnIucHJpdmF0ZS5pbnRmLm1ldGhvZHMubm90LnN1cHBvcnRlZC5pbi5zb3VyY2U9LXNvdXJjZSB7MH0gXHU0RTJEXHU0RTBEXHU2NTJGXHU2MzAxXHU3OUMxXHU2NzA5XHU2M0E1XHU1M0UzXHU2NUI5XHU2Q0Q1XG4oXHU4QkY3XHU0RjdGXHU3NTI4IC1zb3VyY2UgOSBcdTYyMTZcdTY2RjRcdTlBRDhcdTcyNDhcdTY3MkNcdTRFRTVcdTU0MkZcdTc1MjhcdTc5QzFcdTY3MDlcdTYzQTVcdTUzRTNcdTY1QjlcdTZDRDUpCgojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCiMgRGlhZ25vc3RpY3MgZm9yIHZlcmJvc2UgcmVzb2x1dGlvbgojIHVzZWQgYnkgUmVzb2x2ZSAoZGVidWcgb25seSkKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwoKIyAwOiBudW1iZXIsIDE6IHN5bWJvbCwgMjogdW51c2VkCmNvbXBpbGVyLm1pc2MuYXBwbGljYWJsZS5tZXRob2QuZm91bmQ9XHU2MjdFXHU1MjMwXHU3QjJDIHswfSBcdTRFMkFcdTkwMDJcdTc1MjhcdTY1QjlcdTZDRDU6IHsxfQoKIyAwOiBudW1iZXIsIDE6IHN5bWJvbCwgMjogbWVzc2FnZSBzZWdtZW50CmNvbXBpbGVyLm1pc2MuYXBwbGljYWJsZS5tZXRob2QuZm91bmQuMT1cdTYyN0VcdTUyMzBcdTdCMkMgezB9IFx1NEUyQVx1OTAwMlx1NzUyOFx1NjVCOVx1NkNENTogezF9XG4oezJ9KQoKIyAwOiBudW1iZXIsIDE6IHN5bWJvbCwgMjogbWVzc2FnZSBzZWdtZW50CmNvbXBpbGVyLm1pc2Mubm90LmFwcGxpY2FibGUubWV0aG9kLmZvdW5kPVx1NjI3RVx1NTIzMFx1N0IyQyB7MH0gXHU0RTJBXHU0RTBEXHU5MDAyXHU3NTI4XHU3Njg0XHU2NUI5XHU2Q0Q1OiB7MX1cbih7Mn0pCgojIDA6IHR5cGUKY29tcGlsZXIubWlzYy5wYXJ0aWFsLmluc3Quc2lnPVx1OTBFOFx1NTIwNlx1NUI5RVx1NEY4Qlx1NTMxNlx1NEUzQTogezB9CgojIDA6IG5hbWUsIDE6IHN5bWJvbCwgMjogbnVtYmVyLCAzOiBzdHJpbmcgKG1ldGhvZCByZXNvbHV0aW9uIHBoYXNlKSwgNDogbGlzdCBvZiB0eXBlIG9yIG1lc3NhZ2Ugc2VnbWVudCwgNTogbGlzdCBvZiB0eXBlIG9yIG1lc3NhZ2Ugc2VnbWVudApjb21waWxlci5ub3RlLnZlcmJvc2UucmVzb2x2ZS5tdWx0aT1cdTVDMDZcdTdDN0JcdTU3OEIgezF9IFx1NzY4NFx1NjVCOVx1NkNENSB7MH0gXHU4OUUzXHU2NzkwXHU0RTNBXHU1MDE5XHU5MDA5XHU5ODc5IHsyfVxuXHU5NjM2XHU2QkI1OiB7M31cblx1NTE3N1x1NjcwOVx1NUI5RVx1OTY0NVx1NTAzQzogezR9XG5cdTUxNzdcdTY3MDlcdTdDN0JcdTU3OEJcdTUzQzJcdTY1NzA6IHs1fVxuXHU1MDE5XHU5MDA5XHU5ODc5OgoKIyAwOiBuYW1lLCAxOiBzeW1ib2wsIDI6IHVudXNlZCwgMzogc3RyaW5nIChtZXRob2QgcmVzb2x1dGlvbiBwaGFzZSksIDQ6IGxpc3Qgb2YgdHlwZSBvciBtZXNzYWdlIHNlZ21lbnQsIDU6IGxpc3Qgb2YgdHlwZSBvciBtZXNzYWdlIHNlZ21lbnQKY29tcGlsZXIubm90ZS52ZXJib3NlLnJlc29sdmUubXVsdGkuMT1cdTdDN0JcdTU3OEIgezF9IFx1NzY4NFx1NjVCOVx1NkNENSB7MH0gXHU4OUUzXHU2NzkwXHU5NTE5XHU4QkVGXG5cdTk2MzZcdTZCQjU6IHszfVxuXHU1MTc3XHU2NzA5XHU1QjlFXHU5NjQ1XHU1MDNDOiB7NH1cblx1NTE3N1x1NjcwOVx1N0M3Qlx1NTc4Qlx1NTNDMlx1NjU3MDogezV9XG5cdTUwMTlcdTkwMDlcdTk4Nzk6CgojIDA6IHN5bWJvbCwgMTogdHlwZSwgMjogdHlwZQpjb21waWxlci5ub3RlLmRlZmVycmVkLm1ldGhvZC5pbnN0PVx1NjVCOVx1NkNENSB7MH0gXHU3Njg0XHU1RUY2XHU4RkRGXHU1QjlFXHU0RjhCXHU1MzE2XG5cdTVCOUVcdTRGOEJcdTUzMTZcdTdCN0VcdTU0MEQ6IHsxfVxuXHU3NkVFXHU2ODA3XHU3QzdCXHU1NzhCOiB7Mn0KCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKIyBEaWFnbm9zdGljcyBmb3Igd2hlcmUgY2xhdXNlIGltcGxlbWVudGF0aW9uCiMgdXNlZCBieSB0aGUgUmljaERpYWdub3N0aWNGb3JtYXR0ZXIuCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKCmNvbXBpbGVyLm1pc2MudHlwZS5udWxsPTxcdTdBN0FcdTUwM0M+CgojIFgjbiAod2hlcmUgbiBpcyBhbiBpbnQgaWQpIGlzIGRpc2FtYmlndWF0ZWQgdHZhciBuYW1lCiMgMDogbmFtZSwgMTogbnVtYmVyCmNvbXBpbGVyLm1pc2MudHlwZS52YXI9ezB9I3sxfQoKIyBDQVAjbiAod2hlcmUgbiBpcyBhbiBpbnQgaWQpIGlzIGFuIGFiYnJldmlhdGlvbiBmb3IgJ2NhcHR1cmVkIHR5cGUnCiMgMDogbnVtYmVyCmNvbXBpbGVyLm1pc2MuY2FwdHVyZWQudHlwZT1DQVAjezB9CgojIDxJTlQjbj4gKHdoZXJlIG4gaXMgYW4gaW50IGlkKSBpcyBhbiBhYmJyZXZpYXRpb24gZm9yICdpbnRlcnNlY3Rpb24gdHlwZScKIyAwOiBudW1iZXIKY29tcGlsZXIubWlzYy5pbnRlcnNlY3Rpb24udHlwZT1JTlQjezB9CgojIHdoZXJlIGNsYXVzZSBmb3IgY2FwdHVyZWQgdHlwZTogY29udGFpbnMgdXBwZXIgKCdleHRlbmRzIHsxfScpIGFuZCBsb3dlcgojICgnc3VwZXIgezJ9JykgYm91bmQgYWxvbmcgd2l0aCB0aGUgd2lsZGNhcmQgdGhhdCBnZW5lcmF0ZWQgdGhpcyBjYXB0dXJlZCB0eXBlICh7M30pCiMgMDogdHlwZSwgMTogdHlwZSwgMjogdHlwZSwgMzogdHlwZQpjb21waWxlci5taXNjLndoZXJlLmNhcHR1cmVkPXswfVx1NEVDRXszfVx1NzY4NFx1NjM1NVx1ODNCN1x1NjI2OVx1NUM1NXsxfSBcdThEODUgezJ9CgojIGNvbXBhY3Qgd2hlcmUgY2xhdXNlIGZvciBjYXB0dXJlZCB0eXBlOiBjb250YWlucyB1cHBlciAoJ2V4dGVuZHMgezF9JykgYWxvbmcKIyB3aXRoIHRoZSB3aWxkY2FyZCB0aGF0IGdlbmVyYXRlZCB0aGlzIGNhcHR1cmVkIHR5cGUgKHszfSkKIyAwOiB0eXBlLCAxOiB0eXBlLCAyOiB1bnVzZWQsIDM6IHR5cGUKY29tcGlsZXIubWlzYy53aGVyZS5jYXB0dXJlZC4xPXswfVx1NEVDRXszfVx1NzY4NFx1NjM1NVx1ODNCN1x1NjI2OVx1NUM1NXsxfQoKIyB3aGVyZSBjbGF1c2UgZm9yIHR5cGUgdmFyaWFibGU6IGNvbnRhaW5zIHVwcGVyIGJvdW5kKHMpICgnZXh0ZW5kcyB7MX0nKSBhbG9uZyB3aXRoCiMgdGhlIGtpbmRuYW1lICh7Mn0pIGFuZCBsb2NhdGlvbiAoezN9KSBpbiB3aGljaCB0aGUgdHlwZXZhciBoYXMgYmVlbiBkZWNsYXJlZAojIDA6IHR5cGUsIDE6IGxpc3Qgb2YgdHlwZSwgMjogc3ltYm9sIGtpbmQsIDM6IHN5bWJvbApjb21waWxlci5taXNjLndoZXJlLnR5cGV2YXI9ezB9XHU2MjY5XHU1QzU1XHU1REYyXHU1NzI4ezJ9IHszfVx1NEUyRFx1NThGMFx1NjYwRVx1NzY4NHsxfQoKIyBjb21wYWN0IHdoZXJlIGNsYXVzZSBmb3IgdHlwZSB2YXJpYWJsZTogY29udGFpbnMgdGhlIGtpbmRuYW1lICh7Mn0pIGFuZCBsb2NhdGlvbiAoezN9KQojIGluIHdoaWNoIHRoZSB0eXBldmFyIGhhcyBiZWVuIGRlY2xhcmVkCiMgMDogdHlwZSwgMTogbGlzdCBvZiB0eXBlLCAyOiBzeW1ib2wga2luZCwgMzogc3ltYm9sCmNvbXBpbGVyLm1pc2Mud2hlcmUudHlwZXZhci4xPXswfVx1NURGMlx1NTcyOHsyfSB7M31cdTRFMkRcdTU4RjBcdTY2MEUKCiMgd2hlcmUgY2xhdXNlIGZvciBmcmVzaCB0eXBlIHZhcmlhYmxlOiBjb250YWlucyB1cHBlciBib3VuZChzKSAoJ2V4dGVuZHMgezF9JykuCiMgU2luY2UgYSBmcmVzaCB0eXBlLXZhcmlhYmxlIGlzIHN5bnRoZXRpYyAtIHRoZXJlJ3Mgbm8gbG9jYXRpb24va2luZG5hbWUgaGVyZS4KIyAwOiB0eXBlLCAxOiBsaXN0IG9mIHR5cGUKY29tcGlsZXIubWlzYy53aGVyZS5mcmVzaC50eXBldmFyPXswfVx1NjI2OVx1NUM1NXsxfQoKIyB3aGVyZSBjbGF1c2UgZm9yIHR5cGUgdmFyaWFibGU6IGNvbnRhaW5zIGFsbCB0aGUgdXBwZXIgYm91bmQocykgKCdleHRlbmRzIHsxfScpCiMgb2YgdGhpcyBpbnRlcnNlY3Rpb24gdHlwZQojIDA6IHR5cGUsIDE6IGxpc3Qgb2YgdHlwZQpjb21waWxlci5taXNjLndoZXJlLmludGVyc2VjdGlvbj17MH1cdTYyNjlcdTVDNTV7MX0KCiMjIyBXaGVyZSBjbGF1c2UgaGVhZGVycyAjIyMKY29tcGlsZXIubWlzYy53aGVyZS5kZXNjcmlwdGlvbi5jYXB0dXJlZD1cdTUxNzZcdTRFMkQsIHswfVx1NjYyRlx1NjVCMFx1N0M3Qlx1NTc4Qlx1NTNEOFx1OTFDRjoKCiMgMDogc2V0IG9mIHR5cGUKY29tcGlsZXIubWlzYy53aGVyZS5kZXNjcmlwdGlvbi50eXBldmFyPVx1NTE3Nlx1NEUyRCwgezB9XHU2NjJGXHU3QzdCXHU1NzhCXHU1M0Q4XHU5MUNGOgoKIyAwOiBzZXQgb2YgdHlwZQpjb21waWxlci5taXNjLndoZXJlLmRlc2NyaXB0aW9uLmludGVyc2VjdGlvbj1cdTUxNzZcdTRFMkQsIHswfVx1NjYyRlx1NEVBNFx1NTNDOVx1N0M3Qlx1NTc4QjoKCiMgMDogc2V0IG9mIHR5cGUKY29tcGlsZXIubWlzYy53aGVyZS5kZXNjcmlwdGlvbi5jYXB0dXJlZC4xPVx1NTE3Nlx1NEUyRCwgezB9XHU2NjJGXHU2NUIwXHU3QzdCXHU1NzhCXHU1M0Q4XHU5MUNGOgoKIyAwOiBzZXQgb2YgdHlwZQpjb21waWxlci5taXNjLndoZXJlLmRlc2NyaXB0aW9uLnR5cGV2YXIuMT1cdTUxNzZcdTRFMkQsIHswfVx1NjYyRlx1N0M3Qlx1NTc4Qlx1NTNEOFx1OTFDRjoKCiMgMDogc2V0IG9mIHR5cGUKY29tcGlsZXIubWlzYy53aGVyZS5kZXNjcmlwdGlvbi5pbnRlcnNlY3Rpb24uMT1cdTUxNzZcdTRFMkQsIHswfVx1NjYyRlx1NEVBNFx1NTNDOVx1N0M3Qlx1NTc4QjoKCiMjIwojIGVycm9ycyByZWxhdGVkIHRvIGRvYyBjb21tZW50cwoKY29tcGlsZXIuZXJyLmRjLmJhZC5lbnRpdHk9SFRNTCBcdTVCOUVcdTRGNTNcdTk1MTlcdThCRUYKCmNvbXBpbGVyLmVyci5kYy5iYWQuZ3Q9Jyc+JycgXHU3Njg0XHU3NTI4XHU2Q0Q1XHU5NTE5XHU4QkVGCgpjb21waWxlci5lcnIuZGMuYmFkLmlubGluZS50YWc9XHU1MTg1XHU1RDRDXHU2ODA3XHU4QkIwXHU3Njg0XHU3NTI4XHU2Q0Q1XHU0RTBEXHU2QjYzXHU3ODZFCgpjb21waWxlci5lcnIuZGMuaWRlbnRpZmllci5leHBlY3RlZD1cdTk3MDBcdTg5ODFcdTY4MDdcdThCQzZcdTdCMjYKCmNvbXBpbGVyLmVyci5kYy5tYWxmb3JtZWQuaHRtbD1cdTY4M0NcdTVGMEZcdTk1MTlcdThCRUZcdTc2ODQgSFRNTAoKY29tcGlsZXIuZXJyLmRjLm1pc3Npbmcuc2VtaWNvbG9uPVx1N0YzQVx1NUMxMVx1NTIwNlx1NTNGNwoKY29tcGlsZXIuZXJyLmRjLm5vLmNvbnRlbnQ9XHU2NUUwXHU1MTg1XHU1QkI5Cgpjb21waWxlci5lcnIuZGMubm8udGFnLm5hbWU9J0AnIFx1NTQwRVx1NkNBMVx1NjcwOVx1NjgwN1x1OEJCMFx1NTQwRAoKY29tcGlsZXIuZXJyLmRjLmd0LmV4cGVjdGVkPVx1OTcwMFx1ODk4MSAnJz4nJwoKY29tcGlsZXIuZXJyLmRjLnJlZi5iYWQucGFyZW5zPVx1NUYxNVx1NzUyOFx1NEUyRFx1N0YzQVx1NUMxMSAnJyknJwoKY29tcGlsZXIuZXJyLmRjLnJlZi5zeW50YXguZXJyb3I9XHU1RjE1XHU3NTI4XHU0RTJEXHU1MUZBXHU3M0IwXHU4QkVEXHU2Q0Q1XHU5NTE5XHU4QkVGCgpjb21waWxlci5lcnIuZGMucmVmLnVuZXhwZWN0ZWQuaW5wdXQ9XHU2MTBGXHU1OTE2XHU3Njg0XHU2NTg3XHU2NzJDCgpjb21waWxlci5lcnIuZGMudW5leHBlY3RlZC5jb250ZW50PVx1NjEwRlx1NTkxNlx1NzY4NFx1NTE4NVx1NUJCOQoKY29tcGlsZXIuZXJyLmRjLnVudGVybWluYXRlZC5pbmxpbmUudGFnPVx1NjcyQVx1N0VDOFx1NkI2Mlx1NzY4NFx1NTE4NVx1NUQ0Q1x1NjgwN1x1OEJCMAoKY29tcGlsZXIuZXJyLmRjLnVudGVybWluYXRlZC5zaWduYXR1cmU9XHU2NzJBXHU3RUM4XHU2QjYyXHU3Njg0XHU3QjdFXHU1NDBECgpjb21waWxlci5lcnIuZGMudW50ZXJtaW5hdGVkLnN0cmluZz1cdTY3MkFcdTdFQzhcdTZCNjJcdTc2ODRcdTVCNTdcdTdCMjZcdTRFMzIKCiMjIwojIGVycm9ycyByZWxhdGVkIHRvIG1vZHVsZXMKCmNvbXBpbGVyLmVyci5leHBlY3RlZC5tb2R1bGU9XHU5ODg0XHU2NzFGICcnbW9kdWxlJycKCiMgMDogc3ltYm9sCmNvbXBpbGVyLmVyci5tb2R1bGUubm90LmZvdW5kPVx1NjI3RVx1NEUwRFx1NTIzMFx1NkEyMVx1NTc1NzogezB9CgojIDA6IHN5bWJvbApjb21waWxlci53YXJuLm1vZHVsZS5ub3QuZm91bmQ9XHU2MjdFXHU0RTBEXHU1MjMwXHU2QTIxXHU1NzU3OiB7MH0KCmNvbXBpbGVyLmVyci50b28ubWFueS5tb2R1bGVzPVx1NjI3RVx1NTIzMFx1NTkyQVx1NTkxQVx1NzY4NFx1NkEyMVx1NTc1N1x1NThGMFx1NjYwRQoKIyAwOiBzeW1ib2wKY29tcGlsZXIuZXJyLmR1cGxpY2F0ZS5tb2R1bGU9XHU5MUNEXHU1OTBEXHU3Njg0XHU2QTIxXHU1NzU3OiB7MH0KCiMgMDogc3ltYm9sCmNvbXBpbGVyLmVyci5kdXBsaWNhdGUucmVxdWlyZXM9XHU5MUNEXHU1OTBEXHU3Njg0IHJlcXVpcmVzIFx1NjMwN1x1NEVFNDogezB9CgojIDA6IHN5bWJvbApjb21waWxlci5lcnIuY29uZmxpY3RpbmcuZXhwb3J0cz1cdTkxQ0RcdTU5MERcdTYyMTZcdTUxQjJcdTdBODFcdTc2ODRcdTVCRkNcdTUxRkFcdTY0Q0RcdTRGNUM6IHswfQoKIyAwOiBzeW1ib2wKY29tcGlsZXIuZXJyLmNvbmZsaWN0aW5nLm9wZW5zPVx1OTFDRFx1NTkwRFx1NjIxNlx1NTFCMlx1N0E4MVx1NzY4NFx1NjI1M1x1NUYwMFx1NjRDRFx1NEY1QzogezB9CgojIDA6IHN5bWJvbApjb21waWxlci5lcnIuY29uZmxpY3RpbmcuZXhwb3J0cy50by5tb2R1bGU9XHU5MUNEXHU1OTBEXHU2MjE2XHU1MUIyXHU3QTgxXHU3Njg0XHU1QkZDXHU1MUZBXHU1MjMwXHU2QTIxXHU1NzU3XHU2NENEXHU0RjVDOiB7MH0KCiMgMDogc3ltYm9sCmNvbXBpbGVyLmVyci5jb25mbGljdGluZy5vcGVucy50by5tb2R1bGU9XHU5MUNEXHU1OTBEXHU2MjE2XHU1MUIyXHU3QTgxXHU3Njg0XHU2MjUzXHU1RjAwXHU1MjMwXHU2QTIxXHU1NzU3XHU2NENEXHU0RjVDOiB7MH0KCmNvbXBpbGVyLmVyci5uby5vcGVucy51bmxlc3Muc3Ryb25nPVx1NTNFQVx1NTE0MVx1OEJCOFx1NTcyOFx1NUYzQVx1NkEyMVx1NTc1N1x1NEUyRFx1NEY3Rlx1NzUyOCAnJ29wZW5zJycKCiMgMDogc3ltYm9sLCAxOiBzeW1ib2wKY29tcGlsZXIuZXJyLmR1cGxpY2F0ZS5wcm92aWRlcz1cdTkxQ0RcdTU5MERcdTc2ODQgcHJvdmlkZXMgXHU2MzA3XHU0RUU0OiBcdTY3MERcdTUyQTEgezB9LCBcdTVCOUVcdTczQjAgezF9CgojIDA6IHN5bWJvbApjb21waWxlci5lcnIuZHVwbGljYXRlLnVzZXM9XHU5MUNEXHU1OTBEXHU3Njg0IHVzZXMgXHU2MzA3XHU0RUU0OiB7MH0KCiMgMDogc3ltYm9sCmNvbXBpbGVyLmVyci5zZXJ2aWNlLmltcGxlbWVudGF0aW9uLmlzLmFic3RyYWN0PVx1NjcwRFx1NTJBMVx1NUI5RVx1NzNCMFx1NjYyRlx1NjJCRFx1OEM2MVx1N0M3QjogezB9Cgpjb21waWxlci5lcnIuc2VydmljZS5pbXBsZW1lbnRhdGlvbi5tdXN0LmJlLnN1YnR5cGUub2Yuc2VydmljZS5pbnRlcmZhY2U9XHU2NzBEXHU1MkExXHU1QjlFXHU3M0IwXHU3QzdCXHU1NzhCXHU1RkM1XHU5ODdCXHU2NjJGXHU2NzBEXHU1MkExXHU2M0E1XHU1M0UzXHU3QzdCXHU1NzhCXHU3Njg0XHU1QjUwXHU3QzdCXHU1NzhCLCBcdTYyMTZcdTgwMDVcdTUxNzdcdTY3MDlcdTU0MERcdTRFM0EgInByb3ZpZGVyIiBcdTc2ODQsIFx1OEZENFx1NTZERVx1NjcwRFx1NTJBMVx1NUI5RVx1NzNCMFx1NzY4NFx1NTE2Q1x1NTE3MVx1OTc1OVx1NjAwMVx1NjVFMFx1NTNDMlx1NjU3MFx1NjVCOVx1NkNENQoKY29tcGlsZXIuZXJyLnNlcnZpY2UuaW1wbGVtZW50YXRpb24ucHJvdmlkZXIucmV0dXJuLm11c3QuYmUuc3VidHlwZS5vZi5zZXJ2aWNlLmludGVyZmFjZT0icHJvdmlkZXIiIFx1NjVCOVx1NkNENVx1OEZENFx1NTZERVx1N0M3Qlx1NTc4Qlx1NUZDNVx1OTg3Qlx1NjYyRlx1NjcwRFx1NTJBMVx1NjNBNVx1NTNFM1x1N0M3Qlx1NTc4Qlx1NzY4NFx1NUI1MFx1N0M3Qlx1NTc4QgoKIyAwOiBzeW1ib2wKY29tcGlsZXIuZXJyLnNlcnZpY2UuaW1wbGVtZW50YXRpb24uaXMuaW5uZXI9XHU2NzBEXHU1MkExXHU1QjlFXHU3M0IwXHU2NjJGXHU1MTg1XHU5MEU4XHU3QzdCOiB7MH0KCiMgMDogc3ltYm9sCmNvbXBpbGVyLmVyci5zZXJ2aWNlLmRlZmluaXRpb24uaXMuZW51bT1cdTY3MERcdTUyQTFcdTVCOUFcdTRFNDlcdTY2MkZcdTY3OUFcdTRFM0U6IHswfQoKIyAwOiBzeW1ib2wKY29tcGlsZXIuZXJyLnNlcnZpY2UuaW1wbGVtZW50YXRpb24uZG9lc250LmhhdmUuYS5uby5hcmdzLmNvbnN0cnVjdG9yPVx1NjcwRFx1NTJBMVx1NUI5RVx1NzNCMFx1NkNBMVx1NjcwOVx1OUVEOFx1OEJBNFx1NzY4NFx1Njc4NFx1OTAyMFx1NTY2ODogezB9CgojIDA6IHN5bWJvbApjb21waWxlci5lcnIuc2VydmljZS5pbXBsZW1lbnRhdGlvbi5uby5hcmdzLmNvbnN0cnVjdG9yLm5vdC5wdWJsaWM9XHU2NzBEXHU1MkExXHU1QjlFXHU3M0IwXHU3Njg0XHU2NUUwXHU1M0MyXHU2NTcwXHU2Nzg0XHU5MDIwXHU1NjY4XHU0RTBEXHU2NjJGXHU1MTZDXHU1MTcxXHU2Nzg0XHU5MDIwXHU1NjY4OiB7MH0KCiMgMDogc3ltYm9sCmNvbXBpbGVyLmVyci5wYWNrYWdlLmVtcHR5Lm9yLm5vdC5mb3VuZD1cdTdBMEJcdTVFOEZcdTUzMDVcdTRFM0FcdTdBN0FcdTYyMTZcdTRFMERcdTVCNThcdTU3Mjg6IHswfQoKY29tcGlsZXIuZXJyLm5vLm91dHB1dC5kaXI9XHU2NzJBXHU2MzA3XHU1QjlBXHU3QzdCXHU4RjkzXHU1MUZBXHU3NkVFXHU1RjU1Cgpjb21waWxlci5lcnIudW5uYW1lZC5wa2cubm90LmFsbG93ZWQubmFtZWQubW9kdWxlcz1cdTU0N0RcdTU0MERcdTZBMjFcdTU3NTdcdTRFMkRcdTRFMERcdTUxNDFcdThCQjhcdTY3MkFcdTU0N0RcdTU0MERcdTdBMEJcdTVFOEZcdTUzMDUKCiMgMDogbmFtZSwgMTogbmFtZQpjb21waWxlci5lcnIubW9kdWxlLm5hbWUubWlzbWF0Y2g9XHU2QTIxXHU1NzU3XHU1NDBEXHU3OUYwIHswfSBcdTRFMEVcdTk4ODRcdTY3MUZcdTU0MERcdTc5RjAgezF9IFx1NEUwRFx1NTMzOVx1OTE0RAoKIyAwOiBuYW1lLCAxOiBuYW1lCmNvbXBpbGVyLm1pc2MubW9kdWxlLm5hbWUubWlzbWF0Y2g9XHU2QTIxXHU1NzU3XHU1NDBEXHU3OUYwIHswfSBcdTRFMEVcdTk4ODRcdTY3MUZcdTU0MERcdTc5RjAgezF9IFx1NEUwRFx1NTMzOVx1OTE0RAoKIyAwOiBuYW1lCmNvbXBpbGVyLmVyci5tb2R1bGUubm9uLnplcm8ub3BlbnM9XHU2MjUzXHU1RjAwXHU3Njg0XHU2QTIxXHU1NzU3IHswfSBcdTUxNzdcdTY3MDlcdTk3NUVcdTk2RjYgb3BlbnNfY291bnQKCiMgMDogbmFtZQpjb21waWxlci5taXNjLm1vZHVsZS5ub24uemVyby5vcGVucz1cdTYyNTNcdTVGMDBcdTc2ODRcdTZBMjFcdTU3NTcgezB9IFx1NTE3N1x1NjcwOVx1OTc1RVx1OTZGNiBvcGVuc19jb3VudAoKY29tcGlsZXIuZXJyLm1vZHVsZS5kZWNsLnNiLmluLm1vZHVsZS1pbmZvLmphdmE9XHU2QTIxXHU1NzU3XHU1OEYwXHU2NjBFXHU1RTk0XHU4QkU1XHU1NzI4XHU1NDBEXHU0RTNBIG1vZHVsZS1pbmZvLmphdmEgXHU3Njg0XHU2NTg3XHU0RUY2XHU0RTJECgpjb21waWxlci5lcnIubW9kdWxlLWluZm8ud2l0aC54bW9kdWxlLnNvdXJjZXBhdGg9XHU2RTkwXHU4REVGXHU1Rjg0XHU0RTBBXHU3Njg0IC1YbW9kdWxlIFx1NEUwRSBtb2R1bGUtaW5mbyBcdTc2ODRcdTdFQzRcdTU0MDhcdTk3NUVcdTZDRDUKCmNvbXBpbGVyLmVyci5tb2R1bGUtaW5mby53aXRoLnhtb2R1bGUuY2xhc3NwYXRoPVx1N0M3Qlx1OERFRlx1NUY4NFx1NEUwQVx1NzY4NCAtWG1vZHVsZSBcdTRFMEUgbW9kdWxlLWluZm8gXHU3Njg0XHU3RUM0XHU1NDA4XHU5NzVFXHU2Q0Q1Cgpjb21waWxlci5lcnIueG1vZHVsZS5uby5tb2R1bGUuc291cmNlcGF0aD0tWG1vZHVsZSBcdTRFMEUgLS1tb2R1bGUtc291cmNlLXBhdGggXHU3Njg0XHU3RUM0XHU1NDA4XHU5NzVFXHU2Q0Q1Cgpjb21waWxlci5lcnIucHJvY2Vzc29ycGF0aC5uby5wcm9jZXNzb3Jtb2R1bGVwYXRoPS1wcm9jZXNzb3JwYXRoIFx1NEUwRSAtLXByb2Nlc3Nvci1tb2R1bGUtcGF0aCBcdTc2ODRcdTdFQzRcdTU0MDhcdTk3NUVcdTZDRDUKCiMgMDogc3ltYm9sCmNvbXBpbGVyLmVyci5wYWNrYWdlLmluLm90aGVyLm1vZHVsZT1cdTdBMEJcdTVFOEZcdTUzMDVcdTVERjJcdTVCNThcdTU3MjhcdTRFOEVcdTUzRTZcdTRFMDBcdTRFMkFcdTZBMjFcdTU3NTdcdTRFMkQ6IHswfQoKIyAwOiBzeW1ib2wsIDE6IG5hbWUsIDI6IHN5bWJvbCwgMzogc3ltYm9sCmNvbXBpbGVyLmVyci5wYWNrYWdlLmNsYXNoLmZyb20ucmVxdWlyZXM9XHU2QTIxXHU1NzU3IHswfSBcdTU0MENcdTY1RjZcdTRFQ0UgezJ9IFx1NTQ4QyB7M30gXHU4QkZCXHU1M0Q2XHU3QTBCXHU1RThGXHU1MzA1IHsxfQoKIyAwOiBzdHJpbmcKY29tcGlsZXIuZXJyLm1vZHVsZS5ub3QuZm91bmQuaW4ubW9kdWxlLnNvdXJjZS5wYXRoPVx1NTcyOFx1NkEyMVx1NTc1N1x1NkU5MFx1OERFRlx1NUY4NFx1NEUyRFx1NjI3RVx1NEUwRFx1NTIzMFx1NkEyMVx1NTc1NyB7MH0KCmNvbXBpbGVyLmVyci5vdXRwdXQuZGlyLm11c3QuYmUuc3BlY2lmaWVkLndpdGguZGFzaC5tLm9wdGlvbj1cdTU5ODJcdTY3OUNcdTRGN0ZcdTc1MjggLW0gXHU5MDA5XHU5ODc5LCBcdTUyMTlcdTVGQzVcdTk4N0JcdTYzMDdcdTVCOUFcdTdDN0JcdThGOTNcdTUxRkFcdTc2RUVcdTVGNTUKCmNvbXBpbGVyLmVyci5tb2R1bGVzb3VyY2VwYXRoLm11c3QuYmUuc3BlY2lmaWVkLndpdGguZGFzaC5tLm9wdGlvbj1cdTU5ODJcdTY3OUNcdTRGN0ZcdTc1MjggLW0gXHU5MDA5XHU5ODc5LCBcdTUyMTlcdTVGQzVcdTk4N0JcdTYzMDdcdTVCOUFcdTZBMjFcdTU3NTdcdTZFOTBcdThERUZcdTVGODQKCiMgMDogc3ltYm9sCmNvbXBpbGVyLmVyci5zZXJ2aWNlLmltcGxlbWVudGF0aW9uLm5vdC5pbi5yaWdodC5tb2R1bGU9XHU1RkM1XHU5ODdCXHU1NzI4XHU0RTBFIHByb3ZpZGVzIFx1NjMwN1x1NEVFNFx1NzZGOFx1NTQwQ1x1NzY4NFx1NkEyMVx1NTc1N1x1NEUyRFx1NUI5QVx1NEU0OVx1NjcwRFx1NTJBMVx1NUI5RVx1NzNCMAoKIyAwOiBzeW1ib2wKY29tcGlsZXIuZXJyLmN5Y2xpYy5yZXF1aXJlcz1cdTZEODlcdTUzQ0EgezB9IFx1NzY4NFx1NUZBQVx1NzNBRlx1ODhBQlx1NEY5RFx1OEQ1Nlx1NUJGOVx1OEM2MQoKIyAwOiBmcmFnbWVudCwgMTogbmFtZQpjb21waWxlci5lcnIuZHVwbGljYXRlLm1vZHVsZS5vbi5wYXRoPXsxfSBcdTRFMkRcdTc2ODQgezB9IFx1NEUwQVx1NUI1OFx1NTcyOFxuXHU5MUNEXHU1OTBEXHU3Njg0XHU2QTIxXHU1NzU3CgojIDA6IG9wdGlvbiBuYW1lLCAxOiBzdHJpbmcKY29tcGlsZXIud2Fybi5iYWQubmFtZS5mb3Iub3B0aW9uPXswfSBcdTkwMDlcdTk4NzlcdTc2ODRcdTUwM0NcdTRFMkRcdTY3MDlcdTk1MTlcdThCRUZcdTc2ODRcdTU0MERcdTc5RjA6ICcnezF9JycKCiMgMDogb3B0aW9uIG5hbWUsIDE6IHN0cmluZwpjb21waWxlci5lcnIuYmFkLm5hbWUuZm9yLm9wdGlvbj17MH0gXHU5MDA5XHU5ODc5XHU3Njg0XHU1MDNDXHU0RTJEXHU2NzA5XHU5NTE5XHU4QkVGXHU3Njg0XHU1NDBEXHU3OUYwOiAnJ3sxfScnCgojIDA6IG9wdGlvbiBuYW1lLCAxOiBzeW1ib2wKY29tcGlsZXIud2Fybi5tb2R1bGUuZm9yLm9wdGlvbi5ub3QuZm91bmQ9XHU2MjdFXHU0RTBEXHU1MjMwIHswfSBcdTkwMDlcdTk4NzlcdTRFMkRcdTc2ODRcdTZBMjFcdTU3NTdcdTU0MERcdTc5RjA6IHsxfQoKY29tcGlsZXIuZXJyLmFkZG1vZHMuYWxsLm1vZHVsZS5wYXRoLmludmFsaWQ9LS1hZGQtbW9kdWxlcyBBTEwtTU9EVUxFLVBBVEggXHU1M0VBXHU4MEZEXHU1NzI4XHU3RjE2XHU4QkQxXHU2NzJBXHU1NDdEXHU1NDBEXHU2QTIxXHU1NzU3XHU2NUY2XHU0RjdGXHU3NTI4Cgpjb21waWxlci53YXJuLmFkZG9wZW5zLmlnbm9yZWQ9LS1hZGQtb3BlbnMgXHU1NzI4XHU3RjE2XHU4QkQxXHU2NUY2XHU2Q0ExXHU2NzA5XHU0RUZCXHU0RjU1XHU2NTQ4XHU2NzlDCgpjb21waWxlci5taXNjLmxvY24ubW9kdWxlX3NvdXJjZV9wYXRoPVx1NkEyMVx1NTc1N1x1NkU5MFx1OERFRlx1NUY4NAoKY29tcGlsZXIubWlzYy5sb2NuLnVwZ3JhZGVfbW9kdWxlX3BhdGg9XHU1MzQ3XHU3RUE3XHU2QTIxXHU1NzU3XHU4REVGXHU1Rjg0Cgpjb21waWxlci5taXNjLmxvY24uc3lzdGVtX21vZHVsZXM9XHU3Q0ZCXHU3RURGXHU2QTIxXHU1NzU3Cgpjb21waWxlci5taXNjLmxvY24ubW9kdWxlX3BhdGg9XHU1RTk0XHU3NTI4XHU3QTBCXHU1RThGXHU2QTIxXHU1NzU3XHU4REVGXHU1Rjg0Cgpjb21waWxlci5taXNjLmNhbnQucmVzb2x2ZS5tb2R1bGVzPVx1NjVFMFx1NkNENVx1ODlFM1x1Njc5MFx1NkEyMVx1NTc1NwoKIyAwOiBzdHJpbmcKY29tcGlsZXIuZXJyLmludmFsaWQubW9kdWxlLnNwZWNpZmllcj1cdTRFMERcdTUxNDFcdThCQjhcdTZBMjFcdTU3NTdcdThCRjRcdTY2MEVcdTdCMjY6IHswfQoKIyAwOiBzeW1ib2wKY29tcGlsZXIud2Fybi5zZXJ2aWNlLnByb3ZpZGVkLmJ1dC5ub3QuZXhwb3J0ZWQub3IudXNlZD1cdTVERjJcdTYzRDBcdTRGOUJcdTY3MERcdTUyQTFcdTYzQTVcdTUzRTMsIFx1NEY0Nlx1NjcyQVx1NUJGQ1x1NTFGQVx1NjIxNlx1NEY3Rlx1NzUyOFx1NjcwRFx1NTJBMVx1NjNBNVx1NTNFMwoKIyAwOiBraW5kIG5hbWUsIDE6IHN5bWJvbCwgMjogc3ltYm9sCmNvbXBpbGVyLndhcm4ubGVha3Mubm90LmFjY2Vzc2libGU9XHU2QTIxXHU1NzU3IHsyfSBcdTRFMkRcdTc2ODQgezB9IHsxfSBcdTVCRjlcdTk3MDBcdTg5ODFcdThCRTVcdTZBMjFcdTU3NTdcdTc2ODRcdTVCQTJcdTYyMzdcdTY3M0FcdTRFMERcdTUzRUZcdThCQkZcdTk1RUUKIyAwOiBraW5kIG5hbWUsIDE6IHN5bWJvbCwgMjogc3ltYm9sCmNvbXBpbGVyLndhcm4ubGVha3Mubm90LmFjY2Vzc2libGUudW5leHBvcnRlZD1cdTY3MkFcdTVCRkNcdTUxRkFcdTZBMjFcdTU3NTcgezJ9IFx1NEUyRFx1NzY4NCB7MH0gezF9CiMgMDoga2luZCBuYW1lLCAxOiBzeW1ib2wsIDI6IHN5bWJvbApjb21waWxlci53YXJuLmxlYWtzLm5vdC5hY2Nlc3NpYmxlLm5vdC5yZXF1aXJlZC50cmFuc2l0aXZlPVx1NjcyQVx1NEY3Rlx1NzUyOCAnJ3JlcXVpcmVzIHRyYW5zaXRpdmUnJyBcdTk1RjRcdTYzQTVcdTVCRkNcdTUxRkFcdTZBMjFcdTU3NTcgezJ9IFx1NEUyRFx1NzY4NCB7MH0gezF9CiMgMDoga2luZCBuYW1lLCAxOiBzeW1ib2wsIDI6IHN5bWJvbApjb21waWxlci53YXJuLmxlYWtzLm5vdC5hY2Nlc3NpYmxlLnVuZXhwb3J0ZWQucXVhbGlmaWVkPVx1NkEyMVx1NTc1NyB7Mn0gXHU0RTJEXHU3Njg0IHswfSB7MX0gXHU1M0VGXHU4MEZEXHU1QkY5XHU5NzAwXHU4OTgxXHU4QkU1XHU2QTIxXHU1NzU3XHU3Njg0XHU2MjQwXHU2NzA5XHU1QkEyXHU2MjM3XHU2NzNBXHU5MEZEXHU0RTBEXHU1M0VGXHU4OUMxCgojIyMKIyBlcnJvcnMgcmVsYXRlZCB0byBvcHRpb25zCgojIDA6IHN0cmluZywgMTogc3RyaW5nCmNvbXBpbGVyLmVyci5pbGxlZ2FsLmFyZ3VtZW50LmZvci5vcHRpb249ezB9IFx1NzY4NFx1NTNDMlx1NjU3MFx1OTc1RVx1NkNENTogezF9ClBLAwQKAAAIAAAGO6lK9nZ88slpAQDJaQEAMQAAAGNvbS9zdW4vdG9vbHMvamF2YWMvcmVzb3VyY2VzL2NvbXBpbGVyLnByb3BlcnRpZXMjCiMgQ29weXJpZ2h0IChjKSAxOTk5LCAyMDE3LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgojIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KIwojIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiMgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKIyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKIyBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiMgYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiMKIyBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKIyBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKIyBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKIyB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAojIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiMKIyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiMgMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAojIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KIwojIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiMgb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQojIHF1ZXN0aW9ucy4KIwoKIyBNZXNzYWdlcyBpbiB0aGlzIGZpbGUgd2hpY2ggdXNlICJwbGFjZWhvbGRlcnMiIGZvciB2YWx1ZXMgKGUuZy4gezB9LCB7MX0pCiMgYXJlIHByZWNlZGVkIGJ5IGEgc3R5bGl6ZWQgY29tbWVudCBkZXNjcmliaW5nIHRoZSB0eXBlIG9mIHRoZSBjb3JyZXNwb25kaW5nCiMgdmFsdWVzLgojIFRoZSBzaW1wbGUgdHlwZXMgY3VycmVudGx5IGluIHVzZSBhcmU6CiMKIyBib29sZWFuICAgICAgICAgICB0cnVlIG9yIGZhbHNlCiMgZGlhZ25vc3RpYyAgICAgICAgYSBzdWItbWVzc2FnZTsgc2VlIGNvbXBpbGVyLm1pc2MuKgojIGZyYWdtZW50ICAgICAgICAgIHNpbWlsYXIgdG8gJ21lc3NhZ2Ugc2VnbWVudCcsIGJ1dCB3aXRoIG1vcmUgc3BlY2lmaWMgdHlwZQojIG1vZGlmaWVyICAgICAgICAgIGEgSmF2YSBtb2RpZmllcjsgZS5nLiBwdWJsaWMsIHByaXZhdGUsIHByb3RlY3RlZAojIGZpbGUgICAgICAgICAgICAgIGEgZmlsZSBVUkwKIyBmaWxlIG9iamVjdCAgICAgICBhIGZpbGUgVVJMIC0gc2ltaWxhciB0byAnZmlsZScgYnV0IHR5cGljYWxseSB1c2VkIGZvciBzb3VyY2UvY2xhc3MgZmlsZXMsIGhlbmNlIG1vcmUgc3BlY2lmaWMKIyBuYW1lICAgICAgICAgICAgICBhIG5hbWUsIHR5cGljYWxseSBhIEphdmEgaWRlbnRpZmllcgojIG51bWJlciAgICAgICAgICAgIGFuIGludGVnZXIKIyBvcHRpb24gbmFtZSAgICAgICB0aGUgbmFtZSBvZiBhIGNvbW1hbmQgbGluZSBvcHRpb24KIyBzb3VyY2UgdmVyc2lvbiAgICBhIHNvdXJjZSB2ZXJzaW9uIG51bWJlciwgc3VjaCBhcyAxLjUsIDEuNiwgMS43CiMgc3RyaW5nICAgICAgICAgICAgYSBnZW5lcmFsIHN0cmluZwojIHN5bWJvbCAgICAgICAgICAgIHRoZSBuYW1lIG9mIGEgZGVjbGFyZWQgdHlwZQojIHN5bWJvbCBraW5kICAgICAgIHRoZSBraW5kIG9mIGEgc3ltYm9sIChpLmUuIG1ldGhvZCwgdmFyaWFibGUpCiMga2luZCBuYW1lICAgICAgICAgYW4gaW5mb3JtYXRpdmUgZGVzY3JpcHRpb24gb2YgdGhlIGtpbmQgb2YgYSBkZWNsYXJhdGlvbjsgc2VlIGNvbXBpbGVyLm1pc2Mua2luZG5hbWUuKgojIHRva2VuICAgICAgICAgICAgIHRoZSBuYW1lIG9mIGEgbm9uLXRlcm1pbmFsIGluIHNvdXJjZSBjb2RlOyBzZWUgY29tcGlsZXIubWlzYy50b2tlbi4qCiMgdHlwZSAgICAgICAgICAgICAgYSBKYXZhIHR5cGU7IGUuZy4gaW50LCBYLCBYPFQ+CiMgb2JqZWN0ICAgICAgICAgICAgYSBKYXZhIG9iamVjdCAodW5zcGVjaWZpZWQpCiMgdW51c2VkICAgICAgICAgICAgdGhlIHZhbHVlIGlzIG5vdCB1c2VkIGluIHRoaXMgbWVzc2FnZQojCiMgVGhlIGZvbGxvd2luZyBjb21wb3VuZCB0eXBlcyBhcmUgYWxzbyB1c2VkOgojCiMgbGlzdCBvZiBYICAgICAgICAgYSBjb21tYS1zZXBhcmF0ZWQgbGlzdCBvZiBpdGVtczsgZS5nLiBsaXN0IG9mIHR5cGUKIyBzZXQgb2YgWCAgICAgICAgICBhIGNvbW1hLXNlcGFyYXRlZCBjb2xsZWN0aW9uIG9mIGl0ZW1zOyBlLmcuIHNldCBvZiBtb2RpZmllcgojCiMgVGhlc2UgbWF5IGJlIGNvbXBvc2VkOgojCiMgbGlzdCBvZiB0eXBlIG9yIG1lc3NhZ2Ugc2VnbWVudAojCiMgVGhlIGZvbGxvd2luZyB0eXBlIGFsaWFzZXMgYXJlIHN1cHBvcnRlZDoKIwojIG1lc3NhZ2Ugc2VnbWVudCAtLT4gZGlhZ25vc3RpYyBvciBmcmFnbWVudAojIGZpbGUgbmFtZSAtLT4gZmlsZSBvciBmaWxlIG9iamVjdAojCiMgQ3VzdG9tIGNvbW1lbnRzIGFyZSBzdXBwb3J0ZWQgaW4gcGFyZW50aGVzaXMgaS5lLgojCiMgbnVtYmVyIChjbGFzc2ZpbGUgbWFqb3IgdmVyc2lvbikKIwojIFRoZXNlIGNvbW1lbnRzIGFyZSB1c2VkIGludGVybmFsbHkgaW4gb3JkZXIgdG8gZ2VuZXJhdGUgYW4gZW51bS1saWtlIGNsYXNzIGRlY2xhcmF0aW9uIGNvbnRhaW5pbmcKIyBhIG1ldGhvZC9maWVsZCBmb3IgZWFjaCBvZiB0aGUgZGlhZ25vc3RpYyBrZXlzIGxpc3RlZCBoZXJlLiBUaG9zZSBtZXRob2RzL2ZpZWxkcyBjYW4gdGhlbiBiZSB1c2VkCiMgYnkgamF2YWMgY29kZSB0byBidWlsZCBkaWFnbm9zdGljcyBpbiBhIHR5cGUtc2FmZSBmYXNoaW9uLgojCiMgSW4gYWRkaXRpb24sIHRoZXNlIGNvbW1lbnRzIGFyZSB2ZXJpZmllZCBieSB0aGUganRyZWcgdGVzdCB0ZXN0L3Rvb2xzL2phdmFjL2RpYWdzL01lc3NhZ2VJbmZvLAojIHVzaW5nIGluZm8gZGVyaXZlZCBmcm9tIHRoZSBjb2xsZWN0ZWQgc2V0IG9mIGV4YW1wbGVzIGluIHRlc3QvdG9vbHMvamF2YWMvZGlhZ3MvZXhhbXBsZXMuCiMgTWVzc2FnZUluZm8gY2FuIGFsc28gYmUgcnVuIGFzIGEgc3RhbmRhbG9uZSB1dGlsaXR5IHByb3ZpZGluZyBtb3JlIGZhY2lsaXRpZXMKIyBmb3IgbWFuaXB1bGF0aW5nIHRoaXMgZmlsZS4gRm9yIG1vcmUgZGV0YWlscywgc2VlIE1lc3NhZ2VJbmZvLmphdmEuCgojIwojIyBlcnJvcnMKIyMKCiMgMDogc3ltYm9sCmNvbXBpbGVyLmVyci5hYnN0cmFjdC5jYW50LmJlLmluc3RhbnRpYXRlZD1cCiAgICB7MH0gaXMgYWJzdHJhY3Q7IGNhbm5vdCBiZSBpbnN0YW50aWF0ZWQKCmNvbXBpbGVyLmVyci5hYnN0cmFjdC5tZXRoLmNhbnQuaGF2ZS5ib2R5PVwKICAgIGFic3RyYWN0IG1ldGhvZHMgY2Fubm90IGhhdmUgYSBib2R5Cgpjb21waWxlci5lcnIuYWxyZWFkeS5hbm5vdGF0ZWQ9XAogICAgezB9IHsxfSBoYXMgYWxyZWFkeSBiZWVuIGFubm90YXRlZAoKIyAwOiBzeW1ib2wga2luZCwgMTogc3ltYm9sLCAyOiBzeW1ib2wga2luZCwgMzogc3ltYm9sCmNvbXBpbGVyLmVyci5hbHJlYWR5LmRlZmluZWQ9XAogICAgezB9IHsxfSBpcyBhbHJlYWR5IGRlZmluZWQgaW4gezJ9IHszfQoKIyAwOiBzeW1ib2wga2luZCwgMTogc3ltYm9sLCAyOiBzeW1ib2wga2luZCwgMzogc3ltYm9sIGtpbmQsIDQ6IHN5bWJvbApjb21waWxlci5lcnIuYWxyZWFkeS5kZWZpbmVkLmluLmNsaW5pdD1cCiAgICB7MH0gezF9IGlzIGFscmVhZHkgZGVmaW5lZCBpbiB7Mn0gb2YgezN9IHs0fQoKIyAwOiBzdHJpbmcKY29tcGlsZXIuZXJyLmFscmVhZHkuZGVmaW5lZC5zaW5nbGUuaW1wb3J0PVwKICAgIGEgdHlwZSB3aXRoIHRoZSBzYW1lIHNpbXBsZSBuYW1lIGlzIGFscmVhZHkgZGVmaW5lZCBieSB0aGUgc2luZ2xlLXR5cGUtaW1wb3J0IG9mIHswfQoKIyAwOiBzdHJpbmcKY29tcGlsZXIuZXJyLmFscmVhZHkuZGVmaW5lZC5zdGF0aWMuc2luZ2xlLmltcG9ydD1cCiAgICBhIHR5cGUgd2l0aCB0aGUgc2FtZSBzaW1wbGUgbmFtZSBpcyBhbHJlYWR5IGRlZmluZWQgYnkgdGhlIHN0YXRpYyBzaW5nbGUtdHlwZS1pbXBvcnQgb2YgezB9Cgpjb21waWxlci5lcnIuYWxyZWFkeS5kZWZpbmVkLnRoaXMudW5pdD1cCiAgICB7MH0gaXMgYWxyZWFkeSBkZWZpbmVkIGluIHRoaXMgY29tcGlsYXRpb24gdW5pdAoKIyAwOiB0eXBlLCAxOiBsaXN0IG9mIG5hbWUKY29tcGlsZXIuZXJyLmFubm90YXRpb24ubWlzc2luZy5kZWZhdWx0LnZhbHVlPVwKICAgIGFubm90YXRpb24gQHswfSBpcyBtaXNzaW5nIGEgZGVmYXVsdCB2YWx1ZSBmb3IgdGhlIGVsZW1lbnQgJyd7MX0nJwoKIyAwOiB0eXBlLCAxOiBsaXN0IG9mIG5hbWUKY29tcGlsZXIuZXJyLmFubm90YXRpb24ubWlzc2luZy5kZWZhdWx0LnZhbHVlLjE9XAogICAgYW5ub3RhdGlvbiBAezB9IGlzIG1pc3NpbmcgZGVmYXVsdCB2YWx1ZXMgZm9yIGVsZW1lbnRzIHsxfQoKIyAwOiB0eXBlCmNvbXBpbGVyLmVyci5hbm5vdGF0aW9uLm5vdC52YWxpZC5mb3IudHlwZT1cCiAgICBhbm5vdGF0aW9uIG5vdCB2YWxpZCBmb3IgYW4gZWxlbWVudCBvZiB0eXBlIHswfQoKY29tcGlsZXIuZXJyLmFubm90YXRpb24udHlwZS5ub3QuYXBwbGljYWJsZT1cCiAgICBhbm5vdGF0aW9uIHR5cGUgbm90IGFwcGxpY2FibGUgdG8gdGhpcyBraW5kIG9mIGRlY2xhcmF0aW9uCgojIDA6IHR5cGUKY29tcGlsZXIuZXJyLmFubm90YXRpb24udHlwZS5ub3QuYXBwbGljYWJsZS50by50eXBlPVwKICAgIGFubm90YXRpb24gQHswfSBub3QgYXBwbGljYWJsZSBpbiB0aGlzIHR5cGUgY29udGV4dAoKY29tcGlsZXIuZXJyLmFubm90YXRpb24udmFsdWUubXVzdC5iZS5hbm5vdGF0aW9uPVwKICAgIGFubm90YXRpb24gdmFsdWUgbXVzdCBiZSBhbiBhbm5vdGF0aW9uCgpjb21waWxlci5lcnIuYW5ub3RhdGlvbi52YWx1ZS5tdXN0LmJlLmNsYXNzLmxpdGVyYWw9XAogICAgYW5ub3RhdGlvbiB2YWx1ZSBtdXN0IGJlIGEgY2xhc3MgbGl0ZXJhbAoKY29tcGlsZXIuZXJyLmFubm90YXRpb24udmFsdWUubXVzdC5iZS5uYW1lLnZhbHVlPVwKICAgIGFubm90YXRpb24gdmFsdWVzIG11c3QgYmUgb2YgdGhlIGZvcm0gJyduYW1lPXZhbHVlJycKCmNvbXBpbGVyLmVyci5hbm5vdGF0aW9uLnZhbHVlLm5vdC5hbGxvd2FibGUudHlwZT1cCiAgICBhbm5vdGF0aW9uIHZhbHVlIG5vdCBvZiBhbiBhbGxvd2FibGUgdHlwZQoKY29tcGlsZXIuZXJyLmFub24uY2xhc3MuaW1wbC5pbnRmLm5vLmFyZ3M9XAogICAgYW5vbnltb3VzIGNsYXNzIGltcGxlbWVudHMgaW50ZXJmYWNlOyBjYW5ub3QgaGF2ZSBhcmd1bWVudHMKCmNvbXBpbGVyLmVyci5hbm9uLmNsYXNzLmltcGwuaW50Zi5uby50eXBlYXJncz1cCiAgICBhbm9ueW1vdXMgY2xhc3MgaW1wbGVtZW50cyBpbnRlcmZhY2U7IGNhbm5vdCBoYXZlIHR5cGUgYXJndW1lbnRzCgpjb21waWxlci5lcnIuYW5vbi5jbGFzcy5pbXBsLmludGYubm8ucXVhbC5mb3IubmV3PVwKICAgIGFub255bW91cyBjbGFzcyBpbXBsZW1lbnRzIGludGVyZmFjZTsgY2Fubm90IGhhdmUgcXVhbGlmaWVyIGZvciBuZXcKCmNvbXBpbGVyLmVyci5jYW50LmluaGVyaXQuZnJvbS5hbm9uPVwKICAgIGNhbm5vdCBpbmhlcml0IGZyb20gYW5vbnltb3VzIGNsYXNzCgojIDA6IHN5bWJvbCwgMTogc3ltYm9sLCAyOiBzeW1ib2wKY29tcGlsZXIuZXJyLmFycmF5LmFuZC52YXJhcmdzPVwKICAgIGNhbm5vdCBkZWNsYXJlIGJvdGggezB9IGFuZCB7MX0gaW4gezJ9Cgpjb21waWxlci5lcnIuYXJyYXkuZGltZW5zaW9uLm1pc3Npbmc9XAogICAgYXJyYXkgZGltZW5zaW9uIG1pc3NpbmcKCiMgMDogdHlwZQpjb21waWxlci5lcnIuYXJyYXkucmVxLmJ1dC5mb3VuZD1cCiAgICBhcnJheSByZXF1aXJlZCwgYnV0IHswfSBmb3VuZAoKY29tcGlsZXIuZXJyLmF0dHJpYnV0ZS52YWx1ZS5tdXN0LmJlLmNvbnN0YW50PVwKICAgIGVsZW1lbnQgdmFsdWUgbXVzdCBiZSBhIGNvbnN0YW50IGV4cHJlc3Npb24KCiMgMDogc3RyaW5nIChzdGF0ZW1lbnQgdHlwZSkKY29tcGlsZXIuZXJyLmJhZC5pbml0aWFsaXplcj1cCiAgICBiYWQgaW5pdGlhbGl6ZXIgZm9yIHswfQoKY29tcGlsZXIuZXJyLmJyZWFrLm91dHNpZGUuc3dpdGNoLmxvb3A9XAogICAgYnJlYWsgb3V0c2lkZSBzd2l0Y2ggb3IgbG9vcAoKIyAwOiBuYW1lCmNvbXBpbGVyLmVyci5jYWxsLm11c3QuYmUuZmlyc3Quc3RtdC5pbi5jdG9yPVwKICAgIGNhbGwgdG8gezB9IG11c3QgYmUgZmlyc3Qgc3RhdGVtZW50IGluIGNvbnN0cnVjdG9yCgojIDA6IHN5bWJvbCBraW5kLCAxOiBuYW1lLCAyOiBsaXN0IG9mIHR5cGUgb3IgbWVzc2FnZSBzZWdtZW50LCAzOiBsaXN0IG9mIHR5cGUgb3IgbWVzc2FnZSBzZWdtZW50LCA0OiBzeW1ib2wga2luZCwgNTogdHlwZSwgNjogbWVzc2FnZSBzZWdtZW50CmNvbXBpbGVyLmVyci5jYW50LmFwcGx5LnN5bWJvbD1cCiAgICB7MH0gezF9IGluIHs0fSB7NX0gY2Fubm90IGJlIGFwcGxpZWQgdG8gZ2l2ZW4gdHlwZXM7XG5cCiAgICByZXF1aXJlZDogezJ9XG5cCiAgICBmb3VuZDogezN9XG5cCiAgICByZWFzb246IHs2fQoKIyAwOiBzeW1ib2wga2luZCwgMTogbmFtZSwgMjogbGlzdCBvZiB0eXBlCmNvbXBpbGVyLmVyci5jYW50LmFwcGx5LnN5bWJvbHM9XAogICAgbm8gc3VpdGFibGUgezB9IGZvdW5kIGZvciB7MX0oezJ9KQoKIyAwOiBzeW1ib2wga2luZCwgMTogbmFtZSwgMjogbGlzdCBvZiB0eXBlIG9yIG1lc3NhZ2Ugc2VnbWVudCwgMzogbGlzdCBvZiB0eXBlIG9yIG1lc3NhZ2Ugc2VnbWVudCwgNDogc3ltYm9sIGtpbmQsIDU6IHR5cGUsIDY6IG1lc3NhZ2Ugc2VnbWVudApjb21waWxlci5taXNjLmNhbnQuYXBwbHkuc3ltYm9sPVwKICAgIHswfSB7MX0gaW4gezR9IHs1fSBjYW5ub3QgYmUgYXBwbGllZCB0byBnaXZlbiB0eXBlc1xuXAogICAgcmVxdWlyZWQ6IHsyfVxuXAogICAgZm91bmQ6IHszfVxuXAogICAgcmVhc29uOiB7Nn0KCiMgMDogc3ltYm9sIGtpbmQsIDE6IG5hbWUsIDI6IGxpc3Qgb2YgdHlwZQpjb21waWxlci5taXNjLmNhbnQuYXBwbHkuc3ltYm9scz1cCiAgICBubyBzdWl0YWJsZSB7MH0gZm91bmQgZm9yIHsxfSh7Mn0pCgojIDA6IHN5bWJvbCBraW5kLCAxOiBzeW1ib2wKY29tcGlsZXIubWlzYy5uby5hYnN0cmFjdHM9XAogICAgbm8gYWJzdHJhY3QgbWV0aG9kIGZvdW5kIGluIHswfSB7MX0KCiMgMDogc3ltYm9sIGtpbmQsIDE6IHN5bWJvbApjb21waWxlci5taXNjLmluY29tcGF0aWJsZS5hYnN0cmFjdHM9XAogICAgbXVsdGlwbGUgbm9uLW92ZXJyaWRpbmcgYWJzdHJhY3QgbWV0aG9kcyBmb3VuZCBpbiB7MH0gezF9Cgpjb21waWxlci5lcnIuYmFkLmZ1bmN0aW9uYWwuaW50Zi5hbm5vPVwKICAgIFVuZXhwZWN0ZWQgQEZ1bmN0aW9uYWxJbnRlcmZhY2UgYW5ub3RhdGlvbgoKIyAwOiBtZXNzYWdlIHNlZ21lbnQKY29tcGlsZXIuZXJyLmJhZC5mdW5jdGlvbmFsLmludGYuYW5uby4xPVwKICAgIFVuZXhwZWN0ZWQgQEZ1bmN0aW9uYWxJbnRlcmZhY2UgYW5ub3RhdGlvblxuXAogICAgezB9CgojIDA6IG1lc3NhZ2Ugc2VnbWVudApjb21waWxlci5lcnIuYW5vbnltb3VzLmRpYW1vbmQubWV0aG9kLmRvZXMubm90Lm92ZXJyaWRlLnN1cGVyY2xhc3M9XAogICAgbWV0aG9kIGRvZXMgbm90IG92ZXJyaWRlIG9yIGltcGxlbWVudCBhIG1ldGhvZCBmcm9tIGEgc3VwZXJ0eXBlXG5cCiAgICB7MH0KCiMgMDogc3ltYm9sCmNvbXBpbGVyLm1pc2Mubm90LmEuZnVuY3Rpb25hbC5pbnRmPVwKICAgIHswfSBpcyBub3QgYSBmdW5jdGlvbmFsIGludGVyZmFjZQoKIyAwOiBzeW1ib2wsIDE6IG1lc3NhZ2Ugc2VnbWVudApjb21waWxlci5taXNjLm5vdC5hLmZ1bmN0aW9uYWwuaW50Zi4xPVwKICAgIHswfSBpcyBub3QgYSBmdW5jdGlvbmFsIGludGVyZmFjZVxuXAogICAgezF9CgojIDA6IHN5bWJvbCwgMTogc3ltYm9sIGtpbmQsIDI6IHN5bWJvbApjb21waWxlci5taXNjLmludmFsaWQuZ2VuZXJpYy5sYW1iZGEudGFyZ2V0PVwKICAgIGludmFsaWQgZnVuY3Rpb25hbCBkZXNjcmlwdG9yIGZvciBsYW1iZGEgZXhwcmVzc2lvblxuXAogICAgbWV0aG9kIHswfSBpbiB7MX0gezJ9IGlzIGdlbmVyaWMKCiMgMDogc3ltYm9sIGtpbmQsIDE6IHN5bWJvbApjb21waWxlci5taXNjLmluY29tcGF0aWJsZS5kZXNjcy5pbi5mdW5jdGlvbmFsLmludGY9XAogICAgaW5jb21wYXRpYmxlIGZ1bmN0aW9uIGRlc2NyaXB0b3JzIGZvdW5kIGluIHswfSB7MX0KCiMgMDogbmFtZSwgMTogbGlzdCBvZiB0eXBlLCAyOiB0eXBlLCAzOiBsaXN0IG9mIHR5cGUKY29tcGlsZXIubWlzYy5kZXNjcmlwdG9yPVwKICAgIGRlc2NyaXB0b3I6IHsyfSB7MH0oezF9KQoKIyAwOiBuYW1lLCAxOiBsaXN0IG9mIHR5cGUsIDI6IHR5cGUsIDM6IGxpc3Qgb2YgdHlwZQpjb21waWxlci5taXNjLmRlc2NyaXB0b3IudGhyb3dzPVwKICAgIGRlc2NyaXB0b3I6IHsyfSB7MH0oezF9KSB0aHJvd3MgezN9CgojIDA6IHR5cGUKY29tcGlsZXIubWlzYy5uby5zdWl0YWJsZS5mdW5jdGlvbmFsLmludGYuaW5zdD1cCiAgICBjYW5ub3QgaW5mZXIgZnVuY3Rpb25hbCBpbnRlcmZhY2UgZGVzY3JpcHRvciBmb3IgezB9CgojIDA6IG1lc3NhZ2Ugc2VnbWVudApjb21waWxlci5taXNjLmJhZC5pbnRlcnNlY3Rpb24udGFyZ2V0LmZvci5mdW5jdGlvbmFsLmV4cHI9XAogICAgYmFkIGludGVyc2VjdGlvbiB0eXBlIHRhcmdldCBmb3IgbGFtYmRhIG9yIG1ldGhvZCByZWZlcmVuY2VcblwKICAgIHswfQoKIyAwOiBzeW1ib2wgb3IgdHlwZQpjb21waWxlci5taXNjLm5vdC5hbi5pbnRmLmNvbXBvbmVudD1cCiAgICBjb21wb25lbnQgdHlwZSB7MH0gaXMgbm90IGFuIGludGVyZmFjZQoKIyAwOiBzeW1ib2wga2luZCwgMTogbWVzc2FnZSBzZWdtZW50CmNvbXBpbGVyLmVyci5pbnZhbGlkLm1yZWY9XAogICAgaW52YWxpZCB7MH0gcmVmZXJlbmNlXG5cCiAgICB7MX0KCiMgMDogc3ltYm9sIGtpbmQsIDE6IG1lc3NhZ2Ugc2VnbWVudApjb21waWxlci5taXNjLmludmFsaWQubXJlZj1cCiAgICBpbnZhbGlkIHswfSByZWZlcmVuY2VcblwKICAgIHsxfQoKY29tcGlsZXIubWlzYy5zdGF0aWMubXJlZi53aXRoLnRhcmdzPVwKICAgIHBhcmFtZXRlcml6ZWQgcXVhbGlmaWVyIG9uIHN0YXRpYyBtZXRob2QgcmVmZXJlbmNlCgojIDA6IHN5bWJvbApjb21waWxlci5lcnIuY2FudC5hc3NpZ24udmFsLnRvLmZpbmFsLnZhcj1cCiAgICBjYW5ub3QgYXNzaWduIGEgdmFsdWUgdG8gZmluYWwgdmFyaWFibGUgezB9Cgpjb21waWxlci5lcnIuY2FudC5hc3NpZ24udmFsLnRvLnRoaXM9XAogICAgY2Fubm90IGFzc2lnbiB0byAnJ3RoaXMnJwoKIyAwOiBzeW1ib2wsIDE6IG1lc3NhZ2Ugc2VnbWVudApjb21waWxlci5lcnIuY2FudC5yZWYubm9uLmVmZmVjdGl2ZWx5LmZpbmFsLnZhcj1cCiAgICBsb2NhbCB2YXJpYWJsZXMgcmVmZXJlbmNlZCBmcm9tIHsxfSBtdXN0IGJlIGZpbmFsIG9yIGVmZmVjdGl2ZWx5IGZpbmFsCgpjb21waWxlci5lcnIudHJ5LndpdGgucmVzb3VyY2VzLmV4cHIubmVlZHMudmFyPVwKICAgIHRoZSB0cnktd2l0aC1yZXNvdXJjZXMgcmVzb3VyY2UgbXVzdCBlaXRoZXIgYmUgYSB2YXJpYWJsZSBkZWNsYXJhdGlvbiBvciBhbiBleHByZXNzaW9uIGRlbm90aW5nIFwKYSByZWZlcmVuY2UgdG8gYSBmaW5hbCBvciBlZmZlY3RpdmVseSBmaW5hbCB2YXJpYWJsZQoKIyAwOiBzeW1ib2wKY29tcGlsZXIuZXJyLnRyeS53aXRoLnJlc291cmNlcy5leHByLmVmZmVjdGl2ZWx5LmZpbmFsLnZhcj1cCiAgICB2YXJpYWJsZSB7MH0gdXNlZCBhcyBhIHRyeS13aXRoLXJlc291cmNlcyByZXNvdXJjZSBuZWl0aGVyIGZpbmFsIG5vciBlZmZlY3RpdmVseSBmaW5hbAoKCmNvbXBpbGVyLm1pc2MubGFtYmRhPVwKICAgIGEgbGFtYmRhIGV4cHJlc3Npb24KCmNvbXBpbGVyLm1pc2MuaW5uZXIuY2xzPVwKICAgIGFuIGlubmVyIGNsYXNzCgojIDA6IHR5cGUKY29tcGlsZXIuZXJyLmNhbnQuZGVyZWY9XAogICAgezB9IGNhbm5vdCBiZSBkZXJlZmVyZW5jZWQKCmNvbXBpbGVyLmVyci5jYW50LmV4dGVuZC5pbnRmLmFubm90YXRpb249XAogICAgJydleHRlbmRzJycgbm90IGFsbG93ZWQgZm9yIEBpbnRlcmZhY2VzCgojIDA6IHN5bWJvbApjb21waWxlci5lcnIuY2FudC5pbmhlcml0LmZyb20uZmluYWw9XAogICAgY2Fubm90IGluaGVyaXQgZnJvbSBmaW5hbCB7MH0KCiMgMDogc3ltYm9sCmNvbXBpbGVyLmVyci5jYW50LnJlZi5iZWZvcmUuY3Rvci5jYWxsZWQ9XAogICAgY2Fubm90IHJlZmVyZW5jZSB7MH0gYmVmb3JlIHN1cGVydHlwZSBjb25zdHJ1Y3RvciBoYXMgYmVlbiBjYWxsZWQKCmNvbXBpbGVyLmVyci5jYW50LnNlbGVjdC5zdGF0aWMuY2xhc3MuZnJvbS5wYXJhbS50eXBlPVwKICAgIGNhbm5vdCBzZWxlY3QgYSBzdGF0aWMgY2xhc3MgZnJvbSBhIHBhcmFtZXRlcml6ZWQgdHlwZQoKIyAwOiBzeW1ib2wsIDE6IHN0cmluZywgMjogc3RyaW5nCmNvbXBpbGVyLmVyci5jYW50LmluaGVyaXQuZGlmZi5hcmc9XAogICAgezB9IGNhbm5vdCBiZSBpbmhlcml0ZWQgd2l0aCBkaWZmZXJlbnQgYXJndW1lbnRzOiA8ezF9PiBhbmQgPHsyfT4KCmNvbXBpbGVyLmVyci5jYXRjaC53aXRob3V0LnRyeT1cCiAgICAnJ2NhdGNoJycgd2l0aG91dCAnJ3RyeScnCgojIDA6IHN5bWJvbCBraW5kLCAxOiBzeW1ib2wKY29tcGlsZXIuZXJyLmNsYXNoLndpdGgucGtnLm9mLnNhbWUubmFtZT1cCiAgICB7MH0gezF9IGNsYXNoZXMgd2l0aCBwYWNrYWdlIG9mIHNhbWUgbmFtZQoKY29tcGlsZXIuZXJyLmNsYXNzLm5vdC5hbGxvd2VkPVwKICAgIGNsYXNzLCBpbnRlcmZhY2Ugb3IgZW51bSBkZWNsYXJhdGlvbiBub3QgYWxsb3dlZCBoZXJlCgpjb21waWxlci5lcnIuY29uc3QuZXhwci5yZXE9XAogICAgY29uc3RhbnQgZXhwcmVzc2lvbiByZXF1aXJlZAoKY29tcGlsZXIuZXJyLmNvbnQub3V0c2lkZS5sb29wPVwKICAgIGNvbnRpbnVlIG91dHNpZGUgb2YgbG9vcAoKIyAwOiBzeW1ib2wKY29tcGlsZXIuZXJyLmN5Y2xpYy5pbmhlcml0YW5jZT1cCiAgICBjeWNsaWMgaW5oZXJpdGFuY2UgaW52b2x2aW5nIHswfQoKIyAwOiBzeW1ib2wKY29tcGlsZXIuZXJyLmN5Y2xpYy5hbm5vdGF0aW9uLmVsZW1lbnQ9XAogICAgdHlwZSBvZiBlbGVtZW50IHswfSBpcyBjeWNsaWMKCiMgMDogdW51c2VkCmNvbXBpbGVyLmVyci5jYWxsLnRvLnN1cGVyLm5vdC5hbGxvd2VkLmluLmVudW0uY3Rvcj1cCiAgICBjYWxsIHRvIHN1cGVyIG5vdCBhbGxvd2VkIGluIGVudW0gY29uc3RydWN0b3IKCiMgMDogdHlwZQpjb21waWxlci5lcnIubm8uc3VwZXJjbGFzcz1cCiAgICB7MH0gaGFzIG5vIHN1cGVyY2xhc3MuCgojIDA6IHN5bWJvbCwgMTogdHlwZSwgMjogc3ltYm9sLCAzOiB0eXBlLCA0OiB1bnVzZWQKY29tcGlsZXIuZXJyLmNvbmNyZXRlLmluaGVyaXRhbmNlLmNvbmZsaWN0PVwKICAgIG1ldGhvZHMgezB9IGZyb20gezF9IGFuZCB7Mn0gZnJvbSB7M30gYXJlIGluaGVyaXRlZCB3aXRoIHRoZSBzYW1lIHNpZ25hdHVyZQoKY29tcGlsZXIuZXJyLmRlZmF1bHQuYWxsb3dlZC5pbi5pbnRmLmFubm90YXRpb24ubWVtYmVyPVwKICAgIGRlZmF1bHQgdmFsdWUgb25seSBhbGxvd2VkIGluIGFuIGFubm90YXRpb24gdHlwZSBkZWNsYXJhdGlvbgoKIyAwOiBzeW1ib2wKY29tcGlsZXIuZXJyLmRvZXNudC5leGlzdD1cCiAgICBwYWNrYWdlIHswfSBkb2VzIG5vdCBleGlzdAoKIyAwOiB0eXBlCmNvbXBpbGVyLmVyci5kdXBsaWNhdGUuYW5ub3RhdGlvbi5pbnZhbGlkLnJlcGVhdGVkPVwKICAgIGFubm90YXRpb24gezB9IGlzIG5vdCBhIHZhbGlkIHJlcGVhdGFibGUgYW5ub3RhdGlvbgoKIyAwOiBuYW1lLCAxOiB0eXBlCmNvbXBpbGVyLmVyci5kdXBsaWNhdGUuYW5ub3RhdGlvbi5tZW1iZXIudmFsdWU9XAogICAgZHVwbGljYXRlIGVsZW1lbnQgJyd7MH0nJyBpbiBhbm5vdGF0aW9uIEB7MX0uCgojIDA6IG5hbWUsIDE6IHVudXNlZApjb21waWxlci5lcnIuZHVwbGljYXRlLmFubm90YXRpb24ubWlzc2luZy5jb250YWluZXI9XAogICAgezB9IGlzIG5vdCBhIHJlcGVhdGFibGUgYW5ub3RhdGlvbiB0eXBlCgojIDA6IHR5cGUsIDE6IHVudXNlZApjb21waWxlci5lcnIuaW52YWxpZC5yZXBlYXRhYmxlLmFubm90YXRpb249XAogICAgZHVwbGljYXRlIGFubm90YXRpb246IHswfSBpcyBhbm5vdGF0ZWQgd2l0aCBhbiBpbnZhbGlkIEBSZXBlYXRhYmxlIGFubm90YXRpb24KCiMgMDogc3ltYm9sIG9yIHR5cGUKY29tcGlsZXIuZXJyLmludmFsaWQucmVwZWF0YWJsZS5hbm5vdGF0aW9uLm5vLnZhbHVlPVwKICAgIHswfSBpcyBub3QgYSB2YWxpZCBAUmVwZWF0YWJsZSwgbm8gdmFsdWUgZWxlbWVudCBtZXRob2QgZGVjbGFyZWQKCiMgMDogdHlwZSwgMTogbnVtYmVyCmNvbXBpbGVyLmVyci5pbnZhbGlkLnJlcGVhdGFibGUuYW5ub3RhdGlvbi5tdWx0aXBsZS52YWx1ZXM9XAogICAgezB9IGlzIG5vdCBhIHZhbGlkIEBSZXBlYXRhYmxlLCB7MX0gZWxlbWVudCBtZXRob2RzIG5hbWVkICcndmFsdWUnJyBkZWNsYXJlZAoKIyAwOiB0eXBlCmNvbXBpbGVyLmVyci5pbnZhbGlkLnJlcGVhdGFibGUuYW5ub3RhdGlvbi5pbnZhbGlkLnZhbHVlPVwKICAgIHswfSBpcyBub3QgYSB2YWxpZCBAUmVwZWF0YWJsZTogaW52YWxpZCB2YWx1ZSBlbGVtZW50CgojIDA6IHN5bWJvbCBvciB0eXBlLCAxOiB1bnVzZWQsIDI6IHR5cGUKY29tcGlsZXIuZXJyLmludmFsaWQucmVwZWF0YWJsZS5hbm5vdGF0aW9uLnZhbHVlLnJldHVybj1cCiAgICBjb250YWluaW5nIGFubm90YXRpb24gdHlwZSAoezB9KSBtdXN0IGRlY2xhcmUgYW4gZWxlbWVudCBuYW1lZCAnJ3ZhbHVlJycgb2YgdHlwZSB7Mn0KCiMgMDogc3ltYm9sIG9yIHR5cGUsIDE6IHN5bWJvbApjb21waWxlci5lcnIuaW52YWxpZC5yZXBlYXRhYmxlLmFubm90YXRpb24uZWxlbS5ub25kZWZhdWx0PVwKICAgIGNvbnRhaW5pbmcgYW5ub3RhdGlvbiB0eXBlICh7MH0pIGRvZXMgbm90IGhhdmUgYSBkZWZhdWx0IHZhbHVlIGZvciBlbGVtZW50IHsxfQoKIyAwOiBzeW1ib2wsIDE6IHVudXNlZCwgMjogc3ltYm9sLCAzOiB1bnVzZWQKY29tcGlsZXIuZXJyLmludmFsaWQucmVwZWF0YWJsZS5hbm5vdGF0aW9uLnJldGVudGlvbj1cCiAgICByZXRlbnRpb24gb2YgY29udGFpbmluZyBhbm5vdGF0aW9uIHR5cGUgKHswfSkgaXMgc2hvcnRlciB0aGFuIHRoZSByZXRlbnRpb24gb2YgcmVwZWF0YWJsZSBhbm5vdGF0aW9uIHR5cGUgKHsyfSkKCiMgMDogc3ltYm9sLCAxOiBzeW1ib2wKY29tcGlsZXIuZXJyLmludmFsaWQucmVwZWF0YWJsZS5hbm5vdGF0aW9uLm5vdC5kb2N1bWVudGVkPVwKICAgIHJlcGVhdGFibGUgYW5ub3RhdGlvbiB0eXBlICh7MX0pIGlzIEBEb2N1bWVudGVkIHdoaWxlIGNvbnRhaW5pbmcgYW5ub3RhdGlvbiB0eXBlICh7MH0pIGlzIG5vdAoKIyAwOiBzeW1ib2wsIDE6IHN5bWJvbApjb21waWxlci5lcnIuaW52YWxpZC5yZXBlYXRhYmxlLmFubm90YXRpb24ubm90LmluaGVyaXRlZD1cCiAgICByZXBlYXRhYmxlIGFubm90YXRpb24gdHlwZSAoezF9KSBpcyBASW5oZXJpdGVkIHdoaWxlIGNvbnRhaW5pbmcgYW5ub3RhdGlvbiB0eXBlICh7MH0pIGlzIG5vdAoKIyAwOiBzeW1ib2wsIDE6IHN5bWJvbApjb21waWxlci5lcnIuaW52YWxpZC5yZXBlYXRhYmxlLmFubm90YXRpb24uaW5jb21wYXRpYmxlLnRhcmdldD1cCiAgICBjb250YWluaW5nIGFubm90YXRpb24gdHlwZSAoezB9KSBpcyBhcHBsaWNhYmxlIHRvIG1vcmUgdGFyZ2V0cyB0aGFuIHJlcGVhdGFibGUgYW5ub3RhdGlvbiB0eXBlICh7MX0pCgojIDA6IHN5bWJvbApjb21waWxlci5lcnIuaW52YWxpZC5yZXBlYXRhYmxlLmFubm90YXRpb24ucmVwZWF0ZWQuYW5kLmNvbnRhaW5lci5wcmVzZW50PVwKICAgIGNvbnRhaW5lciB7MH0gbXVzdCBub3QgYmUgcHJlc2VudCBhdCB0aGUgc2FtZSB0aW1lIGFzIHRoZSBlbGVtZW50IGl0IGNvbnRhaW5zCgojIDA6IHR5cGUsIDE6IHN5bWJvbApjb21waWxlci5lcnIuaW52YWxpZC5yZXBlYXRhYmxlLmFubm90YXRpb24ubm90LmFwcGxpY2FibGU9XAogICAgY29udGFpbmVyIHswfSBpcyBub3QgYXBwbGljYWJsZSB0byBlbGVtZW50IHsxfQoKIyAwOiB0eXBlCmNvbXBpbGVyLmVyci5pbnZhbGlkLnJlcGVhdGFibGUuYW5ub3RhdGlvbi5ub3QuYXBwbGljYWJsZS5pbi5jb250ZXh0PVwKICAgIGNvbnRhaW5lciB7MH0gaXMgbm90IGFwcGxpY2FibGUgaW4gdGhpcyB0eXBlIGNvbnRleHQKCiMgMDogbmFtZQpjb21waWxlci5lcnIuZHVwbGljYXRlLmNsYXNzPVwKICAgIGR1cGxpY2F0ZSBjbGFzczogezB9Cgpjb21waWxlci5lcnIuZHVwbGljYXRlLmNhc2UubGFiZWw9XAogICAgZHVwbGljYXRlIGNhc2UgbGFiZWwKCmNvbXBpbGVyLmVyci5kdXBsaWNhdGUuZGVmYXVsdC5sYWJlbD1cCiAgICBkdXBsaWNhdGUgZGVmYXVsdCBsYWJlbAoKY29tcGlsZXIuZXJyLmVsc2Uud2l0aG91dC5pZj1cCiAgICAnJ2Vsc2UnJyB3aXRob3V0ICcnaWYnJwoKY29tcGlsZXIuZXJyLmVtcHR5LmNoYXIubGl0PVwKICAgIGVtcHR5IGNoYXJhY3RlciBsaXRlcmFsCgojIDA6IHN5bWJvbApjb21waWxlci5lcnIuZW5jbC5jbGFzcy5yZXF1aXJlZD1cCiAgICBhbiBlbmNsb3NpbmcgaW5zdGFuY2UgdGhhdCBjb250YWlucyB7MH0gaXMgcmVxdWlyZWQKCmNvbXBpbGVyLmVyci5lbnVtLmFubm90YXRpb24ubXVzdC5iZS5lbnVtLmNvbnN0YW50PVwKICAgIGFuIGVudW0gYW5ub3RhdGlvbiB2YWx1ZSBtdXN0IGJlIGFuIGVudW0gY29uc3RhbnQKCmNvbXBpbGVyLmVyci5lbnVtLmNhbnQuYmUuaW5zdGFudGlhdGVkPVwKICAgIGVudW0gdHlwZXMgbWF5IG5vdCBiZSBpbnN0YW50aWF0ZWQKCmNvbXBpbGVyLmVyci5lbnVtLmxhYmVsLm11c3QuYmUudW5xdWFsaWZpZWQuZW51bT1cCiAgICBhbiBlbnVtIHN3aXRjaCBjYXNlIGxhYmVsIG11c3QgYmUgdGhlIHVucXVhbGlmaWVkIG5hbWUgb2YgYW4gZW51bWVyYXRpb24gY29uc3RhbnQKCmNvbXBpbGVyLmVyci5lbnVtLm5vLnN1YmNsYXNzaW5nPVwKICAgIGNsYXNzZXMgY2Fubm90IGRpcmVjdGx5IGV4dGVuZCBqYXZhLmxhbmcuRW51bQoKY29tcGlsZXIuZXJyLmVudW0udHlwZXMubm90LmV4dGVuc2libGU9XAogICAgZW51bSB0eXBlcyBhcmUgbm90IGV4dGVuc2libGUKCmNvbXBpbGVyLmVyci5lbnVtLm5vLmZpbmFsaXplPVwKICAgIGVudW1zIGNhbm5vdCBoYXZlIGZpbmFsaXplIG1ldGhvZHMKCiMgMDogZmlsZSBuYW1lLCAxOiBzdHJpbmcKY29tcGlsZXIuZXJyLmVycm9yLnJlYWRpbmcuZmlsZT1cCiAgICBlcnJvciByZWFkaW5nIHswfTsgezF9CgojIDA6IHR5cGUKY29tcGlsZXIuZXJyLmV4Y2VwdC5hbHJlYWR5LmNhdWdodD1cCiAgICBleGNlcHRpb24gezB9IGhhcyBhbHJlYWR5IGJlZW4gY2F1Z2h0CgojIDA6IHR5cGUKY29tcGlsZXIuZXJyLmV4Y2VwdC5uZXZlci50aHJvd24uaW4udHJ5PVwKICAgIGV4Y2VwdGlvbiB7MH0gaXMgbmV2ZXIgdGhyb3duIGluIGJvZHkgb2YgY29ycmVzcG9uZGluZyB0cnkgc3RhdGVtZW50CgojIDA6IHN5bWJvbApjb21waWxlci5lcnIuZmluYWwucGFyYW1ldGVyLm1heS5ub3QuYmUuYXNzaWduZWQ9XAogICAgZmluYWwgcGFyYW1ldGVyIHswfSBtYXkgbm90IGJlIGFzc2lnbmVkCgojIDA6IHN5bWJvbApjb21waWxlci5lcnIudHJ5LnJlc291cmNlLm1heS5ub3QuYmUuYXNzaWduZWQ9XAogICAgYXV0by1jbG9zZWFibGUgcmVzb3VyY2UgezB9IG1heSBub3QgYmUgYXNzaWduZWQKCiMgMDogc3ltYm9sCmNvbXBpbGVyLmVyci5tdWx0aWNhdGNoLnBhcmFtZXRlci5tYXkubm90LmJlLmFzc2lnbmVkPVwKICAgIG11bHRpLWNhdGNoIHBhcmFtZXRlciB7MH0gbWF5IG5vdCBiZSBhc3NpZ25lZAoKIyAwOiB0eXBlLCAxOiB0eXBlCmNvbXBpbGVyLmVyci5tdWx0aWNhdGNoLnR5cGVzLm11c3QuYmUuZGlzam9pbnQ9XAogICAgQWx0ZXJuYXRpdmVzIGluIGEgbXVsdGktY2F0Y2ggc3RhdGVtZW50IGNhbm5vdCBiZSByZWxhdGVkIGJ5IHN1YmNsYXNzaW5nXG5cCiAgICBBbHRlcm5hdGl2ZSB7MH0gaXMgYSBzdWJjbGFzcyBvZiBhbHRlcm5hdGl2ZSB7MX0KCmNvbXBpbGVyLmVyci5maW5hbGx5LndpdGhvdXQudHJ5PVwKICAgICcnZmluYWxseScnIHdpdGhvdXQgJyd0cnknJwoKIyAwOiB0eXBlLCAxOiBtZXNzYWdlIHNlZ21lbnQKY29tcGlsZXIuZXJyLmZvcmVhY2gubm90LmFwcGxpY2FibGUudG8udHlwZT1cCiAgICBmb3ItZWFjaCBub3QgYXBwbGljYWJsZSB0byBleHByZXNzaW9uIHR5cGVcblwKICAgIHJlcXVpcmVkOiB7MX1cblwKICAgIGZvdW5kOiAgICB7MH0KCmNvbXBpbGVyLmVyci5mcC5udW1iZXIudG9vLmxhcmdlPVwKICAgIGZsb2F0aW5nIHBvaW50IG51bWJlciB0b28gbGFyZ2UKCmNvbXBpbGVyLmVyci5mcC5udW1iZXIudG9vLnNtYWxsPVwKICAgIGZsb2F0aW5nIHBvaW50IG51bWJlciB0b28gc21hbGwKCmNvbXBpbGVyLmVyci5nZW5lcmljLmFycmF5LmNyZWF0aW9uPVwKICAgIGdlbmVyaWMgYXJyYXkgY3JlYXRpb24KCmNvbXBpbGVyLmVyci5nZW5lcmljLnRocm93YWJsZT1cCiAgICBhIGdlbmVyaWMgY2xhc3MgbWF5IG5vdCBleHRlbmQgamF2YS5sYW5nLlRocm93YWJsZQoKIyAwOiBzeW1ib2wKY29tcGlsZXIuZXJyLmljbHMuY2FudC5oYXZlLnN0YXRpYy5kZWNsPVwKICAgIElsbGVnYWwgc3RhdGljIGRlY2xhcmF0aW9uIGluIGlubmVyIGNsYXNzIHswfVxuXAogICAgbW9kaWZpZXIgXCcnc3RhdGljXCcnIGlzIG9ubHkgYWxsb3dlZCBpbiBjb25zdGFudCB2YXJpYWJsZSBkZWNsYXJhdGlvbnMKCiMgMDogc3RyaW5nCmNvbXBpbGVyLmVyci5pbGxlZ2FsLmNoYXI9XAogICAgaWxsZWdhbCBjaGFyYWN0ZXI6ICcnezB9JycKCiMgMDogc3RyaW5nLCAxOiBzdHJpbmcKY29tcGlsZXIuZXJyLmlsbGVnYWwuY2hhci5mb3IuZW5jb2Rpbmc9XAogICAgdW5tYXBwYWJsZSBjaGFyYWN0ZXIgKDB4ezB9KSBmb3IgZW5jb2RpbmcgezF9CgojIDA6IHNldCBvZiBtb2RpZmllciwgMTogc2V0IG9mIG1vZGlmaWVyCmNvbXBpbGVyLmVyci5pbGxlZ2FsLmNvbWJpbmF0aW9uLm9mLm1vZGlmaWVycz1cCiAgICBpbGxlZ2FsIGNvbWJpbmF0aW9uIG9mIG1vZGlmaWVyczogezB9IGFuZCB7MX0KCmNvbXBpbGVyLmVyci5pbGxlZ2FsLmVudW0uc3RhdGljLnJlZj1cCiAgICBpbGxlZ2FsIHJlZmVyZW5jZSB0byBzdGF0aWMgZmllbGQgZnJvbSBpbml0aWFsaXplcgoKY29tcGlsZXIuZXJyLmlsbGVnYWwuZXNjLmNoYXI9XAogICAgaWxsZWdhbCBlc2NhcGUgY2hhcmFjdGVyCgpjb21waWxlci5lcnIuaWxsZWdhbC5mb3J3YXJkLnJlZj1cCiAgICBpbGxlZ2FsIGZvcndhcmQgcmVmZXJlbmNlCgojIDA6IHN5bWJvbCwgMTogc3RyaW5nCmNvbXBpbGVyLmVyci5ub3QuaW4ucHJvZmlsZT1cCiAgICB7MH0gaXMgbm90IGF2YWlsYWJsZSBpbiBwcm9maWxlICcnezF9JycKCiMgMDogc3ltYm9sCmNvbXBpbGVyLndhcm4uZm9yd2FyZC5yZWY9XAogICAgcmVmZXJlbmNlIHRvIHZhcmlhYmxlICcnezB9JycgYmVmb3JlIGl0IGhhcyBiZWVuIGluaXRpYWxpemVkCgpjb21waWxlci5lcnIuaWxsZWdhbC5zZWxmLnJlZj1cCiAgICBzZWxmLXJlZmVyZW5jZSBpbiBpbml0aWFsaXplcgoKIyAwOiBzeW1ib2wKY29tcGlsZXIud2Fybi5zZWxmLnJlZj1cCiAgICBzZWxmLXJlZmVyZW5jZSBpbiBpbml0aWFsaXplciBvZiB2YXJpYWJsZSAnJ3swfScnCgpjb21waWxlci5lcnIuaWxsZWdhbC5nZW5lcmljLnR5cGUuZm9yLmluc3RvZj1cCiAgICBpbGxlZ2FsIGdlbmVyaWMgdHlwZSBmb3IgaW5zdGFuY2VvZgoKIyAwOiB0eXBlCmNvbXBpbGVyLmVyci5pbGxlZ2FsLmluaXRpYWxpemVyLmZvci50eXBlPVwKICAgIGlsbGVnYWwgaW5pdGlhbGl6ZXIgZm9yIHswfQoKY29tcGlsZXIuZXJyLmlsbGVnYWwubGluZS5lbmQuaW4uY2hhci5saXQ9XAogICAgaWxsZWdhbCBsaW5lIGVuZCBpbiBjaGFyYWN0ZXIgbGl0ZXJhbAoKY29tcGlsZXIuZXJyLmlsbGVnYWwubm9uYXNjaWkuZGlnaXQ9XAogICAgaWxsZWdhbCBub24tQVNDSUkgZGlnaXQKCmNvbXBpbGVyLmVyci5pbGxlZ2FsLnVuZGVyc2NvcmU9XAogICAgaWxsZWdhbCB1bmRlcnNjb3JlCgpjb21waWxlci5lcnIuaWxsZWdhbC5kb3Q9XAogICAgaWxsZWdhbCAnJy4nJwoKIyAwOiBzeW1ib2wKY29tcGlsZXIuZXJyLmlsbGVnYWwucXVhbC5ub3QuaWNscz1cCiAgICBpbGxlZ2FsIHF1YWxpZmllcjsgezB9IGlzIG5vdCBhbiBpbm5lciBjbGFzcwoKY29tcGlsZXIuZXJyLmlsbGVnYWwuc3RhcnQub2YuZXhwcj1cCiAgICBpbGxlZ2FsIHN0YXJ0IG9mIGV4cHJlc3Npb24KCmNvbXBpbGVyLmVyci5pbGxlZ2FsLnN0YXJ0Lm9mLnN0bXQ9XAogICAgaWxsZWdhbCBzdGFydCBvZiBzdGF0ZW1lbnQKCmNvbXBpbGVyLmVyci5pbGxlZ2FsLnN0YXJ0Lm9mLnR5cGU9XAogICAgaWxsZWdhbCBzdGFydCBvZiB0eXBlCgpjb21waWxlci5lcnIuaWxsZWdhbC51bmljb2RlLmVzYz1cCiAgICBpbGxlZ2FsIHVuaWNvZGUgZXNjYXBlCgojIDA6IHN5bWJvbApjb21waWxlci5lcnIuaW1wb3J0LnJlcXVpcmVzLmNhbm9uaWNhbD1cCiAgICBpbXBvcnQgcmVxdWlyZXMgY2Fub25pY2FsIG5hbWUgZm9yIHswfQoKY29tcGlsZXIuZXJyLmltcHJvcGVybHkuZm9ybWVkLnR5cGUucGFyYW0ubWlzc2luZz1cCiAgICBpbXByb3Blcmx5IGZvcm1lZCB0eXBlLCBzb21lIHBhcmFtZXRlcnMgYXJlIG1pc3NpbmcKCmNvbXBpbGVyLmVyci5pbXByb3Blcmx5LmZvcm1lZC50eXBlLmlubmVyLnJhdy5wYXJhbT1cCiAgICBpbXByb3Blcmx5IGZvcm1lZCB0eXBlLCB0eXBlIGFyZ3VtZW50cyBnaXZlbiBvbiBhIHJhdyB0eXBlCgojIDA6IHR5cGUsIDE6IHR5cGUKY29tcGlsZXIuZXJyLmluY29tcGFyYWJsZS50eXBlcz1cCiAgICBpbmNvbXBhcmFibGUgdHlwZXM6IHswfSBhbmQgezF9CgojIDA6IG51bWJlcgpjb21waWxlci5lcnIuaW50Lm51bWJlci50b28ubGFyZ2U9XAogICAgaW50ZWdlciBudW1iZXIgdG9vIGxhcmdlOiB7MH0KCmNvbXBpbGVyLmVyci5pbnRmLmFubm90YXRpb24ubWVtYmVycy5jYW50LmhhdmUucGFyYW1zPVwKICAgIGVsZW1lbnRzIGluIGFubm90YXRpb24gdHlwZSBkZWNsYXJhdGlvbnMgY2Fubm90IGRlY2xhcmUgZm9ybWFsIHBhcmFtZXRlcnMKCiMgMDogc3ltYm9sCmNvbXBpbGVyLmVyci5pbnRmLmFubm90YXRpb24uY2FudC5oYXZlLnR5cGUucGFyYW1zPVwKICAgIGFubm90YXRpb24gdHlwZSB7MH0gY2Fubm90IGJlIGdlbmVyaWMKCmNvbXBpbGVyLmVyci5pbnRmLmFubm90YXRpb24ubWVtYmVycy5jYW50LmhhdmUudHlwZS5wYXJhbXM9XAogICAgZWxlbWVudHMgaW4gYW5ub3RhdGlvbiB0eXBlIGRlY2xhcmF0aW9ucyBjYW5ub3QgYmUgZ2VuZXJpYyBtZXRob2RzCgojIDA6IHN5bWJvbCwgMTogdHlwZQpjb21waWxlci5lcnIuaW50Zi5hbm5vdGF0aW9uLm1lbWJlci5jbGFzaD1cCiAgICBhbm5vdGF0aW9uIHR5cGUgezF9IGRlY2xhcmVzIGFuIGVsZW1lbnQgd2l0aCB0aGUgc2FtZSBuYW1lIGFzIG1ldGhvZCB7MH0KCmNvbXBpbGVyLmVyci5pbnRmLmV4cGVjdGVkLmhlcmU9XAogICAgaW50ZXJmYWNlIGV4cGVjdGVkIGhlcmUKCmNvbXBpbGVyLmVyci5pbnRmLm1ldGguY2FudC5oYXZlLmJvZHk9XAogICAgaW50ZXJmYWNlIGFic3RyYWN0IG1ldGhvZHMgY2Fubm90IGhhdmUgYm9keQoKIyAwOiBzeW1ib2wKY29tcGlsZXIuZXJyLmludmFsaWQuYW5ub3RhdGlvbi5tZW1iZXIudHlwZT1cCiAgICBpbnZhbGlkIHR5cGUgZm9yIGVsZW1lbnQgezB9IG9mIGFubm90YXRpb24gdHlwZQoKY29tcGlsZXIuZXJyLmludmFsaWQuYmluYXJ5Lm51bWJlcj1cCiAgICBiaW5hcnkgbnVtYmVycyBtdXN0IGNvbnRhaW4gYXQgbGVhc3Qgb25lIGJpbmFyeSBkaWdpdAoKY29tcGlsZXIuZXJyLmludmFsaWQuaGV4Lm51bWJlcj1cCiAgICBoZXhhZGVjaW1hbCBudW1iZXJzIG11c3QgY29udGFpbiBhdCBsZWFzdCBvbmUgaGV4YWRlY2ltYWwgZGlnaXQKCmNvbXBpbGVyLmVyci5pbnZhbGlkLm1ldGguZGVjbC5yZXQudHlwZS5yZXE9XAogICAgaW52YWxpZCBtZXRob2QgZGVjbGFyYXRpb247IHJldHVybiB0eXBlIHJlcXVpcmVkCgpjb21waWxlci5lcnIudmFyYXJncy5hbmQub2xkLmFycmF5LnN5bnRheD1cCiAgICBsZWdhY3kgYXJyYXkgbm90YXRpb24gbm90IGFsbG93ZWQgb24gdmFyaWFibGUtYXJpdHkgcGFyYW1ldGVyCgpjb21waWxlci5lcnIudmFyYXJncy5hbmQucmVjZWl2ZXIgPVwKICAgIHZhcmFyZ3Mgbm90YXRpb24gbm90IGFsbG93ZWQgb24gcmVjZWl2ZXIgcGFyYW1ldGVyCgpjb21waWxlci5lcnIudmFyYXJncy5tdXN0LmJlLmxhc3QgPVwKICAgIHZhcmFyZ3MgcGFyYW1ldGVyIG11c3QgYmUgdGhlIGxhc3QgcGFyYW1ldGVyCgpjb21waWxlci5lcnIuYXJyYXkuYW5kLnJlY2VpdmVyID1cCiAgICBsZWdhY3kgYXJyYXkgbm90YXRpb24gbm90IGFsbG93ZWQgb24gcmVjZWl2ZXIgcGFyYW1ldGVyCgpjb21waWxlci5lcnIudmFyaWFibGUubm90LmFsbG93ZWQ9XAogICAgdmFyaWFibGUgZGVjbGFyYXRpb24gbm90IGFsbG93ZWQgaGVyZQoKIyAwOiBuYW1lCmNvbXBpbGVyLmVyci5sYWJlbC5hbHJlYWR5LmluLnVzZT1cCiAgICBsYWJlbCB7MH0gYWxyZWFkeSBpbiB1c2UKCiMgMDogc3ltYm9sCmNvbXBpbGVyLmVyci5sb2NhbC52YXIuYWNjZXNzZWQuZnJvbS5pY2xzLm5lZWRzLmZpbmFsPVwKICAgIGxvY2FsIHZhcmlhYmxlIHswfSBpcyBhY2Nlc3NlZCBmcm9tIHdpdGhpbiBpbm5lciBjbGFzczsgbmVlZHMgdG8gYmUgZGVjbGFyZWQgZmluYWwKCmNvbXBpbGVyLmVyci5sb2NhbC5lbnVtPVwKICAgIGVudW0gdHlwZXMgbXVzdCBub3QgYmUgbG9jYWwKCmNvbXBpbGVyLmVyci5jYW5ub3QuY3JlYXRlLmFycmF5LndpdGgudHlwZS5hcmd1bWVudHM9XAogICAgY2Fubm90IGNyZWF0ZSBhcnJheSB3aXRoIHR5cGUgYXJndW1lbnRzCgpjb21waWxlci5lcnIuY2Fubm90LmNyZWF0ZS5hcnJheS53aXRoLmRpYW1vbmQ9XAogICAgY2Fubm90IGNyZWF0ZSBhcnJheSB3aXRoICcnPD4nJwoKY29tcGlsZXIuZXJyLmludmFsaWQubW9kdWxlLmRpcmVjdGl2ZT1cCiAgbW9kdWxlIGRpcmVjdGl2ZSBrZXl3b3JkIG9yICcnfScnIGV4cGVjdGVkCgojCiMgbGltaXRzLiAgV2UgZG9uJ3QgZ2l2ZSB0aGUgbGltaXRzIGluIHRoZSBkaWFnbm9zdGljIGJlY2F1c2Ugd2UgZXhwZWN0CiMgdGhlbSB0byBjaGFuZ2UsIHlldCB3ZSB3YW50IHRvIHVzZSB0aGUgc2FtZSBkaWFnbm9zdGljLiAgVGhlc2UgYXJlIGFsbAojIGRldGVjdGVkIGR1cmluZyBjb2RlIGdlbmVyYXRpb24uCiMKY29tcGlsZXIuZXJyLmxpbWl0LmNvZGU9XAogICAgY29kZSB0b28gbGFyZ2UKCmNvbXBpbGVyLmVyci5saW1pdC5jb2RlLnRvby5sYXJnZS5mb3IudHJ5LnN0bXQ9XAogICAgY29kZSB0b28gbGFyZ2UgZm9yIHRyeSBzdGF0ZW1lbnQKCmNvbXBpbGVyLmVyci5saW1pdC5kaW1lbnNpb25zPVwKICAgIGFycmF5IHR5cGUgaGFzIHRvbyBtYW55IGRpbWVuc2lvbnMKCmNvbXBpbGVyLmVyci5saW1pdC5sb2NhbHM9XAogICAgdG9vIG1hbnkgbG9jYWwgdmFyaWFibGVzCgpjb21waWxlci5lcnIubGltaXQucGFyYW1ldGVycz1cCiAgICB0b28gbWFueSBwYXJhbWV0ZXJzCgpjb21waWxlci5lcnIubGltaXQucG9vbD1cCiAgICB0b28gbWFueSBjb25zdGFudHMKCmNvbXBpbGVyLmVyci5saW1pdC5wb29sLmluLmNsYXNzPVwKICAgIHRvbyBtYW55IGNvbnN0YW50cyBpbiBjbGFzcyB7MH0KCmNvbXBpbGVyLmVyci5saW1pdC5zdGFjaz1cCiAgICBjb2RlIHJlcXVpcmVzIHRvbyBtdWNoIHN0YWNrCgpjb21waWxlci5lcnIubGltaXQuc3RyaW5nPVwKICAgIGNvbnN0YW50IHN0cmluZyB0b28gbG9uZwoKY29tcGlsZXIuZXJyLmxpbWl0LnN0cmluZy5vdmVyZmxvdz1cCiAgICBVVEY4IHJlcHJlc2VudGF0aW9uIGZvciBzdHJpbmcgXCJ7MH0uLi5cIiBpcyB0b28gbG9uZyBmb3IgdGhlIGNvbnN0YW50IHBvb2wKCmNvbXBpbGVyLmVyci5tYWxmb3JtZWQuZnAubGl0PVwKICAgIG1hbGZvcm1lZCBmbG9hdGluZyBwb2ludCBsaXRlcmFsCgpjb21waWxlci5lcnIubWV0aG9kLmRvZXMubm90Lm92ZXJyaWRlLnN1cGVyY2xhc3M9XAogICAgbWV0aG9kIGRvZXMgbm90IG92ZXJyaWRlIG9yIGltcGxlbWVudCBhIG1ldGhvZCBmcm9tIGEgc3VwZXJ0eXBlCgpjb21waWxlci5lcnIubWlzc2luZy5tZXRoLmJvZHkub3IuZGVjbC5hYnN0cmFjdD1cCiAgICBtaXNzaW5nIG1ldGhvZCBib2R5LCBvciBkZWNsYXJlIGFic3RyYWN0Cgpjb21waWxlci5lcnIubWlzc2luZy5yZXQuc3RtdD1cCiAgICBtaXNzaW5nIHJldHVybiBzdGF0ZW1lbnQKCiMgMDogdW51c2VkCmNvbXBpbGVyLm1pc2MubWlzc2luZy5yZXQudmFsPVwKICAgIG1pc3NpbmcgcmV0dXJuIHZhbHVlCgpjb21waWxlci5taXNjLnVuZXhwZWN0ZWQucmV0LnZhbD1cCiAgICB1bmV4cGVjdGVkIHJldHVybiB2YWx1ZQoKIyAwOiBzZXQgb2YgbW9kaWZpZXIKY29tcGlsZXIuZXJyLm1vZC5ub3QuYWxsb3dlZC5oZXJlPVwKICAgIG1vZGlmaWVyIHswfSBub3QgYWxsb3dlZCBoZXJlCgpjb21waWxlci5lcnIuaW50Zi5ub3QuYWxsb3dlZC5oZXJlPVwKICAgIGludGVyZmFjZSBub3QgYWxsb3dlZCBoZXJlCgpjb21waWxlci5lcnIuZW51bXMubXVzdC5iZS5zdGF0aWM9XAogICAgZW51bSBkZWNsYXJhdGlvbnMgYWxsb3dlZCBvbmx5IGluIHN0YXRpYyBjb250ZXh0cwoKIyAwOiBzeW1ib2wsIDE6IHN5bWJvbApjb21waWxlci5lcnIubmFtZS5jbGFzaC5zYW1lLmVyYXN1cmU9XAogICAgbmFtZSBjbGFzaDogezB9IGFuZCB7MX0gaGF2ZSB0aGUgc2FtZSBlcmFzdXJlCgojIDA6IHN5bWJvbCwgMTogc3ltYm9sLCAyOiBzeW1ib2wsIDM6IHN5bWJvbCwgNDogdW51c2VkLCA1OiB1bnVzZWQKY29tcGlsZXIuZXJyLm5hbWUuY2xhc2guc2FtZS5lcmFzdXJlLm5vLm92ZXJyaWRlPVwKICAgIG5hbWUgY2xhc2g6IHswfSBpbiB7MX0gYW5kIHsyfSBpbiB7M30gaGF2ZSB0aGUgc2FtZSBlcmFzdXJlLCB5ZXQgbmVpdGhlciBvdmVycmlkZXMgdGhlIG90aGVyCgojIDA6IHN5bWJvbCwgMTogc3ltYm9sLCAyOiBzeW1ib2wsIDM6IHN5bWJvbCwgNDogc3ltYm9sLCA1OiBzeW1ib2wKY29tcGlsZXIuZXJyLm5hbWUuY2xhc2guc2FtZS5lcmFzdXJlLm5vLm92ZXJyaWRlLjE9XAogICAgbmFtZSBjbGFzaDogezB9IGluIHsxfSBvdmVycmlkZXMgYSBtZXRob2Qgd2hvc2UgZXJhc3VyZSBpcyB0aGUgc2FtZSBhcyBhbm90aGVyIG1ldGhvZCwgeWV0IG5laXRoZXIgb3ZlcnJpZGVzIHRoZSBvdGhlclxuXAogICAgZmlyc3QgbWV0aG9kOiAgezJ9IGluIHszfVxuXAogICAgc2Vjb25kIG1ldGhvZDogezR9IGluIHs1fQoKIyAwOiBzeW1ib2wsIDE6IHN5bWJvbCwgMjogc3ltYm9sLCAzOiBzeW1ib2wKY29tcGlsZXIuZXJyLm5hbWUuY2xhc2guc2FtZS5lcmFzdXJlLm5vLmhpZGU9XAogICAgbmFtZSBjbGFzaDogezB9IGluIHsxfSBhbmQgezJ9IGluIHszfSBoYXZlIHRoZSBzYW1lIGVyYXN1cmUsIHlldCBuZWl0aGVyIGhpZGVzIHRoZSBvdGhlcgoKY29tcGlsZXIuZXJyLm5hbWUucmVzZXJ2ZWQuZm9yLmludGVybmFsLnVzZT1cCiAgICB7MH0gaXMgcmVzZXJ2ZWQgZm9yIGludGVybmFsIHVzZQoKY29tcGlsZXIuZXJyLm5hdGl2ZS5tZXRoLmNhbnQuaGF2ZS5ib2R5PVwKICAgIG5hdGl2ZSBtZXRob2RzIGNhbm5vdCBoYXZlIGEgYm9keQoKIyAwOiB0eXBlLCAxOiB0eXBlCmNvbXBpbGVyLmVyci5uZWl0aGVyLmNvbmRpdGlvbmFsLnN1YnR5cGU9XAogICAgaW5jb21wYXRpYmxlIHR5cGVzIGZvciA/OiBuZWl0aGVyIGlzIGEgc3VidHlwZSBvZiB0aGUgb3RoZXJcblwKICAgIHNlY29uZCBvcGVyYW5kOiB7MH1cblwKICAgIHRoaXJkIG9wZXJhbmQgOiB7MX0KCgojIDA6IG1lc3NhZ2Ugc2VnbWVudApjb21waWxlci5taXNjLmluY29tcGF0aWJsZS50eXBlLmluLmNvbmRpdGlvbmFsPVwKICAgIGJhZCB0eXBlIGluIGNvbmRpdGlvbmFsIGV4cHJlc3Npb25cblwKICAgIHswfQoKY29tcGlsZXIubWlzYy5jb25kaXRpb25hbC50YXJnZXQuY2FudC5iZS52b2lkPVwKICAgIHRhcmdldC10eXBlIGZvciBjb25kaXRpb25hbCBleHByZXNzaW9uIGNhbm5vdCBiZSB2b2lkCgojIDA6IHR5cGUKY29tcGlsZXIubWlzYy5pbmNvbXBhdGlibGUucmV0LnR5cGUuaW4ubGFtYmRhPVwKICAgIGJhZCByZXR1cm4gdHlwZSBpbiBsYW1iZGEgZXhwcmVzc2lvblxuXAogICAgezB9Cgpjb21waWxlci5taXNjLnN0YXQuZXhwci5leHBlY3RlZD1cCiAgICBsYW1iZGEgYm9keSBpcyBub3QgY29tcGF0aWJsZSB3aXRoIGEgdm9pZCBmdW5jdGlvbmFsIGludGVyZmFjZVxuXAogICAgKGNvbnNpZGVyIHVzaW5nIGEgYmxvY2sgbGFtYmRhIGJvZHksIG9yIHVzZSBhIHN0YXRlbWVudCBleHByZXNzaW9uIGluc3RlYWQpCgojIDA6IHR5cGUKY29tcGlsZXIubWlzYy5pbmNvbXBhdGlibGUucmV0LnR5cGUuaW4ubXJlZj1cCiAgICBiYWQgcmV0dXJuIHR5cGUgaW4gbWV0aG9kIHJlZmVyZW5jZVxuXAogICAgezB9Cgpjb21waWxlci5lcnIubGFtYmRhLmJvZHkubmVpdGhlci52YWx1ZS5ub3Iudm9pZC5jb21wYXRpYmxlPVwKICAgIGxhbWJkYSBib2R5IGlzIG5laXRoZXIgdmFsdWUgbm9yIHZvaWQgY29tcGF0aWJsZQoKIyAwOiBsaXN0IG9mIHR5cGUKY29tcGlsZXIuZXJyLmluY29tcGF0aWJsZS50aHJvd24udHlwZXMuaW4ubXJlZj1cCiAgICBpbmNvbXBhdGlibGUgdGhyb3duIHR5cGVzIHswfSBpbiBtZXRob2QgcmVmZXJlbmNlCgpjb21waWxlci5taXNjLmluY29tcGF0aWJsZS5hcmcudHlwZXMuaW4ubGFtYmRhPVwKICAgIGluY29tcGF0aWJsZSBwYXJhbWV0ZXIgdHlwZXMgaW4gbGFtYmRhIGV4cHJlc3Npb24KCmNvbXBpbGVyLm1pc2MuaW5jb21wYXRpYmxlLmFyZy50eXBlcy5pbi5tcmVmPVwKICAgIGluY29tcGF0aWJsZSBwYXJhbWV0ZXIgdHlwZXMgaW4gbWV0aG9kIHJlZmVyZW5jZQoKY29tcGlsZXIuZXJyLm5ldy5ub3QuYWxsb3dlZC5pbi5hbm5vdGF0aW9uPVwKICAgICcnbmV3Jycgbm90IGFsbG93ZWQgaW4gYW4gYW5ub3RhdGlvbgoKY29tcGlsZXIuZXJyLm5vLmFubm90YXRpb24ubWVtYmVyPVwKICAgIG5vIGFubm90YXRpb24gbWVtYmVyIHswfSBpbiB7MX0KCmNvbXBpbGVyLmVyci5uby5lbmNsLmluc3RhbmNlLm9mLnR5cGUuaW4uc2NvcGU9XAogICAgbm8gZW5jbG9zaW5nIGluc3RhbmNlIG9mIHR5cGUgezB9IGlzIGluIHNjb3BlCgpjb21waWxlci5lcnIubm8uaW50Zi5leHBlY3RlZC5oZXJlPVwKICAgIG5vIGludGVyZmFjZSBleHBlY3RlZCBoZXJlCgpjb21waWxlci5lcnIubm8ubWF0Y2guZW50cnk9XAogICAgezB9IGhhcyBubyBtYXRjaCBpbiBlbnRyeSBpbiB7MX07IHJlcXVpcmVkIHsyfQoKY29tcGlsZXIuZXJyLm5vdC5hbm5vdGF0aW9uLnR5cGU9XAogICAgezB9IGlzIG5vdCBhbiBhbm5vdGF0aW9uIHR5cGUKCiMgMDogc3ltYm9sLCAxOiBzeW1ib2wsIDI6IG1lc3NhZ2Ugc2VnbWVudApjb21waWxlci5lcnIubm90LmRlZi5hY2Nlc3MucGFja2FnZS5jYW50LmFjY2Vzcz1cCiAgICB7MH0gaXMgbm90IHZpc2libGVcblwKICAgICh7Mn0pCgojIDA6IHN5bWJvbCwgMTogc3ltYm9sLCAyOiBtZXNzYWdlIHNlZ21lbnQKY29tcGlsZXIubWlzYy5ub3QuZGVmLmFjY2Vzcy5wYWNrYWdlLmNhbnQuYWNjZXNzPVwKICAgIHswfSBpcyBub3QgdmlzaWJsZVxuXAogICAgKHsyfSkKCiMgMDogc3ltYm9sLCAxOiBtZXNzYWdlIHNlZ21lbnQKY29tcGlsZXIuZXJyLnBhY2thZ2Uubm90LnZpc2libGU9XAogICAgcGFja2FnZSB7MH0gaXMgbm90IHZpc2libGVcblwKICAgICh7MX0pCgojIDA6IHN5bWJvbCwgMTogbWVzc2FnZSBzZWdtZW50CmNvbXBpbGVyLm1pc2MucGFja2FnZS5ub3QudmlzaWJsZT1cCiAgICBwYWNrYWdlIHswfSBpcyBub3QgdmlzaWJsZVxuXAogICAgKHsxfSkKCiMgezB9IC0gY3VycmVudCBtb2R1bGUKIyB7MX0gLSBwYWNrYWdlIGluIHdoaWNoIHRoZSBpbnZpc2libGUgY2xhc3MgaXMgZGVjbGFyZWQKIyB7Mn0gLSBtb2R1bGUgaW4gd2hpY2ggezF9IGlzIGRlY2xhcmVkCiMgMDogc3ltYm9sLCAxOiBzeW1ib2wsIDI6IHN5bWJvbApjb21waWxlci5taXNjLm5vdC5kZWYuYWNjZXNzLmRvZXMubm90LnJlYWQ9XAogICAgcGFja2FnZSB7MX0gaXMgZGVjbGFyZWQgaW4gbW9kdWxlIHsyfSwgYnV0IG1vZHVsZSB7MH0gZG9lcyBub3QgcmVhZCBpdAoKIyB7MH0gLSBwYWNrYWdlIGluIHdoaWNoIHRoZSBpbnZpc2libGUgY2xhc3MgaXMgZGVjbGFyZWQKIyB7MX0gLSBtb2R1bGUgaW4gd2hpY2ggezB9IGlzIGRlY2xhcmVkCiMgMDogc3ltYm9sLCAxOiBzeW1ib2wKY29tcGlsZXIubWlzYy5ub3QuZGVmLmFjY2Vzcy5kb2VzLm5vdC5yZWFkLmZyb20udW5uYW1lZD1cCiAgICBwYWNrYWdlIHswfSBpcyBkZWNsYXJlZCBpbiBtb2R1bGUgezF9LCB3aGljaCBpcyBub3QgaW4gdGhlIG1vZHVsZSBncmFwaAoKIyB7MH0gLSBwYWNrYWdlIGluIHdoaWNoIHRoZSBpbnZpc2libGUgY2xhc3MgaXMgZGVjbGFyZWQKIyB7MX0gLSBjdXJyZW50IG1vZHVsZQojIDA6IHN5bWJvbCwgMTogc3ltYm9sCmNvbXBpbGVyLm1pc2Mubm90LmRlZi5hY2Nlc3MuZG9lcy5ub3QucmVhZC51bm5hbWVkPVwKICAgIHBhY2thZ2UgezB9IGlzIGRlY2xhcmVkIGluIHRoZSB1bm5hbWVkIG1vZHVsZSwgYnV0IG1vZHVsZSB7MH0gZG9lcyBub3QgcmVhZCBpdAoKIyB7MH0gLSBwYWNrYWdlIGluIHdoaWNoIHRoZSBpbnZpc2libGUgY2xhc3MgaXMgZGVjbGFyZWQKIyB7MX0gLSBtb2R1bGUgaW4gd2hpY2ggezB9IGlzIGRlY2xhcmVkCiMgMDogc3ltYm9sLCAxOiBzeW1ib2wKY29tcGlsZXIubWlzYy5ub3QuZGVmLmFjY2Vzcy5ub3QuZXhwb3J0ZWQ9XAogICAgcGFja2FnZSB7MH0gaXMgZGVjbGFyZWQgaW4gbW9kdWxlIHsxfSwgd2hpY2ggZG9lcyBub3QgZXhwb3J0IGl0CgojIHswfSAtIHBhY2thZ2UgaW4gd2hpY2ggdGhlIGludmlzaWJsZSBjbGFzcyBpcyBkZWNsYXJlZAojIHsxfSAtIG1vZHVsZSBpbiB3aGljaCB7MH0gaXMgZGVjbGFyZWQKIyAwOiBzeW1ib2wsIDE6IHN5bWJvbApjb21waWxlci5taXNjLm5vdC5kZWYuYWNjZXNzLm5vdC5leHBvcnRlZC5mcm9tLnVubmFtZWQ9XAogICAgcGFja2FnZSB7MH0gaXMgZGVjbGFyZWQgaW4gbW9kdWxlIHsxfSwgd2hpY2ggZG9lcyBub3QgZXhwb3J0IGl0CgojIHswfSAtIHBhY2thZ2UgaW4gd2hpY2ggdGhlIGludmlzaWJsZSBjbGFzcyBpcyBkZWNsYXJlZAojIHsxfSAtIG1vZHVsZSBpbiB3aGljaCB7MH0gaXMgZGVjbGFyZWQKIyB7Mn0gLSBjdXJyZW50IG1vZHVsZQojIDA6IHN5bWJvbCwgMTogc3ltYm9sLCAyOiBzeW1ib2wKY29tcGlsZXIubWlzYy5ub3QuZGVmLmFjY2Vzcy5ub3QuZXhwb3J0ZWQudG8ubW9kdWxlPVwKICAgIHBhY2thZ2UgezB9IGlzIGRlY2xhcmVkIGluIG1vZHVsZSB7MX0sIHdoaWNoIGRvZXMgbm90IGV4cG9ydCBpdCB0byBtb2R1bGUgezJ9CgojIHswfSAtIHBhY2thZ2UgaW4gd2hpY2ggdGhlIGludmlzaWJsZSBjbGFzcyBpcyBkZWNsYXJlZAojIHsxfSAtIG1vZHVsZSBpbiB3aGljaCB7MH0gaXMgZGVjbGFyZWQKIyAwOiBzeW1ib2wsIDE6IHN5bWJvbApjb21waWxlci5taXNjLm5vdC5kZWYuYWNjZXNzLm5vdC5leHBvcnRlZC50by5tb2R1bGUuZnJvbS51bm5hbWVkPVwKICAgIHBhY2thZ2UgezB9IGlzIGRlY2xhcmVkIGluIG1vZHVsZSB7MX0sIHdoaWNoIGRvZXMgbm90IGV4cG9ydCBpdCB0byB0aGUgdW5uYW1lZCBtb2R1bGUKCiMgMDogc3ltYm9sLCAxOiBzeW1ib2wKY29tcGlsZXIuZXJyLm5vdC5kZWYuYWNjZXNzLmNsYXNzLmludGYuY2FudC5hY2Nlc3M9XAogICAgezF9LnswfSBpcyBkZWZpbmVkIGluIGFuIGluYWNjZXNzaWJsZSBjbGFzcyBvciBpbnRlcmZhY2UKCiMgMDogc3ltYm9sLCAxOiBzeW1ib2wKY29tcGlsZXIubWlzYy5ub3QuZGVmLmFjY2Vzcy5jbGFzcy5pbnRmLmNhbnQuYWNjZXNzPVwKICAgIHsxfS57MH0gaXMgZGVmaW5lZCBpbiBhbiBpbmFjY2Vzc2libGUgY2xhc3Mgb3IgaW50ZXJmYWNlCgojIDA6IHN5bWJvbCwgMTogc3ltYm9sLCAyOiBzeW1ib2wsIDM6IG1lc3NhZ2Ugc2VnbWVudApjb21waWxlci5lcnIubm90LmRlZi5hY2Nlc3MuY2xhc3MuaW50Zi5jYW50LmFjY2Vzcy5yZWFzb249XAogICAgezF9LnswfSBpbiBwYWNrYWdlIHsyfSBpcyBub3QgYWNjZXNzaWJsZVxuXAogICAgKHszfSkKCiMgMDogc3ltYm9sLCAxOiBzeW1ib2wsIDI6IHN5bWJvbCwgMzogbWVzc2FnZSBzZWdtZW50CmNvbXBpbGVyLm1pc2Mubm90LmRlZi5hY2Nlc3MuY2xhc3MuaW50Zi5jYW50LmFjY2Vzcy5yZWFzb249XAogICAgezF9LnswfSBpbiBwYWNrYWdlIHsyfSBpcyBub3QgYWNjZXNzaWJsZVxuXAogICAgKHszfSkKCiMgMDogc3ltYm9sLCAxOiBsaXN0IG9mIHR5cGUsIDI6IHR5cGUKY29tcGlsZXIubWlzYy5jYW50LmFjY2Vzcy5pbm5lci5jbHMuY29uc3RyPVwKICAgIGNhbm5vdCBhY2Nlc3MgY29uc3RydWN0b3IgezB9KHsxfSlcblwKICAgIGFuIGVuY2xvc2luZyBpbnN0YW5jZSBvZiB0eXBlIHsyfSBpcyBub3QgaW4gc2NvcGUKCiMgMDogc3ltYm9sLCAxOiBzeW1ib2wKY29tcGlsZXIuZXJyLm5vdC5kZWYucHVibGljLmNhbnQuYWNjZXNzPVwKICAgIHswfSBpcyBub3QgcHVibGljIGluIHsxfTsgY2Fubm90IGJlIGFjY2Vzc2VkIGZyb20gb3V0c2lkZSBwYWNrYWdlCgojIDA6IHN5bWJvbCwgMTogc3ltYm9sCmNvbXBpbGVyLmVyci5ub3QuZGVmLnB1YmxpYz1cCiAgICB7MH0gaXMgbm90IHB1YmxpYyBpbiB7MX0KCiMgMDogc3ltYm9sLCAxOiBzeW1ib2wKY29tcGlsZXIubWlzYy5ub3QuZGVmLnB1YmxpYy5jYW50LmFjY2Vzcz1cCiAgICB7MH0gaXMgbm90IHB1YmxpYyBpbiB7MX07IGNhbm5vdCBiZSBhY2Nlc3NlZCBmcm9tIG91dHNpZGUgcGFja2FnZQoKIyAwOiBuYW1lCmNvbXBpbGVyLmVyci5ub3QubG9vcC5sYWJlbD1cCiAgICBub3QgYSBsb29wIGxhYmVsOiB7MH0KCmNvbXBpbGVyLmVyci5ub3Quc3RtdD1cCiAgICBub3QgYSBzdGF0ZW1lbnQKCiMgMDogc3ltYm9sCmNvbXBpbGVyLmVyci5ub3QuZW5jbC5jbGFzcz1cCiAgICBub3QgYW4gZW5jbG9zaW5nIGNsYXNzOiB7MH0KCiMgMDogbmFtZSwgMTogdHlwZQpjb21waWxlci5lcnIub3BlcmF0b3IuY2FudC5iZS5hcHBsaWVkPVwKICAgIGJhZCBvcGVyYW5kIHR5cGUgezF9IGZvciB1bmFyeSBvcGVyYXRvciAnJ3swfScnCgojIDA6IG5hbWUsIDE6IHR5cGUsIDI6IHR5cGUKY29tcGlsZXIuZXJyLm9wZXJhdG9yLmNhbnQuYmUuYXBwbGllZC4xPVwKICAgIGJhZCBvcGVyYW5kIHR5cGVzIGZvciBiaW5hcnkgb3BlcmF0b3IgJyd7MH0nJ1xuXAogICAgZmlyc3QgdHlwZTogIHsxfVxuXAogICAgc2Vjb25kIHR5cGU6IHsyfQoKY29tcGlsZXIuZXJyLnBrZy5hbm5vdGF0aW9ucy5zYi5pbi5wYWNrYWdlLWluZm8uamF2YT1cCiAgICBwYWNrYWdlIGFubm90YXRpb25zIHNob3VsZCBiZSBpbiBmaWxlIHBhY2thZ2UtaW5mby5qYXZhCgpjb21waWxlci5lcnIubm8ucGtnLmluLm1vZHVsZS1pbmZvLmphdmE9XAogICAgcGFja2FnZSBjbGF1c2VzIHNob3VsZCBub3QgYmUgaW4gZmlsZSBtb2R1bGUtaW5mby5qYXZhCgojIDA6IHN5bWJvbApjb21waWxlci5lcnIucGtnLmNsYXNoZXMud2l0aC5jbGFzcy5vZi5zYW1lLm5hbWU9XAogICAgcGFja2FnZSB7MH0gY2xhc2hlcyB3aXRoIGNsYXNzIG9mIHNhbWUgbmFtZQoKY29tcGlsZXIuZXJyLndhcm5pbmdzLmFuZC53ZXJyb3I9XAogICAgd2FybmluZ3MgZm91bmQgYW5kIC1XZXJyb3Igc3BlY2lmaWVkCgojIEVycm9ycyByZWxhdGVkIHRvIGFubm90YXRpb24gcHJvY2Vzc2luZwoKIyAwOiBzeW1ib2wsIDE6IHN0cmluZywgMjogc3RyaW5nIChzdGFjay10cmFjZSkKY29tcGlsZXIuZXJyLnByb2MuY2FudC5hY2Nlc3M9XAogICAgY2Fubm90IGFjY2VzcyB7MH1cblwKICAgIHsxfVxuXAogICAgQ29uc3VsdCB0aGUgZm9sbG93aW5nIHN0YWNrIHRyYWNlIGZvciBkZXRhaWxzLlxuXAogICAgezJ9CgojIDA6IHN5bWJvbCwgMTogc3RyaW5nCmNvbXBpbGVyLmVyci5wcm9jLmNhbnQuYWNjZXNzLjE9XAogICAgY2Fubm90IGFjY2VzcyB7MH1cblwKICAgIHsxfQoKIyAwOiBzdHJpbmcKY29tcGlsZXIuZXJyLnByb2MuY2FudC5maW5kLmNsYXNzPVwKICAgIENvdWxkIG5vdCBmaW5kIGNsYXNzIGZpbGUgZm9yICcnezB9JycuCgojIFByaW50IGEgY2xpZW50LWdlbmVyYXRlZCBlcnJvciBtZXNzYWdlOyBhc3N1bWVkIHRvIGJlIGxvY2FsaXplZCwgbm8gdHJhbnNsYXRpb24gcmVxdWlyZWQKIyAwOiBzdHJpbmcKY29tcGlsZXIuZXJyLnByb2MubWVzc2FnZXI9XAogICAgezB9CgojIDA6IGxpc3Qgb2Ygc3RyaW5nCmNvbXBpbGVyLmVyci5wcm9jLm5vLmV4cGxpY2l0LmFubm90YXRpb24ucHJvY2Vzc2luZy5yZXF1ZXN0ZWQ9XAogICAgQ2xhc3MgbmFtZXMsICcnezB9JycsIGFyZSBvbmx5IGFjY2VwdGVkIGlmIGFubm90YXRpb24gcHJvY2Vzc2luZyBpcyBleHBsaWNpdGx5IHJlcXVlc3RlZAoKY29tcGlsZXIuZXJyLnByb2Mubm8uc2VydmljZT1cCiAgICBBIFNlcnZpY2VMb2FkZXIgd2FzIG5vdCB1c2FibGUgYW5kIGlzIHJlcXVpcmVkIGZvciBhbm5vdGF0aW9uIHByb2Nlc3NpbmcuCgpjb21waWxlci5lcnIucHJvYy5wcm9jZXNzb3IuYmFkLm9wdGlvbi5uYW1lPVwKICAgIEJhZCBvcHRpb24gbmFtZSAnJ3swfScnIHByb3ZpZGVkIGJ5IHByb2Nlc3NvciAnJ3sxfScnCgojIDA6IHN0cmluZwpjb21waWxlci5lcnIucHJvYy5wcm9jZXNzb3IuY2FudC5pbnN0YW50aWF0ZT1cCiAgICBDb3VsZCBub3QgaW5zdGFudGlhdGUgYW4gaW5zdGFuY2Ugb2YgcHJvY2Vzc29yICcnezB9JycKCiMgMDogc3RyaW5nCmNvbXBpbGVyLmVyci5wcm9jLnByb2Nlc3Nvci5ub3QuZm91bmQ9XAogICAgQW5ub3RhdGlvbiBwcm9jZXNzb3IgJyd7MH0nJyBub3QgZm91bmQKCiMgMDogc3RyaW5nCmNvbXBpbGVyLmVyci5wcm9jLnByb2Nlc3Nvci53cm9uZy50eXBlPVwKICAgIEFubm90YXRpb24gcHJvY2Vzc29yICcnezB9JycgZG9lcyBub3QgaW1wbGVtZW50IGphdmF4LmFubm90YXRpb24ucHJvY2Vzc2luZy5Qcm9jZXNzb3IKCmNvbXBpbGVyLmVyci5wcm9jLnNlcnZpY2UucHJvYmxlbT1cCiAgICBFcnJvciBjcmVhdGluZyBhIHNlcnZpY2UgbG9hZGVyIHRvIGxvYWQgUHJvY2Vzc29ycy4KCmNvbXBpbGVyLmVyci5wcm9jLmJhZC5jb25maWcuZmlsZT1cCiAgICBCYWQgc2VydmljZSBjb25maWd1cmF0aW9uIGZpbGUsIG9yIGV4Y2VwdGlvbiB0aHJvd24gd2hpbGUgY29uc3RydWN0aW5nIFByb2Nlc3NvciBvYmplY3Q6IHswfQoKY29tcGlsZXIuZXJyLnByb2MuY2FudC5jcmVhdGUubG9hZGVyPVwKICAgIENvdWxkIG5vdCBjcmVhdGUgY2xhc3MgbG9hZGVyIGZvciBhbm5vdGF0aW9uIHByb2Nlc3NvcnM6IHswfQoKIyAwOiB1bnVzZWQKY29tcGlsZXIuZXJyLnF1YWxpZmllZC5uZXcub2Yuc3RhdGljLmNsYXNzPVwKICAgIHF1YWxpZmllZCBuZXcgb2Ygc3RhdGljIGNsYXNzCgpjb21waWxlci5lcnIucmVjdXJzaXZlLmN0b3IuaW52b2NhdGlvbj1cCiAgICByZWN1cnNpdmUgY29uc3RydWN0b3IgaW52b2NhdGlvbgoKIyAwOiBuYW1lLCAxOiBzeW1ib2wga2luZCwgMjogc3ltYm9sLCAzOiBzeW1ib2wsIDQ6IHN5bWJvbCBraW5kLCA1OiBzeW1ib2wsIDY6IHN5bWJvbApjb21waWxlci5lcnIucmVmLmFtYmlndW91cz1cCiAgICByZWZlcmVuY2UgdG8gezB9IGlzIGFtYmlndW91c1xuXAogICAgYm90aCB7MX0gezJ9IGluIHszfSBhbmQgezR9IHs1fSBpbiB7Nn0gbWF0Y2gKCiMgMDogbmFtZSwgMTogc3ltYm9sIGtpbmQsIDI6IHN5bWJvbCwgMzogc3ltYm9sLCA0OiBzeW1ib2wga2luZCwgNTogc3ltYm9sLCA2OiBzeW1ib2wKY29tcGlsZXIubWlzYy5yZWYuYW1iaWd1b3VzPVwKICAgIHJlZmVyZW5jZSB0byB7MH0gaXMgYW1iaWd1b3VzXG5cCiAgICBib3RoIHsxfSB7Mn0gaW4gezN9IGFuZCB7NH0gezV9IGluIHs2fSBtYXRjaAoKY29tcGlsZXIuZXJyLnJlcGVhdGVkLmFubm90YXRpb24udGFyZ2V0PVwKICAgIHJlcGVhdGVkIGFubm90YXRpb24gdGFyZ2V0Cgpjb21waWxlci5lcnIucmVwZWF0ZWQuaW50ZXJmYWNlPVwKICAgIHJlcGVhdGVkIGludGVyZmFjZQoKY29tcGlsZXIuZXJyLnJlcGVhdGVkLm1vZGlmaWVyPVwKICAgIHJlcGVhdGVkIG1vZGlmaWVyCgojIDA6IHN5bWJvbCwgMTogc2V0IG9mIG1vZGlmaWVyLCAyOiBzeW1ib2wKY29tcGlsZXIuZXJyLnJlcG9ydC5hY2Nlc3M9XAogICAgezB9IGhhcyB7MX0gYWNjZXNzIGluIHsyfQoKIyAwOiBzeW1ib2wsIDE6IHNldCBvZiBtb2RpZmllciwgMjogc3ltYm9sCmNvbXBpbGVyLm1pc2MucmVwb3J0LmFjY2Vzcz1cCiAgICB7MH0gaGFzIHsxfSBhY2Nlc3MgaW4gezJ9Cgpjb21waWxlci5lcnIucmV0Lm91dHNpZGUubWV0aD1cCiAgICByZXR1cm4gb3V0c2lkZSBtZXRob2QKCmNvbXBpbGVyLmVyci5zaWduYXR1cmUuZG9lc250Lm1hdGNoLnN1cGVydHlwZT1cCiAgICBzaWduYXR1cmUgZG9lcyBub3QgbWF0Y2ggezB9OyBpbmNvbXBhdGlibGUgc3VwZXJ0eXBlCgpjb21waWxlci5lcnIuc2lnbmF0dXJlLmRvZXNudC5tYXRjaC5pbnRmPVwKICAgIHNpZ25hdHVyZSBkb2VzIG5vdCBtYXRjaCB7MH07IGluY29tcGF0aWJsZSBpbnRlcmZhY2VzCgojIDA6IG51bWJlciwgMTogbnVtYmVyCmNvbXBpbGVyLmVyci5tZXRob2QuaW52b2tlZC53aXRoLmluY29ycmVjdC5udW1iZXIuYXJndW1lbnRzPVwKICAgIG1ldGhvZCBpbnZva2VkIHdpdGggaW5jb3JyZWN0IG51bWJlciBvZiBhcmd1bWVudHM7IGV4cGVjdGVkIHswfSwgZm91bmQgezF9CgojIDA6IHN5bWJvbCwgMTogc3ltYm9sLCAyOiBzeW1ib2wKY29tcGlsZXIuZXJyLmRvZXMubm90Lm92ZXJyaWRlLmFic3RyYWN0PVwKICAgIHswfSBpcyBub3QgYWJzdHJhY3QgYW5kIGRvZXMgbm90IG92ZXJyaWRlIGFic3RyYWN0IG1ldGhvZCB7MX0gaW4gezJ9Cgpjb21waWxlci5lcnIuc291cmNlLmNhbnQub3ZlcndyaXRlLmlucHV0LmZpbGU9XAogICAgZXJyb3Igd3JpdGluZyBzb3VyY2U7IGNhbm5vdCBvdmVyd3JpdGUgaW5wdXQgZmlsZSB7MH0KCmNvbXBpbGVyLmVyci5zdGFjay5zaW0uZXJyb3I9XAogICAgSW50ZXJuYWwgZXJyb3I6IHN0YWNrIHNpbSBlcnJvciBvbiB7MH0KCmNvbXBpbGVyLmVyci5zdGF0aWMuaW1wLm9ubHkuY2xhc3Nlcy5hbmQuaW50ZXJmYWNlcz1cCiAgICBzdGF0aWMgaW1wb3J0IG9ubHkgZnJvbSBjbGFzc2VzIGFuZCBpbnRlcmZhY2VzCgpjb21waWxlci5lcnIuc3RyaW5nLmNvbnN0LnJlcT1cCiAgICBjb25zdGFudCBzdHJpbmcgZXhwcmVzc2lvbiByZXF1aXJlZAoKIyAwOiBzeW1ib2wsIDE6IHN5bWJvbApjb21waWxlci5lcnIuc3ludGhldGljLm5hbWUuY29uZmxpY3Q9XAogICAgdGhlIHN5bWJvbCB7MH0gY29uZmxpY3RzIHdpdGggYSBjb21waWxlci1zeW50aGVzaXplZCBzeW1ib2wgaW4gezF9Cgpjb21waWxlci5lcnIudGhyb3dzLm5vdC5hbGxvd2VkLmluLmludGYuYW5ub3RhdGlvbj1cCiAgICB0aHJvd3MgY2xhdXNlIG5vdCBhbGxvd2VkIGluIEBpbnRlcmZhY2UgbWVtYmVycwoKY29tcGlsZXIuZXJyLnRyeS53aXRob3V0LmNhdGNoLm9yLmZpbmFsbHk9XAogICAgJyd0cnknJyB3aXRob3V0ICcnY2F0Y2gnJyBvciAnJ2ZpbmFsbHknJwoKY29tcGlsZXIuZXJyLnRyeS53aXRob3V0LmNhdGNoLmZpbmFsbHkub3IucmVzb3VyY2UuZGVjbHM9XAogICAgJyd0cnknJyB3aXRob3V0ICcnY2F0Y2gnJywgJydmaW5hbGx5Jycgb3IgcmVzb3VyY2UgZGVjbGFyYXRpb25zCgojIDA6IHN5bWJvbApjb21waWxlci5lcnIudHlwZS5kb2VzbnQudGFrZS5wYXJhbXM9XAogICAgdHlwZSB7MH0gZG9lcyBub3QgdGFrZSBwYXJhbWV0ZXJzCgpjb21waWxlci5lcnIudHlwZS52YXIuY2FudC5iZS5kZXJlZj1cCiAgICBjYW5ub3Qgc2VsZWN0IGZyb20gYSB0eXBlIHZhcmlhYmxlCgpjb21waWxlci5lcnIudHlwZS52YXIubWF5Lm5vdC5iZS5mb2xsb3dlZC5ieS5vdGhlci5ib3VuZHM9XAogICAgYSB0eXBlIHZhcmlhYmxlIG1heSBub3QgYmUgZm9sbG93ZWQgYnkgb3RoZXIgYm91bmRzCgpjb21waWxlci5lcnIudHlwZS52YXIubW9yZS50aGFuLm9uY2U9XAogICAgdHlwZSB2YXJpYWJsZSB7MH0gb2NjdXJzIG1vcmUgdGhhbiBvbmNlIGluIHJlc3VsdCB0eXBlIG9mIHsxfTsgY2Fubm90IGJlIGxlZnQgdW5pbnN0YW50aWF0ZWQKCmNvbXBpbGVyLmVyci50eXBlLnZhci5tb3JlLnRoYW4ub25jZS5pbi5yZXN1bHQ9XAogICAgdHlwZSB2YXJpYWJsZSB7MH0gb2NjdXJzIG1vcmUgdGhhbiBvbmNlIGluIHR5cGUgb2YgezF9OyBjYW5ub3QgYmUgbGVmdCB1bmluc3RhbnRpYXRlZAoKIyAwOiB0eXBlLCAxOiB0eXBlLCAyOiBzdHJpbmcKY29tcGlsZXIuZXJyLnR5cGVzLmluY29tcGF0aWJsZS5kaWZmLnJldD1cCiAgICB0eXBlcyB7MH0gYW5kIHsxfSBhcmUgaW5jb21wYXRpYmxlOyBib3RoIGRlZmluZSB7Mn0sIGJ1dCB3aXRoIHVucmVsYXRlZCByZXR1cm4gdHlwZXMKCiMgMDoga2luZCBuYW1lLCAxOiB0eXBlLCAyOiBuYW1lLCAzOiBsaXN0IG9mIHR5cGUsIDQ6IHN5bWJvbCwgNTogc3ltYm9sCmNvbXBpbGVyLmVyci50eXBlcy5pbmNvbXBhdGlibGUudW5yZWxhdGVkLmRlZmF1bHRzPVwKICAgIHswfSB7MX0gaW5oZXJpdHMgdW5yZWxhdGVkIGRlZmF1bHRzIGZvciB7Mn0oezN9KSBmcm9tIHR5cGVzIHs0fSBhbmQgezV9CgojIDA6IGtpbmQgbmFtZSwgMTogdHlwZSwgMjogbmFtZSwgMzogbGlzdCBvZiB0eXBlLCA0OiBzeW1ib2wsIDU6IHN5bWJvbApjb21waWxlci5lcnIudHlwZXMuaW5jb21wYXRpYmxlLmFic3RyYWN0LmRlZmF1bHQ9XAogICAgezB9IHsxfSBpbmhlcml0cyBhYnN0cmFjdCBhbmQgZGVmYXVsdCBmb3IgezJ9KHszfSkgZnJvbSB0eXBlcyB7NH0gYW5kIHs1fQoKIyAwOiBuYW1lLCAxOiBraW5kIG5hbWUsIDI6IHN5bWJvbApjb21waWxlci5lcnIuZGVmYXVsdC5vdmVycmlkZXMub2JqZWN0Lm1lbWJlcj1cCiAgICBkZWZhdWx0IG1ldGhvZCB7MH0gaW4gezF9IHsyfSBvdmVycmlkZXMgYSBtZW1iZXIgb2YgamF2YS5sYW5nLk9iamVjdAoKIyAwOiB0eXBlCmNvbXBpbGVyLmVyci5pbGxlZ2FsLnN0YXRpYy5pbnRmLm1ldGguY2FsbD1cCiAgICBpbGxlZ2FsIHN0YXRpYyBpbnRlcmZhY2UgbWV0aG9kIGNhbGxcblwKICAgIHRoZSByZWNlaXZlciBleHByZXNzaW9uIHNob3VsZCBiZSByZXBsYWNlZCB3aXRoIHRoZSB0eXBlIHF1YWxpZmllciAnJ3swfScnCgojIDA6IHR5cGUsIDE6IG1lc3NhZ2Ugc2VnbWVudApjb21waWxlci5lcnIuaWxsZWdhbC5kZWZhdWx0LnN1cGVyLmNhbGw9XAogICAgYmFkIHR5cGUgcXVhbGlmaWVyIHswfSBpbiBkZWZhdWx0IHN1cGVyIGNhbGxcblwKICAgIHsxfQoKIyAwOiBzeW1ib2wsIDE6IHR5cGUKY29tcGlsZXIubWlzYy5vdmVycmlkZGVuLmRlZmF1bHQ9XAogICAgbWV0aG9kIHswfSBpcyBvdmVycmlkZGVuIGluIHsxfQoKIyAwOiBzeW1ib2wsIDE6IHR5cGUgb3Igc3ltYm9sCmNvbXBpbGVyLm1pc2MucmVkdW5kYW50LnN1cGVydHlwZT1cCiAgICByZWR1bmRhbnQgaW50ZXJmYWNlIHswfSBpcyBleHRlbmRlZCBieSB7MX0KCmNvbXBpbGVyLmVyci51bmNsb3NlZC5jaGFyLmxpdD1cCiAgICB1bmNsb3NlZCBjaGFyYWN0ZXIgbGl0ZXJhbAoKY29tcGlsZXIuZXJyLnVuY2xvc2VkLmNvbW1lbnQ9XAogICAgdW5jbG9zZWQgY29tbWVudAoKY29tcGlsZXIuZXJyLnVuY2xvc2VkLnN0ci5saXQ9XAogICAgdW5jbG9zZWQgc3RyaW5nIGxpdGVyYWwKCiMgMDogbmFtZQpjb21waWxlci5lcnIudW5zdXBwb3J0ZWQuZW5jb2Rpbmc9XAogICAgdW5zdXBwb3J0ZWQgZW5jb2Rpbmc6IHswfQoKY29tcGlsZXIuZXJyLmlvLmV4Y2VwdGlvbj1cCiAgICBlcnJvciByZWFkaW5nIHNvdXJjZSBmaWxlOiB7MH0KCiMgMDogbmFtZQpjb21waWxlci5lcnIudW5kZWYubGFiZWw9XAogICAgdW5kZWZpbmVkIGxhYmVsOiB7MH0KCiMgMDogbWVzc2FnZSBzZWdtZW50LCAxOiB1bnVzZWQKY29tcGlsZXIuZXJyLmNhbnQuYXBwbHkuZGlhbW9uZD1cCiAgICBjYW5ub3QgaW5mZXIgdHlwZSBhcmd1bWVudHMgZm9yIHswfQoKIyAwOiBtZXNzYWdlIHNlZ21lbnQgb3IgdHlwZSwgMTogbWVzc2FnZSBzZWdtZW50CmNvbXBpbGVyLmVyci5jYW50LmFwcGx5LmRpYW1vbmQuMT1cCiAgICBjYW5ub3QgaW5mZXIgdHlwZSBhcmd1bWVudHMgZm9yIHswfVxuXAogICAgcmVhc29uOiB7MX0KCiMgMDogbWVzc2FnZSBzZWdtZW50IG9yIHR5cGUsIDE6IG1lc3NhZ2Ugc2VnbWVudApjb21waWxlci5taXNjLmNhbnQuYXBwbHkuZGlhbW9uZC4xPVwKICAgIGNhbm5vdCBpbmZlciB0eXBlIGFyZ3VtZW50cyBmb3IgezB9XG5cCiAgICByZWFzb246IHsxfQoKY29tcGlsZXIuZXJyLnVucmVhY2hhYmxlLnN0bXQ9XAogICAgdW5yZWFjaGFibGUgc3RhdGVtZW50Cgpjb21waWxlci5lcnIuaW5pdGlhbGl6ZXIubXVzdC5iZS5hYmxlLnRvLmNvbXBsZXRlLm5vcm1hbGx5PVwKICAgIGluaXRpYWxpemVyIG11c3QgYmUgYWJsZSB0byBjb21wbGV0ZSBub3JtYWxseQoKY29tcGlsZXIuZXJyLmluaXRpYWxpemVyLm5vdC5hbGxvd2VkPVwKICAgIGluaXRpYWxpemVycyBub3QgYWxsb3dlZCBpbiBpbnRlcmZhY2VzCgojIDA6IHR5cGUKY29tcGlsZXIuZXJyLnVucmVwb3J0ZWQuZXhjZXB0aW9uLm5lZWQudG8uY2F0Y2gub3IudGhyb3c9XAogICAgdW5yZXBvcnRlZCBleGNlcHRpb24gezB9OyBtdXN0IGJlIGNhdWdodCBvciBkZWNsYXJlZCB0byBiZSB0aHJvd24KCiMgMDogdHlwZQpjb21waWxlci5lcnIudW5yZXBvcnRlZC5leGNlcHRpb24uZGVmYXVsdC5jb25zdHJ1Y3Rvcj1cCiAgICB1bnJlcG9ydGVkIGV4Y2VwdGlvbiB7MH0gaW4gZGVmYXVsdCBjb25zdHJ1Y3RvcgoKIyAwOiB0eXBlLCAxOiBuYW1lCmNvbXBpbGVyLmVyci51bnJlcG9ydGVkLmV4Y2VwdGlvbi5pbXBsaWNpdC5jbG9zZT1cCiAgICB1bnJlcG9ydGVkIGV4Y2VwdGlvbiB7MH07IG11c3QgYmUgY2F1Z2h0IG9yIGRlY2xhcmVkIHRvIGJlIHRocm93blxuXAogICAgZXhjZXB0aW9uIHRocm93biBmcm9tIGltcGxpY2l0IGNhbGwgdG8gY2xvc2UoKSBvbiByZXNvdXJjZSB2YXJpYWJsZSAnJ3sxfScnCgpjb21waWxlci5lcnIudW5zdXBwb3J0ZWQuY3Jvc3MuZnAubGl0PVwKICAgIGhleGFkZWNpbWFsIGZsb2F0aW5nLXBvaW50IGxpdGVyYWxzIGFyZSBub3Qgc3VwcG9ydGVkIG9uIHRoaXMgVk0KCmNvbXBpbGVyLmVyci52b2lkLm5vdC5hbGxvd2VkLmhlcmU9XAogICAgJyd2b2lkJycgdHlwZSBub3QgYWxsb3dlZCBoZXJlCgojIDA6IHN0cmluZwpjb21waWxlci5lcnIud3JvbmcubnVtYmVyLnR5cGUuYXJncz1cCiAgICB3cm9uZyBudW1iZXIgb2YgdHlwZSBhcmd1bWVudHM7IHJlcXVpcmVkIHswfQoKIyAwOiBzeW1ib2wKY29tcGlsZXIuZXJyLnZhci5taWdodC5hbHJlYWR5LmJlLmFzc2lnbmVkPVwKICAgIHZhcmlhYmxlIHswfSBtaWdodCBhbHJlYWR5IGhhdmUgYmVlbiBhc3NpZ25lZAoKIyAwOiBzeW1ib2wKY29tcGlsZXIuZXJyLnZhci5taWdodC5ub3QuaGF2ZS5iZWVuLmluaXRpYWxpemVkPVwKICAgIHZhcmlhYmxlIHswfSBtaWdodCBub3QgaGF2ZSBiZWVuIGluaXRpYWxpemVkCgojIDA6IHN5bWJvbApjb21waWxlci5lcnIudmFyLm5vdC5pbml0aWFsaXplZC5pbi5kZWZhdWx0LmNvbnN0cnVjdG9yPVwKICAgIHZhcmlhYmxlIHswfSBub3QgaW5pdGlhbGl6ZWQgaW4gdGhlIGRlZmF1bHQgY29uc3RydWN0b3IKCiMgMDogc3ltYm9sCmNvbXBpbGVyLmVyci52YXIubWlnaHQuYmUuYXNzaWduZWQuaW4ubG9vcD1cCiAgICB2YXJpYWJsZSB7MH0gbWlnaHQgYmUgYXNzaWduZWQgaW4gbG9vcAoKIyAwOiBzeW1ib2wsIDE6IG1lc3NhZ2Ugc2VnbWVudApjb21waWxlci5lcnIudmFyYXJncy5pbnZhbGlkLnRydXN0bWUuYW5ubz1cCiAgICBJbnZhbGlkIHswfSBhbm5vdGF0aW9uLiB7MX0KCiMgMDogdHlwZQpjb21waWxlci5taXNjLnZhcmFyZ3MudHJ1c3RtZS5vbi5yZWlmaWFibGUudmFyYXJncz1cCiAgICBWYXJhcmdzIGVsZW1lbnQgdHlwZSB7MH0gaXMgcmVpZmlhYmxlLgoKIyAwOiBzeW1ib2wKY29tcGlsZXIubWlzYy52YXJhcmdzLnRydXN0bWUub24ubm9uLnZhcmFyZ3MubWV0aD1cCiAgICBNZXRob2QgezB9IGlzIG5vdCBhIHZhcmFyZ3MgbWV0aG9kLgoKIyAwOiBzeW1ib2wKY29tcGlsZXIubWlzYy52YXJhcmdzLnRydXN0bWUub24udmlydHVhbC52YXJhcmdzPVwKICAgIEluc3RhbmNlIG1ldGhvZCB7MH0gaXMgbmVpdGhlciBmaW5hbCBub3IgcHJpdmF0ZS4KCiMgMDogc3ltYm9sCmNvbXBpbGVyLm1pc2MudmFyYXJncy50cnVzdG1lLm9uLnZpcnR1YWwudmFyYXJncy5maW5hbC5vbmx5PVwKICAgIEluc3RhbmNlIG1ldGhvZCB7MH0gaXMgbm90IGZpbmFsLgoKIyAwOiB0eXBlLCAxOiBzeW1ib2wga2luZCwgMjogc3ltYm9sCmNvbXBpbGVyLm1pc2MuaW5hY2Nlc3NpYmxlLnZhcmFyZ3MudHlwZT1cCiAgICBmb3JtYWwgdmFyYXJncyBlbGVtZW50IHR5cGUgezB9IGlzIG5vdCBhY2Nlc3NpYmxlIGZyb20gezF9IHsyfQoKIyBJbiB0aGUgZm9sbG93aW5nIHN0cmluZywgezF9IHdpbGwgYWx3YXlzIGJlIHRoZSBkZXRhaWwgbWVzc2FnZSBmcm9tCiMgamF2YS5pby5JT0V4Y2VwdGlvbi4KIyAwOiBzeW1ib2wsIDE6IHN0cmluZwpjb21waWxlci5lcnIuY2xhc3MuY2FudC53cml0ZT1cCiAgICBlcnJvciB3aGlsZSB3cml0aW5nIHswfTogezF9CgojIEluIHRoZSBmb2xsb3dpbmcgc3RyaW5nLCB7MH0gaXMgdGhlIG5hbWUgb2YgdGhlIGNsYXNzIGluIHRoZSBKYXZhIHNvdXJjZS4KIyBJdCByZWFsbHkgc2hvdWxkIGJlIHVzZWQgdHdvIHRpbWVzLi4KIyAwOiBraW5kIG5hbWUsIDE6IG5hbWUKY29tcGlsZXIuZXJyLmNsYXNzLnB1YmxpYy5zaG91bGQuYmUuaW4uZmlsZT1cCiAgICB7MH0gezF9IGlzIHB1YmxpYywgc2hvdWxkIGJlIGRlY2xhcmVkIGluIGEgZmlsZSBuYW1lZCB7MX0uamF2YQoKIyMgQWxsIGVycm9ycyB3aGljaCBkbyBub3QgcmVmZXIgdG8gYSBwYXJ0aWN1bGFyIGxpbmUgaW4gdGhlIHNvdXJjZSBjb2RlIGFyZQojIyBwcmVjZWRlZCBieSB0aGlzIHN0cmluZy4KY29tcGlsZXIuZXJyLmVycm9yPVwKICAgIGVycm9yOlx1MDAyMAoKIyBUaGUgZm9sbG93aW5nIGVycm9yIG1lc3NhZ2VzIGRvIG5vdCByZWZlciB0byBhIGxpbmUgaW4gdGhlIHNvdXJjZSBjb2RlLgpjb21waWxlci5lcnIuY2FudC5yZWFkLmZpbGU9XAogICAgY2Fubm90IHJlYWQ6IHswfQoKIyAwOiBzdHJpbmcKY29tcGlsZXIuZXJyLnBsdWdpbi5ub3QuZm91bmQ9XAogICAgcGx1Zy1pbiBub3QgZm91bmQ6IHswfQoKIyAwOiBwYXRoCmNvbXBpbGVyLndhcm4ubG9jbi51bmtub3duLmZpbGUub24ubW9kdWxlLnBhdGg9XAogICAgdW5rbm93biBmaWxlIG9uIG1vZHVsZSBwYXRoOiB7MH0KCgojIDA6IHBhdGgKY29tcGlsZXIuZXJyLmxvY24uYmFkLm1vZHVsZS1pbmZvPVwKICAgIHByb2JsZW0gcmVhZGluZyBtb2R1bGUtaW5mby5jbGFzcyBpbiB7MH0KCiMgMDogcGF0aApjb21waWxlci5lcnIubG9jbi5jYW50LnJlYWQuZGlyZWN0b3J5PVwKICAgIGNhbm5vdCByZWFkIGRpcmVjdG9yeSB7MH0KCiMgMDogcGF0aApjb21waWxlci5lcnIubG9jbi5jYW50LnJlYWQuZmlsZT1cCiAgICBjYW5ub3QgcmVhZCBmaWxlIHswfQoKIyAwOiBwYXRoCmNvbXBpbGVyLmVyci5sb2NuLmNhbnQuZ2V0Lm1vZHVsZS5uYW1lLmZvci5qYXI9XAogICAgY2Fubm90IGRldGVybWluZSBtb2R1bGUgbmFtZSBmb3IgezB9CgojIDA6IHBhdGgKY29tcGlsZXIuZXJyLm11bHRpLW1vZHVsZS5vdXRkaXIuY2Fubm90LmJlLmV4cGxvZGVkLm1vZHVsZT1cCiAgICBpbiBtdWx0aS1tb2R1bGUgbW9kZSwgdGhlIG91dHB1dCBkaXJlY3RvcnkgY2Fubm90IGJlIGFuIGV4cGxvZGVkIG1vZHVsZTogezB9CgojIDA6IHBhdGgKY29tcGlsZXIud2Fybi5vdXRkaXIuaXMuaW4uZXhwbG9kZWQubW9kdWxlPVwKICAgIHRoZSBvdXRwdXQgZGlyZWN0b3J5IGlzIHdpdGhpbiBhbiBleHBsb2RlZCBtb2R1bGU6IHswfQoKIyAwOiBmaWxlIG9iamVjdApjb21waWxlci5lcnIubG9jbi5tb2R1bGUtaW5mby5ub3QuYWxsb3dlZC5vbi5wYXRjaC5wYXRoPVwKICAgIG1vZHVsZS1pbmZvLmNsYXNzIG5vdCBhbGxvd2VkIG9uIHBhdGNoIHBhdGg6IHswfQoKIyAwOiBzdHJpbmcKY29tcGlsZXIuZXJyLmxvY24uaW52YWxpZC5hcmcuZm9yLnhwYXRjaD1cCiAgICBpbnZhbGlkIGFyZ3VtZW50IGZvciAtLXBhdGNoLW1vZHVsZSBvcHRpb246IHswfQoKIyMjIyMKCiMgRmF0YWwgRXJyb3JzCgpjb21waWxlci5taXNjLmZhdGFsLmVyci5uby5qYXZhLmxhbmc9XAogICAgRmF0YWwgRXJyb3I6IFVuYWJsZSB0byBmaW5kIHBhY2thZ2UgamF2YS5sYW5nIGluIGNsYXNzcGF0aCBvciBib290Y2xhc3NwYXRoCgpjb21waWxlci5taXNjLmZhdGFsLmVyci5jYW50LmxvY2F0ZS5tZXRoPVwKICAgIEZhdGFsIEVycm9yOiBVbmFibGUgdG8gZmluZCBtZXRob2QgezB9Cgpjb21waWxlci5taXNjLmZhdGFsLmVyci5jYW50LmxvY2F0ZS5maWVsZD1cCiAgICBGYXRhbCBFcnJvcjogVW5hYmxlIHRvIGZpbmQgZmllbGQgezB9Cgpjb21waWxlci5taXNjLmZhdGFsLmVyci5jYW50LmxvY2F0ZS5jdG9yPVwKICAgIEZhdGFsIEVycm9yOiBVbmFibGUgdG8gZmluZCBjb25zdHJ1Y3RvciBmb3IgezB9Cgpjb21waWxlci5taXNjLmZhdGFsLmVyci5jYW50LmNsb3NlPVwKICAgIEZhdGFsIEVycm9yOiBDYW5ub3QgY2xvc2UgY29tcGlsZXIgcmVzb3VyY2VzCgojIyMjIwoKIyMKIyMgbWlzY2VsbGFuZW91cyBzdHJpbmdzCiMjCgpjb21waWxlci5taXNjLmRpYW1vbmQuYW5vbnltb3VzLm1ldGhvZHMuaW1wbGljaXRseS5vdmVycmlkZT1cCiAgICAoZHVlIHRvIDw+LCBldmVyeSBub24tcHJpdmF0ZSBtZXRob2QgZGVjbGFyZWQgaW4gdGhpcyBhbm9ueW1vdXMgY2xhc3MgbXVzdCBvdmVycmlkZSBvciBpbXBsZW1lbnQgYSBtZXRob2QgZnJvbSBhIHN1cGVydHlwZSkKCmNvbXBpbGVyLm1pc2Muc291cmNlLnVuYXZhaWxhYmxlPVwKICAgIChzb3VyY2UgdW5hdmFpbGFibGUpCgpjb21waWxlci5taXNjLmJhc2UubWVtYmVyc2hpcD1cCiAgICBhbGwgeW91ciBiYXNlIGNsYXNzIGFyZSBiZWxvbmcgdG8gdXMKCiMgMDogc3RyaW5nLCAxOiBzdHJpbmcsIDI6IGJvb2xlYW4KY29tcGlsZXIubWlzYy54LnByaW50LnByb2Nlc3Nvci5pbmZvPVwKICAgIFByb2Nlc3NvciB7MH0gbWF0Y2hlcyB7MX0gYW5kIHJldHVybnMgezJ9LgoKIyAwOiBudW1iZXIsIDE6IHN0cmluZywgMjogc2V0IG9mIHN5bWJvbCwgMzogYm9vbGVhbgpjb21waWxlci5taXNjLngucHJpbnQucm91bmRzPVwKICAgIFJvdW5kIHswfTpcblx0aW5wdXQgZmlsZXM6IHsxfVxuXHRhbm5vdGF0aW9uczogezJ9XG5cdGxhc3Qgcm91bmQ6IHszfQoKIyAwOiBmaWxlIG5hbWUKY29tcGlsZXIud2Fybi5maWxlLmZyb20uZnV0dXJlPVwKICAgIE1vZGlmaWNhdGlvbiBkYXRlIGlzIGluIHRoZSBmdXR1cmUgZm9yIGZpbGUgezB9CgojIyMjIwoKIyMgVGhlIGZvbGxvd2luZyBzdHJpbmcgd2lsbCBhcHBlYXIgYmVmb3JlIGFsbCBtZXNzYWdlcyBrZXllZCBhczoKIyMgImNvbXBpbGVyLm5vdGUiLgoKY29tcGlsZXIubm90ZS5jb21wcmVzc2VkLmRpYWdzPVwKICAgIFNvbWUgbWVzc2FnZXMgaGF2ZSBiZWVuIHNpbXBsaWZpZWQ7IHJlY29tcGlsZSB3aXRoIC1YZGlhZ3M6dmVyYm9zZSB0byBnZXQgZnVsbCBvdXRwdXQKCiMgMDogYm9vbGVhbiwgMTogc3ltYm9sCmNvbXBpbGVyLm5vdGUubGFtYmRhLnN0YXQ9XAogICAgVHJhbnNsYXRpbmcgbGFtYmRhIGV4cHJlc3Npb25cblwKICAgIGFsdGVybmF0ZSBtZXRhZmFjdG9yeSA9IHswfVxuXAogICAgc3ludGhldGljIG1ldGhvZCA9IHsxfQoKIyAwOiBib29sZWFuLCAxOiB1bnVzZWQKY29tcGlsZXIubm90ZS5tcmVmLnN0YXQ9XAogICAgVHJhbnNsYXRpbmcgbWV0aG9kIHJlZmVyZW5jZVxuXAogICAgYWx0ZXJuYXRlIG1ldGFmYWN0b3J5ID0gezB9XG5cCgojIDA6IGJvb2xlYW4sIDE6IHN5bWJvbApjb21waWxlci5ub3RlLm1yZWYuc3RhdC4xPVwKICAgIFRyYW5zbGF0aW5nIG1ldGhvZCByZWZlcmVuY2VcblwKICAgIGFsdGVybmF0ZSBtZXRhZmFjdG9yeSA9IHswfVxuXAogICAgYnJpZGdlIG1ldGhvZCA9IHsxfQoKY29tcGlsZXIubm90ZS5ub3RlPVwKICAgIE5vdGU6XHUwMDIwCgojIDA6IGZpbGUgbmFtZQpjb21waWxlci5ub3RlLmRlcHJlY2F0ZWQuZmlsZW5hbWU9XAogICAgezB9IHVzZXMgb3Igb3ZlcnJpZGVzIGEgZGVwcmVjYXRlZCBBUEkuCgpjb21waWxlci5ub3RlLmRlcHJlY2F0ZWQucGx1cmFsPVwKICAgIFNvbWUgaW5wdXQgZmlsZXMgdXNlIG9yIG92ZXJyaWRlIGEgZGVwcmVjYXRlZCBBUEkuCgojIFRoZSBmb2xsb3dpbmcgc3RyaW5nIG1heSBhcHBlYXIgYWZ0ZXIgb25lIG9mIHRoZSBhYm92ZSBkZXByZWNhdGlvbgojIG1lc3NhZ2VzLgpjb21waWxlci5ub3RlLmRlcHJlY2F0ZWQucmVjb21waWxlPVwKICAgIFJlY29tcGlsZSB3aXRoIC1YbGludDpkZXByZWNhdGlvbiBmb3IgZGV0YWlscy4KCiMgMDogZmlsZSBuYW1lCmNvbXBpbGVyLm5vdGUuZGVwcmVjYXRlZC5maWxlbmFtZS5hZGRpdGlvbmFsPVwKICAgIHswfSBoYXMgYWRkaXRpb25hbCB1c2VzIG9yIG92ZXJyaWRlcyBvZiBhIGRlcHJlY2F0ZWQgQVBJLgoKY29tcGlsZXIubm90ZS5kZXByZWNhdGVkLnBsdXJhbC5hZGRpdGlvbmFsPVwKICAgIFNvbWUgaW5wdXQgZmlsZXMgYWRkaXRpb25hbGx5IHVzZSBvciBvdmVycmlkZSBhIGRlcHJlY2F0ZWQgQVBJLgoKIyAwOiBmaWxlIG5hbWUKY29tcGlsZXIubm90ZS5yZW1vdmFsLmZpbGVuYW1lPVwKICAgIHswfSB1c2VzIG9yIG92ZXJyaWRlcyBhIGRlcHJlY2F0ZWQgQVBJIHRoYXQgaXMgbWFya2VkIGZvciByZW1vdmFsLgoKY29tcGlsZXIubm90ZS5yZW1vdmFsLnBsdXJhbD1cCiAgICBTb21lIGlucHV0IGZpbGVzIHVzZSBvciBvdmVycmlkZSBhIGRlcHJlY2F0ZWQgQVBJIHRoYXQgaXMgbWFya2VkIGZvciByZW1vdmFsLgoKIyBUaGUgZm9sbG93aW5nIHN0cmluZyBtYXkgYXBwZWFyIGFmdGVyIG9uZSBvZiB0aGUgYWJvdmUgcmVtb3ZhbCBtZXNzYWdlcy4KY29tcGlsZXIubm90ZS5yZW1vdmFsLnJlY29tcGlsZT1cCiAgICBSZWNvbXBpbGUgd2l0aCAtWGxpbnQ6cmVtb3ZhbCBmb3IgZGV0YWlscy4KCiMgMDogZmlsZSBuYW1lCmNvbXBpbGVyLm5vdGUucmVtb3ZhbC5maWxlbmFtZS5hZGRpdGlvbmFsPVwKICAgIHswfSBoYXMgYWRkaXRpb25hbCB1c2VzIG9yIG92ZXJyaWRlcyBvZiBhIGRlcHJlY2F0ZWQgQVBJIHRoYXQgaXMgbWFya2VkIGZvciByZW1vdmFsLgoKY29tcGlsZXIubm90ZS5yZW1vdmFsLnBsdXJhbC5hZGRpdGlvbmFsPVwKICAgIFNvbWUgaW5wdXQgZmlsZXMgYWRkaXRpb25hbGx5IHVzZSBvciBvdmVycmlkZSBhIGRlcHJlY2F0ZWQgQVBJIHRoYXQgaXMgbWFya2VkIGZvciByZW1vdmFsLgoKIyAwOiBmaWxlIG5hbWUKY29tcGlsZXIubm90ZS51bmNoZWNrZWQuZmlsZW5hbWU9XAogICAgezB9IHVzZXMgdW5jaGVja2VkIG9yIHVuc2FmZSBvcGVyYXRpb25zLgoKY29tcGlsZXIubm90ZS51bmNoZWNrZWQucGx1cmFsPVwKICAgIFNvbWUgaW5wdXQgZmlsZXMgdXNlIHVuY2hlY2tlZCBvciB1bnNhZmUgb3BlcmF0aW9ucy4KCiMgVGhlIGZvbGxvd2luZyBzdHJpbmcgbWF5IGFwcGVhciBhZnRlciBvbmUgb2YgdGhlIGFib3ZlIHVuY2hlY2tlZCBtZXNzYWdlcy4KY29tcGlsZXIubm90ZS51bmNoZWNrZWQucmVjb21waWxlPVwKICAgIFJlY29tcGlsZSB3aXRoIC1YbGludDp1bmNoZWNrZWQgZm9yIGRldGFpbHMuCgojIDA6IGZpbGUgbmFtZQpjb21waWxlci5ub3RlLnVuY2hlY2tlZC5maWxlbmFtZS5hZGRpdGlvbmFsPVwKICAgIHswfSBoYXMgYWRkaXRpb25hbCB1bmNoZWNrZWQgb3IgdW5zYWZlIG9wZXJhdGlvbnMuCgpjb21waWxlci5ub3RlLnVuY2hlY2tlZC5wbHVyYWwuYWRkaXRpb25hbD1cCiAgICBTb21lIGlucHV0IGZpbGVzIGFkZGl0aW9uYWxseSB1c2UgdW5jaGVja2VkIG9yIHVuc2FmZSBvcGVyYXRpb25zLgoKIyBOb3RlcyByZWxhdGVkIHRvIGFubm90YXRpb24gcHJvY2Vzc2luZwoKIyBQcmludCBhIGNsaWVudC1nZW5lcmF0ZWQgbm90ZTsgYXNzdW1lZCB0byBiZSBsb2NhbGl6ZWQsIG5vIHRyYW5zbGF0aW9uIHJlcXVpcmVkCiMgMDogc3RyaW5nCmNvbXBpbGVyLm5vdGUucHJvYy5tZXNzYWdlcj1cCiAgICB7MH0KCiMgMDogc3RyaW5nLCAxOiBzdHJpbmcsIDI6IHN0cmluZwpjb21waWxlci5ub3RlLm11bHRpcGxlLmVsZW1lbnRzPVwKICAgIE11bHRpcGxlIGVsZW1lbnRzIG5hbWVkICcnezF9JycgaW4gbW9kdWxlcyAnJ3syfScnIHdlcmUgZm91bmQgYnkgamF2YXgubGFuZy5tb2RlbC51dGlsLkVsZW1lbnRzLnswfS4KCiMjIyMjCgojIDA6IG51bWJlcgpjb21waWxlci5taXNjLmNvdW50LmVycm9yPVwKICAgIHswfSBlcnJvcgoKIyAwOiBudW1iZXIKY29tcGlsZXIubWlzYy5jb3VudC5lcnJvci5wbHVyYWw9XAogICAgezB9IGVycm9ycwoKIyAwOiBudW1iZXIKY29tcGlsZXIubWlzYy5jb3VudC53YXJuPVwKICAgIHswfSB3YXJuaW5nCgojIDA6IG51bWJlcgpjb21waWxlci5taXNjLmNvdW50Lndhcm4ucGx1cmFsPVwKICAgIHswfSB3YXJuaW5ncwoKY29tcGlsZXIubWlzYy52ZXJzaW9uLm5vdC5hdmFpbGFibGU9XAogICAgKHZlcnNpb24gaW5mbyBub3QgYXZhaWxhYmxlKQoKIyMgZXh0cmEgb3V0cHV0IHdoZW4gdXNpbmcgLXZlcmJvc2UgKEphdmFDb21waWxlcikKCiMgMDogc3ltYm9sCmNvbXBpbGVyLm1pc2MudmVyYm9zZS5jaGVja2luZy5hdHRyaWJ1dGlvbj1cCiAgICBbY2hlY2tpbmcgezB9XQoKIyAwOiBzdHJpbmcKY29tcGlsZXIubWlzYy52ZXJib3NlLnBhcnNpbmcuZG9uZT1cCiAgICBbcGFyc2luZyBjb21wbGV0ZWQgezB9bXNdCgojIDA6IGZpbGUgbmFtZQpjb21waWxlci5taXNjLnZlcmJvc2UucGFyc2luZy5zdGFydGVkPVwKICAgIFtwYXJzaW5nIHN0YXJ0ZWQgezB9XQoKIyAwOiBzdHJpbmcKY29tcGlsZXIubWlzYy52ZXJib3NlLnRvdGFsPVwKICAgIFt0b3RhbCB7MH1tc10KCiMgMDogZmlsZSBuYW1lCmNvbXBpbGVyLm1pc2MudmVyYm9zZS53cm90ZS5maWxlPVwKICAgIFt3cm90ZSB7MH1dCgojIyBleHRyYSBvdXRwdXQgd2hlbiB1c2luZyAtdmVyYm9zZSAoY29kZS9DbGFzc1JlYWRlcikKIyAwOiBzdHJpbmcKY29tcGlsZXIubWlzYy52ZXJib3NlLmxvYWRpbmc9XAogICAgW2xvYWRpbmcgezB9XQoKIyAwOiBzdHJpbmcKY29tcGlsZXIubWlzYy52ZXJib3NlLnNvdXJjZXBhdGg9XAogICAgW3NlYXJjaCBwYXRoIGZvciBzb3VyY2UgZmlsZXM6IHswfV0KCiMgMDogc3RyaW5nCmNvbXBpbGVyLm1pc2MudmVyYm9zZS5jbGFzc3BhdGg9XAogICAgW3NlYXJjaCBwYXRoIGZvciBjbGFzcyBmaWxlczogezB9XQoKIyMgZXh0cmEgb3V0cHV0IHdoZW4gdXNpbmcgLXByb21wdCAodXRpbC9Mb2cpCmNvbXBpbGVyLm1pc2MucmVzdW1lLmFib3J0PVwKICAgIFIpZXN1bWUsIEEpYm9ydD4KCiMjIyMjCgojIwojIyB3YXJuaW5ncwojIwoKIyMgQWxsIHdhcm5pbmcgbWVzc2FnZXMgYXJlIHByZWNlZGVkIGJ5IHRoZSBmb2xsb3dpbmcgc3RyaW5nLgpjb21waWxlci53YXJuLndhcm5pbmc9XAogICAgd2FybmluZzpcdTAwMjAKCiMjIFdhcm5pbmcgbWVzc2FnZXMgbWF5IGFsc28gaW5jbHVkZSB0aGUgZm9sbG93aW5nIHByZWZpeCB0byBpZGVudGlmeSBhCiMjIGxpbnQgb3B0aW9uCiMgMDogb3B0aW9uIG5hbWUKY29tcGlsZXIud2Fybi5saW50T3B0aW9uPVwKICAgIFt7MH1dXHUwMDIwCgojIDA6IHN5bWJvbApjb21waWxlci53YXJuLmNvbnN0YW50LlNWVUlEPVwKICAgIHNlcmlhbFZlcnNpb25VSUQgbXVzdCBiZSBjb25zdGFudCBpbiBjbGFzcyB7MH0KCiMgMDogZmlsZSBuYW1lCmNvbXBpbGVyLndhcm4uZGlyLnBhdGguZWxlbWVudC5ub3QuZm91bmQ9XAogICAgYmFkIHBhdGggZWxlbWVudCAiezB9Ijogbm8gc3VjaCBkaXJlY3RvcnkKCiMgMDogZmlsZSBuYW1lCmNvbXBpbGVyLndhcm4uZGlyLnBhdGguZWxlbWVudC5ub3QuZGlyZWN0b3J5PVwKICAgIGJhZCBwYXRoIGVsZW1lbnQgInswfSI6IG5vdCBhIGRpcmVjdG9yeQoKY29tcGlsZXIud2Fybi5maW5hbGx5LmNhbm5vdC5jb21wbGV0ZT1cCiAgICBmaW5hbGx5IGNsYXVzZSBjYW5ub3QgY29tcGxldGUgbm9ybWFsbHkKCiMgMDogbmFtZQpjb21waWxlci53YXJuLnBvb3IuY2hvaWNlLmZvci5tb2R1bGUubmFtZT1cCiAgICBtb2R1bGUgbmFtZSB7MH0gc2hvdWxkIGF2b2lkIHRlcm1pbmFsIGRpZ2l0cwoKIyAwOiBzdHJpbmcKY29tcGlsZXIud2Fybi5pbmN1YmF0aW5nLm1vZHVsZXM9XAogICAgdXNpbmcgaW5jdWJhdGluZyBtb2R1bGUocyk6IHswfQoKIyAwOiBzeW1ib2wsIDE6IHN5bWJvbApjb21waWxlci53YXJuLmhhcy5iZWVuLmRlcHJlY2F0ZWQ9XAogICAgezB9IGluIHsxfSBoYXMgYmVlbiBkZXByZWNhdGVkCgojIDA6IHN5bWJvbCwgMTogc3ltYm9sCmNvbXBpbGVyLndhcm4uaGFzLmJlZW4uZGVwcmVjYXRlZC5mb3IucmVtb3ZhbD1cCiAgICB7MH0gaW4gezF9IGhhcyBiZWVuIGRlcHJlY2F0ZWQgYW5kIG1hcmtlZCBmb3IgcmVtb3ZhbAoKIyAwOiBzeW1ib2wKY29tcGlsZXIud2Fybi5oYXMuYmVlbi5kZXByZWNhdGVkLm1vZHVsZT1cCiAgICBtb2R1bGUgezB9IGhhcyBiZWVuIGRlcHJlY2F0ZWQKCiMgMDogc3ltYm9sCmNvbXBpbGVyLndhcm4uaGFzLmJlZW4uZGVwcmVjYXRlZC5mb3IucmVtb3ZhbC5tb2R1bGU9XAogICAgbW9kdWxlIHswfSBoYXMgYmVlbiBkZXByZWNhdGVkIGFuZCBtYXJrZWQgZm9yIHJlbW92YWwKCiMgMDogc3ltYm9sCmNvbXBpbGVyLndhcm4uc3VuLnByb3ByaWV0YXJ5PVwKICAgIHswfSBpcyBpbnRlcm5hbCBwcm9wcmlldGFyeSBBUEkgYW5kIG1heSBiZSByZW1vdmVkIGluIGEgZnV0dXJlIHJlbGVhc2UKCmNvbXBpbGVyLndhcm4uaWxsZWdhbC5jaGFyLmZvci5lbmNvZGluZz1cCiAgICB1bm1hcHBhYmxlIGNoYXJhY3RlciBmb3IgZW5jb2RpbmcgezB9CgojIDA6IHN5bWJvbApjb21waWxlci53YXJuLmltcHJvcGVyLlNWVUlEPVwKICAgIHNlcmlhbFZlcnNpb25VSUQgbXVzdCBiZSBkZWNsYXJlZCBzdGF0aWMgZmluYWwgaW4gY2xhc3MgezB9CgojIDA6IHR5cGUsIDE6IHR5cGUKY29tcGlsZXIud2Fybi5pbmV4YWN0Lm5vbi12YXJhcmdzLmNhbGw9XAogICAgbm9uLXZhcmFyZ3MgY2FsbCBvZiB2YXJhcmdzIG1ldGhvZCB3aXRoIGluZXhhY3QgYXJndW1lbnQgdHlwZSBmb3IgbGFzdCBwYXJhbWV0ZXI7XG5cCiAgICBjYXN0IHRvIHswfSBmb3IgYSB2YXJhcmdzIGNhbGxcblwKICAgIGNhc3QgdG8gezF9IGZvciBhIG5vbi12YXJhcmdzIGNhbGwgYW5kIHRvIHN1cHByZXNzIHRoaXMgd2FybmluZwoKIyAwOiBsaXN0IG9mIHR5cGUKY29tcGlsZXIud2Fybi51bnJlYWNoYWJsZS5jYXRjaD1cCiAgICB1bnJlYWNoYWJsZSBjYXRjaCBjbGF1c2VcblwKICAgIHRocm93biB0eXBlIHswfSBoYXMgYWxyZWFkeSBiZWVuIGNhdWdodAoKIyAwOiBsaXN0IG9mIHR5cGUKY29tcGlsZXIud2Fybi51bnJlYWNoYWJsZS5jYXRjaC4xPVwKICAgIHVucmVhY2hhYmxlIGNhdGNoIGNsYXVzZVxuXAogICAgdGhyb3duIHR5cGVzIHswfSBoYXZlIGFscmVhZHkgYmVlbiBjYXVnaHQKCiMgMDogc3ltYm9sCmNvbXBpbGVyLndhcm4ubG9uZy5TVlVJRD1cCiAgICBzZXJpYWxWZXJzaW9uVUlEIG11c3QgYmUgb2YgdHlwZSBsb25nIGluIGNsYXNzIHswfQoKIyAwOiBzeW1ib2wKY29tcGlsZXIud2Fybi5taXNzaW5nLlNWVUlEPVwKICAgIHNlcmlhbGl6YWJsZSBjbGFzcyB7MH0gaGFzIG5vIGRlZmluaXRpb24gb2Ygc2VyaWFsVmVyc2lvblVJRAoKIyAwOiBzeW1ib2wsIDE6IHN5bWJvbCwgMjogc3ltYm9sLCAzOiBzeW1ib2wKY29tcGlsZXIud2Fybi5wb3RlbnRpYWxseS5hbWJpZ3VvdXMub3ZlcmxvYWQ9XAogICAgezB9IGluIHsxfSBpcyBwb3RlbnRpYWxseSBhbWJpZ3VvdXMgd2l0aCB7Mn0gaW4gezN9CgojIDA6IG1lc3NhZ2Ugc2VnbWVudApjb21waWxlci53YXJuLm92ZXJyaWRlLnZhcmFyZ3MubWlzc2luZz1cCiAgICB7MH07IG92ZXJyaWRkZW4gbWV0aG9kIGhhcyBubyAnJy4uLicnCgojIDA6IG1lc3NhZ2Ugc2VnbWVudApjb21waWxlci53YXJuLm92ZXJyaWRlLnZhcmFyZ3MuZXh0cmE9XAogICAgezB9OyBvdmVycmlkaW5nIG1ldGhvZCBpcyBtaXNzaW5nICcnLi4uJycKCmNvbXBpbGVyLndhcm4ub3ZlcnJpZGUuYnJpZGdlPVwKICAgIHswfTsgb3ZlcnJpZGRlbiBtZXRob2QgaXMgYSBicmlkZ2UgbWV0aG9kCgojIDA6IHN5bWJvbApjb21waWxlci53YXJuLnBrZy1pbmZvLmFscmVhZHkuc2Vlbj1cCiAgICBhIHBhY2thZ2UtaW5mby5qYXZhIGZpbGUgaGFzIGFscmVhZHkgYmVlbiBzZWVuIGZvciBwYWNrYWdlIHswfQoKIyAwOiBmaWxlIG5hbWUKY29tcGlsZXIud2Fybi5wYXRoLmVsZW1lbnQubm90LmZvdW5kPVwKICAgIGJhZCBwYXRoIGVsZW1lbnQgInswfSI6IG5vIHN1Y2ggZmlsZSBvciBkaXJlY3RvcnkKCmNvbXBpbGVyLndhcm4ucG9zc2libGUuZmFsbC10aHJvdWdoLmludG8uY2FzZT1cCiAgICBwb3NzaWJsZSBmYWxsLXRocm91Z2ggaW50byBjYXNlCgojIDA6IHR5cGUKY29tcGlsZXIud2Fybi5yZWR1bmRhbnQuY2FzdD1cCiAgICByZWR1bmRhbnQgY2FzdCB0byB7MH0KCiMgMDogbnVtYmVyCmNvbXBpbGVyLndhcm4ucG9zaXRpb24ub3ZlcmZsb3c9XAogICAgUG9zaXRpb24gZW5jb2Rpbmcgb3ZlcmZsb3dzIGF0IGxpbmUgezB9CgojIDA6IGZpbGUgbmFtZSwgMTogbnVtYmVyLCAyOiBudW1iZXIKY29tcGlsZXIud2Fybi5iaWcubWFqb3IudmVyc2lvbj1cCiAgICB7MH06IG1ham9yIHZlcnNpb24gezF9IGlzIG5ld2VyIHRoYW4gezJ9LCB0aGUgaGlnaGVzdCBtYWpvciB2ZXJzaW9uIHN1cHBvcnRlZCBieSB0aGlzIGNvbXBpbGVyLlxuXAogICAgSXQgaXMgcmVjb21tZW5kZWQgdGhhdCB0aGUgY29tcGlsZXIgYmUgdXBncmFkZWQuCgojIDA6IHN5bWJvbCBraW5kLCAxOiBzeW1ib2wKY29tcGlsZXIud2Fybi5zdGF0aWMubm90LnF1YWxpZmllZC5ieS50eXBlPVwKICAgIHN0YXRpYyB7MH0gc2hvdWxkIGJlIHF1YWxpZmllZCBieSB0eXBlIG5hbWUsIHsxfSwgaW5zdGVhZCBvZiBieSBhbiBleHByZXNzaW9uCgojIDA6IHN0cmluZwpjb21waWxlci53YXJuLnNvdXJjZS5uby5ib290Y2xhc3NwYXRoPVwKICAgIGJvb3RzdHJhcCBjbGFzcyBwYXRoIG5vdCBzZXQgaW4gY29uanVuY3Rpb24gd2l0aCAtc291cmNlIHswfQoKIyAwOiBzdHJpbmcKY29tcGlsZXIud2Fybi5vcHRpb24ub2Jzb2xldGUuc291cmNlPVwKICAgIHNvdXJjZSB2YWx1ZSB7MH0gaXMgb2Jzb2xldGUgYW5kIHdpbGwgYmUgcmVtb3ZlZCBpbiBhIGZ1dHVyZSByZWxlYXNlCgojIDA6IHN0cmluZwpjb21waWxlci53YXJuLm9wdGlvbi5vYnNvbGV0ZS50YXJnZXQ9XAogICAgdGFyZ2V0IHZhbHVlIHswfSBpcyBvYnNvbGV0ZSBhbmQgd2lsbCBiZSByZW1vdmVkIGluIGEgZnV0dXJlIHJlbGVhc2UKCiMgMDogc3RyaW5nLCAxOiBzdHJpbmcKY29tcGlsZXIuZXJyLm9wdGlvbi5yZW1vdmVkLnNvdXJjZT1cCiAgICBTb3VyY2Ugb3B0aW9uIHswfSBpcyBubyBsb25nZXIgc3VwcG9ydGVkLiBVc2UgezF9IG9yIGxhdGVyLgoKIyAwOiBzdHJpbmcsIDE6IHN0cmluZwpjb21waWxlci5lcnIub3B0aW9uLnJlbW92ZWQudGFyZ2V0PVwKICAgIFRhcmdldCBvcHRpb24gezB9IGlzIG5vIGxvbmdlciBzdXBwb3J0ZWQuIFVzZSB7MX0gb3IgbGF0ZXIuCgpjb21waWxlci53YXJuLm9wdGlvbi5vYnNvbGV0ZS5zdXBwcmVzc2lvbj1cCiAgICBUbyBzdXBwcmVzcyB3YXJuaW5ncyBhYm91dCBvYnNvbGV0ZSBvcHRpb25zLCB1c2UgLVhsaW50Oi1vcHRpb25zLgoKIyAwOiBuYW1lLCAxOiBudW1iZXIsIDI6IG51bWJlciwgMzogbnVtYmVyLCA0OiBudW1iZXIKY29tcGlsZXIud2Fybi5mdXR1cmUuYXR0cj1cCiAgICB7MH0gYXR0cmlidXRlIGludHJvZHVjZWQgaW4gdmVyc2lvbiB7MX0uezJ9IGNsYXNzIGZpbGVzIGlzIGlnbm9yZWQgaW4gdmVyc2lvbiB7M30uezR9IGNsYXNzIGZpbGVzCgojIFdhcm5pbmdzIHJlbGF0ZWQgdG8gYW5ub3RhdGlvbiBwcm9jZXNzaW5nCiMgMDogc3RyaW5nCmNvbXBpbGVyLndhcm4ucHJvYy5wYWNrYWdlLmRvZXMubm90LmV4aXN0PVwKICAgIHBhY2thZ2UgezB9IGRvZXMgbm90IGV4aXN0CgojIDA6IG5hbWUKY29tcGlsZXIud2Fybi5wcm9jLmZpbGUucmVvcGVuaW5nPVwKICAgIEF0dGVtcHQgdG8gY3JlYXRlIGEgZmlsZSBmb3IgJyd7MH0nJyBtdWx0aXBsZSB0aW1lcwoKIyAwOiBuYW1lCmNvbXBpbGVyLndhcm4ucHJvYy50eXBlLmFscmVhZHkuZXhpc3RzPVwKICAgIEEgZmlsZSBmb3IgdHlwZSAnJ3swfScnIGFscmVhZHkgZXhpc3RzIG9uIHRoZSBzb3VyY2VwYXRoIG9yIGNsYXNzcGF0aAoKIyAwOiBuYW1lCmNvbXBpbGVyLndhcm4ucHJvYy50eXBlLnJlY3JlYXRlPVwKICAgIEF0dGVtcHQgdG8gY3JlYXRlIGEgZmlsZSBmb3IgdHlwZSAnJ3swfScnIG11bHRpcGxlIHRpbWVzCgojIDA6IHN0cmluZwpjb21waWxlci53YXJuLnByb2MuaWxsZWdhbC5maWxlLm5hbWU9XAogICAgQ2Fubm90IGNyZWF0ZSBmaWxlIGZvciBpbGxlZ2FsIG5hbWUgJyd7MH0nJy4KCiMgMDogc3RyaW5nLCAxOiBzdHJpbmcKY29tcGlsZXIud2Fybi5wcm9jLnN1c3BpY2lvdXMuY2xhc3MubmFtZT1cCiAgICBDcmVhdGluZyBmaWxlIGZvciBhIHR5cGUgd2hvc2UgbmFtZSBlbmRzIGluIHsxfTogJyd7MH0nJwoKIyAwOiBuYW1lCmNvbXBpbGVyLndhcm4ucHJvYy5maWxlLmNyZWF0ZS5sYXN0LnJvdW5kPVwKICAgIEZpbGUgZm9yIHR5cGUgJyd7MH0nJyBjcmVhdGVkIGluIHRoZSBsYXN0IHJvdW5kIHdpbGwgbm90IGJlIHN1YmplY3QgdG8gYW5ub3RhdGlvbiBwcm9jZXNzaW5nLgoKIyAwOiBzdHJpbmcsIDE6IHN0cmluZwpjb21waWxlci53YXJuLnByb2MubWFsZm9ybWVkLnN1cHBvcnRlZC5zdHJpbmc9XAogICAgTWFsZm9ybWVkIHN0cmluZyAnJ3swfScnIGZvciBhIHN1cHBvcnRlZCBhbm5vdGF0aW9uIHR5cGUgcmV0dXJuZWQgYnkgcHJvY2Vzc29yICcnezF9JycKCiMgMDogc2V0IG9mIHN0cmluZwpjb21waWxlci53YXJuLnByb2MuYW5ub3RhdGlvbnMud2l0aG91dC5wcm9jZXNzb3JzPVwKICAgIE5vIHByb2Nlc3NvciBjbGFpbWVkIGFueSBvZiB0aGVzZSBhbm5vdGF0aW9uczogezB9CgojIDA6IHNvdXJjZSB2ZXJzaW9uLCAxOiBzdHJpbmcsIDI6IHN0cmluZwpjb21waWxlci53YXJuLnByb2MucHJvY2Vzc29yLmluY29tcGF0aWJsZS5zb3VyY2UudmVyc2lvbj1cCiAgICBTdXBwb3J0ZWQgc291cmNlIHZlcnNpb24gJyd7MH0nJyBmcm9tIGFubm90YXRpb24gcHJvY2Vzc29yICcnezF9JycgbGVzcyB0aGFuIC1zb3VyY2UgJyd7Mn0nJwoKY29tcGlsZXIud2Fybi5wcm9jLnByb2Mtb25seS5yZXF1ZXN0ZWQubm8ucHJvY3M9XAogICAgQW5ub3RhdGlvbiBwcm9jZXNzaW5nIHdpdGhvdXQgY29tcGlsYXRpb24gcmVxdWVzdGVkIGJ1dCBubyBwcm9jZXNzb3JzIHdlcmUgZm91bmQuCgpjb21waWxlci53YXJuLnByb2MudXNlLmltcGxpY2l0PVwKICAgIEltcGxpY2l0bHkgY29tcGlsZWQgZmlsZXMgd2VyZSBub3Qgc3ViamVjdCB0byBhbm5vdGF0aW9uIHByb2Nlc3NpbmcuXG5cCiAgICBVc2UgLWltcGxpY2l0IHRvIHNwZWNpZnkgYSBwb2xpY3kgZm9yIGltcGxpY2l0IGNvbXBpbGF0aW9uLgoKY29tcGlsZXIud2Fybi5wcm9jLnVzZS5wcm9jLm9yLmltcGxpY2l0PVwKICAgIEltcGxpY2l0bHkgY29tcGlsZWQgZmlsZXMgd2VyZSBub3Qgc3ViamVjdCB0byBhbm5vdGF0aW9uIHByb2Nlc3NpbmcuXG5cCiAgICBVc2UgLXByb2M6bm9uZSB0byBkaXNhYmxlIGFubm90YXRpb24gcHJvY2Vzc2luZyBvciAtaW1wbGljaXQgdG8gc3BlY2lmeSBhIHBvbGljeSBmb3IgaW1wbGljaXQgY29tcGlsYXRpb24uCgojIFByaW50IGEgY2xpZW50LWdlbmVyYXRlZCB3YXJuaW5nOyBhc3N1bWVkIHRvIGJlIGxvY2FsaXplZCwgbm8gdHJhbnNsYXRpb24gcmVxdWlyZWQKIyAwOiBzdHJpbmcKY29tcGlsZXIud2Fybi5wcm9jLm1lc3NhZ2VyPVwKICAgIHswfQoKIyAwOiBzZXQgb2YgbmFtZQpjb21waWxlci53YXJuLnByb2MudW5jbG9zZWQudHlwZS5maWxlcz1cCiAgICBVbmNsb3NlZCBmaWxlcyBmb3IgdGhlIHR5cGVzICcnezB9Jyc7IHRoZXNlIHR5cGVzIHdpbGwgbm90IHVuZGVyZ28gYW5ub3RhdGlvbiBwcm9jZXNzaW5nCgojIDA6IHN0cmluZwpjb21waWxlci53YXJuLnByb2MudW5tYXRjaGVkLnByb2Nlc3Nvci5vcHRpb25zPVwKICAgIFRoZSBmb2xsb3dpbmcgb3B0aW9ucyB3ZXJlIG5vdCByZWNvZ25pemVkIGJ5IGFueSBwcm9jZXNzb3I6ICcnezB9JycKCmNvbXBpbGVyLndhcm4udHJ5LmV4cGxpY2l0LmNsb3NlLmNhbGw9XAogICAgZXhwbGljaXQgY2FsbCB0byBjbG9zZSgpIG9uIGFuIGF1dG8tY2xvc2VhYmxlIHJlc291cmNlCgojIDA6IHN5bWJvbApjb21waWxlci53YXJuLnRyeS5yZXNvdXJjZS5ub3QucmVmZXJlbmNlZD1cCiAgICBhdXRvLWNsb3NlYWJsZSByZXNvdXJjZSB7MH0gaXMgbmV2ZXIgcmVmZXJlbmNlZCBpbiBib2R5IG9mIGNvcnJlc3BvbmRpbmcgdHJ5IHN0YXRlbWVudAoKIyAwOiB0eXBlCmNvbXBpbGVyLndhcm4udHJ5LnJlc291cmNlLnRocm93cy5pbnRlcnJ1cHRlZC5leGM9XAogICAgYXV0by1jbG9zZWFibGUgcmVzb3VyY2UgezB9IGhhcyBhIG1lbWJlciBtZXRob2QgY2xvc2UoKSB0aGF0IGNvdWxkIHRocm93IEludGVycnVwdGVkRXhjZXB0aW9uCgpjb21waWxlci53YXJuLnVuY2hlY2tlZC5hc3NpZ249XAogICAgdW5jaGVja2VkIGFzc2lnbm1lbnQ6IHswfSB0byB7MX0KCiMgMDogc3ltYm9sLCAxOiB0eXBlCmNvbXBpbGVyLndhcm4udW5jaGVja2VkLmFzc2lnbi50by52YXI9XAogICAgdW5jaGVja2VkIGFzc2lnbm1lbnQgdG8gdmFyaWFibGUgezB9IGFzIG1lbWJlciBvZiByYXcgdHlwZSB7MX0KCiMgMDogc3ltYm9sLCAxOiB0eXBlCmNvbXBpbGVyLndhcm4udW5jaGVja2VkLmNhbGwubWJyLm9mLnJhdy50eXBlPVwKICAgIHVuY2hlY2tlZCBjYWxsIHRvIHswfSBhcyBhIG1lbWJlciBvZiB0aGUgcmF3IHR5cGUgezF9Cgpjb21waWxlci53YXJuLnVuY2hlY2tlZC5jYXN0LnRvLnR5cGU9XAogICAgdW5jaGVja2VkIGNhc3QgdG8gdHlwZSB7MH0KCiMgMDogc3ltYm9sIGtpbmQsIDE6IG5hbWUsIDI6IGxpc3Qgb2YgdHlwZSwgMzogbGlzdCBvZiB0eXBlLCA0OiBzeW1ib2wga2luZCwgNTogc3ltYm9sCmNvbXBpbGVyLndhcm4udW5jaGVja2VkLm1ldGguaW52b2NhdGlvbi5hcHBsaWVkPVwKICAgIHVuY2hlY2tlZCBtZXRob2QgaW52b2NhdGlvbjogezB9IHsxfSBpbiB7NH0gezV9IGlzIGFwcGxpZWQgdG8gZ2l2ZW4gdHlwZXNcblwKICAgIHJlcXVpcmVkOiB7Mn1cblwKICAgIGZvdW5kOiB7M30KCiMgMDogdHlwZQpjb21waWxlci53YXJuLnVuY2hlY2tlZC5nZW5lcmljLmFycmF5LmNyZWF0aW9uPVwKICAgIHVuY2hlY2tlZCBnZW5lcmljIGFycmF5IGNyZWF0aW9uIGZvciB2YXJhcmdzIHBhcmFtZXRlciBvZiB0eXBlIHswfQoKIyAwOiB0eXBlCmNvbXBpbGVyLndhcm4udW5jaGVja2VkLnZhcmFyZ3Mubm9uLnJlaWZpYWJsZS50eXBlPVwKICAgIFBvc3NpYmxlIGhlYXAgcG9sbHV0aW9uIGZyb20gcGFyYW1ldGVyaXplZCB2YXJhcmcgdHlwZSB7MH0KCiMgMDogc3ltYm9sCmNvbXBpbGVyLndhcm4udmFyYXJncy51bnNhZmUudXNlLnZhcmFyZ3MucGFyYW09XAogICAgVmFyYXJncyBtZXRob2QgY291bGQgY2F1c2UgaGVhcCBwb2xsdXRpb24gZnJvbSBub24tcmVpZmlhYmxlIHZhcmFyZ3MgcGFyYW1ldGVyIHswfQoKY29tcGlsZXIud2Fybi5taXNzaW5nLmRlcHJlY2F0ZWQuYW5ub3RhdGlvbj1cCiAgICBkZXByZWNhdGVkIGl0ZW0gaXMgbm90IGFubm90YXRlZCB3aXRoIEBEZXByZWNhdGVkCgojIDA6IHN5bWJvbCBraW5kCmNvbXBpbGVyLndhcm4uZGVwcmVjYXRlZC5hbm5vdGF0aW9uLmhhcy5uby5lZmZlY3Q9XAogICAgQERlcHJlY2F0ZWQgYW5ub3RhdGlvbiBoYXMgbm8gZWZmZWN0IG9uIHRoaXMgezB9IGRlY2xhcmF0aW9uCgpjb21waWxlci53YXJuLmludmFsaWQucGF0aD1cCiAgICBJbnZhbGlkIGZpbGVuYW1lOiB7MH0KCmNvbXBpbGVyLndhcm4uaW52YWxpZC5hcmNoaXZlLmZpbGU9XAogICAgVW5leHBlY3RlZCBmaWxlIG9uIHBhdGg6IHswfQoKY29tcGlsZXIud2Fybi51bmV4cGVjdGVkLmFyY2hpdmUuZmlsZT1cCiAgICBVbmV4cGVjdGVkIGV4dGVuc2lvbiBmb3IgYXJjaGl2ZSBmaWxlOiB7MH0KCiMgMDogcGF0aApjb21waWxlci5lcnIubm8uemlwZnMuZm9yLmFyY2hpdmU9XAogICAgTm8gZmlsZSBzeXN0ZW0gcHJvdmlkZXIgaXMgYXZhaWxhYmxlIHRvIGhhbmRsZSB0aGlzIGZpbGU6IHswfQoKY29tcGlsZXIud2Fybi5kaXYuemVybz1cCiAgICBkaXZpc2lvbiBieSB6ZXJvCgpjb21waWxlci53YXJuLmVtcHR5LmlmPVwKICAgIGVtcHR5IHN0YXRlbWVudCBhZnRlciBpZgoKY29tcGlsZXIud2Fybi5hbm5vdGF0aW9uLm1ldGhvZC5ub3QuZm91bmQ9XAogICAgQ2Fubm90IGZpbmQgYW5ub3RhdGlvbiBtZXRob2QgJyd7MX0oKScnIGluIHR5cGUgJyd7MH0nJwoKY29tcGlsZXIud2Fybi5hbm5vdGF0aW9uLm1ldGhvZC5ub3QuZm91bmQucmVhc29uPVwKICAgIENhbm5vdCBmaW5kIGFubm90YXRpb24gbWV0aG9kICcnezF9KCknJyBpbiB0eXBlICcnezB9Jyc6IHsyfQoKIyAwOiBzeW1ib2wsIDE6IG5hbWUKY29tcGlsZXIud2Fybi51bmtub3duLmVudW0uY29uc3RhbnQ9XAogICAgdW5rbm93biBlbnVtIGNvbnN0YW50IHsxfS57Mn0KCiMgMDogc3ltYm9sLCAxOiBuYW1lLCAyOiBtZXNzYWdlIHNlZ21lbnQKY29tcGlsZXIud2Fybi51bmtub3duLmVudW0uY29uc3RhbnQucmVhc29uPVwKICAgIHVua25vd24gZW51bSBjb25zdGFudCB7MX0uezJ9XG5cCiAgICByZWFzb246IHszfQoKIyAwOiB0eXBlLCAxOiB0eXBlCmNvbXBpbGVyLndhcm4ucmF3LmNsYXNzLnVzZT1cCiAgICBmb3VuZCByYXcgdHlwZTogezB9XG5cCiAgICBtaXNzaW5nIHR5cGUgYXJndW1lbnRzIGZvciBnZW5lcmljIGNsYXNzIHsxfQoKIyAwOiB1bnVzZWQsIDE6IHVudXNlZApjb21waWxlci53YXJuLmRpYW1vbmQucmVkdW5kYW50LmFyZ3M9XAogICAgUmVkdW5kYW50IHR5cGUgYXJndW1lbnRzIGluIG5ldyBleHByZXNzaW9uICh1c2UgZGlhbW9uZCBvcGVyYXRvciBpbnN0ZWFkKS4KCmNvbXBpbGVyLndhcm4ucG90ZW50aWFsLmxhbWJkYS5mb3VuZD1cCiAgICBUaGlzIGFub255bW91cyBpbm5lciBjbGFzcyBjcmVhdGlvbiBjYW4gYmUgdHVybmVkIGludG8gYSBsYW1iZGEgZXhwcmVzc2lvbi4KCmNvbXBpbGVyLndhcm4ubWV0aG9kLnJlZHVuZGFudC50eXBlYXJncz1cCiAgICBSZWR1bmRhbnQgdHlwZSBhcmd1bWVudHMgaW4gbWV0aG9kIGNhbGwuCgojIDA6IHN5bWJvbCwgMTogbWVzc2FnZSBzZWdtZW50CmNvbXBpbGVyLndhcm4udmFyYXJncy5yZWR1bmRhbnQudHJ1c3RtZS5hbm5vPVwKICAgIFJlZHVuZGFudCB7MH0gYW5ub3RhdGlvbi4gezF9CgojIDA6IHN5bWJvbApjb21waWxlci53YXJuLmFjY2Vzcy50by5tZW1iZXIuZnJvbS5zZXJpYWxpemFibGUuZWxlbWVudD1cCiAgICBhY2Nlc3MgdG8gbWVtYmVyIHswfSBmcm9tIHNlcmlhbGl6YWJsZSBlbGVtZW50IGNhbiBiZSBwdWJsaWNseSBhY2Nlc3NpYmxlIHRvIHVudHJ1c3RlZCBjb2RlCgojIDA6IHN5bWJvbApjb21waWxlci53YXJuLmFjY2Vzcy50by5tZW1iZXIuZnJvbS5zZXJpYWxpemFibGUubGFtYmRhPVwKICAgIGFjY2VzcyB0byBtZW1iZXIgezB9IGZyb20gc2VyaWFsaXphYmxlIGxhbWJkYSBjYW4gYmUgcHVibGljbHkgYWNjZXNzaWJsZSB0byB1bnRydXN0ZWQgY29kZQoKIyMjIyMKCiMjIFRoZSBmb2xsb3dpbmcgYXJlIHRva2VucyB3aGljaCBhcmUgbm9uLXRlcm1pbmFscyBpbiB0aGUgbGFuZ3VhZ2UuIFRoZXkgc2hvdWxkCiMjIGJlIG5hbWVkIGFzIEpMUzMgY2FsbHMgdGhlbSB3aGVuIHRyYW5zbGF0ZWQgdG8gdGhlIGFwcHJvcHJpYXRlIGxhbmd1YWdlLgpjb21waWxlci5taXNjLnRva2VuLmlkZW50aWZpZXI9XAogICAgPGlkZW50aWZpZXI+Cgpjb21waWxlci5taXNjLnRva2VuLmNoYXJhY3Rlcj1cCiAgICA8Y2hhcmFjdGVyPgoKY29tcGlsZXIubWlzYy50b2tlbi5zdHJpbmc9XAogICAgPHN0cmluZz4KCmNvbXBpbGVyLm1pc2MudG9rZW4uaW50ZWdlcj1cCiAgICA8aW50ZWdlcj4KCmNvbXBpbGVyLm1pc2MudG9rZW4ubG9uZy1pbnRlZ2VyPVwKICAgIDxsb25nIGludGVnZXI+Cgpjb21waWxlci5taXNjLnRva2VuLmZsb2F0PVwKICAgIDxmbG9hdD4KCmNvbXBpbGVyLm1pc2MudG9rZW4uZG91YmxlPVwKICAgIDxkb3VibGU+Cgpjb21waWxlci5taXNjLnRva2VuLmJhZC1zeW1ib2w9XAogICAgPGJhZCBzeW1ib2w+Cgpjb21waWxlci5taXNjLnRva2VuLmVuZC1vZi1pbnB1dD1cCiAgICA8ZW5kIG9mIGlucHV0PgoKIyMgVGhlIGFyZ3VtZW50IHRvIHRoZSBmb2xsb3dpbmcgc3RyaW5nIHdpbGwgYWx3YXlzIGJlIG9uZSBvZiB0aGUgZm9sbG93aW5nOgojIyAxLiBvbmUgb2YgdGhlIGFib3ZlIG5vbi10ZXJtaW5hbHMKIyMgMi4gYSBrZXl3b3JkIChKTFMxLjgpCiMjIDMuIGEgYm9vbGVhbiBsaXRlcmFsIChKTFMzLjEwLjMpCiMjIDQuIHRoZSBudWxsIGxpdGVyYWwgKEpMUzMuMTAuNykKIyMgNS4gYSBKYXZhIHNlcGFyYXRvciAoSkxTMy4xMSkKIyMgNi4gYW4gb3BlcmF0b3IgKEpMUzMuMTIpCiMjCiMjIFRoaXMgaXMgdGhlIG9ubHkgcGxhY2UgdGhlc2UgdG9rZW5zIHdpbGwgYmUgdXNlZC4KIyAwOiB0b2tlbgpjb21waWxlci5lcnIuZXhwZWN0ZWQ9XAogICAgezB9IGV4cGVjdGVkCgojIDA6IHRva2VuLCAxOiB0b2tlbgpjb21waWxlci5lcnIuZXhwZWN0ZWQyPVwKICAgIHswfSBvciB7MX0gZXhwZWN0ZWQKCiMgMDogdG9rZW4sIDE6IHRva2VuLCAyOiB0b2tlbgpjb21waWxlci5lcnIuZXhwZWN0ZWQzPVwKICAgIHswfSwgezF9LCBvciB7Mn0gZXhwZWN0ZWQKCmNvbXBpbGVyLmVyci5wcmVtYXR1cmUuZW9mPVwKICAgIHJlYWNoZWQgZW5kIG9mIGZpbGUgd2hpbGUgcGFyc2luZwoKIyMgVGhlIGZvbGxvd2luZyBhcmUgcmVsYXRlZCBpbiBmb3JtLCBidXQgZG8gbm90IGVhc2lseSBmaXQgdGhlIGFib3ZlIHBhcmFkaWdtLgpjb21waWxlci5lcnIuZXhwZWN0ZWQubW9kdWxlPVwKICAgICcnbW9kdWxlJycgZXhwZWN0ZWQKCmNvbXBpbGVyLmVyci5leHBlY3RlZC5tb2R1bGUub3Iub3Blbj1cCiAgICAnJ21vZHVsZScnIG9yICcnb3BlbicnIGV4cGVjdGVkCgpjb21waWxlci5lcnIuZG90LmNsYXNzLmV4cGVjdGVkPVwKICAgICcnLmNsYXNzJycgZXhwZWN0ZWQKCiMjIFRoZSBhcmd1bWVudCB0byB0aGlzIHN0cmluZyB3aWxsIGFsd2F5cyBiZSBlaXRoZXIgJ2Nhc2UnIG9yICdkZWZhdWx0Jy4KIyAwOiB0b2tlbgpjb21waWxlci5lcnIub3JwaGFuZWQ9XAogICAgb3JwaGFuZWQgezB9CgojIDA6IG5hbWUKY29tcGlsZXIubWlzYy5hbm9ueW1vdXMuY2xhc3M9XAogICAgPGFub255bW91cyB7MH0+CgojIDA6IG5hbWUsIDE6IHR5cGUKY29tcGlsZXIubWlzYy50eXBlLmNhcHR1cmVvZj1cCiAgICBjYXB0dXJlI3swfSBvZiB7MX0KCmNvbXBpbGVyLm1pc2MudHlwZS5jYXB0dXJlb2YuMT1cCiAgICBjYXB0dXJlI3swfQoKY29tcGlsZXIubWlzYy50eXBlLm5vbmU9XAogICAgPG5vbmU+Cgpjb21waWxlci5taXNjLnVubmFtZWQucGFja2FnZT1cCiAgICB1bm5hbWVkIHBhY2thZ2UKCmNvbXBpbGVyLm1pc2MudW5uYW1lZC5tb2R1bGU9XAogICAgdW5uYW1lZCBtb2R1bGUKCiMjIyMjCgojIDA6IHN5bWJvbCwgMTogbWVzc2FnZSBzZWdtZW50CmNvbXBpbGVyLmVyci5jYW50LmFjY2Vzcz1cCiAgICBjYW5ub3QgYWNjZXNzIHswfVxuXAogICAgezF9CgojIDA6IG5hbWUKY29tcGlsZXIubWlzYy5iYWQuY2xhc3MuZmlsZT1cCiAgICBjbGFzcyBmaWxlIGlzIGludmFsaWQgZm9yIGNsYXNzIHswfQoKIyAwOiBmaWxlIG5hbWUsIDE6IHN0cmluZyAoZXhwZWN0ZWQgY29uc3RhbnQgcG9vbCBlbnRyeSB0eXBlKSwgMjogbnVtYmVyIChjb25zdGFudCBwb29sIGluZGV4KQpjb21waWxlci5taXNjLmJhZC5jb25zdC5wb29sLmVudHJ5PVwKICAgIGJhZCBjb25zdGFudCBwb29sIGVudHJ5IGluIHswfVxuXAogICAgZXhwZWN0ZWQgezF9IGF0IGluZGV4IHsyfQoKIyAwOiBmaWxlIG5hbWUsIDE6IG1lc3NhZ2Ugc2VnbWVudApjb21waWxlci5taXNjLmJhZC5jbGFzcy5maWxlLmhlYWRlcj1cCiAgICBiYWQgY2xhc3MgZmlsZTogezB9XG5cCiAgICB7MX1cblwKICAgIFBsZWFzZSByZW1vdmUgb3IgbWFrZSBzdXJlIGl0IGFwcGVhcnMgaW4gdGhlIGNvcnJlY3Qgc3ViZGlyZWN0b3J5IG9mIHRoZSBjbGFzc3BhdGguCgojIDA6IGZpbGUgbmFtZSwgMTogbWVzc2FnZSBzZWdtZW50CmNvbXBpbGVyLm1pc2MuYmFkLnNvdXJjZS5maWxlLmhlYWRlcj1cCiAgICBiYWQgc291cmNlIGZpbGU6IHswfVxuXAogICAgezF9XG5cCiAgICBQbGVhc2UgcmVtb3ZlIG9yIG1ha2Ugc3VyZSBpdCBhcHBlYXJzIGluIHRoZSBjb3JyZWN0IHN1YmRpcmVjdG9yeSBvZiB0aGUgc291cmNlcGF0aC4KCiMjIFRoZSBmb2xsb3dpbmcgYXJlIGFsbCBwb3NzaWJsZSBzdHJpbmdzIGZvciB0aGUgc2Vjb25kIGFyZ3VtZW50ICh7MX0pIG9mIHRoZQojIyBhYm92ZSBzdHJpbmdzLgpjb21waWxlci5taXNjLmJhZC5jbGFzcy5zaWduYXR1cmU9XAogICAgYmFkIGNsYXNzIHNpZ25hdHVyZTogezB9CgojMDogc3ltYm9sLCAxOiBzeW1ib2wKY29tcGlsZXIubWlzYy5iYWQuZW5jbG9zaW5nLmNsYXNzPVwKICAgIGJhZCBlbmNsb3NpbmcgY2xhc3MgZm9yIHswfTogezF9CgojIDA6IHN5bWJvbApjb21waWxlci5taXNjLmJhZC5lbmNsb3NpbmcubWV0aG9kPVwKICAgIGJhZCBlbmNsb3NpbmcgbWV0aG9kIGF0dHJpYnV0ZSBmb3IgY2xhc3MgezB9Cgpjb21waWxlci5taXNjLmJhZC5ydW50aW1lLmludmlzaWJsZS5wYXJhbS5hbm5vdGF0aW9ucz1cCiAgICBiYWQgUnVudGltZUludmlzaWJsZVBhcmFtZXRlckFubm90YXRpb25zIGF0dHJpYnV0ZTogezB9Cgpjb21waWxlci5taXNjLmJhZC5jb25zdC5wb29sLnRhZz1cCiAgICBiYWQgY29uc3RhbnQgcG9vbCB0YWc6IHswfQoKY29tcGlsZXIubWlzYy5iYWQuY29uc3QucG9vbC50YWcuYXQ9XAogICAgYmFkIGNvbnN0YW50IHBvb2wgdGFnOiB7MH0gYXQgezF9Cgpjb21waWxlci5taXNjLmJhZC5zaWduYXR1cmU9XAogICAgYmFkIHNpZ25hdHVyZTogezB9Cgpjb21waWxlci5taXNjLmJhZC50eXBlLmFubm90YXRpb24udmFsdWU9XAogICAgYmFkIHR5cGUgYW5ub3RhdGlvbiB0YXJnZXQgdHlwZSB2YWx1ZTogezB9Cgpjb21waWxlci5taXNjLmJhZC5tb2R1bGUtaW5mby5uYW1lPVwKICAgIGJhZCBjbGFzcyBuYW1lCgpjb21waWxlci5taXNjLmNsYXNzLmZpbGUud3JvbmcuY2xhc3M9XAogICAgY2xhc3MgZmlsZSBjb250YWlucyB3cm9uZyBjbGFzczogezB9Cgpjb21waWxlci5taXNjLm1vZHVsZS5pbmZvLmludmFsaWQuc3VwZXIuY2xhc3M9XAogICAgbW9kdWxlLWluZm8gd2l0aCBpbnZhbGlkIHN1cGVyIGNsYXNzCgpjb21waWxlci5taXNjLmNsYXNzLmZpbGUubm90LmZvdW5kPVwKICAgIGNsYXNzIGZpbGUgZm9yIHswfSBub3QgZm91bmQKCiMgMDogc3RyaW5nIChjb25zdGFudCB2YWx1ZSksIDE6IHN5bWJvbCAoY29uc3RhbnQgZmllbGQpLCAyOiB0eXBlIChmaWVsZCB0eXBlKQpjb21waWxlci5taXNjLmJhZC5jb25zdGFudC5yYW5nZT1cCiAgICBjb25zdGFudCB2YWx1ZSAnJ3swfScnIGZvciB7MX0gaXMgb3V0c2lkZSB0aGUgZXhwZWN0ZWQgcmFuZ2UgZm9yIHsyfQoKIyAwOiBzdHJpbmcgKGNvbnN0YW50IHZhbHVlKSwgMTogc3ltYm9sIChjb25zdGFudCBmaWVsZCksIDI6IHN0cmluZyAoZXhwZWN0ZWQgY2xhc3MpCmNvbXBpbGVyLm1pc2MuYmFkLmNvbnN0YW50LnZhbHVlPVwKICAgIGJhZCBjb25zdGFudCB2YWx1ZSAnJ3swfScnIGZvciB7MX0sIGV4cGVjdGVkIHsyfQoKIyAwOiBzdHJpbmcgKGNsYXNzZmlsZSBtYWpvciB2ZXJzaW9uKSwgMTogc3RyaW5nIChjbGFzc2ZpbGUgbWlub3IgdmVyc2lvbikKY29tcGlsZXIubWlzYy5pbnZhbGlkLmRlZmF1bHQuaW50ZXJmYWNlPVwKICAgIGRlZmF1bHQgbWV0aG9kIGZvdW5kIGluIHZlcnNpb24gezB9LnsxfSBjbGFzc2ZpbGUKCiMgMDogc3RyaW5nIChjbGFzc2ZpbGUgbWFqb3IgdmVyc2lvbiksIDE6IHN0cmluZyAoY2xhc3NmaWxlIG1pbm9yIHZlcnNpb24pCmNvbXBpbGVyLm1pc2MuaW52YWxpZC5zdGF0aWMuaW50ZXJmYWNlPVwKICAgIHN0YXRpYyBtZXRob2QgZm91bmQgaW4gdmVyc2lvbiB7MH0uezF9IGNsYXNzZmlsZQoKIyAwOiBzdHJpbmcgKGNsYXNzZmlsZSBtYWpvciB2ZXJzaW9uKSwgMTogc3RyaW5nIChjbGFzc2ZpbGUgbWlub3IgdmVyc2lvbikKY29tcGlsZXIubWlzYy5hbmFjaHJvbmlzdGljLm1vZHVsZS5pbmZvPVwKICAgIG1vZHVsZSBkZWNsYXJhdGlvbiBmb3VuZCBpbiB2ZXJzaW9uIHswfS57MX0gY2xhc3NmaWxlCgojIDA6IG5hbWUKY29tcGlsZXIubWlzYy5maWxlLmRvZXNudC5jb250YWluLmNsYXNzPVwKICAgIGZpbGUgZG9lcyBub3QgY29udGFpbiBjbGFzcyB7MH0KCmNvbXBpbGVyLm1pc2MuZmlsZS5kb2VzLm5vdC5jb250YWluLnBhY2thZ2U9XAogICAgZmlsZSBkb2VzIG5vdCBjb250YWluIHBhY2thZ2UgezB9Cgpjb21waWxlci5taXNjLmZpbGUuZG9lcy5ub3QuY29udGFpbi5tb2R1bGU9XAogICAgZmlsZSBkb2VzIG5vdCBjb250YWluIG1vZHVsZSBkZWNsYXJhdGlvbgoKY29tcGlsZXIubWlzYy5pbGxlZ2FsLnN0YXJ0Lm9mLmNsYXNzLmZpbGU9XAogICAgaWxsZWdhbCBzdGFydCBvZiBjbGFzcyBmaWxlCgpjb21waWxlci5taXNjLnVuYWJsZS50by5hY2Nlc3MuZmlsZT1cCiAgICB1bmFibGUgdG8gYWNjZXNzIGZpbGU6IHswfQoKY29tcGlsZXIubWlzYy51bmljb2RlLnN0ci5ub3Quc3VwcG9ydGVkPVwKICAgIHVuaWNvZGUgc3RyaW5nIGluIGNsYXNzIGZpbGUgbm90IHN1cHBvcnRlZAoKY29tcGlsZXIubWlzYy51bmRlY2wudHlwZS52YXI9XAogICAgdW5kZWNsYXJlZCB0eXBlIHZhcmlhYmxlOiB7MH0KCmNvbXBpbGVyLm1pc2MubWFsZm9ybWVkLnZhcmFyZy5tZXRob2Q9XAogICAgY2xhc3MgZmlsZSBjb250YWlucyBtYWxmb3JtZWQgdmFyaWFibGUgYXJpdHkgbWV0aG9kOiB7MH0KCmNvbXBpbGVyLm1pc2Mud3JvbmcudmVyc2lvbj1cCiAgICBjbGFzcyBmaWxlIGhhcyB3cm9uZyB2ZXJzaW9uIHswfS57MX0sIHNob3VsZCBiZSB7Mn0uezN9CgojIyMjIwoKIyAwOiB0eXBlLCAxOiB0eXBlIG9yIHN5bWJvbApjb21waWxlci5lcnIubm90LndpdGhpbi5ib3VuZHM9XAogICAgdHlwZSBhcmd1bWVudCB7MH0gaXMgbm90IHdpdGhpbiBib3VuZHMgb2YgdHlwZS12YXJpYWJsZSB7MX0KCiMjIFRoZSBmb2xsb3dpbmcgYXJlIGFsbCBwb3NzaWJsZSBzdHJpbmdzIGZvciB0aGUgc2Vjb25kIGFyZ3VtZW50ICh7MX0pIG9mIHRoZQojIyBhYm92ZSBzdHJpbmcuCgojIyBub25lIHlldC4uLgoKIyMjIyMKCiMgMDogbWVzc2FnZSBzZWdtZW50CmNvbXBpbGVyLmVyci5wcm9iLmZvdW5kLnJlcT1cCiAgICBpbmNvbXBhdGlibGUgdHlwZXM6IHswfQoKIyAwOiBtZXNzYWdlIHNlZ21lbnQKY29tcGlsZXIubWlzYy5wcm9iLmZvdW5kLnJlcT1cCiAgICBpbmNvbXBhdGlibGUgdHlwZXM6IHswfQoKIyAwOiBtZXNzYWdlIHNlZ21lbnQsIDE6IHR5cGUsIDI6IHR5cGUKY29tcGlsZXIud2Fybi5wcm9iLmZvdW5kLnJlcT1cCiAgICB7MH1cblwKICAgIHJlcXVpcmVkOiB7Mn1cblwKICAgIGZvdW5kOiAgICB7MX0KCiMgMDogdHlwZSwgMTogdHlwZQpjb21waWxlci5taXNjLmluY29udmVydGlibGUudHlwZXM9XAogICAgezB9IGNhbm5vdCBiZSBjb252ZXJ0ZWQgdG8gezF9CgojIDA6IHR5cGUsIDE6IHR5cGUKY29tcGlsZXIubWlzYy5wb3NzaWJsZS5sb3NzLm9mLnByZWNpc2lvbj1cCiAgICBwb3NzaWJsZSBsb3NzeSBjb252ZXJzaW9uIGZyb20gezB9IHRvIHsxfQoKY29tcGlsZXIubWlzYy51bmNoZWNrZWQuYXNzaWduPVwKICAgIHVuY2hlY2tlZCBjb252ZXJzaW9uCgojIGNvbXBpbGVyLm1pc2Muc3RvcmVjaGVjaz1cCiMgICAgIGFzc2lnbm1lbnQgbWlnaHQgY2F1c2UgbGF0ZXIgc3RvcmUgY2hlY2tzIHRvIGZhaWwKIyBjb21waWxlci5taXNjLnVuY2hlY2tlZD1cCiMgICAgIGFzc2lnbmVkIGFycmF5IGNhbm5vdCBkeW5hbWljYWxseSBjaGVjayBpdHMgc3RvcmVzCmNvbXBpbGVyLm1pc2MudW5jaGVja2VkLmNhc3QudG8udHlwZT1cCiAgICB1bmNoZWNrZWQgY2FzdAoKIyBjb21waWxlci5lcnIuc3Rhci5leHBlY3RlZD1cCiMgICAgICcnKicnIGV4cGVjdGVkCiMgY29tcGlsZXIuZXJyLm5vLmVsZW0udHlwZT1cCiMgICAgIFxbXCpcXSBjYW5ub3QgaGF2ZSBhIHR5cGUKCiMgMDogdHlwZQpjb21waWxlci5taXNjLnRyeS5ub3QuYXBwbGljYWJsZS50by50eXBlPVwKICAgIHRyeS13aXRoLXJlc291cmNlcyBub3QgYXBwbGljYWJsZSB0byB2YXJpYWJsZSB0eXBlXG5cCiAgICAoezB9KQoKIyMjIyMKCiMgMDogbWVzc2FnZSBzZWdtZW50IG9yIHR5cGUsIDE6IG1lc3NhZ2Ugc2VnbWVudApjb21waWxlci5lcnIudHlwZS5mb3VuZC5yZXE9XAogICAgdW5leHBlY3RlZCB0eXBlXG5cCiAgICByZXF1aXJlZDogezF9XG5cCiAgICBmb3VuZDogICAgezB9CgojIyBUaGUgZm9sbG93aW5nIGFyZSBhbGwgcG9zc2libGUgc3RyaW5ncyBmb3IgdGhlIGZpcnN0IGFyZ3VtZW50ICh7MH0pIG9mIHRoZQojIyBhYm92ZSBzdHJpbmcuCmNvbXBpbGVyLm1pc2MudHlwZS5yZXEuY2xhc3M9XAogICAgY2xhc3MKCmNvbXBpbGVyLm1pc2MudHlwZS5yZXEuY2xhc3MuYXJyYXk9XAogICAgY2xhc3Mgb3IgYXJyYXkKCmNvbXBpbGVyLm1pc2MudHlwZS5yZXEuYXJyYXkub3IuaXRlcmFibGU9XAogICAgYXJyYXkgb3IgamF2YS5sYW5nLkl0ZXJhYmxlCgpjb21waWxlci5taXNjLnR5cGUucmVxLnJlZj1cCiAgICByZWZlcmVuY2UKCmNvbXBpbGVyLm1pc2MudHlwZS5yZXEuZXhhY3Q9XAogICAgY2xhc3Mgb3IgaW50ZXJmYWNlIHdpdGhvdXQgYm91bmRzCgojIDA6IHR5cGUKY29tcGlsZXIubWlzYy50eXBlLnBhcmFtZXRlcj1cCiAgICB0eXBlIHBhcmFtZXRlciB7MH0KCiMjIyMjCgojIyBUaGUgZm9sbG93aW5nIGFyZSBhbGwgcG9zc2libGUgc3RyaW5ncyBmb3IgdGhlIGxhc3QgYXJndW1lbnQgb2YgYWxsIHRob3NlCiMjIGRpYWdub3N0aWNzIHdob3NlIGtleSBlbmRzIGluICIuMSIKCiMgMDogdHlwZSwgMTogbGlzdCBvZiB0eXBlCmNvbXBpbGVyLm1pc2Mubm8udW5pcXVlLm1heGltYWwuaW5zdGFuY2UuZXhpc3RzPVwKICAgIG5vIHVuaXF1ZSBtYXhpbWFsIGluc3RhbmNlIGV4aXN0cyBmb3IgdHlwZSB2YXJpYWJsZSB7MH0gd2l0aCB1cHBlciBib3VuZHMgezF9Cgpjb21waWxlci5taXNjLm5vLnVuaXF1ZS5taW5pbWFsLmluc3RhbmNlLmV4aXN0cz1cCiAgICBubyB1bmlxdWUgbWluaW1hbCBpbnN0YW5jZSBleGlzdHMgZm9yIHR5cGUgdmFyaWFibGUgezB9IHdpdGggbG93ZXIgYm91bmRzIHsxfQoKIyAwOiB0eXBlLCAxOiBsaXN0IG9mIHR5cGUKY29tcGlsZXIubWlzYy5pbmNvbXBhdGlibGUudXBwZXIuYm91bmRzPVwKICAgIGluZmVyZW5jZSB2YXJpYWJsZSB7MH0gaGFzIGluY29tcGF0aWJsZSB1cHBlciBib3VuZHMgezF9CgojIDA6IHR5cGUsIDE6IGxpc3Qgb2YgdHlwZQpjb21waWxlci5taXNjLmluY29tcGF0aWJsZS5lcS5ib3VuZHM9XAogICAgaW5mZXJlbmNlIHZhcmlhYmxlIHswfSBoYXMgaW5jb21wYXRpYmxlIGVxdWFsaXR5IGNvbnN0cmFpbnRzIHsxfQoKIyAwOiB0eXBlLCAxOiBsaXN0IG9mIHR5cGUsIDI6IGxpc3Qgb2YgdHlwZQpjb21waWxlci5taXNjLmluY29tcGF0aWJsZS5lcS51cHBlci5ib3VuZHM9XAogICAgaW5mZXJlbmNlIHZhcmlhYmxlIHswfSBoYXMgaW5jb21wYXRpYmxlIGJvdW5kc1xuXAogICAgZXF1YWxpdHkgY29uc3RyYWludHM6IHsxfVxuXAogICAgdXBwZXIgYm91bmRzOiB7Mn0KCiMgMDogdHlwZSwgMTogbGlzdCBvZiB0eXBlLCAyOiBsaXN0IG9mIHR5cGUKY29tcGlsZXIubWlzYy5pbmNvbXBhdGlibGUudXBwZXIubG93ZXIuYm91bmRzPVwKICAgIGluZmVyZW5jZSB2YXJpYWJsZSB7MH0gaGFzIGluY29tcGF0aWJsZSBib3VuZHNcblwKICAgIHVwcGVyIGJvdW5kczogezF9XG5cCiAgICBsb3dlciBib3VuZHM6IHsyfQoKIyAwOiB0eXBlLCAxOiBsaXN0IG9mIHR5cGUsIDI6IGxpc3Qgb2YgdHlwZQpjb21waWxlci5taXNjLmluY29tcGF0aWJsZS5lcS5sb3dlci5ib3VuZHM9XAogICAgaW5mZXJlbmNlIHZhcmlhYmxlIHswfSBoYXMgaW5jb21wYXRpYmxlIGJvdW5kc1xuXAogICAgZXF1YWxpdHkgY29uc3RyYWludHM6IHsxfVxuXAogICAgbG93ZXIgYm91bmRzOiB7Mn0KCiMgMDogbGlzdCBvZiB0eXBlLCAxOiB0eXBlLCAyOiB0eXBlCmNvbXBpbGVyLm1pc2MuaW5mZXIubm8uY29uZm9ybWluZy5pbnN0YW5jZS5leGlzdHM9XAogICAgbm8gaW5zdGFuY2Uocykgb2YgdHlwZSB2YXJpYWJsZShzKSB7MH0gZXhpc3Qgc28gdGhhdCB7MX0gY29uZm9ybXMgdG8gezJ9CgojIDA6IGxpc3Qgb2YgdHlwZSwgMTogbWVzc2FnZSBzZWdtZW50CmNvbXBpbGVyLm1pc2MuaW5mZXIubm8uY29uZm9ybWluZy5hc3NpZ25tZW50LmV4aXN0cz1cCiAgICBjYW5ub3QgaW5mZXIgdHlwZS12YXJpYWJsZShzKSB7MH1cblwKICAgIChhcmd1bWVudCBtaXNtYXRjaDsgezF9KQoKIyAwOiBsaXN0IG9mIHR5cGUKY29tcGlsZXIubWlzYy5pbmZlci5hcmcubGVuZ3RoLm1pc21hdGNoPVwKICAgIGNhbm5vdCBpbmZlciB0eXBlLXZhcmlhYmxlKHMpIHswfVxuXAogICAgKGFjdHVhbCBhbmQgZm9ybWFsIGFyZ3VtZW50IGxpc3RzIGRpZmZlciBpbiBsZW5ndGgpCgojIDA6IGxpc3Qgb2YgdHlwZSwgMTogbWVzc2FnZSBzZWdtZW50CmNvbXBpbGVyLm1pc2MuaW5mZXIudmFyYXJncy5hcmd1bWVudC5taXNtYXRjaD1cCiAgICBjYW5ub3QgaW5mZXIgdHlwZS12YXJpYWJsZShzKSB7MH1cblwKICAgICh2YXJhcmdzIG1pc21hdGNoOyB7MX0pCgojIDA6IHR5cGUsIDE6IGxpc3Qgb2YgdHlwZQpjb21waWxlci5taXNjLmluZmVycmVkLmRvLm5vdC5jb25mb3JtLnRvLnVwcGVyLmJvdW5kcz1cCiAgICBpbmZlcnJlZCB0eXBlIGRvZXMgbm90IGNvbmZvcm0gdG8gdXBwZXIgYm91bmQocylcblwKICAgIGluZmVycmVkOiB7MH1cblwKICAgIHVwcGVyIGJvdW5kKHMpOiB7MX0KCiMgMDogdHlwZSwgMTogbGlzdCBvZiB0eXBlCmNvbXBpbGVyLm1pc2MuaW5mZXJyZWQuZG8ubm90LmNvbmZvcm0udG8ubG93ZXIuYm91bmRzPVwKICAgIGluZmVycmVkIHR5cGUgZG9lcyBub3QgY29uZm9ybSB0byBsb3dlciBib3VuZChzKVxuXAogICAgaW5mZXJyZWQ6IHswfVxuXAogICAgbG93ZXIgYm91bmQocyk6IHsxfQoKIyAwOiB0eXBlLCAxOiBsaXN0IG9mIHR5cGUKY29tcGlsZXIubWlzYy5pbmZlcnJlZC5kby5ub3QuY29uZm9ybS50by5lcS5ib3VuZHM9XAogICAgaW5mZXJyZWQgdHlwZSBkb2VzIG5vdCBjb25mb3JtIHRvIGVxdWFsaXR5IGNvbnN0cmFpbnQocylcblwKICAgIGluZmVycmVkOiB7MH1cblwKICAgIGVxdWFsaXR5IGNvbnN0cmFpbnRzKHMpOiB7MX0KCiMgMDogc3ltYm9sCmNvbXBpbGVyLm1pc2MuZGlhbW9uZD1cCiAgICB7MH08PgoKIyAwOiB0eXBlCmNvbXBpbGVyLm1pc2MuZGlhbW9uZC5ub24uZ2VuZXJpYz1cCiAgICBjYW5ub3QgdXNlICcnPD4nJyB3aXRoIG5vbi1nZW5lcmljIGNsYXNzIHswfQoKIyAwOiBsaXN0IG9mIHR5cGUsIDE6IG1lc3NhZ2Ugc2VnbWVudApjb21waWxlci5taXNjLmRpYW1vbmQuaW52YWxpZC5hcmc9XAogICAgdHlwZSBhcmd1bWVudCB7MH0gaW5mZXJyZWQgZm9yIHsxfSBpcyBub3QgYWxsb3dlZCBpbiB0aGlzIGNvbnRleHRcblwKICAgIGluZmVycmVkIGFyZ3VtZW50IGlzIG5vdCBleHByZXNzaWJsZSBpbiB0aGUgU2lnbmF0dXJlIGF0dHJpYnV0ZQoKIyAwOiBsaXN0IG9mIHR5cGUsIDE6IG1lc3NhZ2Ugc2VnbWVudApjb21waWxlci5taXNjLmRpYW1vbmQuaW52YWxpZC5hcmdzPVwKICAgIHR5cGUgYXJndW1lbnRzIHswfSBpbmZlcnJlZCBmb3IgezF9IGFyZSBub3QgYWxsb3dlZCBpbiB0aGlzIGNvbnRleHRcblwKICAgIGluZmVycmVkIGFyZ3VtZW50cyBhcmUgbm90IGV4cHJlc3NpYmxlIGluIHRoZSBTaWduYXR1cmUgYXR0cmlidXRlCgojIDA6IHVudXNlZApjb21waWxlci5taXNjLmRpYW1vbmQuYW5kLmV4cGxpY2l0LnBhcmFtcz1cCiAgICBjYW5ub3QgdXNlICcnPD4nJyB3aXRoIGV4cGxpY2l0IHR5cGUgcGFyYW1ldGVycyBmb3IgY29uc3RydWN0b3IKCiMgMDogdW51c2VkCmNvbXBpbGVyLm1pc2MubXJlZi5pbmZlci5hbmQuZXhwbGljaXQucGFyYW1zPVwKICAgIGNhbm5vdCB1c2UgcmF3IGNvbnN0cnVjdG9yIHJlZmVyZW5jZSB3aXRoIGV4cGxpY2l0IHR5cGUgcGFyYW1ldGVycyBmb3IgY29uc3RydWN0b3IKCiMgMDogdHlwZSwgMTogbGlzdCBvZiB0eXBlCmNvbXBpbGVyLm1pc2MuZXhwbGljaXQucGFyYW0uZG8ubm90LmNvbmZvcm0udG8uYm91bmRzPVwKICAgIGV4cGxpY2l0IHR5cGUgYXJndW1lbnQgezB9IGRvZXMgbm90IGNvbmZvcm0gdG8gZGVjbGFyZWQgYm91bmQocykgezF9Cgpjb21waWxlci5taXNjLmFyZy5sZW5ndGgubWlzbWF0Y2g9XAogICAgYWN0dWFsIGFuZCBmb3JtYWwgYXJndW1lbnQgbGlzdHMgZGlmZmVyIGluIGxlbmd0aAoKIyAwOiBzdHJpbmcKY29tcGlsZXIubWlzYy53cm9uZy5udW1iZXIudHlwZS5hcmdzPVwKICAgIHdyb25nIG51bWJlciBvZiB0eXBlIGFyZ3VtZW50czsgcmVxdWlyZWQgezB9CgojIDA6IG1lc3NhZ2Ugc2VnbWVudApjb21waWxlci5taXNjLm5vLmNvbmZvcm1pbmcuYXNzaWdubWVudC5leGlzdHM9XAogICAgYXJndW1lbnQgbWlzbWF0Y2g7IHswfQoKIyAwOiBtZXNzYWdlIHNlZ21lbnQKY29tcGlsZXIubWlzYy52YXJhcmdzLmFyZ3VtZW50Lm1pc21hdGNoPVwKICAgIHZhcmFyZ3MgbWlzbWF0Y2g7IHswfQoKIyMjIyMKCiMgMDogc3ltYm9sIG9yIHR5cGUsIDE6IGZpbGUgbmFtZQpjb21waWxlci53YXJuLmF1eGlsaWFyeS5jbGFzcy5hY2Nlc3NlZC5mcm9tLm91dHNpZGUub2YuaXRzLnNvdXJjZS5maWxlPVwKICAgIGF1eGlsaWFyeSBjbGFzcyB7MH0gaW4gezF9IHNob3VsZCBub3QgYmUgYWNjZXNzZWQgZnJvbSBvdXRzaWRlIGl0cyBvd24gc291cmNlIGZpbGUKCiMjIFRoZSBmaXJzdCBhcmd1bWVudCAoezB9KSBpcyBhICJraW5kbmFtZSIuCiMgMDogc3ltYm9sIGtpbmQsIDE6IHN5bWJvbCwgMjogc3ltYm9sCmNvbXBpbGVyLmVyci5hYnN0cmFjdC5jYW50LmJlLmFjY2Vzc2VkLmRpcmVjdGx5PVwKICAgIGFic3RyYWN0IHswfSB7MX0gaW4gezJ9IGNhbm5vdCBiZSBhY2Nlc3NlZCBkaXJlY3RseQoKIyMgVGhlIGZpcnN0IGFyZ3VtZW50ICh7MH0pIGlzIGEgImtpbmRuYW1lIi4KIyAwOiBzeW1ib2wga2luZCwgMTogc3ltYm9sCmNvbXBpbGVyLmVyci5ub24tc3RhdGljLmNhbnQuYmUucmVmPVwKICAgIG5vbi1zdGF0aWMgezB9IHsxfSBjYW5ub3QgYmUgcmVmZXJlbmNlZCBmcm9tIGEgc3RhdGljIGNvbnRleHQKCiMgMDogc3ltYm9sIGtpbmQsIDE6IHN5bWJvbApjb21waWxlci5taXNjLmJhZC5zdGF0aWMubWV0aG9kLmluLnVuYm91bmQubG9va3VwPVwKICAgIHVuZXhwZWN0ZWQgc3RhdGljIHswfSB7MX0gZm91bmQgaW4gdW5ib3VuZCBsb29rdXAKCiMgMDogc3ltYm9sIGtpbmQsIDE6IHN5bWJvbApjb21waWxlci5taXNjLmJhZC5pbnN0YW5jZS5tZXRob2QuaW4udW5ib3VuZC5sb29rdXA9XAogICAgdW5leHBlY3RlZCBpbnN0YW5jZSB7MH0gezF9IGZvdW5kIGluIHVuYm91bmQgbG9va3VwCgojIDA6IHN5bWJvbCBraW5kLCAxOiBzeW1ib2wKY29tcGlsZXIubWlzYy5iYWQuc3RhdGljLm1ldGhvZC5pbi5ib3VuZC5sb29rdXA9XAogICAgdW5leHBlY3RlZCBzdGF0aWMgezB9IHsxfSBmb3VuZCBpbiBib3VuZCBsb29rdXAKCiMjIEJvdGggYXJndW1lbnRzICh7MH0sIHsxfSkgYXJlICJraW5kbmFtZSJzLiAgezB9IGlzIGEgY29tbWEtc2VwYXJhdGVkIGxpc3QKIyMgb2Yga2luZG5hbWVzICh0aGUgbGlzdCBzaG91bGQgYmUgaWRlbnRpY2FsIHRvIHRoYXQgcHJvdmlkZWQgaW4gc291cmNlLgpjb21waWxlci5lcnIudW5leHBlY3RlZC50eXBlPVwKICAgIHVuZXhwZWN0ZWQgdHlwZVxuXAogICAgcmVxdWlyZWQ6IHswfVxuXAogICAgZm91bmQ6ICAgIHsxfQoKY29tcGlsZXIuZXJyLnVuZXhwZWN0ZWQubGFtYmRhPVwKICAgbGFtYmRhIGV4cHJlc3Npb24gbm90IGV4cGVjdGVkIGhlcmUKCmNvbXBpbGVyLmVyci51bmV4cGVjdGVkLm1yZWY9XAogICBtZXRob2QgcmVmZXJlbmNlIG5vdCBleHBlY3RlZCBoZXJlCgojIyBUaGUgZmlyc3QgYXJndW1lbnQgezB9IGlzIGEgImtpbmRuYW1lIiAoZS5nLiAnY29uc3RydWN0b3InLCAnZmllbGQnLCBldGMuKQojIyBUaGUgc2Vjb25kIGFyZ3VtZW50IHsxfSBpcyB0aGUgbm9uLXJlc29sdmVkIHN5bWJvbAojIyBUaGUgdGhpcmQgYXJndW1lbnQgezJ9IGlzIGEgbGlzdCBvZiB0eXBlIHBhcmFtZXRlcnMgKG5vbi1lbXB0eSBpZiB7MX0gaXMgYSBtZXRob2QpCiMjIFRoZSBmb3VydGggYXJndW1lbnQgezN9IGlzIGEgbGlzdCBvZiBhcmd1bWVudCB0eXBlcyAobm9uLWVtcHR5IGlmIHsxfSBpcyBhIG1ldGhvZCkKIyAwOiBzeW1ib2wga2luZCwgMTogbmFtZSwgMjogdW51c2VkLCAzOiB1bnVzZWQKY29tcGlsZXIuZXJyLmNhbnQucmVzb2x2ZT1cCiAgICBjYW5ub3QgZmluZCBzeW1ib2xcblwKICAgIHN5bWJvbDogezB9IHsxfQoKIyAwOiBzeW1ib2wga2luZCwgMTogbmFtZSwgMjogdW51c2VkLCAzOiBsaXN0IG9mIHR5cGUKY29tcGlsZXIuZXJyLmNhbnQucmVzb2x2ZS5hcmdzPVwKICAgIGNhbm5vdCBmaW5kIHN5bWJvbFxuXAogICAgc3ltYm9sOiB7MH0gezF9KHszfSkKCiMgMDogc3ltYm9sIGtpbmQsIDE6IG5hbWUsIDI6IGxpc3Qgb2YgdHlwZSwgMzogbGlzdCBvZiB0eXBlCmNvbXBpbGVyLmVyci5jYW50LnJlc29sdmUuYXJncy5wYXJhbXM9XAogICAgY2Fubm90IGZpbmQgc3ltYm9sXG5cCiAgICBzeW1ib2w6IHswfSA8ezJ9PnsxfSh7M30pCgojIyBhcmd1bWVudHMgZnJvbSB7MH0gdG8gezN9IGhhdmUgdGhlIHNhbWUgbWVhbmluZyBhcyBhYm92ZQojIyBUaGUgZmlmdGggYXJndW1lbnQgezR9IGlzIGEgbG9jYXRpb24gc3ViZGlhZ25vc3RpYyAoc2VlIGJlbG93KQojIDA6IHN5bWJvbCBraW5kLCAxOiBuYW1lLCAyOiB1bnVzZWQsIDM6IHVudXNlZCwgNDogbWVzc2FnZSBzZWdtZW50CmNvbXBpbGVyLmVyci5jYW50LnJlc29sdmUubG9jYXRpb249XAogICAgY2Fubm90IGZpbmQgc3ltYm9sXG5cCiAgICBzeW1ib2w6ICAgezB9IHsxfVxuXAogICAgbG9jYXRpb246IHs0fQoKIyAwOiBzeW1ib2wga2luZCwgMTogbmFtZSwgMjogdW51c2VkLCAzOiBsaXN0IG9mIHR5cGUsIDQ6IG1lc3NhZ2Ugc2VnbWVudApjb21waWxlci5lcnIuY2FudC5yZXNvbHZlLmxvY2F0aW9uLmFyZ3M9XAogICAgY2Fubm90IGZpbmQgc3ltYm9sXG5cCiAgICBzeW1ib2w6ICAgezB9IHsxfSh7M30pXG5cCiAgICBsb2NhdGlvbjogezR9CgojIDA6IHN5bWJvbCBraW5kLCAxOiBuYW1lLCAyOiBsaXN0IG9mIHR5cGUsIDM6IGxpc3QsIDQ6IG1lc3NhZ2Ugc2VnbWVudApjb21waWxlci5lcnIuY2FudC5yZXNvbHZlLmxvY2F0aW9uLmFyZ3MucGFyYW1zPVwKICAgIGNhbm5vdCBmaW5kIHN5bWJvbFxuXAogICAgc3ltYm9sOiAgIHswfSA8ezJ9PnsxfSh7M30pXG5cCiAgICBsb2NhdGlvbjogezR9CgojIyMgRm9sbG93aW5nIGFyZSByZXBsaWNhdGVkL3VzZWQgZm9yIG1ldGhvZCByZWZlcmVuY2UgZGlhZ25vc3RpY3MKCiMgMDogc3ltYm9sIGtpbmQsIDE6IG5hbWUsIDI6IHVudXNlZCwgMzogbGlzdCBvZiB0eXBlLCA0OiBtZXNzYWdlIHNlZ21lbnQKY29tcGlsZXIubWlzYy5jYW50LnJlc29sdmUubG9jYXRpb24uYXJncz1cCiAgICBjYW5ub3QgZmluZCBzeW1ib2xcblwKICAgIHN5bWJvbDogICB7MH0gezF9KHszfSlcblwKICAgIGxvY2F0aW9uOiB7NH0KCiMgMDogc3ltYm9sIGtpbmQsIDE6IG5hbWUsIDI6IGxpc3Qgb2YgdHlwZSwgMzogbGlzdCwgNDogbWVzc2FnZSBzZWdtZW50CmNvbXBpbGVyLm1pc2MuY2FudC5yZXNvbHZlLmxvY2F0aW9uLmFyZ3MucGFyYW1zPVwKICAgIGNhbm5vdCBmaW5kIHN5bWJvbFxuXAogICAgc3ltYm9sOiAgIHswfSA8ezJ9PnsxfSh7M30pXG5cCiAgICBsb2NhdGlvbjogezR9CgojI2EgbG9jYXRpb24gc3ViZGlhZ25vc3RpYyBpcyBjb21wb3NlZCBhcyBmb2xsb3dzOgojIyBUaGUgZmlyc3QgYXJndW1lbnQgezB9IGlzIHRoZSBsb2NhdGlvbiAia2luZG5hbWUiIChlLmcuICdjb25zdHJ1Y3RvcicsICdmaWVsZCcsIGV0Yy4pCiMjIFRoZSBzZWNvbmQgYXJndW1lbnQgezF9IGlzIHRoZSBsb2NhdGlvbiBuYW1lCiMjIFRoZSB0aGlyZCBhcmd1bWVudCB7Mn0gaXMgdGhlIGxvY2F0aW9uIHR5cGUgKG9ubHkgd2hlbiB7MX0gaXMgYSB2YXJpYWJsZSBuYW1lKQoKIyAwOiBzeW1ib2wga2luZCwgMTogdHlwZSBvciBzeW1ib2wsIDI6IHVudXNlZApjb21waWxlci5taXNjLmxvY2F0aW9uPVwKICAgIHswfSB7MX0KCiMgMDogc3ltYm9sIGtpbmQsIDE6IHN5bWJvbCwgMjogdHlwZQpjb21waWxlci5taXNjLmxvY2F0aW9uLjE9XAogICAgezB9IHsxfSBvZiB0eXBlIHsyfQoKIyMgVGhlIGZvbGxvd2luZyBhcmUgYWxsIHBvc3NpYmxlIHN0cmluZyBmb3IgImtpbmRuYW1lIi4KIyMgVGhleSBzaG91bGQgYmUgY2FsbGVkIHdoYXRldmVyIHRoZSBKTFMgY2FsbHMgdGhlbSBhZnRlciBpdCBiZWVuIHRyYW5zbGF0ZWQKIyMgdG8gdGhlIGFwcHJvcHJpYXRlIGxhbmd1YWdlLgojIGNvbXBpbGVyLm1pc2Mua2luZG5hbWUuY29uc3RydWN0b3I9XAojICAgICBzdGF0aWMgbWVtYmVyCmNvbXBpbGVyLm1pc2Mua2luZG5hbWUuYW5ub3RhdGlvbj1cCiAgICBAaW50ZXJmYWNlCgpjb21waWxlci5taXNjLmtpbmRuYW1lLmNvbnN0cnVjdG9yPVwKICAgIGNvbnN0cnVjdG9yCgpjb21waWxlci5taXNjLmtpbmRuYW1lLmVudW09XAogICAgZW51bQoKY29tcGlsZXIubWlzYy5raW5kbmFtZS5pbnRlcmZhY2U9XAogICAgaW50ZXJmYWNlCgpjb21waWxlci5taXNjLmtpbmRuYW1lLnN0YXRpYz1cCiAgICBzdGF0aWMKCmNvbXBpbGVyLm1pc2Mua2luZG5hbWUudHlwZS52YXJpYWJsZT1cCiAgICB0eXBlIHZhcmlhYmxlCgpjb21waWxlci5taXNjLmtpbmRuYW1lLnR5cGUudmFyaWFibGUuYm91bmQ9XAogICAgYm91bmQgb2YgdHlwZSB2YXJpYWJsZQoKY29tcGlsZXIubWlzYy5raW5kbmFtZS52YXJpYWJsZT1cCiAgICB2YXJpYWJsZQoKY29tcGlsZXIubWlzYy5raW5kbmFtZS52YWx1ZT1cCiAgICB2YWx1ZQoKY29tcGlsZXIubWlzYy5raW5kbmFtZS5tZXRob2Q9XAogICAgbWV0aG9kCgpjb21waWxlci5taXNjLmtpbmRuYW1lLmNsYXNzPVwKICAgIGNsYXNzCgpjb21waWxlci5taXNjLmtpbmRuYW1lLnBhY2thZ2U9XAogICAgcGFja2FnZQoKY29tcGlsZXIubWlzYy5raW5kbmFtZS5tb2R1bGU9XAogICAgbW9kdWxlCgpjb21waWxlci5taXNjLmtpbmRuYW1lLnN0YXRpYy5pbml0PVwKICAgIHN0YXRpYyBpbml0aWFsaXplcgoKY29tcGlsZXIubWlzYy5raW5kbmFtZS5pbnN0YW5jZS5pbml0PVwKICAgIGluc3RhbmNlIGluaXRpYWxpemVyCgojIyMjIwoKY29tcGlsZXIubWlzYy5uby5hcmdzPVwKICAgIG5vIGFyZ3VtZW50cwoKIyAwOiBtZXNzYWdlIHNlZ21lbnQKY29tcGlsZXIuZXJyLm92ZXJyaWRlLnN0YXRpYz1cCiAgICB7MH1cblwKICAgIG92ZXJyaWRpbmcgbWV0aG9kIGlzIHN0YXRpYwoKIyAwOiBtZXNzYWdlIHNlZ21lbnQsIDE6IHNldCBvZiBtb2RpZmllcgpjb21waWxlci5lcnIub3ZlcnJpZGUubWV0aD1cCiAgICB7MH1cblwKICAgIG92ZXJyaWRkZW4gbWV0aG9kIGlzIHsxfQoKIyAwOiBtZXNzYWdlIHNlZ21lbnQsIDE6IHR5cGUKY29tcGlsZXIuZXJyLm92ZXJyaWRlLm1ldGguZG9lc250LnRocm93PVwKICAgIHswfVxuXAogICAgb3ZlcnJpZGRlbiBtZXRob2QgZG9lcyBub3QgdGhyb3cgezF9CgojIEluIHRoZSBmb2xsb3dpbmcgc3RyaW5nIHsxfSBpcyBhIHNwYWNlIHNlcGFyYXRlZCBsaXN0IG9mIEphdmEgS2V5d29yZHMsIGFzCiMgdGhleSB3b3VsZCBoYXZlIGJlZW4gZGVjbGFyZWQgaW4gdGhlIHNvdXJjZSBjb2RlCiMgMDogbWVzc2FnZSBzZWdtZW50LCAxOiBzZXQgb2YgbW9kaWZpZXIKY29tcGlsZXIuZXJyLm92ZXJyaWRlLndlYWtlci5hY2Nlc3M9XAogICAgezB9XG5cCiAgICBhdHRlbXB0aW5nIHRvIGFzc2lnbiB3ZWFrZXIgYWNjZXNzIHByaXZpbGVnZXM7IHdhcyB7MX0KCiMgMDogbWVzc2FnZSBzZWdtZW50LCAxOiB0eXBlLCAyOiB0eXBlCmNvbXBpbGVyLmVyci5vdmVycmlkZS5pbmNvbXBhdGlibGUucmV0PVwKICAgIHswfVxuXAogICAgcmV0dXJuIHR5cGUgezF9IGlzIG5vdCBjb21wYXRpYmxlIHdpdGggezJ9CgojIDA6IG1lc3NhZ2Ugc2VnbWVudCwgMTogdHlwZSwgMjogdHlwZQpjb21waWxlci53YXJuLm92ZXJyaWRlLnVuY2hlY2tlZC5yZXQ9XAogICAgezB9XG5cCiAgICByZXR1cm4gdHlwZSByZXF1aXJlcyB1bmNoZWNrZWQgY29udmVyc2lvbiBmcm9tIHsxfSB0byB7Mn0KCiMgMDogbWVzc2FnZSBzZWdtZW50LCAxOiB0eXBlCmNvbXBpbGVyLndhcm4ub3ZlcnJpZGUudW5jaGVja2VkLnRocm93bj1cCiAgICB7MH1cblwKICAgIG92ZXJyaWRkZW4gbWV0aG9kIGRvZXMgbm90IHRocm93IHsxfQoKIyAwOiBzeW1ib2wKY29tcGlsZXIud2Fybi5vdmVycmlkZS5lcXVhbHMuYnV0Lm5vdC5oYXNoY29kZT1cCiAgICBDbGFzcyB7MH0gb3ZlcnJpZGVzIGVxdWFscywgYnV0IG5laXRoZXIgaXQgbm9yIGFueSBzdXBlcmNsYXNzIG92ZXJyaWRlcyBoYXNoQ29kZSBtZXRob2QKCiMjIFRoZSBmb2xsb3dpbmcgYXJlIGFsbCBwb3NzaWJsZSBzdHJpbmdzIGZvciB0aGUgZmlyc3QgYXJndW1lbnQgKHswfSkgb2YgdGhlCiMjIGFib3ZlIHN0cmluZ3MuCiMgMDogc3ltYm9sLCAxOiBzeW1ib2wsIDI6IHN5bWJvbCwgMzogc3ltYm9sCmNvbXBpbGVyLm1pc2MuY2FudC5vdmVycmlkZT1cCiAgICB7MH0gaW4gezF9IGNhbm5vdCBvdmVycmlkZSB7Mn0gaW4gezN9CgojIDA6IHN5bWJvbCwgMTogc3ltYm9sLCAyOiBzeW1ib2wsIDM6IHN5bWJvbApjb21waWxlci5taXNjLmNhbnQuaGlkZT1cCiAgICB7MH0gaW4gezF9IGNhbm5vdCBoaWRlIHsyfSBpbiB7M30KCiMgMDogc3ltYm9sLCAxOiBzeW1ib2wsIDI6IHN5bWJvbCwgMzogc3ltYm9sCmNvbXBpbGVyLm1pc2MuY2FudC5pbXBsZW1lbnQ9XAogICAgezB9IGluIHsxfSBjYW5ub3QgaW1wbGVtZW50IHsyfSBpbiB7M30KCiMgMDogc3ltYm9sLCAxOiBzeW1ib2wsIDI6IHN5bWJvbCwgMzogc3ltYm9sCmNvbXBpbGVyLm1pc2MuY2xhc2hlcy53aXRoPVwKICAgIHswfSBpbiB7MX0gY2xhc2hlcyB3aXRoIHsyfSBpbiB7M30KCiMgMDogc3ltYm9sLCAxOiBzeW1ib2wsIDI6IHN5bWJvbCwgMzogc3ltYm9sCmNvbXBpbGVyLm1pc2MudW5jaGVja2VkLm92ZXJyaWRlPVwKICAgIHswfSBpbiB7MX0gb3ZlcnJpZGVzIHsyfSBpbiB7M30KCiMgMDogc3ltYm9sLCAxOiBzeW1ib2wsIDI6IHN5bWJvbCwgMzogc3ltYm9sCmNvbXBpbGVyLm1pc2MudW5jaGVja2VkLmltcGxlbWVudD1cCiAgICB7MH0gaW4gezF9IGltcGxlbWVudHMgezJ9IGluIHszfQoKIyAwOiBzeW1ib2wsIDE6IHN5bWJvbCwgMjogc3ltYm9sLCAzOiBzeW1ib2wKY29tcGlsZXIubWlzYy51bmNoZWNrZWQuY2xhc2gud2l0aD1cCiAgICB7MH0gaW4gezF9IG92ZXJyaWRlcyB7Mn0gaW4gezN9CgojIDA6IHN5bWJvbCwgMTogc3ltYm9sLCAyOiBzeW1ib2wsIDM6IHN5bWJvbApjb21waWxlci5taXNjLnZhcmFyZ3Mub3ZlcnJpZGU9XAogICAgezB9IGluIHsxfSBvdmVycmlkZXMgezJ9IGluIHszfQoKIyAwOiBzeW1ib2wsIDE6IHN5bWJvbCwgMjogc3ltYm9sLCAzOiBzeW1ib2wKY29tcGlsZXIubWlzYy52YXJhcmdzLmltcGxlbWVudD1cCiAgICB7MH0gaW4gezF9IGltcGxlbWVudHMgezJ9IGluIHszfQoKIyAwOiBzeW1ib2wsIDE6IHN5bWJvbCwgMjogc3ltYm9sLCAzOiBzeW1ib2wKY29tcGlsZXIubWlzYy52YXJhcmdzLmNsYXNoLndpdGg9XAogICAgezB9IGluIHsxfSBvdmVycmlkZXMgezJ9IGluIHszfQoKIyAwOiBzeW1ib2wga2luZCwgMTogc3ltYm9sLCAyOiBzeW1ib2wsIDM6IG1lc3NhZ2Ugc2VnbWVudApjb21waWxlci5taXNjLmluYXBwbGljYWJsZS5tZXRob2Q9XAogICAgezB9IHsxfS57Mn0gaXMgbm90IGFwcGxpY2FibGVcblwKICAgICh7M30pCgojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCiMgRGlhZ25vc3RpY3MgZm9yIGxhbmd1YWdlIGZlYXR1cmUgY2hhbmdlcwojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCgojIDA6IHN0cmluZwpjb21waWxlci5lcnIubW9kdWxlcy5ub3Quc3VwcG9ydGVkLmluLnNvdXJjZT1cCiAgIG1vZHVsZXMgYXJlIG5vdCBzdXBwb3J0ZWQgaW4gLXNvdXJjZSB7MH1cblwKICAgICh1c2UgLXNvdXJjZSA5IG9yIGhpZ2hlciB0byBlbmFibGUgbW9kdWxlcykKCiMgMDogc3RyaW5nCmNvbXBpbGVyLm1pc2MuZGlhbW9uZC5hbmQuYW5vbi5jbGFzcy5ub3Quc3VwcG9ydGVkLmluLnNvdXJjZT1cCiAgICBjYW5ub3QgdXNlICcnPD4nJyB3aXRoIGFub255bW91cyBpbm5lciBjbGFzc2VzIGluIC1zb3VyY2UgezB9XG5cCiAgICAodXNlIC1zb3VyY2UgOSBvciBoaWdoZXIgdG8gZW5hYmxlICcnPD4nJyB3aXRoIGFub255bW91cyBpbm5lciBjbGFzc2VzKQoKIyAwOiBzdHJpbmcKY29tcGlsZXIuZXJyLnVuc3VwcG9ydGVkLmJpbmFyeS5saXQ9XAogICAgYmluYXJ5IGxpdGVyYWxzIGFyZSBub3Qgc3VwcG9ydGVkIGluIC1zb3VyY2UgezB9XG5cCiAgICAodXNlIC1zb3VyY2UgNyBvciBoaWdoZXIgdG8gZW5hYmxlIGJpbmFyeSBsaXRlcmFscykKCiMgMDogc3RyaW5nCmNvbXBpbGVyLmVyci51bnN1cHBvcnRlZC51bmRlcnNjb3JlLmxpdD1cCiAgICB1bmRlcnNjb3JlcyBpbiBsaXRlcmFscyBhcmUgbm90IHN1cHBvcnRlZCBpbiAtc291cmNlIHswfVxuXAogICAgKHVzZSAtc291cmNlIDcgb3IgaGlnaGVyIHRvIGVuYWJsZSB1bmRlcnNjb3JlcyBpbiBsaXRlcmFscykKCiMgMDogc3RyaW5nCmNvbXBpbGVyLmVyci50cnkud2l0aC5yZXNvdXJjZXMubm90LnN1cHBvcnRlZC5pbi5zb3VyY2U9XAogICAgdHJ5LXdpdGgtcmVzb3VyY2VzIGlzIG5vdCBzdXBwb3J0ZWQgaW4gLXNvdXJjZSB7MH1cblwKICAgICh1c2UgLXNvdXJjZSA3IG9yIGhpZ2hlciB0byBlbmFibGUgdHJ5LXdpdGgtcmVzb3VyY2VzKQoKIyAwOiBzdHJpbmcKY29tcGlsZXIuZXJyLnZhci5pbi50cnkud2l0aC5yZXNvdXJjZXMubm90LnN1cHBvcnRlZC5pbi5zb3VyY2U9XAogICAgdmFyaWFibGVzIGluIHRyeS13aXRoLXJlc291cmNlcyBub3Qgc3VwcG9ydGVkIGluIC1zb3VyY2UgezB9XG5cCiAgICAodXNlIC1zb3VyY2UgOSBvciBoaWdoZXIgdG8gZW5hYmxlIHZhcmlhYmxlcyBpbiB0cnktd2l0aC1yZXNvdXJjZXMpCgpjb21waWxlci53YXJuLnVuZGVyc2NvcmUuYXMuaWRlbnRpZmllcj1cCiAgICBhcyBvZiByZWxlYXNlIDksICcnXycnIGlzIGEga2V5d29yZCwgYW5kIG1heSBub3QgYmUgdXNlZCBhcyBhbiBpZGVudGlmaWVyCgpjb21waWxlci5lcnIudW5kZXJzY29yZS5hcy5pZGVudGlmaWVyPVwKICAgIGFzIG9mIHJlbGVhc2UgOSwgJydfJycgaXMgYSBrZXl3b3JkLCBhbmQgbWF5IG5vdCBiZSB1c2VkIGFzIGFuIGlkZW50aWZpZXIKCmNvbXBpbGVyLmVyci51bmRlcnNjb3JlLmFzLmlkZW50aWZpZXIuaW4ubGFtYmRhPVwKICAgICcnXycnIHVzZWQgYXMgYW4gaWRlbnRpZmllclxuXAogICAgKHVzZSBvZiAnJ18nJyBhcyBhbiBpZGVudGlmaWVyIGlzIGZvcmJpZGRlbiBmb3IgbGFtYmRhIHBhcmFtZXRlcnMpCgpjb21waWxlci5lcnIuZW51bS5hcy5pZGVudGlmaWVyPVwKICAgIGFzIG9mIHJlbGVhc2UgNSwgJydlbnVtJycgaXMgYSBrZXl3b3JkLCBhbmQgbWF5IG5vdCBiZSB1c2VkIGFzIGFuIGlkZW50aWZpZXIKCmNvbXBpbGVyLmVyci5hc3NlcnQuYXMuaWRlbnRpZmllcj1cCiAgICBhcyBvZiByZWxlYXNlIDEuNCwgJydhc3NlcnQnJyBpcyBhIGtleXdvcmQsIGFuZCBtYXkgbm90IGJlIHVzZWQgYXMgYW4gaWRlbnRpZmllcgoKIyBUT0RPIDMwODogbWFrZSBhIGJldHRlciBlcnJvciBtZXNzYWdlCmNvbXBpbGVyLmVyci50aGlzLmFzLmlkZW50aWZpZXI9XAogICAgYXMgb2YgcmVsZWFzZSA4LCAnJ3RoaXMnJyBpcyBhbGxvd2VkIGFzIHRoZSBwYXJhbWV0ZXIgbmFtZSBmb3IgdGhlIHJlY2VpdmVyIHR5cGUgb25seSwgd2hpY2ggaGFzIHRvIGJlIHRoZSBmaXJzdCBwYXJhbWV0ZXIKCiMgMDogc3ltYm9sCmNvbXBpbGVyLmVyci5yZWNlaXZlci5wYXJhbWV0ZXIubm90LmFwcGxpY2FibGUuY29uc3RydWN0b3IudG9wbGV2ZWwuY2xhc3M9XAogICAgcmVjZWl2ZXIgcGFyYW1ldGVyIG5vdCBhcHBsaWNhYmxlIGZvciBjb25zdHJ1Y3RvciBvZiB0b3AtbGV2ZWwgY2xhc3MKCiMgVE9ETyAzMDg6IG1ha2UgYSBiZXR0ZXIgZXJyb3IgbWVzc2FnZQojIDA6IHN5bWJvbApjb21waWxlci5lcnIuY2FudC50eXBlLmFubm90YXRlLnNjb3BpbmcuMT1cCiAgICBzY29waW5nIGNvbnN0cnVjdCBjYW5ub3QgYmUgYW5ub3RhdGVkIHdpdGggdHlwZS11c2UgYW5ub3RhdGlvbjogezB9CgojIFRPRE8gMzA4OiBtYWtlIGEgYmV0dGVyIGVycm9yIG1lc3NhZ2UKIyAwOiBsaXN0IG9mIHN5bWJvbApjb21waWxlci5lcnIuY2FudC50eXBlLmFubm90YXRlLnNjb3Bpbmc9XAogICAgc2NvcGluZyBjb25zdHJ1Y3QgY2Fubm90IGJlIGFubm90YXRlZCB3aXRoIHR5cGUtdXNlIGFubm90YXRpb25zOiB7MH0KCiMgMDogdHlwZSwgMTogdHlwZQpjb21waWxlci5lcnIuaW5jb3JyZWN0LnJlY2VpdmVyLm5hbWU9XAogICAgdGhlIHJlY2VpdmVyIG5hbWUgZG9lcyBub3QgbWF0Y2ggdGhlIGVuY2xvc2luZyBjbGFzcyB0eXBlXG5cCiAgICByZXF1aXJlZDogezB9XG5cCiAgICBmb3VuZDogezF9CgojIDA6IHR5cGUsIDE6IHR5cGUKY29tcGlsZXIuZXJyLmluY29ycmVjdC5yZWNlaXZlci50eXBlPVwKICAgIHRoZSByZWNlaXZlciB0eXBlIGRvZXMgbm90IG1hdGNoIHRoZSBlbmNsb3NpbmcgY2xhc3MgdHlwZVxuXAogICAgcmVxdWlyZWQ6IHswfVxuXAogICAgZm91bmQ6IHsxfQoKIyAwOiB0eXBlLCAxOiB0eXBlCmNvbXBpbGVyLmVyci5pbmNvcnJlY3QuY29uc3RydWN0b3IucmVjZWl2ZXIudHlwZT1cCiAgICB0aGUgcmVjZWl2ZXIgdHlwZSBkb2VzIG5vdCBtYXRjaCB0aGUgZW5jbG9zaW5nIG91dGVyIGNsYXNzIHR5cGVcblwKICAgIHJlcXVpcmVkOiB7MH1cblwKICAgIGZvdW5kOiB7MX0KCiMgMDogdHlwZSwgMTogdHlwZQpjb21waWxlci5lcnIuaW5jb3JyZWN0LmNvbnN0cnVjdG9yLnJlY2VpdmVyLm5hbWU9XAogICAgdGhlIHJlY2VpdmVyIG5hbWUgZG9lcyBub3QgbWF0Y2ggdGhlIGVuY2xvc2luZyBvdXRlciBjbGFzcyB0eXBlXG5cCiAgICByZXF1aXJlZDogezB9XG5cCiAgICBmb3VuZDogezF9Cgpjb21waWxlci5lcnIubm8uYW5ub3RhdGlvbnMub24uZG90LmNsYXNzPVwKICAgIG5vIGFubm90YXRpb25zIGFyZSBhbGxvd2VkIGluIHRoZSB0eXBlIG9mIGEgY2xhc3MgbGl0ZXJhbAoKIyAwOiBzdHJpbmcKY29tcGlsZXIuZXJyLnR5cGUuYW5ub3RhdGlvbnMubm90LnN1cHBvcnRlZC5pbi5zb3VyY2U9XAogICAgdHlwZSBhbm5vdGF0aW9ucyBhcmUgbm90IHN1cHBvcnRlZCBpbiAtc291cmNlIHswfVxuXAoodXNlIC1zb3VyY2UgOCBvciBoaWdoZXIgdG8gZW5hYmxlIHR5cGUgYW5ub3RhdGlvbnMpCgojIDA6IHN0cmluZwpjb21waWxlci5lcnIuYW5ub3RhdGlvbnMuYWZ0ZXIudHlwZS5wYXJhbXMubm90LnN1cHBvcnRlZC5pbi5zb3VyY2U9XAogICAgYW5ub3RhdGlvbnMgYWZ0ZXIgbWV0aG9kIHR5cGUgcGFyYW1ldGVycyBhcmUgbm90IHN1cHBvcnRlZCBpbiAtc291cmNlIHswfVxuXAoodXNlIC1zb3VyY2UgOCBvciBoaWdoZXIgdG8gZW5hYmxlIGFubm90YXRpb25zIGFmdGVyIG1ldGhvZCB0eXBlIHBhcmFtZXRlcnMpCgojIDA6IHN0cmluZwpjb21waWxlci5lcnIucmVwZWF0YWJsZS5hbm5vdGF0aW9ucy5ub3Quc3VwcG9ydGVkLmluLnNvdXJjZT1cCiAgICByZXBlYXRlZCBhbm5vdGF0aW9ucyBhcmUgbm90IHN1cHBvcnRlZCBpbiAtc291cmNlIHswfVxuXAoodXNlIC1zb3VyY2UgOCBvciBoaWdoZXIgdG8gZW5hYmxlIHJlcGVhdGVkIGFubm90YXRpb25zKQoKIyAwOiBzdHJpbmcKY29tcGlsZXIuZXJyLmRpYW1vbmQubm90LnN1cHBvcnRlZC5pbi5zb3VyY2U9XAogICAgZGlhbW9uZCBvcGVyYXRvciBpcyBub3Qgc3VwcG9ydGVkIGluIC1zb3VyY2UgezB9XG5cCiAgICAodXNlIC1zb3VyY2UgNyBvciBoaWdoZXIgdG8gZW5hYmxlIGRpYW1vbmQgb3BlcmF0b3IpCgojIDA6IHN0cmluZwpjb21waWxlci5lcnIubXVsdGljYXRjaC5ub3Quc3VwcG9ydGVkLmluLnNvdXJjZT1cCiAgICBtdWx0aS1jYXRjaCBzdGF0ZW1lbnQgaXMgbm90IHN1cHBvcnRlZCBpbiAtc291cmNlIHswfVxuXAogICAgKHVzZSAtc291cmNlIDcgb3IgaGlnaGVyIHRvIGVuYWJsZSBtdWx0aS1jYXRjaCBzdGF0ZW1lbnQpCgojIDA6IHN0cmluZwpjb21waWxlci5lcnIuc3RyaW5nLnN3aXRjaC5ub3Quc3VwcG9ydGVkLmluLnNvdXJjZT1cCiAgICBzdHJpbmdzIGluIHN3aXRjaCBhcmUgbm90IHN1cHBvcnRlZCBpbiAtc291cmNlIHswfVxuXAogICAgKHVzZSAtc291cmNlIDcgb3IgaGlnaGVyIHRvIGVuYWJsZSBzdHJpbmdzIGluIHN3aXRjaCkKCiMgMDogc3RyaW5nCmNvbXBpbGVyLmVyci5sYW1iZGEubm90LnN1cHBvcnRlZC5pbi5zb3VyY2U9XAogICAgbGFtYmRhIGV4cHJlc3Npb25zIGFyZSBub3Qgc3VwcG9ydGVkIGluIC1zb3VyY2UgezB9XG5cCiAgICAodXNlIC1zb3VyY2UgOCBvciBoaWdoZXIgdG8gZW5hYmxlIGxhbWJkYSBleHByZXNzaW9ucykKCiMgMDogc3RyaW5nCmNvbXBpbGVyLmVyci5tZXRob2QucmVmZXJlbmNlcy5ub3Quc3VwcG9ydGVkLmluLnNvdXJjZT1cCiAgICBtZXRob2QgcmVmZXJlbmNlcyBhcmUgbm90IHN1cHBvcnRlZCBpbiAtc291cmNlIHswfVxuXAogICAgKHVzZSAtc291cmNlIDggb3IgaGlnaGVyIHRvIGVuYWJsZSBtZXRob2QgcmVmZXJlbmNlcykKCiMgMDogc3RyaW5nCmNvbXBpbGVyLmVyci5kZWZhdWx0Lm1ldGhvZHMubm90LnN1cHBvcnRlZC5pbi5zb3VyY2U9XAogICAgZGVmYXVsdCBtZXRob2RzIGFyZSBub3Qgc3VwcG9ydGVkIGluIC1zb3VyY2UgezB9XG5cCiAgICAodXNlIC1zb3VyY2UgOCBvciBoaWdoZXIgdG8gZW5hYmxlIGRlZmF1bHQgbWV0aG9kcykKCiMgMDogc3RyaW5nCmNvbXBpbGVyLmVyci5pbnRlcnNlY3Rpb24udHlwZXMuaW4uY2FzdC5ub3Quc3VwcG9ydGVkLmluLnNvdXJjZT1cCiAgICBpbnRlcnNlY3Rpb24gdHlwZXMgaW4gY2FzdCBhcmUgbm90IHN1cHBvcnRlZCBpbiAtc291cmNlIHswfVxuXAogICAgKHVzZSAtc291cmNlIDggb3IgaGlnaGVyIHRvIGVuYWJsZSBpbnRlcnNlY3Rpb24gdHlwZXMgaW4gY2FzdCkKCiMgMDogc3RyaW5nCmNvbXBpbGVyLmVyci5zdGF0aWMuaW50Zi5tZXRob2RzLm5vdC5zdXBwb3J0ZWQuaW4uc291cmNlPVwKICAgIHN0YXRpYyBpbnRlcmZhY2UgbWV0aG9kcyBhcmUgbm90IHN1cHBvcnRlZCBpbiAtc291cmNlIHswfVxuXAogICAgKHVzZSAtc291cmNlIDggb3IgaGlnaGVyIHRvIGVuYWJsZSBzdGF0aWMgaW50ZXJmYWNlIG1ldGhvZHMpCgojIDA6IHN0cmluZwpjb21waWxlci5lcnIuc3RhdGljLmludGYubWV0aG9kLmludm9rZS5ub3Quc3VwcG9ydGVkLmluLnNvdXJjZT1cCiAgICBzdGF0aWMgaW50ZXJmYWNlIG1ldGhvZCBpbnZvY2F0aW9ucyBhcmUgbm90IHN1cHBvcnRlZCBpbiAtc291cmNlIHswfVxuXAogICAgKHVzZSAtc291cmNlIDggb3IgaGlnaGVyIHRvIGVuYWJsZSBzdGF0aWMgaW50ZXJmYWNlIG1ldGhvZCBpbnZvY2F0aW9ucykKCiMgMDogc3RyaW5nCmNvbXBpbGVyLmVyci5wcml2YXRlLmludGYubWV0aG9kcy5ub3Quc3VwcG9ydGVkLmluLnNvdXJjZT1cCiAgICBwcml2YXRlIGludGVyZmFjZSBtZXRob2RzIGFyZSBub3Qgc3VwcG9ydGVkIGluIC1zb3VyY2UgezB9XG5cCiAgICAodXNlIC1zb3VyY2UgOSBvciBoaWdoZXIgdG8gZW5hYmxlIHByaXZhdGUgaW50ZXJmYWNlIG1ldGhvZHMpCgojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCiMgRGlhZ25vc3RpY3MgZm9yIHZlcmJvc2UgcmVzb2x1dGlvbgojIHVzZWQgYnkgUmVzb2x2ZSAoZGVidWcgb25seSkKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwoKIyAwOiBudW1iZXIsIDE6IHN5bWJvbCwgMjogdW51c2VkCmNvbXBpbGVyLm1pc2MuYXBwbGljYWJsZS5tZXRob2QuZm91bmQ9XAogICAgI3swfSBhcHBsaWNhYmxlIG1ldGhvZCBmb3VuZDogezF9CgojIDA6IG51bWJlciwgMTogc3ltYm9sLCAyOiBtZXNzYWdlIHNlZ21lbnQKY29tcGlsZXIubWlzYy5hcHBsaWNhYmxlLm1ldGhvZC5mb3VuZC4xPVwKICAgICN7MH0gYXBwbGljYWJsZSBtZXRob2QgZm91bmQ6IHsxfVxuXAogICAgKHsyfSkKCiMgMDogbnVtYmVyLCAxOiBzeW1ib2wsIDI6IG1lc3NhZ2Ugc2VnbWVudApjb21waWxlci5taXNjLm5vdC5hcHBsaWNhYmxlLm1ldGhvZC5mb3VuZD1cCiAgICAjezB9IG5vdCBhcHBsaWNhYmxlIG1ldGhvZCBmb3VuZDogezF9XG5cCiAgICAoezJ9KQoKIyAwOiB0eXBlCmNvbXBpbGVyLm1pc2MucGFydGlhbC5pbnN0LnNpZz1cCiAgICBwYXJ0aWFsbHkgaW5zdGFudGlhdGVkIHRvOiB7MH0KCiMgMDogbmFtZSwgMTogc3ltYm9sLCAyOiBudW1iZXIsIDM6IHN0cmluZyAobWV0aG9kIHJlc29sdXRpb24gcGhhc2UpLCA0OiBsaXN0IG9mIHR5cGUgb3IgbWVzc2FnZSBzZWdtZW50LCA1OiBsaXN0IG9mIHR5cGUgb3IgbWVzc2FnZSBzZWdtZW50CmNvbXBpbGVyLm5vdGUudmVyYm9zZS5yZXNvbHZlLm11bHRpPVwKICAgIHJlc29sdmluZyBtZXRob2QgezB9IGluIHR5cGUgezF9IHRvIGNhbmRpZGF0ZSB7Mn1cblwKICAgIHBoYXNlOiB7M31cblwKICAgIHdpdGggYWN0dWFsczogezR9XG5cCiAgICB3aXRoIHR5cGUtYXJnczogezV9XG5cCiAgICBjYW5kaWRhdGVzOgoKIyAwOiBuYW1lLCAxOiBzeW1ib2wsIDI6IHVudXNlZCwgMzogc3RyaW5nIChtZXRob2QgcmVzb2x1dGlvbiBwaGFzZSksIDQ6IGxpc3Qgb2YgdHlwZSBvciBtZXNzYWdlIHNlZ21lbnQsIDU6IGxpc3Qgb2YgdHlwZSBvciBtZXNzYWdlIHNlZ21lbnQKY29tcGlsZXIubm90ZS52ZXJib3NlLnJlc29sdmUubXVsdGkuMT1cCiAgICBlcnJvbmVvdXMgcmVzb2x1dGlvbiBmb3IgbWV0aG9kIHswfSBpbiB0eXBlIHsxfVxuXAogICAgcGhhc2U6IHszfVxuXAogICAgd2l0aCBhY3R1YWxzOiB7NH1cblwKICAgIHdpdGggdHlwZS1hcmdzOiB7NX1cblwKICAgIGNhbmRpZGF0ZXM6CgojIDA6IHN5bWJvbCwgMTogdHlwZSwgMjogdHlwZQpjb21waWxlci5ub3RlLmRlZmVycmVkLm1ldGhvZC5pbnN0PVwKICAgIERlZmVycmVkIGluc3RhbnRpYXRpb24gb2YgbWV0aG9kIHswfVxuXAogICAgaW5zdGFudGlhdGVkIHNpZ25hdHVyZTogezF9XG5cCiAgICB0YXJnZXQtdHlwZTogezJ9CgojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCiMgRGlhZ25vc3RpY3MgZm9yIHdoZXJlIGNsYXVzZSBpbXBsZW1lbnRhdGlvbgojIHVzZWQgYnkgdGhlIFJpY2hEaWFnbm9zdGljRm9ybWF0dGVyLgojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCgpjb21waWxlci5taXNjLnR5cGUubnVsbD1cCiAgICA8bnVsbD4KCiMgWCNuICh3aGVyZSBuIGlzIGFuIGludCBpZCkgaXMgZGlzYW1iaWd1YXRlZCB0dmFyIG5hbWUKIyAwOiBuYW1lLCAxOiBudW1iZXIKY29tcGlsZXIubWlzYy50eXBlLnZhcj1cCiAgICB7MH0jezF9CgojIENBUCNuICh3aGVyZSBuIGlzIGFuIGludCBpZCkgaXMgYW4gYWJicmV2aWF0aW9uIGZvciAnY2FwdHVyZWQgdHlwZScKIyAwOiBudW1iZXIKY29tcGlsZXIubWlzYy5jYXB0dXJlZC50eXBlPVwKICAgIENBUCN7MH0KCiMgPElOVCNuPiAod2hlcmUgbiBpcyBhbiBpbnQgaWQpIGlzIGFuIGFiYnJldmlhdGlvbiBmb3IgJ2ludGVyc2VjdGlvbiB0eXBlJwojIDA6IG51bWJlcgpjb21waWxlci5taXNjLmludGVyc2VjdGlvbi50eXBlPVwKICAgIElOVCN7MH0KCiMgd2hlcmUgY2xhdXNlIGZvciBjYXB0dXJlZCB0eXBlOiBjb250YWlucyB1cHBlciAoJ2V4dGVuZHMgezF9JykgYW5kIGxvd2VyCiMgKCdzdXBlciB7Mn0nKSBib3VuZCBhbG9uZyB3aXRoIHRoZSB3aWxkY2FyZCB0aGF0IGdlbmVyYXRlZCB0aGlzIGNhcHR1cmVkIHR5cGUgKHszfSkKIyAwOiB0eXBlLCAxOiB0eXBlLCAyOiB0eXBlLCAzOiB0eXBlCmNvbXBpbGVyLm1pc2Mud2hlcmUuY2FwdHVyZWQ9XAogICAgezB9IGV4dGVuZHMgezF9IHN1cGVyOiB7Mn0gZnJvbSBjYXB0dXJlIG9mIHszfQoKIyBjb21wYWN0IHdoZXJlIGNsYXVzZSBmb3IgY2FwdHVyZWQgdHlwZTogY29udGFpbnMgdXBwZXIgKCdleHRlbmRzIHsxfScpIGFsb25nCiMgd2l0aCB0aGUgd2lsZGNhcmQgdGhhdCBnZW5lcmF0ZWQgdGhpcyBjYXB0dXJlZCB0eXBlICh7M30pCiMgMDogdHlwZSwgMTogdHlwZSwgMjogdW51c2VkLCAzOiB0eXBlCmNvbXBpbGVyLm1pc2Mud2hlcmUuY2FwdHVyZWQuMT1cCiAgICB7MH0gZXh0ZW5kcyB7MX0gZnJvbSBjYXB0dXJlIG9mIHszfQoKIyB3aGVyZSBjbGF1c2UgZm9yIHR5cGUgdmFyaWFibGU6IGNvbnRhaW5zIHVwcGVyIGJvdW5kKHMpICgnZXh0ZW5kcyB7MX0nKSBhbG9uZyB3aXRoCiMgdGhlIGtpbmRuYW1lICh7Mn0pIGFuZCBsb2NhdGlvbiAoezN9KSBpbiB3aGljaCB0aGUgdHlwZXZhciBoYXMgYmVlbiBkZWNsYXJlZAojIDA6IHR5cGUsIDE6IGxpc3Qgb2YgdHlwZSwgMjogc3ltYm9sIGtpbmQsIDM6IHN5bWJvbApjb21waWxlci5taXNjLndoZXJlLnR5cGV2YXI9XAogICAgezB9IGV4dGVuZHMgezF9IGRlY2xhcmVkIGluIHsyfSB7M30KCiMgY29tcGFjdCB3aGVyZSBjbGF1c2UgZm9yIHR5cGUgdmFyaWFibGU6IGNvbnRhaW5zIHRoZSBraW5kbmFtZSAoezJ9KSBhbmQgbG9jYXRpb24gKHszfSkKIyBpbiB3aGljaCB0aGUgdHlwZXZhciBoYXMgYmVlbiBkZWNsYXJlZAojIDA6IHR5cGUsIDE6IGxpc3Qgb2YgdHlwZSwgMjogc3ltYm9sIGtpbmQsIDM6IHN5bWJvbApjb21waWxlci5taXNjLndoZXJlLnR5cGV2YXIuMT1cCiAgICB7MH0gZGVjbGFyZWQgaW4gezJ9IHszfQoKIyB3aGVyZSBjbGF1c2UgZm9yIGZyZXNoIHR5cGUgdmFyaWFibGU6IGNvbnRhaW5zIHVwcGVyIGJvdW5kKHMpICgnZXh0ZW5kcyB7MX0nKS4KIyBTaW5jZSBhIGZyZXNoIHR5cGUtdmFyaWFibGUgaXMgc3ludGhldGljIC0gdGhlcmUncyBubyBsb2NhdGlvbi9raW5kbmFtZSBoZXJlLgojIDA6IHR5cGUsIDE6IGxpc3Qgb2YgdHlwZQpjb21waWxlci5taXNjLndoZXJlLmZyZXNoLnR5cGV2YXI9XAogICAgezB9IGV4dGVuZHMgezF9CgojIHdoZXJlIGNsYXVzZSBmb3IgdHlwZSB2YXJpYWJsZTogY29udGFpbnMgYWxsIHRoZSB1cHBlciBib3VuZChzKSAoJ2V4dGVuZHMgezF9JykKIyBvZiB0aGlzIGludGVyc2VjdGlvbiB0eXBlCiMgMDogdHlwZSwgMTogbGlzdCBvZiB0eXBlCmNvbXBpbGVyLm1pc2Mud2hlcmUuaW50ZXJzZWN0aW9uPVwKICAgIHswfSBleHRlbmRzIHsxfQoKIyMjIFdoZXJlIGNsYXVzZSBoZWFkZXJzICMjIwpjb21waWxlci5taXNjLndoZXJlLmRlc2NyaXB0aW9uLmNhcHR1cmVkPVwKICAgIHdoZXJlIHswfSBpcyBhIGZyZXNoIHR5cGUtdmFyaWFibGU6CgojIDA6IHNldCBvZiB0eXBlCmNvbXBpbGVyLm1pc2Mud2hlcmUuZGVzY3JpcHRpb24udHlwZXZhcj1cCiAgICB3aGVyZSB7MH0gaXMgYSB0eXBlLXZhcmlhYmxlOgoKIyAwOiBzZXQgb2YgdHlwZQpjb21waWxlci5taXNjLndoZXJlLmRlc2NyaXB0aW9uLmludGVyc2VjdGlvbj1cCiAgICB3aGVyZSB7MH0gaXMgYW4gaW50ZXJzZWN0aW9uIHR5cGU6CgojIDA6IHNldCBvZiB0eXBlCmNvbXBpbGVyLm1pc2Mud2hlcmUuZGVzY3JpcHRpb24uY2FwdHVyZWQuMT1cCiAgICB3aGVyZSB7MH0gYXJlIGZyZXNoIHR5cGUtdmFyaWFibGVzOgoKIyAwOiBzZXQgb2YgdHlwZQpjb21waWxlci5taXNjLndoZXJlLmRlc2NyaXB0aW9uLnR5cGV2YXIuMT1cCiAgICB3aGVyZSB7MH0gYXJlIHR5cGUtdmFyaWFibGVzOgoKIyAwOiBzZXQgb2YgdHlwZQpjb21waWxlci5taXNjLndoZXJlLmRlc2NyaXB0aW9uLmludGVyc2VjdGlvbi4xPVwKICAgIHdoZXJlIHswfSBhcmUgaW50ZXJzZWN0aW9uIHR5cGVzOgoKIyMjCiMgZXJyb3JzIHJlbGF0ZWQgdG8gZG9jIGNvbW1lbnRzCgpjb21waWxlci5lcnIuZGMuYmFkLmVudGl0eT1cCiAgICBiYWQgSFRNTCBlbnRpdHkKCmNvbXBpbGVyLmVyci5kYy5iYWQuZ3Q9XAogICAgYmFkIHVzZSBvZiAnJz4nJwoKY29tcGlsZXIuZXJyLmRjLmJhZC5pbmxpbmUudGFnPVwKICAgIGluY29ycmVjdCB1c2Ugb2YgaW5saW5lIHRhZwoKY29tcGlsZXIuZXJyLmRjLmlkZW50aWZpZXIuZXhwZWN0ZWQ9XAogICAgaWRlbnRpZmllciBleHBlY3RlZAoKY29tcGlsZXIuZXJyLmRjLm1hbGZvcm1lZC5odG1sPVwKICAgIG1hbGZvcm1lZCBIVE1MCgpjb21waWxlci5lcnIuZGMubWlzc2luZy5zZW1pY29sb249XAogICAgc2VtaWNvbG9uIG1pc3NpbmcKCmNvbXBpbGVyLmVyci5kYy5uby5jb250ZW50PVwKICAgIG5vIGNvbnRlbnQKCmNvbXBpbGVyLmVyci5kYy5uby50YWcubmFtZT1cCiAgICBubyB0YWcgbmFtZSBhZnRlciAnQCcKCmNvbXBpbGVyLmVyci5kYy5ndC5leHBlY3RlZD1cCiAgICAnJz4nJyBleHBlY3RlZAoKY29tcGlsZXIuZXJyLmRjLnJlZi5iYWQucGFyZW5zPVwKICAgICcnKScnIG1pc3NpbmcgaW4gcmVmZXJlbmNlCgpjb21waWxlci5lcnIuZGMucmVmLnN5bnRheC5lcnJvcj1cCiAgICBzeW50YXggZXJyb3IgaW4gcmVmZXJlbmNlCgpjb21waWxlci5lcnIuZGMucmVmLnVuZXhwZWN0ZWQuaW5wdXQ9XAogICAgdW5leHBlY3RlZCB0ZXh0Cgpjb21waWxlci5lcnIuZGMudW5leHBlY3RlZC5jb250ZW50PVwKICAgIHVuZXhwZWN0ZWQgY29udGVudAoKY29tcGlsZXIuZXJyLmRjLnVudGVybWluYXRlZC5pbmxpbmUudGFnPVwKICAgIHVudGVybWluYXRlZCBpbmxpbmUgdGFnCgpjb21waWxlci5lcnIuZGMudW50ZXJtaW5hdGVkLnNpZ25hdHVyZT1cCiAgICB1bnRlcm1pbmF0ZWQgc2lnbmF0dXJlCgpjb21waWxlci5lcnIuZGMudW50ZXJtaW5hdGVkLnN0cmluZz1cCiAgICB1bnRlcm1pbmF0ZWQgc3RyaW5nCgojIyMKIyBlcnJvcnMgcmVsYXRlZCB0byBtb2R1bGVzCgpjb21waWxlci5lcnIuZXhwZWN0ZWQubW9kdWxlPVwKICAgIGV4cGVjdGVkICcnbW9kdWxlJycKCiMgMDogc3ltYm9sCmNvbXBpbGVyLmVyci5tb2R1bGUubm90LmZvdW5kPVwKICAgIG1vZHVsZSBub3QgZm91bmQ6IHswfQoKIyAwOiBzeW1ib2wKY29tcGlsZXIud2Fybi5tb2R1bGUubm90LmZvdW5kPVwKICAgIG1vZHVsZSBub3QgZm91bmQ6IHswfQoKY29tcGlsZXIuZXJyLnRvby5tYW55Lm1vZHVsZXM9XAogICAgdG9vIG1hbnkgbW9kdWxlIGRlY2xhcmF0aW9ucyBmb3VuZAoKY29tcGlsZXIuZXJyLm1vZHVsZS5ub3QuZm91bmQub24ubW9kdWxlLnNvdXJjZS5wYXRoPVwKICAgIG1vZHVsZSBub3QgZm91bmQgb24gbW9kdWxlIHNvdXJjZSBwYXRoCgpjb21waWxlci5lcnIubm90LmluLm1vZHVsZS5vbi5tb2R1bGUuc291cmNlLnBhdGg9XAogICAgbm90IGluIGEgbW9kdWxlIG9uIHRoZSBtb2R1bGUgc291cmNlIHBhdGgKCiMgMDogc3ltYm9sCmNvbXBpbGVyLmVyci5kdXBsaWNhdGUubW9kdWxlPVwKICAgIGR1cGxpY2F0ZSBtb2R1bGU6IHswfQoKIyAwOiBzeW1ib2wKY29tcGlsZXIuZXJyLmR1cGxpY2F0ZS5yZXF1aXJlcz1cCiAgICBkdXBsaWNhdGUgcmVxdWlyZXM6IHswfQoKIyAwOiBzeW1ib2wKY29tcGlsZXIuZXJyLmNvbmZsaWN0aW5nLmV4cG9ydHM9XAogICAgZHVwbGljYXRlIG9yIGNvbmZsaWN0aW5nIGV4cG9ydHM6IHswfQoKIyAwOiBzeW1ib2wKY29tcGlsZXIuZXJyLmNvbmZsaWN0aW5nLm9wZW5zPVwKICAgIGR1cGxpY2F0ZSBvciBjb25mbGljdGluZyBvcGVuczogezB9CgojIDA6IHN5bWJvbApjb21waWxlci5lcnIuY29uZmxpY3RpbmcuZXhwb3J0cy50by5tb2R1bGU9XAogICAgZHVwbGljYXRlIG9yIGNvbmZsaWN0aW5nIGV4cG9ydHMgdG8gbW9kdWxlOiB7MH0KCiMgMDogc3ltYm9sCmNvbXBpbGVyLmVyci5jb25mbGljdGluZy5vcGVucy50by5tb2R1bGU9XAogICAgZHVwbGljYXRlIG9yIGNvbmZsaWN0aW5nIG9wZW5zIHRvIG1vZHVsZTogezB9Cgpjb21waWxlci5lcnIubm8ub3BlbnMudW5sZXNzLnN0cm9uZz1cCiAgICAnJ29wZW5zJycgb25seSBhbGxvd2VkIGluIHN0cm9uZyBtb2R1bGVzCgojIDA6IHN5bWJvbApjb21waWxlci5lcnIucmVwZWF0ZWQucHJvdmlkZXMuZm9yLnNlcnZpY2U9XAogICAgbXVsdGlwbGUgJydwcm92aWRlcycnIGZvciBzZXJ2aWNlIHswfQoKIyAwOiBzeW1ib2wsIDE6IHN5bWJvbApjb21waWxlci5lcnIuZHVwbGljYXRlLnByb3ZpZGVzPVwKICAgIGR1cGxpY2F0ZSBwcm92aWRlczogc2VydmljZSB7MH0sIGltcGxlbWVudGF0aW9uIHsxfQoKIyAwOiBzeW1ib2wKY29tcGlsZXIuZXJyLmR1cGxpY2F0ZS51c2VzPVwKICAgIGR1cGxpY2F0ZSB1c2VzOiB7MH0KCiMgMDogc3ltYm9sCmNvbXBpbGVyLmVyci5zZXJ2aWNlLmltcGxlbWVudGF0aW9uLmlzLmFic3RyYWN0PVwKICAgIHRoZSBzZXJ2aWNlIGltcGxlbWVudGF0aW9uIGlzIGFuIGFic3RyYWN0IGNsYXNzOiB7MH0KCmNvbXBpbGVyLmVyci5zZXJ2aWNlLmltcGxlbWVudGF0aW9uLm11c3QuYmUuc3VidHlwZS5vZi5zZXJ2aWNlLmludGVyZmFjZT1cCiAgICB0aGUgc2VydmljZSBpbXBsZW1lbnRhdGlvbiB0eXBlIG11c3QgYmUgYSBzdWJ0eXBlIG9mIHRoZSBzZXJ2aWNlIGludGVyZmFjZSB0eXBlLCBvciBcCiAgICBoYXZlIGEgcHVibGljIHN0YXRpYyBuby1hcmdzIG1ldGhvZCBuYW1lZCAicHJvdmlkZXIiIHJldHVybmluZyB0aGUgc2VydmljZSBpbXBsZW1lbnRhdGlvbgoKY29tcGlsZXIuZXJyLnNlcnZpY2UuaW1wbGVtZW50YXRpb24ucHJvdmlkZXIucmV0dXJuLm11c3QuYmUuc3VidHlwZS5vZi5zZXJ2aWNlLmludGVyZmFjZT1cCiAgICB0aGUgInByb3ZpZGVyIiBtZXRob2QgcmV0dXJuIHR5cGUgbXVzdCBiZSBhIHN1YnR5cGUgb2YgdGhlIHNlcnZpY2UgaW50ZXJmYWNlIHR5cGUKCiMgMDogc3ltYm9sCmNvbXBpbGVyLmVyci5zZXJ2aWNlLmltcGxlbWVudGF0aW9uLmlzLmlubmVyPVwKICAgIHRoZSBzZXJ2aWNlIGltcGxlbWVudGF0aW9uIGlzIGFuIGlubmVyIGNsYXNzOiB7MH0KCiMgMDogc3ltYm9sCmNvbXBpbGVyLmVyci5zZXJ2aWNlLmRlZmluaXRpb24uaXMuZW51bT1cCiAgICB0aGUgc2VydmljZSBkZWZpbml0aW9uIGlzIGFuIGVudW06IHswfQoKIyAwOiBzeW1ib2wKY29tcGlsZXIuZXJyLnNlcnZpY2UuaW1wbGVtZW50YXRpb24uZG9lc250LmhhdmUuYS5uby5hcmdzLmNvbnN0cnVjdG9yPVwKICAgIHRoZSBzZXJ2aWNlIGltcGxlbWVudGF0aW9uIGRvZXMgbm90IGhhdmUgYSBkZWZhdWx0IGNvbnN0cnVjdG9yOiB7MH0KCiMgMDogc3ltYm9sCmNvbXBpbGVyLmVyci5zZXJ2aWNlLmltcGxlbWVudGF0aW9uLm5vLmFyZ3MuY29uc3RydWN0b3Iubm90LnB1YmxpYz1cCiAgICB0aGUgbm8gYXJndW1lbnRzIGNvbnN0cnVjdG9yIG9mIHRoZSBzZXJ2aWNlIGltcGxlbWVudGF0aW9uIGlzIG5vdCBwdWJsaWM6IHswfQoKIyAwOiBzeW1ib2wKY29tcGlsZXIuZXJyLnBhY2thZ2UuZW1wdHkub3Iubm90LmZvdW5kPVwKICAgIHBhY2thZ2UgaXMgZW1wdHkgb3IgZG9lcyBub3QgZXhpc3Q6IHswfQoKIyAwOiBzeW1ib2wKY29tcGlsZXIud2Fybi5wYWNrYWdlLmVtcHR5Lm9yLm5vdC5mb3VuZD1cCiAgICBwYWNrYWdlIGlzIGVtcHR5IG9yIGRvZXMgbm90IGV4aXN0OiB7MH0KCmNvbXBpbGVyLmVyci5uby5vdXRwdXQuZGlyPVwKICAgIG5vIGNsYXNzIG91dHB1dCBkaXJlY3Rvcnkgc3BlY2lmaWVkCgpjb21waWxlci5lcnIudW5uYW1lZC5wa2cubm90LmFsbG93ZWQubmFtZWQubW9kdWxlcz1cCiAgICB1bm5hbWVkIHBhY2thZ2UgaXMgbm90IGFsbG93ZWQgaW4gbmFtZWQgbW9kdWxlcwoKIyAwOiBuYW1lLCAxOiBuYW1lCmNvbXBpbGVyLmVyci5tb2R1bGUubmFtZS5taXNtYXRjaD1cCiAgICBtb2R1bGUgbmFtZSB7MH0gZG9lcyBub3QgbWF0Y2ggZXhwZWN0ZWQgbmFtZSB7MX0KCiMgMDogbmFtZSwgMTogbmFtZQpjb21waWxlci5taXNjLm1vZHVsZS5uYW1lLm1pc21hdGNoPVwKICAgIG1vZHVsZSBuYW1lIHswfSBkb2VzIG5vdCBtYXRjaCBleHBlY3RlZCBuYW1lIHsxfQoKIyAwOiBuYW1lCmNvbXBpbGVyLmVyci5tb2R1bGUubm9uLnplcm8ub3BlbnM9XAogICAgb3BlbiBtb2R1bGUgezB9IGhhcyBub24temVybyBvcGVuc19jb3VudAoKIyAwOiBuYW1lCmNvbXBpbGVyLm1pc2MubW9kdWxlLm5vbi56ZXJvLm9wZW5zPVwKICAgIG9wZW4gbW9kdWxlIHswfSBoYXMgbm9uLXplcm8gb3BlbnNfY291bnQKCmNvbXBpbGVyLmVyci5tb2R1bGUuZGVjbC5zYi5pbi5tb2R1bGUtaW5mby5qYXZhPVwKICAgIG1vZHVsZSBkZWNsYXJhdGlvbnMgc2hvdWxkIGJlIGluIGEgZmlsZSBuYW1lZCBtb2R1bGUtaW5mby5qYXZhCgpjb21waWxlci5lcnIubW9kdWxlLWluZm8ud2l0aC5wYXRjaGVkLm1vZHVsZS5zb3VyY2VwYXRoPVwKICAgIGNvbXBpbGluZyBhIG1vZHVsZSBwYXRjaCB3aXRoIG1vZHVsZS1pbmZvIG9uIHNvdXJjZXBhdGgKCmNvbXBpbGVyLmVyci5tb2R1bGUtaW5mby53aXRoLnBhdGNoZWQubW9kdWxlLmNsYXNzb3V0cHV0PVwKICAgIGNvbXBpbGluZyBhIG1vZHVsZSBwYXRjaCB3aXRoIG1vZHVsZS1pbmZvIG9uIGNsYXNzIG91dHB1dAoKIyAwOiBzZXQgb2Ygc3RyaW5nCmNvbXBpbGVyLmVyci50b28ubWFueS5wYXRjaGVkLm1vZHVsZXM9XAogICAgdG9vIG1hbnkgcGF0Y2hlZCBtb2R1bGVzICh7MH0pLCB1c2UgLS1tb2R1bGUtc291cmNlLXBhdGgKCiMgMDogbmFtZSwgMTogbmFtZQpjb21waWxlci5lcnIuZmlsZS5wYXRjaGVkLmFuZC5tc3A9XAogICAgZmlsZSBhY2Nlc3NpYmxlIGZyb20gYm90aCAtLXBhdGNoLW1vZHVsZSBhbmQgLS1tb2R1bGUtc291cmNlLXBhdGgsIFwKICAgIGJ1dCBiZWxvbmdzIHRvIGEgZGlmZmVyZW50IG1vZHVsZSBvbiBlYWNoIHBhdGg6IHswfSwgezF9Cgpjb21waWxlci5lcnIucHJvY2Vzc29ycGF0aC5uby5wcm9jZXNzb3Jtb2R1bGVwYXRoPVwKICAgIGlsbGVnYWwgY29tYmluYXRpb24gb2YgLXByb2Nlc3NvcnBhdGggYW5kIC0tcHJvY2Vzc29yLW1vZHVsZS1wYXRoCgojIDA6IHN5bWJvbApjb21waWxlci5lcnIucGFja2FnZS5pbi5vdGhlci5tb2R1bGU9XAogICAgcGFja2FnZSBleGlzdHMgaW4gYW5vdGhlciBtb2R1bGU6IHswfQoKIyAwOiBzeW1ib2wsIDE6IG5hbWUsIDI6IHN5bWJvbCwgMzogc3ltYm9sCmNvbXBpbGVyLmVyci5wYWNrYWdlLmNsYXNoLmZyb20ucmVxdWlyZXM9XAogICAgbW9kdWxlIHswfSByZWFkcyBwYWNrYWdlIHsxfSBmcm9tIGJvdGggezJ9IGFuZCB7M30KCiMgMDogc3RyaW5nCmNvbXBpbGVyLmVyci5tb2R1bGUubm90LmZvdW5kLmluLm1vZHVsZS5zb3VyY2UucGF0aD1cCiAgICBtb2R1bGUgezB9IG5vdCBmb3VuZCBpbiBtb2R1bGUgc291cmNlIHBhdGgKCmNvbXBpbGVyLmVyci5vdXRwdXQuZGlyLm11c3QuYmUuc3BlY2lmaWVkLndpdGguZGFzaC5tLm9wdGlvbj1cCiAgICBjbGFzcyBvdXRwdXQgZGlyZWN0b3J5IG11c3QgYmUgc3BlY2lmaWVkIGlmIC1tIG9wdGlvbiBpcyB1c2VkCgpjb21waWxlci5lcnIubW9kdWxlc291cmNlcGF0aC5tdXN0LmJlLnNwZWNpZmllZC53aXRoLmRhc2gubS5vcHRpb249XAogICAgbW9kdWxlIHNvdXJjZSBwYXRoIG11c3QgYmUgc3BlY2lmaWVkIGlmIC1tIG9wdGlvbiBpcyB1c2VkCgojIDA6IHN5bWJvbApjb21waWxlci5lcnIuc2VydmljZS5pbXBsZW1lbnRhdGlvbi5ub3QuaW4ucmlnaHQubW9kdWxlPVwKICAgIHNlcnZpY2UgaW1wbGVtZW50YXRpb24gbXVzdCBiZSBkZWZpbmVkIGluIHRoZSBzYW1lIG1vZHVsZSBhcyB0aGUgcHJvdmlkZXMgZGlyZWN0aXZlCgojIDA6IHN5bWJvbApjb21waWxlci5lcnIuY3ljbGljLnJlcXVpcmVzPVwKICAgIGN5Y2xpYyBkZXBlbmRlbmNlIGludm9sdmluZyB7MH0KCiMgMDogZnJhZ21lbnQsIDE6IG5hbWUKY29tcGlsZXIuZXJyLmR1cGxpY2F0ZS5tb2R1bGUub24ucGF0aD1cCiAgICBkdXBsaWNhdGUgbW9kdWxlIG9uIHswfVxubW9kdWxlIGluIHsxfQoKIyAwOiBvcHRpb24gbmFtZSwgMTogc3RyaW5nCmNvbXBpbGVyLndhcm4uYmFkLm5hbWUuZm9yLm9wdGlvbj1cCiAgICBiYWQgbmFtZSBpbiB2YWx1ZSBmb3IgezB9IG9wdGlvbjogJyd7MX0nJwoKIyAwOiBvcHRpb24gbmFtZSwgMTogc3RyaW5nCmNvbXBpbGVyLmVyci5iYWQubmFtZS5mb3Iub3B0aW9uPVwKICAgIGJhZCBuYW1lIGluIHZhbHVlIGZvciB7MH0gb3B0aW9uOiAnJ3sxfScnCgojIDA6IG9wdGlvbiBuYW1lLCAxOiBzeW1ib2wKY29tcGlsZXIud2Fybi5tb2R1bGUuZm9yLm9wdGlvbi5ub3QuZm91bmQ9XAogICAgbW9kdWxlIG5hbWUgaW4gezB9IG9wdGlvbiBub3QgZm91bmQ6IHsxfQoKY29tcGlsZXIuZXJyLmFkZG1vZHMuYWxsLm1vZHVsZS5wYXRoLmludmFsaWQ9XAogICAgLS1hZGQtbW9kdWxlcyBBTEwtTU9EVUxFLVBBVEggY2FuIG9ubHkgYmUgdXNlZCB3aGVuIGNvbXBpbGluZyB0aGUgdW5uYW1lZCBtb2R1bGUKCmNvbXBpbGVyLndhcm4uYWRkb3BlbnMuaWdub3JlZD1cCiAgICAtLWFkZC1vcGVucyBoYXMgbm8gZWZmZWN0IGF0IGNvbXBpbGUgdGltZQoKY29tcGlsZXIubWlzYy5sb2NuLm1vZHVsZV9zb3VyY2VfcGF0aD1cCiAgICBtb2R1bGUgc291cmNlIHBhdGgKCmNvbXBpbGVyLm1pc2MubG9jbi51cGdyYWRlX21vZHVsZV9wYXRoPVwKICAgIHVwZ3JhZGUgbW9kdWxlIHBhdGgKCmNvbXBpbGVyLm1pc2MubG9jbi5zeXN0ZW1fbW9kdWxlcz1cCiAgICBzeXN0ZW0gbW9kdWxlcwoKY29tcGlsZXIubWlzYy5sb2NuLm1vZHVsZV9wYXRoPVwKICAgIGFwcGxpY2F0aW9uIG1vZHVsZSBwYXRoCgpjb21waWxlci5taXNjLmNhbnQucmVzb2x2ZS5tb2R1bGVzPVwKICAgIGNhbm5vdCByZXNvbHZlIG1vZHVsZXMKCiMgMDogc3RyaW5nCmNvbXBpbGVyLmVyci5pbnZhbGlkLm1vZHVsZS5zcGVjaWZpZXI9XAogICAgbW9kdWxlIHNwZWNpZmllciBub3QgYWxsb3dlZDogezB9CgojIDA6IHN5bWJvbApjb21waWxlci53YXJuLnNlcnZpY2UucHJvdmlkZWQuYnV0Lm5vdC5leHBvcnRlZC5vci51c2VkPVwKICAgIHNlcnZpY2UgaW50ZXJmYWNlIHByb3ZpZGVkIGJ1dCBub3QgZXhwb3J0ZWQgb3IgdXNlZAoKIyAwOiBraW5kIG5hbWUsIDE6IHN5bWJvbCwgMjogc3ltYm9sCmNvbXBpbGVyLndhcm4ubGVha3Mubm90LmFjY2Vzc2libGU9XAogICAgezB9IHsxfSBpbiBtb2R1bGUgezJ9IGlzIG5vdCBhY2Nlc3NpYmxlIHRvIGNsaWVudHMgdGhhdCByZXF1aXJlIHRoaXMgbW9kdWxlCiMgMDoga2luZCBuYW1lLCAxOiBzeW1ib2wsIDI6IHN5bWJvbApjb21waWxlci53YXJuLmxlYWtzLm5vdC5hY2Nlc3NpYmxlLnVuZXhwb3J0ZWQ9XAogICAgezB9IHsxfSBpbiBtb2R1bGUgezJ9IGlzIG5vdCBleHBvcnRlZAojIDA6IGtpbmQgbmFtZSwgMTogc3ltYm9sLCAyOiBzeW1ib2wKY29tcGlsZXIud2Fybi5sZWFrcy5ub3QuYWNjZXNzaWJsZS5ub3QucmVxdWlyZWQudHJhbnNpdGl2ZT1cCiAgICB7MH0gezF9IGluIG1vZHVsZSB7Mn0gaXMgbm90IGluZGlyZWN0bHkgZXhwb3J0ZWQgdXNpbmcgJ3JlcXVpcmVzIHRyYW5zaXRpdmUnCiMgMDoga2luZCBuYW1lLCAxOiBzeW1ib2wsIDI6IHN5bWJvbApjb21waWxlci53YXJuLmxlYWtzLm5vdC5hY2Nlc3NpYmxlLnVuZXhwb3J0ZWQucXVhbGlmaWVkPVwKICAgIHswfSB7MX0gaW4gbW9kdWxlIHsyfSBtYXkgbm90IGJlIHZpc2libGUgdG8gYWxsIGNsaWVudHMgdGhhdCByZXF1aXJlIHRoaXMgbW9kdWxlCgojIyMKIyBlcnJvcnMgcmVsYXRlZCB0byBvcHRpb25zCgojIDA6IHN0cmluZywgMTogc3RyaW5nCmNvbXBpbGVyLmVyci5pbGxlZ2FsLmFyZ3VtZW50LmZvci5vcHRpb249XAogICAgaWxsZWdhbCBhcmd1bWVudCBmb3IgezB9OiB7MX0KUEsDBAoAAAgAAAY7qUqB+A/upocAAKaHAAArAAAAY29tL3N1bi90b29scy9qYXZhYy9yZXNvdXJjZXMvY3QucHJvcGVydGllcyMKIyBDb3B5cmlnaHQgKGMpIDIwMTYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiMgRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgojCiMgVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKIyB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwojIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwojIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKIyBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KIwojIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAojIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgojIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQojIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiMgYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KIwojIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KIyAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiMgSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgojCiMgUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKIyBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiMgcXVlc3Rpb25zLgojCgphcHBsZS5sYWYuKjogaGlkZGVuCmFwcGxlLnNlY3VyaXR5Lio6IGhpZGRlbgpjb20uYXBwbGUuZWF3dC4qOiBoaWRkZW4KY29tLmFwcGxlLmVhd3QuZXZlbnQuKjogaGlkZGVuCmNvbS5hcHBsZS5laW8uKjogaGlkZGVuCmNvbS5hcHBsZS5sYWYuKjogaGlkZGVuCmNvbS5vcmFjbGUud2Vic2VydmljZXMuaW50ZXJuYWwuYXBpLio6IGhpZGRlbgpjb20ub3JhY2xlLndlYnNlcnZpY2VzLmludGVybmFsLmFwaS5kYXRhYmluZGluZy4qOiBoaWRkZW4KY29tLm9yYWNsZS53ZWJzZXJ2aWNlcy5pbnRlcm5hbC5hcGkubWVzc2FnZS4qOiBoaWRkZW4KY29tLm9yYWNsZS53ZWJzZXJ2aWNlcy5pbnRlcm5hbC5pbXBsLmVuY29kaW5nLio6IGhpZGRlbgpjb20ub3JhY2xlLndlYnNlcnZpY2VzLmludGVybmFsLmltcGwuaW50ZXJuYWxzcGkuZW5jb2RpbmcuKjogaGlkZGVuCmNvbS5vcmFjbGUueG1sbnMuaW50ZXJuYWwud2Vic2VydmljZXMuamF4d3NfZGF0YWJpbmRpbmcuKjogaGlkZGVuCmNvbS5zdW4uYWNjZXNzaWJpbGl0eS5pbnRlcm5hbC5yZXNvdXJjZXMuKjogcHJvcHJpZXRhcnkKY29tLnN1bi5hY3RpdmF0aW9uLnJlZ2lzdHJpZXMuKjogaGlkZGVuCmNvbS5zdW4uYXd0Lio6IHByb3ByaWV0YXJ5CmNvbS5zdW4uYmVhbnMuKjogcHJvcHJpZXRhcnkKY29tLnN1bi5iZWFucy5kZWNvZGVyLio6IGhpZGRlbgpjb20uc3VuLmJlYW5zLmVkaXRvcnMuKjogaGlkZGVuCmNvbS5zdW4uYmVhbnMuZmluZGVyLio6IGhpZGRlbgpjb20uc3VuLmJlYW5zLmluZm9zLio6IGhpZGRlbgpjb20uc3VuLmJlYW5zLmludHJvc3BlY3QuKjogaGlkZGVuCmNvbS5zdW4uYmVhbnMudXRpbC4qOiBoaWRkZW4KY29tLnN1bi5jb3JiYS5zZS5pbXBsLmFjdGl2YXRpb24uKjogcHJvcHJpZXRhcnkKY29tLnN1bi5jb3JiYS5zZS5pbXBsLmNvcHlvYmplY3QuKjogcHJvcHJpZXRhcnkKY29tLnN1bi5jb3JiYS5zZS5pbXBsLmNvcmJhLio6IHByb3ByaWV0YXJ5CmNvbS5zdW4uY29yYmEuc2UuaW1wbC5keW5hbWljYW55Lio6IHByb3ByaWV0YXJ5CmNvbS5zdW4uY29yYmEuc2UuaW1wbC5lbmNvZGluZy4qOiBwcm9wcmlldGFyeQpjb20uc3VuLmNvcmJhLnNlLmltcGwuaW50ZXJjZXB0b3JzLio6IHByb3ByaWV0YXJ5CmNvbS5zdW4uY29yYmEuc2UuaW1wbC5pby4qOiBwcm9wcmlldGFyeQpjb20uc3VuLmNvcmJhLnNlLmltcGwuaW9yLio6IHByb3ByaWV0YXJ5CmNvbS5zdW4uY29yYmEuc2UuaW1wbC5pb3IuaWlvcC4qOiBwcm9wcmlldGFyeQpjb20uc3VuLmNvcmJhLnNlLmltcGwuamF2YXgucm1pLio6IHByb3ByaWV0YXJ5CmNvbS5zdW4uY29yYmEuc2UuaW1wbC5qYXZheC5ybWkuQ09SQkEuKjogcHJvcHJpZXRhcnkKY29tLnN1bi5jb3JiYS5zZS5pbXBsLmxlZ2FjeS5jb25uZWN0aW9uLio6IHByb3ByaWV0YXJ5CmNvbS5zdW4uY29yYmEuc2UuaW1wbC5sb2dnaW5nLio6IHByb3ByaWV0YXJ5CmNvbS5zdW4uY29yYmEuc2UuaW1wbC5tb25pdG9yaW5nLio6IHByb3ByaWV0YXJ5CmNvbS5zdW4uY29yYmEuc2UuaW1wbC5uYW1pbmcuY29zbmFtaW5nLio6IHByb3ByaWV0YXJ5CmNvbS5zdW4uY29yYmEuc2UuaW1wbC5uYW1pbmcubmFtaW5ndXRpbC4qOiBwcm9wcmlldGFyeQpjb20uc3VuLmNvcmJhLnNlLmltcGwubmFtaW5nLnBjb3NuYW1pbmcuKjogcHJvcHJpZXRhcnkKY29tLnN1bi5jb3JiYS5zZS5pbXBsLm9hLio6IHByb3ByaWV0YXJ5CmNvbS5zdW4uY29yYmEuc2UuaW1wbC5vYS5wb2EuKjogcHJvcHJpZXRhcnkKY29tLnN1bi5jb3JiYS5zZS5pbXBsLm9hLnRvYS4qOiBwcm9wcmlldGFyeQpjb20uc3VuLmNvcmJhLnNlLmltcGwub3JiLio6IHByb3ByaWV0YXJ5CmNvbS5zdW4uY29yYmEuc2UuaW1wbC5vcmJ1dGlsLio6IHByb3ByaWV0YXJ5CmNvbS5zdW4uY29yYmEuc2UuaW1wbC5vcmJ1dGlsLmNsb3N1cmUuKjogcHJvcHJpZXRhcnkKY29tLnN1bi5jb3JiYS5zZS5pbXBsLm9yYnV0aWwuY29uY3VycmVudC4qOiBwcm9wcmlldGFyeQpjb20uc3VuLmNvcmJhLnNlLmltcGwub3JidXRpbC5mc20uKjogcHJvcHJpZXRhcnkKY29tLnN1bi5jb3JiYS5zZS5pbXBsLm9yYnV0aWwuZ3JhcGguKjogcHJvcHJpZXRhcnkKY29tLnN1bi5jb3JiYS5zZS5pbXBsLm9yYnV0aWwudGhyZWFkcG9vbC4qOiBwcm9wcmlldGFyeQpjb20uc3VuLmNvcmJhLnNlLmltcGwucHJlc2VudGF0aW9uLnJtaS4qOiBwcm9wcmlldGFyeQpjb20uc3VuLmNvcmJhLnNlLmltcGwucHJvdG9jb2wuKjogcHJvcHJpZXRhcnkKY29tLnN1bi5jb3JiYS5zZS5pbXBsLnByb3RvY29sLmdpb3Btc2doZWFkZXJzLio6IHByb3ByaWV0YXJ5CmNvbS5zdW4uY29yYmEuc2UuaW1wbC5yZXNvbHZlci4qOiBwcm9wcmlldGFyeQpjb20uc3VuLmNvcmJhLnNlLmltcGwudHJhbnNwb3J0Lio6IHByb3ByaWV0YXJ5CmNvbS5zdW4uY29yYmEuc2UuaW1wbC51dGlsLio6IHByb3ByaWV0YXJ5CmNvbS5zdW4uY29yYmEuc2UuaW50ZXJuYWwuQ29zTmFtaW5nLio6IHByb3ByaWV0YXJ5CmNvbS5zdW4uY29yYmEuc2UuaW50ZXJuYWwuSW50ZXJjZXB0b3JzLio6IHByb3ByaWV0YXJ5CmNvbS5zdW4uY29yYmEuc2UuaW50ZXJuYWwuUE9BLio6IHByb3ByaWV0YXJ5CmNvbS5zdW4uY29yYmEuc2UuaW50ZXJuYWwuY29yYmEuKjogcHJvcHJpZXRhcnkKY29tLnN1bi5jb3JiYS5zZS5pbnRlcm5hbC5paW9wLio6IHByb3ByaWV0YXJ5CmNvbS5zdW4uY29yYmEuc2Uub3JnLm9tZy5DT1JCQS4qOiBwcm9wcmlldGFyeQpjb20uc3VuLmNvcmJhLnNlLnBlcHQuYnJva2VyLio6IHByb3ByaWV0YXJ5CmNvbS5zdW4uY29yYmEuc2UucGVwdC5lbmNvZGluZy4qOiBwcm9wcmlldGFyeQpjb20uc3VuLmNvcmJhLnNlLnBlcHQucHJvdG9jb2wuKjogcHJvcHJpZXRhcnkKY29tLnN1bi5jb3JiYS5zZS5wZXB0LnRyYW5zcG9ydC4qOiBwcm9wcmlldGFyeQpjb20uc3VuLmNvcmJhLnNlLnNwaS5hY3RpdmF0aW9uLio6IHByb3ByaWV0YXJ5CmNvbS5zdW4uY29yYmEuc2Uuc3BpLmFjdGl2YXRpb24uSW5pdGlhbE5hbWVTZXJ2aWNlUGFja2FnZS4qOiBwcm9wcmlldGFyeQpjb20uc3VuLmNvcmJhLnNlLnNwaS5hY3RpdmF0aW9uLkxvY2F0b3JQYWNrYWdlLio6IHByb3ByaWV0YXJ5CmNvbS5zdW4uY29yYmEuc2Uuc3BpLmFjdGl2YXRpb24uUmVwb3NpdG9yeVBhY2thZ2UuKjogcHJvcHJpZXRhcnkKY29tLnN1bi5jb3JiYS5zZS5zcGkuY29weW9iamVjdC4qOiBwcm9wcmlldGFyeQpjb20uc3VuLmNvcmJhLnNlLnNwaS5lbmNvZGluZy4qOiBwcm9wcmlldGFyeQpjb20uc3VuLmNvcmJhLnNlLnNwaS5leHRlbnNpb24uKjogcHJvcHJpZXRhcnkKY29tLnN1bi5jb3JiYS5zZS5zcGkuaW9yLio6IHByb3ByaWV0YXJ5CmNvbS5zdW4uY29yYmEuc2Uuc3BpLmlvci5paW9wLio6IHByb3ByaWV0YXJ5CmNvbS5zdW4uY29yYmEuc2Uuc3BpLmxlZ2FjeS5jb25uZWN0aW9uLio6IHByb3ByaWV0YXJ5CmNvbS5zdW4uY29yYmEuc2Uuc3BpLmxlZ2FjeS5pbnRlcmNlcHRvci4qOiBwcm9wcmlldGFyeQpjb20uc3VuLmNvcmJhLnNlLnNwaS5sb2dnaW5nLio6IHByb3ByaWV0YXJ5CmNvbS5zdW4uY29yYmEuc2Uuc3BpLm1vbml0b3JpbmcuKjogcHJvcHJpZXRhcnkKY29tLnN1bi5jb3JiYS5zZS5zcGkub2EuKjogcHJvcHJpZXRhcnkKY29tLnN1bi5jb3JiYS5zZS5zcGkub3JiLio6IHByb3ByaWV0YXJ5CmNvbS5zdW4uY29yYmEuc2Uuc3BpLm9yYnV0aWwuY2xvc3VyZS4qOiBwcm9wcmlldGFyeQpjb20uc3VuLmNvcmJhLnNlLnNwaS5vcmJ1dGlsLmZzbS4qOiBwcm9wcmlldGFyeQpjb20uc3VuLmNvcmJhLnNlLnNwaS5vcmJ1dGlsLnByb3h5Lio6IHByb3ByaWV0YXJ5CmNvbS5zdW4uY29yYmEuc2Uuc3BpLm9yYnV0aWwudGhyZWFkcG9vbC4qOiBwcm9wcmlldGFyeQpjb20uc3VuLmNvcmJhLnNlLnNwaS5wcmVzZW50YXRpb24ucm1pLio6IHByb3ByaWV0YXJ5CmNvbS5zdW4uY29yYmEuc2Uuc3BpLnByb3RvY29sLio6IHByb3ByaWV0YXJ5CmNvbS5zdW4uY29yYmEuc2Uuc3BpLnJlc29sdmVyLio6IHByb3ByaWV0YXJ5CmNvbS5zdW4uY29yYmEuc2Uuc3BpLnNlcnZpY2Vjb250ZXh0Lio6IHByb3ByaWV0YXJ5CmNvbS5zdW4uY29yYmEuc2Uuc3BpLnRyYW5zcG9ydC4qOiBwcm9wcmlldGFyeQpjb20uc3VuLmRlbW8uanZtdGkuaHByb2YuKjogaGlkZGVuCmNvbS5zdW4uaW1hZ2Vpby5wbHVnaW5zLmJtcC4qOiBwcm9wcmlldGFyeQpjb20uc3VuLmltYWdlaW8ucGx1Z2lucy5jb21tb24uKjogcHJvcHJpZXRhcnkKY29tLnN1bi5pbWFnZWlvLnBsdWdpbnMuZ2lmLio6IHByb3ByaWV0YXJ5CmNvbS5zdW4uaW1hZ2Vpby5wbHVnaW5zLmpwZWcuKjogcHJvcHJpZXRhcnkKY29tLnN1bi5pbWFnZWlvLnBsdWdpbnMucG5nLio6IHByb3ByaWV0YXJ5CmNvbS5zdW4uaW1hZ2Vpby5wbHVnaW5zLndibXAuKjogcHJvcHJpZXRhcnkKY29tLnN1bi5pbWFnZWlvLnNwaS4qOiBwcm9wcmlldGFyeQpjb20uc3VuLmltYWdlaW8uc3RyZWFtLio6IGhpZGRlbgpjb20uc3VuLmlzdGFjay5pbnRlcm5hbC4qOiBoaWRkZW4KY29tLnN1bi5pc3RhY2suaW50ZXJuYWwubG9jYWxpemF0aW9uLio6IGhpZGRlbgpjb20uc3VuLmlzdGFjay5pbnRlcm5hbC5sb2dnaW5nLio6IGhpZGRlbgpjb20uc3VuLmphdmEuc3dpbmcuKjogcHJvcHJpZXRhcnkKY29tLnN1bi5qYXZhLnN3aW5nLnBsYWYuZ3RrLnJlc291cmNlcy4qOiBwcm9wcmlldGFyeQpjb20uc3VuLmphdmEuc3dpbmcucGxhZi5tb3RpZi5yZXNvdXJjZXMuKjogcHJvcHJpZXRhcnkKY29tLnN1bi5qYXZhLnN3aW5nLnBsYWYubmltYnVzLio6IHByb3ByaWV0YXJ5CmNvbS5zdW4uamF2YS5zd2luZy5wbGFmLndpbmRvd3MucmVzb3VyY2VzLio6IHByb3ByaWV0YXJ5CmNvbS5zdW4uamF2YS51dGlsLmphci5wYWNrLio6IHByb3ByaWV0YXJ5IGNvbXBhY3QxCmNvbS5zdW4uamF2YV9jdXAuaW50ZXJuYWwucnVudGltZS4qOiBwcm9wcmlldGFyeSBjb21wYWN0Mgpjb20uc3VuLmpteC5kZWZhdWx0cy4qOiBwcm9wcmlldGFyeSBjb21wYWN0Mwpjb20uc3VuLmpteC5pbnRlcmNlcHRvci4qOiBwcm9wcmlldGFyeSBjb21wYWN0Mwpjb20uc3VuLmpteC5tYmVhbnNlcnZlci4qOiBwcm9wcmlldGFyeSBjb21wYWN0Mwpjb20uc3VuLmpteC5yZW1vdGUuaW50ZXJuYWwuKjogcHJvcHJpZXRhcnkgY29tcGFjdDMKY29tLnN1bi5qbXgucmVtb3RlLnByb3RvY29sLnJtaS4qOiBwcm9wcmlldGFyeSBjb21wYWN0Mwpjb20uc3VuLmpteC5yZW1vdGUuc2VjdXJpdHkuKjogcHJvcHJpZXRhcnkgY29tcGFjdDMKY29tLnN1bi5qbXgucmVtb3RlLnV0aWwuKjogcHJvcHJpZXRhcnkgY29tcGFjdDMKY29tLnN1bi5qbmRpLmNvc25hbWluZy4qOiBwcm9wcmlldGFyeQpjb20uc3VuLmpuZGkuZG5zLio6IHByb3ByaWV0YXJ5IGNvbXBhY3QzCmNvbS5zdW4uam5kaS5sZGFwLio6IHByb3ByaWV0YXJ5IGNvbXBhY3QzCmNvbS5zdW4uam5kaS5sZGFwLmV4dC4qOiBwcm9wcmlldGFyeSBjb21wYWN0Mwpjb20uc3VuLmpuZGkubGRhcC5wb29sLio6IHByb3ByaWV0YXJ5IGNvbXBhY3QzCmNvbS5zdW4uam5kaS5sZGFwLnNhc2wuKjogcHJvcHJpZXRhcnkgY29tcGFjdDMKY29tLnN1bi5qbmRpLnJtaS5yZWdpc3RyeS4qOiBwcm9wcmlldGFyeSBjb21wYWN0Mwpjb20uc3VuLmpuZGkudG9vbGtpdC5jb3JiYS4qOiBwcm9wcmlldGFyeQpjb20uc3VuLmpuZGkudG9vbGtpdC5jdHguKjogcHJvcHJpZXRhcnkgY29tcGFjdDMKY29tLnN1bi5qbmRpLnRvb2xraXQuZGlyLio6IHByb3ByaWV0YXJ5IGNvbXBhY3QzCmNvbS5zdW4uam5kaS50b29sa2l0LnVybC4qOiBwcm9wcmlldGFyeSBjb21wYWN0Mwpjb20uc3VuLmpuZGkudXJsLmNvcmJhbmFtZS4qOiBwcm9wcmlldGFyeQpjb20uc3VuLmpuZGkudXJsLmRucy4qOiBwcm9wcmlldGFyeSBjb21wYWN0Mwpjb20uc3VuLmpuZGkudXJsLmlpb3AuKjogcHJvcHJpZXRhcnkKY29tLnN1bi5qbmRpLnVybC5paW9wbmFtZS4qOiBwcm9wcmlldGFyeQpjb20uc3VuLmpuZGkudXJsLmxkYXAuKjogcHJvcHJpZXRhcnkgY29tcGFjdDMKY29tLnN1bi5qbmRpLnVybC5sZGFwcy4qOiBwcm9wcmlldGFyeSBjb21wYWN0Mwpjb20uc3VuLmpuZGkudXJsLnJtaS4qOiBwcm9wcmlldGFyeSBjb21wYWN0Mwpjb20uc3VuLm1hbmFnZW1lbnQuKjogY29tcGFjdDMKY29tLnN1bi5tZWRpYS5zb3VuZC4qOiBwcm9wcmlldGFyeQpjb20uc3VuLm5hbWluZy5pbnRlcm5hbC4qOiBwcm9wcmlldGFyeSBjb21wYWN0Mwpjb20uc3VuLm5ldC5odHRwc2VydmVyLio6IGNvbXBhY3QyCmNvbS5zdW4ubmV0Lmh0dHBzZXJ2ZXIuc3BpLio6IGNvbXBhY3QyCmNvbS5zdW4ubmV0LnNzbC4qOiBjb21wYWN0MQpjb20uc3VuLm5ldC5zc2wuaW50ZXJuYWwud3d3LnByb3RvY29sLmh0dHBzLio6IHByb3ByaWV0YXJ5IGNvbXBhY3QxCmNvbS5zdW4ubmlvLmZpbGUuKjogY29tcGFjdDEKY29tLnN1bi5uaW8uc2N0cC4qOiBjb21wYWN0Mwpjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC4qOiBwcm9wcmlldGFyeSBjb21wYWN0Mgpjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC5jbGFzc2ZpbGUuKjogcHJvcHJpZXRhcnkgY29tcGFjdDIKY29tLnN1bi5vcmcuYXBhY2hlLmJjZWwuaW50ZXJuYWwuZ2VuZXJpYy4qOiBwcm9wcmlldGFyeSBjb21wYWN0Mgpjb20uc3VuLm9yZy5hcGFjaGUuYmNlbC5pbnRlcm5hbC51dGlsLio6IHByb3ByaWV0YXJ5IGNvbXBhY3QyCmNvbS5zdW4ub3JnLmFwYWNoZS5yZWdleHAuaW50ZXJuYWwuKjogcHJvcHJpZXRhcnkgY29tcGFjdDIKY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLio6IHByb3ByaWV0YXJ5IGNvbXBhY3QyCmNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC5leHRlbnNpb25zLio6IHByb3ByaWV0YXJ5IGNvbXBhY3QyCmNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC5saWIuKjogcHJvcHJpZXRhcnkgY29tcGFjdDIKY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnJlcy4qOiBwcm9wcmlldGFyeSBjb21wYWN0Mgpjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwudGVtcGxhdGVzLio6IHByb3ByaWV0YXJ5IGNvbXBhY3QyCmNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC51dGlscy4qOiBoaWRkZW4KY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHQuKjogcHJvcHJpZXRhcnkgY29tcGFjdDIKY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLio6IHByb3ByaWV0YXJ5IGNvbXBhY3QyCmNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jbWRsaW5lLio6IHByb3ByaWV0YXJ5IGNvbXBhY3QyCmNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy5jbWRsaW5lLmdldG9wdC4qOiBwcm9wcmlldGFyeSBjb21wYWN0Mgpjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMuY29tcGlsZXIuKjogcHJvcHJpZXRhcnkgY29tcGFjdDIKY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmNvbXBpbGVyLnV0aWwuKjogcHJvcHJpZXRhcnkgY29tcGFjdDIKY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLmRvbS4qOiBwcm9wcmlldGFyeSBjb21wYWN0Mgpjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMucnVudGltZS4qOiBwcm9wcmlldGFyeSBjb21wYWN0Mgpjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMucnVudGltZS5vdXRwdXQuKjogcHJvcHJpZXRhcnkgY29tcGFjdDIKY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLnRyYXguKjogcHJvcHJpZXRhcnkgY29tcGFjdDIKY29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLnV0aWwuKjogcHJvcHJpZXRhcnkgY29tcGFjdDIKY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5kb20uKjogcHJvcHJpZXRhcnkgY29tcGFjdDIKY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5kb20uZXZlbnRzLio6IHByb3ByaWV0YXJ5IGNvbXBhY3QyCmNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC4qOiBwcm9wcmlldGFyeSBjb21wYWN0Mgpjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHRkLio6IHByb3ByaWV0YXJ5IGNvbXBhY3QyCmNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdGQubW9kZWxzLio6IHByb3ByaWV0YXJ5IGNvbXBhY3QyCmNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi4qOiBwcm9wcmlldGFyeSBjb21wYWN0Mgpjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuZHYuZHRkLio6IHByb3ByaWV0YXJ5IGNvbXBhY3QyCmNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi51dGlsLio6IHByb3ByaWV0YXJ5IGNvbXBhY3QyCmNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC5kdi54cy4qOiBwcm9wcmlldGFyeSBjb21wYWN0Mgpjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwuaW8uKjogcHJvcHJpZXRhcnkgY29tcGFjdDIKY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLm1zZy4qOiBwcm9wcmlldGFyeSBjb21wYWN0Mgpjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwudmFsaWRhdGlvbi4qOiBwcm9wcmlldGFyeSBjb21wYWN0Mgpjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHBhdGguKjogcHJvcHJpZXRhcnkgY29tcGFjdDIKY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhwYXRoLnJlZ2V4Lio6IHByb3ByaWV0YXJ5IGNvbXBhY3QyCmNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuaW1wbC54cy4qOiBwcm9wcmlldGFyeSBjb21wYWN0Mgpjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMuaWRlbnRpdHkuKjogcHJvcHJpZXRhcnkgY29tcGFjdDIKY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5pbXBsLnhzLm1vZGVscy4qOiBwcm9wcmlldGFyeSBjb21wYWN0Mgpjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMub3B0aS4qOiBwcm9wcmlldGFyeSBjb21wYWN0Mgpjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMudHJhdmVyc2Vycy4qOiBwcm9wcmlldGFyeSBjb21wYWN0Mgpjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmltcGwueHMudXRpbC4qOiBwcm9wcmlldGFyeSBjb21wYWN0Mgpjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLmpheHAuKjogcHJvcHJpZXRhcnkgY29tcGFjdDIKY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC5qYXhwLmRhdGF0eXBlLio6IHByb3ByaWV0YXJ5IGNvbXBhY3QyCmNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwuamF4cC52YWxpZGF0aW9uLio6IHByb3ByaWV0YXJ5IGNvbXBhY3QyCmNvbS5zdW4ub3JnLmFwYWNoZS54ZXJjZXMuaW50ZXJuYWwucGFyc2Vycy4qOiBwcm9wcmlldGFyeSBjb21wYWN0Mgpjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnV0aWwuKjogcHJvcHJpZXRhcnkgY29tcGFjdDIKY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC51dGlscy4qOiBoaWRkZW4KY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54aW5jbHVkZS4qOiBwcm9wcmlldGFyeSBjb21wYWN0Mgpjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS4qOiBwcm9wcmlldGFyeSBjb21wYWN0Mgpjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5ncmFtbWFycy4qOiBwcm9wcmlldGFyeSBjb21wYWN0Mgpjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhuaS5wYXJzZXIuKjogcHJvcHJpZXRhcnkgY29tcGFjdDIKY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cG9pbnRlci4qOiBoaWRkZW4KY29tLnN1bi5vcmcuYXBhY2hlLnhlcmNlcy5pbnRlcm5hbC54cy4qOiBwcm9wcmlldGFyeSBjb21wYWN0Mgpjb20uc3VuLm9yZy5hcGFjaGUueGVyY2VzLmludGVybmFsLnhzLmRhdGF0eXBlcy4qOiBoaWRkZW4KY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0uKjogcHJvcHJpZXRhcnkgY29tcGFjdDIKY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5kdG0ucmVmLio6IHByb3ByaWV0YXJ5IGNvbXBhY3QyCmNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLnJlZi5kb20yZHRtLio6IHByb3ByaWV0YXJ5IGNvbXBhY3QyCmNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuZHRtLnJlZi5zYXgyZHRtLio6IHByb3ByaWV0YXJ5IGNvbXBhY3QyCmNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwucmVzLio6IHByb3ByaWV0YXJ5IGNvbXBhY3QyCmNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwucmVzb2x2ZXIuKjogaGlkZGVuCmNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwucmVzb2x2ZXIuaGVscGVycy4qOiBoaWRkZW4KY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5yZXNvbHZlci5yZWFkZXJzLio6IGhpZGRlbgpjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnJlc29sdmVyLnRvb2xzLio6IGhpZGRlbgpjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlY3VyaXR5Lio6IGhpZGRlbgpjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlY3VyaXR5LmFsZ29yaXRobXMuKjogaGlkZGVuCmNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VjdXJpdHkuYWxnb3JpdGhtcy5pbXBsZW1lbnRhdGlvbnMuKjogaGlkZGVuCmNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VjdXJpdHkuYzE0bi4qOiBoaWRkZW4KY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZWN1cml0eS5jMTRuLmhlbHBlci4qOiBoaWRkZW4KY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZWN1cml0eS5jMTRuLmltcGxlbWVudGF0aW9ucy4qOiBoaWRkZW4KY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZWN1cml0eS5lbmNyeXB0aW9uLio6IGhpZGRlbgpjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlY3VyaXR5LmV4Y2VwdGlvbnMuKjogaGlkZGVuCmNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VjdXJpdHkua2V5cy4qOiBoaWRkZW4KY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZWN1cml0eS5rZXlzLmNvbnRlbnQuKjogaGlkZGVuCmNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VjdXJpdHkua2V5cy5jb250ZW50LmtleXZhbHVlcy4qOiBoaWRkZW4KY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZWN1cml0eS5rZXlzLmNvbnRlbnQueDUwOS4qOiBoaWRkZW4KY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZWN1cml0eS5rZXlzLmtleXJlc29sdmVyLio6IGhpZGRlbgpjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlY3VyaXR5LmtleXMua2V5cmVzb2x2ZXIuaW1wbGVtZW50YXRpb25zLio6IGhpZGRlbgpjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlY3VyaXR5LmtleXMuc3RvcmFnZS4qOiBoaWRkZW4KY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZWN1cml0eS5rZXlzLnN0b3JhZ2UuaW1wbGVtZW50YXRpb25zLio6IGhpZGRlbgpjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlY3VyaXR5LnNpZ25hdHVyZS4qOiBoaWRkZW4KY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZWN1cml0eS5zaWduYXR1cmUucmVmZXJlbmNlLio6IGhpZGRlbgpjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlY3VyaXR5LnRyYW5zZm9ybXMuKjogaGlkZGVuCmNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VjdXJpdHkudHJhbnNmb3Jtcy5pbXBsZW1lbnRhdGlvbnMuKjogaGlkZGVuCmNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VjdXJpdHkudHJhbnNmb3Jtcy5wYXJhbXMuKjogaGlkZGVuCmNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VjdXJpdHkudXRpbHMuKjogaGlkZGVuCmNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VjdXJpdHkudXRpbHMucmVzb2x2ZXIuKjogaGlkZGVuCmNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VjdXJpdHkudXRpbHMucmVzb2x2ZXIuaW1wbGVtZW50YXRpb25zLio6IGhpZGRlbgpjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZS4qOiBwcm9wcmlldGFyeSBjb21wYWN0Mgpjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnNlcmlhbGl6ZXIuKjogcHJvcHJpZXRhcnkgY29tcGFjdDIKY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC5zZXJpYWxpemVyLmRvbTMuKjogaGlkZGVuCmNvbS5zdW4ub3JnLmFwYWNoZS54bWwuaW50ZXJuYWwuc2VyaWFsaXplci51dGlscy4qOiBoaWRkZW4KY29tLnN1bi5vcmcuYXBhY2hlLnhtbC5pbnRlcm5hbC51dGlscy4qOiBwcm9wcmlldGFyeSBjb21wYWN0Mgpjb20uc3VuLm9yZy5hcGFjaGUueG1sLmludGVybmFsLnV0aWxzLnJlcy4qOiBwcm9wcmlldGFyeSBjb21wYWN0Mgpjb20uc3VuLm9yZy5hcGFjaGUueHBhdGguaW50ZXJuYWwuKjogcHJvcHJpZXRhcnkgY29tcGFjdDIKY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmF4ZXMuKjogcHJvcHJpZXRhcnkgY29tcGFjdDIKY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmNvbXBpbGVyLio6IHByb3ByaWV0YXJ5IGNvbXBhY3QyCmNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5kb21hcGkuKjogaGlkZGVuCmNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5mdW5jdGlvbnMuKjogcHJvcHJpZXRhcnkgY29tcGFjdDIKY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLmpheHAuKjogcHJvcHJpZXRhcnkgY29tcGFjdDIKY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9iamVjdHMuKjogcHJvcHJpZXRhcnkgY29tcGFjdDIKY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLm9wZXJhdGlvbnMuKjogcHJvcHJpZXRhcnkgY29tcGFjdDIKY29tLnN1bi5vcmcuYXBhY2hlLnhwYXRoLmludGVybmFsLnBhdHRlcm5zLio6IHByb3ByaWV0YXJ5IGNvbXBhY3QyCmNvbS5zdW4ub3JnLmFwYWNoZS54cGF0aC5pbnRlcm5hbC5yZXMuKjogcHJvcHJpZXRhcnkgY29tcGFjdDIKY29tLnN1bi5vcmcuZ2xhc3NmaXNoLmV4dGVybmFsLmFteC4qOiBoaWRkZW4KY29tLnN1bi5vcmcuZ2xhc3NmaXNoLmV4dGVybmFsLmFyYy4qOiBoaWRkZW4KY29tLnN1bi5vcmcuZ2xhc3NmaXNoLmV4dGVybmFsLnByb2JlLnByb3ZpZGVyLio6IGhpZGRlbgpjb20uc3VuLm9yZy5nbGFzc2Zpc2guZXh0ZXJuYWwucHJvYmUucHJvdmlkZXIuYW5ub3RhdGlvbnMuKjogaGlkZGVuCmNvbS5zdW4ub3JnLmdsYXNzZmlzaC5leHRlcm5hbC5zdGF0aXN0aWNzLio6IGhpZGRlbgpjb20uc3VuLm9yZy5nbGFzc2Zpc2guZXh0ZXJuYWwuc3RhdGlzdGljcy5hbm5vdGF0aW9ucy4qOiBoaWRkZW4KY29tLnN1bi5vcmcuZ2xhc3NmaXNoLmV4dGVybmFsLnN0YXRpc3RpY3MuaW1wbC4qOiBoaWRkZW4KY29tLnN1bi5vcmcuZ2xhc3NmaXNoLmdtYmFsLio6IGhpZGRlbgpjb20uc3VuLm9yZy5nbGFzc2Zpc2guZ21iYWwudXRpbC4qOiBoaWRkZW4KY29tLnN1bi5vcmcub21nLkNPUkJBLio6IHByb3ByaWV0YXJ5CmNvbS5zdW4ub3JnLm9tZy5DT1JCQS5WYWx1ZURlZlBhY2thZ2UuKjogcHJvcHJpZXRhcnkKY29tLnN1bi5vcmcub21nLkNPUkJBLnBvcnRhYmxlLio6IHByb3ByaWV0YXJ5CmNvbS5zdW4ub3JnLm9tZy5TZW5kaW5nQ29udGV4dC4qOiBwcm9wcmlldGFyeQpjb20uc3VuLm9yZy5vbWcuU2VuZGluZ0NvbnRleHQuQ29kZUJhc2VQYWNrYWdlLio6IHByb3ByaWV0YXJ5CmNvbS5zdW4ucm1pLnJtaWQuKjogcHJvcHJpZXRhcnkgY29tcGFjdDIKY29tLnN1bi5yb3dzZXQuKjogcHJvcHJpZXRhcnkgY29tcGFjdDMKY29tLnN1bi5yb3dzZXQuaW50ZXJuYWwuKjogcHJvcHJpZXRhcnkgY29tcGFjdDMKY29tLnN1bi5yb3dzZXQucHJvdmlkZXJzLio6IHByb3ByaWV0YXJ5IGNvbXBhY3QzCmNvbS5zdW4uc2VjdXJpdHkuYXV0aC4qOiBjb21wYWN0Mwpjb20uc3VuLnNlY3VyaXR5LmF1dGguY2FsbGJhY2suKjogY29tcGFjdDMKY29tLnN1bi5zZWN1cml0eS5hdXRoLmxvZ2luLio6IGNvbXBhY3QzCmNvbS5zdW4uc2VjdXJpdHkuYXV0aC5tb2R1bGUuKjogY29tcGFjdDMKY29tLnN1bi5zZWN1cml0eS5jZXJ0LmludGVybmFsLng1MDkuKjogcHJvcHJpZXRhcnkgY29tcGFjdDEKY29tLnN1bi5zZWN1cml0eS5qZ3NzLio6IGNvbXBhY3QzCmNvbS5zdW4uc2VjdXJpdHkubnRsbS4qOiBoaWRkZW4KY29tLnN1bi5zZWN1cml0eS5zYXNsLio6IHByb3ByaWV0YXJ5IGNvbXBhY3QzCmNvbS5zdW4uc2VjdXJpdHkuc2FzbC5kaWdlc3QuKjogcHJvcHJpZXRhcnkgY29tcGFjdDMKY29tLnN1bi5zZWN1cml0eS5zYXNsLmdzc2tlcmIuKjogcHJvcHJpZXRhcnkgY29tcGFjdDMKY29tLnN1bi5zZWN1cml0eS5zYXNsLm50bG0uKjogaGlkZGVuCmNvbS5zdW4uc2VjdXJpdHkuc2FzbC51dGlsLio6IHByb3ByaWV0YXJ5IGNvbXBhY3QzCmNvbS5zdW4uc3dpbmcuaW50ZXJuYWwucGxhZi5iYXNpYy5yZXNvdXJjZXMuKjogcHJvcHJpZXRhcnkKY29tLnN1bi5zd2luZy5pbnRlcm5hbC5wbGFmLm1ldGFsLnJlc291cmNlcy4qOiBwcm9wcmlldGFyeQpjb20uc3VuLnN3aW5nLmludGVybmFsLnBsYWYuc3ludGgucmVzb3VyY2VzLio6IHByb3ByaWV0YXJ5CmNvbS5zdW4udHJhY2luZy4qOiBwcm9wcmlldGFyeSBjb21wYWN0Mwpjb20uc3VuLnRyYWNpbmcuZHRyYWNlLio6IHByb3ByaWV0YXJ5IGNvbXBhY3QzCmNvbS5zdW4ueG1sLmludGVybmFsLmJpbmQuKjogaGlkZGVuCmNvbS5zdW4ueG1sLmludGVybmFsLmJpbmQuYW5ub3RhdGlvbi4qOiBoaWRkZW4KY29tLnN1bi54bWwuaW50ZXJuYWwuYmluZC5hcGkuKjogaGlkZGVuCmNvbS5zdW4ueG1sLmludGVybmFsLmJpbmQuYXBpLmltcGwuKjogaGlkZGVuCmNvbS5zdW4ueG1sLmludGVybmFsLmJpbmQubWFyc2hhbGxlci4qOiBoaWRkZW4KY29tLnN1bi54bWwuaW50ZXJuYWwuYmluZC51bm1hcnNoYWxsZXIuKjogaGlkZGVuCmNvbS5zdW4ueG1sLmludGVybmFsLmJpbmQudXRpbC4qOiBoaWRkZW4KY29tLnN1bi54bWwuaW50ZXJuYWwuYmluZC52Mi4qOiBoaWRkZW4KY29tLnN1bi54bWwuaW50ZXJuYWwuYmluZC52Mi5ieXRlY29kZS4qOiBoaWRkZW4KY29tLnN1bi54bWwuaW50ZXJuYWwuYmluZC52Mi5tb2RlbC5hbm5vdGF0aW9uLio6IGhpZGRlbgpjb20uc3VuLnhtbC5pbnRlcm5hbC5iaW5kLnYyLm1vZGVsLmNvcmUuKjogaGlkZGVuCmNvbS5zdW4ueG1sLmludGVybmFsLmJpbmQudjIubW9kZWwuaW1wbC4qOiBoaWRkZW4KY29tLnN1bi54bWwuaW50ZXJuYWwuYmluZC52Mi5tb2RlbC5uYXYuKjogaGlkZGVuCmNvbS5zdW4ueG1sLmludGVybmFsLmJpbmQudjIubW9kZWwucnVudGltZS4qOiBoaWRkZW4KY29tLnN1bi54bWwuaW50ZXJuYWwuYmluZC52Mi5tb2RlbC51dGlsLio6IGhpZGRlbgpjb20uc3VuLnhtbC5pbnRlcm5hbC5iaW5kLnYyLnJ1bnRpbWUuKjogaGlkZGVuCmNvbS5zdW4ueG1sLmludGVybmFsLmJpbmQudjIucnVudGltZS5vdXRwdXQuKjogaGlkZGVuCmNvbS5zdW4ueG1sLmludGVybmFsLmJpbmQudjIucnVudGltZS5wcm9wZXJ0eS4qOiBoaWRkZW4KY29tLnN1bi54bWwuaW50ZXJuYWwuYmluZC52Mi5ydW50aW1lLnJlZmxlY3QuKjogaGlkZGVuCmNvbS5zdW4ueG1sLmludGVybmFsLmJpbmQudjIucnVudGltZS5yZWZsZWN0Lm9wdC4qOiBoaWRkZW4KY29tLnN1bi54bWwuaW50ZXJuYWwuYmluZC52Mi5ydW50aW1lLnVubWFyc2hhbGxlci4qOiBoaWRkZW4KY29tLnN1bi54bWwuaW50ZXJuYWwuYmluZC52Mi5zY2hlbWFnZW4uKjogaGlkZGVuCmNvbS5zdW4ueG1sLmludGVybmFsLmJpbmQudjIuc2NoZW1hZ2VuLmVwaXNvZGUuKjogaGlkZGVuCmNvbS5zdW4ueG1sLmludGVybmFsLmJpbmQudjIuc2NoZW1hZ2VuLnhtbHNjaGVtYS4qOiBoaWRkZW4KY29tLnN1bi54bWwuaW50ZXJuYWwuYmluZC52Mi51dGlsLio6IGhpZGRlbgpjb20uc3VuLnhtbC5pbnRlcm5hbC5mYXN0aW5mb3NldC4qOiBoaWRkZW4KY29tLnN1bi54bWwuaW50ZXJuYWwuZmFzdGluZm9zZXQuYWxnb3JpdGhtLio6IGhpZGRlbgpjb20uc3VuLnhtbC5pbnRlcm5hbC5mYXN0aW5mb3NldC5hbHBoYWJldC4qOiBoaWRkZW4KY29tLnN1bi54bWwuaW50ZXJuYWwuZmFzdGluZm9zZXQuZG9tLio6IGhpZGRlbgpjb20uc3VuLnhtbC5pbnRlcm5hbC5mYXN0aW5mb3NldC5vcmcuYXBhY2hlLnhlcmNlcy51dGlsLio6IGhpZGRlbgpjb20uc3VuLnhtbC5pbnRlcm5hbC5mYXN0aW5mb3NldC5zYXguKjogaGlkZGVuCmNvbS5zdW4ueG1sLmludGVybmFsLmZhc3RpbmZvc2V0LnN0YXguKjogaGlkZGVuCmNvbS5zdW4ueG1sLmludGVybmFsLmZhc3RpbmZvc2V0LnN0YXguZXZlbnRzLio6IGhpZGRlbgpjb20uc3VuLnhtbC5pbnRlcm5hbC5mYXN0aW5mb3NldC5zdGF4LmZhY3RvcnkuKjogaGlkZGVuCmNvbS5zdW4ueG1sLmludGVybmFsLmZhc3RpbmZvc2V0LnN0YXgudXRpbC4qOiBoaWRkZW4KY29tLnN1bi54bWwuaW50ZXJuYWwuZmFzdGluZm9zZXQudG9vbHMuKjogaGlkZGVuCmNvbS5zdW4ueG1sLmludGVybmFsLmZhc3RpbmZvc2V0LnV0aWwuKjogaGlkZGVuCmNvbS5zdW4ueG1sLmludGVybmFsLmZhc3RpbmZvc2V0LnZvY2FiLio6IGhpZGRlbgpjb20uc3VuLnhtbC5pbnRlcm5hbC5tZXNzYWdpbmcuc2Fhai4qOiBoaWRkZW4KY29tLnN1bi54bWwuaW50ZXJuYWwubWVzc2FnaW5nLnNhYWouY2xpZW50LnAycC4qOiBoaWRkZW4KY29tLnN1bi54bWwuaW50ZXJuYWwubWVzc2FnaW5nLnNhYWoucGFja2FnaW5nLm1pbWUuKjogaGlkZGVuCmNvbS5zdW4ueG1sLmludGVybmFsLm1lc3NhZ2luZy5zYWFqLnBhY2thZ2luZy5taW1lLmludGVybmV0Lio6IGhpZGRlbgpjb20uc3VuLnhtbC5pbnRlcm5hbC5tZXNzYWdpbmcuc2Fhai5wYWNrYWdpbmcubWltZS51dGlsLio6IGhpZGRlbgpjb20uc3VuLnhtbC5pbnRlcm5hbC5tZXNzYWdpbmcuc2Fhai5zb2FwLio6IGhpZGRlbgpjb20uc3VuLnhtbC5pbnRlcm5hbC5tZXNzYWdpbmcuc2Fhai5zb2FwLmR5bmFtaWMuKjogaGlkZGVuCmNvbS5zdW4ueG1sLmludGVybmFsLm1lc3NhZ2luZy5zYWFqLnNvYXAuaW1wbC4qOiBoaWRkZW4KY29tLnN1bi54bWwuaW50ZXJuYWwubWVzc2FnaW5nLnNhYWouc29hcC5uYW1lLio6IGhpZGRlbgpjb20uc3VuLnhtbC5pbnRlcm5hbC5tZXNzYWdpbmcuc2Fhai5zb2FwLnZlcjFfMS4qOiBoaWRkZW4KY29tLnN1bi54bWwuaW50ZXJuYWwubWVzc2FnaW5nLnNhYWouc29hcC52ZXIxXzIuKjogaGlkZGVuCmNvbS5zdW4ueG1sLmludGVybmFsLm1lc3NhZ2luZy5zYWFqLnV0aWwuKjogaGlkZGVuCmNvbS5zdW4ueG1sLmludGVybmFsLm1lc3NhZ2luZy5zYWFqLnV0aWwuc3RheC4qOiBoaWRkZW4KY29tLnN1bi54bWwuaW50ZXJuYWwubWVzc2FnaW5nLnNhYWoudXRpbC50cmFuc2Zvcm0uKjogaGlkZGVuCmNvbS5zdW4ueG1sLmludGVybmFsLm9yZy5qdm5ldC5mYXN0aW5mb3NldC4qOiBoaWRkZW4KY29tLnN1bi54bWwuaW50ZXJuYWwub3JnLmp2bmV0LmZhc3RpbmZvc2V0LnNheC4qOiBoaWRkZW4KY29tLnN1bi54bWwuaW50ZXJuYWwub3JnLmp2bmV0LmZhc3RpbmZvc2V0LnNheC5oZWxwZXJzLio6IGhpZGRlbgpjb20uc3VuLnhtbC5pbnRlcm5hbC5vcmcuanZuZXQuZmFzdGluZm9zZXQuc3RheC4qOiBoaWRkZW4KY29tLnN1bi54bWwuaW50ZXJuYWwub3JnLmp2bmV0Lm1pbWVwdWxsLio6IGhpZGRlbgpjb20uc3VuLnhtbC5pbnRlcm5hbC5vcmcuanZuZXQuc3RheGV4Lio6IGhpZGRlbgpjb20uc3VuLnhtbC5pbnRlcm5hbC5vcmcuanZuZXQuc3RheGV4LnV0aWwuKjogaGlkZGVuCmNvbS5zdW4ueG1sLmludGVybmFsLnN0cmVhbS4qOiBoaWRkZW4KY29tLnN1bi54bWwuaW50ZXJuYWwuc3RyZWFtLmJ1ZmZlci4qOiBoaWRkZW4KY29tLnN1bi54bWwuaW50ZXJuYWwuc3RyZWFtLmJ1ZmZlci5zYXguKjogaGlkZGVuCmNvbS5zdW4ueG1sLmludGVybmFsLnN0cmVhbS5idWZmZXIuc3RheC4qOiBoaWRkZW4KY29tLnN1bi54bWwuaW50ZXJuYWwuc3RyZWFtLmR0ZC4qOiBoaWRkZW4KY29tLnN1bi54bWwuaW50ZXJuYWwuc3RyZWFtLmR0ZC5ub252YWxpZGF0aW5nLio6IGhpZGRlbgpjb20uc3VuLnhtbC5pbnRlcm5hbC5zdHJlYW0uZXZlbnRzLio6IGhpZGRlbgpjb20uc3VuLnhtbC5pbnRlcm5hbC5zdHJlYW0udXRpbC4qOiBoaWRkZW4KY29tLnN1bi54bWwuaW50ZXJuYWwuc3RyZWFtLndyaXRlcnMuKjogaGlkZGVuCmNvbS5zdW4ueG1sLmludGVybmFsLnR4dzIuKjogaGlkZGVuCmNvbS5zdW4ueG1sLmludGVybmFsLnR4dzIuYW5ub3RhdGlvbi4qOiBoaWRkZW4KY29tLnN1bi54bWwuaW50ZXJuYWwudHh3Mi5vdXRwdXQuKjogaGlkZGVuCmNvbS5zdW4ueG1sLmludGVybmFsLndzLio6IGhpZGRlbgpjb20uc3VuLnhtbC5pbnRlcm5hbC53cy5hZGRyZXNzaW5nLio6IGhpZGRlbgpjb20uc3VuLnhtbC5pbnRlcm5hbC53cy5hZGRyZXNzaW5nLm1vZGVsLio6IGhpZGRlbgpjb20uc3VuLnhtbC5pbnRlcm5hbC53cy5hZGRyZXNzaW5nLnBvbGljeS4qOiBoaWRkZW4KY29tLnN1bi54bWwuaW50ZXJuYWwud3MuYWRkcmVzc2luZy52MjAwNDA4Lio6IGhpZGRlbgpjb20uc3VuLnhtbC5pbnRlcm5hbC53cy5hcGkuKjogaGlkZGVuCmNvbS5zdW4ueG1sLmludGVybmFsLndzLmFwaS5hZGRyZXNzaW5nLio6IGhpZGRlbgpjb20uc3VuLnhtbC5pbnRlcm5hbC53cy5hcGkuY2xpZW50Lio6IGhpZGRlbgpjb20uc3VuLnhtbC5pbnRlcm5hbC53cy5hcGkuY29uZmlnLm1hbmFnZW1lbnQuKjogaGlkZGVuCmNvbS5zdW4ueG1sLmludGVybmFsLndzLmFwaS5jb25maWcubWFuYWdlbWVudC5wb2xpY3kuKjogaGlkZGVuCmNvbS5zdW4ueG1sLmludGVybmFsLndzLmFwaS5kYXRhYmluZGluZy4qOiBoaWRkZW4KY29tLnN1bi54bWwuaW50ZXJuYWwud3MuYXBpLmZhc3RpbmZvc2V0Lio6IGhpZGRlbgpjb20uc3VuLnhtbC5pbnRlcm5hbC53cy5hcGkuaGEuKjogaGlkZGVuCmNvbS5zdW4ueG1sLmludGVybmFsLndzLmFwaS5oYW5kbGVyLio6IGhpZGRlbgpjb20uc3VuLnhtbC5pbnRlcm5hbC53cy5hcGkubWVzc2FnZS4qOiBoaWRkZW4KY29tLnN1bi54bWwuaW50ZXJuYWwud3MuYXBpLm1lc3NhZ2Uuc2Fhai4qOiBoaWRkZW4KY29tLnN1bi54bWwuaW50ZXJuYWwud3MuYXBpLm1lc3NhZ2Uuc3RyZWFtLio6IGhpZGRlbgpjb20uc3VuLnhtbC5pbnRlcm5hbC53cy5hcGkubW9kZWwuKjogaGlkZGVuCmNvbS5zdW4ueG1sLmludGVybmFsLndzLmFwaS5tb2RlbC5zb2FwLio6IGhpZGRlbgpjb20uc3VuLnhtbC5pbnRlcm5hbC53cy5hcGkubW9kZWwud3NkbC4qOiBoaWRkZW4KY29tLnN1bi54bWwuaW50ZXJuYWwud3MuYXBpLm1vZGVsLndzZGwuZWRpdGFibGUuKjogaGlkZGVuCmNvbS5zdW4ueG1sLmludGVybmFsLndzLmFwaS5waXBlLio6IGhpZGRlbgpjb20uc3VuLnhtbC5pbnRlcm5hbC53cy5hcGkucGlwZS5oZWxwZXIuKjogaGlkZGVuCmNvbS5zdW4ueG1sLmludGVybmFsLndzLmFwaS5wb2xpY3kuKjogaGlkZGVuCmNvbS5zdW4ueG1sLmludGVybmFsLndzLmFwaS5wb2xpY3kuc3ViamVjdC4qOiBoaWRkZW4KY29tLnN1bi54bWwuaW50ZXJuYWwud3MuYXBpLnNlcnZlci4qOiBoaWRkZW4KY29tLnN1bi54bWwuaW50ZXJuYWwud3MuYXBpLnN0cmVhbWluZy4qOiBoaWRkZW4KY29tLnN1bi54bWwuaW50ZXJuYWwud3MuYXBpLndzZGwucGFyc2VyLio6IGhpZGRlbgpjb20uc3VuLnhtbC5pbnRlcm5hbC53cy5hcGkud3NkbC53cml0ZXIuKjogaGlkZGVuCmNvbS5zdW4ueG1sLmludGVybmFsLndzLmFzc2VtYmxlci4qOiBoaWRkZW4KY29tLnN1bi54bWwuaW50ZXJuYWwud3MuYXNzZW1ibGVyLmRldi4qOiBoaWRkZW4KY29tLnN1bi54bWwuaW50ZXJuYWwud3MuYXNzZW1ibGVyLmpheHdzLio6IGhpZGRlbgpjb20uc3VuLnhtbC5pbnRlcm5hbC53cy5iaW5kaW5nLio6IGhpZGRlbgpjb20uc3VuLnhtbC5pbnRlcm5hbC53cy5jbGllbnQuKjogaGlkZGVuCmNvbS5zdW4ueG1sLmludGVybmFsLndzLmNsaWVudC5kaXNwYXRjaC4qOiBoaWRkZW4KY29tLnN1bi54bWwuaW50ZXJuYWwud3MuY2xpZW50LnNlaS4qOiBoaWRkZW4KY29tLnN1bi54bWwuaW50ZXJuYWwud3MuY29tbW9ucy54bWx1dGlsLio6IGhpZGRlbgpjb20uc3VuLnhtbC5pbnRlcm5hbC53cy5jb25maWcubWFuYWdlbWVudC5wb2xpY3kuKjogaGlkZGVuCmNvbS5zdW4ueG1sLmludGVybmFsLndzLmNvbmZpZy5tZXRyby5kZXYuKjogaGlkZGVuCmNvbS5zdW4ueG1sLmludGVybmFsLndzLmNvbmZpZy5tZXRyby51dGlsLio6IGhpZGRlbgpjb20uc3VuLnhtbC5pbnRlcm5hbC53cy5kYi4qOiBoaWRkZW4KY29tLnN1bi54bWwuaW50ZXJuYWwud3MuZGIuZ2xhc3NmaXNoLio6IGhpZGRlbgpjb20uc3VuLnhtbC5pbnRlcm5hbC53cy5kZXZlbG9wZXIuKjogaGlkZGVuCmNvbS5zdW4ueG1sLmludGVybmFsLndzLmR1bXAuKjogaGlkZGVuCmNvbS5zdW4ueG1sLmludGVybmFsLndzLmVuY29kaW5nLio6IGhpZGRlbgpjb20uc3VuLnhtbC5pbnRlcm5hbC53cy5lbmNvZGluZy5mYXN0aW5mb3NldC4qOiBoaWRkZW4KY29tLnN1bi54bWwuaW50ZXJuYWwud3MuZW5jb2RpbmcucG9saWN5Lio6IGhpZGRlbgpjb20uc3VuLnhtbC5pbnRlcm5hbC53cy5lbmNvZGluZy5zb2FwLio6IGhpZGRlbgpjb20uc3VuLnhtbC5pbnRlcm5hbC53cy5lbmNvZGluZy5zb2FwLnN0cmVhbWluZy4qOiBoaWRkZW4KY29tLnN1bi54bWwuaW50ZXJuYWwud3MuZW5jb2RpbmcueG1sLio6IGhpZGRlbgpjb20uc3VuLnhtbC5pbnRlcm5hbC53cy5mYXVsdC4qOiBoaWRkZW4KY29tLnN1bi54bWwuaW50ZXJuYWwud3MuaGFuZGxlci4qOiBoaWRkZW4KY29tLnN1bi54bWwuaW50ZXJuYWwud3MubWVzc2FnZS4qOiBoaWRkZW4KY29tLnN1bi54bWwuaW50ZXJuYWwud3MubWVzc2FnZS5qYXhiLio6IGhpZGRlbgpjb20uc3VuLnhtbC5pbnRlcm5hbC53cy5tZXNzYWdlLnNhYWouKjogaGlkZGVuCmNvbS5zdW4ueG1sLmludGVybmFsLndzLm1lc3NhZ2Uuc291cmNlLio6IGhpZGRlbgpjb20uc3VuLnhtbC5pbnRlcm5hbC53cy5tZXNzYWdlLnN0cmVhbS4qOiBoaWRkZW4KY29tLnN1bi54bWwuaW50ZXJuYWwud3MubW9kZWwuKjogaGlkZGVuCmNvbS5zdW4ueG1sLmludGVybmFsLndzLm1vZGVsLnNvYXAuKjogaGlkZGVuCmNvbS5zdW4ueG1sLmludGVybmFsLndzLm1vZGVsLndzZGwuKjogaGlkZGVuCmNvbS5zdW4ueG1sLmludGVybmFsLndzLm9yZy5vYmplY3R3ZWIuYXNtLio6IGhpZGRlbgpjb20uc3VuLnhtbC5pbnRlcm5hbC53cy5wb2xpY3kuKjogaGlkZGVuCmNvbS5zdW4ueG1sLmludGVybmFsLndzLnBvbGljeS5qYXh3cy4qOiBoaWRkZW4KY29tLnN1bi54bWwuaW50ZXJuYWwud3MucG9saWN5LmpheHdzLnNwaS4qOiBoaWRkZW4KY29tLnN1bi54bWwuaW50ZXJuYWwud3MucG9saWN5LnByaXZhdGV1dGlsLio6IGhpZGRlbgpjb20uc3VuLnhtbC5pbnRlcm5hbC53cy5wb2xpY3kuc291cmNlbW9kZWwuKjogaGlkZGVuCmNvbS5zdW4ueG1sLmludGVybmFsLndzLnBvbGljeS5zb3VyY2Vtb2RlbC5hdHRhY2guKjogaGlkZGVuCmNvbS5zdW4ueG1sLmludGVybmFsLndzLnBvbGljeS5zb3VyY2Vtb2RlbC53c3BvbGljeS4qOiBoaWRkZW4KY29tLnN1bi54bWwuaW50ZXJuYWwud3MucG9saWN5LnNwaS4qOiBoaWRkZW4KY29tLnN1bi54bWwuaW50ZXJuYWwud3MucG9saWN5LnN1YmplY3QuKjogaGlkZGVuCmNvbS5zdW4ueG1sLmludGVybmFsLndzLnByb3RvY29sLnNvYXAuKjogaGlkZGVuCmNvbS5zdW4ueG1sLmludGVybmFsLndzLnByb3RvY29sLnhtbC4qOiBoaWRkZW4KY29tLnN1bi54bWwuaW50ZXJuYWwud3MucmVzb3VyY2VzLio6IGhpZGRlbgpjb20uc3VuLnhtbC5pbnRlcm5hbC53cy5ydW50aW1lLmNvbmZpZy4qOiBoaWRkZW4KY29tLnN1bi54bWwuaW50ZXJuYWwud3Muc2VydmVyLio6IGhpZGRlbgpjb20uc3VuLnhtbC5pbnRlcm5hbC53cy5zZXJ2ZXIucHJvdmlkZXIuKjogaGlkZGVuCmNvbS5zdW4ueG1sLmludGVybmFsLndzLnNlcnZlci5zZWkuKjogaGlkZGVuCmNvbS5zdW4ueG1sLmludGVybmFsLndzLnNwaS4qOiBoaWRkZW4KY29tLnN1bi54bWwuaW50ZXJuYWwud3Muc3BpLmRiLio6IGhpZGRlbgpjb20uc3VuLnhtbC5pbnRlcm5hbC53cy5zdHJlYW1pbmcuKjogaGlkZGVuCmNvbS5zdW4ueG1sLmludGVybmFsLndzLnRyYW5zcG9ydC4qOiBoaWRkZW4KY29tLnN1bi54bWwuaW50ZXJuYWwud3MudHJhbnNwb3J0Lmh0dHAuKjogaGlkZGVuCmNvbS5zdW4ueG1sLmludGVybmFsLndzLnRyYW5zcG9ydC5odHRwLmNsaWVudC4qOiBoaWRkZW4KY29tLnN1bi54bWwuaW50ZXJuYWwud3MudHJhbnNwb3J0Lmh0dHAuc2VydmVyLio6IGhpZGRlbgpjb20uc3VuLnhtbC5pbnRlcm5hbC53cy51dGlsLio6IGhpZGRlbgpjb20uc3VuLnhtbC5pbnRlcm5hbC53cy51dGlsLmV4Y2VwdGlvbi4qOiBoaWRkZW4KY29tLnN1bi54bWwuaW50ZXJuYWwud3MudXRpbC5waXBlLio6IGhpZGRlbgpjb20uc3VuLnhtbC5pbnRlcm5hbC53cy51dGlsLnhtbC4qOiBoaWRkZW4KY29tLnN1bi54bWwuaW50ZXJuYWwud3Mud3NkbC4qOiBoaWRkZW4KY29tLnN1bi54bWwuaW50ZXJuYWwud3Mud3NkbC5wYXJzZXIuKjogaGlkZGVuCmNvbS5zdW4ueG1sLmludGVybmFsLndzLndzZGwud3JpdGVyLio6IGhpZGRlbgpjb20uc3VuLnhtbC5pbnRlcm5hbC53cy53c2RsLndyaXRlci5kb2N1bWVudC4qOiBoaWRkZW4KY29tLnN1bi54bWwuaW50ZXJuYWwud3Mud3NkbC53cml0ZXIuZG9jdW1lbnQuaHR0cC4qOiBoaWRkZW4KY29tLnN1bi54bWwuaW50ZXJuYWwud3Mud3NkbC53cml0ZXIuZG9jdW1lbnQuc29hcC4qOiBoaWRkZW4KY29tLnN1bi54bWwuaW50ZXJuYWwud3Mud3NkbC53cml0ZXIuZG9jdW1lbnQuc29hcDEyLio6IGhpZGRlbgpjb20uc3VuLnhtbC5pbnRlcm5hbC53cy53c2RsLndyaXRlci5kb2N1bWVudC54c2QuKjogaGlkZGVuCmphdmEuYXd0LmRuZC5wZWVyLio6IHByb3ByaWV0YXJ5CmphdmEuYXd0LnBlZXIuKjogcHJvcHJpZXRhcnkKamF2YS5kZXNrdG9wLm1hY29zeC5jbGFzc2VzLmNvbS5hcHBsZS5sYWYucmVzb3VyY2VzLio6IGhpZGRlbgpqYXZhLmRlc2t0b3AubWFjb3N4LmNsYXNzZXMuc3VuLmF3dC5yZXNvdXJjZXMuKjogaGlkZGVuCmphdmEuZGVza3RvcC53aW5kb3dzLmNsYXNzZXMuc3VuLmF3dC53aW5kb3dzLio6IGhpZGRlbgpqYXZhLmlvLio6IGNvbXBhY3QxCmphdmEubGFuZy4qOiBjb21wYWN0MQpqYXZhLmxhbmcuYW5ub3RhdGlvbi4qOiBjb21wYWN0MQpqYXZhLmxhbmcuaW5zdHJ1bWVudC4qOiBjb21wYWN0MwpqYXZhLmxhbmcuaW52b2tlLio6IGNvbXBhY3QxCmphdmEubGFuZy5tYW5hZ2VtZW50Lio6IGNvbXBhY3QzCmphdmEubGFuZy5yZWYuKjogY29tcGFjdDEKamF2YS5sYW5nLnJlZmxlY3QuKjogY29tcGFjdDEKamF2YS5tYXRoLio6IGNvbXBhY3QxCmphdmEubmV0Lio6IGNvbXBhY3QxCmphdmEubmlvLio6IGNvbXBhY3QxCmphdmEubmlvLmNoYW5uZWxzLio6IGNvbXBhY3QxCmphdmEubmlvLmNoYW5uZWxzLnNwaS4qOiBjb21wYWN0MQpqYXZhLm5pby5jaGFyc2V0Lio6IGNvbXBhY3QxCmphdmEubmlvLmNoYXJzZXQuc3BpLio6IGNvbXBhY3QxCmphdmEubmlvLmZpbGUuKjogY29tcGFjdDEKamF2YS5uaW8uZmlsZS5hdHRyaWJ1dGUuKjogY29tcGFjdDEKamF2YS5uaW8uZmlsZS5zcGkuKjogY29tcGFjdDEKamF2YS5ybWkuKjogY29tcGFjdDIKamF2YS5ybWkuYWN0aXZhdGlvbi4qOiBjb21wYWN0MgpqYXZhLnJtaS5kZ2MuKjogY29tcGFjdDIKamF2YS5ybWkucmVnaXN0cnkuKjogY29tcGFjdDIKamF2YS5ybWkuc2VydmVyLio6IGNvbXBhY3QyCmphdmEuc2VjdXJpdHkuKjogY29tcGFjdDEKamF2YS5zZWN1cml0eS5hY2wuKjogY29tcGFjdDEKamF2YS5zZWN1cml0eS5jZXJ0Lio6IGNvbXBhY3QxCmphdmEuc2VjdXJpdHkuaW50ZXJmYWNlcy4qOiBjb21wYWN0MQpqYXZhLnNlY3VyaXR5LnNwZWMuKjogY29tcGFjdDEKamF2YS5zcWwuKjogY29tcGFjdDIKamF2YS50ZXh0Lio6IGNvbXBhY3QxCmphdmEudGV4dC5zcGkuKjogY29tcGFjdDEKamF2YS50aW1lLio6IGNvbXBhY3QxCmphdmEudGltZS5jaHJvbm8uKjogY29tcGFjdDEKamF2YS50aW1lLmZvcm1hdC4qOiBjb21wYWN0MQpqYXZhLnRpbWUudGVtcG9yYWwuKjogY29tcGFjdDEKamF2YS50aW1lLnpvbmUuKjogY29tcGFjdDEKamF2YS51dGlsLio6IGNvbXBhY3QxCmphdmEudXRpbC5jb25jdXJyZW50Lio6IGNvbXBhY3QxCmphdmEudXRpbC5jb25jdXJyZW50LmF0b21pYy4qOiBjb21wYWN0MQpqYXZhLnV0aWwuY29uY3VycmVudC5sb2Nrcy4qOiBjb21wYWN0MQpqYXZhLnV0aWwuZnVuY3Rpb24uKjogY29tcGFjdDEKamF2YS51dGlsLmphci4qOiBjb21wYWN0MQpqYXZhLnV0aWwubG9nZ2luZy4qOiBjb21wYWN0MQpqYXZhLnV0aWwucHJlZnMuKjogY29tcGFjdDMKamF2YS51dGlsLnJlZ2V4Lio6IGNvbXBhY3QxCmphdmEudXRpbC5zcGkuKjogY29tcGFjdDEKamF2YS51dGlsLnN0cmVhbS4qOiBjb21wYWN0MQpqYXZhLnV0aWwuemlwLio6IGNvbXBhY3QxCmphdmF4LmFubm90YXRpb24ucHJvY2Vzc2luZy4qOiBjb21wYWN0MwpqYXZheC5sYW5nLm1vZGVsLio6IGNvbXBhY3QzCmphdmF4LmxhbmcubW9kZWwuZWxlbWVudC4qOiBjb21wYWN0MwpqYXZheC5sYW5nLm1vZGVsLnR5cGUuKjogY29tcGFjdDMKamF2YXgubGFuZy5tb2RlbC51dGlsLio6IGNvbXBhY3QzCmphdmF4Lm1hbmFnZW1lbnQuKjogY29tcGFjdDMKamF2YXgubWFuYWdlbWVudC5sb2FkaW5nLio6IGNvbXBhY3QzCmphdmF4Lm1hbmFnZW1lbnQubW9kZWxtYmVhbi4qOiBjb21wYWN0MwpqYXZheC5tYW5hZ2VtZW50Lm1vbml0b3IuKjogY29tcGFjdDMKamF2YXgubWFuYWdlbWVudC5vcGVubWJlYW4uKjogY29tcGFjdDMKamF2YXgubWFuYWdlbWVudC5yZWxhdGlvbi4qOiBjb21wYWN0MwpqYXZheC5tYW5hZ2VtZW50LnJlbW90ZS4qOiBjb21wYWN0MwpqYXZheC5tYW5hZ2VtZW50LnJlbW90ZS5ybWkuKjogY29tcGFjdDMKamF2YXgubWFuYWdlbWVudC50aW1lci4qOiBjb21wYWN0MwpqYXZheC5uYW1pbmcuKjogY29tcGFjdDMKamF2YXgubmFtaW5nLmRpcmVjdG9yeS4qOiBjb21wYWN0MwpqYXZheC5uYW1pbmcuZXZlbnQuKjogY29tcGFjdDMKamF2YXgubmFtaW5nLmxkYXAuKjogY29tcGFjdDMKamF2YXgubmFtaW5nLnNwaS4qOiBjb21wYWN0MwpqYXZheC5uZXQuKjogY29tcGFjdDEKamF2YXgubmV0LnNzbC4qOiBjb21wYWN0MQpqYXZheC5ybWkuc3NsLio6IGNvbXBhY3QyCmphdmF4LnNjcmlwdC4qOiBjb21wYWN0MQpqYXZheC5zZWN1cml0eS5hdXRoLio6IGNvbXBhY3QxCmphdmF4LnNlY3VyaXR5LmF1dGguY2FsbGJhY2suKjogY29tcGFjdDEKamF2YXguc2VjdXJpdHkuYXV0aC5rZXJiZXJvcy4qOiBjb21wYWN0MwpqYXZheC5zZWN1cml0eS5hdXRoLmxvZ2luLio6IGNvbXBhY3QxCmphdmF4LnNlY3VyaXR5LmF1dGguc3BpLio6IGNvbXBhY3QxCmphdmF4LnNlY3VyaXR5LmF1dGgueDUwMC4qOiBjb21wYWN0MQpqYXZheC5zZWN1cml0eS5jZXJ0Lio6IGNvbXBhY3QxCmphdmF4LnNlY3VyaXR5LnNhc2wuKjogY29tcGFjdDMKamF2YXguc21hcnRjYXJkaW8uKjogY29tcGFjdDMKamF2YXguc3FsLio6IGNvbXBhY3QyCmphdmF4LnNxbC5yb3dzZXQuKjogY29tcGFjdDMKamF2YXguc3FsLnJvd3NldC5zZXJpYWwuKjogY29tcGFjdDMKamF2YXguc3FsLnJvd3NldC5zcGkuKjogY29tcGFjdDMKamF2YXgudG9vbHMuKjogY29tcGFjdDMKamF2YXgudHJhbnNhY3Rpb24ueGEuKjogY29tcGFjdDIKamF2YXgueG1sLio6IGNvbXBhY3QyCmphdmF4LnhtbC5jcnlwdG8uKjogY29tcGFjdDMKamF2YXgueG1sLmNyeXB0by5kb20uKjogY29tcGFjdDMKamF2YXgueG1sLmNyeXB0by5kc2lnLio6IGNvbXBhY3QzCmphdmF4LnhtbC5jcnlwdG8uZHNpZy5kb20uKjogY29tcGFjdDMKamF2YXgueG1sLmNyeXB0by5kc2lnLmtleWluZm8uKjogY29tcGFjdDMKamF2YXgueG1sLmNyeXB0by5kc2lnLnNwZWMuKjogY29tcGFjdDMKamF2YXgueG1sLmRhdGF0eXBlLio6IGNvbXBhY3QyCmphdmF4LnhtbC5uYW1lc3BhY2UuKjogY29tcGFjdDIKamF2YXgueG1sLnBhcnNlcnMuKjogY29tcGFjdDIKamF2YXgueG1sLnN0cmVhbS4qOiBjb21wYWN0MgpqYXZheC54bWwuc3RyZWFtLmV2ZW50cy4qOiBjb21wYWN0MgpqYXZheC54bWwuc3RyZWFtLnV0aWwuKjogY29tcGFjdDIKamF2YXgueG1sLnRyYW5zZm9ybS4qOiBjb21wYWN0MgpqYXZheC54bWwudHJhbnNmb3JtLmRvbS4qOiBjb21wYWN0MgpqYXZheC54bWwudHJhbnNmb3JtLnNheC4qOiBjb21wYWN0MgpqYXZheC54bWwudHJhbnNmb3JtLnN0YXguKjogY29tcGFjdDIKamF2YXgueG1sLnRyYW5zZm9ybS5zdHJlYW0uKjogY29tcGFjdDIKamF2YXgueG1sLnZhbGlkYXRpb24uKjogY29tcGFjdDIKamF2YXgueG1sLnhwYXRoLio6IGNvbXBhY3QyCmpkay4qOiBjb21wYWN0MQpqZGsuaW50ZXJuYWwub3JnLm9iamVjdHdlYi5hc20uKjogaGlkZGVuCmpkay5pbnRlcm5hbC5vcmcub2JqZWN0d2ViLmFzbS5jb21tb25zLio6IGhpZGRlbgpqZGsuaW50ZXJuYWwub3JnLm9iamVjdHdlYi5hc20uc2lnbmF0dXJlLio6IGhpZGRlbgpqZGsuaW50ZXJuYWwub3JnLm9iamVjdHdlYi5hc20udHJlZS4qOiBoaWRkZW4KamRrLmludGVybmFsLm9yZy5vYmplY3R3ZWIuYXNtLnRyZWUuYW5hbHlzaXMuKjogaGlkZGVuCmpkay5pbnRlcm5hbC5vcmcub2JqZWN0d2ViLmFzbS51dGlsLio6IGhpZGRlbgpqZGsuaW50ZXJuYWwub3JnLnhtbC5zYXguKjogaGlkZGVuCmpkay5pbnRlcm5hbC5vcmcueG1sLnNheC5oZWxwZXJzLio6IGhpZGRlbgpqZGsuaW50ZXJuYWwudXRpbC54bWwuKjogaGlkZGVuCmpkay5pbnRlcm5hbC51dGlsLnhtbC5pbXBsLio6IGhpZGRlbgpqZGsubmV0Lio6IGNvbXBhY3QxCm9yZy5pZXRmLmpnc3MuKjogY29tcGFjdDMKb3JnLmpjcC54bWwuZHNpZy5pbnRlcm5hbC4qOiBoaWRkZW4Kb3JnLmpjcC54bWwuZHNpZy5pbnRlcm5hbC5kb20uKjogaGlkZGVuCm9yZy53M2MuZG9tLio6IGNvbXBhY3QyCm9yZy53M2MuZG9tLmJvb3RzdHJhcC4qOiBjb21wYWN0MgpvcmcudzNjLmRvbS5jc3MuKjogY29tcGFjdDIKb3JnLnczYy5kb20uZXZlbnRzLio6IGNvbXBhY3QyCm9yZy53M2MuZG9tLmh0bWwuKjogY29tcGFjdDIKb3JnLnczYy5kb20ubHMuKjogY29tcGFjdDIKb3JnLnczYy5kb20ucmFuZ2VzLio6IGNvbXBhY3QyCm9yZy53M2MuZG9tLnN0eWxlc2hlZXRzLio6IGNvbXBhY3QyCm9yZy53M2MuZG9tLnRyYXZlcnNhbC4qOiBjb21wYWN0MgpvcmcudzNjLmRvbS52aWV3cy4qOiBjb21wYWN0MgpvcmcudzNjLmRvbS54cGF0aC4qOiBoaWRkZW4Kb3JnLnhtbC5zYXguKjogY29tcGFjdDIKb3JnLnhtbC5zYXguZXh0Lio6IGNvbXBhY3QyCm9yZy54bWwuc2F4LmhlbHBlcnMuKjogY29tcGFjdDIKc3VuLmFwcGxldC4qOiBwcm9wcmlldGFyeQpzdW4uYXBwbGV0LnJlc291cmNlcy4qOiBwcm9wcmlldGFyeQpzdW4uYXd0Lio6IHByb3ByaWV0YXJ5CnN1bi5hd3QuWDExLio6IHByb3ByaWV0YXJ5CnN1bi5hd3QuZGF0YXRyYW5zZmVyLio6IHByb3ByaWV0YXJ5CnN1bi5hd3QuZG5kLio6IHByb3ByaWV0YXJ5CnN1bi5hd3QuZXZlbnQuKjogaGlkZGVuCnN1bi5hd3QuZ2VvbS4qOiBwcm9wcmlldGFyeQpzdW4uYXd0LmltLio6IHByb3ByaWV0YXJ5CnN1bi5hd3QuaW1hZ2UuKjogcHJvcHJpZXRhcnkKc3VuLmF3dC5tb3RpZi4qOiBwcm9wcmlldGFyeQpzdW4uYXd0LnJlc291cmNlcy4qOiBwcm9wcmlldGFyeQpzdW4uYXd0LnNoZWxsLio6IHByb3ByaWV0YXJ5CnN1bi5hd3QudXRpbC4qOiBoaWRkZW4Kc3VuLmF3dC53aW5kb3dzLio6IHByb3ByaWV0YXJ5CnN1bi5jb3JiYS4qOiBwcm9wcmlldGFyeQpzdW4uZGF0YXRyYW5zZmVyLio6IGhpZGRlbgpzdW4uZm9udC4qOiBwcm9wcmlldGFyeQpzdW4uaW5zdHJ1bWVudC4qOiBwcm9wcmlldGFyeSBjb21wYWN0MwpzdW4uaW52b2tlLio6IGhpZGRlbgpzdW4uaW52b2tlLmFub24uKjogaGlkZGVuCnN1bi5pbnZva2UuZW1wdHkuKjogaGlkZGVuCnN1bi5pbnZva2UudXRpbC4qOiBoaWRkZW4Kc3VuLmlvLio6IHByb3ByaWV0YXJ5IGNvbXBhY3QxCnN1bi5qYXZhMmQuKjogcHJvcHJpZXRhcnkKc3VuLmphdmEyZC5jbW0uKjogaGlkZGVuCnN1bi5qYXZhMmQuY21tLmxjbXMuKjogaGlkZGVuCnN1bi5qYXZhMmQuZDNkLio6IGhpZGRlbgpzdW4uamF2YTJkLmp1bGVzLio6IGhpZGRlbgpzdW4uamF2YTJkLmxvb3BzLio6IHByb3ByaWV0YXJ5CnN1bi5qYXZhMmQub3BlbmdsLio6IHByb3ByaWV0YXJ5CnN1bi5qYXZhMmQucGlwZS4qOiBwcm9wcmlldGFyeQpzdW4uamF2YTJkLnBpcGUuaHcuKjogaGlkZGVuCnN1bi5qYXZhMmQucGlzY2VzLio6IGhpZGRlbgpzdW4uamF2YTJkLndpbmRvd3MuKjogaGlkZGVuCnN1bi5qYXZhMmQueDExLio6IGhpZGRlbgpzdW4uamF2YTJkLnhyLio6IGhpZGRlbgpzdW4ubGF1bmNoZXIuKjogaGlkZGVuCnN1bi5sYXVuY2hlci5yZXNvdXJjZXMuKjogaGlkZGVuCnN1bi5sd2F3dC4qOiBoaWRkZW4Kc3VuLmx3YXd0Lm1hY29zeC4qOiBoaWRkZW4Kc3VuLm1hbmFnZW1lbnQuKjogcHJvcHJpZXRhcnkgY29tcGFjdDMKc3VuLm1hbmFnZW1lbnQuY291bnRlci4qOiBwcm9wcmlldGFyeSBjb21wYWN0MwpzdW4ubWFuYWdlbWVudC5jb3VudGVyLnBlcmYuKjogcHJvcHJpZXRhcnkgY29tcGFjdDMKc3VuLm1hbmFnZW1lbnQuamRwLio6IGhpZGRlbgpzdW4ubWFuYWdlbWVudC5qbXhyZW1vdGUuKjogcHJvcHJpZXRhcnkgY29tcGFjdDMKc3VuLm1hbmFnZW1lbnQucmVzb3VyY2VzLio6IHByb3ByaWV0YXJ5IGNvbXBhY3QzCnN1bi5taXNjLio6IHByb3ByaWV0YXJ5IGNvbXBhY3QxCnN1bi5taXNjLnJlc291cmNlcy4qOiBwcm9wcmlldGFyeSBjb21wYWN0MQpzdW4ubmV0Lio6IHByb3ByaWV0YXJ5IGNvbXBhY3QxCnN1bi5uZXQuZG5zLio6IHByb3ByaWV0YXJ5IGNvbXBhY3QzCnN1bi5uZXQuZnRwLio6IHByb3ByaWV0YXJ5CnN1bi5uZXQuZnRwLmltcGwuKjogaGlkZGVuCnN1bi5uZXQuaHR0cHNlcnZlci4qOiBoaWRkZW4Kc3VuLm5ldC5pZG4uKjogaGlkZGVuCnN1bi5uZXQuc2RwLio6IGhpZGRlbgpzdW4ubmV0LnNtdHAuKjogcHJvcHJpZXRhcnkKc3VuLm5ldC5zcGkuKjogcHJvcHJpZXRhcnkgY29tcGFjdDEKc3VuLm5ldC5zcGkubmFtZXNlcnZpY2UuKjogcHJvcHJpZXRhcnkgY29tcGFjdDEKc3VuLm5ldC51dGlsLio6IHByb3ByaWV0YXJ5IGNvbXBhY3QxCnN1bi5uZXQud3d3Lio6IHByb3ByaWV0YXJ5IGNvbXBhY3QxCnN1bi5uZXQud3d3LmNvbnRlbnQuYXVkaW8uKjogcHJvcHJpZXRhcnkKc3VuLm5ldC53d3cuY29udGVudC5pbWFnZS4qOiBwcm9wcmlldGFyeQpzdW4ubmV0Lnd3dy5jb250ZW50LnRleHQuKjogcHJvcHJpZXRhcnkKc3VuLm5ldC53d3cuaHR0cC4qOiBwcm9wcmlldGFyeSBjb21wYWN0MQpzdW4ubmV0Lnd3dy5wcm90b2NvbC5maWxlLio6IHByb3ByaWV0YXJ5IGNvbXBhY3QxCnN1bi5uZXQud3d3LnByb3RvY29sLmZ0cC4qOiBwcm9wcmlldGFyeQpzdW4ubmV0Lnd3dy5wcm90b2NvbC5odHRwLio6IHByb3ByaWV0YXJ5IGNvbXBhY3QxCnN1bi5uZXQud3d3LnByb3RvY29sLmh0dHAubG9nZ2luZy4qOiBoaWRkZW4Kc3VuLm5ldC53d3cucHJvdG9jb2wuaHR0cC5udGxtLio6IGhpZGRlbgpzdW4ubmV0Lnd3dy5wcm90b2NvbC5odHRwLnNwbmVnby4qOiBoaWRkZW4Kc3VuLm5ldC53d3cucHJvdG9jb2wuaHR0cHMuKjogcHJvcHJpZXRhcnkgY29tcGFjdDEKc3VuLm5ldC53d3cucHJvdG9jb2wuamFyLio6IHByb3ByaWV0YXJ5IGNvbXBhY3QxCnN1bi5uZXQud3d3LnByb3RvY29sLm1haWx0by4qOiBwcm9wcmlldGFyeQpzdW4ubmV0Lnd3dy5wcm90b2NvbC5uZXRkb2MuKjogcHJvcHJpZXRhcnkKc3VuLm5pby4qOiBwcm9wcmlldGFyeSBjb21wYWN0MQpzdW4ubmlvLmNoLio6IHByb3ByaWV0YXJ5IGNvbXBhY3QxCnN1bi5uaW8uY2guc2N0cC4qOiBoaWRkZW4Kc3VuLm5pby5jcy4qOiBwcm9wcmlldGFyeSBjb21wYWN0MQpzdW4ubmlvLmZzLio6IGhpZGRlbgpzdW4ucHJpbnQuKjogcHJvcHJpZXRhcnkKc3VuLnByaW50LnJlc291cmNlcy4qOiBwcm9wcmlldGFyeQpzdW4ucmVmbGVjdC4qOiBwcm9wcmlldGFyeSBjb21wYWN0MQpzdW4ucmVmbGVjdC5hbm5vdGF0aW9uLio6IHByb3ByaWV0YXJ5IGNvbXBhY3QxCnN1bi5yZWZsZWN0LmdlbmVyaWNzLmZhY3RvcnkuKjogcHJvcHJpZXRhcnkgY29tcGFjdDEKc3VuLnJlZmxlY3QuZ2VuZXJpY3MucGFyc2VyLio6IHByb3ByaWV0YXJ5IGNvbXBhY3QxCnN1bi5yZWZsZWN0LmdlbmVyaWNzLnJlZmxlY3RpdmVPYmplY3RzLio6IHByb3ByaWV0YXJ5IGNvbXBhY3QxCnN1bi5yZWZsZWN0LmdlbmVyaWNzLnJlcG9zaXRvcnkuKjogcHJvcHJpZXRhcnkgY29tcGFjdDEKc3VuLnJlZmxlY3QuZ2VuZXJpY3Muc2NvcGUuKjogcHJvcHJpZXRhcnkgY29tcGFjdDEKc3VuLnJlZmxlY3QuZ2VuZXJpY3MudHJlZS4qOiBwcm9wcmlldGFyeSBjb21wYWN0MQpzdW4ucmVmbGVjdC5nZW5lcmljcy52aXNpdG9yLio6IHByb3ByaWV0YXJ5IGNvbXBhY3QxCnN1bi5yZWZsZWN0Lm1pc2MuKjogaGlkZGVuCnN1bi5ybWkubG9nLio6IHByb3ByaWV0YXJ5IGNvbXBhY3QyCnN1bi5ybWkucmVnaXN0cnkuKjogcHJvcHJpZXRhcnkgY29tcGFjdDIKc3VuLnJtaS5ydW50aW1lLio6IHByb3ByaWV0YXJ5IGNvbXBhY3QyCnN1bi5ybWkuc2VydmVyLio6IHByb3ByaWV0YXJ5IGNvbXBhY3QyCnN1bi5ybWkudHJhbnNwb3J0Lio6IHByb3ByaWV0YXJ5IGNvbXBhY3QyCnN1bi5ybWkudHJhbnNwb3J0LnByb3h5Lio6IHByb3ByaWV0YXJ5IGNvbXBhY3QyCnN1bi5ybWkudHJhbnNwb3J0LnRjcC4qOiBwcm9wcmlldGFyeSBjb21wYWN0MgpzdW4uc2VjdXJpdHkuYWN0aW9uLio6IHByb3ByaWV0YXJ5IGNvbXBhY3QxCnN1bi5zZWN1cml0eS5qY2EuKjogcHJvcHJpZXRhcnkgY29tcGFjdDEKc3VuLnNlY3VyaXR5Lmpnc3MuKjogcHJvcHJpZXRhcnkgY29tcGFjdDMKc3VuLnNlY3VyaXR5Lmpnc3Mua3JiNS4qOiBwcm9wcmlldGFyeSBjb21wYWN0MwpzdW4uc2VjdXJpdHkuamdzcy5zcGkuKjogcHJvcHJpZXRhcnkgY29tcGFjdDMKc3VuLnNlY3VyaXR5Lmpnc3Muc3BuZWdvLio6IGhpZGRlbgpzdW4uc2VjdXJpdHkuamdzcy53cmFwcGVyLio6IGhpZGRlbgpzdW4uc2VjdXJpdHkua3JiNS4qOiBwcm9wcmlldGFyeSBjb21wYWN0MwpzdW4uc2VjdXJpdHkua3JiNS5pbnRlcm5hbC4qOiBwcm9wcmlldGFyeSBjb21wYWN0MwpzdW4uc2VjdXJpdHkua3JiNS5pbnRlcm5hbC5jY2FjaGUuKjogcHJvcHJpZXRhcnkgY29tcGFjdDMKc3VuLnNlY3VyaXR5LmtyYjUuaW50ZXJuYWwuY3J5cHRvLio6IHByb3ByaWV0YXJ5IGNvbXBhY3QzCnN1bi5zZWN1cml0eS5rcmI1LmludGVybmFsLmNyeXB0by5kay4qOiBwcm9wcmlldGFyeSBjb21wYWN0MwpzdW4uc2VjdXJpdHkua3JiNS5pbnRlcm5hbC5rdGFiLio6IHByb3ByaWV0YXJ5IGNvbXBhY3QzCnN1bi5zZWN1cml0eS5rcmI1LmludGVybmFsLnJjYWNoZS4qOiBwcm9wcmlldGFyeSBjb21wYWN0MwpzdW4uc2VjdXJpdHkua3JiNS5pbnRlcm5hbC50b29scy4qOiBwcm9wcmlldGFyeSBjb21wYWN0MwpzdW4uc2VjdXJpdHkua3JiNS5pbnRlcm5hbC51dGlsLio6IHByb3ByaWV0YXJ5IGNvbXBhY3QzCnN1bi5zZWN1cml0eS5wa2NzLio6IHByb3ByaWV0YXJ5IGNvbXBhY3QxCnN1bi5zZWN1cml0eS5wa2NzMTAuKjogaGlkZGVuCnN1bi5zZWN1cml0eS5wa2NzMTIuKjogaGlkZGVuCnN1bi5zZWN1cml0eS5wcm92aWRlci4qOiBwcm9wcmlldGFyeSBjb21wYWN0MQpzdW4uc2VjdXJpdHkucHJvdmlkZXIuY2VydHBhdGguKjogcHJvcHJpZXRhcnkgY29tcGFjdDEKc3VuLnNlY3VyaXR5LnByb3ZpZGVyLmNlcnRwYXRoLmxkYXAuKjogaGlkZGVuCnN1bi5zZWN1cml0eS5wcm92aWRlci5jZXJ0cGF0aC5zc2wuKjogaGlkZGVuCnN1bi5zZWN1cml0eS5yc2EuKjogcHJvcHJpZXRhcnkgY29tcGFjdDEKc3VuLnNlY3VyaXR5LnNtYXJ0Y2FyZGlvLio6IGhpZGRlbgpzdW4uc2VjdXJpdHkudGltZXN0YW1wLio6IHByb3ByaWV0YXJ5IGNvbXBhY3QxCnN1bi5zZWN1cml0eS50b29scy4qOiBwcm9wcmlldGFyeSBjb21wYWN0MQpzdW4uc2VjdXJpdHkudG9vbHMua2V5dG9vbC4qOiBoaWRkZW4Kc3VuLnNlY3VyaXR5LnRvb2xzLnBvbGljeXRvb2wuKjogaGlkZGVuCnN1bi5zZWN1cml0eS51dGlsLio6IHByb3ByaWV0YXJ5IGNvbXBhY3QxCnN1bi5zZWN1cml0eS52YWxpZGF0b3IuKjogcHJvcHJpZXRhcnkgY29tcGFjdDEKc3VuLnNlY3VyaXR5Lng1MDkuKjogcHJvcHJpZXRhcnkgY29tcGFjdDEKc3VuLnN3aW5nLio6IHByb3ByaWV0YXJ5CnN1bi5zd2luZy5pY29uLio6IGhpZGRlbgpzdW4uc3dpbmcucGxhZi4qOiBoaWRkZW4Kc3VuLnN3aW5nLnBsYWYuc3ludGguKjogcHJvcHJpZXRhcnkKc3VuLnN3aW5nLnBsYWYud2luZG93cy4qOiBoaWRkZW4Kc3VuLnN3aW5nLnRhYmxlLio6IGhpZGRlbgpzdW4uc3dpbmcudGV4dC4qOiBoaWRkZW4Kc3VuLnN3aW5nLnRleHQuaHRtbC4qOiBoaWRkZW4Kc3VuLnRleHQuKjogcHJvcHJpZXRhcnkgY29tcGFjdDEKc3VuLnRleHQuYmlkaS4qOiBoaWRkZW4Kc3VuLnRleHQubm9ybWFsaXplci4qOiBoaWRkZW4Kc3VuLnRleHQucmVzb3VyY2VzLio6IHByb3ByaWV0YXJ5IGNvbXBhY3QxCnN1bi50ZXh0LnJlc291cmNlcy5lbi4qOiBoaWRkZW4Kc3VuLnRvb2xzLmphci4qOiBwcm9wcmlldGFyeQpzdW4udG9vbHMuamFyLnJlc291cmNlcy4qOiBwcm9wcmlldGFyeQpzdW4udHJhY2luZy4qOiBoaWRkZW4Kc3VuLnRyYWNpbmcuZHRyYWNlLio6IGhpZGRlbgpzdW4udXRpbC4qOiBwcm9wcmlldGFyeSBjb21wYWN0MQpzdW4udXRpbC5jYWxlbmRhci4qOiBwcm9wcmlldGFyeSBjb21wYWN0MQpzdW4udXRpbC5jbGRyLio6IGhpZGRlbgpzdW4udXRpbC5sb2NhbGUuKjogcHJvcHJpZXRhcnkgY29tcGFjdDEKc3VuLnV0aWwubG9jYWxlLnByb3ZpZGVyLio6IGhpZGRlbgpzdW4udXRpbC5sb2dnaW5nLio6IGhpZGRlbgpzdW4udXRpbC5sb2dnaW5nLnJlc291cmNlcy4qOiBwcm9wcmlldGFyeSBjb21wYWN0MQpzdW4udXRpbC5yZXNvdXJjZXMuKjogaGlkZGVuCnN1bi51dGlsLnJlc291cmNlcy5lbi4qOiBoaWRkZW4Kc3VuLnV0aWwuc3BpLio6IGhpZGRlbgpQSwMECgAACAAABjupSgAAAAAAAAAAAAAAABsAAABjb20vc3VuL3Rvb2xzL2phdmFjL3BhcnNlci9QSwMECgAACAAA0n1NSsv2dHCoCwAAqAsAADMAAABjb20vc3VuL3Rvb2xzL2phdmFjL3BhcnNlci9MYXp5RG9jQ29tbWVudFRhYmxlLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDE5OTksIDIwMTIsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhYy5wYXJzZXI7CgppbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CmltcG9ydCBqYXZhLnV0aWwuTWFwOwoKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMucGFyc2VyLlRva2Vucy5Db21tZW50OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkRDVHJlZS5EQ0RvY0NvbW1lbnQ7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuRG9jQ29tbWVudFRhYmxlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkpDVHJlZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5EaWFnbm9zdGljU291cmNlOwoKCi8qKgogKgogKiAgPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24gcmlzay4KICogIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yCiAqICBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+CiAqLwpwdWJsaWMgY2xhc3MgTGF6eURvY0NvbW1lbnRUYWJsZSBpbXBsZW1lbnRzIERvY0NvbW1lbnRUYWJsZSB7CiAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBFbnRyeSB7CiAgICAgICAgZmluYWwgQ29tbWVudCBjb21tZW50OwogICAgICAgIERDRG9jQ29tbWVudCB0cmVlOwoKICAgICAgICBFbnRyeShDb21tZW50IGMpIHsKICAgICAgICAgICAgY29tbWVudCA9IGM7CiAgICAgICAgfQogICAgfQoKICAgIFBhcnNlckZhY3RvcnkgZmFjOwogICAgRGlhZ25vc3RpY1NvdXJjZSBkaWFnU291cmNlOwogICAgTWFwPEpDVHJlZSwgRW50cnk+IHRhYmxlOwoKICAgIExhenlEb2NDb21tZW50VGFibGUoUGFyc2VyRmFjdG9yeSBmYWMpIHsKICAgICAgICB0aGlzLmZhYyA9IGZhYzsKICAgICAgICBkaWFnU291cmNlID0gZmFjLmxvZy5jdXJyZW50U291cmNlKCk7CiAgICAgICAgdGFibGUgPSBuZXcgSGFzaE1hcDw+KCk7CiAgICB9CgogICAgcHVibGljIGJvb2xlYW4gaGFzQ29tbWVudChKQ1RyZWUgdHJlZSkgewogICAgICAgIHJldHVybiB0YWJsZS5jb250YWluc0tleSh0cmVlKTsKICAgIH0KCiAgICBwdWJsaWMgQ29tbWVudCBnZXRDb21tZW50KEpDVHJlZSB0cmVlKSB7CiAgICAgICAgRW50cnkgZSA9IHRhYmxlLmdldCh0cmVlKTsKICAgICAgICByZXR1cm4gKGUgPT0gbnVsbCkgPyBudWxsIDogZS5jb21tZW50OwogICAgfQoKICAgIHB1YmxpYyBTdHJpbmcgZ2V0Q29tbWVudFRleHQoSkNUcmVlIHRyZWUpIHsKICAgICAgICBDb21tZW50IGMgPSBnZXRDb21tZW50KHRyZWUpOwogICAgICAgIHJldHVybiAoYyA9PSBudWxsKSA/IG51bGwgOiBjLmdldFRleHQoKTsKICAgIH0KCiAgICBwdWJsaWMgRENEb2NDb21tZW50IGdldENvbW1lbnRUcmVlKEpDVHJlZSB0cmVlKSB7CiAgICAgICAgRW50cnkgZSA9IHRhYmxlLmdldCh0cmVlKTsKICAgICAgICBpZiAoZSA9PSBudWxsKQogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICBpZiAoZS50cmVlID09IG51bGwpCiAgICAgICAgICAgIGUudHJlZSA9IG5ldyBEb2NDb21tZW50UGFyc2VyKGZhYywgZGlhZ1NvdXJjZSwgZS5jb21tZW50KS5wYXJzZSgpOwogICAgICAgIHJldHVybiBlLnRyZWU7CiAgICB9CgogICAgcHVibGljIHZvaWQgcHV0Q29tbWVudChKQ1RyZWUgdHJlZSwgQ29tbWVudCBjKSB7CiAgICAgICAgdGFibGUucHV0KHRyZWUsIG5ldyBFbnRyeShjKSk7CiAgICB9Cgp9ClBLAwQKAAAIAADSfU1Khpraebg3AAC4NwAAJgAAAGNvbS9zdW4vdG9vbHMvamF2YWMvcGFyc2VyL1Rva2Vucy5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAxOTk5LCAyMDEzLCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuamF2YWMucGFyc2VyOwoKaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CgppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5hcGkuRm9ybWF0dGFibGU7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmFwaS5NZXNzYWdlczsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMucGFyc2VyLlRva2Vucy5Ub2tlbi5UYWc7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuTGlzdDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5OYW1lOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkNvbnRleHQ7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuRmlsdGVyOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkxpc3RCdWZmZXI7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuTmFtZXM7CgovKiogQSBjbGFzcyB0aGF0IGRlZmluZXMgY29kZXMvdXRpbGl0aWVzIGZvciBKYXZhIHNvdXJjZSB0b2tlbnMKICogIHJldHVybmVkIGZyb20gbGV4aWNhbCBhbmFseXNpcy4KICoKICogIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqICBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqICBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogKiAgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPgogKi8KcHVibGljIGNsYXNzIFRva2VucyB7CgogICAgcHJpdmF0ZSBmaW5hbCBOYW1lcyBuYW1lczsKCiAgICAvKioKICAgICAqIEtleXdvcmQgYXJyYXkuIE1hcHMgbmFtZSBpbmRpY2VzIHRvIFRva2VuLgogICAgICovCiAgICBwcml2YXRlIGZpbmFsIFRva2VuS2luZFtdIGtleTsKCiAgICAvKiogIFRoZSBudW1iZXIgb2YgdGhlIGxhc3QgZW50ZXJlZCBrZXl3b3JkLgogICAgICovCiAgICBwcml2YXRlIGludCBtYXhLZXkgPSAwOwoKICAgIC8qKiBUaGUgbmFtZXMgb2YgYWxsIHRva2Vucy4KICAgICAqLwogICAgcHJpdmF0ZSBOYW1lW10gdG9rZW5OYW1lID0gbmV3IE5hbWVbVG9rZW5LaW5kLnZhbHVlcygpLmxlbmd0aF07CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBDb250ZXh0LktleTxUb2tlbnM+IHRva2Vuc0tleSA9IG5ldyBDb250ZXh0LktleTw+KCk7CgogICAgcHVibGljIHN0YXRpYyBUb2tlbnMgaW5zdGFuY2UoQ29udGV4dCBjb250ZXh0KSB7CiAgICAgICAgVG9rZW5zIGluc3RhbmNlID0gY29udGV4dC5nZXQodG9rZW5zS2V5KTsKICAgICAgICBpZiAoaW5zdGFuY2UgPT0gbnVsbCkKICAgICAgICAgICAgaW5zdGFuY2UgPSBuZXcgVG9rZW5zKGNvbnRleHQpOwogICAgICAgIHJldHVybiBpbnN0YW5jZTsKICAgIH0KCiAgICBwcm90ZWN0ZWQgVG9rZW5zKENvbnRleHQgY29udGV4dCkgewogICAgICAgIGNvbnRleHQucHV0KHRva2Vuc0tleSwgdGhpcyk7CiAgICAgICAgbmFtZXMgPSBOYW1lcy5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBmb3IgKFRva2VuS2luZCB0IDogVG9rZW5LaW5kLnZhbHVlcygpKSB7CiAgICAgICAgICAgIGlmICh0Lm5hbWUgIT0gbnVsbCkKICAgICAgICAgICAgICAgIGVudGVyS2V5d29yZCh0Lm5hbWUsIHQpOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB0b2tlbk5hbWVbdC5vcmRpbmFsKCldID0gbnVsbDsKICAgICAgICB9CgogICAgICAgIGtleSA9IG5ldyBUb2tlbktpbmRbbWF4S2V5KzFdOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDw9IG1heEtleTsgaSsrKSBrZXlbaV0gPSBUb2tlbktpbmQuSURFTlRJRklFUjsKICAgICAgICBmb3IgKFRva2VuS2luZCB0IDogVG9rZW5LaW5kLnZhbHVlcygpKSB7CiAgICAgICAgICAgIGlmICh0Lm5hbWUgIT0gbnVsbCkKICAgICAgICAgICAga2V5W3Rva2VuTmFtZVt0Lm9yZGluYWwoKV0uZ2V0SW5kZXgoKV0gPSB0OwogICAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIHZvaWQgZW50ZXJLZXl3b3JkKFN0cmluZyBzLCBUb2tlbktpbmQgdG9rZW4pIHsKICAgICAgICBOYW1lIG4gPSBuYW1lcy5mcm9tU3RyaW5nKHMpOwogICAgICAgIHRva2VuTmFtZVt0b2tlbi5vcmRpbmFsKCldID0gbjsKICAgICAgICBpZiAobi5nZXRJbmRleCgpID4gbWF4S2V5KSBtYXhLZXkgPSBuLmdldEluZGV4KCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDcmVhdGUgYSBuZXcgdG9rZW4gZ2l2ZW4gYSBuYW1lOyBpZiB0aGUgbmFtZSBjb3JyZXNwb25kcyB0byBhIHRva2VuIG5hbWUsCiAgICAgKiBhIG5ldyB0b2tlbiBvZiB0aGUgY29ycmVzcG9uZGluZyBraW5kIGlzIHJldHVybmVkOyBvdGhlcndpc2UsIGFuCiAgICAgKiBpZGVudGlmaWVyIHRva2VuIGlzIHJldHVybmVkLgogICAgICovCiAgICBUb2tlbktpbmQgbG9va3VwS2luZChOYW1lIG5hbWUpIHsKICAgICAgICByZXR1cm4gKG5hbWUuZ2V0SW5kZXgoKSA+IG1heEtleSkgPyBUb2tlbktpbmQuSURFTlRJRklFUiA6IGtleVtuYW1lLmdldEluZGV4KCldOwogICAgfQoKICAgIFRva2VuS2luZCBsb29rdXBLaW5kKFN0cmluZyBuYW1lKSB7CiAgICAgICAgcmV0dXJuIGxvb2t1cEtpbmQobmFtZXMuZnJvbVN0cmluZyhuYW1lKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBUaGlzIGVudW0gZGVmaW5lcyBhbGwgdG9rZW5zIHVzZWQgYnkgdGhlIGphdmFjIHNjYW5uZXIuIEEgdG9rZW4gaXMKICAgICAqIG9wdGlvbmFsbHkgYXNzb2NpYXRlZCB3aXRoIGEgbmFtZS4KICAgICAqLwogICAgcHVibGljIGVudW0gVG9rZW5LaW5kIGltcGxlbWVudHMgRm9ybWF0dGFibGUsIEZpbHRlcjxUb2tlbktpbmQ+IHsKICAgICAgICBFT0YoKSwKICAgICAgICBFUlJPUigpLAogICAgICAgIElERU5USUZJRVIoVGFnLk5BTUVEKSwKICAgICAgICBBQlNUUkFDVCgiYWJzdHJhY3QiKSwKICAgICAgICBBU1NFUlQoImFzc2VydCIsIFRhZy5OQU1FRCksCiAgICAgICAgQk9PTEVBTigiYm9vbGVhbiIsIFRhZy5OQU1FRCksCiAgICAgICAgQlJFQUsoImJyZWFrIiksCiAgICAgICAgQllURSgiYnl0ZSIsIFRhZy5OQU1FRCksCiAgICAgICAgQ0FTRSgiY2FzZSIpLAogICAgICAgIENBVENIKCJjYXRjaCIpLAogICAgICAgIENIQVIoImNoYXIiLCBUYWcuTkFNRUQpLAogICAgICAgIENMQVNTKCJjbGFzcyIpLAogICAgICAgIENPTlNUKCJjb25zdCIpLAogICAgICAgIENPTlRJTlVFKCJjb250aW51ZSIpLAogICAgICAgIERFRkFVTFQoImRlZmF1bHQiKSwKICAgICAgICBETygiZG8iKSwKICAgICAgICBET1VCTEUoImRvdWJsZSIsIFRhZy5OQU1FRCksCiAgICAgICAgRUxTRSgiZWxzZSIpLAogICAgICAgIEVOVU0oImVudW0iLCBUYWcuTkFNRUQpLAogICAgICAgIEVYVEVORFMoImV4dGVuZHMiKSwKICAgICAgICBGSU5BTCgiZmluYWwiKSwKICAgICAgICBGSU5BTExZKCJmaW5hbGx5IiksCiAgICAgICAgRkxPQVQoImZsb2F0IiwgVGFnLk5BTUVEKSwKICAgICAgICBGT1IoImZvciIpLAogICAgICAgIEdPVE8oImdvdG8iKSwKICAgICAgICBJRigiaWYiKSwKICAgICAgICBJTVBMRU1FTlRTKCJpbXBsZW1lbnRzIiksCiAgICAgICAgSU1QT1JUKCJpbXBvcnQiKSwKICAgICAgICBJTlNUQU5DRU9GKCJpbnN0YW5jZW9mIiksCiAgICAgICAgSU5UKCJpbnQiLCBUYWcuTkFNRUQpLAogICAgICAgIElOVEVSRkFDRSgiaW50ZXJmYWNlIiksCiAgICAgICAgTE9ORygibG9uZyIsIFRhZy5OQU1FRCksCiAgICAgICAgTkFUSVZFKCJuYXRpdmUiKSwKICAgICAgICBORVcoIm5ldyIpLAogICAgICAgIFBBQ0tBR0UoInBhY2thZ2UiKSwKICAgICAgICBQUklWQVRFKCJwcml2YXRlIiksCiAgICAgICAgUFJPVEVDVEVEKCJwcm90ZWN0ZWQiKSwKICAgICAgICBQVUJMSUMoInB1YmxpYyIpLAogICAgICAgIFJFVFVSTigicmV0dXJuIiksCiAgICAgICAgU0hPUlQoInNob3J0IiwgVGFnLk5BTUVEKSwKICAgICAgICBTVEFUSUMoInN0YXRpYyIpLAogICAgICAgIFNUUklDVEZQKCJzdHJpY3RmcCIpLAogICAgICAgIFNVUEVSKCJzdXBlciIsIFRhZy5OQU1FRCksCiAgICAgICAgU1dJVENIKCJzd2l0Y2giKSwKICAgICAgICBTWU5DSFJPTklaRUQoInN5bmNocm9uaXplZCIpLAogICAgICAgIFRISVMoInRoaXMiLCBUYWcuTkFNRUQpLAogICAgICAgIFRIUk9XKCJ0aHJvdyIpLAogICAgICAgIFRIUk9XUygidGhyb3dzIiksCiAgICAgICAgVFJBTlNJRU5UKCJ0cmFuc2llbnQiKSwKICAgICAgICBUUlkoInRyeSIpLAogICAgICAgIFZPSUQoInZvaWQiLCBUYWcuTkFNRUQpLAogICAgICAgIFZPTEFUSUxFKCJ2b2xhdGlsZSIpLAogICAgICAgIFdISUxFKCJ3aGlsZSIpLAogICAgICAgIElOVExJVEVSQUwoVGFnLk5VTUVSSUMpLAogICAgICAgIExPTkdMSVRFUkFMKFRhZy5OVU1FUklDKSwKICAgICAgICBGTE9BVExJVEVSQUwoVGFnLk5VTUVSSUMpLAogICAgICAgIERPVUJMRUxJVEVSQUwoVGFnLk5VTUVSSUMpLAogICAgICAgIENIQVJMSVRFUkFMKFRhZy5OVU1FUklDKSwKICAgICAgICBTVFJJTkdMSVRFUkFMKFRhZy5TVFJJTkcpLAogICAgICAgIFRSVUUoInRydWUiLCBUYWcuTkFNRUQpLAogICAgICAgIEZBTFNFKCJmYWxzZSIsIFRhZy5OQU1FRCksCiAgICAgICAgTlVMTCgibnVsbCIsIFRhZy5OQU1FRCksCiAgICAgICAgVU5ERVJTQ09SRSgiXyIsIFRhZy5OQU1FRCksCiAgICAgICAgQVJST1coIi0+IiksCiAgICAgICAgQ09MQ09MKCI6OiIpLAogICAgICAgIExQQVJFTigiKCIpLAogICAgICAgIFJQQVJFTigiKSIpLAogICAgICAgIExCUkFDRSgieyIpLAogICAgICAgIFJCUkFDRSgifSIpLAogICAgICAgIExCUkFDS0VUKCJbIiksCiAgICAgICAgUkJSQUNLRVQoIl0iKSwKICAgICAgICBTRU1JKCI7IiksCiAgICAgICAgQ09NTUEoIiwiKSwKICAgICAgICBET1QoIi4iKSwKICAgICAgICBFTExJUFNJUygiLi4uIiksCiAgICAgICAgRVEoIj0iKSwKICAgICAgICBHVCgiPiIpLAogICAgICAgIExUKCI8IiksCiAgICAgICAgQkFORygiISIpLAogICAgICAgIFRJTERFKCJ+IiksCiAgICAgICAgUVVFUygiPyIpLAogICAgICAgIENPTE9OKCI6IiksCiAgICAgICAgRVFFUSgiPT0iKSwKICAgICAgICBMVEVRKCI8PSIpLAogICAgICAgIEdURVEoIj49IiksCiAgICAgICAgQkFOR0VRKCIhPSIpLAogICAgICAgIEFNUEFNUCgiJiYiKSwKICAgICAgICBCQVJCQVIoInx8IiksCiAgICAgICAgUExVU1BMVVMoIisrIiksCiAgICAgICAgU1VCU1VCKCItLSIpLAogICAgICAgIFBMVVMoIisiKSwKICAgICAgICBTVUIoIi0iKSwKICAgICAgICBTVEFSKCIqIiksCiAgICAgICAgU0xBU0goIi8iKSwKICAgICAgICBBTVAoIiYiKSwKICAgICAgICBCQVIoInwiKSwKICAgICAgICBDQVJFVCgiXiIpLAogICAgICAgIFBFUkNFTlQoIiUiKSwKICAgICAgICBMVExUKCI8PCIpLAogICAgICAgIEdUR1QoIj4+IiksCiAgICAgICAgR1RHVEdUKCI+Pj4iKSwKICAgICAgICBQTFVTRVEoIis9IiksCiAgICAgICAgU1VCRVEoIi09IiksCiAgICAgICAgU1RBUkVRKCIqPSIpLAogICAgICAgIFNMQVNIRVEoIi89IiksCiAgICAgICAgQU1QRVEoIiY9IiksCiAgICAgICAgQkFSRVEoInw9IiksCiAgICAgICAgQ0FSRVRFUSgiXj0iKSwKICAgICAgICBQRVJDRU5URVEoIiU9IiksCiAgICAgICAgTFRMVEVRKCI8PD0iKSwKICAgICAgICBHVEdURVEoIj4+PSIpLAogICAgICAgIEdUR1RHVEVRKCI+Pj49IiksCiAgICAgICAgTU9OS0VZU19BVCgiQCIpLAogICAgICAgIENVU1RPTTsKCiAgICAgICAgcHVibGljIGZpbmFsIFN0cmluZyBuYW1lOwogICAgICAgIHB1YmxpYyBmaW5hbCBUYWcgdGFnOwoKICAgICAgICBUb2tlbktpbmQoKSB7CiAgICAgICAgICAgIHRoaXMobnVsbCwgVGFnLkRFRkFVTFQpOwogICAgICAgIH0KCiAgICAgICAgVG9rZW5LaW5kKFN0cmluZyBuYW1lKSB7CiAgICAgICAgICAgIHRoaXMobmFtZSwgVGFnLkRFRkFVTFQpOwogICAgICAgIH0KCiAgICAgICAgVG9rZW5LaW5kKFRhZyB0YWcpIHsKICAgICAgICAgICAgdGhpcyhudWxsLCB0YWcpOwogICAgICAgIH0KCiAgICAgICAgVG9rZW5LaW5kKFN0cmluZyBuYW1lLCBUYWcgdGFnKSB7CiAgICAgICAgICAgIHRoaXMubmFtZSA9IG5hbWU7CiAgICAgICAgICAgIHRoaXMudGFnID0gdGFnOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKICAgICAgICAgICAgc3dpdGNoICh0aGlzKSB7CiAgICAgICAgICAgIGNhc2UgSURFTlRJRklFUjoKICAgICAgICAgICAgICAgIHJldHVybiAidG9rZW4uaWRlbnRpZmllciI7CiAgICAgICAgICAgIGNhc2UgQ0hBUkxJVEVSQUw6CiAgICAgICAgICAgICAgICByZXR1cm4gInRva2VuLmNoYXJhY3RlciI7CiAgICAgICAgICAgIGNhc2UgU1RSSU5HTElURVJBTDoKICAgICAgICAgICAgICAgIHJldHVybiAidG9rZW4uc3RyaW5nIjsKICAgICAgICAgICAgY2FzZSBJTlRMSVRFUkFMOgogICAgICAgICAgICAgICAgcmV0dXJuICJ0b2tlbi5pbnRlZ2VyIjsKICAgICAgICAgICAgY2FzZSBMT05HTElURVJBTDoKICAgICAgICAgICAgICAgIHJldHVybiAidG9rZW4ubG9uZy1pbnRlZ2VyIjsKICAgICAgICAgICAgY2FzZSBGTE9BVExJVEVSQUw6CiAgICAgICAgICAgICAgICByZXR1cm4gInRva2VuLmZsb2F0IjsKICAgICAgICAgICAgY2FzZSBET1VCTEVMSVRFUkFMOgogICAgICAgICAgICAgICAgcmV0dXJuICJ0b2tlbi5kb3VibGUiOwogICAgICAgICAgICBjYXNlIEVSUk9SOgogICAgICAgICAgICAgICAgcmV0dXJuICJ0b2tlbi5iYWQtc3ltYm9sIjsKICAgICAgICAgICAgY2FzZSBFT0Y6CiAgICAgICAgICAgICAgICByZXR1cm4gInRva2VuLmVuZC1vZi1pbnB1dCI7CiAgICAgICAgICAgIGNhc2UgRE9UOiBjYXNlIENPTU1BOiBjYXNlIFNFTUk6IGNhc2UgTFBBUkVOOiBjYXNlIFJQQVJFTjoKICAgICAgICAgICAgY2FzZSBMQlJBQ0tFVDogY2FzZSBSQlJBQ0tFVDogY2FzZSBMQlJBQ0U6IGNhc2UgUkJSQUNFOgogICAgICAgICAgICAgICAgcmV0dXJuICInIiArIG5hbWUgKyAiJyI7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICByZXR1cm4gbmFtZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHVibGljIFN0cmluZyBnZXRLaW5kKCkgewogICAgICAgICAgICByZXR1cm4gIlRva2VuIjsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoTG9jYWxlIGxvY2FsZSwgTWVzc2FnZXMgbWVzc2FnZXMpIHsKICAgICAgICAgICAgcmV0dXJuIG5hbWUgIT0gbnVsbCA/IHRvU3RyaW5nKCkgOiBtZXNzYWdlcy5nZXRMb2NhbGl6ZWRTdHJpbmcobG9jYWxlLCAiY29tcGlsZXIubWlzYy4iICsgdG9TdHJpbmcoKSk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgYm9vbGVhbiBhY2NlcHRzKFRva2VuS2luZCB0aGF0KSB7CiAgICAgICAgICAgIHJldHVybiB0aGlzID09IHRoYXQ7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBpbnRlcmZhY2UgQ29tbWVudCB7CgogICAgICAgIGVudW0gQ29tbWVudFN0eWxlIHsKICAgICAgICAgICAgTElORSwKICAgICAgICAgICAgQkxPQ0ssCiAgICAgICAgICAgIEpBVkFET0MsCiAgICAgICAgfQoKICAgICAgICBTdHJpbmcgZ2V0VGV4dCgpOwogICAgICAgIGludCBnZXRTb3VyY2VQb3MoaW50IGluZGV4KTsKICAgICAgICBDb21tZW50U3R5bGUgZ2V0U3R5bGUoKTsKICAgICAgICBib29sZWFuIGlzRGVwcmVjYXRlZCgpOwogICAgfQoKICAgIC8qKgogICAgICogVGhpcyBpcyB0aGUgY2xhc3MgcmVwcmVzZW50aW5nIGEgamF2YWMgdG9rZW4uIEVhY2ggdG9rZW4gaGFzIHNldmVyYWwgZmllbGRzCiAgICAgKiB0aGF0IGFyZSBzZXQgYnkgdGhlIGphdmFjIGxleGVyIChpLmUuIHN0YXJ0L2VuZCBwb3NpdGlvbiwgc3RyaW5nIHZhbHVlLCBldGMpLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIFRva2VuIHsKCiAgICAgICAgLyoqIHRhZ3MgY29uc3RhbnRzICoqLwogICAgICAgIGVudW0gVGFnIHsKICAgICAgICAgICAgREVGQVVMVCwKICAgICAgICAgICAgTkFNRUQsCiAgICAgICAgICAgIFNUUklORywKICAgICAgICAgICAgTlVNRVJJQwogICAgICAgIH0KCiAgICAgICAgLyoqIFRoZSB0b2tlbiBraW5kICovCiAgICAgICAgcHVibGljIGZpbmFsIFRva2VuS2luZCBraW5kOwoKICAgICAgICAvKiogVGhlIHN0YXJ0IHBvc2l0aW9uIG9mIHRoaXMgdG9rZW4gKi8KICAgICAgICBwdWJsaWMgZmluYWwgaW50IHBvczsKCiAgICAgICAgLyoqIFRoZSBlbmQgcG9zaXRpb24gb2YgdGhpcyB0b2tlbiAqLwogICAgICAgIHB1YmxpYyBmaW5hbCBpbnQgZW5kUG9zOwoKICAgICAgICAvKiogQ29tbWVudCByZWFkZXIgYXNzb2NpYXRlZCB3aXRoIHRoaXMgdG9rZW4gKi8KICAgICAgICBwdWJsaWMgZmluYWwgTGlzdDxDb21tZW50PiBjb21tZW50czsKCiAgICAgICAgVG9rZW4oVG9rZW5LaW5kIGtpbmQsIGludCBwb3MsIGludCBlbmRQb3MsIExpc3Q8Q29tbWVudD4gY29tbWVudHMpIHsKICAgICAgICAgICAgdGhpcy5raW5kID0ga2luZDsKICAgICAgICAgICAgdGhpcy5wb3MgPSBwb3M7CiAgICAgICAgICAgIHRoaXMuZW5kUG9zID0gZW5kUG9zOwogICAgICAgICAgICB0aGlzLmNvbW1lbnRzID0gY29tbWVudHM7CiAgICAgICAgICAgIGNoZWNrS2luZCgpOwogICAgICAgIH0KCiAgICAgICAgVG9rZW5bXSBzcGxpdChUb2tlbnMgdG9rZW5zKSB7CiAgICAgICAgICAgIGlmIChraW5kLm5hbWUubGVuZ3RoKCkgPCAyIHx8IGtpbmQudGFnICE9IFRhZy5ERUZBVUxUKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoIkNhbnQgc3BsaXQiICsga2luZCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIFRva2VuS2luZCB0MSA9IHRva2Vucy5sb29rdXBLaW5kKGtpbmQubmFtZS5zdWJzdHJpbmcoMCwgMSkpOwogICAgICAgICAgICBUb2tlbktpbmQgdDIgPSB0b2tlbnMubG9va3VwS2luZChraW5kLm5hbWUuc3Vic3RyaW5nKDEpKTsKCiAgICAgICAgICAgIGlmICh0MSA9PSBudWxsIHx8IHQyID09IG51bGwpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigiQ2FudCBzcGxpdCAtIGJhZCBzdWJ0b2tlbnMiKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gbmV3IFRva2VuW10gewogICAgICAgICAgICAgICAgbmV3IFRva2VuKHQxLCBwb3MsIHBvcyArIHQxLm5hbWUubGVuZ3RoKCksIGNvbW1lbnRzKSwKICAgICAgICAgICAgICAgIG5ldyBUb2tlbih0MiwgcG9zICsgdDEubmFtZS5sZW5ndGgoKSwgZW5kUG9zLCBudWxsKQogICAgICAgICAgICB9OwogICAgICAgIH0KCiAgICAgICAgcHJvdGVjdGVkIHZvaWQgY2hlY2tLaW5kKCkgewogICAgICAgICAgICBpZiAoa2luZC50YWcgIT0gVGFnLkRFRkFVTFQpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigiQmFkIHRva2VuIGtpbmQgLSBleHBlY3RlZCAiICsgVGFnLlNUUklORyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHB1YmxpYyBOYW1lIG5hbWUoKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIFN0cmluZyBzdHJpbmdWYWwoKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIGludCByYWRpeCgpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBQcmVzZXJ2ZSBjbGFzc2ljIHNlbWFudGljcyAtIGlmIG11bHRpcGxlIGphdmFkb2NzIGFyZSBmb3VuZCBvbiB0aGUgdG9rZW4KICAgICAgICAgKiB0aGUgbGFzdCBvbmUgaXMgcmV0dXJuZWQKICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQ29tbWVudCBjb21tZW50KENvbW1lbnQuQ29tbWVudFN0eWxlIHN0eWxlKSB7CiAgICAgICAgICAgIExpc3Q8Q29tbWVudD4gY29tbWVudHMgPSBnZXRDb21tZW50cyhDb21tZW50LkNvbW1lbnRTdHlsZS5KQVZBRE9DKTsKICAgICAgICAgICAgcmV0dXJuIGNvbW1lbnRzLmlzRW1wdHkoKSA/CiAgICAgICAgICAgICAgICAgICAgbnVsbCA6CiAgICAgICAgICAgICAgICAgICAgY29tbWVudHMuaGVhZDsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIFByZXNlcnZlIGNsYXNzaWMgc2VtYW50aWNzIC0gZGVwcmVjYXRlZCBzaG91bGQgYmUgc2V0IGlmIGF0IGxlYXN0IG9uZQogICAgICAgICAqIGphdmFkb2MgY29tbWVudCBhdHRhY2hlZCB0byB0aGlzIHRva2VuIGNvbnRhaW5zIHRoZSAnQGRlcHJlY2F0ZWQnIHN0cmluZwogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBib29sZWFuIGRlcHJlY2F0ZWRGbGFnKCkgewogICAgICAgICAgICBmb3IgKENvbW1lbnQgYyA6IGdldENvbW1lbnRzKENvbW1lbnQuQ29tbWVudFN0eWxlLkpBVkFET0MpKSB7CiAgICAgICAgICAgICAgICBpZiAoYy5pc0RlcHJlY2F0ZWQoKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgTGlzdDxDb21tZW50PiBnZXRDb21tZW50cyhDb21tZW50LkNvbW1lbnRTdHlsZSBzdHlsZSkgewogICAgICAgICAgICBpZiAoY29tbWVudHMgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgcmV0dXJuIExpc3QubmlsKCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBMaXN0QnVmZmVyPENvbW1lbnQ+IGJ1ZiA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICAgICAgICAgIGZvciAoQ29tbWVudCBjIDogY29tbWVudHMpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoYy5nZXRTdHlsZSgpID09IHN0eWxlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGJ1Zi5hZGQoYyk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIGJ1Zi50b0xpc3QoKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBmaW5hbCBzdGF0aWMgY2xhc3MgTmFtZWRUb2tlbiBleHRlbmRzIFRva2VuIHsKICAgICAgICAvKiogVGhlIG5hbWUgb2YgdGhpcyB0b2tlbiAqLwogICAgICAgIHB1YmxpYyBmaW5hbCBOYW1lIG5hbWU7CgogICAgICAgIHB1YmxpYyBOYW1lZFRva2VuKFRva2VuS2luZCBraW5kLCBpbnQgcG9zLCBpbnQgZW5kUG9zLCBOYW1lIG5hbWUsIExpc3Q8Q29tbWVudD4gY29tbWVudHMpIHsKICAgICAgICAgICAgc3VwZXIoa2luZCwgcG9zLCBlbmRQb3MsIGNvbW1lbnRzKTsKICAgICAgICAgICAgdGhpcy5uYW1lID0gbmFtZTsKICAgICAgICB9CgogICAgICAgIHByb3RlY3RlZCB2b2lkIGNoZWNrS2luZCgpIHsKICAgICAgICAgICAgaWYgKGtpbmQudGFnICE9IFRhZy5OQU1FRCkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCJCYWQgdG9rZW4ga2luZCAtIGV4cGVjdGVkICIgKyBUYWcuTkFNRUQpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgTmFtZSBuYW1lKCkgewogICAgICAgICAgICByZXR1cm4gbmFtZTsKICAgICAgICB9CiAgICB9CgogICAgc3RhdGljIGNsYXNzIFN0cmluZ1Rva2VuIGV4dGVuZHMgVG9rZW4gewogICAgICAgIC8qKiBUaGUgc3RyaW5nIHZhbHVlIG9mIHRoaXMgdG9rZW4gKi8KICAgICAgICBwdWJsaWMgZmluYWwgU3RyaW5nIHN0cmluZ1ZhbDsKCiAgICAgICAgcHVibGljIFN0cmluZ1Rva2VuKFRva2VuS2luZCBraW5kLCBpbnQgcG9zLCBpbnQgZW5kUG9zLCBTdHJpbmcgc3RyaW5nVmFsLCBMaXN0PENvbW1lbnQ+IGNvbW1lbnRzKSB7CiAgICAgICAgICAgIHN1cGVyKGtpbmQsIHBvcywgZW5kUG9zLCBjb21tZW50cyk7CiAgICAgICAgICAgIHRoaXMuc3RyaW5nVmFsID0gc3RyaW5nVmFsOwogICAgICAgIH0KCiAgICAgICAgcHJvdGVjdGVkIHZvaWQgY2hlY2tLaW5kKCkgewogICAgICAgICAgICBpZiAoa2luZC50YWcgIT0gVGFnLlNUUklORykgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCJCYWQgdG9rZW4ga2luZCAtIGV4cGVjdGVkICIgKyBUYWcuU1RSSU5HKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFN0cmluZyBzdHJpbmdWYWwoKSB7CiAgICAgICAgICAgIHJldHVybiBzdHJpbmdWYWw7CiAgICAgICAgfQogICAgfQoKICAgIGZpbmFsIHN0YXRpYyBjbGFzcyBOdW1lcmljVG9rZW4gZXh0ZW5kcyBTdHJpbmdUb2tlbiB7CiAgICAgICAgLyoqIFRoZSAncmFkaXgnIHZhbHVlIG9mIHRoaXMgdG9rZW4gKi8KICAgICAgICBwdWJsaWMgZmluYWwgaW50IHJhZGl4OwoKICAgICAgICBwdWJsaWMgTnVtZXJpY1Rva2VuKFRva2VuS2luZCBraW5kLCBpbnQgcG9zLCBpbnQgZW5kUG9zLCBTdHJpbmcgc3RyaW5nVmFsLCBpbnQgcmFkaXgsIExpc3Q8Q29tbWVudD4gY29tbWVudHMpIHsKICAgICAgICAgICAgc3VwZXIoa2luZCwgcG9zLCBlbmRQb3MsIHN0cmluZ1ZhbCwgY29tbWVudHMpOwogICAgICAgICAgICB0aGlzLnJhZGl4ID0gcmFkaXg7CiAgICAgICAgfQoKICAgICAgICBwcm90ZWN0ZWQgdm9pZCBjaGVja0tpbmQoKSB7CiAgICAgICAgICAgIGlmIChraW5kLnRhZyAhPSBUYWcuTlVNRVJJQykgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCJCYWQgdG9rZW4ga2luZCAtIGV4cGVjdGVkICIgKyBUYWcuTlVNRVJJQyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBpbnQgcmFkaXgoKSB7CiAgICAgICAgICAgIHJldHVybiByYWRpeDsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBUb2tlbiBEVU1NWSA9CiAgICAgICAgICAgICAgICBuZXcgVG9rZW4oVG9rZW5LaW5kLkVSUk9SLCAwLCAwLCBudWxsKTsKfQpQSwMECgAACAAABjupSgaUO4StCAAArQgAACYAAABjb20vc3VuL3Rvb2xzL2phdmFjL3BhcnNlci9QYXJzZXIuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMTk5OSwgMjAwOCwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLmphdmFjLnBhcnNlcjsKCmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuSkNUcmVlLkpDQ29tcGlsYXRpb25Vbml0OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkpDVHJlZS5KQ0V4cHJlc3Npb247CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuSkNUcmVlLkpDU3RhdGVtZW50OwoKLyoqCiAqIFJlYWRzIHN5bnRhY3RpYyB1bml0cyBmcm9tIHNvdXJjZSBjb2RlLgogKiBQYXJzZXJzIGFyZSBub3JtYWxseSBjcmVhdGVkIGZyb20gYSBQYXJzZXJGYWN0b3J5LgogKgogKiA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yCiAqIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj4KICovCnB1YmxpYyBpbnRlcmZhY2UgUGFyc2VyIHsKICAgIC8qKgogICAgICogUGFyc2UgYSBjb21waWxhdGlvbiB1bml0LgogICAgICogQHJldHVybiBhIGNvbXBpbGF0aW9uIHVuaXQKICAgICAqLwogICAgSkNDb21waWxhdGlvblVuaXQgcGFyc2VDb21waWxhdGlvblVuaXQoKTsKCiAgICAvKioKICAgICAqIFBhcnNlIGFuIGV4cHJlc3Npb24uCiAgICAgKiBAcmV0dXJuIGFuIGV4cHJlc3Npb24KICAgICAqLwogICAgSkNFeHByZXNzaW9uIHBhcnNlRXhwcmVzc2lvbigpOwoKICAgIC8qKgogICAgICogUGFyc2UgYSBzdGF0ZW1lbnQuCiAgICAgKiBAcmV0dXJuIGFuIGV4cHJlc3Npb24KICAgICAqLwogICAgSkNTdGF0ZW1lbnQgcGFyc2VTdGF0ZW1lbnQoKTsKCiAgICAvKioKICAgICAqIFBhcnNlIGEgdHlwZS4KICAgICAqIEByZXR1cm4gYW4gZXhwcmVzc2lvbiBmb3IgYSB0eXBlCiAgICAgKi8KICAgIEpDRXhwcmVzc2lvbiBwYXJzZVR5cGUoKTsKfQpQSwMECgAACAAABjupSk9v+V6EqwAAhKsAADAAAABjb20vc3VuL3Rvb2xzL2phdmFjL3BhcnNlci9Eb2NDb21tZW50UGFyc2VyLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTIsIDIwMTYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhYy5wYXJzZXI7CgppbXBvcnQgamF2YS50ZXh0LkJyZWFrSXRlcmF0b3I7CmltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKaW1wb3J0IGphdmEudXRpbC5NYXA7CgppbXBvcnQgY29tLnN1bi5zb3VyY2UuZG9jdHJlZS5BdHRyaWJ1dGVUcmVlLlZhbHVlS2luZDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMucGFyc2VyLkRvY0NvbW1lbnRQYXJzZXIuVGFnUGFyc2VyLktpbmQ7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnBhcnNlci5Ub2tlbnMuQ29tbWVudDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMucGFyc2VyLlRva2Vucy5Ub2tlbktpbmQ7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuRENUcmVlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkRDVHJlZS5EQ0F0dHJpYnV0ZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5EQ1RyZWUuRENEb2NDb21tZW50OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkRDVHJlZS5EQ0VuZFBvc1RyZWU7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuRENUcmVlLkRDRXJyb25lb3VzOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkRDVHJlZS5EQ0lkZW50aWZpZXI7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuRENUcmVlLkRDUmVmZXJlbmNlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkRDVHJlZS5EQ1RleHQ7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuRG9jVHJlZU1ha2VyOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkpDVHJlZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5EaWFnbm9zdGljU291cmNlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkxpc3Q7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuTGlzdEJ1ZmZlcjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5Mb2c7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuTmFtZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5OYW1lczsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5Qb3NpdGlvbjsKCmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkxheW91dENoYXJhY3RlcnMuKjsKCi8qKgogKgogKiAgPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24gcmlzay4KICogIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yCiAqICBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+CiAqLwpwdWJsaWMgY2xhc3MgRG9jQ29tbWVudFBhcnNlciB7CiAgICBzdGF0aWMgY2xhc3MgUGFyc2VFeGNlcHRpb24gZXh0ZW5kcyBFeGNlcHRpb24gewogICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDA7CiAgICAgICAgUGFyc2VFeGNlcHRpb24oU3RyaW5nIGtleSkgewogICAgICAgICAgICBzdXBlcihrZXkpOwogICAgICAgIH0KICAgIH0KCiAgICBmaW5hbCBQYXJzZXJGYWN0b3J5IGZhYzsKICAgIGZpbmFsIERpYWdub3N0aWNTb3VyY2UgZGlhZ1NvdXJjZTsKICAgIGZpbmFsIENvbW1lbnQgY29tbWVudDsKICAgIGZpbmFsIERvY1RyZWVNYWtlciBtOwogICAgZmluYWwgTmFtZXMgbmFtZXM7CgogICAgQnJlYWtJdGVyYXRvciBzZW50ZW5jZUJyZWFrZXI7CgogICAgLyoqIFRoZSBpbnB1dCBidWZmZXIsIGluZGV4IG9mIG1vc3QgcmVjZW50IGNoYXJhY3RlciByZWFkLAogICAgICogIGluZGV4IG9mIG9uZSBwYXN0IGxhc3QgY2hhcmFjdGVyIGluIGJ1ZmZlci4KICAgICAqLwogICAgcHJvdGVjdGVkIGNoYXJbXSBidWY7CiAgICBwcm90ZWN0ZWQgaW50IGJwOwogICAgcHJvdGVjdGVkIGludCBidWZsZW47CgogICAgLyoqIFRoZSBjdXJyZW50IGNoYXJhY3Rlci4KICAgICAqLwogICAgcHJvdGVjdGVkIGNoYXIgY2g7CgogICAgaW50IHRleHRTdGFydCA9IC0xOwogICAgaW50IGxhc3ROb25XaGl0ZSA9IC0xOwogICAgYm9vbGVhbiBuZXdsaW5lID0gdHJ1ZTsKCiAgICBNYXA8TmFtZSwgVGFnUGFyc2VyPiB0YWdQYXJzZXJzOwoKICAgIHB1YmxpYyBEb2NDb21tZW50UGFyc2VyKFBhcnNlckZhY3RvcnkgZmFjLCBEaWFnbm9zdGljU291cmNlIGRpYWdTb3VyY2UsIENvbW1lbnQgY29tbWVudCkgewogICAgICAgIHRoaXMuZmFjID0gZmFjOwogICAgICAgIHRoaXMuZGlhZ1NvdXJjZSA9IGRpYWdTb3VyY2U7CiAgICAgICAgdGhpcy5jb21tZW50ID0gY29tbWVudDsKICAgICAgICBuYW1lcyA9IGZhYy5uYW1lczsKICAgICAgICBtID0gZmFjLmRvY1RyZWVNYWtlcjsKICAgICAgICBpbml0VGFnUGFyc2VycygpOwogICAgfQoKICAgIHB1YmxpYyBEb2NDb21tZW50UGFyc2VyKFBhcnNlckZhY3RvcnkgZmFjKSB7CiAgICAgICAgdGhpcyhmYWMsIG51bGwsIG51bGwpOwogICAgfQoKICAgIHB1YmxpYyBEQ0RvY0NvbW1lbnQgcGFyc2UoKSB7CiAgICAgICAgU3RyaW5nIGMgPSBjb21tZW50LmdldFRleHQoKTsKICAgICAgICBidWYgPSBuZXcgY2hhcltjLmxlbmd0aCgpICsgMV07CiAgICAgICAgYy5nZXRDaGFycygwLCBjLmxlbmd0aCgpLCBidWYsIDApOwogICAgICAgIGJ1ZltidWYubGVuZ3RoIC0gMV0gPSBFT0k7CiAgICAgICAgYnVmbGVuID0gYnVmLmxlbmd0aCAtIDE7CiAgICAgICAgYnAgPSAtMTsKICAgICAgICBuZXh0Q2hhcigpOwoKICAgICAgICBMaXN0PERDVHJlZT4gYm9keSA9IGJsb2NrQ29udGVudCgpOwogICAgICAgIExpc3Q8RENUcmVlPiB0YWdzID0gYmxvY2tUYWdzKCk7CiAgICAgICAgaW50IHBvcyA9ICFib2R5LmlzRW1wdHkoKQogICAgICAgICAgICAgICAgPyBib2R5LmhlYWQucG9zCiAgICAgICAgICAgICAgICA6ICF0YWdzLmlzRW1wdHkoKSA/IHRhZ3MuaGVhZC5wb3MgOiBQb3NpdGlvbi5OT1BPUzsKCiAgICAgICAgRENEb2NDb21tZW50IGRjID0gbS5hdChwb3MpLm5ld0RvY0NvbW1lbnRUcmVlKGNvbW1lbnQsIGJvZHksIHRhZ3MpOwogICAgICAgIHJldHVybiBkYzsKICAgIH0KCiAgICB2b2lkIG5leHRDaGFyKCkgewogICAgICAgIGNoID0gYnVmW2JwIDwgYnVmbGVuID8gKyticCA6IGJ1Zmxlbl07CiAgICAgICAgc3dpdGNoIChjaCkgewogICAgICAgICAgICBjYXNlICdcZic6IGNhc2UgJ1xuJzogY2FzZSAnXHInOgogICAgICAgICAgICAgICAgbmV3bGluZSA9IHRydWU7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogUmVhZCBibG9jayBjb250ZW50LCBjb25zaXN0aW5nIG9mIHRleHQsIGh0bWwgYW5kIGlubGluZSB0YWdzLgogICAgICogVGVybWluYXRlZCBieSB0aGUgZW5kIG9mIGlucHV0LCBvciB0aGUgYmVnaW5uaW5nIG9mIHRoZSBuZXh0IGJsb2NrIHRhZzoKICAgICAqIGkuZS4gQCBhcyB0aGUgZmlyc3Qgbm9uLXdoaXRlc3BhY2UgY2hhcmFjdGVyIG9uIGEgbGluZS4KICAgICAqLwogICAgQFN1cHByZXNzV2FybmluZ3MoImZhbGx0aHJvdWdoIikKICAgIHByb3RlY3RlZCBMaXN0PERDVHJlZT4gYmxvY2tDb250ZW50KCkgewogICAgICAgIExpc3RCdWZmZXI8RENUcmVlPiB0cmVlcyA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICB0ZXh0U3RhcnQgPSAtMTsKCiAgICAgICAgbG9vcDoKICAgICAgICB3aGlsZSAoYnAgPCBidWZsZW4pIHsKICAgICAgICAgICAgc3dpdGNoIChjaCkgewogICAgICAgICAgICAgICAgY2FzZSAnXG4nOiBjYXNlICdccic6IGNhc2UgJ1xmJzoKICAgICAgICAgICAgICAgICAgICBuZXdsaW5lID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAvLyBmYWxsdGhyb3VnaAoKICAgICAgICAgICAgICAgIGNhc2UgJyAnOiBjYXNlICdcdCc6CiAgICAgICAgICAgICAgICAgICAgbmV4dENoYXIoKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBjYXNlICcmJzoKICAgICAgICAgICAgICAgICAgICBlbnRpdHkodHJlZXMpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgJzwnOgogICAgICAgICAgICAgICAgICAgIG5ld2xpbmUgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICBhZGRQZW5kaW5nVGV4dCh0cmVlcywgYnAgLSAxKTsKICAgICAgICAgICAgICAgICAgICB0cmVlcy5hZGQoaHRtbCgpKTsKICAgICAgICAgICAgICAgICAgICBpZiAodGV4dFN0YXJ0ID09IC0xKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRleHRTdGFydCA9IGJwOwogICAgICAgICAgICAgICAgICAgICAgICBsYXN0Tm9uV2hpdGUgPSAtMTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSAnPic6CiAgICAgICAgICAgICAgICAgICAgbmV3bGluZSA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgIGFkZFBlbmRpbmdUZXh0KHRyZWVzLCBicCAtIDEpOwogICAgICAgICAgICAgICAgICAgIHRyZWVzLmFkZChtLmF0KGJwKS5uZXdFcnJvbmVvdXNUcmVlKG5ld1N0cmluZyhicCwgYnAgKyAxKSwgZGlhZ1NvdXJjZSwgImRjLmJhZC5ndCIpKTsKICAgICAgICAgICAgICAgICAgICBuZXh0Q2hhcigpOwogICAgICAgICAgICAgICAgICAgIGlmICh0ZXh0U3RhcnQgPT0gLTEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGV4dFN0YXJ0ID0gYnA7CiAgICAgICAgICAgICAgICAgICAgICAgIGxhc3ROb25XaGl0ZSA9IC0xOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBjYXNlICd7JzoKICAgICAgICAgICAgICAgICAgICBpbmxpbmVUYWcodHJlZXMpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgJ0AnOgogICAgICAgICAgICAgICAgICAgIGlmIChuZXdsaW5lKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGFkZFBlbmRpbmdUZXh0KHRyZWVzLCBsYXN0Tm9uV2hpdGUpOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhayBsb29wOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAvLyBmYWxsdGhyb3VnaAoKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgbmV3bGluZSA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgIGlmICh0ZXh0U3RhcnQgPT0gLTEpCiAgICAgICAgICAgICAgICAgICAgICAgIHRleHRTdGFydCA9IGJwOwogICAgICAgICAgICAgICAgICAgIGxhc3ROb25XaGl0ZSA9IGJwOwogICAgICAgICAgICAgICAgICAgIG5leHRDaGFyKCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmIChsYXN0Tm9uV2hpdGUgIT0gLTEpCiAgICAgICAgICAgIGFkZFBlbmRpbmdUZXh0KHRyZWVzLCBsYXN0Tm9uV2hpdGUpOwoKICAgICAgICByZXR1cm4gdHJlZXMudG9MaXN0KCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZWFkIGEgc2VyaWVzIG9mIGJsb2NrIHRhZ3MsIGluY2x1ZGluZyB0aGVpciBjb250ZW50LgogICAgICogU3RhbmRhcmQgdGFncyBwYXJzZSB0aGVpciBjb250ZW50IGFwcHJvcHJpYXRlbHkuCiAgICAgKiBOb24tc3RhbmRhcmQgdGFncyBhcmUgcmVwcmVzZW50ZWQgYnkge0BsaW5rIFVua25vd25CbG9ja1RhZ30uCiAgICAgKi8KICAgIHByb3RlY3RlZCBMaXN0PERDVHJlZT4gYmxvY2tUYWdzKCkgewogICAgICAgIExpc3RCdWZmZXI8RENUcmVlPiB0YWdzID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgIHdoaWxlIChjaCA9PSAnQCcpCiAgICAgICAgICAgIHRhZ3MuYWRkKGJsb2NrVGFnKCkpOwogICAgICAgIHJldHVybiB0YWdzLnRvTGlzdCgpOwogICAgfQoKICAgIC8qKgogICAgICogUmVhZCBhIHNpbmdsZSBibG9jayB0YWcsIGluY2x1ZGluZyBpdHMgY29udGVudC4KICAgICAqIFN0YW5kYXJkIHRhZ3MgcGFyc2UgdGhlaXIgY29udGVudCBhcHByb3ByaWF0ZWx5LgogICAgICogTm9uLXN0YW5kYXJkIHRhZ3MgYXJlIHJlcHJlc2VudGVkIGJ5IHtAbGluayBVbmtub3duQmxvY2tUYWd9LgogICAgICovCiAgICBwcm90ZWN0ZWQgRENUcmVlIGJsb2NrVGFnKCkgewogICAgICAgIGludCBwID0gYnA7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgbmV4dENoYXIoKTsKICAgICAgICAgICAgaWYgKGlzSWRlbnRpZmllclN0YXJ0KGNoKSkgewogICAgICAgICAgICAgICAgTmFtZSBuYW1lID0gcmVhZFRhZ05hbWUoKTsKICAgICAgICAgICAgICAgIFRhZ1BhcnNlciB0cCA9IHRhZ1BhcnNlcnMuZ2V0KG5hbWUpOwogICAgICAgICAgICAgICAgaWYgKHRwID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICBMaXN0PERDVHJlZT4gY29udGVudCA9IGJsb2NrQ29udGVudCgpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBtLmF0KHApLm5ld1Vua25vd25CbG9ja1RhZ1RyZWUobmFtZSwgY29udGVudCk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHN3aXRjaCAodHAuZ2V0S2luZCgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgQkxPQ0s6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHAucGFyc2UocCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgSU5MSU5FOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGVycm9uZW91cygiZGMuYmFkLmlubGluZS50YWciLCBwKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYmxvY2tDb250ZW50KCk7CgogICAgICAgICAgICByZXR1cm4gZXJyb25lb3VzKCJkYy5uby50YWcubmFtZSIsIHApOwogICAgICAgIH0gY2F0Y2ggKFBhcnNlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgYmxvY2tDb250ZW50KCk7CiAgICAgICAgICAgIHJldHVybiBlcnJvbmVvdXMoZS5nZXRNZXNzYWdlKCksIHApOwogICAgICAgIH0KICAgIH0KCiAgICBwcm90ZWN0ZWQgdm9pZCBpbmxpbmVUYWcoTGlzdEJ1ZmZlcjxEQ1RyZWU+IGxpc3QpIHsKICAgICAgICBuZXdsaW5lID0gZmFsc2U7CiAgICAgICAgbmV4dENoYXIoKTsKICAgICAgICBpZiAoY2ggPT0gJ0AnKSB7CiAgICAgICAgICAgIGFkZFBlbmRpbmdUZXh0KGxpc3QsIGJwIC0gMik7CiAgICAgICAgICAgIGxpc3QuYWRkKGlubGluZVRhZygpKTsKICAgICAgICAgICAgdGV4dFN0YXJ0ID0gYnA7CiAgICAgICAgICAgIGxhc3ROb25XaGl0ZSA9IC0xOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGlmICh0ZXh0U3RhcnQgPT0gLTEpCiAgICAgICAgICAgICAgICB0ZXh0U3RhcnQgPSBicCAtIDE7CiAgICAgICAgICAgIGxhc3ROb25XaGl0ZSA9IGJwOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFJlYWQgYSBzaW5nbGUgaW5saW5lIHRhZywgaW5jbHVkaW5nIGl0cyBjb250ZW50LgogICAgICogU3RhbmRhcmQgdGFncyBwYXJzZSB0aGVpciBjb250ZW50IGFwcHJvcHJpYXRlbHkuCiAgICAgKiBOb24tc3RhbmRhcmQgdGFncyBhcmUgcmVwcmVzZW50ZWQgYnkge0BsaW5rIFVua25vd25CbG9ja1RhZ30uCiAgICAgKiBNYWxmb3JtZWQgdGFncyBtYXkgYmUgcmV0dXJuZWQgYXMge0BsaW5rIEVycm9uZW91c30uCiAgICAgKi8KICAgIHByb3RlY3RlZCBEQ1RyZWUgaW5saW5lVGFnKCkgewogICAgICAgIGludCBwID0gYnAgLSAxOwogICAgICAgIHRyeSB7CiAgICAgICAgICAgIG5leHRDaGFyKCk7CiAgICAgICAgICAgIGlmIChpc0lkZW50aWZpZXJTdGFydChjaCkpIHsKICAgICAgICAgICAgICAgIE5hbWUgbmFtZSA9IHJlYWRUYWdOYW1lKCk7CiAgICAgICAgICAgICAgICBUYWdQYXJzZXIgdHAgPSB0YWdQYXJzZXJzLmdldChuYW1lKTsKCiAgICAgICAgICAgICAgICBpZiAodHAgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIHNraXBXaGl0ZXNwYWNlKCk7CiAgICAgICAgICAgICAgICAgICAgRENUcmVlIHRleHQgPSBpbmxpbmVUZXh0KFdoaXRlc3BhY2VSZXRlbnRpb25Qb2xpY3kuUkVNT1ZFX0FMTCk7CiAgICAgICAgICAgICAgICAgICAgaWYgKHRleHQgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICBuZXh0Q2hhcigpOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbS5hdChwKS5uZXdVbmtub3duSW5saW5lVGFnVHJlZShuYW1lLCBMaXN0Lm9mKHRleHQpKS5zZXRFbmRQb3MoYnApOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCF0cC5yZXRhaW5XaGl0ZVNwYWNlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHNraXBXaGl0ZXNwYWNlKCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmICh0cC5nZXRLaW5kKCkgPT0gVGFnUGFyc2VyLktpbmQuSU5MSU5FKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIERDRW5kUG9zVHJlZTw/PiB0cmVlID0gKERDRW5kUG9zVHJlZTw/PikgdHAucGFyc2UocCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0cmVlICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cmVlLnNldEVuZFBvcyhicCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeyAvLyBoYW5kbGUgYmxvY2sgdGFncyAoZXg6IEBzZWUpIGluIGlubGluZSBjb250ZW50CiAgICAgICAgICAgICAgICAgICAgICAgIGlubGluZVRleHQoV2hpdGVzcGFjZVJldGVudGlvblBvbGljeS5SRU1PVkVfQUxMKTsgLy8gc2tpcCBjb250ZW50CiAgICAgICAgICAgICAgICAgICAgICAgIG5leHRDaGFyKCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBlcnJvbmVvdXMoImRjLm5vLnRhZy5uYW1lIiwgcCk7CiAgICAgICAgfSBjYXRjaCAoUGFyc2VFeGNlcHRpb24gZSkgewogICAgICAgICAgICByZXR1cm4gZXJyb25lb3VzKGUuZ2V0TWVzc2FnZSgpLCBwKTsKICAgICAgICB9CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgZW51bSBXaGl0ZXNwYWNlUmV0ZW50aW9uUG9saWN5IHsKICAgICAgICBSRVRBSU5fQUxMLAogICAgICAgIFJFTU9WRV9GSVJTVF9TUEFDRSwKICAgICAgICBSRU1PVkVfQUxMCiAgICB9CgogICAgLyoqCiAgICAgKiBSZWFkIHBsYWluIHRleHQgY29udGVudCBvZiBhbiBpbmxpbmUgdGFnLgogICAgICogTWF0Y2hpbmcgcGFpcnMgb2YgeyB9IGFyZSBza2lwcGVkOyB0aGUgdGV4dCBpcyB0ZXJtaW5hdGVkIGJ5IHRoZSBmaXJzdAogICAgICogdW5tYXRjaGVkIH0uIEl0IGlzIGFuIGVycm9yIGlmIHRoZSBiZWdpbm5pbmcgb2YgdGhlIG5leHQgdGFnIGlzIGRldGVjdGVkLgogICAgICovCiAgICBwcml2YXRlIERDVHJlZSBpbmxpbmVUZXh0KFdoaXRlc3BhY2VSZXRlbnRpb25Qb2xpY3kgd2hpdGVzcGFjZVBvbGljeSkgdGhyb3dzIFBhcnNlRXhjZXB0aW9uIHsKICAgICAgICBzd2l0Y2ggKHdoaXRlc3BhY2VQb2xpY3kpIHsKICAgICAgICAgICAgY2FzZSBSRU1PVkVfQUxMOgogICAgICAgICAgICAgICAgc2tpcFdoaXRlc3BhY2UoKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFJFTU9WRV9GSVJTVF9TUEFDRToKICAgICAgICAgICAgICAgIGlmIChjaCA9PSAnICcpCiAgICAgICAgICAgICAgICAgICAgbmV4dENoYXIoKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFJFVEFJTl9BTEw6CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAvLyBkbyBub3RoaW5nCiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgfQogICAgICAgIGludCBwb3MgPSBicDsKICAgICAgICBpbnQgZGVwdGggPSAxOwoKICAgICAgICBsb29wOgogICAgICAgIHdoaWxlIChicCA8IGJ1ZmxlbikgewogICAgICAgICAgICBzd2l0Y2ggKGNoKSB7CiAgICAgICAgICAgICAgICBjYXNlICdcbic6IGNhc2UgJ1xyJzogY2FzZSAnXGYnOgogICAgICAgICAgICAgICAgICAgIG5ld2xpbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgJyAnOiBjYXNlICdcdCc6CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSAneyc6CiAgICAgICAgICAgICAgICAgICAgbmV3bGluZSA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgIGxhc3ROb25XaGl0ZSA9IGJwOwogICAgICAgICAgICAgICAgICAgIGRlcHRoKys7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSAnfSc6CiAgICAgICAgICAgICAgICAgICAgaWYgKC0tZGVwdGggPT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbS5hdChwb3MpLm5ld1RleHRUcmVlKG5ld1N0cmluZyhwb3MsIGJwKSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIG5ld2xpbmUgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICBsYXN0Tm9uV2hpdGUgPSBicDsKICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBjYXNlICdAJzoKICAgICAgICAgICAgICAgICAgICBpZiAobmV3bGluZSkKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWsgbG9vcDsKICAgICAgICAgICAgICAgICAgICBuZXdsaW5lID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgbGFzdE5vbldoaXRlID0gYnA7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICBuZXdsaW5lID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgbGFzdE5vbldoaXRlID0gYnA7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgbmV4dENoYXIoKTsKICAgICAgICB9CiAgICAgICAgdGhyb3cgbmV3IFBhcnNlRXhjZXB0aW9uKCJkYy51bnRlcm1pbmF0ZWQuaW5saW5lLnRhZyIpOwogICAgfQoKICAgIC8qKgogICAgICogUmVhZCBKYXZhIGNsYXNzIG5hbWUsIHBvc3NpYmx5IGZvbGxvd2VkIGJ5IG1lbWJlcgogICAgICogTWF0Y2hpbmcgcGFpcnMgb2Yge0BsaXRlcmFsIDwgPn0gYXJlIHNraXBwZWQuIFRoZSB0ZXh0IGlzIHRlcm1pbmF0ZWQgYnkgdGhlIGZpcnN0CiAgICAgKiB1bm1hdGNoZWQgfS4gSXQgaXMgYW4gZXJyb3IgaWYgdGhlIGJlZ2lubmluZyBvZiB0aGUgbmV4dCB0YWcgaXMgZGV0ZWN0ZWQuCiAgICAgKi8KICAgIC8vIFRPRE86IGJvb2xlYW4gYWxsb3dNZW1iZXIgc2hvdWxkIGJlIGVudW0gRk9SQklELCBBTExPVywgUkVRVUlSRQogICAgLy8gVE9ETzogaW1wcm92ZSBxdWFsaXR5IG9mIHBhcnNlIHRvIGZvcmJpZCBiYWQgY29uc3RydWN0aW9ucy4KICAgIC8vIFRPRE86IHVwZGF0ZSB0byB1c2UgUmVmZXJlbmNlUGFyc2VyCiAgICBAU3VwcHJlc3NXYXJuaW5ncygiZmFsbHRocm91Z2giKQogICAgcHJvdGVjdGVkIERDUmVmZXJlbmNlIHJlZmVyZW5jZShib29sZWFuIGFsbG93TWVtYmVyKSB0aHJvd3MgUGFyc2VFeGNlcHRpb24gewogICAgICAgIGludCBwb3MgPSBicDsKICAgICAgICBpbnQgZGVwdGggPSAwOwoKICAgICAgICAvLyBzY2FuIHRvIGZpbmQgdGhlIGVuZCBvZiB0aGUgc2lnbmF0dXJlLCBieSBsb29raW5nIGZvciB0aGUgZmlyc3QKICAgICAgICAvLyB3aGl0ZXNwYWNlIG5vdCBlbmNsb3NlZCBpbiAoKSBvciA8Piwgb3IgdGhlIGVuZCBvZiB0aGUgdGFnCiAgICAgICAgbG9vcDoKICAgICAgICB3aGlsZSAoYnAgPCBidWZsZW4pIHsKICAgICAgICAgICAgc3dpdGNoIChjaCkgewogICAgICAgICAgICAgICAgY2FzZSAnXG4nOiBjYXNlICdccic6IGNhc2UgJ1xmJzoKICAgICAgICAgICAgICAgICAgICBuZXdsaW5lID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAvLyBmYWxsdGhyb3VnaAoKICAgICAgICAgICAgICAgIGNhc2UgJyAnOiBjYXNlICdcdCc6CiAgICAgICAgICAgICAgICAgICAgaWYgKGRlcHRoID09IDApCiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrIGxvb3A7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSAnKCc6CiAgICAgICAgICAgICAgICBjYXNlICc8JzoKICAgICAgICAgICAgICAgICAgICBuZXdsaW5lID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgZGVwdGgrKzsKICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBjYXNlICcpJzoKICAgICAgICAgICAgICAgIGNhc2UgJz4nOgogICAgICAgICAgICAgICAgICAgIG5ld2xpbmUgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICAtLWRlcHRoOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgJ30nOgogICAgICAgICAgICAgICAgICAgIGlmIChicCA9PSBwb3MpCiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICAgICAgICAgIG5ld2xpbmUgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICBicmVhayBsb29wOwoKICAgICAgICAgICAgICAgIGNhc2UgJ0AnOgogICAgICAgICAgICAgICAgICAgIGlmIChuZXdsaW5lKQogICAgICAgICAgICAgICAgICAgICAgICBicmVhayBsb29wOwogICAgICAgICAgICAgICAgICAgIC8vIGZhbGx0aHJvdWdoCgogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICBuZXdsaW5lID0gZmFsc2U7CgogICAgICAgICAgICB9CiAgICAgICAgICAgIG5leHRDaGFyKCk7CiAgICAgICAgfQoKICAgICAgICBpZiAoZGVwdGggIT0gMCkKICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlRXhjZXB0aW9uKCJkYy51bnRlcm1pbmF0ZWQuc2lnbmF0dXJlIik7CgogICAgICAgIFN0cmluZyBzaWcgPSBuZXdTdHJpbmcocG9zLCBicCk7CgogICAgICAgIC8vIEJyZWFrIHNpZyBhcGFydCBpbnRvIHF1YWxpZmllZEV4cHIgbWVtYmVyIHBhcmFtVHlwZXMuCiAgICAgICAgSkNUcmVlIHF1YWxFeHByOwogICAgICAgIE5hbWUgbWVtYmVyOwogICAgICAgIExpc3Q8SkNUcmVlPiBwYXJhbVR5cGVzOwoKICAgICAgICBMb2cuRGVmZXJyZWREaWFnbm9zdGljSGFuZGxlciBkZWZlcnJlZERpYWdub3N0aWNIYW5kbGVyCiAgICAgICAgICAgICAgICA9IG5ldyBMb2cuRGVmZXJyZWREaWFnbm9zdGljSGFuZGxlcihmYWMubG9nKTsKCiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgaW50IGhhc2ggPSBzaWcuaW5kZXhPZigiIyIpOwogICAgICAgICAgICBpbnQgbHBhcmVuID0gc2lnLmluZGV4T2YoIigiLCBoYXNoICsgMSk7CiAgICAgICAgICAgIGlmIChoYXNoID09IC0xKSB7CiAgICAgICAgICAgICAgICBpZiAobHBhcmVuID09IC0xKSB7CiAgICAgICAgICAgICAgICAgICAgcXVhbEV4cHIgPSBwYXJzZVR5cGUoc2lnKTsKICAgICAgICAgICAgICAgICAgICBtZW1iZXIgPSBudWxsOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBxdWFsRXhwciA9IG51bGw7CiAgICAgICAgICAgICAgICAgICAgbWVtYmVyID0gcGFyc2VNZW1iZXIoc2lnLnN1YnN0cmluZygwLCBscGFyZW4pKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHF1YWxFeHByID0gKGhhc2ggPT0gMCkgPyBudWxsIDogcGFyc2VUeXBlKHNpZy5zdWJzdHJpbmcoMCwgaGFzaCkpOwogICAgICAgICAgICAgICAgaWYgKGxwYXJlbiA9PSAtMSkKICAgICAgICAgICAgICAgICAgICBtZW1iZXIgPSBwYXJzZU1lbWJlcihzaWcuc3Vic3RyaW5nKGhhc2ggKyAxKSk7CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgbWVtYmVyID0gcGFyc2VNZW1iZXIoc2lnLnN1YnN0cmluZyhoYXNoICsgMSwgbHBhcmVuKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChscGFyZW4gPCAwKSB7CiAgICAgICAgICAgICAgICBwYXJhbVR5cGVzID0gbnVsbDsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGludCBycGFyZW4gPSBzaWcuaW5kZXhPZigiKSIsIGxwYXJlbik7CiAgICAgICAgICAgICAgICBpZiAocnBhcmVuICE9IHNpZy5sZW5ndGgoKSAtIDEpCiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlRXhjZXB0aW9uKCJkYy5yZWYuYmFkLnBhcmVucyIpOwogICAgICAgICAgICAgICAgcGFyYW1UeXBlcyA9IHBhcnNlUGFyYW1zKHNpZy5zdWJzdHJpbmcobHBhcmVuICsgMSwgcnBhcmVuKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICghZGVmZXJyZWREaWFnbm9zdGljSGFuZGxlci5nZXREaWFnbm9zdGljcygpLmlzRW1wdHkoKSkKICAgICAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZUV4Y2VwdGlvbigiZGMucmVmLnN5bnRheC5lcnJvciIpOwoKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICBmYWMubG9nLnBvcERpYWdub3N0aWNIYW5kbGVyKGRlZmVycmVkRGlhZ25vc3RpY0hhbmRsZXIpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIG0uYXQocG9zKS5uZXdSZWZlcmVuY2VUcmVlKHNpZywgcXVhbEV4cHIsIG1lbWJlciwgcGFyYW1UeXBlcykuc2V0RW5kUG9zKGJwKTsKICAgIH0KCiAgICBKQ1RyZWUgcGFyc2VUeXBlKFN0cmluZyBzKSB0aHJvd3MgUGFyc2VFeGNlcHRpb24gewogICAgICAgIEphdmFjUGFyc2VyIHAgPSBmYWMubmV3UGFyc2VyKHMsIGZhbHNlLCBmYWxzZSwgZmFsc2UpOwogICAgICAgIEpDVHJlZSB0cmVlID0gcC5wYXJzZVR5cGUoKTsKICAgICAgICBpZiAocC50b2tlbigpLmtpbmQgIT0gVG9rZW5LaW5kLkVPRikKICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlRXhjZXB0aW9uKCJkYy5yZWYudW5leHBlY3RlZC5pbnB1dCIpOwogICAgICAgIHJldHVybiB0cmVlOwogICAgfQoKICAgIE5hbWUgcGFyc2VNZW1iZXIoU3RyaW5nIHMpIHRocm93cyBQYXJzZUV4Y2VwdGlvbiB7CiAgICAgICAgSmF2YWNQYXJzZXIgcCA9IGZhYy5uZXdQYXJzZXIocywgZmFsc2UsIGZhbHNlLCBmYWxzZSk7CiAgICAgICAgTmFtZSBuYW1lID0gcC5pZGVudCgpOwogICAgICAgIGlmIChwLnRva2VuKCkua2luZCAhPSBUb2tlbktpbmQuRU9GKQogICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2VFeGNlcHRpb24oImRjLnJlZi51bmV4cGVjdGVkLmlucHV0Iik7CiAgICAgICAgcmV0dXJuIG5hbWU7CiAgICB9CgogICAgTGlzdDxKQ1RyZWU+IHBhcnNlUGFyYW1zKFN0cmluZyBzKSB0aHJvd3MgUGFyc2VFeGNlcHRpb24gewogICAgICAgIGlmIChzLnRyaW0oKS5pc0VtcHR5KCkpCiAgICAgICAgICAgIHJldHVybiBMaXN0Lm5pbCgpOwoKICAgICAgICBKYXZhY1BhcnNlciBwID0gZmFjLm5ld1BhcnNlcihzLnJlcGxhY2UoIi4uLiIsICJbXSIpLCBmYWxzZSwgZmFsc2UsIGZhbHNlKTsKICAgICAgICBMaXN0QnVmZmVyPEpDVHJlZT4gcGFyYW1UeXBlcyA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICBwYXJhbVR5cGVzLmFkZChwLnBhcnNlVHlwZSgpKTsKCiAgICAgICAgaWYgKHAudG9rZW4oKS5raW5kID09IFRva2VuS2luZC5JREVOVElGSUVSKQogICAgICAgICAgICBwLm5leHRUb2tlbigpOwoKICAgICAgICB3aGlsZSAocC50b2tlbigpLmtpbmQgPT0gVG9rZW5LaW5kLkNPTU1BKSB7CiAgICAgICAgICAgIHAubmV4dFRva2VuKCk7CiAgICAgICAgICAgIHBhcmFtVHlwZXMuYWRkKHAucGFyc2VUeXBlKCkpOwoKICAgICAgICAgICAgaWYgKHAudG9rZW4oKS5raW5kID09IFRva2VuS2luZC5JREVOVElGSUVSKQogICAgICAgICAgICAgICAgcC5uZXh0VG9rZW4oKTsKICAgICAgICB9CgogICAgICAgIGlmIChwLnRva2VuKCkua2luZCAhPSBUb2tlbktpbmQuRU9GKQogICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2VFeGNlcHRpb24oImRjLnJlZi51bmV4cGVjdGVkLmlucHV0Iik7CgogICAgICAgIHJldHVybiBwYXJhbVR5cGVzLnRvTGlzdCgpOwogICAgfQoKICAgIC8qKgogICAgICogUmVhZCBKYXZhIGlkZW50aWZpZXIKICAgICAqIE1hdGNoaW5nIHBhaXJzIG9mIHsgfSBhcmUgc2tpcHBlZDsgdGhlIHRleHQgaXMgdGVybWluYXRlZCBieSB0aGUgZmlyc3QKICAgICAqIHVubWF0Y2hlZCB9LiBJdCBpcyBhbiBlcnJvciBpZiB0aGUgYmVnaW5uaW5nIG9mIHRoZSBuZXh0IHRhZyBpcyBkZXRlY3RlZC4KICAgICAqLwogICAgQFN1cHByZXNzV2FybmluZ3MoImZhbGx0aHJvdWdoIikKICAgIHByb3RlY3RlZCBEQ0lkZW50aWZpZXIgaWRlbnRpZmllcigpIHRocm93cyBQYXJzZUV4Y2VwdGlvbiB7CiAgICAgICAgc2tpcFdoaXRlc3BhY2UoKTsKICAgICAgICBpbnQgcG9zID0gYnA7CgogICAgICAgIGlmIChpc0phdmFJZGVudGlmaWVyU3RhcnQoY2gpKSB7CiAgICAgICAgICAgIE5hbWUgbmFtZSA9IHJlYWRKYXZhSWRlbnRpZmllcigpOwogICAgICAgICAgICByZXR1cm4gbS5hdChwb3MpLm5ld0lkZW50aWZpZXJUcmVlKG5hbWUpOwogICAgICAgIH0KCiAgICAgICAgdGhyb3cgbmV3IFBhcnNlRXhjZXB0aW9uKCJkYy5pZGVudGlmaWVyLmV4cGVjdGVkIik7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZWFkIGEgcXVvdGVkIHN0cmluZy4KICAgICAqIEl0IGlzIGFuIGVycm9yIGlmIHRoZSBiZWdpbm5pbmcgb2YgdGhlIG5leHQgdGFnIGlzIGRldGVjdGVkLgogICAgICovCiAgICBAU3VwcHJlc3NXYXJuaW5ncygiZmFsbHRocm91Z2giKQogICAgcHJvdGVjdGVkIERDVGV4dCBxdW90ZWRTdHJpbmcoKSB7CiAgICAgICAgaW50IHBvcyA9IGJwOwogICAgICAgIG5leHRDaGFyKCk7CgogICAgICAgIGxvb3A6CiAgICAgICAgd2hpbGUgKGJwIDwgYnVmbGVuKSB7CiAgICAgICAgICAgIHN3aXRjaCAoY2gpIHsKICAgICAgICAgICAgICAgIGNhc2UgJ1xuJzogY2FzZSAnXHInOiBjYXNlICdcZic6CiAgICAgICAgICAgICAgICAgICAgbmV3bGluZSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSAnICc6IGNhc2UgJ1x0JzoKICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBjYXNlICciJzoKICAgICAgICAgICAgICAgICAgICBuZXh0Q2hhcigpOwogICAgICAgICAgICAgICAgICAgIC8vIHRyaW0gdHJhaWxpbmcgd2hpdGUtc3BhY2U/CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG0uYXQocG9zKS5uZXdUZXh0VHJlZShuZXdTdHJpbmcocG9zLCBicCkpOwoKICAgICAgICAgICAgICAgIGNhc2UgJ0AnOgogICAgICAgICAgICAgICAgICAgIGlmIChuZXdsaW5lKQogICAgICAgICAgICAgICAgICAgICAgICBicmVhayBsb29wOwoKICAgICAgICAgICAgfQogICAgICAgICAgICBuZXh0Q2hhcigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICAvKioKICAgICAqIFJlYWQgYSB0ZXJtIGllLiBvbmUgd29yZC4KICAgICAqIEl0IGlzIGFuIGVycm9yIGlmIHRoZSBiZWdpbm5pbmcgb2YgdGhlIG5leHQgdGFnIGlzIGRldGVjdGVkLgogICAgICovCiAgICBAU3VwcHJlc3NXYXJuaW5ncygiZmFsbHRocm91Z2giKQogICAgcHJvdGVjdGVkIERDVGV4dCBpbmxpbmVXb3JkKCkgewogICAgICAgIGludCBwb3MgPSBicDsKICAgICAgICBpbnQgZGVwdGggPSAwOwogICAgICAgIGxvb3A6CiAgICAgICAgd2hpbGUgKGJwIDwgYnVmbGVuKSB7CiAgICAgICAgICAgIHN3aXRjaCAoY2gpIHsKICAgICAgICAgICAgICAgIGNhc2UgJ1xuJzoKICAgICAgICAgICAgICAgICAgICBuZXdsaW5lID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAvLyBmYWxsdGhyb3VnaAoKICAgICAgICAgICAgICAgIGNhc2UgJ1xyJzogY2FzZSAnXGYnOiBjYXNlICcgJzogY2FzZSAnXHQnOgogICAgICAgICAgICAgICAgICAgIHJldHVybiBtLmF0KHBvcykubmV3VGV4dFRyZWUobmV3U3RyaW5nKHBvcywgYnApKTsKCiAgICAgICAgICAgICAgICBjYXNlICdAJzoKICAgICAgICAgICAgICAgICAgICBpZiAobmV3bGluZSkKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWsgbG9vcDsKCiAgICAgICAgICAgICAgICBjYXNlICd7JzoKICAgICAgICAgICAgICAgICAgICBkZXB0aCsrOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgJ30nOgogICAgICAgICAgICAgICAgICAgIGlmIChkZXB0aCA9PSAwIHx8IC0tZGVwdGggPT0gMCkKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG0uYXQocG9zKS5uZXdUZXh0VHJlZShuZXdTdHJpbmcocG9zLCBicCkpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIG5ld2xpbmUgPSBmYWxzZTsKICAgICAgICAgICAgbmV4dENoYXIoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZWFkIGdlbmVyYWwgdGV4dCBjb250ZW50IG9mIGFuIGlubGluZSB0YWcsIGluY2x1ZGluZyBIVE1MIGVudGl0aWVzIGFuZCBlbGVtZW50cy4KICAgICAqIE1hdGNoaW5nIHBhaXJzIG9mIHsgfSBhcmUgc2tpcHBlZDsgdGhlIHRleHQgaXMgdGVybWluYXRlZCBieSB0aGUgZmlyc3QKICAgICAqIHVubWF0Y2hlZCB9LiBJdCBpcyBhbiBlcnJvciBpZiB0aGUgYmVnaW5uaW5nIG9mIHRoZSBuZXh0IHRhZyBpcyBkZXRlY3RlZC4KICAgICAqLwogICAgQFN1cHByZXNzV2FybmluZ3MoImZhbGx0aHJvdWdoIikKICAgIHByaXZhdGUgTGlzdDxEQ1RyZWU+IGlubGluZUNvbnRlbnQoKSB7CiAgICAgICAgTGlzdEJ1ZmZlcjxEQ1RyZWU+IHRyZWVzID0gbmV3IExpc3RCdWZmZXI8PigpOwoKICAgICAgICBza2lwV2hpdGVzcGFjZSgpOwogICAgICAgIGludCBwb3MgPSBicDsKICAgICAgICBpbnQgZGVwdGggPSAxOwogICAgICAgIHRleHRTdGFydCA9IC0xOwoKICAgICAgICBsb29wOgogICAgICAgIHdoaWxlIChicCA8IGJ1ZmxlbikgewoKICAgICAgICAgICAgc3dpdGNoIChjaCkgewogICAgICAgICAgICAgICAgY2FzZSAnXG4nOiBjYXNlICdccic6IGNhc2UgJ1xmJzoKICAgICAgICAgICAgICAgICAgICBuZXdsaW5lID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAvLyBmYWxsIHRocm91Z2gKCiAgICAgICAgICAgICAgICBjYXNlICcgJzogY2FzZSAnXHQnOgogICAgICAgICAgICAgICAgICAgIG5leHRDaGFyKCk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSAnJic6CiAgICAgICAgICAgICAgICAgICAgZW50aXR5KHRyZWVzKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBjYXNlICc8JzoKICAgICAgICAgICAgICAgICAgICBuZXdsaW5lID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgYWRkUGVuZGluZ1RleHQodHJlZXMsIGJwIC0gMSk7CiAgICAgICAgICAgICAgICAgICAgdHJlZXMuYWRkKGh0bWwoKSk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSAneyc6CiAgICAgICAgICAgICAgICAgICAgaWYgKHRleHRTdGFydCA9PSAtMSkKICAgICAgICAgICAgICAgICAgICAgICAgdGV4dFN0YXJ0ID0gYnA7CiAgICAgICAgICAgICAgICAgICAgbmV3bGluZSA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgIGRlcHRoKys7CiAgICAgICAgICAgICAgICAgICAgbmV4dENoYXIoKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBjYXNlICd9JzoKICAgICAgICAgICAgICAgICAgICBuZXdsaW5lID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgaWYgKC0tZGVwdGggPT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICBhZGRQZW5kaW5nVGV4dCh0cmVlcywgYnAgLSAxKTsKICAgICAgICAgICAgICAgICAgICAgICAgbmV4dENoYXIoKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRyZWVzLnRvTGlzdCgpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBuZXh0Q2hhcigpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgJ0AnOgogICAgICAgICAgICAgICAgICAgIGlmIChuZXdsaW5lKQogICAgICAgICAgICAgICAgICAgICAgICBicmVhayBsb29wOwogICAgICAgICAgICAgICAgICAgIC8vIGZhbGx0aHJvdWdoCgogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICBpZiAodGV4dFN0YXJ0ID09IC0xKQogICAgICAgICAgICAgICAgICAgICAgICB0ZXh0U3RhcnQgPSBicDsKICAgICAgICAgICAgICAgICAgICBuZXh0Q2hhcigpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gTGlzdC5vZihlcnJvbmVvdXMoImRjLnVudGVybWluYXRlZC5pbmxpbmUudGFnIiwgcG9zKSk7CiAgICB9CgogICAgcHJvdGVjdGVkIHZvaWQgZW50aXR5KExpc3RCdWZmZXI8RENUcmVlPiBsaXN0KSB7CiAgICAgICAgbmV3bGluZSA9IGZhbHNlOwogICAgICAgIGFkZFBlbmRpbmdUZXh0KGxpc3QsIGJwIC0gMSk7CiAgICAgICAgbGlzdC5hZGQoZW50aXR5KCkpOwogICAgICAgIGlmICh0ZXh0U3RhcnQgPT0gLTEpIHsKICAgICAgICAgICAgdGV4dFN0YXJ0ID0gYnA7CiAgICAgICAgICAgIGxhc3ROb25XaGl0ZSA9IC0xOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFJlYWQgYW4gSFRNTCBlbnRpdHkuCiAgICAgKiB7QGxpdGVyYWwgJmlkZW50aWZpZXI7IH0gb3Ige0BsaXRlcmFsICYjZGlnaXRzOyB9IG9yIHtAbGl0ZXJhbCAmI3hoZXgtZGlnaXRzOyB9CiAgICAgKi8KICAgIHByb3RlY3RlZCBEQ1RyZWUgZW50aXR5KCkgewogICAgICAgIGludCBwID0gYnA7CiAgICAgICAgbmV4dENoYXIoKTsKICAgICAgICBOYW1lIG5hbWUgPSBudWxsOwogICAgICAgIGlmIChjaCA9PSAnIycpIHsKICAgICAgICAgICAgaW50IG5hbWVwID0gYnA7CiAgICAgICAgICAgIG5leHRDaGFyKCk7CiAgICAgICAgICAgIGlmIChpc0RlY2ltYWxEaWdpdChjaCkpIHsKICAgICAgICAgICAgICAgIG5leHRDaGFyKCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaXNEZWNpbWFsRGlnaXQoY2gpKQogICAgICAgICAgICAgICAgICAgIG5leHRDaGFyKCk7CiAgICAgICAgICAgICAgICBuYW1lID0gbmFtZXMuZnJvbUNoYXJzKGJ1ZiwgbmFtZXAsIGJwIC0gbmFtZXApOwogICAgICAgICAgICB9IGVsc2UgaWYgKGNoID09ICd4JyB8fCBjaCA9PSAnWCcpIHsKICAgICAgICAgICAgICAgIG5leHRDaGFyKCk7CiAgICAgICAgICAgICAgICBpZiAoaXNIZXhEaWdpdChjaCkpIHsKICAgICAgICAgICAgICAgICAgICBuZXh0Q2hhcigpOwogICAgICAgICAgICAgICAgICAgIHdoaWxlIChpc0hleERpZ2l0KGNoKSkKICAgICAgICAgICAgICAgICAgICAgICAgbmV4dENoYXIoKTsKICAgICAgICAgICAgICAgICAgICBuYW1lID0gbmFtZXMuZnJvbUNoYXJzKGJ1ZiwgbmFtZXAsIGJwIC0gbmFtZXApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmIChpc0lkZW50aWZpZXJTdGFydChjaCkpIHsKICAgICAgICAgICAgbmFtZSA9IHJlYWRJZGVudGlmaWVyKCk7CiAgICAgICAgfQoKICAgICAgICBpZiAobmFtZSA9PSBudWxsKQogICAgICAgICAgICByZXR1cm4gZXJyb25lb3VzKCJkYy5iYWQuZW50aXR5IiwgcCk7CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIGlmIChjaCAhPSAnOycpCiAgICAgICAgICAgICAgICByZXR1cm4gZXJyb25lb3VzKCJkYy5taXNzaW5nLnNlbWljb2xvbiIsIHApOwogICAgICAgICAgICBuZXh0Q2hhcigpOwogICAgICAgICAgICByZXR1cm4gbS5hdChwKS5uZXdFbnRpdHlUcmVlKG5hbWUpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFJlYWQgdGhlIHN0YXJ0IG9yIGVuZCBvZiBhbiBIVE1MIHRhZywgb3IgYW4gSFRNTCBjb21tZW50CiAgICAgKiB7QGxpdGVyYWwgPGlkZW50aWZpZXIgYXR0cnM+IH0gb3Ige0BsaXRlcmFsIDwvaWRlbnRpZmllcj4gfQogICAgICovCiAgICBwcm90ZWN0ZWQgRENUcmVlIGh0bWwoKSB7CiAgICAgICAgaW50IHAgPSBicDsKICAgICAgICBuZXh0Q2hhcigpOwogICAgICAgIGlmIChpc0lkZW50aWZpZXJTdGFydChjaCkpIHsKICAgICAgICAgICAgTmFtZSBuYW1lID0gcmVhZElkZW50aWZpZXIoKTsKICAgICAgICAgICAgTGlzdDxEQ1RyZWU+IGF0dHJzID0gaHRtbEF0dHJzKCk7CiAgICAgICAgICAgIGlmIChhdHRycyAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICBib29sZWFuIHNlbGZDbG9zaW5nID0gZmFsc2U7CiAgICAgICAgICAgICAgICBpZiAoY2ggPT0gJy8nKSB7CiAgICAgICAgICAgICAgICAgICAgbmV4dENoYXIoKTsKICAgICAgICAgICAgICAgICAgICBzZWxmQ2xvc2luZyA9IHRydWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoY2ggPT0gJz4nKSB7CiAgICAgICAgICAgICAgICAgICAgbmV4dENoYXIoKTsKICAgICAgICAgICAgICAgICAgICBEQ1RyZWUgZGN0cmVlID0gbS5hdChwKS5uZXdTdGFydEVsZW1lbnRUcmVlKG5hbWUsIGF0dHJzLCBzZWxmQ2xvc2luZykuc2V0RW5kUG9zKGJwKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGN0cmVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmIChjaCA9PSAnLycpIHsKICAgICAgICAgICAgbmV4dENoYXIoKTsKICAgICAgICAgICAgaWYgKGlzSWRlbnRpZmllclN0YXJ0KGNoKSkgewogICAgICAgICAgICAgICAgTmFtZSBuYW1lID0gcmVhZElkZW50aWZpZXIoKTsKICAgICAgICAgICAgICAgIHNraXBXaGl0ZXNwYWNlKCk7CiAgICAgICAgICAgICAgICBpZiAoY2ggPT0gJz4nKSB7CiAgICAgICAgICAgICAgICAgICAgbmV4dENoYXIoKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbS5hdChwKS5uZXdFbmRFbGVtZW50VHJlZShuYW1lKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSBpZiAoY2ggPT0gJyEnKSB7CiAgICAgICAgICAgIG5leHRDaGFyKCk7CiAgICAgICAgICAgIGlmIChjaCA9PSAnLScpIHsKICAgICAgICAgICAgICAgIG5leHRDaGFyKCk7CiAgICAgICAgICAgICAgICBpZiAoY2ggPT0gJy0nKSB7CiAgICAgICAgICAgICAgICAgICAgbmV4dENoYXIoKTsKICAgICAgICAgICAgICAgICAgICB3aGlsZSAoYnAgPCBidWZsZW4pIHsKICAgICAgICAgICAgICAgICAgICAgICAgaW50IGRhc2ggPSAwOwogICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoY2ggPT0gJy0nKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXNoKys7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXh0Q2hhcigpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFN0cmljdGx5IHNwZWFraW5nLCBhIGNvbW1lbnQgc2hvdWxkIG5vdCBjb250YWluICItLSIKICAgICAgICAgICAgICAgICAgICAgICAgLy8gc28gZGFzaCA+IDIgaXMgYW4gZXJyb3IsIGRhc2ggPT0gMiBpbXBsaWVzIGNoID09ICc+JwogICAgICAgICAgICAgICAgICAgICAgICAvLyBTZWUgaHR0cDovL3d3dy53My5vcmcvVFIvaHRtbC1tYXJrdXAvc3ludGF4Lmh0bWwjc3ludGF4LWNvbW1lbnRzCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZvciBtb3JlIGRldGFpbHMuCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkYXNoID49IDIgJiYgY2ggPT0gJz4nKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXh0Q2hhcigpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG0uYXQocCkubmV3Q29tbWVudFRyZWUobmV3U3RyaW5nKHAsIGJwKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIG5leHRDaGFyKCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBicCA9IHAgKyAxOwogICAgICAgIGNoID0gYnVmW2JwXTsKICAgICAgICByZXR1cm4gZXJyb25lb3VzKCJkYy5tYWxmb3JtZWQuaHRtbCIsIHApOwogICAgfQoKICAgIC8qKgogICAgICogUmVhZCBhIHNlcmllcyBvZiBIVE1MIGF0dHJpYnV0ZXMsIHRlcm1pbmF0ZWQgYnkge0BsaXRlcmFsID4gfS4KICAgICAqIEVhY2ggYXR0cmlidXRlIGlzIG9mIHRoZSBmb3JtIHtAbGl0ZXJhbCBpZGVudGlmaWVyWz12YWx1ZV0gfS4KICAgICAqICJ2YWx1ZSIgbWF5IGJlIHVucXVvdGVkLCBzaW5nbGUtcXVvdGVkLCBvciBkb3VibGUtcXVvdGVkLgogICAgICovCiAgICBwcm90ZWN0ZWQgTGlzdDxEQ1RyZWU+IGh0bWxBdHRycygpIHsKICAgICAgICBMaXN0QnVmZmVyPERDVHJlZT4gYXR0cnMgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgc2tpcFdoaXRlc3BhY2UoKTsKCiAgICAgICAgbG9vcDoKICAgICAgICB3aGlsZSAoaXNJZGVudGlmaWVyU3RhcnQoY2gpKSB7CiAgICAgICAgICAgIGludCBuYW1lUG9zID0gYnA7CiAgICAgICAgICAgIE5hbWUgbmFtZSA9IHJlYWRBdHRyaWJ1dGVOYW1lKCk7CiAgICAgICAgICAgIHNraXBXaGl0ZXNwYWNlKCk7CiAgICAgICAgICAgIExpc3Q8RENUcmVlPiB2YWx1ZSA9IG51bGw7CiAgICAgICAgICAgIFZhbHVlS2luZCB2a2luZCA9IFZhbHVlS2luZC5FTVBUWTsKICAgICAgICAgICAgaWYgKGNoID09ICc9JykgewogICAgICAgICAgICAgICAgTGlzdEJ1ZmZlcjxEQ1RyZWU+IHYgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgICAgICBuZXh0Q2hhcigpOwogICAgICAgICAgICAgICAgc2tpcFdoaXRlc3BhY2UoKTsKICAgICAgICAgICAgICAgIGlmIChjaCA9PSAnXCcnIHx8IGNoID09ICciJykgewogICAgICAgICAgICAgICAgICAgIHZraW5kID0gKGNoID09ICdcJycpID8gVmFsdWVLaW5kLlNJTkdMRSA6IFZhbHVlS2luZC5ET1VCTEU7CiAgICAgICAgICAgICAgICAgICAgY2hhciBxdW90ZSA9IGNoOwogICAgICAgICAgICAgICAgICAgIG5leHRDaGFyKCk7CiAgICAgICAgICAgICAgICAgICAgdGV4dFN0YXJ0ID0gYnA7CiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGJwIDwgYnVmbGVuICYmIGNoICE9IHF1b3RlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChuZXdsaW5lICYmIGNoID09ICdAJykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0cnMuYWRkKGVycm9uZW91cygiZGMudW50ZXJtaW5hdGVkLnN0cmluZyIsIG5hbWVQb3MpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE5vIHBvaW50IHRyeWluZyB0byByZWFkIG1vcmUuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBJbiBmYWN0LCBhbGwgYXR0cnMgZ2V0IGRpc2NhcmRlZCBieSB0aGUgY2FsbGVyCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBhbmQgc3VwZXJzZWRlZCBieSBhIG1hbGZvcm1lZC5odG1sIG5vZGUgYmVjYXVzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhlIGh0bWwgdGFnIGl0c2VsZiBpcyBub3QgdGVybWluYXRlZCBjb3JyZWN0bHkuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhayBsb29wOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJWYWx1ZUNoYXIodik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGFkZFBlbmRpbmdUZXh0KHYsIGJwIC0gMSk7CiAgICAgICAgICAgICAgICAgICAgbmV4dENoYXIoKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgdmtpbmQgPSBWYWx1ZUtpbmQuVU5RVU9URUQ7CiAgICAgICAgICAgICAgICAgICAgdGV4dFN0YXJ0ID0gYnA7CiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGJwIDwgYnVmbGVuICYmICFpc1VucXVvdGVkQXR0clZhbHVlVGVybWluYXRvcihjaCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgYXR0clZhbHVlQ2hhcih2KTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYWRkUGVuZGluZ1RleHQodiwgYnAgLSAxKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHNraXBXaGl0ZXNwYWNlKCk7CiAgICAgICAgICAgICAgICB2YWx1ZSA9IHYudG9MaXN0KCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgRENBdHRyaWJ1dGUgYXR0ciA9IG0uYXQobmFtZVBvcykubmV3QXR0cmlidXRlVHJlZShuYW1lLCB2a2luZCwgdmFsdWUpOwogICAgICAgICAgICBhdHRycy5hZGQoYXR0cik7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gYXR0cnMudG9MaXN0KCk7CiAgICB9CgogICAgcHJvdGVjdGVkIHZvaWQgYXR0clZhbHVlQ2hhcihMaXN0QnVmZmVyPERDVHJlZT4gbGlzdCkgewogICAgICAgIHN3aXRjaCAoY2gpIHsKICAgICAgICAgICAgY2FzZSAnJic6CiAgICAgICAgICAgICAgICBlbnRpdHkobGlzdCk7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgJ3snOgogICAgICAgICAgICAgICAgaW5saW5lVGFnKGxpc3QpOwogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgbmV4dENoYXIoKTsKICAgICAgICB9CiAgICB9CgogICAgcHJvdGVjdGVkIHZvaWQgYWRkUGVuZGluZ1RleHQoTGlzdEJ1ZmZlcjxEQ1RyZWU+IGxpc3QsIGludCB0ZXh0RW5kKSB7CiAgICAgICAgaWYgKHRleHRTdGFydCAhPSAtMSkgewogICAgICAgICAgICBpZiAodGV4dFN0YXJ0IDw9IHRleHRFbmQpIHsKICAgICAgICAgICAgICAgIGxpc3QuYWRkKG0uYXQodGV4dFN0YXJ0KS5uZXdUZXh0VHJlZShuZXdTdHJpbmcodGV4dFN0YXJ0LCB0ZXh0RW5kICsgMSkpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICB0ZXh0U3RhcnQgPSAtMTsKICAgICAgICB9CiAgICB9CgogICAgcHJvdGVjdGVkIERDRXJyb25lb3VzIGVycm9uZW91cyhTdHJpbmcgY29kZSwgaW50IHBvcykgewogICAgICAgIGludCBpID0gYnAgLSAxOwogICAgICAgIGxvb3A6CiAgICAgICAgd2hpbGUgKGkgPiBwb3MpIHsKICAgICAgICAgICAgc3dpdGNoIChidWZbaV0pIHsKICAgICAgICAgICAgICAgIGNhc2UgJ1xmJzogY2FzZSAnXG4nOiBjYXNlICdccic6CiAgICAgICAgICAgICAgICAgICAgbmV3bGluZSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICdcdCc6IGNhc2UgJyAnOgogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICBicmVhayBsb29wOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGktLTsKICAgICAgICB9CiAgICAgICAgdGV4dFN0YXJ0ID0gLTE7CiAgICAgICAgcmV0dXJuIG0uYXQocG9zKS5uZXdFcnJvbmVvdXNUcmVlKG5ld1N0cmluZyhwb3MsIGkgKyAxKSwgZGlhZ1NvdXJjZSwgY29kZSk7CiAgICB9CgogICAgcHJvdGVjdGVkIGJvb2xlYW4gaXNJZGVudGlmaWVyU3RhcnQoY2hhciBjaCkgewogICAgICAgIHJldHVybiBDaGFyYWN0ZXIuaXNVbmljb2RlSWRlbnRpZmllclN0YXJ0KGNoKTsKICAgIH0KCiAgICBwcm90ZWN0ZWQgTmFtZSByZWFkSWRlbnRpZmllcigpIHsKICAgICAgICBpbnQgc3RhcnQgPSBicDsKICAgICAgICBuZXh0Q2hhcigpOwogICAgICAgIHdoaWxlIChicCA8IGJ1ZmxlbiAmJiBDaGFyYWN0ZXIuaXNVbmljb2RlSWRlbnRpZmllclBhcnQoY2gpKQogICAgICAgICAgICBuZXh0Q2hhcigpOwogICAgICAgIHJldHVybiBuYW1lcy5mcm9tQ2hhcnMoYnVmLCBzdGFydCwgYnAgLSBzdGFydCk7CiAgICB9CgogICAgcHJvdGVjdGVkIE5hbWUgcmVhZEF0dHJpYnV0ZU5hbWUoKSB7CiAgICAgICAgaW50IHN0YXJ0ID0gYnA7CiAgICAgICAgbmV4dENoYXIoKTsKICAgICAgICB3aGlsZSAoYnAgPCBidWZsZW4gJiYgKENoYXJhY3Rlci5pc1VuaWNvZGVJZGVudGlmaWVyUGFydChjaCkgfHwgY2ggPT0gJy0nKSkKICAgICAgICAgICAgbmV4dENoYXIoKTsKICAgICAgICByZXR1cm4gbmFtZXMuZnJvbUNoYXJzKGJ1Ziwgc3RhcnQsIGJwIC0gc3RhcnQpOwogICAgfQoKICAgIHByb3RlY3RlZCBOYW1lIHJlYWRUYWdOYW1lKCkgewogICAgICAgIGludCBzdGFydCA9IGJwOwogICAgICAgIG5leHRDaGFyKCk7CiAgICAgICAgd2hpbGUgKGJwIDwgYnVmbGVuCiAgICAgICAgICAgICAgICAmJiAoQ2hhcmFjdGVyLmlzVW5pY29kZUlkZW50aWZpZXJQYXJ0KGNoKSB8fCBjaCA9PSAnLicKICAgICAgICAgICAgICAgIHx8IGNoID09ICctJyB8fCBjaCA9PSAnOicpKSB7CiAgICAgICAgICAgIG5leHRDaGFyKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBuYW1lcy5mcm9tQ2hhcnMoYnVmLCBzdGFydCwgYnAgLSBzdGFydCk7CiAgICB9CgogICAgcHJvdGVjdGVkIGJvb2xlYW4gaXNKYXZhSWRlbnRpZmllclN0YXJ0KGNoYXIgY2gpIHsKICAgICAgICByZXR1cm4gQ2hhcmFjdGVyLmlzSmF2YUlkZW50aWZpZXJTdGFydChjaCk7CiAgICB9CgogICAgcHJvdGVjdGVkIE5hbWUgcmVhZEphdmFJZGVudGlmaWVyKCkgewogICAgICAgIGludCBzdGFydCA9IGJwOwogICAgICAgIG5leHRDaGFyKCk7CiAgICAgICAgd2hpbGUgKGJwIDwgYnVmbGVuICYmIENoYXJhY3Rlci5pc0phdmFJZGVudGlmaWVyUGFydChjaCkpCiAgICAgICAgICAgIG5leHRDaGFyKCk7CiAgICAgICAgcmV0dXJuIG5hbWVzLmZyb21DaGFycyhidWYsIHN0YXJ0LCBicCAtIHN0YXJ0KTsKICAgIH0KCiAgICBwcm90ZWN0ZWQgYm9vbGVhbiBpc0RlY2ltYWxEaWdpdChjaGFyIGNoKSB7CiAgICAgICAgcmV0dXJuICgnMCcgPD0gY2ggJiYgY2ggPD0gJzknKTsKICAgIH0KCiAgICBwcm90ZWN0ZWQgYm9vbGVhbiBpc0hleERpZ2l0KGNoYXIgY2gpIHsKICAgICAgICByZXR1cm4gKCcwJyA8PSBjaCAmJiBjaCA8PSAnOScpCiAgICAgICAgICAgICAgICB8fCAoJ2EnIDw9IGNoICYmIGNoIDw9ICdmJykKICAgICAgICAgICAgICAgIHx8ICgnQScgPD0gY2ggJiYgY2ggPD0gJ0YnKTsKICAgIH0KCiAgICBwcm90ZWN0ZWQgYm9vbGVhbiBpc1VucXVvdGVkQXR0clZhbHVlVGVybWluYXRvcihjaGFyIGNoKSB7CiAgICAgICAgc3dpdGNoIChjaCkgewogICAgICAgICAgICBjYXNlICdcZic6IGNhc2UgJ1xuJzogY2FzZSAnXHInOiBjYXNlICdcdCc6CiAgICAgICAgICAgIGNhc2UgJyAnOgogICAgICAgICAgICBjYXNlICciJzogY2FzZSAnXCcnOiBjYXNlICdgJzoKICAgICAgICAgICAgY2FzZSAnPSc6IGNhc2UgJzwnOiBjYXNlICc+JzoKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgIH0KCiAgICBwcm90ZWN0ZWQgYm9vbGVhbiBpc1doaXRlc3BhY2UoY2hhciBjaCkgewogICAgICAgIHJldHVybiBDaGFyYWN0ZXIuaXNXaGl0ZXNwYWNlKGNoKTsKICAgIH0KCiAgICBwcm90ZWN0ZWQgdm9pZCBza2lwV2hpdGVzcGFjZSgpIHsKICAgICAgICB3aGlsZSAoaXNXaGl0ZXNwYWNlKGNoKSkgewogICAgICAgICAgICBuZXh0Q2hhcigpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSBzdGFydCBwb3NpdGlvbiBvZiBmaXJzdCBjaGFyYWN0ZXIgb2Ygc3RyaW5nCiAgICAgKiBAcGFyYW0gZW5kIHBvc2l0aW9uIG9mIGNoYXJhY3RlciBiZXlvbmQgbGFzdCBjaGFyYWN0ZXIgdG8gYmUgaW5jbHVkZWQKICAgICAqLwogICAgU3RyaW5nIG5ld1N0cmluZyhpbnQgc3RhcnQsIGludCBlbmQpIHsKICAgICAgICByZXR1cm4gbmV3IFN0cmluZyhidWYsIHN0YXJ0LCBlbmQgLSBzdGFydCk7CiAgICB9CgogICAgc3RhdGljIGFic3RyYWN0IGNsYXNzIFRhZ1BhcnNlciB7CiAgICAgICAgZW51bSBLaW5kIHsgSU5MSU5FLCBCTE9DSyB9CgogICAgICAgIGZpbmFsIEtpbmQga2luZDsKICAgICAgICBmaW5hbCBEQ1RyZWUuS2luZCB0cmVlS2luZDsKICAgICAgICBmaW5hbCBib29sZWFuIHJldGFpbldoaXRlU3BhY2U7CgoKICAgICAgICBUYWdQYXJzZXIoS2luZCBrLCBEQ1RyZWUuS2luZCB0aykgewogICAgICAgICAgICBraW5kID0gazsKICAgICAgICAgICAgdHJlZUtpbmQgPSB0azsKICAgICAgICAgICAgcmV0YWluV2hpdGVTcGFjZSA9IGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgVGFnUGFyc2VyKEtpbmQgaywgRENUcmVlLktpbmQgdGssIGJvb2xlYW4gcmV0YWluV2hpdGVTcGFjZSkgewogICAgICAgICAgICBraW5kID0gazsKICAgICAgICAgICAgdHJlZUtpbmQgPSB0azsKICAgICAgICAgICAgdGhpcy5yZXRhaW5XaGl0ZVNwYWNlID0gcmV0YWluV2hpdGVTcGFjZTsKICAgICAgICB9CgogICAgICAgIEtpbmQgZ2V0S2luZCgpIHsKICAgICAgICAgICAgcmV0dXJuIGtpbmQ7CiAgICAgICAgfQoKICAgICAgICBEQ1RyZWUuS2luZCBnZXRUcmVlS2luZCgpIHsKICAgICAgICAgICAgcmV0dXJuIHRyZWVLaW5kOwogICAgICAgIH0KCiAgICAgICAgYWJzdHJhY3QgRENUcmVlIHBhcnNlKGludCBwb3MpIHRocm93cyBQYXJzZUV4Y2VwdGlvbjsKICAgIH0KCiAgICAvKioKICAgICAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL2RvY3Mub3JhY2xlLmNvbS9qYXZhc2UvNy9kb2NzL3RlY2hub3Rlcy90b29scy9zb2xhcmlzL2phdmFkb2MuaHRtbCNqYXZhZG9jdGFncyI+SmF2YWRvYyBUYWdzPC9hPgogICAgICovCiAgICBwcml2YXRlIHZvaWQgaW5pdFRhZ1BhcnNlcnMoKSB7CiAgICAgICAgVGFnUGFyc2VyW10gcGFyc2VycyA9IHsKICAgICAgICAgICAgLy8gQGF1dGhvciBuYW1lLXRleHQKICAgICAgICAgICAgbmV3IFRhZ1BhcnNlcihLaW5kLkJMT0NLLCBEQ1RyZWUuS2luZC5BVVRIT1IpIHsKICAgICAgICAgICAgICAgIHB1YmxpYyBEQ1RyZWUgcGFyc2UoaW50IHBvcykgewogICAgICAgICAgICAgICAgICAgIExpc3Q8RENUcmVlPiBuYW1lID0gYmxvY2tDb250ZW50KCk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG0uYXQocG9zKS5uZXdBdXRob3JUcmVlKG5hbWUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAoKICAgICAgICAgICAgLy8ge0Bjb2RlIHRleHR9CiAgICAgICAgICAgIG5ldyBUYWdQYXJzZXIoS2luZC5JTkxJTkUsIERDVHJlZS5LaW5kLkNPREUsIHRydWUpIHsKICAgICAgICAgICAgICAgIHB1YmxpYyBEQ1RyZWUgcGFyc2UoaW50IHBvcykgdGhyb3dzIFBhcnNlRXhjZXB0aW9uIHsKICAgICAgICAgICAgICAgICAgICBEQ1RyZWUgdGV4dCA9IGlubGluZVRleHQoV2hpdGVzcGFjZVJldGVudGlvblBvbGljeS5SRU1PVkVfRklSU1RfU1BBQ0UpOwogICAgICAgICAgICAgICAgICAgIG5leHRDaGFyKCk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG0uYXQocG9zKS5uZXdDb2RlVHJlZSgoRENUZXh0KSB0ZXh0KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIC8vIEBkZXByZWNhdGVkIGRlcHJlY2F0ZWQtdGV4dAogICAgICAgICAgICBuZXcgVGFnUGFyc2VyKEtpbmQuQkxPQ0ssIERDVHJlZS5LaW5kLkRFUFJFQ0FURUQpIHsKICAgICAgICAgICAgICAgIHB1YmxpYyBEQ1RyZWUgcGFyc2UoaW50IHBvcykgewogICAgICAgICAgICAgICAgICAgIExpc3Q8RENUcmVlPiByZWFzb24gPSBibG9ja0NvbnRlbnQoKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbS5hdChwb3MpLm5ld0RlcHJlY2F0ZWRUcmVlKHJlYXNvbik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICAvLyB7QGRvY1Jvb3R9CiAgICAgICAgICAgIG5ldyBUYWdQYXJzZXIoS2luZC5JTkxJTkUsIERDVHJlZS5LaW5kLkRPQ19ST09UKSB7CiAgICAgICAgICAgICAgICBwdWJsaWMgRENUcmVlIHBhcnNlKGludCBwb3MpIHRocm93cyBQYXJzZUV4Y2VwdGlvbiB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGNoID09ICd9JykgewogICAgICAgICAgICAgICAgICAgICAgICBuZXh0Q2hhcigpOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbS5hdChwb3MpLm5ld0RvY1Jvb3RUcmVlKCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlubGluZVRleHQoV2hpdGVzcGFjZVJldGVudGlvblBvbGljeS5SRU1PVkVfQUxMKTsgLy8gc2tpcCB1bmV4cGVjdGVkIGNvbnRlbnQKICAgICAgICAgICAgICAgICAgICBuZXh0Q2hhcigpOwogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZUV4Y2VwdGlvbigiZGMudW5leHBlY3RlZC5jb250ZW50Iik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICAvLyBAZXhjZXB0aW9uIGNsYXNzLW5hbWUgZGVzY3JpcHRpb24KICAgICAgICAgICAgbmV3IFRhZ1BhcnNlcihLaW5kLkJMT0NLLCBEQ1RyZWUuS2luZC5FWENFUFRJT04pIHsKICAgICAgICAgICAgICAgIHB1YmxpYyBEQ1RyZWUgcGFyc2UoaW50IHBvcykgdGhyb3dzIFBhcnNlRXhjZXB0aW9uIHsKICAgICAgICAgICAgICAgICAgICBza2lwV2hpdGVzcGFjZSgpOwogICAgICAgICAgICAgICAgICAgIERDUmVmZXJlbmNlIHJlZiA9IHJlZmVyZW5jZShmYWxzZSk7CiAgICAgICAgICAgICAgICAgICAgTGlzdDxEQ1RyZWU+IGRlc2NyaXB0aW9uID0gYmxvY2tDb250ZW50KCk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG0uYXQocG9zKS5uZXdFeGNlcHRpb25UcmVlKHJlZiwgZGVzY3JpcHRpb24pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAoKICAgICAgICAgICAgLy8gQGhpZGRlbiBoaWRkZW4tdGV4dAogICAgICAgICAgICBuZXcgVGFnUGFyc2VyKEtpbmQuQkxPQ0ssIERDVHJlZS5LaW5kLkhJRERFTikgewogICAgICAgICAgICAgICAgcHVibGljIERDVHJlZSBwYXJzZShpbnQgcG9zKSB7CiAgICAgICAgICAgICAgICAgICAgTGlzdDxEQ1RyZWU+IHJlYXNvbiA9IGJsb2NrQ29udGVudCgpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBtLmF0KHBvcykubmV3SGlkZGVuVHJlZShyZWFzb24pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAoKICAgICAgICAgICAgLy8gQGluZGV4IHNlYXJjaC10ZXJtIG9wdGlvbnMtZGVzY3JpcHRpb24KICAgICAgICAgICAgbmV3IFRhZ1BhcnNlcihLaW5kLklOTElORSwgRENUcmVlLktpbmQuSU5ERVgpIHsKICAgICAgICAgICAgICAgIHB1YmxpYyBEQ1RyZWUgcGFyc2UoaW50IHBvcykgdGhyb3dzIFBhcnNlRXhjZXB0aW9uIHsKICAgICAgICAgICAgICAgICAgICBza2lwV2hpdGVzcGFjZSgpOwogICAgICAgICAgICAgICAgICAgIGlmIChjaCA9PSAnfScpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlRXhjZXB0aW9uKCJkYy5uby5jb250ZW50Iik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIERDVHJlZSB0ZXJtID0gY2ggPT0gJyInID8gcXVvdGVkU3RyaW5nKCkgOiBpbmxpbmVXb3JkKCk7CiAgICAgICAgICAgICAgICAgICAgaWYgKHRlcm0gPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2VFeGNlcHRpb24oImRjLm5vLmNvbnRlbnQiKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgc2tpcFdoaXRlc3BhY2UoKTsKICAgICAgICAgICAgICAgICAgICBMaXN0PERDVHJlZT4gZGVzY3JpcHRpb24gPSBMaXN0Lm5pbCgpOwogICAgICAgICAgICAgICAgICAgIGlmIChjaCAhPSAnfScpIHsKICAgICAgICAgICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gPSBpbmxpbmVDb250ZW50KCk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgbmV4dENoYXIoKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG0uYXQocG9zKS5uZXdJbmRleFRyZWUodGVybSwgZGVzY3JpcHRpb24pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAoKICAgICAgICAgICAgLy8ge0Bpbmhlcml0RG9jfQogICAgICAgICAgICBuZXcgVGFnUGFyc2VyKEtpbmQuSU5MSU5FLCBEQ1RyZWUuS2luZC5JTkhFUklUX0RPQykgewogICAgICAgICAgICAgICAgcHVibGljIERDVHJlZSBwYXJzZShpbnQgcG9zKSB0aHJvd3MgUGFyc2VFeGNlcHRpb24gewogICAgICAgICAgICAgICAgICAgIGlmIChjaCA9PSAnfScpIHsKICAgICAgICAgICAgICAgICAgICAgICAgbmV4dENoYXIoKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG0uYXQocG9zKS5uZXdJbmhlcml0RG9jVHJlZSgpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpbmxpbmVUZXh0KFdoaXRlc3BhY2VSZXRlbnRpb25Qb2xpY3kuUkVNT1ZFX0FMTCk7IC8vIHNraXAgdW5leHBlY3RlZCBjb250ZW50CiAgICAgICAgICAgICAgICAgICAgbmV4dENoYXIoKTsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2VFeGNlcHRpb24oImRjLnVuZXhwZWN0ZWQuY29udGVudCIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAoKICAgICAgICAgICAgLy8ge0BsaW5rIHBhY2thZ2UuY2xhc3MjbWVtYmVyIGxhYmVsfQogICAgICAgICAgICBuZXcgVGFnUGFyc2VyKEtpbmQuSU5MSU5FLCBEQ1RyZWUuS2luZC5MSU5LKSB7CiAgICAgICAgICAgICAgICBwdWJsaWMgRENUcmVlIHBhcnNlKGludCBwb3MpIHRocm93cyBQYXJzZUV4Y2VwdGlvbiB7CiAgICAgICAgICAgICAgICAgICAgRENSZWZlcmVuY2UgcmVmID0gcmVmZXJlbmNlKHRydWUpOwogICAgICAgICAgICAgICAgICAgIExpc3Q8RENUcmVlPiBsYWJlbCA9IGlubGluZUNvbnRlbnQoKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbS5hdChwb3MpLm5ld0xpbmtUcmVlKHJlZiwgbGFiZWwpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAoKICAgICAgICAgICAgLy8ge0BsaW5rcGxhaW4gcGFja2FnZS5jbGFzcyNtZW1iZXIgbGFiZWx9CiAgICAgICAgICAgIG5ldyBUYWdQYXJzZXIoS2luZC5JTkxJTkUsIERDVHJlZS5LaW5kLkxJTktfUExBSU4pIHsKICAgICAgICAgICAgICAgIHB1YmxpYyBEQ1RyZWUgcGFyc2UoaW50IHBvcykgdGhyb3dzIFBhcnNlRXhjZXB0aW9uIHsKICAgICAgICAgICAgICAgICAgICBEQ1JlZmVyZW5jZSByZWYgPSByZWZlcmVuY2UodHJ1ZSk7CiAgICAgICAgICAgICAgICAgICAgTGlzdDxEQ1RyZWU+IGxhYmVsID0gaW5saW5lQ29udGVudCgpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBtLmF0KHBvcykubmV3TGlua1BsYWluVHJlZShyZWYsIGxhYmVsKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIC8vIHtAbGl0ZXJhbCB0ZXh0fQogICAgICAgICAgICBuZXcgVGFnUGFyc2VyKEtpbmQuSU5MSU5FLCBEQ1RyZWUuS2luZC5MSVRFUkFMLCB0cnVlKSB7CiAgICAgICAgICAgICAgICBwdWJsaWMgRENUcmVlIHBhcnNlKGludCBwb3MpIHRocm93cyBQYXJzZUV4Y2VwdGlvbiB7CiAgICAgICAgICAgICAgICAgICAgRENUcmVlIHRleHQgPSBpbmxpbmVUZXh0KFdoaXRlc3BhY2VSZXRlbnRpb25Qb2xpY3kuUkVNT1ZFX0ZJUlNUX1NQQUNFKTsKICAgICAgICAgICAgICAgICAgICBuZXh0Q2hhcigpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBtLmF0KHBvcykubmV3TGl0ZXJhbFRyZWUoKERDVGV4dCkgdGV4dCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICAvLyBAcGFyYW0gcGFyYW1ldGVyLW5hbWUgZGVzY3JpcHRpb24KICAgICAgICAgICAgbmV3IFRhZ1BhcnNlcihLaW5kLkJMT0NLLCBEQ1RyZWUuS2luZC5QQVJBTSkgewogICAgICAgICAgICAgICAgcHVibGljIERDVHJlZSBwYXJzZShpbnQgcG9zKSB0aHJvd3MgUGFyc2VFeGNlcHRpb24gewogICAgICAgICAgICAgICAgICAgIHNraXBXaGl0ZXNwYWNlKCk7CgogICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gdHlwYXJhbSA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgIGlmIChjaCA9PSAnPCcpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdHlwYXJhbSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIG5leHRDaGFyKCk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBEQ0lkZW50aWZpZXIgaWQgPSBpZGVudGlmaWVyKCk7CgogICAgICAgICAgICAgICAgICAgIGlmICh0eXBhcmFtKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjaCAhPSAnPicpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2VFeGNlcHRpb24oImRjLmd0LmV4cGVjdGVkIik7CiAgICAgICAgICAgICAgICAgICAgICAgIG5leHRDaGFyKCk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBza2lwV2hpdGVzcGFjZSgpOwogICAgICAgICAgICAgICAgICAgIExpc3Q8RENUcmVlPiBkZXNjID0gYmxvY2tDb250ZW50KCk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG0uYXQocG9zKS5uZXdQYXJhbVRyZWUodHlwYXJhbSwgaWQsIGRlc2MpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAoKICAgICAgICAgICAgLy8gQHByb3ZpZGVzIHNlcnZpY2UtbmFtZSBkZXNjcmlwdGlvbgogICAgICAgICAgICBuZXcgVGFnUGFyc2VyKEtpbmQuQkxPQ0ssIERDVHJlZS5LaW5kLlBST1ZJREVTKSB7CiAgICAgICAgICAgICAgICBwdWJsaWMgRENUcmVlIHBhcnNlKGludCBwb3MpIHRocm93cyBQYXJzZUV4Y2VwdGlvbiB7CiAgICAgICAgICAgICAgICAgICAgc2tpcFdoaXRlc3BhY2UoKTsKICAgICAgICAgICAgICAgICAgICBEQ1JlZmVyZW5jZSByZWYgPSByZWZlcmVuY2UodHJ1ZSk7CiAgICAgICAgICAgICAgICAgICAgTGlzdDxEQ1RyZWU+IGRlc2NyaXB0aW9uID0gYmxvY2tDb250ZW50KCk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG0uYXQocG9zKS5uZXdQcm92aWRlc1RyZWUocmVmLCBkZXNjcmlwdGlvbik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICAvLyBAcmV0dXJuIGRlc2NyaXB0aW9uCiAgICAgICAgICAgIG5ldyBUYWdQYXJzZXIoS2luZC5CTE9DSywgRENUcmVlLktpbmQuUkVUVVJOKSB7CiAgICAgICAgICAgICAgICBwdWJsaWMgRENUcmVlIHBhcnNlKGludCBwb3MpIHsKICAgICAgICAgICAgICAgICAgICBMaXN0PERDVHJlZT4gZGVzY3JpcHRpb24gPSBibG9ja0NvbnRlbnQoKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbS5hdChwb3MpLm5ld1JldHVyblRyZWUoZGVzY3JpcHRpb24pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAoKICAgICAgICAgICAgLy8gQHNlZSByZWZlcmVuY2UgfCBxdW90ZWQtc3RyaW5nIHwgSFRNTAogICAgICAgICAgICBuZXcgVGFnUGFyc2VyKEtpbmQuQkxPQ0ssIERDVHJlZS5LaW5kLlNFRSkgewogICAgICAgICAgICAgICAgcHVibGljIERDVHJlZSBwYXJzZShpbnQgcG9zKSB0aHJvd3MgUGFyc2VFeGNlcHRpb24gewogICAgICAgICAgICAgICAgICAgIHNraXBXaGl0ZXNwYWNlKCk7CiAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChjaCkgewogICAgICAgICAgICAgICAgICAgICAgICBjYXNlICciJzoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIERDVGV4dCBzdHJpbmcgPSBxdW90ZWRTdHJpbmcoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdHJpbmcgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNraXBXaGl0ZXNwYWNlKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNoID09ICdAJwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgY2ggPT0gRU9JICYmIGJwID09IGJ1Zi5sZW5ndGggLSAxKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBtLmF0KHBvcykubmV3U2VlVHJlZShMaXN0LjxEQ1RyZWU+b2Yoc3RyaW5nKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgICAgICAgICBjYXNlICc8JzoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIExpc3Q8RENUcmVlPiBodG1sID0gYmxvY2tDb250ZW50KCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaHRtbCAhPSBudWxsKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBtLmF0KHBvcykubmV3U2VlVHJlZShodG1sKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnQCc6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobmV3bGluZSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2VFeGNlcHRpb24oImRjLm5vLmNvbnRlbnQiKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBFT0k6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYnAgPT0gYnVmLmxlbmd0aCAtIDEpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlRXhjZXB0aW9uKCJkYy5uby5jb250ZW50Iik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNKYXZhSWRlbnRpZmllclN0YXJ0KGNoKSB8fCBjaCA9PSAnIycpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEQ1JlZmVyZW5jZSByZWYgPSByZWZlcmVuY2UodHJ1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTGlzdDxEQ1RyZWU+IGRlc2NyaXB0aW9uID0gYmxvY2tDb250ZW50KCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG0uYXQocG9zKS5uZXdTZWVUcmVlKGRlc2NyaXB0aW9uLnByZXBlbmQocmVmKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZUV4Y2VwdGlvbigiZGMudW5leHBlY3RlZC5jb250ZW50Iik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICAvLyBAc2VyaWFsRGF0YSBkYXRhLWRlc2NyaXB0aW9uCiAgICAgICAgICAgIG5ldyBUYWdQYXJzZXIoS2luZC5CTE9DSywgRENUcmVlLktpbmQuU0VSSUFMX0RBVEEpIHsKICAgICAgICAgICAgICAgIHB1YmxpYyBEQ1RyZWUgcGFyc2UoaW50IHBvcykgewogICAgICAgICAgICAgICAgICAgIExpc3Q8RENUcmVlPiBkZXNjcmlwdGlvbiA9IGJsb2NrQ29udGVudCgpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBtLmF0KHBvcykubmV3U2VyaWFsRGF0YVRyZWUoZGVzY3JpcHRpb24pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAoKICAgICAgICAgICAgLy8gQHNlcmlhbEZpZWxkIGZpZWxkLW5hbWUgZmllbGQtdHlwZSBkZXNjcmlwdGlvbgogICAgICAgICAgICBuZXcgVGFnUGFyc2VyKEtpbmQuQkxPQ0ssIERDVHJlZS5LaW5kLlNFUklBTF9GSUVMRCkgewogICAgICAgICAgICAgICAgcHVibGljIERDVHJlZSBwYXJzZShpbnQgcG9zKSB0aHJvd3MgUGFyc2VFeGNlcHRpb24gewogICAgICAgICAgICAgICAgICAgIHNraXBXaGl0ZXNwYWNlKCk7CiAgICAgICAgICAgICAgICAgICAgRENJZGVudGlmaWVyIG5hbWUgPSBpZGVudGlmaWVyKCk7CiAgICAgICAgICAgICAgICAgICAgc2tpcFdoaXRlc3BhY2UoKTsKICAgICAgICAgICAgICAgICAgICBEQ1JlZmVyZW5jZSB0eXBlID0gcmVmZXJlbmNlKGZhbHNlKTsKICAgICAgICAgICAgICAgICAgICBMaXN0PERDVHJlZT4gZGVzY3JpcHRpb24gPSBudWxsOwogICAgICAgICAgICAgICAgICAgIGlmIChpc1doaXRlc3BhY2UoY2gpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHNraXBXaGl0ZXNwYWNlKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uID0gYmxvY2tDb250ZW50KCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHJldHVybiBtLmF0KHBvcykubmV3U2VyaWFsRmllbGRUcmVlKG5hbWUsIHR5cGUsIGRlc2NyaXB0aW9uKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIC8vIEBzZXJpYWwgZmllbGQtZGVzY3JpcHRpb24gfCBpbmNsdWRlIHwgZXhjbHVkZQogICAgICAgICAgICBuZXcgVGFnUGFyc2VyKEtpbmQuQkxPQ0ssIERDVHJlZS5LaW5kLlNFUklBTCkgewogICAgICAgICAgICAgICAgcHVibGljIERDVHJlZSBwYXJzZShpbnQgcG9zKSB7CiAgICAgICAgICAgICAgICAgICAgTGlzdDxEQ1RyZWU+IGRlc2NyaXB0aW9uID0gYmxvY2tDb250ZW50KCk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG0uYXQocG9zKS5uZXdTZXJpYWxUcmVlKGRlc2NyaXB0aW9uKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIC8vIEBzaW5jZSBzaW5jZS10ZXh0CiAgICAgICAgICAgIG5ldyBUYWdQYXJzZXIoS2luZC5CTE9DSywgRENUcmVlLktpbmQuU0lOQ0UpIHsKICAgICAgICAgICAgICAgIHB1YmxpYyBEQ1RyZWUgcGFyc2UoaW50IHBvcykgewogICAgICAgICAgICAgICAgICAgIExpc3Q8RENUcmVlPiBkZXNjcmlwdGlvbiA9IGJsb2NrQ29udGVudCgpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBtLmF0KHBvcykubmV3U2luY2VUcmVlKGRlc2NyaXB0aW9uKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIC8vIEB0aHJvd3MgY2xhc3MtbmFtZSBkZXNjcmlwdGlvbgogICAgICAgICAgICBuZXcgVGFnUGFyc2VyKEtpbmQuQkxPQ0ssIERDVHJlZS5LaW5kLlRIUk9XUykgewogICAgICAgICAgICAgICAgcHVibGljIERDVHJlZSBwYXJzZShpbnQgcG9zKSB0aHJvd3MgUGFyc2VFeGNlcHRpb24gewogICAgICAgICAgICAgICAgICAgIHNraXBXaGl0ZXNwYWNlKCk7CiAgICAgICAgICAgICAgICAgICAgRENSZWZlcmVuY2UgcmVmID0gcmVmZXJlbmNlKGZhbHNlKTsKICAgICAgICAgICAgICAgICAgICBMaXN0PERDVHJlZT4gZGVzY3JpcHRpb24gPSBibG9ja0NvbnRlbnQoKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbS5hdChwb3MpLm5ld1Rocm93c1RyZWUocmVmLCBkZXNjcmlwdGlvbik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICAvLyBAdXNlcyBzZXJ2aWNlLW5hbWUgZGVzY3JpcHRpb24KICAgICAgICAgICAgbmV3IFRhZ1BhcnNlcihLaW5kLkJMT0NLLCBEQ1RyZWUuS2luZC5VU0VTKSB7CiAgICAgICAgICAgICAgICBwdWJsaWMgRENUcmVlIHBhcnNlKGludCBwb3MpIHRocm93cyBQYXJzZUV4Y2VwdGlvbiB7CiAgICAgICAgICAgICAgICAgICAgc2tpcFdoaXRlc3BhY2UoKTsKICAgICAgICAgICAgICAgICAgICBEQ1JlZmVyZW5jZSByZWYgPSByZWZlcmVuY2UodHJ1ZSk7CiAgICAgICAgICAgICAgICAgICAgTGlzdDxEQ1RyZWU+IGRlc2NyaXB0aW9uID0gYmxvY2tDb250ZW50KCk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG0uYXQocG9zKS5uZXdVc2VzVHJlZShyZWYsIGRlc2NyaXB0aW9uKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIC8vIHtAdmFsdWUgcGFja2FnZS5jbGFzcyNmaWVsZH0KICAgICAgICAgICAgbmV3IFRhZ1BhcnNlcihLaW5kLklOTElORSwgRENUcmVlLktpbmQuVkFMVUUpIHsKICAgICAgICAgICAgICAgIHB1YmxpYyBEQ1RyZWUgcGFyc2UoaW50IHBvcykgdGhyb3dzIFBhcnNlRXhjZXB0aW9uIHsKICAgICAgICAgICAgICAgICAgICBEQ1JlZmVyZW5jZSByZWYgPSByZWZlcmVuY2UodHJ1ZSk7CiAgICAgICAgICAgICAgICAgICAgc2tpcFdoaXRlc3BhY2UoKTsKICAgICAgICAgICAgICAgICAgICBpZiAoY2ggPT0gJ30nKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIG5leHRDaGFyKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBtLmF0KHBvcykubmV3VmFsdWVUcmVlKHJlZik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIG5leHRDaGFyKCk7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlRXhjZXB0aW9uKCJkYy51bmV4cGVjdGVkLmNvbnRlbnQiKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIC8vIEB2ZXJzaW9uIHZlcnNpb24tdGV4dAogICAgICAgICAgICBuZXcgVGFnUGFyc2VyKEtpbmQuQkxPQ0ssIERDVHJlZS5LaW5kLlZFUlNJT04pIHsKICAgICAgICAgICAgICAgIHB1YmxpYyBEQ1RyZWUgcGFyc2UoaW50IHBvcykgewogICAgICAgICAgICAgICAgICAgIExpc3Q8RENUcmVlPiBkZXNjcmlwdGlvbiA9IGJsb2NrQ29udGVudCgpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBtLmF0KHBvcykubmV3VmVyc2lvblRyZWUoZGVzY3JpcHRpb24pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAogICAgICAgIH07CgogICAgICAgIHRhZ1BhcnNlcnMgPSBuZXcgSGFzaE1hcDw+KCk7CiAgICAgICAgZm9yIChUYWdQYXJzZXIgcDogcGFyc2VycykKICAgICAgICAgICAgdGFnUGFyc2Vycy5wdXQobmFtZXMuZnJvbVN0cmluZyhwLmdldFRyZWVLaW5kKCkudGFnTmFtZSksIHApOwoKICAgIH0KfQpQSwMECgAACAAA0n1NSosWDyGhEAAAoRAAACcAAABjb20vc3VuL3Rvb2xzL2phdmFjL3BhcnNlci9TY2FubmVyLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDE5OTksIDIwMTMsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhYy5wYXJzZXI7CgppbXBvcnQgamF2YS5uaW8uKjsKaW1wb3J0IGphdmEudXRpbC5MaXN0OwppbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKCmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuUG9zaXRpb24uTGluZU1hcDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMucGFyc2VyLkphdmFUb2tlbml6ZXIuKjsKCmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5wYXJzZXIuVG9rZW5zLio7CgovKiogVGhlIGxleGljYWwgYW5hbHl6ZXIgbWFwcyBhbiBpbnB1dCBzdHJlYW0gY29uc2lzdGluZyBvZgogKiAgQVNDSUkgY2hhcmFjdGVycyBhbmQgVW5pY29kZSBlc2NhcGVzIGludG8gYSB0b2tlbiBzZXF1ZW5jZS4KICoKICogIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqICBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqICBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogKiAgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPgogKi8KcHVibGljIGNsYXNzIFNjYW5uZXIgaW1wbGVtZW50cyBMZXhlciB7CgogICAgcHJpdmF0ZSBUb2tlbnMgdG9rZW5zOwoKICAgIC8qKiBUaGUgdG9rZW4sIHNldCBieSBuZXh0VG9rZW4oKS4KICAgICAqLwogICAgcHJpdmF0ZSBUb2tlbiB0b2tlbjsKCiAgICAvKiogVGhlIHByZXZpb3VzIHRva2VuLCBzZXQgYnkgbmV4dFRva2VuKCkuCiAgICAgKi8KICAgIHByaXZhdGUgVG9rZW4gcHJldlRva2VuOwoKICAgIC8qKiBCdWZmZXIgb2Ygc2F2ZWQgdG9rZW5zICh1c2VkIGR1cmluZyBsb29rYWhlYWQpCiAgICAgKi8KICAgIHByaXZhdGUgTGlzdDxUb2tlbj4gc2F2ZWRUb2tlbnMgPSBuZXcgQXJyYXlMaXN0PD4oKTsKCiAgICBwcml2YXRlIEphdmFUb2tlbml6ZXIgdG9rZW5pemVyOwoKICAgIC8qKgogICAgICogQ3JlYXRlIGEgc2Nhbm5lciBmcm9tIHRoZSBpbnB1dCBhcnJheS4gIFRoaXMgbWV0aG9kIG1pZ2h0CiAgICAgKiBtb2RpZnkgdGhlIGFycmF5LiAgVG8gYXZvaWQgY29weWluZyB0aGUgaW5wdXQgYXJyYXksIGVuc3VyZQogICAgICogdGhhdCB7QGNvZGUgaW5wdXRMZW5ndGggPCBpbnB1dC5sZW5ndGh9IG9yCiAgICAgKiB7QGNvZGUgaW5wdXRbaW5wdXQubGVuZ3RoIC0xXX0gaXMgYSB3aGl0ZSBzcGFjZSBjaGFyYWN0ZXIuCiAgICAgKgogICAgICogQHBhcmFtIGZhYyB0aGUgZmFjdG9yeSB3aGljaCBjcmVhdGVkIHRoaXMgU2Nhbm5lcgogICAgICogQHBhcmFtIGJ1ZiB0aGUgaW5wdXQsIG1pZ2h0IGJlIG1vZGlmaWVkCiAgICAgKiBNdXN0IGJlIHBvc2l0aXZlIGFuZCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gaW5wdXQubGVuZ3RoLgogICAgICovCiAgICBwcm90ZWN0ZWQgU2Nhbm5lcihTY2FubmVyRmFjdG9yeSBmYWMsIENoYXJCdWZmZXIgYnVmKSB7CiAgICAgICAgdGhpcyhmYWMsIG5ldyBKYXZhVG9rZW5pemVyKGZhYywgYnVmKSk7CiAgICB9CgogICAgcHJvdGVjdGVkIFNjYW5uZXIoU2Nhbm5lckZhY3RvcnkgZmFjLCBjaGFyW10gYnVmLCBpbnQgaW5wdXRMZW5ndGgpIHsKICAgICAgICB0aGlzKGZhYywgbmV3IEphdmFUb2tlbml6ZXIoZmFjLCBidWYsIGlucHV0TGVuZ3RoKSk7CiAgICB9CgogICAgcHJvdGVjdGVkIFNjYW5uZXIoU2Nhbm5lckZhY3RvcnkgZmFjLCBKYXZhVG9rZW5pemVyIHRva2VuaXplcikgewogICAgICAgIHRoaXMudG9rZW5pemVyID0gdG9rZW5pemVyOwogICAgICAgIHRva2VucyA9IGZhYy50b2tlbnM7CiAgICAgICAgdG9rZW4gPSBwcmV2VG9rZW4gPSBEVU1NWTsKICAgIH0KCiAgICBwdWJsaWMgVG9rZW4gdG9rZW4oKSB7CiAgICAgICAgcmV0dXJuIHRva2VuKDApOwogICAgfQoKICAgIHB1YmxpYyBUb2tlbiB0b2tlbihpbnQgbG9va2FoZWFkKSB7CiAgICAgICAgaWYgKGxvb2thaGVhZCA9PSAwKSB7CiAgICAgICAgICAgIHJldHVybiB0b2tlbjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVMb29rYWhlYWQobG9va2FoZWFkKTsKICAgICAgICAgICAgcmV0dXJuIHNhdmVkVG9rZW5zLmdldChsb29rYWhlYWQgLSAxKTsKICAgICAgICB9CiAgICB9CiAgICAvL3doZXJlCiAgICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZUxvb2thaGVhZChpbnQgbG9va2FoZWFkKSB7CiAgICAgICAgICAgIGZvciAoaW50IGkgPSBzYXZlZFRva2Vucy5zaXplKCkgOyBpIDwgbG9va2FoZWFkIDsgaSArKykgewogICAgICAgICAgICAgICAgc2F2ZWRUb2tlbnMuYWRkKHRva2VuaXplci5yZWFkVG9rZW4oKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgcHVibGljIFRva2VuIHByZXZUb2tlbigpIHsKICAgICAgICByZXR1cm4gcHJldlRva2VuOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIG5leHRUb2tlbigpIHsKICAgICAgICBwcmV2VG9rZW4gPSB0b2tlbjsKICAgICAgICBpZiAoIXNhdmVkVG9rZW5zLmlzRW1wdHkoKSkgewogICAgICAgICAgICB0b2tlbiA9IHNhdmVkVG9rZW5zLnJlbW92ZSgwKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB0b2tlbiA9IHRva2VuaXplci5yZWFkVG9rZW4oKTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIFRva2VuIHNwbGl0KCkgewogICAgICAgIFRva2VuW10gc3BsaXRUb2tlbnMgPSB0b2tlbi5zcGxpdCh0b2tlbnMpOwogICAgICAgIHByZXZUb2tlbiA9IHNwbGl0VG9rZW5zWzBdOwogICAgICAgIHRva2VuID0gc3BsaXRUb2tlbnNbMV07CiAgICAgICAgcmV0dXJuIHRva2VuOwogICAgfQoKICAgIHB1YmxpYyBMaW5lTWFwIGdldExpbmVNYXAoKSB7CiAgICAgICAgcmV0dXJuIHRva2VuaXplci5nZXRMaW5lTWFwKCk7CiAgICB9CgogICAgcHVibGljIGludCBlcnJQb3MoKSB7CiAgICAgICAgcmV0dXJuIHRva2VuaXplci5lcnJQb3MoKTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCBlcnJQb3MoaW50IHBvcykgewogICAgICAgIHRva2VuaXplci5lcnJQb3MocG9zKTsKICAgIH0KfQpQSwMECgAACAAABjupSq8OvUN2GQAAdhkAAC8AAABjb20vc3VuL3Rvb2xzL2phdmFjL3BhcnNlci9SZWZlcmVuY2VQYXJzZXIuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAxMiwgMjAxNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLmphdmFjLnBhcnNlcjsKCmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnBhcnNlci5Ub2tlbnMuVG9rZW5LaW5kOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkpDVHJlZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5MaXN0OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkxpc3RCdWZmZXI7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuTG9nOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLk5hbWU7CgovKioKICogIEEgdXRpbGl0eSBjbGFzcyB0byBwYXJzZSBhIHN0cmluZyBpbiBhIGRvYyBjb21tZW50IGNvbnRhaW5pbmcgYQogKiAgcmVmZXJlbmNlIHRvIGFuIEFQSSBlbGVtZW50LCBzdWNoIGFzIGEgdHlwZSwgZmllbGQgb3IgbWV0aG9kLgogKgogKiAgPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24gcmlzay4KICogIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yCiAqICBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+CiAqLwpwdWJsaWMgY2xhc3MgUmVmZXJlbmNlUGFyc2VyIHsKICAgIC8qKgogICAgICogQW4gb2JqZWN0IHRvIGNvbnRhaW4gdGhlIHJlc3VsdCBvZiBwYXJzaW5nIGEgcmVmZXJlbmNlIHRvIGFuIEFQSSBlbGVtZW50LgogICAgICogQW55LCBidXQgbm90IGFsbCwgb2YgdGhlIG1lbWJlciBmaWVsZHMgbWF5IGJlIG51bGwuCiAgICAgKi8KICAgIHN0YXRpYyBwdWJsaWMgY2xhc3MgUmVmZXJlbmNlIHsKICAgICAgICAvKiogVGhlIHR5cGUsIGlmIGFueSwgaW4gdGhlIHNpZ25hdHVyZS4gKi8KICAgICAgICBwdWJsaWMgZmluYWwgSkNUcmVlIHF1YWxFeHByOwogICAgICAgIC8qKiBUaGUgbWVtYmVyIG5hbWUsIGlmIGFueSwgaW4gdGhlIHNpZ25hdHVyZS4gKi8KICAgICAgICBwdWJsaWMgZmluYWwgTmFtZSBtZW1iZXI7CiAgICAgICAgLyoqIFRoZSBwYXJhbWV0ZXIgdHlwZXMsIGlmIGFueSwgaW4gdGhlIHNpZ25hdHVyZS4gKi8KICAgICAgICBwdWJsaWMgZmluYWwgTGlzdDxKQ1RyZWU+IHBhcmFtVHlwZXM7CgogICAgICAgIFJlZmVyZW5jZShKQ1RyZWUgcXVhbEV4cHIsIE5hbWUgbWVtYmVyLCBMaXN0PEpDVHJlZT4gcGFyYW1UeXBlcykgewogICAgICAgICAgICB0aGlzLnF1YWxFeHByID0gcXVhbEV4cHI7CiAgICAgICAgICAgIHRoaXMubWVtYmVyID0gbWVtYmVyOwogICAgICAgICAgICB0aGlzLnBhcmFtVHlwZXMgPSBwYXJhbVR5cGVzOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEFuIGV4Y2VwdGlvbiB0aGF0IGluZGljYXRlcyBhbiBlcnJvciBvY2N1cnJlZCB3aGlsZSBwYXJzaW5nIGEgc2lnbmF0dXJlLgogICAgICovCiAgICBzdGF0aWMgcHVibGljIGNsYXNzIFBhcnNlRXhjZXB0aW9uIGV4dGVuZHMgRXhjZXB0aW9uIHsKICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwOwogICAgICAgIFBhcnNlRXhjZXB0aW9uKFN0cmluZyBtZXNzYWdlKSB7CiAgICAgICAgICAgIHN1cGVyKG1lc3NhZ2UpOwogICAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIGZpbmFsIFBhcnNlckZhY3RvcnkgZmFjOwoKICAgIC8qKgogICAgICogQ3JlYXRlIGEgcGFyc2VyIG9iamVjdCB0byBwYXJzZSByZWZlcmVuY2Ugc2lnbmF0dXJlcy4KICAgICAqIEBwYXJhbSBmYWMgYSBmYWN0b3J5IGZvciBwYXJzaW5nIEphdmEgc291cmNlIGNvZGUuCiAgICAgKi8KICAgIHB1YmxpYyBSZWZlcmVuY2VQYXJzZXIoUGFyc2VyRmFjdG9yeSBmYWMpIHsKICAgICAgICB0aGlzLmZhYyA9IGZhYzsKICAgIH0KCiAgICAvKioKICAgICAqIFBhcnNlIGEgcmVmZXJlbmNlIHRvIGFuIEFQSSBlbGVtZW50IGFzIG1heSBiZSBmb3VuZCBpbiBkb2MgY29tbWVudC4KICAgICAqIEBwYXJhbSBzaWcgdGhlIHNpZ25hdHVyZSB0byBiZSBwYXJzZWQKICAgICAqIEByZXR1cm4gYSB7QGNvZGUgUmVmZXJlbmNlfSBvYmplY3QgY29udGFpbmluZyB0aGUgcmVzdWx0IG9mIHBhcnNpbmcgdGhlIHNpZ25hdHVyZQogICAgICogQHRocm93cyBQYXJzZUV4Y2VwdGlvbiBpZiB0aGVyZSBpcyBhbiBlcnJvciB3aGlsZSBwYXJzaW5nIHRoZSBzaWduYXR1cmUKICAgICAqLwogICAgcHVibGljIFJlZmVyZW5jZSBwYXJzZShTdHJpbmcgc2lnKSB0aHJvd3MgUGFyc2VFeGNlcHRpb24gewoKICAgICAgICAvLyBCcmVhayBzaWcgYXBhcnQgaW50byBxdWFsaWZpZWRFeHByIG1lbWJlciBwYXJhbVR5cGVzLgogICAgICAgIEpDVHJlZSBxdWFsRXhwcjsKICAgICAgICBOYW1lIG1lbWJlcjsKICAgICAgICBMaXN0PEpDVHJlZT4gcGFyYW1UeXBlczsKCiAgICAgICAgTG9nLkRlZmVycmVkRGlhZ25vc3RpY0hhbmRsZXIgZGVmZXJyZWREaWFnbm9zdGljSGFuZGxlcgogICAgICAgICAgICAgICAgPSBuZXcgTG9nLkRlZmVycmVkRGlhZ25vc3RpY0hhbmRsZXIoZmFjLmxvZyk7CgogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGludCBoYXNoID0gc2lnLmluZGV4T2YoIiMiKTsKICAgICAgICAgICAgaW50IGxwYXJlbiA9IHNpZy5pbmRleE9mKCIoIiwgaGFzaCArIDEpOwogICAgICAgICAgICBpZiAoaGFzaCA9PSAtMSkgewogICAgICAgICAgICAgICAgaWYgKGxwYXJlbiA9PSAtMSkgewogICAgICAgICAgICAgICAgICAgIHF1YWxFeHByID0gcGFyc2VUeXBlKHNpZyk7CiAgICAgICAgICAgICAgICAgICAgbWVtYmVyID0gbnVsbDsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgcXVhbEV4cHIgPSBudWxsOwogICAgICAgICAgICAgICAgICAgIG1lbWJlciA9IHBhcnNlTWVtYmVyKHNpZy5zdWJzdHJpbmcoMCwgbHBhcmVuKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBxdWFsRXhwciA9IChoYXNoID09IDApID8gbnVsbCA6IHBhcnNlVHlwZShzaWcuc3Vic3RyaW5nKDAsIGhhc2gpKTsKICAgICAgICAgICAgICAgIGlmIChscGFyZW4gPT0gLTEpCiAgICAgICAgICAgICAgICAgICAgbWVtYmVyID0gcGFyc2VNZW1iZXIoc2lnLnN1YnN0cmluZyhoYXNoICsgMSkpOwogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIG1lbWJlciA9IHBhcnNlTWVtYmVyKHNpZy5zdWJzdHJpbmcoaGFzaCArIDEsIGxwYXJlbikpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAobHBhcmVuIDwgMCkgewogICAgICAgICAgICAgICAgcGFyYW1UeXBlcyA9IG51bGw7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBpbnQgcnBhcmVuID0gc2lnLmluZGV4T2YoIikiLCBscGFyZW4pOwogICAgICAgICAgICAgICAgaWYgKHJwYXJlbiAhPSBzaWcubGVuZ3RoKCkgLSAxKQogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZUV4Y2VwdGlvbigiZGMucmVmLmJhZC5wYXJlbnMiKTsKICAgICAgICAgICAgICAgIHBhcmFtVHlwZXMgPSBwYXJzZVBhcmFtcyhzaWcuc3Vic3RyaW5nKGxwYXJlbiArIDEsIHJwYXJlbikpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoIWRlZmVycmVkRGlhZ25vc3RpY0hhbmRsZXIuZ2V0RGlhZ25vc3RpY3MoKS5pc0VtcHR5KCkpCiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2VFeGNlcHRpb24oImRjLnJlZi5zeW50YXguZXJyb3IiKTsKCiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgZmFjLmxvZy5wb3BEaWFnbm9zdGljSGFuZGxlcihkZWZlcnJlZERpYWdub3N0aWNIYW5kbGVyKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBuZXcgUmVmZXJlbmNlKHF1YWxFeHByLCBtZW1iZXIsIHBhcmFtVHlwZXMpOwogICAgfQoKICAgIHByaXZhdGUgSkNUcmVlIHBhcnNlVHlwZShTdHJpbmcgcykgdGhyb3dzIFBhcnNlRXhjZXB0aW9uIHsKICAgICAgICBKYXZhY1BhcnNlciBwID0gZmFjLm5ld1BhcnNlcihzLCBmYWxzZSwgZmFsc2UsIGZhbHNlKTsKICAgICAgICBKQ1RyZWUgdHJlZSA9IHAucGFyc2VUeXBlKCk7CiAgICAgICAgaWYgKHAudG9rZW4oKS5raW5kICE9IFRva2VuS2luZC5FT0YpCiAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZUV4Y2VwdGlvbigiZGMucmVmLnVuZXhwZWN0ZWQuaW5wdXQiKTsKICAgICAgICByZXR1cm4gdHJlZTsKICAgIH0KCiAgICBwcml2YXRlIE5hbWUgcGFyc2VNZW1iZXIoU3RyaW5nIHMpIHRocm93cyBQYXJzZUV4Y2VwdGlvbiB7CiAgICAgICAgSmF2YWNQYXJzZXIgcCA9IGZhYy5uZXdQYXJzZXIocywgZmFsc2UsIGZhbHNlLCBmYWxzZSk7CiAgICAgICAgTmFtZSBuYW1lID0gcC5pZGVudCgpOwogICAgICAgIGlmIChwLnRva2VuKCkua2luZCAhPSBUb2tlbktpbmQuRU9GKQogICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2VFeGNlcHRpb24oImRjLnJlZi51bmV4cGVjdGVkLmlucHV0Iik7CiAgICAgICAgcmV0dXJuIG5hbWU7CiAgICB9CgogICAgcHJpdmF0ZSBMaXN0PEpDVHJlZT4gcGFyc2VQYXJhbXMoU3RyaW5nIHMpIHRocm93cyBQYXJzZUV4Y2VwdGlvbiB7CiAgICAgICAgaWYgKHMudHJpbSgpLmlzRW1wdHkoKSkKICAgICAgICAgICAgcmV0dXJuIExpc3QubmlsKCk7CgogICAgICAgIEphdmFjUGFyc2VyIHAgPSBmYWMubmV3UGFyc2VyKHMucmVwbGFjZSgiLi4uIiwgIltdIiksIGZhbHNlLCBmYWxzZSwgZmFsc2UpOwogICAgICAgIExpc3RCdWZmZXI8SkNUcmVlPiBwYXJhbVR5cGVzID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgIHBhcmFtVHlwZXMuYWRkKHAucGFyc2VUeXBlKCkpOwoKICAgICAgICBpZiAocC50b2tlbigpLmtpbmQgPT0gVG9rZW5LaW5kLklERU5USUZJRVIpCiAgICAgICAgICAgIHAubmV4dFRva2VuKCk7CgogICAgICAgIHdoaWxlIChwLnRva2VuKCkua2luZCA9PSBUb2tlbktpbmQuQ09NTUEpIHsKICAgICAgICAgICAgcC5uZXh0VG9rZW4oKTsKICAgICAgICAgICAgcGFyYW1UeXBlcy5hZGQocC5wYXJzZVR5cGUoKSk7CgogICAgICAgICAgICBpZiAocC50b2tlbigpLmtpbmQgPT0gVG9rZW5LaW5kLklERU5USUZJRVIpCiAgICAgICAgICAgICAgICBwLm5leHRUb2tlbigpOwogICAgICAgIH0KCiAgICAgICAgaWYgKHAudG9rZW4oKS5raW5kICE9IFRva2VuS2luZC5FT0YpCiAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZUV4Y2VwdGlvbigiZGMucmVmLnVuZXhwZWN0ZWQuaW5wdXQiKTsKCiAgICAgICAgcmV0dXJuIHBhcmFtVHlwZXMudG9MaXN0KCk7CiAgICB9Cn0KUEsDBAoAAAgAAAY7qUr5nm3XO4cAADuHAAAtAAAAY29tL3N1bi90b29scy9qYXZhYy9wYXJzZXIvSmF2YVRva2VuaXplci5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAxOTk5LCAyMDE2LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuamF2YWMucGFyc2VyOwoKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5Tb3VyY2U7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnBhcnNlci5Ub2tlbnMuQ29tbWVudC5Db21tZW50U3R5bGU7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuKjsKCmltcG9ydCBqYXZhLm5pby5DaGFyQnVmZmVyOwoKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLnBhcnNlci5Ub2tlbnMuKjsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuTGF5b3V0Q2hhcmFjdGVycy4qOwoKLyoqIFRoZSBsZXhpY2FsIGFuYWx5emVyIG1hcHMgYW4gaW5wdXQgc3RyZWFtIGNvbnNpc3Rpbmcgb2YKICogIEFTQ0lJIGNoYXJhY3RlcnMgYW5kIFVuaWNvZGUgZXNjYXBlcyBpbnRvIGEgdG9rZW4gc2VxdWVuY2UuCiAqCiAqICA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiAgSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93biByaXNrLgogKiAgVGhpcyBjb2RlIGFuZCBpdHMgaW50ZXJuYWwgaW50ZXJmYWNlcyBhcmUgc3ViamVjdCB0byBjaGFuZ2Ugb3IKICogIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj4KICovCnB1YmxpYyBjbGFzcyBKYXZhVG9rZW5pemVyIHsKCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuIHNjYW5uZXJEZWJ1ZyA9IGZhbHNlOwoKICAgIC8qKiBBbGxvdyBiaW5hcnkgbGl0ZXJhbHMuCiAgICAgKi8KICAgIHByaXZhdGUgYm9vbGVhbiBhbGxvd0JpbmFyeUxpdGVyYWxzOwoKICAgIC8qKiBBbGxvdyB1bmRlcnNjb3JlcyBpbiBsaXRlcmFscy4KICAgICAqLwogICAgcHJpdmF0ZSBib29sZWFuIGFsbG93VW5kZXJzY29yZXNJbkxpdGVyYWxzOwoKICAgIC8qKiBUaGUgc291cmNlIGxhbmd1YWdlIHNldHRpbmcuCiAgICAgKi8KICAgIHByaXZhdGUgU291cmNlIHNvdXJjZTsKCiAgICAvKiogVGhlIGxvZyB0byBiZSB1c2VkIGZvciBlcnJvciByZXBvcnRpbmcuCiAgICAgKi8KICAgIHByaXZhdGUgZmluYWwgTG9nIGxvZzsKCiAgICAvKiogVGhlIHRva2VuIGZhY3RvcnkuICovCiAgICBwcml2YXRlIGZpbmFsIFRva2VucyB0b2tlbnM7CgogICAgLyoqIFRoZSB0b2tlbiBraW5kLCBzZXQgYnkgbmV4dFRva2VuKCkuCiAgICAgKi8KICAgIHByb3RlY3RlZCBUb2tlbktpbmQgdGs7CgogICAgLyoqIFRoZSB0b2tlbidzIHJhZGl4LCBzZXQgYnkgbmV4dFRva2VuKCkuCiAgICAgKi8KICAgIHByb3RlY3RlZCBpbnQgcmFkaXg7CgogICAgLyoqIFRoZSB0b2tlbidzIG5hbWUsIHNldCBieSBuZXh0VG9rZW4oKS4KICAgICAqLwogICAgcHJvdGVjdGVkIE5hbWUgbmFtZTsKCiAgICAvKiogVGhlIHBvc2l0aW9uIHdoZXJlIGEgbGV4aWNhbCBlcnJvciBvY2N1cnJlZDsKICAgICAqLwogICAgcHJvdGVjdGVkIGludCBlcnJQb3MgPSBQb3NpdGlvbi5OT1BPUzsKCiAgICAvKiogVGhlIFVuaWNvZGUgcmVhZGVyIChsb3ctbGV2ZWwgc3RyZWFtIHJlYWRlcikuCiAgICAgKi8KICAgIHByb3RlY3RlZCBVbmljb2RlUmVhZGVyIHJlYWRlcjsKCiAgICBwcm90ZWN0ZWQgU2Nhbm5lckZhY3RvcnkgZmFjOwoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW4gaGV4RmxvYXRzV29yayA9IGhleEZsb2F0c1dvcmsoKTsKICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gaGV4RmxvYXRzV29yaygpIHsKICAgICAgICB0cnkgewogICAgICAgICAgICBGbG9hdC52YWx1ZU9mKCIweDEuMHAxIik7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0gY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBleCkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQ3JlYXRlIGEgc2Nhbm5lciBmcm9tIHRoZSBpbnB1dCBhcnJheS4gIFRoaXMgbWV0aG9kIG1pZ2h0CiAgICAgKiBtb2RpZnkgdGhlIGFycmF5LiAgVG8gYXZvaWQgY29weWluZyB0aGUgaW5wdXQgYXJyYXksIGVuc3VyZQogICAgICogdGhhdCB7QGNvZGUgaW5wdXRMZW5ndGggPCBpbnB1dC5sZW5ndGh9IG9yCiAgICAgKiB7QGNvZGUgaW5wdXRbaW5wdXQubGVuZ3RoIC0xXX0gaXMgYSB3aGl0ZSBzcGFjZSBjaGFyYWN0ZXIuCiAgICAgKgogICAgICogQHBhcmFtIGZhYyB0aGUgZmFjdG9yeSB3aGljaCBjcmVhdGVkIHRoaXMgU2Nhbm5lcgogICAgICogQHBhcmFtIGJ1ZiB0aGUgaW5wdXQsIG1pZ2h0IGJlIG1vZGlmaWVkCiAgICAgKiBNdXN0IGJlIHBvc2l0aXZlIGFuZCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gaW5wdXQubGVuZ3RoLgogICAgICovCiAgICBwcm90ZWN0ZWQgSmF2YVRva2VuaXplcihTY2FubmVyRmFjdG9yeSBmYWMsIENoYXJCdWZmZXIgYnVmKSB7CiAgICAgICAgdGhpcyhmYWMsIG5ldyBVbmljb2RlUmVhZGVyKGZhYywgYnVmKSk7CiAgICB9CgogICAgcHJvdGVjdGVkIEphdmFUb2tlbml6ZXIoU2Nhbm5lckZhY3RvcnkgZmFjLCBjaGFyW10gYnVmLCBpbnQgaW5wdXRMZW5ndGgpIHsKICAgICAgICB0aGlzKGZhYywgbmV3IFVuaWNvZGVSZWFkZXIoZmFjLCBidWYsIGlucHV0TGVuZ3RoKSk7CiAgICB9CgogICAgcHJvdGVjdGVkIEphdmFUb2tlbml6ZXIoU2Nhbm5lckZhY3RvcnkgZmFjLCBVbmljb2RlUmVhZGVyIHJlYWRlcikgewogICAgICAgIHRoaXMuZmFjID0gZmFjOwogICAgICAgIHRoaXMubG9nID0gZmFjLmxvZzsKICAgICAgICB0aGlzLnRva2VucyA9IGZhYy50b2tlbnM7CiAgICAgICAgdGhpcy5zb3VyY2UgPSBmYWMuc291cmNlOwogICAgICAgIHRoaXMucmVhZGVyID0gcmVhZGVyOwogICAgICAgIHRoaXMuYWxsb3dCaW5hcnlMaXRlcmFscyA9IHNvdXJjZS5hbGxvd0JpbmFyeUxpdGVyYWxzKCk7CiAgICAgICAgdGhpcy5hbGxvd1VuZGVyc2NvcmVzSW5MaXRlcmFscyA9IHNvdXJjZS5hbGxvd1VuZGVyc2NvcmVzSW5MaXRlcmFscygpOwogICAgfQoKICAgIC8qKiBSZXBvcnQgYW4gZXJyb3IgYXQgdGhlIGdpdmVuIHBvc2l0aW9uIHVzaW5nIHRoZSBwcm92aWRlZCBhcmd1bWVudHMuCiAgICAgKi8KICAgIHByb3RlY3RlZCB2b2lkIGxleEVycm9yKGludCBwb3MsIFN0cmluZyBrZXksIE9iamVjdC4uLiBhcmdzKSB7CiAgICAgICAgbG9nLmVycm9yKHBvcywga2V5LCBhcmdzKTsKICAgICAgICB0ayA9IFRva2VuS2luZC5FUlJPUjsKICAgICAgICBlcnJQb3MgPSBwb3M7CiAgICB9CgogICAgLyoqIFJlYWQgbmV4dCBjaGFyYWN0ZXIgaW4gY2hhcmFjdGVyIG9yIHN0cmluZyBsaXRlcmFsIGFuZCBjb3B5IGludG8gc2J1Zi4KICAgICAqLwogICAgcHJpdmF0ZSB2b2lkIHNjYW5MaXRDaGFyKGludCBwb3MpIHsKICAgICAgICBpZiAocmVhZGVyLmNoID09ICdcXCcpIHsKICAgICAgICAgICAgaWYgKHJlYWRlci5wZWVrQ2hhcigpID09ICdcXCcgJiYgIXJlYWRlci5pc1VuaWNvZGUoKSkgewogICAgICAgICAgICAgICAgcmVhZGVyLnNraXBDaGFyKCk7CiAgICAgICAgICAgICAgICByZWFkZXIucHV0Q2hhcignXFwnLCB0cnVlKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHJlYWRlci5zY2FuQ2hhcigpOwogICAgICAgICAgICAgICAgc3dpdGNoIChyZWFkZXIuY2gpIHsKICAgICAgICAgICAgICAgIGNhc2UgJzAnOiBjYXNlICcxJzogY2FzZSAnMic6IGNhc2UgJzMnOgogICAgICAgICAgICAgICAgY2FzZSAnNCc6IGNhc2UgJzUnOiBjYXNlICc2JzogY2FzZSAnNyc6CiAgICAgICAgICAgICAgICAgICAgY2hhciBsZWFkY2ggPSByZWFkZXIuY2g7CiAgICAgICAgICAgICAgICAgICAgaW50IG9jdCA9IHJlYWRlci5kaWdpdChwb3MsIDgpOwogICAgICAgICAgICAgICAgICAgIHJlYWRlci5zY2FuQ2hhcigpOwogICAgICAgICAgICAgICAgICAgIGlmICgnMCcgPD0gcmVhZGVyLmNoICYmIHJlYWRlci5jaCA8PSAnNycpIHsKICAgICAgICAgICAgICAgICAgICAgICAgb2N0ID0gb2N0ICogOCArIHJlYWRlci5kaWdpdChwb3MsIDgpOwogICAgICAgICAgICAgICAgICAgICAgICByZWFkZXIuc2NhbkNoYXIoKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGxlYWRjaCA8PSAnMycgJiYgJzAnIDw9IHJlYWRlci5jaCAmJiByZWFkZXIuY2ggPD0gJzcnKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvY3QgPSBvY3QgKiA4ICsgcmVhZGVyLmRpZ2l0KHBvcywgOCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWFkZXIuc2NhbkNoYXIoKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICByZWFkZXIucHV0Q2hhcigoY2hhcilvY3QpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAnYic6CiAgICAgICAgICAgICAgICAgICAgcmVhZGVyLnB1dENoYXIoJ1xiJywgdHJ1ZSk7IGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAndCc6CiAgICAgICAgICAgICAgICAgICAgcmVhZGVyLnB1dENoYXIoJ1x0JywgdHJ1ZSk7IGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAnbic6CiAgICAgICAgICAgICAgICAgICAgcmVhZGVyLnB1dENoYXIoJ1xuJywgdHJ1ZSk7IGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAnZic6CiAgICAgICAgICAgICAgICAgICAgcmVhZGVyLnB1dENoYXIoJ1xmJywgdHJ1ZSk7IGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAncic6CiAgICAgICAgICAgICAgICAgICAgcmVhZGVyLnB1dENoYXIoJ1xyJywgdHJ1ZSk7IGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAnXCcnOgogICAgICAgICAgICAgICAgICAgIHJlYWRlci5wdXRDaGFyKCdcJycsIHRydWUpOyBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgJ1wiJzoKICAgICAgICAgICAgICAgICAgICByZWFkZXIucHV0Q2hhcignXCInLCB0cnVlKTsgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICdcXCc6CiAgICAgICAgICAgICAgICAgICAgcmVhZGVyLnB1dENoYXIoJ1xcJywgdHJ1ZSk7IGJyZWFrOwogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICBsZXhFcnJvcihyZWFkZXIuYnAsICJpbGxlZ2FsLmVzYy5jaGFyIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgaWYgKHJlYWRlci5icCAhPSByZWFkZXIuYnVmbGVuKSB7CiAgICAgICAgICAgIHJlYWRlci5wdXRDaGFyKHRydWUpOwogICAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIHZvaWQgc2NhbkRpZ2l0cyhpbnQgcG9zLCBpbnQgZGlnaXRSYWRpeCkgewogICAgICAgIGNoYXIgc2F2ZUNoOwogICAgICAgIGludCBzYXZlUG9zOwogICAgICAgIGRvIHsKICAgICAgICAgICAgaWYgKHJlYWRlci5jaCAhPSAnXycpIHsKICAgICAgICAgICAgICAgIHJlYWRlci5wdXRDaGFyKGZhbHNlKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGlmICghYWxsb3dVbmRlcnNjb3Jlc0luTGl0ZXJhbHMpIHsKICAgICAgICAgICAgICAgICAgICBsZXhFcnJvcihwb3MsICJ1bnN1cHBvcnRlZC51bmRlcnNjb3JlLmxpdCIsIHNvdXJjZS5uYW1lKTsKICAgICAgICAgICAgICAgICAgICBhbGxvd1VuZGVyc2NvcmVzSW5MaXRlcmFscyA9IHRydWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc2F2ZUNoID0gcmVhZGVyLmNoOwogICAgICAgICAgICBzYXZlUG9zID0gcmVhZGVyLmJwOwogICAgICAgICAgICByZWFkZXIuc2NhbkNoYXIoKTsKICAgICAgICB9IHdoaWxlIChyZWFkZXIuZGlnaXQocG9zLCBkaWdpdFJhZGl4KSA+PSAwIHx8IHJlYWRlci5jaCA9PSAnXycpOwogICAgICAgIGlmIChzYXZlQ2ggPT0gJ18nKQogICAgICAgICAgICBsZXhFcnJvcihzYXZlUG9zLCAiaWxsZWdhbC51bmRlcnNjb3JlIik7CiAgICB9CgogICAgLyoqIFJlYWQgZnJhY3Rpb25hbCBwYXJ0IG9mIGhleGFkZWNpbWFsIGZsb2F0aW5nIHBvaW50IG51bWJlci4KICAgICAqLwogICAgcHJpdmF0ZSB2b2lkIHNjYW5IZXhFeHBvbmVudEFuZFN1ZmZpeChpbnQgcG9zKSB7CiAgICAgICAgaWYgKHJlYWRlci5jaCA9PSAncCcgfHwgcmVhZGVyLmNoID09ICdQJykgewogICAgICAgICAgICByZWFkZXIucHV0Q2hhcih0cnVlKTsKICAgICAgICAgICAgc2tpcElsbGVnYWxVbmRlcnNjb3JlcygpOwogICAgICAgICAgICBpZiAocmVhZGVyLmNoID09ICcrJyB8fCByZWFkZXIuY2ggPT0gJy0nKSB7CiAgICAgICAgICAgICAgICByZWFkZXIucHV0Q2hhcih0cnVlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBza2lwSWxsZWdhbFVuZGVyc2NvcmVzKCk7CiAgICAgICAgICAgIGlmIChyZWFkZXIuZGlnaXQocG9zLCAxMCkgPj0gMCkgewogICAgICAgICAgICAgICAgc2NhbkRpZ2l0cyhwb3MsIDEwKTsKICAgICAgICAgICAgICAgIGlmICghaGV4RmxvYXRzV29yaykKICAgICAgICAgICAgICAgICAgICBsZXhFcnJvcihwb3MsICJ1bnN1cHBvcnRlZC5jcm9zcy5mcC5saXQiKTsKICAgICAgICAgICAgfSBlbHNlCiAgICAgICAgICAgICAgICBsZXhFcnJvcihwb3MsICJtYWxmb3JtZWQuZnAubGl0Iik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgbGV4RXJyb3IocG9zLCAibWFsZm9ybWVkLmZwLmxpdCIpOwogICAgICAgIH0KICAgICAgICBpZiAocmVhZGVyLmNoID09ICdmJyB8fCByZWFkZXIuY2ggPT0gJ0YnKSB7CiAgICAgICAgICAgIHJlYWRlci5wdXRDaGFyKHRydWUpOwogICAgICAgICAgICB0ayA9IFRva2VuS2luZC5GTE9BVExJVEVSQUw7CiAgICAgICAgICAgIHJhZGl4ID0gMTY7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgaWYgKHJlYWRlci5jaCA9PSAnZCcgfHwgcmVhZGVyLmNoID09ICdEJykgewogICAgICAgICAgICAgICAgcmVhZGVyLnB1dENoYXIodHJ1ZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdGsgPSBUb2tlbktpbmQuRE9VQkxFTElURVJBTDsKICAgICAgICAgICAgcmFkaXggPSAxNjsKICAgICAgICB9CiAgICB9CgogICAgLyoqIFJlYWQgZnJhY3Rpb25hbCBwYXJ0IG9mIGZsb2F0aW5nIHBvaW50IG51bWJlci4KICAgICAqLwogICAgcHJpdmF0ZSB2b2lkIHNjYW5GcmFjdGlvbihpbnQgcG9zKSB7CiAgICAgICAgc2tpcElsbGVnYWxVbmRlcnNjb3JlcygpOwogICAgICAgIGlmIChyZWFkZXIuZGlnaXQocG9zLCAxMCkgPj0gMCkgewogICAgICAgICAgICBzY2FuRGlnaXRzKHBvcywgMTApOwogICAgICAgIH0KICAgICAgICBpbnQgc3AxID0gcmVhZGVyLnNwOwogICAgICAgIGlmIChyZWFkZXIuY2ggPT0gJ2UnIHx8IHJlYWRlci5jaCA9PSAnRScpIHsKICAgICAgICAgICAgcmVhZGVyLnB1dENoYXIodHJ1ZSk7CiAgICAgICAgICAgIHNraXBJbGxlZ2FsVW5kZXJzY29yZXMoKTsKICAgICAgICAgICAgaWYgKHJlYWRlci5jaCA9PSAnKycgfHwgcmVhZGVyLmNoID09ICctJykgewogICAgICAgICAgICAgICAgcmVhZGVyLnB1dENoYXIodHJ1ZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc2tpcElsbGVnYWxVbmRlcnNjb3JlcygpOwogICAgICAgICAgICBpZiAocmVhZGVyLmRpZ2l0KHBvcywgMTApID49IDApIHsKICAgICAgICAgICAgICAgIHNjYW5EaWdpdHMocG9zLCAxMCk7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICAgICAgbGV4RXJyb3IocG9zLCAibWFsZm9ybWVkLmZwLmxpdCIpOwogICAgICAgICAgICByZWFkZXIuc3AgPSBzcDE7CiAgICAgICAgfQogICAgfQoKICAgIC8qKiBSZWFkIGZyYWN0aW9uYWwgcGFydCBhbmQgJ2QnIG9yICdmJyBzdWZmaXggb2YgZmxvYXRpbmcgcG9pbnQgbnVtYmVyLgogICAgICovCiAgICBwcml2YXRlIHZvaWQgc2NhbkZyYWN0aW9uQW5kU3VmZml4KGludCBwb3MpIHsKICAgICAgICByYWRpeCA9IDEwOwogICAgICAgIHNjYW5GcmFjdGlvbihwb3MpOwogICAgICAgIGlmIChyZWFkZXIuY2ggPT0gJ2YnIHx8IHJlYWRlci5jaCA9PSAnRicpIHsKICAgICAgICAgICAgcmVhZGVyLnB1dENoYXIodHJ1ZSk7CiAgICAgICAgICAgIHRrID0gVG9rZW5LaW5kLkZMT0FUTElURVJBTDsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBpZiAocmVhZGVyLmNoID09ICdkJyB8fCByZWFkZXIuY2ggPT0gJ0QnKSB7CiAgICAgICAgICAgICAgICByZWFkZXIucHV0Q2hhcih0cnVlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICB0ayA9IFRva2VuS2luZC5ET1VCTEVMSVRFUkFMOwogICAgICAgIH0KICAgIH0KCiAgICAvKiogUmVhZCBmcmFjdGlvbmFsIHBhcnQgYW5kICdkJyBvciAnZicgc3VmZml4IG9mIGZsb2F0aW5nIHBvaW50IG51bWJlci4KICAgICAqLwogICAgcHJpdmF0ZSB2b2lkIHNjYW5IZXhGcmFjdGlvbkFuZFN1ZmZpeChpbnQgcG9zLCBib29sZWFuIHNlZW5kaWdpdCkgewogICAgICAgIHJhZGl4ID0gMTY7CiAgICAgICAgQXNzZXJ0LmNoZWNrKHJlYWRlci5jaCA9PSAnLicpOwogICAgICAgIHJlYWRlci5wdXRDaGFyKHRydWUpOwogICAgICAgIHNraXBJbGxlZ2FsVW5kZXJzY29yZXMoKTsKICAgICAgICBpZiAocmVhZGVyLmRpZ2l0KHBvcywgMTYpID49IDApIHsKICAgICAgICAgICAgc2VlbmRpZ2l0ID0gdHJ1ZTsKICAgICAgICAgICAgc2NhbkRpZ2l0cyhwb3MsIDE2KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFzZWVuZGlnaXQpCiAgICAgICAgICAgIGxleEVycm9yKHBvcywgImludmFsaWQuaGV4Lm51bWJlciIpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgc2NhbkhleEV4cG9uZW50QW5kU3VmZml4KHBvcyk7CiAgICB9CgogICAgcHJpdmF0ZSB2b2lkIHNraXBJbGxlZ2FsVW5kZXJzY29yZXMoKSB7CiAgICAgICAgaWYgKHJlYWRlci5jaCA9PSAnXycpIHsKICAgICAgICAgICAgbGV4RXJyb3IocmVhZGVyLmJwLCAiaWxsZWdhbC51bmRlcnNjb3JlIik7CiAgICAgICAgICAgIHdoaWxlIChyZWFkZXIuY2ggPT0gJ18nKQogICAgICAgICAgICAgICAgcmVhZGVyLnNjYW5DaGFyKCk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKiBSZWFkIGEgbnVtYmVyLgogICAgICogIEBwYXJhbSByYWRpeCAgVGhlIHJhZGl4IG9mIHRoZSBudW1iZXI7IG9uZSBvZiAyLCA4LCAxMCwgMTYuCiAgICAgKi8KICAgIHByaXZhdGUgdm9pZCBzY2FuTnVtYmVyKGludCBwb3MsIGludCByYWRpeCkgewogICAgICAgIC8vIGZvciBvY3RhbCwgYWxsb3cgYmFzZS0xMCBkaWdpdCBpbiBjYXNlIGl0J3MgYSBmbG9hdCBsaXRlcmFsCiAgICAgICAgdGhpcy5yYWRpeCA9IHJhZGl4OwogICAgICAgIGludCBkaWdpdFJhZGl4ID0gKHJhZGl4ID09IDggPyAxMCA6IHJhZGl4KTsKICAgICAgICBpbnQgZmlyc3REaWdpdCA9IHJlYWRlci5kaWdpdChwb3MsIE1hdGgubWF4KDEwLCBkaWdpdFJhZGl4KSk7CiAgICAgICAgYm9vbGVhbiBzZWVuZGlnaXQgPSBmaXJzdERpZ2l0ID49IDA7CiAgICAgICAgYm9vbGVhbiBzZWVuVmFsaWREaWdpdCA9IGZpcnN0RGlnaXQgPj0gMCAmJiBmaXJzdERpZ2l0IDwgZGlnaXRSYWRpeDsKICAgICAgICBpZiAoc2VlbmRpZ2l0KSB7CiAgICAgICAgICAgIHNjYW5EaWdpdHMocG9zLCBkaWdpdFJhZGl4KTsKICAgICAgICB9CiAgICAgICAgaWYgKHJhZGl4ID09IDE2ICYmIHJlYWRlci5jaCA9PSAnLicpIHsKICAgICAgICAgICAgc2NhbkhleEZyYWN0aW9uQW5kU3VmZml4KHBvcywgc2VlbmRpZ2l0KTsKICAgICAgICB9IGVsc2UgaWYgKHNlZW5kaWdpdCAmJiByYWRpeCA9PSAxNiAmJiAocmVhZGVyLmNoID09ICdwJyB8fCByZWFkZXIuY2ggPT0gJ1AnKSkgewogICAgICAgICAgICBzY2FuSGV4RXhwb25lbnRBbmRTdWZmaXgocG9zKTsKICAgICAgICB9IGVsc2UgaWYgKGRpZ2l0UmFkaXggPT0gMTAgJiYgcmVhZGVyLmNoID09ICcuJykgewogICAgICAgICAgICByZWFkZXIucHV0Q2hhcih0cnVlKTsKICAgICAgICAgICAgc2NhbkZyYWN0aW9uQW5kU3VmZml4KHBvcyk7CiAgICAgICAgfSBlbHNlIGlmIChkaWdpdFJhZGl4ID09IDEwICYmCiAgICAgICAgICAgICAgICAgICAocmVhZGVyLmNoID09ICdlJyB8fCByZWFkZXIuY2ggPT0gJ0UnIHx8CiAgICAgICAgICAgICAgICAgICAgcmVhZGVyLmNoID09ICdmJyB8fCByZWFkZXIuY2ggPT0gJ0YnIHx8CiAgICAgICAgICAgICAgICAgICAgcmVhZGVyLmNoID09ICdkJyB8fCByZWFkZXIuY2ggPT0gJ0QnKSkgewogICAgICAgICAgICBzY2FuRnJhY3Rpb25BbmRTdWZmaXgocG9zKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBpZiAoIXNlZW5WYWxpZERpZ2l0KSB7CiAgICAgICAgICAgICAgICBzd2l0Y2ggKHJhZGl4KSB7CiAgICAgICAgICAgICAgICBjYXNlIDI6CiAgICAgICAgICAgICAgICAgICAgbGV4RXJyb3IocG9zLCAiaW52YWxpZC5iaW5hcnkubnVtYmVyIik7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIDE2OgogICAgICAgICAgICAgICAgICAgIGxleEVycm9yKHBvcywgImludmFsaWQuaGV4Lm51bWJlciIpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChyZWFkZXIuY2ggPT0gJ2wnIHx8IHJlYWRlci5jaCA9PSAnTCcpIHsKICAgICAgICAgICAgICAgIHJlYWRlci5zY2FuQ2hhcigpOwogICAgICAgICAgICAgICAgdGsgPSBUb2tlbktpbmQuTE9OR0xJVEVSQUw7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB0ayA9IFRva2VuS2luZC5JTlRMSVRFUkFMOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKiBSZWFkIGFuIGlkZW50aWZpZXIuCiAgICAgKi8KICAgIHByaXZhdGUgdm9pZCBzY2FuSWRlbnQoKSB7CiAgICAgICAgYm9vbGVhbiBpc0phdmFJZGVudGlmaWVyUGFydDsKICAgICAgICBjaGFyIGhpZ2g7CiAgICAgICAgcmVhZGVyLnB1dENoYXIodHJ1ZSk7CiAgICAgICAgZG8gewogICAgICAgICAgICBzd2l0Y2ggKHJlYWRlci5jaCkgewogICAgICAgICAgICBjYXNlICdBJzogY2FzZSAnQic6IGNhc2UgJ0MnOiBjYXNlICdEJzogY2FzZSAnRSc6CiAgICAgICAgICAgIGNhc2UgJ0YnOiBjYXNlICdHJzogY2FzZSAnSCc6IGNhc2UgJ0knOiBjYXNlICdKJzoKICAgICAgICAgICAgY2FzZSAnSyc6IGNhc2UgJ0wnOiBjYXNlICdNJzogY2FzZSAnTic6IGNhc2UgJ08nOgogICAgICAgICAgICBjYXNlICdQJzogY2FzZSAnUSc6IGNhc2UgJ1InOiBjYXNlICdTJzogY2FzZSAnVCc6CiAgICAgICAgICAgIGNhc2UgJ1UnOiBjYXNlICdWJzogY2FzZSAnVyc6IGNhc2UgJ1gnOiBjYXNlICdZJzoKICAgICAgICAgICAgY2FzZSAnWic6CiAgICAgICAgICAgIGNhc2UgJ2EnOiBjYXNlICdiJzogY2FzZSAnYyc6IGNhc2UgJ2QnOiBjYXNlICdlJzoKICAgICAgICAgICAgY2FzZSAnZic6IGNhc2UgJ2cnOiBjYXNlICdoJzogY2FzZSAnaSc6IGNhc2UgJ2onOgogICAgICAgICAgICBjYXNlICdrJzogY2FzZSAnbCc6IGNhc2UgJ20nOiBjYXNlICduJzogY2FzZSAnbyc6CiAgICAgICAgICAgIGNhc2UgJ3AnOiBjYXNlICdxJzogY2FzZSAncic6IGNhc2UgJ3MnOiBjYXNlICd0JzoKICAgICAgICAgICAgY2FzZSAndSc6IGNhc2UgJ3YnOiBjYXNlICd3JzogY2FzZSAneCc6IGNhc2UgJ3knOgogICAgICAgICAgICBjYXNlICd6JzoKICAgICAgICAgICAgY2FzZSAnJCc6IGNhc2UgJ18nOgogICAgICAgICAgICBjYXNlICcwJzogY2FzZSAnMSc6IGNhc2UgJzInOiBjYXNlICczJzogY2FzZSAnNCc6CiAgICAgICAgICAgIGNhc2UgJzUnOiBjYXNlICc2JzogY2FzZSAnNyc6IGNhc2UgJzgnOiBjYXNlICc5JzoKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICdcdTAwMDAnOiBjYXNlICdcdTAwMDEnOiBjYXNlICdcdTAwMDInOiBjYXNlICdcdTAwMDMnOgogICAgICAgICAgICBjYXNlICdcdTAwMDQnOiBjYXNlICdcdTAwMDUnOiBjYXNlICdcdTAwMDYnOiBjYXNlICdcdTAwMDcnOgogICAgICAgICAgICBjYXNlICdcdTAwMDgnOiBjYXNlICdcdTAwMEUnOiBjYXNlICdcdTAwMEYnOiBjYXNlICdcdTAwMTAnOgogICAgICAgICAgICBjYXNlICdcdTAwMTEnOiBjYXNlICdcdTAwMTInOiBjYXNlICdcdTAwMTMnOiBjYXNlICdcdTAwMTQnOgogICAgICAgICAgICBjYXNlICdcdTAwMTUnOiBjYXNlICdcdTAwMTYnOiBjYXNlICdcdTAwMTcnOgogICAgICAgICAgICBjYXNlICdcdTAwMTgnOiBjYXNlICdcdTAwMTknOiBjYXNlICdcdTAwMUInOgogICAgICAgICAgICBjYXNlICdcdTAwN0YnOgogICAgICAgICAgICAgICAgcmVhZGVyLnNjYW5DaGFyKCk7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgY2FzZSAnXHUwMDFBJzogLy8gRU9JIGlzIGFsc28gYSBsZWdhbCBpZGVudGlmaWVyIHBhcnQKICAgICAgICAgICAgICAgIGlmIChyZWFkZXIuYnAgPj0gcmVhZGVyLmJ1ZmxlbikgewogICAgICAgICAgICAgICAgICAgIG5hbWUgPSByZWFkZXIubmFtZSgpOwogICAgICAgICAgICAgICAgICAgIHRrID0gdG9rZW5zLmxvb2t1cEtpbmQobmFtZSk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmVhZGVyLnNjYW5DaGFyKCk7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIGlmIChyZWFkZXIuY2ggPCAnXHUwMDgwJykgewogICAgICAgICAgICAgICAgICAgIC8vIGFsbCBBU0NJSSByYW5nZSBjaGFycyBhbHJlYWR5IGhhbmRsZWQsIGFib3ZlCiAgICAgICAgICAgICAgICAgICAgaXNKYXZhSWRlbnRpZmllclBhcnQgPSBmYWxzZTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKENoYXJhY3Rlci5pc0lkZW50aWZpZXJJZ25vcmFibGUocmVhZGVyLmNoKSkgewogICAgICAgICAgICAgICAgICAgICAgICByZWFkZXIuc2NhbkNoYXIoKTsKICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgaW50IGNvZGVQb2ludCA9IHJlYWRlci5wZWVrU3Vycm9nYXRlcygpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoY29kZVBvaW50ID49IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc0phdmFJZGVudGlmaWVyUGFydCA9IENoYXJhY3Rlci5pc0phdmFJZGVudGlmaWVyUGFydChjb2RlUG9pbnQpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVhZGVyLnB1dENoYXIodHJ1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc0phdmFJZGVudGlmaWVyUGFydCA9IENoYXJhY3Rlci5pc0phdmFJZGVudGlmaWVyUGFydChyZWFkZXIuY2gpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCFpc0phdmFJZGVudGlmaWVyUGFydCkgewogICAgICAgICAgICAgICAgICAgIG5hbWUgPSByZWFkZXIubmFtZSgpOwogICAgICAgICAgICAgICAgICAgIHRrID0gdG9rZW5zLmxvb2t1cEtpbmQobmFtZSk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJlYWRlci5wdXRDaGFyKHRydWUpOwogICAgICAgIH0gd2hpbGUgKHRydWUpOwogICAgfQoKICAgIC8qKiBSZXR1cm4gdHJ1ZSBpZiByZWFkZXIuY2ggY2FuIGJlIHBhcnQgb2YgYW4gb3BlcmF0b3IuCiAgICAgKi8KICAgIHByaXZhdGUgYm9vbGVhbiBpc1NwZWNpYWwoY2hhciBjaCkgewogICAgICAgIHN3aXRjaCAoY2gpIHsKICAgICAgICBjYXNlICchJzogY2FzZSAnJSc6IGNhc2UgJyYnOiBjYXNlICcqJzogY2FzZSAnPyc6CiAgICAgICAgY2FzZSAnKyc6IGNhc2UgJy0nOiBjYXNlICc6JzogY2FzZSAnPCc6IGNhc2UgJz0nOgogICAgICAgIGNhc2UgJz4nOiBjYXNlICdeJzogY2FzZSAnfCc6IGNhc2UgJ34nOgogICAgICAgIGNhc2UgJ0AnOgogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgfQoKICAgIC8qKiBSZWFkIGxvbmdlc3QgcG9zc2libGUgc2VxdWVuY2Ugb2Ygc3BlY2lhbCBjaGFyYWN0ZXJzIGFuZCBjb252ZXJ0CiAgICAgKiAgdG8gdG9rZW4uCiAgICAgKi8KICAgIHByaXZhdGUgdm9pZCBzY2FuT3BlcmF0b3IoKSB7CiAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgICAgcmVhZGVyLnB1dENoYXIoZmFsc2UpOwogICAgICAgICAgICBOYW1lIG5ld25hbWUgPSByZWFkZXIubmFtZSgpOwogICAgICAgICAgICBUb2tlbktpbmQgdGsxID0gdG9rZW5zLmxvb2t1cEtpbmQobmV3bmFtZSk7CiAgICAgICAgICAgIGlmICh0azEgPT0gVG9rZW5LaW5kLklERU5USUZJRVIpIHsKICAgICAgICAgICAgICAgIHJlYWRlci5zcC0tOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdGsgPSB0azE7CiAgICAgICAgICAgIHJlYWRlci5zY2FuQ2hhcigpOwogICAgICAgICAgICBpZiAoIWlzU3BlY2lhbChyZWFkZXIuY2gpKSBicmVhazsKICAgICAgICB9CiAgICB9CgogICAgLyoqIFJlYWQgdG9rZW4uCiAgICAgKi8KICAgIHB1YmxpYyBUb2tlbiByZWFkVG9rZW4oKSB7CgogICAgICAgIHJlYWRlci5zcCA9IDA7CiAgICAgICAgbmFtZSA9IG51bGw7CiAgICAgICAgcmFkaXggPSAwOwoKICAgICAgICBpbnQgcG9zID0gMDsKICAgICAgICBpbnQgZW5kUG9zID0gMDsKICAgICAgICBMaXN0PENvbW1lbnQ+IGNvbW1lbnRzID0gbnVsbDsKCiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgbG9vcDogd2hpbGUgKHRydWUpIHsKICAgICAgICAgICAgICAgIHBvcyA9IHJlYWRlci5icDsKICAgICAgICAgICAgICAgIHN3aXRjaCAocmVhZGVyLmNoKSB7CiAgICAgICAgICAgICAgICBjYXNlICcgJzogLy8gKFNwZWMgMy42KQogICAgICAgICAgICAgICAgY2FzZSAnXHQnOiAvLyAoU3BlYyAzLjYpCiAgICAgICAgICAgICAgICBjYXNlIEZGOiAvLyAoU3BlYyAzLjYpCiAgICAgICAgICAgICAgICAgICAgZG8gewogICAgICAgICAgICAgICAgICAgICAgICByZWFkZXIuc2NhbkNoYXIoKTsKICAgICAgICAgICAgICAgICAgICB9IHdoaWxlIChyZWFkZXIuY2ggPT0gJyAnIHx8IHJlYWRlci5jaCA9PSAnXHQnIHx8IHJlYWRlci5jaCA9PSBGRik7CiAgICAgICAgICAgICAgICAgICAgcHJvY2Vzc1doaXRlU3BhY2UocG9zLCByZWFkZXIuYnApOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBMRjogLy8gKFNwZWMgMy40KQogICAgICAgICAgICAgICAgICAgIHJlYWRlci5zY2FuQ2hhcigpOwogICAgICAgICAgICAgICAgICAgIHByb2Nlc3NMaW5lVGVybWluYXRvcihwb3MsIHJlYWRlci5icCk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIENSOiAvLyAoU3BlYyAzLjQpCiAgICAgICAgICAgICAgICAgICAgcmVhZGVyLnNjYW5DaGFyKCk7CiAgICAgICAgICAgICAgICAgICAgaWYgKHJlYWRlci5jaCA9PSBMRikgewogICAgICAgICAgICAgICAgICAgICAgICByZWFkZXIuc2NhbkNoYXIoKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgcHJvY2Vzc0xpbmVUZXJtaW5hdG9yKHBvcywgcmVhZGVyLmJwKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgJ0EnOiBjYXNlICdCJzogY2FzZSAnQyc6IGNhc2UgJ0QnOiBjYXNlICdFJzoKICAgICAgICAgICAgICAgIGNhc2UgJ0YnOiBjYXNlICdHJzogY2FzZSAnSCc6IGNhc2UgJ0knOiBjYXNlICdKJzoKICAgICAgICAgICAgICAgIGNhc2UgJ0snOiBjYXNlICdMJzogY2FzZSAnTSc6IGNhc2UgJ04nOiBjYXNlICdPJzoKICAgICAgICAgICAgICAgIGNhc2UgJ1AnOiBjYXNlICdRJzogY2FzZSAnUic6IGNhc2UgJ1MnOiBjYXNlICdUJzoKICAgICAgICAgICAgICAgIGNhc2UgJ1UnOiBjYXNlICdWJzogY2FzZSAnVyc6IGNhc2UgJ1gnOiBjYXNlICdZJzoKICAgICAgICAgICAgICAgIGNhc2UgJ1onOgogICAgICAgICAgICAgICAgY2FzZSAnYSc6IGNhc2UgJ2InOiBjYXNlICdjJzogY2FzZSAnZCc6IGNhc2UgJ2UnOgogICAgICAgICAgICAgICAgY2FzZSAnZic6IGNhc2UgJ2cnOiBjYXNlICdoJzogY2FzZSAnaSc6IGNhc2UgJ2onOgogICAgICAgICAgICAgICAgY2FzZSAnayc6IGNhc2UgJ2wnOiBjYXNlICdtJzogY2FzZSAnbic6IGNhc2UgJ28nOgogICAgICAgICAgICAgICAgY2FzZSAncCc6IGNhc2UgJ3EnOiBjYXNlICdyJzogY2FzZSAncyc6IGNhc2UgJ3QnOgogICAgICAgICAgICAgICAgY2FzZSAndSc6IGNhc2UgJ3YnOiBjYXNlICd3JzogY2FzZSAneCc6IGNhc2UgJ3knOgogICAgICAgICAgICAgICAgY2FzZSAneic6CiAgICAgICAgICAgICAgICBjYXNlICckJzogY2FzZSAnXyc6CiAgICAgICAgICAgICAgICAgICAgc2NhbklkZW50KCk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWsgbG9vcDsKICAgICAgICAgICAgICAgIGNhc2UgJzAnOgogICAgICAgICAgICAgICAgICAgIHJlYWRlci5zY2FuQ2hhcigpOwogICAgICAgICAgICAgICAgICAgIGlmIChyZWFkZXIuY2ggPT0gJ3gnIHx8IHJlYWRlci5jaCA9PSAnWCcpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmVhZGVyLnNjYW5DaGFyKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHNraXBJbGxlZ2FsVW5kZXJzY29yZXMoKTsKICAgICAgICAgICAgICAgICAgICAgICAgc2Nhbk51bWJlcihwb3MsIDE2KTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHJlYWRlci5jaCA9PSAnYicgfHwgcmVhZGVyLmNoID09ICdCJykgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWFsbG93QmluYXJ5TGl0ZXJhbHMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxleEVycm9yKHBvcywgInVuc3VwcG9ydGVkLmJpbmFyeS5saXQiLCBzb3VyY2UubmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbGxvd0JpbmFyeUxpdGVyYWxzID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICByZWFkZXIuc2NhbkNoYXIoKTsKICAgICAgICAgICAgICAgICAgICAgICAgc2tpcElsbGVnYWxVbmRlcnNjb3JlcygpOwogICAgICAgICAgICAgICAgICAgICAgICBzY2FuTnVtYmVyKHBvcywgMik7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmVhZGVyLnB1dENoYXIoJzAnKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlYWRlci5jaCA9PSAnXycpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBzYXZlUG9zID0gcmVhZGVyLmJwOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZG8gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlYWRlci5zY2FuQ2hhcigpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfSB3aGlsZSAocmVhZGVyLmNoID09ICdfJyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVhZGVyLmRpZ2l0KHBvcywgMTApIDwgMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxleEVycm9yKHNhdmVQb3MsICJpbGxlZ2FsLnVuZGVyc2NvcmUiKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBzY2FuTnVtYmVyKHBvcywgOCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrIGxvb3A7CiAgICAgICAgICAgICAgICBjYXNlICcxJzogY2FzZSAnMic6IGNhc2UgJzMnOiBjYXNlICc0JzoKICAgICAgICAgICAgICAgIGNhc2UgJzUnOiBjYXNlICc2JzogY2FzZSAnNyc6IGNhc2UgJzgnOiBjYXNlICc5JzoKICAgICAgICAgICAgICAgICAgICBzY2FuTnVtYmVyKHBvcywgMTApOwogICAgICAgICAgICAgICAgICAgIGJyZWFrIGxvb3A7CiAgICAgICAgICAgICAgICBjYXNlICcuJzoKICAgICAgICAgICAgICAgICAgICByZWFkZXIuc2NhbkNoYXIoKTsKICAgICAgICAgICAgICAgICAgICBpZiAocmVhZGVyLmRpZ2l0KHBvcywgMTApID49IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmVhZGVyLnB1dENoYXIoJy4nKTsKICAgICAgICAgICAgICAgICAgICAgICAgc2NhbkZyYWN0aW9uQW5kU3VmZml4KHBvcyk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChyZWFkZXIuY2ggPT0gJy4nKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGludCBzYXZlUG9zID0gcmVhZGVyLmJwOwogICAgICAgICAgICAgICAgICAgICAgICByZWFkZXIucHV0Q2hhcignLicpOyByZWFkZXIucHV0Q2hhcignLicsIHRydWUpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVhZGVyLmNoID09ICcuJykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVhZGVyLnNjYW5DaGFyKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWFkZXIucHV0Q2hhcignLicpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGsgPSBUb2tlbktpbmQuRUxMSVBTSVM7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXhFcnJvcihzYXZlUG9zLCAiaWxsZWdhbC5kb3QiKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRrID0gVG9rZW5LaW5kLkRPVDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWsgbG9vcDsKICAgICAgICAgICAgICAgIGNhc2UgJywnOgogICAgICAgICAgICAgICAgICAgIHJlYWRlci5zY2FuQ2hhcigpOyB0ayA9IFRva2VuS2luZC5DT01NQTsgYnJlYWsgbG9vcDsKICAgICAgICAgICAgICAgIGNhc2UgJzsnOgogICAgICAgICAgICAgICAgICAgIHJlYWRlci5zY2FuQ2hhcigpOyB0ayA9IFRva2VuS2luZC5TRU1JOyBicmVhayBsb29wOwogICAgICAgICAgICAgICAgY2FzZSAnKCc6CiAgICAgICAgICAgICAgICAgICAgcmVhZGVyLnNjYW5DaGFyKCk7IHRrID0gVG9rZW5LaW5kLkxQQVJFTjsgYnJlYWsgbG9vcDsKICAgICAgICAgICAgICAgIGNhc2UgJyknOgogICAgICAgICAgICAgICAgICAgIHJlYWRlci5zY2FuQ2hhcigpOyB0ayA9IFRva2VuS2luZC5SUEFSRU47IGJyZWFrIGxvb3A7CiAgICAgICAgICAgICAgICBjYXNlICdbJzoKICAgICAgICAgICAgICAgICAgICByZWFkZXIuc2NhbkNoYXIoKTsgdGsgPSBUb2tlbktpbmQuTEJSQUNLRVQ7IGJyZWFrIGxvb3A7CiAgICAgICAgICAgICAgICBjYXNlICddJzoKICAgICAgICAgICAgICAgICAgICByZWFkZXIuc2NhbkNoYXIoKTsgdGsgPSBUb2tlbktpbmQuUkJSQUNLRVQ7IGJyZWFrIGxvb3A7CiAgICAgICAgICAgICAgICBjYXNlICd7JzoKICAgICAgICAgICAgICAgICAgICByZWFkZXIuc2NhbkNoYXIoKTsgdGsgPSBUb2tlbktpbmQuTEJSQUNFOyBicmVhayBsb29wOwogICAgICAgICAgICAgICAgY2FzZSAnfSc6CiAgICAgICAgICAgICAgICAgICAgcmVhZGVyLnNjYW5DaGFyKCk7IHRrID0gVG9rZW5LaW5kLlJCUkFDRTsgYnJlYWsgbG9vcDsKICAgICAgICAgICAgICAgIGNhc2UgJy8nOgogICAgICAgICAgICAgICAgICAgIHJlYWRlci5zY2FuQ2hhcigpOwogICAgICAgICAgICAgICAgICAgIGlmIChyZWFkZXIuY2ggPT0gJy8nKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGRvIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlYWRlci5zY2FuQ29tbWVudENoYXIoKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSB3aGlsZSAocmVhZGVyLmNoICE9IENSICYmIHJlYWRlci5jaCAhPSBMRiAmJiByZWFkZXIuYnAgPCByZWFkZXIuYnVmbGVuKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlYWRlci5icCA8IHJlYWRlci5idWZsZW4pIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbW1lbnRzID0gYWRkQ29tbWVudChjb21tZW50cywgcHJvY2Vzc0NvbW1lbnQocG9zLCByZWFkZXIuYnAsIENvbW1lbnRTdHlsZS5MSU5FKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChyZWFkZXIuY2ggPT0gJyonKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gaXNFbXB0eSA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgICAgICByZWFkZXIuc2NhbkNoYXIoKTsKICAgICAgICAgICAgICAgICAgICAgICAgQ29tbWVudFN0eWxlIHN0eWxlOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVhZGVyLmNoID09ICcqJykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGUgPSBDb21tZW50U3R5bGUuSkFWQURPQzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlYWRlci5zY2FuQ29tbWVudENoYXIoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZWFkZXIuY2ggPT0gJy8nKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNFbXB0eSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHlsZSA9IENvbW1lbnRTdHlsZS5CTE9DSzsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoIWlzRW1wdHkgJiYgcmVhZGVyLmJwIDwgcmVhZGVyLmJ1ZmxlbikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlYWRlci5jaCA9PSAnKicpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWFkZXIuc2NhbkNoYXIoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVhZGVyLmNoID09ICcvJykgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlYWRlci5zY2FuQ29tbWVudENoYXIoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVhZGVyLmNoID09ICcvJykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVhZGVyLnNjYW5DaGFyKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21tZW50cyA9IGFkZENvbW1lbnQoY29tbWVudHMsIHByb2Nlc3NDb21tZW50KHBvcywgcmVhZGVyLmJwLCBzdHlsZSkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXhFcnJvcihwb3MsICJ1bmNsb3NlZC5jb21tZW50Iik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhayBsb29wOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChyZWFkZXIuY2ggPT0gJz0nKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRrID0gVG9rZW5LaW5kLlNMQVNIRVE7CiAgICAgICAgICAgICAgICAgICAgICAgIHJlYWRlci5zY2FuQ2hhcigpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRrID0gVG9rZW5LaW5kLlNMQVNIOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhayBsb29wOwogICAgICAgICAgICAgICAgY2FzZSAnXCcnOgogICAgICAgICAgICAgICAgICAgIHJlYWRlci5zY2FuQ2hhcigpOwogICAgICAgICAgICAgICAgICAgIGlmIChyZWFkZXIuY2ggPT0gJ1wnJykgewogICAgICAgICAgICAgICAgICAgICAgICBsZXhFcnJvcihwb3MsICJlbXB0eS5jaGFyLmxpdCIpOwogICAgICAgICAgICAgICAgICAgICAgICByZWFkZXIuc2NhbkNoYXIoKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVhZGVyLmNoID09IENSIHx8IHJlYWRlci5jaCA9PSBMRikKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxleEVycm9yKHBvcywgImlsbGVnYWwubGluZS5lbmQuaW4uY2hhci5saXQiKTsKICAgICAgICAgICAgICAgICAgICAgICAgc2NhbkxpdENoYXIocG9zKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlYWRlci5jaCA9PSAnXCcnKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWFkZXIuc2NhbkNoYXIoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRrID0gVG9rZW5LaW5kLkNIQVJMSVRFUkFMOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV4RXJyb3IocG9zLCAidW5jbG9zZWQuY2hhci5saXQiKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhayBsb29wOwogICAgICAgICAgICAgICAgY2FzZSAnXCInOgogICAgICAgICAgICAgICAgICAgIHJlYWRlci5zY2FuQ2hhcigpOwogICAgICAgICAgICAgICAgICAgIHdoaWxlIChyZWFkZXIuY2ggIT0gJ1wiJyAmJiByZWFkZXIuY2ggIT0gQ1IgJiYgcmVhZGVyLmNoICE9IExGICYmIHJlYWRlci5icCA8IHJlYWRlci5idWZsZW4pCiAgICAgICAgICAgICAgICAgICAgICAgIHNjYW5MaXRDaGFyKHBvcyk7CiAgICAgICAgICAgICAgICAgICAgaWYgKHJlYWRlci5jaCA9PSAnXCInKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRrID0gVG9rZW5LaW5kLlNUUklOR0xJVEVSQUw7CiAgICAgICAgICAgICAgICAgICAgICAgIHJlYWRlci5zY2FuQ2hhcigpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGxleEVycm9yKHBvcywgInVuY2xvc2VkLnN0ci5saXQiKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWsgbG9vcDsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgaWYgKGlzU3BlY2lhbChyZWFkZXIuY2gpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHNjYW5PcGVyYXRvcigpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gaXNKYXZhSWRlbnRpZmllclN0YXJ0OwogICAgICAgICAgICAgICAgICAgICAgICBpbnQgY29kZVBvaW50ID0gLTE7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZWFkZXIuY2ggPCAnXHUwMDgwJykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYWxsIEFTQ0lJIHJhbmdlIGNoYXJzIGFscmVhZHkgaGFuZGxlZCwgYWJvdmUKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzSmF2YUlkZW50aWZpZXJTdGFydCA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29kZVBvaW50ID0gcmVhZGVyLnBlZWtTdXJyb2dhdGVzKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY29kZVBvaW50ID49IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNKYXZhSWRlbnRpZmllclN0YXJ0ID0gQ2hhcmFjdGVyLmlzSmF2YUlkZW50aWZpZXJTdGFydChjb2RlUG9pbnQpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlYWRlci5wdXRDaGFyKHRydWUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNKYXZhSWRlbnRpZmllclN0YXJ0ID0gQ2hhcmFjdGVyLmlzSmF2YUlkZW50aWZpZXJTdGFydChyZWFkZXIuY2gpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc0phdmFJZGVudGlmaWVyU3RhcnQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjYW5JZGVudCgpOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHJlYWRlci5kaWdpdChwb3MsIDEwKSA+PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY2FuTnVtYmVyKHBvcywgMTApOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHJlYWRlci5icCA9PSByZWFkZXIuYnVmbGVuIHx8IHJlYWRlci5jaCA9PSBFT0kgJiYgcmVhZGVyLmJwICsgMSA9PSByZWFkZXIuYnVmbGVuKSB7IC8vIEpMUyAzLjUKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRrID0gVG9rZW5LaW5kLkVPRjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvcyA9IHJlYWRlci5idWZsZW47CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgYXJnOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb2RlUG9pbnQgPj0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYXIgaGlnaCA9IHJlYWRlci5jaDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWFkZXIuc2NhbkNoYXIoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmcgPSBTdHJpbmcuZm9ybWF0KCJcXHUlMDR4XFx1JTA0eCIsIChpbnQpIGhpZ2gsIChpbnQpcmVhZGVyLmNoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJnID0gKDMyIDwgcmVhZGVyLmNoICYmIHJlYWRlci5jaCA8IDEyNykgPwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcuZm9ybWF0KCIlcyIsIHJlYWRlci5jaCkgOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcuZm9ybWF0KCJcXHUlMDR4IiwgKGludClyZWFkZXIuY2gpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV4RXJyb3IocG9zLCAiaWxsZWdhbC5jaGFyIiwgYXJnKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlYWRlci5zY2FuQ2hhcigpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrIGxvb3A7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZW5kUG9zID0gcmVhZGVyLmJwOwogICAgICAgICAgICBzd2l0Y2ggKHRrLnRhZykgewogICAgICAgICAgICAgICAgY2FzZSBERUZBVUxUOiByZXR1cm4gbmV3IFRva2VuKHRrLCBwb3MsIGVuZFBvcywgY29tbWVudHMpOwogICAgICAgICAgICAgICAgY2FzZSBOQU1FRDogcmV0dXJuIG5ldyBOYW1lZFRva2VuKHRrLCBwb3MsIGVuZFBvcywgbmFtZSwgY29tbWVudHMpOwogICAgICAgICAgICAgICAgY2FzZSBTVFJJTkc6IHJldHVybiBuZXcgU3RyaW5nVG9rZW4odGssIHBvcywgZW5kUG9zLCByZWFkZXIuY2hhcnMoKSwgY29tbWVudHMpOwogICAgICAgICAgICAgICAgY2FzZSBOVU1FUklDOiByZXR1cm4gbmV3IE51bWVyaWNUb2tlbih0aywgcG9zLCBlbmRQb3MsIHJlYWRlci5jaGFycygpLCByYWRpeCwgY29tbWVudHMpOwogICAgICAgICAgICAgICAgZGVmYXVsdDogdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZmluYWxseSB7CiAgICAgICAgICAgIGlmIChzY2FubmVyRGVidWcpIHsKICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIm5leHRUb2tlbigiICsgcG9zCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiwiICsgZW5kUG9zICsgIik9fCIgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgU3RyaW5nKHJlYWRlci5nZXRSYXdDaGFyYWN0ZXJzKHBvcywgZW5kUG9zKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAifCIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgLy93aGVyZQogICAgICAgIExpc3Q8Q29tbWVudD4gYWRkQ29tbWVudChMaXN0PENvbW1lbnQ+IGNvbW1lbnRzLCBDb21tZW50IGNvbW1lbnQpIHsKICAgICAgICAgICAgcmV0dXJuIGNvbW1lbnRzID09IG51bGwgPwogICAgICAgICAgICAgICAgICAgIExpc3Qub2YoY29tbWVudCkgOgogICAgICAgICAgICAgICAgICAgIGNvbW1lbnRzLnByZXBlbmQoY29tbWVudCk7CiAgICAgICAgfQoKICAgIC8qKiBSZXR1cm4gdGhlIHBvc2l0aW9uIHdoZXJlIGEgbGV4aWNhbCBlcnJvciBvY2N1cnJlZDsKICAgICAqLwogICAgcHVibGljIGludCBlcnJQb3MoKSB7CiAgICAgICAgcmV0dXJuIGVyclBvczsKICAgIH0KCiAgICAvKiogU2V0IHRoZSBwb3NpdGlvbiB3aGVyZSBhIGxleGljYWwgZXJyb3Igb2NjdXJyZWQ7CiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIGVyclBvcyhpbnQgcG9zKSB7CiAgICAgICAgZXJyUG9zID0gcG9zOwogICAgfQoKICAgIC8qKgogICAgICogQ2FsbGVkIHdoZW4gYSBjb21wbGV0ZSBjb21tZW50IGhhcyBiZWVuIHNjYW5uZWQuIHBvcyBhbmQgZW5kUG9zCiAgICAgKiB3aWxsIG1hcmsgdGhlIGNvbW1lbnQgYm91bmRhcnkuCiAgICAgKi8KICAgIHByb3RlY3RlZCBUb2tlbnMuQ29tbWVudCBwcm9jZXNzQ29tbWVudChpbnQgcG9zLCBpbnQgZW5kUG9zLCBDb21tZW50U3R5bGUgc3R5bGUpIHsKICAgICAgICBpZiAoc2Nhbm5lckRlYnVnKQogICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oInByb2Nlc3NDb21tZW50KCIgKyBwb3MKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiwiICsgZW5kUG9zICsgIiwiICsgc3R5bGUgKyAiKT18IgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBuZXcgU3RyaW5nKHJlYWRlci5nZXRSYXdDaGFyYWN0ZXJzKHBvcywgZW5kUG9zKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgInwiKTsKICAgICAgICBjaGFyW10gYnVmID0gcmVhZGVyLmdldFJhd0NoYXJhY3RlcnMocG9zLCBlbmRQb3MpOwogICAgICAgIHJldHVybiBuZXcgQmFzaWNDb21tZW50PD4obmV3IFVuaWNvZGVSZWFkZXIoZmFjLCBidWYsIGJ1Zi5sZW5ndGgpLCBzdHlsZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDYWxsZWQgd2hlbiBhIGNvbXBsZXRlIHdoaXRlc3BhY2UgcnVuIGhhcyBiZWVuIHNjYW5uZWQuIHBvcyBhbmQgZW5kUG9zCiAgICAgKiB3aWxsIG1hcmsgdGhlIHdoaXRlc3BhY2UgYm91bmRhcnkuCiAgICAgKi8KICAgIHByb3RlY3RlZCB2b2lkIHByb2Nlc3NXaGl0ZVNwYWNlKGludCBwb3MsIGludCBlbmRQb3MpIHsKICAgICAgICBpZiAoc2Nhbm5lckRlYnVnKQogICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oInByb2Nlc3NXaGl0ZXNwYWNlKCIgKyBwb3MKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiwiICsgZW5kUG9zICsgIik9fCIgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFN0cmluZyhyZWFkZXIuZ2V0UmF3Q2hhcmFjdGVycyhwb3MsIGVuZFBvcykpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICJ8Iik7CiAgICB9CgogICAgLyoqCiAgICAgKiBDYWxsZWQgd2hlbiBhIGxpbmUgdGVybWluYXRvciBoYXMgYmVlbiBwcm9jZXNzZWQuCiAgICAgKi8KICAgIHByb3RlY3RlZCB2b2lkIHByb2Nlc3NMaW5lVGVybWluYXRvcihpbnQgcG9zLCBpbnQgZW5kUG9zKSB7CiAgICAgICAgaWYgKHNjYW5uZXJEZWJ1ZykKICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJwcm9jZXNzVGVybWluYXRvcigiICsgcG9zCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIsIiArIGVuZFBvcyArICIpPXwiICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBTdHJpbmcocmVhZGVyLmdldFJhd0NoYXJhY3RlcnMocG9zLCBlbmRQb3MpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAifCIpOwogICAgfQoKICAgIC8qKiBCdWlsZCBhIG1hcCBmb3IgdHJhbnNsYXRpbmcgYmV0d2VlbiBsaW5lIG51bWJlcnMgYW5kCiAgICAgKiBwb3NpdGlvbnMgaW4gdGhlIGlucHV0LgogICAgICoKICAgICAqIEByZXR1cm4gYSBMaW5lTWFwICovCiAgICBwdWJsaWMgUG9zaXRpb24uTGluZU1hcCBnZXRMaW5lTWFwKCkgewogICAgICAgIHJldHVybiBQb3NpdGlvbi5tYWtlTGluZU1hcChyZWFkZXIuZ2V0UmF3Q2hhcmFjdGVycygpLCByZWFkZXIuYnVmbGVuLCBmYWxzZSk7CiAgICB9CgoKICAgIC8qKgogICAgKiBTY2FuIGEgZG9jdW1lbnRhdGlvbiBjb21tZW50OyBkZXRlcm1pbmUgaWYgYSBkZXByZWNhdGVkIHRhZyBpcyBwcmVzZW50LgogICAgKiBDYWxsZWQgb25jZSB0aGUgaW5pdGlhbCAvLCAqIGhhdmUgYmVlbiBza2lwcGVkLCBwb3NpdGlvbmVkIGF0IHRoZSBzZWNvbmQgKgogICAgKiAod2hpY2ggaXMgdHJlYXRlZCBhcyB0aGUgYmVnaW5uaW5nIG9mIHRoZSBmaXJzdCBsaW5lKS4KICAgICogU3RvcHMgcG9zaXRpb25lZCBhdCB0aGUgY2xvc2luZyAnLycuCiAgICAqLwogICAgcHJvdGVjdGVkIHN0YXRpYyBjbGFzcyBCYXNpY0NvbW1lbnQ8VSBleHRlbmRzIFVuaWNvZGVSZWFkZXI+IGltcGxlbWVudHMgQ29tbWVudCB7CgogICAgICAgIENvbW1lbnRTdHlsZSBjczsKICAgICAgICBVIGNvbW1lbnRfcmVhZGVyOwoKICAgICAgICBwcm90ZWN0ZWQgYm9vbGVhbiBkZXByZWNhdGVkRmxhZyA9IGZhbHNlOwogICAgICAgIHByb3RlY3RlZCBib29sZWFuIHNjYW5uZWQgPSBmYWxzZTsKCiAgICAgICAgcHJvdGVjdGVkIEJhc2ljQ29tbWVudChVIGNvbW1lbnRfcmVhZGVyLCBDb21tZW50U3R5bGUgY3MpIHsKICAgICAgICAgICAgdGhpcy5jb21tZW50X3JlYWRlciA9IGNvbW1lbnRfcmVhZGVyOwogICAgICAgICAgICB0aGlzLmNzID0gY3M7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgU3RyaW5nIGdldFRleHQoKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIGludCBnZXRTb3VyY2VQb3MoaW50IHBvcykgewogICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgQ29tbWVudFN0eWxlIGdldFN0eWxlKCkgewogICAgICAgICAgICByZXR1cm4gY3M7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc0RlcHJlY2F0ZWQoKSB7CiAgICAgICAgICAgIGlmICghc2Nhbm5lZCAmJiBjcyA9PSBDb21tZW50U3R5bGUuSkFWQURPQykgewogICAgICAgICAgICAgICAgc2NhbkRvY0NvbW1lbnQoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gZGVwcmVjYXRlZEZsYWc7CiAgICAgICAgfQoKICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygiZmFsbHRocm91Z2giKQogICAgICAgIHByb3RlY3RlZCB2b2lkIHNjYW5Eb2NDb21tZW50KCkgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgYm9vbGVhbiBkZXByZWNhdGVkUHJlZml4ID0gZmFsc2U7CgogICAgICAgICAgICAgICAgY29tbWVudF9yZWFkZXIuYnAgKz0gMzsgLy8gJy8qKicKICAgICAgICAgICAgICAgIGNvbW1lbnRfcmVhZGVyLmNoID0gY29tbWVudF9yZWFkZXIuYnVmW2NvbW1lbnRfcmVhZGVyLmJwXTsKCiAgICAgICAgICAgICAgICBmb3JFYWNoTGluZToKICAgICAgICAgICAgICAgIHdoaWxlIChjb21tZW50X3JlYWRlci5icCA8IGNvbW1lbnRfcmVhZGVyLmJ1ZmxlbikgewoKICAgICAgICAgICAgICAgICAgICAvLyBTa2lwIG9wdGlvbmFsIFdoaXRlU3BhY2UgYXQgYmVnaW5uaW5nIG9mIGxpbmUKICAgICAgICAgICAgICAgICAgICB3aGlsZSAoY29tbWVudF9yZWFkZXIuYnAgPCBjb21tZW50X3JlYWRlci5idWZsZW4gJiYgKGNvbW1lbnRfcmVhZGVyLmNoID09ICcgJyB8fCBjb21tZW50X3JlYWRlci5jaCA9PSAnXHQnIHx8IGNvbW1lbnRfcmVhZGVyLmNoID09IEZGKSkgewogICAgICAgICAgICAgICAgICAgICAgICBjb21tZW50X3JlYWRlci5zY2FuQ29tbWVudENoYXIoKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vIFNraXAgb3B0aW9uYWwgY29uc2VjdXRpdmUgU3RhcnMKICAgICAgICAgICAgICAgICAgICB3aGlsZSAoY29tbWVudF9yZWFkZXIuYnAgPCBjb21tZW50X3JlYWRlci5idWZsZW4gJiYgY29tbWVudF9yZWFkZXIuY2ggPT0gJyonKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbW1lbnRfcmVhZGVyLnNjYW5Db21tZW50Q2hhcigpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoY29tbWVudF9yZWFkZXIuY2ggPT0gJy8nKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vIFNraXAgb3B0aW9uYWwgV2hpdGVTcGFjZSBhZnRlciBTdGFycwogICAgICAgICAgICAgICAgICAgIHdoaWxlIChjb21tZW50X3JlYWRlci5icCA8IGNvbW1lbnRfcmVhZGVyLmJ1ZmxlbiAmJiAoY29tbWVudF9yZWFkZXIuY2ggPT0gJyAnIHx8IGNvbW1lbnRfcmVhZGVyLmNoID09ICdcdCcgfHwgY29tbWVudF9yZWFkZXIuY2ggPT0gRkYpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbW1lbnRfcmVhZGVyLnNjYW5Db21tZW50Q2hhcigpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgZGVwcmVjYXRlZFByZWZpeCA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgIC8vIEF0IGJlZ2lubmluZyBvZiBsaW5lIGluIHRoZSBKYXZhRG9jIHNlbnNlLgogICAgICAgICAgICAgICAgICAgIGlmICghZGVwcmVjYXRlZEZsYWcpIHsKICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGRlcHJlY2F0ZWQgPSAiQGRlcHJlY2F0ZWQiOwogICAgICAgICAgICAgICAgICAgICAgICBpbnQgaSA9IDA7CiAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChjb21tZW50X3JlYWRlci5icCA8IGNvbW1lbnRfcmVhZGVyLmJ1ZmxlbiAmJiBjb21tZW50X3JlYWRlci5jaCA9PSBkZXByZWNhdGVkLmNoYXJBdChpKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tbWVudF9yZWFkZXIuc2NhbkNvbW1lbnRDaGFyKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpKys7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaSA9PSBkZXByZWNhdGVkLmxlbmd0aCgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVwcmVjYXRlZFByZWZpeCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGlmIChkZXByZWNhdGVkUHJlZml4ICYmIGNvbW1lbnRfcmVhZGVyLmJwIDwgY29tbWVudF9yZWFkZXIuYnVmbGVuKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChDaGFyYWN0ZXIuaXNXaGl0ZXNwYWNlKGNvbW1lbnRfcmVhZGVyLmNoKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVwcmVjYXRlZEZsYWcgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGNvbW1lbnRfcmVhZGVyLmNoID09ICcqJykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tbWVudF9yZWFkZXIuc2NhbkNvbW1lbnRDaGFyKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY29tbWVudF9yZWFkZXIuY2ggPT0gJy8nKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVwcmVjYXRlZEZsYWcgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gU2tpcCByZXN0IG9mIGxpbmUKICAgICAgICAgICAgICAgICAgICB3aGlsZSAoY29tbWVudF9yZWFkZXIuYnAgPCBjb21tZW50X3JlYWRlci5idWZsZW4pIHsKICAgICAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChjb21tZW50X3JlYWRlci5jaCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnKic6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tbWVudF9yZWFkZXIuc2NhbkNvbW1lbnRDaGFyKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNvbW1lbnRfcmVhZGVyLmNoID09ICcvJykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBDUjogLy8gKFNwZWMgMy40KQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbW1lbnRfcmVhZGVyLnNjYW5Db21tZW50Q2hhcigpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb21tZW50X3JlYWRlci5jaCAhPSBMRikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZSBmb3JFYWNoTGluZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBmYWxsIHRocm91Z2ggdG8gTEYgY2FzZSAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBMRjogLy8gKFNwZWMgMy40KQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbW1lbnRfcmVhZGVyLnNjYW5Db21tZW50Q2hhcigpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlIGZvckVhY2hMaW5lOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21tZW50X3JlYWRlci5zY2FuQ29tbWVudENoYXIoKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0gLy8gcmVzdCBvZiBsaW5lCiAgICAgICAgICAgICAgICB9IC8vIGZvckVhY2hMaW5lCiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgICAgICBzY2FubmVkID0gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KfQpQSwMECgAACAAA0n1NSpA3Ngx4CgAAeAoAACUAAABjb20vc3VuL3Rvb2xzL2phdmFjL3BhcnNlci9MZXhlci5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDA1LCAyMDEyLCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuamF2YWMucGFyc2VyOwoKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMucGFyc2VyLlRva2Vucy4qOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLlBvc2l0aW9uLkxpbmVNYXA7CgovKioKICogVGhlIGxleGljYWwgYW5hbHl6ZXIgbWFwcyBhbiBpbnB1dCBzdHJlYW0gY29uc2lzdGluZyBvZiBBU0NJSQogKiBjaGFyYWN0ZXJzIGFuZCBVbmljb2RlIGVzY2FwZXMgaW50byBhIHRva2VuIHNlcXVlbmNlLgogKgogKiA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yCiAqIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj4KICovCnB1YmxpYyBpbnRlcmZhY2UgTGV4ZXIgewoKICAgIC8qKgogICAgICogQ29uc3VtZSB0aGUgbmV4dCB0b2tlbi4KICAgICAqLwogICAgdm9pZCBuZXh0VG9rZW4oKTsKCiAgICAvKioKICAgICAqIFJldHVybiBjdXJyZW50IHRva2VuLgogICAgICovCiAgICBUb2tlbiB0b2tlbigpOwoKICAgIC8qKgogICAgICogUmV0dXJuIHRva2VuIHdpdGggZ2l2ZW4gbG9va2FoZWFkLgogICAgICovCiAgICBUb2tlbiB0b2tlbihpbnQgbG9va2FoZWFkKTsKCiAgICAvKioKICAgICAqIFJldHVybiB0aGUgbGFzdCBjaGFyYWN0ZXIgcG9zaXRpb24gb2YgdGhlIHByZXZpb3VzIHRva2VuLgogICAgICovCiAgICBUb2tlbiBwcmV2VG9rZW4oKTsKCiAgICAvKioKICAgICAqIFNwbGl0cyB0aGUgY3VycmVudCB0b2tlbiBpbiB0d28gYW5kIHJldHVybiB0aGUgZmlyc3QgKHNwbGl0dGVkKSB0b2tlbi4KICAgICAqIEZvciBpbnN0YW5jZSB7QGxpdGVyYWwgJzw8PCd9IGlzIHNwbGl0IGludG8gdHdvIHRva2VucwogICAgICoge0BsaXRlcmFsICc8J30gYW5kIHtAbGl0ZXJhbCAnPDwnfSByZXNwZWN0aXZlbHksCiAgICAgKiBhbmQgdGhlIGxhdHRlciBpcyByZXR1cm5lZC4KICAgICAqLwogICAgVG9rZW4gc3BsaXQoKTsKCiAgICAvKioKICAgICAqIFJldHVybiB0aGUgcG9zaXRpb24gd2hlcmUgYSBsZXhpY2FsIGVycm9yIG9jY3VycmVkOwogICAgICovCiAgICBpbnQgZXJyUG9zKCk7CgogICAgLyoqCiAgICAgKiBTZXQgdGhlIHBvc2l0aW9uIHdoZXJlIGEgbGV4aWNhbCBlcnJvciBvY2N1cnJlZDsKICAgICAqLwogICAgdm9pZCBlcnJQb3MoaW50IHBvcyk7CgogICAgLyoqCiAgICAgKiBCdWlsZCBhIG1hcCBmb3IgdHJhbnNsYXRpbmcgYmV0d2VlbiBsaW5lIG51bWJlcnMgYW5kCiAgICAgKiBwb3NpdGlvbnMgaW4gdGhlIGlucHV0LgogICAgICoKICAgICAqIEByZXR1cm4gYSBMaW5lTWFwCiAgICAgKi8KICAgIExpbmVNYXAgZ2V0TGluZU1hcCgpOwp9ClBLAwQKAAAIAAAGO6lKycoDmQZ8AgAGfAIAKwAAAGNvbS9zdW4vdG9vbHMvamF2YWMvcGFyc2VyL0phdmFjUGFyc2VyLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDE5OTksIDIwMTcsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhYy5wYXJzZXI7CgppbXBvcnQgamF2YS51dGlsLio7CmltcG9ydCBqYXZhLnV0aWwuc3RyZWFtLkNvbGxlY3RvcnM7CgppbXBvcnQgY29tLnN1bi5zb3VyY2UudHJlZS5NZW1iZXJSZWZlcmVuY2VUcmVlLlJlZmVyZW5jZU1vZGU7CmltcG9ydCBjb20uc3VuLnNvdXJjZS50cmVlLk1vZHVsZVRyZWUuTW9kdWxlS2luZDsKCmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuKjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMucGFyc2VyLlRva2Vucy4qOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5wYXJzZXIuVG9rZW5zLkNvbW1lbnQuQ29tbWVudFN0eWxlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5yZXNvdXJjZXMuQ29tcGlsZXJQcm9wZXJ0aWVzOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5yZXNvdXJjZXMuQ29tcGlsZXJQcm9wZXJ0aWVzLkVycm9yczsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS4qOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkpDVHJlZS4qOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLio7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuSkNEaWFnbm9zdGljLkRpYWdub3N0aWNGbGFnOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkpDRGlhZ25vc3RpYy5EaWFnbm9zdGljUG9zaXRpb247CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuTGlzdDsKCmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5wYXJzZXIuVG9rZW5zLlRva2VuS2luZC4qOwppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMucGFyc2VyLlRva2Vucy5Ub2tlbktpbmQuQVNTRVJUOwppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMucGFyc2VyLlRva2Vucy5Ub2tlbktpbmQuQ0FTRTsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLnBhcnNlci5Ub2tlbnMuVG9rZW5LaW5kLkNBVENIOwppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMucGFyc2VyLlRva2Vucy5Ub2tlbktpbmQuRVE7CmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5wYXJzZXIuVG9rZW5zLlRva2VuS2luZC5HVDsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLnBhcnNlci5Ub2tlbnMuVG9rZW5LaW5kLklNUE9SVDsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLnBhcnNlci5Ub2tlbnMuVG9rZW5LaW5kLkxUOwppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5KQ1RyZWUuVGFnLio7CgovKiogVGhlIHBhcnNlciBtYXBzIGEgdG9rZW4gc2VxdWVuY2UgaW50byBhbiBhYnN0cmFjdCBzeW50YXgKICogIHRyZWUuIEl0IG9wZXJhdGVzIGJ5IHJlY3Vyc2l2ZSBkZXNjZW50LCB3aXRoIGNvZGUgZGVyaXZlZAogKiAgc3lzdGVtYXRpY2FsbHkgZnJvbSBhbiBMTCgxKSBncmFtbWFyLiBGb3IgZWZmaWNpZW5jeSByZWFzb25zLCBhbgogKiAgb3BlcmF0b3IgcHJlY2VkZW5jZSBzY2hlbWUgaXMgdXNlZCBmb3IgcGFyc2luZyBiaW5hcnkgb3BlcmF0aW9uCiAqICBleHByZXNzaW9ucy4KICoKICogIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqICBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqICBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogKiAgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPgogKi8KcHVibGljIGNsYXNzIEphdmFjUGFyc2VyIGltcGxlbWVudHMgUGFyc2VyIHsKCiAgICAvKiogVGhlIG51bWJlciBvZiBwcmVjZWRlbmNlIGxldmVscyBvZiBpbmZpeCBvcGVyYXRvcnMuCiAgICAgKi8KICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBpbmZpeFByZWNlZGVuY2VMZXZlbHMgPSAxMDsKCiAgICAvKiogSXMgdGhlIHBhcnNlciBpbnN0YW50aWF0ZWQgdG8gcGFyc2UgYSBtb2R1bGUtaW5mbyBmaWxlID8KICAgICAqLwogICAgcHJpdmF0ZSBmaW5hbCBib29sZWFuIHBhcnNlTW9kdWxlSW5mbzsKCiAgICAvKiogVGhlIHNjYW5uZXIgdXNlZCBmb3IgbGV4aWNhbCBhbmFseXNpcy4KICAgICAqLwogICAgcHJvdGVjdGVkIExleGVyIFM7CgogICAgLyoqIFRoZSBmYWN0b3J5IHRvIGJlIHVzZWQgZm9yIGFic3RyYWN0IHN5bnRheCB0cmVlIGNvbnN0cnVjdGlvbi4KICAgICAqLwogICAgcHJvdGVjdGVkIFRyZWVNYWtlciBGOwoKICAgIC8qKiBUaGUgbG9nIHRvIGJlIHVzZWQgZm9yIGVycm9yIGRpYWdub3N0aWNzLgogICAgICovCiAgICBwcml2YXRlIExvZyBsb2c7CgogICAgLyoqIFRoZSBTb3VyY2UgbGFuZ3VhZ2Ugc2V0dGluZy4gKi8KICAgIHByaXZhdGUgU291cmNlIHNvdXJjZTsKCiAgICAvKiogVGhlIG5hbWUgdGFibGUuICovCiAgICBwcml2YXRlIE5hbWVzIG5hbWVzOwoKICAgIC8qKiBFbmQgcG9zaXRpb24gbWFwcGluZ3MgY29udGFpbmVyICovCiAgICBwcm90ZWN0ZWQgZmluYWwgQWJzdHJhY3RFbmRQb3NUYWJsZSBlbmRQb3NUYWJsZTsKCiAgICAvLyBCZWNhdXNlIG9mIGphdmFjJ3MgbGltaXRlZCBsb29rYWhlYWQsIHNvbWUgY29udGV4dHMgYXJlIGFtYmlndW91cyBpbgogICAgLy8gdGhlIHByZXNlbmNlIG9mIHR5cGUgYW5ub3RhdGlvbnMgZXZlbiB0aG91Z2ggdGhleSBhcmUgbm90IGFtYmlndW91cwogICAgLy8gaW4gdGhlIGFic2VuY2Ugb2YgdHlwZSBhbm5vdGF0aW9ucy4gIENvbnNpZGVyIHRoaXMgY29kZToKICAgIC8vICAgdm9pZCBtKFN0cmluZyBbXSBtKSB7IH0KICAgIC8vICAgdm9pZCBtKFN0cmluZyAuLi4gbSkgeyB9CiAgICAvLyBBZnRlciBwYXJzaW5nICJTdHJpbmciLCBqYXZhYyBjYWxscyBicmFja2V0c09wdCB3aGljaCBpbW1lZGlhdGVseQogICAgLy8gcmV0dXJucyBpZiB0aGUgbmV4dCBjaGFyYWN0ZXIgaXMgbm90ICdbJy4gIFNpbWlsYXJseSwgamF2YWMgY2FuIHNlZQogICAgLy8gaWYgdGhlIG5leHQgdG9rZW4gaXMgLi4uIGFuZCBpbiB0aGF0IGNhc2UgcGFyc2UgYW4gZWxsaXBzaXMuICBCdXQgaW4KICAgIC8vIHRoZSBwcmVzZW5jZSBvZiB0eXBlIGFubm90YXRpb25zOgogICAgLy8gICB2b2lkIG0oU3RyaW5nIEBBIFtdIG0pIHsgfQogICAgLy8gICB2b2lkIG0oU3RyaW5nIEBBIC4uLiBtKSB7IH0KICAgIC8vIG5vIGZpbml0ZSBsb29rYWhlYWQgaXMgZW5vdWdoIHRvIGRldGVybWluZSB3aGV0aGVyIHRvIHJlYWQgYXJyYXkKICAgIC8vIGxldmVscyBvciBhbiBlbGxpcHNpcy4gIEZ1cnRoZXJtb3JlLCBpZiB5b3UgY2FsbCBicmFja2V0c09wdCwgdGhlbgogICAgLy8gYnJhY2tldHNPcHQgZmlyc3QgcmVhZHMgYWxsIHRoZSBsZWFkaW5nIGFubm90YXRpb25zIGFuZCBvbmx5IHRoZW4KICAgIC8vIGRpc2NvdmVycyB0aGF0IGl0IG5lZWRzIHRvIGZhaWwuICBicmFja2V0c09wdCBuZWVkcyBhIHdheSB0byBwdXNoCiAgICAvLyBiYWNrIHRoZSBleHRyYSBhbm5vdGF0aW9ucyB0aGF0IGl0IHJlYWQuICAoQnV0LCBicmFja2V0c09wdCBzaG91bGQKICAgIC8vIG5vdCAqYWx3YXlzKiBiZSBhbGxvd2VkIHRvIHB1c2ggYmFjayBleHRyYSBhbm5vdGF0aW9ucyB0aGF0IGl0IGZpbmRzCiAgICAvLyAtLSBpbiBtb3N0IGNvbnRleHRzLCBhbnkgc3VjaCBleHRyYSBhbm5vdGF0aW9uIGlzIGFuIGVycm9yLgogICAgLy8KICAgIC8vIFRoZSBmb2xsb3dpbmcgdHdvIHZhcmlhYmxlcyBwZXJtaXQgdHlwZSBhbm5vdGF0aW9ucyB0aGF0IGhhdmUKICAgIC8vIGFscmVhZHkgYmVlbiByZWFkIHRvIGJlIHN0b3JlZCBmb3IgbGF0ZXIgdXNlLiAgQWx0ZXJuYXRlCiAgICAvLyBpbXBsZW1lbnRhdGlvbnMgYXJlIHBvc3NpYmxlIGJ1dCB3b3VsZCBjYXVzZSBtdWNoIGxhcmdlciBjaGFuZ2VzIHRvCiAgICAvLyB0aGUgcGFyc2VyLgoKICAgIC8qKiBUeXBlIGFubm90YXRpb25zIHRoYXQgaGF2ZSBhbHJlYWR5IGJlZW4gcmVhZCBidXQgaGF2ZSBub3QgeWV0IGJlZW4gdXNlZC4gKiovCiAgICBwcml2YXRlIExpc3Q8SkNBbm5vdGF0aW9uPiB0eXBlQW5ub3RhdGlvbnNQdXNoZWRCYWNrID0gTGlzdC5uaWwoKTsKCiAgICAvKioKICAgICAqIElmIHRoZSBwYXJzZXIgbm90aWNlcyBleHRyYSBhbm5vdGF0aW9ucywgdGhlbiBpdCBlaXRoZXIgaW1tZWRpYXRlbHkKICAgICAqIGlzc3VlcyBhbiBlcnJvciAoaWYgdGhpcyB2YXJpYWJsZSBpcyBmYWxzZSkgb3IgcGxhY2VzIHRoZSBleHRyYQogICAgICogYW5ub3RhdGlvbnMgaW4gdmFyaWFibGUgdHlwZUFubm90YXRpb25zUHVzaGVkQmFjayAoaWYgdGhpcyB2YXJpYWJsZQogICAgICogaXMgdHJ1ZSkuCiAgICAgKi8KICAgIHByaXZhdGUgYm9vbGVhbiBwZXJtaXRUeXBlQW5ub3RhdGlvbnNQdXNoQmFjayA9IGZhbHNlOwoKICAgIGludGVyZmFjZSBFcnJvclJlY292ZXJ5QWN0aW9uIHsKICAgICAgICBKQ1RyZWUgZG9SZWNvdmVyKEphdmFjUGFyc2VyIHBhcnNlcik7CiAgICB9CgogICAgZW51bSBCYXNpY0Vycm9yUmVjb3ZlcnlBY3Rpb24gaW1wbGVtZW50cyBFcnJvclJlY292ZXJ5QWN0aW9uIHsKICAgICAgICBCTE9DS19TVE1UIHtwdWJsaWMgSkNUcmVlIGRvUmVjb3ZlcihKYXZhY1BhcnNlciBwYXJzZXIpIHsgcmV0dXJuIHBhcnNlci5wYXJzZVN0YXRlbWVudEFzQmxvY2soKTsgfX0sCiAgICAgICAgQ0FUQ0hfQ0xBVVNFIHtwdWJsaWMgSkNUcmVlIGRvUmVjb3ZlcihKYXZhY1BhcnNlciBwYXJzZXIpIHsgcmV0dXJuIHBhcnNlci5jYXRjaENsYXVzZSgpOyB9fQogICAgfQoKICAgIC8qKiBDb25zdHJ1Y3QgYSBwYXJzZXIgZnJvbSBhIGdpdmVuIHNjYW5uZXIsIHRyZWUgZmFjdG9yeSBhbmQgbG9nLgogICAgICovCiAgICBwcm90ZWN0ZWQgSmF2YWNQYXJzZXIoUGFyc2VyRmFjdG9yeSBmYWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgTGV4ZXIgUywKICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGtlZXBEb2NDb21tZW50cywKICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGtlZXBMaW5lTWFwLAogICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4ga2VlcEVuZFBvc2l0aW9ucykgewogICAgICAgIHRoaXMoZmFjLCBTLCBrZWVwRG9jQ29tbWVudHMsIGtlZXBMaW5lTWFwLCBrZWVwRW5kUG9zaXRpb25zLCBmYWxzZSk7CgogICAgfQogICAgLyoqIENvbnN0cnVjdCBhIHBhcnNlciBmcm9tIGEgZ2l2ZW4gc2Nhbm5lciwgdHJlZSBmYWN0b3J5IGFuZCBsb2cuCiAgICAgKi8KICAgIHByb3RlY3RlZCBKYXZhY1BhcnNlcihQYXJzZXJGYWN0b3J5IGZhYywKICAgICAgICAgICAgICAgICAgICAgTGV4ZXIgUywKICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBrZWVwRG9jQ29tbWVudHMsCiAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4ga2VlcExpbmVNYXAsCiAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4ga2VlcEVuZFBvc2l0aW9ucywKICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBwYXJzZU1vZHVsZUluZm8pIHsKICAgICAgICB0aGlzLlMgPSBTOwogICAgICAgIG5leHRUb2tlbigpOyAvLyBwcmltZSB0aGUgcHVtcAogICAgICAgIHRoaXMuRiA9IGZhYy5GOwogICAgICAgIHRoaXMubG9nID0gZmFjLmxvZzsKICAgICAgICB0aGlzLm5hbWVzID0gZmFjLm5hbWVzOwogICAgICAgIHRoaXMuc291cmNlID0gZmFjLnNvdXJjZTsKICAgICAgICB0aGlzLmFsbG93VFdSID0gc291cmNlLmFsbG93VHJ5V2l0aFJlc291cmNlcygpOwogICAgICAgIHRoaXMuYWxsb3dFZmZlY3RpdmVseUZpbmFsVmFyaWFibGVzSW5UV1IgPQogICAgICAgICAgICAgICAgc291cmNlLmFsbG93RWZmZWN0aXZlbHlGaW5hbFZhcmlhYmxlc0luVHJ5V2l0aFJlc291cmNlcygpOwogICAgICAgIHRoaXMuYWxsb3dEaWFtb25kID0gc291cmNlLmFsbG93RGlhbW9uZCgpOwogICAgICAgIHRoaXMuYWxsb3dNdWx0aWNhdGNoID0gc291cmNlLmFsbG93TXVsdGljYXRjaCgpOwogICAgICAgIHRoaXMuYWxsb3dTdHJpbmdGb2xkaW5nID0gZmFjLm9wdGlvbnMuZ2V0Qm9vbGVhbigiYWxsb3dTdHJpbmdGb2xkaW5nIiwgdHJ1ZSk7CiAgICAgICAgdGhpcy5hbGxvd0xhbWJkYSA9IHNvdXJjZS5hbGxvd0xhbWJkYSgpOwogICAgICAgIHRoaXMuYWxsb3dNZXRob2RSZWZlcmVuY2VzID0gc291cmNlLmFsbG93TWV0aG9kUmVmZXJlbmNlcygpOwogICAgICAgIHRoaXMuYWxsb3dEZWZhdWx0TWV0aG9kcyA9IHNvdXJjZS5hbGxvd0RlZmF1bHRNZXRob2RzKCk7CiAgICAgICAgdGhpcy5hbGxvd1N0YXRpY0ludGVyZmFjZU1ldGhvZHMgPSBzb3VyY2UuYWxsb3dTdGF0aWNJbnRlcmZhY2VNZXRob2RzKCk7CiAgICAgICAgdGhpcy5hbGxvd0ludGVyc2VjdGlvblR5cGVzSW5DYXN0ID0gc291cmNlLmFsbG93SW50ZXJzZWN0aW9uVHlwZXNJbkNhc3QoKTsKICAgICAgICB0aGlzLmFsbG93VHlwZUFubm90YXRpb25zID0gc291cmNlLmFsbG93VHlwZUFubm90YXRpb25zKCk7CiAgICAgICAgdGhpcy5hbGxvd01vZHVsZXMgPSBzb3VyY2UuYWxsb3dNb2R1bGVzKCk7CiAgICAgICAgdGhpcy5hbGxvd0Fubm90YXRpb25zQWZ0ZXJUeXBlUGFyYW1zID0gc291cmNlLmFsbG93QW5ub3RhdGlvbnNBZnRlclR5cGVQYXJhbXMoKTsKICAgICAgICB0aGlzLmFsbG93VW5kZXJzY29yZUlkZW50aWZpZXIgPSBzb3VyY2UuYWxsb3dVbmRlcnNjb3JlSWRlbnRpZmllcigpOwogICAgICAgIHRoaXMuYWxsb3dQcml2YXRlSW50ZXJmYWNlTWV0aG9kcyA9IHNvdXJjZS5hbGxvd1ByaXZhdGVJbnRlcmZhY2VNZXRob2RzKCk7CiAgICAgICAgdGhpcy5rZWVwRG9jQ29tbWVudHMgPSBrZWVwRG9jQ29tbWVudHM7CiAgICAgICAgdGhpcy5wYXJzZU1vZHVsZUluZm8gPSBwYXJzZU1vZHVsZUluZm87CiAgICAgICAgZG9jQ29tbWVudHMgPSBuZXdEb2NDb21tZW50VGFibGUoa2VlcERvY0NvbW1lbnRzLCBmYWMpOwogICAgICAgIHRoaXMua2VlcExpbmVNYXAgPSBrZWVwTGluZU1hcDsKICAgICAgICB0aGlzLmVycm9yVHJlZSA9IEYuRXJyb25lb3VzKCk7CiAgICAgICAgZW5kUG9zVGFibGUgPSBuZXdFbmRQb3NUYWJsZShrZWVwRW5kUG9zaXRpb25zKTsKICAgIH0KCiAgICBwcm90ZWN0ZWQgQWJzdHJhY3RFbmRQb3NUYWJsZSBuZXdFbmRQb3NUYWJsZShib29sZWFuIGtlZXBFbmRQb3NpdGlvbnMpIHsKICAgICAgICByZXR1cm4gIGtlZXBFbmRQb3NpdGlvbnMKICAgICAgICAgICAgICAgID8gbmV3IFNpbXBsZUVuZFBvc1RhYmxlKHRoaXMpCiAgICAgICAgICAgICAgICA6IG5ldyBFbXB0eUVuZFBvc1RhYmxlKHRoaXMpOwogICAgfQoKICAgIHByb3RlY3RlZCBEb2NDb21tZW50VGFibGUgbmV3RG9jQ29tbWVudFRhYmxlKGJvb2xlYW4ga2VlcERvY0NvbW1lbnRzLCBQYXJzZXJGYWN0b3J5IGZhYykgewogICAgICAgIHJldHVybiBrZWVwRG9jQ29tbWVudHMgPyBuZXcgTGF6eURvY0NvbW1lbnRUYWJsZShmYWMpIDogbnVsbDsKICAgIH0KCiAgICAvKiogU3dpdGNoOiBTaG91bGQgZGlhbW9uZCBvcGVyYXRvciBiZSByZWNvZ25pemVkPwogICAgICovCiAgICBib29sZWFuIGFsbG93RGlhbW9uZDsKCiAgICAvKiogU3dpdGNoOiBTaG91bGQgbXVsdGljYXRjaCBjbGF1c2UgYmUgYWNjZXB0ZWQ/CiAgICAgKi8KICAgIGJvb2xlYW4gYWxsb3dNdWx0aWNhdGNoOwoKICAgIC8qKiBTd2l0Y2g6IHNob3VsZCB3ZSByZWNvZ25pemUgdHJ5LXdpdGgtcmVzb3VyY2VzPwogICAgICovCiAgICBib29sZWFuIGFsbG93VFdSOwoKICAgIC8qKiBTd2l0Y2g6IHNob3VsZCB3ZSBhbGxvdyAoZWZmZWN0aXZlbHkpIGZpbmFsIHZhcmlhYmxlcyBhcyByZXNvdXJjZXMgaW4gdHJ5LXdpdGgtcmVzb3VyY2VzPwogICAgICovCiAgICBib29sZWFuIGFsbG93RWZmZWN0aXZlbHlGaW5hbFZhcmlhYmxlc0luVFdSOwoKICAgIC8qKiBTd2l0Y2g6IHNob3VsZCB3ZSBmb2xkIHN0cmluZ3M/CiAgICAgKi8KICAgIGJvb2xlYW4gYWxsb3dTdHJpbmdGb2xkaW5nOwoKICAgIC8qKiBTd2l0Y2g6IHNob3VsZCB3ZSByZWNvZ25pemUgbGFtYmRhIGV4cHJlc3Npb25zPwogICAgICovCiAgICBib29sZWFuIGFsbG93TGFtYmRhOwoKICAgIC8qKiBTd2l0Y2g6IHNob3VsZCB3ZSBhbGxvdyBtZXRob2QvY29uc3RydWN0b3IgcmVmZXJlbmNlcz8KICAgICAqLwogICAgYm9vbGVhbiBhbGxvd01ldGhvZFJlZmVyZW5jZXM7CgogICAgLyoqIFN3aXRjaDogc2hvdWxkIHdlIHJlY29nbml6ZSBtb2R1bGVzPwogICAgICovCiAgICBib29sZWFuIGFsbG93TW9kdWxlczsKCiAgICAvKiogU3dpdGNoOiBzaG91bGQgd2UgYWxsb3cgZGVmYXVsdCBtZXRob2RzIGluIGludGVyZmFjZXM/CiAgICAgKi8KICAgIGJvb2xlYW4gYWxsb3dEZWZhdWx0TWV0aG9kczsKCiAgICAvKiogU3dpdGNoOiBzaG91bGQgd2UgYWxsb3cgc3RhdGljIG1ldGhvZHMgaW4gaW50ZXJmYWNlcz8KICAgICAqLwogICAgYm9vbGVhbiBhbGxvd1N0YXRpY0ludGVyZmFjZU1ldGhvZHM7CgogICAgLyoqIFN3aXRjaDogc2hvdWxkIHdlIGFsbG93IHByaXZhdGUgKGluc3RhbmNlKSBtZXRob2RzIGluIGludGVyZmFjZXM/CiAgICAgKi8KICAgIGJvb2xlYW4gYWxsb3dQcml2YXRlSW50ZXJmYWNlTWV0aG9kczsKCiAgICAvKiogU3dpdGNoOiBzaG91bGQgd2UgYWxsb3cgaW50ZXJzZWN0aW9uIHR5cGVzIGluIGNhc3Q/CiAgICAgKi8KICAgIGJvb2xlYW4gYWxsb3dJbnRlcnNlY3Rpb25UeXBlc0luQ2FzdDsKCiAgICAvKiogU3dpdGNoOiBzaG91bGQgd2Uga2VlcCBkb2NDb21tZW50cz8KICAgICAqLwogICAgYm9vbGVhbiBrZWVwRG9jQ29tbWVudHM7CgogICAgLyoqIFN3aXRjaDogc2hvdWxkIHdlIGtlZXAgbGluZSB0YWJsZT8KICAgICAqLwogICAgYm9vbGVhbiBrZWVwTGluZU1hcDsKCiAgICAvKiogU3dpdGNoOiBzaG91bGQgd2UgcmVjb2duaXplIHR5cGUgYW5ub3RhdGlvbnM/CiAgICAgKi8KICAgIGJvb2xlYW4gYWxsb3dUeXBlQW5ub3RhdGlvbnM7CgogICAgLyoqIFN3aXRjaDogc2hvdWxkIHdlIGFsbG93IGFubm90YXRpb25zIGFmdGVyIHRoZSBtZXRob2QgdHlwZSBwYXJhbWV0ZXJzPwogICAgICovCiAgICBib29sZWFuIGFsbG93QW5ub3RhdGlvbnNBZnRlclR5cGVQYXJhbXM7CgogICAgLyoqIFN3aXRjaDogc2hvdWxkIHdlIGFsbG93ICdfJyBhcyBhbiBpZGVudGlmaWVyPwogICAgICovCiAgICBib29sZWFuIGFsbG93VW5kZXJzY29yZUlkZW50aWZpZXI7CgogICAgLyoqIFN3aXRjaDogaXMgInRoaXMiIGFsbG93ZWQgYXMgYW4gaWRlbnRpZmllcj8KICAgICAqIFRoaXMgaXMgbmVlZGVkIHRvIHBhcnNlIHJlY2VpdmVyIHR5cGVzLgogICAgICovCiAgICBib29sZWFuIGFsbG93VGhpc0lkZW50OwoKICAgIC8qKiBUaGUgdHlwZSBvZiB0aGUgbWV0aG9kIHJlY2VpdmVyLCBhcyBzcGVjaWZpZWQgYnkgYSBmaXJzdCAidGhpcyIgcGFyYW1ldGVyLgogICAgICovCiAgICBKQ1ZhcmlhYmxlRGVjbCByZWNlaXZlclBhcmFtOwoKCiAgICAvKiogV2hlbiB0ZXJtcyBhcmUgcGFyc2VkLCB0aGUgbW9kZSBkZXRlcm1pbmVzIHdoaWNoIGlzIGV4cGVjdGVkOgogICAgICogICAgIG1vZGUgPSBFWFBSICAgICAgICA6IGFuIGV4cHJlc3Npb24KICAgICAqICAgICBtb2RlID0gVFlQRSAgICAgICAgOiBhIHR5cGUKICAgICAqICAgICBtb2RlID0gTk9QQVJBTVMgICAgOiBubyBwYXJhbWV0ZXJzIGFsbG93ZWQgZm9yIHR5cGUKICAgICAqICAgICBtb2RlID0gVFlQRUFSRyAgICAgOiB0eXBlIGFyZ3VtZW50CiAgICAgKi8KICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgaW50IEVYUFIgPSAweDE7CiAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGludCBUWVBFID0gMHgyOwogICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBpbnQgTk9QQVJBTVMgPSAweDQ7CiAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGludCBUWVBFQVJHID0gMHg4OwogICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBpbnQgRElBTU9ORCA9IDB4MTA7CgogICAgLyoqIFRoZSBjdXJyZW50IG1vZGUuCiAgICAgKi8KICAgIHByb3RlY3RlZCBpbnQgbW9kZSA9IDA7CgogICAgLyoqIFRoZSBtb2RlIG9mIHRoZSB0ZXJtIHRoYXQgd2FzIHBhcnNlZCBsYXN0LgogICAgICovCiAgICBwcm90ZWN0ZWQgaW50IGxhc3Rtb2RlID0gMDsKCiAgICAvKiAtLS0tLS0tLS0tIHRva2VuIG1hbmFnZW1lbnQgLS0tLS0tLS0tLS0tLS0gKi8KCiAgICBwcm90ZWN0ZWQgVG9rZW4gdG9rZW47CgogICAgcHVibGljIFRva2VuIHRva2VuKCkgewogICAgICAgIHJldHVybiB0b2tlbjsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCBuZXh0VG9rZW4oKSB7CiAgICAgICAgUy5uZXh0VG9rZW4oKTsKICAgICAgICB0b2tlbiA9IFMudG9rZW4oKTsKICAgIH0KCiAgICBwcm90ZWN0ZWQgYm9vbGVhbiBwZWVrVG9rZW4oRmlsdGVyPFRva2VuS2luZD4gdGspIHsKICAgICAgICByZXR1cm4gcGVla1Rva2VuKDAsIHRrKTsKICAgIH0KCiAgICBwcm90ZWN0ZWQgYm9vbGVhbiBwZWVrVG9rZW4oaW50IGxvb2thaGVhZCwgRmlsdGVyPFRva2VuS2luZD4gdGspIHsKICAgICAgICByZXR1cm4gdGsuYWNjZXB0cyhTLnRva2VuKGxvb2thaGVhZCArIDEpLmtpbmQpOwogICAgfQoKICAgIHByb3RlY3RlZCBib29sZWFuIHBlZWtUb2tlbihGaWx0ZXI8VG9rZW5LaW5kPiB0azEsIEZpbHRlcjxUb2tlbktpbmQ+IHRrMikgewogICAgICAgIHJldHVybiBwZWVrVG9rZW4oMCwgdGsxLCB0azIpOwogICAgfQoKICAgIHByb3RlY3RlZCBib29sZWFuIHBlZWtUb2tlbihpbnQgbG9va2FoZWFkLCBGaWx0ZXI8VG9rZW5LaW5kPiB0azEsIEZpbHRlcjxUb2tlbktpbmQ+IHRrMikgewogICAgICAgIHJldHVybiB0azEuYWNjZXB0cyhTLnRva2VuKGxvb2thaGVhZCArIDEpLmtpbmQpICYmCiAgICAgICAgICAgICAgICB0azIuYWNjZXB0cyhTLnRva2VuKGxvb2thaGVhZCArIDIpLmtpbmQpOwogICAgfQoKICAgIHByb3RlY3RlZCBib29sZWFuIHBlZWtUb2tlbihGaWx0ZXI8VG9rZW5LaW5kPiB0azEsIEZpbHRlcjxUb2tlbktpbmQ+IHRrMiwgRmlsdGVyPFRva2VuS2luZD4gdGszKSB7CiAgICAgICAgcmV0dXJuIHBlZWtUb2tlbigwLCB0azEsIHRrMiwgdGszKTsKICAgIH0KCiAgICBwcm90ZWN0ZWQgYm9vbGVhbiBwZWVrVG9rZW4oaW50IGxvb2thaGVhZCwgRmlsdGVyPFRva2VuS2luZD4gdGsxLCBGaWx0ZXI8VG9rZW5LaW5kPiB0azIsIEZpbHRlcjxUb2tlbktpbmQ+IHRrMykgewogICAgICAgIHJldHVybiB0azEuYWNjZXB0cyhTLnRva2VuKGxvb2thaGVhZCArIDEpLmtpbmQpICYmCiAgICAgICAgICAgICAgICB0azIuYWNjZXB0cyhTLnRva2VuKGxvb2thaGVhZCArIDIpLmtpbmQpICYmCiAgICAgICAgICAgICAgICB0azMuYWNjZXB0cyhTLnRva2VuKGxvb2thaGVhZCArIDMpLmtpbmQpOwogICAgfQoKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQogICAgcHJvdGVjdGVkIGJvb2xlYW4gcGVla1Rva2VuKEZpbHRlcjxUb2tlbktpbmQ+Li4uIGtpbmRzKSB7CiAgICAgICAgcmV0dXJuIHBlZWtUb2tlbigwLCBraW5kcyk7CiAgICB9CgogICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCiAgICBwcm90ZWN0ZWQgYm9vbGVhbiBwZWVrVG9rZW4oaW50IGxvb2thaGVhZCwgRmlsdGVyPFRva2VuS2luZD4uLi4ga2luZHMpIHsKICAgICAgICBmb3IgKDsgbG9va2FoZWFkIDwga2luZHMubGVuZ3RoIDsgbG9va2FoZWFkKyspIHsKICAgICAgICAgICAgaWYgKCFraW5kc1tsb29rYWhlYWRdLmFjY2VwdHMoUy50b2tlbihsb29rYWhlYWQgKyAxKS5raW5kKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIC8qIC0tLS0tLS0tLS0gZXJyb3IgcmVjb3ZlcnkgLS0tLS0tLS0tLS0tLS0gKi8KCiAgICBwcml2YXRlIEpDRXJyb25lb3VzIGVycm9yVHJlZTsKCiAgICAvKiogU2tpcCBmb3J3YXJkIHVudGlsIGEgc3VpdGFibGUgc3RvcCB0b2tlbiBpcyBmb3VuZC4KICAgICAqLwogICAgcHJvdGVjdGVkIHZvaWQgc2tpcChib29sZWFuIHN0b3BBdEltcG9ydCwgYm9vbGVhbiBzdG9wQXRNZW1iZXJEZWNsLCBib29sZWFuIHN0b3BBdElkZW50aWZpZXIsIGJvb2xlYW4gc3RvcEF0U3RhdGVtZW50KSB7CiAgICAgICAgIHdoaWxlICh0cnVlKSB7CiAgICAgICAgICAgICBzd2l0Y2ggKHRva2VuLmtpbmQpIHsKICAgICAgICAgICAgICAgIGNhc2UgU0VNSToKICAgICAgICAgICAgICAgICAgICBuZXh0VG9rZW4oKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICBjYXNlIFBVQkxJQzoKICAgICAgICAgICAgICAgIGNhc2UgRklOQUw6CiAgICAgICAgICAgICAgICBjYXNlIEFCU1RSQUNUOgogICAgICAgICAgICAgICAgY2FzZSBNT05LRVlTX0FUOgogICAgICAgICAgICAgICAgY2FzZSBFT0Y6CiAgICAgICAgICAgICAgICBjYXNlIENMQVNTOgogICAgICAgICAgICAgICAgY2FzZSBJTlRFUkZBQ0U6CiAgICAgICAgICAgICAgICBjYXNlIEVOVU06CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgY2FzZSBJTVBPUlQ6CiAgICAgICAgICAgICAgICAgICAgaWYgKHN0b3BBdEltcG9ydCkKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBMQlJBQ0U6CiAgICAgICAgICAgICAgICBjYXNlIFJCUkFDRToKICAgICAgICAgICAgICAgIGNhc2UgUFJJVkFURToKICAgICAgICAgICAgICAgIGNhc2UgUFJPVEVDVEVEOgogICAgICAgICAgICAgICAgY2FzZSBTVEFUSUM6CiAgICAgICAgICAgICAgICBjYXNlIFRSQU5TSUVOVDoKICAgICAgICAgICAgICAgIGNhc2UgTkFUSVZFOgogICAgICAgICAgICAgICAgY2FzZSBWT0xBVElMRToKICAgICAgICAgICAgICAgIGNhc2UgU1lOQ0hST05JWkVEOgogICAgICAgICAgICAgICAgY2FzZSBTVFJJQ1RGUDoKICAgICAgICAgICAgICAgIGNhc2UgTFQ6CiAgICAgICAgICAgICAgICBjYXNlIEJZVEU6CiAgICAgICAgICAgICAgICBjYXNlIFNIT1JUOgogICAgICAgICAgICAgICAgY2FzZSBDSEFSOgogICAgICAgICAgICAgICAgY2FzZSBJTlQ6CiAgICAgICAgICAgICAgICBjYXNlIExPTkc6CiAgICAgICAgICAgICAgICBjYXNlIEZMT0FUOgogICAgICAgICAgICAgICAgY2FzZSBET1VCTEU6CiAgICAgICAgICAgICAgICBjYXNlIEJPT0xFQU46CiAgICAgICAgICAgICAgICBjYXNlIFZPSUQ6CiAgICAgICAgICAgICAgICAgICAgaWYgKHN0b3BBdE1lbWJlckRlY2wpCiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgVU5ERVJTQ09SRToKICAgICAgICAgICAgICAgIGNhc2UgSURFTlRJRklFUjoKICAgICAgICAgICAgICAgICAgIGlmIChzdG9wQXRJZGVudGlmaWVyKQogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIENBU0U6CiAgICAgICAgICAgICAgICBjYXNlIERFRkFVTFQ6CiAgICAgICAgICAgICAgICBjYXNlIElGOgogICAgICAgICAgICAgICAgY2FzZSBGT1I6CiAgICAgICAgICAgICAgICBjYXNlIFdISUxFOgogICAgICAgICAgICAgICAgY2FzZSBETzoKICAgICAgICAgICAgICAgIGNhc2UgVFJZOgogICAgICAgICAgICAgICAgY2FzZSBTV0lUQ0g6CiAgICAgICAgICAgICAgICBjYXNlIFJFVFVSTjoKICAgICAgICAgICAgICAgIGNhc2UgVEhST1c6CiAgICAgICAgICAgICAgICBjYXNlIEJSRUFLOgogICAgICAgICAgICAgICAgY2FzZSBDT05USU5VRToKICAgICAgICAgICAgICAgIGNhc2UgRUxTRToKICAgICAgICAgICAgICAgIGNhc2UgRklOQUxMWToKICAgICAgICAgICAgICAgIGNhc2UgQ0FUQ0g6CiAgICAgICAgICAgICAgICBjYXNlIFRISVM6CiAgICAgICAgICAgICAgICBjYXNlIFNVUEVSOgogICAgICAgICAgICAgICAgY2FzZSBORVc6CiAgICAgICAgICAgICAgICAgICAgaWYgKHN0b3BBdFN0YXRlbWVudCkKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBBU1NFUlQ6CiAgICAgICAgICAgICAgICAgICAgaWYgKHN0b3BBdFN0YXRlbWVudCkKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIG5leHRUb2tlbigpOwogICAgICAgIH0KICAgIH0KCiAgICBwcm90ZWN0ZWQgSkNFcnJvbmVvdXMgc3ludGF4RXJyb3IoaW50IHBvcywgU3RyaW5nIGtleSwgVG9rZW5LaW5kLi4uIGFyZ3MpIHsKICAgICAgICByZXR1cm4gc3ludGF4RXJyb3IocG9zLCBMaXN0Lm5pbCgpLCBrZXksIGFyZ3MpOwogICAgfQoKICAgIHByb3RlY3RlZCBKQ0Vycm9uZW91cyBzeW50YXhFcnJvcihpbnQgcG9zLCBMaXN0PEpDVHJlZT4gZXJycywgU3RyaW5nIGtleSwgVG9rZW5LaW5kLi4uIGFyZ3MpIHsKICAgICAgICBzZXRFcnJvckVuZFBvcyhwb3MpOwogICAgICAgIEpDRXJyb25lb3VzIGVyciA9IEYuYXQocG9zKS5FcnJvbmVvdXMoZXJycyk7CiAgICAgICAgcmVwb3J0U3ludGF4RXJyb3IoZXJyLCBrZXksIChPYmplY3RbXSlhcmdzKTsKICAgICAgICBpZiAoZXJycyAhPSBudWxsKSB7CiAgICAgICAgICAgIEpDVHJlZSBsYXN0ID0gZXJycy5sYXN0KCk7CiAgICAgICAgICAgIGlmIChsYXN0ICE9IG51bGwpCiAgICAgICAgICAgICAgICBzdG9yZUVuZChsYXN0LCBwb3MpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdG9QKGVycik7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFJFQ09WRVJZX1RIUkVTSE9MRCA9IDUwOwogICAgcHJpdmF0ZSBpbnQgZXJyb3JQb3MgPSBQb3NpdGlvbi5OT1BPUzsKICAgIHByaXZhdGUgaW50IGNvdW50ID0gMDsKCiAgICAvKioKICAgICAqIFJlcG9ydCBhIHN5bnRheCB1c2luZyB0aGUgZ2l2ZW4gdGhlIHBvc2l0aW9uIHBhcmFtZXRlciBhbmQgYXJndW1lbnRzLAogICAgICogdW5sZXNzIG9uZSB3YXMgYWxyZWFkeSByZXBvcnRlZCBhdCB0aGUgc2FtZSBwb3NpdGlvbi4KICAgICAqLwogICAgcHJvdGVjdGVkIHZvaWQgcmVwb3J0U3ludGF4RXJyb3IoaW50IHBvcywgU3RyaW5nIGtleSwgT2JqZWN0Li4uIGFyZ3MpIHsKICAgICAgICBKQ0RpYWdub3N0aWMuRGlhZ25vc3RpY1Bvc2l0aW9uIGRpYWcgPSBuZXcgSkNEaWFnbm9zdGljLlNpbXBsZURpYWdub3N0aWNQb3NpdGlvbihwb3MpOwogICAgICAgIHJlcG9ydFN5bnRheEVycm9yKGRpYWcsIGtleSwgYXJncyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXBvcnQgYSBzeW50YXggZXJyb3IgdXNpbmcgdGhlIGdpdmVuIERpYWdub3N0aWNQb3NpdGlvbiBvYmplY3QgYW5kCiAgICAgKiBhcmd1bWVudHMsIHVubGVzcyBvbmUgd2FzIGFscmVhZHkgcmVwb3J0ZWQgYXQgdGhlIHNhbWUgcG9zaXRpb24uCiAgICAgKi8KICAgIHByb3RlY3RlZCB2b2lkIHJlcG9ydFN5bnRheEVycm9yKEpDRGlhZ25vc3RpYy5EaWFnbm9zdGljUG9zaXRpb24gZGlhZ1BvcywgU3RyaW5nIGtleSwgT2JqZWN0Li4uIGFyZ3MpIHsKICAgICAgICBpbnQgcG9zID0gZGlhZ1Bvcy5nZXRQcmVmZXJyZWRQb3NpdGlvbigpOwogICAgICAgIGlmIChwb3MgPiBTLmVyclBvcygpIHx8IHBvcyA9PSBQb3NpdGlvbi5OT1BPUykgewogICAgICAgICAgICBpZiAodG9rZW4ua2luZCA9PSBFT0YpIHsKICAgICAgICAgICAgICAgIGVycm9yKGRpYWdQb3MsICJwcmVtYXR1cmUuZW9mIik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBlcnJvcihkaWFnUG9zLCBrZXksIGFyZ3MpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIFMuZXJyUG9zKHBvcyk7CiAgICAgICAgaWYgKHRva2VuLnBvcyA9PSBlcnJvclBvcykgewogICAgICAgICAgICAvL2NoZWNrIGZvciBhIHBvc3NpYmxlIGluZmluaXRlIGxvb3AgaW4gcGFyc2luZzoKICAgICAgICAgICAgQXNzZXJ0LmNoZWNrKGNvdW50KysgPCBSRUNPVkVSWV9USFJFU0hPTEQpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGNvdW50ID0gMDsKICAgICAgICAgICAgZXJyb3JQb3MgPSB0b2tlbi5wb3M7CiAgICAgICAgfQogICAgfQoKCiAgICAvKiogR2VuZXJhdGUgYSBzeW50YXggZXJyb3IgYXQgY3VycmVudCBwb3NpdGlvbiB1bmxlc3Mgb25lIHdhcyBhbHJlYWR5CiAgICAgKiAgcmVwb3J0ZWQgYXQgdGhlIHNhbWUgcG9zaXRpb24uCiAgICAgKi8KICAgIHByb3RlY3RlZCBKQ0Vycm9uZW91cyBzeW50YXhFcnJvcihTdHJpbmcga2V5KSB7CiAgICAgICAgcmV0dXJuIHN5bnRheEVycm9yKHRva2VuLnBvcywga2V5KTsKICAgIH0KCiAgICAvKiogR2VuZXJhdGUgYSBzeW50YXggZXJyb3IgYXQgY3VycmVudCBwb3NpdGlvbiB1bmxlc3Mgb25lIHdhcwogICAgICogIGFscmVhZHkgcmVwb3J0ZWQgYXQgdGhlIHNhbWUgcG9zaXRpb24uCiAgICAgKi8KICAgIHByb3RlY3RlZCBKQ0Vycm9uZW91cyBzeW50YXhFcnJvcihTdHJpbmcga2V5LCBUb2tlbktpbmQgYXJnKSB7CiAgICAgICAgcmV0dXJuIHN5bnRheEVycm9yKHRva2VuLnBvcywga2V5LCBhcmcpOwogICAgfQoKICAgIC8qKiBJZiBuZXh0IGlucHV0IHRva2VuIG1hdGNoZXMgZ2l2ZW4gdG9rZW4sIHNraXAgaXQsIG90aGVyd2lzZSByZXBvcnQKICAgICAqICBhbiBlcnJvci4KICAgICAqLwogICAgcHVibGljIHZvaWQgYWNjZXB0KFRva2VuS2luZCB0aykgewogICAgICAgIGlmICh0b2tlbi5raW5kID09IHRrKSB7CiAgICAgICAgICAgIG5leHRUb2tlbigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHNldEVycm9yRW5kUG9zKHRva2VuLnBvcyk7CiAgICAgICAgICAgIHJlcG9ydFN5bnRheEVycm9yKFMucHJldlRva2VuKCkuZW5kUG9zLCAiZXhwZWN0ZWQiLCB0ayk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKiBSZXBvcnQgYW4gaWxsZWdhbCBzdGFydCBvZiBleHByZXNzaW9uL3R5cGUgZXJyb3IgYXQgZ2l2ZW4gcG9zaXRpb24uCiAgICAgKi8KICAgIEpDRXhwcmVzc2lvbiBpbGxlZ2FsKGludCBwb3MpIHsKICAgICAgICBzZXRFcnJvckVuZFBvcyhwb3MpOwogICAgICAgIGlmICgobW9kZSAmIEVYUFIpICE9IDApCiAgICAgICAgICAgIHJldHVybiBzeW50YXhFcnJvcihwb3MsICJpbGxlZ2FsLnN0YXJ0Lm9mLmV4cHIiKTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIHJldHVybiBzeW50YXhFcnJvcihwb3MsICJpbGxlZ2FsLnN0YXJ0Lm9mLnR5cGUiKTsKCiAgICB9CgogICAgLyoqIFJlcG9ydCBhbiBpbGxlZ2FsIHN0YXJ0IG9mIGV4cHJlc3Npb24vdHlwZSBlcnJvciBhdCBjdXJyZW50IHBvc2l0aW9uLgogICAgICovCiAgICBKQ0V4cHJlc3Npb24gaWxsZWdhbCgpIHsKICAgICAgICByZXR1cm4gaWxsZWdhbCh0b2tlbi5wb3MpOwogICAgfQoKICAgIC8qKiBEaWFnbm9zZSBhIG1vZGlmaWVyIGZsYWcgZnJvbSB0aGUgc2V0LCBpZiBhbnkuICovCiAgICBwcm90ZWN0ZWQgdm9pZCBjaGVja05vTW9kcyhsb25nIG1vZHMpIHsKICAgICAgICBpZiAobW9kcyAhPSAwKSB7CiAgICAgICAgICAgIGxvbmcgbG93ZXN0TW9kID0gbW9kcyAmIC1tb2RzOwogICAgICAgICAgICBlcnJvcih0b2tlbi5wb3MsICJtb2Qubm90LmFsbG93ZWQuaGVyZSIsCiAgICAgICAgICAgICAgICAgICAgRmxhZ3MuYXNGbGFnU2V0KGxvd2VzdE1vZCkpOwogICAgICAgIH0KICAgIH0KCi8qIC0tLS0tLS0tLS0gZG9jIGNvbW1lbnRzIC0tLS0tLS0tLSAqLwoKICAgIC8qKiBBIHRhYmxlIHRvIHN0b3JlIGFsbCBkb2N1bWVudGF0aW9uIGNvbW1lbnRzCiAgICAgKiAgaW5kZXhlZCBieSB0aGUgdHJlZSBub2RlcyB0aGV5IHJlZmVyIHRvLgogICAgICogIGRlZmluZWQgb25seSBpZiBvcHRpb24gZmxhZyBrZWVwRG9jQ29tbWVudCBpcyBzZXQuCiAgICAgKi8KICAgIHByaXZhdGUgZmluYWwgRG9jQ29tbWVudFRhYmxlIGRvY0NvbW1lbnRzOwoKICAgIC8qKiBNYWtlIGFuIGVudHJ5IGludG8gZG9jQ29tbWVudHMgaGFzaHRhYmxlLAogICAgICogIHByb3ZpZGVkIGZsYWcga2VlcERvY0NvbW1lbnRzIGlzIHNldCBhbmQgZ2l2ZW4gZG9jIGNvbW1lbnQgaXMgbm9uLW51bGwuCiAgICAgKiAgQHBhcmFtIHRyZWUgICBUaGUgdHJlZSB0byBiZSB1c2VkIGFzIGluZGV4IGluIHRoZSBoYXNodGFibGUKICAgICAqICBAcGFyYW0gZGMgICAgIFRoZSBkb2MgY29tbWVudCB0byBhc3NvY2lhdGUgd2l0aCB0aGUgdHJlZSwgb3IgbnVsbC4KICAgICAqLwogICAgcHJvdGVjdGVkIHZvaWQgYXR0YWNoKEpDVHJlZSB0cmVlLCBDb21tZW50IGRjKSB7CiAgICAgICAgaWYgKGtlZXBEb2NDb21tZW50cyAmJiBkYyAhPSBudWxsKSB7Ci8vICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiZG9jIGNvbW1lbnQgPSAiKTtTeXN0ZW0ub3V0LnByaW50bG4oZGMpOy8vREVCVUcKICAgICAgICAgICAgZG9jQ29tbWVudHMucHV0Q29tbWVudCh0cmVlLCBkYyk7CiAgICAgICAgfQogICAgfQoKLyogLS0tLS0tLS0gc291cmNlIHBvc2l0aW9ucyAtLS0tLS0tICovCgogICAgcHJvdGVjdGVkIHZvaWQgc2V0RXJyb3JFbmRQb3MoaW50IGVyclBvcykgewogICAgICAgIGVuZFBvc1RhYmxlLnNldEVycm9yRW5kUG9zKGVyclBvcyk7CiAgICB9CgogICAgcHJvdGVjdGVkIHZvaWQgc3RvcmVFbmQoSkNUcmVlIHRyZWUsIGludCBlbmRwb3MpIHsKICAgICAgICBlbmRQb3NUYWJsZS5zdG9yZUVuZCh0cmVlLCBlbmRwb3MpOwogICAgfQoKICAgIHByb3RlY3RlZCA8VCBleHRlbmRzIEpDVHJlZT4gVCB0byhUIHQpIHsKICAgICAgICByZXR1cm4gZW5kUG9zVGFibGUudG8odCk7CiAgICB9CgogICAgcHJvdGVjdGVkIDxUIGV4dGVuZHMgSkNUcmVlPiBUIHRvUChUIHQpIHsKICAgICAgICByZXR1cm4gZW5kUG9zVGFibGUudG9QKHQpOwogICAgfQoKICAgIC8qKiBHZXQgdGhlIHN0YXJ0IHBvc2l0aW9uIGZvciBhIHRyZWUgbm9kZS4gIFRoZSBzdGFydCBwb3NpdGlvbiBpcwogICAgICogZGVmaW5lZCB0byBiZSB0aGUgcG9zaXRpb24gb2YgdGhlIGZpcnN0IGNoYXJhY3RlciBvZiB0aGUgZmlyc3QKICAgICAqIHRva2VuIG9mIHRoZSBub2RlJ3Mgc291cmNlIHRleHQuCiAgICAgKiBAcGFyYW0gdHJlZSAgVGhlIHRyZWUgbm9kZQogICAgICovCiAgICBwdWJsaWMgaW50IGdldFN0YXJ0UG9zKEpDVHJlZSB0cmVlKSB7CiAgICAgICAgcmV0dXJuIFRyZWVJbmZvLmdldFN0YXJ0UG9zKHRyZWUpOwogICAgfQoKICAgIC8qKgogICAgICogR2V0IHRoZSBlbmQgcG9zaXRpb24gZm9yIGEgdHJlZSBub2RlLiAgVGhlIGVuZCBwb3NpdGlvbiBpcwogICAgICogZGVmaW5lZCB0byBiZSB0aGUgcG9zaXRpb24gb2YgdGhlIGxhc3QgY2hhcmFjdGVyIG9mIHRoZSBsYXN0CiAgICAgKiB0b2tlbiBvZiB0aGUgbm9kZSdzIHNvdXJjZSB0ZXh0LiAgUmV0dXJucyBQb3NpdGlvbi5OT1BPUyBpZiBlbmQKICAgICAqIHBvc2l0aW9ucyBhcmUgbm90IGdlbmVyYXRlZCBvciB0aGUgcG9zaXRpb24gaXMgb3RoZXJ3aXNlIG5vdAogICAgICogZm91bmQuCiAgICAgKiBAcGFyYW0gdHJlZSAgVGhlIHRyZWUgbm9kZQogICAgICovCiAgICBwdWJsaWMgaW50IGdldEVuZFBvcyhKQ1RyZWUgdHJlZSkgewogICAgICAgIHJldHVybiBlbmRQb3NUYWJsZS5nZXRFbmRQb3ModHJlZSk7CiAgICB9CgoKCi8qIC0tLS0tLS0tLS0gcGFyc2luZyAtLS0tLS0tLS0tLS0tLSAqLwoKICAgIC8qKgogICAgICogSWRlbnQgPSBJREVOVElGSUVSCiAgICAgKi8KICAgIHB1YmxpYyBOYW1lIGlkZW50KCkgewogICAgICAgIHJldHVybiBpZGVudChmYWxzZSk7CiAgICB9CgogICAgcHJvdGVjdGVkIE5hbWUgaWRlbnQoYm9vbGVhbiBhZHZhbmNlT25FcnJvcnMpIHsKICAgICAgICBpZiAodG9rZW4ua2luZCA9PSBJREVOVElGSUVSKSB7CiAgICAgICAgICAgIE5hbWUgbmFtZSA9IHRva2VuLm5hbWUoKTsKICAgICAgICAgICAgbmV4dFRva2VuKCk7CiAgICAgICAgICAgIHJldHVybiBuYW1lOwogICAgICAgIH0gZWxzZSBpZiAodG9rZW4ua2luZCA9PSBBU1NFUlQpIHsKICAgICAgICAgICAgZXJyb3IodG9rZW4ucG9zLCAiYXNzZXJ0LmFzLmlkZW50aWZpZXIiKTsKICAgICAgICAgICAgbmV4dFRva2VuKCk7CiAgICAgICAgICAgIHJldHVybiBuYW1lcy5lcnJvcjsKICAgICAgICB9IGVsc2UgaWYgKHRva2VuLmtpbmQgPT0gRU5VTSkgewogICAgICAgICAgICBlcnJvcih0b2tlbi5wb3MsICJlbnVtLmFzLmlkZW50aWZpZXIiKTsKICAgICAgICAgICAgbmV4dFRva2VuKCk7CiAgICAgICAgICAgIHJldHVybiBuYW1lcy5lcnJvcjsKICAgICAgICB9IGVsc2UgaWYgKHRva2VuLmtpbmQgPT0gVEhJUykgewogICAgICAgICAgICBpZiAoYWxsb3dUaGlzSWRlbnQpIHsKICAgICAgICAgICAgICAgIC8vIE1ha2Ugc3VyZSB3ZSdyZSB1c2luZyBhIHN1cHBvcnRlZCBzb3VyY2UgdmVyc2lvbi4KICAgICAgICAgICAgICAgIGNoZWNrVHlwZUFubm90YXRpb25zKCk7CiAgICAgICAgICAgICAgICBOYW1lIG5hbWUgPSB0b2tlbi5uYW1lKCk7CiAgICAgICAgICAgICAgICBuZXh0VG9rZW4oKTsKICAgICAgICAgICAgICAgIHJldHVybiBuYW1lOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgZXJyb3IodG9rZW4ucG9zLCAidGhpcy5hcy5pZGVudGlmaWVyIik7CiAgICAgICAgICAgICAgICBuZXh0VG9rZW4oKTsKICAgICAgICAgICAgICAgIHJldHVybiBuYW1lcy5lcnJvcjsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSBpZiAodG9rZW4ua2luZCA9PSBVTkRFUlNDT1JFKSB7CiAgICAgICAgICAgIGlmIChhbGxvd1VuZGVyc2NvcmVJZGVudGlmaWVyKSB7CiAgICAgICAgICAgICAgICB3YXJuaW5nKHRva2VuLnBvcywgInVuZGVyc2NvcmUuYXMuaWRlbnRpZmllciIpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgZXJyb3IodG9rZW4ucG9zLCAidW5kZXJzY29yZS5hcy5pZGVudGlmaWVyIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgTmFtZSBuYW1lID0gdG9rZW4ubmFtZSgpOwogICAgICAgICAgICBuZXh0VG9rZW4oKTsKICAgICAgICAgICAgcmV0dXJuIG5hbWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgYWNjZXB0KElERU5USUZJRVIpOwogICAgICAgICAgICBpZiAoYWR2YW5jZU9uRXJyb3JzKSB7CiAgICAgICAgICAgICAgICBuZXh0VG9rZW4oKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gbmFtZXMuZXJyb3I7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogUXVhbGlkZW50ID0gSWRlbnQgeyBET1QgW0Fubm90YXRpb25zXSBJZGVudCB9CiAgICAgKi8KICAgIHB1YmxpYyBKQ0V4cHJlc3Npb24gcXVhbGlkZW50KGJvb2xlYW4gYWxsb3dBbm5vcykgewogICAgICAgIEpDRXhwcmVzc2lvbiB0ID0gdG9QKEYuYXQodG9rZW4ucG9zKS5JZGVudChpZGVudCgpKSk7CiAgICAgICAgd2hpbGUgKHRva2VuLmtpbmQgPT0gRE9UKSB7CiAgICAgICAgICAgIGludCBwb3MgPSB0b2tlbi5wb3M7CiAgICAgICAgICAgIG5leHRUb2tlbigpOwogICAgICAgICAgICBMaXN0PEpDQW5ub3RhdGlvbj4gdHlhbm5vcyA9IG51bGw7CiAgICAgICAgICAgIGlmIChhbGxvd0Fubm9zKSB7CiAgICAgICAgICAgICAgICB0eWFubm9zID0gdHlwZUFubm90YXRpb25zT3B0KCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdCA9IHRvUChGLmF0KHBvcykuU2VsZWN0KHQsIGlkZW50KCkpKTsKICAgICAgICAgICAgaWYgKHR5YW5ub3MgIT0gbnVsbCAmJiB0eWFubm9zLm5vbkVtcHR5KCkpIHsKICAgICAgICAgICAgICAgIHQgPSB0b1AoRi5hdCh0eWFubm9zLmhlYWQucG9zKS5Bbm5vdGF0ZWRUeXBlKHR5YW5ub3MsIHQpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gdDsKICAgIH0KCiAgICBKQ0V4cHJlc3Npb24gbGl0ZXJhbChOYW1lIHByZWZpeCkgewogICAgICAgIHJldHVybiBsaXRlcmFsKHByZWZpeCwgdG9rZW4ucG9zKTsKICAgIH0KCiAgICAvKioKICAgICAqIExpdGVyYWwgPQogICAgICogICAgIElOVExJVEVSQUwKICAgICAqICAgfCBMT05HTElURVJBTAogICAgICogICB8IEZMT0FUTElURVJBTAogICAgICogICB8IERPVUJMRUxJVEVSQUwKICAgICAqICAgfCBDSEFSTElURVJBTAogICAgICogICB8IFNUUklOR0xJVEVSQUwKICAgICAqICAgfCBUUlVFCiAgICAgKiAgIHwgRkFMU0UKICAgICAqICAgfCBOVUxMCiAgICAgKi8KICAgIEpDRXhwcmVzc2lvbiBsaXRlcmFsKE5hbWUgcHJlZml4LCBpbnQgcG9zKSB7CiAgICAgICAgSkNFeHByZXNzaW9uIHQgPSBlcnJvclRyZWU7CiAgICAgICAgc3dpdGNoICh0b2tlbi5raW5kKSB7CiAgICAgICAgY2FzZSBJTlRMSVRFUkFMOgogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgdCA9IEYuYXQocG9zKS5MaXRlcmFsKAogICAgICAgICAgICAgICAgICAgIFR5cGVUYWcuSU5ULAogICAgICAgICAgICAgICAgICAgIENvbnZlcnQuc3RyaW5nMmludChzdHJ2YWwocHJlZml4KSwgdG9rZW4ucmFkaXgoKSkpOwogICAgICAgICAgICB9IGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gZXgpIHsKICAgICAgICAgICAgICAgIGVycm9yKHRva2VuLnBvcywgImludC5udW1iZXIudG9vLmxhcmdlIiwgc3RydmFsKHByZWZpeCkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgTE9OR0xJVEVSQUw6CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICB0ID0gRi5hdChwb3MpLkxpdGVyYWwoCiAgICAgICAgICAgICAgICAgICAgVHlwZVRhZy5MT05HLAogICAgICAgICAgICAgICAgICAgIExvbmcudmFsdWVPZihDb252ZXJ0LnN0cmluZzJsb25nKHN0cnZhbChwcmVmaXgpLCB0b2tlbi5yYWRpeCgpKSkpOwogICAgICAgICAgICB9IGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gZXgpIHsKICAgICAgICAgICAgICAgIGVycm9yKHRva2VuLnBvcywgImludC5udW1iZXIudG9vLmxhcmdlIiwgc3RydmFsKHByZWZpeCkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgRkxPQVRMSVRFUkFMOiB7CiAgICAgICAgICAgIFN0cmluZyBwcm9wZXIgPSB0b2tlbi5yYWRpeCgpID09IDE2ID8KICAgICAgICAgICAgICAgICAgICAoIjB4IisgdG9rZW4uc3RyaW5nVmFsKCkpIDoKICAgICAgICAgICAgICAgICAgICB0b2tlbi5zdHJpbmdWYWwoKTsKICAgICAgICAgICAgRmxvYXQgbjsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIG4gPSBGbG9hdC52YWx1ZU9mKHByb3Blcik7CiAgICAgICAgICAgIH0gY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBleCkgewogICAgICAgICAgICAgICAgLy8gZXJyb3IgYWxyZWFkeSByZXBvcnRlZCBpbiBzY2FubmVyCiAgICAgICAgICAgICAgICBuID0gRmxvYXQuTmFOOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChuLmZsb2F0VmFsdWUoKSA9PSAwLjBmICYmICFpc1plcm8ocHJvcGVyKSkKICAgICAgICAgICAgICAgIGVycm9yKHRva2VuLnBvcywgImZwLm51bWJlci50b28uc21hbGwiKTsKICAgICAgICAgICAgZWxzZSBpZiAobi5mbG9hdFZhbHVlKCkgPT0gRmxvYXQuUE9TSVRJVkVfSU5GSU5JVFkpCiAgICAgICAgICAgICAgICBlcnJvcih0b2tlbi5wb3MsICJmcC5udW1iZXIudG9vLmxhcmdlIik7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHQgPSBGLmF0KHBvcykuTGl0ZXJhbChUeXBlVGFnLkZMT0FULCBuKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGNhc2UgRE9VQkxFTElURVJBTDogewogICAgICAgICAgICBTdHJpbmcgcHJvcGVyID0gdG9rZW4ucmFkaXgoKSA9PSAxNiA/CiAgICAgICAgICAgICAgICAgICAgKCIweCIrIHRva2VuLnN0cmluZ1ZhbCgpKSA6CiAgICAgICAgICAgICAgICAgICAgdG9rZW4uc3RyaW5nVmFsKCk7CiAgICAgICAgICAgIERvdWJsZSBuOwogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgbiA9IERvdWJsZS52YWx1ZU9mKHByb3Blcik7CiAgICAgICAgICAgIH0gY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBleCkgewogICAgICAgICAgICAgICAgLy8gZXJyb3IgYWxyZWFkeSByZXBvcnRlZCBpbiBzY2FubmVyCiAgICAgICAgICAgICAgICBuID0gRG91YmxlLk5hTjsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAobi5kb3VibGVWYWx1ZSgpID09IDAuMGQgJiYgIWlzWmVybyhwcm9wZXIpKQogICAgICAgICAgICAgICAgZXJyb3IodG9rZW4ucG9zLCAiZnAubnVtYmVyLnRvby5zbWFsbCIpOwogICAgICAgICAgICBlbHNlIGlmIChuLmRvdWJsZVZhbHVlKCkgPT0gRG91YmxlLlBPU0lUSVZFX0lORklOSVRZKQogICAgICAgICAgICAgICAgZXJyb3IodG9rZW4ucG9zLCAiZnAubnVtYmVyLnRvby5sYXJnZSIpOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB0ID0gRi5hdChwb3MpLkxpdGVyYWwoVHlwZVRhZy5ET1VCTEUsIG4pOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgY2FzZSBDSEFSTElURVJBTDoKICAgICAgICAgICAgdCA9IEYuYXQocG9zKS5MaXRlcmFsKAogICAgICAgICAgICAgICAgVHlwZVRhZy5DSEFSLAogICAgICAgICAgICAgICAgdG9rZW4uc3RyaW5nVmFsKCkuY2hhckF0KDApICsgMCk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgU1RSSU5HTElURVJBTDoKICAgICAgICAgICAgdCA9IEYuYXQocG9zKS5MaXRlcmFsKAogICAgICAgICAgICAgICAgVHlwZVRhZy5DTEFTUywKICAgICAgICAgICAgICAgIHRva2VuLnN0cmluZ1ZhbCgpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBUUlVFOiBjYXNlIEZBTFNFOgogICAgICAgICAgICB0ID0gRi5hdChwb3MpLkxpdGVyYWwoCiAgICAgICAgICAgICAgICBUeXBlVGFnLkJPT0xFQU4sCiAgICAgICAgICAgICAgICAodG9rZW4ua2luZCA9PSBUUlVFID8gMSA6IDApKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBOVUxMOgogICAgICAgICAgICB0ID0gRi5hdChwb3MpLkxpdGVyYWwoCiAgICAgICAgICAgICAgICBUeXBlVGFnLkJPVCwKICAgICAgICAgICAgICAgIG51bGwpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBBc3NlcnQuZXJyb3IoKTsKICAgICAgICB9CiAgICAgICAgaWYgKHQgPT0gZXJyb3JUcmVlKQogICAgICAgICAgICB0ID0gRi5hdChwb3MpLkVycm9uZW91cygpOwogICAgICAgIHN0b3JlRW5kKHQsIHRva2VuLmVuZFBvcyk7CiAgICAgICAgbmV4dFRva2VuKCk7CiAgICAgICAgcmV0dXJuIHQ7CiAgICB9CiAgICAvL3doZXJlCiAgICAgICAgYm9vbGVhbiBpc1plcm8oU3RyaW5nIHMpIHsKICAgICAgICAgICAgY2hhcltdIGNzID0gcy50b0NoYXJBcnJheSgpOwogICAgICAgICAgICBpbnQgYmFzZSA9ICgoY3MubGVuZ3RoID4gMSAmJiBDaGFyYWN0ZXIudG9Mb3dlckNhc2UoY3NbMV0pID09ICd4JykgPyAxNiA6IDEwKTsKICAgICAgICAgICAgaW50IGkgPSAoKGJhc2U9PTE2KSA/IDIgOiAwKTsKICAgICAgICAgICAgd2hpbGUgKGkgPCBjcy5sZW5ndGggJiYgKGNzW2ldID09ICcwJyB8fCBjc1tpXSA9PSAnLicpKSBpKys7CiAgICAgICAgICAgIHJldHVybiAhKGkgPCBjcy5sZW5ndGggJiYgKENoYXJhY3Rlci5kaWdpdChjc1tpXSwgYmFzZSkgPiAwKSk7CiAgICAgICAgfQoKICAgICAgICBTdHJpbmcgc3RydmFsKE5hbWUgcHJlZml4KSB7CiAgICAgICAgICAgIFN0cmluZyBzID0gdG9rZW4uc3RyaW5nVmFsKCk7CiAgICAgICAgICAgIHJldHVybiBwcmVmaXguaXNFbXB0eSgpID8gcyA6IHByZWZpeCArIHM7CiAgICAgICAgfQoKICAgIC8qKiB0ZXJtcyBjYW4gYmUgZWl0aGVyIGV4cHJlc3Npb25zIG9yIHR5cGVzLgogICAgICovCiAgICBwdWJsaWMgSkNFeHByZXNzaW9uIHBhcnNlRXhwcmVzc2lvbigpIHsKICAgICAgICByZXR1cm4gdGVybShFWFBSKTsKICAgIH0KCiAgICAvKioKICAgICAqIHBhcnNlcyAob3B0aW9uYWwpIHR5cGUgYW5ub3RhdGlvbnMgZm9sbG93ZWQgYnkgYSB0eXBlLiBJZiB0aGUKICAgICAqIGFubm90YXRpb25zIGFyZSBwcmVzZW50IGJlZm9yZSB0aGUgdHlwZSBhbmQgYXJlIG5vdCBjb25zdW1lZCBkdXJpbmcgYXJyYXkKICAgICAqIHBhcnNpbmcsIHRoaXMgbWV0aG9kIHJldHVybnMgYSB7QGxpbmsgSkNBbm5vdGF0ZWRUeXBlfSBjb25zaXN0aW5nIG9mCiAgICAgKiB0aGVzZSBhbm5vdGF0aW9ucyBhbmQgdGhlIHVuZGVybHlpbmcgdHlwZS4gT3RoZXJ3aXNlLCBpdCByZXR1cm5zIHRoZQogICAgICogdW5kZXJseWluZyB0eXBlLgogICAgICoKICAgICAqIDxwPgogICAgICoKICAgICAqIE5vdGUgdGhhdCB0aGlzIG1ldGhvZCBzZXRzIHtAY29kZSBtb2RlfSB0byB7QGNvZGUgVFlQRX0gZmlyc3QsIGJlZm9yZQogICAgICogcGFyc2luZyBhbm5vdGF0aW9ucy4KICAgICAqLwogICAgcHVibGljIEpDRXhwcmVzc2lvbiBwYXJzZVR5cGUoKSB7CiAgICAgICAgTGlzdDxKQ0Fubm90YXRpb24+IGFubm90YXRpb25zID0gdHlwZUFubm90YXRpb25zT3B0KCk7CiAgICAgICAgcmV0dXJuIHBhcnNlVHlwZShhbm5vdGF0aW9ucyk7CiAgICB9CgogICAgcHVibGljIEpDRXhwcmVzc2lvbiBwYXJzZVR5cGUoTGlzdDxKQ0Fubm90YXRpb24+IGFubm90YXRpb25zKSB7CiAgICAgICAgSkNFeHByZXNzaW9uIHJlc3VsdCA9IHVuYW5ub3RhdGVkVHlwZSgpOwoKICAgICAgICBpZiAoYW5ub3RhdGlvbnMubm9uRW1wdHkoKSkgewogICAgICAgICAgICByZXN1bHQgPSBpbnNlcnRBbm5vdGF0aW9uc1RvTW9zdElubmVyKHJlc3VsdCwgYW5ub3RhdGlvbnMsIGZhbHNlKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9CgogICAgcHVibGljIEpDRXhwcmVzc2lvbiB1bmFubm90YXRlZFR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHRlcm0oVFlQRSk7CiAgICB9CgogICAgcHJvdGVjdGVkIEpDRXhwcmVzc2lvbiB0ZXJtKGludCBuZXdtb2RlKSB7CiAgICAgICAgaW50IHByZXZtb2RlID0gbW9kZTsKICAgICAgICBtb2RlID0gbmV3bW9kZTsKICAgICAgICBKQ0V4cHJlc3Npb24gdCA9IHRlcm0oKTsKICAgICAgICBsYXN0bW9kZSA9IG1vZGU7CiAgICAgICAgbW9kZSA9IHByZXZtb2RlOwogICAgICAgIHJldHVybiB0OwogICAgfQoKICAgIC8qKgogICAgICogIHtAbGl0ZXJhbAogICAgICogIEV4cHJlc3Npb24gPSBFeHByZXNzaW9uMSBbRXhwcmVzc2lvblJlc3RdCiAgICAgKiAgRXhwcmVzc2lvblJlc3QgPSBbQXNzaWdubWVudE9wZXJhdG9yIEV4cHJlc3Npb24xXQogICAgICogIEFzc2lnbm1lbnRPcGVyYXRvciA9ICI9IiB8ICIrPSIgfCAiLT0iIHwgIio9IiB8ICIvPSIgfAogICAgICogICAgICAgICAgICAgICAgICAgICAgICImPSIgfCAifD0iIHwgIl49IiB8CiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgIiU9IiB8ICI8PD0iIHwgIj4+PSIgfCAiPj4+PSIKICAgICAqICBUeXBlID0gVHlwZTEKICAgICAqICBUeXBlTm9QYXJhbXMgPSBUeXBlTm9QYXJhbXMxCiAgICAgKiAgU3RhdGVtZW50RXhwcmVzc2lvbiA9IEV4cHJlc3Npb24KICAgICAqICBDb25zdGFudEV4cHJlc3Npb24gPSBFeHByZXNzaW9uCiAgICAgKiAgfQogICAgICovCiAgICBKQ0V4cHJlc3Npb24gdGVybSgpIHsKICAgICAgICBKQ0V4cHJlc3Npb24gdCA9IHRlcm0xKCk7CiAgICAgICAgaWYgKChtb2RlICYgRVhQUikgIT0gMCAmJgogICAgICAgICAgICB0b2tlbi5raW5kID09IEVRIHx8IFBMVVNFUS5jb21wYXJlVG8odG9rZW4ua2luZCkgPD0gMCAmJiB0b2tlbi5raW5kLmNvbXBhcmVUbyhHVEdUR1RFUSkgPD0gMCkKICAgICAgICAgICAgcmV0dXJuIHRlcm1SZXN0KHQpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgcmV0dXJuIHQ7CiAgICB9CgogICAgSkNFeHByZXNzaW9uIHRlcm1SZXN0KEpDRXhwcmVzc2lvbiB0KSB7CiAgICAgICAgc3dpdGNoICh0b2tlbi5raW5kKSB7CiAgICAgICAgY2FzZSBFUTogewogICAgICAgICAgICBpbnQgcG9zID0gdG9rZW4ucG9zOwogICAgICAgICAgICBuZXh0VG9rZW4oKTsKICAgICAgICAgICAgbW9kZSA9IEVYUFI7CiAgICAgICAgICAgIEpDRXhwcmVzc2lvbiB0MSA9IHRlcm0oKTsKICAgICAgICAgICAgcmV0dXJuIHRvUChGLmF0KHBvcykuQXNzaWduKHQsIHQxKSk7CiAgICAgICAgfQogICAgICAgIGNhc2UgUExVU0VROgogICAgICAgIGNhc2UgU1VCRVE6CiAgICAgICAgY2FzZSBTVEFSRVE6CiAgICAgICAgY2FzZSBTTEFTSEVROgogICAgICAgIGNhc2UgUEVSQ0VOVEVROgogICAgICAgIGNhc2UgQU1QRVE6CiAgICAgICAgY2FzZSBCQVJFUToKICAgICAgICBjYXNlIENBUkVURVE6CiAgICAgICAgY2FzZSBMVExURVE6CiAgICAgICAgY2FzZSBHVEdURVE6CiAgICAgICAgY2FzZSBHVEdUR1RFUToKICAgICAgICAgICAgaW50IHBvcyA9IHRva2VuLnBvczsKICAgICAgICAgICAgVG9rZW5LaW5kIHRrID0gdG9rZW4ua2luZDsKICAgICAgICAgICAgbmV4dFRva2VuKCk7CiAgICAgICAgICAgIG1vZGUgPSBFWFBSOwogICAgICAgICAgICBKQ0V4cHJlc3Npb24gdDEgPSB0ZXJtKCk7CiAgICAgICAgICAgIHJldHVybiBGLmF0KHBvcykuQXNzaWdub3Aob3B0YWcodGspLCB0LCB0MSk7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgcmV0dXJuIHQ7CiAgICAgICAgfQogICAgfQoKICAgIC8qKiBFeHByZXNzaW9uMSAgID0gRXhwcmVzc2lvbjIgW0V4cHJlc3Npb24xUmVzdF0KICAgICAqICBUeXBlMSAgICAgICAgID0gVHlwZTIKICAgICAqICBUeXBlTm9QYXJhbXMxID0gVHlwZU5vUGFyYW1zMgogICAgICovCiAgICBKQ0V4cHJlc3Npb24gdGVybTEoKSB7CiAgICAgICAgSkNFeHByZXNzaW9uIHQgPSB0ZXJtMigpOwogICAgICAgIGlmICgobW9kZSAmIEVYUFIpICE9IDAgJiYgdG9rZW4ua2luZCA9PSBRVUVTKSB7CiAgICAgICAgICAgIG1vZGUgPSBFWFBSOwogICAgICAgICAgICByZXR1cm4gdGVybTFSZXN0KHQpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiB0OwogICAgICAgIH0KICAgIH0KCiAgICAvKiogRXhwcmVzc2lvbjFSZXN0ID0gWyI/IiBFeHByZXNzaW9uICI6IiBFeHByZXNzaW9uMV0KICAgICAqLwogICAgSkNFeHByZXNzaW9uIHRlcm0xUmVzdChKQ0V4cHJlc3Npb24gdCkgewogICAgICAgIGlmICh0b2tlbi5raW5kID09IFFVRVMpIHsKICAgICAgICAgICAgaW50IHBvcyA9IHRva2VuLnBvczsKICAgICAgICAgICAgbmV4dFRva2VuKCk7CiAgICAgICAgICAgIEpDRXhwcmVzc2lvbiB0MSA9IHRlcm0oKTsKICAgICAgICAgICAgYWNjZXB0KENPTE9OKTsKICAgICAgICAgICAgSkNFeHByZXNzaW9uIHQyID0gdGVybTEoKTsKICAgICAgICAgICAgcmV0dXJuIEYuYXQocG9zKS5Db25kaXRpb25hbCh0LCB0MSwgdDIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiB0OwogICAgICAgIH0KICAgIH0KCiAgICAvKiogRXhwcmVzc2lvbjIgICA9IEV4cHJlc3Npb24zIFtFeHByZXNzaW9uMlJlc3RdCiAgICAgKiAgVHlwZTIgICAgICAgICA9IFR5cGUzCiAgICAgKiAgVHlwZU5vUGFyYW1zMiA9IFR5cGVOb1BhcmFtczMKICAgICAqLwogICAgSkNFeHByZXNzaW9uIHRlcm0yKCkgewogICAgICAgIEpDRXhwcmVzc2lvbiB0ID0gdGVybTMoKTsKICAgICAgICBpZiAoKG1vZGUgJiBFWFBSKSAhPSAwICYmIHByZWModG9rZW4ua2luZCkgPj0gVHJlZUluZm8ub3JQcmVjKSB7CiAgICAgICAgICAgIG1vZGUgPSBFWFBSOwogICAgICAgICAgICByZXR1cm4gdGVybTJSZXN0KHQsIFRyZWVJbmZvLm9yUHJlYyk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIHQ7CiAgICAgICAgfQogICAgfQoKICAgIC8qICBFeHByZXNzaW9uMlJlc3QgPSB7aW5maXhvcCBFeHByZXNzaW9uM30KICAgICAqICAgICAgICAgICAgICAgICAgfCBFeHByZXNzaW9uMyBpbnN0YW5jZW9mIFR5cGUKICAgICAqICBpbmZpeG9wICAgICAgICAgPSAifHwiCiAgICAgKiAgICAgICAgICAgICAgICAgIHwgIiYmIgogICAgICogICAgICAgICAgICAgICAgICB8ICJ8IgogICAgICogICAgICAgICAgICAgICAgICB8ICJeIgogICAgICogICAgICAgICAgICAgICAgICB8ICImIgogICAgICogICAgICAgICAgICAgICAgICB8ICI9PSIgfCAiIT0iCiAgICAgKiAgICAgICAgICAgICAgICAgIHwgIjwiIHwgIj4iIHwgIjw9IiB8ICI+PSIKICAgICAqICAgICAgICAgICAgICAgICAgfCAiPDwiIHwgIj4+IiB8ICI+Pj4iCiAgICAgKiAgICAgICAgICAgICAgICAgIHwgIisiIHwgIi0iCiAgICAgKiAgICAgICAgICAgICAgICAgIHwgIioiIHwgIi8iIHwgIiUiCiAgICAgKi8KICAgIEpDRXhwcmVzc2lvbiB0ZXJtMlJlc3QoSkNFeHByZXNzaW9uIHQsIGludCBtaW5wcmVjKSB7CiAgICAgICAgSkNFeHByZXNzaW9uW10gb2RTdGFjayA9IG5ld09kU3RhY2soKTsKICAgICAgICBUb2tlbltdIG9wU3RhY2sgPSBuZXdPcFN0YWNrKCk7CgogICAgICAgIC8vIG9wdGltaXphdGlvbiwgd2FzIG9kU3RhY2sgPSBuZXcgVHJlZVsuLi5dOyBvcFN0YWNrID0gbmV3IFRyZWVbLi4uXTsKICAgICAgICBpbnQgdG9wID0gMDsKICAgICAgICBvZFN0YWNrWzBdID0gdDsKICAgICAgICBpbnQgc3RhcnRQb3MgPSB0b2tlbi5wb3M7CiAgICAgICAgVG9rZW4gdG9wT3AgPSBUb2tlbnMuRFVNTVk7CiAgICAgICAgd2hpbGUgKHByZWModG9rZW4ua2luZCkgPj0gbWlucHJlYykgewogICAgICAgICAgICBvcFN0YWNrW3RvcF0gPSB0b3BPcDsKICAgICAgICAgICAgdG9wKys7CiAgICAgICAgICAgIHRvcE9wID0gdG9rZW47CiAgICAgICAgICAgIG5leHRUb2tlbigpOwogICAgICAgICAgICBvZFN0YWNrW3RvcF0gPSAodG9wT3Aua2luZCA9PSBJTlNUQU5DRU9GKSA/IHBhcnNlVHlwZSgpIDogdGVybTMoKTsKICAgICAgICAgICAgd2hpbGUgKHRvcCA+IDAgJiYgcHJlYyh0b3BPcC5raW5kKSA+PSBwcmVjKHRva2VuLmtpbmQpKSB7CiAgICAgICAgICAgICAgICBvZFN0YWNrW3RvcC0xXSA9IG1ha2VPcCh0b3BPcC5wb3MsIHRvcE9wLmtpbmQsIG9kU3RhY2tbdG9wLTFdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2RTdGFja1t0b3BdKTsKICAgICAgICAgICAgICAgIHRvcC0tOwogICAgICAgICAgICAgICAgdG9wT3AgPSBvcFN0YWNrW3RvcF07CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgQXNzZXJ0LmNoZWNrKHRvcCA9PSAwKTsKICAgICAgICB0ID0gb2RTdGFja1swXTsKCiAgICAgICAgaWYgKHQuaGFzVGFnKEpDVHJlZS5UYWcuUExVUykpIHsKICAgICAgICAgICAgdCA9IGZvbGRTdHJpbmdzKHQpOwogICAgICAgIH0KCiAgICAgICAgb2RTdGFja1N1cHBseS5hZGQob2RTdGFjayk7CiAgICAgICAgb3BTdGFja1N1cHBseS5hZGQob3BTdGFjayk7CiAgICAgICAgcmV0dXJuIHQ7CiAgICB9CiAgICAvL3doZXJlCiAgICAgICAgLyoqIENvbnN0cnVjdCBhIGJpbmFyeSBvciB0eXBlIHRlc3Qgbm9kZS4KICAgICAgICAgKi8KICAgICAgICBwcml2YXRlIEpDRXhwcmVzc2lvbiBtYWtlT3AoaW50IHBvcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVG9rZW5LaW5kIHRvcE9wLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBKQ0V4cHJlc3Npb24gb2QxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBKQ0V4cHJlc3Npb24gb2QyKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKHRvcE9wID09IElOU1RBTkNFT0YpIHsKICAgICAgICAgICAgICAgIHJldHVybiBGLmF0KHBvcykuVHlwZVRlc3Qob2QxLCBvZDIpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcmV0dXJuIEYuYXQocG9zKS5CaW5hcnkob3B0YWcodG9wT3ApLCBvZDEsIG9kMik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLyoqIElmIHRyZWUgaXMgYSBjb25jYXRlbmF0aW9uIG9mIHN0cmluZyBsaXRlcmFscywgcmVwbGFjZSBpdAogICAgICAgICAqICBieSBhIHNpbmdsZSBsaXRlcmFsIHJlcHJlc2VudGluZyB0aGUgY29uY2F0ZW5hdGVkIHN0cmluZy4KICAgICAgICAgKi8KICAgICAgICBwcm90ZWN0ZWQgSkNFeHByZXNzaW9uIGZvbGRTdHJpbmdzKEpDRXhwcmVzc2lvbiB0cmVlKSB7CiAgICAgICAgICAgIGlmICghYWxsb3dTdHJpbmdGb2xkaW5nKQogICAgICAgICAgICAgICAgcmV0dXJuIHRyZWU7CiAgICAgICAgICAgIExpc3RCdWZmZXI8SkNFeHByZXNzaW9uPiBvcFN0YWNrID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgICAgICBMaXN0QnVmZmVyPEpDTGl0ZXJhbD4gbGl0QnVmID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgICAgICBib29sZWFuIG5lZWRzRm9sZGluZyA9IGZhbHNlOwogICAgICAgICAgICBKQ0V4cHJlc3Npb24gY3VyciA9IHRyZWU7CiAgICAgICAgICAgIHdoaWxlICh0cnVlKSB7CiAgICAgICAgICAgICAgICBpZiAoY3Vyci5oYXNUYWcoSkNUcmVlLlRhZy5QTFVTKSkgewogICAgICAgICAgICAgICAgICAgIEpDQmluYXJ5IG9wID0gKEpDQmluYXJ5KWN1cnI7CiAgICAgICAgICAgICAgICAgICAgbmVlZHNGb2xkaW5nIHw9IGZvbGRJZk5lZWRlZChvcC5yaHMsIGxpdEJ1Ziwgb3BTdGFjaywgZmFsc2UpOwogICAgICAgICAgICAgICAgICAgIGN1cnIgPSBvcC5saHM7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIG5lZWRzRm9sZGluZyB8PSBmb2xkSWZOZWVkZWQoY3VyciwgbGl0QnVmLCBvcFN0YWNrLCB0cnVlKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsgLy9sYXN0IG9uZSEKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAobmVlZHNGb2xkaW5nKSB7CiAgICAgICAgICAgICAgICBMaXN0PEpDRXhwcmVzc2lvbj4gb3BzID0gb3BTdGFjay50b0xpc3QoKTsKICAgICAgICAgICAgICAgIEpDRXhwcmVzc2lvbiByZXMgPSBvcHMuaGVhZDsKICAgICAgICAgICAgICAgIGZvciAoSkNFeHByZXNzaW9uIG9wIDogb3BzLnRhaWwpIHsKICAgICAgICAgICAgICAgICAgICByZXMgPSBGLmF0KG9wLmdldFN0YXJ0UG9zaXRpb24oKSkuQmluYXJ5KG9wdGFnKFRva2VuS2luZC5QTFVTKSwgcmVzLCBvcCk7CiAgICAgICAgICAgICAgICAgICAgc3RvcmVFbmQocmVzLCBnZXRFbmRQb3Mob3ApKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiByZXM7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJlZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBib29sZWFuIGZvbGRJZk5lZWRlZChKQ0V4cHJlc3Npb24gdHJlZSwgTGlzdEJ1ZmZlcjxKQ0xpdGVyYWw+IGxpdEJ1ZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTGlzdEJ1ZmZlcjxKQ0V4cHJlc3Npb24+IG9wU3RhY2ssIGJvb2xlYW4gbGFzdCkgewogICAgICAgICAgICBKQ0xpdGVyYWwgc3RyID0gc3RyaW5nTGl0ZXJhbCh0cmVlKTsKICAgICAgICAgICAgaWYgKHN0ciAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICBsaXRCdWYucHJlcGVuZChzdHIpOwogICAgICAgICAgICAgICAgcmV0dXJuIGxhc3QgJiYgbWVyZ2UobGl0QnVmLCBvcFN0YWNrKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGJvb2xlYW4gcmVzID0gbWVyZ2UobGl0QnVmLCBvcFN0YWNrKTsKICAgICAgICAgICAgICAgIGxpdEJ1Zi5jbGVhcigpOwogICAgICAgICAgICAgICAgb3BTdGFjay5wcmVwZW5kKHRyZWUpOwogICAgICAgICAgICAgICAgcmV0dXJuIHJlczsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgYm9vbGVhbiBtZXJnZShMaXN0QnVmZmVyPEpDTGl0ZXJhbD4gbGl0QnVmLCBMaXN0QnVmZmVyPEpDRXhwcmVzc2lvbj4gb3BTdGFjaykgewogICAgICAgICAgICBpZiAobGl0QnVmLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9IGVsc2UgaWYgKGxpdEJ1Zi5zaXplKCkgPT0gMSkgewogICAgICAgICAgICAgICAgb3BTdGFjay5wcmVwZW5kKGxpdEJ1Zi5maXJzdCgpKTsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIEpDRXhwcmVzc2lvbiB0ID0gRi5hdChsaXRCdWYuZmlyc3QoKS5nZXRTdGFydFBvc2l0aW9uKCkpLkxpdGVyYWwoVHlwZVRhZy5DTEFTUywKICAgICAgICAgICAgICAgICAgICAgICAgbGl0QnVmLnN0cmVhbSgpLm1hcChsaXQgLT4gKFN0cmluZylsaXQuZ2V0VmFsdWUoKSkuY29sbGVjdChDb2xsZWN0b3JzLmpvaW5pbmcoKSkpOwogICAgICAgICAgICAgICAgc3RvcmVFbmQodCwgbGl0QnVmLmxhc3QoKS5nZXRFbmRQb3NpdGlvbihlbmRQb3NUYWJsZSkpOwogICAgICAgICAgICAgICAgb3BTdGFjay5wcmVwZW5kKHQpOwogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHByaXZhdGUgSkNMaXRlcmFsIHN0cmluZ0xpdGVyYWwoSkNUcmVlIHRyZWUpIHsKICAgICAgICAgICAgaWYgKHRyZWUuaGFzVGFnKExJVEVSQUwpKSB7CiAgICAgICAgICAgICAgICBKQ0xpdGVyYWwgbGl0ID0gKEpDTGl0ZXJhbCl0cmVlOwogICAgICAgICAgICAgICAgaWYgKGxpdC50eXBldGFnID09IFR5cGVUYWcuQ0xBU1MpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbGl0OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCgogICAgICAgIC8qKiBvcHRpbWl6YXRpb246IFRvIHNhdmUgYWxsb2NhdGluZyBhIG5ldyBvcGVyYW5kL29wZXJhdG9yIHN0YWNrCiAgICAgICAgICogIGZvciBldmVyeSBiaW5hcnkgb3BlcmF0aW9uLCB3ZSB1c2Ugc3VwcGx5cy4KICAgICAgICAgKi8KICAgICAgICBBcnJheUxpc3Q8SkNFeHByZXNzaW9uW10+IG9kU3RhY2tTdXBwbHkgPSBuZXcgQXJyYXlMaXN0PD4oKTsKICAgICAgICBBcnJheUxpc3Q8VG9rZW5bXT4gb3BTdGFja1N1cHBseSA9IG5ldyBBcnJheUxpc3Q8PigpOwoKICAgICAgICBwcml2YXRlIEpDRXhwcmVzc2lvbltdIG5ld09kU3RhY2soKSB7CiAgICAgICAgICAgIGlmIChvZFN0YWNrU3VwcGx5LmlzRW1wdHkoKSkKICAgICAgICAgICAgICAgIHJldHVybiBuZXcgSkNFeHByZXNzaW9uW2luZml4UHJlY2VkZW5jZUxldmVscyArIDFdOwogICAgICAgICAgICByZXR1cm4gb2RTdGFja1N1cHBseS5yZW1vdmUob2RTdGFja1N1cHBseS5zaXplKCkgLSAxKTsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgVG9rZW5bXSBuZXdPcFN0YWNrKCkgewogICAgICAgICAgICBpZiAob3BTdGFja1N1cHBseS5pc0VtcHR5KCkpCiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFRva2VuW2luZml4UHJlY2VkZW5jZUxldmVscyArIDFdOwogICAgICAgICAgICByZXR1cm4gb3BTdGFja1N1cHBseS5yZW1vdmUob3BTdGFja1N1cHBseS5zaXplKCkgLSAxKTsKICAgICAgICB9CgogICAgLyoqCiAgICAgKiAgRXhwcmVzc2lvbjMgICAgPSBQcmVmaXhPcCBFeHByZXNzaW9uMwogICAgICogICAgICAgICAgICAgICAgIHwgIigiIEV4cHIgfCBUeXBlTm9QYXJhbXMgIikiIEV4cHJlc3Npb24zCiAgICAgKiAgICAgICAgICAgICAgICAgfCBQcmltYXJ5IHtTZWxlY3Rvcn0ge1Bvc3RmaXhPcH0KICAgICAqCiAgICAgKiAge0BsaXRlcmFsCiAgICAgKiAgUHJpbWFyeSAgICAgICAgPSAiKCIgRXhwcmVzc2lvbiAiKSIKICAgICAqICAgICAgICAgICAgICAgICB8IExpdGVyYWwKICAgICAqICAgICAgICAgICAgICAgICB8IFtUeXBlQXJndW1lbnRzXSBUSElTIFtBcmd1bWVudHNdCiAgICAgKiAgICAgICAgICAgICAgICAgfCBbVHlwZUFyZ3VtZW50c10gU1VQRVIgU3VwZXJTdWZmaXgKICAgICAqICAgICAgICAgICAgICAgICB8IE5FVyBbVHlwZUFyZ3VtZW50c10gQ3JlYXRvcgogICAgICogICAgICAgICAgICAgICAgIHwgIigiIEFyZ3VtZW50cyAiKSIgIi0+IiAoIEV4cHJlc3Npb24gfCBCbG9jayApCiAgICAgKiAgICAgICAgICAgICAgICAgfCBJZGVudCAiLT4iICggRXhwcmVzc2lvbiB8IEJsb2NrICkKICAgICAqICAgICAgICAgICAgICAgICB8IFtBbm5vdGF0aW9uc10gSWRlbnQgeyAiLiIgW0Fubm90YXRpb25zXSBJZGVudCB9CiAgICAgKiAgICAgICAgICAgICAgICAgfCBFeHByZXNzaW9uMyBNZW1iZXJSZWZlcmVuY2VTdWZmaXgKICAgICAqICAgICAgICAgICAgICAgICAgIFsgW0Fubm90YXRpb25zXSAiWyIgKCAiXSIgQnJhY2tldHNPcHQgIi4iIENMQVNTIHwgRXhwcmVzc2lvbiAiXSIgKQogICAgICogICAgICAgICAgICAgICAgICAgfCBBcmd1bWVudHMKICAgICAqICAgICAgICAgICAgICAgICAgIHwgIi4iICggQ0xBU1MgfCBUSElTIHwgW1R5cGVBcmd1bWVudHNdIFNVUEVSIEFyZ3VtZW50cyB8IE5FVyBbVHlwZUFyZ3VtZW50c10gSW5uZXJDcmVhdG9yICkKICAgICAqICAgICAgICAgICAgICAgICAgIF0KICAgICAqICAgICAgICAgICAgICAgICB8IEJhc2ljVHlwZSBCcmFja2V0c09wdCAiLiIgQ0xBU1MKICAgICAqICB9CiAgICAgKgogICAgICogIFByZWZpeE9wICAgICAgID0gIisrIiB8ICItLSIgfCAiISIgfCAifiIgfCAiKyIgfCAiLSIKICAgICAqICBQb3N0Zml4T3AgICAgICA9ICIrKyIgfCAiLS0iCiAgICAgKiAgVHlwZTMgICAgICAgICAgPSBJZGVudCB7ICIuIiBJZGVudCB9IFtUeXBlQXJndW1lbnRzXSB7VHlwZVNlbGVjdG9yfSBCcmFja2V0c09wdAogICAgICogICAgICAgICAgICAgICAgIHwgQmFzaWNUeXBlCiAgICAgKiAgVHlwZU5vUGFyYW1zMyAgPSBJZGVudCB7ICIuIiBJZGVudCB9IEJyYWNrZXRzT3B0CiAgICAgKiAgU2VsZWN0b3IgICAgICAgPSAiLiIgW1R5cGVBcmd1bWVudHNdIElkZW50IFtBcmd1bWVudHNdCiAgICAgKiAgICAgICAgICAgICAgICAgfCAiLiIgVEhJUwogICAgICogICAgICAgICAgICAgICAgIHwgIi4iIFtUeXBlQXJndW1lbnRzXSBTVVBFUiBTdXBlclN1ZmZpeAogICAgICogICAgICAgICAgICAgICAgIHwgIi4iIE5FVyBbVHlwZUFyZ3VtZW50c10gSW5uZXJDcmVhdG9yCiAgICAgKiAgICAgICAgICAgICAgICAgfCAiWyIgRXhwcmVzc2lvbiAiXSIKICAgICAqICBUeXBlU2VsZWN0b3IgICA9ICIuIiBJZGVudCBbVHlwZUFyZ3VtZW50c10KICAgICAqICBTdXBlclN1ZmZpeCAgICA9IEFyZ3VtZW50cyB8ICIuIiBJZGVudCBbQXJndW1lbnRzXQogICAgICovCiAgICBwcm90ZWN0ZWQgSkNFeHByZXNzaW9uIHRlcm0zKCkgewogICAgICAgIGludCBwb3MgPSB0b2tlbi5wb3M7CiAgICAgICAgSkNFeHByZXNzaW9uIHQ7CiAgICAgICAgTGlzdDxKQ0V4cHJlc3Npb24+IHR5cGVBcmdzID0gdHlwZUFyZ3VtZW50c09wdChFWFBSKTsKICAgICAgICBzd2l0Y2ggKHRva2VuLmtpbmQpIHsKICAgICAgICBjYXNlIFFVRVM6CiAgICAgICAgICAgIGlmICgobW9kZSAmIFRZUEUpICE9IDAgJiYgKG1vZGUgJiAoVFlQRUFSR3xOT1BBUkFNUykpID09IFRZUEVBUkcpIHsKICAgICAgICAgICAgICAgIG1vZGUgPSBUWVBFOwogICAgICAgICAgICAgICAgcmV0dXJuIHR5cGVBcmd1bWVudCgpOwogICAgICAgICAgICB9IGVsc2UKICAgICAgICAgICAgICAgIHJldHVybiBpbGxlZ2FsKCk7CiAgICAgICAgY2FzZSBQTFVTUExVUzogY2FzZSBTVUJTVUI6IGNhc2UgQkFORzogY2FzZSBUSUxERTogY2FzZSBQTFVTOiBjYXNlIFNVQjoKICAgICAgICAgICAgaWYgKHR5cGVBcmdzID09IG51bGwgJiYgKG1vZGUgJiBFWFBSKSAhPSAwKSB7CiAgICAgICAgICAgICAgICBUb2tlbktpbmQgdGsgPSB0b2tlbi5raW5kOwogICAgICAgICAgICAgICAgbmV4dFRva2VuKCk7CiAgICAgICAgICAgICAgICBtb2RlID0gRVhQUjsKICAgICAgICAgICAgICAgIGlmICh0ayA9PSBTVUIgJiYKICAgICAgICAgICAgICAgICAgICAodG9rZW4ua2luZCA9PSBJTlRMSVRFUkFMIHx8IHRva2VuLmtpbmQgPT0gTE9OR0xJVEVSQUwpICYmCiAgICAgICAgICAgICAgICAgICAgdG9rZW4ucmFkaXgoKSA9PSAxMCkgewogICAgICAgICAgICAgICAgICAgIG1vZGUgPSBFWFBSOwogICAgICAgICAgICAgICAgICAgIHQgPSBsaXRlcmFsKG5hbWVzLmh5cGhlbiwgcG9zKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgdCA9IHRlcm0zKCk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEYuYXQocG9zKS5VbmFyeSh1bm9wdGFnKHRrKSwgdCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSByZXR1cm4gaWxsZWdhbCgpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIExQQVJFTjoKICAgICAgICAgICAgaWYgKHR5cGVBcmdzID09IG51bGwgJiYgKG1vZGUgJiBFWFBSKSAhPSAwKSB7CiAgICAgICAgICAgICAgICBQYXJlbnNSZXN1bHQgcHJlcyA9IGFuYWx5emVQYXJlbnMoKTsKICAgICAgICAgICAgICAgIHN3aXRjaCAocHJlcykgewogICAgICAgICAgICAgICAgICAgIGNhc2UgQ0FTVDoKICAgICAgICAgICAgICAgICAgICAgICBhY2NlcHQoTFBBUkVOKTsKICAgICAgICAgICAgICAgICAgICAgICBtb2RlID0gVFlQRTsKICAgICAgICAgICAgICAgICAgICAgICBpbnQgcG9zMSA9IHBvczsKICAgICAgICAgICAgICAgICAgICAgICBMaXN0PEpDRXhwcmVzc2lvbj4gdGFyZ2V0cyA9IExpc3Qub2YodCA9IHRlcm0zKCkpOwogICAgICAgICAgICAgICAgICAgICAgIHdoaWxlICh0b2tlbi5raW5kID09IEFNUCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICBjaGVja0ludGVyc2VjdGlvblR5cGVzSW5DYXN0KCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgIGFjY2VwdChBTVApOwogICAgICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXRzID0gdGFyZ2V0cy5wcmVwZW5kKHRlcm0zKCkpOwogICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICBpZiAodGFyZ2V0cy5sZW5ndGgoKSA+IDEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgdCA9IHRvUChGLmF0KHBvczEpLlR5cGVJbnRlcnNlY3Rpb24odGFyZ2V0cy5yZXZlcnNlKCkpKTsKICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgYWNjZXB0KFJQQVJFTik7CiAgICAgICAgICAgICAgICAgICAgICAgbW9kZSA9IEVYUFI7CiAgICAgICAgICAgICAgICAgICAgICAgSkNFeHByZXNzaW9uIHQxID0gdGVybTMoKTsKICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gRi5hdChwb3MpLlR5cGVDYXN0KHQsIHQxKTsKICAgICAgICAgICAgICAgICAgICBjYXNlIElNUExJQ0lUX0xBTUJEQToKICAgICAgICAgICAgICAgICAgICBjYXNlIEVYUExJQ0lUX0xBTUJEQToKICAgICAgICAgICAgICAgICAgICAgICAgdCA9IGxhbWJkYUV4cHJlc3Npb25PclN0YXRlbWVudCh0cnVlLCBwcmVzID09IFBhcmVuc1Jlc3VsdC5FWFBMSUNJVF9MQU1CREEsIHBvcyk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6IC8vUEFSRU5TCiAgICAgICAgICAgICAgICAgICAgICAgIGFjY2VwdChMUEFSRU4pOwogICAgICAgICAgICAgICAgICAgICAgICBtb2RlID0gRVhQUjsKICAgICAgICAgICAgICAgICAgICAgICAgdCA9IHRlcm1SZXN0KHRlcm0xUmVzdCh0ZXJtMlJlc3QodGVybTMoKSwgVHJlZUluZm8ub3JQcmVjKSkpOwogICAgICAgICAgICAgICAgICAgICAgICBhY2NlcHQoUlBBUkVOKTsKICAgICAgICAgICAgICAgICAgICAgICAgdCA9IHRvUChGLmF0KHBvcykuUGFyZW5zKHQpKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICByZXR1cm4gaWxsZWdhbCgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgVEhJUzoKICAgICAgICAgICAgaWYgKChtb2RlICYgRVhQUikgIT0gMCkgewogICAgICAgICAgICAgICAgbW9kZSA9IEVYUFI7CiAgICAgICAgICAgICAgICB0ID0gdG8oRi5hdChwb3MpLklkZW50KG5hbWVzLl90aGlzKSk7CiAgICAgICAgICAgICAgICBuZXh0VG9rZW4oKTsKICAgICAgICAgICAgICAgIGlmICh0eXBlQXJncyA9PSBudWxsKQogICAgICAgICAgICAgICAgICAgIHQgPSBhcmd1bWVudHNPcHQobnVsbCwgdCk7CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgdCA9IGFyZ3VtZW50cyh0eXBlQXJncywgdCk7CiAgICAgICAgICAgICAgICB0eXBlQXJncyA9IG51bGw7CiAgICAgICAgICAgIH0gZWxzZSByZXR1cm4gaWxsZWdhbCgpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFNVUEVSOgogICAgICAgICAgICBpZiAoKG1vZGUgJiBFWFBSKSAhPSAwKSB7CiAgICAgICAgICAgICAgICBtb2RlID0gRVhQUjsKICAgICAgICAgICAgICAgIHQgPSB0byhGLmF0KHBvcykuSWRlbnQobmFtZXMuX3N1cGVyKSk7CiAgICAgICAgICAgICAgICB0ID0gc3VwZXJTdWZmaXgodHlwZUFyZ3MsIHQpOwogICAgICAgICAgICAgICAgdHlwZUFyZ3MgPSBudWxsOwogICAgICAgICAgICB9IGVsc2UgcmV0dXJuIGlsbGVnYWwoKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBJTlRMSVRFUkFMOiBjYXNlIExPTkdMSVRFUkFMOiBjYXNlIEZMT0FUTElURVJBTDogY2FzZSBET1VCTEVMSVRFUkFMOgogICAgICAgIGNhc2UgQ0hBUkxJVEVSQUw6IGNhc2UgU1RSSU5HTElURVJBTDoKICAgICAgICBjYXNlIFRSVUU6IGNhc2UgRkFMU0U6IGNhc2UgTlVMTDoKICAgICAgICAgICAgaWYgKHR5cGVBcmdzID09IG51bGwgJiYgKG1vZGUgJiBFWFBSKSAhPSAwKSB7CiAgICAgICAgICAgICAgICBtb2RlID0gRVhQUjsKICAgICAgICAgICAgICAgIHQgPSBsaXRlcmFsKG5hbWVzLmVtcHR5KTsKICAgICAgICAgICAgfSBlbHNlIHJldHVybiBpbGxlZ2FsKCk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgTkVXOgogICAgICAgICAgICBpZiAodHlwZUFyZ3MgIT0gbnVsbCkgcmV0dXJuIGlsbGVnYWwoKTsKICAgICAgICAgICAgaWYgKChtb2RlICYgRVhQUikgIT0gMCkgewogICAgICAgICAgICAgICAgbW9kZSA9IEVYUFI7CiAgICAgICAgICAgICAgICBuZXh0VG9rZW4oKTsKICAgICAgICAgICAgICAgIGlmICh0b2tlbi5raW5kID09IExUKSB0eXBlQXJncyA9IHR5cGVBcmd1bWVudHMoZmFsc2UpOwogICAgICAgICAgICAgICAgdCA9IGNyZWF0b3IocG9zLCB0eXBlQXJncyk7CiAgICAgICAgICAgICAgICB0eXBlQXJncyA9IG51bGw7CiAgICAgICAgICAgIH0gZWxzZSByZXR1cm4gaWxsZWdhbCgpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIE1PTktFWVNfQVQ6CiAgICAgICAgICAgIC8vIE9ubHkgYW5ub3RhdGVkIGNhc3QgdHlwZXMgYW5kIG1ldGhvZCByZWZlcmVuY2VzIGFyZSB2YWxpZAogICAgICAgICAgICBMaXN0PEpDQW5ub3RhdGlvbj4gdHlwZUFubm9zID0gdHlwZUFubm90YXRpb25zT3B0KCk7CiAgICAgICAgICAgIGlmICh0eXBlQW5ub3MuaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgICAvLyBlbHNlIHRoZXJlIHdvdWxkIGJlIG5vICdAJwogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCJFeHBlY3RlZCB0eXBlIGFubm90YXRpb25zLCBidXQgZm91bmQgbm9uZSEiKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgSkNFeHByZXNzaW9uIGV4cHIgPSB0ZXJtMygpOwoKICAgICAgICAgICAgaWYgKChtb2RlICYgVFlQRSkgPT0gMCkgewogICAgICAgICAgICAgICAgLy8gVHlwZSBhbm5vdGF0aW9ucyBvbiBjbGFzcyBsaXRlcmFscyBubyBsb25nZXIgbGVnYWwKICAgICAgICAgICAgICAgIHN3aXRjaCAoZXhwci5nZXRUYWcoKSkgewogICAgICAgICAgICAgICAgY2FzZSBSRUZFUkVOQ0U6IHsKICAgICAgICAgICAgICAgICAgICBKQ01lbWJlclJlZmVyZW5jZSBtcmVmID0gKEpDTWVtYmVyUmVmZXJlbmNlKSBleHByOwogICAgICAgICAgICAgICAgICAgIG1yZWYuZXhwciA9IHRvUChGLmF0KHBvcykuQW5ub3RhdGVkVHlwZSh0eXBlQW5ub3MsIG1yZWYuZXhwcikpOwogICAgICAgICAgICAgICAgICAgIHQgPSBtcmVmOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgY2FzZSBTRUxFQ1Q6IHsKICAgICAgICAgICAgICAgICAgICBKQ0ZpZWxkQWNjZXNzIHNlbCA9IChKQ0ZpZWxkQWNjZXNzKSBleHByOwoKICAgICAgICAgICAgICAgICAgICBpZiAoc2VsLm5hbWUgIT0gbmFtZXMuX2NsYXNzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBpbGxlZ2FsKCk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgbG9nLmVycm9yKHRva2VuLnBvcywgIm5vLmFubm90YXRpb25zLm9uLmRvdC5jbGFzcyIpOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZXhwcjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgIHJldHVybiBpbGxlZ2FsKHR5cGVBbm5vcy5oZWFkLnBvcyk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgLy8gVHlwZSBhbm5vdGF0aW9ucyB0YXJnZXRpbmcgYSBjYXN0CiAgICAgICAgICAgICAgICB0ID0gaW5zZXJ0QW5ub3RhdGlvbnNUb01vc3RJbm5lcihleHByLCB0eXBlQW5ub3MsIGZhbHNlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFVOREVSU0NPUkU6IGNhc2UgSURFTlRJRklFUjogY2FzZSBBU1NFUlQ6IGNhc2UgRU5VTToKICAgICAgICAgICAgaWYgKHR5cGVBcmdzICE9IG51bGwpIHJldHVybiBpbGxlZ2FsKCk7CiAgICAgICAgICAgIGlmICgobW9kZSAmIEVYUFIpICE9IDAgJiYgcGVla1Rva2VuKEFSUk9XKSkgewogICAgICAgICAgICAgICAgdCA9IGxhbWJkYUV4cHJlc3Npb25PclN0YXRlbWVudChmYWxzZSwgZmFsc2UsIHBvcyk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB0ID0gdG9QKEYuYXQodG9rZW4ucG9zKS5JZGVudChpZGVudCgpKSk7CiAgICAgICAgICAgICAgICBsb29wOiB3aGlsZSAodHJ1ZSkgewogICAgICAgICAgICAgICAgICAgIHBvcyA9IHRva2VuLnBvczsKICAgICAgICAgICAgICAgICAgICBmaW5hbCBMaXN0PEpDQW5ub3RhdGlvbj4gYW5ub3MgPSB0eXBlQW5ub3RhdGlvbnNPcHQoKTsKCiAgICAgICAgICAgICAgICAgICAgLy8gbmVlZCB0byByZXBvcnQgYW4gZXJyb3IgbGF0ZXIgaWYgTEJSQUNLRVQgaXMgZm9yIGFycmF5CiAgICAgICAgICAgICAgICAgICAgLy8gaW5kZXggYWNjZXNzIHJhdGhlciB0aGFuIGFycmF5IGNyZWF0aW9uIGxldmVsCiAgICAgICAgICAgICAgICAgICAgaWYgKCFhbm5vcy5pc0VtcHR5KCkgJiYgdG9rZW4ua2luZCAhPSBMQlJBQ0tFVCAmJiB0b2tlbi5raW5kICE9IEVMTElQU0lTKQogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaWxsZWdhbChhbm5vcy5oZWFkLnBvcyk7CgogICAgICAgICAgICAgICAgICAgIHN3aXRjaCAodG9rZW4ua2luZCkgewogICAgICAgICAgICAgICAgICAgIGNhc2UgTEJSQUNLRVQ6CiAgICAgICAgICAgICAgICAgICAgICAgIG5leHRUb2tlbigpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAodG9rZW4ua2luZCA9PSBSQlJBQ0tFVCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV4dFRva2VuKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ID0gYnJhY2tldHNPcHQodCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ID0gdG9QKEYuYXQocG9zKS5UeXBlQXJyYXkodCkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFubm9zLm5vbkVtcHR5KCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ID0gdG9QKEYuYXQocG9zKS5Bbm5vdGF0ZWRUeXBlKGFubm9zLCB0KSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ID0gYnJhY2tldHNTdWZmaXgodCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoKG1vZGUgJiBFWFBSKSAhPSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9kZSA9IEVYUFI7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSkNFeHByZXNzaW9uIHQxID0gdGVybSgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghYW5ub3MuaXNFbXB0eSgpKSB0ID0gaWxsZWdhbChhbm5vcy5oZWFkLnBvcyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdCA9IHRvKEYuYXQocG9zKS5JbmRleGVkKHQsIHQxKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhY2NlcHQoUkJSQUNLRVQpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrIGxvb3A7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBMUEFSRU46CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgobW9kZSAmIEVYUFIpICE9IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vZGUgPSBFWFBSOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdCA9IGFyZ3VtZW50cyh0eXBlQXJncywgdCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWFubm9zLmlzRW1wdHkoKSkgdCA9IGlsbGVnYWwoYW5ub3MuaGVhZC5wb3MpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZUFyZ3MgPSBudWxsOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrIGxvb3A7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBET1Q6CiAgICAgICAgICAgICAgICAgICAgICAgIG5leHRUb2tlbigpOwogICAgICAgICAgICAgICAgICAgICAgICBpbnQgb2xkbW9kZSA9IG1vZGU7CiAgICAgICAgICAgICAgICAgICAgICAgIG1vZGUgJj0gfk5PUEFSQU1TOwogICAgICAgICAgICAgICAgICAgICAgICB0eXBlQXJncyA9IHR5cGVBcmd1bWVudHNPcHQoRVhQUik7CiAgICAgICAgICAgICAgICAgICAgICAgIG1vZGUgPSBvbGRtb2RlOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoKG1vZGUgJiBFWFBSKSAhPSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKHRva2VuLmtpbmQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgQ0xBU1M6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVBcmdzICE9IG51bGwpIHJldHVybiBpbGxlZ2FsKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9kZSA9IEVYUFI7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdCA9IHRvKEYuYXQocG9zKS5TZWxlY3QodCwgbmFtZXMuX2NsYXNzKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV4dFRva2VuKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWsgbG9vcDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgVEhJUzoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZUFyZ3MgIT0gbnVsbCkgcmV0dXJuIGlsbGVnYWwoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb2RlID0gRVhQUjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ID0gdG8oRi5hdChwb3MpLlNlbGVjdCh0LCBuYW1lcy5fdGhpcykpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5leHRUb2tlbigpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrIGxvb3A7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFNVUEVSOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vZGUgPSBFWFBSOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHQgPSB0byhGLmF0KHBvcykuU2VsZWN0KHQsIG5hbWVzLl9zdXBlcikpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHQgPSBzdXBlclN1ZmZpeCh0eXBlQXJncywgdCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZUFyZ3MgPSBudWxsOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrIGxvb3A7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIE5FVzoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZUFyZ3MgIT0gbnVsbCkgcmV0dXJuIGlsbGVnYWwoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb2RlID0gRVhQUjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgcG9zMSA9IHRva2VuLnBvczsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXh0VG9rZW4oKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodG9rZW4ua2luZCA9PSBMVCkgdHlwZUFyZ3MgPSB0eXBlQXJndW1lbnRzKGZhbHNlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ID0gaW5uZXJDcmVhdG9yKHBvczEsIHR5cGVBcmdzLCB0KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlQXJncyA9IG51bGw7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWsgbG9vcDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgTGlzdDxKQ0Fubm90YXRpb24+IHR5YW5ub3MgPSBudWxsOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoKG1vZGUgJiBUWVBFKSAhPSAwICYmIHRva2VuLmtpbmQgPT0gTU9OS0VZU19BVCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlhbm5vcyA9IHR5cGVBbm5vdGF0aW9uc09wdCgpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHR5cGVBcmdzIHNhdmVkIGZvciBuZXh0IGxvb3AgaXRlcmF0aW9uLgogICAgICAgICAgICAgICAgICAgICAgICB0ID0gdG9QKEYuYXQocG9zKS5TZWxlY3QodCwgaWRlbnQoKSkpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlhbm5vcyAhPSBudWxsICYmIHR5YW5ub3Mubm9uRW1wdHkoKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdCA9IHRvUChGLmF0KHR5YW5ub3MuaGVhZC5wb3MpLkFubm90YXRlZFR5cGUodHlhbm5vcywgdCkpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgRUxMSVBTSVM6CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnBlcm1pdFR5cGVBbm5vdGF0aW9uc1B1c2hCYWNrKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnR5cGVBbm5vdGF0aW9uc1B1c2hlZEJhY2sgPSBhbm5vczsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChhbm5vcy5ub25FbXB0eSgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBEb24ndCByZXR1cm4gaGVyZSAtLSBlcnJvciByZWNvdmVyeSBhdHRlbXB0CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbGxlZ2FsKGFubm9zLmhlYWQucG9zKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBicmVhayBsb29wOwogICAgICAgICAgICAgICAgICAgIGNhc2UgTFQ6CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgobW9kZSAmIFRZUEUpID09IDAgJiYgaXNVbmJvdW5kTWVtYmVyUmVmKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vdGhpcyBpcyBhbiB1bmJvdW5kIG1ldGhvZCByZWZlcmVuY2Ugd2hvc2UgcXVhbGlmaWVyCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2lzIGEgZ2VuZXJpYyB0eXBlIGkuZS4gQTxTPjo6bQogICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHBvczEgPSB0b2tlbi5wb3M7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhY2NlcHQoTFQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgTGlzdEJ1ZmZlcjxKQ0V4cHJlc3Npb24+IGFyZ3MgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmdzLmFwcGVuZCh0eXBlQXJndW1lbnQoKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAodG9rZW4ua2luZCA9PSBDT01NQSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5leHRUb2tlbigpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyZ3MuYXBwZW5kKHR5cGVBcmd1bWVudCgpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFjY2VwdChHVCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ID0gdG9QKEYuYXQocG9zMSkuVHlwZUFwcGx5KHQsIGFyZ3MudG9MaXN0KCkpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlICh0b2tlbi5raW5kID09IERPVCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5leHRUb2tlbigpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vZGUgPSBUWVBFOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHQgPSB0b1AoRi5hdCh0b2tlbi5wb3MpLlNlbGVjdCh0LCBpZGVudCgpKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdCA9IHR5cGVBcmd1bWVudHNPcHQodCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ID0gYnJhY2tldHNPcHQodCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodG9rZW4ua2luZCAhPSBDT0xDT0wpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL21ldGhvZCByZWZlcmVuY2UgZXhwZWN0ZWQgaGVyZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHQgPSBpbGxlZ2FsKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb2RlID0gRVhQUjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0ZXJtM1Jlc3QodCwgdHlwZUFyZ3MpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrIGxvb3A7CiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWsgbG9vcDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHR5cGVBcmdzICE9IG51bGwpIGlsbGVnYWwoKTsKICAgICAgICAgICAgdCA9IHR5cGVBcmd1bWVudHNPcHQodCk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgQllURTogY2FzZSBTSE9SVDogY2FzZSBDSEFSOiBjYXNlIElOVDogY2FzZSBMT05HOiBjYXNlIEZMT0FUOgogICAgICAgIGNhc2UgRE9VQkxFOiBjYXNlIEJPT0xFQU46CiAgICAgICAgICAgIGlmICh0eXBlQXJncyAhPSBudWxsKSBpbGxlZ2FsKCk7CiAgICAgICAgICAgIHQgPSBicmFja2V0c1N1ZmZpeChicmFja2V0c09wdChiYXNpY1R5cGUoKSkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFZPSUQ6CiAgICAgICAgICAgIGlmICh0eXBlQXJncyAhPSBudWxsKSBpbGxlZ2FsKCk7CiAgICAgICAgICAgIGlmICgobW9kZSAmIEVYUFIpICE9IDApIHsKICAgICAgICAgICAgICAgIG5leHRUb2tlbigpOwogICAgICAgICAgICAgICAgaWYgKHRva2VuLmtpbmQgPT0gRE9UKSB7CiAgICAgICAgICAgICAgICAgICAgSkNQcmltaXRpdmVUeXBlVHJlZSB0aSA9IHRvUChGLmF0KHBvcykuVHlwZUlkZW50KFR5cGVUYWcuVk9JRCkpOwogICAgICAgICAgICAgICAgICAgIHQgPSBicmFja2V0c1N1ZmZpeCh0aSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBpbGxlZ2FsKHBvcyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvLyBTdXBwb3J0IHRoZSBjb3JuZXIgY2FzZSBvZiBteU1ldGhvZEhhbmRsZS48dm9pZD5pbnZva2UoKSBieSBwYXNzaW5nCiAgICAgICAgICAgICAgICAvLyBhIHZvaWQgdHlwZSAobGlrZSBvdGhlciBwcmltaXRpdmUgdHlwZXMpIHRvIHRoZSBuZXh0IHBoYXNlLgogICAgICAgICAgICAgICAgLy8gVGhlIGVycm9yIHdpbGwgYmUgcmVwb3J0ZWQgaW4gQXR0ci5hdHRyaWJUeXBlcyBvciBBdHRyLnZpc2l0QXBwbHkuCiAgICAgICAgICAgICAgICBKQ1ByaW1pdGl2ZVR5cGVUcmVlIHRpID0gdG8oRi5hdChwb3MpLlR5cGVJZGVudChUeXBlVGFnLlZPSUQpKTsKICAgICAgICAgICAgICAgIG5leHRUb2tlbigpOwogICAgICAgICAgICAgICAgcmV0dXJuIHRpOwogICAgICAgICAgICAgICAgLy9yZXR1cm4gaWxsZWdhbCgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHJldHVybiBpbGxlZ2FsKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0ZXJtM1Jlc3QodCwgdHlwZUFyZ3MpOwogICAgfQoKICAgIEpDRXhwcmVzc2lvbiB0ZXJtM1Jlc3QoSkNFeHByZXNzaW9uIHQsIExpc3Q8SkNFeHByZXNzaW9uPiB0eXBlQXJncykgewogICAgICAgIGlmICh0eXBlQXJncyAhPSBudWxsKSBpbGxlZ2FsKCk7CiAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgICAgaW50IHBvczEgPSB0b2tlbi5wb3M7CiAgICAgICAgICAgIGZpbmFsIExpc3Q8SkNBbm5vdGF0aW9uPiBhbm5vcyA9IHR5cGVBbm5vdGF0aW9uc09wdCgpOwoKICAgICAgICAgICAgaWYgKHRva2VuLmtpbmQgPT0gTEJSQUNLRVQpIHsKICAgICAgICAgICAgICAgIG5leHRUb2tlbigpOwogICAgICAgICAgICAgICAgaWYgKChtb2RlICYgVFlQRSkgIT0gMCkgewogICAgICAgICAgICAgICAgICAgIGludCBvbGRtb2RlID0gbW9kZTsKICAgICAgICAgICAgICAgICAgICBtb2RlID0gVFlQRTsKICAgICAgICAgICAgICAgICAgICBpZiAodG9rZW4ua2luZCA9PSBSQlJBQ0tFVCkgewogICAgICAgICAgICAgICAgICAgICAgICBuZXh0VG9rZW4oKTsKICAgICAgICAgICAgICAgICAgICAgICAgdCA9IGJyYWNrZXRzT3B0KHQpOwogICAgICAgICAgICAgICAgICAgICAgICB0ID0gdG9QKEYuYXQocG9zMSkuVHlwZUFycmF5KHQpKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRva2VuLmtpbmQgPT0gQ09MQ09MKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb2RlID0gRVhQUjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhbm5vcy5ub25FbXB0eSgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ID0gdG9QKEYuYXQocG9zMSkuQW5ub3RhdGVkVHlwZShhbm5vcywgdCkpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0OwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBtb2RlID0gb2xkbW9kZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICgobW9kZSAmIEVYUFIpICE9IDApIHsKICAgICAgICAgICAgICAgICAgICBtb2RlID0gRVhQUjsKICAgICAgICAgICAgICAgICAgICBKQ0V4cHJlc3Npb24gdDEgPSB0ZXJtKCk7CiAgICAgICAgICAgICAgICAgICAgdCA9IHRvKEYuYXQocG9zMSkuSW5kZXhlZCh0LCB0MSkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYWNjZXB0KFJCUkFDS0VUKTsKICAgICAgICAgICAgfSBlbHNlIGlmICh0b2tlbi5raW5kID09IERPVCkgewogICAgICAgICAgICAgICAgbmV4dFRva2VuKCk7CiAgICAgICAgICAgICAgICB0eXBlQXJncyA9IHR5cGVBcmd1bWVudHNPcHQoRVhQUik7CiAgICAgICAgICAgICAgICBpZiAodG9rZW4ua2luZCA9PSBTVVBFUiAmJiAobW9kZSAmIEVYUFIpICE9IDApIHsKICAgICAgICAgICAgICAgICAgICBtb2RlID0gRVhQUjsKICAgICAgICAgICAgICAgICAgICB0ID0gdG8oRi5hdChwb3MxKS5TZWxlY3QodCwgbmFtZXMuX3N1cGVyKSk7CiAgICAgICAgICAgICAgICAgICAgbmV4dFRva2VuKCk7CiAgICAgICAgICAgICAgICAgICAgdCA9IGFyZ3VtZW50cyh0eXBlQXJncywgdCk7CiAgICAgICAgICAgICAgICAgICAgdHlwZUFyZ3MgPSBudWxsOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmICh0b2tlbi5raW5kID09IE5FVyAmJiAobW9kZSAmIEVYUFIpICE9IDApIHsKICAgICAgICAgICAgICAgICAgICBpZiAodHlwZUFyZ3MgIT0gbnVsbCkgcmV0dXJuIGlsbGVnYWwoKTsKICAgICAgICAgICAgICAgICAgICBtb2RlID0gRVhQUjsKICAgICAgICAgICAgICAgICAgICBpbnQgcG9zMiA9IHRva2VuLnBvczsKICAgICAgICAgICAgICAgICAgICBuZXh0VG9rZW4oKTsKICAgICAgICAgICAgICAgICAgICBpZiAodG9rZW4ua2luZCA9PSBMVCkgdHlwZUFyZ3MgPSB0eXBlQXJndW1lbnRzKGZhbHNlKTsKICAgICAgICAgICAgICAgICAgICB0ID0gaW5uZXJDcmVhdG9yKHBvczIsIHR5cGVBcmdzLCB0KTsKICAgICAgICAgICAgICAgICAgICB0eXBlQXJncyA9IG51bGw7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIExpc3Q8SkNBbm5vdGF0aW9uPiB0eWFubm9zID0gbnVsbDsKICAgICAgICAgICAgICAgICAgICBpZiAoKG1vZGUgJiBUWVBFKSAhPSAwICYmIHRva2VuLmtpbmQgPT0gTU9OS0VZU19BVCkgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBpcyB0aGUgbW9kZSBjaGVjayBuZWVkZWQ/CiAgICAgICAgICAgICAgICAgICAgICAgIHR5YW5ub3MgPSB0eXBlQW5ub3RhdGlvbnNPcHQoKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgdCA9IHRvUChGLmF0KHBvczEpLlNlbGVjdCh0LCBpZGVudCh0cnVlKSkpOwogICAgICAgICAgICAgICAgICAgIGlmICh0eWFubm9zICE9IG51bGwgJiYgdHlhbm5vcy5ub25FbXB0eSgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHQgPSB0b1AoRi5hdCh0eWFubm9zLmhlYWQucG9zKS5Bbm5vdGF0ZWRUeXBlKHR5YW5ub3MsIHQpKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgdCA9IGFyZ3VtZW50c09wdCh0eXBlQXJncywgdHlwZUFyZ3VtZW50c09wdCh0KSk7CiAgICAgICAgICAgICAgICAgICAgdHlwZUFyZ3MgPSBudWxsOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgaWYgKChtb2RlICYgRVhQUikgIT0gMCAmJiB0b2tlbi5raW5kID09IENPTENPTCkgewogICAgICAgICAgICAgICAgbW9kZSA9IEVYUFI7CiAgICAgICAgICAgICAgICBpZiAodHlwZUFyZ3MgIT0gbnVsbCkgcmV0dXJuIGlsbGVnYWwoKTsKICAgICAgICAgICAgICAgIGFjY2VwdChDT0xDT0wpOwogICAgICAgICAgICAgICAgdCA9IG1lbWJlclJlZmVyZW5jZVN1ZmZpeChwb3MxLCB0KTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGlmICghYW5ub3MuaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHBlcm1pdFR5cGVBbm5vdGF0aW9uc1B1c2hCYWNrKQogICAgICAgICAgICAgICAgICAgICAgICB0eXBlQW5ub3RhdGlvbnNQdXNoZWRCYWNrID0gYW5ub3M7CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaWxsZWdhbChhbm5vcy5oZWFkLnBvcyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB3aGlsZSAoKHRva2VuLmtpbmQgPT0gUExVU1BMVVMgfHwgdG9rZW4ua2luZCA9PSBTVUJTVUIpICYmIChtb2RlICYgRVhQUikgIT0gMCkgewogICAgICAgICAgICBtb2RlID0gRVhQUjsKICAgICAgICAgICAgdCA9IHRvKEYuYXQodG9rZW4ucG9zKS5VbmFyeSgKICAgICAgICAgICAgICAgICAgdG9rZW4ua2luZCA9PSBQTFVTUExVUyA/IFBPU1RJTkMgOiBQT1NUREVDLCB0KSk7CiAgICAgICAgICAgIG5leHRUb2tlbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdG9QKHQpOwogICAgfQoKICAgIC8qKgogICAgICogSWYgd2Ugc2VlIGFuIGlkZW50aWZpZXIgZm9sbG93ZWQgYnkgYSAnJmx0OycgaXQgY291bGQgYmUgYW4gdW5ib3VuZAogICAgICogbWV0aG9kIHJlZmVyZW5jZSBvciBhIGJpbmFyeSBleHByZXNzaW9uLiBUbyBkaXNhbWJpZ3VhdGUsIGxvb2sgZm9yIGEKICAgICAqIG1hdGNoaW5nICcmZ3Q7JyBhbmQgc2VlIGlmIHRoZSBzdWJzZXF1ZW50IHRlcm1pbmFsIGlzIGVpdGhlciAnLicgb3IgJzo6Jy4KICAgICAqLwogICAgQFN1cHByZXNzV2FybmluZ3MoImZhbGx0aHJvdWdoIikKICAgIGJvb2xlYW4gaXNVbmJvdW5kTWVtYmVyUmVmKCkgewogICAgICAgIGludCBwb3MgPSAwLCBkZXB0aCA9IDA7CiAgICAgICAgb3V0ZXI6IGZvciAoVG9rZW4gdCA9IFMudG9rZW4ocG9zKSA7IDsgdCA9IFMudG9rZW4oKytwb3MpKSB7CiAgICAgICAgICAgIHN3aXRjaCAodC5raW5kKSB7CiAgICAgICAgICAgICAgICBjYXNlIElERU5USUZJRVI6IGNhc2UgVU5ERVJTQ09SRTogY2FzZSBRVUVTOiBjYXNlIEVYVEVORFM6IGNhc2UgU1VQRVI6CiAgICAgICAgICAgICAgICBjYXNlIERPVDogY2FzZSBSQlJBQ0tFVDogY2FzZSBMQlJBQ0tFVDogY2FzZSBDT01NQToKICAgICAgICAgICAgICAgIGNhc2UgQllURTogY2FzZSBTSE9SVDogY2FzZSBJTlQ6IGNhc2UgTE9ORzogY2FzZSBGTE9BVDoKICAgICAgICAgICAgICAgIGNhc2UgRE9VQkxFOiBjYXNlIEJPT0xFQU46IGNhc2UgQ0hBUjoKICAgICAgICAgICAgICAgIGNhc2UgTU9OS0VZU19BVDoKICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBjYXNlIExQQVJFTjoKICAgICAgICAgICAgICAgICAgICAvLyBza2lwIGFubm90YXRpb24gdmFsdWVzCiAgICAgICAgICAgICAgICAgICAgaW50IG5lc3RpbmcgPSAwOwogICAgICAgICAgICAgICAgICAgIGZvciAoOyA7IHBvcysrKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIFRva2VuS2luZCB0azIgPSBTLnRva2VuKHBvcykua2luZDsKICAgICAgICAgICAgICAgICAgICAgICAgc3dpdGNoICh0azIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgRU9GOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgTFBBUkVOOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5lc3RpbmcrKzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgUlBBUkVOOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5lc3RpbmctLTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobmVzdGluZyA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlIG91dGVyOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBjYXNlIExUOgogICAgICAgICAgICAgICAgICAgIGRlcHRoKys7IGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBHVEdUR1Q6CiAgICAgICAgICAgICAgICAgICAgZGVwdGgtLTsKICAgICAgICAgICAgICAgIGNhc2UgR1RHVDoKICAgICAgICAgICAgICAgICAgICBkZXB0aC0tOwogICAgICAgICAgICAgICAgY2FzZSBHVDoKICAgICAgICAgICAgICAgICAgICBkZXB0aC0tOwogICAgICAgICAgICAgICAgICAgIGlmIChkZXB0aCA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIFRva2VuS2luZCBuZXh0S2luZCA9IFMudG9rZW4ocG9zICsgMSkua2luZDsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXh0S2luZCA9PSBUb2tlbktpbmQuRE9UIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXh0S2luZCA9PSBUb2tlbktpbmQuTEJSQUNLRVQgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5leHRLaW5kID09IFRva2VuS2luZC5DT0xDT0w7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBJZiB3ZSBzZWUgYW4gaWRlbnRpZmllciBmb2xsb3dlZCBieSBhICcmbHQ7JyBpdCBjb3VsZCBiZSBhbiB1bmJvdW5kCiAgICAgKiBtZXRob2QgcmVmZXJlbmNlIG9yIGEgYmluYXJ5IGV4cHJlc3Npb24uIFRvIGRpc2FtYmlndWF0ZSwgbG9vayBmb3IgYQogICAgICogbWF0Y2hpbmcgJyZndDsnIGFuZCBzZWUgaWYgdGhlIHN1YnNlcXVlbnQgdGVybWluYWwgaXMgZWl0aGVyICcuJyBvciAnOjonLgogICAgICovCiAgICBAU3VwcHJlc3NXYXJuaW5ncygiZmFsbHRocm91Z2giKQogICAgUGFyZW5zUmVzdWx0IGFuYWx5emVQYXJlbnMoKSB7CiAgICAgICAgaW50IGRlcHRoID0gMDsKICAgICAgICBib29sZWFuIHR5cGUgPSBmYWxzZTsKICAgICAgICBvdXRlcjogZm9yIChpbnQgbG9va2FoZWFkID0gMCA7IDsgbG9va2FoZWFkKyspIHsKICAgICAgICAgICAgVG9rZW5LaW5kIHRrID0gUy50b2tlbihsb29rYWhlYWQpLmtpbmQ7CiAgICAgICAgICAgIHN3aXRjaCAodGspIHsKICAgICAgICAgICAgICAgIGNhc2UgQ09NTUE6CiAgICAgICAgICAgICAgICAgICAgdHlwZSA9IHRydWU7CiAgICAgICAgICAgICAgICBjYXNlIEVYVEVORFM6IGNhc2UgU1VQRVI6IGNhc2UgRE9UOiBjYXNlIEFNUDoKICAgICAgICAgICAgICAgICAgICAvL3NraXAKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgUVVFUzoKICAgICAgICAgICAgICAgICAgICBpZiAocGVla1Rva2VuKGxvb2thaGVhZCwgRVhURU5EUykgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBlZWtUb2tlbihsb29rYWhlYWQsIFNVUEVSKSkgewogICAgICAgICAgICAgICAgICAgICAgICAvL3dpbGRjYXJkcwogICAgICAgICAgICAgICAgICAgICAgICB0eXBlID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIEJZVEU6IGNhc2UgU0hPUlQ6IGNhc2UgSU5UOiBjYXNlIExPTkc6IGNhc2UgRkxPQVQ6CiAgICAgICAgICAgICAgICBjYXNlIERPVUJMRTogY2FzZSBCT09MRUFOOiBjYXNlIENIQVI6IGNhc2UgVk9JRDoKICAgICAgICAgICAgICAgICAgICBpZiAocGVla1Rva2VuKGxvb2thaGVhZCwgUlBBUkVOKSkgewogICAgICAgICAgICAgICAgICAgICAgICAvL1R5cGUsICcpJyAtPiBjYXN0CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBQYXJlbnNSZXN1bHQuQ0FTVDsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHBlZWtUb2tlbihsb29rYWhlYWQsIExBWF9JREVOVElGSUVSKSkgewogICAgICAgICAgICAgICAgICAgICAgICAvL1R5cGUsIElkZW50aWZpZXIvJ18nLydhc3NlcnQnLydlbnVtJyAtPiBleHBsaWNpdCBsYW1iZGEKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFBhcmVuc1Jlc3VsdC5FWFBMSUNJVF9MQU1CREE7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBMUEFSRU46CiAgICAgICAgICAgICAgICAgICAgaWYgKGxvb2thaGVhZCAhPSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vICcoJyBpbiBhIG5vbi1zdGFydGluZyBwb3NpdGlvbiAtPiBwYXJlbnMKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFBhcmVuc1Jlc3VsdC5QQVJFTlM7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChwZWVrVG9rZW4obG9va2FoZWFkLCBSUEFSRU4pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vICcoJywgJyknIC0+IGV4cGxpY2l0IGxhbWJkYQogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gUGFyZW5zUmVzdWx0LkVYUExJQ0lUX0xBTUJEQTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIFJQQVJFTjoKICAgICAgICAgICAgICAgICAgICAvLyBpZiB3ZSBoYXZlIHNlZW4gc29tZXRoaW5nIHRoYXQgbG9va3MgbGlrZSBhIHR5cGUsCiAgICAgICAgICAgICAgICAgICAgLy8gdGhlbiBpdCdzIGEgY2FzdCBleHByZXNzaW9uCiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGUpIHJldHVybiBQYXJlbnNSZXN1bHQuQ0FTVDsKICAgICAgICAgICAgICAgICAgICAvLyBvdGhlcndpc2UsIGRpc2FtYmlndWF0ZSBjYXN0IHZzLiBwYXJlbnRoZXNpemVkIGV4cHJlc3Npb24KICAgICAgICAgICAgICAgICAgICAvLyBiYXNlZCBvbiBzdWJzZXF1ZW50IHRva2VuLgogICAgICAgICAgICAgICAgICAgIHN3aXRjaCAoUy50b2tlbihsb29rYWhlYWQgKyAxKS5raW5kKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8qY2FzZSBQTFVTUExVUzogY2FzZSBTVUJTVUI6ICovCiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgQkFORzogY2FzZSBUSUxERToKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBMUEFSRU46IGNhc2UgVEhJUzogY2FzZSBTVVBFUjoKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBJTlRMSVRFUkFMOiBjYXNlIExPTkdMSVRFUkFMOiBjYXNlIEZMT0FUTElURVJBTDoKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBET1VCTEVMSVRFUkFMOiBjYXNlIENIQVJMSVRFUkFMOiBjYXNlIFNUUklOR0xJVEVSQUw6CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgVFJVRTogY2FzZSBGQUxTRTogY2FzZSBOVUxMOgogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIE5FVzogY2FzZSBJREVOVElGSUVSOiBjYXNlIEFTU0VSVDogY2FzZSBFTlVNOiBjYXNlIFVOREVSU0NPUkU6CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgQllURTogY2FzZSBTSE9SVDogY2FzZSBDSEFSOiBjYXNlIElOVDoKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBMT05HOiBjYXNlIEZMT0FUOiBjYXNlIERPVUJMRTogY2FzZSBCT09MRUFOOiBjYXNlIFZPSUQ6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gUGFyZW5zUmVzdWx0LkNBU1Q7CiAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gUGFyZW5zUmVzdWx0LlBBUkVOUzsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBjYXNlIFVOREVSU0NPUkU6CiAgICAgICAgICAgICAgICBjYXNlIEFTU0VSVDoKICAgICAgICAgICAgICAgIGNhc2UgRU5VTToKICAgICAgICAgICAgICAgIGNhc2UgSURFTlRJRklFUjoKICAgICAgICAgICAgICAgICAgICBpZiAocGVla1Rva2VuKGxvb2thaGVhZCwgTEFYX0lERU5USUZJRVIpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIElkZW50aWZpZXIsIElkZW50aWZpZXIvJ18nLydhc3NlcnQnLydlbnVtJyAtPiBleHBsaWNpdCBsYW1iZGEKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFBhcmVuc1Jlc3VsdC5FWFBMSUNJVF9MQU1CREE7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChwZWVrVG9rZW4obG9va2FoZWFkLCBSUEFSRU4sIEFSUk9XKSkgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBJZGVudGlmaWVyLCAnKScgJy0+JyAtPiBpbXBsaWNpdCBsYW1iZGEKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFBhcmVuc1Jlc3VsdC5JTVBMSUNJVF9MQU1CREE7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHR5cGUgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgRklOQUw6CiAgICAgICAgICAgICAgICBjYXNlIEVMTElQU0lTOgogICAgICAgICAgICAgICAgICAgIC8vdGhvc2UgY2FuIG9ubHkgYXBwZWFyIGluIGV4cGxpY2l0IGxhbWJkYXMKICAgICAgICAgICAgICAgICAgICByZXR1cm4gUGFyZW5zUmVzdWx0LkVYUExJQ0lUX0xBTUJEQTsKICAgICAgICAgICAgICAgIGNhc2UgTU9OS0VZU19BVDoKICAgICAgICAgICAgICAgICAgICB0eXBlID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBsb29rYWhlYWQgKz0gMTsgLy9za2lwICdAJwogICAgICAgICAgICAgICAgICAgIHdoaWxlIChwZWVrVG9rZW4obG9va2FoZWFkLCBET1QpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGxvb2thaGVhZCArPSAyOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAocGVla1Rva2VuKGxvb2thaGVhZCwgTFBBUkVOKSkgewogICAgICAgICAgICAgICAgICAgICAgICBsb29rYWhlYWQrKzsKICAgICAgICAgICAgICAgICAgICAgICAgLy9za2lwIGFubm90YXRpb24gdmFsdWVzCiAgICAgICAgICAgICAgICAgICAgICAgIGludCBuZXN0aW5nID0gMDsKICAgICAgICAgICAgICAgICAgICAgICAgZm9yICg7IDsgbG9va2FoZWFkKyspIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRva2VuS2luZCB0azIgPSBTLnRva2VuKGxvb2thaGVhZCkua2luZDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN3aXRjaCAodGsyKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBFT0Y6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBQYXJlbnNSZXN1bHQuUEFSRU5TOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgTFBBUkVOOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXN0aW5nKys7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgUlBBUkVOOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXN0aW5nLS07CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChuZXN0aW5nID09IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlIG91dGVyOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIExCUkFDS0VUOgogICAgICAgICAgICAgICAgICAgIGlmIChwZWVrVG9rZW4obG9va2FoZWFkLCBSQlJBQ0tFVCwgTEFYX0lERU5USUZJRVIpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vICdbJywgJ10nLCBJZGVudGlmaWVyLydfJy8nYXNzZXJ0Jy8nZW51bScgLT4gZXhwbGljaXQgbGFtYmRhCiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBQYXJlbnNSZXN1bHQuRVhQTElDSVRfTEFNQkRBOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocGVla1Rva2VuKGxvb2thaGVhZCwgUkJSQUNLRVQsIFJQQVJFTikgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBlZWtUb2tlbihsb29rYWhlYWQsIFJCUkFDS0VULCBBTVApKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vICdbJywgJ10nLCAnKScgLT4gY2FzdAogICAgICAgICAgICAgICAgICAgICAgICAvLyAnWycsICddJywgJyYnIC0+IGNhc3QgKGludGVyc2VjdGlvbiB0eXBlKQogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gUGFyZW5zUmVzdWx0LkNBU1Q7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChwZWVrVG9rZW4obG9va2FoZWFkLCBSQlJBQ0tFVCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy9jb25zdW1lIHRoZSAnXScgYW5kIHNraXAKICAgICAgICAgICAgICAgICAgICAgICAgdHlwZSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIGxvb2thaGVhZCsrOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gUGFyZW5zUmVzdWx0LlBBUkVOUzsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBjYXNlIExUOgogICAgICAgICAgICAgICAgICAgIGRlcHRoKys7IGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBHVEdUR1Q6CiAgICAgICAgICAgICAgICAgICAgZGVwdGgtLTsKICAgICAgICAgICAgICAgIGNhc2UgR1RHVDoKICAgICAgICAgICAgICAgICAgICBkZXB0aC0tOwogICAgICAgICAgICAgICAgY2FzZSBHVDoKICAgICAgICAgICAgICAgICAgICBkZXB0aC0tOwogICAgICAgICAgICAgICAgICAgIGlmIChkZXB0aCA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwZWVrVG9rZW4obG9va2FoZWFkLCBSUEFSRU4pIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGVla1Rva2VuKGxvb2thaGVhZCwgQU1QKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gJz4nLCAnKScgLT4gY2FzdAogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gJz4nLCAnJicgLT4gY2FzdAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFBhcmVuc1Jlc3VsdC5DQVNUOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHBlZWtUb2tlbihsb29rYWhlYWQsIExBWF9JREVOVElGSUVSLCBDT01NQSkgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwZWVrVG9rZW4obG9va2FoZWFkLCBMQVhfSURFTlRJRklFUiwgUlBBUkVOLCBBUlJPVykgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwZWVrVG9rZW4obG9va2FoZWFkLCBFTExJUFNJUykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICc+JywgSWRlbnRpZmllci8nXycvJ2Fzc2VydCcvJ2VudW0nLCAnLCcgLT4gZXhwbGljaXQgbGFtYmRhCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAnPicsIElkZW50aWZpZXIvJ18nLydhc3NlcnQnLydlbnVtJywgJyknLCAnLT4nIC0+IGV4cGxpY2l0IGxhbWJkYQogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gJz4nLCAnLi4uJyAtPiBleHBsaWNpdCBsYW1iZGEKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBQYXJlbnNSZXN1bHQuRVhQTElDSVRfTEFNQkRBOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIC8vaXQgbG9va3MgYSB0eXBlLCBidXQgY291bGQgc3RpbGwgYmUgKGkpIGEgY2FzdCB0byBnZW5lcmljIHR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgIC8vKGlpKSBhbiB1bmJvdW5kIG1ldGhvZCByZWZlcmVuY2Ugb3IgKGlpaSkgYW4gZXhwbGljaXQgbGFtYmRhCiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGRlcHRoIDwgMCkgewogICAgICAgICAgICAgICAgICAgICAgICAvL3VuYmFsYW5jZWQgJzwnLCAnPicgLSBub3QgYSBnZW5lcmljIHR5cGUKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFBhcmVuc1Jlc3VsdC5QQVJFTlM7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAvL3RoaXMgaW5jbHVkZXMgRU9GCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFBhcmVuc1Jlc3VsdC5QQVJFTlM7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqIEFjY2VwdHMgYWxsIGlkZW50aWZpZXItbGlrZSB0b2tlbnMgKi8KICAgIHByb3RlY3RlZCBGaWx0ZXI8VG9rZW5LaW5kPiBMQVhfSURFTlRJRklFUiA9IHQgLT4gdCA9PSBJREVOVElGSUVSIHx8IHQgPT0gVU5ERVJTQ09SRSB8fCB0ID09IEFTU0VSVCB8fCB0ID09IEVOVU07CgogICAgZW51bSBQYXJlbnNSZXN1bHQgewogICAgICAgIENBU1QsCiAgICAgICAgRVhQTElDSVRfTEFNQkRBLAogICAgICAgIElNUExJQ0lUX0xBTUJEQSwKICAgICAgICBQQVJFTlMKICAgIH0KCiAgICBKQ0V4cHJlc3Npb24gbGFtYmRhRXhwcmVzc2lvbk9yU3RhdGVtZW50KGJvb2xlYW4gaGFzUGFyZW5zLCBib29sZWFuIGV4cGxpY2l0UGFyYW1zLCBpbnQgcG9zKSB7CiAgICAgICAgTGlzdDxKQ1ZhcmlhYmxlRGVjbD4gcGFyYW1zID0gZXhwbGljaXRQYXJhbXMgPwogICAgICAgICAgICAgICAgZm9ybWFsUGFyYW1ldGVycyh0cnVlKSA6CiAgICAgICAgICAgICAgICBpbXBsaWNpdFBhcmFtZXRlcnMoaGFzUGFyZW5zKTsKCiAgICAgICAgcmV0dXJuIGxhbWJkYUV4cHJlc3Npb25PclN0YXRlbWVudFJlc3QocGFyYW1zLCBwb3MpOwogICAgfQoKICAgIEpDRXhwcmVzc2lvbiBsYW1iZGFFeHByZXNzaW9uT3JTdGF0ZW1lbnRSZXN0KExpc3Q8SkNWYXJpYWJsZURlY2w+IGFyZ3MsIGludCBwb3MpIHsKICAgICAgICBjaGVja0xhbWJkYSgpOwogICAgICAgIGFjY2VwdChBUlJPVyk7CgogICAgICAgIHJldHVybiB0b2tlbi5raW5kID09IExCUkFDRSA/CiAgICAgICAgICAgIGxhbWJkYVN0YXRlbWVudChhcmdzLCBwb3MsIHRva2VuLnBvcykgOgogICAgICAgICAgICBsYW1iZGFFeHByZXNzaW9uKGFyZ3MsIHBvcyk7CiAgICB9CgogICAgSkNFeHByZXNzaW9uIGxhbWJkYVN0YXRlbWVudChMaXN0PEpDVmFyaWFibGVEZWNsPiBhcmdzLCBpbnQgcG9zLCBpbnQgcG9zMikgewogICAgICAgIEpDQmxvY2sgYmxvY2sgPSBibG9jayhwb3MyLCAwKTsKICAgICAgICByZXR1cm4gdG9QKEYuYXQocG9zKS5MYW1iZGEoYXJncywgYmxvY2spKTsKICAgIH0KCiAgICBKQ0V4cHJlc3Npb24gbGFtYmRhRXhwcmVzc2lvbihMaXN0PEpDVmFyaWFibGVEZWNsPiBhcmdzLCBpbnQgcG9zKSB7CiAgICAgICAgSkNUcmVlIGV4cHIgPSBwYXJzZUV4cHJlc3Npb24oKTsKICAgICAgICByZXR1cm4gdG9QKEYuYXQocG9zKS5MYW1iZGEoYXJncywgZXhwcikpOwogICAgfQoKICAgIC8qKiBTdXBlclN1ZmZpeCA9IEFyZ3VtZW50cyB8ICIuIiBbVHlwZUFyZ3VtZW50c10gSWRlbnQgW0FyZ3VtZW50c10KICAgICAqLwogICAgSkNFeHByZXNzaW9uIHN1cGVyU3VmZml4KExpc3Q8SkNFeHByZXNzaW9uPiB0eXBlQXJncywgSkNFeHByZXNzaW9uIHQpIHsKICAgICAgICBuZXh0VG9rZW4oKTsKICAgICAgICBpZiAodG9rZW4ua2luZCA9PSBMUEFSRU4gfHwgdHlwZUFyZ3MgIT0gbnVsbCkgewogICAgICAgICAgICB0ID0gYXJndW1lbnRzKHR5cGVBcmdzLCB0KTsKICAgICAgICB9IGVsc2UgaWYgKHRva2VuLmtpbmQgPT0gQ09MQ09MKSB7CiAgICAgICAgICAgIGlmICh0eXBlQXJncyAhPSBudWxsKSByZXR1cm4gaWxsZWdhbCgpOwogICAgICAgICAgICB0ID0gbWVtYmVyUmVmZXJlbmNlU3VmZml4KHQpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGludCBwb3MgPSB0b2tlbi5wb3M7CiAgICAgICAgICAgIGFjY2VwdChET1QpOwogICAgICAgICAgICB0eXBlQXJncyA9ICh0b2tlbi5raW5kID09IExUKSA/IHR5cGVBcmd1bWVudHMoZmFsc2UpIDogbnVsbDsKICAgICAgICAgICAgdCA9IHRvUChGLmF0KHBvcykuU2VsZWN0KHQsIGlkZW50KCkpKTsKICAgICAgICAgICAgdCA9IGFyZ3VtZW50c09wdCh0eXBlQXJncywgdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0OwogICAgfQoKICAgIC8qKiBCYXNpY1R5cGUgPSBCWVRFIHwgU0hPUlQgfCBDSEFSIHwgSU5UIHwgTE9ORyB8IEZMT0FUIHwgRE9VQkxFIHwgQk9PTEVBTgogICAgICovCiAgICBKQ1ByaW1pdGl2ZVR5cGVUcmVlIGJhc2ljVHlwZSgpIHsKICAgICAgICBKQ1ByaW1pdGl2ZVR5cGVUcmVlIHQgPSB0byhGLmF0KHRva2VuLnBvcykuVHlwZUlkZW50KHR5cGV0YWcodG9rZW4ua2luZCkpKTsKICAgICAgICBuZXh0VG9rZW4oKTsKICAgICAgICByZXR1cm4gdDsKICAgIH0KCiAgICAvKiogQXJndW1lbnRzT3B0ID0gWyBBcmd1bWVudHMgXQogICAgICovCiAgICBKQ0V4cHJlc3Npb24gYXJndW1lbnRzT3B0KExpc3Q8SkNFeHByZXNzaW9uPiB0eXBlQXJncywgSkNFeHByZXNzaW9uIHQpIHsKICAgICAgICBpZiAoKG1vZGUgJiBFWFBSKSAhPSAwICYmIHRva2VuLmtpbmQgPT0gTFBBUkVOIHx8IHR5cGVBcmdzICE9IG51bGwpIHsKICAgICAgICAgICAgbW9kZSA9IEVYUFI7CiAgICAgICAgICAgIHJldHVybiBhcmd1bWVudHModHlwZUFyZ3MsIHQpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiB0OwogICAgICAgIH0KICAgIH0KCiAgICAvKiogQXJndW1lbnRzID0gIigiIFtFeHByZXNzaW9uIHsgQ09NTUEgRXhwcmVzc2lvbiB9XSAiKSIKICAgICAqLwogICAgTGlzdDxKQ0V4cHJlc3Npb24+IGFyZ3VtZW50cygpIHsKICAgICAgICBMaXN0QnVmZmVyPEpDRXhwcmVzc2lvbj4gYXJncyA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICBpZiAodG9rZW4ua2luZCA9PSBMUEFSRU4pIHsKICAgICAgICAgICAgbmV4dFRva2VuKCk7CiAgICAgICAgICAgIGlmICh0b2tlbi5raW5kICE9IFJQQVJFTikgewogICAgICAgICAgICAgICAgYXJncy5hcHBlbmQocGFyc2VFeHByZXNzaW9uKCkpOwogICAgICAgICAgICAgICAgd2hpbGUgKHRva2VuLmtpbmQgPT0gQ09NTUEpIHsKICAgICAgICAgICAgICAgICAgICBuZXh0VG9rZW4oKTsKICAgICAgICAgICAgICAgICAgICBhcmdzLmFwcGVuZChwYXJzZUV4cHJlc3Npb24oKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYWNjZXB0KFJQQVJFTik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc3ludGF4RXJyb3IodG9rZW4ucG9zLCAiZXhwZWN0ZWQiLCBMUEFSRU4pOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYXJncy50b0xpc3QoKTsKICAgIH0KCiAgICBKQ01ldGhvZEludm9jYXRpb24gYXJndW1lbnRzKExpc3Q8SkNFeHByZXNzaW9uPiB0eXBlQXJncywgSkNFeHByZXNzaW9uIHQpIHsKICAgICAgICBpbnQgcG9zID0gdG9rZW4ucG9zOwogICAgICAgIExpc3Q8SkNFeHByZXNzaW9uPiBhcmdzID0gYXJndW1lbnRzKCk7CiAgICAgICAgcmV0dXJuIHRvUChGLmF0KHBvcykuQXBwbHkodHlwZUFyZ3MsIHQsIGFyZ3MpKTsKICAgIH0KCiAgICAvKiogIFR5cGVBcmd1bWVudHNPcHQgPSBbIFR5cGVBcmd1bWVudHMgXQogICAgICovCiAgICBKQ0V4cHJlc3Npb24gdHlwZUFyZ3VtZW50c09wdChKQ0V4cHJlc3Npb24gdCkgewogICAgICAgIGlmICh0b2tlbi5raW5kID09IExUICYmCiAgICAgICAgICAgIChtb2RlICYgVFlQRSkgIT0gMCAmJgogICAgICAgICAgICAobW9kZSAmIE5PUEFSQU1TKSA9PSAwKSB7CiAgICAgICAgICAgIG1vZGUgPSBUWVBFOwogICAgICAgICAgICByZXR1cm4gdHlwZUFyZ3VtZW50cyh0LCBmYWxzZSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIHQ7CiAgICAgICAgfQogICAgfQogICAgTGlzdDxKQ0V4cHJlc3Npb24+IHR5cGVBcmd1bWVudHNPcHQoKSB7CiAgICAgICAgcmV0dXJuIHR5cGVBcmd1bWVudHNPcHQoVFlQRSk7CiAgICB9CgogICAgTGlzdDxKQ0V4cHJlc3Npb24+IHR5cGVBcmd1bWVudHNPcHQoaW50IHVzZU1vZGUpIHsKICAgICAgICBpZiAodG9rZW4ua2luZCA9PSBMVCkgewogICAgICAgICAgICBpZiAoKG1vZGUgJiB1c2VNb2RlKSA9PSAwIHx8CiAgICAgICAgICAgICAgICAobW9kZSAmIE5PUEFSQU1TKSAhPSAwKSB7CiAgICAgICAgICAgICAgICBpbGxlZ2FsKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgbW9kZSA9IHVzZU1vZGU7CiAgICAgICAgICAgIHJldHVybiB0eXBlQXJndW1lbnRzKGZhbHNlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgLyoqCiAgICAgKiAge0BsaXRlcmFsCiAgICAgKiAgVHlwZUFyZ3VtZW50cyAgPSAiPCIgVHlwZUFyZ3VtZW50IHsiLCIgVHlwZUFyZ3VtZW50fSAiPiIKICAgICAqICB9CiAgICAgKi8KICAgIExpc3Q8SkNFeHByZXNzaW9uPiB0eXBlQXJndW1lbnRzKGJvb2xlYW4gZGlhbW9uZEFsbG93ZWQpIHsKICAgICAgICBpZiAodG9rZW4ua2luZCA9PSBMVCkgewogICAgICAgICAgICBuZXh0VG9rZW4oKTsKICAgICAgICAgICAgaWYgKHRva2VuLmtpbmQgPT0gR1QgJiYgZGlhbW9uZEFsbG93ZWQpIHsKICAgICAgICAgICAgICAgIGNoZWNrRGlhbW9uZCgpOwogICAgICAgICAgICAgICAgbW9kZSB8PSBESUFNT05EOwogICAgICAgICAgICAgICAgbmV4dFRva2VuKCk7CiAgICAgICAgICAgICAgICByZXR1cm4gTGlzdC5uaWwoKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIExpc3RCdWZmZXI8SkNFeHByZXNzaW9uPiBhcmdzID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgICAgICAgICAgYXJncy5hcHBlbmQoKChtb2RlICYgRVhQUikgPT0gMCkgPyB0eXBlQXJndW1lbnQoKSA6IHBhcnNlVHlwZSgpKTsKICAgICAgICAgICAgICAgIHdoaWxlICh0b2tlbi5raW5kID09IENPTU1BKSB7CiAgICAgICAgICAgICAgICAgICAgbmV4dFRva2VuKCk7CiAgICAgICAgICAgICAgICAgICAgYXJncy5hcHBlbmQoKChtb2RlICYgRVhQUikgPT0gMCkgPyB0eXBlQXJndW1lbnQoKSA6IHBhcnNlVHlwZSgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHN3aXRjaCAodG9rZW4ua2luZCkgewoKICAgICAgICAgICAgICAgIGNhc2UgR1RHVEdURVE6IGNhc2UgR1RHVEVROiBjYXNlIEdURVE6CiAgICAgICAgICAgICAgICBjYXNlIEdUR1RHVDogY2FzZSBHVEdUOgogICAgICAgICAgICAgICAgICAgIHRva2VuID0gUy5zcGxpdCgpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBHVDoKICAgICAgICAgICAgICAgICAgICBuZXh0VG9rZW4oKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgYXJncy5hcHBlbmQoc3ludGF4RXJyb3IodG9rZW4ucG9zLCAiZXhwZWN0ZWQiLCBHVCkpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIGFyZ3MudG9MaXN0KCk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gTGlzdC5vZihzeW50YXhFcnJvcih0b2tlbi5wb3MsICJleHBlY3RlZCIsIExUKSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogIHtAbGl0ZXJhbAogICAgICogIFR5cGVBcmd1bWVudCA9IFR5cGUKICAgICAqICAgICAgICAgICAgICAgfCBbQW5ub3RhdGlvbnNdICI/IgogICAgICogICAgICAgICAgICAgICB8IFtBbm5vdGF0aW9uc10gIj8iIEVYVEVORFMgVHlwZSB7IiYiIFR5cGV9CiAgICAgKiAgICAgICAgICAgICAgIHwgW0Fubm90YXRpb25zXSAiPyIgU1VQRVIgVHlwZQogICAgICogIH0KICAgICAqLwogICAgSkNFeHByZXNzaW9uIHR5cGVBcmd1bWVudCgpIHsKICAgICAgICBMaXN0PEpDQW5ub3RhdGlvbj4gYW5ub3RhdGlvbnMgPSB0eXBlQW5ub3RhdGlvbnNPcHQoKTsKICAgICAgICBpZiAodG9rZW4ua2luZCAhPSBRVUVTKSByZXR1cm4gcGFyc2VUeXBlKGFubm90YXRpb25zKTsKICAgICAgICBpbnQgcG9zID0gdG9rZW4ucG9zOwogICAgICAgIG5leHRUb2tlbigpOwogICAgICAgIEpDRXhwcmVzc2lvbiByZXN1bHQ7CiAgICAgICAgaWYgKHRva2VuLmtpbmQgPT0gRVhURU5EUykgewogICAgICAgICAgICBUeXBlQm91bmRLaW5kIHQgPSB0byhGLmF0KHBvcykuVHlwZUJvdW5kS2luZChCb3VuZEtpbmQuRVhURU5EUykpOwogICAgICAgICAgICBuZXh0VG9rZW4oKTsKICAgICAgICAgICAgSkNFeHByZXNzaW9uIGJvdW5kID0gcGFyc2VUeXBlKCk7CiAgICAgICAgICAgIHJlc3VsdCA9IEYuYXQocG9zKS5XaWxkY2FyZCh0LCBib3VuZCk7CiAgICAgICAgfSBlbHNlIGlmICh0b2tlbi5raW5kID09IFNVUEVSKSB7CiAgICAgICAgICAgIFR5cGVCb3VuZEtpbmQgdCA9IHRvKEYuYXQocG9zKS5UeXBlQm91bmRLaW5kKEJvdW5kS2luZC5TVVBFUikpOwogICAgICAgICAgICBuZXh0VG9rZW4oKTsKICAgICAgICAgICAgSkNFeHByZXNzaW9uIGJvdW5kID0gcGFyc2VUeXBlKCk7CiAgICAgICAgICAgIHJlc3VsdCA9IEYuYXQocG9zKS5XaWxkY2FyZCh0LCBib3VuZCk7CiAgICAgICAgfSBlbHNlIGlmIChMQVhfSURFTlRJRklFUi5hY2NlcHRzKHRva2VuLmtpbmQpKSB7CiAgICAgICAgICAgIC8vZXJyb3IgcmVjb3ZlcnkKICAgICAgICAgICAgVHlwZUJvdW5kS2luZCB0ID0gRi5hdChQb3NpdGlvbi5OT1BPUykuVHlwZUJvdW5kS2luZChCb3VuZEtpbmQuVU5CT1VORCk7CiAgICAgICAgICAgIEpDRXhwcmVzc2lvbiB3YyA9IHRvUChGLmF0KHBvcykuV2lsZGNhcmQodCwgbnVsbCkpOwogICAgICAgICAgICBKQ0lkZW50IGlkID0gdG9QKEYuYXQodG9rZW4ucG9zKS5JZGVudChpZGVudCgpKSk7CiAgICAgICAgICAgIEpDRXJyb25lb3VzIGVyciA9IEYuYXQocG9zKS5FcnJvbmVvdXMoTGlzdC48SkNUcmVlPm9mKHdjLCBpZCkpOwogICAgICAgICAgICByZXBvcnRTeW50YXhFcnJvcihlcnIsICJleHBlY3RlZDMiLCBHVCwgRVhURU5EUywgU1VQRVIpOwogICAgICAgICAgICByZXN1bHQgPSBlcnI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgVHlwZUJvdW5kS2luZCB0ID0gdG9QKEYuYXQocG9zKS5UeXBlQm91bmRLaW5kKEJvdW5kS2luZC5VTkJPVU5EKSk7CiAgICAgICAgICAgIHJlc3VsdCA9IHRvUChGLmF0KHBvcykuV2lsZGNhcmQodCwgbnVsbCkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWFubm90YXRpb25zLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXN1bHQgPSB0b1AoRi5hdChhbm5vdGF0aW9ucy5oZWFkLnBvcykuQW5ub3RhdGVkVHlwZShhbm5vdGF0aW9ucyxyZXN1bHQpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KCiAgICBKQ1R5cGVBcHBseSB0eXBlQXJndW1lbnRzKEpDRXhwcmVzc2lvbiB0LCBib29sZWFuIGRpYW1vbmRBbGxvd2VkKSB7CiAgICAgICAgaW50IHBvcyA9IHRva2VuLnBvczsKICAgICAgICBMaXN0PEpDRXhwcmVzc2lvbj4gYXJncyA9IHR5cGVBcmd1bWVudHMoZGlhbW9uZEFsbG93ZWQpOwogICAgICAgIHJldHVybiB0b1AoRi5hdChwb3MpLlR5cGVBcHBseSh0LCBhcmdzKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBCcmFja2V0c09wdCA9IHsgW0Fubm90YXRpb25zXSAiWyIgIl0iIH0qCiAgICAgKgogICAgICogPHA+CiAgICAgKgogICAgICogPGNvZGU+YW5ub3RhdGlvbnM8L2NvZGU+IGlzIHRoZSBsaXN0IG9mIGFubm90YXRpb25zIHRhcmdldGluZwogICAgICogdGhlIGV4cHJlc3Npb24gPGNvZGU+dDwvY29kZT4uCiAgICAgKi8KICAgIHByaXZhdGUgSkNFeHByZXNzaW9uIGJyYWNrZXRzT3B0KEpDRXhwcmVzc2lvbiB0LAogICAgICAgICAgICBMaXN0PEpDQW5ub3RhdGlvbj4gYW5ub3RhdGlvbnMpIHsKICAgICAgICBMaXN0PEpDQW5ub3RhdGlvbj4gbmV4dExldmVsQW5ub3RhdGlvbnMgPSB0eXBlQW5ub3RhdGlvbnNPcHQoKTsKCiAgICAgICAgaWYgKHRva2VuLmtpbmQgPT0gTEJSQUNLRVQpIHsKICAgICAgICAgICAgaW50IHBvcyA9IHRva2VuLnBvczsKICAgICAgICAgICAgbmV4dFRva2VuKCk7CiAgICAgICAgICAgIHQgPSBicmFja2V0c09wdENvbnQodCwgcG9zLCBuZXh0TGV2ZWxBbm5vdGF0aW9ucyk7CiAgICAgICAgfSBlbHNlIGlmICghbmV4dExldmVsQW5ub3RhdGlvbnMuaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGlmIChwZXJtaXRUeXBlQW5ub3RhdGlvbnNQdXNoQmFjaykgewogICAgICAgICAgICAgICAgdGhpcy50eXBlQW5ub3RhdGlvbnNQdXNoZWRCYWNrID0gbmV4dExldmVsQW5ub3RhdGlvbnM7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICByZXR1cm4gaWxsZWdhbChuZXh0TGV2ZWxBbm5vdGF0aW9ucy5oZWFkLnBvcyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICghYW5ub3RhdGlvbnMuaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHQgPSB0b1AoRi5hdCh0b2tlbi5wb3MpLkFubm90YXRlZFR5cGUoYW5ub3RhdGlvbnMsIHQpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHQ7CiAgICB9CgogICAgLyoqIEJyYWNrZXRzT3B0ID0gWyAiWyIgIl0iIHsgW0Fubm90YXRpb25zXSAiWyIgIl0ifSBdCiAgICAgKi8KICAgIHByaXZhdGUgSkNFeHByZXNzaW9uIGJyYWNrZXRzT3B0KEpDRXhwcmVzc2lvbiB0KSB7CiAgICAgICAgcmV0dXJuIGJyYWNrZXRzT3B0KHQsIExpc3QubmlsKCkpOwogICAgfQoKICAgIHByaXZhdGUgSkNFeHByZXNzaW9uIGJyYWNrZXRzT3B0Q29udChKQ0V4cHJlc3Npb24gdCwgaW50IHBvcywKICAgICAgICAgICAgTGlzdDxKQ0Fubm90YXRpb24+IGFubm90YXRpb25zKSB7CiAgICAgICAgYWNjZXB0KFJCUkFDS0VUKTsKICAgICAgICB0ID0gYnJhY2tldHNPcHQodCk7CiAgICAgICAgdCA9IHRvUChGLmF0KHBvcykuVHlwZUFycmF5KHQpKTsKICAgICAgICBpZiAoYW5ub3RhdGlvbnMubm9uRW1wdHkoKSkgewogICAgICAgICAgICB0ID0gdG9QKEYuYXQocG9zKS5Bbm5vdGF0ZWRUeXBlKGFubm90YXRpb25zLCB0KSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0OwogICAgfQoKICAgIC8qKiBCcmFja2V0c1N1ZmZpeEV4cHIgPSAiLiIgQ0xBU1MKICAgICAqICBCcmFja2V0c1N1ZmZpeFR5cGUgPQogICAgICovCiAgICBKQ0V4cHJlc3Npb24gYnJhY2tldHNTdWZmaXgoSkNFeHByZXNzaW9uIHQpIHsKICAgICAgICBpZiAoKG1vZGUgJiBFWFBSKSAhPSAwICYmIHRva2VuLmtpbmQgPT0gRE9UKSB7CiAgICAgICAgICAgIG1vZGUgPSBFWFBSOwogICAgICAgICAgICBpbnQgcG9zID0gdG9rZW4ucG9zOwogICAgICAgICAgICBuZXh0VG9rZW4oKTsKICAgICAgICAgICAgYWNjZXB0KENMQVNTKTsKICAgICAgICAgICAgaWYgKHRva2VuLnBvcyA9PSBlbmRQb3NUYWJsZS5lcnJvckVuZFBvcykgewogICAgICAgICAgICAgICAgLy8gZXJyb3IgcmVjb3ZlcnkKICAgICAgICAgICAgICAgIE5hbWUgbmFtZTsKICAgICAgICAgICAgICAgIGlmIChMQVhfSURFTlRJRklFUi5hY2NlcHRzKHRva2VuLmtpbmQpKSB7CiAgICAgICAgICAgICAgICAgICAgbmFtZSA9IHRva2VuLm5hbWUoKTsKICAgICAgICAgICAgICAgICAgICBuZXh0VG9rZW4oKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgbmFtZSA9IG5hbWVzLmVycm9yOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdCA9IEYuYXQocG9zKS5FcnJvbmVvdXMoTGlzdC48SkNUcmVlPm9mKHRvUChGLmF0KHBvcykuU2VsZWN0KHQsIG5hbWUpKSkpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgVGFnIHRhZyA9IHQuZ2V0VGFnKCk7CiAgICAgICAgICAgICAgICAvLyBUeXBlIGFubm90YXRpb25zIGFyZSBpbGxlZ2FsIG9uIGNsYXNzIGxpdGVyYWxzLiBBbm5vdGF0ZWQgbm9uIGFycmF5IGNsYXNzIGxpdGVyYWxzCiAgICAgICAgICAgICAgICAvLyBhcmUgY29tcGxhaW5lZCBhYm91dCBkaXJlY3RseSBpbiB0ZXJtMygpLCBIZXJlIGNoZWNrIGZvciB0eXBlIGFubm90YXRpb25zIG9uIGRpbWVuc2lvbnMKICAgICAgICAgICAgICAgIC8vIHRha2luZyBjYXJlIHRvIGhhbmRsZSBzb21lIGludGVyaW9yIGRpbWVuc2lvbihzKSBiZWluZyBhbm5vdGF0ZWQuCiAgICAgICAgICAgICAgICBpZiAoKHRhZyA9PSBUWVBFQVJSQVkgJiYgVHJlZUluZm8uY29udGFpbnNUeXBlQW5ub3RhdGlvbih0KSkgfHwgdGFnID09IEFOTk9UQVRFRF9UWVBFKQogICAgICAgICAgICAgICAgICAgIHN5bnRheEVycm9yKCJuby5hbm5vdGF0aW9ucy5vbi5kb3QuY2xhc3MiKTsKICAgICAgICAgICAgICAgIHQgPSB0b1AoRi5hdChwb3MpLlNlbGVjdCh0LCBuYW1lcy5fY2xhc3MpKTsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSBpZiAoKG1vZGUgJiBUWVBFKSAhPSAwKSB7CiAgICAgICAgICAgIGlmICh0b2tlbi5raW5kICE9IENPTENPTCkgewogICAgICAgICAgICAgICAgbW9kZSA9IFRZUEU7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgaWYgKHRva2VuLmtpbmQgIT0gQ09MQ09MKSB7CiAgICAgICAgICAgIHN5bnRheEVycm9yKHRva2VuLnBvcywgImRvdC5jbGFzcy5leHBlY3RlZCIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdDsKICAgIH0KCiAgICAvKioKICAgICAqIE1lbWJlclJlZmVyZW5jZVN1ZmZpeCA9ICI6OiIgW1R5cGVBcmd1bWVudHNdIElkZW50CiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgfCAiOjoiIFtUeXBlQXJndW1lbnRzXSAibmV3IgogICAgICovCiAgICBKQ0V4cHJlc3Npb24gbWVtYmVyUmVmZXJlbmNlU3VmZml4KEpDRXhwcmVzc2lvbiB0KSB7CiAgICAgICAgaW50IHBvczEgPSB0b2tlbi5wb3M7CiAgICAgICAgYWNjZXB0KENPTENPTCk7CiAgICAgICAgcmV0dXJuIG1lbWJlclJlZmVyZW5jZVN1ZmZpeChwb3MxLCB0KTsKICAgIH0KCiAgICBKQ0V4cHJlc3Npb24gbWVtYmVyUmVmZXJlbmNlU3VmZml4KGludCBwb3MxLCBKQ0V4cHJlc3Npb24gdCkgewogICAgICAgIGNoZWNrTWV0aG9kUmVmZXJlbmNlcygpOwogICAgICAgIG1vZGUgPSBFWFBSOwogICAgICAgIExpc3Q8SkNFeHByZXNzaW9uPiB0eXBlQXJncyA9IG51bGw7CiAgICAgICAgaWYgKHRva2VuLmtpbmQgPT0gTFQpIHsKICAgICAgICAgICAgdHlwZUFyZ3MgPSB0eXBlQXJndW1lbnRzKGZhbHNlKTsKICAgICAgICB9CiAgICAgICAgTmFtZSByZWZOYW1lOwogICAgICAgIFJlZmVyZW5jZU1vZGUgcmVmTW9kZTsKICAgICAgICBpZiAodG9rZW4ua2luZCA9PSBORVcpIHsKICAgICAgICAgICAgcmVmTW9kZSA9IFJlZmVyZW5jZU1vZGUuTkVXOwogICAgICAgICAgICByZWZOYW1lID0gbmFtZXMuaW5pdDsKICAgICAgICAgICAgbmV4dFRva2VuKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmVmTW9kZSA9IFJlZmVyZW5jZU1vZGUuSU5WT0tFOwogICAgICAgICAgICByZWZOYW1lID0gaWRlbnQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRvUChGLmF0KHQuZ2V0U3RhcnRQb3NpdGlvbigpKS5SZWZlcmVuY2UocmVmTW9kZSwgcmVmTmFtZSwgdCwgdHlwZUFyZ3MpKTsKICAgIH0KCiAgICAvKiogQ3JlYXRvciA9IFtBbm5vdGF0aW9uc10gUXVhbGlkZW50IFtUeXBlQXJndW1lbnRzXSAoIEFycmF5Q3JlYXRvclJlc3QgfCBDbGFzc0NyZWF0b3JSZXN0ICkKICAgICAqLwogICAgSkNFeHByZXNzaW9uIGNyZWF0b3IoaW50IG5ld3BvcywgTGlzdDxKQ0V4cHJlc3Npb24+IHR5cGVBcmdzKSB7CiAgICAgICAgTGlzdDxKQ0Fubm90YXRpb24+IG5ld0Fubm90YXRpb25zID0gdHlwZUFubm90YXRpb25zT3B0KCk7CgogICAgICAgIHN3aXRjaCAodG9rZW4ua2luZCkgewogICAgICAgIGNhc2UgQllURTogY2FzZSBTSE9SVDogY2FzZSBDSEFSOiBjYXNlIElOVDogY2FzZSBMT05HOiBjYXNlIEZMT0FUOgogICAgICAgIGNhc2UgRE9VQkxFOiBjYXNlIEJPT0xFQU46CiAgICAgICAgICAgIGlmICh0eXBlQXJncyA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICBpZiAobmV3QW5ub3RhdGlvbnMuaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGFycmF5Q3JlYXRvclJlc3QobmV3cG9zLCBiYXNpY1R5cGUoKSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBhcnJheUNyZWF0b3JSZXN0KG5ld3BvcywgdG9QKEYuYXQobmV3QW5ub3RhdGlvbnMuaGVhZC5wb3MpLkFubm90YXRlZFR5cGUobmV3QW5ub3RhdGlvbnMsIGJhc2ljVHlwZSgpKSkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgfQogICAgICAgIEpDRXhwcmVzc2lvbiB0ID0gcXVhbGlkZW50KHRydWUpOwoKICAgICAgICBpbnQgb2xkbW9kZSA9IG1vZGU7CiAgICAgICAgbW9kZSA9IFRZUEU7CiAgICAgICAgYm9vbGVhbiBkaWFtb25kRm91bmQgPSBmYWxzZTsKICAgICAgICBpbnQgbGFzdFR5cGVhcmdzUG9zID0gLTE7CiAgICAgICAgaWYgKHRva2VuLmtpbmQgPT0gTFQpIHsKICAgICAgICAgICAgbGFzdFR5cGVhcmdzUG9zID0gdG9rZW4ucG9zOwogICAgICAgICAgICB0ID0gdHlwZUFyZ3VtZW50cyh0LCB0cnVlKTsKICAgICAgICAgICAgZGlhbW9uZEZvdW5kID0gKG1vZGUgJiBESUFNT05EKSAhPSAwOwogICAgICAgIH0KICAgICAgICB3aGlsZSAodG9rZW4ua2luZCA9PSBET1QpIHsKICAgICAgICAgICAgaWYgKGRpYW1vbmRGb3VuZCkgewogICAgICAgICAgICAgICAgLy9jYW5ub3Qgc2VsZWN0IGFmdGVyIGEgZGlhbW9uZAogICAgICAgICAgICAgICAgaWxsZWdhbCgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGludCBwb3MgPSB0b2tlbi5wb3M7CiAgICAgICAgICAgIG5leHRUb2tlbigpOwogICAgICAgICAgICBMaXN0PEpDQW5ub3RhdGlvbj4gdHlhbm5vcyA9IHR5cGVBbm5vdGF0aW9uc09wdCgpOwogICAgICAgICAgICB0ID0gdG9QKEYuYXQocG9zKS5TZWxlY3QodCwgaWRlbnQoKSkpOwoKICAgICAgICAgICAgaWYgKHR5YW5ub3MgIT0gbnVsbCAmJiB0eWFubm9zLm5vbkVtcHR5KCkpIHsKICAgICAgICAgICAgICAgIHQgPSB0b1AoRi5hdCh0eWFubm9zLmhlYWQucG9zKS5Bbm5vdGF0ZWRUeXBlKHR5YW5ub3MsIHQpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKHRva2VuLmtpbmQgPT0gTFQpIHsKICAgICAgICAgICAgICAgIGxhc3RUeXBlYXJnc1BvcyA9IHRva2VuLnBvczsKICAgICAgICAgICAgICAgIHQgPSB0eXBlQXJndW1lbnRzKHQsIHRydWUpOwogICAgICAgICAgICAgICAgZGlhbW9uZEZvdW5kID0gKG1vZGUgJiBESUFNT05EKSAhPSAwOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIG1vZGUgPSBvbGRtb2RlOwogICAgICAgIGlmICh0b2tlbi5raW5kID09IExCUkFDS0VUIHx8IHRva2VuLmtpbmQgPT0gTU9OS0VZU19BVCkgewogICAgICAgICAgICAvLyBoYW5kbGUgdHlwZSBhbm5vdGF0aW9ucyBmb3Igbm9uIHByaW1pdGl2ZSBhcnJheXMKICAgICAgICAgICAgaWYgKG5ld0Fubm90YXRpb25zLm5vbkVtcHR5KCkpIHsKICAgICAgICAgICAgICAgIHQgPSBpbnNlcnRBbm5vdGF0aW9uc1RvTW9zdElubmVyKHQsIG5ld0Fubm90YXRpb25zLCBmYWxzZSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEpDRXhwcmVzc2lvbiBlID0gYXJyYXlDcmVhdG9yUmVzdChuZXdwb3MsIHQpOwogICAgICAgICAgICBpZiAoZGlhbW9uZEZvdW5kKSB7CiAgICAgICAgICAgICAgICByZXBvcnRTeW50YXhFcnJvcihsYXN0VHlwZWFyZ3NQb3MsICJjYW5ub3QuY3JlYXRlLmFycmF5LndpdGguZGlhbW9uZCIpOwogICAgICAgICAgICAgICAgcmV0dXJuIHRvUChGLmF0KG5ld3BvcykuRXJyb25lb3VzKExpc3Qub2YoZSkpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmICh0eXBlQXJncyAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICBpbnQgcG9zID0gbmV3cG9zOwogICAgICAgICAgICAgICAgaWYgKCF0eXBlQXJncy5pc0VtcHR5KCkgJiYgdHlwZUFyZ3MuaGVhZC5wb3MgIT0gUG9zaXRpb24uTk9QT1MpIHsKICAgICAgICAgICAgICAgICAgICAvLyBub3RlOiB0aGlzIHNob3VsZCBhbHdheXMgaGFwcGVuIGJ1dCB3ZSBzaG91bGQKICAgICAgICAgICAgICAgICAgICAvLyBub3QgcmVseSBvbiB0aGlzIGFzIHRoZSBwYXJzZXIgaXMgY29udGludW91c2x5CiAgICAgICAgICAgICAgICAgICAgLy8gbW9kaWZpZWQgdG8gaW1wcm92ZSBlcnJvciByZWNvdmVyeS4KICAgICAgICAgICAgICAgICAgICBwb3MgPSB0eXBlQXJncy5oZWFkLnBvczsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHNldEVycm9yRW5kUG9zKFMucHJldlRva2VuKCkuZW5kUG9zKTsKICAgICAgICAgICAgICAgIEpDRXJyb25lb3VzIGVyciA9IEYuYXQocG9zKS5FcnJvbmVvdXModHlwZUFyZ3MucHJlcGVuZChlKSk7CiAgICAgICAgICAgICAgICByZXBvcnRTeW50YXhFcnJvcihlcnIsICJjYW5ub3QuY3JlYXRlLmFycmF5LndpdGgudHlwZS5hcmd1bWVudHMiKTsKICAgICAgICAgICAgICAgIHJldHVybiB0b1AoZXJyKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gZTsKICAgICAgICB9IGVsc2UgaWYgKHRva2VuLmtpbmQgPT0gTFBBUkVOKSB7CiAgICAgICAgICAgIEpDTmV3Q2xhc3MgbmV3Q2xhc3MgPSBjbGFzc0NyZWF0b3JSZXN0KG5ld3BvcywgbnVsbCwgdHlwZUFyZ3MsIHQpOwogICAgICAgICAgICBpZiAobmV3Q2xhc3MuZGVmICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIGFzc2VydCBuZXdDbGFzcy5kZWYubW9kcy5hbm5vdGF0aW9ucy5pc0VtcHR5KCk7CiAgICAgICAgICAgICAgICBpZiAobmV3QW5ub3RhdGlvbnMubm9uRW1wdHkoKSkgewogICAgICAgICAgICAgICAgICAgIC8vIEFkZCB0eXBlIGFuZCBkZWNsYXJhdGlvbiBhbm5vdGF0aW9ucyB0byB0aGUgbmV3IGNsYXNzOwogICAgICAgICAgICAgICAgICAgIC8vIGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5UeXBlQW5ub3RhdGlvbnMuVHlwZUFubm90YXRpb25Qb3NpdGlvbnMudmlzaXROZXdDbGFzcyhKQ05ld0NsYXNzKQogICAgICAgICAgICAgICAgICAgIC8vIHdpbGwgbGF0ZXIgcmVtb3ZlIGFsbCB0eXBlIGFubm90YXRpb25zIGFuZCBvbmx5IGxlYXZlIHRoZQogICAgICAgICAgICAgICAgICAgIC8vIGRlY2xhcmF0aW9uIGFubm90YXRpb25zLgogICAgICAgICAgICAgICAgICAgIG5ld0NsYXNzLmRlZi5tb2RzLnBvcyA9IGVhcmxpZXIobmV3Q2xhc3MuZGVmLm1vZHMucG9zLCBuZXdBbm5vdGF0aW9ucy5oZWFkLnBvcyk7CiAgICAgICAgICAgICAgICAgICAgbmV3Q2xhc3MuZGVmLm1vZHMuYW5ub3RhdGlvbnMgPSBuZXdBbm5vdGF0aW9uczsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIC8vIGhhbmRsZSB0eXBlIGFubm90YXRpb25zIGZvciBpbnN0YW50aWF0aW9ucwogICAgICAgICAgICAgICAgaWYgKG5ld0Fubm90YXRpb25zLm5vbkVtcHR5KCkpIHsKICAgICAgICAgICAgICAgICAgICB0ID0gaW5zZXJ0QW5ub3RhdGlvbnNUb01vc3RJbm5lcih0LCBuZXdBbm5vdGF0aW9ucywgZmFsc2UpOwogICAgICAgICAgICAgICAgICAgIG5ld0NsYXNzLmNsYXp6ID0gdDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gbmV3Q2xhc3M7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc2V0RXJyb3JFbmRQb3ModG9rZW4ucG9zKTsKICAgICAgICAgICAgcmVwb3J0U3ludGF4RXJyb3IodG9rZW4ucG9zLCAiZXhwZWN0ZWQyIiwgTFBBUkVOLCBMQlJBQ0tFVCk7CiAgICAgICAgICAgIHQgPSB0b1AoRi5hdChuZXdwb3MpLk5ld0NsYXNzKG51bGwsIHR5cGVBcmdzLCB0LCBMaXN0Lm5pbCgpLCBudWxsKSk7CiAgICAgICAgICAgIHJldHVybiB0b1AoRi5hdChuZXdwb3MpLkVycm9uZW91cyhMaXN0LjxKQ1RyZWU+b2YodCkpKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqIElubmVyQ3JlYXRvciA9IFtBbm5vdGF0aW9uc10gSWRlbnQgW1R5cGVBcmd1bWVudHNdIENsYXNzQ3JlYXRvclJlc3QKICAgICAqLwogICAgSkNFeHByZXNzaW9uIGlubmVyQ3JlYXRvcihpbnQgbmV3cG9zLCBMaXN0PEpDRXhwcmVzc2lvbj4gdHlwZUFyZ3MsIEpDRXhwcmVzc2lvbiBlbmNsKSB7CiAgICAgICAgTGlzdDxKQ0Fubm90YXRpb24+IG5ld0Fubm90YXRpb25zID0gdHlwZUFubm90YXRpb25zT3B0KCk7CgogICAgICAgIEpDRXhwcmVzc2lvbiB0ID0gdG9QKEYuYXQodG9rZW4ucG9zKS5JZGVudChpZGVudCgpKSk7CgogICAgICAgIGlmIChuZXdBbm5vdGF0aW9ucy5ub25FbXB0eSgpKSB7CiAgICAgICAgICAgIHQgPSB0b1AoRi5hdChuZXdBbm5vdGF0aW9ucy5oZWFkLnBvcykuQW5ub3RhdGVkVHlwZShuZXdBbm5vdGF0aW9ucywgdCkpOwogICAgICAgIH0KCiAgICAgICAgaWYgKHRva2VuLmtpbmQgPT0gTFQpIHsKICAgICAgICAgICAgaW50IG9sZG1vZGUgPSBtb2RlOwogICAgICAgICAgICB0ID0gdHlwZUFyZ3VtZW50cyh0LCB0cnVlKTsKICAgICAgICAgICAgbW9kZSA9IG9sZG1vZGU7CiAgICAgICAgfQogICAgICAgIHJldHVybiBjbGFzc0NyZWF0b3JSZXN0KG5ld3BvcywgZW5jbCwgdHlwZUFyZ3MsIHQpOwogICAgfQoKICAgIC8qKiBBcnJheUNyZWF0b3JSZXN0ID0gW0Fubm90YXRpb25zXSAiWyIgKCAiXSIgQnJhY2tldHNPcHQgQXJyYXlJbml0aWFsaXplcgogICAgICogICAgICAgICAgICAgICAgICAgICAgICAgfCBFeHByZXNzaW9uICJdIiB7W0Fubm90YXRpb25zXSAgIlsiIEV4cHJlc3Npb24gIl0ifSBCcmFja2V0c09wdCApCiAgICAgKi8KICAgIEpDRXhwcmVzc2lvbiBhcnJheUNyZWF0b3JSZXN0KGludCBuZXdwb3MsIEpDRXhwcmVzc2lvbiBlbGVtdHlwZSkgewogICAgICAgIExpc3Q8SkNBbm5vdGF0aW9uPiBhbm5vcyA9IHR5cGVBbm5vdGF0aW9uc09wdCgpOwoKICAgICAgICBhY2NlcHQoTEJSQUNLRVQpOwogICAgICAgIGlmICh0b2tlbi5raW5kID09IFJCUkFDS0VUKSB7CiAgICAgICAgICAgIGFjY2VwdChSQlJBQ0tFVCk7CiAgICAgICAgICAgIGVsZW10eXBlID0gYnJhY2tldHNPcHQoZWxlbXR5cGUsIGFubm9zKTsKICAgICAgICAgICAgaWYgKHRva2VuLmtpbmQgPT0gTEJSQUNFKSB7CiAgICAgICAgICAgICAgICBKQ05ld0FycmF5IG5hID0gKEpDTmV3QXJyYXkpYXJyYXlJbml0aWFsaXplcihuZXdwb3MsIGVsZW10eXBlKTsKICAgICAgICAgICAgICAgIGlmIChhbm5vcy5ub25FbXB0eSgpKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gd2hlbiBhbiBhcnJheSBpbml0aWFsaXplciBpcyBwcmVzZW50IHRoZW4KICAgICAgICAgICAgICAgICAgICAvLyB0aGUgcGFyc2VkIGFubm90YXRpb25zIHNob3VsZCB0YXJnZXQgdGhlCiAgICAgICAgICAgICAgICAgICAgLy8gbmV3IGFycmF5IHRyZWUKICAgICAgICAgICAgICAgICAgICAvLyBicmFja2V0c09wdCBpbnNlcnRzIHRoZSBhbm5vdGF0aW9uIGluCiAgICAgICAgICAgICAgICAgICAgLy8gZWxlbXR5cGUsIGFuZCBpdCBuZWVkcyB0byBiZSBjb3JyZWN0ZWQKICAgICAgICAgICAgICAgICAgICAvLwogICAgICAgICAgICAgICAgICAgIEpDQW5ub3RhdGVkVHlwZSBhbm5vdGF0ZWQgPSAoSkNBbm5vdGF0ZWRUeXBlKWVsZW10eXBlOwogICAgICAgICAgICAgICAgICAgIGFzc2VydCBhbm5vdGF0ZWQuYW5ub3RhdGlvbnMgPT0gYW5ub3M7CiAgICAgICAgICAgICAgICAgICAgbmEuYW5ub3RhdGlvbnMgPSBhbm5vdGF0ZWQuYW5ub3RhdGlvbnM7CiAgICAgICAgICAgICAgICAgICAgbmEuZWxlbXR5cGUgPSBhbm5vdGF0ZWQudW5kZXJseWluZ1R5cGU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gbmE7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBKQ0V4cHJlc3Npb24gdCA9IHRvUChGLmF0KG5ld3BvcykuTmV3QXJyYXkoZWxlbXR5cGUsIExpc3QubmlsKCksIG51bGwpKTsKICAgICAgICAgICAgICAgIHJldHVybiBzeW50YXhFcnJvcih0b2tlbi5wb3MsIExpc3Qub2YodCksICJhcnJheS5kaW1lbnNpb24ubWlzc2luZyIpOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgTGlzdEJ1ZmZlcjxKQ0V4cHJlc3Npb24+IGRpbXMgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CgogICAgICAgICAgICAvLyBtYWludGFpbiBhcnJheSBkaW1lbnNpb24gdHlwZSBhbm5vdGF0aW9ucwogICAgICAgICAgICBMaXN0QnVmZmVyPExpc3Q8SkNBbm5vdGF0aW9uPj4gZGltQW5ub3RhdGlvbnMgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgIGRpbUFubm90YXRpb25zLmFwcGVuZChhbm5vcyk7CgogICAgICAgICAgICBkaW1zLmFwcGVuZChwYXJzZUV4cHJlc3Npb24oKSk7CiAgICAgICAgICAgIGFjY2VwdChSQlJBQ0tFVCk7CiAgICAgICAgICAgIHdoaWxlICh0b2tlbi5raW5kID09IExCUkFDS0VUCiAgICAgICAgICAgICAgICAgICAgfHwgdG9rZW4ua2luZCA9PSBNT05LRVlTX0FUKSB7CiAgICAgICAgICAgICAgICBMaXN0PEpDQW5ub3RhdGlvbj4gbWF5YmVEaW1Bbm5vcyA9IHR5cGVBbm5vdGF0aW9uc09wdCgpOwogICAgICAgICAgICAgICAgaW50IHBvcyA9IHRva2VuLnBvczsKICAgICAgICAgICAgICAgIG5leHRUb2tlbigpOwogICAgICAgICAgICAgICAgaWYgKHRva2VuLmtpbmQgPT0gUkJSQUNLRVQpIHsKICAgICAgICAgICAgICAgICAgICBlbGVtdHlwZSA9IGJyYWNrZXRzT3B0Q29udChlbGVtdHlwZSwgcG9zLCBtYXliZURpbUFubm9zKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHRva2VuLmtpbmQgPT0gUkJSQUNLRVQpIHsgLy8gbm8gZGltZW5zaW9uCiAgICAgICAgICAgICAgICAgICAgICAgIGVsZW10eXBlID0gYnJhY2tldHNPcHRDb250KGVsZW10eXBlLCBwb3MsIG1heWJlRGltQW5ub3MpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGRpbUFubm90YXRpb25zLmFwcGVuZChtYXliZURpbUFubm9zKTsKICAgICAgICAgICAgICAgICAgICAgICAgZGltcy5hcHBlbmQocGFyc2VFeHByZXNzaW9uKCkpOwogICAgICAgICAgICAgICAgICAgICAgICBhY2NlcHQoUkJSQUNLRVQpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgSkNOZXdBcnJheSBuYSA9IHRvUChGLmF0KG5ld3BvcykuTmV3QXJyYXkoZWxlbXR5cGUsIGRpbXMudG9MaXN0KCksIG51bGwpKTsKICAgICAgICAgICAgbmEuZGltQW5ub3RhdGlvbnMgPSBkaW1Bbm5vdGF0aW9ucy50b0xpc3QoKTsKICAgICAgICAgICAgcmV0dXJuIG5hOwogICAgICAgIH0KICAgIH0KCiAgICAvKiogQ2xhc3NDcmVhdG9yUmVzdCA9IEFyZ3VtZW50cyBbQ2xhc3NCb2R5XQogICAgICovCiAgICBKQ05ld0NsYXNzIGNsYXNzQ3JlYXRvclJlc3QoaW50IG5ld3BvcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEpDRXhwcmVzc2lvbiBlbmNsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTGlzdDxKQ0V4cHJlc3Npb24+IHR5cGVBcmdzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSkNFeHByZXNzaW9uIHQpCiAgICB7CiAgICAgICAgTGlzdDxKQ0V4cHJlc3Npb24+IGFyZ3MgPSBhcmd1bWVudHMoKTsKICAgICAgICBKQ0NsYXNzRGVjbCBib2R5ID0gbnVsbDsKICAgICAgICBpZiAodG9rZW4ua2luZCA9PSBMQlJBQ0UpIHsKICAgICAgICAgICAgaW50IHBvcyA9IHRva2VuLnBvczsKICAgICAgICAgICAgTGlzdDxKQ1RyZWU+IGRlZnMgPSBjbGFzc09ySW50ZXJmYWNlQm9keShuYW1lcy5lbXB0eSwgZmFsc2UpOwogICAgICAgICAgICBKQ01vZGlmaWVycyBtb2RzID0gRi5hdChQb3NpdGlvbi5OT1BPUykuTW9kaWZpZXJzKDApOwogICAgICAgICAgICBib2R5ID0gdG9QKEYuYXQocG9zKS5Bbm9ueW1vdXNDbGFzc0RlZihtb2RzLCBkZWZzKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0b1AoRi5hdChuZXdwb3MpLk5ld0NsYXNzKGVuY2wsIHR5cGVBcmdzLCB0LCBhcmdzLCBib2R5KSk7CiAgICB9CgogICAgLyoqIEFycmF5SW5pdGlhbGl6ZXIgPSAieyIgW1ZhcmlhYmxlSW5pdGlhbGl6ZXIgeyIsIiBWYXJpYWJsZUluaXRpYWxpemVyfV0gWyIsIl0gIn0iCiAgICAgKi8KICAgIEpDRXhwcmVzc2lvbiBhcnJheUluaXRpYWxpemVyKGludCBuZXdwb3MsIEpDRXhwcmVzc2lvbiB0KSB7CiAgICAgICAgYWNjZXB0KExCUkFDRSk7CiAgICAgICAgTGlzdEJ1ZmZlcjxKQ0V4cHJlc3Npb24+IGVsZW1zID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgIGlmICh0b2tlbi5raW5kID09IENPTU1BKSB7CiAgICAgICAgICAgIG5leHRUb2tlbigpOwogICAgICAgIH0gZWxzZSBpZiAodG9rZW4ua2luZCAhPSBSQlJBQ0UpIHsKICAgICAgICAgICAgZWxlbXMuYXBwZW5kKHZhcmlhYmxlSW5pdGlhbGl6ZXIoKSk7CiAgICAgICAgICAgIHdoaWxlICh0b2tlbi5raW5kID09IENPTU1BKSB7CiAgICAgICAgICAgICAgICBuZXh0VG9rZW4oKTsKICAgICAgICAgICAgICAgIGlmICh0b2tlbi5raW5kID09IFJCUkFDRSkgYnJlYWs7CiAgICAgICAgICAgICAgICBlbGVtcy5hcHBlbmQodmFyaWFibGVJbml0aWFsaXplcigpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBhY2NlcHQoUkJSQUNFKTsKICAgICAgICByZXR1cm4gdG9QKEYuYXQobmV3cG9zKS5OZXdBcnJheSh0LCBMaXN0Lm5pbCgpLCBlbGVtcy50b0xpc3QoKSkpOwogICAgfQoKICAgIC8qKiBWYXJpYWJsZUluaXRpYWxpemVyID0gQXJyYXlJbml0aWFsaXplciB8IEV4cHJlc3Npb24KICAgICAqLwogICAgcHVibGljIEpDRXhwcmVzc2lvbiB2YXJpYWJsZUluaXRpYWxpemVyKCkgewogICAgICAgIHJldHVybiB0b2tlbi5raW5kID09IExCUkFDRSA/IGFycmF5SW5pdGlhbGl6ZXIodG9rZW4ucG9zLCBudWxsKSA6IHBhcnNlRXhwcmVzc2lvbigpOwogICAgfQoKICAgIC8qKiBQYXJFeHByZXNzaW9uID0gIigiIEV4cHJlc3Npb24gIikiCiAgICAgKi8KICAgIEpDRXhwcmVzc2lvbiBwYXJFeHByZXNzaW9uKCkgewogICAgICAgIGludCBwb3MgPSB0b2tlbi5wb3M7CiAgICAgICAgYWNjZXB0KExQQVJFTik7CiAgICAgICAgSkNFeHByZXNzaW9uIHQgPSBwYXJzZUV4cHJlc3Npb24oKTsKICAgICAgICBhY2NlcHQoUlBBUkVOKTsKICAgICAgICByZXR1cm4gdG9QKEYuYXQocG9zKS5QYXJlbnModCkpOwogICAgfQoKICAgIC8qKiBCbG9jayA9ICJ7IiBCbG9ja1N0YXRlbWVudHMgIn0iCiAgICAgKi8KICAgIEpDQmxvY2sgYmxvY2soaW50IHBvcywgbG9uZyBmbGFncykgewogICAgICAgIGFjY2VwdChMQlJBQ0UpOwogICAgICAgIExpc3Q8SkNTdGF0ZW1lbnQ+IHN0YXRzID0gYmxvY2tTdGF0ZW1lbnRzKCk7CiAgICAgICAgSkNCbG9jayB0ID0gRi5hdChwb3MpLkJsb2NrKGZsYWdzLCBzdGF0cyk7CiAgICAgICAgd2hpbGUgKHRva2VuLmtpbmQgPT0gQ0FTRSB8fCB0b2tlbi5raW5kID09IERFRkFVTFQpIHsKICAgICAgICAgICAgc3ludGF4RXJyb3IoIm9ycGhhbmVkIiwgdG9rZW4ua2luZCk7CiAgICAgICAgICAgIHN3aXRjaEJsb2NrU3RhdGVtZW50R3JvdXBzKCk7CiAgICAgICAgfQogICAgICAgIC8vIHRoZSBCbG9jayBub2RlIGhhcyBhIGZpZWxkICJlbmRwb3MiIGZvciBmaXJzdCBjaGFyIG9mIGxhc3QgdG9rZW4sIHdoaWNoIGlzCiAgICAgICAgLy8gdXN1YWxseSBidXQgbm90IG5lY2Vzc2FyaWx5IHRoZSBsYXN0IGNoYXIgb2YgdGhlIGxhc3QgdG9rZW4uCiAgICAgICAgdC5lbmRwb3MgPSB0b2tlbi5wb3M7CiAgICAgICAgYWNjZXB0KFJCUkFDRSk7CiAgICAgICAgcmV0dXJuIHRvUCh0KTsKICAgIH0KCiAgICBwdWJsaWMgSkNCbG9jayBibG9jaygpIHsKICAgICAgICByZXR1cm4gYmxvY2sodG9rZW4ucG9zLCAwKTsKICAgIH0KCiAgICAvKiogQmxvY2tTdGF0ZW1lbnRzID0geyBCbG9ja1N0YXRlbWVudCB9CiAgICAgKiAgQmxvY2tTdGF0ZW1lbnQgID0gTG9jYWxWYXJpYWJsZURlY2xhcmF0aW9uU3RhdGVtZW50CiAgICAgKiAgICAgICAgICAgICAgICAgIHwgQ2xhc3NPckludGVyZmFjZU9yRW51bURlY2xhcmF0aW9uCiAgICAgKiAgICAgICAgICAgICAgICAgIHwgW0lkZW50ICI6Il0gU3RhdGVtZW50CiAgICAgKiAgTG9jYWxWYXJpYWJsZURlY2xhcmF0aW9uU3RhdGVtZW50CiAgICAgKiAgICAgICAgICAgICAgICAgID0geyBGSU5BTCB8ICdAJyBBbm5vdGF0aW9uIH0gVHlwZSBWYXJpYWJsZURlY2xhcmF0b3JzICI7IgogICAgICovCiAgICBAU3VwcHJlc3NXYXJuaW5ncygiZmFsbHRocm91Z2giKQogICAgTGlzdDxKQ1N0YXRlbWVudD4gYmxvY2tTdGF0ZW1lbnRzKCkgewogICAgICAgIC8vdG9kbzogc2tpcCB0byBhbmNob3Igb24gZXJyb3IoPykKICAgICAgICBpbnQgbGFzdEVyclBvcyA9IC0xOwogICAgICAgIExpc3RCdWZmZXI8SkNTdGF0ZW1lbnQ+IHN0YXRzID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgIHdoaWxlICh0cnVlKSB7CiAgICAgICAgICAgIExpc3Q8SkNTdGF0ZW1lbnQ+IHN0YXQgPSBibG9ja1N0YXRlbWVudCgpOwogICAgICAgICAgICBpZiAoc3RhdC5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICAgIHJldHVybiBzdGF0cy50b0xpc3QoKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIC8vIGVycm9yIHJlY292ZXJ5CiAgICAgICAgICAgICAgICBpZiAodG9rZW4ucG9zID09IGxhc3RFcnJQb3MpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHN0YXRzLnRvTGlzdCgpOwogICAgICAgICAgICAgICAgaWYgKHRva2VuLnBvcyA8PSBlbmRQb3NUYWJsZS5lcnJvckVuZFBvcykgewogICAgICAgICAgICAgICAgICAgIHNraXAoZmFsc2UsIHRydWUsIHRydWUsIHRydWUpOwogICAgICAgICAgICAgICAgICAgIGxhc3RFcnJQb3MgPSB0b2tlbi5wb3M7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBzdGF0cy5hZGRBbGwoc3RhdCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoKICAgICAqIFBhcnNlIGEgU3RhdGVtZW50IChKTFMgMTQuNSkuIEFzIGFuIGVuaGFuY2VtZW50IHRvIGltcHJvdmUgZXJyb3IgcmVjb3ZlcnksCiAgICAgKiB0aGlzIG1ldGhvZCB3aWxsIGFsc28gcmVjb2duaXplIHZhcmlhYmxlIGFuZCBjbGFzcyBkZWNsYXJhdGlvbnMgKHdoaWNoIGFyZQogICAgICogbm90IGxlZ2FsIGZvciBhIFN0YXRlbWVudCkgYnkgZGVsZWdhdGluZyB0aGUgcGFyc2luZyB0byBCbG9ja1N0YXRlbWVudCAoSkxTIDE0LjIpLgogICAgICogSWYgYW55IGlsbGVnYWwgZGVjbGFyYXRpb25zIGFyZSBmb3VuZCwgdGhleSB3aWxsIGJlIHdyYXBwZWQgaW4gYW4gZXJyb25lb3VzIHRyZWUsCiAgICAgKiBhbmQgYW4gZXJyb3Igd2lsbCBiZSBwcm9kdWNlZCBieSB0aGlzIG1ldGhvZC4KICAgICAqLwogICAgSkNTdGF0ZW1lbnQgcGFyc2VTdGF0ZW1lbnRBc0Jsb2NrKCkgewogICAgICAgIGludCBwb3MgPSB0b2tlbi5wb3M7CiAgICAgICAgTGlzdDxKQ1N0YXRlbWVudD4gc3RhdHMgPSBibG9ja1N0YXRlbWVudCgpOwogICAgICAgIGlmIChzdGF0cy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgSkNFcnJvbmVvdXMgZSA9IEYuYXQocG9zKS5FcnJvbmVvdXMoKTsKICAgICAgICAgICAgZXJyb3IoZSwgImlsbGVnYWwuc3RhcnQub2Yuc3RtdCIpOwogICAgICAgICAgICByZXR1cm4gRi5hdChwb3MpLkV4ZWMoZSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgSkNTdGF0ZW1lbnQgZmlyc3QgPSBzdGF0cy5oZWFkOwogICAgICAgICAgICBTdHJpbmcgZXJyb3IgPSBudWxsOwogICAgICAgICAgICBzd2l0Y2ggKGZpcnN0LmdldFRhZygpKSB7CiAgICAgICAgICAgIGNhc2UgQ0xBU1NERUY6CiAgICAgICAgICAgICAgICBlcnJvciA9ICJjbGFzcy5ub3QuYWxsb3dlZCI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBWQVJERUY6CiAgICAgICAgICAgICAgICBlcnJvciA9ICJ2YXJpYWJsZS5ub3QuYWxsb3dlZCI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoZXJyb3IgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgZXJyb3IoZmlyc3QsIGVycm9yKTsKICAgICAgICAgICAgICAgIExpc3Q8SkNCbG9jaz4gYmxpc3QgPSBMaXN0Lm9mKEYuYXQoZmlyc3QucG9zKS5CbG9jaygwLCBzdGF0cykpOwogICAgICAgICAgICAgICAgcmV0dXJuIHRvUChGLmF0KHBvcykuRXhlYyhGLmF0KGZpcnN0LnBvcykuRXJyb25lb3VzKGJsaXN0KSkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBmaXJzdDsKICAgICAgICB9CiAgICB9CgogICAgLyoqVGhpcyBtZXRob2QgcGFyc2VzIGEgc3RhdGVtZW50IGFwcGVhcmluZyBpbnNpZGUgYSBibG9jay4KICAgICAqLwogICAgTGlzdDxKQ1N0YXRlbWVudD4gYmxvY2tTdGF0ZW1lbnQoKSB7CiAgICAgICAgLy90b2RvOiBza2lwIHRvIGFuY2hvciBvbiBlcnJvcig/KQogICAgICAgIGludCBwb3MgPSB0b2tlbi5wb3M7CiAgICAgICAgc3dpdGNoICh0b2tlbi5raW5kKSB7CiAgICAgICAgY2FzZSBSQlJBQ0U6IGNhc2UgQ0FTRTogY2FzZSBERUZBVUxUOiBjYXNlIEVPRjoKICAgICAgICAgICAgcmV0dXJuIExpc3QubmlsKCk7CiAgICAgICAgY2FzZSBMQlJBQ0U6IGNhc2UgSUY6IGNhc2UgRk9SOiBjYXNlIFdISUxFOiBjYXNlIERPOiBjYXNlIFRSWToKICAgICAgICBjYXNlIFNXSVRDSDogY2FzZSBTWU5DSFJPTklaRUQ6IGNhc2UgUkVUVVJOOiBjYXNlIFRIUk9XOiBjYXNlIEJSRUFLOgogICAgICAgIGNhc2UgQ09OVElOVUU6IGNhc2UgU0VNSTogY2FzZSBFTFNFOiBjYXNlIEZJTkFMTFk6IGNhc2UgQ0FUQ0g6CiAgICAgICAgY2FzZSBBU1NFUlQ6CiAgICAgICAgICAgIHJldHVybiBMaXN0Lm9mKHBhcnNlU2ltcGxlU3RhdGVtZW50KCkpOwogICAgICAgIGNhc2UgTU9OS0VZU19BVDoKICAgICAgICBjYXNlIEZJTkFMOiB7CiAgICAgICAgICAgIENvbW1lbnQgZGMgPSB0b2tlbi5jb21tZW50KENvbW1lbnRTdHlsZS5KQVZBRE9DKTsKICAgICAgICAgICAgSkNNb2RpZmllcnMgbW9kcyA9IG1vZGlmaWVyc09wdCgpOwogICAgICAgICAgICBpZiAodG9rZW4ua2luZCA9PSBJTlRFUkZBQ0UgfHwKICAgICAgICAgICAgICAgIHRva2VuLmtpbmQgPT0gQ0xBU1MgfHwKICAgICAgICAgICAgICAgIHRva2VuLmtpbmQgPT0gRU5VTSkgewogICAgICAgICAgICAgICAgcmV0dXJuIExpc3Qub2YoY2xhc3NPckludGVyZmFjZU9yRW51bURlY2xhcmF0aW9uKG1vZHMsIGRjKSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBKQ0V4cHJlc3Npb24gdCA9IHBhcnNlVHlwZSgpOwogICAgICAgICAgICAgICAgTGlzdEJ1ZmZlcjxKQ1N0YXRlbWVudD4gc3RhdHMgPQogICAgICAgICAgICAgICAgICAgICAgICB2YXJpYWJsZURlY2xhcmF0b3JzKG1vZHMsIHQsIG5ldyBMaXN0QnVmZmVyPEpDU3RhdGVtZW50PigpKTsKICAgICAgICAgICAgICAgIC8vIEEgIkxvY2FsVmFyaWFibGVEZWNsYXJhdGlvblN0YXRlbWVudCIgc3Vic3VtZXMgdGhlIHRlcm1pbmF0aW5nIHNlbWljb2xvbgogICAgICAgICAgICAgICAgYWNjZXB0KFNFTUkpOwogICAgICAgICAgICAgICAgc3RvcmVFbmQoc3RhdHMubGFzdCgpLCBTLnByZXZUb2tlbigpLmVuZFBvcyk7CiAgICAgICAgICAgICAgICByZXR1cm4gc3RhdHMudG9MaXN0KCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgY2FzZSBBQlNUUkFDVDogY2FzZSBTVFJJQ1RGUDogewogICAgICAgICAgICBDb21tZW50IGRjID0gdG9rZW4uY29tbWVudChDb21tZW50U3R5bGUuSkFWQURPQyk7CiAgICAgICAgICAgIEpDTW9kaWZpZXJzIG1vZHMgPSBtb2RpZmllcnNPcHQoKTsKICAgICAgICAgICAgcmV0dXJuIExpc3Qub2YoY2xhc3NPckludGVyZmFjZU9yRW51bURlY2xhcmF0aW9uKG1vZHMsIGRjKSk7CiAgICAgICAgfQogICAgICAgIGNhc2UgSU5URVJGQUNFOgogICAgICAgIGNhc2UgQ0xBU1M6CiAgICAgICAgICAgIENvbW1lbnQgZGMgPSB0b2tlbi5jb21tZW50KENvbW1lbnRTdHlsZS5KQVZBRE9DKTsKICAgICAgICAgICAgcmV0dXJuIExpc3Qub2YoY2xhc3NPckludGVyZmFjZU9yRW51bURlY2xhcmF0aW9uKG1vZGlmaWVyc09wdCgpLCBkYykpOwogICAgICAgIGNhc2UgRU5VTToKICAgICAgICAgICAgZXJyb3IodG9rZW4ucG9zLCAibG9jYWwuZW51bSIpOwogICAgICAgICAgICBkYyA9IHRva2VuLmNvbW1lbnQoQ29tbWVudFN0eWxlLkpBVkFET0MpOwogICAgICAgICAgICByZXR1cm4gTGlzdC5vZihjbGFzc09ySW50ZXJmYWNlT3JFbnVtRGVjbGFyYXRpb24obW9kaWZpZXJzT3B0KCksIGRjKSk7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgVG9rZW4gcHJldlRva2VuID0gdG9rZW47CiAgICAgICAgICAgIEpDRXhwcmVzc2lvbiB0ID0gdGVybShFWFBSIHwgVFlQRSk7CiAgICAgICAgICAgIGlmICh0b2tlbi5raW5kID09IENPTE9OICYmIHQuaGFzVGFnKElERU5UKSkgewogICAgICAgICAgICAgICAgbmV4dFRva2VuKCk7CiAgICAgICAgICAgICAgICBKQ1N0YXRlbWVudCBzdGF0ID0gcGFyc2VTdGF0ZW1lbnRBc0Jsb2NrKCk7CiAgICAgICAgICAgICAgICByZXR1cm4gTGlzdC5vZihGLmF0KHBvcykuTGFiZWxsZWQocHJldlRva2VuLm5hbWUoKSwgc3RhdCkpOwogICAgICAgICAgICB9IGVsc2UgaWYgKChsYXN0bW9kZSAmIFRZUEUpICE9IDAgJiYgTEFYX0lERU5USUZJRVIuYWNjZXB0cyh0b2tlbi5raW5kKSkgewogICAgICAgICAgICAgICAgcG9zID0gdG9rZW4ucG9zOwogICAgICAgICAgICAgICAgSkNNb2RpZmllcnMgbW9kcyA9IEYuYXQoUG9zaXRpb24uTk9QT1MpLk1vZGlmaWVycygwKTsKICAgICAgICAgICAgICAgIEYuYXQocG9zKTsKICAgICAgICAgICAgICAgIExpc3RCdWZmZXI8SkNTdGF0ZW1lbnQ+IHN0YXRzID0KICAgICAgICAgICAgICAgICAgICAgICAgdmFyaWFibGVEZWNsYXJhdG9ycyhtb2RzLCB0LCBuZXcgTGlzdEJ1ZmZlcjxKQ1N0YXRlbWVudD4oKSk7CiAgICAgICAgICAgICAgICAvLyBBICJMb2NhbFZhcmlhYmxlRGVjbGFyYXRpb25TdGF0ZW1lbnQiIHN1YnN1bWVzIHRoZSB0ZXJtaW5hdGluZyBzZW1pY29sb24KICAgICAgICAgICAgICAgIGFjY2VwdChTRU1JKTsKICAgICAgICAgICAgICAgIHN0b3JlRW5kKHN0YXRzLmxhc3QoKSwgUy5wcmV2VG9rZW4oKS5lbmRQb3MpOwogICAgICAgICAgICAgICAgcmV0dXJuIHN0YXRzLnRvTGlzdCgpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgLy8gVGhpcyBFeGVjIGlzIGFuICJFeHByZXNzaW9uU3RhdGVtZW50IjsgaXQgc3Vic3VtZXMgdGhlIHRlcm1pbmF0aW5nIHNlbWljb2xvbgogICAgICAgICAgICAgICAgdCA9IGNoZWNrRXhwclN0YXQodCk7CiAgICAgICAgICAgICAgICBhY2NlcHQoU0VNSSk7CiAgICAgICAgICAgICAgICBKQ0V4cHJlc3Npb25TdGF0ZW1lbnQgZXhwciA9IHRvUChGLmF0KHBvcykuRXhlYyh0KSk7CiAgICAgICAgICAgICAgICByZXR1cm4gTGlzdC5vZihleHByKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKiogU3RhdGVtZW50ID0KICAgICAqICAgICAgIEJsb2NrCiAgICAgKiAgICAgfCBJRiBQYXJFeHByZXNzaW9uIFN0YXRlbWVudCBbRUxTRSBTdGF0ZW1lbnRdCiAgICAgKiAgICAgfCBGT1IgIigiIEZvckluaXRPcHQgIjsiIFtFeHByZXNzaW9uXSAiOyIgRm9yVXBkYXRlT3B0ICIpIiBTdGF0ZW1lbnQKICAgICAqICAgICB8IEZPUiAiKCIgRm9ybWFsUGFyYW1ldGVyIDogRXhwcmVzc2lvbiAiKSIgU3RhdGVtZW50CiAgICAgKiAgICAgfCBXSElMRSBQYXJFeHByZXNzaW9uIFN0YXRlbWVudAogICAgICogICAgIHwgRE8gU3RhdGVtZW50IFdISUxFIFBhckV4cHJlc3Npb24gIjsiCiAgICAgKiAgICAgfCBUUlkgQmxvY2sgKCBDYXRjaGVzIHwgW0NhdGNoZXNdIEZpbmFsbHlQYXJ0ICkKICAgICAqICAgICB8IFRSWSAiKCIgUmVzb3VyY2VTcGVjaWZpY2F0aW9uICI7Im9wdCAiKSIgQmxvY2sgW0NhdGNoZXNdIFtGaW5hbGx5UGFydF0KICAgICAqICAgICB8IFNXSVRDSCBQYXJFeHByZXNzaW9uICJ7IiBTd2l0Y2hCbG9ja1N0YXRlbWVudEdyb3VwcyAifSIKICAgICAqICAgICB8IFNZTkNIUk9OSVpFRCBQYXJFeHByZXNzaW9uIEJsb2NrCiAgICAgKiAgICAgfCBSRVRVUk4gW0V4cHJlc3Npb25dICI7IgogICAgICogICAgIHwgVEhST1cgRXhwcmVzc2lvbiAiOyIKICAgICAqICAgICB8IEJSRUFLIFtJZGVudF0gIjsiCiAgICAgKiAgICAgfCBDT05USU5VRSBbSWRlbnRdICI7IgogICAgICogICAgIHwgQVNTRVJUIEV4cHJlc3Npb24gWyAiOiIgRXhwcmVzc2lvbiBdICI7IgogICAgICogICAgIHwgIjsiCiAgICAgKi8KICAgIHB1YmxpYyBKQ1N0YXRlbWVudCBwYXJzZVNpbXBsZVN0YXRlbWVudCgpIHsKICAgICAgICBpbnQgcG9zID0gdG9rZW4ucG9zOwogICAgICAgIHN3aXRjaCAodG9rZW4ua2luZCkgewogICAgICAgIGNhc2UgTEJSQUNFOgogICAgICAgICAgICByZXR1cm4gYmxvY2soKTsKICAgICAgICBjYXNlIElGOiB7CiAgICAgICAgICAgIG5leHRUb2tlbigpOwogICAgICAgICAgICBKQ0V4cHJlc3Npb24gY29uZCA9IHBhckV4cHJlc3Npb24oKTsKICAgICAgICAgICAgSkNTdGF0ZW1lbnQgdGhlbnBhcnQgPSBwYXJzZVN0YXRlbWVudEFzQmxvY2soKTsKICAgICAgICAgICAgSkNTdGF0ZW1lbnQgZWxzZXBhcnQgPSBudWxsOwogICAgICAgICAgICBpZiAodG9rZW4ua2luZCA9PSBFTFNFKSB7CiAgICAgICAgICAgICAgICBuZXh0VG9rZW4oKTsKICAgICAgICAgICAgICAgIGVsc2VwYXJ0ID0gcGFyc2VTdGF0ZW1lbnRBc0Jsb2NrKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIEYuYXQocG9zKS5JZihjb25kLCB0aGVucGFydCwgZWxzZXBhcnQpOwogICAgICAgIH0KICAgICAgICBjYXNlIEZPUjogewogICAgICAgICAgICBuZXh0VG9rZW4oKTsKICAgICAgICAgICAgYWNjZXB0KExQQVJFTik7CiAgICAgICAgICAgIExpc3Q8SkNTdGF0ZW1lbnQ+IGluaXRzID0gdG9rZW4ua2luZCA9PSBTRU1JID8gTGlzdC5uaWwoKSA6IGZvckluaXQoKTsKICAgICAgICAgICAgaWYgKGluaXRzLmxlbmd0aCgpID09IDEgJiYKICAgICAgICAgICAgICAgIGluaXRzLmhlYWQuaGFzVGFnKFZBUkRFRikgJiYKICAgICAgICAgICAgICAgICgoSkNWYXJpYWJsZURlY2wpIGluaXRzLmhlYWQpLmluaXQgPT0gbnVsbCAmJgogICAgICAgICAgICAgICAgdG9rZW4ua2luZCA9PSBDT0xPTikgewogICAgICAgICAgICAgICAgSkNWYXJpYWJsZURlY2wgdmFyID0gKEpDVmFyaWFibGVEZWNsKWluaXRzLmhlYWQ7CiAgICAgICAgICAgICAgICBhY2NlcHQoQ09MT04pOwogICAgICAgICAgICAgICAgSkNFeHByZXNzaW9uIGV4cHIgPSBwYXJzZUV4cHJlc3Npb24oKTsKICAgICAgICAgICAgICAgIGFjY2VwdChSUEFSRU4pOwogICAgICAgICAgICAgICAgSkNTdGF0ZW1lbnQgYm9keSA9IHBhcnNlU3RhdGVtZW50QXNCbG9jaygpOwogICAgICAgICAgICAgICAgcmV0dXJuIEYuYXQocG9zKS5Gb3JlYWNoTG9vcCh2YXIsIGV4cHIsIGJvZHkpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgYWNjZXB0KFNFTUkpOwogICAgICAgICAgICAgICAgSkNFeHByZXNzaW9uIGNvbmQgPSB0b2tlbi5raW5kID09IFNFTUkgPyBudWxsIDogcGFyc2VFeHByZXNzaW9uKCk7CiAgICAgICAgICAgICAgICBhY2NlcHQoU0VNSSk7CiAgICAgICAgICAgICAgICBMaXN0PEpDRXhwcmVzc2lvblN0YXRlbWVudD4gc3RlcHMgPSB0b2tlbi5raW5kID09IFJQQVJFTiA/IExpc3QubmlsKCkgOiBmb3JVcGRhdGUoKTsKICAgICAgICAgICAgICAgIGFjY2VwdChSUEFSRU4pOwogICAgICAgICAgICAgICAgSkNTdGF0ZW1lbnQgYm9keSA9IHBhcnNlU3RhdGVtZW50QXNCbG9jaygpOwogICAgICAgICAgICAgICAgcmV0dXJuIEYuYXQocG9zKS5Gb3JMb29wKGluaXRzLCBjb25kLCBzdGVwcywgYm9keSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgY2FzZSBXSElMRTogewogICAgICAgICAgICBuZXh0VG9rZW4oKTsKICAgICAgICAgICAgSkNFeHByZXNzaW9uIGNvbmQgPSBwYXJFeHByZXNzaW9uKCk7CiAgICAgICAgICAgIEpDU3RhdGVtZW50IGJvZHkgPSBwYXJzZVN0YXRlbWVudEFzQmxvY2soKTsKICAgICAgICAgICAgcmV0dXJuIEYuYXQocG9zKS5XaGlsZUxvb3AoY29uZCwgYm9keSk7CiAgICAgICAgfQogICAgICAgIGNhc2UgRE86IHsKICAgICAgICAgICAgbmV4dFRva2VuKCk7CiAgICAgICAgICAgIEpDU3RhdGVtZW50IGJvZHkgPSBwYXJzZVN0YXRlbWVudEFzQmxvY2soKTsKICAgICAgICAgICAgYWNjZXB0KFdISUxFKTsKICAgICAgICAgICAgSkNFeHByZXNzaW9uIGNvbmQgPSBwYXJFeHByZXNzaW9uKCk7CiAgICAgICAgICAgIGFjY2VwdChTRU1JKTsKICAgICAgICAgICAgSkNEb1doaWxlTG9vcCB0ID0gdG9QKEYuYXQocG9zKS5Eb0xvb3AoYm9keSwgY29uZCkpOwogICAgICAgICAgICByZXR1cm4gdDsKICAgICAgICB9CiAgICAgICAgY2FzZSBUUlk6IHsKICAgICAgICAgICAgbmV4dFRva2VuKCk7CiAgICAgICAgICAgIExpc3Q8SkNUcmVlPiByZXNvdXJjZXMgPSBMaXN0Lm5pbCgpOwogICAgICAgICAgICBpZiAodG9rZW4ua2luZCA9PSBMUEFSRU4pIHsKICAgICAgICAgICAgICAgIGNoZWNrVHJ5V2l0aFJlc291cmNlcygpOwogICAgICAgICAgICAgICAgbmV4dFRva2VuKCk7CiAgICAgICAgICAgICAgICByZXNvdXJjZXMgPSByZXNvdXJjZXMoKTsKICAgICAgICAgICAgICAgIGFjY2VwdChSUEFSRU4pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIEpDQmxvY2sgYm9keSA9IGJsb2NrKCk7CiAgICAgICAgICAgIExpc3RCdWZmZXI8SkNDYXRjaD4gY2F0Y2hlcnMgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgIEpDQmxvY2sgZmluYWxpemVyID0gbnVsbDsKICAgICAgICAgICAgaWYgKHRva2VuLmtpbmQgPT0gQ0FUQ0ggfHwgdG9rZW4ua2luZCA9PSBGSU5BTExZKSB7CiAgICAgICAgICAgICAgICB3aGlsZSAodG9rZW4ua2luZCA9PSBDQVRDSCkgY2F0Y2hlcnMuYXBwZW5kKGNhdGNoQ2xhdXNlKCkpOwogICAgICAgICAgICAgICAgaWYgKHRva2VuLmtpbmQgPT0gRklOQUxMWSkgewogICAgICAgICAgICAgICAgICAgIG5leHRUb2tlbigpOwogICAgICAgICAgICAgICAgICAgIGZpbmFsaXplciA9IGJsb2NrKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBpZiAocmVzb3VyY2VzLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgICAgICAgIGlmIChhbGxvd1RXUikgewogICAgICAgICAgICAgICAgICAgICAgICBlcnJvcihwb3MsICJ0cnkud2l0aG91dC5jYXRjaC5maW5hbGx5Lm9yLnJlc291cmNlLmRlY2xzIik7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3IocG9zLCAidHJ5LndpdGhvdXQuY2F0Y2gub3IuZmluYWxseSIpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gRi5hdChwb3MpLlRyeShyZXNvdXJjZXMsIGJvZHksIGNhdGNoZXJzLnRvTGlzdCgpLCBmaW5hbGl6ZXIpOwogICAgICAgIH0KICAgICAgICBjYXNlIFNXSVRDSDogewogICAgICAgICAgICBuZXh0VG9rZW4oKTsKICAgICAgICAgICAgSkNFeHByZXNzaW9uIHNlbGVjdG9yID0gcGFyRXhwcmVzc2lvbigpOwogICAgICAgICAgICBhY2NlcHQoTEJSQUNFKTsKICAgICAgICAgICAgTGlzdDxKQ0Nhc2U+IGNhc2VzID0gc3dpdGNoQmxvY2tTdGF0ZW1lbnRHcm91cHMoKTsKICAgICAgICAgICAgSkNTd2l0Y2ggdCA9IHRvKEYuYXQocG9zKS5Td2l0Y2goc2VsZWN0b3IsIGNhc2VzKSk7CiAgICAgICAgICAgIGFjY2VwdChSQlJBQ0UpOwogICAgICAgICAgICByZXR1cm4gdDsKICAgICAgICB9CiAgICAgICAgY2FzZSBTWU5DSFJPTklaRUQ6IHsKICAgICAgICAgICAgbmV4dFRva2VuKCk7CiAgICAgICAgICAgIEpDRXhwcmVzc2lvbiBsb2NrID0gcGFyRXhwcmVzc2lvbigpOwogICAgICAgICAgICBKQ0Jsb2NrIGJvZHkgPSBibG9jaygpOwogICAgICAgICAgICByZXR1cm4gRi5hdChwb3MpLlN5bmNocm9uaXplZChsb2NrLCBib2R5KTsKICAgICAgICB9CiAgICAgICAgY2FzZSBSRVRVUk46IHsKICAgICAgICAgICAgbmV4dFRva2VuKCk7CiAgICAgICAgICAgIEpDRXhwcmVzc2lvbiByZXN1bHQgPSB0b2tlbi5raW5kID09IFNFTUkgPyBudWxsIDogcGFyc2VFeHByZXNzaW9uKCk7CiAgICAgICAgICAgIGFjY2VwdChTRU1JKTsKICAgICAgICAgICAgSkNSZXR1cm4gdCA9IHRvUChGLmF0KHBvcykuUmV0dXJuKHJlc3VsdCkpOwogICAgICAgICAgICByZXR1cm4gdDsKICAgICAgICB9CiAgICAgICAgY2FzZSBUSFJPVzogewogICAgICAgICAgICBuZXh0VG9rZW4oKTsKICAgICAgICAgICAgSkNFeHByZXNzaW9uIGV4YyA9IHBhcnNlRXhwcmVzc2lvbigpOwogICAgICAgICAgICBhY2NlcHQoU0VNSSk7CiAgICAgICAgICAgIEpDVGhyb3cgdCA9IHRvUChGLmF0KHBvcykuVGhyb3coZXhjKSk7CiAgICAgICAgICAgIHJldHVybiB0OwogICAgICAgIH0KICAgICAgICBjYXNlIEJSRUFLOiB7CiAgICAgICAgICAgIG5leHRUb2tlbigpOwogICAgICAgICAgICBOYW1lIGxhYmVsID0gTEFYX0lERU5USUZJRVIuYWNjZXB0cyh0b2tlbi5raW5kKSA/IGlkZW50KCkgOiBudWxsOwogICAgICAgICAgICBhY2NlcHQoU0VNSSk7CiAgICAgICAgICAgIEpDQnJlYWsgdCA9IHRvUChGLmF0KHBvcykuQnJlYWsobGFiZWwpKTsKICAgICAgICAgICAgcmV0dXJuIHQ7CiAgICAgICAgfQogICAgICAgIGNhc2UgQ09OVElOVUU6IHsKICAgICAgICAgICAgbmV4dFRva2VuKCk7CiAgICAgICAgICAgIE5hbWUgbGFiZWwgPSBMQVhfSURFTlRJRklFUi5hY2NlcHRzKHRva2VuLmtpbmQpID8gaWRlbnQoKSA6IG51bGw7CiAgICAgICAgICAgIGFjY2VwdChTRU1JKTsKICAgICAgICAgICAgSkNDb250aW51ZSB0ID0gIHRvUChGLmF0KHBvcykuQ29udGludWUobGFiZWwpKTsKICAgICAgICAgICAgcmV0dXJuIHQ7CiAgICAgICAgfQogICAgICAgIGNhc2UgU0VNSToKICAgICAgICAgICAgbmV4dFRva2VuKCk7CiAgICAgICAgICAgIHJldHVybiB0b1AoRi5hdChwb3MpLlNraXAoKSk7CiAgICAgICAgY2FzZSBFTFNFOgogICAgICAgICAgICBpbnQgZWxzZVBvcyA9IHRva2VuLnBvczsKICAgICAgICAgICAgbmV4dFRva2VuKCk7CiAgICAgICAgICAgIHJldHVybiBkb1JlY292ZXIoZWxzZVBvcywgQmFzaWNFcnJvclJlY292ZXJ5QWN0aW9uLkJMT0NLX1NUTVQsICJlbHNlLndpdGhvdXQuaWYiKTsKICAgICAgICBjYXNlIEZJTkFMTFk6CiAgICAgICAgICAgIGludCBmaW5hbGx5UG9zID0gdG9rZW4ucG9zOwogICAgICAgICAgICBuZXh0VG9rZW4oKTsKICAgICAgICAgICAgcmV0dXJuIGRvUmVjb3ZlcihmaW5hbGx5UG9zLCBCYXNpY0Vycm9yUmVjb3ZlcnlBY3Rpb24uQkxPQ0tfU1RNVCwgImZpbmFsbHkud2l0aG91dC50cnkiKTsKICAgICAgICBjYXNlIENBVENIOgogICAgICAgICAgICByZXR1cm4gZG9SZWNvdmVyKHRva2VuLnBvcywgQmFzaWNFcnJvclJlY292ZXJ5QWN0aW9uLkNBVENIX0NMQVVTRSwgImNhdGNoLndpdGhvdXQudHJ5Iik7CiAgICAgICAgY2FzZSBBU1NFUlQ6IHsKICAgICAgICAgICAgbmV4dFRva2VuKCk7CiAgICAgICAgICAgIEpDRXhwcmVzc2lvbiBhc3NlcnRpb24gPSBwYXJzZUV4cHJlc3Npb24oKTsKICAgICAgICAgICAgSkNFeHByZXNzaW9uIG1lc3NhZ2UgPSBudWxsOwogICAgICAgICAgICBpZiAodG9rZW4ua2luZCA9PSBDT0xPTikgewogICAgICAgICAgICAgICAgbmV4dFRva2VuKCk7CiAgICAgICAgICAgICAgICBtZXNzYWdlID0gcGFyc2VFeHByZXNzaW9uKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYWNjZXB0KFNFTUkpOwogICAgICAgICAgICBKQ0Fzc2VydCB0ID0gdG9QKEYuYXQocG9zKS5Bc3NlcnQoYXNzZXJ0aW9uLCBtZXNzYWdlKSk7CiAgICAgICAgICAgIHJldHVybiB0OwogICAgICAgIH0KICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBBc3NlcnQuZXJyb3IoKTsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIEpDU3RhdGVtZW50IHBhcnNlU3RhdGVtZW50KCkgewogICAgICAgIHJldHVybiBwYXJzZVN0YXRlbWVudEFzQmxvY2soKTsKICAgIH0KCiAgICBwcml2YXRlIEpDU3RhdGVtZW50IGRvUmVjb3ZlcihpbnQgc3RhcnRQb3MsIEVycm9yUmVjb3ZlcnlBY3Rpb24gYWN0aW9uLCBTdHJpbmcga2V5KSB7CiAgICAgICAgaW50IGVyclBvcyA9IFMuZXJyUG9zKCk7CiAgICAgICAgSkNUcmVlIHN0bSA9IGFjdGlvbi5kb1JlY292ZXIodGhpcyk7CiAgICAgICAgUy5lcnJQb3MoZXJyUG9zKTsKICAgICAgICByZXR1cm4gdG9QKEYuRXhlYyhzeW50YXhFcnJvcihzdGFydFBvcywgTGlzdC5vZihzdG0pLCBrZXkpKSk7CiAgICB9CgogICAgLyoqIENhdGNoQ2xhdXNlICAgICA9IENBVENIICIoIiBGb3JtYWxQYXJhbWV0ZXIgIikiIEJsb2NrCiAgICAgKiBUT0RPOiB0aGUgIkZvcm1hbFBhcmFtZXRlciIgaXMgbm90IGNvcnJlY3QsIGl0IHVzZXMgdGhlIHNwZWNpYWwgImNhdGNoVHlwZXMiIHJ1bGUgYmVsb3cuCiAgICAgKi8KICAgIHByb3RlY3RlZCBKQ0NhdGNoIGNhdGNoQ2xhdXNlKCkgewogICAgICAgIGludCBwb3MgPSB0b2tlbi5wb3M7CiAgICAgICAgYWNjZXB0KENBVENIKTsKICAgICAgICBhY2NlcHQoTFBBUkVOKTsKICAgICAgICBKQ01vZGlmaWVycyBtb2RzID0gb3B0RmluYWwoRmxhZ3MuUEFSQU1FVEVSKTsKICAgICAgICBMaXN0PEpDRXhwcmVzc2lvbj4gY2F0Y2hUeXBlcyA9IGNhdGNoVHlwZXMoKTsKICAgICAgICBKQ0V4cHJlc3Npb24gcGFyYW1UeXBlID0gY2F0Y2hUeXBlcy5zaXplKCkgPiAxID8KICAgICAgICAgICAgICAgIHRvUChGLmF0KGNhdGNoVHlwZXMuaGVhZC5nZXRTdGFydFBvc2l0aW9uKCkpLlR5cGVVbmlvbihjYXRjaFR5cGVzKSkgOgogICAgICAgICAgICAgICAgY2F0Y2hUeXBlcy5oZWFkOwogICAgICAgIEpDVmFyaWFibGVEZWNsIGZvcm1hbCA9IHZhcmlhYmxlRGVjbGFyYXRvcklkKG1vZHMsIHBhcmFtVHlwZSk7CiAgICAgICAgYWNjZXB0KFJQQVJFTik7CiAgICAgICAgSkNCbG9jayBib2R5ID0gYmxvY2soKTsKICAgICAgICByZXR1cm4gRi5hdChwb3MpLkNhdGNoKGZvcm1hbCwgYm9keSk7CiAgICB9CgogICAgTGlzdDxKQ0V4cHJlc3Npb24+IGNhdGNoVHlwZXMoKSB7CiAgICAgICAgTGlzdEJ1ZmZlcjxKQ0V4cHJlc3Npb24+IGNhdGNoVHlwZXMgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgY2F0Y2hUeXBlcy5hZGQocGFyc2VUeXBlKCkpOwogICAgICAgIHdoaWxlICh0b2tlbi5raW5kID09IEJBUikgewogICAgICAgICAgICBjaGVja011bHRpY2F0Y2goKTsKICAgICAgICAgICAgbmV4dFRva2VuKCk7CiAgICAgICAgICAgIC8vIEluc3RlYWQgb2YgcXVhbGlkZW50IHRoaXMgaXMgbm93IHBhcnNlVHlwZS4KICAgICAgICAgICAgLy8gQnV0IHdvdWxkIHRoYXQgYWxsb3cgdG9vIG11Y2gsIGUuZy4gYXJyYXlzIG9yIGdlbmVyaWNzPwogICAgICAgICAgICBjYXRjaFR5cGVzLmFkZChwYXJzZVR5cGUoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBjYXRjaFR5cGVzLnRvTGlzdCgpOwogICAgfQoKICAgIC8qKiBTd2l0Y2hCbG9ja1N0YXRlbWVudEdyb3VwcyA9IHsgU3dpdGNoQmxvY2tTdGF0ZW1lbnRHcm91cCB9CiAgICAgKiAgU3dpdGNoQmxvY2tTdGF0ZW1lbnRHcm91cCA9IFN3aXRjaExhYmVsIEJsb2NrU3RhdGVtZW50cwogICAgICogIFN3aXRjaExhYmVsID0gQ0FTRSBDb25zdGFudEV4cHJlc3Npb24gIjoiIHwgREVGQVVMVCAiOiIKICAgICAqLwogICAgTGlzdDxKQ0Nhc2U+IHN3aXRjaEJsb2NrU3RhdGVtZW50R3JvdXBzKCkgewogICAgICAgIExpc3RCdWZmZXI8SkNDYXNlPiBjYXNlcyA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICB3aGlsZSAodHJ1ZSkgewogICAgICAgICAgICBpbnQgcG9zID0gdG9rZW4ucG9zOwogICAgICAgICAgICBzd2l0Y2ggKHRva2VuLmtpbmQpIHsKICAgICAgICAgICAgY2FzZSBDQVNFOgogICAgICAgICAgICBjYXNlIERFRkFVTFQ6CiAgICAgICAgICAgICAgICBjYXNlcy5hcHBlbmQoc3dpdGNoQmxvY2tTdGF0ZW1lbnRHcm91cCgpKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFJCUkFDRTogY2FzZSBFT0Y6CiAgICAgICAgICAgICAgICByZXR1cm4gY2FzZXMudG9MaXN0KCk7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICBuZXh0VG9rZW4oKTsgLy8gdG8gZW5zdXJlIHByb2dyZXNzCiAgICAgICAgICAgICAgICBzeW50YXhFcnJvcihwb3MsICJleHBlY3RlZDMiLAogICAgICAgICAgICAgICAgICAgIENBU0UsIERFRkFVTFQsIFJCUkFDRSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgcHJvdGVjdGVkIEpDQ2FzZSBzd2l0Y2hCbG9ja1N0YXRlbWVudEdyb3VwKCkgewogICAgICAgIGludCBwb3MgPSB0b2tlbi5wb3M7CiAgICAgICAgTGlzdDxKQ1N0YXRlbWVudD4gc3RhdHM7CiAgICAgICAgSkNDYXNlIGM7CiAgICAgICAgc3dpdGNoICh0b2tlbi5raW5kKSB7CiAgICAgICAgY2FzZSBDQVNFOgogICAgICAgICAgICBuZXh0VG9rZW4oKTsKICAgICAgICAgICAgSkNFeHByZXNzaW9uIHBhdCA9IHBhcnNlRXhwcmVzc2lvbigpOwogICAgICAgICAgICBhY2NlcHQoQ09MT04pOwogICAgICAgICAgICBzdGF0cyA9IGJsb2NrU3RhdGVtZW50cygpOwogICAgICAgICAgICBjID0gRi5hdChwb3MpLkNhc2UocGF0LCBzdGF0cyk7CiAgICAgICAgICAgIGlmIChzdGF0cy5pc0VtcHR5KCkpCiAgICAgICAgICAgICAgICBzdG9yZUVuZChjLCBTLnByZXZUb2tlbigpLmVuZFBvcyk7CiAgICAgICAgICAgIHJldHVybiBjOwogICAgICAgIGNhc2UgREVGQVVMVDoKICAgICAgICAgICAgbmV4dFRva2VuKCk7CiAgICAgICAgICAgIGFjY2VwdChDT0xPTik7CiAgICAgICAgICAgIHN0YXRzID0gYmxvY2tTdGF0ZW1lbnRzKCk7CiAgICAgICAgICAgIGMgPSBGLmF0KHBvcykuQ2FzZShudWxsLCBzdGF0cyk7CiAgICAgICAgICAgIGlmIChzdGF0cy5pc0VtcHR5KCkpCiAgICAgICAgICAgICAgICBzdG9yZUVuZChjLCBTLnByZXZUb2tlbigpLmVuZFBvcyk7CiAgICAgICAgICAgIHJldHVybiBjOwogICAgICAgIH0KICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoInNob3VsZCBub3QgcmVhY2ggaGVyZSIpOwogICAgfQoKICAgIC8qKiBNb3JlU3RhdGVtZW50RXhwcmVzc2lvbnMgPSB7IENPTU1BIFN0YXRlbWVudEV4cHJlc3Npb24gfQogICAgICovCiAgICA8VCBleHRlbmRzIExpc3RCdWZmZXI8PyBzdXBlciBKQ0V4cHJlc3Npb25TdGF0ZW1lbnQ+PiBUIG1vcmVTdGF0ZW1lbnRFeHByZXNzaW9ucyhpbnQgcG9zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEpDRXhwcmVzc2lvbiBmaXJzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUIHN0YXRzKSB7CiAgICAgICAgLy8gVGhpcyBFeGVjIGlzIGEgIlN0YXRlbWVudEV4cHJlc3Npb24iOyBpdCBzdWJzdW1lcyBubyB0ZXJtaW5hdGluZyB0b2tlbgogICAgICAgIHN0YXRzLmFwcGVuZCh0b1AoRi5hdChwb3MpLkV4ZWMoY2hlY2tFeHByU3RhdChmaXJzdCkpKSk7CiAgICAgICAgd2hpbGUgKHRva2VuLmtpbmQgPT0gQ09NTUEpIHsKICAgICAgICAgICAgbmV4dFRva2VuKCk7CiAgICAgICAgICAgIHBvcyA9IHRva2VuLnBvczsKICAgICAgICAgICAgSkNFeHByZXNzaW9uIHQgPSBwYXJzZUV4cHJlc3Npb24oKTsKICAgICAgICAgICAgLy8gVGhpcyBFeGVjIGlzIGEgIlN0YXRlbWVudEV4cHJlc3Npb24iOyBpdCBzdWJzdW1lcyBubyB0ZXJtaW5hdGluZyB0b2tlbgogICAgICAgICAgICBzdGF0cy5hcHBlbmQodG9QKEYuYXQocG9zKS5FeGVjKGNoZWNrRXhwclN0YXQodCkpKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzdGF0czsKICAgIH0KCiAgICAvKiogRm9ySW5pdCA9IFN0YXRlbWVudEV4cHJlc3Npb24gTW9yZVN0YXRlbWVudEV4cHJlc3Npb25zCiAgICAgKiAgICAgICAgICAgfCAgeyBGSU5BTCB8ICdAJyBBbm5vdGF0aW9uIH0gVHlwZSBWYXJpYWJsZURlY2xhcmF0b3JzCiAgICAgKi8KICAgIExpc3Q8SkNTdGF0ZW1lbnQ+IGZvckluaXQoKSB7CiAgICAgICAgTGlzdEJ1ZmZlcjxKQ1N0YXRlbWVudD4gc3RhdHMgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgaW50IHBvcyA9IHRva2VuLnBvczsKICAgICAgICBpZiAodG9rZW4ua2luZCA9PSBGSU5BTCB8fCB0b2tlbi5raW5kID09IE1PTktFWVNfQVQpIHsKICAgICAgICAgICAgcmV0dXJuIHZhcmlhYmxlRGVjbGFyYXRvcnMob3B0RmluYWwoMCksIHBhcnNlVHlwZSgpLCBzdGF0cykudG9MaXN0KCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgSkNFeHByZXNzaW9uIHQgPSB0ZXJtKEVYUFIgfCBUWVBFKTsKICAgICAgICAgICAgaWYgKChsYXN0bW9kZSAmIFRZUEUpICE9IDAgJiYgTEFYX0lERU5USUZJRVIuYWNjZXB0cyh0b2tlbi5raW5kKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIHZhcmlhYmxlRGVjbGFyYXRvcnMobW9kaWZpZXJzT3B0KCksIHQsIHN0YXRzKS50b0xpc3QoKTsKICAgICAgICAgICAgfSBlbHNlIGlmICgobGFzdG1vZGUgJiBUWVBFKSAhPSAwICYmIHRva2VuLmtpbmQgPT0gQ09MT04pIHsKICAgICAgICAgICAgICAgIGVycm9yKHBvcywgImJhZC5pbml0aWFsaXplciIsICJmb3ItbG9vcCIpOwogICAgICAgICAgICAgICAgcmV0dXJuIExpc3Qub2YoKEpDU3RhdGVtZW50KUYuYXQocG9zKS5WYXJEZWYobnVsbCwgbnVsbCwgdCwgbnVsbCkpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcmV0dXJuIG1vcmVTdGF0ZW1lbnRFeHByZXNzaW9ucyhwb3MsIHQsIHN0YXRzKS50b0xpc3QoKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKiogRm9yVXBkYXRlID0gU3RhdGVtZW50RXhwcmVzc2lvbiBNb3JlU3RhdGVtZW50RXhwcmVzc2lvbnMKICAgICAqLwogICAgTGlzdDxKQ0V4cHJlc3Npb25TdGF0ZW1lbnQ+IGZvclVwZGF0ZSgpIHsKICAgICAgICByZXR1cm4gbW9yZVN0YXRlbWVudEV4cHJlc3Npb25zKHRva2VuLnBvcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcnNlRXhwcmVzc2lvbigpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IExpc3RCdWZmZXI8SkNFeHByZXNzaW9uU3RhdGVtZW50PigpKS50b0xpc3QoKTsKICAgIH0KCiAgICAvKiogQW5ub3RhdGlvbnNPcHQgPSB7ICdAJyBBbm5vdGF0aW9uIH0KICAgICAqCiAgICAgKiBAcGFyYW0ga2luZCBXaGV0aGVyIHRvIHBhcnNlIGFuIEFOTk9UQVRJT04gb3IgVFlQRV9BTk5PVEFUSU9OCiAgICAgKi8KICAgIHByb3RlY3RlZCBMaXN0PEpDQW5ub3RhdGlvbj4gYW5ub3RhdGlvbnNPcHQoVGFnIGtpbmQpIHsKICAgICAgICBpZiAodG9rZW4ua2luZCAhPSBNT05LRVlTX0FUKSByZXR1cm4gTGlzdC5uaWwoKTsgLy8gb3B0aW1pemF0aW9uCiAgICAgICAgTGlzdEJ1ZmZlcjxKQ0Fubm90YXRpb24+IGJ1ZiA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICBpbnQgcHJldm1vZGUgPSBtb2RlOwogICAgICAgIHdoaWxlICh0b2tlbi5raW5kID09IE1PTktFWVNfQVQpIHsKICAgICAgICAgICAgaW50IHBvcyA9IHRva2VuLnBvczsKICAgICAgICAgICAgbmV4dFRva2VuKCk7CiAgICAgICAgICAgIGJ1Zi5hcHBlbmQoYW5ub3RhdGlvbihwb3MsIGtpbmQpKTsKICAgICAgICB9CiAgICAgICAgbGFzdG1vZGUgPSBtb2RlOwogICAgICAgIG1vZGUgPSBwcmV2bW9kZTsKICAgICAgICBMaXN0PEpDQW5ub3RhdGlvbj4gYW5ub3RhdGlvbnMgPSBidWYudG9MaXN0KCk7CgogICAgICAgIHJldHVybiBhbm5vdGF0aW9uczsKICAgIH0KCiAgICBMaXN0PEpDQW5ub3RhdGlvbj4gdHlwZUFubm90YXRpb25zT3B0KCkgewogICAgICAgIExpc3Q8SkNBbm5vdGF0aW9uPiBhbm5vdGF0aW9ucyA9IGFubm90YXRpb25zT3B0KFRhZy5UWVBFX0FOTk9UQVRJT04pOwogICAgICAgIHJldHVybiBhbm5vdGF0aW9uczsKICAgIH0KCiAgICAvKiogTW9kaWZpZXJzT3B0ID0geyBNb2RpZmllciB9CiAgICAgKiAgTW9kaWZpZXIgPSBQVUJMSUMgfCBQUk9URUNURUQgfCBQUklWQVRFIHwgU1RBVElDIHwgQUJTVFJBQ1QgfCBGSU5BTAogICAgICogICAgICAgICAgIHwgTkFUSVZFIHwgU1lOQ0hST05JWkVEIHwgVFJBTlNJRU5UIHwgVk9MQVRJTEUgfCAiQCIKICAgICAqICAgICAgICAgICB8ICJAIiBBbm5vdGF0aW9uCiAgICAgKi8KICAgIHByb3RlY3RlZCBKQ01vZGlmaWVycyBtb2RpZmllcnNPcHQoKSB7CiAgICAgICAgcmV0dXJuIG1vZGlmaWVyc09wdChudWxsKTsKICAgIH0KICAgIHByb3RlY3RlZCBKQ01vZGlmaWVycyBtb2RpZmllcnNPcHQoSkNNb2RpZmllcnMgcGFydGlhbCkgewogICAgICAgIGxvbmcgZmxhZ3M7CiAgICAgICAgTGlzdEJ1ZmZlcjxKQ0Fubm90YXRpb24+IGFubm90YXRpb25zID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgIGludCBwb3M7CiAgICAgICAgaWYgKHBhcnRpYWwgPT0gbnVsbCkgewogICAgICAgICAgICBmbGFncyA9IDA7CiAgICAgICAgICAgIHBvcyA9IHRva2VuLnBvczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBmbGFncyA9IHBhcnRpYWwuZmxhZ3M7CiAgICAgICAgICAgIGFubm90YXRpb25zLmFwcGVuZExpc3QocGFydGlhbC5hbm5vdGF0aW9ucyk7CiAgICAgICAgICAgIHBvcyA9IHBhcnRpYWwucG9zOwogICAgICAgIH0KICAgICAgICBpZiAodG9rZW4uZGVwcmVjYXRlZEZsYWcoKSkgewogICAgICAgICAgICBmbGFncyB8PSBGbGFncy5ERVBSRUNBVEVEOwogICAgICAgIH0KICAgICAgICBpbnQgbGFzdFBvczsKICAgIGxvb3A6CiAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgICAgbG9uZyBmbGFnOwogICAgICAgICAgICBzd2l0Y2ggKHRva2VuLmtpbmQpIHsKICAgICAgICAgICAgY2FzZSBQUklWQVRFICAgICA6IGZsYWcgPSBGbGFncy5QUklWQVRFOyBicmVhazsKICAgICAgICAgICAgY2FzZSBQUk9URUNURUQgICA6IGZsYWcgPSBGbGFncy5QUk9URUNURUQ7IGJyZWFrOwogICAgICAgICAgICBjYXNlIFBVQkxJQyAgICAgIDogZmxhZyA9IEZsYWdzLlBVQkxJQzsgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgU1RBVElDICAgICAgOiBmbGFnID0gRmxhZ3MuU1RBVElDOyBicmVhazsKICAgICAgICAgICAgY2FzZSBUUkFOU0lFTlQgICA6IGZsYWcgPSBGbGFncy5UUkFOU0lFTlQ7IGJyZWFrOwogICAgICAgICAgICBjYXNlIEZJTkFMICAgICAgIDogZmxhZyA9IEZsYWdzLkZJTkFMOyBicmVhazsKICAgICAgICAgICAgY2FzZSBBQlNUUkFDVCAgICA6IGZsYWcgPSBGbGFncy5BQlNUUkFDVDsgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgTkFUSVZFICAgICAgOiBmbGFnID0gRmxhZ3MuTkFUSVZFOyBicmVhazsKICAgICAgICAgICAgY2FzZSBWT0xBVElMRSAgICA6IGZsYWcgPSBGbGFncy5WT0xBVElMRTsgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgU1lOQ0hST05JWkVEOiBmbGFnID0gRmxhZ3MuU1lOQ0hST05JWkVEOyBicmVhazsKICAgICAgICAgICAgY2FzZSBTVFJJQ1RGUCAgICA6IGZsYWcgPSBGbGFncy5TVFJJQ1RGUDsgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgTU9OS0VZU19BVCAgOiBmbGFnID0gRmxhZ3MuQU5OT1RBVElPTjsgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgREVGQVVMVCAgICAgOiBjaGVja0RlZmF1bHRNZXRob2RzKCk7IGZsYWcgPSBGbGFncy5ERUZBVUxUOyBicmVhazsKICAgICAgICAgICAgY2FzZSBFUlJPUiAgICAgICA6IGZsYWcgPSAwOyBuZXh0VG9rZW4oKTsgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6IGJyZWFrIGxvb3A7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKChmbGFncyAmIGZsYWcpICE9IDApIGVycm9yKHRva2VuLnBvcywgInJlcGVhdGVkLm1vZGlmaWVyIik7CiAgICAgICAgICAgIGxhc3RQb3MgPSB0b2tlbi5wb3M7CiAgICAgICAgICAgIG5leHRUb2tlbigpOwogICAgICAgICAgICBpZiAoZmxhZyA9PSBGbGFncy5BTk5PVEFUSU9OKSB7CiAgICAgICAgICAgICAgICBpZiAodG9rZW4ua2luZCAhPSBJTlRFUkZBQ0UpIHsKICAgICAgICAgICAgICAgICAgICBKQ0Fubm90YXRpb24gYW5uID0gYW5ub3RhdGlvbihsYXN0UG9zLCBUYWcuQU5OT1RBVElPTik7CiAgICAgICAgICAgICAgICAgICAgLy8gaWYgZmlyc3QgbW9kaWZpZXIgaXMgYW4gYW5ub3RhdGlvbiwgc2V0IHBvcyB0byBhbm5vdGF0aW9uJ3MuCiAgICAgICAgICAgICAgICAgICAgaWYgKGZsYWdzID09IDAgJiYgYW5ub3RhdGlvbnMuaXNFbXB0eSgpKQogICAgICAgICAgICAgICAgICAgICAgICBwb3MgPSBhbm4ucG9zOwogICAgICAgICAgICAgICAgICAgIGFubm90YXRpb25zLmFwcGVuZChhbm4pOwogICAgICAgICAgICAgICAgICAgIGZsYWcgPSAwOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGZsYWdzIHw9IGZsYWc7CiAgICAgICAgfQogICAgICAgIHN3aXRjaCAodG9rZW4ua2luZCkgewogICAgICAgIGNhc2UgRU5VTTogZmxhZ3MgfD0gRmxhZ3MuRU5VTTsgYnJlYWs7CiAgICAgICAgY2FzZSBJTlRFUkZBQ0U6IGZsYWdzIHw9IEZsYWdzLklOVEVSRkFDRTsgYnJlYWs7CiAgICAgICAgZGVmYXVsdDogYnJlYWs7CiAgICAgICAgfQoKICAgICAgICAvKiBBIG1vZGlmaWVycyB0cmVlIHdpdGggbm8gbW9kaWZpZXIgdG9rZW5zIG9yIGFubm90YXRpb25zCiAgICAgICAgICogaGFzIG5vIHRleHQgcG9zaXRpb24uICovCiAgICAgICAgaWYgKChmbGFncyAmIChGbGFncy5Nb2RpZmllckZsYWdzIHwgRmxhZ3MuQU5OT1RBVElPTikpID09IDAgJiYgYW5ub3RhdGlvbnMuaXNFbXB0eSgpKQogICAgICAgICAgICBwb3MgPSBQb3NpdGlvbi5OT1BPUzsKCiAgICAgICAgSkNNb2RpZmllcnMgbW9kcyA9IEYuYXQocG9zKS5Nb2RpZmllcnMoZmxhZ3MsIGFubm90YXRpb25zLnRvTGlzdCgpKTsKICAgICAgICBpZiAocG9zICE9IFBvc2l0aW9uLk5PUE9TKQogICAgICAgICAgICBzdG9yZUVuZChtb2RzLCBTLnByZXZUb2tlbigpLmVuZFBvcyk7CiAgICAgICAgcmV0dXJuIG1vZHM7CiAgICB9CgogICAgLyoqIEFubm90YXRpb24gICAgICAgICAgICAgID0gIkAiIFF1YWxpZGVudCBbICIoIiBBbm5vdGF0aW9uRmllbGRWYWx1ZXMgIikiIF0KICAgICAqCiAgICAgKiBAcGFyYW0gcG9zIHBvc2l0aW9uIG9mICJAIiB0b2tlbgogICAgICogQHBhcmFtIGtpbmQgV2hldGhlciB0byBwYXJzZSBhbiBBTk5PVEFUSU9OIG9yIFRZUEVfQU5OT1RBVElPTgogICAgICovCiAgICBKQ0Fubm90YXRpb24gYW5ub3RhdGlvbihpbnQgcG9zLCBUYWcga2luZCkgewogICAgICAgIC8vIGFjY2VwdChBVCk7IC8vIEFUIGNvbnN1bWVkIGJ5IGNhbGxlcgogICAgICAgIGlmIChraW5kID09IFRhZy5UWVBFX0FOTk9UQVRJT04pIHsKICAgICAgICAgICAgY2hlY2tUeXBlQW5ub3RhdGlvbnMoKTsKICAgICAgICB9CiAgICAgICAgSkNUcmVlIGlkZW50ID0gcXVhbGlkZW50KGZhbHNlKTsKICAgICAgICBMaXN0PEpDRXhwcmVzc2lvbj4gZmllbGRWYWx1ZXMgPSBhbm5vdGF0aW9uRmllbGRWYWx1ZXNPcHQoKTsKICAgICAgICBKQ0Fubm90YXRpb24gYW5uOwogICAgICAgIGlmIChraW5kID09IFRhZy5BTk5PVEFUSU9OKSB7CiAgICAgICAgICAgIGFubiA9IEYuYXQocG9zKS5Bbm5vdGF0aW9uKGlkZW50LCBmaWVsZFZhbHVlcyk7CiAgICAgICAgfSBlbHNlIGlmIChraW5kID09IFRhZy5UWVBFX0FOTk9UQVRJT04pIHsKICAgICAgICAgICAgYW5uID0gRi5hdChwb3MpLlR5cGVBbm5vdGF0aW9uKGlkZW50LCBmaWVsZFZhbHVlcyk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCJVbmhhbmRsZWQgYW5ub3RhdGlvbiBraW5kOiAiICsga2luZCk7CiAgICAgICAgfQoKICAgICAgICBzdG9yZUVuZChhbm4sIFMucHJldlRva2VuKCkuZW5kUG9zKTsKICAgICAgICByZXR1cm4gYW5uOwogICAgfQoKICAgIExpc3Q8SkNFeHByZXNzaW9uPiBhbm5vdGF0aW9uRmllbGRWYWx1ZXNPcHQoKSB7CiAgICAgICAgcmV0dXJuICh0b2tlbi5raW5kID09IExQQVJFTikgPyBhbm5vdGF0aW9uRmllbGRWYWx1ZXMoKSA6IExpc3QubmlsKCk7CiAgICB9CgogICAgLyoqIEFubm90YXRpb25GaWVsZFZhbHVlcyAgID0gIigiIFsgQW5ub3RhdGlvbkZpZWxkVmFsdWUgeyAiLCIgQW5ub3RhdGlvbkZpZWxkVmFsdWUgfSBdICIpIiAqLwogICAgTGlzdDxKQ0V4cHJlc3Npb24+IGFubm90YXRpb25GaWVsZFZhbHVlcygpIHsKICAgICAgICBhY2NlcHQoTFBBUkVOKTsKICAgICAgICBMaXN0QnVmZmVyPEpDRXhwcmVzc2lvbj4gYnVmID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgIGlmICh0b2tlbi5raW5kICE9IFJQQVJFTikgewogICAgICAgICAgICBidWYuYXBwZW5kKGFubm90YXRpb25GaWVsZFZhbHVlKCkpOwogICAgICAgICAgICB3aGlsZSAodG9rZW4ua2luZCA9PSBDT01NQSkgewogICAgICAgICAgICAgICAgbmV4dFRva2VuKCk7CiAgICAgICAgICAgICAgICBidWYuYXBwZW5kKGFubm90YXRpb25GaWVsZFZhbHVlKCkpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGFjY2VwdChSUEFSRU4pOwogICAgICAgIHJldHVybiBidWYudG9MaXN0KCk7CiAgICB9CgogICAgLyoqIEFubm90YXRpb25GaWVsZFZhbHVlICAgID0gQW5ub3RhdGlvblZhbHVlCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgfCBJZGVudGlmaWVyICI9IiBBbm5vdGF0aW9uVmFsdWUKICAgICAqLwogICAgSkNFeHByZXNzaW9uIGFubm90YXRpb25GaWVsZFZhbHVlKCkgewogICAgICAgIGlmIChMQVhfSURFTlRJRklFUi5hY2NlcHRzKHRva2VuLmtpbmQpKSB7CiAgICAgICAgICAgIG1vZGUgPSBFWFBSOwogICAgICAgICAgICBKQ0V4cHJlc3Npb24gdDEgPSB0ZXJtMSgpOwogICAgICAgICAgICBpZiAodDEuaGFzVGFnKElERU5UKSAmJiB0b2tlbi5raW5kID09IEVRKSB7CiAgICAgICAgICAgICAgICBpbnQgcG9zID0gdG9rZW4ucG9zOwogICAgICAgICAgICAgICAgYWNjZXB0KEVRKTsKICAgICAgICAgICAgICAgIEpDRXhwcmVzc2lvbiB2ID0gYW5ub3RhdGlvblZhbHVlKCk7CiAgICAgICAgICAgICAgICByZXR1cm4gdG9QKEYuYXQocG9zKS5Bc3NpZ24odDEsIHYpKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHJldHVybiB0MTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gYW5ub3RhdGlvblZhbHVlKCk7CiAgICB9CgogICAgLyogQW5ub3RhdGlvblZhbHVlICAgICAgICAgID0gQ29uZGl0aW9uYWxFeHByZXNzaW9uCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgfCBBbm5vdGF0aW9uCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgfCAieyIgWyBBbm5vdGF0aW9uVmFsdWUgeyAiLCIgQW5ub3RhdGlvblZhbHVlIH0gXSBbIiwiXSAifSIKICAgICAqLwogICAgSkNFeHByZXNzaW9uIGFubm90YXRpb25WYWx1ZSgpIHsKICAgICAgICBpbnQgcG9zOwogICAgICAgIHN3aXRjaCAodG9rZW4ua2luZCkgewogICAgICAgIGNhc2UgTU9OS0VZU19BVDoKICAgICAgICAgICAgcG9zID0gdG9rZW4ucG9zOwogICAgICAgICAgICBuZXh0VG9rZW4oKTsKICAgICAgICAgICAgcmV0dXJuIGFubm90YXRpb24ocG9zLCBUYWcuQU5OT1RBVElPTik7CiAgICAgICAgY2FzZSBMQlJBQ0U6CiAgICAgICAgICAgIHBvcyA9IHRva2VuLnBvczsKICAgICAgICAgICAgYWNjZXB0KExCUkFDRSk7CiAgICAgICAgICAgIExpc3RCdWZmZXI8SkNFeHByZXNzaW9uPiBidWYgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgIGlmICh0b2tlbi5raW5kID09IENPTU1BKSB7CiAgICAgICAgICAgICAgICBuZXh0VG9rZW4oKTsKICAgICAgICAgICAgfSBlbHNlIGlmICh0b2tlbi5raW5kICE9IFJCUkFDRSkgewogICAgICAgICAgICAgICAgYnVmLmFwcGVuZChhbm5vdGF0aW9uVmFsdWUoKSk7CiAgICAgICAgICAgICAgICB3aGlsZSAodG9rZW4ua2luZCA9PSBDT01NQSkgewogICAgICAgICAgICAgICAgICAgIG5leHRUb2tlbigpOwogICAgICAgICAgICAgICAgICAgIGlmICh0b2tlbi5raW5kID09IFJCUkFDRSkgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgYnVmLmFwcGVuZChhbm5vdGF0aW9uVmFsdWUoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYWNjZXB0KFJCUkFDRSk7CiAgICAgICAgICAgIHJldHVybiB0b1AoRi5hdChwb3MpLk5ld0FycmF5KG51bGwsIExpc3QubmlsKCksIGJ1Zi50b0xpc3QoKSkpOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIG1vZGUgPSBFWFBSOwogICAgICAgICAgICByZXR1cm4gdGVybTEoKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqIFZhcmlhYmxlRGVjbGFyYXRvcnMgPSBWYXJpYWJsZURlY2xhcmF0b3IgeyAiLCIgVmFyaWFibGVEZWNsYXJhdG9yIH0KICAgICAqLwogICAgcHVibGljIDxUIGV4dGVuZHMgTGlzdEJ1ZmZlcjw/IHN1cGVyIEpDVmFyaWFibGVEZWNsPj4gVCB2YXJpYWJsZURlY2xhcmF0b3JzKEpDTW9kaWZpZXJzIG1vZHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBKQ0V4cHJlc3Npb24gdHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFQgdmRlZnMpCiAgICB7CiAgICAgICAgcmV0dXJuIHZhcmlhYmxlRGVjbGFyYXRvcnNSZXN0KHRva2VuLnBvcywgbW9kcywgdHlwZSwgaWRlbnQoKSwgZmFsc2UsIG51bGwsIHZkZWZzKTsKICAgIH0KCiAgICAvKiogVmFyaWFibGVEZWNsYXJhdG9yc1Jlc3QgPSBWYXJpYWJsZURlY2xhcmF0b3JSZXN0IHsgIiwiIFZhcmlhYmxlRGVjbGFyYXRvciB9CiAgICAgKiAgQ29uc3RhbnREZWNsYXJhdG9yc1Jlc3QgPSBDb25zdGFudERlY2xhcmF0b3JSZXN0IHsgIiwiIENvbnN0YW50RGVjbGFyYXRvciB9CiAgICAgKgogICAgICogIEBwYXJhbSByZXFJbml0ICBJcyBhbiBpbml0aWFsaXplciBhbHdheXMgcmVxdWlyZWQ/CiAgICAgKiAgQHBhcmFtIGRjICAgICAgIFRoZSBkb2N1bWVudGF0aW9uIGNvbW1lbnQgZm9yIHRoZSB2YXJpYWJsZSBkZWNsYXJhdGlvbnMsIG9yIG51bGwuCiAgICAgKi8KICAgIHByb3RlY3RlZCA8VCBleHRlbmRzIExpc3RCdWZmZXI8PyBzdXBlciBKQ1ZhcmlhYmxlRGVjbD4+IFQgdmFyaWFibGVEZWNsYXJhdG9yc1Jlc3QoaW50IHBvcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSkNNb2RpZmllcnMgbW9kcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSkNFeHByZXNzaW9uIHR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5hbWUgbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiByZXFJbml0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb21tZW50IGRjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUIHZkZWZzKQogICAgewogICAgICAgIHZkZWZzLmFwcGVuZCh2YXJpYWJsZURlY2xhcmF0b3JSZXN0KHBvcywgbW9kcywgdHlwZSwgbmFtZSwgcmVxSW5pdCwgZGMpKTsKICAgICAgICB3aGlsZSAodG9rZW4ua2luZCA9PSBDT01NQSkgewogICAgICAgICAgICAvLyBBbGwgYnV0IGxhc3Qgb2YgbXVsdGlwbGUgZGVjbGFyYXRvcnMgc3Vic3VtZSBhIGNvbW1hCiAgICAgICAgICAgIHN0b3JlRW5kKChKQ1RyZWUpdmRlZnMubGFzdCgpLCB0b2tlbi5lbmRQb3MpOwogICAgICAgICAgICBuZXh0VG9rZW4oKTsKICAgICAgICAgICAgdmRlZnMuYXBwZW5kKHZhcmlhYmxlRGVjbGFyYXRvcihtb2RzLCB0eXBlLCByZXFJbml0LCBkYykpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdmRlZnM7CiAgICB9CgogICAgLyoqIFZhcmlhYmxlRGVjbGFyYXRvciA9IElkZW50IFZhcmlhYmxlRGVjbGFyYXRvclJlc3QKICAgICAqICBDb25zdGFudERlY2xhcmF0b3IgPSBJZGVudCBDb25zdGFudERlY2xhcmF0b3JSZXN0CiAgICAgKi8KICAgIEpDVmFyaWFibGVEZWNsIHZhcmlhYmxlRGVjbGFyYXRvcihKQ01vZGlmaWVycyBtb2RzLCBKQ0V4cHJlc3Npb24gdHlwZSwgYm9vbGVhbiByZXFJbml0LCBDb21tZW50IGRjKSB7CiAgICAgICAgcmV0dXJuIHZhcmlhYmxlRGVjbGFyYXRvclJlc3QodG9rZW4ucG9zLCBtb2RzLCB0eXBlLCBpZGVudCgpLCByZXFJbml0LCBkYyk7CiAgICB9CgogICAgLyoqIFZhcmlhYmxlRGVjbGFyYXRvclJlc3QgPSBCcmFja2V0c09wdCBbIj0iIFZhcmlhYmxlSW5pdGlhbGl6ZXJdCiAgICAgKiAgQ29uc3RhbnREZWNsYXJhdG9yUmVzdCA9IEJyYWNrZXRzT3B0ICI9IiBWYXJpYWJsZUluaXRpYWxpemVyCiAgICAgKgogICAgICogIEBwYXJhbSByZXFJbml0ICBJcyBhbiBpbml0aWFsaXplciBhbHdheXMgcmVxdWlyZWQ/CiAgICAgKiAgQHBhcmFtIGRjICAgICAgIFRoZSBkb2N1bWVudGF0aW9uIGNvbW1lbnQgZm9yIHRoZSB2YXJpYWJsZSBkZWNsYXJhdGlvbnMsIG9yIG51bGwuCiAgICAgKi8KICAgIEpDVmFyaWFibGVEZWNsIHZhcmlhYmxlRGVjbGFyYXRvclJlc3QoaW50IHBvcywgSkNNb2RpZmllcnMgbW9kcywgSkNFeHByZXNzaW9uIHR5cGUsIE5hbWUgbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gcmVxSW5pdCwgQ29tbWVudCBkYykgewogICAgICAgIHR5cGUgPSBicmFja2V0c09wdCh0eXBlKTsKICAgICAgICBKQ0V4cHJlc3Npb24gaW5pdCA9IG51bGw7CiAgICAgICAgaWYgKHRva2VuLmtpbmQgPT0gRVEpIHsKICAgICAgICAgICAgbmV4dFRva2VuKCk7CiAgICAgICAgICAgIGluaXQgPSB2YXJpYWJsZUluaXRpYWxpemVyKCk7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKHJlcUluaXQpIHN5bnRheEVycm9yKHRva2VuLnBvcywgImV4cGVjdGVkIiwgRVEpOwogICAgICAgIEpDVmFyaWFibGVEZWNsIHJlc3VsdCA9CiAgICAgICAgICAgIHRvUChGLmF0KHBvcykuVmFyRGVmKG1vZHMsIG5hbWUsIHR5cGUsIGluaXQpKTsKICAgICAgICBhdHRhY2gocmVzdWx0LCBkYyk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KCiAgICAvKiogVmFyaWFibGVEZWNsYXJhdG9ySWQgPSBJZGVudCBCcmFja2V0c09wdAogICAgICovCiAgICBKQ1ZhcmlhYmxlRGVjbCB2YXJpYWJsZURlY2xhcmF0b3JJZChKQ01vZGlmaWVycyBtb2RzLCBKQ0V4cHJlc3Npb24gdHlwZSkgewogICAgICAgIHJldHVybiB2YXJpYWJsZURlY2xhcmF0b3JJZChtb2RzLCB0eXBlLCBmYWxzZSk7CiAgICB9CiAgICAvL3doZXJlCiAgICBKQ1ZhcmlhYmxlRGVjbCB2YXJpYWJsZURlY2xhcmF0b3JJZChKQ01vZGlmaWVycyBtb2RzLCBKQ0V4cHJlc3Npb24gdHlwZSwgYm9vbGVhbiBsYW1iZGFQYXJhbWV0ZXIpIHsKICAgICAgICBpbnQgcG9zID0gdG9rZW4ucG9zOwogICAgICAgIE5hbWUgbmFtZTsKICAgICAgICBpZiAobGFtYmRhUGFyYW1ldGVyICYmIHRva2VuLmtpbmQgPT0gVU5ERVJTQ09SRSkgewogICAgICAgICAgICBsb2cuZXJyb3IocG9zLCAidW5kZXJzY29yZS5hcy5pZGVudGlmaWVyLmluLmxhbWJkYSIpOwogICAgICAgICAgICBuYW1lID0gdG9rZW4ubmFtZSgpOwogICAgICAgICAgICBuZXh0VG9rZW4oKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBpZiAoYWxsb3dUaGlzSWRlbnQgJiYgIWxhbWJkYVBhcmFtZXRlcikgewogICAgICAgICAgICAgICAgSkNFeHByZXNzaW9uIHBuID0gcXVhbGlkZW50KGZhbHNlKTsKICAgICAgICAgICAgICAgIGlmIChwbi5oYXNUYWcoVGFnLklERU5UKSAmJiAoKEpDSWRlbnQpcG4pLm5hbWUgIT0gbmFtZXMuX3RoaXMpIHsKICAgICAgICAgICAgICAgICAgICBuYW1lID0gKChKQ0lkZW50KXBuKS5uYW1lOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBpZiAoKG1vZHMuZmxhZ3MgJiBGbGFncy5WQVJBUkdTKSAhPSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGxvZy5lcnJvcih0b2tlbi5wb3MsICJ2YXJhcmdzLmFuZC5yZWNlaXZlciIpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAodG9rZW4ua2luZCA9PSBMQlJBQ0tFVCkgewogICAgICAgICAgICAgICAgICAgICAgICBsb2cuZXJyb3IodG9rZW4ucG9zLCAiYXJyYXkuYW5kLnJlY2VpdmVyIik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHJldHVybiB0b1AoRi5hdChwb3MpLlJlY2VpdmVyVmFyRGVmKG1vZHMsIHBuLCB0eXBlKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBuYW1lID0gaWRlbnQoKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoKG1vZHMuZmxhZ3MgJiBGbGFncy5WQVJBUkdTKSAhPSAwICYmCiAgICAgICAgICAgICAgICB0b2tlbi5raW5kID09IExCUkFDS0VUKSB7CiAgICAgICAgICAgIGxvZy5lcnJvcih0b2tlbi5wb3MsICJ2YXJhcmdzLmFuZC5vbGQuYXJyYXkuc3ludGF4Iik7CiAgICAgICAgfQogICAgICAgIHR5cGUgPSBicmFja2V0c09wdCh0eXBlKTsKICAgICAgICByZXR1cm4gdG9QKEYuYXQocG9zKS5WYXJEZWYobW9kcywgbmFtZSwgdHlwZSwgbnVsbCkpOwogICAgfQoKICAgIC8qKiBSZXNvdXJjZXMgPSBSZXNvdXJjZSB7ICI7IiBSZXNvdXJjZXMgfQogICAgICovCiAgICBMaXN0PEpDVHJlZT4gcmVzb3VyY2VzKCkgewogICAgICAgIExpc3RCdWZmZXI8SkNUcmVlPiBkZWZzID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgIGRlZnMuYXBwZW5kKHJlc291cmNlKCkpOwogICAgICAgIHdoaWxlICh0b2tlbi5raW5kID09IFNFTUkpIHsKICAgICAgICAgICAgLy8gQWxsIGJ1dCBsYXN0IG9mIG11bHRpcGxlIGRlY2xhcmF0b3JzIG11c3Qgc3Vic3VtZSBhIHNlbWljb2xvbgogICAgICAgICAgICBzdG9yZUVuZChkZWZzLmxhc3QoKSwgdG9rZW4uZW5kUG9zKTsKICAgICAgICAgICAgaW50IHNlbWlDb2xvblBvcyA9IHRva2VuLnBvczsKICAgICAgICAgICAgbmV4dFRva2VuKCk7CiAgICAgICAgICAgIGlmICh0b2tlbi5raW5kID09IFJQQVJFTikgeyAvLyBPcHRpb25hbCB0cmFpbGluZyBzZW1pY29sb24KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYWZ0ZXIgbGFzdCByZXNvdXJjZQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZGVmcy5hcHBlbmQocmVzb3VyY2UoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBkZWZzLnRvTGlzdCgpOwogICAgfQoKICAgIC8qKiBSZXNvdXJjZSA9IFZhcmlhYmxlTW9kaWZpZXJzT3B0IFR5cGUgVmFyaWFibGVEZWNsYXJhdG9ySWQgIj0iIEV4cHJlc3Npb24KICAgICAqICAgICAgICAgICB8IEV4cHJlc3Npb24KICAgICAqLwogICAgcHJvdGVjdGVkIEpDVHJlZSByZXNvdXJjZSgpIHsKICAgICAgICBpbnQgc3RhcnRQb3MgPSB0b2tlbi5wb3M7CiAgICAgICAgaWYgKHRva2VuLmtpbmQgPT0gRklOQUwgfHwgdG9rZW4ua2luZCA9PSBNT05LRVlTX0FUKSB7CiAgICAgICAgICAgIEpDTW9kaWZpZXJzIG1vZHMgPSBvcHRGaW5hbChGbGFncy5GSU5BTCk7CiAgICAgICAgICAgIEpDRXhwcmVzc2lvbiB0ID0gcGFyc2VUeXBlKCk7CiAgICAgICAgICAgIHJldHVybiB2YXJpYWJsZURlY2xhcmF0b3JSZXN0KHRva2VuLnBvcywgbW9kcywgdCwgaWRlbnQoKSwgdHJ1ZSwgbnVsbCk7CiAgICAgICAgfQogICAgICAgIEpDRXhwcmVzc2lvbiB0ID0gdGVybShFWFBSIHwgVFlQRSk7CiAgICAgICAgaWYgKChsYXN0bW9kZSAmIFRZUEUpICE9IDAgJiYgTEFYX0lERU5USUZJRVIuYWNjZXB0cyh0b2tlbi5raW5kKSkgewogICAgICAgICAgICBKQ01vZGlmaWVycyBtb2RzID0gdG9QKEYuYXQoc3RhcnRQb3MpLk1vZGlmaWVycyhGbGFncy5GSU5BTCkpOwogICAgICAgICAgICByZXR1cm4gdmFyaWFibGVEZWNsYXJhdG9yUmVzdCh0b2tlbi5wb3MsIG1vZHMsIHQsIGlkZW50KCksIHRydWUsIG51bGwpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGNoZWNrVmFyaWFibGVJblRyeVdpdGhSZXNvdXJjZXMoc3RhcnRQb3MpOwogICAgICAgICAgICBpZiAoIXQuaGFzVGFnKElERU5UKSAmJiAhdC5oYXNUYWcoU0VMRUNUKSkgewogICAgICAgICAgICAgICAgbG9nLmVycm9yKHQucG9zKCksICJ0cnkud2l0aC5yZXNvdXJjZXMuZXhwci5uZWVkcy52YXIiKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIHQ7CiAgICAgICAgfQogICAgfQoKICAgIC8qKiBDb21waWxhdGlvblVuaXQgPSBbIHsgIkAiIEFubm90YXRpb24gfSBQQUNLQUdFIFF1YWxpZGVudCAiOyJdIHtJbXBvcnREZWNsYXJhdGlvbn0ge1R5cGVEZWNsYXJhdGlvbn0KICAgICAqLwogICAgcHVibGljIEpDVHJlZS5KQ0NvbXBpbGF0aW9uVW5pdCBwYXJzZUNvbXBpbGF0aW9uVW5pdCgpIHsKICAgICAgICBUb2tlbiBmaXJzdFRva2VuID0gdG9rZW47CiAgICAgICAgSkNNb2RpZmllcnMgbW9kcyA9IG51bGw7CiAgICAgICAgYm9vbGVhbiBjb25zdW1lZFRvcGxldmVsRG9jID0gZmFsc2U7CiAgICAgICAgYm9vbGVhbiBzZWVuSW1wb3J0ID0gZmFsc2U7CiAgICAgICAgYm9vbGVhbiBzZWVuUGFja2FnZSA9IGZhbHNlOwogICAgICAgIExpc3RCdWZmZXI8SkNUcmVlPiBkZWZzID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgIGlmICh0b2tlbi5raW5kID09IE1PTktFWVNfQVQpCiAgICAgICAgICAgIG1vZHMgPSBtb2RpZmllcnNPcHQoKTsKCiAgICAgICAgaWYgKHRva2VuLmtpbmQgPT0gUEFDS0FHRSkgewogICAgICAgICAgICBpbnQgcGFja2FnZVBvcyA9IHRva2VuLnBvczsKICAgICAgICAgICAgTGlzdDxKQ0Fubm90YXRpb24+IGFubm90YXRpb25zID0gTGlzdC5uaWwoKTsKICAgICAgICAgICAgc2VlblBhY2thZ2UgPSB0cnVlOwogICAgICAgICAgICBpZiAobW9kcyAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICBjaGVja05vTW9kcyhtb2RzLmZsYWdzKTsKICAgICAgICAgICAgICAgIGFubm90YXRpb25zID0gbW9kcy5hbm5vdGF0aW9uczsKICAgICAgICAgICAgICAgIG1vZHMgPSBudWxsOwogICAgICAgICAgICB9CiAgICAgICAgICAgIG5leHRUb2tlbigpOwogICAgICAgICAgICBKQ0V4cHJlc3Npb24gcGlkID0gcXVhbGlkZW50KGZhbHNlKTsKICAgICAgICAgICAgYWNjZXB0KFNFTUkpOwogICAgICAgICAgICBKQ1BhY2thZ2VEZWNsIHBkID0gRi5hdChwYWNrYWdlUG9zKS5QYWNrYWdlRGVjbChhbm5vdGF0aW9ucywgcGlkKTsKICAgICAgICAgICAgYXR0YWNoKHBkLCBmaXJzdFRva2VuLmNvbW1lbnQoQ29tbWVudFN0eWxlLkpBVkFET0MpKTsKICAgICAgICAgICAgY29uc3VtZWRUb3BsZXZlbERvYyA9IHRydWU7CiAgICAgICAgICAgIHN0b3JlRW5kKHBkLCB0b2tlbi5wb3MpOwogICAgICAgICAgICBkZWZzLmFwcGVuZChwZCk7CiAgICAgICAgfQoKICAgICAgICBib29sZWFuIGNoZWNrRm9ySW1wb3J0cyA9IHRydWU7CiAgICAgICAgYm9vbGVhbiBmaXJzdFR5cGVEZWNsID0gdHJ1ZTsKICAgICAgICB3aGlsZSAodG9rZW4ua2luZCAhPSBFT0YpIHsKICAgICAgICAgICAgaWYgKHRva2VuLnBvcyA8PSBlbmRQb3NUYWJsZS5lcnJvckVuZFBvcykgewogICAgICAgICAgICAgICAgLy8gZXJyb3IgcmVjb3ZlcnkKICAgICAgICAgICAgICAgIHNraXAoY2hlY2tGb3JJbXBvcnRzLCBmYWxzZSwgZmFsc2UsIGZhbHNlKTsKICAgICAgICAgICAgICAgIGlmICh0b2tlbi5raW5kID09IEVPRikKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoY2hlY2tGb3JJbXBvcnRzICYmIG1vZHMgPT0gbnVsbCAmJiB0b2tlbi5raW5kID09IElNUE9SVCkgewogICAgICAgICAgICAgICAgc2VlbkltcG9ydCA9IHRydWU7CiAgICAgICAgICAgICAgICBkZWZzLmFwcGVuZChpbXBvcnREZWNsYXJhdGlvbigpKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIENvbW1lbnQgZG9jQ29tbWVudCA9IHRva2VuLmNvbW1lbnQoQ29tbWVudFN0eWxlLkpBVkFET0MpOwogICAgICAgICAgICAgICAgaWYgKGZpcnN0VHlwZURlY2wgJiYgIXNlZW5JbXBvcnQgJiYgIXNlZW5QYWNrYWdlKSB7CiAgICAgICAgICAgICAgICAgICAgZG9jQ29tbWVudCA9IGZpcnN0VG9rZW4uY29tbWVudChDb21tZW50U3R5bGUuSkFWQURPQyk7CiAgICAgICAgICAgICAgICAgICAgY29uc3VtZWRUb3BsZXZlbERvYyA9IHRydWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAobW9kcyAhPSBudWxsIHx8IHRva2VuLmtpbmQgIT0gU0VNSSkKICAgICAgICAgICAgICAgICAgICBtb2RzID0gbW9kaWZpZXJzT3B0KG1vZHMpOwogICAgICAgICAgICAgICAgaWYgKGZpcnN0VHlwZURlY2wgJiYgdG9rZW4ua2luZCA9PSBJREVOVElGSUVSKSB7CiAgICAgICAgICAgICAgICAgICAgTW9kdWxlS2luZCBraW5kID0gTW9kdWxlS2luZC5TVFJPTkc7CiAgICAgICAgICAgICAgICAgICAgaWYgKHRva2VuLm5hbWUoKSA9PSBuYW1lcy5vcGVuKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGtpbmQgPSBNb2R1bGVLaW5kLk9QRU47CiAgICAgICAgICAgICAgICAgICAgICAgIG5leHRUb2tlbigpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAodG9rZW4ua2luZCA9PSBJREVOVElGSUVSICYmIHRva2VuLm5hbWUoKSA9PSBuYW1lcy5tb2R1bGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG1vZHMgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tOb01vZHMobW9kcy5mbGFncyAmIH5GbGFncy5ERVBSRUNBVEVEKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBkZWZzLmFwcGVuZChtb2R1bGVEZWNsKG1vZHMsIGtpbmQsIGRvY0NvbW1lbnQpKTsKICAgICAgICAgICAgICAgICAgICAgICAgY29uc3VtZWRUb3BsZXZlbERvYyA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoa2luZCAhPSBNb2R1bGVLaW5kLlNUUk9ORykgewogICAgICAgICAgICAgICAgICAgICAgICByZXBvcnRTeW50YXhFcnJvcih0b2tlbi5wb3MsICJleHBlY3RlZC5tb2R1bGUiKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBKQ1RyZWUgZGVmID0gdHlwZURlY2xhcmF0aW9uKG1vZHMsIGRvY0NvbW1lbnQpOwogICAgICAgICAgICAgICAgaWYgKGRlZiBpbnN0YW5jZW9mIEpDRXhwcmVzc2lvblN0YXRlbWVudCkKICAgICAgICAgICAgICAgICAgICBkZWYgPSAoKEpDRXhwcmVzc2lvblN0YXRlbWVudClkZWYpLmV4cHI7CiAgICAgICAgICAgICAgICBkZWZzLmFwcGVuZChkZWYpOwogICAgICAgICAgICAgICAgaWYgKGRlZiBpbnN0YW5jZW9mIEpDQ2xhc3NEZWNsKQogICAgICAgICAgICAgICAgICAgIGNoZWNrRm9ySW1wb3J0cyA9IGZhbHNlOwogICAgICAgICAgICAgICAgbW9kcyA9IG51bGw7CiAgICAgICAgICAgICAgICBmaXJzdFR5cGVEZWNsID0gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgSkNUcmVlLkpDQ29tcGlsYXRpb25Vbml0IHRvcGxldmVsID0gRi5hdChmaXJzdFRva2VuLnBvcykuVG9wTGV2ZWwoZGVmcy50b0xpc3QoKSk7CiAgICAgICAgaWYgKCFjb25zdW1lZFRvcGxldmVsRG9jKQogICAgICAgICAgICBhdHRhY2godG9wbGV2ZWwsIGZpcnN0VG9rZW4uY29tbWVudChDb21tZW50U3R5bGUuSkFWQURPQykpOwogICAgICAgIGlmIChkZWZzLmlzRW1wdHkoKSkKICAgICAgICAgICAgc3RvcmVFbmQodG9wbGV2ZWwsIFMucHJldlRva2VuKCkuZW5kUG9zKTsKICAgICAgICBpZiAoa2VlcERvY0NvbW1lbnRzKQogICAgICAgICAgICB0b3BsZXZlbC5kb2NDb21tZW50cyA9IGRvY0NvbW1lbnRzOwogICAgICAgIGlmIChrZWVwTGluZU1hcCkKICAgICAgICAgICAgdG9wbGV2ZWwubGluZU1hcCA9IFMuZ2V0TGluZU1hcCgpOwogICAgICAgIHRoaXMuZW5kUG9zVGFibGUuc2V0UGFyc2VyKG51bGwpOyAvLyByZW1vdmUgcmVmZXJlbmNlIHRvIHBhcnNlcgogICAgICAgIHRvcGxldmVsLmVuZFBvc2l0aW9ucyA9IHRoaXMuZW5kUG9zVGFibGU7CiAgICAgICAgcmV0dXJuIHRvcGxldmVsOwogICAgfQoKICAgIEpDTW9kdWxlRGVjbCBtb2R1bGVEZWNsKEpDTW9kaWZpZXJzIG1vZHMsIE1vZHVsZUtpbmQga2luZCwgQ29tbWVudCBkYykgewogICAgICAgIGludCBwb3MgPSB0b2tlbi5wb3M7CiAgICAgICAgaWYgKCFhbGxvd01vZHVsZXMpIHsKICAgICAgICAgICAgbG9nLmVycm9yKHBvcywgRXJyb3JzLk1vZHVsZXNOb3RTdXBwb3J0ZWRJblNvdXJjZShzb3VyY2UubmFtZSkpOwogICAgICAgICAgICBhbGxvd01vZHVsZXMgPSB0cnVlOwogICAgICAgIH0KCiAgICAgICAgbmV4dFRva2VuKCk7CiAgICAgICAgSkNFeHByZXNzaW9uIG5hbWUgPSBxdWFsaWRlbnQoZmFsc2UpOwogICAgICAgIExpc3Q8SkNEaXJlY3RpdmU+IGRpcmVjdGl2ZXMgPSBudWxsOwoKICAgICAgICBhY2NlcHQoTEJSQUNFKTsKICAgICAgICBkaXJlY3RpdmVzID0gbW9kdWxlRGlyZWN0aXZlTGlzdCgpOwogICAgICAgIGFjY2VwdChSQlJBQ0UpOwogICAgICAgIGFjY2VwdChFT0YpOwoKICAgICAgICBKQ01vZHVsZURlY2wgcmVzdWx0ID0gdG9QKEYuYXQocG9zKS5Nb2R1bGVEZWYobW9kcywga2luZCwgbmFtZSwgZGlyZWN0aXZlcykpOwogICAgICAgIGF0dGFjaChyZXN1bHQsIGRjKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgfQoKICAgIExpc3Q8SkNEaXJlY3RpdmU+IG1vZHVsZURpcmVjdGl2ZUxpc3QoKSB7CiAgICAgICAgTGlzdEJ1ZmZlcjxKQ0RpcmVjdGl2ZT4gZGVmcyA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICB3aGlsZSAodG9rZW4ua2luZCA9PSBJREVOVElGSUVSKSB7CiAgICAgICAgICAgIGludCBwb3MgPSB0b2tlbi5wb3M7CiAgICAgICAgICAgIGlmICh0b2tlbi5uYW1lKCkgPT0gbmFtZXMucmVxdWlyZXMpIHsKICAgICAgICAgICAgICAgIG5leHRUb2tlbigpOwogICAgICAgICAgICAgICAgYm9vbGVhbiBpc1RyYW5zaXRpdmUgPSBmYWxzZTsKICAgICAgICAgICAgICAgIGJvb2xlYW4gaXNTdGF0aWNQaGFzZSA9IGZhbHNlOwogICAgICAgICAgICBsb29wOgogICAgICAgICAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKHRva2VuLmtpbmQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBJREVOVElGSUVSOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRva2VuLm5hbWUoKSA9PSBuYW1lcy50cmFuc2l0aXZlICYmICFpc1RyYW5zaXRpdmUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUb2tlbiB0MSA9IFMudG9rZW4oMSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHQxLmtpbmQgPT0gU0VNSSB8fCB0MS5raW5kID09IERPVCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhayBsb29wOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc1RyYW5zaXRpdmUgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhayBsb29wOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFNUQVRJQzoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc1N0YXRpY1BoYXNlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3IodG9rZW4ucG9zLCAicmVwZWF0ZWQubW9kaWZpZXIiKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzU3RhdGljUGhhc2UgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhayBsb29wOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBuZXh0VG9rZW4oKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIEpDRXhwcmVzc2lvbiBtb2R1bGVOYW1lID0gcXVhbGlkZW50KGZhbHNlKTsKICAgICAgICAgICAgICAgIGFjY2VwdChTRU1JKTsKICAgICAgICAgICAgICAgIGRlZnMuYXBwZW5kKHRvUChGLmF0KHBvcykuUmVxdWlyZXMoaXNUcmFuc2l0aXZlLCBpc1N0YXRpY1BoYXNlLCBtb2R1bGVOYW1lKSkpOwogICAgICAgICAgICB9IGVsc2UgaWYgKHRva2VuLm5hbWUoKSA9PSBuYW1lcy5leHBvcnRzIHx8IHRva2VuLm5hbWUoKSA9PSBuYW1lcy5vcGVucykgewogICAgICAgICAgICAgICAgYm9vbGVhbiBleHBvcnRzID0gdG9rZW4ubmFtZSgpID09IG5hbWVzLmV4cG9ydHM7CiAgICAgICAgICAgICAgICBuZXh0VG9rZW4oKTsKICAgICAgICAgICAgICAgIEpDRXhwcmVzc2lvbiBwa2dOYW1lID0gcXVhbGlkZW50KGZhbHNlKTsKICAgICAgICAgICAgICAgIExpc3Q8SkNFeHByZXNzaW9uPiBtb2R1bGVOYW1lcyA9IG51bGw7CiAgICAgICAgICAgICAgICBpZiAodG9rZW4ua2luZCA9PSBJREVOVElGSUVSICYmIHRva2VuLm5hbWUoKSA9PSBuYW1lcy50bykgewogICAgICAgICAgICAgICAgICAgIG5leHRUb2tlbigpOwogICAgICAgICAgICAgICAgICAgIG1vZHVsZU5hbWVzID0gcXVhbGlkZW50TGlzdChmYWxzZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBhY2NlcHQoU0VNSSk7CiAgICAgICAgICAgICAgICBKQ0RpcmVjdGl2ZSBkOwogICAgICAgICAgICAgICAgaWYgKGV4cG9ydHMpIHsKICAgICAgICAgICAgICAgICAgICBkID0gRi5hdChwb3MpLkV4cG9ydHMocGtnTmFtZSwgbW9kdWxlTmFtZXMpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBkID0gRi5hdChwb3MpLk9wZW5zKHBrZ05hbWUsIG1vZHVsZU5hbWVzKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGRlZnMuYXBwZW5kKHRvUChkKSk7CiAgICAgICAgICAgIH0gZWxzZSBpZiAodG9rZW4ubmFtZSgpID09IG5hbWVzLnByb3ZpZGVzKSB7CiAgICAgICAgICAgICAgICBuZXh0VG9rZW4oKTsKICAgICAgICAgICAgICAgIEpDRXhwcmVzc2lvbiBzZXJ2aWNlTmFtZSA9IHF1YWxpZGVudChmYWxzZSk7CiAgICAgICAgICAgICAgICBpZiAodG9rZW4ua2luZCA9PSBJREVOVElGSUVSICYmIHRva2VuLm5hbWUoKSA9PSBuYW1lcy53aXRoKSB7CiAgICAgICAgICAgICAgICAgICAgbmV4dFRva2VuKCk7CiAgICAgICAgICAgICAgICAgICAgTGlzdDxKQ0V4cHJlc3Npb24+IGltcGxOYW1lcyA9IHF1YWxpZGVudExpc3QoZmFsc2UpOwogICAgICAgICAgICAgICAgICAgIGFjY2VwdChTRU1JKTsKICAgICAgICAgICAgICAgICAgICBkZWZzLmFwcGVuZCh0b1AoRi5hdChwb3MpLlByb3ZpZGVzKHNlcnZpY2VOYW1lLCBpbXBsTmFtZXMpKSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGVycm9yKHRva2VuLnBvcywgImV4cGVjdGVkIiwgIiciICsgbmFtZXMud2l0aCArICInIik7CiAgICAgICAgICAgICAgICAgICAgc2tpcChmYWxzZSwgZmFsc2UsIGZhbHNlLCBmYWxzZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSBpZiAodG9rZW4ubmFtZSgpID09IG5hbWVzLnVzZXMpIHsKICAgICAgICAgICAgICAgIG5leHRUb2tlbigpOwogICAgICAgICAgICAgICAgSkNFeHByZXNzaW9uIHNlcnZpY2UgPSBxdWFsaWRlbnQoZmFsc2UpOwogICAgICAgICAgICAgICAgYWNjZXB0KFNFTUkpOwogICAgICAgICAgICAgICAgZGVmcy5hcHBlbmQodG9QKEYuYXQocG9zKS5Vc2VzKHNlcnZpY2UpKSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBzZXRFcnJvckVuZFBvcyhwb3MpOwogICAgICAgICAgICAgICAgcmVwb3J0U3ludGF4RXJyb3IocG9zLCAiaW52YWxpZC5tb2R1bGUuZGlyZWN0aXZlIik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gZGVmcy50b0xpc3QoKTsKICAgIH0KCiAgICAvKiogSW1wb3J0RGVjbGFyYXRpb24gPSBJTVBPUlQgWyBTVEFUSUMgXSBJZGVudCB7ICIuIiBJZGVudCB9IFsgIi4iICIqIiBdICI7IgogICAgICovCiAgICBwcm90ZWN0ZWQgSkNUcmVlIGltcG9ydERlY2xhcmF0aW9uKCkgewogICAgICAgIGludCBwb3MgPSB0b2tlbi5wb3M7CiAgICAgICAgbmV4dFRva2VuKCk7CiAgICAgICAgYm9vbGVhbiBpbXBvcnRTdGF0aWMgPSBmYWxzZTsKICAgICAgICBpZiAodG9rZW4ua2luZCA9PSBTVEFUSUMpIHsKICAgICAgICAgICAgaW1wb3J0U3RhdGljID0gdHJ1ZTsKICAgICAgICAgICAgbmV4dFRva2VuKCk7CiAgICAgICAgfQogICAgICAgIEpDRXhwcmVzc2lvbiBwaWQgPSB0b1AoRi5hdCh0b2tlbi5wb3MpLklkZW50KGlkZW50KCkpKTsKICAgICAgICBkbyB7CiAgICAgICAgICAgIGludCBwb3MxID0gdG9rZW4ucG9zOwogICAgICAgICAgICBhY2NlcHQoRE9UKTsKICAgICAgICAgICAgaWYgKHRva2VuLmtpbmQgPT0gU1RBUikgewogICAgICAgICAgICAgICAgcGlkID0gdG8oRi5hdChwb3MxKS5TZWxlY3QocGlkLCBuYW1lcy5hc3RlcmlzaykpOwogICAgICAgICAgICAgICAgbmV4dFRva2VuKCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHBpZCA9IHRvUChGLmF0KHBvczEpLlNlbGVjdChwaWQsIGlkZW50KCkpKTsKICAgICAgICAgICAgfQogICAgICAgIH0gd2hpbGUgKHRva2VuLmtpbmQgPT0gRE9UKTsKICAgICAgICBhY2NlcHQoU0VNSSk7CiAgICAgICAgcmV0dXJuIHRvUChGLmF0KHBvcykuSW1wb3J0KHBpZCwgaW1wb3J0U3RhdGljKSk7CiAgICB9CgogICAgLyoqIFR5cGVEZWNsYXJhdGlvbiA9IENsYXNzT3JJbnRlcmZhY2VPckVudW1EZWNsYXJhdGlvbgogICAgICogICAgICAgICAgICAgICAgICB8ICI7IgogICAgICovCiAgICBKQ1RyZWUgdHlwZURlY2xhcmF0aW9uKEpDTW9kaWZpZXJzIG1vZHMsIENvbW1lbnQgZG9jQ29tbWVudCkgewogICAgICAgIGludCBwb3MgPSB0b2tlbi5wb3M7CiAgICAgICAgaWYgKG1vZHMgPT0gbnVsbCAmJiB0b2tlbi5raW5kID09IFNFTUkpIHsKICAgICAgICAgICAgbmV4dFRva2VuKCk7CiAgICAgICAgICAgIHJldHVybiB0b1AoRi5hdChwb3MpLlNraXAoKSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIGNsYXNzT3JJbnRlcmZhY2VPckVudW1EZWNsYXJhdGlvbihtb2RpZmllcnNPcHQobW9kcyksIGRvY0NvbW1lbnQpOwogICAgICAgIH0KICAgIH0KCiAgICAvKiogQ2xhc3NPckludGVyZmFjZU9yRW51bURlY2xhcmF0aW9uID0gTW9kaWZpZXJzT3B0CiAgICAgKiAgICAgICAgICAgKENsYXNzRGVjbGFyYXRpb24gfCBJbnRlcmZhY2VEZWNsYXJhdGlvbiB8IEVudW1EZWNsYXJhdGlvbikKICAgICAqICBAcGFyYW0gbW9kcyAgICAgQW55IG1vZGlmaWVycyBzdGFydGluZyB0aGUgY2xhc3Mgb3IgaW50ZXJmYWNlIGRlY2xhcmF0aW9uCiAgICAgKiAgQHBhcmFtIGRjICAgICAgIFRoZSBkb2N1bWVudGF0aW9uIGNvbW1lbnQgZm9yIHRoZSBjbGFzcywgb3IgbnVsbC4KICAgICAqLwogICAgcHJvdGVjdGVkIEpDU3RhdGVtZW50IGNsYXNzT3JJbnRlcmZhY2VPckVudW1EZWNsYXJhdGlvbihKQ01vZGlmaWVycyBtb2RzLCBDb21tZW50IGRjKSB7CiAgICAgICAgaWYgKHRva2VuLmtpbmQgPT0gQ0xBU1MpIHsKICAgICAgICAgICAgcmV0dXJuIGNsYXNzRGVjbGFyYXRpb24obW9kcywgZGMpOwogICAgICAgIH0gZWxzZSBpZiAodG9rZW4ua2luZCA9PSBJTlRFUkZBQ0UpIHsKICAgICAgICAgICAgcmV0dXJuIGludGVyZmFjZURlY2xhcmF0aW9uKG1vZHMsIGRjKTsKICAgICAgICB9IGVsc2UgaWYgKHRva2VuLmtpbmQgPT0gRU5VTSkgewogICAgICAgICAgICByZXR1cm4gZW51bURlY2xhcmF0aW9uKG1vZHMsIGRjKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBpbnQgcG9zID0gdG9rZW4ucG9zOwogICAgICAgICAgICBMaXN0PEpDVHJlZT4gZXJyczsKICAgICAgICAgICAgaWYgKExBWF9JREVOVElGSUVSLmFjY2VwdHModG9rZW4ua2luZCkpIHsKICAgICAgICAgICAgICAgIGVycnMgPSBMaXN0Lm9mKG1vZHMsIHRvUChGLmF0KHBvcykuSWRlbnQoaWRlbnQoKSkpKTsKICAgICAgICAgICAgICAgIHNldEVycm9yRW5kUG9zKHRva2VuLnBvcyk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBlcnJzID0gTGlzdC5vZihtb2RzKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBmaW5hbCBKQ0Vycm9uZW91cyBlcnJvbmVvdXNUcmVlOwogICAgICAgICAgICBpZiAocGFyc2VNb2R1bGVJbmZvKSB7CiAgICAgICAgICAgICAgICBlcnJvbmVvdXNUcmVlID0gc3ludGF4RXJyb3IocG9zLCBlcnJzLCAiZXhwZWN0ZWQubW9kdWxlLm9yLm9wZW4iKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGVycm9uZW91c1RyZWUgPSBzeW50YXhFcnJvcihwb3MsIGVycnMsICJleHBlY3RlZDMiLCBDTEFTUywgSU5URVJGQUNFLCBFTlVNKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gdG9QKEYuRXhlYyhlcnJvbmVvdXNUcmVlKSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKiBDbGFzc0RlY2xhcmF0aW9uID0gQ0xBU1MgSWRlbnQgVHlwZVBhcmFtZXRlcnNPcHQgW0VYVEVORFMgVHlwZV0KICAgICAqICAgICAgICAgICAgICAgICAgICAgW0lNUExFTUVOVFMgVHlwZUxpc3RdIENsYXNzQm9keQogICAgICogIEBwYXJhbSBtb2RzICAgIFRoZSBtb2RpZmllcnMgc3RhcnRpbmcgdGhlIGNsYXNzIGRlY2xhcmF0aW9uCiAgICAgKiAgQHBhcmFtIGRjICAgICAgIFRoZSBkb2N1bWVudGF0aW9uIGNvbW1lbnQgZm9yIHRoZSBjbGFzcywgb3IgbnVsbC4KICAgICAqLwogICAgcHJvdGVjdGVkIEpDQ2xhc3NEZWNsIGNsYXNzRGVjbGFyYXRpb24oSkNNb2RpZmllcnMgbW9kcywgQ29tbWVudCBkYykgewogICAgICAgIGludCBwb3MgPSB0b2tlbi5wb3M7CiAgICAgICAgYWNjZXB0KENMQVNTKTsKICAgICAgICBOYW1lIG5hbWUgPSBpZGVudCgpOwoKICAgICAgICBMaXN0PEpDVHlwZVBhcmFtZXRlcj4gdHlwYXJhbXMgPSB0eXBlUGFyYW1ldGVyc09wdCgpOwoKICAgICAgICBKQ0V4cHJlc3Npb24gZXh0ZW5kaW5nID0gbnVsbDsKICAgICAgICBpZiAodG9rZW4ua2luZCA9PSBFWFRFTkRTKSB7CiAgICAgICAgICAgIG5leHRUb2tlbigpOwogICAgICAgICAgICBleHRlbmRpbmcgPSBwYXJzZVR5cGUoKTsKICAgICAgICB9CiAgICAgICAgTGlzdDxKQ0V4cHJlc3Npb24+IGltcGxlbWVudGluZyA9IExpc3QubmlsKCk7CiAgICAgICAgaWYgKHRva2VuLmtpbmQgPT0gSU1QTEVNRU5UUykgewogICAgICAgICAgICBuZXh0VG9rZW4oKTsKICAgICAgICAgICAgaW1wbGVtZW50aW5nID0gdHlwZUxpc3QoKTsKICAgICAgICB9CiAgICAgICAgTGlzdDxKQ1RyZWU+IGRlZnMgPSBjbGFzc09ySW50ZXJmYWNlQm9keShuYW1lLCBmYWxzZSk7CiAgICAgICAgSkNDbGFzc0RlY2wgcmVzdWx0ID0gdG9QKEYuYXQocG9zKS5DbGFzc0RlZigKICAgICAgICAgICAgbW9kcywgbmFtZSwgdHlwYXJhbXMsIGV4dGVuZGluZywgaW1wbGVtZW50aW5nLCBkZWZzKSk7CiAgICAgICAgYXR0YWNoKHJlc3VsdCwgZGMpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9CgogICAgLyoqIEludGVyZmFjZURlY2xhcmF0aW9uID0gSU5URVJGQUNFIElkZW50IFR5cGVQYXJhbWV0ZXJzT3B0CiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICBbRVhURU5EUyBUeXBlTGlzdF0gSW50ZXJmYWNlQm9keQogICAgICogIEBwYXJhbSBtb2RzICAgIFRoZSBtb2RpZmllcnMgc3RhcnRpbmcgdGhlIGludGVyZmFjZSBkZWNsYXJhdGlvbgogICAgICogIEBwYXJhbSBkYyAgICAgICBUaGUgZG9jdW1lbnRhdGlvbiBjb21tZW50IGZvciB0aGUgaW50ZXJmYWNlLCBvciBudWxsLgogICAgICovCiAgICBwcm90ZWN0ZWQgSkNDbGFzc0RlY2wgaW50ZXJmYWNlRGVjbGFyYXRpb24oSkNNb2RpZmllcnMgbW9kcywgQ29tbWVudCBkYykgewogICAgICAgIGludCBwb3MgPSB0b2tlbi5wb3M7CiAgICAgICAgYWNjZXB0KElOVEVSRkFDRSk7CiAgICAgICAgTmFtZSBuYW1lID0gaWRlbnQoKTsKCiAgICAgICAgTGlzdDxKQ1R5cGVQYXJhbWV0ZXI+IHR5cGFyYW1zID0gdHlwZVBhcmFtZXRlcnNPcHQoKTsKCiAgICAgICAgTGlzdDxKQ0V4cHJlc3Npb24+IGV4dGVuZGluZyA9IExpc3QubmlsKCk7CiAgICAgICAgaWYgKHRva2VuLmtpbmQgPT0gRVhURU5EUykgewogICAgICAgICAgICBuZXh0VG9rZW4oKTsKICAgICAgICAgICAgZXh0ZW5kaW5nID0gdHlwZUxpc3QoKTsKICAgICAgICB9CiAgICAgICAgTGlzdDxKQ1RyZWU+IGRlZnMgPSBjbGFzc09ySW50ZXJmYWNlQm9keShuYW1lLCB0cnVlKTsKICAgICAgICBKQ0NsYXNzRGVjbCByZXN1bHQgPSB0b1AoRi5hdChwb3MpLkNsYXNzRGVmKAogICAgICAgICAgICBtb2RzLCBuYW1lLCB0eXBhcmFtcywgbnVsbCwgZXh0ZW5kaW5nLCBkZWZzKSk7CiAgICAgICAgYXR0YWNoKHJlc3VsdCwgZGMpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9CgogICAgLyoqIEVudW1EZWNsYXJhdGlvbiA9IEVOVU0gSWRlbnQgW0lNUExFTUVOVFMgVHlwZUxpc3RdIEVudW1Cb2R5CiAgICAgKiAgQHBhcmFtIG1vZHMgICAgVGhlIG1vZGlmaWVycyBzdGFydGluZyB0aGUgZW51bSBkZWNsYXJhdGlvbgogICAgICogIEBwYXJhbSBkYyAgICAgICBUaGUgZG9jdW1lbnRhdGlvbiBjb21tZW50IGZvciB0aGUgZW51bSwgb3IgbnVsbC4KICAgICAqLwogICAgcHJvdGVjdGVkIEpDQ2xhc3NEZWNsIGVudW1EZWNsYXJhdGlvbihKQ01vZGlmaWVycyBtb2RzLCBDb21tZW50IGRjKSB7CiAgICAgICAgaW50IHBvcyA9IHRva2VuLnBvczsKICAgICAgICBhY2NlcHQoRU5VTSk7CiAgICAgICAgTmFtZSBuYW1lID0gaWRlbnQoKTsKCiAgICAgICAgTGlzdDxKQ0V4cHJlc3Npb24+IGltcGxlbWVudGluZyA9IExpc3QubmlsKCk7CiAgICAgICAgaWYgKHRva2VuLmtpbmQgPT0gSU1QTEVNRU5UUykgewogICAgICAgICAgICBuZXh0VG9rZW4oKTsKICAgICAgICAgICAgaW1wbGVtZW50aW5nID0gdHlwZUxpc3QoKTsKICAgICAgICB9CgogICAgICAgIExpc3Q8SkNUcmVlPiBkZWZzID0gZW51bUJvZHkobmFtZSk7CiAgICAgICAgbW9kcy5mbGFncyB8PSBGbGFncy5FTlVNOwogICAgICAgIEpDQ2xhc3NEZWNsIHJlc3VsdCA9IHRvUChGLmF0KHBvcykuCiAgICAgICAgICAgIENsYXNzRGVmKG1vZHMsIG5hbWUsIExpc3QubmlsKCksCiAgICAgICAgICAgICAgICAgICAgIG51bGwsIGltcGxlbWVudGluZywgZGVmcykpOwogICAgICAgIGF0dGFjaChyZXN1bHQsIGRjKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgfQoKICAgIC8qKiBFbnVtQm9keSA9ICJ7IiB7IEVudW1lcmF0b3JEZWNsYXJhdGlvbkxpc3QgfSBbIiwiXQogICAgICogICAgICAgICAgICAgICAgICBbICI7IiB7Q2xhc3NCb2R5RGVjbGFyYXRpb259IF0gIn0iCiAgICAgKi8KICAgIExpc3Q8SkNUcmVlPiBlbnVtQm9keShOYW1lIGVudW1OYW1lKSB7CiAgICAgICAgYWNjZXB0KExCUkFDRSk7CiAgICAgICAgTGlzdEJ1ZmZlcjxKQ1RyZWU+IGRlZnMgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgaWYgKHRva2VuLmtpbmQgPT0gQ09NTUEpIHsKICAgICAgICAgICAgbmV4dFRva2VuKCk7CiAgICAgICAgfSBlbHNlIGlmICh0b2tlbi5raW5kICE9IFJCUkFDRSAmJiB0b2tlbi5raW5kICE9IFNFTUkpIHsKICAgICAgICAgICAgZGVmcy5hcHBlbmQoZW51bWVyYXRvckRlY2xhcmF0aW9uKGVudW1OYW1lKSk7CiAgICAgICAgICAgIHdoaWxlICh0b2tlbi5raW5kID09IENPTU1BKSB7CiAgICAgICAgICAgICAgICBuZXh0VG9rZW4oKTsKICAgICAgICAgICAgICAgIGlmICh0b2tlbi5raW5kID09IFJCUkFDRSB8fCB0b2tlbi5raW5kID09IFNFTUkpIGJyZWFrOwogICAgICAgICAgICAgICAgZGVmcy5hcHBlbmQoZW51bWVyYXRvckRlY2xhcmF0aW9uKGVudW1OYW1lKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHRva2VuLmtpbmQgIT0gU0VNSSAmJiB0b2tlbi5raW5kICE9IFJCUkFDRSkgewogICAgICAgICAgICAgICAgZGVmcy5hcHBlbmQoc3ludGF4RXJyb3IodG9rZW4ucG9zLCAiZXhwZWN0ZWQzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDT01NQSwgUkJSQUNFLCBTRU1JKSk7CiAgICAgICAgICAgICAgICBuZXh0VG9rZW4oKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAodG9rZW4ua2luZCA9PSBTRU1JKSB7CiAgICAgICAgICAgIG5leHRUb2tlbigpOwogICAgICAgICAgICB3aGlsZSAodG9rZW4ua2luZCAhPSBSQlJBQ0UgJiYgdG9rZW4ua2luZCAhPSBFT0YpIHsKICAgICAgICAgICAgICAgIGRlZnMuYXBwZW5kTGlzdChjbGFzc09ySW50ZXJmYWNlQm9keURlY2xhcmF0aW9uKGVudW1OYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFsc2UpKTsKICAgICAgICAgICAgICAgIGlmICh0b2tlbi5wb3MgPD0gZW5kUG9zVGFibGUuZXJyb3JFbmRQb3MpIHsKICAgICAgICAgICAgICAgICAgICAvLyBlcnJvciByZWNvdmVyeQogICAgICAgICAgICAgICAgICAgc2tpcChmYWxzZSwgdHJ1ZSwgdHJ1ZSwgZmFsc2UpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGFjY2VwdChSQlJBQ0UpOwogICAgICAgIHJldHVybiBkZWZzLnRvTGlzdCgpOwogICAgfQoKICAgIC8qKiBFbnVtZXJhdG9yRGVjbGFyYXRpb24gPSBBbm5vdGF0aW9uc09wdCBbVHlwZUFyZ3VtZW50c10gSURFTlRJRklFUiBbIEFyZ3VtZW50cyBdIFsgInsiIENsYXNzQm9keSAifSIgXQogICAgICovCiAgICBKQ1RyZWUgZW51bWVyYXRvckRlY2xhcmF0aW9uKE5hbWUgZW51bU5hbWUpIHsKICAgICAgICBDb21tZW50IGRjID0gdG9rZW4uY29tbWVudChDb21tZW50U3R5bGUuSkFWQURPQyk7CiAgICAgICAgaW50IGZsYWdzID0gRmxhZ3MuUFVCTElDfEZsYWdzLlNUQVRJQ3xGbGFncy5GSU5BTHxGbGFncy5FTlVNOwogICAgICAgIGlmICh0b2tlbi5kZXByZWNhdGVkRmxhZygpKSB7CiAgICAgICAgICAgIGZsYWdzIHw9IEZsYWdzLkRFUFJFQ0FURUQ7CiAgICAgICAgfQogICAgICAgIGludCBwb3MgPSB0b2tlbi5wb3M7CiAgICAgICAgTGlzdDxKQ0Fubm90YXRpb24+IGFubm90YXRpb25zID0gYW5ub3RhdGlvbnNPcHQoVGFnLkFOTk9UQVRJT04pOwogICAgICAgIEpDTW9kaWZpZXJzIG1vZHMgPSBGLmF0KGFubm90YXRpb25zLmlzRW1wdHkoKSA/IFBvc2l0aW9uLk5PUE9TIDogcG9zKS5Nb2RpZmllcnMoZmxhZ3MsIGFubm90YXRpb25zKTsKICAgICAgICBMaXN0PEpDRXhwcmVzc2lvbj4gdHlwZUFyZ3MgPSB0eXBlQXJndW1lbnRzT3B0KCk7CiAgICAgICAgaW50IGlkZW50UG9zID0gdG9rZW4ucG9zOwogICAgICAgIE5hbWUgbmFtZSA9IGlkZW50KCk7CiAgICAgICAgaW50IGNyZWF0ZVBvcyA9IHRva2VuLnBvczsKICAgICAgICBMaXN0PEpDRXhwcmVzc2lvbj4gYXJncyA9ICh0b2tlbi5raW5kID09IExQQVJFTikKICAgICAgICAgICAgPyBhcmd1bWVudHMoKSA6IExpc3QubmlsKCk7CiAgICAgICAgSkNDbGFzc0RlY2wgYm9keSA9IG51bGw7CiAgICAgICAgaWYgKHRva2VuLmtpbmQgPT0gTEJSQUNFKSB7CiAgICAgICAgICAgIEpDTW9kaWZpZXJzIG1vZHMxID0gRi5hdChQb3NpdGlvbi5OT1BPUykuTW9kaWZpZXJzKEZsYWdzLkVOVU0pOwogICAgICAgICAgICBMaXN0PEpDVHJlZT4gZGVmcyA9IGNsYXNzT3JJbnRlcmZhY2VCb2R5KG5hbWVzLmVtcHR5LCBmYWxzZSk7CiAgICAgICAgICAgIGJvZHkgPSB0b1AoRi5hdChpZGVudFBvcykuQW5vbnltb3VzQ2xhc3NEZWYobW9kczEsIGRlZnMpKTsKICAgICAgICB9CiAgICAgICAgaWYgKGFyZ3MuaXNFbXB0eSgpICYmIGJvZHkgPT0gbnVsbCkKICAgICAgICAgICAgY3JlYXRlUG9zID0gaWRlbnRQb3M7CiAgICAgICAgSkNJZGVudCBpZGVudCA9IEYuYXQoaWRlbnRQb3MpLklkZW50KGVudW1OYW1lKTsKICAgICAgICBKQ05ld0NsYXNzIGNyZWF0ZSA9IEYuYXQoY3JlYXRlUG9zKS5OZXdDbGFzcyhudWxsLCB0eXBlQXJncywgaWRlbnQsIGFyZ3MsIGJvZHkpOwogICAgICAgIGlmIChjcmVhdGVQb3MgIT0gaWRlbnRQb3MpCiAgICAgICAgICAgIHN0b3JlRW5kKGNyZWF0ZSwgUy5wcmV2VG9rZW4oKS5lbmRQb3MpOwogICAgICAgIGlkZW50ID0gRi5hdChpZGVudFBvcykuSWRlbnQoZW51bU5hbWUpOwogICAgICAgIEpDVHJlZSByZXN1bHQgPSB0b1AoRi5hdChwb3MpLlZhckRlZihtb2RzLCBuYW1lLCBpZGVudCwgY3JlYXRlKSk7CiAgICAgICAgYXR0YWNoKHJlc3VsdCwgZGMpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9CgogICAgLyoqIFR5cGVMaXN0ID0gVHlwZSB7IiwiIFR5cGV9CiAgICAgKi8KICAgIExpc3Q8SkNFeHByZXNzaW9uPiB0eXBlTGlzdCgpIHsKICAgICAgICBMaXN0QnVmZmVyPEpDRXhwcmVzc2lvbj4gdHMgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgdHMuYXBwZW5kKHBhcnNlVHlwZSgpKTsKICAgICAgICB3aGlsZSAodG9rZW4ua2luZCA9PSBDT01NQSkgewogICAgICAgICAgICBuZXh0VG9rZW4oKTsKICAgICAgICAgICAgdHMuYXBwZW5kKHBhcnNlVHlwZSgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRzLnRvTGlzdCgpOwogICAgfQoKICAgIC8qKiBDbGFzc0JvZHkgICAgID0gInsiIHtDbGFzc0JvZHlEZWNsYXJhdGlvbn0gIn0iCiAgICAgKiAgSW50ZXJmYWNlQm9keSA9ICJ7IiB7SW50ZXJmYWNlQm9keURlY2xhcmF0aW9ufSAifSIKICAgICAqLwogICAgTGlzdDxKQ1RyZWU+IGNsYXNzT3JJbnRlcmZhY2VCb2R5KE5hbWUgY2xhc3NOYW1lLCBib29sZWFuIGlzSW50ZXJmYWNlKSB7CiAgICAgICAgYWNjZXB0KExCUkFDRSk7CiAgICAgICAgaWYgKHRva2VuLnBvcyA8PSBlbmRQb3NUYWJsZS5lcnJvckVuZFBvcykgewogICAgICAgICAgICAvLyBlcnJvciByZWNvdmVyeQogICAgICAgICAgICBza2lwKGZhbHNlLCB0cnVlLCBmYWxzZSwgZmFsc2UpOwogICAgICAgICAgICBpZiAodG9rZW4ua2luZCA9PSBMQlJBQ0UpCiAgICAgICAgICAgICAgICBuZXh0VG9rZW4oKTsKICAgICAgICB9CiAgICAgICAgTGlzdEJ1ZmZlcjxKQ1RyZWU+IGRlZnMgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgd2hpbGUgKHRva2VuLmtpbmQgIT0gUkJSQUNFICYmIHRva2VuLmtpbmQgIT0gRU9GKSB7CiAgICAgICAgICAgIGRlZnMuYXBwZW5kTGlzdChjbGFzc09ySW50ZXJmYWNlQm9keURlY2xhcmF0aW9uKGNsYXNzTmFtZSwgaXNJbnRlcmZhY2UpKTsKICAgICAgICAgICAgaWYgKHRva2VuLnBvcyA8PSBlbmRQb3NUYWJsZS5lcnJvckVuZFBvcykgewogICAgICAgICAgICAgICAvLyBlcnJvciByZWNvdmVyeQogICAgICAgICAgICAgICBza2lwKGZhbHNlLCB0cnVlLCB0cnVlLCBmYWxzZSk7CiAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBhY2NlcHQoUkJSQUNFKTsKICAgICAgICByZXR1cm4gZGVmcy50b0xpc3QoKTsKICAgIH0KCiAgICAvKiogQ2xhc3NCb2R5RGVjbGFyYXRpb24gPQogICAgICogICAgICAiOyIKICAgICAqICAgIHwgW1NUQVRJQ10gQmxvY2sKICAgICAqICAgIHwgTW9kaWZpZXJzT3B0CiAgICAgKiAgICAgICggVHlwZSBJZGVudAogICAgICogICAgICAgICggVmFyaWFibGVEZWNsYXJhdG9yc1Jlc3QgIjsiIHwgTWV0aG9kRGVjbGFyYXRvclJlc3QgKQogICAgICogICAgICB8IFZPSUQgSWRlbnQgVm9pZE1ldGhvZERlY2xhcmF0b3JSZXN0CiAgICAgKiAgICAgIHwgVHlwZVBhcmFtZXRlcnMgW0Fubm90YXRpb25zXQogICAgICogICAgICAgICggVHlwZSBJZGVudCBNZXRob2REZWNsYXJhdG9yUmVzdAogICAgICogICAgICAgIHwgVk9JRCBJZGVudCBWb2lkTWV0aG9kRGVjbGFyYXRvclJlc3QKICAgICAqICAgICAgICApCiAgICAgKiAgICAgIHwgSWRlbnQgQ29uc3RydWN0b3JEZWNsYXJhdG9yUmVzdAogICAgICogICAgICB8IFR5cGVQYXJhbWV0ZXJzIElkZW50IENvbnN0cnVjdG9yRGVjbGFyYXRvclJlc3QKICAgICAqICAgICAgfCBDbGFzc09ySW50ZXJmYWNlT3JFbnVtRGVjbGFyYXRpb24KICAgICAqICAgICAgKQogICAgICogIEludGVyZmFjZUJvZHlEZWNsYXJhdGlvbiA9CiAgICAgKiAgICAgICI7IgogICAgICogICAgfCBNb2RpZmllcnNPcHQKICAgICAqICAgICAgKCBUeXBlIElkZW50CiAgICAgKiAgICAgICAgKCBDb25zdGFudERlY2xhcmF0b3JzUmVzdCAiOyIgfCBNZXRob2REZWNsYXJhdG9yUmVzdCApCiAgICAgKiAgICAgIHwgVk9JRCBJZGVudCBNZXRob2REZWNsYXJhdG9yUmVzdAogICAgICogICAgICB8IFR5cGVQYXJhbWV0ZXJzIFtBbm5vdGF0aW9uc10KICAgICAqICAgICAgICAoIFR5cGUgSWRlbnQgTWV0aG9kRGVjbGFyYXRvclJlc3QKICAgICAqICAgICAgICB8IFZPSUQgSWRlbnQgVm9pZE1ldGhvZERlY2xhcmF0b3JSZXN0CiAgICAgKiAgICAgICAgKQogICAgICogICAgICB8IENsYXNzT3JJbnRlcmZhY2VPckVudW1EZWNsYXJhdGlvbgogICAgICogICAgICApCiAgICAgKgogICAgICovCiAgICBwcm90ZWN0ZWQgTGlzdDxKQ1RyZWU+IGNsYXNzT3JJbnRlcmZhY2VCb2R5RGVjbGFyYXRpb24oTmFtZSBjbGFzc05hbWUsIGJvb2xlYW4gaXNJbnRlcmZhY2UpIHsKICAgICAgICBpZiAodG9rZW4ua2luZCA9PSBTRU1JKSB7CiAgICAgICAgICAgIG5leHRUb2tlbigpOwogICAgICAgICAgICByZXR1cm4gTGlzdC5uaWwoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBDb21tZW50IGRjID0gdG9rZW4uY29tbWVudChDb21tZW50U3R5bGUuSkFWQURPQyk7CiAgICAgICAgICAgIGludCBwb3MgPSB0b2tlbi5wb3M7CiAgICAgICAgICAgIEpDTW9kaWZpZXJzIG1vZHMgPSBtb2RpZmllcnNPcHQoKTsKICAgICAgICAgICAgaWYgKHRva2VuLmtpbmQgPT0gQ0xBU1MgfHwKICAgICAgICAgICAgICAgIHRva2VuLmtpbmQgPT0gSU5URVJGQUNFIHx8CiAgICAgICAgICAgICAgICB0b2tlbi5raW5kID09IEVOVU0pIHsKICAgICAgICAgICAgICAgIHJldHVybiBMaXN0Lm9mKGNsYXNzT3JJbnRlcmZhY2VPckVudW1EZWNsYXJhdGlvbihtb2RzLCBkYykpOwogICAgICAgICAgICB9IGVsc2UgaWYgKHRva2VuLmtpbmQgPT0gTEJSQUNFICYmCiAgICAgICAgICAgICAgICAgICAgICAgKG1vZHMuZmxhZ3MgJiBGbGFncy5TdGFuZGFyZEZsYWdzICYgfkZsYWdzLlNUQVRJQykgPT0gMCAmJgogICAgICAgICAgICAgICAgICAgICAgIG1vZHMuYW5ub3RhdGlvbnMuaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgICBpZiAoaXNJbnRlcmZhY2UpIHsKICAgICAgICAgICAgICAgICAgICBlcnJvcih0b2tlbi5wb3MsICJpbml0aWFsaXplci5ub3QuYWxsb3dlZCIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIExpc3Qub2YoYmxvY2socG9zLCBtb2RzLmZsYWdzKSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBwb3MgPSB0b2tlbi5wb3M7CiAgICAgICAgICAgICAgICBMaXN0PEpDVHlwZVBhcmFtZXRlcj4gdHlwYXJhbXMgPSB0eXBlUGFyYW1ldGVyc09wdCgpOwogICAgICAgICAgICAgICAgLy8gaWYgdGhlcmUgYXJlIHR5cGUgcGFyYW1ldGVycyBidXQgbm8gbW9kaWZpZXJzLCBzYXZlIHRoZSBzdGFydAogICAgICAgICAgICAgICAgLy8gcG9zaXRpb24gb2YgdGhlIG1ldGhvZCBpbiB0aGUgbW9kaWZpZXJzLgogICAgICAgICAgICAgICAgaWYgKHR5cGFyYW1zLm5vbkVtcHR5KCkgJiYgbW9kcy5wb3MgPT0gUG9zaXRpb24uTk9QT1MpIHsKICAgICAgICAgICAgICAgICAgICBtb2RzLnBvcyA9IHBvczsKICAgICAgICAgICAgICAgICAgICBzdG9yZUVuZChtb2RzLCBwb3MpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgTGlzdDxKQ0Fubm90YXRpb24+IGFubm9zQWZ0ZXJQYXJhbXMgPSBhbm5vdGF0aW9uc09wdChUYWcuQU5OT1RBVElPTik7CgogICAgICAgICAgICAgICAgaWYgKGFubm9zQWZ0ZXJQYXJhbXMubm9uRW1wdHkoKSkgewogICAgICAgICAgICAgICAgICAgIGNoZWNrQW5ub3RhdGlvbnNBZnRlclR5cGVQYXJhbXMoYW5ub3NBZnRlclBhcmFtcy5oZWFkLnBvcyk7CiAgICAgICAgICAgICAgICAgICAgbW9kcy5hbm5vdGF0aW9ucyA9IG1vZHMuYW5ub3RhdGlvbnMuYXBwZW5kTGlzdChhbm5vc0FmdGVyUGFyYW1zKTsKICAgICAgICAgICAgICAgICAgICBpZiAobW9kcy5wb3MgPT0gUG9zaXRpb24uTk9QT1MpCiAgICAgICAgICAgICAgICAgICAgICAgIG1vZHMucG9zID0gbW9kcy5hbm5vdGF0aW9ucy5oZWFkLnBvczsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBUb2tlbiB0ayA9IHRva2VuOwogICAgICAgICAgICAgICAgcG9zID0gdG9rZW4ucG9zOwogICAgICAgICAgICAgICAgSkNFeHByZXNzaW9uIHR5cGU7CiAgICAgICAgICAgICAgICBib29sZWFuIGlzVm9pZCA9IHRva2VuLmtpbmQgPT0gVk9JRDsKICAgICAgICAgICAgICAgIGlmIChpc1ZvaWQpIHsKICAgICAgICAgICAgICAgICAgICB0eXBlID0gdG8oRi5hdChwb3MpLlR5cGVJZGVudChUeXBlVGFnLlZPSUQpKTsKICAgICAgICAgICAgICAgICAgICBuZXh0VG9rZW4oKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgLy8gbWV0aG9kIHJldHVybnMgdHlwZXMgYXJlIHVuLWFubm90YXRlZCB0eXBlcwogICAgICAgICAgICAgICAgICAgIHR5cGUgPSB1bmFubm90YXRlZFR5cGUoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICh0b2tlbi5raW5kID09IExQQVJFTiAmJiAhaXNJbnRlcmZhY2UgJiYgdHlwZS5oYXNUYWcoSURFTlQpKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGlzSW50ZXJmYWNlIHx8IHRrLm5hbWUoKSAhPSBjbGFzc05hbWUpCiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yKHBvcywgImludmFsaWQubWV0aC5kZWNsLnJldC50eXBlLnJlcSIpOwogICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGFubm9zQWZ0ZXJQYXJhbXMubm9uRW1wdHkoKSkKICAgICAgICAgICAgICAgICAgICAgICAgaWxsZWdhbChhbm5vc0FmdGVyUGFyYW1zLmhlYWQucG9zKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gTGlzdC5vZihtZXRob2REZWNsYXJhdG9yUmVzdCgKICAgICAgICAgICAgICAgICAgICAgICAgcG9zLCBtb2RzLCBudWxsLCBuYW1lcy5pbml0LCB0eXBhcmFtcywKICAgICAgICAgICAgICAgICAgICAgICAgaXNJbnRlcmZhY2UsIHRydWUsIGRjKSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHBvcyA9IHRva2VuLnBvczsKICAgICAgICAgICAgICAgICAgICBOYW1lIG5hbWUgPSBpZGVudCgpOwogICAgICAgICAgICAgICAgICAgIGlmICh0b2tlbi5raW5kID09IExQQVJFTikgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gTGlzdC5vZihtZXRob2REZWNsYXJhdG9yUmVzdCgKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvcywgbW9kcywgdHlwZSwgbmFtZSwgdHlwYXJhbXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc0ludGVyZmFjZSwgaXNWb2lkLCBkYykpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoIWlzVm9pZCAmJiB0eXBhcmFtcy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgTGlzdDxKQ1RyZWU+IGRlZnMgPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyaWFibGVEZWNsYXJhdG9yc1Jlc3QocG9zLCBtb2RzLCB0eXBlLCBuYW1lLCBpc0ludGVyZmFjZSwgZGMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgTGlzdEJ1ZmZlcjxKQ1RyZWU+KCkpLnRvTGlzdCgpOwogICAgICAgICAgICAgICAgICAgICAgICBhY2NlcHQoU0VNSSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHN0b3JlRW5kKGRlZnMubGFzdCgpLCBTLnByZXZUb2tlbigpLmVuZFBvcyk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBkZWZzOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHBvcyA9IHRva2VuLnBvczsKICAgICAgICAgICAgICAgICAgICAgICAgTGlzdDxKQ1RyZWU+IGVyciA9IGlzVm9pZAogICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBMaXN0Lm9mKHRvUChGLmF0KHBvcykuTWV0aG9kRGVmKG1vZHMsIG5hbWUsIHR5cGUsIHR5cGFyYW1zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExpc3QubmlsKCksIExpc3QubmlsKCksIG51bGwsIG51bGwpKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogbnVsbDsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIExpc3Qub2Yoc3ludGF4RXJyb3IodG9rZW4ucG9zLCBlcnIsICJleHBlY3RlZCIsIExQQVJFTikpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKiogTWV0aG9kRGVjbGFyYXRvclJlc3QgPQogICAgICogICAgICBGb3JtYWxQYXJhbWV0ZXJzIEJyYWNrZXRzT3B0IFtUSFJPV1MgVHlwZUxpc3RdICggTWV0aG9kQm9keSB8IFtERUZBVUxUIEFubm90YXRpb25WYWx1ZV0gIjsiKQogICAgICogIFZvaWRNZXRob2REZWNsYXJhdG9yUmVzdCA9CiAgICAgKiAgICAgIEZvcm1hbFBhcmFtZXRlcnMgW1RIUk9XUyBUeXBlTGlzdF0gKCBNZXRob2RCb2R5IHwgIjsiKQogICAgICogIENvbnN0cnVjdG9yRGVjbGFyYXRvclJlc3QgPQogICAgICogICAgICAiKCIgRm9ybWFsUGFyYW1ldGVyTGlzdE9wdCAiKSIgW1RIUk9XUyBUeXBlTGlzdF0gTWV0aG9kQm9keQogICAgICovCiAgICBwcm90ZWN0ZWQgSkNUcmVlIG1ldGhvZERlY2xhcmF0b3JSZXN0KGludCBwb3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEpDTW9kaWZpZXJzIG1vZHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEpDRXhwcmVzc2lvbiB0eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOYW1lIG5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExpc3Q8SkNUeXBlUGFyYW1ldGVyPiB0eXBhcmFtcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBpc0ludGVyZmFjZSwgYm9vbGVhbiBpc1ZvaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbW1lbnQgZGMpIHsKICAgICAgICBpZiAoaXNJbnRlcmZhY2UpIHsKICAgICAgICAgICAgaWYgKChtb2RzLmZsYWdzICYgRmxhZ3MuU1RBVElDKSAhPSAwKSB7CiAgICAgICAgICAgICAgICBjaGVja1N0YXRpY0ludGVyZmFjZU1ldGhvZHMoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoKG1vZHMuZmxhZ3MgJiBGbGFncy5QUklWQVRFKSAhPSAwKSB7CiAgICAgICAgICAgICAgICBjaGVja1ByaXZhdGVJbnRlcmZhY2VNZXRob2RzKCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgSkNWYXJpYWJsZURlY2wgcHJldlJlY2VpdmVyUGFyYW0gPSB0aGlzLnJlY2VpdmVyUGFyYW07CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgdGhpcy5yZWNlaXZlclBhcmFtID0gbnVsbDsKICAgICAgICAgICAgLy8gUGFyc2luZyBmb3JtYWxQYXJhbWV0ZXJzIHNldHMgdGhlIHJlY2VpdmVyUGFyYW0sIGlmIHByZXNlbnQKICAgICAgICAgICAgTGlzdDxKQ1ZhcmlhYmxlRGVjbD4gcGFyYW1zID0gZm9ybWFsUGFyYW1ldGVycygpOwogICAgICAgICAgICBpZiAoIWlzVm9pZCkgdHlwZSA9IGJyYWNrZXRzT3B0KHR5cGUpOwogICAgICAgICAgICBMaXN0PEpDRXhwcmVzc2lvbj4gdGhyb3duID0gTGlzdC5uaWwoKTsKICAgICAgICAgICAgaWYgKHRva2VuLmtpbmQgPT0gVEhST1dTKSB7CiAgICAgICAgICAgICAgICBuZXh0VG9rZW4oKTsKICAgICAgICAgICAgICAgIHRocm93biA9IHF1YWxpZGVudExpc3QodHJ1ZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgSkNCbG9jayBib2R5ID0gbnVsbDsKICAgICAgICAgICAgSkNFeHByZXNzaW9uIGRlZmF1bHRWYWx1ZTsKICAgICAgICAgICAgaWYgKHRva2VuLmtpbmQgPT0gTEJSQUNFKSB7CiAgICAgICAgICAgICAgICBib2R5ID0gYmxvY2soKTsKICAgICAgICAgICAgICAgIGRlZmF1bHRWYWx1ZSA9IG51bGw7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBpZiAodG9rZW4ua2luZCA9PSBERUZBVUxUKSB7CiAgICAgICAgICAgICAgICAgICAgYWNjZXB0KERFRkFVTFQpOwogICAgICAgICAgICAgICAgICAgIGRlZmF1bHRWYWx1ZSA9IGFubm90YXRpb25WYWx1ZSgpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBkZWZhdWx0VmFsdWUgPSBudWxsOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYWNjZXB0KFNFTUkpOwogICAgICAgICAgICAgICAgaWYgKHRva2VuLnBvcyA8PSBlbmRQb3NUYWJsZS5lcnJvckVuZFBvcykgewogICAgICAgICAgICAgICAgICAgIC8vIGVycm9yIHJlY292ZXJ5CiAgICAgICAgICAgICAgICAgICAgc2tpcChmYWxzZSwgdHJ1ZSwgZmFsc2UsIGZhbHNlKTsKICAgICAgICAgICAgICAgICAgICBpZiAodG9rZW4ua2luZCA9PSBMQlJBQ0UpIHsKICAgICAgICAgICAgICAgICAgICAgICAgYm9keSA9IGJsb2NrKCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBKQ01ldGhvZERlY2wgcmVzdWx0ID0KICAgICAgICAgICAgICAgICAgICB0b1AoRi5hdChwb3MpLk1ldGhvZERlZihtb2RzLCBuYW1lLCB0eXBlLCB0eXBhcmFtcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWNlaXZlclBhcmFtLCBwYXJhbXMsIHRocm93biwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib2R5LCBkZWZhdWx0VmFsdWUpKTsKICAgICAgICAgICAgYXR0YWNoKHJlc3VsdCwgZGMpOwogICAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgIHRoaXMucmVjZWl2ZXJQYXJhbSA9IHByZXZSZWNlaXZlclBhcmFtOwogICAgICAgIH0KICAgIH0KCiAgICAvKiogUXVhbGlkZW50TGlzdCA9IFtBbm5vdGF0aW9uc10gUXVhbGlkZW50IHsiLCIgW0Fubm90YXRpb25zXSBRdWFsaWRlbnR9CiAgICAgKi8KICAgIExpc3Q8SkNFeHByZXNzaW9uPiBxdWFsaWRlbnRMaXN0KGJvb2xlYW4gYWxsb3dBbm5vcykgewogICAgICAgIExpc3RCdWZmZXI8SkNFeHByZXNzaW9uPiB0cyA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKCiAgICAgICAgTGlzdDxKQ0Fubm90YXRpb24+IHR5cGVBbm5vcyA9IGFsbG93QW5ub3MgPyB0eXBlQW5ub3RhdGlvbnNPcHQoKSA6IExpc3QubmlsKCk7CiAgICAgICAgSkNFeHByZXNzaW9uIHFpID0gcXVhbGlkZW50KGFsbG93QW5ub3MpOwogICAgICAgIGlmICghdHlwZUFubm9zLmlzRW1wdHkoKSkgewogICAgICAgICAgICBKQ0V4cHJlc3Npb24gYXQgPSBpbnNlcnRBbm5vdGF0aW9uc1RvTW9zdElubmVyKHFpLCB0eXBlQW5ub3MsIGZhbHNlKTsKICAgICAgICAgICAgdHMuYXBwZW5kKGF0KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB0cy5hcHBlbmQocWkpOwogICAgICAgIH0KICAgICAgICB3aGlsZSAodG9rZW4ua2luZCA9PSBDT01NQSkgewogICAgICAgICAgICBuZXh0VG9rZW4oKTsKCiAgICAgICAgICAgIHR5cGVBbm5vcyA9IGFsbG93QW5ub3MgPyB0eXBlQW5ub3RhdGlvbnNPcHQoKSA6IExpc3QubmlsKCk7CiAgICAgICAgICAgIHFpID0gcXVhbGlkZW50KGFsbG93QW5ub3MpOwogICAgICAgICAgICBpZiAoIXR5cGVBbm5vcy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICAgIEpDRXhwcmVzc2lvbiBhdCA9IGluc2VydEFubm90YXRpb25zVG9Nb3N0SW5uZXIocWksIHR5cGVBbm5vcywgZmFsc2UpOwogICAgICAgICAgICAgICAgdHMuYXBwZW5kKGF0KTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHRzLmFwcGVuZChxaSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRzLnRvTGlzdCgpOwogICAgfQoKICAgIC8qKgogICAgICogIHtAbGl0ZXJhbAogICAgICogIFR5cGVQYXJhbWV0ZXJzT3B0ID0gWyI8IiBUeXBlUGFyYW1ldGVyIHsiLCIgVHlwZVBhcmFtZXRlcn0gIj4iXQogICAgICogIH0KICAgICAqLwogICAgcHJvdGVjdGVkIExpc3Q8SkNUeXBlUGFyYW1ldGVyPiB0eXBlUGFyYW1ldGVyc09wdCgpIHsKICAgICAgICBpZiAodG9rZW4ua2luZCA9PSBMVCkgewogICAgICAgICAgICBMaXN0QnVmZmVyPEpDVHlwZVBhcmFtZXRlcj4gdHlwYXJhbXMgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgIG5leHRUb2tlbigpOwogICAgICAgICAgICB0eXBhcmFtcy5hcHBlbmQodHlwZVBhcmFtZXRlcigpKTsKICAgICAgICAgICAgd2hpbGUgKHRva2VuLmtpbmQgPT0gQ09NTUEpIHsKICAgICAgICAgICAgICAgIG5leHRUb2tlbigpOwogICAgICAgICAgICAgICAgdHlwYXJhbXMuYXBwZW5kKHR5cGVQYXJhbWV0ZXIoKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYWNjZXB0KEdUKTsKICAgICAgICAgICAgcmV0dXJuIHR5cGFyYW1zLnRvTGlzdCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiBMaXN0Lm5pbCgpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqICB7QGxpdGVyYWwKICAgICAqICBUeXBlUGFyYW1ldGVyID0gW0Fubm90YXRpb25zXSBUeXBlVmFyaWFibGUgW1R5cGVQYXJhbWV0ZXJCb3VuZF0KICAgICAqICBUeXBlUGFyYW1ldGVyQm91bmQgPSBFWFRFTkRTIFR5cGUgeyImIiBUeXBlfQogICAgICogIFR5cGVWYXJpYWJsZSA9IElkZW50CiAgICAgKiAgfQogICAgICovCiAgICBKQ1R5cGVQYXJhbWV0ZXIgdHlwZVBhcmFtZXRlcigpIHsKICAgICAgICBpbnQgcG9zID0gdG9rZW4ucG9zOwogICAgICAgIExpc3Q8SkNBbm5vdGF0aW9uPiBhbm5vcyA9IHR5cGVBbm5vdGF0aW9uc09wdCgpOwogICAgICAgIE5hbWUgbmFtZSA9IGlkZW50KCk7CiAgICAgICAgTGlzdEJ1ZmZlcjxKQ0V4cHJlc3Npb24+IGJvdW5kcyA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICBpZiAodG9rZW4ua2luZCA9PSBFWFRFTkRTKSB7CiAgICAgICAgICAgIG5leHRUb2tlbigpOwogICAgICAgICAgICBib3VuZHMuYXBwZW5kKHBhcnNlVHlwZSgpKTsKICAgICAgICAgICAgd2hpbGUgKHRva2VuLmtpbmQgPT0gQU1QKSB7CiAgICAgICAgICAgICAgICBuZXh0VG9rZW4oKTsKICAgICAgICAgICAgICAgIGJvdW5kcy5hcHBlbmQocGFyc2VUeXBlKCkpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiB0b1AoRi5hdChwb3MpLlR5cGVQYXJhbWV0ZXIobmFtZSwgYm91bmRzLnRvTGlzdCgpLCBhbm5vcykpOwogICAgfQoKICAgIC8qKiBGb3JtYWxQYXJhbWV0ZXJzID0gIigiIFsgRm9ybWFsUGFyYW1ldGVyTGlzdCBdICIpIgogICAgICogIEZvcm1hbFBhcmFtZXRlckxpc3QgPSBbIEZvcm1hbFBhcmFtZXRlckxpc3ROb3ZhcmFyZ3MgLCBdIExhc3RGb3JtYWxQYXJhbWV0ZXIKICAgICAqICBGb3JtYWxQYXJhbWV0ZXJMaXN0Tm92YXJhcmdzID0gWyBGb3JtYWxQYXJhbWV0ZXJMaXN0Tm92YXJhcmdzICwgXSBGb3JtYWxQYXJhbWV0ZXIKICAgICAqLwogICAgTGlzdDxKQ1ZhcmlhYmxlRGVjbD4gZm9ybWFsUGFyYW1ldGVycygpIHsKICAgICAgICByZXR1cm4gZm9ybWFsUGFyYW1ldGVycyhmYWxzZSk7CiAgICB9CiAgICBMaXN0PEpDVmFyaWFibGVEZWNsPiBmb3JtYWxQYXJhbWV0ZXJzKGJvb2xlYW4gbGFtYmRhUGFyYW1ldGVycykgewogICAgICAgIExpc3RCdWZmZXI8SkNWYXJpYWJsZURlY2w+IHBhcmFtcyA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICBKQ1ZhcmlhYmxlRGVjbCBsYXN0UGFyYW07CiAgICAgICAgYWNjZXB0KExQQVJFTik7CiAgICAgICAgaWYgKHRva2VuLmtpbmQgIT0gUlBBUkVOKSB7CiAgICAgICAgICAgIHRoaXMuYWxsb3dUaGlzSWRlbnQgPSB0cnVlOwogICAgICAgICAgICBsYXN0UGFyYW0gPSBmb3JtYWxQYXJhbWV0ZXIobGFtYmRhUGFyYW1ldGVycyk7CiAgICAgICAgICAgIGlmIChsYXN0UGFyYW0ubmFtZWV4cHIgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgdGhpcy5yZWNlaXZlclBhcmFtID0gbGFzdFBhcmFtOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcGFyYW1zLmFwcGVuZChsYXN0UGFyYW0pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHRoaXMuYWxsb3dUaGlzSWRlbnQgPSBmYWxzZTsKICAgICAgICAgICAgd2hpbGUgKHRva2VuLmtpbmQgPT0gQ09NTUEpIHsKICAgICAgICAgICAgICAgIGlmICgobGFzdFBhcmFtLm1vZHMuZmxhZ3MgJiBGbGFncy5WQVJBUkdTKSAhPSAwKSB7CiAgICAgICAgICAgICAgICAgICAgZXJyb3IobGFzdFBhcmFtLCAidmFyYXJncy5tdXN0LmJlLmxhc3QiKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIG5leHRUb2tlbigpOwogICAgICAgICAgICAgICAgcGFyYW1zLmFwcGVuZChsYXN0UGFyYW0gPSBmb3JtYWxQYXJhbWV0ZXIobGFtYmRhUGFyYW1ldGVycykpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmICh0b2tlbi5raW5kID09IFJQQVJFTikgewogICAgICAgICAgICBuZXh0VG9rZW4oKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzZXRFcnJvckVuZFBvcyh0b2tlbi5wb3MpOwogICAgICAgICAgICByZXBvcnRTeW50YXhFcnJvcihTLnByZXZUb2tlbigpLmVuZFBvcywgImV4cGVjdGVkMyIsIENPTU1BLCBSUEFSRU4sIExCUkFDS0VUKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHBhcmFtcy50b0xpc3QoKTsKICAgIH0KCiAgICBMaXN0PEpDVmFyaWFibGVEZWNsPiBpbXBsaWNpdFBhcmFtZXRlcnMoYm9vbGVhbiBoYXNQYXJlbnMpIHsKICAgICAgICBpZiAoaGFzUGFyZW5zKSB7CiAgICAgICAgICAgIGFjY2VwdChMUEFSRU4pOwogICAgICAgIH0KICAgICAgICBMaXN0QnVmZmVyPEpDVmFyaWFibGVEZWNsPiBwYXJhbXMgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgaWYgKHRva2VuLmtpbmQgIT0gUlBBUkVOICYmIHRva2VuLmtpbmQgIT0gQVJST1cpIHsKICAgICAgICAgICAgcGFyYW1zLmFwcGVuZChpbXBsaWNpdFBhcmFtZXRlcigpKTsKICAgICAgICAgICAgd2hpbGUgKHRva2VuLmtpbmQgPT0gQ09NTUEpIHsKICAgICAgICAgICAgICAgIG5leHRUb2tlbigpOwogICAgICAgICAgICAgICAgcGFyYW1zLmFwcGVuZChpbXBsaWNpdFBhcmFtZXRlcigpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoaGFzUGFyZW5zKSB7CiAgICAgICAgICAgIGFjY2VwdChSUEFSRU4pOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcGFyYW1zLnRvTGlzdCgpOwogICAgfQoKICAgIEpDTW9kaWZpZXJzIG9wdEZpbmFsKGxvbmcgZmxhZ3MpIHsKICAgICAgICBKQ01vZGlmaWVycyBtb2RzID0gbW9kaWZpZXJzT3B0KCk7CiAgICAgICAgY2hlY2tOb01vZHMobW9kcy5mbGFncyAmIH4oRmxhZ3MuRklOQUwgfCBGbGFncy5ERVBSRUNBVEVEKSk7CiAgICAgICAgbW9kcy5mbGFncyB8PSBmbGFnczsKICAgICAgICByZXR1cm4gbW9kczsKICAgIH0KCiAgICAvKioKICAgICAqIEluc2VydHMgdGhlIGFubm90YXRpb25zIChhbmQgcG9zc2libHkgYSBuZXcgYXJyYXkgbGV2ZWwpCiAgICAgKiB0byB0aGUgbGVmdC1tb3N0IHR5cGUgaW4gYW4gYXJyYXkgb3IgbmVzdGVkIHR5cGUuCiAgICAgKgogICAgICogV2hlbiBwYXJzaW5nIGEgdHlwZSBsaWtlIHtAY29kZSBAQiBPdXRlci5Jbm5lciBAQSBbXX0sIHRoZQogICAgICoge0Bjb2RlIEBBfSBhbm5vdGF0aW9uIHNob3VsZCB0YXJnZXQgdGhlIGFycmF5IGl0c2VsZiwgd2hpbGUKICAgICAqIHtAY29kZSBAQn0gdGFyZ2V0cyB0aGUgbmVzdGVkIHR5cGUge0Bjb2RlIE91dGVyfS4KICAgICAqCiAgICAgKiBDdXJyZW50bHkgdGhlIHBhcnNlciBwYXJzZXMgdGhlIGFubm90YXRpb24gZmlyc3QsIHRoZW4KICAgICAqIHRoZSBhcnJheSwgYW5kIHRoZW4gaW5zZXJ0cyB0aGUgYW5ub3RhdGlvbiB0byB0aGUgbGVmdC1tb3N0CiAgICAgKiBuZXN0ZWQgdHlwZS4KICAgICAqCiAgICAgKiBXaGVuIHtAY29kZSBjcmVhdGVOZXdMZXZlbH0gaXMgdHJ1ZSwgdGhlbiBhIG5ldyBhcnJheQogICAgICogbGV2ZWwgaXMgaW5zZXJ0ZWQgYXMgdGhlIG1vc3QgaW5uZXIgdHlwZSwgYW5kIGhhdmUgdGhlCiAgICAgKiBhbm5vdGF0aW9ucyB0YXJnZXQgaXQuICBUaGlzIGlzIHVzZWZ1bCBpbiB0aGUgY2FzZSBvZgogICAgICogdmFyYXJncywgZS5nLiB7QGNvZGUgU3RyaW5nIEBBIFtdIEBCIC4uLn0sIGFzIHRoZSBwYXJzZXIKICAgICAqIGZpcnN0IHBhcnNlcyB0aGUgdHlwZSB7QGNvZGUgU3RyaW5nIEBBIFtdfSB0aGVuIGluc2VydHMKICAgICAqIGEgbmV3IGFycmF5IGxldmVsIHdpdGgge0Bjb2RlIEBCfSBhbm5vdGF0aW9uLgogICAgICovCiAgICBwcml2YXRlIEpDRXhwcmVzc2lvbiBpbnNlcnRBbm5vdGF0aW9uc1RvTW9zdElubmVyKAogICAgICAgICAgICBKQ0V4cHJlc3Npb24gdHlwZSwgTGlzdDxKQ0Fubm90YXRpb24+IGFubm9zLAogICAgICAgICAgICBib29sZWFuIGNyZWF0ZU5ld0xldmVsKSB7CiAgICAgICAgaW50IG9yaWdFbmRQb3MgPSBnZXRFbmRQb3ModHlwZSk7CiAgICAgICAgSkNFeHByZXNzaW9uIG1vc3RJbm5lclR5cGUgPSB0eXBlOwogICAgICAgIEpDQXJyYXlUeXBlVHJlZSBtb3N0SW5uZXJBcnJheVR5cGUgPSBudWxsOwogICAgICAgIHdoaWxlIChUcmVlSW5mby50eXBlSW4obW9zdElubmVyVHlwZSkuaGFzVGFnKFRZUEVBUlJBWSkpIHsKICAgICAgICAgICAgbW9zdElubmVyQXJyYXlUeXBlID0gKEpDQXJyYXlUeXBlVHJlZSkgVHJlZUluZm8udHlwZUluKG1vc3RJbm5lclR5cGUpOwogICAgICAgICAgICBtb3N0SW5uZXJUeXBlID0gbW9zdElubmVyQXJyYXlUeXBlLmVsZW10eXBlOwogICAgICAgIH0KCiAgICAgICAgaWYgKGNyZWF0ZU5ld0xldmVsKSB7CiAgICAgICAgICAgIG1vc3RJbm5lclR5cGUgPSB0byhGLmF0KHRva2VuLnBvcykuVHlwZUFycmF5KG1vc3RJbm5lclR5cGUpKTsKICAgICAgICB9CgogICAgICAgIEpDRXhwcmVzc2lvbiBtb3N0SW5uZXJUeXBlVG9SZXR1cm4gPSBtb3N0SW5uZXJUeXBlOwogICAgICAgIGlmIChhbm5vcy5ub25FbXB0eSgpKSB7CiAgICAgICAgICAgIEpDRXhwcmVzc2lvbiBsYXN0VG9Nb2RpZnkgPSBtb3N0SW5uZXJUeXBlOwoKICAgICAgICAgICAgd2hpbGUgKFRyZWVJbmZvLnR5cGVJbihtb3N0SW5uZXJUeXBlKS5oYXNUYWcoU0VMRUNUKSB8fAogICAgICAgICAgICAgICAgICAgIFRyZWVJbmZvLnR5cGVJbihtb3N0SW5uZXJUeXBlKS5oYXNUYWcoVFlQRUFQUExZKSkgewogICAgICAgICAgICAgICAgd2hpbGUgKFRyZWVJbmZvLnR5cGVJbihtb3N0SW5uZXJUeXBlKS5oYXNUYWcoU0VMRUNUKSkgewogICAgICAgICAgICAgICAgICAgIGxhc3RUb01vZGlmeSA9IG1vc3RJbm5lclR5cGU7CiAgICAgICAgICAgICAgICAgICAgbW9zdElubmVyVHlwZSA9ICgoSkNGaWVsZEFjY2VzcykgVHJlZUluZm8udHlwZUluKG1vc3RJbm5lclR5cGUpKS5nZXRFeHByZXNzaW9uKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB3aGlsZSAoVHJlZUluZm8udHlwZUluKG1vc3RJbm5lclR5cGUpLmhhc1RhZyhUWVBFQVBQTFkpKSB7CiAgICAgICAgICAgICAgICAgICAgbGFzdFRvTW9kaWZ5ID0gbW9zdElubmVyVHlwZTsKICAgICAgICAgICAgICAgICAgICBtb3N0SW5uZXJUeXBlID0gKChKQ1R5cGVBcHBseSkgVHJlZUluZm8udHlwZUluKG1vc3RJbm5lclR5cGUpKS5jbGF6ejsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgbW9zdElubmVyVHlwZSA9IEYuYXQoYW5ub3MuaGVhZC5wb3MpLkFubm90YXRlZFR5cGUoYW5ub3MsIG1vc3RJbm5lclR5cGUpOwoKICAgICAgICAgICAgaWYgKFRyZWVJbmZvLnR5cGVJbihsYXN0VG9Nb2RpZnkpLmhhc1RhZyhUWVBFQVBQTFkpKSB7CiAgICAgICAgICAgICAgICAoKEpDVHlwZUFwcGx5KSBUcmVlSW5mby50eXBlSW4obGFzdFRvTW9kaWZ5KSkuY2xhenogPSBtb3N0SW5uZXJUeXBlOwogICAgICAgICAgICB9IGVsc2UgaWYgKFRyZWVJbmZvLnR5cGVJbihsYXN0VG9Nb2RpZnkpLmhhc1RhZyhTRUxFQ1QpKSB7CiAgICAgICAgICAgICAgICAoKEpDRmllbGRBY2Nlc3MpIFRyZWVJbmZvLnR5cGVJbihsYXN0VG9Nb2RpZnkpKS5zZWxlY3RlZCA9IG1vc3RJbm5lclR5cGU7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvLyBXZSBuZXZlciBzYXcgYSBTRUxFQ1Qgb3IgVFlQRUFQUExZLCByZXR1cm4gdGhlIGFubm90YXRlZCB0eXBlLgogICAgICAgICAgICAgICAgbW9zdElubmVyVHlwZVRvUmV0dXJuID0gbW9zdElubmVyVHlwZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKG1vc3RJbm5lckFycmF5VHlwZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHJldHVybiBtb3N0SW5uZXJUeXBlVG9SZXR1cm47CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgbW9zdElubmVyQXJyYXlUeXBlLmVsZW10eXBlID0gbW9zdElubmVyVHlwZVRvUmV0dXJuOwogICAgICAgICAgICBzdG9yZUVuZCh0eXBlLCBvcmlnRW5kUG9zKTsKICAgICAgICAgICAgcmV0dXJuIHR5cGU7CiAgICAgICAgfQogICAgfQoKICAgIC8qKiBGb3JtYWxQYXJhbWV0ZXIgPSB7IEZJTkFMIHwgJ0AnIEFubm90YXRpb24gfSBUeXBlIFZhcmlhYmxlRGVjbGFyYXRvcklkCiAgICAgKiAgTGFzdEZvcm1hbFBhcmFtZXRlciA9IHsgRklOQUwgfCAnQCcgQW5ub3RhdGlvbiB9IFR5cGUgJy4uLicgSWRlbnQgfCBGb3JtYWxQYXJhbWV0ZXIKICAgICAqLwogICAgcHJvdGVjdGVkIEpDVmFyaWFibGVEZWNsIGZvcm1hbFBhcmFtZXRlcigpIHsKICAgICAgICByZXR1cm4gZm9ybWFsUGFyYW1ldGVyKGZhbHNlKTsKICAgIH0KICAgIHByb3RlY3RlZCBKQ1ZhcmlhYmxlRGVjbCBmb3JtYWxQYXJhbWV0ZXIoYm9vbGVhbiBsYW1iZGFQYXJhbWV0ZXIpIHsKICAgICAgICBKQ01vZGlmaWVycyBtb2RzID0gb3B0RmluYWwoRmxhZ3MuUEFSQU1FVEVSKTsKICAgICAgICAvLyBuZWVkIHRvIGRpc3Rpbmd1aXNoIGJldHdlZW4gdmFyYXJnIGFubm9zIGFuZCBhcnJheSBhbm5vcwogICAgICAgIC8vIGxvb2sgYXQgdHlwZUFubm90YXRpb25zUHVzaGVkQmFjayBjb21tZW50CiAgICAgICAgdGhpcy5wZXJtaXRUeXBlQW5ub3RhdGlvbnNQdXNoQmFjayA9IHRydWU7CiAgICAgICAgSkNFeHByZXNzaW9uIHR5cGUgPSBwYXJzZVR5cGUoKTsKICAgICAgICB0aGlzLnBlcm1pdFR5cGVBbm5vdGF0aW9uc1B1c2hCYWNrID0gZmFsc2U7CgogICAgICAgIGlmICh0b2tlbi5raW5kID09IEVMTElQU0lTKSB7CiAgICAgICAgICAgIExpc3Q8SkNBbm5vdGF0aW9uPiB2YXJhcmdzQW5ub3MgPSB0eXBlQW5ub3RhdGlvbnNQdXNoZWRCYWNrOwogICAgICAgICAgICB0eXBlQW5ub3RhdGlvbnNQdXNoZWRCYWNrID0gTGlzdC5uaWwoKTsKICAgICAgICAgICAgbW9kcy5mbGFncyB8PSBGbGFncy5WQVJBUkdTOwogICAgICAgICAgICAvLyBpbnNlcnQgdmFyIGFyZyB0eXBlIGFubm90YXRpb25zCiAgICAgICAgICAgIHR5cGUgPSBpbnNlcnRBbm5vdGF0aW9uc1RvTW9zdElubmVyKHR5cGUsIHZhcmFyZ3NBbm5vcywgdHJ1ZSk7CiAgICAgICAgICAgIG5leHRUb2tlbigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8vIGlmIG5vdCBhIHZhciBhcmcsIHRoZW4gdHlwZUFubm90YXRpb25zUHVzaGVkQmFjayBzaG91bGQgYmUgbnVsbAogICAgICAgICAgICBpZiAodHlwZUFubm90YXRpb25zUHVzaGVkQmFjay5ub25FbXB0eSgpKSB7CiAgICAgICAgICAgICAgICByZXBvcnRTeW50YXhFcnJvcih0eXBlQW5ub3RhdGlvbnNQdXNoZWRCYWNrLmhlYWQucG9zLAogICAgICAgICAgICAgICAgICAgICAgICAiaWxsZWdhbC5zdGFydC5vZi50eXBlIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdHlwZUFubm90YXRpb25zUHVzaGVkQmFjayA9IExpc3QubmlsKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB2YXJpYWJsZURlY2xhcmF0b3JJZChtb2RzLCB0eXBlLCBsYW1iZGFQYXJhbWV0ZXIpOwogICAgfQoKICAgIHByb3RlY3RlZCBKQ1ZhcmlhYmxlRGVjbCBpbXBsaWNpdFBhcmFtZXRlcigpIHsKICAgICAgICBKQ01vZGlmaWVycyBtb2RzID0gRi5hdCh0b2tlbi5wb3MpLk1vZGlmaWVycyhGbGFncy5QQVJBTUVURVIpOwogICAgICAgIHJldHVybiB2YXJpYWJsZURlY2xhcmF0b3JJZChtb2RzLCBudWxsLCB0cnVlKTsKICAgIH0KCi8qIC0tLS0tLS0tLS0gYXV4aWxpYXJ5IG1ldGhvZHMgLS0tLS0tLS0tLS0tLS0gKi8KCiAgICB2b2lkIGVycm9yKGludCBwb3MsIFN0cmluZyBrZXksIE9iamVjdCAuLi4gYXJncykgewogICAgICAgIGxvZy5lcnJvcihEaWFnbm9zdGljRmxhZy5TWU5UQVgsIHBvcywga2V5LCBhcmdzKTsKICAgIH0KCiAgICB2b2lkIGVycm9yKERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIFN0cmluZyBrZXksIE9iamVjdCAuLi4gYXJncykgewogICAgICAgIGxvZy5lcnJvcihEaWFnbm9zdGljRmxhZy5TWU5UQVgsIHBvcywga2V5LCBhcmdzKTsKICAgIH0KCiAgICB2b2lkIHdhcm5pbmcoaW50IHBvcywgU3RyaW5nIGtleSwgT2JqZWN0IC4uLiBhcmdzKSB7CiAgICAgICAgbG9nLndhcm5pbmcocG9zLCBrZXksIGFyZ3MpOwogICAgfQoKICAgIC8qKiBDaGVjayB0aGF0IGdpdmVuIHRyZWUgaXMgYSBsZWdhbCBleHByZXNzaW9uIHN0YXRlbWVudC4KICAgICAqLwogICAgcHJvdGVjdGVkIEpDRXhwcmVzc2lvbiBjaGVja0V4cHJTdGF0KEpDRXhwcmVzc2lvbiB0KSB7CiAgICAgICAgaWYgKCFUcmVlSW5mby5pc0V4cHJlc3Npb25TdGF0ZW1lbnQodCkpIHsKICAgICAgICAgICAgSkNFeHByZXNzaW9uIHJldCA9IEYuYXQodC5wb3MpLkVycm9uZW91cyhMaXN0LjxKQ1RyZWU+b2YodCkpOwogICAgICAgICAgICBlcnJvcihyZXQsICJub3Quc3RtdCIpOwogICAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiB0OwogICAgICAgIH0KICAgIH0KCiAgICAvKiogUmV0dXJuIHByZWNlZGVuY2Ugb2Ygb3BlcmF0b3IgcmVwcmVzZW50ZWQgYnkgdG9rZW4sCiAgICAgKiAgLTEgaWYgdG9rZW4gaXMgbm90IGEgYmluYXJ5IG9wZXJhdG9yLiBAc2VlIFRyZWVJbmZvLm9wUHJlYwogICAgICovCiAgICBzdGF0aWMgaW50IHByZWMoVG9rZW5LaW5kIHRva2VuKSB7CiAgICAgICAgSkNUcmVlLlRhZyBvYyA9IG9wdGFnKHRva2VuKTsKICAgICAgICByZXR1cm4gKG9jICE9IE5PX1RBRykgPyBUcmVlSW5mby5vcFByZWMob2MpIDogLTE7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm4gdGhlIGxlc3NlciBvZiB0d28gcG9zaXRpb25zLCBtYWtpbmcgYWxsb3dhbmNlIGZvciBlaXRoZXIgb25lCiAgICAgKiBiZWluZyB1bnNldC4KICAgICAqLwogICAgc3RhdGljIGludCBlYXJsaWVyKGludCBwb3MxLCBpbnQgcG9zMikgewogICAgICAgIGlmIChwb3MxID09IFBvc2l0aW9uLk5PUE9TKQogICAgICAgICAgICByZXR1cm4gcG9zMjsKICAgICAgICBpZiAocG9zMiA9PSBQb3NpdGlvbi5OT1BPUykKICAgICAgICAgICAgcmV0dXJuIHBvczE7CiAgICAgICAgcmV0dXJuIChwb3MxIDwgcG9zMiA/IHBvczEgOiBwb3MyKTsKICAgIH0KCiAgICAvKiogUmV0dXJuIG9wZXJhdGlvbiB0YWcgb2YgYmluYXJ5IG9wZXJhdG9yIHJlcHJlc2VudGVkIGJ5IHRva2VuLAogICAgICogIE5vX1RBRyBpZiB0b2tlbiBpcyBub3QgYSBiaW5hcnkgb3BlcmF0b3IuCiAgICAgKi8KICAgIHN0YXRpYyBKQ1RyZWUuVGFnIG9wdGFnKFRva2VuS2luZCB0b2tlbikgewogICAgICAgIHN3aXRjaCAodG9rZW4pIHsKICAgICAgICBjYXNlIEJBUkJBUjoKICAgICAgICAgICAgcmV0dXJuIE9SOwogICAgICAgIGNhc2UgQU1QQU1QOgogICAgICAgICAgICByZXR1cm4gQU5EOwogICAgICAgIGNhc2UgQkFSOgogICAgICAgICAgICByZXR1cm4gQklUT1I7CiAgICAgICAgY2FzZSBCQVJFUToKICAgICAgICAgICAgcmV0dXJuIEJJVE9SX0FTRzsKICAgICAgICBjYXNlIENBUkVUOgogICAgICAgICAgICByZXR1cm4gQklUWE9SOwogICAgICAgIGNhc2UgQ0FSRVRFUToKICAgICAgICAgICAgcmV0dXJuIEJJVFhPUl9BU0c7CiAgICAgICAgY2FzZSBBTVA6CiAgICAgICAgICAgIHJldHVybiBCSVRBTkQ7CiAgICAgICAgY2FzZSBBTVBFUToKICAgICAgICAgICAgcmV0dXJuIEJJVEFORF9BU0c7CiAgICAgICAgY2FzZSBFUUVROgogICAgICAgICAgICByZXR1cm4gSkNUcmVlLlRhZy5FUTsKICAgICAgICBjYXNlIEJBTkdFUToKICAgICAgICAgICAgcmV0dXJuIE5FOwogICAgICAgIGNhc2UgTFQ6CiAgICAgICAgICAgIHJldHVybiBKQ1RyZWUuVGFnLkxUOwogICAgICAgIGNhc2UgR1Q6CiAgICAgICAgICAgIHJldHVybiBKQ1RyZWUuVGFnLkdUOwogICAgICAgIGNhc2UgTFRFUToKICAgICAgICAgICAgcmV0dXJuIExFOwogICAgICAgIGNhc2UgR1RFUToKICAgICAgICAgICAgcmV0dXJuIEdFOwogICAgICAgIGNhc2UgTFRMVDoKICAgICAgICAgICAgcmV0dXJuIFNMOwogICAgICAgIGNhc2UgTFRMVEVROgogICAgICAgICAgICByZXR1cm4gU0xfQVNHOwogICAgICAgIGNhc2UgR1RHVDoKICAgICAgICAgICAgcmV0dXJuIFNSOwogICAgICAgIGNhc2UgR1RHVEVROgogICAgICAgICAgICByZXR1cm4gU1JfQVNHOwogICAgICAgIGNhc2UgR1RHVEdUOgogICAgICAgICAgICByZXR1cm4gVVNSOwogICAgICAgIGNhc2UgR1RHVEdURVE6CiAgICAgICAgICAgIHJldHVybiBVU1JfQVNHOwogICAgICAgIGNhc2UgUExVUzoKICAgICAgICAgICAgcmV0dXJuIEpDVHJlZS5UYWcuUExVUzsKICAgICAgICBjYXNlIFBMVVNFUToKICAgICAgICAgICAgcmV0dXJuIFBMVVNfQVNHOwogICAgICAgIGNhc2UgU1VCOgogICAgICAgICAgICByZXR1cm4gTUlOVVM7CiAgICAgICAgY2FzZSBTVUJFUToKICAgICAgICAgICAgcmV0dXJuIE1JTlVTX0FTRzsKICAgICAgICBjYXNlIFNUQVI6CiAgICAgICAgICAgIHJldHVybiBNVUw7CiAgICAgICAgY2FzZSBTVEFSRVE6CiAgICAgICAgICAgIHJldHVybiBNVUxfQVNHOwogICAgICAgIGNhc2UgU0xBU0g6CiAgICAgICAgICAgIHJldHVybiBESVY7CiAgICAgICAgY2FzZSBTTEFTSEVROgogICAgICAgICAgICByZXR1cm4gRElWX0FTRzsKICAgICAgICBjYXNlIFBFUkNFTlQ6CiAgICAgICAgICAgIHJldHVybiBNT0Q7CiAgICAgICAgY2FzZSBQRVJDRU5URVE6CiAgICAgICAgICAgIHJldHVybiBNT0RfQVNHOwogICAgICAgIGNhc2UgSU5TVEFOQ0VPRjoKICAgICAgICAgICAgcmV0dXJuIFRZUEVURVNUOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHJldHVybiBOT19UQUc7CiAgICAgICAgfQogICAgfQoKICAgIC8qKiBSZXR1cm4gb3BlcmF0aW9uIHRhZyBvZiB1bmFyeSBvcGVyYXRvciByZXByZXNlbnRlZCBieSB0b2tlbiwKICAgICAqICBOb19UQUcgaWYgdG9rZW4gaXMgbm90IGEgYmluYXJ5IG9wZXJhdG9yLgogICAgICovCiAgICBzdGF0aWMgSkNUcmVlLlRhZyB1bm9wdGFnKFRva2VuS2luZCB0b2tlbikgewogICAgICAgIHN3aXRjaCAodG9rZW4pIHsKICAgICAgICBjYXNlIFBMVVM6CiAgICAgICAgICAgIHJldHVybiBQT1M7CiAgICAgICAgY2FzZSBTVUI6CiAgICAgICAgICAgIHJldHVybiBORUc7CiAgICAgICAgY2FzZSBCQU5HOgogICAgICAgICAgICByZXR1cm4gTk9UOwogICAgICAgIGNhc2UgVElMREU6CiAgICAgICAgICAgIHJldHVybiBDT01QTDsKICAgICAgICBjYXNlIFBMVVNQTFVTOgogICAgICAgICAgICByZXR1cm4gUFJFSU5DOwogICAgICAgIGNhc2UgU1VCU1VCOgogICAgICAgICAgICByZXR1cm4gUFJFREVDOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHJldHVybiBOT19UQUc7CiAgICAgICAgfQogICAgfQoKICAgIC8qKiBSZXR1cm4gdHlwZSB0YWcgb2YgYmFzaWMgdHlwZSByZXByZXNlbnRlZCBieSB0b2tlbiwKICAgICAqICBOT05FIGlmIHRva2VuIGlzIG5vdCBhIGJhc2ljIHR5cGUgaWRlbnRpZmllci4KICAgICAqLwogICAgc3RhdGljIFR5cGVUYWcgdHlwZXRhZyhUb2tlbktpbmQgdG9rZW4pIHsKICAgICAgICBzd2l0Y2ggKHRva2VuKSB7CiAgICAgICAgY2FzZSBCWVRFOgogICAgICAgICAgICByZXR1cm4gVHlwZVRhZy5CWVRFOwogICAgICAgIGNhc2UgQ0hBUjoKICAgICAgICAgICAgcmV0dXJuIFR5cGVUYWcuQ0hBUjsKICAgICAgICBjYXNlIFNIT1JUOgogICAgICAgICAgICByZXR1cm4gVHlwZVRhZy5TSE9SVDsKICAgICAgICBjYXNlIElOVDoKICAgICAgICAgICAgcmV0dXJuIFR5cGVUYWcuSU5UOwogICAgICAgIGNhc2UgTE9ORzoKICAgICAgICAgICAgcmV0dXJuIFR5cGVUYWcuTE9ORzsKICAgICAgICBjYXNlIEZMT0FUOgogICAgICAgICAgICByZXR1cm4gVHlwZVRhZy5GTE9BVDsKICAgICAgICBjYXNlIERPVUJMRToKICAgICAgICAgICAgcmV0dXJuIFR5cGVUYWcuRE9VQkxFOwogICAgICAgIGNhc2UgQk9PTEVBTjoKICAgICAgICAgICAgcmV0dXJuIFR5cGVUYWcuQk9PTEVBTjsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICByZXR1cm4gVHlwZVRhZy5OT05FOwogICAgICAgIH0KICAgIH0KCiAgICB2b2lkIGNoZWNrRGlhbW9uZCgpIHsKICAgICAgICBpZiAoIWFsbG93RGlhbW9uZCkgewogICAgICAgICAgICBsb2cuZXJyb3IoRGlhZ25vc3RpY0ZsYWcuU09VUkNFX0xFVkVMLCB0b2tlbi5wb3MsICJkaWFtb25kLm5vdC5zdXBwb3J0ZWQuaW4uc291cmNlIiwgc291cmNlLm5hbWUpOwogICAgICAgIH0KICAgIH0KICAgIHZvaWQgY2hlY2tNdWx0aWNhdGNoKCkgewogICAgICAgIGlmICghYWxsb3dNdWx0aWNhdGNoKSB7CiAgICAgICAgICAgIGxvZy5lcnJvcihEaWFnbm9zdGljRmxhZy5TT1VSQ0VfTEVWRUwsIHRva2VuLnBvcywgIm11bHRpY2F0Y2gubm90LnN1cHBvcnRlZC5pbi5zb3VyY2UiLCBzb3VyY2UubmFtZSk7CiAgICAgICAgfQogICAgfQogICAgdm9pZCBjaGVja1RyeVdpdGhSZXNvdXJjZXMoKSB7CiAgICAgICAgaWYgKCFhbGxvd1RXUikgewogICAgICAgICAgICBsb2cuZXJyb3IoRGlhZ25vc3RpY0ZsYWcuU09VUkNFX0xFVkVMLCB0b2tlbi5wb3MsICJ0cnkud2l0aC5yZXNvdXJjZXMubm90LnN1cHBvcnRlZC5pbi5zb3VyY2UiLCBzb3VyY2UubmFtZSk7CiAgICAgICAgfQogICAgfQogICAgdm9pZCBjaGVja1ZhcmlhYmxlSW5UcnlXaXRoUmVzb3VyY2VzKGludCBzdGFydFBvcykgewogICAgICAgIGlmICghYWxsb3dFZmZlY3RpdmVseUZpbmFsVmFyaWFibGVzSW5UV1IpIHsKICAgICAgICAgICAgbG9nLmVycm9yKERpYWdub3N0aWNGbGFnLlNPVVJDRV9MRVZFTCwgc3RhcnRQb3MsICJ2YXIuaW4udHJ5LndpdGgucmVzb3VyY2VzLm5vdC5zdXBwb3J0ZWQuaW4uc291cmNlIiwgc291cmNlLm5hbWUpOwogICAgICAgIH0KICAgIH0KICAgIHZvaWQgY2hlY2tMYW1iZGEoKSB7CiAgICAgICAgaWYgKCFhbGxvd0xhbWJkYSkgewogICAgICAgICAgICBsb2cuZXJyb3IoRGlhZ25vc3RpY0ZsYWcuU09VUkNFX0xFVkVMLCB0b2tlbi5wb3MsICJsYW1iZGEubm90LnN1cHBvcnRlZC5pbi5zb3VyY2UiLCBzb3VyY2UubmFtZSk7CiAgICAgICAgfQogICAgfQogICAgdm9pZCBjaGVja01ldGhvZFJlZmVyZW5jZXMoKSB7CiAgICAgICAgaWYgKCFhbGxvd01ldGhvZFJlZmVyZW5jZXMpIHsKICAgICAgICAgICAgbG9nLmVycm9yKERpYWdub3N0aWNGbGFnLlNPVVJDRV9MRVZFTCwgdG9rZW4ucG9zLCAibWV0aG9kLnJlZmVyZW5jZXMubm90LnN1cHBvcnRlZC5pbi5zb3VyY2UiLCBzb3VyY2UubmFtZSk7CiAgICAgICAgfQogICAgfQogICAgdm9pZCBjaGVja0RlZmF1bHRNZXRob2RzKCkgewogICAgICAgIGlmICghYWxsb3dEZWZhdWx0TWV0aG9kcykgewogICAgICAgICAgICBsb2cuZXJyb3IoRGlhZ25vc3RpY0ZsYWcuU09VUkNFX0xFVkVMLCB0b2tlbi5wb3MsICJkZWZhdWx0Lm1ldGhvZHMubm90LnN1cHBvcnRlZC5pbi5zb3VyY2UiLCBzb3VyY2UubmFtZSk7CiAgICAgICAgfQogICAgfQogICAgdm9pZCBjaGVja0ludGVyc2VjdGlvblR5cGVzSW5DYXN0KCkgewogICAgICAgIGlmICghYWxsb3dJbnRlcnNlY3Rpb25UeXBlc0luQ2FzdCkgewogICAgICAgICAgICBsb2cuZXJyb3IoRGlhZ25vc3RpY0ZsYWcuU09VUkNFX0xFVkVMLCB0b2tlbi5wb3MsICJpbnRlcnNlY3Rpb24udHlwZXMuaW4uY2FzdC5ub3Quc3VwcG9ydGVkLmluLnNvdXJjZSIsIHNvdXJjZS5uYW1lKTsKICAgICAgICB9CiAgICB9CiAgICB2b2lkIGNoZWNrU3RhdGljSW50ZXJmYWNlTWV0aG9kcygpIHsKICAgICAgICBpZiAoIWFsbG93U3RhdGljSW50ZXJmYWNlTWV0aG9kcykgewogICAgICAgICAgICBsb2cuZXJyb3IoRGlhZ25vc3RpY0ZsYWcuU09VUkNFX0xFVkVMLCB0b2tlbi5wb3MsICJzdGF0aWMuaW50Zi5tZXRob2RzLm5vdC5zdXBwb3J0ZWQuaW4uc291cmNlIiwgc291cmNlLm5hbWUpOwogICAgICAgIH0KICAgIH0KICAgIHZvaWQgY2hlY2tUeXBlQW5ub3RhdGlvbnMoKSB7CiAgICAgICAgaWYgKCFhbGxvd1R5cGVBbm5vdGF0aW9ucykgewogICAgICAgICAgICBsb2cuZXJyb3IoRGlhZ25vc3RpY0ZsYWcuU09VUkNFX0xFVkVMLCB0b2tlbi5wb3MsICJ0eXBlLmFubm90YXRpb25zLm5vdC5zdXBwb3J0ZWQuaW4uc291cmNlIiwgc291cmNlLm5hbWUpOwogICAgICAgIH0KICAgIH0KICAgIHZvaWQgY2hlY2tQcml2YXRlSW50ZXJmYWNlTWV0aG9kcygpIHsKICAgICAgICBpZiAoIWFsbG93UHJpdmF0ZUludGVyZmFjZU1ldGhvZHMpIHsKICAgICAgICAgICAgbG9nLmVycm9yKERpYWdub3N0aWNGbGFnLlNPVVJDRV9MRVZFTCwgdG9rZW4ucG9zLCBDb21waWxlclByb3BlcnRpZXMuRXJyb3JzLlByaXZhdGVJbnRmTWV0aG9kc05vdFN1cHBvcnRlZEluU291cmNlKHNvdXJjZS5uYW1lKSk7CiAgICAgICAgfQogICAgfQogICAgcHJvdGVjdGVkIHZvaWQgY2hlY2tBbm5vdGF0aW9uc0FmdGVyVHlwZVBhcmFtcyhpbnQgcG9zKSB7CiAgICAgICAgaWYgKCFhbGxvd0Fubm90YXRpb25zQWZ0ZXJUeXBlUGFyYW1zKSB7CiAgICAgICAgICAgIGxvZy5lcnJvcihEaWFnbm9zdGljRmxhZy5TT1VSQ0VfTEVWRUwsIHBvcywgImFubm90YXRpb25zLmFmdGVyLnR5cGUucGFyYW1zLm5vdC5zdXBwb3J0ZWQuaW4uc291cmNlIiwgc291cmNlLm5hbWUpOwogICAgICAgIH0KICAgIH0KCiAgICAvKgogICAgICogYSBmdW5jdGlvbmFsIHNvdXJjZSB0cmVlIGFuZCBlbmQgcG9zaXRpb24gbWFwcGluZ3MKICAgICAqLwogICAgcHJvdGVjdGVkIHN0YXRpYyBjbGFzcyBTaW1wbGVFbmRQb3NUYWJsZSBleHRlbmRzIEFic3RyYWN0RW5kUG9zVGFibGUgewoKICAgICAgICBwcml2YXRlIGZpbmFsIEludEhhc2hUYWJsZSBlbmRQb3NNYXA7CgogICAgICAgIFNpbXBsZUVuZFBvc1RhYmxlKEphdmFjUGFyc2VyIHBhcnNlcikgewogICAgICAgICAgICBzdXBlcihwYXJzZXIpOwogICAgICAgICAgICBlbmRQb3NNYXAgPSBuZXcgSW50SGFzaFRhYmxlKCk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgdm9pZCBzdG9yZUVuZChKQ1RyZWUgdHJlZSwgaW50IGVuZHBvcykgewogICAgICAgICAgICBlbmRQb3NNYXAucHV0QXRJbmRleCh0cmVlLCBlcnJvckVuZFBvcyA+IGVuZHBvcyA/IGVycm9yRW5kUG9zIDogZW5kcG9zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmRQb3NNYXAubG9va3VwKHRyZWUpKTsKICAgICAgICB9CgogICAgICAgIHByb3RlY3RlZCA8VCBleHRlbmRzIEpDVHJlZT4gVCB0byhUIHQpIHsKICAgICAgICAgICAgc3RvcmVFbmQodCwgcGFyc2VyLnRva2VuLmVuZFBvcyk7CiAgICAgICAgICAgIHJldHVybiB0OwogICAgICAgIH0KCiAgICAgICAgcHJvdGVjdGVkIDxUIGV4dGVuZHMgSkNUcmVlPiBUIHRvUChUIHQpIHsKICAgICAgICAgICAgc3RvcmVFbmQodCwgcGFyc2VyLlMucHJldlRva2VuKCkuZW5kUG9zKTsKICAgICAgICAgICAgcmV0dXJuIHQ7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgaW50IGdldEVuZFBvcyhKQ1RyZWUgdHJlZSkgewogICAgICAgICAgICBpbnQgdmFsdWUgPSBlbmRQb3NNYXAuZ2V0RnJvbUluZGV4KGVuZFBvc01hcC5sb29rdXAodHJlZSkpOwogICAgICAgICAgICAvLyBBcyBsb25nIGFzIFBvc2l0aW9uLk5PUE9TPT0tMSwgdGhpcyBqdXN0IHJldHVybnMgdmFsdWUuCiAgICAgICAgICAgIHJldHVybiAodmFsdWUgPT0gLTEpID8gUG9zaXRpb24uTk9QT1MgOiB2YWx1ZTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBpbnQgcmVwbGFjZVRyZWUoSkNUcmVlIG9sZFRyZWUsIEpDVHJlZSBuZXdUcmVlKSB7CiAgICAgICAgICAgIGludCBwb3MgPSBlbmRQb3NNYXAucmVtb3ZlKG9sZFRyZWUpOwogICAgICAgICAgICBpZiAocG9zICE9IC0xKSB7CiAgICAgICAgICAgICAgICBzdG9yZUVuZChuZXdUcmVlLCBwb3MpOwogICAgICAgICAgICAgICAgcmV0dXJuIHBvczsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gUG9zaXRpb24uTk9QT1M7CiAgICAgICAgfQogICAgfQoKICAgIC8qCiAgICAgKiBhIGRlZmF1bHQgc2tlbGV0YWwgaW1wbGVtZW50YXRpb24gd2l0aG91dCBhbnkgbWFwcGluZyBvdmVyaGVhZC4KICAgICAqLwogICAgcHJvdGVjdGVkIHN0YXRpYyBjbGFzcyBFbXB0eUVuZFBvc1RhYmxlIGV4dGVuZHMgQWJzdHJhY3RFbmRQb3NUYWJsZSB7CgogICAgICAgIEVtcHR5RW5kUG9zVGFibGUoSmF2YWNQYXJzZXIgcGFyc2VyKSB7CiAgICAgICAgICAgIHN1cGVyKHBhcnNlcik7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgdm9pZCBzdG9yZUVuZChKQ1RyZWUgdHJlZSwgaW50IGVuZHBvcykgeyAvKiBlbXB0eSAqLyB9CgogICAgICAgIHByb3RlY3RlZCA8VCBleHRlbmRzIEpDVHJlZT4gVCB0byhUIHQpIHsKICAgICAgICAgICAgcmV0dXJuIHQ7CiAgICAgICAgfQoKICAgICAgICBwcm90ZWN0ZWQgPFQgZXh0ZW5kcyBKQ1RyZWU+IFQgdG9QKFQgdCkgewogICAgICAgICAgICByZXR1cm4gdDsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBpbnQgZ2V0RW5kUG9zKEpDVHJlZSB0cmVlKSB7CiAgICAgICAgICAgIHJldHVybiBQb3NpdGlvbi5OT1BPUzsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBpbnQgcmVwbGFjZVRyZWUoSkNUcmVlIG9sZFRyZWUsIEpDVHJlZSBuZXdUcmVlKSB7CiAgICAgICAgICAgIHJldHVybiBQb3NpdGlvbi5OT1BPUzsKICAgICAgICB9CgogICAgfQoKICAgIHByb3RlY3RlZCBzdGF0aWMgYWJzdHJhY3QgY2xhc3MgQWJzdHJhY3RFbmRQb3NUYWJsZSBpbXBsZW1lbnRzIEVuZFBvc1RhYmxlIHsKICAgICAgICAvKioKICAgICAgICAgKiBUaGUgY3VycmVudCBwYXJzZXIuCiAgICAgICAgICovCiAgICAgICAgcHJvdGVjdGVkIEphdmFjUGFyc2VyIHBhcnNlcjsKCiAgICAgICAgLyoqCiAgICAgICAgICogU3RvcmUgdGhlIGxhc3QgZXJyb3IgcG9zaXRpb24uCiAgICAgICAgICovCiAgICAgICAgcHVibGljIGludCBlcnJvckVuZFBvcyA9IFBvc2l0aW9uLk5PUE9TOwoKICAgICAgICBwdWJsaWMgQWJzdHJhY3RFbmRQb3NUYWJsZShKYXZhY1BhcnNlciBwYXJzZXIpIHsKICAgICAgICAgICAgdGhpcy5wYXJzZXIgPSBwYXJzZXI7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBTdG9yZSBjdXJyZW50IHRva2VuJ3MgZW5kaW5nIHBvc2l0aW9uIGZvciBhIHRyZWUsIHRoZSB2YWx1ZSBvZiB3aGljaAogICAgICAgICAqIHdpbGwgYmUgdGhlIGdyZWF0ZXIgb2YgbGFzdCBlcnJvciBwb3NpdGlvbiBhbmQgdGhlIGVuZGluZyBwb3NpdGlvbiBvZgogICAgICAgICAqIHRoZSBjdXJyZW50IHRva2VuLgogICAgICAgICAqIEBwYXJhbSB0IFRoZSB0cmVlLgogICAgICAgICAqLwogICAgICAgIHByb3RlY3RlZCBhYnN0cmFjdCA8VCBleHRlbmRzIEpDVHJlZT4gVCB0byhUIHQpOwoKICAgICAgICAvKioKICAgICAgICAgKiBTdG9yZSBjdXJyZW50IHRva2VuJ3MgZW5kaW5nIHBvc2l0aW9uIGZvciBhIHRyZWUsIHRoZSB2YWx1ZSBvZiB3aGljaAogICAgICAgICAqIHdpbGwgYmUgdGhlIGdyZWF0ZXIgb2YgbGFzdCBlcnJvciBwb3NpdGlvbiBhbmQgdGhlIGVuZGluZyBwb3NpdGlvbiBvZgogICAgICAgICAqIHRoZSBwcmV2aW91cyB0b2tlbi4KICAgICAgICAgKiBAcGFyYW0gdCBUaGUgdHJlZS4KICAgICAgICAgKi8KICAgICAgICBwcm90ZWN0ZWQgYWJzdHJhY3QgPFQgZXh0ZW5kcyBKQ1RyZWU+IFQgdG9QKFQgdCk7CgogICAgICAgIC8qKgogICAgICAgICAqIFNldCB0aGUgZXJyb3IgcG9zaXRpb24gZHVyaW5nIHRoZSBwYXJzaW5nIHBoYXNlcywgdGhlIHZhbHVlIG9mIHdoaWNoCiAgICAgICAgICogd2lsbCBiZSBzZXQgb25seSBpZiBpdCBpcyBncmVhdGVyIHRoYW4gdGhlIGxhc3Qgc3RvcmVkIGVycm9yIHBvc2l0aW9uLgogICAgICAgICAqIEBwYXJhbSBlcnJQb3MgVGhlIGVycm9yIHBvc2l0aW9uCiAgICAgICAgICovCiAgICAgICAgcHVibGljIHZvaWQgc2V0RXJyb3JFbmRQb3MoaW50IGVyclBvcykgewogICAgICAgICAgICBpZiAoZXJyUG9zID4gZXJyb3JFbmRQb3MpIHsKICAgICAgICAgICAgICAgIGVycm9yRW5kUG9zID0gZXJyUG9zOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgdm9pZCBzZXRQYXJzZXIoSmF2YWNQYXJzZXIgcGFyc2VyKSB7CiAgICAgICAgICAgIHRoaXMucGFyc2VyID0gcGFyc2VyOwogICAgICAgIH0KICAgIH0KfQpQSwMECgAACAAA0n1NSj4QK6A3DQAANw0AAC4AAABjb20vc3VuL3Rvb2xzL2phdmFjL3BhcnNlci9TY2FubmVyRmFjdG9yeS5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAxOTk5LCAyMDEwLCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuamF2YWMucGFyc2VyOwoKaW1wb3J0IGphdmEubmlvLkNoYXJCdWZmZXI7CgppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlNvdXJjZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5Db250ZXh0OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkxvZzsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5OYW1lczsKCgovKioKICogQSBmYWN0b3J5IGZvciBjcmVhdGluZyBzY2FubmVycy4KICoKICogIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqICBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duCiAqICByaXNrLiAgVGhpcyBjb2RlIGFuZCBpdHMgaW50ZXJuYWwgaW50ZXJmYWNlcyBhcmUgc3ViamVjdCB0byBjaGFuZ2UKICogIG9yIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj4KICovCnB1YmxpYyBjbGFzcyBTY2FubmVyRmFjdG9yeSB7CiAgICAvKiogVGhlIGNvbnRleHQga2V5IGZvciB0aGUgc2Nhbm5lciBmYWN0b3J5LiAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBDb250ZXh0LktleTxTY2FubmVyRmFjdG9yeT4gc2Nhbm5lckZhY3RvcnlLZXkgPSBuZXcgQ29udGV4dC5LZXk8PigpOwoKICAgIC8qKiBHZXQgdGhlIEZhY3RvcnkgaW5zdGFuY2UgZm9yIHRoaXMgY29udGV4dC4gKi8KICAgIHB1YmxpYyBzdGF0aWMgU2Nhbm5lckZhY3RvcnkgaW5zdGFuY2UoQ29udGV4dCBjb250ZXh0KSB7CiAgICAgICAgU2Nhbm5lckZhY3RvcnkgaW5zdGFuY2UgPSBjb250ZXh0LmdldChzY2FubmVyRmFjdG9yeUtleSk7CiAgICAgICAgaWYgKGluc3RhbmNlID09IG51bGwpCiAgICAgICAgICAgIGluc3RhbmNlID0gbmV3IFNjYW5uZXJGYWN0b3J5KGNvbnRleHQpOwogICAgICAgIHJldHVybiBpbnN0YW5jZTsKICAgIH0KCiAgICBmaW5hbCBMb2cgbG9nOwogICAgZmluYWwgTmFtZXMgbmFtZXM7CiAgICBmaW5hbCBTb3VyY2Ugc291cmNlOwogICAgZmluYWwgVG9rZW5zIHRva2VuczsKCiAgICAvKiogQ3JlYXRlIGEgbmV3IHNjYW5uZXIgZmFjdG9yeS4gKi8KICAgIHByb3RlY3RlZCBTY2FubmVyRmFjdG9yeShDb250ZXh0IGNvbnRleHQpIHsKICAgICAgICBjb250ZXh0LnB1dChzY2FubmVyRmFjdG9yeUtleSwgdGhpcyk7CiAgICAgICAgdGhpcy5sb2cgPSBMb2cuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgdGhpcy5uYW1lcyA9IE5hbWVzLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIHRoaXMuc291cmNlID0gU291cmNlLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIHRoaXMudG9rZW5zID0gVG9rZW5zLmluc3RhbmNlKGNvbnRleHQpOwogICAgfQoKICAgIHB1YmxpYyBTY2FubmVyIG5ld1NjYW5uZXIoQ2hhclNlcXVlbmNlIGlucHV0LCBib29sZWFuIGtlZXBEb2NDb21tZW50cykgewogICAgICAgIGlmIChpbnB1dCBpbnN0YW5jZW9mIENoYXJCdWZmZXIpIHsKICAgICAgICAgICAgQ2hhckJ1ZmZlciBidWYgPSAoQ2hhckJ1ZmZlcikgaW5wdXQ7CiAgICAgICAgICAgIGlmIChrZWVwRG9jQ29tbWVudHMpCiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFNjYW5uZXIodGhpcywgbmV3IEphdmFkb2NUb2tlbml6ZXIodGhpcywgYnVmKSk7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHJldHVybiBuZXcgU2Nhbm5lcih0aGlzLCBidWYpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGNoYXJbXSBhcnJheSA9IGlucHV0LnRvU3RyaW5nKCkudG9DaGFyQXJyYXkoKTsKICAgICAgICAgICAgcmV0dXJuIG5ld1NjYW5uZXIoYXJyYXksIGFycmF5Lmxlbmd0aCwga2VlcERvY0NvbW1lbnRzKTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIFNjYW5uZXIgbmV3U2Nhbm5lcihjaGFyW10gaW5wdXQsIGludCBpbnB1dExlbmd0aCwgYm9vbGVhbiBrZWVwRG9jQ29tbWVudHMpIHsKICAgICAgICBpZiAoa2VlcERvY0NvbW1lbnRzKQogICAgICAgICAgICByZXR1cm4gbmV3IFNjYW5uZXIodGhpcywgbmV3IEphdmFkb2NUb2tlbml6ZXIodGhpcywgaW5wdXQsIGlucHV0TGVuZ3RoKSk7CiAgICAgICAgZWxzZQogICAgICAgICAgICByZXR1cm4gbmV3IFNjYW5uZXIodGhpcywgaW5wdXQsIGlucHV0TGVuZ3RoKTsKICAgIH0KfQpQSwMECgAACAAABjupSmwmpQsSTQAAEk0AADAAAABjb20vc3VuL3Rvb2xzL2phdmFjL3BhcnNlci9KYXZhZG9jVG9rZW5pemVyLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDQsIDIwMTMsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhYy5wYXJzZXI7CgppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5wYXJzZXIuVG9rZW5zLkNvbW1lbnQ7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnBhcnNlci5Ub2tlbnMuQ29tbWVudC5Db21tZW50U3R5bGU7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuKjsKCmltcG9ydCBqYXZhLm5pby4qOwppbXBvcnQgamF2YS51dGlsLnJlZ2V4LlBhdHRlcm47CgppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5MYXlvdXRDaGFyYWN0ZXJzLio7CgovKiogQW4gZXh0ZW5zaW9uIHRvIHRoZSBiYXNlIGxleGljYWwgYW5hbHl6ZXIgdGhhdCBjYXB0dXJlcwogKiAgYW5kIHByb2Nlc3NlcyB0aGUgY29udGVudHMgb2YgZG9jIGNvbW1lbnRzLiAgSXQgZG9lcyBzbyBieQogKiAgdHJhbnNsYXRpbmcgVW5pY29kZSBlc2NhcGUgc2VxdWVuY2VzIGFuZCBieSBzdHJpcHBpbmcgdGhlCiAqICBsZWFkaW5nIHdoaXRlc3BhY2UgYW5kIHN0YXJ0cyBmcm9tIGVhY2ggbGluZSBvZiB0aGUgY29tbWVudC4KICoKICogIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqICBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqICBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogKiAgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPgogKi8KcHVibGljIGNsYXNzIEphdmFkb2NUb2tlbml6ZXIgZXh0ZW5kcyBKYXZhVG9rZW5pemVyIHsKCiAgICAvKiogQ3JlYXRlIGEgc2Nhbm5lciBmcm9tIHRoZSBpbnB1dCBidWZmZXIuICBidWZmZXIgbXVzdCBpbXBsZW1lbnQKICAgICAqICBhcnJheSgpIGFuZCBjb21wYWN0KCksIGFuZCByZW1haW5pbmcoKSBtdXN0IGJlIGxlc3MgdGhhbiBsaW1pdCgpLgogICAgICovCiAgICBwcm90ZWN0ZWQgSmF2YWRvY1Rva2VuaXplcihTY2FubmVyRmFjdG9yeSBmYWMsIENoYXJCdWZmZXIgYnVmZmVyKSB7CiAgICAgICAgc3VwZXIoZmFjLCBidWZmZXIpOwogICAgfQoKICAgIC8qKiBDcmVhdGUgYSBzY2FubmVyIGZyb20gdGhlIGlucHV0IGFycmF5LiAgVGhlIGFycmF5IG11c3QgaGF2ZSBhdAogICAgICogIGxlYXN0IGEgc2luZ2xlIGNoYXJhY3RlciBvZiBleHRyYSBzcGFjZS4KICAgICAqLwogICAgcHJvdGVjdGVkIEphdmFkb2NUb2tlbml6ZXIoU2Nhbm5lckZhY3RvcnkgZmFjLCBjaGFyW10gaW5wdXQsIGludCBpbnB1dExlbmd0aCkgewogICAgICAgIHN1cGVyKGZhYywgaW5wdXQsIGlucHV0TGVuZ3RoKTsKICAgIH0KCiAgICBAT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBDb21tZW50IHByb2Nlc3NDb21tZW50KGludCBwb3MsIGludCBlbmRQb3MsIENvbW1lbnRTdHlsZSBzdHlsZSkgewogICAgICAgIGNoYXJbXSBidWYgPSByZWFkZXIuZ2V0UmF3Q2hhcmFjdGVycyhwb3MsIGVuZFBvcyk7CiAgICAgICAgcmV0dXJuIG5ldyBKYXZhZG9jQ29tbWVudChuZXcgRG9jUmVhZGVyKGZhYywgYnVmLCBidWYubGVuZ3RoLCBwb3MpLCBzdHlsZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBUaGlzIGlzIGEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBVbmljb2RlUmVhZGVyIHRoYXQga2VlcHMgdHJhY2sgb2YgdGhlCiAgICAgKiBjb2x1bW4gcG9zaXRpb24gd2l0aGluIGEgZ2l2ZW4gY2hhcmFjdGVyIHN0cmVhbSAodXNlZCBmb3IgSmF2YWRvYyBwcm9jZXNzaW5nKSwKICAgICAqIGFuZCB3aGljaCBidWlsZHMgYSB0YWJsZSBmb3IgbWFwcGluZyBwb3NpdGlvbnMgaW4gdGhlIGNvbW1lbnQgc3RyaW5nIHRvCiAgICAgKiBwb3NpdGlvbnMgaW4gdGhlIHNvdXJjZSBmaWxlLgogICAgICovCiAgICBzdGF0aWMgY2xhc3MgRG9jUmVhZGVyIGV4dGVuZHMgVW5pY29kZVJlYWRlciB7CgogICAgICAgICBpbnQgY29sOwogICAgICAgICBpbnQgc3RhcnRQb3M7CgogICAgICAgICAvKioKICAgICAgICAgICogQSBidWZmZXIgZm9yIGJ1aWxkaW5nIGEgdGFibGUgZm9yIG1hcHBpbmcgcG9zaXRpb25zIGluIHtAbGluayAjc2J1Zn0KICAgICAgICAgICogdG8gcG9zaXRpb25zIGluIHRoZSBzb3VyY2UgYnVmZmVyLgogICAgICAgICAgKgogICAgICAgICAgKiBUaGUgYXJyYXkgaXMgb3JnYW5pemVkIGFzIGEgc2VyaWVzIG9mIHBhaXJzIG9mIGludGVnZXJzOiB0aGUgZmlyc3QKICAgICAgICAgICogbnVtYmVyIGluIGVhY2ggcGFpciBzcGVjaWZpZXMgYSBwb3NpdGlvbiBpbiB0aGUgY29tbWVudCB0ZXh0LAogICAgICAgICAgKiB0aGUgc2Vjb25kIG51bWJlciBpbiBlYWNoIHBhaXIgc3BlY2lmaWVzIHRoZSBjb3JyZXNwb25kaW5nIHBvc2l0aW9uCiAgICAgICAgICAqIGluIHRoZSBzb3VyY2UgYnVmZmVyLiBUaGUgcGFpcnMgYXJlIHNvcnRlZCBpbiBhc2NlbmRpbmcgb3JkZXIuCiAgICAgICAgICAqCiAgICAgICAgICAqIFNpbmNlIHRoZSBtYXBwaW5nIGZ1bmN0aW9uIGlzIGdlbmVyYWxseSBjb250aW51b3VzLCB3aXRoIHN1Y2Nlc3NpdmUKICAgICAgICAgICogcG9zaXRpb25zIGluIHRoZSBzdHJpbmcgY29ycmVzcG9uZGluZyB0byBzdWNjZXNzaXZlIHBvc2l0aW9ucyBpbiB0aGUKICAgICAgICAgICogc291cmNlIGJ1ZmZlciwgdGhlIHRhYmxlIG9ubHkgbmVlZHMgdG8gcmVjb3JkIGRpc2NvbnRpbnVpdGllcyBpbgogICAgICAgICAgKiB0aGUgbWFwcGluZy4gVGhlIHZhbHVlcyBvZiBpbnRlcm1lZGlhdGUgcG9zaXRpb25zIGNhbiBiZSBpbmZlcnJlZC4KICAgICAgICAgICoKICAgICAgICAgICogRGlzY29udGludWl0aWVzIG1heSBvY2N1ciBpbiBhIG51bWJlciBvZiBwbGFjZXM6IHdoZW4gYSBuZXdsaW5lCiAgICAgICAgICAqIGlzIGZvbGxvd2VkIGJ5IHdoaXRlc3BhY2UgYW5kIGFzdGVyaXNrcyAod2hpY2ggYXJlIGlnbm9yZWQpLAogICAgICAgICAgKiB3aGVuIGEgdGFiIGlzIGV4cGFuZGVkIGludG8gc3BhY2VzLCBhbmQgd2hlbiB1bmljb2RlIGVzY2FwZXMKICAgICAgICAgICogYXJlIHVzZWQgaW4gdGhlIHNvdXJjZSBidWZmZXIuCiAgICAgICAgICAqCiAgICAgICAgICAqIFRodXMsIHRvIGZpbmQgdGhlIHNvdXJjZSBwb3NpdGlvbiBvZiBhbnkgcG9zaXRpb24sIHAsIGluIHRoZSBjb21tZW50CiAgICAgICAgICAqIHN0cmluZywgZmluZCB0aGUgaW5kZXgsIGksIG9mIHRoZSBwYWlyIHdob3NlIHN0cmluZyBvZmZzZXQKICAgICAgICAgICogKHtAY29kZSBwYnVmW2ldIH0pIGlzIGNsb3Nlc3QgdG8gYnV0IG5vdCBncmVhdGVyIHRoYW4gcC4gVGhlbiwKICAgICAgICAgICoge0Bjb2RlIHNvdXJjZVBvcyhwKSA9IHBidWZbaSsxXSArIChwIC0gcGJ1ZltpXSkgfS4KICAgICAgICAgICovCiAgICAgICAgIGludFtdIHBidWYgPSBuZXcgaW50WzEyOF07CgogICAgICAgICAvKioKICAgICAgICAgICogVGhlIGluZGV4IG9mIHRoZSBuZXh0IGVtcHR5IHNsb3QgaW4gdGhlIHBidWYgYnVmZmVyLgogICAgICAgICAgKi8KICAgICAgICAgaW50IHBwID0gMDsKCiAgICAgICAgIC8qKiBUaGUgYnVmZmVyIGluZGV4IG9mIHRoZSBsYXN0IGRvdWJsZSBiYWNrc2xhc2ggc2VxdWVuY2UKICAgICAgICAgICovCiAgICAgICAgIHByaXZhdGUgaW50IGRvdWJsZUJhY2tzbGFzaEJwID0gLTE7CgogICAgICAgICBEb2NSZWFkZXIoU2Nhbm5lckZhY3RvcnkgZmFjLCBjaGFyW10gaW5wdXQsIGludCBpbnB1dExlbmd0aCwgaW50IHN0YXJ0UG9zKSB7CiAgICAgICAgICAgICBzdXBlcihmYWMsIGlucHV0LCBpbnB1dExlbmd0aCk7CiAgICAgICAgICAgICB0aGlzLnN0YXJ0UG9zID0gc3RhcnRQb3M7CiAgICAgICAgIH0KCiAgICAgICAgIEBPdmVycmlkZQogICAgICAgICBwcm90ZWN0ZWQgdm9pZCBjb252ZXJ0VW5pY29kZSgpIHsKICAgICAgICAgICAgIGlmIChjaCA9PSAnXFwnICYmIHVuaWNvZGVDb252ZXJzaW9uQnAgIT0gYnApIHsKICAgICAgICAgICAgICAgICBicCsrOyBjaCA9IGJ1ZlticF07IGNvbCsrOwogICAgICAgICAgICAgICAgIGlmIChjaCA9PSAndScpIHsKICAgICAgICAgICAgICAgICAgICAgZG8gewogICAgICAgICAgICAgICAgICAgICAgICAgYnArKzsgY2ggPSBidWZbYnBdOyBjb2wrKzsKICAgICAgICAgICAgICAgICAgICAgfSB3aGlsZSAoY2ggPT0gJ3UnKTsKICAgICAgICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gYnAgKyAzOwogICAgICAgICAgICAgICAgICAgICBpZiAobGltaXQgPCBidWZsZW4pIHsKICAgICAgICAgICAgICAgICAgICAgICAgIGludCBkID0gZGlnaXQoYnAsIDE2KTsKICAgICAgICAgICAgICAgICAgICAgICAgIGludCBjb2RlID0gZDsKICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChicCA8IGxpbWl0ICYmIGQgPj0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJwKys7IGNoID0gYnVmW2JwXTsgY29sKys7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZCA9IGRpZ2l0KGJwLCAxNik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29kZSA9IChjb2RlIDw8IDQpICsgZDsKICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkID49IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaCA9IChjaGFyKWNvZGU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5pY29kZUNvbnZlcnNpb25CcCA9IGJwOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAvLyAiaWxsZWdhbC5Vbmljb2RlLmVzYyIsIHJlcG9ydGVkIGJ5IGJhc2Ugc2Nhbm5lcgogICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgIGJwLS07CiAgICAgICAgICAgICAgICAgICAgIGNoID0gJ1xcJzsKICAgICAgICAgICAgICAgICAgICAgY29sLS07CiAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgfQogICAgICAgICB9CgogICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgcHJvdGVjdGVkIHZvaWQgc2NhbkNvbW1lbnRDaGFyKCkgewogICAgICAgICAgICAgc2NhbkNoYXIoKTsKICAgICAgICAgICAgIGlmIChjaCA9PSAnXFwnKSB7CiAgICAgICAgICAgICAgICAgaWYgKHBlZWtDaGFyKCkgPT0gJ1xcJyAmJiAhaXNVbmljb2RlKCkpIHsKICAgICAgICAgICAgICAgICAgICAgYnArKzsgY29sKys7CiAgICAgICAgICAgICAgICAgICAgIGRvdWJsZUJhY2tzbGFzaEJwID0gYnA7CiAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgY29udmVydFVuaWNvZGUoKTsKICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICB9CiAgICAgICAgIH0KCiAgICAgICAgIEBPdmVycmlkZQogICAgICAgICBwcm90ZWN0ZWQgdm9pZCBzY2FuQ2hhcigpIHsKICAgICAgICAgICAgIGJwKys7CiAgICAgICAgICAgICBjaCA9IGJ1ZlticF07CiAgICAgICAgICAgICBzd2l0Y2ggKGNoKSB7CiAgICAgICAgICAgICBjYXNlICdccic6IC8vIHJldHVybgogICAgICAgICAgICAgICAgIGNvbCA9IDA7CiAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICBjYXNlICdcbic6IC8vIG5ld2xpbmUKICAgICAgICAgICAgICAgICBpZiAoYnAgPT0gMCB8fCBidWZbYnAtMV0gIT0gJ1xyJykgewogICAgICAgICAgICAgICAgICAgICBjb2wgPSAwOwogICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgIGNhc2UgJ1x0JzogLy8gdGFiCiAgICAgICAgICAgICAgICAgY29sID0gKGNvbCAvIFRhYkluYyAqIFRhYkluYykgKyBUYWJJbmM7CiAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICBjYXNlICdcXCc6IC8vIHBvc3NpYmxlIFVuaWNvZGUKICAgICAgICAgICAgICAgICBjb2wrKzsKICAgICAgICAgICAgICAgICBjb252ZXJ0VW5pY29kZSgpOwogICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICBjb2wrKzsKICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgIH0KICAgICAgICAgfQoKICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgIHB1YmxpYyB2b2lkIHB1dENoYXIoY2hhciBjaCwgYm9vbGVhbiBzY2FuKSB7CiAgICAgICAgICAgICAvLyBBdCB0aGlzIHBvaW50LCBicCBpcyB0aGUgcG9zaXRpb24gb2YgdGhlIGN1cnJlbnQgY2hhcmFjdGVyIGluIGJ1ZiwKICAgICAgICAgICAgIC8vIGFuZCBzcCBpcyB0aGUgcG9zaXRpb24gaW4gc2J1ZiB3aGVyZSB0aGlzIGNoYXJhY3RlciB3aWxsIGJlIHB1dC4KICAgICAgICAgICAgIC8vIFJlY29yZCBhIG5ldyBlbnRyeSBpbiBwYnVmIGlmIHBidWYgaXMgZW1wdHkgb3IgaWYgc3AgYW5kIGl0cwogICAgICAgICAgICAgLy8gY29ycmVzcG9uZGluZyBzb3VyY2UgcG9zaXRpb24gYXJlIG5vdCBlcXVpZGlzdGFudCBmcm9tIHRoZQogICAgICAgICAgICAgLy8gY29ycmVzcG9uZGluZyB2YWx1ZXMgaW4gdGhlIGxhdGVzdCBlbnRyeSBpbiB0aGUgcGJ1ZiBhcnJheS4KICAgICAgICAgICAgIC8vIChpLmUuIHRoZXJlIGlzIGEgZGlzY29udGludWl0eSBpbiB0aGUgbWFwIGZ1bmN0aW9uLikKICAgICAgICAgICAgIGlmICgocHAgPT0gMCkKICAgICAgICAgICAgICAgICAgICAgfHwgKHNwIC0gcGJ1ZltwcCAtIDJdICE9IChzdGFydFBvcyArIGJwKSAtIHBidWZbcHAgLSAxXSkpIHsKICAgICAgICAgICAgICAgICBpZiAocHAgKyAxID49IHBidWYubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICAgICAgIGludFtdIG5ld19wYnVmID0gbmV3IGludFtwYnVmLmxlbmd0aCAqIDJdOwogICAgICAgICAgICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHBidWYsIDAsIG5ld19wYnVmLCAwLCBwYnVmLmxlbmd0aCk7CiAgICAgICAgICAgICAgICAgICAgIHBidWYgPSBuZXdfcGJ1ZjsKICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgcGJ1ZltwcF0gPSBzcDsKICAgICAgICAgICAgICAgICBwYnVmW3BwICsgMV0gPSBzdGFydFBvcyArIGJwOwogICAgICAgICAgICAgICAgIHBwICs9IDI7CiAgICAgICAgICAgICB9CiAgICAgICAgICAgICBzdXBlci5wdXRDaGFyKGNoLCBzY2FuKTsKICAgICAgICAgfQoKICAgICAgICAgLyoqIFdoZXRoZXIgdGhlIGNoIHJlcHJlc2VudHMgYSBzZXF1ZW5jZSBvZiB0d28gYmFja3NsYXNoZXMuICovCiAgICAgICAgIGJvb2xlYW4gaXNEb3VibGVCYWNrc2xhc2goKSB7CiAgICAgICAgICAgICByZXR1cm4gZG91YmxlQmFja3NsYXNoQnAgPT0gYnA7CiAgICAgICAgIH0KCgogICAgIH0KCiAgICAgcHJvdGVjdGVkIHN0YXRpYyBjbGFzcyBKYXZhZG9jQ29tbWVudCBleHRlbmRzIEphdmFUb2tlbml6ZXIuQmFzaWNDb21tZW50PERvY1JlYWRlcj4gewoKICAgICAgICAvKioKICAgICAgICAqIFRyYW5zbGF0ZWQgYW5kIHN0cmlwcGVkIGNvbnRlbnRzIG9mIGRvYyBjb21tZW50CiAgICAgICAgKi8KICAgICAgICBwcml2YXRlIFN0cmluZyBkb2NDb21tZW50ID0gbnVsbDsKICAgICAgICBwcml2YXRlIGludFtdIGRvY1Bvc25zID0gbnVsbDsKCiAgICAgICAgSmF2YWRvY0NvbW1lbnQoRG9jUmVhZGVyIHJlYWRlciwgQ29tbWVudFN0eWxlIGNzKSB7CiAgICAgICAgICAgIHN1cGVyKHJlYWRlciwgY3MpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFN0cmluZyBnZXRUZXh0KCkgewogICAgICAgICAgICBpZiAoIXNjYW5uZWQgJiYgY3MgPT0gQ29tbWVudFN0eWxlLkpBVkFET0MpIHsKICAgICAgICAgICAgICAgIHNjYW5Eb2NDb21tZW50KCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGRvY0NvbW1lbnQ7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgaW50IGdldFNvdXJjZVBvcyhpbnQgcG9zKSB7CiAgICAgICAgICAgIC8vIEJpbmFyeSBzZWFyY2ggdG8gZmluZCB0aGUgZW50cnkgZm9yIHdoaWNoIHRoZSBzdHJpbmcgaW5kZXggaXMKICAgICAgICAgICAgLy8gbGVzcyB0aGFuIHBvcy4gU2luY2UgZG9jUG9zbnMgaXMgYSBsaXN0IG9mIHBhaXJzIG9mIGludGVnZXJzCiAgICAgICAgICAgIC8vIHdlIG11c3QgbWFrZSBzdXJlIHRoZSBpbmRleCBpcyBhbHdheXMgZXZlbi4KICAgICAgICAgICAgLy8gSWYgd2UgZmluZCBhbiBleGFjdCBtYXRjaCBmb3IgcG9zLCB0aGUgb3RoZXIgaXRlbSBpbiB0aGUgcGFpcgogICAgICAgICAgICAvLyBnaXZlcyB0aGUgc291cmNlIHBvczsgb3RoZXJ3aXNlLCBjb21wdXRlIHRoZSBzb3VyY2UgcG9zaXRpb24KICAgICAgICAgICAgLy8gcmVsYXRpdmUgdG8gdGhlIGJlc3QgbWF0Y2ggZm91bmQgaW4gdGhlIGFycmF5LgogICAgICAgICAgICBpZiAocG9zID09IFBvc2l0aW9uLk5PUE9TKQogICAgICAgICAgICAgICAgcmV0dXJuIFBvc2l0aW9uLk5PUE9TOwogICAgICAgICAgICBpZiAocG9zIDwgMCB8fCBwb3MgPiBkb2NDb21tZW50Lmxlbmd0aCgpKQogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oU3RyaW5nLnZhbHVlT2YocG9zKSk7CiAgICAgICAgICAgIGlmIChkb2NQb3NucyA9PSBudWxsKQogICAgICAgICAgICAgICAgcmV0dXJuIFBvc2l0aW9uLk5PUE9TOwogICAgICAgICAgICBpbnQgc3RhcnQgPSAwOwogICAgICAgICAgICBpbnQgZW5kID0gZG9jUG9zbnMubGVuZ3RoOwogICAgICAgICAgICB3aGlsZSAoc3RhcnQgPCBlbmQgLSAyKSB7CiAgICAgICAgICAgICAgICAvLyBmaW5kIGFuIGV2ZW4gaW5kZXggbWlkd2F5IGJldHdlZW4gc3RhcnQgYW5kIGVuZAogICAgICAgICAgICAgICAgaW50IGluZGV4ID0gKChzdGFydCAgKyBlbmQpIC8gNCkgKiAyOwogICAgICAgICAgICAgICAgaWYgKGRvY1Bvc25zW2luZGV4XSA8IHBvcykKICAgICAgICAgICAgICAgICAgICBzdGFydCA9IGluZGV4OwogICAgICAgICAgICAgICAgZWxzZSBpZiAoZG9jUG9zbnNbaW5kZXhdID09IHBvcykKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZG9jUG9zbnNbaW5kZXggKyAxXTsKICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICBlbmQgPSBpbmRleDsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gZG9jUG9zbnNbc3RhcnQgKyAxXSArIChwb3MgLSBkb2NQb3Nuc1tzdGFydF0pOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoImZhbGx0aHJvdWdoIikKICAgICAgICBwcm90ZWN0ZWQgdm9pZCBzY2FuRG9jQ29tbWVudCgpIHsKICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgYm9vbGVhbiBmaXJzdExpbmUgPSB0cnVlOwoKICAgICAgICAgICAgICAgICAvLyBTa2lwIG92ZXIgZmlyc3Qgc2xhc2gKICAgICAgICAgICAgICAgICBjb21tZW50X3JlYWRlci5zY2FuQ29tbWVudENoYXIoKTsKICAgICAgICAgICAgICAgICAvLyBTa2lwIG92ZXIgZmlyc3Qgc3RhcgogICAgICAgICAgICAgICAgIGNvbW1lbnRfcmVhZGVyLnNjYW5Db21tZW50Q2hhcigpOwoKICAgICAgICAgICAgICAgICAvLyBjb25zdW1lIGFueSBudW1iZXIgb2Ygc3RhcnMKICAgICAgICAgICAgICAgICB3aGlsZSAoY29tbWVudF9yZWFkZXIuYnAgPCBjb21tZW50X3JlYWRlci5idWZsZW4gJiYgY29tbWVudF9yZWFkZXIuY2ggPT0gJyonKSB7CiAgICAgICAgICAgICAgICAgICAgIGNvbW1lbnRfcmVhZGVyLnNjYW5Db21tZW50Q2hhcigpOwogICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAvLyBpcyB0aGUgY29tbWVudCBpbiB0aGUgZm9ybSAvKiovLCAvKioqLywgLyoqKiovLCBldGMuID8KICAgICAgICAgICAgICAgICBpZiAoY29tbWVudF9yZWFkZXIuYnAgPCBjb21tZW50X3JlYWRlci5idWZsZW4gJiYgY29tbWVudF9yZWFkZXIuY2ggPT0gJy8nKSB7CiAgICAgICAgICAgICAgICAgICAgIGRvY0NvbW1lbnQgPSAiIjsKICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgLy8gc2tpcCBhIG5ld2xpbmUgb24gdGhlIGZpcnN0IGxpbmUgb2YgdGhlIGNvbW1lbnQuCiAgICAgICAgICAgICAgICAgaWYgKGNvbW1lbnRfcmVhZGVyLmJwIDwgY29tbWVudF9yZWFkZXIuYnVmbGVuKSB7CiAgICAgICAgICAgICAgICAgICAgIGlmIChjb21tZW50X3JlYWRlci5jaCA9PSBMRikgewogICAgICAgICAgICAgICAgICAgICAgICAgY29tbWVudF9yZWFkZXIuc2NhbkNvbW1lbnRDaGFyKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICBmaXJzdExpbmUgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjb21tZW50X3JlYWRlci5jaCA9PSBDUikgewogICAgICAgICAgICAgICAgICAgICAgICAgY29tbWVudF9yZWFkZXIuc2NhbkNvbW1lbnRDaGFyKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY29tbWVudF9yZWFkZXIuY2ggPT0gTEYpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21tZW50X3JlYWRlci5zY2FuQ29tbWVudENoYXIoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaXJzdExpbmUgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICBvdXRlckxvb3A6CgogICAgICAgICAgICAgICAgIC8vIFRoZSBvdXRlckxvb3AgcHJvY2Vzc2VzIHRoZSBkb2MgY29tbWVudCwgbG9vcGluZyBvbmNlCiAgICAgICAgICAgICAgICAgLy8gZm9yIGVhY2ggbGluZS4gIEZvciBlYWNoIGxpbmUsIGl0IGZpcnN0IHN0cmlwcyBvZmYKICAgICAgICAgICAgICAgICAvLyB3aGl0ZXNwYWNlLCB0aGVuIGl0IGNvbnN1bWVzIGFueSBzdGFycywgdGhlbiBpdAogICAgICAgICAgICAgICAgIC8vIHB1dHMgdGhlIHJlc3Qgb2YgdGhlIGxpbmUgaW50byBvdXIgYnVmZmVyLgogICAgICAgICAgICAgICAgIHdoaWxlIChjb21tZW50X3JlYWRlci5icCA8IGNvbW1lbnRfcmVhZGVyLmJ1ZmxlbikgewogICAgICAgICAgICAgICAgICAgICBpbnQgYmVnaW5fYnAgPSBjb21tZW50X3JlYWRlci5icDsKICAgICAgICAgICAgICAgICAgICAgY2hhciBiZWdpbl9jaCA9IGNvbW1lbnRfcmVhZGVyLmNoOwogICAgICAgICAgICAgICAgICAgICAvLyBUaGUgd3NMb29wIGNvbnN1bWVzIHdoaXRlc3BhY2UgZnJvbSB0aGUgYmVnaW5uaW5nCiAgICAgICAgICAgICAgICAgICAgIC8vIG9mIGVhY2ggbGluZS4KICAgICAgICAgICAgICAgICB3c0xvb3A6CgogICAgICAgICAgICAgICAgICAgICB3aGlsZSAoY29tbWVudF9yZWFkZXIuYnAgPCBjb21tZW50X3JlYWRlci5idWZsZW4pIHsKICAgICAgICAgICAgICAgICAgICAgICAgIHN3aXRjaChjb21tZW50X3JlYWRlci5jaCkgewogICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnICc6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tbWVudF9yZWFkZXIuc2NhbkNvbW1lbnRDaGFyKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdcdCc6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tbWVudF9yZWFkZXIuY29sID0gKChjb21tZW50X3JlYWRlci5jb2wgLSAxKSAvIFRhYkluYyAqIFRhYkluYykgKyBUYWJJbmM7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tbWVudF9yZWFkZXIuc2NhbkNvbW1lbnRDaGFyKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIEZGOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbW1lbnRfcmVhZGVyLmNvbCA9IDA7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tbWVudF9yZWFkZXIuc2NhbkNvbW1lbnRDaGFyKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgIC8vIFRyZWF0IG5ld2xpbmUgYXQgYmVnaW5uaW5nIG9mIGxpbmUgKGJsYW5rIGxpbmUsIG5vIHN0YXIpCiAgICAgICAgIC8vIGFzIGNvbW1lbnQgdGV4dC4gIE9sZCBKYXZhZG9jIGNvbXBhdGliaWxpdHkgcmVxdWlyZXMgdGhpcy4KICAgICAgICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qCiAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIENSOiAvLyAoU3BlYyAzLjQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9jX3JlYWRlci5zY2FuQ29tbWVudENoYXIoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY2ggPT0gTEYpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sID0gMDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9jX3JlYWRlci5zY2FuQ29tbWVudENoYXIoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIExGOiAvLyAoU3BlYyAzLjQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9jX3JlYWRlci5zY2FuQ29tbWVudENoYXIoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCiAgICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHdlJ3ZlIHNlZW4gc29tZXRoaW5nIHRoYXQgaXNuJ3Qgd2hpdGVzcGFjZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBqdW1wIG91dC4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhayB3c0xvb3A7CiAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgIC8vIEFyZSB0aGVyZSBzdGFycyBoZXJlPyAgSWYgc28sIGNvbnN1bWUgdGhlbSBhbGwKICAgICAgICAgICAgICAgICAgICAgLy8gYW5kIGNoZWNrIGZvciB0aGUgZW5kIG9mIGNvbW1lbnQuCiAgICAgICAgICAgICAgICAgICAgIGlmIChjb21tZW50X3JlYWRlci5jaCA9PSAnKicpIHsKICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNraXAgYWxsIG9mIHRoZSBzdGFycwogICAgICAgICAgICAgICAgICAgICAgICAgZG8gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbW1lbnRfcmVhZGVyLnNjYW5Db21tZW50Q2hhcigpOwogICAgICAgICAgICAgICAgICAgICAgICAgfSB3aGlsZSAoY29tbWVudF9yZWFkZXIuY2ggPT0gJyonKTsKCiAgICAgICAgICAgICAgICAgICAgICAgICAvLyBjaGVjayBmb3IgdGhlIGNsb3Npbmcgc2xhc2guCiAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY29tbWVudF9yZWFkZXIuY2ggPT0gJy8nKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gV2UncmUgZG9uZSB3aXRoIHRoZSBkb2MgY29tbWVudAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNjYW5DaGFyKCkgYW5kIGJyZWFrb3V0LgogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrIG91dGVyTG9vcDsKICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICghIGZpcnN0TGluZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgLy8gVGhlIGN1cnJlbnQgbGluZSBkb2VzIG5vdCBiZWdpbiB3aXRoIGEgJyonIHNvIHdlIHdpbGwKICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRyZWF0IGl0IGFzIGNvbW1lbnQKICAgICAgICAgICAgICAgICAgICAgICAgIGNvbW1lbnRfcmVhZGVyLmJwID0gYmVnaW5fYnA7CiAgICAgICAgICAgICAgICAgICAgICAgICBjb21tZW50X3JlYWRlci5jaCA9IGJlZ2luX2NoOwogICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgIC8vIFRoZSB0ZXh0TG9vcCBwcm9jZXNzZXMgdGhlIHJlc3Qgb2YgdGhlIGNoYXJhY3RlcnMKICAgICAgICAgICAgICAgICAgICAgLy8gb24gdGhlIGxpbmUsIGFkZGluZyB0aGVtIHRvIG91ciBidWZmZXIuCiAgICAgICAgICAgICAgICAgdGV4dExvb3A6CiAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChjb21tZW50X3JlYWRlci5icCA8IGNvbW1lbnRfcmVhZGVyLmJ1ZmxlbikgewogICAgICAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChjb21tZW50X3JlYWRlci5jaCkgewogICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnKic6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSXMgdGhpcyBqdXN0IGEgc3Rhcj8gIE9yIGlzIHRoaXMgdGhlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZW5kIG9mIGEgY29tbWVudD8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21tZW50X3JlYWRlci5zY2FuQ29tbWVudENoYXIoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY29tbWVudF9yZWFkZXIuY2ggPT0gJy8nKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoaXMgaXMgdGhlIGVuZCBvZiB0aGUgY29tbWVudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc2V0IGNoIGFuZCByZXR1cm4gb3VyIGJ1ZmZlci4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWsgb3V0ZXJMb29wOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBUaGlzIGlzIGp1c3QgYW4gb3JkaW5hcnkgc3Rhci4gIEFkZCBpdCB0bwogICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRoZSBidWZmZXIuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tbWVudF9yZWFkZXIucHV0Q2hhcignKicsIGZhbHNlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ1xcJzoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21tZW50X3JlYWRlci5wdXRDaGFyKCdcXCcsIGZhbHNlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBJZiBhIGRvdWJsZSBiYWNrc2xhc2ggd2FzIGZvdW5kLCB3cml0ZSB0d28KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY29tbWVudF9yZWFkZXIuaXNEb3VibGVCYWNrc2xhc2goKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21tZW50X3JlYWRlci5wdXRDaGFyKCdcXCcsIGZhbHNlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tbWVudF9yZWFkZXIuc2NhbkNvbW1lbnRDaGFyKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlICcgJzoKICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ1x0JzoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21tZW50X3JlYWRlci5wdXRDaGFyKGNvbW1lbnRfcmVhZGVyLmNoLCBmYWxzZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tbWVudF9yZWFkZXIuc2NhbkNvbW1lbnRDaGFyKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIEZGOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbW1lbnRfcmVhZGVyLnNjYW5Db21tZW50Q2hhcigpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrIHRleHRMb29wOyAvLyB0cmVhdCBhcyBlbmQgb2YgbGluZQogICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBDUjogLy8gKFNwZWMgMy40KQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbW1lbnRfcmVhZGVyLnNjYW5Db21tZW50Q2hhcigpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb21tZW50X3JlYWRlci5jaCAhPSBMRikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBDYW5vbmljYWxpemUgQ1Itb25seSBsaW5lIHRlcm1pbmF0b3IgdG8gTEYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tbWVudF9yZWFkZXIucHV0Q2hhcigoY2hhcilMRiwgZmFsc2UpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhayB0ZXh0TG9vcDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogZmFsbCB0aHJvdWdoIHRvIExGIGNhc2UgKi8KICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgTEY6IC8vIChTcGVjIDMuNCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBXZSd2ZSBzZWVuIGEgbmV3bGluZS4gIEFkZCBpdCB0byBvdXIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBidWZmZXIgYW5kIGJyZWFrIG91dCBvZiB0aGlzIGxvb3AsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc3RhcnRpbmcgZnJlc2ggb24gYSBuZXcgbGluZS4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21tZW50X3JlYWRlci5wdXRDaGFyKGNvbW1lbnRfcmVhZGVyLmNoLCBmYWxzZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tbWVudF9yZWFkZXIuc2NhbkNvbW1lbnRDaGFyKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWsgdGV4dExvb3A7CiAgICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEFkZCB0aGUgY2hhcmFjdGVyIHRvIG91ciBidWZmZXIuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tbWVudF9yZWFkZXIucHV0Q2hhcihjb21tZW50X3JlYWRlci5jaCwgZmFsc2UpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbW1lbnRfcmVhZGVyLnNjYW5Db21tZW50Q2hhcigpOwogICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICB9IC8vIGVuZCB0ZXh0TG9vcAogICAgICAgICAgICAgICAgICAgICBmaXJzdExpbmUgPSBmYWxzZTsKICAgICAgICAgICAgICAgICB9IC8vIGVuZCBvdXRlckxvb3AKCiAgICAgICAgICAgICAgICAgaWYgKGNvbW1lbnRfcmVhZGVyLnNwID4gMCkgewogICAgICAgICAgICAgICAgICAgICBpbnQgaSA9IGNvbW1lbnRfcmVhZGVyLnNwIC0gMTsKICAgICAgICAgICAgICAgICB0cmFpbExvb3A6CiAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChpID4gLTEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgIHN3aXRjaCAoY29tbWVudF9yZWFkZXIuc2J1ZltpXSkgewogICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnKic6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaS0tOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhayB0cmFpbExvb3A7CiAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgY29tbWVudF9yZWFkZXIuc3AgPSBpICsgMTsKCiAgICAgICAgICAgICAgICAgICAgIC8vIFN0b3JlIHRoZSB0ZXh0IG9mIHRoZSBkb2MgY29tbWVudAogICAgICAgICAgICAgICAgICAgIGRvY0NvbW1lbnQgPSBjb21tZW50X3JlYWRlci5jaGFycygpOwogICAgICAgICAgICAgICAgICAgIGRvY1Bvc25zID0gbmV3IGludFtjb21tZW50X3JlYWRlci5wcF07CiAgICAgICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShjb21tZW50X3JlYWRlci5wYnVmLCAwLCBkb2NQb3NucywgMCwgZG9jUG9zbnMubGVuZ3RoKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgZG9jQ29tbWVudCA9ICIiOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAgICAgc2Nhbm5lZCA9IHRydWU7CiAgICAgICAgICAgICAgICBjb21tZW50X3JlYWRlciA9IG51bGw7CiAgICAgICAgICAgICAgICBpZiAoZG9jQ29tbWVudCAhPSBudWxsICYmCiAgICAgICAgICAgICAgICAgICAgICAgIERFUFJFQ0FURURfUEFUVEVSTi5tYXRjaGVyKGRvY0NvbW1lbnQpLm1hdGNoZXMoKSkgewogICAgICAgICAgICAgICAgICAgIGRlcHJlY2F0ZWRGbGFnID0gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvL3doZXJlOgogICAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBQYXR0ZXJuIERFUFJFQ0FURURfUEFUVEVSTiA9CiAgICAgICAgICAgICAgICAgICAgUGF0dGVybi5jb21waWxlKCIoP3NtKS4qXlxccypAZGVwcmVjYXRlZCggfCQpLioiKTsKCiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgUG9zaXRpb24uTGluZU1hcCBnZXRMaW5lTWFwKCkgewogICAgICAgIGNoYXJbXSBidWYgPSByZWFkZXIuZ2V0UmF3Q2hhcmFjdGVycygpOwogICAgICAgIHJldHVybiBQb3NpdGlvbi5tYWtlTGluZU1hcChidWYsIGJ1Zi5sZW5ndGgsIHRydWUpOwogICAgfQp9ClBLAwQKAAAIAAAGO6lKo/LgrxkOAAAZDgAALQAAAGNvbS9zdW4vdG9vbHMvamF2YWMvcGFyc2VyL1BhcnNlckZhY3RvcnkuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMTk5OSwgMjAxMiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLmphdmFjLnBhcnNlcjsKCmltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOwoKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5Tb3VyY2U7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuRG9jVHJlZU1ha2VyOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLlRyZWVNYWtlcjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5Db250ZXh0OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkxvZzsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5OYW1lczsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5PcHRpb25zOwoKLyoqCiAqIEEgZmFjdG9yeSBmb3IgY3JlYXRpbmcgcGFyc2Vycy4KICoKICogPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93biByaXNrLgogKiBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogKiBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+CiAqLwpwdWJsaWMgY2xhc3MgUGFyc2VyRmFjdG9yeSB7CgogICAgLyoqIFRoZSBjb250ZXh0IGtleSBmb3IgdGhlIHBhcnNlciBmYWN0b3J5LiAqLwogICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBDb250ZXh0LktleTxQYXJzZXJGYWN0b3J5PiBwYXJzZXJGYWN0b3J5S2V5ID0gbmV3IENvbnRleHQuS2V5PD4oKTsKCiAgICBwdWJsaWMgc3RhdGljIFBhcnNlckZhY3RvcnkgaW5zdGFuY2UoQ29udGV4dCBjb250ZXh0KSB7CiAgICAgICAgUGFyc2VyRmFjdG9yeSBpbnN0YW5jZSA9IGNvbnRleHQuZ2V0KHBhcnNlckZhY3RvcnlLZXkpOwogICAgICAgIGlmIChpbnN0YW5jZSA9PSBudWxsKSB7CiAgICAgICAgICAgIGluc3RhbmNlID0gbmV3IFBhcnNlckZhY3RvcnkoY29udGV4dCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBpbnN0YW5jZTsKICAgIH0KCiAgICBmaW5hbCBUcmVlTWFrZXIgRjsKICAgIGZpbmFsIERvY1RyZWVNYWtlciBkb2NUcmVlTWFrZXI7CiAgICBmaW5hbCBMb2cgbG9nOwogICAgZmluYWwgVG9rZW5zIHRva2VuczsKICAgIGZpbmFsIFNvdXJjZSBzb3VyY2U7CiAgICBmaW5hbCBOYW1lcyBuYW1lczsKICAgIGZpbmFsIE9wdGlvbnMgb3B0aW9uczsKICAgIGZpbmFsIFNjYW5uZXJGYWN0b3J5IHNjYW5uZXJGYWN0b3J5OwogICAgZmluYWwgTG9jYWxlIGxvY2FsZTsKCiAgICBwcm90ZWN0ZWQgUGFyc2VyRmFjdG9yeShDb250ZXh0IGNvbnRleHQpIHsKICAgICAgICBzdXBlcigpOwogICAgICAgIGNvbnRleHQucHV0KHBhcnNlckZhY3RvcnlLZXksIHRoaXMpOwogICAgICAgIHRoaXMuRiA9IFRyZWVNYWtlci5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICB0aGlzLmRvY1RyZWVNYWtlciA9IERvY1RyZWVNYWtlci5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICB0aGlzLmxvZyA9IExvZy5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICB0aGlzLm5hbWVzID0gTmFtZXMuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgdGhpcy50b2tlbnMgPSBUb2tlbnMuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgdGhpcy5zb3VyY2UgPSBTb3VyY2UuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgdGhpcy5vcHRpb25zID0gT3B0aW9ucy5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICB0aGlzLnNjYW5uZXJGYWN0b3J5ID0gU2Nhbm5lckZhY3RvcnkuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgdGhpcy5sb2NhbGUgPSBjb250ZXh0LmdldChMb2NhbGUuY2xhc3MpOwogICAgfQoKICAgIHB1YmxpYyBKYXZhY1BhcnNlciBuZXdQYXJzZXIoQ2hhclNlcXVlbmNlIGlucHV0LCBib29sZWFuIGtlZXBEb2NDb21tZW50cywgYm9vbGVhbiBrZWVwRW5kUG9zLCBib29sZWFuIGtlZXBMaW5lTWFwKSB7CiAgICAgICAgcmV0dXJuIG5ld1BhcnNlcihpbnB1dCwga2VlcERvY0NvbW1lbnRzLCBrZWVwRW5kUG9zLCBrZWVwTGluZU1hcCwgZmFsc2UpOwogICAgfQoKICAgIHB1YmxpYyBKYXZhY1BhcnNlciBuZXdQYXJzZXIoQ2hhclNlcXVlbmNlIGlucHV0LCBib29sZWFuIGtlZXBEb2NDb21tZW50cywgYm9vbGVhbiBrZWVwRW5kUG9zLCBib29sZWFuIGtlZXBMaW5lTWFwLCBib29sZWFuIHBhcnNlTW9kdWxlSW5mbykgewogICAgICAgIExleGVyIGxleGVyID0gc2Nhbm5lckZhY3RvcnkubmV3U2Nhbm5lcihpbnB1dCwga2VlcERvY0NvbW1lbnRzKTsKICAgICAgICByZXR1cm4gbmV3IEphdmFjUGFyc2VyKHRoaXMsIGxleGVyLCBrZWVwRG9jQ29tbWVudHMsIGtlZXBMaW5lTWFwLCBrZWVwRW5kUG9zLCBwYXJzZU1vZHVsZUluZm8pOwogICAgfQp9ClBLAwQKAAAIAADSfU1K5117KesiAADrIgAALQAAAGNvbS9zdW4vdG9vbHMvamF2YWMvcGFyc2VyL1VuaWNvZGVSZWFkZXIuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAxMSwgMjAxMywgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLmphdmFjLnBhcnNlcjsKCmltcG9ydCBqYXZhLm5pby5DaGFyQnVmZmVyOwppbXBvcnQgamF2YS51dGlsLkFycmF5czsKCmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmZpbGUuSmF2YWNGaWxlTWFuYWdlcjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5BcnJheVV0aWxzOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkxvZzsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5OYW1lOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLk5hbWVzOwoKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuTGF5b3V0Q2hhcmFjdGVycy4qOwoKLyoqIFRoZSBjaGFyIHJlYWRlciB1c2VkIGJ5IHRoZSBqYXZhYyBsZXhlci90b2tlbml6ZXIuIFJldHVybnMgdGhlIHNlcXVlbmNlIG9mCiAqIGNoYXJhY3RlcnMgY29udGFpbmVkIGluIHRoZSBpbnB1dCBzdHJlYW0sIGhhbmRsaW5nIHVuaWNvZGUgZXNjYXBlIGFjY29yZGluZ2x5LgogKiBBZGRpdGlvbmFsbHksIGl0IHByb3ZpZGVzIGZlYXR1cmVzIGZvciBzYXZpbmcgY2hhcnMgaW50byBhIGJ1ZmZlciBhbmQgdG8gcmV0cmlldmUKICogdGhlbSBhdCBhIGxhdGVyIHN0YWdlLgogKgogKiAgPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24gcmlzay4KICogIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yCiAqICBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+CiAqLwpwdWJsaWMgY2xhc3MgVW5pY29kZVJlYWRlciB7CgogICAgLyoqIFRoZSBpbnB1dCBidWZmZXIsIGluZGV4IG9mIG5leHQgY2hhcmFjdGVyIHRvIGJlIHJlYWQsCiAgICAgKiAgaW5kZXggb2Ygb25lIHBhc3QgbGFzdCBjaGFyYWN0ZXIgaW4gYnVmZmVyLgogICAgICovCiAgICBwcm90ZWN0ZWQgY2hhcltdIGJ1ZjsKICAgIHByb3RlY3RlZCBpbnQgYnA7CiAgICBwcm90ZWN0ZWQgZmluYWwgaW50IGJ1ZmxlbjsKCiAgICAvKiogVGhlIGN1cnJlbnQgY2hhcmFjdGVyLgogICAgICovCiAgICBwcm90ZWN0ZWQgY2hhciBjaDsKCiAgICAvKiogVGhlIGJ1ZmZlciBpbmRleCBvZiB0aGUgbGFzdCBjb252ZXJ0ZWQgdW5pY29kZSBjaGFyYWN0ZXIKICAgICAqLwogICAgcHJvdGVjdGVkIGludCB1bmljb2RlQ29udmVyc2lvbkJwID0gLTE7CgogICAgcHJvdGVjdGVkIExvZyBsb2c7CiAgICBwcm90ZWN0ZWQgTmFtZXMgbmFtZXM7CgogICAgLyoqIEEgY2hhcmFjdGVyIGJ1ZmZlciBmb3Igc2F2ZWQgY2hhcnMuCiAgICAgKi8KICAgIHByb3RlY3RlZCBjaGFyW10gc2J1ZiA9IG5ldyBjaGFyWzEyOF07CiAgICBwcm90ZWN0ZWQgaW50IHNwOwoKICAgIC8qKgogICAgICogQ3JlYXRlIGEgc2Nhbm5lciBmcm9tIHRoZSBpbnB1dCBhcnJheS4gIFRoaXMgbWV0aG9kIG1pZ2h0CiAgICAgKiBtb2RpZnkgdGhlIGFycmF5LiAgVG8gYXZvaWQgY29weWluZyB0aGUgaW5wdXQgYXJyYXksIGVuc3VyZQogICAgICogdGhhdCB7QGNvZGUgaW5wdXRMZW5ndGggPCBpbnB1dC5sZW5ndGh9IG9yCiAgICAgKiB7QGNvZGUgaW5wdXRbaW5wdXQubGVuZ3RoIC0xXX0gaXMgYSB3aGl0ZSBzcGFjZSBjaGFyYWN0ZXIuCiAgICAgKgogICAgICogQHBhcmFtIHNmIHRoZSBmYWN0b3J5IHdoaWNoIGNyZWF0ZWQgdGhpcyBTY2FubmVyCiAgICAgKiBAcGFyYW0gYnVmZmVyIHRoZSBpbnB1dCwgbWlnaHQgYmUgbW9kaWZpZWQKICAgICAqIE11c3QgYmUgcG9zaXRpdmUgYW5kIGxlc3MgdGhhbiBvciBlcXVhbCB0byBpbnB1dC5sZW5ndGguCiAgICAgKi8KICAgIHByb3RlY3RlZCBVbmljb2RlUmVhZGVyKFNjYW5uZXJGYWN0b3J5IHNmLCBDaGFyQnVmZmVyIGJ1ZmZlcikgewogICAgICAgIHRoaXMoc2YsIEphdmFjRmlsZU1hbmFnZXIudG9BcnJheShidWZmZXIpLCBidWZmZXIubGltaXQoKSk7CiAgICB9CgogICAgcHJvdGVjdGVkIFVuaWNvZGVSZWFkZXIoU2Nhbm5lckZhY3Rvcnkgc2YsIGNoYXJbXSBpbnB1dCwgaW50IGlucHV0TGVuZ3RoKSB7CiAgICAgICAgbG9nID0gc2YubG9nOwogICAgICAgIG5hbWVzID0gc2YubmFtZXM7CiAgICAgICAgaWYgKGlucHV0TGVuZ3RoID09IGlucHV0Lmxlbmd0aCkgewogICAgICAgICAgICBpZiAoaW5wdXQubGVuZ3RoID4gMCAmJiBDaGFyYWN0ZXIuaXNXaGl0ZXNwYWNlKGlucHV0W2lucHV0Lmxlbmd0aCAtIDFdKSkgewogICAgICAgICAgICAgICAgaW5wdXRMZW5ndGgtLTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGlucHV0ID0gQXJyYXlzLmNvcHlPZihpbnB1dCwgaW5wdXRMZW5ndGggKyAxKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBidWYgPSBpbnB1dDsKICAgICAgICBidWZsZW4gPSBpbnB1dExlbmd0aDsKICAgICAgICBidWZbYnVmbGVuXSA9IEVPSTsKICAgICAgICBicCA9IC0xOwogICAgICAgIHNjYW5DaGFyKCk7CiAgICB9CgogICAgLyoqIFJlYWQgbmV4dCBjaGFyYWN0ZXIuCiAgICAgKi8KICAgIHByb3RlY3RlZCB2b2lkIHNjYW5DaGFyKCkgewogICAgICAgIGlmIChicCA8IGJ1ZmxlbikgewogICAgICAgICAgICBjaCA9IGJ1ZlsrK2JwXTsKICAgICAgICAgICAgaWYgKGNoID09ICdcXCcpIHsKICAgICAgICAgICAgICAgIGNvbnZlcnRVbmljb2RlKCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqIFJlYWQgbmV4dCBjaGFyYWN0ZXIgaW4gY29tbWVudCwgc2tpcHBpbmcgb3ZlciBkb3VibGUgJ1wnIGNoYXJhY3RlcnMuCiAgICAgKi8KICAgIHByb3RlY3RlZCB2b2lkIHNjYW5Db21tZW50Q2hhcigpIHsKICAgICAgICBzY2FuQ2hhcigpOwogICAgICAgIGlmIChjaCA9PSAnXFwnKSB7CiAgICAgICAgICAgIGlmIChwZWVrQ2hhcigpID09ICdcXCcgJiYgIWlzVW5pY29kZSgpKSB7CiAgICAgICAgICAgICAgICBza2lwQ2hhcigpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgY29udmVydFVuaWNvZGUoKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKiogQXBwZW5kIGEgY2hhcmFjdGVyIHRvIHNidWYuCiAgICAgKi8KICAgIHByb3RlY3RlZCB2b2lkIHB1dENoYXIoY2hhciBjaCwgYm9vbGVhbiBzY2FuKSB7CiAgICAgICAgc2J1ZiA9IEFycmF5VXRpbHMuZW5zdXJlQ2FwYWNpdHkoc2J1Ziwgc3ApOwogICAgICAgIHNidWZbc3ArK10gPSBjaDsKICAgICAgICBpZiAoc2NhbikKICAgICAgICAgICAgc2NhbkNoYXIoKTsKICAgIH0KCiAgICBwcm90ZWN0ZWQgdm9pZCBwdXRDaGFyKGNoYXIgY2gpIHsKICAgICAgICBwdXRDaGFyKGNoLCBmYWxzZSk7CiAgICB9CgogICAgcHJvdGVjdGVkIHZvaWQgcHV0Q2hhcihib29sZWFuIHNjYW4pIHsKICAgICAgICBwdXRDaGFyKGNoLCBzY2FuKTsKICAgIH0KCiAgICBOYW1lIG5hbWUoKSB7CiAgICAgICAgcmV0dXJuIG5hbWVzLmZyb21DaGFycyhzYnVmLCAwLCBzcCk7CiAgICB9CgogICAgU3RyaW5nIGNoYXJzKCkgewogICAgICAgIHJldHVybiBuZXcgU3RyaW5nKHNidWYsIDAsIHNwKTsKICAgIH0KCiAgICAvKiogQ29udmVydCB1bmljb2RlIGVzY2FwZTsgYnAgcG9pbnRzIHRvIGluaXRpYWwgJ1wnIGNoYXJhY3RlcgogICAgICogIChTcGVjIDMuMykuCiAgICAgKi8KICAgIHByb3RlY3RlZCB2b2lkIGNvbnZlcnRVbmljb2RlKCkgewogICAgICAgIGlmIChjaCA9PSAnXFwnICYmIHVuaWNvZGVDb252ZXJzaW9uQnAgIT0gYnApIHsKICAgICAgICAgICAgYnArKzsgY2ggPSBidWZbYnBdOwogICAgICAgICAgICBpZiAoY2ggPT0gJ3UnKSB7CiAgICAgICAgICAgICAgICBkbyB7CiAgICAgICAgICAgICAgICAgICAgYnArKzsgY2ggPSBidWZbYnBdOwogICAgICAgICAgICAgICAgfSB3aGlsZSAoY2ggPT0gJ3UnKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGJwICsgMzsKICAgICAgICAgICAgICAgIGlmIChsaW1pdCA8IGJ1ZmxlbikgewogICAgICAgICAgICAgICAgICAgIGludCBkID0gZGlnaXQoYnAsIDE2KTsKICAgICAgICAgICAgICAgICAgICBpbnQgY29kZSA9IGQ7CiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGJwIDwgbGltaXQgJiYgZCA+PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGJwKys7IGNoID0gYnVmW2JwXTsKICAgICAgICAgICAgICAgICAgICAgICAgZCA9IGRpZ2l0KGJwLCAxNik7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvZGUgPSAoY29kZSA8PCA0KSArIGQ7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmIChkID49IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgY2ggPSAoY2hhciljb2RlOwogICAgICAgICAgICAgICAgICAgICAgICB1bmljb2RlQ29udmVyc2lvbkJwID0gYnA7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBsb2cuZXJyb3IoYnAsICJpbGxlZ2FsLnVuaWNvZGUuZXNjIik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBicC0tOwogICAgICAgICAgICAgICAgY2ggPSAnXFwnOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKiBBcmUgc3Vycm9nYXRlcyBzdXBwb3J0ZWQ/CiAgICAgKi8KICAgIGZpbmFsIHN0YXRpYyBib29sZWFuIHN1cnJvZ2F0ZXNTdXBwb3J0ZWQgPSBzdXJyb2dhdGVzU3VwcG9ydGVkKCk7CiAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIHN1cnJvZ2F0ZXNTdXBwb3J0ZWQoKSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgQ2hhcmFjdGVyLmlzSGlnaFN1cnJvZ2F0ZSgnYScpOwogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9IGNhdGNoIChOb1N1Y2hNZXRob2RFcnJvciBleCkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgfQoKICAgIC8qKiBTY2FuIHN1cnJvZ2F0ZSBwYWlycy4gIElmICdjaCcgaXMgYSBoaWdoIHN1cnJvZ2F0ZSBhbmQKICAgICAqICB0aGUgbmV4dCBjaGFyYWN0ZXIgaXMgYSBsb3cgc3Vycm9nYXRlLCByZXR1cm5zIHRoZSBjb2RlIHBvaW50CiAgICAgKiAgY29uc3RydWN0ZWQgZnJvbSB0aGVzZSBzdXJyb2dhdGVzLiBPdGhlcndpc2UsIHJldHVybnMgLTEuCiAgICAgKiAgVGhpcyBtZXRob2Qgd2lsbCBub3QgY29uc3VtZSBhbnkgb2YgdGhlIGNoYXJhY3RlcnMuCiAgICAgKi8KICAgIHByb3RlY3RlZCBpbnQgcGVla1N1cnJvZ2F0ZXMoKSB7CiAgICAgICAgaWYgKHN1cnJvZ2F0ZXNTdXBwb3J0ZWQgJiYgQ2hhcmFjdGVyLmlzSGlnaFN1cnJvZ2F0ZShjaCkpIHsKICAgICAgICAgICAgY2hhciBoaWdoID0gY2g7CiAgICAgICAgICAgIGludCBwcmV2QlAgPSBicDsKCiAgICAgICAgICAgIHNjYW5DaGFyKCk7CgogICAgICAgICAgICBjaGFyIGxvdyA9IGNoOwoKICAgICAgICAgICAgY2ggPSBoaWdoOwogICAgICAgICAgICBicCA9IHByZXZCUDsKCiAgICAgICAgICAgIGlmIChDaGFyYWN0ZXIuaXNMb3dTdXJyb2dhdGUobG93KSkgewogICAgICAgICAgICAgICAgcmV0dXJuIENoYXJhY3Rlci50b0NvZGVQb2ludChoaWdoLCBsb3cpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gLTE7CiAgICB9CgogICAgLyoqIENvbnZlcnQgYW4gQVNDSUkgZGlnaXQgZnJvbSBpdHMgYmFzZSAoOCwgMTAsIG9yIDE2KQogICAgICogIHRvIGl0cyB2YWx1ZS4KICAgICAqLwogICAgcHJvdGVjdGVkIGludCBkaWdpdChpbnQgcG9zLCBpbnQgYmFzZSkgewogICAgICAgIGNoYXIgYyA9IGNoOwogICAgICAgIGlmICgnMCcgPD0gYyAmJiBjIDw9ICc5JykKICAgICAgICAgICAgcmV0dXJuIENoYXJhY3Rlci5kaWdpdChjLCBiYXNlKTsgLy9hIGZhc3QgY29tbW9uIGNhc2UKICAgICAgICBpbnQgY29kZVBvaW50ID0gcGVla1N1cnJvZ2F0ZXMoKTsKICAgICAgICBpbnQgcmVzdWx0ID0gY29kZVBvaW50ID49IDAgPyBDaGFyYWN0ZXIuZGlnaXQoY29kZVBvaW50LCBiYXNlKSA6IENoYXJhY3Rlci5kaWdpdChjLCBiYXNlKTsKICAgICAgICBpZiAocmVzdWx0ID49IDAgJiYgYyA+IDB4N2YpIHsKICAgICAgICAgICAgbG9nLmVycm9yKHBvcyArIDEsICJpbGxlZ2FsLm5vbmFzY2lpLmRpZ2l0Iik7CiAgICAgICAgICAgIGlmIChjb2RlUG9pbnQgPj0gMCkKICAgICAgICAgICAgICAgIHNjYW5DaGFyKCk7CiAgICAgICAgICAgIGNoID0gIjAxMjM0NTY3ODlhYmNkZWYiLmNoYXJBdChyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgfQoKICAgIHByb3RlY3RlZCBib29sZWFuIGlzVW5pY29kZSgpIHsKICAgICAgICByZXR1cm4gdW5pY29kZUNvbnZlcnNpb25CcCA9PSBicDsKICAgIH0KCiAgICBwcm90ZWN0ZWQgdm9pZCBza2lwQ2hhcigpIHsKICAgICAgICBicCsrOwogICAgfQoKICAgIHByb3RlY3RlZCBjaGFyIHBlZWtDaGFyKCkgewogICAgICAgIHJldHVybiBidWZbYnAgKyAxXTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgYSBjb3B5IG9mIHRoZSBpbnB1dCBidWZmZXIsIHVwIHRvIGl0cyBpbnB1dExlbmd0aC4KICAgICAqIFVuaWNvZGUgZXNjYXBlIHNlcXVlbmNlcyBhcmUgbm90IHRyYW5zbGF0ZWQuCiAgICAgKi8KICAgIHB1YmxpYyBjaGFyW10gZ2V0UmF3Q2hhcmFjdGVycygpIHsKICAgICAgICBjaGFyW10gY2hhcnMgPSBuZXcgY2hhcltidWZsZW5dOwogICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYnVmLCAwLCBjaGFycywgMCwgYnVmbGVuKTsKICAgICAgICByZXR1cm4gY2hhcnM7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgY29weSBvZiBhIGNoYXJhY3RlciBhcnJheSBzdWJzZXQgb2YgdGhlIGlucHV0IGJ1ZmZlci4KICAgICAqIFRoZSByZXR1cm5lZCBhcnJheSBiZWdpbnMgYXQgdGhlIHtAY29kZSBiZWdpbkluZGV4fSBhbmQKICAgICAqIGV4dGVuZHMgdG8gdGhlIGNoYXJhY3RlciBhdCBpbmRleCB7QGNvZGUgZW5kSW5kZXggLSAxfS4KICAgICAqIFRodXMgdGhlIGxlbmd0aCBvZiB0aGUgc3Vic3RyaW5nIGlzIHtAY29kZSBlbmRJbmRleC1iZWdpbkluZGV4fS4KICAgICAqIFRoaXMgYmVoYXZpb3IgaXMgbGlrZQogICAgICoge0Bjb2RlIFN0cmluZy5zdWJzdHJpbmcoYmVnaW5JbmRleCwgZW5kSW5kZXgpfS4KICAgICAqIFVuaWNvZGUgZXNjYXBlIHNlcXVlbmNlcyBhcmUgbm90IHRyYW5zbGF0ZWQuCiAgICAgKgogICAgICogQHBhcmFtIGJlZ2luSW5kZXggdGhlIGJlZ2lubmluZyBpbmRleCwgaW5jbHVzaXZlLgogICAgICogQHBhcmFtIGVuZEluZGV4IHRoZSBlbmRpbmcgaW5kZXgsIGV4Y2x1c2l2ZS4KICAgICAqIEB0aHJvd3MgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGlmIGVpdGhlciBvZmZzZXQgaXMgb3V0c2lkZSBvZiB0aGUKICAgICAqICAgICAgICAgYXJyYXkgYm91bmRzCiAgICAgKi8KICAgIHB1YmxpYyBjaGFyW10gZ2V0UmF3Q2hhcmFjdGVycyhpbnQgYmVnaW5JbmRleCwgaW50IGVuZEluZGV4KSB7CiAgICAgICAgaW50IGxlbmd0aCA9IGVuZEluZGV4IC0gYmVnaW5JbmRleDsKICAgICAgICBjaGFyW10gY2hhcnMgPSBuZXcgY2hhcltsZW5ndGhdOwogICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYnVmLCBiZWdpbkluZGV4LCBjaGFycywgMCwgbGVuZ3RoKTsKICAgICAgICByZXR1cm4gY2hhcnM7CiAgICB9Cn0KUEsDBAoAAAgAAAY7qUoAAAAAAAAAAAAAAAAZAAAAY29tL3N1bi90b29scy9qYXZhYy9maWxlL1BLAwQKAAAIAAAGO6lKaGT4zfelAAD3pQAALgAAAGNvbS9zdW4vdG9vbHMvamF2YWMvZmlsZS9KYXZhY0ZpbGVNYW5hZ2VyLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMTcsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhYy5maWxlOwoKaW1wb3J0IGphdmEuaW8uRmlsZTsKaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CmltcG9ydCBqYXZhLm5ldC5NYWxmb3JtZWRVUkxFeGNlcHRpb247CmltcG9ydCBqYXZhLm5ldC5VUkk7CmltcG9ydCBqYXZhLm5ldC5VUklTeW50YXhFeGNlcHRpb247CmltcG9ydCBqYXZhLm5ldC5VUkw7CmltcG9ydCBqYXZhLm5pby5DaGFyQnVmZmVyOwppbXBvcnQgamF2YS5uaW8uY2hhcnNldC5DaGFyc2V0OwppbXBvcnQgamF2YS5uaW8uZmlsZS5GaWxlU3lzdGVtOwppbXBvcnQgamF2YS5uaW8uZmlsZS5GaWxlU3lzdGVtczsKaW1wb3J0IGphdmEubmlvLmZpbGUuRmlsZVZpc2l0T3B0aW9uOwppbXBvcnQgamF2YS5uaW8uZmlsZS5GaWxlVmlzaXRSZXN1bHQ7CmltcG9ydCBqYXZhLm5pby5maWxlLkZpbGVzOwppbXBvcnQgamF2YS5uaW8uZmlsZS5JbnZhbGlkUGF0aEV4Y2VwdGlvbjsKaW1wb3J0IGphdmEubmlvLmZpbGUuTGlua09wdGlvbjsKaW1wb3J0IGphdmEubmlvLmZpbGUuUGF0aDsKaW1wb3J0IGphdmEubmlvLmZpbGUuUGF0aHM7CmltcG9ydCBqYXZhLm5pby5maWxlLlByb3ZpZGVyTm90Rm91bmRFeGNlcHRpb247CmltcG9ydCBqYXZhLm5pby5maWxlLlNpbXBsZUZpbGVWaXNpdG9yOwppbXBvcnQgamF2YS5uaW8uZmlsZS5hdHRyaWJ1dGUuQmFzaWNGaWxlQXR0cmlidXRlczsKaW1wb3J0IGphdmEubmlvLmZpbGUuc3BpLkZpbGVTeXN0ZW1Qcm92aWRlcjsKaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CmltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOwppbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb247CmltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbnM7CmltcG9ydCBqYXZhLnV0aWwuQ29tcGFyYXRvcjsKaW1wb3J0IGphdmEudXRpbC5FbnVtU2V0OwppbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CmltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CmltcG9ydCBqYXZhLnV0aWwuTWFwOwppbXBvcnQgamF2YS51dGlsLk9iamVjdHM7CmltcG9ydCBqYXZhLnV0aWwuU2VydmljZUxvYWRlcjsKaW1wb3J0IGphdmEudXRpbC5TZXQ7CmltcG9ydCBqYXZhLnV0aWwuc3RyZWFtLkNvbGxlY3RvcnM7CmltcG9ydCBqYXZhLnV0aWwuc3RyZWFtLlN0cmVhbTsKCmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLlNvdXJjZVZlcnNpb247CmltcG9ydCBqYXZheC50b29scy5GaWxlT2JqZWN0OwppbXBvcnQgamF2YXgudG9vbHMuSmF2YUZpbGVNYW5hZ2VyOwppbXBvcnQgamF2YXgudG9vbHMuSmF2YUZpbGVPYmplY3Q7CmltcG9ydCBqYXZheC50b29scy5TdGFuZGFyZEphdmFGaWxlTWFuYWdlcjsKCmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmZpbGUuUmVsYXRpdmVQYXRoLlJlbGF0aXZlRGlyZWN0b3J5OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5maWxlLlJlbGF0aXZlUGF0aC5SZWxhdGl2ZUZpbGU7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuQXNzZXJ0OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkNvbnRleHQ7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuQ29udGV4dC5GYWN0b3J5OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkRlZmluZWRCeTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5EZWZpbmVkQnkuQXBpOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkxpc3Q7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuTGlzdEJ1ZmZlcjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5KREs5V3JhcHBlcnMuQ29uZmlndXJhdGlvbjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5KREs5V3JhcHBlcnMuTGF5ZXI7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuSkRLOVdyYXBwZXJzLk1vZHVsZUZpbmRlcjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5KREs5V3JhcHBlcnMuTW9kdWxlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkpESzlXcmFwcGVycy5TZXJ2aWNlTG9hZGVySGVscGVyOwoKaW1wb3J0IHN0YXRpYyBqYXZhLm5pby5maWxlLkZpbGVWaXNpdE9wdGlvbi5GT0xMT1dfTElOS1M7CgppbXBvcnQgc3RhdGljIGphdmF4LnRvb2xzLlN0YW5kYXJkTG9jYXRpb24uKjsKCi8qKgogKiBUaGlzIGNsYXNzIHByb3ZpZGVzIGFjY2VzcyB0byB0aGUgc291cmNlLCBjbGFzcyBhbmQgb3RoZXIgZmlsZXMKICogdXNlZCBieSB0aGUgY29tcGlsZXIgYW5kIHJlbGF0ZWQgdG9vbHMuCiAqCiAqIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24gcmlzay4KICogVGhpcyBjb2RlIGFuZCBpdHMgaW50ZXJuYWwgaW50ZXJmYWNlcyBhcmUgc3ViamVjdCB0byBjaGFuZ2Ugb3IKICogZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPgogKi8KcHVibGljIGNsYXNzIEphdmFjRmlsZU1hbmFnZXIgZXh0ZW5kcyBCYXNlRmlsZU1hbmFnZXIgaW1wbGVtZW50cyBTdGFuZGFyZEphdmFGaWxlTWFuYWdlciB7CgogICAgQFN1cHByZXNzV2FybmluZ3MoImNhc3QiKQogICAgcHVibGljIHN0YXRpYyBjaGFyW10gdG9BcnJheShDaGFyQnVmZmVyIGJ1ZmZlcikgewogICAgICAgIGlmIChidWZmZXIuaGFzQXJyYXkoKSkKICAgICAgICAgICAgcmV0dXJuICgoQ2hhckJ1ZmZlcilidWZmZXIuY29tcGFjdCgpLmZsaXAoKSkuYXJyYXkoKTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIHJldHVybiBidWZmZXIudG9TdHJpbmcoKS50b0NoYXJBcnJheSgpOwogICAgfQoKICAgIHByaXZhdGUgRlNJbmZvIGZzSW5mbzsKCiAgICBwcml2YXRlIGZpbmFsIFNldDxKYXZhRmlsZU9iamVjdC5LaW5kPiBzb3VyY2VPckNsYXNzID0KICAgICAgICBFbnVtU2V0Lm9mKEphdmFGaWxlT2JqZWN0LktpbmQuU09VUkNFLCBKYXZhRmlsZU9iamVjdC5LaW5kLkNMQVNTKTsKCiAgICBwcm90ZWN0ZWQgYm9vbGVhbiBzeW1ib2xGaWxlRW5hYmxlZDsKCiAgICBwcml2YXRlIFBhdGhGYWN0b3J5IHBhdGhGYWN0b3J5ID0gUGF0aHM6OmdldDsKCiAgICBwcm90ZWN0ZWQgZW51bSBTb3J0RmlsZXMgaW1wbGVtZW50cyBDb21wYXJhdG9yPFBhdGg+IHsKICAgICAgICBGT1JXQVJEIHsKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHB1YmxpYyBpbnQgY29tcGFyZShQYXRoIGYxLCBQYXRoIGYyKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZjEuZ2V0RmlsZU5hbWUoKS5jb21wYXJlVG8oZjIuZ2V0RmlsZU5hbWUoKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIFJFVkVSU0UgewogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHVibGljIGludCBjb21wYXJlKFBhdGggZjEsIFBhdGggZjIpIHsKICAgICAgICAgICAgICAgIHJldHVybiAtZjEuZ2V0RmlsZU5hbWUoKS5jb21wYXJlVG8oZjIuZ2V0RmlsZU5hbWUoKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgcHJvdGVjdGVkIFNvcnRGaWxlcyBzb3J0RmlsZXM7CgogICAgLyoqCiAgICAgKiBSZWdpc3RlciBhIENvbnRleHQuRmFjdG9yeSB0byBjcmVhdGUgYSBKYXZhY0ZpbGVNYW5hZ2VyLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIHZvaWQgcHJlUmVnaXN0ZXIoQ29udGV4dCBjb250ZXh0KSB7CiAgICAgICAgY29udGV4dC5wdXQoSmF2YUZpbGVNYW5hZ2VyLmNsYXNzLAogICAgICAgICAgICAgICAgKEZhY3Rvcnk8SmF2YUZpbGVNYW5hZ2VyPiljIC0+IG5ldyBKYXZhY0ZpbGVNYW5hZ2VyKGMsIHRydWUsIG51bGwpKTsKICAgIH0KCiAgICAvKioKICAgICAqIENyZWF0ZSBhIEphdmFjRmlsZU1hbmFnZXIgdXNpbmcgYSBnaXZlbiBjb250ZXh0LCBvcHRpb25hbGx5IHJlZ2lzdGVyaW5nCiAgICAgKiBpdCBhcyB0aGUgSmF2YUZpbGVNYW5hZ2VyIGZvciB0aGF0IGNvbnRleHQuCiAgICAgKi8KICAgIHB1YmxpYyBKYXZhY0ZpbGVNYW5hZ2VyKENvbnRleHQgY29udGV4dCwgYm9vbGVhbiByZWdpc3RlciwgQ2hhcnNldCBjaGFyc2V0KSB7CiAgICAgICAgc3VwZXIoY2hhcnNldCk7CiAgICAgICAgaWYgKHJlZ2lzdGVyKQogICAgICAgICAgICBjb250ZXh0LnB1dChKYXZhRmlsZU1hbmFnZXIuY2xhc3MsIHRoaXMpOwogICAgICAgIHNldENvbnRleHQoY29udGV4dCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXQgdGhlIGNvbnRleHQgZm9yIEphdmFjRmlsZU1hbmFnZXIuCiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIHZvaWQgc2V0Q29udGV4dChDb250ZXh0IGNvbnRleHQpIHsKICAgICAgICBzdXBlci5zZXRDb250ZXh0KGNvbnRleHQpOwoKICAgICAgICBmc0luZm8gPSBGU0luZm8uaW5zdGFuY2UoY29udGV4dCk7CgogICAgICAgIHN5bWJvbEZpbGVFbmFibGVkID0gIW9wdGlvbnMuaXNTZXQoImlnbm9yZS5zeW1ib2wuZmlsZSIpOwoKICAgICAgICBTdHJpbmcgc2YgPSBvcHRpb25zLmdldCgic29ydEZpbGVzIik7CiAgICAgICAgaWYgKHNmICE9IG51bGwpIHsKICAgICAgICAgICAgc29ydEZpbGVzID0gKHNmLmVxdWFscygicmV2ZXJzZSIpID8gU29ydEZpbGVzLlJFVkVSU0UgOiBTb3J0RmlsZXMuRk9SV0FSRCk7CiAgICAgICAgfQogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KERlZmluZWRCeS5BcGkuQ09NUElMRVIpCiAgICBwdWJsaWMgdm9pZCBzZXRQYXRoRmFjdG9yeShQYXRoRmFjdG9yeSBmKSB7CiAgICAgICAgcGF0aEZhY3RvcnkgPSBPYmplY3RzLnJlcXVpcmVOb25OdWxsKGYpOwogICAgICAgIGxvY2F0aW9ucy5zZXRQYXRoRmFjdG9yeShmKTsKICAgIH0KCiAgICBwcml2YXRlIFBhdGggZ2V0UGF0aChTdHJpbmcgZmlyc3QsIFN0cmluZy4uLiBtb3JlKSB7CiAgICAgICAgcmV0dXJuIHBhdGhGYWN0b3J5LmdldFBhdGgoZmlyc3QsIG1vcmUpOwogICAgfQoKICAgIC8qKgogICAgICogU2V0IHdoZXRoZXIgb3Igbm90IHRvIHVzZSBjdC5zeW0gYXMgYW4gYWx0ZXJuYXRlIHRvIHJ0Lmphci4KICAgICAqLwogICAgcHVibGljIHZvaWQgc2V0U3ltYm9sRmlsZUVuYWJsZWQoYm9vbGVhbiBiKSB7CiAgICAgICAgc3ltYm9sRmlsZUVuYWJsZWQgPSBiOwogICAgfQoKICAgIHB1YmxpYyBib29sZWFuIGlzU3ltYm9sRmlsZUVuYWJsZWQoKSB7CiAgICAgICAgcmV0dXJuIHN5bWJvbEZpbGVFbmFibGVkOwogICAgfQoKICAgIC8vIHVzZWQgYnkgdGVzdHMKICAgIHB1YmxpYyBKYXZhRmlsZU9iamVjdCBnZXRKYXZhRmlsZU9iamVjdChTdHJpbmcgbmFtZSkgewogICAgICAgIHJldHVybiBnZXRKYXZhRmlsZU9iamVjdHMobmFtZSkuaXRlcmF0b3IoKS5uZXh0KCk7CiAgICB9CgogICAgLy8gdXNlZCBieSB0ZXN0cwogICAgcHVibGljIEphdmFGaWxlT2JqZWN0IGdldEphdmFGaWxlT2JqZWN0KFBhdGggZmlsZSkgewogICAgICAgIHJldHVybiBnZXRKYXZhRmlsZU9iamVjdHMoZmlsZSkuaXRlcmF0b3IoKS5uZXh0KCk7CiAgICB9CgogICAgcHVibGljIEphdmFGaWxlT2JqZWN0IGdldEZpbGVGb3JPdXRwdXQoU3RyaW5nIGNsYXNzbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEphdmFGaWxlT2JqZWN0LktpbmQga2luZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEphdmFGaWxlT2JqZWN0IHNpYmxpbmcpCiAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uCiAgICB7CiAgICAgICAgcmV0dXJuIGdldEphdmFGaWxlRm9yT3V0cHV0KENMQVNTX09VVFBVVCwgY2xhc3NuYW1lLCBraW5kLCBzaWJsaW5nKTsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICBwdWJsaWMgSXRlcmFibGU8PyBleHRlbmRzIEphdmFGaWxlT2JqZWN0PiBnZXRKYXZhRmlsZU9iamVjdHNGcm9tU3RyaW5ncyhJdGVyYWJsZTxTdHJpbmc+IG5hbWVzKSB7CiAgICAgICAgTGlzdEJ1ZmZlcjxQYXRoPiBwYXRocyA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICBmb3IgKFN0cmluZyBuYW1lIDogbmFtZXMpCiAgICAgICAgICAgIHBhdGhzLmFwcGVuZChnZXRQYXRoKG51bGxDaGVjayhuYW1lKSkpOwogICAgICAgIHJldHVybiBnZXRKYXZhRmlsZU9iamVjdHNGcm9tUGF0aHMocGF0aHMudG9MaXN0KCkpOwogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgIHB1YmxpYyBJdGVyYWJsZTw/IGV4dGVuZHMgSmF2YUZpbGVPYmplY3Q+IGdldEphdmFGaWxlT2JqZWN0cyhTdHJpbmcuLi4gbmFtZXMpIHsKICAgICAgICByZXR1cm4gZ2V0SmF2YUZpbGVPYmplY3RzRnJvbVN0cmluZ3MoQXJyYXlzLmFzTGlzdChudWxsQ2hlY2sobmFtZXMpKSk7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBpc1ZhbGlkTmFtZShTdHJpbmcgbmFtZSkgewogICAgICAgIC8vIEFyZ3VhYmx5LCBpc1ZhbGlkTmFtZSBzaG91bGQgcmVqZWN0IGtleXdvcmRzIChzdWNoIGFzIGluIFNvdXJjZVZlcnNpb24uaXNOYW1lKCkgKSwKICAgICAgICAvLyBidXQgdGhlIHNldCBvZiBrZXl3b3JkcyBkZXBlbmRzIG9uIHRoZSBzb3VyY2UgbGV2ZWwsIGFuZCB3ZSBkb24ndCB3YW50CiAgICAgICAgLy8gaW1wbHMgb2YgSmF2YUZpbGVNYW5hZ2VyIHRvIGhhdmUgdG8gYmUgZGVwZW5kZW50IG9uIHRoZSBzb3VyY2UgbGV2ZWwuCiAgICAgICAgLy8gVGhlcmVmb3JlIHdlIHNpbXBseSBjaGVjayB0aGF0IHRoZSBhcmd1bWVudCBpcyBhIHNlcXVlbmNlIG9mIGlkZW50aWZpZXJzCiAgICAgICAgLy8gc2VwYXJhdGVkIGJ5ICIuIi4KICAgICAgICBmb3IgKFN0cmluZyBzIDogbmFtZS5zcGxpdCgiXFwuIiwgLTEpKSB7CiAgICAgICAgICAgIGlmICghU291cmNlVmVyc2lvbi5pc0lkZW50aWZpZXIocykpCiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIHZvaWQgdmFsaWRhdGVDbGFzc05hbWUoU3RyaW5nIGNsYXNzTmFtZSkgewogICAgICAgIGlmICghaXNWYWxpZE5hbWUoY2xhc3NOYW1lKSkKICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiSW52YWxpZCBjbGFzcyBuYW1lOiAiICsgY2xhc3NOYW1lKTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyB2b2lkIHZhbGlkYXRlUGFja2FnZU5hbWUoU3RyaW5nIHBhY2thZ2VOYW1lKSB7CiAgICAgICAgaWYgKHBhY2thZ2VOYW1lLmxlbmd0aCgpID4gMCAmJiAhaXNWYWxpZE5hbWUocGFja2FnZU5hbWUpKQogICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJJbnZhbGlkIHBhY2thZ2VOYW1lIG5hbWU6ICIgKyBwYWNrYWdlTmFtZSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyB2b2lkIHRlc3ROYW1lKFN0cmluZyBuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gaXNWYWxpZFBhY2thZ2VOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gaXNWYWxpZENsYXNzTmFtZSkKICAgIHsKICAgICAgICB0cnkgewogICAgICAgICAgICB2YWxpZGF0ZVBhY2thZ2VOYW1lKG5hbWUpOwogICAgICAgICAgICBpZiAoIWlzVmFsaWRQYWNrYWdlTmFtZSkKICAgICAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigiSW52YWxpZCBwYWNrYWdlIG5hbWUgYWNjZXB0ZWQ6ICIgKyBuYW1lKTsKICAgICAgICAgICAgcHJpbnRBc2NpaSgiVmFsaWQgcGFja2FnZSBuYW1lOiBcIiVzXCIiLCBuYW1lKTsKICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgewogICAgICAgICAgICBpZiAoaXNWYWxpZFBhY2thZ2VOYW1lKQogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCJWYWxpZCBwYWNrYWdlIG5hbWUgcmVqZWN0ZWQ6ICIgKyBuYW1lKTsKICAgICAgICAgICAgcHJpbnRBc2NpaSgiSW52YWxpZCBwYWNrYWdlIG5hbWU6IFwiJXNcIiIsIG5hbWUpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgICB2YWxpZGF0ZUNsYXNzTmFtZShuYW1lKTsKICAgICAgICAgICAgaWYgKCFpc1ZhbGlkQ2xhc3NOYW1lKQogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCJJbnZhbGlkIGNsYXNzIG5hbWUgYWNjZXB0ZWQ6ICIgKyBuYW1lKTsKICAgICAgICAgICAgcHJpbnRBc2NpaSgiVmFsaWQgY2xhc3MgbmFtZTogXCIlc1wiIiwgbmFtZSk7CiAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgaWYgKGlzVmFsaWRDbGFzc05hbWUpCiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoIlZhbGlkIGNsYXNzIG5hbWUgcmVqZWN0ZWQ6ICIgKyBuYW1lKTsKICAgICAgICAgICAgcHJpbnRBc2NpaSgiSW52YWxpZCBjbGFzcyBuYW1lOiBcIiVzXCIiLCBuYW1lKTsKICAgICAgICB9CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBwcmludEFzY2lpKFN0cmluZyBmb3JtYXQsIE9iamVjdC4uLiBhcmdzKSB7CiAgICAgICAgU3RyaW5nIG1lc3NhZ2U7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgZmluYWwgU3RyaW5nIGFzY2lpID0gIlVTLUFTQ0lJIjsKICAgICAgICAgICAgbWVzc2FnZSA9IG5ldyBTdHJpbmcoU3RyaW5nLmZvcm1hdChudWxsLCBmb3JtYXQsIGFyZ3MpLmdldEJ5dGVzKGFzY2lpKSwgYXNjaWkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiBleCkgewogICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoZXgpOwogICAgICAgIH0KICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4obWVzc2FnZSk7CiAgICB9CgogICAgcHJpdmF0ZSBmaW5hbCBNYXA8UGF0aCwgQ29udGFpbmVyPiBjb250YWluZXJzID0gbmV3IEhhc2hNYXA8PigpOwoKICAgIHN5bmNocm9uaXplZCBDb250YWluZXIgZ2V0Q29udGFpbmVyKFBhdGggcGF0aCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICBDb250YWluZXIgZnMgPSBjb250YWluZXJzLmdldChwYXRoKTsKCiAgICAgICAgaWYgKGZzICE9IG51bGwpIHsKICAgICAgICAgICAgcmV0dXJuIGZzOwogICAgICAgIH0KCiAgICAgICAgaWYgKGZzSW5mby5pc0ZpbGUocGF0aCkgJiYgcGF0aC5lcXVhbHMoTG9jYXRpb25zLnRoaXNTeXN0ZW1Nb2R1bGVzKSkgewogICAgICAgICAgICBjb250YWluZXJzLnB1dChwYXRoLCBmcyA9IG5ldyBKUlRJbWFnZUNvbnRhaW5lcigpKTsKICAgICAgICAgICAgcmV0dXJuIGZzOwogICAgICAgIH0KCiAgICAgICAgUGF0aCByZWFsUGF0aCA9IGZzSW5mby5nZXRDYW5vbmljYWxGaWxlKHBhdGgpOwoKICAgICAgICBmcyA9IGNvbnRhaW5lcnMuZ2V0KHJlYWxQYXRoKTsKCiAgICAgICAgaWYgKGZzICE9IG51bGwpIHsKICAgICAgICAgICAgY29udGFpbmVycy5wdXQocGF0aCwgZnMpOwogICAgICAgICAgICByZXR1cm4gZnM7CiAgICAgICAgfQoKICAgICAgICBCYXNpY0ZpbGVBdHRyaWJ1dGVzIGF0dHIgPSBudWxsOwoKICAgICAgICB0cnkgewogICAgICAgICAgICBhdHRyID0gRmlsZXMucmVhZEF0dHJpYnV0ZXMocmVhbFBhdGgsIEJhc2ljRmlsZUF0dHJpYnV0ZXMuY2xhc3MpOwogICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7CiAgICAgICAgICAgIC8vbm9uLWV4aXN0aW5nCiAgICAgICAgICAgIGZzID0gTUlTU0lOR19DT05UQUlORVI7CiAgICAgICAgfQoKICAgICAgICBpZiAoYXR0ciAhPSBudWxsKSB7CiAgICAgICAgICAgIGlmIChhdHRyLmlzRGlyZWN0b3J5KCkpIHsKICAgICAgICAgICAgICAgIGZzID0gbmV3IERpcmVjdG9yeUNvbnRhaW5lcihwYXRoKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgZnMgPSBuZXcgQXJjaGl2ZUNvbnRhaW5lcihwYXRoKTsKICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFByb3ZpZGVyTm90Rm91bmRFeGNlcHRpb24gfCBTZWN1cml0eUV4Y2VwdGlvbiBleCkgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbihleCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGNvbnRhaW5lcnMucHV0KHJlYWxQYXRoLCBmcyk7CiAgICAgICAgY29udGFpbmVycy5wdXQocGF0aCwgZnMpOwoKICAgICAgICByZXR1cm4gZnM7CiAgICB9CgogICAgcHJpdmF0ZSBpbnRlcmZhY2UgQ29udGFpbmVyIHsKICAgICAgICAvKioKICAgICAgICAgKiBJbnNlcnQgYWxsIGZpbGVzIGluIHN1YmRpcmVjdG9yeSBzdWJkaXJlY3Rvcnkgb2YgY29udGFpbmVyIHdoaWNoCiAgICAgICAgICogbWF0Y2ggZmlsZUtpbmRzIGludG8gcmVzdWx0TGlzdAogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIGxpc3QoUGF0aCB1c2VyUGF0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlbGF0aXZlRGlyZWN0b3J5IHN1YmRpcmVjdG9yeSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNldDxKYXZhRmlsZU9iamVjdC5LaW5kPiBmaWxlS2luZHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIHJlY3Vyc2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0QnVmZmVyPEphdmFGaWxlT2JqZWN0PiByZXN1bHRMaXN0KSB0aHJvd3MgSU9FeGNlcHRpb247CiAgICAgICAgcHVibGljIGFic3RyYWN0IEphdmFGaWxlT2JqZWN0IGdldEZpbGVPYmplY3QoUGF0aCB1c2VyUGF0aCwgUmVsYXRpdmVGaWxlIG5hbWUpIHRocm93cyBJT0V4Y2VwdGlvbjsKICAgICAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbjsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBDb250YWluZXIgTUlTU0lOR19DT05UQUlORVIgPSAgbmV3IENvbnRhaW5lcigpIHsKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCBsaXN0KFBhdGggdXNlclBhdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICBSZWxhdGl2ZURpcmVjdG9yeSBzdWJkaXJlY3RvcnksCiAgICAgICAgICAgICAgICAgICAgICAgICBTZXQ8SmF2YUZpbGVPYmplY3QuS2luZD4gZmlsZUtpbmRzLAogICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiByZWN1cnNlLAogICAgICAgICAgICAgICAgICAgICAgICAgTGlzdEJ1ZmZlcjxKYXZhRmlsZU9iamVjdD4gcmVzdWx0TGlzdCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICB9CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIEphdmFGaWxlT2JqZWN0IGdldEZpbGVPYmplY3QoUGF0aCB1c2VyUGF0aCwgUmVsYXRpdmVGaWxlIG5hbWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7fQogICAgfTsKCiAgICBwcml2YXRlIGZpbmFsIGNsYXNzIEpSVEltYWdlQ29udGFpbmVyIGltcGxlbWVudHMgQ29udGFpbmVyIHsKCiAgICAgICAgLyoqCiAgICAgICAgICogSW5zZXJ0IGFsbCBmaWxlcyBpbiBhIHN1YmRpcmVjdG9yeSBvZiB0aGUgcGxhdGZvcm0gaW1hZ2UKICAgICAgICAgKiB3aGljaCBtYXRjaCBmaWxlS2luZHMgaW50byByZXN1bHRMaXN0LgogICAgICAgICAqLwogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIGxpc3QoUGF0aCB1c2VyUGF0aCwKICAgICAgICAgICAgICAgICAgICAgICAgIFJlbGF0aXZlRGlyZWN0b3J5IHN1YmRpcmVjdG9yeSwKICAgICAgICAgICAgICAgICAgICAgICAgIFNldDxKYXZhRmlsZU9iamVjdC5LaW5kPiBmaWxlS2luZHMsCiAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIHJlY3Vyc2UsCiAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0QnVmZmVyPEphdmFGaWxlT2JqZWN0PiByZXN1bHRMaXN0KSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgSlJUSW5kZXguRW50cnkgZSA9IGdldEpSVEluZGV4KCkuZ2V0RW50cnkoc3ViZGlyZWN0b3J5KTsKICAgICAgICAgICAgICAgIGlmIChzeW1ib2xGaWxlRW5hYmxlZCAmJiBlLmN0U3ltLmhpZGRlbikKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICBmb3IgKFBhdGggZmlsZTogZS5maWxlcy52YWx1ZXMoKSkgewogICAgICAgICAgICAgICAgICAgIGlmIChmaWxlS2luZHMuY29udGFpbnMoZ2V0S2luZChmaWxlKSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgSmF2YUZpbGVPYmplY3QgZmUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IFBhdGhGaWxlT2JqZWN0LmZvckpSVFBhdGgoSmF2YWNGaWxlTWFuYWdlci50aGlzLCBmaWxlKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0TGlzdC5hcHBlbmQoZmUpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAocmVjdXJzZSkgewogICAgICAgICAgICAgICAgICAgIGZvciAoUmVsYXRpdmVEaXJlY3RvcnkgcmQ6IGUuc3ViZGlycykgewogICAgICAgICAgICAgICAgICAgICAgICBsaXN0KHVzZXJQYXRoLCByZCwgZmlsZUtpbmRzLCByZWN1cnNlLCByZXN1bHRMaXN0KTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7CiAgICAgICAgICAgICAgICBleC5wcmludFN0YWNrVHJhY2UoU3lzdGVtLmVycik7CiAgICAgICAgICAgICAgICBsb2cuZXJyb3IoImVycm9yLnJlYWRpbmcuZmlsZSIsIHVzZXJQYXRoLCBnZXRNZXNzYWdlKGV4KSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBKYXZhRmlsZU9iamVjdCBnZXRGaWxlT2JqZWN0KFBhdGggdXNlclBhdGgsIFJlbGF0aXZlRmlsZSBuYW1lKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgICAgICBKUlRJbmRleC5FbnRyeSBlID0gZ2V0SlJUSW5kZXgoKS5nZXRFbnRyeShuYW1lLmRpcm5hbWUoKSk7CiAgICAgICAgICAgIGlmIChzeW1ib2xGaWxlRW5hYmxlZCAmJiBlLmN0U3ltLmhpZGRlbikKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICBQYXRoIHAgPSBlLmZpbGVzLmdldChuYW1lLmJhc2VuYW1lKCkpOwogICAgICAgICAgICBpZiAocCAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gUGF0aEZpbGVPYmplY3QuZm9ySlJUUGF0aChKYXZhY0ZpbGVNYW5hZ2VyLnRoaXMsIHApOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICB9CiAgICB9CgogICAgcHJpdmF0ZSBzeW5jaHJvbml6ZWQgSlJUSW5kZXggZ2V0SlJUSW5kZXgoKSB7CiAgICAgICAgaWYgKGpydEluZGV4ID09IG51bGwpCiAgICAgICAgICAgIGpydEluZGV4ID0gSlJUSW5kZXguZ2V0U2hhcmVkSW5zdGFuY2UoKTsKICAgICAgICByZXR1cm4ganJ0SW5kZXg7CiAgICB9CgogICAgcHJpdmF0ZSBKUlRJbmRleCBqcnRJbmRleDsKCiAgICBwcml2YXRlIGZpbmFsIGNsYXNzIERpcmVjdG9yeUNvbnRhaW5lciBpbXBsZW1lbnRzIENvbnRhaW5lciB7CiAgICAgICAgcHJpdmF0ZSBmaW5hbCBQYXRoIGRpcmVjdG9yeTsKCiAgICAgICAgcHVibGljIERpcmVjdG9yeUNvbnRhaW5lcihQYXRoIGRpcmVjdG9yeSkgewogICAgICAgICAgICB0aGlzLmRpcmVjdG9yeSA9IGRpcmVjdG9yeTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIEluc2VydCBhbGwgZmlsZXMgaW4gc3ViZGlyZWN0b3J5IHN1YmRpcmVjdG9yeSBvZiBkaXJlY3RvcnkgdXNlclBhdGgKICAgICAgICAgKiB3aGljaCBtYXRjaCBmaWxlS2luZHMgaW50byByZXN1bHRMaXN0CiAgICAgICAgICovCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgbGlzdChQYXRoIHVzZXJQYXRoLAogICAgICAgICAgICAgICAgICAgICAgICAgUmVsYXRpdmVEaXJlY3Rvcnkgc3ViZGlyZWN0b3J5LAogICAgICAgICAgICAgICAgICAgICAgICAgU2V0PEphdmFGaWxlT2JqZWN0LktpbmQ+IGZpbGVLaW5kcywKICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gcmVjdXJzZSwKICAgICAgICAgICAgICAgICAgICAgICAgIExpc3RCdWZmZXI8SmF2YUZpbGVPYmplY3Q+IHJlc3VsdExpc3QpIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgICAgIFBhdGggZDsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIGQgPSBzdWJkaXJlY3RvcnkucmVzb2x2ZUFnYWluc3QodXNlclBhdGgpOwogICAgICAgICAgICB9IGNhdGNoIChJbnZhbGlkUGF0aEV4Y2VwdGlvbiBpZ25vcmUpIHsKICAgICAgICAgICAgICAgIHJldHVybiA7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICghRmlsZXMuZXhpc3RzKGQpKSB7CiAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCFjYXNlTWFwQ2hlY2soZCwgc3ViZGlyZWN0b3J5KSkgewogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CgogICAgICAgICAgICBqYXZhLnV0aWwuTGlzdDxQYXRoPiBmaWxlczsKICAgICAgICAgICAgdHJ5IChTdHJlYW08UGF0aD4gcyA9IEZpbGVzLmxpc3QoZCkpIHsKICAgICAgICAgICAgICAgIGZpbGVzID0gKHNvcnRGaWxlcyA9PSBudWxsID8gcyA6IHMuc29ydGVkKHNvcnRGaWxlcykpLmNvbGxlY3QoQ29sbGVjdG9ycy50b0xpc3QoKSk7CiAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGlnbm9yZSkgewogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CgogICAgICAgICAgICBmb3IgKFBhdGggZjogZmlsZXMpIHsKICAgICAgICAgICAgICAgIFN0cmluZyBmbmFtZSA9IGYuZ2V0RmlsZU5hbWUoKS50b1N0cmluZygpOwogICAgICAgICAgICAgICAgaWYgKGZuYW1lLmVuZHNXaXRoKCIvIikpCiAgICAgICAgICAgICAgICAgICAgZm5hbWUgPSBmbmFtZS5zdWJzdHJpbmcoMCwgZm5hbWUubGVuZ3RoKCkgLSAxKTsKICAgICAgICAgICAgICAgIGlmIChGaWxlcy5pc0RpcmVjdG9yeShmKSkgewogICAgICAgICAgICAgICAgICAgIGlmIChyZWN1cnNlICYmIFNvdXJjZVZlcnNpb24uaXNJZGVudGlmaWVyKGZuYW1lKSkgewogICAgICAgICAgICAgICAgICAgICAgICBsaXN0KHVzZXJQYXRoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBSZWxhdGl2ZURpcmVjdG9yeShzdWJkaXJlY3RvcnksIGZuYW1lKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlS2luZHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVjdXJzZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHRMaXN0KTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGlmIChpc1ZhbGlkRmlsZShmbmFtZSwgZmlsZUtpbmRzKSkgewogICAgICAgICAgICAgICAgICAgICAgICBSZWxhdGl2ZUZpbGUgZmlsZSA9IG5ldyBSZWxhdGl2ZUZpbGUoc3ViZGlyZWN0b3J5LCBmbmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIEphdmFGaWxlT2JqZWN0IGZlID0gUGF0aEZpbGVPYmplY3QuZm9yRGlyZWN0b3J5UGF0aChKYXZhY0ZpbGVNYW5hZ2VyLnRoaXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZS5yZXNvbHZlQWdhaW5zdChkaXJlY3RvcnkpLCB1c2VyUGF0aCwgZmlsZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdExpc3QuYXBwZW5kKGZlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBKYXZhRmlsZU9iamVjdCBnZXRGaWxlT2JqZWN0KFBhdGggdXNlclBhdGgsIFJlbGF0aXZlRmlsZSBuYW1lKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgUGF0aCBmID0gbmFtZS5yZXNvbHZlQWdhaW5zdCh1c2VyUGF0aCk7CiAgICAgICAgICAgICAgICBpZiAoRmlsZXMuZXhpc3RzKGYpKQogICAgICAgICAgICAgICAgICAgIHJldHVybiBQYXRoRmlsZU9iamVjdC5mb3JTaW1wbGVQYXRoKEphdmFjRmlsZU1hbmFnZXIudGhpcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZzSW5mby5nZXRDYW5vbmljYWxGaWxlKGYpLCBmKTsKICAgICAgICAgICAgfSBjYXRjaCAoSW52YWxpZFBhdGhFeGNlcHRpb24gaWdub3JlKSB7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgZmluYWwgY2xhc3MgQXJjaGl2ZUNvbnRhaW5lciBpbXBsZW1lbnRzIENvbnRhaW5lciB7CiAgICAgICAgcHJpdmF0ZSBmaW5hbCBQYXRoIGFyY2hpdmVQYXRoOwogICAgICAgIHByaXZhdGUgZmluYWwgRmlsZVN5c3RlbSBmaWxlU3lzdGVtOwogICAgICAgIHByaXZhdGUgZmluYWwgTWFwPFJlbGF0aXZlUGF0aCwgUGF0aD4gcGFja2FnZXM7CgogICAgICAgIHB1YmxpYyBBcmNoaXZlQ29udGFpbmVyKFBhdGggYXJjaGl2ZVBhdGgpIHRocm93cyBJT0V4Y2VwdGlvbiwgUHJvdmlkZXJOb3RGb3VuZEV4Y2VwdGlvbiwgU2VjdXJpdHlFeGNlcHRpb24gewogICAgICAgICAgICB0aGlzLmFyY2hpdmVQYXRoID0gYXJjaGl2ZVBhdGg7CiAgICAgICAgICAgIGlmIChtdWx0aVJlbGVhc2VWYWx1ZSAhPSBudWxsICYmIGFyY2hpdmVQYXRoLnRvU3RyaW5nKCkuZW5kc1dpdGgoIi5qYXIiKSkgewogICAgICAgICAgICAgICAgTWFwPFN0cmluZyxTdHJpbmc+IGVudiA9IENvbGxlY3Rpb25zLnNpbmdsZXRvbk1hcCgibXVsdGktcmVsZWFzZSIsIG11bHRpUmVsZWFzZVZhbHVlKTsKICAgICAgICAgICAgICAgIEZpbGVTeXN0ZW1Qcm92aWRlciBqYXJGU1Byb3ZpZGVyID0gZnNJbmZvLmdldEphckZTUHJvdmlkZXIoKTsKICAgICAgICAgICAgICAgIEFzc2VydC5jaGVja05vbk51bGwoamFyRlNQcm92aWRlciwgInNob3VsZCBoYXZlIGJlZW4gY2F1Z2h0IGJlZm9yZSEiKTsKICAgICAgICAgICAgICAgIHRoaXMuZmlsZVN5c3RlbSA9IGphckZTUHJvdmlkZXIubmV3RmlsZVN5c3RlbShhcmNoaXZlUGF0aCwgZW52KTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHRoaXMuZmlsZVN5c3RlbSA9IEZpbGVTeXN0ZW1zLm5ld0ZpbGVTeXN0ZW0oYXJjaGl2ZVBhdGgsIG51bGwpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHBhY2thZ2VzID0gbmV3IEhhc2hNYXA8PigpOwogICAgICAgICAgICBmb3IgKFBhdGggcm9vdCA6IGZpbGVTeXN0ZW0uZ2V0Um9vdERpcmVjdG9yaWVzKCkpIHsKICAgICAgICAgICAgICAgIEZpbGVzLndhbGtGaWxlVHJlZShyb290LCBFbnVtU2V0Lm5vbmVPZihGaWxlVmlzaXRPcHRpb24uY2xhc3MpLCBJbnRlZ2VyLk1BWF9WQUxVRSwKICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFNpbXBsZUZpbGVWaXNpdG9yPFBhdGg+KCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwdWJsaWMgRmlsZVZpc2l0UmVzdWx0IHByZVZpc2l0RGlyZWN0b3J5KFBhdGggZGlyLCBCYXNpY0ZpbGVBdHRyaWJ1dGVzIGF0dHJzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzVmFsaWQoZGlyLmdldEZpbGVOYW1lKCkpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhY2thZ2VzLnB1dChuZXcgUmVsYXRpdmVEaXJlY3Rvcnkocm9vdC5yZWxhdGl2aXplKGRpcikudG9TdHJpbmcoKSksIGRpcik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBGaWxlVmlzaXRSZXN1bHQuQ09OVElOVUU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEZpbGVWaXNpdFJlc3VsdC5TS0lQX1NVQlRSRUU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogSW5zZXJ0IGFsbCBmaWxlcyBpbiBzdWJkaXJlY3Rvcnkgc3ViZGlyZWN0b3J5IG9mIHRoaXMgYXJjaGl2ZQogICAgICAgICAqIHdoaWNoIG1hdGNoIGZpbGVLaW5kcyBpbnRvIHJlc3VsdExpc3QKICAgICAgICAgKi8KICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCBsaXN0KFBhdGggdXNlclBhdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICBSZWxhdGl2ZURpcmVjdG9yeSBzdWJkaXJlY3RvcnksCiAgICAgICAgICAgICAgICAgICAgICAgICBTZXQ8SmF2YUZpbGVPYmplY3QuS2luZD4gZmlsZUtpbmRzLAogICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiByZWN1cnNlLAogICAgICAgICAgICAgICAgICAgICAgICAgTGlzdEJ1ZmZlcjxKYXZhRmlsZU9iamVjdD4gcmVzdWx0TGlzdCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICAgICAgUGF0aCByZXNvbHZlZFN1YmRpcmVjdG9yeSA9IHBhY2thZ2VzLmdldChzdWJkaXJlY3RvcnkpOwoKICAgICAgICAgICAgaWYgKHJlc29sdmVkU3ViZGlyZWN0b3J5ID09IG51bGwpCiAgICAgICAgICAgICAgICByZXR1cm4gOwoKICAgICAgICAgICAgaW50IG1heERlcHRoID0gKHJlY3Vyc2UgPyBJbnRlZ2VyLk1BWF9WQUxVRSA6IDEpOwogICAgICAgICAgICBTZXQ8RmlsZVZpc2l0T3B0aW9uPiBvcHRzID0gRW51bVNldC5vZihGT0xMT1dfTElOS1MpOwogICAgICAgICAgICBGaWxlcy53YWxrRmlsZVRyZWUocmVzb2x2ZWRTdWJkaXJlY3RvcnksIG9wdHMsIG1heERlcHRoLAogICAgICAgICAgICAgICAgICAgIG5ldyBTaW1wbGVGaWxlVmlzaXRvcjxQYXRoPigpIHsKICAgICAgICAgICAgICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgICAgICAgICAgICAgIHB1YmxpYyBGaWxlVmlzaXRSZXN1bHQgcHJlVmlzaXREaXJlY3RvcnkoUGF0aCBkaXIsIEJhc2ljRmlsZUF0dHJpYnV0ZXMgYXR0cnMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc1ZhbGlkKGRpci5nZXRGaWxlTmFtZSgpKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBGaWxlVmlzaXRSZXN1bHQuQ09OVElOVUU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBGaWxlVmlzaXRSZXN1bHQuU0tJUF9TVUJUUkVFOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgICAgICAgICAgICAgcHVibGljIEZpbGVWaXNpdFJlc3VsdCB2aXNpdEZpbGUoUGF0aCBmaWxlLCBCYXNpY0ZpbGVBdHRyaWJ1dGVzIGF0dHJzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXR0cnMuaXNSZWd1bGFyRmlsZSgpICYmIGZpbGVLaW5kcy5jb250YWlucyhnZXRLaW5kKGZpbGUuZ2V0RmlsZU5hbWUoKS50b1N0cmluZygpKSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBKYXZhRmlsZU9iamVjdCBmZSA9IFBhdGhGaWxlT2JqZWN0LmZvckphclBhdGgoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBKYXZhY0ZpbGVNYW5hZ2VyLnRoaXMsIGZpbGUsIGFyY2hpdmVQYXRoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHRMaXN0LmFwcGVuZChmZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gRmlsZVZpc2l0UmVzdWx0LkNPTlRJTlVFOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSk7CgogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBib29sZWFuIGlzVmFsaWQoUGF0aCBmaWxlTmFtZSkgewogICAgICAgICAgICBpZiAoZmlsZU5hbWUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBTdHJpbmcgbmFtZSA9IGZpbGVOYW1lLnRvU3RyaW5nKCk7CiAgICAgICAgICAgICAgICBpZiAobmFtZS5lbmRzV2l0aCgiLyIpKSB7CiAgICAgICAgICAgICAgICAgICAgbmFtZSA9IG5hbWUuc3Vic3RyaW5nKDAsIG5hbWUubGVuZ3RoKCkgLSAxKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBTb3VyY2VWZXJzaW9uLmlzSWRlbnRpZmllcihuYW1lKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIEphdmFGaWxlT2JqZWN0IGdldEZpbGVPYmplY3QoUGF0aCB1c2VyUGF0aCwgUmVsYXRpdmVGaWxlIG5hbWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgICAgIFJlbGF0aXZlRGlyZWN0b3J5IHJvb3QgPSBuYW1lLmRpcm5hbWUoKTsKICAgICAgICAgICAgUGF0aCBwYWNrYWdlcGF0aCA9IHBhY2thZ2VzLmdldChyb290KTsKICAgICAgICAgICAgaWYgKHBhY2thZ2VwYXRoICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIFBhdGggcmVscGF0aCA9IHBhY2thZ2VwYXRoLnJlc29sdmUobmFtZS5iYXNlbmFtZSgpKTsKICAgICAgICAgICAgICAgIGlmIChGaWxlcy5leGlzdHMocmVscGF0aCkpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gUGF0aEZpbGVPYmplY3QuZm9ySmFyUGF0aChKYXZhY0ZpbGVNYW5hZ2VyLnRoaXMsIHJlbHBhdGgsIHVzZXJQYXRoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICAgICAgZmlsZVN5c3RlbS5jbG9zZSgpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIGNvbnRhaW5lciBpcyBhIGRpcmVjdG9yeSwgYSB6aXAgZmlsZSwgb3IgYSBub24tZXhpc3RlbnQgcGF0aC4KICAgICAqLwogICAgcHJpdmF0ZSBib29sZWFuIGlzVmFsaWRGaWxlKFN0cmluZyBzLCBTZXQ8SmF2YUZpbGVPYmplY3QuS2luZD4gZmlsZUtpbmRzKSB7CiAgICAgICAgSmF2YUZpbGVPYmplY3QuS2luZCBraW5kID0gZ2V0S2luZChzKTsKICAgICAgICByZXR1cm4gZmlsZUtpbmRzLmNvbnRhaW5zKGtpbmQpOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW4gZmlsZVN5c3RlbUlzQ2FzZVNlbnNpdGl2ZSA9CiAgICAgICAgRmlsZS5zZXBhcmF0b3JDaGFyID09ICcvJzsKCiAgICAvKiogSGFjayB0byBtYWtlIFdpbmRvd3MgY2FzZSBzZW5zaXRpdmUuIFRlc3Qgd2hldGhlciBnaXZlbiBwYXRoCiAgICAgKiAgZW5kcyBpbiBhIHN0cmluZyBvZiBjaGFyYWN0ZXJzIHdpdGggdGhlIHNhbWUgY2FzZSBhcyBnaXZlbiBuYW1lLgogICAgICogIElnbm9yZSBmaWxlIHNlcGFyYXRvcnMgaW4gYm90aCBwYXRoIGFuZCBuYW1lLgogICAgICovCiAgICBwcml2YXRlIGJvb2xlYW4gY2FzZU1hcENoZWNrKFBhdGggZiwgUmVsYXRpdmVQYXRoIG5hbWUpIHsKICAgICAgICBpZiAoZmlsZVN5c3RlbUlzQ2FzZVNlbnNpdGl2ZSkgcmV0dXJuIHRydWU7CiAgICAgICAgLy8gTm90ZSB0aGF0IHRvUmVhbFBhdGgoKSByZXR1cm5zIHRoZSBjYXNlLXNlbnNpdGl2ZQogICAgICAgIC8vIHNwZWxsZWQgZmlsZSBuYW1lLgogICAgICAgIFN0cmluZyBwYXRoOwogICAgICAgIGNoYXIgc2VwOwogICAgICAgIHRyeSB7CiAgICAgICAgICAgIHBhdGggPSBmLnRvUmVhbFBhdGgoTGlua09wdGlvbi5OT0ZPTExPV19MSU5LUykudG9TdHJpbmcoKTsKICAgICAgICAgICAgc2VwID0gZi5nZXRGaWxlU3lzdGVtKCkuZ2V0U2VwYXJhdG9yKCkuY2hhckF0KDApOwogICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgY2hhcltdIHBjcyA9IHBhdGgudG9DaGFyQXJyYXkoKTsKICAgICAgICBjaGFyW10gbmNzID0gbmFtZS5wYXRoLnRvQ2hhckFycmF5KCk7CiAgICAgICAgaW50IGkgPSBwY3MubGVuZ3RoIC0gMTsKICAgICAgICBpbnQgaiA9IG5jcy5sZW5ndGggLSAxOwogICAgICAgIHdoaWxlIChpID49IDAgJiYgaiA+PSAwKSB7CiAgICAgICAgICAgIHdoaWxlIChpID49IDAgJiYgcGNzW2ldID09IHNlcCkgaS0tOwogICAgICAgICAgICB3aGlsZSAoaiA+PSAwICYmIG5jc1tqXSA9PSAnLycpIGotLTsKICAgICAgICAgICAgaWYgKGkgPj0gMCAmJiBqID49IDApIHsKICAgICAgICAgICAgICAgIGlmIChwY3NbaV0gIT0gbmNzW2pdKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICBpLS07CiAgICAgICAgICAgICAgICBqLS07CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIGogPCAwOwogICAgfQoKICAgIC8qKiBGbHVzaCBhbnkgb3V0cHV0IHJlc291cmNlcy4KICAgICAqLwogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSKQogICAgcHVibGljIHZvaWQgZmx1c2goKSB7CiAgICAgICAgY29udGVudENhY2hlLmNsZWFyKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDbG9zZSB0aGUgSmF2YUZpbGVNYW5hZ2VyLCByZWxlYXNpbmcgcmVzb3VyY2VzLgogICAgICovCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGRlZmVycmVkQ2xvc2VUaW1lb3V0ID4gMCkgewogICAgICAgICAgICBkZWZlcnJlZENsb3NlKCk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIGxvY2F0aW9ucy5jbG9zZSgpOwogICAgICAgIGZvciAoQ29udGFpbmVyIGNvbnRhaW5lcjogY29udGFpbmVycy52YWx1ZXMoKSkgewogICAgICAgICAgICBjb250YWluZXIuY2xvc2UoKTsKICAgICAgICB9CiAgICAgICAgY29udGFpbmVycy5jbGVhcigpOwogICAgICAgIGNvbnRlbnRDYWNoZS5jbGVhcigpOwogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgIHB1YmxpYyBDbGFzc0xvYWRlciBnZXRDbGFzc0xvYWRlcihMb2NhdGlvbiBsb2NhdGlvbikgewogICAgICAgIGNoZWNrTm90TW9kdWxlT3JpZW50ZWRMb2NhdGlvbihsb2NhdGlvbik7CiAgICAgICAgSXRlcmFibGU8PyBleHRlbmRzIEZpbGU+IHBhdGggPSBnZXRMb2NhdGlvbihsb2NhdGlvbik7CiAgICAgICAgaWYgKHBhdGggPT0gbnVsbCkKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgTGlzdEJ1ZmZlcjxVUkw+IGxiID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgIGZvciAoRmlsZSBmOiBwYXRoKSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBsYi5hcHBlbmQoZi50b1VSSSgpLnRvVVJMKCkpOwogICAgICAgICAgICB9IGNhdGNoIChNYWxmb3JtZWRVUkxFeGNlcHRpb24gZSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKGUpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gZ2V0Q2xhc3NMb2FkZXIobGIudG9BcnJheShuZXcgVVJMW2xiLnNpemUoKV0pKTsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICBwdWJsaWMgSXRlcmFibGU8SmF2YUZpbGVPYmplY3Q+IGxpc3QoTG9jYXRpb24gbG9jYXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHBhY2thZ2VOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNldDxKYXZhRmlsZU9iamVjdC5LaW5kPiBraW5kcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIHJlY3Vyc2UpCiAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uCiAgICB7CiAgICAgICAgY2hlY2tOb3RNb2R1bGVPcmllbnRlZExvY2F0aW9uKGxvY2F0aW9uKTsKICAgICAgICAvLyB2YWxpZGF0ZVBhY2thZ2VOYW1lKHBhY2thZ2VOYW1lKTsKICAgICAgICBudWxsQ2hlY2socGFja2FnZU5hbWUpOwogICAgICAgIG51bGxDaGVjayhraW5kcyk7CgogICAgICAgIEl0ZXJhYmxlPD8gZXh0ZW5kcyBQYXRoPiBwYXRoID0gZ2V0TG9jYXRpb25Bc1BhdGhzKGxvY2F0aW9uKTsKICAgICAgICBpZiAocGF0aCA9PSBudWxsKQogICAgICAgICAgICByZXR1cm4gTGlzdC5uaWwoKTsKICAgICAgICBSZWxhdGl2ZURpcmVjdG9yeSBzdWJkaXJlY3RvcnkgPSBSZWxhdGl2ZURpcmVjdG9yeS5mb3JQYWNrYWdlKHBhY2thZ2VOYW1lKTsKICAgICAgICBMaXN0QnVmZmVyPEphdmFGaWxlT2JqZWN0PiByZXN1bHRzID0gbmV3IExpc3RCdWZmZXI8PigpOwoKICAgICAgICBmb3IgKFBhdGggZGlyZWN0b3J5IDogcGF0aCkgewogICAgICAgICAgICBDb250YWluZXIgY29udGFpbmVyID0gZ2V0Q29udGFpbmVyKGRpcmVjdG9yeSk7CgogICAgICAgICAgICBjb250YWluZXIubGlzdChkaXJlY3RvcnksIHN1YmRpcmVjdG9yeSwga2luZHMsIHJlY3Vyc2UsIHJlc3VsdHMpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHJlc3VsdHMudG9MaXN0KCk7CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSKQogICAgcHVibGljIFN0cmluZyBpbmZlckJpbmFyeU5hbWUoTG9jYXRpb24gbG9jYXRpb24sIEphdmFGaWxlT2JqZWN0IGZpbGUpIHsKICAgICAgICBjaGVja05vdE1vZHVsZU9yaWVudGVkTG9jYXRpb24obG9jYXRpb24pOwogICAgICAgIE9iamVjdHMucmVxdWlyZU5vbk51bGwoZmlsZSk7CiAgICAgICAgLy8gTmVlZCB0byBtYXRjaCB0aGUgcGF0aCBzZW1hbnRpY3Mgb2YgbGlzdChsb2NhdGlvbiwgLi4uKQogICAgICAgIEl0ZXJhYmxlPD8gZXh0ZW5kcyBQYXRoPiBwYXRoID0gZ2V0TG9jYXRpb25Bc1BhdGhzKGxvY2F0aW9uKTsKICAgICAgICBpZiAocGF0aCA9PSBudWxsKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgaWYgKGZpbGUgaW5zdGFuY2VvZiBQYXRoRmlsZU9iamVjdCkgewogICAgICAgICAgICByZXR1cm4gKChQYXRoRmlsZU9iamVjdCkgZmlsZSkuaW5mZXJCaW5hcnlOYW1lKHBhdGgpOwogICAgICAgIH0gZWxzZQogICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKGZpbGUuZ2V0Q2xhc3MoKS5nZXROYW1lKCkpOwogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgIHB1YmxpYyBib29sZWFuIGlzU2FtZUZpbGUoRmlsZU9iamVjdCBhLCBGaWxlT2JqZWN0IGIpIHsKICAgICAgICBudWxsQ2hlY2soYSk7CiAgICAgICAgbnVsbENoZWNrKGIpOwogICAgICAgIGlmIChhIGluc3RhbmNlb2YgUGF0aEZpbGVPYmplY3QgJiYgYiBpbnN0YW5jZW9mIFBhdGhGaWxlT2JqZWN0KQogICAgICAgICAgICByZXR1cm4gKChQYXRoRmlsZU9iamVjdCkgYSkuaXNTYW1lRmlsZSgoUGF0aEZpbGVPYmplY3QpIGIpOwogICAgICAgIHJldHVybiBhLmVxdWFscyhiKTsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb2NhdGlvbihMb2NhdGlvbiBsb2NhdGlvbikgewogICAgICAgIG51bGxDaGVjayhsb2NhdGlvbik7CiAgICAgICAgcmV0dXJuIGxvY2F0aW9ucy5oYXNMb2NhdGlvbihsb2NhdGlvbik7CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSKQogICAgcHVibGljIEphdmFGaWxlT2JqZWN0IGdldEphdmFGaWxlRm9ySW5wdXQoTG9jYXRpb24gbG9jYXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgY2xhc3NOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSmF2YUZpbGVPYmplY3QuS2luZCBraW5kKQogICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbgogICAgewogICAgICAgIGNoZWNrTm90TW9kdWxlT3JpZW50ZWRMb2NhdGlvbihsb2NhdGlvbik7CiAgICAgICAgLy8gdmFsaWRhdGVDbGFzc05hbWUoY2xhc3NOYW1lKTsKICAgICAgICBudWxsQ2hlY2soY2xhc3NOYW1lKTsKICAgICAgICBudWxsQ2hlY2soa2luZCk7CiAgICAgICAgaWYgKCFzb3VyY2VPckNsYXNzLmNvbnRhaW5zKGtpbmQpKQogICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJJbnZhbGlkIGtpbmQ6ICIgKyBraW5kKTsKICAgICAgICByZXR1cm4gZ2V0RmlsZUZvcklucHV0KGxvY2F0aW9uLCBSZWxhdGl2ZUZpbGUuZm9yQ2xhc3MoY2xhc3NOYW1lLCBraW5kKSk7CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSKQogICAgcHVibGljIEZpbGVPYmplY3QgZ2V0RmlsZUZvcklucHV0KExvY2F0aW9uIGxvY2F0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBwYWNrYWdlTmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcmVsYXRpdmVOYW1lKQogICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbgogICAgewogICAgICAgIGNoZWNrTm90TW9kdWxlT3JpZW50ZWRMb2NhdGlvbihsb2NhdGlvbik7CiAgICAgICAgLy8gdmFsaWRhdGVQYWNrYWdlTmFtZShwYWNrYWdlTmFtZSk7CiAgICAgICAgbnVsbENoZWNrKHBhY2thZ2VOYW1lKTsKICAgICAgICBpZiAoIWlzUmVsYXRpdmVVcmkocmVsYXRpdmVOYW1lKSkKICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiSW52YWxpZCByZWxhdGl2ZSBuYW1lOiAiICsgcmVsYXRpdmVOYW1lKTsKICAgICAgICBSZWxhdGl2ZUZpbGUgbmFtZSA9IHBhY2thZ2VOYW1lLmxlbmd0aCgpID09IDAKICAgICAgICAgICAgPyBuZXcgUmVsYXRpdmVGaWxlKHJlbGF0aXZlTmFtZSkKICAgICAgICAgICAgOiBuZXcgUmVsYXRpdmVGaWxlKFJlbGF0aXZlRGlyZWN0b3J5LmZvclBhY2thZ2UocGFja2FnZU5hbWUpLCByZWxhdGl2ZU5hbWUpOwogICAgICAgIHJldHVybiBnZXRGaWxlRm9ySW5wdXQobG9jYXRpb24sIG5hbWUpOwogICAgfQoKICAgIHByaXZhdGUgSmF2YUZpbGVPYmplY3QgZ2V0RmlsZUZvcklucHV0KExvY2F0aW9uIGxvY2F0aW9uLCBSZWxhdGl2ZUZpbGUgbmFtZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICBJdGVyYWJsZTw/IGV4dGVuZHMgUGF0aD4gcGF0aCA9IGdldExvY2F0aW9uQXNQYXRocyhsb2NhdGlvbik7CiAgICAgICAgaWYgKHBhdGggPT0gbnVsbCkKICAgICAgICAgICAgcmV0dXJuIG51bGw7CgogICAgICAgIGZvciAoUGF0aCBmaWxlOiBwYXRoKSB7CiAgICAgICAgICAgIEphdmFGaWxlT2JqZWN0IGZvID0gZ2V0Q29udGFpbmVyKGZpbGUpLmdldEZpbGVPYmplY3QoZmlsZSwgbmFtZSk7CgogICAgICAgICAgICBpZiAoZm8gIT0gbnVsbCkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZvOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgIHB1YmxpYyBKYXZhRmlsZU9iamVjdCBnZXRKYXZhRmlsZUZvck91dHB1dChMb2NhdGlvbiBsb2NhdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgY2xhc3NOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEphdmFGaWxlT2JqZWN0LktpbmQga2luZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGaWxlT2JqZWN0IHNpYmxpbmcpCiAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uCiAgICB7CiAgICAgICAgY2hlY2tPdXRwdXRMb2NhdGlvbihsb2NhdGlvbik7CiAgICAgICAgLy8gdmFsaWRhdGVDbGFzc05hbWUoY2xhc3NOYW1lKTsKICAgICAgICBudWxsQ2hlY2soY2xhc3NOYW1lKTsKICAgICAgICBudWxsQ2hlY2soa2luZCk7CiAgICAgICAgaWYgKCFzb3VyY2VPckNsYXNzLmNvbnRhaW5zKGtpbmQpKQogICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJJbnZhbGlkIGtpbmQ6ICIgKyBraW5kKTsKICAgICAgICByZXR1cm4gZ2V0RmlsZUZvck91dHB1dChsb2NhdGlvbiwgUmVsYXRpdmVGaWxlLmZvckNsYXNzKGNsYXNzTmFtZSwga2luZCksIHNpYmxpbmcpOwogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgIHB1YmxpYyBGaWxlT2JqZWN0IGdldEZpbGVGb3JPdXRwdXQoTG9jYXRpb24gbG9jYXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBwYWNrYWdlTmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHJlbGF0aXZlTmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmlsZU9iamVjdCBzaWJsaW5nKQogICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbgogICAgewogICAgICAgIGNoZWNrT3V0cHV0TG9jYXRpb24obG9jYXRpb24pOwogICAgICAgIC8vIHZhbGlkYXRlUGFja2FnZU5hbWUocGFja2FnZU5hbWUpOwogICAgICAgIG51bGxDaGVjayhwYWNrYWdlTmFtZSk7CiAgICAgICAgaWYgKCFpc1JlbGF0aXZlVXJpKHJlbGF0aXZlTmFtZSkpCiAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkludmFsaWQgcmVsYXRpdmUgbmFtZTogIiArIHJlbGF0aXZlTmFtZSk7CiAgICAgICAgUmVsYXRpdmVGaWxlIG5hbWUgPSBwYWNrYWdlTmFtZS5sZW5ndGgoKSA9PSAwCiAgICAgICAgICAgID8gbmV3IFJlbGF0aXZlRmlsZShyZWxhdGl2ZU5hbWUpCiAgICAgICAgICAgIDogbmV3IFJlbGF0aXZlRmlsZShSZWxhdGl2ZURpcmVjdG9yeS5mb3JQYWNrYWdlKHBhY2thZ2VOYW1lKSwgcmVsYXRpdmVOYW1lKTsKICAgICAgICByZXR1cm4gZ2V0RmlsZUZvck91dHB1dChsb2NhdGlvbiwgbmFtZSwgc2libGluZyk7CiAgICB9CgogICAgcHJpdmF0ZSBKYXZhRmlsZU9iamVjdCBnZXRGaWxlRm9yT3V0cHV0KExvY2F0aW9uIGxvY2F0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlbGF0aXZlRmlsZSBmaWxlTmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGaWxlT2JqZWN0IHNpYmxpbmcpCiAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uCiAgICB7CiAgICAgICAgUGF0aCBkaXI7CiAgICAgICAgaWYgKGxvY2F0aW9uID09IENMQVNTX09VVFBVVCkgewogICAgICAgICAgICBpZiAoZ2V0Q2xhc3NPdXREaXIoKSAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICBkaXIgPSBnZXRDbGFzc091dERpcigpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgU3RyaW5nIGJhc2VOYW1lID0gZmlsZU5hbWUuYmFzZW5hbWUoKTsKICAgICAgICAgICAgICAgIGlmIChzaWJsaW5nICE9IG51bGwgJiYgc2libGluZyBpbnN0YW5jZW9mIFBhdGhGaWxlT2JqZWN0KSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICgoUGF0aEZpbGVPYmplY3QpIHNpYmxpbmcpLmdldFNpYmxpbmcoYmFzZU5hbWUpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBQYXRoIHAgPSBnZXRQYXRoKGJhc2VOYW1lKTsKICAgICAgICAgICAgICAgICAgICBQYXRoIHJlYWwgPSBmc0luZm8uZ2V0Q2Fub25pY2FsRmlsZShwKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gUGF0aEZpbGVPYmplY3QuZm9yU2ltcGxlUGF0aCh0aGlzLCByZWFsLCBwKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSBpZiAobG9jYXRpb24gPT0gU09VUkNFX09VVFBVVCkgewogICAgICAgICAgICBkaXIgPSAoZ2V0U291cmNlT3V0RGlyKCkgIT0gbnVsbCA/IGdldFNvdXJjZU91dERpcigpIDogZ2V0Q2xhc3NPdXREaXIoKSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgSXRlcmFibGU8PyBleHRlbmRzIFBhdGg+IHBhdGggPSBsb2NhdGlvbnMuZ2V0TG9jYXRpb24obG9jYXRpb24pOwogICAgICAgICAgICBkaXIgPSBudWxsOwogICAgICAgICAgICBmb3IgKFBhdGggZjogcGF0aCkgewogICAgICAgICAgICAgICAgZGlyID0gZjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICB0cnkgewogICAgICAgICAgICBpZiAoZGlyID09IG51bGwpIHsKICAgICAgICAgICAgICAgIGRpciA9IGdldFBhdGgoU3lzdGVtLmdldFByb3BlcnR5KCJ1c2VyLmRpciIpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBQYXRoIHBhdGggPSBmaWxlTmFtZS5yZXNvbHZlQWdhaW5zdChmc0luZm8uZ2V0Q2Fub25pY2FsRmlsZShkaXIpKTsKICAgICAgICAgICAgcmV0dXJuIFBhdGhGaWxlT2JqZWN0LmZvckRpcmVjdG9yeVBhdGgodGhpcywgcGF0aCwgZGlyLCBmaWxlTmFtZSk7CiAgICAgICAgfSBjYXRjaCAoSW52YWxpZFBhdGhFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oImJhZCBmaWxlbmFtZSAiICsgZmlsZU5hbWUsIGUpOwogICAgICAgIH0KICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICBwdWJsaWMgSXRlcmFibGU8PyBleHRlbmRzIEphdmFGaWxlT2JqZWN0PiBnZXRKYXZhRmlsZU9iamVjdHNGcm9tRmlsZXMoCiAgICAgICAgSXRlcmFibGU8PyBleHRlbmRzIEZpbGU+IGZpbGVzKQogICAgewogICAgICAgIEFycmF5TGlzdDxQYXRoRmlsZU9iamVjdD4gcmVzdWx0OwogICAgICAgIGlmIChmaWxlcyBpbnN0YW5jZW9mIENvbGxlY3Rpb248Pz4pCiAgICAgICAgICAgIHJlc3VsdCA9IG5ldyBBcnJheUxpc3Q8PigoKENvbGxlY3Rpb248Pz4pZmlsZXMpLnNpemUoKSk7CiAgICAgICAgZWxzZQogICAgICAgICAgICByZXN1bHQgPSBuZXcgQXJyYXlMaXN0PD4oKTsKICAgICAgICBmb3IgKEZpbGUgZjogZmlsZXMpIHsKICAgICAgICAgICAgT2JqZWN0cy5yZXF1aXJlTm9uTnVsbChmKTsKICAgICAgICAgICAgUGF0aCBwID0gZi50b1BhdGgoKTsKICAgICAgICAgICAgcmVzdWx0LmFkZChQYXRoRmlsZU9iamVjdC5mb3JTaW1wbGVQYXRoKHRoaXMsCiAgICAgICAgICAgICAgICAgICAgZnNJbmZvLmdldENhbm9uaWNhbEZpbGUocCksIHApKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICBwdWJsaWMgSXRlcmFibGU8PyBleHRlbmRzIEphdmFGaWxlT2JqZWN0PiBnZXRKYXZhRmlsZU9iamVjdHNGcm9tUGF0aHMoCiAgICAgICAgSXRlcmFibGU8PyBleHRlbmRzIFBhdGg+IHBhdGhzKQogICAgewogICAgICAgIEFycmF5TGlzdDxQYXRoRmlsZU9iamVjdD4gcmVzdWx0OwogICAgICAgIGlmIChwYXRocyBpbnN0YW5jZW9mIENvbGxlY3Rpb248Pz4pCiAgICAgICAgICAgIHJlc3VsdCA9IG5ldyBBcnJheUxpc3Q8PigoKENvbGxlY3Rpb248Pz4pcGF0aHMpLnNpemUoKSk7CiAgICAgICAgZWxzZQogICAgICAgICAgICByZXN1bHQgPSBuZXcgQXJyYXlMaXN0PD4oKTsKICAgICAgICBmb3IgKFBhdGggcDogcGF0aHMpCiAgICAgICAgICAgIHJlc3VsdC5hZGQoUGF0aEZpbGVPYmplY3QuZm9yU2ltcGxlUGF0aCh0aGlzLAogICAgICAgICAgICAgICAgICAgIGZzSW5mby5nZXRDYW5vbmljYWxGaWxlKHApLCBwKSk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICBwdWJsaWMgSXRlcmFibGU8PyBleHRlbmRzIEphdmFGaWxlT2JqZWN0PiBnZXRKYXZhRmlsZU9iamVjdHMoRmlsZS4uLiBmaWxlcykgewogICAgICAgIHJldHVybiBnZXRKYXZhRmlsZU9iamVjdHNGcm9tRmlsZXMoQXJyYXlzLmFzTGlzdChudWxsQ2hlY2soZmlsZXMpKSk7CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSKQogICAgcHVibGljIEl0ZXJhYmxlPD8gZXh0ZW5kcyBKYXZhRmlsZU9iamVjdD4gZ2V0SmF2YUZpbGVPYmplY3RzKFBhdGguLi4gcGF0aHMpIHsKICAgICAgICByZXR1cm4gZ2V0SmF2YUZpbGVPYmplY3RzRnJvbVBhdGhzKEFycmF5cy5hc0xpc3QobnVsbENoZWNrKHBhdGhzKSkpOwogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgIHB1YmxpYyB2b2lkIHNldExvY2F0aW9uKExvY2F0aW9uIGxvY2F0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgSXRlcmFibGU8PyBleHRlbmRzIEZpbGU+IHNlYXJjaHBhdGgpCiAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uCiAgICB7CiAgICAgICAgbnVsbENoZWNrKGxvY2F0aW9uKTsKICAgICAgICBsb2NhdGlvbnMuc2V0TG9jYXRpb24obG9jYXRpb24sIGFzUGF0aHMoc2VhcmNocGF0aCkpOwogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgIHB1YmxpYyB2b2lkIHNldExvY2F0aW9uRnJvbVBhdGhzKExvY2F0aW9uIGxvY2F0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29sbGVjdGlvbjw/IGV4dGVuZHMgUGF0aD4gc2VhcmNocGF0aCkKICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24KICAgIHsKICAgICAgICBudWxsQ2hlY2sobG9jYXRpb24pOwogICAgICAgIGxvY2F0aW9ucy5zZXRMb2NhdGlvbihsb2NhdGlvbiwgbnVsbENoZWNrKHNlYXJjaHBhdGgpKTsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICBwdWJsaWMgSXRlcmFibGU8PyBleHRlbmRzIEZpbGU+IGdldExvY2F0aW9uKExvY2F0aW9uIGxvY2F0aW9uKSB7CiAgICAgICAgbnVsbENoZWNrKGxvY2F0aW9uKTsKICAgICAgICByZXR1cm4gYXNGaWxlcyhsb2NhdGlvbnMuZ2V0TG9jYXRpb24obG9jYXRpb24pKTsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICBwdWJsaWMgSXRlcmFibGU8PyBleHRlbmRzIFBhdGg+IGdldExvY2F0aW9uQXNQYXRocyhMb2NhdGlvbiBsb2NhdGlvbikgewogICAgICAgIG51bGxDaGVjayhsb2NhdGlvbik7CiAgICAgICAgcmV0dXJuIGxvY2F0aW9ucy5nZXRMb2NhdGlvbihsb2NhdGlvbik7CiAgICB9CgogICAgcHJpdmF0ZSBQYXRoIGdldENsYXNzT3V0RGlyKCkgewogICAgICAgIHJldHVybiBsb2NhdGlvbnMuZ2V0T3V0cHV0TG9jYXRpb24oQ0xBU1NfT1VUUFVUKTsKICAgIH0KCiAgICBwcml2YXRlIFBhdGggZ2V0U291cmNlT3V0RGlyKCkgewogICAgICAgIHJldHVybiBsb2NhdGlvbnMuZ2V0T3V0cHV0TG9jYXRpb24oU09VUkNFX09VVFBVVCk7CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSKQogICAgcHVibGljIExvY2F0aW9uIGdldExvY2F0aW9uRm9yTW9kdWxlKExvY2F0aW9uIGxvY2F0aW9uLCBTdHJpbmcgbW9kdWxlTmFtZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICBjaGVja01vZHVsZU9yaWVudGVkT3JPdXRwdXRMb2NhdGlvbihsb2NhdGlvbik7CiAgICAgICAgbnVsbENoZWNrKG1vZHVsZU5hbWUpOwogICAgICAgIGlmIChsb2NhdGlvbiA9PSBTT1VSQ0VfT1VUUFVUICYmIGdldFNvdXJjZU91dERpcigpID09IG51bGwpCiAgICAgICAgICAgIGxvY2F0aW9uID0gQ0xBU1NfT1VUUFVUOwogICAgICAgIHJldHVybiBsb2NhdGlvbnMuZ2V0TG9jYXRpb25Gb3JNb2R1bGUobG9jYXRpb24sIG1vZHVsZU5hbWUpOwogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgIHB1YmxpYyA8Uz4gU2VydmljZUxvYWRlcjxTPiBnZXRTZXJ2aWNlTG9hZGVyKExvY2F0aW9uIGxvY2F0aW9uLCBDbGFzczxTPiBzZXJ2aWNlKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgIG51bGxDaGVjayhsb2NhdGlvbik7CiAgICAgICAgbnVsbENoZWNrKHNlcnZpY2UpOwogICAgICAgIE1vZHVsZS5nZXRNb2R1bGUoZ2V0Q2xhc3MoKSkuYWRkVXNlcyhzZXJ2aWNlKTsKICAgICAgICBpZiAobG9jYXRpb24uaXNNb2R1bGVPcmllbnRlZExvY2F0aW9uKCkpIHsKICAgICAgICAgICAgQ29sbGVjdGlvbjxQYXRoPiBwYXRocyA9IGxvY2F0aW9ucy5nZXRMb2NhdGlvbihsb2NhdGlvbik7CiAgICAgICAgICAgIE1vZHVsZUZpbmRlciBmaW5kZXIgPSBNb2R1bGVGaW5kZXIub2YocGF0aHMudG9BcnJheShuZXcgUGF0aFtwYXRocy5zaXplKCldKSk7CiAgICAgICAgICAgIExheWVyIGJvb3RMYXllciA9IExheWVyLmJvb3QoKTsKICAgICAgICAgICAgQ29uZmlndXJhdGlvbiBjZiA9IGJvb3RMYXllci5jb25maWd1cmF0aW9uKCkucmVzb2x2ZUFuZEJpbmQoTW9kdWxlRmluZGVyLm9mKCksIGZpbmRlciwgQ29sbGVjdGlvbnMuZW1wdHlTZXQoKSk7CiAgICAgICAgICAgIExheWVyIGxheWVyID0gYm9vdExheWVyLmRlZmluZU1vZHVsZXNXaXRoT25lTG9hZGVyKGNmLCBDbGFzc0xvYWRlci5nZXRTeXN0ZW1DbGFzc0xvYWRlcigpKTsKICAgICAgICAgICAgcmV0dXJuIFNlcnZpY2VMb2FkZXJIZWxwZXIubG9hZChsYXllciwgc2VydmljZSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIFNlcnZpY2VMb2FkZXIubG9hZChzZXJ2aWNlLCBnZXRDbGFzc0xvYWRlcihsb2NhdGlvbikpOwogICAgICAgIH0KICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICBwdWJsaWMgTG9jYXRpb24gZ2V0TG9jYXRpb25Gb3JNb2R1bGUoTG9jYXRpb24gbG9jYXRpb24sIEphdmFGaWxlT2JqZWN0IGZvKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgIGNoZWNrTW9kdWxlT3JpZW50ZWRPck91dHB1dExvY2F0aW9uKGxvY2F0aW9uKTsKICAgICAgICBpZiAoIShmbyBpbnN0YW5jZW9mIFBhdGhGaWxlT2JqZWN0KSkKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgUGF0aCBwID0gTG9jYXRpb25zLm5vcm1hbGl6ZSgoKFBhdGhGaWxlT2JqZWN0KSBmbykucGF0aCk7CiAgICAgICAgICAgIC8vIG5lZWQgdG8gZmluZCBwIGluIGxvY2F0aW9uCiAgICAgICAgcmV0dXJuIGxvY2F0aW9ucy5nZXRMb2NhdGlvbkZvck1vZHVsZShsb2NhdGlvbiwgcCk7CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSKQogICAgcHVibGljIHZvaWQgc2V0TG9jYXRpb25Gb3JNb2R1bGUoTG9jYXRpb24gbG9jYXRpb24sIFN0cmluZyBtb2R1bGVOYW1lLCBDb2xsZWN0aW9uPD8gZXh0ZW5kcyBQYXRoPiBwYXRocykKICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICBudWxsQ2hlY2sobG9jYXRpb24pOwogICAgICAgIGNoZWNrTW9kdWxlT3JpZW50ZWRPck91dHB1dExvY2F0aW9uKGxvY2F0aW9uKTsKICAgICAgICBsb2NhdGlvbnMuc2V0TG9jYXRpb25Gb3JNb2R1bGUobG9jYXRpb24sIG51bGxDaGVjayhtb2R1bGVOYW1lKSwgbnVsbENoZWNrKHBhdGhzKSk7CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSKQogICAgcHVibGljIFN0cmluZyBpbmZlck1vZHVsZU5hbWUoTG9jYXRpb24gbG9jYXRpb24pIHsKICAgICAgICBjaGVja05vdE1vZHVsZU9yaWVudGVkTG9jYXRpb24obG9jYXRpb24pOwogICAgICAgIHJldHVybiBsb2NhdGlvbnMuaW5mZXJNb2R1bGVOYW1lKGxvY2F0aW9uKTsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICBwdWJsaWMgSXRlcmFibGU8U2V0PExvY2F0aW9uPj4gbGlzdExvY2F0aW9uc0Zvck1vZHVsZXMoTG9jYXRpb24gbG9jYXRpb24pIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgY2hlY2tNb2R1bGVPcmllbnRlZE9yT3V0cHV0TG9jYXRpb24obG9jYXRpb24pOwogICAgICAgIHJldHVybiBsb2NhdGlvbnMubGlzdExvY2F0aW9uc0Zvck1vZHVsZXMobG9jYXRpb24pOwogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgIHB1YmxpYyBQYXRoIGFzUGF0aChGaWxlT2JqZWN0IGZpbGUpIHsKICAgICAgICBpZiAoZmlsZSBpbnN0YW5jZW9mIFBhdGhGaWxlT2JqZWN0KSB7CiAgICAgICAgICAgIHJldHVybiAoKFBhdGhGaWxlT2JqZWN0KSBmaWxlKS5wYXRoOwogICAgICAgIH0gZWxzZQogICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKGZpbGUuZ2V0TmFtZSgpKTsKICAgIH0KCiAgICAvKioKICAgICAqIEVuZm9yY2VzIHRoZSBzcGVjaWZpY2F0aW9uIG9mIGEgInJlbGF0aXZlIiBuYW1lIGFzIHVzZWQgaW4KICAgICAqIHtAbGlua3BsYWluICNnZXRGaWxlRm9ySW5wdXQoTG9jYXRpb24sU3RyaW5nLFN0cmluZykKICAgICAqIGdldEZpbGVGb3JJbnB1dH0uICBUaGlzIG1ldGhvZCBtdXN0IGZvbGxvdyB0aGUgcnVsZXMgZGVmaW5lZCBpbgogICAgICogdGhhdCBtZXRob2QsIGRvIG5vdCBtYWtlIGFueSBjaGFuZ2VzIHdpdGhvdXQgY29uc3VsdGluZyB0aGUKICAgICAqIHNwZWNpZmljYXRpb24uCiAgICAgKi8KICAgIHByb3RlY3RlZCBzdGF0aWMgYm9vbGVhbiBpc1JlbGF0aXZlVXJpKFVSSSB1cmkpIHsKICAgICAgICBpZiAodXJpLmlzQWJzb2x1dGUoKSkKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIFN0cmluZyBwYXRoID0gdXJpLm5vcm1hbGl6ZSgpLmdldFBhdGgoKTsKICAgICAgICBpZiAocGF0aC5sZW5ndGgoKSA9PSAwIC8qIGlzRW1wdHkoKSBpcyBtdXN0YW5nIEFQSSAqLykKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIGlmICghcGF0aC5lcXVhbHModXJpLmdldFBhdGgoKSkpIC8vIGltcGxpY2l0bHkgY2hlY2tzIGZvciBlbWJlZGRlZCAuIGFuZCAuLgogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgaWYgKHBhdGguc3RhcnRzV2l0aCgiLyIpIHx8IHBhdGguc3RhcnRzV2l0aCgiLi8iKSB8fCBwYXRoLnN0YXJ0c1dpdGgoIi4uLyIpKQogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgLy8gQ29udmVuaWVuY2UgbWV0aG9kCiAgICBwcm90ZWN0ZWQgc3RhdGljIGJvb2xlYW4gaXNSZWxhdGl2ZVVyaShTdHJpbmcgdSkgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIHJldHVybiBpc1JlbGF0aXZlVXJpKG5ldyBVUkkodSkpOwogICAgICAgIH0gY2F0Y2ggKFVSSVN5bnRheEV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBDb252ZXJ0cyBhIHJlbGF0aXZlIGZpbGUgbmFtZSB0byBhIHJlbGF0aXZlIFVSSS4gIFRoaXMgaXMKICAgICAqIGRpZmZlcmVudCBmcm9tIEZpbGUudG9VUkkgYXMgdGhpcyBtZXRob2QgZG9lcyBub3QgY2Fub25pY2FsaXplCiAgICAgKiB0aGUgZmlsZSBiZWZvcmUgY3JlYXRpbmcgdGhlIFVSSS4gIEZ1cnRoZXJtb3JlLCBubyBzY2hlbWEgaXMKICAgICAqIHVzZWQuCiAgICAgKiBAcGFyYW0gZmlsZSBhIHJlbGF0aXZlIGZpbGUgbmFtZQogICAgICogQHJldHVybiBhIHJlbGF0aXZlIFVSSQogICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgdGhlIGZpbGUgbmFtZSBpcyBub3QKICAgICAqIHJlbGF0aXZlIGFjY29yZGluZyB0byB0aGUgZGVmaW5pdGlvbiBnaXZlbiBpbiB7QGxpbmsKICAgICAqIGphdmF4LnRvb2xzLkphdmFGaWxlTWFuYWdlciNnZXRGaWxlRm9ySW5wdXR9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldFJlbGF0aXZlTmFtZShGaWxlIGZpbGUpIHsKICAgICAgICBpZiAoIWZpbGUuaXNBYnNvbHV0ZSgpKSB7CiAgICAgICAgICAgIFN0cmluZyByZXN1bHQgPSBmaWxlLmdldFBhdGgoKS5yZXBsYWNlKEZpbGUuc2VwYXJhdG9yQ2hhciwgJy8nKTsKICAgICAgICAgICAgaWYgKGlzUmVsYXRpdmVVcmkocmVzdWx0KSkKICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfQogICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkludmFsaWQgcmVsYXRpdmUgcGF0aDogIiArIGZpbGUpOwogICAgfQoKICAgIC8qKgogICAgICogR2V0IGEgZGV0YWlsIG1lc3NhZ2UgZnJvbSBhbiBJT0V4Y2VwdGlvbi4KICAgICAqIE1vc3QsIGJ1dCBub3QgYWxsLCBpbnN0YW5jZXMgb2YgSU9FeGNlcHRpb24gcHJvdmlkZSBhIG5vbi1udWxsIHJlc3VsdAogICAgICogZm9yIGdldExvY2FsaXplZE1lc3NhZ2UoKS4gIEJ1dCBzb21lIGluc3RhbmNlcyByZXR1cm4gbnVsbDogaW4gdGhlc2UKICAgICAqIGNhc2VzLCBmYWxsb3ZlciB0byBnZXRNZXNzYWdlKCksIGFuZCBpZiBldmVuIHRoYXQgaXMgbnVsbCwgcmV0dXJuIHRoZQogICAgICogbmFtZSBvZiB0aGUgZXhjZXB0aW9uIGl0c2VsZi4KICAgICAqIEBwYXJhbSBlIGFuIElPRXhjZXB0aW9uCiAgICAgKiBAcmV0dXJuIGEgc3RyaW5nIHRvIGluY2x1ZGUgaW4gYSBjb21waWxlciBkaWFnbm9zdGljCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldE1lc3NhZ2UoSU9FeGNlcHRpb24gZSkgewogICAgICAgIFN0cmluZyBzID0gZS5nZXRMb2NhbGl6ZWRNZXNzYWdlKCk7CiAgICAgICAgaWYgKHMgIT0gbnVsbCkKICAgICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgcyA9IGUuZ2V0TWVzc2FnZSgpOwogICAgICAgIGlmIChzICE9IG51bGwpCiAgICAgICAgICAgIHJldHVybiBzOwogICAgICAgIHJldHVybiBlLnRvU3RyaW5nKCk7CiAgICB9CgogICAgcHJpdmF0ZSB2b2lkIGNoZWNrT3V0cHV0TG9jYXRpb24oTG9jYXRpb24gbG9jYXRpb24pIHsKICAgICAgICBPYmplY3RzLnJlcXVpcmVOb25OdWxsKGxvY2F0aW9uKTsKICAgICAgICBpZiAoIWxvY2F0aW9uLmlzT3V0cHV0TG9jYXRpb24oKSkKICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigibG9jYXRpb24gaXMgbm90IGFuIG91dHB1dCBsb2NhdGlvbjogIiArIGxvY2F0aW9uLmdldE5hbWUoKSk7CiAgICB9CgogICAgcHJpdmF0ZSB2b2lkIGNoZWNrTW9kdWxlT3JpZW50ZWRPck91dHB1dExvY2F0aW9uKExvY2F0aW9uIGxvY2F0aW9uKSB7CiAgICAgICAgT2JqZWN0cy5yZXF1aXJlTm9uTnVsbChsb2NhdGlvbik7CiAgICAgICAgaWYgKCFsb2NhdGlvbi5pc01vZHVsZU9yaWVudGVkTG9jYXRpb24oKSAmJiAhbG9jYXRpb24uaXNPdXRwdXRMb2NhdGlvbigpKQogICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAogICAgICAgICAgICAgICAgICAgICJsb2NhdGlvbiBpcyBub3QgYW4gb3V0cHV0IGxvY2F0aW9uIG9yIGEgbW9kdWxlLW9yaWVudGVkIGxvY2F0aW9uOiAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICArIGxvY2F0aW9uLmdldE5hbWUoKSk7CiAgICB9CgogICAgcHJpdmF0ZSB2b2lkIGNoZWNrTm90TW9kdWxlT3JpZW50ZWRMb2NhdGlvbihMb2NhdGlvbiBsb2NhdGlvbikgewogICAgICAgIE9iamVjdHMucmVxdWlyZU5vbk51bGwobG9jYXRpb24pOwogICAgICAgIGlmIChsb2NhdGlvbi5pc01vZHVsZU9yaWVudGVkTG9jYXRpb24oKSkKICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigibG9jYXRpb24gaXMgbW9kdWxlLW9yaWVudGVkOiAiICsgbG9jYXRpb24uZ2V0TmFtZSgpKTsKICAgIH0KCiAgICAvKiBDb252ZXJ0ZXJzIGJldHdlZW4gZmlsZXMgYW5kIHBhdGhzLgogICAgICogVGhlc2UgYXJlIHRlbXBvcmFyeSB1bnRpbCB3ZSBjYW4gdXBkYXRlIHRoZSBTdGFuZGFyZEphdmFGaWxlTWFuYWdlciBBUEkuCiAgICAgKi8KCiAgICBwcml2YXRlIHN0YXRpYyBJdGVyYWJsZTxQYXRoPiBhc1BhdGhzKGZpbmFsIEl0ZXJhYmxlPD8gZXh0ZW5kcyBGaWxlPiBmaWxlcykgewogICAgICAgIGlmIChmaWxlcyA9PSBudWxsKQogICAgICAgICAgICByZXR1cm4gbnVsbDsKCiAgICAgICAgcmV0dXJuICgpIC0+IG5ldyBJdGVyYXRvcjxQYXRoPigpIHsKICAgICAgICAgICAgSXRlcmF0b3I8PyBleHRlbmRzIEZpbGU+IGl0ZXIgPSBmaWxlcy5pdGVyYXRvcigpOwoKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHB1YmxpYyBib29sZWFuIGhhc05leHQoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gaXRlci5oYXNOZXh0KCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgUGF0aCBuZXh0KCkgewogICAgICAgICAgICAgICAgcmV0dXJuIGl0ZXIubmV4dCgpLnRvUGF0aCgpOwogICAgICAgICAgICB9CiAgICAgICAgfTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBJdGVyYWJsZTxGaWxlPiBhc0ZpbGVzKGZpbmFsIEl0ZXJhYmxlPD8gZXh0ZW5kcyBQYXRoPiBwYXRocykgewogICAgICAgIGlmIChwYXRocyA9PSBudWxsKQogICAgICAgICAgICByZXR1cm4gbnVsbDsKCiAgICAgICAgcmV0dXJuICgpIC0+IG5ldyBJdGVyYXRvcjxGaWxlPigpIHsKICAgICAgICAgICAgSXRlcmF0b3I8PyBleHRlbmRzIFBhdGg+IGl0ZXIgPSBwYXRocy5pdGVyYXRvcigpOwoKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHB1YmxpYyBib29sZWFuIGhhc05leHQoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gaXRlci5oYXNOZXh0KCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgRmlsZSBuZXh0KCkgewogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gaXRlci5uZXh0KCkudG9GaWxlKCk7CiAgICAgICAgICAgICAgICB9IGNhdGNoIChVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbihlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH07CiAgICB9Cn0KUEsDBAoAAAgAAAY7qUqDtbtHZyUAAGclAAAmAAAAY29tL3N1bi90b29scy9qYXZhYy9maWxlL0pSVEluZGV4LmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTQsIDIwMTUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhYy5maWxlOwoKaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CmltcG9ydCBqYXZhLmlvLlVuY2hlY2tlZElPRXhjZXB0aW9uOwppbXBvcnQgamF2YS5sYW5nLnJlZi5Tb2Z0UmVmZXJlbmNlOwppbXBvcnQgamF2YS5uZXQuVVJJOwppbXBvcnQgamF2YS5uaW8uZmlsZS5EaXJlY3RvcnlTdHJlYW07CmltcG9ydCBqYXZhLm5pby5maWxlLkZpbGVTeXN0ZW07CmltcG9ydCBqYXZhLm5pby5maWxlLkZpbGVTeXN0ZW1zOwppbXBvcnQgamF2YS5uaW8uZmlsZS5GaWxlU3lzdGVtTm90Rm91bmRFeGNlcHRpb247CmltcG9ydCBqYXZhLm5pby5maWxlLkZpbGVzOwppbXBvcnQgamF2YS5uaW8uZmlsZS5QYXRoOwppbXBvcnQgamF2YS5uaW8uZmlsZS5Qcm92aWRlck5vdEZvdW5kRXhjZXB0aW9uOwppbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOwppbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CmltcG9ydCBqYXZhLnV0aWwuTGlua2VkSGFzaE1hcDsKaW1wb3J0IGphdmEudXRpbC5MaW5rZWRIYXNoU2V0OwppbXBvcnQgamF2YS51dGlsLk1hcDsKaW1wb3J0IGphdmEudXRpbC5NaXNzaW5nUmVzb3VyY2VFeGNlcHRpb247CmltcG9ydCBqYXZhLnV0aWwuUmVzb3VyY2VCdW5kbGU7CmltcG9ydCBqYXZhLnV0aWwuU2V0OwoKaW1wb3J0IGphdmF4LnRvb2xzLkZpbGVPYmplY3Q7CgppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5maWxlLlJlbGF0aXZlUGF0aC5SZWxhdGl2ZURpcmVjdG9yeTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5Db250ZXh0OwoKLyoqCiAqIEEgcGFja2FnZS1vcmllbnRlZCBpbmRleCBpbnRvIHRoZSBqcnQ6IGZpbGVzeXN0ZW0uCiAqLwpwdWJsaWMgY2xhc3MgSlJUSW5kZXggewogICAgLyoqIEdldCBhIHNoYXJlZCBpbnN0YW5jZSBvZiB0aGUgY2FjaGUuICovCiAgICBwcml2YXRlIHN0YXRpYyBKUlRJbmRleCBzaGFyZWRJbnN0YW5jZTsKICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgc3RhdGljIEpSVEluZGV4IGdldFNoYXJlZEluc3RhbmNlKCkgewogICAgICAgIGlmIChzaGFyZWRJbnN0YW5jZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBzaGFyZWRJbnN0YW5jZSA9IG5ldyBKUlRJbmRleCgpOwogICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVW5jaGVja2VkSU9FeGNlcHRpb24oZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHNoYXJlZEluc3RhbmNlOwogICAgfQoKICAgIC8qKiBHZXQgYSBjb250ZXh0LXNwZWNpZmljIGluc3RhbmNlIG9mIGEgY2FjaGUuICovCiAgICBwdWJsaWMgc3RhdGljIEpSVEluZGV4IGluc3RhbmNlKENvbnRleHQgY29udGV4dCkgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIEpSVEluZGV4IGluc3RhbmNlID0gY29udGV4dC5nZXQoSlJUSW5kZXguY2xhc3MpOwogICAgICAgICAgICBpZiAoaW5zdGFuY2UgPT0gbnVsbCkKICAgICAgICAgICAgICAgIGNvbnRleHQucHV0KEpSVEluZGV4LmNsYXNzLCBpbnN0YW5jZSA9IG5ldyBKUlRJbmRleCgpKTsKICAgICAgICAgICAgcmV0dXJuIGluc3RhbmNlOwogICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFVuY2hlY2tlZElPRXhjZXB0aW9uKGUpOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNBdmFpbGFibGUoKSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgRmlsZVN5c3RlbXMuZ2V0RmlsZVN5c3RlbShVUkkuY3JlYXRlKCJqcnQ6LyIpKTsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfSBjYXRjaCAoUHJvdmlkZXJOb3RGb3VuZEV4Y2VwdGlvbiB8IEZpbGVTeXN0ZW1Ob3RGb3VuZEV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICB9CgoKICAgIC8qKgogICAgICogVGhlIGpydDogZmlsZSBzeXN0ZW0uCiAgICAgKi8KICAgIHByaXZhdGUgZmluYWwgRmlsZVN5c3RlbSBqcnRmczsKCiAgICAvKioKICAgICAqIEEgbGF6aWx5IGV2YWx1YXRlZCBzZXQgb2YgZW50cmllcyBhYm91dCB0aGUgY29udGVudHMgb2YgdGhlIGpydDogZmlsZSBzeXN0ZW0uCiAgICAgKi8KICAgIHByaXZhdGUgZmluYWwgTWFwPFJlbGF0aXZlRGlyZWN0b3J5LCBTb2Z0UmVmZXJlbmNlPEVudHJ5Pj4gZW50cmllczsKCiAgICAvKioKICAgICAqIEFuIGVudHJ5IHByb3ZpZGVzIGNhY2hlZCBpbmZvIGFib3V0IGEgc3BlY2lmaWMgcGFja2FnZSBkaXJlY3Rvcnkgd2l0aGluIGpydDouCiAgICAgKi8KICAgIGNsYXNzIEVudHJ5IHsKICAgICAgICAvKioKICAgICAgICAgKiBUaGUgcmVndWxhciBmaWxlcyBmb3IgdGhpcyBwYWNrYWdlLgogICAgICAgICAqIEZvciBub3csIGFzc3VtZSBqdXN0IG9uZSBpbnN0YW5jZSBvZiBlYWNoIGZpbGUgYWNyb3NzIGFsbCBtb2R1bGVzLgogICAgICAgICAqLwogICAgICAgIGZpbmFsIE1hcDxTdHJpbmcsIFBhdGg+IGZpbGVzOwoKICAgICAgICAvKioKICAgICAgICAgKiBUaGUgc2V0IG9mIHN1YmRpcmVjdG9yaWVzIGluIGpydDogZm9yIHRoaXMgcGFja2FnZS4KICAgICAgICAgKi8KICAgICAgICBmaW5hbCBTZXQ8UmVsYXRpdmVEaXJlY3Rvcnk+IHN1YmRpcnM7CgogICAgICAgIC8qKgogICAgICAgICAqIFRoZSBpbmZvIHRoYXQgdXNlZCB0byBiZSBpbiBjdC5zeW0gZm9yIGNsYXNzZXMgaW4gdGhpcyBwYWNrYWdlLgogICAgICAgICAqLwogICAgICAgIGZpbmFsIEN0U3ltIGN0U3ltOwoKICAgICAgICBwcml2YXRlIEVudHJ5KE1hcDxTdHJpbmcsIFBhdGg+IGZpbGVzLCBTZXQ8UmVsYXRpdmVEaXJlY3Rvcnk+IHN1YmRpcnMsIEN0U3ltIGN0U3ltKSB7CiAgICAgICAgICAgIHRoaXMuZmlsZXMgPSBmaWxlczsKICAgICAgICAgICAgdGhpcy5zdWJkaXJzID0gc3ViZGlyczsKICAgICAgICAgICAgdGhpcy5jdFN5bSA9IGN0U3ltOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFRoZSBpbmZvIHRoYXQgdXNlZCB0byBiZSBpbiBjdC5zeW0gZm9yIGNsYXNzZXMgaW4gYSBwYWNrYWdlLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIEN0U3ltIHsKICAgICAgICAvKioKICAgICAgICAgKiBUaGUgY2xhc3NlcyBpbiB0aGlzIHBhY2thZ2UgYXJlIGludGVybmFsIGFuZCBub3QgdmlzaWJsZS4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBoaWRkZW47CiAgICAgICAgLyoqCiAgICAgICAgICogVGhlIGNsYXNzZXMgaW4gdGhpcyBwYWNrYWdlIGFyZSBwcm9wcmlldGFyeSBhbmQgd2lsbCBnZW5lcmF0ZSBhIHdhcm5pbmcuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gcHJvcHJpZXRhcnk7CiAgICAgICAgLyoqCiAgICAgICAgICogVGhlIG1pbmltdW0gcHJvZmlsZSBpbiB3aGljaCBjbGFzc2VzIGluIHRoaXMgcGFja2FnZSBhcmUgYXZhaWxhYmxlLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBmaW5hbCBTdHJpbmcgbWluUHJvZmlsZTsKCiAgICAgICAgQ3RTeW0oYm9vbGVhbiBoaWRkZW4sIGJvb2xlYW4gcHJvcHJpZXRhcnksIFN0cmluZyBtaW5Qcm9maWxlKSB7CiAgICAgICAgICAgIHRoaXMuaGlkZGVuID0gaGlkZGVuOwogICAgICAgICAgICB0aGlzLnByb3ByaWV0YXJ5ID0gcHJvcHJpZXRhcnk7CiAgICAgICAgICAgIHRoaXMubWluUHJvZmlsZSA9IG1pblByb2ZpbGU7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewogICAgICAgICAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoIkN0U3ltWyIpOwogICAgICAgICAgICBib29sZWFuIG5lZWRTZXAgPSBmYWxzZTsKICAgICAgICAgICAgaWYgKGhpZGRlbikgewogICAgICAgICAgICAgICAgc2IuYXBwZW5kKCJoaWRkZW4iKTsKICAgICAgICAgICAgICAgIG5lZWRTZXAgPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChwcm9wcmlldGFyeSkgewogICAgICAgICAgICAgICAgaWYgKG5lZWRTZXApIHNiLmFwcGVuZCgiLCIpOwogICAgICAgICAgICAgICAgc2IuYXBwZW5kKCJwcm9wcmlldGFyeSIpOwogICAgICAgICAgICAgICAgbmVlZFNlcCA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKG1pblByb2ZpbGUgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgaWYgKG5lZWRTZXApIHNiLmFwcGVuZCgiLCIpOwogICAgICAgICAgICAgICAgc2IuYXBwZW5kKG1pblByb2ZpbGUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHNiLmFwcGVuZCgiXSIpOwogICAgICAgICAgICByZXR1cm4gc2IudG9TdHJpbmcoKTsKICAgICAgICB9CgogICAgICAgIHN0YXRpYyBmaW5hbCBDdFN5bSBFTVBUWSA9IG5ldyBDdFN5bShmYWxzZSwgZmFsc2UsIG51bGwpOwogICAgfQoKICAgIC8qKgogICAgICogQ3JlYXRlIGFuZCBpbml0aWFsaXplIHRoZSBpbmRleC4KICAgICAqLwogICAgcHJpdmF0ZSBKUlRJbmRleCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAganJ0ZnMgPSBGaWxlU3lzdGVtcy5nZXRGaWxlU3lzdGVtKFVSSS5jcmVhdGUoImpydDovIikpOwogICAgICAgIGVudHJpZXMgPSBuZXcgSGFzaE1hcDw+KCk7CiAgICB9CgogICAgcHVibGljIEN0U3ltIGdldEN0U3ltKENoYXJTZXF1ZW5jZSBwYWNrYWdlTmFtZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gZ2V0RW50cnkoUmVsYXRpdmVEaXJlY3RvcnkuZm9yUGFja2FnZShwYWNrYWdlTmFtZSkpLmN0U3ltOwogICAgfQoKICAgIHN5bmNocm9uaXplZCBFbnRyeSBnZXRFbnRyeShSZWxhdGl2ZURpcmVjdG9yeSByZCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICBTb2Z0UmVmZXJlbmNlPEVudHJ5PiByZWYgPSBlbnRyaWVzLmdldChyZCk7CiAgICAgICAgRW50cnkgZSA9IChyZWYgPT0gbnVsbCkgPyBudWxsIDogcmVmLmdldCgpOwogICAgICAgIGlmIChlID09IG51bGwpIHsKICAgICAgICAgICAgTWFwPFN0cmluZywgUGF0aD4gZmlsZXMgPSBuZXcgTGlua2VkSGFzaE1hcDw+KCk7CiAgICAgICAgICAgIFNldDxSZWxhdGl2ZURpcmVjdG9yeT4gc3ViZGlycyA9IG5ldyBMaW5rZWRIYXNoU2V0PD4oKTsKICAgICAgICAgICAgUGF0aCBkaXI7CiAgICAgICAgICAgIGlmIChyZC5wYXRoLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgICAgZGlyID0ganJ0ZnMuZ2V0UGF0aCgiL21vZHVsZXMiKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIFBhdGggcGtncyA9IGpydGZzLmdldFBhdGgoIi9wYWNrYWdlcyIpOwogICAgICAgICAgICAgICAgZGlyID0gcGtncy5yZXNvbHZlKHJkLmdldFBhdGgoKS5yZXBsYWNlQWxsKCIvJCIsICIiKS5yZXBsYWNlKCIvIiwgIi4iKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKEZpbGVzLmV4aXN0cyhkaXIpKSB7CiAgICAgICAgICAgICAgICB0cnkgKERpcmVjdG9yeVN0cmVhbTxQYXRoPiBtb2R1bGVzID0gRmlsZXMubmV3RGlyZWN0b3J5U3RyZWFtKGRpcikpIHsKICAgICAgICAgICAgICAgICAgICBmb3IgKFBhdGggbW9kdWxlOiBtb2R1bGVzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChGaWxlcy5pc1N5bWJvbGljTGluayhtb2R1bGUpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9kdWxlID0gRmlsZXMucmVhZFN5bWJvbGljTGluayhtb2R1bGUpOwogICAgICAgICAgICAgICAgICAgICAgICBQYXRoIHAgPSByZC5yZXNvbHZlQWdhaW5zdChtb2R1bGUpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIUZpbGVzLmV4aXN0cyhwKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgICAgICB0cnkgKERpcmVjdG9yeVN0cmVhbTxQYXRoPiBzdHJlYW0gPSBGaWxlcy5uZXdEaXJlY3RvcnlTdHJlYW0ocCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoUGF0aCBlbnRyeTogc3RyZWFtKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG5hbWUgPSBlbnRyeS5nZXRGaWxlTmFtZSgpLnRvU3RyaW5nKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKEZpbGVzLmlzUmVndWxhckZpbGUoZW50cnkpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRPRE86IGNvbnNpZGVyIGlzc3VlIG9mIGZpbGVzIHdpdGggc2FtZSBuYW1lIGluIGRpZmZlcmVudCBtb2R1bGVzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVzLnB1dChuYW1lLCBlbnRyeSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChGaWxlcy5pc0RpcmVjdG9yeShlbnRyeSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ViZGlycy5hZGQobmV3IFJlbGF0aXZlRGlyZWN0b3J5KHJkLCBuYW1lKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGUgPSBuZXcgRW50cnkoQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTWFwKGZpbGVzKSwKICAgICAgICAgICAgICAgICAgICBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVTZXQoc3ViZGlycyksCiAgICAgICAgICAgICAgICAgICAgZ2V0Q3RJbmZvKHJkKSk7CiAgICAgICAgICAgIGVudHJpZXMucHV0KHJkLCBuZXcgU29mdFJlZmVyZW5jZTw+KGUpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGU7CiAgICB9CgogICAgcHVibGljIGJvb2xlYW4gaXNJbkpSVChGaWxlT2JqZWN0IGZvKSB7CiAgICAgICAgaWYgKGZvIGluc3RhbmNlb2YgUGF0aEZpbGVPYmplY3QpIHsKICAgICAgICAgICAgUGF0aCBwYXRoID0gKChQYXRoRmlsZU9iamVjdCkgZm8pLmdldFBhdGgoKTsKICAgICAgICAgICAgcmV0dXJuIChwYXRoLmdldEZpbGVTeXN0ZW0oKSA9PSBqcnRmcyk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIEN0U3ltIGdldEN0SW5mbyhSZWxhdGl2ZURpcmVjdG9yeSBkaXIpIHsKICAgICAgICBpZiAoZGlyLnBhdGguaXNFbXB0eSgpKQogICAgICAgICAgICByZXR1cm4gQ3RTeW0uRU1QVFk7CiAgICAgICAgLy8gSXQncyBhIHNpZGUtZWZmZWN0IG9mIHRoZSBkZWZhdWx0IGJ1aWxkIHJ1bGVzIHRoYXQgY3QucHJvcGVydGllcwogICAgICAgIC8vIGVuZHMgdXAgYXMgYSByZXNvdXJjZSBidW5kbGUuCiAgICAgICAgaWYgKGN0QnVuZGxlID09IG51bGwpIHsKICAgICAgICAgICAgZmluYWwgU3RyaW5nIGJ1bmRsZU5hbWUgPSAiY29tLnN1bi50b29scy5qYXZhYy5yZXNvdXJjZXMuY3QiOwogICAgICAgICAgICBjdEJ1bmRsZSA9IFJlc291cmNlQnVuZGxlLmdldEJ1bmRsZShidW5kbGVOYW1lKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgU3RyaW5nIGF0dHJzID0gY3RCdW5kbGUuZ2V0U3RyaW5nKGRpci5wYXRoLnJlcGxhY2UoJy8nLCAnLicpICsgJyonKTsKICAgICAgICAgICAgYm9vbGVhbiBoaWRkZW4gPSBmYWxzZTsKICAgICAgICAgICAgYm9vbGVhbiBwcm9wcmlldGFyeSA9IGZhbHNlOwogICAgICAgICAgICBTdHJpbmcgbWluUHJvZmlsZSA9IG51bGw7CiAgICAgICAgICAgIGZvciAoU3RyaW5nIGF0dHI6IGF0dHJzLnNwbGl0KCIgKyIsIDApKSB7CiAgICAgICAgICAgICAgICBzd2l0Y2ggKGF0dHIpIHsKICAgICAgICAgICAgICAgICAgICBjYXNlICJoaWRkZW4iOgogICAgICAgICAgICAgICAgICAgICAgICBoaWRkZW4gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICBjYXNlICJwcm9wcmlldGFyeSI6CiAgICAgICAgICAgICAgICAgICAgICAgIHByb3ByaWV0YXJ5ID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgICAgbWluUHJvZmlsZSA9IGF0dHI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG5ldyBDdFN5bShoaWRkZW4sIHByb3ByaWV0YXJ5LCBtaW5Qcm9maWxlKTsKICAgICAgICB9IGNhdGNoIChNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24gZSkgewogICAgICAgICAgICByZXR1cm4gQ3RTeW0uRU1QVFk7CiAgICAgICAgfQoKICAgIH0KCiAgICBwcml2YXRlIFJlc291cmNlQnVuZGxlIGN0QnVuZGxlOwp9ClBLAwQKAAAIAAAGO6lKjVpJT0kRAABJEQAAJAAAAGNvbS9zdW4vdG9vbHMvamF2YWMvZmlsZS9GU0luZm8uamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwOCwgMjAxNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLmphdmFjLmZpbGU7CgppbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKaW1wb3J0IGphdmEubmlvLmZpbGUuRmlsZVN5c3RlbXM7CmltcG9ydCBqYXZhLm5pby5maWxlLkZpbGVzOwppbXBvcnQgamF2YS5uaW8uZmlsZS5QYXRoOwppbXBvcnQgamF2YS5uaW8uZmlsZS5zcGkuRmlsZVN5c3RlbVByb3ZpZGVyOwppbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKaW1wb3J0IGphdmEudXRpbC5MaXN0OwppbXBvcnQgamF2YS51dGlsLlN0cmluZ1Rva2VuaXplcjsKaW1wb3J0IGphdmEudXRpbC5qYXIuQXR0cmlidXRlczsKaW1wb3J0IGphdmEudXRpbC5qYXIuSmFyRmlsZTsKaW1wb3J0IGphdmEudXRpbC5qYXIuTWFuaWZlc3Q7CgppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkNvbnRleHQ7CgovKioKICogR2V0IG1ldGEtaW5mbyBhYm91dCBmaWxlcy4gRGVmYXVsdCBkaXJlY3QgKG5vbi1jYWNoaW5nKSBpbXBsZW1lbnRhdGlvbi4KICogQHNlZSBDYWNoZUZTSW5mbwogKgogKiA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yCiAqIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj4KICovCnB1YmxpYyBjbGFzcyBGU0luZm8gewoKICAgIC8qKiBHZXQgdGhlIEZTSW5mbyBpbnN0YW5jZSBmb3IgdGhpcyBjb250ZXh0LgogICAgICogIEBwYXJhbSBjb250ZXh0IHRoZSBjb250ZXh0CiAgICAgKiAgQHJldHVybiB0aGUgUGF0aHMgaW5zdGFuY2UgZm9yIHRoaXMgY29udGV4dAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIEZTSW5mbyBpbnN0YW5jZShDb250ZXh0IGNvbnRleHQpIHsKICAgICAgICBGU0luZm8gaW5zdGFuY2UgPSBjb250ZXh0LmdldChGU0luZm8uY2xhc3MpOwogICAgICAgIGlmIChpbnN0YW5jZSA9PSBudWxsKQogICAgICAgICAgICBpbnN0YW5jZSA9IG5ldyBGU0luZm8oKTsKICAgICAgICByZXR1cm4gaW5zdGFuY2U7CiAgICB9CgogICAgcHJvdGVjdGVkIEZTSW5mbygpIHsKICAgIH0KCiAgICBwcm90ZWN0ZWQgRlNJbmZvKENvbnRleHQgY29udGV4dCkgewogICAgICAgIGNvbnRleHQucHV0KEZTSW5mby5jbGFzcywgdGhpcyk7CiAgICB9CgogICAgcHVibGljIFBhdGggZ2V0Q2Fub25pY2FsRmlsZShQYXRoIGZpbGUpIHsKICAgICAgICB0cnkgewogICAgICAgICAgICByZXR1cm4gZmlsZS50b1JlYWxQYXRoKCk7CiAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICByZXR1cm4gZmlsZS50b0Fic29sdXRlUGF0aCgpLm5vcm1hbGl6ZSgpOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgYm9vbGVhbiBleGlzdHMoUGF0aCBmaWxlKSB7CiAgICAgICAgcmV0dXJuIEZpbGVzLmV4aXN0cyhmaWxlKTsKICAgIH0KCiAgICBwdWJsaWMgYm9vbGVhbiBpc0RpcmVjdG9yeShQYXRoIGZpbGUpIHsKICAgICAgICByZXR1cm4gRmlsZXMuaXNEaXJlY3RvcnkoZmlsZSk7CiAgICB9CgogICAgcHVibGljIGJvb2xlYW4gaXNGaWxlKFBhdGggZmlsZSkgewogICAgICAgIHJldHVybiBGaWxlcy5pc1JlZ3VsYXJGaWxlKGZpbGUpOwogICAgfQoKICAgIHB1YmxpYyBMaXN0PFBhdGg+IGdldEphckNsYXNzUGF0aChQYXRoIGZpbGUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgUGF0aCBwYXJlbnQgPSBmaWxlLmdldFBhcmVudCgpOwogICAgICAgIHRyeSAoSmFyRmlsZSBqYXJGaWxlID0gbmV3IEphckZpbGUoZmlsZS50b0ZpbGUoKSkpIHsKICAgICAgICAgICAgTWFuaWZlc3QgbWFuID0gamFyRmlsZS5nZXRNYW5pZmVzdCgpOwogICAgICAgICAgICBpZiAobWFuID09IG51bGwpCiAgICAgICAgICAgICAgICByZXR1cm4gQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CgogICAgICAgICAgICBBdHRyaWJ1dGVzIGF0dHIgPSBtYW4uZ2V0TWFpbkF0dHJpYnV0ZXMoKTsKICAgICAgICAgICAgaWYgKGF0dHIgPT0gbnVsbCkKICAgICAgICAgICAgICAgIHJldHVybiBDb2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKCiAgICAgICAgICAgIFN0cmluZyBwYXRoID0gYXR0ci5nZXRWYWx1ZShBdHRyaWJ1dGVzLk5hbWUuQ0xBU1NfUEFUSCk7CiAgICAgICAgICAgIGlmIChwYXRoID09IG51bGwpCiAgICAgICAgICAgICAgICByZXR1cm4gQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CgogICAgICAgICAgICBMaXN0PFBhdGg+IGxpc3QgPSBuZXcgQXJyYXlMaXN0PD4oKTsKCiAgICAgICAgICAgIGZvciAoU3RyaW5nVG9rZW5pemVyIHN0ID0gbmV3IFN0cmluZ1Rva2VuaXplcihwYXRoKTsKICAgICAgICAgICAgICAgICBzdC5oYXNNb3JlVG9rZW5zKCk7ICkgewogICAgICAgICAgICAgICAgU3RyaW5nIGVsdCA9IHN0Lm5leHRUb2tlbigpOwogICAgICAgICAgICAgICAgUGF0aCBmID0gRmlsZVN5c3RlbXMuZ2V0RGVmYXVsdCgpLmdldFBhdGgoZWx0KTsKICAgICAgICAgICAgICAgIGlmICghZi5pc0Fic29sdXRlKCkgJiYgcGFyZW50ICE9IG51bGwpCiAgICAgICAgICAgICAgICAgICAgZiA9IHBhcmVudC5yZXNvbHZlKGYpLnRvQWJzb2x1dGVQYXRoKCk7CiAgICAgICAgICAgICAgICBsaXN0LmFkZChmKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIGxpc3Q7CiAgICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgRmlsZVN5c3RlbVByb3ZpZGVyIGphckZTUHJvdmlkZXI7CgogICAgcHVibGljIHN5bmNocm9uaXplZCBGaWxlU3lzdGVtUHJvdmlkZXIgZ2V0SmFyRlNQcm92aWRlcigpIHsKICAgICAgICBpZiAoamFyRlNQcm92aWRlciAhPSBudWxsKSB7CiAgICAgICAgICAgIHJldHVybiBqYXJGU1Byb3ZpZGVyOwogICAgICAgIH0KICAgICAgICBmb3IgKEZpbGVTeXN0ZW1Qcm92aWRlciBwcm92aWRlcjogRmlsZVN5c3RlbVByb3ZpZGVyLmluc3RhbGxlZFByb3ZpZGVycygpKSB7CiAgICAgICAgICAgIGlmIChwcm92aWRlci5nZXRTY2hlbWUoKS5lcXVhbHMoImphciIpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gKGphckZTUHJvdmlkZXIgPSBwcm92aWRlcik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9Cgp9ClBLAwQKAAAIAAAGO6lKDjwTU0ZSAABGUgAALAAAAGNvbS9zdW4vdG9vbHMvamF2YWMvZmlsZS9QYXRoRmlsZU9iamVjdC5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDA5LCAyMDE2LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuamF2YWMuZmlsZTsKCmltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwppbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW1SZWFkZXI7CmltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtV3JpdGVyOwppbXBvcnQgamF2YS5pby5SZWFkZXI7CmltcG9ydCBqYXZhLmlvLldyaXRlcjsKaW1wb3J0IGphdmEubmV0LlVSSTsKaW1wb3J0IGphdmEubmV0LlVSSVN5bnRheEV4Y2VwdGlvbjsKaW1wb3J0IGphdmEubmlvLkJ5dGVCdWZmZXI7CmltcG9ydCBqYXZhLm5pby5DaGFyQnVmZmVyOwppbXBvcnQgamF2YS5uaW8uY2hhcnNldC5DaGFyc2V0RGVjb2RlcjsKaW1wb3J0IGphdmEubmlvLmZpbGUuRmlsZVN5c3RlbTsKaW1wb3J0IGphdmEubmlvLmZpbGUuRmlsZVN5c3RlbXM7CmltcG9ydCBqYXZhLm5pby5maWxlLkZpbGVzOwppbXBvcnQgamF2YS5uaW8uZmlsZS5MaW5rT3B0aW9uOwppbXBvcnQgamF2YS5uaW8uZmlsZS5QYXRoOwppbXBvcnQgamF2YS50ZXh0Lk5vcm1hbGl6ZXI7CmltcG9ydCBqYXZhLnV0aWwuT2JqZWN0czsKCmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuTW9kaWZpZXI7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuTmVzdGluZ0tpbmQ7CmltcG9ydCBqYXZheC50b29scy5GaWxlT2JqZWN0OwppbXBvcnQgamF2YXgudG9vbHMuSmF2YUZpbGVPYmplY3Q7CgppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5maWxlLlJlbGF0aXZlUGF0aC5SZWxhdGl2ZUZpbGU7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuRGVmaW5lZEJ5OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkRlZmluZWRCeS5BcGk7CgoKLyoqCiAqICBJbXBsZW1lbnRhdGlvbiBvZiBKYXZhRmlsZU9iamVjdCB1c2luZyBqYXZhLm5pby5maWxlIEFQSS4KICoKICogIDxwPlBhdGhGaWxlT2JqZWN0cyBhcmUsIGZvciB0aGUgbW9zdCBwYXJ0LCBzdHJhaWdodGZvcndhcmQgd3JhcHBlcnMgYXJvdW5kCiAqICBpbW11dGFibGUgYWJzb2x1dGUgUGF0aCBvYmplY3RzLiBEaWZmZXJlbnQgc3VidHlwZXMgYXJlIHVzZWQgdG8gcHJvdmlkZQogKiAgc3BlY2lhbGl6ZWQgaW1wbGVtZW50YXRpb25zIG9mICJpbmZlckJpbmFyeU5hbWUiIGFuZCAiZ2V0TmFtZSIgdGhhdCBjYXB0dXJlCiAqICBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIGF2YWlsYWJsZSBhdCB0aGUgdGltZSB0aGUgb2JqZWN0IGlzIGNyZWF0ZWQuCiAqCiAqICA8cD5JbiBnZW5lcmFsLCB7QGxpbmsgSmF2YUZpbGVNYW5hZ2VyI2lzU2FtZUZpbGV9IHNob3VsZCBiZSB1c2VkIHRvCiAqICBkZXRlcm1pbmUgd2hldGhlciB0d28gZmlsZSBvYmplY3RzIHJlZmVyIHRvIHRoZSBzYW1lIGZpbGUgb24gZGlzay4KICogIFBhdGhGaWxlT2JqZWN0IGFsc28gc3VwcG9ydHMgdGhlIHN0YW5kYXJkIHtAY29kZSBlcXVhbHN9IGFuZCB7QGNvZGUgaGFzaENvZGV9CiAqICBtZXRob2RzLCBwcmltYXJpbHkgZm9yIGNvbnZlbmllbmNlIHdoZW4gd29ya2luZyB3aXRoIGNvbGxlY3Rpb25zLgogKiAgQWxsIG9mIHRoZXNlIG9wZXJhdGlvbnMgZGVsZWdhdGUgdG8gdGhlIGVxdWl2YWxlbnQgb3BlcmF0aW9ucyBvbiB0aGUKICogIHVuZGVybHlpbmcgUGF0aCBvYmplY3QuCiAqCiAqICA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiAgSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93biByaXNrLgogKiAgVGhpcyBjb2RlIGFuZCBpdHMgaW50ZXJuYWwgaW50ZXJmYWNlcyBhcmUgc3ViamVjdCB0byBjaGFuZ2Ugb3IKICogIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj4KICovCnB1YmxpYyBhYnN0cmFjdCBjbGFzcyBQYXRoRmlsZU9iamVjdCBpbXBsZW1lbnRzIEphdmFGaWxlT2JqZWN0IHsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEZpbGVTeXN0ZW0gZGVmYXVsdEZpbGVTeXN0ZW0gPSBGaWxlU3lzdGVtcy5nZXREZWZhdWx0KCk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuIGlzTWFjT1MgPSBTeXN0ZW0uZ2V0UHJvcGVydHkoIm9zLm5hbWUiLCAiIikuY29udGFpbnMoIk9TIFgiKTsKCiAgICBwcm90ZWN0ZWQgZmluYWwgQmFzZUZpbGVNYW5hZ2VyIGZpbGVNYW5hZ2VyOwogICAgcHJvdGVjdGVkIGZpbmFsIFBhdGggcGF0aDsKICAgIHByaXZhdGUgYm9vbGVhbiBoYXNQYXJlbnRzOwoKICAgIC8qKgogICAgICogQ3JlYXRlIGEgUGF0aEZpbGVPYmplY3QgZm9yIGEgZmlsZSB3aXRoaW4gYSBkaXJlY3RvcnksIHN1Y2ggdGhhdCB0aGUKICAgICAqIGJpbmFyeSBuYW1lIGNhbiBiZSBpbmZlcnJlZCBmcm9tIHRoZSByZWxhdGlvbnNoaXAgdG8gYW4gZW5jbG9zaW5nIGRpcmVjdG9yeS4KICAgICAqCiAgICAgKiBUaGUgYmluYXJ5IG5hbWUgaXMgZGVyaXZlZCBmcm9tIHtAY29kZSByZWxhdGl2ZVBhdGh9LgogICAgICogVGhlIG5hbWUgaXMgZGVyaXZlZCBmcm9tIHRoZSBjb21wb3NpdGlvbiBvZiB7QGNvZGUgdXNlclBhY2thZ2VSb290RGlyfQogICAgICogYW5kIHtAY29kZSByZWxhdGl2ZVBhdGh9LgogICAgICoKICAgICAqIEBwYXJhbSBmaWxlTWFuYWdlciB0aGUgZmlsZSBtYW5hZ2VyIGNyZWF0aW5nIHRoaXMgZmlsZSBvYmplY3QKICAgICAqIEBwYXJhbSBwYXRoIHRoZSBhYnNvbHV0ZSBwYXRoIHJlZmVycmVkIHRvIGJ5IHRoaXMgZmlsZSBvYmplY3QKICAgICAqIEBwYXJhbSB1c2VyUGFja2FnZVJvb3REaXIgdGhlIHBhdGggb2YgdGhlIGRpcmVjdG9yeSBjb250YWluaW5nIHRoZQogICAgICogICAgICAgICAgcm9vdCBvZiB0aGUgcGFja2FnZSBoaWVyYXJjaHkKICAgICAqIEBwYXJhbSByZWxhdGl2ZVBhdGggdGhlIHBhdGggb2YgdGhpcyBmaWxlIHJlbGF0aXZlIHRvIHtAY29kZSB1c2VyUGFja2FnZVJvb3REaXJ9CiAgICAgKi8KICAgIHN0YXRpYyBQYXRoRmlsZU9iamVjdCBmb3JEaXJlY3RvcnlQYXRoKEJhc2VGaWxlTWFuYWdlciBmaWxlTWFuYWdlciwgUGF0aCBwYXRoLAogICAgICAgICAgICBQYXRoIHVzZXJQYWNrYWdlUm9vdERpciwgUmVsYXRpdmVQYXRoIHJlbGF0aXZlUGF0aCkgewogICAgICAgIHJldHVybiBuZXcgRGlyZWN0b3J5RmlsZU9iamVjdChmaWxlTWFuYWdlciwgcGF0aCwgdXNlclBhY2thZ2VSb290RGlyLCByZWxhdGl2ZVBhdGgpOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIERpcmVjdG9yeUZpbGVPYmplY3QgZXh0ZW5kcyBQYXRoRmlsZU9iamVjdCB7CiAgICAgICAgcHJpdmF0ZSBmaW5hbCBQYXRoIHVzZXJQYWNrYWdlUm9vdERpcjsKICAgICAgICBwcml2YXRlIGZpbmFsIFJlbGF0aXZlUGF0aCByZWxhdGl2ZVBhdGg7CgogICAgICAgIHByaXZhdGUgRGlyZWN0b3J5RmlsZU9iamVjdChCYXNlRmlsZU1hbmFnZXIgZmlsZU1hbmFnZXIsIFBhdGggcGF0aCwKICAgICAgICAgICAgICAgIFBhdGggdXNlclBhY2thZ2VSb290RGlyLCBSZWxhdGl2ZVBhdGggcmVsYXRpdmVQYXRoKSB7CiAgICAgICAgICAgIHN1cGVyKGZpbGVNYW5hZ2VyLCBwYXRoKTsKICAgICAgICAgICAgdGhpcy51c2VyUGFja2FnZVJvb3REaXIgPSBPYmplY3RzLnJlcXVpcmVOb25OdWxsKHVzZXJQYWNrYWdlUm9vdERpcik7CiAgICAgICAgICAgIHRoaXMucmVsYXRpdmVQYXRoID0gcmVsYXRpdmVQYXRoOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSKQogICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZSgpIHsKICAgICAgICAgICAgcmV0dXJuIHJlbGF0aXZlUGF0aC5yZXNvbHZlQWdhaW5zdCh1c2VyUGFja2FnZVJvb3REaXIpLnRvU3RyaW5nKCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgU3RyaW5nIGluZmVyQmluYXJ5TmFtZShJdGVyYWJsZTw/IGV4dGVuZHMgUGF0aD4gcGF0aHMpIHsKICAgICAgICAgICAgcmV0dXJuIHRvQmluYXJ5TmFtZShyZWxhdGl2ZVBhdGgpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKICAgICAgICAgICAgcmV0dXJuICJEaXJlY3RvcnlGaWxlT2JqZWN0WyIgKyB1c2VyUGFja2FnZVJvb3REaXIgKyAiOiIgKyByZWxhdGl2ZVBhdGgucGF0aCArICJdIjsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIFBhdGhGaWxlT2JqZWN0IGdldFNpYmxpbmcoU3RyaW5nIGJhc2VOYW1lKSB7CiAgICAgICAgICAgIHJldHVybiBuZXcgRGlyZWN0b3J5RmlsZU9iamVjdChmaWxlTWFuYWdlciwKICAgICAgICAgICAgICAgICAgICBwYXRoLnJlc29sdmVTaWJsaW5nKGJhc2VOYW1lKSwKICAgICAgICAgICAgICAgICAgICB1c2VyUGFja2FnZVJvb3REaXIsCiAgICAgICAgICAgICAgICAgICAgbmV3IFJlbGF0aXZlRmlsZShyZWxhdGl2ZVBhdGguZGlybmFtZSgpLCBiYXNlTmFtZSkKICAgICAgICAgICAgKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBDcmVhdGUgYSBQYXRoRmlsZU9iamVjdCBmb3IgYSBmaWxlIGluIGEgZmlsZSBzeXN0ZW0gc3VjaCBhcyBhIGphciBmaWxlLAogICAgICogc3VjaCB0aGF0IHRoZSBiaW5hcnkgbmFtZSBjYW4gYmUgaW5mZXJyZWQgZnJvbSBpdHMgcG9zaXRpb24gd2l0aGluIHRoZQogICAgICogZmlsZSBzeXN0ZW0uCiAgICAgKgogICAgICogVGhlIGJpbmFyeSBuYW1lIGlzIGRlcml2ZWQgZnJvbSB7QGNvZGUgcGF0aH0uCiAgICAgKiBUaGUgbmFtZSBpcyBkZXJpdmVkIGZyb20gdGhlIGNvbXBvc2l0aW9uIG9mIHtAY29kZSB1c2VySmFyUGF0aH0KICAgICAqIGFuZCB7QGNvZGUgcGF0aH0uCiAgICAgKgogICAgICogQHBhcmFtIGZpbGVNYW5hZ2VyIHRoZSBmaWxlIG1hbmFnZXIgY3JlYXRpbmcgdGhpcyBmaWxlIG9iamVjdAogICAgICogQHBhcmFtIHBhdGggdGhlIHBhdGggcmVmZXJyZWQgdG8gYnkgdGhpcyBmaWxlIG9iamVjdAogICAgICogQHBhcmFtIHVzZXJKYXJQYXRoIHRoZSBwYXRoIG9mIHRoZSBqYXIgZmlsZSBjb250YWluaW5nIHRoZSBmaWxlIHN5c3RlbS4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBQYXRoRmlsZU9iamVjdCBmb3JKYXJQYXRoKEJhc2VGaWxlTWFuYWdlciBmaWxlTWFuYWdlciwKICAgICAgICAgICAgUGF0aCBwYXRoLCBQYXRoIHVzZXJKYXJQYXRoKSB7CiAgICAgICAgcmV0dXJuIG5ldyBKYXJGaWxlT2JqZWN0KGZpbGVNYW5hZ2VyLCBwYXRoLCB1c2VySmFyUGF0aCk7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgSmFyRmlsZU9iamVjdCBleHRlbmRzIFBhdGhGaWxlT2JqZWN0IHsKICAgICAgICBwcml2YXRlIGZpbmFsIFBhdGggdXNlckphclBhdGg7CgogICAgICAgIHByaXZhdGUgSmFyRmlsZU9iamVjdChCYXNlRmlsZU1hbmFnZXIgZmlsZU1hbmFnZXIsIFBhdGggcGF0aCwgUGF0aCB1c2VySmFyUGF0aCkgewogICAgICAgICAgICBzdXBlcihmaWxlTWFuYWdlciwgcGF0aCk7CiAgICAgICAgICAgIHRoaXMudXNlckphclBhdGggPSB1c2VySmFyUGF0aDsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgICAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWUoKSB7CiAgICAgICAgICAgIC8vIFRoZSB1c2Ugb2YgKCApIHRvIGRlbGltaXQgdGhlIGVudHJ5IG5hbWUgaXMgbm90IGlkZWFsCiAgICAgICAgICAgIC8vIGJ1dCBpdCBkb2VzIG1hdGNoIGVhcmxpZXIgYmVoYXZpb3IKICAgICAgICAgICAgcmV0dXJuIHVzZXJKYXJQYXRoICsgIigiICsgcGF0aCArICIpIjsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBTdHJpbmcgaW5mZXJCaW5hcnlOYW1lKEl0ZXJhYmxlPD8gZXh0ZW5kcyBQYXRoPiBwYXRocykgewogICAgICAgICAgICBQYXRoIHJvb3QgPSBwYXRoLmdldEZpbGVTeXN0ZW0oKS5nZXRSb290RGlyZWN0b3JpZXMoKS5pdGVyYXRvcigpLm5leHQoKTsKICAgICAgICAgICAgcmV0dXJuIHRvQmluYXJ5TmFtZShyb290LnJlbGF0aXZpemUocGF0aCkpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSKQogICAgICAgIHB1YmxpYyBVUkkgdG9VcmkoKSB7CiAgICAgICAgICAgIC8vIFdvcmsgYXJvdW5kIGJ1ZyBKREstODEzNDQ1MToKICAgICAgICAgICAgLy8gcGF0aC50b1VyaSgpIHJldHVybnMgZG91YmxlLWVuY29kZWQgVVJJcywgdGhhdCBjYW5ub3QgYmUgb3BlbmVkIGJ5IFVSTENvbm5lY3Rpb24KICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZUphclVyaSh1c2VySmFyUGF0aCwgcGF0aC50b1N0cmluZygpKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CiAgICAgICAgICAgIHJldHVybiAiSmFyRmlsZU9iamVjdFsiICsgdXNlckphclBhdGggKyAiOiIgKyBwYXRoICsgIl0iOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgUGF0aEZpbGVPYmplY3QgZ2V0U2libGluZyhTdHJpbmcgYmFzZU5hbWUpIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyBKYXJGaWxlT2JqZWN0KGZpbGVNYW5hZ2VyLAogICAgICAgICAgICAgICAgICAgIHBhdGgucmVzb2x2ZVNpYmxpbmcoYmFzZU5hbWUpLAogICAgICAgICAgICAgICAgICAgIHVzZXJKYXJQYXRoCiAgICAgICAgICAgICk7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIHN0YXRpYyBVUkkgY3JlYXRlSmFyVXJpKFBhdGggamFyRmlsZSwgU3RyaW5nIGVudHJ5TmFtZSkgewogICAgICAgICAgICBVUkkgamFyVVJJID0gamFyRmlsZS50b1VyaSgpLm5vcm1hbGl6ZSgpOwogICAgICAgICAgICBTdHJpbmcgc2VwYXJhdG9yID0gZW50cnlOYW1lLnN0YXJ0c1dpdGgoIi8iKSA/ICIhIiA6ICIhLyI7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAvLyBUaGUgamFyIFVSSSBjb252ZW50aW9uIGFwcGVhcnMgdG8gYmUgbm90IHRvIHJlLWVuY29kZSB0aGUgamFyVVJJCiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFVSSSgiamFyOiIgKyBqYXJVUkkgKyBzZXBhcmF0b3IgKyBlbnRyeU5hbWUpOwogICAgICAgICAgICB9IGNhdGNoIChVUklTeW50YXhFeGNlcHRpb24gZSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IENhbm5vdENyZWF0ZVVyaUVycm9yKGphclVSSSArIHNlcGFyYXRvciArIGVudHJ5TmFtZSwgZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBDcmVhdGUgYSBQYXRoRmlsZU9iamVjdCBmb3IgYSBmaWxlIGluIGEgbW9kdWxhciBmaWxlIHN5c3RlbSwgc3VjaCBhcyBqcnQ6LAogICAgICogc3VjaCB0aGF0IHRoZSBiaW5hcnkgbmFtZSBjYW4gYmUgaW5mZXJyZWQgZnJvbSBpdHMgcG9zaXRpb24gd2l0aGluIHRoZQogICAgICogZmlsZXN5c3RlbS4KICAgICAqCiAgICAgKiBUaGUgYmluYXJ5IG5hbWUgaXMgZGVyaXZlZCBmcm9tIHtAY29kZSBwYXRofSwgaWdub3JpbmcgdGhlIGZpcnN0IHR3bwogICAgICogZWxlbWVudHMgb2YgdGhlIG5hbWUgKHdoaWNoIGFyZSAibW9kdWxlcyIgYW5kIGEgbW9kdWxlIG5hbWUpLgogICAgICogVGhlIG5hbWUgaXMgZGVyaXZlZCBmcm9tIHtAY29kZSBwYXRofS4KICAgICAqCiAgICAgKiBAcGFyYW0gZmlsZU1hbmFnZXIgdGhlIGZpbGUgbWFuYWdlciBjcmVhdGluZyB0aGlzIGZpbGUgb2JqZWN0CiAgICAgKiBAcGFyYW0gcGF0aCB0aGUgcGF0aCByZWZlcnJlZCB0byBieSB0aGlzIGZpbGUgb2JqZWN0CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgUGF0aEZpbGVPYmplY3QgZm9ySlJUUGF0aChCYXNlRmlsZU1hbmFnZXIgZmlsZU1hbmFnZXIsCiAgICAgICAgICAgIGZpbmFsIFBhdGggcGF0aCkgewogICAgICAgIHJldHVybiBuZXcgSlJURmlsZU9iamVjdChmaWxlTWFuYWdlciwgcGF0aCk7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgSlJURmlsZU9iamVjdCBleHRlbmRzIFBhdGhGaWxlT2JqZWN0IHsKICAgICAgICAvLyBwcml2YXRlIGZpbmFsIFBhdGggamF2YUhvbWU7CiAgICAgICAgcHJpdmF0ZSBKUlRGaWxlT2JqZWN0KEJhc2VGaWxlTWFuYWdlciBmaWxlTWFuYWdlciwgUGF0aCBwYXRoKSB7CiAgICAgICAgICAgIHN1cGVyKGZpbGVNYW5hZ2VyLCBwYXRoKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgICAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWUoKSB7CiAgICAgICAgICAgIHJldHVybiBwYXRoLnRvU3RyaW5nKCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgU3RyaW5nIGluZmVyQmluYXJ5TmFtZShJdGVyYWJsZTw/IGV4dGVuZHMgUGF0aD4gcGF0aHMpIHsKICAgICAgICAgICAgLy8gdXNlIHN1YnBhdGggdG8gaWdub3JlIHRoZSBsZWFkaW5nIC9tb2R1bGVzL01PRFVMRS1OQU1FCiAgICAgICAgICAgIHJldHVybiB0b0JpbmFyeU5hbWUocGF0aC5zdWJwYXRoKDIsIHBhdGguZ2V0TmFtZUNvdW50KCkpKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CiAgICAgICAgICAgIHJldHVybiAiSlJURmlsZU9iamVjdFsiICsgcGF0aCArICJdIjsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIFBhdGhGaWxlT2JqZWN0IGdldFNpYmxpbmcoU3RyaW5nIGJhc2VOYW1lKSB7CiAgICAgICAgICAgIHJldHVybiBuZXcgSlJURmlsZU9iamVjdChmaWxlTWFuYWdlciwKICAgICAgICAgICAgICAgICAgICBwYXRoLnJlc29sdmVTaWJsaW5nKGJhc2VOYW1lKQogICAgICAgICAgICApOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIENyZWF0ZSBhIFBhdGhGaWxlT2JqZWN0IGZvciBhIGZpbGUgd2hvc2UgYmluYXJ5IG5hbWUgbXVzdCBiZSBpbmZlcnJlZAogICAgICogZnJvbSBpdHMgcG9zaXRpb24gb24gYSBzZWFyY2ggcGF0aC4KICAgICAqCiAgICAgKiBUaGUgYmluYXJ5IG5hbWUgaXMgaW5mZXJyZWQgYnkgZmluZGluZyBhbiBlbmNsb3NpbmcgZGlyZWN0b3J5IGluCiAgICAgKiB0aGUgc2VxdWVuY2Ugb2YgcGF0aHMgYXNzb2NpYXRlZCB3aXRoIHRoZSBsb2NhdGlvbiBnaXZlbiB0bwogICAgICoge0BsaW5rIEphdmFGaWxlTWFuYWdlciNpbmZlckJpbmFyeU5hbWUpLgogICAgICogVGhlIG5hbWUgaXMgZGVyaXZlZCBmcm9tIHtAY29kZSB1c2VyUGF0aH0uCiAgICAgKgogICAgICogQHBhcmFtIGZpbGVNYW5hZ2VyIHRoZSBmaWxlIG1hbmFnZXIgY3JlYXRpbmcgdGhpcyBmaWxlIG9iamVjdAogICAgICogQHBhcmFtIHBhdGggdGhlIHBhdGggcmVmZXJyZWQgdG8gYnkgdGhpcyBmaWxlIG9iamVjdAogICAgICogQHBhcmFtIHVzZXJQYXRoIHRoZSAidXNlci1mcmllbmRseSIgbmFtZSBmb3IgdGhpcyBwYXRoLgogICAgICovCiAgICBzdGF0aWMgUGF0aEZpbGVPYmplY3QgZm9yU2ltcGxlUGF0aChCYXNlRmlsZU1hbmFnZXIgZmlsZU1hbmFnZXIsCiAgICAgICAgICAgIFBhdGggcGF0aCwgUGF0aCB1c2VyUGF0aCkgewogICAgICAgIHJldHVybiBuZXcgU2ltcGxlRmlsZU9iamVjdChmaWxlTWFuYWdlciwgcGF0aCwgdXNlclBhdGgpOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIFNpbXBsZUZpbGVPYmplY3QgZXh0ZW5kcyBQYXRoRmlsZU9iamVjdCB7CiAgICAgICAgcHJpdmF0ZSBmaW5hbCBQYXRoIHVzZXJQYXRoOwogICAgICAgIHByaXZhdGUgU2ltcGxlRmlsZU9iamVjdChCYXNlRmlsZU1hbmFnZXIgZmlsZU1hbmFnZXIsIFBhdGggcGF0aCwgUGF0aCB1c2VyUGF0aCkgewogICAgICAgICAgICBzdXBlcihmaWxlTWFuYWdlciwgcGF0aCk7CiAgICAgICAgICAgIHRoaXMudXNlclBhdGggPSB1c2VyUGF0aDsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgICAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWUoKSB7CiAgICAgICAgICAgIHJldHVybiB1c2VyUGF0aC50b1N0cmluZygpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFN0cmluZyBpbmZlckJpbmFyeU5hbWUoSXRlcmFibGU8PyBleHRlbmRzIFBhdGg+IHBhdGhzKSB7CiAgICAgICAgICAgIFBhdGggYWJzUGF0aCA9IHBhdGgudG9BYnNvbHV0ZVBhdGgoKTsKICAgICAgICAgICAgZm9yIChQYXRoIHA6IHBhdGhzKSB7CiAgICAgICAgICAgICAgICBQYXRoIGFwID0gcC50b0Fic29sdXRlUGF0aCgpOwogICAgICAgICAgICAgICAgaWYgKGFic1BhdGguc3RhcnRzV2l0aChhcCkpIHsKICAgICAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgICAgICBQYXRoIHJwID0gYXAucmVsYXRpdml6ZShhYnNQYXRoKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJwICE9IG51bGwpIC8vIG1heWJlIG51bGwgaWYgYWJzUGF0aCBzYW1lIGFzIGFwCiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdG9CaW5hcnlOYW1lKHJwKTsKICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBpZ25vcmUgdGhpcyBwIGlmIGNhbm5vdCByZWxhdGl2aXplIHBhdGggdG8gcAogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIFBhdGhGaWxlT2JqZWN0IGdldFNpYmxpbmcoU3RyaW5nIGJhc2VOYW1lKSB7CiAgICAgICAgICAgIHJldHVybiBuZXcgU2ltcGxlRmlsZU9iamVjdChmaWxlTWFuYWdlciwKICAgICAgICAgICAgICAgICAgICBwYXRoLnJlc29sdmVTaWJsaW5nKGJhc2VOYW1lKSwKICAgICAgICAgICAgICAgICAgICB1c2VyUGF0aC5yZXNvbHZlU2libGluZyhiYXNlTmFtZSkKICAgICAgICAgICAgKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBDcmVhdGUgYSBQYXRoRmlsZU9iamVjdCwgZm9yIGEgc3BlY2lmaWVkIHBhdGgsIGluIHRoZSBjb250ZXh0IG9mCiAgICAgKiBhIGdpdmVuIGZpbGUgbWFuYWdlci4KICAgICAqCiAgICAgKiBJbiBnZW5lcmFsLCB0aGlzIHBhdGggc2hvdWxkIGJlIGFuCiAgICAgKiB7QGxpbmsgUGF0aCN0b0Fic29sdXRlUGF0aCBhYnNvbHV0ZSBwYXRofSwgaWYgbm90IGEKICAgICAqIHtAbGluayBQYXRoI3RvUmVhbFBhdGh9IHJlYWwgcGF0aC4KICAgICAqIEl0IHdpbGwgYmUgdXNlZCBhcyB0aGUgYmFzaXMgb2Yge0Bjb2RlIGVxdWFsc30sIHtAY29kZSBoYXNoQ29kZX0KICAgICAqIGFuZCB7QGNvZGUgaXNTYW1lRmlsZX0gbWV0aG9kcyBvbiB0aGlzIGZpbGUgb2JqZWN0LgogICAgICoKICAgICAqIEEgUGF0aEZpbGVPYmplY3Qgc2hvdWxkIGFsc28gaGF2ZSBhICJmcmllbmRseSBuYW1lIiBwZXIgdGhlCiAgICAgKiBzcGVjaWZpY2F0aW9uIGZvciB7QGxpbmsgRmlsZU9iamVjdCNnZXROYW1lfS4gVGhlIGZyaWVuZGx5IG5hbWUKICAgICAqIGlzIHByb3ZpZGVkIGJ5IHRoZSB2YXJpb3VzIHN1YnR5cGVzIG9mIHtAY29kZSBQYXRoRmlsZU9iamVjdH0uCiAgICAgKgogICAgICogQHBhcmFtIGZpbGVNYW5hZ2VyIHRoZSBmaWxlIG1hbmFnZXIgY3JlYXRpbmcgdGhpcyBmaWxlIG9iamVjdAogICAgICogQHBhcmFtIHBhdGggdGhlIHBhdGggY29udGFpbmVkIGluIHRoaXMgZmlsZSBvYmplY3QuCiAgICAgKi8KICAgIHByb3RlY3RlZCBQYXRoRmlsZU9iamVjdChCYXNlRmlsZU1hbmFnZXIgZmlsZU1hbmFnZXIsIFBhdGggcGF0aCkgewogICAgICAgIHRoaXMuZmlsZU1hbmFnZXIgPSBPYmplY3RzLnJlcXVpcmVOb25OdWxsKGZpbGVNYW5hZ2VyKTsKICAgICAgICBpZiAoRmlsZXMuaXNEaXJlY3RvcnkocGF0aCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiZGlyZWN0b3JpZXMgbm90IHN1cHBvcnRlZCIpOwogICAgICAgIH0KICAgICAgICB0aGlzLnBhdGggPSBwYXRoOwogICAgfQoKICAgIC8qKgogICAgICogU2VlIHtAbGluayBKYXZhY0ZpbGVNYW5hZ2VyI2luZmVyQmluYXJ5TmFtZX0uCiAgICAgKi8KICAgIGFic3RyYWN0IFN0cmluZyBpbmZlckJpbmFyeU5hbWUoSXRlcmFibGU8PyBleHRlbmRzIFBhdGg+IHBhdGhzKTsKCiAgICAvKioKICAgICAqIFJldHVybiB0aGUgZmlsZSBvYmplY3QgZm9yIGEgc2libGluZyBmaWxlIHdpdGggYSBnaXZlbiBmaWxlIG5hbWUuCiAgICAgKiBTZWUge0BsaW5rIEphdmFjRmlsZU1hbmFnZXIjZ2V0RmlsZUZvck91dHB1dH0gYW5kCiAgICAgKiB7QGxpbmsgSmF2YWNGaWxlTWFuYWdlciNnZXRKYXZhRmlsZUZvck91dHB1dH0uCiAgICAgKi8KICAgIGFic3RyYWN0IFBhdGhGaWxlT2JqZWN0IGdldFNpYmxpbmcoU3RyaW5nIGJhc2VuYW1lKTsKCiAgICAvKioKICAgICAqIFJldHVybiB0aGUgUGF0aCBmb3IgdGhpcyBvYmplY3QuCiAgICAgKiBAcmV0dXJuIHRoZSBQYXRoIGZvciB0aGlzIG9iamVjdC4KICAgICAqIEBzZWUgU3RhbmRhcmRKYXZhRmlsZU1hbmFnZXIjYXNQYXRoCiAgICAgKi8KICAgIHB1YmxpYyBQYXRoIGdldFBhdGgoKSB7CiAgICAgICAgcmV0dXJuIHBhdGg7CiAgICB9CgogICAgLyoqCiAgICAgKiBUaGUgc2hvcnQgbmFtZSBpcyB1c2VkIHdoZW4gZ2VuZXJhdGluZyByYXcgZGlhZ25vc3RpY3MuCiAgICAgKiBAcmV0dXJuIHRoZSBsYXN0IGNvbXBvbmVudCBvZiB0aGUgcGF0aAogICAgICovCiAgICBwdWJsaWMgU3RyaW5nIGdldFNob3J0TmFtZSgpIHsKICAgICAgICByZXR1cm4gcGF0aC5nZXRGaWxlTmFtZSgpLnRvU3RyaW5nKCk7CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSKQogICAgcHVibGljIEtpbmQgZ2V0S2luZCgpIHsKICAgICAgICByZXR1cm4gQmFzZUZpbGVNYW5hZ2VyLmdldEtpbmQocGF0aC5nZXRGaWxlTmFtZSgpLnRvU3RyaW5nKCkpOwogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgIHB1YmxpYyBib29sZWFuIGlzTmFtZUNvbXBhdGlibGUoU3RyaW5nIHNpbXBsZU5hbWUsIEtpbmQga2luZCkgewogICAgICAgIE9iamVjdHMucmVxdWlyZU5vbk51bGwoc2ltcGxlTmFtZSk7CiAgICAgICAgT2JqZWN0cy5yZXF1aXJlTm9uTnVsbChraW5kKTsKCiAgICAgICAgaWYgKGtpbmQgPT0gS2luZC5PVEhFUiAmJiBnZXRLaW5kKCkgIT0ga2luZCkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICBTdHJpbmcgc24gPSBzaW1wbGVOYW1lICsga2luZC5leHRlbnNpb247CiAgICAgICAgU3RyaW5nIHBuID0gcGF0aC5nZXRGaWxlTmFtZSgpLnRvU3RyaW5nKCk7CiAgICAgICAgaWYgKHBuLmVxdWFscyhzbikpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICBpZiAocGF0aC5nZXRGaWxlU3lzdGVtKCkgPT0gZGVmYXVsdEZpbGVTeXN0ZW0pIHsKICAgICAgICAgICAgaWYgKGlzTWFjT1MpIHsKICAgICAgICAgICAgICAgIFN0cmluZyBuYW1lID0gcGF0aC5nZXRGaWxlTmFtZSgpLnRvU3RyaW5nKCk7CiAgICAgICAgICAgICAgICBpZiAoTm9ybWFsaXplci5pc05vcm1hbGl6ZWQobmFtZSwgTm9ybWFsaXplci5Gb3JtLk5GRCkKICAgICAgICAgICAgICAgICAgICAgICAgJiYgTm9ybWFsaXplci5pc05vcm1hbGl6ZWQoc24sIE5vcm1hbGl6ZXIuRm9ybS5ORkMpKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gT24gTWFjIE9TIFggaXQgaXMgcXVpdGUgcG9zc2libGUgdG8gaGF2ZSB0aGUgZmlsZSBuYW1lIGFuZCB0aGUKICAgICAgICAgICAgICAgICAgICAvLyBnaXZlbiBzaW1wbGUgbmFtZSBub3JtYWxpemVkIGluIGRpZmZlcmVudCB3YXlzLgogICAgICAgICAgICAgICAgICAgIC8vIEluIHRoYXQgY2FzZSB3ZSBoYXZlIHRvIG5vcm1hbGl6ZSBmaWxlIG5hbWUgdG8gdGhlCiAgICAgICAgICAgICAgICAgICAgLy8gTm9ybWFsIEZvcm0gQ29tcG9zZWQgKE5GQykuCiAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG5vcm1OYW1lID0gTm9ybWFsaXplci5ub3JtYWxpemUobmFtZSwgTm9ybWFsaXplci5Gb3JtLk5GQyk7CiAgICAgICAgICAgICAgICAgICAgaWYgKG5vcm1OYW1lLmVxdWFscyhzbikpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAocG4uZXF1YWxzSWdub3JlQ2FzZShzbikpIHsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgLy8gYWxsb3cgZm9yIFdpbmRvd3MKICAgICAgICAgICAgICAgICAgICByZXR1cm4gcGF0aC50b1JlYWxQYXRoKExpbmtPcHRpb24uTk9GT0xMT1dfTElOS1MpLmdldEZpbGVOYW1lKCkudG9TdHJpbmcoKS5lcXVhbHMoc24pOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSKQogICAgcHVibGljIE5lc3RpbmdLaW5kIGdldE5lc3RpbmdLaW5kKCkgewogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgIHB1YmxpYyBNb2RpZmllciBnZXRBY2Nlc3NMZXZlbCgpIHsKICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICBwdWJsaWMgVVJJIHRvVXJpKCkgewogICAgICAgIHJldHVybiBwYXRoLnRvVXJpKCk7CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSKQogICAgcHVibGljIElucHV0U3RyZWFtIG9wZW5JbnB1dFN0cmVhbSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgZmlsZU1hbmFnZXIudXBkYXRlTGFzdFVzZWRUaW1lKCk7CiAgICAgICAgcmV0dXJuIEZpbGVzLm5ld0lucHV0U3RyZWFtKHBhdGgpOwogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgIHB1YmxpYyBPdXRwdXRTdHJlYW0gb3Blbk91dHB1dFN0cmVhbSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgZmlsZU1hbmFnZXIudXBkYXRlTGFzdFVzZWRUaW1lKCk7CiAgICAgICAgZmlsZU1hbmFnZXIuZmx1c2hDYWNoZSh0aGlzKTsKICAgICAgICBlbnN1cmVQYXJlbnREaXJlY3Rvcmllc0V4aXN0KCk7CiAgICAgICAgcmV0dXJuIEZpbGVzLm5ld091dHB1dFN0cmVhbShwYXRoKTsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICBwdWJsaWMgUmVhZGVyIG9wZW5SZWFkZXIoYm9vbGVhbiBpZ25vcmVFbmNvZGluZ0Vycm9ycykgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICBDaGFyc2V0RGVjb2RlciBkZWNvZGVyID0gZmlsZU1hbmFnZXIuZ2V0RGVjb2RlcihmaWxlTWFuYWdlci5nZXRFbmNvZGluZ05hbWUoKSwgaWdub3JlRW5jb2RpbmdFcnJvcnMpOwogICAgICAgIHJldHVybiBuZXcgSW5wdXRTdHJlYW1SZWFkZXIob3BlbklucHV0U3RyZWFtKCksIGRlY29kZXIpOwogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgIHB1YmxpYyBDaGFyU2VxdWVuY2UgZ2V0Q2hhckNvbnRlbnQoYm9vbGVhbiBpZ25vcmVFbmNvZGluZ0Vycm9ycykgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICBDaGFyQnVmZmVyIGNiID0gZmlsZU1hbmFnZXIuZ2V0Q2FjaGVkQ29udGVudCh0aGlzKTsKICAgICAgICBpZiAoY2IgPT0gbnVsbCkgewogICAgICAgICAgICB0cnkgKElucHV0U3RyZWFtIGluID0gb3BlbklucHV0U3RyZWFtKCkpIHsKICAgICAgICAgICAgICAgIEJ5dGVCdWZmZXIgYmIgPSBmaWxlTWFuYWdlci5tYWtlQnl0ZUJ1ZmZlcihpbik7CiAgICAgICAgICAgICAgICBKYXZhRmlsZU9iamVjdCBwcmV2ID0gZmlsZU1hbmFnZXIubG9nLnVzZVNvdXJjZSh0aGlzKTsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgY2IgPSBmaWxlTWFuYWdlci5kZWNvZGUoYmIsIGlnbm9yZUVuY29kaW5nRXJyb3JzKTsKICAgICAgICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgICAgICAgICAgZmlsZU1hbmFnZXIubG9nLnVzZVNvdXJjZShwcmV2KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGZpbGVNYW5hZ2VyLnJlY3ljbGVCeXRlQnVmZmVyKGJiKTsKICAgICAgICAgICAgICAgIGlmICghaWdub3JlRW5jb2RpbmdFcnJvcnMpIHsKICAgICAgICAgICAgICAgICAgICBmaWxlTWFuYWdlci5jYWNoZSh0aGlzLCBjYik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIGNiOwogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgIHB1YmxpYyBXcml0ZXIgb3BlbldyaXRlcigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgZmlsZU1hbmFnZXIudXBkYXRlTGFzdFVzZWRUaW1lKCk7CiAgICAgICAgZmlsZU1hbmFnZXIuZmx1c2hDYWNoZSh0aGlzKTsKICAgICAgICBlbnN1cmVQYXJlbnREaXJlY3Rvcmllc0V4aXN0KCk7CiAgICAgICAgcmV0dXJuIG5ldyBPdXRwdXRTdHJlYW1Xcml0ZXIoRmlsZXMubmV3T3V0cHV0U3RyZWFtKHBhdGgpLCBmaWxlTWFuYWdlci5nZXRFbmNvZGluZ05hbWUoKSk7CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSKQogICAgcHVibGljIGxvbmcgZ2V0TGFzdE1vZGlmaWVkKCkgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIHJldHVybiBGaWxlcy5nZXRMYXN0TW9kaWZpZWRUaW1lKHBhdGgpLnRvTWlsbGlzKCk7CiAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSKQogICAgcHVibGljIGJvb2xlYW4gZGVsZXRlKCkgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIEZpbGVzLmRlbGV0ZShwYXRoKTsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgfQoKICAgIGJvb2xlYW4gaXNTYW1lRmlsZShQYXRoRmlsZU9iamVjdCBvdGhlcikgewogICAgICAgIC8vIEJ5IGNvbnN0cnVjdGlvbiwgdGhlICJwYXRoIiBmaWVsZCBzaG91bGQgYmUgY2Fub25pY2FsIGluIGFsbCBsaWtlbHksIHN1cHBvcnRlZCBzY2VuYXJpb3MuCiAgICAgICAgLy8gKEFueSBleGNlcHRpb25zIHdvdWxkIGludm9sdmUgdGhlIHVzZSBvZiBzeW1saW5rcyB3aXRoaW4gYSBwYWNrYWdlIGhpZXJhcmNoeS4pCiAgICAgICAgLy8gVGhlcmVmb3JlLCBpdCBpcyBzdWZmaWNpZW50IHRvIGNoZWNrIHRoYXQgdGhlIHBhdGhzIGFyZSAuZXF1YWxzLgogICAgICAgIHJldHVybiBwYXRoLmVxdWFscyhvdGhlci5wYXRoKTsKICAgIH0KCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb3RoZXIpIHsKICAgICAgICByZXR1cm4gKG90aGVyIGluc3RhbmNlb2YgUGF0aEZpbGVPYmplY3QgJiYgcGF0aC5lcXVhbHMoKChQYXRoRmlsZU9iamVjdCkgb3RoZXIpLnBhdGgpKTsKICAgIH0KCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgICAgcmV0dXJuIHBhdGguaGFzaENvZGUoKTsKICAgIH0KCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CiAgICAgICAgcmV0dXJuIGdldENsYXNzKCkuZ2V0U2ltcGxlTmFtZSgpICsgIlsiICsgcGF0aCArICJdIjsKICAgIH0KCiAgICBwcml2YXRlIHZvaWQgZW5zdXJlUGFyZW50RGlyZWN0b3JpZXNFeGlzdCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKCFoYXNQYXJlbnRzKSB7CiAgICAgICAgICAgIFBhdGggcGFyZW50ID0gcGF0aC5nZXRQYXJlbnQoKTsKICAgICAgICAgICAgaWYgKHBhcmVudCAhPSBudWxsICYmICFGaWxlcy5pc0RpcmVjdG9yeShwYXJlbnQpKSB7CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIEZpbGVzLmNyZWF0ZURpcmVjdG9yaWVzKHBhcmVudCk7CiAgICAgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJjb3VsZCBub3QgY3JlYXRlIHBhcmVudCBkaXJlY3RvcmllcyIsIGUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGhhc1BhcmVudHMgPSB0cnVlOwogICAgICAgIH0KICAgIH0KCiAgICBwcm90ZWN0ZWQgc3RhdGljIFN0cmluZyB0b0JpbmFyeU5hbWUoUmVsYXRpdmVQYXRoIHJlbGF0aXZlUGF0aCkgewogICAgICAgIHJldHVybiB0b0JpbmFyeU5hbWUocmVsYXRpdmVQYXRoLnBhdGgsICIvIik7CiAgICB9CgogICAgcHJvdGVjdGVkIHN0YXRpYyBTdHJpbmcgdG9CaW5hcnlOYW1lKFBhdGggcmVsYXRpdmVQYXRoKSB7CiAgICAgICAgcmV0dXJuIHRvQmluYXJ5TmFtZShyZWxhdGl2ZVBhdGgudG9TdHJpbmcoKSwKICAgICAgICAgICAgICAgIHJlbGF0aXZlUGF0aC5nZXRGaWxlU3lzdGVtKCkuZ2V0U2VwYXJhdG9yKCkpOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyB0b0JpbmFyeU5hbWUoU3RyaW5nIHJlbGF0aXZlUGF0aCwgU3RyaW5nIHNlcCkgewogICAgICAgIHJldHVybiByZW1vdmVFeHRlbnNpb24ocmVsYXRpdmVQYXRoKS5yZXBsYWNlKHNlcCwgIi4iKTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgcmVtb3ZlRXh0ZW5zaW9uKFN0cmluZyBmaWxlTmFtZSkgewogICAgICAgIGludCBsYXN0RG90ID0gZmlsZU5hbWUubGFzdEluZGV4T2YoIi4iKTsKICAgICAgICByZXR1cm4gKGxhc3REb3QgPT0gLTEgPyBmaWxlTmFtZSA6IGZpbGVOYW1lLnN1YnN0cmluZygwLCBsYXN0RG90KSk7CiAgICB9CgogICAgLyoqIFJldHVybiB0aGUgbGFzdCBjb21wb25lbnQgb2YgYSBwcmVzdW1lZCBoaWVyYXJjaGljYWwgVVJJLgogICAgICogIEZyb20gdGhlIHNjaGVtZSBzcGVjaWZpYyBwYXJ0IG9mIHRoZSBVUkksIGl0IHJldHVybnMgdGhlIHN1YnN0cmluZwogICAgICogIGFmdGVyIHRoZSBsYXN0ICIvIiBpZiBhbnksIG9yIGV2ZXJ5dGhpbmcgaWYgbm8gIi8iIGlzIGZvdW5kLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBnZXRTaW1wbGVOYW1lKEZpbGVPYmplY3QgZm8pIHsKICAgICAgICBVUkkgdXJpID0gZm8udG9VcmkoKTsKICAgICAgICBTdHJpbmcgcyA9IHVyaS5nZXRTY2hlbWVTcGVjaWZpY1BhcnQoKTsKICAgICAgICByZXR1cm4gcy5zdWJzdHJpbmcocy5sYXN0SW5kZXhPZigiLyIpICsgMSk7IC8vIHNhZmUgd2hlbiAvIG5vdCBmb3VuZAoKICAgIH0KCiAgICAvKiogVXNlZCB3aGVuIFVSTFN5bnRheEV4Y2VwdGlvbiBpcyB0aHJvd24gdW5leHBlY3RlZGx5IGR1cmluZwogICAgICogIGltcGxlbWVudGF0aW9ucyBvZiBGaWxlT2JqZWN0LnRvVVJJKCkuICovCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIENhbm5vdENyZWF0ZVVyaUVycm9yIGV4dGVuZHMgRXJyb3IgewogICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDkxMDE3MDg4NDA5OTc2MTM1NDZMOwogICAgICAgIHB1YmxpYyBDYW5ub3RDcmVhdGVVcmlFcnJvcihTdHJpbmcgdmFsdWUsIFRocm93YWJsZSBjYXVzZSkgewogICAgICAgICAgICBzdXBlcih2YWx1ZSwgY2F1c2UpOwogICAgICAgIH0KICAgIH0KfQpQSwMECgAACAAABjupSvZCCgDqSQAA6kkAAC0AAABjb20vc3VuL3Rvb2xzL2phdmFjL2ZpbGUvQmFzZUZpbGVNYW5hZ2VyLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDksIDIwMTYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhYy5maWxlOwoKaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CmltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOwppbXBvcnQgamF2YS5sYW5nLnJlZi5Tb2Z0UmVmZXJlbmNlOwppbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuQ29uc3RydWN0b3I7CmltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5JbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uOwppbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuTWV0aG9kOwppbXBvcnQgamF2YS5uZXQuVVJMOwppbXBvcnQgamF2YS5uZXQuVVJMQ2xhc3NMb2FkZXI7CmltcG9ydCBqYXZhLm5pby5CeXRlQnVmZmVyOwppbXBvcnQgamF2YS5uaW8uQ2hhckJ1ZmZlcjsKaW1wb3J0IGphdmEubmlvLmNoYXJzZXQuQ2hhcnNldDsKaW1wb3J0IGphdmEubmlvLmNoYXJzZXQuQ2hhcnNldERlY29kZXI7CmltcG9ydCBqYXZhLm5pby5jaGFyc2V0LkNvZGVyUmVzdWx0OwppbXBvcnQgamF2YS5uaW8uY2hhcnNldC5Db2RpbmdFcnJvckFjdGlvbjsKaW1wb3J0IGphdmEubmlvLmNoYXJzZXQuSWxsZWdhbENoYXJzZXROYW1lRXhjZXB0aW9uOwppbXBvcnQgamF2YS5uaW8uY2hhcnNldC5VbnN1cHBvcnRlZENoYXJzZXRFeGNlcHRpb247CmltcG9ydCBqYXZhLm5pby5maWxlLlBhdGg7CmltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbjsKaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOwppbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOwppbXBvcnQgamF2YS51dGlsLk1hcDsKaW1wb3J0IGphdmEudXRpbC5PYmplY3RzOwppbXBvcnQgamF2YS51dGlsLlNldDsKCmltcG9ydCBqYXZheC50b29scy5KYXZhRmlsZU1hbmFnZXI7CmltcG9ydCBqYXZheC50b29scy5KYXZhRmlsZU9iamVjdDsKaW1wb3J0IGphdmF4LnRvb2xzLkphdmFGaWxlT2JqZWN0LktpbmQ7CgppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5tYWluLk9wdGlvbjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMubWFpbi5PcHRpb25IZWxwZXI7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLm1haW4uT3B0aW9uSGVscGVyLkdydW1weUhlbHBlcjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMucmVzb3VyY2VzLkNvbXBpbGVyUHJvcGVydGllcy5FcnJvcnM7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuQWJvcnQ7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuQ29udGV4dDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5EZWZpbmVkQnk7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuRGVmaW5lZEJ5LkFwaTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5Mb2c7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuT3B0aW9uczsKCi8qKgogKiBVdGlsaXR5IG1ldGhvZHMgZm9yIGJ1aWxkaW5nIGEgZmlsZW1hbmFnZXIuCiAqIFRoZXJlIGFyZSBubyByZWZlcmVuY2VzIGhlcmUgdG8gZmlsZS1zeXN0ZW0gc3BlY2lmaWMgb2JqZWN0cyBzdWNoIGFzCiAqIGphdmEuaW8uRmlsZSBvciBqYXZhLm5pby5maWxlLlBhdGguCiAqLwpwdWJsaWMgYWJzdHJhY3QgY2xhc3MgQmFzZUZpbGVNYW5hZ2VyIGltcGxlbWVudHMgSmF2YUZpbGVNYW5hZ2VyIHsKICAgIHByb3RlY3RlZCBCYXNlRmlsZU1hbmFnZXIoQ2hhcnNldCBjaGFyc2V0KSB7CiAgICAgICAgdGhpcy5jaGFyc2V0ID0gY2hhcnNldDsKICAgICAgICBieXRlQnVmZmVyQ2FjaGUgPSBuZXcgQnl0ZUJ1ZmZlckNhY2hlKCk7CiAgICAgICAgbG9jYXRpb25zID0gY3JlYXRlTG9jYXRpb25zKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXQgdGhlIGNvbnRleHQgZm9yIEphdmFjUGF0aEZpbGVNYW5hZ2VyLgogICAgICogQHBhcmFtIGNvbnRleHQgdGhlIGNvbnRleHQgY29udGFpbmluZyBpdGVtcyB0byBiZSBhc3NvY2lhdGVkIHdpdGggdGhlIGZpbGUgbWFuYWdlcgogICAgICovCiAgICBwdWJsaWMgdm9pZCBzZXRDb250ZXh0KENvbnRleHQgY29udGV4dCkgewogICAgICAgIGxvZyA9IExvZy5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBvcHRpb25zID0gT3B0aW9ucy5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBjbGFzc0xvYWRlckNsYXNzID0gb3B0aW9ucy5nZXQoInByb2Nsb2FkZXIiKTsKCiAgICAgICAgLy8gQXZvaWQgaW5pdGlhbGl6aW5nIExpbnQKICAgICAgICBib29sZWFuIHdhcm4gPSBvcHRpb25zLmlzTGludFNldCgicGF0aCIpOwogICAgICAgIGxvY2F0aW9ucy51cGRhdGUobG9nLCB3YXJuLCBGU0luZm8uaW5zdGFuY2UoY29udGV4dCkpOwoKICAgICAgICAvLyBTZXR0aW5nIHRoaXMgb3B0aW9uIGlzIGFuIGluZGljYXRpb24gdGhhdCBjbG9zZSgpIHNob3VsZCBkZWZlciBhY3R1YWxseSBjbG9zaW5nCiAgICAgICAgLy8gdGhlIGZpbGUgbWFuYWdlciB1bnRpbCBhZnRlciBhIHNwZWNpZmllZCBwZXJpb2Qgb2YgaW5hY3Rpdml0eS4KICAgICAgICAvLyBUaGlzIGlzIHRvIGFjY29tb2RhdGUgY2xpZW50cyB3aGljaCBzYXZlIHJlZmVyZW5jZXMgdG8gU3ltYm9scyBjcmVhdGVkIGZvciB1c2UKICAgICAgICAvLyB3aXRoaW4gZG9jbGV0cyBvciBhbm5vdGF0aW9uIHByb2Nlc3NvcnMsIGFuZCB3aGljaCB0aGVuIGF0dGVtcHQgdG8gdXNlIHRob3NlCiAgICAgICAgLy8gcmVmZXJlbmNlcyBhZnRlciB0aGUgdG9vbCBleGl0cywgaGF2aW5nIGNsb3NlZCBhbnkgaW50ZXJuYWxseSBtYW5hZ2VkIGZpbGUgbWFuYWdlci4KICAgICAgICAvLyBJZGVhbGx5LCBzdWNoIGNsaWVudHMgc2hvdWxkIHJ1biB0aGUgdG9vbCB2aWEgdGhlIGphdmF4LnRvb2xzIEFQSSwgcHJvdmlkaW5nIHRoZWlyCiAgICAgICAgLy8gb3duIGZpbGUgbWFuYWdlciwgd2hpY2ggY2FuIGJlIGNsb3NlZCBieSB0aGUgY2xpZW50IHdoZW4gYWxsIHVzZSBvZiB0aGF0IGZpbGUKICAgICAgICAvLyBtYW5hZ2VyIGlzIGNvbXBsZXRlLgogICAgICAgIC8vIElmIHRoZSBvcHRpb24gaGFzIGEgbnVtZXJpYyB2YWx1ZSwgaXQgd2lsbCBiZSBpbnRlcnByZXRlZCBhcyB0aGUgZHVyYXRpb24sCiAgICAgICAgLy8gaW4gc2Vjb25kcywgb2YgdGhlIHBlcmlvZCBvZiBpbmFjdGl2aXR5IHRvIHdhaXQgZm9yLCBiZWZvcmUgdGhlIGZpbGUgbWFuYWdlcgogICAgICAgIC8vIGlzIGFjdHVhbGx5IGNsb3NlZC4KICAgICAgICAvLyBTZWUgYWxzbyBkZWZlcnJlZENsb3NlKCkuCiAgICAgICAgU3RyaW5nIHMgPSBvcHRpb25zLmdldCgiZmlsZU1hbmFnZXIuZGVmZXJDbG9zZSIpOwogICAgICAgIGlmIChzICE9IG51bGwpIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIGRlZmVycmVkQ2xvc2VUaW1lb3V0ID0gKGludCkgKEZsb2F0LnBhcnNlRmxvYXQocykgKiAxMDAwKTsKICAgICAgICAgICAgfSBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgICAgIGRlZmVycmVkQ2xvc2VUaW1lb3V0ID0gNjAgKiAxMDAwOyAgLy8gZGVmYXVsdDogb25lIG1pbnV0ZSwgaW4gbWlsbGlzCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgcHJvdGVjdGVkIExvY2F0aW9ucyBjcmVhdGVMb2NhdGlvbnMoKSB7CiAgICAgICAgcmV0dXJuIG5ldyBMb2NhdGlvbnMoKTsKICAgIH0KCiAgICAvKioKICAgICAqIFRoZSBsb2cgdG8gYmUgdXNlZCBmb3IgZXJyb3IgcmVwb3J0aW5nLgogICAgICovCiAgICBwdWJsaWMgTG9nIGxvZzsKCiAgICAvKioKICAgICAqIFVzZXIgcHJvdmlkZWQgY2hhcnNldCAodGhyb3VnaCBqYXZheC50b29scykuCiAgICAgKi8KICAgIHByb3RlY3RlZCBDaGFyc2V0IGNoYXJzZXQ7CgogICAgcHJvdGVjdGVkIE9wdGlvbnMgb3B0aW9uczsKCiAgICBwcm90ZWN0ZWQgU3RyaW5nIGNsYXNzTG9hZGVyQ2xhc3M7CgogICAgcHJvdGVjdGVkIGZpbmFsIExvY2F0aW9ucyBsb2NhdGlvbnM7CgogICAgLyoqCiAgICAgKiBBIGZsYWcgZm9yIGNsaWVudHMgdG8gdXNlIHRvIGluZGljYXRlIHRoYXQgdGhpcyBmaWxlIG1hbmFnZXIgc2hvdWxkCiAgICAgKiBiZSBjbG9zZWQgd2hlbiBpdCBpcyBubyBsb25nZXIgcmVxdWlyZWQuCiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGF1dG9DbG9zZTsKCiAgICAvKioKICAgICAqIFdhaXQgZm9yIGEgcGVyaW9kIG9mIGluYWN0aXZpdHkgYmVmb3JlIGNhbGxpbmcgY2xvc2UoKS4KICAgICAqIFRoZSBsZW5ndGggb2YgdGhlIHBlcmlvZCBvZiBpbmFjdGl2aXR5IGlzIGdpdmVuIGJ5IHtAY29kZSBkZWZlcnJlZENsb3NlVGltZW91dH0KICAgICAqLwogICAgcHJvdGVjdGVkIHZvaWQgZGVmZXJyZWRDbG9zZSgpIHsKICAgICAgICBUaHJlYWQgdCA9IG5ldyBUaHJlYWQoZ2V0Q2xhc3MoKS5nZXROYW1lKCkgKyAiIERlZmVycmVkQ2xvc2UiKSB7CiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgdm9pZCBydW4oKSB7CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIHN5bmNocm9uaXplZCAoQmFzZUZpbGVNYW5hZ2VyLnRoaXMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgbG9uZyBub3cgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKG5vdyA8IGxhc3RVc2VkVGltZSArIGRlZmVycmVkQ2xvc2VUaW1lb3V0KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBCYXNlRmlsZU1hbmFnZXIudGhpcy53YWl0KGxhc3RVc2VkVGltZSArIGRlZmVycmVkQ2xvc2VUaW1lb3V0IC0gbm93KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vdyA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGRlZmVycmVkQ2xvc2VUaW1lb3V0ID0gMDsKICAgICAgICAgICAgICAgICAgICAgICAgY2xvc2UoKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9OwogICAgICAgIHQuc2V0RGFlbW9uKHRydWUpOwogICAgICAgIHQuc3RhcnQoKTsKICAgIH0KCiAgICBzeW5jaHJvbml6ZWQgdm9pZCB1cGRhdGVMYXN0VXNlZFRpbWUoKSB7CiAgICAgICAgaWYgKGRlZmVycmVkQ2xvc2VUaW1lb3V0ID4gMCkgeyAvLyBhdm9pZCB1cGRhdGluZyB0aGUgdGltZSB1bm5lY2Vzc2FyaWx5CiAgICAgICAgICAgIGxhc3RVc2VkVGltZSA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOwogICAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIGxvbmcgbGFzdFVzZWRUaW1lID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CiAgICBwcm90ZWN0ZWQgbG9uZyBkZWZlcnJlZENsb3NlVGltZW91dCA9IDA7CgogICAgcHJvdGVjdGVkIENsYXNzTG9hZGVyIGdldENsYXNzTG9hZGVyKFVSTFtdIHVybHMpIHsKICAgICAgICBDbGFzc0xvYWRlciB0aGlzQ2xhc3NMb2FkZXIgPSBnZXRDbGFzcygpLmdldENsYXNzTG9hZGVyKCk7CgogICAgICAgIC8vIEFsbG93IHRoZSBmb2xsb3dpbmcgdG8gc3BlY2lmeSBhIGNsb3NlYWJsZSBjbGFzc2xvYWRlcgogICAgICAgIC8vIG90aGVyIHRoYW4gVVJMQ2xhc3NMb2FkZXIuCgogICAgICAgIC8vIDE6IEFsbG93IGNsaWVudCB0byBzcGVjaWZ5IHRoZSBjbGFzcyB0byB1c2UgdmlhIGhpZGRlbiBvcHRpb24KICAgICAgICBpZiAoY2xhc3NMb2FkZXJDbGFzcyAhPSBudWxsKSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBDbGFzczw/IGV4dGVuZHMgQ2xhc3NMb2FkZXI+IGxvYWRlciA9CiAgICAgICAgICAgICAgICAgICAgICAgIENsYXNzLmZvck5hbWUoY2xhc3NMb2FkZXJDbGFzcykuYXNTdWJjbGFzcyhDbGFzc0xvYWRlci5jbGFzcyk7CiAgICAgICAgICAgICAgICBDbGFzczw/PltdIGNvbnN0ckFyZ1R5cGVzID0geyBVUkxbXS5jbGFzcywgQ2xhc3NMb2FkZXIuY2xhc3MgfTsKICAgICAgICAgICAgICAgIENvbnN0cnVjdG9yPD8gZXh0ZW5kcyBDbGFzc0xvYWRlcj4gY29uc3RyID0gbG9hZGVyLmdldENvbnN0cnVjdG9yKGNvbnN0ckFyZ1R5cGVzKTsKICAgICAgICAgICAgICAgIHJldHVybiBlbnN1cmVSZWFkYWJsZShjb25zdHIubmV3SW5zdGFuY2UodXJscywgdGhpc0NsYXNzTG9hZGVyKSk7CiAgICAgICAgICAgIH0gY2F0Y2ggKFJlZmxlY3RpdmVPcGVyYXRpb25FeGNlcHRpb24gdCkgewogICAgICAgICAgICAgICAgLy8gaWdub3JlIGVycm9ycyBsb2FkaW5nIHVzZXItcHJvdmlkZWQgY2xhc3MgbG9hZGVyLCBmYWxsIHRocm91Z2gKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gZW5zdXJlUmVhZGFibGUobmV3IFVSTENsYXNzTG9hZGVyKHVybHMsIHRoaXNDbGFzc0xvYWRlcikpOwogICAgfQoKICAgIC8qKgogICAgICogRW5zdXJlcyB0aGF0IHRoZSB1bm5hbWVkIG1vZHVsZSBvZiB0aGUgZ2l2ZW4gY2xhc3Nsb2FkZXIgaXMgcmVhZGFibGUgdG8gdGhpcwogICAgICogbW9kdWxlLgogICAgICovCiAgICBwcml2YXRlIENsYXNzTG9hZGVyIGVuc3VyZVJlYWRhYmxlKENsYXNzTG9hZGVyIHRhcmdldExvYWRlcikgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIE1ldGhvZCBnZXRNb2R1bGVNZXRob2QgPSBDbGFzcy5jbGFzcy5nZXRNZXRob2QoImdldE1vZHVsZSIpOwogICAgICAgICAgICBPYmplY3QgdGhpc01vZHVsZSA9IGdldE1vZHVsZU1ldGhvZC5pbnZva2UodGhpcy5nZXRDbGFzcygpKTsKICAgICAgICAgICAgTWV0aG9kIGdldFVubmFtZWRNb2R1bGVNZXRob2QgPSBDbGFzc0xvYWRlci5jbGFzcy5nZXRNZXRob2QoImdldFVubmFtZWRNb2R1bGUiKTsKICAgICAgICAgICAgT2JqZWN0IHRhcmdldE1vZHVsZSA9IGdldFVubmFtZWRNb2R1bGVNZXRob2QuaW52b2tlKHRhcmdldExvYWRlcik7CgogICAgICAgICAgICBDbGFzczw/PiBtb2R1bGVDbGFzcyA9IGdldE1vZHVsZU1ldGhvZC5nZXRSZXR1cm5UeXBlKCk7CiAgICAgICAgICAgIE1ldGhvZCBhZGRSZWFkc01ldGhvZCA9IG1vZHVsZUNsYXNzLmdldE1ldGhvZCgiYWRkUmVhZHMiLCBtb2R1bGVDbGFzcyk7CiAgICAgICAgICAgIGFkZFJlYWRzTWV0aG9kLmludm9rZSh0aGlzTW9kdWxlLCB0YXJnZXRNb2R1bGUpOwogICAgICAgIH0gY2F0Y2ggKE5vU3VjaE1ldGhvZEV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIC8vIGlnbm9yZQogICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBY2Nlc3NFeGNlcHRpb24KICAgICAgICAgICAgICAgIHwgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCiAgICAgICAgICAgICAgICB8IFNlY3VyaXR5RXhjZXB0aW9uCiAgICAgICAgICAgICAgICB8IEludm9jYXRpb25UYXJnZXRFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgQWJvcnQoZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0YXJnZXRMb2FkZXI7CiAgICB9CgogICAgcHVibGljIGJvb2xlYW4gaXNEZWZhdWx0Qm9vdENsYXNzUGF0aCgpIHsKICAgICAgICByZXR1cm4gbG9jYXRpb25zLmlzRGVmYXVsdEJvb3RDbGFzc1BhdGgoKTsKICAgIH0KCiAgICAvLyA8ZWRpdG9yLWZvbGQgZGVmYXVsdHN0YXRlPSJjb2xsYXBzZWQiIGRlc2M9Ik9wdGlvbiBoYW5kbGluZyI+CiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICBwdWJsaWMgYm9vbGVhbiBoYW5kbGVPcHRpb24oU3RyaW5nIGN1cnJlbnQsIEl0ZXJhdG9yPFN0cmluZz4gcmVtYWluaW5nKSB7CiAgICAgICAgT3B0aW9uSGVscGVyIGhlbHBlciA9IG5ldyBHcnVtcHlIZWxwZXIobG9nKSB7CiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgU3RyaW5nIGdldChPcHRpb24gb3B0aW9uKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gb3B0aW9ucy5nZXQob3B0aW9uKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHB1YmxpYyB2b2lkIHB1dChTdHJpbmcgbmFtZSwgU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgICAgICAgICBvcHRpb25zLnB1dChuYW1lLCB2YWx1ZSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgdm9pZCByZW1vdmUoU3RyaW5nIG5hbWUpIHsKICAgICAgICAgICAgICAgIG9wdGlvbnMucmVtb3ZlKG5hbWUpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHVibGljIGJvb2xlYW4gaGFuZGxlRmlsZU1hbmFnZXJPcHRpb24oT3B0aW9uIG9wdGlvbiwgU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gaGFuZGxlT3B0aW9uKG9wdGlvbiwgdmFsdWUpOwogICAgICAgICAgICB9CiAgICAgICAgfTsKCiAgICAgICAgT3B0aW9uIG8gPSBPcHRpb24ubG9va3VwKGN1cnJlbnQsIGphdmFjRmlsZU1hbmFnZXJPcHRpb25zKTsKICAgICAgICBpZiAobyA9PSBudWxsKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIHRyeSB7CiAgICAgICAgICAgIG8uaGFuZGxlT3B0aW9uKGhlbHBlciwgY3VycmVudCwgcmVtYWluaW5nKTsKICAgICAgICB9IGNhdGNoIChPcHRpb24uSW52YWxpZFZhbHVlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihlLmdldE1lc3NhZ2UoKSwgZSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KICAgIC8vIHdoZXJlCiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU2V0PE9wdGlvbj4gamF2YWNGaWxlTWFuYWdlck9wdGlvbnMgPQogICAgICAgICAgICBPcHRpb24uZ2V0SmF2YWNGaWxlTWFuYWdlck9wdGlvbnMoKTsKCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICBwdWJsaWMgaW50IGlzU3VwcG9ydGVkT3B0aW9uKFN0cmluZyBvcHRpb24pIHsKICAgICAgICBPcHRpb24gbyA9IE9wdGlvbi5sb29rdXAob3B0aW9uLCBqYXZhY0ZpbGVNYW5hZ2VyT3B0aW9ucyk7CiAgICAgICAgcmV0dXJuIChvID09IG51bGwpID8gLTEgOiBvLmhhc0FyZygpID8gMSA6IDA7CiAgICB9CgogICAgcHJvdGVjdGVkIFN0cmluZyBtdWx0aVJlbGVhc2VWYWx1ZTsKCiAgICAvKioKICAgICAqIENvbW1vbiBiYWNrIGVuZCBmb3IgT3B0aW9uSGVscGVyIGhhbmRsZUZpbGVNYW5hZ2VyT3B0aW9uLgogICAgICogQHBhcmFtIG9wdGlvbiB0aGUgb3B0aW9uIHdob3NlIHZhbHVlIHRvIGJlIHNldAogICAgICogQHBhcmFtIHZhbHVlIHRoZSB2YWx1ZSBmb3IgdGhlIG9wdGlvbgogICAgICogQHJldHVybiB0cnVlIGlmIHN1Y2Nlc3NmdWwsIGFuZCBmYWxzZSBvdGhlcndpc2UKICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gaGFuZGxlT3B0aW9uKE9wdGlvbiBvcHRpb24sIFN0cmluZyB2YWx1ZSkgewogICAgICAgIHN3aXRjaCAob3B0aW9uKSB7CiAgICAgICAgICAgIGNhc2UgRU5DT0RJTkc6CiAgICAgICAgICAgICAgICBlbmNvZGluZ05hbWUgPSB2YWx1ZTsKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwoKICAgICAgICAgICAgY2FzZSBNVUxUSVJFTEVBU0U6CiAgICAgICAgICAgICAgICBtdWx0aVJlbGVhc2VWYWx1ZSA9IHZhbHVlOwogICAgICAgICAgICAgICAgbG9jYXRpb25zLnNldE11bHRpUmVsZWFzZVZhbHVlKHZhbHVlKTsKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwoKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIHJldHVybiBsb2NhdGlvbnMuaGFuZGxlT3B0aW9uKG9wdGlvbiwgdmFsdWUpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIENhbGwgaGFuZGxlT3B0aW9uIGZvciBjb2xsZWN0aW9uIG9mIG9wdGlvbnMgYW5kIGNvcnJlc3BvbmRpbmcgdmFsdWVzLgogICAgICogQHBhcmFtIG1hcCBhIGNvbGxlY3Rpb24gb2Ygb3B0aW9ucyBhbmQgY29ycmVzcG9uZGluZyB2YWx1ZXMKICAgICAqIEByZXR1cm4gdHJ1ZSBpZiBhbGwgdGhlIGNhbGxzIGFyZSBzdWNjZXNzZnVsCiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGhhbmRsZU9wdGlvbnMoTWFwPE9wdGlvbiwgU3RyaW5nPiBtYXApIHsKICAgICAgICBib29sZWFuIG9rID0gdHJ1ZTsKICAgICAgICBmb3IgKE1hcC5FbnRyeTxPcHRpb24sIFN0cmluZz4gZTogbWFwLmVudHJ5U2V0KCkpIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIG9rID0gb2sgJiBoYW5kbGVPcHRpb24oZS5nZXRLZXkoKSwgZS5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4KSB7CiAgICAgICAgICAgICAgICBsb2cuZXJyb3IoRXJyb3JzLklsbGVnYWxBcmd1bWVudEZvck9wdGlvbihlLmdldEtleSgpLmdldFByaW1hcnlOYW1lKCksIGV4LmdldE1lc3NhZ2UoKSkpOwogICAgICAgICAgICAgICAgb2sgPSBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gb2s7CiAgICB9CgogICAgLy8gPC9lZGl0b3ItZm9sZD4KCiAgICAvLyA8ZWRpdG9yLWZvbGQgZGVmYXVsdHN0YXRlPSJjb2xsYXBzZWQiIGRlc2M9IkVuY29kaW5nIj4KICAgIHByaXZhdGUgU3RyaW5nIGVuY29kaW5nTmFtZTsKICAgIHByaXZhdGUgU3RyaW5nIGRlZmF1bHRFbmNvZGluZ05hbWU7CiAgICBwcml2YXRlIFN0cmluZyBnZXREZWZhdWx0RW5jb2RpbmdOYW1lKCkgewogICAgICAgIGlmIChkZWZhdWx0RW5jb2RpbmdOYW1lID09IG51bGwpIHsKICAgICAgICAgICAgZGVmYXVsdEVuY29kaW5nTmFtZSA9IENoYXJzZXQuZGVmYXVsdENoYXJzZXQoKS5uYW1lKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBkZWZhdWx0RW5jb2RpbmdOYW1lOwogICAgfQoKICAgIHB1YmxpYyBTdHJpbmcgZ2V0RW5jb2RpbmdOYW1lKCkgewogICAgICAgIHJldHVybiAoZW5jb2RpbmdOYW1lICE9IG51bGwpID8gZW5jb2RpbmdOYW1lIDogZ2V0RGVmYXVsdEVuY29kaW5nTmFtZSgpOwogICAgfQoKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJjYXN0IikKICAgIHB1YmxpYyBDaGFyQnVmZmVyIGRlY29kZShCeXRlQnVmZmVyIGluYnVmLCBib29sZWFuIGlnbm9yZUVuY29kaW5nRXJyb3JzKSB7CiAgICAgICAgU3RyaW5nIGVuY05hbWUgPSBnZXRFbmNvZGluZ05hbWUoKTsKICAgICAgICBDaGFyc2V0RGVjb2RlciBkZWNvZGVyOwogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGRlY29kZXIgPSBnZXREZWNvZGVyKGVuY05hbWUsIGlnbm9yZUVuY29kaW5nRXJyb3JzKTsKICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQ2hhcnNldE5hbWVFeGNlcHRpb24gfCBVbnN1cHBvcnRlZENoYXJzZXRFeGNlcHRpb24gZSkgewogICAgICAgICAgICBsb2cuZXJyb3IoInVuc3VwcG9ydGVkLmVuY29kaW5nIiwgZW5jTmFtZSk7CiAgICAgICAgICAgIHJldHVybiAoQ2hhckJ1ZmZlcilDaGFyQnVmZmVyLmFsbG9jYXRlKDEpLmZsaXAoKTsKICAgICAgICB9CgogICAgICAgIC8vIHNsaWdodGx5IG92ZXJlc3RpbWF0ZSB0aGUgYnVmZmVyIHNpemUgdG8gYXZvaWQgcmVhbGxvY2F0aW9uLgogICAgICAgIGZsb2F0IGZhY3RvciA9CiAgICAgICAgICAgIGRlY29kZXIuYXZlcmFnZUNoYXJzUGVyQnl0ZSgpICogMC44ZiArCiAgICAgICAgICAgIGRlY29kZXIubWF4Q2hhcnNQZXJCeXRlKCkgKiAwLjJmOwogICAgICAgIENoYXJCdWZmZXIgZGVzdCA9IENoYXJCdWZmZXIuCiAgICAgICAgICAgIGFsbG9jYXRlKDEwICsgKGludCkoaW5idWYucmVtYWluaW5nKCkqZmFjdG9yKSk7CgogICAgICAgIHdoaWxlICh0cnVlKSB7CiAgICAgICAgICAgIENvZGVyUmVzdWx0IHJlc3VsdCA9IGRlY29kZXIuZGVjb2RlKGluYnVmLCBkZXN0LCB0cnVlKTsKICAgICAgICAgICAgZGVzdC5mbGlwKCk7CgogICAgICAgICAgICBpZiAocmVzdWx0LmlzVW5kZXJmbG93KCkpIHsgLy8gZG9uZSByZWFkaW5nCiAgICAgICAgICAgICAgICAvLyBtYWtlIHN1cmUgdGhlcmUgaXMgYXQgbGVhc3Qgb25lIGV4dHJhIGNoYXJhY3RlcgogICAgICAgICAgICAgICAgaWYgKGRlc3QubGltaXQoKSA9PSBkZXN0LmNhcGFjaXR5KCkpIHsKICAgICAgICAgICAgICAgICAgICBkZXN0ID0gQ2hhckJ1ZmZlci5hbGxvY2F0ZShkZXN0LmNhcGFjaXR5KCkrMSkucHV0KGRlc3QpOwogICAgICAgICAgICAgICAgICAgIGRlc3QuZmxpcCgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIGRlc3Q7CiAgICAgICAgICAgIH0gZWxzZSBpZiAocmVzdWx0LmlzT3ZlcmZsb3coKSkgeyAvLyBidWZmZXIgdG9vIHNtYWxsOyBleHBhbmQKICAgICAgICAgICAgICAgIGludCBuZXdDYXBhY2l0eSA9CiAgICAgICAgICAgICAgICAgICAgMTAgKyBkZXN0LmNhcGFjaXR5KCkgKwogICAgICAgICAgICAgICAgICAgIChpbnQpKGluYnVmLnJlbWFpbmluZygpKmRlY29kZXIubWF4Q2hhcnNQZXJCeXRlKCkpOwogICAgICAgICAgICAgICAgZGVzdCA9IENoYXJCdWZmZXIuYWxsb2NhdGUobmV3Q2FwYWNpdHkpLnB1dChkZXN0KTsKICAgICAgICAgICAgfSBlbHNlIGlmIChyZXN1bHQuaXNNYWxmb3JtZWQoKSB8fCByZXN1bHQuaXNVbm1hcHBhYmxlKCkpIHsKICAgICAgICAgICAgICAgIC8vIGJhZCBjaGFyYWN0ZXIgaW4gaW5wdXQKICAgICAgICAgICAgICAgIFN0cmluZ0J1aWxkZXIgdW5tYXBwYWJsZSA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGVuID0gcmVzdWx0Lmxlbmd0aCgpOwoKICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICB1bm1hcHBhYmxlLmFwcGVuZChTdHJpbmcuZm9ybWF0KCIlMDJYIiwgaW5idWYuZ2V0KCkpKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBTdHJpbmcgY2hhcnNldE5hbWUgPSBjaGFyc2V0ID09IG51bGwgPyBlbmNOYW1lIDogY2hhcnNldC5uYW1lKCk7CgogICAgICAgICAgICAgICAgbG9nLmVycm9yKGRlc3QubGltaXQoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICBFcnJvcnMuSWxsZWdhbENoYXJGb3JFbmNvZGluZyh1bm1hcHBhYmxlLnRvU3RyaW5nKCksIGNoYXJzZXROYW1lKSk7CgogICAgICAgICAgICAgICAgLy8gdW5kbyB0aGUgZmxpcCgpIHRvIHByZXBhcmUgdGhlIG91dHB1dCBidWZmZXIKICAgICAgICAgICAgICAgIC8vIGZvciBtb3JlIHRyYW5zbGF0aW9uCiAgICAgICAgICAgICAgICBkZXN0LnBvc2l0aW9uKGRlc3QubGltaXQoKSk7CiAgICAgICAgICAgICAgICBkZXN0LmxpbWl0KGRlc3QuY2FwYWNpdHkoKSk7CiAgICAgICAgICAgICAgICBkZXN0LnB1dCgoY2hhcikweGZmZmQpOyAvLyBiYWNrd2FyZCBjb21wYXRpYmxlCiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IocmVzdWx0KTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvLyB1bnJlYWNoZWQKICAgIH0KCiAgICBwdWJsaWMgQ2hhcnNldERlY29kZXIgZ2V0RGVjb2RlcihTdHJpbmcgZW5jb2RpbmdOYW1lLCBib29sZWFuIGlnbm9yZUVuY29kaW5nRXJyb3JzKSB7CiAgICAgICAgQ2hhcnNldCBjcyA9ICh0aGlzLmNoYXJzZXQgPT0gbnVsbCkKICAgICAgICAgICAgPyBDaGFyc2V0LmZvck5hbWUoZW5jb2RpbmdOYW1lKQogICAgICAgICAgICA6IHRoaXMuY2hhcnNldDsKICAgICAgICBDaGFyc2V0RGVjb2RlciBkZWNvZGVyID0gY3MubmV3RGVjb2RlcigpOwoKICAgICAgICBDb2RpbmdFcnJvckFjdGlvbiBhY3Rpb247CiAgICAgICAgaWYgKGlnbm9yZUVuY29kaW5nRXJyb3JzKQogICAgICAgICAgICBhY3Rpb24gPSBDb2RpbmdFcnJvckFjdGlvbi5SRVBMQUNFOwogICAgICAgIGVsc2UKICAgICAgICAgICAgYWN0aW9uID0gQ29kaW5nRXJyb3JBY3Rpb24uUkVQT1JUOwoKICAgICAgICByZXR1cm4gZGVjb2RlcgogICAgICAgICAgICAub25NYWxmb3JtZWRJbnB1dChhY3Rpb24pCiAgICAgICAgICAgIC5vblVubWFwcGFibGVDaGFyYWN0ZXIoYWN0aW9uKTsKICAgIH0KICAgIC8vIDwvZWRpdG9yLWZvbGQ+CgogICAgLy8gPGVkaXRvci1mb2xkIGRlZmF1bHRzdGF0ZT0iY29sbGFwc2VkIiBkZXNjPSJCeXRlQnVmZmVycyI+CiAgICAvKioKICAgICAqIE1ha2UgYSBieXRlIGJ1ZmZlciBmcm9tIGFuIGlucHV0IHN0cmVhbS4KICAgICAqIEBwYXJhbSBpbiB0aGUgc3RyZWFtCiAgICAgKiBAcmV0dXJuIGEgYnl0ZSBidWZmZXIgY29udGFpbmluZyB0aGUgY29udGVudHMgb2YgdGhlIHN0cmVhbQogICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiBhbiBlcnJvciBvY2N1cnJlZCB3aGlsZSByZWFkaW5nIHRoZSBzdHJlYW0KICAgICAqLwogICAgQFN1cHByZXNzV2FybmluZ3MoImNhc3QiKQogICAgcHVibGljIEJ5dGVCdWZmZXIgbWFrZUJ5dGVCdWZmZXIoSW5wdXRTdHJlYW0gaW4pCiAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICBpbnQgbGltaXQgPSBpbi5hdmFpbGFibGUoKTsKICAgICAgICBpZiAobGltaXQgPCAxMDI0KSBsaW1pdCA9IDEwMjQ7CiAgICAgICAgQnl0ZUJ1ZmZlciByZXN1bHQgPSBieXRlQnVmZmVyQ2FjaGUuZ2V0KGxpbWl0KTsKICAgICAgICBpbnQgcG9zaXRpb24gPSAwOwogICAgICAgIHdoaWxlIChpbi5hdmFpbGFibGUoKSAhPSAwKSB7CiAgICAgICAgICAgIGlmIChwb3NpdGlvbiA+PSBsaW1pdCkKICAgICAgICAgICAgICAgIC8vIGV4cGFuZCBidWZmZXIKICAgICAgICAgICAgICAgIHJlc3VsdCA9IEJ5dGVCdWZmZXIuCiAgICAgICAgICAgICAgICAgICAgYWxsb2NhdGUobGltaXQgPDw9IDEpLgogICAgICAgICAgICAgICAgICAgIHB1dCgoQnl0ZUJ1ZmZlcilyZXN1bHQuZmxpcCgpKTsKICAgICAgICAgICAgaW50IGNvdW50ID0gaW4ucmVhZChyZXN1bHQuYXJyYXkoKSwKICAgICAgICAgICAgICAgIHBvc2l0aW9uLAogICAgICAgICAgICAgICAgbGltaXQgLSBwb3NpdGlvbik7CiAgICAgICAgICAgIGlmIChjb3VudCA8IDApIGJyZWFrOwogICAgICAgICAgICByZXN1bHQucG9zaXRpb24ocG9zaXRpb24gKz0gY291bnQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gKEJ5dGVCdWZmZXIpcmVzdWx0LmZsaXAoKTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCByZWN5Y2xlQnl0ZUJ1ZmZlcihCeXRlQnVmZmVyIGJiKSB7CiAgICAgICAgYnl0ZUJ1ZmZlckNhY2hlLnB1dChiYik7CiAgICB9CgogICAgLyoqCiAgICAgKiBBIHNpbmdsZS1lbGVtZW50IGNhY2hlIG9mIGRpcmVjdCBieXRlIGJ1ZmZlcnMuCiAgICAgKi8KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJjYXN0IikKICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIEJ5dGVCdWZmZXJDYWNoZSB7CiAgICAgICAgcHJpdmF0ZSBCeXRlQnVmZmVyIGNhY2hlZDsKICAgICAgICBCeXRlQnVmZmVyIGdldChpbnQgY2FwYWNpdHkpIHsKICAgICAgICAgICAgaWYgKGNhcGFjaXR5IDwgMjA0ODApIGNhcGFjaXR5ID0gMjA0ODA7CiAgICAgICAgICAgIEJ5dGVCdWZmZXIgcmVzdWx0ID0KICAgICAgICAgICAgICAgIChjYWNoZWQgIT0gbnVsbCAmJiBjYWNoZWQuY2FwYWNpdHkoKSA+PSBjYXBhY2l0eSkKICAgICAgICAgICAgICAgID8gKEJ5dGVCdWZmZXIpY2FjaGVkLmNsZWFyKCkKICAgICAgICAgICAgICAgIDogQnl0ZUJ1ZmZlci5hbGxvY2F0ZShjYXBhY2l0eSArIGNhcGFjaXR5Pj4xKTsKICAgICAgICAgICAgY2FjaGVkID0gbnVsbDsKICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CiAgICAgICAgdm9pZCBwdXQoQnl0ZUJ1ZmZlciB4KSB7CiAgICAgICAgICAgIGNhY2hlZCA9IHg7CiAgICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgZmluYWwgQnl0ZUJ1ZmZlckNhY2hlIGJ5dGVCdWZmZXJDYWNoZTsKICAgIC8vIDwvZWRpdG9yLWZvbGQ+CgogICAgLy8gPGVkaXRvci1mb2xkIGRlZmF1bHRzdGF0ZT0iY29sbGFwc2VkIiBkZXNjPSJDb250ZW50IGNhY2hlIj4KICAgIHB1YmxpYyBDaGFyQnVmZmVyIGdldENhY2hlZENvbnRlbnQoSmF2YUZpbGVPYmplY3QgZmlsZSkgewogICAgICAgIENvbnRlbnRDYWNoZUVudHJ5IGUgPSBjb250ZW50Q2FjaGUuZ2V0KGZpbGUpOwogICAgICAgIGlmIChlID09IG51bGwpCiAgICAgICAgICAgIHJldHVybiBudWxsOwoKICAgICAgICBpZiAoIWUuaXNWYWxpZChmaWxlKSkgewogICAgICAgICAgICBjb250ZW50Q2FjaGUucmVtb3ZlKGZpbGUpOwogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgIHJldHVybiBlLmdldFZhbHVlKCk7CiAgICB9CgogICAgcHVibGljIHZvaWQgY2FjaGUoSmF2YUZpbGVPYmplY3QgZmlsZSwgQ2hhckJ1ZmZlciBjYikgewogICAgICAgIGNvbnRlbnRDYWNoZS5wdXQoZmlsZSwgbmV3IENvbnRlbnRDYWNoZUVudHJ5KGZpbGUsIGNiKSk7CiAgICB9CgogICAgcHVibGljIHZvaWQgZmx1c2hDYWNoZShKYXZhRmlsZU9iamVjdCBmaWxlKSB7CiAgICAgICAgY29udGVudENhY2hlLnJlbW92ZShmaWxlKTsKICAgIH0KCiAgICBwcm90ZWN0ZWQgZmluYWwgTWFwPEphdmFGaWxlT2JqZWN0LCBDb250ZW50Q2FjaGVFbnRyeT4gY29udGVudENhY2hlID0gbmV3IEhhc2hNYXA8PigpOwoKICAgIHByb3RlY3RlZCBzdGF0aWMgY2xhc3MgQ29udGVudENhY2hlRW50cnkgewogICAgICAgIGZpbmFsIGxvbmcgdGltZXN0YW1wOwogICAgICAgIGZpbmFsIFNvZnRSZWZlcmVuY2U8Q2hhckJ1ZmZlcj4gcmVmOwoKICAgICAgICBDb250ZW50Q2FjaGVFbnRyeShKYXZhRmlsZU9iamVjdCBmaWxlLCBDaGFyQnVmZmVyIGNiKSB7CiAgICAgICAgICAgIHRoaXMudGltZXN0YW1wID0gZmlsZS5nZXRMYXN0TW9kaWZpZWQoKTsKICAgICAgICAgICAgdGhpcy5yZWYgPSBuZXcgU29mdFJlZmVyZW5jZTw+KGNiKTsKICAgICAgICB9CgogICAgICAgIGJvb2xlYW4gaXNWYWxpZChKYXZhRmlsZU9iamVjdCBmaWxlKSB7CiAgICAgICAgICAgIHJldHVybiB0aW1lc3RhbXAgPT0gZmlsZS5nZXRMYXN0TW9kaWZpZWQoKTsKICAgICAgICB9CgogICAgICAgIENoYXJCdWZmZXIgZ2V0VmFsdWUoKSB7CiAgICAgICAgICAgIHJldHVybiByZWYuZ2V0KCk7CiAgICAgICAgfQogICAgfQogICAgLy8gPC9lZGl0b3ItZm9sZD4KCiAgICBwdWJsaWMgc3RhdGljIEtpbmQgZ2V0S2luZChQYXRoIHBhdGgpIHsKICAgICAgICByZXR1cm4gZ2V0S2luZChwYXRoLmdldEZpbGVOYW1lKCkudG9TdHJpbmcoKSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBLaW5kIGdldEtpbmQoU3RyaW5nIG5hbWUpIHsKICAgICAgICBpZiAobmFtZS5lbmRzV2l0aChLaW5kLkNMQVNTLmV4dGVuc2lvbikpCiAgICAgICAgICAgIHJldHVybiBLaW5kLkNMQVNTOwogICAgICAgIGVsc2UgaWYgKG5hbWUuZW5kc1dpdGgoS2luZC5TT1VSQ0UuZXh0ZW5zaW9uKSkKICAgICAgICAgICAgcmV0dXJuIEtpbmQuU09VUkNFOwogICAgICAgIGVsc2UgaWYgKG5hbWUuZW5kc1dpdGgoS2luZC5IVE1MLmV4dGVuc2lvbikpCiAgICAgICAgICAgIHJldHVybiBLaW5kLkhUTUw7CiAgICAgICAgZWxzZQogICAgICAgICAgICByZXR1cm4gS2luZC5PVEhFUjsKICAgIH0KCiAgICBwcm90ZWN0ZWQgc3RhdGljIDxUPiBUIG51bGxDaGVjayhUIG8pIHsKICAgICAgICByZXR1cm4gT2JqZWN0cy5yZXF1aXJlTm9uTnVsbChvKTsKICAgIH0KCiAgICBwcm90ZWN0ZWQgc3RhdGljIDxUPiBDb2xsZWN0aW9uPFQ+IG51bGxDaGVjayhDb2xsZWN0aW9uPFQ+IGl0KSB7CiAgICAgICAgZm9yIChUIHQgOiBpdCkKICAgICAgICAgICAgT2JqZWN0cy5yZXF1aXJlTm9uTnVsbCh0KTsKICAgICAgICByZXR1cm4gaXQ7CiAgICB9Cn0KUEsDBAoAAAgAAAY7qUonDsmpvxQBAL8UAQAnAAAAY29tL3N1bi90b29scy9qYXZhYy9maWxlL0xvY2F0aW9ucy5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDAzLCAyMDE3LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuamF2YWMuZmlsZTsKCmltcG9ydCBqYXZhLmlvLkNsb3NlYWJsZTsKaW1wb3J0IGphdmEuaW8uRmlsZTsKaW1wb3J0IGphdmEuaW8uRmlsZU5vdEZvdW5kRXhjZXB0aW9uOwppbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKaW1wb3J0IGphdmEuaW8uVW5jaGVja2VkSU9FeGNlcHRpb247CmltcG9ydCBqYXZhLm5ldC5VUkk7CmltcG9ydCBqYXZhLm5ldC5VUkw7CmltcG9ydCBqYXZhLm5ldC5VUkxDbGFzc0xvYWRlcjsKaW1wb3J0IGphdmEubmlvLmZpbGUuRGlyZWN0b3J5SXRlcmF0b3JFeGNlcHRpb247CmltcG9ydCBqYXZhLm5pby5maWxlLkRpcmVjdG9yeVN0cmVhbTsKaW1wb3J0IGphdmEubmlvLmZpbGUuRmlsZVN5c3RlbTsKaW1wb3J0IGphdmEubmlvLmZpbGUuRmlsZVN5c3RlbU5vdEZvdW5kRXhjZXB0aW9uOwppbXBvcnQgamF2YS5uaW8uZmlsZS5GaWxlU3lzdGVtczsKaW1wb3J0IGphdmEubmlvLmZpbGUuRmlsZXM7CmltcG9ydCBqYXZhLm5pby5maWxlLkludmFsaWRQYXRoRXhjZXB0aW9uOwppbXBvcnQgamF2YS5uaW8uZmlsZS5QYXRoOwppbXBvcnQgamF2YS5uaW8uZmlsZS5QYXRoczsKaW1wb3J0IGphdmEubmlvLmZpbGUuUHJvdmlkZXJOb3RGb3VuZEV4Y2VwdGlvbjsKaW1wb3J0IGphdmEubmlvLmZpbGUuc3BpLkZpbGVTeXN0ZW1Qcm92aWRlcjsKaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CmltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOwppbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb247CmltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbnM7CmltcG9ydCBqYXZhLnV0aWwuRW51bU1hcDsKaW1wb3J0IGphdmEudXRpbC5FbnVtU2V0OwppbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CmltcG9ydCBqYXZhLnV0aWwuSGFzaFNldDsKaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKaW1wb3J0IGphdmEudXRpbC5MaW5rZWRIYXNoTWFwOwppbXBvcnQgamF2YS51dGlsLkxpbmtlZEhhc2hTZXQ7CmltcG9ydCBqYXZhLnV0aWwuTGlzdDsKaW1wb3J0IGphdmEudXRpbC5NYXA7CmltcG9ydCBqYXZhLnV0aWwuT2JqZWN0czsKaW1wb3J0IGphdmEudXRpbC5Ob1N1Y2hFbGVtZW50RXhjZXB0aW9uOwppbXBvcnQgamF2YS51dGlsLlNldDsKaW1wb3J0IGphdmEudXRpbC5mdW5jdGlvbi5QcmVkaWNhdGU7CmltcG9ydCBqYXZhLnV0aWwucmVnZXguTWF0Y2hlcjsKaW1wb3J0IGphdmEudXRpbC5yZWdleC5QYXR0ZXJuOwppbXBvcnQgamF2YS51dGlsLnN0cmVhbS5Db2xsZWN0b3JzOwppbXBvcnQgamF2YS51dGlsLnN0cmVhbS5TdHJlYW07CgppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5Tb3VyY2VWZXJzaW9uOwppbXBvcnQgamF2YXgudG9vbHMuSmF2YUZpbGVNYW5hZ2VyOwppbXBvcnQgamF2YXgudG9vbHMuSmF2YUZpbGVNYW5hZ2VyLkxvY2F0aW9uOwppbXBvcnQgamF2YXgudG9vbHMuSmF2YUZpbGVPYmplY3Q7CmltcG9ydCBqYXZheC50b29scy5TdGFuZGFyZEphdmFGaWxlTWFuYWdlcjsKaW1wb3J0IGphdmF4LnRvb2xzLlN0YW5kYXJkSmF2YUZpbGVNYW5hZ2VyLlBhdGhGYWN0b3J5OwppbXBvcnQgamF2YXgudG9vbHMuU3RhbmRhcmRMb2NhdGlvbjsKCmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuTGludDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5MaW50LkxpbnRDYXRlZ29yeTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMubWFpbi5PcHRpb247CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnJlc291cmNlcy5Db21waWxlclByb3BlcnRpZXMuRXJyb3JzOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5yZXNvdXJjZXMuQ29tcGlsZXJQcm9wZXJ0aWVzLldhcm5pbmdzOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkRlZmluZWRCeTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5EZWZpbmVkQnkuQXBpOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkpESzlXcmFwcGVyczsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5MaXN0QnVmZmVyOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkxvZzsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuanZtLk1vZHVsZU5hbWVSZWFkZXI7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuUGFpcjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5TdHJpbmdVdGlsczsKCmltcG9ydCBzdGF0aWMgamF2YXgudG9vbHMuU3RhbmRhcmRMb2NhdGlvbi5QTEFURk9STV9DTEFTU19QQVRIOwoKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLm1haW4uT3B0aW9uLkJPT1RfQ0xBU1NfUEFUSDsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLm1haW4uT3B0aW9uLkRKQVZBX0VORE9SU0VEX0RJUlM7CmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5tYWluLk9wdGlvbi5ESkFWQV9FWFRfRElSUzsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLm1haW4uT3B0aW9uLkVORE9SU0VERElSUzsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLm1haW4uT3B0aW9uLkVYVERJUlM7CmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5tYWluLk9wdGlvbi5YQk9PVENMQVNTUEFUSDsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLm1haW4uT3B0aW9uLlhCT09UQ0xBU1NQQVRIX0FQUEVORDsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLm1haW4uT3B0aW9uLlhCT09UQ0xBU1NQQVRIX1BSRVBFTkQ7CgovKioKICogVGhpcyBjbGFzcyBjb252ZXJ0cyBjb21tYW5kIGxpbmUgYXJndW1lbnRzLCBlbnZpcm9ubWVudCB2YXJpYWJsZXMgYW5kIHN5c3RlbSBwcm9wZXJ0aWVzIChpbgogKiBGaWxlLnBhdGhTZXBhcmF0b3Itc2VwYXJhdGVkIFN0cmluZyBmb3JtKSBpbnRvIGEgYm9vdCBjbGFzcyBwYXRoLCB1c2VyIGNsYXNzIHBhdGgsIGFuZCBzb3VyY2UKICogcGF0aCAoaW4ge0Bjb2RlIENvbGxlY3Rpb248U3RyaW5nPn0gZm9ybSkuCiAqCiAqIDxwPgogKiA8Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLiBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0CiAqIHlvdXIgb3duIHJpc2suIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yIGRlbGV0aW9uIHdpdGhvdXQKICogbm90aWNlLjwvYj4KICovCnB1YmxpYyBjbGFzcyBMb2NhdGlvbnMgewoKICAgIC8qKgogICAgICogVGhlIGxvZyB0byB1c2UgZm9yIHdhcm5pbmcgb3V0cHV0CiAgICAgKi8KICAgIHByaXZhdGUgTG9nIGxvZzsKCiAgICAvKioKICAgICAqIEFjY2VzcyB0byAocG9zc2libHkgY2FjaGVkKSBmaWxlIGluZm8KICAgICAqLwogICAgcHJpdmF0ZSBGU0luZm8gZnNJbmZvOwoKICAgIC8qKgogICAgICogV2hldGhlciB0byB3YXJuIGFib3V0IG5vbi1leGlzdGVudCBwYXRoIGVsZW1lbnRzCiAgICAgKi8KICAgIHByaXZhdGUgYm9vbGVhbiB3YXJuOwoKICAgIHByaXZhdGUgTW9kdWxlTmFtZVJlYWRlciBtb2R1bGVOYW1lUmVhZGVyOwoKICAgIHByaXZhdGUgUGF0aEZhY3RvcnkgcGF0aEZhY3RvcnkgPSBQYXRoczo6Z2V0OwoKICAgIHN0YXRpYyBmaW5hbCBQYXRoIGphdmFIb21lID0gRmlsZVN5c3RlbXMuZ2V0RGVmYXVsdCgpLmdldFBhdGgoU3lzdGVtLmdldFByb3BlcnR5KCJqYXZhLmhvbWUiKSk7CiAgICBzdGF0aWMgZmluYWwgUGF0aCB0aGlzU3lzdGVtTW9kdWxlcyA9IGphdmFIb21lLnJlc29sdmUoImxpYiIpLnJlc29sdmUoIm1vZHVsZXMiKTsKCiAgICBNYXA8UGF0aCwgRmlsZVN5c3RlbT4gZmlsZVN5c3RlbXMgPSBuZXcgTGlua2VkSGFzaE1hcDw+KCk7CiAgICBMaXN0PENsb3NlYWJsZT4gY2xvc2VhYmxlcyA9IG5ldyBBcnJheUxpc3Q8PigpOwogICAgcHJpdmF0ZSBNYXA8U3RyaW5nLFN0cmluZz4gZnNFbnYgPSBDb2xsZWN0aW9ucy5lbXB0eU1hcCgpOwoKICAgIExvY2F0aW9ucygpIHsKICAgICAgICBpbml0SGFuZGxlcnMoKTsKICAgIH0KCiAgICBQYXRoIGdldFBhdGgoU3RyaW5nIGZpcnN0LCBTdHJpbmcuLi4gbW9yZSkgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIHJldHVybiBwYXRoRmFjdG9yeS5nZXRQYXRoKGZpcnN0LCBtb3JlKTsKICAgICAgICB9IGNhdGNoIChJbnZhbGlkUGF0aEV4Y2VwdGlvbiBpcGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihpcGUpOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgTGlzdEJ1ZmZlcjxJT0V4Y2VwdGlvbj4gbGlzdCA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICBjbG9zZWFibGVzLmZvckVhY2goY2xvc2VhYmxlIC0+IHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIGNsb3NlYWJsZS5jbG9zZSgpOwogICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgewogICAgICAgICAgICAgICAgbGlzdC5hZGQoZXgpOwogICAgICAgICAgICB9CiAgICAgICAgfSk7CiAgICAgICAgaWYgKGxpc3Qubm9uRW1wdHkoKSkgewogICAgICAgICAgICBJT0V4Y2VwdGlvbiBleCA9IG5ldyBJT0V4Y2VwdGlvbigpOwogICAgICAgICAgICBmb3IgKElPRXhjZXB0aW9uIGU6IGxpc3QpCiAgICAgICAgICAgICAgICBleC5hZGRTdXBwcmVzc2VkKGUpOwogICAgICAgICAgICB0aHJvdyBleDsKICAgICAgICB9CiAgICB9CgogICAgdm9pZCB1cGRhdGUoTG9nIGxvZywgYm9vbGVhbiB3YXJuLCBGU0luZm8gZnNJbmZvKSB7CiAgICAgICAgdGhpcy5sb2cgPSBsb2c7CiAgICAgICAgdGhpcy53YXJuID0gd2FybjsKICAgICAgICB0aGlzLmZzSW5mbyA9IGZzSW5mbzsKICAgIH0KCiAgICB2b2lkIHNldFBhdGhGYWN0b3J5KFBhdGhGYWN0b3J5IGYpIHsKICAgICAgICBwYXRoRmFjdG9yeSA9IGY7CiAgICB9CgogICAgYm9vbGVhbiBpc0RlZmF1bHRCb290Q2xhc3NQYXRoKCkgewogICAgICAgIEJvb3RDbGFzc1BhdGhMb2NhdGlvbkhhbmRsZXIgaAogICAgICAgICAgICAgICAgPSAoQm9vdENsYXNzUGF0aExvY2F0aW9uSGFuZGxlcikgZ2V0SGFuZGxlcihQTEFURk9STV9DTEFTU19QQVRIKTsKICAgICAgICByZXR1cm4gaC5pc0RlZmF1bHQoKTsKICAgIH0KCiAgICAvKioKICAgICAqIFNwbGl0IGEgc2VhcmNoIHBhdGggaW50byBpdHMgZWxlbWVudHMuIEVtcHR5IHBhdGggZWxlbWVudHMgd2lsbCBiZSBpZ25vcmVkLgogICAgICoKICAgICAqIEBwYXJhbSBzZWFyY2hQYXRoIFRoZSBzZWFyY2ggcGF0aCB0byBiZSBzcGxpdAogICAgICogQHJldHVybiBUaGUgZWxlbWVudHMgb2YgdGhlIHBhdGgKICAgICAqLwogICAgcHJpdmF0ZSBJdGVyYWJsZTxQYXRoPiBnZXRQYXRoRW50cmllcyhTdHJpbmcgc2VhcmNoUGF0aCkgewogICAgICAgIHJldHVybiBnZXRQYXRoRW50cmllcyhzZWFyY2hQYXRoLCBudWxsKTsKICAgIH0KCiAgICAvKioKICAgICAqIFNwbGl0IGEgc2VhcmNoIHBhdGggaW50byBpdHMgZWxlbWVudHMuIElmIGVtcHR5UGF0aERlZmF1bHQgaXMgbm90IG51bGwsIGFsbCBlbXB0eSBlbGVtZW50cyBpbiB0aGUKICAgICAqIHBhdGgsIGluY2x1ZGluZyBlbXB0eSBlbGVtZW50cyBhdCBlaXRoZXIgZW5kIG9mIHRoZSBwYXRoLCB3aWxsIGJlIHJlcGxhY2VkIHdpdGggdGhlIHZhbHVlIG9mCiAgICAgKiBlbXB0eVBhdGhEZWZhdWx0LgogICAgICoKICAgICAqIEBwYXJhbSBzZWFyY2hQYXRoIFRoZSBzZWFyY2ggcGF0aCB0byBiZSBzcGxpdAogICAgICogQHBhcmFtIGVtcHR5UGF0aERlZmF1bHQgVGhlIHZhbHVlIHRvIHN1YnN0aXR1dGUgZm9yIGVtcHR5IHBhdGggZWxlbWVudHMsIG9yIG51bGwsIHRvIGlnbm9yZQogICAgICogZW1wdHkgcGF0aCBlbGVtZW50cwogICAgICogQHJldHVybiBUaGUgZWxlbWVudHMgb2YgdGhlIHBhdGgKICAgICAqLwogICAgcHJpdmF0ZSBJdGVyYWJsZTxQYXRoPiBnZXRQYXRoRW50cmllcyhTdHJpbmcgc2VhcmNoUGF0aCwgUGF0aCBlbXB0eVBhdGhEZWZhdWx0KSB7CiAgICAgICAgTGlzdEJ1ZmZlcjxQYXRoPiBlbnRyaWVzID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgIGZvciAoU3RyaW5nIHM6IHNlYXJjaFBhdGguc3BsaXQoUGF0dGVybi5xdW90ZShGaWxlLnBhdGhTZXBhcmF0b3IpLCAtMSkpIHsKICAgICAgICAgICAgaWYgKHMuaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgICBpZiAoZW1wdHlQYXRoRGVmYXVsdCAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgZW50cmllcy5hZGQoZW1wdHlQYXRoRGVmYXVsdCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIGVudHJpZXMuYWRkKGdldFBhdGgocykpOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgICAgICAgICBpZiAod2FybikgewogICAgICAgICAgICAgICAgICAgICAgICBsb2cud2FybmluZyhMaW50Q2F0ZWdvcnkuUEFUSCwgImludmFsaWQucGF0aCIsIHMpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gZW50cmllczsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCBzZXRNdWx0aVJlbGVhc2VWYWx1ZShTdHJpbmcgbXVsdGlSZWxlYXNlVmFsdWUpIHsKICAgICAgICBmc0VudiA9IENvbGxlY3Rpb25zLnNpbmdsZXRvbk1hcCgibXVsdGktcmVsZWFzZSIsIG11bHRpUmVsZWFzZVZhbHVlKTsKICAgIH0KCiAgICAvKioKICAgICAqIFV0aWxpdHkgY2xhc3MgdG8gaGVscCBldmFsdWF0ZSBhIHBhdGggb3B0aW9uLiBEdXBsaWNhdGUgZW50cmllcyBhcmUgaWdub3JlZCwgamFyIGNsYXNzIHBhdGhzCiAgICAgKiBjYW4gYmUgZXhwYW5kZWQuCiAgICAgKi8KICAgIHByaXZhdGUgY2xhc3MgU2VhcmNoUGF0aCBleHRlbmRzIExpbmtlZEhhc2hTZXQ8UGF0aD4gewoKICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwOwoKICAgICAgICBwcml2YXRlIGJvb2xlYW4gZXhwYW5kSmFyQ2xhc3NQYXRocyA9IGZhbHNlOwogICAgICAgIHByaXZhdGUgZmluYWwgU2V0PFBhdGg+IGNhbm9uaWNhbFZhbHVlcyA9IG5ldyBIYXNoU2V0PD4oKTsKCiAgICAgICAgcHVibGljIFNlYXJjaFBhdGggZXhwYW5kSmFyQ2xhc3NQYXRocyhib29sZWFuIHgpIHsKICAgICAgICAgICAgZXhwYW5kSmFyQ2xhc3NQYXRocyA9IHg7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogV2hhdCB0byB1c2Ugd2hlbiBwYXRoIGVsZW1lbnQgaXMgdGhlIGVtcHR5IHN0cmluZwogICAgICAgICAqLwogICAgICAgIHByaXZhdGUgUGF0aCBlbXB0eVBhdGhEZWZhdWx0ID0gbnVsbDsKCiAgICAgICAgcHVibGljIFNlYXJjaFBhdGggZW1wdHlQYXRoRGVmYXVsdChQYXRoIHgpIHsKICAgICAgICAgICAgZW1wdHlQYXRoRGVmYXVsdCA9IHg7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIFNlYXJjaFBhdGggYWRkRGlyZWN0b3JpZXMoU3RyaW5nIGRpcnMsIGJvb2xlYW4gd2FybikgewogICAgICAgICAgICBib29sZWFuIHByZXYgPSBleHBhbmRKYXJDbGFzc1BhdGhzOwogICAgICAgICAgICBleHBhbmRKYXJDbGFzc1BhdGhzID0gdHJ1ZTsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIGlmIChkaXJzICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICBmb3IgKFBhdGggZGlyIDogZ2V0UGF0aEVudHJpZXMoZGlycykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgYWRkRGlyZWN0b3J5KGRpciwgd2Fybik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgICAgICBleHBhbmRKYXJDbGFzc1BhdGhzID0gcHJldjsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHVibGljIFNlYXJjaFBhdGggYWRkRGlyZWN0b3JpZXMoU3RyaW5nIGRpcnMpIHsKICAgICAgICAgICAgcmV0dXJuIGFkZERpcmVjdG9yaWVzKGRpcnMsIHdhcm4pOwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSB2b2lkIGFkZERpcmVjdG9yeShQYXRoIGRpciwgYm9vbGVhbiB3YXJuKSB7CiAgICAgICAgICAgIGlmICghRmlsZXMuaXNEaXJlY3RvcnkoZGlyKSkgewogICAgICAgICAgICAgICAgaWYgKHdhcm4pIHsKICAgICAgICAgICAgICAgICAgICBsb2cud2FybmluZyhMaW50LkxpbnRDYXRlZ29yeS5QQVRILAogICAgICAgICAgICAgICAgICAgICAgICAgICAgImRpci5wYXRoLmVsZW1lbnQubm90LmZvdW5kIiwgZGlyKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdHJ5IChTdHJlYW08UGF0aD4gcyA9IEZpbGVzLmxpc3QoZGlyKSkgewogICAgICAgICAgICAgICAgcy5maWx0ZXIoTG9jYXRpb25zLnRoaXM6OmlzQXJjaGl2ZSkKICAgICAgICAgICAgICAgICAgICAgICAgLmZvckVhY2goZGlyRW50cnkgLT4gYWRkRmlsZShkaXJFbnRyeSwgd2FybikpOwogICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBpZ25vcmUpIHsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHVibGljIFNlYXJjaFBhdGggYWRkRmlsZXMoU3RyaW5nIGZpbGVzLCBib29sZWFuIHdhcm4pIHsKICAgICAgICAgICAgaWYgKGZpbGVzICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIGFkZEZpbGVzKGdldFBhdGhFbnRyaWVzKGZpbGVzLCBlbXB0eVBhdGhEZWZhdWx0KSwgd2Fybik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgU2VhcmNoUGF0aCBhZGRGaWxlcyhTdHJpbmcgZmlsZXMpIHsKICAgICAgICAgICAgcmV0dXJuIGFkZEZpbGVzKGZpbGVzLCB3YXJuKTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBTZWFyY2hQYXRoIGFkZEZpbGVzKEl0ZXJhYmxlPD8gZXh0ZW5kcyBQYXRoPiBmaWxlcywgYm9vbGVhbiB3YXJuKSB7CiAgICAgICAgICAgIGlmIChmaWxlcyAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICBmb3IgKFBhdGggZmlsZSA6IGZpbGVzKSB7CiAgICAgICAgICAgICAgICAgICAgYWRkRmlsZShmaWxlLCB3YXJuKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBTZWFyY2hQYXRoIGFkZEZpbGVzKEl0ZXJhYmxlPD8gZXh0ZW5kcyBQYXRoPiBmaWxlcykgewogICAgICAgICAgICByZXR1cm4gYWRkRmlsZXMoZmlsZXMsIHdhcm4pOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHZvaWQgYWRkRmlsZShQYXRoIGZpbGUsIGJvb2xlYW4gd2FybikgewogICAgICAgICAgICBpZiAoY29udGFpbnMoZmlsZSkpIHsKICAgICAgICAgICAgICAgIC8vIGRpc2NhcmQgZHVwbGljYXRlcwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoIWZzSW5mby5leGlzdHMoZmlsZSkpIHsKICAgICAgICAgICAgICAgIC8qIE5vIHN1Y2ggZmlsZSBvciBkaXJlY3RvcnkgZXhpc3RzICovCiAgICAgICAgICAgICAgICBpZiAod2FybikgewogICAgICAgICAgICAgICAgICAgIGxvZy53YXJuaW5nKExpbnQuTGludENhdGVnb3J5LlBBVEgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAicGF0aC5lbGVtZW50Lm5vdC5mb3VuZCIsIGZpbGUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgc3VwZXIuYWRkKGZpbGUpOwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CgogICAgICAgICAgICBQYXRoIGNhbm9uRmlsZSA9IGZzSW5mby5nZXRDYW5vbmljYWxGaWxlKGZpbGUpOwogICAgICAgICAgICBpZiAoY2Fub25pY2FsVmFsdWVzLmNvbnRhaW5zKGNhbm9uRmlsZSkpIHsKICAgICAgICAgICAgICAgIC8qIERpc2NhcmQgZHVwbGljYXRlcyBhbmQgYXZvaWQgaW5maW5pdGUgcmVjdXJzaW9uICovCiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChmc0luZm8uaXNGaWxlKGZpbGUpKSB7CiAgICAgICAgICAgICAgICAvKiBGaWxlIGlzIGFuIG9yZGluYXJ5IGZpbGUuICovCiAgICAgICAgICAgICAgICBpZiAoICAgIWZpbGUuZ2V0RmlsZU5hbWUoKS50b1N0cmluZygpLmVuZHNXaXRoKCIuam1vZCIpCiAgICAgICAgICAgICAgICAgICAgJiYgIWZpbGUuZW5kc1dpdGgoIm1vZHVsZXMiKSkgewogICAgICAgICAgICAgICAgICAgIGlmICghaXNBcmNoaXZlKGZpbGUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIE5vdCBhIHJlY29nbml6ZWQgZXh0ZW5zaW9uOyBvcGVuIGl0IHRvIHNlZSBpZgogICAgICAgICAgICAgICAgICAgICAgICAgaXQgbG9va3MgbGlrZSBhIHZhbGlkIHppcCBmaWxlLiAqLwogICAgICAgICAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgRmlsZVN5c3RlbXMubmV3RmlsZVN5c3RlbShmaWxlLCBudWxsKS5jbG9zZSgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHdhcm4pIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2cud2FybmluZyhMaW50LkxpbnRDYXRlZ29yeS5QQVRILAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInVuZXhwZWN0ZWQuYXJjaGl2ZS5maWxlIiwgZmlsZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIHwgUHJvdmlkZXJOb3RGb3VuZEV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBGSVhNRTogaW5jbHVkZSBlLmdldExvY2FsaXplZE1lc3NhZ2UgaW4gd2FybmluZwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHdhcm4pIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2cud2FybmluZyhMaW50LkxpbnRDYXRlZ29yeS5QQVRILAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImludmFsaWQuYXJjaGl2ZS5maWxlIiwgZmlsZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoZnNJbmZvLmdldEphckZTUHJvdmlkZXIoKSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2cuZXJyb3IoRXJyb3JzLk5vWmlwZnNGb3JBcmNoaXZlKGZpbGUpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiA7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qIE5vdyB3aGF0IHdlIGhhdmUgbGVmdCBpcyBlaXRoZXIgYSBkaXJlY3Rvcnkgb3IgYSBmaWxlIG5hbWUKICAgICAgICAgICAgIGNvbmZvcm1pbmcgdG8gYXJjaGl2ZSBuYW1pbmcgY29udmVudGlvbiAqLwogICAgICAgICAgICBzdXBlci5hZGQoZmlsZSk7CiAgICAgICAgICAgIGNhbm9uaWNhbFZhbHVlcy5hZGQoY2Fub25GaWxlKTsKCiAgICAgICAgICAgIGlmIChleHBhbmRKYXJDbGFzc1BhdGhzICYmIGZzSW5mby5pc0ZpbGUoZmlsZSkgJiYgIWZpbGUuZW5kc1dpdGgoIm1vZHVsZXMiKSkgewogICAgICAgICAgICAgICAgYWRkSmFyQ2xhc3NQYXRoKGZpbGUsIHdhcm4pOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBBZGRzIHJlZmVyZW5jZWQgY2xhc3NwYXRoIGVsZW1lbnRzIGZyb20gYSBqYXIncyBDbGFzcy1QYXRoCiAgICAgICAgLy8gTWFuaWZlc3QgZW50cnkuICBJbiBzb21lIGZ1dHVyZSByZWxlYXNlLCB3ZSBtYXkgd2FudCB0bwogICAgICAgIC8vIHVwZGF0ZSB0aGlzIGNvZGUgdG8gcmVjb2duaXplIFVSTHMgcmF0aGVyIHRoYW4gc2ltcGxlCiAgICAgICAgLy8gZmlsZW5hbWVzLCBidXQgaWYgd2UgZG8sIHdlIHNob3VsZCByZWRvIGFsbCBwYXRoLXJlbGF0ZWQgY29kZS4KICAgICAgICBwcml2YXRlIHZvaWQgYWRkSmFyQ2xhc3NQYXRoKFBhdGggamFyRmlsZSwgYm9vbGVhbiB3YXJuKSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBmb3IgKFBhdGggZiA6IGZzSW5mby5nZXRKYXJDbGFzc1BhdGgoamFyRmlsZSkpIHsKICAgICAgICAgICAgICAgICAgICBhZGRGaWxlKGYsIHdhcm4pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgICBsb2cuZXJyb3IoImVycm9yLnJlYWRpbmcuZmlsZSIsIGphckZpbGUsIEphdmFjRmlsZU1hbmFnZXIuZ2V0TWVzc2FnZShlKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBCYXNlIGNsYXNzIGZvciBoYW5kbGluZyBzdXBwb3J0IGZvciB0aGUgcmVwcmVzZW50YXRpb24gb2YgTG9jYXRpb25zLgogICAgICoKICAgICAqIExvY2F0aW9ucyBhcmUgKGJ5IGRlc2lnbikgb3BhcXVlIGhhbmRsZXMgdGhhdCBjYW4gZWFzaWx5IGJlIGltcGxlbWVudGVkCiAgICAgKiBieSBlbnVtcyBsaWtlIFN0YW5kYXJkTG9jYXRpb24uIFdpdGhpbiBKYXZhY0ZpbGVNYW5hZ2VyLCBlYWNoIExvY2F0aW9uCiAgICAgKiBoYXMgYW4gYXNzb2NpYXRlZCBMb2NhdGlvbkhhbmRsZXIsIHdoaWNoIHByb3ZpZGVzIG11Y2ggb2YgdGhlIGFwcHJvcHJpYXRlCiAgICAgKiBmdW5jdGlvbmFsaXR5IGZvciB0aGUgY29ycmVzcG9uZGluZyBMb2NhdGlvbi4KICAgICAqCiAgICAgKiBAc2VlICNpbml0SGFuZGxlcnMKICAgICAqIEBzZWUgI2dldEhhbmRsZXIKICAgICAqLwogICAgcHJvdGVjdGVkIHN0YXRpYyBhYnN0cmFjdCBjbGFzcyBMb2NhdGlvbkhhbmRsZXIgewoKICAgICAgICAvKioKICAgICAgICAgKiBAc2VlIEphdmFGaWxlTWFuYWdlciNoYW5kbGVPcHRpb24KICAgICAgICAgKi8KICAgICAgICBhYnN0cmFjdCBib29sZWFuIGhhbmRsZU9wdGlvbihPcHRpb24gb3B0aW9uLCBTdHJpbmcgdmFsdWUpOwoKICAgICAgICAvKioKICAgICAgICAgKiBAc2VlIFN0YW5kYXJkSmF2YUZpbGVNYW5hZ2VyI2hhc0xvY2F0aW9uCiAgICAgICAgICovCiAgICAgICAgYm9vbGVhbiBpc1NldCgpIHsKICAgICAgICAgICAgcmV0dXJuIChnZXRQYXRocygpICE9IG51bGwpOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogQHNlZSBTdGFuZGFyZEphdmFGaWxlTWFuYWdlciNnZXRMb2NhdGlvbgogICAgICAgICAqLwogICAgICAgIGFic3RyYWN0IENvbGxlY3Rpb248UGF0aD4gZ2V0UGF0aHMoKTsKCiAgICAgICAgLyoqCiAgICAgICAgICogQHNlZSBTdGFuZGFyZEphdmFGaWxlTWFuYWdlciNzZXRMb2NhdGlvbgogICAgICAgICAqLwogICAgICAgIGFic3RyYWN0IHZvaWQgc2V0UGF0aHMoSXRlcmFibGU8PyBleHRlbmRzIFBhdGg+IHBhdGhzKSB0aHJvd3MgSU9FeGNlcHRpb247CgogICAgICAgIC8qKgogICAgICAgICAqIEBzZWUgU3RhbmRhcmRKYXZhRmlsZU1hbmFnZXIjc2V0TG9jYXRpb25Gb3JNb2R1bGUKICAgICAgICAgKi8KICAgICAgICBhYnN0cmFjdCB2b2lkIHNldFBhdGhzRm9yTW9kdWxlKFN0cmluZyBtb2R1bGVOYW1lLCBJdGVyYWJsZTw/IGV4dGVuZHMgUGF0aD4gcGF0aHMpCiAgICAgICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb247CgogICAgICAgIC8qKgogICAgICAgICAqIEBzZWUgSmF2YUZpbGVNYW5hZ2VyI2dldExvY2F0aW9uRm9yTW9kdWxlKExvY2F0aW9uLCBTdHJpbmcpCiAgICAgICAgICovCiAgICAgICAgTG9jYXRpb24gZ2V0TG9jYXRpb25Gb3JNb2R1bGUoU3RyaW5nIG1vZHVsZU5hbWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogQHNlZSBKYXZhRmlsZU1hbmFnZXIjZ2V0TG9jYXRpb25Gb3JNb2R1bGUoTG9jYXRpb24sIEphdmFGaWxlT2JqZWN0LCBTdHJpbmcpCiAgICAgICAgICovCiAgICAgICAgTG9jYXRpb24gZ2V0TG9jYXRpb25Gb3JNb2R1bGUoUGF0aCBmaWxlKSB0aHJvd3MgSU9FeGNlcHRpb24gIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBAc2VlIEphdmFGaWxlTWFuYWdlciNpbmZlck1vZHVsZU5hbWUKICAgICAgICAgKi8KICAgICAgICBTdHJpbmcgaW5mZXJNb2R1bGVOYW1lKCkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIEBzZWUgSmF2YUZpbGVNYW5hZ2VyI2xpc3RMb2NhdGlvbnNGb3JNb2R1bGVzCiAgICAgICAgICovCiAgICAgICAgSXRlcmFibGU8U2V0PExvY2F0aW9uPj4gbGlzdExvY2F0aW9uc0Zvck1vZHVsZXMoKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBBIExvY2F0aW9uSGFuZGxlciBmb3IgYSBnaXZlbiBMb2NhdGlvbiwgYW5kIGFzc29jaWF0ZWQgc2V0IG9mIG9wdGlvbnMuCiAgICAgKi8KICAgIHByaXZhdGUgc3RhdGljIGFic3RyYWN0IGNsYXNzIEJhc2ljTG9jYXRpb25IYW5kbGVyIGV4dGVuZHMgTG9jYXRpb25IYW5kbGVyIHsKCiAgICAgICAgZmluYWwgTG9jYXRpb24gbG9jYXRpb247CiAgICAgICAgZmluYWwgU2V0PE9wdGlvbj4gb3B0aW9uczsKCiAgICAgICAgLyoqCiAgICAgICAgICogQ3JlYXRlIGEgaGFuZGxlci4gVGhlIGxvY2F0aW9uIGFuZCBvcHRpb25zIHByb3ZpZGUgYSB3YXkgdG8gbWFwIGZyb20gYSBsb2NhdGlvbiBvciBhbgogICAgICAgICAqIG9wdGlvbiB0byB0aGUgY29ycmVzcG9uZGluZyBoYW5kbGVyLgogICAgICAgICAqCiAgICAgICAgICogQHBhcmFtIGxvY2F0aW9uIHRoZSBsb2NhdGlvbiBmb3Igd2hpY2ggdGhpcyBpcyB0aGUgaGFuZGxlcgogICAgICAgICAqIEBwYXJhbSBvcHRpb25zIHRoZSBvcHRpb25zIGFmZmVjdGluZyB0aGlzIGxvY2F0aW9uCiAgICAgICAgICogQHNlZSAjaW5pdEhhbmRsZXJzCiAgICAgICAgICovCiAgICAgICAgcHJvdGVjdGVkIEJhc2ljTG9jYXRpb25IYW5kbGVyKExvY2F0aW9uIGxvY2F0aW9uLCBPcHRpb24uLi4gb3B0aW9ucykgewogICAgICAgICAgICB0aGlzLmxvY2F0aW9uID0gbG9jYXRpb247CiAgICAgICAgICAgIHRoaXMub3B0aW9ucyA9IG9wdGlvbnMubGVuZ3RoID09IDAKICAgICAgICAgICAgICAgICAgICA/IEVudW1TZXQubm9uZU9mKE9wdGlvbi5jbGFzcykKICAgICAgICAgICAgICAgICAgICA6IEVudW1TZXQuY29weU9mKEFycmF5cy5hc0xpc3Qob3B0aW9ucykpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgdm9pZCBzZXRQYXRoc0Zvck1vZHVsZShTdHJpbmcgbW9kdWxlTmFtZSwgSXRlcmFibGU8PyBleHRlbmRzIFBhdGg+IGZpbGVzKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgICAgICAvLyBzaG91bGQgbm90IGhhcHBlbjogcHJvdGVjdGVkIGJ5IGNoZWNrIGluIEphdmFjRmlsZU1hbmFnZXIKICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJub3Qgc3VwcG9ydGVkIGZvciAiICsgbG9jYXRpb24pOwogICAgICAgIH0KCiAgICAgICAgcHJvdGVjdGVkIFBhdGggY2hlY2tTaW5nbGV0b25EaXJlY3RvcnkoSXRlcmFibGU8PyBleHRlbmRzIFBhdGg+IHBhdGhzKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgICAgICBJdGVyYXRvcjw/IGV4dGVuZHMgUGF0aD4gcGF0aEl0ZXIgPSBwYXRocy5pdGVyYXRvcigpOwogICAgICAgICAgICBpZiAoIXBhdGhJdGVyLmhhc05leHQoKSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiZW1wdHkgcGF0aCBmb3IgZGlyZWN0b3J5Iik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgUGF0aCBwYXRoID0gcGF0aEl0ZXIubmV4dCgpOwogICAgICAgICAgICBpZiAocGF0aEl0ZXIuaGFzTmV4dCgpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJwYXRoIHRvbyBsb25nIGZvciBkaXJlY3RvcnkiKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBjaGVja0RpcmVjdG9yeShwYXRoKTsKICAgICAgICAgICAgcmV0dXJuIHBhdGg7CiAgICAgICAgfQoKICAgICAgICBwcm90ZWN0ZWQgUGF0aCBjaGVja0RpcmVjdG9yeShQYXRoIHBhdGgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgICAgIE9iamVjdHMucmVxdWlyZU5vbk51bGwocGF0aCk7CiAgICAgICAgICAgIGlmICghRmlsZXMuZXhpc3RzKHBhdGgpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRmlsZU5vdEZvdW5kRXhjZXB0aW9uKHBhdGggKyAiOiBkb2VzIG5vdCBleGlzdCIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICghRmlsZXMuaXNEaXJlY3RvcnkocGF0aCkpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbihwYXRoICsgIjogbm90IGEgZGlyZWN0b3J5Iik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHBhdGg7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogR2VuZXJhbCBwdXJwb3NlIGltcGxlbWVudGF0aW9uIGZvciBvdXRwdXQgbG9jYXRpb25zLCBzdWNoIGFzIC1kL0NMQVNTX09VVFBVVCBhbmQKICAgICAqIC1zL1NPVVJDRV9PVVRQVVQuIEFsbCBvcHRpb25zIGFyZSB0cmVhdGVkIGFzIGVxdWl2YWxlbnQgKGkuZS4gYWxpYXNlcy4pCiAgICAgKiBUaGUgdmFsdWUgaXMgYSBzaW5nbGUgZmlsZSwgcG9zc2libHkgbnVsbC4KICAgICAqLwogICAgcHJpdmF0ZSBjbGFzcyBPdXRwdXRMb2NhdGlvbkhhbmRsZXIgZXh0ZW5kcyBCYXNpY0xvY2F0aW9uSGFuZGxlciB7CgogICAgICAgIHByaXZhdGUgUGF0aCBvdXRwdXREaXI7CiAgICAgICAgcHJpdmF0ZSBNb2R1bGVUYWJsZSBtb2R1bGVUYWJsZTsKCiAgICAgICAgT3V0cHV0TG9jYXRpb25IYW5kbGVyKExvY2F0aW9uIGxvY2F0aW9uLCBPcHRpb24uLi4gb3B0aW9ucykgewogICAgICAgICAgICBzdXBlcihsb2NhdGlvbiwgb3B0aW9ucyk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBib29sZWFuIGhhbmRsZU9wdGlvbihPcHRpb24gb3B0aW9uLCBTdHJpbmcgdmFsdWUpIHsKICAgICAgICAgICAgaWYgKCFvcHRpb25zLmNvbnRhaW5zKG9wdGlvbikpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gVE9ETzogY291bGQvc2hvdWxkIHZhbGlkYXRlIG91dHB1dERpciBleGlzdHMgYW5kIGlzIGEgZGlyZWN0b3J5CiAgICAgICAgICAgIC8vIG5lZWQgdG8gZGVjaWRlIGhvdyBiZXN0IHRvIHJlcG9ydCBpc3N1ZSBmb3IgYmVuZWZpdCBvZgogICAgICAgICAgICAvLyBkaXJlY3QgQVBJIGNhbGwgb24gSmF2YUZpbGVNYW5hZ2VyLmhhbmRsZU9wdGlvbihzcGVjaWZpZXMgSUFFKQogICAgICAgICAgICAvLyB2cy4gY29tbWFuZCBsaW5lIGRlY29kaW5nLgogICAgICAgICAgICBvdXRwdXREaXIgPSAodmFsdWUgPT0gbnVsbCkgPyBudWxsIDogZ2V0UGF0aCh2YWx1ZSk7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgQ29sbGVjdGlvbjxQYXRoPiBnZXRQYXRocygpIHsKICAgICAgICAgICAgcmV0dXJuIChvdXRwdXREaXIgPT0gbnVsbCkgPyBudWxsIDogQ29sbGVjdGlvbnMuc2luZ2xldG9uKG91dHB1dERpcik7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICB2b2lkIHNldFBhdGhzKEl0ZXJhYmxlPD8gZXh0ZW5kcyBQYXRoPiBwYXRocykgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICAgICAgaWYgKHBhdGhzID09IG51bGwpIHsKICAgICAgICAgICAgICAgIG91dHB1dERpciA9IG51bGw7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBvdXRwdXREaXIgPSBjaGVja1NpbmdsZXRvbkRpcmVjdG9yeShwYXRocyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgbW9kdWxlVGFibGUgPSBudWxsOwogICAgICAgICAgICBsaXN0ZWQgPSBmYWxzZTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIExvY2F0aW9uIGdldExvY2F0aW9uRm9yTW9kdWxlKFN0cmluZyBuYW1lKSB7CiAgICAgICAgICAgIGlmIChtb2R1bGVUYWJsZSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICBtb2R1bGVUYWJsZSA9IG5ldyBNb2R1bGVUYWJsZSgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIE1vZHVsZUxvY2F0aW9uSGFuZGxlciBsID0gbW9kdWxlVGFibGUuZ2V0KG5hbWUpOwogICAgICAgICAgICBpZiAobCA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICBQYXRoIG91dCA9IG91dHB1dERpci5yZXNvbHZlKG5hbWUpOwogICAgICAgICAgICAgICAgbCA9IG5ldyBNb2R1bGVMb2NhdGlvbkhhbmRsZXIodGhpcywgbG9jYXRpb24uZ2V0TmFtZSgpICsgIlsiICsgbmFtZSArICJdIiwKICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSwgQ29sbGVjdGlvbnMuc2luZ2xldG9uTGlzdChvdXQpLCB0cnVlKTsKICAgICAgICAgICAgICAgIG1vZHVsZVRhYmxlLmFkZChsKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gbDsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHZvaWQgc2V0UGF0aHNGb3JNb2R1bGUoU3RyaW5nIG5hbWUsIEl0ZXJhYmxlPD8gZXh0ZW5kcyBQYXRoPiBwYXRocykgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICAgICAgUGF0aCBvdXQgPSBjaGVja1NpbmdsZXRvbkRpcmVjdG9yeShwYXRocyk7CiAgICAgICAgICAgIGlmIChtb2R1bGVUYWJsZSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICBtb2R1bGVUYWJsZSA9IG5ldyBNb2R1bGVUYWJsZSgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIE1vZHVsZUxvY2F0aW9uSGFuZGxlciBsID0gbW9kdWxlVGFibGUuZ2V0KG5hbWUpOwogICAgICAgICAgICBpZiAobCA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICBsID0gbmV3IE1vZHVsZUxvY2F0aW9uSGFuZGxlcih0aGlzLCBsb2NhdGlvbi5nZXROYW1lKCkgKyAiWyIgKyBuYW1lICsgIl0iLAogICAgICAgICAgICAgICAgICAgICAgICBuYW1lLCBDb2xsZWN0aW9ucy5zaW5nbGV0b25MaXN0KG91dCksIHRydWUpOwogICAgICAgICAgICAgICAgbW9kdWxlVGFibGUuYWRkKGwpOwogICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBsLnNlYXJjaFBhdGggPSBDb2xsZWN0aW9ucy5zaW5nbGV0b25MaXN0KG91dCk7CiAgICAgICAgICAgICAgICBtb2R1bGVUYWJsZS51cGRhdGVQYXRocyhsKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgTG9jYXRpb24gZ2V0TG9jYXRpb25Gb3JNb2R1bGUoUGF0aCBmaWxlKSB7CiAgICAgICAgICAgIHJldHVybiAobW9kdWxlVGFibGUgPT0gbnVsbCkgPyBudWxsIDogbW9kdWxlVGFibGUuZ2V0KGZpbGUpOwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBib29sZWFuIGxpc3RlZDsKCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgSXRlcmFibGU8U2V0PExvY2F0aW9uPj4gbGlzdExvY2F0aW9uc0Zvck1vZHVsZXMoKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgICAgICBpZiAoIWxpc3RlZCAmJiBvdXRwdXREaXIgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgdHJ5IChEaXJlY3RvcnlTdHJlYW08UGF0aD4gc3RyZWFtID0gRmlsZXMubmV3RGlyZWN0b3J5U3RyZWFtKG91dHB1dERpcikpIHsKICAgICAgICAgICAgICAgICAgICBmb3IgKFBhdGggcCA6IHN0cmVhbSkgewogICAgICAgICAgICAgICAgICAgICAgICBnZXRMb2NhdGlvbkZvck1vZHVsZShwLmdldEZpbGVOYW1lKCkudG9TdHJpbmcoKSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgbGlzdGVkID0gdHJ1ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKG1vZHVsZVRhYmxlID09IG51bGwgfHwgbW9kdWxlVGFibGUuaXNFbXB0eSgpKQogICAgICAgICAgICAgICAgcmV0dXJuIENvbGxlY3Rpb25zLmVtcHR5U2V0KCk7CgogICAgICAgICAgICByZXR1cm4gQ29sbGVjdGlvbnMuc2luZ2xldG9uKG1vZHVsZVRhYmxlLmxvY2F0aW9ucygpKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBHZW5lcmFsIHB1cnBvc2UgaW1wbGVtZW50YXRpb24gZm9yIHNlYXJjaCBwYXRoIGxvY2F0aW9ucywKICAgICAqIHN1Y2ggYXMgLXNvdXJjZXBhdGgvU09VUkNFX1BBVEggYW5kIC1wcm9jZXNzb3JQYXRoL0FOTk9UQVRJT05fUFJPQ0VTU09SX1BBVEguCiAgICAgKiBBbGwgb3B0aW9ucyBhcmUgdHJlYXRlZCBhcyBlcXVpdmFsZW50IChpLmUuIGFsaWFzZXMuKQogICAgICogVGhlIHZhbHVlIGlzIGFuIG9yZGVyZWQgc2V0IG9mIGZpbGVzIGFuZC9vciBkaXJlY3Rvcmllcy4KICAgICAqLwogICAgcHJpdmF0ZSBjbGFzcyBTaW1wbGVMb2NhdGlvbkhhbmRsZXIgZXh0ZW5kcyBCYXNpY0xvY2F0aW9uSGFuZGxlciB7CgogICAgICAgIHByb3RlY3RlZCBDb2xsZWN0aW9uPFBhdGg+IHNlYXJjaFBhdGg7CgogICAgICAgIFNpbXBsZUxvY2F0aW9uSGFuZGxlcihMb2NhdGlvbiBsb2NhdGlvbiwgT3B0aW9uLi4uIG9wdGlvbnMpIHsKICAgICAgICAgICAgc3VwZXIobG9jYXRpb24sIG9wdGlvbnMpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgYm9vbGVhbiBoYW5kbGVPcHRpb24oT3B0aW9uIG9wdGlvbiwgU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgICAgIGlmICghb3B0aW9ucy5jb250YWlucyhvcHRpb24pKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc2VhcmNoUGF0aCA9IHZhbHVlID09IG51bGwgPyBudWxsCiAgICAgICAgICAgICAgICAgICAgOiBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVDb2xsZWN0aW9uKGNyZWF0ZVBhdGgoKS5hZGRGaWxlcyh2YWx1ZSkpOwogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIENvbGxlY3Rpb248UGF0aD4gZ2V0UGF0aHMoKSB7CiAgICAgICAgICAgIHJldHVybiBzZWFyY2hQYXRoOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgdm9pZCBzZXRQYXRocyhJdGVyYWJsZTw/IGV4dGVuZHMgUGF0aD4gZmlsZXMpIHsKICAgICAgICAgICAgU2VhcmNoUGF0aCBwOwogICAgICAgICAgICBpZiAoZmlsZXMgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgcCA9IGNvbXB1dGVQYXRoKG51bGwpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcCA9IGNyZWF0ZVBhdGgoKS5hZGRGaWxlcyhmaWxlcyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc2VhcmNoUGF0aCA9IENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUNvbGxlY3Rpb24ocCk7CiAgICAgICAgfQoKICAgICAgICBwcm90ZWN0ZWQgU2VhcmNoUGF0aCBjb21wdXRlUGF0aChTdHJpbmcgdmFsdWUpIHsKICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZVBhdGgoKS5hZGRGaWxlcyh2YWx1ZSk7CiAgICAgICAgfQoKICAgICAgICBwcm90ZWN0ZWQgU2VhcmNoUGF0aCBjcmVhdGVQYXRoKCkgewogICAgICAgICAgICByZXR1cm4gbmV3IFNlYXJjaFBhdGgoKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBTdWJ0eXBlIG9mIFNpbXBsZUxvY2F0aW9uSGFuZGxlciBmb3IgLWNsYXNzcGF0aC9DTEFTU19QQVRILgogICAgICogSWYgbm8gdmFsdWUgaXMgZ2l2ZW4sIGEgZGVmYXVsdCBpcyBwcm92aWRlZCwgYmFzZWQgb24gc3lzdGVtIHByb3BlcnRpZXMgYW5kIG90aGVyIHZhbHVlcy4KICAgICAqLwogICAgcHJpdmF0ZSBjbGFzcyBDbGFzc1BhdGhMb2NhdGlvbkhhbmRsZXIgZXh0ZW5kcyBTaW1wbGVMb2NhdGlvbkhhbmRsZXIgewoKICAgICAgICBDbGFzc1BhdGhMb2NhdGlvbkhhbmRsZXIoKSB7CiAgICAgICAgICAgIHN1cGVyKFN0YW5kYXJkTG9jYXRpb24uQ0xBU1NfUEFUSCwgT3B0aW9uLkNMQVNTX1BBVEgpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgQ29sbGVjdGlvbjxQYXRoPiBnZXRQYXRocygpIHsKICAgICAgICAgICAgbGF6eSgpOwogICAgICAgICAgICByZXR1cm4gc2VhcmNoUGF0aDsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHByb3RlY3RlZCBTZWFyY2hQYXRoIGNvbXB1dGVQYXRoKFN0cmluZyB2YWx1ZSkgewogICAgICAgICAgICBTdHJpbmcgY3AgPSB2YWx1ZTsKCiAgICAgICAgICAgIC8vIENMQVNTUEFUSCBlbnZpcm9ubWVudCB2YXJpYWJsZSB3aGVuIHJ1biBmcm9tIGBqYXZhYycuCiAgICAgICAgICAgIGlmIChjcCA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICBjcCA9IFN5c3RlbS5nZXRQcm9wZXJ0eSgiZW52LmNsYXNzLnBhdGgiKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gSWYgaW52b2tlZCB2aWEgYSBqYXZhIFZNIChub3QgdGhlIGphdmFjIGxhdW5jaGVyKSwgdXNlIHRoZQogICAgICAgICAgICAvLyBwbGF0Zm9ybSBjbGFzcyBwYXRoCiAgICAgICAgICAgIGlmIChjcCA9PSBudWxsICYmIFN5c3RlbS5nZXRQcm9wZXJ0eSgiYXBwbGljYXRpb24uaG9tZSIpID09IG51bGwpIHsKICAgICAgICAgICAgICAgIGNwID0gU3lzdGVtLmdldFByb3BlcnR5KCJqYXZhLmNsYXNzLnBhdGgiKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gRGVmYXVsdCB0byBjdXJyZW50IHdvcmtpbmcgZGlyZWN0b3J5LgogICAgICAgICAgICBpZiAoY3AgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgY3AgPSAiLiI7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBjcmVhdGVQYXRoKCkuYWRkRmlsZXMoY3ApOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHJvdGVjdGVkIFNlYXJjaFBhdGggY3JlYXRlUGF0aCgpIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyBTZWFyY2hQYXRoKCkKICAgICAgICAgICAgICAgICAgICAuZXhwYW5kSmFyQ2xhc3NQYXRocyh0cnVlKSAvLyBPbmx5IHNlYXJjaCB1c2VyIGphcnMgZm9yIENsYXNzLVBhdGhzCiAgICAgICAgICAgICAgICAgICAgLmVtcHR5UGF0aERlZmF1bHQoZ2V0UGF0aCgiLiIpKTsgIC8vIEVtcHR5IHBhdGggZWx0ID09PiBjdXJyZW50IGRpcmVjdG9yeQogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSB2b2lkIGxhenkoKSB7CiAgICAgICAgICAgIGlmIChzZWFyY2hQYXRoID09IG51bGwpIHsKICAgICAgICAgICAgICAgIHNldFBhdGhzKG51bGwpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQ3VzdG9tIHN1YnR5cGUgb2YgTG9jYXRpb25IYW5kbGVyIGZvciBQTEFURk9STV9DTEFTU19QQVRILgogICAgICogVmFyaW91cyBvcHRpb25zIGFyZSBzdXBwb3J0ZWQgZm9yIGRpZmZlcmVudCBjb21wb25lbnRzIG9mIHRoZQogICAgICogcGxhdGZvcm0gY2xhc3MgcGF0aC4KICAgICAqIFNldHRpbmcgYSB2YWx1ZSB3aXRoIHNldExvY2F0aW9uIG92ZXJyaWRlcyBhbGwgZXhpc3Rpbmcgb3B0aW9uIHZhbHVlcy4KICAgICAqIFNldHRpbmcgYW55IG9wdGlvbiBvdmVycmlkZXMgYW55IHZhbHVlIHNldCB3aXRoIHNldExvY2F0aW9uLCBhbmQKICAgICAqIHJldmVydHMgdG8gdXNpbmcgZGVmYXVsdCB2YWx1ZXMgZm9yIG9wdGlvbnMgdGhhdCBoYXZlIG5vdCBiZWVuIHNldC4KICAgICAqIFNldHRpbmcgLWJvb3RjbGFzc3BhdGggb3IgLVhib290Y2xhc3NwYXRoIG92ZXJyaWRlcyBhbnkgZXhpc3RpbmcKICAgICAqIHZhbHVlIGZvciAtWGJvb3RjbGFzc3BhdGgvcDogYW5kIC1YYm9vdGNsYXNzcGF0aC9hOi4KICAgICAqLwogICAgcHJpdmF0ZSBjbGFzcyBCb290Q2xhc3NQYXRoTG9jYXRpb25IYW5kbGVyIGV4dGVuZHMgQmFzaWNMb2NhdGlvbkhhbmRsZXIgewoKICAgICAgICBwcml2YXRlIENvbGxlY3Rpb248UGF0aD4gc2VhcmNoUGF0aDsKICAgICAgICBmaW5hbCBNYXA8T3B0aW9uLCBTdHJpbmc+IG9wdGlvblZhbHVlcyA9IG5ldyBFbnVtTWFwPD4oT3B0aW9uLmNsYXNzKTsKCiAgICAgICAgLyoqCiAgICAgICAgICogSXMgdGhlIGJvb3RjbGFzc3BhdGggdGhlIGRlZmF1bHQ/CiAgICAgICAgICovCiAgICAgICAgcHJpdmF0ZSBib29sZWFuIGlzRGVmYXVsdDsKCiAgICAgICAgQm9vdENsYXNzUGF0aExvY2F0aW9uSGFuZGxlcigpIHsKICAgICAgICAgICAgc3VwZXIoU3RhbmRhcmRMb2NhdGlvbi5QTEFURk9STV9DTEFTU19QQVRILAogICAgICAgICAgICAgICAgICAgIE9wdGlvbi5CT09UX0NMQVNTX1BBVEgsIE9wdGlvbi5YQk9PVENMQVNTUEFUSCwKICAgICAgICAgICAgICAgICAgICBPcHRpb24uWEJPT1RDTEFTU1BBVEhfUFJFUEVORCwKICAgICAgICAgICAgICAgICAgICBPcHRpb24uWEJPT1RDTEFTU1BBVEhfQVBQRU5ELAogICAgICAgICAgICAgICAgICAgIE9wdGlvbi5FTkRPUlNFRERJUlMsIE9wdGlvbi5ESkFWQV9FTkRPUlNFRF9ESVJTLAogICAgICAgICAgICAgICAgICAgIE9wdGlvbi5FWFRESVJTLCBPcHRpb24uREpBVkFfRVhUX0RJUlMpOwogICAgICAgIH0KCiAgICAgICAgYm9vbGVhbiBpc0RlZmF1bHQoKSB7CiAgICAgICAgICAgIGxhenkoKTsKICAgICAgICAgICAgcmV0dXJuIGlzRGVmYXVsdDsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIGJvb2xlYW4gaGFuZGxlT3B0aW9uKE9wdGlvbiBvcHRpb24sIFN0cmluZyB2YWx1ZSkgewogICAgICAgICAgICBpZiAoIW9wdGlvbnMuY29udGFpbnMob3B0aW9uKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBvcHRpb24gPSBjYW5vbmljYWxpemUob3B0aW9uKTsKICAgICAgICAgICAgb3B0aW9uVmFsdWVzLnB1dChvcHRpb24sIHZhbHVlKTsKICAgICAgICAgICAgaWYgKG9wdGlvbiA9PSBCT09UX0NMQVNTX1BBVEgpIHsKICAgICAgICAgICAgICAgIG9wdGlvblZhbHVlcy5yZW1vdmUoWEJPT1RDTEFTU1BBVEhfUFJFUEVORCk7CiAgICAgICAgICAgICAgICBvcHRpb25WYWx1ZXMucmVtb3ZlKFhCT09UQ0xBU1NQQVRIX0FQUEVORCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc2VhcmNoUGF0aCA9IG51bGw7ICAvLyByZXNldCB0byAidW5pbml0aWFsaXplZCIKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgICAgIC8vIHdoZXJlCiAgICAgICAgLy8gVE9ETzogd291bGQgYmUgYmV0dGVyIGlmIG9wdGlvbiBhbGlhc2luZyB3YXMgaGFuZGxlZCBhdCBhIGhpZ2hlcgogICAgICAgIC8vIGxldmVsCiAgICAgICAgcHJpdmF0ZSBPcHRpb24gY2Fub25pY2FsaXplKE9wdGlvbiBvcHRpb24pIHsKICAgICAgICAgICAgc3dpdGNoIChvcHRpb24pIHsKICAgICAgICAgICAgICAgIGNhc2UgWEJPT1RDTEFTU1BBVEg6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE9wdGlvbi5CT09UX0NMQVNTX1BBVEg7CiAgICAgICAgICAgICAgICBjYXNlIERKQVZBX0VORE9SU0VEX0RJUlM6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE9wdGlvbi5FTkRPUlNFRERJUlM7CiAgICAgICAgICAgICAgICBjYXNlIERKQVZBX0VYVF9ESVJTOgogICAgICAgICAgICAgICAgICAgIHJldHVybiBPcHRpb24uRVhURElSUzsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG9wdGlvbjsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgQ29sbGVjdGlvbjxQYXRoPiBnZXRQYXRocygpIHsKICAgICAgICAgICAgbGF6eSgpOwogICAgICAgICAgICByZXR1cm4gc2VhcmNoUGF0aDsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHZvaWQgc2V0UGF0aHMoSXRlcmFibGU8PyBleHRlbmRzIFBhdGg+IGZpbGVzKSB7CiAgICAgICAgICAgIGlmIChmaWxlcyA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICBzZWFyY2hQYXRoID0gbnVsbDsgIC8vIHJlc2V0IHRvICJ1bmluaXRpYWxpemVkIgogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgaXNEZWZhdWx0ID0gZmFsc2U7CiAgICAgICAgICAgICAgICBTZWFyY2hQYXRoIHAgPSBuZXcgU2VhcmNoUGF0aCgpLmFkZEZpbGVzKGZpbGVzLCBmYWxzZSk7CiAgICAgICAgICAgICAgICBzZWFyY2hQYXRoID0gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlQ29sbGVjdGlvbihwKTsKICAgICAgICAgICAgICAgIG9wdGlvblZhbHVlcy5jbGVhcigpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBTZWFyY2hQYXRoIGNvbXB1dGVQYXRoKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICAgICAgU2VhcmNoUGF0aCBwYXRoID0gbmV3IFNlYXJjaFBhdGgoKTsKCiAgICAgICAgICAgIFN0cmluZyBib290Y2xhc3NwYXRoT3B0ID0gb3B0aW9uVmFsdWVzLmdldChCT09UX0NMQVNTX1BBVEgpOwogICAgICAgICAgICBTdHJpbmcgZW5kb3JzZWRkaXJzT3B0ID0gb3B0aW9uVmFsdWVzLmdldChFTkRPUlNFRERJUlMpOwogICAgICAgICAgICBTdHJpbmcgZXh0ZGlyc09wdCA9IG9wdGlvblZhbHVlcy5nZXQoRVhURElSUyk7CiAgICAgICAgICAgIFN0cmluZyB4Ym9vdGNsYXNzcGF0aFByZXBlbmRPcHQgPSBvcHRpb25WYWx1ZXMuZ2V0KFhCT09UQ0xBU1NQQVRIX1BSRVBFTkQpOwogICAgICAgICAgICBTdHJpbmcgeGJvb3RjbGFzc3BhdGhBcHBlbmRPcHQgPSBvcHRpb25WYWx1ZXMuZ2V0KFhCT09UQ0xBU1NQQVRIX0FQUEVORCk7CiAgICAgICAgICAgIHBhdGguYWRkRmlsZXMoeGJvb3RjbGFzc3BhdGhQcmVwZW5kT3B0KTsKCiAgICAgICAgICAgIGlmIChlbmRvcnNlZGRpcnNPcHQgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgcGF0aC5hZGREaXJlY3RvcmllcyhlbmRvcnNlZGRpcnNPcHQpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcGF0aC5hZGREaXJlY3RvcmllcyhTeXN0ZW0uZ2V0UHJvcGVydHkoImphdmEuZW5kb3JzZWQuZGlycyIpLCBmYWxzZSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChib290Y2xhc3NwYXRoT3B0ICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIHBhdGguYWRkRmlsZXMoYm9vdGNsYXNzcGF0aE9wdCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvLyBTdGFuZGFyZCBzeXN0ZW0gY2xhc3NlcyBmb3IgdGhpcyBjb21waWxlcidzIHJlbGVhc2UuCiAgICAgICAgICAgICAgICBDb2xsZWN0aW9uPFBhdGg+IHN5c3RlbUNsYXNzZXMgPSBzeXN0ZW1DbGFzc2VzKCk7CiAgICAgICAgICAgICAgICBpZiAoc3lzdGVtQ2xhc3NlcyAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgcGF0aC5hZGRGaWxlcyhzeXN0ZW1DbGFzc2VzLCBmYWxzZSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIC8vIGZhbGxiYWNrIHRvIHRoZSB2YWx1ZSBvZiBzdW4uYm9vdC5jbGFzcy5wYXRoCiAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGZpbGVzID0gU3lzdGVtLmdldFByb3BlcnR5KCJzdW4uYm9vdC5jbGFzcy5wYXRoIik7CiAgICAgICAgICAgICAgICAgICAgcGF0aC5hZGRGaWxlcyhmaWxlcywgZmFsc2UpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBwYXRoLmFkZEZpbGVzKHhib290Y2xhc3NwYXRoQXBwZW5kT3B0KTsKCiAgICAgICAgICAgIC8vIFN0cmljdGx5IHNwZWFraW5nLCBzdGFuZGFyZCBleHRlbnNpb25zIGFyZSBub3QgYm9vdHN0cmFwCiAgICAgICAgICAgIC8vIGNsYXNzZXMsIGJ1dCB3ZSB0cmVhdCB0aGVtIGlkZW50aWNhbGx5LCBzbyB3ZSdsbCBwcmV0ZW5kCiAgICAgICAgICAgIC8vIHRoYXQgdGhleSBhcmUuCiAgICAgICAgICAgIGlmIChleHRkaXJzT3B0ICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIHBhdGguYWRkRGlyZWN0b3JpZXMoZXh0ZGlyc09wdCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvLyBBZGQgbGliL2pmeHJ0LmphciB0byB0aGUgc2VhcmNoIHBhdGgKICAgICAgICAgICAgICAgUGF0aCBqZnhydCA9IGphdmFIb21lLnJlc29sdmUoImxpYi9qZnhydC5qYXIiKTsKICAgICAgICAgICAgICAgIGlmIChGaWxlcy5leGlzdHMoamZ4cnQpKSB7CiAgICAgICAgICAgICAgICAgICAgcGF0aC5hZGRGaWxlKGpmeHJ0LCBmYWxzZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBwYXRoLmFkZERpcmVjdG9yaWVzKFN5c3RlbS5nZXRQcm9wZXJ0eSgiamF2YS5leHQuZGlycyIpLCBmYWxzZSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlzRGVmYXVsdCA9CiAgICAgICAgICAgICAgICAgICAgICAgKHhib290Y2xhc3NwYXRoUHJlcGVuZE9wdCA9PSBudWxsKQogICAgICAgICAgICAgICAgICAgICYmIChib290Y2xhc3NwYXRoT3B0ID09IG51bGwpCiAgICAgICAgICAgICAgICAgICAgJiYgKHhib290Y2xhc3NwYXRoQXBwZW5kT3B0ID09IG51bGwpOwoKICAgICAgICAgICAgcmV0dXJuIHBhdGg7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBSZXR1cm4gYSBjb2xsZWN0aW9uIG9mIGZpbGVzIGNvbnRhaW5pbmcgc3lzdGVtIGNsYXNzZXMuCiAgICAgICAgICogUmV0dXJucyB7QGNvZGUgbnVsbH0gaWYgbm90IHJ1bm5pbmcgb24gYSBtb2R1bGFyIGltYWdlLgogICAgICAgICAqCiAgICAgICAgICogQHRocm93cyBVbmNoZWNrZWRJT0V4Y2VwdGlvbiBpZiBhbiBJL08gZXJyb3JzIG9jY3VycwogICAgICAgICAqLwogICAgICAgIHByaXZhdGUgQ29sbGVjdGlvbjxQYXRoPiBzeXN0ZW1DbGFzc2VzKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICAgICAgLy8gUmV0dXJuICJtb2R1bGVzIiBqaW1hZ2UgZmlsZSBpZiBhdmFpbGFibGUKICAgICAgICAgICAgaWYgKEZpbGVzLmlzUmVndWxhckZpbGUodGhpc1N5c3RlbU1vZHVsZXMpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gQ29sbGVjdGlvbnMuc2luZ2xldG9uKHRoaXNTeXN0ZW1Nb2R1bGVzKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gRXhwbG9kZWQgbW9kdWxlIGltYWdlCiAgICAgICAgICAgIFBhdGggbW9kdWxlcyA9IGphdmFIb21lLnJlc29sdmUoIm1vZHVsZXMiKTsKICAgICAgICAgICAgaWYgKEZpbGVzLmlzRGlyZWN0b3J5KG1vZHVsZXMucmVzb2x2ZSgiamF2YS5iYXNlIikpKSB7CiAgICAgICAgICAgICAgICB0cnkgKFN0cmVhbTxQYXRoPiBsaXN0ZWRNb2R1bGVzID0gRmlsZXMubGlzdChtb2R1bGVzKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBsaXN0ZWRNb2R1bGVzLmNvbGxlY3QoQ29sbGVjdG9ycy50b0xpc3QoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIG5vdCBhIG1vZHVsYXIgaW1hZ2UgdGhhdCB3ZSBrbm93IGFib3V0CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSB2b2lkIGxhenkoKSB7CiAgICAgICAgICAgIGlmIChzZWFyY2hQYXRoID09IG51bGwpIHsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBzZWFyY2hQYXRoID0gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlQ29sbGVjdGlvbihjb21wdXRlUGF0aCgpKTsKICAgICAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgICAgICAgICAvLyBUT0RPOiBuZWVkIGJldHRlciBoYW5kbGluZyBoZXJlLCBlLmcuIGphdmFjIEFib3J0PwogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBVbmNoZWNrZWRJT0V4Y2VwdGlvbihlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEEgTG9jYXRpb25IYW5kZXIgdG8gcmVwcmVzZW50IG1vZHVsZXMgZm91bmQgZnJvbSBhIG1vZHVsZS1vcmllbnRlZAogICAgICogbG9jYXRpb24gc3VjaCBhcyBNT0RVTEVfU09VUkNFX1BBVEgsIFVQR1JBREVfTU9EVUxFX1BBVEgsCiAgICAgKiBTWVNURU1fTU9EVUxFUyBhbmQgTU9EVUxFX1BBVEguCiAgICAgKgogICAgICogVGhlIExvY2F0aW9uIGNhbiBiZSBzcGVjaWZpZWQgdG8gYWNjZXB0IG92ZXJyaWRpbmcgY2xhc3NlcyBmcm9tIHRoZQogICAgICoge0Bjb2RlIC0tcGF0Y2gtbW9kdWxlIDxtb2R1bGU+PTxwYXRoPiB9IHBhcmFtZXRlci4KICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgTW9kdWxlTG9jYXRpb25IYW5kbGVyIGV4dGVuZHMgTG9jYXRpb25IYW5kbGVyIGltcGxlbWVudHMgTG9jYXRpb24gewogICAgICAgIHByaXZhdGUgZmluYWwgTG9jYXRpb25IYW5kbGVyIHBhcmVudDsKICAgICAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBuYW1lOwogICAgICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIG1vZHVsZU5hbWU7CiAgICAgICAgcHJpdmF0ZSBmaW5hbCBib29sZWFuIG91dHB1dDsKICAgICAgICBDb2xsZWN0aW9uPFBhdGg+IHNlYXJjaFBhdGg7CgogICAgICAgIE1vZHVsZUxvY2F0aW9uSGFuZGxlcihMb2NhdGlvbkhhbmRsZXIgcGFyZW50LCBTdHJpbmcgbmFtZSwgU3RyaW5nIG1vZHVsZU5hbWUsCiAgICAgICAgICAgICAgICBDb2xsZWN0aW9uPFBhdGg+IHNlYXJjaFBhdGgsIGJvb2xlYW4gb3V0cHV0KSB7CiAgICAgICAgICAgIHRoaXMucGFyZW50ID0gcGFyZW50OwogICAgICAgICAgICB0aGlzLm5hbWUgPSBuYW1lOwogICAgICAgICAgICB0aGlzLm1vZHVsZU5hbWUgPSBtb2R1bGVOYW1lOwogICAgICAgICAgICB0aGlzLnNlYXJjaFBhdGggPSBzZWFyY2hQYXRoOwogICAgICAgICAgICB0aGlzLm91dHB1dCA9IG91dHB1dDsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgICAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWUoKSB7CiAgICAgICAgICAgIHJldHVybiBuYW1lOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSKQogICAgICAgIHB1YmxpYyBib29sZWFuIGlzT3V0cHV0TG9jYXRpb24oKSB7CiAgICAgICAgICAgIHJldHVybiBvdXRwdXQ7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgLy8gZGVmaW5lZCBieSBMb2NhdGlvbkhhbmRsZXIKICAgICAgICBib29sZWFuIGhhbmRsZU9wdGlvbihPcHRpb24gb3B0aW9uLCBTdHJpbmcgdmFsdWUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgLy8gZGVmaW5lZCBieSBMb2NhdGlvbkhhbmRsZXIKICAgICAgICBDb2xsZWN0aW9uPFBhdGg+IGdldFBhdGhzKCkgewogICAgICAgICAgICByZXR1cm4gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlQ29sbGVjdGlvbihzZWFyY2hQYXRoKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSAvLyBkZWZpbmVkIGJ5IExvY2F0aW9uSGFuZGxlcgogICAgICAgIHZvaWQgc2V0UGF0aHMoSXRlcmFibGU8PyBleHRlbmRzIFBhdGg+IHBhdGhzKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgICAgICAvLyBkZWZlciB0byB0aGUgcGFyZW50IHRvIGRldGVybWluZSBpZiB0aGlzIGlzIGFjY2VwdGFibGUKICAgICAgICAgICAgcGFyZW50LnNldFBhdGhzRm9yTW9kdWxlKG1vZHVsZU5hbWUsIHBhdGhzKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSAvLyBkZWZpbmVkIGJ5IExvY2F0aW9uSGFuZGxlcgogICAgICAgIHZvaWQgc2V0UGF0aHNGb3JNb2R1bGUoU3RyaW5nIG1vZHVsZU5hbWUsIEl0ZXJhYmxlPD8gZXh0ZW5kcyBQYXRoPiBwYXRocykgewogICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIm5vdCBzdXBwb3J0ZWQgZm9yICIgKyBuYW1lKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSAvLyBkZWZpbmVkIGJ5IExvY2F0aW9uSGFuZGxlcgogICAgICAgIFN0cmluZyBpbmZlck1vZHVsZU5hbWUoKSB7CiAgICAgICAgICAgIHJldHVybiBtb2R1bGVOYW1lOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKICAgICAgICAgICAgcmV0dXJuIG5hbWU7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQSB0YWJsZSBvZiBtb2R1bGUgbG9jYXRpb24gaGFuZGxlcnMsIGluZGV4ZWQgYnkgbmFtZSBhbmQgcGF0aC4KICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgTW9kdWxlVGFibGUgewogICAgICAgIHByaXZhdGUgZmluYWwgTWFwPFN0cmluZywgTW9kdWxlTG9jYXRpb25IYW5kbGVyPiBuYW1lTWFwID0gbmV3IExpbmtlZEhhc2hNYXA8PigpOwogICAgICAgIHByaXZhdGUgZmluYWwgTWFwPFBhdGgsIE1vZHVsZUxvY2F0aW9uSGFuZGxlcj4gcGF0aE1hcCA9IG5ldyBMaW5rZWRIYXNoTWFwPD4oKTsKCiAgICAgICAgdm9pZCBhZGQoTW9kdWxlTG9jYXRpb25IYW5kbGVyIGgpIHsKICAgICAgICAgICAgbmFtZU1hcC5wdXQoaC5tb2R1bGVOYW1lLCBoKTsKICAgICAgICAgICAgZm9yIChQYXRoIHAgOiBoLnNlYXJjaFBhdGgpIHsKICAgICAgICAgICAgICAgIHBhdGhNYXAucHV0KG5vcm1hbGl6ZShwKSwgaCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHZvaWQgdXBkYXRlUGF0aHMoTW9kdWxlTG9jYXRpb25IYW5kbGVyIGgpIHsKICAgICAgICAgICAgLy8gdXNlIGl0ZXJhdG9yLCB0byBiZSBhYmxlIHRvIHJlbW92ZSBvbGQgZW50cmllcwogICAgICAgICAgICBmb3IgKEl0ZXJhdG9yPE1hcC5FbnRyeTxQYXRoLCBNb2R1bGVMb2NhdGlvbkhhbmRsZXI+PiBpdGVyID0gcGF0aE1hcC5lbnRyeVNldCgpLml0ZXJhdG9yKCk7CiAgICAgICAgICAgICAgICAgICAgaXRlci5oYXNOZXh0KCk7ICkgewogICAgICAgICAgICAgICAgTWFwLkVudHJ5PFBhdGgsIE1vZHVsZUxvY2F0aW9uSGFuZGxlcj4gZSA9IGl0ZXIubmV4dCgpOwogICAgICAgICAgICAgICAgaWYgKGUuZ2V0VmFsdWUoKSA9PSBoKSB7CiAgICAgICAgICAgICAgICAgICAgaXRlci5yZW1vdmUoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBmb3IgKFBhdGggcCA6IGguc2VhcmNoUGF0aCkgewogICAgICAgICAgICAgICAgcGF0aE1hcC5wdXQobm9ybWFsaXplKHApLCBoKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgTW9kdWxlTG9jYXRpb25IYW5kbGVyIGdldChTdHJpbmcgbmFtZSkgewogICAgICAgICAgICByZXR1cm4gbmFtZU1hcC5nZXQobmFtZSk7CiAgICAgICAgfQoKICAgICAgICBNb2R1bGVMb2NhdGlvbkhhbmRsZXIgZ2V0KFBhdGggcGF0aCkgewogICAgICAgICAgICB3aGlsZSAocGF0aCAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICBNb2R1bGVMb2NhdGlvbkhhbmRsZXIgbCA9IHBhdGhNYXAuZ2V0KHBhdGgpOwoKICAgICAgICAgICAgICAgIGlmIChsICE9IG51bGwpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGw7CgogICAgICAgICAgICAgICAgcGF0aCA9IHBhdGguZ2V0UGFyZW50KCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgdm9pZCBjbGVhcigpIHsKICAgICAgICAgICAgbmFtZU1hcC5jbGVhcigpOwogICAgICAgICAgICBwYXRoTWFwLmNsZWFyKCk7CiAgICAgICAgfQoKICAgICAgICBib29sZWFuIGlzRW1wdHkoKSB7CiAgICAgICAgICAgIHJldHVybiBuYW1lTWFwLmlzRW1wdHkoKTsKICAgICAgICB9CgogICAgICAgIFNldDxMb2NhdGlvbj4gbG9jYXRpb25zKCkgewogICAgICAgICAgICByZXR1cm4gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlU2V0KG5hbWVNYXAudmFsdWVzKCkuc3RyZWFtKCkuY29sbGVjdChDb2xsZWN0b3JzLnRvU2V0KCkpKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBBIExvY2F0aW9uSGFuZGxlciBmb3Igc2ltcGxlIG1vZHVsZS1vcmllbnRlZCBzZWFyY2ggcGF0aHMsCiAgICAgKiBsaWtlIFVQR1JBREVfTU9EVUxFX1BBVEggYW5kIE1PRFVMRV9QQVRILgogICAgICovCiAgICBwcml2YXRlIGNsYXNzIE1vZHVsZVBhdGhMb2NhdGlvbkhhbmRsZXIgZXh0ZW5kcyBTaW1wbGVMb2NhdGlvbkhhbmRsZXIgewogICAgICAgIHByaXZhdGUgTW9kdWxlVGFibGUgbW9kdWxlVGFibGU7CgogICAgICAgIE1vZHVsZVBhdGhMb2NhdGlvbkhhbmRsZXIoTG9jYXRpb24gbG9jYXRpb24sIE9wdGlvbi4uLiBvcHRpb25zKSB7CiAgICAgICAgICAgIHN1cGVyKGxvY2F0aW9uLCBvcHRpb25zKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBib29sZWFuIGhhbmRsZU9wdGlvbihPcHRpb24gb3B0aW9uLCBTdHJpbmcgdmFsdWUpIHsKICAgICAgICAgICAgaWYgKCFvcHRpb25zLmNvbnRhaW5zKG9wdGlvbikpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBzZXRQYXRocyh2YWx1ZSA9PSBudWxsID8gbnVsbCA6IGdldFBhdGhFbnRyaWVzKHZhbHVlKSk7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIExvY2F0aW9uIGdldExvY2F0aW9uRm9yTW9kdWxlKFN0cmluZyBtb2R1bGVOYW1lKSB7CiAgICAgICAgICAgIGluaXRNb2R1bGVMb2NhdGlvbnMoKTsKICAgICAgICAgICAgcmV0dXJuIG1vZHVsZVRhYmxlLmdldChtb2R1bGVOYW1lKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIEl0ZXJhYmxlPFNldDxMb2NhdGlvbj4+IGxpc3RMb2NhdGlvbnNGb3JNb2R1bGVzKCkgewogICAgICAgICAgICBpZiAoc2VhcmNoUGF0aCA9PSBudWxsKQogICAgICAgICAgICAgICAgcmV0dXJuIENvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwoKICAgICAgICAgICAgcmV0dXJuIE1vZHVsZVBhdGhJdGVyYXRvcjo6bmV3OwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgdm9pZCBzZXRQYXRocyhJdGVyYWJsZTw/IGV4dGVuZHMgUGF0aD4gcGF0aHMpIHsKICAgICAgICAgICAgaWYgKHBhdGhzICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIGZvciAoUGF0aCBwOiBwYXRocykgewogICAgICAgICAgICAgICAgICAgIGNoZWNrVmFsaWRNb2R1bGVQYXRoRW50cnkocCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc3VwZXIuc2V0UGF0aHMocGF0aHMpOwogICAgICAgICAgICBtb2R1bGVUYWJsZSA9IG51bGw7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICB2b2lkIHNldFBhdGhzRm9yTW9kdWxlKFN0cmluZyBuYW1lLCBJdGVyYWJsZTw/IGV4dGVuZHMgUGF0aD4gcGF0aHMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgICAgIExpc3Q8UGF0aD4gY2hlY2tlZFBhdGhzID0gY2hlY2tQYXRocyhwYXRocyk7CiAgICAgICAgICAgIC8vIGhvdyBmYXIgc2hvdWxkIHdlIGdvIHRvIHZhbGlkYXRlIHRoZSBwYXRocyBwcm92aWRlIGEgbW9kdWxlPwogICAgICAgICAgICAvLyBlLmcuIGNvbnRhaW4gbW9kdWxlLWluZm8gd2l0aCB0aGUgY29ycmVjdCBuYW1lPwogICAgICAgICAgICBpbml0TW9kdWxlTG9jYXRpb25zKCk7CiAgICAgICAgICAgIE1vZHVsZUxvY2F0aW9uSGFuZGxlciBsID0gbW9kdWxlVGFibGUuZ2V0KG5hbWUpOwogICAgICAgICAgICBpZiAobCA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICBsID0gbmV3IE1vZHVsZUxvY2F0aW9uSGFuZGxlcih0aGlzLCBsb2NhdGlvbi5nZXROYW1lKCkgKyAiWyIgKyBuYW1lICsgIl0iLAogICAgICAgICAgICAgICAgICAgICAgICBuYW1lLCBjaGVja2VkUGF0aHMsIHRydWUpOwogICAgICAgICAgICAgICAgbW9kdWxlVGFibGUuYWRkKGwpOwogICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBsLnNlYXJjaFBhdGggPSBjaGVja2VkUGF0aHM7CiAgICAgICAgICAgICAgICBtb2R1bGVUYWJsZS51cGRhdGVQYXRocyhsKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBMaXN0PFBhdGg+IGNoZWNrUGF0aHMoSXRlcmFibGU8PyBleHRlbmRzIFBhdGg+IHBhdGhzKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgICAgICBPYmplY3RzLnJlcXVpcmVOb25OdWxsKHBhdGhzKTsKICAgICAgICAgICAgTGlzdDxQYXRoPiB2YWxpZFBhdGhzID0gbmV3IEFycmF5TGlzdDw+KCk7CiAgICAgICAgICAgIGZvciAoUGF0aCBwIDogcGF0aHMpIHsKICAgICAgICAgICAgICAgIHZhbGlkUGF0aHMuYWRkKGNoZWNrRGlyZWN0b3J5KHApKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gdmFsaWRQYXRoczsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgdm9pZCBpbml0TW9kdWxlTG9jYXRpb25zKCkgewogICAgICAgICAgICBpZiAobW9kdWxlVGFibGUgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CgogICAgICAgICAgICBtb2R1bGVUYWJsZSA9IG5ldyBNb2R1bGVUYWJsZSgpOwoKICAgICAgICAgICAgZm9yIChTZXQ8TG9jYXRpb24+IHNldCA6IGxpc3RMb2NhdGlvbnNGb3JNb2R1bGVzKCkpIHsKICAgICAgICAgICAgICAgIGZvciAoTG9jYXRpb24gbG9jbiA6IHNldCkgewogICAgICAgICAgICAgICAgICAgIGlmIChsb2NuIGluc3RhbmNlb2YgTW9kdWxlTG9jYXRpb25IYW5kbGVyKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIE1vZHVsZUxvY2F0aW9uSGFuZGxlciBsID0gKE1vZHVsZUxvY2F0aW9uSGFuZGxlcikgbG9jbjsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFtb2R1bGVUYWJsZS5uYW1lTWFwLmNvbnRhaW5zS2V5KGwubW9kdWxlTmFtZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vZHVsZVRhYmxlLmFkZChsKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSB2b2lkIGNoZWNrVmFsaWRNb2R1bGVQYXRoRW50cnkoUGF0aCBwKSB7CiAgICAgICAgICAgIGlmICghRmlsZXMuZXhpc3RzKHApKSB7CiAgICAgICAgICAgICAgICAvLyB3YXJuaW5nIG1heSBiZSBnZW5lcmF0ZWQgbGF0ZXIKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKEZpbGVzLmlzRGlyZWN0b3J5KHApKSB7CiAgICAgICAgICAgICAgICAvLyBlaXRoZXIgYW4gZXhwbG9kZWQgbW9kdWxlIG9yIGEgZGlyZWN0b3J5IG9mIG1vZHVsZXMKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgU3RyaW5nIG5hbWUgPSBwLmdldEZpbGVOYW1lKCkudG9TdHJpbmcoKTsKICAgICAgICAgICAgaW50IGxhc3REb3QgPSBuYW1lLmxhc3RJbmRleE9mKCIuIik7CiAgICAgICAgICAgIGlmIChsYXN0RG90ID4gMCkgewogICAgICAgICAgICAgICAgc3dpdGNoIChuYW1lLnN1YnN0cmluZyhsYXN0RG90KSkgewogICAgICAgICAgICAgICAgICAgIGNhc2UgIi5qYXIiOgogICAgICAgICAgICAgICAgICAgIGNhc2UgIi5qbW9kIjoKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24ocC50b1N0cmluZygpKTsKICAgICAgICB9CgogICAgICAgIGNsYXNzIE1vZHVsZVBhdGhJdGVyYXRvciBpbXBsZW1lbnRzIEl0ZXJhdG9yPFNldDxMb2NhdGlvbj4+IHsKICAgICAgICAgICAgSXRlcmF0b3I8UGF0aD4gcGF0aEl0ZXIgPSBzZWFyY2hQYXRoLml0ZXJhdG9yKCk7CiAgICAgICAgICAgIGludCBwYXRoSW5kZXggPSAwOwogICAgICAgICAgICBTZXQ8TG9jYXRpb24+IG5leHQgPSBudWxsOwoKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHB1YmxpYyBib29sZWFuIGhhc05leHQoKSB7CiAgICAgICAgICAgICAgICBpZiAobmV4dCAhPSBudWxsKQogICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwoKICAgICAgICAgICAgICAgIHdoaWxlIChuZXh0ID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICBpZiAocGF0aEl0ZXIuaGFzTmV4dCgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIFBhdGggcGF0aCA9IHBhdGhJdGVyLm5leHQoKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKEZpbGVzLmlzRGlyZWN0b3J5KHBhdGgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXh0ID0gc2NhbkRpcmVjdG9yeShwYXRoKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5leHQgPSBzY2FuRmlsZShwYXRoKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBwYXRoSW5kZXgrKzsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgU2V0PExvY2F0aW9uPiBuZXh0KCkgewogICAgICAgICAgICAgICAgaGFzTmV4dCgpOwogICAgICAgICAgICAgICAgaWYgKG5leHQgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIFNldDxMb2NhdGlvbj4gcmVzdWx0ID0gbmV4dDsKICAgICAgICAgICAgICAgICAgICBuZXh0ID0gbnVsbDsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaEVsZW1lbnRFeGNlcHRpb24oKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHJpdmF0ZSBTZXQ8TG9jYXRpb24+IHNjYW5EaXJlY3RvcnkoUGF0aCBwYXRoKSB7CiAgICAgICAgICAgICAgICBTZXQ8UGF0aD4gcGF0aHMgPSBuZXcgTGlua2VkSGFzaFNldDw+KCk7CiAgICAgICAgICAgICAgICBQYXRoIG1vZHVsZUluZm9DbGFzcyA9IG51bGw7CiAgICAgICAgICAgICAgICB0cnkgKERpcmVjdG9yeVN0cmVhbTxQYXRoPiBzdHJlYW0gPSBGaWxlcy5uZXdEaXJlY3RvcnlTdHJlYW0ocGF0aCkpIHsKICAgICAgICAgICAgICAgICAgICBmb3IgKFBhdGggZW50cnk6IHN0cmVhbSkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoZW50cnkuZW5kc1dpdGgoIm1vZHVsZS1pbmZvLmNsYXNzIikpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vZHVsZUluZm9DbGFzcyA9IGVudHJ5OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7ICAvLyBubyBuZWVkIHRvIGNvbnRpbnVlIHNjYW5uaW5nCiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgcGF0aHMuYWRkKGVudHJ5KTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGNhdGNoIChEaXJlY3RvcnlJdGVyYXRvckV4Y2VwdGlvbiB8IElPRXhjZXB0aW9uIGlnbm9yZSkgewogICAgICAgICAgICAgICAgICAgIGxvZy5lcnJvcihFcnJvcnMuTG9jbkNhbnRSZWFkRGlyZWN0b3J5KHBhdGgpKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gQ29sbGVjdGlvbnMuZW1wdHlTZXQoKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAobW9kdWxlSW5mb0NsYXNzICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAvLyBJdCdzIGFuIGV4cGxvZGVkIG1vZHVsZSBkaXJlY3RseSBvbiB0aGUgbW9kdWxlIHBhdGguCiAgICAgICAgICAgICAgICAgICAgLy8gV2UgY2FuJ3QgaW5mZXIgbW9kdWxlIG5hbWUgZnJvbSB0aGUgZGlyZWN0b3J5IG5hbWUsIHNvIGhhdmUgdG8KICAgICAgICAgICAgICAgICAgICAvLyByZWFkIG1vZHVsZS1pbmZvLmNsYXNzLgogICAgICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBtb2R1bGVOYW1lID0gcmVhZE1vZHVsZU5hbWUobW9kdWxlSW5mb0NsYXNzKTsKICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG5hbWUgPSBsb2NhdGlvbi5nZXROYW1lKCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICJbIiArIHBhdGhJbmRleCArICI6IiArIG1vZHVsZU5hbWUgKyAiXSI7CiAgICAgICAgICAgICAgICAgICAgICAgIE1vZHVsZUxvY2F0aW9uSGFuZGxlciBsID0gbmV3IE1vZHVsZUxvY2F0aW9uSGFuZGxlcigKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNb2R1bGVQYXRoTG9jYXRpb25IYW5kbGVyLnRoaXMsIG5hbWUsIG1vZHVsZU5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29sbGVjdGlvbnMuc2luZ2xldG9uTGlzdChwYXRoKSwgZmFsc2UpOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gQ29sbGVjdGlvbnMuc2luZ2xldG9uKGwpOwogICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKE1vZHVsZU5hbWVSZWFkZXIuQmFkQ2xhc3NGaWxlIGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgbG9nLmVycm9yKEVycm9ycy5Mb2NuQmFkTW9kdWxlSW5mbyhwYXRoKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBDb2xsZWN0aW9ucy5lbXB0eVNldCgpOwogICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgbG9nLmVycm9yKEVycm9ycy5Mb2NuQ2FudFJlYWRGaWxlKHBhdGgpKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIENvbGxlY3Rpb25zLmVtcHR5U2V0KCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIEEgZGlyZWN0b3J5IG9mIG1vZHVsZXMKICAgICAgICAgICAgICAgIFNldDxMb2NhdGlvbj4gcmVzdWx0ID0gbmV3IExpbmtlZEhhc2hTZXQ8PigpOwogICAgICAgICAgICAgICAgaW50IGluZGV4ID0gMDsKICAgICAgICAgICAgICAgIGZvciAoUGF0aCBlbnRyeSA6IHBhdGhzKSB7CiAgICAgICAgICAgICAgICAgICAgUGFpcjxTdHJpbmcsUGF0aD4gbW9kdWxlID0gaW5mZXJNb2R1bGVOYW1lKGVudHJ5KTsKICAgICAgICAgICAgICAgICAgICBpZiAobW9kdWxlID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gZGlhZ25vc3RpYyByZXBvcnRlZCBpZiBuZWNlc3Nhcnk7IHNraXAgdG8gbmV4dAogICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG1vZHVsZU5hbWUgPSBtb2R1bGUuZnN0OwogICAgICAgICAgICAgICAgICAgIFBhdGggbW9kdWxlUGF0aCA9IG1vZHVsZS5zbmQ7CiAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG5hbWUgPSBsb2NhdGlvbi5nZXROYW1lKCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIlsiICsgcGF0aEluZGV4ICsgIi4iICsgKGluZGV4KyspICsgIjoiICsgbW9kdWxlTmFtZSArICJdIjsKICAgICAgICAgICAgICAgICAgICBNb2R1bGVMb2NhdGlvbkhhbmRsZXIgbCA9IG5ldyBNb2R1bGVMb2NhdGlvbkhhbmRsZXIoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBNb2R1bGVQYXRoTG9jYXRpb25IYW5kbGVyLnRoaXMsIG5hbWUsIG1vZHVsZU5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb2xsZWN0aW9ucy5zaW5nbGV0b25MaXN0KG1vZHVsZVBhdGgpLCBmYWxzZSk7CiAgICAgICAgICAgICAgICAgICAgcmVzdWx0LmFkZChsKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHByaXZhdGUgU2V0PExvY2F0aW9uPiBzY2FuRmlsZShQYXRoIHBhdGgpIHsKICAgICAgICAgICAgICAgIFBhaXI8U3RyaW5nLFBhdGg+IG1vZHVsZSA9IGluZmVyTW9kdWxlTmFtZShwYXRoKTsKICAgICAgICAgICAgICAgIGlmIChtb2R1bGUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIC8vIGRpYWdub3N0aWMgcmVwb3J0ZWQgaWYgbmVjZXNzYXJ5CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIENvbGxlY3Rpb25zLmVtcHR5U2V0KCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBTdHJpbmcgbW9kdWxlTmFtZSA9IG1vZHVsZS5mc3Q7CiAgICAgICAgICAgICAgICBQYXRoIG1vZHVsZVBhdGggPSBtb2R1bGUuc25kOwogICAgICAgICAgICAgICAgU3RyaW5nIG5hbWUgPSBsb2NhdGlvbi5nZXROYW1lKCkKICAgICAgICAgICAgICAgICAgICAgICAgKyAiWyIgKyBwYXRoSW5kZXggKyAiOiIgKyBtb2R1bGVOYW1lICsgIl0iOwogICAgICAgICAgICAgICAgTW9kdWxlTG9jYXRpb25IYW5kbGVyIGwgPSBuZXcgTW9kdWxlTG9jYXRpb25IYW5kbGVyKAogICAgICAgICAgICAgICAgICAgICAgICBNb2R1bGVQYXRoTG9jYXRpb25IYW5kbGVyLnRoaXMsIG5hbWUsIG1vZHVsZU5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgIENvbGxlY3Rpb25zLnNpbmdsZXRvbkxpc3QobW9kdWxlUGF0aCksIGZhbHNlKTsKICAgICAgICAgICAgICAgIHJldHVybiBDb2xsZWN0aW9ucy5zaW5nbGV0b24obCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHByaXZhdGUgUGFpcjxTdHJpbmcsUGF0aD4gaW5mZXJNb2R1bGVOYW1lKFBhdGggcCkgewogICAgICAgICAgICAgICAgaWYgKEZpbGVzLmlzRGlyZWN0b3J5KHApKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKEZpbGVzLmV4aXN0cyhwLnJlc29sdmUoIm1vZHVsZS1pbmZvLmNsYXNzIikpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBuYW1lID0gcC5nZXRGaWxlTmFtZSgpLnRvU3RyaW5nKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChTb3VyY2VWZXJzaW9uLmlzTmFtZShuYW1lKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgUGFpcjw+KG5hbWUsIHApOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAocC5nZXRGaWxlTmFtZSgpLnRvU3RyaW5nKCkuZW5kc1dpdGgoIi5qYXIiKSAmJiBmc0luZm8uZXhpc3RzKHApKSB7CiAgICAgICAgICAgICAgICAgICAgRmlsZVN5c3RlbVByb3ZpZGVyIGphckZTUHJvdmlkZXIgPSBmc0luZm8uZ2V0SmFyRlNQcm92aWRlcigpOwogICAgICAgICAgICAgICAgICAgIGlmIChqYXJGU1Byb3ZpZGVyID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgbG9nLmVycm9yKEVycm9ycy5Ob1ppcGZzRm9yQXJjaGl2ZShwKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB0cnkgKEZpbGVTeXN0ZW0gZnMgPSBqYXJGU1Byb3ZpZGVyLm5ld0ZpbGVTeXN0ZW0ocCwgZnNFbnYpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIFBhdGggbW9kdWxlSW5mb0NsYXNzID0gZnMuZ2V0UGF0aCgibW9kdWxlLWluZm8uY2xhc3MiKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKEZpbGVzLmV4aXN0cyhtb2R1bGVJbmZvQ2xhc3MpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbW9kdWxlTmFtZSA9IHJlYWRNb2R1bGVOYW1lKG1vZHVsZUluZm9DbGFzcyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFBhaXI8Pihtb2R1bGVOYW1lLCBwKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKE1vZHVsZU5hbWVSZWFkZXIuQmFkQ2xhc3NGaWxlIGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgbG9nLmVycm9yKEVycm9ycy5Mb2NuQmFkTW9kdWxlSW5mbyhwKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgbG9nLmVycm9yKEVycm9ycy5Mb2NuQ2FudFJlYWRGaWxlKHApKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAvL2F1dG9tYXRpYyBtb2R1bGU6CiAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGZuID0gcC5nZXRGaWxlTmFtZSgpLnRvU3RyaW5nKCk7CiAgICAgICAgICAgICAgICAgICAgLy9mcm9tIE1vZHVsZVBhdGguZGVyaXZlTW9kdWxlRGVzY3JpcHRvcjoKCiAgICAgICAgICAgICAgICAgICAgLy8gZHJvcCAuamFyCiAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG1uID0gZm4uc3Vic3RyaW5nKDAsIGZuLmxlbmd0aCgpLTQpOwoKICAgICAgICAgICAgICAgICAgICAvLyBmaW5kIGZpcnN0IG9jY3VycmVuY2Ugb2YgLSR7TlVNQkVSfS4gb3IgLSR7TlVNQkVSfSQKICAgICAgICAgICAgICAgICAgICBNYXRjaGVyIG1hdGNoZXIgPSBQYXR0ZXJuLmNvbXBpbGUoIi0oXFxkKyhcXC58JCkpIikubWF0Y2hlcihtbik7CiAgICAgICAgICAgICAgICAgICAgaWYgKG1hdGNoZXIuZmluZCgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGludCBzdGFydCA9IG1hdGNoZXIuc3RhcnQoKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIG1uID0gbW4uc3Vic3RyaW5nKDAsIHN0YXJ0KTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vIGZpbmFsbHkgY2xlYW4gdXAgdGhlIG1vZHVsZSBuYW1lCiAgICAgICAgICAgICAgICAgICAgbW4gPSAgbW4ucmVwbGFjZUFsbCgiKFxcLnxcXGQpKiQiLCAiIikgICAgLy8gcmVtb3ZlIHRyYWlsaW5nIHZlcnNpb24KICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5yZXBsYWNlQWxsKCJbXkEtWmEtejAtOV0iLCAiLiIpICAvLyByZXBsYWNlIG5vbi1hbHBoYW51bWVyaWMKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5yZXBsYWNlQWxsKCIoXFwuKShcXDEpKyIsICIuIikgICAvLyBjb2xsYXBzZSByZXBlYXRpbmcgZG90cwogICAgICAgICAgICAgICAgICAgICAgICAgICAgLnJlcGxhY2VBbGwoIl5cXC4iLCAiIikgICAgICAgICAgIC8vIGRyb3AgbGVhZGluZyBkb3RzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAucmVwbGFjZUFsbCgiXFwuJCIsICIiKTsgICAgICAgICAgLy8gZHJvcCB0cmFpbGluZyBkb3RzCgoKICAgICAgICAgICAgICAgICAgICBpZiAoIW1uLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFBhaXI8PihtbiwgcCk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBsb2cuZXJyb3IoRXJyb3JzLkxvY25DYW50R2V0TW9kdWxlTmFtZUZvckphcihwKSk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKHAuZ2V0RmlsZU5hbWUoKS50b1N0cmluZygpLmVuZHNXaXRoKCIuam1vZCIpKSB7CiAgICAgICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gY2hlY2sgaWYgdGhlIEpNT0QgZmlsZSBpcyB2YWxpZAogICAgICAgICAgICAgICAgICAgICAgICBKREs5V3JhcHBlcnMuSm1vZEZpbGUuY2hlY2tNYWdpYyhwKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIE5vIEpNT0QgZmlsZSBzeXN0ZW0uICBVc2UgSmFyRmlsZVN5c3RlbSB0bwogICAgICAgICAgICAgICAgICAgICAgICAvLyB3b3JrYXJvdW5kIGZvciBub3cKICAgICAgICAgICAgICAgICAgICAgICAgRmlsZVN5c3RlbSBmcyA9IGZpbGVTeXN0ZW1zLmdldChwKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZzID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZpbGVTeXN0ZW1Qcm92aWRlciBqYXJGU1Byb3ZpZGVyID0gZnNJbmZvLmdldEphckZTUHJvdmlkZXIoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChqYXJGU1Byb3ZpZGVyID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2cuZXJyb3IoRXJyb3JzLkxvY25DYW50UmVhZEZpbGUocCkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZnMgPSBqYXJGU1Byb3ZpZGVyLm5ld0ZpbGVTeXN0ZW0ocCwgQ29sbGVjdGlvbnMuZW1wdHlNYXAoKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBhdGggbW9kdWxlSW5mb0NsYXNzID0gZnMuZ2V0UGF0aCgiY2xhc3Nlcy9tb2R1bGUtaW5mby5jbGFzcyIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBtb2R1bGVOYW1lID0gcmVhZE1vZHVsZU5hbWUobW9kdWxlSW5mb0NsYXNzKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQYXRoIG1vZHVsZVBhdGggPSBmcy5nZXRQYXRoKCJjbGFzc2VzIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZVN5c3RlbXMucHV0KHAsIGZzKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbG9zZWFibGVzLmFkZChmcyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnMgPSBudWxsOyAvLyBwcmV2ZW50IGZzIGJlaW5nIGNsb3NlZCBpbiB0aGUgZmluYWxseSBjbGF1c2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFBhaXI8Pihtb2R1bGVOYW1lLCBtb2R1bGVQYXRoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZzICE9IG51bGwpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZzLmNsb3NlKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChNb2R1bGVOYW1lUmVhZGVyLkJhZENsYXNzRmlsZSBlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGxvZy5lcnJvcihFcnJvcnMuTG9jbkJhZE1vZHVsZUluZm8ocCkpOwogICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgbG9nLmVycm9yKEVycm9ycy5Mb2NuQ2FudFJlYWRGaWxlKHApKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmICh3YXJuICYmIGZhbHNlKSB7ICAvLyB0ZW1wIGRpc2FibGUsIHdoZW4gZW5hYmxlZCwgbWFzc2FnZSBleGFtcGxlcy5ub3QteWV0LnR4dCBzdWl0YWJseS4KICAgICAgICAgICAgICAgICAgICBsb2cud2FybmluZyhXYXJuaW5ncy5Mb2NuVW5rbm93bkZpbGVPbk1vZHVsZVBhdGgocCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHByaXZhdGUgU3RyaW5nIHJlYWRNb2R1bGVOYW1lKFBhdGggcGF0aCkgdGhyb3dzIElPRXhjZXB0aW9uLCBNb2R1bGVOYW1lUmVhZGVyLkJhZENsYXNzRmlsZSB7CiAgICAgICAgICAgICAgICBpZiAobW9kdWxlTmFtZVJlYWRlciA9PSBudWxsKQogICAgICAgICAgICAgICAgICAgIG1vZHVsZU5hbWVSZWFkZXIgPSBuZXcgTW9kdWxlTmFtZVJlYWRlcigpOwogICAgICAgICAgICAgICAgcmV0dXJuIG1vZHVsZU5hbWVSZWFkZXIucmVhZE1vZHVsZU5hbWUocGF0aCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgfQoKICAgIHByaXZhdGUgY2xhc3MgTW9kdWxlU291cmNlUGF0aExvY2F0aW9uSGFuZGxlciBleHRlbmRzIEJhc2ljTG9jYXRpb25IYW5kbGVyIHsKICAgICAgICBwcml2YXRlIE1vZHVsZVRhYmxlIG1vZHVsZVRhYmxlOwoKICAgICAgICBNb2R1bGVTb3VyY2VQYXRoTG9jYXRpb25IYW5kbGVyKCkgewogICAgICAgICAgICBzdXBlcihTdGFuZGFyZExvY2F0aW9uLk1PRFVMRV9TT1VSQ0VfUEFUSCwKICAgICAgICAgICAgICAgICAgICBPcHRpb24uTU9EVUxFX1NPVVJDRV9QQVRIKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIGJvb2xlYW4gaGFuZGxlT3B0aW9uKE9wdGlvbiBvcHRpb24sIFN0cmluZyB2YWx1ZSkgewogICAgICAgICAgICBpbml0KHZhbHVlKTsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICB2b2lkIGluaXQoU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgICAgIENvbGxlY3Rpb248U3RyaW5nPiBzZWdtZW50cyA9IG5ldyBBcnJheUxpc3Q8PigpOwogICAgICAgICAgICBmb3IgKFN0cmluZyBzOiB2YWx1ZS5zcGxpdChGaWxlLnBhdGhTZXBhcmF0b3IpKSB7CiAgICAgICAgICAgICAgICBleHBhbmRCcmFjZXMocywgc2VnbWVudHMpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBNYXA8U3RyaW5nLCBMaXN0PFBhdGg+PiBtYXAgPSBuZXcgTGlua2VkSGFzaE1hcDw+KCk7CiAgICAgICAgICAgIGZpbmFsIFN0cmluZyBNQVJLRVIgPSAiKiI7CiAgICAgICAgICAgIGZvciAoU3RyaW5nIHNlZzogc2VnbWVudHMpIHsKICAgICAgICAgICAgICAgIGludCBtYXJrU3RhcnQgPSBzZWcuaW5kZXhPZihNQVJLRVIpOwogICAgICAgICAgICAgICAgaWYgKG1hcmtTdGFydCA9PSAtMSkgewogICAgICAgICAgICAgICAgICAgIGFkZChtYXAsIGdldFBhdGgoc2VnKSwgbnVsbCk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGlmIChtYXJrU3RhcnQgPT0gMCB8fCAhaXNTZXBhcmF0b3Ioc2VnLmNoYXJBdChtYXJrU3RhcnQgLSAxKSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiaWxsZWdhbCB1c2Ugb2YgIiArIE1BUktFUiArICIgaW4gIiArIHNlZyk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIFBhdGggcHJlZml4ID0gZ2V0UGF0aChzZWcuc3Vic3RyaW5nKDAsIG1hcmtTdGFydCAtIDEpKTsKICAgICAgICAgICAgICAgICAgICBQYXRoIHN1ZmZpeDsKICAgICAgICAgICAgICAgICAgICBpbnQgbWFya0VuZCA9IG1hcmtTdGFydCArIE1BUktFUi5sZW5ndGgoKTsKICAgICAgICAgICAgICAgICAgICBpZiAobWFya0VuZCA9PSBzZWcubGVuZ3RoKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgc3VmZml4ID0gbnVsbDsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCFpc1NlcGFyYXRvcihzZWcuY2hhckF0KG1hcmtFbmQpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgc2VnLmluZGV4T2YoTUFSS0VSLCBtYXJrRW5kKSAhPSAtMSkgewogICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJpbGxlZ2FsIHVzZSBvZiAiICsgTUFSS0VSICsgIiBpbiAiICsgc2VnKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBzdWZmaXggPSBnZXRQYXRoKHNlZy5zdWJzdHJpbmcobWFya0VuZCArIDEpKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYWRkKG1hcCwgcHJlZml4LCBzdWZmaXgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBtb2R1bGVUYWJsZSA9IG5ldyBNb2R1bGVUYWJsZSgpOwogICAgICAgICAgICBtYXAuZm9yRWFjaCgobW9kTmFtZSwgbW9kUGF0aCkgLT4gewogICAgICAgICAgICAgICAgYm9vbGVhbiBoYXNNb2R1bGVJbmZvID0gbW9kUGF0aC5zdHJlYW0oKS5hbnlNYXRjaChjaGVja01vZHVsZUluZm8pOwogICAgICAgICAgICAgICAgaWYgKGhhc01vZHVsZUluZm8pIHsKICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbG9jbk5hbWUgPSBsb2NhdGlvbi5nZXROYW1lKCkgKyAiWyIgKyBtb2ROYW1lICsgIl0iOwogICAgICAgICAgICAgICAgICAgIE1vZHVsZUxvY2F0aW9uSGFuZGxlciBsID0gbmV3IE1vZHVsZUxvY2F0aW9uSGFuZGxlcih0aGlzLCBsb2NuTmFtZSwgbW9kTmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vZFBhdGgsIGZhbHNlKTsKICAgICAgICAgICAgICAgICAgICBtb2R1bGVUYWJsZS5hZGQobCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KICAgICAgICAvL3doZXJlOgogICAgICAgICAgICBwcml2YXRlIGZpbmFsIFByZWRpY2F0ZTxQYXRoPiBjaGVja01vZHVsZUluZm8gPQogICAgICAgICAgICAgICAgICAgIHAgLT4gRmlsZXMuZXhpc3RzKHAucmVzb2x2ZSgibW9kdWxlLWluZm8uamF2YSIpKTsKCgogICAgICAgIHByaXZhdGUgYm9vbGVhbiBpc1NlcGFyYXRvcihjaGFyIGNoKSB7CiAgICAgICAgICAgIC8vIGFsbG93IGJvdGggc2VwYXJhdG9ycyBvbiBXaW5kb3dzCiAgICAgICAgICAgIHJldHVybiAoY2ggPT0gRmlsZS5zZXBhcmF0b3JDaGFyKSB8fCAoY2ggPT0gJy8nKTsKICAgICAgICB9CgogICAgICAgIHZvaWQgYWRkKE1hcDxTdHJpbmcsIExpc3Q8UGF0aD4+IG1hcCwgUGF0aCBwcmVmaXgsIFBhdGggc3VmZml4KSB7CiAgICAgICAgICAgIGlmICghRmlsZXMuaXNEaXJlY3RvcnkocHJlZml4KSkgewogICAgICAgICAgICAgICAgaWYgKHdhcm4pIHsKICAgICAgICAgICAgICAgICAgICBTdHJpbmcga2V5ID0gRmlsZXMuZXhpc3RzKHByZWZpeCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gImRpci5wYXRoLmVsZW1lbnQubm90LmRpcmVjdG9yeSIKICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogImRpci5wYXRoLmVsZW1lbnQubm90LmZvdW5kIjsKICAgICAgICAgICAgICAgICAgICBsb2cud2FybmluZyhMaW50LkxpbnRDYXRlZ29yeS5QQVRILCBrZXksIHByZWZpeCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdHJ5IChEaXJlY3RvcnlTdHJlYW08UGF0aD4gc3RyZWFtID0gRmlsZXMubmV3RGlyZWN0b3J5U3RyZWFtKHByZWZpeCwgcGF0aCAtPiBGaWxlcy5pc0RpcmVjdG9yeShwYXRoKSkpIHsKICAgICAgICAgICAgICAgIGZvciAoUGF0aCBlbnRyeTogc3RyZWFtKSB7CiAgICAgICAgICAgICAgICAgICAgUGF0aCBwYXRoID0gKHN1ZmZpeCA9PSBudWxsKSA/IGVudHJ5IDogZW50cnkucmVzb2x2ZShzdWZmaXgpOwogICAgICAgICAgICAgICAgICAgIGlmIChGaWxlcy5pc0RpcmVjdG9yeShwYXRoKSkgewogICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbmFtZSA9IGVudHJ5LmdldEZpbGVOYW1lKCkudG9TdHJpbmcoKTsKICAgICAgICAgICAgICAgICAgICAgICAgTGlzdDxQYXRoPiBwYXRocyA9IG1hcC5nZXQobmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwYXRocyA9PSBudWxsKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFwLnB1dChuYW1lLCBwYXRocyA9IG5ldyBBcnJheUxpc3Q8PigpKTsKICAgICAgICAgICAgICAgICAgICAgICAgcGF0aHMuYWRkKHBhdGgpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICAgICAgLy8gVE9ETz8gV2hhdCB0byBkbz8KICAgICAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbihlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSB2b2lkIGV4cGFuZEJyYWNlcyhTdHJpbmcgdmFsdWUsIENvbGxlY3Rpb248U3RyaW5nPiByZXN1bHRzKSB7CiAgICAgICAgICAgIGludCBkZXB0aCA9IDA7CiAgICAgICAgICAgIGludCBzdGFydCA9IC0xOwogICAgICAgICAgICBTdHJpbmcgcHJlZml4ID0gbnVsbDsKICAgICAgICAgICAgU3RyaW5nIHN1ZmZpeCA9IG51bGw7CiAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdmFsdWUubGVuZ3RoKCk7IGkrKykgewogICAgICAgICAgICAgICAgc3dpdGNoICh2YWx1ZS5jaGFyQXQoaSkpIHsKICAgICAgICAgICAgICAgICAgICBjYXNlICd7JzoKICAgICAgICAgICAgICAgICAgICAgICAgZGVwdGgrKzsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRlcHRoID09IDEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZWZpeCA9IHZhbHVlLnN1YnN0cmluZygwLCBpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1ZmZpeCA9IHZhbHVlLnN1YnN0cmluZyhnZXRNYXRjaGluZ0JyYWNlKHZhbHVlLCBpKSArIDEpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhcnQgPSBpICsgMTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICAgICAgY2FzZSAnLCc6CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkZXB0aCA9PSAxKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgZWxlbSA9IHZhbHVlLnN1YnN0cmluZyhzdGFydCwgaSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHBhbmRCcmFjZXMocHJlZml4ICsgZWxlbSArIHN1ZmZpeCwgcmVzdWx0cyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGFydCA9IGkgKyAxOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgICAgICBjYXNlICd9JzoKICAgICAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChkZXB0aCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIm1pc21hdGNoZWQgYnJhY2VzIik7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAxOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBlbGVtID0gdmFsdWUuc3Vic3RyaW5nKHN0YXJ0LCBpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHBhbmRCcmFjZXMocHJlZml4ICsgZWxlbSArIHN1ZmZpeCwgcmVzdWx0cyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVwdGgtLTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoZGVwdGggPiAwKQogICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigibWlzbWF0Y2hlZCBicmFjZXMiKTsKICAgICAgICAgICAgcmVzdWx0cy5hZGQodmFsdWUpOwogICAgICAgIH0KCiAgICAgICAgaW50IGdldE1hdGNoaW5nQnJhY2UoU3RyaW5nIHZhbHVlLCBpbnQgb2Zmc2V0KSB7CiAgICAgICAgICAgIGludCBkZXB0aCA9IDE7CiAgICAgICAgICAgIGZvciAoaW50IGkgPSBvZmZzZXQgKyAxOyBpIDwgdmFsdWUubGVuZ3RoKCk7IGkrKykgewogICAgICAgICAgICAgICAgc3dpdGNoICh2YWx1ZS5jaGFyQXQoaSkpIHsKICAgICAgICAgICAgICAgICAgICBjYXNlICd7JzoKICAgICAgICAgICAgICAgICAgICAgICAgZGVwdGgrKzsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgICAgIGNhc2UgJ30nOgogICAgICAgICAgICAgICAgICAgICAgICBpZiAoLS1kZXB0aCA9PSAwKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIm1pc21hdGNoZWQgYnJhY2VzIik7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBib29sZWFuIGlzU2V0KCkgewogICAgICAgICAgICByZXR1cm4gKG1vZHVsZVRhYmxlICE9IG51bGwpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgQ29sbGVjdGlvbjxQYXRoPiBnZXRQYXRocygpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICB2b2lkIHNldFBhdGhzKEl0ZXJhYmxlPD8gZXh0ZW5kcyBQYXRoPiBmaWxlcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICB2b2lkIHNldFBhdGhzRm9yTW9kdWxlKFN0cmluZyBuYW1lLCBJdGVyYWJsZTw/IGV4dGVuZHMgUGF0aD4gcGF0aHMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgICAgIExpc3Q8UGF0aD4gdmFsaWRQYXRocyA9IGNoZWNrUGF0aHMocGF0aHMpOwoKICAgICAgICAgICAgaWYgKG1vZHVsZVRhYmxlID09IG51bGwpCiAgICAgICAgICAgICAgICBtb2R1bGVUYWJsZSA9IG5ldyBNb2R1bGVUYWJsZSgpOwoKICAgICAgICAgICAgTW9kdWxlTG9jYXRpb25IYW5kbGVyIGwgPSBtb2R1bGVUYWJsZS5nZXQobmFtZSk7CiAgICAgICAgICAgIGlmIChsID09IG51bGwpIHsKICAgICAgICAgICAgICAgIGwgPSBuZXcgTW9kdWxlTG9jYXRpb25IYW5kbGVyKHRoaXMsCiAgICAgICAgICAgICAgICAgICAgICAgIGxvY2F0aW9uLmdldE5hbWUoKSArICJbIiArIG5hbWUgKyAiXSIsCiAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgIHZhbGlkUGF0aHMsCiAgICAgICAgICAgICAgICAgICAgICAgIHRydWUpOwogICAgICAgICAgICAgICAgbW9kdWxlVGFibGUuYWRkKGwpOwogICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBsLnNlYXJjaFBhdGggPSB2YWxpZFBhdGhzOwogICAgICAgICAgICAgICAgbW9kdWxlVGFibGUudXBkYXRlUGF0aHMobCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHByaXZhdGUgTGlzdDxQYXRoPiBjaGVja1BhdGhzKEl0ZXJhYmxlPD8gZXh0ZW5kcyBQYXRoPiBwYXRocykgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICAgICAgT2JqZWN0cy5yZXF1aXJlTm9uTnVsbChwYXRocyk7CiAgICAgICAgICAgIExpc3Q8UGF0aD4gdmFsaWRQYXRocyA9IG5ldyBBcnJheUxpc3Q8PigpOwogICAgICAgICAgICBmb3IgKFBhdGggcCA6IHBhdGhzKSB7CiAgICAgICAgICAgICAgICB2YWxpZFBhdGhzLmFkZChjaGVja0RpcmVjdG9yeShwKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHZhbGlkUGF0aHM7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBMb2NhdGlvbiBnZXRMb2NhdGlvbkZvck1vZHVsZShTdHJpbmcgbmFtZSkgewogICAgICAgICAgICByZXR1cm4gKG1vZHVsZVRhYmxlID09IG51bGwpID8gbnVsbCA6IG1vZHVsZVRhYmxlLmdldChuYW1lKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIExvY2F0aW9uIGdldExvY2F0aW9uRm9yTW9kdWxlKFBhdGggZmlsZSkgewogICAgICAgICAgICByZXR1cm4gKG1vZHVsZVRhYmxlID09IG51bGwpID8gbnVsbCA6IG1vZHVsZVRhYmxlLmdldChmaWxlKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIEl0ZXJhYmxlPFNldDxMb2NhdGlvbj4+IGxpc3RMb2NhdGlvbnNGb3JNb2R1bGVzKCkgewogICAgICAgICAgICBpZiAobW9kdWxlVGFibGUgPT0gbnVsbCkKICAgICAgICAgICAgICAgIHJldHVybiBDb2xsZWN0aW9ucy5lbXB0eVNldCgpOwoKICAgICAgICAgICAgcmV0dXJuIENvbGxlY3Rpb25zLnNpbmdsZXRvbihtb2R1bGVUYWJsZS5sb2NhdGlvbnMoKSk7CiAgICAgICAgfQoKICAgIH0KCiAgICBwcml2YXRlIGNsYXNzIFN5c3RlbU1vZHVsZXNMb2NhdGlvbkhhbmRsZXIgZXh0ZW5kcyBCYXNpY0xvY2F0aW9uSGFuZGxlciB7CiAgICAgICAgcHJpdmF0ZSBQYXRoIHN5c3RlbUphdmFIb21lOwogICAgICAgIHByaXZhdGUgUGF0aCBtb2R1bGVzOwogICAgICAgIHByaXZhdGUgTW9kdWxlVGFibGUgbW9kdWxlVGFibGU7CgogICAgICAgIFN5c3RlbU1vZHVsZXNMb2NhdGlvbkhhbmRsZXIoKSB7CiAgICAgICAgICAgIHN1cGVyKFN0YW5kYXJkTG9jYXRpb24uU1lTVEVNX01PRFVMRVMsIE9wdGlvbi5TWVNURU0pOwogICAgICAgICAgICBzeXN0ZW1KYXZhSG9tZSA9IExvY2F0aW9ucy5qYXZhSG9tZTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIGJvb2xlYW4gaGFuZGxlT3B0aW9uKE9wdGlvbiBvcHRpb24sIFN0cmluZyB2YWx1ZSkgewogICAgICAgICAgICBpZiAoIW9wdGlvbnMuY29udGFpbnMob3B0aW9uKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgc3lzdGVtSmF2YUhvbWUgPSBMb2NhdGlvbnMuamF2YUhvbWU7CiAgICAgICAgICAgIH0gZWxzZSBpZiAodmFsdWUuZXF1YWxzKCJub25lIikpIHsKICAgICAgICAgICAgICAgIHN5c3RlbUphdmFIb21lID0gbnVsbDsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHVwZGF0ZShnZXRQYXRoKHZhbHVlKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIG1vZHVsZXMgPSBudWxsOwogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIENvbGxlY3Rpb248UGF0aD4gZ2V0UGF0aHMoKSB7CiAgICAgICAgICAgIHJldHVybiAoc3lzdGVtSmF2YUhvbWUgPT0gbnVsbCkgPyBudWxsIDogQ29sbGVjdGlvbnMuc2luZ2xldG9uKHN5c3RlbUphdmFIb21lKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHZvaWQgc2V0UGF0aHMoSXRlcmFibGU8PyBleHRlbmRzIFBhdGg+IGZpbGVzKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgICAgICBpZiAoZmlsZXMgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgc3lzdGVtSmF2YUhvbWUgPSBudWxsOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgUGF0aCBkaXIgPSBjaGVja1NpbmdsZXRvbkRpcmVjdG9yeShmaWxlcyk7CiAgICAgICAgICAgICAgICB1cGRhdGUoZGlyKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgdm9pZCBzZXRQYXRoc0Zvck1vZHVsZShTdHJpbmcgbmFtZSwgSXRlcmFibGU8PyBleHRlbmRzIFBhdGg+IHBhdGhzKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgICAgICBMaXN0PFBhdGg+IGNoZWNrZWRQYXRocyA9IGNoZWNrUGF0aHMocGF0aHMpOwogICAgICAgICAgICBpbml0U3lzdGVtTW9kdWxlcygpOwogICAgICAgICAgICBNb2R1bGVMb2NhdGlvbkhhbmRsZXIgbCA9IG1vZHVsZVRhYmxlLmdldChuYW1lKTsKICAgICAgICAgICAgaWYgKGwgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgbCA9IG5ldyBNb2R1bGVMb2NhdGlvbkhhbmRsZXIodGhpcywKICAgICAgICAgICAgICAgICAgICAgICAgbG9jYXRpb24uZ2V0TmFtZSgpICsgIlsiICsgbmFtZSArICJdIiwKICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tlZFBhdGhzLAogICAgICAgICAgICAgICAgICAgICAgICB0cnVlKTsKICAgICAgICAgICAgICAgIG1vZHVsZVRhYmxlLmFkZChsKTsKICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgbC5zZWFyY2hQYXRoID0gY2hlY2tlZFBhdGhzOwogICAgICAgICAgICAgICAgbW9kdWxlVGFibGUudXBkYXRlUGF0aHMobCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHByaXZhdGUgTGlzdDxQYXRoPiBjaGVja1BhdGhzKEl0ZXJhYmxlPD8gZXh0ZW5kcyBQYXRoPiBwYXRocykgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICAgICAgT2JqZWN0cy5yZXF1aXJlTm9uTnVsbChwYXRocyk7CiAgICAgICAgICAgIExpc3Q8UGF0aD4gdmFsaWRQYXRocyA9IG5ldyBBcnJheUxpc3Q8PigpOwogICAgICAgICAgICBmb3IgKFBhdGggcCA6IHBhdGhzKSB7CiAgICAgICAgICAgICAgICB2YWxpZFBhdGhzLmFkZChjaGVja0RpcmVjdG9yeShwKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHZhbGlkUGF0aHM7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIHZvaWQgdXBkYXRlKFBhdGggcCkgewogICAgICAgICAgICBpZiAoIWlzQ3VycmVudFBsYXRmb3JtKHApICYmICFGaWxlcy5leGlzdHMocC5yZXNvbHZlKCJsaWIiKS5yZXNvbHZlKCJqcnQtZnMuamFyIikpICYmCiAgICAgICAgICAgICAgICAgICAgIUZpbGVzLmV4aXN0cyhzeXN0ZW1KYXZhSG9tZS5yZXNvbHZlKCJtb2R1bGVzIikpKQogICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihwLnRvU3RyaW5nKCkpOwogICAgICAgICAgICBzeXN0ZW1KYXZhSG9tZSA9IHA7CiAgICAgICAgICAgIG1vZHVsZXMgPSBudWxsOwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBib29sZWFuIGlzQ3VycmVudFBsYXRmb3JtKFBhdGggcCkgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgcmV0dXJuIEZpbGVzLmlzU2FtZUZpbGUocCwgTG9jYXRpb25zLmphdmFIb21lKTsKICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24ocC50b1N0cmluZygpLCBleCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIExvY2F0aW9uIGdldExvY2F0aW9uRm9yTW9kdWxlKFN0cmluZyBuYW1lKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgICAgICBpbml0U3lzdGVtTW9kdWxlcygpOwogICAgICAgICAgICByZXR1cm4gbW9kdWxlVGFibGUuZ2V0KG5hbWUpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgTG9jYXRpb24gZ2V0TG9jYXRpb25Gb3JNb2R1bGUoUGF0aCBmaWxlKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgICAgICBpbml0U3lzdGVtTW9kdWxlcygpOwogICAgICAgICAgICByZXR1cm4gbW9kdWxlVGFibGUuZ2V0KGZpbGUpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgSXRlcmFibGU8U2V0PExvY2F0aW9uPj4gbGlzdExvY2F0aW9uc0Zvck1vZHVsZXMoKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgICAgICBpbml0U3lzdGVtTW9kdWxlcygpOwogICAgICAgICAgICByZXR1cm4gQ29sbGVjdGlvbnMuc2luZ2xldG9uKG1vZHVsZVRhYmxlLmxvY2F0aW9ucygpKTsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgdm9pZCBpbml0U3lzdGVtTW9kdWxlcygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgICAgIGlmIChtb2R1bGVUYWJsZSAhPSBudWxsKQogICAgICAgICAgICAgICAgcmV0dXJuOwoKICAgICAgICAgICAgaWYgKHN5c3RlbUphdmFIb21lID09IG51bGwpIHsKICAgICAgICAgICAgICAgIG1vZHVsZVRhYmxlID0gbmV3IE1vZHVsZVRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChtb2R1bGVzID09IG51bGwpIHsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgVVJJIGpydFVSSSA9IFVSSS5jcmVhdGUoImpydDovIik7CiAgICAgICAgICAgICAgICAgICAgRmlsZVN5c3RlbSBqcnRmczsKCiAgICAgICAgICAgICAgICAgICAgaWYgKGlzQ3VycmVudFBsYXRmb3JtKHN5c3RlbUphdmFIb21lKSkgewogICAgICAgICAgICAgICAgICAgICAgICBqcnRmcyA9IEZpbGVTeXN0ZW1zLmdldEZpbGVTeXN0ZW0oanJ0VVJJKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgTWFwPFN0cmluZywgU3RyaW5nPiBhdHRyTWFwID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29sbGVjdGlvbnMuc2luZ2xldG9uTWFwKCJqYXZhLmhvbWUiLCBzeXN0ZW1KYXZhSG9tZS50b1N0cmluZygpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGpydGZzID0gRmlsZVN5c3RlbXMubmV3RmlsZVN5c3RlbShqcnRVUkksIGF0dHJNYXApOwogICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChQcm92aWRlck5vdEZvdW5kRXhjZXB0aW9uIGV4KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBVUkwgamF2YUhvbWVVUkwgPSBzeXN0ZW1KYXZhSG9tZS5yZXNvbHZlKCJqcnQtZnMuamFyIikudG9VcmkoKS50b1VSTCgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2xhc3NMb2FkZXIgY3VycmVudExvYWRlciA9IExvY2F0aW9ucy5jbGFzcy5nZXRDbGFzc0xvYWRlcigpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgVVJMQ2xhc3NMb2FkZXIgZnNMb2FkZXIgPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgVVJMQ2xhc3NMb2FkZXIobmV3IFVSTFtdIHtqYXZhSG9tZVVSTH0sIGN1cnJlbnRMb2FkZXIpOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGpydGZzID0gRmlsZVN5c3RlbXMubmV3RmlsZVN5c3RlbShqcnRVUkksIENvbGxlY3Rpb25zLmVtcHR5TWFwKCksIGZzTG9hZGVyKTsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbG9zZWFibGVzLmFkZChmc0xvYWRlcik7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIGNsb3NlYWJsZXMuYWRkKGpydGZzKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIG1vZHVsZXMgPSBqcnRmcy5nZXRQYXRoKCIvbW9kdWxlcyIpOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoRmlsZVN5c3RlbU5vdEZvdW5kRXhjZXB0aW9uIHwgUHJvdmlkZXJOb3RGb3VuZEV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgICAgICAgbW9kdWxlcyA9IHN5c3RlbUphdmFIb21lLnJlc29sdmUoIm1vZHVsZXMiKTsKICAgICAgICAgICAgICAgICAgICBpZiAoIUZpbGVzLmV4aXN0cyhtb2R1bGVzKSkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJjYW4ndCBmaW5kIHN5c3RlbSBjbGFzc2VzIiwgZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIG1vZHVsZVRhYmxlID0gbmV3IE1vZHVsZVRhYmxlKCk7CiAgICAgICAgICAgIHRyeSAoRGlyZWN0b3J5U3RyZWFtPFBhdGg+IHN0cmVhbSA9IEZpbGVzLm5ld0RpcmVjdG9yeVN0cmVhbShtb2R1bGVzLCBGaWxlczo6aXNEaXJlY3RvcnkpKSB7CiAgICAgICAgICAgICAgICBmb3IgKFBhdGggZW50cnkgOiBzdHJlYW0pIHsKICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbW9kdWxlTmFtZSA9IGVudHJ5LmdldEZpbGVOYW1lKCkudG9TdHJpbmcoKTsKICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbmFtZSA9IGxvY2F0aW9uLmdldE5hbWUoKSArICJbIiArIG1vZHVsZU5hbWUgKyAiXSI7CiAgICAgICAgICAgICAgICAgICAgTW9kdWxlTG9jYXRpb25IYW5kbGVyIGggPSBuZXcgTW9kdWxlTG9jYXRpb25IYW5kbGVyKHRoaXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lLCBtb2R1bGVOYW1lLCBDb2xsZWN0aW9ucy5zaW5nbGV0b25MaXN0KGVudHJ5KSwgZmFsc2UpOwogICAgICAgICAgICAgICAgICAgIG1vZHVsZVRhYmxlLmFkZChoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIGNsYXNzIFBhdGNoTW9kdWxlc0xvY2F0aW9uSGFuZGxlciBleHRlbmRzIEJhc2ljTG9jYXRpb25IYW5kbGVyIHsKICAgICAgICBwcml2YXRlIGZpbmFsIE1vZHVsZVRhYmxlIG1vZHVsZVRhYmxlID0gbmV3IE1vZHVsZVRhYmxlKCk7CgogICAgICAgIFBhdGNoTW9kdWxlc0xvY2F0aW9uSGFuZGxlcigpIHsKICAgICAgICAgICAgc3VwZXIoU3RhbmRhcmRMb2NhdGlvbi5QQVRDSF9NT0RVTEVfUEFUSCwgT3B0aW9uLlBBVENIX01PRFVMRSk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBib29sZWFuIGhhbmRsZU9wdGlvbihPcHRpb24gb3B0aW9uLCBTdHJpbmcgdmFsdWUpIHsKICAgICAgICAgICAgaWYgKCFvcHRpb25zLmNvbnRhaW5zKG9wdGlvbikpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbW9kdWxlVGFibGUuY2xlYXIoKTsKCiAgICAgICAgICAgIC8vIEFsbG93IGFuIGV4dGVuZGVkIHN5bnRheCBmb3IgLS1wYXRjaC1tb2R1bGUgY29uc2lzdGluZyBvZiBhIHNlcmllcwogICAgICAgICAgICAvLyBvZiB2YWx1ZXMgc2VwYXJhdGVkIGJ5IE5VTEwgY2hhcmFjdGVycy4gVGhpcyBpcyB0byBmYWNpbGl0YXRlCiAgICAgICAgICAgIC8vIHN1cHBvcnRpbmcgZGVmZXJyZWQgZmlsZSBtYW5hZ2VyIG9wdGlvbnMgb24gdGhlIGNvbW1hbmQgbGluZS4KICAgICAgICAgICAgLy8gU2VlIE9wdGlvbi5QQVRDSF9NT0RVTEUgZm9yIHRoZSBjb2RlIHRoYXQgY29tcG9zZXMgdGhlc2UgbXVsdGlwbGUKICAgICAgICAgICAgLy8gdmFsdWVzLgogICAgICAgICAgICBmb3IgKFN0cmluZyB2IDogdmFsdWUuc3BsaXQoIlwwIikpIHsKICAgICAgICAgICAgICAgIGludCBlcSA9IHYuaW5kZXhPZignPScpOwogICAgICAgICAgICAgICAgaWYgKGVxID4gMCkgewogICAgICAgICAgICAgICAgICAgIFN0cmluZyBtb2R1bGVOYW1lID0gdi5zdWJzdHJpbmcoMCwgZXEpOwogICAgICAgICAgICAgICAgICAgIFNlYXJjaFBhdGggbVBhdGNoUGF0aCA9IG5ldyBTZWFyY2hQYXRoKCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5hZGRGaWxlcyh2LnN1YnN0cmluZyhlcSArIDEpKTsKICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbmFtZSA9IGxvY2F0aW9uLmdldE5hbWUoKSArICJbIiArIG1vZHVsZU5hbWUgKyAiXSI7CiAgICAgICAgICAgICAgICAgICAgTW9kdWxlTG9jYXRpb25IYW5kbGVyIGggPSBuZXcgTW9kdWxlTG9jYXRpb25IYW5kbGVyKHRoaXMsIG5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb2R1bGVOYW1lLCBtUGF0Y2hQYXRoLCBmYWxzZSk7CiAgICAgICAgICAgICAgICAgICAgbW9kdWxlVGFibGUuYWRkKGgpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAvLyBTaG91bGQgbm90IGJlIGFibGUgdG8gZ2V0IGhlcmU7CiAgICAgICAgICAgICAgICAgICAgLy8gdGhpcyBzaG91bGQgYmUgY2F1Z2h0IGFuZCBoYW5kbGVkIGluIE9wdGlvbi5QQVRDSF9NT0RVTEUKICAgICAgICAgICAgICAgICAgICBsb2cuZXJyb3IoRXJyb3JzLkxvY25JbnZhbGlkQXJnRm9yWHBhdGNoKHZhbHVlKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgYm9vbGVhbiBpc1NldCgpIHsKICAgICAgICAgICAgcmV0dXJuICFtb2R1bGVUYWJsZS5pc0VtcHR5KCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBDb2xsZWN0aW9uPFBhdGg+IGdldFBhdGhzKCkgewogICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHZvaWQgc2V0UGF0aHMoSXRlcmFibGU8PyBleHRlbmRzIFBhdGg+IGZpbGVzKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSAvLyBkZWZpbmVkIGJ5IExvY2F0aW9uSGFuZGxlcgogICAgICAgIHZvaWQgc2V0UGF0aHNGb3JNb2R1bGUoU3RyaW5nIG1vZHVsZU5hbWUsIEl0ZXJhYmxlPD8gZXh0ZW5kcyBQYXRoPiBmaWxlcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7IC8vIG5vdCB5ZXQKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIExvY2F0aW9uIGdldExvY2F0aW9uRm9yTW9kdWxlKFN0cmluZyBuYW1lKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgICAgICByZXR1cm4gbW9kdWxlVGFibGUuZ2V0KG5hbWUpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgTG9jYXRpb24gZ2V0TG9jYXRpb25Gb3JNb2R1bGUoUGF0aCBmaWxlKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgICAgICByZXR1cm4gbW9kdWxlVGFibGUuZ2V0KGZpbGUpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgSXRlcmFibGU8U2V0PExvY2F0aW9uPj4gbGlzdExvY2F0aW9uc0Zvck1vZHVsZXMoKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgICAgICByZXR1cm4gQ29sbGVjdGlvbnMuc2luZ2xldG9uKG1vZHVsZVRhYmxlLmxvY2F0aW9ucygpKTsKICAgICAgICB9CiAgICB9CgogICAgTWFwPExvY2F0aW9uLCBMb2NhdGlvbkhhbmRsZXI+IGhhbmRsZXJzRm9yTG9jYXRpb247CiAgICBNYXA8T3B0aW9uLCBMb2NhdGlvbkhhbmRsZXI+IGhhbmRsZXJzRm9yT3B0aW9uOwoKICAgIHZvaWQgaW5pdEhhbmRsZXJzKCkgewogICAgICAgIGhhbmRsZXJzRm9yTG9jYXRpb24gPSBuZXcgSGFzaE1hcDw+KCk7CiAgICAgICAgaGFuZGxlcnNGb3JPcHRpb24gPSBuZXcgRW51bU1hcDw+KE9wdGlvbi5jbGFzcyk7CgogICAgICAgIEJhc2ljTG9jYXRpb25IYW5kbGVyW10gaGFuZGxlcnMgPSB7CiAgICAgICAgICAgIG5ldyBCb290Q2xhc3NQYXRoTG9jYXRpb25IYW5kbGVyKCksCiAgICAgICAgICAgIG5ldyBDbGFzc1BhdGhMb2NhdGlvbkhhbmRsZXIoKSwKICAgICAgICAgICAgbmV3IFNpbXBsZUxvY2F0aW9uSGFuZGxlcihTdGFuZGFyZExvY2F0aW9uLlNPVVJDRV9QQVRILCBPcHRpb24uU09VUkNFX1BBVEgpLAogICAgICAgICAgICBuZXcgU2ltcGxlTG9jYXRpb25IYW5kbGVyKFN0YW5kYXJkTG9jYXRpb24uQU5OT1RBVElPTl9QUk9DRVNTT1JfUEFUSCwgT3B0aW9uLlBST0NFU1NPUl9QQVRIKSwKICAgICAgICAgICAgbmV3IFNpbXBsZUxvY2F0aW9uSGFuZGxlcihTdGFuZGFyZExvY2F0aW9uLkFOTk9UQVRJT05fUFJPQ0VTU09SX01PRFVMRV9QQVRILCBPcHRpb24uUFJPQ0VTU09SX01PRFVMRV9QQVRIKSwKICAgICAgICAgICAgbmV3IE91dHB1dExvY2F0aW9uSGFuZGxlcihTdGFuZGFyZExvY2F0aW9uLkNMQVNTX09VVFBVVCwgT3B0aW9uLkQpLAogICAgICAgICAgICBuZXcgT3V0cHV0TG9jYXRpb25IYW5kbGVyKFN0YW5kYXJkTG9jYXRpb24uU09VUkNFX09VVFBVVCwgT3B0aW9uLlMpLAogICAgICAgICAgICBuZXcgT3V0cHV0TG9jYXRpb25IYW5kbGVyKFN0YW5kYXJkTG9jYXRpb24uTkFUSVZFX0hFQURFUl9PVVRQVVQsIE9wdGlvbi5IKSwKICAgICAgICAgICAgbmV3IE1vZHVsZVNvdXJjZVBhdGhMb2NhdGlvbkhhbmRsZXIoKSwKICAgICAgICAgICAgbmV3IFBhdGNoTW9kdWxlc0xvY2F0aW9uSGFuZGxlcigpLAogICAgICAgICAgICBuZXcgTW9kdWxlUGF0aExvY2F0aW9uSGFuZGxlcihTdGFuZGFyZExvY2F0aW9uLlVQR1JBREVfTU9EVUxFX1BBVEgsIE9wdGlvbi5VUEdSQURFX01PRFVMRV9QQVRIKSwKICAgICAgICAgICAgbmV3IE1vZHVsZVBhdGhMb2NhdGlvbkhhbmRsZXIoU3RhbmRhcmRMb2NhdGlvbi5NT0RVTEVfUEFUSCwgT3B0aW9uLk1PRFVMRV9QQVRIKSwKICAgICAgICAgICAgbmV3IFN5c3RlbU1vZHVsZXNMb2NhdGlvbkhhbmRsZXIoKSwKICAgICAgICB9OwoKICAgICAgICBmb3IgKEJhc2ljTG9jYXRpb25IYW5kbGVyIGggOiBoYW5kbGVycykgewogICAgICAgICAgICBoYW5kbGVyc0ZvckxvY2F0aW9uLnB1dChoLmxvY2F0aW9uLCBoKTsKICAgICAgICAgICAgZm9yIChPcHRpb24gbyA6IGgub3B0aW9ucykgewogICAgICAgICAgICAgICAgaGFuZGxlcnNGb3JPcHRpb24ucHV0KG8sIGgpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIGJvb2xlYW4gaGFuZGxlT3B0aW9uKE9wdGlvbiBvcHRpb24sIFN0cmluZyB2YWx1ZSkgewogICAgICAgIExvY2F0aW9uSGFuZGxlciBoID0gaGFuZGxlcnNGb3JPcHRpb24uZ2V0KG9wdGlvbik7CiAgICAgICAgcmV0dXJuIChoID09IG51bGwgPyBmYWxzZSA6IGguaGFuZGxlT3B0aW9uKG9wdGlvbiwgdmFsdWUpKTsKICAgIH0KCiAgICBib29sZWFuIGhhc0xvY2F0aW9uKExvY2F0aW9uIGxvY2F0aW9uKSB7CiAgICAgICAgTG9jYXRpb25IYW5kbGVyIGggPSBnZXRIYW5kbGVyKGxvY2F0aW9uKTsKICAgICAgICByZXR1cm4gKGggPT0gbnVsbCA/IGZhbHNlIDogaC5pc1NldCgpKTsKICAgIH0KCiAgICBDb2xsZWN0aW9uPFBhdGg+IGdldExvY2F0aW9uKExvY2F0aW9uIGxvY2F0aW9uKSB7CiAgICAgICAgTG9jYXRpb25IYW5kbGVyIGggPSBnZXRIYW5kbGVyKGxvY2F0aW9uKTsKICAgICAgICByZXR1cm4gKGggPT0gbnVsbCA/IG51bGwgOiBoLmdldFBhdGhzKCkpOwogICAgfQoKICAgIFBhdGggZ2V0T3V0cHV0TG9jYXRpb24oTG9jYXRpb24gbG9jYXRpb24pIHsKICAgICAgICBpZiAoIWxvY2F0aW9uLmlzT3V0cHV0TG9jYXRpb24oKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIExvY2F0aW9uSGFuZGxlciBoID0gZ2V0SGFuZGxlcihsb2NhdGlvbik7CiAgICAgICAgcmV0dXJuICgoT3V0cHV0TG9jYXRpb25IYW5kbGVyKSBoKS5vdXRwdXREaXI7CiAgICB9CgogICAgdm9pZCBzZXRMb2NhdGlvbihMb2NhdGlvbiBsb2NhdGlvbiwgSXRlcmFibGU8PyBleHRlbmRzIFBhdGg+IGZpbGVzKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgIExvY2F0aW9uSGFuZGxlciBoID0gZ2V0SGFuZGxlcihsb2NhdGlvbik7CiAgICAgICAgaWYgKGggPT0gbnVsbCkgewogICAgICAgICAgICBpZiAobG9jYXRpb24uaXNPdXRwdXRMb2NhdGlvbigpKSB7CiAgICAgICAgICAgICAgICBoID0gbmV3IE91dHB1dExvY2F0aW9uSGFuZGxlcihsb2NhdGlvbik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBoID0gbmV3IFNpbXBsZUxvY2F0aW9uSGFuZGxlcihsb2NhdGlvbik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaGFuZGxlcnNGb3JMb2NhdGlvbi5wdXQobG9jYXRpb24sIGgpOwogICAgICAgIH0KICAgICAgICBoLnNldFBhdGhzKGZpbGVzKTsKICAgIH0KCiAgICBMb2NhdGlvbiBnZXRMb2NhdGlvbkZvck1vZHVsZShMb2NhdGlvbiBsb2NhdGlvbiwgU3RyaW5nIG5hbWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgTG9jYXRpb25IYW5kbGVyIGggPSBnZXRIYW5kbGVyKGxvY2F0aW9uKTsKICAgICAgICByZXR1cm4gKGggPT0gbnVsbCA/IG51bGwgOiBoLmdldExvY2F0aW9uRm9yTW9kdWxlKG5hbWUpKTsKICAgIH0KCiAgICBMb2NhdGlvbiBnZXRMb2NhdGlvbkZvck1vZHVsZShMb2NhdGlvbiBsb2NhdGlvbiwgUGF0aCBmaWxlKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgIExvY2F0aW9uSGFuZGxlciBoID0gZ2V0SGFuZGxlcihsb2NhdGlvbik7CiAgICAgICAgcmV0dXJuIChoID09IG51bGwgPyBudWxsIDogaC5nZXRMb2NhdGlvbkZvck1vZHVsZShmaWxlKSk7CiAgICB9CgogICAgdm9pZCBzZXRMb2NhdGlvbkZvck1vZHVsZShMb2NhdGlvbiBsb2NhdGlvbiwgU3RyaW5nIG1vZHVsZU5hbWUsCiAgICAgICAgICAgIEl0ZXJhYmxlPD8gZXh0ZW5kcyBQYXRoPiBmaWxlcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICBMb2NhdGlvbkhhbmRsZXIgaCA9IGdldEhhbmRsZXIobG9jYXRpb24pOwogICAgICAgIGlmIChoID09IG51bGwpIHsKICAgICAgICAgICAgaWYgKGxvY2F0aW9uLmlzT3V0cHV0TG9jYXRpb24oKSkgewogICAgICAgICAgICAgICAgaCA9IG5ldyBPdXRwdXRMb2NhdGlvbkhhbmRsZXIobG9jYXRpb24pOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgaCA9IG5ldyBNb2R1bGVQYXRoTG9jYXRpb25IYW5kbGVyKGxvY2F0aW9uKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBoYW5kbGVyc0ZvckxvY2F0aW9uLnB1dChsb2NhdGlvbiwgaCk7CiAgICAgICAgfQogICAgICAgIGguc2V0UGF0aHNGb3JNb2R1bGUobW9kdWxlTmFtZSwgZmlsZXMpOwogICAgfQoKICAgIFN0cmluZyBpbmZlck1vZHVsZU5hbWUoTG9jYXRpb24gbG9jYXRpb24pIHsKICAgICAgICBMb2NhdGlvbkhhbmRsZXIgaCA9IGdldEhhbmRsZXIobG9jYXRpb24pOwogICAgICAgIHJldHVybiAoaCA9PSBudWxsID8gbnVsbCA6IGguaW5mZXJNb2R1bGVOYW1lKCkpOwogICAgfQoKICAgIEl0ZXJhYmxlPFNldDxMb2NhdGlvbj4+IGxpc3RMb2NhdGlvbnNGb3JNb2R1bGVzKExvY2F0aW9uIGxvY2F0aW9uKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgIExvY2F0aW9uSGFuZGxlciBoID0gZ2V0SGFuZGxlcihsb2NhdGlvbik7CiAgICAgICAgcmV0dXJuIChoID09IG51bGwgPyBudWxsIDogaC5saXN0TG9jYXRpb25zRm9yTW9kdWxlcygpKTsKICAgIH0KCiAgICBwcm90ZWN0ZWQgTG9jYXRpb25IYW5kbGVyIGdldEhhbmRsZXIoTG9jYXRpb24gbG9jYXRpb24pIHsKICAgICAgICBPYmplY3RzLnJlcXVpcmVOb25OdWxsKGxvY2F0aW9uKTsKICAgICAgICByZXR1cm4gKGxvY2F0aW9uIGluc3RhbmNlb2YgTG9jYXRpb25IYW5kbGVyKQogICAgICAgICAgICAgICAgPyAoTG9jYXRpb25IYW5kbGVyKSBsb2NhdGlvbgogICAgICAgICAgICAgICAgOiBoYW5kbGVyc0ZvckxvY2F0aW9uLmdldChsb2NhdGlvbik7CiAgICB9CgogICAgLyoqCiAgICAgKiBJcyB0aGlzIHRoZSBuYW1lIG9mIGFuIGFyY2hpdmUgZmlsZT8KICAgICAqLwogICAgcHJpdmF0ZSBib29sZWFuIGlzQXJjaGl2ZShQYXRoIGZpbGUpIHsKICAgICAgICBTdHJpbmcgbiA9IFN0cmluZ1V0aWxzLnRvTG93ZXJDYXNlKGZpbGUuZ2V0RmlsZU5hbWUoKS50b1N0cmluZygpKTsKICAgICAgICByZXR1cm4gZnNJbmZvLmlzRmlsZShmaWxlKQogICAgICAgICAgICAgICAgJiYgKG4uZW5kc1dpdGgoIi5qYXIiKSB8fCBuLmVuZHNXaXRoKCIuemlwIikpOwogICAgfQoKICAgIHN0YXRpYyBQYXRoIG5vcm1hbGl6ZShQYXRoIHApIHsKICAgICAgICB0cnkgewogICAgICAgICAgICByZXR1cm4gcC50b1JlYWxQYXRoKCk7CiAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICByZXR1cm4gcC50b0Fic29sdXRlUGF0aCgpLm5vcm1hbGl6ZSgpOwogICAgICAgIH0KICAgIH0KfQpQSwMECgAACAAABjupSjiNRF/2DwAA9g8AACkAAABjb20vc3VuL3Rvb2xzL2phdmFjL2ZpbGUvQ2FjaGVGU0luZm8uamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAxNCwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLmphdmFjLmZpbGU7CgppbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKaW1wb3J0IGphdmEubmlvLmZpbGUuUGF0aDsKaW1wb3J0IGphdmEudXRpbC5MaXN0OwppbXBvcnQgamF2YS51dGlsLk1hcDsKaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkNvbmN1cnJlbnRIYXNoTWFwOwoKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5Db250ZXh0OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkNvbnRleHQuRmFjdG9yeTsKCi8qKgogKiBDYWNoaW5nIGltcGxlbWVudGF0aW9uIG9mIEZTSW5mby4KICoKICogPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93biByaXNrLgogKiBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogKiBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+CiAqLwpwdWJsaWMgY2xhc3MgQ2FjaGVGU0luZm8gZXh0ZW5kcyBGU0luZm8gewoKICAgIC8qKgogICAgICogUmVnaXN0ZXIgYSBDb250ZXh0LkZhY3RvcnkgdG8gY3JlYXRlIGEgQ2FjaGVGU0luZm8uCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBwcmVSZWdpc3RlcihDb250ZXh0IGNvbnRleHQpIHsKICAgICAgICBjb250ZXh0LnB1dChGU0luZm8uY2xhc3MsIChGYWN0b3J5PEZTSW5mbz4pYyAtPiB7CiAgICAgICAgICAgICAgICBGU0luZm8gaW5zdGFuY2UgPSBuZXcgQ2FjaGVGU0luZm8oKTsKICAgICAgICAgICAgICAgIGMucHV0KEZTSW5mby5jbGFzcywgaW5zdGFuY2UpOwogICAgICAgICAgICAgICAgcmV0dXJuIGluc3RhbmNlOwogICAgICAgICAgICB9KTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCBjbGVhckNhY2hlKCkgewogICAgICAgIGNhY2hlLmNsZWFyKCk7CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgUGF0aCBnZXRDYW5vbmljYWxGaWxlKFBhdGggZmlsZSkgewogICAgICAgIEVudHJ5IGUgPSBnZXRFbnRyeShmaWxlKTsKICAgICAgICByZXR1cm4gZS5jYW5vbmljYWxGaWxlOwogICAgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXhpc3RzKFBhdGggZmlsZSkgewogICAgICAgIEVudHJ5IGUgPSBnZXRFbnRyeShmaWxlKTsKICAgICAgICByZXR1cm4gZS5leGlzdHM7CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBpc0RpcmVjdG9yeShQYXRoIGZpbGUpIHsKICAgICAgICBFbnRyeSBlID0gZ2V0RW50cnkoZmlsZSk7CiAgICAgICAgcmV0dXJuIGUuaXNEaXJlY3Rvcnk7CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBpc0ZpbGUoUGF0aCBmaWxlKSB7CiAgICAgICAgRW50cnkgZSA9IGdldEVudHJ5KGZpbGUpOwogICAgICAgIHJldHVybiBlLmlzRmlsZTsKICAgIH0KCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBMaXN0PFBhdGg+IGdldEphckNsYXNzUGF0aChQYXRoIGZpbGUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgLy8gZG9uJ3QgYm90aGVyIHRvIGxvY2sgdGhlIGNhY2hlLCBiZWNhdXNlIGl0IGlzIHRocmVhZC1zYWZlLCBhbmQKICAgICAgICAvLyBiZWNhdXNlIHRoZSB3b3JzdCB0aGF0IGNhbiBoYXBwZW4gd291bGQgYmUgdG8gY3JlYXRlIHR3byBpZGVudGljYWwKICAgICAgICAvLyBqYXIgY2xhc3MgcGF0aHMgdG9nZXRoZXIgYW5kIGhhdmUgb25lIG92ZXJ3cml0ZSB0aGUgb3RoZXIuCiAgICAgICAgRW50cnkgZSA9IGdldEVudHJ5KGZpbGUpOwogICAgICAgIGlmIChlLmphckNsYXNzUGF0aCA9PSBudWxsKQogICAgICAgICAgICBlLmphckNsYXNzUGF0aCA9IHN1cGVyLmdldEphckNsYXNzUGF0aChmaWxlKTsKICAgICAgICByZXR1cm4gZS5qYXJDbGFzc1BhdGg7CiAgICB9CgogICAgcHJpdmF0ZSBFbnRyeSBnZXRFbnRyeShQYXRoIGZpbGUpIHsKICAgICAgICAvLyBkb24ndCBib3RoZXIgdG8gbG9jayB0aGUgY2FjaGUsIGJlY2F1c2UgaXQgaXMgdGhyZWFkLXNhZmUsIGFuZAogICAgICAgIC8vIGJlY2F1c2UgdGhlIHdvcnN0IHRoYXQgY2FuIGhhcHBlbiB3b3VsZCBiZSB0byBjcmVhdGUgdHdvIGlkZW50aWNhbAogICAgICAgIC8vIGVudHJpZXMgdG9nZXRoZXIgYW5kIGhhdmUgb25lIG92ZXJ3cml0ZSB0aGUgb3RoZXIuCiAgICAgICAgRW50cnkgZSA9IGNhY2hlLmdldChmaWxlKTsKICAgICAgICBpZiAoZSA9PSBudWxsKSB7CiAgICAgICAgICAgIGUgPSBuZXcgRW50cnkoKTsKICAgICAgICAgICAgZS5jYW5vbmljYWxGaWxlID0gc3VwZXIuZ2V0Q2Fub25pY2FsRmlsZShmaWxlKTsKICAgICAgICAgICAgZS5leGlzdHMgPSBzdXBlci5leGlzdHMoZmlsZSk7CiAgICAgICAgICAgIGUuaXNEaXJlY3RvcnkgPSBzdXBlci5pc0RpcmVjdG9yeShmaWxlKTsKICAgICAgICAgICAgZS5pc0ZpbGUgPSBzdXBlci5pc0ZpbGUoZmlsZSk7CiAgICAgICAgICAgIGNhY2hlLnB1dChmaWxlLCBlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGU7CiAgICB9CgogICAgLy8gY291bGQgYWxzbyBiZSBhIE1hcDxGaWxlLFNvZnRSZWZlcmVuY2U8RW50cnk+PiA/CiAgICBwcml2YXRlIGZpbmFsIE1hcDxQYXRoLEVudHJ5PiBjYWNoZSA9IG5ldyBDb25jdXJyZW50SGFzaE1hcDw+KCk7CgogICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgRW50cnkgewogICAgICAgIFBhdGggY2Fub25pY2FsRmlsZTsKICAgICAgICBib29sZWFuIGV4aXN0czsKICAgICAgICBib29sZWFuIGlzRmlsZTsKICAgICAgICBib29sZWFuIGlzRGlyZWN0b3J5OwogICAgICAgIExpc3Q8UGF0aD4gamFyQ2xhc3NQYXRoOwogICAgfQp9ClBLAwQKAAAIAAAGO6lKEDxc4HoZAAB6GQAAKgAAAGNvbS9zdW4vdG9vbHMvamF2YWMvZmlsZS9SZWxhdGl2ZVBhdGguamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwOCwgMjAxNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLmphdmFjLmZpbGU7CgppbXBvcnQgamF2YS5uaW8uZmlsZS5GaWxlU3lzdGVtOwppbXBvcnQgamF2YS5uaW8uZmlsZS5JbnZhbGlkUGF0aEV4Y2VwdGlvbjsKaW1wb3J0IGphdmEubmlvLmZpbGUuUGF0aDsKaW1wb3J0IGphdmEudXRpbC56aXAuWmlwRW50cnk7CmltcG9ydCBqYXZhLnV0aWwuemlwLlppcEZpbGU7CgppbXBvcnQgamF2YXgudG9vbHMuSmF2YUZpbGVPYmplY3Q7CgovKioKICogVXNlZCB0byByZXByZXNlbnQgYSBwbGF0Zm9ybS1uZXV0cmFsIHBhdGggd2l0aGluIGEgcGxhdGZvcm0tc3BlY2lmaWMKICogY29udGFpbmVyLCBzdWNoIGFzIGEgZGlyZWN0b3J5IG9yIHppcCBmaWxlLgogKiBJbnRlcm5hbGx5LCB0aGUgZmlsZSBzZXBhcmF0b3IgaXMgYWx3YXlzICcvJy4KICoKICogPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93biByaXNrLgogKiBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogKiBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+CiAqLwpwdWJsaWMgYWJzdHJhY3QgY2xhc3MgUmVsYXRpdmVQYXRoIGltcGxlbWVudHMgQ29tcGFyYWJsZTxSZWxhdGl2ZVBhdGg+IHsKICAgIC8qKgogICAgICogQHBhcmFtIHAgbXVzdCB1c2UgJy8nIGFzIGFuIGludGVybmFsIHNlcGFyYXRvcgogICAgICovCiAgICBwcm90ZWN0ZWQgUmVsYXRpdmVQYXRoKFN0cmluZyBwKSB7CiAgICAgICAgcGF0aCA9IHA7CiAgICB9CgogICAgcHVibGljIGFic3RyYWN0IFJlbGF0aXZlRGlyZWN0b3J5IGRpcm5hbWUoKTsKCiAgICBwdWJsaWMgYWJzdHJhY3QgU3RyaW5nIGJhc2VuYW1lKCk7CgogICAgcHVibGljIFBhdGggcmVzb2x2ZUFnYWluc3QoUGF0aCBkaXJlY3RvcnkpIHRocm93cyAvKnVuY2hlY2tlZCovIEludmFsaWRQYXRoRXhjZXB0aW9uIHsKICAgICAgICBTdHJpbmcgc2VwID0gZGlyZWN0b3J5LmdldEZpbGVTeXN0ZW0oKS5nZXRTZXBhcmF0b3IoKTsKICAgICAgICByZXR1cm4gZGlyZWN0b3J5LnJlc29sdmUocGF0aC5yZXBsYWNlKCIvIiwgc2VwKSk7CiAgICB9CgogICAgcHVibGljIFBhdGggcmVzb2x2ZUFnYWluc3QoRmlsZVN5c3RlbSBmcykgdGhyb3dzIC8qdW5jaGVja2VkKi8gSW52YWxpZFBhdGhFeGNlcHRpb24gewogICAgICAgIFN0cmluZyBzZXAgPSBmcy5nZXRTZXBhcmF0b3IoKTsKICAgICAgICBQYXRoIHJvb3QgPSBmcy5nZXRSb290RGlyZWN0b3JpZXMoKS5pdGVyYXRvcigpLm5leHQoKTsKICAgICAgICByZXR1cm4gcm9vdC5yZXNvbHZlKHBhdGgucmVwbGFjZSgiLyIsIHNlcCkpOwogICAgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIGludCBjb21wYXJlVG8oUmVsYXRpdmVQYXRoIG90aGVyKSB7CiAgICAgICAgcmV0dXJuIHBhdGguY29tcGFyZVRvKG90aGVyLnBhdGgpOwogICAgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvdGhlcikgewogICAgICAgIGlmICghKG90aGVyIGluc3RhbmNlb2YgUmVsYXRpdmVQYXRoKSkKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICByZXR1cm4gcGF0aC5lcXVhbHMoKChSZWxhdGl2ZVBhdGgpIG90aGVyKS5wYXRoKTsKICAgIH0KCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgICAgcmV0dXJuIHBhdGguaGFzaENvZGUoKTsKICAgIH0KCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CiAgICAgICAgcmV0dXJuICJSZWxQYXRoWyIgKyBwYXRoICsgIl0iOwogICAgfQoKICAgIHB1YmxpYyBTdHJpbmcgZ2V0UGF0aCgpIHsKICAgICAgICByZXR1cm4gcGF0aDsKICAgIH0KCiAgICBwcm90ZWN0ZWQgZmluYWwgU3RyaW5nIHBhdGg7CgogICAgLyoqCiAgICAgKiBVc2VkIHRvIHJlcHJlc2VudCBhIHBsYXRmb3JtLW5ldXRyYWwgc3ViZGlyZWN0b3J5IHdpdGhpbiBhIHBsYXRmb3JtLXNwZWNpZmljCiAgICAgKiBjb250YWluZXIsIHN1Y2ggYXMgYSBkaXJlY3Rvcnkgb3IgemlwIGZpbGUuCiAgICAgKiBJbnRlcm5hbGx5LCB0aGUgZmlsZSBzZXBhcmF0b3IgaXMgYWx3YXlzICcvJywgYW5kIGlmIHRoZSBwYXRoIGlzIG5vdCBlbXB0eSwKICAgICAqIGl0IGFsd2F5cyBlbmRzIGluIGEgJy8nIGFzIHdlbGwuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgUmVsYXRpdmVEaXJlY3RvcnkgZXh0ZW5kcyBSZWxhdGl2ZVBhdGggewoKICAgICAgICBzdGF0aWMgUmVsYXRpdmVEaXJlY3RvcnkgZm9yUGFja2FnZShDaGFyU2VxdWVuY2UgcGFja2FnZU5hbWUpIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyBSZWxhdGl2ZURpcmVjdG9yeShwYWNrYWdlTmFtZS50b1N0cmluZygpLnJlcGxhY2UoJy4nLCAnLycpKTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIEBwYXJhbSBwIG11c3QgdXNlICcvJyBhcyBhbiBpbnRlcm5hbCBzZXBhcmF0b3IKICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgUmVsYXRpdmVEaXJlY3RvcnkoU3RyaW5nIHApIHsKICAgICAgICAgICAgc3VwZXIocC5sZW5ndGgoKSA9PSAwIHx8IHAuZW5kc1dpdGgoIi8iKSA/IHAgOiBwICsgIi8iKTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIEBwYXJhbSBwIG11c3QgdXNlICcvJyBhcyBhbiBpbnRlcm5hbCBzZXBhcmF0b3IKICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgUmVsYXRpdmVEaXJlY3RvcnkoUmVsYXRpdmVEaXJlY3RvcnkgZCwgU3RyaW5nIHApIHsKICAgICAgICAgICAgdGhpcyhkLnBhdGggKyBwKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBSZWxhdGl2ZURpcmVjdG9yeSBkaXJuYW1lKCkgewogICAgICAgICAgICBpbnQgbCA9IHBhdGgubGVuZ3RoKCk7CiAgICAgICAgICAgIGlmIChsID09IDApCiAgICAgICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgICAgaW50IHNlcCA9IHBhdGgubGFzdEluZGV4T2YoJy8nLCBsIC0gMik7CiAgICAgICAgICAgIHJldHVybiBuZXcgUmVsYXRpdmVEaXJlY3RvcnkocGF0aC5zdWJzdHJpbmcoMCwgc2VwICsgMSkpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFN0cmluZyBiYXNlbmFtZSgpIHsKICAgICAgICAgICAgaW50IGwgPSBwYXRoLmxlbmd0aCgpOwogICAgICAgICAgICBpZiAobCA9PSAwKQogICAgICAgICAgICAgICAgcmV0dXJuIHBhdGg7CiAgICAgICAgICAgIGludCBzZXAgPSBwYXRoLmxhc3RJbmRleE9mKCcvJywgbCAtIDIpOwogICAgICAgICAgICByZXR1cm4gcGF0aC5zdWJzdHJpbmcoc2VwICsgMSwgbCAtIDEpOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogUmV0dXJuIHRydWUgaWYgdGhpcyBzdWJkaXJlY3RvcnkgImNvbnRhaW5zIiB0aGUgb3RoZXIgcGF0aC4KICAgICAgICAgKiBBIHN1YmRpcmVjdG9yeSBwYXRoIGRvZXMgbm90IGNvbnRhaW4gaXRzZWxmLgogICAgICAgICAqKi8KICAgICAgICBib29sZWFuIGNvbnRhaW5zKFJlbGF0aXZlUGF0aCBvdGhlcikgewogICAgICAgICAgICByZXR1cm4gb3RoZXIucGF0aC5sZW5ndGgoKSA+IHBhdGgubGVuZ3RoKCkgJiYgb3RoZXIucGF0aC5zdGFydHNXaXRoKHBhdGgpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKICAgICAgICAgICAgcmV0dXJuICJSZWxhdGl2ZURpcmVjdG9yeVsiICsgcGF0aCArICJdIjsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBVc2VkIHRvIHJlcHJlc2VudCBhIHBsYXRmb3JtLW5ldXRyYWwgZmlsZSB3aXRoaW4gYSBwbGF0Zm9ybS1zcGVjaWZpYwogICAgICogY29udGFpbmVyLCBzdWNoIGFzIGEgZGlyZWN0b3J5IG9yIHppcCBmaWxlLgogICAgICogSW50ZXJuYWxseSwgdGhlIGZpbGUgc2VwYXJhdG9yIGlzIGFsd2F5cyAnLycuIEl0IG5ldmVyIGVuZHMgaW4gJy8nLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIFJlbGF0aXZlRmlsZSBleHRlbmRzIFJlbGF0aXZlUGF0aCB7CiAgICAgICAgc3RhdGljIFJlbGF0aXZlRmlsZSBmb3JDbGFzcyhDaGFyU2VxdWVuY2UgY2xhc3NOYW1lLCBKYXZhRmlsZU9iamVjdC5LaW5kIGtpbmQpIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyBSZWxhdGl2ZUZpbGUoY2xhc3NOYW1lLnRvU3RyaW5nKCkucmVwbGFjZSgnLicsICcvJykgKyBraW5kLmV4dGVuc2lvbik7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgUmVsYXRpdmVGaWxlKFN0cmluZyBwKSB7CiAgICAgICAgICAgIHN1cGVyKHApOwogICAgICAgICAgICBpZiAocC5lbmRzV2l0aCgiLyIpKQogICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihwKTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIEBwYXJhbSBwIG11c3QgdXNlICcvJyBhcyBhbiBpbnRlcm5hbCBzZXBhcmF0b3IKICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgUmVsYXRpdmVGaWxlKFJlbGF0aXZlRGlyZWN0b3J5IGQsIFN0cmluZyBwKSB7CiAgICAgICAgICAgIHRoaXMoZC5wYXRoICsgcCk7CiAgICAgICAgfQoKICAgICAgICBSZWxhdGl2ZUZpbGUoUmVsYXRpdmVEaXJlY3RvcnkgZCwgUmVsYXRpdmVQYXRoIHApIHsKICAgICAgICAgICAgdGhpcyhkLCBwLnBhdGgpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFJlbGF0aXZlRGlyZWN0b3J5IGRpcm5hbWUoKSB7CiAgICAgICAgICAgIGludCBzZXAgPSBwYXRoLmxhc3RJbmRleE9mKCcvJyk7CiAgICAgICAgICAgIHJldHVybiBuZXcgUmVsYXRpdmVEaXJlY3RvcnkocGF0aC5zdWJzdHJpbmcoMCwgc2VwICsgMSkpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFN0cmluZyBiYXNlbmFtZSgpIHsKICAgICAgICAgICAgaW50IHNlcCA9IHBhdGgubGFzdEluZGV4T2YoJy8nKTsKICAgICAgICAgICAgcmV0dXJuIHBhdGguc3Vic3RyaW5nKHNlcCArIDEpOwogICAgICAgIH0KCiAgICAgICAgWmlwRW50cnkgZ2V0WmlwRW50cnkoWmlwRmlsZSB6aXApIHsKICAgICAgICAgICAgcmV0dXJuIHppcC5nZXRFbnRyeShwYXRoKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CiAgICAgICAgICAgIHJldHVybiAiUmVsYXRpdmVGaWxlWyIgKyBwYXRoICsgIl0iOwogICAgICAgIH0KCiAgICB9Cgp9ClBLAwQKAAAIAADSfU1KAAAAAAAAAAAAAAAAHQAAAGNvbS9zdW4vdG9vbHMvamF2YWMvc2VydmljZXMvUEsDBAoAAAgAANJ9TUrRjTxVHQAAAB0AAAA5AAAAY29tL3N1bi90b29scy9qYXZhYy9zZXJ2aWNlcy9qYXZheC50b29scy5KYXZhQ29tcGlsZXJUb29sY29tLnN1bi50b29scy5qYXZhYy5hcGkuVG9vbApQSwMECgAACAAABjupSgAAAAAAAAAAAAAAABgAAABjb20vc3VuL3Rvb2xzL2phdmFjL2FwaS9QSwMECgAACAAA0n1NSoTrIVinCgAApwoAACgAAABjb20vc3VuL3Rvb2xzL2phdmFjL2FwaS9Gb3JtYXR0YWJsZS5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDA4LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuamF2YWMuYXBpOwoKaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CgovKioKICogVGhpcyBpbnRlcmZhY2UgbXVzdCBiZSBpbXBsZW1lbnRlZCBieSBhbnkgamF2YWMgY2xhc3MgdGhhdCBoYXMgbm9uLXRyaXZpYWwKICogZm9ybWF0dGluZyBuZWVkcyAoZS5nLiB3aGVyZSB0b1N0cmluZygpIGRvZXMgbm90IGFwcGx5IGJlY2F1c2Ugb2YgbG9jYWxpemF0aW9uKS4KICoKICogPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93biByaXNrLgogKiBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogKiBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+CiAqCiAqIEBhdXRob3IgTWF1cml6aW8gQ2ltYWRhbW9yZQogKi8KcHVibGljIGludGVyZmFjZSBGb3JtYXR0YWJsZSB7CgogICAgLyoqCiAgICAgKiBVc2VkIHRvIG9idGFpbiBhIGxvY2FsaXplZCBTdHJpbmcgcmVwcmVzZW50aW5nIHRoZSBvYmplY3QgYWNjb3JkaW5nbHkKICAgICAqIHRvIGEgZ2l2ZW4gbG9jYWxlCiAgICAgKgogICAgICogQHBhcmFtIGxvY2FsZSBsb2NhbGUgaW4gd2hpY2ggdGhlIG9iamVjdCdzIHJlcHJlc2VudGF0aW9uIGlzIHRvIGJlIHJlbmRlcmVkCiAgICAgKiBAcGFyYW0gbWVzc2FnZXMgbWVzc2FnZXMgb2JqZWN0IHVzZWQgZm9yIGxvY2FsaXphdGlvbgogICAgICogQHJldHVybiBhIGxvY2FsZS1kZXBlbmRlbnQgc3RyaW5nIHJlcHJlc2VudGluZyB0aGUgb2JqZWN0CiAgICAgKi8KICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoTG9jYWxlIGxvY2FsZSwgTWVzc2FnZXMgbWVzc2FnZXMpOwogICAgLyoqCiAgICAgKiBSZXRyaWV2ZSBhIHByZXR0eSBuYW1lIG9mIHRoaXMgb2JqZWN0J3Mga2luZAogICAgICogQHJldHVybiBhIHN0cmluZyByZXByZXNlbnRpbmcgdGhlIG9iamVjdCdzIGtpbmQKICAgICAqLwogICAgU3RyaW5nIGdldEtpbmQoKTsKCiAgICBzdGF0aWMgY2xhc3MgTG9jYWxpemVkU3RyaW5nIGltcGxlbWVudHMgRm9ybWF0dGFibGUgewogICAgICAgIFN0cmluZyBrZXk7CgogICAgICAgIHB1YmxpYyBMb2NhbGl6ZWRTdHJpbmcoU3RyaW5nIGtleSkgewogICAgICAgICAgICB0aGlzLmtleSA9IGtleTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoamF2YS51dGlsLkxvY2FsZSBsLCBNZXNzYWdlcyBtZXNzYWdlcykgewogICAgICAgICAgICByZXR1cm4gbWVzc2FnZXMuZ2V0TG9jYWxpemVkU3RyaW5nKGwsIGtleSk7CiAgICAgICAgfQogICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0S2luZCgpIHsKICAgICAgICAgICAgcmV0dXJuICJMb2NhbGl6ZWRTdHJpbmciOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKICAgICAgICAgICAgcmV0dXJuIGtleTsKICAgICAgICB9CiAgICB9Cn0KUEsDBAoAAAgAANJ9TUoSL7SEZB0AAGQdAAA0AAAAY29tL3N1bi90b29scy9qYXZhYy9hcGkvV3JhcHBpbmdKYXZhRmlsZU1hbmFnZXIuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNiwgMjAxMiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLmphdmFjLmFwaTsKCmltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwppbXBvcnQgamF2YS5uZXQuVVJJOwppbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKaW1wb3J0IGphdmEudXRpbC5MaXN0OwppbXBvcnQgamF2YS51dGlsLlNldDsKCmltcG9ydCBqYXZheC50b29scy4qOwppbXBvcnQgamF2YXgudG9vbHMuSmF2YUZpbGVPYmplY3QuS2luZDsKCmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuRGVmaW5lZEJ5OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkRlZmluZWRCeS5BcGk7CgovKioKICogV3JhcHMgYWxsIGNhbGxzIHRvIGEgZ2l2ZW4gZmlsZSBtYW5hZ2VyLiAgU3ViY2xhc3NlcyBvZiB0aGlzIGNsYXNzCiAqIG1pZ2h0IG92ZXJyaWRlIHNvbWUgb2YgdGhlc2UgbWV0aG9kcyBhbmQgbWlnaHQgYWxzbyBwcm92aWRlCiAqIGFkZGl0aW9uYWwgZmllbGRzIGFuZCBtZXRob2RzLgogKgogKiA8cD5UaGlzIGNsYXNzIG1pZ2h0IGJlIG1vdmVkIHRvIHtAbGluayBqYXZheC50b29sc30gaW4gYSBmdXR1cmUKICogcmVsZWFzZS4KICoKICogPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93bgogKiByaXNrLiAgVGhpcyBjb2RlIGFuZCBpdHMgaW50ZXJuYWwgaW50ZXJmYWNlcyBhcmUgc3ViamVjdCB0byBjaGFuZ2UKICogb3IgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPjwvcD4KICoKICogQHBhcmFtIDxNPiB0aGUgdHlwZSBvZiBmaWxlIG1hbmFnZXIgd3JhcHBlZCB0byBieSB0aGlzIG9iamVjdAogKgogKiBAYXV0aG9yIFBldGVyIHZvbiBkZXIgQWgmZWFjdXRlOwogKiBAc2luY2UgMS42CiAqLwpwdWJsaWMgY2xhc3MgV3JhcHBpbmdKYXZhRmlsZU1hbmFnZXI8TSBleHRlbmRzIEphdmFGaWxlTWFuYWdlcj4gZXh0ZW5kcyBGb3J3YXJkaW5nSmF2YUZpbGVNYW5hZ2VyPE0+IHsKCiAgICAvKioKICAgICAqIENyZWF0ZXMgYSBuZXcgaW5zdGFuY2Ugb2YgV3JhcHBpbmdKYXZhRmlsZU1hbmFnZXIuCiAgICAgKiBAcGFyYW0gZmlsZU1hbmFnZXIgZmlsZSBtYW5hZ2VyIHRvIGJlIHdyYXBwZWQKICAgICAqLwogICAgcHJvdGVjdGVkIFdyYXBwaW5nSmF2YUZpbGVNYW5hZ2VyKE0gZmlsZU1hbmFnZXIpIHsKICAgICAgICBzdXBlcihmaWxlTWFuYWdlcik7CiAgICB9CgogICAgLyoqCiAgICAgKiBUaGlzIGltcGxlbWVudGF0aW9uIHJldHVybnMgdGhlIGdpdmVuIGZpbGUgb2JqZWN0LiAgU3ViY2xhc3NlcwogICAgICogbWF5IG92ZXJyaWRlIHRoaXMgYmVoYXZpb3IuCiAgICAgKgogICAgICogQHBhcmFtIGZpbGVPYmplY3QgYSBmaWxlIG9iamVjdAogICAgICovCiAgICBwcm90ZWN0ZWQgRmlsZU9iamVjdCB3cmFwKEZpbGVPYmplY3QgZmlsZU9iamVjdCkgewogICAgICAgIHJldHVybiBmaWxlT2JqZWN0OwogICAgfQoKICAgIC8qKgogICAgICogVGhpcyBpbXBsZW1lbnRhdGlvbiBmb3J3YXJkcyB0byB7QGxpbmsgI3dyYXAoRmlsZU9iamVjdCl9LgogICAgICogU3ViY2xhc3NlcyBtYXkgb3ZlcnJpZGUgdGhpcyBiZWhhdmlvci4KICAgICAqCiAgICAgKiBAcGFyYW0gZmlsZU9iamVjdCBhIGZpbGUgb2JqZWN0CiAgICAgKiBAdGhyb3dzIENsYXNzQ2FzdEV4Y2VwdGlvbiBpZiB0aGUgZmlsZSBvYmplY3QgcmV0dXJuZWQgZnJvbSB0aGUKICAgICAqIGZvcndhcmRlZCBjYWxsIGlzIG5vdCBhIHN1YnR5cGUgb2Yge0BsaW5rcGxhaW4gSmF2YUZpbGVPYmplY3R9CiAgICAgKi8KICAgIHByb3RlY3RlZCBKYXZhRmlsZU9iamVjdCB3cmFwKEphdmFGaWxlT2JqZWN0IGZpbGVPYmplY3QpIHsKICAgICAgICByZXR1cm4gKEphdmFGaWxlT2JqZWN0KXdyYXAoKEZpbGVPYmplY3QpZmlsZU9iamVjdCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBUaGlzIGltcGxlbWVudGF0aW9uIHJldHVybnMgdGhlIGdpdmVuIGZpbGUgb2JqZWN0LiAgU3ViY2xhc3NlcwogICAgICogbWF5IG92ZXJyaWRlIHRoaXMgYmVoYXZpb3IuCiAgICAgKgogICAgICogQHBhcmFtIGZpbGVPYmplY3QgYSBmaWxlIG9iamVjdAogICAgICovCiAgICBwcm90ZWN0ZWQgRmlsZU9iamVjdCB1bndyYXAoRmlsZU9iamVjdCBmaWxlT2JqZWN0KSB7CiAgICAgICAgcmV0dXJuIGZpbGVPYmplY3Q7CiAgICB9CgogICAgLyoqCiAgICAgKiBUaGlzIGltcGxlbWVudGF0aW9uIGZvcndhcmRzIHRvIHtAbGluayAjdW53cmFwKEZpbGVPYmplY3QpfS4KICAgICAqIFN1YmNsYXNzZXMgbWF5IG92ZXJyaWRlIHRoaXMgYmVoYXZpb3IuCiAgICAgKgogICAgICogQHBhcmFtIGZpbGVPYmplY3QgYSBmaWxlIG9iamVjdAogICAgICogQHRocm93cyBDbGFzc0Nhc3RFeGNlcHRpb24gaWYgdGhlIGZpbGUgb2JqZWN0IHJldHVybmVkIGZyb20gdGhlCiAgICAgKiBmb3J3YXJkZWQgY2FsbCBpcyBub3QgYSBzdWJ0eXBlIG9mIHtAbGlua3BsYWluIEphdmFGaWxlT2JqZWN0fQogICAgICovCiAgICBwcm90ZWN0ZWQgSmF2YUZpbGVPYmplY3QgdW53cmFwKEphdmFGaWxlT2JqZWN0IGZpbGVPYmplY3QpIHsKICAgICAgICByZXR1cm4gKEphdmFGaWxlT2JqZWN0KXVud3JhcCgoRmlsZU9iamVjdClmaWxlT2JqZWN0KTsKICAgIH0KCiAgICAvKioKICAgICAqIFRoaXMgaW1wbGVtZW50YXRpb24gbWFwcyB0aGUgZ2l2ZW4gbGlzdCBvZiBmaWxlIG9iamVjdHMgYnkKICAgICAqIGNhbGxpbmcgd3JhcCBvbiBlYWNoLiAgU3ViY2xhc3NlcyBtYXkgb3ZlcnJpZGUgdGhpcyBiZWhhdmlvci4KICAgICAqCiAgICAgKiBAcGFyYW0gZmlsZU9iamVjdHMgYSBsaXN0IG9mIGZpbGUgb2JqZWN0cwogICAgICogQHJldHVybiB0aGUgbWFwcGluZwogICAgICovCiAgICBwcm90ZWN0ZWQgSXRlcmFibGU8SmF2YUZpbGVPYmplY3Q+IHdyYXAoSXRlcmFibGU8SmF2YUZpbGVPYmplY3Q+IGZpbGVPYmplY3RzKSB7CiAgICAgICAgTGlzdDxKYXZhRmlsZU9iamVjdD4gbWFwcGVkID0gbmV3IEFycmF5TGlzdDw+KCk7CiAgICAgICAgZm9yIChKYXZhRmlsZU9iamVjdCBmaWxlT2JqZWN0IDogZmlsZU9iamVjdHMpCiAgICAgICAgICAgIG1hcHBlZC5hZGQod3JhcChmaWxlT2JqZWN0KSk7CiAgICAgICAgcmV0dXJuIENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QobWFwcGVkKTsKICAgIH0KCiAgICAvKioKICAgICAqIFRoaXMgaW1wbGVtZW50YXRpb24gcmV0dXJucyB0aGUgZ2l2ZW4gVVJJLiAgU3ViY2xhc3NlcyBtYXkKICAgICAqIG92ZXJyaWRlIHRoaXMgYmVoYXZpb3IuCiAgICAgKgogICAgICogQHBhcmFtIHVyaSBhIFVSSQogICAgICovCiAgICBwcm90ZWN0ZWQgVVJJIHVud3JhcChVUkkgdXJpKSB7CiAgICAgICAgcmV0dXJuIHVyaTsKICAgIH0KCiAgICAvKioKICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICBwdWJsaWMgSXRlcmFibGU8SmF2YUZpbGVPYmplY3Q+IGxpc3QoTG9jYXRpb24gbG9jYXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHBhY2thZ2VOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNldDxLaW5kPiBraW5kcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIHJlY3Vyc2UpCiAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uCiAgICB7CiAgICAgICAgcmV0dXJuIHdyYXAoc3VwZXIubGlzdChsb2NhdGlvbiwgcGFja2FnZU5hbWUsIGtpbmRzLCByZWN1cnNlKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSKQogICAgcHVibGljIFN0cmluZyBpbmZlckJpbmFyeU5hbWUoTG9jYXRpb24gbG9jYXRpb24sIEphdmFGaWxlT2JqZWN0IGZpbGUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuaW5mZXJCaW5hcnlOYW1lKGxvY2F0aW9uLCB1bndyYXAoZmlsZSkpOwogICAgfQoKICAgIC8qKgogICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24ge0Bpbmhlcml0RG9jfQogICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CiAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSKQogICAgcHVibGljIEphdmFGaWxlT2JqZWN0IGdldEphdmFGaWxlRm9ySW5wdXQoTG9jYXRpb24gbG9jYXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgY2xhc3NOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgS2luZCBraW5kKQogICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbgogICAgewogICAgICAgIHJldHVybiB3cmFwKHN1cGVyLmdldEphdmFGaWxlRm9ySW5wdXQobG9jYXRpb24sIGNsYXNzTmFtZSwga2luZCkpOwogICAgfQoKICAgIC8qKgogICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24ge0Bpbmhlcml0RG9jfQogICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CiAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSKQogICAgcHVibGljIEphdmFGaWxlT2JqZWN0IGdldEphdmFGaWxlRm9yT3V0cHV0KExvY2F0aW9uIGxvY2F0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBjbGFzc05hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgS2luZCBraW5kLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZpbGVPYmplY3Qgc2libGluZykKICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24KICAgIHsKICAgICAgICByZXR1cm4gd3JhcChzdXBlci5nZXRKYXZhRmlsZUZvck91dHB1dChsb2NhdGlvbiwgY2xhc3NOYW1lLCBraW5kLCB1bndyYXAoc2libGluZykpKTsKICAgIH0KCiAgICAvKioKICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHtAaW5oZXJpdERvY30KICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICBwdWJsaWMgRmlsZU9iamVjdCBnZXRGaWxlRm9ySW5wdXQoTG9jYXRpb24gbG9jYXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHBhY2thZ2VOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyByZWxhdGl2ZU5hbWUpCiAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uCiAgICB7CiAgICAgICAgcmV0dXJuIHdyYXAoc3VwZXIuZ2V0RmlsZUZvcklucHV0KGxvY2F0aW9uLCBwYWNrYWdlTmFtZSwgcmVsYXRpdmVOYW1lKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CiAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSKQogICAgcHVibGljIEZpbGVPYmplY3QgZ2V0RmlsZUZvck91dHB1dChMb2NhdGlvbiBsb2NhdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHBhY2thZ2VOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcmVsYXRpdmVOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGaWxlT2JqZWN0IHNpYmxpbmcpCiAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uCiAgICB7CiAgICAgICAgcmV0dXJuIHdyYXAoc3VwZXIuZ2V0RmlsZUZvck91dHB1dChsb2NhdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhY2thZ2VOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVsYXRpdmVOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW53cmFwKHNpYmxpbmcpKSk7CiAgICB9Cgp9ClBLAwQKAAAIAAAGO6lKC8K57pBPAACQTwAAKgAAAGNvbS9zdW4vdG9vbHMvamF2YWMvYXBpL0phdmFjVGFza0ltcGwuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAxNywgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLmphdmFjLmFwaTsKCmltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwppbXBvcnQgamF2YS5uaW8uQ2hhckJ1ZmZlcjsKaW1wb3J0IGphdmEudXRpbC4qOwppbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuQ2FsbGFibGU7CmltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5hdG9taWMuQXRvbWljQm9vbGVhbjsKCmltcG9ydCBqYXZheC5hbm5vdGF0aW9uLnByb2Nlc3NpbmcuUHJvY2Vzc29yOwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5lbGVtZW50LkVsZW1lbnQ7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuVHlwZUVsZW1lbnQ7CmltcG9ydCBqYXZheC50b29scy4qOwoKaW1wb3J0IGNvbS5zdW4uc291cmNlLnRyZWUuKjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS4qOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlN5bWJvbC5DbGFzc1N5bWJvbDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29tcC4qOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5maWxlLkJhc2VGaWxlTWFuYWdlcjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMubWFpbi4qOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5tYWluLkphdmFDb21waWxlcjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMucGFyc2VyLlBhcnNlcjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMucGFyc2VyLlBhcnNlckZhY3Rvcnk7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnByb2Nlc3NpbmcuQW5ub3RhdGlvblByb2Nlc3NpbmdFcnJvcjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS4qOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkpDVHJlZS5KQ0NsYXNzRGVjbDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5KQ1RyZWUuSkNDb21waWxhdGlvblVuaXQ7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuSkNUcmVlLkpDTW9kdWxlRGVjbDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5KQ1RyZWUuVGFnOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLio7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuRGVmaW5lZEJ5LkFwaTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5MaXN0OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkxvZy5QcmVmaXhLaW5kOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkxvZy5Xcml0ZXJLaW5kOwoKLyoqCiAqIFByb3ZpZGVzIGFjY2VzcyB0byBmdW5jdGlvbmFsaXR5IHNwZWNpZmljIHRvIHRoZSBKREsgSmF2YSBDb21waWxlciwgamF2YWMuCiAqCiAqIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24KICogcmlzay4gIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlCiAqIG9yIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj48L3A+CiAqCiAqIEBhdXRob3IgUGV0ZXIgdm9uIGRlciBBaCZlYWN1dGU7CiAqIEBhdXRob3IgSm9uYXRoYW4gR2liYm9ucwogKi8KcHVibGljIGNsYXNzIEphdmFjVGFza0ltcGwgZXh0ZW5kcyBCYXNpY0phdmFjVGFzayB7CiAgICBwcml2YXRlIGZpbmFsIEFyZ3VtZW50cyBhcmdzOwogICAgcHJpdmF0ZSBKYXZhQ29tcGlsZXIgY29tcGlsZXI7CiAgICBwcml2YXRlIEphdmFGaWxlTWFuYWdlciBmaWxlTWFuYWdlcjsKICAgIHByaXZhdGUgTG9jYWxlIGxvY2FsZTsKICAgIHByaXZhdGUgTWFwPEphdmFGaWxlT2JqZWN0LCBKQ0NvbXBpbGF0aW9uVW5pdD4gbm90WWV0RW50ZXJlZDsKICAgIHByaXZhdGUgTGlzdEJ1ZmZlcjxFbnY8QXR0ckNvbnRleHQ+PiBnZW5MaXN0OwogICAgcHJpdmF0ZSBmaW5hbCBBdG9taWNCb29sZWFuIHVzZWQgPSBuZXcgQXRvbWljQm9vbGVhbigpOwogICAgcHJpdmF0ZSBJdGVyYWJsZTw/IGV4dGVuZHMgUHJvY2Vzc29yPiBwcm9jZXNzb3JzOwogICAgcHJpdmF0ZSBMaXN0QnVmZmVyPFN0cmluZz4gYWRkTW9kdWxlcyA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKCiAgICBwcm90ZWN0ZWQgSmF2YWNUYXNrSW1wbChDb250ZXh0IGNvbnRleHQpIHsKICAgICAgICBzdXBlcihjb250ZXh0LCB0cnVlKTsKICAgICAgICBhcmdzID0gQXJndW1lbnRzLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIGZpbGVNYW5hZ2VyID0gY29udGV4dC5nZXQoSmF2YUZpbGVNYW5hZ2VyLmNsYXNzKTsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICBwdWJsaWMgQm9vbGVhbiBjYWxsKCkgewogICAgICAgIHJldHVybiBkb0NhbGwoKS5pc09LKCk7CiAgICB9CgogICAgLyogSW50ZXJuYWwgdmVyc2lvbiBvZiBjYWxsIGV4cG9zaW5nIE1haW4uUmVzdWx0LiAqLwogICAgcHVibGljIE1haW4uUmVzdWx0IGRvQ2FsbCgpIHsKICAgICAgICB0cnkgewogICAgICAgICAgICByZXR1cm4gaGFuZGxlRXhjZXB0aW9ucygoKSAtPiB7CiAgICAgICAgICAgICAgICBwcmVwYXJlQ29tcGlsZXIoZmFsc2UpOwogICAgICAgICAgICAgICAgaWYgKGNvbXBpbGVyLmVycm9yQ291bnQoKSA+IDApCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE1haW4uUmVzdWx0LkVSUk9SOwogICAgICAgICAgICAgICAgY29tcGlsZXIuY29tcGlsZShhcmdzLmdldEZpbGVPYmplY3RzKCksIGFyZ3MuZ2V0Q2xhc3NOYW1lcygpLCBwcm9jZXNzb3JzLCBhZGRNb2R1bGVzKTsKICAgICAgICAgICAgICAgIHJldHVybiAoY29tcGlsZXIuZXJyb3JDb3VudCgpID4gMCkgPyBNYWluLlJlc3VsdC5FUlJPUiA6IE1haW4uUmVzdWx0Lk9LOyAvLyBGSVhNRT8KICAgICAgICAgICAgfSwgTWFpbi5SZXN1bHQuU1lTRVJSLCBNYWluLlJlc3VsdC5BQk5PUk1BTCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIGNsZWFudXAoKTsKICAgICAgICAgICAgfSBjYXRjaCAoQ2xpZW50Q29kZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihlLmdldENhdXNlKCkpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgIHB1YmxpYyB2b2lkIGFkZE1vZHVsZXMoSXRlcmFibGU8U3RyaW5nPiBtb2R1bGVOYW1lcykgewogICAgICAgIE9iamVjdHMucmVxdWlyZU5vbk51bGwobW9kdWxlTmFtZXMpOwogICAgICAgIC8vIG5vdCBtdC1zYWZlCiAgICAgICAgaWYgKHVzZWQuZ2V0KCkpCiAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oKTsKICAgICAgICBmb3IgKFN0cmluZyBtIDogbW9kdWxlTmFtZXMpIHsKICAgICAgICAgICAgT2JqZWN0cy5yZXF1aXJlTm9uTnVsbChtKTsKICAgICAgICAgICAgYWRkTW9kdWxlcy5hZGQobSk7CiAgICAgICAgfQogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgIHB1YmxpYyB2b2lkIHNldFByb2Nlc3NvcnMoSXRlcmFibGU8PyBleHRlbmRzIFByb2Nlc3Nvcj4gcHJvY2Vzc29ycykgewogICAgICAgIE9iamVjdHMucmVxdWlyZU5vbk51bGwocHJvY2Vzc29ycyk7CiAgICAgICAgLy8gbm90IG10LXNhZmUKICAgICAgICBpZiAodXNlZC5nZXQoKSkKICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigpOwogICAgICAgIHRoaXMucHJvY2Vzc29ycyA9IHByb2Nlc3NvcnM7CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSKQogICAgcHVibGljIHZvaWQgc2V0TG9jYWxlKExvY2FsZSBsb2NhbGUpIHsKICAgICAgICBpZiAodXNlZC5nZXQoKSkKICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigpOwogICAgICAgIHRoaXMubG9jYWxlID0gbG9jYWxlOwogICAgfQoKICAgIHByaXZhdGUgPFQ+IFQgaGFuZGxlRXhjZXB0aW9ucyhDYWxsYWJsZTxUPiBjLCBUIHN5c0Vycm9yUmVzdWx0LCBUIGFibm9ybWFsRXJyb3JSZXN1bHQpIHsKICAgICAgICB0cnkgewogICAgICAgICAgICByZXR1cm4gYy5jYWxsKCk7CiAgICAgICAgfSBjYXRjaCAoRmF0YWxFcnJvciBleCkgewogICAgICAgICAgICBMb2cgbG9nID0gTG9nLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgICAgICBPcHRpb25zIG9wdGlvbnMgPSBPcHRpb25zLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgICAgICBsb2cucHJpbnRSYXdMaW5lcyhleC5nZXRNZXNzYWdlKCkpOwogICAgICAgICAgICBpZiAoZXguZ2V0Q2F1c2UoKSAhPSBudWxsICYmIG9wdGlvbnMuaXNTZXQoImRldiIpKSB7CiAgICAgICAgICAgICAgICBleC5nZXRDYXVzZSgpLnByaW50U3RhY2tUcmFjZShsb2cuZ2V0V3JpdGVyKFdyaXRlcktpbmQuTk9USUNFKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHN5c0Vycm9yUmVzdWx0OwogICAgICAgIH0gY2F0Y2ggKEFubm90YXRpb25Qcm9jZXNzaW5nRXJyb3IgfCBDbGllbnRDb2RlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgLy8gQW5ub3RhdGlvblByb2Nlc3NpbmdFcnJvciBpcyB0aHJvd24gZnJvbSBKYXZhY1Byb2Nlc3NpbmdFbnZpcm9ubWVudCwKICAgICAgICAgICAgLy8gdG8gZm9yd2FyZCBlcnJvcnMgdGhyb3duIGZyb20gYW4gYW5ub3RhdGlvbiBwcm9jZXNzb3IKICAgICAgICAgICAgLy8gQ2xpZW50Q29kZUV4Y2VwdGlvbiBpcyB0aHJvd24gZnJvbSBDbGllbnRDb2RlV3JhcHBlciwKICAgICAgICAgICAgLy8gdG8gZm9yd2FyZCBlcnJvcnMgdGhyb3duIGZyb20gdXNlci1zdXBwbGllZCBjb2RlIGZvciBDb21waWxlciBBUEkKICAgICAgICAgICAgLy8gYXMgc3BlY2lmaWVkIGJ5IGphdmF4LnRvb2xzLkphdmFDb21waWxlciNnZXRUYXNrCiAgICAgICAgICAgIC8vIGFuZCBqYXZheC50b29scy5KYXZhQ29tcGlsZXIuQ29tcGlsYXRpb25UYXNrI2NhbGwKICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oZS5nZXRDYXVzZSgpKTsKICAgICAgICB9IGNhdGNoIChQcm9wYWdhdGVkRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS5nZXRDYXVzZSgpOwogICAgICAgIH0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGU7CiAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIHwgRXJyb3IgZXgpIHsKICAgICAgICAgICAgLy8gTmFzdHkuICBJZiB3ZSd2ZSBhbHJlYWR5IHJlcG9ydGVkIGFuIGVycm9yLCBjb21wZW5zYXRlCiAgICAgICAgICAgIC8vIGZvciBidWdneSBjb21waWxlciBlcnJvciByZWNvdmVyeSBieSBzd2FsbG93aW5nIHRocm93bgogICAgICAgICAgICAvLyBleGNlcHRpb25zLgogICAgICAgICAgICBpZiAoY29tcGlsZXIgPT0gbnVsbCB8fCBjb21waWxlci5lcnJvckNvdW50KCkgPT0gMAogICAgICAgICAgICAgICAgICAgIHx8IE9wdGlvbnMuaW5zdGFuY2UoY29udGV4dCkuaXNTZXQoImRldiIpKSB7CiAgICAgICAgICAgICAgICBMb2cgbG9nID0gTG9nLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgICAgICAgICAgbG9nLnByaW50TGluZXMoUHJlZml4S2luZC5KQVZBQywgIm1zZy5idWciLCBKYXZhQ29tcGlsZXIudmVyc2lvbigpKTsKICAgICAgICAgICAgICAgIGV4LnByaW50U3RhY2tUcmFjZShsb2cuZ2V0V3JpdGVyKFdyaXRlcktpbmQuTk9USUNFKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGFibm9ybWFsRXJyb3JSZXN1bHQ7CiAgICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgdm9pZCBwcmVwYXJlQ29tcGlsZXIoYm9vbGVhbiBmb3JQYXJzZSkgewogICAgICAgIGlmICh1c2VkLmdldEFuZFNldCh0cnVlKSkgewogICAgICAgICAgICBpZiAoY29tcGlsZXIgPT0gbnVsbCkKICAgICAgICAgICAgICAgIHRocm93IG5ldyBQcm9wYWdhdGVkRXhjZXB0aW9uKG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oKSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgYXJncy52YWxpZGF0ZSgpOwoKICAgICAgICAgICAgLy9pbml0aWFsaXplIGNvbXBpbGVyJ3MgZGVmYXVsdCBsb2NhbGUKICAgICAgICAgICAgY29udGV4dC5wdXQoTG9jYWxlLmNsYXNzLCBsb2NhbGUpOwoKICAgICAgICAgICAgLy8gaGFjawogICAgICAgICAgICBKYXZhY01lc3NhZ2VzIG1lc3NhZ2VzID0gY29udGV4dC5nZXQoSmF2YWNNZXNzYWdlcy5tZXNzYWdlc0tleSk7CiAgICAgICAgICAgIGlmIChtZXNzYWdlcyAhPSBudWxsICYmICFtZXNzYWdlcy5nZXRDdXJyZW50TG9jYWxlKCkuZXF1YWxzKGxvY2FsZSkpCiAgICAgICAgICAgICAgICBtZXNzYWdlcy5zZXRDdXJyZW50TG9jYWxlKGxvY2FsZSk7CgogICAgICAgICAgICBpbml0UGx1Z2lucyhhcmdzLmdldFBsdWdpbk9wdHMoKSk7CiAgICAgICAgICAgIGluaXREb2NMaW50KGFyZ3MuZ2V0RG9jTGludE9wdHMoKSk7CgogICAgICAgICAgICAvLyBpbml0IEphdmFDb21waWxlciBhbmQgcXVldWVzCiAgICAgICAgICAgIGNvbXBpbGVyID0gSmF2YUNvbXBpbGVyLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgICAgICBjb21waWxlci5rZWVwQ29tbWVudHMgPSB0cnVlOwogICAgICAgICAgICBjb21waWxlci5nZW5FbmRQb3MgPSB0cnVlOwogICAgICAgICAgICBub3RZZXRFbnRlcmVkID0gbmV3IEhhc2hNYXA8PigpOwogICAgICAgICAgICBpZiAoZm9yUGFyc2UpIHsKICAgICAgICAgICAgICAgIGNvbXBpbGVyLmluaXRQcm9jZXNzQW5ub3RhdGlvbnMocHJvY2Vzc29ycywgYXJncy5nZXRGaWxlT2JqZWN0cygpLCBhcmdzLmdldENsYXNzTmFtZXMoKSk7CiAgICAgICAgICAgICAgICBmb3IgKEphdmFGaWxlT2JqZWN0IGZpbGU6IGFyZ3MuZ2V0RmlsZU9iamVjdHMoKSkKICAgICAgICAgICAgICAgICAgICBub3RZZXRFbnRlcmVkLnB1dChmaWxlLCBudWxsKTsKICAgICAgICAgICAgICAgIGdlbkxpc3QgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgPFQ+IFN0cmluZyB0b1N0cmluZyhJdGVyYWJsZTxUPiBpdGVtcywgU3RyaW5nIHNlcCkgewogICAgICAgIFN0cmluZyBjdXJyU2VwID0gIiI7CiAgICAgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CiAgICAgICAgZm9yIChUIGl0ZW06IGl0ZW1zKSB7CiAgICAgICAgICAgIHNiLmFwcGVuZChjdXJyU2VwKTsKICAgICAgICAgICAgc2IuYXBwZW5kKGl0ZW0udG9TdHJpbmcoKSk7CiAgICAgICAgICAgIGN1cnJTZXAgPSBzZXA7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzYi50b1N0cmluZygpOwogICAgfQoKICAgIHZvaWQgY2xlYW51cCgpIHsKICAgICAgICBpZiAoY29tcGlsZXIgIT0gbnVsbCkKICAgICAgICAgICAgY29tcGlsZXIuY2xvc2UoKTsKICAgICAgICBpZiAoZmlsZU1hbmFnZXIgaW5zdGFuY2VvZiBCYXNlRmlsZU1hbmFnZXIgJiYgKChCYXNlRmlsZU1hbmFnZXIpIGZpbGVNYW5hZ2VyKS5hdXRvQ2xvc2UpIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIGZpbGVNYW5hZ2VyLmNsb3NlKCk7CiAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGlnbm9yZSkgewogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGNvbXBpbGVyID0gbnVsbDsKICAgICAgICBjb250ZXh0ID0gbnVsbDsKICAgICAgICBub3RZZXRFbnRlcmVkID0gbnVsbDsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBJdGVyYWJsZTw/IGV4dGVuZHMgQ29tcGlsYXRpb25Vbml0VHJlZT4gcGFyc2UoKSB7CiAgICAgICAgcmV0dXJuIGhhbmRsZUV4Y2VwdGlvbnModGhpczo6cGFyc2VJbnRlcm5hbCwgTGlzdC5uaWwoKSwgTGlzdC5uaWwoKSk7CiAgICB9CgogICAgcHJpdmF0ZSBJdGVyYWJsZTw/IGV4dGVuZHMgQ29tcGlsYXRpb25Vbml0VHJlZT4gcGFyc2VJbnRlcm5hbCgpIHsKICAgICAgICB0cnkgewogICAgICAgICAgICBwcmVwYXJlQ29tcGlsZXIodHJ1ZSk7CiAgICAgICAgICAgIExpc3Q8SkNDb21waWxhdGlvblVuaXQ+IHVuaXRzID0gY29tcGlsZXIucGFyc2VGaWxlcyhhcmdzLmdldEZpbGVPYmplY3RzKCkpOwogICAgICAgICAgICBmb3IgKEpDQ29tcGlsYXRpb25Vbml0IHVuaXQ6IHVuaXRzKSB7CiAgICAgICAgICAgICAgICBKYXZhRmlsZU9iamVjdCBmaWxlID0gdW5pdC5nZXRTb3VyY2VGaWxlKCk7CiAgICAgICAgICAgICAgICBpZiAobm90WWV0RW50ZXJlZC5jb250YWluc0tleShmaWxlKSkKICAgICAgICAgICAgICAgICAgICBub3RZZXRFbnRlcmVkLnB1dChmaWxlLCB1bml0KTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gdW5pdHM7CiAgICAgICAgfQogICAgICAgIGZpbmFsbHkgewogICAgICAgICAgICBwYXJzZWQgPSB0cnVlOwogICAgICAgICAgICBpZiAoY29tcGlsZXIgIT0gbnVsbCAmJiBjb21waWxlci5sb2cgIT0gbnVsbCkKICAgICAgICAgICAgICAgIGNvbXBpbGVyLmxvZy5mbHVzaCgpOwogICAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIGJvb2xlYW4gcGFyc2VkID0gZmFsc2U7CgogICAgLyoqCiAgICAgKiBUcmFuc2xhdGUgYWxsIHRoZSBhYnN0cmFjdCBzeW50YXggdHJlZXMgdG8gZWxlbWVudHMuCiAgICAgKgogICAgICogQHJldHVybiBhIGxpc3Qgb2YgZWxlbWVudHMgY29ycmVzcG9uZGluZyB0byB0aGUgdG9wIGxldmVsCiAgICAgKiBjbGFzc2VzIGluIHRoZSBhYnN0cmFjdCBzeW50YXggdHJlZXMKICAgICAqLwogICAgcHVibGljIEl0ZXJhYmxlPD8gZXh0ZW5kcyBFbGVtZW50PiBlbnRlcigpIHsKICAgICAgICByZXR1cm4gZW50ZXIobnVsbCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBUcmFuc2xhdGUgdGhlIGdpdmVuIGFic3RyYWN0IHN5bnRheCB0cmVlcyB0byBlbGVtZW50cy4KICAgICAqCiAgICAgKiBAcGFyYW0gdHJlZXMgYSBsaXN0IG9mIGFic3RyYWN0IHN5bnRheCB0cmVlcy4KICAgICAqIEByZXR1cm4gYSBsaXN0IG9mIGVsZW1lbnRzIGNvcnJlc3BvbmRpbmcgdG8gdGhlIHRvcCBsZXZlbAogICAgICogY2xhc3NlcyBpbiB0aGUgYWJzdHJhY3Qgc3ludGF4IHRyZWVzCiAgICAgKi8KICAgIHB1YmxpYyBJdGVyYWJsZTw/IGV4dGVuZHMgRWxlbWVudD4gZW50ZXIoSXRlcmFibGU8PyBleHRlbmRzIENvbXBpbGF0aW9uVW5pdFRyZWU+IHRyZWVzKQogICAgewogICAgICAgIGlmICh0cmVlcyA9PSBudWxsICYmIG5vdFlldEVudGVyZWQgIT0gbnVsbCAmJiBub3RZZXRFbnRlcmVkLmlzRW1wdHkoKSkKICAgICAgICAgICAgcmV0dXJuIExpc3QubmlsKCk7CgogICAgICAgIGJvb2xlYW4gd2FzSW5pdGlhbGl6ZWQgPSBjb21waWxlciAhPSBudWxsOwoKICAgICAgICBwcmVwYXJlQ29tcGlsZXIodHJ1ZSk7CgogICAgICAgIExpc3RCdWZmZXI8SkNDb21waWxhdGlvblVuaXQ+IHJvb3RzID0gbnVsbDsKCiAgICAgICAgaWYgKHRyZWVzID09IG51bGwpIHsKICAgICAgICAgICAgLy8gSWYgdGhlcmUgYXJlIHN0aWxsIGZpbGVzIHdoaWNoIHdlcmUgc3BlY2lmaWVkIHRvIGJlIGNvbXBpbGVkCiAgICAgICAgICAgIC8vIChpLmUuIGluIGZpbGVPYmplY3RzKSBidXQgd2hpY2ggaGF2ZSBub3QgeWV0IGJlZW4gZW50ZXJlZCwKICAgICAgICAgICAgLy8gdGhlbiB3ZSBtYWtlIHN1cmUgdGhleSBoYXZlIGJlZW4gcGFyc2VkIGFuZCBhZGQgdGhlbSB0byB0aGUKICAgICAgICAgICAgLy8gbGlzdCB0byBiZSBlbnRlcmVkLgogICAgICAgICAgICBpZiAobm90WWV0RW50ZXJlZC5zaXplKCkgPiAwKSB7CiAgICAgICAgICAgICAgICBpZiAoIXBhcnNlZCkKICAgICAgICAgICAgICAgICAgICBwYXJzZUludGVybmFsKCk7IC8vIFRPRE8gd291bGQgYmUgbmljZSB0byBzcGVjaWZ5IGZpbGVzIG5lZWRlZCB0byBiZSBwYXJzZWQKICAgICAgICAgICAgICAgIGZvciAoSmF2YUZpbGVPYmplY3QgZmlsZTogYXJncy5nZXRGaWxlT2JqZWN0cygpKSB7CiAgICAgICAgICAgICAgICAgICAgSkNDb21waWxhdGlvblVuaXQgdW5pdCA9IG5vdFlldEVudGVyZWQucmVtb3ZlKGZpbGUpOwogICAgICAgICAgICAgICAgICAgIGlmICh1bml0ICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJvb3RzID09IG51bGwpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICByb290cyA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICAgICAgICAgICAgICAgICAgcm9vdHMuYXBwZW5kKHVuaXQpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIG5vdFlldEVudGVyZWQuY2xlYXIoKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgZm9yIChDb21waWxhdGlvblVuaXRUcmVlIGN1IDogdHJlZXMpIHsKICAgICAgICAgICAgICAgIGlmIChjdSBpbnN0YW5jZW9mIEpDQ29tcGlsYXRpb25Vbml0KSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHJvb3RzID09IG51bGwpCiAgICAgICAgICAgICAgICAgICAgICAgIHJvb3RzID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgICAgICAgICAgICAgIHJvb3RzLmFwcGVuZCgoSkNDb21waWxhdGlvblVuaXQpY3UpOwogICAgICAgICAgICAgICAgICAgIG5vdFlldEVudGVyZWQucmVtb3ZlKGN1LmdldFNvdXJjZUZpbGUoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihjdS50b1N0cmluZygpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKHJvb3RzID09IG51bGwpIHsKICAgICAgICAgICAgaWYgKHRyZWVzID09IG51bGwgJiYgIXdhc0luaXRpYWxpemVkKSB7CiAgICAgICAgICAgICAgICBjb21waWxlci5pbml0TW9kdWxlcyhMaXN0Lm5pbCgpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gTGlzdC5uaWwoKTsKICAgICAgICB9CgogICAgICAgIExpc3Q8SkNDb21waWxhdGlvblVuaXQ+IHVuaXRzID0gY29tcGlsZXIuaW5pdE1vZHVsZXMocm9vdHMudG9MaXN0KCkpOwoKICAgICAgICB0cnkgewogICAgICAgICAgICB1bml0cyA9IGNvbXBpbGVyLmVudGVyVHJlZXModW5pdHMpOwoKICAgICAgICAgICAgaWYgKG5vdFlldEVudGVyZWQuaXNFbXB0eSgpKQogICAgICAgICAgICAgICAgY29tcGlsZXIucHJvY2Vzc0Fubm90YXRpb25zKHVuaXRzKTsKCiAgICAgICAgICAgIExpc3RCdWZmZXI8RWxlbWVudD4gZWxlbWVudHMgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgIGZvciAoSkNDb21waWxhdGlvblVuaXQgdW5pdCA6IHVuaXRzKSB7CiAgICAgICAgICAgICAgICBib29sZWFuIGlzUGtnSW5mbyA9IHVuaXQuc291cmNlZmlsZS5pc05hbWVDb21wYXRpYmxlKCJwYWNrYWdlLWluZm8iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBKYXZhRmlsZU9iamVjdC5LaW5kLlNPVVJDRSk7CiAgICAgICAgICAgICAgICBpZiAoaXNQa2dJbmZvKSB7CiAgICAgICAgICAgICAgICAgICAgZWxlbWVudHMuYXBwZW5kKHVuaXQucGFja2dlKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgZm9yIChKQ1RyZWUgbm9kZSA6IHVuaXQuZGVmcykgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAobm9kZS5oYXNUYWcoSkNUcmVlLlRhZy5DTEFTU0RFRikpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEpDQ2xhc3NEZWNsIGNkZWYgPSAoSkNDbGFzc0RlY2wpIG5vZGU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY2RlZi5zeW0gIT0gbnVsbCkgLy8gbWF5YmUgbnVsbCBpZiBlcnJvcnMgaW4gYW5ubyBwcm9jZXNzaW5nCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudHMuYXBwZW5kKGNkZWYuc3ltKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChub2RlLmhhc1RhZyhKQ1RyZWUuVGFnLk1PRFVMRURFRikpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEpDTW9kdWxlRGVjbCBtZGVmID0gKEpDTW9kdWxlRGVjbCkgbm9kZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChtZGVmLnN5bSAhPSBudWxsKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnRzLmFwcGVuZChtZGVmLnN5bSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGVsZW1lbnRzLnRvTGlzdCgpOwogICAgICAgIH0KICAgICAgICBmaW5hbGx5IHsKICAgICAgICAgICAgY29tcGlsZXIubG9nLmZsdXNoKCk7CiAgICAgICAgfQogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIEl0ZXJhYmxlPD8gZXh0ZW5kcyBFbGVtZW50PiBhbmFseXplKCkgewogICAgICAgIHJldHVybiBoYW5kbGVFeGNlcHRpb25zKCgpIC0+IGFuYWx5emUobnVsbCksIExpc3QubmlsKCksIExpc3QubmlsKCkpOwogICAgfQoKICAgIC8qKgogICAgICogQ29tcGxldGUgYWxsIGFuYWx5c2lzIG9uIHRoZSBnaXZlbiBjbGFzc2VzLgogICAgICogVGhpcyBjYW4gYmUgdXNlZCB0byBlbnN1cmUgdGhhdCBhbGwgY29tcGlsZSB0aW1lIGVycm9ycyBhcmUgcmVwb3J0ZWQuCiAgICAgKiBUaGUgY2xhc3NlcyBtdXN0IGhhdmUgcHJldmlvdXNseSBiZWVuIHJldHVybmVkIGZyb20ge0BsaW5rICNlbnRlcn0uCiAgICAgKiBJZiBudWxsIGlzIHNwZWNpZmllZCwgYWxsIG91dHN0YW5kaW5nIGNsYXNzZXMgd2lsbCBiZSBhbmFseXplZC4KICAgICAqCiAgICAgKiBAcGFyYW0gY2xhc3NlcyBhIGxpc3Qgb2YgY2xhc3MgZWxlbWVudHMKICAgICAqIEByZXR1cm4gdGhlIGVsZW1lbnRzIHRoYXQgd2VyZSBhbmFseXplZAogICAgICovCiAgICAvLyBUaGlzIGltcGxlbWVudGF0aW9uIHJlcXVpcmVzIHRoYXQgd2Ugb3BlbiB1cCBwcml2aWxlZ2VzIG9uIEphdmFDb21waWxlci4KICAgIC8vIEFuIGFsdGVybmF0aXZlIGltcGxlbWVudGF0aW9uIHdvdWxkIGJlIHRvIG1vdmUgdGhpcyBjb2RlIHRvIEphdmFDb21waWxlciBhbmQKICAgIC8vIHdyYXAgaXQgaGVyZQogICAgcHVibGljIEl0ZXJhYmxlPD8gZXh0ZW5kcyBFbGVtZW50PiBhbmFseXplKEl0ZXJhYmxlPD8gZXh0ZW5kcyBFbGVtZW50PiBjbGFzc2VzKSB7CiAgICAgICAgZW50ZXIobnVsbCk7ICAvLyBlbnN1cmUgYWxsIGNsYXNzZXMgaGF2ZSBiZWVuIGVudGVyZWQKCiAgICAgICAgZmluYWwgTGlzdEJ1ZmZlcjxFbGVtZW50PiByZXN1bHRzID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGlmIChjbGFzc2VzID09IG51bGwpIHsKICAgICAgICAgICAgICAgIGhhbmRsZUZsb3dSZXN1bHRzKGNvbXBpbGVyLmZsb3coY29tcGlsZXIuYXR0cmlidXRlKGNvbXBpbGVyLnRvZG8pKSwgcmVzdWx0cyk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBGaWx0ZXIgZiA9IG5ldyBGaWx0ZXIoKSB7CiAgICAgICAgICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgICAgICAgICAgcHVibGljIHZvaWQgcHJvY2VzcyhFbnY8QXR0ckNvbnRleHQ+IGVudikgewogICAgICAgICAgICAgICAgICAgICAgICBoYW5kbGVGbG93UmVzdWx0cyhjb21waWxlci5mbG93KGNvbXBpbGVyLmF0dHJpYnV0ZShlbnYpKSwgcmVzdWx0cyk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgICAgIGYucnVuKGNvbXBpbGVyLnRvZG8sIGNsYXNzZXMpOwogICAgICAgICAgICB9CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgY29tcGlsZXIubG9nLmZsdXNoKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHRzOwogICAgfQogICAgLy8gd2hlcmUKICAgICAgICBwcml2YXRlIHZvaWQgaGFuZGxlRmxvd1Jlc3VsdHMoUXVldWU8RW52PEF0dHJDb250ZXh0Pj4gcXVldWUsIExpc3RCdWZmZXI8RWxlbWVudD4gZWxlbXMpIHsKICAgICAgICAgICAgZm9yIChFbnY8QXR0ckNvbnRleHQ+IGVudjogcXVldWUpIHsKICAgICAgICAgICAgICAgIHN3aXRjaCAoZW52LnRyZWUuZ2V0VGFnKCkpIHsKICAgICAgICAgICAgICAgICAgICBjYXNlIENMQVNTREVGOgogICAgICAgICAgICAgICAgICAgICAgICBKQ0NsYXNzRGVjbCBjZGVmID0gKEpDQ2xhc3NEZWNsKSBlbnYudHJlZTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNkZWYuc3ltICE9IG51bGwpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtcy5hcHBlbmQoY2RlZi5zeW0pOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICBjYXNlIE1PRFVMRURFRjoKICAgICAgICAgICAgICAgICAgICAgICAgSkNNb2R1bGVEZWNsIG1vZCA9IChKQ01vZHVsZURlY2wpIGVudi50cmVlOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAobW9kLnN5bSAhPSBudWxsKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbXMuYXBwZW5kKG1vZC5zeW0pOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICBjYXNlIFBBQ0tBR0VERUY6CiAgICAgICAgICAgICAgICAgICAgICAgIEpDQ29tcGlsYXRpb25Vbml0IHVuaXQgPSBlbnYudG9wbGV2ZWw7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh1bml0LnBhY2tnZSAhPSBudWxsKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbXMuYXBwZW5kKHVuaXQucGFja2dlKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZ2VuTGlzdC5hZGRBbGwocXVldWUpOwogICAgICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBJdGVyYWJsZTw/IGV4dGVuZHMgSmF2YUZpbGVPYmplY3Q+IGdlbmVyYXRlKCkgewogICAgICAgIHJldHVybiBoYW5kbGVFeGNlcHRpb25zKCgpIC0+IGdlbmVyYXRlKG51bGwpLCBMaXN0Lm5pbCgpLCBMaXN0Lm5pbCgpKTsKICAgIH0KCiAgICAvKioKICAgICAqIEdlbmVyYXRlIGNvZGUgY29ycmVzcG9uZGluZyB0byB0aGUgZ2l2ZW4gY2xhc3Nlcy4KICAgICAqIFRoZSBjbGFzc2VzIG11c3QgaGF2ZSBwcmV2aW91c2x5IGJlZW4gcmV0dXJuZWQgZnJvbSB7QGxpbmsgI2VudGVyfS4KICAgICAqIElmIHRoZXJlIGFyZSBjbGFzc2VzIG91dHN0YW5kaW5nIHRvIGJlIGFuYWx5emVkLCB0aGF0IHdpbGwgYmUgZG9uZSBiZWZvcmUKICAgICAqIGFueSBjbGFzc2VzIGFyZSBnZW5lcmF0ZWQuCiAgICAgKiBJZiBudWxsIGlzIHNwZWNpZmllZCwgY29kZSB3aWxsIGJlIGdlbmVyYXRlZCBmb3IgYWxsIG91dHN0YW5kaW5nIGNsYXNzZXMuCiAgICAgKgogICAgICogQHBhcmFtIGNsYXNzZXMgYSBsaXN0IG9mIGNsYXNzIGVsZW1lbnRzCiAgICAgKiBAcmV0dXJuIHRoZSBmaWxlcyB0aGF0IHdlcmUgZ2VuZXJhdGVkCiAgICAgKi8KICAgIHB1YmxpYyBJdGVyYWJsZTw/IGV4dGVuZHMgSmF2YUZpbGVPYmplY3Q+IGdlbmVyYXRlKEl0ZXJhYmxlPD8gZXh0ZW5kcyBFbGVtZW50PiBjbGFzc2VzKSB7CiAgICAgICAgZmluYWwgTGlzdEJ1ZmZlcjxKYXZhRmlsZU9iamVjdD4gcmVzdWx0cyA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICB0cnkgewogICAgICAgICAgICBhbmFseXplKG51bGwpOyAgLy8gZW5zdXJlIGFsbCBjbGFzc2VzIGhhdmUgYmVlbiBwYXJzZWQsIGVudGVyZWQsIGFuZCBhbmFseXplZAoKICAgICAgICAgICAgaWYgKGNsYXNzZXMgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgY29tcGlsZXIuZ2VuZXJhdGUoY29tcGlsZXIuZGVzdWdhcihnZW5MaXN0KSwgcmVzdWx0cyk7CiAgICAgICAgICAgICAgICBnZW5MaXN0LmNsZWFyKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICBGaWx0ZXIgZiA9IG5ldyBGaWx0ZXIoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCBwcm9jZXNzKEVudjxBdHRyQ29udGV4dD4gZW52KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21waWxlci5nZW5lcmF0ZShjb21waWxlci5kZXN1Z2FyKExpc3RCdWZmZXIub2YoZW52KSksIHJlc3VsdHMpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgICAgIGYucnVuKGdlbkxpc3QsIGNsYXNzZXMpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChnZW5MaXN0LmlzRW1wdHkoKSkgewogICAgICAgICAgICAgICAgY29tcGlsZXIucmVwb3J0RGVmZXJyZWREaWFnbm9zdGljcygpOwogICAgICAgICAgICAgICAgY2xlYW51cCgpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGZpbmFsbHkgewogICAgICAgICAgICBpZiAoY29tcGlsZXIgIT0gbnVsbCkKICAgICAgICAgICAgICAgIGNvbXBpbGVyLmxvZy5mbHVzaCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0czsKICAgIH0KCiAgICBwdWJsaWMgSXRlcmFibGU8PyBleHRlbmRzIFRyZWU+IHBhdGhGb3IoQ29tcGlsYXRpb25Vbml0VHJlZSB1bml0LCBUcmVlIG5vZGUpIHsKICAgICAgICByZXR1cm4gVHJlZUluZm8ucGF0aEZvcigoSkNUcmVlKSBub2RlLCAoSkNUcmVlLkpDQ29tcGlsYXRpb25Vbml0KSB1bml0KS5yZXZlcnNlKCk7CiAgICB9CgogICAgcHVibGljIHZvaWQgZW5zdXJlRW50ZXJlZCgpIHsKICAgICAgICBhcmdzLmFsbG93RW1wdHkoKTsKICAgICAgICBlbnRlcihudWxsKTsKICAgIH0KCiAgICBhYnN0cmFjdCBjbGFzcyBGaWx0ZXIgewogICAgICAgIHZvaWQgcnVuKFF1ZXVlPEVudjxBdHRyQ29udGV4dD4+IGxpc3QsIEl0ZXJhYmxlPD8gZXh0ZW5kcyBFbGVtZW50PiBlbGVtZW50cykgewogICAgICAgICAgICBTZXQ8RWxlbWVudD4gc2V0ID0gbmV3IEhhc2hTZXQ8PigpOwogICAgICAgICAgICBmb3IgKEVsZW1lbnQgaXRlbTogZWxlbWVudHMpIHsKICAgICAgICAgICAgICAgIHNldC5hZGQoaXRlbSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIExpc3RCdWZmZXI8RW52PEF0dHJDb250ZXh0Pj4gZGVmZXIgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgIHdoaWxlIChsaXN0LnBlZWsoKSAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICBFbnY8QXR0ckNvbnRleHQ+IGVudiA9IGxpc3QucmVtb3ZlKCk7CiAgICAgICAgICAgICAgICBTeW1ib2wgdGVzdCA9IG51bGw7CgogICAgICAgICAgICAgICAgaWYgKGVudi50cmVlLmhhc1RhZyhUYWcuTU9EVUxFREVGKSkgewogICAgICAgICAgICAgICAgICAgIHRlc3QgPSAoKEpDTW9kdWxlRGVjbCkgZW52LnRyZWUpLnN5bTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZW52LnRyZWUuaGFzVGFnKFRhZy5QQUNLQUdFREVGKSkgewogICAgICAgICAgICAgICAgICAgIHRlc3QgPSBlbnYudG9wbGV2ZWwucGFja2dlOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBDbGFzc1N5bWJvbCBjc3ltID0gZW52LmVuY2xDbGFzcy5zeW07CiAgICAgICAgICAgICAgICAgICAgaWYgKGNzeW0gIT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICAgICAgdGVzdCA9IGNzeW0ub3V0ZXJtb3N0Q2xhc3MoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICh0ZXN0ICE9IG51bGwgJiYgc2V0LmNvbnRhaW5zKHRlc3QpKQogICAgICAgICAgICAgICAgICAgIHByb2Nlc3MoZW52KTsKICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICBkZWZlciA9IGRlZmVyLmFwcGVuZChlbnYpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBsaXN0LmFkZEFsbChkZWZlcik7CiAgICAgICAgfQoKICAgICAgICBhYnN0cmFjdCB2b2lkIHByb2Nlc3MoRW52PEF0dHJDb250ZXh0PiBlbnYpOwogICAgfQoKICAgIC8qKgogICAgICogRm9yIGludGVybmFsIHVzZSBvbmx5LiAgVGhpcyBtZXRob2Qgd2lsbCBiZQogICAgICogcmVtb3ZlZCB3aXRob3V0IHdhcm5pbmcuCiAgICAgKiBAcGFyYW0gZXhwciB0aGUgdHlwZSBleHByZXNzaW9uIHRvIGJlIGFuYWx5emVkCiAgICAgKiBAcGFyYW0gc2NvcGUgdGhlIHNjb3BlIGluIHdoaWNoIHRvIGFuYWx5emUgdGhlIHR5cGUgZXhwcmVzc2lvbgogICAgICogQHJldHVybiB0aGUgdHlwZQogICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgdGhlIHR5cGUgZXhwcmVzc2lvbiBvZiBudWxsIG9yIGVtcHR5CiAgICAgKi8KICAgIHB1YmxpYyBUeXBlIHBhcnNlVHlwZShTdHJpbmcgZXhwciwgVHlwZUVsZW1lbnQgc2NvcGUpIHsKICAgICAgICBpZiAoZXhwciA9PSBudWxsIHx8IGV4cHIuZXF1YWxzKCIiKSkKICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIGNvbXBpbGVyID0gSmF2YUNvbXBpbGVyLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIEphdmFGaWxlT2JqZWN0IHByZXYgPSBjb21waWxlci5sb2cudXNlU291cmNlKG51bGwpOwogICAgICAgIFBhcnNlckZhY3RvcnkgcGFyc2VyRmFjdG9yeSA9IFBhcnNlckZhY3RvcnkuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgQXR0ciBhdHRyID0gQXR0ci5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICB0cnkgewogICAgICAgICAgICBDaGFyQnVmZmVyIGJ1ZiA9IENoYXJCdWZmZXIud3JhcCgoZXhwcisiXHUwMDAwIikudG9DaGFyQXJyYXkoKSwgMCwgZXhwci5sZW5ndGgoKSk7CiAgICAgICAgICAgIFBhcnNlciBwYXJzZXIgPSBwYXJzZXJGYWN0b3J5Lm5ld1BhcnNlcihidWYsIGZhbHNlLCBmYWxzZSwgZmFsc2UpOwogICAgICAgICAgICBKQ1RyZWUgdHJlZSA9IHBhcnNlci5wYXJzZVR5cGUoKTsKICAgICAgICAgICAgcmV0dXJuIGF0dHIuYXR0cmliVHlwZSh0cmVlLCAoU3ltYm9sLlR5cGVTeW1ib2wpc2NvcGUpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgIGNvbXBpbGVyLmxvZy51c2VTb3VyY2UocHJldik7CiAgICAgICAgfQogICAgfQoKfQpQSwMECgAACAAA0n1NSp3z8j5KCQAASgkAACUAAABjb20vc3VuL3Rvb2xzL2phdmFjL2FwaS9NZXNzYWdlcy5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDA4LCAyMDA5LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuamF2YWMuYXBpOwoKaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CmltcG9ydCBqYXZhLnV0aWwuTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uOwoKLyoqCiAqIFRoaXMgaW50ZXJmYWNlIGRlZmluZXMgdGhlIG1pbmltdW0gcmVxdWlyZW1lbnRzIGluIG9yZGVyIHRvIHByb3ZpZGUgc3VwcG9ydAogKiBmb3IgbG9jYWxpemVkIGZvcm1hdHRlZCBzdHJpbmdzLgogKgogKiA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yCiAqIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj4KICoKICogQGF1dGhvciBNYXVyaXppbyBDaW1hZGFtb3JlCiAqLwpwdWJsaWMgaW50ZXJmYWNlIE1lc3NhZ2VzIHsKCiAgICAvKioKICAgICAqIEFkZCBhIG5ldyByZXNvdXJjZSBidW5kbGUgdG8gdGhlIGxpc3QgdGhhdCBpcyBzZWFyY2hlZCBmb3IgbG9jYWxpemVkIG1lc3NhZ2VzLgogICAgICogQHBhcmFtIGJ1bmRsZU5hbWUgdGhlIG5hbWUgdG8gaWRlbnRpZnkgdGhlIHJlc291cmNlIGJ1bmRsZSBvZiBsb2NhbGl6ZWQgbWVzc2FnZXMuCiAgICAgKiBAdGhyb3dzIE1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbiBpZiB0aGUgZ2l2ZW4gcmVzb3VyY2UgaXMgbm90IGZvdW5kCiAgICAgKi8KICAgIHZvaWQgYWRkKFN0cmluZyBidW5kbGVOYW1lKSB0aHJvd3MgTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uOwoKICAgIC8qKgogICAgICogR2V0IGEgbG9jYWxpemVkIGZvcm1hdHRlZCBzdHJpbmcuCiAgICAgKiBAcGFyYW0gbCBsb2NhbGUgaW4gd2hpY2ggdGhlIHRleHQgaXMgdG8gYmUgbG9jYWxpemVkCiAgICAgKiBAcGFyYW0ga2V5IGxvY2FsZS1pbmRlcGVuZGVudCBtZXNzYWdlIGtleQogICAgICogQHBhcmFtIGFyZ3MgbWlzYyBtZXNzYWdlIGFyZ3VtZW50cwogICAgICogQHJldHVybiBhIGxvY2FsaXplZCBmb3JtYXR0ZWQgc3RyaW5nCiAgICAgKi8KICAgIFN0cmluZyBnZXRMb2NhbGl6ZWRTdHJpbmcoTG9jYWxlIGwsIFN0cmluZyBrZXksIE9iamVjdC4uLiBhcmdzKTsKfQpQSwMECgAACAAABjupSsbhIGhGEgAARhIAACcAAABjb20vc3VuL3Rvb2xzL2phdmFjL2FwaS9KYXZhY1Njb3BlLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDYsIDIwMTQsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhYy5hcGk7CgoKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC5FbGVtZW50OwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5lbGVtZW50LkV4ZWN1dGFibGVFbGVtZW50OwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5lbGVtZW50LlR5cGVFbGVtZW50OwoKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29tcC5BdHRyQ29udGV4dDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29tcC5FbnY7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuRGVmaW5lZEJ5OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkRlZmluZWRCeS5BcGk7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuQXNzZXJ0OwoKLyoqCiAqIFByb3ZpZGVzIGFuIGltcGxlbWVudGF0aW9uIG9mIFNjb3BlLgogKgogKiA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duCiAqIHJpc2suICBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZQogKiBvciBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+PC9wPgogKgogKiBAYXV0aG9yIEpvbmF0aGFuIEdpYmJvbnM7CiAqLwpwdWJsaWMgY2xhc3MgSmF2YWNTY29wZSBpbXBsZW1lbnRzIGNvbS5zdW4uc291cmNlLnRyZWUuU2NvcGUgewoKICAgIHN0YXRpYyBKYXZhY1Njb3BlIGNyZWF0ZShFbnY8QXR0ckNvbnRleHQ+IGVudikgewogICAgICAgIGlmIChlbnYub3V0ZXIgPT0gbnVsbCB8fCBlbnYub3V0ZXIgPT0gZW52KSB7CiAgICAgICAgICAgIC8vdGhlICJ0b3AtbGV2ZWwiIHNjb3BlIG5lZWRzIHRvIHJldHVybiBib3RoIGltcG9ydGVkIGFuZCBkZWZpbmVkIGVsZW1lbnRzCiAgICAgICAgICAgIC8vc2VlIHRlc3QgQ2hlY2tMb2NhbEVsZW1lbnRzCiAgICAgICAgICAgIHJldHVybiBuZXcgSmF2YWNTY29wZShlbnYpIHsKICAgICAgICAgICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgICAgICAgICAgcHVibGljIEl0ZXJhYmxlPD8gZXh0ZW5kcyBFbGVtZW50PiBnZXRMb2NhbEVsZW1lbnRzKCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBlbnYudG9wbGV2ZWwubmFtZWRJbXBvcnRTY29wZS5nZXRTeW1ib2xzKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyBKYXZhY1Njb3BlKGVudik7CiAgICAgICAgfQogICAgfQoKICAgIHByb3RlY3RlZCBmaW5hbCBFbnY8QXR0ckNvbnRleHQ+IGVudjsKCiAgICBwcml2YXRlIEphdmFjU2NvcGUoRW52PEF0dHJDb250ZXh0PiBlbnYpIHsKICAgICAgICB0aGlzLmVudiA9IEFzc2VydC5jaGVja05vbk51bGwoZW52KTsKICAgIH0KCiAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIEphdmFjU2NvcGUgZ2V0RW5jbG9zaW5nU2NvcGUoKSB7CiAgICAgICAgaWYgKGVudi5vdXRlciAhPSBudWxsICYmIGVudi5vdXRlciAhPSBlbnYpIHsKICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZShlbnYub3V0ZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8vIHN5bnRoZXNpemUgYW4gb3V0ZXJtb3N0ICJzdGFyLWltcG9ydCIgc2NvcGUKICAgICAgICAgICAgcmV0dXJuIG5ldyBKYXZhY1Njb3BlKGVudikgewogICAgICAgICAgICAgICAgcHVibGljIGJvb2xlYW4gaXNTdGFySW1wb3J0U2NvcGUoKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgICAgICAgICAgcHVibGljIEphdmFjU2NvcGUgZ2V0RW5jbG9zaW5nU2NvcGUoKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgICAgICAgICAgcHVibGljIEl0ZXJhYmxlPD8gZXh0ZW5kcyBFbGVtZW50PiBnZXRMb2NhbEVsZW1lbnRzKCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBlbnYudG9wbGV2ZWwuc3RhckltcG9ydFNjb3BlLmdldFN5bWJvbHMoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKICAgICAgICB9CiAgICB9CgogICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBUeXBlRWxlbWVudCBnZXRFbmNsb3NpbmdDbGFzcygpIHsKICAgICAgICAvLyBoaWRlIHRoZSBkdW1teSBjbGFzcyB0aGF0IGphdmFjIHVzZXMgdG8gZW5jbG9zZSB0aGUgdG9wIGxldmVsIGRlY2xhcmF0aW9ucwogICAgICAgIHJldHVybiAoZW52Lm91dGVyID09IG51bGwgfHwgZW52Lm91dGVyID09IGVudiA/IG51bGwgOiBlbnYuZW5jbENsYXNzLnN5bSk7CiAgICB9CgogICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBFeGVjdXRhYmxlRWxlbWVudCBnZXRFbmNsb3NpbmdNZXRob2QoKSB7CiAgICAgICAgcmV0dXJuIChlbnYuZW5jbE1ldGhvZCA9PSBudWxsID8gbnVsbCA6IGVudi5lbmNsTWV0aG9kLnN5bSk7CiAgICB9CgogICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBJdGVyYWJsZTw/IGV4dGVuZHMgRWxlbWVudD4gZ2V0TG9jYWxFbGVtZW50cygpIHsKICAgICAgICByZXR1cm4gZW52LmluZm8uZ2V0TG9jYWxFbGVtZW50cygpOwogICAgfQoKICAgIHB1YmxpYyBFbnY8QXR0ckNvbnRleHQ+IGdldEVudigpIHsKICAgICAgICByZXR1cm4gZW52OwogICAgfQoKICAgIHB1YmxpYyBib29sZWFuIGlzU3RhckltcG9ydFNjb3BlKCkgewogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgSmF2YWNTY29wZSkgewogICAgICAgICAgICBKYXZhY1Njb3BlIHMgPSAoSmF2YWNTY29wZSkgb3RoZXI7CiAgICAgICAgICAgIHJldHVybiAoZW52LmVxdWFscyhzLmVudikKICAgICAgICAgICAgICAgICYmIGlzU3RhckltcG9ydFNjb3BlKCkgPT0gcy5pc1N0YXJJbXBvcnRTY29wZSgpKTsKICAgICAgICB9IGVsc2UKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgICAgcmV0dXJuIGVudi5oYXNoQ29kZSgpICsgKGlzU3RhckltcG9ydFNjb3BlKCkgPyAxIDogMCk7CiAgICB9CgogICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKICAgICAgICByZXR1cm4gIkphdmFjU2NvcGVbZW52PSIgKyBlbnYgKyAiLHN0YXJJbXBvcnQ9IiArIGlzU3RhckltcG9ydFNjb3BlKCkgKyAiXSI7CiAgICB9Cn0KUEsDBAoAAAgAAAY7qUpLA14nUSMAAFEjAAAmAAAAY29tL3N1bi90b29scy9qYXZhYy9hcGkvSmF2YWNUb29sLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMTYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhYy5hcGk7CgppbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOwppbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW1Xcml0ZXI7CmltcG9ydCBqYXZhLmlvLlByaW50V3JpdGVyOwppbXBvcnQgamF2YS5pby5Xcml0ZXI7CmltcG9ydCBqYXZhLm5pby5jaGFyc2V0LkNoYXJzZXQ7CmltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbnM7CmltcG9ydCBqYXZhLnV0aWwuRW51bVNldDsKaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CmltcG9ydCBqYXZhLnV0aWwuT2JqZWN0czsKaW1wb3J0IGphdmEudXRpbC5TZXQ7CgppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5Tb3VyY2VWZXJzaW9uOwppbXBvcnQgamF2YXgudG9vbHMuKjsKCmltcG9ydCBjb20uc3VuLnNvdXJjZS51dGlsLkphdmFjVGFzazsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuZmlsZS5KYXZhY0ZpbGVNYW5hZ2VyOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5tYWluLkFyZ3VtZW50czsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMubWFpbi5PcHRpb247CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmZpbGUuQmFzZUZpbGVNYW5hZ2VyOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5maWxlLkNhY2hlRlNJbmZvOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5qdm0uVGFyZ2V0OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkNsaWVudENvZGVFeGNlcHRpb247CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuQ29udGV4dDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5EZWZpbmVkQnk7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuRGVmaW5lZEJ5LkFwaTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5MaXN0OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkxvZzsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5Qcm9wYWdhdGVkRXhjZXB0aW9uOwoKLyoqCiAqIFRPRE86IGRlc2NyaWJlIGNvbS5zdW4udG9vbHMuamF2YWMuYXBpLlRvb2wKICoKICogPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93bgogKiByaXNrLiAgVGhpcyBjb2RlIGFuZCBpdHMgaW50ZXJuYWwgaW50ZXJmYWNlcyBhcmUgc3ViamVjdCB0byBjaGFuZ2UKICogb3IgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPjwvcD4KICoKICogQGF1dGhvciBQZXRlciB2b24gZGVyIEFoXHUwMGU5CiAqLwpwdWJsaWMgZmluYWwgY2xhc3MgSmF2YWNUb29sIGltcGxlbWVudHMgSmF2YUNvbXBpbGVyIHsKICAgIC8qKgogICAgICogQ29uc3RydWN0b3IgdXNlZCBieSBzZXJ2aWNlIHByb3ZpZGVyIG1lY2hhbmlzbS4gIFRoZSByZWNvbW1lbmRlZCB3YXkgdG8KICAgICAqIG9idGFpbiBhbiBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzIGlzIGJ5IHVzaW5nIHtAbGluayAjY3JlYXRlfSBvciB0aGUKICAgICAqIHNlcnZpY2UgcHJvdmlkZXIgbWVjaGFuaXNtLgogICAgICogQHNlZSBqYXZheC50b29scy5KYXZhQ29tcGlsZXIKICAgICAqIEBzZWUgamF2YXgudG9vbHMuVG9vbFByb3ZpZGVyCiAgICAgKiBAc2VlICNjcmVhdGUKICAgICAqLwogICAgQERlcHJlY2F0ZWQKICAgIHB1YmxpYyBKYXZhY1Rvb2woKSB7fQoKICAgIC8vIEBPdmVycmlkZSAvLyBjYW4ndCBhZGQgQE92ZXJyaWRlIHVudGlsIGJvb3RzdHJhcCBKREsgcHJvdmlkZXMgVG9vbC5uYW1lKCkKICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSKQogICAgcHVibGljIFN0cmluZyBuYW1lKCkgewogICAgICAgIHJldHVybiAiamF2YWMiOwogICAgfQoKICAgIC8qKgogICAgICogU3RhdGljIGZhY3RvcnkgbWV0aG9kIGZvciBjcmVhdGluZyBuZXcgaW5zdGFuY2VzIG9mIHRoaXMgdG9vbC4KICAgICAqIEByZXR1cm4gbmV3IGluc3RhbmNlIG9mIHRoaXMgdG9vbAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIEphdmFjVG9vbCBjcmVhdGUoKSB7CiAgICAgICAgcmV0dXJuIG5ldyBKYXZhY1Rvb2woKTsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICBwdWJsaWMgSmF2YWNGaWxlTWFuYWdlciBnZXRTdGFuZGFyZEZpbGVNYW5hZ2VyKAogICAgICAgIERpYWdub3N0aWNMaXN0ZW5lcjw/IHN1cGVyIEphdmFGaWxlT2JqZWN0PiBkaWFnbm9zdGljTGlzdGVuZXIsCiAgICAgICAgTG9jYWxlIGxvY2FsZSwKICAgICAgICBDaGFyc2V0IGNoYXJzZXQpIHsKICAgICAgICBDb250ZXh0IGNvbnRleHQgPSBuZXcgQ29udGV4dCgpOwogICAgICAgIGNvbnRleHQucHV0KExvY2FsZS5jbGFzcywgbG9jYWxlKTsKICAgICAgICBpZiAoZGlhZ25vc3RpY0xpc3RlbmVyICE9IG51bGwpCiAgICAgICAgICAgIGNvbnRleHQucHV0KERpYWdub3N0aWNMaXN0ZW5lci5jbGFzcywgZGlhZ25vc3RpY0xpc3RlbmVyKTsKICAgICAgICBQcmludFdyaXRlciBwdyA9IChjaGFyc2V0ID09IG51bGwpCiAgICAgICAgICAgICAgICA/IG5ldyBQcmludFdyaXRlcihTeXN0ZW0uZXJyLCB0cnVlKQogICAgICAgICAgICAgICAgOiBuZXcgUHJpbnRXcml0ZXIobmV3IE91dHB1dFN0cmVhbVdyaXRlcihTeXN0ZW0uZXJyLCBjaGFyc2V0KSwgdHJ1ZSk7CiAgICAgICAgY29udGV4dC5wdXQoTG9nLmVycktleSwgcHcpOwogICAgICAgIENhY2hlRlNJbmZvLnByZVJlZ2lzdGVyKGNvbnRleHQpOwogICAgICAgIHJldHVybiBuZXcgSmF2YWNGaWxlTWFuYWdlcihjb250ZXh0LCB0cnVlLCBjaGFyc2V0KTsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICBwdWJsaWMgSmF2YWNUYXNrIGdldFRhc2soV3JpdGVyIG91dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBKYXZhRmlsZU1hbmFnZXIgZmlsZU1hbmFnZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRGlhZ25vc3RpY0xpc3RlbmVyPD8gc3VwZXIgSmF2YUZpbGVPYmplY3Q+IGRpYWdub3N0aWNMaXN0ZW5lciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJdGVyYWJsZTxTdHJpbmc+IG9wdGlvbnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSXRlcmFibGU8U3RyaW5nPiBjbGFzc2VzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIEl0ZXJhYmxlPD8gZXh0ZW5kcyBKYXZhRmlsZU9iamVjdD4gY29tcGlsYXRpb25Vbml0cykgewogICAgICAgIENvbnRleHQgY29udGV4dCA9IG5ldyBDb250ZXh0KCk7CiAgICAgICAgcmV0dXJuIGdldFRhc2sob3V0LCBmaWxlTWFuYWdlciwgZGlhZ25vc3RpY0xpc3RlbmVyLAogICAgICAgICAgICAgICAgb3B0aW9ucywgY2xhc3NlcywgY29tcGlsYXRpb25Vbml0cywKICAgICAgICAgICAgICAgIGNvbnRleHQpOwogICAgfQoKICAgIC8qIEludGVybmFsIHZlcnNpb24gb2YgZ2V0VGFzaywgYWxsb3dpbmcgY29udGV4dCB0byBiZSBwcm92aWRlZC4gKi8KICAgIHB1YmxpYyBKYXZhY1Rhc2sgZ2V0VGFzayhXcml0ZXIgb3V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIEphdmFGaWxlTWFuYWdlciBmaWxlTWFuYWdlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEaWFnbm9zdGljTGlzdGVuZXI8PyBzdXBlciBKYXZhRmlsZU9iamVjdD4gZGlhZ25vc3RpY0xpc3RlbmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIEl0ZXJhYmxlPFN0cmluZz4gb3B0aW9ucywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJdGVyYWJsZTxTdHJpbmc+IGNsYXNzZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSXRlcmFibGU8PyBleHRlbmRzIEphdmFGaWxlT2JqZWN0PiBjb21waWxhdGlvblVuaXRzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB0cnkgewogICAgICAgICAgICBDbGllbnRDb2RlV3JhcHBlciBjY3cgPSBDbGllbnRDb2RlV3JhcHBlci5pbnN0YW5jZShjb250ZXh0KTsKCiAgICAgICAgICAgIGlmIChvcHRpb25zICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIGZvciAoU3RyaW5nIG9wdGlvbiA6IG9wdGlvbnMpCiAgICAgICAgICAgICAgICAgICAgT2JqZWN0cy5yZXF1aXJlTm9uTnVsbChvcHRpb24pOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoY2xhc3NlcyAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICBmb3IgKFN0cmluZyBjbHMgOiBjbGFzc2VzKSB7CiAgICAgICAgICAgICAgICAgICAgaW50IHNlcCA9IGNscy5pbmRleE9mKCcvJyk7IC8vIGltcGxpY2l0IG51bGwgY2hlY2sKICAgICAgICAgICAgICAgICAgICBpZiAoc2VwID4gMCkgewogICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbW9kID0gY2xzLnN1YnN0cmluZygwLCBzZXApOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIVNvdXJjZVZlcnNpb24uaXNOYW1lKG1vZCkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJOb3QgYSB2YWxpZCBtb2R1bGUgbmFtZTogIiArIG1vZCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGNscyA9IGNscy5zdWJzdHJpbmcoc2VwICsgMSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmICghU291cmNlVmVyc2lvbi5pc05hbWUoY2xzKSkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiTm90IGEgdmFsaWQgY2xhc3MgbmFtZTogIiArIGNscyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChjb21waWxhdGlvblVuaXRzICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIGNvbXBpbGF0aW9uVW5pdHMgPSBjY3cud3JhcEphdmFGaWxlT2JqZWN0cyhjb21waWxhdGlvblVuaXRzKTsgLy8gaW1wbGljaXQgbnVsbCBjaGVjawogICAgICAgICAgICAgICAgZm9yIChKYXZhRmlsZU9iamVjdCBjdSA6IGNvbXBpbGF0aW9uVW5pdHMpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoY3UuZ2V0S2luZCgpICE9IEphdmFGaWxlT2JqZWN0LktpbmQuU09VUkNFKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBraW5kTXNnID0gIkNvbXBpbGF0aW9uIHVuaXQgaXMgbm90IG9mIFNPVVJDRSBraW5kOiAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiXCIiICsgY3UuZ2V0TmFtZSgpICsgIlwiIjsKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihraW5kTXNnKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChkaWFnbm9zdGljTGlzdGVuZXIgIT0gbnVsbCkKICAgICAgICAgICAgICAgIGNvbnRleHQucHV0KERpYWdub3N0aWNMaXN0ZW5lci5jbGFzcywgY2N3LndyYXAoZGlhZ25vc3RpY0xpc3RlbmVyKSk7CgogICAgICAgICAgICBpZiAob3V0ID09IG51bGwpCiAgICAgICAgICAgICAgICBjb250ZXh0LnB1dChMb2cuZXJyS2V5LCBuZXcgUHJpbnRXcml0ZXIoU3lzdGVtLmVyciwgdHJ1ZSkpOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBjb250ZXh0LnB1dChMb2cuZXJyS2V5LCBuZXcgUHJpbnRXcml0ZXIob3V0LCB0cnVlKSk7CgogICAgICAgICAgICBpZiAoZmlsZU1hbmFnZXIgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgZmlsZU1hbmFnZXIgPSBnZXRTdGFuZGFyZEZpbGVNYW5hZ2VyKGRpYWdub3N0aWNMaXN0ZW5lciwgbnVsbCwgbnVsbCk7CiAgICAgICAgICAgICAgICBpZiAoZmlsZU1hbmFnZXIgaW5zdGFuY2VvZiBCYXNlRmlsZU1hbmFnZXIpIHsKICAgICAgICAgICAgICAgICAgICAoKEJhc2VGaWxlTWFuYWdlcikgZmlsZU1hbmFnZXIpLmF1dG9DbG9zZSA9IHRydWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZmlsZU1hbmFnZXIgPSBjY3cud3JhcChmaWxlTWFuYWdlcik7CgogICAgICAgICAgICBjb250ZXh0LnB1dChKYXZhRmlsZU1hbmFnZXIuY2xhc3MsIGZpbGVNYW5hZ2VyKTsKCiAgICAgICAgICAgIEFyZ3VtZW50cyBhcmdzID0gQXJndW1lbnRzLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgICAgICBhcmdzLmluaXQoImphdmFjIiwgb3B0aW9ucywgY2xhc3NlcywgY29tcGlsYXRpb25Vbml0cyk7CgogICAgICAgICAgICAvLyBpbml0IG11bHRpLXJlbGVhc2UgamFyIGhhbmRsaW5nCiAgICAgICAgICAgIGlmIChmaWxlTWFuYWdlci5pc1N1cHBvcnRlZE9wdGlvbihPcHRpb24uTVVMVElSRUxFQVNFLnByaW1hcnlOYW1lKSA9PSAxKSB7CiAgICAgICAgICAgICAgICBUYXJnZXQgdGFyZ2V0ID0gVGFyZ2V0Lmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgICAgICAgICAgTGlzdDxTdHJpbmc+IGxpc3QgPSBMaXN0Lm9mKHRhcmdldC5tdWx0aVJlbGVhc2VWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGZpbGVNYW5hZ2VyLmhhbmRsZU9wdGlvbihPcHRpb24uTVVMVElSRUxFQVNFLnByaW1hcnlOYW1lLCBsaXN0Lml0ZXJhdG9yKCkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gbmV3IEphdmFjVGFza0ltcGwoY29udGV4dCk7CiAgICAgICAgfSBjYXRjaCAoUHJvcGFnYXRlZEV4Y2VwdGlvbiBleCkgewogICAgICAgICAgICB0aHJvdyBleC5nZXRDYXVzZSgpOwogICAgICAgIH0gY2F0Y2ggKENsaWVudENvZGVFeGNlcHRpb24gZXgpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oZXguZ2V0Q2F1c2UoKSk7CiAgICAgICAgfQogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgIHB1YmxpYyBpbnQgcnVuKElucHV0U3RyZWFtIGluLCBPdXRwdXRTdHJlYW0gb3V0LCBPdXRwdXRTdHJlYW0gZXJyLCBTdHJpbmcuLi4gYXJndW1lbnRzKSB7CiAgICAgICAgaWYgKGVyciA9PSBudWxsKQogICAgICAgICAgICBlcnIgPSBTeXN0ZW0uZXJyOwogICAgICAgIGZvciAoU3RyaW5nIGFyZ3VtZW50IDogYXJndW1lbnRzKQogICAgICAgICAgICBPYmplY3RzLnJlcXVpcmVOb25OdWxsKGFyZ3VtZW50KTsKICAgICAgICByZXR1cm4gY29tLnN1bi50b29scy5qYXZhYy5NYWluLmNvbXBpbGUoYXJndW1lbnRzLCBuZXcgUHJpbnRXcml0ZXIoZXJyLCB0cnVlKSk7CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSKQogICAgcHVibGljIFNldDxTb3VyY2VWZXJzaW9uPiBnZXRTb3VyY2VWZXJzaW9ucygpIHsKICAgICAgICByZXR1cm4gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlU2V0KEVudW1TZXQucmFuZ2UoU291cmNlVmVyc2lvbi5SRUxFQVNFXzMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNvdXJjZVZlcnNpb24ubGF0ZXN0KCkpKTsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICBwdWJsaWMgaW50IGlzU3VwcG9ydGVkT3B0aW9uKFN0cmluZyBvcHRpb24pIHsKICAgICAgICBTZXQ8T3B0aW9uPiByZWNvZ25pemVkT3B0aW9ucyA9IE9wdGlvbi5nZXRKYXZhY1Rvb2xPcHRpb25zKCk7CiAgICAgICAgZm9yIChPcHRpb24gbyA6IHJlY29nbml6ZWRPcHRpb25zKSB7CiAgICAgICAgICAgIGlmIChvLm1hdGNoZXMob3B0aW9uKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIG8uaGFzQXJnKCkgPyAxIDogMDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gLTE7CiAgICB9Cgp9ClBLAwQKAAAIAAAGO6lK8ApFJgl2AAAJdgAALgAAAGNvbS9zdW4vdG9vbHMvamF2YWMvYXBpL0NsaWVudENvZGVXcmFwcGVyLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTEsIDIwMTcsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhYy5hcGk7CgppbXBvcnQgamF2YS5pby5GaWxlOwppbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CmltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKaW1wb3J0IGphdmEuaW8uUmVhZGVyOwppbXBvcnQgamF2YS5pby5Xcml0ZXI7CmltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5FbGVtZW50VHlwZTsKaW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLlJldGVudGlvbjsKaW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLlJldGVudGlvblBvbGljeTsKaW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLlRhcmdldDsKaW1wb3J0IGphdmEubmV0LlVSSTsKaW1wb3J0IGphdmEubmlvLmZpbGUuUGF0aDsKaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CmltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbjsKaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOwppbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOwppbXBvcnQgamF2YS51dGlsLkxpc3Q7CmltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOwppbXBvcnQgamF2YS51dGlsLk1hcDsKaW1wb3J0IGphdmEudXRpbC5PYmplY3RzOwppbXBvcnQgamF2YS51dGlsLlNldDsKCmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuTW9kaWZpZXI7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuTmVzdGluZ0tpbmQ7CmltcG9ydCBqYXZheC50b29scy5EaWFnbm9zdGljOwppbXBvcnQgamF2YXgudG9vbHMuRGlhZ25vc3RpY0xpc3RlbmVyOwppbXBvcnQgamF2YXgudG9vbHMuRmlsZU9iamVjdDsKaW1wb3J0IGphdmF4LnRvb2xzLkphdmFGaWxlTWFuYWdlcjsKaW1wb3J0IGphdmF4LnRvb2xzLkphdmFGaWxlTWFuYWdlci5Mb2NhdGlvbjsKaW1wb3J0IGphdmF4LnRvb2xzLkphdmFGaWxlT2JqZWN0OwppbXBvcnQgamF2YXgudG9vbHMuSmF2YUZpbGVPYmplY3QuS2luZDsKaW1wb3J0IGphdmF4LnRvb2xzLlN0YW5kYXJkSmF2YUZpbGVNYW5hZ2VyOwoKaW1wb3J0IGNvbS5zdW4uc291cmNlLnV0aWwuVGFza0V2ZW50OwppbXBvcnQgY29tLnN1bi5zb3VyY2UudXRpbC5UYXNrTGlzdGVuZXI7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuQ2xpZW50Q29kZUV4Y2VwdGlvbjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5Db250ZXh0OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkRlZmluZWRCeTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5EZWZpbmVkQnkuQXBpOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkpDRGlhZ25vc3RpYzsKCi8qKgogKiAgV3JhcCBvYmplY3RzIHRvIGVuYWJsZSB1bmNoZWNrZWQgZXhjZXB0aW9ucyB0byBiZSBjYXVnaHQgYW5kIGhhbmRsZWQuCiAqCiAqICBGb3IgZWFjaCBtZXRob2QsIGV4Y2VwdGlvbnMgYXJlIGhhbmRsZWQgYXMgZm9sbG93czoKICogIDx1bD4KICogIDxsaT5DaGVja2VkIGV4Y2VwdGlvbnMgYXJlIGxlZnQgYWxvbmUgYW5kIHByb3BvZ2F0ZSB1cHdhcmRzIGluIHRoZQogKiAgICAgIG9idmlvdXMgd2F5LCBzaW5jZSB0aGV5IGFyZSBhbiBleHBlY3RlZCBhc3BlY3Qgb2YgdGhlIG1ldGhvZCdzCiAqICAgICAgc3BlY2lmaWNhdGlvbi4KICogIDxsaT5VbmNoZWNrZWQgZXhjZXB0aW9ucyB3aGljaCBoYXZlIGFscmVhZHkgYmVlbiBjYXVnaHQgYW5kIHdyYXBwZWQgaW4KICogICAgICBDbGllbnRDb2RlRXhjZXB0aW9uIGFyZSBsZWZ0IGFsb25lIHRvIGNvbnRpbnVlIHByb3BvZ2F0aW5nIHVwd2FyZHMuCiAqICA8bGk+QWxsIG90aGVyIHVuY2hlY2tlZCBleGNlcHRpb25zIChpLmUuIHN1YnR5cGVzIG9mIFJ1bnRpbWVFeGNlcHRpb24KICogICAgICBhbmQgRXJyb3IpIGFuZCBjYXVnaHQsIGFuZCByZXRocm93biBhcyBhIENsaWVudENvZGVFeGNlcHRpb24gd2l0aAogKiAgICAgIGl0cyBjYXVzZSBzZXQgdG8gdGhlIG9yaWdpbmFsIGV4Y2VwdGlvbi4KICogIDwvdWw+CiAqCiAqICBUaGUgaW50ZW50IGlzIHRoYXQgQ2xpZW50Q29kZUV4Y2VwdGlvbiBjYW4gYmUgY2F1Z2h0IGF0IGFuIGFwcHJvcHJpYXRlIHBvaW50CiAqICBpbiB0aGUgcHJvZ3JhbSBhbmQgY2FuIGJlIGRpc3Rpbmd1aXNoZWQgZnJvbSBhbnkgdW5hbnRpY2lwYXRlZCB1bmNoZWNrZWQKICogIGV4Y2VwdGlvbnMgYXJpc2luZyBpbiB0aGUgbWFpbiBib2R5IG9mIHRoZSBjb2RlIChpLmUuIGJ1Z3MuKSBXaGVuIHRoZQogKiAgQ2xpZW50Q29kZUV4Y2VwdGlvbiBoYXMgYmVlbiBjYXVnaHQsIGVpdGhlciBhIHN1aXRhYmxlIG1lc3NhZ2UgY2FuIGJlCiAqICBnZW5lcmF0ZWQsIG9yIGlmIGFwcHJvcHJpYXRlLCB0aGUgb3JpZ2luYWwgY2F1c2UgY2FuIGJlIHJldGhyb3duLgogKgogKiAgPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24gcmlzay4KICogIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yCiAqICBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+CiAqLwpwdWJsaWMgY2xhc3MgQ2xpZW50Q29kZVdyYXBwZXIgewogICAgQFJldGVudGlvbihSZXRlbnRpb25Qb2xpY3kuUlVOVElNRSkKICAgIEBUYXJnZXQoRWxlbWVudFR5cGUuVFlQRSkKICAgIHB1YmxpYyBAaW50ZXJmYWNlIFRydXN0ZWQgeyB9CgogICAgcHVibGljIHN0YXRpYyBDbGllbnRDb2RlV3JhcHBlciBpbnN0YW5jZShDb250ZXh0IGNvbnRleHQpIHsKICAgICAgICBDbGllbnRDb2RlV3JhcHBlciBpbnN0YW5jZSA9IGNvbnRleHQuZ2V0KENsaWVudENvZGVXcmFwcGVyLmNsYXNzKTsKICAgICAgICBpZiAoaW5zdGFuY2UgPT0gbnVsbCkKICAgICAgICAgICAgaW5zdGFuY2UgPSBuZXcgQ2xpZW50Q29kZVdyYXBwZXIoY29udGV4dCk7CiAgICAgICAgcmV0dXJuIGluc3RhbmNlOwogICAgfQoKICAgIC8qKgogICAgICogQSBtYXAgdG8gY2FjaGUgdGhlIHJlc3VsdHMgb2Ygd2hldGhlciBvciBub3QgYSBzcGVjaWZpYyBjbGFzc2VzIGNhbgogICAgICogYmUgInRydXN0ZWQiLCBhbmQgdGh1cyBkb2VzIG5vdCBuZWVkIHRvIGJlIHdyYXBwZWQuCiAgICAgKi8KICAgIE1hcDxDbGFzczw/PiwgQm9vbGVhbj4gdHJ1c3RlZENsYXNzZXM7CgogICAgcHJvdGVjdGVkIENsaWVudENvZGVXcmFwcGVyKENvbnRleHQgY29udGV4dCkgewogICAgICAgIHRydXN0ZWRDbGFzc2VzID0gbmV3IEhhc2hNYXA8PigpOwogICAgfQoKICAgIHB1YmxpYyBKYXZhRmlsZU1hbmFnZXIgd3JhcChKYXZhRmlsZU1hbmFnZXIgZm0pIHsKICAgICAgICBpZiAoaXNUcnVzdGVkKGZtKSkKICAgICAgICAgICAgcmV0dXJuIGZtOwogICAgICAgIGlmIChmbSBpbnN0YW5jZW9mIFN0YW5kYXJkSmF2YUZpbGVNYW5hZ2VyKQogICAgICAgICAgICByZXR1cm4gbmV3IFdyYXBwZWRTdGFuZGFyZEphdmFGaWxlTWFuYWdlcigoU3RhbmRhcmRKYXZhRmlsZU1hbmFnZXIpIGZtKTsKICAgICAgICByZXR1cm4gbmV3IFdyYXBwZWRKYXZhRmlsZU1hbmFnZXIoZm0pOwogICAgfQoKICAgIHB1YmxpYyBGaWxlT2JqZWN0IHdyYXAoRmlsZU9iamVjdCBmbykgewogICAgICAgIGlmIChmbyA9PSBudWxsIHx8IGlzVHJ1c3RlZChmbykpCiAgICAgICAgICAgIHJldHVybiBmbzsKICAgICAgICByZXR1cm4gbmV3IFdyYXBwZWRGaWxlT2JqZWN0KGZvKTsKICAgIH0KCiAgICBGaWxlT2JqZWN0IHVud3JhcChGaWxlT2JqZWN0IGZvKSB7CiAgICAgICAgaWYgKGZvIGluc3RhbmNlb2YgV3JhcHBlZEZpbGVPYmplY3QpCiAgICAgICAgICAgIHJldHVybiAoKFdyYXBwZWRGaWxlT2JqZWN0KSBmbykuY2xpZW50RmlsZU9iamVjdDsKICAgICAgICBlbHNlCiAgICAgICAgICAgIHJldHVybiBmbzsKICAgIH0KCiAgICBwdWJsaWMgSmF2YUZpbGVPYmplY3Qgd3JhcChKYXZhRmlsZU9iamVjdCBmbykgewogICAgICAgIGlmIChmbyA9PSBudWxsIHx8IGlzVHJ1c3RlZChmbykpCiAgICAgICAgICAgIHJldHVybiBmbzsKICAgICAgICByZXR1cm4gbmV3IFdyYXBwZWRKYXZhRmlsZU9iamVjdChmbyk7CiAgICB9CgogICAgcHVibGljIEl0ZXJhYmxlPEphdmFGaWxlT2JqZWN0PiB3cmFwSmF2YUZpbGVPYmplY3RzKEl0ZXJhYmxlPD8gZXh0ZW5kcyBKYXZhRmlsZU9iamVjdD4gbGlzdCkgewogICAgICAgIExpc3Q8SmF2YUZpbGVPYmplY3Q+IHdyYXBwZWQgPSBuZXcgQXJyYXlMaXN0PD4oKTsKICAgICAgICBmb3IgKEphdmFGaWxlT2JqZWN0IGZvIDogbGlzdCkKICAgICAgICAgICAgd3JhcHBlZC5hZGQod3JhcChmbykpOwogICAgICAgIHJldHVybiBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHdyYXBwZWQpOwogICAgfQoKICAgIEphdmFGaWxlT2JqZWN0IHVud3JhcChKYXZhRmlsZU9iamVjdCBmbykgewogICAgICAgIGlmIChmbyBpbnN0YW5jZW9mIFdyYXBwZWRKYXZhRmlsZU9iamVjdCkKICAgICAgICAgICAgcmV0dXJuICgoSmF2YUZpbGVPYmplY3QpICgoV3JhcHBlZEphdmFGaWxlT2JqZWN0KSBmbykuY2xpZW50RmlsZU9iamVjdCk7CiAgICAgICAgZWxzZQogICAgICAgICAgICByZXR1cm4gZm87CiAgICB9CgogICAgcHVibGljIDxUIC8qc3VwZXIgSmF2YUZpbGVPamVjdCovPiBEaWFnbm9zdGljTGlzdGVuZXI8VD4gd3JhcChEaWFnbm9zdGljTGlzdGVuZXI8VD4gZGwpIHsKICAgICAgICBpZiAoaXNUcnVzdGVkKGRsKSkKICAgICAgICAgICAgcmV0dXJuIGRsOwogICAgICAgIHJldHVybiBuZXcgV3JhcHBlZERpYWdub3N0aWNMaXN0ZW5lcjw+KGRsKTsKICAgIH0KCiAgICBUYXNrTGlzdGVuZXIgd3JhcChUYXNrTGlzdGVuZXIgdGwpIHsKICAgICAgICBpZiAoaXNUcnVzdGVkKHRsKSkKICAgICAgICAgICAgcmV0dXJuIHRsOwogICAgICAgIHJldHVybiBuZXcgV3JhcHBlZFRhc2tMaXN0ZW5lcih0bCk7CiAgICB9CgogICAgVGFza0xpc3RlbmVyIHVud3JhcChUYXNrTGlzdGVuZXIgbCkgewogICAgICAgIGlmIChsIGluc3RhbmNlb2YgV3JhcHBlZFRhc2tMaXN0ZW5lcikKICAgICAgICAgICAgcmV0dXJuICgoV3JhcHBlZFRhc2tMaXN0ZW5lcikgbCkuY2xpZW50VGFza0xpc3RlbmVyOwogICAgICAgIGVsc2UKICAgICAgICAgICAgcmV0dXJuIGw7CiAgICB9CgogICAgQ29sbGVjdGlvbjxUYXNrTGlzdGVuZXI+IHVud3JhcChDb2xsZWN0aW9uPD8gZXh0ZW5kcyBUYXNrTGlzdGVuZXI+IGxpc3RlbmVycykgewogICAgICAgIENvbGxlY3Rpb248VGFza0xpc3RlbmVyPiBjID0gbmV3IEFycmF5TGlzdDw+KGxpc3RlbmVycy5zaXplKCkpOwogICAgICAgIGZvciAoVGFza0xpc3RlbmVyIGw6IGxpc3RlbmVycykKICAgICAgICAgICAgYy5hZGQodW53cmFwKGwpKTsKICAgICAgICByZXR1cm4gYzsKICAgIH0KCiAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKICAgIHByaXZhdGUgPFQ+IERpYWdub3N0aWM8VD4gdW53cmFwKGZpbmFsIERpYWdub3N0aWM8VD4gZGlhZ25vc3RpYykgewogICAgICAgIGlmIChkaWFnbm9zdGljIGluc3RhbmNlb2YgSkNEaWFnbm9zdGljKSB7CiAgICAgICAgICAgIEpDRGlhZ25vc3RpYyBkID0gKEpDRGlhZ25vc3RpYykgZGlhZ25vc3RpYzsKICAgICAgICAgICAgcmV0dXJuIChEaWFnbm9zdGljPFQ+KSBuZXcgRGlhZ25vc3RpY1NvdXJjZVVud3JhcHBlcihkKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gZGlhZ25vc3RpYzsKICAgICAgICB9CiAgICB9CgogICAgcHJvdGVjdGVkIGJvb2xlYW4gaXNUcnVzdGVkKE9iamVjdCBvKSB7CiAgICAgICAgQ2xhc3M8Pz4gYyA9IG8uZ2V0Q2xhc3MoKTsKICAgICAgICBCb29sZWFuIHRydXN0ZWQgPSB0cnVzdGVkQ2xhc3Nlcy5nZXQoYyk7CiAgICAgICAgaWYgKHRydXN0ZWQgPT0gbnVsbCkgewogICAgICAgICAgICB0cnVzdGVkID0gYy5nZXROYW1lKCkuc3RhcnRzV2l0aCgiY29tLnN1bi50b29scy5qYXZhYy4iKQogICAgICAgICAgICAgICAgICAgIHx8IGMuaXNBbm5vdGF0aW9uUHJlc2VudChUcnVzdGVkLmNsYXNzKTsKICAgICAgICAgICAgdHJ1c3RlZENsYXNzZXMucHV0KGMsIHRydXN0ZWQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdHJ1c3RlZDsKICAgIH0KCiAgICBwcml2YXRlIFN0cmluZyB3cmFwcGVkVG9TdHJpbmcoQ2xhc3M8Pz4gd3JhcHBlckNsYXNzLCBPYmplY3Qgd3JhcHBlZCkgewogICAgICAgIHJldHVybiB3cmFwcGVyQ2xhc3MuZ2V0U2ltcGxlTmFtZSgpICsgIlsiICsgd3JhcHBlZCArICJdIjsKICAgIH0KCiAgICAvLyA8ZWRpdG9yLWZvbGQgZGVmYXVsdHN0YXRlPSJjb2xsYXBzZWQiIGRlc2M9IldyYXBwZXIgY2xhc3NlcyI+CgogICAgcHJvdGVjdGVkIGNsYXNzIFdyYXBwZWRKYXZhRmlsZU1hbmFnZXIgaW1wbGVtZW50cyBKYXZhRmlsZU1hbmFnZXIgewogICAgICAgIHByb3RlY3RlZCBKYXZhRmlsZU1hbmFnZXIgY2xpZW50SmF2YUZpbGVNYW5hZ2VyOwogICAgICAgIFdyYXBwZWRKYXZhRmlsZU1hbmFnZXIoSmF2YUZpbGVNYW5hZ2VyIGNsaWVudEphdmFGaWxlTWFuYWdlcikgewogICAgICAgICAgICB0aGlzLmNsaWVudEphdmFGaWxlTWFuYWdlciA9IE9iamVjdHMucmVxdWlyZU5vbk51bGwoY2xpZW50SmF2YUZpbGVNYW5hZ2VyKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgICAgICBwdWJsaWMgQ2xhc3NMb2FkZXIgZ2V0Q2xhc3NMb2FkZXIoTG9jYXRpb24gbG9jYXRpb24pIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIHJldHVybiBjbGllbnRKYXZhRmlsZU1hbmFnZXIuZ2V0Q2xhc3NMb2FkZXIobG9jYXRpb24pOwogICAgICAgICAgICB9IGNhdGNoIChDbGllbnRDb2RlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgICAgIHRocm93IGU7CiAgICAgICAgICAgIH0gY2F0Y2ggKFJ1bnRpbWVFeGNlcHRpb24gfCBFcnJvciBlKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ2xpZW50Q29kZUV4Y2VwdGlvbihlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSKQogICAgICAgIHB1YmxpYyBJdGVyYWJsZTxKYXZhRmlsZU9iamVjdD4gbGlzdChMb2NhdGlvbiBsb2NhdGlvbiwgU3RyaW5nIHBhY2thZ2VOYW1lLCBTZXQ8S2luZD4ga2luZHMsIGJvb2xlYW4gcmVjdXJzZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIHJldHVybiB3cmFwSmF2YUZpbGVPYmplY3RzKGNsaWVudEphdmFGaWxlTWFuYWdlci5saXN0KGxvY2F0aW9uLCBwYWNrYWdlTmFtZSwga2luZHMsIHJlY3Vyc2UpKTsKICAgICAgICAgICAgfSBjYXRjaCAoQ2xpZW50Q29kZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBlOwogICAgICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIHwgRXJyb3IgZSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IENsaWVudENvZGVFeGNlcHRpb24oZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgICAgICBwdWJsaWMgU3RyaW5nIGluZmVyQmluYXJ5TmFtZShMb2NhdGlvbiBsb2NhdGlvbiwgSmF2YUZpbGVPYmplY3QgZmlsZSkgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgcmV0dXJuIGNsaWVudEphdmFGaWxlTWFuYWdlci5pbmZlckJpbmFyeU5hbWUobG9jYXRpb24sIHVud3JhcChmaWxlKSk7CiAgICAgICAgICAgIH0gY2F0Y2ggKENsaWVudENvZGVFeGNlcHRpb24gZSkgewogICAgICAgICAgICAgICAgdGhyb3cgZTsKICAgICAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiB8IEVycm9yIGUpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBDbGllbnRDb2RlRXhjZXB0aW9uKGUpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICAgICAgcHVibGljIGJvb2xlYW4gaXNTYW1lRmlsZShGaWxlT2JqZWN0IGEsIEZpbGVPYmplY3QgYikgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgcmV0dXJuIGNsaWVudEphdmFGaWxlTWFuYWdlci5pc1NhbWVGaWxlKHVud3JhcChhKSwgdW53cmFwKGIpKTsKICAgICAgICAgICAgfSBjYXRjaCAoQ2xpZW50Q29kZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBlOwogICAgICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIHwgRXJyb3IgZSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IENsaWVudENvZGVFeGNlcHRpb24oZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYW5kbGVPcHRpb24oU3RyaW5nIGN1cnJlbnQsIEl0ZXJhdG9yPFN0cmluZz4gcmVtYWluaW5nKSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICByZXR1cm4gY2xpZW50SmF2YUZpbGVNYW5hZ2VyLmhhbmRsZU9wdGlvbihjdXJyZW50LCByZW1haW5pbmcpOwogICAgICAgICAgICB9IGNhdGNoIChDbGllbnRDb2RlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgICAgIHRocm93IGU7CiAgICAgICAgICAgIH0gY2F0Y2ggKFJ1bnRpbWVFeGNlcHRpb24gfCBFcnJvciBlKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ2xpZW50Q29kZUV4Y2VwdGlvbihlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSKQogICAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvY2F0aW9uKExvY2F0aW9uIGxvY2F0aW9uKSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICByZXR1cm4gY2xpZW50SmF2YUZpbGVNYW5hZ2VyLmhhc0xvY2F0aW9uKGxvY2F0aW9uKTsKICAgICAgICAgICAgfSBjYXRjaCAoQ2xpZW50Q29kZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBlOwogICAgICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIHwgRXJyb3IgZSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IENsaWVudENvZGVFeGNlcHRpb24oZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgICAgICBwdWJsaWMgSmF2YUZpbGVPYmplY3QgZ2V0SmF2YUZpbGVGb3JJbnB1dChMb2NhdGlvbiBsb2NhdGlvbiwgU3RyaW5nIGNsYXNzTmFtZSwgS2luZCBraW5kKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgcmV0dXJuIHdyYXAoY2xpZW50SmF2YUZpbGVNYW5hZ2VyLmdldEphdmFGaWxlRm9ySW5wdXQobG9jYXRpb24sIGNsYXNzTmFtZSwga2luZCkpOwogICAgICAgICAgICB9IGNhdGNoIChDbGllbnRDb2RlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgICAgIHRocm93IGU7CiAgICAgICAgICAgIH0gY2F0Y2ggKFJ1bnRpbWVFeGNlcHRpb24gfCBFcnJvciBlKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ2xpZW50Q29kZUV4Y2VwdGlvbihlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSKQogICAgICAgIHB1YmxpYyBKYXZhRmlsZU9iamVjdCBnZXRKYXZhRmlsZUZvck91dHB1dChMb2NhdGlvbiBsb2NhdGlvbiwgU3RyaW5nIGNsYXNzTmFtZSwgS2luZCBraW5kLCBGaWxlT2JqZWN0IHNpYmxpbmcpIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICByZXR1cm4gd3JhcChjbGllbnRKYXZhRmlsZU1hbmFnZXIuZ2V0SmF2YUZpbGVGb3JPdXRwdXQobG9jYXRpb24sIGNsYXNzTmFtZSwga2luZCwgdW53cmFwKHNpYmxpbmcpKSk7CiAgICAgICAgICAgIH0gY2F0Y2ggKENsaWVudENvZGVFeGNlcHRpb24gZSkgewogICAgICAgICAgICAgICAgdGhyb3cgZTsKICAgICAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiB8IEVycm9yIGUpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBDbGllbnRDb2RlRXhjZXB0aW9uKGUpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICAgICAgcHVibGljIEZpbGVPYmplY3QgZ2V0RmlsZUZvcklucHV0KExvY2F0aW9uIGxvY2F0aW9uLCBTdHJpbmcgcGFja2FnZU5hbWUsIFN0cmluZyByZWxhdGl2ZU5hbWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICByZXR1cm4gd3JhcChjbGllbnRKYXZhRmlsZU1hbmFnZXIuZ2V0RmlsZUZvcklucHV0KGxvY2F0aW9uLCBwYWNrYWdlTmFtZSwgcmVsYXRpdmVOYW1lKSk7CiAgICAgICAgICAgIH0gY2F0Y2ggKENsaWVudENvZGVFeGNlcHRpb24gZSkgewogICAgICAgICAgICAgICAgdGhyb3cgZTsKICAgICAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiB8IEVycm9yIGUpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBDbGllbnRDb2RlRXhjZXB0aW9uKGUpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICAgICAgcHVibGljIEZpbGVPYmplY3QgZ2V0RmlsZUZvck91dHB1dChMb2NhdGlvbiBsb2NhdGlvbiwgU3RyaW5nIHBhY2thZ2VOYW1lLCBTdHJpbmcgcmVsYXRpdmVOYW1lLCBGaWxlT2JqZWN0IHNpYmxpbmcpIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICByZXR1cm4gd3JhcChjbGllbnRKYXZhRmlsZU1hbmFnZXIuZ2V0RmlsZUZvck91dHB1dChsb2NhdGlvbiwgcGFja2FnZU5hbWUsIHJlbGF0aXZlTmFtZSwgdW53cmFwKHNpYmxpbmcpKSk7CiAgICAgICAgICAgIH0gY2F0Y2ggKENsaWVudENvZGVFeGNlcHRpb24gZSkgewogICAgICAgICAgICAgICAgdGhyb3cgZTsKICAgICAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiB8IEVycm9yIGUpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBDbGllbnRDb2RlRXhjZXB0aW9uKGUpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICAgICAgcHVibGljIHZvaWQgZmx1c2goKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgY2xpZW50SmF2YUZpbGVNYW5hZ2VyLmZsdXNoKCk7CiAgICAgICAgICAgIH0gY2F0Y2ggKENsaWVudENvZGVFeGNlcHRpb24gZSkgewogICAgICAgICAgICAgICAgdGhyb3cgZTsKICAgICAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiB8IEVycm9yIGUpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBDbGllbnRDb2RlRXhjZXB0aW9uKGUpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICAgICAgcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgY2xpZW50SmF2YUZpbGVNYW5hZ2VyLmNsb3NlKCk7CiAgICAgICAgICAgIH0gY2F0Y2ggKENsaWVudENvZGVFeGNlcHRpb24gZSkgewogICAgICAgICAgICAgICAgdGhyb3cgZTsKICAgICAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiB8IEVycm9yIGUpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBDbGllbnRDb2RlRXhjZXB0aW9uKGUpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICAgICAgcHVibGljIExvY2F0aW9uIGdldExvY2F0aW9uRm9yTW9kdWxlKExvY2F0aW9uIGxvY2F0aW9uLCBTdHJpbmcgbW9kdWxlTmFtZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIHJldHVybiBjbGllbnRKYXZhRmlsZU1hbmFnZXIuZ2V0TG9jYXRpb25Gb3JNb2R1bGUobG9jYXRpb24sIG1vZHVsZU5hbWUpOwogICAgICAgICAgICB9IGNhdGNoIChDbGllbnRDb2RlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgICAgIHRocm93IGU7CiAgICAgICAgICAgIH0gY2F0Y2ggKFJ1bnRpbWVFeGNlcHRpb24gfCBFcnJvciBlKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ2xpZW50Q29kZUV4Y2VwdGlvbihlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSKQogICAgICAgIHB1YmxpYyBMb2NhdGlvbiBnZXRMb2NhdGlvbkZvck1vZHVsZShMb2NhdGlvbiBsb2NhdGlvbiwgSmF2YUZpbGVPYmplY3QgZm8pIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICByZXR1cm4gY2xpZW50SmF2YUZpbGVNYW5hZ2VyLmdldExvY2F0aW9uRm9yTW9kdWxlKGxvY2F0aW9uLCB1bndyYXAoZm8pKTsKICAgICAgICAgICAgfSBjYXRjaCAoQ2xpZW50Q29kZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBlOwogICAgICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIHwgRXJyb3IgZSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IENsaWVudENvZGVFeGNlcHRpb24oZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgICAgICBwdWJsaWMgU3RyaW5nIGluZmVyTW9kdWxlTmFtZShMb2NhdGlvbiBsb2NhdGlvbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIHJldHVybiBjbGllbnRKYXZhRmlsZU1hbmFnZXIuaW5mZXJNb2R1bGVOYW1lKGxvY2F0aW9uKTsKICAgICAgICAgICAgfSBjYXRjaCAoQ2xpZW50Q29kZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBlOwogICAgICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIHwgRXJyb3IgZSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IENsaWVudENvZGVFeGNlcHRpb24oZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgICAgICBwdWJsaWMgSXRlcmFibGU8U2V0PExvY2F0aW9uPj4gbGlzdExvY2F0aW9uc0Zvck1vZHVsZXMoTG9jYXRpb24gbG9jYXRpb24pIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICByZXR1cm4gY2xpZW50SmF2YUZpbGVNYW5hZ2VyLmxpc3RMb2NhdGlvbnNGb3JNb2R1bGVzKGxvY2F0aW9uKTsKICAgICAgICAgICAgfSBjYXRjaCAoQ2xpZW50Q29kZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBlOwogICAgICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIHwgRXJyb3IgZSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IENsaWVudENvZGVFeGNlcHRpb24oZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgICAgICBwdWJsaWMgaW50IGlzU3VwcG9ydGVkT3B0aW9uKFN0cmluZyBvcHRpb24pIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIHJldHVybiBjbGllbnRKYXZhRmlsZU1hbmFnZXIuaXNTdXBwb3J0ZWRPcHRpb24ob3B0aW9uKTsKICAgICAgICAgICAgfSBjYXRjaCAoQ2xpZW50Q29kZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBlOwogICAgICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIHwgRXJyb3IgZSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IENsaWVudENvZGVFeGNlcHRpb24oZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CiAgICAgICAgICAgIHJldHVybiB3cmFwcGVkVG9TdHJpbmcoZ2V0Q2xhc3MoKSwgY2xpZW50SmF2YUZpbGVNYW5hZ2VyKTsKICAgICAgICB9CiAgICB9CgogICAgcHJvdGVjdGVkIGNsYXNzIFdyYXBwZWRTdGFuZGFyZEphdmFGaWxlTWFuYWdlciBleHRlbmRzIFdyYXBwZWRKYXZhRmlsZU1hbmFnZXIKICAgICAgICAgICAgaW1wbGVtZW50cyBTdGFuZGFyZEphdmFGaWxlTWFuYWdlciB7CiAgICAgICAgV3JhcHBlZFN0YW5kYXJkSmF2YUZpbGVNYW5hZ2VyKFN0YW5kYXJkSmF2YUZpbGVNYW5hZ2VyIGNsaWVudEphdmFGaWxlTWFuYWdlcikgewogICAgICAgICAgICBzdXBlcihjbGllbnRKYXZhRmlsZU1hbmFnZXIpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSKQogICAgICAgIHB1YmxpYyBJdGVyYWJsZTw/IGV4dGVuZHMgSmF2YUZpbGVPYmplY3Q+IGdldEphdmFGaWxlT2JqZWN0c0Zyb21GaWxlcyhJdGVyYWJsZTw/IGV4dGVuZHMgRmlsZT4gZmlsZXMpIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIHJldHVybiAoKFN0YW5kYXJkSmF2YUZpbGVNYW5hZ2VyKWNsaWVudEphdmFGaWxlTWFuYWdlcikuZ2V0SmF2YUZpbGVPYmplY3RzRnJvbUZpbGVzKGZpbGVzKTsKICAgICAgICAgICAgfSBjYXRjaCAoQ2xpZW50Q29kZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBlOwogICAgICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIHwgRXJyb3IgZSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IENsaWVudENvZGVFeGNlcHRpb24oZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgICAgICBwdWJsaWMgSXRlcmFibGU8PyBleHRlbmRzIEphdmFGaWxlT2JqZWN0PiBnZXRKYXZhRmlsZU9iamVjdHNGcm9tUGF0aHMoSXRlcmFibGU8PyBleHRlbmRzIFBhdGg+IHBhdGhzKSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICByZXR1cm4gKChTdGFuZGFyZEphdmFGaWxlTWFuYWdlciljbGllbnRKYXZhRmlsZU1hbmFnZXIpLmdldEphdmFGaWxlT2JqZWN0c0Zyb21QYXRocyhwYXRocyk7CiAgICAgICAgICAgIH0gY2F0Y2ggKENsaWVudENvZGVFeGNlcHRpb24gZSkgewogICAgICAgICAgICAgICAgdGhyb3cgZTsKICAgICAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiB8IEVycm9yIGUpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBDbGllbnRDb2RlRXhjZXB0aW9uKGUpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICAgICAgcHVibGljIEl0ZXJhYmxlPD8gZXh0ZW5kcyBKYXZhRmlsZU9iamVjdD4gZ2V0SmF2YUZpbGVPYmplY3RzKEZpbGUuLi4gZmlsZXMpIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIHJldHVybiAoKFN0YW5kYXJkSmF2YUZpbGVNYW5hZ2VyKWNsaWVudEphdmFGaWxlTWFuYWdlcikuZ2V0SmF2YUZpbGVPYmplY3RzKGZpbGVzKTsKICAgICAgICAgICAgfSBjYXRjaCAoQ2xpZW50Q29kZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBlOwogICAgICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIHwgRXJyb3IgZSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IENsaWVudENvZGVFeGNlcHRpb24oZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgICAgICBwdWJsaWMgSXRlcmFibGU8PyBleHRlbmRzIEphdmFGaWxlT2JqZWN0PiBnZXRKYXZhRmlsZU9iamVjdHMoUGF0aC4uLiBwYXRocykgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgcmV0dXJuICgoU3RhbmRhcmRKYXZhRmlsZU1hbmFnZXIpY2xpZW50SmF2YUZpbGVNYW5hZ2VyKS5nZXRKYXZhRmlsZU9iamVjdHMocGF0aHMpOwogICAgICAgICAgICB9IGNhdGNoIChDbGllbnRDb2RlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgICAgIHRocm93IGU7CiAgICAgICAgICAgIH0gY2F0Y2ggKFJ1bnRpbWVFeGNlcHRpb24gfCBFcnJvciBlKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ2xpZW50Q29kZUV4Y2VwdGlvbihlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSKQogICAgICAgIHB1YmxpYyBJdGVyYWJsZTw/IGV4dGVuZHMgSmF2YUZpbGVPYmplY3Q+IGdldEphdmFGaWxlT2JqZWN0c0Zyb21TdHJpbmdzKEl0ZXJhYmxlPFN0cmluZz4gbmFtZXMpIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIHJldHVybiAoKFN0YW5kYXJkSmF2YUZpbGVNYW5hZ2VyKWNsaWVudEphdmFGaWxlTWFuYWdlcikuZ2V0SmF2YUZpbGVPYmplY3RzRnJvbVN0cmluZ3MobmFtZXMpOwogICAgICAgICAgICB9IGNhdGNoIChDbGllbnRDb2RlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgICAgIHRocm93IGU7CiAgICAgICAgICAgIH0gY2F0Y2ggKFJ1bnRpbWVFeGNlcHRpb24gfCBFcnJvciBlKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ2xpZW50Q29kZUV4Y2VwdGlvbihlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSKQogICAgICAgIHB1YmxpYyBJdGVyYWJsZTw/IGV4dGVuZHMgSmF2YUZpbGVPYmplY3Q+IGdldEphdmFGaWxlT2JqZWN0cyhTdHJpbmcuLi4gbmFtZXMpIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIHJldHVybiAoKFN0YW5kYXJkSmF2YUZpbGVNYW5hZ2VyKWNsaWVudEphdmFGaWxlTWFuYWdlcikuZ2V0SmF2YUZpbGVPYmplY3RzKG5hbWVzKTsKICAgICAgICAgICAgfSBjYXRjaCAoQ2xpZW50Q29kZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBlOwogICAgICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIHwgRXJyb3IgZSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IENsaWVudENvZGVFeGNlcHRpb24oZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgICAgICBwdWJsaWMgdm9pZCBzZXRMb2NhdGlvbihMb2NhdGlvbiBsb2NhdGlvbiwgSXRlcmFibGU8PyBleHRlbmRzIEZpbGU+IGZpbGVzKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgKChTdGFuZGFyZEphdmFGaWxlTWFuYWdlciljbGllbnRKYXZhRmlsZU1hbmFnZXIpLnNldExvY2F0aW9uKGxvY2F0aW9uLCBmaWxlcyk7CiAgICAgICAgICAgIH0gY2F0Y2ggKENsaWVudENvZGVFeGNlcHRpb24gZSkgewogICAgICAgICAgICAgICAgdGhyb3cgZTsKICAgICAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiB8IEVycm9yIGUpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBDbGllbnRDb2RlRXhjZXB0aW9uKGUpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICAgICAgcHVibGljIHZvaWQgc2V0TG9jYXRpb25Gcm9tUGF0aHMoTG9jYXRpb24gbG9jYXRpb24sIENvbGxlY3Rpb248PyBleHRlbmRzIFBhdGg+IHBhdGhzKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgKChTdGFuZGFyZEphdmFGaWxlTWFuYWdlciljbGllbnRKYXZhRmlsZU1hbmFnZXIpLnNldExvY2F0aW9uRnJvbVBhdGhzKGxvY2F0aW9uLCBwYXRocyk7CiAgICAgICAgICAgIH0gY2F0Y2ggKENsaWVudENvZGVFeGNlcHRpb24gZSkgewogICAgICAgICAgICAgICAgdGhyb3cgZTsKICAgICAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiB8IEVycm9yIGUpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBDbGllbnRDb2RlRXhjZXB0aW9uKGUpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICAgICAgcHVibGljIEl0ZXJhYmxlPD8gZXh0ZW5kcyBGaWxlPiBnZXRMb2NhdGlvbihMb2NhdGlvbiBsb2NhdGlvbikgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgcmV0dXJuICgoU3RhbmRhcmRKYXZhRmlsZU1hbmFnZXIpY2xpZW50SmF2YUZpbGVNYW5hZ2VyKS5nZXRMb2NhdGlvbihsb2NhdGlvbik7CiAgICAgICAgICAgIH0gY2F0Y2ggKENsaWVudENvZGVFeGNlcHRpb24gZSkgewogICAgICAgICAgICAgICAgdGhyb3cgZTsKICAgICAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiB8IEVycm9yIGUpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBDbGllbnRDb2RlRXhjZXB0aW9uKGUpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICAgICAgcHVibGljIEl0ZXJhYmxlPD8gZXh0ZW5kcyBQYXRoPiBnZXRMb2NhdGlvbkFzUGF0aHMoTG9jYXRpb24gbG9jYXRpb24pIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIHJldHVybiAoKFN0YW5kYXJkSmF2YUZpbGVNYW5hZ2VyKWNsaWVudEphdmFGaWxlTWFuYWdlcikuZ2V0TG9jYXRpb25Bc1BhdGhzKGxvY2F0aW9uKTsKICAgICAgICAgICAgfSBjYXRjaCAoQ2xpZW50Q29kZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBlOwogICAgICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIHwgRXJyb3IgZSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IENsaWVudENvZGVFeGNlcHRpb24oZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgICAgICBwdWJsaWMgUGF0aCBhc1BhdGgoRmlsZU9iamVjdCBmaWxlKSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICByZXR1cm4gKChTdGFuZGFyZEphdmFGaWxlTWFuYWdlciljbGllbnRKYXZhRmlsZU1hbmFnZXIpLmFzUGF0aChmaWxlKTsKICAgICAgICAgICAgfSBjYXRjaCAoQ2xpZW50Q29kZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBlOwogICAgICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIHwgRXJyb3IgZSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IENsaWVudENvZGVFeGNlcHRpb24oZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgICAgICBwdWJsaWMgdm9pZCBzZXRQYXRoRmFjdG9yeShQYXRoRmFjdG9yeSBmKSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAoKFN0YW5kYXJkSmF2YUZpbGVNYW5hZ2VyKWNsaWVudEphdmFGaWxlTWFuYWdlcikuc2V0UGF0aEZhY3RvcnkoZik7CiAgICAgICAgICAgIH0gY2F0Y2ggKENsaWVudENvZGVFeGNlcHRpb24gZSkgewogICAgICAgICAgICAgICAgdGhyb3cgZTsKICAgICAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiB8IEVycm9yIGUpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBDbGllbnRDb2RlRXhjZXB0aW9uKGUpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIHByb3RlY3RlZCBjbGFzcyBXcmFwcGVkRmlsZU9iamVjdCBpbXBsZW1lbnRzIEZpbGVPYmplY3QgewogICAgICAgIHByb3RlY3RlZCBGaWxlT2JqZWN0IGNsaWVudEZpbGVPYmplY3Q7CiAgICAgICAgV3JhcHBlZEZpbGVPYmplY3QoRmlsZU9iamVjdCBjbGllbnRGaWxlT2JqZWN0KSB7CiAgICAgICAgICAgIHRoaXMuY2xpZW50RmlsZU9iamVjdCA9IE9iamVjdHMucmVxdWlyZU5vbk51bGwoY2xpZW50RmlsZU9iamVjdCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICAgICAgcHVibGljIFVSSSB0b1VyaSgpIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIHJldHVybiBjbGllbnRGaWxlT2JqZWN0LnRvVXJpKCk7CiAgICAgICAgICAgIH0gY2F0Y2ggKENsaWVudENvZGVFeGNlcHRpb24gZSkgewogICAgICAgICAgICAgICAgdGhyb3cgZTsKICAgICAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiB8IEVycm9yIGUpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBDbGllbnRDb2RlRXhjZXB0aW9uKGUpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICAgICAgcHVibGljIFN0cmluZyBnZXROYW1lKCkgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgcmV0dXJuIGNsaWVudEZpbGVPYmplY3QuZ2V0TmFtZSgpOwogICAgICAgICAgICB9IGNhdGNoIChDbGllbnRDb2RlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgICAgIHRocm93IGU7CiAgICAgICAgICAgIH0gY2F0Y2ggKFJ1bnRpbWVFeGNlcHRpb24gfCBFcnJvciBlKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ2xpZW50Q29kZUV4Y2VwdGlvbihlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSKQogICAgICAgIHB1YmxpYyBJbnB1dFN0cmVhbSBvcGVuSW5wdXRTdHJlYW0oKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgcmV0dXJuIGNsaWVudEZpbGVPYmplY3Qub3BlbklucHV0U3RyZWFtKCk7CiAgICAgICAgICAgIH0gY2F0Y2ggKENsaWVudENvZGVFeGNlcHRpb24gZSkgewogICAgICAgICAgICAgICAgdGhyb3cgZTsKICAgICAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiB8IEVycm9yIGUpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBDbGllbnRDb2RlRXhjZXB0aW9uKGUpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICAgICAgcHVibGljIE91dHB1dFN0cmVhbSBvcGVuT3V0cHV0U3RyZWFtKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIHJldHVybiBjbGllbnRGaWxlT2JqZWN0Lm9wZW5PdXRwdXRTdHJlYW0oKTsKICAgICAgICAgICAgfSBjYXRjaCAoQ2xpZW50Q29kZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBlOwogICAgICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIHwgRXJyb3IgZSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IENsaWVudENvZGVFeGNlcHRpb24oZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgICAgICBwdWJsaWMgUmVhZGVyIG9wZW5SZWFkZXIoYm9vbGVhbiBpZ25vcmVFbmNvZGluZ0Vycm9ycykgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIHJldHVybiBjbGllbnRGaWxlT2JqZWN0Lm9wZW5SZWFkZXIoaWdub3JlRW5jb2RpbmdFcnJvcnMpOwogICAgICAgICAgICB9IGNhdGNoIChDbGllbnRDb2RlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgICAgIHRocm93IGU7CiAgICAgICAgICAgIH0gY2F0Y2ggKFJ1bnRpbWVFeGNlcHRpb24gfCBFcnJvciBlKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ2xpZW50Q29kZUV4Y2VwdGlvbihlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSKQogICAgICAgIHB1YmxpYyBDaGFyU2VxdWVuY2UgZ2V0Q2hhckNvbnRlbnQoYm9vbGVhbiBpZ25vcmVFbmNvZGluZ0Vycm9ycykgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIHJldHVybiBjbGllbnRGaWxlT2JqZWN0LmdldENoYXJDb250ZW50KGlnbm9yZUVuY29kaW5nRXJyb3JzKTsKICAgICAgICAgICAgfSBjYXRjaCAoQ2xpZW50Q29kZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBlOwogICAgICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIHwgRXJyb3IgZSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IENsaWVudENvZGVFeGNlcHRpb24oZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgICAgICBwdWJsaWMgV3JpdGVyIG9wZW5Xcml0ZXIoKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgcmV0dXJuIGNsaWVudEZpbGVPYmplY3Qub3BlbldyaXRlcigpOwogICAgICAgICAgICB9IGNhdGNoIChDbGllbnRDb2RlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgICAgIHRocm93IGU7CiAgICAgICAgICAgIH0gY2F0Y2ggKFJ1bnRpbWVFeGNlcHRpb24gfCBFcnJvciBlKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ2xpZW50Q29kZUV4Y2VwdGlvbihlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSKQogICAgICAgIHB1YmxpYyBsb25nIGdldExhc3RNb2RpZmllZCgpIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIHJldHVybiBjbGllbnRGaWxlT2JqZWN0LmdldExhc3RNb2RpZmllZCgpOwogICAgICAgICAgICB9IGNhdGNoIChDbGllbnRDb2RlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgICAgIHRocm93IGU7CiAgICAgICAgICAgIH0gY2F0Y2ggKFJ1bnRpbWVFeGNlcHRpb24gfCBFcnJvciBlKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ2xpZW50Q29kZUV4Y2VwdGlvbihlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSKQogICAgICAgIHB1YmxpYyBib29sZWFuIGRlbGV0ZSgpIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIHJldHVybiBjbGllbnRGaWxlT2JqZWN0LmRlbGV0ZSgpOwogICAgICAgICAgICB9IGNhdGNoIChDbGllbnRDb2RlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgICAgIHRocm93IGU7CiAgICAgICAgICAgIH0gY2F0Y2ggKFJ1bnRpbWVFeGNlcHRpb24gfCBFcnJvciBlKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ2xpZW50Q29kZUV4Y2VwdGlvbihlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKICAgICAgICAgICAgcmV0dXJuIHdyYXBwZWRUb1N0cmluZyhnZXRDbGFzcygpLCBjbGllbnRGaWxlT2JqZWN0KTsKICAgICAgICB9CiAgICB9CgogICAgcHJvdGVjdGVkIGNsYXNzIFdyYXBwZWRKYXZhRmlsZU9iamVjdCBleHRlbmRzIFdyYXBwZWRGaWxlT2JqZWN0IGltcGxlbWVudHMgSmF2YUZpbGVPYmplY3QgewogICAgICAgIFdyYXBwZWRKYXZhRmlsZU9iamVjdChKYXZhRmlsZU9iamVjdCBjbGllbnRKYXZhRmlsZU9iamVjdCkgewogICAgICAgICAgICBzdXBlcihjbGllbnRKYXZhRmlsZU9iamVjdCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICAgICAgcHVibGljIEtpbmQgZ2V0S2luZCgpIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIHJldHVybiAoKEphdmFGaWxlT2JqZWN0KWNsaWVudEZpbGVPYmplY3QpLmdldEtpbmQoKTsKICAgICAgICAgICAgfSBjYXRjaCAoQ2xpZW50Q29kZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBlOwogICAgICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIHwgRXJyb3IgZSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IENsaWVudENvZGVFeGNlcHRpb24oZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc05hbWVDb21wYXRpYmxlKFN0cmluZyBzaW1wbGVOYW1lLCBLaW5kIGtpbmQpIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIHJldHVybiAoKEphdmFGaWxlT2JqZWN0KWNsaWVudEZpbGVPYmplY3QpLmlzTmFtZUNvbXBhdGlibGUoc2ltcGxlTmFtZSwga2luZCk7CiAgICAgICAgICAgIH0gY2F0Y2ggKENsaWVudENvZGVFeGNlcHRpb24gZSkgewogICAgICAgICAgICAgICAgdGhyb3cgZTsKICAgICAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiB8IEVycm9yIGUpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBDbGllbnRDb2RlRXhjZXB0aW9uKGUpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICAgICAgcHVibGljIE5lc3RpbmdLaW5kIGdldE5lc3RpbmdLaW5kKCkgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgcmV0dXJuICgoSmF2YUZpbGVPYmplY3QpY2xpZW50RmlsZU9iamVjdCkuZ2V0TmVzdGluZ0tpbmQoKTsKICAgICAgICAgICAgfSBjYXRjaCAoQ2xpZW50Q29kZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBlOwogICAgICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIHwgRXJyb3IgZSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IENsaWVudENvZGVFeGNlcHRpb24oZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgICAgICBwdWJsaWMgTW9kaWZpZXIgZ2V0QWNjZXNzTGV2ZWwoKSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICByZXR1cm4gKChKYXZhRmlsZU9iamVjdCljbGllbnRGaWxlT2JqZWN0KS5nZXRBY2Nlc3NMZXZlbCgpOwogICAgICAgICAgICB9IGNhdGNoIChDbGllbnRDb2RlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgICAgIHRocm93IGU7CiAgICAgICAgICAgIH0gY2F0Y2ggKFJ1bnRpbWVFeGNlcHRpb24gfCBFcnJvciBlKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ2xpZW50Q29kZUV4Y2VwdGlvbihlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKICAgICAgICAgICAgcmV0dXJuIHdyYXBwZWRUb1N0cmluZyhnZXRDbGFzcygpLCBjbGllbnRGaWxlT2JqZWN0KTsKICAgICAgICB9CiAgICB9CgogICAgcHJvdGVjdGVkIGNsYXNzIFdyYXBwZWREaWFnbm9zdGljTGlzdGVuZXI8VCAvKnN1cGVyIEphdmFGaWxlT2JqZWN0Ki8+IGltcGxlbWVudHMgRGlhZ25vc3RpY0xpc3RlbmVyPFQ+IHsKICAgICAgICBwcm90ZWN0ZWQgRGlhZ25vc3RpY0xpc3RlbmVyPFQ+IGNsaWVudERpYWdub3N0aWNMaXN0ZW5lcjsKICAgICAgICBXcmFwcGVkRGlhZ25vc3RpY0xpc3RlbmVyKERpYWdub3N0aWNMaXN0ZW5lcjxUPiBjbGllbnREaWFnbm9zdGljTGlzdGVuZXIpIHsKICAgICAgICAgICAgdGhpcy5jbGllbnREaWFnbm9zdGljTGlzdGVuZXIgPSBPYmplY3RzLnJlcXVpcmVOb25OdWxsKGNsaWVudERpYWdub3N0aWNMaXN0ZW5lcik7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICAgICAgcHVibGljIHZvaWQgcmVwb3J0KERpYWdub3N0aWM8PyBleHRlbmRzIFQ+IGRpYWdub3N0aWMpIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIGNsaWVudERpYWdub3N0aWNMaXN0ZW5lci5yZXBvcnQodW53cmFwKGRpYWdub3N0aWMpKTsKICAgICAgICAgICAgfSBjYXRjaCAoQ2xpZW50Q29kZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBlOwogICAgICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIHwgRXJyb3IgZSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IENsaWVudENvZGVFeGNlcHRpb24oZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CiAgICAgICAgICAgIHJldHVybiB3cmFwcGVkVG9TdHJpbmcoZ2V0Q2xhc3MoKSwgY2xpZW50RGlhZ25vc3RpY0xpc3RlbmVyKTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIGNsYXNzIERpYWdub3N0aWNTb3VyY2VVbndyYXBwZXIgaW1wbGVtZW50cyBEaWFnbm9zdGljPEphdmFGaWxlT2JqZWN0PiB7CiAgICAgICAgcHVibGljIGZpbmFsIEpDRGlhZ25vc3RpYyBkOwoKICAgICAgICBEaWFnbm9zdGljU291cmNlVW53cmFwcGVyKEpDRGlhZ25vc3RpYyBkKSB7CiAgICAgICAgICAgIHRoaXMuZCA9IGQ7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICAgICAgcHVibGljIERpYWdub3N0aWMuS2luZCBnZXRLaW5kKCkgewogICAgICAgICAgICByZXR1cm4gZC5nZXRLaW5kKCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICAgICAgcHVibGljIEphdmFGaWxlT2JqZWN0IGdldFNvdXJjZSgpIHsKICAgICAgICAgICAgcmV0dXJuIHVud3JhcChkLmdldFNvdXJjZSgpKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgICAgICBwdWJsaWMgbG9uZyBnZXRQb3NpdGlvbigpIHsKICAgICAgICAgICAgcmV0dXJuIGQuZ2V0UG9zaXRpb24oKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgICAgICBwdWJsaWMgbG9uZyBnZXRTdGFydFBvc2l0aW9uKCkgewogICAgICAgICAgICByZXR1cm4gZC5nZXRTdGFydFBvc2l0aW9uKCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICAgICAgcHVibGljIGxvbmcgZ2V0RW5kUG9zaXRpb24oKSB7CiAgICAgICAgICAgIHJldHVybiBkLmdldEVuZFBvc2l0aW9uKCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICAgICAgcHVibGljIGxvbmcgZ2V0TGluZU51bWJlcigpIHsKICAgICAgICAgICAgcmV0dXJuIGQuZ2V0TGluZU51bWJlcigpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSKQogICAgICAgIHB1YmxpYyBsb25nIGdldENvbHVtbk51bWJlcigpIHsKICAgICAgICAgICAgcmV0dXJuIGQuZ2V0Q29sdW1uTnVtYmVyKCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICAgICAgcHVibGljIFN0cmluZyBnZXRDb2RlKCkgewogICAgICAgICAgICByZXR1cm4gZC5nZXRDb2RlKCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICAgICAgcHVibGljIFN0cmluZyBnZXRNZXNzYWdlKExvY2FsZSBsb2NhbGUpIHsKICAgICAgICAgICAgcmV0dXJuIGQuZ2V0TWVzc2FnZShsb2NhbGUpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKICAgICAgICAgICAgcmV0dXJuIGQudG9TdHJpbmcoKTsKICAgICAgICB9CiAgICB9CgogICAgcHJvdGVjdGVkIGNsYXNzIFdyYXBwZWRUYXNrTGlzdGVuZXIgaW1wbGVtZW50cyBUYXNrTGlzdGVuZXIgewogICAgICAgIHByb3RlY3RlZCBUYXNrTGlzdGVuZXIgY2xpZW50VGFza0xpc3RlbmVyOwogICAgICAgIFdyYXBwZWRUYXNrTGlzdGVuZXIoVGFza0xpc3RlbmVyIGNsaWVudFRhc2tMaXN0ZW5lcikgewogICAgICAgICAgICB0aGlzLmNsaWVudFRhc2tMaXN0ZW5lciA9IE9iamVjdHMucmVxdWlyZU5vbk51bGwoY2xpZW50VGFza0xpc3RlbmVyKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyB2b2lkIHN0YXJ0ZWQoVGFza0V2ZW50IGV2KSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBjbGllbnRUYXNrTGlzdGVuZXIuc3RhcnRlZChldik7CiAgICAgICAgICAgIH0gY2F0Y2ggKENsaWVudENvZGVFeGNlcHRpb24gZSkgewogICAgICAgICAgICAgICAgdGhyb3cgZTsKICAgICAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiB8IEVycm9yIGUpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBDbGllbnRDb2RlRXhjZXB0aW9uKGUpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgdm9pZCBmaW5pc2hlZChUYXNrRXZlbnQgZXYpIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIGNsaWVudFRhc2tMaXN0ZW5lci5maW5pc2hlZChldik7CiAgICAgICAgICAgIH0gY2F0Y2ggKENsaWVudENvZGVFeGNlcHRpb24gZSkgewogICAgICAgICAgICAgICAgdGhyb3cgZTsKICAgICAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiB8IEVycm9yIGUpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBDbGllbnRDb2RlRXhjZXB0aW9uKGUpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewogICAgICAgICAgICByZXR1cm4gd3JhcHBlZFRvU3RyaW5nKGdldENsYXNzKCksIGNsaWVudFRhc2tMaXN0ZW5lcik7CiAgICAgICAgfQogICAgfQoKICAgIC8vIDwvZWRpdG9yLWZvbGQ+Cn0KUEsDBAoAAAgAAAY7qUqCufc+/bQAAP20AAAnAAAAY29tL3N1bi90b29scy9qYXZhYy9hcGkvSmF2YWNUcmVlcy5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDA1LCAyMDE3LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuamF2YWMuYXBpOwoKaW1wb3J0IGphdmEuaW8uRmlsZU5vdEZvdW5kRXhjZXB0aW9uOwppbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKaW1wb3J0IGphdmEudGV4dC5CcmVha0l0ZXJhdG9yOwppbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CmltcG9ydCBqYXZhLnV0aWwuSGFzaFNldDsKaW1wb3J0IGphdmEudXRpbC5NYXA7CmltcG9ydCBqYXZhLnV0aWwuU2V0OwppbXBvcnQgamF2YS51dGlsLnJlZ2V4Lk1hdGNoZXI7CmltcG9ydCBqYXZhLnV0aWwucmVnZXguUGF0dGVybjsKCmltcG9ydCBqYXZheC5hbm5vdGF0aW9uLnByb2Nlc3NpbmcuUHJvY2Vzc2luZ0Vudmlyb25tZW50OwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5lbGVtZW50LkFubm90YXRpb25NaXJyb3I7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuQW5ub3RhdGlvblZhbHVlOwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5lbGVtZW50LkVsZW1lbnQ7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuRWxlbWVudEtpbmQ7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuRXhlY3V0YWJsZUVsZW1lbnQ7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuTW9kaWZpZXI7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuTmVzdGluZ0tpbmQ7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuUGFja2FnZUVsZW1lbnQ7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuVHlwZUVsZW1lbnQ7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLnR5cGUuRGVjbGFyZWRUeXBlOwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC50eXBlLlR5cGVLaW5kOwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC50eXBlLlR5cGVNaXJyb3I7CmltcG9ydCBqYXZheC50b29scy5EaWFnbm9zdGljOwppbXBvcnQgamF2YXgudG9vbHMuRmlsZU9iamVjdDsKaW1wb3J0IGphdmF4LnRvb2xzLkZvcndhcmRpbmdGaWxlT2JqZWN0OwppbXBvcnQgamF2YXgudG9vbHMuSmF2YUNvbXBpbGVyOwppbXBvcnQgamF2YXgudG9vbHMuSmF2YUZpbGVNYW5hZ2VyOwppbXBvcnQgamF2YXgudG9vbHMuSmF2YUZpbGVPYmplY3Q7CmltcG9ydCBqYXZheC50b29scy5KYXZhRmlsZU9iamVjdC5LaW5kOwppbXBvcnQgamF2YXgudG9vbHMuU3RhbmRhcmRMb2NhdGlvbjsKCmltcG9ydCBjb20uc3VuLnNvdXJjZS5kb2N0cmVlLkRvY0NvbW1lbnRUcmVlOwppbXBvcnQgY29tLnN1bi5zb3VyY2UuZG9jdHJlZS5Eb2NUcmVlOwppbXBvcnQgY29tLnN1bi5zb3VyY2UudHJlZS5DYXRjaFRyZWU7CmltcG9ydCBjb20uc3VuLnNvdXJjZS50cmVlLkNvbXBpbGF0aW9uVW5pdFRyZWU7CmltcG9ydCBjb20uc3VuLnNvdXJjZS50cmVlLlNjb3BlOwppbXBvcnQgY29tLnN1bi5zb3VyY2UudHJlZS5UcmVlOwppbXBvcnQgY29tLnN1bi5zb3VyY2UudXRpbC5Eb2NTb3VyY2VQb3NpdGlvbnM7CmltcG9ydCBjb20uc3VuLnNvdXJjZS51dGlsLkRvY1RyZWVQYXRoOwppbXBvcnQgY29tLnN1bi5zb3VyY2UudXRpbC5Eb2NUcmVlU2Nhbm5lcjsKaW1wb3J0IGNvbS5zdW4uc291cmNlLnV0aWwuRG9jVHJlZXM7CmltcG9ydCBjb20uc3VuLnNvdXJjZS51dGlsLkphdmFjVGFzazsKaW1wb3J0IGNvbS5zdW4uc291cmNlLnV0aWwuVHJlZVBhdGg7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuRmxhZ3M7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuU2NvcGUuTmFtZWRJbXBvcnRTY29wZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5TY29wZS5TdGFySW1wb3J0U2NvcGU7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuU2NvcGUuV3JpdGVhYmxlU2NvcGU7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuU3ltYm9sOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlN5bWJvbC5DbGFzc1N5bWJvbDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5TeW1ib2wuTWV0aG9kU3ltYm9sOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlN5bWJvbC5Nb2R1bGVTeW1ib2w7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuU3ltYm9sLlBhY2thZ2VTeW1ib2w7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuU3ltYm9sLlR5cGVTeW1ib2w7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuU3ltYm9sLlZhclN5bWJvbDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5TeW10YWI7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuVHlwZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5UeXBlLkFycmF5VHlwZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5UeXBlLkNsYXNzVHlwZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5UeXBlLkVycm9yVHlwZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5UeXBlLlVuaW9uQ2xhc3NUeXBlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlR5cGVzOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlR5cGVzLlR5cGVSZWxhdGlvbjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29tcC5BdHRyOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb21wLkF0dHJDb250ZXh0OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb21wLkVudGVyOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb21wLkVudjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29tcC5NZW1iZXJFbnRlcjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29tcC5Nb2R1bGVzOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb21wLlJlc29sdmU7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmZpbGUuQmFzZUZpbGVNYW5hZ2VyOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5tb2RlbC5KYXZhY0VsZW1lbnRzOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5wYXJzZXIuRG9jQ29tbWVudFBhcnNlcjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMucGFyc2VyLlBhcnNlckZhY3Rvcnk7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnBhcnNlci5Ub2tlbnMuQ29tbWVudDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMucGFyc2VyLlRva2Vucy5Db21tZW50LkNvbW1lbnRTdHlsZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMucHJvY2Vzc2luZy5KYXZhY1Byb2Nlc3NpbmdFbnZpcm9ubWVudDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5EQ1RyZWU7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuRENUcmVlLkRDQmxvY2tUYWc7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuRENUcmVlLkRDRG9jQ29tbWVudDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5EQ1RyZWUuRENFbmRQb3NUcmVlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkRDVHJlZS5EQ0Vycm9uZW91czsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5EQ1RyZWUuRENJZGVudGlmaWVyOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkRDVHJlZS5EQ1BhcmFtOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkRDVHJlZS5EQ1JlZmVyZW5jZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5EQ1RyZWUuRENUZXh0OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkRvY0NvbW1lbnRUYWJsZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5Eb2NUcmVlTWFrZXI7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuRW5kUG9zVGFibGU7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuSkNUcmVlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkpDVHJlZS5KQ0Jsb2NrOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkpDVHJlZS5KQ0NhdGNoOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkpDVHJlZS5KQ0NsYXNzRGVjbDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5KQ1RyZWUuSkNDb21waWxhdGlvblVuaXQ7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuSkNUcmVlLkpDRXhwcmVzc2lvbjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5KQ1RyZWUuSkNJZGVudDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5KQ1RyZWUuSkNNZXRob2REZWNsOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkpDVHJlZS5KQ1ZhcmlhYmxlRGVjbDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5UcmVlQ29waWVyOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLlRyZWVJbmZvOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLlRyZWVNYWtlcjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5BYm9ydDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5Bc3NlcnQ7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuQ29udGV4dDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5EZWZpbmVkQnk7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuRGVmaW5lZEJ5LkFwaTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5EaWFnbm9zdGljU291cmNlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkpDRGlhZ25vc3RpYzsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5KQ0RpYWdub3N0aWMuRGlhZ25vc3RpY0ZsYWc7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuTGlzdDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5MaXN0QnVmZmVyOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkxvZzsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5OYW1lOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLk5hbWVzOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLlBhaXI7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuUG9zaXRpb247CgppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5LaW5kcy5LaW5kLio7CmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlR5cGVUYWcuKjsKCi8qKgogKiBQcm92aWRlcyBhbiBpbXBsZW1lbnRhdGlvbiBvZiBUcmVlcy4KICoKICogPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93bgogKiByaXNrLiAgVGhpcyBjb2RlIGFuZCBpdHMgaW50ZXJuYWwgaW50ZXJmYWNlcyBhcmUgc3ViamVjdCB0byBjaGFuZ2UKICogb3IgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPjwvcD4KICoKICogQGF1dGhvciBQZXRlciB2b24gZGVyIEFoJmVhY3V0ZTsKICovCnB1YmxpYyBjbGFzcyBKYXZhY1RyZWVzIGV4dGVuZHMgRG9jVHJlZXMgewoKICAgIC8vIGluIGEgd29ybGQgb2YgYSBzaW5nbGUgY29udGV4dCBwZXIgY29tcGlsYXRpb24sIHRoZXNlIHdvdWxkIGFsbCBiZSBmaW5hbAogICAgcHJpdmF0ZSBNb2R1bGVzIG1vZHVsZXM7CiAgICBwcml2YXRlIFJlc29sdmUgcmVzb2x2ZTsKICAgIHByaXZhdGUgRW50ZXIgZW50ZXI7CiAgICBwcml2YXRlIExvZyBsb2c7CiAgICBwcml2YXRlIE1lbWJlckVudGVyIG1lbWJlckVudGVyOwogICAgcHJpdmF0ZSBBdHRyIGF0dHI7CiAgICBwcml2YXRlIFRyZWVNYWtlciB0cmVlTWFrZXI7CiAgICBwcml2YXRlIEphdmFjRWxlbWVudHMgZWxlbWVudHM7CiAgICBwcml2YXRlIEphdmFjVGFza0ltcGwgamF2YWNUYXNrSW1wbDsKICAgIHByaXZhdGUgTmFtZXMgbmFtZXM7CiAgICBwcml2YXRlIFR5cGVzIHR5cGVzOwogICAgcHJpdmF0ZSBEb2NUcmVlTWFrZXIgZG9jVHJlZU1ha2VyOwogICAgcHJpdmF0ZSBCcmVha0l0ZXJhdG9yIGJyZWFrSXRlcmF0b3I7CiAgICBwcml2YXRlIEphdmFGaWxlTWFuYWdlciBmaWxlTWFuYWdlcjsKICAgIHByaXZhdGUgUGFyc2VyRmFjdG9yeSBwYXJzZXI7CiAgICBwcml2YXRlIFN5bXRhYiBzeW1zOwoKICAgIC8vIGNhbGxlZCByZWZsZWN0aXZlbHkgZnJvbSBUcmVlcy5pbnN0YW5jZShDb21waWxhdGlvblRhc2sgdGFzaykKICAgIHB1YmxpYyBzdGF0aWMgSmF2YWNUcmVlcyBpbnN0YW5jZShKYXZhQ29tcGlsZXIuQ29tcGlsYXRpb25UYXNrIHRhc2spIHsKICAgICAgICBpZiAoISh0YXNrIGluc3RhbmNlb2YgQmFzaWNKYXZhY1Rhc2spKQogICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgcmV0dXJuIGluc3RhbmNlKCgoQmFzaWNKYXZhY1Rhc2spdGFzaykuZ2V0Q29udGV4dCgpKTsKICAgIH0KCiAgICAvLyBjYWxsZWQgcmVmbGVjdGl2ZWx5IGZyb20gVHJlZXMuaW5zdGFuY2UoUHJvY2Vzc2luZ0Vudmlyb25tZW50IGVudikKICAgIHB1YmxpYyBzdGF0aWMgSmF2YWNUcmVlcyBpbnN0YW5jZShQcm9jZXNzaW5nRW52aXJvbm1lbnQgZW52KSB7CiAgICAgICAgaWYgKCEoZW52IGluc3RhbmNlb2YgSmF2YWNQcm9jZXNzaW5nRW52aXJvbm1lbnQpKQogICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgcmV0dXJuIGluc3RhbmNlKCgoSmF2YWNQcm9jZXNzaW5nRW52aXJvbm1lbnQpZW52KS5nZXRDb250ZXh0KCkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgSmF2YWNUcmVlcyBpbnN0YW5jZShDb250ZXh0IGNvbnRleHQpIHsKICAgICAgICBKYXZhY1RyZWVzIGluc3RhbmNlID0gY29udGV4dC5nZXQoSmF2YWNUcmVlcy5jbGFzcyk7CiAgICAgICAgaWYgKGluc3RhbmNlID09IG51bGwpCiAgICAgICAgICAgIGluc3RhbmNlID0gbmV3IEphdmFjVHJlZXMoY29udGV4dCk7CiAgICAgICAgcmV0dXJuIGluc3RhbmNlOwogICAgfQoKICAgIHByb3RlY3RlZCBKYXZhY1RyZWVzKENvbnRleHQgY29udGV4dCkgewogICAgICAgIHRoaXMuYnJlYWtJdGVyYXRvciA9IG51bGw7CiAgICAgICAgY29udGV4dC5wdXQoSmF2YWNUcmVlcy5jbGFzcywgdGhpcyk7CiAgICAgICAgaW5pdChjb250ZXh0KTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCB1cGRhdGVDb250ZXh0KENvbnRleHQgY29udGV4dCkgewogICAgICAgIGluaXQoY29udGV4dCk7CiAgICB9CgogICAgcHJpdmF0ZSB2b2lkIGluaXQoQ29udGV4dCBjb250ZXh0KSB7CiAgICAgICAgbW9kdWxlcyA9IE1vZHVsZXMuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgYXR0ciA9IEF0dHIuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgZW50ZXIgPSBFbnRlci5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBlbGVtZW50cyA9IEphdmFjRWxlbWVudHMuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgbG9nID0gTG9nLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIHJlc29sdmUgPSBSZXNvbHZlLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIHRyZWVNYWtlciA9IFRyZWVNYWtlci5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBtZW1iZXJFbnRlciA9IE1lbWJlckVudGVyLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIG5hbWVzID0gTmFtZXMuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgdHlwZXMgPSBUeXBlcy5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBkb2NUcmVlTWFrZXIgPSBEb2NUcmVlTWFrZXIuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgcGFyc2VyID0gUGFyc2VyRmFjdG9yeS5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBzeW1zID0gU3ltdGFiLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIGZpbGVNYW5hZ2VyID0gY29udGV4dC5nZXQoSmF2YUZpbGVNYW5hZ2VyLmNsYXNzKTsKICAgICAgICBKYXZhY1Rhc2sgdCA9IGNvbnRleHQuZ2V0KEphdmFjVGFzay5jbGFzcyk7CiAgICAgICAgaWYgKHQgaW5zdGFuY2VvZiBKYXZhY1Rhc2tJbXBsKQogICAgICAgICAgICBqYXZhY1Rhc2tJbXBsID0gKEphdmFjVGFza0ltcGwpIHQ7CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICBwdWJsaWMgQnJlYWtJdGVyYXRvciBnZXRCcmVha0l0ZXJhdG9yKCkgewogICAgICAgIHJldHVybiBicmVha0l0ZXJhdG9yOwogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIERvY1NvdXJjZVBvc2l0aW9ucyBnZXRTb3VyY2VQb3NpdGlvbnMoKSB7CiAgICAgICAgcmV0dXJuIG5ldyBEb2NTb3VyY2VQb3NpdGlvbnMoKSB7CiAgICAgICAgICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICAgICAgICAgIHB1YmxpYyBsb25nIGdldFN0YXJ0UG9zaXRpb24oQ29tcGlsYXRpb25Vbml0VHJlZSBmaWxlLCBUcmVlIHRyZWUpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gVHJlZUluZm8uZ2V0U3RhcnRQb3MoKEpDVHJlZSkgdHJlZSk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgICAgICAgICBwdWJsaWMgbG9uZyBnZXRFbmRQb3NpdGlvbihDb21waWxhdGlvblVuaXRUcmVlIGZpbGUsIFRyZWUgdHJlZSkgewogICAgICAgICAgICAgICAgICAgIEVuZFBvc1RhYmxlIGVuZFBvc1RhYmxlID0gKChKQ0NvbXBpbGF0aW9uVW5pdCkgZmlsZSkuZW5kUG9zaXRpb25zOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBUcmVlSW5mby5nZXRFbmRQb3MoKEpDVHJlZSkgdHJlZSwgZW5kUG9zVGFibGUpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgICAgICAgICAgcHVibGljIGxvbmcgZ2V0U3RhcnRQb3NpdGlvbihDb21waWxhdGlvblVuaXRUcmVlIGZpbGUsIERvY0NvbW1lbnRUcmVlIGNvbW1lbnQsIERvY1RyZWUgdHJlZSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAoKERDVHJlZSkgdHJlZSkuZ2V0U291cmNlUG9zaXRpb24oKERDRG9jQ29tbWVudCkgY29tbWVudCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBAT3ZlcnJpZGUgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpIEBTdXBwcmVzc1dhcm5pbmdzKCJmYWxsdGhyb3VnaCIpCiAgICAgICAgICAgICAgICBwdWJsaWMgbG9uZyBnZXRFbmRQb3NpdGlvbihDb21waWxhdGlvblVuaXRUcmVlIGZpbGUsIERvY0NvbW1lbnRUcmVlIGNvbW1lbnQsIERvY1RyZWUgdHJlZSkgewogICAgICAgICAgICAgICAgICAgIERDRG9jQ29tbWVudCBkY0NvbW1lbnQgPSAoRENEb2NDb21tZW50KSBjb21tZW50OwogICAgICAgICAgICAgICAgICAgIGlmICh0cmVlIGluc3RhbmNlb2YgRENFbmRQb3NUcmVlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGludCBlbmRQb3MgPSAoKERDRW5kUG9zVHJlZSkgdHJlZSkuZ2V0RW5kUG9zKGRjQ29tbWVudCk7CgogICAgICAgICAgICAgICAgICAgICAgICBpZiAoZW5kUG9zICE9IFBvc2l0aW9uLk5PUE9TKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZW5kUG9zOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGludCBjb3JyZWN0aW9uID0gMDsKICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKHRyZWUuZ2V0S2luZCgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgVEVYVDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIERDVGV4dCB0ZXh0ID0gKERDVGV4dCkgdHJlZTsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGNDb21tZW50LmNvbW1lbnQuZ2V0U291cmNlUG9zKHRleHQucG9zICsgdGV4dC50ZXh0Lmxlbmd0aCgpKTsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBFUlJPTkVPVVM6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBEQ0Vycm9uZW91cyBlcnIgPSAoRENFcnJvbmVvdXMpIHRyZWU7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRjQ29tbWVudC5jb21tZW50LmdldFNvdXJjZVBvcyhlcnIucG9zICsgZXJyLmJvZHkubGVuZ3RoKCkpOwogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIElERU5USUZJRVI6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBEQ0lkZW50aWZpZXIgaWRlbnQgPSAoRENJZGVudGlmaWVyKSB0cmVlOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBkY0NvbW1lbnQuY29tbWVudC5nZXRTb3VyY2VQb3MoaWRlbnQucG9zICsgKGlkZW50Lm5hbWUgIT0gbmFtZXMuZXJyb3IgPyBpZGVudC5uYW1lLmxlbmd0aCgpIDogMCkpOwogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFBBUkFNOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgRENQYXJhbSBwYXJhbSA9IChEQ1BhcmFtKSB0cmVlOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwYXJhbS5pc1R5cGVQYXJhbWV0ZXIgJiYgcGFyYW0uZ2V0RGVzY3JpcHRpb24oKS5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3JyZWN0aW9uID0gMTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBBVVRIT1I6IGNhc2UgREVQUkVDQVRFRDogY2FzZSBSRVRVUk46IGNhc2UgU0VFOgogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFNFUklBTDogY2FzZSBTRVJJQUxfREFUQTogY2FzZSBTRVJJQUxfRklFTEQ6IGNhc2UgU0lOQ0U6CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgVEhST1dTOiBjYXNlIFVOS05PV05fQkxPQ0tfVEFHOiBjYXNlIFZFUlNJT046IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIERvY1RyZWUgbGFzdCA9IGdldExhc3RDaGlsZCh0cmVlKTsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobGFzdCAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGdldEVuZFBvc2l0aW9uKGZpbGUsIGNvbW1lbnQsIGxhc3QpICsgY29ycmVjdGlvbjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBEQ0Jsb2NrVGFnIGJsb2NrID0gKERDQmxvY2tUYWcpIHRyZWU7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRjQ29tbWVudC5jb21tZW50LmdldFNvdXJjZVBvcyhibG9jay5wb3MgKyBibG9jay5nZXRUYWdOYW1lKCkubGVuZ3RoKCkgKyAxKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgICAgICAgICAgRG9jVHJlZSBsYXN0ID0gZ2V0TGFzdENoaWxkKHRyZWUpOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChsYXN0ICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZ2V0RW5kUG9zaXRpb24oZmlsZSwgY29tbWVudCwgbGFzdCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIHJldHVybiBQb3NpdGlvbi5OT1BPUzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBEb2NUcmVlTWFrZXIgZ2V0RG9jVHJlZUZhY3RvcnkoKSB7CiAgICAgICAgcmV0dXJuIGRvY1RyZWVNYWtlcjsKICAgIH0KCiAgICBwcml2YXRlIERvY1RyZWUgZ2V0TGFzdENoaWxkKERvY1RyZWUgdHJlZSkgewogICAgICAgIGZpbmFsIERvY1RyZWVbXSBsYXN0ID0gbmV3IERvY1RyZWVbXSB7bnVsbH07CgogICAgICAgIHRyZWUuYWNjZXB0KG5ldyBEb2NUcmVlU2Nhbm5lcjxWb2lkLCBWb2lkPigpIHsKICAgICAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgICAgIHB1YmxpYyBWb2lkIHNjYW4oRG9jVHJlZSBub2RlLCBWb2lkIHApIHsKICAgICAgICAgICAgICAgIGlmIChub2RlICE9IG51bGwpIGxhc3RbMF0gPSBub2RlOwogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KICAgICAgICB9LCBudWxsKTsKCiAgICAgICAgcmV0dXJuIGxhc3RbMF07CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICBwdWJsaWMgSkNDbGFzc0RlY2wgZ2V0VHJlZShUeXBlRWxlbWVudCBlbGVtZW50KSB7CiAgICAgICAgcmV0dXJuIChKQ0NsYXNzRGVjbCkgZ2V0VHJlZSgoRWxlbWVudCkgZWxlbWVudCk7CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICBwdWJsaWMgSkNNZXRob2REZWNsIGdldFRyZWUoRXhlY3V0YWJsZUVsZW1lbnQgbWV0aG9kKSB7CiAgICAgICAgcmV0dXJuIChKQ01ldGhvZERlY2wpIGdldFRyZWUoKEVsZW1lbnQpIG1ldGhvZCk7CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICBwdWJsaWMgSkNUcmVlIGdldFRyZWUoRWxlbWVudCBlbGVtZW50KSB7CiAgICAgICAgcmV0dXJuIGdldFRyZWUoZWxlbWVudCwgbnVsbCk7CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICBwdWJsaWMgSkNUcmVlIGdldFRyZWUoRWxlbWVudCBlLCBBbm5vdGF0aW9uTWlycm9yIGEpIHsKICAgICAgICByZXR1cm4gZ2V0VHJlZShlLCBhLCBudWxsKTsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBKQ1RyZWUgZ2V0VHJlZShFbGVtZW50IGUsIEFubm90YXRpb25NaXJyb3IgYSwgQW5ub3RhdGlvblZhbHVlIHYpIHsKICAgICAgICBQYWlyPEpDVHJlZSwgSkNDb21waWxhdGlvblVuaXQ+IHRyZWVUb3BMZXZlbCA9IGVsZW1lbnRzLmdldFRyZWVBbmRUb3BMZXZlbChlLCBhLCB2KTsKICAgICAgICBpZiAodHJlZVRvcExldmVsID09IG51bGwpCiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIHJldHVybiB0cmVlVG9wTGV2ZWwuZnN0OwogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIFRyZWVQYXRoIGdldFBhdGgoQ29tcGlsYXRpb25Vbml0VHJlZSB1bml0LCBUcmVlIG5vZGUpIHsKICAgICAgICByZXR1cm4gVHJlZVBhdGguZ2V0UGF0aCh1bml0LCBub2RlKTsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBUcmVlUGF0aCBnZXRQYXRoKEVsZW1lbnQgZSkgewogICAgICAgIHJldHVybiBnZXRQYXRoKGUsIG51bGwsIG51bGwpOwogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIFRyZWVQYXRoIGdldFBhdGgoRWxlbWVudCBlLCBBbm5vdGF0aW9uTWlycm9yIGEpIHsKICAgICAgICByZXR1cm4gZ2V0UGF0aChlLCBhLCBudWxsKTsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBUcmVlUGF0aCBnZXRQYXRoKEVsZW1lbnQgZSwgQW5ub3RhdGlvbk1pcnJvciBhLCBBbm5vdGF0aW9uVmFsdWUgdikgewogICAgICAgIGZpbmFsIFBhaXI8SkNUcmVlLCBKQ0NvbXBpbGF0aW9uVW5pdD4gdHJlZVRvcExldmVsID0gZWxlbWVudHMuZ2V0VHJlZUFuZFRvcExldmVsKGUsIGEsIHYpOwogICAgICAgIGlmICh0cmVlVG9wTGV2ZWwgPT0gbnVsbCkKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgcmV0dXJuIFRyZWVQYXRoLmdldFBhdGgodHJlZVRvcExldmVsLnNuZCwgdHJlZVRvcExldmVsLmZzdCk7CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICBwdWJsaWMgU3ltYm9sIGdldEVsZW1lbnQoVHJlZVBhdGggcGF0aCkgewogICAgICAgIEpDVHJlZSB0cmVlID0gKEpDVHJlZSkgcGF0aC5nZXRMZWFmKCk7CiAgICAgICAgU3ltYm9sIHN5bSA9IFRyZWVJbmZvLnN5bWJvbEZvcih0cmVlKTsKICAgICAgICBpZiAoc3ltID09IG51bGwpIHsKICAgICAgICAgICAgZm9yIChUcmVlUGF0aCBwID0gcGF0aDsgcCAhPSBudWxsOyBwID0gcC5nZXRQYXJlbnRQYXRoKCkpIHsKICAgICAgICAgICAgICAgIEpDVHJlZSB0ID0gKEpDVHJlZSkgcC5nZXRMZWFmKCk7CiAgICAgICAgICAgICAgICBpZiAodC5oYXNUYWcoSkNUcmVlLlRhZy5DTEFTU0RFRikpIHsKICAgICAgICAgICAgICAgICAgICBKQ0NsYXNzRGVjbCBjdCA9IChKQ0NsYXNzRGVjbCkgdDsKICAgICAgICAgICAgICAgICAgICBpZiAoY3Quc3ltICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKChjdC5zeW0uZmxhZ3NfZmllbGQgJiBGbGFncy5VTkFUVFJJQlVURUQpICE9IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHIuYXR0cmliQ2xhc3MoY3QucG9zKCksIGN0LnN5bSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeW0gPSBUcmVlSW5mby5zeW1ib2xGb3IodHJlZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBzeW07CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICBwdWJsaWMgRWxlbWVudCBnZXRFbGVtZW50KERvY1RyZWVQYXRoIHBhdGgpIHsKICAgICAgICBEb2NUcmVlIGZvclRyZWUgPSBwYXRoLmdldExlYWYoKTsKICAgICAgICBpZiAoZm9yVHJlZSBpbnN0YW5jZW9mIERDUmVmZXJlbmNlKQogICAgICAgICAgICByZXR1cm4gYXR0cmlidXRlRG9jUmVmZXJlbmNlKHBhdGguZ2V0VHJlZVBhdGgoKSwgKChEQ1JlZmVyZW5jZSkgZm9yVHJlZSkpOwogICAgICAgIGlmIChmb3JUcmVlIGluc3RhbmNlb2YgRENJZGVudGlmaWVyKSB7CiAgICAgICAgICAgIGlmIChwYXRoLmdldFBhcmVudFBhdGgoKS5nZXRMZWFmKCkgaW5zdGFuY2VvZiBEQ1BhcmFtKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gYXR0cmlidXRlUGFyYW1JZGVudGlmaWVyKHBhdGguZ2V0VHJlZVBhdGgoKSwgKERDUGFyYW0pIHBhdGguZ2V0UGFyZW50UGF0aCgpLmdldExlYWYoKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8RG9jVHJlZT4gZ2V0Rmlyc3RTZW50ZW5jZShqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgRG9jVHJlZT4gbGlzdCkgewogICAgICAgIHJldHVybiBkb2NUcmVlTWFrZXIuZ2V0Rmlyc3RTZW50ZW5jZShsaXN0KTsKICAgIH0KCiAgICBwcml2YXRlIFN5bWJvbCBhdHRyaWJ1dGVEb2NSZWZlcmVuY2UoVHJlZVBhdGggcGF0aCwgRENSZWZlcmVuY2UgcmVmKSB7CiAgICAgICAgRW52PEF0dHJDb250ZXh0PiBlbnYgPSBnZXRBdHRyQ29udGV4dChwYXRoKTsKICAgICAgICBpZiAoZW52ID09IG51bGwpIHJldHVybiBudWxsOwoKICAgICAgICBMb2cuRGVmZXJyZWREaWFnbm9zdGljSGFuZGxlciBkZWZlcnJlZERpYWdub3N0aWNIYW5kbGVyID0KICAgICAgICAgICAgICAgIG5ldyBMb2cuRGVmZXJyZWREaWFnbm9zdGljSGFuZGxlcihsb2cpOwogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGZpbmFsIFR5cGVTeW1ib2wgdHN5bTsKICAgICAgICAgICAgZmluYWwgTmFtZSBtZW1iZXJOYW1lOwogICAgICAgICAgICBpZiAocmVmLnF1YWxpZmllckV4cHJlc3Npb24gPT0gbnVsbCkgewogICAgICAgICAgICAgICAgdHN5bSA9IGVudi5lbmNsQ2xhc3Muc3ltOwogICAgICAgICAgICAgICAgbWVtYmVyTmFtZSA9IChOYW1lKSByZWYubWVtYmVyTmFtZTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIC8vIG5ld1NlZVRyZWUgaWYgdGhlIHF1YWxpZmllckV4cHJlc3Npb24gaXMgYSB0eXBlIG9yIHBhY2thZ2UgbmFtZS4KICAgICAgICAgICAgICAgIC8vIGphdmFjIGRvZXMgbm90IHByb3ZpZGUgdGhlIGV4YWN0IG1ldGhvZCByZXF1aXJlZCwgc28KICAgICAgICAgICAgICAgIC8vIHdlIGZpcnN0IGNoZWNrIGlmIHF1YWxpZmllckV4cHJlc3Npb24gaWRlbnRpZmllcyBhIHR5cGUsCiAgICAgICAgICAgICAgICAvLyBhbmQgaWYgbm90LCB0aGVuIHdlIGNoZWNrIHRvIHNlZSBpZiBpdCBpZGVudGlmaWVzIGEgcGFja2FnZS4KICAgICAgICAgICAgICAgIFR5cGUgdCA9IGF0dHIuYXR0cmliVHlwZShyZWYucXVhbGlmaWVyRXhwcmVzc2lvbiwgZW52KTsKICAgICAgICAgICAgICAgIGlmICh0LmlzRXJyb25lb3VzKCkpIHsKICAgICAgICAgICAgICAgICAgICBKQ0NvbXBpbGF0aW9uVW5pdCB0b3BsZXZlbCA9CiAgICAgICAgICAgICAgICAgICAgICAgIHRyZWVNYWtlci5Ub3BMZXZlbChMaXN0Lm5pbCgpKTsKICAgICAgICAgICAgICAgICAgICBmaW5hbCBNb2R1bGVTeW1ib2wgbXN5bSA9IG1vZHVsZXMuZ2V0RGVmYXVsdE1vZHVsZSgpOwogICAgICAgICAgICAgICAgICAgIHRvcGxldmVsLm1vZGxlID0gbXN5bTsKICAgICAgICAgICAgICAgICAgICB0b3BsZXZlbC5wYWNrZ2UgPSBtc3ltLnVubmFtZWRQYWNrYWdlOwogICAgICAgICAgICAgICAgICAgIFN5bWJvbCBzeW0gPSBhdHRyLmF0dHJpYklkZW50KHJlZi5xdWFsaWZpZXJFeHByZXNzaW9uLCB0b3BsZXZlbCk7CgogICAgICAgICAgICAgICAgICAgIHN5bS5jb21wbGV0ZSgpOwoKICAgICAgICAgICAgICAgICAgICBpZiAoKHN5bS5raW5kID09IFBDSyB8fCBzeW0ua2luZCA9PSBUWVApICYmIHN5bS5leGlzdHMoKSkgewogICAgICAgICAgICAgICAgICAgICAgICB0c3ltID0gKFR5cGVTeW1ib2wpIHN5bTsKICAgICAgICAgICAgICAgICAgICAgICAgbWVtYmVyTmFtZSA9IChOYW1lKSByZWYubWVtYmVyTmFtZTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN5bS5raW5kID09IFBDSyAmJiBtZW1iZXJOYW1lICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vY2Fubm90IHJlZmVyIHRvIGEgcGFja2FnZSAibWVtYmVyIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVmLnF1YWxpZmllckV4cHJlc3Npb24uaGFzVGFnKEpDVHJlZS5UYWcuSURFTlQpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBmaXh1cDogIGFsbG93ICJpZGVudGlmaWVyIiBpbnN0ZWFkIG9mICIjaWRlbnRpZmllciIKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZvciBjb21wYXRpYmlsaXR5IHdpdGggamF2YWRvYwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdHN5bSA9IGVudi5lbmNsQ2xhc3Muc3ltOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVtYmVyTmFtZSA9ICgoSkNJZGVudCkgcmVmLnF1YWxpZmllckV4cHJlc3Npb24pLm5hbWU7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgdHN5bSA9IHQudHN5bTsKICAgICAgICAgICAgICAgICAgICBtZW1iZXJOYW1lID0gKE5hbWUpIHJlZi5tZW1iZXJOYW1lOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAobWVtYmVyTmFtZSA9PSBudWxsKQogICAgICAgICAgICAgICAgcmV0dXJuIHRzeW07CgogICAgICAgICAgICBmaW5hbCBMaXN0PFR5cGU+IHBhcmFtVHlwZXM7CiAgICAgICAgICAgIGlmIChyZWYucGFyYW1UeXBlcyA9PSBudWxsKQogICAgICAgICAgICAgICAgcGFyYW1UeXBlcyA9IG51bGw7CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgTGlzdEJ1ZmZlcjxUeXBlPiBsYiA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICAgICAgICAgIGZvciAoTGlzdDxKQ1RyZWU+IGwgPSAoTGlzdDxKQ1RyZWU+KSByZWYucGFyYW1UeXBlczsgbC5ub25FbXB0eSgpOyBsID0gbC50YWlsKSB7CiAgICAgICAgICAgICAgICAgICAgSkNUcmVlIHRyZWUgPSBsLmhlYWQ7CiAgICAgICAgICAgICAgICAgICAgVHlwZSB0ID0gYXR0ci5hdHRyaWJUeXBlKHRyZWUsIGVudik7CiAgICAgICAgICAgICAgICAgICAgbGIuYWRkKHQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcGFyYW1UeXBlcyA9IGxiLnRvTGlzdCgpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBDbGFzc1N5bWJvbCBzeW0gPSAoQ2xhc3NTeW1ib2wpIHR5cGVzLnNraXBUeXBlVmFycyh0c3ltLnR5cGUsIGZhbHNlKS50c3ltOwoKICAgICAgICAgICAgU3ltYm9sIG1zeW0gPSAobWVtYmVyTmFtZSA9PSBzeW0ubmFtZSkKICAgICAgICAgICAgICAgICAgICA/IGZpbmRDb25zdHJ1Y3RvcihzeW0sIHBhcmFtVHlwZXMpCiAgICAgICAgICAgICAgICAgICAgOiBmaW5kTWV0aG9kKHN5bSwgbWVtYmVyTmFtZSwgcGFyYW1UeXBlcyk7CiAgICAgICAgICAgIGlmIChwYXJhbVR5cGVzICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIC8vIGV4cGxpY2l0IChwb3NzaWJseSBlbXB0eSkgYXJnIGxpc3QgZ2l2ZW4sIHNvIGNhbm5vdCBiZSBhIGZpZWxkCiAgICAgICAgICAgICAgICByZXR1cm4gbXN5bTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgVmFyU3ltYm9sIHZzeW0gPSAocmVmLnBhcmFtVHlwZXMgIT0gbnVsbCkgPyBudWxsIDogZmluZEZpZWxkKHN5bSwgbWVtYmVyTmFtZSk7CiAgICAgICAgICAgIC8vIHByZWZlciBhIGZpZWxkIG92ZXIgYSBtZXRob2Qgd2l0aCBubyBwYXJhbWV0ZXJzCiAgICAgICAgICAgIGlmICh2c3ltICE9IG51bGwgJiYKICAgICAgICAgICAgICAgICAgICAobXN5bSA9PSBudWxsIHx8CiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVzLmlzU3VidHlwZVVuY2hlY2tlZCh2c3ltLmVuY2xDbGFzcygpLmFzVHlwZSgpLCBtc3ltLmVuY2xDbGFzcygpLmFzVHlwZSgpKSkpIHsKICAgICAgICAgICAgICAgIHJldHVybiB2c3ltOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcmV0dXJuIG1zeW07CiAgICAgICAgICAgIH0KICAgICAgICB9IGNhdGNoIChBYm9ydCBlKSB7IC8vIG1heSBiZSB0aHJvd24gYnkgQ2hlY2suY29tcGxldGlvbkVycm9yIGluIGNhc2Ugb2YgYmFkIGNsYXNzIGZpbGUKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgbG9nLnBvcERpYWdub3N0aWNIYW5kbGVyKGRlZmVycmVkRGlhZ25vc3RpY0hhbmRsZXIpOwogICAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIFN5bWJvbCBhdHRyaWJ1dGVQYXJhbUlkZW50aWZpZXIoVHJlZVBhdGggcGF0aCwgRENQYXJhbSBwdGFnKSB7CiAgICAgICAgU3ltYm9sIGphdmFkb2NTeW1ib2wgPSBnZXRFbGVtZW50KHBhdGgpOwogICAgICAgIGlmIChqYXZhZG9jU3ltYm9sID09IG51bGwpCiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIEVsZW1lbnRLaW5kIGtpbmQgPSBqYXZhZG9jU3ltYm9sLmdldEtpbmQoKTsKICAgICAgICBMaXN0PD8gZXh0ZW5kcyBTeW1ib2w+IHBhcmFtcyA9IExpc3QubmlsKCk7CiAgICAgICAgaWYgKGtpbmQgPT0gRWxlbWVudEtpbmQuTUVUSE9EIHx8IGtpbmQgPT0gRWxlbWVudEtpbmQuQ09OU1RSVUNUT1IpIHsKICAgICAgICAgICAgTWV0aG9kU3ltYm9sIGVlID0gKE1ldGhvZFN5bWJvbCkgamF2YWRvY1N5bWJvbDsKICAgICAgICAgICAgcGFyYW1zID0gcHRhZy5pc1R5cGVQYXJhbWV0ZXIoKQogICAgICAgICAgICAgICAgICAgID8gZWUuZ2V0VHlwZVBhcmFtZXRlcnMoKQogICAgICAgICAgICAgICAgICAgIDogZWUuZ2V0UGFyYW1ldGVycygpOwogICAgICAgIH0gZWxzZSBpZiAoa2luZC5pc0NsYXNzKCkgfHwga2luZC5pc0ludGVyZmFjZSgpKSB7CiAgICAgICAgICAgIENsYXNzU3ltYm9sIHRlID0gKENsYXNzU3ltYm9sKSBqYXZhZG9jU3ltYm9sOwogICAgICAgICAgICBwYXJhbXMgPSB0ZS5nZXRUeXBlUGFyYW1ldGVycygpOwogICAgICAgIH0KCiAgICAgICAgZm9yIChTeW1ib2wgcGFyYW0gOiBwYXJhbXMpIHsKICAgICAgICAgICAgaWYgKHBhcmFtLmdldFNpbXBsZU5hbWUoKSA9PSBwdGFnLmdldE5hbWUoKS5nZXROYW1lKCkpIHsKICAgICAgICAgICAgICAgIHJldHVybiBwYXJhbTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICAvKiogQHNlZSBjb20uc3VuLnRvb2xzLmphdmFkb2MuQ2xhc3NEb2NJbXBsI2ZpbmRGaWVsZCAqLwogICAgcHJpdmF0ZSBWYXJTeW1ib2wgZmluZEZpZWxkKENsYXNzU3ltYm9sIHRzeW0sIE5hbWUgZmllbGROYW1lKSB7CiAgICAgICAgcmV0dXJuIHNlYXJjaEZpZWxkKHRzeW0sIGZpZWxkTmFtZSwgbmV3IEhhc2hTZXQ8PigpKTsKICAgIH0KCiAgICAvKiogQHNlZSBjb20uc3VuLnRvb2xzLmphdmFkb2MuQ2xhc3NEb2NJbXBsI3NlYXJjaEZpZWxkICovCiAgICBwcml2YXRlIFZhclN5bWJvbCBzZWFyY2hGaWVsZChDbGFzc1N5bWJvbCB0c3ltLCBOYW1lIGZpZWxkTmFtZSwgU2V0PENsYXNzU3ltYm9sPiBzZWFyY2hlZCkgewogICAgICAgIGlmIChzZWFyY2hlZC5jb250YWlucyh0c3ltKSkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICAgICAgc2VhcmNoZWQuYWRkKHRzeW0pOwoKICAgICAgICBmb3IgKFN5bWJvbCBzeW0gOiB0c3ltLm1lbWJlcnMoKS5nZXRTeW1ib2xzQnlOYW1lKGZpZWxkTmFtZSkpIHsKICAgICAgICAgICAgaWYgKHN5bS5raW5kID09IFZBUikgewogICAgICAgICAgICAgICAgcmV0dXJuIChWYXJTeW1ib2wpc3ltOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyMjIyBJZiB3ZSBmb3VuZCBhIFZhclN5bWJvbCBhYm92ZSwgYnV0IHdoaWNoIGRpZCBub3QgcGFzcwogICAgICAgIC8vIyMjIHRoZSBtb2RpZmllciBmaWx0ZXIsIHdlIHNob3VsZCByZXR1cm4gZmFpbHVyZSBoZXJlIQoKICAgICAgICBDbGFzc1N5bWJvbCBlbmNsID0gdHN5bS5vd25lci5lbmNsQ2xhc3MoKTsKICAgICAgICBpZiAoZW5jbCAhPSBudWxsKSB7CiAgICAgICAgICAgIFZhclN5bWJvbCB2c3ltID0gc2VhcmNoRmllbGQoZW5jbCwgZmllbGROYW1lLCBzZWFyY2hlZCk7CiAgICAgICAgICAgIGlmICh2c3ltICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIHJldHVybiB2c3ltOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBzZWFyY2ggc3VwZXJjbGFzcwogICAgICAgIFR5cGUgc3VwZXJjbGFzcyA9IHRzeW0uZ2V0U3VwZXJjbGFzcygpOwogICAgICAgIGlmIChzdXBlcmNsYXNzLnRzeW0gIT0gbnVsbCkgewogICAgICAgICAgICBWYXJTeW1ib2wgdnN5bSA9IHNlYXJjaEZpZWxkKChDbGFzc1N5bWJvbCkgc3VwZXJjbGFzcy50c3ltLCBmaWVsZE5hbWUsIHNlYXJjaGVkKTsKICAgICAgICAgICAgaWYgKHZzeW0gIT0gbnVsbCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHZzeW07CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIHNlYXJjaCBpbnRlcmZhY2VzCiAgICAgICAgTGlzdDxUeXBlPiBpbnRmcyA9IHRzeW0uZ2V0SW50ZXJmYWNlcygpOwogICAgICAgIGZvciAoTGlzdDxUeXBlPiBsID0gaW50ZnM7IGwubm9uRW1wdHkoKTsgbCA9IGwudGFpbCkgewogICAgICAgICAgICBUeXBlIGludGYgPSBsLmhlYWQ7CiAgICAgICAgICAgIGlmIChpbnRmLmlzRXJyb25lb3VzKCkpIGNvbnRpbnVlOwogICAgICAgICAgICBWYXJTeW1ib2wgdnN5bSA9IHNlYXJjaEZpZWxkKChDbGFzc1N5bWJvbCkgaW50Zi50c3ltLCBmaWVsZE5hbWUsIHNlYXJjaGVkKTsKICAgICAgICAgICAgaWYgKHZzeW0gIT0gbnVsbCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHZzeW07CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIC8qKiBAc2VlIGNvbS5zdW4udG9vbHMuamF2YWRvYy5DbGFzc0RvY0ltcGwjZmluZENvbnN0cnVjdG9yICovCiAgICBNZXRob2RTeW1ib2wgZmluZENvbnN0cnVjdG9yKENsYXNzU3ltYm9sIHRzeW0sIExpc3Q8VHlwZT4gcGFyYW1UeXBlcykgewogICAgICAgIGZvciAoU3ltYm9sIHN5bSA6IHRzeW0ubWVtYmVycygpLmdldFN5bWJvbHNCeU5hbWUobmFtZXMuaW5pdCkpIHsKICAgICAgICAgICAgaWYgKHN5bS5raW5kID09IE1USCkgewogICAgICAgICAgICAgICAgaWYgKGhhc1BhcmFtZXRlclR5cGVzKChNZXRob2RTeW1ib2wpIHN5bSwgcGFyYW1UeXBlcykpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gKE1ldGhvZFN5bWJvbCkgc3ltOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIC8qKiBAc2VlIGNvbS5zdW4udG9vbHMuamF2YWRvYy5DbGFzc0RvY0ltcGwjZmluZE1ldGhvZCAqLwogICAgcHJpdmF0ZSBNZXRob2RTeW1ib2wgZmluZE1ldGhvZChDbGFzc1N5bWJvbCB0c3ltLCBOYW1lIG1ldGhvZE5hbWUsIExpc3Q8VHlwZT4gcGFyYW1UeXBlcykgewogICAgICAgIHJldHVybiBzZWFyY2hNZXRob2QodHN5bSwgbWV0aG9kTmFtZSwgcGFyYW1UeXBlcywgbmV3IEhhc2hTZXQ8PigpKTsKICAgIH0KCiAgICAvKiogQHNlZSBjb20uc3VuLnRvb2xzLmphdmFkb2MuQ2xhc3NEb2NJbXBsI3NlYXJjaE1ldGhvZCAqLwogICAgcHJpdmF0ZSBNZXRob2RTeW1ib2wgc2VhcmNoTWV0aG9kKENsYXNzU3ltYm9sIHRzeW0sIE5hbWUgbWV0aG9kTmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTGlzdDxUeXBlPiBwYXJhbVR5cGVzLCBTZXQ8Q2xhc3NTeW1ib2w+IHNlYXJjaGVkKSB7CiAgICAgICAgLy8jIyMgTm90ZSB0aGF0IHRoaXMgc2VhcmNoIGlzIG5vdCBuZWNlc3NhcmlseSB3aGF0IHRoZSBjb21waWxlciB3b3VsZCBkbyEKCiAgICAgICAgLy8gZG8gbm90IG1hdGNoIGNvbnN0cnVjdG9ycwogICAgICAgIGlmIChtZXRob2ROYW1lID09IG5hbWVzLmluaXQpCiAgICAgICAgICAgIHJldHVybiBudWxsOwoKICAgICAgICBpZiAoc2VhcmNoZWQuY29udGFpbnModHN5bSkpCiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIHNlYXJjaGVkLmFkZCh0c3ltKTsKCiAgICAgICAgLy8gc2VhcmNoIGN1cnJlbnQgY2xhc3MKCiAgICAgICAgLy8jIyMgVXNpbmcgbW9kaWZpZXIgZmlsdGVyIGhlcmUgaXNuJ3QgcmVhbGx5IGNvcnJlY3QsCiAgICAgICAgLy8jIyMgYnV0IGVtdWxhdGVzIHRoZSBvbGQgYmVoYXZpb3IuICBJbnN0ZWFkLCB3ZSBzaG91bGQKICAgICAgICAvLyMjIyBhcHBseSB0aGUgbm9ybWFsIHJ1bGVzIG9mIHZpc2liaWxpdHkgYW5kIGluaGVyaXRhbmNlLgoKICAgICAgICBpZiAocGFyYW1UeXBlcyA9PSBudWxsKSB7CiAgICAgICAgICAgIC8vIElmIG5vIHBhcmFtZXRlcnMgc3BlY2lmaWVkLCB3ZSBhcmUgYWxsb3dlZCB0byByZXR1cm4KICAgICAgICAgICAgLy8gYW55IG1ldGhvZCB3aXRoIGEgbWF0Y2hpbmcgbmFtZS4gIEluIHByYWN0aWNlLCB0aGUgb2xkCiAgICAgICAgICAgIC8vIGNvZGUgcmV0dXJuZWQgdGhlIGZpcnN0IG1ldGhvZCwgd2hpY2ggaXMgbm93IHRoZSBsYXN0IQogICAgICAgICAgICAvLyBJbiBvcmRlciB0byBwcm92aWRlIHRleHR1YWxseSBpZGVudGljYWwgcmVzdWx0cywgd2UKICAgICAgICAgICAgLy8gYXR0ZW1wdCB0byBlbXVsYXRlIHRoZSBvbGQgYmVoYXZpb3IuCiAgICAgICAgICAgIE1ldGhvZFN5bWJvbCBsYXN0Rm91bmQgPSBudWxsOwogICAgICAgICAgICBmb3IgKFN5bWJvbCBzeW0gOiB0c3ltLm1lbWJlcnMoKS5nZXRTeW1ib2xzQnlOYW1lKG1ldGhvZE5hbWUpKSB7CiAgICAgICAgICAgICAgICBpZiAoc3ltLmtpbmQgPT0gTVRIKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHN5bS5uYW1lID09IG1ldGhvZE5hbWUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgbGFzdEZvdW5kID0gKE1ldGhvZFN5bWJvbClzeW07CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChsYXN0Rm91bmQgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgcmV0dXJuIGxhc3RGb3VuZDsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGZvciAoU3ltYm9sIHN5bSA6IHRzeW0ubWVtYmVycygpLmdldFN5bWJvbHNCeU5hbWUobWV0aG9kTmFtZSkpIHsKICAgICAgICAgICAgICAgIGlmIChzeW0gIT0gbnVsbCAmJgogICAgICAgICAgICAgICAgICAgIHN5bS5raW5kID09IE1USCkgewogICAgICAgICAgICAgICAgICAgIGlmIChoYXNQYXJhbWV0ZXJUeXBlcygoTWV0aG9kU3ltYm9sKSBzeW0sIHBhcmFtVHlwZXMpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAoTWV0aG9kU3ltYm9sKSBzeW07CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyMjIyBJZiB3ZSBmb3VuZCBhIE1ldGhvZFN5bWJvbCBhYm92ZSwgYnV0IHdoaWNoIGRpZCBub3QgcGFzcwogICAgICAgIC8vIyMjIHRoZSBtb2RpZmllciBmaWx0ZXIsIHdlIHNob3VsZCByZXR1cm4gZmFpbHVyZSBoZXJlIQoKICAgICAgICAvLyBzZWFyY2ggc3VwZXJjbGFzcwogICAgICAgIFR5cGUgc3VwZXJjbGFzcyA9IHRzeW0uZ2V0U3VwZXJjbGFzcygpOwogICAgICAgIGlmIChzdXBlcmNsYXNzLnRzeW0gIT0gbnVsbCkgewogICAgICAgICAgICBNZXRob2RTeW1ib2wgbXN5bSA9IHNlYXJjaE1ldGhvZCgoQ2xhc3NTeW1ib2wpIHN1cGVyY2xhc3MudHN5bSwgbWV0aG9kTmFtZSwgcGFyYW1UeXBlcywgc2VhcmNoZWQpOwogICAgICAgICAgICBpZiAobXN5bSAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gbXN5bTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gc2VhcmNoIGludGVyZmFjZXMKICAgICAgICBMaXN0PFR5cGU+IGludGZzID0gdHN5bS5nZXRJbnRlcmZhY2VzKCk7CiAgICAgICAgZm9yIChMaXN0PFR5cGU+IGwgPSBpbnRmczsgbC5ub25FbXB0eSgpOyBsID0gbC50YWlsKSB7CiAgICAgICAgICAgIFR5cGUgaW50ZiA9IGwuaGVhZDsKICAgICAgICAgICAgaWYgKGludGYuaXNFcnJvbmVvdXMoKSkgY29udGludWU7CiAgICAgICAgICAgIE1ldGhvZFN5bWJvbCBtc3ltID0gc2VhcmNoTWV0aG9kKChDbGFzc1N5bWJvbCkgaW50Zi50c3ltLCBtZXRob2ROYW1lLCBwYXJhbVR5cGVzLCBzZWFyY2hlZCk7CiAgICAgICAgICAgIGlmIChtc3ltICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIHJldHVybiBtc3ltOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBzZWFyY2ggZW5jbG9zaW5nIGNsYXNzCiAgICAgICAgQ2xhc3NTeW1ib2wgZW5jbCA9IHRzeW0ub3duZXIuZW5jbENsYXNzKCk7CiAgICAgICAgaWYgKGVuY2wgIT0gbnVsbCkgewogICAgICAgICAgICBNZXRob2RTeW1ib2wgbXN5bSA9IHNlYXJjaE1ldGhvZChlbmNsLCBtZXRob2ROYW1lLCBwYXJhbVR5cGVzLCBzZWFyY2hlZCk7CiAgICAgICAgICAgIGlmIChtc3ltICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIHJldHVybiBtc3ltOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICAvKiogQHNlZSBjb20uc3VuLnRvb2xzLmphdmFkb2MuQ2xhc3NEb2NJbXBsICovCiAgICBwcml2YXRlIGJvb2xlYW4gaGFzUGFyYW1ldGVyVHlwZXMoTWV0aG9kU3ltYm9sIG1ldGhvZCwgTGlzdDxUeXBlPiBwYXJhbVR5cGVzKSB7CiAgICAgICAgaWYgKHBhcmFtVHlwZXMgPT0gbnVsbCkKICAgICAgICAgICAgcmV0dXJuIHRydWU7CgogICAgICAgIGlmIChtZXRob2QucGFyYW1zKCkuc2l6ZSgpICE9IHBhcmFtVHlwZXMuc2l6ZSgpKQogICAgICAgICAgICByZXR1cm4gZmFsc2U7CgogICAgICAgIExpc3Q8VHlwZT4gbWV0aG9kUGFyYW1UeXBlcyA9IHR5cGVzLmVyYXN1cmVSZWN1cnNpdmUobWV0aG9kLmFzVHlwZSgpKS5nZXRQYXJhbWV0ZXJUeXBlcygpOwoKICAgICAgICByZXR1cm4gKFR5cGUuaXNFcnJvbmVvdXMocGFyYW1UeXBlcykpCiAgICAgICAgICAgID8gZnV6enlNYXRjaChwYXJhbVR5cGVzLCBtZXRob2RQYXJhbVR5cGVzKQogICAgICAgICAgICA6IHR5cGVzLmlzU2FtZVR5cGVzKHBhcmFtVHlwZXMsIG1ldGhvZFBhcmFtVHlwZXMpOwogICAgfQoKICAgIGJvb2xlYW4gZnV6enlNYXRjaChMaXN0PFR5cGU+IHBhcmFtVHlwZXMsIExpc3Q8VHlwZT4gbWV0aG9kUGFyYW1UeXBlcykgewogICAgICAgIExpc3Q8VHlwZT4gbDEgPSBwYXJhbVR5cGVzOwogICAgICAgIExpc3Q8VHlwZT4gbDIgPSBtZXRob2RQYXJhbVR5cGVzOwogICAgICAgIHdoaWxlIChsMS5ub25FbXB0eSgpKSB7CiAgICAgICAgICAgIGlmICghZnV6enlNYXRjaChsMS5oZWFkLCBsMi5oZWFkKSkKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgbDEgPSBsMS50YWlsOwogICAgICAgICAgICBsMiA9IGwyLnRhaWw7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIGJvb2xlYW4gZnV6enlNYXRjaChUeXBlIHBhcmFtVHlwZSwgVHlwZSBtZXRob2RQYXJhbVR5cGUpIHsKICAgICAgICBCb29sZWFuIGIgPSBmdXp6eU1hdGNoZXIudmlzaXQocGFyYW1UeXBlLCBtZXRob2RQYXJhbVR5cGUpOwogICAgICAgIHJldHVybiAoYiA9PSBCb29sZWFuLlRSVUUpOwogICAgfQoKICAgIFR5cGVSZWxhdGlvbiBmdXp6eU1hdGNoZXIgPSBuZXcgVHlwZVJlbGF0aW9uKCkgewogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBCb29sZWFuIHZpc2l0VHlwZShUeXBlIHQsIFR5cGUgcykgewogICAgICAgICAgICBpZiAodCA9PSBzKQogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CgogICAgICAgICAgICBpZiAocy5pc1BhcnRpYWwoKSkKICAgICAgICAgICAgICAgIHJldHVybiB2aXNpdChzLCB0KTsKCiAgICAgICAgICAgIHN3aXRjaCAodC5nZXRUYWcoKSkgewogICAgICAgICAgICBjYXNlIEJZVEU6IGNhc2UgQ0hBUjogY2FzZSBTSE9SVDogY2FzZSBJTlQ6IGNhc2UgTE9ORzogY2FzZSBGTE9BVDoKICAgICAgICAgICAgY2FzZSBET1VCTEU6IGNhc2UgQk9PTEVBTjogY2FzZSBWT0lEOiBjYXNlIEJPVDogY2FzZSBOT05FOgogICAgICAgICAgICAgICAgcmV0dXJuIHQuaGFzVGFnKHMuZ2V0VGFnKCkpOwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCJmdXp6eU1hdGNoZXIgIiArIHQuZ2V0VGFnKCkpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQm9vbGVhbiB2aXNpdEFycmF5VHlwZShBcnJheVR5cGUgdCwgVHlwZSBzKSB7CiAgICAgICAgICAgIGlmICh0ID09IHMpCiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKCiAgICAgICAgICAgIGlmIChzLmlzUGFydGlhbCgpKQogICAgICAgICAgICAgICAgcmV0dXJuIHZpc2l0KHMsIHQpOwoKICAgICAgICAgICAgcmV0dXJuIHMuaGFzVGFnKEFSUkFZKQogICAgICAgICAgICAgICAgJiYgdmlzaXQodC5lbGVtdHlwZSwgdHlwZXMuZWxlbXR5cGUocykpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIEJvb2xlYW4gdmlzaXRDbGFzc1R5cGUoQ2xhc3NUeXBlIHQsIFR5cGUgcykgewogICAgICAgICAgICBpZiAodCA9PSBzKQogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CgogICAgICAgICAgICBpZiAocy5pc1BhcnRpYWwoKSkKICAgICAgICAgICAgICAgIHJldHVybiB2aXNpdChzLCB0KTsKCiAgICAgICAgICAgIHJldHVybiB0LnRzeW0gPT0gcy50c3ltOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIEJvb2xlYW4gdmlzaXRFcnJvclR5cGUoRXJyb3JUeXBlIHQsIFR5cGUgcykgewogICAgICAgICAgICByZXR1cm4gcy5oYXNUYWcoQ0xBU1MpCiAgICAgICAgICAgICAgICAgICAgJiYgdC50c3ltLm5hbWUgPT0gKChDbGFzc1R5cGUpIHMpLnRzeW0ubmFtZTsKICAgICAgICB9CiAgICB9OwoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIFR5cGVNaXJyb3IgZ2V0VHlwZU1pcnJvcihUcmVlUGF0aCBwYXRoKSB7CiAgICAgICAgVHJlZSB0ID0gcGF0aC5nZXRMZWFmKCk7CiAgICAgICAgVHlwZSB0eSA9ICgoSkNUcmVlKXQpLnR5cGU7CiAgICAgICAgcmV0dXJuIHR5ID09IG51bGwgPyBudWxsIDogdHkuc3RyaXBNZXRhZGF0YUlmTmVlZGVkKCk7CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICBwdWJsaWMgSmF2YWNTY29wZSBnZXRTY29wZShUcmVlUGF0aCBwYXRoKSB7CiAgICAgICAgcmV0dXJuIEphdmFjU2NvcGUuY3JlYXRlKGdldEF0dHJDb250ZXh0KHBhdGgpKTsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBTdHJpbmcgZ2V0RG9jQ29tbWVudChUcmVlUGF0aCBwYXRoKSB7CiAgICAgICAgQ29tcGlsYXRpb25Vbml0VHJlZSB0ID0gcGF0aC5nZXRDb21waWxhdGlvblVuaXQoKTsKICAgICAgICBUcmVlIGxlYWYgPSBwYXRoLmdldExlYWYoKTsKICAgICAgICBpZiAodCBpbnN0YW5jZW9mIEpDVHJlZS5KQ0NvbXBpbGF0aW9uVW5pdCAmJiBsZWFmIGluc3RhbmNlb2YgSkNUcmVlKSB7CiAgICAgICAgICAgIEpDQ29tcGlsYXRpb25Vbml0IGN1ID0gKEpDQ29tcGlsYXRpb25Vbml0KSB0OwogICAgICAgICAgICBpZiAoY3UuZG9jQ29tbWVudHMgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgcmV0dXJuIGN1LmRvY0NvbW1lbnRzLmdldENvbW1lbnRUZXh0KChKQ1RyZWUpIGxlYWYpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIERvY0NvbW1lbnRUcmVlIGdldERvY0NvbW1lbnRUcmVlKFRyZWVQYXRoIHBhdGgpIHsKICAgICAgICBDb21waWxhdGlvblVuaXRUcmVlIHQgPSBwYXRoLmdldENvbXBpbGF0aW9uVW5pdCgpOwogICAgICAgIFRyZWUgbGVhZiA9IHBhdGguZ2V0TGVhZigpOwogICAgICAgIGlmICh0IGluc3RhbmNlb2YgSkNUcmVlLkpDQ29tcGlsYXRpb25Vbml0ICYmIGxlYWYgaW5zdGFuY2VvZiBKQ1RyZWUpIHsKICAgICAgICAgICAgSkNDb21waWxhdGlvblVuaXQgY3UgPSAoSkNDb21waWxhdGlvblVuaXQpIHQ7CiAgICAgICAgICAgIGlmIChjdS5kb2NDb21tZW50cyAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gY3UuZG9jQ29tbWVudHMuZ2V0Q29tbWVudFRyZWUoKEpDVHJlZSkgbGVhZik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICBwdWJsaWMgRG9jQ29tbWVudFRyZWUgZ2V0RG9jQ29tbWVudFRyZWUoRWxlbWVudCBlKSB7CiAgICAgICAgVHJlZVBhdGggcGF0aCA9IGdldFBhdGgoZSk7CiAgICAgICAgaWYgKHBhdGggPT0gbnVsbCkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGdldERvY0NvbW1lbnRUcmVlKHBhdGgpOwogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIERvY0NvbW1lbnRUcmVlIGdldERvY0NvbW1lbnRUcmVlKEVsZW1lbnQgZSwgU3RyaW5nIHJlbGF0aXZlRmlsZU5hbWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgUGFja2FnZUVsZW1lbnQgcGtnID0gZWxlbWVudHMuZ2V0UGFja2FnZU9mKGUpOwogICAgICAgIEZpbGVPYmplY3QgZmlsZUZvcklucHV0ID0gZmlsZU1hbmFnZXIuZ2V0RmlsZUZvcklucHV0KFN0YW5kYXJkTG9jYXRpb24uU09VUkNFX1BBVEgsCiAgICAgICAgICAgICAgICBwa2cuZ2V0UXVhbGlmaWVkTmFtZSgpLnRvU3RyaW5nKCksIHJlbGF0aXZlRmlsZU5hbWUpOwoKICAgICAgICBpZiAoZmlsZUZvcklucHV0ID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEZpbGVOb3RGb3VuZEV4Y2VwdGlvbihyZWxhdGl2ZUZpbGVOYW1lKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGdldERvY0NvbW1lbnRUcmVlKGZpbGVGb3JJbnB1dCk7CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICBwdWJsaWMgYm9vbGVhbiBpc0FjY2Vzc2libGUoU2NvcGUgc2NvcGUsIFR5cGVFbGVtZW50IHR5cGUpIHsKICAgICAgICBpZiAoc2NvcGUgaW5zdGFuY2VvZiBKYXZhY1Njb3BlICYmIHR5cGUgaW5zdGFuY2VvZiBDbGFzc1N5bWJvbCkgewogICAgICAgICAgICBFbnY8QXR0ckNvbnRleHQ+IGVudiA9ICgoSmF2YWNTY29wZSkgc2NvcGUpLmVudjsKICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUuaXNBY2Nlc3NpYmxlKGVudiwgKENsYXNzU3ltYm9sKXR5cGUsIHRydWUpOwogICAgICAgIH0gZWxzZQogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICBwdWJsaWMgYm9vbGVhbiBpc0FjY2Vzc2libGUoU2NvcGUgc2NvcGUsIEVsZW1lbnQgbWVtYmVyLCBEZWNsYXJlZFR5cGUgdHlwZSkgewogICAgICAgIGlmIChzY29wZSBpbnN0YW5jZW9mIEphdmFjU2NvcGUKICAgICAgICAgICAgICAgICYmIG1lbWJlciBpbnN0YW5jZW9mIFN5bWJvbAogICAgICAgICAgICAgICAgJiYgdHlwZSBpbnN0YW5jZW9mIGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5UeXBlKSB7CiAgICAgICAgICAgIEVudjxBdHRyQ29udGV4dD4gZW52ID0gKChKYXZhY1Njb3BlKSBzY29wZSkuZW52OwogICAgICAgICAgICByZXR1cm4gcmVzb2x2ZS5pc0FjY2Vzc2libGUoZW52LCAoY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlR5cGUpdHlwZSwgKFN5bWJvbCltZW1iZXIsIHRydWUpOwogICAgICAgIH0gZWxzZQogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgcHJpdmF0ZSBFbnY8QXR0ckNvbnRleHQ+IGdldEF0dHJDb250ZXh0KFRyZWVQYXRoIHBhdGgpIHsKICAgICAgICBpZiAoIShwYXRoLmdldExlYWYoKSBpbnN0YW5jZW9mIEpDVHJlZSkpICAvLyBpbXBsaWNpdCBudWxsLWNoZWNrCiAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKCiAgICAgICAgLy8gaWYgd2UncmUgYmVpbmcgaW52b2tlZCBmcm9tIGEgVHJlZSBBUEkgY2xpZW50IHZpYSBwYXJzZS9lbnRlci9hbmFseXplLAogICAgICAgIC8vIHdlIG5lZWQgdG8gbWFrZSBzdXJlIGFsbCB0aGUgY2xhc3NlcyBoYXZlIGJlZW4gZW50ZXJlZDsKICAgICAgICAvLyBpZiB3ZSdyZSBiZWluZyBpbnZva2VkIGZyb20gSlNSIDE5OSBvciBKU1IgMjY5LCB0aGVuIHRoZSBjbGFzc2VzCiAgICAgICAgLy8gd2lsbCBhbHJlYWR5IGhhdmUgYmVlbiBlbnRlcmVkLgogICAgICAgIGlmIChqYXZhY1Rhc2tJbXBsICE9IG51bGwpIHsKICAgICAgICAgICAgamF2YWNUYXNrSW1wbC5lbnRlcihudWxsKTsKICAgICAgICB9CgogICAgICAgIEpDQ29tcGlsYXRpb25Vbml0IHVuaXQgPSAoSkNDb21waWxhdGlvblVuaXQpIHBhdGguZ2V0Q29tcGlsYXRpb25Vbml0KCk7CiAgICAgICAgQ29waWVyIGNvcGllciA9IGNyZWF0ZUNvcGllcih0cmVlTWFrZXIuZm9yVG9wbGV2ZWwodW5pdCkpOwoKICAgICAgICBFbnY8QXR0ckNvbnRleHQ+IGVudiA9IG51bGw7CiAgICAgICAgSkNNZXRob2REZWNsIG1ldGhvZCA9IG51bGw7CiAgICAgICAgSkNWYXJpYWJsZURlY2wgZmllbGQgPSBudWxsOwoKICAgICAgICBMaXN0PFRyZWU+IGwgPSBMaXN0Lm5pbCgpOwogICAgICAgIFRyZWVQYXRoIHAgPSBwYXRoOwogICAgICAgIHdoaWxlIChwICE9IG51bGwpIHsKICAgICAgICAgICAgbCA9IGwucHJlcGVuZChwLmdldExlYWYoKSk7CiAgICAgICAgICAgIHAgPSBwLmdldFBhcmVudFBhdGgoKTsKICAgICAgICB9CgogICAgICAgIGZvciAoIDsgbC5ub25FbXB0eSgpOyBsID0gbC50YWlsKSB7CiAgICAgICAgICAgIFRyZWUgdHJlZSA9IGwuaGVhZDsKICAgICAgICAgICAgc3dpdGNoICh0cmVlLmdldEtpbmQoKSkgewogICAgICAgICAgICAgICAgY2FzZSBDT01QSUxBVElPTl9VTklUOgovLyAgICAgICAgICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKCJDT01QOiAiICsgKChKQ0NvbXBpbGF0aW9uVW5pdCl0cmVlKS5zb3VyY2VmaWxlKTsKICAgICAgICAgICAgICAgICAgICBlbnYgPSBlbnRlci5nZXRUb3BMZXZlbEVudigoSkNDb21waWxhdGlvblVuaXQpdHJlZSk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIEFOTk9UQVRJT05fVFlQRToKICAgICAgICAgICAgICAgIGNhc2UgQ0xBU1M6CiAgICAgICAgICAgICAgICBjYXNlIEVOVU06CiAgICAgICAgICAgICAgICBjYXNlIElOVEVSRkFDRToKLy8gICAgICAgICAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigiQ0xBU1M6ICIgKyAoKEpDQ2xhc3NEZWNsKXRyZWUpLnN5bS5nZXRTaW1wbGVOYW1lKCkpOwogICAgICAgICAgICAgICAgICAgIGVudiA9IGVudGVyLmdldENsYXNzRW52KCgoSkNDbGFzc0RlY2wpdHJlZSkuc3ltKTsKICAgICAgICAgICAgICAgICAgICBpZiAoZW52ID09IG51bGwpIHJldHVybiBudWxsOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBNRVRIT0Q6Ci8vICAgICAgICAgICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oIk1FVEhPRDogIiArICgoSkNNZXRob2REZWNsKXRyZWUpLnN5bS5nZXRTaW1wbGVOYW1lKCkpOwogICAgICAgICAgICAgICAgICAgIG1ldGhvZCA9IChKQ01ldGhvZERlY2wpdHJlZTsKICAgICAgICAgICAgICAgICAgICBlbnYgPSBtZW1iZXJFbnRlci5nZXRNZXRob2RFbnYobWV0aG9kLCBlbnYpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBWQVJJQUJMRToKLy8gICAgICAgICAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigiRklFTEQ6ICIgKyAoKEpDVmFyaWFibGVEZWNsKXRyZWUpLnN5bS5nZXRTaW1wbGVOYW1lKCkpOwogICAgICAgICAgICAgICAgICAgIGZpZWxkID0gKEpDVmFyaWFibGVEZWNsKXRyZWU7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIEJMT0NLOiB7Ci8vICAgICAgICAgICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oIkJMT0NLOiAiKTsKICAgICAgICAgICAgICAgICAgICBpZiAobWV0aG9kICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFzc2VydC5jaGVjayhtZXRob2QuYm9keSA9PSB0cmVlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZC5ib2R5ID0gY29waWVyLmNvcHkoKEpDQmxvY2spdHJlZSwgKEpDVHJlZSkgcGF0aC5nZXRMZWFmKCkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZW52ID0gYXR0cmliU3RhdFRvVHJlZShtZXRob2QuYm9keSwgZW52LCBjb3BpZXIubGVhZkNvcHkpOwogICAgICAgICAgICAgICAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kLmJvZHkgPSAoSkNCbG9jaykgdHJlZTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIEpDQmxvY2sgYm9keSA9IGNvcGllci5jb3B5KChKQ0Jsb2NrKXRyZWUsIChKQ1RyZWUpIHBhdGguZ2V0TGVhZigpKTsKICAgICAgICAgICAgICAgICAgICAgICAgZW52ID0gYXR0cmliU3RhdFRvVHJlZShib2R5LCBlbnYsIGNvcGllci5sZWFmQ29weSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHJldHVybiBlbnY7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBkZWZhdWx0OgovLyAgICAgICAgICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKCJERUZBVUxUOiAiICsgdHJlZS5nZXRLaW5kKCkpOwogICAgICAgICAgICAgICAgICAgIGlmIChmaWVsZCAhPSBudWxsICYmIGZpZWxkLmdldEluaXRpYWxpemVyKCkgPT0gdHJlZSkgewogICAgICAgICAgICAgICAgICAgICAgICBlbnYgPSBtZW1iZXJFbnRlci5nZXRJbml0RW52KGZpZWxkLCBlbnYpOwogICAgICAgICAgICAgICAgICAgICAgICBKQ0V4cHJlc3Npb24gZXhwciA9IGNvcGllci5jb3B5KChKQ0V4cHJlc3Npb24pdHJlZSwgKEpDVHJlZSkgcGF0aC5nZXRMZWFmKCkpOwogICAgICAgICAgICAgICAgICAgICAgICBlbnYgPSBhdHRyaWJFeHByVG9UcmVlKGV4cHIsIGVudiwgY29waWVyLmxlYWZDb3B5KTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGVudjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIChmaWVsZCAhPSBudWxsKSA/IG1lbWJlckVudGVyLmdldEluaXRFbnYoZmllbGQsIGVudikgOiBlbnY7CiAgICB9CgogICAgcHJpdmF0ZSBFbnY8QXR0ckNvbnRleHQ+IGF0dHJpYlN0YXRUb1RyZWUoSkNUcmVlIHN0YXQsIEVudjxBdHRyQ29udGV4dD5lbnYsIEpDVHJlZSB0cmVlKSB7CiAgICAgICAgSmF2YUZpbGVPYmplY3QgcHJldiA9IGxvZy51c2VTb3VyY2UoZW52LnRvcGxldmVsLnNvdXJjZWZpbGUpOwogICAgICAgIHRyeSB7CiAgICAgICAgICAgIHJldHVybiBhdHRyLmF0dHJpYlN0YXRUb1RyZWUoc3RhdCwgZW52LCB0cmVlKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICBsb2cudXNlU291cmNlKHByZXYpOwogICAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIEVudjxBdHRyQ29udGV4dD4gYXR0cmliRXhwclRvVHJlZShKQ0V4cHJlc3Npb24gZXhwciwgRW52PEF0dHJDb250ZXh0PmVudiwgSkNUcmVlIHRyZWUpIHsKICAgICAgICBKYXZhRmlsZU9iamVjdCBwcmV2ID0gbG9nLnVzZVNvdXJjZShlbnYudG9wbGV2ZWwuc291cmNlZmlsZSk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgcmV0dXJuIGF0dHIuYXR0cmliRXhwclRvVHJlZShleHByLCBlbnYsIHRyZWUpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgIGxvZy51c2VTb3VyY2UocHJldik7CiAgICAgICAgfQogICAgfQoKICAgIHN0YXRpYyBKYXZhRmlsZU9iamVjdCBhc0phdmFGaWxlT2JqZWN0KEZpbGVPYmplY3QgZmlsZU9iamVjdCkgewogICAgICAgIEphdmFGaWxlT2JqZWN0IGpmbyA9IG51bGw7CgogICAgICAgIGlmIChmaWxlT2JqZWN0IGluc3RhbmNlb2YgSmF2YUZpbGVPYmplY3QpIHsKICAgICAgICAgICAgamZvID0gKEphdmFGaWxlT2JqZWN0KSBmaWxlT2JqZWN0OwogICAgICAgICAgICBjaGVja0h0bWxLaW5kKGZpbGVPYmplY3QsIEtpbmQuSFRNTCk7CiAgICAgICAgICAgIHJldHVybiBqZm87CiAgICAgICAgfQoKICAgICAgICBjaGVja0h0bWxLaW5kKGZpbGVPYmplY3QpOwogICAgICAgIGpmbyA9IG5ldyBIdG1sRmlsZU9iamVjdChmaWxlT2JqZWN0KTsKICAgICAgICByZXR1cm4gamZvOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIHZvaWQgY2hlY2tIdG1sS2luZChGaWxlT2JqZWN0IGZpbGVPYmplY3QpIHsKICAgICAgICBjaGVja0h0bWxLaW5kKGZpbGVPYmplY3QsIEJhc2VGaWxlTWFuYWdlci5nZXRLaW5kKGZpbGVPYmplY3QuZ2V0TmFtZSgpKSk7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBjaGVja0h0bWxLaW5kKEZpbGVPYmplY3QgZmlsZU9iamVjdCwgSmF2YUZpbGVPYmplY3QuS2luZCBraW5kKSB7CiAgICAgICAgaWYgKGtpbmQgIT0gSmF2YUZpbGVPYmplY3QuS2luZC5IVE1MKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkhUTUwgZmlsZSBleHBlY3RlZDoiICsgZmlsZU9iamVjdC5nZXROYW1lKCkpOwogICAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBIdG1sRmlsZU9iamVjdCBleHRlbmRzIEZvcndhcmRpbmdGaWxlT2JqZWN0PEZpbGVPYmplY3Q+CiAgICAgICAgICAgIGltcGxlbWVudHMgSmF2YUZpbGVPYmplY3QgewoKICAgICAgICBwdWJsaWMgSHRtbEZpbGVPYmplY3QoRmlsZU9iamVjdCBmaWxlT2JqZWN0KSB7CiAgICAgICAgICAgIHN1cGVyKGZpbGVPYmplY3QpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSKQogICAgICAgIHB1YmxpYyBLaW5kIGdldEtpbmQoKSB7CiAgICAgICAgICAgIHJldHVybiBCYXNlRmlsZU1hbmFnZXIuZ2V0S2luZChmaWxlT2JqZWN0LmdldE5hbWUoKSk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICAgICAgcHVibGljIGJvb2xlYW4gaXNOYW1lQ29tcGF0aWJsZShTdHJpbmcgc2ltcGxlTmFtZSwgS2luZCBraW5kKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgICAgICBwdWJsaWMgTmVzdGluZ0tpbmQgZ2V0TmVzdGluZ0tpbmQoKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSKQogICAgICAgIHB1YmxpYyBNb2RpZmllciBnZXRBY2Nlc3NMZXZlbCgpIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIERvY0NvbW1lbnRUcmVlIGdldERvY0NvbW1lbnRUcmVlKEZpbGVPYmplY3QgZmlsZU9iamVjdCkgewogICAgICAgIEphdmFGaWxlT2JqZWN0IGpmbyA9IGFzSmF2YUZpbGVPYmplY3QoZmlsZU9iamVjdCk7CiAgICAgICAgRGlhZ25vc3RpY1NvdXJjZSBkaWFnU291cmNlID0gbmV3IERpYWdub3N0aWNTb3VyY2UoamZvLCBsb2cpOwoKICAgICAgICBmaW5hbCBDb21tZW50IGNvbW1lbnQgPSBuZXcgQ29tbWVudCgpIHsKICAgICAgICAgICAgaW50IG9mZnNldCA9IDA7CiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgU3RyaW5nIGdldFRleHQoKSB7CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIENoYXJTZXF1ZW5jZSByYXdEb2MgPSBmaWxlT2JqZWN0LmdldENoYXJDb250ZW50KHRydWUpOwogICAgICAgICAgICAgICAgICAgIFBhdHRlcm4gYm9keVBhdCA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBQYXR0ZXJuLmNvbXBpbGUoIig/aXMpLio/PGJvZHlcXGJbXj5dKj4oLiopPC9ib2R5XFxiLioiKTsKICAgICAgICAgICAgICAgICAgICBNYXRjaGVyIG0gPSBib2R5UGF0Lm1hdGNoZXIocmF3RG9jKTsKICAgICAgICAgICAgICAgICAgICBpZiAobS5tYXRjaGVzKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgb2Zmc2V0ID0gbS5lbmQoMSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBtLmdyb3VwKDEpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEFzc3VtZSBkb2NsaW50IHdpbGwgZG8gdGhlIHJpZ2h0IHRoaW5nLgogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gIiI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gaWdub3JlKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gZG8gbm90aGluZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuICIiOwogICAgICAgICAgICB9CgogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHVibGljIGludCBnZXRTb3VyY2VQb3MoaW50IGluZGV4KSB7CiAgICAgICAgICAgICAgICByZXR1cm4gb2Zmc2V0ICsgaW5kZXg7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgQ29tbWVudFN0eWxlIGdldFN0eWxlKCkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc0RlcHJlY2F0ZWQoKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKICAgICAgICAgICAgfQogICAgICAgIH07CgogICAgICAgIHJldHVybiBuZXcgRG9jQ29tbWVudFBhcnNlcihwYXJzZXIsIGRpYWdTb3VyY2UsIGNvbW1lbnQpLnBhcnNlKCk7CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICBwdWJsaWMgRG9jVHJlZVBhdGggZ2V0RG9jVHJlZVBhdGgoRmlsZU9iamVjdCBmaWxlT2JqZWN0LCBQYWNrYWdlRWxlbWVudCBwYWNrYWdlRWxlbWVudCkgewogICAgICAgIEphdmFGaWxlT2JqZWN0IGpmbyA9IGFzSmF2YUZpbGVPYmplY3QoZmlsZU9iamVjdCk7CiAgICAgICAgRG9jQ29tbWVudFRyZWUgZG9jQ29tbWVudFRyZWUgPSBnZXREb2NDb21tZW50VHJlZShqZm8pOwogICAgICAgIFRyZWVQYXRoIHRyZWVQYXRoID0gbWFrZVRyZWVQYXRoKChQYWNrYWdlU3ltYm9sKXBhY2thZ2VFbGVtZW50LCBqZm8sIGRvY0NvbW1lbnRUcmVlKTsKICAgICAgICByZXR1cm4gbmV3IERvY1RyZWVQYXRoKHRyZWVQYXRoLCBkb2NDb21tZW50VHJlZSk7CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICBwdWJsaWMgdm9pZCBzZXRCcmVha0l0ZXJhdG9yKEJyZWFrSXRlcmF0b3IgYnJlYWtpdGVyYXRvcikgewogICAgICAgIHRoaXMuYnJlYWtJdGVyYXRvciA9IGJyZWFraXRlcmF0b3I7CiAgICB9CgogICAgLyoqCiAgICAgKiBNYWtlcyBhIGNvcHkgb2YgYSB0cmVlLCBub3RpbmcgdGhlIHZhbHVlIHJlc3VsdGluZyBmcm9tIGNvcHlpbmcgYSBwYXJ0aWN1bGFyIGxlYWYuCiAgICAgKiovCiAgICBwcm90ZWN0ZWQgc3RhdGljIGNsYXNzIENvcGllciBleHRlbmRzIFRyZWVDb3BpZXI8SkNUcmVlPiB7CiAgICAgICAgSkNUcmVlIGxlYWZDb3B5ID0gbnVsbDsKCiAgICAgICAgcHJvdGVjdGVkIENvcGllcihUcmVlTWFrZXIgTSkgewogICAgICAgICAgICBzdXBlcihNKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyA8VCBleHRlbmRzIEpDVHJlZT4gVCBjb3B5KFQgdCwgSkNUcmVlIGxlYWYpIHsKICAgICAgICAgICAgVCB0MiA9IHN1cGVyLmNvcHkodCwgbGVhZik7CiAgICAgICAgICAgIGlmICh0ID09IGxlYWYpCiAgICAgICAgICAgICAgICBsZWFmQ29weSA9IHQyOwogICAgICAgICAgICByZXR1cm4gdDI7CiAgICAgICAgfQogICAgfQoKICAgIHByb3RlY3RlZCBDb3BpZXIgY3JlYXRlQ29waWVyKFRyZWVNYWtlciBtYWtlcikgewogICAgICAgIHJldHVybiBuZXcgQ29waWVyKG1ha2VyKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIG9yaWdpbmFsIHR5cGUgZnJvbSB0aGUgRXJyb3JUeXBlIG9iamVjdC4KICAgICAqIEBwYXJhbSBlcnJvclR5cGUgVGhlIGVycm9yVHlwZSBmb3Igd2hpY2ggd2Ugd2FudCB0byBnZXQgdGhlIG9yaWdpbmFsIHR5cGUuCiAgICAgKiBAcmV0dXJuIFR5cGVNaXJyb3IgY29ycmVzcG9uZGluZyB0byB0aGUgb3JpZ2luYWwgdHlwZSwgcmVwbGFjZWQgYnkgdGhlIEVycm9yVHlwZS4KICAgICAqICAgICAgICAgbm9UeXBlICh0eXBlLnRhZyA9PSBOT05FKSBpcyByZXR1cm5lZCBpZiB0aGVyZSBpcyBubyBvcmlnaW5hbCB0eXBlLgogICAgICovCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBUeXBlTWlycm9yIGdldE9yaWdpbmFsVHlwZShqYXZheC5sYW5nLm1vZGVsLnR5cGUuRXJyb3JUeXBlIGVycm9yVHlwZSkgewogICAgICAgIGlmIChlcnJvclR5cGUgaW5zdGFuY2VvZiBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuVHlwZS5FcnJvclR5cGUpIHsKICAgICAgICAgICAgcmV0dXJuICgoY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlR5cGUuRXJyb3JUeXBlKWVycm9yVHlwZSkuZ2V0T3JpZ2luYWxUeXBlKCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlR5cGUubm9UeXBlOwogICAgfQoKICAgIC8qKgogICAgICogUHJpbnRzIGEgbWVzc2FnZSBvZiB0aGUgc3BlY2lmaWVkIGtpbmQgYXQgdGhlIGxvY2F0aW9uIG9mIHRoZQogICAgICogdHJlZSB3aXRoaW4gdGhlIHByb3ZpZGVkIGNvbXBpbGF0aW9uIHVuaXQKICAgICAqCiAgICAgKiBAcGFyYW0ga2luZCB0aGUga2luZCBvZiBtZXNzYWdlCiAgICAgKiBAcGFyYW0gbXNnICB0aGUgbWVzc2FnZSwgb3IgYW4gZW1wdHkgc3RyaW5nIGlmIG5vbmUKICAgICAqIEBwYXJhbSB0ICAgIHRoZSB0cmVlIHRvIHVzZSBhcyBhIHBvc2l0aW9uIGhpbnQKICAgICAqIEBwYXJhbSByb290IHRoZSBjb21waWxhdGlvbiB1bml0IHRoYXQgY29udGFpbnMgdHJlZQogICAgICovCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyB2b2lkIHByaW50TWVzc2FnZShEaWFnbm9zdGljLktpbmQga2luZCwgQ2hhclNlcXVlbmNlIG1zZywKICAgICAgICAgICAgY29tLnN1bi5zb3VyY2UudHJlZS5UcmVlIHQsCiAgICAgICAgICAgIGNvbS5zdW4uc291cmNlLnRyZWUuQ29tcGlsYXRpb25Vbml0VHJlZSByb290KSB7CiAgICAgICAgcHJpbnRNZXNzYWdlKGtpbmQsIG1zZywgKChKQ1RyZWUpIHQpLnBvcygpLCByb290KTsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyB2b2lkIHByaW50TWVzc2FnZShEaWFnbm9zdGljLktpbmQga2luZCwgQ2hhclNlcXVlbmNlIG1zZywKICAgICAgICAgICAgY29tLnN1bi5zb3VyY2UuZG9jdHJlZS5Eb2NUcmVlIHQsCiAgICAgICAgICAgIGNvbS5zdW4uc291cmNlLmRvY3RyZWUuRG9jQ29tbWVudFRyZWUgYywKICAgICAgICAgICAgY29tLnN1bi5zb3VyY2UudHJlZS5Db21waWxhdGlvblVuaXRUcmVlIHJvb3QpIHsKICAgICAgICBwcmludE1lc3NhZ2Uoa2luZCwgbXNnLCAoKERDVHJlZSkgdCkucG9zKChEQ0RvY0NvbW1lbnQpIGMpLCByb290KTsKICAgIH0KCiAgICBwcml2YXRlIHZvaWQgcHJpbnRNZXNzYWdlKERpYWdub3N0aWMuS2luZCBraW5kLCBDaGFyU2VxdWVuY2UgbXNnLAogICAgICAgICAgICBKQ0RpYWdub3N0aWMuRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcywKICAgICAgICAgICAgY29tLnN1bi5zb3VyY2UudHJlZS5Db21waWxhdGlvblVuaXRUcmVlIHJvb3QpIHsKICAgICAgICBKYXZhRmlsZU9iamVjdCBvbGRTb3VyY2UgPSBudWxsOwogICAgICAgIEphdmFGaWxlT2JqZWN0IG5ld1NvdXJjZSA9IG51bGw7CgogICAgICAgIG5ld1NvdXJjZSA9IHJvb3QuZ2V0U291cmNlRmlsZSgpOwogICAgICAgIGlmIChuZXdTb3VyY2UgPT0gbnVsbCkgewogICAgICAgICAgICBwb3MgPSBudWxsOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIG9sZFNvdXJjZSA9IGxvZy51c2VTb3VyY2UobmV3U291cmNlKTsKICAgICAgICB9CgogICAgICAgIHRyeSB7CiAgICAgICAgICAgIHN3aXRjaCAoa2luZCkgewogICAgICAgICAgICBjYXNlIEVSUk9SOgogICAgICAgICAgICAgICAgbG9nLmVycm9yKERpYWdub3N0aWNGbGFnLk1VTFRJUExFLCBwb3MsICJwcm9jLm1lc3NhZ2VyIiwgbXNnLnRvU3RyaW5nKCkpOwogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIFdBUk5JTkc6CiAgICAgICAgICAgICAgICBsb2cud2FybmluZyhwb3MsICJwcm9jLm1lc3NhZ2VyIiwgbXNnLnRvU3RyaW5nKCkpOwogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIE1BTkRBVE9SWV9XQVJOSU5HOgogICAgICAgICAgICAgICAgbG9nLm1hbmRhdG9yeVdhcm5pbmcocG9zLCAicHJvYy5tZXNzYWdlciIsIG1zZy50b1N0cmluZygpKTsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIGxvZy5ub3RlKHBvcywgInByb2MubWVzc2FnZXIiLCBtc2cudG9TdHJpbmcoKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICBpZiAob2xkU291cmNlICE9IG51bGwpCiAgICAgICAgICAgICAgICBsb2cudXNlU291cmNlKG9sZFNvdXJjZSk7CiAgICAgICAgfQogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIFR5cGVNaXJyb3IgZ2V0THViKENhdGNoVHJlZSB0cmVlKSB7CiAgICAgICAgSkNDYXRjaCBjdCA9IChKQ0NhdGNoKSB0cmVlOwogICAgICAgIEpDVmFyaWFibGVEZWNsIHYgPSBjdC5wYXJhbTsKICAgICAgICBpZiAodi50eXBlICE9IG51bGwgJiYgdi50eXBlLmdldEtpbmQoKSA9PSBUeXBlS2luZC5VTklPTikgewogICAgICAgICAgICBVbmlvbkNsYXNzVHlwZSB1dCA9IChVbmlvbkNsYXNzVHlwZSkgdi50eXBlOwogICAgICAgICAgICByZXR1cm4gdXQuZ2V0THViKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIHYudHlwZTsKICAgICAgICB9CiAgICB9CgogICAgcHJpdmF0ZSBUcmVlUGF0aCBtYWtlVHJlZVBhdGgoZmluYWwgUGFja2FnZVN5bWJvbCBwc3ltLCBmaW5hbCBKYXZhRmlsZU9iamVjdCBqZm8sCiAgICAgICAgICAgIERvY0NvbW1lbnRUcmVlIGRjVHJlZSkgewogICAgICAgIEpDQ29tcGlsYXRpb25Vbml0IGpjQ29tcGlsYXRpb25Vbml0ID0gbmV3IEpDQ29tcGlsYXRpb25Vbml0KExpc3QubmlsKCkpIHsKICAgICAgICAgICAgcHVibGljIGludCBnZXRQb3MoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gUG9zaXRpb24uRklSU1RQT1M7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHB1YmxpYyBKYXZhRmlsZU9iamVjdCBnZXRTb3VyY2VmaWxlKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIGpmbzsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgICAgIHB1YmxpYyBQb3NpdGlvbi5MaW5lTWFwIGdldExpbmVNYXAoKSB7CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIENoYXJTZXF1ZW5jZSBjb250ZW50ID0gamZvLmdldENoYXJDb250ZW50KHRydWUpOwogICAgICAgICAgICAgICAgICAgIFN0cmluZyBzID0gY29udGVudC50b1N0cmluZygpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBQb3NpdGlvbi5tYWtlTGluZU1hcChzLnRvQ2hhckFycmF5KCksIHMubGVuZ3RoKCksIHRydWUpOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gaWdub3JlKSB7fQogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KICAgICAgICB9OwoKICAgICAgICBqY0NvbXBpbGF0aW9uVW5pdC5kb2NDb21tZW50cyA9IG5ldyBEb2NDb21tZW50VGFibGUoKSB7CiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNDb21tZW50KEpDVHJlZSB0cmVlKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgQ29tbWVudCBnZXRDb21tZW50KEpDVHJlZSB0cmVlKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0Q29tbWVudFRleHQoSkNUcmVlIHRyZWUpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHVibGljIERDRG9jQ29tbWVudCBnZXRDb21tZW50VHJlZShKQ1RyZWUgdHJlZSkgewogICAgICAgICAgICAgICAgcmV0dXJuIChEQ0RvY0NvbW1lbnQpZGNUcmVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHVibGljIHZvaWQgcHV0Q29tbWVudChKQ1RyZWUgdHJlZSwgQ29tbWVudCBjKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKICAgICAgICAgICAgfQoKICAgICAgICB9OwogICAgICAgIGpjQ29tcGlsYXRpb25Vbml0LmxpbmVNYXAgPSBqY0NvbXBpbGF0aW9uVW5pdC5nZXRMaW5lTWFwKCk7CiAgICAgICAgamNDb21waWxhdGlvblVuaXQubW9kbGUgPSBwc3ltLm1vZGxlOwogICAgICAgIGpjQ29tcGlsYXRpb25Vbml0LnNvdXJjZWZpbGUgPSBqZm87CiAgICAgICAgamNDb21waWxhdGlvblVuaXQubmFtZWRJbXBvcnRTY29wZSA9IG5ldyBOYW1lZEltcG9ydFNjb3BlKHBzeW0sIGpjQ29tcGlsYXRpb25Vbml0LnRvcGxldmVsU2NvcGUpOwogICAgICAgIGpjQ29tcGlsYXRpb25Vbml0LnBhY2tnZSA9IHBzeW07CiAgICAgICAgamNDb21waWxhdGlvblVuaXQuc3RhckltcG9ydFNjb3BlID0gbmV3IFN0YXJJbXBvcnRTY29wZShwc3ltKTsKICAgICAgICBqY0NvbXBpbGF0aW9uVW5pdC50b3BsZXZlbFNjb3BlID0gV3JpdGVhYmxlU2NvcGUuY3JlYXRlKHBzeW0pOwogICAgICAgIHJldHVybiBuZXcgVHJlZVBhdGgoamNDb21waWxhdGlvblVuaXQpOwogICAgfQp9ClBLAwQKAAAIAAAGO6lK1TqUHZkcAACZHAAAMAAAAGNvbS9zdW4vdG9vbHMvamF2YWMvYXBpL0RpYWdub3N0aWNGb3JtYXR0ZXIuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwOCwgMjAxMiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLmphdmFjLmFwaTsKCmltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOwppbXBvcnQgamF2YS51dGlsLlNldDsKaW1wb3J0IGphdmF4LnRvb2xzLkRpYWdub3N0aWM7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmFwaS5EaWFnbm9zdGljRm9ybWF0dGVyLio7CgovKioKICogUHJvdmlkZXMgc2ltcGxlIGZ1bmN0aW9uYWxpdGllcyBmb3IgamF2YWMgZGlhZ25vc3RpYyBmb3JtYXR0aW5nLgogKiBAcGFyYW0gPEQ+IHR5cGUgb2YgZGlhZ25vc3RpYyBoYW5kbGVkIGJ5IHRoaXMgZm9ybWF0dGVyCiAqCiAqIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24gcmlzay4KICogVGhpcyBjb2RlIGFuZCBpdHMgaW50ZXJuYWwgaW50ZXJmYWNlcyBhcmUgc3ViamVjdCB0byBjaGFuZ2Ugb3IKICogZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPgogKi8KcHVibGljIGludGVyZmFjZSBEaWFnbm9zdGljRm9ybWF0dGVyPEQgZXh0ZW5kcyBEaWFnbm9zdGljPD8+PiB7CgogICAgLyoqCiAgICAgKiBXaGV0aGVyIHRoZSBzb3VyY2UgY29kZSBvdXRwdXQgZm9yIHRoaXMgZGlhZ25vc3RpYyBpcyB0byBiZSBkaXNwbGF5ZWQuCiAgICAgKgogICAgICogQHBhcmFtIGRpYWcgZGlhZ25vc3RpYyB0byBiZSBmb3JtYXR0ZWQKICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgc291cmNlIGxpbmUgdGhpcyBkaWFnbm9zdGljIHJlZmVycyB0byBpcyB0byBiZSBkaXNwbGF5ZWQKICAgICAqLwogICAgYm9vbGVhbiBkaXNwbGF5U291cmNlKEQgZGlhZyk7CgogICAgLyoqCiAgICAgKiBGb3JtYXQgdGhlIGNvbnRlbnRzIG9mIGEgZGlhZ25vc3RpY3MuCiAgICAgKgogICAgICogQHBhcmFtIGRpYWcgdGhlIGRpYWdub3N0aWMgdG8gYmUgZm9ybWF0dGVkCiAgICAgKiBAcGFyYW0gbCBsb2NhbGUgb2JqZWN0IHRvIGJlIHVzZWQgZm9yIGkxOG4KICAgICAqIEByZXR1cm4gYSBzdHJpbmcgcmVwcmVzZW50aW5nIHRoZSBkaWFnbm9zdGljCiAgICAgKi8KICAgIHB1YmxpYyBTdHJpbmcgZm9ybWF0KEQgZGlhZywgTG9jYWxlIGwpOwoKICAgIC8qKgogICAgICogQ29udHJvbHMgdGhlIHdheSBpbiB3aGljaCBhIGRpYWdub3N0aWMgbWVzc2FnZSBpcyBkaXNwbGF5ZWQuCiAgICAgKgogICAgICogQHBhcmFtIGRpYWcgZGlhZ25vc3RpYyB0byBiZSBmb3JtYXR0ZWQKICAgICAqIEBwYXJhbSBsIGxvY2FsZSBvYmplY3QgdG8gYmUgdXNlZCBmb3IgaTE4bgogICAgICogQHJldHVybiBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIGRpYWdub3N0aWMgbWVzc2FnZQogICAgICovCiAgICBwdWJsaWMgU3RyaW5nIGZvcm1hdE1lc3NhZ2UoRCBkaWFnLExvY2FsZSBsKTsKCiAgICAvKioKICAgICAqIENvbnRyb2xzIHRoZSB3YXkgaW4gd2hpY2ggYSBkaWFnbm9zdGljIGtpbmQgaXMgZGlzcGxheWVkLgogICAgICoKICAgICAqIEBwYXJhbSBkaWFnIGRpYWdub3N0aWMgdG8gYmUgZm9ybWF0dGVkCiAgICAgKiBAcGFyYW0gbCBsb2NhbGUgb2JqZWN0IHRvIGJlIHVzZWQgZm9yIGkxOG4KICAgICAqIEByZXR1cm4gc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBkaWFnbm9zdGljIHByZWZpeAogICAgICovCiAgICBwdWJsaWMgU3RyaW5nIGZvcm1hdEtpbmQoRCBkaWFnLCBMb2NhbGUgbCk7CgogICAgLyoqCiAgICAgKiBDb250cm9scyB0aGUgd2F5IGluIHdoaWNoIGEgZGlhZ25vc3RpYyBzb3VyY2UgaXMgZGlzcGxheWVkLgogICAgICoKICAgICAqIEBwYXJhbSBkaWFnIGRpYWdub3N0aWMgdG8gYmUgZm9ybWF0dGVkCiAgICAgKiBAcGFyYW0gbCBsb2NhbGUgb2JqZWN0IHRvIGJlIHVzZWQgZm9yIGkxOG4KICAgICAqIEBwYXJhbSBmdWxsbmFtZSB3aGV0aGVyIHRoZSBzb3VyY2UgZnVsbG5hbWUgc2hvdWxkIGJlIHByaW50ZWQKICAgICAqIEByZXR1cm4gc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBkaWFnbm9zdGljIHNvdXJjZQogICAgICovCiAgICBwdWJsaWMgU3RyaW5nIGZvcm1hdFNvdXJjZShEIGRpYWcsIGJvb2xlYW4gZnVsbG5hbWUsIExvY2FsZSBsKTsKCiAgICAvKioKICAgICAqIENvbnRyb2xzIHRoZSB3YXkgaW4gd2hpY2ggYSBkaWFnbm9zdGljIHBvc2l0aW9uIGlzIGRpc3BsYXllZC4KICAgICAqCiAgICAgKiBAcGFyYW0gZGlhZyBkaWFnbm9zdGljIHRvIGJlIGZvcm1hdHRlZAogICAgICogQHBhcmFtIHBrIGVudW0gY29uc3RhbnQgcmVwcmVzZW50aW5nIHRoZSBwb3NpdGlvbiBraW5kCiAgICAgKiBAcGFyYW0gbCBsb2NhbGUgb2JqZWN0IHRvIGJlIHVzZWQgZm9yIGkxOG4KICAgICAqIEByZXR1cm4gc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBkaWFnbm9zdGljIHBvc2l0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBTdHJpbmcgZm9ybWF0UG9zaXRpb24oRCBkaWFnLCBQb3NpdGlvbktpbmQgcGssIExvY2FsZSBsKTsKICAgIC8vd2hlcmUKICAgIC8qKgogICAgICogVGhpcyBlbnVtIGRlZmluZXMgYSBzZXQgb2YgY29uc3RhbnRzIGZvciBhbGwgdGhlIGtpbmRzIG9mIHBvc2l0aW9uCiAgICAgKiB0aGF0IGEgZGlhZ25vc3RpYyBjYW4gYmUgYXNrZWQgZm9yLiBBbGwgcG9zaXRpb25zIGFyZSBpbnRlbmRlZCB0byBiZQogICAgICogcmVsYXRpdmUgdG8gYSBnaXZlbiBkaWFnbm9zdGljIHNvdXJjZS4KICAgICAqLwogICAgcHVibGljIGVudW0gUG9zaXRpb25LaW5kIHsKICAgICAgICAvKioKICAgICAgICAgKiBTdGFydCBwb3NpdGlvbgogICAgICAgICAqLwogICAgICAgIFNUQVJULAogICAgICAgIC8qKgogICAgICAgICAqIEVuZCBwb3NpdGlvbgogICAgICAgICAqLwogICAgICAgIEVORCwKICAgICAgICAvKioKICAgICAgICAgKiBMaW5lIG51bWJlcgogICAgICAgICAqLwogICAgICAgIExJTkUsCiAgICAgICAgLyoqCiAgICAgICAgICogQ29sdW1uIG51bWJlcgogICAgICAgICAqLwogICAgICAgIENPTFVNTiwKICAgICAgICAvKioKICAgICAgICAgKiBPZmZzZXQgcG9zaXRpb24KICAgICAgICAgKi8KICAgICAgICBPRkZTRVQKICAgIH0KCiAgICAvKioKICAgICAqIEdldCBhIGxpc3Qgb2YgYWxsIHRoZSBlbmFibGVkIHZlcmJvc2l0eSBvcHRpb25zLgogICAgICogQHJldHVybiB2ZXJib3NpdHkgb3B0aW9ucwogICAgICovCiAgICBwdWJsaWMgQ29uZmlndXJhdGlvbiBnZXRDb25maWd1cmF0aW9uKCk7CiAgICAvL3doZXJlCgogICAgLyoqCiAgICAgKiBUaGlzIGludGVyZmFjZSBwcm92aWRlcyBmdW5jdGlvbmFsaXRpZXMgZm9yIHR1bmluZyB0aGUgb3V0cHV0IG9mIGEKICAgICAqIGRpYWdub3N0aWMgZm9ybWF0dGVyIGluIG11bHRpcGxlIHdheXMuCiAgICAgKi8KICAgIGludGVyZmFjZSBDb25maWd1cmF0aW9uIHsKICAgICAgICAvKioKICAgICAgICAgKiBDb25maWd1cmUgdGhlIHNldCBvZiBkaWFnbm9zdGljIHBhcnRzIHRoYXQgc2hvdWxkIGJlIGRpc3BsYXllZAogICAgICAgICAqIGJ5IHRoZSBmb3JtYXR0ZXIuCiAgICAgICAgICogQHBhcmFtIHZpc2libGVQYXJ0cyB0aGUgcGFydHMgdG8gYmUgc2V0CiAgICAgICAgICovCiAgICAgICAgcHVibGljIHZvaWQgc2V0VmlzaWJsZShTZXQ8RGlhZ25vc3RpY1BhcnQ+IHZpc2libGVQYXJ0cyk7CgogICAgICAgIC8qKgogICAgICAgICAqIFJldHJpZXZlIHRoZSBzZXQgb2YgZGlhZ25vc3RpYyBwYXJ0cyB0aGF0IHNob3VsZCBiZSBkaXNwbGF5ZWQKICAgICAgICAgKiBieSB0aGUgZm9ybWF0dGVyLgogICAgICAgICAqIEByZXR1cm4gdmVyYm9zaXR5IG9wdGlvbnMKICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgU2V0PERpYWdub3N0aWNQYXJ0PiBnZXRWaXNpYmxlKCk7CgogICAgICAgIC8vd2hlcmUKICAgICAgICAvKioKICAgICAgICAgKiBBIGdpdmVuIGRpYWdub3N0aWMgbWVzc2FnZSBjYW4gYmUgZGl2aWRlZCBpbnRvIHN1Yi1wYXJ0cyBlYWNoIG9mIHdoaWNoCiAgICAgICAgICogbWlnaHQvbWlnaHQgbm90IGJlIGRpc3BsYXllZCBieSB0aGUgZm9ybWF0dGVyLCBhY2NvcmRpbmcgdG8gdGhlCiAgICAgICAgICogY3VycmVudCBjb25maWd1cmF0aW9uIHNldHRpbmdzLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBlbnVtIERpYWdub3N0aWNQYXJ0IHsKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIFNob3J0IGRlc2NyaXB0aW9uIG9mIHRoZSBkaWFnbm9zdGljIC0gdXN1YWxseSBvbmUgbGluZSBsb25nLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgU1VNTUFSWSwKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIExvbmdlciBkZXNjcmlwdGlvbiB0aGF0IHByb3ZpZGVzIGFkZGl0aW9uYWwgZGV0YWlscyB3LnIudC4gdGhlIG9uZXMKICAgICAgICAgICAgICogaW4gdGhlIGRpYWdub3N0aWMncyBkZXNjcmlwdGlvbi4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIERFVEFJTFMsCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBTb3VyY2UgbGluZSB0aGUgZGlhZ25vc3RpYyByZWZlcnMgdG8gKGlmIGFwcGxpY2FibGUpLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgU09VUkNFLAogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogU3ViZGlhZ25vc3RpY3MgYXR0YWNoZWQgdG8gYSBnaXZlbiBtdWx0aWxpbmUgZGlhZ25vc3RpYy4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIFNVQkRJQUdOT1NUSUNTLAogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogSkxTIHBhcmFncmFwaCB0aGlzIGRpYWdub3N0aWMgbWlnaHQgcmVmZXIgdG8gKGlmIGFwcGxpY2FibGUpLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgSkxTCiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBTZXQgYSBsaW1pdCBmb3IgbXVsdGlsaW5lIGRpYWdub3N0aWNzLgogICAgICAgICAqIE5vdGU6IFNldHRpbmcgYSBsaW1pdCBoYXMgbm8gZWZmZWN0IGlmIG11bHRpbGluZSBkaWFnbm9zdGljcyBhcmUgZWl0aGVyCiAgICAgICAgICogZnVsbHkgZW5hYmxlZCBvciBkaXNhYmxlZC4KICAgICAgICAgKgogICAgICAgICAqIEBwYXJhbSBsaW1pdCB0aGUga2luZCBvZiBsaW1pdCB0byBiZSBzZXQKICAgICAgICAgKiBAcGFyYW0gdmFsdWUgdGhlIGxpbWl0IHZhbHVlCiAgICAgICAgICovCiAgICAgICAgcHVibGljIHZvaWQgc2V0TXVsdGlsaW5lTGltaXQoTXVsdGlsaW5lTGltaXQgbGltaXQsIGludCB2YWx1ZSk7CgogICAgICAgIC8qKgogICAgICAgICAqIEdldCBhIG11bHRpbGluZSBkaWFnbm9zdGljIGxpbWl0LgogICAgICAgICAqCiAgICAgICAgICogQHBhcmFtIGxpbWl0IHRoZSBraW5kIG9mIGxpbWl0IHRvIGJlIHJldHJpZXZlZAogICAgICAgICAqIEByZXR1cm4gbGltaXQgdmFsdWUgb3IgLTEgaWYgbm8gbGltaXQgaXMgc2V0CiAgICAgICAgICovCiAgICAgICAgcHVibGljIGludCBnZXRNdWx0aWxpbmVMaW1pdChNdWx0aWxpbmVMaW1pdCBsaW1pdCk7CiAgICAgICAgLy93aGVyZQogICAgICAgIC8qKgogICAgICAgICAqIEEgbXVsdGlsaW5lIGxpbWl0IGNvbnRyb2wgdGhlIHZlcmJvc2l0eSBvZiBtdWx0aWxpbmUgZGlhZ25vc3RpY3MKICAgICAgICAgKiBlaXRoZXIgYnkgc2V0dGluZyBhIG1heGltdW0gZGVwdGggb2YgbmVzdGVkIG11bHRpZGlhZ25vc3RpY3MsCiAgICAgICAgICogb3IgYnkgbGltaXRpbmcgdGhlIGFtb3VudCBvZiBzdWJkaWFnbm9zdGljcyBhdHRhY2hlZCB0byBhIGdpdmVuCiAgICAgICAgICogZGlhZ25vc3RpYyAob3IgYm90aCkuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIGVudW0gTXVsdGlsaW5lTGltaXQgewogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogQ29udHJvbHMgdGhlIG1heGltdW0gZGVwdGggb2YgbmVzdGVkIG11bHRpbGluZSBkaWFnbm9zdGljcy4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIERFUFRILAogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogQ29udHJvbHMgdGhlIG1heGltdW0gYW1vdW50IG9mIHN1YmRpYWdub3N0aWNzIHRoYXQgYXJlIHBhcnQgb2YgYQogICAgICAgICAgICAgKiBnaXZlbiBtdWx0aWxpbmUgZGlhZ25vc3RpYy4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIExFTkdUSAogICAgICAgIH0KICAgIH0KfQpQSwMECgAACAAABjupSpWtTVySIAAAkiAAACsAAABjb20vc3VuL3Rvb2xzL2phdmFjL2FwaS9CYXNpY0phdmFjVGFzay5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDA1LCAyMDE3LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuamF2YWMuYXBpOwoKaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uOwppbXBvcnQgamF2YS51dGlsLkxpbmtlZEhhc2hTZXQ7CmltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOwppbXBvcnQgamF2YS51dGlsLk9iamVjdHM7CmltcG9ydCBqYXZhLnV0aWwuU2VydmljZUxvYWRlcjsKaW1wb3J0IGphdmEudXRpbC5TZXQ7CmltcG9ydCBqYXZhLnV0aWwuc3RyZWFtLkNvbGxlY3RvcnM7CgppbXBvcnQgamF2YXguYW5ub3RhdGlvbi5wcm9jZXNzaW5nLlByb2Nlc3NvcjsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC5FbGVtZW50OwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC50eXBlLlR5cGVNaXJyb3I7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLnV0aWwuRWxlbWVudHM7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLnV0aWwuVHlwZXM7CmltcG9ydCBqYXZheC50b29scy5KYXZhRmlsZU9iamVjdDsKCmltcG9ydCBjb20uc3VuLnNvdXJjZS50cmVlLkNvbXBpbGF0aW9uVW5pdFRyZWU7CmltcG9ydCBjb20uc3VuLnNvdXJjZS50cmVlLlRyZWU7CmltcG9ydCBjb20uc3VuLnNvdXJjZS51dGlsLkphdmFjVGFzazsKaW1wb3J0IGNvbS5zdW4uc291cmNlLnV0aWwuUGx1Z2luOwppbXBvcnQgY29tLnN1bi5zb3VyY2UudXRpbC5UYXNrTGlzdGVuZXI7CmltcG9ydCBjb20uc3VuLnRvb2xzLmRvY2xpbnQuRG9jTGludDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMubWFpbi5KYXZhQ29tcGlsZXI7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLm1vZGVsLkphdmFjRWxlbWVudHM7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLm1vZGVsLkphdmFjVHlwZXM7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnBsYXRmb3JtLlBsYXRmb3JtRGVzY3JpcHRpb247CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnBsYXRmb3JtLlBsYXRmb3JtRGVzY3JpcHRpb24uUGx1Z2luSW5mbzsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMucHJvY2Vzc2luZy5KYXZhY1Byb2Nlc3NpbmdFbnZpcm9ubWVudDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5KQ1RyZWU7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuQ29udGV4dDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5EZWZpbmVkQnk7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuRGVmaW5lZEJ5LkFwaTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5MaXN0OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkxvZzsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5Qcm9wYWdhdGVkRXhjZXB0aW9uOwoKLyoqCiAqIFByb3ZpZGVzIGJhc2ljIGZ1bmN0aW9uYWxpdHkgZm9yIGltcGxlbWVudGF0aW9ucyBvZiBKYXZhY1Rhc2suCiAqCiAqIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24KICogcmlzay4gIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlCiAqIG9yIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj48L3A+CiAqLwpwdWJsaWMgY2xhc3MgQmFzaWNKYXZhY1Rhc2sgZXh0ZW5kcyBKYXZhY1Rhc2sgewogICAgcHJvdGVjdGVkIENvbnRleHQgY29udGV4dDsKICAgIHByaXZhdGUgVGFza0xpc3RlbmVyIHRhc2tMaXN0ZW5lcjsKCiAgICBwdWJsaWMgc3RhdGljIEphdmFjVGFzayBpbnN0YW5jZShDb250ZXh0IGNvbnRleHQpIHsKICAgICAgICBKYXZhY1Rhc2sgaW5zdGFuY2UgPSBjb250ZXh0LmdldChKYXZhY1Rhc2suY2xhc3MpOwogICAgICAgIGlmIChpbnN0YW5jZSA9PSBudWxsKQogICAgICAgICAgICBpbnN0YW5jZSA9IG5ldyBCYXNpY0phdmFjVGFzayhjb250ZXh0LCB0cnVlKTsKICAgICAgICByZXR1cm4gaW5zdGFuY2U7CiAgICB9CgogICAgcHVibGljIEJhc2ljSmF2YWNUYXNrKENvbnRleHQgYywgYm9vbGVhbiByZWdpc3RlcikgewogICAgICAgIGNvbnRleHQgPSBjOwogICAgICAgIGlmIChyZWdpc3RlcikKICAgICAgICAgICAgY29udGV4dC5wdXQoSmF2YWNUYXNrLmNsYXNzLCB0aGlzKTsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBJdGVyYWJsZTw/IGV4dGVuZHMgQ29tcGlsYXRpb25Vbml0VHJlZT4gcGFyc2UoKSB7CiAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigpOwogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIEl0ZXJhYmxlPD8gZXh0ZW5kcyBFbGVtZW50PiBhbmFseXplKCkgewogICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oKTsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBJdGVyYWJsZTw/IGV4dGVuZHMgSmF2YUZpbGVPYmplY3Q+IGdlbmVyYXRlKCkgewogICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oKTsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyB2b2lkIHNldFRhc2tMaXN0ZW5lcihUYXNrTGlzdGVuZXIgdGwpIHsKICAgICAgICBNdWx0aVRhc2tMaXN0ZW5lciBtdGwgPSBNdWx0aVRhc2tMaXN0ZW5lci5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBpZiAodGFza0xpc3RlbmVyICE9IG51bGwpCiAgICAgICAgICAgIG10bC5yZW1vdmUodGFza0xpc3RlbmVyKTsKICAgICAgICBpZiAodGwgIT0gbnVsbCkKICAgICAgICAgICAgbXRsLmFkZCh0bCk7CiAgICAgICAgdGFza0xpc3RlbmVyID0gdGw7CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICBwdWJsaWMgdm9pZCBhZGRUYXNrTGlzdGVuZXIoVGFza0xpc3RlbmVyIHRhc2tMaXN0ZW5lcikgewogICAgICAgIE11bHRpVGFza0xpc3RlbmVyIG10bCA9IE11bHRpVGFza0xpc3RlbmVyLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIG10bC5hZGQodGFza0xpc3RlbmVyKTsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyB2b2lkIHJlbW92ZVRhc2tMaXN0ZW5lcihUYXNrTGlzdGVuZXIgdGFza0xpc3RlbmVyKSB7CiAgICAgICAgTXVsdGlUYXNrTGlzdGVuZXIgbXRsID0gTXVsdGlUYXNrTGlzdGVuZXIuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgbXRsLnJlbW92ZSh0YXNrTGlzdGVuZXIpOwogICAgfQoKICAgIHB1YmxpYyBDb2xsZWN0aW9uPFRhc2tMaXN0ZW5lcj4gZ2V0VGFza0xpc3RlbmVycygpIHsKICAgICAgICBNdWx0aVRhc2tMaXN0ZW5lciBtdGwgPSBNdWx0aVRhc2tMaXN0ZW5lci5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICByZXR1cm4gbXRsLmdldFRhc2tMaXN0ZW5lcnMoKTsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBUeXBlTWlycm9yIGdldFR5cGVNaXJyb3IoSXRlcmFibGU8PyBleHRlbmRzIFRyZWU+IHBhdGgpIHsKICAgICAgICAvLyBUT0RPOiBTaG91bGQgY29tcGxldGUgYXR0cmlidXRpb24gaWYgbmVjZXNzYXJ5CiAgICAgICAgVHJlZSBsYXN0ID0gbnVsbDsKICAgICAgICBmb3IgKFRyZWUgbm9kZSA6IHBhdGgpIHsKICAgICAgICAgICAgbGFzdCA9IE9iamVjdHMucmVxdWlyZU5vbk51bGwobm9kZSk7CiAgICAgICAgfQogICAgICAgIGlmIChsYXN0ID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiZW1wdHkgcGF0aCIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gKChKQ1RyZWUpIGxhc3QpLnR5cGU7CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICBwdWJsaWMgRWxlbWVudHMgZ2V0RWxlbWVudHMoKSB7CiAgICAgICAgaWYgKGNvbnRleHQgPT0gbnVsbCkKICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigpOwogICAgICAgIHJldHVybiBKYXZhY0VsZW1lbnRzLmluc3RhbmNlKGNvbnRleHQpOwogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIFR5cGVzIGdldFR5cGVzKCkgewogICAgICAgIGlmIChjb250ZXh0ID09IG51bGwpCiAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oKTsKICAgICAgICByZXR1cm4gSmF2YWNUeXBlcy5pbnN0YW5jZShjb250ZXh0KTsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICBwdWJsaWMgdm9pZCBhZGRNb2R1bGVzKEl0ZXJhYmxlPFN0cmluZz4gbW9kdWxlTmFtZXMpIHsKICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCk7CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSKQogICAgcHVibGljIHZvaWQgc2V0UHJvY2Vzc29ycyhJdGVyYWJsZTw/IGV4dGVuZHMgUHJvY2Vzc29yPiBwcm9jZXNzb3JzKSB7CiAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigpOwogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgIHB1YmxpYyB2b2lkIHNldExvY2FsZShMb2NhbGUgbG9jYWxlKSB7CiAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigpOwogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgIHB1YmxpYyBCb29sZWFuIGNhbGwoKSB7CiAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigpOwogICAgfQoKICAgIC8qKgogICAgICogRm9yIGludGVybmFsIHVzZSBvbmx5LgogICAgICogVGhpcyBtZXRob2Qgd2lsbCBiZSByZW1vdmVkIHdpdGhvdXQgd2FybmluZy4KICAgICAqIEByZXR1cm4gdGhlIGNvbnRleHQKICAgICAqLwogICAgcHVibGljIENvbnRleHQgZ2V0Q29udGV4dCgpIHsKICAgICAgICByZXR1cm4gY29udGV4dDsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCBpbml0UGx1Z2lucyhTZXQ8TGlzdDxTdHJpbmc+PiBwbHVnaW5PcHRzKSB7CiAgICAgICAgUGxhdGZvcm1EZXNjcmlwdGlvbiBwbGF0Zm9ybVByb3ZpZGVyID0gY29udGV4dC5nZXQoUGxhdGZvcm1EZXNjcmlwdGlvbi5jbGFzcyk7CgogICAgICAgIGlmIChwbGF0Zm9ybVByb3ZpZGVyICE9IG51bGwpIHsKICAgICAgICAgICAgZm9yIChQbHVnaW5JbmZvPFBsdWdpbj4gcGx1Z2luRGVzYyA6IHBsYXRmb3JtUHJvdmlkZXIuZ2V0UGx1Z2lucygpKSB7CiAgICAgICAgICAgICAgICBqYXZhLnV0aWwuTGlzdDxTdHJpbmc+IG9wdGlvbnMgPQogICAgICAgICAgICAgICAgICAgICAgICBwbHVnaW5EZXNjLmdldE9wdGlvbnMoKS5lbnRyeVNldCgpLnN0cmVhbSgpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAubWFwKGUgLT4gZS5nZXRLZXkoKSArICI9IiArIGUuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jb2xsZWN0KENvbGxlY3RvcnMudG9MaXN0KCkpOwogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICBwbHVnaW5EZXNjLmdldFBsdWdpbigpLmluaXQodGhpcywgb3B0aW9ucy50b0FycmF5KG5ldyBTdHJpbmdbb3B0aW9ucy5zaXplKCldKSk7CiAgICAgICAgICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIGV4KSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFByb3BhZ2F0ZWRFeGNlcHRpb24oZXgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAocGx1Z2luT3B0cy5pc0VtcHR5KCkpCiAgICAgICAgICAgIHJldHVybjsKCiAgICAgICAgU2V0PExpc3Q8U3RyaW5nPj4gcGx1Z2luc1RvQ2FsbCA9IG5ldyBMaW5rZWRIYXNoU2V0PD4ocGx1Z2luT3B0cyk7CiAgICAgICAgSmF2YWNQcm9jZXNzaW5nRW52aXJvbm1lbnQgcEVudiA9IEphdmFjUHJvY2Vzc2luZ0Vudmlyb25tZW50Lmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIFNlcnZpY2VMb2FkZXI8UGx1Z2luPiBzbCA9IHBFbnYuZ2V0U2VydmljZUxvYWRlcihQbHVnaW4uY2xhc3MpOwogICAgICAgIGZvciAoUGx1Z2luIHBsdWdpbiA6IHNsKSB7CiAgICAgICAgICAgIGZvciAoTGlzdDxTdHJpbmc+IHAgOiBwbHVnaW5zVG9DYWxsKSB7CiAgICAgICAgICAgICAgICBpZiAocGx1Z2luLmdldE5hbWUoKS5lcXVhbHMocC5oZWFkKSkgewogICAgICAgICAgICAgICAgICAgIHBsdWdpbnNUb0NhbGwucmVtb3ZlKHApOwogICAgICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHBsdWdpbi5pbml0KHRoaXMsIHAudGFpbC50b0FycmF5KG5ldyBTdHJpbmdbcC50YWlsLnNpemUoKV0pKTsKICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIGV4KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBQcm9wYWdhdGVkRXhjZXB0aW9uKGV4KTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZm9yIChMaXN0PFN0cmluZz4gcDogcGx1Z2luc1RvQ2FsbCkgewogICAgICAgICAgICBMb2cuaW5zdGFuY2UoY29udGV4dCkuZXJyb3IoInBsdWdpbi5ub3QuZm91bmQiLCBwLmhlYWQpOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgdm9pZCBpbml0RG9jTGludChMaXN0PFN0cmluZz4gZG9jTGludE9wdHMpIHsKICAgICAgICBpZiAoZG9jTGludE9wdHMuaXNFbXB0eSgpKQogICAgICAgICAgICByZXR1cm47CgogICAgICAgIG5ldyBEb2NMaW50KCkuaW5pdCh0aGlzLCBkb2NMaW50T3B0cy50b0FycmF5KG5ldyBTdHJpbmdbZG9jTGludE9wdHMuc2l6ZSgpXSkpOwogICAgICAgIEphdmFDb21waWxlci5pbnN0YW5jZShjb250ZXh0KS5rZWVwQ29tbWVudHMgPSB0cnVlOwogICAgfQp9ClBLAwQKAAAIAAAGO6lKnRwU/4MSAACDEgAALgAAAGNvbS9zdW4vdG9vbHMvamF2YWMvYXBpL011bHRpVGFza0xpc3RlbmVyLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTEsIDIwMTIsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhYy5hcGk7CgppbXBvcnQgamF2YS51dGlsLkFycmF5czsKaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uOwoKaW1wb3J0IGNvbS5zdW4uc291cmNlLnV0aWwuVGFza0V2ZW50OwppbXBvcnQgY29tLnN1bi5zb3VyY2UudXRpbC5UYXNrTGlzdGVuZXI7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuQ29udGV4dDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5EZWZpbmVkQnk7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuRGVmaW5lZEJ5LkFwaTsKCi8qKgogKiBBIGNvbGxlY3Rpb24gb2YgY3VycmVudGx5IHJlZ2lzdGVyZWQge0BsaW5rIFRhc2tMaXN0ZW5lcn1zLiBFdmVudHMgcGFzc2VkIHRvIHRoaXMgVGFza0xpc3RlbmVyCiAqIHdpbGwgYmUgZm9yd2FyZGVkIHRvIGFsbCB0aGUgcmVnaXN0ZXJlZCBUYXNrTGlzdGVuZXJzLgogKgogKiA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yCiAqIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj4KICovCnB1YmxpYyBjbGFzcyBNdWx0aVRhc2tMaXN0ZW5lciBpbXBsZW1lbnRzIFRhc2tMaXN0ZW5lciB7CiAgICAvKiogVGhlIGNvbnRleHQga2V5IGZvciB0aGUgTXVsdGlUYXNrTGlzdGVuZXIuICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIENvbnRleHQuS2V5PE11bHRpVGFza0xpc3RlbmVyPiB0YXNrTGlzdGVuZXJLZXkgPSBuZXcgQ29udGV4dC5LZXk8PigpOwoKICAgIC8qKiBFbXB0eSBhcnJheSBvZiB0YXNrIGxpc3RlbmVycyAqLwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVGFza0xpc3RlbmVyW10gRU1QVFlfTElTVEVORVJTID0gbmV3IFRhc2tMaXN0ZW5lclswXTsKCiAgICAvKiogR2V0IHRoZSBNdWx0aVRhc2tMaXN0ZW5lciBpbnN0YW5jZSBmb3IgdGhpcyBjb250ZXh0LiAqLwogICAgcHVibGljIHN0YXRpYyBNdWx0aVRhc2tMaXN0ZW5lciBpbnN0YW5jZShDb250ZXh0IGNvbnRleHQpIHsKICAgICAgICBNdWx0aVRhc2tMaXN0ZW5lciBpbnN0YW5jZSA9IGNvbnRleHQuZ2V0KHRhc2tMaXN0ZW5lcktleSk7CiAgICAgICAgaWYgKGluc3RhbmNlID09IG51bGwpCiAgICAgICAgICAgIGluc3RhbmNlID0gbmV3IE11bHRpVGFza0xpc3RlbmVyKGNvbnRleHQpOwogICAgICAgIHJldHVybiBpbnN0YW5jZTsKICAgIH0KCiAgICBwcm90ZWN0ZWQgTXVsdGlUYXNrTGlzdGVuZXIoQ29udGV4dCBjb250ZXh0KSB7CiAgICAgICAgY29udGV4dC5wdXQodGFza0xpc3RlbmVyS2V5LCB0aGlzKTsKICAgICAgICBjY3cgPSBDbGllbnRDb2RlV3JhcHBlci5pbnN0YW5jZShjb250ZXh0KTsKICAgIH0KCiAgICAvKioKICAgICAqIFRoZSBjdXJyZW50IHNldCBvZiByZWdpc3RlcmVkIGxpc3RlbmVycy4KICAgICAqIFRoaXMgaXMgYSBtdXRhYmxlIHJlZmVyZW5jZSB0byBhbiBpbW11dGFibGUgYXJyYXkuCiAgICAgKi8KICAgIFRhc2tMaXN0ZW5lcltdIGxpc3RlbmVycyA9IEVNUFRZX0xJU1RFTkVSUzsKCiAgICBDbGllbnRDb2RlV3JhcHBlciBjY3c7CgogICAgcHVibGljIENvbGxlY3Rpb248VGFza0xpc3RlbmVyPiBnZXRUYXNrTGlzdGVuZXJzKCkgewogICAgICAgIHJldHVybiBBcnJheXMuYXNMaXN0KGxpc3RlbmVycyk7CiAgICB9CgogICAgcHVibGljIGJvb2xlYW4gaXNFbXB0eSgpIHsKICAgICAgICByZXR1cm4gbGlzdGVuZXJzID09IEVNUFRZX0xJU1RFTkVSUzsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCBhZGQoVGFza0xpc3RlbmVyIGxpc3RlbmVyKSB7CiAgICAgICAgZm9yIChUYXNrTGlzdGVuZXIgbDogbGlzdGVuZXJzKSB7CiAgICAgICAgICAgIGlmIChjY3cudW53cmFwKGwpID09IGxpc3RlbmVyKQogICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBsaXN0ZW5lcnMgPSBBcnJheXMuY29weU9mKGxpc3RlbmVycywgbGlzdGVuZXJzLmxlbmd0aCArIDEpOwogICAgICAgIGxpc3RlbmVyc1tsaXN0ZW5lcnMubGVuZ3RoIC0gMV0gPSBjY3cud3JhcChsaXN0ZW5lcik7CiAgICB9CgogICAgcHVibGljIHZvaWQgcmVtb3ZlKFRhc2tMaXN0ZW5lciBsaXN0ZW5lcikgewogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGlzdGVuZXJzLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgIGlmIChjY3cudW53cmFwKGxpc3RlbmVyc1tpXSkgPT0gbGlzdGVuZXIpIHsKICAgICAgICAgICAgICAgIGlmIChsaXN0ZW5lcnMubGVuZ3RoID09IDEpIHsKICAgICAgICAgICAgICAgICAgICBsaXN0ZW5lcnMgPSBFTVBUWV9MSVNURU5FUlM7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIFRhc2tMaXN0ZW5lcltdIG5ld0xpc3RlbmVycyA9IG5ldyBUYXNrTGlzdGVuZXJbbGlzdGVuZXJzLmxlbmd0aCAtIDFdOwogICAgICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkobGlzdGVuZXJzLCAwLCBuZXdMaXN0ZW5lcnMsIDAsIGkpOwogICAgICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkobGlzdGVuZXJzLCBpICsgMSwgbmV3TGlzdGVuZXJzLCBpLCBuZXdMaXN0ZW5lcnMubGVuZ3RoIC0gaSk7CiAgICAgICAgICAgICAgICAgICAgbGlzdGVuZXJzID0gbmV3TGlzdGVuZXJzOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICBwdWJsaWMgdm9pZCBzdGFydGVkKFRhc2tFdmVudCBlKSB7CiAgICAgICAgLy8gZ3VhcmQgYWdhaW5zdCBsaXN0ZW5lcnMgYmVpbmcgdXBkYXRlZCBieSBhIGxpc3RlbmVyCiAgICAgICAgVGFza0xpc3RlbmVyW10gbGwgPSB0aGlzLmxpc3RlbmVyczsKICAgICAgICBmb3IgKFRhc2tMaXN0ZW5lciBsOiBsbCkKICAgICAgICAgICAgbC5zdGFydGVkKGUpOwogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIHZvaWQgZmluaXNoZWQoVGFza0V2ZW50IGUpIHsKICAgICAgICAvLyBndWFyZCBhZ2FpbnN0IGxpc3RlbmVycyBiZWluZyB1cGRhdGVkIGJ5IGEgbGlzdGVuZXIKICAgICAgICBUYXNrTGlzdGVuZXJbXSBsbCA9IHRoaXMubGlzdGVuZXJzOwogICAgICAgIGZvciAoVGFza0xpc3RlbmVyIGw6IGxsKQogICAgICAgICAgICBsLmZpbmlzaGVkKGUpOwogICAgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKICAgICAgICByZXR1cm4gQXJyYXlzLnRvU3RyaW5nKGxpc3RlbmVycyk7CiAgICB9CgogICAgcHVibGljIHZvaWQgY2xlYXIoKSB7CiAgICAgICAgbGlzdGVuZXJzID0gRU1QVFlfTElTVEVORVJTOwogICAgfQp9ClBLAwQKAAAIAACxPKlKAAAAAAAAAAAAAAAAGQAAAGNvbS9zdW4vdG9vbHMvamF2YWMvY29tcC9QSwMECgAACAAArjypSmPdoDZAwQAAQMEAACoAAABjb20vc3VuL3Rvb2xzL2phdmFjL2NvbXAvRGVmZXJyZWRBdHRyLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTIsIDIwMTUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhYy5jb21wOwoKaW1wb3J0IGNvbS5zdW4uc291cmNlLnRyZWUuTGFtYmRhRXhwcmVzc2lvblRyZWUuQm9keUtpbmQ7CmltcG9ydCBjb20uc3VuLnNvdXJjZS50cmVlLk5ld0NsYXNzVHJlZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS4qOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlR5cGUuU3RydWN0dXJhbFR5cGVNYXBwaW5nOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlR5cGVzLlR5cGVNYXBwaW5nOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb21wLkFyZ3VtZW50QXR0ci5Mb2NhbENhY2hlQ29udGV4dDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29tcC5SZXNvbHZlLlJlc29sdmVFcnJvcjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMucmVzb3VyY2VzLkNvbXBpbGVyUHJvcGVydGllcy5GcmFnbWVudHM7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuKjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC4qOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkRlZmluZWRCeS5BcGk7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuR3JhcGhVdGlscy5EZXBlbmRlbmN5S2luZDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5KQ0RpYWdub3N0aWMuRGlhZ25vc3RpY1Bvc2l0aW9uOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlN5bWJvbC4qOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb21wLkF0dHIuUmVzdWx0SW5mbzsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29tcC5SZXNvbHZlLk1ldGhvZFJlc29sdXRpb25QaGFzZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5KQ1RyZWUuKjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5KQ0RpYWdub3N0aWMuRGlhZ25vc3RpY1R5cGU7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuTG9nLkRlZmVycmVkRGlhZ25vc3RpY0hhbmRsZXI7CgppbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uOwppbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOwppbXBvcnQgamF2YS51dGlsLkVudW1TZXQ7CmltcG9ydCBqYXZhLnV0aWwuSGFzaFNldDsKaW1wb3J0IGphdmEudXRpbC5MaW5rZWRIYXNoU2V0OwppbXBvcnQgamF2YS51dGlsLk1hcDsKaW1wb3J0IGphdmEudXRpbC5TZXQ7CmltcG9ydCBqYXZhLnV0aWwuV2Vha0hhc2hNYXA7CmltcG9ydCBqYXZhLnV0aWwuZnVuY3Rpb24uRnVuY3Rpb247CgppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5UeXBlVGFnLio7CmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkpDVHJlZS5UYWcuKjsKCi8qKgogKiBUaGlzIGlzIGFuIGhlbHBlciBjbGFzcyB0aGF0IGlzIHVzZWQgdG8gcGVyZm9ybSBkZWZlcnJlZCB0eXBlLWFuYWx5c2lzLgogKiBFYWNoIHRpbWUgYSBwb2x5IGV4cHJlc3Npb24gb2NjdXJzIGluIGFyZ3VtZW50IHBvc2l0aW9uLCBqYXZhYyBhdHRyaWJ1dGVzIGl0CiAqIHdpdGggYSB0ZW1wb3JhcnkgJ2RlZmVycmVkIHR5cGUnIHRoYXQgaXMgY2hlY2tlZCAocG9zc2libHkgbXVsdGlwbGUgdGltZXMpCiAqIGFnYWluc3QgYW4gZXhwZWN0ZWQgZm9ybWFsIHR5cGUuCiAqCiAqICA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiAgSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93biByaXNrLgogKiAgVGhpcyBjb2RlIGFuZCBpdHMgaW50ZXJuYWwgaW50ZXJmYWNlcyBhcmUgc3ViamVjdCB0byBjaGFuZ2Ugb3IKICogIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj4KICovCnB1YmxpYyBjbGFzcyBEZWZlcnJlZEF0dHIgZXh0ZW5kcyBKQ1RyZWUuVmlzaXRvciB7CiAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIENvbnRleHQuS2V5PERlZmVycmVkQXR0cj4gZGVmZXJyZWRBdHRyS2V5ID0gbmV3IENvbnRleHQuS2V5PD4oKTsKCiAgICBmaW5hbCBBdHRyIGF0dHI7CiAgICBmaW5hbCBBcmd1bWVudEF0dHIgYXJndW1lbnRBdHRyOwogICAgZmluYWwgQ2hlY2sgY2hrOwogICAgZmluYWwgSkNEaWFnbm9zdGljLkZhY3RvcnkgZGlhZ3M7CiAgICBmaW5hbCBFbnRlciBlbnRlcjsKICAgIGZpbmFsIEluZmVyIGluZmVyOwogICAgZmluYWwgUmVzb2x2ZSByczsKICAgIGZpbmFsIExvZyBsb2c7CiAgICBmaW5hbCBTeW10YWIgc3ltczsKICAgIGZpbmFsIFRyZWVNYWtlciBtYWtlOwogICAgZmluYWwgVHJlZUNvcGllcjxWb2lkPiB0cmVlQ29waWVyOwogICAgZmluYWwgVHlwZU1hcHBpbmc8Vm9pZD4gZGVmZXJyZWRDb3BpZXI7CiAgICBmaW5hbCBUeXBlcyB0eXBlczsKICAgIGZpbmFsIEZsb3cgZmxvdzsKICAgIGZpbmFsIE5hbWVzIG5hbWVzOwogICAgZmluYWwgVHlwZUVudnMgdHlwZUVudnM7CgogICAgcHVibGljIHN0YXRpYyBEZWZlcnJlZEF0dHIgaW5zdGFuY2UoQ29udGV4dCBjb250ZXh0KSB7CiAgICAgICAgRGVmZXJyZWRBdHRyIGluc3RhbmNlID0gY29udGV4dC5nZXQoZGVmZXJyZWRBdHRyS2V5KTsKICAgICAgICBpZiAoaW5zdGFuY2UgPT0gbnVsbCkKICAgICAgICAgICAgaW5zdGFuY2UgPSBuZXcgRGVmZXJyZWRBdHRyKGNvbnRleHQpOwogICAgICAgIHJldHVybiBpbnN0YW5jZTsKICAgIH0KCiAgICBwcm90ZWN0ZWQgRGVmZXJyZWRBdHRyKENvbnRleHQgY29udGV4dCkgewogICAgICAgIGNvbnRleHQucHV0KGRlZmVycmVkQXR0cktleSwgdGhpcyk7CiAgICAgICAgYXR0ciA9IEF0dHIuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgYXJndW1lbnRBdHRyID0gQXJndW1lbnRBdHRyLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIGNoayA9IENoZWNrLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIGRpYWdzID0gSkNEaWFnbm9zdGljLkZhY3RvcnkuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgZW50ZXIgPSBFbnRlci5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBpbmZlciA9IEluZmVyLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIHJzID0gUmVzb2x2ZS5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBsb2cgPSBMb2cuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgc3ltcyA9IFN5bXRhYi5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBtYWtlID0gVHJlZU1ha2VyLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIHR5cGVzID0gVHlwZXMuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgZmxvdyA9IEZsb3cuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgbmFtZXMgPSBOYW1lcy5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBzdHVja1RyZWUgPSBtYWtlLklkZW50KG5hbWVzLmVtcHR5KS5zZXRUeXBlKFR5cGUuc3R1Y2tUeXBlKTsKICAgICAgICB0eXBlRW52cyA9IFR5cGVFbnZzLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIGVtcHR5RGVmZXJyZWRBdHRyQ29udGV4dCA9CiAgICAgICAgICAgIG5ldyBEZWZlcnJlZEF0dHJDb250ZXh0KEF0dHJNb2RlLkNIRUNLLCBudWxsLCBNZXRob2RSZXNvbHV0aW9uUGhhc2UuQk9YLCBpbmZlci5lbXB0eUNvbnRleHQsIG51bGwsIG51bGwpIHsKICAgICAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICAgICAgdm9pZCBhZGREZWZlcnJlZEF0dHJOb2RlKERlZmVycmVkVHlwZSBkdCwgUmVzdWx0SW5mbyByaSwgRGVmZXJyZWRTdHVja1BvbGljeSBkZWZlcnJlZFN0dWNrUG9saWN5KSB7CiAgICAgICAgICAgICAgICAgICAgQXNzZXJ0LmVycm9yKCJFbXB0eSBkZWZlcnJlZCBjb250ZXh0ISIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgICAgICB2b2lkIGNvbXBsZXRlKCkgewogICAgICAgICAgICAgICAgICAgIEFzc2VydC5lcnJvcigiRW1wdHkgZGVmZXJyZWQgY29udGV4dCEiKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICJFbXB0eSBkZWZlcnJlZCBjb250ZXh0ISI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CgogICAgICAgIC8vIEZvciBzcGVjdWxhdGl2ZSBhdHRyaWJ1dGlvbiwgc2tpcCB0aGUgY2xhc3MgZGVmaW5pdGlvbiBpbiA8Pi4KICAgICAgICB0cmVlQ29waWVyID0KICAgICAgICAgICAgbmV3IFRyZWVDb3BpZXI8Vm9pZD4obWFrZSkgewogICAgICAgICAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgICAgICAgICBwdWJsaWMgSkNUcmVlIHZpc2l0TmV3Q2xhc3MoTmV3Q2xhc3NUcmVlIG5vZGUsIFZvaWQgcCkgewogICAgICAgICAgICAgICAgICAgIEpDTmV3Q2xhc3MgdCA9IChKQ05ld0NsYXNzKSBub2RlOwogICAgICAgICAgICAgICAgICAgIGlmIChUcmVlSW5mby5pc0RpYW1vbmQodCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgSkNFeHByZXNzaW9uIGVuY2wgPSBjb3B5KHQuZW5jbCwgcCk7CiAgICAgICAgICAgICAgICAgICAgICAgIExpc3Q8SkNFeHByZXNzaW9uPiB0eXBlYXJncyA9IGNvcHkodC50eXBlYXJncywgcCk7CiAgICAgICAgICAgICAgICAgICAgICAgIEpDRXhwcmVzc2lvbiBjbGF6eiA9IGNvcHkodC5jbGF6eiwgcCk7CiAgICAgICAgICAgICAgICAgICAgICAgIExpc3Q8SkNFeHByZXNzaW9uPiBhcmdzID0gY29weSh0LmFyZ3MsIHApOwogICAgICAgICAgICAgICAgICAgICAgICBKQ0NsYXNzRGVjbCBkZWYgPSBudWxsOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbWFrZS5hdCh0LnBvcykuTmV3Q2xhc3MoZW5jbCwgdHlwZWFyZ3MsIGNsYXp6LCBhcmdzLCBkZWYpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzdXBlci52aXNpdE5ld0NsYXNzKG5vZGUsIHApOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKICAgICAgICBkZWZlcnJlZENvcGllciA9IG5ldyBUeXBlTWFwcGluZzxWb2lkPiAoKSB7CiAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgICAgIHB1YmxpYyBUeXBlIHZpc2l0VHlwZShUeXBlIHQsIFZvaWQgdikgewogICAgICAgICAgICAgICAgICAgIGlmICh0Lmhhc1RhZyhERUZFUlJFRCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgRGVmZXJyZWRUeXBlIGR0ID0gKERlZmVycmVkVHlwZSkgdDsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBEZWZlcnJlZFR5cGUodHJlZUNvcGllci5jb3B5KGR0LnRyZWUpLCBkdC5lbnYpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICByZXR1cm4gdDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKICAgIH0KCiAgICAvKiogc2hhcmVkIHRyZWUgZm9yIHN0dWNrIGV4cHJlc3Npb25zICovCiAgICBmaW5hbCBKQ1RyZWUgc3R1Y2tUcmVlOwoKICAgIC8qKgogICAgICogVGhpcyB0eXBlIHJlcHJlc2VudHMgYSBkZWZlcnJlZCB0eXBlLiBBIGRlZmVycmVkIHR5cGUgc3RhcnRzIG9mZiB3aXRoCiAgICAgKiBubyBpbmZvcm1hdGlvbiBvbiB0aGUgdW5kZXJseWluZyBleHByZXNzaW9uIHR5cGUuIFN1Y2ggaW5mbyBuZWVkcyB0byBiZQogICAgICogZGlzY292ZXJlZCB0aHJvdWdoIHR5cGUtY2hlY2tpbmcgdGhlIGRlZmVycmVkIHR5cGUgYWdhaW5zdCBhIHRhcmdldC10eXBlLgogICAgICogRXZlcnkgZGVmZXJyZWQgdHlwZSBrZWVwcyBhIHBvaW50ZXIgdG8gdGhlIEFTVCBub2RlIGZyb20gd2hpY2ggaXQgb3JpZ2luYXRlZC4KICAgICAqLwogICAgcHVibGljIGNsYXNzIERlZmVycmVkVHlwZSBleHRlbmRzIFR5cGUgewoKICAgICAgICBwdWJsaWMgSkNFeHByZXNzaW9uIHRyZWU7CiAgICAgICAgRW52PEF0dHJDb250ZXh0PiBlbnY7CiAgICAgICAgQXR0ck1vZGUgbW9kZTsKICAgICAgICBib29sZWFuIHBlcnRpbmVudFRvQXBwbGljYWJpbGl0eSA9IHRydWU7CiAgICAgICAgU3BlY3VsYXRpdmVDYWNoZSBzcGVjdWxhdGl2ZUNhY2hlOwoKICAgICAgICBEZWZlcnJlZFR5cGUoSkNFeHByZXNzaW9uIHRyZWUsIEVudjxBdHRyQ29udGV4dD4gZW52KSB7CiAgICAgICAgICAgIHN1cGVyKG51bGwsIFR5cGVNZXRhZGF0YS5FTVBUWSk7CiAgICAgICAgICAgIHRoaXMudHJlZSA9IHRyZWU7CiAgICAgICAgICAgIHRoaXMuZW52ID0gYXR0ci5jb3B5RW52KGVudik7CiAgICAgICAgICAgIHRoaXMuc3BlY3VsYXRpdmVDYWNoZSA9IG5ldyBTcGVjdWxhdGl2ZUNhY2hlKCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgRGVmZXJyZWRUeXBlIGNsb25lV2l0aE1ldGFkYXRhKFR5cGVNZXRhZGF0YSBtZCkgewogICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoIkNhbm5vdCBhZGQgbWV0YWRhdGEgdG8gYSBkZWZlcnJlZCB0eXBlIik7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgVHlwZVRhZyBnZXRUYWcoKSB7CiAgICAgICAgICAgIHJldHVybiBERUZFUlJFRDsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgICAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewogICAgICAgICAgICByZXR1cm4gIkRlZmVycmVkVHlwZSI7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBBIHNwZWN1bGF0aXZlIGNhY2hlIGlzIHVzZWQgdG8ga2VlcCB0cmFjayBvZiBhbGwgb3ZlcmxvYWQgcmVzb2x1dGlvbiByb3VuZHMKICAgICAgICAgKiB0aGF0IHRyaWdnZXJlZCBzcGVjdWxhdGl2ZSBhdHRyaWJ1dGlvbiBvbiBhIGdpdmVuIGRlZmVycmVkIHR5cGUuIEVhY2ggZW50cnkKICAgICAgICAgKiBzdG9yZXMgYSBwb2ludGVyIHRvIHRoZSBzcGVjdWxhdGl2ZSB0cmVlIGFuZCB0aGUgcmVzb2x1dGlvbiBwaGFzZSBpbiB3aGljaCB0aGUgZW50cnkKICAgICAgICAgKiBoYXMgYmVlbiBhZGRlZC4KICAgICAgICAgKi8KICAgICAgICBjbGFzcyBTcGVjdWxhdGl2ZUNhY2hlIHsKCiAgICAgICAgICAgIHByaXZhdGUgTWFwPFN5bWJvbCwgTGlzdDxFbnRyeT4+IGNhY2hlID0gbmV3IFdlYWtIYXNoTWFwPD4oKTsKCiAgICAgICAgICAgIGNsYXNzIEVudHJ5IHsKICAgICAgICAgICAgICAgIEpDVHJlZSBzcGVjdWxhdGl2ZVRyZWU7CiAgICAgICAgICAgICAgICBSZXN1bHRJbmZvIHJlc3VsdEluZm87CgogICAgICAgICAgICAgICAgcHVibGljIEVudHJ5KEpDVHJlZSBzcGVjdWxhdGl2ZVRyZWUsIFJlc3VsdEluZm8gcmVzdWx0SW5mbykgewogICAgICAgICAgICAgICAgICAgIHRoaXMuc3BlY3VsYXRpdmVUcmVlID0gc3BlY3VsYXRpdmVUcmVlOwogICAgICAgICAgICAgICAgICAgIHRoaXMucmVzdWx0SW5mbyA9IHJlc3VsdEluZm87CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgYm9vbGVhbiBtYXRjaGVzKE1ldGhvZFJlc29sdXRpb25QaGFzZSBwaGFzZSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHRJbmZvLmNoZWNrQ29udGV4dC5kZWZlcnJlZEF0dHJDb250ZXh0KCkucGhhc2UgPT0gcGhhc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBSZXRyaWV2ZSBhIHNwZWN1bGF0aXZlIGNhY2hlIGVudHJ5IGNvcnJlc3BvbmRpbmcgdG8gZ2l2ZW4gc3ltYm9sCiAgICAgICAgICAgICAqIGFuZCByZXNvbHV0aW9uIHBoYXNlCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBFbnRyeSBnZXQoU3ltYm9sIG1zeW0sIE1ldGhvZFJlc29sdXRpb25QaGFzZSBwaGFzZSkgewogICAgICAgICAgICAgICAgTGlzdDxFbnRyeT4gZW50cmllcyA9IGNhY2hlLmdldChtc3ltKTsKICAgICAgICAgICAgICAgIGlmIChlbnRyaWVzID09IG51bGwpIHJldHVybiBudWxsOwogICAgICAgICAgICAgICAgZm9yIChFbnRyeSBlIDogZW50cmllcykgewogICAgICAgICAgICAgICAgICAgIGlmIChlLm1hdGNoZXMocGhhc2UpKSByZXR1cm4gZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogU3RvcmVzIGEgc3BlY3VsYXRpdmUgY2FjaGUgZW50cnkgY29ycmVzcG9uZGluZyB0byBnaXZlbiBzeW1ib2wKICAgICAgICAgICAgICogYW5kIHJlc29sdXRpb24gcGhhc2UKICAgICAgICAgICAgICovCiAgICAgICAgICAgIHZvaWQgcHV0KEpDVHJlZSBzcGVjdWxhdGl2ZVRyZWUsIFJlc3VsdEluZm8gcmVzdWx0SW5mbykgewogICAgICAgICAgICAgICAgU3ltYm9sIG1zeW0gPSByZXN1bHRJbmZvLmNoZWNrQ29udGV4dC5kZWZlcnJlZEF0dHJDb250ZXh0KCkubXN5bTsKICAgICAgICAgICAgICAgIExpc3Q8RW50cnk+IGVudHJpZXMgPSBjYWNoZS5nZXQobXN5bSk7CiAgICAgICAgICAgICAgICBpZiAoZW50cmllcyA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgZW50cmllcyA9IExpc3QubmlsKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBjYWNoZS5wdXQobXN5bSwgZW50cmllcy5wcmVwZW5kKG5ldyBFbnRyeShzcGVjdWxhdGl2ZVRyZWUsIHJlc3VsdEluZm8pKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIEdldCB0aGUgdHlwZSB0aGF0IGhhcyBiZWVuIGNvbXB1dGVkIGR1cmluZyBhIHNwZWN1bGF0aXZlIGF0dHJpYnV0aW9uIHJvdW5kCiAgICAgICAgICovCiAgICAgICAgVHlwZSBzcGVjdWxhdGl2ZVR5cGUoU3ltYm9sIG1zeW0sIE1ldGhvZFJlc29sdXRpb25QaGFzZSBwaGFzZSkgewogICAgICAgICAgICBTcGVjdWxhdGl2ZUNhY2hlLkVudHJ5IGUgPSBzcGVjdWxhdGl2ZUNhY2hlLmdldChtc3ltLCBwaGFzZSk7CiAgICAgICAgICAgIHJldHVybiBlICE9IG51bGwgPyBlLnNwZWN1bGF0aXZlVHJlZS50eXBlIDogVHlwZS5ub1R5cGU7CiAgICAgICAgfQoKICAgICAgICBKQ1RyZWUgc3BlY3VsYXRpdmVUcmVlKERlZmVycmVkQXR0ckNvbnRleHQgZGVmZXJyZWRBdHRyQ29udGV4dCkgewogICAgICAgICAgICBEZWZlcnJlZFR5cGUuU3BlY3VsYXRpdmVDYWNoZS5FbnRyeSBlID0gc3BlY3VsYXRpdmVDYWNoZS5nZXQoZGVmZXJyZWRBdHRyQ29udGV4dC5tc3ltLCBkZWZlcnJlZEF0dHJDb250ZXh0LnBoYXNlKTsKICAgICAgICAgICAgcmV0dXJuIGUgIT0gbnVsbCA/IGUuc3BlY3VsYXRpdmVUcmVlIDogc3R1Y2tUcmVlOwogICAgICAgIH0KCiAgICAgICAgRGVmZXJyZWRUeXBlQ29tcGxldGVyIGNvbXBsZXRlcigpIHsKICAgICAgICAgICAgcmV0dXJuIGJhc2ljQ29tcGxldGVyOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogQ2hlY2sgYSBkZWZlcnJlZCB0eXBlIGFnYWluc3QgYSBwb3RlbnRpYWwgdGFyZ2V0LXR5cGUuIERlcGVuZGluZyBvbgogICAgICAgICAqIHRoZSBjdXJyZW50IGF0dHJpYnV0aW9uIG1vZGUsIGEgbm9ybWFsIHZzLiBzcGVjdWxhdGl2ZSBhdHRyaWJ1dGlvbgogICAgICAgICAqIHJvdW5kIGlzIHBlcmZvcm1lZCBvbiB0aGUgdW5kZXJseWluZyBBU1Qgbm9kZS4gVGhlcmUgY2FuIGJlIG9ubHkgb25lCiAgICAgICAgICogc3BlY3VsYXRpdmUgcm91bmQgZm9yIGEgZ2l2ZW4gdGFyZ2V0IG1ldGhvZCBzeW1ib2w7IG1vcmVvdmVyLCBhIG5vcm1hbAogICAgICAgICAqIGF0dHJpYnV0aW9uIHJvdW5kIG11c3QgZm9sbG93IG9uZSBvciBtb3JlIHNwZWN1bGF0aXZlIHJvdW5kcy4KICAgICAgICAgKi8KICAgICAgICBUeXBlIGNoZWNrKFJlc3VsdEluZm8gcmVzdWx0SW5mbykgewogICAgICAgICAgICBEZWZlcnJlZFN0dWNrUG9saWN5IGRlZmVycmVkU3R1Y2tQb2xpY3k7CiAgICAgICAgICAgIGlmIChyZXN1bHRJbmZvLnB0Lmhhc1RhZyhOT05FKSB8fCByZXN1bHRJbmZvLnB0LmlzRXJyb25lb3VzKCkpIHsKICAgICAgICAgICAgICAgIGRlZmVycmVkU3R1Y2tQb2xpY3kgPSBkdW1teVN0dWNrUG9saWN5OwogICAgICAgICAgICB9IGVsc2UgaWYgKHJlc3VsdEluZm8uY2hlY2tDb250ZXh0LmRlZmVycmVkQXR0ckNvbnRleHQoKS5tb2RlID09IEF0dHJNb2RlLlNQRUNVTEFUSVZFIHx8CiAgICAgICAgICAgICAgICAgICAgcmVzdWx0SW5mby5jaGVja0NvbnRleHQuZGVmZXJyZWRBdHRyQ29udGV4dCgpLmluc2lkZU92ZXJsb2FkUGhhc2UoKSkgewogICAgICAgICAgICAgICAgZGVmZXJyZWRTdHVja1BvbGljeSA9IG5ldyBPdmVybG9hZFN0dWNrUG9saWN5KHJlc3VsdEluZm8sIHRoaXMpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgZGVmZXJyZWRTdHVja1BvbGljeSA9IG5ldyBDaGVja1N0dWNrUG9saWN5KHJlc3VsdEluZm8sIHRoaXMpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBjaGVjayhyZXN1bHRJbmZvLCBkZWZlcnJlZFN0dWNrUG9saWN5LCBjb21wbGV0ZXIoKSk7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIFR5cGUgY2hlY2soUmVzdWx0SW5mbyByZXN1bHRJbmZvLCBEZWZlcnJlZFN0dWNrUG9saWN5IGRlZmVycmVkU3R1Y2tQb2xpY3ksCiAgICAgICAgICAgICAgICBEZWZlcnJlZFR5cGVDb21wbGV0ZXIgZGVmZXJyZWRUeXBlQ29tcGxldGVyKSB7CiAgICAgICAgICAgIERlZmVycmVkQXR0ckNvbnRleHQgZGVmZXJyZWRBdHRyQ29udGV4dCA9CiAgICAgICAgICAgICAgICAgICAgcmVzdWx0SW5mby5jaGVja0NvbnRleHQuZGVmZXJyZWRBdHRyQ29udGV4dCgpOwogICAgICAgICAgICBBc3NlcnQuY2hlY2soZGVmZXJyZWRBdHRyQ29udGV4dCAhPSBlbXB0eURlZmVycmVkQXR0ckNvbnRleHQpOwogICAgICAgICAgICBpZiAoZGVmZXJyZWRTdHVja1BvbGljeS5pc1N0dWNrKCkpIHsKICAgICAgICAgICAgICAgIHBlcnRpbmVudFRvQXBwbGljYWJpbGl0eSA9IGZhbHNlOwogICAgICAgICAgICAgICAgZGVmZXJyZWRBdHRyQ29udGV4dC5hZGREZWZlcnJlZEF0dHJOb2RlKHRoaXMsIHJlc3VsdEluZm8sIGRlZmVycmVkU3R1Y2tQb2xpY3kpOwogICAgICAgICAgICAgICAgcmV0dXJuIFR5cGUubm9UeXBlOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGVmZXJyZWRUeXBlQ29tcGxldGVyLmNvbXBsZXRlKHRoaXMsIHJlc3VsdEluZm8sIGRlZmVycmVkQXR0ckNvbnRleHQpOwogICAgICAgICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgICAgICAgICBtb2RlID0gZGVmZXJyZWRBdHRyQ29udGV4dC5tb2RlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQSBjb21wbGV0ZXIgZm9yIGRlZmVycmVkIHR5cGVzLiBEZWZpbmVzIGFuIGVudHJ5IHBvaW50IGZvciB0eXBlLWNoZWNraW5nCiAgICAgKiBhIGRlZmVycmVkIHR5cGUuCiAgICAgKi8KICAgIGludGVyZmFjZSBEZWZlcnJlZFR5cGVDb21wbGV0ZXIgewogICAgICAgIC8qKgogICAgICAgICAqIEVudHJ5IHBvaW50IGZvciB0eXBlLWNoZWNraW5nIGEgZGVmZXJyZWQgdHlwZS4gRGVwZW5kaW5nIG9uIHRoZQogICAgICAgICAqIGNpcmN1bXN0YW5jZXMsIHR5cGUtY2hlY2tpbmcgY291bGQgYW1vdW50IHRvIGZ1bGwgYXR0cmlidXRpb24KICAgICAgICAgKiBvciBwYXJ0aWFsIHN0cnVjdHVyYWwgY2hlY2sgKGFrYSBwb3RlbnRpYWwgYXBwbGljYWJpbGl0eSkuCiAgICAgICAgICovCiAgICAgICAgVHlwZSBjb21wbGV0ZShEZWZlcnJlZFR5cGUgZHQsIFJlc3VsdEluZm8gcmVzdWx0SW5mbywgRGVmZXJyZWRBdHRyQ29udGV4dCBkZWZlcnJlZEF0dHJDb250ZXh0KTsKICAgIH0KCgogICAgLyoqCiAgICAgKiBBIGJhc2ljIGNvbXBsZXRlciBmb3IgZGVmZXJyZWQgdHlwZXMuIFRoaXMgY29tcGxldGVyIHR5cGUtY2hlY2tzIGEgZGVmZXJyZWQgdHlwZQogICAgICogdXNpbmcgYXR0cmlidXRpb247IGRlcGVuZGluZyBvbiB0aGUgYXR0cmlidXRpb24gbW9kZSwgdGhpcyBjb3VsZCBiZSBlaXRoZXIgc3RhbmRhcmQKICAgICAqIG9yIHNwZWN1bGF0aXZlIGF0dHJpYnV0aW9uLgogICAgICovCiAgICBEZWZlcnJlZFR5cGVDb21wbGV0ZXIgYmFzaWNDb21wbGV0ZXIgPSBuZXcgRGVmZXJyZWRUeXBlQ29tcGxldGVyKCkgewogICAgICAgIHB1YmxpYyBUeXBlIGNvbXBsZXRlKERlZmVycmVkVHlwZSBkdCwgUmVzdWx0SW5mbyByZXN1bHRJbmZvLCBEZWZlcnJlZEF0dHJDb250ZXh0IGRlZmVycmVkQXR0ckNvbnRleHQpIHsKICAgICAgICAgICAgc3dpdGNoIChkZWZlcnJlZEF0dHJDb250ZXh0Lm1vZGUpIHsKICAgICAgICAgICAgICAgIGNhc2UgU1BFQ1VMQVRJVkU6CiAgICAgICAgICAgICAgICAgICAgLy9Ob3RlOiBpZiBhIHN5bWJvbCBpcyBpbXBvcnRlZCB0d2ljZSB3ZSBtaWdodCBkbyB0d28gaWRlbnRpY2FsCiAgICAgICAgICAgICAgICAgICAgLy9zcGVjdWxhdGl2ZSByb3VuZHMuLi4KICAgICAgICAgICAgICAgICAgICBBc3NlcnQuY2hlY2soZHQubW9kZSA9PSBudWxsIHx8IGR0Lm1vZGUgPT0gQXR0ck1vZGUuU1BFQ1VMQVRJVkUpOwogICAgICAgICAgICAgICAgICAgIEpDVHJlZSBzcGVjdWxhdGl2ZVRyZWUgPSBhdHRyaWJTcGVjdWxhdGl2ZShkdC50cmVlLCBkdC5lbnYsIHJlc3VsdEluZm8pOwogICAgICAgICAgICAgICAgICAgIGR0LnNwZWN1bGF0aXZlQ2FjaGUucHV0KHNwZWN1bGF0aXZlVHJlZSwgcmVzdWx0SW5mbyk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHNwZWN1bGF0aXZlVHJlZS50eXBlOwogICAgICAgICAgICAgICAgY2FzZSBDSEVDSzoKICAgICAgICAgICAgICAgICAgICBBc3NlcnQuY2hlY2soZHQubW9kZSAhPSBudWxsKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gYXR0ci5hdHRyaWJUcmVlKGR0LnRyZWUsIGR0LmVudiwgcmVzdWx0SW5mbyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgQXNzZXJ0LmVycm9yKCk7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KICAgIH07CgogICAgLyoqCiAgICAgKiBQb2xpY3kgZm9yIGRldGVjdGluZyBzdHVjayBleHByZXNzaW9ucy4gRGlmZmVyZW50IGNyaXRlcmlhIG1pZ2h0IGNhdXNlCiAgICAgKiBhbiBleHByZXNzaW9uIHRvIGJlIGp1ZGdlZCBhcyBzdHVjaywgZGVwZW5kaW5nIG9uIHdoZXRoZXIgdGhlIGNoZWNrCiAgICAgKiBpcyBwZXJmb3JtZWQgZHVyaW5nIG92ZXJsb2FkIHJlc29sdXRpb24gb3IgYWZ0ZXIgbW9zdCBzcGVjaWZpYy4KICAgICAqLwogICAgaW50ZXJmYWNlIERlZmVycmVkU3R1Y2tQb2xpY3kgewogICAgICAgIC8qKgogICAgICAgICAqIEhhcyB0aGUgcG9saWN5IGRldGVjdGVkIHRoYXQgYSBnaXZlbiBleHByZXNzaW9uIHNob3VsZCBiZSBjb25zaWRlcmVkIHN0dWNrPwogICAgICAgICAqLwogICAgICAgIGJvb2xlYW4gaXNTdHVjaygpOwogICAgICAgIC8qKgogICAgICAgICAqIEdldCB0aGUgc2V0IG9mIGluZmVyZW5jZSB2YXJpYWJsZXMgYSBnaXZlbiBleHByZXNzaW9uIGRlcGVuZHMgdXBvbi4KICAgICAgICAgKi8KICAgICAgICBTZXQ8VHlwZT4gc3R1Y2tWYXJzKCk7CiAgICAgICAgLyoqCiAgICAgICAgICogR2V0IHRoZSBzZXQgb2YgaW5mZXJlbmNlIHZhcmlhYmxlcyB3aGljaCBtaWdodCBnZXQgbmV3IGNvbnN0cmFpbnRzCiAgICAgICAgICogaWYgYSBnaXZlbiBleHByZXNzaW9uIGlzIGJlaW5nIHR5cGUtY2hlY2tlZC4KICAgICAgICAgKi8KICAgICAgICBTZXQ8VHlwZT4gZGVwVmFycygpOwogICAgfQoKICAgIC8qKgogICAgICogQmFzaWMgc3R1Y2sgcG9saWN5OyBhbiBleHByZXNzaW9uIGlzIG5ldmVyIGNvbnNpZGVyZWQgdG8gYmUgc3R1Y2suCiAgICAgKi8KICAgIERlZmVycmVkU3R1Y2tQb2xpY3kgZHVtbXlTdHVja1BvbGljeSA9IG5ldyBEZWZlcnJlZFN0dWNrUG9saWN5KCkgewogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBib29sZWFuIGlzU3R1Y2soKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFNldDxUeXBlPiBzdHVja1ZhcnMoKSB7CiAgICAgICAgICAgIHJldHVybiBDb2xsZWN0aW9ucy5lbXB0eVNldCgpOwogICAgICAgIH0KICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgU2V0PFR5cGU+IGRlcFZhcnMoKSB7CiAgICAgICAgICAgIHJldHVybiBDb2xsZWN0aW9ucy5lbXB0eVNldCgpOwogICAgICAgIH0KICAgIH07CgogICAgLyoqCiAgICAgKiBUaGUgJ21vZGUnIGluIHdoaWNoIHRoZSBkZWZlcnJlZCB0eXBlIGlzIHRvIGJlIHR5cGUtY2hlY2tlZAogICAgICovCiAgICBwdWJsaWMgZW51bSBBdHRyTW9kZSB7CiAgICAgICAgLyoqCiAgICAgICAgICogQSBzcGVjdWxhdGl2ZSB0eXBlLWNoZWNraW5nIHJvdW5kIGlzIHVzZWQgZHVyaW5nIG92ZXJsb2FkIHJlc29sdXRpb24KICAgICAgICAgKiBtYWlubHkgdG8gZ2VuZXJhdGUgY29uc3RyYWludHMgb24gaW5mZXJlbmNlIHZhcmlhYmxlcy4gU2lkZS1lZmZlY3RzCiAgICAgICAgICogYXJpc2luZyBmcm9tIHR5cGUtY2hlY2tpbmcgdGhlIGV4cHJlc3Npb24gYXNzb2NpYXRlZCB3aXRoIHRoZSBkZWZlcnJlZAogICAgICAgICAqIHR5cGUgYXJlIHJldmVyc2VkIGFmdGVyIHRoZSBzcGVjdWxhdGl2ZSByb3VuZCBmaW5pc2hlcy4gVGhpcyBtZWFucyB0aGUKICAgICAgICAgKiBleHByZXNzaW9uIHRyZWUgd2lsbCBiZSBsZWZ0IGluIGEgYmxhbmsgc3RhdGUuCiAgICAgICAgICovCiAgICAgICAgU1BFQ1VMQVRJVkUsCiAgICAgICAgLyoqCiAgICAgICAgICogVGhpcyBpcyB0aGUgcGxhaW4gdHlwZS1jaGVja2luZyBtb2RlLiBQcm9kdWNlcyBzaWRlLWVmZmVjdHMgb24gdGhlIHVuZGVybHlpbmcgQVNUIG5vZGUKICAgICAgICAgKi8KICAgICAgICBDSEVDSwogICAgfQoKICAgIC8qKgogICAgICogUGVyZm9ybXMgc3BlY3VsYXRpdmUgYXR0cmlidXRpb24gb2YgYSBsYW1iZGEgYm9keSBhbmQgcmV0dXJucyB0aGUgc3BlY3VsYXRpdmUgbGFtYmRhIHRyZWUsCiAgICAgKiBpbiB0aGUgYWJzZW5jZSBvZiBhIHRhcmdldC10eXBlLiBTaW5jZSB7QGxpbmsgQXR0ciN2aXNpdExhbWJkYShKQ0xhbWJkYSl9IGNhbm5vdCB0eXBlLWNoZWNrCiAgICAgKiBsYW1iZGEgYm9kaWVzIHcvbyBhIHN1aXRhYmxlIHRhcmdldC10eXBlLCB0aGlzIHJvdXRpbmUgJ3Vucm9sbHMnIHRoZSBsYW1iZGEgYnkgdHVybmluZyBpdAogICAgICogaW50byBhIHJlZ3VsYXIgYmxvY2ssIHNwZWN1bGF0aXZlbHkgdHlwZS1jaGVja3MgdGhlIGJsb2NrIGFuZCB0aGVuIHB1dHMgYmFjayB0aGUgcGllY2VzLgogICAgICovCiAgICBKQ0xhbWJkYSBhdHRyaWJTcGVjdWxhdGl2ZUxhbWJkYShKQ0xhbWJkYSB0aGF0LCBFbnY8QXR0ckNvbnRleHQ+IGVudiwgUmVzdWx0SW5mbyByZXN1bHRJbmZvKSB7CiAgICAgICAgTGlzdEJ1ZmZlcjxKQ1N0YXRlbWVudD4gc3RhdHMgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgc3RhdHMuYWRkQWxsKHRoYXQucGFyYW1zKTsKICAgICAgICBpZiAodGhhdC5nZXRCb2R5S2luZCgpID09IEpDTGFtYmRhLkJvZHlLaW5kLkVYUFJFU1NJT04pIHsKICAgICAgICAgICAgc3RhdHMuYWRkKG1ha2UuUmV0dXJuKChKQ0V4cHJlc3Npb24pdGhhdC5ib2R5KSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc3RhdHMuYWRkKChKQ0Jsb2NrKXRoYXQuYm9keSk7CiAgICAgICAgfQogICAgICAgIEpDQmxvY2sgbGFtYmRhQmxvY2sgPSBtYWtlLkJsb2NrKDAsIHN0YXRzLnRvTGlzdCgpKTsKICAgICAgICBFbnY8QXR0ckNvbnRleHQ+IGxvY2FsRW52ID0gYXR0ci5sYW1iZGFFbnYodGhhdCwgZW52KTsKICAgICAgICB0cnkgewogICAgICAgICAgICBsb2NhbEVudi5pbmZvLnJldHVyblJlc3VsdCA9IHJlc3VsdEluZm87CiAgICAgICAgICAgIEpDQmxvY2sgc3BlY3VsYXRpdmVUcmVlID0gKEpDQmxvY2spYXR0cmliU3BlY3VsYXRpdmUobGFtYmRhQmxvY2ssIGxvY2FsRW52LCByZXN1bHRJbmZvKTsKICAgICAgICAgICAgTGlzdDxKQ1ZhcmlhYmxlRGVjbD4gYXJncyA9IHNwZWN1bGF0aXZlVHJlZS5nZXRTdGF0ZW1lbnRzKCkuc3RyZWFtKCkKICAgICAgICAgICAgICAgICAgICAuZmlsdGVyKHMgLT4gcy5oYXNUYWcoVGFnLlZBUkRFRikpCiAgICAgICAgICAgICAgICAgICAgLm1hcCh0IC0+IChKQ1ZhcmlhYmxlRGVjbCl0KQogICAgICAgICAgICAgICAgICAgIC5jb2xsZWN0KExpc3QuY29sbGVjdG9yKCkpOwogICAgICAgICAgICBKQ1RyZWUgbGFtYmRhQm9keSA9IHNwZWN1bGF0aXZlVHJlZS5nZXRTdGF0ZW1lbnRzKCkubGFzdCgpOwogICAgICAgICAgICBpZiAobGFtYmRhQm9keS5oYXNUYWcoVGFnLlJFVFVSTikpIHsKICAgICAgICAgICAgICAgIGxhbWJkYUJvZHkgPSAoKEpDUmV0dXJuKWxhbWJkYUJvZHkpLmV4cHI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgSkNMYW1iZGEgc3BlY3VsYXRpdmVMYW1iZGEgPSBtYWtlLkxhbWJkYShhcmdzLCBsYW1iZGFCb2R5KTsKICAgICAgICAgICAgYXR0ci5wcmVGbG93KHNwZWN1bGF0aXZlTGFtYmRhKTsKICAgICAgICAgICAgZmxvdy5hbmFseXplTGFtYmRhKGVudiwgc3BlY3VsYXRpdmVMYW1iZGEsIG1ha2UsIGZhbHNlKTsKICAgICAgICAgICAgcmV0dXJuIHNwZWN1bGF0aXZlTGFtYmRhOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgIGxvY2FsRW52LmluZm8uc2NvcGUubGVhdmUoKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBSb3V0aW5lIHRoYXQgcGVyZm9ybXMgc3BlY3VsYXRpdmUgdHlwZS1jaGVja2luZzsgdGhlIGlucHV0IEFTVCBub2RlIGlzCiAgICAgKiBjbG9uZWQgKHRvIGF2b2lkIHNpZGUtZWZmZWN0cyBjYXVzZSBieSBBdHRyKSBhbmQgY29tcGlsZXIgc3RhdGUgaXMKICAgICAqIHJlc3RvcmVkIGFmdGVyIHR5cGUtY2hlY2tpbmcuIEFsbCBkaWFnbm9zdGljcyAoYnV0IGNyaXRpY2FsIG9uZXMpIGFyZQogICAgICogZGlzYWJsZWQgZHVyaW5nIHNwZWN1bGF0aXZlIHR5cGUtY2hlY2tpbmcuCiAgICAgKi8KICAgIEpDVHJlZSBhdHRyaWJTcGVjdWxhdGl2ZShKQ1RyZWUgdHJlZSwgRW52PEF0dHJDb250ZXh0PiBlbnYsIFJlc3VsdEluZm8gcmVzdWx0SW5mbykgewogICAgICAgIHJldHVybiBhdHRyaWJTcGVjdWxhdGl2ZSh0cmVlLCBlbnYsIHJlc3VsdEluZm8sIHRyZWVDb3BpZXIsCiAgICAgICAgICAgICAgICAobmV3VHJlZSktPm5ldyBEZWZlcnJlZEF0dHJEaWFnSGFuZGxlcihsb2csIG5ld1RyZWUpKTsKICAgIH0KCiAgICA8Wj4gSkNUcmVlIGF0dHJpYlNwZWN1bGF0aXZlKEpDVHJlZSB0cmVlLCBFbnY8QXR0ckNvbnRleHQ+IGVudiwgUmVzdWx0SW5mbyByZXN1bHRJbmZvLCBUcmVlQ29waWVyPFo+IGRlZmVycmVkQ29waWVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGdW5jdGlvbjxKQ1RyZWUsIERlZmVycmVkRGlhZ25vc3RpY0hhbmRsZXI+IGRpYWdIYW5kbGVyQ3JlYXRvcikgewogICAgICAgIGZpbmFsIEpDVHJlZSBuZXdUcmVlID0gZGVmZXJyZWRDb3BpZXIuY29weSh0cmVlKTsKICAgICAgICBFbnY8QXR0ckNvbnRleHQ+IHNwZWN1bGF0aXZlRW52ID0gZW52LmR1cChuZXdUcmVlLCBlbnYuaW5mby5kdXAoZW52LmluZm8uc2NvcGUuZHVwVW5zaGFyZWQoZW52LmluZm8uc2NvcGUub3duZXIpKSk7CiAgICAgICAgc3BlY3VsYXRpdmVFbnYuaW5mby5pc1NwZWN1bGF0aXZlID0gdHJ1ZTsKICAgICAgICBMb2cuRGVmZXJyZWREaWFnbm9zdGljSGFuZGxlciBkZWZlcnJlZERpYWdub3N0aWNIYW5kbGVyID0gZGlhZ0hhbmRsZXJDcmVhdG9yLmFwcGx5KG5ld1RyZWUpOwogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGF0dHIuYXR0cmliVHJlZShuZXdUcmVlLCBzcGVjdWxhdGl2ZUVudiwgcmVzdWx0SW5mbyk7CiAgICAgICAgICAgIHJldHVybiBuZXdUcmVlOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgIG5ldyBVbmVudGVyU2Nhbm5lcihlbnYudG9wbGV2ZWwubW9kbGUpLnNjYW4obmV3VHJlZSk7CiAgICAgICAgICAgIGxvZy5wb3BEaWFnbm9zdGljSGFuZGxlcihkZWZlcnJlZERpYWdub3N0aWNIYW5kbGVyKTsKICAgICAgICB9CiAgICB9CiAgICAvL3doZXJlCgogICAgICAgIGNsYXNzIFVuZW50ZXJTY2FubmVyIGV4dGVuZHMgVHJlZVNjYW5uZXIgewogICAgICAgICAgICBwcml2YXRlIGZpbmFsIE1vZHVsZVN5bWJvbCBtc3ltOwoKICAgICAgICAgICAgcHVibGljIFVuZW50ZXJTY2FubmVyKE1vZHVsZVN5bWJvbCBtc3ltKSB7CiAgICAgICAgICAgICAgICB0aGlzLm1zeW0gPSBtc3ltOwogICAgICAgICAgICB9CgogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHVibGljIHZvaWQgdmlzaXRDbGFzc0RlZihKQ0NsYXNzRGVjbCB0cmVlKSB7CiAgICAgICAgICAgICAgICBDbGFzc1N5bWJvbCBjc3ltID0gdHJlZS5zeW07CiAgICAgICAgICAgICAgICAvL2lmIHNvbWV0aGluZyB3ZW50IHdyb25nIGR1cmluZyBtZXRob2QgYXBwbGljYWJpbGl0eSBjaGVjawogICAgICAgICAgICAgICAgLy9pdCBpcyBwb3NzaWJsZSB0aGF0IG5lc3RlZCBleHByZXNzaW9ucyBpbnNpZGUgYXJndW1lbnQgZXhwcmVzc2lvbgogICAgICAgICAgICAgICAgLy9hcmUgbGVmdCB1bmNoZWNrZWQgLSBpbiBzdWNoIGNhc2VzIHRoZXJlJ3Mgbm90aGluZyB0byBjbGVhbiB1cC4KICAgICAgICAgICAgICAgIGlmIChjc3ltID09IG51bGwpIHJldHVybjsKICAgICAgICAgICAgICAgIHR5cGVFbnZzLnJlbW92ZShjc3ltKTsKICAgICAgICAgICAgICAgIGNoay5yZW1vdmVDb21waWxlZChjc3ltKTsKICAgICAgICAgICAgICAgIGNoay5jbGVhckxvY2FsQ2xhc3NOYW1lSW5kZXhlcyhjc3ltKTsKICAgICAgICAgICAgICAgIHN5bXMucmVtb3ZlQ2xhc3MobXN5bSwgY3N5bS5mbGF0bmFtZSk7CiAgICAgICAgICAgICAgICBzdXBlci52aXNpdENsYXNzRGVmKHRyZWUpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBzdGF0aWMgY2xhc3MgRGVmZXJyZWRBdHRyRGlhZ0hhbmRsZXIgZXh0ZW5kcyBMb2cuRGVmZXJyZWREaWFnbm9zdGljSGFuZGxlciB7CgogICAgICAgICAgICBzdGF0aWMgY2xhc3MgUG9zU2Nhbm5lciBleHRlbmRzIFRyZWVTY2FubmVyIHsKICAgICAgICAgICAgICAgIERpYWdub3N0aWNQb3NpdGlvbiBwb3M7CiAgICAgICAgICAgICAgICBib29sZWFuIGZvdW5kID0gZmFsc2U7CgogICAgICAgICAgICAgICAgUG9zU2Nhbm5lcihEaWFnbm9zdGljUG9zaXRpb24gcG9zKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5wb3MgPSBwb3M7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCBzY2FuKEpDVHJlZSB0cmVlKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHRyZWUgIT0gbnVsbCAmJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJlZS5wb3MoKSA9PSBwb3MpIHsKICAgICAgICAgICAgICAgICAgICAgICAgZm91bmQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBzdXBlci5zY2FuKHRyZWUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBEZWZlcnJlZEF0dHJEaWFnSGFuZGxlcihMb2cgbG9nLCBKQ1RyZWUgbmV3VHJlZSkgewogICAgICAgICAgICAgICAgc3VwZXIobG9nLCBkIC0+IHsKICAgICAgICAgICAgICAgICAgICBQb3NTY2FubmVyIHBvc1NjYW5uZXIgPSBuZXcgUG9zU2Nhbm5lcihkLmdldERpYWdub3N0aWNQb3NpdGlvbigpKTsKICAgICAgICAgICAgICAgICAgICBwb3NTY2FubmVyLnNjYW4obmV3VHJlZSk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHBvc1NjYW5uZXIuZm91bmQ7CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAvKioKICAgICAqIEEgZGVmZXJyZWQgY29udGV4dCBpcyBjcmVhdGVkIG9uIGVhY2ggbWV0aG9kIGNoZWNrLiBBIGRlZmVycmVkIGNvbnRleHQgaXMKICAgICAqIHVzZWQgdG8ga2VlcCB0cmFjayBvZiBpbmZvcm1hdGlvbiBhc3NvY2lhdGVkIHdpdGggdGhlIG1ldGhvZCBjaGVjaywgc3VjaCBhcwogICAgICogdGhlIHN5bWJvbCBvZiB0aGUgbWV0aG9kIGJlaW5nIGNoZWNrZWQsIHRoZSBvdmVybG9hZCByZXNvbHV0aW9uIHBoYXNlLAogICAgICogdGhlIGtpbmQgb2YgYXR0cmlidXRpb24gbW9kZSB0byBiZSBhcHBsaWVkIHRvIGRlZmVycmVkIHR5cGVzIGFuZCBzbyBmb3J0aC4KICAgICAqIEFzIGRlZmVycmVkIHR5cGVzIGFyZSBwcm9jZXNzZWQgKGJ5IHRoZSBtZXRob2QgY2hlY2sgcm91dGluZSkgc3R1Y2sgQVNUIG5vZGVzCiAgICAgKiBhcmUgYWRkZWQgKGFzIG5ldyBkZWZlcnJlZCBhdHRyaWJ1dGlvbiBub2RlcykgdG8gdGhpcyBjb250ZXh0LiBUaGUgY29tcGxldGUoKQogICAgICogcm91dGluZSBtYWtlcyBzdXJlIHRoYXQgYWxsIHBlbmRpbmcgbm9kZXMgYXJlIHByb3Blcmx5IHByb2Nlc3NlZCwgYnkKICAgICAqIHByb2dyZXNzaXZlbHkgaW5zdGFudGlhdGluZyBhbGwgaW5mZXJlbmNlIHZhcmlhYmxlcyBvbiB3aGljaCBvbmUgb3IgbW9yZQogICAgICogZGVmZXJyZWQgYXR0cmlidXRpb24gbm9kZSBpcyBzdHVjay4KICAgICAqLwogICAgY2xhc3MgRGVmZXJyZWRBdHRyQ29udGV4dCB7CgogICAgICAgIC8qKiBhdHRyaWJ1dGlvbiBtb2RlICovCiAgICAgICAgZmluYWwgQXR0ck1vZGUgbW9kZTsKCiAgICAgICAgLyoqIHN5bWJvbCBvZiB0aGUgbWV0aG9kIGJlaW5nIGNoZWNrZWQgKi8KICAgICAgICBmaW5hbCBTeW1ib2wgbXN5bTsKCiAgICAgICAgLyoqIG1ldGhvZCByZXNvbHV0aW9uIHN0ZXAgKi8KICAgICAgICBmaW5hbCBSZXNvbHZlLk1ldGhvZFJlc29sdXRpb25QaGFzZSBwaGFzZTsKCiAgICAgICAgLyoqIGluZmVyZW5jZSBjb250ZXh0ICovCiAgICAgICAgZmluYWwgSW5mZXJlbmNlQ29udGV4dCBpbmZlcmVuY2VDb250ZXh0OwoKICAgICAgICAvKiogcGFyZW50IGRlZmVycmVkIGNvbnRleHQgKi8KICAgICAgICBmaW5hbCBEZWZlcnJlZEF0dHJDb250ZXh0IHBhcmVudDsKCiAgICAgICAgLyoqIFdhcm5lciBvYmplY3QgdG8gcmVwb3J0IHdhcm5pbmdzICovCiAgICAgICAgZmluYWwgV2FybmVyIHdhcm47CgogICAgICAgIC8qKiBsaXN0IG9mIGRlZmVycmVkIGF0dHJpYnV0aW9uIG5vZGVzIHRvIGJlIHByb2Nlc3NlZCAqLwogICAgICAgIEFycmF5TGlzdDxEZWZlcnJlZEF0dHJOb2RlPiBkZWZlcnJlZEF0dHJOb2RlcyA9IG5ldyBBcnJheUxpc3Q8PigpOwoKICAgICAgICBEZWZlcnJlZEF0dHJDb250ZXh0KEF0dHJNb2RlIG1vZGUsIFN5bWJvbCBtc3ltLCBNZXRob2RSZXNvbHV0aW9uUGhhc2UgcGhhc2UsCiAgICAgICAgICAgICAgICBJbmZlcmVuY2VDb250ZXh0IGluZmVyZW5jZUNvbnRleHQsIERlZmVycmVkQXR0ckNvbnRleHQgcGFyZW50LCBXYXJuZXIgd2FybikgewogICAgICAgICAgICB0aGlzLm1vZGUgPSBtb2RlOwogICAgICAgICAgICB0aGlzLm1zeW0gPSBtc3ltOwogICAgICAgICAgICB0aGlzLnBoYXNlID0gcGhhc2U7CiAgICAgICAgICAgIHRoaXMucGFyZW50ID0gcGFyZW50OwogICAgICAgICAgICB0aGlzLndhcm4gPSB3YXJuOwogICAgICAgICAgICB0aGlzLmluZmVyZW5jZUNvbnRleHQgPSBpbmZlcmVuY2VDb250ZXh0OwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogQWRkcyBhIG5vZGUgdG8gdGhlIGxpc3Qgb2YgZGVmZXJyZWQgYXR0cmlidXRpb24gbm9kZXMgLSB1c2VkIGJ5IFJlc29sdmUucmF3Q2hlY2tBcmd1bWVudHNBcHBsaWNhYmxlCiAgICAgICAgICogTm9kZXMgYWRkZWQgdGhpcyB3YXkgYWN0IGFzICdyb290cycgZm9yIHRoZSBvdXQtb2Ytb3JkZXIgbWV0aG9kIGNoZWNraW5nIHByb2Nlc3MuCiAgICAgICAgICovCiAgICAgICAgdm9pZCBhZGREZWZlcnJlZEF0dHJOb2RlKGZpbmFsIERlZmVycmVkVHlwZSBkdCwgUmVzdWx0SW5mbyByZXN1bHRJbmZvLAogICAgICAgICAgICAgICAgRGVmZXJyZWRTdHVja1BvbGljeSBkZWZlcnJlZFN0dWNrUG9saWN5KSB7CiAgICAgICAgICAgIGRlZmVycmVkQXR0ck5vZGVzLmFkZChuZXcgRGVmZXJyZWRBdHRyTm9kZShkdCwgcmVzdWx0SW5mbywgZGVmZXJyZWRTdHVja1BvbGljeSkpOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogSW5jcmVtZW50YWxseSBwcm9jZXNzIGFsbCBub2RlcywgYnkgc2tpcHBpbmcgJ3N0dWNrJyBub2RlcyBhbmQgYXR0cmlidXRpbmcKICAgICAgICAgKiAndW5zdHVjaycgb25lcy4gSWYgYXQgYW55IHBvaW50IG5vIHByb2dyZXNzIGNhbiBiZSBtYWRlIChubyAndW5zdHVjaycgbm9kZXMpCiAgICAgICAgICogc29tZSBpbmZlcmVuY2UgdmFyaWFibGUgbWlnaHQgZ2V0IGVhZ2VybHkgaW5zdGFudGlhdGVkIHNvIHRoYXQgYWxsIG5vZGVzCiAgICAgICAgICogY2FuIGJlIHR5cGUtY2hlY2tlZC4KICAgICAgICAgKi8KICAgICAgICB2b2lkIGNvbXBsZXRlKCkgewogICAgICAgICAgICB3aGlsZSAoIWRlZmVycmVkQXR0ck5vZGVzLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgICAgYm9vbGVhbiBwcm9ncmVzcyA9IGZhbHNlOwogICAgICAgICAgICAgICAgLy9zY2FuIGEgZGVmZW5zaXZlIGNvcHkgb2YgdGhlIG5vZGUgbGlzdCAtIHRoaXMgaXMgYmVjYXVzZSBhIGRlZmVycmVkCiAgICAgICAgICAgICAgICAvL2F0dHJpYnV0aW9uIHJvdW5kIGNhbiBhZGQgbmV3IG5vZGVzIHRvIHRoZSBsaXN0CiAgICAgICAgICAgICAgICBmb3IgKERlZmVycmVkQXR0ck5vZGUgZGVmZXJyZWRBdHRyTm9kZSA6IExpc3QuZnJvbShkZWZlcnJlZEF0dHJOb2RlcykpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoZGVmZXJyZWRBdHRyTm9kZS5wcm9jZXNzKHRoaXMpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGRlZmVycmVkQXR0ck5vZGVzLnJlbW92ZShkZWZlcnJlZEF0dHJOb2RlKTsKICAgICAgICAgICAgICAgICAgICAgICAgcHJvZ3Jlc3MgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICghcHJvZ3Jlc3MpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoaW5zaWRlT3ZlcmxvYWRQaGFzZSgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoRGVmZXJyZWRBdHRyTm9kZSBkZWZlcnJlZE5vZGU6IGRlZmVycmVkQXR0ck5vZGVzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWZlcnJlZE5vZGUuZHQudHJlZS50eXBlID0gVHlwZS5ub1R5cGU7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAvL3JlbW92ZSBhbGwgdmFyaWFibGVzIHRoYXQgaGF2ZSBhbHJlYWR5IGJlZW4gaW5zdGFudGlhdGVkCiAgICAgICAgICAgICAgICAgICAgLy9mcm9tIHRoZSBsaXN0IG9mIHN0dWNrIHZhcmlhYmxlcwogICAgICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vZmluZCBzdHVjayBleHByZXNzaW9uIHRvIHVuc3R1Y2sKICAgICAgICAgICAgICAgICAgICAgICAgRGVmZXJyZWRBdHRyTm9kZSB0b1Vuc3R1Y2sgPSBwaWNrRGVmZXJyZWROb2RlKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGluZmVyZW5jZUNvbnRleHQuc29sdmVBbnkoTGlzdC5mcm9tKHRvVW5zdHVjay5kZWZlcnJlZFN0dWNrUG9saWN5LnN0dWNrVmFycygpKSwgd2Fybik7CiAgICAgICAgICAgICAgICAgICAgICAgIGluZmVyZW5jZUNvbnRleHQubm90aWZ5Q2hhbmdlKCk7CiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoSW5mZXIuR3JhcGhTdHJhdGVneS5Ob2RlTm90Rm91bmRFeGNlcHRpb24gZXgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy90aGlzIG1lYW5zIHRoYXQgd2UgYXJlIGluIHNwZWN1bGF0aXZlIG1vZGUgYW5kIHRoZQogICAgICAgICAgICAgICAgICAgICAgICAvL3NldCBvZiBjb250cmFpbnRzIGFyZSB0b28gdGlnaHQgZm9yIHByb2dlc3MgdG8gYmUgbWFkZS4KICAgICAgICAgICAgICAgICAgICAgICAgLy9KdXN0IGxlYXZlIHRoZSByZW1haW5pbmcgZXhwcmVzc2lvbnMgYXMgc3R1Y2suCiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHVibGljIGJvb2xlYW4gaW5zaWRlT3ZlcmxvYWRQaGFzZSgpIHsKICAgICAgICAgICAgRGVmZXJyZWRBdHRyQ29udGV4dCBkYWMgPSB0aGlzOwogICAgICAgICAgICBpZiAoZGFjID09IGVtcHR5RGVmZXJyZWRBdHRyQ29udGV4dCkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChkYWMubW9kZSA9PSBBdHRyTW9kZS5TUEVDVUxBVElWRSkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGRhYy5wYXJlbnQuaW5zaWRlT3ZlcmxvYWRQaGFzZSgpOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogUGljayB0aGUgZGVmZXJyZWQgbm9kZSB0byBiZSB1bnN0dWNrLiBUaGUgY2hvc2VuIG5vZGUgaXMgdGhlIGZpcnN0IHN0cm9uZ2x5IGNvbm5lY3RlZAogICAgICAgICAqIGNvbXBvbmVudCBjb250YWluaW5nIGV4YWN0bHkgb25lIG5vZGUgZm91bmQgaW4gdGhlIGRlcGVuZGVuY3kgZ3JhcGggaW5kdWNlZCBieSBkZWZlcnJlZCBub2Rlcy4KICAgICAgICAgKiBJZiBubyBzdWNoIGNvbXBvbmVudCBpcyBmb3VuZCwgdGhlIGZpcnN0IGRlZmVycmVkIG5vZGUgaXMgcmV0dXJuZWQuCiAgICAgICAgICovCiAgICAgICAgRGVmZXJyZWRBdHRyTm9kZSBwaWNrRGVmZXJyZWROb2RlKCkgewogICAgICAgICAgICBMaXN0PFN0dWNrTm9kZT4gbm9kZXMgPSBkZWZlcnJlZEF0dHJOb2Rlcy5zdHJlYW0oKQogICAgICAgICAgICAgICAgICAgIC5tYXAoU3R1Y2tOb2RlOjpuZXcpCiAgICAgICAgICAgICAgICAgICAgLmNvbGxlY3QoTGlzdC5jb2xsZWN0b3IoKSk7CiAgICAgICAgICAgIC8vaW5pdCBzdHVjayBleHByZXNzaW9uIGdyYXBoOyBhIGRlZmVycmVkIG5vZGUgQSBkZXBlbmRzIG9uIGEgZGVmZXJyZWQgbm9kZSBCIGlmZgogICAgICAgICAgICAvL3RoZSBpbnRlcnNlY3Rpb24gYmV0d2VlbiBBJ3MgaW5wdXQgdmFyaWFibGUgYW5kIEIncyBvdXRwdXQgdmFyaWFibGUgaXMgbm9uLWVtcHR5LgogICAgICAgICAgICBmb3IgKFN0dWNrTm9kZSBzbjEgOiBub2RlcykgewogICAgICAgICAgICAgICAgZm9yIChUeXBlIHQgOiBzbjEuZGF0YS5kZWZlcnJlZFN0dWNrUG9saWN5LnN0dWNrVmFycygpKSB7CiAgICAgICAgICAgICAgICAgICAgZm9yIChTdHVja05vZGUgc24yIDogbm9kZXMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNuMSAhPSBzbjIgJiYgc24yLmRhdGEuZGVmZXJyZWRTdHVja1BvbGljeS5kZXBWYXJzKCkuY29udGFpbnModCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNuMS5kZXBzLmFkZChzbjIpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vY29tcHV0ZSB0YXJqYW4gb24gdGhlIHN0dWNrIGdyYXBoCiAgICAgICAgICAgIExpc3Q8PyBleHRlbmRzIFN0dWNrTm9kZT4gY3NuID0gR3JhcGhVdGlscy50YXJqYW4obm9kZXMpLmdldCgwKTsKICAgICAgICAgICAgcmV0dXJuIGNzbi5sZW5ndGgoKSA9PSAxID8gY3NuLmdldCgwKS5kYXRhIDogZGVmZXJyZWRBdHRyTm9kZXMuZ2V0KDApOwogICAgICAgIH0KCiAgICAgICAgY2xhc3MgU3R1Y2tOb2RlIGV4dGVuZHMgR3JhcGhVdGlscy5UYXJqYW5Ob2RlPERlZmVycmVkQXR0ck5vZGUsIFN0dWNrTm9kZT4gewoKICAgICAgICAgICAgU2V0PFN0dWNrTm9kZT4gZGVwcyA9IG5ldyBIYXNoU2V0PD4oKTsKCiAgICAgICAgICAgIFN0dWNrTm9kZShEZWZlcnJlZEF0dHJOb2RlIGRhdGEpIHsKICAgICAgICAgICAgICAgIHN1cGVyKGRhdGEpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHVibGljIERlcGVuZGVuY3lLaW5kW10gZ2V0U3VwcG9ydGVkRGVwZW5kZW5jeUtpbmRzKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBEZXBlbmRlbmN5S2luZFtdIHsgSW5mZXIuRGVwZW5kZW5jeUtpbmQuU1RVQ0sgfTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHB1YmxpYyBDb2xsZWN0aW9uPD8gZXh0ZW5kcyBTdHVja05vZGU+IGdldERlcGVuZGVuY2llc0J5S2luZChEZXBlbmRlbmN5S2luZCBkaykgewogICAgICAgICAgICAgICAgaWYgKGRrID09IEluZmVyLkRlcGVuZGVuY3lLaW5kLlNUVUNLKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRlcHM7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHB1YmxpYyBJdGVyYWJsZTw/IGV4dGVuZHMgU3R1Y2tOb2RlPiBnZXRBbGxEZXBlbmRlbmNpZXMoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZGVwczsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIENsYXNzIHJlcHJlc2VudGluZyBhIGRlZmVycmVkIGF0dHJpYnV0aW9uIG5vZGUuIEl0IGtlZXBzIHRyYWNrIG9mCiAgICAgKiBhIGRlZmVycmVkIHR5cGUsIGFsb25nIHdpdGggdGhlIGV4cGVjdGVkIHRhcmdldCB0eXBlIGluZm9ybWF0aW9uLgogICAgICovCiAgICBjbGFzcyBEZWZlcnJlZEF0dHJOb2RlIHsKCiAgICAgICAgLyoqIHVuZGVybHlpbmcgZGVmZXJyZWQgdHlwZSAqLwogICAgICAgIERlZmVycmVkVHlwZSBkdDsKCiAgICAgICAgLyoqIHVuZGVybHlpbmcgdGFyZ2V0IHR5cGUgaW5mb3JtYXRpb24gKi8KICAgICAgICBSZXN1bHRJbmZvIHJlc3VsdEluZm87CgogICAgICAgIC8qKiBzdHVjayBwb2xpY3kgYXNzb2NpYXRlZCB3aXRoIHRoaXMgbm9kZSAqLwogICAgICAgIERlZmVycmVkU3R1Y2tQb2xpY3kgZGVmZXJyZWRTdHVja1BvbGljeTsKCiAgICAgICAgRGVmZXJyZWRBdHRyTm9kZShEZWZlcnJlZFR5cGUgZHQsIFJlc3VsdEluZm8gcmVzdWx0SW5mbywgRGVmZXJyZWRTdHVja1BvbGljeSBkZWZlcnJlZFN0dWNrUG9saWN5KSB7CiAgICAgICAgICAgIHRoaXMuZHQgPSBkdDsKICAgICAgICAgICAgdGhpcy5yZXN1bHRJbmZvID0gcmVzdWx0SW5mbzsKICAgICAgICAgICAgdGhpcy5kZWZlcnJlZFN0dWNrUG9saWN5ID0gZGVmZXJyZWRTdHVja1BvbGljeTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIFByb2Nlc3MgYSBkZWZlcnJlZCBhdHRyaWJ1dGlvbiBub2RlLgogICAgICAgICAqIEludmFyaWFudDogYSBzdHVjayBub2RlIGNhbm5vdCBiZSBwcm9jZXNzZWQuCiAgICAgICAgICovCiAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoImZhbGx0aHJvdWdoIikKICAgICAgICBib29sZWFuIHByb2Nlc3MoZmluYWwgRGVmZXJyZWRBdHRyQ29udGV4dCBkZWZlcnJlZEF0dHJDb250ZXh0KSB7CiAgICAgICAgICAgIHN3aXRjaCAoZGVmZXJyZWRBdHRyQ29udGV4dC5tb2RlKSB7CiAgICAgICAgICAgICAgICBjYXNlIFNQRUNVTEFUSVZFOgogICAgICAgICAgICAgICAgICAgIGlmIChkZWZlcnJlZFN0dWNrUG9saWN5LmlzU3R1Y2soKSkgewogICAgICAgICAgICAgICAgICAgICAgICBkdC5jaGVjayhyZXN1bHRJbmZvLCBkdW1teVN0dWNrUG9saWN5LCBuZXcgU3RydWN0dXJhbFN0dWNrQ2hlY2tlcigpKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgQXNzZXJ0LmVycm9yKCJDYW5ub3QgZ2V0IGhlcmUiKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBjYXNlIENIRUNLOgogICAgICAgICAgICAgICAgICAgIGlmIChkZWZlcnJlZFN0dWNrUG9saWN5LmlzU3R1Y2soKSkgewogICAgICAgICAgICAgICAgICAgICAgICAvL3N0dWNrIGV4cHJlc3Npb24gLSBzZWUgaWYgd2UgY2FuIHByb3BhZ2F0ZQogICAgICAgICAgICAgICAgICAgICAgICBpZiAoZGVmZXJyZWRBdHRyQ29udGV4dC5wYXJlbnQgIT0gZW1wdHlEZWZlcnJlZEF0dHJDb250ZXh0ICYmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVHlwZS5jb250YWluc0FueShkZWZlcnJlZEF0dHJDb250ZXh0LnBhcmVudC5pbmZlcmVuY2VDb250ZXh0LmluZmVyZW5jZXZhcnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0LmZyb20oZGVmZXJyZWRTdHVja1BvbGljeS5zdHVja1ZhcnMoKSkpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWZlcnJlZEF0dHJDb250ZXh0LnBhcmVudC5hZGREZWZlcnJlZEF0dHJOb2RlKGR0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHRJbmZvLmR1cChuZXcgQ2hlY2suTmVzdGVkQ2hlY2tDb250ZXh0KHJlc3VsdEluZm8uY2hlY2tDb250ZXh0KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHVibGljIEluZmVyZW5jZUNvbnRleHQgaW5mZXJlbmNlQ29udGV4dCgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRlZmVycmVkQXR0ckNvbnRleHQucGFyZW50LmluZmVyZW5jZUNvbnRleHQ7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHB1YmxpYyBEZWZlcnJlZEF0dHJDb250ZXh0IGRlZmVycmVkQXR0ckNvbnRleHQoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBkZWZlcnJlZEF0dHJDb250ZXh0LnBhcmVudDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KSwgZGVmZXJyZWRTdHVja1BvbGljeSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkdC50cmVlLnR5cGUgPSBUeXBlLnN0dWNrVHlwZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgQXNzZXJ0LmNoZWNrKCFkZWZlcnJlZEF0dHJDb250ZXh0Lmluc2lkZU92ZXJsb2FkUGhhc2UoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiYXR0cmlidXRpb24gc2hvdWxkbid0IGJlIGhhcHBlbmluZyBoZXJlIik7CiAgICAgICAgICAgICAgICAgICAgICAgIFJlc3VsdEluZm8gaW5zdFJlc3VsdEluZm8gPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdEluZm8uZHVwKGRlZmVycmVkQXR0ckNvbnRleHQuaW5mZXJlbmNlQ29udGV4dC5hc0luc3RUeXBlKHJlc3VsdEluZm8ucHQpKTsKICAgICAgICAgICAgICAgICAgICAgICAgZHQuY2hlY2soaW5zdFJlc3VsdEluZm8sIGR1bW15U3R1Y2tQb2xpY3ksIGJhc2ljQ29tcGxldGVyKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoIkJhZCBtb2RlIik7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIFN0cnVjdHVyYWwgY2hlY2tlciBmb3Igc3R1Y2sgZXhwcmVzc2lvbnMKICAgICAgICAgKi8KICAgICAgICBjbGFzcyBTdHJ1Y3R1cmFsU3R1Y2tDaGVja2VyIGV4dGVuZHMgVHJlZVNjYW5uZXIgaW1wbGVtZW50cyBEZWZlcnJlZFR5cGVDb21wbGV0ZXIgewoKICAgICAgICAgICAgUmVzdWx0SW5mbyByZXN1bHRJbmZvOwogICAgICAgICAgICBJbmZlcmVuY2VDb250ZXh0IGluZmVyZW5jZUNvbnRleHQ7CiAgICAgICAgICAgIEVudjxBdHRyQ29udGV4dD4gZW52OwoKICAgICAgICAgICAgcHVibGljIFR5cGUgY29tcGxldGUoRGVmZXJyZWRUeXBlIGR0LCBSZXN1bHRJbmZvIHJlc3VsdEluZm8sIERlZmVycmVkQXR0ckNvbnRleHQgZGVmZXJyZWRBdHRyQ29udGV4dCkgewogICAgICAgICAgICAgICAgdGhpcy5yZXN1bHRJbmZvID0gcmVzdWx0SW5mbzsKICAgICAgICAgICAgICAgIHRoaXMuaW5mZXJlbmNlQ29udGV4dCA9IGRlZmVycmVkQXR0ckNvbnRleHQuaW5mZXJlbmNlQ29udGV4dDsKICAgICAgICAgICAgICAgIHRoaXMuZW52ID0gZHQuZW52OwogICAgICAgICAgICAgICAgZHQudHJlZS5hY2NlcHQodGhpcyk7CiAgICAgICAgICAgICAgICBkdC5zcGVjdWxhdGl2ZUNhY2hlLnB1dChzdHVja1RyZWUsIHJlc3VsdEluZm8pOwogICAgICAgICAgICAgICAgcmV0dXJuIFR5cGUubm9UeXBlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHVibGljIHZvaWQgdmlzaXRMYW1iZGEoSkNMYW1iZGEgdHJlZSkgewogICAgICAgICAgICAgICAgQ2hlY2suQ2hlY2tDb250ZXh0IGNoZWNrQ29udGV4dCA9IHJlc3VsdEluZm8uY2hlY2tDb250ZXh0OwogICAgICAgICAgICAgICAgVHlwZSBwdCA9IHJlc3VsdEluZm8ucHQ7CiAgICAgICAgICAgICAgICBpZiAoIWluZmVyZW5jZUNvbnRleHQuaW5mZXJlbmNldmFycy5jb250YWlucyhwdCkpIHsKICAgICAgICAgICAgICAgICAgICAvL211c3QgYmUgYSBmdW5jdGlvbmFsIGRlc2NyaXB0b3IKICAgICAgICAgICAgICAgICAgICBUeXBlIGRlc2NyaXB0b3JUeXBlID0gbnVsbDsKICAgICAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdG9yVHlwZSA9IHR5cGVzLmZpbmREZXNjcmlwdG9yVHlwZShwdCk7CiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoVHlwZXMuRnVuY3Rpb25EZXNjcmlwdG9yTG9va3VwRXJyb3IgZXgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tDb250ZXh0LnJlcG9ydChudWxsLCBleC5nZXREaWFnbm9zdGljKCkpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgaWYgKGRlc2NyaXB0b3JUeXBlLmdldFBhcmFtZXRlclR5cGVzKCkubGVuZ3RoKCkgIT0gdHJlZS5wYXJhbXMubGVuZ3RoKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tDb250ZXh0LnJlcG9ydCh0cmVlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpYWdzLmZyYWdtZW50KCJpbmNvbXBhdGlibGUuYXJnLnR5cGVzLmluLmxhbWJkYSIpKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIFR5cGUgY3VycmVudFJldHVyblR5cGUgPSBkZXNjcmlwdG9yVHlwZS5nZXRSZXR1cm5UeXBlKCk7CiAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiByZXR1cm5UeXBlSXNWb2lkID0gY3VycmVudFJldHVyblR5cGUuaGFzVGFnKFZPSUQpOwogICAgICAgICAgICAgICAgICAgIGlmICh0cmVlLmdldEJvZHlLaW5kKCkgPT0gQm9keUtpbmQuRVhQUkVTU0lPTikgewogICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGlzRXhwcmVzc2lvbkNvbXBhdGlibGUgPSAhcmV0dXJuVHlwZUlzVm9pZCB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgVHJlZUluZm8uaXNFeHByZXNzaW9uU3RhdGVtZW50KChKQ0V4cHJlc3Npb24pdHJlZS5nZXRCb2R5KCkpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWlzRXhwcmVzc2lvbkNvbXBhdGlibGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdEluZm8uY2hlY2tDb250ZXh0LnJlcG9ydCh0cmVlLnBvcygpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpYWdzLmZyYWdtZW50KCJpbmNvbXBhdGlibGUucmV0LnR5cGUuaW4ubGFtYmRhIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlhZ3MuZnJhZ21lbnQoIm1pc3NpbmcucmV0LnZhbCIsIGN1cnJlbnRSZXR1cm5UeXBlKSkpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgTGFtYmRhQm9keVN0cnVjdENoZWNrZXIgbGFtYmRhQm9keUNoZWNrZXIgPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBMYW1iZGFCb2R5U3RydWN0Q2hlY2tlcigpOwoKICAgICAgICAgICAgICAgICAgICAgICAgdHJlZS5ib2R5LmFjY2VwdChsYW1iZGFCb2R5Q2hlY2tlcik7CiAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gaXNWb2lkQ29tcGF0aWJsZSA9IGxhbWJkYUJvZHlDaGVja2VyLmlzVm9pZENvbXBhdGlibGU7CgogICAgICAgICAgICAgICAgICAgICAgICBpZiAocmV0dXJuVHlwZUlzVm9pZCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFpc1ZvaWRDb21wYXRpYmxlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0SW5mby5jaGVja0NvbnRleHQucmVwb3J0KHRyZWUucG9zKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpYWdzLmZyYWdtZW50KCJ1bmV4cGVjdGVkLnJldC52YWwiKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGlzVmFsdWVDb21wYXRpYmxlID0gbGFtYmRhQm9keUNoZWNrZXIuaXNQb3RlbnRpYWxseVZhbHVlQ29tcGF0aWJsZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICYmICFjYW5MYW1iZGFCb2R5Q29tcGxldGVOb3JtYWxseSh0cmVlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghaXNWYWx1ZUNvbXBhdGlibGUgJiYgIWlzVm9pZENvbXBhdGlibGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2cuZXJyb3IodHJlZS5ib2R5LnBvcygpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAibGFtYmRhLmJvZHkubmVpdGhlci52YWx1ZS5ub3Iudm9pZC5jb21wYXRpYmxlIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFpc1ZhbHVlQ29tcGF0aWJsZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdEluZm8uY2hlY2tDb250ZXh0LnJlcG9ydCh0cmVlLnBvcygpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaWFncy5mcmFnbWVudCgiaW5jb21wYXRpYmxlLnJldC50eXBlLmluLmxhbWJkYSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaWFncy5mcmFnbWVudCgibWlzc2luZy5yZXQudmFsIiwgY3VycmVudFJldHVyblR5cGUpKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGJvb2xlYW4gY2FuTGFtYmRhQm9keUNvbXBsZXRlTm9ybWFsbHkoSkNMYW1iZGEgdHJlZSkgewogICAgICAgICAgICAgICAgTGlzdDxKQ1ZhcmlhYmxlRGVjbD4gb2xkUGFyYW1zID0gdHJlZS5wYXJhbXM7CiAgICAgICAgICAgICAgICBMb2NhbENhY2hlQ29udGV4dCBsb2NhbENhY2hlQ29udGV4dCA9IGFyZ3VtZW50QXR0ci53aXRoTG9jYWxDYWNoZUNvbnRleHQoKTsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgdHJlZS5wYXJhbXMgPSB0cmVlLnBhcmFtcy5zdHJlYW0oKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgLm1hcCh2ZCAtPiBtYWtlLlZhckRlZih2ZC5tb2RzLCB2ZC5uYW1lLCBtYWtlLkVycm9uZW91cygpLCBudWxsKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jb2xsZWN0KExpc3QuY29sbGVjdG9yKCkpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBhdHRyaWJTcGVjdWxhdGl2ZUxhbWJkYSh0cmVlLCBlbnYsIGF0dHIudW5rbm93bkV4cHJJbmZvKS5jYW5Db21wbGV0ZU5vcm1hbGx5OwogICAgICAgICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgICAgICAgICBsb2NhbENhY2hlQ29udGV4dC5sZWF2ZSgpOwogICAgICAgICAgICAgICAgICAgIHRyZWUucGFyYW1zID0gb2xkUGFyYW1zOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHVibGljIHZvaWQgdmlzaXROZXdDbGFzcyhKQ05ld0NsYXNzIHRyZWUpIHsKICAgICAgICAgICAgICAgIC8vZG8gbm90aGluZwogICAgICAgICAgICB9CgogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHVibGljIHZvaWQgdmlzaXRBcHBseShKQ01ldGhvZEludm9jYXRpb24gdHJlZSkgewogICAgICAgICAgICAgICAgLy9kbyBub3RoaW5nCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdFJlZmVyZW5jZShKQ01lbWJlclJlZmVyZW5jZSB0cmVlKSB7CiAgICAgICAgICAgICAgICBDaGVjay5DaGVja0NvbnRleHQgY2hlY2tDb250ZXh0ID0gcmVzdWx0SW5mby5jaGVja0NvbnRleHQ7CiAgICAgICAgICAgICAgICBUeXBlIHB0ID0gcmVzdWx0SW5mby5wdDsKICAgICAgICAgICAgICAgIGlmICghaW5mZXJlbmNlQ29udGV4dC5pbmZlcmVuY2V2YXJzLmNvbnRhaW5zKHB0KSkgewogICAgICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVzLmZpbmREZXNjcmlwdG9yVHlwZShwdCk7CiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoVHlwZXMuRnVuY3Rpb25EZXNjcmlwdG9yTG9va3VwRXJyb3IgZXgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tDb250ZXh0LnJlcG9ydChudWxsLCBleC5nZXREaWFnbm9zdGljKCkpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBFbnY8QXR0ckNvbnRleHQ+IGxvY2FsRW52ID0gZW52LmR1cCh0cmVlKTsKICAgICAgICAgICAgICAgICAgICBKQ0V4cHJlc3Npb24gZXhwclRyZWUgPSAoSkNFeHByZXNzaW9uKWF0dHJpYlNwZWN1bGF0aXZlKHRyZWUuZ2V0UXVhbGlmaWVyRXhwcmVzc2lvbigpLCBsb2NhbEVudiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHIubWVtYmVyUmVmZXJlbmNlUXVhbGlmaWVyUmVzdWx0KHRyZWUpKTsKICAgICAgICAgICAgICAgICAgICBMaXN0QnVmZmVyPFR5cGU+IGFyZ3R5cGVzID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgICAgICAgICAgICAgIGZvciAoVHlwZSB0IDogdHlwZXMuZmluZERlc2NyaXB0b3JUeXBlKHB0KS5nZXRQYXJhbWV0ZXJUeXBlcygpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGFyZ3R5cGVzLmFwcGVuZChUeXBlLm5vVHlwZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIEpDTWVtYmVyUmVmZXJlbmNlIG1yZWYyID0gbmV3IFRyZWVDb3BpZXI8Vm9pZD4obWFrZSkuY29weSh0cmVlKTsKICAgICAgICAgICAgICAgICAgICBtcmVmMi5leHByID0gZXhwclRyZWU7CiAgICAgICAgICAgICAgICAgICAgU3ltYm9sIGxvb2t1cFN5bSA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBycy5yZXNvbHZlTWVtYmVyUmVmZXJlbmNlKGxvY2FsRW52LCBtcmVmMiwgZXhwclRyZWUudHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJlZS5uYW1lLCBhcmd0eXBlcy50b0xpc3QoKSwgTGlzdC5uaWwoKSwgcnMuYXJpdHlNZXRob2RDaGVjaywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5mZXJlbmNlQ29udGV4dCwgcnMuc3RydWN0dXJhbFJlZmVyZW5jZUNob29zZXIpLmZzdDsKICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKGxvb2t1cFN5bS5raW5kKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgV1JPTkdfTVRIOgogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFdST05HX01USFM6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL25vdGU6IGFzIGFyZ3R5cGVzIGFyZSBlcnJvbmVvdXMgdHlwZXMsIHR5cGUtZXJyb3JzIG11c3QKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vaGF2ZSBiZWVuIGNhdXNlZCBieSBhcml0eSBtaXNtYXRjaAogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tDb250ZXh0LnJlcG9ydCh0cmVlLCBkaWFncy5mcmFnbWVudChGcmFnbWVudHMuSW5jb21wYXRpYmxlQXJnVHlwZXNJbk1yZWYpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIEFCU0VOVF9NVEg6CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgU1RBVElDRVJSOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9pZiBubyBtZXRob2QgZm91bmQsIG9yIG1ldGhvZCBmb3VuZCB3aXRoIHdyb25nIHN0YXRpY25lc3MsIHJlcG9ydCBiZXR0ZXIgbWVzc2FnZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tDb250ZXh0LnJlcG9ydCh0cmVlLCAoKFJlc29sdmVFcnJvcilsb29rdXBTeW0pLmdldERpYWdub3N0aWMoRGlhZ25vc3RpY1R5cGUuRlJBR01FTlQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyZWUsIGV4cHJUcmVlLnR5cGUudHN5bSwgZXhwclRyZWUudHlwZSwgdHJlZS5uYW1lLCBhcmd0eXBlcy50b0xpc3QoKSwgTGlzdC5uaWwoKSkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvKiBUaGlzIHZpc2l0b3IgbG9va3MgZm9yIHJldHVybiBzdGF0ZW1lbnRzLCBpdHMgYW5hbHlzaXMgd2lsbCBkZXRlcm1pbmUgaWYKICAgICAgICAgKiBhIGxhbWJkYSBib2R5IGlzIHZvaWQgb3IgdmFsdWUgY29tcGF0aWJsZS4gV2UgbXVzdCBhbmFseXplIHJldHVybgogICAgICAgICAqIHN0YXRlbWVudHMgY29udGFpbmVkIGluIHRoZSBsYW1iZGEgYm9keSBvbmx5LCB0aHVzIGFueSByZXR1cm4gc3RhdGVtZW50CiAgICAgICAgICogY29udGFpbmVkIGluIGFuIGlubmVyIGNsYXNzIG9yIGlubmVyIGxhbWJkYSBib2R5LCBzaG91bGQgYmUgaWdub3JlZC4KICAgICAgICAgKi8KICAgICAgICBjbGFzcyBMYW1iZGFCb2R5U3RydWN0Q2hlY2tlciBleHRlbmRzIFRyZWVTY2FubmVyIHsKICAgICAgICAgICAgYm9vbGVhbiBpc1ZvaWRDb21wYXRpYmxlID0gdHJ1ZTsKICAgICAgICAgICAgYm9vbGVhbiBpc1BvdGVudGlhbGx5VmFsdWVDb21wYXRpYmxlID0gdHJ1ZTsKCiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdENsYXNzRGVmKEpDQ2xhc3NEZWNsIHRyZWUpIHsKICAgICAgICAgICAgICAgIC8vIGRvIG5vdGhpbmcKICAgICAgICAgICAgfQoKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0TGFtYmRhKEpDTGFtYmRhIHRyZWUpIHsKICAgICAgICAgICAgICAgIC8vIGRvIG5vdGhpbmcKICAgICAgICAgICAgfQoKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0TmV3Q2xhc3MoSkNOZXdDbGFzcyB0cmVlKSB7CiAgICAgICAgICAgICAgICAvLyBkbyBub3RoaW5nCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdFJldHVybihKQ1JldHVybiB0cmVlKSB7CiAgICAgICAgICAgICAgICBpZiAodHJlZS5leHByICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICBpc1ZvaWRDb21wYXRpYmxlID0gZmFsc2U7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGlzUG90ZW50aWFsbHlWYWx1ZUNvbXBhdGlibGUgPSBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKiogYW4gZW1wdHkgZGVmZXJyZWQgYXR0cmlidXRpb24gY29udGV4dCAtIGFsbCBtZXRob2RzIHRocm93IGV4Y2VwdGlvbnMgKi8KICAgIGZpbmFsIERlZmVycmVkQXR0ckNvbnRleHQgZW1wdHlEZWZlcnJlZEF0dHJDb250ZXh0OwoKICAgIC8qKgogICAgICogTWFwIGEgbGlzdCBvZiB0eXBlcyBwb3NzaWJseSBjb250YWluaW5nIG9uZSBvciBtb3JlIGRlZmVycmVkIHR5cGVzCiAgICAgKiBpbnRvIGEgbGlzdCBvZiBvcmRpbmFyeSB0eXBlcy4gRWFjaCBkZWZlcnJlZCB0eXBlIEQgaXMgbWFwcGVkIGludG8gYSB0eXBlIFQsCiAgICAgKiB3aGVyZSBUIGlzIGNvbXB1dGVkIGJ5IHJldHJpZXZpbmcgdGhlIHR5cGUgdGhhdCBoYXMgYWxyZWFkeSBiZWVuCiAgICAgKiBjb21wdXRlZCBmb3IgRCBkdXJpbmcgYSBwcmV2aW91cyBkZWZlcnJlZCBhdHRyaWJ1dGlvbiByb3VuZCBvZiB0aGUgZ2l2ZW4ga2luZC4KICAgICAqLwogICAgY2xhc3MgRGVmZXJyZWRUeXBlTWFwIGV4dGVuZHMgU3RydWN0dXJhbFR5cGVNYXBwaW5nPFZvaWQ+IHsKICAgICAgICBEZWZlcnJlZEF0dHJDb250ZXh0IGRlZmVycmVkQXR0ckNvbnRleHQ7CgogICAgICAgIHByb3RlY3RlZCBEZWZlcnJlZFR5cGVNYXAoQXR0ck1vZGUgbW9kZSwgU3ltYm9sIG1zeW0sIE1ldGhvZFJlc29sdXRpb25QaGFzZSBwaGFzZSkgewogICAgICAgICAgICB0aGlzLmRlZmVycmVkQXR0ckNvbnRleHQgPSBuZXcgRGVmZXJyZWRBdHRyQ29udGV4dChtb2RlLCBtc3ltLCBwaGFzZSwKICAgICAgICAgICAgICAgICAgICBpbmZlci5lbXB0eUNvbnRleHQsIGVtcHR5RGVmZXJyZWRBdHRyQ29udGV4dCwgdHlwZXMubm9XYXJuaW5ncyk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgVHlwZSB2aXNpdFR5cGUoVHlwZSB0LCBWb2lkIF91bnVzZWQpIHsKICAgICAgICAgICAgaWYgKCF0Lmhhc1RhZyhERUZFUlJFRCkpIHsKICAgICAgICAgICAgICAgIHJldHVybiBzdXBlci52aXNpdFR5cGUodCwgbnVsbCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBEZWZlcnJlZFR5cGUgZHQgPSAoRGVmZXJyZWRUeXBlKXQ7CiAgICAgICAgICAgICAgICByZXR1cm4gdHlwZU9mKGR0KTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHJvdGVjdGVkIFR5cGUgdHlwZU9mKERlZmVycmVkVHlwZSBkdCkgewogICAgICAgICAgICBzd2l0Y2ggKGRlZmVycmVkQXR0ckNvbnRleHQubW9kZSkgewogICAgICAgICAgICAgICAgY2FzZSBDSEVDSzoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZHQudHJlZS50eXBlID09IG51bGwgPyBUeXBlLm5vVHlwZSA6IGR0LnRyZWUudHlwZTsKICAgICAgICAgICAgICAgIGNhc2UgU1BFQ1VMQVRJVkU6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGR0LnNwZWN1bGF0aXZlVHlwZShkZWZlcnJlZEF0dHJDb250ZXh0Lm1zeW0sIGRlZmVycmVkQXR0ckNvbnRleHQucGhhc2UpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIEFzc2VydC5lcnJvcigpOwogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBTcGVjaWFsaXplZCByZWNvdmVyeSBkZWZlcnJlZCBtYXBwaW5nLgogICAgICogRWFjaCBkZWZlcnJlZCB0eXBlIEQgaXMgbWFwcGVkIGludG8gYSB0eXBlIFQsIHdoZXJlIFQgaXMgY29tcHV0ZWQgZWl0aGVyIGJ5CiAgICAgKiAoaSkgcmV0cmlldmluZyB0aGUgdHlwZSB0aGF0IGhhcyBhbHJlYWR5IGJlZW4gY29tcHV0ZWQgZm9yIEQgZHVyaW5nIGEgcHJldmlvdXMKICAgICAqIGF0dHJpYnV0aW9uIHJvdW5kIChhcyBiZWZvcmUpLCBvciAoaWkpIGJ5IHN5bnRoZXNpemluZyBhIG5ldyB0eXBlIFIgZm9yIEQKICAgICAqICh0aGUgbGF0dGVyIHN0ZXAgaXMgdXNlZnVsIGluIGEgcmVjb3Zlcnkgc2NlbmFyaW8pLgogICAgICovCiAgICBwdWJsaWMgY2xhc3MgUmVjb3ZlcnlEZWZlcnJlZFR5cGVNYXAgZXh0ZW5kcyBEZWZlcnJlZFR5cGVNYXAgewoKICAgICAgICBwdWJsaWMgUmVjb3ZlcnlEZWZlcnJlZFR5cGVNYXAoQXR0ck1vZGUgbW9kZSwgU3ltYm9sIG1zeW0sIE1ldGhvZFJlc29sdXRpb25QaGFzZSBwaGFzZSkgewogICAgICAgICAgICBzdXBlcihtb2RlLCBtc3ltLCBwaGFzZSAhPSBudWxsID8gcGhhc2UgOiBNZXRob2RSZXNvbHV0aW9uUGhhc2UuQk9YKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHByb3RlY3RlZCBUeXBlIHR5cGVPZihEZWZlcnJlZFR5cGUgZHQpIHsKICAgICAgICAgICAgVHlwZSBvd250eXBlID0gc3VwZXIudHlwZU9mKGR0KTsKICAgICAgICAgICAgcmV0dXJuIG93bnR5cGUgPT0gVHlwZS5ub1R5cGUgPwogICAgICAgICAgICAgICAgICAgICAgICByZWNvdmVyKGR0KSA6IG93bnR5cGU7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBTeW50aGVzaXplIGEgdHlwZSBmb3IgYSBkZWZlcnJlZCB0eXBlIHRoYXQgaGFzbid0IGJlZW4gcHJldmlvdXNseQogICAgICAgICAqIHJlZHVjZWQgdG8gYW4gb3JkaW5hcnkgdHlwZS4gRnVuY3Rpb25hbCBkZWZlcnJlZCB0eXBlcyBhbmQgY29uZGl0aW9uYWxzCiAgICAgICAgICogYXJlIG1hcHBlZCB0byB0aGVtc2VsdmVzLCBpbiBvcmRlciB0byBoYXZlIGEgcmljaGVyIGRpYWdub3N0aWMKICAgICAgICAgKiByZXByZXNlbnRhdGlvbi4gUmVtYWluaW5nIGRlZmVycmVkIHR5cGVzIGFyZSBhdHRyaWJ1dGVkIHVzaW5nCiAgICAgICAgICogYSBkZWZhdWx0IGV4cGVjdGVkIHR5cGUgKGoubC5PYmplY3QpLgogICAgICAgICAqLwogICAgICAgIHByaXZhdGUgVHlwZSByZWNvdmVyKERlZmVycmVkVHlwZSBkdCkgewogICAgICAgICAgICBkdC5jaGVjayhhdHRyLm5ldyBSZWNvdmVyeUluZm8oZGVmZXJyZWRBdHRyQ29udGV4dCkgewogICAgICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgICAgICBwcm90ZWN0ZWQgVHlwZSBjaGVjayhEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBUeXBlIGZvdW5kKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNoay5jaGVja05vblZvaWQocG9zLCBzdXBlci5jaGVjayhwb3MsIGZvdW5kKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0pOwogICAgICAgICAgICByZXR1cm4gc3VwZXIudmlzaXQoZHQpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEEgc3BlY2lhbCB0cmVlIHNjYW5uZXIgdGhhdCB3b3VsZCBvbmx5IHZpc2l0IHBvcnRpb25zIG9mIGEgZ2l2ZW4gdHJlZS4KICAgICAqIFRoZSBzZXQgb2Ygbm9kZXMgdmlzaXRlZCBieSB0aGUgc2Nhbm5lciBjYW4gYmUgY3VzdG9taXplZCBhdCBjb25zdHJ1Y3Rpb24tdGltZS4KICAgICAqLwogICAgYWJzdHJhY3Qgc3RhdGljIGNsYXNzIEZpbHRlclNjYW5uZXIgZXh0ZW5kcyBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuVHJlZVNjYW5uZXIgewoKICAgICAgICBmaW5hbCBGaWx0ZXI8SkNUcmVlPiB0cmVlRmlsdGVyOwoKICAgICAgICBGaWx0ZXJTY2FubmVyKGZpbmFsIFNldDxKQ1RyZWUuVGFnPiB2YWxpZFRhZ3MpIHsKICAgICAgICAgICAgdGhpcy50cmVlRmlsdGVyID0gdCAtPiB2YWxpZFRhZ3MuY29udGFpbnModC5nZXRUYWcoKSk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCBzY2FuKEpDVHJlZSB0cmVlKSB7CiAgICAgICAgICAgIGlmICh0cmVlICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIGlmICh0cmVlRmlsdGVyLmFjY2VwdHModHJlZSkpIHsKICAgICAgICAgICAgICAgICAgICBzdXBlci5zY2FuKHRyZWUpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBza2lwKHRyZWUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBoYW5kbGVyIHRoYXQgaXMgZXhlY3V0ZWQgd2hlbiBhIG5vZGUgaGFzIGJlZW4gZGlzY2FyZGVkCiAgICAgICAgICovCiAgICAgICAgdm9pZCBza2lwKEpDVHJlZSB0cmVlKSB7fQogICAgfQoKICAgIC8qKgogICAgICogQSB0cmVlIHNjYW5uZXIgc3VpdGFibGUgZm9yIHZpc2l0aW5nIHRoZSB0YXJnZXQtdHlwZSBkZXBlbmRlbnQgbm9kZXMgb2YKICAgICAqIGEgZ2l2ZW4gYXJndW1lbnQgZXhwcmVzc2lvbi4KICAgICAqLwogICAgc3RhdGljIGNsYXNzIFBvbHlTY2FubmVyIGV4dGVuZHMgRmlsdGVyU2Nhbm5lciB7CgogICAgICAgIFBvbHlTY2FubmVyKCkgewogICAgICAgICAgICBzdXBlcihFbnVtU2V0Lm9mKENPTkRFWFBSLCBQQVJFTlMsIExBTUJEQSwgUkVGRVJFTkNFKSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQSB0cmVlIHNjYW5uZXIgc3VpdGFibGUgZm9yIHZpc2l0aW5nIHRoZSB0YXJnZXQtdHlwZSBkZXBlbmRlbnQgbm9kZXMgbmVzdGVkCiAgICAgKiB3aXRoaW4gYSBsYW1iZGEgZXhwcmVzc2lvbiBib2R5LgogICAgICovCiAgICBzdGF0aWMgY2xhc3MgTGFtYmRhUmV0dXJuU2Nhbm5lciBleHRlbmRzIEZpbHRlclNjYW5uZXIgewoKICAgICAgICBMYW1iZGFSZXR1cm5TY2FubmVyKCkgewogICAgICAgICAgICBzdXBlcihFbnVtU2V0Lm9mKEJMT0NLLCBDQVNFLCBDQVRDSCwgRE9MT09QLCBGT1JFQUNITE9PUCwKICAgICAgICAgICAgICAgICAgICBGT1JMT09QLCBJRiwgUkVUVVJOLCBTWU5DSFJPTklaRUQsIFNXSVRDSCwgVFJZLCBXSElMRUxPT1ApKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBUaGlzIHZpc2l0b3IgaXMgdXNlZCB0byBjaGVjayB0aGF0IHN0cnVjdHVyYWwgZXhwcmVzc2lvbnMgY29uZm9ybQogICAgICogdG8gdGhlaXIgdGFyZ2V0IC0gdGhpcyBzdGVwIGlzIHJlcXVpcmVkIGFzIGluZmVyZW5jZSBjb3VsZCBlbmQgdXAKICAgICAqIGluZmVycmluZyB0eXBlcyB0aGF0IG1ha2Ugc29tZSBvZiB0aGUgbmVzdGVkIGV4cHJlc3Npb25zIGluY29tcGF0aWJsZQogICAgICogd2l0aCB0aGVpciBjb3JyZXNwb25kaW5nIGluc3RhbnRpYXRlZCB0YXJnZXQKICAgICAqLwogICAgY2xhc3MgQ2hlY2tTdHVja1BvbGljeSBleHRlbmRzIFBvbHlTY2FubmVyIGltcGxlbWVudHMgRGVmZXJyZWRTdHVja1BvbGljeSwgSW5mZXIuRnJlZVR5cGVMaXN0ZW5lciB7CgogICAgICAgIFR5cGUgcHQ7CiAgICAgICAgSW5mZXJlbmNlQ29udGV4dCBpbmZlcmVuY2VDb250ZXh0OwogICAgICAgIFNldDxUeXBlPiBzdHVja1ZhcnMgPSBuZXcgTGlua2VkSGFzaFNldDw+KCk7CiAgICAgICAgU2V0PFR5cGU+IGRlcFZhcnMgPSBuZXcgTGlua2VkSGFzaFNldDw+KCk7CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBib29sZWFuIGlzU3R1Y2soKSB7CiAgICAgICAgICAgIHJldHVybiAhc3R1Y2tWYXJzLmlzRW1wdHkoKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBTZXQ8VHlwZT4gc3R1Y2tWYXJzKCkgewogICAgICAgICAgICByZXR1cm4gc3R1Y2tWYXJzOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFNldDxUeXBlPiBkZXBWYXJzKCkgewogICAgICAgICAgICByZXR1cm4gZGVwVmFyczsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBDaGVja1N0dWNrUG9saWN5KFJlc3VsdEluZm8gcmVzdWx0SW5mbywgRGVmZXJyZWRUeXBlIGR0KSB7CiAgICAgICAgICAgIHRoaXMucHQgPSByZXN1bHRJbmZvLnB0OwogICAgICAgICAgICB0aGlzLmluZmVyZW5jZUNvbnRleHQgPSByZXN1bHRJbmZvLmNoZWNrQ29udGV4dC5pbmZlcmVuY2VDb250ZXh0KCk7CiAgICAgICAgICAgIHNjYW4oZHQudHJlZSk7CiAgICAgICAgICAgIGlmICghc3R1Y2tWYXJzLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgICAgcmVzdWx0SW5mby5jaGVja0NvbnRleHQuaW5mZXJlbmNlQ29udGV4dCgpCiAgICAgICAgICAgICAgICAgICAgICAgIC5hZGRGcmVlVHlwZUxpc3RlbmVyKExpc3QuZnJvbShzdHVja1ZhcnMpLCB0aGlzKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgdHlwZXNJbmZlcnJlZChJbmZlcmVuY2VDb250ZXh0IGluZmVyZW5jZUNvbnRleHQpIHsKICAgICAgICAgICAgc3R1Y2tWYXJzLmNsZWFyKCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdExhbWJkYShKQ0xhbWJkYSB0cmVlKSB7CiAgICAgICAgICAgIGlmIChpbmZlcmVuY2VDb250ZXh0LmluZmVyZW5jZVZhcnMoKS5jb250YWlucyhwdCkpIHsKICAgICAgICAgICAgICAgIHN0dWNrVmFycy5hZGQocHQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICghdHlwZXMuaXNGdW5jdGlvbmFsSW50ZXJmYWNlKHB0KSkgewogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CiAgICAgICAgICAgIFR5cGUgZGVzY1R5cGUgPSB0eXBlcy5maW5kRGVzY3JpcHRvclR5cGUocHQpOwogICAgICAgICAgICBMaXN0PFR5cGU+IGZyZWVBcmdWYXJzID0gaW5mZXJlbmNlQ29udGV4dC5mcmVlVmFyc0luKGRlc2NUeXBlLmdldFBhcmFtZXRlclR5cGVzKCkpOwogICAgICAgICAgICBpZiAodHJlZS5wYXJhbUtpbmQgPT0gSkNMYW1iZGEuUGFyYW1ldGVyS2luZC5JTVBMSUNJVCAmJgogICAgICAgICAgICAgICAgICAgIGZyZWVBcmdWYXJzLm5vbkVtcHR5KCkpIHsKICAgICAgICAgICAgICAgIHN0dWNrVmFycy5hZGRBbGwoZnJlZUFyZ1ZhcnMpOwogICAgICAgICAgICAgICAgZGVwVmFycy5hZGRBbGwoaW5mZXJlbmNlQ29udGV4dC5mcmVlVmFyc0luKGRlc2NUeXBlLmdldFJldHVyblR5cGUoKSkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHNjYW5MYW1iZGFCb2R5KHRyZWUsIGRlc2NUeXBlLmdldFJldHVyblR5cGUoKSk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdFJlZmVyZW5jZShKQ01lbWJlclJlZmVyZW5jZSB0cmVlKSB7CiAgICAgICAgICAgIHNjYW4odHJlZS5leHByKTsKICAgICAgICAgICAgaWYgKGluZmVyZW5jZUNvbnRleHQuaW5mZXJlbmNlVmFycygpLmNvbnRhaW5zKHB0KSkgewogICAgICAgICAgICAgICAgc3R1Y2tWYXJzLmFkZChwdCk7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCF0eXBlcy5pc0Z1bmN0aW9uYWxJbnRlcmZhY2UocHQpKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIFR5cGUgZGVzY1R5cGUgPSB0eXBlcy5maW5kRGVzY3JpcHRvclR5cGUocHQpOwogICAgICAgICAgICBMaXN0PFR5cGU+IGZyZWVBcmdWYXJzID0gaW5mZXJlbmNlQ29udGV4dC5mcmVlVmFyc0luKGRlc2NUeXBlLmdldFBhcmFtZXRlclR5cGVzKCkpOwogICAgICAgICAgICBpZiAoZnJlZUFyZ1ZhcnMubm9uRW1wdHkoKSAmJgogICAgICAgICAgICAgICAgICAgIHRyZWUub3ZlcmxvYWRLaW5kID09IEpDTWVtYmVyUmVmZXJlbmNlLk92ZXJsb2FkS2luZC5PVkVSTE9BREVEKSB7CiAgICAgICAgICAgICAgICBzdHVja1ZhcnMuYWRkQWxsKGZyZWVBcmdWYXJzKTsKICAgICAgICAgICAgICAgIGRlcFZhcnMuYWRkQWxsKGluZmVyZW5jZUNvbnRleHQuZnJlZVZhcnNJbihkZXNjVHlwZS5nZXRSZXR1cm5UeXBlKCkpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgdm9pZCBzY2FuTGFtYmRhQm9keShKQ0xhbWJkYSBsYW1iZGEsIGZpbmFsIFR5cGUgcHQpIHsKICAgICAgICAgICAgaWYgKGxhbWJkYS5nZXRCb2R5S2luZCgpID09IEpDVHJlZS5KQ0xhbWJkYS5Cb2R5S2luZC5FWFBSRVNTSU9OKSB7CiAgICAgICAgICAgICAgICBUeXBlIHByZXZQdCA9IHRoaXMucHQ7CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIHRoaXMucHQgPSBwdDsKICAgICAgICAgICAgICAgICAgICBzY2FuKGxhbWJkYS5ib2R5KTsKICAgICAgICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5wdCA9IHByZXZQdDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIExhbWJkYVJldHVyblNjYW5uZXIgbGFtYmRhU2Nhbm5lciA9IG5ldyBMYW1iZGFSZXR1cm5TY2FubmVyKCkgewogICAgICAgICAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICAgICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0UmV0dXJuKEpDUmV0dXJuIHRyZWUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRyZWUuZXhwciAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBUeXBlIHByZXZQdCA9IENoZWNrU3R1Y2tQb2xpY3kudGhpcy5wdDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2hlY2tTdHVja1BvbGljeS50aGlzLnB0ID0gcHQ7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2hlY2tTdHVja1BvbGljeS50aGlzLnNjYW4odHJlZS5leHByKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2hlY2tTdHVja1BvbGljeS50aGlzLnB0ID0gcHJldlB0OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgICAgIGxhbWJkYVNjYW5uZXIuc2NhbihsYW1iZGEuYm9keSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBUaGlzIHZpc2l0b3IgaXMgdXNlZCB0byBjaGVjayB0aGF0IHN0cnVjdHVyYWwgZXhwcmVzc2lvbnMgY29uZm9ybQogICAgICogdG8gdGhlaXIgdGFyZ2V0IC0gdGhpcyBzdGVwIGlzIHJlcXVpcmVkIGFzIGluZmVyZW5jZSBjb3VsZCBlbmQgdXAKICAgICAqIGluZmVycmluZyB0eXBlcyB0aGF0IG1ha2Ugc29tZSBvZiB0aGUgbmVzdGVkIGV4cHJlc3Npb25zIGluY29tcGF0aWJsZQogICAgICogd2l0aCB0aGVpciBjb3JyZXNwb25kaW5nIGluc3RhbnRpYXRlZCB0YXJnZXQKICAgICAqLwogICAgY2xhc3MgT3ZlcmxvYWRTdHVja1BvbGljeSBleHRlbmRzIENoZWNrU3R1Y2tQb2xpY3kgaW1wbGVtZW50cyBEZWZlcnJlZFN0dWNrUG9saWN5IHsKCiAgICAgICAgYm9vbGVhbiBzdHVjazsKCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gaXNTdHVjaygpIHsKICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmlzU3R1Y2soKSB8fCBzdHVjazsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBPdmVybG9hZFN0dWNrUG9saWN5KFJlc3VsdEluZm8gcmVzdWx0SW5mbywgRGVmZXJyZWRUeXBlIGR0KSB7CiAgICAgICAgICAgIHN1cGVyKHJlc3VsdEluZm8sIGR0KTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0TGFtYmRhKEpDTGFtYmRhIHRyZWUpIHsKICAgICAgICAgICAgc3VwZXIudmlzaXRMYW1iZGEodHJlZSk7CiAgICAgICAgICAgIGlmICh0cmVlLnBhcmFtS2luZCA9PSBKQ0xhbWJkYS5QYXJhbWV0ZXJLaW5kLklNUExJQ0lUKSB7CiAgICAgICAgICAgICAgICBzdHVjayA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0UmVmZXJlbmNlKEpDTWVtYmVyUmVmZXJlbmNlIHRyZWUpIHsKICAgICAgICAgICAgc3VwZXIudmlzaXRSZWZlcmVuY2UodHJlZSk7CiAgICAgICAgICAgIGlmICh0cmVlLm92ZXJsb2FkS2luZCA9PSBKQ01lbWJlclJlZmVyZW5jZS5PdmVybG9hZEtpbmQuT1ZFUkxPQURFRCkgewogICAgICAgICAgICAgICAgc3R1Y2sgPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQp9ClBLAwQKAAAIAAAGO6lKdYYLSRyfAQAcnwEAIgAAAGNvbS9zdW4vdG9vbHMvamF2YWMvY29tcC9GbG93LmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDE5OTksIDIwMTUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCi8vdG9kbzogb25lIG1pZ2h0IGVsaW1pbmF0ZSB1bmluaXRzLmFuZFNldHMgd2hlbiBtb25vdG9uaWMKCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhYy5jb21wOwoKaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOwoKaW1wb3J0IGNvbS5zdW4uc291cmNlLnRyZWUuTGFtYmRhRXhwcmVzc2lvblRyZWUuQm9keUtpbmQ7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuKjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5TY29wZS5Xcml0ZWFibGVTY29wZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS4qOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLio7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuSkNEaWFnbm9zdGljLkRpYWdub3N0aWNQb3NpdGlvbjsKCmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuU3ltYm9sLio7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuSkNUcmVlLio7CgppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5GbGFncy4qOwppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5GbGFncy5CTE9DSzsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuS2luZHMuS2luZC4qOwppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5UeXBlVGFnLkJPT0xFQU47CmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlR5cGVUYWcuVk9JRDsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuSkNUcmVlLlRhZy4qOwoKLyoqIFRoaXMgcGFzcyBpbXBsZW1lbnRzIGRhdGFmbG93IGFuYWx5c2lzIGZvciBKYXZhIHByb2dyYW1zIHRob3VnaAogKiAgZGlmZmVyZW50IEFTVCB2aXNpdG9yIHN0ZXBzLiBMaXZlbmVzcyBhbmFseXNpcyAoc2VlIEFsaXZlQW5hbHl6ZXIpIGNoZWNrcyB0aGF0CiAqICBldmVyeSBzdGF0ZW1lbnQgaXMgcmVhY2hhYmxlLiBFeGNlcHRpb24gYW5hbHlzaXMgKHNlZSBGbG93QW5hbHl6ZXIpIGVuc3VyZXMgdGhhdAogKiAgZXZlcnkgY2hlY2tlZCBleGNlcHRpb24gdGhhdCBpcyB0aHJvd24gaXMgZGVjbGFyZWQgb3IgY2F1Z2h0LiAgRGVmaW5pdGUgYXNzaWdubWVudCBhbmFseXNpcwogKiAgKHNlZSBBc3NpZ25BbmFseXplcikgZW5zdXJlcyB0aGF0IGVhY2ggdmFyaWFibGUgaXMgYXNzaWduZWQgd2hlbiB1c2VkLiAgRGVmaW5pdGUKICogIHVuYXNzaWdubWVudCBhbmFseXNpcyAoc2VlIEFzc2lnbkFuYWx5emVyKSBpbiBlbnN1cmVzIHRoYXQgbm8gZmluYWwgdmFyaWFibGUKICogIGlzIGFzc2lnbmVkIG1vcmUgdGhhbiBvbmNlLiBGaW5hbGx5LCBsb2NhbCB2YXJpYWJsZSBjYXB0dXJlIGFuYWx5c2lzIChzZWUgQ2FwdHVyZUFuYWx5emVyKQogKiAgZGV0ZXJtaW5lcyB0aGF0IGxvY2FsIHZhcmlhYmxlcyBhY2Nlc3NlZCB3aXRoaW4gdGhlIHNjb3BlIG9mIGFuIGlubmVyIGNsYXNzL2xhbWJkYQogKiAgYXJlIGVpdGhlciBmaW5hbCBvciBlZmZlY3RpdmVseS1maW5hbC4KICoKICogIDxwPlRoZSBKTFMgaGFzIGEgbnVtYmVyIG9mIHByb2JsZW1zIGluIHRoZQogKiAgc3BlY2lmaWNhdGlvbiBvZiB0aGVzZSBmbG93IGFuYWx5c2lzIHByb2JsZW1zLiBUaGlzIGltcGxlbWVudGF0aW9uCiAqICBhdHRlbXB0cyB0byBhZGRyZXNzIHRob3NlIGlzc3Vlcy4KICoKICogIDxwPkZpcnN0LCB0aGVyZSBpcyBubyBhY2NvbW1vZGF0aW9uIGZvciBhIGZpbmFsbHkgY2xhdXNlIHRoYXQgY2Fubm90CiAqICBjb21wbGV0ZSBub3JtYWxseS4gRm9yIGxpdmVuZXNzIGFuYWx5c2lzLCBhbiBpbnRlcnZlbmluZyBmaW5hbGx5CiAqICBjbGF1c2UgY2FuIGNhdXNlIGEgYnJlYWssIGNvbnRpbnVlLCBvciByZXR1cm4gbm90IHRvIHJlYWNoIGl0cwogKiAgdGFyZ2V0LiAgRm9yIGV4Y2VwdGlvbiBhbmFseXNpcywgYW4gaW50ZXJ2ZW5pbmcgZmluYWxseSBjbGF1c2UgY2FuCiAqICBjYXVzZSBhbnkgZXhjZXB0aW9uIHRvIGJlICJjYXVnaHQiLiAgRm9yIERBL0RVIGFuYWx5c2lzLCB0aGUgZmluYWxseQogKiAgY2xhdXNlIGNhbiBwcmV2ZW50IGEgdHJhbnNmZXIgb2YgY29udHJvbCBmcm9tIHByb3BhZ2F0aW5nIERBL0RVCiAqICBzdGF0ZSB0byB0aGUgdGFyZ2V0LiAgSW4gYWRkaXRpb24sIGNvZGUgaW4gdGhlIGZpbmFsbHkgY2xhdXNlIGNhbgogKiAgYWZmZWN0IHRoZSBEQS9EVSBzdGF0dXMgb2YgdmFyaWFibGVzLgogKgogKiAgPHA+Rm9yIHRyeSBzdGF0ZW1lbnRzLCB3ZSBpbnRyb2R1Y2UgdGhlIGlkZWEgb2YgYSB2YXJpYWJsZSBiZWluZwogKiAgZGVmaW5pdGVseSB1bmFzc2lnbmVkICJldmVyeXdoZXJlIiBpbiBhIGJsb2NrLiAgQSB2YXJpYWJsZSBWIGlzCiAqICAidW5hc3NpZ25lZCBldmVyeXdoZXJlIiBpbiBhIGJsb2NrIGlmZiBpdCBpcyB1bmFzc2lnbmVkIGF0IHRoZQogKiAgYmVnaW5uaW5nIG9mIHRoZSBibG9jayBhbmQgdGhlcmUgaXMgbm8gcmVhY2hhYmxlIGFzc2lnbm1lbnQgdG8gVgogKiAgaW4gdGhlIGJsb2NrLiAgQW4gYXNzaWdubWVudCBWPWUgaXMgcmVhY2hhYmxlIGlmZiBWIGlzIG5vdCBEQQogKiAgYWZ0ZXIgZS4gIFRoZW4gd2UgY2FuIHNheSB0aGF0IFYgaXMgRFUgYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUKICogIGNhdGNoIGJsb2NrIGlmZiBWIGlzIERVIGV2ZXJ5d2hlcmUgaW4gdGhlIHRyeSBibG9jay4gIFNpbWlsYXJseSwgVgogKiAgaXMgRFUgYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgZmluYWxseSBibG9jayBpZmYgViBpcyBEVSBldmVyeXdoZXJlCiAqICBpbiB0aGUgdHJ5IGJsb2NrIGFuZCBpbiBldmVyeSBjYXRjaCBibG9jay4gIFNwZWNpZmljYWxseSwgdGhlCiAqICBmb2xsb3dpbmcgYnVsbGV0IGlzIGFkZGVkIHRvIDE2LjIuMgogKiAgPHByZT4KICogICAgICBWIGlzIDxlbT51bmFzc2lnbmVkIGV2ZXJ5d2hlcmU8L2VtPiBpbiBhIGJsb2NrIGlmIGl0IGlzCiAqICAgICAgdW5hc3NpZ25lZCBiZWZvcmUgdGhlIGJsb2NrIGFuZCB0aGVyZSBpcyBubyByZWFjaGFibGUKICogICAgICBhc3NpZ25tZW50IHRvIFYgd2l0aGluIHRoZSBibG9jay4KICogIDwvcHJlPgogKiAgPHA+SW4gMTYuMi4xNSwgdGhlIHRoaXJkIGJ1bGxldCAoYW5kIGFsbCBvZiBpdHMgc3ViLWJ1bGxldHMpIGZvciBhbGwKICogIHRyeSBibG9ja3MgaXMgY2hhbmdlZCB0bwogKiAgPHByZT4KICogICAgICBWIGlzIGRlZmluaXRlbHkgdW5hc3NpZ25lZCBiZWZvcmUgYSBjYXRjaCBibG9jayBpZmYgViBpcwogKiAgICAgIGRlZmluaXRlbHkgdW5hc3NpZ25lZCBldmVyeXdoZXJlIGluIHRoZSB0cnkgYmxvY2suCiAqICA8L3ByZT4KICogIDxwPlRoZSBsYXN0IGJ1bGxldCAoYW5kIGFsbCBvZiBpdHMgc3ViLWJ1bGxldHMpIGZvciB0cnkgYmxvY2tzIHRoYXQKICogIGhhdmUgYSBmaW5hbGx5IGJsb2NrIGlzIGNoYW5nZWQgdG8KICogIDxwcmU+CiAqICAgICAgViBpcyBkZWZpbml0ZWx5IHVuYXNzaWduZWQgYmVmb3JlIHRoZSBmaW5hbGx5IGJsb2NrIGlmZgogKiAgICAgIFYgaXMgZGVmaW5pdGVseSB1bmFzc2lnbmVkIGV2ZXJ5d2hlcmUgaW4gdGhlIHRyeSBibG9jawogKiAgICAgIGFuZCBldmVyeXdoZXJlIGluIGVhY2ggY2F0Y2ggYmxvY2sgb2YgdGhlIHRyeSBzdGF0ZW1lbnQuCiAqICA8L3ByZT4KICogIDxwPkluIGFkZGl0aW9uLAogKiAgPHByZT4KICogICAgICBWIGlzIGRlZmluaXRlbHkgYXNzaWduZWQgYXQgdGhlIGVuZCBvZiBhIGNvbnN0cnVjdG9yIGlmZgogKiAgICAgIFYgaXMgZGVmaW5pdGVseSBhc3NpZ25lZCBhZnRlciB0aGUgYmxvY2sgdGhhdCBpcyB0aGUgYm9keQogKiAgICAgIG9mIHRoZSBjb25zdHJ1Y3RvciBhbmQgViBpcyBkZWZpbml0ZWx5IGFzc2lnbmVkIGF0IGV2ZXJ5CiAqICAgICAgcmV0dXJuIHRoYXQgY2FuIHJldHVybiBmcm9tIHRoZSBjb25zdHJ1Y3Rvci4KICogIDwvcHJlPgogKiAgPHA+SW4gYWRkaXRpb24sIGVhY2ggY29udGludWUgc3RhdGVtZW50IHdpdGggdGhlIGxvb3AgYXMgaXRzIHRhcmdldAogKiAgaXMgdHJlYXRlZCBhcyBhIGp1bXAgdG8gdGhlIGVuZCBvZiB0aGUgbG9vcCBib2R5LCBhbmQgImludGVydmVuaW5nIgogKiAgZmluYWxseSBjbGF1c2VzIGFyZSB0cmVhdGVkIGFzIGZvbGxvd3M6IFYgaXMgREEgImR1ZSB0byB0aGUKICogIGNvbnRpbnVlIiBpZmYgViBpcyBEQSBiZWZvcmUgdGhlIGNvbnRpbnVlIHN0YXRlbWVudCBvciBWIGlzIERBIGF0CiAqICB0aGUgZW5kIG9mIGFueSBpbnRlcnZlbmluZyBmaW5hbGx5IGJsb2NrLiAgViBpcyBEVSAiZHVlIHRvIHRoZQogKiAgY29udGludWUiIGlmZiBhbnkgaW50ZXJ2ZW5pbmcgZmluYWxseSBjYW5ub3QgY29tcGxldGUgbm9ybWFsbHkgb3IgVgogKiAgaXMgRFUgYXQgdGhlIGVuZCBvZiBldmVyeSBpbnRlcnZlbmluZyBmaW5hbGx5IGJsb2NrLiAgVGhpcyAiZHVlIHRvCiAqICB0aGUgY29udGludWUiIGNvbmNlcHQgaXMgdGhlbiB1c2VkIGluIHRoZSBzcGVjIGZvciB0aGUgbG9vcHMuCiAqCiAqICA8cD5TaW1pbGFybHksIGJyZWFrIHN0YXRlbWVudHMgbXVzdCBjb25zaWRlciBpbnRlcnZlbmluZyBmaW5hbGx5CiAqICBibG9ja3MuICBGb3IgbGl2ZW5lc3MgYW5hbHlzaXMsIGEgYnJlYWsgc3RhdGVtZW50IGZvciB3aGljaCBhbnkKICogIGludGVydmVuaW5nIGZpbmFsbHkgY2Fubm90IGNvbXBsZXRlIG5vcm1hbGx5IGlzIG5vdCBjb25zaWRlcmVkIHRvCiAqICBjYXVzZSB0aGUgdGFyZ2V0IHN0YXRlbWVudCB0byBiZSBhYmxlIHRvIGNvbXBsZXRlIG5vcm1hbGx5LiBUaGVuCiAqICB3ZSBzYXkgViBpcyBEQSAiZHVlIHRvIHRoZSBicmVhayIgaWZmIFYgaXMgREEgYmVmb3JlIHRoZSBicmVhayBvcgogKiAgViBpcyBEQSBhdCB0aGUgZW5kIG9mIGFueSBpbnRlcnZlbmluZyBmaW5hbGx5IGJsb2NrLiAgViBpcyBEVSAiZHVlCiAqICB0byB0aGUgYnJlYWsiIGlmZiBhbnkgaW50ZXJ2ZW5pbmcgZmluYWxseSBjYW5ub3QgY29tcGxldGUgbm9ybWFsbHkKICogIG9yIFYgaXMgRFUgYXQgdGhlIGJyZWFrIGFuZCBhdCB0aGUgZW5kIG9mIGV2ZXJ5IGludGVydmVuaW5nCiAqICBmaW5hbGx5IGJsb2NrLiAgKEkgc3VzcGVjdCB0aGlzIGxhdHRlciBjb25kaXRpb24gY2FuIGJlCiAqICBzaW1wbGlmaWVkLikgIFRoaXMgImR1ZSB0byB0aGUgYnJlYWsiIGlzIHRoZW4gdXNlZCBpbiB0aGUgc3BlYyBmb3IKICogIGFsbCBzdGF0ZW1lbnRzIHRoYXQgY2FuIGJlICJicm9rZW4iLgogKgogKiAgPHA+VGhlIHJldHVybiBzdGF0ZW1lbnQgaXMgdHJlYXRlZCBzaW1pbGFybHkuICBWIGlzIERBICJkdWUgdG8gYQogKiAgcmV0dXJuIHN0YXRlbWVudCIgaWZmIFYgaXMgREEgYmVmb3JlIHRoZSByZXR1cm4gc3RhdGVtZW50IG9yIFYgaXMKICogIERBIGF0IHRoZSBlbmQgb2YgYW55IGludGVydmVuaW5nIGZpbmFsbHkgYmxvY2suICBOb3RlIHRoYXQgd2UKICogIGRvbid0IGhhdmUgdG8gd29ycnkgYWJvdXQgdGhlIHJldHVybiBleHByZXNzaW9uIGJlY2F1c2UgdGhpcwogKiAgY29uY2VwdCBpcyBvbmx5IHVzZWQgZm9yIGNvbnN0cnVjcm9ycy4KICoKICogIDxwPlRoZXJlIGlzIG5vIHNwZWMgaW4gdGhlIEpMUyBmb3Igd2hlbiBhIHZhcmlhYmxlIGlzIGRlZmluaXRlbHkKICogIGFzc2lnbmVkIGF0IHRoZSBlbmQgb2YgYSBjb25zdHJ1Y3Rvciwgd2hpY2ggaXMgbmVlZGVkIGZvciBmaW5hbAogKiAgZmllbGRzICg4LjMuMS4yKS4gIFdlIGltcGxlbWVudCB0aGUgcnVsZSB0aGF0IFYgaXMgREEgYXQgdGhlIGVuZAogKiAgb2YgdGhlIGNvbnN0cnVjdG9yIGlmZiBpdCBpcyBEQSBhbmQgdGhlIGVuZCBvZiB0aGUgYm9keSBvZiB0aGUKICogIGNvbnN0cnVjdG9yIGFuZCBWIGlzIERBICJkdWUgdG8iIGV2ZXJ5IHJldHVybiBvZiB0aGUgY29uc3RydWN0b3IuCiAqCiAqICA8cD5JbnRlcnZlbmluZyBmaW5hbGx5IGJsb2NrcyBzaW1pbGFybHkgYWZmZWN0IGV4Y2VwdGlvbiBhbmFseXNpcy4gIEFuCiAqICBpbnRlcnZlbmluZyBmaW5hbGx5IHRoYXQgY2Fubm90IGNvbXBsZXRlIG5vcm1hbGx5IGFsbG93cyB1cyB0byBpZ25vcmUKICogIGFuIG90aGVyd2lzZSB1bmNhdWdodCBleGNlcHRpb24uCiAqCiAqICA8cD5UbyBpbXBsZW1lbnQgdGhlIHNlbWFudGljcyBvZiBpbnRlcnZlbmluZyBmaW5hbGx5IGNsYXVzZXMsIGFsbAogKiAgbm9ubG9jYWwgdHJhbnNmZXJzIChicmVhaywgY29udGludWUsIHJldHVybiwgdGhyb3csIG1ldGhvZCBjYWxsIHRoYXQKICogIGNhbiB0aHJvdyBhIGNoZWNrZWQgZXhjZXB0aW9uLCBhbmQgYSBjb25zdHJ1Y3RvciBpbnZvY2F0aW9uIHRoYXQgY2FuCiAqICB0aHJvd24gYSBjaGVja2VkIGV4Y2VwdGlvbikgYXJlIHJlY29yZGVkIGluIGEgcXVldWUsIGFuZCByZW1vdmVkCiAqICBmcm9tIHRoZSBxdWV1ZSB3aGVuIHdlIGNvbXBsZXRlIHByb2Nlc3NpbmcgdGhlIHRhcmdldCBvZiB0aGUKICogIG5vbmxvY2FsIHRyYW5zZmVyLiAgVGhpcyBhbGxvd3MgdXMgdG8gbW9kaWZ5IHRoZSBxdWV1ZSBpbiBhY2NvcmRhbmNlCiAqICB3aXRoIHRoZSBhYm92ZSBydWxlcyB3aGVuIHdlIGVuY291bnRlciBhIGZpbmFsbHkgY2xhdXNlLiAgVGhlIG9ubHkKICogIGV4Y2VwdGlvbiB0byB0aGlzIFtubyBwdW4gaW50ZW5kZWRdIGlzIHRoYXQgY2hlY2tlZCBleGNlcHRpb25zIHRoYXQKICogIGFyZSBrbm93biB0byBiZSBjYXVnaHQgb3IgZGVjbGFyZWQgdG8gYmUgY2F1Z2h0IGluIHRoZSBlbmNsb3NpbmcKICogIG1ldGhvZCBhcmUgbm90IHJlY29yZGVkIGluIHRoZSBxdWV1ZSwgYnV0IGluc3RlYWQgYXJlIHJlY29yZGVkIGluIGEKICogIGdsb2JhbCB2YXJpYWJsZSAie0Bjb2RlIFNldDxUeXBlPiB0aHJvd259IiB0aGF0IHJlY29yZHMgdGhlIHR5cGUgb2YgYWxsCiAqICBleGNlcHRpb25zIHRoYXQgY2FuIGJlIHRocm93bi4KICoKICogIDxwPk90aGVyIG1pbm9yIGlzc3VlcyB0aGUgdHJlYXRtZW50IG9mIG1lbWJlcnMgb2Ygb3RoZXIgY2xhc3NlcwogKiAgKGFsd2F5cyBjb25zaWRlcmVkIERBIGV4Y2VwdCB0aGF0IHdpdGhpbiBhbiBhbm9ueW1vdXMgY2xhc3MKICogIGNvbnN0cnVjdG9yLCB3aGVyZSBEQSBzdGF0dXMgZnJvbSB0aGUgZW5jbG9zaW5nIHNjb3BlIGlzCiAqICBwcmVzZXJ2ZWQpLCB0cmVhdG1lbnQgb2YgdGhlIGNhc2UgZXhwcmVzc2lvbiAoViBpcyBEQSBiZWZvcmUgdGhlCiAqICBjYXNlIGV4cHJlc3Npb24gaWZmIFYgaXMgREEgYWZ0ZXIgdGhlIHN3aXRjaCBleHByZXNzaW9uKSwKICogIHRyZWF0bWVudCBvZiB2YXJpYWJsZXMgZGVjbGFyZWQgaW4gYSBzd2l0Y2ggYmxvY2sgKHRoZSBpbXBsaWVkCiAqICBEQS9EVSBzdGF0dXMgYWZ0ZXIgdGhlIHN3aXRjaCBleHByZXNzaW9uIGlzIERVIGFuZCBub3QgREEgZm9yCiAqICB2YXJpYWJsZXMgZGVmaW5lZCBpbiBhIHN3aXRjaCBibG9jayksIHRoZSB0cmVhdG1lbnQgb2YgYm9vbGVhbiA/OgogKiAgZXhwcmVzc2lvbnMgKFRoZSBKTFMgcnVsZXMgb25seSBoYW5kbGUgYiBhbmQgYyBub24tYm9vbGVhbjsgdGhlCiAqICBuZXcgcnVsZSBpcyB0aGF0IGlmIGIgYW5kIGMgYXJlIGJvb2xlYW4gdmFsdWVkLCB0aGVuIFYgaXMKICogICh1bilhc3NpZ25lZCBhZnRlciBhP2I6YyB3aGVuIHRydWUvZmFsc2UgaWZmIFYgaXMgKHVuKWFzc2lnbmVkCiAqICBhZnRlciBiIHdoZW4gdHJ1ZS9mYWxzZSBhbmQgViBpcyAodW4pYXNzaWduZWQgYWZ0ZXIgYyB3aGVuCiAqICB0cnVlL2ZhbHNlKS4KICoKICogIDxwPlRoZXJlIGlzIHRoZSByZW1haW5pbmcgcXVlc3Rpb24gb2Ygd2hhdCBzeW50YWN0aWMgZm9ybXMgY29uc3RpdHV0ZSBhCiAqICByZWZlcmVuY2UgdG8gYSB2YXJpYWJsZS4gIEl0IGlzIGNvbnZlbnRpb25hbCB0byBhbGxvdyB0aGlzLnggb24gdGhlCiAqICBsZWZ0LWhhbmQtc2lkZSB0byBpbml0aWFsaXplIGEgZmluYWwgaW5zdGFuY2UgZmllbGQgbmFtZWQgeCwgeWV0CiAqICB0aGlzLnggaXNuJ3QgY29uc2lkZXJlZCBhICJ1c2UiIHdoZW4gYXBwZWFyaW5nIG9uIGEgcmlnaHQtaGFuZC1zaWRlCiAqICBpbiBtb3N0IGltcGxlbWVudGF0aW9ucy4gIFNob3VsZCBwYXJlbnRoZXNlcyBhZmZlY3Qgd2hhdCBpcwogKiAgY29uc2lkZXJlZCBhIHZhcmlhYmxlIHJlZmVyZW5jZT8gIFRoZSBzaW1wbGVzdCBydWxlIHdvdWxkIGJlIHRvCiAqICBhbGxvdyB1bnF1YWxpZmllZCBmb3JtcyBvbmx5LCBwYXJlbnRoZXNlcyBvcHRpb25hbCwgYW5kIHBoYXNlIG91dAogKiAgc3VwcG9ydCBmb3IgYXNzaWduaW5nIHRvIGEgZmluYWwgZmllbGQgdmlhIHRoaXMueC4KICoKICogIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqICBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqICBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogKiAgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPgogKi8KcHVibGljIGNsYXNzIEZsb3cgewogICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBDb250ZXh0LktleTxGbG93PiBmbG93S2V5ID0gbmV3IENvbnRleHQuS2V5PD4oKTsKCiAgICBwcml2YXRlIGZpbmFsIE5hbWVzIG5hbWVzOwogICAgcHJpdmF0ZSBmaW5hbCBMb2cgbG9nOwogICAgcHJpdmF0ZSBmaW5hbCBTeW10YWIgc3ltczsKICAgIHByaXZhdGUgZmluYWwgVHlwZXMgdHlwZXM7CiAgICBwcml2YXRlIGZpbmFsIENoZWNrIGNoazsKICAgIHByaXZhdGUgICAgICAgVHJlZU1ha2VyIG1ha2U7CiAgICBwcml2YXRlIGZpbmFsIFJlc29sdmUgcnM7CiAgICBwcml2YXRlIGZpbmFsIEpDRGlhZ25vc3RpYy5GYWN0b3J5IGRpYWdzOwogICAgcHJpdmF0ZSBFbnY8QXR0ckNvbnRleHQ+IGF0dHJFbnY7CiAgICBwcml2YXRlICAgICAgIExpbnQgbGludDsKICAgIHByaXZhdGUgZmluYWwgYm9vbGVhbiBhbGxvd0ltcHJvdmVkUmV0aHJvd0FuYWx5c2lzOwogICAgcHJpdmF0ZSBmaW5hbCBib29sZWFuIGFsbG93SW1wcm92ZWRDYXRjaEFuYWx5c2lzOwogICAgcHJpdmF0ZSBmaW5hbCBib29sZWFuIGFsbG93RWZmZWN0aXZlbHlGaW5hbEluSW5uZXJDbGFzc2VzOwogICAgcHJpdmF0ZSBmaW5hbCBib29sZWFuIGVuZm9yY2VUaGlzRG90SW5pdDsKCiAgICBwdWJsaWMgc3RhdGljIEZsb3cgaW5zdGFuY2UoQ29udGV4dCBjb250ZXh0KSB7CiAgICAgICAgRmxvdyBpbnN0YW5jZSA9IGNvbnRleHQuZ2V0KGZsb3dLZXkpOwogICAgICAgIGlmIChpbnN0YW5jZSA9PSBudWxsKQogICAgICAgICAgICBpbnN0YW5jZSA9IG5ldyBGbG93KGNvbnRleHQpOwogICAgICAgIHJldHVybiBpbnN0YW5jZTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCBhbmFseXplVHJlZShFbnY8QXR0ckNvbnRleHQ+IGVudiwgVHJlZU1ha2VyIG1ha2UpIHsKICAgICAgICBuZXcgQWxpdmVBbmFseXplcigpLmFuYWx5emVUcmVlKGVudiwgbWFrZSk7CiAgICAgICAgbmV3IEFzc2lnbkFuYWx5emVyKCkuYW5hbHl6ZVRyZWUoZW52KTsKICAgICAgICBuZXcgRmxvd0FuYWx5emVyKCkuYW5hbHl6ZVRyZWUoZW52LCBtYWtlKTsKICAgICAgICBuZXcgQ2FwdHVyZUFuYWx5emVyKCkuYW5hbHl6ZVRyZWUoZW52LCBtYWtlKTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCBhbmFseXplTGFtYmRhKEVudjxBdHRyQ29udGV4dD4gZW52LCBKQ0xhbWJkYSB0aGF0LCBUcmVlTWFrZXIgbWFrZSwgYm9vbGVhbiBzcGVjdWxhdGl2ZSkgewogICAgICAgIExvZy5EaWFnbm9zdGljSGFuZGxlciBkaWFnSGFuZGxlciA9IG51bGw7CiAgICAgICAgLy93ZSBuZWVkIHRvIGRpc2FibGUgZGlhZ25vc3RpY3MgdGVtcG9yYXJpbHk7IHRoZSBwcm9ibGVtIGlzIHRoYXQgaWYKICAgICAgICAvL2EgbGFtYmRhIGV4cHJlc3Npb24gY29udGFpbnMgZS5nLiBhbiB1bnJlYWNoYWJsZSBzdGF0ZW1lbnQsIGFuIGVycm9yCiAgICAgICAgLy9tZXNzYWdlIHdpbGwgYmUgcmVwb3J0ZWQgYW5kIHdpbGwgY2F1c2UgY29tcGlsYXRpb24gdG8gc2tpcCB0aGUgZmxvdyBhbmFseWlzCiAgICAgICAgLy9zdGVwIC0gaWYgd2Ugc3VwcHJlc3MgZGlhZ25vc3RpY3MsIHdlIHdvbid0IHN0b3AgYXQgQXR0ciBmb3IgZmxvdy1hbmFseXNpcwogICAgICAgIC8vcmVsYXRlZCBlcnJvcnMsIHdoaWNoIHdpbGwgYWxsb3cgZm9yIG1vcmUgZXJyb3JzIHRvIGJlIGRldGVjdGVkCiAgICAgICAgaWYgKCFzcGVjdWxhdGl2ZSkgewogICAgICAgICAgICBkaWFnSGFuZGxlciA9IG5ldyBMb2cuRGlzY2FyZERpYWdub3N0aWNIYW5kbGVyKGxvZyk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICAgIG5ldyBMYW1iZGFBbGl2ZUFuYWx5emVyKCkuYW5hbHl6ZVRyZWUoZW52LCB0aGF0LCBtYWtlKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICBpZiAoIXNwZWN1bGF0aXZlKSB7CiAgICAgICAgICAgICAgICBsb2cucG9wRGlhZ25vc3RpY0hhbmRsZXIoZGlhZ0hhbmRsZXIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBMaXN0PFR5cGU+IGFuYWx5emVMYW1iZGFUaHJvd25UeXBlcyhmaW5hbCBFbnY8QXR0ckNvbnRleHQ+IGVudiwKICAgICAgICAgICAgSkNMYW1iZGEgdGhhdCwgVHJlZU1ha2VyIG1ha2UpIHsKICAgICAgICAvL3dlIG5lZWQgdG8gZGlzYWJsZSBkaWFnbm9zdGljcyB0ZW1wb3JhcmlseTsgdGhlIHByb2JsZW0gaXMgdGhhdCBpZgogICAgICAgIC8vYSBsYW1iZGEgZXhwcmVzc2lvbiBjb250YWlucyBlLmcuIGFuIHVucmVhY2hhYmxlIHN0YXRlbWVudCwgYW4gZXJyb3IKICAgICAgICAvL21lc3NhZ2Ugd2lsbCBiZSByZXBvcnRlZCBhbmQgd2lsbCBjYXVzZSBjb21waWxhdGlvbiB0byBza2lwIHRoZSBmbG93IGFuYWx5aXMKICAgICAgICAvL3N0ZXAgLSBpZiB3ZSBzdXBwcmVzcyBkaWFnbm9zdGljcywgd2Ugd29uJ3Qgc3RvcCBhdCBBdHRyIGZvciBmbG93LWFuYWx5c2lzCiAgICAgICAgLy9yZWxhdGVkIGVycm9ycywgd2hpY2ggd2lsbCBhbGxvdyBmb3IgbW9yZSBlcnJvcnMgdG8gYmUgZGV0ZWN0ZWQKICAgICAgICBMb2cuRGlhZ25vc3RpY0hhbmRsZXIgZGlhZ0hhbmRsZXIgPSBuZXcgTG9nLkRpc2NhcmREaWFnbm9zdGljSGFuZGxlcihsb2cpOwogICAgICAgIHRyeSB7CiAgICAgICAgICAgIG5ldyBMYW1iZGFBc3NpZ25BbmFseXplcihlbnYpLmFuYWx5emVUcmVlKGVudiwgdGhhdCk7CiAgICAgICAgICAgIExhbWJkYUZsb3dBbmFseXplciBmbG93QW5hbHl6ZXIgPSBuZXcgTGFtYmRhRmxvd0FuYWx5emVyKCk7CiAgICAgICAgICAgIGZsb3dBbmFseXplci5hbmFseXplVHJlZShlbnYsIHRoYXQsIG1ha2UpOwogICAgICAgICAgICByZXR1cm4gZmxvd0FuYWx5emVyLmluZmVycmVkVGhyb3duVHlwZXM7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgbG9nLnBvcERpYWdub3N0aWNIYW5kbGVyKGRpYWdIYW5kbGVyKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBEZWZpbml0ZSBhc3NpZ25tZW50IHNjYW4gbW9kZQogICAgICovCiAgICBlbnVtIEZsb3dLaW5kIHsKICAgICAgICAvKioKICAgICAgICAgKiBUaGlzIGlzIHRoZSBub3JtYWwgREEvRFUgYW5hbHlzaXMgbW9kZQogICAgICAgICAqLwogICAgICAgIE5PUk1BTCgidmFyLm1pZ2h0LmFscmVhZHkuYmUuYXNzaWduZWQiLCBmYWxzZSksCiAgICAgICAgLyoqCiAgICAgICAgICogVGhpcyBpcyB0aGUgc3BlY3VsYXRpdmUgREEvRFUgYW5hbHlzaXMgbW9kZSB1c2VkIHRvIHNwZWN1bGF0aXZlbHkKICAgICAgICAgKiBkZXJpdmUgYXNzZXJ0aW9ucyB3aXRoaW4gbG9vcCBib2RpZXMKICAgICAgICAgKi8KICAgICAgICBTUEVDVUxBVElWRV9MT09QKCJ2YXIubWlnaHQuYmUuYXNzaWduZWQuaW4ubG9vcCIsIHRydWUpOwoKICAgICAgICBmaW5hbCBTdHJpbmcgZXJyS2V5OwogICAgICAgIGZpbmFsIGJvb2xlYW4gaXNGaW5hbDsKCiAgICAgICAgRmxvd0tpbmQoU3RyaW5nIGVycktleSwgYm9vbGVhbiBpc0ZpbmFsKSB7CiAgICAgICAgICAgIHRoaXMuZXJyS2V5ID0gZXJyS2V5OwogICAgICAgICAgICB0aGlzLmlzRmluYWwgPSBpc0ZpbmFsOwogICAgICAgIH0KCiAgICAgICAgYm9vbGVhbiBpc0ZpbmFsKCkgewogICAgICAgICAgICByZXR1cm4gaXNGaW5hbDsKICAgICAgICB9CiAgICB9CgogICAgcHJvdGVjdGVkIEZsb3coQ29udGV4dCBjb250ZXh0KSB7CiAgICAgICAgY29udGV4dC5wdXQoZmxvd0tleSwgdGhpcyk7CiAgICAgICAgbmFtZXMgPSBOYW1lcy5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBsb2cgPSBMb2cuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgc3ltcyA9IFN5bXRhYi5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICB0eXBlcyA9IFR5cGVzLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIGNoayA9IENoZWNrLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIGxpbnQgPSBMaW50Lmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIHJzID0gUmVzb2x2ZS5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBkaWFncyA9IEpDRGlhZ25vc3RpYy5GYWN0b3J5Lmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIFNvdXJjZSBzb3VyY2UgPSBTb3VyY2UuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgYWxsb3dJbXByb3ZlZFJldGhyb3dBbmFseXNpcyA9IHNvdXJjZS5hbGxvd0ltcHJvdmVkUmV0aHJvd0FuYWx5c2lzKCk7CiAgICAgICAgYWxsb3dJbXByb3ZlZENhdGNoQW5hbHlzaXMgPSBzb3VyY2UuYWxsb3dJbXByb3ZlZENhdGNoQW5hbHlzaXMoKTsKICAgICAgICBhbGxvd0VmZmVjdGl2ZWx5RmluYWxJbklubmVyQ2xhc3NlcyA9IHNvdXJjZS5hbGxvd0VmZmVjdGl2ZWx5RmluYWxJbklubmVyQ2xhc3NlcygpOwogICAgICAgIGVuZm9yY2VUaGlzRG90SW5pdCA9IHNvdXJjZS5lbmZvcmNlVGhpc0RvdEluaXQoKTsKICAgIH0KCiAgICAvKioKICAgICAqIEJhc2UgdmlzaXRvciBjbGFzcyBmb3IgYWxsIHZpc2l0b3JzIGltcGxlbWVudGluZyBkYXRhZmxvdyBhbmFseXNpcyBsb2dpYy4KICAgICAqIFRoaXMgY2xhc3MgZGVmaW5lIHRoZSBzaGFyZWQgbG9naWMgZm9yIGhhbmRsaW5nIGp1bXBzIChicmVhay9jb250aW51ZSBzdGF0ZW1lbnRzKS4KICAgICAqLwogICAgc3RhdGljIGFic3RyYWN0IGNsYXNzIEJhc2VBbmFseXplcjxQIGV4dGVuZHMgQmFzZUFuYWx5emVyLlBlbmRpbmdFeGl0PiBleHRlbmRzIFRyZWVTY2FubmVyIHsKCiAgICAgICAgZW51bSBKdW1wS2luZCB7CiAgICAgICAgICAgIEJSRUFLKEpDVHJlZS5UYWcuQlJFQUspIHsKICAgICAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICAgICAgSkNUcmVlIGdldFRhcmdldChKQ1RyZWUgdHJlZSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAoKEpDQnJlYWspdHJlZSkudGFyZ2V0OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAogICAgICAgICAgICBDT05USU5VRShKQ1RyZWUuVGFnLkNPTlRJTlVFKSB7CiAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgICAgIEpDVHJlZSBnZXRUYXJnZXQoSkNUcmVlIHRyZWUpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gKChKQ0NvbnRpbnVlKXRyZWUpLnRhcmdldDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKCiAgICAgICAgICAgIGZpbmFsIEpDVHJlZS5UYWcgdHJlZVRhZzsKCiAgICAgICAgICAgIHByaXZhdGUgSnVtcEtpbmQoVGFnIHRyZWVUYWcpIHsKICAgICAgICAgICAgICAgIHRoaXMudHJlZVRhZyA9IHRyZWVUYWc7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGFic3RyYWN0IEpDVHJlZSBnZXRUYXJnZXQoSkNUcmVlIHRyZWUpOwogICAgICAgIH0KCiAgICAgICAgLyoqIFRoZSBjdXJyZW50bHkgcGVuZGluZyBleGl0cyB0aGF0IGdvIGZyb20gY3VycmVudCBpbm5lciBibG9ja3MKICAgICAgICAgKiAgdG8gYW4gZW5jbG9zaW5nIGJsb2NrLCBpbiBzb3VyY2Ugb3JkZXIuCiAgICAgICAgICovCiAgICAgICAgTGlzdEJ1ZmZlcjxQPiBwZW5kaW5nRXhpdHM7CgogICAgICAgIC8qKiBBIHBlbmRpbmcgZXhpdC4gIFRoZXNlIGFyZSB0aGUgc3RhdGVtZW50cyByZXR1cm4sIGJyZWFrLCBhbmQKICAgICAgICAgKiAgY29udGludWUuICBJbiBhZGRpdGlvbiwgZXhjZXB0aW9uLXRocm93aW5nIGV4cHJlc3Npb25zIG9yCiAgICAgICAgICogIHN0YXRlbWVudHMgYXJlIHB1dCBoZXJlIHdoZW4gbm90IGtub3duIHRvIGJlIGNhdWdodC4gIFRoaXMKICAgICAgICAgKiAgd2lsbCB0eXBpY2FsbHkgcmVzdWx0IGluIGFuIGVycm9yIHVubGVzcyBpdCBpcyB3aXRoaW4gYQogICAgICAgICAqICB0cnktZmluYWxseSB3aG9zZSBmaW5hbGx5IGJsb2NrIGNhbm5vdCBjb21wbGV0ZSBub3JtYWxseS4KICAgICAgICAgKi8KICAgICAgICBzdGF0aWMgY2xhc3MgUGVuZGluZ0V4aXQgewogICAgICAgICAgICBKQ1RyZWUgdHJlZTsKCiAgICAgICAgICAgIFBlbmRpbmdFeGl0KEpDVHJlZSB0cmVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnRyZWUgPSB0cmVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2b2lkIHJlc29sdmVKdW1wKCkgewogICAgICAgICAgICAgICAgLy9kbyBub3RoaW5nCiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGFic3RyYWN0IHZvaWQgbWFya0RlYWQoKTsKCiAgICAgICAgLyoqIFJlY29yZCBhbiBvdXR3YXJkIHRyYW5zZmVyIG9mIGNvbnRyb2wuICovCiAgICAgICAgdm9pZCByZWNvcmRFeGl0KFAgcGUpIHsKICAgICAgICAgICAgcGVuZGluZ0V4aXRzLmFwcGVuZChwZSk7CiAgICAgICAgICAgIG1hcmtEZWFkKCk7CiAgICAgICAgfQoKICAgICAgICAvKiogUmVzb2x2ZSBhbGwganVtcHMgb2YgdGhpcyBzdGF0ZW1lbnQuICovCiAgICAgICAgcHJpdmF0ZSBib29sZWFuIHJlc29sdmVKdW1wKEpDVHJlZSB0cmVlLAogICAgICAgICAgICAgICAgICAgICAgICBMaXN0QnVmZmVyPFA+IG9sZFBlbmRpbmdFeGl0cywKICAgICAgICAgICAgICAgICAgICAgICAgSnVtcEtpbmQgamspIHsKICAgICAgICAgICAgYm9vbGVhbiByZXNvbHZlZCA9IGZhbHNlOwogICAgICAgICAgICBMaXN0PFA+IGV4aXRzID0gcGVuZGluZ0V4aXRzLnRvTGlzdCgpOwogICAgICAgICAgICBwZW5kaW5nRXhpdHMgPSBvbGRQZW5kaW5nRXhpdHM7CiAgICAgICAgICAgIGZvciAoOyBleGl0cy5ub25FbXB0eSgpOyBleGl0cyA9IGV4aXRzLnRhaWwpIHsKICAgICAgICAgICAgICAgIFAgZXhpdCA9IGV4aXRzLmhlYWQ7CiAgICAgICAgICAgICAgICBpZiAoZXhpdC50cmVlLmhhc1RhZyhqay50cmVlVGFnKSAmJgogICAgICAgICAgICAgICAgICAgICAgICBqay5nZXRUYXJnZXQoZXhpdC50cmVlKSA9PSB0cmVlKSB7CiAgICAgICAgICAgICAgICAgICAgZXhpdC5yZXNvbHZlSnVtcCgpOwogICAgICAgICAgICAgICAgICAgIHJlc29sdmVkID0gdHJ1ZTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgcGVuZGluZ0V4aXRzLmFwcGVuZChleGl0KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gcmVzb2x2ZWQ7CiAgICAgICAgfQoKICAgICAgICAvKiogUmVzb2x2ZSBhbGwgY29udGludWVzIG9mIHRoaXMgc3RhdGVtZW50LiAqLwogICAgICAgIGJvb2xlYW4gcmVzb2x2ZUNvbnRpbnVlcyhKQ1RyZWUgdHJlZSkgewogICAgICAgICAgICByZXR1cm4gcmVzb2x2ZUp1bXAodHJlZSwgbmV3IExpc3RCdWZmZXI8UD4oKSwgSnVtcEtpbmQuQ09OVElOVUUpOwogICAgICAgIH0KCiAgICAgICAgLyoqIFJlc29sdmUgYWxsIGJyZWFrcyBvZiB0aGlzIHN0YXRlbWVudC4gKi8KICAgICAgICBib29sZWFuIHJlc29sdmVCcmVha3MoSkNUcmVlIHRyZWUsIExpc3RCdWZmZXI8UD4gb2xkUGVuZGluZ0V4aXRzKSB7CiAgICAgICAgICAgIHJldHVybiByZXNvbHZlSnVtcCh0cmVlLCBvbGRQZW5kaW5nRXhpdHMsIEp1bXBLaW5kLkJSRUFLKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHNjYW4oSkNUcmVlIHRyZWUpIHsKICAgICAgICAgICAgaWYgKHRyZWUgIT0gbnVsbCAmJiAoCiAgICAgICAgICAgICAgICAgICAgdHJlZS50eXBlID09IG51bGwgfHwKICAgICAgICAgICAgICAgICAgICB0cmVlLnR5cGUgIT0gVHlwZS5zdHVja1R5cGUpKSB7CiAgICAgICAgICAgICAgICBzdXBlci5zY2FuKHRyZWUpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdFBhY2thZ2VEZWYoSkNQYWNrYWdlRGVjbCB0cmVlKSB7CiAgICAgICAgICAgIC8vIERvIG5vdGhpbmcgZm9yIFBhY2thZ2VEZWNsCiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogVGhpcyBwYXNzIGltcGxlbWVudHMgdGhlIGZpcnN0IHN0ZXAgb2YgdGhlIGRhdGFmbG93IGFuYWx5c2lzLCBuYW1lbHkKICAgICAqIHRoZSBsaXZlbmVzcyBhbmFseXNpcyBjaGVjay4gVGhpcyBjaGVja3MgdGhhdCBldmVyeSBzdGF0ZW1lbnQgaXMgcmVhY2hhYmxlLgogICAgICogVGhlIG91dHB1dCBvZiB0aGlzIGFuYWx5c2lzIHBhc3MgYXJlIHVzZWQgYnkgb3RoZXIgYW5hbHl6ZXJzLiBUaGlzIGFuYWx5emVyCiAgICAgKiBzZXRzIHRoZSAnZmluYWxseUNhbkNvbXBsZXRlTm9ybWFsbHknIGZpZWxkIGluIHRoZSBKQ1RyeSBjbGFzcy4KICAgICAqLwogICAgY2xhc3MgQWxpdmVBbmFseXplciBleHRlbmRzIEJhc2VBbmFseXplcjxCYXNlQW5hbHl6ZXIuUGVuZGluZ0V4aXQ+IHsKCiAgICAgICAgLyoqIEEgZmxhZyB0aGF0IGluZGljYXRlcyB3aGV0aGVyIHRoZSBsYXN0IHN0YXRlbWVudCBjb3VsZAogICAgICAgICAqICBjb21wbGV0ZSBub3JtYWxseS4KICAgICAgICAgKi8KICAgICAgICBwcml2YXRlIGJvb2xlYW4gYWxpdmU7CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHZvaWQgbWFya0RlYWQoKSB7CiAgICAgICAgICAgIGFsaXZlID0gZmFsc2U7CiAgICAgICAgfQoKICAgIC8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAgICAgKiBWaXNpdG9yIG1ldGhvZHMgZm9yIHN0YXRlbWVudHMgYW5kIGRlZmluaXRpb25zCiAgICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiAgICAgICAgLyoqIEFuYWx5emUgYSBkZWZpbml0aW9uLgogICAgICAgICAqLwogICAgICAgIHZvaWQgc2NhbkRlZihKQ1RyZWUgdHJlZSkgewogICAgICAgICAgICBzY2FuU3RhdCh0cmVlKTsKICAgICAgICAgICAgaWYgKHRyZWUgIT0gbnVsbCAmJiB0cmVlLmhhc1RhZyhKQ1RyZWUuVGFnLkJMT0NLKSAmJiAhYWxpdmUpIHsKICAgICAgICAgICAgICAgIGxvZy5lcnJvcih0cmVlLnBvcygpLAogICAgICAgICAgICAgICAgICAgICAgICAgICJpbml0aWFsaXplci5tdXN0LmJlLmFibGUudG8uY29tcGxldGUubm9ybWFsbHkiKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLyoqIEFuYWx5emUgYSBzdGF0ZW1lbnQuIENoZWNrIHRoYXQgc3RhdGVtZW50IGlzIHJlYWNoYWJsZS4KICAgICAgICAgKi8KICAgICAgICB2b2lkIHNjYW5TdGF0KEpDVHJlZSB0cmVlKSB7CiAgICAgICAgICAgIGlmICghYWxpdmUgJiYgdHJlZSAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICBsb2cuZXJyb3IodHJlZS5wb3MoKSwgInVucmVhY2hhYmxlLnN0bXQiKTsKICAgICAgICAgICAgICAgIGlmICghdHJlZS5oYXNUYWcoU0tJUCkpIGFsaXZlID0gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBzY2FuKHRyZWUpOwogICAgICAgIH0KCiAgICAgICAgLyoqIEFuYWx5emUgbGlzdCBvZiBzdGF0ZW1lbnRzLgogICAgICAgICAqLwogICAgICAgIHZvaWQgc2NhblN0YXRzKExpc3Q8PyBleHRlbmRzIEpDU3RhdGVtZW50PiB0cmVlcykgewogICAgICAgICAgICBpZiAodHJlZXMgIT0gbnVsbCkKICAgICAgICAgICAgICAgIGZvciAoTGlzdDw/IGV4dGVuZHMgSkNTdGF0ZW1lbnQ+IGwgPSB0cmVlczsgbC5ub25FbXB0eSgpOyBsID0gbC50YWlsKQogICAgICAgICAgICAgICAgICAgIHNjYW5TdGF0KGwuaGVhZCk7CiAgICAgICAgfQoKICAgICAgICAvKiAtLS0tLS0tLS0tLS0gVmlzaXRvciBtZXRob2RzIGZvciB2YXJpb3VzIHNvcnRzIG9mIHRyZWVzIC0tLS0tLS0tLS0tLS0qLwoKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdENsYXNzRGVmKEpDQ2xhc3NEZWNsIHRyZWUpIHsKICAgICAgICAgICAgaWYgKHRyZWUuc3ltID09IG51bGwpIHJldHVybjsKICAgICAgICAgICAgYm9vbGVhbiBhbGl2ZVByZXYgPSBhbGl2ZTsKICAgICAgICAgICAgTGlzdEJ1ZmZlcjxQZW5kaW5nRXhpdD4gcGVuZGluZ0V4aXRzUHJldiA9IHBlbmRpbmdFeGl0czsKICAgICAgICAgICAgTGludCBsaW50UHJldiA9IGxpbnQ7CgogICAgICAgICAgICBwZW5kaW5nRXhpdHMgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgIGxpbnQgPSBsaW50LmF1Z21lbnQodHJlZS5zeW0pOwoKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIC8vIHByb2Nlc3MgYWxsIHRoZSBzdGF0aWMgaW5pdGlhbGl6ZXJzCiAgICAgICAgICAgICAgICBmb3IgKExpc3Q8SkNUcmVlPiBsID0gdHJlZS5kZWZzOyBsLm5vbkVtcHR5KCk7IGwgPSBsLnRhaWwpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoIWwuaGVhZC5oYXNUYWcoTUVUSE9EREVGKSAmJgogICAgICAgICAgICAgICAgICAgICAgICAoVHJlZUluZm8uZmxhZ3MobC5oZWFkKSAmIFNUQVRJQykgIT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICBzY2FuRGVmKGwuaGVhZCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIHByb2Nlc3MgYWxsIHRoZSBpbnN0YW5jZSBpbml0aWFsaXplcnMKICAgICAgICAgICAgICAgIGZvciAoTGlzdDxKQ1RyZWU+IGwgPSB0cmVlLmRlZnM7IGwubm9uRW1wdHkoKTsgbCA9IGwudGFpbCkgewogICAgICAgICAgICAgICAgICAgIGlmICghbC5oZWFkLmhhc1RhZyhNRVRIT0RERUYpICYmCiAgICAgICAgICAgICAgICAgICAgICAgIChUcmVlSW5mby5mbGFncyhsLmhlYWQpICYgU1RBVElDKSA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHNjYW5EZWYobC5oZWFkKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gcHJvY2VzcyBhbGwgdGhlIG1ldGhvZHMKICAgICAgICAgICAgICAgIGZvciAoTGlzdDxKQ1RyZWU+IGwgPSB0cmVlLmRlZnM7IGwubm9uRW1wdHkoKTsgbCA9IGwudGFpbCkgewogICAgICAgICAgICAgICAgICAgIGlmIChsLmhlYWQuaGFzVGFnKE1FVEhPRERFRikpIHsKICAgICAgICAgICAgICAgICAgICAgICAgc2NhbihsLmhlYWQpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgICAgIHBlbmRpbmdFeGl0cyA9IHBlbmRpbmdFeGl0c1ByZXY7CiAgICAgICAgICAgICAgICBhbGl2ZSA9IGFsaXZlUHJldjsKICAgICAgICAgICAgICAgIGxpbnQgPSBsaW50UHJldjsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRNZXRob2REZWYoSkNNZXRob2REZWNsIHRyZWUpIHsKICAgICAgICAgICAgaWYgKHRyZWUuYm9keSA9PSBudWxsKSByZXR1cm47CiAgICAgICAgICAgIExpbnQgbGludFByZXYgPSBsaW50OwoKICAgICAgICAgICAgbGludCA9IGxpbnQuYXVnbWVudCh0cmVlLnN5bSk7CgogICAgICAgICAgICBBc3NlcnQuY2hlY2socGVuZGluZ0V4aXRzLmlzRW1wdHkoKSk7CgogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgYWxpdmUgPSB0cnVlOwogICAgICAgICAgICAgICAgc2NhblN0YXQodHJlZS5ib2R5KTsKCiAgICAgICAgICAgICAgICBpZiAoYWxpdmUgJiYgIXRyZWUuc3ltLnR5cGUuZ2V0UmV0dXJuVHlwZSgpLmhhc1RhZyhWT0lEKSkKICAgICAgICAgICAgICAgICAgICBsb2cuZXJyb3IoVHJlZUluZm8uZGlhZ0VuZFBvcyh0cmVlLmJvZHkpLCAibWlzc2luZy5yZXQuc3RtdCIpOwoKICAgICAgICAgICAgICAgIExpc3Q8UGVuZGluZ0V4aXQ+IGV4aXRzID0gcGVuZGluZ0V4aXRzLnRvTGlzdCgpOwogICAgICAgICAgICAgICAgcGVuZGluZ0V4aXRzID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgICAgICAgICAgd2hpbGUgKGV4aXRzLm5vbkVtcHR5KCkpIHsKICAgICAgICAgICAgICAgICAgICBQZW5kaW5nRXhpdCBleGl0ID0gZXhpdHMuaGVhZDsKICAgICAgICAgICAgICAgICAgICBleGl0cyA9IGV4aXRzLnRhaWw7CiAgICAgICAgICAgICAgICAgICAgQXNzZXJ0LmNoZWNrKGV4aXQudHJlZS5oYXNUYWcoUkVUVVJOKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgICAgICBsaW50ID0gbGludFByZXY7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0VmFyRGVmKEpDVmFyaWFibGVEZWNsIHRyZWUpIHsKICAgICAgICAgICAgaWYgKHRyZWUuaW5pdCAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICBMaW50IGxpbnRQcmV2ID0gbGludDsKICAgICAgICAgICAgICAgIGxpbnQgPSBsaW50LmF1Z21lbnQodHJlZS5zeW0pOwogICAgICAgICAgICAgICAgdHJ5ewogICAgICAgICAgICAgICAgICAgIHNjYW4odHJlZS5pbml0KTsKICAgICAgICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgICAgICAgICAgbGludCA9IGxpbnRQcmV2OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdEJsb2NrKEpDQmxvY2sgdHJlZSkgewogICAgICAgICAgICBzY2FuU3RhdHModHJlZS5zdGF0cyk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdERvTG9vcChKQ0RvV2hpbGVMb29wIHRyZWUpIHsKICAgICAgICAgICAgTGlzdEJ1ZmZlcjxQZW5kaW5nRXhpdD4gcHJldlBlbmRpbmdFeGl0cyA9IHBlbmRpbmdFeGl0czsKICAgICAgICAgICAgcGVuZGluZ0V4aXRzID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgICAgICBzY2FuU3RhdCh0cmVlLmJvZHkpOwogICAgICAgICAgICBhbGl2ZSB8PSByZXNvbHZlQ29udGludWVzKHRyZWUpOwogICAgICAgICAgICBzY2FuKHRyZWUuY29uZCk7CiAgICAgICAgICAgIGFsaXZlID0gYWxpdmUgJiYgIXRyZWUuY29uZC50eXBlLmlzVHJ1ZSgpOwogICAgICAgICAgICBhbGl2ZSB8PSByZXNvbHZlQnJlYWtzKHRyZWUsIHByZXZQZW5kaW5nRXhpdHMpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRXaGlsZUxvb3AoSkNXaGlsZUxvb3AgdHJlZSkgewogICAgICAgICAgICBMaXN0QnVmZmVyPFBlbmRpbmdFeGl0PiBwcmV2UGVuZGluZ0V4aXRzID0gcGVuZGluZ0V4aXRzOwogICAgICAgICAgICBwZW5kaW5nRXhpdHMgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgIHNjYW4odHJlZS5jb25kKTsKICAgICAgICAgICAgYWxpdmUgPSAhdHJlZS5jb25kLnR5cGUuaXNGYWxzZSgpOwogICAgICAgICAgICBzY2FuU3RhdCh0cmVlLmJvZHkpOwogICAgICAgICAgICBhbGl2ZSB8PSByZXNvbHZlQ29udGludWVzKHRyZWUpOwogICAgICAgICAgICBhbGl2ZSA9IHJlc29sdmVCcmVha3ModHJlZSwgcHJldlBlbmRpbmdFeGl0cykgfHwKICAgICAgICAgICAgICAgICF0cmVlLmNvbmQudHlwZS5pc1RydWUoKTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0Rm9yTG9vcChKQ0Zvckxvb3AgdHJlZSkgewogICAgICAgICAgICBMaXN0QnVmZmVyPFBlbmRpbmdFeGl0PiBwcmV2UGVuZGluZ0V4aXRzID0gcGVuZGluZ0V4aXRzOwogICAgICAgICAgICBzY2FuU3RhdHModHJlZS5pbml0KTsKICAgICAgICAgICAgcGVuZGluZ0V4aXRzID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgICAgICBpZiAodHJlZS5jb25kICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIHNjYW4odHJlZS5jb25kKTsKICAgICAgICAgICAgICAgIGFsaXZlID0gIXRyZWUuY29uZC50eXBlLmlzRmFsc2UoKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGFsaXZlID0gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBzY2FuU3RhdCh0cmVlLmJvZHkpOwogICAgICAgICAgICBhbGl2ZSB8PSByZXNvbHZlQ29udGludWVzKHRyZWUpOwogICAgICAgICAgICBzY2FuKHRyZWUuc3RlcCk7CiAgICAgICAgICAgIGFsaXZlID0gcmVzb2x2ZUJyZWFrcyh0cmVlLCBwcmV2UGVuZGluZ0V4aXRzKSB8fAogICAgICAgICAgICAgICAgdHJlZS5jb25kICE9IG51bGwgJiYgIXRyZWUuY29uZC50eXBlLmlzVHJ1ZSgpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRGb3JlYWNoTG9vcChKQ0VuaGFuY2VkRm9yTG9vcCB0cmVlKSB7CiAgICAgICAgICAgIHZpc2l0VmFyRGVmKHRyZWUudmFyKTsKICAgICAgICAgICAgTGlzdEJ1ZmZlcjxQZW5kaW5nRXhpdD4gcHJldlBlbmRpbmdFeGl0cyA9IHBlbmRpbmdFeGl0czsKICAgICAgICAgICAgc2Nhbih0cmVlLmV4cHIpOwogICAgICAgICAgICBwZW5kaW5nRXhpdHMgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgIHNjYW5TdGF0KHRyZWUuYm9keSk7CiAgICAgICAgICAgIGFsaXZlIHw9IHJlc29sdmVDb250aW51ZXModHJlZSk7CiAgICAgICAgICAgIHJlc29sdmVCcmVha3ModHJlZSwgcHJldlBlbmRpbmdFeGl0cyk7CiAgICAgICAgICAgIGFsaXZlID0gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0TGFiZWxsZWQoSkNMYWJlbGVkU3RhdGVtZW50IHRyZWUpIHsKICAgICAgICAgICAgTGlzdEJ1ZmZlcjxQZW5kaW5nRXhpdD4gcHJldlBlbmRpbmdFeGl0cyA9IHBlbmRpbmdFeGl0czsKICAgICAgICAgICAgcGVuZGluZ0V4aXRzID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgICAgICBzY2FuU3RhdCh0cmVlLmJvZHkpOwogICAgICAgICAgICBhbGl2ZSB8PSByZXNvbHZlQnJlYWtzKHRyZWUsIHByZXZQZW5kaW5nRXhpdHMpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRTd2l0Y2goSkNTd2l0Y2ggdHJlZSkgewogICAgICAgICAgICBMaXN0QnVmZmVyPFBlbmRpbmdFeGl0PiBwcmV2UGVuZGluZ0V4aXRzID0gcGVuZGluZ0V4aXRzOwogICAgICAgICAgICBwZW5kaW5nRXhpdHMgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgIHNjYW4odHJlZS5zZWxlY3Rvcik7CiAgICAgICAgICAgIGJvb2xlYW4gaGFzRGVmYXVsdCA9IGZhbHNlOwogICAgICAgICAgICBmb3IgKExpc3Q8SkNDYXNlPiBsID0gdHJlZS5jYXNlczsgbC5ub25FbXB0eSgpOyBsID0gbC50YWlsKSB7CiAgICAgICAgICAgICAgICBhbGl2ZSA9IHRydWU7CiAgICAgICAgICAgICAgICBKQ0Nhc2UgYyA9IGwuaGVhZDsKICAgICAgICAgICAgICAgIGlmIChjLnBhdCA9PSBudWxsKQogICAgICAgICAgICAgICAgICAgIGhhc0RlZmF1bHQgPSB0cnVlOwogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHNjYW4oYy5wYXQpOwogICAgICAgICAgICAgICAgc2NhblN0YXRzKGMuc3RhdHMpOwogICAgICAgICAgICAgICAgLy8gV2FybiBhYm91dCBmYWxsLXRocm91Z2ggaWYgbGludCBzd2l0Y2ggZmFsbHRocm91Z2ggZW5hYmxlZC4KICAgICAgICAgICAgICAgIGlmIChhbGl2ZSAmJgogICAgICAgICAgICAgICAgICAgIGxpbnQuaXNFbmFibGVkKExpbnQuTGludENhdGVnb3J5LkZBTExUSFJPVUdIKSAmJgogICAgICAgICAgICAgICAgICAgIGMuc3RhdHMubm9uRW1wdHkoKSAmJiBsLnRhaWwubm9uRW1wdHkoKSkKICAgICAgICAgICAgICAgICAgICBsb2cud2FybmluZyhMaW50LkxpbnRDYXRlZ29yeS5GQUxMVEhST1VHSCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsLnRhaWwuaGVhZC5wb3MoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAicG9zc2libGUuZmFsbC10aHJvdWdoLmludG8uY2FzZSIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICghaGFzRGVmYXVsdCkgewogICAgICAgICAgICAgICAgYWxpdmUgPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGFsaXZlIHw9IHJlc29sdmVCcmVha3ModHJlZSwgcHJldlBlbmRpbmdFeGl0cyk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdFRyeShKQ1RyeSB0cmVlKSB7CiAgICAgICAgICAgIExpc3RCdWZmZXI8UGVuZGluZ0V4aXQ+IHByZXZQZW5kaW5nRXhpdHMgPSBwZW5kaW5nRXhpdHM7CiAgICAgICAgICAgIHBlbmRpbmdFeGl0cyA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICAgICAgZm9yIChKQ1RyZWUgcmVzb3VyY2UgOiB0cmVlLnJlc291cmNlcykgewogICAgICAgICAgICAgICAgaWYgKHJlc291cmNlIGluc3RhbmNlb2YgSkNWYXJpYWJsZURlY2wpIHsKICAgICAgICAgICAgICAgICAgICBKQ1ZhcmlhYmxlRGVjbCB2ZGVjbCA9IChKQ1ZhcmlhYmxlRGVjbCkgcmVzb3VyY2U7CiAgICAgICAgICAgICAgICAgICAgdmlzaXRWYXJEZWYodmRlY2wpOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChyZXNvdXJjZSBpbnN0YW5jZW9mIEpDRXhwcmVzc2lvbikgewogICAgICAgICAgICAgICAgICAgIHNjYW4oKEpDRXhwcmVzc2lvbikgcmVzb3VyY2UpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IodHJlZSk7ICAvLyBwYXJzZXIgZXJyb3IKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgc2NhblN0YXQodHJlZS5ib2R5KTsKICAgICAgICAgICAgYm9vbGVhbiBhbGl2ZUVuZCA9IGFsaXZlOwoKICAgICAgICAgICAgZm9yIChMaXN0PEpDQ2F0Y2g+IGwgPSB0cmVlLmNhdGNoZXJzOyBsLm5vbkVtcHR5KCk7IGwgPSBsLnRhaWwpIHsKICAgICAgICAgICAgICAgIGFsaXZlID0gdHJ1ZTsKICAgICAgICAgICAgICAgIEpDVmFyaWFibGVEZWNsIHBhcmFtID0gbC5oZWFkLnBhcmFtOwogICAgICAgICAgICAgICAgc2NhbihwYXJhbSk7CiAgICAgICAgICAgICAgICBzY2FuU3RhdChsLmhlYWQuYm9keSk7CiAgICAgICAgICAgICAgICBhbGl2ZUVuZCB8PSBhbGl2ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAodHJlZS5maW5hbGl6ZXIgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgTGlzdEJ1ZmZlcjxQZW5kaW5nRXhpdD4gZXhpdHMgPSBwZW5kaW5nRXhpdHM7CiAgICAgICAgICAgICAgICBwZW5kaW5nRXhpdHMgPSBwcmV2UGVuZGluZ0V4aXRzOwogICAgICAgICAgICAgICAgYWxpdmUgPSB0cnVlOwogICAgICAgICAgICAgICAgc2NhblN0YXQodHJlZS5maW5hbGl6ZXIpOwogICAgICAgICAgICAgICAgdHJlZS5maW5hbGx5Q2FuQ29tcGxldGVOb3JtYWxseSA9IGFsaXZlOwogICAgICAgICAgICAgICAgaWYgKCFhbGl2ZSkgewogICAgICAgICAgICAgICAgICAgIGlmIChsaW50LmlzRW5hYmxlZChMaW50LkxpbnRDYXRlZ29yeS5GSU5BTExZKSkgewogICAgICAgICAgICAgICAgICAgICAgICBsb2cud2FybmluZyhMaW50LkxpbnRDYXRlZ29yeS5GSU5BTExZLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRyZWVJbmZvLmRpYWdFbmRQb3ModHJlZS5maW5hbGl6ZXIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJmaW5hbGx5LmNhbm5vdC5jb21wbGV0ZSIpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGV4aXRzLm5vbkVtcHR5KCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcGVuZGluZ0V4aXRzLmFwcGVuZChleGl0cy5uZXh0KCkpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBhbGl2ZSA9IGFsaXZlRW5kOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgYWxpdmUgPSBhbGl2ZUVuZDsKICAgICAgICAgICAgICAgIExpc3RCdWZmZXI8UGVuZGluZ0V4aXQ+IGV4aXRzID0gcGVuZGluZ0V4aXRzOwogICAgICAgICAgICAgICAgcGVuZGluZ0V4aXRzID0gcHJldlBlbmRpbmdFeGl0czsKICAgICAgICAgICAgICAgIHdoaWxlIChleGl0cy5ub25FbXB0eSgpKSBwZW5kaW5nRXhpdHMuYXBwZW5kKGV4aXRzLm5leHQoKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0SWYoSkNJZiB0cmVlKSB7CiAgICAgICAgICAgIHNjYW4odHJlZS5jb25kKTsKICAgICAgICAgICAgc2NhblN0YXQodHJlZS50aGVucGFydCk7CiAgICAgICAgICAgIGlmICh0cmVlLmVsc2VwYXJ0ICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIGJvb2xlYW4gYWxpdmVBZnRlclRoZW4gPSBhbGl2ZTsKICAgICAgICAgICAgICAgIGFsaXZlID0gdHJ1ZTsKICAgICAgICAgICAgICAgIHNjYW5TdGF0KHRyZWUuZWxzZXBhcnQpOwogICAgICAgICAgICAgICAgYWxpdmUgPSBhbGl2ZSB8IGFsaXZlQWZ0ZXJUaGVuOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgYWxpdmUgPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdEJyZWFrKEpDQnJlYWsgdHJlZSkgewogICAgICAgICAgICByZWNvcmRFeGl0KG5ldyBQZW5kaW5nRXhpdCh0cmVlKSk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdENvbnRpbnVlKEpDQ29udGludWUgdHJlZSkgewogICAgICAgICAgICByZWNvcmRFeGl0KG5ldyBQZW5kaW5nRXhpdCh0cmVlKSk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdFJldHVybihKQ1JldHVybiB0cmVlKSB7CiAgICAgICAgICAgIHNjYW4odHJlZS5leHByKTsKICAgICAgICAgICAgcmVjb3JkRXhpdChuZXcgUGVuZGluZ0V4aXQodHJlZSkpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRUaHJvdyhKQ1Rocm93IHRyZWUpIHsKICAgICAgICAgICAgc2Nhbih0cmVlLmV4cHIpOwogICAgICAgICAgICBtYXJrRGVhZCgpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRBcHBseShKQ01ldGhvZEludm9jYXRpb24gdHJlZSkgewogICAgICAgICAgICBzY2FuKHRyZWUubWV0aCk7CiAgICAgICAgICAgIHNjYW4odHJlZS5hcmdzKTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0TmV3Q2xhc3MoSkNOZXdDbGFzcyB0cmVlKSB7CiAgICAgICAgICAgIHNjYW4odHJlZS5lbmNsKTsKICAgICAgICAgICAgc2Nhbih0cmVlLmFyZ3MpOwogICAgICAgICAgICBpZiAodHJlZS5kZWYgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgc2Nhbih0cmVlLmRlZik7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0TGFtYmRhKEpDTGFtYmRhIHRyZWUpIHsKICAgICAgICAgICAgaWYgKHRyZWUudHlwZSAhPSBudWxsICYmCiAgICAgICAgICAgICAgICAgICAgdHJlZS50eXBlLmlzRXJyb25lb3VzKCkpIHsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgTGlzdEJ1ZmZlcjxQZW5kaW5nRXhpdD4gcHJldlBlbmRpbmcgPSBwZW5kaW5nRXhpdHM7CiAgICAgICAgICAgIGJvb2xlYW4gcHJldkFsaXZlID0gYWxpdmU7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBwZW5kaW5nRXhpdHMgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgICAgICBhbGl2ZSA9IHRydWU7CiAgICAgICAgICAgICAgICBzY2FuU3RhdCh0cmVlLmJvZHkpOwogICAgICAgICAgICAgICAgdHJlZS5jYW5Db21wbGV0ZU5vcm1hbGx5ID0gYWxpdmU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZmluYWxseSB7CiAgICAgICAgICAgICAgICBwZW5kaW5nRXhpdHMgPSBwcmV2UGVuZGluZzsKICAgICAgICAgICAgICAgIGFsaXZlID0gcHJldkFsaXZlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdE1vZHVsZURlZihKQ01vZHVsZURlY2wgdHJlZSkgewogICAgICAgICAgICAvLyBEbyBub3RoaW5nIGZvciBtb2R1bGVzCiAgICAgICAgfQoKICAgIC8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogICAgICogbWFpbiBtZXRob2QKICAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKICAgICAgICAvKiogUGVyZm9ybSBkZWZpbml0ZSBhc3NpZ25tZW50L3VuYXNzaWdubWVudCBhbmFseXNpcyBvbiBhIHRyZWUuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIHZvaWQgYW5hbHl6ZVRyZWUoRW52PEF0dHJDb250ZXh0PiBlbnYsIFRyZWVNYWtlciBtYWtlKSB7CiAgICAgICAgICAgIGFuYWx5emVUcmVlKGVudiwgZW52LnRyZWUsIG1ha2UpOwogICAgICAgIH0KICAgICAgICBwdWJsaWMgdm9pZCBhbmFseXplVHJlZShFbnY8QXR0ckNvbnRleHQ+IGVudiwgSkNUcmVlIHRyZWUsIFRyZWVNYWtlciBtYWtlKSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBhdHRyRW52ID0gZW52OwogICAgICAgICAgICAgICAgRmxvdy50aGlzLm1ha2UgPSBtYWtlOwogICAgICAgICAgICAgICAgcGVuZGluZ0V4aXRzID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgICAgICAgICAgYWxpdmUgPSB0cnVlOwogICAgICAgICAgICAgICAgc2Nhbih0cmVlKTsKICAgICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgICAgIHBlbmRpbmdFeGl0cyA9IG51bGw7CiAgICAgICAgICAgICAgICBGbG93LnRoaXMubWFrZSA9IG51bGw7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBUaGlzIHBhc3MgaW1wbGVtZW50cyB0aGUgc2Vjb25kIHN0ZXAgb2YgdGhlIGRhdGFmbG93IGFuYWx5c2lzLCBuYW1lbHkKICAgICAqIHRoZSBleGNlcHRpb24gYW5hbHlzaXMuIFRoaXMgaXMgdG8gZW5zdXJlIHRoYXQgZXZlcnkgY2hlY2tlZCBleGNlcHRpb24gdGhhdCBpcwogICAgICogdGhyb3duIGlzIGRlY2xhcmVkIG9yIGNhdWdodC4gVGhlIGFuYWx5emVyIHVzZXMgc29tZSBpbmZvIHRoYXQgaGFzIGJlZW4gc2V0IGJ5CiAgICAgKiB0aGUgbGl2ZWxpbmVzcyBhbmFseXplci4KICAgICAqLwogICAgY2xhc3MgRmxvd0FuYWx5emVyIGV4dGVuZHMgQmFzZUFuYWx5emVyPEZsb3dBbmFseXplci5GbG93UGVuZGluZ0V4aXQ+IHsKCiAgICAgICAgLyoqIEEgZmxhZyB0aGF0IGluZGljYXRlcyB3aGV0aGVyIHRoZSBsYXN0IHN0YXRlbWVudCBjb3VsZAogICAgICAgICAqICBjb21wbGV0ZSBub3JtYWxseS4KICAgICAgICAgKi8KICAgICAgICBIYXNoTWFwPFN5bWJvbCwgTGlzdDxUeXBlPj4gcHJlY2lzZVJldGhyb3dUeXBlczsKCiAgICAgICAgLyoqIFRoZSBjdXJyZW50IGNsYXNzIGJlaW5nIGRlZmluZWQuCiAgICAgICAgICovCiAgICAgICAgSkNDbGFzc0RlY2wgY2xhc3NEZWY7CgogICAgICAgIC8qKiBUaGUgbGlzdCBvZiBwb3NzaWJseSB0aHJvd24gZGVjbGFyYWJsZSBleGNlcHRpb25zLgogICAgICAgICAqLwogICAgICAgIExpc3Q8VHlwZT4gdGhyb3duOwoKICAgICAgICAvKiogVGhlIGxpc3Qgb2YgZXhjZXB0aW9ucyB0aGF0IGFyZSBlaXRoZXIgY2F1Z2h0IG9yIGRlY2xhcmVkIHRvIGJlCiAgICAgICAgICogIHRocm93bi4KICAgICAgICAgKi8KICAgICAgICBMaXN0PFR5cGU+IGNhdWdodDsKCiAgICAgICAgY2xhc3MgRmxvd1BlbmRpbmdFeGl0IGV4dGVuZHMgQmFzZUFuYWx5emVyLlBlbmRpbmdFeGl0IHsKCiAgICAgICAgICAgIFR5cGUgdGhyb3duOwoKICAgICAgICAgICAgRmxvd1BlbmRpbmdFeGl0KEpDVHJlZSB0cmVlLCBUeXBlIHRocm93bikgewogICAgICAgICAgICAgICAgc3VwZXIodHJlZSk7CiAgICAgICAgICAgICAgICB0aGlzLnRocm93biA9IHRocm93bjsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgdm9pZCBtYXJrRGVhZCgpIHsKICAgICAgICAgICAgLy9kbyBub3RoaW5nCiAgICAgICAgfQoKICAgICAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tIEV4Y2VwdGlvbnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCgogICAgICAgIC8qKiBDb21wbGFpbiB0aGF0IHBlbmRpbmcgZXhjZXB0aW9ucyBhcmUgbm90IGNhdWdodC4KICAgICAgICAgKi8KICAgICAgICB2b2lkIGVycm9yVW5jYXVnaHQoKSB7CiAgICAgICAgICAgIGZvciAoRmxvd1BlbmRpbmdFeGl0IGV4aXQgPSBwZW5kaW5nRXhpdHMubmV4dCgpOwogICAgICAgICAgICAgICAgIGV4aXQgIT0gbnVsbDsKICAgICAgICAgICAgICAgICBleGl0ID0gcGVuZGluZ0V4aXRzLm5leHQoKSkgewogICAgICAgICAgICAgICAgaWYgKGNsYXNzRGVmICE9IG51bGwgJiYKICAgICAgICAgICAgICAgICAgICBjbGFzc0RlZi5wb3MgPT0gZXhpdC50cmVlLnBvcykgewogICAgICAgICAgICAgICAgICAgIGxvZy5lcnJvcihleGl0LnRyZWUucG9zKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAidW5yZXBvcnRlZC5leGNlcHRpb24uZGVmYXVsdC5jb25zdHJ1Y3RvciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBleGl0LnRocm93bik7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGV4aXQudHJlZS5oYXNUYWcoVkFSREVGKSAmJgogICAgICAgICAgICAgICAgICAgICAgICAoKEpDVmFyaWFibGVEZWNsKWV4aXQudHJlZSkuc3ltLmlzUmVzb3VyY2VWYXJpYWJsZSgpKSB7CiAgICAgICAgICAgICAgICAgICAgbG9nLmVycm9yKGV4aXQudHJlZS5wb3MoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ1bnJlcG9ydGVkLmV4Y2VwdGlvbi5pbXBsaWNpdC5jbG9zZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBleGl0LnRocm93biwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoSkNWYXJpYWJsZURlY2wpZXhpdC50cmVlKS5zeW0ubmFtZSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGxvZy5lcnJvcihleGl0LnRyZWUucG9zKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAidW5yZXBvcnRlZC5leGNlcHRpb24ubmVlZC50by5jYXRjaC5vci50aHJvdyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBleGl0LnRocm93bik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8qKiBSZWNvcmQgdGhhdCBleGNlcHRpb24gaXMgcG90ZW50aWFsbHkgdGhyb3duIGFuZCBjaGVjayB0aGF0IGl0CiAgICAgICAgICogIGlzIGNhdWdodC4KICAgICAgICAgKi8KICAgICAgICB2b2lkIG1hcmtUaHJvd24oSkNUcmVlIHRyZWUsIFR5cGUgZXhjKSB7CiAgICAgICAgICAgIGlmICghY2hrLmlzVW5jaGVja2VkKHRyZWUucG9zKCksIGV4YykpIHsKICAgICAgICAgICAgICAgIGlmICghY2hrLmlzSGFuZGxlZChleGMsIGNhdWdodCkpIHsKICAgICAgICAgICAgICAgICAgICBwZW5kaW5nRXhpdHMuYXBwZW5kKG5ldyBGbG93UGVuZGluZ0V4aXQodHJlZSwgZXhjKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB0aHJvd24gPSBjaGsuaW5jbChleGMsIHRocm93bik7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICAgICAqIFZpc2l0b3IgbWV0aG9kcyBmb3Igc3RhdGVtZW50cyBhbmQgZGVmaW5pdGlvbnMKICAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKICAgICAgICAvKiAtLS0tLS0tLS0tLS0gVmlzaXRvciBtZXRob2RzIGZvciB2YXJpb3VzIHNvcnRzIG9mIHRyZWVzIC0tLS0tLS0tLS0tLS0qLwoKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdENsYXNzRGVmKEpDQ2xhc3NEZWNsIHRyZWUpIHsKICAgICAgICAgICAgaWYgKHRyZWUuc3ltID09IG51bGwpIHJldHVybjsKCiAgICAgICAgICAgIEpDQ2xhc3NEZWNsIGNsYXNzRGVmUHJldiA9IGNsYXNzRGVmOwogICAgICAgICAgICBMaXN0PFR5cGU+IHRocm93blByZXYgPSB0aHJvd247CiAgICAgICAgICAgIExpc3Q8VHlwZT4gY2F1Z2h0UHJldiA9IGNhdWdodDsKICAgICAgICAgICAgTGlzdEJ1ZmZlcjxGbG93UGVuZGluZ0V4aXQ+IHBlbmRpbmdFeGl0c1ByZXYgPSBwZW5kaW5nRXhpdHM7CiAgICAgICAgICAgIExpbnQgbGludFByZXYgPSBsaW50OwogICAgICAgICAgICBib29sZWFuIGFub255bW91c0NsYXNzID0gdHJlZS5uYW1lID09IG5hbWVzLmVtcHR5OwogICAgICAgICAgICBwZW5kaW5nRXhpdHMgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgIGlmICghYW5vbnltb3VzQ2xhc3MpIHsKICAgICAgICAgICAgICAgIGNhdWdodCA9IExpc3QubmlsKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY2xhc3NEZWYgPSB0cmVlOwogICAgICAgICAgICB0aHJvd24gPSBMaXN0Lm5pbCgpOwogICAgICAgICAgICBsaW50ID0gbGludC5hdWdtZW50KHRyZWUuc3ltKTsKCiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAvLyBwcm9jZXNzIGFsbCB0aGUgc3RhdGljIGluaXRpYWxpemVycwogICAgICAgICAgICAgICAgZm9yIChMaXN0PEpDVHJlZT4gbCA9IHRyZWUuZGVmczsgbC5ub25FbXB0eSgpOyBsID0gbC50YWlsKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCFsLmhlYWQuaGFzVGFnKE1FVEhPRERFRikgJiYKICAgICAgICAgICAgICAgICAgICAgICAgKFRyZWVJbmZvLmZsYWdzKGwuaGVhZCkgJiBTVEFUSUMpICE9IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgc2NhbihsLmhlYWQpOwogICAgICAgICAgICAgICAgICAgICAgICBlcnJvclVuY2F1Z2h0KCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIGFkZCBpbnRlcnNlY3Rpb24gb2YgYWxsIHRocm93biBjbGF1c2VzIG9mIGluaXRpYWwgY29uc3RydWN0b3JzCiAgICAgICAgICAgICAgICAvLyB0byBzZXQgb2YgY2F1Z2h0IGV4Y2VwdGlvbnMsIHVubGVzcyBjbGFzcyBpcyBhbm9ueW1vdXMuCiAgICAgICAgICAgICAgICBpZiAoIWFub255bW91c0NsYXNzKSB7CiAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBmaXJzdENvbnN0cnVjdG9yID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBmb3IgKExpc3Q8SkNUcmVlPiBsID0gdHJlZS5kZWZzOyBsLm5vbkVtcHR5KCk7IGwgPSBsLnRhaWwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKFRyZWVJbmZvLmlzSW5pdGlhbENvbnN0cnVjdG9yKGwuaGVhZCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIExpc3Q8VHlwZT4gbXRocm93biA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKChKQ01ldGhvZERlY2wpIGwuaGVhZCkuc3ltLnR5cGUuZ2V0VGhyb3duVHlwZXMoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmaXJzdENvbnN0cnVjdG9yKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2F1Z2h0ID0gbXRocm93bjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaXJzdENvbnN0cnVjdG9yID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhdWdodCA9IGNoay5pbnRlcnNlY3QobXRocm93biwgY2F1Z2h0KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBwcm9jZXNzIGFsbCB0aGUgaW5zdGFuY2UgaW5pdGlhbGl6ZXJzCiAgICAgICAgICAgICAgICBmb3IgKExpc3Q8SkNUcmVlPiBsID0gdHJlZS5kZWZzOyBsLm5vbkVtcHR5KCk7IGwgPSBsLnRhaWwpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoIWwuaGVhZC5oYXNUYWcoTUVUSE9EREVGKSAmJgogICAgICAgICAgICAgICAgICAgICAgICAoVHJlZUluZm8uZmxhZ3MobC5oZWFkKSAmIFNUQVRJQykgPT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICBzY2FuKGwuaGVhZCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yVW5jYXVnaHQoKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gaW4gYW4gYW5vbnltb3VzIGNsYXNzLCBhZGQgdGhlIHNldCBvZiB0aHJvd24gZXhjZXB0aW9ucyB0bwogICAgICAgICAgICAgICAgLy8gdGhlIHRocm93cyBjbGF1c2Ugb2YgdGhlIHN5bnRoZXRpYyBjb25zdHJ1Y3RvciBhbmQgcHJvcGFnYXRlCiAgICAgICAgICAgICAgICAvLyBvdXR3YXJkcy4KICAgICAgICAgICAgICAgIC8vIENoYW5naW5nIHRoZSB0aHJvd3MgY2xhdXNlIG9uIHRoZSBmbHkgaXMgb2theSBoZXJlIGJlY2F1c2UKICAgICAgICAgICAgICAgIC8vIHRoZSBhbm9ueW1vdXMgY29uc3RydWN0b3IgY2FuJ3QgYmUgaW52b2tlZCBhbnl3aGVyZSBlbHNlLAogICAgICAgICAgICAgICAgLy8gYW5kIGl0cyB0eXBlIGhhc24ndCBiZWVuIGNhY2hlZC4KICAgICAgICAgICAgICAgIGlmIChhbm9ueW1vdXNDbGFzcykgewogICAgICAgICAgICAgICAgICAgIGZvciAoTGlzdDxKQ1RyZWU+IGwgPSB0cmVlLmRlZnM7IGwubm9uRW1wdHkoKTsgbCA9IGwudGFpbCkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoVHJlZUluZm8uaXNDb25zdHJ1Y3RvcihsLmhlYWQpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBKQ01ldGhvZERlY2wgbWRlZiA9IChKQ01ldGhvZERlY2wpbC5oZWFkOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NhbihtZGVmKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1kZWYudGhyb3duID0gbWFrZS5UeXBlcyh0aHJvd24pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgbWRlZi5zeW0udHlwZSA9IHR5cGVzLmNyZWF0ZU1ldGhvZFR5cGVXaXRoVGhyb3duKG1kZWYuc3ltLnR5cGUsIHRocm93bik7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgdGhyb3duUHJldiA9IGNoay51bmlvbih0aHJvd24sIHRocm93blByZXYpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIHByb2Nlc3MgYWxsIHRoZSBtZXRob2RzCiAgICAgICAgICAgICAgICBmb3IgKExpc3Q8SkNUcmVlPiBsID0gdHJlZS5kZWZzOyBsLm5vbkVtcHR5KCk7IGwgPSBsLnRhaWwpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoYW5vbnltb3VzQ2xhc3MgJiYgVHJlZUluZm8uaXNDb25zdHJ1Y3RvcihsLmhlYWQpKQogICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsgLy8gdGhlcmUgY2FuIG5ldmVyIGJlIGFuIHVuY2F1Z2h0IGV4Y2VwdGlvbi4KICAgICAgICAgICAgICAgICAgICBpZiAobC5oZWFkLmhhc1RhZyhNRVRIT0RERUYpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHNjYW4obC5oZWFkKTsKICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JVbmNhdWdodCgpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB0aHJvd24gPSB0aHJvd25QcmV2OwogICAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAgICAgcGVuZGluZ0V4aXRzID0gcGVuZGluZ0V4aXRzUHJldjsKICAgICAgICAgICAgICAgIGNhdWdodCA9IGNhdWdodFByZXY7CiAgICAgICAgICAgICAgICBjbGFzc0RlZiA9IGNsYXNzRGVmUHJldjsKICAgICAgICAgICAgICAgIGxpbnQgPSBsaW50UHJldjsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRNZXRob2REZWYoSkNNZXRob2REZWNsIHRyZWUpIHsKICAgICAgICAgICAgaWYgKHRyZWUuYm9keSA9PSBudWxsKSByZXR1cm47CgogICAgICAgICAgICBMaXN0PFR5cGU+IGNhdWdodFByZXYgPSBjYXVnaHQ7CiAgICAgICAgICAgIExpc3Q8VHlwZT4gbXRocm93biA9IHRyZWUuc3ltLnR5cGUuZ2V0VGhyb3duVHlwZXMoKTsKICAgICAgICAgICAgTGludCBsaW50UHJldiA9IGxpbnQ7CgogICAgICAgICAgICBsaW50ID0gbGludC5hdWdtZW50KHRyZWUuc3ltKTsKCiAgICAgICAgICAgIEFzc2VydC5jaGVjayhwZW5kaW5nRXhpdHMuaXNFbXB0eSgpKTsKCiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBmb3IgKExpc3Q8SkNWYXJpYWJsZURlY2w+IGwgPSB0cmVlLnBhcmFtczsgbC5ub25FbXB0eSgpOyBsID0gbC50YWlsKSB7CiAgICAgICAgICAgICAgICAgICAgSkNWYXJpYWJsZURlY2wgZGVmID0gbC5oZWFkOwogICAgICAgICAgICAgICAgICAgIHNjYW4oZGVmKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChUcmVlSW5mby5pc0luaXRpYWxDb25zdHJ1Y3Rvcih0cmVlKSkKICAgICAgICAgICAgICAgICAgICBjYXVnaHQgPSBjaGsudW5pb24oY2F1Z2h0LCBtdGhyb3duKTsKICAgICAgICAgICAgICAgIGVsc2UgaWYgKCh0cmVlLnN5bS5mbGFncygpICYgKEJMT0NLIHwgU1RBVElDKSkgIT0gQkxPQ0spCiAgICAgICAgICAgICAgICAgICAgY2F1Z2h0ID0gbXRocm93bjsKICAgICAgICAgICAgICAgIC8vIGVsc2Ugd2UgYXJlIGluIGFuIGluc3RhbmNlIGluaXRpYWxpemVyIGJsb2NrOwogICAgICAgICAgICAgICAgLy8gbGVhdmUgY2F1Z2h0IHVuY2hhbmdlZC4KCiAgICAgICAgICAgICAgICBzY2FuKHRyZWUuYm9keSk7CgogICAgICAgICAgICAgICAgTGlzdDxGbG93UGVuZGluZ0V4aXQ+IGV4aXRzID0gcGVuZGluZ0V4aXRzLnRvTGlzdCgpOwogICAgICAgICAgICAgICAgcGVuZGluZ0V4aXRzID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgICAgICAgICAgd2hpbGUgKGV4aXRzLm5vbkVtcHR5KCkpIHsKICAgICAgICAgICAgICAgICAgICBGbG93UGVuZGluZ0V4aXQgZXhpdCA9IGV4aXRzLmhlYWQ7CiAgICAgICAgICAgICAgICAgICAgZXhpdHMgPSBleGl0cy50YWlsOwogICAgICAgICAgICAgICAgICAgIGlmIChleGl0LnRocm93biA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIEFzc2VydC5jaGVjayhleGl0LnRyZWUuaGFzVGFnKFJFVFVSTikpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHVuY2F1Z2h0IHRocm93cyB3aWxsIGJlIHJlcG9ydGVkIGxhdGVyCiAgICAgICAgICAgICAgICAgICAgICAgIHBlbmRpbmdFeGl0cy5hcHBlbmQoZXhpdCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAgICAgY2F1Z2h0ID0gY2F1Z2h0UHJldjsKICAgICAgICAgICAgICAgIGxpbnQgPSBsaW50UHJldjsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRWYXJEZWYoSkNWYXJpYWJsZURlY2wgdHJlZSkgewogICAgICAgICAgICBpZiAodHJlZS5pbml0ICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIExpbnQgbGludFByZXYgPSBsaW50OwogICAgICAgICAgICAgICAgbGludCA9IGxpbnQuYXVnbWVudCh0cmVlLnN5bSk7CiAgICAgICAgICAgICAgICB0cnl7CiAgICAgICAgICAgICAgICAgICAgc2Nhbih0cmVlLmluaXQpOwogICAgICAgICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgICAgICAgICBsaW50ID0gbGludFByZXY7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0QmxvY2soSkNCbG9jayB0cmVlKSB7CiAgICAgICAgICAgIHNjYW4odHJlZS5zdGF0cyk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdERvTG9vcChKQ0RvV2hpbGVMb29wIHRyZWUpIHsKICAgICAgICAgICAgTGlzdEJ1ZmZlcjxGbG93UGVuZGluZ0V4aXQ+IHByZXZQZW5kaW5nRXhpdHMgPSBwZW5kaW5nRXhpdHM7CiAgICAgICAgICAgIHBlbmRpbmdFeGl0cyA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICAgICAgc2Nhbih0cmVlLmJvZHkpOwogICAgICAgICAgICByZXNvbHZlQ29udGludWVzKHRyZWUpOwogICAgICAgICAgICBzY2FuKHRyZWUuY29uZCk7CiAgICAgICAgICAgIHJlc29sdmVCcmVha3ModHJlZSwgcHJldlBlbmRpbmdFeGl0cyk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdFdoaWxlTG9vcChKQ1doaWxlTG9vcCB0cmVlKSB7CiAgICAgICAgICAgIExpc3RCdWZmZXI8Rmxvd1BlbmRpbmdFeGl0PiBwcmV2UGVuZGluZ0V4aXRzID0gcGVuZGluZ0V4aXRzOwogICAgICAgICAgICBwZW5kaW5nRXhpdHMgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgIHNjYW4odHJlZS5jb25kKTsKICAgICAgICAgICAgc2Nhbih0cmVlLmJvZHkpOwogICAgICAgICAgICByZXNvbHZlQ29udGludWVzKHRyZWUpOwogICAgICAgICAgICByZXNvbHZlQnJlYWtzKHRyZWUsIHByZXZQZW5kaW5nRXhpdHMpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRGb3JMb29wKEpDRm9yTG9vcCB0cmVlKSB7CiAgICAgICAgICAgIExpc3RCdWZmZXI8Rmxvd1BlbmRpbmdFeGl0PiBwcmV2UGVuZGluZ0V4aXRzID0gcGVuZGluZ0V4aXRzOwogICAgICAgICAgICBzY2FuKHRyZWUuaW5pdCk7CiAgICAgICAgICAgIHBlbmRpbmdFeGl0cyA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICAgICAgaWYgKHRyZWUuY29uZCAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICBzY2FuKHRyZWUuY29uZCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc2Nhbih0cmVlLmJvZHkpOwogICAgICAgICAgICByZXNvbHZlQ29udGludWVzKHRyZWUpOwogICAgICAgICAgICBzY2FuKHRyZWUuc3RlcCk7CiAgICAgICAgICAgIHJlc29sdmVCcmVha3ModHJlZSwgcHJldlBlbmRpbmdFeGl0cyk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdEZvcmVhY2hMb29wKEpDRW5oYW5jZWRGb3JMb29wIHRyZWUpIHsKICAgICAgICAgICAgdmlzaXRWYXJEZWYodHJlZS52YXIpOwogICAgICAgICAgICBMaXN0QnVmZmVyPEZsb3dQZW5kaW5nRXhpdD4gcHJldlBlbmRpbmdFeGl0cyA9IHBlbmRpbmdFeGl0czsKICAgICAgICAgICAgc2Nhbih0cmVlLmV4cHIpOwogICAgICAgICAgICBwZW5kaW5nRXhpdHMgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgIHNjYW4odHJlZS5ib2R5KTsKICAgICAgICAgICAgcmVzb2x2ZUNvbnRpbnVlcyh0cmVlKTsKICAgICAgICAgICAgcmVzb2x2ZUJyZWFrcyh0cmVlLCBwcmV2UGVuZGluZ0V4aXRzKTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0TGFiZWxsZWQoSkNMYWJlbGVkU3RhdGVtZW50IHRyZWUpIHsKICAgICAgICAgICAgTGlzdEJ1ZmZlcjxGbG93UGVuZGluZ0V4aXQ+IHByZXZQZW5kaW5nRXhpdHMgPSBwZW5kaW5nRXhpdHM7CiAgICAgICAgICAgIHBlbmRpbmdFeGl0cyA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICAgICAgc2Nhbih0cmVlLmJvZHkpOwogICAgICAgICAgICByZXNvbHZlQnJlYWtzKHRyZWUsIHByZXZQZW5kaW5nRXhpdHMpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRTd2l0Y2goSkNTd2l0Y2ggdHJlZSkgewogICAgICAgICAgICBMaXN0QnVmZmVyPEZsb3dQZW5kaW5nRXhpdD4gcHJldlBlbmRpbmdFeGl0cyA9IHBlbmRpbmdFeGl0czsKICAgICAgICAgICAgcGVuZGluZ0V4aXRzID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgICAgICBzY2FuKHRyZWUuc2VsZWN0b3IpOwogICAgICAgICAgICBmb3IgKExpc3Q8SkNDYXNlPiBsID0gdHJlZS5jYXNlczsgbC5ub25FbXB0eSgpOyBsID0gbC50YWlsKSB7CiAgICAgICAgICAgICAgICBKQ0Nhc2UgYyA9IGwuaGVhZDsKICAgICAgICAgICAgICAgIGlmIChjLnBhdCAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgc2NhbihjLnBhdCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBzY2FuKGMuc3RhdHMpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJlc29sdmVCcmVha3ModHJlZSwgcHJldlBlbmRpbmdFeGl0cyk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdFRyeShKQ1RyeSB0cmVlKSB7CiAgICAgICAgICAgIExpc3Q8VHlwZT4gY2F1Z2h0UHJldiA9IGNhdWdodDsKICAgICAgICAgICAgTGlzdDxUeXBlPiB0aHJvd25QcmV2ID0gdGhyb3duOwogICAgICAgICAgICB0aHJvd24gPSBMaXN0Lm5pbCgpOwogICAgICAgICAgICBmb3IgKExpc3Q8SkNDYXRjaD4gbCA9IHRyZWUuY2F0Y2hlcnM7IGwubm9uRW1wdHkoKTsgbCA9IGwudGFpbCkgewogICAgICAgICAgICAgICAgTGlzdDxKQ0V4cHJlc3Npb24+IHN1YkNsYXVzZXMgPSBUcmVlSW5mby5pc011bHRpQ2F0Y2gobC5oZWFkKSA/CiAgICAgICAgICAgICAgICAgICAgICAgICgoSkNUeXBlVW5pb24pbC5oZWFkLnBhcmFtLnZhcnR5cGUpLmFsdGVybmF0aXZlcyA6CiAgICAgICAgICAgICAgICAgICAgICAgIExpc3Qub2YobC5oZWFkLnBhcmFtLnZhcnR5cGUpOwogICAgICAgICAgICAgICAgZm9yIChKQ0V4cHJlc3Npb24gY3QgOiBzdWJDbGF1c2VzKSB7CiAgICAgICAgICAgICAgICAgICAgY2F1Z2h0ID0gY2hrLmluY2woY3QudHlwZSwgY2F1Z2h0KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgTGlzdEJ1ZmZlcjxGbG93UGVuZGluZ0V4aXQ+IHByZXZQZW5kaW5nRXhpdHMgPSBwZW5kaW5nRXhpdHM7CiAgICAgICAgICAgIHBlbmRpbmdFeGl0cyA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICAgICAgZm9yIChKQ1RyZWUgcmVzb3VyY2UgOiB0cmVlLnJlc291cmNlcykgewogICAgICAgICAgICAgICAgaWYgKHJlc291cmNlIGluc3RhbmNlb2YgSkNWYXJpYWJsZURlY2wpIHsKICAgICAgICAgICAgICAgICAgICBKQ1ZhcmlhYmxlRGVjbCB2ZGVjbCA9IChKQ1ZhcmlhYmxlRGVjbCkgcmVzb3VyY2U7CiAgICAgICAgICAgICAgICAgICAgdmlzaXRWYXJEZWYodmRlY2wpOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChyZXNvdXJjZSBpbnN0YW5jZW9mIEpDRXhwcmVzc2lvbikgewogICAgICAgICAgICAgICAgICAgIHNjYW4oKEpDRXhwcmVzc2lvbikgcmVzb3VyY2UpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IodHJlZSk7ICAvLyBwYXJzZXIgZXJyb3IKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBmb3IgKEpDVHJlZSByZXNvdXJjZSA6IHRyZWUucmVzb3VyY2VzKSB7CiAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IGNsb3NlYWJsZVN1cGVydHlwZXMgPSByZXNvdXJjZS50eXBlLmlzQ29tcG91bmQoKSA/CiAgICAgICAgICAgICAgICAgICAgdHlwZXMuaW50ZXJmYWNlcyhyZXNvdXJjZS50eXBlKS5wcmVwZW5kKHR5cGVzLnN1cGVydHlwZShyZXNvdXJjZS50eXBlKSkgOgogICAgICAgICAgICAgICAgICAgIExpc3Qub2YocmVzb3VyY2UudHlwZSk7CiAgICAgICAgICAgICAgICBmb3IgKFR5cGUgc3VwIDogY2xvc2VhYmxlU3VwZXJ0eXBlcykgewogICAgICAgICAgICAgICAgICAgIGlmICh0eXBlcy5hc1N1cGVyKHN1cCwgc3ltcy5hdXRvQ2xvc2VhYmxlVHlwZS50c3ltKSAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIFN5bWJvbCBjbG9zZU1ldGhvZCA9IHJzLnJlc29sdmVRdWFsaWZpZWRNZXRob2QodHJlZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRyRW52LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVzLnNraXBUeXBlVmFycyhzdXAsIGZhbHNlKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lcy5jbG9zZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0Lm5pbCgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExpc3QubmlsKCkpOwogICAgICAgICAgICAgICAgICAgICAgICBUeXBlIG10ID0gdHlwZXMubWVtYmVyVHlwZShyZXNvdXJjZS50eXBlLCBjbG9zZU1ldGhvZCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjbG9zZU1ldGhvZC5raW5kID09IE1USCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChUeXBlIHQgOiBtdC5nZXRUaHJvd25UeXBlcygpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFya1Rocm93bihyZXNvdXJjZSwgdCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc2Nhbih0cmVlLmJvZHkpOwogICAgICAgICAgICBMaXN0PFR5cGU+IHRocm93bkluVHJ5ID0gYWxsb3dJbXByb3ZlZENhdGNoQW5hbHlzaXMgPwogICAgICAgICAgICAgICAgY2hrLnVuaW9uKHRocm93biwgTGlzdC5vZihzeW1zLnJ1bnRpbWVFeGNlcHRpb25UeXBlLCBzeW1zLmVycm9yVHlwZSkpIDoKICAgICAgICAgICAgICAgIHRocm93bjsKICAgICAgICAgICAgdGhyb3duID0gdGhyb3duUHJldjsKICAgICAgICAgICAgY2F1Z2h0ID0gY2F1Z2h0UHJldjsKCiAgICAgICAgICAgIExpc3Q8VHlwZT4gY2F1Z2h0SW5UcnkgPSBMaXN0Lm5pbCgpOwogICAgICAgICAgICBmb3IgKExpc3Q8SkNDYXRjaD4gbCA9IHRyZWUuY2F0Y2hlcnM7IGwubm9uRW1wdHkoKTsgbCA9IGwudGFpbCkgewogICAgICAgICAgICAgICAgSkNWYXJpYWJsZURlY2wgcGFyYW0gPSBsLmhlYWQucGFyYW07CiAgICAgICAgICAgICAgICBMaXN0PEpDRXhwcmVzc2lvbj4gc3ViQ2xhdXNlcyA9IFRyZWVJbmZvLmlzTXVsdGlDYXRjaChsLmhlYWQpID8KICAgICAgICAgICAgICAgICAgICAgICAgKChKQ1R5cGVVbmlvbilsLmhlYWQucGFyYW0udmFydHlwZSkuYWx0ZXJuYXRpdmVzIDoKICAgICAgICAgICAgICAgICAgICAgICAgTGlzdC5vZihsLmhlYWQucGFyYW0udmFydHlwZSk7CiAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IGN0eXBlcyA9IExpc3QubmlsKCk7CiAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IHJldGhyb3duVHlwZXMgPSBjaGsuZGlmZih0aHJvd25JblRyeSwgY2F1Z2h0SW5UcnkpOwogICAgICAgICAgICAgICAgZm9yIChKQ0V4cHJlc3Npb24gY3QgOiBzdWJDbGF1c2VzKSB7CiAgICAgICAgICAgICAgICAgICAgVHlwZSBleGMgPSBjdC50eXBlOwogICAgICAgICAgICAgICAgICAgIGlmIChleGMgIT0gc3ltcy51bmtub3duVHlwZSkgewogICAgICAgICAgICAgICAgICAgICAgICBjdHlwZXMgPSBjdHlwZXMuYXBwZW5kKGV4Yyk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlcy5pc1NhbWVUeXBlKGV4Yywgc3ltcy5vYmplY3RUeXBlKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgICAgICBjaGVja0NhdWdodFR5cGUobC5oZWFkLnBvcygpLCBleGMsIHRocm93bkluVHJ5LCBjYXVnaHRJblRyeSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhdWdodEluVHJ5ID0gY2hrLmluY2woZXhjLCBjYXVnaHRJblRyeSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgc2NhbihwYXJhbSk7CiAgICAgICAgICAgICAgICBwcmVjaXNlUmV0aHJvd1R5cGVzLnB1dChwYXJhbS5zeW0sIGNoay5pbnRlcnNlY3QoY3R5cGVzLCByZXRocm93blR5cGVzKSk7CiAgICAgICAgICAgICAgICBzY2FuKGwuaGVhZC5ib2R5KTsKICAgICAgICAgICAgICAgIHByZWNpc2VSZXRocm93VHlwZXMucmVtb3ZlKHBhcmFtLnN5bSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHRyZWUuZmluYWxpemVyICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIExpc3Q8VHlwZT4gc2F2ZWRUaHJvd24gPSB0aHJvd247CiAgICAgICAgICAgICAgICB0aHJvd24gPSBMaXN0Lm5pbCgpOwogICAgICAgICAgICAgICAgTGlzdEJ1ZmZlcjxGbG93UGVuZGluZ0V4aXQ+IGV4aXRzID0gcGVuZGluZ0V4aXRzOwogICAgICAgICAgICAgICAgcGVuZGluZ0V4aXRzID0gcHJldlBlbmRpbmdFeGl0czsKICAgICAgICAgICAgICAgIHNjYW4odHJlZS5maW5hbGl6ZXIpOwogICAgICAgICAgICAgICAgaWYgKCF0cmVlLmZpbmFsbHlDYW5Db21wbGV0ZU5vcm1hbGx5KSB7CiAgICAgICAgICAgICAgICAgICAgLy8gZGlzY2FyZCBleGl0cyBhbmQgZXhjZXB0aW9ucyBmcm9tIHRyeSBhbmQgZmluYWxseQogICAgICAgICAgICAgICAgICAgIHRocm93biA9IGNoay51bmlvbih0aHJvd24sIHRocm93blByZXYpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICB0aHJvd24gPSBjaGsudW5pb24odGhyb3duLCBjaGsuZGlmZih0aHJvd25JblRyeSwgY2F1Z2h0SW5UcnkpKTsKICAgICAgICAgICAgICAgICAgICB0aHJvd24gPSBjaGsudW5pb24odGhyb3duLCBzYXZlZFRocm93bik7CiAgICAgICAgICAgICAgICAgICAgLy8gRklYOiB0aGlzIGRvZXNuJ3QgcHJlc2VydmUgc291cmNlIG9yZGVyIG9mIGV4aXRzIGluIGNhdGNoCiAgICAgICAgICAgICAgICAgICAgLy8gdmVyc3VzIGZpbmFsbHkhCiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGV4aXRzLm5vbkVtcHR5KCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcGVuZGluZ0V4aXRzLmFwcGVuZChleGl0cy5uZXh0KCkpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHRocm93biA9IGNoay51bmlvbih0aHJvd24sIGNoay5kaWZmKHRocm93bkluVHJ5LCBjYXVnaHRJblRyeSkpOwogICAgICAgICAgICAgICAgTGlzdEJ1ZmZlcjxGbG93UGVuZGluZ0V4aXQ+IGV4aXRzID0gcGVuZGluZ0V4aXRzOwogICAgICAgICAgICAgICAgcGVuZGluZ0V4aXRzID0gcHJldlBlbmRpbmdFeGl0czsKICAgICAgICAgICAgICAgIHdoaWxlIChleGl0cy5ub25FbXB0eSgpKSBwZW5kaW5nRXhpdHMuYXBwZW5kKGV4aXRzLm5leHQoKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0SWYoSkNJZiB0cmVlKSB7CiAgICAgICAgICAgIHNjYW4odHJlZS5jb25kKTsKICAgICAgICAgICAgc2Nhbih0cmVlLnRoZW5wYXJ0KTsKICAgICAgICAgICAgaWYgKHRyZWUuZWxzZXBhcnQgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgc2Nhbih0cmVlLmVsc2VwYXJ0KTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgdm9pZCBjaGVja0NhdWdodFR5cGUoRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcywgVHlwZSBleGMsIExpc3Q8VHlwZT4gdGhyb3duSW5UcnksIExpc3Q8VHlwZT4gY2F1Z2h0SW5UcnkpIHsKICAgICAgICAgICAgaWYgKGNoay5zdWJzZXQoZXhjLCBjYXVnaHRJblRyeSkpIHsKICAgICAgICAgICAgICAgIGxvZy5lcnJvcihwb3MsICJleGNlcHQuYWxyZWFkeS5jYXVnaHQiLCBleGMpOwogICAgICAgICAgICB9IGVsc2UgaWYgKCFjaGsuaXNVbmNoZWNrZWQocG9zLCBleGMpICYmCiAgICAgICAgICAgICAgICAgICAgIWlzRXhjZXB0aW9uT3JUaHJvd2FibGUoZXhjKSAmJgogICAgICAgICAgICAgICAgICAgICFjaGsuaW50ZXJzZWN0cyhleGMsIHRocm93bkluVHJ5KSkgewogICAgICAgICAgICAgICAgbG9nLmVycm9yKHBvcywgImV4Y2VwdC5uZXZlci50aHJvd24uaW4udHJ5IiwgZXhjKTsKICAgICAgICAgICAgfSBlbHNlIGlmIChhbGxvd0ltcHJvdmVkQ2F0Y2hBbmFseXNpcykgewogICAgICAgICAgICAgICAgTGlzdDxUeXBlPiBjYXRjaGFibGVUaHJvd25UeXBlcyA9IGNoay5pbnRlcnNlY3QoTGlzdC5vZihleGMpLCB0aHJvd25JblRyeSk7CiAgICAgICAgICAgICAgICAvLyAnY2F0Y2hhYmxlVGhyb3duVHlwZXMnIGNhbm5ub3QgcG9zc2libHkgYmUgZW1wdHkgLSBpZiAnZXhjJyB3YXMgYW4KICAgICAgICAgICAgICAgIC8vIHVuY2hlY2tlZCBleGNlcHRpb24sIHRoZSByZXN1bHQgbGlzdCB3b3VsZCBub3QgYmUgZW1wdHksIGFzIHRoZSBhdWdtZW50ZWQKICAgICAgICAgICAgICAgIC8vIHRocm93biBzZXQgaW5jbHVkZXMgeyBSdW50aW1lRXhjZXB0aW9uLCBFcnJvciB9OyBpZiAnZXhjJyB3YXMgYSBjaGVja2VkCiAgICAgICAgICAgICAgICAvLyBleGNlcHRpb24sIHRoYXQgd291bGQgaGF2ZSBiZWVuIGNvdmVyZWQgaW4gdGhlIGJyYW5jaCBhYm92ZQogICAgICAgICAgICAgICAgaWYgKGNoay5kaWZmKGNhdGNoYWJsZVRocm93blR5cGVzLCBjYXVnaHRJblRyeSkuaXNFbXB0eSgpICYmCiAgICAgICAgICAgICAgICAgICAgICAgICFpc0V4Y2VwdGlvbk9yVGhyb3dhYmxlKGV4YykpIHsKICAgICAgICAgICAgICAgICAgICBTdHJpbmcga2V5ID0gY2F0Y2hhYmxlVGhyb3duVHlwZXMubGVuZ3RoKCkgPT0gMSA/CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAidW5yZWFjaGFibGUuY2F0Y2giIDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ1bnJlYWNoYWJsZS5jYXRjaC4xIjsKICAgICAgICAgICAgICAgICAgICBsb2cud2FybmluZyhwb3MsIGtleSwgY2F0Y2hhYmxlVGhyb3duVHlwZXMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8vd2hlcmUKICAgICAgICAgICAgcHJpdmF0ZSBib29sZWFuIGlzRXhjZXB0aW9uT3JUaHJvd2FibGUoVHlwZSBleGMpIHsKICAgICAgICAgICAgICAgIHJldHVybiBleGMudHN5bSA9PSBzeW1zLnRocm93YWJsZVR5cGUudHN5bSB8fAogICAgICAgICAgICAgICAgICAgIGV4Yy50c3ltID09IHN5bXMuZXhjZXB0aW9uVHlwZS50c3ltOwogICAgICAgICAgICB9CgogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0QnJlYWsoSkNCcmVhayB0cmVlKSB7CiAgICAgICAgICAgIHJlY29yZEV4aXQobmV3IEZsb3dQZW5kaW5nRXhpdCh0cmVlLCBudWxsKSk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdENvbnRpbnVlKEpDQ29udGludWUgdHJlZSkgewogICAgICAgICAgICByZWNvcmRFeGl0KG5ldyBGbG93UGVuZGluZ0V4aXQodHJlZSwgbnVsbCkpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRSZXR1cm4oSkNSZXR1cm4gdHJlZSkgewogICAgICAgICAgICBzY2FuKHRyZWUuZXhwcik7CiAgICAgICAgICAgIHJlY29yZEV4aXQobmV3IEZsb3dQZW5kaW5nRXhpdCh0cmVlLCBudWxsKSk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdFRocm93KEpDVGhyb3cgdHJlZSkgewogICAgICAgICAgICBzY2FuKHRyZWUuZXhwcik7CiAgICAgICAgICAgIFN5bWJvbCBzeW0gPSBUcmVlSW5mby5zeW1ib2wodHJlZS5leHByKTsKICAgICAgICAgICAgaWYgKHN5bSAhPSBudWxsICYmCiAgICAgICAgICAgICAgICBzeW0ua2luZCA9PSBWQVIgJiYKICAgICAgICAgICAgICAgIChzeW0uZmxhZ3MoKSAmIChGSU5BTCB8IEVGRkVDVElWRUxZX0ZJTkFMKSkgIT0gMCAmJgogICAgICAgICAgICAgICAgcHJlY2lzZVJldGhyb3dUeXBlcy5nZXQoc3ltKSAhPSBudWxsICYmCiAgICAgICAgICAgICAgICBhbGxvd0ltcHJvdmVkUmV0aHJvd0FuYWx5c2lzKSB7CiAgICAgICAgICAgICAgICBmb3IgKFR5cGUgdCA6IHByZWNpc2VSZXRocm93VHlwZXMuZ2V0KHN5bSkpIHsKICAgICAgICAgICAgICAgICAgICBtYXJrVGhyb3duKHRyZWUsIHQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgbWFya1Rocm93bih0cmVlLCB0cmVlLmV4cHIudHlwZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgbWFya0RlYWQoKTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0QXBwbHkoSkNNZXRob2RJbnZvY2F0aW9uIHRyZWUpIHsKICAgICAgICAgICAgc2Nhbih0cmVlLm1ldGgpOwogICAgICAgICAgICBzY2FuKHRyZWUuYXJncyk7CiAgICAgICAgICAgIGZvciAoTGlzdDxUeXBlPiBsID0gdHJlZS5tZXRoLnR5cGUuZ2V0VGhyb3duVHlwZXMoKTsgbC5ub25FbXB0eSgpOyBsID0gbC50YWlsKQogICAgICAgICAgICAgICAgbWFya1Rocm93bih0cmVlLCBsLmhlYWQpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXROZXdDbGFzcyhKQ05ld0NsYXNzIHRyZWUpIHsKICAgICAgICAgICAgc2Nhbih0cmVlLmVuY2wpOwogICAgICAgICAgICBzY2FuKHRyZWUuYXJncyk7CiAgICAgICAgICAgLy8gc2Nhbih0cmVlLmRlZik7CiAgICAgICAgICAgIGZvciAoTGlzdDxUeXBlPiBsID0gdHJlZS5jb25zdHJ1Y3RvclR5cGUuZ2V0VGhyb3duVHlwZXMoKTsKICAgICAgICAgICAgICAgICBsLm5vbkVtcHR5KCk7CiAgICAgICAgICAgICAgICAgbCA9IGwudGFpbCkgewogICAgICAgICAgICAgICAgbWFya1Rocm93bih0cmVlLCBsLmhlYWQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIExpc3Q8VHlwZT4gY2F1Z2h0UHJldiA9IGNhdWdodDsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIC8vIElmIHRoZSBuZXcgY2xhc3MgZXhwcmVzc2lvbiBkZWZpbmVzIGFuIGFub255bW91cyBjbGFzcywKICAgICAgICAgICAgICAgIC8vIGFuYWx5c2lzIG9mIHRoZSBhbm9ueW1vdXMgY29uc3RydWN0b3IgbWF5IGVuY291bnRlciB0aHJvd24KICAgICAgICAgICAgICAgIC8vIHR5cGVzIHdoaWNoIGFyZSB1bnN1YnN0aXR1dGVkIHR5cGUgdmFyaWFibGVzLgogICAgICAgICAgICAgICAgLy8gSG93ZXZlciwgc2luY2UgdGhlIGNvbnN0cnVjdG9yJ3MgYWN0dWFsIHRocm93biB0eXBlcyBoYXZlCiAgICAgICAgICAgICAgICAvLyBhbHJlYWR5IGJlZW4gbWFya2VkIGFzIHRocm93biwgaXQgaXMgc2FmZSB0byBzaW1wbHkgaW5jbHVkZQogICAgICAgICAgICAgICAgLy8gZWFjaCBvZiB0aGUgY29uc3RydWN0b3IncyBmb3JtYWwgdGhyb3duIHR5cGVzIGluIHRoZSBzZXQgb2YKICAgICAgICAgICAgICAgIC8vICdjYXVnaHQvZGVjbGFyZWQgdG8gYmUgdGhyb3duJyB0eXBlcywgZm9yIHRoZSBkdXJhdGlvbiBvZgogICAgICAgICAgICAgICAgLy8gdGhlIGNsYXNzIGRlZiBhbmFseXNpcy4KICAgICAgICAgICAgICAgIGlmICh0cmVlLmRlZiAhPSBudWxsKQogICAgICAgICAgICAgICAgICAgIGZvciAoTGlzdDxUeXBlPiBsID0gdHJlZS5jb25zdHJ1Y3Rvci50eXBlLmdldFRocm93blR5cGVzKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICBsLm5vbkVtcHR5KCk7CiAgICAgICAgICAgICAgICAgICAgICAgICBsID0gbC50YWlsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhdWdodCA9IGNoay5pbmNsKGwuaGVhZCwgY2F1Z2h0KTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBzY2FuKHRyZWUuZGVmKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBmaW5hbGx5IHsKICAgICAgICAgICAgICAgIGNhdWdodCA9IGNhdWdodFByZXY7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0TGFtYmRhKEpDTGFtYmRhIHRyZWUpIHsKICAgICAgICAgICAgaWYgKHRyZWUudHlwZSAhPSBudWxsICYmCiAgICAgICAgICAgICAgICAgICAgdHJlZS50eXBlLmlzRXJyb25lb3VzKCkpIHsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgICAgICBMaXN0PFR5cGU+IHByZXZDYXVnaHQgPSBjYXVnaHQ7CiAgICAgICAgICAgIExpc3Q8VHlwZT4gcHJldlRocm93biA9IHRocm93bjsKICAgICAgICAgICAgTGlzdEJ1ZmZlcjxGbG93UGVuZGluZ0V4aXQ+IHByZXZQZW5kaW5nID0gcGVuZGluZ0V4aXRzOwogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgcGVuZGluZ0V4aXRzID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgICAgICAgICAgY2F1Z2h0ID0gdHJlZS5nZXREZXNjcmlwdG9yVHlwZSh0eXBlcykuZ2V0VGhyb3duVHlwZXMoKTsKICAgICAgICAgICAgICAgIHRocm93biA9IExpc3QubmlsKCk7CiAgICAgICAgICAgICAgICBzY2FuKHRyZWUuYm9keSk7CiAgICAgICAgICAgICAgICBMaXN0PEZsb3dQZW5kaW5nRXhpdD4gZXhpdHMgPSBwZW5kaW5nRXhpdHMudG9MaXN0KCk7CiAgICAgICAgICAgICAgICBwZW5kaW5nRXhpdHMgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoZXhpdHMubm9uRW1wdHkoKSkgewogICAgICAgICAgICAgICAgICAgIEZsb3dQZW5kaW5nRXhpdCBleGl0ID0gZXhpdHMuaGVhZDsKICAgICAgICAgICAgICAgICAgICBleGl0cyA9IGV4aXRzLnRhaWw7CiAgICAgICAgICAgICAgICAgICAgaWYgKGV4aXQudGhyb3duID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgQXNzZXJ0LmNoZWNrKGV4aXQudHJlZS5oYXNUYWcoUkVUVVJOKSk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gdW5jYXVnaHQgdGhyb3dzIHdpbGwgYmUgcmVwb3J0ZWQgbGF0ZXIKICAgICAgICAgICAgICAgICAgICAgICAgcGVuZGluZ0V4aXRzLmFwcGVuZChleGl0KTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgZXJyb3JVbmNhdWdodCgpOwogICAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAgICAgcGVuZGluZ0V4aXRzID0gcHJldlBlbmRpbmc7CiAgICAgICAgICAgICAgICBjYXVnaHQgPSBwcmV2Q2F1Z2h0OwogICAgICAgICAgICAgICAgdGhyb3duID0gcHJldlRocm93bjsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRNb2R1bGVEZWYoSkNNb2R1bGVEZWNsIHRyZWUpIHsKICAgICAgICAgICAgLy8gRG8gbm90aGluZyBmb3IgbW9kdWxlcwogICAgICAgIH0KCiAgICAvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICAgICAqIG1haW4gbWV0aG9kCiAgICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiAgICAgICAgLyoqIFBlcmZvcm0gZGVmaW5pdGUgYXNzaWdubWVudC91bmFzc2lnbm1lbnQgYW5hbHlzaXMgb24gYSB0cmVlLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyB2b2lkIGFuYWx5emVUcmVlKEVudjxBdHRyQ29udGV4dD4gZW52LCBUcmVlTWFrZXIgbWFrZSkgewogICAgICAgICAgICBhbmFseXplVHJlZShlbnYsIGVudi50cmVlLCBtYWtlKTsKICAgICAgICB9CiAgICAgICAgcHVibGljIHZvaWQgYW5hbHl6ZVRyZWUoRW52PEF0dHJDb250ZXh0PiBlbnYsIEpDVHJlZSB0cmVlLCBUcmVlTWFrZXIgbWFrZSkgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgYXR0ckVudiA9IGVudjsKICAgICAgICAgICAgICAgIEZsb3cudGhpcy5tYWtlID0gbWFrZTsKICAgICAgICAgICAgICAgIHBlbmRpbmdFeGl0cyA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICAgICAgICAgIHByZWNpc2VSZXRocm93VHlwZXMgPSBuZXcgSGFzaE1hcDw+KCk7CiAgICAgICAgICAgICAgICB0aGlzLnRocm93biA9IHRoaXMuY2F1Z2h0ID0gbnVsbDsKICAgICAgICAgICAgICAgIHRoaXMuY2xhc3NEZWYgPSBudWxsOwogICAgICAgICAgICAgICAgc2Nhbih0cmVlKTsKICAgICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgICAgIHBlbmRpbmdFeGl0cyA9IG51bGw7CiAgICAgICAgICAgICAgICBGbG93LnRoaXMubWFrZSA9IG51bGw7CiAgICAgICAgICAgICAgICB0aGlzLnRocm93biA9IHRoaXMuY2F1Z2h0ID0gbnVsbDsKICAgICAgICAgICAgICAgIHRoaXMuY2xhc3NEZWYgPSBudWxsOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogU3BlY2lhbGl6ZWQgcGFzcyB0aGF0IHBlcmZvcm1zIHJlYWNoYWJpbGl0eSBhbmFseXNpcyBvbiBhIGxhbWJkYQogICAgICovCiAgICBjbGFzcyBMYW1iZGFBbGl2ZUFuYWx5emVyIGV4dGVuZHMgQWxpdmVBbmFseXplciB7CgogICAgICAgIGJvb2xlYW4gaW5MYW1iZGE7CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0UmV0dXJuKEpDUmV0dXJuIHRyZWUpIHsKICAgICAgICAgICAgLy9pZ25vcmUgbGFtYmRhIHJldHVybiBleHByZXNzaW9uICh3aGljaCBtaWdodCBub3QgZXZlbiBiZSBhdHRyaWJ1dGVkKQogICAgICAgICAgICByZWNvcmRFeGl0KG5ldyBQZW5kaW5nRXhpdCh0cmVlKSk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdExhbWJkYShKQ0xhbWJkYSB0cmVlKSB7CiAgICAgICAgICAgIGlmIChpbkxhbWJkYSB8fCB0cmVlLmdldEJvZHlLaW5kKCkgPT0gQm9keUtpbmQuRVhQUkVTU0lPTikgewogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGluTGFtYmRhID0gdHJ1ZTsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIHN1cGVyLnZpc2l0TGFtYmRhKHRyZWUpOwogICAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAgICAgaW5MYW1iZGEgPSBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRDbGFzc0RlZihKQ0NsYXNzRGVjbCB0cmVlKSB7CiAgICAgICAgICAgIC8vc2tpcAogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFNwZWNpYWxpemVkIHBhc3MgdGhhdCBwZXJmb3JtcyBEQS9EVSBvbiBhIGxhbWJkYQogICAgICovCiAgICBjbGFzcyBMYW1iZGFBc3NpZ25BbmFseXplciBleHRlbmRzIEFzc2lnbkFuYWx5emVyIHsKICAgICAgICBXcml0ZWFibGVTY29wZSBlbmNsb3NlZFN5bWJvbHM7CiAgICAgICAgYm9vbGVhbiBpbkxhbWJkYTsKCiAgICAgICAgTGFtYmRhQXNzaWduQW5hbHl6ZXIoRW52PEF0dHJDb250ZXh0PiBlbnYpIHsKICAgICAgICAgICAgZW5jbG9zZWRTeW1ib2xzID0gV3JpdGVhYmxlU2NvcGUuY3JlYXRlKGVudi5lbmNsQ2xhc3Muc3ltKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0TGFtYmRhKEpDTGFtYmRhIHRyZWUpIHsKICAgICAgICAgICAgaWYgKGluTGFtYmRhKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaW5MYW1iZGEgPSB0cnVlOwogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgc3VwZXIudmlzaXRMYW1iZGEodHJlZSk7CiAgICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgICAgICBpbkxhbWJkYSA9IGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdFZhckRlZihKQ1ZhcmlhYmxlRGVjbCB0cmVlKSB7CiAgICAgICAgICAgIGVuY2xvc2VkU3ltYm9scy5lbnRlcih0cmVlLnN5bSk7CiAgICAgICAgICAgIHN1cGVyLnZpc2l0VmFyRGVmKHRyZWUpOwogICAgICAgIH0KICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwcm90ZWN0ZWQgYm9vbGVhbiB0cmFja2FibGUoVmFyU3ltYm9sIHN5bSkgewogICAgICAgICAgICByZXR1cm4gZW5jbG9zZWRTeW1ib2xzLmluY2x1ZGVzKHN5bSkgJiYKICAgICAgICAgICAgICAgICAgIHN5bS5vd25lci5raW5kID09IE1USDsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0Q2xhc3NEZWYoSkNDbGFzc0RlY2wgdHJlZSkgewogICAgICAgICAgICAvL3NraXAKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBTcGVjaWFsaXplZCBwYXNzIHRoYXQgcGVyZm9ybXMgaW5mZXJlbmNlIG9mIHRocm93biB0eXBlcyBmb3IgbGFtYmRhcy4KICAgICAqLwogICAgY2xhc3MgTGFtYmRhRmxvd0FuYWx5emVyIGV4dGVuZHMgRmxvd0FuYWx5emVyIHsKICAgICAgICBMaXN0PFR5cGU+IGluZmVycmVkVGhyb3duVHlwZXM7CiAgICAgICAgYm9vbGVhbiBpbkxhbWJkYTsKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdExhbWJkYShKQ0xhbWJkYSB0cmVlKSB7CiAgICAgICAgICAgIGlmICgodHJlZS50eXBlICE9IG51bGwgJiYKICAgICAgICAgICAgICAgICAgICB0cmVlLnR5cGUuaXNFcnJvbmVvdXMoKSkgfHwgaW5MYW1iZGEpIHsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgICAgICBMaXN0PFR5cGU+IHByZXZDYXVnaHQgPSBjYXVnaHQ7CiAgICAgICAgICAgIExpc3Q8VHlwZT4gcHJldlRocm93biA9IHRocm93bjsKICAgICAgICAgICAgTGlzdEJ1ZmZlcjxGbG93UGVuZGluZ0V4aXQ+IHByZXZQZW5kaW5nID0gcGVuZGluZ0V4aXRzOwogICAgICAgICAgICBpbkxhbWJkYSA9IHRydWU7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBwZW5kaW5nRXhpdHMgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgICAgICBjYXVnaHQgPSBMaXN0Lm9mKHN5bXMudGhyb3dhYmxlVHlwZSk7CiAgICAgICAgICAgICAgICB0aHJvd24gPSBMaXN0Lm5pbCgpOwogICAgICAgICAgICAgICAgc2Nhbih0cmVlLmJvZHkpOwogICAgICAgICAgICAgICAgaW5mZXJyZWRUaHJvd25UeXBlcyA9IHRocm93bjsKICAgICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgICAgIHBlbmRpbmdFeGl0cyA9IHByZXZQZW5kaW5nOwogICAgICAgICAgICAgICAgY2F1Z2h0ID0gcHJldkNhdWdodDsKICAgICAgICAgICAgICAgIHRocm93biA9IHByZXZUaHJvd247CiAgICAgICAgICAgICAgICBpbkxhbWJkYSA9IGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0Q2xhc3NEZWYoSkNDbGFzc0RlY2wgdHJlZSkgewogICAgICAgICAgICAvL3NraXAKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBUaGlzIHBhc3MgaW1wbGVtZW50cyAoaSkgZGVmaW5pdGUgYXNzaWdubWVudCBhbmFseXNpcywgd2hpY2ggZW5zdXJlcyB0aGF0CiAgICAgKiBlYWNoIHZhcmlhYmxlIGlzIGFzc2lnbmVkIHdoZW4gdXNlZCBhbmQgKGlpKSBkZWZpbml0ZSB1bmFzc2lnbm1lbnQgYW5hbHlzaXMsCiAgICAgKiB3aGljaCBlbnN1cmVzIHRoYXQgbm8gZmluYWwgdmFyaWFibGUgaXMgYXNzaWduZWQgbW9yZSB0aGFuIG9uY2UuIFRoaXMgdmlzaXRvcgogICAgICogZGVwZW5kcyBvbiB0aGUgcmVzdWx0cyBvZiB0aGUgbGl2ZWxpbmVzcyBhbmFseXplci4gVGhpcyBwYXNzIGlzIGFsc28gdXNlZCB0byBtYXJrCiAgICAgKiBlZmZlY3RpdmVseS1maW5hbCBsb2NhbCB2YXJpYWJsZXMvcGFyYW1ldGVycy4KICAgICAqLwoKICAgIHB1YmxpYyBjbGFzcyBBc3NpZ25BbmFseXplciBleHRlbmRzIEJhc2VBbmFseXplcjxBc3NpZ25BbmFseXplci5Bc3NpZ25QZW5kaW5nRXhpdD4gewoKICAgICAgICAvKiogVGhlIHNldCBvZiBkZWZpbml0ZWx5IGFzc2lnbmVkIHZhcmlhYmxlcy4KICAgICAgICAgKi8KICAgICAgICBmaW5hbCBCaXRzIGluaXRzOwoKICAgICAgICAvKiogVGhlIHNldCBvZiBkZWZpbml0ZWx5IHVuYXNzaWduZWQgdmFyaWFibGVzLgogICAgICAgICAqLwogICAgICAgIGZpbmFsIEJpdHMgdW5pbml0czsKCiAgICAgICAgLyoqIFRoZSBzZXQgb2YgdmFyaWFibGVzIHRoYXQgYXJlIGRlZmluaXRlbHkgdW5hc3NpZ25lZCBldmVyeXdoZXJlCiAgICAgICAgICogIGluIGN1cnJlbnQgdHJ5IGJsb2NrLiBUaGlzIHZhcmlhYmxlIGlzIG1haW50YWluZWQgbGF6aWx5OyBpdCBpcwogICAgICAgICAqICB1cGRhdGVkIG9ubHkgd2hlbiBzb21ldGhpbmcgZ2V0cyByZW1vdmVkIGZyb20gdW5pbml0cywKICAgICAgICAgKiAgdHlwaWNhbGx5IGJ5IGJlaW5nIGFzc2lnbmVkIGluIHJlYWNoYWJsZSBjb2RlLiAgVG8gb2J0YWluIHRoZQogICAgICAgICAqICBjb3JyZWN0IHNldCBvZiB2YXJpYWJsZXMgd2hpY2ggYXJlIGRlZmluaXRlbHkgdW5hc3NpZ25lZAogICAgICAgICAqICBhbnl3aGVyZSBpbiBjdXJyZW50IHRyeSBibG9jaywgaW50ZXJzZWN0IHVuaW5pdHNUcnkgYW5kCiAgICAgICAgICogIHVuaW5pdHMuCiAgICAgICAgICovCiAgICAgICAgZmluYWwgQml0cyB1bmluaXRzVHJ5OwoKICAgICAgICAvKiogV2hlbiBhbmFseXppbmcgYSBjb25kaXRpb24sIGluaXRzIGFuZCB1bmluaXRzIGFyZSBudWxsLgogICAgICAgICAqICBJbnN0ZWFkIHdlIGhhdmU6CiAgICAgICAgICovCiAgICAgICAgZmluYWwgQml0cyBpbml0c1doZW5UcnVlOwogICAgICAgIGZpbmFsIEJpdHMgaW5pdHNXaGVuRmFsc2U7CiAgICAgICAgZmluYWwgQml0cyB1bmluaXRzV2hlblRydWU7CiAgICAgICAgZmluYWwgQml0cyB1bmluaXRzV2hlbkZhbHNlOwoKICAgICAgICAvKiogQSBtYXBwaW5nIGZyb20gYWRkcmVzc2VzIHRvIHZhcmlhYmxlIHN5bWJvbHMuCiAgICAgICAgICovCiAgICAgICAgcHJvdGVjdGVkIEpDVmFyaWFibGVEZWNsW10gdmFyZGVjbHM7CgogICAgICAgIC8qKiBUaGUgY3VycmVudCBjbGFzcyBiZWluZyBkZWZpbmVkLgogICAgICAgICAqLwogICAgICAgIEpDQ2xhc3NEZWNsIGNsYXNzRGVmOwoKICAgICAgICAvKiogVGhlIGZpcnN0IHZhcmlhYmxlIHNlcXVlbmNlIG51bWJlciBpbiB0aGlzIGNsYXNzIGRlZmluaXRpb24uCiAgICAgICAgICovCiAgICAgICAgaW50IGZpcnN0YWRyOwoKICAgICAgICAvKiogVGhlIG5leHQgYXZhaWxhYmxlIHZhcmlhYmxlIHNlcXVlbmNlIG51bWJlci4KICAgICAgICAgKi8KICAgICAgICBwcm90ZWN0ZWQgaW50IG5leHRhZHI7CgogICAgICAgIC8qKiBUaGUgZmlyc3QgdmFyaWFibGUgc2VxdWVuY2UgbnVtYmVyIGluIGEgYmxvY2sgdGhhdCBjYW4gcmV0dXJuLgogICAgICAgICAqLwogICAgICAgIHByb3RlY3RlZCBpbnQgcmV0dXJuYWRyOwoKICAgICAgICAvKiogVGhlIGxpc3Qgb2YgdW5yZWZlcmVuY2VkIGF1dG9tYXRpYyByZXNvdXJjZXMuCiAgICAgICAgICovCiAgICAgICAgV3JpdGVhYmxlU2NvcGUgdW5yZWZkUmVzb3VyY2VzOwoKICAgICAgICAvKiogTW9kaWZpZWQgd2hlbiBwcm9jZXNzaW5nIGEgbG9vcCBib2R5IHRoZSBzZWNvbmQgdGltZSBmb3IgRFUgYW5hbHlzaXMuICovCiAgICAgICAgRmxvd0tpbmQgZmxvd0tpbmQgPSBGbG93S2luZC5OT1JNQUw7CgogICAgICAgIC8qKiBUaGUgc3RhcnRpbmcgcG9zaXRpb24gb2YgdGhlIGFuYWx5emVkIHRyZWUgKi8KICAgICAgICBpbnQgc3RhcnRQb3M7CgogICAgICAgIHB1YmxpYyBjbGFzcyBBc3NpZ25QZW5kaW5nRXhpdCBleHRlbmRzIEJhc2VBbmFseXplci5QZW5kaW5nRXhpdCB7CgogICAgICAgICAgICBmaW5hbCBCaXRzIGluaXRzOwogICAgICAgICAgICBmaW5hbCBCaXRzIHVuaW5pdHM7CiAgICAgICAgICAgIGZpbmFsIEJpdHMgZXhpdF9pbml0cyA9IG5ldyBCaXRzKHRydWUpOwogICAgICAgICAgICBmaW5hbCBCaXRzIGV4aXRfdW5pbml0cyA9IG5ldyBCaXRzKHRydWUpOwoKICAgICAgICAgICAgcHVibGljIEFzc2lnblBlbmRpbmdFeGl0KEpDVHJlZSB0cmVlLCBmaW5hbCBCaXRzIGluaXRzLCBmaW5hbCBCaXRzIHVuaW5pdHMpIHsKICAgICAgICAgICAgICAgIHN1cGVyKHRyZWUpOwogICAgICAgICAgICAgICAgdGhpcy5pbml0cyA9IGluaXRzOwogICAgICAgICAgICAgICAgdGhpcy51bmluaXRzID0gdW5pbml0czsKICAgICAgICAgICAgICAgIHRoaXMuZXhpdF9pbml0cy5hc3NpZ24oaW5pdHMpOwogICAgICAgICAgICAgICAgdGhpcy5leGl0X3VuaW5pdHMuYXNzaWduKHVuaW5pdHMpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHVibGljIHZvaWQgcmVzb2x2ZUp1bXAoKSB7CiAgICAgICAgICAgICAgICBpbml0cy5hbmRTZXQoZXhpdF9pbml0cyk7CiAgICAgICAgICAgICAgICB1bmluaXRzLmFuZFNldChleGl0X3VuaW5pdHMpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgQXNzaWduQW5hbHl6ZXIoKSB7CiAgICAgICAgICAgIHRoaXMuaW5pdHMgPSBuZXcgQml0cygpOwogICAgICAgICAgICB1bmluaXRzID0gbmV3IEJpdHMoKTsKICAgICAgICAgICAgdW5pbml0c1RyeSA9IG5ldyBCaXRzKCk7CiAgICAgICAgICAgIGluaXRzV2hlblRydWUgPSBuZXcgQml0cyh0cnVlKTsKICAgICAgICAgICAgaW5pdHNXaGVuRmFsc2UgPSBuZXcgQml0cyh0cnVlKTsKICAgICAgICAgICAgdW5pbml0c1doZW5UcnVlID0gbmV3IEJpdHModHJ1ZSk7CiAgICAgICAgICAgIHVuaW5pdHNXaGVuRmFsc2UgPSBuZXcgQml0cyh0cnVlKTsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgYm9vbGVhbiBpc0luaXRpYWxDb25zdHJ1Y3RvciA9IGZhbHNlOwoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwcm90ZWN0ZWQgdm9pZCBtYXJrRGVhZCgpIHsKICAgICAgICAgICAgaWYgKCFpc0luaXRpYWxDb25zdHJ1Y3RvcikgewogICAgICAgICAgICAgICAgaW5pdHMuaW5jbFJhbmdlKHJldHVybmFkciwgbmV4dGFkcik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBmb3IgKGludCBhZGRyZXNzID0gcmV0dXJuYWRyOyBhZGRyZXNzIDwgbmV4dGFkcjsgYWRkcmVzcysrKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCEoaXNGaW5hbFVuaW5pdGlhbGl6ZWRTdGF0aWNGaWVsZCh2YXJkZWNsc1thZGRyZXNzXS5zeW0pKSkgewogICAgICAgICAgICAgICAgICAgICAgICBpbml0cy5pbmNsKGFkZHJlc3MpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICB1bmluaXRzLmluY2xSYW5nZShyZXR1cm5hZHIsIG5leHRhZHIpOwogICAgICAgIH0KCiAgICAgICAgLyotLS0tLS0tLS0tLS0tLSBQcm9jZXNzaW5nIHZhcmlhYmxlcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KCiAgICAgICAgLyoqIERvIHdlIG5lZWQgdG8gdHJhY2sgaW5pdC91bmluaXQgc3RhdGUgb2YgdGhpcyBzeW1ib2w/CiAgICAgICAgICogIEkuZS4gaXMgc3ltYm9sIGVpdGhlciBhIGxvY2FsIG9yIGEgYmxhbmsgZmluYWwgdmFyaWFibGU/CiAgICAgICAgICovCiAgICAgICAgcHJvdGVjdGVkIGJvb2xlYW4gdHJhY2thYmxlKFZhclN5bWJvbCBzeW0pIHsKICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgICAgICAgICBzeW0ucG9zID49IHN0YXJ0UG9zICYmCiAgICAgICAgICAgICAgICAoKHN5bS5vd25lci5raW5kID09IE1USCB8fAogICAgICAgICAgICAgICAgaXNGaW5hbFVuaW5pdGlhbGl6ZWRGaWVsZChzeW0pKSk7CiAgICAgICAgfQoKICAgICAgICBib29sZWFuIGlzRmluYWxVbmluaXRpYWxpemVkRmllbGQoVmFyU3ltYm9sIHN5bSkgewogICAgICAgICAgICByZXR1cm4gc3ltLm93bmVyLmtpbmQgPT0gVFlQICYmCiAgICAgICAgICAgICAgICAgICAoKHN5bS5mbGFncygpICYgKEZJTkFMIHwgSEFTSU5JVCB8IFBBUkFNRVRFUikpID09IEZJTkFMICYmCiAgICAgICAgICAgICAgICAgICBjbGFzc0RlZi5zeW0uaXNFbmNsb3NlZEJ5KChDbGFzc1N5bWJvbClzeW0ub3duZXIpKTsKICAgICAgICB9CgogICAgICAgIGJvb2xlYW4gaXNGaW5hbFVuaW5pdGlhbGl6ZWRTdGF0aWNGaWVsZChWYXJTeW1ib2wgc3ltKSB7CiAgICAgICAgICAgIHJldHVybiBpc0ZpbmFsVW5pbml0aWFsaXplZEZpZWxkKHN5bSkgJiYgc3ltLmlzU3RhdGljKCk7CiAgICAgICAgfQoKICAgICAgICAvKiogSW5pdGlhbGl6ZSBuZXcgdHJhY2thYmxlIHZhcmlhYmxlIGJ5IHNldHRpbmcgaXRzIGFkZHJlc3MgZmllbGQKICAgICAgICAgKiAgdG8gdGhlIG5leHQgYXZhaWxhYmxlIHNlcXVlbmNlIG51bWJlciBhbmQgZW50ZXJpbmcgaXQgdW5kZXIgdGhhdAogICAgICAgICAqICBpbmRleCBpbnRvIHRoZSB2YXJzIGFycmF5LgogICAgICAgICAqLwogICAgICAgIHZvaWQgbmV3VmFyKEpDVmFyaWFibGVEZWNsIHZhckRlY2wpIHsKICAgICAgICAgICAgVmFyU3ltYm9sIHN5bSA9IHZhckRlY2wuc3ltOwogICAgICAgICAgICB2YXJkZWNscyA9IEFycmF5VXRpbHMuZW5zdXJlQ2FwYWNpdHkodmFyZGVjbHMsIG5leHRhZHIpOwogICAgICAgICAgICBpZiAoKHN5bS5mbGFncygpICYgRklOQUwpID09IDApIHsKICAgICAgICAgICAgICAgIHN5bS5mbGFnc19maWVsZCB8PSBFRkZFQ1RJVkVMWV9GSU5BTDsKICAgICAgICAgICAgfQogICAgICAgICAgICBzeW0uYWRyID0gbmV4dGFkcjsKICAgICAgICAgICAgdmFyZGVjbHNbbmV4dGFkcl0gPSB2YXJEZWNsOwogICAgICAgICAgICBpbml0cy5leGNsKG5leHRhZHIpOwogICAgICAgICAgICB1bmluaXRzLmluY2wobmV4dGFkcik7CiAgICAgICAgICAgIG5leHRhZHIrKzsKICAgICAgICB9CgogICAgICAgIC8qKiBSZWNvcmQgYW4gaW5pdGlhbGl6YXRpb24gb2YgYSB0cmFja2FibGUgdmFyaWFibGUuCiAgICAgICAgICovCiAgICAgICAgdm9pZCBsZXRJbml0KERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIFZhclN5bWJvbCBzeW0pIHsKICAgICAgICAgICAgaWYgKHN5bS5hZHIgPj0gZmlyc3RhZHIgJiYgdHJhY2thYmxlKHN5bSkpIHsKICAgICAgICAgICAgICAgIGlmICgoc3ltLmZsYWdzKCkgJiBFRkZFQ1RJVkVMWV9GSU5BTCkgIT0gMCkgewogICAgICAgICAgICAgICAgICAgIGlmICghdW5pbml0cy5pc01lbWJlcihzeW0uYWRyKSkgewogICAgICAgICAgICAgICAgICAgICAgICAvL2Fzc2lnbm1lbnQgdGFyZ2V0aW5nIGFuIGVmZmVjdGl2ZWx5IGZpbmFsIHZhcmlhYmxlCiAgICAgICAgICAgICAgICAgICAgICAgIC8vbWFrZXMgdGhlIHZhcmlhYmxlIGxvc2UgaXRzIHN0YXR1cyBvZiBlZmZlY3RpdmVseSBmaW5hbAogICAgICAgICAgICAgICAgICAgICAgICAvL2lmIHRoZSB2YXJpYWJsZSBpcyBfbm90XyBkZWZpbml0aXZlbHkgdW5hc3NpZ25lZAogICAgICAgICAgICAgICAgICAgICAgICBzeW0uZmxhZ3NfZmllbGQgJj0gfkVGRkVDVElWRUxZX0ZJTkFMOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHVuaW5pdChzeW0pOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKChzeW0uZmxhZ3MoKSAmIEZJTkFMKSAhPSAwKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKChzeW0uZmxhZ3MoKSAmIFBBUkFNRVRFUikgIT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoKHN5bS5mbGFncygpICYgVU5JT04pICE9IDApIHsgLy9tdWx0aS1jYXRjaCBwYXJhbWV0ZXIKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZy5lcnJvcihwb3MsICJtdWx0aWNhdGNoLnBhcmFtZXRlci5tYXkubm90LmJlLmFzc2lnbmVkIiwgc3ltKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZy5lcnJvcihwb3MsICJmaW5hbC5wYXJhbWV0ZXIubWF5Lm5vdC5iZS5hc3NpZ25lZCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeW0pOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICghdW5pbml0cy5pc01lbWJlcihzeW0uYWRyKSkgewogICAgICAgICAgICAgICAgICAgICAgICBsb2cuZXJyb3IocG9zLCBmbG93S2luZC5lcnJLZXksIHN5bSk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgdW5pbml0KHN5bSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5pdHMuaW5jbChzeW0uYWRyKTsKICAgICAgICAgICAgfSBlbHNlIGlmICgoc3ltLmZsYWdzKCkgJiBGSU5BTCkgIT0gMCkgewogICAgICAgICAgICAgICAgbG9nLmVycm9yKHBvcywgInZhci5taWdodC5hbHJlYWR5LmJlLmFzc2lnbmVkIiwgc3ltKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvL3doZXJlCiAgICAgICAgICAgIHZvaWQgdW5pbml0KFZhclN5bWJvbCBzeW0pIHsKICAgICAgICAgICAgICAgIGlmICghaW5pdHMuaXNNZW1iZXIoc3ltLmFkcikpIHsKICAgICAgICAgICAgICAgICAgICAvLyByZWFjaGFibGUgYXNzaWdubWVudAogICAgICAgICAgICAgICAgICAgIHVuaW5pdHMuZXhjbChzeW0uYWRyKTsKICAgICAgICAgICAgICAgICAgICB1bmluaXRzVHJ5LmV4Y2woc3ltLmFkcik7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIC8vbG9nLnJhd1dhcm5pbmcocG9zLCAidW5yZWFjaGFibGUgYXNzaWdubWVudCIpOy8vREVCVUcKICAgICAgICAgICAgICAgICAgICB1bmluaXRzLmV4Y2woc3ltLmFkcik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgLyoqIElmIHRyZWUgaXMgZWl0aGVyIGEgc2ltcGxlIG5hbWUgb3Igb2YgdGhlIGZvcm0gdGhpcy5uYW1lIG9yCiAgICAgICAgICogIEMudGhpcy5uYW1lLCBhbmQgdHJlZSByZXByZXNlbnRzIGEgdHJhY2thYmxlIHZhcmlhYmxlLAogICAgICAgICAqICByZWNvcmQgYW4gaW5pdGlhbGl6YXRpb24gb2YgdGhlIHZhcmlhYmxlLgogICAgICAgICAqLwogICAgICAgIHZvaWQgbGV0SW5pdChKQ1RyZWUgdHJlZSkgewogICAgICAgICAgICB0cmVlID0gVHJlZUluZm8uc2tpcFBhcmVucyh0cmVlKTsKICAgICAgICAgICAgaWYgKHRyZWUuaGFzVGFnKElERU5UKSB8fCB0cmVlLmhhc1RhZyhTRUxFQ1QpKSB7CiAgICAgICAgICAgICAgICBTeW1ib2wgc3ltID0gVHJlZUluZm8uc3ltYm9sKHRyZWUpOwogICAgICAgICAgICAgICAgaWYgKHN5bS5raW5kID09IFZBUikgewogICAgICAgICAgICAgICAgICAgIGxldEluaXQodHJlZS5wb3MoKSwgKFZhclN5bWJvbClzeW0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvKiogQ2hlY2sgdGhhdCB0cmFja2FibGUgdmFyaWFibGUgaXMgaW5pdGlhbGl6ZWQuCiAgICAgICAgICovCiAgICAgICAgdm9pZCBjaGVja0luaXQoRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcywgVmFyU3ltYm9sIHN5bSkgewogICAgICAgICAgICBjaGVja0luaXQocG9zLCBzeW0sICJ2YXIubWlnaHQubm90LmhhdmUuYmVlbi5pbml0aWFsaXplZCIpOwogICAgICAgIH0KCiAgICAgICAgdm9pZCBjaGVja0luaXQoRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcywgVmFyU3ltYm9sIHN5bSwgU3RyaW5nIGVycmtleSkgewogICAgICAgICAgICBpZiAoKHN5bS5hZHIgPj0gZmlyc3RhZHIgfHwgc3ltLm93bmVyLmtpbmQgIT0gVFlQKSAmJgogICAgICAgICAgICAgICAgdHJhY2thYmxlKHN5bSkgJiYKICAgICAgICAgICAgICAgICFpbml0cy5pc01lbWJlcihzeW0uYWRyKSkgewogICAgICAgICAgICAgICAgbG9nLmVycm9yKHBvcywgZXJya2V5LCBzeW0pOwogICAgICAgICAgICAgICAgaW5pdHMuaW5jbChzeW0uYWRyKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLyoqIFV0aWxpdHkgbWV0aG9kIHRvIHJlc2V0IHNldmVyYWwgQml0cyBpbnN0YW5jZXMuCiAgICAgICAgICovCiAgICAgICAgcHJpdmF0ZSB2b2lkIHJlc2V0Qml0cyhCaXRzLi4uIGJpdHMpIHsKICAgICAgICAgICAgZm9yIChCaXRzIGIgOiBiaXRzKSB7CiAgICAgICAgICAgICAgICBiLnJlc2V0KCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8qKiBTcGxpdCAoZHVwbGljYXRlKSBpbml0cy91bmluaXRzIGludG8gV2hlblRydWUvV2hlbkZhbHNlIHNldHMKICAgICAgICAgKi8KICAgICAgICB2b2lkIHNwbGl0KGJvb2xlYW4gc2V0VG9OdWxsKSB7CiAgICAgICAgICAgIGluaXRzV2hlbkZhbHNlLmFzc2lnbihpbml0cyk7CiAgICAgICAgICAgIHVuaW5pdHNXaGVuRmFsc2UuYXNzaWduKHVuaW5pdHMpOwogICAgICAgICAgICBpbml0c1doZW5UcnVlLmFzc2lnbihpbml0cyk7CiAgICAgICAgICAgIHVuaW5pdHNXaGVuVHJ1ZS5hc3NpZ24odW5pbml0cyk7CiAgICAgICAgICAgIGlmIChzZXRUb051bGwpIHsKICAgICAgICAgICAgICAgIHJlc2V0Qml0cyhpbml0cywgdW5pbml0cyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8qKiBNZXJnZSAoaW50ZXJzZWN0KSBpbml0cy91bmluaXRzIGZyb20gV2hlblRydWUvV2hlbkZhbHNlIHNldHMuCiAgICAgICAgICovCiAgICAgICAgcHJvdGVjdGVkIHZvaWQgbWVyZ2UoKSB7CiAgICAgICAgICAgIGluaXRzLmFzc2lnbihpbml0c1doZW5GYWxzZS5hbmRTZXQoaW5pdHNXaGVuVHJ1ZSkpOwogICAgICAgICAgICB1bmluaXRzLmFzc2lnbih1bmluaXRzV2hlbkZhbHNlLmFuZFNldCh1bmluaXRzV2hlblRydWUpKTsKICAgICAgICB9CgogICAgLyogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAgICAgKiBWaXNpdG9yIG1ldGhvZHMgZm9yIHN0YXRlbWVudHMgYW5kIGRlZmluaXRpb25zCiAgICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiAgICAgICAgLyoqIEFuYWx5emUgYW4gZXhwcmVzc2lvbi4gTWFrZSBzdXJlIHRvIHNldCAodW4paW5pdHMgcmF0aGVyIHRoYW4KICAgICAgICAgKiAgKHVuKWluaXRzV2hlblRydWUoV2hlbkZhbHNlKSBvbiBleGl0LgogICAgICAgICAqLwogICAgICAgIHZvaWQgc2NhbkV4cHIoSkNUcmVlIHRyZWUpIHsKICAgICAgICAgICAgaWYgKHRyZWUgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgc2Nhbih0cmVlKTsKICAgICAgICAgICAgICAgIGlmIChpbml0cy5pc1Jlc2V0KCkpIHsKICAgICAgICAgICAgICAgICAgICBtZXJnZSgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvKiogQW5hbHl6ZSBhIGxpc3Qgb2YgZXhwcmVzc2lvbnMuCiAgICAgICAgICovCiAgICAgICAgdm9pZCBzY2FuRXhwcnMoTGlzdDw/IGV4dGVuZHMgSkNFeHByZXNzaW9uPiB0cmVlcykgewogICAgICAgICAgICBpZiAodHJlZXMgIT0gbnVsbCkKICAgICAgICAgICAgICAgIGZvciAoTGlzdDw/IGV4dGVuZHMgSkNFeHByZXNzaW9uPiBsID0gdHJlZXM7IGwubm9uRW1wdHkoKTsgbCA9IGwudGFpbCkKICAgICAgICAgICAgICAgICAgICBzY2FuRXhwcihsLmhlYWQpOwogICAgICAgIH0KCiAgICAgICAgLyoqIEFuYWx5emUgYSBjb25kaXRpb24uIE1ha2Ugc3VyZSB0byBzZXQgKHVuKWluaXRzV2hlblRydWUoV2hlbkZhbHNlKQogICAgICAgICAqICByYXRoZXIgdGhhbiAodW4paW5pdHMgb24gZXhpdC4KICAgICAgICAgKi8KICAgICAgICB2b2lkIHNjYW5Db25kKEpDVHJlZSB0cmVlKSB7CiAgICAgICAgICAgIGlmICh0cmVlLnR5cGUuaXNGYWxzZSgpKSB7CiAgICAgICAgICAgICAgICBpZiAoaW5pdHMuaXNSZXNldCgpKSBtZXJnZSgpOwogICAgICAgICAgICAgICAgaW5pdHNXaGVuVHJ1ZS5hc3NpZ24oaW5pdHMpOwogICAgICAgICAgICAgICAgaW5pdHNXaGVuVHJ1ZS5pbmNsUmFuZ2UoZmlyc3RhZHIsIG5leHRhZHIpOwogICAgICAgICAgICAgICAgdW5pbml0c1doZW5UcnVlLmFzc2lnbih1bmluaXRzKTsKICAgICAgICAgICAgICAgIHVuaW5pdHNXaGVuVHJ1ZS5pbmNsUmFuZ2UoZmlyc3RhZHIsIG5leHRhZHIpOwogICAgICAgICAgICAgICAgaW5pdHNXaGVuRmFsc2UuYXNzaWduKGluaXRzKTsKICAgICAgICAgICAgICAgIHVuaW5pdHNXaGVuRmFsc2UuYXNzaWduKHVuaW5pdHMpOwogICAgICAgICAgICB9IGVsc2UgaWYgKHRyZWUudHlwZS5pc1RydWUoKSkgewogICAgICAgICAgICAgICAgaWYgKGluaXRzLmlzUmVzZXQoKSkgbWVyZ2UoKTsKICAgICAgICAgICAgICAgIGluaXRzV2hlbkZhbHNlLmFzc2lnbihpbml0cyk7CiAgICAgICAgICAgICAgICBpbml0c1doZW5GYWxzZS5pbmNsUmFuZ2UoZmlyc3RhZHIsIG5leHRhZHIpOwogICAgICAgICAgICAgICAgdW5pbml0c1doZW5GYWxzZS5hc3NpZ24odW5pbml0cyk7CiAgICAgICAgICAgICAgICB1bmluaXRzV2hlbkZhbHNlLmluY2xSYW5nZShmaXJzdGFkciwgbmV4dGFkcik7CiAgICAgICAgICAgICAgICBpbml0c1doZW5UcnVlLmFzc2lnbihpbml0cyk7CiAgICAgICAgICAgICAgICB1bmluaXRzV2hlblRydWUuYXNzaWduKHVuaW5pdHMpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgc2Nhbih0cmVlKTsKICAgICAgICAgICAgICAgIGlmICghaW5pdHMuaXNSZXNldCgpKQogICAgICAgICAgICAgICAgICAgIHNwbGl0KHRyZWUudHlwZSAhPSBzeW1zLnVua25vd25UeXBlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAodHJlZS50eXBlICE9IHN5bXMudW5rbm93blR5cGUpIHsKICAgICAgICAgICAgICAgIHJlc2V0Qml0cyhpbml0cywgdW5pbml0cyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8qIC0tLS0tLS0tLS0tLSBWaXNpdG9yIG1ldGhvZHMgZm9yIHZhcmlvdXMgc29ydHMgb2YgdHJlZXMgLS0tLS0tLS0tLS0tLSovCgogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0Q2xhc3NEZWYoSkNDbGFzc0RlY2wgdHJlZSkgewogICAgICAgICAgICBpZiAodHJlZS5zeW0gPT0gbnVsbCkgewogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CgogICAgICAgICAgICBMaW50IGxpbnRQcmV2ID0gbGludDsKICAgICAgICAgICAgbGludCA9IGxpbnQuYXVnbWVudCh0cmVlLnN5bSk7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBpZiAodHJlZS5zeW0gPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBKQ0NsYXNzRGVjbCBjbGFzc0RlZlByZXYgPSBjbGFzc0RlZjsKICAgICAgICAgICAgICAgIGludCBmaXJzdGFkclByZXYgPSBmaXJzdGFkcjsKICAgICAgICAgICAgICAgIGludCBuZXh0YWRyUHJldiA9IG5leHRhZHI7CiAgICAgICAgICAgICAgICBMaXN0QnVmZmVyPEFzc2lnblBlbmRpbmdFeGl0PiBwZW5kaW5nRXhpdHNQcmV2ID0gcGVuZGluZ0V4aXRzOwoKICAgICAgICAgICAgICAgIHBlbmRpbmdFeGl0cyA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICAgICAgICAgIGlmICh0cmVlLm5hbWUgIT0gbmFtZXMuZW1wdHkpIHsKICAgICAgICAgICAgICAgICAgICBmaXJzdGFkciA9IG5leHRhZHI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBjbGFzc0RlZiA9IHRyZWU7CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIC8vIGRlZmluZSBhbGwgdGhlIHN0YXRpYyBmaWVsZHMKICAgICAgICAgICAgICAgICAgICBmb3IgKExpc3Q8SkNUcmVlPiBsID0gdHJlZS5kZWZzOyBsLm5vbkVtcHR5KCk7IGwgPSBsLnRhaWwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGwuaGVhZC5oYXNUYWcoVkFSREVGKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgSkNWYXJpYWJsZURlY2wgZGVmID0gKEpDVmFyaWFibGVEZWNsKWwuaGVhZDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgoZGVmLm1vZHMuZmxhZ3MgJiBTVEFUSUMpICE9IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWYXJTeW1ib2wgc3ltID0gZGVmLnN5bTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodHJhY2thYmxlKHN5bSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3VmFyKGRlZik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAvLyBwcm9jZXNzIGFsbCB0aGUgc3RhdGljIGluaXRpYWxpemVycwogICAgICAgICAgICAgICAgICAgIGZvciAoTGlzdDxKQ1RyZWU+IGwgPSB0cmVlLmRlZnM7IGwubm9uRW1wdHkoKTsgbCA9IGwudGFpbCkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWwuaGVhZC5oYXNUYWcoTUVUSE9EREVGKSAmJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgKFRyZWVJbmZvLmZsYWdzKGwuaGVhZCkgJiBTVEFUSUMpICE9IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjYW4obC5oZWFkKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gZGVmaW5lIGFsbCB0aGUgaW5zdGFuY2UgZmllbGRzCiAgICAgICAgICAgICAgICAgICAgZm9yIChMaXN0PEpDVHJlZT4gbCA9IHRyZWUuZGVmczsgbC5ub25FbXB0eSgpOyBsID0gbC50YWlsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChsLmhlYWQuaGFzVGFnKFZBUkRFRikpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEpDVmFyaWFibGVEZWNsIGRlZiA9IChKQ1ZhcmlhYmxlRGVjbClsLmhlYWQ7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoKGRlZi5tb2RzLmZsYWdzICYgU1RBVElDKSA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVmFyU3ltYm9sIHN5bSA9IGRlZi5zeW07CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRyYWNrYWJsZShzeW0pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld1ZhcihkZWYpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gcHJvY2VzcyBhbGwgdGhlIGluc3RhbmNlIGluaXRpYWxpemVycwogICAgICAgICAgICAgICAgICAgIGZvciAoTGlzdDxKQ1RyZWU+IGwgPSB0cmVlLmRlZnM7IGwubm9uRW1wdHkoKTsgbCA9IGwudGFpbCkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWwuaGVhZC5oYXNUYWcoTUVUSE9EREVGKSAmJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgKFRyZWVJbmZvLmZsYWdzKGwuaGVhZCkgJiBTVEFUSUMpID09IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjYW4obC5oZWFkKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gcHJvY2VzcyBhbGwgdGhlIG1ldGhvZHMKICAgICAgICAgICAgICAgICAgICBmb3IgKExpc3Q8SkNUcmVlPiBsID0gdHJlZS5kZWZzOyBsLm5vbkVtcHR5KCk7IGwgPSBsLnRhaWwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGwuaGVhZC5oYXNUYWcoTUVUSE9EREVGKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NhbihsLmhlYWQpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgICAgICAgICBwZW5kaW5nRXhpdHMgPSBwZW5kaW5nRXhpdHNQcmV2OwogICAgICAgICAgICAgICAgICAgIG5leHRhZHIgPSBuZXh0YWRyUHJldjsKICAgICAgICAgICAgICAgICAgICBmaXJzdGFkciA9IGZpcnN0YWRyUHJldjsKICAgICAgICAgICAgICAgICAgICBjbGFzc0RlZiA9IGNsYXNzRGVmUHJldjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgICAgIGxpbnQgPSBsaW50UHJldjsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRNZXRob2REZWYoSkNNZXRob2REZWNsIHRyZWUpIHsKICAgICAgICAgICAgaWYgKHRyZWUuYm9keSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qICBNZW1iZXJFbnRlciBjYW4gZ2VuZXJhdGUgc3ludGhldGljIG1ldGhvZHMgaWdub3JlIHRoZW0KICAgICAgICAgICAgICovCiAgICAgICAgICAgIGlmICgodHJlZS5zeW0uZmxhZ3MoKSAmIFNZTlRIRVRJQykgIT0gMCkgewogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CgogICAgICAgICAgICBMaW50IGxpbnRQcmV2ID0gbGludDsKICAgICAgICAgICAgbGludCA9IGxpbnQuYXVnbWVudCh0cmVlLnN5bSk7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBpZiAodHJlZS5ib2R5ID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvKiAgSWdub3JlIHN5bnRoZXRpYyBtZXRob2RzLCBleGNlcHQgZm9yIHRyYW5zbGF0ZWQgbGFtYmRhIG1ldGhvZHMuCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIGlmICgodHJlZS5zeW0uZmxhZ3MoKSAmIChTWU5USEVUSUMgfCBMQU1CREFfTUVUSE9EKSkgPT0gU1lOVEhFVElDKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGZpbmFsIEJpdHMgaW5pdHNQcmV2ID0gbmV3IEJpdHMoaW5pdHMpOwogICAgICAgICAgICAgICAgZmluYWwgQml0cyB1bmluaXRzUHJldiA9IG5ldyBCaXRzKHVuaW5pdHMpOwogICAgICAgICAgICAgICAgaW50IG5leHRhZHJQcmV2ID0gbmV4dGFkcjsKICAgICAgICAgICAgICAgIGludCBmaXJzdGFkclByZXYgPSBmaXJzdGFkcjsKICAgICAgICAgICAgICAgIGludCByZXR1cm5hZHJQcmV2ID0gcmV0dXJuYWRyOwoKICAgICAgICAgICAgICAgIEFzc2VydC5jaGVjayhwZW5kaW5nRXhpdHMuaXNFbXB0eSgpKTsKICAgICAgICAgICAgICAgIGJvb2xlYW4gbGFzdEluaXRpYWxDb25zdHJ1Y3RvciA9IGlzSW5pdGlhbENvbnN0cnVjdG9yOwogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICBpc0luaXRpYWxDb25zdHJ1Y3RvciA9IFRyZWVJbmZvLmlzSW5pdGlhbENvbnN0cnVjdG9yKHRyZWUpOwoKICAgICAgICAgICAgICAgICAgICBpZiAoIWlzSW5pdGlhbENvbnN0cnVjdG9yKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGZpcnN0YWRyID0gbmV4dGFkcjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZm9yIChMaXN0PEpDVmFyaWFibGVEZWNsPiBsID0gdHJlZS5wYXJhbXM7IGwubm9uRW1wdHkoKTsgbCA9IGwudGFpbCkgewogICAgICAgICAgICAgICAgICAgICAgICBKQ1ZhcmlhYmxlRGVjbCBkZWYgPSBsLmhlYWQ7CiAgICAgICAgICAgICAgICAgICAgICAgIHNjYW4oZGVmKTsKICAgICAgICAgICAgICAgICAgICAgICAgQXNzZXJ0LmNoZWNrKChkZWYuc3ltLmZsYWdzKCkgJiBQQVJBTUVURVIpICE9IDAsICJNZXRob2QgcGFyYW1ldGVyIHdpdGhvdXQgUEFSQU1FVEVSIGZsYWciKTsKICAgICAgICAgICAgICAgICAgICAgICAgLyogIElmIHdlIGFyZSBleGVjdXRpbmcgdGhlIGNvZGUgZnJvbSBHZW4sIHRoZW4gdGhlcmUgY2FuIGJlCiAgICAgICAgICAgICAgICAgICAgICAgICAqICBzeW50aGV0aWMgb3IgbWFuZGF0ZWQgdmFyaWFibGVzLCBpZ25vcmUgdGhlbS4KICAgICAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgICAgIGluaXRQYXJhbShkZWYpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAvLyBlbHNlIHdlIGFyZSBpbiBhbiBpbnN0YW5jZSBpbml0aWFsaXplciBibG9jazsKICAgICAgICAgICAgICAgICAgICAvLyBsZWF2ZSBjYXVnaHQgdW5jaGFuZ2VkLgogICAgICAgICAgICAgICAgICAgIHNjYW4odHJlZS5ib2R5KTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKGlzSW5pdGlhbENvbnN0cnVjdG9yKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gaXNTeW50aGVzaXplZCA9ICh0cmVlLnN5bS5mbGFncygpICYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdFTkVSQVRFRENPTlNUUikgIT0gMDsKICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IGZpcnN0YWRyOyBpIDwgbmV4dGFkcjsgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBKQ1ZhcmlhYmxlRGVjbCB2YXJkZWNsID0gdmFyZGVjbHNbaV07CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBWYXJTeW1ib2wgdmFyID0gdmFyZGVjbC5zeW07CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodmFyLm93bmVyID09IGNsYXNzRGVmLnN5bSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNob29zZSB0aGUgZGlhZ25vc3RpYyBwb3NpdGlvbiBiYXNlZCBvbiB3aGV0aGVyCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhlIGN0b3IgaXMgZGVmYXVsdChzeW50aGVzaXplZCkgb3Igbm90CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzU3ludGhlc2l6ZWQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tJbml0KFRyZWVJbmZvLmRpYWdub3N0aWNQb3NpdGlvbkZvcih2YXIsIHZhcmRlY2wpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyLCAidmFyLm5vdC5pbml0aWFsaXplZC5pbi5kZWZhdWx0LmNvbnN0cnVjdG9yIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tJbml0KFRyZWVJbmZvLmRpYWdFbmRQb3ModHJlZS5ib2R5KSwgdmFyKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgTGlzdDxBc3NpZ25QZW5kaW5nRXhpdD4gZXhpdHMgPSBwZW5kaW5nRXhpdHMudG9MaXN0KCk7CiAgICAgICAgICAgICAgICAgICAgcGVuZGluZ0V4aXRzID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgICAgICAgICAgICAgIHdoaWxlIChleGl0cy5ub25FbXB0eSgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIEFzc2lnblBlbmRpbmdFeGl0IGV4aXQgPSBleGl0cy5oZWFkOwogICAgICAgICAgICAgICAgICAgICAgICBleGl0cyA9IGV4aXRzLnRhaWw7CiAgICAgICAgICAgICAgICAgICAgICAgIEFzc2VydC5jaGVjayhleGl0LnRyZWUuaGFzVGFnKFJFVFVSTiksIGV4aXQudHJlZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc0luaXRpYWxDb25zdHJ1Y3RvcikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5pdHMuYXNzaWduKGV4aXQuZXhpdF9pbml0cyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gZmlyc3RhZHI7IGkgPCBuZXh0YWRyOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGVja0luaXQoZXhpdC50cmVlLnBvcygpLCB2YXJkZWNsc1tpXS5zeW0pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgICAgICAgICBpbml0cy5hc3NpZ24oaW5pdHNQcmV2KTsKICAgICAgICAgICAgICAgICAgICB1bmluaXRzLmFzc2lnbih1bmluaXRzUHJldik7CiAgICAgICAgICAgICAgICAgICAgbmV4dGFkciA9IG5leHRhZHJQcmV2OwogICAgICAgICAgICAgICAgICAgIGZpcnN0YWRyID0gZmlyc3RhZHJQcmV2OwogICAgICAgICAgICAgICAgICAgIHJldHVybmFkciA9IHJldHVybmFkclByZXY7CiAgICAgICAgICAgICAgICAgICAgaXNJbml0aWFsQ29uc3RydWN0b3IgPSBsYXN0SW5pdGlhbENvbnN0cnVjdG9yOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAgICAgbGludCA9IGxpbnRQcmV2OwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwcm90ZWN0ZWQgdm9pZCBpbml0UGFyYW0oSkNWYXJpYWJsZURlY2wgZGVmKSB7CiAgICAgICAgICAgIGluaXRzLmluY2woZGVmLnN5bS5hZHIpOwogICAgICAgICAgICB1bmluaXRzLmV4Y2woZGVmLnN5bS5hZHIpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRWYXJEZWYoSkNWYXJpYWJsZURlY2wgdHJlZSkgewogICAgICAgICAgICBMaW50IGxpbnRQcmV2ID0gbGludDsKICAgICAgICAgICAgbGludCA9IGxpbnQuYXVnbWVudCh0cmVlLnN5bSk7CiAgICAgICAgICAgIHRyeXsKICAgICAgICAgICAgICAgIGJvb2xlYW4gdHJhY2sgPSB0cmFja2FibGUodHJlZS5zeW0pOwogICAgICAgICAgICAgICAgaWYgKHRyYWNrICYmIHRyZWUuc3ltLm93bmVyLmtpbmQgPT0gTVRIKSB7CiAgICAgICAgICAgICAgICAgICAgbmV3VmFyKHRyZWUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKHRyZWUuaW5pdCAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgc2NhbkV4cHIodHJlZS5pbml0KTsKICAgICAgICAgICAgICAgICAgICBpZiAodHJhY2spIHsKICAgICAgICAgICAgICAgICAgICAgICAgbGV0SW5pdCh0cmVlLnBvcygpLCB0cmVlLnN5bSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAgICAgbGludCA9IGxpbnRQcmV2OwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdEJsb2NrKEpDQmxvY2sgdHJlZSkgewogICAgICAgICAgICBpbnQgbmV4dGFkclByZXYgPSBuZXh0YWRyOwogICAgICAgICAgICBzY2FuKHRyZWUuc3RhdHMpOwogICAgICAgICAgICBuZXh0YWRyID0gbmV4dGFkclByZXY7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdERvTG9vcChKQ0RvV2hpbGVMb29wIHRyZWUpIHsKICAgICAgICAgICAgTGlzdEJ1ZmZlcjxBc3NpZ25QZW5kaW5nRXhpdD4gcHJldlBlbmRpbmdFeGl0cyA9IHBlbmRpbmdFeGl0czsKICAgICAgICAgICAgRmxvd0tpbmQgcHJldkZsb3dLaW5kID0gZmxvd0tpbmQ7CiAgICAgICAgICAgIGZsb3dLaW5kID0gRmxvd0tpbmQuTk9STUFMOwogICAgICAgICAgICBmaW5hbCBCaXRzIGluaXRzU2tpcCA9IG5ldyBCaXRzKHRydWUpOwogICAgICAgICAgICBmaW5hbCBCaXRzIHVuaW5pdHNTa2lwID0gbmV3IEJpdHModHJ1ZSk7CiAgICAgICAgICAgIHBlbmRpbmdFeGl0cyA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICAgICAgaW50IHByZXZFcnJvcnMgPSBsb2cubmVycm9yczsKICAgICAgICAgICAgZG8gewogICAgICAgICAgICAgICAgZmluYWwgQml0cyB1bmluaXRzRW50cnkgPSBuZXcgQml0cyh1bmluaXRzKTsKICAgICAgICAgICAgICAgIHVuaW5pdHNFbnRyeS5leGNsdWRlRnJvbShuZXh0YWRyKTsKICAgICAgICAgICAgICAgIHNjYW4odHJlZS5ib2R5KTsKICAgICAgICAgICAgICAgIHJlc29sdmVDb250aW51ZXModHJlZSk7CiAgICAgICAgICAgICAgICBzY2FuQ29uZCh0cmVlLmNvbmQpOwogICAgICAgICAgICAgICAgaWYgKCFmbG93S2luZC5pc0ZpbmFsKCkpIHsKICAgICAgICAgICAgICAgICAgICBpbml0c1NraXAuYXNzaWduKGluaXRzV2hlbkZhbHNlKTsKICAgICAgICAgICAgICAgICAgICB1bmluaXRzU2tpcC5hc3NpZ24odW5pbml0c1doZW5GYWxzZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAobG9nLm5lcnJvcnMgIT0gIHByZXZFcnJvcnMgfHwKICAgICAgICAgICAgICAgICAgICBmbG93S2luZC5pc0ZpbmFsKCkgfHwKICAgICAgICAgICAgICAgICAgICBuZXcgQml0cyh1bmluaXRzRW50cnkpLmRpZmZTZXQodW5pbml0c1doZW5UcnVlKS5uZXh0Qml0KGZpcnN0YWRyKT09LTEpCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBpbml0cy5hc3NpZ24oaW5pdHNXaGVuVHJ1ZSk7CiAgICAgICAgICAgICAgICB1bmluaXRzLmFzc2lnbih1bmluaXRzRW50cnkuYW5kU2V0KHVuaW5pdHNXaGVuVHJ1ZSkpOwogICAgICAgICAgICAgICAgZmxvd0tpbmQgPSBGbG93S2luZC5TUEVDVUxBVElWRV9MT09QOwogICAgICAgICAgICB9IHdoaWxlICh0cnVlKTsKICAgICAgICAgICAgZmxvd0tpbmQgPSBwcmV2Rmxvd0tpbmQ7CiAgICAgICAgICAgIGluaXRzLmFzc2lnbihpbml0c1NraXApOwogICAgICAgICAgICB1bmluaXRzLmFzc2lnbih1bmluaXRzU2tpcCk7CiAgICAgICAgICAgIHJlc29sdmVCcmVha3ModHJlZSwgcHJldlBlbmRpbmdFeGl0cyk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdFdoaWxlTG9vcChKQ1doaWxlTG9vcCB0cmVlKSB7CiAgICAgICAgICAgIExpc3RCdWZmZXI8QXNzaWduUGVuZGluZ0V4aXQ+IHByZXZQZW5kaW5nRXhpdHMgPSBwZW5kaW5nRXhpdHM7CiAgICAgICAgICAgIEZsb3dLaW5kIHByZXZGbG93S2luZCA9IGZsb3dLaW5kOwogICAgICAgICAgICBmbG93S2luZCA9IEZsb3dLaW5kLk5PUk1BTDsKICAgICAgICAgICAgZmluYWwgQml0cyBpbml0c1NraXAgPSBuZXcgQml0cyh0cnVlKTsKICAgICAgICAgICAgZmluYWwgQml0cyB1bmluaXRzU2tpcCA9IG5ldyBCaXRzKHRydWUpOwogICAgICAgICAgICBwZW5kaW5nRXhpdHMgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgIGludCBwcmV2RXJyb3JzID0gbG9nLm5lcnJvcnM7CiAgICAgICAgICAgIGZpbmFsIEJpdHMgdW5pbml0c0VudHJ5ID0gbmV3IEJpdHModW5pbml0cyk7CiAgICAgICAgICAgIHVuaW5pdHNFbnRyeS5leGNsdWRlRnJvbShuZXh0YWRyKTsKICAgICAgICAgICAgZG8gewogICAgICAgICAgICAgICAgc2NhbkNvbmQodHJlZS5jb25kKTsKICAgICAgICAgICAgICAgIGlmICghZmxvd0tpbmQuaXNGaW5hbCgpKSB7CiAgICAgICAgICAgICAgICAgICAgaW5pdHNTa2lwLmFzc2lnbihpbml0c1doZW5GYWxzZSkgOwogICAgICAgICAgICAgICAgICAgIHVuaW5pdHNTa2lwLmFzc2lnbih1bmluaXRzV2hlbkZhbHNlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGluaXRzLmFzc2lnbihpbml0c1doZW5UcnVlKTsKICAgICAgICAgICAgICAgIHVuaW5pdHMuYXNzaWduKHVuaW5pdHNXaGVuVHJ1ZSk7CiAgICAgICAgICAgICAgICBzY2FuKHRyZWUuYm9keSk7CiAgICAgICAgICAgICAgICByZXNvbHZlQ29udGludWVzKHRyZWUpOwogICAgICAgICAgICAgICAgaWYgKGxvZy5uZXJyb3JzICE9IHByZXZFcnJvcnMgfHwKICAgICAgICAgICAgICAgICAgICBmbG93S2luZC5pc0ZpbmFsKCkgfHwKICAgICAgICAgICAgICAgICAgICBuZXcgQml0cyh1bmluaXRzRW50cnkpLmRpZmZTZXQodW5pbml0cykubmV4dEJpdChmaXJzdGFkcikgPT0gLTEpIHsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHVuaW5pdHMuYXNzaWduKHVuaW5pdHNFbnRyeS5hbmRTZXQodW5pbml0cykpOwogICAgICAgICAgICAgICAgZmxvd0tpbmQgPSBGbG93S2luZC5TUEVDVUxBVElWRV9MT09QOwogICAgICAgICAgICB9IHdoaWxlICh0cnVlKTsKICAgICAgICAgICAgZmxvd0tpbmQgPSBwcmV2Rmxvd0tpbmQ7CiAgICAgICAgICAgIC8vYSB2YXJpYWJsZSBpcyBEQS9EVSBhZnRlciB0aGUgd2hpbGUgc3RhdGVtZW50LCBpZiBpdCdzIERBL0RVIGFzc3VtaW5nIHRoZQogICAgICAgICAgICAvL2JyYW5jaCBpcyBub3QgdGFrZW4gQU5EIGlmIGl0J3MgREEvRFUgYmVmb3JlIGFueSBicmVhayBzdGF0ZW1lbnQKICAgICAgICAgICAgaW5pdHMuYXNzaWduKGluaXRzU2tpcCk7CiAgICAgICAgICAgIHVuaW5pdHMuYXNzaWduKHVuaW5pdHNTa2lwKTsKICAgICAgICAgICAgcmVzb2x2ZUJyZWFrcyh0cmVlLCBwcmV2UGVuZGluZ0V4aXRzKTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0Rm9yTG9vcChKQ0Zvckxvb3AgdHJlZSkgewogICAgICAgICAgICBMaXN0QnVmZmVyPEFzc2lnblBlbmRpbmdFeGl0PiBwcmV2UGVuZGluZ0V4aXRzID0gcGVuZGluZ0V4aXRzOwogICAgICAgICAgICBGbG93S2luZCBwcmV2Rmxvd0tpbmQgPSBmbG93S2luZDsKICAgICAgICAgICAgZmxvd0tpbmQgPSBGbG93S2luZC5OT1JNQUw7CiAgICAgICAgICAgIGludCBuZXh0YWRyUHJldiA9IG5leHRhZHI7CiAgICAgICAgICAgIHNjYW4odHJlZS5pbml0KTsKICAgICAgICAgICAgZmluYWwgQml0cyBpbml0c1NraXAgPSBuZXcgQml0cyh0cnVlKTsKICAgICAgICAgICAgZmluYWwgQml0cyB1bmluaXRzU2tpcCA9IG5ldyBCaXRzKHRydWUpOwogICAgICAgICAgICBwZW5kaW5nRXhpdHMgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgIGludCBwcmV2RXJyb3JzID0gbG9nLm5lcnJvcnM7CiAgICAgICAgICAgIGRvIHsKICAgICAgICAgICAgICAgIGZpbmFsIEJpdHMgdW5pbml0c0VudHJ5ID0gbmV3IEJpdHModW5pbml0cyk7CiAgICAgICAgICAgICAgICB1bmluaXRzRW50cnkuZXhjbHVkZUZyb20obmV4dGFkcik7CiAgICAgICAgICAgICAgICBpZiAodHJlZS5jb25kICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICBzY2FuQ29uZCh0cmVlLmNvbmQpOwogICAgICAgICAgICAgICAgICAgIGlmICghZmxvd0tpbmQuaXNGaW5hbCgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGluaXRzU2tpcC5hc3NpZ24oaW5pdHNXaGVuRmFsc2UpOwogICAgICAgICAgICAgICAgICAgICAgICB1bmluaXRzU2tpcC5hc3NpZ24odW5pbml0c1doZW5GYWxzZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGluaXRzLmFzc2lnbihpbml0c1doZW5UcnVlKTsKICAgICAgICAgICAgICAgICAgICB1bmluaXRzLmFzc2lnbih1bmluaXRzV2hlblRydWUpOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmICghZmxvd0tpbmQuaXNGaW5hbCgpKSB7CiAgICAgICAgICAgICAgICAgICAgaW5pdHNTa2lwLmFzc2lnbihpbml0cyk7CiAgICAgICAgICAgICAgICAgICAgaW5pdHNTa2lwLmluY2xSYW5nZShmaXJzdGFkciwgbmV4dGFkcik7CiAgICAgICAgICAgICAgICAgICAgdW5pbml0c1NraXAuYXNzaWduKHVuaW5pdHMpOwogICAgICAgICAgICAgICAgICAgIHVuaW5pdHNTa2lwLmluY2xSYW5nZShmaXJzdGFkciwgbmV4dGFkcik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBzY2FuKHRyZWUuYm9keSk7CiAgICAgICAgICAgICAgICByZXNvbHZlQ29udGludWVzKHRyZWUpOwogICAgICAgICAgICAgICAgc2Nhbih0cmVlLnN0ZXApOwogICAgICAgICAgICAgICAgaWYgKGxvZy5uZXJyb3JzICE9IHByZXZFcnJvcnMgfHwKICAgICAgICAgICAgICAgICAgICBmbG93S2luZC5pc0ZpbmFsKCkgfHwKICAgICAgICAgICAgICAgICAgICBuZXcgQml0cyh1bmluaXRzRW50cnkpLmRpZmZTZXQodW5pbml0cykubmV4dEJpdChmaXJzdGFkcikgPT0gLTEpCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB1bmluaXRzLmFzc2lnbih1bmluaXRzRW50cnkuYW5kU2V0KHVuaW5pdHMpKTsKICAgICAgICAgICAgICAgIGZsb3dLaW5kID0gRmxvd0tpbmQuU1BFQ1VMQVRJVkVfTE9PUDsKICAgICAgICAgICAgfSB3aGlsZSAodHJ1ZSk7CiAgICAgICAgICAgIGZsb3dLaW5kID0gcHJldkZsb3dLaW5kOwogICAgICAgICAgICAvL2EgdmFyaWFibGUgaXMgREEvRFUgYWZ0ZXIgYSBmb3IgbG9vcCwgaWYgaXQncyBEQS9EVSBhc3N1bWluZyB0aGUKICAgICAgICAgICAgLy9icmFuY2ggaXMgbm90IHRha2VuIEFORCBpZiBpdCdzIERBL0RVIGJlZm9yZSBhbnkgYnJlYWsgc3RhdGVtZW50CiAgICAgICAgICAgIGluaXRzLmFzc2lnbihpbml0c1NraXApOwogICAgICAgICAgICB1bmluaXRzLmFzc2lnbih1bmluaXRzU2tpcCk7CiAgICAgICAgICAgIHJlc29sdmVCcmVha3ModHJlZSwgcHJldlBlbmRpbmdFeGl0cyk7CiAgICAgICAgICAgIG5leHRhZHIgPSBuZXh0YWRyUHJldjsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0Rm9yZWFjaExvb3AoSkNFbmhhbmNlZEZvckxvb3AgdHJlZSkgewogICAgICAgICAgICB2aXNpdFZhckRlZih0cmVlLnZhcik7CgogICAgICAgICAgICBMaXN0QnVmZmVyPEFzc2lnblBlbmRpbmdFeGl0PiBwcmV2UGVuZGluZ0V4aXRzID0gcGVuZGluZ0V4aXRzOwogICAgICAgICAgICBGbG93S2luZCBwcmV2Rmxvd0tpbmQgPSBmbG93S2luZDsKICAgICAgICAgICAgZmxvd0tpbmQgPSBGbG93S2luZC5OT1JNQUw7CiAgICAgICAgICAgIGludCBuZXh0YWRyUHJldiA9IG5leHRhZHI7CiAgICAgICAgICAgIHNjYW4odHJlZS5leHByKTsKICAgICAgICAgICAgZmluYWwgQml0cyBpbml0c1N0YXJ0ID0gbmV3IEJpdHMoaW5pdHMpOwogICAgICAgICAgICBmaW5hbCBCaXRzIHVuaW5pdHNTdGFydCA9IG5ldyBCaXRzKHVuaW5pdHMpOwoKICAgICAgICAgICAgbGV0SW5pdCh0cmVlLnBvcygpLCB0cmVlLnZhci5zeW0pOwogICAgICAgICAgICBwZW5kaW5nRXhpdHMgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgIGludCBwcmV2RXJyb3JzID0gbG9nLm5lcnJvcnM7CiAgICAgICAgICAgIGRvIHsKICAgICAgICAgICAgICAgIGZpbmFsIEJpdHMgdW5pbml0c0VudHJ5ID0gbmV3IEJpdHModW5pbml0cyk7CiAgICAgICAgICAgICAgICB1bmluaXRzRW50cnkuZXhjbHVkZUZyb20obmV4dGFkcik7CiAgICAgICAgICAgICAgICBzY2FuKHRyZWUuYm9keSk7CiAgICAgICAgICAgICAgICByZXNvbHZlQ29udGludWVzKHRyZWUpOwogICAgICAgICAgICAgICAgaWYgKGxvZy5uZXJyb3JzICE9IHByZXZFcnJvcnMgfHwKICAgICAgICAgICAgICAgICAgICBmbG93S2luZC5pc0ZpbmFsKCkgfHwKICAgICAgICAgICAgICAgICAgICBuZXcgQml0cyh1bmluaXRzRW50cnkpLmRpZmZTZXQodW5pbml0cykubmV4dEJpdChmaXJzdGFkcikgPT0gLTEpCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB1bmluaXRzLmFzc2lnbih1bmluaXRzRW50cnkuYW5kU2V0KHVuaW5pdHMpKTsKICAgICAgICAgICAgICAgIGZsb3dLaW5kID0gRmxvd0tpbmQuU1BFQ1VMQVRJVkVfTE9PUDsKICAgICAgICAgICAgfSB3aGlsZSAodHJ1ZSk7CiAgICAgICAgICAgIGZsb3dLaW5kID0gcHJldkZsb3dLaW5kOwogICAgICAgICAgICBpbml0cy5hc3NpZ24oaW5pdHNTdGFydCk7CiAgICAgICAgICAgIHVuaW5pdHMuYXNzaWduKHVuaW5pdHNTdGFydC5hbmRTZXQodW5pbml0cykpOwogICAgICAgICAgICByZXNvbHZlQnJlYWtzKHRyZWUsIHByZXZQZW5kaW5nRXhpdHMpOwogICAgICAgICAgICBuZXh0YWRyID0gbmV4dGFkclByZXY7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdExhYmVsbGVkKEpDTGFiZWxlZFN0YXRlbWVudCB0cmVlKSB7CiAgICAgICAgICAgIExpc3RCdWZmZXI8QXNzaWduUGVuZGluZ0V4aXQ+IHByZXZQZW5kaW5nRXhpdHMgPSBwZW5kaW5nRXhpdHM7CiAgICAgICAgICAgIHBlbmRpbmdFeGl0cyA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICAgICAgc2Nhbih0cmVlLmJvZHkpOwogICAgICAgICAgICByZXNvbHZlQnJlYWtzKHRyZWUsIHByZXZQZW5kaW5nRXhpdHMpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRTd2l0Y2goSkNTd2l0Y2ggdHJlZSkgewogICAgICAgICAgICBMaXN0QnVmZmVyPEFzc2lnblBlbmRpbmdFeGl0PiBwcmV2UGVuZGluZ0V4aXRzID0gcGVuZGluZ0V4aXRzOwogICAgICAgICAgICBwZW5kaW5nRXhpdHMgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgIGludCBuZXh0YWRyUHJldiA9IG5leHRhZHI7CiAgICAgICAgICAgIHNjYW5FeHByKHRyZWUuc2VsZWN0b3IpOwogICAgICAgICAgICBmaW5hbCBCaXRzIGluaXRzU3dpdGNoID0gbmV3IEJpdHMoaW5pdHMpOwogICAgICAgICAgICBmaW5hbCBCaXRzIHVuaW5pdHNTd2l0Y2ggPSBuZXcgQml0cyh1bmluaXRzKTsKICAgICAgICAgICAgYm9vbGVhbiBoYXNEZWZhdWx0ID0gZmFsc2U7CiAgICAgICAgICAgIGZvciAoTGlzdDxKQ0Nhc2U+IGwgPSB0cmVlLmNhc2VzOyBsLm5vbkVtcHR5KCk7IGwgPSBsLnRhaWwpIHsKICAgICAgICAgICAgICAgIGluaXRzLmFzc2lnbihpbml0c1N3aXRjaCk7CiAgICAgICAgICAgICAgICB1bmluaXRzLmFzc2lnbih1bmluaXRzLmFuZFNldCh1bmluaXRzU3dpdGNoKSk7CiAgICAgICAgICAgICAgICBKQ0Nhc2UgYyA9IGwuaGVhZDsKICAgICAgICAgICAgICAgIGlmIChjLnBhdCA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgaGFzRGVmYXVsdCA9IHRydWU7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHNjYW5FeHByKGMucGF0KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChoYXNEZWZhdWx0KSB7CiAgICAgICAgICAgICAgICAgICAgaW5pdHMuYXNzaWduKGluaXRzU3dpdGNoKTsKICAgICAgICAgICAgICAgICAgICB1bmluaXRzLmFzc2lnbih1bmluaXRzLmFuZFNldCh1bmluaXRzU3dpdGNoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBzY2FuKGMuc3RhdHMpOwogICAgICAgICAgICAgICAgYWRkVmFycyhjLnN0YXRzLCBpbml0c1N3aXRjaCwgdW5pbml0c1N3aXRjaCk7CiAgICAgICAgICAgICAgICBpZiAoIWhhc0RlZmF1bHQpIHsKICAgICAgICAgICAgICAgICAgICBpbml0cy5hc3NpZ24oaW5pdHNTd2l0Y2gpOwogICAgICAgICAgICAgICAgICAgIHVuaW5pdHMuYXNzaWduKHVuaW5pdHMuYW5kU2V0KHVuaW5pdHNTd2l0Y2gpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIC8vIFdhcm4gYWJvdXQgZmFsbC10aHJvdWdoIGlmIGxpbnQgc3dpdGNoIGZhbGx0aHJvdWdoIGVuYWJsZWQuCiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCFoYXNEZWZhdWx0KSB7CiAgICAgICAgICAgICAgICBpbml0cy5hbmRTZXQoaW5pdHNTd2l0Y2gpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJlc29sdmVCcmVha3ModHJlZSwgcHJldlBlbmRpbmdFeGl0cyk7CiAgICAgICAgICAgIG5leHRhZHIgPSBuZXh0YWRyUHJldjsKICAgICAgICB9CiAgICAgICAgLy8gd2hlcmUKICAgICAgICAgICAgLyoqIEFkZCBhbnkgdmFyaWFibGVzIGRlZmluZWQgaW4gc3RhdHMgdG8gaW5pdHMgYW5kIHVuaW5pdHMuICovCiAgICAgICAgICAgIHByaXZhdGUgdm9pZCBhZGRWYXJzKExpc3Q8SkNTdGF0ZW1lbnQ+IHN0YXRzLCBmaW5hbCBCaXRzIGluaXRzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgQml0cyB1bmluaXRzKSB7CiAgICAgICAgICAgICAgICBmb3IgKDtzdGF0cy5ub25FbXB0eSgpOyBzdGF0cyA9IHN0YXRzLnRhaWwpIHsKICAgICAgICAgICAgICAgICAgICBKQ1RyZWUgc3RhdCA9IHN0YXRzLmhlYWQ7CiAgICAgICAgICAgICAgICAgICAgaWYgKHN0YXQuaGFzVGFnKFZBUkRFRikpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaW50IGFkciA9ICgoSkNWYXJpYWJsZURlY2wpIHN0YXQpLnN5bS5hZHI7CiAgICAgICAgICAgICAgICAgICAgICAgIGluaXRzLmV4Y2woYWRyKTsKICAgICAgICAgICAgICAgICAgICAgICAgdW5pbml0cy5pbmNsKGFkcik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0VHJ5KEpDVHJ5IHRyZWUpIHsKICAgICAgICAgICAgTGlzdEJ1ZmZlcjxKQ1ZhcmlhYmxlRGVjbD4gcmVzb3VyY2VWYXJEZWNscyA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICAgICAgZmluYWwgQml0cyB1bmluaXRzVHJ5UHJldiA9IG5ldyBCaXRzKHVuaW5pdHNUcnkpOwogICAgICAgICAgICBMaXN0QnVmZmVyPEFzc2lnblBlbmRpbmdFeGl0PiBwcmV2UGVuZGluZ0V4aXRzID0gcGVuZGluZ0V4aXRzOwogICAgICAgICAgICBwZW5kaW5nRXhpdHMgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgIGZpbmFsIEJpdHMgaW5pdHNUcnkgPSBuZXcgQml0cyhpbml0cyk7CiAgICAgICAgICAgIHVuaW5pdHNUcnkuYXNzaWduKHVuaW5pdHMpOwogICAgICAgICAgICBmb3IgKEpDVHJlZSByZXNvdXJjZSA6IHRyZWUucmVzb3VyY2VzKSB7CiAgICAgICAgICAgICAgICBpZiAocmVzb3VyY2UgaW5zdGFuY2VvZiBKQ1ZhcmlhYmxlRGVjbCkgewogICAgICAgICAgICAgICAgICAgIEpDVmFyaWFibGVEZWNsIHZkZWNsID0gKEpDVmFyaWFibGVEZWNsKSByZXNvdXJjZTsKICAgICAgICAgICAgICAgICAgICB2aXNpdFZhckRlZih2ZGVjbCk7CiAgICAgICAgICAgICAgICAgICAgdW5yZWZkUmVzb3VyY2VzLmVudGVyKHZkZWNsLnN5bSk7CiAgICAgICAgICAgICAgICAgICAgcmVzb3VyY2VWYXJEZWNscy5hcHBlbmQodmRlY2wpOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChyZXNvdXJjZSBpbnN0YW5jZW9mIEpDRXhwcmVzc2lvbikgewogICAgICAgICAgICAgICAgICAgIHNjYW5FeHByKChKQ0V4cHJlc3Npb24pIHJlc291cmNlKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKHRyZWUpOyAgLy8gcGFyc2VyIGVycm9yCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc2Nhbih0cmVlLmJvZHkpOwogICAgICAgICAgICB1bmluaXRzVHJ5LmFuZFNldCh1bmluaXRzKTsKICAgICAgICAgICAgZmluYWwgQml0cyBpbml0c0VuZCA9IG5ldyBCaXRzKGluaXRzKTsKICAgICAgICAgICAgZmluYWwgQml0cyB1bmluaXRzRW5kID0gbmV3IEJpdHModW5pbml0cyk7CiAgICAgICAgICAgIGludCBuZXh0YWRyQ2F0Y2ggPSBuZXh0YWRyOwoKICAgICAgICAgICAgaWYgKCFyZXNvdXJjZVZhckRlY2xzLmlzRW1wdHkoKSAmJgogICAgICAgICAgICAgICAgICAgIGxpbnQuaXNFbmFibGVkKExpbnQuTGludENhdGVnb3J5LlRSWSkpIHsKICAgICAgICAgICAgICAgIGZvciAoSkNWYXJpYWJsZURlY2wgcmVzVmFyIDogcmVzb3VyY2VWYXJEZWNscykgewogICAgICAgICAgICAgICAgICAgIGlmICh1bnJlZmRSZXNvdXJjZXMuaW5jbHVkZXMocmVzVmFyLnN5bSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgbG9nLndhcm5pbmcoTGludC5MaW50Q2F0ZWdvcnkuVFJZLCByZXNWYXIucG9zKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0cnkucmVzb3VyY2Uubm90LnJlZmVyZW5jZWQiLCByZXNWYXIuc3ltKTsKICAgICAgICAgICAgICAgICAgICAgICAgdW5yZWZkUmVzb3VyY2VzLnJlbW92ZShyZXNWYXIuc3ltKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qICBUaGUgYW5hbHlzaXMgb2YgZWFjaCBjYXRjaCBzaG91bGQgYmUgaW5kZXBlbmRlbnQuCiAgICAgICAgICAgICAqICBFYWNoIG9uZSBzaG91bGQgaGF2ZSB0aGUgc2FtZSBpbml0aWFsIHZhbHVlcyBvZiBpbml0cyBhbmQKICAgICAgICAgICAgICogIHVuaW5pdHMuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBmaW5hbCBCaXRzIGluaXRzQ2F0Y2hQcmV2ID0gbmV3IEJpdHMoaW5pdHNUcnkpOwogICAgICAgICAgICBmaW5hbCBCaXRzIHVuaW5pdHNDYXRjaFByZXYgPSBuZXcgQml0cyh1bmluaXRzVHJ5KTsKCiAgICAgICAgICAgIGZvciAoTGlzdDxKQ0NhdGNoPiBsID0gdHJlZS5jYXRjaGVyczsgbC5ub25FbXB0eSgpOyBsID0gbC50YWlsKSB7CiAgICAgICAgICAgICAgICBKQ1ZhcmlhYmxlRGVjbCBwYXJhbSA9IGwuaGVhZC5wYXJhbTsKICAgICAgICAgICAgICAgIGluaXRzLmFzc2lnbihpbml0c0NhdGNoUHJldik7CiAgICAgICAgICAgICAgICB1bmluaXRzLmFzc2lnbih1bmluaXRzQ2F0Y2hQcmV2KTsKICAgICAgICAgICAgICAgIHNjYW4ocGFyYW0pOwogICAgICAgICAgICAgICAgLyogSWYgdGhpcyBpcyBhIFRXUiBhbmQgd2UgYXJlIGV4ZWN1dGluZyB0aGUgY29kZSBmcm9tIEdlbiwKICAgICAgICAgICAgICAgICAqIHRoZW4gdGhlcmUgY2FuIGJlIHN5bnRoZXRpYyB2YXJpYWJsZXMsIGlnbm9yZSB0aGVtLgogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBpbml0UGFyYW0ocGFyYW0pOwogICAgICAgICAgICAgICAgc2NhbihsLmhlYWQuYm9keSk7CiAgICAgICAgICAgICAgICBpbml0c0VuZC5hbmRTZXQoaW5pdHMpOwogICAgICAgICAgICAgICAgdW5pbml0c0VuZC5hbmRTZXQodW5pbml0cyk7CiAgICAgICAgICAgICAgICBuZXh0YWRyID0gbmV4dGFkckNhdGNoOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICh0cmVlLmZpbmFsaXplciAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICBpbml0cy5hc3NpZ24oaW5pdHNUcnkpOwogICAgICAgICAgICAgICAgdW5pbml0cy5hc3NpZ24odW5pbml0c1RyeSk7CiAgICAgICAgICAgICAgICBMaXN0QnVmZmVyPEFzc2lnblBlbmRpbmdFeGl0PiBleGl0cyA9IHBlbmRpbmdFeGl0czsKICAgICAgICAgICAgICAgIHBlbmRpbmdFeGl0cyA9IHByZXZQZW5kaW5nRXhpdHM7CiAgICAgICAgICAgICAgICBzY2FuKHRyZWUuZmluYWxpemVyKTsKICAgICAgICAgICAgICAgIGlmICghdHJlZS5maW5hbGx5Q2FuQ29tcGxldGVOb3JtYWxseSkgewogICAgICAgICAgICAgICAgICAgIC8vIGRpc2NhcmQgZXhpdHMgYW5kIGV4Y2VwdGlvbnMgZnJvbSB0cnkgYW5kIGZpbmFsbHkKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgdW5pbml0cy5hbmRTZXQodW5pbml0c0VuZCk7CiAgICAgICAgICAgICAgICAgICAgLy8gRklYOiB0aGlzIGRvZXNuJ3QgcHJlc2VydmUgc291cmNlIG9yZGVyIG9mIGV4aXRzIGluIGNhdGNoCiAgICAgICAgICAgICAgICAgICAgLy8gdmVyc3VzIGZpbmFsbHkhCiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGV4aXRzLm5vbkVtcHR5KCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgQXNzaWduUGVuZGluZ0V4aXQgZXhpdCA9IGV4aXRzLm5leHQoKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGV4aXQuZXhpdF9pbml0cyAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBleGl0LmV4aXRfaW5pdHMub3JTZXQoaW5pdHMpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhpdC5leGl0X3VuaW5pdHMuYW5kU2V0KHVuaW5pdHMpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIHBlbmRpbmdFeGl0cy5hcHBlbmQoZXhpdCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGluaXRzLm9yU2V0KGluaXRzRW5kKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGluaXRzLmFzc2lnbihpbml0c0VuZCk7CiAgICAgICAgICAgICAgICB1bmluaXRzLmFzc2lnbih1bmluaXRzRW5kKTsKICAgICAgICAgICAgICAgIExpc3RCdWZmZXI8QXNzaWduUGVuZGluZ0V4aXQ+IGV4aXRzID0gcGVuZGluZ0V4aXRzOwogICAgICAgICAgICAgICAgcGVuZGluZ0V4aXRzID0gcHJldlBlbmRpbmdFeGl0czsKICAgICAgICAgICAgICAgIHdoaWxlIChleGl0cy5ub25FbXB0eSgpKSBwZW5kaW5nRXhpdHMuYXBwZW5kKGV4aXRzLm5leHQoKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdW5pbml0c1RyeS5hbmRTZXQodW5pbml0c1RyeVByZXYpLmFuZFNldCh1bmluaXRzKTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0Q29uZGl0aW9uYWwoSkNDb25kaXRpb25hbCB0cmVlKSB7CiAgICAgICAgICAgIHNjYW5Db25kKHRyZWUuY29uZCk7CiAgICAgICAgICAgIGZpbmFsIEJpdHMgaW5pdHNCZWZvcmVFbHNlID0gbmV3IEJpdHMoaW5pdHNXaGVuRmFsc2UpOwogICAgICAgICAgICBmaW5hbCBCaXRzIHVuaW5pdHNCZWZvcmVFbHNlID0gbmV3IEJpdHModW5pbml0c1doZW5GYWxzZSk7CiAgICAgICAgICAgIGluaXRzLmFzc2lnbihpbml0c1doZW5UcnVlKTsKICAgICAgICAgICAgdW5pbml0cy5hc3NpZ24odW5pbml0c1doZW5UcnVlKTsKICAgICAgICAgICAgaWYgKHRyZWUudHJ1ZXBhcnQudHlwZS5oYXNUYWcoQk9PTEVBTikgJiYKICAgICAgICAgICAgICAgIHRyZWUuZmFsc2VwYXJ0LnR5cGUuaGFzVGFnKEJPT0xFQU4pKSB7CiAgICAgICAgICAgICAgICAvLyBpZiBiIGFuZCBjIGFyZSBib29sZWFuIHZhbHVlZCwgdGhlbgogICAgICAgICAgICAgICAgLy8gdiBpcyAodW4pYXNzaWduZWQgYWZ0ZXIgYT9iOmMgd2hlbiB0cnVlIGlmZgogICAgICAgICAgICAgICAgLy8gICAgdiBpcyAodW4pYXNzaWduZWQgYWZ0ZXIgYiB3aGVuIHRydWUgYW5kCiAgICAgICAgICAgICAgICAvLyAgICB2IGlzICh1bilhc3NpZ25lZCBhZnRlciBjIHdoZW4gdHJ1ZQogICAgICAgICAgICAgICAgc2NhbkNvbmQodHJlZS50cnVlcGFydCk7CiAgICAgICAgICAgICAgICBmaW5hbCBCaXRzIGluaXRzQWZ0ZXJUaGVuV2hlblRydWUgPSBuZXcgQml0cyhpbml0c1doZW5UcnVlKTsKICAgICAgICAgICAgICAgIGZpbmFsIEJpdHMgaW5pdHNBZnRlclRoZW5XaGVuRmFsc2UgPSBuZXcgQml0cyhpbml0c1doZW5GYWxzZSk7CiAgICAgICAgICAgICAgICBmaW5hbCBCaXRzIHVuaW5pdHNBZnRlclRoZW5XaGVuVHJ1ZSA9IG5ldyBCaXRzKHVuaW5pdHNXaGVuVHJ1ZSk7CiAgICAgICAgICAgICAgICBmaW5hbCBCaXRzIHVuaW5pdHNBZnRlclRoZW5XaGVuRmFsc2UgPSBuZXcgQml0cyh1bmluaXRzV2hlbkZhbHNlKTsKICAgICAgICAgICAgICAgIGluaXRzLmFzc2lnbihpbml0c0JlZm9yZUVsc2UpOwogICAgICAgICAgICAgICAgdW5pbml0cy5hc3NpZ24odW5pbml0c0JlZm9yZUVsc2UpOwogICAgICAgICAgICAgICAgc2NhbkNvbmQodHJlZS5mYWxzZXBhcnQpOwogICAgICAgICAgICAgICAgaW5pdHNXaGVuVHJ1ZS5hbmRTZXQoaW5pdHNBZnRlclRoZW5XaGVuVHJ1ZSk7CiAgICAgICAgICAgICAgICBpbml0c1doZW5GYWxzZS5hbmRTZXQoaW5pdHNBZnRlclRoZW5XaGVuRmFsc2UpOwogICAgICAgICAgICAgICAgdW5pbml0c1doZW5UcnVlLmFuZFNldCh1bmluaXRzQWZ0ZXJUaGVuV2hlblRydWUpOwogICAgICAgICAgICAgICAgdW5pbml0c1doZW5GYWxzZS5hbmRTZXQodW5pbml0c0FmdGVyVGhlbldoZW5GYWxzZSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBzY2FuRXhwcih0cmVlLnRydWVwYXJ0KTsKICAgICAgICAgICAgICAgIGZpbmFsIEJpdHMgaW5pdHNBZnRlclRoZW4gPSBuZXcgQml0cyhpbml0cyk7CiAgICAgICAgICAgICAgICBmaW5hbCBCaXRzIHVuaW5pdHNBZnRlclRoZW4gPSBuZXcgQml0cyh1bmluaXRzKTsKICAgICAgICAgICAgICAgIGluaXRzLmFzc2lnbihpbml0c0JlZm9yZUVsc2UpOwogICAgICAgICAgICAgICAgdW5pbml0cy5hc3NpZ24odW5pbml0c0JlZm9yZUVsc2UpOwogICAgICAgICAgICAgICAgc2NhbkV4cHIodHJlZS5mYWxzZXBhcnQpOwogICAgICAgICAgICAgICAgaW5pdHMuYW5kU2V0KGluaXRzQWZ0ZXJUaGVuKTsKICAgICAgICAgICAgICAgIHVuaW5pdHMuYW5kU2V0KHVuaW5pdHNBZnRlclRoZW4pOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdElmKEpDSWYgdHJlZSkgewogICAgICAgICAgICBzY2FuQ29uZCh0cmVlLmNvbmQpOwogICAgICAgICAgICBmaW5hbCBCaXRzIGluaXRzQmVmb3JlRWxzZSA9IG5ldyBCaXRzKGluaXRzV2hlbkZhbHNlKTsKICAgICAgICAgICAgZmluYWwgQml0cyB1bmluaXRzQmVmb3JlRWxzZSA9IG5ldyBCaXRzKHVuaW5pdHNXaGVuRmFsc2UpOwogICAgICAgICAgICBpbml0cy5hc3NpZ24oaW5pdHNXaGVuVHJ1ZSk7CiAgICAgICAgICAgIHVuaW5pdHMuYXNzaWduKHVuaW5pdHNXaGVuVHJ1ZSk7CiAgICAgICAgICAgIHNjYW4odHJlZS50aGVucGFydCk7CiAgICAgICAgICAgIGlmICh0cmVlLmVsc2VwYXJ0ICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIGZpbmFsIEJpdHMgaW5pdHNBZnRlclRoZW4gPSBuZXcgQml0cyhpbml0cyk7CiAgICAgICAgICAgICAgICBmaW5hbCBCaXRzIHVuaW5pdHNBZnRlclRoZW4gPSBuZXcgQml0cyh1bmluaXRzKTsKICAgICAgICAgICAgICAgIGluaXRzLmFzc2lnbihpbml0c0JlZm9yZUVsc2UpOwogICAgICAgICAgICAgICAgdW5pbml0cy5hc3NpZ24odW5pbml0c0JlZm9yZUVsc2UpOwogICAgICAgICAgICAgICAgc2Nhbih0cmVlLmVsc2VwYXJ0KTsKICAgICAgICAgICAgICAgIGluaXRzLmFuZFNldChpbml0c0FmdGVyVGhlbik7CiAgICAgICAgICAgICAgICB1bmluaXRzLmFuZFNldCh1bmluaXRzQWZ0ZXJUaGVuKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGluaXRzLmFuZFNldChpbml0c0JlZm9yZUVsc2UpOwogICAgICAgICAgICAgICAgdW5pbml0cy5hbmRTZXQodW5pbml0c0JlZm9yZUVsc2UpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdEJyZWFrKEpDQnJlYWsgdHJlZSkgewogICAgICAgICAgICByZWNvcmRFeGl0KG5ldyBBc3NpZ25QZW5kaW5nRXhpdCh0cmVlLCBpbml0cywgdW5pbml0cykpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRDb250aW51ZShKQ0NvbnRpbnVlIHRyZWUpIHsKICAgICAgICAgICAgcmVjb3JkRXhpdChuZXcgQXNzaWduUGVuZGluZ0V4aXQodHJlZSwgaW5pdHMsIHVuaW5pdHMpKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0UmV0dXJuKEpDUmV0dXJuIHRyZWUpIHsKICAgICAgICAgICAgc2NhbkV4cHIodHJlZS5leHByKTsKICAgICAgICAgICAgcmVjb3JkRXhpdChuZXcgQXNzaWduUGVuZGluZ0V4aXQodHJlZSwgaW5pdHMsIHVuaW5pdHMpKTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0VGhyb3coSkNUaHJvdyB0cmVlKSB7CiAgICAgICAgICAgIHNjYW5FeHByKHRyZWUuZXhwcik7CiAgICAgICAgICAgIG1hcmtEZWFkKCk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdEFwcGx5KEpDTWV0aG9kSW52b2NhdGlvbiB0cmVlKSB7CiAgICAgICAgICAgIHNjYW5FeHByKHRyZWUubWV0aCk7CiAgICAgICAgICAgIHNjYW5FeHBycyh0cmVlLmFyZ3MpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXROZXdDbGFzcyhKQ05ld0NsYXNzIHRyZWUpIHsKICAgICAgICAgICAgc2NhbkV4cHIodHJlZS5lbmNsKTsKICAgICAgICAgICAgc2NhbkV4cHJzKHRyZWUuYXJncyk7CiAgICAgICAgICAgIHNjYW4odHJlZS5kZWYpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRMYW1iZGEoSkNMYW1iZGEgdHJlZSkgewogICAgICAgICAgICBmaW5hbCBCaXRzIHByZXZVbmluaXRzID0gbmV3IEJpdHModW5pbml0cyk7CiAgICAgICAgICAgIGZpbmFsIEJpdHMgcHJldkluaXRzID0gbmV3IEJpdHMoaW5pdHMpOwogICAgICAgICAgICBpbnQgcmV0dXJuYWRyUHJldiA9IHJldHVybmFkcjsKICAgICAgICAgICAgaW50IG5leHRhZHJQcmV2ID0gbmV4dGFkcjsKICAgICAgICAgICAgTGlzdEJ1ZmZlcjxBc3NpZ25QZW5kaW5nRXhpdD4gcHJldlBlbmRpbmcgPSBwZW5kaW5nRXhpdHM7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICByZXR1cm5hZHIgPSBuZXh0YWRyOwogICAgICAgICAgICAgICAgcGVuZGluZ0V4aXRzID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgICAgICAgICAgZm9yIChMaXN0PEpDVmFyaWFibGVEZWNsPiBsID0gdHJlZS5wYXJhbXM7IGwubm9uRW1wdHkoKTsgbCA9IGwudGFpbCkgewogICAgICAgICAgICAgICAgICAgIEpDVmFyaWFibGVEZWNsIGRlZiA9IGwuaGVhZDsKICAgICAgICAgICAgICAgICAgICBzY2FuKGRlZik7CiAgICAgICAgICAgICAgICAgICAgaW5pdHMuaW5jbChkZWYuc3ltLmFkcik7CiAgICAgICAgICAgICAgICAgICAgdW5pbml0cy5leGNsKGRlZi5zeW0uYWRyKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICh0cmVlLmdldEJvZHlLaW5kKCkgPT0gSkNMYW1iZGEuQm9keUtpbmQuRVhQUkVTU0lPTikgewogICAgICAgICAgICAgICAgICAgIHNjYW5FeHByKHRyZWUuYm9keSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHNjYW4odHJlZS5ib2R5KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBmaW5hbGx5IHsKICAgICAgICAgICAgICAgIHJldHVybmFkciA9IHJldHVybmFkclByZXY7CiAgICAgICAgICAgICAgICB1bmluaXRzLmFzc2lnbihwcmV2VW5pbml0cyk7CiAgICAgICAgICAgICAgICBpbml0cy5hc3NpZ24ocHJldkluaXRzKTsKICAgICAgICAgICAgICAgIHBlbmRpbmdFeGl0cyA9IHByZXZQZW5kaW5nOwogICAgICAgICAgICAgICAgbmV4dGFkciA9IG5leHRhZHJQcmV2OwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdE5ld0FycmF5KEpDTmV3QXJyYXkgdHJlZSkgewogICAgICAgICAgICBzY2FuRXhwcnModHJlZS5kaW1zKTsKICAgICAgICAgICAgc2NhbkV4cHJzKHRyZWUuZWxlbXMpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRBc3NlcnQoSkNBc3NlcnQgdHJlZSkgewogICAgICAgICAgICBmaW5hbCBCaXRzIGluaXRzRXhpdCA9IG5ldyBCaXRzKGluaXRzKTsKICAgICAgICAgICAgZmluYWwgQml0cyB1bmluaXRzRXhpdCA9IG5ldyBCaXRzKHVuaW5pdHMpOwogICAgICAgICAgICBzY2FuQ29uZCh0cmVlLmNvbmQpOwogICAgICAgICAgICB1bmluaXRzRXhpdC5hbmRTZXQodW5pbml0c1doZW5UcnVlKTsKICAgICAgICAgICAgaWYgKHRyZWUuZGV0YWlsICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIGluaXRzLmFzc2lnbihpbml0c1doZW5GYWxzZSk7CiAgICAgICAgICAgICAgICB1bmluaXRzLmFzc2lnbih1bmluaXRzV2hlbkZhbHNlKTsKICAgICAgICAgICAgICAgIHNjYW5FeHByKHRyZWUuZGV0YWlsKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpbml0cy5hc3NpZ24oaW5pdHNFeGl0KTsKICAgICAgICAgICAgdW5pbml0cy5hc3NpZ24odW5pbml0c0V4aXQpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRBc3NpZ24oSkNBc3NpZ24gdHJlZSkgewogICAgICAgICAgICBKQ1RyZWUgbGhzID0gVHJlZUluZm8uc2tpcFBhcmVucyh0cmVlLmxocyk7CiAgICAgICAgICAgIGlmICghaXNJZGVudE9yVGhpc0RvdElkZW50KGxocykpCiAgICAgICAgICAgICAgICBzY2FuRXhwcihsaHMpOwogICAgICAgICAgICBzY2FuRXhwcih0cmVlLnJocyk7CiAgICAgICAgICAgIGxldEluaXQobGhzKTsKICAgICAgICB9CiAgICAgICAgcHJpdmF0ZSBib29sZWFuIGlzSWRlbnRPclRoaXNEb3RJZGVudChKQ1RyZWUgbGhzKSB7CiAgICAgICAgICAgIGlmIChsaHMuaGFzVGFnKElERU5UKSkKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICBpZiAoIWxocy5oYXNUYWcoU0VMRUNUKSkKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKCiAgICAgICAgICAgIEpDRmllbGRBY2Nlc3MgZmEgPSAoSkNGaWVsZEFjY2VzcylsaHM7CiAgICAgICAgICAgIHJldHVybiBmYS5zZWxlY3RlZC5oYXNUYWcoSURFTlQpICYmCiAgICAgICAgICAgICAgICAgICAoKEpDSWRlbnQpZmEuc2VsZWN0ZWQpLm5hbWUgPT0gbmFtZXMuX3RoaXM7CiAgICAgICAgfQoKICAgICAgICAvLyBjaGVjayBmaWVsZHMgYWNjZXNzZWQgdGhyb3VnaCB0aGlzLjxmaWVsZD4gYXJlIGRlZmluaXRlbHkKICAgICAgICAvLyBhc3NpZ25lZCBiZWZvcmUgcmVhZGluZyB0aGVpciB2YWx1ZQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0U2VsZWN0KEpDRmllbGRBY2Nlc3MgdHJlZSkgewogICAgICAgICAgICBzdXBlci52aXNpdFNlbGVjdCh0cmVlKTsKICAgICAgICAgICAgSkNUcmVlIHNlbCA9IFRyZWVJbmZvLnNraXBQYXJlbnModHJlZS5zZWxlY3RlZCk7CiAgICAgICAgICAgIGlmIChlbmZvcmNlVGhpc0RvdEluaXQgJiYKICAgICAgICAgICAgICAgICAgICBzZWwuaGFzVGFnKElERU5UKSAmJgogICAgICAgICAgICAgICAgICAgICgoSkNJZGVudClzZWwpLm5hbWUgPT0gbmFtZXMuX3RoaXMgJiYKICAgICAgICAgICAgICAgICAgICB0cmVlLnN5bS5raW5kID09IFZBUikgewogICAgICAgICAgICAgICAgY2hlY2tJbml0KHRyZWUucG9zKCksIChWYXJTeW1ib2wpdHJlZS5zeW0pOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdEFzc2lnbm9wKEpDQXNzaWduT3AgdHJlZSkgewogICAgICAgICAgICBzY2FuRXhwcih0cmVlLmxocyk7CiAgICAgICAgICAgIHNjYW5FeHByKHRyZWUucmhzKTsKICAgICAgICAgICAgbGV0SW5pdCh0cmVlLmxocyk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdFVuYXJ5KEpDVW5hcnkgdHJlZSkgewogICAgICAgICAgICBzd2l0Y2ggKHRyZWUuZ2V0VGFnKCkpIHsKICAgICAgICAgICAgY2FzZSBOT1Q6CiAgICAgICAgICAgICAgICBzY2FuQ29uZCh0cmVlLmFyZyk7CiAgICAgICAgICAgICAgICBmaW5hbCBCaXRzIHQgPSBuZXcgQml0cyhpbml0c1doZW5GYWxzZSk7CiAgICAgICAgICAgICAgICBpbml0c1doZW5GYWxzZS5hc3NpZ24oaW5pdHNXaGVuVHJ1ZSk7CiAgICAgICAgICAgICAgICBpbml0c1doZW5UcnVlLmFzc2lnbih0KTsKICAgICAgICAgICAgICAgIHQuYXNzaWduKHVuaW5pdHNXaGVuRmFsc2UpOwogICAgICAgICAgICAgICAgdW5pbml0c1doZW5GYWxzZS5hc3NpZ24odW5pbml0c1doZW5UcnVlKTsKICAgICAgICAgICAgICAgIHVuaW5pdHNXaGVuVHJ1ZS5hc3NpZ24odCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBQUkVJTkM6IGNhc2UgUE9TVElOQzoKICAgICAgICAgICAgY2FzZSBQUkVERUM6IGNhc2UgUE9TVERFQzoKICAgICAgICAgICAgICAgIHNjYW5FeHByKHRyZWUuYXJnKTsKICAgICAgICAgICAgICAgIGxldEluaXQodHJlZS5hcmcpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICBzY2FuRXhwcih0cmVlLmFyZyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0QmluYXJ5KEpDQmluYXJ5IHRyZWUpIHsKICAgICAgICAgICAgc3dpdGNoICh0cmVlLmdldFRhZygpKSB7CiAgICAgICAgICAgIGNhc2UgQU5EOgogICAgICAgICAgICAgICAgc2NhbkNvbmQodHJlZS5saHMpOwogICAgICAgICAgICAgICAgZmluYWwgQml0cyBpbml0c1doZW5GYWxzZUxlZnQgPSBuZXcgQml0cyhpbml0c1doZW5GYWxzZSk7CiAgICAgICAgICAgICAgICBmaW5hbCBCaXRzIHVuaW5pdHNXaGVuRmFsc2VMZWZ0ID0gbmV3IEJpdHModW5pbml0c1doZW5GYWxzZSk7CiAgICAgICAgICAgICAgICBpbml0cy5hc3NpZ24oaW5pdHNXaGVuVHJ1ZSk7CiAgICAgICAgICAgICAgICB1bmluaXRzLmFzc2lnbih1bmluaXRzV2hlblRydWUpOwogICAgICAgICAgICAgICAgc2NhbkNvbmQodHJlZS5yaHMpOwogICAgICAgICAgICAgICAgaW5pdHNXaGVuRmFsc2UuYW5kU2V0KGluaXRzV2hlbkZhbHNlTGVmdCk7CiAgICAgICAgICAgICAgICB1bmluaXRzV2hlbkZhbHNlLmFuZFNldCh1bmluaXRzV2hlbkZhbHNlTGVmdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBPUjoKICAgICAgICAgICAgICAgIHNjYW5Db25kKHRyZWUubGhzKTsKICAgICAgICAgICAgICAgIGZpbmFsIEJpdHMgaW5pdHNXaGVuVHJ1ZUxlZnQgPSBuZXcgQml0cyhpbml0c1doZW5UcnVlKTsKICAgICAgICAgICAgICAgIGZpbmFsIEJpdHMgdW5pbml0c1doZW5UcnVlTGVmdCA9IG5ldyBCaXRzKHVuaW5pdHNXaGVuVHJ1ZSk7CiAgICAgICAgICAgICAgICBpbml0cy5hc3NpZ24oaW5pdHNXaGVuRmFsc2UpOwogICAgICAgICAgICAgICAgdW5pbml0cy5hc3NpZ24odW5pbml0c1doZW5GYWxzZSk7CiAgICAgICAgICAgICAgICBzY2FuQ29uZCh0cmVlLnJocyk7CiAgICAgICAgICAgICAgICBpbml0c1doZW5UcnVlLmFuZFNldChpbml0c1doZW5UcnVlTGVmdCk7CiAgICAgICAgICAgICAgICB1bmluaXRzV2hlblRydWUuYW5kU2V0KHVuaW5pdHNXaGVuVHJ1ZUxlZnQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICBzY2FuRXhwcih0cmVlLmxocyk7CiAgICAgICAgICAgICAgICBzY2FuRXhwcih0cmVlLnJocyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0SWRlbnQoSkNJZGVudCB0cmVlKSB7CiAgICAgICAgICAgIGlmICh0cmVlLnN5bS5raW5kID09IFZBUikgewogICAgICAgICAgICAgICAgY2hlY2tJbml0KHRyZWUucG9zKCksIChWYXJTeW1ib2wpdHJlZS5zeW0pOwogICAgICAgICAgICAgICAgcmVmZXJlbmNlZCh0cmVlLnN5bSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHZvaWQgcmVmZXJlbmNlZChTeW1ib2wgc3ltKSB7CiAgICAgICAgICAgIHVucmVmZFJlc291cmNlcy5yZW1vdmUoc3ltKTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0QW5ub3RhdGVkVHlwZShKQ0Fubm90YXRlZFR5cGUgdHJlZSkgewogICAgICAgICAgICAvLyBhbm5vdGF0aW9ucyBkb24ndCBnZXQgc2Nhbm5lZAogICAgICAgICAgICB0cmVlLnVuZGVybHlpbmdUeXBlLmFjY2VwdCh0aGlzKTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0TW9kdWxlRGVmKEpDTW9kdWxlRGVjbCB0cmVlKSB7CiAgICAgICAgICAgIC8vIERvIG5vdGhpbmcgZm9yIG1vZHVsZXMKICAgICAgICB9CgogICAgLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAgICAgKiBtYWluIG1ldGhvZAogICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgogICAgICAgIC8qKiBQZXJmb3JtIGRlZmluaXRlIGFzc2lnbm1lbnQvdW5hc3NpZ25tZW50IGFuYWx5c2lzIG9uIGEgdHJlZS4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgdm9pZCBhbmFseXplVHJlZShFbnY8Pz4gZW52KSB7CiAgICAgICAgICAgIGFuYWx5emVUcmVlKGVudiwgZW52LnRyZWUpOwogICAgICAgICB9CgogICAgICAgIHB1YmxpYyB2b2lkIGFuYWx5emVUcmVlKEVudjw/PiBlbnYsIEpDVHJlZSB0cmVlKSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBzdGFydFBvcyA9IHRyZWUucG9zKCkuZ2V0U3RhcnRQb3NpdGlvbigpOwoKICAgICAgICAgICAgICAgIGlmICh2YXJkZWNscyA9PSBudWxsKQogICAgICAgICAgICAgICAgICAgIHZhcmRlY2xzID0gbmV3IEpDVmFyaWFibGVEZWNsWzMyXTsKICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpPTA7IGk8dmFyZGVjbHMubGVuZ3RoOyBpKyspCiAgICAgICAgICAgICAgICAgICAgICAgIHZhcmRlY2xzW2ldID0gbnVsbDsKICAgICAgICAgICAgICAgIGZpcnN0YWRyID0gMDsKICAgICAgICAgICAgICAgIG5leHRhZHIgPSAwOwogICAgICAgICAgICAgICAgcGVuZGluZ0V4aXRzID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgICAgICAgICAgdGhpcy5jbGFzc0RlZiA9IG51bGw7CiAgICAgICAgICAgICAgICB1bnJlZmRSZXNvdXJjZXMgPSBXcml0ZWFibGVTY29wZS5jcmVhdGUoZW52LmVuY2xDbGFzcy5zeW0pOwogICAgICAgICAgICAgICAgc2Nhbih0cmVlKTsKICAgICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgICAgIC8vIG5vdGUgdGhhdCByZWN1cnNpdmUgaW52b2NhdGlvbnMgb2YgdGhpcyBtZXRob2QgZmFpbCBoYXJkCiAgICAgICAgICAgICAgICBzdGFydFBvcyA9IC0xOwogICAgICAgICAgICAgICAgcmVzZXRCaXRzKGluaXRzLCB1bmluaXRzLCB1bmluaXRzVHJ5LCBpbml0c1doZW5UcnVlLAogICAgICAgICAgICAgICAgICAgICAgICBpbml0c1doZW5GYWxzZSwgdW5pbml0c1doZW5UcnVlLCB1bmluaXRzV2hlbkZhbHNlKTsKICAgICAgICAgICAgICAgIGlmICh2YXJkZWNscyAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaT0wOyBpPHZhcmRlY2xzLmxlbmd0aDsgaSsrKQogICAgICAgICAgICAgICAgICAgICAgICB2YXJkZWNsc1tpXSA9IG51bGw7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBmaXJzdGFkciA9IDA7CiAgICAgICAgICAgICAgICBuZXh0YWRyID0gMDsKICAgICAgICAgICAgICAgIHBlbmRpbmdFeGl0cyA9IG51bGw7CiAgICAgICAgICAgICAgICB0aGlzLmNsYXNzRGVmID0gbnVsbDsKICAgICAgICAgICAgICAgIHVucmVmZFJlc291cmNlcyA9IG51bGw7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBUaGlzIHBhc3MgaW1wbGVtZW50cyB0aGUgbGFzdCBzdGVwIG9mIHRoZSBkYXRhZmxvdyBhbmFseXNpcywgbmFtZWx5CiAgICAgKiB0aGUgZWZmZWN0aXZlbHktZmluYWwgYW5hbHlzaXMgY2hlY2suIFRoaXMgY2hlY2tzIHRoYXQgZXZlcnkgbG9jYWwgdmFyaWFibGUKICAgICAqIHJlZmVyZW5jZSBmcm9tIGEgbGFtYmRhIGJvZHkvbG9jYWwgaW5uZXIgY2xhc3MgaXMgZWl0aGVyIGZpbmFsIG9yIGVmZmVjdGl2ZWx5IGZpbmFsLgogICAgICogQWRkaXRpb25hbCB0aGlzIGFsc28gY2hlY2tzIHRoYXQgZXZlcnkgdmFyaWFibGUgdGhhdCBpcyB1c2VkIGFzIGFuIG9wZXJhbmQgdG8KICAgICAqIHRyeS13aXRoLXJlc291cmNlcyBpcyBmaW5hbCBvciBlZmZlY3RpdmVseSBmaW5hbC4KICAgICAqIEFzIGVmZmVjdGl2ZWx5IGZpbmFsIHZhcmlhYmxlcyBhcmUgbWFya2VkIGFzIHN1Y2ggZHVyaW5nIERBL0RVLCB0aGlzIHBhc3MgbXVzdCBydW4gYWZ0ZXIKICAgICAqIEFzc2lnbkFuYWx5emVyLgogICAgICovCiAgICBjbGFzcyBDYXB0dXJlQW5hbHl6ZXIgZXh0ZW5kcyBCYXNlQW5hbHl6ZXI8QmFzZUFuYWx5emVyLlBlbmRpbmdFeGl0PiB7CgogICAgICAgIEpDVHJlZSBjdXJyZW50VHJlZTsgLy9sb2NhbCBjbGFzcyBvciBsYW1iZGEKCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgdm9pZCBtYXJrRGVhZCgpIHsKICAgICAgICAgICAgLy9kbyBub3RoaW5nCiAgICAgICAgfQoKICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygiZmFsbHRocm91Z2giKQogICAgICAgIHZvaWQgY2hlY2tFZmZlY3RpdmVseUZpbmFsKERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIFZhclN5bWJvbCBzeW0pIHsKICAgICAgICAgICAgaWYgKGN1cnJlbnRUcmVlICE9IG51bGwgJiYKICAgICAgICAgICAgICAgICAgICBzeW0ub3duZXIua2luZCA9PSBNVEggJiYKICAgICAgICAgICAgICAgICAgICBzeW0ucG9zIDwgY3VycmVudFRyZWUuZ2V0U3RhcnRQb3NpdGlvbigpKSB7CiAgICAgICAgICAgICAgICBzd2l0Y2ggKGN1cnJlbnRUcmVlLmdldFRhZygpKSB7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBDTEFTU0RFRjoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFhbGxvd0VmZmVjdGl2ZWx5RmluYWxJbklubmVyQ2xhc3NlcykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKChzeW0uZmxhZ3MoKSAmIEZJTkFMKSA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwb3J0SW5uZXJDbHNOZWVkc0ZpbmFsRXJyb3IocG9zLCBzeW0pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBjYXNlIExBTUJEQToKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKChzeW0uZmxhZ3MoKSAmIChFRkZFQ1RJVkVMWV9GSU5BTCB8IEZJTkFMKSkgPT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICByZXBvcnRFZmZlY3RpdmVseUZpbmFsRXJyb3IocG9zLCBzeW0pOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJmYWxsdGhyb3VnaCIpCiAgICAgICAgdm9pZCBsZXRJbml0KEpDVHJlZSB0cmVlKSB7CiAgICAgICAgICAgIHRyZWUgPSBUcmVlSW5mby5za2lwUGFyZW5zKHRyZWUpOwogICAgICAgICAgICBpZiAodHJlZS5oYXNUYWcoSURFTlQpIHx8IHRyZWUuaGFzVGFnKFNFTEVDVCkpIHsKICAgICAgICAgICAgICAgIFN5bWJvbCBzeW0gPSBUcmVlSW5mby5zeW1ib2wodHJlZSk7CiAgICAgICAgICAgICAgICBpZiAoY3VycmVudFRyZWUgIT0gbnVsbCAmJgogICAgICAgICAgICAgICAgICAgICAgICBzeW0ua2luZCA9PSBWQVIgJiYKICAgICAgICAgICAgICAgICAgICAgICAgc3ltLm93bmVyLmtpbmQgPT0gTVRIICYmCiAgICAgICAgICAgICAgICAgICAgICAgICgoVmFyU3ltYm9sKXN5bSkucG9zIDwgY3VycmVudFRyZWUuZ2V0U3RhcnRQb3NpdGlvbigpKSB7CiAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChjdXJyZW50VHJlZS5nZXRUYWcoKSkgewogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIENMQVNTREVGOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFhbGxvd0VmZmVjdGl2ZWx5RmluYWxJbklubmVyQ2xhc3NlcykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydElubmVyQ2xzTmVlZHNGaW5hbEVycm9yKHRyZWUsIHN5bSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgTEFNQkRBOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwb3J0RWZmZWN0aXZlbHlGaW5hbEVycm9yKHRyZWUsIHN5bSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICB2b2lkIHJlcG9ydEVmZmVjdGl2ZWx5RmluYWxFcnJvcihEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBTeW1ib2wgc3ltKSB7CiAgICAgICAgICAgIFN0cmluZyBzdWJLZXkgPSBjdXJyZW50VHJlZS5oYXNUYWcoTEFNQkRBKSA/CiAgICAgICAgICAgICAgICAgICJsYW1iZGEiICA6ICJpbm5lci5jbHMiOwogICAgICAgICAgICBsb2cuZXJyb3IocG9zLCAiY2FudC5yZWYubm9uLmVmZmVjdGl2ZWx5LmZpbmFsLnZhciIsIHN5bSwgZGlhZ3MuZnJhZ21lbnQoc3ViS2V5KSk7CiAgICAgICAgfQoKICAgICAgICB2b2lkIHJlcG9ydElubmVyQ2xzTmVlZHNGaW5hbEVycm9yKERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIFN5bWJvbCBzeW0pIHsKICAgICAgICAgICAgbG9nLmVycm9yKHBvcywKICAgICAgICAgICAgICAgICAgICAibG9jYWwudmFyLmFjY2Vzc2VkLmZyb20uaWNscy5uZWVkcy5maW5hbCIsCiAgICAgICAgICAgICAgICAgICAgc3ltKTsKICAgICAgICB9CgogICAgLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICAgICAqIFZpc2l0b3IgbWV0aG9kcyBmb3Igc3RhdGVtZW50cyBhbmQgZGVmaW5pdGlvbnMKICAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKICAgICAgICAvKiAtLS0tLS0tLS0tLS0gVmlzaXRvciBtZXRob2RzIGZvciB2YXJpb3VzIHNvcnRzIG9mIHRyZWVzIC0tLS0tLS0tLS0tLS0qLwoKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdENsYXNzRGVmKEpDQ2xhc3NEZWNsIHRyZWUpIHsKICAgICAgICAgICAgSkNUcmVlIHByZXZUcmVlID0gY3VycmVudFRyZWU7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBjdXJyZW50VHJlZSA9IHRyZWUuc3ltLmlzTG9jYWwoKSA/IHRyZWUgOiBudWxsOwogICAgICAgICAgICAgICAgc3VwZXIudmlzaXRDbGFzc0RlZih0cmVlKTsKICAgICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgICAgIGN1cnJlbnRUcmVlID0gcHJldlRyZWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0TGFtYmRhKEpDTGFtYmRhIHRyZWUpIHsKICAgICAgICAgICAgSkNUcmVlIHByZXZUcmVlID0gY3VycmVudFRyZWU7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBjdXJyZW50VHJlZSA9IHRyZWU7CiAgICAgICAgICAgICAgICBzdXBlci52aXNpdExhbWJkYSh0cmVlKTsKICAgICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgICAgIGN1cnJlbnRUcmVlID0gcHJldlRyZWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0SWRlbnQoSkNJZGVudCB0cmVlKSB7CiAgICAgICAgICAgIGlmICh0cmVlLnN5bS5raW5kID09IFZBUikgewogICAgICAgICAgICAgICAgY2hlY2tFZmZlY3RpdmVseUZpbmFsKHRyZWUsIChWYXJTeW1ib2wpdHJlZS5zeW0pOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdEFzc2lnbihKQ0Fzc2lnbiB0cmVlKSB7CiAgICAgICAgICAgIEpDVHJlZSBsaHMgPSBUcmVlSW5mby5za2lwUGFyZW5zKHRyZWUubGhzKTsKICAgICAgICAgICAgaWYgKCEobGhzIGluc3RhbmNlb2YgSkNJZGVudCkpIHsKICAgICAgICAgICAgICAgIHNjYW4obGhzKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBzY2FuKHRyZWUucmhzKTsKICAgICAgICAgICAgbGV0SW5pdChsaHMpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRBc3NpZ25vcChKQ0Fzc2lnbk9wIHRyZWUpIHsKICAgICAgICAgICAgc2Nhbih0cmVlLmxocyk7CiAgICAgICAgICAgIHNjYW4odHJlZS5yaHMpOwogICAgICAgICAgICBsZXRJbml0KHRyZWUubGhzKTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0VW5hcnkoSkNVbmFyeSB0cmVlKSB7CiAgICAgICAgICAgIHN3aXRjaCAodHJlZS5nZXRUYWcoKSkgewogICAgICAgICAgICAgICAgY2FzZSBQUkVJTkM6IGNhc2UgUE9TVElOQzoKICAgICAgICAgICAgICAgIGNhc2UgUFJFREVDOiBjYXNlIFBPU1RERUM6CiAgICAgICAgICAgICAgICAgICAgc2Nhbih0cmVlLmFyZyk7CiAgICAgICAgICAgICAgICAgICAgbGV0SW5pdCh0cmVlLmFyZyk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgIHNjYW4odHJlZS5hcmcpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdFRyeShKQ1RyeSB0cmVlKSB7CiAgICAgICAgICAgIGZvciAoSkNUcmVlIHJlc291cmNlIDogdHJlZS5yZXNvdXJjZXMpIHsKICAgICAgICAgICAgICAgIGlmICghcmVzb3VyY2UuaGFzVGFnKFZBUkRFRikpIHsKICAgICAgICAgICAgICAgICAgICBTeW1ib2wgdmFyID0gVHJlZUluZm8uc3ltYm9sKHJlc291cmNlKTsKICAgICAgICAgICAgICAgICAgICBpZiAodmFyICE9IG51bGwgJiYgKHZhci5mbGFncygpICYgKEZJTkFMIHwgRUZGRUNUSVZFTFlfRklOQUwpKSA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGxvZy5lcnJvcihyZXNvdXJjZS5wb3MoKSwgInRyeS53aXRoLnJlc291cmNlcy5leHByLmVmZmVjdGl2ZWx5LmZpbmFsLnZhciIsIHZhcik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHN1cGVyLnZpc2l0VHJ5KHRyZWUpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRNb2R1bGVEZWYoSkNNb2R1bGVEZWNsIHRyZWUpIHsKICAgICAgICAgICAgLy8gRG8gbm90aGluZyBmb3IgbW9kdWxlcwogICAgICAgIH0KCiAgICAvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICAgICAqIG1haW4gbWV0aG9kCiAgICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiAgICAgICAgLyoqIFBlcmZvcm0gZGVmaW5pdGUgYXNzaWdubWVudC91bmFzc2lnbm1lbnQgYW5hbHlzaXMgb24gYSB0cmVlLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyB2b2lkIGFuYWx5emVUcmVlKEVudjxBdHRyQ29udGV4dD4gZW52LCBUcmVlTWFrZXIgbWFrZSkgewogICAgICAgICAgICBhbmFseXplVHJlZShlbnYsIGVudi50cmVlLCBtYWtlKTsKICAgICAgICB9CiAgICAgICAgcHVibGljIHZvaWQgYW5hbHl6ZVRyZWUoRW52PEF0dHJDb250ZXh0PiBlbnYsIEpDVHJlZSB0cmVlLCBUcmVlTWFrZXIgbWFrZSkgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgYXR0ckVudiA9IGVudjsKICAgICAgICAgICAgICAgIEZsb3cudGhpcy5tYWtlID0gbWFrZTsKICAgICAgICAgICAgICAgIHBlbmRpbmdFeGl0cyA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICAgICAgICAgIHNjYW4odHJlZSk7CiAgICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgICAgICBwZW5kaW5nRXhpdHMgPSBudWxsOwogICAgICAgICAgICAgICAgRmxvdy50aGlzLm1ha2UgPSBudWxsOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQp9ClBLAwQKAAAIAAAGO6lKGopaOiuLAAAriwAAJwAAAGNvbS9zdW4vdG9vbHMvamF2YWMvY29tcC9PcGVyYXRvcnMuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAxNSwgMjAxNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLmphdmFjLmNvbXA7CgppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlN5bWJvbDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5TeW1ib2wuT3BlcmF0b3JTeW1ib2w7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuU3ltdGFiOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlR5cGU7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuVHlwZS5NZXRob2RUeXBlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlR5cGVUYWc7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuVHlwZXM7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmp2bS5CeXRlQ29kZXM7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnJlc291cmNlcy5Db21waWxlclByb3BlcnRpZXMuRXJyb3JzOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkpDVHJlZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5KQ1RyZWUuVGFnOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkFzc2VydDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5Db250ZXh0OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkpDRGlhZ25vc3RpYzsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5KQ0RpYWdub3N0aWMuRGlhZ25vc3RpY1Bvc2l0aW9uOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkxpc3Q7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuTG9nOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLk5hbWU7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuTmFtZXM7CgppbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CmltcG9ydCBqYXZhLnV0aWwuTWFwOwppbXBvcnQgamF2YS51dGlsLk9wdGlvbmFsOwppbXBvcnQgamF2YS51dGlsLmZ1bmN0aW9uLkJpUHJlZGljYXRlOwppbXBvcnQgamF2YS51dGlsLmZ1bmN0aW9uLkZ1bmN0aW9uOwppbXBvcnQgamF2YS51dGlsLmZ1bmN0aW9uLlByZWRpY2F0ZTsKaW1wb3J0IGphdmEudXRpbC5mdW5jdGlvbi5TdXBwbGllcjsKaW1wb3J0IGphdmEudXRpbC5zdHJlYW0uU3RyZWFtOwoKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmp2bS5CeXRlQ29kZXMuKjsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmNvbXAuT3BlcmF0b3JzLk9wZXJhdG9yVHlwZS4qOwoKLyoqCiAqIFRoaXMgY2xhc3MgY29udGFpbnMgdGhlIGxvZ2ljIGZvciB1bmFyeSBhbmQgYmluYXJ5IG9wZXJhdG9yIHJlc29sdXRpb24vbG9va3VwLgogKgogKiA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yCiAqIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj4KICovCnB1YmxpYyBjbGFzcyBPcGVyYXRvcnMgewogICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBDb250ZXh0LktleTxPcGVyYXRvcnM+IG9wZXJhdG9yc0tleSA9IG5ldyBDb250ZXh0LktleTw+KCk7CgogICAgcHJpdmF0ZSBmaW5hbCBOYW1lcyBuYW1lczsKICAgIHByaXZhdGUgZmluYWwgTG9nIGxvZzsKICAgIHByaXZhdGUgZmluYWwgU3ltdGFiIHN5bXM7CiAgICBwcml2YXRlIGZpbmFsIFR5cGVzIHR5cGVzOwoKICAgIC8qKiBVbmFyeSBvcGVyYXRvcnMgbWFwLiAqLwogICAgcHJpdmF0ZSBNYXA8TmFtZSwgTGlzdDxVbmFyeU9wZXJhdG9ySGVscGVyPj4gdW5hcnlPcGVyYXRvcnMgPSBuZXcgSGFzaE1hcDw+KFRhZy5nZXROdW1iZXJPZk9wZXJhdG9ycygpKTsKCiAgICAvKiogQmluYXJ5IG9wZXJhdG9ycyBtYXAuICovCiAgICBwcml2YXRlIE1hcDxOYW1lLCBMaXN0PEJpbmFyeU9wZXJhdG9ySGVscGVyPj4gYmluYXJ5T3BlcmF0b3JzID0gbmV3IEhhc2hNYXA8PihUYWcuZ2V0TnVtYmVyT2ZPcGVyYXRvcnMoKSk7CgogICAgLyoqIFRoZSBuYW1lcyBvZiBhbGwgb3BlcmF0b3JzLiAqLwogICAgcHJpdmF0ZSBOYW1lW10gb3BuYW1lID0gbmV3IE5hbWVbVGFnLmdldE51bWJlck9mT3BlcmF0b3JzKCldOwoKICAgIHB1YmxpYyBzdGF0aWMgT3BlcmF0b3JzIGluc3RhbmNlKENvbnRleHQgY29udGV4dCkgewogICAgICAgIE9wZXJhdG9ycyBpbnN0YW5jZSA9IGNvbnRleHQuZ2V0KG9wZXJhdG9yc0tleSk7CiAgICAgICAgaWYgKGluc3RhbmNlID09IG51bGwpCiAgICAgICAgICAgIGluc3RhbmNlID0gbmV3IE9wZXJhdG9ycyhjb250ZXh0KTsKICAgICAgICByZXR1cm4gaW5zdGFuY2U7CiAgICB9CgogICAgcHJvdGVjdGVkIE9wZXJhdG9ycyhDb250ZXh0IGNvbnRleHQpIHsKICAgICAgICBjb250ZXh0LnB1dChvcGVyYXRvcnNLZXksIHRoaXMpOwogICAgICAgIHN5bXMgPSBTeW10YWIuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgbmFtZXMgPSBOYW1lcy5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBsb2cgPSBMb2cuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgdHlwZXMgPSBUeXBlcy5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBub09wU3ltYm9sID0gbmV3IE9wZXJhdG9yU3ltYm9sKG5hbWVzLmVtcHR5LCBUeXBlLm5vVHlwZSwgLTEsIHN5bXMubm9TeW1ib2wpOwogICAgICAgIGluaXRPcGVyYXRvck5hbWVzKCk7CiAgICAgICAgaW5pdFVuYXJ5T3BlcmF0b3JzKCk7CiAgICAgICAgaW5pdEJpbmFyeU9wZXJhdG9ycygpOwogICAgfQoKICAgIC8qKgogICAgICogUGVyZm9ybSB1bmFyeSBwcm9tb3Rpb24gb2YgYSB0eXBlOyB0aGlzIHJvdXRpbmUgaW1wbGVtZW50cyBKTFMgNS42LjEuCiAgICAgKiBJZiB0aGUgaW5wdXQgdHlwZSBpcyBub3Qgc3VwcG9ydGVkIGJ5IHVuYXJ5IHByb21vdGlvbiwgaXQgaXMgcmV0dXJuZWQgdW5hbHRlcmVkLgogICAgICovCiAgICBUeXBlIHVuYXJ5UHJvbW90aW9uKFR5cGUgdCkgewogICAgICAgIFR5cGUgdW5ib3hlZCA9IHR5cGVzLnVuYm94ZWRUeXBlT3JUeXBlKHQpOwogICAgICAgIHN3aXRjaCAodW5ib3hlZC5nZXRUYWcoKSkgewogICAgICAgICAgICBjYXNlIEJZVEU6CiAgICAgICAgICAgIGNhc2UgU0hPUlQ6CiAgICAgICAgICAgIGNhc2UgQ0hBUjoKICAgICAgICAgICAgICAgIHJldHVybiBzeW1zLmludFR5cGU7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICByZXR1cm4gdW5ib3hlZDsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBQZXJmb3JtIGJpbmFyeSBwcm9tb3Rpb24gb2YgYSBwYWlyIG9mIHR5cGVzOyB0aGlzIHJvdXRpbmUgaW1wbGVtZW50cyBKTFMgNS42LjIuCiAgICAgKiBJZiB0aGUgaW5wdXQgdHlwZXMgYXJlIG5vdCBzdXBwb3J0ZWQgYnkgdW5hcnkgcHJvbW90aW9uLCBpZiBzdWNoIHR5cGVzIGFyZSBpZGVudGljYWwgdG8KICAgICAqIGEgdHlwZSBDLCB0aGVuIEMgaXMgcmV0dXJuZWQsIG90aGVyd2lzZSBPYmplY3QgaXMgcmV0dXJuZWQuCiAgICAgKi8KICAgIFR5cGUgYmluYXJ5UHJvbW90aW9uKFR5cGUgdDEsIFR5cGUgdDIpIHsKICAgICAgICBUeXBlIHVuYm94ZWRUMSA9IHR5cGVzLnVuYm94ZWRUeXBlT3JUeXBlKHQxKTsKICAgICAgICBUeXBlIHVuYm94ZWRUMiA9IHR5cGVzLnVuYm94ZWRUeXBlT3JUeXBlKHQyKTsKCiAgICAgICAgaWYgKHVuYm94ZWRUMS5pc051bWVyaWMoKSAmJiB1bmJveGVkVDIuaXNOdW1lcmljKCkpIHsKICAgICAgICAgICAgaWYgKHVuYm94ZWRUMS5oYXNUYWcoVHlwZVRhZy5ET1VCTEUpIHx8IHVuYm94ZWRUMi5oYXNUYWcoVHlwZVRhZy5ET1VCTEUpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gc3ltcy5kb3VibGVUeXBlOwogICAgICAgICAgICB9IGVsc2UgaWYgKHVuYm94ZWRUMS5oYXNUYWcoVHlwZVRhZy5GTE9BVCkgfHwgdW5ib3hlZFQyLmhhc1RhZyhUeXBlVGFnLkZMT0FUKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIHN5bXMuZmxvYXRUeXBlOwogICAgICAgICAgICB9IGVsc2UgaWYgKHVuYm94ZWRUMS5oYXNUYWcoVHlwZVRhZy5MT05HKSB8fCB1bmJveGVkVDIuaGFzVGFnKFR5cGVUYWcuTE9ORykpIHsKICAgICAgICAgICAgICAgIHJldHVybiBzeW1zLmxvbmdUeXBlOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcmV0dXJuIHN5bXMuaW50VHlwZTsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSBpZiAodHlwZXMuaXNTYW1lVHlwZSh1bmJveGVkVDEsIHVuYm94ZWRUMikpIHsKICAgICAgICAgICAgcmV0dXJuIHVuYm94ZWRUMTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gc3ltcy5vYmplY3RUeXBlOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEVudHJ5IHBvaW50IGZvciByZXNvbHZpbmcgYSB1bmFyeSBvcGVyYXRvciBnaXZlbiBhbiBvcGVyYXRvciB0YWcgYW5kIGFuIGFyZ3VtZW50IHR5cGUuCiAgICAgKi8KICAgIE9wZXJhdG9yU3ltYm9sIHJlc29sdmVVbmFyeShEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBKQ1RyZWUuVGFnIHRhZywgVHlwZSBvcCkgewogICAgICAgIHJldHVybiByZXNvbHZlKHRhZywKICAgICAgICAgICAgICAgIHVuYXJ5T3BlcmF0b3JzLAogICAgICAgICAgICAgICAgdW5vcCAtPiB1bm9wLnRlc3Qob3ApLAogICAgICAgICAgICAgICAgdW5vcCAtPiB1bm9wLnJlc29sdmUob3ApLAogICAgICAgICAgICAgICAgKCkgLT4gcmVwb3J0RXJyb3JJZk5lZWRlZChwb3MsIHRhZywgb3ApKTsKICAgIH0KCiAgICAvKioKICAgICAqIEVudHJ5IHBvaW50IGZvciByZXNvbHZpbmcgYSBiaW5hcnkgb3BlcmF0b3IgZ2l2ZW4gYW4gb3BlcmF0b3IgdGFnIGFuZCBhIHBhaXIgb2YgYXJndW1lbnQgdHlwZXMuCiAgICAgKi8KICAgIE9wZXJhdG9yU3ltYm9sIHJlc29sdmVCaW5hcnkoRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcywgSkNUcmVlLlRhZyB0YWcsIFR5cGUgb3AxLCBUeXBlIG9wMikgewogICAgICAgIHJldHVybiByZXNvbHZlKHRhZywKICAgICAgICAgICAgICAgIGJpbmFyeU9wZXJhdG9ycywKICAgICAgICAgICAgICAgIGJpbm9wIC0+IGJpbm9wLnRlc3Qob3AxLCBvcDIpLAogICAgICAgICAgICAgICAgYmlub3AgLT4gYmlub3AucmVzb2x2ZShvcDEsIG9wMiksCiAgICAgICAgICAgICAgICAoKSAtPiByZXBvcnRFcnJvcklmTmVlZGVkKHBvcywgdGFnLCBvcDEsIG9wMikpOwogICAgfQoKICAgIC8qKgogICAgICogTWFpbiBvcGVyYXRvciBsb29rdXAgcm91dGluZTsgbG9va3VwIGFuIG9wZXJhdG9yIChlaXRoZXIgdW5hcnkgb3IgYmluYXJ5KSBpbiBpdHMgY29ycmVzcG9uZGluZwogICAgICogbWFwLiBJZiB0aGVyZSdzIGEgbWF0Y2hpbmcgb3BlcmF0b3IsIGl0cyByZXNvbHZlIHJvdXRpbmUgaXMgY2FsbGVkIGFuZCB0aGUgcmVzdWx0IGlzIHJldHVybmVkOwogICAgICogb3RoZXJ3aXNlIHRoZSByZXN1bHQgb2YgYSBmYWxsYmFjayBmdW5jdGlvbiBpcyByZXR1cm5lZC4KICAgICAqLwogICAgcHJpdmF0ZSA8Tz4gT3BlcmF0b3JTeW1ib2wgcmVzb2x2ZShUYWcgdGFnLCBNYXA8TmFtZSwgTGlzdDxPPj4gb3BNYXAsIFByZWRpY2F0ZTxPPiBvcFRlc3RGdW5jLAogICAgICAgICAgICAgICAgICAgICAgIEZ1bmN0aW9uPE8sIE9wZXJhdG9yU3ltYm9sPiByZXNvbHZlRnVuYywgU3VwcGxpZXI8T3BlcmF0b3JTeW1ib2w+IG5vUmVzdWx0RnVuYykgewogICAgICAgIHJldHVybiBvcE1hcC5nZXQob3BlcmF0b3JOYW1lKHRhZykpLnN0cmVhbSgpCiAgICAgICAgICAgICAgICAuZmlsdGVyKG9wVGVzdEZ1bmMpCiAgICAgICAgICAgICAgICAubWFwKHJlc29sdmVGdW5jKQogICAgICAgICAgICAgICAgLmZpbmRGaXJzdCgpCiAgICAgICAgICAgICAgICAub3JFbHNlR2V0KG5vUmVzdWx0RnVuYyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDcmVhdGVzIGFuIG9wZXJhdG9yIHN5bWJvbC4KICAgICAqLwogICAgcHJpdmF0ZSBPcGVyYXRvclN5bWJvbCBtYWtlT3BlcmF0b3IoTmFtZSBuYW1lLCBMaXN0PE9wZXJhdG9yVHlwZT4gZm9ybWFscywgT3BlcmF0b3JUeXBlIHJlcywgaW50Li4uIG9wY29kZXMpIHsKICAgICAgICBNZXRob2RUeXBlIG9wVHlwZSA9IG5ldyBNZXRob2RUeXBlKAogICAgICAgICAgICAgICAgZm9ybWFscy5zdHJlYW0oKQogICAgICAgICAgICAgICAgICAgICAgICAubWFwKG8gLT4gby5hc1R5cGUoc3ltcykpCiAgICAgICAgICAgICAgICAgICAgICAgIC5jb2xsZWN0KExpc3QuY29sbGVjdG9yKCkpLAogICAgICAgICAgICAgICAgcmVzLmFzVHlwZShzeW1zKSwgTGlzdC5uaWwoKSwgc3ltcy5tZXRob2RDbGFzcyk7CiAgICAgICAgcmV0dXJuIG5ldyBPcGVyYXRvclN5bWJvbChuYW1lLCBvcFR5cGUsIG1lcmdlT3Bjb2RlcyhvcGNvZGVzKSwgc3ltcy5ub1N5bWJvbCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBGb2xkIHR3byBvcGNvZGVzIGluIGEgc2luZ2xlIGludCB2YWx1ZSAoaWYgcmVxdWlyZWQpLgogICAgICovCiAgICBwcml2YXRlIGludCBtZXJnZU9wY29kZXMoaW50Li4uIG9wY29kZXMpIHsKICAgICAgICBpbnQgb3Bjb2Rlc0xlbiA9IG9wY29kZXMubGVuZ3RoOwogICAgICAgIEFzc2VydC5jaGVjayhvcGNvZGVzTGVuID09IDEgfHwgb3Bjb2Rlc0xlbiA9PSAyKTsKICAgICAgICByZXR1cm4gKG9wY29kZXNMZW4gPT0gMSkgPwogICAgICAgICAgICAgICAgb3Bjb2Rlc1swXSA6CiAgICAgICAgICAgICAgICAoKG9wY29kZXNbMF0gPDwgQnl0ZUNvZGVzLnByZVNoaWZ0KSB8IG9wY29kZXNbMV0pOwogICAgfQoKICAgIC8qKiBBIHN5bWJvbCB0aGF0IHN0YW5kcyBmb3IgYSBtaXNzaW5nIG9wZXJhdG9yLgogICAgICovCiAgICBwdWJsaWMgZmluYWwgT3BlcmF0b3JTeW1ib2wgbm9PcFN5bWJvbDsKCiAgICAvKioKICAgICAqIFJlcG9ydCBhbiBvcGVyYXRvciBsb29rdXAgZXJyb3IuCiAgICAgKi8KICAgIHByaXZhdGUgT3BlcmF0b3JTeW1ib2wgcmVwb3J0RXJyb3JJZk5lZWRlZChEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBUYWcgdGFnLCBUeXBlLi4uIGFyZ3MpIHsKICAgICAgICBpZiAoU3RyZWFtLm9mKGFyZ3MpLm5vbmVNYXRjaChUeXBlOjppc0Vycm9uZW91cykpIHsKICAgICAgICAgICAgTmFtZSBvcE5hbWUgPSBvcGVyYXRvck5hbWUodGFnKTsKICAgICAgICAgICAgSkNEaWFnbm9zdGljLkVycm9yIG9wRXJyb3IgPSAoYXJncy5sZW5ndGgpID09IDEgPwogICAgICAgICAgICAgICAgICAgIEVycm9ycy5PcGVyYXRvckNhbnRCZUFwcGxpZWQob3BOYW1lLCBhcmdzWzBdKSA6CiAgICAgICAgICAgICAgICAgICAgRXJyb3JzLk9wZXJhdG9yQ2FudEJlQXBwbGllZDEob3BOYW1lLCBhcmdzWzBdLCBhcmdzWzFdKTsKICAgICAgICAgICAgbG9nLmVycm9yKHBvcywgb3BFcnJvcik7CiAgICAgICAgfQogICAgICAgIHJldHVybiBub09wU3ltYm9sOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJuIG5hbWUgb2Ygb3BlcmF0b3Igd2l0aCBnaXZlbiB0cmVlIHRhZy4KICAgICAqLwogICAgcHVibGljIE5hbWUgb3BlcmF0b3JOYW1lKEpDVHJlZS5UYWcgdGFnKSB7CiAgICAgICAgcmV0dXJuIG9wbmFtZVt0YWcub3BlcmF0b3JJbmRleCgpXTsKICAgIH0KCiAgICAvKioKICAgICAqIFRoZSBjb25zdGFudHMgaW4gdGhpcyBlbnVtIHJlcHJlc2VudCB0aGUgdHlwZXMgdXBvbiB3aGljaCBhbGwgdGhlIG9wZXJhdG9yIGhlbHBlcnMKICAgICAqIG9wZXJhdGUgdXBvbi4gVGhpcyBhbGxvd3MgbGF6eSBhbmQgY29uc2lzZSBtYXBwaW5nIGJldHdlZW4gYSB0eXBlIG5hbWUgYW5kIGEgdHlwZSBpbnN0YW5jZS4KICAgICAqLwogICAgZW51bSBPcGVyYXRvclR5cGUgewogICAgICAgIEJZVEUoc3ltcyAtPiBzeW1zLmJ5dGVUeXBlKSwKICAgICAgICBTSE9SVChzeW1zIC0+IHN5bXMuc2hvcnRUeXBlKSwKICAgICAgICBJTlQoc3ltcyAtPiBzeW1zLmludFR5cGUpLAogICAgICAgIExPTkcoc3ltcyAtPiBzeW1zLmxvbmdUeXBlKSwKICAgICAgICBGTE9BVChzeW1zIC0+IHN5bXMuZmxvYXRUeXBlKSwKICAgICAgICBET1VCTEUoc3ltcyAtPiBzeW1zLmRvdWJsZVR5cGUpLAogICAgICAgIENIQVIoc3ltcyAtPiBzeW1zLmNoYXJUeXBlKSwKICAgICAgICBCT09MRUFOKHN5bXMgLT4gc3ltcy5ib29sZWFuVHlwZSksCiAgICAgICAgT0JKRUNUKHN5bXMgLT4gc3ltcy5vYmplY3RUeXBlKSwKICAgICAgICBTVFJJTkcoc3ltcyAtPiBzeW1zLnN0cmluZ1R5cGUpLAogICAgICAgIEJPVChzeW1zIC0+IHN5bXMuYm90VHlwZSk7CgogICAgICAgIGZpbmFsIEZ1bmN0aW9uPFN5bXRhYiwgVHlwZT4gYXNUeXBlRnVuYzsKCiAgICAgICAgT3BlcmF0b3JUeXBlKEZ1bmN0aW9uPFN5bXRhYiwgVHlwZT4gYXNUeXBlRnVuYykgewogICAgICAgICAgICB0aGlzLmFzVHlwZUZ1bmMgPSBhc1R5cGVGdW5jOwogICAgICAgIH0KCiAgICAgICAgVHlwZSBhc1R5cGUoU3ltdGFiIHN5bXMpIHsKICAgICAgICAgICAgcmV0dXJuIGFzVHlwZUZ1bmMuYXBwbHkoc3ltcyk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQ29tbW9uIHJvb3QgZm9yIGFsbCBvcGVyYXRvciBoZWxwZXJzLiBBbiBvcGVyYXRvciBoZWxwZXIgaW5zdGFuY2UgaXMgYXNzb2NpYXRlZCB3aXRoIGEKICAgICAqIGdpdmVuIG9wZXJhdG9yIChpLmUuICcrJyk7IGl0IGNvbnRhaW5zIHJvdXRpbmVzIHRvIHBlcmZvcm0gb3BlcmF0b3IgbG9va3VwLCBpLmUuIGZpbmQKICAgICAqIHdoaWNoIHZlcnNpb24gb2YgdGhlICcrJyBvcGVyYXRvciBpcyB0aGUgYmVzdCBnaXZlbiBhbiBhcmd1bWVudCB0eXBlIGxpc3QuIFN1cHBvcnRlZAogICAgICogb3BlcmF0b3Igc3ltYm9scyBhcmUgaW5pdGlhbGl6ZWQgbGF6aWx5IHVwb24gZmlyc3QgbG9va3VwIHJlcXVlc3QgLSB0aGlzIGlzIGluIG9yZGVyIHRvIGF2b2lkCiAgICAgKiBpbml0aWFsaXphdGlvbiBjaXJjdWxhcml0aWVzIGJldHdlZW4gdGhpcyBjbGFzcyBhbmQge0Bjb2RlIFN5bXRhYn0uCiAgICAgKi8KICAgIGFic3RyYWN0IGNsYXNzIE9wZXJhdG9ySGVscGVyIHsKCiAgICAgICAgLyoqIFRoZSBvcGVyYXRvciBuYW1lLiAqLwogICAgICAgIGZpbmFsIE5hbWUgbmFtZTsKCiAgICAgICAgLyoqIFRoZSBsaXN0IG9mIHN5bWJvbHMgYXNzb2NpYXRlZCB3aXRoIHRoaXMgb3BlcmF0b3IgKGxhemlseSBwb3B1bGF0ZWQpLiAqLwogICAgICAgIE9wdGlvbmFsPE9wZXJhdG9yU3ltYm9sW10+IGFsdGVybmF0aXZlcyA9IE9wdGlvbmFsLmVtcHR5KCk7CgogICAgICAgIC8qKiBBbiBhcnJheSBvZiBvcGVyYXRvciBzeW1ib2wgc3VwcGxpZXJzICh1c2VkIHRvIGxhemlseSBwb3B1bGF0ZSB0aGUgc3ltYm9sIGxpc3QpLiAqLwogICAgICAgIExpc3Q8U3VwcGxpZXI8T3BlcmF0b3JTeW1ib2w+PiBvcGVyYXRvclN1cHBsaWVycyA9IExpc3QubmlsKCk7CgogICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ2YXJhcmdzIikKICAgICAgICBPcGVyYXRvckhlbHBlcihUYWcgdGFnKSB7CiAgICAgICAgICAgIHRoaXMubmFtZSA9IG9wZXJhdG9yTmFtZSh0YWcpOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogVGhpcyByb3V0aW5lIGltcGxlbWVudHMgdGhlIG1haW4gb3BlcmF0b3IgbG9va3VwIHByb2Nlc3MuIEVhY2ggb3BlcmF0b3IgaXMgdGVzdGVkCiAgICAgICAgICogdXNpbmcgYW4gYXBwbGljYWJpbGl0eSBwcmVkaWNhdGU7IGlmIHRoZSB0ZXN0IHN1Y2VlZHMgdGhhdCBzYW1lIG9wZXJhdG9yIGlzIHJldHVybmVkLAogICAgICAgICAqIG90aGVyd2lzZSBhIGR1bW15IHN5bWJvbCBpcyByZXR1cm5lZC4KICAgICAgICAgKi8KICAgICAgICBmaW5hbCBPcGVyYXRvclN5bWJvbCBkb0xvb2t1cChQcmVkaWNhdGU8T3BlcmF0b3JTeW1ib2w+IGFwcGxpY2FiaWxpdHlUZXN0KSB7CiAgICAgICAgICAgIHJldHVybiBTdHJlYW0ub2YoYWx0ZXJuYXRpdmVzLm9yRWxzZUdldCh0aGlzOjppbml0T3BlcmF0b3JzKSkKICAgICAgICAgICAgICAgICAgICAuZmlsdGVyKGFwcGxpY2FiaWxpdHlUZXN0KQogICAgICAgICAgICAgICAgICAgIC5maW5kRmlyc3QoKQogICAgICAgICAgICAgICAgICAgIC5vckVsc2Uobm9PcFN5bWJvbCk7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBUaGlzIHJvdXRpbmUgcGVyZm9ybXMgbGF6eSBpbnN0YW50aWF0aW9uIG9mIHRoZSBvcGVyYXRvciBzeW1ib2xzIHN1cHBvcnRlZCBieSB0aGlzIGhlbHBlci4KICAgICAgICAgKiBBZnRlciBpbml0aWFsaXphdGlvbiBpcyBkb25lLCB0aGUgc3VwcGxpZXJzIGFyZSBjbGVhcmVkLCB0byBmcmVlIHVwIG1lbW9yeS4KICAgICAgICAgKi8KICAgICAgICBwcml2YXRlIE9wZXJhdG9yU3ltYm9sW10gaW5pdE9wZXJhdG9ycygpIHsKICAgICAgICAgICAgT3BlcmF0b3JTeW1ib2xbXSBvcGVyYXRvcnMgPSBvcGVyYXRvclN1cHBsaWVycy5zdHJlYW0oKQogICAgICAgICAgICAgICAgICAgIC5tYXAoU3VwcGxpZXI6OmdldCkKICAgICAgICAgICAgICAgICAgICAudG9BcnJheShPcGVyYXRvclN5bWJvbFtdOjpuZXcpOwogICAgICAgICAgICBhbHRlcm5hdGl2ZXMgPSBPcHRpb25hbC5vZihvcGVyYXRvcnMpOwogICAgICAgICAgICBvcGVyYXRvclN1cHBsaWVycyA9IG51bGw7IC8vbGV0IEdDIGRvIGl0cyB3b3JrCiAgICAgICAgICAgIHJldHVybiBvcGVyYXRvcnM7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQ29tbW9uIHN1cGVyY2xhc3MgZm9yIGFsbCB1bmFyeSBvcGVyYXRvciBoZWxwZXJzLgogICAgICovCiAgICBhYnN0cmFjdCBjbGFzcyBVbmFyeU9wZXJhdG9ySGVscGVyIGV4dGVuZHMgT3BlcmF0b3JIZWxwZXIgaW1wbGVtZW50cyBQcmVkaWNhdGU8VHlwZT4gewoKICAgICAgICBVbmFyeU9wZXJhdG9ySGVscGVyKFRhZyB0YWcpIHsKICAgICAgICAgICAgc3VwZXIodGFnKTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIFRoaXMgcm91dGluZSBpbXBsZW1lbnRzIHRoZSB1bmFyeSBvcGVyYXRvciBsb29rdXAgcHJvY2Vzcy4gSXQgY3VzdG9taXplcyB0aGUgYmVoYXZpb3IKICAgICAgICAgKiBvZiB0aGUgc2hhcmVkIGxvb2t1cCByb3V0aW5lIGluIHtAbGluayBPcGVyYXRvckhlbHBlcn0sIGJ5IHVzaW5nIGFuIHVuYXJ5IGFwcGxpY2FiaWxpdHkgdGVzdAogICAgICAgICAqIChzZWUge0BsaW5rIFVuYXJ5T3BlcmF0b3JIZWxwZXIjaXNVbmFyeU9wZXJhdG9yQXBwbGljYWJsZShPcGVyYXRvck9wZXJhdG9yU3ltYm9sLCBUeXBlKX0KICAgICAgICAgKi8KICAgICAgICBmaW5hbCBPcGVyYXRvclN5bWJvbCBkb0xvb2t1cChUeXBlIHQpIHsKICAgICAgICAgICAgcmV0dXJuIGRvTG9va3VwKG9wIC0+IGlzVW5hcnlPcGVyYXRvckFwcGxpY2FibGUob3AsIHQpKTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIFVuYXJ5IG9wZXJhdG9yIGFwcGxpY2FiaWxpdHkgdGVzdCAtIGlzIHRoZSBpbnB1dCB0eXBlIHRoZSBzYW1lIGFzIHRoZSBleHBlY3RlZCBvcGVyYW5kIHR5cGU/CiAgICAgICAgICovCiAgICAgICAgYm9vbGVhbiBpc1VuYXJ5T3BlcmF0b3JBcHBsaWNhYmxlKE9wZXJhdG9yU3ltYm9sIG9wLCBUeXBlIHQpIHsKICAgICAgICAgICAgcmV0dXJuIHR5cGVzLmlzU2FtZVR5cGUob3AudHlwZS5nZXRQYXJhbWV0ZXJUeXBlcygpLmhlYWQsIHQpOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogQWRkcyBhIHVuYXJ5IG9wZXJhdG9yIHN5bWJvbC4KICAgICAgICAgKi8KICAgICAgICBmaW5hbCBVbmFyeU9wZXJhdG9ySGVscGVyIGFkZFVuYXJ5T3BlcmF0b3IoT3BlcmF0b3JUeXBlIGFyZywgT3BlcmF0b3JUeXBlIHJlcywgaW50Li4uIG9wY29kZSkgewogICAgICAgICAgICBvcGVyYXRvclN1cHBsaWVycyA9IG9wZXJhdG9yU3VwcGxpZXJzLnByZXBlbmQoKCkgLT4gbWFrZU9wZXJhdG9yKG5hbWUsIExpc3Qub2YoYXJnKSwgcmVzLCBvcGNvZGUpKTsKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBUaGlzIG1ldGhvZCB3aWxsIGJlIG92ZXJyaWRkZW4gYnkgdW5hcnkgb3BlcmF0b3IgaGVscGVycyB0byBwcm92aWRlIGN1c3RvbSByZXNvbHV0aW9uCiAgICAgICAgICogbG9naWMuCiAgICAgICAgICovCiAgICAgICAgYWJzdHJhY3QgT3BlcmF0b3JTeW1ib2wgcmVzb2x2ZShUeXBlIHQpOwogICAgfQoKICAgIGFic3RyYWN0IGNsYXNzIEJpbmFyeU9wZXJhdG9ySGVscGVyIGV4dGVuZHMgT3BlcmF0b3JIZWxwZXIgaW1wbGVtZW50cyBCaVByZWRpY2F0ZTxUeXBlLCBUeXBlPiB7CgogICAgICAgIEJpbmFyeU9wZXJhdG9ySGVscGVyKFRhZyB0YWcpIHsKICAgICAgICAgICAgc3VwZXIodGFnKTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIFRoaXMgcm91dGluZSBpbXBsZW1lbnRzIHRoZSBiaW5hcnkgb3BlcmF0b3IgbG9va3VwIHByb2Nlc3MuIEl0IGN1c3RvbWl6ZXMgdGhlIGJlaGF2aW9yCiAgICAgICAgICogb2YgdGhlIHNoYXJlZCBsb29rdXAgcm91dGluZSBpbiB7QGxpbmsgT3BlcmF0b3JIZWxwZXJ9LCBieSB1c2luZyBhbiB1bmFyeSBhcHBsaWNhYmlsaXR5IHRlc3QKICAgICAgICAgKiAoc2VlIHtAbGluayBCaW5hcnlPcGVyYXRvckhlbHBlciNpc0JpbmFyeU9wZXJhdG9yQXBwbGljYWJsZShPcGVyYXRvclN5bWJvbCwgVHlwZSwgVHlwZSl9CiAgICAgICAgICovCiAgICAgICAgZmluYWwgT3BlcmF0b3JTeW1ib2wgZG9Mb29rdXAoVHlwZSB0MSwgVHlwZSB0MikgewogICAgICAgICAgICByZXR1cm4gZG9Mb29rdXAob3AgLT4gaXNCaW5hcnlPcGVyYXRvckFwcGxpY2FibGUob3AsIHQxLCB0MikpOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogQmluYXJ5IG9wZXJhdG9yIGFwcGxpY2FiaWxpdHkgdGVzdCAtIGFyZSB0aGUgaW5wdXQgdHlwZXMgdGhlIHNhbWUgYXMgdGhlIGV4cGVjdGVkIG9wZXJhbmQgdHlwZXM/CiAgICAgICAgICovCiAgICAgICAgYm9vbGVhbiBpc0JpbmFyeU9wZXJhdG9yQXBwbGljYWJsZShPcGVyYXRvclN5bWJvbCBvcCwgVHlwZSB0MSwgVHlwZSB0MikgewogICAgICAgICAgICBMaXN0PFR5cGU+IGZvcm1hbHMgPSBvcC50eXBlLmdldFBhcmFtZXRlclR5cGVzKCk7CiAgICAgICAgICAgIHJldHVybiB0eXBlcy5pc1NhbWVUeXBlKGZvcm1hbHMuaGVhZCwgdDEpICYmCiAgICAgICAgICAgICAgICAgICAgdHlwZXMuaXNTYW1lVHlwZShmb3JtYWxzLnRhaWwuaGVhZCwgdDIpOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogQWRkcyBhIGJpbmFyeSBvcGVyYXRvciBzeW1ib2wuCiAgICAgICAgICovCiAgICAgICAgZmluYWwgQmluYXJ5T3BlcmF0b3JIZWxwZXIgYWRkQmluYXJ5T3BlcmF0b3IoT3BlcmF0b3JUeXBlIGFyZzEsIE9wZXJhdG9yVHlwZSBhcmcyLCBPcGVyYXRvclR5cGUgcmVzLCBpbnQuLi4gb3Bjb2RlKSB7CiAgICAgICAgICAgIG9wZXJhdG9yU3VwcGxpZXJzID0gb3BlcmF0b3JTdXBwbGllcnMucHJlcGVuZCgoKSAtPiBtYWtlT3BlcmF0b3IobmFtZSwgTGlzdC5vZihhcmcxLCBhcmcyKSwgcmVzLCBvcGNvZGUpKTsKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBUaGlzIG1ldGhvZCB3aWxsIGJlIG92ZXJyaWRkZW4gYnkgYmluYXJ5IG9wZXJhdG9yIGhlbHBlcnMgdG8gcHJvdmlkZSBjdXN0b20gcmVzb2x1dGlvbgogICAgICAgICAqIGxvZ2ljLgogICAgICAgICAqLwogICAgICAgIGFic3RyYWN0IE9wZXJhdG9yU3ltYm9sIHJlc29sdmUoVHlwZSB0MSwgVHlwZSB0Mik7CiAgICB9CgogICAgLyoqCiAgICAgKiBDbGFzcyByZXByZXNlbnRpbmcgdW5hcnkgb3BlcmF0b3IgaGVscGVycyB0aGF0IG9wZXJhdGUgb24gcmVmZXJlbmNlIHR5cGVzLgogICAgICovCiAgICBjbGFzcyBVbmFyeVJlZmVyZW5jZU9wZXJhdG9yIGV4dGVuZHMgVW5hcnlPcGVyYXRvckhlbHBlciB7CgogICAgICAgIFVuYXJ5UmVmZXJlbmNlT3BlcmF0b3IoVGFnIHRhZykgewogICAgICAgICAgICBzdXBlcih0YWcpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gdGVzdChUeXBlIHR5cGUpIHsKICAgICAgICAgICAgcmV0dXJuIHR5cGUuaXNOdWxsT3JSZWZlcmVuY2UoKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBPcGVyYXRvclN5bWJvbCByZXNvbHZlKFR5cGUgYXJnKSB7CiAgICAgICAgICAgIHJldHVybiBkb0xvb2t1cChzeW1zLm9iamVjdFR5cGUpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIENsYXNzIHJlcHJlc2VudGluZyB1bmFyeSBvcGVyYXRvciBoZWxwZXJzIHRoYXQgb3BlcmF0ZSBvbiBudW1lcmljIHR5cGVzIChlaXRoZXIgYm94ZWQgb3IgdW5ib3hlZCkuCiAgICAgKiBPcGVyYXRvciBsb29rdXAgaXMgcGVyZm9ybWVkIGFmdGVyIGFwcGx5aW5nIG51bWVyaWMgcHJvbW90aW9uIG9mIHRoZSBpbnB1dCB0eXBlLgogICAgICovCiAgICBjbGFzcyBVbmFyeU51bWVyaWNPcGVyYXRvciBleHRlbmRzIFVuYXJ5T3BlcmF0b3JIZWxwZXIgewoKICAgICAgICBQcmVkaWNhdGU8VHlwZT4gbnVtZXJpY1Rlc3Q7CgogICAgICAgIFVuYXJ5TnVtZXJpY09wZXJhdG9yKFRhZyB0YWcpIHsKICAgICAgICAgICAgdGhpcyh0YWcsIFR5cGU6OmlzTnVtZXJpYyk7CiAgICAgICAgfQoKICAgICAgICBVbmFyeU51bWVyaWNPcGVyYXRvcihUYWcgdGFnLCBQcmVkaWNhdGU8VHlwZT4gbnVtZXJpY1Rlc3QpIHsKICAgICAgICAgICAgc3VwZXIodGFnKTsKICAgICAgICAgICAgdGhpcy5udW1lcmljVGVzdCA9IG51bWVyaWNUZXN0OwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gdGVzdChUeXBlIHR5cGUpIHsKICAgICAgICAgICAgcmV0dXJuIG51bWVyaWNUZXN0LnRlc3QodW5hcnlQcm9tb3Rpb24odHlwZSkpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIE9wZXJhdG9yU3ltYm9sIHJlc29sdmUoVHlwZSBhcmcpIHsKICAgICAgICAgICAgcmV0dXJuIGRvTG9va3VwKHVuYXJ5UHJvbW90aW9uKGFyZykpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIENsYXNzIHJlcHJlc2VudGluZyB1bmFyeSBvcGVyYXRvciBoZWxwZXJzIHRoYXQgb3BlcmF0ZSBvbiBib29sZWFuIHR5cGVzICAoZWl0aGVyIGJveGVkIG9yIHVuYm94ZWQpLgogICAgICogT3BlcmF0b3IgbG9va3VwIGlzIHBlcmZvcm1lZCBhc3N1bWluZyB0aGUgaW5wdXQgdHlwZSBpcyBhIGJvb2xlYW4gdHlwZS4KICAgICAqLwogICAgY2xhc3MgVW5hcnlCb29sZWFuT3BlcmF0b3IgZXh0ZW5kcyBVbmFyeU9wZXJhdG9ySGVscGVyIHsKCiAgICAgICAgVW5hcnlCb29sZWFuT3BlcmF0b3IoVGFnIHRhZykgewogICAgICAgICAgICBzdXBlcih0YWcpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gdGVzdChUeXBlIHR5cGUpIHsKICAgICAgICAgICAgcmV0dXJuIHR5cGVzLnVuYm94ZWRUeXBlT3JUeXBlKHR5cGUpLmhhc1RhZyhUeXBlVGFnLkJPT0xFQU4pOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIE9wZXJhdG9yU3ltYm9sIHJlc29sdmUoVHlwZSBhcmcpIHsKICAgICAgICAgICAgcmV0dXJuIGRvTG9va3VwKHN5bXMuYm9vbGVhblR5cGUpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIENsYXNzIHJlcHJlc2VudGluZyBwcmVmaXgvcG9zdGZpeCB1bmFyeSBvcGVyYXRvciBoZWxwZXJzLiBPcGVyYXRlcyBvbiBudW1lcmljIHR5cGVzIChlaXRoZXIKICAgICAqIGJveGVkIG9yIHVuYm94ZWQpLiBPcGVyYXRvciBsb29rdXAgaXMgcGVyZm9ybWVkIG9uIHRoZSB1bmJveGVkIHZlcnNpb24gb2YgdGhlIGlucHV0IHR5cGUuCiAgICAgKi8KICAgIGNsYXNzIFVuYXJ5UHJlZml4UG9zdGZpeE9wZXJhdG9yIGV4dGVuZHMgVW5hcnlOdW1lcmljT3BlcmF0b3IgewoKICAgICAgICBVbmFyeVByZWZpeFBvc3RmaXhPcGVyYXRvcihUYWcgdGFnKSB7CiAgICAgICAgICAgIHN1cGVyKHRhZyk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgT3BlcmF0b3JTeW1ib2wgcmVzb2x2ZShUeXBlIGFyZykgewogICAgICAgICAgICByZXR1cm4gZG9Mb29rdXAodHlwZXMudW5ib3hlZFR5cGVPclR5cGUoYXJnKSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQ2xhc3MgcmVwcmVzZW50aW5nIGJpbmFyeSBvcGVyYXRvciBoZWxwZXJzIHRoYXQgb3BlcmF0ZSBvbiBudW1lcmljIHR5cGVzIChlaXRoZXIgYm94ZWQgb3IgdW5ib3hlZCkuCiAgICAgKiBPcGVyYXRvciBsb29rdXAgaXMgcGVyZm9ybWVkIGFmdGVyIGFwcGx5aW5nIGJpbmFyeSBudW1lcmljIHByb21vdGlvbiBvZiB0aGUgaW5wdXQgdHlwZXMuCiAgICAgKi8KICAgIGNsYXNzIEJpbmFyeU51bWVyaWNPcGVyYXRvciBleHRlbmRzIEJpbmFyeU9wZXJhdG9ySGVscGVyIHsKCiAgICAgICAgUHJlZGljYXRlPFR5cGU+IG51bWVyaWNUZXN0OwoKICAgICAgICBCaW5hcnlOdW1lcmljT3BlcmF0b3IoVGFnIHRhZykgewogICAgICAgICAgICB0aGlzKHRhZywgVHlwZTo6aXNOdW1lcmljKTsKICAgICAgICB9CgogICAgICAgIEJpbmFyeU51bWVyaWNPcGVyYXRvcihUYWcgdGFnLCBQcmVkaWNhdGU8VHlwZT4gbnVtZXJpY1Rlc3QpIHsKICAgICAgICAgICAgc3VwZXIodGFnKTsKICAgICAgICAgICAgdGhpcy5udW1lcmljVGVzdCA9IG51bWVyaWNUZXN0OwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIE9wZXJhdG9yU3ltYm9sIHJlc29sdmUoVHlwZSBhcmcxLCBUeXBlIGFyZzIpIHsKICAgICAgICAgICAgVHlwZSB0ID0gYmluYXJ5UHJvbW90aW9uKGFyZzEsIGFyZzIpOwogICAgICAgICAgICByZXR1cm4gZG9Mb29rdXAodCwgdCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgYm9vbGVhbiB0ZXN0KFR5cGUgYXJnMSwgVHlwZSBhcmcyKSB7CiAgICAgICAgICAgIHJldHVybiBudW1lcmljVGVzdC50ZXN0KHVuYXJ5UHJvbW90aW9uKGFyZzEpKSAmJgogICAgICAgICAgICAgICAgICAgIG51bWVyaWNUZXN0LnRlc3QodW5hcnlQcm9tb3Rpb24oYXJnMikpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIENsYXNzIHJlcHJlc2VudGluZyBiaXR3aXNlIG9wZXJhdG9yIGhlbHBlcnMgdGhhdCBvcGVyYXRlIG9uIGJvb2xlYW4gdHlwZXMgKGVpdGhlciBib3hlZCBvciB1bmJveGVkKS4KICAgICAqIE9wZXJhdG9yIGxvb2t1cCBpcyBwZXJmb3JtZWQgYXNzdW1pbmcgYm90aCBpbnB1dCB0eXBlcyBhcmUgYm9vbGVhbiB0eXBlcy4KICAgICAqLwogICAgY2xhc3MgQmluYXJ5Qm9vbGVhbk9wZXJhdG9yIGV4dGVuZHMgQmluYXJ5T3BlcmF0b3JIZWxwZXIgewoKICAgICAgICBCaW5hcnlCb29sZWFuT3BlcmF0b3IoVGFnIHRhZykgewogICAgICAgICAgICBzdXBlcih0YWcpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIE9wZXJhdG9yU3ltYm9sIHJlc29sdmUoVHlwZSBhcmcxLCBUeXBlIGFyZzIpIHsKICAgICAgICAgICAgcmV0dXJuIGRvTG9va3VwKHN5bXMuYm9vbGVhblR5cGUsIHN5bXMuYm9vbGVhblR5cGUpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gdGVzdChUeXBlIGFyZzEsIFR5cGUgYXJnMikgewogICAgICAgICAgICByZXR1cm4gdHlwZXMudW5ib3hlZFR5cGVPclR5cGUoYXJnMSkuaGFzVGFnKFR5cGVUYWcuQk9PTEVBTikgJiYKICAgICAgICAgICAgICAgICAgICB0eXBlcy51bmJveGVkVHlwZU9yVHlwZShhcmcyKS5oYXNUYWcoVHlwZVRhZy5CT09MRUFOKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBDbGFzcyByZXByZXNlbnRpbmcgc3RyaW5nIGNvbmNhdGVuYXRpb24gb3BlcmF0b3IgaGVscGVyIHRoYXQgb3BlcmF0ZXMgb24gYXQgbGVhc3QgYW4KICAgICAqIHN0cmluZyBvcGVyYW5kLiBJbnB1dCB0eXBlcyBzdWJqZWN0IHRvIGFuIG9wZXJhdG9yIGxvb2t1cCB1bmRlcmdvZXMgYSBzcGVjaWFsIHN0cmluZyBwcm9tb3Rpb24KICAgICAqIChzZWUge0BsaW5rIEJpbmFyeVN0cmluZ09wZXJhdG9yI3N0cmluZ1Byb21vdGlvbihUeXBlKX0uCiAgICAgKi8KICAgIGNsYXNzIEJpbmFyeVN0cmluZ09wZXJhdG9yIGV4dGVuZHMgQmluYXJ5T3BlcmF0b3JIZWxwZXIgewoKICAgICAgICBCaW5hcnlTdHJpbmdPcGVyYXRvcihUYWcgdGFnKSB7CiAgICAgICAgICAgIHN1cGVyKHRhZyk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgT3BlcmF0b3JTeW1ib2wgcmVzb2x2ZShUeXBlIGFyZzEsIFR5cGUgYXJnMikgewogICAgICAgICAgICByZXR1cm4gZG9Mb29rdXAoc3RyaW5nUHJvbW90aW9uKGFyZzEpLCBzdHJpbmdQcm9tb3Rpb24oYXJnMikpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gdGVzdChUeXBlIGFyZzEsIFR5cGUgYXJnMikgewogICAgICAgICAgICBib29sZWFuIGhhc1N0cmluZ09wID0gdHlwZXMuaXNTYW1lVHlwZShhcmcxLCBzeW1zLnN0cmluZ1R5cGUpIHx8CiAgICAgICAgICAgICAgICAgICAgdHlwZXMuaXNTYW1lVHlwZShhcmcyLCBzeW1zLnN0cmluZ1R5cGUpOwogICAgICAgICAgICBib29sZWFuIGhhc1ZvaWRPcCA9IGFyZzEuaGFzVGFnKFR5cGVUYWcuVk9JRCkgfHwgYXJnMi5oYXNUYWcoVHlwZVRhZy5WT0lEKTsKICAgICAgICAgICAgcmV0dXJuIGhhc1N0cmluZ09wICYmICFoYXNWb2lkT3A7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBUaGlzIHJvdXRpbmUgYXBwbGllcyBmb2xsb3dpbmcgbWFwcGluZ3M6CiAgICAgICAgICogLSBpZiBpbnB1dCB0eXBlIGlzIHByaW1pdGl2ZSwgYXBwbHkgbnVtZXJpYyBwcm9tb3Rpb24KICAgICAgICAgKiAtIGlmIGlucHV0IHR5cGUgaXMgZWl0aGVyICd2b2lkJywgJ251bGwnIG9yICdTdHJpbmcnIGxlYXZlIGl0IHVudG91Y2hlZAogICAgICAgICAqIC0gb3RoZXJ3aXNlIHJldHVybiAnT2JqZWN0JwogICAgICAgICAqLwogICAgICAgIHByaXZhdGUgVHlwZSBzdHJpbmdQcm9tb3Rpb24oVHlwZSB0KSB7CiAgICAgICAgICAgIGlmICh0LmlzUHJpbWl0aXZlKCkpIHsKICAgICAgICAgICAgICAgIHJldHVybiB1bmFyeVByb21vdGlvbih0KTsKICAgICAgICAgICAgfSBlbHNlIGlmICh0Lmhhc1RhZyhUeXBlVGFnLlZPSUQpIHx8IHQuaGFzVGFnKFR5cGVUYWcuQk9UKSB8fAogICAgICAgICAgICAgICAgICAgIHR5cGVzLmlzU2FtZVR5cGUodCwgc3ltcy5zdHJpbmdUeXBlKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIHQ7CiAgICAgICAgICAgIH0gZWxzZSBpZiAodC5oYXNUYWcoVHlwZVRhZy5UWVBFVkFSKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIHN0cmluZ1Byb21vdGlvbih0LmdldFVwcGVyQm91bmQoKSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICByZXR1cm4gc3ltcy5vYmplY3RUeXBlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQ2xhc3MgcmVwcmVzZW50aW5nIHNoaWZ0IG9wZXJhdG9yIGhlbHBlciB0aGF0IG9wZXJhdGVzIG9uIGludGVncmFsIG9wZXJhbmQgdHlwZXMgKGVpdGhlciBib3hlZAogICAgICogb3IgdW5ib3hlZCkuIE9wZXJhdG9yIGxvb2t1cCBpcyBwZXJmb3JtZWQgYWZ0ZXIgYXBwbHlpbmcgdW5hcnkgbnVtZXJpYyBwcm9tb3Rpb24gdG8gZWFjaCBpbnB1dCB0eXBlLgogICAgICovCiAgICBjbGFzcyBCaW5hcnlTaGlmdE9wZXJhdG9yIGV4dGVuZHMgQmluYXJ5T3BlcmF0b3JIZWxwZXIgewoKICAgICAgICBCaW5hcnlTaGlmdE9wZXJhdG9yKFRhZyB0YWcpIHsKICAgICAgICAgICAgc3VwZXIodGFnKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBPcGVyYXRvclN5bWJvbCByZXNvbHZlKFR5cGUgYXJnMSwgVHlwZSBhcmcyKSB7CiAgICAgICAgICAgIHJldHVybiBkb0xvb2t1cCh1bmFyeVByb21vdGlvbihhcmcxKSwgdW5hcnlQcm9tb3Rpb24oYXJnMikpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gdGVzdChUeXBlIGFyZzEsIFR5cGUgYXJnMikgewogICAgICAgICAgICBUeXBlVGFnIG9wMSA9IHVuYXJ5UHJvbW90aW9uKGFyZzEpLmdldFRhZygpOwogICAgICAgICAgICBUeXBlVGFnIG9wMiA9IHVuYXJ5UHJvbW90aW9uKGFyZzIpLmdldFRhZygpOwogICAgICAgICAgICByZXR1cm4gKG9wMSA9PSBUeXBlVGFnLkxPTkcgfHwgb3AxID09IFR5cGVUYWcuSU5UKSAmJgogICAgICAgICAgICAgICAgICAgIChvcDIgPT0gVHlwZVRhZy5MT05HIHx8IG9wMiA9PSBUeXBlVGFnLklOVCk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogVGhpcyBlbnVtIHJlcHJlc2VudCB0aGUgcG9zc2libGUga2luZHMgb2YgYW4gY29tcGFyaXNvbiB0ZXN0ICgnPT0nIGFuZCAnIT0nKS4KICAgICAqLwogICAgZW51bSBDb21wYXJpc29uS2luZCB7CiAgICAgICAgLyoqIGVxdWFsaXR5IGJldHdlZW4gbnVtZXJpYyBvciBib29sZWFuIG9wZXJhbmRzLiAqLwogICAgICAgIE5VTUVSSUNfT1JfQk9PTEVBTiwKICAgICAgICAvKiogZXF1YWxpdHkgYmV0d2VlbiByZWZlcmVuY2Ugb3BlcmFuZHMuICovCiAgICAgICAgUkVGRVJFTkNFLAogICAgICAgIC8qKiBlcnJvbmVvdXMgZXF1YWxpdHkgKi8KICAgICAgICBJTlZBTElECiAgICB9CgogICAgLyoqCiAgICAgKiBDbGFzcyByZXByZXNlbnRpbmcgZXF1YWxpdHkgb3BlcmF0b3IgaGVscGVyIHRoYXQgb3BlcmF0ZXMgb24gZWl0aGVyIG51bWVyaWMsIGJvb2xlYW4gb3IgcmVmZXJlbmNlCiAgICAgKiB0eXBlcy4gT3BlcmF0b3IgbG9va3VwIGZvciBudW1lcmljL2Jvb2xlYW4gZXF1YWxpdHkgdGVzdCBpcyBwZXJmb3JtZWQgYWZ0ZXIgYmluYXJ5IG51bWVyaWMKICAgICAqIHByb21vdGlvbiB0byB0aGUgaW5wdXQgdHlwZXMuIE9wZXJhdG9yIGxvb2t1cCBmb3IgcmVmZXJlbmNlIGVxdWFsaXR5IHRlc3QgaXMgcGVyZm9ybWVkIGFzc3VtaW5nCiAgICAgKiB0aGUgaW5wdXQgdHlwZSBpcyAnT2JqZWN0Jy4KICAgICAqLwogICAgY2xhc3MgQmluYXJ5RXF1YWxpdHlPcGVyYXRvciBleHRlbmRzIEJpbmFyeU9wZXJhdG9ySGVscGVyIHsKCiAgICAgICAgQmluYXJ5RXF1YWxpdHlPcGVyYXRvcihUYWcgdGFnKSB7CiAgICAgICAgICAgIHN1cGVyKHRhZyk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgYm9vbGVhbiB0ZXN0KFR5cGUgYXJnMSwgVHlwZSBhcmcyKSB7CiAgICAgICAgICAgIHJldHVybiBnZXRLaW5kKGFyZzEsIGFyZzIpICE9IENvbXBhcmlzb25LaW5kLklOVkFMSUQ7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgT3BlcmF0b3JTeW1ib2wgcmVzb2x2ZShUeXBlIHQxLCBUeXBlIHQyKSB7CiAgICAgICAgICAgIENvbXBhcmlzb25LaW5kIGtpbmQgPSBnZXRLaW5kKHQxLCB0Mik7CiAgICAgICAgICAgIFR5cGUgdCA9IChraW5kID09IENvbXBhcmlzb25LaW5kLk5VTUVSSUNfT1JfQk9PTEVBTikgPwogICAgICAgICAgICAgICAgICAgIGJpbmFyeVByb21vdGlvbih0MSwgdDIpIDoKICAgICAgICAgICAgICAgICAgICBzeW1zLm9iamVjdFR5cGU7CiAgICAgICAgICAgIHJldHVybiBkb0xvb2t1cCh0LCB0KTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIFJldHJpZXZlIHRoZSBjb21wYXJpc29uIGtpbmQgYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBhcmd1bWVudCB0eXBlIHBhaXIuCiAgICAgICAgICovCiAgICAgICAgcHJpdmF0ZSBDb21wYXJpc29uS2luZCBnZXRLaW5kKFR5cGUgYXJnMSwgVHlwZSBhcmcyKSB7CiAgICAgICAgICAgIGJvb2xlYW4gYXJnMVByaW1pdGl2ZSA9IGFyZzEuaXNQcmltaXRpdmUoKTsKICAgICAgICAgICAgYm9vbGVhbiBhcmcyUHJpbWl0aXZlID0gYXJnMi5pc1ByaW1pdGl2ZSgpOwogICAgICAgICAgICBpZiAoYXJnMVByaW1pdGl2ZSAmJiBhcmcyUHJpbWl0aXZlKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gQ29tcGFyaXNvbktpbmQuTlVNRVJJQ19PUl9CT09MRUFOOwogICAgICAgICAgICB9IGVsc2UgaWYgKGFyZzFQcmltaXRpdmUpIHsKICAgICAgICAgICAgICAgIHJldHVybiB1bmFyeVByb21vdGlvbihhcmcyKS5pc1ByaW1pdGl2ZSgpID8KICAgICAgICAgICAgICAgICAgICAgICAgQ29tcGFyaXNvbktpbmQuTlVNRVJJQ19PUl9CT09MRUFOIDogQ29tcGFyaXNvbktpbmQuSU5WQUxJRDsKICAgICAgICAgICAgfSBlbHNlIGlmIChhcmcyUHJpbWl0aXZlKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdW5hcnlQcm9tb3Rpb24oYXJnMSkuaXNQcmltaXRpdmUoKSA/CiAgICAgICAgICAgICAgICAgICAgICAgIENvbXBhcmlzb25LaW5kLk5VTUVSSUNfT1JfQk9PTEVBTiA6IENvbXBhcmlzb25LaW5kLklOVkFMSUQ7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICByZXR1cm4gYXJnMS5pc051bGxPclJlZmVyZW5jZSgpICYmIGFyZzIuaXNOdWxsT3JSZWZlcmVuY2UoKSA/CiAgICAgICAgICAgICAgICAgICAgICAgIENvbXBhcmlzb25LaW5kLlJFRkVSRU5DRSA6IENvbXBhcmlzb25LaW5kLklOVkFMSUQ7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBJbml0aWFsaXplIGFsbCB1bmFyeSBvcGVyYXRvcnMuCiAgICAgKi8KICAgIHByaXZhdGUgdm9pZCBpbml0VW5hcnlPcGVyYXRvcnMoKSB7CiAgICAgICAgaW5pdE9wZXJhdG9ycyh1bmFyeU9wZXJhdG9ycywKICAgICAgICAgICAgICAgIG5ldyBVbmFyeU51bWVyaWNPcGVyYXRvcihUYWcuUE9TKQogICAgICAgICAgICAgICAgICAgICAgICAuYWRkVW5hcnlPcGVyYXRvcihET1VCTEUsIERPVUJMRSwgbm9wKQogICAgICAgICAgICAgICAgICAgICAgICAuYWRkVW5hcnlPcGVyYXRvcihGTE9BVCwgRkxPQVQsIG5vcCkKICAgICAgICAgICAgICAgICAgICAgICAgLmFkZFVuYXJ5T3BlcmF0b3IoTE9ORywgTE9ORywgbm9wKQogICAgICAgICAgICAgICAgICAgICAgICAuYWRkVW5hcnlPcGVyYXRvcihJTlQsIElOVCwgbm9wKSwKICAgICAgICAgICAgICAgIG5ldyBVbmFyeU51bWVyaWNPcGVyYXRvcihUYWcuTkVHKQogICAgICAgICAgICAgICAgICAgICAgICAuYWRkVW5hcnlPcGVyYXRvcihET1VCTEUsIERPVUJMRSwgZG5lZykKICAgICAgICAgICAgICAgICAgICAgICAgLmFkZFVuYXJ5T3BlcmF0b3IoRkxPQVQsIEZMT0FULCBmbmVnKQogICAgICAgICAgICAgICAgICAgICAgICAuYWRkVW5hcnlPcGVyYXRvcihMT05HLCBMT05HLCBsbmVnKQogICAgICAgICAgICAgICAgICAgICAgICAuYWRkVW5hcnlPcGVyYXRvcihJTlQsIElOVCwgaW5lZyksCiAgICAgICAgICAgICAgICBuZXcgVW5hcnlOdW1lcmljT3BlcmF0b3IoVGFnLkNPTVBMLCBUeXBlOjppc0ludGVncmFsKQogICAgICAgICAgICAgICAgICAgICAgICAuYWRkVW5hcnlPcGVyYXRvcihMT05HLCBMT05HLCBseG9yKQogICAgICAgICAgICAgICAgICAgICAgICAuYWRkVW5hcnlPcGVyYXRvcihJTlQsIElOVCwgaXhvciksCiAgICAgICAgICAgICAgICBuZXcgVW5hcnlQcmVmaXhQb3N0Zml4T3BlcmF0b3IoVGFnLlBPU1RJTkMpCiAgICAgICAgICAgICAgICAgICAgICAgIC5hZGRVbmFyeU9wZXJhdG9yKERPVUJMRSwgRE9VQkxFLCBkYWRkKQogICAgICAgICAgICAgICAgICAgICAgICAuYWRkVW5hcnlPcGVyYXRvcihGTE9BVCwgRkxPQVQsIGZhZGQpCiAgICAgICAgICAgICAgICAgICAgICAgIC5hZGRVbmFyeU9wZXJhdG9yKExPTkcsIExPTkcsIGxhZGQpCiAgICAgICAgICAgICAgICAgICAgICAgIC5hZGRVbmFyeU9wZXJhdG9yKElOVCwgSU5ULCBpYWRkKQogICAgICAgICAgICAgICAgICAgICAgICAuYWRkVW5hcnlPcGVyYXRvcihDSEFSLCBDSEFSLCBpYWRkKQogICAgICAgICAgICAgICAgICAgICAgICAuYWRkVW5hcnlPcGVyYXRvcihTSE9SVCwgU0hPUlQsIGlhZGQpCiAgICAgICAgICAgICAgICAgICAgICAgIC5hZGRVbmFyeU9wZXJhdG9yKEJZVEUsIEJZVEUsIGlhZGQpLAogICAgICAgICAgICAgICAgbmV3IFVuYXJ5UHJlZml4UG9zdGZpeE9wZXJhdG9yKFRhZy5QT1NUREVDKQogICAgICAgICAgICAgICAgICAgICAgICAuYWRkVW5hcnlPcGVyYXRvcihET1VCTEUsIERPVUJMRSwgZHN1YikKICAgICAgICAgICAgICAgICAgICAgICAgLmFkZFVuYXJ5T3BlcmF0b3IoRkxPQVQsIEZMT0FULCBmc3ViKQogICAgICAgICAgICAgICAgICAgICAgICAuYWRkVW5hcnlPcGVyYXRvcihMT05HLCBMT05HLCBsc3ViKQogICAgICAgICAgICAgICAgICAgICAgICAuYWRkVW5hcnlPcGVyYXRvcihJTlQsIElOVCwgaXN1YikKICAgICAgICAgICAgICAgICAgICAgICAgLmFkZFVuYXJ5T3BlcmF0b3IoQ0hBUiwgQ0hBUiwgaXN1YikKICAgICAgICAgICAgICAgICAgICAgICAgLmFkZFVuYXJ5T3BlcmF0b3IoU0hPUlQsIFNIT1JULCBpc3ViKQogICAgICAgICAgICAgICAgICAgICAgICAuYWRkVW5hcnlPcGVyYXRvcihCWVRFLCBCWVRFLCBpc3ViKSwKICAgICAgICAgICAgICAgIG5ldyBVbmFyeUJvb2xlYW5PcGVyYXRvcihUYWcuTk9UKQogICAgICAgICAgICAgICAgICAgICAgICAuYWRkVW5hcnlPcGVyYXRvcihCT09MRUFOLCBCT09MRUFOLCBib29sX25vdCksCiAgICAgICAgICAgICAgICBuZXcgVW5hcnlSZWZlcmVuY2VPcGVyYXRvcihUYWcuTlVMTENISykKICAgICAgICAgICAgICAgICAgICAgICAgLmFkZFVuYXJ5T3BlcmF0b3IoT0JKRUNULCBPQkpFQ1QsIG51bGxjaGspKTsKICAgIH0KCiAgICAvKioKICAgICAqIEluaXRpYWxpemUgYWxsIGJpbmFyeSBvcGVyYXRvcnMuCiAgICAgKi8KICAgIHByaXZhdGUgdm9pZCBpbml0QmluYXJ5T3BlcmF0b3JzKCkgewogICAgICAgIGluaXRPcGVyYXRvcnMoYmluYXJ5T3BlcmF0b3JzLAogICAgICAgICAgICBuZXcgQmluYXJ5U3RyaW5nT3BlcmF0b3IoVGFnLlBMVVMpCiAgICAgICAgICAgICAgICAgICAgLmFkZEJpbmFyeU9wZXJhdG9yKFNUUklORywgT0JKRUNULCBTVFJJTkcsIHN0cmluZ19hZGQpCiAgICAgICAgICAgICAgICAgICAgLmFkZEJpbmFyeU9wZXJhdG9yKE9CSkVDVCwgU1RSSU5HLCBTVFJJTkcsIHN0cmluZ19hZGQpCiAgICAgICAgICAgICAgICAgICAgLmFkZEJpbmFyeU9wZXJhdG9yKFNUUklORywgU1RSSU5HLCBTVFJJTkcsIHN0cmluZ19hZGQpCiAgICAgICAgICAgICAgICAgICAgLmFkZEJpbmFyeU9wZXJhdG9yKFNUUklORywgSU5ULCBTVFJJTkcsIHN0cmluZ19hZGQpCiAgICAgICAgICAgICAgICAgICAgLmFkZEJpbmFyeU9wZXJhdG9yKFNUUklORywgTE9ORywgU1RSSU5HLCBzdHJpbmdfYWRkKQogICAgICAgICAgICAgICAgICAgIC5hZGRCaW5hcnlPcGVyYXRvcihTVFJJTkcsIEZMT0FULCBTVFJJTkcsIHN0cmluZ19hZGQpCiAgICAgICAgICAgICAgICAgICAgLmFkZEJpbmFyeU9wZXJhdG9yKFNUUklORywgRE9VQkxFLCBTVFJJTkcsIHN0cmluZ19hZGQpCiAgICAgICAgICAgICAgICAgICAgLmFkZEJpbmFyeU9wZXJhdG9yKFNUUklORywgQk9PTEVBTiwgU1RSSU5HLCBzdHJpbmdfYWRkKQogICAgICAgICAgICAgICAgICAgIC5hZGRCaW5hcnlPcGVyYXRvcihTVFJJTkcsIEJPVCwgU1RSSU5HLCBzdHJpbmdfYWRkKQogICAgICAgICAgICAgICAgICAgIC5hZGRCaW5hcnlPcGVyYXRvcihJTlQsIFNUUklORywgU1RSSU5HLCBzdHJpbmdfYWRkKQogICAgICAgICAgICAgICAgICAgIC5hZGRCaW5hcnlPcGVyYXRvcihMT05HLCBTVFJJTkcsIFNUUklORywgc3RyaW5nX2FkZCkKICAgICAgICAgICAgICAgICAgICAuYWRkQmluYXJ5T3BlcmF0b3IoRkxPQVQsIFNUUklORywgU1RSSU5HLCBzdHJpbmdfYWRkKQogICAgICAgICAgICAgICAgICAgIC5hZGRCaW5hcnlPcGVyYXRvcihET1VCTEUsIFNUUklORywgU1RSSU5HLCBzdHJpbmdfYWRkKQogICAgICAgICAgICAgICAgICAgIC5hZGRCaW5hcnlPcGVyYXRvcihCT09MRUFOLCBTVFJJTkcsIFNUUklORywgc3RyaW5nX2FkZCkKICAgICAgICAgICAgICAgICAgICAuYWRkQmluYXJ5T3BlcmF0b3IoQk9ULCBTVFJJTkcsIFNUUklORywgc3RyaW5nX2FkZCksCiAgICAgICAgICAgIG5ldyBCaW5hcnlOdW1lcmljT3BlcmF0b3IoVGFnLlBMVVMpCiAgICAgICAgICAgICAgICAgICAgLmFkZEJpbmFyeU9wZXJhdG9yKERPVUJMRSwgRE9VQkxFLCBET1VCTEUsIGRhZGQpCiAgICAgICAgICAgICAgICAgICAgLmFkZEJpbmFyeU9wZXJhdG9yKEZMT0FULCBGTE9BVCwgRkxPQVQsIGZhZGQpCiAgICAgICAgICAgICAgICAgICAgLmFkZEJpbmFyeU9wZXJhdG9yKExPTkcsIExPTkcsIExPTkcsIGxhZGQpCiAgICAgICAgICAgICAgICAgICAgLmFkZEJpbmFyeU9wZXJhdG9yKElOVCwgSU5ULCBJTlQsIGlhZGQpLAogICAgICAgICAgICBuZXcgQmluYXJ5TnVtZXJpY09wZXJhdG9yKFRhZy5NSU5VUykKICAgICAgICAgICAgICAgICAgICAuYWRkQmluYXJ5T3BlcmF0b3IoRE9VQkxFLCBET1VCTEUsIERPVUJMRSwgZHN1YikKICAgICAgICAgICAgICAgICAgICAuYWRkQmluYXJ5T3BlcmF0b3IoRkxPQVQsIEZMT0FULCBGTE9BVCwgZnN1YikKICAgICAgICAgICAgICAgICAgICAuYWRkQmluYXJ5T3BlcmF0b3IoTE9ORywgTE9ORywgTE9ORywgbHN1YikKICAgICAgICAgICAgICAgICAgICAuYWRkQmluYXJ5T3BlcmF0b3IoSU5ULCBJTlQsIElOVCwgaXN1YiksCiAgICAgICAgICAgIG5ldyBCaW5hcnlOdW1lcmljT3BlcmF0b3IoVGFnLk1VTCkKICAgICAgICAgICAgICAgICAgICAuYWRkQmluYXJ5T3BlcmF0b3IoRE9VQkxFLCBET1VCTEUsIERPVUJMRSwgZG11bCkKICAgICAgICAgICAgICAgICAgICAuYWRkQmluYXJ5T3BlcmF0b3IoRkxPQVQsIEZMT0FULCBGTE9BVCwgZm11bCkKICAgICAgICAgICAgICAgICAgICAuYWRkQmluYXJ5T3BlcmF0b3IoTE9ORywgTE9ORywgTE9ORywgbG11bCkKICAgICAgICAgICAgICAgICAgICAuYWRkQmluYXJ5T3BlcmF0b3IoSU5ULCBJTlQsIElOVCwgaW11bCksCiAgICAgICAgICAgIG5ldyBCaW5hcnlOdW1lcmljT3BlcmF0b3IoVGFnLkRJVikKICAgICAgICAgICAgICAgICAgICAuYWRkQmluYXJ5T3BlcmF0b3IoRE9VQkxFLCBET1VCTEUsIERPVUJMRSwgZGRpdikKICAgICAgICAgICAgICAgICAgICAuYWRkQmluYXJ5T3BlcmF0b3IoRkxPQVQsIEZMT0FULCBGTE9BVCwgZmRpdikKICAgICAgICAgICAgICAgICAgICAuYWRkQmluYXJ5T3BlcmF0b3IoTE9ORywgTE9ORywgTE9ORywgbGRpdikKICAgICAgICAgICAgICAgICAgICAuYWRkQmluYXJ5T3BlcmF0b3IoSU5ULCBJTlQsIElOVCwgaWRpdiksCiAgICAgICAgICAgIG5ldyBCaW5hcnlOdW1lcmljT3BlcmF0b3IoVGFnLk1PRCkKICAgICAgICAgICAgICAgICAgICAuYWRkQmluYXJ5T3BlcmF0b3IoRE9VQkxFLCBET1VCTEUsIERPVUJMRSwgZG1vZCkKICAgICAgICAgICAgICAgICAgICAuYWRkQmluYXJ5T3BlcmF0b3IoRkxPQVQsIEZMT0FULCBGTE9BVCwgZm1vZCkKICAgICAgICAgICAgICAgICAgICAuYWRkQmluYXJ5T3BlcmF0b3IoTE9ORywgTE9ORywgTE9ORywgbG1vZCkKICAgICAgICAgICAgICAgICAgICAuYWRkQmluYXJ5T3BlcmF0b3IoSU5ULCBJTlQsIElOVCwgaW1vZCksCiAgICAgICAgICAgIG5ldyBCaW5hcnlCb29sZWFuT3BlcmF0b3IoVGFnLkJJVEFORCkKICAgICAgICAgICAgICAgICAgICAuYWRkQmluYXJ5T3BlcmF0b3IoQk9PTEVBTiwgQk9PTEVBTiwgQk9PTEVBTiwgaWFuZCksCiAgICAgICAgICAgIG5ldyBCaW5hcnlOdW1lcmljT3BlcmF0b3IoVGFnLkJJVEFORCwgVHlwZTo6aXNJbnRlZ3JhbCkKICAgICAgICAgICAgICAgICAgICAuYWRkQmluYXJ5T3BlcmF0b3IoTE9ORywgTE9ORywgTE9ORywgbGFuZCkKICAgICAgICAgICAgICAgICAgICAuYWRkQmluYXJ5T3BlcmF0b3IoSU5ULCBJTlQsIElOVCwgaWFuZCksCiAgICAgICAgICAgIG5ldyBCaW5hcnlCb29sZWFuT3BlcmF0b3IoVGFnLkJJVE9SKQogICAgICAgICAgICAgICAgICAgIC5hZGRCaW5hcnlPcGVyYXRvcihCT09MRUFOLCBCT09MRUFOLCBCT09MRUFOLCBpb3IpLAogICAgICAgICAgICBuZXcgQmluYXJ5TnVtZXJpY09wZXJhdG9yKFRhZy5CSVRPUiwgVHlwZTo6aXNJbnRlZ3JhbCkKICAgICAgICAgICAgICAgICAgICAuYWRkQmluYXJ5T3BlcmF0b3IoTE9ORywgTE9ORywgTE9ORywgbG9yKQogICAgICAgICAgICAgICAgICAgIC5hZGRCaW5hcnlPcGVyYXRvcihJTlQsIElOVCwgSU5ULCBpb3IpLAogICAgICAgICAgICBuZXcgQmluYXJ5Qm9vbGVhbk9wZXJhdG9yKFRhZy5CSVRYT1IpCiAgICAgICAgICAgICAgICAgICAgLmFkZEJpbmFyeU9wZXJhdG9yKEJPT0xFQU4sIEJPT0xFQU4sIEJPT0xFQU4sIGl4b3IpLAogICAgICAgICAgICBuZXcgQmluYXJ5TnVtZXJpY09wZXJhdG9yKFRhZy5CSVRYT1IsIFR5cGU6OmlzSW50ZWdyYWwpCiAgICAgICAgICAgICAgICAgICAgLmFkZEJpbmFyeU9wZXJhdG9yKExPTkcsIExPTkcsIExPTkcsIGx4b3IpCiAgICAgICAgICAgICAgICAgICAgLmFkZEJpbmFyeU9wZXJhdG9yKElOVCwgSU5ULCBJTlQsIGl4b3IpLAogICAgICAgICAgICBuZXcgQmluYXJ5U2hpZnRPcGVyYXRvcihUYWcuU0wpCiAgICAgICAgICAgICAgICAgICAgLmFkZEJpbmFyeU9wZXJhdG9yKElOVCwgSU5ULCBJTlQsIGlzaGwpCiAgICAgICAgICAgICAgICAgICAgLmFkZEJpbmFyeU9wZXJhdG9yKElOVCwgTE9ORywgSU5ULCBpc2hsbCkKICAgICAgICAgICAgICAgICAgICAuYWRkQmluYXJ5T3BlcmF0b3IoTE9ORywgSU5ULCBMT05HLCBsc2hsKQogICAgICAgICAgICAgICAgICAgIC5hZGRCaW5hcnlPcGVyYXRvcihMT05HLCBMT05HLCBMT05HLCBsc2hsbCksCiAgICAgICAgICAgIG5ldyBCaW5hcnlTaGlmdE9wZXJhdG9yKFRhZy5TUikKICAgICAgICAgICAgICAgICAgICAuYWRkQmluYXJ5T3BlcmF0b3IoSU5ULCBJTlQsIElOVCwgaXNocikKICAgICAgICAgICAgICAgICAgICAuYWRkQmluYXJ5T3BlcmF0b3IoSU5ULCBMT05HLCBJTlQsIGlzaHJsKQogICAgICAgICAgICAgICAgICAgIC5hZGRCaW5hcnlPcGVyYXRvcihMT05HLCBJTlQsIExPTkcsIGxzaHIpCiAgICAgICAgICAgICAgICAgICAgLmFkZEJpbmFyeU9wZXJhdG9yKExPTkcsIExPTkcsIExPTkcsIGxzaHJsKSwKICAgICAgICAgICAgbmV3IEJpbmFyeVNoaWZ0T3BlcmF0b3IoVGFnLlVTUikKICAgICAgICAgICAgICAgICAgICAuYWRkQmluYXJ5T3BlcmF0b3IoSU5ULCBJTlQsIElOVCwgaXVzaHIpCiAgICAgICAgICAgICAgICAgICAgLmFkZEJpbmFyeU9wZXJhdG9yKElOVCwgTE9ORywgSU5ULCBpdXNocmwpCiAgICAgICAgICAgICAgICAgICAgLmFkZEJpbmFyeU9wZXJhdG9yKExPTkcsIElOVCwgTE9ORywgbHVzaHIpCiAgICAgICAgICAgICAgICAgICAgLmFkZEJpbmFyeU9wZXJhdG9yKExPTkcsIExPTkcsIExPTkcsIGx1c2hybCksCiAgICAgICAgICAgIG5ldyBCaW5hcnlOdW1lcmljT3BlcmF0b3IoVGFnLkxUKQogICAgICAgICAgICAgICAgICAgIC5hZGRCaW5hcnlPcGVyYXRvcihET1VCTEUsIERPVUJMRSwgQk9PTEVBTiwgZGNtcGcsIGlmbHQpCiAgICAgICAgICAgICAgICAgICAgLmFkZEJpbmFyeU9wZXJhdG9yKEZMT0FULCBGTE9BVCwgQk9PTEVBTiwgZmNtcGcsIGlmbHQpCiAgICAgICAgICAgICAgICAgICAgLmFkZEJpbmFyeU9wZXJhdG9yKExPTkcsIExPTkcsIEJPT0xFQU4sIGxjbXAsIGlmbHQpCiAgICAgICAgICAgICAgICAgICAgLmFkZEJpbmFyeU9wZXJhdG9yKElOVCwgSU5ULCBCT09MRUFOLCBpZl9pY21wbHQpLAogICAgICAgICAgICBuZXcgQmluYXJ5TnVtZXJpY09wZXJhdG9yKFRhZy5HVCkKICAgICAgICAgICAgICAgICAgICAuYWRkQmluYXJ5T3BlcmF0b3IoRE9VQkxFLCBET1VCTEUsIEJPT0xFQU4sIGRjbXBsLCBpZmd0KQogICAgICAgICAgICAgICAgICAgIC5hZGRCaW5hcnlPcGVyYXRvcihGTE9BVCwgRkxPQVQsIEJPT0xFQU4sIGZjbXBsLCBpZmd0KQogICAgICAgICAgICAgICAgICAgIC5hZGRCaW5hcnlPcGVyYXRvcihMT05HLCBMT05HLCBCT09MRUFOLCBsY21wLCBpZmd0KQogICAgICAgICAgICAgICAgICAgIC5hZGRCaW5hcnlPcGVyYXRvcihJTlQsIElOVCwgQk9PTEVBTiwgaWZfaWNtcGd0KSwKICAgICAgICAgICAgbmV3IEJpbmFyeU51bWVyaWNPcGVyYXRvcihUYWcuTEUpCiAgICAgICAgICAgICAgICAgICAgLmFkZEJpbmFyeU9wZXJhdG9yKERPVUJMRSwgRE9VQkxFLCBCT09MRUFOLCBkY21wZywgaWZsZSkKICAgICAgICAgICAgICAgICAgICAuYWRkQmluYXJ5T3BlcmF0b3IoRkxPQVQsIEZMT0FULCBCT09MRUFOLCBmY21wZywgaWZsZSkKICAgICAgICAgICAgICAgICAgICAuYWRkQmluYXJ5T3BlcmF0b3IoTE9ORywgTE9ORywgQk9PTEVBTiwgbGNtcCwgaWZsZSkKICAgICAgICAgICAgICAgICAgICAuYWRkQmluYXJ5T3BlcmF0b3IoSU5ULCBJTlQsIEJPT0xFQU4sIGlmX2ljbXBsZSksCiAgICAgICAgICAgIG5ldyBCaW5hcnlOdW1lcmljT3BlcmF0b3IoVGFnLkdFKQogICAgICAgICAgICAgICAgICAgIC5hZGRCaW5hcnlPcGVyYXRvcihET1VCTEUsIERPVUJMRSwgQk9PTEVBTiwgZGNtcGwsIGlmZ2UpCiAgICAgICAgICAgICAgICAgICAgLmFkZEJpbmFyeU9wZXJhdG9yKEZMT0FULCBGTE9BVCwgQk9PTEVBTiwgZmNtcGwsIGlmZ2UpCiAgICAgICAgICAgICAgICAgICAgLmFkZEJpbmFyeU9wZXJhdG9yKExPTkcsIExPTkcsIEJPT0xFQU4sIGxjbXAsIGlmZ2UpCiAgICAgICAgICAgICAgICAgICAgLmFkZEJpbmFyeU9wZXJhdG9yKElOVCwgSU5ULCBCT09MRUFOLCBpZl9pY21wZ2UpLAogICAgICAgICAgICBuZXcgQmluYXJ5RXF1YWxpdHlPcGVyYXRvcihUYWcuRVEpCiAgICAgICAgICAgICAgICAgICAgLmFkZEJpbmFyeU9wZXJhdG9yKE9CSkVDVCwgT0JKRUNULCBCT09MRUFOLCBpZl9hY21wZXEpCiAgICAgICAgICAgICAgICAgICAgLmFkZEJpbmFyeU9wZXJhdG9yKEJPT0xFQU4sIEJPT0xFQU4sIEJPT0xFQU4sIGlmX2ljbXBlcSkKICAgICAgICAgICAgICAgICAgICAuYWRkQmluYXJ5T3BlcmF0b3IoRE9VQkxFLCBET1VCTEUsIEJPT0xFQU4sIGRjbXBsLCBpZmVxKQogICAgICAgICAgICAgICAgICAgIC5hZGRCaW5hcnlPcGVyYXRvcihGTE9BVCwgRkxPQVQsIEJPT0xFQU4sIGZjbXBsLCBpZmVxKQogICAgICAgICAgICAgICAgICAgIC5hZGRCaW5hcnlPcGVyYXRvcihMT05HLCBMT05HLCBCT09MRUFOLCBsY21wLCBpZmVxKQogICAgICAgICAgICAgICAgICAgIC5hZGRCaW5hcnlPcGVyYXRvcihJTlQsIElOVCwgQk9PTEVBTiwgaWZfaWNtcGVxKSwKICAgICAgICAgICAgbmV3IEJpbmFyeUVxdWFsaXR5T3BlcmF0b3IoVGFnLk5FKQogICAgICAgICAgICAgICAgICAgIC5hZGRCaW5hcnlPcGVyYXRvcihPQkpFQ1QsIE9CSkVDVCwgQk9PTEVBTiwgaWZfYWNtcG5lKQogICAgICAgICAgICAgICAgICAgIC5hZGRCaW5hcnlPcGVyYXRvcihCT09MRUFOLCBCT09MRUFOLCBCT09MRUFOLCBpZl9pY21wbmUpCiAgICAgICAgICAgICAgICAgICAgLmFkZEJpbmFyeU9wZXJhdG9yKERPVUJMRSwgRE9VQkxFLCBCT09MRUFOLCBkY21wbCwgaWZuZSkKICAgICAgICAgICAgICAgICAgICAuYWRkQmluYXJ5T3BlcmF0b3IoRkxPQVQsIEZMT0FULCBCT09MRUFOLCBmY21wbCwgaWZuZSkKICAgICAgICAgICAgICAgICAgICAuYWRkQmluYXJ5T3BlcmF0b3IoTE9ORywgTE9ORywgQk9PTEVBTiwgbGNtcCwgaWZuZSkKICAgICAgICAgICAgICAgICAgICAuYWRkQmluYXJ5T3BlcmF0b3IoSU5ULCBJTlQsIEJPT0xFQU4sIGlmX2ljbXBuZSksCiAgICAgICAgICAgIG5ldyBCaW5hcnlCb29sZWFuT3BlcmF0b3IoVGFnLkFORCkKICAgICAgICAgICAgICAgICAgICAuYWRkQmluYXJ5T3BlcmF0b3IoQk9PTEVBTiwgQk9PTEVBTiwgQk9PTEVBTiwgYm9vbF9hbmQpLAogICAgICAgICAgICBuZXcgQmluYXJ5Qm9vbGVhbk9wZXJhdG9yKFRhZy5PUikKICAgICAgICAgICAgICAgICAgICAuYWRkQmluYXJ5T3BlcmF0b3IoQk9PTEVBTiwgQk9PTEVBTiwgQk9PTEVBTiwgYm9vbF9vcikpOwogICAgfQoKICAgIE9wZXJhdG9yU3ltYm9sIGxvb2t1cEJpbmFyeU9wKFByZWRpY2F0ZTxPcGVyYXRvclN5bWJvbD4gYXBwbGljYWJpbGl0eVRlc3QpIHsKICAgICAgICByZXR1cm4gYmluYXJ5T3BlcmF0b3JzLnZhbHVlcygpLnN0cmVhbSgpCiAgICAgICAgICAgICAgICAuZmxhdE1hcChMaXN0OjpzdHJlYW0pCiAgICAgICAgICAgICAgICAubWFwKGhlbHBlciAtPiBoZWxwZXIuZG9Mb29rdXAoYXBwbGljYWJpbGl0eVRlc3QpKQogICAgICAgICAgICAgICAgLmRpc3RpbmN0KCkKICAgICAgICAgICAgICAgIC5maWx0ZXIoc3ltIC0+IHN5bSAhPSBub09wU3ltYm9sKQogICAgICAgICAgICAgICAgLmZpbmRGaXJzdCgpLmdldCgpOwogICAgfQoKICAgIC8qKgogICAgICogQ29tcGxldGUgdGhlIGluaXRpYWxpemF0aW9uIG9mIGFuIG9wZXJhdG9yIGhlbHBlciBieSBzdG9yaW5nIGl0IGludG8gdGhlIGNvcnJlc3BvbmRpbmcgb3BlcmF0b3IgbWFwLgogICAgICovCiAgICBAU2FmZVZhcmFyZ3MKICAgIHByaXZhdGUgZmluYWwgPE8gZXh0ZW5kcyBPcGVyYXRvckhlbHBlcj4gdm9pZCBpbml0T3BlcmF0b3JzKE1hcDxOYW1lLCBMaXN0PE8+PiBvcHNNYXAsIE8uLi4gb3BzKSB7CiAgICAgICAgZm9yIChPIG8gOiBvcHMpIHsKICAgICAgICAgICAgTmFtZSBvcE5hbWUgPSBvLm5hbWU7CiAgICAgICAgICAgIExpc3Q8Tz4gaGVscGVycyA9IG9wc01hcC5nZXRPckRlZmF1bHQob3BOYW1lLCBMaXN0Lm5pbCgpKTsKICAgICAgICAgICAgb3BzTWFwLnB1dChvcE5hbWUsIGhlbHBlcnMucHJlcGVuZChvKSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogSW5pdGlhbGl6ZSBvcGVyYXRvciBuYW1lIGFycmF5LgogICAgICovCiAgICBwcml2YXRlIHZvaWQgaW5pdE9wZXJhdG9yTmFtZXMoKSB7CiAgICAgICAgc2V0T3BlcmF0b3JOYW1lKFRhZy5QT1MsICIrIik7CiAgICAgICAgc2V0T3BlcmF0b3JOYW1lKFRhZy5ORUcsICItIik7CiAgICAgICAgc2V0T3BlcmF0b3JOYW1lKFRhZy5OT1QsICIhIik7CiAgICAgICAgc2V0T3BlcmF0b3JOYW1lKFRhZy5DT01QTCwgIn4iKTsKICAgICAgICBzZXRPcGVyYXRvck5hbWUoVGFnLlBSRUlOQywgIisrIik7CiAgICAgICAgc2V0T3BlcmF0b3JOYW1lKFRhZy5QUkVERUMsICItLSIpOwogICAgICAgIHNldE9wZXJhdG9yTmFtZShUYWcuUE9TVElOQywgIisrIik7CiAgICAgICAgc2V0T3BlcmF0b3JOYW1lKFRhZy5QT1NUREVDLCAiLS0iKTsKICAgICAgICBzZXRPcGVyYXRvck5hbWUoVGFnLk5VTExDSEssICI8Km51bGxjaGsqPiIpOwogICAgICAgIHNldE9wZXJhdG9yTmFtZShUYWcuT1IsICJ8fCIpOwogICAgICAgIHNldE9wZXJhdG9yTmFtZShUYWcuQU5ELCAiJiYiKTsKICAgICAgICBzZXRPcGVyYXRvck5hbWUoVGFnLkVRLCAiPT0iKTsKICAgICAgICBzZXRPcGVyYXRvck5hbWUoVGFnLk5FLCAiIT0iKTsKICAgICAgICBzZXRPcGVyYXRvck5hbWUoVGFnLkxULCAiPCIpOwogICAgICAgIHNldE9wZXJhdG9yTmFtZShUYWcuR1QsICI+Iik7CiAgICAgICAgc2V0T3BlcmF0b3JOYW1lKFRhZy5MRSwgIjw9Iik7CiAgICAgICAgc2V0T3BlcmF0b3JOYW1lKFRhZy5HRSwgIj49Iik7CiAgICAgICAgc2V0T3BlcmF0b3JOYW1lKFRhZy5CSVRPUiwgInwiKTsKICAgICAgICBzZXRPcGVyYXRvck5hbWUoVGFnLkJJVFhPUiwgIl4iKTsKICAgICAgICBzZXRPcGVyYXRvck5hbWUoVGFnLkJJVEFORCwgIiYiKTsKICAgICAgICBzZXRPcGVyYXRvck5hbWUoVGFnLlNMLCAiPDwiKTsKICAgICAgICBzZXRPcGVyYXRvck5hbWUoVGFnLlNSLCAiPj4iKTsKICAgICAgICBzZXRPcGVyYXRvck5hbWUoVGFnLlVTUiwgIj4+PiIpOwogICAgICAgIHNldE9wZXJhdG9yTmFtZShUYWcuUExVUywgIisiKTsKICAgICAgICBzZXRPcGVyYXRvck5hbWUoVGFnLk1JTlVTLCBuYW1lcy5oeXBoZW4pOwogICAgICAgIHNldE9wZXJhdG9yTmFtZShUYWcuTVVMLCBuYW1lcy5hc3Rlcmlzayk7CiAgICAgICAgc2V0T3BlcmF0b3JOYW1lKFRhZy5ESVYsIG5hbWVzLnNsYXNoKTsKICAgICAgICBzZXRPcGVyYXRvck5hbWUoVGFnLk1PRCwgIiUiKTsKICAgIH0KICAgIC8vd2hlcmUKICAgICAgICBwcml2YXRlIHZvaWQgc2V0T3BlcmF0b3JOYW1lKFRhZyB0YWcsIFN0cmluZyBuYW1lKSB7CiAgICAgICAgICAgIHNldE9wZXJhdG9yTmFtZSh0YWcsIG5hbWVzLmZyb21TdHJpbmcobmFtZSkpOwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSB2b2lkIHNldE9wZXJhdG9yTmFtZShUYWcgdGFnLCBOYW1lIG5hbWUpIHsKICAgICAgICAgICAgb3BuYW1lW3RhZy5vcGVyYXRvckluZGV4KCldID0gbmFtZTsKICAgICAgICB9Cn0KUEsDBAoAAAgAAAY7qUrVJZEqK14AACteAAAjAAAAY29tL3N1bi90b29scy9qYXZhYy9jb21wL0VudGVyLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDE5OTksIDIwMTcsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhYy5jb21wOwoKaW1wb3J0IGphdmEudXRpbC5NYXA7CmltcG9ydCBqYXZhLnV0aWwuT3B0aW9uYWw7CgppbXBvcnQgamF2YXgudG9vbHMuSmF2YUZpbGVPYmplY3Q7CmltcG9ydCBqYXZheC50b29scy5KYXZhRmlsZU1hbmFnZXI7CgppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLio7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuS2luZHMuS2luZE5hbWU7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuS2luZHMuS2luZFNlbGVjdG9yOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlNjb3BlLio7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuU3ltYm9sLio7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuVHlwZS4qOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5tYWluLk9wdGlvbi5Qa2dJbmZvOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5yZXNvdXJjZXMuQ29tcGlsZXJQcm9wZXJ0aWVzLkVycm9yczsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS4qOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkpDVHJlZS4qOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLio7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuSkNEaWFnbm9zdGljLkRpYWdub3N0aWNQb3NpdGlvbjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5MaXN0OwoKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuRmxhZ3MuKjsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuS2luZHMuS2luZC4qOwoKLyoqIFRoaXMgY2xhc3MgZW50ZXJzIHN5bWJvbHMgZm9yIGFsbCBlbmNvdW50ZXJlZCBkZWZpbml0aW9ucyBpbnRvCiAqICB0aGUgc3ltYm9sIHRhYmxlLiBUaGUgcGFzcyBjb25zaXN0cyBvZiBoaWdoLWxldmVsIHR3byBwaGFzZXMsCiAqICBvcmdhbml6ZWQgYXMgZm9sbG93czoKICoKICogIDxwPkluIHRoZSBmaXJzdCBwaGFzZSwgYWxsIGNsYXNzIHN5bWJvbHMgYXJlIGVudGVyZWQgaW50byB0aGVpcgogKiAgZW5jbG9zaW5nIHNjb3BlLCBkZXNjZW5kaW5nIHJlY3Vyc2l2ZWx5IGRvd24gdGhlIHRyZWUgZm9yIGNsYXNzZXMKICogIHdoaWNoIGFyZSBtZW1iZXJzIG9mIG90aGVyIGNsYXNzZXMuIFRoZSBjbGFzcyBzeW1ib2xzIGFyZSBnaXZlbiBhCiAqICBUeXBlRW50ZXIgb2JqZWN0IGFzIGNvbXBsZXRlci4KICoKICogIDxwPkluIHRoZSBzZWNvbmQgcGhhc2UgY2xhc3NlcyBhcmUgY29tcGxldGVkIHVzaW5nCiAqICBUeXBlRW50ZXIuY29tcGxldGUoKS4gQ29tcGxldGlvbiBtaWdodCBvY2N1ciBvbiBkZW1hbmQsIGJ1dAogKiAgYW55IGNsYXNzZXMgdGhhdCBhcmUgbm90IGNvbXBsZXRlZCB0aGF0IHdheSB3aWxsIGJlIGV2ZW50dWFsbHkKICogIGNvbXBsZXRlZCBieSBwcm9jZXNzaW5nIHRoZSBgdW5jb21wbGV0ZWQnIHF1ZXVlLiBDb21wbGV0aW9uCiAqICBlbnRhaWxzIGRldGVybWluYXRpb24gb2YgYSBjbGFzcydzIHBhcmFtZXRlcnMsIHN1cGVydHlwZSBhbmQKICogIGludGVyZmFjZXMsIGFzIHdlbGwgYXMgZW50ZXJpbmcgYWxsIHN5bWJvbHMgZGVmaW5lZCBpbiB0aGUKICogIGNsYXNzIGludG8gaXRzIHNjb3BlLCB3aXRoIHRoZSBleGNlcHRpb24gb2YgY2xhc3Mgc3ltYm9scyB3aGljaAogKiAgaGF2ZSBiZWVuIGVudGVyZWQgaW4gcGhhc2UgMS4KICoKICogIDxwPldoZXJlYXMgdGhlIGZpcnN0IHBoYXNlIGlzIG9yZ2FuaXplZCBhcyBhIHN3ZWVwIHRocm91Z2ggYWxsCiAqICBjb21waWxlZCBzeW50YXggdHJlZXMsIHRoZSBzZWNvbmQgcGhhc2UgaXMgb24tZGVtYW5kLiBNZW1iZXJzIG9mIGEKICogIGNsYXNzIGFyZSBlbnRlcmVkIHdoZW4gdGhlIGNvbnRlbnRzIG9mIGEgY2xhc3MgYXJlIGZpcnN0CiAqICBhY2Nlc3NlZC4gVGhpcyBpcyBhY2NvbXBsaXNoZWQgYnkgaW5zdGFsbGluZyBjb21wbGV0ZXIgb2JqZWN0cyBpbgogKiAgY2xhc3Mgc3ltYm9scyBmb3IgY29tcGlsZWQgY2xhc3NlcyB3aGljaCBpbnZva2UgdGhlIHR5cGUtZW50ZXIKICogIHBoYXNlIGZvciB0aGUgY29ycmVzcG9uZGluZyBjbGFzcyB0cmVlLgogKgogKiAgPHA+Q2xhc3NlcyBtaWdyYXRlIGZyb20gb25lIHBoYXNlIHRvIHRoZSBuZXh0IHZpYSBxdWV1ZXM6CiAqCiAqICA8cHJlPntAbGl0ZXJhbAogKiAgY2xhc3MgZW50ZXIgLT4gKEVudGVyLnVuY29tcGxldGVkKSAgICAgICAgIC0tPiB0eXBlIGVudGVyCiAqICAgICAgICAgICAgICAtPiAoVG9kbykgICAgICAgICAgICAgICAgICAgICAgLS0+IGF0dHJpYnV0ZQogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAob25seSBmb3IgdG9wbGV2ZWwgY2xhc3NlcykKICogIH08L3ByZT4KICoKICogIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqICBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqICBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogKiAgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPgogKi8KcHVibGljIGNsYXNzIEVudGVyIGV4dGVuZHMgSkNUcmVlLlZpc2l0b3IgewogICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBDb250ZXh0LktleTxFbnRlcj4gZW50ZXJLZXkgPSBuZXcgQ29udGV4dC5LZXk8PigpOwoKICAgIEFubm90YXRlIGFubm90YXRlOwogICAgTG9nIGxvZzsKICAgIFN5bXRhYiBzeW1zOwogICAgQ2hlY2sgY2hrOwogICAgVHJlZU1ha2VyIG1ha2U7CiAgICBUeXBlRW50ZXIgdHlwZUVudGVyOwogICAgVHlwZXMgdHlwZXM7CiAgICBMaW50IGxpbnQ7CiAgICBOYW1lcyBuYW1lczsKICAgIEphdmFGaWxlTWFuYWdlciBmaWxlTWFuYWdlcjsKICAgIFBrZ0luZm8gcGtnaW5mb09wdDsKICAgIFR5cGVFbnZzIHR5cGVFbnZzOwogICAgTW9kdWxlcyBtb2R1bGVzOwogICAgSkNEaWFnbm9zdGljLkZhY3RvcnkgZGlhZ3M7CgogICAgcHJpdmF0ZSBmaW5hbCBUb2RvIHRvZG87CgogICAgcHVibGljIHN0YXRpYyBFbnRlciBpbnN0YW5jZShDb250ZXh0IGNvbnRleHQpIHsKICAgICAgICBFbnRlciBpbnN0YW5jZSA9IGNvbnRleHQuZ2V0KGVudGVyS2V5KTsKICAgICAgICBpZiAoaW5zdGFuY2UgPT0gbnVsbCkKICAgICAgICAgICAgaW5zdGFuY2UgPSBuZXcgRW50ZXIoY29udGV4dCk7CiAgICAgICAgcmV0dXJuIGluc3RhbmNlOwogICAgfQoKICAgIHByb3RlY3RlZCBFbnRlcihDb250ZXh0IGNvbnRleHQpIHsKICAgICAgICBjb250ZXh0LnB1dChlbnRlcktleSwgdGhpcyk7CgogICAgICAgIGxvZyA9IExvZy5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBtYWtlID0gVHJlZU1ha2VyLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIHN5bXMgPSBTeW10YWIuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgY2hrID0gQ2hlY2suaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgdHlwZUVudGVyID0gVHlwZUVudGVyLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIHR5cGVzID0gVHlwZXMuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgYW5ub3RhdGUgPSBBbm5vdGF0ZS5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBsaW50ID0gTGludC5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBuYW1lcyA9IE5hbWVzLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIG1vZHVsZXMgPSBNb2R1bGVzLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIGRpYWdzID0gSkNEaWFnbm9zdGljLkZhY3RvcnkuaW5zdGFuY2UoY29udGV4dCk7CgogICAgICAgIHByZWRlZkNsYXNzRGVmID0gbWFrZS5DbGFzc0RlZigKICAgICAgICAgICAgbWFrZS5Nb2RpZmllcnMoUFVCTElDKSwKICAgICAgICAgICAgc3ltcy5wcmVkZWZDbGFzcy5uYW1lLAogICAgICAgICAgICBMaXN0Lm5pbCgpLAogICAgICAgICAgICBudWxsLAogICAgICAgICAgICBMaXN0Lm5pbCgpLAogICAgICAgICAgICBMaXN0Lm5pbCgpKTsKICAgICAgICBwcmVkZWZDbGFzc0RlZi5zeW0gPSBzeW1zLnByZWRlZkNsYXNzOwogICAgICAgIHRvZG8gPSBUb2RvLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIGZpbGVNYW5hZ2VyID0gY29udGV4dC5nZXQoSmF2YUZpbGVNYW5hZ2VyLmNsYXNzKTsKCiAgICAgICAgT3B0aW9ucyBvcHRpb25zID0gT3B0aW9ucy5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBwa2dpbmZvT3B0ID0gUGtnSW5mby5nZXQob3B0aW9ucyk7CiAgICAgICAgdHlwZUVudnMgPSBUeXBlRW52cy5pbnN0YW5jZShjb250ZXh0KTsKICAgIH0KCiAgICAvKiogQWNjZXNzb3IgZm9yIHR5cGVFbnZzCiAgICAgKi8KICAgIHB1YmxpYyBFbnY8QXR0ckNvbnRleHQ+IGdldEVudihUeXBlU3ltYm9sIHN5bSkgewogICAgICAgIHJldHVybiB0eXBlRW52cy5nZXQoc3ltKTsKICAgIH0KCiAgICBwdWJsaWMgSXRlcmFibGU8RW52PEF0dHJDb250ZXh0Pj4gZ2V0RW52cygpIHsKICAgICAgICByZXR1cm4gdHlwZUVudnMudmFsdWVzKCk7CiAgICB9CgogICAgcHVibGljIEVudjxBdHRyQ29udGV4dD4gZ2V0Q2xhc3NFbnYoVHlwZVN5bWJvbCBzeW0pIHsKICAgICAgICBFbnY8QXR0ckNvbnRleHQ+IGxvY2FsRW52ID0gZ2V0RW52KHN5bSk7CiAgICAgICAgaWYgKGxvY2FsRW52ID09IG51bGwpIHJldHVybiBudWxsOwogICAgICAgIEVudjxBdHRyQ29udGV4dD4gbGludEVudiA9IGxvY2FsRW52OwogICAgICAgIHdoaWxlIChsaW50RW52LmluZm8ubGludCA9PSBudWxsKQogICAgICAgICAgICBsaW50RW52ID0gbGludEVudi5uZXh0OwogICAgICAgIGxvY2FsRW52LmluZm8ubGludCA9IGxpbnRFbnYuaW5mby5saW50LmF1Z21lbnQoc3ltKTsKICAgICAgICByZXR1cm4gbG9jYWxFbnY7CiAgICB9CgogICAgLyoqIFRoZSBxdWV1ZSBvZiBhbGwgY2xhc3NlcyB0aGF0IG1pZ2h0IHN0aWxsIG5lZWQgdG8gYmUgY29tcGxldGVkOwogICAgICogIHNhdmVkIGFuZCBpbml0aWFsaXplZCBieSBtYWluKCkuCiAgICAgKi8KICAgIExpc3RCdWZmZXI8Q2xhc3NTeW1ib2w+IHVuY29tcGxldGVkOwoKICAgIC8qKiBUaGUgcXVldWUgb2YgbW9kdWxlcyB3aG9zZSBpbXBvcnRzIHN0aWxsIG5lZWQgdG8gYmUgY2hlY2tlZC4gKi8KICAgIExpc3RCdWZmZXI8SkNDb21waWxhdGlvblVuaXQ+IHVuZmluaXNoZWRNb2R1bGVzID0gbmV3IExpc3RCdWZmZXI8PigpOwoKICAgIC8qKiBBIGR1bW15IGNsYXNzIHRvIHNlcnZlIGFzIGVuY2xDbGFzcyBmb3IgdG9wbGV2ZWwgZW52aXJvbm1lbnRzLgogICAgICovCiAgICBwcml2YXRlIEpDQ2xhc3NEZWNsIHByZWRlZkNsYXNzRGVmOwoKLyogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIGVudmlyb25tZW50IGNvbnN0cnVjdGlvbgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCgogICAgLyoqIENyZWF0ZSBhIGZyZXNoIGVudmlyb25tZW50IGZvciBjbGFzcyBib2RpZXMuCiAgICAgKiAgVGhpcyB3aWxsIGNyZWF0ZSBhIGZyZXNoIHNjb3BlIGZvciBsb2NhbCBzeW1ib2xzIG9mIGEgY2xhc3MsIHJlZmVycmVkCiAgICAgKiAgdG8gYnkgdGhlIGVudmlyb25tZW50cyBpbmZvLnNjb3BlIGZpZWxkLgogICAgICogIFRoaXMgc2NvcGUgd2lsbCBjb250YWluCiAgICAgKiAgICAtIHN5bWJvbHMgZm9yIHRoaXMgYW5kIHN1cGVyCiAgICAgKiAgICAtIHN5bWJvbHMgZm9yIGFueSB0eXBlIHBhcmFtZXRlcnMKICAgICAqICBJbiBhZGRpdGlvbiwgaXQgc2VydmVzIGFzIGFuIGFuY2hvciBmb3Igc2NvcGVzIG9mIG1ldGhvZHMgYW5kIGluaXRpYWxpemVycwogICAgICogIHdoaWNoIGFyZSBuZXN0ZWQgaW4gdGhpcyBzY29wZSB2aWEgU2NvcGUuZHVwKCkuCiAgICAgKiAgVGhpcyBzY29wZSBzaG91bGQgbm90IGJlIGNvbmZ1c2VkIHdpdGggdGhlIG1lbWJlcnMgc2NvcGUgb2YgYSBjbGFzcy4KICAgICAqCiAgICAgKiAgQHBhcmFtIHRyZWUgICAgIFRoZSBjbGFzcyBkZWZpbml0aW9uLgogICAgICogIEBwYXJhbSBlbnYgICAgICBUaGUgZW52aXJvbm1lbnQgY3VycmVudCBvdXRzaWRlIG9mIHRoZSBjbGFzcyBkZWZpbml0aW9uLgogICAgICovCiAgICBwdWJsaWMgRW52PEF0dHJDb250ZXh0PiBjbGFzc0VudihKQ0NsYXNzRGVjbCB0cmVlLCBFbnY8QXR0ckNvbnRleHQ+IGVudikgewogICAgICAgIEVudjxBdHRyQ29udGV4dD4gbG9jYWxFbnYgPQogICAgICAgICAgICBlbnYuZHVwKHRyZWUsIGVudi5pbmZvLmR1cChXcml0ZWFibGVTY29wZS5jcmVhdGUodHJlZS5zeW0pKSk7CiAgICAgICAgbG9jYWxFbnYuZW5jbENsYXNzID0gdHJlZTsKICAgICAgICBsb2NhbEVudi5vdXRlciA9IGVudjsKICAgICAgICBsb2NhbEVudi5pbmZvLmlzU2VsZkNhbGwgPSBmYWxzZTsKICAgICAgICBsb2NhbEVudi5pbmZvLmxpbnQgPSBudWxsOyAvLyBsZWF2ZSB0aGlzIHRvIGJlIGZpbGxlZCBpbiBieSBBdHRyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHdoZW4gYW5ub3RhdGlvbnMgaGF2ZSBiZWVuIHByb2Nlc3NlZAogICAgICAgIGxvY2FsRW52LmluZm8uaXNBbm9ueW1vdXNEaWFtb25kID0gVHJlZUluZm8uaXNEaWFtb25kKGVudi50cmVlKTsKICAgICAgICByZXR1cm4gbG9jYWxFbnY7CiAgICB9CgogICAgLyoqIENyZWF0ZSBhIGZyZXNoIGVudmlyb25tZW50IGZvciB0b3BsZXZlbHMuCiAgICAgKiAgQHBhcmFtIHRyZWUgICAgIFRoZSB0b3BsZXZlbCB0cmVlLgogICAgICovCiAgICBFbnY8QXR0ckNvbnRleHQ+IHRvcExldmVsRW52KEpDQ29tcGlsYXRpb25Vbml0IHRyZWUpIHsKICAgICAgICBFbnY8QXR0ckNvbnRleHQ+IGxvY2FsRW52ID0gbmV3IEVudjw+KHRyZWUsIG5ldyBBdHRyQ29udGV4dCgpKTsKICAgICAgICBsb2NhbEVudi50b3BsZXZlbCA9IHRyZWU7CiAgICAgICAgbG9jYWxFbnYuZW5jbENsYXNzID0gcHJlZGVmQ2xhc3NEZWY7CiAgICAgICAgdHJlZS50b3BsZXZlbFNjb3BlID0gV3JpdGVhYmxlU2NvcGUuY3JlYXRlKHRyZWUucGFja2dlKTsKICAgICAgICB0cmVlLm5hbWVkSW1wb3J0U2NvcGUgPSBuZXcgTmFtZWRJbXBvcnRTY29wZSh0cmVlLnBhY2tnZSwgdHJlZS50b3BsZXZlbFNjb3BlKTsKICAgICAgICB0cmVlLnN0YXJJbXBvcnRTY29wZSA9IG5ldyBTdGFySW1wb3J0U2NvcGUodHJlZS5wYWNrZ2UpOwogICAgICAgIGxvY2FsRW52LmluZm8uc2NvcGUgPSB0cmVlLnRvcGxldmVsU2NvcGU7CiAgICAgICAgbG9jYWxFbnYuaW5mby5saW50ID0gbGludDsKICAgICAgICByZXR1cm4gbG9jYWxFbnY7CiAgICB9CgogICAgcHVibGljIEVudjxBdHRyQ29udGV4dD4gZ2V0VG9wTGV2ZWxFbnYoSkNDb21waWxhdGlvblVuaXQgdHJlZSkgewogICAgICAgIEVudjxBdHRyQ29udGV4dD4gbG9jYWxFbnYgPSBuZXcgRW52PD4odHJlZSwgbmV3IEF0dHJDb250ZXh0KCkpOwogICAgICAgIGxvY2FsRW52LnRvcGxldmVsID0gdHJlZTsKICAgICAgICBsb2NhbEVudi5lbmNsQ2xhc3MgPSBwcmVkZWZDbGFzc0RlZjsKICAgICAgICBsb2NhbEVudi5pbmZvLnNjb3BlID0gdHJlZS50b3BsZXZlbFNjb3BlOwogICAgICAgIGxvY2FsRW52LmluZm8ubGludCA9IGxpbnQ7CiAgICAgICAgcmV0dXJuIGxvY2FsRW52OwogICAgfQoKICAgIC8qKiBUaGUgc2NvcGUgaW4gd2hpY2ggYSBtZW1iZXIgZGVmaW5pdGlvbiBpbiBlbnZpcm9ubWVudCBlbnYgaXMgdG8gYmUgZW50ZXJlZAogICAgICogIFRoaXMgaXMgdXN1YWxseSB0aGUgZW52aXJvbm1lbnQncyBzY29wZSwgZXhjZXB0IGZvciBjbGFzcyBlbnZpcm9ubWVudHMsCiAgICAgKiAgd2hlcmUgdGhlIGxvY2FsIHNjb3BlIGlzIGZvciB0eXBlIHZhcmlhYmxlcywgYW5kIHRoZSB0aGlzIGFuZCBzdXBlciBzeW1ib2wKICAgICAqICBvbmx5LCBhbmQgbWVtYmVycyBnbyBpbnRvIHRoZSBjbGFzcyBtZW1iZXIgc2NvcGUuCiAgICAgKi8KICAgIFdyaXRlYWJsZVNjb3BlIGVudGVyU2NvcGUoRW52PEF0dHJDb250ZXh0PiBlbnYpIHsKICAgICAgICByZXR1cm4gKGVudi50cmVlLmhhc1RhZyhKQ1RyZWUuVGFnLkNMQVNTREVGKSkKICAgICAgICAgICAgPyAoKEpDQ2xhc3NEZWNsKSBlbnYudHJlZSkuc3ltLm1lbWJlcnNfZmllbGQKICAgICAgICAgICAgOiBlbnYuaW5mby5zY29wZTsKICAgIH0KCiAgICAvKiogQ3JlYXRlIGEgZnJlc2ggZW52aXJvbm1lbnQgZm9yIG1vZHVsZXMuCiAgICAgKgogICAgICogIEBwYXJhbSB0cmVlICAgICBUaGUgbW9kdWxlIGRlZmluaXRpb24uCiAgICAgKiAgQHBhcmFtIGVudiAgICAgIFRoZSBlbnZpcm9ubWVudCBjdXJyZW50IG91dHNpZGUgb2YgdGhlIG1vZHVsZSBkZWZpbml0aW9uLgogICAgICovCiAgICBwdWJsaWMgRW52PEF0dHJDb250ZXh0PiBtb2R1bGVFbnYoSkNNb2R1bGVEZWNsIHRyZWUsIEVudjxBdHRyQ29udGV4dD4gZW52KSB7CiAgICAgICAgQXNzZXJ0LmNoZWNrTm9uTnVsbCh0cmVlLnN5bSk7CiAgICAgICAgRW52PEF0dHJDb250ZXh0PiBsb2NhbEVudiA9CiAgICAgICAgICAgIGVudi5kdXAodHJlZSwgZW52LmluZm8uZHVwKFdyaXRlYWJsZVNjb3BlLmNyZWF0ZSh0cmVlLnN5bSkpKTsKICAgICAgICBsb2NhbEVudi5lbmNsQ2xhc3MgPSBwcmVkZWZDbGFzc0RlZjsKICAgICAgICBsb2NhbEVudi5vdXRlciA9IGVudjsKICAgICAgICBsb2NhbEVudi5pbmZvLmlzU2VsZkNhbGwgPSBmYWxzZTsKICAgICAgICBsb2NhbEVudi5pbmZvLmxpbnQgPSBudWxsOyAvLyBsZWF2ZSB0aGlzIHRvIGJlIGZpbGxlZCBpbiBieSBBdHRyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHdoZW4gYW5ub3RhdGlvbnMgaGF2ZSBiZWVuIHByb2Nlc3NlZAogICAgICAgIHJldHVybiBsb2NhbEVudjsKICAgIH0KCgovKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogVmlzaXRvciBtZXRob2RzIGZvciBwaGFzZSAxOiBjbGFzcyBlbnRlcgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiAgICAvKiogVmlzaXRvciBhcmd1bWVudDogdGhlIGN1cnJlbnQgZW52aXJvbm1lbnQuCiAgICAgKi8KICAgIHByb3RlY3RlZCBFbnY8QXR0ckNvbnRleHQ+IGVudjsKCiAgICAvKiogVmlzaXRvciByZXN1bHQ6IHRoZSBjb21wdXRlZCB0eXBlLgogICAgICovCiAgICBUeXBlIHJlc3VsdDsKCiAgICAvKiogVmlzaXRvciBtZXRob2Q6IGVudGVyIGFsbCBjbGFzc2VzIGluIGdpdmVuIHRyZWUsIGNhdGNoaW5nIGFueQogICAgICogIGNvbXBsZXRpb24gZmFpbHVyZSBleGNlcHRpb25zLiBSZXR1cm4gdGhlIHRyZWUncyB0eXBlLgogICAgICoKICAgICAqICBAcGFyYW0gdHJlZSAgICBUaGUgdHJlZSB0byBiZSB2aXNpdGVkLgogICAgICogIEBwYXJhbSBlbnYgICAgIFRoZSBlbnZpcm9ubWVudCB2aXNpdG9yIGFyZ3VtZW50LgogICAgICovCiAgICBUeXBlIGNsYXNzRW50ZXIoSkNUcmVlIHRyZWUsIEVudjxBdHRyQ29udGV4dD4gZW52KSB7CiAgICAgICAgRW52PEF0dHJDb250ZXh0PiBwcmV2RW52ID0gdGhpcy5lbnY7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgdGhpcy5lbnYgPSBlbnY7CiAgICAgICAgICAgIGFubm90YXRlLmJsb2NrQW5ub3RhdGlvbnMoKTsKICAgICAgICAgICAgdHJlZS5hY2NlcHQodGhpcyk7CiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfSAgY2F0Y2ggKENvbXBsZXRpb25GYWlsdXJlIGV4KSB7CiAgICAgICAgICAgIHJldHVybiBjaGsuY29tcGxldGlvbkVycm9yKHRyZWUucG9zKCksIGV4KTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICBhbm5vdGF0ZS51bmJsb2NrQW5ub3RhdGlvbnMoKTsKICAgICAgICAgICAgdGhpcy5lbnYgPSBwcmV2RW52OwogICAgICAgIH0KICAgIH0KCiAgICAvKiogVmlzaXRvciBtZXRob2Q6IGVudGVyIGNsYXNzZXMgb2YgYSBsaXN0IG9mIHRyZWVzLCByZXR1cm5pbmcgYSBsaXN0IG9mIHR5cGVzLgogICAgICovCiAgICA8VCBleHRlbmRzIEpDVHJlZT4gTGlzdDxUeXBlPiBjbGFzc0VudGVyKExpc3Q8VD4gdHJlZXMsIEVudjxBdHRyQ29udGV4dD4gZW52KSB7CiAgICAgICAgTGlzdEJ1ZmZlcjxUeXBlPiB0cyA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICBmb3IgKExpc3Q8VD4gbCA9IHRyZWVzOyBsLm5vbkVtcHR5KCk7IGwgPSBsLnRhaWwpIHsKICAgICAgICAgICAgVHlwZSB0ID0gY2xhc3NFbnRlcihsLmhlYWQsIGVudik7CiAgICAgICAgICAgIGlmICh0ICE9IG51bGwpCiAgICAgICAgICAgICAgICB0cy5hcHBlbmQodCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0cy50b0xpc3QoKTsKICAgIH0KCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHZpc2l0VG9wTGV2ZWwoSkNDb21waWxhdGlvblVuaXQgdHJlZSkgewovLyAgICAgICAgQXNzZXJ0LmNoZWNrTm9uTnVsbCh0cmVlLm1vZGxlLCB0cmVlLnNvdXJjZWZpbGUudG9TdHJpbmcoKSk7CgogICAgICAgIEphdmFGaWxlT2JqZWN0IHByZXYgPSBsb2cudXNlU291cmNlKHRyZWUuc291cmNlZmlsZSk7CiAgICAgICAgYm9vbGVhbiBhZGRFbnYgPSBmYWxzZTsKICAgICAgICBib29sZWFuIGlzUGtnSW5mbyA9IHRyZWUuc291cmNlZmlsZS5pc05hbWVDb21wYXRpYmxlKCJwYWNrYWdlLWluZm8iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSmF2YUZpbGVPYmplY3QuS2luZC5TT1VSQ0UpOwogICAgICAgIGlmIChUcmVlSW5mby5pc01vZHVsZUluZm8odHJlZSkpIHsKICAgICAgICAgICAgSkNQYWNrYWdlRGVjbCBwZCA9IHRyZWUuZ2V0UGFja2FnZSgpOwogICAgICAgICAgICBpZiAocGQgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgbG9nLmVycm9yKHBkLnBvcygpLCBFcnJvcnMuTm9Qa2dJbk1vZHVsZUluZm9KYXZhKTsKICAgICAgICAgICAgfQogICAgICAgICAgICB0cmVlLnBhY2tnZSA9IHN5bXMucm9vdFBhY2thZ2U7CiAgICAgICAgICAgIEVudjxBdHRyQ29udGV4dD4gdG9wRW52ID0gdG9wTGV2ZWxFbnYodHJlZSk7CiAgICAgICAgICAgIGNsYXNzRW50ZXIodHJlZS5kZWZzLCB0b3BFbnYpOwogICAgICAgICAgICB0cmVlLm1vZGxlLnVzZXNQcm92aWRlc0NvbXBsZXRlciA9IG1vZHVsZXMuZ2V0VXNlc1Byb3ZpZGVzQ29tcGxldGVyKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgSkNQYWNrYWdlRGVjbCBwZCA9IHRyZWUuZ2V0UGFja2FnZSgpOwogICAgICAgICAgICBpZiAocGQgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgdHJlZS5wYWNrZ2UgPSBwZC5wYWNrZ2UgPSBzeW1zLmVudGVyUGFja2FnZSh0cmVlLm1vZGxlLCBUcmVlSW5mby5mdWxsTmFtZShwZC5waWQpKTsKICAgICAgICAgICAgICAgIGlmICggICBwZC5hbm5vdGF0aW9ucy5ub25FbXB0eSgpCiAgICAgICAgICAgICAgICAgICAgfHwgcGtnaW5mb09wdCA9PSBQa2dJbmZvLkFMV0FZUwogICAgICAgICAgICAgICAgICAgIHx8IHRyZWUuZG9jQ29tbWVudHMgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIGlmIChpc1BrZ0luZm8pIHsKICAgICAgICAgICAgICAgICAgICAgICAgYWRkRW52ID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHBkLmFubm90YXRpb25zLm5vbkVtcHR5KCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgbG9nLmVycm9yKHBkLmFubm90YXRpb25zLmhlYWQucG9zKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAicGtnLmFubm90YXRpb25zLnNiLmluLnBhY2thZ2UtaW5mby5qYXZhIik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdHJlZS5wYWNrZ2UgPSB0cmVlLm1vZGxlLnVubmFtZWRQYWNrYWdlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBNYXA8TmFtZSwgUGFja2FnZVN5bWJvbD4gdmlzaWJsZVBhY2thZ2VzID0gdHJlZS5tb2RsZS52aXNpYmxlUGFja2FnZXM7CiAgICAgICAgICAgIE9wdGlvbmFsPE1vZHVsZVN5bWJvbD4gZGVwZW5kZW5jeVdpdGhQYWNrYWdlID0KICAgICAgICAgICAgICAgIHN5bXMubGlzdFBhY2thZ2VNb2R1bGVzKHRyZWUucGFja2dlLmZ1bGxuYW1lKQogICAgICAgICAgICAgICAgICAgIC5zdHJlYW0oKQogICAgICAgICAgICAgICAgICAgIC5maWx0ZXIobSAtPiBtICE9IHRyZWUubW9kbGUpCiAgICAgICAgICAgICAgICAgICAgLmZpbHRlcihjYW5kIC0+IHZpc2libGVQYWNrYWdlcy5nZXQodHJlZS5wYWNrZ2UuZnVsbG5hbWUpID09IHN5bXMuZ2V0UGFja2FnZShjYW5kLCB0cmVlLnBhY2tnZS5mdWxsbmFtZSkpCiAgICAgICAgICAgICAgICAgICAgLmZpbmRBbnkoKTsKCiAgICAgICAgICAgIGlmIChkZXBlbmRlbmN5V2l0aFBhY2thZ2UuaXNQcmVzZW50KCkpIHsKICAgICAgICAgICAgICAgIGxvZy5lcnJvcihwZCwgRXJyb3JzLlBhY2thZ2VJbk90aGVyTW9kdWxlKGRlcGVuZGVuY3lXaXRoUGFja2FnZS5nZXQoKSkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICB0cmVlLnBhY2tnZS5jb21wbGV0ZSgpOyAvLyBGaW5kIGFsbCBjbGFzc2VzIGluIHBhY2thZ2UuCgogICAgICAgICAgICBFbnY8QXR0ckNvbnRleHQ+IHRvcEVudiA9IHRvcExldmVsRW52KHRyZWUpOwogICAgICAgICAgICBFbnY8QXR0ckNvbnRleHQ+IHBhY2thZ2VFbnYgPSBpc1BrZ0luZm8gPyB0b3BFbnYuZHVwKHBkKSA6IG51bGw7CgogICAgICAgICAgICAvLyBTYXZlIGVudmlyb25tZW50IG9mIHBhY2thZ2UtaW5mby5qYXZhIGZpbGUuCiAgICAgICAgICAgIGlmIChpc1BrZ0luZm8pIHsKICAgICAgICAgICAgICAgIEVudjxBdHRyQ29udGV4dD4gZW52MCA9IHR5cGVFbnZzLmdldCh0cmVlLnBhY2tnZSk7CiAgICAgICAgICAgICAgICBpZiAoZW52MCAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgSkNDb21waWxhdGlvblVuaXQgdHJlZTAgPSBlbnYwLnRvcGxldmVsOwogICAgICAgICAgICAgICAgICAgIGlmICghZmlsZU1hbmFnZXIuaXNTYW1lRmlsZSh0cmVlLnNvdXJjZWZpbGUsIHRyZWUwLnNvdXJjZWZpbGUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGxvZy53YXJuaW5nKHBkICE9IG51bGwgPyBwZC5waWQucG9zKCkgOiBudWxsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAicGtnLWluZm8uYWxyZWFkeS5zZWVuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJlZS5wYWNrZ2UpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHR5cGVFbnZzLnB1dCh0cmVlLnBhY2tnZSwgcGFja2FnZUVudik7CgogICAgICAgICAgICAgICAgZm9yIChTeW1ib2wgcSA9IHRyZWUucGFja2dlOyBxICE9IG51bGwgJiYgcS5raW5kID09IFBDSzsgcSA9IHEub3duZXIpCiAgICAgICAgICAgICAgICAgICAgcS5mbGFnc19maWVsZCB8PSBFWElTVFM7CgogICAgICAgICAgICAgICAgTmFtZSBuYW1lID0gbmFtZXMucGFja2FnZV9pbmZvOwogICAgICAgICAgICAgICAgQ2xhc3NTeW1ib2wgYyA9IHN5bXMuZW50ZXJDbGFzcyh0cmVlLm1vZGxlLCBuYW1lLCB0cmVlLnBhY2tnZSk7CiAgICAgICAgICAgICAgICBjLmZsYXRuYW1lID0gbmFtZXMuZnJvbVN0cmluZyh0cmVlLnBhY2tnZSArICIuIiArIG5hbWUpOwogICAgICAgICAgICAgICAgYy5zb3VyY2VmaWxlID0gdHJlZS5zb3VyY2VmaWxlOwogICAgICAgICAgICBjLmNvbXBsZXRlciA9IENvbXBsZXRlci5OVUxMX0NPTVBMRVRFUjsKICAgICAgICAgICAgICAgIGMubWVtYmVyc19maWVsZCA9IFdyaXRlYWJsZVNjb3BlLmNyZWF0ZShjKTsKICAgICAgICAgICAgICAgIHRyZWUucGFja2dlLnBhY2thZ2VfaW5mbyA9IGM7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY2xhc3NFbnRlcih0cmVlLmRlZnMsIHRvcEVudik7CiAgICAgICAgICAgIGlmIChhZGRFbnYpIHsKICAgICAgICAgICAgICAgIHRvZG8uYXBwZW5kKHBhY2thZ2VFbnYpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGxvZy51c2VTb3VyY2UocHJldik7CiAgICAgICAgcmVzdWx0ID0gbnVsbDsKICAgIH0KCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHZpc2l0Q2xhc3NEZWYoSkNDbGFzc0RlY2wgdHJlZSkgewogICAgICAgIFN5bWJvbCBvd25lciA9IGVudi5pbmZvLnNjb3BlLm93bmVyOwogICAgICAgIFdyaXRlYWJsZVNjb3BlIGVuY2xTY29wZSA9IGVudGVyU2NvcGUoZW52KTsKICAgICAgICBDbGFzc1N5bWJvbCBjOwogICAgICAgIGlmIChvd25lci5raW5kID09IFBDSykgewogICAgICAgICAgICAvLyBXZSBhcmUgc2VlaW5nIGEgdG9wbGV2ZWwgY2xhc3MuCiAgICAgICAgICAgIFBhY2thZ2VTeW1ib2wgcGFja2dlID0gKFBhY2thZ2VTeW1ib2wpb3duZXI7CiAgICAgICAgICAgIGZvciAoU3ltYm9sIHEgPSBwYWNrZ2U7IHEgIT0gbnVsbCAmJiBxLmtpbmQgPT0gUENLOyBxID0gcS5vd25lcikKICAgICAgICAgICAgICAgIHEuZmxhZ3NfZmllbGQgfD0gRVhJU1RTOwogICAgICAgICAgICBjID0gc3ltcy5lbnRlckNsYXNzKGVudi50b3BsZXZlbC5tb2RsZSwgdHJlZS5uYW1lLCBwYWNrZ2UpOwogICAgICAgICAgICBwYWNrZ2UubWVtYmVycygpLmVudGVySWZBYnNlbnQoYyk7CiAgICAgICAgICAgIGlmICgodHJlZS5tb2RzLmZsYWdzICYgUFVCTElDKSAhPSAwICYmICFjbGFzc05hbWVNYXRjaGVzRmlsZU5hbWUoYywgZW52KSkgewogICAgICAgICAgICAgICAgS2luZE5hbWUgdG9wRWxlbWVudCA9IEtpbmROYW1lLkNMQVNTOwogICAgICAgICAgICAgICAgaWYgKCh0cmVlLm1vZHMuZmxhZ3MgJiBFTlVNKSAhPSAwKSB7CiAgICAgICAgICAgICAgICAgICAgdG9wRWxlbWVudCA9IEtpbmROYW1lLkVOVU07CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCh0cmVlLm1vZHMuZmxhZ3MgJiBJTlRFUkZBQ0UpICE9IDApIHsKICAgICAgICAgICAgICAgICAgICB0b3BFbGVtZW50ID0gS2luZE5hbWUuSU5URVJGQUNFOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgbG9nLmVycm9yKHRyZWUucG9zKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgImNsYXNzLnB1YmxpYy5zaG91bGQuYmUuaW4uZmlsZSIsIHRvcEVsZW1lbnQsIHRyZWUubmFtZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBpZiAoIXRyZWUubmFtZS5pc0VtcHR5KCkgJiYKICAgICAgICAgICAgICAgICFjaGsuY2hlY2tVbmlxdWVDbGFzc05hbWUodHJlZS5wb3MoKSwgdHJlZS5uYW1lLCBlbmNsU2NvcGUpKSB7CiAgICAgICAgICAgICAgICByZXN1bHQgPSBudWxsOwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChvd25lci5raW5kID09IFRZUCkgewogICAgICAgICAgICAgICAgLy8gV2UgYXJlIHNlZWluZyBhIG1lbWJlciBjbGFzcy4KICAgICAgICAgICAgICAgIGMgPSBzeW1zLmVudGVyQ2xhc3MoZW52LnRvcGxldmVsLm1vZGxlLCB0cmVlLm5hbWUsIChUeXBlU3ltYm9sKW93bmVyKTsKICAgICAgICAgICAgICAgIGlmIChjLm93bmVyICE9IG93bmVyKSB7CiAgICAgICAgICAgICAgICAgICAgLy9hbm9ueW1vdXMgY2xhc3MgbG9hZGVkIGZyb20gYSBjbGFzc2ZpbGUgbWF5IGJlIHJlY3JlYXRlZCBmcm9tIHNvdXJjZSAoc2VlIGJlbG93KQogICAgICAgICAgICAgICAgICAgIC8vaWYgdGhpcyBjbGFzcyBpcyBhIG1lbWJlciBvZiBzdWNoIGFuIGFub255bW91cyBjbGFzcywgZml4IHRoZSBvd25lcjoKICAgICAgICAgICAgICAgICAgICBBc3NlcnQuY2hlY2sob3duZXIub3duZXIua2luZCAhPSBUWVAsIG93bmVyOjp0b1N0cmluZyk7CiAgICAgICAgICAgICAgICAgICAgQXNzZXJ0LmNoZWNrKGMub3duZXIua2luZCA9PSBUWVAsICgpIC0+IGMub3duZXIudG9TdHJpbmcoKSk7CiAgICAgICAgICAgICAgICAgICAgQ2xhc3NTeW1ib2wgY293bmVyID0gKENsYXNzU3ltYm9sKSBjLm93bmVyOwogICAgICAgICAgICAgICAgICAgIGlmIChjb3duZXIubWVtYmVyc19maWVsZCAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvd25lci5tZW1iZXJzX2ZpZWxkLnJlbW92ZShjKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYy5vd25lciA9IG93bmVyOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKChvd25lci5mbGFnc19maWVsZCAmIElOVEVSRkFDRSkgIT0gMCkgewogICAgICAgICAgICAgICAgICAgIHRyZWUubW9kcy5mbGFncyB8PSBQVUJMSUMgfCBTVEFUSUM7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvLyBXZSBhcmUgc2VlaW5nIGEgbG9jYWwgY2xhc3MuCiAgICAgICAgICAgICAgICBjID0gc3ltcy5kZWZpbmVDbGFzcyh0cmVlLm5hbWUsIG93bmVyKTsKICAgICAgICAgICAgICAgIGMuZmxhdG5hbWUgPSBjaGsubG9jYWxDbGFzc05hbWUoYyk7CiAgICAgICAgICAgICAgICBpZiAoIWMubmFtZS5pc0VtcHR5KCkpCiAgICAgICAgICAgICAgICAgICAgY2hrLmNoZWNrVHJhbnNwYXJlbnRDbGFzcyh0cmVlLnBvcygpLCBjLCBlbnYuaW5mby5zY29wZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgdHJlZS5zeW0gPSBjOwoKICAgICAgICAvLyBFbnRlciBjbGFzcyBpbnRvIGBjb21waWxlZCcgdGFibGUgYW5kIGVuY2xvc2luZyBzY29wZS4KICAgICAgICBpZiAoY2hrLmdldENvbXBpbGVkKGMpICE9IG51bGwpIHsKICAgICAgICAgICAgZHVwbGljYXRlQ2xhc3ModHJlZS5wb3MoKSwgYyk7CiAgICAgICAgICAgIHJlc3VsdCA9IHR5cGVzLmNyZWF0ZUVycm9yVHlwZSh0cmVlLm5hbWUsIChUeXBlU3ltYm9sKW93bmVyLCBUeXBlLm5vVHlwZSk7CiAgICAgICAgICAgIHRyZWUuc3ltID0gKENsYXNzU3ltYm9sKXJlc3VsdC50c3ltOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIGNoay5wdXRDb21waWxlZChjKTsKICAgICAgICBlbmNsU2NvcGUuZW50ZXIoYyk7CgogICAgICAgIC8vIFNldCB1cCBhbiBlbnZpcm9ubWVudCBmb3IgY2xhc3MgYmxvY2sgYW5kIHN0b3JlIGluIGB0eXBlRW52cycKICAgICAgICAvLyB0YWJsZSwgdG8gYmUgcmV0cmlldmVkIGxhdGVyIGluIG1lbWJlckVudGVyIGFuZCBhdHRyaWJ1dGlvbi4KICAgICAgICBFbnY8QXR0ckNvbnRleHQ+IGxvY2FsRW52ID0gY2xhc3NFbnYodHJlZSwgZW52KTsKICAgICAgICB0eXBlRW52cy5wdXQoYywgbG9jYWxFbnYpOwoKICAgICAgICAvLyBGaWxsIG91dCBjbGFzcyBmaWVsZHMuCiAgICAgICAgYy5jb21wbGV0ZXIgPSBDb21wbGV0ZXIuTlVMTF9DT01QTEVURVI7IC8vIGRvIG5vdCBhbGxvdyB0aGUgaW5pdGlhbCBjb21wbGV0ZXIgbGluZ2VyIG9uLgogICAgICAgIGMuZmxhZ3NfZmllbGQgPSBjaGsuY2hlY2tGbGFncyh0cmVlLnBvcygpLCB0cmVlLm1vZHMuZmxhZ3MsIGMsIHRyZWUpOwogICAgICAgIGMuc291cmNlZmlsZSA9IGVudi50b3BsZXZlbC5zb3VyY2VmaWxlOwogICAgICAgIGMubWVtYmVyc19maWVsZCA9IFdyaXRlYWJsZVNjb3BlLmNyZWF0ZShjKTsKICAgICAgICBjLmNsZWFyQW5ub3RhdGlvbk1ldGFkYXRhKCk7CgogICAgICAgIENsYXNzVHlwZSBjdCA9IChDbGFzc1R5cGUpYy50eXBlOwogICAgICAgIGlmIChvd25lci5raW5kICE9IFBDSyAmJiAoYy5mbGFnc19maWVsZCAmIFNUQVRJQykgPT0gMCkgewogICAgICAgICAgICAvLyBXZSBhcmUgc2VlaW5nIGEgbG9jYWwgb3IgaW5uZXIgY2xhc3MuCiAgICAgICAgICAgIC8vIFNldCBvdXRlcl9maWVsZCBvZiB0aGlzIGNsYXNzIHRvIGNsb3Nlc3QgZW5jbG9zaW5nIGNsYXNzCiAgICAgICAgICAgIC8vIHdoaWNoIGNvbnRhaW5zIHRoaXMgY2xhc3MgaW4gYSBub24tc3RhdGljIGNvbnRleHQKICAgICAgICAgICAgLy8gKGl0cyAiZW5jbG9zaW5nIGluc3RhbmNlIGNsYXNzIiksIHByb3ZpZGVkIHN1Y2ggYSBjbGFzcyBleGlzdHMuCiAgICAgICAgICAgIFN5bWJvbCBvd25lcjEgPSBvd25lcjsKICAgICAgICAgICAgd2hpbGUgKG93bmVyMS5raW5kLm1hdGNoZXMoS2luZFNlbGVjdG9yLlZBTF9NVEgpICYmCiAgICAgICAgICAgICAgICAgICAob3duZXIxLmZsYWdzX2ZpZWxkICYgU1RBVElDKSA9PSAwKSB7CiAgICAgICAgICAgICAgICBvd25lcjEgPSBvd25lcjEub3duZXI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKG93bmVyMS5raW5kID09IFRZUCkgewogICAgICAgICAgICAgICAgY3Quc2V0RW5jbG9zaW5nVHlwZShvd25lcjEudHlwZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIEVudGVyIHR5cGUgcGFyYW1ldGVycy4KICAgICAgICBjdC50eXBhcmFtc19maWVsZCA9IGNsYXNzRW50ZXIodHJlZS50eXBhcmFtcywgbG9jYWxFbnYpOwogICAgICAgIGN0LmFsbHBhcmFtc19maWVsZCA9IG51bGw7CgogICAgICAgIC8vIGluc3RhbGwgZnVydGhlciBjb21wbGV0ZXIgZm9yIHRoaXMgdHlwZS4KICAgICAgICBjLmNvbXBsZXRlciA9IHR5cGVFbnRlcjsKCiAgICAgICAgLy8gQWRkIG5vbi1sb2NhbCBjbGFzcyB0byB1bmNvbXBsZXRlZCwgdG8gbWFrZSBzdXJlIGl0IHdpbGwgYmUKICAgICAgICAvLyBjb21wbGV0ZWQgbGF0ZXIuCiAgICAgICAgaWYgKCFjLmlzTG9jYWwoKSAmJiB1bmNvbXBsZXRlZCAhPSBudWxsKSB1bmNvbXBsZXRlZC5hcHBlbmQoYyk7Ci8vICAgICAgU3lzdGVtLmVyci5wcmludGxuKCJlbnRlcmluZyAiICsgYy5mdWxsbmFtZSArICIgaW4gIiArIGMub3duZXIpOy8vREVCVUcKCiAgICAgICAgLy8gUmVjdXJzaXZlbHkgZW50ZXIgYWxsIG1lbWJlciBjbGFzc2VzLgogICAgICAgIGNsYXNzRW50ZXIodHJlZS5kZWZzLCBsb2NhbEVudik7CgovLyAgICAgICAgQXNzZXJ0LmNoZWNrTm9uTnVsbChjLm1vZGxlLCBjLnNvdXJjZWZpbGUudG9TdHJpbmcoKSk7CgogICAgICAgIHJlc3VsdCA9IGMudHlwZTsKICAgIH0KICAgIC8vd2hlcmUKICAgICAgICAvKiogRG9lcyBjbGFzcyBoYXZlIHRoZSBzYW1lIG5hbWUgYXMgdGhlIGZpbGUgaXQgYXBwZWFycyBpbj8KICAgICAgICAgKi8KICAgICAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGNsYXNzTmFtZU1hdGNoZXNGaWxlTmFtZShDbGFzc1N5bWJvbCBjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVudjxBdHRyQ29udGV4dD4gZW52KSB7CiAgICAgICAgICAgIHJldHVybiBlbnYudG9wbGV2ZWwuc291cmNlZmlsZS5pc05hbWVDb21wYXRpYmxlKGMubmFtZS50b1N0cmluZygpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBKYXZhRmlsZU9iamVjdC5LaW5kLlNPVVJDRSk7CiAgICAgICAgfQoKICAgIC8qKiBDb21wbGFpbiBhYm91dCBhIGR1cGxpY2F0ZSBjbGFzcy4gKi8KICAgIHByb3RlY3RlZCB2b2lkIGR1cGxpY2F0ZUNsYXNzKERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIENsYXNzU3ltYm9sIGMpIHsKICAgICAgICBsb2cuZXJyb3IocG9zLCAiZHVwbGljYXRlLmNsYXNzIiwgYy5mdWxsbmFtZSk7CiAgICB9CgogICAgLyoqIENsYXNzIGVudGVyIHZpc2l0b3IgbWV0aG9kIGZvciB0eXBlIHBhcmFtZXRlcnMuCiAgICAgKiAgRW50ZXIgYSBzeW1ib2wgZm9yIHR5cGUgcGFyYW1ldGVyIGluIGxvY2FsIHNjb3BlLCBhZnRlciBjaGVja2luZyB0aGF0IGl0CiAgICAgKiAgaXMgdW5pcXVlLgogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHZpc2l0VHlwZVBhcmFtZXRlcihKQ1R5cGVQYXJhbWV0ZXIgdHJlZSkgewogICAgICAgIFR5cGVWYXIgYSA9ICh0cmVlLnR5cGUgIT0gbnVsbCkKICAgICAgICAgICAgPyAoVHlwZVZhcil0cmVlLnR5cGUKICAgICAgICAgICAgOiBuZXcgVHlwZVZhcih0cmVlLm5hbWUsIGVudi5pbmZvLnNjb3BlLm93bmVyLCBzeW1zLmJvdFR5cGUpOwogICAgICAgIHRyZWUudHlwZSA9IGE7CiAgICAgICAgaWYgKGNoay5jaGVja1VuaXF1ZSh0cmVlLnBvcygpLCBhLnRzeW0sIGVudi5pbmZvLnNjb3BlKSkgewogICAgICAgICAgICBlbnYuaW5mby5zY29wZS5lbnRlcihhLnRzeW0pOwogICAgICAgIH0KICAgICAgICByZXN1bHQgPSBhOwogICAgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIHZvaWQgdmlzaXRNb2R1bGVEZWYoSkNNb2R1bGVEZWNsIHRyZWUpIHsKICAgICAgICBFbnY8QXR0ckNvbnRleHQ+IG1vZHVsZUVudiA9IG1vZHVsZUVudih0cmVlLCBlbnYpOwogICAgICAgIHR5cGVFbnZzLnB1dCh0cmVlLnN5bSwgbW9kdWxlRW52KTsKICAgICAgICBpZiAobW9kdWxlcy5pc0luTW9kdWxlR3JhcGgodHJlZS5zeW0pKSB7CiAgICAgICAgICAgIHRvZG8uYXBwZW5kKG1vZHVsZUVudik7CiAgICAgICAgfQogICAgfQoKICAgIC8qKiBEZWZhdWx0IGNsYXNzIGVudGVyIHZpc2l0b3IgbWV0aG9kOiBkbyBub3RoaW5nLgogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHZpc2l0VHJlZShKQ1RyZWUgdHJlZSkgewogICAgICAgIHJlc3VsdCA9IG51bGw7CiAgICB9CgogICAgLyoqIE1haW4gbWV0aG9kOiBlbnRlciBhbGwgY2xhc3NlcyBpbiBhIGxpc3Qgb2YgdG9wbGV2ZWwgdHJlZXMuCiAgICAgKiAgQHBhcmFtIHRyZWVzICAgICAgVGhlIGxpc3Qgb2YgdHJlZXMgdG8gYmUgcHJvY2Vzc2VkLgogICAgICovCiAgICBwdWJsaWMgdm9pZCBtYWluKExpc3Q8SkNDb21waWxhdGlvblVuaXQ+IHRyZWVzKSB7CiAgICAgICAgY29tcGxldGUodHJlZXMsIG51bGwpOwogICAgfQoKICAgIC8qKiBNYWluIG1ldGhvZDogZW50ZXIgY2xhc3NlcyBmcm9tIHRoZSBsaXN0IG9mIHRvcGxldmVsIHRyZWVzLCBwb3NzaWJseQogICAgICogIHNraXBwaW5nIFR5cGVFbnRlciBmb3IgYWxsIGJ1dCAnYycgYnkgcGxhY2luZyB0aGVtIG9uIHRoZSB1bmNvbXBsZXRlZAogICAgICogIGxpc3QuCiAgICAgKiAgQHBhcmFtIHRyZWVzICAgICAgVGhlIGxpc3Qgb2YgdHJlZXMgdG8gYmUgcHJvY2Vzc2VkLgogICAgICogIEBwYXJhbSBjICAgICAgICAgIFRoZSBjbGFzcyBzeW1ib2wgdG8gYmUgcHJvY2Vzc2VkIG9yIG51bGwgdG8gcHJvY2VzcyBhbGwuCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIGNvbXBsZXRlKExpc3Q8SkNDb21waWxhdGlvblVuaXQ+IHRyZWVzLCBDbGFzc1N5bWJvbCBjKSB7CiAgICAgICAgYW5ub3RhdGUuYmxvY2tBbm5vdGF0aW9ucygpOwogICAgICAgIExpc3RCdWZmZXI8Q2xhc3NTeW1ib2w+IHByZXZVbmNvbXBsZXRlZCA9IHVuY29tcGxldGVkOwogICAgICAgIGlmICh0eXBlRW50ZXIuY29tcGxldGlvbkVuYWJsZWQpIHVuY29tcGxldGVkID0gbmV3IExpc3RCdWZmZXI8PigpOwoKICAgICAgICB0cnkgewogICAgICAgICAgICAvLyBlbnRlciBhbGwgY2xhc3NlcywgYW5kIGNvbnN0cnVjdCB1bmNvbXBsZXRlZCBsaXN0CiAgICAgICAgICAgIGNsYXNzRW50ZXIodHJlZXMsIG51bGwpOwoKICAgICAgICAgICAgLy8gY29tcGxldGUgYWxsIHVuY29tcGxldGVkIGNsYXNzZXMgaW4gbWVtYmVyRW50ZXIKICAgICAgICAgICAgaWYgKHR5cGVFbnRlci5jb21wbGV0aW9uRW5hYmxlZCkgewogICAgICAgICAgICAgICAgd2hpbGUgKHVuY29tcGxldGVkLm5vbkVtcHR5KCkpIHsKICAgICAgICAgICAgICAgICAgICBDbGFzc1N5bWJvbCBjbGF6eiA9IHVuY29tcGxldGVkLm5leHQoKTsKICAgICAgICAgICAgICAgICAgICBpZiAoYyA9PSBudWxsIHx8IGMgPT0gY2xhenogfHwgcHJldlVuY29tcGxldGVkID09IG51bGwpCiAgICAgICAgICAgICAgICAgICAgICAgIGNsYXp6LmNvbXBsZXRlKCk7CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAvLyBkZWZlcgogICAgICAgICAgICAgICAgICAgICAgICBwcmV2VW5jb21wbGV0ZWQuYXBwZW5kKGNsYXp6KTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoIW1vZHVsZXMubW9kdWxlc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgICAgICAgICAgICBmb3IgKEpDQ29tcGlsYXRpb25Vbml0IGN1dCA6IHRyZWVzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjdXQuZ2V0TW9kdWxlRGVjbCgpICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuZmluaXNoZWRNb2R1bGVzLmFwcGVuZChjdXQpOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZUVudGVyLmVuc3VyZUltcG9ydHNDaGVja2VkKExpc3Qub2YoY3V0KSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHR5cGVFbnRlci5lbnN1cmVJbXBvcnRzQ2hlY2tlZCh1bmZpbmlzaGVkTW9kdWxlcy50b0xpc3QoKSk7CiAgICAgICAgICAgICAgICAgICAgdW5maW5pc2hlZE1vZHVsZXMuY2xlYXIoKTsKICAgICAgICAgICAgICAgICAgICB0eXBlRW50ZXIuZW5zdXJlSW1wb3J0c0NoZWNrZWQodHJlZXMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgdW5jb21wbGV0ZWQgPSBwcmV2VW5jb21wbGV0ZWQ7CiAgICAgICAgICAgIGFubm90YXRlLnVuYmxvY2tBbm5vdGF0aW9ucygpOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgdm9pZCBuZXdSb3VuZCgpIHsKICAgICAgICB0eXBlRW52cy5jbGVhcigpOwogICAgfQp9ClBLAwQKAAAIAADSfU1KP8wvYUEKAABBCgAAJgAAAGNvbS9zdW4vdG9vbHMvamF2YWMvY29tcC9UeXBlRW52cy5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDE0LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuamF2YWMuY29tcDsKCmltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbjsKaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlN5bWJvbC5UeXBlU3ltYm9sOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkNvbnRleHQ7CgovKiogVGhpcyBjbGFzcyBjb250YWlucyB0aGUgdHlwZSBlbnZpcm9ubWVudHMgdXNlZCBieSBFbnRlciwgTWVtYmVyRW50ZXIsCiAqICBBdHRyLCBEZWZlcnJlZEF0dHIsIGFuZCBMb3dlci4KICoKICogIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqICBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqICBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogKiAgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPgogKi8KY2xhc3MgVHlwZUVudnMgewogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gNTcxNTI0NzUyNDg5OTU0NjMxTDsKCiAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIENvbnRleHQuS2V5PFR5cGVFbnZzPiB0eXBlRW52c0tleSA9IG5ldyBDb250ZXh0LktleTw+KCk7CiAgICBwdWJsaWMgc3RhdGljIFR5cGVFbnZzIGluc3RhbmNlKENvbnRleHQgY29udGV4dCkgewogICAgICAgIFR5cGVFbnZzIGluc3RhbmNlID0gY29udGV4dC5nZXQodHlwZUVudnNLZXkpOwogICAgICAgIGlmIChpbnN0YW5jZSA9PSBudWxsKQogICAgICAgICAgICBpbnN0YW5jZSA9IG5ldyBUeXBlRW52cyhjb250ZXh0KTsKICAgICAgICByZXR1cm4gaW5zdGFuY2U7CiAgICB9CgogICAgcHJpdmF0ZSBIYXNoTWFwPFR5cGVTeW1ib2wsRW52PEF0dHJDb250ZXh0Pj4gbWFwOwogICAgcHJvdGVjdGVkIFR5cGVFbnZzKENvbnRleHQgY29udGV4dCkgewogICAgICAgIG1hcCA9IG5ldyBIYXNoTWFwPD4oKTsKICAgICAgICBjb250ZXh0LnB1dCh0eXBlRW52c0tleSwgdGhpcyk7CiAgICB9CgogICAgRW52PEF0dHJDb250ZXh0PiBnZXQoVHlwZVN5bWJvbCBzeW0pIHsgcmV0dXJuIG1hcC5nZXQoc3ltKTsgfQogICAgRW52PEF0dHJDb250ZXh0PiBwdXQoVHlwZVN5bWJvbCBzeW0sIEVudjxBdHRyQ29udGV4dD4gZW52KSB7IHJldHVybiBtYXAucHV0KHN5bSwgZW52KTsgfQogICAgRW52PEF0dHJDb250ZXh0PiByZW1vdmUoVHlwZVN5bWJvbCBzeW0pIHsgcmV0dXJuIG1hcC5yZW1vdmUoc3ltKTsgfQogICAgQ29sbGVjdGlvbjxFbnY8QXR0ckNvbnRleHQ+PiB2YWx1ZXMoKSB7IHJldHVybiBtYXAudmFsdWVzKCk7IH0KICAgIHZvaWQgY2xlYXIoKSB7IG1hcC5jbGVhcigpOyB9Cn0KUEsDBAoAAAgAANJ9TUocHHhqLBcAACwXAAAiAAAAY29tL3N1bi90b29scy9qYXZhYy9jb21wL1RvZG8uamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwMSwgMjAxNCwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLmphdmFjLmNvbXA7CgppbXBvcnQgamF2YS51dGlsLkFic3RyYWN0UXVldWU7CmltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbjsKaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOwppbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOwppbXBvcnQgamF2YS51dGlsLkxpbmtlZExpc3Q7CmltcG9ydCBqYXZhLnV0aWwuTWFwOwppbXBvcnQgamF2YS51dGlsLlF1ZXVlOwppbXBvcnQgamF2YXgudG9vbHMuSmF2YUZpbGVPYmplY3Q7CgppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkNvbnRleHQ7CgovKiogQSBxdWV1ZSBvZiBhbGwgYXMgeWV0IHVuYXR0cmlidXRlZCBjbGFzc2VzLgogKgogKiAgPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24gcmlzay4KICogIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yCiAqICBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+CiAqLwpwdWJsaWMgY2xhc3MgVG9kbyBleHRlbmRzIEFic3RyYWN0UXVldWU8RW52PEF0dHJDb250ZXh0Pj4gewogICAgLyoqIFRoZSBjb250ZXh0IGtleSBmb3IgdGhlIHRvZG8gbGlzdC4gKi8KICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgQ29udGV4dC5LZXk8VG9kbz4gdG9kb0tleSA9IG5ldyBDb250ZXh0LktleTw+KCk7CgogICAgLyoqIEdldCB0aGUgVG9kbyBpbnN0YW5jZSBmb3IgdGhpcyBjb250ZXh0LiAqLwogICAgcHVibGljIHN0YXRpYyBUb2RvIGluc3RhbmNlKENvbnRleHQgY29udGV4dCkgewogICAgICAgIFRvZG8gaW5zdGFuY2UgPSBjb250ZXh0LmdldCh0b2RvS2V5KTsKICAgICAgICBpZiAoaW5zdGFuY2UgPT0gbnVsbCkKICAgICAgICAgICAgaW5zdGFuY2UgPSBuZXcgVG9kbyhjb250ZXh0KTsKICAgICAgICByZXR1cm4gaW5zdGFuY2U7CiAgICB9CgogICAgLyoqIENyZWF0ZSBhIG5ldyB0b2RvIGxpc3QuICovCiAgICBwcm90ZWN0ZWQgVG9kbyhDb250ZXh0IGNvbnRleHQpIHsKICAgICAgICBjb250ZXh0LnB1dCh0b2RvS2V5LCB0aGlzKTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCBhcHBlbmQoRW52PEF0dHJDb250ZXh0PiBlbnYpIHsKICAgICAgICBhZGQoZW52KTsKICAgIH0KCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBJdGVyYXRvcjxFbnY8QXR0ckNvbnRleHQ+PiBpdGVyYXRvcigpIHsKICAgICAgICByZXR1cm4gY29udGVudHMuaXRlcmF0b3IoKTsKICAgIH0KCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgc2l6ZSgpIHsKICAgICAgICByZXR1cm4gY29udGVudHMuc2l6ZSgpOwogICAgfQoKICAgIHB1YmxpYyBib29sZWFuIG9mZmVyKEVudjxBdHRyQ29udGV4dD4gZSkgewogICAgICAgIGlmIChjb250ZW50cy5hZGQoZSkpIHsKICAgICAgICAgICAgaWYgKGNvbnRlbnRzQnlGaWxlICE9IG51bGwpCiAgICAgICAgICAgICAgICBhZGRCeUZpbGUoZSk7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBSZW1vdmVzIGFsbCB1bmF0dHJpYnV0ZWQgY2xhc3NlcyBleGNlcHQgdGhvc2UgYmVsb25naW5nIHRvIHRoZSBnaXZlbgogICAgICogY29sbGVjdGlvbiBvZiBmaWxlcy4KICAgICAqCiAgICAgKiBAcGFyYW0gc291cmNlRmlsZXMgVGhlIHNvdXJjZSBmaWxlcyBvZiB0aGUgY2xhc3NlcyB0byBrZWVwLgogICAgICovCiAgICBwdWJsaWMgdm9pZCByZXRhaW5GaWxlcyhDb2xsZWN0aW9uPD8gZXh0ZW5kcyBKYXZhRmlsZU9iamVjdD4gc291cmNlRmlsZXMpIHsKICAgICAgICBmb3IgKEl0ZXJhdG9yPEVudjxBdHRyQ29udGV4dD4+IGl0ID0gY29udGVudHMuaXRlcmF0b3IoKTsgaXQuaGFzTmV4dCgpOyApIHsKICAgICAgICAgICAgRW52PEF0dHJDb250ZXh0PiBlbnYgPSBpdC5uZXh0KCk7CiAgICAgICAgICAgIGlmICghc291cmNlRmlsZXMuY29udGFpbnMoZW52LnRvcGxldmVsLnNvdXJjZWZpbGUpKSB7CiAgICAgICAgICAgICAgICBpZiAoY29udGVudHNCeUZpbGUgIT0gbnVsbCkgcmVtb3ZlQnlGaWxlKGVudik7CiAgICAgICAgICAgICAgICBpdC5yZW1vdmUoKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgRW52PEF0dHJDb250ZXh0PiBwb2xsKCkgewogICAgICAgIGlmIChzaXplKCkgPT0gMCkKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgRW52PEF0dHJDb250ZXh0PiBlbnYgPSBjb250ZW50cy5yZW1vdmUoMCk7CiAgICAgICAgaWYgKGNvbnRlbnRzQnlGaWxlICE9IG51bGwpCiAgICAgICAgICAgIHJlbW92ZUJ5RmlsZShlbnYpOwogICAgICAgIHJldHVybiBlbnY7CiAgICB9CgogICAgcHVibGljIEVudjxBdHRyQ29udGV4dD4gcGVlaygpIHsKICAgICAgICByZXR1cm4gKHNpemUoKSA9PSAwID8gbnVsbCA6IGNvbnRlbnRzLmdldCgwKSk7CiAgICB9CgogICAgcHVibGljIFF1ZXVlPFF1ZXVlPEVudjxBdHRyQ29udGV4dD4+PiBncm91cEJ5RmlsZSgpIHsKICAgICAgICBpZiAoY29udGVudHNCeUZpbGUgPT0gbnVsbCkgewogICAgICAgICAgICBjb250ZW50c0J5RmlsZSA9IG5ldyBMaW5rZWRMaXN0PD4oKTsKICAgICAgICAgICAgZm9yIChFbnY8QXR0ckNvbnRleHQ+IGVudjogY29udGVudHMpIHsKICAgICAgICAgICAgICAgIGFkZEJ5RmlsZShlbnYpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBjb250ZW50c0J5RmlsZTsKICAgIH0KCiAgICBwcml2YXRlIHZvaWQgYWRkQnlGaWxlKEVudjxBdHRyQ29udGV4dD4gZW52KSB7CiAgICAgICAgSmF2YUZpbGVPYmplY3QgZmlsZSA9IGVudi50b3BsZXZlbC5zb3VyY2VmaWxlOwogICAgICAgIGlmIChmaWxlTWFwID09IG51bGwpCiAgICAgICAgICAgIGZpbGVNYXAgPSBuZXcgSGFzaE1hcDw+KCk7CiAgICAgICAgRmlsZVF1ZXVlIGZxID0gZmlsZU1hcC5nZXQoZmlsZSk7CiAgICAgICAgaWYgKGZxID09IG51bGwpIHsKICAgICAgICAgICAgZnEgPSBuZXcgRmlsZVF1ZXVlKCk7CiAgICAgICAgICAgIGZpbGVNYXAucHV0KGZpbGUsIGZxKTsKICAgICAgICAgICAgY29udGVudHNCeUZpbGUuYWRkKGZxKTsKICAgICAgICB9CiAgICAgICAgZnEuZmlsZUNvbnRlbnRzLmFkZChlbnYpOwogICAgfQoKICAgIHByaXZhdGUgdm9pZCByZW1vdmVCeUZpbGUoRW52PEF0dHJDb250ZXh0PiBlbnYpIHsKICAgICAgICBKYXZhRmlsZU9iamVjdCBmaWxlID0gZW52LnRvcGxldmVsLnNvdXJjZWZpbGU7CiAgICAgICAgRmlsZVF1ZXVlIGZxID0gZmlsZU1hcC5nZXQoZmlsZSk7CiAgICAgICAgaWYgKGZxID09IG51bGwpCiAgICAgICAgICAgIHJldHVybjsKICAgICAgICBpZiAoZnEuZmlsZUNvbnRlbnRzLnJlbW92ZShlbnYpKSB7CiAgICAgICAgICAgIGlmIChmcS5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICAgIGZpbGVNYXAucmVtb3ZlKGZpbGUpOwogICAgICAgICAgICAgICAgY29udGVudHNCeUZpbGUucmVtb3ZlKGZxKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBMaW5rZWRMaXN0PEVudjxBdHRyQ29udGV4dD4+IGNvbnRlbnRzID0gbmV3IExpbmtlZExpc3Q8PigpOwogICAgTGlua2VkTGlzdDxRdWV1ZTxFbnY8QXR0ckNvbnRleHQ+Pj4gY29udGVudHNCeUZpbGU7CiAgICBNYXA8SmF2YUZpbGVPYmplY3QsIEZpbGVRdWV1ZT4gZmlsZU1hcDsKCiAgICBjbGFzcyBGaWxlUXVldWUgZXh0ZW5kcyBBYnN0cmFjdFF1ZXVlPEVudjxBdHRyQ29udGV4dD4+IHsKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgSXRlcmF0b3I8RW52PEF0dHJDb250ZXh0Pj4gaXRlcmF0b3IoKSB7CiAgICAgICAgICAgIHJldHVybiBmaWxlQ29udGVudHMuaXRlcmF0b3IoKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBpbnQgc2l6ZSgpIHsKICAgICAgICAgICAgcmV0dXJuIGZpbGVDb250ZW50cy5zaXplKCk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgYm9vbGVhbiBvZmZlcihFbnY8QXR0ckNvbnRleHQ+IGUpIHsKICAgICAgICAgICAgaWYgKGZpbGVDb250ZW50cy5vZmZlcihlKSkgewogICAgICAgICAgICAgICAgY29udGVudHMuYWRkKGUpOwogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIEVudjxBdHRyQ29udGV4dD4gcG9sbCgpIHsKICAgICAgICAgICAgaWYgKGZpbGVDb250ZW50cy5zaXplKCkgPT0gMCkKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICBFbnY8QXR0ckNvbnRleHQ+IGVudiA9IGZpbGVDb250ZW50cy5yZW1vdmUoMCk7CiAgICAgICAgICAgIGNvbnRlbnRzLnJlbW92ZShlbnYpOwogICAgICAgICAgICByZXR1cm4gZW52OwogICAgICAgIH0KCiAgICAgICAgcHVibGljIEVudjxBdHRyQ29udGV4dD4gcGVlaygpIHsKICAgICAgICAgICAgcmV0dXJuIChmaWxlQ29udGVudHMuc2l6ZSgpID09IDAgPyBudWxsIDogZmlsZUNvbnRlbnRzLmdldCgwKSk7CiAgICAgICAgfQoKICAgICAgICBMaW5rZWRMaXN0PEVudjxBdHRyQ29udGV4dD4+IGZpbGVDb250ZW50cyA9IG5ldyBMaW5rZWRMaXN0PD4oKTsKICAgIH0KfQpQSwMECgAACAAAsTypSpNsXUGrOAEAqzgBACMAAABjb20vc3VuL3Rvb2xzL2phdmFjL2NvbXAvSW5mZXIuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMTk5OSwgMjAxNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLmphdmFjLmNvbXA7CgppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlR5cGUuVW5kZXRWYXIuVW5kZXRWYXJMaXN0ZW5lcjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5UeXBlcy5UeXBlTWFwcGluZzsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5KQ1RyZWU7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuSkNUcmVlLkpDVHlwZUNhc3Q7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuVHJlZUluZm87CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuKjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5HcmFwaFV0aWxzLkRvdHRhYmxlTm9kZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5KQ0RpYWdub3N0aWMuRGlhZ25vc3RpY1Bvc2l0aW9uOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkxpc3Q7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuKjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5UeXBlLio7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuVHlwZS5VbmRldFZhci5JbmZlcmVuY2VCb3VuZDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5TeW1ib2wuKjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29tcC5EZWZlcnJlZEF0dHIuQXR0ck1vZGU7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvbXAuRGVmZXJyZWRBdHRyLkRlZmVycmVkQXR0ckNvbnRleHQ7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvbXAuSW5mZXIuR3JhcGhTb2x2ZXIuSW5mZXJlbmNlR3JhcGg7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvbXAuSW5mZXIuR3JhcGhTb2x2ZXIuSW5mZXJlbmNlR3JhcGguTm9kZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29tcC5SZXNvbHZlLkluYXBwbGljYWJsZU1ldGhvZEV4Y2VwdGlvbjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29tcC5SZXNvbHZlLlZlcmJvc2VSZXNvbHV0aW9uTW9kZTsKCmltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwppbXBvcnQgamF2YS5pby5Xcml0ZXI7CmltcG9ydCBqYXZhLm5pby5maWxlLkZpbGVzOwppbXBvcnQgamF2YS5uaW8uZmlsZS5QYXRoOwppbXBvcnQgamF2YS5uaW8uZmlsZS5QYXRoczsKaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CmltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbjsKaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKaW1wb3J0IGphdmEudXRpbC5FbnVtU2V0OwppbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CmltcG9ydCBqYXZhLnV0aWwuSGFzaFNldDsKaW1wb3J0IGphdmEudXRpbC5NYXA7CmltcG9ydCBqYXZhLnV0aWwuT3B0aW9uYWw7CmltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKaW1wb3J0IGphdmEudXRpbC5TZXQ7CmltcG9ydCBqYXZhLnV0aWwuZnVuY3Rpb24uQmlGdW5jdGlvbjsKaW1wb3J0IGphdmEudXRpbC5mdW5jdGlvbi5CaVByZWRpY2F0ZTsKCmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlR5cGVUYWcuKjsKCi8qKiBIZWxwZXIgY2xhc3MgZm9yIHR5cGUgcGFyYW1ldGVyIGluZmVyZW5jZSwgdXNlZCBieSB0aGUgYXR0cmlidXRpb24gcGhhc2UuCiAqCiAqICA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiAgSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93biByaXNrLgogKiAgVGhpcyBjb2RlIGFuZCBpdHMgaW50ZXJuYWwgaW50ZXJmYWNlcyBhcmUgc3ViamVjdCB0byBjaGFuZ2Ugb3IKICogIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj4KICovCnB1YmxpYyBjbGFzcyBJbmZlciB7CiAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIENvbnRleHQuS2V5PEluZmVyPiBpbmZlcktleSA9IG5ldyBDb250ZXh0LktleTw+KCk7CgogICAgUmVzb2x2ZSByczsKICAgIENoZWNrIGNoazsKICAgIFN5bXRhYiBzeW1zOwogICAgVHlwZXMgdHlwZXM7CiAgICBKQ0RpYWdub3N0aWMuRmFjdG9yeSBkaWFnczsKICAgIExvZyBsb2c7CgogICAgLyoqIHNob3VsZCB0aGUgZ3JhcGggc29sdmVyIGJlIHVzZWQ/ICovCiAgICBib29sZWFuIGFsbG93R3JhcGhJbmZlcmVuY2U7CgogICAgLyoqCiAgICAgKiBmb2xkZXIgaW4gd2hpY2ggdGhlIGluZmVyZW5jZSBkZXBlbmRlbmN5IGdyYXBocyBzaG91bGQgYmUgd3JpdHRlbi4KICAgICAqLwogICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgZGVwZW5kZW5jaWVzRm9sZGVyOwoKICAgIC8qKgogICAgICogTGlzdCBvZiBncmFwaHMgYXdhaXRpbmcgdG8gYmUgZHVtcGVkIHRvIGEgZmlsZS4KICAgICAqLwogICAgcHJpdmF0ZSBMaXN0PFN0cmluZz4gcGVuZGluZ0dyYXBoczsKCiAgICBwdWJsaWMgc3RhdGljIEluZmVyIGluc3RhbmNlKENvbnRleHQgY29udGV4dCkgewogICAgICAgIEluZmVyIGluc3RhbmNlID0gY29udGV4dC5nZXQoaW5mZXJLZXkpOwogICAgICAgIGlmIChpbnN0YW5jZSA9PSBudWxsKQogICAgICAgICAgICBpbnN0YW5jZSA9IG5ldyBJbmZlcihjb250ZXh0KTsKICAgICAgICByZXR1cm4gaW5zdGFuY2U7CiAgICB9CgogICAgcHJvdGVjdGVkIEluZmVyKENvbnRleHQgY29udGV4dCkgewogICAgICAgIGNvbnRleHQucHV0KGluZmVyS2V5LCB0aGlzKTsKCiAgICAgICAgcnMgPSBSZXNvbHZlLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIGNoayA9IENoZWNrLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIHN5bXMgPSBTeW10YWIuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgdHlwZXMgPSBUeXBlcy5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBkaWFncyA9IEpDRGlhZ25vc3RpYy5GYWN0b3J5Lmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIGxvZyA9IExvZy5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBpbmZlcmVuY2VFeGNlcHRpb24gPSBuZXcgSW5mZXJlbmNlRXhjZXB0aW9uKGRpYWdzKTsKICAgICAgICBPcHRpb25zIG9wdGlvbnMgPSBPcHRpb25zLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIGFsbG93R3JhcGhJbmZlcmVuY2UgPSBTb3VyY2UuaW5zdGFuY2UoY29udGV4dCkuYWxsb3dHcmFwaEluZmVyZW5jZSgpCiAgICAgICAgICAgICAgICAmJiBvcHRpb25zLmlzVW5zZXQoInVzZUxlZ2FjeUluZmVyZW5jZSIpOwogICAgICAgIGRlcGVuZGVuY2llc0ZvbGRlciA9IG9wdGlvbnMuZ2V0KCJkZWJ1Zy5kdW1wSW5mZXJlbmNlR3JhcGhzVG8iKTsKICAgICAgICBwZW5kaW5nR3JhcGhzID0gTGlzdC5uaWwoKTsKCiAgICAgICAgZW1wdHlDb250ZXh0ID0gbmV3IEluZmVyZW5jZUNvbnRleHQodGhpcywgTGlzdC5uaWwoKSk7CiAgICB9CgogICAgLyoqIEEgdmFsdWUgZm9yIHByb3RvdHlwZXMgdGhhdCBhZG1pdCBhbnkgdHlwZSwgaW5jbHVkaW5nIHBvbHltb3JwaGljIG9uZXMuICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFR5cGUgYW55UG9seSA9IG5ldyBKQ05vVHlwZSgpOwoKICAgLyoqCiAgICAqIFRoaXMgZXhjZXB0aW9uIGNsYXNzIGlzIGRlc2lnbiB0byBzdG9yZSBhIGxpc3Qgb2YgZGlhZ25vc3RpY3MgY29ycmVzcG9uZGluZwogICAgKiB0byBpbmZlcmVuY2UgZXJyb3JzIHRoYXQgY2FuIGFyaXNlIGR1cmluZyBhIG1ldGhvZCBhcHBsaWNhYmlsaXR5IGNoZWNrLgogICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgSW5mZXJlbmNlRXhjZXB0aW9uIGV4dGVuZHMgSW5hcHBsaWNhYmxlTWV0aG9kRXhjZXB0aW9uIHsKICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwOwoKICAgICAgICBMaXN0PEpDRGlhZ25vc3RpYz4gbWVzc2FnZXMgPSBMaXN0Lm5pbCgpOwoKICAgICAgICBJbmZlcmVuY2VFeGNlcHRpb24oSkNEaWFnbm9zdGljLkZhY3RvcnkgZGlhZ3MpIHsKICAgICAgICAgICAgc3VwZXIoZGlhZ3MpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgSW5hcHBsaWNhYmxlTWV0aG9kRXhjZXB0aW9uIHNldE1lc3NhZ2UoKSB7CiAgICAgICAgICAgIC8vbm8gbWVzc2FnZSB0byBzZXQKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBJbmFwcGxpY2FibGVNZXRob2RFeGNlcHRpb24gc2V0TWVzc2FnZShKQ0RpYWdub3N0aWMgZGlhZykgewogICAgICAgICAgICBtZXNzYWdlcyA9IG1lc3NhZ2VzLmFwcGVuZChkaWFnKTsKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgSkNEaWFnbm9zdGljIGdldERpYWdub3N0aWMoKSB7CiAgICAgICAgICAgIHJldHVybiBtZXNzYWdlcy5oZWFkOwogICAgICAgIH0KCiAgICAgICAgdm9pZCBjbGVhcigpIHsKICAgICAgICAgICAgbWVzc2FnZXMgPSBMaXN0Lm5pbCgpOwogICAgICAgIH0KICAgIH0KCiAgICBwcm90ZWN0ZWQgZmluYWwgSW5mZXJlbmNlRXhjZXB0aW9uIGluZmVyZW5jZUV4Y2VwdGlvbjsKCiAgICAvLyA8ZWRpdG9yLWZvbGQgZGVmYXVsdHN0YXRlPSJjb2xsYXBzZWQiIGRlc2M9IkluZmVyZW5jZSByb3V0aW5lcyI+CiAgICAvKioKICAgICAqIE1haW4gaW5mZXJlbmNlIGVudHJ5IHBvaW50IC0gaW5zdGFudGlhdGUgYSBnZW5lcmljIG1ldGhvZCB0eXBlCiAgICAgKiB1c2luZyBnaXZlbiBhcmd1bWVudCB0eXBlcyBhbmQgKHBvc3NpYmx5KSBhbiBleHBlY3RlZCB0YXJnZXQtdHlwZS4KICAgICAqLwogICAgVHlwZSBpbnN0YW50aWF0ZU1ldGhvZCggRW52PEF0dHJDb250ZXh0PiBlbnYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IHR2YXJzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgTWV0aG9kVHlwZSBtdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0dHIuUmVzdWx0SW5mbyByZXN1bHRJbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgTWV0aG9kU3ltYm9sIG1zeW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IGFyZ3R5cGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBhbGxvd0JveGluZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gdXNlVmFyYXJncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlc29sdmUuTWV0aG9kUmVzb2x1dGlvbkNvbnRleHQgcmVzb2x2ZUNvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBXYXJuZXIgd2FybikgdGhyb3dzIEluZmVyZW5jZUV4Y2VwdGlvbiB7CiAgICAgICAgLy8tU3lzdGVtLmVyci5wcmludGxuKCJpbnN0YW50aWF0ZU1ldGhvZCgiICsgdHZhcnMgKyAiLCAiICsgbXQgKyAiLCAiICsgYXJndHlwZXMgKyAiKSIpOyAvL0RFQlVHCiAgICAgICAgZmluYWwgSW5mZXJlbmNlQ29udGV4dCBpbmZlcmVuY2VDb250ZXh0ID0gbmV3IEluZmVyZW5jZUNvbnRleHQodGhpcywgdHZhcnMpOyAgLy9CMAogICAgICAgIGluZmVyZW5jZUV4Y2VwdGlvbi5jbGVhcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICAgIERlZmVycmVkQXR0ci5EZWZlcnJlZEF0dHJDb250ZXh0IGRlZmVycmVkQXR0ckNvbnRleHQgPQogICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlQ29udGV4dC5kZWZlcnJlZEF0dHJDb250ZXh0KG1zeW0sIGluZmVyZW5jZUNvbnRleHQsIHJlc3VsdEluZm8sIHdhcm4pOwoKICAgICAgICAgICAgcmVzb2x2ZUNvbnRleHQubWV0aG9kQ2hlY2suYXJndW1lbnRzQWNjZXB0YWJsZShlbnYsIGRlZmVycmVkQXR0ckNvbnRleHQsICAgLy9CMgogICAgICAgICAgICAgICAgICAgIGFyZ3R5cGVzLCBtdC5nZXRQYXJhbWV0ZXJUeXBlcygpLCB3YXJuKTsKCiAgICAgICAgICAgIGlmIChhbGxvd0dyYXBoSW5mZXJlbmNlICYmIHJlc3VsdEluZm8gIT0gbnVsbCAmJiByZXN1bHRJbmZvLnB0ID09IGFueVBvbHkpIHsKICAgICAgICAgICAgICAgIGRvSW5jb3Jwb3JhdGlvbihpbmZlcmVuY2VDb250ZXh0LCB3YXJuKTsKICAgICAgICAgICAgICAgIC8vd2UgYXJlIGluc2lkZSBtZXRob2QgYXR0cmlidXRpb24gLSBqdXN0IHJldHVybiBhIHBhcnRpYWxseSBpbmZlcnJlZCB0eXBlCiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFBhcnRpYWxseUluZmVycmVkTWV0aG9kVHlwZShtdCwgaW5mZXJlbmNlQ29udGV4dCwgZW52LCB3YXJuKTsKICAgICAgICAgICAgfSBlbHNlIGlmIChhbGxvd0dyYXBoSW5mZXJlbmNlICYmIHJlc3VsdEluZm8gIT0gbnVsbCkgewoKICAgICAgICAgICAgICAgIC8vaW5qZWN0IHJldHVybiBjb25zdHJhaW50cyBlYXJsaWVyCiAgICAgICAgICAgICAgICBkb0luY29ycG9yYXRpb24oaW5mZXJlbmNlQ29udGV4dCwgd2Fybik7IC8vcHJvcGFnYXRpb24KCiAgICAgICAgICAgICAgICBpZiAoIXdhcm4uaGFzTm9uU2lsZW50TGludChMaW50LkxpbnRDYXRlZ29yeS5VTkNIRUNLRUQpKSB7CiAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBzaG91bGRQcm9wYWdhdGUgPSBzaG91bGRQcm9wYWdhdGUobXQuZ2V0UmV0dXJuVHlwZSgpLCByZXN1bHRJbmZvLCBpbmZlcmVuY2VDb250ZXh0KTsKCiAgICAgICAgICAgICAgICAgICAgSW5mZXJlbmNlQ29udGV4dCBtaW5Db250ZXh0ID0gc2hvdWxkUHJvcGFnYXRlID8KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZmVyZW5jZUNvbnRleHQubWluKHJvb3RzKG10LCBkZWZlcnJlZEF0dHJDb250ZXh0KSwgdHJ1ZSwgd2FybikgOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5mZXJlbmNlQ29udGV4dDsKCiAgICAgICAgICAgICAgICAgICAgVHlwZSBuZXdSZXN0eXBlID0gZ2VuZXJhdGVSZXR1cm5Db25zdHJhaW50cyhlbnYudHJlZSwgcmVzdWx0SW5mbywgIC8vQjMKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG10LCBtaW5Db250ZXh0KTsKICAgICAgICAgICAgICAgICAgICBtdCA9IChNZXRob2RUeXBlKXR5cGVzLmNyZWF0ZU1ldGhvZFR5cGVXaXRoUmV0dXJuKG10LCBuZXdSZXN0eXBlKTsKCiAgICAgICAgICAgICAgICAgICAgLy9wcm9wYWdhdGUgb3V0d2FyZHMgaWYgbmVlZGVkCiAgICAgICAgICAgICAgICAgICAgaWYgKHNob3VsZFByb3BhZ2F0ZSkgewogICAgICAgICAgICAgICAgICAgICAgICAvL3Byb3BhZ2F0ZSBpbmZlcmVuY2UgY29udGV4dCBvdXR3YXJkcyBhbmQgZXhpdAogICAgICAgICAgICAgICAgICAgICAgICBtaW5Db250ZXh0LmR1cFRvKHJlc3VsdEluZm8uY2hlY2tDb250ZXh0LmluZmVyZW5jZUNvbnRleHQoKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGRlZmVycmVkQXR0ckNvbnRleHQuY29tcGxldGUoKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG10OwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgZGVmZXJyZWRBdHRyQ29udGV4dC5jb21wbGV0ZSgpOwoKICAgICAgICAgICAgLy8gbWluaW1pemUgYXMgeWV0IHVuZGV0ZXJtaW5lZCB0eXBlIHZhcmlhYmxlcwogICAgICAgICAgICBpZiAoYWxsb3dHcmFwaEluZmVyZW5jZSkgewogICAgICAgICAgICAgICAgaW5mZXJlbmNlQ29udGV4dC5zb2x2ZSh3YXJuKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGluZmVyZW5jZUNvbnRleHQuc29sdmVMZWdhY3kodHJ1ZSwgd2FybiwgTGVnYWN5SW5mZXJlbmNlU3RlcHMuRVFfTE9XRVIuc3RlcHMpOyAvL21pbmltaXplSW5zdAogICAgICAgICAgICB9CgogICAgICAgICAgICBtdCA9IChNZXRob2RUeXBlKWluZmVyZW5jZUNvbnRleHQuYXNJbnN0VHlwZShtdCk7CgogICAgICAgICAgICBpZiAoIWFsbG93R3JhcGhJbmZlcmVuY2UgJiYKICAgICAgICAgICAgICAgICAgICBpbmZlcmVuY2VDb250ZXh0LnJlc3R2YXJzKCkubm9uRW1wdHkoKSAmJgogICAgICAgICAgICAgICAgICAgIHJlc3VsdEluZm8gIT0gbnVsbCAmJgogICAgICAgICAgICAgICAgICAgICF3YXJuLmhhc05vblNpbGVudExpbnQoTGludC5MaW50Q2F0ZWdvcnkuVU5DSEVDS0VEKSkgewogICAgICAgICAgICAgICAgZ2VuZXJhdGVSZXR1cm5Db25zdHJhaW50cyhlbnYudHJlZSwgcmVzdWx0SW5mbywgbXQsIGluZmVyZW5jZUNvbnRleHQpOwogICAgICAgICAgICAgICAgaW5mZXJlbmNlQ29udGV4dC5zb2x2ZUxlZ2FjeShmYWxzZSwgd2FybiwgTGVnYWN5SW5mZXJlbmNlU3RlcHMuRVFfVVBQRVIuc3RlcHMpOyAvL21heGltaXplSW5zdAogICAgICAgICAgICAgICAgbXQgPSAoTWV0aG9kVHlwZSlpbmZlcmVuY2VDb250ZXh0LmFzSW5zdFR5cGUobXQpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAocmVzdWx0SW5mbyAhPSBudWxsICYmIHJzLnZlcmJvc2VSZXNvbHV0aW9uTW9kZS5jb250YWlucyhWZXJib3NlUmVzb2x1dGlvbk1vZGUuREVGRVJSRURfSU5TVCkpIHsKICAgICAgICAgICAgICAgIGxvZy5ub3RlKGVudi50cmVlLnBvcywgImRlZmVycmVkLm1ldGhvZC5pbnN0IiwgbXN5bSwgbXQsIHJlc3VsdEluZm8ucHQpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyByZXR1cm4gaW5zdGFudGlhdGVkIHZlcnNpb24gb2YgbWV0aG9kIHR5cGUKICAgICAgICAgICAgcmV0dXJuIG10OwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgIGlmIChyZXN1bHRJbmZvICE9IG51bGwgfHwgIWFsbG93R3JhcGhJbmZlcmVuY2UpIHsKICAgICAgICAgICAgICAgIGluZmVyZW5jZUNvbnRleHQubm90aWZ5Q2hhbmdlKCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBpbmZlcmVuY2VDb250ZXh0Lm5vdGlmeUNoYW5nZShpbmZlcmVuY2VDb250ZXh0LmJvdW5kZWRWYXJzKCkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChyZXN1bHRJbmZvID09IG51bGwpIHsKICAgICAgICAgICAgICAgIC8qIGlmIHRoZSBpcyBubyByZXN1bHQgaW5mbyB0aGVuIHdlIGNhbiBjbGVhciB0aGUgY2FwdHVyZSB0eXBlcwogICAgICAgICAgICAgICAgICogY2FjaGUgd2l0aG91dCBhZmZlY3RpbmcgYW55IHJlc3VsdCBpbmZvIGNoZWNrCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIGluZmVyZW5jZUNvbnRleHQuY2FwdHVyZVR5cGVDYWNoZS5jbGVhcigpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGR1bXBHcmFwaHNJZk5lZWRlZChlbnYudHJlZSwgbXN5bSwgcmVzb2x2ZUNvbnRleHQpOwogICAgICAgIH0KICAgIH0KICAgIC8vd2hlcmUKICAgICAgICBwcml2YXRlIGJvb2xlYW4gc2hvdWxkUHJvcGFnYXRlKFR5cGUgcmVzdHlwZSwgQXR0ci5SZXN1bHRJbmZvIHRhcmdldCwgSW5mZXJlbmNlQ29udGV4dCBpbmZlcmVuY2VDb250ZXh0KSB7CiAgICAgICAgICAgIHJldHVybiB0YXJnZXQuY2hlY2tDb250ZXh0LmluZmVyZW5jZUNvbnRleHQoKSAhPSBlbXB0eUNvbnRleHQgJiYgLy9lbmNsb3NpbmcgY29udGV4dCBpcyBhIGdlbmVyaWMgbWV0aG9kCiAgICAgICAgICAgICAgICAgICAgICAgIGluZmVyZW5jZUNvbnRleHQuZnJlZShyZXN0eXBlKSAmJiAvL3JldHVybiB0eXBlIGNvbnRhaW5zIGluZmVyZW5jZSB2YXJzCiAgICAgICAgICAgICAgICAgICAgICAgICghaW5mZXJlbmNlQ29udGV4dC5pbmZlcmVuY2V2YXJzLmNvbnRhaW5zKHJlc3R5cGUpIHx8IC8vbm8gZWFnZXIgaW5zdGFudGlhdGlvbiBpcyByZXF1aXJlZCAoYXMgcGVyIDE4LjUuMikKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAhbmVlZHNFYWdlckluc3RhbnRpYXRpb24oKFVuZGV0VmFyKWluZmVyZW5jZUNvbnRleHQuYXNVbmRldFZhcihyZXN0eXBlKSwgdGFyZ2V0LnB0LCBpbmZlcmVuY2VDb250ZXh0KSk7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIExpc3Q8VHlwZT4gcm9vdHMoTWV0aG9kVHlwZSBtdCwgRGVmZXJyZWRBdHRyQ29udGV4dCBkZWZlcnJlZEF0dHJDb250ZXh0KSB7CiAgICAgICAgICAgIExpc3RCdWZmZXI8VHlwZT4gcm9vdHMgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgIHJvb3RzLmFkZChtdC5nZXRSZXR1cm5UeXBlKCkpOwogICAgICAgICAgICBpZiAoZGVmZXJyZWRBdHRyQ29udGV4dCAhPSBudWxsICYmIGRlZmVycmVkQXR0ckNvbnRleHQubW9kZSA9PSBBdHRyTW9kZS5DSEVDSykgewogICAgICAgICAgICAgICAgcm9vdHMuYWRkQWxsKG10LmdldFRocm93blR5cGVzKCkpOwogICAgICAgICAgICAgICAgZm9yIChEZWZlcnJlZEF0dHIuRGVmZXJyZWRBdHRyTm9kZSBuIDogZGVmZXJyZWRBdHRyQ29udGV4dC5kZWZlcnJlZEF0dHJOb2RlcykgewogICAgICAgICAgICAgICAgICAgIHJvb3RzLmFkZEFsbChuLmRlZmVycmVkU3R1Y2tQb2xpY3kuc3R1Y2tWYXJzKCkpOwogICAgICAgICAgICAgICAgICAgIHJvb3RzLmFkZEFsbChuLmRlZmVycmVkU3R1Y2tQb2xpY3kuZGVwVmFycygpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gcm9vdHMudG9MaXN0KCk7CiAgICAgICAgfQoKICAgIC8qKgogICAgICogQSBwYXJ0aWFsbHkgaW5mZXJlZCBtZXRob2QvY29uc3RydWN0b3IgdHlwZTsgc3VjaCBhIHR5cGUgY2FuIGJlIGNoZWNrZWQgbXVsdGlwbGUgdGltZXMKICAgICAqIGFnYWluc3QgZGlmZmVyZW50IHRhcmdldHMuCiAgICAgKi8KICAgIHB1YmxpYyBjbGFzcyBQYXJ0aWFsbHlJbmZlcnJlZE1ldGhvZFR5cGUgZXh0ZW5kcyBNZXRob2RUeXBlIHsKICAgICAgICBwdWJsaWMgUGFydGlhbGx5SW5mZXJyZWRNZXRob2RUeXBlKE1ldGhvZFR5cGUgbXR5cGUsIEluZmVyZW5jZUNvbnRleHQgaW5mZXJlbmNlQ29udGV4dCwgRW52PEF0dHJDb250ZXh0PiBlbnYsIFdhcm5lciB3YXJuKSB7CiAgICAgICAgICAgIHN1cGVyKG10eXBlLmdldFBhcmFtZXRlclR5cGVzKCksIG10eXBlLmdldFJldHVyblR5cGUoKSwgbXR5cGUuZ2V0VGhyb3duVHlwZXMoKSwgbXR5cGUudHN5bSk7CiAgICAgICAgICAgIHRoaXMuaW5mZXJlbmNlQ29udGV4dCA9IGluZmVyZW5jZUNvbnRleHQ7CiAgICAgICAgICAgIHRoaXMuZW52ID0gZW52OwogICAgICAgICAgICB0aGlzLndhcm4gPSB3YXJuOwogICAgICAgIH0KCiAgICAgICAgLyoqIFRoZSBpbmZlcmVuY2UgY29udGV4dC4gKi8KICAgICAgICBmaW5hbCBJbmZlcmVuY2VDb250ZXh0IGluZmVyZW5jZUNvbnRleHQ7CgogICAgICAgIC8qKiBUaGUgYXR0cmlidXRpb24gZW52aXJvbm1lbnQuICovCiAgICAgICAgRW52PEF0dHJDb250ZXh0PiBlbnY7CgogICAgICAgIC8qKiBUaGUgd2FybmVyLiAqLwogICAgICAgIGZpbmFsIFdhcm5lciB3YXJuOwoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc1BhcnRpYWwoKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogQ2hlY2tzIHRoaXMgdHlwZSBhZ2FpbnN0IGEgdGFyZ2V0OyB0aGlzIG1lYW5zIGdlbmVyYXRpbmcgcmV0dXJuIHR5cGUgY29uc3RyYWludHMsIHNvbHZlCiAgICAgICAgICogYW5kIHRoZW4gcm9sbCBiYWNrIHRoZSByZXN1bHRzICh0byBhdm9pZCBwb29sbHV0aW5nIHRoZSBjb250ZXh0KS4KICAgICAgICAgKi8KICAgICAgICBUeXBlIGNoZWNrKEF0dHIuUmVzdWx0SW5mbyByZXN1bHRJbmZvKSB7CiAgICAgICAgICAgIFdhcm5lciBub1dhcm5pbmdzID0gbmV3IFdhcm5lcihudWxsKTsKICAgICAgICAgICAgaW5mZXJlbmNlRXhjZXB0aW9uLmNsZWFyKCk7CiAgICAgICAgICAgIExpc3Q8VHlwZT4gc2F2ZWRfdW5kZXQgPSBudWxsOwogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgLyoqIHdlIG5lZWQgdG8gc2F2ZSB0aGUgaW5mZXJlbmNlIGNvbnRleHQgYmVmb3JlIGdlbmVyYXRpbmcgdGFyZ2V0IHR5cGUgY29uc3RyYWludHMuCiAgICAgICAgICAgICAgICAgKiAgVGhpcyBjb25zdHJhaW50cyBtYXkgcG9sbHV0ZSB0aGUgaW5mZXJlbmNlIGNvbnRleHQgYW5kIG1ha2UgaXQgdXNlbGVzcyBpbiBjYXNlIHdlCiAgICAgICAgICAgICAgICAgKiAgbmVlZCB0byB1c2UgaXQgc2V2ZXJhbCB0aW1lczogd2l0aCBzZXZlcmFsIHRhcmdldHMuCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIHNhdmVkX3VuZGV0ID0gaW5mZXJlbmNlQ29udGV4dC5zYXZlKCk7CiAgICAgICAgICAgICAgICBib29sZWFuIHVuY2hlY2tlZCA9IHdhcm4uaGFzTm9uU2lsZW50TGludChMaW50LkxpbnRDYXRlZ29yeS5VTkNIRUNLRUQpOwogICAgICAgICAgICAgICAgaWYgKCF1bmNoZWNrZWQpIHsKICAgICAgICAgICAgICAgICAgICBib29sZWFuIHNob3VsZFByb3BhZ2F0ZSA9IHNob3VsZFByb3BhZ2F0ZShnZXRSZXR1cm5UeXBlKCksIHJlc3VsdEluZm8sIGluZmVyZW5jZUNvbnRleHQpOwoKICAgICAgICAgICAgICAgICAgICBJbmZlcmVuY2VDb250ZXh0IG1pbkNvbnRleHQgPSBzaG91bGRQcm9wYWdhdGUgPwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5mZXJlbmNlQ29udGV4dC5taW4ocm9vdHMoYXNNZXRob2RUeXBlKCksIG51bGwpLCBmYWxzZSwgd2FybikgOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5mZXJlbmNlQ29udGV4dDsKCiAgICAgICAgICAgICAgICAgICAgTWV0aG9kVHlwZSBvdGhlciA9IChNZXRob2RUeXBlKW1pbkNvbnRleHQudXBkYXRlKGFzTWV0aG9kVHlwZSgpKTsKICAgICAgICAgICAgICAgICAgICBUeXBlIG5ld1Jlc3R5cGUgPSBnZW5lcmF0ZVJldHVybkNvbnN0cmFpbnRzKGVudi50cmVlLCByZXN1bHRJbmZvLCAgLy9CMwogICAgICAgICAgICAgICAgICAgICAgICAgICAgb3RoZXIsIG1pbkNvbnRleHQpOwoKICAgICAgICAgICAgICAgICAgICBpZiAoc2hvdWxkUHJvcGFnYXRlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vcHJvcGFnYXRlIGluZmVyZW5jZSBjb250ZXh0IG91dHdhcmRzIGFuZCBleGl0CiAgICAgICAgICAgICAgICAgICAgICAgIG1pbkNvbnRleHQuZHVwVG8ocmVzdWx0SW5mby5jaGVja0NvbnRleHQuaW5mZXJlbmNlQ29udGV4dCgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdEluZm8uY2hlY2tDb250ZXh0LmRlZmVycmVkQXR0ckNvbnRleHQoKS5pbnNpZGVPdmVybG9hZFBoYXNlKCkpOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3UmVzdHlwZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbmZlcmVuY2VDb250ZXh0LnNvbHZlKG5vV2FybmluZ3MpOwogICAgICAgICAgICAgICAgVHlwZSByZXQgPSBpbmZlcmVuY2VDb250ZXh0LmFzSW5zdFR5cGUodGhpcykuZ2V0UmV0dXJuVHlwZSgpOwogICAgICAgICAgICAgICAgaWYgKHVuY2hlY2tlZCkgewogICAgICAgICAgICAgICAgICAgIC8vaW5saW5lIGxvZ2ljIGZyb20gQXR0ci5jaGVja01ldGhvZCAtIGlmIHVuY2hlY2tlZCBjb252ZXJzaW9uIHdhcyByZXF1aXJlZCwgZXJhc2UKICAgICAgICAgICAgICAgICAgICAvL3JldHVybiB0eXBlIF9hZnRlcl8gcmVzb2x1dGlvbiwgYW5kIGNoZWNrIGFnYWluc3QgdGFyZ2V0CiAgICAgICAgICAgICAgICAgICAgcmV0ID0gdHlwZXMuZXJhc3VyZShyZXQpOwogICAgICAgICAgICAgICAgICAgIHJlc3VsdEluZm8uY2hlY2soZW52LnRyZWUsIHJldCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgICAgICB9IGNhdGNoIChJbmZlcmVuY2VFeGNlcHRpb24gZXgpIHsKICAgICAgICAgICAgICAgIHJlc3VsdEluZm8uY2hlY2tDb250ZXh0LnJlcG9ydChudWxsLCBleC5nZXREaWFnbm9zdGljKCkpOwogICAgICAgICAgICAgICAgQXNzZXJ0LmVycm9yKCk7IC8vY2Fubm90IGdldCBoZXJlICh0aGUgYWJvdmUgc2hvdWxkIHRocm93KQogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgICAgICBpZiAoc2F2ZWRfdW5kZXQgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIGluZmVyZW5jZUNvbnRleHQucm9sbGJhY2soc2F2ZWRfdW5kZXQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgdm9pZCBkdW1wR3JhcGhzSWZOZWVkZWQoRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcywgU3ltYm9sIG1zeW0sIFJlc29sdmUuTWV0aG9kUmVzb2x1dGlvbkNvbnRleHQgcnNDb250ZXh0KSB7CiAgICAgICAgaW50IHJvdW5kID0gMDsKICAgICAgICB0cnkgewogICAgICAgICAgICBmb3IgKFN0cmluZyBncmFwaCA6IHBlbmRpbmdHcmFwaHMucmV2ZXJzZSgpKSB7CiAgICAgICAgICAgICAgICBBc3NlcnQuY2hlY2tOb25OdWxsKGRlcGVuZGVuY2llc0ZvbGRlcik7CiAgICAgICAgICAgICAgICBOYW1lIG5hbWUgPSBtc3ltLm5hbWUgPT0gbXN5bS5uYW1lLnRhYmxlLm5hbWVzLmluaXQgPwogICAgICAgICAgICAgICAgICAgICAgICBtc3ltLm93bmVyLm5hbWUgOiBtc3ltLm5hbWU7CiAgICAgICAgICAgICAgICBTdHJpbmcgZmlsZW5hbWUgPSBTdHJpbmcuZm9ybWF0KCIlc0Alc1ttb2RlPSVzLHN0ZXA9JXNdXyVkLmRvdCIsCiAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgIHBvcy5nZXRTdGFydFBvc2l0aW9uKCksCiAgICAgICAgICAgICAgICAgICAgICAgIHJzQ29udGV4dC5hdHRyTW9kZSgpLAogICAgICAgICAgICAgICAgICAgICAgICByc0NvbnRleHQuc3RlcCwKICAgICAgICAgICAgICAgICAgICAgICAgcm91bmQpOwogICAgICAgICAgICAgICAgUGF0aCBkb3RGaWxlID0gUGF0aHMuZ2V0KGRlcGVuZGVuY2llc0ZvbGRlciwgZmlsZW5hbWUpOwogICAgICAgICAgICAgICAgdHJ5IChXcml0ZXIgdyA9IEZpbGVzLm5ld0J1ZmZlcmVkV3JpdGVyKGRvdEZpbGUpKSB7CiAgICAgICAgICAgICAgICAgICAgdy5hcHBlbmQoZ3JhcGgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcm91bmQrKzsKICAgICAgICAgICAgfQogICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7CiAgICAgICAgICAgIEFzc2VydC5lcnJvcigiRXJyb3Igb2NjdXJyZWQgd2hlbiBkdW1waW5nIGluZmVyZW5jZSBncmFwaDogIiArIGV4LmdldE1lc3NhZ2UoKSk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgcGVuZGluZ0dyYXBocyA9IExpc3QubmlsKCk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogR2VuZXJhdGUgY29uc3RyYWludHMgZnJvbSB0aGUgZ2VuZXJpYyBtZXRob2QncyByZXR1cm4gdHlwZS4gSWYgdGhlIG1ldGhvZAogICAgICogY2FsbCBvY2N1cnMgaW4gYSBjb250ZXh0IHdoZXJlIGEgdHlwZSBUIGlzIGV4cGVjdGVkLCB1c2UgdGhlIGV4cGVjdGVkCiAgICAgKiB0eXBlIHRvIGRlcml2ZSBtb3JlIGNvbnN0cmFpbnRzIG9uIHRoZSBnZW5lcmljIG1ldGhvZCBpbmZlcmVuY2UgdmFyaWFibGVzLgogICAgICovCiAgICBUeXBlIGdlbmVyYXRlUmV0dXJuQ29uc3RyYWludHMoSkNUcmVlIHRyZWUsIEF0dHIuUmVzdWx0SW5mbyByZXN1bHRJbmZvLAogICAgICAgICAgICBNZXRob2RUeXBlIG10LCBJbmZlcmVuY2VDb250ZXh0IGluZmVyZW5jZUNvbnRleHQpIHsKICAgICAgICBJbmZlcmVuY2VDb250ZXh0IHJzSW5mb0luZkNvbnRleHQgPSByZXN1bHRJbmZvLmNoZWNrQ29udGV4dC5pbmZlcmVuY2VDb250ZXh0KCk7CiAgICAgICAgVHlwZSBmcm9tID0gbXQuZ2V0UmV0dXJuVHlwZSgpOwogICAgICAgIGlmIChtdC5nZXRSZXR1cm5UeXBlKCkuY29udGFpbnNBbnkoaW5mZXJlbmNlQ29udGV4dC5pbmZlcmVuY2V2YXJzKSAmJgogICAgICAgICAgICAgICAgcnNJbmZvSW5mQ29udGV4dCAhPSBlbXB0eUNvbnRleHQpIHsKICAgICAgICAgICAgZnJvbSA9IHR5cGVzLmNhcHR1cmUoZnJvbSk7CiAgICAgICAgICAgIC8vYWRkIHN5bnRoZXRpYyBjYXB0dXJlZCBpdmFycwogICAgICAgICAgICBmb3IgKFR5cGUgdCA6IGZyb20uZ2V0VHlwZUFyZ3VtZW50cygpKSB7CiAgICAgICAgICAgICAgICBpZiAodC5oYXNUYWcoVFlQRVZBUikgJiYgKChUeXBlVmFyKXQpLmlzQ2FwdHVyZWQoKSkgewogICAgICAgICAgICAgICAgICAgIGluZmVyZW5jZUNvbnRleHQuYWRkVmFyKChUeXBlVmFyKXQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIFR5cGUgcXR5cGUgPSBpbmZlcmVuY2VDb250ZXh0LmFzVW5kZXRWYXIoZnJvbSk7CiAgICAgICAgVHlwZSB0byA9IHJlc3VsdEluZm8ucHQ7CgogICAgICAgIGlmIChxdHlwZS5oYXNUYWcoVk9JRCkpIHsKICAgICAgICAgICAgdG8gPSBzeW1zLnZvaWRUeXBlOwogICAgICAgIH0gZWxzZSBpZiAodG8uaGFzVGFnKE5PTkUpKSB7CiAgICAgICAgICAgIHRvID0gZnJvbS5pc1ByaW1pdGl2ZSgpID8gZnJvbSA6IHN5bXMub2JqZWN0VHlwZTsKICAgICAgICB9IGVsc2UgaWYgKHF0eXBlLmhhc1RhZyhVTkRFVFZBUikpIHsKICAgICAgICAgICAgaWYgKG5lZWRzRWFnZXJJbnN0YW50aWF0aW9uKChVbmRldFZhcilxdHlwZSwgdG8sIGluZmVyZW5jZUNvbnRleHQpICYmCiAgICAgICAgICAgICAgICAgICAgKGFsbG93R3JhcGhJbmZlcmVuY2UgfHwgIXRvLmlzUHJpbWl0aXZlKCkpKSB7CiAgICAgICAgICAgICAgICB0byA9IGdlbmVyYXRlUmVmZXJlbmNlVG9UYXJnZXRDb25zdHJhaW50KHRyZWUsIChVbmRldFZhcilxdHlwZSwgdG8sIHJlc3VsdEluZm8sIGluZmVyZW5jZUNvbnRleHQpOwogICAgICAgICAgICB9IGVsc2UgaWYgKHRvLmlzUHJpbWl0aXZlKCkpIHsKICAgICAgICAgICAgICAgIHRvID0gdHlwZXMuYm94ZWRDbGFzcyh0bykudHlwZTsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSBpZiAocnNJbmZvSW5mQ29udGV4dC5mcmVlKHJlc3VsdEluZm8ucHQpKSB7CiAgICAgICAgICAgIC8vcHJvcGFnYXRpb24gLSBjYWNoZSBjYXB0dXJlZCB2YXJzCiAgICAgICAgICAgIHF0eXBlID0gaW5mZXJlbmNlQ29udGV4dC5hc1VuZGV0VmFyKHJzSW5mb0luZkNvbnRleHQuY2FjaGVkQ2FwdHVyZSh0cmVlLCBmcm9tLCBmYWxzZSkpOwogICAgICAgIH0KICAgICAgICBBc3NlcnQuY2hlY2soYWxsb3dHcmFwaEluZmVyZW5jZSB8fCAhcnNJbmZvSW5mQ29udGV4dC5mcmVlKHRvKSwKICAgICAgICAgICAgICAgICJsZWdhY3kgaW5mZXJlbmNlIGVuZ2luZSBjYW5ub3QgaGFuZGxlIGNvbnN0cmFpbnRzIG9uIGJvdGggc2lkZXMgb2YgYSBzdWJ0eXBpbmcgYXNzZXJ0aW9uIik7CiAgICAgICAgLy93ZSBuZWVkIHRvIHNraXAgY2FwdHVyZT8KICAgICAgICBXYXJuZXIgcmV0V2FybiA9IG5ldyBXYXJuZXIoKTsKICAgICAgICBpZiAoIXJlc3VsdEluZm8uY2hlY2tDb250ZXh0LmNvbXBhdGlibGUocXR5cGUsIHJzSW5mb0luZkNvbnRleHQuYXNVbmRldFZhcih0byksIHJldFdhcm4pIHx8CiAgICAgICAgICAgICAgICAvL3VuY2hlY2tlZCBjb252ZXJzaW9uIGlzIG5vdCBhbGxvd2VkIGluIHNvdXJjZSA3IG1vZGUKICAgICAgICAgICAgICAgICghYWxsb3dHcmFwaEluZmVyZW5jZSAmJiByZXRXYXJuLmhhc0xpbnQoTGludC5MaW50Q2F0ZWdvcnkuVU5DSEVDS0VEKSkpIHsKICAgICAgICAgICAgdGhyb3cgaW5mZXJlbmNlRXhjZXB0aW9uCiAgICAgICAgICAgICAgICAgICAgLnNldE1lc3NhZ2UoImluZmVyLm5vLmNvbmZvcm1pbmcuaW5zdGFuY2UuZXhpc3RzIiwKICAgICAgICAgICAgICAgICAgICBpbmZlcmVuY2VDb250ZXh0LnJlc3R2YXJzKCksIG10LmdldFJldHVyblR5cGUoKSwgdG8pOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZnJvbTsKICAgIH0KCiAgICBwcml2YXRlIGJvb2xlYW4gbmVlZHNFYWdlckluc3RhbnRpYXRpb24oVW5kZXRWYXIgZnJvbSwgVHlwZSB0bywgSW5mZXJlbmNlQ29udGV4dCBpbmZlcmVuY2VDb250ZXh0KSB7CiAgICAgICAgaWYgKHRvLmlzUHJpbWl0aXZlKCkpIHsKICAgICAgICAgICAgLyogVCBpcyBhIHByaW1pdGl2ZSB0eXBlLCBhbmQgb25lIG9mIHRoZSBwcmltaXRpdmUgd3JhcHBlciBjbGFzc2VzIGlzIGFuIGluc3RhbnRpYXRpb24sCiAgICAgICAgICAgICAqIHVwcGVyIGJvdW5kLCBvciBsb3dlciBib3VuZCBmb3IgYWxwaGEgaW4gQjIuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBmb3IgKFR5cGUgdCA6IGZyb20uZ2V0Qm91bmRzKEluZmVyZW5jZUJvdW5kLnZhbHVlcygpKSkgewogICAgICAgICAgICAgICAgVHlwZSBib3VuZEFzUHJpbWl0aXZlID0gdHlwZXMudW5ib3hlZFR5cGUodCk7CiAgICAgICAgICAgICAgICBpZiAoYm91bmRBc1ByaW1pdGl2ZSA9PSBudWxsIHx8IGJvdW5kQXNQcmltaXRpdmUuaGFzVGFnKE5PTkUpKSB7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICBUeXBlIGNhcHR1cmVPZlRvID0gdHlwZXMuY2FwdHVyZSh0byk7CiAgICAgICAgLyogVCBpcyBhIHJlZmVyZW5jZSB0eXBlLCBidXQgaXMgbm90IGEgd2lsZGNhcmQtcGFyYW1ldGVyaXplZCB0eXBlLCBhbmQgZWl0aGVyCiAgICAgICAgICovCiAgICAgICAgaWYgKGNhcHR1cmVPZlRvID09IHRvKSB7IC8vbm90IGEgd2lsZGNhcmQgcGFyYW1ldGVyaXplZCB0eXBlCiAgICAgICAgICAgIC8qIGkpIEIyIGNvbnRhaW5zIGEgYm91bmQgb2Ygb25lIG9mIHRoZSBmb3JtcyBhbHBoYSA9IFMgb3IgUyA8OiBhbHBoYSwKICAgICAgICAgICAgICogICAgICB3aGVyZSBTIGlzIGEgd2lsZGNhcmQtcGFyYW1ldGVyaXplZCB0eXBlLCBvcgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgZm9yIChUeXBlIHQgOiBmcm9tLmdldEJvdW5kcyhJbmZlcmVuY2VCb3VuZC5FUSwgSW5mZXJlbmNlQm91bmQuTE9XRVIpKSB7CiAgICAgICAgICAgICAgICBUeXBlIGNhcHR1cmVPZkJvdW5kID0gdHlwZXMuY2FwdHVyZSh0KTsKICAgICAgICAgICAgICAgIGlmIChjYXB0dXJlT2ZCb3VuZCAhPSB0KSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qIGlpKSBCMiBjb250YWlucyB0d28gYm91bmRzIG9mIHRoZSBmb3JtcyBTMSA8OiBhbHBoYSBhbmQgUzIgPDogYWxwaGEsCiAgICAgICAgICAgICAqIHdoZXJlIFMxIGFuZCBTMiBoYXZlIHN1cGVydHlwZXMgdGhhdCBhcmUgdHdvIGRpZmZlcmVudAogICAgICAgICAgICAgKiBwYXJhbWV0ZXJpemF0aW9ucyBvZiB0aGUgc2FtZSBnZW5lcmljIGNsYXNzIG9yIGludGVyZmFjZS4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIGZvciAoVHlwZSBhTG93ZXJCb3VuZCA6IGZyb20uZ2V0Qm91bmRzKEluZmVyZW5jZUJvdW5kLkxPV0VSKSkgewogICAgICAgICAgICAgICAgZm9yIChUeXBlIGFub3RoZXJMb3dlckJvdW5kIDogZnJvbS5nZXRCb3VuZHMoSW5mZXJlbmNlQm91bmQuTE9XRVIpKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGFMb3dlckJvdW5kICE9IGFub3RoZXJMb3dlckJvdW5kICYmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAhaW5mZXJlbmNlQ29udGV4dC5mcmVlKGFMb3dlckJvdW5kKSAmJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgIWluZmVyZW5jZUNvbnRleHQuZnJlZShhbm90aGVyTG93ZXJCb3VuZCkgJiYKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbW1vblN1cGVyV2l0aERpZmZQYXJhbWV0ZXJpemF0aW9uKGFMb3dlckJvdW5kLCBhbm90aGVyTG93ZXJCb3VuZCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvKiBUIGlzIGEgcGFyYW1ldGVyaXphdGlvbiBvZiBhIGdlbmVyaWMgY2xhc3Mgb3IgaW50ZXJmYWNlLCBHLAogICAgICAgICAqIGFuZCBCMiBjb250YWlucyBhIGJvdW5kIG9mIG9uZSBvZiB0aGUgZm9ybXMgYWxwaGEgPSBTIG9yIFMgPDogYWxwaGEsCiAgICAgICAgICogd2hlcmUgdGhlcmUgZXhpc3RzIG5vIHR5cGUgb2YgdGhlIGZvcm0gRzwuLi4+IHRoYXQgaXMgYQogICAgICAgICAqIHN1cGVydHlwZSBvZiBTLCBidXQgdGhlIHJhdyB0eXBlIEcgaXMgYSBzdXBlcnR5cGUgb2YgUwogICAgICAgICAqLwogICAgICAgIGlmICh0by5pc1BhcmFtZXRlcml6ZWQoKSkgewogICAgICAgICAgICBmb3IgKFR5cGUgdCA6IGZyb20uZ2V0Qm91bmRzKEluZmVyZW5jZUJvdW5kLkVRLCBJbmZlcmVuY2VCb3VuZC5MT1dFUikpIHsKICAgICAgICAgICAgICAgIFR5cGUgc3VwID0gdHlwZXMuYXNTdXBlcih0LCB0by50c3ltKTsKICAgICAgICAgICAgICAgIGlmIChzdXAgIT0gbnVsbCAmJiBzdXAuaXNSYXcoKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICBwcml2YXRlIGJvb2xlYW4gY29tbW9uU3VwZXJXaXRoRGlmZlBhcmFtZXRlcml6YXRpb24oVHlwZSB0LCBUeXBlIHMpIHsKICAgICAgICBmb3IgKFBhaXI8VHlwZSwgVHlwZT4gc3VwZXJzIDogZ2V0UGFyYW1ldGVyaXplZFN1cGVycyh0LCBzKSkgewogICAgICAgICAgICBpZiAoIXR5cGVzLmlzU2FtZVR5cGUoc3VwZXJzLmZzdCwgc3VwZXJzLnNuZCkpIHJldHVybiB0cnVlOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgcHJpdmF0ZSBUeXBlIGdlbmVyYXRlUmVmZXJlbmNlVG9UYXJnZXRDb25zdHJhaW50KEpDVHJlZSB0cmVlLCBVbmRldFZhciBmcm9tLAogICAgICAgICAgICBUeXBlIHRvLCBBdHRyLlJlc3VsdEluZm8gcmVzdWx0SW5mbywKICAgICAgICAgICAgSW5mZXJlbmNlQ29udGV4dCBpbmZlcmVuY2VDb250ZXh0KSB7CiAgICAgICAgaW5mZXJlbmNlQ29udGV4dC5zb2x2ZShMaXN0Lm9mKGZyb20ucXR5cGUpLCBuZXcgV2FybmVyKCkpOwogICAgICAgIGluZmVyZW5jZUNvbnRleHQubm90aWZ5Q2hhbmdlKCk7CiAgICAgICAgVHlwZSBjYXB0dXJlZFR5cGUgPSByZXN1bHRJbmZvLmNoZWNrQ29udGV4dC5pbmZlcmVuY2VDb250ZXh0KCkKICAgICAgICAgICAgICAgIC5jYWNoZWRDYXB0dXJlKHRyZWUsIGZyb20uZ2V0SW5zdCgpLCBmYWxzZSk7CiAgICAgICAgaWYgKHR5cGVzLmlzQ29udmVydGlibGUoY2FwdHVyZWRUeXBlLAogICAgICAgICAgICAgICAgcmVzdWx0SW5mby5jaGVja0NvbnRleHQuaW5mZXJlbmNlQ29udGV4dCgpLmFzVW5kZXRWYXIodG8pKSkgewogICAgICAgICAgICAvL2VmZmVjdGl2ZWx5IHNraXAgYWRkaXRpb25hbCByZXR1cm4tdHlwZSBjb25zdHJhaW50IGdlbmVyYXRpb24gKGNvbXBhdGliaWxpdHkpCiAgICAgICAgICAgIHJldHVybiBzeW1zLm9iamVjdFR5cGU7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0bzsKICAgIH0KCiAgICAvKioKICAgICAgKiBJbmZlciBjeWNsaWMgaW5mZXJlbmNlIHZhcmlhYmxlcyBhcyBkZXNjcmliZWQgaW4gMTUuMTIuMi44LgogICAgICAqLwogICAgdm9pZCBpbnN0YW50aWF0ZUFzVW5pbmZlcnJlZFZhcnMoTGlzdDxUeXBlPiB2YXJzLCBJbmZlcmVuY2VDb250ZXh0IGluZmVyZW5jZUNvbnRleHQpIHsKICAgICAgICBMaXN0QnVmZmVyPFR5cGU+IHRvZG8gPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgLy9zdGVwIDEgLSBjcmVhdGUgZnJlc2ggdHZhcnMKICAgICAgICBmb3IgKFR5cGUgdCA6IHZhcnMpIHsKICAgICAgICAgICAgVW5kZXRWYXIgdXYgPSAoVW5kZXRWYXIpaW5mZXJlbmNlQ29udGV4dC5hc1VuZGV0VmFyKHQpOwogICAgICAgICAgICBMaXN0PFR5cGU+IHVwcGVyQm91bmRzID0gdXYuZ2V0Qm91bmRzKEluZmVyZW5jZUJvdW5kLlVQUEVSKTsKICAgICAgICAgICAgaWYgKFR5cGUuY29udGFpbnNBbnkodXBwZXJCb3VuZHMsIHZhcnMpKSB7CiAgICAgICAgICAgICAgICBUeXBlU3ltYm9sIGZyZXNoX3R2YXIgPSBuZXcgVHlwZVZhcmlhYmxlU3ltYm9sKEZsYWdzLlNZTlRIRVRJQywgdXYucXR5cGUudHN5bS5uYW1lLCBudWxsLCB1di5xdHlwZS50c3ltLm93bmVyKTsKICAgICAgICAgICAgICAgIGZyZXNoX3R2YXIudHlwZSA9IG5ldyBUeXBlVmFyKGZyZXNoX3R2YXIsIHR5cGVzLm1ha2VJbnRlcnNlY3Rpb25UeXBlKHV2LmdldEJvdW5kcyhJbmZlcmVuY2VCb3VuZC5VUFBFUikpLCBudWxsKTsKICAgICAgICAgICAgICAgIHRvZG8uYXBwZW5kKHV2KTsKICAgICAgICAgICAgICAgIHV2LnNldEluc3QoZnJlc2hfdHZhci50eXBlKTsKICAgICAgICAgICAgfSBlbHNlIGlmICh1cHBlckJvdW5kcy5ub25FbXB0eSgpKSB7CiAgICAgICAgICAgICAgICB1di5zZXRJbnN0KHR5cGVzLmdsYih1cHBlckJvdW5kcykpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdXYuc2V0SW5zdChzeW1zLm9iamVjdFR5cGUpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8vc3RlcCAyIC0gcmVwbGFjZSBmcmVzaCB0dmFycyBpbiB0aGVpciBib3VuZHMKICAgICAgICBMaXN0PFR5cGU+IGZvcm1hbHMgPSB2YXJzOwogICAgICAgIGZvciAoVHlwZSB0IDogdG9kbykgewogICAgICAgICAgICBVbmRldFZhciB1diA9IChVbmRldFZhcil0OwogICAgICAgICAgICBUeXBlVmFyIGN0ID0gKFR5cGVWYXIpdXYuZ2V0SW5zdCgpOwogICAgICAgICAgICBjdC5ib3VuZCA9IHR5cGVzLmdsYihpbmZlcmVuY2VDb250ZXh0LmFzSW5zdFR5cGVzKHR5cGVzLmdldEJvdW5kcyhjdCkpKTsKICAgICAgICAgICAgaWYgKGN0LmJvdW5kLmlzRXJyb25lb3VzKCkpIHsKICAgICAgICAgICAgICAgIC8vcmVwb3J0IGluZmVyZW5jZSBlcnJvciBpZiBnbGIgZmFpbHMKICAgICAgICAgICAgICAgIHJlcG9ydEJvdW5kRXJyb3IodXYsIEluZmVyZW5jZUJvdW5kLlVQUEVSKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBmb3JtYWxzID0gZm9ybWFscy50YWlsOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIENvbXB1dGUgYSBzeW50aGV0aWMgbWV0aG9kIHR5cGUgY29ycmVzcG9uZGluZyB0byB0aGUgcmVxdWVzdGVkIHBvbHltb3JwaGljCiAgICAgKiBtZXRob2Qgc2lnbmF0dXJlLiBUaGUgdGFyZ2V0IHJldHVybiB0eXBlIGlzIGNvbXB1dGVkIGZyb20gdGhlIGltbWVkaWF0ZWx5CiAgICAgKiBlbmNsb3Npbmcgc2NvcGUgc3Vycm91bmRpbmcgdGhlIHBvbHltb3JwaGljLXNpZ25hdHVyZSBjYWxsLgogICAgICovCiAgICBUeXBlIGluc3RhbnRpYXRlUG9seW1vcnBoaWNTaWduYXR1cmVJbnN0YW5jZShFbnY8QXR0ckNvbnRleHQ+IGVudiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXRob2RTeW1ib2wgc3BNZXRob2QsICAvLyBzaWcuIHBvbHkuIG1ldGhvZCBvciBudWxsIGlmIG5vbmUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZXNvbHZlLk1ldGhvZFJlc29sdXRpb25Db250ZXh0IHJlc29sdmVDb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExpc3Q8VHlwZT4gYXJndHlwZXMpIHsKICAgICAgICBmaW5hbCBUeXBlIHJlc3R5cGU7CgogICAgICAgIGlmIChzcE1ldGhvZCA9PSBudWxsIHx8IHR5cGVzLmlzU2FtZVR5cGUoc3BNZXRob2QuZ2V0UmV0dXJuVHlwZSgpLCBzeW1zLm9iamVjdFR5cGUsIHRydWUpKSB7CiAgICAgICAgICAgIC8vIFRoZSByZXR1cm4gdHlwZSBvZiB0aGUgcG9seW1vcnBoaWMgc2lnbmF0dXJlIGlzIHBvbHltb3JwaGljLAogICAgICAgICAgICAvLyBhbmQgaXMgY29tcHV0ZWQgZnJvbSB0aGUgZW5jbG9zaW5nIHRyZWUgRSwgYXMgZm9sbG93czoKICAgICAgICAgICAgLy8gaWYgRSBpcyBhIGNhc3QsIHRoZW4gdXNlIHRoZSB0YXJnZXQgdHlwZSBvZiB0aGUgY2FzdCBleHByZXNzaW9uCiAgICAgICAgICAgIC8vIGFzIGEgcmV0dXJuIHR5cGU7IGlmIEUgaXMgYW4gZXhwcmVzc2lvbiBzdGF0ZW1lbnQsIHRoZSByZXR1cm4KICAgICAgICAgICAgLy8gdHlwZSBpcyAndm9pZCc7IG90aGVyd2lzZQogICAgICAgICAgICAvLyB0aGUgcmV0dXJuIHR5cGUgaXMgc2ltcGx5ICdPYmplY3QnLiBBIGNvcnJlY3RuZXNzIGNoZWNrIGVuc3VyZXMKICAgICAgICAgICAgLy8gdGhhdCBlbnYubmV4dCByZWZlcnMgdG8gdGhlIGxleGljYWxseSBlbmNsb3NpbmcgZW52aXJvbm1lbnQgaW4KICAgICAgICAgICAgLy8gd2hpY2ggdGhlIHBvbHltb3JwaGljIHNpZ25hdHVyZSBjYWxsIGVudmlyb25tZW50IGlzIG5lc3RlZC4KCiAgICAgICAgICAgIHN3aXRjaCAoZW52Lm5leHQudHJlZS5nZXRUYWcoKSkgewogICAgICAgICAgICAgICAgY2FzZSBUWVBFQ0FTVDoKICAgICAgICAgICAgICAgICAgICBKQ1R5cGVDYXN0IGNhc3RUcmVlID0gKEpDVHlwZUNhc3QpZW52Lm5leHQudHJlZTsKICAgICAgICAgICAgICAgICAgICByZXN0eXBlID0gKFRyZWVJbmZvLnNraXBQYXJlbnMoY2FzdFRyZWUuZXhwcikgPT0gZW52LnRyZWUpID8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzdFRyZWUuY2xhenoudHlwZSA6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5bXMub2JqZWN0VHlwZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgRVhFQzoKICAgICAgICAgICAgICAgICAgICBKQ1RyZWUuSkNFeHByZXNzaW9uU3RhdGVtZW50IGV4ZWNUcmVlID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIChKQ1RyZWUuSkNFeHByZXNzaW9uU3RhdGVtZW50KWVudi5uZXh0LnRyZWU7CiAgICAgICAgICAgICAgICAgICAgcmVzdHlwZSA9IChUcmVlSW5mby5za2lwUGFyZW5zKGV4ZWNUcmVlLmV4cHIpID09IGVudi50cmVlKSA/CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5bXMudm9pZFR5cGUgOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeW1zLm9iamVjdFR5cGU7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgIHJlc3R5cGUgPSBzeW1zLm9iamVjdFR5cGU7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvLyBUaGUgcmV0dXJuIHR5cGUgb2YgdGhlIHBvbHltb3JwaGljIHNpZ25hdHVyZSBpcyBmaXhlZAogICAgICAgICAgICAvLyAobm90IHBvbHltb3JwaGljKQogICAgICAgICAgICByZXN0eXBlID0gc3BNZXRob2QuZ2V0UmV0dXJuVHlwZSgpOwogICAgICAgIH0KCiAgICAgICAgTGlzdDxUeXBlPiBwYXJhbXR5cGVzID0gYXJndHlwZXMubWFwKG5ldyBJbXBsaWNpdEFyZ1R5cGUoc3BNZXRob2QsIHJlc29sdmVDb250ZXh0LnN0ZXApKTsKICAgICAgICBMaXN0PFR5cGU+IGV4VHlwZSA9IHNwTWV0aG9kICE9IG51bGwgPwogICAgICAgICAgICBzcE1ldGhvZC5nZXRUaHJvd25UeXBlcygpIDoKICAgICAgICAgICAgTGlzdC5vZihzeW1zLnRocm93YWJsZVR5cGUpOyAvLyBtYWtlIGl0IHRocm93IGFsbCBleGNlcHRpb25zCgogICAgICAgIE1ldGhvZFR5cGUgbXR5cGUgPSBuZXcgTWV0aG9kVHlwZShwYXJhbXR5cGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN0eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleFR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5bXMubWV0aG9kQ2xhc3MpOwogICAgICAgIHJldHVybiBtdHlwZTsKICAgIH0KICAgIC8vd2hlcmUKICAgICAgICBjbGFzcyBJbXBsaWNpdEFyZ1R5cGUgZXh0ZW5kcyBEZWZlcnJlZEF0dHIuRGVmZXJyZWRUeXBlTWFwIHsKCiAgICAgICAgICAgIHB1YmxpYyBJbXBsaWNpdEFyZ1R5cGUoU3ltYm9sIG1zeW0sIFJlc29sdmUuTWV0aG9kUmVzb2x1dGlvblBoYXNlIHBoYXNlKSB7CiAgICAgICAgICAgICAgICAocnMuZGVmZXJyZWRBdHRyKS5zdXBlcihBdHRyTW9kZS5TUEVDVUxBVElWRSwgbXN5bSwgcGhhc2UpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHVibGljIFR5cGUgdmlzaXRDbGFzc1R5cGUoQ2xhc3NUeXBlIHQsIFZvaWQgYVZvaWQpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0eXBlcy5lcmFzdXJlKHQpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHVibGljIFR5cGUgdmlzaXRUeXBlKFR5cGUgdCwgVm9pZCBfdW51c2VkKSB7CiAgICAgICAgICAgICAgICBpZiAodC5oYXNUYWcoREVGRVJSRUQpKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZpc2l0KHN1cGVyLnZpc2l0VHlwZSh0LCBudWxsKSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHQuaGFzVGFnKEJPVCkpCiAgICAgICAgICAgICAgICAgICAgLy8gbnVsbHMgdHlwZSBhcyB0aGUgbWFya2VyIHR5cGUgTnVsbCAod2hpY2ggaGFzIG5vIGluc3RhbmNlcykKICAgICAgICAgICAgICAgICAgICAvLyBpbmZlciBhcyBqYXZhLmxhbmcuVm9pZCBmb3Igbm93CiAgICAgICAgICAgICAgICAgICAgdCA9IHR5cGVzLmJveGVkQ2xhc3Moc3ltcy52b2lkVHlwZSkudHlwZTsKICAgICAgICAgICAgICAgIHJldHVybiB0OwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgIFR5cGVNYXBwaW5nPFZvaWQ+IGZyb21UeXBlVmFyRnVuID0gbmV3IFN0cnVjdHVyYWxUeXBlTWFwcGluZzxWb2lkPigpIHsKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgVHlwZSB2aXNpdFR5cGVWYXIoVHlwZVZhciB0diwgVm9pZCBhVm9pZCkgewogICAgICAgICAgICBVbmRldFZhciB1diA9IG5ldyBVbmRldFZhcih0diwgaW5jb3Jwb3JhdGlvbkVuZ2luZSgpLCB0eXBlcyk7CiAgICAgICAgICAgIGlmICgodHYudHN5bS5mbGFncygpICYgRmxhZ3MuVEhST1dTKSAhPSAwKSB7CiAgICAgICAgICAgICAgICB1di5zZXRUaHJvdygpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiB1djsKICAgICAgICB9CiAgICB9OwoKICAgIC8qKgogICAgICAqIFRoaXMgbWV0aG9kIGlzIHVzZWQgdG8gaW5mZXIgYSBzdWl0YWJsZSB0YXJnZXQgU0FNIGluIGNhc2UgdGhlIG9yaWdpbmFsCiAgICAgICogU0FNIHR5cGUgY29udGFpbnMgb25lIG9yIG1vcmUgd2lsZGNhcmRzLiBBbiBpbmZlcmVuY2UgcHJvY2VzcyBpcyBhcHBsaWVkCiAgICAgICogc28gdGhhdCB3aWxkY2FyZCBib3VuZHMsIGFzIHdlbGwgYXMgZXhwbGljaXQgbGFtYmRhL21ldGhvZCByZWYgcGFyYW1ldGVycwogICAgICAqICh3aGVyZSBhcHBsaWNhYmxlKSBhcmUgdXNlZCB0byBjb25zdHJhaW50IHRoZSBzb2x1dGlvbi4KICAgICAgKi8KICAgIHB1YmxpYyBUeXBlIGluc3RhbnRpYXRlRnVuY3Rpb25hbEludGVyZmFjZShEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBUeXBlIGZ1bmNJbnRlcmZhY2UsCiAgICAgICAgICAgIExpc3Q8VHlwZT4gcGFyYW1UeXBlcywgQ2hlY2suQ2hlY2tDb250ZXh0IGNoZWNrQ29udGV4dCkgewogICAgICAgIGlmICh0eXBlcy5jYXB0dXJlKGZ1bmNJbnRlcmZhY2UpID09IGZ1bmNJbnRlcmZhY2UpIHsKICAgICAgICAgICAgLy9pZiBjYXB0dXJlIGRvZXNuJ3QgY2hhbmdlIHRoZSB0eXBlIHRoZW4gcmV0dXJuIHRoZSB0YXJnZXQgdW5jaGFuZ2VkCiAgICAgICAgICAgIC8vKHRoaXMgbWVhbnMgdGhlIHRhcmdldCBjb250YWlucyBubyB3aWxkY2FyZHMhKQogICAgICAgICAgICByZXR1cm4gZnVuY0ludGVyZmFjZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBUeXBlIGZvcm1hbEludGVyZmFjZSA9IGZ1bmNJbnRlcmZhY2UudHN5bS50eXBlOwogICAgICAgICAgICBJbmZlcmVuY2VDb250ZXh0IGZ1bmNJbnRlcmZhY2VDb250ZXh0ID0KICAgICAgICAgICAgICAgICAgICBuZXcgSW5mZXJlbmNlQ29udGV4dCh0aGlzLCBmdW5jSW50ZXJmYWNlLnRzeW0udHlwZS5nZXRUeXBlQXJndW1lbnRzKCkpOwoKICAgICAgICAgICAgQXNzZXJ0LmNoZWNrKHBhcmFtVHlwZXMgIT0gbnVsbCk7CiAgICAgICAgICAgIC8vZ2V0IGNvbnN0cmFpbnRzIGZyb20gZXhwbGljaXQgcGFyYW1zICh0aGlzIGlzIGRvbmUgYnkKICAgICAgICAgICAgLy9jaGVja2luZyB0aGF0IGV4cGxpY2l0IHBhcmFtIHR5cGVzIGFyZSBlcXVhbCB0byB0aGUgb25lcwogICAgICAgICAgICAvL2luIHRoZSBmdW5jdGlvbmFsIGludGVyZmFjZSBkZXNjcmlwdG9ycykKICAgICAgICAgICAgTGlzdDxUeXBlPiBkZXNjUGFyYW1ldGVyVHlwZXMgPSB0eXBlcy5maW5kRGVzY3JpcHRvclR5cGUoZm9ybWFsSW50ZXJmYWNlKS5nZXRQYXJhbWV0ZXJUeXBlcygpOwogICAgICAgICAgICBpZiAoZGVzY1BhcmFtZXRlclR5cGVzLnNpemUoKSAhPSBwYXJhbVR5cGVzLnNpemUoKSkgewogICAgICAgICAgICAgICAgY2hlY2tDb250ZXh0LnJlcG9ydChwb3MsIGRpYWdzLmZyYWdtZW50KCJpbmNvbXBhdGlibGUuYXJnLnR5cGVzLmluLmxhbWJkYSIpKTsKICAgICAgICAgICAgICAgIHJldHVybiB0eXBlcy5jcmVhdGVFcnJvclR5cGUoZnVuY0ludGVyZmFjZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZm9yIChUeXBlIHAgOiBkZXNjUGFyYW1ldGVyVHlwZXMpIHsKICAgICAgICAgICAgICAgIGlmICghdHlwZXMuaXNTYW1lVHlwZShmdW5jSW50ZXJmYWNlQ29udGV4dC5hc1VuZGV0VmFyKHApLCBwYXJhbVR5cGVzLmhlYWQpKSB7CiAgICAgICAgICAgICAgICAgICAgY2hlY2tDb250ZXh0LnJlcG9ydChwb3MsIGRpYWdzLmZyYWdtZW50KCJuby5zdWl0YWJsZS5mdW5jdGlvbmFsLmludGYuaW5zdCIsIGZ1bmNJbnRlcmZhY2UpKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHlwZXMuY3JlYXRlRXJyb3JUeXBlKGZ1bmNJbnRlcmZhY2UpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcGFyYW1UeXBlcyA9IHBhcmFtVHlwZXMudGFpbDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgTGlzdDxUeXBlPiBhY3R1YWxUeXBlYXJncyA9IGZ1bmNJbnRlcmZhY2UuZ2V0VHlwZUFyZ3VtZW50cygpOwogICAgICAgICAgICBmb3IgKFR5cGUgdCA6IGZ1bmNJbnRlcmZhY2VDb250ZXh0LnVuZGV0dmFycykgewogICAgICAgICAgICAgICAgVW5kZXRWYXIgdXYgPSAoVW5kZXRWYXIpdDsKICAgICAgICAgICAgICAgIE9wdGlvbmFsPFR5cGU+IGluc3QgPSB1di5nZXRCb3VuZHMoSW5mZXJlbmNlQm91bmQuRVEpLnN0cmVhbSgpCiAgICAgICAgICAgICAgICAgICAgICAgIC5maWx0ZXIoYiAtPiAhYi5jb250YWluc0FueShmb3JtYWxJbnRlcmZhY2UuZ2V0VHlwZUFyZ3VtZW50cygpKSkuZmluZEZpcnN0KCk7CiAgICAgICAgICAgICAgICB1di5zZXRJbnN0KGluc3Qub3JFbHNlKGFjdHVhbFR5cGVhcmdzLmhlYWQpKTsKICAgICAgICAgICAgICAgIGFjdHVhbFR5cGVhcmdzID0gYWN0dWFsVHlwZWFyZ3MudGFpbDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgVHlwZSBvd250eXBlID0gZnVuY0ludGVyZmFjZUNvbnRleHQuYXNJbnN0VHlwZShmb3JtYWxJbnRlcmZhY2UpOwogICAgICAgICAgICBpZiAoIWNoay5jaGVja1ZhbGlkR2VuZXJpY1R5cGUob3dudHlwZSkpIHsKICAgICAgICAgICAgICAgIC8vaWYgdGhlIGluZmVycmVkIGZ1bmN0aW9uYWwgaW50ZXJmYWNlIHR5cGUgaXMgbm90IHdlbGwtZm9ybWVkLAogICAgICAgICAgICAgICAgLy9vciBpZiBpdCdzIG5vdCBhIHN1YnR5cGUgb2YgdGhlIG9yaWdpbmFsIHRhcmdldCwgaXNzdWUgYW4gZXJyb3IKICAgICAgICAgICAgICAgIGNoZWNrQ29udGV4dC5yZXBvcnQocG9zLCBkaWFncy5mcmFnbWVudCgibm8uc3VpdGFibGUuZnVuY3Rpb25hbC5pbnRmLmluc3QiLCBmdW5jSW50ZXJmYWNlKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy9wcm9wYWdhdGUgY29uc3RyYWludHMgYXMgcGVyIEpMUyAxOC4yLjEKICAgICAgICAgICAgY2hlY2tDb250ZXh0LmNvbXBhdGlibGUob3dudHlwZSwgZnVuY0ludGVyZmFjZSwgdHlwZXMubm9XYXJuaW5ncyk7CiAgICAgICAgICAgIHJldHVybiBvd250eXBlOwogICAgICAgIH0KICAgIH0KICAgIC8vIDwvZWRpdG9yLWZvbGQ+CgogICAgLy8gPGVkaXRvci1mb2xkIGRlZmF1bHRzdGF0ZT0iY29sbGFwc2VkIiBkZXNjPSJJbmNvcnBvcmF0aW9uIj4KCiAgICAvKioKICAgICAqIFRoaXMgY2xhc3MgaXMgdGhlIHJvb3Qgb2YgYWxsIGluY29ycG9yYXRpb24gYWN0aW9ucy4KICAgICAqLwogICAgcHVibGljIGFic3RyYWN0IGNsYXNzIEluY29ycG9yYXRpb25BY3Rpb24gewogICAgICAgIFVuZGV0VmFyIHV2OwogICAgICAgIFR5cGUgdDsKCiAgICAgICAgSW5jb3Jwb3JhdGlvbkFjdGlvbihVbmRldFZhciB1diwgVHlwZSB0KSB7CiAgICAgICAgICAgIHRoaXMudXYgPSB1djsKICAgICAgICAgICAgdGhpcy50ID0gdDsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBhYnN0cmFjdCBJbmNvcnBvcmF0aW9uQWN0aW9uIGR1cChVbmRldFZhciB0aGF0KTsKCiAgICAgICAgLyoqCiAgICAgICAgICogSW5jb3Jwb3JhdGlvbiBhY3Rpb24gZW50cnktcG9pbnQuIFN1YmNsYXNzZXMgc2hvdWxkIGRlZmluZSB0aGUgbG9naWMgYXNzb2NpYXRlZCB3aXRoCiAgICAgICAgICogdGhpcyBpbmNvcnBvcmF0aW9uIGFjdGlvbi4KICAgICAgICAgKi8KICAgICAgICBhYnN0cmFjdCB2b2lkIGFwcGx5KEluZmVyZW5jZUNvbnRleHQgaWMsIFdhcm5lciB3YXJuKTsKCiAgICAgICAgLyoqCiAgICAgICAgICogSGVscGVyIGZ1bmN0aW9uOiBwZXJmb3JtIHN1YnR5cGluZyB0aHJvdWdoIGluY29ycG9yYXRpb24gY2FjaGUuCiAgICAgICAgICovCiAgICAgICAgYm9vbGVhbiBpc1N1YnR5cGUoVHlwZSBzLCBUeXBlIHQsIFdhcm5lciB3YXJuKSB7CiAgICAgICAgICAgIHJldHVybiBkb0luY29ycG9yYXRpb25PcChJbmNvcnBvcmF0aW9uQmluYXJ5T3BLaW5kLklTX1NVQlRZUEUsIHMsIHQsIHdhcm4pOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogSGVscGVyIGZ1bmN0aW9uOiBwZXJmb3JtIHR5cGUtZXF1aXZhbGVuY2UgdGhyb3VnaCBpbmNvcnBvcmF0aW9uIGNhY2hlLgogICAgICAgICAqLwogICAgICAgIGJvb2xlYW4gaXNTYW1lVHlwZShUeXBlIHMsIFR5cGUgdCkgewogICAgICAgICAgICByZXR1cm4gZG9JbmNvcnBvcmF0aW9uT3AoSW5jb3Jwb3JhdGlvbkJpbmFyeU9wS2luZC5JU19TQU1FX1RZUEUsIHMsIHQsIG51bGwpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKICAgICAgICAgICAgcmV0dXJuIFN0cmluZy5mb3JtYXQoIiVzW3VuZGV0PSVzLHQ9JXNdIiwgZ2V0Q2xhc3MoKS5nZXRTaW1wbGVOYW1lKCksIHV2LnF0eXBlLCB0KTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBCb3VuZC1jaGVjayBpbmNvcnBvcmF0aW9uIGFjdGlvbi4gQSBuZXdseSBhZGRlZCBib3VuZCBpcyBjaGVja2VkIGFnYWluc3QgZXhpc3RpbmcgYm91bmRzLAogICAgICogdG8gdmVyaWZ5IGl0cyBjb21wYXRpYmlsaXR5OyBlYWNoIGJvdW5kIGlzIGNoZWNrZWQgdXNpbmcgZWl0aGVyIHN1YnR5cGluZyBvciB0eXBlIGVxdWl2YWxlbmNlLgogICAgICovCiAgICBjbGFzcyBDaGVja0JvdW5kcyBleHRlbmRzIEluY29ycG9yYXRpb25BY3Rpb24gewoKICAgICAgICBJbmZlcmVuY2VCb3VuZCBmcm9tOwogICAgICAgIEJpRnVuY3Rpb248SW5mZXJlbmNlQ29udGV4dCwgVHlwZSwgVHlwZT4gdHlwZUZ1bmM7CiAgICAgICAgQmlQcmVkaWNhdGU8SW5mZXJlbmNlQ29udGV4dCwgVHlwZT4gb3B0RmlsdGVyOwoKICAgICAgICBDaGVja0JvdW5kcyhVbmRldFZhciB1diwgVHlwZSB0LCBJbmZlcmVuY2VCb3VuZCBmcm9tKSB7CiAgICAgICAgICAgIHRoaXModXYsIHQsIEluZmVyZW5jZUNvbnRleHQ6OmFzVW5kZXRWYXIsIG51bGwsIGZyb20pOwogICAgICAgIH0KCiAgICAgICAgQ2hlY2tCb3VuZHMoVW5kZXRWYXIgdXYsIFR5cGUgdCwgQmlGdW5jdGlvbjxJbmZlcmVuY2VDb250ZXh0LCBUeXBlLCBUeXBlPiB0eXBlRnVuYywKICAgICAgICAgICAgICAgICAgICBCaVByZWRpY2F0ZTxJbmZlcmVuY2VDb250ZXh0LCBUeXBlPiB0eXBlRmlsdGVyLCBJbmZlcmVuY2VCb3VuZCBmcm9tKSB7CiAgICAgICAgICAgIHN1cGVyKHV2LCB0KTsKICAgICAgICAgICAgdGhpcy5mcm9tID0gZnJvbTsKICAgICAgICAgICAgdGhpcy50eXBlRnVuYyA9IHR5cGVGdW5jOwogICAgICAgICAgICB0aGlzLm9wdEZpbHRlciA9IHR5cGVGaWx0ZXI7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgSW5jb3Jwb3JhdGlvbkFjdGlvbiBkdXAoVW5kZXRWYXIgdGhhdCkgewogICAgICAgICAgICByZXR1cm4gbmV3IENoZWNrQm91bmRzKHRoYXQsIHQsIHR5cGVGdW5jLCBvcHRGaWx0ZXIsIGZyb20pOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgdm9pZCBhcHBseShJbmZlcmVuY2VDb250ZXh0IGluZmVyZW5jZUNvbnRleHQsIFdhcm5lciB3YXJuKSB7CiAgICAgICAgICAgIHQgPSB0eXBlRnVuYy5hcHBseShpbmZlcmVuY2VDb250ZXh0LCB0KTsKICAgICAgICAgICAgaWYgKG9wdEZpbHRlciAhPSBudWxsICYmIG9wdEZpbHRlci50ZXN0KGluZmVyZW5jZUNvbnRleHQsIHQpKSByZXR1cm47CiAgICAgICAgICAgIGZvciAoSW5mZXJlbmNlQm91bmQgdG8gOiBib3VuZHNUb0NoZWNrKCkpIHsKICAgICAgICAgICAgICAgIGZvciAoVHlwZSBiIDogdXYuZ2V0Qm91bmRzKHRvKSkgewogICAgICAgICAgICAgICAgICAgIGIgPSB0eXBlRnVuYy5hcHBseShpbmZlcmVuY2VDb250ZXh0LCBiKTsKICAgICAgICAgICAgICAgICAgICBpZiAob3B0RmlsdGVyICE9IG51bGwgJiYgb3B0RmlsdGVyLnRlc3QoaW5mZXJlbmNlQ29udGV4dCwgYikpIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gc3VjY2VzcyA9IGNoZWNrQm91bmQodCwgYiwgZnJvbSwgdG8sIHdhcm4pOwogICAgICAgICAgICAgICAgICAgIGlmICghc3VjY2VzcykgewogICAgICAgICAgICAgICAgICAgICAgICByZXBvcnQoZnJvbSwgdG8pOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogVGhlIGxpc3Qgb2YgYm91bmQga2luZHMgdG8gYmUgY2hlY2tlZC4KICAgICAgICAgKi8KICAgICAgICBFbnVtU2V0PEluZmVyZW5jZUJvdW5kPiBib3VuZHNUb0NoZWNrKCkgewogICAgICAgICAgICByZXR1cm4gKGZyb20gPT0gSW5mZXJlbmNlQm91bmQuRVEpID8KICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVudW1TZXQuYWxsT2YoSW5mZXJlbmNlQm91bmQuY2xhc3MpIDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVudW1TZXQuY29tcGxlbWVudE9mKEVudW1TZXQub2YoZnJvbSkpOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogSXMgc291cmNlIHR5cGUgJ3MnIGNvbXBhdGlibGUgd2l0aCB0YXJnZXQgdHlwZSAndCcgZ2l2ZW4gc291cmNlIGFuZCB0YXJnZXQgYm91bmQga2luZHM/CiAgICAgICAgICovCiAgICAgICAgYm9vbGVhbiBjaGVja0JvdW5kKFR5cGUgcywgVHlwZSB0LCBJbmZlcmVuY2VCb3VuZCBpYl9zLCBJbmZlcmVuY2VCb3VuZCBpYl90LCBXYXJuZXIgd2FybikgewogICAgICAgICAgICBpZiAoaWJfcy5sZXNzVGhhbihpYl90KSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGlzU3VidHlwZShzLCB0LCB3YXJuKTsKICAgICAgICAgICAgfSBlbHNlIGlmIChpYl90Lmxlc3NUaGFuKGliX3MpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gaXNTdWJ0eXBlKHQsIHMsIHdhcm4pOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcmV0dXJuIGlzU2FtZVR5cGUocywgdCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIFJlcG9ydCBhIGJvdW5kIGNoZWNrIGVycm9yLgogICAgICAgICAqLwogICAgICAgIHZvaWQgcmVwb3J0KEluZmVyZW5jZUJvdW5kIGZyb20sIEluZmVyZW5jZUJvdW5kIHRvKSB7CiAgICAgICAgICAgIC8vdGhpcyBpcyBhIHdvcmthcm91bmQgdG8gcHJlc2VydmUgY29tcGF0aWJpbGl0eSB3aXRoIGV4aXN0aW5nIG1lc3NhZ2VzCiAgICAgICAgICAgIGlmIChmcm9tID09IHRvKSB7CiAgICAgICAgICAgICAgICByZXBvcnRCb3VuZEVycm9yKHV2LCBmcm9tKTsKICAgICAgICAgICAgfSBlbHNlIGlmIChmcm9tID09IEluZmVyZW5jZUJvdW5kLkxPV0VSIHx8IHRvID09IEluZmVyZW5jZUJvdW5kLkVRKSB7CiAgICAgICAgICAgICAgICByZXBvcnRCb3VuZEVycm9yKHV2LCB0bywgZnJvbSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICByZXBvcnRCb3VuZEVycm9yKHV2LCBmcm9tLCB0byk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CiAgICAgICAgICAgIHJldHVybiBTdHJpbmcuZm9ybWF0KCIlc1t1bmRldD0lcyx0PSVzLGJvdW5kPSVzXSIsIGdldENsYXNzKCkuZ2V0U2ltcGxlTmFtZSgpLCB1di5xdHlwZSwgdCwgZnJvbSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQ3VzdG9tIGNoZWNrIGV4ZWN1dGVkIGJ5IHRoZSBsZWdhY3kgaW5jb3Jwb3JhdGlvbiBlbmdpbmUuIE5ld2x5IGFkZGVkIGJvdW5kcyBhcmUgY2hlY2tlZAogICAgICogYWdhaW5zdCBleGlzdGluZyBlcSBib3VuZHMuCiAgICAgKi8KICAgIGNsYXNzIEVxQ2hlY2tMZWdhY3kgZXh0ZW5kcyBDaGVja0JvdW5kcyB7CiAgICAgICAgRXFDaGVja0xlZ2FjeShVbmRldFZhciB1diwgVHlwZSB0LCBJbmZlcmVuY2VCb3VuZCBmcm9tKSB7CiAgICAgICAgICAgIHN1cGVyKHV2LCB0LCBJbmZlcmVuY2VDb250ZXh0Ojphc0luc3RUeXBlLCBJbmZlcmVuY2VDb250ZXh0OjpmcmVlLCBmcm9tKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBJbmNvcnBvcmF0aW9uQWN0aW9uIGR1cChVbmRldFZhciB0aGF0KSB7CiAgICAgICAgICAgIHJldHVybiBuZXcgRXFDaGVja0xlZ2FjeSh0aGF0LCB0LCBmcm9tKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIEVudW1TZXQ8SW5mZXJlbmNlQm91bmQ+IGJvdW5kc1RvQ2hlY2soKSB7CiAgICAgICAgICAgIHJldHVybiAoZnJvbSA9PSBJbmZlcmVuY2VCb3VuZC5FUSkgPwogICAgICAgICAgICAgICAgICAgICAgICAgICAgRW51bVNldC5hbGxPZihJbmZlcmVuY2VCb3VuZC5jbGFzcykgOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgRW51bVNldC5vZihJbmZlcmVuY2VCb3VuZC5FUSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQ2hlY2sgdGhhdCB0aGUgaW5mZXJyZWQgdHlwZSBjb25mb3JtcyB0byBhbGwgYm91bmRzLgogICAgICovCiAgICBjbGFzcyBDaGVja0luc3QgZXh0ZW5kcyBDaGVja0JvdW5kcyB7CgogICAgICAgIEVudW1TZXQ8SW5mZXJlbmNlQm91bmQ+IHRvOwoKICAgICAgICBDaGVja0luc3QoVW5kZXRWYXIgdXYsIEluZmVyZW5jZUJvdW5kIGliLCBJbmZlcmVuY2VCb3VuZC4uLiByZXN0KSB7CiAgICAgICAgICAgIHRoaXModXYsIEVudW1TZXQub2YoaWIsIHJlc3QpKTsKICAgICAgICB9CgogICAgICAgIENoZWNrSW5zdChVbmRldFZhciB1diwgRW51bVNldDxJbmZlcmVuY2VCb3VuZD4gdG8pIHsKICAgICAgICAgICAgc3VwZXIodXYsIHV2LmdldEluc3QoKSwgSW5mZXJlbmNlQm91bmQuRVEpOwogICAgICAgICAgICB0aGlzLnRvID0gdG87CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgSW5jb3Jwb3JhdGlvbkFjdGlvbiBkdXAoVW5kZXRWYXIgdGhhdCkgewogICAgICAgICAgICByZXR1cm4gbmV3IENoZWNrSW5zdCh0aGF0LCB0byk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBFbnVtU2V0PEluZmVyZW5jZUJvdW5kPiBib3VuZHNUb0NoZWNrKCkgewogICAgICAgICAgICByZXR1cm4gdG87CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICB2b2lkIHJlcG9ydChJbmZlcmVuY2VCb3VuZCBmcm9tLCBJbmZlcmVuY2VCb3VuZCB0bykgewogICAgICAgICAgICByZXBvcnRJbnN0RXJyb3IodXYsIHRvKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXBsYWNlIHVuZGV0dmFycyBpbiBib3VuZHMgYW5kIGNoZWNrIHRoYXQgdGhlIGluZmVycmVkIHR5cGUgY29uZm9ybXMgdG8gYWxsIGJvdW5kcy4KICAgICAqLwogICAgY2xhc3MgU3Vic3RCb3VuZHMgZXh0ZW5kcyBDaGVja0luc3QgewogICAgICAgIFN1YnN0Qm91bmRzKFVuZGV0VmFyIHV2KSB7CiAgICAgICAgICAgIHN1cGVyKHV2LCBJbmZlcmVuY2VCb3VuZC5MT1dFUiwgSW5mZXJlbmNlQm91bmQuRVEsIEluZmVyZW5jZUJvdW5kLlVQUEVSKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBJbmNvcnBvcmF0aW9uQWN0aW9uIGR1cChVbmRldFZhciB0aGF0KSB7CiAgICAgICAgICAgIHJldHVybiBuZXcgU3Vic3RCb3VuZHModGhhdCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICB2b2lkIGFwcGx5KEluZmVyZW5jZUNvbnRleHQgaW5mZXJlbmNlQ29udGV4dCwgV2FybmVyIHdhcm4pIHsKICAgICAgICAgICAgZm9yIChUeXBlIHVuZGV0IDogaW5mZXJlbmNlQ29udGV4dC51bmRldHZhcnMpIHsKICAgICAgICAgICAgICAgIC8vd2UgY291bGQgZmlsdGVyIG91dCB2YXJpYWJsZXMgbm90IG1lbnRpb25pbmcgdXYyLi4uCiAgICAgICAgICAgICAgICBVbmRldFZhciB1djIgPSAoVW5kZXRWYXIpdW5kZXQ7CiAgICAgICAgICAgICAgICB1djIuc3Vic3RCb3VuZHMoTGlzdC5vZih1di5xdHlwZSksIExpc3Qub2YodXYuZ2V0SW5zdCgpKSwgdHlwZXMpOwogICAgICAgICAgICAgICAgY2hlY2tDb21wYXRpYmxlVXBwZXJCb3VuZHModXYyLCBpbmZlcmVuY2VDb250ZXh0KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBzdXBlci5hcHBseShpbmZlcmVuY2VDb250ZXh0LCB3YXJuKTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIE1ha2Ugc3VyZSB0aGF0IHRoZSB1cHBlciBib3VuZHMgd2UgZ290IHNvIGZhciBsZWFkIHRvIGEgc29sdmFibGUgaW5mZXJlbmNlCiAgICAgICAgICogdmFyaWFibGUgYnkgbWFraW5nIHN1cmUgdGhhdCBhIGdsYiBleGlzdHMuCiAgICAgICAgICovCiAgICAgICAgdm9pZCBjaGVja0NvbXBhdGlibGVVcHBlckJvdW5kcyhVbmRldFZhciB1diwgSW5mZXJlbmNlQ29udGV4dCBpbmZlcmVuY2VDb250ZXh0KSB7CiAgICAgICAgICAgIExpc3Q8VHlwZT4gaGlib3VuZHMgPQogICAgICAgICAgICAgICAgICAgIFR5cGUuZmlsdGVyKHV2LmdldEJvdW5kcyhJbmZlcmVuY2VCb3VuZC5VUFBFUiksIG5ldyBCb3VuZEZpbHRlcihpbmZlcmVuY2VDb250ZXh0KSk7CiAgICAgICAgICAgIGZpbmFsIFR5cGUgaGI7CiAgICAgICAgICAgIGlmIChoaWJvdW5kcy5pc0VtcHR5KCkpCiAgICAgICAgICAgICAgICBoYiA9IHN5bXMub2JqZWN0VHlwZTsKICAgICAgICAgICAgZWxzZSBpZiAoaGlib3VuZHMudGFpbC5pc0VtcHR5KCkpCiAgICAgICAgICAgICAgICBoYiA9IGhpYm91bmRzLmhlYWQ7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIGhiID0gdHlwZXMuZ2xiKGhpYm91bmRzKTsKICAgICAgICAgICAgaWYgKGhiID09IG51bGwgfHwgaGIuaXNFcnJvbmVvdXMoKSkKICAgICAgICAgICAgICAgIHJlcG9ydEJvdW5kRXJyb3IodXYsIEluZmVyZW5jZUJvdW5kLlVQUEVSKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBQZXJmb3JtIHBhaXJ3aXNlIGNvbXBhcmlzb24gYmV0d2VlbiBjb21tb24gZ2VuZXJpYyBzdXBlcnR5cGVzIG9mIHR3byB1cHBlciBib3VuZHMuCiAgICAgKi8KICAgIGNsYXNzIENoZWNrVXBwZXJCb3VuZHMgZXh0ZW5kcyBJbmNvcnBvcmF0aW9uQWN0aW9uIHsKCiAgICAgICAgcHVibGljIENoZWNrVXBwZXJCb3VuZHMoVW5kZXRWYXIgdXYsIFR5cGUgdCkgewogICAgICAgICAgICBzdXBlcih1diwgdCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgSW5jb3Jwb3JhdGlvbkFjdGlvbiBkdXAoVW5kZXRWYXIgdGhhdCkgewogICAgICAgICAgICByZXR1cm4gbmV3IENoZWNrVXBwZXJCb3VuZHModGhhdCwgdCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICB2b2lkIGFwcGx5KEluZmVyZW5jZUNvbnRleHQgaW5mZXJlbmNlQ29udGV4dCwgV2FybmVyIHdhcm4pIHsKICAgICAgICAgICAgTGlzdDxUeXBlPiBib3VuZExpc3QgPSB1di5nZXRCb3VuZHMoSW5mZXJlbmNlQm91bmQuVVBQRVIpLnN0cmVhbSgpCiAgICAgICAgICAgICAgICAgICAgLmNvbGxlY3QodHlwZXMuY2xvc3VyZUNvbGxlY3Rvcih0cnVlLCB0eXBlczo6aXNTYW1lVHlwZSkpOwogICAgICAgICAgICBmb3IgKFR5cGUgYjIgOiBib3VuZExpc3QpIHsKICAgICAgICAgICAgICAgIGlmICh0ID09IGIyKSBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICAvKiBUaGlzIHdpbGRjYXJkIGNoZWNrIGlzIHRlbXBvcmFyeSB3b3JrYXJvdW5kLiBUaGlzIGNvZGUgbWF5IG5lZWQgdG8gYmUKICAgICAgICAgICAgICAgICAgICAgKiByZXZpc2l0ZWQgb25jZSBzcGVjIGJ1ZyBKREstNzAzNDkyMiBpcyBmaXhlZC4KICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIGlmICh0ICE9IGIyICYmICF0Lmhhc1RhZyhXSUxEQ0FSRCkgJiYgIWIyLmhhc1RhZyhXSUxEQ0FSRCkpIHsKICAgICAgICAgICAgICAgICAgICBmb3IgKFBhaXI8VHlwZSwgVHlwZT4gY29tbW9uU3VwZXJzIDogZ2V0UGFyYW1ldGVyaXplZFN1cGVycyh0LCBiMikpIHsKICAgICAgICAgICAgICAgICAgICAgICAgTGlzdDxUeXBlPiBhbGxQYXJhbXNTdXBlckJvdW5kMSA9IGNvbW1vblN1cGVycy5mc3QuYWxscGFyYW1zKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIExpc3Q8VHlwZT4gYWxsUGFyYW1zU3VwZXJCb3VuZDIgPSBjb21tb25TdXBlcnMuc25kLmFsbHBhcmFtcygpOwogICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoYWxsUGFyYW1zU3VwZXJCb3VuZDEubm9uRW1wdHkoKSAmJiBhbGxQYXJhbXNTdXBlckJvdW5kMi5ub25FbXB0eSgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3RyYXZlcnNlIHRoZSBsaXN0IG9mIGFsbCBwYXJhbXMgY29tcGFyaW5nIHRoZW0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghYWxsUGFyYW1zU3VwZXJCb3VuZDEuaGVhZC5oYXNUYWcoV0lMRENBUkQpICYmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICFhbGxQYXJhbXNTdXBlckJvdW5kMi5oZWFkLmhhc1RhZyhXSUxEQ0FSRCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWlzU2FtZVR5cGUoaW5mZXJlbmNlQ29udGV4dC5hc1VuZGV0VmFyKGFsbFBhcmFtc1N1cGVyQm91bmQxLmhlYWQpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5mZXJlbmNlQ29udGV4dC5hc1VuZGV0VmFyKGFsbFBhcmFtc1N1cGVyQm91bmQyLmhlYWQpKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXBvcnRCb3VuZEVycm9yKHV2LCBJbmZlcmVuY2VCb3VuZC5VUFBFUik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgYWxsUGFyYW1zU3VwZXJCb3VuZDEgPSBhbGxQYXJhbXNTdXBlckJvdW5kMS50YWlsOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYWxsUGFyYW1zU3VwZXJCb3VuZDIgPSBhbGxQYXJhbXNTdXBlckJvdW5kMi50YWlsOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIEFzc2VydC5jaGVjayhhbGxQYXJhbXNTdXBlckJvdW5kMS5pc0VtcHR5KCkgJiYgYWxsUGFyYW1zU3VwZXJCb3VuZDIuaXNFbXB0eSgpKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBQZXJmb3JtIHByb3BhZ2F0aW9uIG9mIGJvdW5kcy4gR2l2ZW4gYSBjb25zdHJhaW50IG9mIHRoZSBraW5kIHtAY29kZSBhbHBoYSA8OiBUfSwgdGhyZWUKICAgICAqIGtpbmQgb2YgcHJvcGFnYXRpb24gb2NjdXI6CiAgICAgKgogICAgICogPGxpPlQgaXMgY29waWVkIGludG8gYWxsIG1hdGNoaW5nIGJvdW5kcyAoaS5lLiBsb3dlci9lcSBib3VuZHMpIEIgb2YgYWxwaGEgc3VjaCB0aGF0IEI9YmV0YSAoZm9yd2FyZCBwcm9wYWdhdGlvbik8L2xpPgogICAgICogPGxpPmlmIFQ9YmV0YSwgbWF0Y2hpbmcgYm91bmRzIChpLmUuIHVwcGVyIGJvdW5kcykgb2YgYmV0YSBhcmUgY29waWVkIGludG8gYWxwaGEgKGJhY2t3YXJkcyBwcm9wYWdhdGlvbik8L2xpPgogICAgICogPGxpPmlmIFQ9YmV0YSwgc2V0cyBhIHN5bW1ldHJpYyBib3VuZCBvbiBiZXRhIChpLmUuIGJldGEgOj4gYWxwaGEpIChzeW1tZXRyaWMgcHJvcGFnYXRpb24pIDwvbGk+CiAgICAgKi8KICAgIGNsYXNzIFByb3BhZ2F0ZUJvdW5kcyBleHRlbmRzIEluY29ycG9yYXRpb25BY3Rpb24gewoKICAgICAgICBJbmZlcmVuY2VCb3VuZCBpYjsKCiAgICAgICAgcHVibGljIFByb3BhZ2F0ZUJvdW5kcyhVbmRldFZhciB1diwgVHlwZSB0LCBJbmZlcmVuY2VCb3VuZCBpYikgewogICAgICAgICAgICBzdXBlcih1diwgdCk7CiAgICAgICAgICAgIHRoaXMuaWIgPSBpYjsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBJbmNvcnBvcmF0aW9uQWN0aW9uIGR1cChVbmRldFZhciB0aGF0KSB7CiAgICAgICAgICAgIHJldHVybiBuZXcgUHJvcGFnYXRlQm91bmRzKHRoYXQsIHQsIGliKTsKICAgICAgICB9CgogICAgICAgIHZvaWQgYXBwbHkoSW5mZXJlbmNlQ29udGV4dCBpbmZlcmVuY2VDb250ZXh0LCBXYXJuZXIgd2FybmVyKSB7CiAgICAgICAgICAgIFR5cGUgdW5kZXRUID0gaW5mZXJlbmNlQ29udGV4dC5hc1VuZGV0VmFyKHQpOwogICAgICAgICAgICBpZiAodW5kZXRULmhhc1RhZyhVTkRFVFZBUikgJiYgISgoVW5kZXRWYXIpdW5kZXRUKS5pc0NhcHR1cmVkKCkpIHsKICAgICAgICAgICAgICAgIFVuZGV0VmFyIHV2MiA9IChVbmRldFZhcil1bmRldFQ7CiAgICAgICAgICAgICAgICAvL3N5bW1ldHJpYyBwcm9wYWdhdGlvbgogICAgICAgICAgICAgICAgdXYyLmFkZEJvdW5kKGliLmNvbXBsZW1lbnQoKSwgdXYsIHR5cGVzKTsKICAgICAgICAgICAgICAgIC8vYmFja3dhcmRzIHByb3BhZ2F0aW9uCiAgICAgICAgICAgICAgICBmb3IgKEluZmVyZW5jZUJvdW5kIGliMiA6IGJhY2t3YXJkcygpKSB7CiAgICAgICAgICAgICAgICAgICAgZm9yIChUeXBlIGIgOiB1djIuZ2V0Qm91bmRzKGliMikpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdXYuYWRkQm91bmQoaWIyLCBiLCB0eXBlcyk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vZm9yd2FyZCBwcm9wYWdhdGlvbgogICAgICAgICAgICBmb3IgKEluZmVyZW5jZUJvdW5kIGliMiA6IGZvcndhcmQoKSkgewogICAgICAgICAgICAgICAgZm9yIChUeXBlIGwgOiB1di5nZXRCb3VuZHMoaWIyKSkgewogICAgICAgICAgICAgICAgICAgIFR5cGUgdW5kZXQgPSBpbmZlcmVuY2VDb250ZXh0LmFzVW5kZXRWYXIobCk7CiAgICAgICAgICAgICAgICAgICAgaWYgKHVuZGV0Lmhhc1RhZyhUeXBlVGFnLlVOREVUVkFSKSAmJiAhKChVbmRldFZhcil1bmRldCkuaXNDYXB0dXJlZCgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIFVuZGV0VmFyIHV2MiA9IChVbmRldFZhcil1bmRldDsKICAgICAgICAgICAgICAgICAgICAgICAgdXYyLmFkZEJvdW5kKGliLCBpbmZlcmVuY2VDb250ZXh0LmFzSW5zdFR5cGUodCksIHR5cGVzKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEVudW1TZXQ8SW5mZXJlbmNlQm91bmQ+IGZvcndhcmQoKSB7CiAgICAgICAgICAgIHJldHVybiAoaWIgPT0gSW5mZXJlbmNlQm91bmQuRVEpID8KICAgICAgICAgICAgICAgICAgICBFbnVtU2V0Lm9mKEluZmVyZW5jZUJvdW5kLkVRKSA6IEVudW1TZXQuY29tcGxlbWVudE9mKEVudW1TZXQub2YoaWIpKTsKICAgICAgICB9CgogICAgICAgIEVudW1TZXQ8SW5mZXJlbmNlQm91bmQ+IGJhY2t3YXJkcygpIHsKICAgICAgICAgICAgcmV0dXJuIChpYiA9PSBJbmZlcmVuY2VCb3VuZC5FUSkgPwogICAgICAgICAgICAgICAgICAgIEVudW1TZXQuYWxsT2YoSW5mZXJlbmNlQm91bmQuY2xhc3MpIDogRW51bVNldC5vZihpYik7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewogICAgICAgICAgICByZXR1cm4gU3RyaW5nLmZvcm1hdCgiJXNbdW5kZXQ9JXMsdD0lcyxib3VuZD0lc10iLCBnZXRDbGFzcygpLmdldFNpbXBsZU5hbWUoKSwgdXYucXR5cGUsIHQsIGliKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBUaGlzIGNsYXNzIG1vZGVscyBhbiBpbmNvcnBvcmF0aW9uIGVuZ2luZS4gVGhlIGVuZ2luZSBpcyByZXNwb25zaWJsZSBmb3IgbGlzdGVuaW5nIHRvCiAgICAgKiBjaGFuZ2VzIGluIGluZmVyZW5jZSB2YXJpYWJsZXMgYW5kIHJlZ2lzdGVyIGluY29ycG9yYXRpb24gYWN0aW9ucyBhY2NvcmRpbmdseS4KICAgICAqLwogICAgYWJzdHJhY3QgY2xhc3MgQWJzdHJhY3RJbmNvcnBvcmF0aW9uRW5naW5lIGltcGxlbWVudHMgVW5kZXRWYXJMaXN0ZW5lciB7CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHZhckluc3RhbnRpYXRlZChVbmRldFZhciB1dikgewogICAgICAgICAgICB1di5pbmNvcnBvcmF0aW9uQWN0aW9ucy5hZGRGaXJzdChuZXcgU3Vic3RCb3VuZHModXYpKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHZhckJvdW5kQ2hhbmdlZChVbmRldFZhciB1diwgSW5mZXJlbmNlQm91bmQgaWIsIFR5cGUgYm91bmQsIGJvb2xlYW4gdXBkYXRlKSB7CiAgICAgICAgICAgIGlmICh1di5pc0NhcHR1cmVkKCkpIHJldHVybjsKICAgICAgICAgICAgdXYuaW5jb3Jwb3JhdGlvbkFjdGlvbnMuYWRkQWxsKGdldEluY29ycG9yYXRpb25BY3Rpb25zKHV2LCBpYiwgYm91bmQsIHVwZGF0ZSkpOwogICAgICAgIH0KCiAgICAgICAgYWJzdHJhY3QgTGlzdDxJbmNvcnBvcmF0aW9uQWN0aW9uPiBnZXRJbmNvcnBvcmF0aW9uQWN0aW9ucyhVbmRldFZhciB1diwgSW5mZXJlbmNlQm91bmQgaWIsIFR5cGUgdCwgYm9vbGVhbiB1cGRhdGUpOwogICAgfQoKICAgIC8qKgogICAgICogQSBsZWdhY3kgaW5jb3Jwb3JhdGlvbiBlbmdpbmUuIFVzZWQgZm9yIHNvdXJjZSA8PSA3LgogICAgICovCiAgICBBYnN0cmFjdEluY29ycG9yYXRpb25FbmdpbmUgbGVnYWN5RW5naW5lID0gbmV3IEFic3RyYWN0SW5jb3Jwb3JhdGlvbkVuZ2luZSgpIHsKCiAgICAgICAgTGlzdDxJbmNvcnBvcmF0aW9uQWN0aW9uPiBnZXRJbmNvcnBvcmF0aW9uQWN0aW9ucyhVbmRldFZhciB1diwgSW5mZXJlbmNlQm91bmQgaWIsIFR5cGUgdCwgYm9vbGVhbiB1cGRhdGUpIHsKICAgICAgICAgICAgTGlzdEJ1ZmZlcjxJbmNvcnBvcmF0aW9uQWN0aW9uPiBhY3Rpb25zID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgICAgICBUeXBlIGluc3QgPSB1di5nZXRJbnN0KCk7CiAgICAgICAgICAgIGlmIChpbnN0ICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIGFjdGlvbnMuYWRkKG5ldyBDaGVja0luc3QodXYsIGliKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYWN0aW9ucy5hZGQobmV3IEVxQ2hlY2tMZWdhY3kodXYsIHQsIGliKSk7CiAgICAgICAgICAgIHJldHVybiBhY3Rpb25zLnRvTGlzdCgpOwogICAgICAgIH0KICAgIH07CgogICAgLyoqCiAgICAgKiBUaGUgc3RhbmRhcmQgaW5jb3Jwb3JhdGlvbiBlbmdpbmUuIFVzZWQgZm9yIHNvdXJjZSA+PSA4LgogICAgICovCiAgICBBYnN0cmFjdEluY29ycG9yYXRpb25FbmdpbmUgZ3JhcGhFbmdpbmUgPSBuZXcgQWJzdHJhY3RJbmNvcnBvcmF0aW9uRW5naW5lKCkgewoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBMaXN0PEluY29ycG9yYXRpb25BY3Rpb24+IGdldEluY29ycG9yYXRpb25BY3Rpb25zKFVuZGV0VmFyIHV2LCBJbmZlcmVuY2VCb3VuZCBpYiwgVHlwZSB0LCBib29sZWFuIHVwZGF0ZSkgewogICAgICAgICAgICBMaXN0QnVmZmVyPEluY29ycG9yYXRpb25BY3Rpb24+IGFjdGlvbnMgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgIFR5cGUgaW5zdCA9IHV2LmdldEluc3QoKTsKICAgICAgICAgICAgaWYgKGluc3QgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgYWN0aW9ucy5hZGQobmV3IENoZWNrSW5zdCh1diwgaWIpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBhY3Rpb25zLmFkZChuZXcgQ2hlY2tCb3VuZHModXYsIHQsIGliKSk7CgogICAgICAgICAgICBpZiAodXBkYXRlKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gYWN0aW9ucy50b0xpc3QoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKGliID09IEluZmVyZW5jZUJvdW5kLlVQUEVSKSB7CiAgICAgICAgICAgICAgICBhY3Rpb25zLmFkZChuZXcgQ2hlY2tVcHBlckJvdW5kcyh1diwgdCkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBhY3Rpb25zLmFkZChuZXcgUHJvcGFnYXRlQm91bmRzKHV2LCB0LCBpYikpOwoKICAgICAgICAgICAgcmV0dXJuIGFjdGlvbnMudG9MaXN0KCk7CiAgICAgICAgfQogICAgfTsKCiAgICAvKioKICAgICAqIEdldCB0aGUgaW5jb3Jwb3JhdGlvbiBlbmdpbmUgdG8gYmUgdXNlZCBpbiB0aGlzIGNvbXBpbGF0aW9uLgogICAgICovCiAgICBBYnN0cmFjdEluY29ycG9yYXRpb25FbmdpbmUgaW5jb3Jwb3JhdGlvbkVuZ2luZSgpIHsKICAgICAgICByZXR1cm4gYWxsb3dHcmFwaEluZmVyZW5jZSA/IGdyYXBoRW5naW5lIDogbGVnYWN5RW5naW5lOwogICAgfQoKICAgIC8qKiBtYXggbnVtYmVyIG9mIGluY29ycG9yYXRpb24gcm91bmRzLiAqLwogICAgc3RhdGljIGZpbmFsIGludCBNQVhfSU5DT1JQT1JBVElPTl9TVEVQUyA9IDEwMDAwOwoKICAgIC8qKgogICAgICogQ2hlY2sgYm91bmRzIGFuZCBwZXJmb3JtIGluY29ycG9yYXRpb24uCiAgICAgKi8KICAgIHZvaWQgZG9JbmNvcnBvcmF0aW9uKEluZmVyZW5jZUNvbnRleHQgaW5mZXJlbmNlQ29udGV4dCwgV2FybmVyIHdhcm4pIHRocm93cyBJbmZlcmVuY2VFeGNlcHRpb24gewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGJvb2xlYW4gcHJvZ3Jlc3MgPSB0cnVlOwogICAgICAgICAgICBpbnQgcm91bmQgPSAwOwogICAgICAgICAgICB3aGlsZSAocHJvZ3Jlc3MgJiYgcm91bmQgPCBNQVhfSU5DT1JQT1JBVElPTl9TVEVQUykgewogICAgICAgICAgICAgICAgcHJvZ3Jlc3MgPSBmYWxzZTsKICAgICAgICAgICAgICAgIGZvciAoVHlwZSB0IDogaW5mZXJlbmNlQ29udGV4dC51bmRldHZhcnMpIHsKICAgICAgICAgICAgICAgICAgICBVbmRldFZhciB1diA9IChVbmRldFZhcil0OwogICAgICAgICAgICAgICAgICAgIGlmICghdXYuaW5jb3Jwb3JhdGlvbkFjdGlvbnMuaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHByb2dyZXNzID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgdXYuaW5jb3Jwb3JhdGlvbkFjdGlvbnMucmVtb3ZlRmlyc3QoKS5hcHBseShpbmZlcmVuY2VDb250ZXh0LCB3YXJuKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByb3VuZCsrOwogICAgICAgICAgICB9CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgaW5jb3Jwb3JhdGlvbkNhY2hlLmNsZWFyKCk7CiAgICAgICAgfQogICAgfQoKICAgIC8qIElmIGZvciB0d28gdHlwZXMgdCBhbmQgcyB0aGVyZSBpcyBhIGxlYXN0IHVwcGVyIGJvdW5kIHRoYXQgY29udGFpbnMKICAgICAqIHBhcmFtZXRlcml6ZWQgdHlwZXMgRzEsIEcyIC4uLiBHbiwgdGhlbiB0aGVyZSBleGlzdHMgc3VwZXJ0eXBlcyBvZiAndCcgb2YgdGhlIGZvcm0KICAgICAqIEcxPFQxLCAuLi4sIFRuPiwgRzI8VDEsIC4uLiwgVG4+LCAuLi4gR248VDEsIC4uLiwgVG4+IGFuZCBzdXBlcnR5cGVzIG9mICdzJyBvZiB0aGUgZm9ybQogICAgICogRzE8UzEsIC4uLiwgU24+LCBHMjxTMSwgLi4uLCBTbj4sIC4uLiBHbjxTMSwgLi4uLCBTbj4gd2hpY2ggd2lsbCBiZSByZXR1cm5lZCBieSB0aGlzIG1ldGhvZC4KICAgICAqIElmIG5vIHN1Y2ggY29tbW9uIHN1cGVydHlwZXMgZXhpc3RzIHRoZW4gYW4gZW1wdHkgbGlzdCBpcyByZXR1cm5lZC4KICAgICAqCiAgICAgKiBBcyBhbiBleGFtcGxlIGZvciB0aGUgZm9sbG93aW5nIGlucHV0OgogICAgICoKICAgICAqIHQgPSBqYXZhLnV0aWwuQXJyYXlMaXN0PGphdmEubGFuZy5TdHJpbmc+CiAgICAgKiBzID0gamF2YS51dGlsLkxpc3Q8VD4KICAgICAqCiAgICAgKiB3ZSBnZXQgdGhpcyBvdXB1dCAoc2luZ2xldG9uIGxpc3QpOgogICAgICoKICAgICAqIFtQYWlyW2phdmEudXRpbC5MaXN0PGphdmEubGFuZy5TdHJpbmc+LGphdmEudXRpbC5MaXN0PFQ+XV0KICAgICAqLwogICAgcHJpdmF0ZSBMaXN0PFBhaXI8VHlwZSwgVHlwZT4+IGdldFBhcmFtZXRlcml6ZWRTdXBlcnMoVHlwZSB0LCBUeXBlIHMpIHsKICAgICAgICBUeXBlIGx1YlJlc3VsdCA9IHR5cGVzLmx1Yih0LCBzKTsKICAgICAgICBpZiAobHViUmVzdWx0ID09IHN5bXMuZXJyVHlwZSB8fCBsdWJSZXN1bHQgPT0gc3ltcy5ib3RUeXBlKSB7CiAgICAgICAgICAgIHJldHVybiBMaXN0Lm5pbCgpOwogICAgICAgIH0KICAgICAgICBMaXN0PFR5cGU+IHN1cGVydHlwZXNUb0NoZWNrID0gbHViUmVzdWx0LmlzSW50ZXJzZWN0aW9uKCkgPwogICAgICAgICAgICAgICAgKChJbnRlcnNlY3Rpb25DbGFzc1R5cGUpbHViUmVzdWx0KS5nZXRDb21wb25lbnRzKCkgOgogICAgICAgICAgICAgICAgTGlzdC5vZihsdWJSZXN1bHQpOwogICAgICAgIExpc3RCdWZmZXI8UGFpcjxUeXBlLCBUeXBlPj4gY29tbW9uU3VwZXJ0eXBlcyA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICBmb3IgKFR5cGUgc3VwIDogc3VwZXJ0eXBlc1RvQ2hlY2spIHsKICAgICAgICAgICAgaWYgKHN1cC5pc1BhcmFtZXRlcml6ZWQoKSkgewogICAgICAgICAgICAgICAgVHlwZSBhc1N1cGVyT2ZUID0gYXNTdXBlcih0LCBzdXApOwogICAgICAgICAgICAgICAgVHlwZSBhc1N1cGVyT2ZTID0gYXNTdXBlcihzLCBzdXApOwogICAgICAgICAgICAgICAgY29tbW9uU3VwZXJ0eXBlcy5hZGQobmV3IFBhaXI8Pihhc1N1cGVyT2ZULCBhc1N1cGVyT2ZTKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIGNvbW1vblN1cGVydHlwZXMudG9MaXN0KCk7CiAgICB9CiAgICAvL3doZXJlCiAgICAgICAgcHJpdmF0ZSBUeXBlIGFzU3VwZXIoVHlwZSB0LCBUeXBlIHN1cCkgewogICAgICAgICAgICByZXR1cm4gKHN1cC5oYXNUYWcoQVJSQVkpKSA/CiAgICAgICAgICAgICAgICAgICAgbmV3IEFycmF5VHlwZShhc1N1cGVyKHR5cGVzLmVsZW10eXBlKHQpLCB0eXBlcy5lbGVtdHlwZShzdXApKSwgc3ltcy5hcnJheUNsYXNzKSA6CiAgICAgICAgICAgICAgICAgICAgdHlwZXMuYXNTdXBlcih0LCBzdXAudHN5bSk7CiAgICAgICAgfQoKICAgIGJvb2xlYW4gZG9JbmNvcnBvcmF0aW9uT3AoSW5jb3Jwb3JhdGlvbkJpbmFyeU9wS2luZCBvcEtpbmQsIFR5cGUgb3AxLCBUeXBlIG9wMiwgV2FybmVyIHdhcm4pIHsKICAgICAgICAgICAgSW5jb3Jwb3JhdGlvbkJpbmFyeU9wIG5ld09wID0gbmV3IEluY29ycG9yYXRpb25CaW5hcnlPcChvcEtpbmQsIG9wMSwgb3AyKTsKICAgICAgICAgICAgQm9vbGVhbiByZXMgPSBpbmNvcnBvcmF0aW9uQ2FjaGUuZ2V0KG5ld09wKTsKICAgICAgICAgICAgaWYgKHJlcyA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICBpbmNvcnBvcmF0aW9uQ2FjaGUucHV0KG5ld09wLCByZXMgPSBuZXdPcC5hcHBseSh3YXJuKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHJlczsKICAgICAgICB9CgogICAgLyoqCiAgICAgKiBUaHJlZSBraW5kcyBvZiBiYXNpYyBvcGVyYXRpb24gYXJlIHN1cHBvcnRlZCBhcyBwYXJ0IG9mIGFuIGluY29ycG9yYXRpb24gc3RlcDoKICAgICAqIChpKSBzdWJ0eXBlIGNoZWNrLCAoaWkpIHNhbWUgdHlwZSBjaGVjayBhbmQgKGlpaSkgYm91bmQgYWRkaXRpb24gKGVpdGhlcgogICAgICogdXBwZXIvbG93ZXIvZXEgYm91bmQpLgogICAgICovCiAgICBlbnVtIEluY29ycG9yYXRpb25CaW5hcnlPcEtpbmQgewogICAgICAgIElTX1NVQlRZUEUoKSB7CiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBib29sZWFuIGFwcGx5KFR5cGUgb3AxLCBUeXBlIG9wMiwgV2FybmVyIHdhcm4sIFR5cGVzIHR5cGVzKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHlwZXMuaXNTdWJ0eXBlVW5jaGVja2VkKG9wMSwgb3AyLCB3YXJuKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgSVNfU0FNRV9UWVBFKCkgewogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgYm9vbGVhbiBhcHBseShUeXBlIG9wMSwgVHlwZSBvcDIsIFdhcm5lciB3YXJuLCBUeXBlcyB0eXBlcykgewogICAgICAgICAgICAgICAgcmV0dXJuIHR5cGVzLmlzU2FtZVR5cGUob3AxLCBvcDIpOwogICAgICAgICAgICB9CiAgICAgICAgfTsKCiAgICAgICAgYWJzdHJhY3QgYm9vbGVhbiBhcHBseShUeXBlIG9wMSwgVHlwZSBvcDIsIFdhcm5lciB3YXJuLCBUeXBlcyB0eXBlcyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBUaGlzIGNsYXNzIGVuY2Fwc3VsYXRlcyBhIGJhc2ljIGluY29ycG9yYXRpb24gb3BlcmF0aW9uOyBpbmNvcnBvcmF0aW9uCiAgICAgKiBvcGVyYXRpb25zIHRha2VzIHR3byB0eXBlIG9wZXJhbmRzIGFuZCBhIGtpbmQuIEVhY2ggb3BlcmF0aW9uIHBlcmZvcm1lZAogICAgICogZHVyaW5nIGFuIGluY29ycG9yYXRpb24gcm91bmQgaXMgc3RvcmVkIGluIGEgY2FjaGUsIHNvIHRoYXQgb3BlcmF0aW9ucwogICAgICogYXJlIG5vdCBleGVjdXRlZCB1bm5lY2Vzc2FyaWx5ICh3aGljaCB3b3VsZCBwb3RlbnRpYWxseSBsZWFkIHRvIGFkZGluZwogICAgICogc2FtZSBib3VuZHMgb3ZlciBhbmQgb3ZlcikuCiAgICAgKi8KICAgIGNsYXNzIEluY29ycG9yYXRpb25CaW5hcnlPcCB7CgogICAgICAgIEluY29ycG9yYXRpb25CaW5hcnlPcEtpbmQgb3BLaW5kOwogICAgICAgIFR5cGUgb3AxOwogICAgICAgIFR5cGUgb3AyOwoKICAgICAgICBJbmNvcnBvcmF0aW9uQmluYXJ5T3AoSW5jb3Jwb3JhdGlvbkJpbmFyeU9wS2luZCBvcEtpbmQsIFR5cGUgb3AxLCBUeXBlIG9wMikgewogICAgICAgICAgICB0aGlzLm9wS2luZCA9IG9wS2luZDsKICAgICAgICAgICAgdGhpcy5vcDEgPSBvcDE7CiAgICAgICAgICAgIHRoaXMub3AyID0gb3AyOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvKSB7CiAgICAgICAgICAgIGlmICghKG8gaW5zdGFuY2VvZiBJbmNvcnBvcmF0aW9uQmluYXJ5T3ApKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBJbmNvcnBvcmF0aW9uQmluYXJ5T3AgdGhhdCA9IChJbmNvcnBvcmF0aW9uQmluYXJ5T3ApbzsKICAgICAgICAgICAgICAgIHJldHVybiBvcEtpbmQgPT0gdGhhdC5vcEtpbmQgJiYKICAgICAgICAgICAgICAgICAgICAgICAgdHlwZXMuaXNTYW1lVHlwZShvcDEsIHRoYXQub3AxLCB0cnVlKSAmJgogICAgICAgICAgICAgICAgICAgICAgICB0eXBlcy5pc1NhbWVUeXBlKG9wMiwgdGhhdC5vcDIsIHRydWUpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICAgICAgICBpbnQgcmVzdWx0ID0gb3BLaW5kLmhhc2hDb2RlKCk7CiAgICAgICAgICAgIHJlc3VsdCAqPSAxMjc7CiAgICAgICAgICAgIHJlc3VsdCArPSB0eXBlcy5oYXNoQ29kZShvcDEpOwogICAgICAgICAgICByZXN1bHQgKj0gMTI3OwogICAgICAgICAgICByZXN1bHQgKz0gdHlwZXMuaGFzaENvZGUob3AyKTsKICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CgogICAgICAgIGJvb2xlYW4gYXBwbHkoV2FybmVyIHdhcm4pIHsKICAgICAgICAgICAgcmV0dXJuIG9wS2luZC5hcHBseShvcDEsIG9wMiwgd2FybiwgdHlwZXMpOwogICAgICAgIH0KICAgIH0KCiAgICAvKiogYW4gaW5jb3Jwb3JhdGlvbiBjYWNoZSBrZWVwcyB0cmFjayBvZiBhbGwgZXhlY3V0ZWQgaW5jb3Jwb3JhdGlvbi1yZWxhdGVkIG9wZXJhdGlvbnMgKi8KICAgIE1hcDxJbmNvcnBvcmF0aW9uQmluYXJ5T3AsIEJvb2xlYW4+IGluY29ycG9yYXRpb25DYWNoZSA9IG5ldyBIYXNoTWFwPD4oKTsKCiAgICBwcm90ZWN0ZWQgc3RhdGljIGNsYXNzIEJvdW5kRmlsdGVyIGltcGxlbWVudHMgRmlsdGVyPFR5cGU+IHsKCiAgICAgICAgSW5mZXJlbmNlQ29udGV4dCBpbmZlcmVuY2VDb250ZXh0OwoKICAgICAgICBwdWJsaWMgQm91bmRGaWx0ZXIoSW5mZXJlbmNlQ29udGV4dCBpbmZlcmVuY2VDb250ZXh0KSB7CiAgICAgICAgICAgIHRoaXMuaW5mZXJlbmNlQ29udGV4dCA9IGluZmVyZW5jZUNvbnRleHQ7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgYm9vbGVhbiBhY2NlcHRzKFR5cGUgdCkgewogICAgICAgICAgICByZXR1cm4gIXQuaXNFcnJvbmVvdXMoKSAmJiAhaW5mZXJlbmNlQ29udGV4dC5mcmVlKHQpICYmCiAgICAgICAgICAgICAgICAgICAgIXQuaGFzVGFnKEJPVCk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogSW5jb3Jwb3JhdGlvbiBlcnJvcjogbWlzbWF0Y2ggYmV0d2VlbiBpbmZlcnJlZCB0eXBlIGFuZCBnaXZlbiBib3VuZC4KICAgICAqLwogICAgdm9pZCByZXBvcnRJbnN0RXJyb3IoVW5kZXRWYXIgdXYsIEluZmVyZW5jZUJvdW5kIGliKSB7CiAgICAgICAgcmVwb3J0SW5mZXJlbmNlRXJyb3IoCiAgICAgICAgICAgICAgICBTdHJpbmcuZm9ybWF0KCJpbmZlcnJlZC5kby5ub3QuY29uZm9ybS50by4lcy5ib3VuZHMiLCBTdHJpbmdVdGlscy50b0xvd2VyQ2FzZShpYi5uYW1lKCkpKSwKICAgICAgICAgICAgICAgIHV2LmdldEluc3QoKSwKICAgICAgICAgICAgICAgIHV2LmdldEJvdW5kcyhpYikpOwogICAgfQoKICAgIC8qKgogICAgICogSW5jb3Jwb3JhdGlvbiBlcnJvcjogbWlzbWF0Y2ggYmV0d2VlbiB0d28gKG9yIG1vcmUpIGJvdW5kcyBvZiBzYW1lIGtpbmQuCiAgICAgKi8KICAgIHZvaWQgcmVwb3J0Qm91bmRFcnJvcihVbmRldFZhciB1diwgSW5mZXJlbmNlQm91bmQgaWIpIHsKICAgICAgICByZXBvcnRJbmZlcmVuY2VFcnJvcigKICAgICAgICAgICAgICAgIFN0cmluZy5mb3JtYXQoImluY29tcGF0aWJsZS4lcy5ib3VuZHMiLCBTdHJpbmdVdGlscy50b0xvd2VyQ2FzZShpYi5uYW1lKCkpKSwKICAgICAgICAgICAgICAgIHV2LnF0eXBlLAogICAgICAgICAgICAgICAgdXYuZ2V0Qm91bmRzKGliKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBJbmNvcnBvcmF0aW9uIGVycm9yOiBtaXNtYXRjaCBiZXR3ZWVuIHR3byAob3IgbW9yZSkgYm91bmRzIG9mIGRpZmZlcmVudCBraW5kcy4KICAgICAqLwogICAgdm9pZCByZXBvcnRCb3VuZEVycm9yKFVuZGV0VmFyIHV2LCBJbmZlcmVuY2VCb3VuZCBpYjEsIEluZmVyZW5jZUJvdW5kIGliMikgewogICAgICAgIHJlcG9ydEluZmVyZW5jZUVycm9yKAogICAgICAgICAgICAgICAgU3RyaW5nLmZvcm1hdCgiaW5jb21wYXRpYmxlLiVzLiVzLmJvdW5kcyIsCiAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZ1V0aWxzLnRvTG93ZXJDYXNlKGliMS5uYW1lKCkpLAogICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmdVdGlscy50b0xvd2VyQ2FzZShpYjIubmFtZSgpKSksCiAgICAgICAgICAgICAgICB1di5xdHlwZSwKICAgICAgICAgICAgICAgIHV2LmdldEJvdW5kcyhpYjEpLAogICAgICAgICAgICAgICAgdXYuZ2V0Qm91bmRzKGliMikpOwogICAgfQoKICAgIC8qKgogICAgICogSGVscGVyIG1ldGhvZDogcmVwb3J0cyBhbiBpbmZlcmVuY2UgZXJyb3IuCiAgICAgKi8KICAgIHZvaWQgcmVwb3J0SW5mZXJlbmNlRXJyb3IoU3RyaW5nIGtleSwgT2JqZWN0Li4uIGFyZ3MpIHsKICAgICAgICB0aHJvdyBpbmZlcmVuY2VFeGNlcHRpb24uc2V0TWVzc2FnZShrZXksIGFyZ3MpOwogICAgfQogICAgLy8gPC9lZGl0b3ItZm9sZD4KCiAgICAvLyA8ZWRpdG9yLWZvbGQgZGVmYXVsdHN0YXRlPSJjb2xsYXBzZWQiIGRlc2M9IkluZmVyZW5jZSBlbmdpbmUiPgogICAgLyoqCiAgICAgKiBHcmFwaCBpbmZlcmVuY2Ugc3RyYXRlZ3kgLSBhY3QgYXMgYW4gaW5wdXQgdG8gdGhlIGluZmVyZW5jZSBzb2x2ZXI7IGEgc3RyYXRlZ3kgaXMKICAgICAqIGNvbXBvc2VkIG9mIHR3byBpbmdyZWRpZW50czogKGkpIGZpbmQgYSBub2RlIHRvIHNvbHZlIGluIHRoZSBpbmZlcmVuY2UgZ3JhcGgsCiAgICAgKiBhbmQgKGlpKSB0ZWxsIHRoIGVuZ2luZSB3aGVuIHdlIGFyZSBkb25lIGZpeGluZyBpbmZlcmVuY2UgdmFyaWFibGVzCiAgICAgKi8KICAgIGludGVyZmFjZSBHcmFwaFN0cmF0ZWd5IHsKCiAgICAgICAgLyoqCiAgICAgICAgICogQSBOb2RlTm90Rm91bmRFeGNlcHRpb24gaXMgdGhyb3duIHdoZW5ldmVyIGFuIGluZmVyZW5jZSBzdHJhdGVneSBmYWlscwogICAgICAgICAqIHRvIHBpY2sgdGhlIG5leHQgbm9kZSB0byBzb2x2ZSBpbiB0aGUgaW5mZXJlbmNlIGdyYXBoLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgTm9kZU5vdEZvdW5kRXhjZXB0aW9uIGV4dGVuZHMgUnVudGltZUV4Y2VwdGlvbiB7CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDA7CgogICAgICAgICAgICBJbmZlcmVuY2VHcmFwaCBncmFwaDsKCiAgICAgICAgICAgIHB1YmxpYyBOb2RlTm90Rm91bmRFeGNlcHRpb24oSW5mZXJlbmNlR3JhcGggZ3JhcGgpIHsKICAgICAgICAgICAgICAgIHRoaXMuZ3JhcGggPSBncmFwaDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiBQaWNrIHRoZSBuZXh0IG5vZGUgKGxlYWYpIHRvIHNvbHZlIGluIHRoZSBncmFwaAogICAgICAgICAqLwogICAgICAgIE5vZGUgcGlja05vZGUoSW5mZXJlbmNlR3JhcGggZykgdGhyb3dzIE5vZGVOb3RGb3VuZEV4Y2VwdGlvbjsKICAgICAgICAvKioKICAgICAgICAgKiBJcyB0aGlzIHRoZSBsYXN0IHN0ZXA/CiAgICAgICAgICovCiAgICAgICAgYm9vbGVhbiBkb25lKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBTaW1wbGUgc29sdmVyIHN0cmF0ZWd5IGNsYXNzIHRoYXQgbG9jYXRlcyBhbGwgbGVhdmVzIGluc2lkZSBhIGdyYXBoCiAgICAgKiBhbmQgcGlja3MgdGhlIGZpcnN0IGxlYWYgYXMgdGhlIG5leHQgbm9kZSB0byBzb2x2ZQogICAgICovCiAgICBhYnN0cmFjdCBjbGFzcyBMZWFmU29sdmVyIGltcGxlbWVudHMgR3JhcGhTdHJhdGVneSB7CiAgICAgICAgcHVibGljIE5vZGUgcGlja05vZGUoSW5mZXJlbmNlR3JhcGggZykgewogICAgICAgICAgICBpZiAoZy5ub2Rlcy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICAgIC8vc2hvdWxkIG5vdCBoYXBwZW4KICAgICAgICAgICAgICAgIHRocm93IG5ldyBOb2RlTm90Rm91bmRFeGNlcHRpb24oZyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGcubm9kZXMuZ2V0KDApOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFRoaXMgc29sdmVyIHVzZXMgYW4gaGV1cmlzdGljIHRvIHBpY2sgdGhlIGJlc3QgbGVhZiAtIHRoZSBoZXVyaXN0aWMKICAgICAqIHRyaWVzIHRvIHNlbGVjdCB0aGUgbm9kZSB0aGF0IGhhcyBtYXhpbWFsIHByb2JhYmlsaXR5IHRvIGNvbnRhaW4gb25lCiAgICAgKiBvciBtb3JlIGluZmVyZW5jZSB2YXJpYWJsZXMgaW4gYSBnaXZlbiBsaXN0CiAgICAgKi8KICAgIGFic3RyYWN0IGNsYXNzIEJlc3RMZWFmU29sdmVyIGV4dGVuZHMgTGVhZlNvbHZlciB7CgogICAgICAgIC8qKiBsaXN0IG9mIGl2YXJzIG9mIHdoaWNoIGF0IGxlYXN0IG9uZSBtdXN0IGJlIHNvbHZlZCAqLwogICAgICAgIExpc3Q8VHlwZT4gdmFyc1RvU29sdmU7CgogICAgICAgIEJlc3RMZWFmU29sdmVyKExpc3Q8VHlwZT4gdmFyc1RvU29sdmUpIHsKICAgICAgICAgICAgdGhpcy52YXJzVG9Tb2x2ZSA9IHZhcnNUb1NvbHZlOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogQ29tcHV0ZXMgYSBwYXRoIHRoYXQgZ29lcyBmcm9tIGEgZ2l2ZW4gbm9kZSB0byB0aGUgbGVhZnMgaW4gdGhlIGdyYXBoLgogICAgICAgICAqIFR5cGljYWxseSB0aGlzIHdpbGwgc3RhcnQgZnJvbSBhIG5vZGUgY29udGFpbmluZyBhIHZhcmlhYmxlIGluCiAgICAgICAgICoge0Bjb2RlIHZhcnNUb1NvbHZlfS4gRm9yIGFueSBnaXZlbiBwYXRoLCB0aGUgY29zdCBpcyBjb21wdXRlZCBhcyB0aGUgdG90YWwKICAgICAgICAgKiBudW1iZXIgb2YgdHlwZS12YXJpYWJsZXMgdGhhdCBzaG91bGQgYmUgZWFnZXJseSBpbnN0YW50aWF0ZWQgYWNyb3NzIHRoYXQgcGF0aC4KICAgICAgICAgKi8KICAgICAgICBQYWlyPExpc3Q8Tm9kZT4sIEludGVnZXI+IGNvbXB1dGVUcmVlVG9MZWFmcyhOb2RlIG4pIHsKICAgICAgICAgICAgUGFpcjxMaXN0PE5vZGU+LCBJbnRlZ2VyPiBjYWNoZWRQYXRoID0gdHJlZUNhY2hlLmdldChuKTsKICAgICAgICAgICAgaWYgKGNhY2hlZFBhdGggPT0gbnVsbCkgewogICAgICAgICAgICAgICAgLy9jYWNoZSBtaXNzCiAgICAgICAgICAgICAgICBpZiAobi5pc0xlYWYoKSkgewogICAgICAgICAgICAgICAgICAgIC8vaWYgbGVhZiwgc3RvcAogICAgICAgICAgICAgICAgICAgIGNhY2hlZFBhdGggPSBuZXcgUGFpcjw+KExpc3Qub2YobiksIG4uZGF0YS5sZW5ndGgoKSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIC8vaWYgbm9uLWxlYWYsIHByb2NlZWQgcmVjdXJzaXZlbHkKICAgICAgICAgICAgICAgICAgICBQYWlyPExpc3Q8Tm9kZT4sIEludGVnZXI+IHBhdGggPSBuZXcgUGFpcjw+KExpc3Qub2YobiksIG4uZGF0YS5sZW5ndGgoKSk7CiAgICAgICAgICAgICAgICAgICAgZm9yIChOb2RlIG4yIDogbi5nZXRBbGxEZXBlbmRlbmNpZXMoKSkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAobjIgPT0gbikgY29udGludWU7CiAgICAgICAgICAgICAgICAgICAgICAgIFBhaXI8TGlzdDxOb2RlPiwgSW50ZWdlcj4gc3VicGF0aCA9IGNvbXB1dGVUcmVlVG9MZWFmcyhuMik7CiAgICAgICAgICAgICAgICAgICAgICAgIHBhdGggPSBuZXcgUGFpcjw+KHBhdGguZnN0LnByZXBlbmRMaXN0KHN1YnBhdGguZnN0KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGF0aC5zbmQgKyBzdWJwYXRoLnNuZCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGNhY2hlZFBhdGggPSBwYXRoOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgLy9zYXZlIHJlc3VsdHMgaW4gY2FjaGUKICAgICAgICAgICAgICAgIHRyZWVDYWNoZS5wdXQobiwgY2FjaGVkUGF0aCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGNhY2hlZFBhdGg7CiAgICAgICAgfQoKICAgICAgICAvKiogY2FjaGUgdXNlZCB0byBhdm9pZCByZWR1bmRhbnQgY29tcHV0YXRpb24gb2YgdHJlZSBjb3N0cyAqLwogICAgICAgIGZpbmFsIE1hcDxOb2RlLCBQYWlyPExpc3Q8Tm9kZT4sIEludGVnZXI+PiB0cmVlQ2FjaGUgPSBuZXcgSGFzaE1hcDw+KCk7CgogICAgICAgIC8qKiBjb25zdGFudCB2YWx1ZSB1c2VkIHRvIG1hcmsgbm9uLWV4aXN0ZW50IHBhdGhzICovCiAgICAgICAgZmluYWwgUGFpcjxMaXN0PE5vZGU+LCBJbnRlZ2VyPiBub1BhdGggPSBuZXcgUGFpcjw+KG51bGwsIEludGVnZXIuTUFYX1ZBTFVFKTsKCiAgICAgICAgLyoqCiAgICAgICAgICogUGljayB0aGUgbGVhZiB0aGF0IG1pbmltaXplIGNvc3QKICAgICAgICAgKi8KICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgTm9kZSBwaWNrTm9kZShmaW5hbCBJbmZlcmVuY2VHcmFwaCBnKSB7CiAgICAgICAgICAgIHRyZWVDYWNoZS5jbGVhcigpOyAvL2dyYXBoIGNoYW5nZXMgYXQgZXZlcnkgc3RlcCAtIGNhY2hlIG11c3QgYmUgY2xlYXJlZAogICAgICAgICAgICBQYWlyPExpc3Q8Tm9kZT4sIEludGVnZXI+IGJlc3RQYXRoID0gbm9QYXRoOwogICAgICAgICAgICBmb3IgKE5vZGUgbiA6IGcubm9kZXMpIHsKICAgICAgICAgICAgICAgIGlmICghQ29sbGVjdGlvbnMuZGlzam9pbnQobi5kYXRhLCB2YXJzVG9Tb2x2ZSkpIHsKICAgICAgICAgICAgICAgICAgICBQYWlyPExpc3Q8Tm9kZT4sIEludGVnZXI+IHBhdGggPSBjb21wdXRlVHJlZVRvTGVhZnMobik7CiAgICAgICAgICAgICAgICAgICAgLy9kaXNjYXJkIGFsbCBwYXRocyBjb250YWluaW5nIGF0IGxlYXN0IGEgbm9kZSBpbiB0aGUKICAgICAgICAgICAgICAgICAgICAvL2Nsb3N1cmUgY29tcHV0ZWQgYWJvdmUKICAgICAgICAgICAgICAgICAgICBpZiAocGF0aC5zbmQgPCBiZXN0UGF0aC5zbmQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgYmVzdFBhdGggPSBwYXRoOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoYmVzdFBhdGggPT0gbm9QYXRoKSB7CiAgICAgICAgICAgICAgICAvL25vIHBhdGggbGVhZHMgdGhlcmUKICAgICAgICAgICAgICAgIHRocm93IG5ldyBOb2RlTm90Rm91bmRFeGNlcHRpb24oZyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGJlc3RQYXRoLmZzdC5oZWFkOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFRoZSBpbmZlcmVuY2UgcHJvY2VzcyBjYW4gYmUgdGhvdWdodCBvZiBhcyBhIHNlcXVlbmNlIG9mIHN0ZXBzLiBFYWNoIHN0ZXAKICAgICAqIGluc3RhbnRpYXRlcyBhbiBpbmZlcmVuY2UgdmFyaWFibGUgdXNpbmcgYSBzdWJzZXQgb2YgdGhlIGluZmVyZW5jZSB2YXJpYWJsZQogICAgICogYm91bmRzLCBpZiBjZXJ0YWluIGNvbmRpdGlvbiBhcmUgbWV0LiBEZWNpc2lvbnMgc3VjaCBhcyB0aGUgc2VxdWVuY2UgaW4gd2hpY2gKICAgICAqIHN0ZXBzIGFyZSBhcHBsaWVkLCBvciB3aGljaCBzdGVwcyBhcmUgdG8gYmUgYXBwbGllZCBhcmUgbGVmdCB0byB0aGUgaW5mZXJlbmNlIGVuZ2luZS4KICAgICAqLwogICAgZW51bSBJbmZlcmVuY2VTdGVwIHsKCiAgICAgICAgLyoqCiAgICAgICAgICogSW5zdGFudGlhdGUgYW4gaW5mZXJlbmNlIHZhcmlhYmxlcyB1c2luZyBvbmUgb2YgaXRzIChncm91bmQpIGVxdWFsaXR5CiAgICAgICAgICogY29uc3RyYWludHMKICAgICAgICAgKi8KICAgICAgICBFUShJbmZlcmVuY2VCb3VuZC5FUSkgewogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgVHlwZSBzb2x2ZShVbmRldFZhciB1diwgSW5mZXJlbmNlQ29udGV4dCBpbmZlcmVuY2VDb250ZXh0KSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmlsdGVyQm91bmRzKHV2LCBpbmZlcmVuY2VDb250ZXh0KS5oZWFkOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAvKioKICAgICAgICAgKiBJbnN0YW50aWF0ZSBhbiBpbmZlcmVuY2UgdmFyaWFibGVzIHVzaW5nIGl0cyAoZ3JvdW5kKSBsb3dlciBib3VuZHMuIFN1Y2gKICAgICAgICAgKiBib3VuZHMgYXJlIG1lcmdlZCB0b2dldGhlciB1c2luZyBsdWIoKS4KICAgICAgICAgKi8KICAgICAgICBMT1dFUihJbmZlcmVuY2VCb3VuZC5MT1dFUikgewogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgVHlwZSBzb2x2ZShVbmRldFZhciB1diwgSW5mZXJlbmNlQ29udGV4dCBpbmZlcmVuY2VDb250ZXh0KSB7CiAgICAgICAgICAgICAgICBJbmZlciBpbmZlciA9IGluZmVyZW5jZUNvbnRleHQuaW5mZXI7CiAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IGxvYm91bmRzID0gZmlsdGVyQm91bmRzKHV2LCBpbmZlcmVuY2VDb250ZXh0KTsKICAgICAgICAgICAgICAgIC8vbm90ZTogbG9ib3VuZHMgc2hvdWxkIGhhdmUgYXQgbGVhc3Qgb25lIGVsZW1lbnQKICAgICAgICAgICAgICAgIFR5cGUgb3dudHlwZSA9IGxvYm91bmRzLnRhaWwudGFpbCA9PSBudWxsICA/IGxvYm91bmRzLmhlYWQgOiBpbmZlci50eXBlcy5sdWIobG9ib3VuZHMpOwogICAgICAgICAgICAgICAgaWYgKG93bnR5cGUuaXNQcmltaXRpdmUoKSB8fCBvd250eXBlLmhhc1RhZyhFUlJPUikpIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBpbmZlci5pbmZlcmVuY2VFeGNlcHRpb24KICAgICAgICAgICAgICAgICAgICAgICAgLnNldE1lc3NhZ2UoIm5vLnVuaXF1ZS5taW5pbWFsLmluc3RhbmNlLmV4aXN0cyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHV2LnF0eXBlLCBsb2JvdW5kcyk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBvd250eXBlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAvKioKICAgICAgICAgKiBJbmZlciB1bmluc3RhbnRpYXRlZC91bmJvdW5kIGluZmVyZW5jZSB2YXJpYWJsZXMgb2NjdXJyaW5nIGluICd0aHJvd3MnCiAgICAgICAgICogY2xhdXNlIGFzIFJ1bnRpbWVFeGNlcHRpb24KICAgICAgICAgKi8KICAgICAgICBUSFJPV1MoSW5mZXJlbmNlQm91bmQuVVBQRVIpIHsKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHB1YmxpYyBib29sZWFuIGFjY2VwdHMoVW5kZXRWYXIgdCwgSW5mZXJlbmNlQ29udGV4dCBpbmZlcmVuY2VDb250ZXh0KSB7CiAgICAgICAgICAgICAgICBpZiAoIXQuaXNUaHJvd3MoKSkgewogICAgICAgICAgICAgICAgICAgIC8vbm90IGEgdGhyb3dzIHVuZGV0IHZhcgogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIFR5cGVzIHR5cGVzID0gaW5mZXJlbmNlQ29udGV4dC50eXBlczsKICAgICAgICAgICAgICAgIFN5bXRhYiBzeW1zID0gaW5mZXJlbmNlQ29udGV4dC5pbmZlci5zeW1zOwogICAgICAgICAgICAgICAgcmV0dXJuIHQuZ2V0Qm91bmRzKEluZmVyZW5jZUJvdW5kLlVQUEVSKS5zdHJlYW0oKQogICAgICAgICAgICAgICAgICAgICAgICAuZmlsdGVyKGIgLT4gIWluZmVyZW5jZUNvbnRleHQuZnJlZShiKSkKICAgICAgICAgICAgICAgICAgICAgICAgLmFsbE1hdGNoKHUgLT4gdHlwZXMuaXNTdWJ0eXBlKHN5bXMucnVudGltZUV4Y2VwdGlvblR5cGUsIHUpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIFR5cGUgc29sdmUoVW5kZXRWYXIgdXYsIEluZmVyZW5jZUNvbnRleHQgaW5mZXJlbmNlQ29udGV4dCkgewogICAgICAgICAgICAgICAgcmV0dXJuIGluZmVyZW5jZUNvbnRleHQuaW5mZXIuc3ltcy5ydW50aW1lRXhjZXB0aW9uVHlwZTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgLyoqCiAgICAgICAgICogSW5zdGFudGlhdGUgYW4gaW5mZXJlbmNlIHZhcmlhYmxlcyB1c2luZyBpdHMgKGdyb3VuZCkgdXBwZXIgYm91bmRzLiBTdWNoCiAgICAgICAgICogYm91bmRzIGFyZSBtZXJnZWQgdG9nZXRoZXIgdXNpbmcgZ2xiKCkuCiAgICAgICAgICovCiAgICAgICAgVVBQRVIoSW5mZXJlbmNlQm91bmQuVVBQRVIpIHsKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIFR5cGUgc29sdmUoVW5kZXRWYXIgdXYsIEluZmVyZW5jZUNvbnRleHQgaW5mZXJlbmNlQ29udGV4dCkgewogICAgICAgICAgICAgICAgSW5mZXIgaW5mZXIgPSBpbmZlcmVuY2VDb250ZXh0LmluZmVyOwogICAgICAgICAgICAgICAgTGlzdDxUeXBlPiBoaWJvdW5kcyA9IGZpbHRlckJvdW5kcyh1diwgaW5mZXJlbmNlQ29udGV4dCk7CiAgICAgICAgICAgICAgICAvL25vdGU6IGhpYm91bmRzIHNob3VsZCBoYXZlIGF0IGxlYXN0IG9uZSBlbGVtZW50CiAgICAgICAgICAgICAgICBUeXBlIG93bnR5cGUgPSBoaWJvdW5kcy50YWlsLnRhaWwgPT0gbnVsbCAgPyBoaWJvdW5kcy5oZWFkIDogaW5mZXIudHlwZXMuZ2xiKGhpYm91bmRzKTsKICAgICAgICAgICAgICAgIGlmIChvd250eXBlLmlzUHJpbWl0aXZlKCkgfHwgb3dudHlwZS5oYXNUYWcoRVJST1IpKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgaW5mZXIuaW5mZXJlbmNlRXhjZXB0aW9uCiAgICAgICAgICAgICAgICAgICAgICAgIC5zZXRNZXNzYWdlKCJuby51bmlxdWUubWF4aW1hbC5pbnN0YW5jZS5leGlzdHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1di5xdHlwZSwgaGlib3VuZHMpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gb3dudHlwZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgLyoqCiAgICAgICAgICogTGlrZSB0aGUgZm9ybWVyOyB0aGUgb25seSBkaWZmZXJlbmNlIGlzIHRoYXQgdGhpcyBzdGVwIGNhbiBvbmx5IGJlIGFwcGxpZWQKICAgICAgICAgKiBpZiBhbGwgdXBwZXIgYm91bmRzIGFyZSBncm91bmQuCiAgICAgICAgICovCiAgICAgICAgVVBQRVJfTEVHQUNZKEluZmVyZW5jZUJvdW5kLlVQUEVSKSB7CiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgYm9vbGVhbiBhY2NlcHRzKFVuZGV0VmFyIHQsIEluZmVyZW5jZUNvbnRleHQgaW5mZXJlbmNlQ29udGV4dCkgewogICAgICAgICAgICAgICAgcmV0dXJuICFpbmZlcmVuY2VDb250ZXh0LmZyZWUodC5nZXRCb3VuZHMoaWIpKSAmJiAhdC5pc0NhcHR1cmVkKCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBUeXBlIHNvbHZlKFVuZGV0VmFyIHV2LCBJbmZlcmVuY2VDb250ZXh0IGluZmVyZW5jZUNvbnRleHQpIHsKICAgICAgICAgICAgICAgIHJldHVybiBVUFBFUi5zb2x2ZSh1diwgaW5mZXJlbmNlQ29udGV4dCk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIC8qKgogICAgICAgICAqIExpa2UgdGhlIGZvcm1lcjsgdGhlIG9ubHkgZGlmZmVyZW5jZSBpcyB0aGF0IHRoaXMgc3RlcCBjYW4gb25seSBiZSBhcHBsaWVkCiAgICAgICAgICogaWYgYWxsIHVwcGVyL2xvd2VyIGJvdW5kcyBhcmUgZ3JvdW5kLgogICAgICAgICAqLwogICAgICAgIENBUFRVUkVEKEluZmVyZW5jZUJvdW5kLlVQUEVSKSB7CiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgYm9vbGVhbiBhY2NlcHRzKFVuZGV0VmFyIHQsIEluZmVyZW5jZUNvbnRleHQgaW5mZXJlbmNlQ29udGV4dCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHQuaXNDYXB0dXJlZCgpICYmCiAgICAgICAgICAgICAgICAgICAgICAgICFpbmZlcmVuY2VDb250ZXh0LmZyZWUodC5nZXRCb3VuZHMoSW5mZXJlbmNlQm91bmQuVVBQRVIsIEluZmVyZW5jZUJvdW5kLkxPV0VSKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBUeXBlIHNvbHZlKFVuZGV0VmFyIHV2LCBJbmZlcmVuY2VDb250ZXh0IGluZmVyZW5jZUNvbnRleHQpIHsKICAgICAgICAgICAgICAgIEluZmVyIGluZmVyID0gaW5mZXJlbmNlQ29udGV4dC5pbmZlcjsKICAgICAgICAgICAgICAgIFR5cGUgdXBwZXIgPSBVUFBFUi5maWx0ZXJCb3VuZHModXYsIGluZmVyZW5jZUNvbnRleHQpLm5vbkVtcHR5KCkgPwogICAgICAgICAgICAgICAgICAgICAgICBVUFBFUi5zb2x2ZSh1diwgaW5mZXJlbmNlQ29udGV4dCkgOgogICAgICAgICAgICAgICAgICAgICAgICBpbmZlci5zeW1zLm9iamVjdFR5cGU7CiAgICAgICAgICAgICAgICBUeXBlIGxvd2VyID0gTE9XRVIuZmlsdGVyQm91bmRzKHV2LCBpbmZlcmVuY2VDb250ZXh0KS5ub25FbXB0eSgpID8KICAgICAgICAgICAgICAgICAgICAgICAgTE9XRVIuc29sdmUodXYsIGluZmVyZW5jZUNvbnRleHQpIDoKICAgICAgICAgICAgICAgICAgICAgICAgaW5mZXIuc3ltcy5ib3RUeXBlOwogICAgICAgICAgICAgICAgQ2FwdHVyZWRUeXBlIHByZXZDYXB0dXJlZCA9IChDYXB0dXJlZFR5cGUpdXYucXR5cGU7CiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IENhcHR1cmVkVHlwZShwcmV2Q2FwdHVyZWQudHN5bS5uYW1lLCBwcmV2Q2FwdHVyZWQudHN5bS5vd25lciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVwcGVyLCBsb3dlciwgcHJldkNhcHR1cmVkLndpbGRjYXJkKTsKICAgICAgICAgICAgfQogICAgICAgIH07CgogICAgICAgIGZpbmFsIEluZmVyZW5jZUJvdW5kIGliOwoKICAgICAgICBJbmZlcmVuY2VTdGVwKEluZmVyZW5jZUJvdW5kIGliKSB7CiAgICAgICAgICAgIHRoaXMuaWIgPSBpYjsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIEZpbmQgYW4gaW5zdGFudGlhdGVkIHR5cGUgZm9yIGEgZ2l2ZW4gaW5mZXJlbmNlIHZhcmlhYmxlIHdpdGhpbgogICAgICAgICAqIGEgZ2l2ZW4gaW5mZXJlbmNlIGNvbnRleHQKICAgICAgICAgKi8KICAgICAgICBhYnN0cmFjdCBUeXBlIHNvbHZlKFVuZGV0VmFyIHV2LCBJbmZlcmVuY2VDb250ZXh0IGluZmVyZW5jZUNvbnRleHQpOwoKICAgICAgICAvKioKICAgICAgICAgKiBDYW4gdGhlIGluZmVyZW5jZSB2YXJpYWJsZSBiZSBpbnN0YW50aWF0ZWQgdXNpbmcgdGhpcyBzdGVwPwogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBib29sZWFuIGFjY2VwdHMoVW5kZXRWYXIgdCwgSW5mZXJlbmNlQ29udGV4dCBpbmZlcmVuY2VDb250ZXh0KSB7CiAgICAgICAgICAgIHJldHVybiBmaWx0ZXJCb3VuZHModCwgaW5mZXJlbmNlQ29udGV4dCkubm9uRW1wdHkoKSAmJiAhdC5pc0NhcHR1cmVkKCk7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBSZXR1cm4gdGhlIHN1YnNldCBvZiBncm91bmQgYm91bmRzIGluIGEgZ2l2ZW4gYm91bmQgc2V0IChpLmUuIGVxL2xvd2VyL3VwcGVyKQogICAgICAgICAqLwogICAgICAgIExpc3Q8VHlwZT4gZmlsdGVyQm91bmRzKFVuZGV0VmFyIHV2LCBJbmZlcmVuY2VDb250ZXh0IGluZmVyZW5jZUNvbnRleHQpIHsKICAgICAgICAgICAgcmV0dXJuIFR5cGUuZmlsdGVyKHV2LmdldEJvdW5kcyhpYiksIG5ldyBCb3VuZEZpbHRlcihpbmZlcmVuY2VDb250ZXh0KSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogVGhpcyBlbnVtZXJhdGlvbiBkZWZpbmVzIHRoZSBzZXF1ZW5jZSBvZiBzdGVwcyB0byBiZSBhcHBsaWVkIHdoZW4gdGhlCiAgICAgKiBzb2x2ZXIgd29ya3MgaW4gbGVnYWN5IG1vZGUuIFRoZSBzdGVwcyBpbiB0aGlzIGVudW1lcmF0aW9uIHJlZmxlY3QKICAgICAqIHRoZSBiZWhhdmlvciBvZiBvbGQgaW5mZXJlbmNlIHJvdXRpbmUgKHNlZSBKTFMgU0UgNyAxNS4xMi4yLjcvMTUuMTIuMi44KS4KICAgICAqLwogICAgZW51bSBMZWdhY3lJbmZlcmVuY2VTdGVwcyB7CgogICAgICAgIEVRX0xPV0VSKEVudW1TZXQub2YoSW5mZXJlbmNlU3RlcC5FUSwgSW5mZXJlbmNlU3RlcC5MT1dFUikpLAogICAgICAgIEVRX1VQUEVSKEVudW1TZXQub2YoSW5mZXJlbmNlU3RlcC5FUSwgSW5mZXJlbmNlU3RlcC5VUFBFUl9MRUdBQ1kpKTsKCiAgICAgICAgZmluYWwgRW51bVNldDxJbmZlcmVuY2VTdGVwPiBzdGVwczsKCiAgICAgICAgTGVnYWN5SW5mZXJlbmNlU3RlcHMoRW51bVNldDxJbmZlcmVuY2VTdGVwPiBzdGVwcykgewogICAgICAgICAgICB0aGlzLnN0ZXBzID0gc3RlcHM7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogVGhpcyBlbnVtZXJhdGlvbiBkZWZpbmVzIHRoZSBzZXF1ZW5jZSBvZiBzdGVwcyB0byBiZSBhcHBsaWVkIHdoZW4gdGhlCiAgICAgKiBncmFwaCBzb2x2ZXIgaXMgdXNlZC4gVGhpcyBvcmRlciBpcyBkZWZpbmVkIHNvIGFzIHRvIG1heGltaXplIGNvbXBhdGliaWxpdHkKICAgICAqIHcuci50LiBvbGQgaW5mZXJlbmNlIHJvdXRpbmUgKHNlZSBKTFMgU0UgNyAxNS4xMi4yLjcvMTUuMTIuMi44KS4KICAgICAqLwogICAgZW51bSBHcmFwaEluZmVyZW5jZVN0ZXBzIHsKCiAgICAgICAgRVEoRW51bVNldC5vZihJbmZlcmVuY2VTdGVwLkVRKSksCiAgICAgICAgRVFfTE9XRVIoRW51bVNldC5vZihJbmZlcmVuY2VTdGVwLkVRLCBJbmZlcmVuY2VTdGVwLkxPV0VSKSksCiAgICAgICAgRVFfTE9XRVJfVEhST1dTX1VQUEVSX0NBUFRVUkVEKEVudW1TZXQub2YoSW5mZXJlbmNlU3RlcC5FUSwgSW5mZXJlbmNlU3RlcC5MT1dFUiwgSW5mZXJlbmNlU3RlcC5VUFBFUiwgSW5mZXJlbmNlU3RlcC5USFJPV1MsIEluZmVyZW5jZVN0ZXAuQ0FQVFVSRUQpKTsKCiAgICAgICAgZmluYWwgRW51bVNldDxJbmZlcmVuY2VTdGVwPiBzdGVwczsKCiAgICAgICAgR3JhcGhJbmZlcmVuY2VTdGVwcyhFbnVtU2V0PEluZmVyZW5jZVN0ZXA+IHN0ZXBzKSB7CiAgICAgICAgICAgIHRoaXMuc3RlcHMgPSBzdGVwczsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBUaGVyZSBhcmUgdHdvIGtpbmRzIG9mIGRlcGVuZGVuY2llcyBiZXR3ZWVuIGluZmVyZW5jZSB2YXJpYWJsZXMuIFRoZSBiYXNpYwogICAgICoga2luZCBvZiBkZXBlbmRlbmN5IChvciBib3VuZCBkZXBlbmRlbmN5KSBhcmlzZXMgd2hlbiBhIHZhcmlhYmxlIG1lbnRpb24KICAgICAqIGFub3RoZXIgdmFyaWFibGUgaW4gb25lIG9mIGl0cyBib3VuZHMuIFRoZXJlJ3MgYWxzbyBhIG1vcmUgc3VidGxlIGtpbmQKICAgICAqIG9mIGRlcGVuZGVuY3kgdGhhdCBhcmlzZXMgd2hlbiBhIHZhcmlhYmxlICdtaWdodCcgbGVhZCB0byBiZXR0ZXIgY29uc3RyYWludHMKICAgICAqIG9uIGFub3RoZXIgdmFyaWFibGUgKHRoaXMgaXMgdHlwaWNhbGx5IHRoZSBjYXNlIHdpdGggdmFyaWFibGVzIGhvbGRpbmcgdXAKICAgICAqIHN0dWNrIGV4cHJlc3Npb25zKS4KICAgICAqLwogICAgZW51bSBEZXBlbmRlbmN5S2luZCBpbXBsZW1lbnRzIEdyYXBoVXRpbHMuRGVwZW5kZW5jeUtpbmQgewoKICAgICAgICAvKiogYm91bmQgZGVwZW5kZW5jeSAqLwogICAgICAgIEJPVU5EKCJkb3R0ZWQiKSwKICAgICAgICAvKiogc3R1Y2sgZGVwZW5kZW5jeSAqLwogICAgICAgIFNUVUNLKCJkYXNoZWQiKTsKCiAgICAgICAgZmluYWwgU3RyaW5nIGRvdFN5bGU7CgogICAgICAgIHByaXZhdGUgRGVwZW5kZW5jeUtpbmQoU3RyaW5nIGRvdFN5bGUpIHsKICAgICAgICAgICAgdGhpcy5kb3RTeWxlID0gZG90U3lsZTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBUaGlzIGlzIHRoZSBncmFwaCBpbmZlcmVuY2Ugc29sdmVyIC0gdGhlIHNvbHZlciBvcmdhbml6ZXMgYWxsIGluZmVyZW5jZSB2YXJpYWJsZXMgaW4KICAgICAqIGEgZ2l2ZW4gaW5mZXJlbmNlIGNvbnRleHQgYnkgYm91bmQgZGVwZW5kZW5jaWVzIC0gaW4gdGhlIGdlbmVyYWwgY2FzZSwgc3VjaCBkZXBlbmRlbmNpZXMKICAgICAqIHdvdWxkIGxlYWQgdG8gYSBjeWNsaWMgZGlyZWN0ZWQgZ3JhcGggKGhlbmNlIHRoZSBuYW1lKTsgdGhlIGRlcGVuZGVuY3kgaW5mbyBpcyB1c2VkIHRvIGJ1aWxkCiAgICAgKiBhbiBhY3ljbGljIGdyYXBoLCB3aGVyZSBhbGwgY3ljbGljIHZhcmlhYmxlcyBhcmUgYnVuZGxlZCB0b2dldGhlci4gQW4gaW5mZXJlbmNlCiAgICAgKiBzdGVwIGNvcnJlc3BvbmRzIHRvIHNvbHZpbmcgYSBub2RlIGluIHRoZSBhY3ljbGljIGdyYXBoIC0gdGhpcyBpcyBkb25lIGJ5CiAgICAgKiByZWx5aW5nIG9uIGEgZ2l2ZW4gc3RyYXRlZ3kgKHNlZSBHcmFwaFN0cmF0ZWd5KS4KICAgICAqLwogICAgY2xhc3MgR3JhcGhTb2x2ZXIgewoKICAgICAgICBJbmZlcmVuY2VDb250ZXh0IGluZmVyZW5jZUNvbnRleHQ7CiAgICAgICAgV2FybmVyIHdhcm47CgogICAgICAgIEdyYXBoU29sdmVyKEluZmVyZW5jZUNvbnRleHQgaW5mZXJlbmNlQ29udGV4dCwgV2FybmVyIHdhcm4pIHsKICAgICAgICAgICAgdGhpcy5pbmZlcmVuY2VDb250ZXh0ID0gaW5mZXJlbmNlQ29udGV4dDsKICAgICAgICAgICAgdGhpcy53YXJuID0gd2FybjsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIFNvbHZlIHZhcmlhYmxlcyBpbiBhIGdpdmVuIGluZmVyZW5jZSBjb250ZXh0LiBUaGUgYW1vdW50IG9mIHZhcmlhYmxlcwogICAgICAgICAqIHRvIGJlIHNvbHZlZCwgYW5kIHRoZSB3YXkgaW4gd2hpY2ggdGhlIHVuZGVybHlpbmcgYWN5Y2xpYyBncmFwaCBpcyBleHBsb3JlZAogICAgICAgICAqIGRlcGVuZHMgb24gdGhlIHNlbGVjdGVkIHNvbHZlciBzdHJhdGVneS4KICAgICAgICAgKi8KICAgICAgICB2b2lkIHNvbHZlKEdyYXBoU3RyYXRlZ3kgc3N0cmF0ZWd5KSB7CiAgICAgICAgICAgIGRvSW5jb3Jwb3JhdGlvbihpbmZlcmVuY2VDb250ZXh0LCB3YXJuKTsgLy9pbml0aWFsIHByb3BhZ2F0aW9uIG9mIGJvdW5kcwogICAgICAgICAgICBJbmZlcmVuY2VHcmFwaCBpbmZlcmVuY2VHcmFwaCA9IG5ldyBJbmZlcmVuY2VHcmFwaCgpOwogICAgICAgICAgICB3aGlsZSAoIXNzdHJhdGVneS5kb25lKCkpIHsKICAgICAgICAgICAgICAgIGlmIChkZXBlbmRlbmNpZXNGb2xkZXIgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIC8vYWRkIHRoaXMgZ3JhcGggdG8gdGhlIHBlbmRpbmcgcXVldWUKICAgICAgICAgICAgICAgICAgICBwZW5kaW5nR3JhcGhzID0gcGVuZGluZ0dyYXBocy5wcmVwZW5kKGluZmVyZW5jZUdyYXBoLnRvRG90KCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgSW5mZXJlbmNlR3JhcGguTm9kZSBub2RlVG9Tb2x2ZSA9IHNzdHJhdGVneS5waWNrTm9kZShpbmZlcmVuY2VHcmFwaCk7CiAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IHZhcnNUb1NvbHZlID0gTGlzdC5mcm9tKG5vZGVUb1NvbHZlLmRhdGEpOwogICAgICAgICAgICAgICAgTGlzdDxUeXBlPiBzYXZlZF91bmRldCA9IGluZmVyZW5jZUNvbnRleHQuc2F2ZSgpOwogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICAvL3JlcGVhdCB1bnRpbCBhbGwgdmFyaWFibGVzIGFyZSBzb2x2ZWQKICAgICAgICAgICAgICAgICAgICBvdXRlcjogd2hpbGUgKFR5cGUuY29udGFpbnNBbnkoaW5mZXJlbmNlQ29udGV4dC5yZXN0dmFycygpLCB2YXJzVG9Tb2x2ZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy9mb3IgZWFjaCBpbmZlcmVuY2UgcGhhc2UKICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChHcmFwaEluZmVyZW5jZVN0ZXBzIHN0ZXAgOiBHcmFwaEluZmVyZW5jZVN0ZXBzLnZhbHVlcygpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW5mZXJlbmNlQ29udGV4dC5zb2x2ZUJhc2ljKHZhcnNUb1NvbHZlLCBzdGVwLnN0ZXBzKS5ub25FbXB0eSgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9JbmNvcnBvcmF0aW9uKGluZmVyZW5jZUNvbnRleHQsIHdhcm4pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlIG91dGVyOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIC8vbm8gcHJvZ3Jlc3MKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgaW5mZXJlbmNlRXhjZXB0aW9uLnNldE1lc3NhZ2UoKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBjYXRjaCAoSW5mZXJlbmNlRXhjZXB0aW9uIGV4KSB7CiAgICAgICAgICAgICAgICAgICAgLy9kaWQgd2UgZmFpbCBiZWNhdXNlIG9mIGludGVyZGVwZW5kZW50IGl2YXJzPwogICAgICAgICAgICAgICAgICAgIGluZmVyZW5jZUNvbnRleHQucm9sbGJhY2soc2F2ZWRfdW5kZXQpOwogICAgICAgICAgICAgICAgICAgIGluc3RhbnRpYXRlQXNVbmluZmVycmVkVmFycyh2YXJzVG9Tb2x2ZSwgaW5mZXJlbmNlQ29udGV4dCk7CiAgICAgICAgICAgICAgICAgICAgZG9JbmNvcnBvcmF0aW9uKGluZmVyZW5jZUNvbnRleHQsIHdhcm4pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5mZXJlbmNlR3JhcGguZGVsZXRlTm9kZShub2RlVG9Tb2x2ZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIFRoZSBkZXBlbmRlbmNpZXMgYmV0d2VlbiB0aGUgaW5mZXJlbmNlIHZhcmlhYmxlcyB0aGF0IG5lZWQgdG8gYmUgc29sdmVkCiAgICAgICAgICogZm9ybSBhIChwb3NzaWJseSBjeWNsaWMpIGdyYXBoLiBUaGlzIGNsYXNzIHJlZHVjZXMgdGhlIG9yaWdpbmFsIGRlcGVuZGVuY3kgZ3JhcGgKICAgICAgICAgKiB0byBhbiBhY3ljbGljIHZlcnNpb24sIHdoZXJlIGN5Y2xpYyBub2RlcyBhcmUgZm9sZGVkIGludG8gYSBzaW5nbGUgJ3N1cGVyIG5vZGUnLgogICAgICAgICAqLwogICAgICAgIGNsYXNzIEluZmVyZW5jZUdyYXBoIHsKCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBUaGlzIGNsYXNzIHJlcHJlc2VudHMgYSBub2RlIGluIHRoZSBncmFwaC4gRWFjaCBub2RlIGNvcnJlc3BvbmRzCiAgICAgICAgICAgICAqIHRvIGFuIGluZmVyZW5jZSB2YXJpYWJsZSBhbmQgaGFzIGVkZ2VzIChkZXBlbmRlbmNpZXMpIG9uIG90aGVyCiAgICAgICAgICAgICAqIG5vZGVzLiBUaGUgbm9kZSBkZWZpbmVzIGFuIGVudHJ5IHBvaW50IHRoYXQgY2FuIGJlIHVzZWQgdG8gcmVjZWl2ZQogICAgICAgICAgICAgKiB1cGRhdGVzIG9uIHRoZSBzdHJ1Y3R1cmUgb2YgdGhlIGdyYXBoIHRoaXMgbm9kZSBiZWxvbmdzIHRvICh1c2VkIHRvCiAgICAgICAgICAgICAqIGtlZXAgZGVwZW5kZW5jaWVzIGluIHN5bmMpLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgY2xhc3MgTm9kZSBleHRlbmRzIEdyYXBoVXRpbHMuVGFyamFuTm9kZTxMaXN0QnVmZmVyPFR5cGU+LCBOb2RlPiBpbXBsZW1lbnRzIERvdHRhYmxlTm9kZTxMaXN0QnVmZmVyPFR5cGU+LCBOb2RlPiB7CgogICAgICAgICAgICAgICAgLyoqIG5vZGUgZGVwZW5kZW5jaWVzICovCiAgICAgICAgICAgICAgICBTZXQ8Tm9kZT4gZGVwczsKCiAgICAgICAgICAgICAgICBOb2RlKFR5cGUgaXZhcikgewogICAgICAgICAgICAgICAgICAgIHN1cGVyKExpc3RCdWZmZXIub2YoaXZhcikpOwogICAgICAgICAgICAgICAgICAgIHRoaXMuZGVwcyA9IG5ldyBIYXNoU2V0PD4oKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgICAgIHB1YmxpYyBHcmFwaFV0aWxzLkRlcGVuZGVuY3lLaW5kW10gZ2V0U3VwcG9ydGVkRGVwZW5kZW5jeUtpbmRzKCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgR3JhcGhVdGlscy5EZXBlbmRlbmN5S2luZFtdIHsgRGVwZW5kZW5jeUtpbmQuQk9VTkQgfTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBwdWJsaWMgSXRlcmFibGU8PyBleHRlbmRzIE5vZGU+IGdldEFsbERlcGVuZGVuY2llcygpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGVwczsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgICAgIHB1YmxpYyBDb2xsZWN0aW9uPD8gZXh0ZW5kcyBOb2RlPiBnZXREZXBlbmRlbmNpZXNCeUtpbmQoR3JhcGhVdGlscy5EZXBlbmRlbmN5S2luZCBkaykgewogICAgICAgICAgICAgICAgICAgIGlmIChkayA9PSBEZXBlbmRlbmN5S2luZC5CT1VORCkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGVwczsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgICAgICogQWRkcyBkZXBlbmRlbmN5IHdpdGggZ2l2ZW4ga2luZC4KICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgcHJvdGVjdGVkIHZvaWQgYWRkRGVwZW5kZW5jeShOb2RlIGRlcFRvQWRkKSB7CiAgICAgICAgICAgICAgICAgICAgZGVwcy5hZGQoZGVwVG9BZGQpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgICAgICogQWRkIG11bHRpcGxlIGRlcGVuZGVuY2llcyBvZiBzYW1lIGdpdmVuIGtpbmQuCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIHByb3RlY3RlZCB2b2lkIGFkZERlcGVuZGVuY2llcyhTZXQ8Tm9kZT4gZGVwc1RvQWRkKSB7CiAgICAgICAgICAgICAgICAgICAgZm9yIChOb2RlIG4gOiBkZXBzVG9BZGQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgYWRkRGVwZW5kZW5jeShuKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAgICAgKiBSZW1vdmUgYSBkZXBlbmRlbmN5LCByZWdhcmRsZXNzIG9mIGl0cyBraW5kLgogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBwcm90ZWN0ZWQgYm9vbGVhbiByZW1vdmVEZXBlbmRlbmN5KE5vZGUgbikgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBkZXBzLnJlbW92ZShuKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvKioKICAgICAgICAgICAgICAgICAqIENvbXB1dGUgY2xvc3VyZSBvZiBhIGdpdmUgbm9kZSwgYnkgcmVjdXJzaXZlbHkgd2Fsa2luZwogICAgICAgICAgICAgICAgICogdGhyb3VnaCBhbGwgaXRzIGRlcGVuZGVuY2llcyAob2YgZ2l2ZW4ga2luZHMpCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIHByb3RlY3RlZCBTZXQ8Tm9kZT4gY2xvc3VyZSgpIHsKICAgICAgICAgICAgICAgICAgICBib29sZWFuIHByb2dyZXNzID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBTZXQ8Tm9kZT4gY2xvc3VyZSA9IG5ldyBIYXNoU2V0PD4oKTsKICAgICAgICAgICAgICAgICAgICBjbG9zdXJlLmFkZCh0aGlzKTsKICAgICAgICAgICAgICAgICAgICB3aGlsZSAocHJvZ3Jlc3MpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcHJvZ3Jlc3MgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChOb2RlIG4xIDogbmV3IEhhc2hTZXQ8PihjbG9zdXJlKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvZ3Jlc3MgPSBjbG9zdXJlLmFkZEFsbChuMS5kZXBzKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICByZXR1cm4gY2xvc3VyZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvKioKICAgICAgICAgICAgICAgICAqIElzIHRoaXMgbm9kZSBhIGxlYWY/IFRoaXMgbWVhbnMgZWl0aGVyIHRoZSBub2RlIGhhcyBubyBkZXBlbmRlbmNpZXMsCiAgICAgICAgICAgICAgICAgKiBvciBpdCBqdXN0IGhhcyBzZWxmLWRlcGVuZGVuY2llcy4KICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgcHJvdGVjdGVkIGJvb2xlYW4gaXNMZWFmKCkgewogICAgICAgICAgICAgICAgICAgIC8vbm8gZGVwcywgb3Igb25seSBvbmUgc2VsZiBkZXAKICAgICAgICAgICAgICAgICAgICBpZiAoZGVwcy5pc0VtcHR5KCkpIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgICAgIGZvciAoTm9kZSBuIDogZGVwcykgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAobiAhPSB0aGlzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAgICAgKiBNZXJnZSB0aGlzIG5vZGUgd2l0aCBhbm90aGVyIG5vZGUsIGFjcXVpcmluZyBpdHMgZGVwZW5kZW5jaWVzLgogICAgICAgICAgICAgICAgICogVGhpcyByb3V0aW5lIGlzIHVzZWQgdG8gbWVyZ2UgYWxsIGN5Y2xpYyBub2RlIHRvZ2V0aGVyIGFuZAogICAgICAgICAgICAgICAgICogZm9ybSBhbiBhY3ljbGljIGdyYXBoLgogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBwcm90ZWN0ZWQgdm9pZCBtZXJnZVdpdGgoTGlzdDw/IGV4dGVuZHMgTm9kZT4gbm9kZXMpIHsKICAgICAgICAgICAgICAgICAgICBmb3IgKE5vZGUgbiA6IG5vZGVzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIEFzc2VydC5jaGVjayhuLmRhdGEubGVuZ3RoKCkgPT0gMSwgIkF0dGVtcHQgdG8gbWVyZ2UgYSBjb21wb3VuZCBub2RlISIpOwogICAgICAgICAgICAgICAgICAgICAgICBkYXRhLmFwcGVuZExpc3Qobi5kYXRhKTsKICAgICAgICAgICAgICAgICAgICAgICAgYWRkRGVwZW5kZW5jaWVzKG4uZGVwcyk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIC8vdXBkYXRlIGRlcHMKICAgICAgICAgICAgICAgICAgICBTZXQ8Tm9kZT4gZGVwczIgPSBuZXcgSGFzaFNldDw+KCk7CiAgICAgICAgICAgICAgICAgICAgZm9yIChOb2RlIGQgOiBkZXBzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkYXRhLmNvbnRhaW5zKGQuZGF0YS5maXJzdCgpKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVwczIuYWRkKHRoaXMpOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVwczIuYWRkKGQpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGRlcHMgPSBkZXBzMjsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvKioKICAgICAgICAgICAgICAgICAqIE5vdGlmeSBhbGwgbm9kZXMgdGhhdCBzb21ldGhpbmcgaGFzIGNoYW5nZWQgaW4gdGhlIGdyYXBoCiAgICAgICAgICAgICAgICAgKiB0b3BvbG9neS4KICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgcHJpdmF0ZSB2b2lkIGdyYXBoQ2hhbmdlZChOb2RlIGZyb20sIE5vZGUgdG8pIHsKICAgICAgICAgICAgICAgICAgICBpZiAocmVtb3ZlRGVwZW5kZW5jeShmcm9tKSkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAodG8gIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkRGVwZW5kZW5jeSh0byk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgICAgICBwdWJsaWMgUHJvcGVydGllcyBub2RlQXR0cmlidXRlcygpIHsKICAgICAgICAgICAgICAgICAgICBQcm9wZXJ0aWVzIHAgPSBuZXcgUHJvcGVydGllcygpOwogICAgICAgICAgICAgICAgICAgIHAucHV0KCJsYWJlbCIsICJcIiIgKyB0b1N0cmluZygpICsgIlwiIik7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHA7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgICAgICBwdWJsaWMgUHJvcGVydGllcyBkZXBlbmRlbmN5QXR0cmlidXRlcyhOb2RlIHNpbmssIEdyYXBoVXRpbHMuRGVwZW5kZW5jeUtpbmQgZGspIHsKICAgICAgICAgICAgICAgICAgICBQcm9wZXJ0aWVzIHAgPSBuZXcgUHJvcGVydGllcygpOwogICAgICAgICAgICAgICAgICAgIHAucHV0KCJzdHlsZSIsICgoRGVwZW5kZW5jeUtpbmQpZGspLmRvdFN5bGUpOwogICAgICAgICAgICAgICAgICAgIFN0cmluZ0J1aWxkZXIgYnVmID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKICAgICAgICAgICAgICAgICAgICBTdHJpbmcgc2VwID0gIiI7CiAgICAgICAgICAgICAgICAgICAgZm9yIChUeXBlIGZyb20gOiBkYXRhKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIFVuZGV0VmFyIHV2ID0gKFVuZGV0VmFyKWluZmVyZW5jZUNvbnRleHQuYXNVbmRldFZhcihmcm9tKTsKICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChUeXBlIGJvdW5kIDogdXYuZ2V0Qm91bmRzKEluZmVyZW5jZUJvdW5kLnZhbHVlcygpKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGJvdW5kLmNvbnRhaW5zQW55KExpc3QuZnJvbShzaW5rLmRhdGEpKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQoc2VwKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBidWYuYXBwZW5kKGJvdW5kKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXAgPSAiLCI7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgcC5wdXQoImxhYmVsIiwgIlwiIiArIGJ1Zi50b1N0cmluZygpICsgIlwiIik7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qKiB0aGUgbm9kZXMgaW4gdGhlIGluZmVyZW5jZSBncmFwaCAqLwogICAgICAgICAgICBBcnJheUxpc3Q8Tm9kZT4gbm9kZXM7CgogICAgICAgICAgICBJbmZlcmVuY2VHcmFwaCgpIHsKICAgICAgICAgICAgICAgIGluaXROb2RlcygpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogQmFzaWMgbG9va3VwIGhlbHBlciBmb3IgcmV0cmlldmluZyBhIGdyYXBoIG5vZGUgZ2l2ZW4gYW4gaW5mZXJlbmNlCiAgICAgICAgICAgICAqIHZhcmlhYmxlIHR5cGUuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBwdWJsaWMgTm9kZSBmaW5kTm9kZShUeXBlIHQpIHsKICAgICAgICAgICAgICAgIGZvciAoTm9kZSBuIDogbm9kZXMpIHsKICAgICAgICAgICAgICAgICAgICBpZiAobi5kYXRhLmNvbnRhaW5zKHQpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBuOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogRGVsZXRlIGEgbm9kZSBmcm9tIHRoZSBncmFwaC4gVGhpcyB1cGRhdGUgdGhlIHVuZGVybHlpbmcgc3RydWN0dXJlCiAgICAgICAgICAgICAqIG9mIHRoZSBncmFwaCAoaW5jbHVkaW5nIGRlcGVuZGVuY2llcykgdmlhIGxpc3RlbmVycyB1cGRhdGVzLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgcHVibGljIHZvaWQgZGVsZXRlTm9kZShOb2RlIG4pIHsKICAgICAgICAgICAgICAgIEFzc2VydC5jaGVjayhub2Rlcy5jb250YWlucyhuKSk7CiAgICAgICAgICAgICAgICBub2Rlcy5yZW1vdmUobik7CiAgICAgICAgICAgICAgICBub3RpZnlVcGRhdGUobiwgbnVsbCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBOb3RpZnkgYWxsIG5vZGVzIG9mIGEgY2hhbmdlIGluIHRoZSBncmFwaC4gSWYgdGhlIHRhcmdldCBub2RlIGlzCiAgICAgICAgICAgICAqIHtAY29kZSBudWxsfSB0aGUgc291cmNlIG5vZGUgaXMgYXNzdW1lZCB0byBiZSByZW1vdmVkLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgdm9pZCBub3RpZnlVcGRhdGUoTm9kZSBmcm9tLCBOb2RlIHRvKSB7CiAgICAgICAgICAgICAgICBmb3IgKE5vZGUgbiA6IG5vZGVzKSB7CiAgICAgICAgICAgICAgICAgICAgbi5ncmFwaENoYW5nZWQoZnJvbSwgdG8pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogQ3JlYXRlIHRoZSBncmFwaCBub2Rlcy4gRmlyc3QgYSBzaW1wbGUgbm9kZSBpcyBjcmVhdGVkIGZvciBldmVyeSBpbmZlcmVuY2UKICAgICAgICAgICAgICogdmFyaWFibGVzIHRvIGJlIHNvbHZlZC4gVGhlbiBUYXJqYW4gaXMgdXNlZCB0byBmb3VuZCBhbGwgY29ubmVjdGVkIGNvbXBvbmVudHMKICAgICAgICAgICAgICogaW4gdGhlIGdyYXBoLiBGb3IgZWFjaCBjb21wb25lbnQgY29udGFpbmluZyBtb3JlIHRoYW4gb25lIG5vZGUsIGEgc3VwZXIgbm9kZSBpcwogICAgICAgICAgICAgKiBjcmVhdGVkLCBlZmZlY3RpdmVseSByZXBsYWNpbmcgdGhlIG9yaWdpbmFsIGN5Y2xpYyBub2Rlcy4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIHZvaWQgaW5pdE5vZGVzKCkgewogICAgICAgICAgICAgICAgLy9hZGQgbm9kZXMKICAgICAgICAgICAgICAgIG5vZGVzID0gbmV3IEFycmF5TGlzdDw+KCk7CiAgICAgICAgICAgICAgICBmb3IgKFR5cGUgdCA6IGluZmVyZW5jZUNvbnRleHQucmVzdHZhcnMoKSkgewogICAgICAgICAgICAgICAgICAgIG5vZGVzLmFkZChuZXcgTm9kZSh0KSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvL2FkZCBkZXBlbmRlbmNpZXMKICAgICAgICAgICAgICAgIGZvciAoTm9kZSBuX2kgOiBub2RlcykgewogICAgICAgICAgICAgICAgICAgIFR5cGUgaSA9IG5faS5kYXRhLmZpcnN0KCk7CiAgICAgICAgICAgICAgICAgICAgZm9yIChOb2RlIG5faiA6IG5vZGVzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIFR5cGUgaiA9IG5fai5kYXRhLmZpcnN0KCk7CiAgICAgICAgICAgICAgICAgICAgICAgIFVuZGV0VmFyIHV2X2kgPSAoVW5kZXRWYXIpaW5mZXJlbmNlQ29udGV4dC5hc1VuZGV0VmFyKGkpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoVHlwZS5jb250YWluc0FueSh1dl9pLmdldEJvdW5kcyhJbmZlcmVuY2VCb3VuZC52YWx1ZXMoKSksIExpc3Qub2YoaikpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3VwZGF0ZSBpJ3MgYm91bmQgZGVwZW5kZW5jaWVzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuX2kuYWRkRGVwZW5kZW5jeShuX2opOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgLy9tZXJnZSBjeWNsaWMgbm9kZXMKICAgICAgICAgICAgICAgIEFycmF5TGlzdDxOb2RlPiBhY3ljbGljTm9kZXMgPSBuZXcgQXJyYXlMaXN0PD4oKTsKICAgICAgICAgICAgICAgIGZvciAoTGlzdDw/IGV4dGVuZHMgTm9kZT4gY29uU3ViR3JhcGggOiBHcmFwaFV0aWxzLnRhcmphbihub2RlcykpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoY29uU3ViR3JhcGgubGVuZ3RoKCkgPiAxKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIE5vZGUgcm9vdCA9IGNvblN1YkdyYXBoLmhlYWQ7CiAgICAgICAgICAgICAgICAgICAgICAgIHJvb3QubWVyZ2VXaXRoKGNvblN1YkdyYXBoLnRhaWwpOwogICAgICAgICAgICAgICAgICAgICAgICBmb3IgKE5vZGUgbiA6IGNvblN1YkdyYXBoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBub3RpZnlVcGRhdGUobiwgcm9vdCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYWN5Y2xpY05vZGVzLmFkZChjb25TdWJHcmFwaC5oZWFkKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIG5vZGVzID0gYWN5Y2xpY05vZGVzOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogRGVidWdnaW5nOiBkb3QgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBncmFwaAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgU3RyaW5nIHRvRG90KCkgewogICAgICAgICAgICAgICAgU3RyaW5nQnVpbGRlciBidWYgPSBuZXcgU3RyaW5nQnVpbGRlcigpOwogICAgICAgICAgICAgICAgZm9yIChUeXBlIHQgOiBpbmZlcmVuY2VDb250ZXh0LnVuZGV0dmFycykgewogICAgICAgICAgICAgICAgICAgIFVuZGV0VmFyIHV2ID0gKFVuZGV0VmFyKXQ7CiAgICAgICAgICAgICAgICAgICAgYnVmLmFwcGVuZChTdHJpbmcuZm9ybWF0KCJ2YXIgJXMgLSB1cHBlciBib3VuZHMgPSAlcywgbG93ZXIgYm91bmRzID0gJXMsIGVxIGJvdW5kcyA9ICVzXFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHV2LnF0eXBlLCB1di5nZXRCb3VuZHMoSW5mZXJlbmNlQm91bmQuVVBQRVIpLCB1di5nZXRCb3VuZHMoSW5mZXJlbmNlQm91bmQuTE9XRVIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdXYuZ2V0Qm91bmRzKEluZmVyZW5jZUJvdW5kLkVRKSkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIEdyYXBoVXRpbHMudG9Eb3Qobm9kZXMsICJpbmZlcmVuY2VHcmFwaCIgKyBoYXNoQ29kZSgpLCBidWYudG9TdHJpbmcoKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICAvLyA8L2VkaXRvci1mb2xkPgoKICAgIC8vIDxlZGl0b3ItZm9sZCBkZWZhdWx0c3RhdGU9ImNvbGxhcHNlZCIgZGVzYz0iSW5mZXJlbmNlIGNvbnRleHQiPgogICAgLyoqCiAgICAgKiBGdW5jdGlvbmFsIGludGVyZmFjZSBmb3IgZGVmaW5pbmcgaW5mZXJlbmNlIGNhbGxiYWNrcy4gQ2VydGFpbiBhY3Rpb25zCiAgICAgKiAoaS5lLiBzdWJ0eXBpbmcgY2hlY2tzKSBtaWdodCBuZWVkIHRvIGJlIHJlZG9uZSBhZnRlciBhbGwgaW5mZXJlbmNlIHZhcmlhYmxlcwogICAgICogaGF2ZSBiZWVuIGZpeGVkLgogICAgICovCiAgICBpbnRlcmZhY2UgRnJlZVR5cGVMaXN0ZW5lciB7CiAgICAgICAgdm9pZCB0eXBlc0luZmVycmVkKEluZmVyZW5jZUNvbnRleHQgaW5mZXJlbmNlQ29udGV4dCk7CiAgICB9CgogICAgZmluYWwgSW5mZXJlbmNlQ29udGV4dCBlbXB0eUNvbnRleHQ7CiAgICAvLyA8L2VkaXRvci1mb2xkPgp9ClBLAwQKAAAIAAAGO6lKNETLFT8VAAA/FQAAKQAAAGNvbS9zdW4vdG9vbHMvamF2YWMvY29tcC9BdHRyQ29udGV4dC5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAxOTk5LCAyMDE3LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuamF2YWMuY29tcDsKCmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuSkNUcmVlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLio7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuKjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5TY29wZS5Xcml0ZWFibGVTY29wZTsKCi8qKiBDb250YWlucyBpbmZvcm1hdGlvbiBzcGVjaWZpYyB0byB0aGUgYXR0cmlidXRlIGFuZCBlbnRlcgogKiAgcGFzc2VzLCB0byBiZSB1c2VkIGluIHBsYWNlIG9mIHRoZSBnZW5lcmljIGZpZWxkIGluIGVudmlyb25tZW50cy4KICoKICogIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqICBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqICBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogKiAgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPgogKi8KcHVibGljIGNsYXNzIEF0dHJDb250ZXh0IHsKCiAgICAvKiogVGhlIHNjb3BlIG9mIGxvY2FsIHN5bWJvbHMuCiAgICAgKi8KICAgIFdyaXRlYWJsZVNjb3BlIHNjb3BlID0gbnVsbDsKCiAgICAvKiogVGhlIG51bWJlciBvZiBlbmNsb3NpbmcgYHN0YXRpYycgbW9kaWZpZXJzLgogICAgICovCiAgICBpbnQgc3RhdGljTGV2ZWwgPSAwOwoKICAgIC8qKiBJcyB0aGlzIGFuIGVudmlyb25tZW50IGZvciBhIHRoaXMoLi4uKSBvciBzdXBlciguLi4pIGNhbGw/CiAgICAgKi8KICAgIGJvb2xlYW4gaXNTZWxmQ2FsbCA9IGZhbHNlOwoKICAgIC8qKiBBcmUgd2UgZXZhbHVhdGluZyB0aGUgc2VsZWN0b3Igb2YgYSBgc3VwZXInIG9yIHR5cGUgbmFtZT8KICAgICAqLwogICAgYm9vbGVhbiBzZWxlY3RTdXBlciA9IGZhbHNlOwoKICAgIC8qKiBJcyB0aGUgY3VycmVudCB0YXJnZXQgb2YgbGFtYmRhIGV4cHJlc3Npb24gb3IgbWV0aG9kIHJlZmVyZW5jZSBzZXJpYWxpemFibGUgb3IgaXMgdGhpcyBhCiAgICAgKiAgc2VyaWFsaXphYmxlIGNsYXNzPwogICAgICovCiAgICBib29sZWFuIGlzU2VyaWFsaXphYmxlID0gZmFsc2U7CgogICAgLyoqIElzIHRoaXMgYSBsYW1iZGEgZW52aXJvbm1lbnQ/CiAgICAgKi8KICAgIGJvb2xlYW4gaXNMYW1iZGEgPSBmYWxzZTsKCiAgICAvKiogSXMgdGhpcyBhIHNwZWN1bGF0aXZlIGF0dHJpYnV0aW9uIGVudmlyb25tZW50PwogICAgICovCiAgICBib29sZWFuIGlzU3BlY3VsYXRpdmUgPSBmYWxzZTsKCiAgICAvKioKICAgICAqICBJcyB0aGlzIGFuIGF0dHJpYnV0aW9uIGVudmlyb25tZW50IGZvciBhbiBhbm9ueW1vdXMgY2xhc3MgaW5zdGFudGlhdGVkIHVzaW5nIDw+ID8KICAgICAqLwogICAgYm9vbGVhbiBpc0Fub255bW91c0RpYW1vbmQgPSBmYWxzZTsKCiAgICAvKioKICAgICAqICBJcyB0aGlzIGFuIGF0dHJpYnV0aW9uIGVudmlyb25tZW50IGZvciBhbiBpbnN0YW5jZSBjcmVhdGlvbiBleHByZXNzaW9uPwogICAgICovCiAgICBib29sZWFuIGlzTmV3Q2xhc3MgPSBmYWxzZTsKCiAgICAvKiogSW5kaWNhdGUgaWYgdGhlIHR5cGUgYmVpbmcgdmlzaXRlZCBpcyBhIHNlcnZpY2UgaW1wbGVtZW50YXRpb24KICAgICAqLwogICAgYm9vbGVhbiB2aXNpdGluZ1NlcnZpY2VJbXBsZW1lbnRhdGlvbiA9IGZhbHNlOwoKICAgIC8qKiBBcmUgYXJndW1lbnRzIHRvIGN1cnJlbnQgZnVuY3Rpb24gYXBwbGljYXRpb25zIGJveGVkIGludG8gYW4gYXJyYXkgZm9yIHZhcmFyZ3M/CiAgICAgKi8KICAgIFJlc29sdmUuTWV0aG9kUmVzb2x1dGlvblBoYXNlIHBlbmRpbmdSZXNvbHV0aW9uUGhhc2UgPSBudWxsOwoKICAgIC8qKiBBIHJlY29yZCBvZiB0aGUgbGludC9TdXBwcmVzc1dhcm5pbmdzIGN1cnJlbnRseSBpbiBlZmZlY3QKICAgICAqLwogICAgTGludCBsaW50OwoKICAgIC8qKiBUaGUgdmFyaWFibGUgd2hvc2UgaW5pdGlhbGl6ZXIgaXMgYmVpbmcgYXR0cmlidXRlZAogICAgICogdXNlZnVsIGZvciBkZXRlY3Rpbmcgc2VsZi1yZWZlcmVuY2VzIGluIHZhcmlhYmxlIGluaXRpYWxpemVycwogICAgICovCiAgICBTeW1ib2wgZW5jbFZhciA9IG51bGw7CgogICAgLyoqIFJlc3VsdEluZm8gdG8gYmUgdXNlZCBmb3IgYXR0cmlidXRpbmcgJ3JldHVybicgc3RhdGVtZW50IGV4cHJlc3Npb25zCiAgICAgKiAoc2V0IGJ5IEF0dHIudmlzaXRNZXRob2QgYW5kIEF0dHIudmlzaXRMYW1iZGEpCiAgICAgKi8KICAgIEF0dHIuUmVzdWx0SW5mbyByZXR1cm5SZXN1bHQgPSBudWxsOwoKICAgIC8qKiBTeW1ib2wgY29ycmVzcG9uZGluZyB0byB0aGUgc2l0ZSBvZiBhIHF1YWxpZmllZCBkZWZhdWx0IHN1cGVyIGNhbGwKICAgICAqLwogICAgVHlwZSBkZWZhdWx0U3VwZXJDYWxsU2l0ZSA9IG51bGw7CgogICAgLyoqIFRyZWUgdGhhdCB3aGVuIG5vbiBudWxsLCBpcyB0byBiZSBwcmVmZXJlbnRpYWxseSB1c2VkIGluIGRpYWdub3N0aWNzLgogICAgICogIFVzdWFsbHkgRW52PEF0dHJDb250ZXh0Pi50cmVlIGlzIHRoZSB0cmVlIHRvIGJlIHJlZmVycmVkIHRvIGluIG1lc3NhZ2VzLAogICAgICogIGJ1dCB0aGlzIG1heSBub3QgYmUgdHJ1ZSBkdXJpbmcgdGhlIHdpbmRvdyBhIG1ldGhvZCBpcyBsb29rZWQgdXAgaW4gZW5jbG9zaW5nCiAgICAgKiAgY29udGV4dHMgKEpESy04MTQ1NDY2KQogICAgICovCiAgICBKQ1RyZWUgcHJlZmVycmVkVHJlZUZvckRpYWdub3N0aWNzOwoKICAgIC8qKiBEdXBsaWNhdGUgdGhpcyBjb250ZXh0LCByZXBsYWNpbmcgc2NvcGUgZmllbGQgYW5kIGNvcHlpbmcgYWxsIG90aGVycy4KICAgICAqLwogICAgQXR0ckNvbnRleHQgZHVwKFdyaXRlYWJsZVNjb3BlIHNjb3BlKSB7CiAgICAgICAgQXR0ckNvbnRleHQgaW5mbyA9IG5ldyBBdHRyQ29udGV4dCgpOwogICAgICAgIGluZm8uc2NvcGUgPSBzY29wZTsKICAgICAgICBpbmZvLnN0YXRpY0xldmVsID0gc3RhdGljTGV2ZWw7CiAgICAgICAgaW5mby5pc1NlbGZDYWxsID0gaXNTZWxmQ2FsbDsKICAgICAgICBpbmZvLnNlbGVjdFN1cGVyID0gc2VsZWN0U3VwZXI7CiAgICAgICAgaW5mby5wZW5kaW5nUmVzb2x1dGlvblBoYXNlID0gcGVuZGluZ1Jlc29sdXRpb25QaGFzZTsKICAgICAgICBpbmZvLmxpbnQgPSBsaW50OwogICAgICAgIGluZm8uZW5jbFZhciA9IGVuY2xWYXI7CiAgICAgICAgaW5mby5yZXR1cm5SZXN1bHQgPSByZXR1cm5SZXN1bHQ7CiAgICAgICAgaW5mby5kZWZhdWx0U3VwZXJDYWxsU2l0ZSA9IGRlZmF1bHRTdXBlckNhbGxTaXRlOwogICAgICAgIGluZm8uaXNTZXJpYWxpemFibGUgPSBpc1NlcmlhbGl6YWJsZTsKICAgICAgICBpbmZvLmlzTGFtYmRhID0gaXNMYW1iZGE7CiAgICAgICAgaW5mby5pc1NwZWN1bGF0aXZlID0gaXNTcGVjdWxhdGl2ZTsKICAgICAgICBpbmZvLmlzQW5vbnltb3VzRGlhbW9uZCA9IGlzQW5vbnltb3VzRGlhbW9uZDsKICAgICAgICBpbmZvLmlzTmV3Q2xhc3MgPSBpc05ld0NsYXNzOwogICAgICAgIGluZm8ucHJlZmVycmVkVHJlZUZvckRpYWdub3N0aWNzID0gcHJlZmVycmVkVHJlZUZvckRpYWdub3N0aWNzOwogICAgICAgIGluZm8udmlzaXRpbmdTZXJ2aWNlSW1wbGVtZW50YXRpb24gPSB2aXNpdGluZ1NlcnZpY2VJbXBsZW1lbnRhdGlvbjsKICAgICAgICByZXR1cm4gaW5mbzsKICAgIH0KCiAgICAvKiogRHVwbGljYXRlIHRoaXMgY29udGV4dCwgY29weWluZyBhbGwgZmllbGRzLgogICAgICovCiAgICBBdHRyQ29udGV4dCBkdXAoKSB7CiAgICAgICAgcmV0dXJuIGR1cChzY29wZSk7CiAgICB9CgogICAgcHVibGljIEl0ZXJhYmxlPFN5bWJvbD4gZ2V0TG9jYWxFbGVtZW50cygpIHsKICAgICAgICBpZiAoc2NvcGUgPT0gbnVsbCkKICAgICAgICAgICAgcmV0dXJuIExpc3QubmlsKCk7CiAgICAgICAgcmV0dXJuIHNjb3BlLmdldFN5bWJvbHMoKTsKICAgIH0KCiAgICBib29sZWFuIGxhc3RSZXNvbHZlVmFyYXJncygpIHsKICAgICAgICByZXR1cm4gcGVuZGluZ1Jlc29sdXRpb25QaGFzZSAhPSBudWxsICYmCiAgICAgICAgICAgICAgICBwZW5kaW5nUmVzb2x1dGlvblBoYXNlLmlzVmFyYXJnc1JlcXVpcmVkKCk7CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewogICAgICAgIHJldHVybiAiQXR0ckNvbnRleHRbIiArIHNjb3BlLnRvU3RyaW5nKCkgKyAiXSI7CiAgICB9Cn0KUEsDBAoAAAgAAAY7qUoMBs5eSr4AAEq+AAAnAAAAY29tL3N1bi90b29scy9qYXZhYy9jb21wL1R5cGVFbnRlci5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDAzLCAyMDE3LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuamF2YWMuY29tcDsKCmltcG9ydCBqYXZhLnV0aWwuSGFzaFNldDsKaW1wb3J0IGphdmEudXRpbC5TZXQ7CmltcG9ydCBqYXZhLnV0aWwuZnVuY3Rpb24uQmlDb25zdW1lcjsKCmltcG9ydCBqYXZheC50b29scy5KYXZhRmlsZU9iamVjdDsKCmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuKjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5MaW50LkxpbnRDYXRlZ29yeTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5TY29wZS5JbXBvcnRGaWx0ZXI7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuU2NvcGUuTmFtZWRJbXBvcnRTY29wZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5TY29wZS5TdGFySW1wb3J0U2NvcGU7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuU2NvcGUuV3JpdGVhYmxlU2NvcGU7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvbXAuQW5ub3RhdGUuQW5ub3RhdGlvblR5cGVNZXRhZGF0YTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS4qOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLio7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuRGVmaW5lZEJ5LkFwaTsKCmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuU3ltYm9sLio7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuVHlwZS4qOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkpDVHJlZS4qOwoKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuRmxhZ3MuKjsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuRmxhZ3MuQU5OT1RBVElPTjsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuU2NvcGUuTG9va3VwS2luZC5OT05fUkVDVVJTSVZFOwppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5LaW5kcy5LaW5kLio7CmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlR5cGVUYWcuQ0xBU1M7CmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlR5cGVUYWcuRVJST1I7CmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkpDVHJlZS5UYWcuKjsKCmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuRGVwZW5kZW5jaWVzLkNvbXBsZXRpb25DYXVzZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5KQ0RpYWdub3N0aWMuRGlhZ25vc3RpY0ZsYWc7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuSkNEaWFnbm9zdGljLkRpYWdub3N0aWNQb3NpdGlvbjsKCi8qKiBUaGlzIGlzIHRoZSBzZWNvbmQgcGhhc2Ugb2YgRW50ZXIsIGluIHdoaWNoIGNsYXNzZXMgYXJlIGNvbXBsZXRlZAogKiAgYnkgcmVzb2x2aW5nIHRoZWlyIGhlYWRlcnMgYW5kIGVudGVyaW5nIHRoZWlyIG1lbWJlcnMgaW4gdGhlIGludG8KICogIHRoZSBjbGFzcyBzY29wZS4gU2VlIEVudGVyIGZvciBhbiBvdmVyYWxsIG92ZXJ2aWV3LgogKgogKiAgVGhpcyBjbGFzcyB1c2VzIGludGVybmFsIHBoYXNlcyB0byBwcm9jZXNzIHRoZSBjbGFzc2VzLiBXaGVuIGEgcGhhc2UKICogIHByb2Nlc3NlcyBjbGFzc2VzLCB0aGUgbG93ZXIgcGhhc2VzIGFyZSBub3QgaW52b2tlZCB1bnRpbCBhbGwgY2xhc3NlcwogKiAgcGFzcyB0aHJvdWdoIHRoZSBjdXJyZW50IHBoYXNlLiBOb3RlIHRoYXQgaXQgaXMgcG9zc2libGUgdGhhdCB1cHBlciBwaGFzZXMKICogIGFyZSBydW4gZHVlIHRvIHJlY3Vyc2l2ZSBjb21wbGV0aW9uLiBUaGUgaW50ZXJuYWwgcGhhc2VzIGFyZToKICogIC0gSW1wb3J0UGhhc2U6IHNoYWxsb3cgcGFzcyB0aHJvdWdoIGltcG9ydHMsIGFkZHMgaW5mb3JtYXRpb24gYWJvdXQgaW1wb3J0cwogKiAgICAgICAgICAgICAgICAgdGhlIE5hbWVkSW1wb3J0U2NvcGUgYW5kIFN0YXJJbXBvcnRTY29wZSwgYnV0IGF2b2lkcyBxdWVyaWVzCiAqICAgICAgICAgICAgICAgICBhYm91dCBjbGFzcyBoaWVyYXJjaHkuCiAqICAtIEhpZXJhcmNoeVBoYXNlOiByZXNvbHZlcyB0aGUgc3VwZXJ0eXBlcyBvZiB0aGUgZ2l2ZW4gY2xhc3MuIERvZXMgbm90IGhhbmRsZQogKiAgICAgICAgICAgICAgICAgICAgdHlwZSBwYXJhbWV0ZXJzIG9mIHRoZSBjbGFzcyBvciB0eXBlIGFyZ3VtZW50IG9mIHRoZSBzdXBlcnR5cGVzLgogKiAgLSBIZWFkZXJQaGFzZTogZmluaXNoZXMgYW5hbHlzaXMgb2YgdGhlIGhlYWRlciBvZiB0aGUgZ2l2ZW4gY2xhc3MgYnkgcmVzb2x2aW5nCiAqICAgICAgICAgICAgICAgICB0eXBlIHBhcmFtZXRlcnMsIGF0dHJpYnV0aW5nIHN1cGVydHlwZXMgaW5jbHVkaW5nIHR5cGUgYXJndW1lbnRzCiAqICAgICAgICAgICAgICAgICBhbmQgc2NoZWR1bGluZyBmdWxsIGFubm90YXRpb24gYXR0cmlidXRpb24uIFRoaXMgcGhhc2UgYWxzbyBhZGRzCiAqICAgICAgICAgICAgICAgICBhIHN5bnRoZXRpYyBkZWZhdWx0IGNvbnN0cnVjdG9yIGlmIG5lZWRlZCBhbmQgc3ludGhldGljICJ0aGlzIiBmaWVsZC4KICogIC0gTWVtYmVyc1BoYXNlOiByZXNvbHZlcyBoZWFkZXJzIGZvciBmaWVsZHMsIG1ldGhvZHMgYW5kIGNvbnN0cnVjdG9ycyBpbiB0aGUgZ2l2ZW4gY2xhc3MuCiAqICAgICAgICAgICAgICAgICAgQWxzbyBnZW5lcmF0ZXMgc3ludGhldGljIGVudW0gbWVtYmVycy4KICoKICogIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqICBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqICBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogKiAgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPgogKi8KcHVibGljIGNsYXNzIFR5cGVFbnRlciBpbXBsZW1lbnRzIENvbXBsZXRlciB7CiAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIENvbnRleHQuS2V5PFR5cGVFbnRlcj4gdHlwZUVudGVyS2V5ID0gbmV3IENvbnRleHQuS2V5PD4oKTsKCiAgICAvKiogQSBzd2l0Y2ggdG8gZGV0ZXJtaW5lIHdoZXRoZXIgd2UgY2hlY2sgZm9yIHBhY2thZ2UvY2xhc3MgY29uZmxpY3RzCiAgICAgKi8KICAgIGZpbmFsIHN0YXRpYyBib29sZWFuIGNoZWNrQ2xhc2ggPSB0cnVlOwoKICAgIHByaXZhdGUgZmluYWwgTmFtZXMgbmFtZXM7CiAgICBwcml2YXRlIGZpbmFsIEVudGVyIGVudGVyOwogICAgcHJpdmF0ZSBmaW5hbCBNZW1iZXJFbnRlciBtZW1iZXJFbnRlcjsKICAgIHByaXZhdGUgZmluYWwgTG9nIGxvZzsKICAgIHByaXZhdGUgZmluYWwgQ2hlY2sgY2hrOwogICAgcHJpdmF0ZSBmaW5hbCBBdHRyIGF0dHI7CiAgICBwcml2YXRlIGZpbmFsIFN5bXRhYiBzeW1zOwogICAgcHJpdmF0ZSBmaW5hbCBUcmVlTWFrZXIgbWFrZTsKICAgIHByaXZhdGUgZmluYWwgVG9kbyB0b2RvOwogICAgcHJpdmF0ZSBmaW5hbCBBbm5vdGF0ZSBhbm5vdGF0ZTsKICAgIHByaXZhdGUgZmluYWwgVHlwZUFubm90YXRpb25zIHR5cGVBbm5vdGF0aW9uczsKICAgIHByaXZhdGUgZmluYWwgVHlwZXMgdHlwZXM7CiAgICBwcml2YXRlIGZpbmFsIEpDRGlhZ25vc3RpYy5GYWN0b3J5IGRpYWdzOwogICAgcHJpdmF0ZSBmaW5hbCBEZWZlcnJlZExpbnRIYW5kbGVyIGRlZmVycmVkTGludEhhbmRsZXI7CiAgICBwcml2YXRlIGZpbmFsIExpbnQgbGludDsKICAgIHByaXZhdGUgZmluYWwgVHlwZUVudnMgdHlwZUVudnM7CiAgICBwcml2YXRlIGZpbmFsIERlcGVuZGVuY2llcyBkZXBlbmRlbmNpZXM7CgogICAgcHVibGljIHN0YXRpYyBUeXBlRW50ZXIgaW5zdGFuY2UoQ29udGV4dCBjb250ZXh0KSB7CiAgICAgICAgVHlwZUVudGVyIGluc3RhbmNlID0gY29udGV4dC5nZXQodHlwZUVudGVyS2V5KTsKICAgICAgICBpZiAoaW5zdGFuY2UgPT0gbnVsbCkKICAgICAgICAgICAgaW5zdGFuY2UgPSBuZXcgVHlwZUVudGVyKGNvbnRleHQpOwogICAgICAgIHJldHVybiBpbnN0YW5jZTsKICAgIH0KCiAgICBwcm90ZWN0ZWQgVHlwZUVudGVyKENvbnRleHQgY29udGV4dCkgewogICAgICAgIGNvbnRleHQucHV0KHR5cGVFbnRlcktleSwgdGhpcyk7CiAgICAgICAgbmFtZXMgPSBOYW1lcy5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBlbnRlciA9IEVudGVyLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIG1lbWJlckVudGVyID0gTWVtYmVyRW50ZXIuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgbG9nID0gTG9nLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIGNoayA9IENoZWNrLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIGF0dHIgPSBBdHRyLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIHN5bXMgPSBTeW10YWIuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgbWFrZSA9IFRyZWVNYWtlci5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICB0b2RvID0gVG9kby5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBhbm5vdGF0ZSA9IEFubm90YXRlLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIHR5cGVBbm5vdGF0aW9ucyA9IFR5cGVBbm5vdGF0aW9ucy5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICB0eXBlcyA9IFR5cGVzLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIGRpYWdzID0gSkNEaWFnbm9zdGljLkZhY3RvcnkuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgZGVmZXJyZWRMaW50SGFuZGxlciA9IERlZmVycmVkTGludEhhbmRsZXIuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgbGludCA9IExpbnQuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgdHlwZUVudnMgPSBUeXBlRW52cy5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBkZXBlbmRlbmNpZXMgPSBEZXBlbmRlbmNpZXMuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgU291cmNlIHNvdXJjZSA9IFNvdXJjZS5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBhbGxvd1R5cGVBbm5vcyA9IHNvdXJjZS5hbGxvd1R5cGVBbm5vdGF0aW9ucygpOwogICAgICAgIGFsbG93RGVwcmVjYXRpb25PbkltcG9ydCA9IHNvdXJjZS5hbGxvd0RlcHJlY2F0aW9uT25JbXBvcnQoKTsKICAgIH0KCiAgICAvKiogU3dpdGNoOiBzdXBwb3J0IHR5cGUgYW5ub3RhdGlvbnMuCiAgICAgKi8KICAgIGJvb2xlYW4gYWxsb3dUeXBlQW5ub3M7CgogICAgLyoqCiAgICAgKiBTd2l0Y2g6IHNob3VsZCBkZXByZWNhdGlvbiB3YXJuaW5ncyBiZSBpc3N1ZWQgb24gaW1wb3J0CiAgICAgKi8KICAgIGJvb2xlYW4gYWxsb3dEZXByZWNhdGlvbk9uSW1wb3J0OwoKICAgIC8qKiBBIGZsYWcgdG8gZGlzYWJsZSBjb21wbGV0aW9uIGZyb20gdGltZSB0byB0aW1lIGR1cmluZyBtZW1iZXIKICAgICAqICBlbnRlciwgYXMgd2Ugb25seSBuZWVkIHRvIGxvb2sgdXAgdHlwZXMuICBUaGlzIGF2b2lkcwogICAgICogIHVubmVjZXNzYXJpbHkgZGVlcCByZWN1cnNpb24uCiAgICAgKi8KICAgIGJvb2xlYW4gY29tcGxldGlvbkVuYWJsZWQgPSB0cnVlOwoKICAgIC8qIFZlcmlmeSBJbXBvcnRzOgogICAgICovCiAgICBwcm90ZWN0ZWQgdm9pZCBlbnN1cmVJbXBvcnRzQ2hlY2tlZChMaXN0PEpDQ29tcGlsYXRpb25Vbml0PiB0cmVlcykgewogICAgICAgIC8vIGlmIHRoZXJlIHJlbWFpbiBhbnkgdW5pbXBvcnRlZCB0b3BsZXZlbHMgKHRoZXNlIG11c3QgaGF2ZQogICAgICAgIC8vIG5vIGNsYXNzZXMgYXQgYWxsKSwgcHJvY2VzcyB0aGVpciBpbXBvcnQgc3RhdGVtZW50cyBhcyB3ZWxsLgogICAgICAgIGZvciAoSkNDb21waWxhdGlvblVuaXQgdHJlZSA6IHRyZWVzKSB7CiAgICAgICAgICAgIGlmICghdHJlZS5zdGFySW1wb3J0U2NvcGUuaXNGaWxsZWQoKSkgewogICAgICAgICAgICAgICAgRW52PEF0dHJDb250ZXh0PiB0b3BFbnYgPSBlbnRlci50b3BMZXZlbEVudih0cmVlKTsKICAgICAgICAgICAgICAgIGZpbmlzaEltcG9ydHModHJlZSwgKCkgLT4geyBjb21wbGV0ZUNsYXNzLnJlc29sdmVJbXBvcnRzKHRyZWUsIHRvcEVudik7IH0pOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKLyogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU291cmNlIGNvbXBsZXRlcgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKICAgIC8qKiBDb21wbGV0ZSBlbnRlcmluZyBhIGNsYXNzLgogICAgICogIEBwYXJhbSBzeW0gICAgICAgICBUaGUgc3ltYm9sIG9mIHRoZSBjbGFzcyB0byBiZSBjb21wbGV0ZWQuCiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIHZvaWQgY29tcGxldGUoU3ltYm9sIHN5bSkgdGhyb3dzIENvbXBsZXRpb25GYWlsdXJlIHsKICAgICAgICAvLyBTdXBwcmVzcyBzb21lIChyZWN1cnNpdmUpIE1lbWJlckVudGVyIGludm9jYXRpb25zCiAgICAgICAgaWYgKCFjb21wbGV0aW9uRW5hYmxlZCkgewogICAgICAgICAgICAvLyBSZS1pbnN0YWxsIHNhbWUgY29tcGxldGVyIGZvciBuZXh0IHRpbWUgYXJvdW5kIGFuZCByZXR1cm4uCiAgICAgICAgICAgIEFzc2VydC5jaGVjaygoc3ltLmZsYWdzKCkgJiBGbGFncy5DT01QT1VORCkgPT0gMCk7CiAgICAgICAgICAgIHN5bS5jb21wbGV0ZXIgPSB0aGlzOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICB0cnkgewogICAgICAgICAgICBhbm5vdGF0ZS5ibG9ja0Fubm90YXRpb25zKCk7CiAgICAgICAgICAgIHN5bS5mbGFnc19maWVsZCB8PSBVTkFUVFJJQlVURUQ7CgogICAgICAgICAgICBMaXN0PEVudjxBdHRyQ29udGV4dD4+IHF1ZXVlOwoKICAgICAgICAgICAgZGVwZW5kZW5jaWVzLnB1c2goKENsYXNzU3ltYm9sKSBzeW0sIENvbXBsZXRpb25DYXVzZS5NRU1CRVJfRU5URVIpOwogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgcXVldWUgPSBjb21wbGV0ZUNsYXNzLmNvbXBsZXRlRW52cyhMaXN0Lm9mKHR5cGVFbnZzLmdldCgoQ2xhc3NTeW1ib2wpIHN5bSkpKTsKICAgICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgICAgIGRlcGVuZGVuY2llcy5wb3AoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCFxdWV1ZS5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICAgIFNldDxKQ0NvbXBpbGF0aW9uVW5pdD4gc2VlbiA9IG5ldyBIYXNoU2V0PD4oKTsKCiAgICAgICAgICAgICAgICBmb3IgKEVudjxBdHRyQ29udGV4dD4gZW52IDogcXVldWUpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoZW52LnRvcGxldmVsLmRlZnMuY29udGFpbnMoZW52LmVuY2xDbGFzcykgJiYgc2Vlbi5hZGQoZW52LnRvcGxldmVsKSkgewogICAgICAgICAgICAgICAgICAgICAgICBmaW5pc2hJbXBvcnRzKGVudi50b3BsZXZlbCwgKCkgLT4ge30pOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgIGFubm90YXRlLnVuYmxvY2tBbm5vdGF0aW9ucygpOwogICAgICAgIH0KICAgIH0KCiAgICB2b2lkIGZpbmlzaEltcG9ydHMoSkNDb21waWxhdGlvblVuaXQgdG9wbGV2ZWwsIFJ1bm5hYmxlIHJlc29sdmUpIHsKICAgICAgICBKYXZhRmlsZU9iamVjdCBwcmV2ID0gbG9nLnVzZVNvdXJjZSh0b3BsZXZlbC5zb3VyY2VmaWxlKTsKICAgICAgICB0cnkgewogICAgICAgICAgICByZXNvbHZlLnJ1bigpOwogICAgICAgICAgICBjaGsuY2hlY2tJbXBvcnRzVW5pcXVlKHRvcGxldmVsKTsKICAgICAgICAgICAgY2hrLmNoZWNrSW1wb3J0c1Jlc29sdmFibGUodG9wbGV2ZWwpOwogICAgICAgICAgICBjaGsuY2hlY2tJbXBvcnRlZFBhY2thZ2VzT2JzZXJ2YWJsZSh0b3BsZXZlbCk7CiAgICAgICAgICAgIHRvcGxldmVsLm5hbWVkSW1wb3J0U2NvcGUuZmluYWxpemVTY29wZSgpOwogICAgICAgICAgICB0b3BsZXZlbC5zdGFySW1wb3J0U2NvcGUuZmluYWxpemVTY29wZSgpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgIGxvZy51c2VTb3VyY2UocHJldik7CiAgICAgICAgfQogICAgfQoKICAgIGFic3RyYWN0IGNsYXNzIFBoYXNlIHsKICAgICAgICBwcml2YXRlIGZpbmFsIExpc3RCdWZmZXI8RW52PEF0dHJDb250ZXh0Pj4gcXVldWUgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgcHJpdmF0ZSBmaW5hbCBQaGFzZSBuZXh0OwogICAgICAgIHByaXZhdGUgZmluYWwgQ29tcGxldGlvbkNhdXNlIHBoYXNlTmFtZTsKCiAgICAgICAgUGhhc2UoQ29tcGxldGlvbkNhdXNlIHBoYXNlTmFtZSwgUGhhc2UgbmV4dCkgewogICAgICAgICAgICB0aGlzLnBoYXNlTmFtZSA9IHBoYXNlTmFtZTsKICAgICAgICAgICAgdGhpcy5uZXh0ID0gbmV4dDsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBmaW5hbCBMaXN0PEVudjxBdHRyQ29udGV4dD4+IGNvbXBsZXRlRW52cyhMaXN0PEVudjxBdHRyQ29udGV4dD4+IGVudnMpIHsKICAgICAgICAgICAgYm9vbGVhbiBmaXJzdFRvQ29tcGxldGUgPSBxdWV1ZS5pc0VtcHR5KCk7CgogICAgICAgICAgICBQaGFzZSBwcmV2VG9wTGV2ZWxQaGFzZSA9IHRvcExldmVsUGhhc2U7CgogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgdG9wTGV2ZWxQaGFzZSA9IHRoaXM7CiAgICAgICAgICAgICAgICBkb0NvbXBsZXRlRW52cyhlbnZzKTsKICAgICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgICAgIHRvcExldmVsUGhhc2UgPSBwcmV2VG9wTGV2ZWxQaGFzZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKGZpcnN0VG9Db21wbGV0ZSkgewogICAgICAgICAgICAgICAgTGlzdDxFbnY8QXR0ckNvbnRleHQ+PiBvdXQgPSBxdWV1ZS50b0xpc3QoKTsKCiAgICAgICAgICAgICAgICBxdWV1ZS5jbGVhcigpOwogICAgICAgICAgICAgICAgcmV0dXJuIG5leHQgIT0gbnVsbCA/IG5leHQuY29tcGxldGVFbnZzKG91dCkgOiBvdXQ7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICByZXR1cm4gTGlzdC5uaWwoKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHJvdGVjdGVkIHZvaWQgZG9Db21wbGV0ZUVudnMoTGlzdDxFbnY8QXR0ckNvbnRleHQ+PiBlbnZzKSB7CiAgICAgICAgICAgIGZvciAoRW52PEF0dHJDb250ZXh0PiBlbnYgOiBlbnZzKSB7CiAgICAgICAgICAgICAgICBKQ0NsYXNzRGVjbCB0cmVlID0gKEpDQ2xhc3NEZWNsKWVudi50cmVlOwoKICAgICAgICAgICAgICAgIHF1ZXVlLmFkZChlbnYpOwoKICAgICAgICAgICAgICAgIEphdmFGaWxlT2JqZWN0IHByZXYgPSBsb2cudXNlU291cmNlKGVudi50b3BsZXZlbC5zb3VyY2VmaWxlKTsKICAgICAgICAgICAgICAgIERpYWdub3N0aWNQb3NpdGlvbiBwcmV2TGludFBvcyA9IGRlZmVycmVkTGludEhhbmRsZXIuc2V0UG9zKHRyZWUucG9zKCkpOwogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICBkZXBlbmRlbmNpZXMucHVzaChlbnYuZW5jbENsYXNzLnN5bSwgcGhhc2VOYW1lKTsKICAgICAgICAgICAgICAgICAgICBydW5QaGFzZShlbnYpOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoQ29tcGxldGlvbkZhaWx1cmUgZXgpIHsKICAgICAgICAgICAgICAgICAgICBjaGsuY29tcGxldGlvbkVycm9yKHRyZWUucG9zKCksIGV4KTsKICAgICAgICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgICAgICAgICAgZGVwZW5kZW5jaWVzLnBvcCgpOwogICAgICAgICAgICAgICAgICAgIGRlZmVycmVkTGludEhhbmRsZXIuc2V0UG9zKHByZXZMaW50UG9zKTsKICAgICAgICAgICAgICAgICAgICBsb2cudXNlU291cmNlKHByZXYpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwcm90ZWN0ZWQgYWJzdHJhY3Qgdm9pZCBydW5QaGFzZShFbnY8QXR0ckNvbnRleHQ+IGVudik7CiAgICB9CgogICAgcHJpdmF0ZSBmaW5hbCBJbXBvcnRzUGhhc2UgY29tcGxldGVDbGFzcyA9IG5ldyBJbXBvcnRzUGhhc2UoKTsKICAgIHByaXZhdGUgUGhhc2UgdG9wTGV2ZWxQaGFzZTsKCiAgICAvKipBbmFseXplIGltcG9ydCBjbGF1c2VzLgogICAgICovCiAgICBwcml2YXRlIGZpbmFsIGNsYXNzIEltcG9ydHNQaGFzZSBleHRlbmRzIFBoYXNlIHsKCiAgICAgICAgcHVibGljIEltcG9ydHNQaGFzZSgpIHsKICAgICAgICAgICAgc3VwZXIoQ29tcGxldGlvbkNhdXNlLklNUE9SVFNfUEhBU0UsIG5ldyBIaWVyYXJjaHlQaGFzZSgpKTsKICAgICAgICB9CgogICAgICAgIEVudjxBdHRyQ29udGV4dD4gZW52OwogICAgICAgIEltcG9ydEZpbHRlciBzdGF0aWNJbXBvcnRGaWx0ZXI7CiAgICAgICAgSW1wb3J0RmlsdGVyIHR5cGVJbXBvcnRGaWx0ZXI7CiAgICAgICAgQmlDb25zdW1lcjxKQ0ltcG9ydCwgQ29tcGxldGlvbkZhaWx1cmU+IGNmSGFuZGxlciA9CiAgICAgICAgICAgICAgICAoaW1wLCBjZikgLT4gY2hrLmNvbXBsZXRpb25FcnJvcihpbXAucG9zKCksIGNmKTsKCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHJvdGVjdGVkIHZvaWQgcnVuUGhhc2UoRW52PEF0dHJDb250ZXh0PiBlbnYpIHsKICAgICAgICAgICAgSkNDbGFzc0RlY2wgdHJlZSA9IGVudi5lbmNsQ2xhc3M7CiAgICAgICAgICAgIENsYXNzU3ltYm9sIHN5bSA9IHRyZWUuc3ltOwoKICAgICAgICAgICAgLy8gSWYgc3ltIGlzIGEgdG9wbGV2ZWwtY2xhc3MsIG1ha2Ugc3VyZSBhbnkgaW1wb3J0CiAgICAgICAgICAgIC8vIGNsYXVzZXMgaW4gaXRzIHNvdXJjZSBmaWxlIGhhdmUgYmVlbiBzZWVuLgogICAgICAgICAgICBpZiAoc3ltLm93bmVyLmtpbmQgPT0gUENLKSB7CiAgICAgICAgICAgICAgICByZXNvbHZlSW1wb3J0cyhlbnYudG9wbGV2ZWwsIGVudi5lbmNsb3NpbmcoVE9QTEVWRUwpKTsKICAgICAgICAgICAgICAgIHRvZG8uYXBwZW5kKGVudik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChzeW0ub3duZXIua2luZCA9PSBUWVApCiAgICAgICAgICAgICAgICBzeW0ub3duZXIuY29tcGxldGUoKTsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgdm9pZCByZXNvbHZlSW1wb3J0cyhKQ0NvbXBpbGF0aW9uVW5pdCB0cmVlLCBFbnY8QXR0ckNvbnRleHQ+IGVudikgewogICAgICAgICAgICBpZiAodHJlZS5zdGFySW1wb3J0U2NvcGUuaXNGaWxsZWQoKSkgewogICAgICAgICAgICAgICAgLy8gd2UgbXVzdCBoYXZlIGFscmVhZHkgcHJvY2Vzc2VkIHRoaXMgdG9wbGV2ZWwKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgSW1wb3J0RmlsdGVyIHByZXZTdGF0aWNJbXBvcnRGaWx0ZXIgPSBzdGF0aWNJbXBvcnRGaWx0ZXI7CiAgICAgICAgICAgIEltcG9ydEZpbHRlciBwcmV2VHlwZUltcG9ydEZpbHRlciA9IHR5cGVJbXBvcnRGaWx0ZXI7CiAgICAgICAgICAgIERpYWdub3N0aWNQb3NpdGlvbiBwcmV2TGludFBvcyA9IGRlZmVycmVkTGludEhhbmRsZXIuaW1tZWRpYXRlKCk7CiAgICAgICAgICAgIExpbnQgcHJldkxpbnQgPSBjaGsuc2V0TGludChsaW50KTsKICAgICAgICAgICAgRW52PEF0dHJDb250ZXh0PiBwcmV2RW52ID0gdGhpcy5lbnY7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICB0aGlzLmVudiA9IGVudjsKICAgICAgICAgICAgICAgIGZpbmFsIFBhY2thZ2VTeW1ib2wgcGFja2dlID0gZW52LnRvcGxldmVsLnBhY2tnZTsKICAgICAgICAgICAgICAgIHRoaXMuc3RhdGljSW1wb3J0RmlsdGVyID0KICAgICAgICAgICAgICAgICAgICAgICAgKG9yaWdpbiwgc3ltKSAtPiBzeW0uaXNTdGF0aWMoKSAmJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoay5pbXBvcnRBY2Nlc3NpYmxlKHN5bSwgcGFja2dlKSAmJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5bS5pc01lbWJlck9mKChUeXBlU3ltYm9sKSBvcmlnaW4ub3duZXIsIHR5cGVzKTsKICAgICAgICAgICAgICAgIHRoaXMudHlwZUltcG9ydEZpbHRlciA9CiAgICAgICAgICAgICAgICAgICAgICAgIChvcmlnaW4sIHN5bSkgLT4gc3ltLmtpbmQgPT0gVFlQICYmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hrLmltcG9ydEFjY2Vzc2libGUoc3ltLCBwYWNrZ2UpOwoKICAgICAgICAgICAgICAgIC8vIEltcG9ydC1vbi1kZW1hbmQgamF2YS5sYW5nLgogICAgICAgICAgICAgICAgUGFja2FnZVN5bWJvbCBqYXZhTGFuZyA9IHN5bXMuZW50ZXJQYWNrYWdlKHN5bXMuamF2YV9iYXNlLCBuYW1lcy5qYXZhX2xhbmcpOwogICAgICAgICAgICAgICAgaWYgKGphdmFMYW5nLm1lbWJlcnMoKS5pc0VtcHR5KCkgJiYgIWphdmFMYW5nLmV4aXN0cygpKQogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBGYXRhbEVycm9yKGRpYWdzLmZyYWdtZW50KCJmYXRhbC5lcnIubm8uamF2YS5sYW5nIikpOwogICAgICAgICAgICAgICAgaW1wb3J0QWxsKG1ha2UuYXQodHJlZS5wb3MoKSkuSW1wb3J0KG1ha2UuUXVhbElkZW50KGphdmFMYW5nKSwgZmFsc2UpLCBqYXZhTGFuZywgZW52KTsKCiAgICAgICAgICAgICAgICBKQ01vZHVsZURlY2wgZGVjbCA9IHRyZWUuZ2V0TW9kdWxlRGVjbCgpOwoKICAgICAgICAgICAgICAgIC8vIFByb2Nlc3MgdGhlIHBhY2thZ2UgZGVmIGFuZCBhbGwgaW1wb3J0IGNsYXVzZXMuCiAgICAgICAgICAgICAgICBpZiAodHJlZS5nZXRQYWNrYWdlKCkgIT0gbnVsbCAmJiBkZWNsID09IG51bGwpCiAgICAgICAgICAgICAgICAgICAgY2hlY2tDbGFzc1BhY2thZ2VDbGFzaCh0cmVlLmdldFBhY2thZ2UoKSk7CgogICAgICAgICAgICAgICAgZm9yIChKQ0ltcG9ydCBpbXAgOiB0cmVlLmdldEltcG9ydHMoKSkgewogICAgICAgICAgICAgICAgICAgIGRvSW1wb3J0KGltcCk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKGRlY2wgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIC8vY2hlY2sgQERlcHJlY2F0ZWQ6CiAgICAgICAgICAgICAgICAgICAgbWFya0RlcHJlY2F0ZWQoZGVjbC5zeW0sIGRlY2wubW9kcy5hbm5vdGF0aW9ucywgZW52KTsKICAgICAgICAgICAgICAgICAgICAvLyBwcm9jZXNzIG1vZHVsZSBhbm5vdGF0aW9ucwogICAgICAgICAgICAgICAgICAgIGFubm90YXRlLmFubm90YXRlTGF0ZXIoZGVjbC5tb2RzLmFubm90YXRpb25zLCBlbnYsIGVudi50b3BsZXZlbC5tb2RsZSwgbnVsbCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgICAgICB0aGlzLmVudiA9IHByZXZFbnY7CiAgICAgICAgICAgICAgICBjaGsuc2V0TGludChwcmV2TGludCk7CiAgICAgICAgICAgICAgICBkZWZlcnJlZExpbnRIYW5kbGVyLnNldFBvcyhwcmV2TGludFBvcyk7CiAgICAgICAgICAgICAgICB0aGlzLnN0YXRpY0ltcG9ydEZpbHRlciA9IHByZXZTdGF0aWNJbXBvcnRGaWx0ZXI7CiAgICAgICAgICAgICAgICB0aGlzLnR5cGVJbXBvcnRGaWx0ZXIgPSBwcmV2VHlwZUltcG9ydEZpbHRlcjsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSB2b2lkIGNoZWNrQ2xhc3NQYWNrYWdlQ2xhc2goSkNQYWNrYWdlRGVjbCB0cmVlKSB7CiAgICAgICAgICAgIC8vIGNoZWNrIHRoYXQgbm8gY2xhc3MgZXhpc3RzIHdpdGggc2FtZSBmdWxseSBxdWFsaWZpZWQgbmFtZSBhcwogICAgICAgICAgICAvLyB0b3BsZXZlbCBwYWNrYWdlCiAgICAgICAgICAgIGlmIChjaGVja0NsYXNoICYmIHRyZWUucGlkICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIFN5bWJvbCBwID0gZW52LnRvcGxldmVsLnBhY2tnZTsKICAgICAgICAgICAgICAgIHdoaWxlIChwLm93bmVyICE9IHN5bXMucm9vdFBhY2thZ2UpIHsKICAgICAgICAgICAgICAgICAgICBwLm93bmVyLmNvbXBsZXRlKCk7IC8vIGVudGVyIGFsbCBjbGFzcyBtZW1iZXJzIG9mIHAKICAgICAgICAgICAgICAgICAgICAvL25lZWQgdG8gbG9va3VwIHRoZSBvd25pbmcgbW9kdWxlL3BhY2thZ2U6CiAgICAgICAgICAgICAgICAgICAgUGFja2FnZVN5bWJvbCBwYWNrID0gc3ltcy5sb29rdXBQYWNrYWdlKGVudi50b3BsZXZlbC5tb2RsZSwgcC5vd25lci5nZXRRdWFsaWZpZWROYW1lKCkpOwogICAgICAgICAgICAgICAgICAgIGlmIChzeW1zLmdldENsYXNzKHBhY2subW9kbGUsIHAuZ2V0UXVhbGlmaWVkTmFtZSgpKSAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGxvZy5lcnJvcih0cmVlLnBvcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJwa2cuY2xhc2hlcy53aXRoLmNsYXNzLm9mLnNhbWUubmFtZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgcCA9IHAub3duZXI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gcHJvY2VzcyBwYWNrYWdlIGFubm90YXRpb25zCiAgICAgICAgICAgIGFubm90YXRlLmFubm90YXRlTGF0ZXIodHJlZS5hbm5vdGF0aW9ucywgZW52LCBlbnYudG9wbGV2ZWwucGFja2dlLCBudWxsKTsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgdm9pZCBkb0ltcG9ydChKQ0ltcG9ydCB0cmVlKSB7CiAgICAgICAgICAgIEpDRmllbGRBY2Nlc3MgaW1wID0gKEpDRmllbGRBY2Nlc3MpdHJlZS5xdWFsaWQ7CiAgICAgICAgICAgIE5hbWUgbmFtZSA9IFRyZWVJbmZvLm5hbWUoaW1wKTsKCiAgICAgICAgICAgIC8vIENyZWF0ZSBhIGxvY2FsIGVudmlyb25tZW50IHBvaW50aW5nIHRvIHRoaXMgdHJlZSB0byBkaXNhYmxlCiAgICAgICAgICAgIC8vIGVmZmVjdHMgb2Ygb3RoZXIgaW1wb3J0cyBpbiBSZXNvbHZlLmZpbmRHbG9iYWxUeXBlCiAgICAgICAgICAgIEVudjxBdHRyQ29udGV4dD4gbG9jYWxFbnYgPSBlbnYuZHVwKHRyZWUpOwoKICAgICAgICAgICAgVHlwZVN5bWJvbCBwID0gYXR0ci5hdHRyaWJJbXBvcnRRdWFsaWZpZXIodHJlZSwgbG9jYWxFbnYpLnRzeW07CiAgICAgICAgICAgIGlmIChuYW1lID09IG5hbWVzLmFzdGVyaXNrKSB7CiAgICAgICAgICAgICAgICAvLyBJbXBvcnQgb24gZGVtYW5kLgogICAgICAgICAgICAgICAgY2hrLmNoZWNrQ2Fub25pY2FsKGltcC5zZWxlY3RlZCk7CiAgICAgICAgICAgICAgICBpZiAodHJlZS5zdGF0aWNJbXBvcnQpCiAgICAgICAgICAgICAgICAgICAgaW1wb3J0U3RhdGljQWxsKHRyZWUsIHAsIGVudik7CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgaW1wb3J0QWxsKHRyZWUsIHAsIGVudik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvLyBOYW1lZCB0eXBlIGltcG9ydC4KICAgICAgICAgICAgICAgIGlmICh0cmVlLnN0YXRpY0ltcG9ydCkgewogICAgICAgICAgICAgICAgICAgIGltcG9ydE5hbWVkU3RhdGljKHRyZWUsIHAsIG5hbWUsIGxvY2FsRW52KTsKICAgICAgICAgICAgICAgICAgICBjaGsuY2hlY2tDYW5vbmljYWwoaW1wLnNlbGVjdGVkKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgVHlwZSBpbXBvcnRlZFR5cGUgPSBhdHRyaWJJbXBvcnRUeXBlKGltcCwgbG9jYWxFbnYpOwogICAgICAgICAgICAgICAgICAgIFR5cGUgb3JpZ2luYWxUeXBlID0gaW1wb3J0ZWRUeXBlLmdldE9yaWdpbmFsVHlwZSgpOwogICAgICAgICAgICAgICAgICAgIFR5cGVTeW1ib2wgYyA9IG9yaWdpbmFsVHlwZS5oYXNUYWcoQ0xBU1MpID8gb3JpZ2luYWxUeXBlLnRzeW0gOiBpbXBvcnRlZFR5cGUudHN5bTsKICAgICAgICAgICAgICAgICAgICBjaGsuY2hlY2tDYW5vbmljYWwoaW1wKTsKICAgICAgICAgICAgICAgICAgICBpbXBvcnROYW1lZCh0cmVlLnBvcygpLCBjLCBlbnYsIHRyZWUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBUeXBlIGF0dHJpYkltcG9ydFR5cGUoSkNUcmVlIHRyZWUsIEVudjxBdHRyQ29udGV4dD4gZW52KSB7CiAgICAgICAgICAgIEFzc2VydC5jaGVjayhjb21wbGV0aW9uRW5hYmxlZCk7CiAgICAgICAgICAgIExpbnQgcHJldkxpbnQgPSBjaGsuc2V0TGludChhbGxvd0RlcHJlY2F0aW9uT25JbXBvcnQgPwogICAgICAgICAgICAgICAgICAgIGxpbnQgOiBsaW50LnN1cHByZXNzKExpbnRDYXRlZ29yeS5ERVBSRUNBVElPTiwgTGludENhdGVnb3J5LlJFTU9WQUwpKTsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIC8vIFRvIHByZXZlbnQgZGVlcCByZWN1cnNpb24sIHN1cHByZXNzIGNvbXBsZXRpb24gb2Ygc29tZQogICAgICAgICAgICAgICAgLy8gdHlwZXMuCiAgICAgICAgICAgICAgICBjb21wbGV0aW9uRW5hYmxlZCA9IGZhbHNlOwogICAgICAgICAgICAgICAgcmV0dXJuIGF0dHIuYXR0cmliVHlwZSh0cmVlLCBlbnYpOwogICAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAgICAgY29tcGxldGlvbkVuYWJsZWQgPSB0cnVlOwogICAgICAgICAgICAgICAgY2hrLnNldExpbnQocHJldkxpbnQpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvKiogSW1wb3J0IGFsbCBjbGFzc2VzIG9mIGEgY2xhc3Mgb3IgcGFja2FnZSBvbiBkZW1hbmQuCiAgICAgICAgICogIEBwYXJhbSBpbXAgICAgICAgICAgIFRoZSBpbXBvcnQgdGhhdCBpcyBiZWluZyBoYW5kbGVkLgogICAgICAgICAqICBAcGFyYW0gdHN5bSAgICAgICAgICBUaGUgY2xhc3Mgb3IgcGFja2FnZSB0aGUgbWVtYmVycyBvZiB3aGljaCBhcmUgaW1wb3J0ZWQuCiAgICAgICAgICogIEBwYXJhbSBlbnYgICAgICAgICAgIFRoZSBlbnYgaW4gd2hpY2ggdGhlIGltcG9ydGVkIGNsYXNzZXMgd2lsbCBiZSBlbnRlcmVkLgogICAgICAgICAqLwogICAgICAgIHByaXZhdGUgdm9pZCBpbXBvcnRBbGwoSkNJbXBvcnQgaW1wLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgVHlwZVN5bWJvbCB0c3ltLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRW52PEF0dHJDb250ZXh0PiBlbnYpIHsKICAgICAgICAgICAgZW52LnRvcGxldmVsLnN0YXJJbXBvcnRTY29wZS5pbXBvcnRBbGwodHlwZXMsIHRzeW0ubWVtYmVycygpLCB0eXBlSW1wb3J0RmlsdGVyLCBpbXAsIGNmSGFuZGxlcik7CiAgICAgICAgfQoKICAgICAgICAvKiogSW1wb3J0IGFsbCBzdGF0aWMgbWVtYmVycyBvZiBhIGNsYXNzIG9yIHBhY2thZ2Ugb24gZGVtYW5kLgogICAgICAgICAqICBAcGFyYW0gaW1wICAgICAgICAgICBUaGUgaW1wb3J0IHRoYXQgaXMgYmVpbmcgaGFuZGxlZC4KICAgICAgICAgKiAgQHBhcmFtIHRzeW0gICAgICAgICAgVGhlIGNsYXNzIG9yIHBhY2thZ2UgdGhlIG1lbWJlcnMgb2Ygd2hpY2ggYXJlIGltcG9ydGVkLgogICAgICAgICAqICBAcGFyYW0gZW52ICAgICAgICAgICBUaGUgZW52IGluIHdoaWNoIHRoZSBpbXBvcnRlZCBjbGFzc2VzIHdpbGwgYmUgZW50ZXJlZC4KICAgICAgICAgKi8KICAgICAgICBwcml2YXRlIHZvaWQgaW1wb3J0U3RhdGljQWxsKEpDSW1wb3J0IGltcCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIFR5cGVTeW1ib2wgdHN5bSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVudjxBdHRyQ29udGV4dD4gZW52KSB7CiAgICAgICAgICAgIGZpbmFsIFN0YXJJbXBvcnRTY29wZSB0b1Njb3BlID0gZW52LnRvcGxldmVsLnN0YXJJbXBvcnRTY29wZTsKICAgICAgICAgICAgZmluYWwgVHlwZVN5bWJvbCBvcmlnaW4gPSB0c3ltOwoKICAgICAgICAgICAgdG9TY29wZS5pbXBvcnRBbGwodHlwZXMsIG9yaWdpbi5tZW1iZXJzKCksIHN0YXRpY0ltcG9ydEZpbHRlciwgaW1wLCBjZkhhbmRsZXIpOwogICAgICAgIH0KCiAgICAgICAgLyoqIEltcG9ydCBzdGF0aWNzIHR5cGVzIG9mIGEgZ2l2ZW4gbmFtZS4gIE5vbi10eXBlcyBhcmUgaGFuZGxlZCBpbiBBdHRyLgogICAgICAgICAqICBAcGFyYW0gaW1wICAgICAgICAgICBUaGUgaW1wb3J0IHRoYXQgaXMgYmVpbmcgaGFuZGxlZC4KICAgICAgICAgKiAgQHBhcmFtIHRzeW0gICAgICAgICAgVGhlIGNsYXNzIGZyb20gd2hpY2ggdGhlIG5hbWUgaXMgaW1wb3J0ZWQuCiAgICAgICAgICogIEBwYXJhbSBuYW1lICAgICAgICAgIFRoZSAoc2ltcGxlKSBuYW1lIGJlaW5nIGltcG9ydGVkLgogICAgICAgICAqICBAcGFyYW0gZW52ICAgICAgICAgICBUaGUgZW52aXJvbm1lbnQgY29udGFpbmluZyB0aGUgbmFtZWQgaW1wb3J0CiAgICAgICAgICogICAgICAgICAgICAgICAgICBzY29wZSB0byBhZGQgdG8uCiAgICAgICAgICovCiAgICAgICAgcHJpdmF0ZSB2b2lkIGltcG9ydE5hbWVkU3RhdGljKGZpbmFsIEpDSW1wb3J0IGltcCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgVHlwZVN5bWJvbCB0c3ltLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBOYW1lIG5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIEVudjxBdHRyQ29udGV4dD4gZW52KSB7CiAgICAgICAgICAgIGlmICh0c3ltLmtpbmQgIT0gVFlQKSB7CiAgICAgICAgICAgICAgICBsb2cuZXJyb3IoRGlhZ25vc3RpY0ZsYWcuUkVDT1ZFUkFCTEUsIGltcC5wb3MoKSwgInN0YXRpYy5pbXAub25seS5jbGFzc2VzLmFuZC5pbnRlcmZhY2VzIik7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGZpbmFsIE5hbWVkSW1wb3J0U2NvcGUgdG9TY29wZSA9IGVudi50b3BsZXZlbC5uYW1lZEltcG9ydFNjb3BlOwogICAgICAgICAgICBmaW5hbCBTY29wZSBvcmlnaW5NZW1iZXJzID0gdHN5bS5tZW1iZXJzKCk7CgogICAgICAgICAgICBpbXAuaW1wb3J0U2NvcGUgPSB0b1Njb3BlLmltcG9ydEJ5TmFtZSh0eXBlcywgb3JpZ2luTWVtYmVycywgbmFtZSwgc3RhdGljSW1wb3J0RmlsdGVyLCBpbXAsIGNmSGFuZGxlcik7CiAgICAgICAgfQoKICAgICAgICAvKiogSW1wb3J0IGdpdmVuIGNsYXNzLgogICAgICAgICAqICBAcGFyYW0gcG9zICAgICAgICAgICBQb3NpdGlvbiB0byBiZSB1c2VkIGZvciBlcnJvciByZXBvcnRpbmcuCiAgICAgICAgICogIEBwYXJhbSB0c3ltICAgICAgICAgIFRoZSBjbGFzcyB0byBiZSBpbXBvcnRlZC4KICAgICAgICAgKiAgQHBhcmFtIGVudiAgICAgICAgICAgVGhlIGVudmlyb25tZW50IGNvbnRhaW5pbmcgdGhlIG5hbWVkIGltcG9ydAogICAgICAgICAqICAgICAgICAgICAgICAgICAgc2NvcGUgdG8gYWRkIHRvLgogICAgICAgICAqLwogICAgICAgIHByaXZhdGUgdm9pZCBpbXBvcnROYW1lZChEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBmaW5hbCBTeW1ib2wgdHN5bSwgRW52PEF0dHJDb250ZXh0PiBlbnYsIEpDSW1wb3J0IGltcCkgewogICAgICAgICAgICBpZiAodHN5bS5raW5kID09IFRZUCkKICAgICAgICAgICAgICAgIGltcC5pbXBvcnRTY29wZSA9IGVudi50b3BsZXZlbC5uYW1lZEltcG9ydFNjb3BlLmltcG9ydFR5cGUodHN5bS5vd25lci5tZW1iZXJzKCksIHRzeW0ub3duZXIubWVtYmVycygpLCB0c3ltKTsKICAgICAgICB9CgogICAgfQoKICAgIC8qKkRlZmluZXMgY29tbW9uIHV0aWxpdHkgbWV0aG9kcyB1c2VkIGJ5IHRoZSBIaWVyYXJjaHlQaGFzZSBhbmQgSGVhZGVyUGhhc2UuCiAgICAgKi8KICAgIHByaXZhdGUgYWJzdHJhY3QgY2xhc3MgQWJzdHJhY3RIZWFkZXJQaGFzZSBleHRlbmRzIFBoYXNlIHsKCiAgICAgICAgcHVibGljIEFic3RyYWN0SGVhZGVyUGhhc2UoQ29tcGxldGlvbkNhdXNlIHBoYXNlTmFtZSwgUGhhc2UgbmV4dCkgewogICAgICAgICAgICBzdXBlcihwaGFzZU5hbWUsIG5leHQpOwogICAgICAgIH0KCiAgICAgICAgcHJvdGVjdGVkIEVudjxBdHRyQ29udGV4dD4gYmFzZUVudihKQ0NsYXNzRGVjbCB0cmVlLCBFbnY8QXR0ckNvbnRleHQ+IGVudikgewogICAgICAgICAgICBXcml0ZWFibGVTY29wZSBiYXNlU2NvcGUgPSBXcml0ZWFibGVTY29wZS5jcmVhdGUodHJlZS5zeW0pOwogICAgICAgICAgICAvL2ltcG9ydCBhbHJlYWR5IGVudGVyZWQgbG9jYWwgY2xhc3NlcyBpbnRvIGJhc2Ugc2NvcGUKICAgICAgICAgICAgZm9yIChTeW1ib2wgc3ltIDogZW52Lm91dGVyLmluZm8uc2NvcGUuZ2V0U3ltYm9scyhOT05fUkVDVVJTSVZFKSkgewogICAgICAgICAgICAgICAgaWYgKHN5bS5pc0xvY2FsKCkpIHsKICAgICAgICAgICAgICAgICAgICBiYXNlU2NvcGUuZW50ZXIoc3ltKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICAvL2ltcG9ydCBjdXJyZW50IHR5cGUtcGFyYW1ldGVycyBpbnRvIGJhc2Ugc2NvcGUKICAgICAgICAgICAgaWYgKHRyZWUudHlwYXJhbXMgIT0gbnVsbCkKICAgICAgICAgICAgICAgIGZvciAoTGlzdDxKQ1R5cGVQYXJhbWV0ZXI+IHR5cGFyYW1zID0gdHJlZS50eXBhcmFtczsKICAgICAgICAgICAgICAgICAgICAgdHlwYXJhbXMubm9uRW1wdHkoKTsKICAgICAgICAgICAgICAgICAgICAgdHlwYXJhbXMgPSB0eXBhcmFtcy50YWlsKQogICAgICAgICAgICAgICAgICAgIGJhc2VTY29wZS5lbnRlcih0eXBhcmFtcy5oZWFkLnR5cGUudHN5bSk7CiAgICAgICAgICAgIEVudjxBdHRyQ29udGV4dD4gb3V0ZXIgPSBlbnYub3V0ZXI7IC8vIHRoZSBiYXNlIGNsYXVzZSBjYW4ndCBzZWUgbWVtYmVycyBvZiB0aGlzIGNsYXNzCiAgICAgICAgICAgIEVudjxBdHRyQ29udGV4dD4gbG9jYWxFbnYgPSBvdXRlci5kdXAodHJlZSwgb3V0ZXIuaW5mby5kdXAoYmFzZVNjb3BlKSk7CiAgICAgICAgICAgIGxvY2FsRW52LmJhc2VDbGF1c2UgPSB0cnVlOwogICAgICAgICAgICBsb2NhbEVudi5vdXRlciA9IG91dGVyOwogICAgICAgICAgICBsb2NhbEVudi5pbmZvLmlzU2VsZkNhbGwgPSBmYWxzZTsKICAgICAgICAgICAgcmV0dXJuIGxvY2FsRW52OwogICAgICAgIH0KCiAgICAgICAgLyoqIEdlbmVyYXRlIGEgYmFzZSBjbGF1c2UgZm9yIGFuIGVudW0gdHlwZS4KICAgICAgICAgKiAgQHBhcmFtIHBvcyAgICAgICAgICAgICAgVGhlIHBvc2l0aW9uIGZvciB0cmVlcyBhbmQgZGlhZ25vc3RpY3MsIGlmIGFueQogICAgICAgICAqICBAcGFyYW0gYyAgICAgICAgICAgICAgICBUaGUgY2xhc3Mgc3ltYm9sIG9mIHRoZSBlbnVtCiAgICAgICAgICovCiAgICAgICAgcHJvdGVjdGVkICBKQ0V4cHJlc3Npb24gZW51bUJhc2UoaW50IHBvcywgQ2xhc3NTeW1ib2wgYykgewogICAgICAgICAgICBKQ0V4cHJlc3Npb24gcmVzdWx0ID0gbWFrZS5hdChwb3MpLgogICAgICAgICAgICAgICAgVHlwZUFwcGx5KG1ha2UuUXVhbElkZW50KHN5bXMuZW51bVN5bSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgTGlzdC5vZihtYWtlLlR5cGUoYy50eXBlKSkpOwogICAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgIH0KCiAgICAgICAgcHJvdGVjdGVkIFR5cGUgbW9kZWxNaXNzaW5nVHlwZXMoRW52PEF0dHJDb250ZXh0PiBlbnYsIFR5cGUgdCwgZmluYWwgSkNFeHByZXNzaW9uIHRyZWUsIGZpbmFsIGJvb2xlYW4gaW50ZXJmYWNlRXhwZWN0ZWQpIHsKICAgICAgICAgICAgaWYgKCF0Lmhhc1RhZyhFUlJPUikpCiAgICAgICAgICAgICAgICByZXR1cm4gdDsKCiAgICAgICAgICAgIHJldHVybiBuZXcgRXJyb3JUeXBlKHQuZ2V0T3JpZ2luYWxUeXBlKCksIHQudHN5bSkgewogICAgICAgICAgICAgICAgcHJpdmF0ZSBUeXBlIG1vZGVsVHlwZTsKCiAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgICAgIHB1YmxpYyBUeXBlIGdldE1vZGVsVHlwZSgpIHsKICAgICAgICAgICAgICAgICAgICBpZiAobW9kZWxUeXBlID09IG51bGwpCiAgICAgICAgICAgICAgICAgICAgICAgIG1vZGVsVHlwZSA9IG5ldyBTeW50aGVzaXplcihlbnYudG9wbGV2ZWwubW9kbGUsIGdldE9yaWdpbmFsVHlwZSgpLCBpbnRlcmZhY2VFeHBlY3RlZCkudmlzaXQodHJlZSk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG1vZGVsVHlwZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKICAgICAgICB9CiAgICAgICAgICAgIC8vIHdoZXJlOgogICAgICAgICAgICBwcml2YXRlIGNsYXNzIFN5bnRoZXNpemVyIGV4dGVuZHMgSkNUcmVlLlZpc2l0b3IgewogICAgICAgICAgICAgICAgTW9kdWxlU3ltYm9sIG1zeW07CiAgICAgICAgICAgICAgICBUeXBlIG9yaWdpbmFsVHlwZTsKICAgICAgICAgICAgICAgIGJvb2xlYW4gaW50ZXJmYWNlRXhwZWN0ZWQ7CiAgICAgICAgICAgICAgICBMaXN0PENsYXNzU3ltYm9sPiBzeW50aGVzaXplZFN5bWJvbHMgPSBMaXN0Lm5pbCgpOwogICAgICAgICAgICAgICAgVHlwZSByZXN1bHQ7CgogICAgICAgICAgICAgICAgU3ludGhlc2l6ZXIoTW9kdWxlU3ltYm9sIG1zeW0sIFR5cGUgb3JpZ2luYWxUeXBlLCBib29sZWFuIGludGVyZmFjZUV4cGVjdGVkKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5tc3ltID0gbXN5bTsKICAgICAgICAgICAgICAgICAgICB0aGlzLm9yaWdpbmFsVHlwZSA9IG9yaWdpbmFsVHlwZTsKICAgICAgICAgICAgICAgICAgICB0aGlzLmludGVyZmFjZUV4cGVjdGVkID0gaW50ZXJmYWNlRXhwZWN0ZWQ7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgVHlwZSB2aXNpdChKQ1RyZWUgdHJlZSkgewogICAgICAgICAgICAgICAgICAgIHRyZWUuYWNjZXB0KHRoaXMpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgTGlzdDxUeXBlPiB2aXNpdChMaXN0PD8gZXh0ZW5kcyBKQ1RyZWU+IHRyZWVzKSB7CiAgICAgICAgICAgICAgICAgICAgTGlzdEJ1ZmZlcjxUeXBlPiBsYiA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICAgICAgICAgICAgICBmb3IgKEpDVHJlZSB0OiB0cmVlcykKICAgICAgICAgICAgICAgICAgICAgICAgbGIuYXBwZW5kKHZpc2l0KHQpKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbGIudG9MaXN0KCk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdFRyZWUoSkNUcmVlIHRyZWUpIHsKICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBzeW1zLmVyclR5cGU7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdElkZW50KEpDSWRlbnQgdHJlZSkgewogICAgICAgICAgICAgICAgICAgIGlmICghdHJlZS50eXBlLmhhc1RhZyhFUlJPUikpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gdHJlZS50eXBlOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IHN5bnRoZXNpemVDbGFzcyh0cmVlLm5hbWUsIG1zeW0udW5uYW1lZFBhY2thZ2UpLnR5cGU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICAgICAgcHVibGljIHZvaWQgdmlzaXRTZWxlY3QoSkNGaWVsZEFjY2VzcyB0cmVlKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCF0cmVlLnR5cGUuaGFzVGFnKEVSUk9SKSkgewogICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSB0cmVlLnR5cGU7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgVHlwZSBzZWxlY3RlZFR5cGU7CiAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gcHJldiA9IGludGVyZmFjZUV4cGVjdGVkOwogICAgICAgICAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50ZXJmYWNlRXhwZWN0ZWQgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGVjdGVkVHlwZSA9IHZpc2l0KHRyZWUuc2VsZWN0ZWQpOwogICAgICAgICAgICAgICAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50ZXJmYWNlRXhwZWN0ZWQgPSBwcmV2OwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIENsYXNzU3ltYm9sIGMgPSBzeW50aGVzaXplQ2xhc3ModHJlZS5uYW1lLCBzZWxlY3RlZFR5cGUudHN5bSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IGMudHlwZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdFR5cGVBcHBseShKQ1R5cGVBcHBseSB0cmVlKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCF0cmVlLnR5cGUuaGFzVGFnKEVSUk9SKSkgewogICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSB0cmVlLnR5cGU7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgQ2xhc3NUeXBlIGNsYXp6VHlwZSA9IChDbGFzc1R5cGUpIHZpc2l0KHRyZWUuY2xhenopOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3ludGhlc2l6ZWRTeW1ib2xzLmNvbnRhaW5zKGNsYXp6VHlwZS50c3ltKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5bnRoZXNpemVUeXBhcmFtcygoQ2xhc3NTeW1ib2wpIGNsYXp6VHlwZS50c3ltLCB0cmVlLmFyZ3VtZW50cy5zaXplKCkpOwogICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBMaXN0PFR5cGU+IGFjdHVhbHMgPSB2aXNpdCh0cmVlLmFyZ3VtZW50cyk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IG5ldyBFcnJvclR5cGUodHJlZS50eXBlLCBjbGF6elR5cGUudHN5bSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgcHVibGljIExpc3Q8VHlwZT4gZ2V0VHlwZUFyZ3VtZW50cygpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYWN0dWFsczsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgQ2xhc3NTeW1ib2wgc3ludGhlc2l6ZUNsYXNzKE5hbWUgbmFtZSwgU3ltYm9sIG93bmVyKSB7CiAgICAgICAgICAgICAgICAgICAgaW50IGZsYWdzID0gaW50ZXJmYWNlRXhwZWN0ZWQgPyBJTlRFUkZBQ0UgOiAwOwogICAgICAgICAgICAgICAgICAgIENsYXNzU3ltYm9sIGMgPSBuZXcgQ2xhc3NTeW1ib2woZmxhZ3MsIG5hbWUsIG93bmVyKTsKICAgICAgICAgICAgICAgICAgICBjLm1lbWJlcnNfZmllbGQgPSBuZXcgU2NvcGUuRXJyb3JTY29wZShjKTsKICAgICAgICAgICAgICAgICAgICBjLnR5cGUgPSBuZXcgRXJyb3JUeXBlKG9yaWdpbmFsVHlwZSwgYykgewogICAgICAgICAgICAgICAgICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICAgICAgICAgICAgICAgICAgICAgIHB1YmxpYyBMaXN0PFR5cGU+IGdldFR5cGVBcmd1bWVudHMoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHlwYXJhbXNfZmllbGQ7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgICAgIHN5bnRoZXNpemVkU3ltYm9scyA9IHN5bnRoZXNpemVkU3ltYm9scy5wcmVwZW5kKGMpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBjOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHZvaWQgc3ludGhlc2l6ZVR5cGFyYW1zKENsYXNzU3ltYm9sIHN5bSwgaW50IG4pIHsKICAgICAgICAgICAgICAgICAgICBDbGFzc1R5cGUgY3QgPSAoQ2xhc3NUeXBlKSBzeW0udHlwZTsKICAgICAgICAgICAgICAgICAgICBBc3NlcnQuY2hlY2soY3QudHlwYXJhbXNfZmllbGQuaXNFbXB0eSgpKTsKICAgICAgICAgICAgICAgICAgICBpZiAobiA9PSAxKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIFR5cGVWYXIgdiA9IG5ldyBUeXBlVmFyKG5hbWVzLmZyb21TdHJpbmcoIlQiKSwgc3ltLCBzeW1zLmJvdFR5cGUpOwogICAgICAgICAgICAgICAgICAgICAgICBjdC50eXBhcmFtc19maWVsZCA9IGN0LnR5cGFyYW1zX2ZpZWxkLnByZXBlbmQodik7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IG47IGkgPiAwOyBpLS0pIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFR5cGVWYXIgdiA9IG5ldyBUeXBlVmFyKG5hbWVzLmZyb21TdHJpbmcoIlQiICsgaSksIHN5bSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5bXMuYm90VHlwZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdC50eXBhcmFtc19maWVsZCA9IGN0LnR5cGFyYW1zX2ZpZWxkLnByZXBlbmQodik7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgcHJvdGVjdGVkIHZvaWQgYXR0cmliU3VwZXJUeXBlcyhFbnY8QXR0ckNvbnRleHQ+IGVudiwgRW52PEF0dHJDb250ZXh0PiBiYXNlRW52KSB7CiAgICAgICAgICAgIEpDQ2xhc3NEZWNsIHRyZWUgPSBlbnYuZW5jbENsYXNzOwogICAgICAgICAgICBDbGFzc1N5bWJvbCBzeW0gPSB0cmVlLnN5bTsKICAgICAgICAgICAgQ2xhc3NUeXBlIGN0ID0gKENsYXNzVHlwZSlzeW0udHlwZTsKICAgICAgICAgICAgLy8gRGV0ZXJtaW5lIHN1cGVydHlwZS4KICAgICAgICAgICAgVHlwZSBzdXBlcnR5cGU7CiAgICAgICAgICAgIEpDRXhwcmVzc2lvbiBleHRlbmRpbmc7CgogICAgICAgICAgICBpZiAodHJlZS5leHRlbmRpbmcgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgZXh0ZW5kaW5nID0gY2xlYXJUeXBlUGFyYW1zKHRyZWUuZXh0ZW5kaW5nKTsKICAgICAgICAgICAgICAgIHN1cGVydHlwZSA9IGF0dHIuYXR0cmliQmFzZShleHRlbmRpbmcsIGJhc2VFbnYsIHRydWUsIGZhbHNlLCB0cnVlKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGV4dGVuZGluZyA9IG51bGw7CiAgICAgICAgICAgICAgICBzdXBlcnR5cGUgPSAoKHRyZWUubW9kcy5mbGFncyAmIEZsYWdzLkVOVU0pICE9IDApCiAgICAgICAgICAgICAgICA/IGF0dHIuYXR0cmliQmFzZShlbnVtQmFzZSh0cmVlLnBvcywgc3ltKSwgYmFzZUVudiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRydWUsIGZhbHNlLCBmYWxzZSkKICAgICAgICAgICAgICAgIDogKHN5bS5mdWxsbmFtZSA9PSBuYW1lcy5qYXZhX2xhbmdfT2JqZWN0KQogICAgICAgICAgICAgICAgPyBUeXBlLm5vVHlwZQogICAgICAgICAgICAgICAgOiBzeW1zLm9iamVjdFR5cGU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY3Quc3VwZXJ0eXBlX2ZpZWxkID0gbW9kZWxNaXNzaW5nVHlwZXMoYmFzZUVudiwgc3VwZXJ0eXBlLCBleHRlbmRpbmcsIGZhbHNlKTsKCiAgICAgICAgICAgIC8vIERldGVybWluZSBpbnRlcmZhY2VzLgogICAgICAgICAgICBMaXN0QnVmZmVyPFR5cGU+IGludGVyZmFjZXMgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgIExpc3RCdWZmZXI8VHlwZT4gYWxsX2ludGVyZmFjZXMgPSBudWxsOyAvLyBsYXp5IGluaXQKICAgICAgICAgICAgTGlzdDxKQ0V4cHJlc3Npb24+IGludGVyZmFjZVRyZWVzID0gdHJlZS5pbXBsZW1lbnRpbmc7CiAgICAgICAgICAgIGZvciAoSkNFeHByZXNzaW9uIGlmYWNlIDogaW50ZXJmYWNlVHJlZXMpIHsKICAgICAgICAgICAgICAgIGlmYWNlID0gY2xlYXJUeXBlUGFyYW1zKGlmYWNlKTsKICAgICAgICAgICAgICAgIFR5cGUgaXQgPSBhdHRyLmF0dHJpYkJhc2UoaWZhY2UsIGJhc2VFbnYsIGZhbHNlLCB0cnVlLCB0cnVlKTsKICAgICAgICAgICAgICAgIGlmIChpdC5oYXNUYWcoQ0xBU1MpKSB7CiAgICAgICAgICAgICAgICAgICAgaW50ZXJmYWNlcy5hcHBlbmQoaXQpOwogICAgICAgICAgICAgICAgICAgIGlmIChhbGxfaW50ZXJmYWNlcyAhPSBudWxsKSBhbGxfaW50ZXJmYWNlcy5hcHBlbmQoaXQpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBpZiAoYWxsX2ludGVyZmFjZXMgPT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICAgICAgYWxsX2ludGVyZmFjZXMgPSBuZXcgTGlzdEJ1ZmZlcjxUeXBlPigpLmFwcGVuZExpc3QoaW50ZXJmYWNlcyk7CiAgICAgICAgICAgICAgICAgICAgYWxsX2ludGVyZmFjZXMuYXBwZW5kKG1vZGVsTWlzc2luZ1R5cGVzKGJhc2VFbnYsIGl0LCBpZmFjZSwgdHJ1ZSkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoKHN5bS5mbGFnc19maWVsZCAmIEFOTk9UQVRJT04pICE9IDApIHsKICAgICAgICAgICAgICAgIGN0LmludGVyZmFjZXNfZmllbGQgPSBMaXN0Lm9mKHN5bXMuYW5ub3RhdGlvblR5cGUpOwogICAgICAgICAgICAgICAgY3QuYWxsX2ludGVyZmFjZXNfZmllbGQgPSBjdC5pbnRlcmZhY2VzX2ZpZWxkOwogICAgICAgICAgICB9ICBlbHNlIHsKICAgICAgICAgICAgICAgIGN0LmludGVyZmFjZXNfZmllbGQgPSBpbnRlcmZhY2VzLnRvTGlzdCgpOwogICAgICAgICAgICAgICAgY3QuYWxsX2ludGVyZmFjZXNfZmllbGQgPSAoYWxsX2ludGVyZmFjZXMgPT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICAgICAgPyBjdC5pbnRlcmZhY2VzX2ZpZWxkIDogYWxsX2ludGVyZmFjZXMudG9MaXN0KCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgICAgIC8vd2hlcmU6CiAgICAgICAgICAgIHByb3RlY3RlZCBKQ0V4cHJlc3Npb24gY2xlYXJUeXBlUGFyYW1zKEpDRXhwcmVzc2lvbiBzdXBlclR5cGUpIHsKICAgICAgICAgICAgICAgIHJldHVybiBzdXBlclR5cGU7CiAgICAgICAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIGZpbmFsIGNsYXNzIEhpZXJhcmNoeVBoYXNlIGV4dGVuZHMgQWJzdHJhY3RIZWFkZXJQaGFzZSBpbXBsZW1lbnRzIENvbXBsZXRlciB7CgogICAgICAgIHB1YmxpYyBIaWVyYXJjaHlQaGFzZSgpIHsKICAgICAgICAgICAgc3VwZXIoQ29tcGxldGlvbkNhdXNlLkhJRVJBUkNIWV9QSEFTRSwgbmV3IEhlYWRlclBoYXNlKCkpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHJvdGVjdGVkIHZvaWQgZG9Db21wbGV0ZUVudnMoTGlzdDxFbnY8QXR0ckNvbnRleHQ+PiBlbnZzKSB7CiAgICAgICAgICAgIC8vVGhlIENsYXNzU3ltYm9scyBpbiB0aGUgZW52cyBsaXN0IG1heSBub3QgYmUgaW4gdGhlIGRlcGVuZGVuY3kgb3JkZXIuCiAgICAgICAgICAgIC8vVG8gZ2V0IHByb3BlciByZXN1bHRzLCBmb3IgZXZlcnkgY2xhc3Mgb3IgaW50ZXJmYWNlIEMsIHRoZSBzdXBlcnR5cGVzIG9mCiAgICAgICAgICAgIC8vQyBtdXN0IGJlIHByb2Nlc3NlZCBieSB0aGUgSGllcmFyY2h5UGhhc2UgcGhhc2UgYmVmb3JlIEMuCiAgICAgICAgICAgIC8vVG8gYWNoaWV2ZSB0aGF0LCB0aGUgSGllcmFyY2h5UGhhc2UgaXMgcmVnaXN0ZXJlZCBhcyB0aGUgQ29tcGxldGVyIGZvcgogICAgICAgICAgICAvL2FsbCB0aGUgY2xhc3NlcyBmaXJzdCwgYW5kIHRoZW4gYWxsIHRoZSBjbGFzc2VzIGFyZSBjb21wbGV0ZWQuCiAgICAgICAgICAgIGZvciAoRW52PEF0dHJDb250ZXh0PiBlbnYgOiBlbnZzKSB7CiAgICAgICAgICAgICAgICBlbnYuZW5jbENsYXNzLnN5bS5jb21wbGV0ZXIgPSB0aGlzOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGZvciAoRW52PEF0dHJDb250ZXh0PiBlbnYgOiBlbnZzKSB7CiAgICAgICAgICAgICAgICBlbnYuZW5jbENsYXNzLnN5bS5jb21wbGV0ZSgpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwcm90ZWN0ZWQgdm9pZCBydW5QaGFzZShFbnY8QXR0ckNvbnRleHQ+IGVudikgewogICAgICAgICAgICBKQ0NsYXNzRGVjbCB0cmVlID0gZW52LmVuY2xDbGFzczsKICAgICAgICAgICAgQ2xhc3NTeW1ib2wgc3ltID0gdHJlZS5zeW07CiAgICAgICAgICAgIENsYXNzVHlwZSBjdCA9IChDbGFzc1R5cGUpc3ltLnR5cGU7CgogICAgICAgICAgICBFbnY8QXR0ckNvbnRleHQ+IGJhc2VFbnYgPSBiYXNlRW52KHRyZWUsIGVudik7CgogICAgICAgICAgICBhdHRyaWJTdXBlclR5cGVzKGVudiwgYmFzZUVudik7CgogICAgICAgICAgICBpZiAoc3ltLmZ1bGxuYW1lID09IG5hbWVzLmphdmFfbGFuZ19PYmplY3QpIHsKICAgICAgICAgICAgICAgIGlmICh0cmVlLmV4dGVuZGluZyAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgY2hrLmNoZWNrTm9uQ3ljbGljKHRyZWUuZXh0ZW5kaW5nLnBvcygpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdC5zdXBlcnR5cGVfZmllbGQpOwogICAgICAgICAgICAgICAgICAgIGN0LnN1cGVydHlwZV9maWVsZCA9IFR5cGUubm9UeXBlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSBpZiAodHJlZS5pbXBsZW1lbnRpbmcubm9uRW1wdHkoKSkgewogICAgICAgICAgICAgICAgICAgIGNoay5jaGVja05vbkN5Y2xpYyh0cmVlLmltcGxlbWVudGluZy5oZWFkLnBvcygpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdC5pbnRlcmZhY2VzX2ZpZWxkLmhlYWQpOwogICAgICAgICAgICAgICAgICAgIGN0LmludGVyZmFjZXNfZmllbGQgPSBMaXN0Lm5pbCgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBtYXJrRGVwcmVjYXRlZChzeW0sIHRyZWUubW9kcy5hbm5vdGF0aW9ucywgYmFzZUVudik7CgogICAgICAgICAgICBjaGsuY2hlY2tOb25DeWNsaWNEZWNsKHRyZWUpOwogICAgICAgIH0KICAgICAgICAgICAgLy93aGVyZToKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHByb3RlY3RlZCBKQ0V4cHJlc3Npb24gY2xlYXJUeXBlUGFyYW1zKEpDRXhwcmVzc2lvbiBzdXBlclR5cGUpIHsKICAgICAgICAgICAgICAgIHN3aXRjaCAoc3VwZXJUeXBlLmdldFRhZygpKSB7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBUWVBFQVBQTFk6CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAoKEpDVHlwZUFwcGx5KSBzdXBlclR5cGUpLmNsYXp6OwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHJldHVybiBzdXBlclR5cGU7CiAgICAgICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgY29tcGxldGUoU3ltYm9sIHN5bSkgdGhyb3dzIENvbXBsZXRpb25GYWlsdXJlIHsKICAgICAgICAgICAgQXNzZXJ0LmNoZWNrKCh0b3BMZXZlbFBoYXNlIGluc3RhbmNlb2YgSW1wb3J0c1BoYXNlKSB8fAogICAgICAgICAgICAgICAgICAgICAgICAgKHRvcExldmVsUGhhc2UgPT0gdGhpcykpOwoKICAgICAgICAgICAgaWYgKHRvcExldmVsUGhhc2UgIT0gdGhpcykgewogICAgICAgICAgICAgICAgLy9vbmx5IGRvIHRoZSBwcm9jZXNzaW5nIGJhc2VkIG9uIGRlcGVuZGVuY2llcyBpbiB0aGUgSGllcmFyY2h5UGhhc2U6CiAgICAgICAgICAgICAgICBzeW0uY29tcGxldGVyID0gdGhpczsKICAgICAgICAgICAgICAgIHJldHVybiA7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEVudjxBdHRyQ29udGV4dD4gZW52ID0gdHlwZUVudnMuZ2V0KChDbGFzc1N5bWJvbCkgc3ltKTsKCiAgICAgICAgICAgIHN1cGVyLmRvQ29tcGxldGVFbnZzKExpc3Qub2YoZW52KSk7CiAgICAgICAgfQoKICAgIH0KCiAgICBwcml2YXRlIGZpbmFsIGNsYXNzIEhlYWRlclBoYXNlIGV4dGVuZHMgQWJzdHJhY3RIZWFkZXJQaGFzZSB7CgogICAgICAgIHB1YmxpYyBIZWFkZXJQaGFzZSgpIHsKICAgICAgICAgICAgc3VwZXIoQ29tcGxldGlvbkNhdXNlLkhFQURFUl9QSEFTRSwgbmV3IE1lbWJlcnNQaGFzZSgpKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHByb3RlY3RlZCB2b2lkIHJ1blBoYXNlKEVudjxBdHRyQ29udGV4dD4gZW52KSB7CiAgICAgICAgICAgIEpDQ2xhc3NEZWNsIHRyZWUgPSBlbnYuZW5jbENsYXNzOwogICAgICAgICAgICBDbGFzc1N5bWJvbCBzeW0gPSB0cmVlLnN5bTsKICAgICAgICAgICAgQ2xhc3NUeXBlIGN0ID0gKENsYXNzVHlwZSlzeW0udHlwZTsKCiAgICAgICAgICAgIC8vIGNyZWF0ZSBhbiBlbnZpcm9ubWVudCBmb3IgZXZhbHVhdGluZyB0aGUgYmFzZSBjbGF1c2VzCiAgICAgICAgICAgIEVudjxBdHRyQ29udGV4dD4gYmFzZUVudiA9IGJhc2VFbnYodHJlZSwgZW52KTsKCiAgICAgICAgICAgIGlmICh0cmVlLmV4dGVuZGluZyAhPSBudWxsKQogICAgICAgICAgICAgICAgYW5ub3RhdGUucXVldWVTY2FuVHJlZUFuZFR5cGVBbm5vdGF0ZSh0cmVlLmV4dGVuZGluZywgYmFzZUVudiwgc3ltLCB0cmVlLnBvcygpKTsKICAgICAgICAgICAgZm9yIChKQ0V4cHJlc3Npb24gaW1wbCA6IHRyZWUuaW1wbGVtZW50aW5nKQogICAgICAgICAgICAgICAgYW5ub3RhdGUucXVldWVTY2FuVHJlZUFuZFR5cGVBbm5vdGF0ZShpbXBsLCBiYXNlRW52LCBzeW0sIHRyZWUucG9zKCkpOwogICAgICAgICAgICBhbm5vdGF0ZS5mbHVzaCgpOwoKICAgICAgICAgICAgYXR0cmliU3VwZXJUeXBlcyhlbnYsIGJhc2VFbnYpOwoKICAgICAgICAgICAgU2V0PFR5cGU+IGludGVyZmFjZVNldCA9IG5ldyBIYXNoU2V0PD4oKTsKCiAgICAgICAgICAgIGZvciAoSkNFeHByZXNzaW9uIGlmYWNlIDogdHJlZS5pbXBsZW1lbnRpbmcpIHsKICAgICAgICAgICAgICAgIFR5cGUgaXQgPSBpZmFjZS50eXBlOwogICAgICAgICAgICAgICAgaWYgKGl0Lmhhc1RhZyhDTEFTUykpCiAgICAgICAgICAgICAgICAgICAgY2hrLmNoZWNrTm90UmVwZWF0ZWQoaWZhY2UucG9zKCksIHR5cGVzLmVyYXN1cmUoaXQpLCBpbnRlcmZhY2VTZXQpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBhbm5vdGF0ZS5hbm5vdGF0ZUxhdGVyKHRyZWUubW9kcy5hbm5vdGF0aW9ucywgYmFzZUVudiwKICAgICAgICAgICAgICAgICAgICAgICAgc3ltLCB0cmVlLnBvcygpKTsKCiAgICAgICAgICAgIGF0dHIuYXR0cmliVHlwZVZhcmlhYmxlcyh0cmVlLnR5cGFyYW1zLCBiYXNlRW52KTsKICAgICAgICAgICAgZm9yIChKQ1R5cGVQYXJhbWV0ZXIgdHAgOiB0cmVlLnR5cGFyYW1zKQogICAgICAgICAgICAgICAgYW5ub3RhdGUucXVldWVTY2FuVHJlZUFuZFR5cGVBbm5vdGF0ZSh0cCwgYmFzZUVudiwgc3ltLCB0cmVlLnBvcygpKTsKCiAgICAgICAgICAgIC8vIGNoZWNrIHRoYXQgbm8gcGFja2FnZSBleGlzdHMgd2l0aCBzYW1lIGZ1bGx5IHF1YWxpZmllZCBuYW1lLAogICAgICAgICAgICAvLyBidXQgYWRtaXQgY2xhc3NlcyBpbiB0aGUgdW5uYW1lZCBwYWNrYWdlIHdoaWNoIGhhdmUgdGhlIHNhbWUKICAgICAgICAgICAgLy8gbmFtZSBhcyBhIHRvcC1sZXZlbCBwYWNrYWdlLgogICAgICAgICAgICBpZiAoY2hlY2tDbGFzaCAmJgogICAgICAgICAgICAgICAgc3ltLm93bmVyLmtpbmQgPT0gUENLICYmIHN5bS5vd25lciAhPSBlbnYudG9wbGV2ZWwubW9kbGUudW5uYW1lZFBhY2thZ2UgJiYKICAgICAgICAgICAgICAgIHN5bXMucGFja2FnZUV4aXN0cyhlbnYudG9wbGV2ZWwubW9kbGUsIHN5bS5mdWxsbmFtZSkpIHsKICAgICAgICAgICAgICAgIGxvZy5lcnJvcih0cmVlLnBvcywgImNsYXNoLndpdGgucGtnLm9mLnNhbWUubmFtZSIsIEtpbmRzLmtpbmROYW1lKHN5bSksIHN5bSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHN5bS5vd25lci5raW5kID09IFBDSyAmJiAoc3ltLmZsYWdzX2ZpZWxkICYgUFVCTElDKSA9PSAwICYmCiAgICAgICAgICAgICAgICAhZW52LnRvcGxldmVsLnNvdXJjZWZpbGUuaXNOYW1lQ29tcGF0aWJsZShzeW0ubmFtZS50b1N0cmluZygpLEphdmFGaWxlT2JqZWN0LktpbmQuU09VUkNFKSkgewogICAgICAgICAgICAgICAgc3ltLmZsYWdzX2ZpZWxkIHw9IEFVWElMSUFSWTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKiogRW50ZXIgbWVtYmVyIGZpZWxkcyBhbmQgbWV0aG9kcyBvZiBhIGNsYXNzCiAgICAgKi8KICAgIHByaXZhdGUgZmluYWwgY2xhc3MgTWVtYmVyc1BoYXNlIGV4dGVuZHMgUGhhc2UgewoKICAgICAgICBwdWJsaWMgTWVtYmVyc1BoYXNlKCkgewogICAgICAgICAgICBzdXBlcihDb21wbGV0aW9uQ2F1c2UuTUVNQkVSU19QSEFTRSwgbnVsbCk7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIGJvb2xlYW4gY29tcGxldGluZzsKICAgICAgICBwcml2YXRlIExpc3Q8RW52PEF0dHJDb250ZXh0Pj4gdG9kbyA9IExpc3QubmlsKCk7CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHByb3RlY3RlZCB2b2lkIGRvQ29tcGxldGVFbnZzKExpc3Q8RW52PEF0dHJDb250ZXh0Pj4gZW52cykgewogICAgICAgICAgICB0b2RvID0gdG9kby5wcmVwZW5kTGlzdChlbnZzKTsKICAgICAgICAgICAgaWYgKGNvbXBsZXRpbmcpIHsKICAgICAgICAgICAgICAgIHJldHVybiA7IC8vdGhlIHRvcC1sZXZlbCBpbnZvY2F0aW9uIHdpbGwgaGFuZGxlIGFsbCBlbnZzCiAgICAgICAgICAgIH0KICAgICAgICAgICAgYm9vbGVhbiBwcmV2Q29tcGxldGluZyA9IGNvbXBsZXRpbmc7CiAgICAgICAgICAgIGNvbXBsZXRpbmcgPSB0cnVlOwogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgd2hpbGUgKHRvZG8ubm9uRW1wdHkoKSkgewogICAgICAgICAgICAgICAgICAgIEVudjxBdHRyQ29udGV4dD4gaGVhZCA9IHRvZG8uaGVhZDsKICAgICAgICAgICAgICAgICAgICB0b2RvID0gdG9kby50YWlsOwogICAgICAgICAgICAgICAgICAgIHN1cGVyLmRvQ29tcGxldGVFbnZzKExpc3Qub2YoaGVhZCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAgICAgY29tcGxldGluZyA9IHByZXZDb21wbGV0aW5nOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwcm90ZWN0ZWQgdm9pZCBydW5QaGFzZShFbnY8QXR0ckNvbnRleHQ+IGVudikgewogICAgICAgICAgICBKQ0NsYXNzRGVjbCB0cmVlID0gZW52LmVuY2xDbGFzczsKICAgICAgICAgICAgQ2xhc3NTeW1ib2wgc3ltID0gdHJlZS5zeW07CiAgICAgICAgICAgIENsYXNzVHlwZSBjdCA9IChDbGFzc1R5cGUpc3ltLnR5cGU7CgogICAgICAgICAgICAvLyBBZGQgZGVmYXVsdCBjb25zdHJ1Y3RvciBpZiBuZWVkZWQuCiAgICAgICAgICAgIGlmICgoc3ltLmZsYWdzKCkgJiBJTlRFUkZBQ0UpID09IDAgJiYKICAgICAgICAgICAgICAgICFUcmVlSW5mby5oYXNDb25zdHJ1Y3RvcnModHJlZS5kZWZzKSkgewogICAgICAgICAgICAgICAgTGlzdDxUeXBlPiBhcmd0eXBlcyA9IExpc3QubmlsKCk7CiAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IHR5cGFyYW1zID0gTGlzdC5uaWwoKTsKICAgICAgICAgICAgICAgIExpc3Q8VHlwZT4gdGhyb3duID0gTGlzdC5uaWwoKTsKICAgICAgICAgICAgICAgIGxvbmcgY3RvckZsYWdzID0gMDsKICAgICAgICAgICAgICAgIGJvb2xlYW4gYmFzZWQgPSBmYWxzZTsKICAgICAgICAgICAgICAgIGJvb2xlYW4gYWRkQ29uc3RydWN0b3IgPSB0cnVlOwogICAgICAgICAgICAgICAgSkNOZXdDbGFzcyBuYyA9IG51bGw7CiAgICAgICAgICAgICAgICBpZiAoc3ltLm5hbWUuaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgICAgICAgbmMgPSAoSkNOZXdDbGFzcyllbnYubmV4dC50cmVlOwogICAgICAgICAgICAgICAgICAgIGlmIChuYy5jb25zdHJ1Y3RvciAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGFkZENvbnN0cnVjdG9yID0gbmMuY29uc3RydWN0b3Iua2luZCAhPSBFUlI7CiAgICAgICAgICAgICAgICAgICAgICAgIFR5cGUgc3VwZXJDb25zdHJUeXBlID0gdHlwZXMubWVtYmVyVHlwZShzeW0udHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5jLmNvbnN0cnVjdG9yKTsKICAgICAgICAgICAgICAgICAgICAgICAgYXJndHlwZXMgPSBzdXBlckNvbnN0clR5cGUuZ2V0UGFyYW1ldGVyVHlwZXMoKTsKICAgICAgICAgICAgICAgICAgICAgICAgdHlwYXJhbXMgPSBzdXBlckNvbnN0clR5cGUuZ2V0VHlwZUFyZ3VtZW50cygpOwogICAgICAgICAgICAgICAgICAgICAgICBjdG9yRmxhZ3MgPSBuYy5jb25zdHJ1Y3Rvci5mbGFncygpICYgVkFSQVJHUzsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5jLmVuY2wgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJndHlwZXMgPSBhcmd0eXBlcy5wcmVwZW5kKG5jLmVuY2wudHlwZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYXNlZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3duID0gc3VwZXJDb25zdHJUeXBlLmdldFRocm93blR5cGVzKCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKGFkZENvbnN0cnVjdG9yKSB7CiAgICAgICAgICAgICAgICAgICAgTWV0aG9kU3ltYm9sIGJhc2VkQ29uc3RydWN0b3IgPSBuYyAhPSBudWxsID8KICAgICAgICAgICAgICAgICAgICAgICAgICAgIChNZXRob2RTeW1ib2wpbmMuY29uc3RydWN0b3IgOiBudWxsOwogICAgICAgICAgICAgICAgICAgIEpDVHJlZSBjb25zdHJEZWYgPSBEZWZhdWx0Q29uc3RydWN0b3IobWFrZS5hdCh0cmVlLnBvcyksIHN5bSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYXNlZENvbnN0cnVjdG9yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGFyYW1zLCBhcmd0eXBlcywgdGhyb3duLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0b3JGbGFncywgYmFzZWQpOwogICAgICAgICAgICAgICAgICAgIHRyZWUuZGVmcyA9IHRyZWUuZGVmcy5wcmVwZW5kKGNvbnN0ckRlZik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIGVudGVyIHN5bWJvbHMgZm9yICd0aGlzJyBpbnRvIGN1cnJlbnQgc2NvcGUuCiAgICAgICAgICAgIFZhclN5bWJvbCB0aGlzU3ltID0KICAgICAgICAgICAgICAgIG5ldyBWYXJTeW1ib2woRklOQUwgfCBIQVNJTklULCBuYW1lcy5fdGhpcywgc3ltLnR5cGUsIHN5bSk7CiAgICAgICAgICAgIHRoaXNTeW0ucG9zID0gUG9zaXRpb24uRklSU1RQT1M7CiAgICAgICAgICAgIGVudi5pbmZvLnNjb3BlLmVudGVyKHRoaXNTeW0pOwogICAgICAgICAgICAvLyBpZiB0aGlzIGlzIGEgY2xhc3MsIGVudGVyIHN5bWJvbCBmb3IgJ3N1cGVyJyBpbnRvIGN1cnJlbnQgc2NvcGUuCiAgICAgICAgICAgIGlmICgoc3ltLmZsYWdzX2ZpZWxkICYgSU5URVJGQUNFKSA9PSAwICYmCiAgICAgICAgICAgICAgICAgICAgY3Quc3VwZXJ0eXBlX2ZpZWxkLmhhc1RhZyhDTEFTUykpIHsKICAgICAgICAgICAgICAgIFZhclN5bWJvbCBzdXBlclN5bSA9CiAgICAgICAgICAgICAgICAgICAgbmV3IFZhclN5bWJvbChGSU5BTCB8IEhBU0lOSVQsIG5hbWVzLl9zdXBlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0LnN1cGVydHlwZV9maWVsZCwgc3ltKTsKICAgICAgICAgICAgICAgIHN1cGVyU3ltLnBvcyA9IFBvc2l0aW9uLkZJUlNUUE9TOwogICAgICAgICAgICAgICAgZW52LmluZm8uc2NvcGUuZW50ZXIoc3VwZXJTeW0pOwogICAgICAgICAgICB9CgogICAgICAgICAgICBmaW5pc2hDbGFzcyh0cmVlLCBlbnYpOwoKICAgICAgICAgICAgaWYgKGFsbG93VHlwZUFubm9zKSB7CiAgICAgICAgICAgICAgICB0eXBlQW5ub3RhdGlvbnMub3JnYW5pemVUeXBlQW5ub3RhdGlvbnNTaWduYXR1cmVzKGVudiwgKEpDQ2xhc3NEZWNsKWVudi50cmVlKTsKICAgICAgICAgICAgICAgIHR5cGVBbm5vdGF0aW9ucy52YWxpZGF0ZVR5cGVBbm5vdGF0aW9uc1NpZ25hdHVyZXMoZW52LCAoSkNDbGFzc0RlY2wpZW52LnRyZWUpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvKiogRW50ZXIgbWVtYmVycyBmb3IgYSBjbGFzcy4KICAgICAgICAgKi8KICAgICAgICB2b2lkIGZpbmlzaENsYXNzKEpDQ2xhc3NEZWNsIHRyZWUsIEVudjxBdHRyQ29udGV4dD4gZW52KSB7CiAgICAgICAgICAgIGlmICgodHJlZS5tb2RzLmZsYWdzICYgRmxhZ3MuRU5VTSkgIT0gMCAmJgogICAgICAgICAgICAgICAgIXRyZWUuc3ltLnR5cGUuaGFzVGFnKEVSUk9SKSAmJgogICAgICAgICAgICAgICAgKHR5cGVzLnN1cGVydHlwZSh0cmVlLnN5bS50eXBlKS50c3ltLmZsYWdzKCkgJiBGbGFncy5FTlVNKSA9PSAwKSB7CiAgICAgICAgICAgICAgICBhZGRFbnVtTWVtYmVycyh0cmVlLCBlbnYpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIG1lbWJlckVudGVyLm1lbWJlckVudGVyKHRyZWUuZGVmcywgZW52KTsKCiAgICAgICAgICAgIGlmICh0cmVlLnN5bS5pc0Fubm90YXRpb25UeXBlKCkpIHsKICAgICAgICAgICAgICAgIEFzc2VydC5jaGVjayh0cmVlLnN5bS5pc0NvbXBsZXRlZCgpKTsKICAgICAgICAgICAgICAgIHRyZWUuc3ltLnNldEFubm90YXRpb25UeXBlTWV0YWRhdGEobmV3IEFubm90YXRpb25UeXBlTWV0YWRhdGEodHJlZS5zeW0sIGFubm90YXRlLmFubm90YXRpb25UeXBlU291cmNlQ29tcGxldGVyKCkpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLyoqIEFkZCB0aGUgaW1wbGljaXQgbWVtYmVycyBmb3IgYW4gZW51bSB0eXBlCiAgICAgICAgICogIHRvIHRoZSBzeW1ib2wgdGFibGUuCiAgICAgICAgICovCiAgICAgICAgcHJpdmF0ZSB2b2lkIGFkZEVudW1NZW1iZXJzKEpDQ2xhc3NEZWNsIHRyZWUsIEVudjxBdHRyQ29udGV4dD4gZW52KSB7CiAgICAgICAgICAgIEpDRXhwcmVzc2lvbiB2YWx1ZXNUeXBlID0gbWFrZS5UeXBlKG5ldyBBcnJheVR5cGUodHJlZS5zeW0udHlwZSwgc3ltcy5hcnJheUNsYXNzKSk7CgogICAgICAgICAgICAvLyBwdWJsaWMgc3RhdGljIFRbXSB2YWx1ZXMoKSB7IHJldHVybiA/Pz87IH0KICAgICAgICAgICAgSkNNZXRob2REZWNsIHZhbHVlcyA9IG1ha2UuCiAgICAgICAgICAgICAgICBNZXRob2REZWYobWFrZS5Nb2RpZmllcnMoRmxhZ3MuUFVCTElDfEZsYWdzLlNUQVRJQyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZXMudmFsdWVzLAogICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlc1R5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgTGlzdC5uaWwoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0Lm5pbCgpLAogICAgICAgICAgICAgICAgICAgICAgICAgIExpc3QubmlsKCksIC8vIHRocm93bgogICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwsIC8vbWFrZS5CbG9jaygwLCBUcmVlLmVtcHR5TGlzdC5wcmVwZW5kKG1ha2UuUmV0dXJuKG1ha2UuSWRlbnQobmFtZXMuX251bGwpKSkpLAogICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwpOwogICAgICAgICAgICBtZW1iZXJFbnRlci5tZW1iZXJFbnRlcih2YWx1ZXMsIGVudik7CgogICAgICAgICAgICAvLyBwdWJsaWMgc3RhdGljIFQgdmFsdWVPZihTdHJpbmcgbmFtZSkgeyByZXR1cm4gPz8/OyB9CiAgICAgICAgICAgIEpDTWV0aG9kRGVjbCB2YWx1ZU9mID0gbWFrZS4KICAgICAgICAgICAgICAgIE1ldGhvZERlZihtYWtlLk1vZGlmaWVycyhGbGFncy5QVUJMSUN8RmxhZ3MuU1RBVElDKSwKICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lcy52YWx1ZU9mLAogICAgICAgICAgICAgICAgICAgICAgICAgIG1ha2UuVHlwZSh0cmVlLnN5bS50eXBlKSwKICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0Lm5pbCgpLAogICAgICAgICAgICAgICAgICAgICAgICAgIExpc3Qub2YobWFrZS5WYXJEZWYobWFrZS5Nb2RpZmllcnMoRmxhZ3MuUEFSQU1FVEVSIHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZsYWdzLk1BTkRBVEVEKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZXMuZnJvbVN0cmluZygibmFtZSIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYWtlLlR5cGUoc3ltcy5zdHJpbmdUeXBlKSwgbnVsbCkpLAogICAgICAgICAgICAgICAgICAgICAgICAgIExpc3QubmlsKCksIC8vIHRocm93bgogICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwsIC8vbWFrZS5CbG9jaygwLCBUcmVlLmVtcHR5TGlzdC5wcmVwZW5kKG1ha2UuUmV0dXJuKG1ha2UuSWRlbnQobmFtZXMuX251bGwpKSkpLAogICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwpOwogICAgICAgICAgICBtZW1iZXJFbnRlci5tZW1iZXJFbnRlcih2YWx1ZU9mLCBlbnYpOwogICAgICAgIH0KCiAgICB9CgovKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogdHJlZSBidWlsZGluZwogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiAgICAvKiogR2VuZXJhdGUgZGVmYXVsdCBjb25zdHJ1Y3RvciBmb3IgZ2l2ZW4gY2xhc3MuIEZvciBjbGFzc2VzIGRpZmZlcmVudAogICAgICogIGZyb20gamF2YS5sYW5nLk9iamVjdCwgdGhpcyBpczoKICAgICAqCiAgICAgKiAgICBjKGFyZ3R5cGVfMCB4XzAsIC4uLiwgYXJndHlwZV9uIHhfbikgdGhyb3dzIHRocm93biB7CiAgICAgKiAgICAgIHN1cGVyKHhfMCwgLi4uLCB4X24pCiAgICAgKiAgICB9CiAgICAgKgogICAgICogIG9yLCBpZiBiYXNlZCA9PSB0cnVlOgogICAgICoKICAgICAqICAgIGMoYXJndHlwZV8wIHhfMCwgLi4uLCBhcmd0eXBlX24geF9uKSB0aHJvd3MgdGhyb3duIHsKICAgICAqICAgICAgeF8wLnN1cGVyKHhfMSwgLi4uLCB4X24pCiAgICAgKiAgICB9CiAgICAgKgogICAgICogIEBwYXJhbSBtYWtlICAgICBUaGUgdHJlZSBmYWN0b3J5LgogICAgICogIEBwYXJhbSBjICAgICAgICBUaGUgY2xhc3Mgb3duaW5nIHRoZSBkZWZhdWx0IGNvbnN0cnVjdG9yLgogICAgICogIEBwYXJhbSBhcmd0eXBlcyBUaGUgcGFyYW1ldGVyIHR5cGVzIG9mIHRoZSBjb25zdHJ1Y3Rvci4KICAgICAqICBAcGFyYW0gdGhyb3duICAgVGhlIHRocm93biBleGNlcHRpb25zIG9mIHRoZSBjb25zdHJ1Y3Rvci4KICAgICAqICBAcGFyYW0gYmFzZWQgICAgSXMgZmlyc3QgcGFyYW1ldGVyIGEgdGhpcyRuPwogICAgICovCiAgICBKQ1RyZWUgRGVmYXVsdENvbnN0cnVjdG9yKFRyZWVNYWtlciBtYWtlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2xhc3NTeW1ib2wgYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1ldGhvZFN5bWJvbCBiYXNlSW5pdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIExpc3Q8VHlwZT4gdHlwYXJhbXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IGFyZ3R5cGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgTGlzdDxUeXBlPiB0aHJvd24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb25nIGZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBiYXNlZCkgewogICAgICAgIEpDVHJlZSByZXN1bHQ7CiAgICAgICAgaWYgKChjLmZsYWdzKCkgJiBFTlVNKSAhPSAwICYmCiAgICAgICAgICAgICh0eXBlcy5zdXBlcnR5cGUoYy50eXBlKS50c3ltID09IHN5bXMuZW51bVN5bSkpIHsKICAgICAgICAgICAgLy8gY29uc3RydWN0b3JzIG9mIHRydWUgZW51bXMgYXJlIHByaXZhdGUKICAgICAgICAgICAgZmxhZ3MgPSAoZmxhZ3MgJiB+QWNjZXNzRmxhZ3MpIHwgUFJJVkFURSB8IEdFTkVSQVRFRENPTlNUUjsKICAgICAgICB9IGVsc2UKICAgICAgICAgICAgZmxhZ3MgfD0gKGMuZmxhZ3MoKSAmIEFjY2Vzc0ZsYWdzKSB8IEdFTkVSQVRFRENPTlNUUjsKICAgICAgICBpZiAoYy5uYW1lLmlzRW1wdHkoKSkgewogICAgICAgICAgICBmbGFncyB8PSBBTk9OQ09OU1RSOwogICAgICAgIH0KICAgICAgICBUeXBlIG1UeXBlID0gbmV3IE1ldGhvZFR5cGUoYXJndHlwZXMsIG51bGwsIHRocm93biwgYyk7CiAgICAgICAgVHlwZSBpbml0VHlwZSA9IHR5cGFyYW1zLm5vbkVtcHR5KCkgPwogICAgICAgICAgICBuZXcgRm9yQWxsKHR5cGFyYW1zLCBtVHlwZSkgOgogICAgICAgICAgICBtVHlwZTsKICAgICAgICBNZXRob2RTeW1ib2wgaW5pdCA9IG5ldyBNZXRob2RTeW1ib2woZmxhZ3MsIG5hbWVzLmluaXQsCiAgICAgICAgICAgICAgICBpbml0VHlwZSwgYyk7CiAgICAgICAgaW5pdC5wYXJhbXMgPSBjcmVhdGVEZWZhdWx0Q29uc3RydWN0b3JQYXJhbXMobWFrZSwgYmFzZUluaXQsIGluaXQsCiAgICAgICAgICAgICAgICBhcmd0eXBlcywgYmFzZWQpOwogICAgICAgIExpc3Q8SkNWYXJpYWJsZURlY2w+IHBhcmFtcyA9IG1ha2UuUGFyYW1zKGFyZ3R5cGVzLCBpbml0KTsKICAgICAgICBMaXN0PEpDU3RhdGVtZW50PiBzdGF0cyA9IExpc3QubmlsKCk7CiAgICAgICAgaWYgKGMudHlwZSAhPSBzeW1zLm9iamVjdFR5cGUpIHsKICAgICAgICAgICAgc3RhdHMgPSBzdGF0cy5wcmVwZW5kKFN1cGVyQ2FsbChtYWtlLCB0eXBhcmFtcywgcGFyYW1zLCBiYXNlZCkpOwogICAgICAgIH0KICAgICAgICByZXN1bHQgPSBtYWtlLk1ldGhvZERlZihpbml0LCBtYWtlLkJsb2NrKDAsIHN0YXRzKSk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KCiAgICBwcml2YXRlIExpc3Q8VmFyU3ltYm9sPiBjcmVhdGVEZWZhdWx0Q29uc3RydWN0b3JQYXJhbXMoCiAgICAgICAgICAgIFRyZWVNYWtlciBtYWtlLAogICAgICAgICAgICBNZXRob2RTeW1ib2wgYmFzZUluaXQsCiAgICAgICAgICAgIE1ldGhvZFN5bWJvbCBpbml0LAogICAgICAgICAgICBMaXN0PFR5cGU+IGFyZ3R5cGVzLAogICAgICAgICAgICBib29sZWFuIGJhc2VkKSB7CiAgICAgICAgTGlzdDxWYXJTeW1ib2w+IGluaXRQYXJhbXMgPSBudWxsOwogICAgICAgIExpc3Q8VHlwZT4gYXJnVHlwZXNMaXN0ID0gYXJndHlwZXM7CiAgICAgICAgaWYgKGJhc2VkKSB7CiAgICAgICAgICAgIC8qICBJbiB0aGlzIGNhc2UgYXJndHlwZXMgd2lsbCBoYXZlIGFuIGV4dHJhIHR5cGUsIGNvbXBhcmVkIHRvIGJhc2VJbml0LAogICAgICAgICAgICAgKiAgY29ycmVzcG9uZGluZyB0byB0aGUgdHlwZSBvZiB0aGUgZW5jbG9zaW5nIGluc3RhbmNlIGkuZS46CiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqICBJbm5lciBpID0gb3V0ZXIubmV3IElubmVyKDEpe30KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogIGluIHRoZSBhYm92ZSBleGFtcGxlIGFyZ3R5cGVzIHdpbGwgYmUgKE91dGVyLCBpbnQpIGFuZCBiYXNlSW5pdAogICAgICAgICAgICAgKiAgd2lsbCBoYXZlIHBhcmFtZXRlcidzIHR5cGVzIChpbnQpLiBTbyBpbiB0aGlzIGNhc2Ugd2UgaGF2ZSB0byBhZGQKICAgICAgICAgICAgICogIGZpcnN0IHRoZSBleHRyYSB0eXBlIGluIGFyZ3R5cGVzIGFuZCB0aGVuIGdldCB0aGUgbmFtZXMgb2YgdGhlCiAgICAgICAgICAgICAqICBwYXJhbWV0ZXJzIGZyb20gYmFzZUluaXQuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpbml0UGFyYW1zID0gTGlzdC5uaWwoKTsKICAgICAgICAgICAgVmFyU3ltYm9sIHBhcmFtID0gbmV3IFZhclN5bWJvbChQQVJBTUVURVIsIG1ha2UucGFyYW1OYW1lKDApLCBhcmd0eXBlcy5oZWFkLCBpbml0KTsKICAgICAgICAgICAgaW5pdFBhcmFtcyA9IGluaXRQYXJhbXMuYXBwZW5kKHBhcmFtKTsKICAgICAgICAgICAgYXJnVHlwZXNMaXN0ID0gYXJnVHlwZXNMaXN0LnRhaWw7CiAgICAgICAgfQogICAgICAgIGlmIChiYXNlSW5pdCAhPSBudWxsICYmIGJhc2VJbml0LnBhcmFtcyAhPSBudWxsICYmCiAgICAgICAgICAgIGJhc2VJbml0LnBhcmFtcy5ub25FbXB0eSgpICYmIGFyZ1R5cGVzTGlzdC5ub25FbXB0eSgpKSB7CiAgICAgICAgICAgIGluaXRQYXJhbXMgPSAoaW5pdFBhcmFtcyA9PSBudWxsKSA/IExpc3QubmlsKCkgOiBpbml0UGFyYW1zOwogICAgICAgICAgICBMaXN0PFZhclN5bWJvbD4gYmFzZUluaXRQYXJhbXMgPSBiYXNlSW5pdC5wYXJhbXM7CiAgICAgICAgICAgIHdoaWxlIChiYXNlSW5pdFBhcmFtcy5ub25FbXB0eSgpICYmIGFyZ1R5cGVzTGlzdC5ub25FbXB0eSgpKSB7CiAgICAgICAgICAgICAgICBWYXJTeW1ib2wgcGFyYW0gPSBuZXcgVmFyU3ltYm9sKGJhc2VJbml0UGFyYW1zLmhlYWQuZmxhZ3MoKSB8IFBBUkFNRVRFUiwKICAgICAgICAgICAgICAgICAgICAgICAgYmFzZUluaXRQYXJhbXMuaGVhZC5uYW1lLCBhcmdUeXBlc0xpc3QuaGVhZCwgaW5pdCk7CiAgICAgICAgICAgICAgICBpbml0UGFyYW1zID0gaW5pdFBhcmFtcy5hcHBlbmQocGFyYW0pOwogICAgICAgICAgICAgICAgYmFzZUluaXRQYXJhbXMgPSBiYXNlSW5pdFBhcmFtcy50YWlsOwogICAgICAgICAgICAgICAgYXJnVHlwZXNMaXN0ID0gYXJnVHlwZXNMaXN0LnRhaWw7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIGluaXRQYXJhbXM7CiAgICB9CgogICAgLyoqIEdlbmVyYXRlIGNhbGwgdG8gc3VwZXJjbGFzcyBjb25zdHJ1Y3Rvci4gVGhpcyBpczoKICAgICAqCiAgICAgKiAgICBzdXBlcihpZF8wLCAuLi4sIGlkX24pCiAgICAgKgogICAgICogb3IsIGlmIGJhc2VkID09IHRydWUKICAgICAqCiAgICAgKiAgICBpZF8wLnN1cGVyKGlkXzEsLi4uLGlkX24pCiAgICAgKgogICAgICogIHdoZXJlIGlkXzAsIC4uLiwgaWRfbiBhcmUgdGhlIG5hbWVzIG9mIHRoZSBnaXZlbiBwYXJhbWV0ZXJzLgogICAgICoKICAgICAqICBAcGFyYW0gbWFrZSAgICBUaGUgdHJlZSBmYWN0b3J5CiAgICAgKiAgQHBhcmFtIHBhcmFtcyAgVGhlIHBhcmFtZXRlcnMgdGhhdCBuZWVkIHRvIGJlIHBhc3NlZCB0byBzdXBlcgogICAgICogIEBwYXJhbSB0eXBhcmFtcyAgVGhlIHR5cGUgcGFyYW1ldGVycyB0aGF0IG5lZWQgdG8gYmUgcGFzc2VkIHRvIHN1cGVyCiAgICAgKiAgQHBhcmFtIGJhc2VkICAgSXMgZmlyc3QgcGFyYW1ldGVyIGEgdGhpcyRuPwogICAgICovCiAgICBKQ0V4cHJlc3Npb25TdGF0ZW1lbnQgU3VwZXJDYWxsKFRyZWVNYWtlciBtYWtlLAogICAgICAgICAgICAgICAgICAgTGlzdDxUeXBlPiB0eXBhcmFtcywKICAgICAgICAgICAgICAgICAgIExpc3Q8SkNWYXJpYWJsZURlY2w+IHBhcmFtcywKICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gYmFzZWQpIHsKICAgICAgICBKQ0V4cHJlc3Npb24gbWV0aDsKICAgICAgICBpZiAoYmFzZWQpIHsKICAgICAgICAgICAgbWV0aCA9IG1ha2UuU2VsZWN0KG1ha2UuSWRlbnQocGFyYW1zLmhlYWQpLCBuYW1lcy5fc3VwZXIpOwogICAgICAgICAgICBwYXJhbXMgPSBwYXJhbXMudGFpbDsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBtZXRoID0gbWFrZS5JZGVudChuYW1lcy5fc3VwZXIpOwogICAgICAgIH0KICAgICAgICBMaXN0PEpDRXhwcmVzc2lvbj4gdHlwZWFyZ3MgPSB0eXBhcmFtcy5ub25FbXB0eSgpID8gbWFrZS5UeXBlcyh0eXBhcmFtcykgOiBudWxsOwogICAgICAgIHJldHVybiBtYWtlLkV4ZWMobWFrZS5BcHBseSh0eXBlYXJncywgbWV0aCwgbWFrZS5JZGVudHMocGFyYW1zKSkpOwogICAgfQoKICAgIC8qKgogICAgICogTWFyayBzeW0gZGVwcmVjYXRlZCBpZiBhbm5vdGF0aW9ucyBjb250YWluIEBEZXByZWNhdGVkIGFubm90YXRpb24uCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIG1hcmtEZXByZWNhdGVkKFN5bWJvbCBzeW0sIExpc3Q8SkNBbm5vdGF0aW9uPiBhbm5vdGF0aW9ucywgRW52PEF0dHJDb250ZXh0PiBlbnYpIHsKICAgICAgICAvLyBJbiBnZW5lcmFsLCB3ZSBjYW5ub3QgZnVsbHkgcHJvY2VzcyBhbm5vdGF0aW9ucyB5ZXQsICBidXQgd2UKICAgICAgICAvLyBjYW4gYXR0cmlidXRlIHRoZSBhbm5vdGF0aW9uIHR5cGVzIGFuZCB0aGVuIGNoZWNrIHRvIHNlZSBpZiB0aGUKICAgICAgICAvLyBARGVwcmVjYXRlZCBhbm5vdGF0aW9uIGlzIHByZXNlbnQuCiAgICAgICAgYXR0ci5hdHRyaWJBbm5vdGF0aW9uVHlwZXMoYW5ub3RhdGlvbnMsIGVudik7CiAgICAgICAgaGFuZGxlRGVwcmVjYXRlZEFubm90YXRpb25zKGFubm90YXRpb25zLCBzeW0pOwogICAgfQoKICAgIC8qKgogICAgICogSWYgYSBsaXN0IG9mIGFubm90YXRpb25zIGNvbnRhaW5zIGEgcmVmZXJlbmNlIHRvIGphdmEubGFuZy5EZXByZWNhdGVkLAogICAgICogc2V0IHRoZSBERVBSRUNBVEVEIGZsYWcuCiAgICAgKiBJZiB0aGUgYW5ub3RhdGlvbiBpcyBtYXJrZWQgZm9yUmVtb3ZhbD10cnVlLCBhbHNvIHNldCBERVBSRUNBVEVEX1JFTU9WQUwuCiAgICAgKiovCiAgICBwcml2YXRlIHZvaWQgaGFuZGxlRGVwcmVjYXRlZEFubm90YXRpb25zKExpc3Q8SkNBbm5vdGF0aW9uPiBhbm5vdGF0aW9ucywgU3ltYm9sIHN5bSkgewogICAgICAgIGZvciAoTGlzdDxKQ0Fubm90YXRpb24+IGFsID0gYW5ub3RhdGlvbnM7ICFhbC5pc0VtcHR5KCk7IGFsID0gYWwudGFpbCkgewogICAgICAgICAgICBKQ0Fubm90YXRpb24gYSA9IGFsLmhlYWQ7CiAgICAgICAgICAgIGlmIChhLmFubm90YXRpb25UeXBlLnR5cGUgPT0gc3ltcy5kZXByZWNhdGVkVHlwZSkgewogICAgICAgICAgICAgICAgc3ltLmZsYWdzX2ZpZWxkIHw9IChGbGFncy5ERVBSRUNBVEVEIHwgRmxhZ3MuREVQUkVDQVRFRF9BTk5PVEFUSU9OKTsKICAgICAgICAgICAgICAgIGEuYXJncy5zdHJlYW0oKQogICAgICAgICAgICAgICAgICAgICAgICAuZmlsdGVyKGUgLT4gZS5oYXNUYWcoQVNTSUdOKSkKICAgICAgICAgICAgICAgICAgICAgICAgLm1hcChlIC0+IChKQ0Fzc2lnbikgZSkKICAgICAgICAgICAgICAgICAgICAgICAgLmZpbHRlcihhc3NpZ24gLT4gVHJlZUluZm8ubmFtZShhc3NpZ24ubGhzKSA9PSBuYW1lcy5mb3JSZW1vdmFsKQogICAgICAgICAgICAgICAgICAgICAgICAuZmluZEZpcnN0KCkKICAgICAgICAgICAgICAgICAgICAgICAgLmlmUHJlc2VudChhc3NpZ24gLT4gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgSkNFeHByZXNzaW9uIHJocyA9IFRyZWVJbmZvLnNraXBQYXJlbnMoYXNzaWduLnJocyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmhzLmhhc1RhZyhMSVRFUkFMKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiBCb29sZWFuLlRSVUUuZXF1YWxzKCgoSkNMaXRlcmFsKSByaHMpLmdldFZhbHVlKCkpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ltLmZsYWdzX2ZpZWxkIHw9IERFUFJFQ0FURURfUkVNT1ZBTDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9Cn0KUEsDBAoAAAgAAAY7qUqGmg+60UMAANFDAAApAAAAY29tL3N1bi90b29scy9qYXZhYy9jb21wL01lbWJlckVudGVyLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDMsIDIwMTUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhYy5jb21wOwoKaW1wb3J0IGphdmEudXRpbC5FbnVtU2V0OwppbXBvcnQgamF2YS51dGlsLlNldDsKCmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuKjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5TY29wZS5Xcml0ZWFibGVTY29wZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS4qOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLio7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuSkNEaWFnbm9zdGljLkRpYWdub3N0aWNQb3NpdGlvbjsKCmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuU3ltYm9sLio7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuVHlwZS4qOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkpDVHJlZS4qOwoKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuRmxhZ3MuKjsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuS2luZHMuKjsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuS2luZHMuS2luZC4qOwppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5UeXBlVGFnLlRZUEVWQVI7CgovKiogUmVzb2x2ZXMgZmllbGQsIG1ldGhvZCBhbmQgY29uc3RydWN0b3IgaGVhZGVyLCBhbmQgY29uc3RydWN0cyBjb3JyZXNwb25kaW5nIFN5bWJvbHMuCiAqCiAqICA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiAgSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93biByaXNrLgogKiAgVGhpcyBjb2RlIGFuZCBpdHMgaW50ZXJuYWwgaW50ZXJmYWNlcyBhcmUgc3ViamVjdCB0byBjaGFuZ2Ugb3IKICogIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj4KICovCnB1YmxpYyBjbGFzcyBNZW1iZXJFbnRlciBleHRlbmRzIEpDVHJlZS5WaXNpdG9yIHsKICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgQ29udGV4dC5LZXk8TWVtYmVyRW50ZXI+IG1lbWJlckVudGVyS2V5ID0gbmV3IENvbnRleHQuS2V5PD4oKTsKCiAgICBwcml2YXRlIGZpbmFsIEVudGVyIGVudGVyOwogICAgcHJpdmF0ZSBmaW5hbCBMb2cgbG9nOwogICAgcHJpdmF0ZSBmaW5hbCBDaGVjayBjaGs7CiAgICBwcml2YXRlIGZpbmFsIEF0dHIgYXR0cjsKICAgIHByaXZhdGUgZmluYWwgU3ltdGFiIHN5bXM7CiAgICBwcml2YXRlIGZpbmFsIEFubm90YXRlIGFubm90YXRlOwogICAgcHJpdmF0ZSBmaW5hbCBUeXBlcyB0eXBlczsKICAgIHByaXZhdGUgZmluYWwgRGVmZXJyZWRMaW50SGFuZGxlciBkZWZlcnJlZExpbnRIYW5kbGVyOwoKICAgIHB1YmxpYyBzdGF0aWMgTWVtYmVyRW50ZXIgaW5zdGFuY2UoQ29udGV4dCBjb250ZXh0KSB7CiAgICAgICAgTWVtYmVyRW50ZXIgaW5zdGFuY2UgPSBjb250ZXh0LmdldChtZW1iZXJFbnRlcktleSk7CiAgICAgICAgaWYgKGluc3RhbmNlID09IG51bGwpCiAgICAgICAgICAgIGluc3RhbmNlID0gbmV3IE1lbWJlckVudGVyKGNvbnRleHQpOwogICAgICAgIHJldHVybiBpbnN0YW5jZTsKICAgIH0KCiAgICBwcm90ZWN0ZWQgTWVtYmVyRW50ZXIoQ29udGV4dCBjb250ZXh0KSB7CiAgICAgICAgY29udGV4dC5wdXQobWVtYmVyRW50ZXJLZXksIHRoaXMpOwogICAgICAgIGVudGVyID0gRW50ZXIuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgbG9nID0gTG9nLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIGNoayA9IENoZWNrLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIGF0dHIgPSBBdHRyLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIHN5bXMgPSBTeW10YWIuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgYW5ub3RhdGUgPSBBbm5vdGF0ZS5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICB0eXBlcyA9IFR5cGVzLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIGRlZmVycmVkTGludEhhbmRsZXIgPSBEZWZlcnJlZExpbnRIYW5kbGVyLmluc3RhbmNlKGNvbnRleHQpOwogICAgfQoKICAgIC8qKiBDb25zdHJ1Y3QgbWV0aG9kIHR5cGUgZnJvbSBtZXRob2Qgc2lnbmF0dXJlLgogICAgICogIEBwYXJhbSB0eXBhcmFtcyAgICBUaGUgbWV0aG9kJ3MgdHlwZSBwYXJhbWV0ZXJzLgogICAgICogIEBwYXJhbSBwYXJhbXMgICAgICBUaGUgbWV0aG9kJ3MgdmFsdWUgcGFyYW1ldGVycy4KICAgICAqICBAcGFyYW0gcmVzICAgICAgICAgICAgIFRoZSBtZXRob2QncyByZXN1bHQgdHlwZSwKICAgICAqICAgICAgICAgICAgICAgICBudWxsIGlmIGl0IGlzIGEgY29uc3RydWN0b3IuCiAgICAgKiAgQHBhcmFtIHJlY3ZwYXJhbSAgICAgICBUaGUgbWV0aG9kJ3MgcmVjZWl2ZXIgcGFyYW1ldGVyLAogICAgICogICAgICAgICAgICAgICAgIG51bGwgaWYgbm9uZSBnaXZlbjsgVE9ETzogb3IgYWxyZWFkeSBzZXQgaGVyZT8KICAgICAqICBAcGFyYW0gdGhyb3duICAgICAgVGhlIG1ldGhvZCdzIHRocm93biBleGNlcHRpb25zLgogICAgICogIEBwYXJhbSBlbnYgICAgICAgICAgICAgVGhlIG1ldGhvZCdzIChsb2NhbCkgZW52aXJvbm1lbnQuCiAgICAgKi8KICAgIFR5cGUgc2lnbmF0dXJlKE1ldGhvZFN5bWJvbCBtc3ltLAogICAgICAgICAgICAgICAgICAgTGlzdDxKQ1R5cGVQYXJhbWV0ZXI+IHR5cGFyYW1zLAogICAgICAgICAgICAgICAgICAgTGlzdDxKQ1ZhcmlhYmxlRGVjbD4gcGFyYW1zLAogICAgICAgICAgICAgICAgICAgSkNUcmVlIHJlcywKICAgICAgICAgICAgICAgICAgIEpDVmFyaWFibGVEZWNsIHJlY3ZwYXJhbSwKICAgICAgICAgICAgICAgICAgIExpc3Q8SkNFeHByZXNzaW9uPiB0aHJvd24sCiAgICAgICAgICAgICAgICAgICBFbnY8QXR0ckNvbnRleHQ+IGVudikgewoKICAgICAgICAvLyBFbnRlciBhbmQgYXR0cmlidXRlIHR5cGUgcGFyYW1ldGVycy4KICAgICAgICBMaXN0PFR5cGU+IHR2YXJzID0gZW50ZXIuY2xhc3NFbnRlcih0eXBhcmFtcywgZW52KTsKICAgICAgICBhdHRyLmF0dHJpYlR5cGVWYXJpYWJsZXModHlwYXJhbXMsIGVudik7CgogICAgICAgIC8vIEVudGVyIGFuZCBhdHRyaWJ1dGUgdmFsdWUgcGFyYW1ldGVycy4KICAgICAgICBMaXN0QnVmZmVyPFR5cGU+IGFyZ2J1ZiA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICBmb3IgKExpc3Q8SkNWYXJpYWJsZURlY2w+IGwgPSBwYXJhbXM7IGwubm9uRW1wdHkoKTsgbCA9IGwudGFpbCkgewogICAgICAgICAgICBtZW1iZXJFbnRlcihsLmhlYWQsIGVudik7CiAgICAgICAgICAgIGFyZ2J1Zi5hcHBlbmQobC5oZWFkLnZhcnR5cGUudHlwZSk7CiAgICAgICAgfQoKICAgICAgICAvLyBBdHRyaWJ1dGUgcmVzdWx0IHR5cGUsIGlmIG9uZSBpcyBnaXZlbi4KICAgICAgICBUeXBlIHJlc3R5cGUgPSByZXMgPT0gbnVsbCA/IHN5bXMudm9pZFR5cGUgOiBhdHRyLmF0dHJpYlR5cGUocmVzLCBlbnYpOwoKICAgICAgICAvLyBBdHRyaWJ1dGUgcmVjZWl2ZXIgdHlwZSwgaWYgb25lIGlzIGdpdmVuLgogICAgICAgIFR5cGUgcmVjdnR5cGU7CiAgICAgICAgaWYgKHJlY3ZwYXJhbSE9bnVsbCkgewogICAgICAgICAgICBtZW1iZXJFbnRlcihyZWN2cGFyYW0sIGVudik7CiAgICAgICAgICAgIHJlY3Z0eXBlID0gcmVjdnBhcmFtLnZhcnR5cGUudHlwZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZWN2dHlwZSA9IG51bGw7CiAgICAgICAgfQoKICAgICAgICAvLyBBdHRyaWJ1dGUgdGhyb3duIGV4Y2VwdGlvbnMuCiAgICAgICAgTGlzdEJ1ZmZlcjxUeXBlPiB0aHJvd25idWYgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgZm9yIChMaXN0PEpDRXhwcmVzc2lvbj4gbCA9IHRocm93bjsgbC5ub25FbXB0eSgpOyBsID0gbC50YWlsKSB7CiAgICAgICAgICAgIFR5cGUgZXhjID0gYXR0ci5hdHRyaWJUeXBlKGwuaGVhZCwgZW52KTsKICAgICAgICAgICAgaWYgKCFleGMuaGFzVGFnKFRZUEVWQVIpKSB7CiAgICAgICAgICAgICAgICBleGMgPSBjaGsuY2hlY2tDbGFzc1R5cGUobC5oZWFkLnBvcygpLCBleGMpOwogICAgICAgICAgICB9IGVsc2UgaWYgKGV4Yy50c3ltLm93bmVyID09IG1zeW0pIHsKICAgICAgICAgICAgICAgIC8vbWFyayBpbmZlcmVuY2UgdmFyaWFibGVzIGluICd0aHJvd3MnIGNsYXVzZQogICAgICAgICAgICAgICAgZXhjLnRzeW0uZmxhZ3NfZmllbGQgfD0gVEhST1dTOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHRocm93bmJ1Zi5hcHBlbmQoZXhjKTsKICAgICAgICB9CiAgICAgICAgTWV0aG9kVHlwZSBtdHlwZSA9IG5ldyBNZXRob2RUeXBlKGFyZ2J1Zi50b0xpc3QoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3duYnVmLnRvTGlzdCgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeW1zLm1ldGhvZENsYXNzKTsKICAgICAgICBtdHlwZS5yZWN2dHlwZSA9IHJlY3Z0eXBlOwoKICAgICAgICByZXR1cm4gdHZhcnMuaXNFbXB0eSgpID8gbXR5cGUgOiBuZXcgRm9yQWxsKHR2YXJzLCBtdHlwZSk7CiAgICB9CgovKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBWaXNpdG9yIG1ldGhvZHMgZm9yIG1lbWJlciBlbnRlcgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKICAgIC8qKiBWaXNpdG9yIGFyZ3VtZW50OiB0aGUgY3VycmVudCBlbnZpcm9ubWVudAogICAgICovCiAgICBwcm90ZWN0ZWQgRW52PEF0dHJDb250ZXh0PiBlbnY7CgogICAgLyoqIEVudGVyIGZpZWxkIGFuZCBtZXRob2QgZGVmaW5pdGlvbnMgYW5kIHByb2Nlc3MgaW1wb3J0CiAgICAgKiAgY2xhdXNlcywgY2F0Y2hpbmcgYW55IGNvbXBsZXRpb24gZmFpbHVyZSBleGNlcHRpb25zLgogICAgICovCiAgICBwcm90ZWN0ZWQgdm9pZCBtZW1iZXJFbnRlcihKQ1RyZWUgdHJlZSwgRW52PEF0dHJDb250ZXh0PiBlbnYpIHsKICAgICAgICBFbnY8QXR0ckNvbnRleHQ+IHByZXZFbnYgPSB0aGlzLmVudjsKICAgICAgICB0cnkgewogICAgICAgICAgICB0aGlzLmVudiA9IGVudjsKICAgICAgICAgICAgdHJlZS5hY2NlcHQodGhpcyk7CiAgICAgICAgfSAgY2F0Y2ggKENvbXBsZXRpb25GYWlsdXJlIGV4KSB7CiAgICAgICAgICAgIGNoay5jb21wbGV0aW9uRXJyb3IodHJlZS5wb3MoKSwgZXgpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgIHRoaXMuZW52ID0gcHJldkVudjsKICAgICAgICB9CiAgICB9CgogICAgLyoqIEVudGVyIG1lbWJlcnMgZnJvbSBhIGxpc3Qgb2YgdHJlZXMuCiAgICAgKi8KICAgIHZvaWQgbWVtYmVyRW50ZXIoTGlzdDw/IGV4dGVuZHMgSkNUcmVlPiB0cmVlcywgRW52PEF0dHJDb250ZXh0PiBlbnYpIHsKICAgICAgICBmb3IgKExpc3Q8PyBleHRlbmRzIEpDVHJlZT4gbCA9IHRyZWVzOyBsLm5vbkVtcHR5KCk7IGwgPSBsLnRhaWwpCiAgICAgICAgICAgIG1lbWJlckVudGVyKGwuaGVhZCwgZW52KTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdE1ldGhvZERlZihKQ01ldGhvZERlY2wgdHJlZSkgewogICAgICAgIFdyaXRlYWJsZVNjb3BlIGVuY2xTY29wZSA9IGVudGVyLmVudGVyU2NvcGUoZW52KTsKICAgICAgICBNZXRob2RTeW1ib2wgbSA9IG5ldyBNZXRob2RTeW1ib2woMCwgdHJlZS5uYW1lLCBudWxsLCBlbmNsU2NvcGUub3duZXIpOwogICAgICAgIG0uZmxhZ3NfZmllbGQgPSBjaGsuY2hlY2tGbGFncyh0cmVlLnBvcygpLCB0cmVlLm1vZHMuZmxhZ3MsIG0sIHRyZWUpOwogICAgICAgIHRyZWUuc3ltID0gbTsKCiAgICAgICAgLy9pZiB0aGlzIGlzIGEgZGVmYXVsdCBtZXRob2QsIGFkZCB0aGUgREVGQVVMVCBmbGFnIHRvIHRoZSBlbmNsb3NpbmcgaW50ZXJmYWNlCiAgICAgICAgaWYgKCh0cmVlLm1vZHMuZmxhZ3MgJiBERUZBVUxUKSAhPSAwKSB7CiAgICAgICAgICAgIG0uZW5jbENsYXNzKCkuZmxhZ3NfZmllbGQgfD0gREVGQVVMVDsKICAgICAgICB9CgogICAgICAgIEVudjxBdHRyQ29udGV4dD4gbG9jYWxFbnYgPSBtZXRob2RFbnYodHJlZSwgZW52KTsKICAgICAgICBEaWFnbm9zdGljUG9zaXRpb24gcHJldkxpbnRQb3MgPSBkZWZlcnJlZExpbnRIYW5kbGVyLnNldFBvcyh0cmVlLnBvcygpKTsKICAgICAgICB0cnkgewogICAgICAgICAgICAvLyBDb21wdXRlIHRoZSBtZXRob2QgdHlwZQogICAgICAgICAgICBtLnR5cGUgPSBzaWduYXR1cmUobSwgdHJlZS50eXBhcmFtcywgdHJlZS5wYXJhbXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmVlLnJlc3R5cGUsIHRyZWUucmVjdnBhcmFtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJlZS50aHJvd24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2NhbEVudik7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgZGVmZXJyZWRMaW50SGFuZGxlci5zZXRQb3MocHJldkxpbnRQb3MpOwogICAgICAgIH0KCiAgICAgICAgaWYgKHR5cGVzLmlzU2lnbmF0dXJlUG9seW1vcnBoaWMobSkpIHsKICAgICAgICAgICAgbS5mbGFnc19maWVsZCB8PSBTSUdOQVRVUkVfUE9MWU1PUlBISUM7CiAgICAgICAgfQoKICAgICAgICAvLyBTZXQgbS5wYXJhbXMKICAgICAgICBMaXN0QnVmZmVyPFZhclN5bWJvbD4gcGFyYW1zID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgIEpDVmFyaWFibGVEZWNsIGxhc3RQYXJhbSA9IG51bGw7CiAgICAgICAgZm9yIChMaXN0PEpDVmFyaWFibGVEZWNsPiBsID0gdHJlZS5wYXJhbXM7IGwubm9uRW1wdHkoKTsgbCA9IGwudGFpbCkgewogICAgICAgICAgICBKQ1ZhcmlhYmxlRGVjbCBwYXJhbSA9IGxhc3RQYXJhbSA9IGwuaGVhZDsKICAgICAgICAgICAgcGFyYW1zLmFwcGVuZChBc3NlcnQuY2hlY2tOb25OdWxsKHBhcmFtLnN5bSkpOwogICAgICAgIH0KICAgICAgICBtLnBhcmFtcyA9IHBhcmFtcy50b0xpc3QoKTsKCiAgICAgICAgLy8gbWFyayB0aGUgbWV0aG9kIHZhcmFyZ3MsIGlmIG5lY2Vzc2FyeQogICAgICAgIGlmIChsYXN0UGFyYW0gIT0gbnVsbCAmJiAobGFzdFBhcmFtLm1vZHMuZmxhZ3MgJiBGbGFncy5WQVJBUkdTKSAhPSAwKQogICAgICAgICAgICBtLmZsYWdzX2ZpZWxkIHw9IEZsYWdzLlZBUkFSR1M7CgogICAgICAgIGxvY2FsRW52LmluZm8uc2NvcGUubGVhdmUoKTsKICAgICAgICBpZiAoY2hrLmNoZWNrVW5pcXVlKHRyZWUucG9zKCksIG0sIGVuY2xTY29wZSkpIHsKICAgICAgICBlbmNsU2NvcGUuZW50ZXIobSk7CiAgICAgICAgfQoKICAgICAgICBhbm5vdGF0ZS5hbm5vdGF0ZUxhdGVyKHRyZWUubW9kcy5hbm5vdGF0aW9ucywgbG9jYWxFbnYsIG0sIHRyZWUucG9zKCkpOwogICAgICAgIC8vIFZpc2l0IHRoZSBzaWduYXR1cmUgb2YgdGhlIG1ldGhvZC4gTm90ZSB0aGF0CiAgICAgICAgLy8gVHlwZUFubm90YXRlIGRvZXNuJ3QgZGVzY2VuZCBpbnRvIHRoZSBib2R5LgogICAgICAgIGFubm90YXRlLnF1ZXVlU2NhblRyZWVBbmRUeXBlQW5ub3RhdGUodHJlZSwgbG9jYWxFbnYsIG0sIHRyZWUucG9zKCkpOwoKICAgICAgICBpZiAodHJlZS5kZWZhdWx0VmFsdWUgIT0gbnVsbCkgewogICAgICAgICAgICBtLmRlZmF1bHRWYWx1ZSA9IGFubm90YXRlLnVuZmluaXNoZWREZWZhdWx0VmFsdWUoKTsgLy8gc2V0IGl0IHRvIHRlbXBvcmFyeSBzZW50aW5lbCBmb3Igbm93CiAgICAgICAgICAgIGFubm90YXRlLmFubm90YXRlRGVmYXVsdFZhbHVlTGF0ZXIodHJlZS5kZWZhdWx0VmFsdWUsIGxvY2FsRW52LCBtLCB0cmVlLnBvcygpKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqIENyZWF0ZSBhIGZyZXNoIGVudmlyb25tZW50IGZvciBtZXRob2QgYm9kaWVzLgogICAgICogIEBwYXJhbSB0cmVlICAgICBUaGUgbWV0aG9kIGRlZmluaXRpb24uCiAgICAgKiAgQHBhcmFtIGVudiAgICAgIFRoZSBlbnZpcm9ubWVudCBjdXJyZW50IG91dHNpZGUgb2YgdGhlIG1ldGhvZCBkZWZpbml0aW9uLgogICAgICovCiAgICBFbnY8QXR0ckNvbnRleHQ+IG1ldGhvZEVudihKQ01ldGhvZERlY2wgdHJlZSwgRW52PEF0dHJDb250ZXh0PiBlbnYpIHsKICAgICAgICBFbnY8QXR0ckNvbnRleHQ+IGxvY2FsRW52ID0KICAgICAgICAgICAgZW52LmR1cCh0cmVlLCBlbnYuaW5mby5kdXAoZW52LmluZm8uc2NvcGUuZHVwVW5zaGFyZWQodHJlZS5zeW0pKSk7CiAgICAgICAgbG9jYWxFbnYuZW5jbE1ldGhvZCA9IHRyZWU7CiAgICAgICAgaWYgKHRyZWUuc3ltLnR5cGUgIT0gbnVsbCkgewogICAgICAgICAgICAvL3doZW4gdGhpcyBpcyBjYWxsZWQgaW4gdGhlIGVudGVyIHN0YWdlLCB0aGVyZSdzIG5vIHR5cGUgdG8gYmUgc2V0CiAgICAgICAgICAgIGxvY2FsRW52LmluZm8ucmV0dXJuUmVzdWx0ID0gYXR0ci5uZXcgUmVzdWx0SW5mbyhLaW5kU2VsZWN0b3IuVkFMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJlZS5zeW0udHlwZS5nZXRSZXR1cm5UeXBlKCkpOwogICAgICAgIH0KICAgICAgICBpZiAoKHRyZWUubW9kcy5mbGFncyAmIFNUQVRJQykgIT0gMCkgbG9jYWxFbnYuaW5mby5zdGF0aWNMZXZlbCsrOwogICAgICAgIHJldHVybiBsb2NhbEVudjsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdFZhckRlZihKQ1ZhcmlhYmxlRGVjbCB0cmVlKSB7CiAgICAgICAgRW52PEF0dHJDb250ZXh0PiBsb2NhbEVudiA9IGVudjsKICAgICAgICBpZiAoKHRyZWUubW9kcy5mbGFncyAmIFNUQVRJQykgIT0gMCB8fAogICAgICAgICAgICAoZW52LmluZm8uc2NvcGUub3duZXIuZmxhZ3MoKSAmIElOVEVSRkFDRSkgIT0gMCkgewogICAgICAgICAgICBsb2NhbEVudiA9IGVudi5kdXAodHJlZSwgZW52LmluZm8uZHVwKCkpOwogICAgICAgICAgICBsb2NhbEVudi5pbmZvLnN0YXRpY0xldmVsKys7CiAgICAgICAgfQogICAgICAgIERpYWdub3N0aWNQb3NpdGlvbiBwcmV2TGludFBvcyA9IGRlZmVycmVkTGludEhhbmRsZXIuc2V0UG9zKHRyZWUucG9zKCkpOwoKICAgICAgICB0cnkgewogICAgICAgICAgICBpZiAoVHJlZUluZm8uaXNFbnVtSW5pdCh0cmVlKSkgewogICAgICAgICAgICAgICAgYXR0ci5hdHRyaWJJZGVudEFzRW51bVR5cGUobG9jYWxFbnYsIChKQ0lkZW50KXRyZWUudmFydHlwZSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBhdHRyLmF0dHJpYlR5cGUodHJlZS52YXJ0eXBlLCBsb2NhbEVudik7CiAgICAgICAgICAgICAgICBpZiAoVHJlZUluZm8uaXNSZWNlaXZlclBhcmFtKHRyZWUpKQogICAgICAgICAgICAgICAgICAgIGNoZWNrUmVjZWl2ZXIodHJlZSwgbG9jYWxFbnYpOwogICAgICAgICAgICB9CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgZGVmZXJyZWRMaW50SGFuZGxlci5zZXRQb3MocHJldkxpbnRQb3MpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCh0cmVlLm1vZHMuZmxhZ3MgJiBWQVJBUkdTKSAhPSAwKSB7CiAgICAgICAgICAgIC8vaWYgd2UgYXJlIGVudGVyaW5nIGEgdmFyYXJncyBwYXJhbWV0ZXIsIHdlIG5lZWQgdG8KICAgICAgICAgICAgLy9yZXBsYWNlIGl0cyB0eXBlIChhIHBsYWluIGFycmF5IHR5cGUpIHdpdGggdGhlIG1vcmUKICAgICAgICAgICAgLy9wcmVjaXNlIFZhcmFyZ3NUeXBlIC0tLSB3ZSBuZWVkIHRvIGRvIGl0IHRoaXMgd2F5CiAgICAgICAgICAgIC8vYmVjYXVzZSB2YXJhcmdzIGlzIHJlcHJlc2VudGVkIGluIHRoZSB0cmVlIGFzIGEKICAgICAgICAgICAgLy9tb2RpZmllciBvbiB0aGUgcGFyYW1ldGVyIGRlY2xhcmF0aW9uLCBhbmQgbm90IGFzIGEKICAgICAgICAgICAgLy9kaXN0aW5jdCB0eXBlIG9mIGFycmF5IG5vZGUuCiAgICAgICAgICAgIEFycmF5VHlwZSBhdHlwZSA9IChBcnJheVR5cGUpdHJlZS52YXJ0eXBlLnR5cGU7CiAgICAgICAgICAgIHRyZWUudmFydHlwZS50eXBlID0gYXR5cGUubWFrZVZhcmFyZ3MoKTsKICAgICAgICB9CiAgICAgICAgV3JpdGVhYmxlU2NvcGUgZW5jbFNjb3BlID0gZW50ZXIuZW50ZXJTY29wZShlbnYpOwogICAgICAgIFZhclN5bWJvbCB2ID0KICAgICAgICAgICAgbmV3IFZhclN5bWJvbCgwLCB0cmVlLm5hbWUsIHRyZWUudmFydHlwZS50eXBlLCBlbmNsU2NvcGUub3duZXIpOwogICAgICAgIHYuZmxhZ3NfZmllbGQgPSBjaGsuY2hlY2tGbGFncyh0cmVlLnBvcygpLCB0cmVlLm1vZHMuZmxhZ3MsIHYsIHRyZWUpOwogICAgICAgIHRyZWUuc3ltID0gdjsKICAgICAgICBpZiAodHJlZS5pbml0ICE9IG51bGwpIHsKICAgICAgICAgICAgdi5mbGFnc19maWVsZCB8PSBIQVNJTklUOwogICAgICAgICAgICBpZiAoKHYuZmxhZ3NfZmllbGQgJiBGSU5BTCkgIT0gMCAmJgogICAgICAgICAgICAgICAgbmVlZHNMYXp5Q29uc3RWYWx1ZSh0cmVlLmluaXQpKSB7CiAgICAgICAgICAgICAgICBFbnY8QXR0ckNvbnRleHQ+IGluaXRFbnYgPSBnZXRJbml0RW52KHRyZWUsIGVudik7CiAgICAgICAgICAgICAgICBpbml0RW52LmluZm8uZW5jbFZhciA9IHY7CiAgICAgICAgICAgICAgICB2LnNldExhenlDb25zdFZhbHVlKGluaXRFbnYodHJlZSwgaW5pdEVudiksIGF0dHIsIHRyZWUpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmIChjaGsuY2hlY2tVbmlxdWUodHJlZS5wb3MoKSwgdiwgZW5jbFNjb3BlKSkgewogICAgICAgICAgICBjaGsuY2hlY2tUcmFuc3BhcmVudFZhcih0cmVlLnBvcygpLCB2LCBlbmNsU2NvcGUpOwogICAgICAgICAgICBlbmNsU2NvcGUuZW50ZXIodik7CiAgICAgICAgfQoKICAgICAgICBhbm5vdGF0ZS5hbm5vdGF0ZUxhdGVyKHRyZWUubW9kcy5hbm5vdGF0aW9ucywgbG9jYWxFbnYsIHYsIHRyZWUucG9zKCkpOwogICAgICAgIGFubm90YXRlLnF1ZXVlU2NhblRyZWVBbmRUeXBlQW5ub3RhdGUodHJlZS52YXJ0eXBlLCBsb2NhbEVudiwgdiwgdHJlZS5wb3MoKSk7CgogICAgICAgIHYucG9zID0gdHJlZS5wb3M7CiAgICB9CiAgICAvLyB3aGVyZQogICAgdm9pZCBjaGVja1R5cGUoSkNUcmVlIHRyZWUsIFR5cGUgdHlwZSwgU3RyaW5nIGRpYWcpIHsKICAgICAgICBpZiAoIXRyZWUudHlwZS5pc0Vycm9uZW91cygpICYmICF0eXBlcy5pc1NhbWVUeXBlKHRyZWUudHlwZSwgdHlwZSkpIHsKICAgICAgICAgICAgbG9nLmVycm9yKHRyZWUsIGRpYWcsIHR5cGUsIHRyZWUudHlwZSk7CiAgICAgICAgfQogICAgfQogICAgdm9pZCBjaGVja1JlY2VpdmVyKEpDVmFyaWFibGVEZWNsIHRyZWUsIEVudjxBdHRyQ29udGV4dD4gbG9jYWxFbnYpIHsKICAgICAgICBhdHRyLmF0dHJpYkV4cHIodHJlZS5uYW1lZXhwciwgbG9jYWxFbnYpOwogICAgICAgIE1ldGhvZFN5bWJvbCBtID0gbG9jYWxFbnYuZW5jbE1ldGhvZC5zeW07CiAgICAgICAgaWYgKG0uaXNDb25zdHJ1Y3RvcigpKSB7CiAgICAgICAgICAgIFR5cGUgb3V0ZXJ0eXBlID0gbS5vd25lci5vd25lci50eXBlOwogICAgICAgICAgICBpZiAob3V0ZXJ0eXBlLmhhc1RhZyhUeXBlVGFnLk1FVEhPRCkpIHsKICAgICAgICAgICAgICAgIC8vIHdlIGhhdmUgYSBsb2NhbCBpbm5lciBjbGFzcwogICAgICAgICAgICAgICAgb3V0ZXJ0eXBlID0gbS5vd25lci5vd25lci5vd25lci50eXBlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChvdXRlcnR5cGUuaGFzVGFnKFR5cGVUYWcuQ0xBU1MpKSB7CiAgICAgICAgICAgICAgICBjaGVja1R5cGUodHJlZS52YXJ0eXBlLCBvdXRlcnR5cGUsICJpbmNvcnJlY3QuY29uc3RydWN0b3IucmVjZWl2ZXIudHlwZSIpOwogICAgICAgICAgICAgICAgY2hlY2tUeXBlKHRyZWUubmFtZWV4cHIsIG91dGVydHlwZSwgImluY29ycmVjdC5jb25zdHJ1Y3Rvci5yZWNlaXZlci5uYW1lIik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBsb2cuZXJyb3IodHJlZSwgInJlY2VpdmVyLnBhcmFtZXRlci5ub3QuYXBwbGljYWJsZS5jb25zdHJ1Y3Rvci50b3BsZXZlbC5jbGFzcyIpOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgY2hlY2tUeXBlKHRyZWUudmFydHlwZSwgbS5vd25lci50eXBlLCAiaW5jb3JyZWN0LnJlY2VpdmVyLnR5cGUiKTsKICAgICAgICAgICAgY2hlY2tUeXBlKHRyZWUubmFtZWV4cHIsIG0ub3duZXIudHlwZSwgImluY29ycmVjdC5yZWNlaXZlci5uYW1lIik7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBib29sZWFuIG5lZWRzTGF6eUNvbnN0VmFsdWUoSkNUcmVlIHRyZWUpIHsKICAgICAgICBJbml0VHJlZVZpc2l0b3IgaW5pdFRyZWVWaXNpdG9yID0gbmV3IEluaXRUcmVlVmlzaXRvcigpOwogICAgICAgIHRyZWUuYWNjZXB0KGluaXRUcmVlVmlzaXRvcik7CiAgICAgICAgcmV0dXJuIGluaXRUcmVlVmlzaXRvci5yZXN1bHQ7CiAgICB9CgogICAgLyoqIFZpc2l0b3IgY2xhc3MgZm9yIGV4cHJlc3Npb25zIHdoaWNoIG1pZ2h0IGJlIGNvbnN0YW50IGV4cHJlc3Npb25zLAogICAgICogIGFzIHBlciBKTFMgMTUuMjggKENvbnN0YW50IEV4cHJlc3Npb25zKS4KICAgICAqLwogICAgc3RhdGljIGNsYXNzIEluaXRUcmVlVmlzaXRvciBleHRlbmRzIEpDVHJlZS5WaXNpdG9yIHsKCiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU2V0PFRhZz4gQUxMT1dFRF9PUEVSQVRPUlMgPQogICAgICAgICAgICAgICAgRW51bVNldC5vZihUYWcuUE9TLCBUYWcuTkVHLCBUYWcuTk9ULCBUYWcuQ09NUEwsIFRhZy5QTFVTLCBUYWcuTUlOVVMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFRhZy5NVUwsIFRhZy5ESVYsIFRhZy5NT0QsIFRhZy5TTCwgVGFnLlNSLCBUYWcuVVNSLAogICAgICAgICAgICAgICAgICAgICAgICAgICBUYWcuTFQsIFRhZy5MRSwgVGFnLkdULCBUYWcuR0UsIFRhZy5FUSwgVGFnLk5FLAogICAgICAgICAgICAgICAgICAgICAgICAgICBUYWcuQklUQU5ELCBUYWcuQklUWE9SLCBUYWcuQklUT1IsIFRhZy5BTkQsIFRhZy5PUik7CgogICAgICAgIHByaXZhdGUgYm9vbGVhbiByZXN1bHQgPSB0cnVlOwoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdFRyZWUoSkNUcmVlIHRyZWUpIHsKICAgICAgICAgICAgcmVzdWx0ID0gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdExpdGVyYWwoSkNMaXRlcmFsIHRoYXQpIHt9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0VHlwZUNhc3QoSkNUeXBlQ2FzdCB0cmVlKSB7CiAgICAgICAgICAgIHRyZWUuZXhwci5hY2NlcHQodGhpcyk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdFVuYXJ5KEpDVW5hcnkgdGhhdCkgewogICAgICAgICAgICBpZiAoIUFMTE9XRURfT1BFUkFUT1JTLmNvbnRhaW5zKHRoYXQuZ2V0VGFnKCkpKSB7CiAgICAgICAgICAgICAgICByZXN1bHQgPSBmYWxzZTsKICAgICAgICAgICAgICAgIHJldHVybiA7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdGhhdC5hcmcuYWNjZXB0KHRoaXMpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRCaW5hcnkoSkNCaW5hcnkgdGhhdCkgewogICAgICAgICAgICBpZiAoIUFMTE9XRURfT1BFUkFUT1JTLmNvbnRhaW5zKHRoYXQuZ2V0VGFnKCkpKSB7CiAgICAgICAgICAgICAgICByZXN1bHQgPSBmYWxzZTsKICAgICAgICAgICAgICAgIHJldHVybiA7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdGhhdC5saHMuYWNjZXB0KHRoaXMpOwogICAgICAgICAgICB0aGF0LnJocy5hY2NlcHQodGhpcyk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdENvbmRpdGlvbmFsKEpDQ29uZGl0aW9uYWwgdHJlZSkgewogICAgICAgICAgICB0cmVlLmNvbmQuYWNjZXB0KHRoaXMpOwogICAgICAgICAgICB0cmVlLnRydWVwYXJ0LmFjY2VwdCh0aGlzKTsKICAgICAgICAgICAgdHJlZS5mYWxzZXBhcnQuYWNjZXB0KHRoaXMpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRQYXJlbnMoSkNQYXJlbnMgdHJlZSkgewogICAgICAgICAgICB0cmVlLmV4cHIuYWNjZXB0KHRoaXMpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRJZGVudChKQ0lkZW50IHRoYXQpIHt9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0U2VsZWN0KEpDRmllbGRBY2Nlc3MgdHJlZSkgewogICAgICAgICAgICB0cmVlLnNlbGVjdGVkLmFjY2VwdCh0aGlzKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqIENyZWF0ZSBhIGZyZXNoIGVudmlyb25tZW50IGZvciBhIHZhcmlhYmxlJ3MgaW5pdGlhbGl6ZXIuCiAgICAgKiAgSWYgdGhlIHZhcmlhYmxlIGlzIGEgZmllbGQsIHRoZSBvd25lciBvZiB0aGUgZW52aXJvbm1lbnQncyBzY29wZQogICAgICogIGlzIGJlIHRoZSB2YXJpYWJsZSBpdHNlbGYsIG90aGVyd2lzZSB0aGUgb3duZXIgaXMgdGhlIG1ldGhvZAogICAgICogIGVuY2xvc2luZyB0aGUgdmFyaWFibGUgZGVmaW5pdGlvbi4KICAgICAqCiAgICAgKiAgQHBhcmFtIHRyZWUgICAgIFRoZSB2YXJpYWJsZSBkZWZpbml0aW9uLgogICAgICogIEBwYXJhbSBlbnYgICAgICBUaGUgZW52aXJvbm1lbnQgY3VycmVudCBvdXRzaWRlIG9mIHRoZSB2YXJpYWJsZSBkZWZpbml0aW9uLgogICAgICovCiAgICBFbnY8QXR0ckNvbnRleHQ+IGluaXRFbnYoSkNWYXJpYWJsZURlY2wgdHJlZSwgRW52PEF0dHJDb250ZXh0PiBlbnYpIHsKICAgICAgICBFbnY8QXR0ckNvbnRleHQ+IGxvY2FsRW52ID0gZW52LmR1cHRvKG5ldyBBdHRyQ29udGV4dEVudih0cmVlLCBlbnYuaW5mby5kdXAoKSkpOwogICAgICAgIGlmICh0cmVlLnN5bS5vd25lci5raW5kID09IFRZUCkgewogICAgICAgICAgICBsb2NhbEVudi5pbmZvLnNjb3BlID0gZW52LmluZm8uc2NvcGUuZHVwVW5zaGFyZWQodHJlZS5zeW0pOwogICAgICAgIH0KICAgICAgICBpZiAoKHRyZWUubW9kcy5mbGFncyAmIFNUQVRJQykgIT0gMCB8fAogICAgICAgICAgICAgICAgKChlbnYuZW5jbENsYXNzLnN5bS5mbGFncygpICYgSU5URVJGQUNFKSAhPSAwICYmIGVudi5lbmNsTWV0aG9kID09IG51bGwpKQogICAgICAgICAgICBsb2NhbEVudi5pbmZvLnN0YXRpY0xldmVsKys7CiAgICAgICAgcmV0dXJuIGxvY2FsRW52OwogICAgfQoKICAgIC8qKiBEZWZhdWx0IG1lbWJlciBlbnRlciB2aXNpdG9yIG1ldGhvZDogZG8gbm90aGluZwogICAgICovCiAgICBwdWJsaWMgdm9pZCB2aXNpdFRyZWUoSkNUcmVlIHRyZWUpIHsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdEVycm9uZW91cyhKQ0Vycm9uZW91cyB0cmVlKSB7CiAgICAgICAgaWYgKHRyZWUuZXJycyAhPSBudWxsKQogICAgICAgICAgICBtZW1iZXJFbnRlcih0cmVlLmVycnMsIGVudik7CiAgICB9CgogICAgcHVibGljIEVudjxBdHRyQ29udGV4dD4gZ2V0TWV0aG9kRW52KEpDTWV0aG9kRGVjbCB0cmVlLCBFbnY8QXR0ckNvbnRleHQ+IGVudikgewogICAgICAgIEVudjxBdHRyQ29udGV4dD4gbUVudiA9IG1ldGhvZEVudih0cmVlLCBlbnYpOwogICAgICAgIG1FbnYuaW5mby5saW50ID0gbUVudi5pbmZvLmxpbnQuYXVnbWVudCh0cmVlLnN5bSk7CiAgICAgICAgZm9yIChMaXN0PEpDVHlwZVBhcmFtZXRlcj4gbCA9IHRyZWUudHlwYXJhbXM7IGwubm9uRW1wdHkoKTsgbCA9IGwudGFpbCkKICAgICAgICAgICAgbUVudi5pbmZvLnNjb3BlLmVudGVySWZBYnNlbnQobC5oZWFkLnR5cGUudHN5bSk7CiAgICAgICAgZm9yIChMaXN0PEpDVmFyaWFibGVEZWNsPiBsID0gdHJlZS5wYXJhbXM7IGwubm9uRW1wdHkoKTsgbCA9IGwudGFpbCkKICAgICAgICAgICAgbUVudi5pbmZvLnNjb3BlLmVudGVySWZBYnNlbnQobC5oZWFkLnN5bSk7CiAgICAgICAgcmV0dXJuIG1FbnY7CiAgICB9CgogICAgcHVibGljIEVudjxBdHRyQ29udGV4dD4gZ2V0SW5pdEVudihKQ1ZhcmlhYmxlRGVjbCB0cmVlLCBFbnY8QXR0ckNvbnRleHQ+IGVudikgewogICAgICAgIEVudjxBdHRyQ29udGV4dD4gaUVudiA9IGluaXRFbnYodHJlZSwgZW52KTsKICAgICAgICByZXR1cm4gaUVudjsKICAgIH0KfQpQSwMECgAACAAABjupShHNqLHriAIA64gCACMAAABjb20vc3VuL3Rvb2xzL2phdmFjL2NvbXAvTG93ZXIuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMTk5OSwgMjAxNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLmphdmFjLmNvbXA7CgppbXBvcnQgamF2YS51dGlsLio7CgppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLio7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuS2luZHMuS2luZFNlbGVjdG9yOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlNjb3BlLldyaXRlYWJsZVNjb3BlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5qdm0uKjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMubWFpbi5PcHRpb24uUGtnSW5mbzsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS4qOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLio7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuSkNEaWFnbm9zdGljLkRpYWdub3N0aWNQb3NpdGlvbjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5MaXN0OwoKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5TeW1ib2wuKjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5TeW1ib2wuT3BlcmF0b3JTeW1ib2wuQWNjZXNzQ29kZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5KQ1RyZWUuKjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5UeXBlLio7CgppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5qdm0uVGFyZ2V0OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkVuZFBvc1RhYmxlOwoKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuRmxhZ3MuKjsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuRmxhZ3MuQkxPQ0s7CmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlNjb3BlLkxvb2t1cEtpbmQuTk9OX1JFQ1VSU0lWRTsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuVHlwZVRhZy4qOwppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5LaW5kcy5LaW5kLio7CmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlN5bWJvbC5PcGVyYXRvclN5bWJvbC5BY2Nlc3NDb2RlLkRFUkVGOwppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMuanZtLkJ5dGVDb2Rlcy4qOwppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5KQ1RyZWUuSkNPcGVyYXRvckV4cHJlc3Npb24uT3BlcmFuZFBvcy5MRUZUOwppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5KQ1RyZWUuVGFnLio7CgovKiogVGhpcyBwYXNzIHRyYW5zbGF0ZXMgYXdheSBzb21lIHN5bnRhY3RpYyBzdWdhcjogaW5uZXIgY2xhc3NlcywKICogIGNsYXNzIGxpdGVyYWxzLCBhc3NlcnRpb25zLCBmb3JlYWNoIGxvb3BzLCBldGMuCiAqCiAqICA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiAgSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93biByaXNrLgogKiAgVGhpcyBjb2RlIGFuZCBpdHMgaW50ZXJuYWwgaW50ZXJmYWNlcyBhcmUgc3ViamVjdCB0byBjaGFuZ2Ugb3IKICogIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj4KICovCnB1YmxpYyBjbGFzcyBMb3dlciBleHRlbmRzIFRyZWVUcmFuc2xhdG9yIHsKICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgQ29udGV4dC5LZXk8TG93ZXI+IGxvd2VyS2V5ID0gbmV3IENvbnRleHQuS2V5PD4oKTsKCiAgICBwdWJsaWMgc3RhdGljIExvd2VyIGluc3RhbmNlKENvbnRleHQgY29udGV4dCkgewogICAgICAgIExvd2VyIGluc3RhbmNlID0gY29udGV4dC5nZXQobG93ZXJLZXkpOwogICAgICAgIGlmIChpbnN0YW5jZSA9PSBudWxsKQogICAgICAgICAgICBpbnN0YW5jZSA9IG5ldyBMb3dlcihjb250ZXh0KTsKICAgICAgICByZXR1cm4gaW5zdGFuY2U7CiAgICB9CgogICAgcHJpdmF0ZSBmaW5hbCBOYW1lcyBuYW1lczsKICAgIHByaXZhdGUgZmluYWwgTG9nIGxvZzsKICAgIHByaXZhdGUgZmluYWwgU3ltdGFiIHN5bXM7CiAgICBwcml2YXRlIGZpbmFsIFJlc29sdmUgcnM7CiAgICBwcml2YXRlIGZpbmFsIE9wZXJhdG9ycyBvcGVyYXRvcnM7CiAgICBwcml2YXRlIGZpbmFsIENoZWNrIGNoazsKICAgIHByaXZhdGUgZmluYWwgQXR0ciBhdHRyOwogICAgcHJpdmF0ZSBUcmVlTWFrZXIgbWFrZTsKICAgIHByaXZhdGUgRGlhZ25vc3RpY1Bvc2l0aW9uIG1ha2VfcG9zOwogICAgcHJpdmF0ZSBmaW5hbCBDbGFzc1dyaXRlciB3cml0ZXI7CiAgICBwcml2YXRlIGZpbmFsIENvbnN0Rm9sZCBjZm9sZGVyOwogICAgcHJpdmF0ZSBmaW5hbCBUYXJnZXQgdGFyZ2V0OwogICAgcHJpdmF0ZSBmaW5hbCBTb3VyY2Ugc291cmNlOwogICAgcHJpdmF0ZSBmaW5hbCBUeXBlRW52cyB0eXBlRW52czsKICAgIHByaXZhdGUgZmluYWwgTmFtZSBkb2xsYXJBc3NlcnRpb25zRGlzYWJsZWQ7CiAgICBwcml2YXRlIGZpbmFsIE5hbWUgY2xhc3NEb2xsYXI7CiAgICBwcml2YXRlIGZpbmFsIE5hbWUgZG9sbGFyQ2xvc2VSZXNvdXJjZTsKICAgIHByaXZhdGUgZmluYWwgVHlwZXMgdHlwZXM7CiAgICBwcml2YXRlIGZpbmFsIGJvb2xlYW4gZGVidWdMb3dlcjsKICAgIHByaXZhdGUgZmluYWwgUGtnSW5mbyBwa2dpbmZvT3B0OwoKICAgIHByb3RlY3RlZCBMb3dlcihDb250ZXh0IGNvbnRleHQpIHsKICAgICAgICBjb250ZXh0LnB1dChsb3dlcktleSwgdGhpcyk7CiAgICAgICAgbmFtZXMgPSBOYW1lcy5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBsb2cgPSBMb2cuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgc3ltcyA9IFN5bXRhYi5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBycyA9IFJlc29sdmUuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgb3BlcmF0b3JzID0gT3BlcmF0b3JzLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIGNoayA9IENoZWNrLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIGF0dHIgPSBBdHRyLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIG1ha2UgPSBUcmVlTWFrZXIuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgd3JpdGVyID0gQ2xhc3NXcml0ZXIuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgY2ZvbGRlciA9IENvbnN0Rm9sZC5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICB0YXJnZXQgPSBUYXJnZXQuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgc291cmNlID0gU291cmNlLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIHR5cGVFbnZzID0gVHlwZUVudnMuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgZG9sbGFyQXNzZXJ0aW9uc0Rpc2FibGVkID0gbmFtZXMuCiAgICAgICAgICAgIGZyb21TdHJpbmcodGFyZ2V0LnN5bnRoZXRpY05hbWVDaGFyKCkgKyAiYXNzZXJ0aW9uc0Rpc2FibGVkIik7CiAgICAgICAgY2xhc3NEb2xsYXIgPSBuYW1lcy4KICAgICAgICAgICAgZnJvbVN0cmluZygiY2xhc3MiICsgdGFyZ2V0LnN5bnRoZXRpY05hbWVDaGFyKCkpOwogICAgICAgIGRvbGxhckNsb3NlUmVzb3VyY2UgPSBuYW1lcy4KICAgICAgICAgICAgZnJvbVN0cmluZyh0YXJnZXQuc3ludGhldGljTmFtZUNoYXIoKSArICJjbG9zZVJlc291cmNlIik7CgogICAgICAgIHR5cGVzID0gVHlwZXMuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgT3B0aW9ucyBvcHRpb25zID0gT3B0aW9ucy5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBkZWJ1Z0xvd2VyID0gb3B0aW9ucy5pc1NldCgiZGVidWdsb3dlciIpOwogICAgICAgIHBrZ2luZm9PcHQgPSBQa2dJbmZvLmdldChvcHRpb25zKTsKICAgIH0KCiAgICAvKiogVGhlIGN1cnJlbnRseSBlbmNsb3NpbmcgY2xhc3MuCiAgICAgKi8KICAgIENsYXNzU3ltYm9sIGN1cnJlbnRDbGFzczsKCiAgICAvKiogQSBxdWV1ZSBvZiBhbGwgdHJhbnNsYXRlZCBjbGFzc2VzLgogICAgICovCiAgICBMaXN0QnVmZmVyPEpDVHJlZT4gdHJhbnNsYXRlZDsKCiAgICAvKiogRW52aXJvbm1lbnQgZm9yIHN5bWJvbCBsb29rdXAsIHNldCBieSB0cmFuc2xhdGVUb3BMZXZlbENsYXNzLgogICAgICovCiAgICBFbnY8QXR0ckNvbnRleHQ+IGF0dHJFbnY7CgogICAgLyoqIEEgaGFzaCB0YWJsZSBtYXBwaW5nIHN5bnRheCB0cmVlcyB0byB0aGVpciBlbmRpbmcgc291cmNlIHBvc2l0aW9ucy4KICAgICAqLwogICAgRW5kUG9zVGFibGUgZW5kUG9zVGFibGU7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogR2xvYmFsIG1hcHBpbmdzCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKICAgIC8qKiBBIGhhc2ggdGFibGUgbWFwcGluZyBsb2NhbCBjbGFzc2VzIHRvIHRoZWlyIGRlZmluaXRpb25zLgogICAgICovCiAgICBNYXA8Q2xhc3NTeW1ib2wsIEpDQ2xhc3NEZWNsPiBjbGFzc2RlZnM7CgogICAgLyoqIEEgaGFzaCB0YWJsZSBtYXBwaW5nIGxvY2FsIGNsYXNzZXMgdG8gYSBsaXN0IG9mIHBydW5lZCB0cmVlcy4KICAgICAqLwogICAgcHVibGljIE1hcDxDbGFzc1N5bWJvbCwgTGlzdDxKQ1RyZWU+PiBwcnVuZWRUcmVlID0gbmV3IFdlYWtIYXNoTWFwPD4oKTsKCiAgICAvKiogQSBoYXNoIHRhYmxlIG1hcHBpbmcgdmlydHVhbCBhY2Nlc3NlZCBzeW1ib2xzIGluIG91dGVyIHN1YmNsYXNzZXMKICAgICAqICB0byB0aGUgYWN0dWFsbHkgcmVmZXJyZWQgc3ltYm9sIGluIHN1cGVyY2xhc3Nlcy4KICAgICAqLwogICAgTWFwPFN5bWJvbCxTeW1ib2w+IGFjdHVhbFN5bWJvbHM7CgogICAgLyoqIFRoZSBjdXJyZW50IG1ldGhvZCBkZWZpbml0aW9uLgogICAgICovCiAgICBKQ01ldGhvZERlY2wgY3VycmVudE1ldGhvZERlZjsKCiAgICAvKiogVGhlIGN1cnJlbnQgbWV0aG9kIHN5bWJvbC4KICAgICAqLwogICAgTWV0aG9kU3ltYm9sIGN1cnJlbnRNZXRob2RTeW07CgogICAgLyoqIFRoZSBjdXJyZW50bHkgZW5jbG9zaW5nIG91dGVybW9zdCBjbGFzcyBkZWZpbml0aW9uLgogICAgICovCiAgICBKQ0NsYXNzRGVjbCBvdXRlcm1vc3RDbGFzc0RlZjsKCiAgICAvKiogVGhlIGN1cnJlbnRseSBlbmNsb3Npbmcgb3V0ZXJtb3N0IG1lbWJlciBkZWZpbml0aW9uLgogICAgICovCiAgICBKQ1RyZWUgb3V0ZXJtb3N0TWVtYmVyRGVmOwoKICAgIC8qKiBBIG1hcCBmcm9tIGxvY2FsIHZhcmlhYmxlIHN5bWJvbHMgdG8gdGhlaXIgdHJhbnNsYXRpb24gKGFzIHBlciBMYW1iZGFUb01ldGhvZCkuCiAgICAgKiBUaGlzIGlzIHJlcXVpcmVkIHdoZW4gYSBjYXB0dXJpbmcgbG9jYWwgY2xhc3MgaXMgY3JlYXRlZCBmcm9tIGEgbGFtYmRhIChpbiB3aGljaAogICAgICogY2FzZSB0aGUgY2FwdHVyZWQgc3ltYm9scyBzaG91bGQgYmUgcmVwbGFjZWQgd2l0aCB0aGUgdHJhbnNsYXRlZCBsYW1iZGEgc3ltYm9scykuCiAgICAgKi8KICAgIE1hcDxTeW1ib2wsIFN5bWJvbD4gbGFtYmRhVHJhbnNsYXRpb25NYXAgPSBudWxsOwoKICAgIC8qKiBBIG5hdmlnYXRvciBjbGFzcyBmb3IgYXNzZW1ibGluZyBhIG1hcHBpbmcgZnJvbSBsb2NhbCBjbGFzcyBzeW1ib2xzCiAgICAgKiAgdG8gY2xhc3MgZGVmaW5pdGlvbiB0cmVlcy4KICAgICAqICBUaGVyZSBpcyBvbmx5IG9uZSBjYXNlOyBhbGwgb3RoZXIgY2FzZXMgc2ltcGx5IHRyYXZlcnNlIGRvd24gdGhlIHRyZWUuCiAgICAgKi8KICAgIGNsYXNzIENsYXNzTWFwIGV4dGVuZHMgVHJlZVNjYW5uZXIgewoKICAgICAgICAvKiogQWxsIGVuY291bnRlcmVkIGNsYXNzIGRlZnMgYXJlIGVudGVyZWQgaW50byBjbGFzc2RlZnMgdGFibGUuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRDbGFzc0RlZihKQ0NsYXNzRGVjbCB0cmVlKSB7CiAgICAgICAgICAgIGNsYXNzZGVmcy5wdXQodHJlZS5zeW0sIHRyZWUpOwogICAgICAgICAgICBzdXBlci52aXNpdENsYXNzRGVmKHRyZWUpOwogICAgICAgIH0KICAgIH0KICAgIENsYXNzTWFwIGNsYXNzTWFwID0gbmV3IENsYXNzTWFwKCk7CgogICAgLyoqIE1hcCBhIGNsYXNzIHN5bWJvbCB0byBpdHMgZGVmaW5pdGlvbi4KICAgICAqICBAcGFyYW0gYyAgICBUaGUgY2xhc3Mgc3ltYm9sIG9mIHdoaWNoIHdlIHdhbnQgdG8gZGV0ZXJtaW5lIHRoZSBkZWZpbml0aW9uLgogICAgICovCiAgICBKQ0NsYXNzRGVjbCBjbGFzc0RlZihDbGFzc1N5bWJvbCBjKSB7CiAgICAgICAgLy8gRmlyc3QgbG9va3VwIHRoZSBjbGFzcyBpbiB0aGUgY2xhc3NkZWZzIHRhYmxlLgogICAgICAgIEpDQ2xhc3NEZWNsIGRlZiA9IGNsYXNzZGVmcy5nZXQoYyk7CiAgICAgICAgaWYgKGRlZiA9PSBudWxsICYmIG91dGVybW9zdE1lbWJlckRlZiAhPSBudWxsKSB7CiAgICAgICAgICAgIC8vIElmIHRoaXMgZmFpbHMsIHRyYXZlcnNlIG91dGVybW9zdCBtZW1iZXIgZGVmaW5pdGlvbiwgZW50ZXJpbmcgYWxsCiAgICAgICAgICAgIC8vIGxvY2FsIGNsYXNzZXMgaW50byBjbGFzc2RlZnMsIGFuZCB0cnkgYWdhaW4uCiAgICAgICAgICAgIGNsYXNzTWFwLnNjYW4ob3V0ZXJtb3N0TWVtYmVyRGVmKTsKICAgICAgICAgICAgZGVmID0gY2xhc3NkZWZzLmdldChjKTsKICAgICAgICB9CiAgICAgICAgaWYgKGRlZiA9PSBudWxsKSB7CiAgICAgICAgICAgIC8vIElmIHRoaXMgZmFpbHMsIHRyYXZlcnNlIG91dGVybW9zdCBjbGFzcyBkZWZpbml0aW9uLCBlbnRlcmluZyBhbGwKICAgICAgICAgICAgLy8gbG9jYWwgY2xhc3NlcyBpbnRvIGNsYXNzZGVmcywgYW5kIHRyeSBhZ2Fpbi4KICAgICAgICAgICAgY2xhc3NNYXAuc2NhbihvdXRlcm1vc3RDbGFzc0RlZik7CiAgICAgICAgICAgIGRlZiA9IGNsYXNzZGVmcy5nZXQoYyk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBkZWY7CiAgICB9CgogICAgLyoqIEEgaGFzaCB0YWJsZSBtYXBwaW5nIGNsYXNzIHN5bWJvbHMgdG8gbGlzdHMgb2YgZnJlZSB2YXJpYWJsZXMuCiAgICAgKiAgYWNjZXNzZWQgYnkgdGhlbS4gT25seSBmcmVlIHZhcmlhYmxlcyBvZiB0aGUgbWV0aG9kIGltbWVkaWF0ZWx5IGNvbnRhaW5pbmcKICAgICAqICBhIGNsYXNzIGFyZSBhc3NvY2lhdGVkIHdpdGggdGhhdCBjbGFzcy4KICAgICAqLwogICAgTWFwPENsYXNzU3ltYm9sLExpc3Q8VmFyU3ltYm9sPj4gZnJlZXZhckNhY2hlOwoKICAgIC8qKiBBIG5hdmlnYXRvciBjbGFzcyBmb3IgY29sbGVjdGluZyB0aGUgZnJlZSB2YXJpYWJsZXMgYWNjZXNzZWQKICAgICAqICBmcm9tIGEgbG9jYWwgY2xhc3MuIFRoZXJlIGlzIG9ubHkgb25lIGNhc2U7IGFsbCBvdGhlciBjYXNlcyBzaW1wbHkKICAgICAqICB0cmF2ZXJzZSBkb3duIHRoZSB0cmVlLiBUaGlzIGNsYXNzIGRvZXNuJ3QgZGVhbCB3aXRoIHRoZSBzcGVjaWZpYwogICAgICogIG9mIExvd2VyIC0gaXQncyBhbiBhYnN0cmFjdCB2aXNpdG9yIHRoYXQgaXMgbWVhbnQgdG8gYmUgcmV1c2VkIGluCiAgICAgKiAgb3JkZXIgdG8gc2hhcmUgdGhlIGxvY2FsIHZhcmlhYmxlIGNhcHR1cmUgbG9naWMuCiAgICAgKi8KICAgIGFic3RyYWN0IGNsYXNzIEJhc2ljRnJlZVZhckNvbGxlY3RvciBleHRlbmRzIFRyZWVTY2FubmVyIHsKCiAgICAgICAgLyoqIEFkZCBhbGwgZnJlZSB2YXJpYWJsZXMgb2YgY2xhc3MgYyB0byBmdnMgbGlzdAogICAgICAgICAqICB1bmxlc3MgdGhleSBhcmUgYWxyZWFkeSB0aGVyZS4KICAgICAgICAgKi8KICAgICAgICBhYnN0cmFjdCB2b2lkIGFkZEZyZWVWYXJzKENsYXNzU3ltYm9sIGMpOwoKICAgICAgICAvKiogSWYgdHJlZSByZWZlcnMgdG8gYSB2YXJpYWJsZSBpbiBvd25lciBvZiBsb2NhbCBjbGFzcywgYWRkIGl0IHRvCiAgICAgICAgICogIGZyZWUgdmFyaWFibGVzIGxpc3QuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRJZGVudChKQ0lkZW50IHRyZWUpIHsKICAgICAgICAgICAgdmlzaXRTeW1ib2wodHJlZS5zeW0pOwogICAgICAgIH0KICAgICAgICAvLyB3aGVyZQogICAgICAgIGFic3RyYWN0IHZvaWQgdmlzaXRTeW1ib2woU3ltYm9sIF9zeW0pOwoKICAgICAgICAvKiogSWYgdHJlZSByZWZlcnMgdG8gYSBjbGFzcyBpbnN0YW5jZSBjcmVhdGlvbiBleHByZXNzaW9uCiAgICAgICAgICogIGFkZCBhbGwgZnJlZSB2YXJpYWJsZXMgb2YgdGhlIGZyZXNobHkgY3JlYXRlZCBjbGFzcy4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdE5ld0NsYXNzKEpDTmV3Q2xhc3MgdHJlZSkgewogICAgICAgICAgICBDbGFzc1N5bWJvbCBjID0gKENsYXNzU3ltYm9sKXRyZWUuY29uc3RydWN0b3Iub3duZXI7CiAgICAgICAgICAgIGFkZEZyZWVWYXJzKGMpOwogICAgICAgICAgICBzdXBlci52aXNpdE5ld0NsYXNzKHRyZWUpOwogICAgICAgIH0KCiAgICAgICAgLyoqIElmIHRyZWUgcmVmZXJzIHRvIGEgc3VwZXJjbGFzcyBjb25zdHJ1Y3RvciBjYWxsLAogICAgICAgICAqICBhZGQgYWxsIGZyZWUgdmFyaWFibGVzIG9mIHRoZSBzdXBlcmNsYXNzLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0QXBwbHkoSkNNZXRob2RJbnZvY2F0aW9uIHRyZWUpIHsKICAgICAgICAgICAgaWYgKFRyZWVJbmZvLm5hbWUodHJlZS5tZXRoKSA9PSBuYW1lcy5fc3VwZXIpIHsKICAgICAgICAgICAgICAgIGFkZEZyZWVWYXJzKChDbGFzc1N5bWJvbCkgVHJlZUluZm8uc3ltYm9sKHRyZWUubWV0aCkub3duZXIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHN1cGVyLnZpc2l0QXBwbHkodHJlZSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogTG93ZXItc3BlY2lmaWMgc3ViY2xhc3Mgb2Yge0Bjb2RlIEJhc2ljRnJlZVZhckNvbGxlY3Rvcn0uCiAgICAgKi8KICAgIGNsYXNzIEZyZWVWYXJDb2xsZWN0b3IgZXh0ZW5kcyBCYXNpY0ZyZWVWYXJDb2xsZWN0b3IgewoKICAgICAgICAvKiogVGhlIG93bmVyIG9mIHRoZSBsb2NhbCBjbGFzcy4KICAgICAgICAgKi8KICAgICAgICBTeW1ib2wgb3duZXI7CgogICAgICAgIC8qKiBUaGUgbG9jYWwgY2xhc3MuCiAgICAgICAgICovCiAgICAgICAgQ2xhc3NTeW1ib2wgY2xheno7CgogICAgICAgIC8qKiBUaGUgbGlzdCBvZiBvd25lcidzIHZhcmlhYmxlcyBhY2Nlc3NlZCBmcm9tIHdpdGhpbiB0aGUgbG9jYWwgY2xhc3MsCiAgICAgICAgICogIHdpdGhvdXQgYW55IGR1cGxpY2F0ZXMuCiAgICAgICAgICovCiAgICAgICAgTGlzdDxWYXJTeW1ib2w+IGZ2czsKCiAgICAgICAgRnJlZVZhckNvbGxlY3RvcihDbGFzc1N5bWJvbCBjbGF6eikgewogICAgICAgICAgICB0aGlzLmNsYXp6ID0gY2xheno7CiAgICAgICAgICAgIHRoaXMub3duZXIgPSBjbGF6ei5vd25lcjsKICAgICAgICAgICAgdGhpcy5mdnMgPSBMaXN0Lm5pbCgpOwogICAgICAgIH0KCiAgICAgICAgLyoqIEFkZCBmcmVlIHZhcmlhYmxlIHRvIGZ2cyBsaXN0IHVubGVzcyBpdCBpcyBhbHJlYWR5IHRoZXJlLgogICAgICAgICAqLwogICAgICAgIHByaXZhdGUgdm9pZCBhZGRGcmVlVmFyKFZhclN5bWJvbCB2KSB7CiAgICAgICAgICAgIGZvciAoTGlzdDxWYXJTeW1ib2w+IGwgPSBmdnM7IGwubm9uRW1wdHkoKTsgbCA9IGwudGFpbCkKICAgICAgICAgICAgICAgIGlmIChsLmhlYWQgPT0gdikgcmV0dXJuOwogICAgICAgICAgICBmdnMgPSBmdnMucHJlcGVuZCh2KTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHZvaWQgYWRkRnJlZVZhcnMoQ2xhc3NTeW1ib2wgYykgewogICAgICAgICAgICBMaXN0PFZhclN5bWJvbD4gZnZzID0gZnJlZXZhckNhY2hlLmdldChjKTsKICAgICAgICAgICAgaWYgKGZ2cyAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICBmb3IgKExpc3Q8VmFyU3ltYm9sPiBsID0gZnZzOyBsLm5vbkVtcHR5KCk7IGwgPSBsLnRhaWwpIHsKICAgICAgICAgICAgICAgICAgICBhZGRGcmVlVmFyKGwuaGVhZCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHZvaWQgdmlzaXRTeW1ib2woU3ltYm9sIF9zeW0pIHsKICAgICAgICAgICAgU3ltYm9sIHN5bSA9IF9zeW07CiAgICAgICAgICAgIGlmIChzeW0ua2luZCA9PSBWQVIgfHwgc3ltLmtpbmQgPT0gTVRIKSB7CiAgICAgICAgICAgICAgICB3aGlsZSAoc3ltICE9IG51bGwgJiYgc3ltLm93bmVyICE9IG93bmVyKQogICAgICAgICAgICAgICAgICAgIHN5bSA9IHByb3hpZXMuZmluZEZpcnN0KHByb3h5TmFtZShzeW0ubmFtZSkpOwogICAgICAgICAgICAgICAgaWYgKHN5bSAhPSBudWxsICYmIHN5bS5vd25lciA9PSBvd25lcikgewogICAgICAgICAgICAgICAgICAgIFZhclN5bWJvbCB2ID0gKFZhclN5bWJvbClzeW07CiAgICAgICAgICAgICAgICAgICAgaWYgKHYuZ2V0Q29uc3RWYWx1ZSgpID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgYWRkRnJlZVZhcih2KTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGlmIChvdXRlclRoaXNTdGFjay5oZWFkICE9IG51bGwgJiYKICAgICAgICAgICAgICAgICAgICAgICAgb3V0ZXJUaGlzU3RhY2suaGVhZCAhPSBfc3ltKQogICAgICAgICAgICAgICAgICAgICAgICB2aXNpdFN5bWJvbChvdXRlclRoaXNTdGFjay5oZWFkKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLyoqIElmIHRyZWUgcmVmZXJzIHRvIGEgY2xhc3MgaW5zdGFuY2UgY3JlYXRpb24gZXhwcmVzc2lvbgogICAgICAgICAqICBhZGQgYWxsIGZyZWUgdmFyaWFibGVzIG9mIHRoZSBmcmVzaGx5IGNyZWF0ZWQgY2xhc3MuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXROZXdDbGFzcyhKQ05ld0NsYXNzIHRyZWUpIHsKICAgICAgICAgICAgQ2xhc3NTeW1ib2wgYyA9IChDbGFzc1N5bWJvbCl0cmVlLmNvbnN0cnVjdG9yLm93bmVyOwogICAgICAgICAgICBpZiAodHJlZS5lbmNsID09IG51bGwgJiYKICAgICAgICAgICAgICAgIGMuaGFzT3V0ZXJJbnN0YW5jZSgpICYmCiAgICAgICAgICAgICAgICBvdXRlclRoaXNTdGFjay5oZWFkICE9IG51bGwpCiAgICAgICAgICAgICAgICB2aXNpdFN5bWJvbChvdXRlclRoaXNTdGFjay5oZWFkKTsKICAgICAgICAgICAgc3VwZXIudmlzaXROZXdDbGFzcyh0cmVlKTsKICAgICAgICB9CgogICAgICAgIC8qKiBJZiB0cmVlIHJlZmVycyB0byBhIHF1YWxpZmllZCB0aGlzIG9yIHN1cGVyIGV4cHJlc3Npb24KICAgICAgICAgKiAgZm9yIGFueXRoaW5nIGJ1dCB0aGUgY3VycmVudCBjbGFzcywgYWRkIHRoZSBvdXRlciB0aGlzCiAgICAgICAgICogIHN0YWNrIGFzIGEgZnJlZSB2YXJpYWJsZS4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdFNlbGVjdChKQ0ZpZWxkQWNjZXNzIHRyZWUpIHsKICAgICAgICAgICAgaWYgKCh0cmVlLm5hbWUgPT0gbmFtZXMuX3RoaXMgfHwgdHJlZS5uYW1lID09IG5hbWVzLl9zdXBlcikgJiYKICAgICAgICAgICAgICAgIHRyZWUuc2VsZWN0ZWQudHlwZS50c3ltICE9IGNsYXp6ICYmCiAgICAgICAgICAgICAgICBvdXRlclRoaXNTdGFjay5oZWFkICE9IG51bGwpCiAgICAgICAgICAgICAgICB2aXNpdFN5bWJvbChvdXRlclRoaXNTdGFjay5oZWFkKTsKICAgICAgICAgICAgc3VwZXIudmlzaXRTZWxlY3QodHJlZSk7CiAgICAgICAgfQoKICAgICAgICAvKiogSWYgdHJlZSByZWZlcnMgdG8gYSBzdXBlcmNsYXNzIGNvbnN0cnVjdG9yIGNhbGwsCiAgICAgICAgICogIGFkZCBhbGwgZnJlZSB2YXJpYWJsZXMgb2YgdGhlIHN1cGVyY2xhc3MuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRBcHBseShKQ01ldGhvZEludm9jYXRpb24gdHJlZSkgewogICAgICAgICAgICBpZiAoVHJlZUluZm8ubmFtZSh0cmVlLm1ldGgpID09IG5hbWVzLl9zdXBlcikgewogICAgICAgICAgICAgICAgU3ltYm9sIGNvbnN0cnVjdG9yID0gVHJlZUluZm8uc3ltYm9sKHRyZWUubWV0aCk7CiAgICAgICAgICAgICAgICBDbGFzc1N5bWJvbCBjID0gKENsYXNzU3ltYm9sKWNvbnN0cnVjdG9yLm93bmVyOwogICAgICAgICAgICAgICAgaWYgKGMuaGFzT3V0ZXJJbnN0YW5jZSgpICYmCiAgICAgICAgICAgICAgICAgICAgIXRyZWUubWV0aC5oYXNUYWcoU0VMRUNUKSAmJgogICAgICAgICAgICAgICAgICAgIG91dGVyVGhpc1N0YWNrLmhlYWQgIT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICB2aXNpdFN5bWJvbChvdXRlclRoaXNTdGFjay5oZWFkKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBzdXBlci52aXNpdEFwcGx5KHRyZWUpOwogICAgICAgIH0KICAgIH0KCiAgICBDbGFzc1N5bWJvbCBvd25lclRvQ29weUZyZWVWYXJzRnJvbShDbGFzc1N5bWJvbCBjKSB7CiAgICAgICAgaWYgKCFjLmlzTG9jYWwoKSkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICAgICAgU3ltYm9sIGN1cnJlbnRPd25lciA9IGMub3duZXI7CiAgICAgICAgd2hpbGUgKGN1cnJlbnRPd25lci5vd25lci5raW5kLm1hdGNoZXMoS2luZFNlbGVjdG9yLlRZUCkgJiYgY3VycmVudE93bmVyLmlzTG9jYWwoKSkgewogICAgICAgICAgICBjdXJyZW50T3duZXIgPSBjdXJyZW50T3duZXIub3duZXI7CiAgICAgICAgfQogICAgICAgIGlmIChjdXJyZW50T3duZXIub3duZXIua2luZC5tYXRjaGVzKEtpbmRTZWxlY3Rvci5WQUxfTVRIKSAmJiBjLmlzU3ViQ2xhc3MoY3VycmVudE93bmVyLCB0eXBlcykpIHsKICAgICAgICAgICAgcmV0dXJuIChDbGFzc1N5bWJvbCljdXJyZW50T3duZXI7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIC8qKiBSZXR1cm4gdGhlIHZhcmlhYmxlcyBhY2Nlc3NlZCBmcm9tIHdpdGhpbiBhIGxvY2FsIGNsYXNzLCB3aGljaAogICAgICogIGFyZSBkZWNsYXJlZCBpbiB0aGUgbG9jYWwgY2xhc3MnIG93bmVyLgogICAgICogIChpbiByZXZlcnNlIG9yZGVyIG9mIGZpcnN0IGFjY2VzcykuCiAgICAgKi8KICAgIExpc3Q8VmFyU3ltYm9sPiBmcmVldmFycyhDbGFzc1N5bWJvbCBjKSAgewogICAgICAgIExpc3Q8VmFyU3ltYm9sPiBmdnMgPSBmcmVldmFyQ2FjaGUuZ2V0KGMpOwogICAgICAgIGlmIChmdnMgIT0gbnVsbCkgewogICAgICAgICAgICByZXR1cm4gZnZzOwogICAgICAgIH0KICAgICAgICBpZiAoYy5vd25lci5raW5kLm1hdGNoZXMoS2luZFNlbGVjdG9yLlZBTF9NVEgpKSB7CiAgICAgICAgICAgIEZyZWVWYXJDb2xsZWN0b3IgY29sbGVjdG9yID0gbmV3IEZyZWVWYXJDb2xsZWN0b3IoYyk7CiAgICAgICAgICAgIGNvbGxlY3Rvci5zY2FuKGNsYXNzRGVmKGMpKTsKICAgICAgICAgICAgZnZzID0gY29sbGVjdG9yLmZ2czsKICAgICAgICAgICAgZnJlZXZhckNhY2hlLnB1dChjLCBmdnMpOwogICAgICAgICAgICByZXR1cm4gZnZzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIENsYXNzU3ltYm9sIG93bmVyID0gb3duZXJUb0NvcHlGcmVlVmFyc0Zyb20oYyk7CiAgICAgICAgICAgIGlmIChvd25lciAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICBmdnMgPSBmcmVldmFyQ2FjaGUuZ2V0KG93bmVyKTsKICAgICAgICAgICAgICAgIGZyZWV2YXJDYWNoZS5wdXQoYywgZnZzKTsKICAgICAgICAgICAgICAgIHJldHVybiBmdnM7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICByZXR1cm4gTGlzdC5uaWwoKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBNYXA8VHlwZVN5bWJvbCxFbnVtTWFwcGluZz4gZW51bVN3aXRjaE1hcCA9IG5ldyBMaW5rZWRIYXNoTWFwPD4oKTsKCiAgICBFbnVtTWFwcGluZyBtYXBGb3JFbnVtKERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIFR5cGVTeW1ib2wgZW51bUNsYXNzKSB7CiAgICAgICAgRW51bU1hcHBpbmcgbWFwID0gZW51bVN3aXRjaE1hcC5nZXQoZW51bUNsYXNzKTsKICAgICAgICBpZiAobWFwID09IG51bGwpCiAgICAgICAgICAgIGVudW1Td2l0Y2hNYXAucHV0KGVudW1DbGFzcywgbWFwID0gbmV3IEVudW1NYXBwaW5nKHBvcywgZW51bUNsYXNzKSk7CiAgICAgICAgcmV0dXJuIG1hcDsKICAgIH0KCiAgICAvKiogVGhpcyBtYXAgZ2l2ZXMgYSB0cmFuc2xhdGlvbiB0YWJsZSB0byBiZSB1c2VkIGZvciBlbnVtCiAgICAgKiAgc3dpdGNoZXMuCiAgICAgKgogICAgICogIDxwPkZvciBlYWNoIGVudW0gdGhhdCBhcHBlYXJzIGFzIHRoZSB0eXBlIG9mIGEgc3dpdGNoCiAgICAgKiAgZXhwcmVzc2lvbiwgd2UgbWFpbnRhaW4gYW4gRW51bU1hcHBpbmcgdG8gYXNzaXN0IGluIHRoZQogICAgICogIHRyYW5zbGF0aW9uLCBhcyBleGVtcGxpZmllZCBieSB0aGUgZm9sbG93aW5nIGV4YW1wbGU6CiAgICAgKgogICAgICogIDxwPndlIHRyYW5zbGF0ZQogICAgICogIDxwcmU+CiAgICAgKiAgICAgICAgICBzd2l0Y2goY29sb3JFeHByZXNzaW9uKSB7CiAgICAgKiAgICAgICAgICBjYXNlIHJlZDogc3RtdDE7CiAgICAgKiAgICAgICAgICBjYXNlIGdyZWVuOiBzdG10MjsKICAgICAqICAgICAgICAgIH0KICAgICAqICA8L3ByZT4KICAgICAqICBpbnRvCiAgICAgKiAgPHByZT4KICAgICAqICAgICAgICAgIHN3aXRjaChPdXRlciQwLiRFbnVtTWFwJENvbG9yW2NvbG9yRXhwcmVzc2lvbi5vcmRpbmFsKCldKSB7CiAgICAgKiAgICAgICAgICBjYXNlIDE6IHN0bXQxOwogICAgICogICAgICAgICAgY2FzZSAyOiBzdG10MgogICAgICogICAgICAgICAgfQogICAgICogIDwvcHJlPgogICAgICogIHdpdGggdGhlIGF1eGlsaWFyeSB0YWJsZSBpbml0aWFsaXplZCBhcyBmb2xsb3dzOgogICAgICogIDxwcmU+CiAgICAgKiAgICAgICAgICBjbGFzcyBPdXRlciQwIHsKICAgICAqICAgICAgICAgICAgICBzeW50aGV0aWMgZmluYWwgaW50W10gJEVudW1NYXAkQ29sb3IgPSBuZXcgaW50W0NvbG9yLnZhbHVlcygpLmxlbmd0aF07CiAgICAgKiAgICAgICAgICAgICAgc3RhdGljIHsKICAgICAqICAgICAgICAgICAgICAgICAgdHJ5IHsgJEVudW1NYXAkQ29sb3JbcmVkLm9yZGluYWwoKV0gPSAxOyB9IGNhdGNoIChOb1N1Y2hGaWVsZEVycm9yIGV4KSB7fQogICAgICogICAgICAgICAgICAgICAgICB0cnkgeyAkRW51bU1hcCRDb2xvcltncmVlbi5vcmRpbmFsKCldID0gMjsgfSBjYXRjaCAoTm9TdWNoRmllbGRFcnJvciBleCkge30KICAgICAqICAgICAgICAgICAgICB9CiAgICAgKiAgICAgICAgICB9CiAgICAgKiAgPC9wcmU+CiAgICAgKiAgY2xhc3MgRW51bU1hcHBpbmcgcHJvdmlkZXMgbWFwcGluZyBkYXRhIGFuZCBzdXBwb3J0IG1ldGhvZHMgZm9yIHRoaXMgdHJhbnNsYXRpb24uCiAgICAgKi8KICAgIGNsYXNzIEVudW1NYXBwaW5nIHsKICAgICAgICBFbnVtTWFwcGluZyhEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBUeXBlU3ltYm9sIGZvckVudW0pIHsKICAgICAgICAgICAgdGhpcy5mb3JFbnVtID0gZm9yRW51bTsKICAgICAgICAgICAgdGhpcy52YWx1ZXMgPSBuZXcgTGlua2VkSGFzaE1hcDw+KCk7CiAgICAgICAgICAgIHRoaXMucG9zID0gcG9zOwogICAgICAgICAgICBOYW1lIHZhck5hbWUgPSBuYW1lcwogICAgICAgICAgICAgICAgLmZyb21TdHJpbmcodGFyZ2V0LnN5bnRoZXRpY05hbWVDaGFyKCkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgIlN3aXRjaE1hcCIgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0LnN5bnRoZXRpY05hbWVDaGFyKCkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGVyLnhDbGFzc05hbWUoZm9yRW51bS50eXBlKS50b1N0cmluZygpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAucmVwbGFjZSgnLycsICcuJykKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5yZXBsYWNlKCcuJywgdGFyZ2V0LnN5bnRoZXRpY05hbWVDaGFyKCkpKTsKICAgICAgICAgICAgQ2xhc3NTeW1ib2wgb3V0ZXJDYWNoZUNsYXNzID0gb3V0ZXJDYWNoZUNsYXNzKCk7CiAgICAgICAgICAgIHRoaXMubWFwVmFyID0gbmV3IFZhclN5bWJvbChTVEFUSUMgfCBTWU5USEVUSUMgfCBGSU5BTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhck5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgQXJyYXlUeXBlKHN5bXMuaW50VHlwZSwgc3ltcy5hcnJheUNsYXNzKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG91dGVyQ2FjaGVDbGFzcyk7CiAgICAgICAgICAgIGVudGVyU3ludGhldGljKHBvcywgbWFwVmFyLCBvdXRlckNhY2hlQ2xhc3MubWVtYmVycygpKTsKICAgICAgICB9CgogICAgICAgIERpYWdub3N0aWNQb3NpdGlvbiBwb3MgPSBudWxsOwoKICAgICAgICAvLyB0aGUgbmV4dCB2YWx1ZSB0byB1c2UKICAgICAgICBpbnQgbmV4dCA9IDE7IC8vIDAgKHVudXNlZCBtYXAgZWxlbWVudHMpIGdvIHRvIHRoZSBkZWZhdWx0IGxhYmVsCgogICAgICAgIC8vIHRoZSBlbnVtIGZvciB3aGljaCB0aGlzIGlzIGEgbWFwCiAgICAgICAgZmluYWwgVHlwZVN5bWJvbCBmb3JFbnVtOwoKICAgICAgICAvLyB0aGUgZmllbGQgY29udGFpbmluZyB0aGUgbWFwCiAgICAgICAgZmluYWwgVmFyU3ltYm9sIG1hcFZhcjsKCiAgICAgICAgLy8gdGhlIG1hcHBlZCB2YWx1ZXMKICAgICAgICBmaW5hbCBNYXA8VmFyU3ltYm9sLEludGVnZXI+IHZhbHVlczsKCiAgICAgICAgSkNMaXRlcmFsIGZvckNvbnN0YW50KFZhclN5bWJvbCB2KSB7CiAgICAgICAgICAgIEludGVnZXIgcmVzdWx0ID0gdmFsdWVzLmdldCh2KTsKICAgICAgICAgICAgaWYgKHJlc3VsdCA9PSBudWxsKQogICAgICAgICAgICAgICAgdmFsdWVzLnB1dCh2LCByZXN1bHQgPSBuZXh0KyspOwogICAgICAgICAgICByZXR1cm4gbWFrZS5MaXRlcmFsKHJlc3VsdCk7CiAgICAgICAgfQoKICAgICAgICAvLyBnZW5lcmF0ZSB0aGUgZmllbGQgaW5pdGlhbGl6ZXIgZm9yIHRoZSBtYXAKICAgICAgICB2b2lkIHRyYW5zbGF0ZSgpIHsKICAgICAgICAgICAgbWFrZS5hdChwb3MuZ2V0U3RhcnRQb3NpdGlvbigpKTsKICAgICAgICAgICAgSkNDbGFzc0RlY2wgb3duZXIgPSBjbGFzc0RlZigoQ2xhc3NTeW1ib2wpbWFwVmFyLm93bmVyKTsKCiAgICAgICAgICAgIC8vIHN5bnRoZXRpYyBzdGF0aWMgZmluYWwgaW50W10gJFN3aXRjaE1hcCRDb2xvciA9IG5ldyBpbnRbQ29sb3IudmFsdWVzKCkubGVuZ3RoXTsKICAgICAgICAgICAgTWV0aG9kU3ltYm9sIHZhbHVlc01ldGhvZCA9IGxvb2t1cE1ldGhvZChwb3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZXMudmFsdWVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvckVudW0udHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0Lm5pbCgpKTsKICAgICAgICAgICAgSkNFeHByZXNzaW9uIHNpemUgPSBtYWtlIC8vIENvbG9yLnZhbHVlcygpLmxlbmd0aAogICAgICAgICAgICAgICAgLlNlbGVjdChtYWtlLkFwcChtYWtlLlF1YWxJZGVudCh2YWx1ZXNNZXRob2QpKSwKICAgICAgICAgICAgICAgICAgICAgICAgc3ltcy5sZW5ndGhWYXIpOwogICAgICAgICAgICBKQ0V4cHJlc3Npb24gbWFwVmFySW5pdCA9IG1ha2UKICAgICAgICAgICAgICAgIC5OZXdBcnJheShtYWtlLlR5cGUoc3ltcy5pbnRUeXBlKSwgTGlzdC5vZihzaXplKSwgbnVsbCkKICAgICAgICAgICAgICAgIC5zZXRUeXBlKG5ldyBBcnJheVR5cGUoc3ltcy5pbnRUeXBlLCBzeW1zLmFycmF5Q2xhc3MpKTsKCiAgICAgICAgICAgIC8vIHRyeSB7ICRTd2l0Y2hNYXAkQ29sb3JbcmVkLm9yZGluYWwoKV0gPSAxOyB9IGNhdGNoIChqYXZhLmxhbmcuTm9TdWNoRmllbGRFcnJvciBleCkge30KICAgICAgICAgICAgTGlzdEJ1ZmZlcjxKQ1N0YXRlbWVudD4gc3RtdHMgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgIFN5bWJvbCBvcmRpbmFsTWV0aG9kID0gbG9va3VwTWV0aG9kKHBvcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZXMub3JkaW5hbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yRW51bS50eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0Lm5pbCgpKTsKICAgICAgICAgICAgTGlzdDxKQ0NhdGNoPiBjYXRjaGVyID0gTGlzdC48SkNDYXRjaD5uaWwoKQogICAgICAgICAgICAgICAgLnByZXBlbmQobWFrZS5DYXRjaChtYWtlLlZhckRlZihuZXcgVmFyU3ltYm9sKFBBUkFNRVRFUiwgbmFtZXMuZXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ltcy5ub1N1Y2hGaWVsZEVycm9yVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeW1zLm5vU3ltYm9sKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ha2UuQmxvY2soMCwgTGlzdC5uaWwoKSkpKTsKICAgICAgICAgICAgZm9yIChNYXAuRW50cnk8VmFyU3ltYm9sLEludGVnZXI+IGUgOiB2YWx1ZXMuZW50cnlTZXQoKSkgewogICAgICAgICAgICAgICAgVmFyU3ltYm9sIGVudW1lcmF0b3IgPSBlLmdldEtleSgpOwogICAgICAgICAgICAgICAgSW50ZWdlciBtYXBwZWRWYWx1ZSA9IGUuZ2V0VmFsdWUoKTsKICAgICAgICAgICAgICAgIEpDRXhwcmVzc2lvbiBhc3NpZ24gPSBtYWtlCiAgICAgICAgICAgICAgICAgICAgLkFzc2lnbihtYWtlLkluZGV4ZWQobWFwVmFyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ha2UuQXBwKG1ha2UuU2VsZWN0KG1ha2UuUXVhbElkZW50KGVudW1lcmF0b3IpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yZGluYWxNZXRob2QpKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYWtlLkxpdGVyYWwobWFwcGVkVmFsdWUpKQogICAgICAgICAgICAgICAgICAgIC5zZXRUeXBlKHN5bXMuaW50VHlwZSk7CiAgICAgICAgICAgICAgICBKQ1N0YXRlbWVudCBleGVjID0gbWFrZS5FeGVjKGFzc2lnbik7CiAgICAgICAgICAgICAgICBKQ1N0YXRlbWVudCBfdHJ5ID0gbWFrZS5UcnkobWFrZS5CbG9jaygwLCBMaXN0Lm9mKGV4ZWMpKSwgY2F0Y2hlciwgbnVsbCk7CiAgICAgICAgICAgICAgICBzdG10cy5hcHBlbmQoX3RyeSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIG93bmVyLmRlZnMgPSBvd25lci5kZWZzCiAgICAgICAgICAgICAgICAucHJlcGVuZChtYWtlLkJsb2NrKFNUQVRJQywgc3RtdHMudG9MaXN0KCkpKQogICAgICAgICAgICAgICAgLnByZXBlbmQobWFrZS5WYXJEZWYobWFwVmFyLCBtYXBWYXJJbml0KSk7CiAgICAgICAgfQogICAgfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBUcmVlIGJ1aWxkaW5nIGJsb2NrcwogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiAgICAvKiogRXF1aXZhbGVudCB0byBtYWtlLmF0KHBvcy5nZXRTdGFydFBvc2l0aW9uKCkpIHdpdGggc2lkZSBlZmZlY3Qgb2YgY2FjaGluZwogICAgICogIHBvcyBhcyBtYWtlX3BvcywgZm9yIHVzZSBpbiBkaWFnbm9zdGljcy4KICAgICAqKi8KICAgIFRyZWVNYWtlciBtYWtlX2F0KERpYWdub3N0aWNQb3NpdGlvbiBwb3MpIHsKICAgICAgICBtYWtlX3BvcyA9IHBvczsKICAgICAgICByZXR1cm4gbWFrZS5hdChwb3MpOwogICAgfQoKICAgIC8qKiBNYWtlIGFuIGF0dHJpYnV0ZWQgdHJlZSByZXByZXNlbnRpbmcgYSBsaXRlcmFsLiBUaGlzIHdpbGwgYmUgYW4KICAgICAqICBJZGVudCBub2RlIGluIHRoZSBjYXNlIG9mIGJvb2xlYW4gbGl0ZXJhbHMsIGEgTGl0ZXJhbCBub2RlIGluIGFsbAogICAgICogIG90aGVyIGNhc2VzLgogICAgICogIEBwYXJhbSB0eXBlICAgICAgIFRoZSBsaXRlcmFsJ3MgdHlwZS4KICAgICAqICBAcGFyYW0gdmFsdWUgICAgICBUaGUgbGl0ZXJhbCdzIHZhbHVlLgogICAgICovCiAgICBKQ0V4cHJlc3Npb24gbWFrZUxpdChUeXBlIHR5cGUsIE9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBtYWtlLkxpdGVyYWwodHlwZS5nZXRUYWcoKSwgdmFsdWUpLnNldFR5cGUodHlwZS5jb25zdFR5cGUodmFsdWUpKTsKICAgIH0KCiAgICAvKiogTWFrZSBhbiBhdHRyaWJ1dGVkIHRyZWUgcmVwcmVzZW50aW5nIG51bGwuCiAgICAgKi8KICAgIEpDRXhwcmVzc2lvbiBtYWtlTnVsbCgpIHsKICAgICAgICByZXR1cm4gbWFrZUxpdChzeW1zLmJvdFR5cGUsIG51bGwpOwogICAgfQoKICAgIC8qKiBNYWtlIGFuIGF0dHJpYnV0ZWQgY2xhc3MgaW5zdGFuY2UgY3JlYXRpb24gZXhwcmVzc2lvbi4KICAgICAqICBAcGFyYW0gY3R5cGUgICAgVGhlIGNsYXNzIHR5cGUuCiAgICAgKiAgQHBhcmFtIGFyZ3MgICAgIFRoZSBjb25zdHJ1Y3RvciBhcmd1bWVudHMuCiAgICAgKi8KICAgIEpDTmV3Q2xhc3MgbWFrZU5ld0NsYXNzKFR5cGUgY3R5cGUsIExpc3Q8SkNFeHByZXNzaW9uPiBhcmdzKSB7CiAgICAgICAgSkNOZXdDbGFzcyB0cmVlID0gbWFrZS5OZXdDbGFzcyhudWxsLAogICAgICAgICAgICBudWxsLCBtYWtlLlF1YWxJZGVudChjdHlwZS50c3ltKSwgYXJncywgbnVsbCk7CiAgICAgICAgdHJlZS5jb25zdHJ1Y3RvciA9IHJzLnJlc29sdmVDb25zdHJ1Y3RvcigKICAgICAgICAgICAgbWFrZV9wb3MsIGF0dHJFbnYsIGN0eXBlLCBUcmVlSW5mby50eXBlcyhhcmdzKSwgTGlzdC5uaWwoKSk7CiAgICAgICAgdHJlZS50eXBlID0gY3R5cGU7CiAgICAgICAgcmV0dXJuIHRyZWU7CiAgICB9CgogICAgLyoqIE1ha2UgYW4gYXR0cmlidXRlZCB1bmFyeSBleHByZXNzaW9uLgogICAgICogIEBwYXJhbSBvcHRhZyAgICBUaGUgb3BlcmF0b3JzIHRyZWUgdGFnLgogICAgICogIEBwYXJhbSBhcmcgICAgICBUaGUgb3BlcmF0b3IncyBhcmd1bWVudC4KICAgICAqLwogICAgSkNVbmFyeSBtYWtlVW5hcnkoSkNUcmVlLlRhZyBvcHRhZywgSkNFeHByZXNzaW9uIGFyZykgewogICAgICAgIEpDVW5hcnkgdHJlZSA9IG1ha2UuVW5hcnkob3B0YWcsIGFyZyk7CiAgICAgICAgdHJlZS5vcGVyYXRvciA9IG9wZXJhdG9ycy5yZXNvbHZlVW5hcnkodHJlZSwgb3B0YWcsIGFyZy50eXBlKTsKICAgICAgICB0cmVlLnR5cGUgPSB0cmVlLm9wZXJhdG9yLnR5cGUuZ2V0UmV0dXJuVHlwZSgpOwogICAgICAgIHJldHVybiB0cmVlOwogICAgfQoKICAgIC8qKiBNYWtlIGFuIGF0dHJpYnV0ZWQgYmluYXJ5IGV4cHJlc3Npb24uCiAgICAgKiAgQHBhcmFtIG9wdGFnICAgIFRoZSBvcGVyYXRvcnMgdHJlZSB0YWcuCiAgICAgKiAgQHBhcmFtIGxocyAgICAgIFRoZSBvcGVyYXRvcidzIGxlZnQgYXJndW1lbnQuCiAgICAgKiAgQHBhcmFtIHJocyAgICAgIFRoZSBvcGVyYXRvcidzIHJpZ2h0IGFyZ3VtZW50LgogICAgICovCiAgICBKQ0JpbmFyeSBtYWtlQmluYXJ5KEpDVHJlZS5UYWcgb3B0YWcsIEpDRXhwcmVzc2lvbiBsaHMsIEpDRXhwcmVzc2lvbiByaHMpIHsKICAgICAgICBKQ0JpbmFyeSB0cmVlID0gbWFrZS5CaW5hcnkob3B0YWcsIGxocywgcmhzKTsKICAgICAgICB0cmVlLm9wZXJhdG9yID0gb3BlcmF0b3JzLnJlc29sdmVCaW5hcnkodHJlZSwgb3B0YWcsIGxocy50eXBlLCByaHMudHlwZSk7CiAgICAgICAgdHJlZS50eXBlID0gdHJlZS5vcGVyYXRvci50eXBlLmdldFJldHVyblR5cGUoKTsKICAgICAgICByZXR1cm4gdHJlZTsKICAgIH0KCiAgICAvKiogTWFrZSBhbiBhdHRyaWJ1dGVkIGFzc2lnbm9wIGV4cHJlc3Npb24uCiAgICAgKiAgQHBhcmFtIG9wdGFnICAgIFRoZSBvcGVyYXRvcnMgdHJlZSB0YWcuCiAgICAgKiAgQHBhcmFtIGxocyAgICAgIFRoZSBvcGVyYXRvcidzIGxlZnQgYXJndW1lbnQuCiAgICAgKiAgQHBhcmFtIHJocyAgICAgIFRoZSBvcGVyYXRvcidzIHJpZ2h0IGFyZ3VtZW50LgogICAgICovCiAgICBKQ0Fzc2lnbk9wIG1ha2VBc3NpZ25vcChKQ1RyZWUuVGFnIG9wdGFnLCBKQ1RyZWUgbGhzLCBKQ1RyZWUgcmhzKSB7CiAgICAgICAgSkNBc3NpZ25PcCB0cmVlID0gbWFrZS5Bc3NpZ25vcChvcHRhZywgbGhzLCByaHMpOwogICAgICAgIHRyZWUub3BlcmF0b3IgPSBvcGVyYXRvcnMucmVzb2x2ZUJpbmFyeSh0cmVlLCB0cmVlLmdldFRhZygpLm5vQXNzaWduT3AoKSwgbGhzLnR5cGUsIHJocy50eXBlKTsKICAgICAgICB0cmVlLnR5cGUgPSBsaHMudHlwZTsKICAgICAgICByZXR1cm4gdHJlZTsKICAgIH0KCiAgICAvKiogQ29udmVydCB0cmVlIGludG8gc3RyaW5nIG9iamVjdCwgdW5sZXNzIGl0IGhhcyBhbHJlYWR5IGEKICAgICAqICByZWZlcmVuY2UgdHlwZS4uCiAgICAgKi8KICAgIEpDRXhwcmVzc2lvbiBtYWtlU3RyaW5nKEpDRXhwcmVzc2lvbiB0cmVlKSB7CiAgICAgICAgaWYgKCF0cmVlLnR5cGUuaXNQcmltaXRpdmVPclZvaWQoKSkgewogICAgICAgICAgICByZXR1cm4gdHJlZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBTeW1ib2wgdmFsdWVPZlN5bSA9IGxvb2t1cE1ldGhvZCh0cmVlLnBvcygpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lcy52YWx1ZU9mLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeW1zLnN0cmluZ1R5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExpc3Qub2YodHJlZS50eXBlKSk7CiAgICAgICAgICAgIHJldHVybiBtYWtlLkFwcChtYWtlLlF1YWxJZGVudCh2YWx1ZU9mU3ltKSwgTGlzdC5vZih0cmVlKSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKiBDcmVhdGUgYW4gZW1wdHkgYW5vbnltb3VzIGNsYXNzIGRlZmluaXRpb24gYW5kIGVudGVyIGFuZCBjb21wbGV0ZQogICAgICogIGl0cyBzeW1ib2wuIFJldHVybiB0aGUgY2xhc3MgZGVmaW5pdGlvbidzIHN5bWJvbC4KICAgICAqICBhbmQgY3JlYXRlCiAgICAgKiAgQHBhcmFtIGZsYWdzICAgIFRoZSBjbGFzcyBzeW1ib2wncyBmbGFncwogICAgICogIEBwYXJhbSBvd25lciAgICBUaGUgY2xhc3Mgc3ltYm9sJ3Mgb3duZXIKICAgICAqLwogICAgSkNDbGFzc0RlY2wgbWFrZUVtcHR5Q2xhc3MobG9uZyBmbGFncywgQ2xhc3NTeW1ib2wgb3duZXIpIHsKICAgICAgICByZXR1cm4gbWFrZUVtcHR5Q2xhc3MoZmxhZ3MsIG93bmVyLCBudWxsLCB0cnVlKTsKICAgIH0KCiAgICBKQ0NsYXNzRGVjbCBtYWtlRW1wdHlDbGFzcyhsb25nIGZsYWdzLCBDbGFzc1N5bWJvbCBvd25lciwgTmFtZSBmbGF0bmFtZSwKICAgICAgICAgICAgYm9vbGVhbiBhZGRUb0RlZnMpIHsKICAgICAgICAvLyBDcmVhdGUgY2xhc3Mgc3ltYm9sLgogICAgICAgIENsYXNzU3ltYm9sIGMgPSBzeW1zLmRlZmluZUNsYXNzKG5hbWVzLmVtcHR5LCBvd25lcik7CiAgICAgICAgaWYgKGZsYXRuYW1lICE9IG51bGwpIHsKICAgICAgICAgICAgYy5mbGF0bmFtZSA9IGZsYXRuYW1lOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGMuZmxhdG5hbWUgPSBjaGsubG9jYWxDbGFzc05hbWUoYyk7CiAgICAgICAgfQogICAgICAgIGMuc291cmNlZmlsZSA9IG93bmVyLnNvdXJjZWZpbGU7CiAgICAgICAgYy5jb21wbGV0ZXIgPSBDb21wbGV0ZXIuTlVMTF9DT01QTEVURVI7CiAgICAgICAgYy5tZW1iZXJzX2ZpZWxkID0gV3JpdGVhYmxlU2NvcGUuY3JlYXRlKGMpOwogICAgICAgIGMuZmxhZ3NfZmllbGQgPSBmbGFnczsKICAgICAgICBDbGFzc1R5cGUgY3R5cGUgPSAoQ2xhc3NUeXBlKSBjLnR5cGU7CiAgICAgICAgY3R5cGUuc3VwZXJ0eXBlX2ZpZWxkID0gc3ltcy5vYmplY3RUeXBlOwogICAgICAgIGN0eXBlLmludGVyZmFjZXNfZmllbGQgPSBMaXN0Lm5pbCgpOwoKICAgICAgICBKQ0NsYXNzRGVjbCBvZGVmID0gY2xhc3NEZWYob3duZXIpOwoKICAgICAgICAvLyBFbnRlciBjbGFzcyBzeW1ib2wgaW4gb3duZXIgc2NvcGUgYW5kIGNvbXBpbGVkIHRhYmxlLgogICAgICAgIGVudGVyU3ludGhldGljKG9kZWYucG9zKCksIGMsIG93bmVyLm1lbWJlcnMoKSk7CiAgICAgICAgY2hrLnB1dENvbXBpbGVkKGMpOwoKICAgICAgICAvLyBDcmVhdGUgY2xhc3MgZGVmaW5pdGlvbiB0cmVlLgogICAgICAgIEpDQ2xhc3NEZWNsIGNkZWYgPSBtYWtlLkNsYXNzRGVmKAogICAgICAgICAgICBtYWtlLk1vZGlmaWVycyhmbGFncyksIG5hbWVzLmVtcHR5LAogICAgICAgICAgICBMaXN0Lm5pbCgpLAogICAgICAgICAgICBudWxsLCBMaXN0Lm5pbCgpLCBMaXN0Lm5pbCgpKTsKICAgICAgICBjZGVmLnN5bSA9IGM7CiAgICAgICAgY2RlZi50eXBlID0gYy50eXBlOwoKICAgICAgICAvLyBBcHBlbmQgY2xhc3MgZGVmaW5pdGlvbiB0cmVlIHRvIG93bmVyJ3MgZGVmaW5pdGlvbnMuCiAgICAgICAgaWYgKGFkZFRvRGVmcykgb2RlZi5kZWZzID0gb2RlZi5kZWZzLnByZXBlbmQoY2RlZik7CiAgICAgICAgcmV0dXJuIGNkZWY7CiAgICB9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU3ltYm9sIG1hbmlwdWxhdGlvbiB1dGlsaXRpZXMKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgogICAgLyoqIEVudGVyIGEgc3ludGhldGljIHN5bWJvbCBpbiBhIGdpdmVuIHNjb3BlLCBidXQgY29tcGxhaW4gaWYgdGhlcmUgd2FzIGFscmVhZHkgb25lIHRoZXJlLgogICAgICogIEBwYXJhbSBwb3MgICAgICAgICAgIFBvc2l0aW9uIGZvciBlcnJvciByZXBvcnRpbmcuCiAgICAgKiAgQHBhcmFtIHN5bSAgICAgICAgICAgVGhlIHN5bWJvbC4KICAgICAqICBAcGFyYW0gcyAgICAgICAgICAgICBUaGUgc2NvcGUuCiAgICAgKi8KICAgIHByaXZhdGUgdm9pZCBlbnRlclN5bnRoZXRpYyhEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBTeW1ib2wgc3ltLCBXcml0ZWFibGVTY29wZSBzKSB7CiAgICAgICAgcy5lbnRlcihzeW0pOwogICAgfQoKICAgIC8qKiBDcmVhdGUgYSBmcmVzaCBzeW50aGV0aWMgbmFtZSB3aXRoaW4gYSBnaXZlbiBzY29wZSAtIHRoZSB1bmlxdWUgbmFtZSBpcwogICAgICogIG9idGFpbmVkIGJ5IGFwcGVuZGluZyAnJCcgY2hhcnMgYXQgdGhlIGVuZCBvZiB0aGUgbmFtZSB1bnRpbCBubyBtYXRjaAogICAgICogIGlzIGZvdW5kLgogICAgICoKICAgICAqIEBwYXJhbSBuYW1lIGJhc2UgbmFtZQogICAgICogQHBhcmFtIHMgc2NvcGUgaW4gd2hpY2ggdGhlIG5hbWUgaGFzIHRvIGJlIHVuaXF1ZQogICAgICogQHJldHVybiBmcmVzaCBzeW50aGV0aWMgbmFtZQogICAgICovCiAgICBwcml2YXRlIE5hbWUgbWFrZVN5bnRoZXRpY05hbWUoTmFtZSBuYW1lLCBTY29wZSBzKSB7CiAgICAgICAgZG8gewogICAgICAgICAgICBuYW1lID0gbmFtZS5hcHBlbmQoCiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0LnN5bnRoZXRpY05hbWVDaGFyKCksCiAgICAgICAgICAgICAgICAgICAgbmFtZXMuZW1wdHkpOwogICAgICAgIH0gd2hpbGUgKGxvb2t1cFN5bnRoZXRpYyhuYW1lLCBzKSAhPSBudWxsKTsKICAgICAgICByZXR1cm4gbmFtZTsKICAgIH0KCiAgICAvKiogQ2hlY2sgd2hldGhlciBzeW50aGV0aWMgc3ltYm9scyBnZW5lcmF0ZWQgZHVyaW5nIGxvd2VyaW5nIGNvbmZsaWN0CiAgICAgKiAgd2l0aCB1c2VyLWRlZmluZWQgc3ltYm9scy4KICAgICAqCiAgICAgKiAgQHBhcmFtIHRyYW5zbGF0ZWRUcmVlcyBsb3dlcmVkIGNsYXNzIHRyZWVzCiAgICAgKi8KICAgIHZvaWQgY2hlY2tDb25mbGljdHMoTGlzdDxKQ1RyZWU+IHRyYW5zbGF0ZWRUcmVlcykgewogICAgICAgIGZvciAoSkNUcmVlIHQgOiB0cmFuc2xhdGVkVHJlZXMpIHsKICAgICAgICAgICAgdC5hY2NlcHQoY29uZmxpY3RzQ2hlY2tlcik7CiAgICAgICAgfQogICAgfQoKICAgIEpDVHJlZS5WaXNpdG9yIGNvbmZsaWN0c0NoZWNrZXIgPSBuZXcgVHJlZVNjYW5uZXIoKSB7CgogICAgICAgIFR5cGVTeW1ib2wgY3VycmVudENsYXNzOwoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdE1ldGhvZERlZihKQ01ldGhvZERlY2wgdGhhdCkgewogICAgICAgICAgICBjaGsuY2hlY2tDb25mbGljdHModGhhdC5wb3MoKSwgdGhhdC5zeW0sIGN1cnJlbnRDbGFzcyk7CiAgICAgICAgICAgIHN1cGVyLnZpc2l0TWV0aG9kRGVmKHRoYXQpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRWYXJEZWYoSkNWYXJpYWJsZURlY2wgdGhhdCkgewogICAgICAgICAgICBpZiAodGhhdC5zeW0ub3duZXIua2luZCA9PSBUWVApIHsKICAgICAgICAgICAgICAgIGNoay5jaGVja0NvbmZsaWN0cyh0aGF0LnBvcygpLCB0aGF0LnN5bSwgY3VycmVudENsYXNzKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBzdXBlci52aXNpdFZhckRlZih0aGF0KTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0Q2xhc3NEZWYoSkNDbGFzc0RlY2wgdGhhdCkgewogICAgICAgICAgICBUeXBlU3ltYm9sIHByZXZDdXJyZW50Q2xhc3MgPSBjdXJyZW50Q2xhc3M7CiAgICAgICAgICAgIGN1cnJlbnRDbGFzcyA9IHRoYXQuc3ltOwogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgc3VwZXIudmlzaXRDbGFzc0RlZih0aGF0KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBmaW5hbGx5IHsKICAgICAgICAgICAgICAgIGN1cnJlbnRDbGFzcyA9IHByZXZDdXJyZW50Q2xhc3M7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9OwoKICAgIC8qKiBMb29rIHVwIGEgc3ludGhldGljIG5hbWUgaW4gYSBnaXZlbiBzY29wZS4KICAgICAqICBAcGFyYW0gcyAgICAgICAgICAgIFRoZSBzY29wZS4KICAgICAqICBAcGFyYW0gbmFtZSAgICAgICAgIFRoZSBuYW1lLgogICAgICovCiAgICBwcml2YXRlIFN5bWJvbCBsb29rdXBTeW50aGV0aWMoTmFtZSBuYW1lLCBTY29wZSBzKSB7CiAgICAgICAgU3ltYm9sIHN5bSA9IHMuZmluZEZpcnN0KG5hbWUpOwogICAgICAgIHJldHVybiAoc3ltPT1udWxsIHx8IChzeW0uZmxhZ3MoKSZTWU5USEVUSUMpPT0wKSA/IG51bGwgOiBzeW07CiAgICB9CgogICAgLyoqIExvb2sgdXAgYSBtZXRob2QgaW4gYSBnaXZlbiBzY29wZS4KICAgICAqLwogICAgcHJpdmF0ZSBNZXRob2RTeW1ib2wgbG9va3VwTWV0aG9kKERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIE5hbWUgbmFtZSwgVHlwZSBxdWFsLCBMaXN0PFR5cGU+IGFyZ3MpIHsKICAgICAgICByZXR1cm4gcnMucmVzb2x2ZUludGVybmFsTWV0aG9kKHBvcywgYXR0ckVudiwgcXVhbCwgbmFtZSwgYXJncywgTGlzdC5uaWwoKSk7CiAgICB9CgogICAgLyoqIExvb2sgdXAgYSBjb25zdHJ1Y3Rvci4KICAgICAqLwogICAgcHJpdmF0ZSBNZXRob2RTeW1ib2wgbG9va3VwQ29uc3RydWN0b3IoRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcywgVHlwZSBxdWFsLCBMaXN0PFR5cGU+IGFyZ3MpIHsKICAgICAgICByZXR1cm4gcnMucmVzb2x2ZUludGVybmFsQ29uc3RydWN0b3IocG9zLCBhdHRyRW52LCBxdWFsLCBhcmdzLCBudWxsKTsKICAgIH0KCiAgICAvKiogTG9vayB1cCBhIGZpZWxkLgogICAgICovCiAgICBwcml2YXRlIFZhclN5bWJvbCBsb29rdXBGaWVsZChEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBUeXBlIHF1YWwsIE5hbWUgbmFtZSkgewogICAgICAgIHJldHVybiBycy5yZXNvbHZlSW50ZXJuYWxGaWVsZChwb3MsIGF0dHJFbnYsIHF1YWwsIG5hbWUpOwogICAgfQoKICAgIC8qKiBBbm9uIGlubmVyIGNsYXNzZXMgYXJlIHVzZWQgYXMgYWNjZXNzIGNvbnN0cnVjdG9yIHRhZ3MuCiAgICAgKiBhY2Nlc3NDb25zdHJ1Y3RvclRhZyB3aWxsIHVzZSBhbiBleGlzdGluZyBhbm9uIGNsYXNzIGlmIG9uZSBpcyBhdmFpbGFibGUsCiAgICAgKiBhbmQgc3ludGhldGhpc2UgYSBjbGFzcyAod2l0aCBtYWtlRW1wdHlDbGFzcykgaWYgb25lIGlzIG5vdCBhdmFpbGFibGUuCiAgICAgKiBIb3dldmVyLCB0aGVyZSBpcyBhIHNtYWxsIHBvc3NpYmlsaXR5IHRoYXQgYW4gZXhpc3RpbmcgY2xhc3Mgd2lsbCBub3QKICAgICAqIGJlIGdlbmVyYXRlZCBhcyBleHBlY3RlZCBpZiBpdCBpcyBpbnNpZGUgYSBjb25kaXRpb25hbCB3aXRoIGEgY29uc3RhbnQKICAgICAqIGV4cHJlc3Npb24uIElmIHRoYXQgaXMgZm91bmQgdG8gYmUgdGhlIGNhc2UsIGNyZWF0ZSBhbiBlbXB0eSBjbGFzcyB0cmVlIGhlcmUuCiAgICAgKi8KICAgIHByaXZhdGUgdm9pZCBjaGVja0FjY2Vzc0NvbnN0cnVjdG9yVGFncygpIHsKICAgICAgICBmb3IgKExpc3Q8Q2xhc3NTeW1ib2w+IGwgPSBhY2Nlc3NDb25zdHJUYWdzOyBsLm5vbkVtcHR5KCk7IGwgPSBsLnRhaWwpIHsKICAgICAgICAgICAgQ2xhc3NTeW1ib2wgYyA9IGwuaGVhZDsKICAgICAgICAgICAgaWYgKGlzVHJhbnNsYXRlZENsYXNzQXZhaWxhYmxlKGMpKQogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIC8vIENyZWF0ZSBjbGFzcyBkZWZpbml0aW9uIHRyZWUuCiAgICAgICAgICAgIEpDQ2xhc3NEZWNsIGNkZWMgPSBtYWtlRW1wdHlDbGFzcyhTVEFUSUMgfCBTWU5USEVUSUMsCiAgICAgICAgICAgICAgICAgICAgYy5vdXRlcm1vc3RDbGFzcygpLCBjLmZsYXRuYW1lLCBmYWxzZSk7CiAgICAgICAgICAgIHN3YXBBY2Nlc3NDb25zdHJ1Y3RvclRhZyhjLCBjZGVjLnN5bSk7CiAgICAgICAgICAgIHRyYW5zbGF0ZWQuYXBwZW5kKGNkZWMpOwogICAgICAgIH0KICAgIH0KICAgIC8vIHdoZXJlCiAgICBwcml2YXRlIGJvb2xlYW4gaXNUcmFuc2xhdGVkQ2xhc3NBdmFpbGFibGUoQ2xhc3NTeW1ib2wgYykgewogICAgICAgIGZvciAoSkNUcmVlIHRyZWU6IHRyYW5zbGF0ZWQpIHsKICAgICAgICAgICAgaWYgKHRyZWUuaGFzVGFnKENMQVNTREVGKQogICAgICAgICAgICAgICAgICAgICYmICgoSkNDbGFzc0RlY2wpIHRyZWUpLnN5bSA9PSBjKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgdm9pZCBzd2FwQWNjZXNzQ29uc3RydWN0b3JUYWcoQ2xhc3NTeW1ib2wgb2xkQ1RhZywgQ2xhc3NTeW1ib2wgbmV3Q1RhZykgewogICAgICAgIGZvciAoTWV0aG9kU3ltYm9sIG1ldGhvZFN5bWJvbCA6IGFjY2Vzc0NvbnN0cnMudmFsdWVzKCkpIHsKICAgICAgICAgICAgQXNzZXJ0LmNoZWNrKG1ldGhvZFN5bWJvbC50eXBlLmhhc1RhZyhNRVRIT0QpKTsKICAgICAgICAgICAgTWV0aG9kVHlwZSBvbGRNZXRob2RUeXBlID0KICAgICAgICAgICAgICAgICAgICAoTWV0aG9kVHlwZSltZXRob2RTeW1ib2wudHlwZTsKICAgICAgICAgICAgaWYgKG9sZE1ldGhvZFR5cGUuYXJndHlwZXMuaGVhZC50c3ltID09IG9sZENUYWcpCiAgICAgICAgICAgICAgICBtZXRob2RTeW1ib2wudHlwZSA9CiAgICAgICAgICAgICAgICAgICAgdHlwZXMuY3JlYXRlTWV0aG9kVHlwZVdpdGhQYXJhbWV0ZXJzKG9sZE1ldGhvZFR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgIG9sZE1ldGhvZFR5cGUuZ2V0UGFyYW1ldGVyVHlwZXMoKS50YWlsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAucHJlcGVuZChuZXdDVGFnLmVyYXN1cmUodHlwZXMpKSk7CiAgICAgICAgfQogICAgfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEFjY2VzcyBtZXRob2RzCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKICAgIC8qKiBBIG1hcHBpbmcgZnJvbSBzeW1ib2xzIHRvIHRoZWlyIGFjY2VzcyBudW1iZXJzLgogICAgICovCiAgICBwcml2YXRlIE1hcDxTeW1ib2wsSW50ZWdlcj4gYWNjZXNzTnVtczsKCiAgICAvKiogQSBtYXBwaW5nIGZyb20gc3ltYm9scyB0byBhbiBhcnJheSBvZiBhY2Nlc3Mgc3ltYm9scywgaW5kZXhlZCBieQogICAgICogIGFjY2VzcyBjb2RlLgogICAgICovCiAgICBwcml2YXRlIE1hcDxTeW1ib2wsTWV0aG9kU3ltYm9sW10+IGFjY2Vzc1N5bXM7CgogICAgLyoqIEEgbWFwcGluZyBmcm9tIChjb25zdHJ1Y3Rvcikgc3ltYm9scyB0byBhY2Nlc3MgY29uc3RydWN0b3Igc3ltYm9scy4KICAgICAqLwogICAgcHJpdmF0ZSBNYXA8U3ltYm9sLE1ldGhvZFN5bWJvbD4gYWNjZXNzQ29uc3RyczsKCiAgICAvKiogQSBsaXN0IG9mIGFsbCBjbGFzcyBzeW1ib2xzIHVzZWQgZm9yIGFjY2VzcyBjb25zdHJ1Y3RvciB0YWdzLgogICAgICovCiAgICBwcml2YXRlIExpc3Q8Q2xhc3NTeW1ib2w+IGFjY2Vzc0NvbnN0clRhZ3M7CgogICAgLyoqIEEgcXVldWUgZm9yIGFsbCBhY2Nlc3NlZCBzeW1ib2xzLgogICAgICovCiAgICBwcml2YXRlIExpc3RCdWZmZXI8U3ltYm9sPiBhY2Nlc3NlZDsKCiAgICAvKiogcmV0dXJuIGFjY2VzcyBjb2RlIGZvciBpZGVudGlmaWVyLAogICAgICogIEBwYXJhbSB0cmVlICAgICBUaGUgdHJlZSByZXByZXNlbnRpbmcgdGhlIGlkZW50aWZpZXIgdXNlLgogICAgICogIEBwYXJhbSBlbmNsT3AgICBUaGUgY2xvc2VzdCBlbmNsb3Npbmcgb3BlcmF0aW9uIG5vZGUgb2YgdHJlZSwKICAgICAqICAgICAgICAgICAgICAgICAgbnVsbCBpZiB0cmVlIGlzIG5vdCBhIHN1YnRyZWUgb2YgYW4gb3BlcmF0aW9uLgogICAgICovCiAgICBwcml2YXRlIHN0YXRpYyBpbnQgYWNjZXNzQ29kZShKQ1RyZWUgdHJlZSwgSkNUcmVlIGVuY2xPcCkgewogICAgICAgIGlmIChlbmNsT3AgPT0gbnVsbCkKICAgICAgICAgICAgcmV0dXJuIEFjY2Vzc0NvZGUuREVSRUYuY29kZTsKICAgICAgICBlbHNlIGlmIChlbmNsT3AuaGFzVGFnKEFTU0lHTikgJiYKICAgICAgICAgICAgICAgICB0cmVlID09IFRyZWVJbmZvLnNraXBQYXJlbnMoKChKQ0Fzc2lnbikgZW5jbE9wKS5saHMpKQogICAgICAgICAgICByZXR1cm4gQWNjZXNzQ29kZS5BU1NJR04uY29kZTsKICAgICAgICBlbHNlIGlmICgoZW5jbE9wLmdldFRhZygpLmlzSW5jT3JEZWNVbmFyeU9wKCkgfHwgZW5jbE9wLmdldFRhZygpLmlzQXNzaWdub3AoKSkgJiYKICAgICAgICAgICAgICAgIHRyZWUgPT0gVHJlZUluZm8uc2tpcFBhcmVucygoKEpDT3BlcmF0b3JFeHByZXNzaW9uKSBlbmNsT3ApLmdldE9wZXJhbmQoTEVGVCkpKQogICAgICAgICAgICByZXR1cm4gKCgoSkNPcGVyYXRvckV4cHJlc3Npb24pIGVuY2xPcCkub3BlcmF0b3IpLmdldEFjY2Vzc0NvZGUoZW5jbE9wLmdldFRhZygpKTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIHJldHVybiBBY2Nlc3NDb2RlLkRFUkVGLmNvZGU7CiAgICB9CgogICAgLyoqIFJldHVybiBiaW5hcnkgb3BlcmF0b3IgdGhhdCBjb3JyZXNwb25kcyB0byBnaXZlbiBhY2Nlc3MgY29kZS4KICAgICAqLwogICAgcHJpdmF0ZSBPcGVyYXRvclN5bWJvbCBiaW5hcnlBY2Nlc3NPcGVyYXRvcihpbnQgYWNvZGUsIFRhZyB0YWcpIHsKICAgICAgICByZXR1cm4gb3BlcmF0b3JzLmxvb2t1cEJpbmFyeU9wKG9wIC0+IG9wLmdldEFjY2Vzc0NvZGUodGFnKSA9PSBhY29kZSk7CiAgICB9CgogICAgLyoqIFJldHVybiB0cmVlIHRhZyBmb3IgYXNzaWdubWVudCBvcGVyYXRpb24gY29ycmVzcG9uZGluZwogICAgICogIHRvIGdpdmVuIGJpbmFyeSBvcGVyYXRvci4KICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgSkNUcmVlLlRhZyB0cmVlVGFnKE9wZXJhdG9yU3ltYm9sIG9wZXJhdG9yKSB7CiAgICAgICAgc3dpdGNoIChvcGVyYXRvci5vcGNvZGUpIHsKICAgICAgICBjYXNlIEJ5dGVDb2Rlcy5pb3I6IGNhc2UgQnl0ZUNvZGVzLmxvcjoKICAgICAgICAgICAgcmV0dXJuIEJJVE9SX0FTRzsKICAgICAgICBjYXNlIEJ5dGVDb2Rlcy5peG9yOiBjYXNlIEJ5dGVDb2Rlcy5seG9yOgogICAgICAgICAgICByZXR1cm4gQklUWE9SX0FTRzsKICAgICAgICBjYXNlIEJ5dGVDb2Rlcy5pYW5kOiBjYXNlIEJ5dGVDb2Rlcy5sYW5kOgogICAgICAgICAgICByZXR1cm4gQklUQU5EX0FTRzsKICAgICAgICBjYXNlIEJ5dGVDb2Rlcy5pc2hsOiBjYXNlIEJ5dGVDb2Rlcy5sc2hsOgogICAgICAgIGNhc2UgQnl0ZUNvZGVzLmlzaGxsOiBjYXNlIEJ5dGVDb2Rlcy5sc2hsbDoKICAgICAgICAgICAgcmV0dXJuIFNMX0FTRzsKICAgICAgICBjYXNlIEJ5dGVDb2Rlcy5pc2hyOiBjYXNlIEJ5dGVDb2Rlcy5sc2hyOgogICAgICAgIGNhc2UgQnl0ZUNvZGVzLmlzaHJsOiBjYXNlIEJ5dGVDb2Rlcy5sc2hybDoKICAgICAgICAgICAgcmV0dXJuIFNSX0FTRzsKICAgICAgICBjYXNlIEJ5dGVDb2Rlcy5pdXNocjogY2FzZSBCeXRlQ29kZXMubHVzaHI6CiAgICAgICAgY2FzZSBCeXRlQ29kZXMuaXVzaHJsOiBjYXNlIEJ5dGVDb2Rlcy5sdXNocmw6CiAgICAgICAgICAgIHJldHVybiBVU1JfQVNHOwogICAgICAgIGNhc2UgQnl0ZUNvZGVzLmlhZGQ6IGNhc2UgQnl0ZUNvZGVzLmxhZGQ6CiAgICAgICAgY2FzZSBCeXRlQ29kZXMuZmFkZDogY2FzZSBCeXRlQ29kZXMuZGFkZDoKICAgICAgICBjYXNlIEJ5dGVDb2Rlcy5zdHJpbmdfYWRkOgogICAgICAgICAgICByZXR1cm4gUExVU19BU0c7CiAgICAgICAgY2FzZSBCeXRlQ29kZXMuaXN1YjogY2FzZSBCeXRlQ29kZXMubHN1YjoKICAgICAgICBjYXNlIEJ5dGVDb2Rlcy5mc3ViOiBjYXNlIEJ5dGVDb2Rlcy5kc3ViOgogICAgICAgICAgICByZXR1cm4gTUlOVVNfQVNHOwogICAgICAgIGNhc2UgQnl0ZUNvZGVzLmltdWw6IGNhc2UgQnl0ZUNvZGVzLmxtdWw6CiAgICAgICAgY2FzZSBCeXRlQ29kZXMuZm11bDogY2FzZSBCeXRlQ29kZXMuZG11bDoKICAgICAgICAgICAgcmV0dXJuIE1VTF9BU0c7CiAgICAgICAgY2FzZSBCeXRlQ29kZXMuaWRpdjogY2FzZSBCeXRlQ29kZXMubGRpdjoKICAgICAgICBjYXNlIEJ5dGVDb2Rlcy5mZGl2OiBjYXNlIEJ5dGVDb2Rlcy5kZGl2OgogICAgICAgICAgICByZXR1cm4gRElWX0FTRzsKICAgICAgICBjYXNlIEJ5dGVDb2Rlcy5pbW9kOiBjYXNlIEJ5dGVDb2Rlcy5sbW9kOgogICAgICAgIGNhc2UgQnl0ZUNvZGVzLmZtb2Q6IGNhc2UgQnl0ZUNvZGVzLmRtb2Q6CiAgICAgICAgICAgIHJldHVybiBNT0RfQVNHOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigpOwogICAgICAgIH0KICAgIH0KCiAgICAvKiogVGhlIG5hbWUgb2YgdGhlIGFjY2VzcyBtZXRob2Qgd2l0aCBudW1iZXIgYGFudW0nIGFuZCBhY2Nlc3MgY29kZSBgYWNvZGUnLgogICAgICovCiAgICBOYW1lIGFjY2Vzc05hbWUoaW50IGFudW0sIGludCBhY29kZSkgewogICAgICAgIHJldHVybiBuYW1lcy5mcm9tU3RyaW5nKAogICAgICAgICAgICAiYWNjZXNzIiArIHRhcmdldC5zeW50aGV0aWNOYW1lQ2hhcigpICsgYW51bSArIGFjb2RlIC8gMTAgKyBhY29kZSAlIDEwKTsKICAgIH0KCiAgICAvKiogUmV0dXJuIGFjY2VzcyBzeW1ib2wgZm9yIGEgcHJpdmF0ZSBvciBwcm90ZWN0ZWQgc3ltYm9sIGZyb20gYW4gaW5uZXIgY2xhc3MuCiAgICAgKiAgQHBhcmFtIHN5bSAgICAgICAgVGhlIGFjY2Vzc2VkIHByaXZhdGUgc3ltYm9sLgogICAgICogIEBwYXJhbSB0cmVlICAgICAgIFRoZSBhY2Nlc3NpbmcgdHJlZS4KICAgICAqICBAcGFyYW0gZW5jbE9wICAgICBUaGUgY2xvc2VzdCBlbmNsb3Npbmcgb3BlcmF0aW9uIG5vZGUgb2YgdHJlZSwKICAgICAqICAgICAgICAgICAgICAgICAgICBudWxsIGlmIHRyZWUgaXMgbm90IGEgc3VidHJlZSBvZiBhbiBvcGVyYXRpb24uCiAgICAgKiAgQHBhcmFtIHByb3RBY2Nlc3MgSXMgYWNjZXNzIHRvIGEgcHJvdGVjdGVkIHN5bWJvbCBpbiBhbm90aGVyCiAgICAgKiAgICAgICAgICAgICAgICAgICAgcGFja2FnZT8KICAgICAqICBAcGFyYW0gcmVmU3VwZXIgICBJcyBhY2Nlc3MgdmlhIGEgKHF1YWxpZmllZCkgQy5zdXBlcj8KICAgICAqLwogICAgTWV0aG9kU3ltYm9sIGFjY2Vzc1N5bWJvbChTeW1ib2wgc3ltLCBKQ1RyZWUgdHJlZSwgSkNUcmVlIGVuY2xPcCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBwcm90QWNjZXNzLCBib29sZWFuIHJlZlN1cGVyKSB7CiAgICAgICAgQ2xhc3NTeW1ib2wgYWNjT3duZXIgPSByZWZTdXBlciAmJiBwcm90QWNjZXNzCiAgICAgICAgICAgIC8vIEZvciBhY2Nlc3MgdmlhIHF1YWxpZmllZCBzdXBlciAoVC5zdXBlci54KSwgcGxhY2UgdGhlCiAgICAgICAgICAgIC8vIGFjY2VzcyBzeW1ib2wgb24gVC4KICAgICAgICAgICAgPyAoQ2xhc3NTeW1ib2wpKChKQ0ZpZWxkQWNjZXNzKSB0cmVlKS5zZWxlY3RlZC50eXBlLnRzeW0KICAgICAgICAgICAgLy8gT3RoZXJ3aXNlIHByZXRlbmQgdGhhdCB0aGUgb3duZXIgb2YgYW4gYWNjZXNzZWQKICAgICAgICAgICAgLy8gcHJvdGVjdGVkIHN5bWJvbCBpcyB0aGUgZW5jbG9zaW5nIGNsYXNzIG9mIHRoZSBjdXJyZW50CiAgICAgICAgICAgIC8vIGNsYXNzIHdoaWNoIGlzIGEgc3ViY2xhc3Mgb2YgdGhlIHN5bWJvbCdzIG93bmVyLgogICAgICAgICAgICA6IGFjY2Vzc0NsYXNzKHN5bSwgcHJvdEFjY2VzcywgdHJlZSk7CgogICAgICAgIFN5bWJvbCB2c3ltID0gc3ltOwogICAgICAgIGlmIChzeW0ub3duZXIgIT0gYWNjT3duZXIpIHsKICAgICAgICAgICAgdnN5bSA9IHN5bS5jbG9uZShhY2NPd25lcik7CiAgICAgICAgICAgIGFjdHVhbFN5bWJvbHMucHV0KHZzeW0sIHN5bSk7CiAgICAgICAgfQoKICAgICAgICBJbnRlZ2VyIGFudW0gICAgICAgICAgICAgIC8vIFRoZSBhY2Nlc3MgbnVtYmVyIG9mIHRoZSBhY2Nlc3MgbWV0aG9kLgogICAgICAgICAgICA9IGFjY2Vzc051bXMuZ2V0KHZzeW0pOwogICAgICAgIGlmIChhbnVtID09IG51bGwpIHsKICAgICAgICAgICAgYW51bSA9IGFjY2Vzc2VkLmxlbmd0aCgpOwogICAgICAgICAgICBhY2Nlc3NOdW1zLnB1dCh2c3ltLCBhbnVtKTsKICAgICAgICAgICAgYWNjZXNzU3ltcy5wdXQodnN5bSwgbmV3IE1ldGhvZFN5bWJvbFtBY2Nlc3NDb2RlLm51bWJlck9mQWNjZXNzQ29kZXNdKTsKICAgICAgICAgICAgYWNjZXNzZWQuYXBwZW5kKHZzeW0pOwogICAgICAgICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oImFjY2Vzc2luZyAiICsgdnN5bSArICIgaW4gIiArIHZzeW0ubG9jYXRpb24oKSk7CiAgICAgICAgfQoKICAgICAgICBpbnQgYWNvZGU7ICAgICAgICAgICAgICAgIC8vIFRoZSBhY2Nlc3MgY29kZSBvZiB0aGUgYWNjZXNzIG1ldGhvZC4KICAgICAgICBMaXN0PFR5cGU+IGFyZ3R5cGVzOyAgICAgIC8vIFRoZSBhcmd1bWVudCB0eXBlcyBvZiB0aGUgYWNjZXNzIG1ldGhvZC4KICAgICAgICBUeXBlIHJlc3R5cGU7ICAgICAgICAgICAgIC8vIFRoZSByZXN1bHQgdHlwZSBvZiB0aGUgYWNjZXNzIG1ldGhvZC4KICAgICAgICBMaXN0PFR5cGU+IHRocm93bjsgICAgICAgIC8vIFRoZSB0aHJvd24gZXhjZXB0aW9ucyBvZiB0aGUgYWNjZXNzIG1ldGhvZC4KICAgICAgICBzd2l0Y2ggKHZzeW0ua2luZCkgewogICAgICAgIGNhc2UgVkFSOgogICAgICAgICAgICBhY29kZSA9IGFjY2Vzc0NvZGUodHJlZSwgZW5jbE9wKTsKICAgICAgICAgICAgaWYgKGFjb2RlID49IEFjY2Vzc0NvZGUuRklSU1RBU0dPUC5jb2RlKSB7CiAgICAgICAgICAgICAgICBPcGVyYXRvclN5bWJvbCBvcGVyYXRvciA9IGJpbmFyeUFjY2Vzc09wZXJhdG9yKGFjb2RlLCBlbmNsT3AuZ2V0VGFnKCkpOwogICAgICAgICAgICAgICAgaWYgKG9wZXJhdG9yLm9wY29kZSA9PSBzdHJpbmdfYWRkKQogICAgICAgICAgICAgICAgICAgIGFyZ3R5cGVzID0gTGlzdC5vZihzeW1zLm9iamVjdFR5cGUpOwogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIGFyZ3R5cGVzID0gb3BlcmF0b3IudHlwZS5nZXRQYXJhbWV0ZXJUeXBlcygpLnRhaWw7CiAgICAgICAgICAgIH0gZWxzZSBpZiAoYWNvZGUgPT0gQWNjZXNzQ29kZS5BU1NJR04uY29kZSkKICAgICAgICAgICAgICAgIGFyZ3R5cGVzID0gTGlzdC5vZih2c3ltLmVyYXN1cmUodHlwZXMpKTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgYXJndHlwZXMgPSBMaXN0Lm5pbCgpOwogICAgICAgICAgICByZXN0eXBlID0gdnN5bS5lcmFzdXJlKHR5cGVzKTsKICAgICAgICAgICAgdGhyb3duID0gTGlzdC5uaWwoKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBNVEg6CiAgICAgICAgICAgIGFjb2RlID0gQWNjZXNzQ29kZS5ERVJFRi5jb2RlOwogICAgICAgICAgICBhcmd0eXBlcyA9IHZzeW0uZXJhc3VyZSh0eXBlcykuZ2V0UGFyYW1ldGVyVHlwZXMoKTsKICAgICAgICAgICAgcmVzdHlwZSA9IHZzeW0uZXJhc3VyZSh0eXBlcykuZ2V0UmV0dXJuVHlwZSgpOwogICAgICAgICAgICB0aHJvd24gPSB2c3ltLnR5cGUuZ2V0VGhyb3duVHlwZXMoKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCk7CiAgICAgICAgfQoKICAgICAgICAvLyBGb3IgcmVmZXJlbmNlcyB2aWEgcXVhbGlmaWVkIHN1cGVyLCBpbmNyZW1lbnQgYWNvZGUgYnkgb25lLAogICAgICAgIC8vIG1ha2luZyBpdCBvZGQuCiAgICAgICAgaWYgKHByb3RBY2Nlc3MgJiYgcmVmU3VwZXIpIGFjb2RlKys7CgogICAgICAgIC8vIEluc3RhbmNlIGFjY2VzcyBtZXRob2RzIGdldCBpbnN0YW5jZSBhcyBmaXJzdCBwYXJhbWV0ZXIuCiAgICAgICAgLy8gRm9yIHByb3RlY3RlZCBzeW1ib2xzIHRoaXMgbmVlZHMgdG8gYmUgdGhlIGluc3RhbmNlIGFzIGEgbWVtYmVyCiAgICAgICAgLy8gb2YgdGhlIHR5cGUgY29udGFpbmluZyB0aGUgYWNjZXNzZWQgc3ltYm9sLCBub3QgdGhlIGNsYXNzCiAgICAgICAgLy8gY29udGFpbmluZyB0aGUgYWNjZXNzIG1ldGhvZC4KICAgICAgICBpZiAoKHZzeW0uZmxhZ3MoKSAmIFNUQVRJQykgPT0gMCkgewogICAgICAgICAgICBhcmd0eXBlcyA9IGFyZ3R5cGVzLnByZXBlbmQodnN5bS5vd25lci5lcmFzdXJlKHR5cGVzKSk7CiAgICAgICAgfQogICAgICAgIE1ldGhvZFN5bWJvbFtdIGFjY2Vzc29ycyA9IGFjY2Vzc1N5bXMuZ2V0KHZzeW0pOwogICAgICAgIE1ldGhvZFN5bWJvbCBhY2Nlc3NvciA9IGFjY2Vzc29yc1thY29kZV07CiAgICAgICAgaWYgKGFjY2Vzc29yID09IG51bGwpIHsKICAgICAgICAgICAgYWNjZXNzb3IgPSBuZXcgTWV0aG9kU3ltYm9sKAogICAgICAgICAgICAgICAgU1RBVElDIHwgU1lOVEhFVElDIHwgKGFjY093bmVyLmlzSW50ZXJmYWNlKCkgPyBQVUJMSUMgOiAwKSwKICAgICAgICAgICAgICAgIGFjY2Vzc05hbWUoYW51bS5pbnRWYWx1ZSgpLCBhY29kZSksCiAgICAgICAgICAgICAgICBuZXcgTWV0aG9kVHlwZShhcmd0eXBlcywgcmVzdHlwZSwgdGhyb3duLCBzeW1zLm1ldGhvZENsYXNzKSwKICAgICAgICAgICAgICAgIGFjY093bmVyKTsKICAgICAgICAgICAgZW50ZXJTeW50aGV0aWModHJlZS5wb3MoKSwgYWNjZXNzb3IsIGFjY093bmVyLm1lbWJlcnMoKSk7CiAgICAgICAgICAgIGFjY2Vzc29yc1thY29kZV0gPSBhY2Nlc3NvcjsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGFjY2Vzc29yOwogICAgfQoKICAgIC8qKiBUaGUgcXVhbGlmaWVyIHRvIGJlIHVzZWQgZm9yIGFjY2Vzc2luZyBhIHN5bWJvbCBpbiBhbiBvdXRlciBjbGFzcy4KICAgICAqICBUaGlzIGlzIGVpdGhlciBDLnN5bSBvciBDLnRoaXMuc3ltLCBkZXBlbmRpbmcgb24gd2hldGhlciBvciBub3QKICAgICAqICBzeW0gaXMgc3RhdGljLgogICAgICogIEBwYXJhbSBzeW0gICBUaGUgYWNjZXNzZWQgc3ltYm9sLgogICAgICovCiAgICBKQ0V4cHJlc3Npb24gYWNjZXNzQmFzZShEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBTeW1ib2wgc3ltKSB7CiAgICAgICAgcmV0dXJuIChzeW0uZmxhZ3MoKSAmIFNUQVRJQykgIT0gMAogICAgICAgICAgICA/IGFjY2VzcyhtYWtlLmF0KHBvcy5nZXRTdGFydFBvc2l0aW9uKCkpLlF1YWxJZGVudChzeW0ub3duZXIpKQogICAgICAgICAgICA6IG1ha2VPd25lclRoaXMocG9zLCBzeW0sIHRydWUpOwogICAgfQoKICAgIC8qKiBEbyB3ZSBuZWVkIGFuIGFjY2VzcyBtZXRob2QgdG8gcmVmZXJlbmNlIHByaXZhdGUgc3ltYm9sPwogICAgICovCiAgICBib29sZWFuIG5lZWRzUHJpdmF0ZUFjY2VzcyhTeW1ib2wgc3ltKSB7CiAgICAgICAgaWYgKChzeW0uZmxhZ3MoKSAmIFBSSVZBVEUpID09IDAgfHwgc3ltLm93bmVyID09IGN1cnJlbnRDbGFzcykgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfSBlbHNlIGlmIChzeW0ubmFtZSA9PSBuYW1lcy5pbml0ICYmIHN5bS5vd25lci5pc0xvY2FsKCkpIHsKICAgICAgICAgICAgLy8gcHJpdmF0ZSBjb25zdHJ1Y3RvciBpbiBsb2NhbCBjbGFzczogcmVsYXggcHJvdGVjdGlvbgogICAgICAgICAgICBzeW0uZmxhZ3NfZmllbGQgJj0gflBSSVZBVEU7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICB9CgogICAgLyoqIERvIHdlIG5lZWQgYW4gYWNjZXNzIG1ldGhvZCB0byByZWZlcmVuY2Ugc3ltYm9sIGluIG90aGVyIHBhY2thZ2U/CiAgICAgKi8KICAgIGJvb2xlYW4gbmVlZHNQcm90ZWN0ZWRBY2Nlc3MoU3ltYm9sIHN5bSwgSkNUcmVlIHRyZWUpIHsKICAgICAgICBpZiAoKHN5bS5mbGFncygpICYgUFJPVEVDVEVEKSA9PSAwIHx8CiAgICAgICAgICAgIHN5bS5vd25lci5vd25lciA9PSBjdXJyZW50Q2xhc3Mub3duZXIgfHwgLy8gZmFzdCBzcGVjaWFsIGNhc2UKICAgICAgICAgICAgc3ltLnBhY2tnZSgpID09IGN1cnJlbnRDbGFzcy5wYWNrZ2UoKSkKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIGlmICghY3VycmVudENsYXNzLmlzU3ViQ2xhc3Moc3ltLm93bmVyLCB0eXBlcykpCiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIGlmICgoc3ltLmZsYWdzKCkgJiBTVEFUSUMpICE9IDAgfHwKICAgICAgICAgICAgIXRyZWUuaGFzVGFnKFNFTEVDVCkgfHwKICAgICAgICAgICAgVHJlZUluZm8ubmFtZSgoKEpDRmllbGRBY2Nlc3MpIHRyZWUpLnNlbGVjdGVkKSA9PSBuYW1lcy5fc3VwZXIpCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICByZXR1cm4gISgoSkNGaWVsZEFjY2VzcykgdHJlZSkuc2VsZWN0ZWQudHlwZS50c3ltLmlzU3ViQ2xhc3MoY3VycmVudENsYXNzLCB0eXBlcyk7CiAgICB9CgogICAgLyoqIFRoZSBjbGFzcyBpbiB3aGljaCBhbiBhY2Nlc3MgbWV0aG9kIGZvciBnaXZlbiBzeW1ib2wgZ29lcy4KICAgICAqICBAcGFyYW0gc3ltICAgICAgICBUaGUgYWNjZXNzIHN5bWJvbAogICAgICogIEBwYXJhbSBwcm90QWNjZXNzIElzIGFjY2VzcyB0byBhIHByb3RlY3RlZCBzeW1ib2wgaW4gYW5vdGhlcgogICAgICogICAgICAgICAgICAgICAgICAgIHBhY2thZ2U/CiAgICAgKi8KICAgIENsYXNzU3ltYm9sIGFjY2Vzc0NsYXNzKFN5bWJvbCBzeW0sIGJvb2xlYW4gcHJvdEFjY2VzcywgSkNUcmVlIHRyZWUpIHsKICAgICAgICBpZiAocHJvdEFjY2VzcykgewogICAgICAgICAgICBTeW1ib2wgcXVhbGlmaWVyID0gbnVsbDsKICAgICAgICAgICAgQ2xhc3NTeW1ib2wgYyA9IGN1cnJlbnRDbGFzczsKICAgICAgICAgICAgaWYgKHRyZWUuaGFzVGFnKFNFTEVDVCkgJiYgKHN5bS5mbGFncygpICYgU1RBVElDKSA9PSAwKSB7CiAgICAgICAgICAgICAgICBxdWFsaWZpZXIgPSAoKEpDRmllbGRBY2Nlc3MpIHRyZWUpLnNlbGVjdGVkLnR5cGUudHN5bTsKICAgICAgICAgICAgICAgIHdoaWxlICghcXVhbGlmaWVyLmlzU3ViQ2xhc3MoYywgdHlwZXMpKSB7CiAgICAgICAgICAgICAgICAgICAgYyA9IGMub3duZXIuZW5jbENsYXNzKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gYzsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHdoaWxlICghYy5pc1N1YkNsYXNzKHN5bS5vd25lciwgdHlwZXMpKSB7CiAgICAgICAgICAgICAgICAgICAgYyA9IGMub3duZXIuZW5jbENsYXNzKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLy8gdGhlIHN5bWJvbCBpcyBwcml2YXRlCiAgICAgICAgICAgIHJldHVybiBzeW0ub3duZXIuZW5jbENsYXNzKCk7CiAgICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgdm9pZCBhZGRQcnVuZWRJbmZvKEpDVHJlZSB0cmVlKSB7CiAgICAgICAgTGlzdDxKQ1RyZWU+IGluZm9MaXN0ID0gcHJ1bmVkVHJlZS5nZXQoY3VycmVudENsYXNzKTsKICAgICAgICBpbmZvTGlzdCA9IChpbmZvTGlzdCA9PSBudWxsKSA/IExpc3Qub2YodHJlZSkgOiBpbmZvTGlzdC5wcmVwZW5kKHRyZWUpOwogICAgICAgIHBydW5lZFRyZWUucHV0KGN1cnJlbnRDbGFzcywgaW5mb0xpc3QpOwogICAgfQoKICAgIC8qKiBFbnN1cmUgdGhhdCBpZGVudGlmaWVyIGlzIGFjY2Vzc2libGUsIHJldHVybiB0cmVlIGFjY2Vzc2luZyB0aGUgaWRlbnRpZmllci4KICAgICAqICBAcGFyYW0gc3ltICAgICAgVGhlIGFjY2Vzc2VkIHN5bWJvbC4KICAgICAqICBAcGFyYW0gdHJlZSAgICAgVGhlIHRyZWUgcmVmZXJyaW5nIHRvIHRoZSBzeW1ib2wuCiAgICAgKiAgQHBhcmFtIGVuY2xPcCAgIFRoZSBjbG9zZXN0IGVuY2xvc2luZyBvcGVyYXRpb24gbm9kZSBvZiB0cmVlLAogICAgICogICAgICAgICAgICAgICAgICBudWxsIGlmIHRyZWUgaXMgbm90IGEgc3VidHJlZSBvZiBhbiBvcGVyYXRpb24uCiAgICAgKiAgQHBhcmFtIHJlZlN1cGVyIElzIGFjY2VzcyB2aWEgYSAocXVhbGlmaWVkKSBDLnN1cGVyPwogICAgICovCiAgICBKQ0V4cHJlc3Npb24gYWNjZXNzKFN5bWJvbCBzeW0sIEpDRXhwcmVzc2lvbiB0cmVlLCBKQ0V4cHJlc3Npb24gZW5jbE9wLCBib29sZWFuIHJlZlN1cGVyKSB7CiAgICAgICAgLy8gQWNjZXNzIGEgZnJlZSB2YXJpYWJsZSB2aWEgaXRzIHByb3h5LCBvciBpdHMgcHJveHkncyBwcm94eQogICAgICAgIHdoaWxlIChzeW0ua2luZCA9PSBWQVIgJiYgc3ltLm93bmVyLmtpbmQgPT0gTVRIICYmCiAgICAgICAgICAgIHN5bS5vd25lci5lbmNsQ2xhc3MoKSAhPSBjdXJyZW50Q2xhc3MpIHsKICAgICAgICAgICAgLy8gQSBjb25zdGFudCBpcyByZXBsYWNlZCBieSBpdHMgY29uc3RhbnQgdmFsdWUuCiAgICAgICAgICAgIE9iamVjdCBjdiA9ICgoVmFyU3ltYm9sKXN5bSkuZ2V0Q29uc3RWYWx1ZSgpOwogICAgICAgICAgICBpZiAoY3YgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgbWFrZS5hdCh0cmVlLnBvcyk7CiAgICAgICAgICAgICAgICByZXR1cm4gbWFrZUxpdChzeW0udHlwZSwgY3YpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIE90aGVyd2lzZSByZXBsYWNlIHRoZSB2YXJpYWJsZSBieSBpdHMgcHJveHkuCiAgICAgICAgICAgIHN5bSA9IHByb3hpZXMuZmluZEZpcnN0KHByb3h5TmFtZShzeW0ubmFtZSkpOwogICAgICAgICAgICBBc3NlcnQuY2hlY2soc3ltICE9IG51bGwgJiYgKHN5bS5mbGFnc19maWVsZCAmIEZJTkFMKSAhPSAwKTsKICAgICAgICAgICAgdHJlZSA9IG1ha2UuYXQodHJlZS5wb3MpLklkZW50KHN5bSk7CiAgICAgICAgfQogICAgICAgIEpDRXhwcmVzc2lvbiBiYXNlID0gKHRyZWUuaGFzVGFnKFNFTEVDVCkpID8gKChKQ0ZpZWxkQWNjZXNzKSB0cmVlKS5zZWxlY3RlZCA6IG51bGw7CiAgICAgICAgc3dpdGNoIChzeW0ua2luZCkgewogICAgICAgIGNhc2UgVFlQOgogICAgICAgICAgICBpZiAoc3ltLm93bmVyLmtpbmQgIT0gUENLKSB7CiAgICAgICAgICAgICAgICAvLyBDb252ZXJ0IHR5cGUgaWRlbnRzIHRvCiAgICAgICAgICAgICAgICAvLyA8ZmxhdCBuYW1lPiBvciA8cGFja2FnZSBuYW1lPiAuIDxmbGF0IG5hbWU+CiAgICAgICAgICAgICAgICBOYW1lIGZsYXRuYW1lID0gQ29udmVydC5zaG9ydE5hbWUoc3ltLmZsYXROYW1lKCkpOwogICAgICAgICAgICAgICAgd2hpbGUgKGJhc2UgIT0gbnVsbCAmJgogICAgICAgICAgICAgICAgICAgICAgIFRyZWVJbmZvLnN5bWJvbChiYXNlKSAhPSBudWxsICYmCiAgICAgICAgICAgICAgICAgICAgICAgVHJlZUluZm8uc3ltYm9sKGJhc2UpLmtpbmQgIT0gUENLKSB7CiAgICAgICAgICAgICAgICAgICAgYmFzZSA9IChiYXNlLmhhc1RhZyhTRUxFQ1QpKQogICAgICAgICAgICAgICAgICAgICAgICA/ICgoSkNGaWVsZEFjY2VzcykgYmFzZSkuc2VsZWN0ZWQKICAgICAgICAgICAgICAgICAgICAgICAgOiBudWxsOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKHRyZWUuaGFzVGFnKElERU5UKSkgewogICAgICAgICAgICAgICAgICAgICgoSkNJZGVudCkgdHJlZSkubmFtZSA9IGZsYXRuYW1lOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChiYXNlID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICB0cmVlID0gbWFrZS5hdCh0cmVlLnBvcykuSWRlbnQoc3ltKTsKICAgICAgICAgICAgICAgICAgICAoKEpDSWRlbnQpIHRyZWUpLm5hbWUgPSBmbGF0bmFtZTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgKChKQ0ZpZWxkQWNjZXNzKSB0cmVlKS5zZWxlY3RlZCA9IGJhc2U7CiAgICAgICAgICAgICAgICAgICAgKChKQ0ZpZWxkQWNjZXNzKSB0cmVlKS5uYW1lID0gZmxhdG5hbWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBNVEg6IGNhc2UgVkFSOgogICAgICAgICAgICBpZiAoc3ltLm93bmVyLmtpbmQgPT0gVFlQKSB7CgogICAgICAgICAgICAgICAgLy8gQWNjZXNzIG1ldGhvZHMgYXJlIHJlcXVpcmVkIGZvcgogICAgICAgICAgICAgICAgLy8gIC0gcHJpdmF0ZSBtZW1iZXJzLAogICAgICAgICAgICAgICAgLy8gIC0gcHJvdGVjdGVkIG1lbWJlcnMgaW4gYSBzdXBlcmNsYXNzIG9mIGFuCiAgICAgICAgICAgICAgICAvLyAgICBlbmNsb3NpbmcgY2xhc3MgY29udGFpbmVkIGluIGFub3RoZXIgcGFja2FnZS4KICAgICAgICAgICAgICAgIC8vICAtIGFsbCBub24tcHJpdmF0ZSBtZW1iZXJzIGFjY2Vzc2VkIHZpYSBhIHF1YWxpZmllZCBzdXBlci4KICAgICAgICAgICAgICAgIGJvb2xlYW4gcHJvdEFjY2VzcyA9IHJlZlN1cGVyICYmICFuZWVkc1ByaXZhdGVBY2Nlc3Moc3ltKQogICAgICAgICAgICAgICAgICAgIHx8IG5lZWRzUHJvdGVjdGVkQWNjZXNzKHN5bSwgdHJlZSk7CiAgICAgICAgICAgICAgICBib29sZWFuIGFjY1JlcSA9IHByb3RBY2Nlc3MgfHwgbmVlZHNQcml2YXRlQWNjZXNzKHN5bSk7CgogICAgICAgICAgICAgICAgLy8gQSBiYXNlIGhhcyB0byBiZSBzdXBwbGllZCBmb3IKICAgICAgICAgICAgICAgIC8vICAtIHNpbXBsZSBpZGVudGlmaWVycyBhY2Nlc3NpbmcgdmFyaWFibGVzIGluIG91dGVyIGNsYXNzZXMuCiAgICAgICAgICAgICAgICBib29sZWFuIGJhc2VSZXEgPQogICAgICAgICAgICAgICAgICAgIGJhc2UgPT0gbnVsbCAmJgogICAgICAgICAgICAgICAgICAgIHN5bS5vd25lciAhPSBzeW1zLnByZWRlZkNsYXNzICYmCiAgICAgICAgICAgICAgICAgICAgIXN5bS5pc01lbWJlck9mKGN1cnJlbnRDbGFzcywgdHlwZXMpOwoKICAgICAgICAgICAgICAgIGlmIChhY2NSZXEgfHwgYmFzZVJlcSkgewogICAgICAgICAgICAgICAgICAgIG1ha2UuYXQodHJlZS5wb3MpOwoKICAgICAgICAgICAgICAgICAgICAvLyBDb25zdGFudHMgYXJlIHJlcGxhY2VkIGJ5IHRoZWlyIGNvbnN0YW50IHZhbHVlLgogICAgICAgICAgICAgICAgICAgIGlmIChzeW0ua2luZCA9PSBWQVIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgT2JqZWN0IGN2ID0gKChWYXJTeW1ib2wpc3ltKS5nZXRDb25zdFZhbHVlKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjdiAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRQcnVuZWRJbmZvKHRyZWUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG1ha2VMaXQoc3ltLnR5cGUsIGN2KTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gUHJpdmF0ZSB2YXJpYWJsZXMgYW5kIG1ldGhvZHMgYXJlIHJlcGxhY2VkIGJ5IGNhbGxzCiAgICAgICAgICAgICAgICAgICAgLy8gdG8gdGhlaXIgYWNjZXNzIG1ldGhvZHMuCiAgICAgICAgICAgICAgICAgICAgaWYgKGFjY1JlcSkgewogICAgICAgICAgICAgICAgICAgICAgICBMaXN0PEpDRXhwcmVzc2lvbj4gYXJncyA9IExpc3QubmlsKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgoc3ltLmZsYWdzKCkgJiBTVEFUSUMpID09IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEluc3RhbmNlIGFjY2VzcyBtZXRob2RzIGdldCBpbnN0YW5jZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYXMgZmlyc3QgcGFyYW1ldGVyLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGJhc2UgPT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYXNlID0gbWFrZU93bmVyVGhpcyh0cmVlLnBvcygpLCBzeW0sIHRydWUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJncyA9IGFyZ3MucHJlcGVuZChiYXNlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJhc2UgPSBudWxsOyAgIC8vIHNvIHdlIGRvbid0IGR1cGxpY2F0ZSBjb2RlCiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgU3ltYm9sIGFjY2VzcyA9IGFjY2Vzc1N5bWJvbChzeW0sIHRyZWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5jbE9wLCBwcm90QWNjZXNzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZlN1cGVyKTsKICAgICAgICAgICAgICAgICAgICAgICAgSkNFeHByZXNzaW9uIHJlY2VpdmVyID0gbWFrZS5TZWxlY3QoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYXNlICE9IG51bGwgPyBiYXNlIDogbWFrZS5RdWFsSWRlbnQoYWNjZXNzLm93bmVyKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFjY2Vzcyk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBtYWtlLkFwcChyZWNlaXZlciwgYXJncyk7CgogICAgICAgICAgICAgICAgICAgIC8vIE90aGVyIGFjY2Vzc2VzIHRvIG1lbWJlcnMgb2Ygb3V0ZXIgY2xhc3NlcyBnZXQgYQogICAgICAgICAgICAgICAgICAgIC8vIHF1YWxpZmllci4KICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGJhc2VSZXEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG1ha2UuYXQodHJlZS5wb3MpLlNlbGVjdCgKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFjY2Vzc0Jhc2UodHJlZS5wb3MoKSwgc3ltKSwgc3ltKS5zZXRUeXBlKHRyZWUudHlwZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgaWYgKHN5bS5vd25lci5raW5kID09IE1USCAmJiBsYW1iZGFUcmFuc2xhdGlvbk1hcCAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAvL3N5bSBpcyBhIGxvY2FsIHZhcmlhYmxlIC0gY2hlY2sgdGhlIGxhbWJkYSB0cmFuc2xhdGlvbiBtYXAgdG8KICAgICAgICAgICAgICAgIC8vc2VlIGlmIHN5bSBoYXMgYmVlbiB0cmFuc2xhdGVkIHRvIHNvbWV0aGluZyBlbHNlIGluIHRoZSBjdXJyZW50CiAgICAgICAgICAgICAgICAvL3Njb3BlIChieSBMYW1iZGFUb01ldGhvZCkKICAgICAgICAgICAgICAgIFN5bWJvbCB0cmFuc2xhdGVkU3ltID0gbGFtYmRhVHJhbnNsYXRpb25NYXAuZ2V0KHN5bSk7CiAgICAgICAgICAgICAgICBpZiAodHJhbnNsYXRlZFN5bSAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgdHJlZSA9IG1ha2UuYXQodHJlZS5wb3MpLklkZW50KHRyYW5zbGF0ZWRTeW0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiB0cmVlOwogICAgfQoKICAgIC8qKiBFbnN1cmUgdGhhdCBpZGVudGlmaWVyIGlzIGFjY2Vzc2libGUsIHJldHVybiB0cmVlIGFjY2Vzc2luZyB0aGUgaWRlbnRpZmllci4KICAgICAqICBAcGFyYW0gdHJlZSAgICAgVGhlIGlkZW50aWZpZXIgdHJlZS4KICAgICAqLwogICAgSkNFeHByZXNzaW9uIGFjY2VzcyhKQ0V4cHJlc3Npb24gdHJlZSkgewogICAgICAgIFN5bWJvbCBzeW0gPSBUcmVlSW5mby5zeW1ib2wodHJlZSk7CiAgICAgICAgcmV0dXJuIHN5bSA9PSBudWxsID8gdHJlZSA6IGFjY2VzcyhzeW0sIHRyZWUsIG51bGwsIGZhbHNlKTsKICAgIH0KCiAgICAvKiogUmV0dXJuIGFjY2VzcyBjb25zdHJ1Y3RvciBmb3IgYSBwcml2YXRlIGNvbnN0cnVjdG9yLAogICAgICogIG9yIHRoZSBjb25zdHJ1Y3RvciBpdHNlbGYsIGlmIG5vIGFjY2VzcyBjb25zdHJ1Y3RvciBpcyBuZWVkZWQuCiAgICAgKiAgQHBhcmFtIHBvcyAgICAgICBUaGUgcG9zaXRpb24gdG8gcmVwb3J0IGRpYWdub3N0aWNzLCBpZiBhbnkuCiAgICAgKiAgQHBhcmFtIGNvbnN0ciAgICBUaGUgcHJpdmF0ZSBjb25zdHJ1Y3Rvci4KICAgICAqLwogICAgU3ltYm9sIGFjY2Vzc0NvbnN0cnVjdG9yKERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIFN5bWJvbCBjb25zdHIpIHsKICAgICAgICBpZiAobmVlZHNQcml2YXRlQWNjZXNzKGNvbnN0cikpIHsKICAgICAgICAgICAgQ2xhc3NTeW1ib2wgYWNjT3duZXIgPSBjb25zdHIub3duZXIuZW5jbENsYXNzKCk7CiAgICAgICAgICAgIE1ldGhvZFN5bWJvbCBhY29uc3RyID0gYWNjZXNzQ29uc3Rycy5nZXQoY29uc3RyKTsKICAgICAgICAgICAgaWYgKGFjb25zdHIgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgTGlzdDxUeXBlPiBhcmd0eXBlcyA9IGNvbnN0ci50eXBlLmdldFBhcmFtZXRlclR5cGVzKCk7CiAgICAgICAgICAgICAgICBpZiAoKGFjY093bmVyLmZsYWdzX2ZpZWxkICYgRU5VTSkgIT0gMCkKICAgICAgICAgICAgICAgICAgICBhcmd0eXBlcyA9IGFyZ3R5cGVzCiAgICAgICAgICAgICAgICAgICAgICAgIC5wcmVwZW5kKHN5bXMuaW50VHlwZSkKICAgICAgICAgICAgICAgICAgICAgICAgLnByZXBlbmQoc3ltcy5zdHJpbmdUeXBlKTsKICAgICAgICAgICAgICAgIGFjb25zdHIgPSBuZXcgTWV0aG9kU3ltYm9sKAogICAgICAgICAgICAgICAgICAgIFNZTlRIRVRJQywKICAgICAgICAgICAgICAgICAgICBuYW1lcy5pbml0LAogICAgICAgICAgICAgICAgICAgIG5ldyBNZXRob2RUeXBlKAogICAgICAgICAgICAgICAgICAgICAgICBhcmd0eXBlcy5hcHBlbmQoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhY2Nlc3NDb25zdHJ1Y3RvclRhZygpLmVyYXN1cmUodHlwZXMpKSwKICAgICAgICAgICAgICAgICAgICAgICAgY29uc3RyLnR5cGUuZ2V0UmV0dXJuVHlwZSgpLAogICAgICAgICAgICAgICAgICAgICAgICBjb25zdHIudHlwZS5nZXRUaHJvd25UeXBlcygpLAogICAgICAgICAgICAgICAgICAgICAgICBzeW1zLm1ldGhvZENsYXNzKSwKICAgICAgICAgICAgICAgICAgICBhY2NPd25lcik7CiAgICAgICAgICAgICAgICBlbnRlclN5bnRoZXRpYyhwb3MsIGFjb25zdHIsIGFjY093bmVyLm1lbWJlcnMoKSk7CiAgICAgICAgICAgICAgICBhY2Nlc3NDb25zdHJzLnB1dChjb25zdHIsIGFjb25zdHIpOwogICAgICAgICAgICAgICAgYWNjZXNzZWQuYXBwZW5kKGNvbnN0cik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGFjb25zdHI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIGNvbnN0cjsKICAgICAgICB9CiAgICB9CgogICAgLyoqIFJldHVybiBhbiBhbm9ueW1vdXMgY2xhc3MgbmVzdGVkIGluIHRoaXMgdG9wbGV2ZWwgY2xhc3MuCiAgICAgKi8KICAgIENsYXNzU3ltYm9sIGFjY2Vzc0NvbnN0cnVjdG9yVGFnKCkgewogICAgICAgIENsYXNzU3ltYm9sIHRvcENsYXNzID0gY3VycmVudENsYXNzLm91dGVybW9zdENsYXNzKCk7CiAgICAgICAgTW9kdWxlU3ltYm9sIHRvcE1vZGxlID0gdG9wQ2xhc3MucGFja2dlKCkubW9kbGU7CiAgICAgICAgTmFtZSBmbGF0bmFtZSA9IG5hbWVzLmZyb21TdHJpbmcoIiIgKyB0b3BDbGFzcy5nZXRRdWFsaWZpZWROYW1lKCkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldC5zeW50aGV0aWNOYW1lQ2hhcigpICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiMSIpOwogICAgICAgIENsYXNzU3ltYm9sIGN0YWcgPSBjaGsuZ2V0Q29tcGlsZWQodG9wTW9kbGUsIGZsYXRuYW1lKTsKICAgICAgICBpZiAoY3RhZyA9PSBudWxsKQogICAgICAgICAgICBjdGFnID0gbWFrZUVtcHR5Q2xhc3MoU1RBVElDIHwgU1lOVEhFVElDLCB0b3BDbGFzcykuc3ltOwogICAgICAgIC8vIGtlZXAgYSByZWNvcmQgb2YgYWxsIHRhZ3MsIHRvIHZlcmlmeSB0aGF0IGFsbCBhcmUgZ2VuZXJhdGVkIGFzIHJlcXVpcmVkCiAgICAgICAgYWNjZXNzQ29uc3RyVGFncyA9IGFjY2Vzc0NvbnN0clRhZ3MucHJlcGVuZChjdGFnKTsKICAgICAgICByZXR1cm4gY3RhZzsKICAgIH0KCiAgICAvKiogQWRkIGFsbCByZXF1aXJlZCBhY2Nlc3MgbWV0aG9kcyBmb3IgYSBwcml2YXRlIHN5bWJvbCB0byBlbmNsb3NpbmcgY2xhc3MuCiAgICAgKiAgQHBhcmFtIHN5bSAgICAgICBUaGUgc3ltYm9sLgogICAgICovCiAgICB2b2lkIG1ha2VBY2Nlc3NpYmxlKFN5bWJvbCBzeW0pIHsKICAgICAgICBKQ0NsYXNzRGVjbCBjZGVmID0gY2xhc3NEZWYoc3ltLm93bmVyLmVuY2xDbGFzcygpKTsKICAgICAgICBpZiAoY2RlZiA9PSBudWxsKSBBc3NlcnQuZXJyb3IoImNsYXNzIGRlZiBub3QgZm91bmQ6ICIgKyBzeW0gKyAiIGluICIgKyBzeW0ub3duZXIpOwogICAgICAgIGlmIChzeW0ubmFtZSA9PSBuYW1lcy5pbml0KSB7CiAgICAgICAgICAgIGNkZWYuZGVmcyA9IGNkZWYuZGVmcy5wcmVwZW5kKAogICAgICAgICAgICAgICAgYWNjZXNzQ29uc3RydWN0b3JEZWYoY2RlZi5wb3MsIHN5bSwgYWNjZXNzQ29uc3Rycy5nZXQoc3ltKSkpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIE1ldGhvZFN5bWJvbFtdIGFjY2Vzc29ycyA9IGFjY2Vzc1N5bXMuZ2V0KHN5bSk7CiAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgQWNjZXNzQ29kZS5udW1iZXJPZkFjY2Vzc0NvZGVzOyBpKyspIHsKICAgICAgICAgICAgICAgIGlmIChhY2Nlc3NvcnNbaV0gIT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICBjZGVmLmRlZnMgPSBjZGVmLmRlZnMucHJlcGVuZCgKICAgICAgICAgICAgICAgICAgICAgICAgYWNjZXNzRGVmKGNkZWYucG9zLCBzeW0sIGFjY2Vzc29yc1tpXSwgaSkpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKiBDb25zdHJ1Y3QgZGVmaW5pdGlvbiBvZiBhbiBhY2Nlc3MgbWV0aG9kLgogICAgICogIEBwYXJhbSBwb3MgICAgICAgIFRoZSBzb3VyY2UgY29kZSBwb3NpdGlvbiBvZiB0aGUgZGVmaW5pdGlvbi4KICAgICAqICBAcGFyYW0gdnN5bSAgICAgICBUaGUgcHJpdmF0ZSBvciBwcm90ZWN0ZWQgc3ltYm9sLgogICAgICogIEBwYXJhbSBhY2Nlc3NvciAgIFRoZSBhY2Nlc3MgbWV0aG9kIGZvciB0aGUgc3ltYm9sLgogICAgICogIEBwYXJhbSBhY29kZSAgICAgIFRoZSBhY2Nlc3MgY29kZS4KICAgICAqLwogICAgSkNUcmVlIGFjY2Vzc0RlZihpbnQgcG9zLCBTeW1ib2wgdnN5bSwgTWV0aG9kU3ltYm9sIGFjY2Vzc29yLCBpbnQgYWNvZGUpIHsKLy8gICAgICBTeXN0ZW0uZXJyLnByaW50bG4oImFjY2VzcyAiICsgdnN5bSArICIgd2l0aCAiICsgYWNjZXNzb3IpOy8vREVCVUcKICAgICAgICBjdXJyZW50Q2xhc3MgPSB2c3ltLm93bmVyLmVuY2xDbGFzcygpOwogICAgICAgIG1ha2UuYXQocG9zKTsKICAgICAgICBKQ01ldGhvZERlY2wgbWQgPSBtYWtlLk1ldGhvZERlZihhY2Nlc3NvciwgbnVsbCk7CgogICAgICAgIC8vIEZpbmQgYWN0dWFsIHN5bWJvbAogICAgICAgIFN5bWJvbCBzeW0gPSBhY3R1YWxTeW1ib2xzLmdldCh2c3ltKTsKICAgICAgICBpZiAoc3ltID09IG51bGwpIHN5bSA9IHZzeW07CgogICAgICAgIEpDRXhwcmVzc2lvbiByZWY7ICAgICAgICAgICAvLyBUaGUgdHJlZSByZWZlcmVuY2luZyB0aGUgcHJpdmF0ZSBzeW1ib2wuCiAgICAgICAgTGlzdDxKQ0V4cHJlc3Npb24+IGFyZ3M7ICAgIC8vIEFueSBhZGRpdGlvbmFsIGFyZ3VtZW50cyB0byBiZSBwYXNzZWQgYWxvbmcuCiAgICAgICAgaWYgKChzeW0uZmxhZ3MoKSAmIFNUQVRJQykgIT0gMCkgewogICAgICAgICAgICByZWYgPSBtYWtlLklkZW50KHN5bSk7CiAgICAgICAgICAgIGFyZ3MgPSBtYWtlLklkZW50cyhtZC5wYXJhbXMpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIEpDRXhwcmVzc2lvbiBzaXRlID0gbWFrZS5JZGVudChtZC5wYXJhbXMuaGVhZCk7CiAgICAgICAgICAgIGlmIChhY29kZSAlIDIgIT0gMCkgewogICAgICAgICAgICAgICAgLy9vZGQgYWNjZXNzIGNvZGVzIHJlcHJlc2VudCBxdWFsaWZpZWQgc3VwZXIgYWNjZXNzZXMgLSBuZWVkIHRvCiAgICAgICAgICAgICAgICAvL2VtaXQgcmVmZXJlbmNlIHRvIHRoZSBkaXJlY3Qgc3VwZXJjbGFzcywgZXZlbiBpZiB0aGUgcmVmZXJlZAogICAgICAgICAgICAgICAgLy9tZW1iZXIgaXMgZnJvbSBhbiBpbmRpcmVjdCBzdXBlcmNsYXNzIChKTFMgMTMuMSkKICAgICAgICAgICAgICAgIHNpdGUuc2V0VHlwZSh0eXBlcy5lcmFzdXJlKHR5cGVzLnN1cGVydHlwZSh2c3ltLm93bmVyLmVuY2xDbGFzcygpLnR5cGUpKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmVmID0gbWFrZS5TZWxlY3Qoc2l0ZSwgc3ltKTsKICAgICAgICAgICAgYXJncyA9IG1ha2UuSWRlbnRzKG1kLnBhcmFtcy50YWlsKTsKICAgICAgICB9CiAgICAgICAgSkNTdGF0ZW1lbnQgc3RhdDsgICAgICAgICAgLy8gVGhlIHN0YXRlbWVudCBhY2Nlc3NpbmcgdGhlIHByaXZhdGUgc3ltYm9sLgogICAgICAgIGlmIChzeW0ua2luZCA9PSBWQVIpIHsKICAgICAgICAgICAgLy8gTm9ybWFsaXplIG91dCBhbGwgb2RkIGFjY2VzcyBjb2RlcyBieSB0YWtpbmcgZmxvb3IgbW9kdWxvIDI6CiAgICAgICAgICAgIGludCBhY29kZTEgPSBhY29kZSAtIChhY29kZSAmIDEpOwoKICAgICAgICAgICAgSkNFeHByZXNzaW9uIGV4cHI7ICAgICAgLy8gVGhlIGFjY2VzcyBtZXRob2QncyByZXR1cm4gdmFsdWUuCiAgICAgICAgICAgIEFjY2Vzc0NvZGUgYUNvZGUgPSBBY2Nlc3NDb2RlLmdldEZyb21Db2RlKGFjb2RlMSk7CiAgICAgICAgICAgIHN3aXRjaCAoYUNvZGUpIHsKICAgICAgICAgICAgY2FzZSBERVJFRjoKICAgICAgICAgICAgICAgIGV4cHIgPSByZWY7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBBU1NJR046CiAgICAgICAgICAgICAgICBleHByID0gbWFrZS5Bc3NpZ24ocmVmLCBhcmdzLmhlYWQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgUFJFSU5DOiBjYXNlIFBPU1RJTkM6IGNhc2UgUFJFREVDOiBjYXNlIFBPU1RERUM6CiAgICAgICAgICAgICAgICBleHByID0gbWFrZVVuYXJ5KGFDb2RlLnRhZywgcmVmKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgZXhwciA9IG1ha2UuQXNzaWdub3AoCiAgICAgICAgICAgICAgICAgICAgdHJlZVRhZyhiaW5hcnlBY2Nlc3NPcGVyYXRvcihhY29kZTEsIEpDVHJlZS5UYWcuTk9fVEFHKSksIHJlZiwgYXJncy5oZWFkKTsKICAgICAgICAgICAgICAgICgoSkNBc3NpZ25PcCkgZXhwcikub3BlcmF0b3IgPSBiaW5hcnlBY2Nlc3NPcGVyYXRvcihhY29kZTEsIEpDVHJlZS5UYWcuTk9fVEFHKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBzdGF0ID0gbWFrZS5SZXR1cm4oZXhwci5zZXRUeXBlKHN5bS50eXBlKSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc3RhdCA9IG1ha2UuQ2FsbChtYWtlLkFwcChyZWYsIGFyZ3MpKTsKICAgICAgICB9CiAgICAgICAgbWQuYm9keSA9IG1ha2UuQmxvY2soMCwgTGlzdC5vZihzdGF0KSk7CgogICAgICAgIC8vIE1ha2Ugc3VyZSBhbGwgcGFyYW1ldGVycywgcmVzdWx0IHR5cGVzIGFuZCB0aHJvd24gZXhjZXB0aW9ucwogICAgICAgIC8vIGFyZSBhY2Nlc3NpYmxlLgogICAgICAgIGZvciAoTGlzdDxKQ1ZhcmlhYmxlRGVjbD4gbCA9IG1kLnBhcmFtczsgbC5ub25FbXB0eSgpOyBsID0gbC50YWlsKQogICAgICAgICAgICBsLmhlYWQudmFydHlwZSA9IGFjY2VzcyhsLmhlYWQudmFydHlwZSk7CiAgICAgICAgbWQucmVzdHlwZSA9IGFjY2VzcyhtZC5yZXN0eXBlKTsKICAgICAgICBmb3IgKExpc3Q8SkNFeHByZXNzaW9uPiBsID0gbWQudGhyb3duOyBsLm5vbkVtcHR5KCk7IGwgPSBsLnRhaWwpCiAgICAgICAgICAgIGwuaGVhZCA9IGFjY2VzcyhsLmhlYWQpOwoKICAgICAgICByZXR1cm4gbWQ7CiAgICB9CgogICAgLyoqIENvbnN0cnVjdCBkZWZpbml0aW9uIG9mIGFuIGFjY2VzcyBjb25zdHJ1Y3Rvci4KICAgICAqICBAcGFyYW0gcG9zICAgICAgICBUaGUgc291cmNlIGNvZGUgcG9zaXRpb24gb2YgdGhlIGRlZmluaXRpb24uCiAgICAgKiAgQHBhcmFtIGNvbnN0ciAgICAgVGhlIHByaXZhdGUgY29uc3RydWN0b3IuCiAgICAgKiAgQHBhcmFtIGFjY2Vzc29yICAgVGhlIGFjY2VzcyBtZXRob2QgZm9yIHRoZSBjb25zdHJ1Y3Rvci4KICAgICAqLwogICAgSkNUcmVlIGFjY2Vzc0NvbnN0cnVjdG9yRGVmKGludCBwb3MsIFN5bWJvbCBjb25zdHIsIE1ldGhvZFN5bWJvbCBhY2Nlc3NvcikgewogICAgICAgIG1ha2UuYXQocG9zKTsKICAgICAgICBKQ01ldGhvZERlY2wgbWQgPSBtYWtlLk1ldGhvZERlZihhY2Nlc3NvciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhY2Nlc3Nvci5leHRlcm5hbFR5cGUodHlwZXMpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwpOwogICAgICAgIEpDSWRlbnQgY2FsbGVlID0gbWFrZS5JZGVudChuYW1lcy5fdGhpcyk7CiAgICAgICAgY2FsbGVlLnN5bSA9IGNvbnN0cjsKICAgICAgICBjYWxsZWUudHlwZSA9IGNvbnN0ci50eXBlOwogICAgICAgIG1kLmJvZHkgPQogICAgICAgICAgICBtYWtlLkJsb2NrKDAsIExpc3Qub2YoCiAgICAgICAgICAgICAgICBtYWtlLkNhbGwoCiAgICAgICAgICAgICAgICAgICAgbWFrZS5BcHAoCiAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxlZSwKICAgICAgICAgICAgICAgICAgICAgICAgbWFrZS5JZGVudHMobWQucGFyYW1zLnJldmVyc2UoKS50YWlsLnJldmVyc2UoKSkpKSkpOwogICAgICAgIHJldHVybiBtZDsKICAgIH0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBGcmVlIHZhcmlhYmxlcyBwcm94aWVzIGFuZCB0aGlzJG4KICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgogICAgLyoqIEEgc2NvcGUgY29udGFpbmluZyBhbGwgZnJlZSB2YXJpYWJsZSBwcm94aWVzIGZvciBjdXJyZW50bHkgdHJhbnNsYXRlZAogICAgICogIGNsYXNzLCBhcyB3ZWxsIGFzIGl0cyB0aGlzJG4gc3ltYm9sIChpZiBuZWVkZWQpLgogICAgICogIFByb3h5IHNjb3BlcyBhcmUgbmVzdGVkIGluIHRoZSBzYW1lIHdheSBjbGFzc2VzIGFyZS4KICAgICAqICBJbnNpZGUgYSBjb25zdHJ1Y3RvciwgcHJveGllcyBhbmQgYW55IHRoaXMkbiBzeW1ib2wgYXJlIGR1cGxpY2F0ZWQKICAgICAqICBpbiBhbiBhZGRpdGlvbmFsIGlubmVybW9zdCBzY29wZSwgd2hlcmUgdGhleSByZXByZXNlbnQgdGhlIGNvbnN0cnVjdG9yCiAgICAgKiAgcGFyYW1ldGVycy4KICAgICAqLwogICAgV3JpdGVhYmxlU2NvcGUgcHJveGllczsKCiAgICAvKiogQSBzY29wZSBjb250YWluaW5nIGFsbCB1bm5hbWVkIHJlc291cmNlIHZhcmlhYmxlcy9zYXZlZAogICAgICogIGV4Y2VwdGlvbiB2YXJpYWJsZXMgZm9yIHRyYW5zbGF0ZWQgVFdSIGJsb2NrcwogICAgICovCiAgICBXcml0ZWFibGVTY29wZSB0d3JWYXJzOwoKICAgIC8qKiBBIHN0YWNrIGNvbnRhaW5pbmcgdGhlIHRoaXMkbiBmaWVsZCBvZiB0aGUgY3VycmVudGx5IHRyYW5zbGF0ZWQKICAgICAqICBjbGFzc2VzIChpZiBuZWVkZWQpIGluIGlubmVybW9zdCBmaXJzdCBvcmRlci4KICAgICAqICBJbnNpZGUgYSBjb25zdHJ1Y3RvciwgcHJveGllcyBhbmQgYW55IHRoaXMkbiBzeW1ib2wgYXJlIGR1cGxpY2F0ZWQKICAgICAqICBpbiBhbiBhZGRpdGlvbmFsIGlubmVybW9zdCBzY29wZSwgd2hlcmUgdGhleSByZXByZXNlbnQgdGhlIGNvbnN0cnVjdG9yCiAgICAgKiAgcGFyYW1ldGVycy4KICAgICAqLwogICAgTGlzdDxWYXJTeW1ib2w+IG91dGVyVGhpc1N0YWNrOwoKICAgIC8qKiBUaGUgbmFtZSBvZiBhIGZyZWUgdmFyaWFibGUgcHJveHkuCiAgICAgKi8KICAgIE5hbWUgcHJveHlOYW1lKE5hbWUgbmFtZSkgewogICAgICAgIHJldHVybiBuYW1lcy5mcm9tU3RyaW5nKCJ2YWwiICsgdGFyZ2V0LnN5bnRoZXRpY05hbWVDaGFyKCkgKyBuYW1lKTsKICAgIH0KCiAgICAvKiogUHJveHkgZGVmaW5pdGlvbnMgZm9yIGFsbCBmcmVlIHZhcmlhYmxlcyBpbiBnaXZlbiBsaXN0LCBpbiByZXZlcnNlIG9yZGVyLgogICAgICogIEBwYXJhbSBwb3MgICAgICAgIFRoZSBzb3VyY2UgY29kZSBwb3NpdGlvbiBvZiB0aGUgZGVmaW5pdGlvbi4KICAgICAqICBAcGFyYW0gZnJlZXZhcnMgICBUaGUgZnJlZSB2YXJpYWJsZXMuCiAgICAgKiAgQHBhcmFtIG93bmVyICAgICAgVGhlIGNsYXNzIGluIHdoaWNoIHRoZSBkZWZpbml0aW9ucyBnby4KICAgICAqLwogICAgTGlzdDxKQ1ZhcmlhYmxlRGVjbD4gZnJlZXZhckRlZnMoaW50IHBvcywgTGlzdDxWYXJTeW1ib2w+IGZyZWV2YXJzLCBTeW1ib2wgb3duZXIpIHsKICAgICAgICByZXR1cm4gZnJlZXZhckRlZnMocG9zLCBmcmVldmFycywgb3duZXIsIDApOwogICAgfQoKICAgIExpc3Q8SkNWYXJpYWJsZURlY2w+IGZyZWV2YXJEZWZzKGludCBwb3MsIExpc3Q8VmFyU3ltYm9sPiBmcmVldmFycywgU3ltYm9sIG93bmVyLAogICAgICAgICAgICBsb25nIGFkZGl0aW9uYWxGbGFncykgewogICAgICAgIGxvbmcgZmxhZ3MgPSBGSU5BTCB8IFNZTlRIRVRJQyB8IGFkZGl0aW9uYWxGbGFnczsKICAgICAgICBMaXN0PEpDVmFyaWFibGVEZWNsPiBkZWZzID0gTGlzdC5uaWwoKTsKICAgICAgICBmb3IgKExpc3Q8VmFyU3ltYm9sPiBsID0gZnJlZXZhcnM7IGwubm9uRW1wdHkoKTsgbCA9IGwudGFpbCkgewogICAgICAgICAgICBWYXJTeW1ib2wgdiA9IGwuaGVhZDsKICAgICAgICAgICAgVmFyU3ltYm9sIHByb3h5ID0gbmV3IFZhclN5bWJvbCgKICAgICAgICAgICAgICAgIGZsYWdzLCBwcm94eU5hbWUodi5uYW1lKSwgdi5lcmFzdXJlKHR5cGVzKSwgb3duZXIpOwogICAgICAgICAgICBwcm94aWVzLmVudGVyKHByb3h5KTsKICAgICAgICAgICAgSkNWYXJpYWJsZURlY2wgdmQgPSBtYWtlLmF0KHBvcykuVmFyRGVmKHByb3h5LCBudWxsKTsKICAgICAgICAgICAgdmQudmFydHlwZSA9IGFjY2Vzcyh2ZC52YXJ0eXBlKTsKICAgICAgICAgICAgZGVmcyA9IGRlZnMucHJlcGVuZCh2ZCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBkZWZzOwogICAgfQoKICAgIC8qKiBUaGUgbmFtZSBvZiBhIHRoaXMkbiBmaWVsZAogICAgICogIEBwYXJhbSB0eXBlICAgVGhlIGNsYXNzIHJlZmVyZW5jZWQgYnkgdGhlIHRoaXMkbiBmaWVsZAogICAgICovCiAgICBOYW1lIG91dGVyVGhpc05hbWUoVHlwZSB0eXBlLCBTeW1ib2wgb3duZXIpIHsKICAgICAgICBUeXBlIHQgPSB0eXBlLmdldEVuY2xvc2luZ1R5cGUoKTsKICAgICAgICBpbnQgbmVzdGluZ0xldmVsID0gMDsKICAgICAgICB3aGlsZSAodC5oYXNUYWcoQ0xBU1MpKSB7CiAgICAgICAgICAgIHQgPSB0LmdldEVuY2xvc2luZ1R5cGUoKTsKICAgICAgICAgICAgbmVzdGluZ0xldmVsKys7CiAgICAgICAgfQogICAgICAgIE5hbWUgcmVzdWx0ID0gbmFtZXMuZnJvbVN0cmluZygidGhpcyIgKyB0YXJnZXQuc3ludGhldGljTmFtZUNoYXIoKSArIG5lc3RpbmdMZXZlbCk7CiAgICAgICAgd2hpbGUgKG93bmVyLmtpbmQgPT0gVFlQICYmICgoQ2xhc3NTeW1ib2wpb3duZXIpLm1lbWJlcnMoKS5maW5kRmlyc3QocmVzdWx0KSAhPSBudWxsKQogICAgICAgICAgICByZXN1bHQgPSBuYW1lcy5mcm9tU3RyaW5nKHJlc3VsdC50b1N0cmluZygpICsgdGFyZ2V0LnN5bnRoZXRpY05hbWVDaGFyKCkpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9CgogICAgcHJpdmF0ZSBWYXJTeW1ib2wgbWFrZU91dGVyVGhpc1ZhclN5bWJvbChTeW1ib2wgb3duZXIsIGxvbmcgZmxhZ3MpIHsKICAgICAgICBUeXBlIHRhcmdldCA9IHR5cGVzLmVyYXN1cmUob3duZXIuZW5jbENsYXNzKCkudHlwZS5nZXRFbmNsb3NpbmdUeXBlKCkpOwogICAgICAgIFZhclN5bWJvbCBvdXRlclRoaXMgPQogICAgICAgICAgICBuZXcgVmFyU3ltYm9sKGZsYWdzLCBvdXRlclRoaXNOYW1lKHRhcmdldCwgb3duZXIpLCB0YXJnZXQsIG93bmVyKTsKICAgICAgICBvdXRlclRoaXNTdGFjayA9IG91dGVyVGhpc1N0YWNrLnByZXBlbmQob3V0ZXJUaGlzKTsKICAgICAgICByZXR1cm4gb3V0ZXJUaGlzOwogICAgfQoKICAgIHByaXZhdGUgSkNWYXJpYWJsZURlY2wgbWFrZU91dGVyVGhpc1ZhckRlY2woaW50IHBvcywgVmFyU3ltYm9sIHN5bSkgewogICAgICAgIEpDVmFyaWFibGVEZWNsIHZkID0gbWFrZS5hdChwb3MpLlZhckRlZihzeW0sIG51bGwpOwogICAgICAgIHZkLnZhcnR5cGUgPSBhY2Nlc3ModmQudmFydHlwZSk7CiAgICAgICAgcmV0dXJuIHZkOwogICAgfQoKICAgIC8qKiBEZWZpbml0aW9uIGZvciB0aGlzJG4gZmllbGQuCiAgICAgKiAgQHBhcmFtIHBvcyAgICAgICAgVGhlIHNvdXJjZSBjb2RlIHBvc2l0aW9uIG9mIHRoZSBkZWZpbml0aW9uLgogICAgICogIEBwYXJhbSBvd25lciAgICAgIFRoZSBtZXRob2QgaW4gd2hpY2ggdGhlIGRlZmluaXRpb24gZ29lcy4KICAgICAqLwogICAgSkNWYXJpYWJsZURlY2wgb3V0ZXJUaGlzRGVmKGludCBwb3MsIE1ldGhvZFN5bWJvbCBvd25lcikgewogICAgICAgIENsYXNzU3ltYm9sIGMgPSBvd25lci5lbmNsQ2xhc3MoKTsKICAgICAgICBib29sZWFuIGlzTWFuZGF0ZWQgPQogICAgICAgICAgICAvLyBBbm9ueW1vdXMgY29uc3RydWN0b3JzCiAgICAgICAgICAgIChvd25lci5pc0NvbnN0cnVjdG9yKCkgJiYgb3duZXIuaXNBbm9ueW1vdXMoKSkgfHwKICAgICAgICAgICAgLy8gQ29uc3RydWN0b3JzIG9mIG5vbi1wcml2YXRlIGlubmVyIG1lbWJlciBjbGFzc2VzCiAgICAgICAgICAgIChvd25lci5pc0NvbnN0cnVjdG9yKCkgJiYgYy5pc0lubmVyKCkgJiYKICAgICAgICAgICAgICFjLmlzUHJpdmF0ZSgpICYmICFjLmlzU3RhdGljKCkpOwogICAgICAgIGxvbmcgZmxhZ3MgPQogICAgICAgICAgICBGSU5BTCB8IChpc01hbmRhdGVkID8gTUFOREFURUQgOiBTWU5USEVUSUMpIHwgUEFSQU1FVEVSOwogICAgICAgIFZhclN5bWJvbCBvdXRlclRoaXMgPSBtYWtlT3V0ZXJUaGlzVmFyU3ltYm9sKG93bmVyLCBmbGFncyk7CiAgICAgICAgb3duZXIuZXh0cmFQYXJhbXMgPSBvd25lci5leHRyYVBhcmFtcy5wcmVwZW5kKG91dGVyVGhpcyk7CiAgICAgICAgcmV0dXJuIG1ha2VPdXRlclRoaXNWYXJEZWNsKHBvcywgb3V0ZXJUaGlzKTsKICAgIH0KCiAgICAvKiogRGVmaW5pdGlvbiBmb3IgdGhpcyRuIGZpZWxkLgogICAgICogIEBwYXJhbSBwb3MgICAgICAgIFRoZSBzb3VyY2UgY29kZSBwb3NpdGlvbiBvZiB0aGUgZGVmaW5pdGlvbi4KICAgICAqICBAcGFyYW0gb3duZXIgICAgICBUaGUgY2xhc3MgaW4gd2hpY2ggdGhlIGRlZmluaXRpb24gZ29lcy4KICAgICAqLwogICAgSkNWYXJpYWJsZURlY2wgb3V0ZXJUaGlzRGVmKGludCBwb3MsIENsYXNzU3ltYm9sIG93bmVyKSB7CiAgICAgICAgVmFyU3ltYm9sIG91dGVyVGhpcyA9IG1ha2VPdXRlclRoaXNWYXJTeW1ib2wob3duZXIsIEZJTkFMIHwgU1lOVEhFVElDKTsKICAgICAgICByZXR1cm4gbWFrZU91dGVyVGhpc1ZhckRlY2wocG9zLCBvdXRlclRoaXMpOwogICAgfQoKICAgIC8qKiBSZXR1cm4gYSBsaXN0IG9mIHRyZWVzIHRoYXQgbG9hZCB0aGUgZnJlZSB2YXJpYWJsZXMgaW4gZ2l2ZW4gbGlzdCwKICAgICAqICBpbiByZXZlcnNlIG9yZGVyLgogICAgICogIEBwYXJhbSBwb3MgICAgICAgICAgVGhlIHNvdXJjZSBjb2RlIHBvc2l0aW9uIHRvIGJlIHVzZWQgZm9yIHRoZSB0cmVlcy4KICAgICAqICBAcGFyYW0gZnJlZXZhcnMgICAgIFRoZSBsaXN0IG9mIGZyZWUgdmFyaWFibGVzLgogICAgICovCiAgICBMaXN0PEpDRXhwcmVzc2lvbj4gbG9hZEZyZWV2YXJzKERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIExpc3Q8VmFyU3ltYm9sPiBmcmVldmFycykgewogICAgICAgIExpc3Q8SkNFeHByZXNzaW9uPiBhcmdzID0gTGlzdC5uaWwoKTsKICAgICAgICBmb3IgKExpc3Q8VmFyU3ltYm9sPiBsID0gZnJlZXZhcnM7IGwubm9uRW1wdHkoKTsgbCA9IGwudGFpbCkKICAgICAgICAgICAgYXJncyA9IGFyZ3MucHJlcGVuZChsb2FkRnJlZXZhcihwb3MsIGwuaGVhZCkpOwogICAgICAgIHJldHVybiBhcmdzOwogICAgfQovL3doZXJlCiAgICAgICAgSkNFeHByZXNzaW9uIGxvYWRGcmVldmFyKERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIFZhclN5bWJvbCB2KSB7CiAgICAgICAgICAgIHJldHVybiBhY2Nlc3ModiwgbWFrZS5hdChwb3MpLklkZW50KHYpLCBudWxsLCBmYWxzZSk7CiAgICAgICAgfQoKICAgIC8qKiBDb25zdHJ1Y3QgYSB0cmVlIHNpbXVsYXRpbmcgdGhlIGV4cHJlc3Npb24ge0Bjb2RlIEMudGhpc30uCiAgICAgKiAgQHBhcmFtIHBvcyAgICAgICAgICAgVGhlIHNvdXJjZSBjb2RlIHBvc2l0aW9uIHRvIGJlIHVzZWQgZm9yIHRoZSB0cmVlLgogICAgICogIEBwYXJhbSBjICAgICAgICAgICAgIFRoZSBxdWFsaWZpZXIgY2xhc3MuCiAgICAgKi8KICAgIEpDRXhwcmVzc2lvbiBtYWtlVGhpcyhEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBUeXBlU3ltYm9sIGMpIHsKICAgICAgICBpZiAoY3VycmVudENsYXNzID09IGMpIHsKICAgICAgICAgICAgLy8gaW4gdGhpcyBjYXNlLCBgdGhpcycgd29ya3MgZmluZQogICAgICAgICAgICByZXR1cm4gbWFrZS5hdChwb3MpLlRoaXMoYy5lcmFzdXJlKHR5cGVzKSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLy8gbmVlZCB0byBnbyB2aWEgdGhpcyRuCiAgICAgICAgICAgIHJldHVybiBtYWtlT3V0ZXJUaGlzKHBvcywgYyk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogT3B0aW9uYWxseSByZXBsYWNlIGEgdHJ5IHN0YXRlbWVudCB3aXRoIHRoZSBkZXN1Z2FyaW5nIG9mIGEKICAgICAqIHRyeS13aXRoLXJlc291cmNlcyBzdGF0ZW1lbnQuICBUaGUgY2Fub25pY2FsIGRlc3VnYXJpbmcgb2YKICAgICAqCiAgICAgKiB0cnkgUmVzb3VyY2VTcGVjaWZpY2F0aW9uCiAgICAgKiAgIEJsb2NrCiAgICAgKgogICAgICogaXMKICAgICAqCiAgICAgKiB7CiAgICAgKiAgIGZpbmFsIFZhcmlhYmxlTW9kaWZpZXJzX21pbnVzX2ZpbmFsIFIgI3Jlc291cmNlID0gRXhwcmVzc2lvbjsKICAgICAqICAgVGhyb3dhYmxlICNwcmltYXJ5RXhjZXB0aW9uID0gbnVsbDsKICAgICAqCiAgICAgKiAgIHRyeSBSZXNvdXJjZVNwZWNpZmljYXRpb250YWlsCiAgICAgKiAgICAgQmxvY2sKICAgICAqICAgY2F0Y2ggKFRocm93YWJsZSAjdCkgewogICAgICogICAgICNwcmltYXJ5RXhjZXB0aW9uID0gdDsKICAgICAqICAgICB0aHJvdyAjdDsKICAgICAqICAgfSBmaW5hbGx5IHsKICAgICAqICAgICBpZiAoI3Jlc291cmNlICE9IG51bGwpIHsKICAgICAqICAgICAgIGlmICgjcHJpbWFyeUV4Y2VwdGlvbiAhPSBudWxsKSB7CiAgICAgKiAgICAgICAgIHRyeSB7CiAgICAgKiAgICAgICAgICAgI3Jlc291cmNlLmNsb3NlKCk7CiAgICAgKiAgICAgICAgIH0gY2F0Y2goVGhyb3dhYmxlICNzdXBwcmVzc2VkRXhjZXB0aW9uKSB7CiAgICAgKiAgICAgICAgICAgI3ByaW1hcnlFeGNlcHRpb24uYWRkU3VwcHJlc3NlZCgjc3VwcHJlc3NlZEV4Y2VwdGlvbik7CiAgICAgKiAgICAgICAgIH0KICAgICAqICAgICAgIH0gZWxzZSB7CiAgICAgKiAgICAgICAgICNyZXNvdXJjZS5jbG9zZSgpOwogICAgICogICAgICAgfQogICAgICogICAgIH0KICAgICAqICAgfQogICAgICoKICAgICAqIEBwYXJhbSB0cmVlICBUaGUgdHJ5IHN0YXRlbWVudCB0byBpbnNwZWN0LgogICAgICogQHJldHVybiBBIGEgZGVzdWdhcmVkIHRyeS13aXRoLXJlc291cmNlcyB0cmVlLCBvciB0aGUgb3JpZ2luYWwKICAgICAqIHRyeSBibG9jayBpZiB0aGVyZSBhcmUgbm8gcmVzb3VyY2VzIHRvIG1hbmFnZS4KICAgICAqLwogICAgSkNUcmVlIG1ha2VUd3JUcnkoSkNUcnkgdHJlZSkgewogICAgICAgIG1ha2VfYXQodHJlZS5wb3MoKSk7CiAgICAgICAgdHdyVmFycyA9IHR3clZhcnMuZHVwKCk7CiAgICAgICAgSkNCbG9jayB0d3JCbG9jayA9IG1ha2VUd3JCbG9jayh0cmVlLnJlc291cmNlcywgdHJlZS5ib2R5LAogICAgICAgICAgICAgICAgdHJlZS5maW5hbGx5Q2FuQ29tcGxldGVOb3JtYWxseSwgMCk7CiAgICAgICAgaWYgKHRyZWUuY2F0Y2hlcnMuaXNFbXB0eSgpICYmIHRyZWUuZmluYWxpemVyID09IG51bGwpCiAgICAgICAgICAgIHJlc3VsdCA9IHRyYW5zbGF0ZSh0d3JCbG9jayk7CiAgICAgICAgZWxzZQogICAgICAgICAgICByZXN1bHQgPSB0cmFuc2xhdGUobWFrZS5UcnkodHdyQmxvY2ssIHRyZWUuY2F0Y2hlcnMsIHRyZWUuZmluYWxpemVyKSk7CiAgICAgICAgdHdyVmFycyA9IHR3clZhcnMubGVhdmUoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgfQoKICAgIHByaXZhdGUgSkNCbG9jayBtYWtlVHdyQmxvY2soTGlzdDxKQ1RyZWU+IHJlc291cmNlcywgSkNCbG9jayBibG9jaywKICAgICAgICAgICAgYm9vbGVhbiBmaW5hbGx5Q2FuQ29tcGxldGVOb3JtYWxseSwgaW50IGRlcHRoKSB7CiAgICAgICAgaWYgKHJlc291cmNlcy5pc0VtcHR5KCkpCiAgICAgICAgICAgIHJldHVybiBibG9jazsKCiAgICAgICAgLy8gQWRkIHJlc291cmNlIGRlY2xhcmF0aW9uIG9yIGV4cHJlc3Npb24gdG8gYmxvY2sgc3RhdGVtZW50cwogICAgICAgIExpc3RCdWZmZXI8SkNTdGF0ZW1lbnQ+IHN0YXRzID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgIEpDVHJlZSByZXNvdXJjZSA9IHJlc291cmNlcy5oZWFkOwogICAgICAgIEpDRXhwcmVzc2lvbiBleHByID0gbnVsbDsKICAgICAgICBib29sZWFuIHJlc291cmNlTm9uTnVsbDsKICAgICAgICBpZiAocmVzb3VyY2UgaW5zdGFuY2VvZiBKQ1ZhcmlhYmxlRGVjbCkgewogICAgICAgICAgICBKQ1ZhcmlhYmxlRGVjbCB2YXIgPSAoSkNWYXJpYWJsZURlY2wpIHJlc291cmNlOwogICAgICAgICAgICBleHByID0gbWFrZS5JZGVudCh2YXIuc3ltKS5zZXRUeXBlKHJlc291cmNlLnR5cGUpOwogICAgICAgICAgICByZXNvdXJjZU5vbk51bGwgPSB2YXIuaW5pdCAhPSBudWxsICYmIFRyZWVJbmZvLnNraXBQYXJlbnModmFyLmluaXQpLmhhc1RhZyhORVdDTEFTUyk7CiAgICAgICAgICAgIHN0YXRzLmFkZCh2YXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIEFzc2VydC5jaGVjayhyZXNvdXJjZSBpbnN0YW5jZW9mIEpDRXhwcmVzc2lvbik7CiAgICAgICAgICAgIFZhclN5bWJvbCBzeW50aGV0aWNUd3JWYXIgPQogICAgICAgICAgICBuZXcgVmFyU3ltYm9sKFNZTlRIRVRJQyB8IEZJTkFMLAogICAgICAgICAgICAgICAgICAgICAgICAgIG1ha2VTeW50aGV0aWNOYW1lKG5hbWVzLmZyb21TdHJpbmcoInR3clZhciIgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVwdGgpLCB0d3JWYXJzKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAocmVzb3VyY2UudHlwZS5oYXNUYWcoQk9UKSkgPwogICAgICAgICAgICAgICAgICAgICAgICAgIHN5bXMuYXV0b0Nsb3NlYWJsZVR5cGUgOiByZXNvdXJjZS50eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRNZXRob2RTeW0pOwogICAgICAgICAgICB0d3JWYXJzLmVudGVyKHN5bnRoZXRpY1R3clZhcik7CiAgICAgICAgICAgIEpDVmFyaWFibGVEZWNsIHN5bnRoZXRpY1R3clZhckRlY2wgPQogICAgICAgICAgICAgICAgbWFrZS5WYXJEZWYoc3ludGhldGljVHdyVmFyLCAoSkNFeHByZXNzaW9uKXJlc291cmNlKTsKICAgICAgICAgICAgZXhwciA9IChKQ0V4cHJlc3Npb24pbWFrZS5JZGVudChzeW50aGV0aWNUd3JWYXIpOwogICAgICAgICAgICByZXNvdXJjZU5vbk51bGwgPSBUcmVlSW5mby5za2lwUGFyZW5zKHJlc291cmNlKS5oYXNUYWcoTkVXQ0xBU1MpOwogICAgICAgICAgICBzdGF0cy5hZGQoc3ludGhldGljVHdyVmFyRGVjbCk7CiAgICAgICAgfQoKICAgICAgICAvLyBBZGQgcHJpbWFyeUV4Y2VwdGlvbiBkZWNsYXJhdGlvbgogICAgICAgIFZhclN5bWJvbCBwcmltYXJ5RXhjZXB0aW9uID0KICAgICAgICAgICAgbmV3IFZhclN5bWJvbChTWU5USEVUSUMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgbWFrZVN5bnRoZXRpY05hbWUobmFtZXMuZnJvbVN0cmluZygicHJpbWFyeUV4Y2VwdGlvbiIgKwogICAgICAgICAgICAgICAgICAgICAgICAgIGRlcHRoKSwgdHdyVmFycyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgc3ltcy50aHJvd2FibGVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRNZXRob2RTeW0pOwogICAgICAgIHR3clZhcnMuZW50ZXIocHJpbWFyeUV4Y2VwdGlvbik7CiAgICAgICAgSkNWYXJpYWJsZURlY2wgcHJpbWFyeUV4Y2VwdGlvblRyZWVEZWNsID0gbWFrZS5WYXJEZWYocHJpbWFyeUV4Y2VwdGlvbiwgbWFrZU51bGwoKSk7CiAgICAgICAgc3RhdHMuYWRkKHByaW1hcnlFeGNlcHRpb25UcmVlRGVjbCk7CgogICAgICAgIC8vIENyZWF0ZSBjYXRjaCBjbGF1c2UgdGhhdCBzYXZlcyBleGNlcHRpb24gYW5kIHRoZW4gcmV0aHJvd3MgaXQKICAgICAgICBWYXJTeW1ib2wgcGFyYW0gPQogICAgICAgICAgICBuZXcgVmFyU3ltYm9sKEZJTkFMfFNZTlRIRVRJQywKICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lcy5mcm9tU3RyaW5nKCJ0IiArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXQuc3ludGhldGljTmFtZUNoYXIoKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgc3ltcy50aHJvd2FibGVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRNZXRob2RTeW0pOwogICAgICAgIEpDVmFyaWFibGVEZWNsIHBhcmFtVHJlZSA9IG1ha2UuVmFyRGVmKHBhcmFtLCBudWxsKTsKICAgICAgICBKQ1N0YXRlbWVudCBhc3NpZ24gPSBtYWtlLkFzc2lnbm1lbnQocHJpbWFyeUV4Y2VwdGlvbiwgbWFrZS5JZGVudChwYXJhbSkpOwogICAgICAgIEpDU3RhdGVtZW50IHJldGhyb3dTdGF0ID0gbWFrZS5UaHJvdyhtYWtlLklkZW50KHBhcmFtKSk7CiAgICAgICAgSkNCbG9jayBjYXRjaEJsb2NrID0gbWFrZS5CbG9jaygwTCwgTGlzdC5vZihhc3NpZ24sIHJldGhyb3dTdGF0KSk7CiAgICAgICAgSkNDYXRjaCBjYXRjaENsYXVzZSA9IG1ha2UuQ2F0Y2gocGFyYW1UcmVlLCBjYXRjaEJsb2NrKTsKCiAgICAgICAgaW50IG9sZFBvcyA9IG1ha2UucG9zOwogICAgICAgIG1ha2UuYXQoVHJlZUluZm8uZW5kUG9zKGJsb2NrKSk7CiAgICAgICAgSkNCbG9jayBmaW5hbGx5Q2xhdXNlID0gbWFrZVR3ckZpbmFsbHlDbGF1c2UocHJpbWFyeUV4Y2VwdGlvbiwgZXhwciwgcmVzb3VyY2VOb25OdWxsKTsKICAgICAgICBtYWtlLmF0KG9sZFBvcyk7CiAgICAgICAgSkNUcnkgb3V0ZXJUcnkgPSBtYWtlLlRyeShtYWtlVHdyQmxvY2socmVzb3VyY2VzLnRhaWwsIGJsb2NrLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbGx5Q2FuQ29tcGxldGVOb3JtYWxseSwgZGVwdGggKyAxKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExpc3Qub2YoY2F0Y2hDbGF1c2UpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxseUNsYXVzZSk7CiAgICAgICAgb3V0ZXJUcnkuZmluYWxseUNhbkNvbXBsZXRlTm9ybWFsbHkgPSBmaW5hbGx5Q2FuQ29tcGxldGVOb3JtYWxseTsKICAgICAgICBzdGF0cy5hZGQob3V0ZXJUcnkpOwogICAgICAgIEpDQmxvY2sgbmV3QmxvY2sgPSBtYWtlLkJsb2NrKDBMLCBzdGF0cy50b0xpc3QoKSk7CiAgICAgICAgcmV0dXJuIG5ld0Jsb2NrOwogICAgfQoKICAgIC8qKklmIHRoZSBlc3RpbWF0ZWQgbnVtYmVyIG9mIGNvcGllcyB0aGUgY2xvc2UgcmVzb3VyY2UgY29kZSBpbiBhIHNpbmdsZSBjbGFzcyBpcyBhYm92ZSB0aGlzCiAgICAgKiB0aHJlc2hvbGQsIGdlbmVyYXRlIGFuZCB1c2UgYSBtZXRob2QgZm9yIHRoZSBjbG9zZSByZXNvdXJjZSBjb2RlLCBsZWFkaW5nIHRvIHNtYWxsZXIgY29kZS4KICAgICAqIEFzIGdlbmVyYXRpbmcgYSBtZXRob2QgaGFzIG92ZXJoZWFkIG9uIGl0cyBvd24sIGdlbmVyYXRpbmcgdGhlIG1ldGhvZCBmb3IgY2FzZXMgYmVsb3cgdGhlCiAgICAgKiB0aHJlc2hvbGQgY291bGQgbGVhZCB0byBhbiBpbmNyZWFzZSBpbiBjb2RlIHNpemUuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFVTRV9DTE9TRV9SRVNPVVJDRV9NRVRIT0RfVEhSRVNIT0xEID0gNDsKCiAgICBwcml2YXRlIEpDQmxvY2sgbWFrZVR3ckZpbmFsbHlDbGF1c2UoU3ltYm9sIHByaW1hcnlFeGNlcHRpb24sIEpDRXhwcmVzc2lvbiByZXNvdXJjZSwKICAgICAgICAgICAgYm9vbGVhbiByZXNvdXJjZU5vbk51bGwpIHsKICAgICAgICBNZXRob2RTeW1ib2wgY2xvc2VSZXNvdXJjZSA9IChNZXRob2RTeW1ib2wpbG9va3VwU3ludGhldGljKGRvbGxhckNsb3NlUmVzb3VyY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50Q2xhc3MubWVtYmVycygpKTsKCiAgICAgICAgaWYgKGNsb3NlUmVzb3VyY2UgPT0gbnVsbCAmJiBzaG91bGRVc2VDbG9zZVJlc291cmNlTWV0aG9kKCkpIHsKICAgICAgICAgICAgY2xvc2VSZXNvdXJjZSA9IG5ldyBNZXRob2RTeW1ib2woCiAgICAgICAgICAgICAgICBQUklWQVRFIHwgU1RBVElDIHwgU1lOVEhFVElDLAogICAgICAgICAgICAgICAgZG9sbGFyQ2xvc2VSZXNvdXJjZSwKICAgICAgICAgICAgICAgIG5ldyBNZXRob2RUeXBlKAogICAgICAgICAgICAgICAgICAgIExpc3Qub2Yoc3ltcy50aHJvd2FibGVUeXBlLCBzeW1zLmF1dG9DbG9zZWFibGVUeXBlKSwKICAgICAgICAgICAgICAgICAgICBzeW1zLnZvaWRUeXBlLAogICAgICAgICAgICAgICAgICAgIExpc3QubmlsKCksCiAgICAgICAgICAgICAgICAgICAgc3ltcy5tZXRob2RDbGFzcyksCiAgICAgICAgICAgICAgICBjdXJyZW50Q2xhc3MpOwogICAgICAgICAgICBlbnRlclN5bnRoZXRpYyhyZXNvdXJjZS5wb3MoKSwgY2xvc2VSZXNvdXJjZSwgY3VycmVudENsYXNzLm1lbWJlcnMoKSk7CgogICAgICAgICAgICBKQ01ldGhvZERlY2wgbWQgPSBtYWtlLk1ldGhvZERlZihjbG9zZVJlc291cmNlLCBudWxsKTsKICAgICAgICAgICAgTGlzdDxKQ1ZhcmlhYmxlRGVjbD4gcGFyYW1zID0gbWQuZ2V0UGFyYW1ldGVycygpOwogICAgICAgICAgICBtZC5ib2R5ID0gbWFrZS5CbG9jaygwLCBMaXN0Lm9mKG1ha2VUd3JDbG9zZVN0YXRlbWVudChwYXJhbXMuZ2V0KDApLnN5bSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ha2UuSWRlbnQocGFyYW1zLmdldCgxKSkpKSk7CgogICAgICAgICAgICBKQ0NsYXNzRGVjbCBjdXJyZW50Q2xhc3NEZWNsID0gY2xhc3NEZWYoY3VycmVudENsYXNzKTsKICAgICAgICAgICAgY3VycmVudENsYXNzRGVjbC5kZWZzID0gY3VycmVudENsYXNzRGVjbC5kZWZzLnByZXBlbmQobWQpOwogICAgICAgIH0KCiAgICAgICAgSkNTdGF0ZW1lbnQgY2xvc2VTdGF0ZW1lbnQ7CgogICAgICAgIGlmIChjbG9zZVJlc291cmNlICE9IG51bGwpIHsKICAgICAgICAgICAgLy8kY2xvc2VSZXNvdXJjZSgjcHJpbWFyeUV4Y2VwdGlvbiwgI3Jlc291cmNlKQogICAgICAgICAgICBjbG9zZVN0YXRlbWVudCA9IG1ha2UuRXhlYyhtYWtlLkFwcGx5KExpc3QubmlsKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFrZS5JZGVudChjbG9zZVJlc291cmNlKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0Lm9mKG1ha2UuSWRlbnQocHJpbWFyeUV4Y2VwdGlvbiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvdXJjZSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkuc2V0VHlwZShzeW1zLnZvaWRUeXBlKSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgY2xvc2VTdGF0ZW1lbnQgPSBtYWtlVHdyQ2xvc2VTdGF0ZW1lbnQocHJpbWFyeUV4Y2VwdGlvbiwgcmVzb3VyY2UpOwogICAgICAgIH0KCiAgICAgICAgSkNTdGF0ZW1lbnQgZmluYWxseVN0YXRlbWVudDsKCiAgICAgICAgaWYgKHJlc291cmNlTm9uTnVsbCkgewogICAgICAgICAgICBmaW5hbGx5U3RhdGVtZW50ID0gY2xvc2VTdGF0ZW1lbnQ7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLy8gaWYgKCNyZXNvdXJjZSAhPSBudWxsKSB7ICRjbG9zZVJlc291cmNlKC4uLik7IH0KICAgICAgICAgICAgZmluYWxseVN0YXRlbWVudCA9IG1ha2UuSWYobWFrZU5vbk51bGxDaGVjayhyZXNvdXJjZSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsb3NlU3RhdGVtZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBtYWtlLkJsb2NrKDBMLAogICAgICAgICAgICAgICAgICAgICAgICAgIExpc3Qub2YoZmluYWxseVN0YXRlbWVudCkpOwogICAgfQogICAgICAgIC8vd2hlcmU6CiAgICAgICAgcHJpdmF0ZSBib29sZWFuIHNob3VsZFVzZUNsb3NlUmVzb3VyY2VNZXRob2QoKSB7CiAgICAgICAgICAgIGNsYXNzIFRyeUZpbmRlciBleHRlbmRzIFRyZWVTY2FubmVyIHsKICAgICAgICAgICAgICAgIGludCBjbG9zZUNvdW50OwogICAgICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdFRyeShKQ1RyeSB0cmVlKSB7CiAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBlbXB0eSA9IHRyZWUuYm9keS5zdGF0cy5pc0VtcHR5KCk7CgogICAgICAgICAgICAgICAgICAgIGZvciAoSkNUcmVlIHIgOiB0cmVlLnJlc291cmNlcykgewogICAgICAgICAgICAgICAgICAgICAgICBjbG9zZUNvdW50ICs9IGVtcHR5ID8gMSA6IDI7CiAgICAgICAgICAgICAgICAgICAgICAgIGVtcHR5ID0gZmFsc2U7IC8vd2l0aCBtdWx0aXBsZSByZXNvdXJjZXMsIG9ubHkgdGhlIGlubmVybW9zdCB0cnkgY2FuIGJlIGVtcHR5LgogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBzdXBlci52aXNpdFRyeSh0cmVlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICAgICAgcHVibGljIHZvaWQgc2NhbihKQ1RyZWUgdHJlZSkgewogICAgICAgICAgICAgICAgICAgIGlmICh1c2VDbG9zZVJlc291cmNlTWV0aG9kKCkpCiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICBzdXBlci5zY2FuKHRyZWUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYm9vbGVhbiB1c2VDbG9zZVJlc291cmNlTWV0aG9kKCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBjbG9zZUNvdW50ID49IFVTRV9DTE9TRV9SRVNPVVJDRV9NRVRIT0RfVEhSRVNIT0xEOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIFRyeUZpbmRlciB0cnlGaW5kZXIgPSBuZXcgVHJ5RmluZGVyKCk7CiAgICAgICAgICAgIHRyeUZpbmRlci5zY2FuKGNsYXNzRGVmKGN1cnJlbnRDbGFzcykpOwogICAgICAgICAgICByZXR1cm4gdHJ5RmluZGVyLnVzZUNsb3NlUmVzb3VyY2VNZXRob2QoKTsKICAgICAgICB9CgogICAgcHJpdmF0ZSBKQ1N0YXRlbWVudCBtYWtlVHdyQ2xvc2VTdGF0ZW1lbnQoU3ltYm9sIHByaW1hcnlFeGNlcHRpb24sIEpDRXhwcmVzc2lvbiByZXNvdXJjZSkgewogICAgICAgIC8vIHByaW1hcnlFeGNlcHRpb24uYWRkU3VwcHJlc3NlZChjYXRjaEV4Y2VwdGlvbik7CiAgICAgICAgVmFyU3ltYm9sIGNhdGNoRXhjZXB0aW9uID0KICAgICAgICAgICAgbmV3IFZhclN5bWJvbChTWU5USEVUSUMsIG1ha2UucGFyYW1OYW1lKDIpLAogICAgICAgICAgICAgICAgICAgICAgICAgIHN5bXMudGhyb3dhYmxlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50TWV0aG9kU3ltKTsKICAgICAgICBKQ1N0YXRlbWVudCBhZGRTdXBwcmVzc2lvblN0YXRlbWVudCA9CiAgICAgICAgICAgIG1ha2UuRXhlYyhtYWtlQ2FsbChtYWtlLklkZW50KHByaW1hcnlFeGNlcHRpb24pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZXMuYWRkU3VwcHJlc3NlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExpc3Qub2YobWFrZS5JZGVudChjYXRjaEV4Y2VwdGlvbikpKSk7CgogICAgICAgIC8vIHRyeSB7IHJlc291cmNlLmNsb3NlKCk7IH0gY2F0Y2ggKGUpIHsgcHJpbWFyeUV4Y2VwdGlvbi5hZGRTdXBwcmVzc2VkKGUpOyB9CiAgICAgICAgSkNCbG9jayB0cnlCbG9jayA9CiAgICAgICAgICAgIG1ha2UuQmxvY2soMEwsIExpc3Qub2YobWFrZVJlc291cmNlQ2xvc2VJbnZvY2F0aW9uKHJlc291cmNlKSkpOwogICAgICAgIEpDVmFyaWFibGVEZWNsIGNhdGNoRXhjZXB0aW9uRGVjbCA9IG1ha2UuVmFyRGVmKGNhdGNoRXhjZXB0aW9uLCBudWxsKTsKICAgICAgICBKQ0Jsb2NrIGNhdGNoQmxvY2sgPSBtYWtlLkJsb2NrKDBMLCBMaXN0Lm9mKGFkZFN1cHByZXNzaW9uU3RhdGVtZW50KSk7CiAgICAgICAgTGlzdDxKQ0NhdGNoPiBjYXRjaENsYXVzZXMgPSBMaXN0Lm9mKG1ha2UuQ2F0Y2goY2F0Y2hFeGNlcHRpb25EZWNsLCBjYXRjaEJsb2NrKSk7CiAgICAgICAgSkNUcnkgdHJ5VHJlZSA9IG1ha2UuVHJ5KHRyeUJsb2NrLCBjYXRjaENsYXVzZXMsIG51bGwpOwogICAgICAgIHRyeVRyZWUuZmluYWxseUNhbkNvbXBsZXRlTm9ybWFsbHkgPSB0cnVlOwoKICAgICAgICAvLyBpZiAocHJpbWFyeUV4Y2VwdGlvbiAhPSBudWxsKSB7dHJ5Li4ufSBlbHNlIHJlc291cmNlQ2xvc2U7CiAgICAgICAgSkNJZiBjbG9zZUlmU3RhdGVtZW50ID0gbWFrZS5JZihtYWtlTm9uTnVsbENoZWNrKG1ha2UuSWRlbnQocHJpbWFyeUV4Y2VwdGlvbikpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ5VHJlZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ha2VSZXNvdXJjZUNsb3NlSW52b2NhdGlvbihyZXNvdXJjZSkpOwoKICAgICAgICByZXR1cm4gY2xvc2VJZlN0YXRlbWVudDsKICAgIH0KCiAgICBwcml2YXRlIEpDU3RhdGVtZW50IG1ha2VSZXNvdXJjZUNsb3NlSW52b2NhdGlvbihKQ0V4cHJlc3Npb24gcmVzb3VyY2UpIHsKICAgICAgICAvLyBjb252ZXJ0IHRvIEF1dG9DbG9zZWFibGUgaWYgbmVlZGVkCiAgICAgICAgaWYgKHR5cGVzLmFzU3VwZXIocmVzb3VyY2UudHlwZSwgc3ltcy5hdXRvQ2xvc2VhYmxlVHlwZS50c3ltKSA9PSBudWxsKSB7CiAgICAgICAgICAgIHJlc291cmNlID0gY29udmVydChyZXNvdXJjZSwgc3ltcy5hdXRvQ2xvc2VhYmxlVHlwZSk7CiAgICAgICAgfQoKICAgICAgICAvLyBjcmVhdGUgcmVzb3VyY2UuY2xvc2UoKSBtZXRob2QgaW52b2NhdGlvbgogICAgICAgIEpDRXhwcmVzc2lvbiByZXNvdXJjZUNsb3NlID0gbWFrZUNhbGwocmVzb3VyY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lcy5jbG9zZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExpc3QubmlsKCkpOwogICAgICAgIHJldHVybiBtYWtlLkV4ZWMocmVzb3VyY2VDbG9zZSk7CiAgICB9CgogICAgcHJpdmF0ZSBKQ0V4cHJlc3Npb24gbWFrZU5vbk51bGxDaGVjayhKQ0V4cHJlc3Npb24gZXhwcmVzc2lvbikgewogICAgICAgIHJldHVybiBtYWtlQmluYXJ5KE5FLCBleHByZXNzaW9uLCBtYWtlTnVsbCgpKTsKICAgIH0KCiAgICAvKiogQ29uc3RydWN0IGEgdHJlZSB0aGF0IHJlcHJlc2VudHMgdGhlIG91dGVyIGluc3RhbmNlCiAgICAgKiAge0Bjb2RlIEMudGhpc30uIE5ldmVyIHBpY2sgdGhlIGN1cnJlbnQgYHRoaXMnLgogICAgICogIEBwYXJhbSBwb3MgICAgICAgICAgIFRoZSBzb3VyY2UgY29kZSBwb3NpdGlvbiB0byBiZSB1c2VkIGZvciB0aGUgdHJlZS4KICAgICAqICBAcGFyYW0gYyAgICAgICAgICAgICBUaGUgcXVhbGlmaWVyIGNsYXNzLgogICAgICovCiAgICBKQ0V4cHJlc3Npb24gbWFrZU91dGVyVGhpcyhEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBUeXBlU3ltYm9sIGMpIHsKICAgICAgICBMaXN0PFZhclN5bWJvbD4gb3RzID0gb3V0ZXJUaGlzU3RhY2s7CiAgICAgICAgaWYgKG90cy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgbG9nLmVycm9yKHBvcywgIm5vLmVuY2wuaW5zdGFuY2Uub2YudHlwZS5pbi5zY29wZSIsIGMpOwogICAgICAgICAgICBBc3NlcnQuZXJyb3IoKTsKICAgICAgICAgICAgcmV0dXJuIG1ha2VOdWxsKCk7CiAgICAgICAgfQogICAgICAgIFZhclN5bWJvbCBvdCA9IG90cy5oZWFkOwogICAgICAgIEpDRXhwcmVzc2lvbiB0cmVlID0gYWNjZXNzKG1ha2UuYXQocG9zKS5JZGVudChvdCkpOwogICAgICAgIFR5cGVTeW1ib2wgb3RjID0gb3QudHlwZS50c3ltOwogICAgICAgIHdoaWxlIChvdGMgIT0gYykgewogICAgICAgICAgICBkbyB7CiAgICAgICAgICAgICAgICBvdHMgPSBvdHMudGFpbDsKICAgICAgICAgICAgICAgIGlmIChvdHMuaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgICAgICAgbG9nLmVycm9yKHBvcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm5vLmVuY2wuaW5zdGFuY2Uub2YudHlwZS5pbi5zY29wZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMpOwogICAgICAgICAgICAgICAgICAgIEFzc2VydC5lcnJvcigpOyAvLyBzaG91bGQgaGF2ZSBiZWVuIGNhdWdodCBpbiBBdHRyCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRyZWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBvdCA9IG90cy5oZWFkOwogICAgICAgICAgICB9IHdoaWxlIChvdC5vd25lciAhPSBvdGMpOwogICAgICAgICAgICBpZiAob3RjLm93bmVyLmtpbmQgIT0gUENLICYmICFvdGMuaGFzT3V0ZXJJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgICAgICBjaGsuZWFybHlSZWZFcnJvcihwb3MsIGMpOwogICAgICAgICAgICAgICAgQXNzZXJ0LmVycm9yKCk7IC8vIHNob3VsZCBoYXZlIGJlZW4gY2F1Z2h0IGluIEF0dHIKICAgICAgICAgICAgICAgIHJldHVybiBtYWtlTnVsbCgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHRyZWUgPSBhY2Nlc3MobWFrZS5hdChwb3MpLlNlbGVjdCh0cmVlLCBvdCkpOwogICAgICAgICAgICBvdGMgPSBvdC50eXBlLnRzeW07CiAgICAgICAgfQogICAgICAgIHJldHVybiB0cmVlOwogICAgfQoKICAgIC8qKiBDb25zdHJ1Y3QgYSB0cmVlIHRoYXQgcmVwcmVzZW50cyB0aGUgY2xvc2VzdCBvdXRlciBpbnN0YW5jZQogICAgICogIHtAY29kZSBDLnRoaXN9IHN1Y2ggdGhhdCB0aGUgZ2l2ZW4gc3ltYm9sIGlzIGEgbWVtYmVyIG9mIEMuCiAgICAgKiAgQHBhcmFtIHBvcyAgICAgICAgICAgVGhlIHNvdXJjZSBjb2RlIHBvc2l0aW9uIHRvIGJlIHVzZWQgZm9yIHRoZSB0cmVlLgogICAgICogIEBwYXJhbSBzeW0gICAgICAgICAgIFRoZSBhY2Nlc3NlZCBzeW1ib2wuCiAgICAgKiAgQHBhcmFtIHByZWNpc2VNYXRjaCAgc2hvdWxkIHdlIGFjY2VwdCBhIHR5cGUgdGhhdCBpcyBhIHN1YnR5cGUgb2YKICAgICAqICAgICAgICAgICAgICAgICAgICAgICBzeW0ncyBvd25lciwgZXZlbiBpZiBpdCBkb2Vzbid0IGNvbnRhaW4gc3ltCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgZHVlIHRvIGhpZGluZywgb3ZlcnJpZGluZywgb3Igbm9uLWluaGVyaXRhbmNlCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgZHVlIHRvIHByb3RlY3Rpb24/CiAgICAgKi8KICAgIEpDRXhwcmVzc2lvbiBtYWtlT3duZXJUaGlzKERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIFN5bWJvbCBzeW0sIGJvb2xlYW4gcHJlY2lzZU1hdGNoKSB7CiAgICAgICAgU3ltYm9sIGMgPSBzeW0ub3duZXI7CiAgICAgICAgaWYgKHByZWNpc2VNYXRjaCA/IHN5bS5pc01lbWJlck9mKGN1cnJlbnRDbGFzcywgdHlwZXMpCiAgICAgICAgICAgICAgICAgICAgICAgICA6IGN1cnJlbnRDbGFzcy5pc1N1YkNsYXNzKHN5bS5vd25lciwgdHlwZXMpKSB7CiAgICAgICAgICAgIC8vIGluIHRoaXMgY2FzZSwgYHRoaXMnIHdvcmtzIGZpbmUKICAgICAgICAgICAgcmV0dXJuIG1ha2UuYXQocG9zKS5UaGlzKGMuZXJhc3VyZSh0eXBlcykpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8vIG5lZWQgdG8gZ28gdmlhIHRoaXMkbgogICAgICAgICAgICByZXR1cm4gbWFrZU93bmVyVGhpc04ocG9zLCBzeW0sIHByZWNpc2VNYXRjaCk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogU2ltaWxhciB0byBtYWtlT3duZXJUaGlzIGJ1dCB3aWxsIG5ldmVyIHBpY2sgInRoaXMiLgogICAgICovCiAgICBKQ0V4cHJlc3Npb24gbWFrZU93bmVyVGhpc04oRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcywgU3ltYm9sIHN5bSwgYm9vbGVhbiBwcmVjaXNlTWF0Y2gpIHsKICAgICAgICBTeW1ib2wgYyA9IHN5bS5vd25lcjsKICAgICAgICBMaXN0PFZhclN5bWJvbD4gb3RzID0gb3V0ZXJUaGlzU3RhY2s7CiAgICAgICAgaWYgKG90cy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgbG9nLmVycm9yKHBvcywgIm5vLmVuY2wuaW5zdGFuY2Uub2YudHlwZS5pbi5zY29wZSIsIGMpOwogICAgICAgICAgICBBc3NlcnQuZXJyb3IoKTsKICAgICAgICAgICAgcmV0dXJuIG1ha2VOdWxsKCk7CiAgICAgICAgfQogICAgICAgIFZhclN5bWJvbCBvdCA9IG90cy5oZWFkOwogICAgICAgIEpDRXhwcmVzc2lvbiB0cmVlID0gYWNjZXNzKG1ha2UuYXQocG9zKS5JZGVudChvdCkpOwogICAgICAgIFR5cGVTeW1ib2wgb3RjID0gb3QudHlwZS50c3ltOwogICAgICAgIHdoaWxlICghKHByZWNpc2VNYXRjaCA/IHN5bS5pc01lbWJlck9mKG90YywgdHlwZXMpIDogb3RjLmlzU3ViQ2xhc3Moc3ltLm93bmVyLCB0eXBlcykpKSB7CiAgICAgICAgICAgIGRvIHsKICAgICAgICAgICAgICAgIG90cyA9IG90cy50YWlsOwogICAgICAgICAgICAgICAgaWYgKG90cy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICAgICAgICBsb2cuZXJyb3IocG9zLAogICAgICAgICAgICAgICAgICAgICAgICAibm8uZW5jbC5pbnN0YW5jZS5vZi50eXBlLmluLnNjb3BlIiwKICAgICAgICAgICAgICAgICAgICAgICAgYyk7CiAgICAgICAgICAgICAgICAgICAgQXNzZXJ0LmVycm9yKCk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRyZWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBvdCA9IG90cy5oZWFkOwogICAgICAgICAgICB9IHdoaWxlIChvdC5vd25lciAhPSBvdGMpOwogICAgICAgICAgICB0cmVlID0gYWNjZXNzKG1ha2UuYXQocG9zKS5TZWxlY3QodHJlZSwgb3QpKTsKICAgICAgICAgICAgb3RjID0gb3QudHlwZS50c3ltOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdHJlZTsKICAgIH0KCiAgICAvKiogUmV0dXJuIHRyZWUgc2ltdWxhdGluZyB0aGUgYXNzaWdubWVudCB7QGNvZGUgdGhpcy5uYW1lID0gbmFtZX0sIHdoZXJlCiAgICAgKiAgbmFtZSBpcyB0aGUgbmFtZSBvZiBhIGZyZWUgdmFyaWFibGUuCiAgICAgKi8KICAgIEpDU3RhdGVtZW50IGluaXRGaWVsZChpbnQgcG9zLCBOYW1lIG5hbWUpIHsKICAgICAgICBJdGVyYXRvcjxTeW1ib2w+IGl0ID0gcHJveGllcy5nZXRTeW1ib2xzQnlOYW1lKG5hbWUpLml0ZXJhdG9yKCk7CiAgICAgICAgU3ltYm9sIHJocyA9IGl0Lm5leHQoKTsKICAgICAgICBBc3NlcnQuY2hlY2socmhzLm93bmVyLmtpbmQgPT0gTVRIKTsKICAgICAgICBTeW1ib2wgbGhzID0gaXQubmV4dCgpOwogICAgICAgIEFzc2VydC5jaGVjayhyaHMub3duZXIub3duZXIgPT0gbGhzLm93bmVyKTsKICAgICAgICBtYWtlLmF0KHBvcyk7CiAgICAgICAgcmV0dXJuCiAgICAgICAgICAgIG1ha2UuRXhlYygKICAgICAgICAgICAgICAgIG1ha2UuQXNzaWduKAogICAgICAgICAgICAgICAgICAgIG1ha2UuU2VsZWN0KG1ha2UuVGhpcyhsaHMub3duZXIuZXJhc3VyZSh0eXBlcykpLCBsaHMpLAogICAgICAgICAgICAgICAgICAgIG1ha2UuSWRlbnQocmhzKSkuc2V0VHlwZShsaHMuZXJhc3VyZSh0eXBlcykpKTsKICAgIH0KCiAgICAvKiogUmV0dXJuIHRyZWUgc2ltdWxhdGluZyB0aGUgYXNzaWdubWVudCB7QGNvZGUgdGhpcy50aGlzJG4gPSB0aGlzJG59LgogICAgICovCiAgICBKQ1N0YXRlbWVudCBpbml0T3V0ZXJUaGlzKGludCBwb3MpIHsKICAgICAgICBWYXJTeW1ib2wgcmhzID0gb3V0ZXJUaGlzU3RhY2suaGVhZDsKICAgICAgICBBc3NlcnQuY2hlY2socmhzLm93bmVyLmtpbmQgPT0gTVRIKTsKICAgICAgICBWYXJTeW1ib2wgbGhzID0gb3V0ZXJUaGlzU3RhY2sudGFpbC5oZWFkOwogICAgICAgIEFzc2VydC5jaGVjayhyaHMub3duZXIub3duZXIgPT0gbGhzLm93bmVyKTsKICAgICAgICBtYWtlLmF0KHBvcyk7CiAgICAgICAgcmV0dXJuCiAgICAgICAgICAgIG1ha2UuRXhlYygKICAgICAgICAgICAgICAgIG1ha2UuQXNzaWduKAogICAgICAgICAgICAgICAgICAgIG1ha2UuU2VsZWN0KG1ha2UuVGhpcyhsaHMub3duZXIuZXJhc3VyZSh0eXBlcykpLCBsaHMpLAogICAgICAgICAgICAgICAgICAgIG1ha2UuSWRlbnQocmhzKSkuc2V0VHlwZShsaHMuZXJhc3VyZSh0eXBlcykpKTsKICAgIH0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBDb2RlIGZvciAuY2xhc3MKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgogICAgLyoqIFJldHVybiB0aGUgc3ltYm9sIG9mIGEgY2xhc3MgdG8gY29udGFpbiBhIGNhY2hlIG9mCiAgICAgKiAgY29tcGlsZXItZ2VuZXJhdGVkIHN0YXRpY3Mgc3VjaCBhcyBjbGFzcyQgYW5kIHRoZQogICAgICogICRhc3NlcnRpb25zRGlzYWJsZWQgZmxhZy4gIFdlIGNyZWF0ZSBhbiBhbm9ueW1vdXMgbmVzdGVkIGNsYXNzCiAgICAgKiAgKHVubGVzcyBvbmUgYWxyZWFkeSBleGlzdHMpIGFuZCByZXR1cm4gaXRzIHN5bWJvbC4gIEhvd2V2ZXIsCiAgICAgKiAgZm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHkgaW4gMS40IGFuZCBlYXJsaWVyIHdlIHVzZSB0aGUKICAgICAqICB0b3AtbGV2ZWwgY2xhc3MgaXRzZWxmLgogICAgICovCiAgICBwcml2YXRlIENsYXNzU3ltYm9sIG91dGVyQ2FjaGVDbGFzcygpIHsKICAgICAgICBDbGFzc1N5bWJvbCBjbGF6eiA9IG91dGVybW9zdENsYXNzRGVmLnN5bTsKICAgICAgICBTY29wZSBzID0gY2xhenoubWVtYmVycygpOwogICAgICAgIGZvciAoU3ltYm9sIHN5bSA6IHMuZ2V0U3ltYm9scyhOT05fUkVDVVJTSVZFKSkKICAgICAgICAgICAgaWYgKHN5bS5raW5kID09IFRZUCAmJgogICAgICAgICAgICAgICAgc3ltLm5hbWUgPT0gbmFtZXMuZW1wdHkgJiYKICAgICAgICAgICAgICAgIChzeW0uZmxhZ3MoKSAmIElOVEVSRkFDRSkgPT0gMCkgcmV0dXJuIChDbGFzc1N5bWJvbCkgc3ltOwogICAgICAgIHJldHVybiBtYWtlRW1wdHlDbGFzcyhTVEFUSUMgfCBTWU5USEVUSUMsIGNsYXp6KS5zeW07CiAgICB9CgogICAgLyoqIFJldHVybiBzeW1ib2wgZm9yICJjbGFzcyQiIG1ldGhvZC4gSWYgdGhlcmUgaXMgbm8gbWV0aG9kIGRlZmluaXRpb24KICAgICAqICBmb3IgY2xhc3MkLCBjb25zdHJ1Y3Qgb25lIGFzIGZvbGxvd3M6CiAgICAgKgogICAgICogICAgY2xhc3MgY2xhc3MkKFN0cmluZyB4MCkgewogICAgICogICAgICB0cnkgewogICAgICogICAgICAgIHJldHVybiBDbGFzcy5mb3JOYW1lKHgwKTsKICAgICAqICAgICAgfSBjYXRjaCAoQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiB4MSkgewogICAgICogICAgICAgIHRocm93IG5ldyBOb0NsYXNzRGVmRm91bmRFcnJvcih4MS5nZXRNZXNzYWdlKCkpOwogICAgICogICAgICB9CiAgICAgKiAgICB9CiAgICAgKi8KICAgIHByaXZhdGUgTWV0aG9kU3ltYm9sIGNsYXNzRG9sbGFyU3ltKERpYWdub3N0aWNQb3NpdGlvbiBwb3MpIHsKICAgICAgICBDbGFzc1N5bWJvbCBvdXRlckNhY2hlQ2xhc3MgPSBvdXRlckNhY2hlQ2xhc3MoKTsKICAgICAgICBNZXRob2RTeW1ib2wgY2xhc3NEb2xsYXJTeW0gPQogICAgICAgICAgICAoTWV0aG9kU3ltYm9sKWxvb2t1cFN5bnRoZXRpYyhjbGFzc0RvbGxhciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3V0ZXJDYWNoZUNsYXNzLm1lbWJlcnMoKSk7CiAgICAgICAgaWYgKGNsYXNzRG9sbGFyU3ltID09IG51bGwpIHsKICAgICAgICAgICAgY2xhc3NEb2xsYXJTeW0gPSBuZXcgTWV0aG9kU3ltYm9sKAogICAgICAgICAgICAgICAgU1RBVElDIHwgU1lOVEhFVElDLAogICAgICAgICAgICAgICAgY2xhc3NEb2xsYXIsCiAgICAgICAgICAgICAgICBuZXcgTWV0aG9kVHlwZSgKICAgICAgICAgICAgICAgICAgICBMaXN0Lm9mKHN5bXMuc3RyaW5nVHlwZSksCiAgICAgICAgICAgICAgICAgICAgdHlwZXMuZXJhc3VyZShzeW1zLmNsYXNzVHlwZSksCiAgICAgICAgICAgICAgICAgICAgTGlzdC5uaWwoKSwKICAgICAgICAgICAgICAgICAgICBzeW1zLm1ldGhvZENsYXNzKSwKICAgICAgICAgICAgICAgIG91dGVyQ2FjaGVDbGFzcyk7CiAgICAgICAgICAgIGVudGVyU3ludGhldGljKHBvcywgY2xhc3NEb2xsYXJTeW0sIG91dGVyQ2FjaGVDbGFzcy5tZW1iZXJzKCkpOwoKICAgICAgICAgICAgSkNNZXRob2REZWNsIG1kID0gbWFrZS5NZXRob2REZWYoY2xhc3NEb2xsYXJTeW0sIG51bGwpOwogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgbWQuYm9keSA9IGNsYXNzRG9sbGFyU3ltQm9keShwb3MsIG1kKTsKICAgICAgICAgICAgfSBjYXRjaCAoQ29tcGxldGlvbkZhaWx1cmUgZXgpIHsKICAgICAgICAgICAgICAgIG1kLmJvZHkgPSBtYWtlLkJsb2NrKDAsIExpc3QubmlsKCkpOwogICAgICAgICAgICAgICAgY2hrLmNvbXBsZXRpb25FcnJvcihwb3MsIGV4KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBKQ0NsYXNzRGVjbCBvdXRlckNhY2hlQ2xhc3NEZWYgPSBjbGFzc0RlZihvdXRlckNhY2hlQ2xhc3MpOwogICAgICAgICAgICBvdXRlckNhY2hlQ2xhc3NEZWYuZGVmcyA9IG91dGVyQ2FjaGVDbGFzc0RlZi5kZWZzLnByZXBlbmQobWQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gY2xhc3NEb2xsYXJTeW07CiAgICB9CgogICAgLyoqIEdlbmVyYXRlIGNvZGUgZm9yIGNsYXNzJChTdHJpbmcgbmFtZSkuICovCiAgICBKQ0Jsb2NrIGNsYXNzRG9sbGFyU3ltQm9keShEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBKQ01ldGhvZERlY2wgbWQpIHsKICAgICAgICBNZXRob2RTeW1ib2wgY2xhc3NEb2xsYXJTeW0gPSBtZC5zeW07CiAgICAgICAgQ2xhc3NTeW1ib2wgb3V0ZXJDYWNoZUNsYXNzID0gKENsYXNzU3ltYm9sKWNsYXNzRG9sbGFyU3ltLm93bmVyOwoKICAgICAgICBKQ0Jsb2NrIHJldHVyblJlc3VsdDsKCiAgICAgICAgLy8gY2FjaGUgdGhlIGN1cnJlbnQgbG9hZGVyIGluIGNsJAogICAgICAgIC8vIGNsc3ltID0gInByaXZhdGUgc3RhdGljIENsYXNzTG9hZGVyIGNsJCIKICAgICAgICBWYXJTeW1ib2wgY2xzeW0gPSBuZXcgVmFyU3ltYm9sKFNUQVRJQyB8IFNZTlRIRVRJQywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVzLmZyb21TdHJpbmcoImNsIiArIHRhcmdldC5zeW50aGV0aWNOYW1lQ2hhcigpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5bXMuY2xhc3NMb2FkZXJUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3V0ZXJDYWNoZUNsYXNzKTsKICAgICAgICBlbnRlclN5bnRoZXRpYyhwb3MsIGNsc3ltLCBvdXRlckNhY2hlQ2xhc3MubWVtYmVycygpKTsKCiAgICAgICAgLy8gZW1pdCAicHJpdmF0ZSBzdGF0aWMgQ2xhc3NMb2FkZXIgY2wkOyIKICAgICAgICBKQ1ZhcmlhYmxlRGVjbCBjbGRlZiA9IG1ha2UuVmFyRGVmKGNsc3ltLCBudWxsKTsKICAgICAgICBKQ0NsYXNzRGVjbCBvdXRlckNhY2hlQ2xhc3NEZWYgPSBjbGFzc0RlZihvdXRlckNhY2hlQ2xhc3MpOwogICAgICAgIG91dGVyQ2FjaGVDbGFzc0RlZi5kZWZzID0gb3V0ZXJDYWNoZUNsYXNzRGVmLmRlZnMucHJlcGVuZChjbGRlZik7CgogICAgICAgIC8vIG5ld2NhY2hlIDo9ICJuZXcgY2FjaGUkMVswXSIKICAgICAgICBKQ05ld0FycmF5IG5ld2NhY2hlID0gbWFrZS5OZXdBcnJheShtYWtlLlR5cGUob3V0ZXJDYWNoZUNsYXNzLnR5cGUpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExpc3Qub2YobWFrZS5MaXRlcmFsKElOVCwgMCkuc2V0VHlwZShzeW1zLmludFR5cGUpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsKTsKICAgICAgICBuZXdjYWNoZS50eXBlID0gbmV3IEFycmF5VHlwZSh0eXBlcy5lcmFzdXJlKG91dGVyQ2FjaGVDbGFzcy50eXBlKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeW1zLmFycmF5Q2xhc3MpOwoKICAgICAgICAvLyBmb3JOYW1lU3ltIDo9IGphdmEubGFuZy5DbGFzcy5mb3JOYW1lKAogICAgICAgIC8vICAgICBTdHJpbmcgcyxib29sZWFuIGluaXQsQ2xhc3NMb2FkZXIgbG9hZGVyKQogICAgICAgIFN5bWJvbCBmb3JOYW1lU3ltID0gbG9va3VwTWV0aG9kKG1ha2VfcG9zLCBuYW1lcy5mb3JOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVzLmVyYXN1cmUoc3ltcy5jbGFzc1R5cGUpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExpc3Qub2Yoc3ltcy5zdHJpbmdUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ltcy5ib29sZWFuVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5bXMuY2xhc3NMb2FkZXJUeXBlKSk7CiAgICAgICAgLy8gY2x2YWx1ZSA6PSAiKGNsJCA9PSBudWxsKSA/CiAgICAgICAgLy8gJG5ld2NhY2hlLmdldENsYXNzKCkuZ2V0Q29tcG9uZW50VHlwZSgpLmdldENsYXNzTG9hZGVyKCkgOiBjbCQiCiAgICAgICAgSkNFeHByZXNzaW9uIGNsdmFsdWUgPQogICAgICAgICAgICAgICAgbWFrZS5Db25kaXRpb25hbCgKICAgICAgICAgICAgICAgICAgICAgICAgbWFrZUJpbmFyeShFUSwgbWFrZS5JZGVudChjbHN5bSksIG1ha2VOdWxsKCkpLAogICAgICAgICAgICAgICAgICAgICAgICBtYWtlLkFzc2lnbihtYWtlLklkZW50KGNsc3ltKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFrZUNhbGwoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFrZUNhbGwobWFrZUNhbGwobmV3Y2FjaGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZXMuZ2V0Q2xhc3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTGlzdC5uaWwoKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZXMuZ2V0Q29tcG9uZW50VHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0Lm5pbCgpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lcy5nZXRDbGFzc0xvYWRlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0Lm5pbCgpKSkuc2V0VHlwZShzeW1zLmNsYXNzTG9hZGVyVHlwZSksCiAgICAgICAgICAgICAgICAgICAgICAgIG1ha2UuSWRlbnQoY2xzeW0pKS5zZXRUeXBlKHN5bXMuY2xhc3NMb2FkZXJUeXBlKTsKCiAgICAgICAgLy8gcmV0dXJuUmVzdWx0IDo9ICJ7IHJldHVybiBDbGFzcy5mb3JOYW1lKHBhcmFtMSwgZmFsc2UsIGNsJCk7IH0iCiAgICAgICAgTGlzdDxKQ0V4cHJlc3Npb24+IGFyZ3MgPSBMaXN0Lm9mKG1ha2UuSWRlbnQobWQucGFyYW1zLmhlYWQuc3ltKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFrZUxpdChzeW1zLmJvb2xlYW5UeXBlLCAwKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2x2YWx1ZSk7CiAgICAgICAgcmV0dXJuUmVzdWx0ID0gbWFrZS5CbG9jaygwLCBMaXN0Lm9mKG1ha2UuQ2FsbChtYWtlLkFwcChtYWtlLklkZW50KGZvck5hbWVTeW0pLCBhcmdzKSkpKTsKCiAgICAgICAgLy8gY2F0Y2hQYXJhbSA6PSBDbGFzc05vdEZvdW5kRXhjZXB0aW9uIGUxCiAgICAgICAgVmFyU3ltYm9sIGNhdGNoUGFyYW0gPQogICAgICAgICAgICBuZXcgVmFyU3ltYm9sKFNZTlRIRVRJQywgbWFrZS5wYXJhbU5hbWUoMSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgc3ltcy5jbGFzc05vdEZvdW5kRXhjZXB0aW9uVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzc0RvbGxhclN5bSk7CgogICAgICAgIEpDU3RhdGVtZW50IHJldGhyb3c7CiAgICAgICAgLy8gcmV0aHJvdyA9ICJ0aHJvdyBuZXcgTm9DbGFzc0RlZkZvdW5kRXJyb3IoKS5pbml0Q2F1c2UoZSk7CiAgICAgICAgSkNFeHByZXNzaW9uIHRocm93RXhwciA9CiAgICAgICAgICAgIG1ha2VDYWxsKG1ha2VOZXdDbGFzcyhzeW1zLm5vQ2xhc3NEZWZGb3VuZEVycm9yVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExpc3QubmlsKCkpLAogICAgICAgICAgICAgICAgICAgICBuYW1lcy5pbml0Q2F1c2UsCiAgICAgICAgICAgICAgICAgICAgIExpc3Qub2YobWFrZS5JZGVudChjYXRjaFBhcmFtKSkpOwogICAgICAgIHJldGhyb3cgPSBtYWtlLlRocm93KHRocm93RXhwcik7CgogICAgICAgIC8vIHJldGhyb3dTdG10IDo9ICIoICRyZXRocm93ICkiCiAgICAgICAgSkNCbG9jayByZXRocm93U3RtdCA9IG1ha2UuQmxvY2soMCwgTGlzdC5vZihyZXRocm93KSk7CgogICAgICAgIC8vIGNhdGNoQmxvY2sgOj0gImNhdGNoICgkY2F0Y2hQYXJhbSkgJHJldGhyb3dTdG10IgogICAgICAgIEpDQ2F0Y2ggY2F0Y2hCbG9jayA9IG1ha2UuQ2F0Y2gobWFrZS5WYXJEZWYoY2F0Y2hQYXJhbSwgbnVsbCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0aHJvd1N0bXQpOwoKICAgICAgICAvLyB0cnlDYXRjaCA6PSAidHJ5ICRyZXR1cm5SZXN1bHQgJGNhdGNoQmxvY2siCiAgICAgICAgSkNTdGF0ZW1lbnQgdHJ5Q2F0Y2ggPSBtYWtlLlRyeShyZXR1cm5SZXN1bHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0Lm9mKGNhdGNoQmxvY2spLCBudWxsKTsKCiAgICAgICAgcmV0dXJuIG1ha2UuQmxvY2soMCwgTGlzdC5vZih0cnlDYXRjaCkpOwogICAgfQogICAgLy8gd2hlcmUKICAgICAgICAvKiogQ3JlYXRlIGFuIGF0dHJpYnV0ZWQgdHJlZSBvZiB0aGUgZm9ybSBsZWZ0Lm5hbWUoKS4gKi8KICAgICAgICBwcml2YXRlIEpDTWV0aG9kSW52b2NhdGlvbiBtYWtlQ2FsbChKQ0V4cHJlc3Npb24gbGVmdCwgTmFtZSBuYW1lLCBMaXN0PEpDRXhwcmVzc2lvbj4gYXJncykgewogICAgICAgICAgICBBc3NlcnQuY2hlY2tOb25OdWxsKGxlZnQudHlwZSk7CiAgICAgICAgICAgIFN5bWJvbCBmdW5jc3ltID0gbG9va3VwTWV0aG9kKG1ha2VfcG9zLCBuYW1lLCBsZWZ0LnR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRyZWVJbmZvLnR5cGVzKGFyZ3MpKTsKICAgICAgICAgICAgcmV0dXJuIG1ha2UuQXBwKG1ha2UuU2VsZWN0KGxlZnQsIGZ1bmNzeW0pLCBhcmdzKTsKICAgICAgICB9CgogICAgLyoqIFRoZSBOYW1lIE9mIFRoZSB2YXJpYWJsZSB0byBjYWNoZSBULmNsYXNzIHZhbHVlcy4KICAgICAqICBAcGFyYW0gc2lnICAgICAgVGhlIHNpZ25hdHVyZSBvZiB0eXBlIFQuCiAgICAgKi8KICAgIHByaXZhdGUgTmFtZSBjYWNoZU5hbWUoU3RyaW5nIHNpZykgewogICAgICAgIFN0cmluZ0J1aWxkZXIgYnVmID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKICAgICAgICBpZiAoc2lnLnN0YXJ0c1dpdGgoIlsiKSkgewogICAgICAgICAgICBidWYgPSBidWYuYXBwZW5kKCJhcnJheSIpOwogICAgICAgICAgICB3aGlsZSAoc2lnLnN0YXJ0c1dpdGgoIlsiKSkgewogICAgICAgICAgICAgICAgYnVmID0gYnVmLmFwcGVuZCh0YXJnZXQuc3ludGhldGljTmFtZUNoYXIoKSk7CiAgICAgICAgICAgICAgICBzaWcgPSBzaWcuc3Vic3RyaW5nKDEpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChzaWcuc3RhcnRzV2l0aCgiTCIpKSB7CiAgICAgICAgICAgICAgICBzaWcgPSBzaWcuc3Vic3RyaW5nKDAsIHNpZy5sZW5ndGgoKSAtIDEpOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgYnVmID0gYnVmLmFwcGVuZCgiY2xhc3MiICsgdGFyZ2V0LnN5bnRoZXRpY05hbWVDaGFyKCkpOwogICAgICAgIH0KICAgICAgICBidWYgPSBidWYuYXBwZW5kKHNpZy5yZXBsYWNlKCcuJywgdGFyZ2V0LnN5bnRoZXRpY05hbWVDaGFyKCkpKTsKICAgICAgICByZXR1cm4gbmFtZXMuZnJvbVN0cmluZyhidWYudG9TdHJpbmcoKSk7CiAgICB9CgogICAgLyoqIFRoZSB2YXJpYWJsZSBzeW1ib2wgdGhhdCBjYWNoZXMgVC5jbGFzcyB2YWx1ZXMuCiAgICAgKiAgSWYgbm9uZSBleGlzdHMgeWV0LCBjcmVhdGUgYSBkZWZpbml0aW9uLgogICAgICogIEBwYXJhbSBzaWcgICAgICBUaGUgc2lnbmF0dXJlIG9mIHR5cGUgVC4KICAgICAqICBAcGFyYW0gcG9zICAgICAgVGhlIHBvc2l0aW9uIHRvIHJlcG9ydCBkaWFnbm9zdGljcywgaWYgYW55LgogICAgICovCiAgICBwcml2YXRlIFZhclN5bWJvbCBjYWNoZVN5bShEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBTdHJpbmcgc2lnKSB7CiAgICAgICAgQ2xhc3NTeW1ib2wgb3V0ZXJDYWNoZUNsYXNzID0gb3V0ZXJDYWNoZUNsYXNzKCk7CiAgICAgICAgTmFtZSBjbmFtZSA9IGNhY2hlTmFtZShzaWcpOwogICAgICAgIFZhclN5bWJvbCBjYWNoZVN5bSA9CiAgICAgICAgICAgIChWYXJTeW1ib2wpbG9va3VwU3ludGhldGljKGNuYW1lLCBvdXRlckNhY2hlQ2xhc3MubWVtYmVycygpKTsKICAgICAgICBpZiAoY2FjaGVTeW0gPT0gbnVsbCkgewogICAgICAgICAgICBjYWNoZVN5bSA9IG5ldyBWYXJTeW1ib2woCiAgICAgICAgICAgICAgICBTVEFUSUMgfCBTWU5USEVUSUMsIGNuYW1lLCB0eXBlcy5lcmFzdXJlKHN5bXMuY2xhc3NUeXBlKSwgb3V0ZXJDYWNoZUNsYXNzKTsKICAgICAgICAgICAgZW50ZXJTeW50aGV0aWMocG9zLCBjYWNoZVN5bSwgb3V0ZXJDYWNoZUNsYXNzLm1lbWJlcnMoKSk7CgogICAgICAgICAgICBKQ1ZhcmlhYmxlRGVjbCBjYWNoZURlZiA9IG1ha2UuVmFyRGVmKGNhY2hlU3ltLCBudWxsKTsKICAgICAgICAgICAgSkNDbGFzc0RlY2wgb3V0ZXJDYWNoZUNsYXNzRGVmID0gY2xhc3NEZWYob3V0ZXJDYWNoZUNsYXNzKTsKICAgICAgICAgICAgb3V0ZXJDYWNoZUNsYXNzRGVmLmRlZnMgPSBvdXRlckNhY2hlQ2xhc3NEZWYuZGVmcy5wcmVwZW5kKGNhY2hlRGVmKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGNhY2hlU3ltOwogICAgfQoKICAgIC8qKiBUaGUgdHJlZSBzaW11bGF0aW5nIGEgVC5jbGFzcyBleHByZXNzaW9uLgogICAgICogIEBwYXJhbSBjbGF6eiAgICAgIFRoZSB0cmVlIGlkZW50aWZ5aW5nIHR5cGUgVC4KICAgICAqLwogICAgcHJpdmF0ZSBKQ0V4cHJlc3Npb24gY2xhc3NPZihKQ1RyZWUgY2xhenopIHsKICAgICAgICByZXR1cm4gY2xhc3NPZlR5cGUoY2xhenoudHlwZSwgY2xhenoucG9zKCkpOwogICAgfQoKICAgIHByaXZhdGUgSkNFeHByZXNzaW9uIGNsYXNzT2ZUeXBlKFR5cGUgdHlwZSwgRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcykgewogICAgICAgIHN3aXRjaCAodHlwZS5nZXRUYWcoKSkgewogICAgICAgIGNhc2UgQllURTogY2FzZSBTSE9SVDogY2FzZSBDSEFSOiBjYXNlIElOVDogY2FzZSBMT05HOiBjYXNlIEZMT0FUOgogICAgICAgIGNhc2UgRE9VQkxFOiBjYXNlIEJPT0xFQU46IGNhc2UgVk9JRDoKICAgICAgICAgICAgLy8gcmVwbGFjZSB3aXRoIDxCb3hlZENsYXNzPi5UWVBFCiAgICAgICAgICAgIENsYXNzU3ltYm9sIGMgPSB0eXBlcy5ib3hlZENsYXNzKHR5cGUpOwogICAgICAgICAgICBTeW1ib2wgdHlwZVN5bSA9CiAgICAgICAgICAgICAgICBycy5hY2Nlc3NCYXNlKAogICAgICAgICAgICAgICAgICAgIHJzLmZpbmRJZGVudEluVHlwZShhdHRyRW52LCBjLnR5cGUsIG5hbWVzLlRZUEUsIEtpbmRTZWxlY3Rvci5WQVIpLAogICAgICAgICAgICAgICAgICAgIHBvcywgYy50eXBlLCBuYW1lcy5UWVBFLCB0cnVlKTsKICAgICAgICAgICAgaWYgKHR5cGVTeW0ua2luZCA9PSBWQVIpCiAgICAgICAgICAgICAgICAoKFZhclN5bWJvbCl0eXBlU3ltKS5nZXRDb25zdFZhbHVlKCk7IC8vIGVuc3VyZSBpbml0aWFsaXplciBpcyBldmFsdWF0ZWQKICAgICAgICAgICAgcmV0dXJuIG1ha2UuUXVhbElkZW50KHR5cGVTeW0pOwogICAgICAgIGNhc2UgQ0xBU1M6IGNhc2UgQVJSQVk6CiAgICAgICAgICAgICAgICBWYXJTeW1ib2wgc3ltID0gbmV3IFZhclN5bWJvbCgKICAgICAgICAgICAgICAgICAgICAgICAgU1RBVElDIHwgUFVCTElDIHwgRklOQUwsIG5hbWVzLl9jbGFzcywKICAgICAgICAgICAgICAgICAgICAgICAgc3ltcy5jbGFzc1R5cGUsIHR5cGUudHN5bSk7CiAgICAgICAgICAgICAgICByZXR1cm4gbWFrZV9hdChwb3MpLlNlbGVjdChtYWtlLlR5cGUodHlwZSksIHN5bSk7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCk7CiAgICAgICAgfQogICAgfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIENvZGUgZm9yIGVuYWJsaW5nL2Rpc2FibGluZyBhc3NlcnRpb25zLgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiAgICBwcml2YXRlIENsYXNzU3ltYm9sIGFzc2VydGlvbnNEaXNhYmxlZENsYXNzQ2FjaGU7CgogICAgLyoqVXNlZCB0byBjcmVhdGUgYW4gYXV4aWxpYXJ5IGNsYXNzIHRvIGhvbGQgJGFzc2VydGlvbnNEaXNhYmxlZCBmb3IgaW50ZXJmYWNlcy4KICAgICAqLwogICAgcHJpdmF0ZSBDbGFzc1N5bWJvbCBhc3NlcnRpb25zRGlzYWJsZWRDbGFzcygpIHsKICAgICAgICBpZiAoYXNzZXJ0aW9uc0Rpc2FibGVkQ2xhc3NDYWNoZSAhPSBudWxsKSByZXR1cm4gYXNzZXJ0aW9uc0Rpc2FibGVkQ2xhc3NDYWNoZTsKCiAgICAgICAgYXNzZXJ0aW9uc0Rpc2FibGVkQ2xhc3NDYWNoZSA9IG1ha2VFbXB0eUNsYXNzKFNUQVRJQyB8IFNZTlRIRVRJQywgb3V0ZXJtb3N0Q2xhc3NEZWYuc3ltKS5zeW07CgogICAgICAgIHJldHVybiBhc3NlcnRpb25zRGlzYWJsZWRDbGFzc0NhY2hlOwogICAgfQoKICAgIC8vIFRoaXMgY29kZSBpcyBub3QgcGFydGljdWxhcmx5IHJvYnVzdCBpZiB0aGUgdXNlciBoYXMKICAgIC8vIHByZXZpb3VzbHkgZGVjbGFyZWQgYSBtZW1iZXIgbmFtZWQgJyRhc3NlcnRpb25zRGlzYWJsZWQnLgogICAgLy8gVGhlIHNhbWUgZmF1bHR5IGlkaW9tIGFsc28gYXBwZWFycyBpbiB0aGUgdHJhbnNsYXRpb24gb2YKICAgIC8vIGNsYXNzIGxpdGVyYWxzIGFib3ZlLiAgV2Ugc2hvdWxkIHJlcG9ydCBhbiBlcnJvciBpZiBhCiAgICAvLyBwcmV2aW91cyBkZWNsYXJhdGlvbiBpcyBub3Qgc3ludGhldGljLgoKICAgIHByaXZhdGUgSkNFeHByZXNzaW9uIGFzc2VydEZsYWdUZXN0KERpYWdub3N0aWNQb3NpdGlvbiBwb3MpIHsKICAgICAgICAvLyBPdXRlcm1vc3QgY2xhc3MgbWF5IGJlIGVpdGhlciB0cnVlIGNsYXNzIG9yIGFuIGludGVyZmFjZS4KICAgICAgICBDbGFzc1N5bWJvbCBvdXRlcm1vc3RDbGFzcyA9IG91dGVybW9zdENsYXNzRGVmLnN5bTsKCiAgICAgICAgLy9vbmx5IGNsYXNzZXMgY2FuIGhvbGQgYSBub24tcHVibGljIGZpZWxkLCBsb29rIGZvciBhIHVzYWJsZSBvbmU6CiAgICAgICAgQ2xhc3NTeW1ib2wgY29udGFpbmVyID0gIWN1cnJlbnRDbGFzcy5pc0ludGVyZmFjZSgpID8gY3VycmVudENsYXNzIDoKICAgICAgICAgICAgICAgIGFzc2VydGlvbnNEaXNhYmxlZENsYXNzKCk7CgogICAgICAgIFZhclN5bWJvbCBhc3NlcnREaXNhYmxlZFN5bSA9CiAgICAgICAgICAgIChWYXJTeW1ib2wpbG9va3VwU3ludGhldGljKGRvbGxhckFzc2VydGlvbnNEaXNhYmxlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGFpbmVyLm1lbWJlcnMoKSk7CiAgICAgICAgaWYgKGFzc2VydERpc2FibGVkU3ltID09IG51bGwpIHsKICAgICAgICAgICAgYXNzZXJ0RGlzYWJsZWRTeW0gPQogICAgICAgICAgICAgICAgbmV3IFZhclN5bWJvbChTVEFUSUMgfCBGSU5BTCB8IFNZTlRIRVRJQywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9sbGFyQXNzZXJ0aW9uc0Rpc2FibGVkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeW1zLmJvb2xlYW5UeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250YWluZXIpOwogICAgICAgICAgICBlbnRlclN5bnRoZXRpYyhwb3MsIGFzc2VydERpc2FibGVkU3ltLCBjb250YWluZXIubWVtYmVycygpKTsKICAgICAgICAgICAgU3ltYm9sIGRlc2lyZWRBc3NlcnRpb25TdGF0dXNTeW0gPSBsb29rdXBNZXRob2QocG9zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lcy5kZXNpcmVkQXNzZXJ0aW9uU3RhdHVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlcy5lcmFzdXJlKHN5bXMuY2xhc3NUeXBlKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTGlzdC5uaWwoKSk7CiAgICAgICAgICAgIEpDQ2xhc3NEZWNsIGNvbnRhaW5lckRlZiA9IGNsYXNzRGVmKGNvbnRhaW5lcik7CiAgICAgICAgICAgIG1ha2VfYXQoY29udGFpbmVyRGVmLnBvcygpKTsKICAgICAgICAgICAgSkNFeHByZXNzaW9uIG5vdFN0YXR1cyA9IG1ha2VVbmFyeShOT1QsIG1ha2UuQXBwKG1ha2UuU2VsZWN0KAogICAgICAgICAgICAgICAgICAgIGNsYXNzT2ZUeXBlKHR5cGVzLmVyYXN1cmUob3V0ZXJtb3N0Q2xhc3MudHlwZSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGFpbmVyRGVmLnBvcygpKSwKICAgICAgICAgICAgICAgICAgICBkZXNpcmVkQXNzZXJ0aW9uU3RhdHVzU3ltKSkpOwogICAgICAgICAgICBKQ1ZhcmlhYmxlRGVjbCBhc3NlcnREaXNhYmxlZERlZiA9IG1ha2UuVmFyRGVmKGFzc2VydERpc2FibGVkU3ltLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub3RTdGF0dXMpOwogICAgICAgICAgICBjb250YWluZXJEZWYuZGVmcyA9IGNvbnRhaW5lckRlZi5kZWZzLnByZXBlbmQoYXNzZXJ0RGlzYWJsZWREZWYpOwoKICAgICAgICAgICAgaWYgKGN1cnJlbnRDbGFzcy5pc0ludGVyZmFjZSgpKSB7CiAgICAgICAgICAgICAgICAvL25lZWQgdG8gbG9hZCB0aGUgYXNzZXJ0aW9ucyBlbmFibGVkL2Rpc2FibGVkIHN0YXRlIHdoaWxlCiAgICAgICAgICAgICAgICAvL2luaXRpYWxpemluZyB0aGUgaW50ZXJmYWNlOgogICAgICAgICAgICAgICAgSkNDbGFzc0RlY2wgY3VycmVudENsYXNzRGVmID0gY2xhc3NEZWYoY3VycmVudENsYXNzKTsKICAgICAgICAgICAgICAgIG1ha2VfYXQoY3VycmVudENsYXNzRGVmLnBvcygpKTsKICAgICAgICAgICAgICAgIEpDU3RhdGVtZW50IGR1bW15ID0gbWFrZS5JZihtYWtlLlF1YWxJZGVudChhc3NlcnREaXNhYmxlZFN5bSksIG1ha2UuU2tpcCgpLCBudWxsKTsKICAgICAgICAgICAgICAgIEpDQmxvY2sgY2xpbml0ID0gbWFrZS5CbG9jayhTVEFUSUMsIExpc3Qub2YoZHVtbXkpKTsKICAgICAgICAgICAgICAgIGN1cnJlbnRDbGFzc0RlZi5kZWZzID0gY3VycmVudENsYXNzRGVmLmRlZnMucHJlcGVuZChjbGluaXQpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIG1ha2VfYXQocG9zKTsKICAgICAgICByZXR1cm4gbWFrZVVuYXJ5KE5PVCwgbWFrZS5JZGVudChhc3NlcnREaXNhYmxlZFN5bSkpOwogICAgfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBCdWlsZGluZyBibG9ja3MgZm9yIGxldCBleHByZXNzaW9ucwogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiAgICBpbnRlcmZhY2UgVHJlZUJ1aWxkZXIgewogICAgICAgIEpDRXhwcmVzc2lvbiBidWlsZChKQ0V4cHJlc3Npb24gYXJnKTsKICAgIH0KCiAgICAvKiogQ29uc3RydWN0IGFuIGV4cHJlc3Npb24gdXNpbmcgdGhlIGJ1aWxkZXIsIHdpdGggdGhlIGdpdmVuIHJ2YWwKICAgICAqICBleHByZXNzaW9uIGFzIGFuIGFyZ3VtZW50IHRvIHRoZSBidWlsZGVyLiAgSG93ZXZlciwgdGhlIHJ2YWwKICAgICAqICBleHByZXNzaW9uIG11c3QgYmUgY29tcHV0ZWQgb25seSBvbmNlLCBldmVuIGlmIHVzZWQgbXVsdGlwbGUKICAgICAqICB0aW1lcyBpbiB0aGUgcmVzdWx0IG9mIHRoZSBidWlsZGVyLiAgV2UgZG8gdGhhdCBieQogICAgICogIGNvbnN0cnVjdGluZyBhICJsZXQiIGV4cHJlc3Npb24gdGhhdCBzYXZlcyB0aGUgcnZhbHVlIGludG8gYQogICAgICogIHRlbXBvcmFyeSB2YXJpYWJsZSBhbmQgdGhlbiB1c2VzIHRoZSB0ZW1wb3JhcnkgdmFyaWFibGUgaW4KICAgICAqICBwbGFjZSBvZiB0aGUgZXhwcmVzc2lvbiBidWlsdCBieSB0aGUgYnVpbGRlci4gIFRoZSBjb21wbGV0ZQogICAgICogIHJlc3VsdGluZyBleHByZXNzaW9uIGlzIG9mIHRoZSBmb3JtCiAgICAgKiAgPHByZT4KICAgICAqICAgIChsZXQgPGI+VFlQRTwvYj4gPGI+VEVNUDwvYj4gPSA8Yj5SVkFMPC9iPjsKICAgICAqICAgICBpbiAoPGI+QlVJTERFUjwvYj4oPGI+VEVNUDwvYj4pKSkKICAgICAqICA8L3ByZT4KICAgICAqICB3aGVyZSA8Y29kZT48Yj5URU1QPC9iPjwvY29kZT4gaXMgYSBuZXdseSBkZWNsYXJlZCB2YXJpYWJsZQogICAgICogIGluIHRoZSBsZXQgZXhwcmVzc2lvbi4KICAgICAqLwogICAgSkNFeHByZXNzaW9uIGFic3RyYWN0UnZhbChKQ0V4cHJlc3Npb24gcnZhbCwgVHlwZSB0eXBlLCBUcmVlQnVpbGRlciBidWlsZGVyKSB7CiAgICAgICAgcnZhbCA9IFRyZWVJbmZvLnNraXBQYXJlbnMocnZhbCk7CiAgICAgICAgc3dpdGNoIChydmFsLmdldFRhZygpKSB7CiAgICAgICAgY2FzZSBMSVRFUkFMOgogICAgICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZChydmFsKTsKICAgICAgICBjYXNlIElERU5UOgogICAgICAgICAgICBKQ0lkZW50IGlkID0gKEpDSWRlbnQpIHJ2YWw7CiAgICAgICAgICAgIGlmICgoaWQuc3ltLmZsYWdzKCkgJiBGSU5BTCkgIT0gMCAmJiBpZC5zeW0ub3duZXIua2luZCA9PSBNVEgpCiAgICAgICAgICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZChydmFsKTsKICAgICAgICB9CiAgICAgICAgTmFtZSBuYW1lID0gVHJlZUluZm8ubmFtZShydmFsKTsKICAgICAgICBpZiAobmFtZSA9PSBuYW1lcy5fc3VwZXIgfHwgbmFtZSA9PSBuYW1lcy5fdGhpcykKICAgICAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGQocnZhbCk7CiAgICAgICAgVmFyU3ltYm9sIHZhciA9CiAgICAgICAgICAgIG5ldyBWYXJTeW1ib2woRklOQUx8U1lOVEhFVElDLAogICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVzLmZyb21TdHJpbmcoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldC5zeW50aGV0aWNOYW1lQ2hhcigpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiIgKyBydmFsLmhhc2hDb2RlKCkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudE1ldGhvZFN5bSk7CiAgICAgICAgcnZhbCA9IGNvbnZlcnQocnZhbCx0eXBlKTsKICAgICAgICBKQ1ZhcmlhYmxlRGVjbCBkZWYgPSBtYWtlLlZhckRlZih2YXIsIHJ2YWwpOyAvLyBYWFggY2FzdAogICAgICAgIEpDRXhwcmVzc2lvbiBidWlsdCA9IGJ1aWxkZXIuYnVpbGQobWFrZS5JZGVudCh2YXIpKTsKICAgICAgICBKQ0V4cHJlc3Npb24gcmVzID0gbWFrZS5MZXRFeHByKGRlZiwgYnVpbHQpOwogICAgICAgIHJlcy50eXBlID0gYnVpbHQudHlwZTsKICAgICAgICByZXR1cm4gcmVzOwogICAgfQoKICAgIC8vIHNhbWUgYXMgYWJvdmUsIHdpdGggdGhlIHR5cGUgb2YgdGhlIHRlbXBvcmFyeSB2YXJpYWJsZSBjb21wdXRlZAogICAgSkNFeHByZXNzaW9uIGFic3RyYWN0UnZhbChKQ0V4cHJlc3Npb24gcnZhbCwgVHJlZUJ1aWxkZXIgYnVpbGRlcikgewogICAgICAgIHJldHVybiBhYnN0cmFjdFJ2YWwocnZhbCwgcnZhbC50eXBlLCBidWlsZGVyKTsKICAgIH0KCiAgICAvLyBzYW1lIGFzIGFib3ZlLCBidXQgZm9yIGFuIGV4cHJlc3Npb24gdGhhdCBtYXkgYmUgdXNlZCBhcyBlaXRoZXIKICAgIC8vIGFuIHJ2YWx1ZSBvciBhbiBsdmFsdWUuICBUaGlzIHJlcXVpcmVzIHNwZWNpYWwgaGFuZGxpbmcgZm9yCiAgICAvLyBTZWxlY3QgZXhwcmVzc2lvbnMsIHdoZXJlIHdlIHBsYWNlIHRoZSBsZWZ0LWhhbmQtc2lkZSBvZiB0aGUKICAgIC8vIHNlbGVjdCBpbiBhIHRlbXBvcmFyeSwgYW5kIGZvciBJbmRleGVkIGV4cHJlc3Npb25zLCB3aGVyZSB3ZQogICAgLy8gcGxhY2UgYm90aCB0aGUgaW5kZXhlZCBleHByZXNzaW9uIGFuZCB0aGUgaW5kZXggdmFsdWUgaW4gdGVtcHMuCiAgICBKQ0V4cHJlc3Npb24gYWJzdHJhY3RMdmFsKEpDRXhwcmVzc2lvbiBsdmFsLCBmaW5hbCBUcmVlQnVpbGRlciBidWlsZGVyKSB7CiAgICAgICAgbHZhbCA9IFRyZWVJbmZvLnNraXBQYXJlbnMobHZhbCk7CiAgICAgICAgc3dpdGNoIChsdmFsLmdldFRhZygpKSB7CiAgICAgICAgY2FzZSBJREVOVDoKICAgICAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGQobHZhbCk7CiAgICAgICAgY2FzZSBTRUxFQ1Q6IHsKICAgICAgICAgICAgZmluYWwgSkNGaWVsZEFjY2VzcyBzID0gKEpDRmllbGRBY2Nlc3MpbHZhbDsKICAgICAgICAgICAgU3ltYm9sIGxpZCA9IFRyZWVJbmZvLnN5bWJvbChzLnNlbGVjdGVkKTsKICAgICAgICAgICAgaWYgKGxpZCAhPSBudWxsICYmIGxpZC5raW5kID09IFRZUCkgcmV0dXJuIGJ1aWxkZXIuYnVpbGQobHZhbCk7CiAgICAgICAgICAgIHJldHVybiBhYnN0cmFjdFJ2YWwocy5zZWxlY3RlZCwgc2VsZWN0ZWQgLT4gYnVpbGRlci5idWlsZChtYWtlLlNlbGVjdChzZWxlY3RlZCwgcy5zeW0pKSk7CiAgICAgICAgfQogICAgICAgIGNhc2UgSU5ERVhFRDogewogICAgICAgICAgICBmaW5hbCBKQ0FycmF5QWNjZXNzIGkgPSAoSkNBcnJheUFjY2VzcylsdmFsOwogICAgICAgICAgICByZXR1cm4gYWJzdHJhY3RSdmFsKGkuaW5kZXhlZCwgaW5kZXhlZCAtPiBhYnN0cmFjdFJ2YWwoaS5pbmRleCwgc3ltcy5pbnRUeXBlLCBpbmRleCAtPiB7CiAgICAgICAgICAgICAgICBKQ0V4cHJlc3Npb24gbmV3THZhbCA9IG1ha2UuSW5kZXhlZChpbmRleGVkLCBpbmRleCk7CiAgICAgICAgICAgICAgICBuZXdMdmFsLnNldFR5cGUoaS50eXBlKTsKICAgICAgICAgICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkKG5ld0x2YWwpOwogICAgICAgICAgICB9KSk7CiAgICAgICAgfQogICAgICAgIGNhc2UgVFlQRUNBU1Q6IHsKICAgICAgICAgICAgcmV0dXJuIGFic3RyYWN0THZhbCgoKEpDVHlwZUNhc3QpbHZhbCkuZXhwciwgYnVpbGRlcik7CiAgICAgICAgfQogICAgICAgIH0KICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IobHZhbCk7CiAgICB9CgogICAgLy8gZXZhbHVhdGUgYW5kIGRpc2NhcmQgdGhlIGZpcnN0IGV4cHJlc3Npb24sIHRoZW4gZXZhbHVhdGUgdGhlIHNlY29uZC4KICAgIEpDRXhwcmVzc2lvbiBtYWtlQ29tbWEoZmluYWwgSkNFeHByZXNzaW9uIGV4cHIxLCBmaW5hbCBKQ0V4cHJlc3Npb24gZXhwcjIpIHsKICAgICAgICByZXR1cm4gYWJzdHJhY3RSdmFsKGV4cHIxLCBkaXNjYXJkZWQgLT4gZXhwcjIpOwogICAgfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFRyYW5zbGF0aW9uIG1ldGhvZHMKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgogICAgLyoqIFZpc2l0b3IgYXJndW1lbnQ6IGVuY2xvc2luZyBvcGVyYXRvciBub2RlLgogICAgICovCiAgICBwcml2YXRlIEpDRXhwcmVzc2lvbiBlbmNsT3A7CgogICAgLyoqIFZpc2l0b3IgbWV0aG9kOiBUcmFuc2xhdGUgYSBzaW5nbGUgbm9kZS4KICAgICAqICBBdHRhY2ggdGhlIHNvdXJjZSBwb3NpdGlvbiBmcm9tIHRoZSBvbGQgdHJlZSB0byBpdHMgcmVwbGFjZW1lbnQgdHJlZS4KICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgPFQgZXh0ZW5kcyBKQ1RyZWU+IFQgdHJhbnNsYXRlKFQgdHJlZSkgewogICAgICAgIGlmICh0cmVlID09IG51bGwpIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgbWFrZV9hdCh0cmVlLnBvcygpKTsKICAgICAgICAgICAgVCByZXN1bHQgPSBzdXBlci50cmFuc2xhdGUodHJlZSk7CiAgICAgICAgICAgIGlmIChlbmRQb3NUYWJsZSAhPSBudWxsICYmIHJlc3VsdCAhPSB0cmVlKSB7CiAgICAgICAgICAgICAgICBlbmRQb3NUYWJsZS5yZXBsYWNlVHJlZSh0cmVlLCByZXN1bHQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfQogICAgfQoKICAgIC8qKiBWaXNpdG9yIG1ldGhvZDogVHJhbnNsYXRlIGEgc2luZ2xlIG5vZGUsIGJveGluZyBvciB1bmJveGluZyBpZiBuZWVkZWQuCiAgICAgKi8KICAgIHB1YmxpYyA8VCBleHRlbmRzIEpDRXhwcmVzc2lvbj4gVCB0cmFuc2xhdGUoVCB0cmVlLCBUeXBlIHR5cGUpIHsKICAgICAgICByZXR1cm4gKHRyZWUgPT0gbnVsbCkgPyBudWxsIDogYm94SWZOZWVkZWQodHJhbnNsYXRlKHRyZWUpLCB0eXBlKTsKICAgIH0KCiAgICAvKiogVmlzaXRvciBtZXRob2Q6IFRyYW5zbGF0ZSB0cmVlLgogICAgICovCiAgICBwdWJsaWMgPFQgZXh0ZW5kcyBKQ1RyZWU+IFQgdHJhbnNsYXRlKFQgdHJlZSwgSkNFeHByZXNzaW9uIGVuY2xPcCkgewogICAgICAgIEpDRXhwcmVzc2lvbiBwcmV2RW5jbE9wID0gdGhpcy5lbmNsT3A7CiAgICAgICAgdGhpcy5lbmNsT3AgPSBlbmNsT3A7CiAgICAgICAgVCByZXMgPSB0cmFuc2xhdGUodHJlZSk7CiAgICAgICAgdGhpcy5lbmNsT3AgPSBwcmV2RW5jbE9wOwogICAgICAgIHJldHVybiByZXM7CiAgICB9CgogICAgLyoqIFZpc2l0b3IgbWV0aG9kOiBUcmFuc2xhdGUgbGlzdCBvZiB0cmVlcy4KICAgICAqLwogICAgcHVibGljIDxUIGV4dGVuZHMgSkNUcmVlPiBMaXN0PFQ+IHRyYW5zbGF0ZShMaXN0PFQ+IHRyZWVzLCBKQ0V4cHJlc3Npb24gZW5jbE9wKSB7CiAgICAgICAgSkNFeHByZXNzaW9uIHByZXZFbmNsT3AgPSB0aGlzLmVuY2xPcDsKICAgICAgICB0aGlzLmVuY2xPcCA9IGVuY2xPcDsKICAgICAgICBMaXN0PFQ+IHJlcyA9IHRyYW5zbGF0ZSh0cmVlcyk7CiAgICAgICAgdGhpcy5lbmNsT3AgPSBwcmV2RW5jbE9wOwogICAgICAgIHJldHVybiByZXM7CiAgICB9CgogICAgLyoqIFZpc2l0b3IgbWV0aG9kOiBUcmFuc2xhdGUgbGlzdCBvZiB0cmVlcy4KICAgICAqLwogICAgcHVibGljIDxUIGV4dGVuZHMgSkNFeHByZXNzaW9uPiBMaXN0PFQ+IHRyYW5zbGF0ZShMaXN0PFQ+IHRyZWVzLCBUeXBlIHR5cGUpIHsKICAgICAgICBpZiAodHJlZXMgPT0gbnVsbCkgcmV0dXJuIG51bGw7CiAgICAgICAgZm9yIChMaXN0PFQ+IGwgPSB0cmVlczsgbC5ub25FbXB0eSgpOyBsID0gbC50YWlsKQogICAgICAgICAgICBsLmhlYWQgPSB0cmFuc2xhdGUobC5oZWFkLCB0eXBlKTsKICAgICAgICByZXR1cm4gdHJlZXM7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRQYWNrYWdlRGVmKEpDUGFja2FnZURlY2wgdHJlZSkgewogICAgICAgIGlmICghbmVlZFBhY2thZ2VJbmZvQ2xhc3ModHJlZSkpCiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKCiAgICAgICAgbG9uZyBmbGFncyA9IEZsYWdzLkFCU1RSQUNUIHwgRmxhZ3MuSU5URVJGQUNFOwogICAgICAgIC8vIHBhY2thZ2UtaW5mbyBpcyBtYXJrZWQgU1lOVEhFVElDIGluIEpESyAxLjYgYW5kIGxhdGVyIHJlbGVhc2VzCiAgICAgICAgZmxhZ3MgPSBmbGFncyB8IEZsYWdzLlNZTlRIRVRJQzsKICAgICAgICBDbGFzc1N5bWJvbCBjID0gdHJlZS5wYWNrZ2UucGFja2FnZV9pbmZvOwogICAgICAgIGMuc2V0QXR0cmlidXRlcyh0cmVlLnBhY2tnZSk7CiAgICAgICAgYy5mbGFnc19maWVsZCB8PSBmbGFnczsKICAgICAgICBDbGFzc1R5cGUgY3R5cGUgPSAoQ2xhc3NUeXBlKSBjLnR5cGU7CiAgICAgICAgY3R5cGUuc3VwZXJ0eXBlX2ZpZWxkID0gc3ltcy5vYmplY3RUeXBlOwogICAgICAgIGN0eXBlLmludGVyZmFjZXNfZmllbGQgPSBMaXN0Lm5pbCgpOwogICAgICAgIGNyZWF0ZUluZm9DbGFzcyh0cmVlLmFubm90YXRpb25zLCBjKTsKICAgIH0KICAgIC8vIHdoZXJlCiAgICBwcml2YXRlIGJvb2xlYW4gbmVlZFBhY2thZ2VJbmZvQ2xhc3MoSkNQYWNrYWdlRGVjbCBwZCkgewogICAgICAgIHN3aXRjaCAocGtnaW5mb09wdCkgewogICAgICAgICAgICBjYXNlIEFMV0FZUzoKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICBjYXNlIExFR0FDWToKICAgICAgICAgICAgICAgIHJldHVybiBwZC5nZXRBbm5vdGF0aW9ucygpLm5vbkVtcHR5KCk7CiAgICAgICAgICAgIGNhc2UgTk9ORU1QVFk6CiAgICAgICAgICAgICAgICBmb3IgKEF0dHJpYnV0ZS5Db21wb3VuZCBhIDoKICAgICAgICAgICAgICAgICAgICAgICAgIHBkLnBhY2tnZS5nZXREZWNsYXJhdGlvbkF0dHJpYnV0ZXMoKSkgewogICAgICAgICAgICAgICAgICAgIEF0dHJpYnV0ZS5SZXRlbnRpb25Qb2xpY3kgcCA9IHR5cGVzLmdldFJldGVudGlvbihhKTsKICAgICAgICAgICAgICAgICAgICBpZiAocCAhPSBBdHRyaWJ1dGUuUmV0ZW50aW9uUG9saWN5LlNPVVJDRSkKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigpOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0TW9kdWxlRGVmKEpDTW9kdWxlRGVjbCB0cmVlKSB7CiAgICAgICAgTW9kdWxlU3ltYm9sIG1zeW0gPSB0cmVlLnN5bTsKICAgICAgICBDbGFzc1N5bWJvbCBjID0gbXN5bS5tb2R1bGVfaW5mbzsKICAgICAgICBjLnNldEF0dHJpYnV0ZXMobXN5bSk7CiAgICAgICAgYy5mbGFnc19maWVsZCB8PSBGbGFncy5NT0RVTEU7CiAgICAgICAgY3JlYXRlSW5mb0NsYXNzKExpc3QubmlsKCksIHRyZWUuc3ltLm1vZHVsZV9pbmZvKTsKICAgIH0KCiAgICBwcml2YXRlIHZvaWQgY3JlYXRlSW5mb0NsYXNzKExpc3Q8SkNBbm5vdGF0aW9uPiBhbm5vdHMsIENsYXNzU3ltYm9sIGMpIHsKICAgICAgICBsb25nIGZsYWdzID0gRmxhZ3MuQUJTVFJBQ1QgfCBGbGFncy5JTlRFUkZBQ0U7CiAgICAgICAgSkNDbGFzc0RlY2wgaW5mb0NsYXNzID0KICAgICAgICAgICAgICAgIG1ha2UuQ2xhc3NEZWYobWFrZS5Nb2RpZmllcnMoZmxhZ3MsIGFubm90cyksCiAgICAgICAgICAgICAgICAgICAgYy5uYW1lLCBMaXN0Lm5pbCgpLAogICAgICAgICAgICAgICAgICAgIG51bGwsIExpc3QubmlsKCksIExpc3QubmlsKCkpOwogICAgICAgIGluZm9DbGFzcy5zeW0gPSBjOwogICAgICAgIHRyYW5zbGF0ZWQuYXBwZW5kKGluZm9DbGFzcyk7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRDbGFzc0RlZihKQ0NsYXNzRGVjbCB0cmVlKSB7CiAgICAgICAgRW52PEF0dHJDb250ZXh0PiBwcmV2RW52ID0gYXR0ckVudjsKICAgICAgICBDbGFzc1N5bWJvbCBjdXJyZW50Q2xhc3NQcmV2ID0gY3VycmVudENsYXNzOwogICAgICAgIE1ldGhvZFN5bWJvbCBjdXJyZW50TWV0aG9kU3ltUHJldiA9IGN1cnJlbnRNZXRob2RTeW07CgogICAgICAgIGN1cnJlbnRDbGFzcyA9IHRyZWUuc3ltOwogICAgICAgIGN1cnJlbnRNZXRob2RTeW0gPSBudWxsOwogICAgICAgIGF0dHJFbnYgPSB0eXBlRW52cy5yZW1vdmUoY3VycmVudENsYXNzKTsKICAgICAgICBpZiAoYXR0ckVudiA9PSBudWxsKQogICAgICAgICAgICBhdHRyRW52ID0gcHJldkVudjsKCiAgICAgICAgY2xhc3NkZWZzLnB1dChjdXJyZW50Q2xhc3MsIHRyZWUpOwoKICAgICAgICBwcm94aWVzID0gcHJveGllcy5kdXAoY3VycmVudENsYXNzKTsKICAgICAgICBMaXN0PFZhclN5bWJvbD4gcHJldk91dGVyVGhpc1N0YWNrID0gb3V0ZXJUaGlzU3RhY2s7CgogICAgICAgIC8vIElmIHRoaXMgaXMgYW4gZW51bSBkZWZpbml0aW9uCiAgICAgICAgaWYgKCh0cmVlLm1vZHMuZmxhZ3MgJiBFTlVNKSAhPSAwICYmCiAgICAgICAgICAgICh0eXBlcy5zdXBlcnR5cGUoY3VycmVudENsYXNzLnR5cGUpLnRzeW0uZmxhZ3MoKSAmIEVOVU0pID09IDApCiAgICAgICAgICAgIHZpc2l0RW51bURlZih0cmVlKTsKCiAgICAgICAgLy8gSWYgdGhpcyBpcyBhIG5lc3RlZCBjbGFzcywgZGVmaW5lIGEgdGhpcyRuIGZpZWxkIGZvcgogICAgICAgIC8vIGl0IGFuZCBhZGQgdG8gcHJveGllcy4KICAgICAgICBKQ1ZhcmlhYmxlRGVjbCBvdGRlZiA9IG51bGw7CiAgICAgICAgaWYgKGN1cnJlbnRDbGFzcy5oYXNPdXRlckluc3RhbmNlKCkpCiAgICAgICAgICAgIG90ZGVmID0gb3V0ZXJUaGlzRGVmKHRyZWUucG9zLCBjdXJyZW50Q2xhc3MpOwoKICAgICAgICAvLyBJZiB0aGlzIGlzIGEgbG9jYWwgY2xhc3MsIGRlZmluZSBwcm94aWVzIGZvciBhbGwgaXRzIGZyZWUgdmFyaWFibGVzLgogICAgICAgIExpc3Q8SkNWYXJpYWJsZURlY2w+IGZ2ZGVmcyA9IGZyZWV2YXJEZWZzKAogICAgICAgICAgICB0cmVlLnBvcywgZnJlZXZhcnMoY3VycmVudENsYXNzKSwgY3VycmVudENsYXNzKTsKCiAgICAgICAgLy8gUmVjdXJzaXZlbHkgdHJhbnNsYXRlIHN1cGVyY2xhc3MsIGludGVyZmFjZXMuCiAgICAgICAgdHJlZS5leHRlbmRpbmcgPSB0cmFuc2xhdGUodHJlZS5leHRlbmRpbmcpOwogICAgICAgIHRyZWUuaW1wbGVtZW50aW5nID0gdHJhbnNsYXRlKHRyZWUuaW1wbGVtZW50aW5nKTsKCiAgICAgICAgaWYgKGN1cnJlbnRDbGFzcy5pc0xvY2FsKCkpIHsKICAgICAgICAgICAgQ2xhc3NTeW1ib2wgZW5jbCA9IGN1cnJlbnRDbGFzcy5vd25lci5lbmNsQ2xhc3MoKTsKICAgICAgICAgICAgaWYgKGVuY2wudHJhbnNfbG9jYWwgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgZW5jbC50cmFuc19sb2NhbCA9IExpc3QubmlsKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZW5jbC50cmFuc19sb2NhbCA9IGVuY2wudHJhbnNfbG9jYWwucHJlcGVuZChjdXJyZW50Q2xhc3MpOwogICAgICAgIH0KCiAgICAgICAgLy8gUmVjdXJzaXZlbHkgdHJhbnNsYXRlIG1lbWJlcnMsIHRha2luZyBpbnRvIGFjY291bnQgdGhhdCBuZXcgbWVtYmVycwogICAgICAgIC8vIG1pZ2h0IGJlIGNyZWF0ZWQgZHVyaW5nIHRoZSB0cmFuc2xhdGlvbiBhbmQgcHJlcGVuZGVkIHRvIHRoZSBtZW1iZXIKICAgICAgICAvLyBsaXN0IGB0cmVlLmRlZnMnLgogICAgICAgIExpc3Q8SkNUcmVlPiBzZWVuID0gTGlzdC5uaWwoKTsKICAgICAgICB3aGlsZSAodHJlZS5kZWZzICE9IHNlZW4pIHsKICAgICAgICAgICAgTGlzdDxKQ1RyZWU+IHVuc2VlbiA9IHRyZWUuZGVmczsKICAgICAgICAgICAgZm9yIChMaXN0PEpDVHJlZT4gbCA9IHVuc2VlbjsgbC5ub25FbXB0eSgpICYmIGwgIT0gc2VlbjsgbCA9IGwudGFpbCkgewogICAgICAgICAgICAgICAgSkNUcmVlIG91dGVybW9zdE1lbWJlckRlZlByZXYgPSBvdXRlcm1vc3RNZW1iZXJEZWY7CiAgICAgICAgICAgICAgICBpZiAob3V0ZXJtb3N0TWVtYmVyRGVmUHJldiA9PSBudWxsKSBvdXRlcm1vc3RNZW1iZXJEZWYgPSBsLmhlYWQ7CiAgICAgICAgICAgICAgICBsLmhlYWQgPSB0cmFuc2xhdGUobC5oZWFkKTsKICAgICAgICAgICAgICAgIG91dGVybW9zdE1lbWJlckRlZiA9IG91dGVybW9zdE1lbWJlckRlZlByZXY7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc2VlbiA9IHVuc2VlbjsKICAgICAgICB9CgogICAgICAgIC8vIENvbnZlcnQgYSBwcm90ZWN0ZWQgbW9kaWZpZXIgdG8gcHVibGljLCBtYXNrIHN0YXRpYyBtb2RpZmllci4KICAgICAgICBpZiAoKHRyZWUubW9kcy5mbGFncyAmIFBST1RFQ1RFRCkgIT0gMCkgdHJlZS5tb2RzLmZsYWdzIHw9IFBVQkxJQzsKICAgICAgICB0cmVlLm1vZHMuZmxhZ3MgJj0gQ2xhc3NGbGFnczsKCiAgICAgICAgLy8gQ29udmVydCBuYW1lIHRvIGZsYXQgcmVwcmVzZW50YXRpb24sIHJlcGxhY2luZyAnLicgYnkgJyQnLgogICAgICAgIHRyZWUubmFtZSA9IENvbnZlcnQuc2hvcnROYW1lKGN1cnJlbnRDbGFzcy5mbGF0TmFtZSgpKTsKCiAgICAgICAgLy8gQWRkIHRoaXMkbiBhbmQgZnJlZSB2YXJpYWJsZXMgcHJveHkgZGVmaW5pdGlvbnMgdG8gY2xhc3MuCgogICAgICAgIGZvciAoTGlzdDxKQ1ZhcmlhYmxlRGVjbD4gbCA9IGZ2ZGVmczsgbC5ub25FbXB0eSgpOyBsID0gbC50YWlsKSB7CiAgICAgICAgICAgIHRyZWUuZGVmcyA9IHRyZWUuZGVmcy5wcmVwZW5kKGwuaGVhZCk7CiAgICAgICAgICAgIGVudGVyU3ludGhldGljKHRyZWUucG9zKCksIGwuaGVhZC5zeW0sIGN1cnJlbnRDbGFzcy5tZW1iZXJzKCkpOwogICAgICAgIH0KICAgICAgICBpZiAoY3VycmVudENsYXNzLmhhc091dGVySW5zdGFuY2UoKSkgewogICAgICAgICAgICB0cmVlLmRlZnMgPSB0cmVlLmRlZnMucHJlcGVuZChvdGRlZik7CiAgICAgICAgICAgIGVudGVyU3ludGhldGljKHRyZWUucG9zKCksIG90ZGVmLnN5bSwgY3VycmVudENsYXNzLm1lbWJlcnMoKSk7CiAgICAgICAgfQoKICAgICAgICBwcm94aWVzID0gcHJveGllcy5sZWF2ZSgpOwogICAgICAgIG91dGVyVGhpc1N0YWNrID0gcHJldk91dGVyVGhpc1N0YWNrOwoKICAgICAgICAvLyBBcHBlbmQgdHJhbnNsYXRlZCB0cmVlIHRvIGB0cmFuc2xhdGVkJyBxdWV1ZS4KICAgICAgICB0cmFuc2xhdGVkLmFwcGVuZCh0cmVlKTsKCiAgICAgICAgYXR0ckVudiA9IHByZXZFbnY7CiAgICAgICAgY3VycmVudENsYXNzID0gY3VycmVudENsYXNzUHJldjsKICAgICAgICBjdXJyZW50TWV0aG9kU3ltID0gY3VycmVudE1ldGhvZFN5bVByZXY7CgogICAgICAgIC8vIFJldHVybiBlbXB0eSBibG9jayB7fSBhcyBhIHBsYWNlaG9sZGVyIGZvciBhbiBpbm5lciBjbGFzcy4KICAgICAgICByZXN1bHQgPSBtYWtlX2F0KHRyZWUucG9zKCkpLkJsb2NrKFNZTlRIRVRJQywgTGlzdC5uaWwoKSk7CiAgICB9CgogICAgLyoqIFRyYW5zbGF0ZSBhbiBlbnVtIGNsYXNzLiAqLwogICAgcHJpdmF0ZSB2b2lkIHZpc2l0RW51bURlZihKQ0NsYXNzRGVjbCB0cmVlKSB7CiAgICAgICAgbWFrZV9hdCh0cmVlLnBvcygpKTsKCiAgICAgICAgLy8gYWRkIHRoZSBzdXBlcnR5cGUsIGlmIG5lZWRlZAogICAgICAgIGlmICh0cmVlLmV4dGVuZGluZyA9PSBudWxsKQogICAgICAgICAgICB0cmVlLmV4dGVuZGluZyA9IG1ha2UuVHlwZSh0eXBlcy5zdXBlcnR5cGUodHJlZS50eXBlKSk7CgogICAgICAgIC8vIGNsYXNzT2ZUeXBlIGFkZHMgYSBjYWNoZSBmaWVsZCB0byB0cmVlLmRlZnMKICAgICAgICBKQ0V4cHJlc3Npb24gZV9jbGFzcyA9IGNsYXNzT2ZUeXBlKHRyZWUuc3ltLnR5cGUsIHRyZWUucG9zKCkpLgogICAgICAgICAgICBzZXRUeXBlKHR5cGVzLmVyYXN1cmUoc3ltcy5jbGFzc1R5cGUpKTsKCiAgICAgICAgLy8gcHJvY2VzcyBlYWNoIGVudW1lcmF0aW9uIGNvbnN0YW50LCBhZGRpbmcgaW1wbGljaXQgY29uc3RydWN0b3IgcGFyYW1ldGVycwogICAgICAgIGludCBuZXh0T3JkaW5hbCA9IDA7CiAgICAgICAgTGlzdEJ1ZmZlcjxKQ0V4cHJlc3Npb24+IHZhbHVlcyA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICBMaXN0QnVmZmVyPEpDVHJlZT4gZW51bURlZnMgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgTGlzdEJ1ZmZlcjxKQ1RyZWU+IG90aGVyRGVmcyA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICBmb3IgKExpc3Q8SkNUcmVlPiBkZWZzID0gdHJlZS5kZWZzOwogICAgICAgICAgICAgZGVmcy5ub25FbXB0eSgpOwogICAgICAgICAgICAgZGVmcz1kZWZzLnRhaWwpIHsKICAgICAgICAgICAgaWYgKGRlZnMuaGVhZC5oYXNUYWcoVkFSREVGKSAmJiAoKChKQ1ZhcmlhYmxlRGVjbCkgZGVmcy5oZWFkKS5tb2RzLmZsYWdzICYgRU5VTSkgIT0gMCkgewogICAgICAgICAgICAgICAgSkNWYXJpYWJsZURlY2wgdmFyID0gKEpDVmFyaWFibGVEZWNsKWRlZnMuaGVhZDsKICAgICAgICAgICAgICAgIHZpc2l0RW51bUNvbnN0YW50RGVmKHZhciwgbmV4dE9yZGluYWwrKyk7CiAgICAgICAgICAgICAgICB2YWx1ZXMuYXBwZW5kKG1ha2UuUXVhbElkZW50KHZhci5zeW0pKTsKICAgICAgICAgICAgICAgIGVudW1EZWZzLmFwcGVuZCh2YXIpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgb3RoZXJEZWZzLmFwcGVuZChkZWZzLmhlYWQpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBwcml2YXRlIHN0YXRpYyBmaW5hbCBUW10gI1ZBTFVFUyA9IHsgYSwgYiwgYyB9OwogICAgICAgIE5hbWUgdmFsdWVzTmFtZSA9IG5hbWVzLmZyb21TdHJpbmcodGFyZ2V0LnN5bnRoZXRpY05hbWVDaGFyKCkgKyAiVkFMVUVTIik7CiAgICAgICAgd2hpbGUgKHRyZWUuc3ltLm1lbWJlcnMoKS5maW5kRmlyc3QodmFsdWVzTmFtZSkgIT0gbnVsbCkgLy8gYXZvaWQgbmFtZSBjbGFzaAogICAgICAgICAgICB2YWx1ZXNOYW1lID0gbmFtZXMuZnJvbVN0cmluZyh2YWx1ZXNOYW1lICsgIiIgKyB0YXJnZXQuc3ludGhldGljTmFtZUNoYXIoKSk7CiAgICAgICAgVHlwZSBhcnJheVR5cGUgPSBuZXcgQXJyYXlUeXBlKHR5cGVzLmVyYXN1cmUodHJlZS50eXBlKSwgc3ltcy5hcnJheUNsYXNzKTsKICAgICAgICBWYXJTeW1ib2wgdmFsdWVzVmFyID0gbmV3IFZhclN5bWJvbChQUklWQVRFfEZJTkFMfFNUQVRJQ3xTWU5USEVUSUMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVzTmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnJheVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJlZS50eXBlLnRzeW0pOwogICAgICAgIEpDTmV3QXJyYXkgbmV3QXJyYXkgPSBtYWtlLk5ld0FycmF5KG1ha2UuVHlwZSh0eXBlcy5lcmFzdXJlKHRyZWUudHlwZSkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0Lm5pbCgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZXMudG9MaXN0KCkpOwogICAgICAgIG5ld0FycmF5LnR5cGUgPSBhcnJheVR5cGU7CiAgICAgICAgZW51bURlZnMuYXBwZW5kKG1ha2UuVmFyRGVmKHZhbHVlc1ZhciwgbmV3QXJyYXkpKTsKICAgICAgICB0cmVlLnN5bS5tZW1iZXJzKCkuZW50ZXIodmFsdWVzVmFyKTsKCiAgICAgICAgU3ltYm9sIHZhbHVlc1N5bSA9IGxvb2t1cE1ldGhvZCh0cmVlLnBvcygpLCBuYW1lcy52YWx1ZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmVlLnR5cGUsIExpc3QubmlsKCkpOwogICAgICAgIExpc3Q8SkNTdGF0ZW1lbnQ+IHZhbHVlc0JvZHk7CiAgICAgICAgaWYgKHVzZUNsb25lKCkpIHsKICAgICAgICAgICAgLy8gcmV0dXJuIChUW10pICRWQUxVRVMuY2xvbmUoKTsKICAgICAgICAgICAgSkNUeXBlQ2FzdCB2YWx1ZXNSZXN1bHQgPQogICAgICAgICAgICAgICAgbWFrZS5UeXBlQ2FzdCh2YWx1ZXNTeW0udHlwZS5nZXRSZXR1cm5UeXBlKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ha2UuQXBwKG1ha2UuU2VsZWN0KG1ha2UuSWRlbnQodmFsdWVzVmFyKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ltcy5hcnJheUNsb25lTWV0aG9kKSkpOwogICAgICAgICAgICB2YWx1ZXNCb2R5ID0gTGlzdC5vZihtYWtlLlJldHVybih2YWx1ZXNSZXN1bHQpKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvLyB0ZW1wbGF0ZTogVFtdICRyZXN1bHQgPSBuZXcgVFskdmFsdWVzLmxlbmd0aF07CiAgICAgICAgICAgIE5hbWUgcmVzdWx0TmFtZSA9IG5hbWVzLmZyb21TdHJpbmcodGFyZ2V0LnN5bnRoZXRpY05hbWVDaGFyKCkgKyAicmVzdWx0Iik7CiAgICAgICAgICAgIHdoaWxlICh0cmVlLnN5bS5tZW1iZXJzKCkuZmluZEZpcnN0KHJlc3VsdE5hbWUpICE9IG51bGwpIC8vIGF2b2lkIG5hbWUgY2xhc2gKICAgICAgICAgICAgICAgIHJlc3VsdE5hbWUgPSBuYW1lcy5mcm9tU3RyaW5nKHJlc3VsdE5hbWUgKyAiIiArIHRhcmdldC5zeW50aGV0aWNOYW1lQ2hhcigpKTsKICAgICAgICAgICAgVmFyU3ltYm9sIHJlc3VsdFZhciA9IG5ldyBWYXJTeW1ib2woRklOQUx8U1lOVEhFVElDLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHROYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnJheVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlc1N5bSk7CiAgICAgICAgICAgIEpDTmV3QXJyYXkgcmVzdWx0QXJyYXkgPSBtYWtlLk5ld0FycmF5KG1ha2UuVHlwZSh0eXBlcy5lcmFzdXJlKHRyZWUudHlwZSkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTGlzdC5vZihtYWtlLlNlbGVjdChtYWtlLklkZW50KHZhbHVlc1ZhciksIHN5bXMubGVuZ3RoVmFyKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsKTsKICAgICAgICAgICAgcmVzdWx0QXJyYXkudHlwZSA9IGFycmF5VHlwZTsKICAgICAgICAgICAgSkNWYXJpYWJsZURlY2wgZGVjbCA9IG1ha2UuVmFyRGVmKHJlc3VsdFZhciwgcmVzdWx0QXJyYXkpOwoKICAgICAgICAgICAgLy8gdGVtcGxhdGU6IFN5c3RlbS5hcnJheWNvcHkoJFZBTFVFUywgMCwgJHJlc3VsdCwgMCwgJFZBTFVFUy5sZW5ndGgpOwogICAgICAgICAgICBpZiAoc3lzdGVtQXJyYXljb3B5TWV0aG9kID09IG51bGwpIHsKICAgICAgICAgICAgICAgIHN5c3RlbUFycmF5Y29weU1ldGhvZCA9CiAgICAgICAgICAgICAgICAgICAgbmV3IE1ldGhvZFN5bWJvbChQVUJMSUMgfCBTVEFUSUMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lcy5mcm9tU3RyaW5nKCJhcnJheWNvcHkiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBNZXRob2RUeXBlKExpc3Qub2Yoc3ltcy5vYmplY3RUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeW1zLmludFR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5bXMub2JqZWN0VHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ltcy5pbnRUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeW1zLmludFR5cGUpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ltcy52b2lkVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExpc3QubmlsKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeW1zLm1ldGhvZENsYXNzKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5bXMuc3lzdGVtVHlwZS50c3ltKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBKQ1N0YXRlbWVudCBjb3B5ID0KICAgICAgICAgICAgICAgIG1ha2UuRXhlYyhtYWtlLkFwcChtYWtlLlNlbGVjdChtYWtlLklkZW50KHN5bXMuc3lzdGVtVHlwZS50c3ltKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeXN0ZW1BcnJheWNvcHlNZXRob2QpLAogICAgICAgICAgICAgICAgICAgICAgICAgIExpc3Qub2YobWFrZS5JZGVudCh2YWx1ZXNWYXIpLCBtYWtlLkxpdGVyYWwoMCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYWtlLklkZW50KHJlc3VsdFZhciksIG1ha2UuTGl0ZXJhbCgwKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ha2UuU2VsZWN0KG1ha2UuSWRlbnQodmFsdWVzVmFyKSwgc3ltcy5sZW5ndGhWYXIpKSkpOwoKICAgICAgICAgICAgLy8gdGVtcGxhdGU6IHJldHVybiAkcmVzdWx0OwogICAgICAgICAgICBKQ1N0YXRlbWVudCByZXQgPSBtYWtlLlJldHVybihtYWtlLklkZW50KHJlc3VsdFZhcikpOwogICAgICAgICAgICB2YWx1ZXNCb2R5ID0gTGlzdC5vZihkZWNsLCBjb3B5LCByZXQpOwogICAgICAgIH0KCiAgICAgICAgSkNNZXRob2REZWNsIHZhbHVlc0RlZiA9CiAgICAgICAgICAgICBtYWtlLk1ldGhvZERlZigoTWV0aG9kU3ltYm9sKXZhbHVlc1N5bSwgbWFrZS5CbG9jaygwLCB2YWx1ZXNCb2R5KSk7CgogICAgICAgIGVudW1EZWZzLmFwcGVuZCh2YWx1ZXNEZWYpOwoKICAgICAgICBpZiAoZGVidWdMb3dlcikKICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKHRyZWUuc3ltICsgIi52YWx1ZXNEZWYgPSAiICsgdmFsdWVzRGVmKTsKCiAgICAgICAgLyoqIFRoZSB0ZW1wbGF0ZSBmb3IgdGhlIGZvbGxvd2luZyBjb2RlIGlzOgogICAgICAgICAqCiAgICAgICAgICogICAgIHB1YmxpYyBzdGF0aWMgRSB2YWx1ZU9mKFN0cmluZyBuYW1lKSB7CiAgICAgICAgICogICAgICAgICByZXR1cm4gKEUpRW51bS52YWx1ZU9mKEUuY2xhc3MsIG5hbWUpOwogICAgICAgICAqICAgICB9CiAgICAgICAgICoKICAgICAgICAgKiAgd2hlcmUgRSBpcyB0cmVlLnN5bQogICAgICAgICAqLwogICAgICAgIE1ldGhvZFN5bWJvbCB2YWx1ZU9mU3ltID0gbG9va3VwTWV0aG9kKHRyZWUucG9zKCksCiAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lcy52YWx1ZU9mLAogICAgICAgICAgICAgICAgICAgICAgICAgdHJlZS5zeW0udHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgIExpc3Qub2Yoc3ltcy5zdHJpbmdUeXBlKSk7CiAgICAgICAgQXNzZXJ0LmNoZWNrKCh2YWx1ZU9mU3ltLmZsYWdzKCkgJiBTVEFUSUMpICE9IDApOwogICAgICAgIFZhclN5bWJvbCBuYW1lQXJnU3ltID0gdmFsdWVPZlN5bS5wYXJhbXMuaGVhZDsKICAgICAgICBKQ0lkZW50IG5hbWVWYWwgPSBtYWtlLklkZW50KG5hbWVBcmdTeW0pOwogICAgICAgIEpDU3RhdGVtZW50IGVudW1fVmFsdWVPZiA9CiAgICAgICAgICAgIG1ha2UuUmV0dXJuKG1ha2UuVHlwZUNhc3QodHJlZS5zeW0udHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYWtlQ2FsbChtYWtlLklkZW50KHN5bXMuZW51bVN5bSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZXMudmFsdWVPZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0Lm9mKGVfY2xhc3MsIG5hbWVWYWwpKSkpOwogICAgICAgIEpDTWV0aG9kRGVjbCB2YWx1ZU9mID0gbWFrZS5NZXRob2REZWYodmFsdWVPZlN5bSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ha2UuQmxvY2soMCwgTGlzdC5vZihlbnVtX1ZhbHVlT2YpKSk7CiAgICAgICAgbmFtZVZhbC5zeW0gPSB2YWx1ZU9mLnBhcmFtcy5oZWFkLnN5bTsKICAgICAgICBpZiAoZGVidWdMb3dlcikKICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKHRyZWUuc3ltICsgIi52YWx1ZU9mID0gIiArIHZhbHVlT2YpOwogICAgICAgIGVudW1EZWZzLmFwcGVuZCh2YWx1ZU9mKTsKCiAgICAgICAgZW51bURlZnMuYXBwZW5kTGlzdChvdGhlckRlZnMudG9MaXN0KCkpOwogICAgICAgIHRyZWUuZGVmcyA9IGVudW1EZWZzLnRvTGlzdCgpOwogICAgfQogICAgICAgIC8vIHdoZXJlCiAgICAgICAgcHJpdmF0ZSBNZXRob2RTeW1ib2wgc3lzdGVtQXJyYXljb3B5TWV0aG9kOwogICAgICAgIHByaXZhdGUgYm9vbGVhbiB1c2VDbG9uZSgpIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIHJldHVybiBzeW1zLm9iamVjdFR5cGUudHN5bS5tZW1iZXJzKCkuZmluZEZpcnN0KG5hbWVzLmNsb25lKSAhPSBudWxsOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGNhdGNoIChDb21wbGV0aW9uRmFpbHVyZSBlKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgLyoqIFRyYW5zbGF0ZSBhbiBlbnVtZXJhdGlvbiBjb25zdGFudCBhbmQgaXRzIGluaXRpYWxpemVyLiAqLwogICAgcHJpdmF0ZSB2b2lkIHZpc2l0RW51bUNvbnN0YW50RGVmKEpDVmFyaWFibGVEZWNsIHZhciwgaW50IG9yZGluYWwpIHsKICAgICAgICBKQ05ld0NsYXNzIHZhckRlZiA9IChKQ05ld0NsYXNzKXZhci5pbml0OwogICAgICAgIHZhckRlZi5hcmdzID0gdmFyRGVmLmFyZ3MuCiAgICAgICAgICAgIHByZXBlbmQobWFrZUxpdChzeW1zLmludFR5cGUsIG9yZGluYWwpKS4KICAgICAgICAgICAgcHJlcGVuZChtYWtlTGl0KHN5bXMuc3RyaW5nVHlwZSwgdmFyLm5hbWUudG9TdHJpbmcoKSkpOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0TWV0aG9kRGVmKEpDTWV0aG9kRGVjbCB0cmVlKSB7CiAgICAgICAgaWYgKHRyZWUubmFtZSA9PSBuYW1lcy5pbml0ICYmIChjdXJyZW50Q2xhc3MuZmxhZ3NfZmllbGQmRU5VTSkgIT0gMCkgewogICAgICAgICAgICAvLyBBZGQgIlN0cmluZyAkZW51bSRuYW1lLCBpbnQgJGVudW0kb3JkaW5hbCIgdG8gdGhlIGJlZ2lubmluZyBvZiB0aGUKICAgICAgICAgICAgLy8gYXJndW1lbnQgbGlzdCBmb3IgZWFjaCBjb25zdHJ1Y3RvciBvZiBhbiBlbnVtLgogICAgICAgICAgICBKQ1ZhcmlhYmxlRGVjbCBuYW1lUGFyYW0gPSBtYWtlX2F0KHRyZWUucG9zKCkpLgogICAgICAgICAgICAgICAgUGFyYW0obmFtZXMuZnJvbVN0cmluZyh0YXJnZXQuc3ludGhldGljTmFtZUNoYXIoKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJlbnVtIiArIHRhcmdldC5zeW50aGV0aWNOYW1lQ2hhcigpICsgIm5hbWUiKSwKICAgICAgICAgICAgICAgICAgICAgIHN5bXMuc3RyaW5nVHlwZSwgdHJlZS5zeW0pOwogICAgICAgICAgICBuYW1lUGFyYW0ubW9kcy5mbGFncyB8PSBTWU5USEVUSUM7IG5hbWVQYXJhbS5zeW0uZmxhZ3NfZmllbGQgfD0gU1lOVEhFVElDOwogICAgICAgICAgICBKQ1ZhcmlhYmxlRGVjbCBvcmRQYXJhbSA9IG1ha2UuCiAgICAgICAgICAgICAgICBQYXJhbShuYW1lcy5mcm9tU3RyaW5nKHRhcmdldC5zeW50aGV0aWNOYW1lQ2hhcigpICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImVudW0iICsgdGFyZ2V0LnN5bnRoZXRpY05hbWVDaGFyKCkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAib3JkaW5hbCIpLAogICAgICAgICAgICAgICAgICAgICAgc3ltcy5pbnRUeXBlLCB0cmVlLnN5bSk7CiAgICAgICAgICAgIG9yZFBhcmFtLm1vZHMuZmxhZ3MgfD0gU1lOVEhFVElDOyBvcmRQYXJhbS5zeW0uZmxhZ3NfZmllbGQgfD0gU1lOVEhFVElDOwoKICAgICAgICAgICAgTWV0aG9kU3ltYm9sIG0gPSB0cmVlLnN5bTsKICAgICAgICAgICAgdHJlZS5wYXJhbXMgPSB0cmVlLnBhcmFtcy5wcmVwZW5kKG9yZFBhcmFtKS5wcmVwZW5kKG5hbWVQYXJhbSk7CgogICAgICAgICAgICBtLmV4dHJhUGFyYW1zID0gbS5leHRyYVBhcmFtcy5wcmVwZW5kKG9yZFBhcmFtLnN5bSk7CiAgICAgICAgICAgIG0uZXh0cmFQYXJhbXMgPSBtLmV4dHJhUGFyYW1zLnByZXBlbmQobmFtZVBhcmFtLnN5bSk7CiAgICAgICAgICAgIFR5cGUgb2xkZXJhc3VyZSA9IG0uZXJhc3VyZSh0eXBlcyk7CiAgICAgICAgICAgIG0uZXJhc3VyZV9maWVsZCA9IG5ldyBNZXRob2RUeXBlKAogICAgICAgICAgICAgICAgb2xkZXJhc3VyZS5nZXRQYXJhbWV0ZXJUeXBlcygpLnByZXBlbmQoc3ltcy5pbnRUeXBlKS5wcmVwZW5kKHN5bXMuc3RyaW5nVHlwZSksCiAgICAgICAgICAgICAgICBvbGRlcmFzdXJlLmdldFJldHVyblR5cGUoKSwKICAgICAgICAgICAgICAgIG9sZGVyYXN1cmUuZ2V0VGhyb3duVHlwZXMoKSwKICAgICAgICAgICAgICAgIHN5bXMubWV0aG9kQ2xhc3MpOwogICAgICAgIH0KCiAgICAgICAgSkNNZXRob2REZWNsIHByZXZNZXRob2REZWYgPSBjdXJyZW50TWV0aG9kRGVmOwogICAgICAgIE1ldGhvZFN5bWJvbCBwcmV2TWV0aG9kU3ltID0gY3VycmVudE1ldGhvZFN5bTsKICAgICAgICB0cnkgewogICAgICAgICAgICBjdXJyZW50TWV0aG9kRGVmID0gdHJlZTsKICAgICAgICAgICAgY3VycmVudE1ldGhvZFN5bSA9IHRyZWUuc3ltOwogICAgICAgICAgICB2aXNpdE1ldGhvZERlZkludGVybmFsKHRyZWUpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgIGN1cnJlbnRNZXRob2REZWYgPSBwcmV2TWV0aG9kRGVmOwogICAgICAgICAgICBjdXJyZW50TWV0aG9kU3ltID0gcHJldk1ldGhvZFN5bTsKICAgICAgICB9CiAgICB9CgogICAgcHJpdmF0ZSB2b2lkIHZpc2l0TWV0aG9kRGVmSW50ZXJuYWwoSkNNZXRob2REZWNsIHRyZWUpIHsKICAgICAgICBpZiAodHJlZS5uYW1lID09IG5hbWVzLmluaXQgJiYKICAgICAgICAgICAgKGN1cnJlbnRDbGFzcy5pc0lubmVyKCkgfHwgY3VycmVudENsYXNzLmlzTG9jYWwoKSkpIHsKICAgICAgICAgICAgLy8gV2UgYXJlIHNlZWluZyBhIGNvbnN0cnVjdG9yIG9mIGFuIGlubmVyIGNsYXNzLgogICAgICAgICAgICBNZXRob2RTeW1ib2wgbSA9IHRyZWUuc3ltOwoKICAgICAgICAgICAgLy8gUHVzaCBhIG5ldyBwcm94eSBzY29wZSBmb3IgY29uc3RydWN0b3IgcGFyYW1ldGVycy4KICAgICAgICAgICAgLy8gYW5kIGNyZWF0ZSBkZWZpbml0aW9ucyBmb3IgYW55IHRoaXMkbiBhbmQgcHJveHkgcGFyYW1ldGVycy4KICAgICAgICAgICAgcHJveGllcyA9IHByb3hpZXMuZHVwKG0pOwogICAgICAgICAgICBMaXN0PFZhclN5bWJvbD4gcHJldk91dGVyVGhpc1N0YWNrID0gb3V0ZXJUaGlzU3RhY2s7CiAgICAgICAgICAgIExpc3Q8VmFyU3ltYm9sPiBmdnMgPSBmcmVldmFycyhjdXJyZW50Q2xhc3MpOwogICAgICAgICAgICBKQ1ZhcmlhYmxlRGVjbCBvdGRlZiA9IG51bGw7CiAgICAgICAgICAgIGlmIChjdXJyZW50Q2xhc3MuaGFzT3V0ZXJJbnN0YW5jZSgpKQogICAgICAgICAgICAgICAgb3RkZWYgPSBvdXRlclRoaXNEZWYodHJlZS5wb3MsIG0pOwogICAgICAgICAgICBMaXN0PEpDVmFyaWFibGVEZWNsPiBmdmRlZnMgPSBmcmVldmFyRGVmcyh0cmVlLnBvcywgZnZzLCBtLCBQQVJBTUVURVIpOwoKICAgICAgICAgICAgLy8gUmVjdXJzaXZlbHkgdHJhbnNsYXRlIHJlc3VsdCB0eXBlLCBwYXJhbWV0ZXJzIGFuZCB0aHJvd24gbGlzdC4KICAgICAgICAgICAgdHJlZS5yZXN0eXBlID0gdHJhbnNsYXRlKHRyZWUucmVzdHlwZSk7CiAgICAgICAgICAgIHRyZWUucGFyYW1zID0gdHJhbnNsYXRlVmFyRGVmcyh0cmVlLnBhcmFtcyk7CiAgICAgICAgICAgIHRyZWUudGhyb3duID0gdHJhbnNsYXRlKHRyZWUudGhyb3duKTsKCiAgICAgICAgICAgIC8vIHdoZW4gY29tcGlsaW5nIHN0dWJzLCBkb24ndCBwcm9jZXNzIGJvZHkKICAgICAgICAgICAgaWYgKHRyZWUuYm9keSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICByZXN1bHQgPSB0cmVlOwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBBZGQgdGhpcyRuIChpZiBuZWVkZWQpIGluIGZyb250IG9mIGFuZCBmcmVlIHZhcmlhYmxlcyBiZWhpbmQKICAgICAgICAgICAgLy8gY29uc3RydWN0b3IgcGFyYW1ldGVyIGxpc3QuCiAgICAgICAgICAgIHRyZWUucGFyYW1zID0gdHJlZS5wYXJhbXMuYXBwZW5kTGlzdChmdmRlZnMpOwogICAgICAgICAgICBpZiAoY3VycmVudENsYXNzLmhhc091dGVySW5zdGFuY2UoKSkgewogICAgICAgICAgICAgICAgdHJlZS5wYXJhbXMgPSB0cmVlLnBhcmFtcy5wcmVwZW5kKG90ZGVmKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gSWYgdGhpcyBpcyBhbiBpbml0aWFsIGNvbnN0cnVjdG9yLCBpLmUuLCBpdCBkb2VzIG5vdCBzdGFydCB3aXRoCiAgICAgICAgICAgIC8vIHRoaXMoLi4uKSwgaW5zZXJ0IGluaXRpYWxpemVycyBmb3IgdGhpcyRuIGFuZCBwcm94aWVzCiAgICAgICAgICAgIC8vIGJlZm9yZSAocHJlLTEuNCwgYWZ0ZXIpIHRoZSBjYWxsIHRvIHN1cGVyY2xhc3MgY29uc3RydWN0b3IuCiAgICAgICAgICAgIEpDU3RhdGVtZW50IHNlbGZDYWxsID0gdHJhbnNsYXRlKHRyZWUuYm9keS5zdGF0cy5oZWFkKTsKCiAgICAgICAgICAgIExpc3Q8SkNTdGF0ZW1lbnQ+IGFkZGVkID0gTGlzdC5uaWwoKTsKICAgICAgICAgICAgaWYgKGZ2cy5ub25FbXB0eSgpKSB7CiAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IGFkZGVkYXJndHlwZXMgPSBMaXN0Lm5pbCgpOwogICAgICAgICAgICAgICAgZm9yIChMaXN0PFZhclN5bWJvbD4gbCA9IGZ2czsgbC5ub25FbXB0eSgpOyBsID0gbC50YWlsKSB7CiAgICAgICAgICAgICAgICAgICAgZmluYWwgTmFtZSBwTmFtZSA9IHByb3h5TmFtZShsLmhlYWQubmFtZSk7CiAgICAgICAgICAgICAgICAgICAgbS5jYXB0dXJlZExvY2FscyA9CiAgICAgICAgICAgICAgICAgICAgICAgIG0uY2FwdHVyZWRMb2NhbHMucHJlcGVuZCgoVmFyU3ltYm9sKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAocHJveGllcy5maW5kRmlyc3QocE5hbWUpKSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKFRyZWVJbmZvLmlzSW5pdGlhbENvbnN0cnVjdG9yKHRyZWUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGFkZGVkID0gYWRkZWQucHJlcGVuZCgKICAgICAgICAgICAgICAgICAgICAgICAgICBpbml0RmllbGQodHJlZS5ib2R5LnBvcywgcE5hbWUpKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYWRkZWRhcmd0eXBlcyA9IGFkZGVkYXJndHlwZXMucHJlcGVuZChsLmhlYWQuZXJhc3VyZSh0eXBlcykpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgVHlwZSBvbGRlcmFzdXJlID0gbS5lcmFzdXJlKHR5cGVzKTsKICAgICAgICAgICAgICAgIG0uZXJhc3VyZV9maWVsZCA9IG5ldyBNZXRob2RUeXBlKAogICAgICAgICAgICAgICAgICAgIG9sZGVyYXN1cmUuZ2V0UGFyYW1ldGVyVHlwZXMoKS5hcHBlbmRMaXN0KGFkZGVkYXJndHlwZXMpLAogICAgICAgICAgICAgICAgICAgIG9sZGVyYXN1cmUuZ2V0UmV0dXJuVHlwZSgpLAogICAgICAgICAgICAgICAgICAgIG9sZGVyYXN1cmUuZ2V0VGhyb3duVHlwZXMoKSwKICAgICAgICAgICAgICAgICAgICBzeW1zLm1ldGhvZENsYXNzKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoY3VycmVudENsYXNzLmhhc091dGVySW5zdGFuY2UoKSAmJgogICAgICAgICAgICAgICAgVHJlZUluZm8uaXNJbml0aWFsQ29uc3RydWN0b3IodHJlZSkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGFkZGVkID0gYWRkZWQucHJlcGVuZChpbml0T3V0ZXJUaGlzKHRyZWUuYm9keS5wb3MpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gcG9wIGxvY2FsIHZhcmlhYmxlcyBmcm9tIHByb3h5IHN0YWNrCiAgICAgICAgICAgIHByb3hpZXMgPSBwcm94aWVzLmxlYXZlKCk7CgogICAgICAgICAgICAvLyByZWN1cnNpdmVseSB0cmFuc2xhdGUgZm9sbG93aW5nIGxvY2FsIHN0YXRlbWVudHMgYW5kCiAgICAgICAgICAgIC8vIGNvbWJpbmUgd2l0aCB0aGlzLSBvciBzdXBlci1jYWxsCiAgICAgICAgICAgIExpc3Q8SkNTdGF0ZW1lbnQ+IHN0YXRzID0gdHJhbnNsYXRlKHRyZWUuYm9keS5zdGF0cy50YWlsKTsKICAgICAgICAgICAgdHJlZS5ib2R5LnN0YXRzID0gc3RhdHMucHJlcGVuZChzZWxmQ2FsbCkucHJlcGVuZExpc3QoYWRkZWQpOwogICAgICAgICAgICBvdXRlclRoaXNTdGFjayA9IHByZXZPdXRlclRoaXNTdGFjazsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBNYXA8U3ltYm9sLCBTeW1ib2w+IHByZXZMYW1iZGFUcmFuc2xhdGlvbk1hcCA9CiAgICAgICAgICAgICAgICAgICAgbGFtYmRhVHJhbnNsYXRpb25NYXA7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBsYW1iZGFUcmFuc2xhdGlvbk1hcCA9ICh0cmVlLnN5bS5mbGFncygpICYgU1lOVEhFVElDKSAhPSAwICYmCiAgICAgICAgICAgICAgICAgICAgICAgIHRyZWUuc3ltLm5hbWUuc3RhcnRzV2l0aChuYW1lcy5sYW1iZGEpID8KICAgICAgICAgICAgICAgICAgICAgICAgbWFrZVRyYW5zbGF0aW9uTWFwKHRyZWUpIDogbnVsbDsKICAgICAgICAgICAgICAgIHN1cGVyLnZpc2l0TWV0aG9kRGVmKHRyZWUpOwogICAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAgICAgbGFtYmRhVHJhbnNsYXRpb25NYXAgPSBwcmV2TGFtYmRhVHJhbnNsYXRpb25NYXA7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmVzdWx0ID0gdHJlZTsKICAgIH0KICAgIC8vd2hlcmUKICAgICAgICBwcml2YXRlIE1hcDxTeW1ib2wsIFN5bWJvbD4gbWFrZVRyYW5zbGF0aW9uTWFwKEpDTWV0aG9kRGVjbCB0cmVlKSB7CiAgICAgICAgICAgIE1hcDxTeW1ib2wsIFN5bWJvbD4gdHJhbnNsYXRpb25NYXAgPSBuZXcgSGFzaE1hcDw+KCk7CiAgICAgICAgICAgIGZvciAoSkNWYXJpYWJsZURlY2wgdmQgOiB0cmVlLnBhcmFtcykgewogICAgICAgICAgICAgICAgU3ltYm9sIHAgPSB2ZC5zeW07CiAgICAgICAgICAgICAgICBpZiAocCAhPSBwLmJhc2VTeW1ib2woKSkgewogICAgICAgICAgICAgICAgICAgIHRyYW5zbGF0aW9uTWFwLnB1dChwLmJhc2VTeW1ib2woKSwgcCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHRyYW5zbGF0aW9uTWFwOwogICAgICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdFR5cGVDYXN0KEpDVHlwZUNhc3QgdHJlZSkgewogICAgICAgIHRyZWUuY2xhenogPSB0cmFuc2xhdGUodHJlZS5jbGF6eik7CiAgICAgICAgaWYgKHRyZWUudHlwZS5pc1ByaW1pdGl2ZSgpICE9IHRyZWUuZXhwci50eXBlLmlzUHJpbWl0aXZlKCkpCiAgICAgICAgICAgIHRyZWUuZXhwciA9IHRyYW5zbGF0ZSh0cmVlLmV4cHIsIHRyZWUudHlwZSk7CiAgICAgICAgZWxzZQogICAgICAgICAgICB0cmVlLmV4cHIgPSB0cmFuc2xhdGUodHJlZS5leHByKTsKICAgICAgICByZXN1bHQgPSB0cmVlOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0TmV3Q2xhc3MoSkNOZXdDbGFzcyB0cmVlKSB7CiAgICAgICAgQ2xhc3NTeW1ib2wgYyA9IChDbGFzc1N5bWJvbCl0cmVlLmNvbnN0cnVjdG9yLm93bmVyOwoKICAgICAgICAvLyBCb3ggYXJndW1lbnRzLCBpZiBuZWNlc3NhcnkKICAgICAgICBib29sZWFuIGlzRW51bSA9ICh0cmVlLmNvbnN0cnVjdG9yLm93bmVyLmZsYWdzKCkgJiBFTlVNKSAhPSAwOwogICAgICAgIExpc3Q8VHlwZT4gYXJnVHlwZXMgPSB0cmVlLmNvbnN0cnVjdG9yLnR5cGUuZ2V0UGFyYW1ldGVyVHlwZXMoKTsKICAgICAgICBpZiAoaXNFbnVtKSBhcmdUeXBlcyA9IGFyZ1R5cGVzLnByZXBlbmQoc3ltcy5pbnRUeXBlKS5wcmVwZW5kKHN5bXMuc3RyaW5nVHlwZSk7CiAgICAgICAgdHJlZS5hcmdzID0gYm94QXJncyhhcmdUeXBlcywgdHJlZS5hcmdzLCB0cmVlLnZhcmFyZ3NFbGVtZW50KTsKICAgICAgICB0cmVlLnZhcmFyZ3NFbGVtZW50ID0gbnVsbDsKCiAgICAgICAgLy8gSWYgY3JlYXRlZCBjbGFzcyBpcyBsb2NhbCwgYWRkIGZyZWUgdmFyaWFibGVzIGFmdGVyCiAgICAgICAgLy8gZXhwbGljaXQgY29uc3RydWN0b3IgYXJndW1lbnRzLgogICAgICAgIGlmIChjLmlzTG9jYWwoKSkgewogICAgICAgICAgICB0cmVlLmFyZ3MgPSB0cmVlLmFyZ3MuYXBwZW5kTGlzdChsb2FkRnJlZXZhcnModHJlZS5wb3MoKSwgZnJlZXZhcnMoYykpKTsKICAgICAgICB9CgogICAgICAgIC8vIElmIGFuIGFjY2VzcyBjb25zdHJ1Y3RvciBpcyB1c2VkLCBhcHBlbmQgbnVsbCBhcyBhIGxhc3QgYXJndW1lbnQuCiAgICAgICAgU3ltYm9sIGNvbnN0cnVjdG9yID0gYWNjZXNzQ29uc3RydWN0b3IodHJlZS5wb3MoKSwgdHJlZS5jb25zdHJ1Y3Rvcik7CiAgICAgICAgaWYgKGNvbnN0cnVjdG9yICE9IHRyZWUuY29uc3RydWN0b3IpIHsKICAgICAgICAgICAgdHJlZS5hcmdzID0gdHJlZS5hcmdzLmFwcGVuZChtYWtlTnVsbCgpKTsKICAgICAgICAgICAgdHJlZS5jb25zdHJ1Y3RvciA9IGNvbnN0cnVjdG9yOwogICAgICAgIH0KCiAgICAgICAgLy8gSWYgY3JlYXRlZCBjbGFzcyBoYXMgYW4gb3V0ZXIgaW5zdGFuY2UsIGFuZCBuZXcgaXMgcXVhbGlmaWVkLCBwYXNzCiAgICAgICAgLy8gcXVhbGlmaWVyIGFzIGZpcnN0IGFyZ3VtZW50LiBJZiBuZXcgaXMgbm90IHF1YWxpZmllZCwgcGFzcyB0aGUKICAgICAgICAvLyBjb3JyZWN0IG91dGVyIGluc3RhbmNlIGFzIGZpcnN0IGFyZ3VtZW50LgogICAgICAgIGlmIChjLmhhc091dGVySW5zdGFuY2UoKSkgewogICAgICAgICAgICBKQ0V4cHJlc3Npb24gdGhpc0FyZzsKICAgICAgICAgICAgaWYgKHRyZWUuZW5jbCAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICB0aGlzQXJnID0gYXR0ci5tYWtlTnVsbENoZWNrKHRyYW5zbGF0ZSh0cmVlLmVuY2wpKTsKICAgICAgICAgICAgICAgIHRoaXNBcmcudHlwZSA9IHRyZWUuZW5jbC50eXBlOwogICAgICAgICAgICB9IGVsc2UgaWYgKGMuaXNMb2NhbCgpKSB7CiAgICAgICAgICAgICAgICAvLyBsb2NhbCBjbGFzcwogICAgICAgICAgICAgICAgdGhpc0FyZyA9IG1ha2VUaGlzKHRyZWUucG9zKCksIGMudHlwZS5nZXRFbmNsb3NpbmdUeXBlKCkudHN5bSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvLyBuZXN0ZWQgY2xhc3MKICAgICAgICAgICAgICAgIHRoaXNBcmcgPSBtYWtlT3duZXJUaGlzKHRyZWUucG9zKCksIGMsIGZhbHNlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICB0cmVlLmFyZ3MgPSB0cmVlLmFyZ3MucHJlcGVuZCh0aGlzQXJnKTsKICAgICAgICB9CiAgICAgICAgdHJlZS5lbmNsID0gbnVsbDsKCiAgICAgICAgLy8gSWYgd2UgaGF2ZSBhbiBhbm9ueW1vdXMgY2xhc3MsIGNyZWF0ZSBpdHMgZmxhdCB2ZXJzaW9uLCByYXRoZXIKICAgICAgICAvLyB0aGFuIHRoZSBjbGFzcyBvciBpbnRlcmZhY2UgZm9sbG93aW5nIG5ldy4KICAgICAgICBpZiAodHJlZS5kZWYgIT0gbnVsbCkgewogICAgICAgICAgICB0cmFuc2xhdGUodHJlZS5kZWYpOwogICAgICAgICAgICB0cmVlLmNsYXp6ID0gYWNjZXNzKG1ha2VfYXQodHJlZS5jbGF6ei5wb3MoKSkuSWRlbnQodHJlZS5kZWYuc3ltKSk7CiAgICAgICAgICAgIHRyZWUuZGVmID0gbnVsbDsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB0cmVlLmNsYXp6ID0gYWNjZXNzKGMsIHRyZWUuY2xhenosIGVuY2xPcCwgZmFsc2UpOwogICAgICAgIH0KICAgICAgICByZXN1bHQgPSB0cmVlOwogICAgfQoKICAgIC8vIFNpbXBsaWZ5IGNvbmRpdGlvbmFscyB3aXRoIGtub3duIGNvbnN0YW50IGNvbnRyb2xsaW5nIGV4cHJlc3Npb25zLgogICAgLy8gVGhpcyBhbGxvd3MgdXMgdG8gYXZvaWQgZ2VuZXJhdGluZyBzdXBwb3J0aW5nIGRlY2xhcmF0aW9ucyBmb3IKICAgIC8vIHRoZSBkZWFkIGNvZGUsIHdoaWNoIHdpbGwgbm90IGJlIGVsaW1pbmF0ZWQgZHVyaW5nIGNvZGUgZ2VuZXJhdGlvbi4KICAgIC8vIE5vdGUgdGhhdCBGbG93LmlzRmFsc2UgYW5kIEZsb3cuaXNUcnVlIG9ubHkgcmV0dXJuIHRydWUKICAgIC8vIGZvciBjb25zdGFudCBleHByZXNzaW9ucyBpbiB0aGUgc2Vuc2Ugb2YgSkxTIDE1LjI3LCB3aGljaAogICAgLy8gYXJlIGd1YXJhbnRlZWQgdG8gaGF2ZSBubyBzaWRlLWVmZmVjdHMuICBNb3JlIGFnZ3Jlc3NpdmUKICAgIC8vIGNvbnN0YW50IHByb3BhZ2F0aW9uIHdvdWxkIHJlcXVpcmUgdGhhdCB3ZSB0YWtlIGNhcmUgdG8KICAgIC8vIHByZXNlcnZlIHBvc3NpYmxlIHNpZGUtZWZmZWN0cyBpbiB0aGUgY29uZGl0aW9uIGV4cHJlc3Npb24uCgogICAgLy8gT25lIGNvbW1vbiBjYXNlIGlzIGVxdWFsaXR5IGV4cHJlc3Npb25zIGludm9sdmluZyBhIGNvbnN0YW50IGFuZCBudWxsLgogICAgLy8gU2luY2UgbnVsbCBpcyBub3QgYSBjb25zdGFudCBleHByZXNzaW9uIChiZWNhdXNlIG51bGwgY2Fubm90IGJlCiAgICAvLyByZXByZXNlbnRlZCBpbiB0aGUgY29uc3RhbnQgcG9vbCksIGVxdWFsaXR5IGNoZWNrcyBpbnZvbHZpbmcgbnVsbCBhcmUKICAgIC8vIG5vdCBjYXB0dXJlZCBieSBGbG93LmlzVHJ1ZS9pc0ZhbHNlLgogICAgLy8gRXF1YWxpdHkgY2hlY2tzIGludm9sdmluZyBhIGNvbnN0YW50IGFuZCBudWxsLCBlLmcuCiAgICAvLyAgICAgIiIgPT0gbnVsbAogICAgLy8gYXJlIHNhZmUgdG8gc2ltcGxpZnkgYXMgbm8gc2lkZS1lZmZlY3RzIGNhbiBvY2N1ci4KCiAgICBwcml2YXRlIGJvb2xlYW4gaXNUcnVlKEpDVHJlZSBleHApIHsKICAgICAgICBpZiAoZXhwLnR5cGUuaXNUcnVlKCkpCiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIEJvb2xlYW4gYiA9IGV4cFZhbHVlKGV4cCk7CiAgICAgICAgcmV0dXJuIGIgPT0gbnVsbCA/IGZhbHNlIDogYjsKICAgIH0KICAgIHByaXZhdGUgYm9vbGVhbiBpc0ZhbHNlKEpDVHJlZSBleHApIHsKICAgICAgICBpZiAoZXhwLnR5cGUuaXNGYWxzZSgpKQogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICBCb29sZWFuIGIgPSBleHBWYWx1ZShleHApOwogICAgICAgIHJldHVybiBiID09IG51bGwgPyBmYWxzZSA6ICFiOwogICAgfQogICAgLyogbG9vayBmb3IgKGluKWVxdWFsaXR5IHJlbGF0aW9ucyBpbnZvbHZpbmcgbnVsbC4KICAgICAqIHJldHVybiB0cnVlIC0gaWYgZXhwcmVzc2lvbiBpcyBhbHdheXMgdHJ1ZQogICAgICogICAgICAgZmFsc2UgLSBpZiBleHByZXNzaW9uIGlzIGFsd2F5cyBmYWxzZQogICAgICogICAgICAgIG51bGwgLSBpZiBleHByZXNzaW9uIGNhbm5vdCBiZSBlbGltaW5hdGVkCiAgICAgKi8KICAgIHByaXZhdGUgQm9vbGVhbiBleHBWYWx1ZShKQ1RyZWUgZXhwKSB7CiAgICAgICAgd2hpbGUgKGV4cC5oYXNUYWcoUEFSRU5TKSkKICAgICAgICAgICAgZXhwID0gKChKQ1BhcmVucylleHApLmV4cHI7CgogICAgICAgIGJvb2xlYW4gZXE7CiAgICAgICAgc3dpdGNoIChleHAuZ2V0VGFnKCkpIHsKICAgICAgICBjYXNlIEVROiBlcSA9IHRydWU7ICBicmVhazsKICAgICAgICBjYXNlIE5FOiBlcSA9IGZhbHNlOyBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgIC8vIHdlIGhhdmUgYSBKQ0JpbmFyeShFUXxORSkKICAgICAgICAvLyBjaGVjayBpZiB3ZSBoYXZlIHR3byBsaXRlcmFscyAoY29uc3RhbnRzIG9yIG51bGwpCiAgICAgICAgSkNCaW5hcnkgYiA9IChKQ0JpbmFyeSlleHA7CiAgICAgICAgaWYgKGIubGhzLnR5cGUuaGFzVGFnKEJPVCkpIHJldHVybiBleHBWYWx1ZUlzTnVsbChlcSwgYi5yaHMpOwogICAgICAgIGlmIChiLnJocy50eXBlLmhhc1RhZyhCT1QpKSByZXR1cm4gZXhwVmFsdWVJc051bGwoZXEsIGIubGhzKTsKICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIHByaXZhdGUgQm9vbGVhbiBleHBWYWx1ZUlzTnVsbChib29sZWFuIGVxLCBKQ1RyZWUgdCkgewogICAgICAgIGlmICh0LnR5cGUuaGFzVGFnKEJPVCkpIHJldHVybiBCb29sZWFuLnZhbHVlT2YoZXEpOwogICAgICAgIGlmICh0Lmhhc1RhZyhMSVRFUkFMKSkgIHJldHVybiBCb29sZWFuLnZhbHVlT2YoIWVxKTsKICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICAvKiogVmlzaXRvciBtZXRob2QgZm9yIGNvbmRpdGlvbmFsIGV4cHJlc3Npb25zLgogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHZpc2l0Q29uZGl0aW9uYWwoSkNDb25kaXRpb25hbCB0cmVlKSB7CiAgICAgICAgSkNUcmVlIGNvbmQgPSB0cmVlLmNvbmQgPSB0cmFuc2xhdGUodHJlZS5jb25kLCBzeW1zLmJvb2xlYW5UeXBlKTsKICAgICAgICBpZiAoaXNUcnVlKGNvbmQpKSB7CiAgICAgICAgICAgIHJlc3VsdCA9IGNvbnZlcnQodHJhbnNsYXRlKHRyZWUudHJ1ZXBhcnQsIHRyZWUudHlwZSksIHRyZWUudHlwZSk7CiAgICAgICAgICAgIGFkZFBydW5lZEluZm8oY29uZCk7CiAgICAgICAgfSBlbHNlIGlmIChpc0ZhbHNlKGNvbmQpKSB7CiAgICAgICAgICAgIHJlc3VsdCA9IGNvbnZlcnQodHJhbnNsYXRlKHRyZWUuZmFsc2VwYXJ0LCB0cmVlLnR5cGUpLCB0cmVlLnR5cGUpOwogICAgICAgICAgICBhZGRQcnVuZWRJbmZvKGNvbmQpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8vIENvbmRpdGlvbiBpcyBub3QgYSBjb21waWxlLXRpbWUgY29uc3RhbnQuCiAgICAgICAgICAgIHRyZWUudHJ1ZXBhcnQgPSB0cmFuc2xhdGUodHJlZS50cnVlcGFydCwgdHJlZS50eXBlKTsKICAgICAgICAgICAgdHJlZS5mYWxzZXBhcnQgPSB0cmFuc2xhdGUodHJlZS5mYWxzZXBhcnQsIHRyZWUudHlwZSk7CiAgICAgICAgICAgIHJlc3VsdCA9IHRyZWU7CiAgICAgICAgfQogICAgfQovL3doZXJlCiAgICBwcml2YXRlIEpDRXhwcmVzc2lvbiBjb252ZXJ0KEpDRXhwcmVzc2lvbiB0cmVlLCBUeXBlIHB0KSB7CiAgICAgICAgaWYgKHRyZWUudHlwZSA9PSBwdCB8fCB0cmVlLnR5cGUuaGFzVGFnKEJPVCkpCiAgICAgICAgICAgIHJldHVybiB0cmVlOwogICAgICAgIEpDRXhwcmVzc2lvbiByZXN1bHQgPSBtYWtlX2F0KHRyZWUucG9zKCkpLlR5cGVDYXN0KG1ha2UuVHlwZShwdCksIHRyZWUpOwogICAgICAgIHJlc3VsdC50eXBlID0gKHRyZWUudHlwZS5jb25zdFZhbHVlKCkgIT0gbnVsbCkgPyBjZm9sZGVyLmNvZXJjZSh0cmVlLnR5cGUsIHB0KQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBwdDsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgfQoKICAgIC8qKiBWaXNpdG9yIG1ldGhvZCBmb3IgaWYgc3RhdGVtZW50cy4KICAgICAqLwogICAgcHVibGljIHZvaWQgdmlzaXRJZihKQ0lmIHRyZWUpIHsKICAgICAgICBKQ1RyZWUgY29uZCA9IHRyZWUuY29uZCA9IHRyYW5zbGF0ZSh0cmVlLmNvbmQsIHN5bXMuYm9vbGVhblR5cGUpOwogICAgICAgIGlmIChpc1RydWUoY29uZCkpIHsKICAgICAgICAgICAgcmVzdWx0ID0gdHJhbnNsYXRlKHRyZWUudGhlbnBhcnQpOwogICAgICAgICAgICBhZGRQcnVuZWRJbmZvKGNvbmQpOwogICAgICAgIH0gZWxzZSBpZiAoaXNGYWxzZShjb25kKSkgewogICAgICAgICAgICBpZiAodHJlZS5lbHNlcGFydCAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICByZXN1bHQgPSB0cmFuc2xhdGUodHJlZS5lbHNlcGFydCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICByZXN1bHQgPSBtYWtlLlNraXAoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBhZGRQcnVuZWRJbmZvKGNvbmQpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8vIENvbmRpdGlvbiBpcyBub3QgYSBjb21waWxlLXRpbWUgY29uc3RhbnQuCiAgICAgICAgICAgIHRyZWUudGhlbnBhcnQgPSB0cmFuc2xhdGUodHJlZS50aGVucGFydCk7CiAgICAgICAgICAgIHRyZWUuZWxzZXBhcnQgPSB0cmFuc2xhdGUodHJlZS5lbHNlcGFydCk7CiAgICAgICAgICAgIHJlc3VsdCA9IHRyZWU7CiAgICAgICAgfQogICAgfQoKICAgIC8qKiBWaXNpdG9yIG1ldGhvZCBmb3IgYXNzZXJ0IHN0YXRlbWVudHMuIFRyYW5zbGF0ZSB0aGVtIGF3YXkuCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHZpc2l0QXNzZXJ0KEpDQXNzZXJ0IHRyZWUpIHsKICAgICAgICBEaWFnbm9zdGljUG9zaXRpb24gZGV0YWlsUG9zID0gKHRyZWUuZGV0YWlsID09IG51bGwpID8gdHJlZS5wb3MoKSA6IHRyZWUuZGV0YWlsLnBvcygpOwogICAgICAgIHRyZWUuY29uZCA9IHRyYW5zbGF0ZSh0cmVlLmNvbmQsIHN5bXMuYm9vbGVhblR5cGUpOwogICAgICAgIGlmICghdHJlZS5jb25kLnR5cGUuaXNUcnVlKCkpIHsKICAgICAgICAgICAgSkNFeHByZXNzaW9uIGNvbmQgPSBhc3NlcnRGbGFnVGVzdCh0cmVlLnBvcygpKTsKICAgICAgICAgICAgTGlzdDxKQ0V4cHJlc3Npb24+IGV4bkFyZ3MgPSAodHJlZS5kZXRhaWwgPT0gbnVsbCkgPwogICAgICAgICAgICAgICAgTGlzdC5uaWwoKSA6IExpc3Qub2YodHJhbnNsYXRlKHRyZWUuZGV0YWlsKSk7CiAgICAgICAgICAgIGlmICghdHJlZS5jb25kLnR5cGUuaXNGYWxzZSgpKSB7CiAgICAgICAgICAgICAgICBjb25kID0gbWFrZUJpbmFyeQogICAgICAgICAgICAgICAgICAgIChBTkQsCiAgICAgICAgICAgICAgICAgICAgIGNvbmQsCiAgICAgICAgICAgICAgICAgICAgIG1ha2VVbmFyeShOT1QsIHRyZWUuY29uZCkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJlc3VsdCA9CiAgICAgICAgICAgICAgICBtYWtlLklmKGNvbmQsCiAgICAgICAgICAgICAgICAgICAgICAgIG1ha2VfYXQodHJlZSkuCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFRocm93KG1ha2VOZXdDbGFzcyhzeW1zLmFzc2VydGlvbkVycm9yVHlwZSwgZXhuQXJncykpLAogICAgICAgICAgICAgICAgICAgICAgICBudWxsKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXN1bHQgPSBtYWtlLlNraXAoKTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRBcHBseShKQ01ldGhvZEludm9jYXRpb24gdHJlZSkgewogICAgICAgIFN5bWJvbCBtZXRoID0gVHJlZUluZm8uc3ltYm9sKHRyZWUubWV0aCk7CiAgICAgICAgTGlzdDxUeXBlPiBhcmd0eXBlcyA9IG1ldGgudHlwZS5nZXRQYXJhbWV0ZXJUeXBlcygpOwogICAgICAgIGlmIChtZXRoLm5hbWUgPT0gbmFtZXMuaW5pdCAmJiBtZXRoLm93bmVyID09IHN5bXMuZW51bVN5bSkKICAgICAgICAgICAgYXJndHlwZXMgPSBhcmd0eXBlcy50YWlsLnRhaWw7CiAgICAgICAgdHJlZS5hcmdzID0gYm94QXJncyhhcmd0eXBlcywgdHJlZS5hcmdzLCB0cmVlLnZhcmFyZ3NFbGVtZW50KTsKICAgICAgICB0cmVlLnZhcmFyZ3NFbGVtZW50ID0gbnVsbDsKICAgICAgICBOYW1lIG1ldGhOYW1lID0gVHJlZUluZm8ubmFtZSh0cmVlLm1ldGgpOwogICAgICAgIGlmIChtZXRoLm5hbWU9PW5hbWVzLmluaXQpIHsKICAgICAgICAgICAgLy8gV2UgYXJlIHNlZWluZyBhIHRoaXMoLi4uKSBvciBzdXBlciguLi4pIGNvbnN0cnVjdG9yIGNhbGwuCiAgICAgICAgICAgIC8vIElmIGFuIGFjY2VzcyBjb25zdHJ1Y3RvciBpcyB1c2VkLCBhcHBlbmQgbnVsbCBhcyBhIGxhc3QgYXJndW1lbnQuCiAgICAgICAgICAgIFN5bWJvbCBjb25zdHJ1Y3RvciA9IGFjY2Vzc0NvbnN0cnVjdG9yKHRyZWUucG9zKCksIG1ldGgpOwogICAgICAgICAgICBpZiAoY29uc3RydWN0b3IgIT0gbWV0aCkgewogICAgICAgICAgICAgICAgdHJlZS5hcmdzID0gdHJlZS5hcmdzLmFwcGVuZChtYWtlTnVsbCgpKTsKICAgICAgICAgICAgICAgIFRyZWVJbmZvLnNldFN5bWJvbCh0cmVlLm1ldGgsIGNvbnN0cnVjdG9yKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gSWYgd2UgYXJlIGNhbGxpbmcgYSBjb25zdHJ1Y3RvciBvZiBhIGxvY2FsIGNsYXNzLCBhZGQKICAgICAgICAgICAgLy8gZnJlZSB2YXJpYWJsZXMgYWZ0ZXIgZXhwbGljaXQgY29uc3RydWN0b3IgYXJndW1lbnRzLgogICAgICAgICAgICBDbGFzc1N5bWJvbCBjID0gKENsYXNzU3ltYm9sKWNvbnN0cnVjdG9yLm93bmVyOwogICAgICAgICAgICBpZiAoYy5pc0xvY2FsKCkpIHsKICAgICAgICAgICAgICAgIHRyZWUuYXJncyA9IHRyZWUuYXJncy5hcHBlbmRMaXN0KGxvYWRGcmVldmFycyh0cmVlLnBvcygpLCBmcmVldmFycyhjKSkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBJZiB3ZSBhcmUgY2FsbGluZyBhIGNvbnN0cnVjdG9yIG9mIGFuIGVudW0gY2xhc3MsIHBhc3MKICAgICAgICAgICAgLy8gYWxvbmcgdGhlIG5hbWUgYW5kIG9yZGluYWwgYXJndW1lbnRzCiAgICAgICAgICAgIGlmICgoYy5mbGFnc19maWVsZCZFTlVNKSAhPSAwIHx8IGMuZ2V0UXVhbGlmaWVkTmFtZSgpID09IG5hbWVzLmphdmFfbGFuZ19FbnVtKSB7CiAgICAgICAgICAgICAgICBMaXN0PEpDVmFyaWFibGVEZWNsPiBwYXJhbXMgPSBjdXJyZW50TWV0aG9kRGVmLnBhcmFtczsKICAgICAgICAgICAgICAgIGlmIChjdXJyZW50TWV0aG9kU3ltLm93bmVyLmhhc091dGVySW5zdGFuY2UoKSkKICAgICAgICAgICAgICAgICAgICBwYXJhbXMgPSBwYXJhbXMudGFpbDsgLy8gZHJvcCB0aGlzJG4KICAgICAgICAgICAgICAgIHRyZWUuYXJncyA9IHRyZWUuYXJncwogICAgICAgICAgICAgICAgICAgIC5wcmVwZW5kKG1ha2VfYXQodHJlZS5wb3MoKSkuSWRlbnQocGFyYW1zLnRhaWwuaGVhZC5zeW0pKSAvLyBvcmRpbmFsCiAgICAgICAgICAgICAgICAgICAgLnByZXBlbmQobWFrZS5JZGVudChwYXJhbXMuaGVhZC5zeW0pKTsgLy8gbmFtZQogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBJZiB3ZSBhcmUgY2FsbGluZyBhIGNvbnN0cnVjdG9yIG9mIGEgY2xhc3Mgd2l0aCBhbiBvdXRlcgogICAgICAgICAgICAvLyBpbnN0YW5jZSwgYW5kIHRoZSBjYWxsCiAgICAgICAgICAgIC8vIGlzIHF1YWxpZmllZCwgcGFzcyBxdWFsaWZpZXIgYXMgZmlyc3QgYXJndW1lbnQgaW4gZnJvbnQgb2YKICAgICAgICAgICAgLy8gdGhlIGV4cGxpY2l0IGNvbnN0cnVjdG9yIGFyZ3VtZW50cy4gSWYgdGhlIGNhbGwKICAgICAgICAgICAgLy8gaXMgbm90IHF1YWxpZmllZCwgcGFzcyB0aGUgY29ycmVjdCBvdXRlciBpbnN0YW5jZSBhcwogICAgICAgICAgICAvLyBmaXJzdCBhcmd1bWVudC4KICAgICAgICAgICAgaWYgKGMuaGFzT3V0ZXJJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgICAgICBKQ0V4cHJlc3Npb24gdGhpc0FyZzsKICAgICAgICAgICAgICAgIGlmICh0cmVlLm1ldGguaGFzVGFnKFNFTEVDVCkpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzQXJnID0gYXR0ci4KICAgICAgICAgICAgICAgICAgICAgICAgbWFrZU51bGxDaGVjayh0cmFuc2xhdGUoKChKQ0ZpZWxkQWNjZXNzKSB0cmVlLm1ldGgpLnNlbGVjdGVkKSk7CiAgICAgICAgICAgICAgICAgICAgdHJlZS5tZXRoID0gbWFrZS5JZGVudChjb25zdHJ1Y3Rvcik7CiAgICAgICAgICAgICAgICAgICAgKChKQ0lkZW50KSB0cmVlLm1ldGgpLm5hbWUgPSBtZXRoTmFtZTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoYy5pc0xvY2FsKCkgfHwgbWV0aE5hbWUgPT0gbmFtZXMuX3RoaXMpewogICAgICAgICAgICAgICAgICAgIC8vIGxvY2FsIGNsYXNzIG9yIHRoaXMoKSBjYWxsCiAgICAgICAgICAgICAgICAgICAgdGhpc0FyZyA9IG1ha2VUaGlzKHRyZWUubWV0aC5wb3MoKSwgYy50eXBlLmdldEVuY2xvc2luZ1R5cGUoKS50c3ltKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgLy8gc3VwZXIoKSBjYWxsIG9mIG5lc3RlZCBjbGFzcyAtIG5ldmVyIHBpY2sgJ3RoaXMnCiAgICAgICAgICAgICAgICAgICAgdGhpc0FyZyA9IG1ha2VPd25lclRoaXNOKHRyZWUubWV0aC5wb3MoKSwgYywgZmFsc2UpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdHJlZS5hcmdzID0gdHJlZS5hcmdzLnByZXBlbmQodGhpc0FyZyk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvLyBXZSBhcmUgc2VlaW5nIGEgbm9ybWFsIG1ldGhvZCBpbnZvY2F0aW9uOyB0cmFuc2xhdGUgdGhpcyBhcyB1c3VhbC4KICAgICAgICAgICAgdHJlZS5tZXRoID0gdHJhbnNsYXRlKHRyZWUubWV0aCk7CgogICAgICAgICAgICAvLyBJZiB0aGUgdHJhbnNsYXRlZCBtZXRob2QgaXRzZWxmIGlzIGFuIEFwcGx5IHRyZWUsIHdlIGFyZQogICAgICAgICAgICAvLyBzZWVpbmcgYW4gYWNjZXNzIG1ldGhvZCBpbnZvY2F0aW9uLiBJbiB0aGlzIGNhc2UsIGFwcGVuZAogICAgICAgICAgICAvLyB0aGUgbWV0aG9kIGFyZ3VtZW50cyB0byB0aGUgYXJndW1lbnRzIG9mIHRoZSBhY2Nlc3MgbWV0aG9kLgogICAgICAgICAgICBpZiAodHJlZS5tZXRoLmhhc1RhZyhBUFBMWSkpIHsKICAgICAgICAgICAgICAgIEpDTWV0aG9kSW52b2NhdGlvbiBhcHAgPSAoSkNNZXRob2RJbnZvY2F0aW9uKXRyZWUubWV0aDsKICAgICAgICAgICAgICAgIGFwcC5hcmdzID0gdHJlZS5hcmdzLnByZXBlbmRMaXN0KGFwcC5hcmdzKTsKICAgICAgICAgICAgICAgIHJlc3VsdCA9IGFwcDsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXN1bHQgPSB0cmVlOwogICAgfQoKICAgIExpc3Q8SkNFeHByZXNzaW9uPiBib3hBcmdzKExpc3Q8VHlwZT4gcGFyYW1ldGVycywgTGlzdDxKQ0V4cHJlc3Npb24+IF9hcmdzLCBUeXBlIHZhcmFyZ3NFbGVtZW50KSB7CiAgICAgICAgTGlzdDxKQ0V4cHJlc3Npb24+IGFyZ3MgPSBfYXJnczsKICAgICAgICBpZiAocGFyYW1ldGVycy5pc0VtcHR5KCkpIHJldHVybiBhcmdzOwogICAgICAgIGJvb2xlYW4gYW55Q2hhbmdlcyA9IGZhbHNlOwogICAgICAgIExpc3RCdWZmZXI8SkNFeHByZXNzaW9uPiByZXN1bHQgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgd2hpbGUgKHBhcmFtZXRlcnMudGFpbC5ub25FbXB0eSgpKSB7CiAgICAgICAgICAgIEpDRXhwcmVzc2lvbiBhcmcgPSB0cmFuc2xhdGUoYXJncy5oZWFkLCBwYXJhbWV0ZXJzLmhlYWQpOwogICAgICAgICAgICBhbnlDaGFuZ2VzIHw9IChhcmcgIT0gYXJncy5oZWFkKTsKICAgICAgICAgICAgcmVzdWx0LmFwcGVuZChhcmcpOwogICAgICAgICAgICBhcmdzID0gYXJncy50YWlsOwogICAgICAgICAgICBwYXJhbWV0ZXJzID0gcGFyYW1ldGVycy50YWlsOwogICAgICAgIH0KICAgICAgICBUeXBlIHBhcmFtZXRlciA9IHBhcmFtZXRlcnMuaGVhZDsKICAgICAgICBpZiAodmFyYXJnc0VsZW1lbnQgIT0gbnVsbCkgewogICAgICAgICAgICBhbnlDaGFuZ2VzID0gdHJ1ZTsKICAgICAgICAgICAgTGlzdEJ1ZmZlcjxKQ0V4cHJlc3Npb24+IGVsZW1zID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgICAgICB3aGlsZSAoYXJncy5ub25FbXB0eSgpKSB7CiAgICAgICAgICAgICAgICBKQ0V4cHJlc3Npb24gYXJnID0gdHJhbnNsYXRlKGFyZ3MuaGVhZCwgdmFyYXJnc0VsZW1lbnQpOwogICAgICAgICAgICAgICAgZWxlbXMuYXBwZW5kKGFyZyk7CiAgICAgICAgICAgICAgICBhcmdzID0gYXJncy50YWlsOwogICAgICAgICAgICB9CiAgICAgICAgICAgIEpDTmV3QXJyYXkgYm94ZWRBcmdzID0gbWFrZS5OZXdBcnJheShtYWtlLlR5cGUodmFyYXJnc0VsZW1lbnQpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExpc3QubmlsKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbXMudG9MaXN0KCkpOwogICAgICAgICAgICBib3hlZEFyZ3MudHlwZSA9IG5ldyBBcnJheVR5cGUodmFyYXJnc0VsZW1lbnQsIHN5bXMuYXJyYXlDbGFzcyk7CiAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoYm94ZWRBcmdzKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBpZiAoYXJncy5sZW5ndGgoKSAhPSAxKSB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoYXJncyk7CiAgICAgICAgICAgIEpDRXhwcmVzc2lvbiBhcmcgPSB0cmFuc2xhdGUoYXJncy5oZWFkLCBwYXJhbWV0ZXIpOwogICAgICAgICAgICBhbnlDaGFuZ2VzIHw9IChhcmcgIT0gYXJncy5oZWFkKTsKICAgICAgICAgICAgcmVzdWx0LmFwcGVuZChhcmcpOwogICAgICAgICAgICBpZiAoIWFueUNoYW5nZXMpIHJldHVybiBfYXJnczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdC50b0xpc3QoKTsKICAgIH0KCiAgICAvKiogRXhwYW5kIGEgYm94aW5nIG9yIHVuYm94aW5nIGNvbnZlcnNpb24gaWYgbmVlZGVkLiAqLwogICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpIC8vIFhYWCB1bmNoZWNrZWQKICAgIDxUIGV4dGVuZHMgSkNFeHByZXNzaW9uPiBUIGJveElmTmVlZGVkKFQgdHJlZSwgVHlwZSB0eXBlKSB7CiAgICAgICAgYm9vbGVhbiBoYXZlUHJpbWl0aXZlID0gdHJlZS50eXBlLmlzUHJpbWl0aXZlKCk7CiAgICAgICAgaWYgKGhhdmVQcmltaXRpdmUgPT0gdHlwZS5pc1ByaW1pdGl2ZSgpKQogICAgICAgICAgICByZXR1cm4gdHJlZTsKICAgICAgICBpZiAoaGF2ZVByaW1pdGl2ZSkgewogICAgICAgICAgICBUeXBlIHVuYm94ZWRUYXJnZXQgPSB0eXBlcy51bmJveGVkVHlwZSh0eXBlKTsKICAgICAgICAgICAgaWYgKCF1bmJveGVkVGFyZ2V0Lmhhc1RhZyhOT05FKSkgewogICAgICAgICAgICAgICAgaWYgKCF0eXBlcy5pc1N1YnR5cGUodHJlZS50eXBlLCB1bmJveGVkVGFyZ2V0KSkgLy9lLmcuIENoYXJhY3RlciBjID0gODk7CiAgICAgICAgICAgICAgICAgICAgdHJlZS50eXBlID0gdW5ib3hlZFRhcmdldC5jb25zdFR5cGUodHJlZS50eXBlLmNvbnN0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICByZXR1cm4gKFQpYm94UHJpbWl0aXZlKHRyZWUsIHR5cGVzLmVyYXN1cmUodHlwZSkpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdHJlZSA9IChUKWJveFByaW1pdGl2ZSh0cmVlKTsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHRyZWUgPSAoVCl1bmJveCh0cmVlLCB0eXBlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRyZWU7CiAgICB9CgogICAgLyoqIEJveCB1cCBhIHNpbmdsZSBwcmltaXRpdmUgZXhwcmVzc2lvbi4gKi8KICAgIEpDRXhwcmVzc2lvbiBib3hQcmltaXRpdmUoSkNFeHByZXNzaW9uIHRyZWUpIHsKICAgICAgICByZXR1cm4gYm94UHJpbWl0aXZlKHRyZWUsIHR5cGVzLmJveGVkQ2xhc3ModHJlZS50eXBlKS50eXBlKTsKICAgIH0KCiAgICAvKiogQm94IHVwIGEgc2luZ2xlIHByaW1pdGl2ZSBleHByZXNzaW9uLiAqLwogICAgSkNFeHByZXNzaW9uIGJveFByaW1pdGl2ZShKQ0V4cHJlc3Npb24gdHJlZSwgVHlwZSBib3gpIHsKICAgICAgICBtYWtlX2F0KHRyZWUucG9zKCkpOwogICAgICAgIFN5bWJvbCB2YWx1ZU9mU3ltID0gbG9va3VwTWV0aG9kKHRyZWUucG9zKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZXMudmFsdWVPZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib3gsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTGlzdC48VHlwZT5uaWwoKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5wcmVwZW5kKHRyZWUudHlwZSkpOwogICAgICAgIHJldHVybiBtYWtlLkFwcChtYWtlLlF1YWxJZGVudCh2YWx1ZU9mU3ltKSwgTGlzdC5vZih0cmVlKSk7CiAgICB9CgogICAgLyoqIFVuYm94IGFuIG9iamVjdCB0byBhIHByaW1pdGl2ZSB2YWx1ZS4gKi8KICAgIEpDRXhwcmVzc2lvbiB1bmJveChKQ0V4cHJlc3Npb24gdHJlZSwgVHlwZSBwcmltaXRpdmUpIHsKICAgICAgICBUeXBlIHVuYm94ZWRUeXBlID0gdHlwZXMudW5ib3hlZFR5cGUodHJlZS50eXBlKTsKICAgICAgICBpZiAodW5ib3hlZFR5cGUuaGFzVGFnKE5PTkUpKSB7CiAgICAgICAgICAgIHVuYm94ZWRUeXBlID0gcHJpbWl0aXZlOwogICAgICAgICAgICBpZiAoIXVuYm94ZWRUeXBlLmlzUHJpbWl0aXZlKCkpCiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IodW5ib3hlZFR5cGUpOwogICAgICAgICAgICBtYWtlX2F0KHRyZWUucG9zKCkpOwogICAgICAgICAgICB0cmVlID0gbWFrZS5UeXBlQ2FzdCh0eXBlcy5ib3hlZENsYXNzKHVuYm94ZWRUeXBlKS50eXBlLCB0cmVlKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvLyBUaGVyZSBtdXN0IGJlIGEgY29udmVyc2lvbiBmcm9tIHVuYm94ZWRUeXBlIHRvIHByaW1pdGl2ZS4KICAgICAgICAgICAgaWYgKCF0eXBlcy5pc1N1YnR5cGUodW5ib3hlZFR5cGUsIHByaW1pdGl2ZSkpCiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IodHJlZSk7CiAgICAgICAgfQogICAgICAgIG1ha2VfYXQodHJlZS5wb3MoKSk7CiAgICAgICAgU3ltYm9sIHZhbHVlU3ltID0gbG9va3VwTWV0aG9kKHRyZWUucG9zKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuYm94ZWRUeXBlLnRzeW0ubmFtZS5hcHBlbmQobmFtZXMuVmFsdWUpLCAvLyB4LmludFZhbHVlKCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJlZS50eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0Lm5pbCgpKTsKICAgICAgICByZXR1cm4gbWFrZS5BcHAobWFrZS5TZWxlY3QodHJlZSwgdmFsdWVTeW0pKTsKICAgIH0KCiAgICAvKiogVmlzaXRvciBtZXRob2QgZm9yIHBhcmVudGhlc2l6ZWQgZXhwcmVzc2lvbnMuCiAgICAgKiAgSWYgdGhlIHN1YmV4cHJlc3Npb24gaGFzIGNoYW5nZWQsIG9taXQgdGhlIHBhcmVucy4KICAgICAqLwogICAgcHVibGljIHZvaWQgdmlzaXRQYXJlbnMoSkNQYXJlbnMgdHJlZSkgewogICAgICAgIEpDVHJlZSBleHByID0gdHJhbnNsYXRlKHRyZWUuZXhwcik7CiAgICAgICAgcmVzdWx0ID0gKChleHByID09IHRyZWUuZXhwcikgPyB0cmVlIDogZXhwcik7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRJbmRleGVkKEpDQXJyYXlBY2Nlc3MgdHJlZSkgewogICAgICAgIHRyZWUuaW5kZXhlZCA9IHRyYW5zbGF0ZSh0cmVlLmluZGV4ZWQpOwogICAgICAgIHRyZWUuaW5kZXggPSB0cmFuc2xhdGUodHJlZS5pbmRleCwgc3ltcy5pbnRUeXBlKTsKICAgICAgICByZXN1bHQgPSB0cmVlOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0QXNzaWduKEpDQXNzaWduIHRyZWUpIHsKICAgICAgICB0cmVlLmxocyA9IHRyYW5zbGF0ZSh0cmVlLmxocywgdHJlZSk7CiAgICAgICAgdHJlZS5yaHMgPSB0cmFuc2xhdGUodHJlZS5yaHMsIHRyZWUubGhzLnR5cGUpOwoKICAgICAgICAvLyBJZiB0cmFuc2xhdGVkIGxlZnQgaGFuZCBzaWRlIGlzIGFuIEFwcGx5LCB3ZSBhcmUKICAgICAgICAvLyBzZWVpbmcgYW4gYWNjZXNzIG1ldGhvZCBpbnZvY2F0aW9uLiBJbiB0aGlzIGNhc2UsIGFwcGVuZAogICAgICAgIC8vIHJpZ2h0IGhhbmQgc2lkZSBhcyBsYXN0IGFyZ3VtZW50IG9mIHRoZSBhY2Nlc3MgbWV0aG9kLgogICAgICAgIGlmICh0cmVlLmxocy5oYXNUYWcoQVBQTFkpKSB7CiAgICAgICAgICAgIEpDTWV0aG9kSW52b2NhdGlvbiBhcHAgPSAoSkNNZXRob2RJbnZvY2F0aW9uKXRyZWUubGhzOwogICAgICAgICAgICBhcHAuYXJncyA9IExpc3Qub2YodHJlZS5yaHMpLnByZXBlbmRMaXN0KGFwcC5hcmdzKTsKICAgICAgICAgICAgcmVzdWx0ID0gYXBwOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJlc3VsdCA9IHRyZWU7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0QXNzaWdub3AoZmluYWwgSkNBc3NpZ25PcCB0cmVlKSB7CiAgICAgICAgZmluYWwgYm9vbGVhbiBib3hpbmdSZXEgPSAhdHJlZS5saHMudHlwZS5pc1ByaW1pdGl2ZSgpICYmCiAgICAgICAgICAgIHRyZWUub3BlcmF0b3IudHlwZS5nZXRSZXR1cm5UeXBlKCkuaXNQcmltaXRpdmUoKTsKCiAgICAgICAgQXNzaWdub3BEZXBlbmRlbmN5U2Nhbm5lciBkZXBTY2FubmVyID0gbmV3IEFzc2lnbm9wRGVwZW5kZW5jeVNjYW5uZXIodHJlZSk7CiAgICAgICAgZGVwU2Nhbm5lci5zY2FuKHRyZWUucmhzKTsKCiAgICAgICAgaWYgKGJveGluZ1JlcSB8fCBkZXBTY2FubmVyLmRlcGVuZGVuY3lGb3VuZCkgewogICAgICAgICAgICAvLyBib3hpbmcgcmVxdWlyZWQ7IG5lZWQgdG8gcmV3cml0ZSBhcyB4ID0gKHVuYm94IHR5cGVvZiB4KSh4IG9wIHkpOwogICAgICAgICAgICAvLyBvciBpZiB4ID09ICh0eXBlb2YgeCl6IHRoZW4geiA9ICh1bmJveCB0eXBlb2YgeCkoKHR5cGVvZiB4KXogb3AgeSkKICAgICAgICAgICAgLy8gKGJ1dCB3aXRob3V0IHJlY29tcHV0aW5nIHgpCiAgICAgICAgICAgIEpDVHJlZSBuZXdUcmVlID0gYWJzdHJhY3RMdmFsKHRyZWUubGhzLCBsaHMgLT4gewogICAgICAgICAgICAgICAgVGFnIG5ld1RhZyA9IHRyZWUuZ2V0VGFnKCkubm9Bc3NpZ25PcCgpOwogICAgICAgICAgICAgICAgLy8gRXJhc3VyZSAoVHJhbnNUeXBlcykgY2FuIGNoYW5nZSB0aGUgdHlwZSBvZgogICAgICAgICAgICAgICAgLy8gdHJlZS5saHMuICBIb3dldmVyLCB3ZSBjYW4gc3RpbGwgZ2V0IHRoZQogICAgICAgICAgICAgICAgLy8gdW5lcmFzZWQgdHlwZSBvZiB0cmVlLmxocyBhcyBpdCBpcyBzdG9yZWQKICAgICAgICAgICAgICAgIC8vIGluIHRyZWUudHlwZSBpbiBBdHRyLgogICAgICAgICAgICAgICAgT3BlcmF0b3JTeW1ib2wgbmV3T3BlcmF0b3IgPSBvcGVyYXRvcnMucmVzb2x2ZUJpbmFyeSh0cmVlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld1RhZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmVlLnR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJlZS5yaHMudHlwZSk7CiAgICAgICAgICAgICAgICAvL05lZWQgdG8gdXNlIHRoZSAibGhzIiBhdCB0d28gcGxhY2VzLCBvbmNlIG9uIHRoZSBmdXR1cmUgbGVmdCBoYW5kIHNpZGUKICAgICAgICAgICAgICAgIC8vYW5kIG9uY2UgaW4gdGhlIGZ1dHVyZSBiaW5hcnkgb3BlcmF0b3IuIEJ1dCBmdXJ0aGVyIHByb2Nlc3NpbmcgbWF5IGNoYW5nZQogICAgICAgICAgICAgICAgLy90aGUgY29tcG9uZW50cyBvZiB0aGUgdHJlZSBpbiBwbGFjZSAoc2VlIHZpc2l0U2VsZWN0IGZvciBlLmcuIDxDbGFzcz4uc3VwZXIuPGlkZW50PiksCiAgICAgICAgICAgICAgICAvL3NvIGNsb25pbmcgdGhlIHRyZWUgdG8gYXZvaWQgaW50ZXJmZXJlbmNlIGJldHdlZW4gdGhlIHVzZXM6CiAgICAgICAgICAgICAgICBKQ0V4cHJlc3Npb24gZXhwciA9IChKQ0V4cHJlc3Npb24pIGxocy5jbG9uZSgpOwogICAgICAgICAgICAgICAgaWYgKGV4cHIudHlwZSAhPSB0cmVlLnR5cGUpCiAgICAgICAgICAgICAgICAgICAgZXhwciA9IG1ha2UuVHlwZUNhc3QodHJlZS50eXBlLCBleHByKTsKICAgICAgICAgICAgICAgIEpDQmluYXJ5IG9wUmVzdWx0ID0gbWFrZS5CaW5hcnkobmV3VGFnLCBleHByLCB0cmVlLnJocyk7CiAgICAgICAgICAgICAgICBvcFJlc3VsdC5vcGVyYXRvciA9IG5ld09wZXJhdG9yOwogICAgICAgICAgICAgICAgb3BSZXN1bHQudHlwZSA9IG5ld09wZXJhdG9yLnR5cGUuZ2V0UmV0dXJuVHlwZSgpOwogICAgICAgICAgICAgICAgSkNFeHByZXNzaW9uIG5ld1JocyA9IGJveGluZ1JlcSA/CiAgICAgICAgICAgICAgICAgICAgbWFrZS5UeXBlQ2FzdCh0eXBlcy51bmJveGVkVHlwZSh0cmVlLnR5cGUpLCBvcFJlc3VsdCkgOgogICAgICAgICAgICAgICAgICAgIG9wUmVzdWx0OwogICAgICAgICAgICAgICAgcmV0dXJuIG1ha2UuQXNzaWduKGxocywgbmV3UmhzKS5zZXRUeXBlKHRyZWUudHlwZSk7CiAgICAgICAgICAgIH0pOwogICAgICAgICAgICByZXN1bHQgPSB0cmFuc2xhdGUobmV3VHJlZSk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgdHJlZS5saHMgPSB0cmFuc2xhdGUodHJlZS5saHMsIHRyZWUpOwogICAgICAgIHRyZWUucmhzID0gdHJhbnNsYXRlKHRyZWUucmhzLCB0cmVlLm9wZXJhdG9yLnR5cGUuZ2V0UGFyYW1ldGVyVHlwZXMoKS50YWlsLmhlYWQpOwoKICAgICAgICAvLyBJZiB0cmFuc2xhdGVkIGxlZnQgaGFuZCBzaWRlIGlzIGFuIEFwcGx5LCB3ZSBhcmUKICAgICAgICAvLyBzZWVpbmcgYW4gYWNjZXNzIG1ldGhvZCBpbnZvY2F0aW9uLiBJbiB0aGlzIGNhc2UsIGFwcGVuZAogICAgICAgIC8vIHJpZ2h0IGhhbmQgc2lkZSBhcyBsYXN0IGFyZ3VtZW50IG9mIHRoZSBhY2Nlc3MgbWV0aG9kLgogICAgICAgIGlmICh0cmVlLmxocy5oYXNUYWcoQVBQTFkpKSB7CiAgICAgICAgICAgIEpDTWV0aG9kSW52b2NhdGlvbiBhcHAgPSAoSkNNZXRob2RJbnZvY2F0aW9uKXRyZWUubGhzOwogICAgICAgICAgICAvLyBpZiBvcGVyYXRpb24gaXMgYSArPSBvbiBzdHJpbmdzLAogICAgICAgICAgICAvLyBtYWtlIHN1cmUgdG8gY29udmVydCBhcmd1bWVudCB0byBzdHJpbmcKICAgICAgICAgICAgSkNFeHByZXNzaW9uIHJocyA9IHRyZWUub3BlcmF0b3Iub3Bjb2RlID09IHN0cmluZ19hZGQKICAgICAgICAgICAgICA/IG1ha2VTdHJpbmcodHJlZS5yaHMpCiAgICAgICAgICAgICAgOiB0cmVlLnJoczsKICAgICAgICAgICAgYXBwLmFyZ3MgPSBMaXN0Lm9mKHJocykucHJlcGVuZExpc3QoYXBwLmFyZ3MpOwogICAgICAgICAgICByZXN1bHQgPSBhcHA7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmVzdWx0ID0gdHJlZTsKICAgICAgICB9CiAgICB9CgogICAgY2xhc3MgQXNzaWdub3BEZXBlbmRlbmN5U2Nhbm5lciBleHRlbmRzIFRyZWVTY2FubmVyIHsKCiAgICAgICAgU3ltYm9sIHN5bTsKICAgICAgICBib29sZWFuIGRlcGVuZGVuY3lGb3VuZCA9IGZhbHNlOwoKICAgICAgICBBc3NpZ25vcERlcGVuZGVuY3lTY2FubmVyKEpDQXNzaWduT3AgdHJlZSkgewogICAgICAgICAgICB0aGlzLnN5bSA9IFRyZWVJbmZvLnN5bWJvbCh0cmVlLmxocyk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCBzY2FuKEpDVHJlZSB0cmVlKSB7CiAgICAgICAgICAgIGlmICh0cmVlICE9IG51bGwgJiYgc3ltICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIHRyZWUuYWNjZXB0KHRoaXMpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdEFzc2lnbm9wKEpDQXNzaWduT3AgdHJlZSkgewogICAgICAgICAgICBpZiAoVHJlZUluZm8uc3ltYm9sKHRyZWUubGhzKSA9PSBzeW0pIHsKICAgICAgICAgICAgICAgIGRlcGVuZGVuY3lGb3VuZCA9IHRydWU7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc3VwZXIudmlzaXRBc3NpZ25vcCh0cmVlKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0VW5hcnkoSkNVbmFyeSB0cmVlKSB7CiAgICAgICAgICAgIGlmIChUcmVlSW5mby5zeW1ib2wodHJlZS5hcmcpID09IHN5bSkgewogICAgICAgICAgICAgICAgZGVwZW5kZW5jeUZvdW5kID0gdHJ1ZTsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgICAgICBzdXBlci52aXNpdFVuYXJ5KHRyZWUpOwogICAgICAgIH0KICAgIH0KCiAgICAvKiogTG93ZXIgYSB0cmVlIG9mIHRoZSBmb3JtIGUrKyBvciBlLS0gd2hlcmUgZSBpcyBhbiBvYmplY3QgdHlwZSAqLwogICAgSkNFeHByZXNzaW9uIGxvd2VyQm94ZWRQb3N0b3AoZmluYWwgSkNVbmFyeSB0cmVlKSB7CiAgICAgICAgLy8gdHJhbnNsYXRlIHRvIHRtcDE9bHZhbChlKTsgdG1wMj10bXAxOyB0bXAxIE9QIDE7IHRtcDIKICAgICAgICAvLyBvcgogICAgICAgIC8vIHRyYW5zbGF0ZSB0byB0bXAxPWx2YWwoZSk7IHRtcDI9dG1wMTsgKHR5cGVvZiB0cmVlKXRtcDEgT1AgMTsgdG1wMgogICAgICAgIC8vIHdoZXJlIE9QIGlzICs9IG9yIC09CiAgICAgICAgZmluYWwgYm9vbGVhbiBjYXN0ID0gVHJlZUluZm8uc2tpcFBhcmVucyh0cmVlLmFyZykuaGFzVGFnKFRZUEVDQVNUKTsKICAgICAgICByZXR1cm4gYWJzdHJhY3RMdmFsKHRyZWUuYXJnLCB0bXAxIC0+IGFic3RyYWN0UnZhbCh0bXAxLCB0cmVlLmFyZy50eXBlLCB0bXAyIC0+IHsKICAgICAgICAgICAgVGFnIG9wY29kZSA9ICh0cmVlLmhhc1RhZyhQT1NUSU5DKSkKICAgICAgICAgICAgICAgID8gUExVU19BU0cgOiBNSU5VU19BU0c7CiAgICAgICAgICAgIC8vInRtcDEiIGFuZCAidG1wMiIgbWF5IHJlZmVyIHRvIHRoZSBzYW1lIGluc3RhbmNlCiAgICAgICAgICAgIC8vKGZvciBlLmcuIDxDbGFzcz4uc3VwZXIuPGlkZW50PikuIEJ1dCBmdXJ0aGVyIHByb2Nlc3NpbmcgbWF5CiAgICAgICAgICAgIC8vY2hhbmdlIHRoZSBjb21wb25lbnRzIG9mIHRoZSB0cmVlIGluIHBsYWNlIChzZWUgdmlzaXRTZWxlY3QpLAogICAgICAgICAgICAvL3NvIGNsb25pbmcgdGhlIHRyZWUgdG8gYXZvaWQgaW50ZXJmZXJlbmNlIGJldHdlZW4gdGhlIHR3byB1c2VzOgogICAgICAgICAgICBKQ0V4cHJlc3Npb24gbGhzID0gKEpDRXhwcmVzc2lvbil0bXAxLmNsb25lKCk7CiAgICAgICAgICAgIGxocyA9IGNhc3QKICAgICAgICAgICAgICAgID8gbWFrZS5UeXBlQ2FzdCh0cmVlLmFyZy50eXBlLCBsaHMpCiAgICAgICAgICAgICAgICA6IGxoczsKICAgICAgICAgICAgSkNFeHByZXNzaW9uIHVwZGF0ZSA9IG1ha2VBc3NpZ25vcChvcGNvZGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGhzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ha2UuTGl0ZXJhbCgxKSk7CiAgICAgICAgICAgIHJldHVybiBtYWtlQ29tbWEodXBkYXRlLCB0bXAyKTsKICAgICAgICB9KSk7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRVbmFyeShKQ1VuYXJ5IHRyZWUpIHsKICAgICAgICBib29sZWFuIGlzVXBkYXRlT3BlcmF0b3IgPSB0cmVlLmdldFRhZygpLmlzSW5jT3JEZWNVbmFyeU9wKCk7CiAgICAgICAgaWYgKGlzVXBkYXRlT3BlcmF0b3IgJiYgIXRyZWUuYXJnLnR5cGUuaXNQcmltaXRpdmUoKSkgewogICAgICAgICAgICBzd2l0Y2godHJlZS5nZXRUYWcoKSkgewogICAgICAgICAgICBjYXNlIFBSRUlOQzogICAgICAgICAgICAvLyArKyBlCiAgICAgICAgICAgICAgICAgICAgLy8gdHJhbnNsYXRlIHRvIGUgKz0gMQogICAgICAgICAgICBjYXNlIFBSRURFQzogICAgICAgICAgICAvLyAtLSBlCiAgICAgICAgICAgICAgICAgICAgLy8gdHJhbnNsYXRlIHRvIGUgLT0gMQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIEpDVHJlZS5UYWcgb3Bjb2RlID0gKHRyZWUuaGFzVGFnKFBSRUlOQykpCiAgICAgICAgICAgICAgICAgICAgICAgID8gUExVU19BU0cgOiBNSU5VU19BU0c7CiAgICAgICAgICAgICAgICAgICAgSkNBc3NpZ25PcCBuZXdUcmVlID0gbWFrZUFzc2lnbm9wKG9wY29kZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyZWUuYXJnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFrZS5MaXRlcmFsKDEpKTsKICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSB0cmFuc2xhdGUobmV3VHJlZSwgdHJlZS50eXBlKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIGNhc2UgUE9TVElOQzogICAgICAgICAgIC8vIGUgKysKICAgICAgICAgICAgY2FzZSBQT1NUREVDOiAgICAgICAgICAgLy8gZSAtLQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IHRyYW5zbGF0ZShsb3dlckJveGVkUG9zdG9wKHRyZWUpLCB0cmVlLnR5cGUpOwogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IodHJlZSk7CiAgICAgICAgfQoKICAgICAgICB0cmVlLmFyZyA9IGJveElmTmVlZGVkKHRyYW5zbGF0ZSh0cmVlLmFyZywgdHJlZSksIHRyZWUudHlwZSk7CgogICAgICAgIGlmICh0cmVlLmhhc1RhZyhOT1QpICYmIHRyZWUuYXJnLnR5cGUuY29uc3RWYWx1ZSgpICE9IG51bGwpIHsKICAgICAgICAgICAgdHJlZS50eXBlID0gY2ZvbGRlci5mb2xkMShib29sX25vdCwgdHJlZS5hcmcudHlwZSk7CiAgICAgICAgfQoKICAgICAgICAvLyBJZiB0cmFuc2xhdGVkIGxlZnQgaGFuZCBzaWRlIGlzIGFuIEFwcGx5LCB3ZSBhcmUKICAgICAgICAvLyBzZWVpbmcgYW4gYWNjZXNzIG1ldGhvZCBpbnZvY2F0aW9uLiBJbiB0aGlzIGNhc2UsIHJldHVybgogICAgICAgIC8vIHRoYXQgYWNjZXNzIG1ldGhvZCBpbnZvY2F0aW9uIGFzIHJlc3VsdC4KICAgICAgICBpZiAoaXNVcGRhdGVPcGVyYXRvciAmJiB0cmVlLmFyZy5oYXNUYWcoQVBQTFkpKSB7CiAgICAgICAgICAgIHJlc3VsdCA9IHRyZWUuYXJnOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJlc3VsdCA9IHRyZWU7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0QmluYXJ5KEpDQmluYXJ5IHRyZWUpIHsKICAgICAgICBMaXN0PFR5cGU+IGZvcm1hbHMgPSB0cmVlLm9wZXJhdG9yLnR5cGUuZ2V0UGFyYW1ldGVyVHlwZXMoKTsKICAgICAgICBKQ1RyZWUgbGhzID0gdHJlZS5saHMgPSB0cmFuc2xhdGUodHJlZS5saHMsIGZvcm1hbHMuaGVhZCk7CiAgICAgICAgc3dpdGNoICh0cmVlLmdldFRhZygpKSB7CiAgICAgICAgY2FzZSBPUjoKICAgICAgICAgICAgaWYgKGlzVHJ1ZShsaHMpKSB7CiAgICAgICAgICAgICAgICByZXN1bHQgPSBsaHM7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGlzRmFsc2UobGhzKSkgewogICAgICAgICAgICAgICAgcmVzdWx0ID0gdHJhbnNsYXRlKHRyZWUucmhzLCBmb3JtYWxzLnRhaWwuaGVhZCk7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBBTkQ6CiAgICAgICAgICAgIGlmIChpc0ZhbHNlKGxocykpIHsKICAgICAgICAgICAgICAgIHJlc3VsdCA9IGxoczsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoaXNUcnVlKGxocykpIHsKICAgICAgICAgICAgICAgIHJlc3VsdCA9IHRyYW5zbGF0ZSh0cmVlLnJocywgZm9ybWFscy50YWlsLmhlYWQpOwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICB0cmVlLnJocyA9IHRyYW5zbGF0ZSh0cmVlLnJocywgZm9ybWFscy50YWlsLmhlYWQpOwogICAgICAgIHJlc3VsdCA9IHRyZWU7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRJZGVudChKQ0lkZW50IHRyZWUpIHsKICAgICAgICByZXN1bHQgPSBhY2Nlc3ModHJlZS5zeW0sIHRyZWUsIGVuY2xPcCwgZmFsc2UpOwogICAgfQoKICAgIC8qKiBUcmFuc2xhdGUgYXdheSB0aGUgZm9yZWFjaCBsb29wLiAgKi8KICAgIHB1YmxpYyB2b2lkIHZpc2l0Rm9yZWFjaExvb3AoSkNFbmhhbmNlZEZvckxvb3AgdHJlZSkgewogICAgICAgIGlmICh0eXBlcy5lbGVtdHlwZSh0cmVlLmV4cHIudHlwZSkgPT0gbnVsbCkKICAgICAgICAgICAgdmlzaXRJdGVyYWJsZUZvcmVhY2hMb29wKHRyZWUpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgdmlzaXRBcnJheUZvcmVhY2hMb29wKHRyZWUpOwogICAgfQogICAgICAgIC8vIHdoZXJlCiAgICAgICAgLyoqCiAgICAgICAgICogQSBzdGF0ZW1lbnQgb2YgdGhlIGZvcm0KICAgICAgICAgKgogICAgICAgICAqIDxwcmU+CiAgICAgICAgICogICAgIGZvciAoIFQgdiA6IGFycmF5ZXhwciApIHN0bXQ7CiAgICAgICAgICogPC9wcmU+CiAgICAgICAgICoKICAgICAgICAgKiAod2hlcmUgYXJyYXlleHByIGlzIG9mIGFuIGFycmF5IHR5cGUpIGdldHMgdHJhbnNsYXRlZCB0bwogICAgICAgICAqCiAgICAgICAgICogPHByZT57QGNvZGUKICAgICAgICAgKiAgICAgZm9yICggeyBhcnJheXR5cGUgI2FyciA9IGFycmF5ZXhwcjsKICAgICAgICAgKiAgICAgICAgICAgICBpbnQgI2xlbiA9IGFycmF5Lmxlbmd0aDsKICAgICAgICAgKiAgICAgICAgICAgICBpbnQgI2kgPSAwOyB9OwogICAgICAgICAqICAgICAgICAgICAjaSA8ICNsZW47IGkkKysgKSB7CiAgICAgICAgICogICAgICAgICBUIHYgPSBhcnIkWyNpXTsKICAgICAgICAgKiAgICAgICAgIHN0bXQ7CiAgICAgICAgICogICAgIH0KICAgICAgICAgKiB9PC9wcmU+CiAgICAgICAgICoKICAgICAgICAgKiB3aGVyZSAjYXJyLCAjbGVuLCBhbmQgI2kgYXJlIGZyZXNobHkgbmFtZWQgc3ludGhldGljIGxvY2FsIHZhcmlhYmxlcy4KICAgICAgICAgKi8KICAgICAgICBwcml2YXRlIHZvaWQgdmlzaXRBcnJheUZvcmVhY2hMb29wKEpDRW5oYW5jZWRGb3JMb29wIHRyZWUpIHsKICAgICAgICAgICAgbWFrZV9hdCh0cmVlLmV4cHIucG9zKCkpOwogICAgICAgICAgICBWYXJTeW1ib2wgYXJyYXljYWNoZSA9IG5ldyBWYXJTeW1ib2woU1lOVEhFVElDLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZXMuZnJvbVN0cmluZygiYXJyIiArIHRhcmdldC5zeW50aGV0aWNOYW1lQ2hhcigpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyZWUuZXhwci50eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudE1ldGhvZFN5bSk7CiAgICAgICAgICAgIEpDU3RhdGVtZW50IGFycmF5Y2FjaGVkZWYgPSBtYWtlLlZhckRlZihhcnJheWNhY2hlLCB0cmVlLmV4cHIpOwogICAgICAgICAgICBWYXJTeW1ib2wgbGVuY2FjaGUgPSBuZXcgVmFyU3ltYm9sKFNZTlRIRVRJQywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lcy5mcm9tU3RyaW5nKCJsZW4iICsgdGFyZ2V0LnN5bnRoZXRpY05hbWVDaGFyKCkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5bXMuaW50VHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50TWV0aG9kU3ltKTsKICAgICAgICAgICAgSkNTdGF0ZW1lbnQgbGVuY2FjaGVkZWYgPSBtYWtlLgogICAgICAgICAgICAgICAgVmFyRGVmKGxlbmNhY2hlLCBtYWtlLlNlbGVjdChtYWtlLklkZW50KGFycmF5Y2FjaGUpLCBzeW1zLmxlbmd0aFZhcikpOwogICAgICAgICAgICBWYXJTeW1ib2wgaW5kZXggPSBuZXcgVmFyU3ltYm9sKFNZTlRIRVRJQywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lcy5mcm9tU3RyaW5nKCJpIiArIHRhcmdldC5zeW50aGV0aWNOYW1lQ2hhcigpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeW1zLmludFR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudE1ldGhvZFN5bSk7CgogICAgICAgICAgICBKQ1ZhcmlhYmxlRGVjbCBpbmRleGRlZiA9IG1ha2UuVmFyRGVmKGluZGV4LCBtYWtlLkxpdGVyYWwoSU5ULCAwKSk7CiAgICAgICAgICAgIGluZGV4ZGVmLmluaXQudHlwZSA9IGluZGV4ZGVmLnR5cGUgPSBzeW1zLmludFR5cGUuY29uc3RUeXBlKDApOwoKICAgICAgICAgICAgTGlzdDxKQ1N0YXRlbWVudD4gbG9vcGluaXQgPSBMaXN0Lm9mKGFycmF5Y2FjaGVkZWYsIGxlbmNhY2hlZGVmLCBpbmRleGRlZik7CiAgICAgICAgICAgIEpDQmluYXJ5IGNvbmQgPSBtYWtlQmluYXJ5KExULCBtYWtlLklkZW50KGluZGV4KSwgbWFrZS5JZGVudChsZW5jYWNoZSkpOwoKICAgICAgICAgICAgSkNFeHByZXNzaW9uU3RhdGVtZW50IHN0ZXAgPSBtYWtlLkV4ZWMobWFrZVVuYXJ5KFBSRUlOQywgbWFrZS5JZGVudChpbmRleCkpKTsKCiAgICAgICAgICAgIFR5cGUgZWxlbXR5cGUgPSB0eXBlcy5lbGVtdHlwZSh0cmVlLmV4cHIudHlwZSk7CiAgICAgICAgICAgIEpDRXhwcmVzc2lvbiBsb29wdmFyaW5pdCA9IG1ha2UuSW5kZXhlZChtYWtlLklkZW50KGFycmF5Y2FjaGUpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFrZS5JZGVudChpbmRleCkpLnNldFR5cGUoZWxlbXR5cGUpOwogICAgICAgICAgICBKQ1ZhcmlhYmxlRGVjbCBsb29wdmFyZGVmID0gKEpDVmFyaWFibGVEZWNsKW1ha2UuVmFyRGVmKHRyZWUudmFyLm1vZHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJlZS52YXIubmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmVlLnZhci52YXJ0eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvb3B2YXJpbml0KS5zZXRUeXBlKHRyZWUudmFyLnR5cGUpOwogICAgICAgICAgICBsb29wdmFyZGVmLnN5bSA9IHRyZWUudmFyLnN5bTsKICAgICAgICAgICAgSkNCbG9jayBib2R5ID0gbWFrZS4KICAgICAgICAgICAgICAgIEJsb2NrKDAsIExpc3Qub2YobG9vcHZhcmRlZiwgdHJlZS5ib2R5KSk7CgogICAgICAgICAgICByZXN1bHQgPSB0cmFuc2xhdGUobWFrZS4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZvckxvb3AobG9vcGluaXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbmQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExpc3Qub2Yoc3RlcCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvZHkpKTsKICAgICAgICAgICAgcGF0Y2hUYXJnZXRzKGJvZHksIHRyZWUsIHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIC8qKiBQYXRjaCB1cCBicmVhayBhbmQgY29udGludWUgdGFyZ2V0cy4gKi8KICAgICAgICBwcml2YXRlIHZvaWQgcGF0Y2hUYXJnZXRzKEpDVHJlZSBib2R5LCBmaW5hbCBKQ1RyZWUgc3JjLCBmaW5hbCBKQ1RyZWUgZGVzdCkgewogICAgICAgICAgICBjbGFzcyBQYXRjaGVyIGV4dGVuZHMgVHJlZVNjYW5uZXIgewogICAgICAgICAgICAgICAgcHVibGljIHZvaWQgdmlzaXRCcmVhayhKQ0JyZWFrIHRyZWUpIHsKICAgICAgICAgICAgICAgICAgICBpZiAodHJlZS50YXJnZXQgPT0gc3JjKQogICAgICAgICAgICAgICAgICAgICAgICB0cmVlLnRhcmdldCA9IGRlc3Q7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdENvbnRpbnVlKEpDQ29udGludWUgdHJlZSkgewogICAgICAgICAgICAgICAgICAgIGlmICh0cmVlLnRhcmdldCA9PSBzcmMpCiAgICAgICAgICAgICAgICAgICAgICAgIHRyZWUudGFyZ2V0ID0gZGVzdDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0Q2xhc3NEZWYoSkNDbGFzc0RlY2wgdHJlZSkge30KICAgICAgICAgICAgfQogICAgICAgICAgICBuZXcgUGF0Y2hlcigpLnNjYW4oYm9keSk7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIEEgc3RhdGVtZW50IG9mIHRoZSBmb3JtCiAgICAgICAgICoKICAgICAgICAgKiA8cHJlPgogICAgICAgICAqICAgICBmb3IgKCBUIHYgOiBjb2xsICkgc3RtdCA7CiAgICAgICAgICogPC9wcmU+CiAgICAgICAgICoKICAgICAgICAgKiAod2hlcmUgY29sbCBpbXBsZW1lbnRzIHtAY29kZSBJdGVyYWJsZTw/IGV4dGVuZHMgVD59KSBnZXRzIHRyYW5zbGF0ZWQgdG8KICAgICAgICAgKgogICAgICAgICAqIDxwcmU+e0Bjb2RlCiAgICAgICAgICogICAgIGZvciAoIEl0ZXJhdG9yPD8gZXh0ZW5kcyBUPiAjaSA9IGNvbGwuaXRlcmF0b3IoKTsgI2kuaGFzTmV4dCgpOyApIHsKICAgICAgICAgKiAgICAgICAgIFQgdiA9IChUKSAjaS5uZXh0KCk7CiAgICAgICAgICogICAgICAgICBzdG10OwogICAgICAgICAqICAgICB9CiAgICAgICAgICogfTwvcHJlPgogICAgICAgICAqCiAgICAgICAgICogd2hlcmUgI2kgaXMgYSBmcmVzaGx5IG5hbWVkIHN5bnRoZXRpYyBsb2NhbCB2YXJpYWJsZS4KICAgICAgICAgKi8KICAgICAgICBwcml2YXRlIHZvaWQgdmlzaXRJdGVyYWJsZUZvcmVhY2hMb29wKEpDRW5oYW5jZWRGb3JMb29wIHRyZWUpIHsKICAgICAgICAgICAgbWFrZV9hdCh0cmVlLmV4cHIucG9zKCkpOwogICAgICAgICAgICBUeXBlIGl0ZXJhdG9yVGFyZ2V0ID0gc3ltcy5vYmplY3RUeXBlOwogICAgICAgICAgICBUeXBlIGl0ZXJhYmxlVHlwZSA9IHR5cGVzLmFzU3VwZXIodHlwZXMuY3ZhclVwcGVyQm91bmQodHJlZS5leHByLnR5cGUpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ltcy5pdGVyYWJsZVR5cGUudHN5bSk7CiAgICAgICAgICAgIGlmIChpdGVyYWJsZVR5cGUuZ2V0VHlwZUFyZ3VtZW50cygpLm5vbkVtcHR5KCkpCiAgICAgICAgICAgICAgICBpdGVyYXRvclRhcmdldCA9IHR5cGVzLmVyYXN1cmUoaXRlcmFibGVUeXBlLmdldFR5cGVBcmd1bWVudHMoKS5oZWFkKTsKICAgICAgICAgICAgVHlwZSBlVHlwZSA9IHR5cGVzLnNraXBUeXBlVmFycyh0cmVlLmV4cHIudHlwZSwgZmFsc2UpOwogICAgICAgICAgICB0cmVlLmV4cHIudHlwZSA9IHR5cGVzLmVyYXN1cmUoZVR5cGUpOwogICAgICAgICAgICBpZiAoZVR5cGUuaXNDb21wb3VuZCgpKQogICAgICAgICAgICAgICAgdHJlZS5leHByID0gbWFrZS5UeXBlQ2FzdCh0eXBlcy5lcmFzdXJlKGl0ZXJhYmxlVHlwZSksIHRyZWUuZXhwcik7CiAgICAgICAgICAgIFN5bWJvbCBpdGVyYXRvciA9IGxvb2t1cE1ldGhvZCh0cmVlLmV4cHIucG9zKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lcy5pdGVyYXRvciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTGlzdC5uaWwoKSk7CiAgICAgICAgICAgIFZhclN5bWJvbCBpdHZhciA9IG5ldyBWYXJTeW1ib2woU1lOVEhFVElDLCBuYW1lcy5mcm9tU3RyaW5nKCJpIiArIHRhcmdldC5zeW50aGV0aWNOYW1lQ2hhcigpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlcy5lcmFzdXJlKHR5cGVzLmFzU3VwZXIoaXRlcmF0b3IudHlwZS5nZXRSZXR1cm5UeXBlKCksIHN5bXMuaXRlcmF0b3JUeXBlLnRzeW0pKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50TWV0aG9kU3ltKTsKCiAgICAgICAgICAgICBKQ1N0YXRlbWVudCBpbml0ID0gbWFrZS4KICAgICAgICAgICAgICAgIFZhckRlZihpdHZhciwgbWFrZS5BcHAobWFrZS5TZWxlY3QodHJlZS5leHByLCBpdGVyYXRvcikKICAgICAgICAgICAgICAgICAgICAgLnNldFR5cGUodHlwZXMuZXJhc3VyZShpdGVyYXRvci50eXBlKSkpKTsKCiAgICAgICAgICAgIFN5bWJvbCBoYXNOZXh0ID0gbG9va3VwTWV0aG9kKHRyZWUuZXhwci5wb3MoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZXMuaGFzTmV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXR2YXIudHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTGlzdC5uaWwoKSk7CiAgICAgICAgICAgIEpDTWV0aG9kSW52b2NhdGlvbiBjb25kID0gbWFrZS5BcHAobWFrZS5TZWxlY3QobWFrZS5JZGVudChpdHZhciksIGhhc05leHQpKTsKICAgICAgICAgICAgU3ltYm9sIG5leHQgPSBsb29rdXBNZXRob2QodHJlZS5leHByLnBvcygpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lcy5uZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpdHZhci50eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0Lm5pbCgpKTsKICAgICAgICAgICAgSkNFeHByZXNzaW9uIHZhcmRlZmluaXQgPSBtYWtlLkFwcChtYWtlLlNlbGVjdChtYWtlLklkZW50KGl0dmFyKSwgbmV4dCkpOwogICAgICAgICAgICBpZiAodHJlZS52YXIudHlwZS5pc1ByaW1pdGl2ZSgpKQogICAgICAgICAgICAgICAgdmFyZGVmaW5pdCA9IG1ha2UuVHlwZUNhc3QodHlwZXMuY3ZhclVwcGVyQm91bmQoaXRlcmF0b3JUYXJnZXQpLCB2YXJkZWZpbml0KTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgdmFyZGVmaW5pdCA9IG1ha2UuVHlwZUNhc3QodHJlZS52YXIudHlwZSwgdmFyZGVmaW5pdCk7CiAgICAgICAgICAgIEpDVmFyaWFibGVEZWNsIGluZGV4RGVmID0gKEpDVmFyaWFibGVEZWNsKW1ha2UuVmFyRGVmKHRyZWUudmFyLm1vZHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJlZS52YXIubmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmVlLnZhci52YXJ0eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhcmRlZmluaXQpLnNldFR5cGUodHJlZS52YXIudHlwZSk7CiAgICAgICAgICAgIGluZGV4RGVmLnN5bSA9IHRyZWUudmFyLnN5bTsKICAgICAgICAgICAgSkNCbG9jayBib2R5ID0gbWFrZS5CbG9jaygwLCBMaXN0Lm9mKGluZGV4RGVmLCB0cmVlLmJvZHkpKTsKICAgICAgICAgICAgYm9keS5lbmRwb3MgPSBUcmVlSW5mby5lbmRQb3ModHJlZS5ib2R5KTsKICAgICAgICAgICAgcmVzdWx0ID0gdHJhbnNsYXRlKG1ha2UuCiAgICAgICAgICAgICAgICBGb3JMb29wKExpc3Qub2YoaW5pdCksCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbmQsCiAgICAgICAgICAgICAgICAgICAgICAgIExpc3QubmlsKCksCiAgICAgICAgICAgICAgICAgICAgICAgIGJvZHkpKTsKICAgICAgICAgICAgcGF0Y2hUYXJnZXRzKGJvZHksIHRyZWUsIHJlc3VsdCk7CiAgICAgICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0VmFyRGVmKEpDVmFyaWFibGVEZWNsIHRyZWUpIHsKICAgICAgICBNZXRob2RTeW1ib2wgb2xkTWV0aG9kU3ltID0gY3VycmVudE1ldGhvZFN5bTsKICAgICAgICB0cmVlLm1vZHMgPSB0cmFuc2xhdGUodHJlZS5tb2RzKTsKICAgICAgICB0cmVlLnZhcnR5cGUgPSB0cmFuc2xhdGUodHJlZS52YXJ0eXBlKTsKICAgICAgICBpZiAoY3VycmVudE1ldGhvZFN5bSA9PSBudWxsKSB7CiAgICAgICAgICAgIC8vIEEgY2xhc3Mgb3IgaW5zdGFuY2UgZmllbGQgaW5pdGlhbGl6ZXIuCiAgICAgICAgICAgIGN1cnJlbnRNZXRob2RTeW0gPQogICAgICAgICAgICAgICAgbmV3IE1ldGhvZFN5bWJvbCgodHJlZS5tb2RzLmZsYWdzJlNUQVRJQykgfCBCTE9DSywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZXMuZW1wdHksIG51bGwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRDbGFzcyk7CiAgICAgICAgfQogICAgICAgIGlmICh0cmVlLmluaXQgIT0gbnVsbCkgdHJlZS5pbml0ID0gdHJhbnNsYXRlKHRyZWUuaW5pdCwgdHJlZS50eXBlKTsKICAgICAgICByZXN1bHQgPSB0cmVlOwogICAgICAgIGN1cnJlbnRNZXRob2RTeW0gPSBvbGRNZXRob2RTeW07CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRCbG9jayhKQ0Jsb2NrIHRyZWUpIHsKICAgICAgICBNZXRob2RTeW1ib2wgb2xkTWV0aG9kU3ltID0gY3VycmVudE1ldGhvZFN5bTsKICAgICAgICBpZiAoY3VycmVudE1ldGhvZFN5bSA9PSBudWxsKSB7CiAgICAgICAgICAgIC8vIEJsb2NrIGlzIGEgc3RhdGljIG9yIGluc3RhbmNlIGluaXRpYWxpemVyLgogICAgICAgICAgICBjdXJyZW50TWV0aG9kU3ltID0KICAgICAgICAgICAgICAgIG5ldyBNZXRob2RTeW1ib2wodHJlZS5mbGFncyB8IEJMT0NLLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lcy5lbXB0eSwgbnVsbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudENsYXNzKTsKICAgICAgICB9CiAgICAgICAgc3VwZXIudmlzaXRCbG9jayh0cmVlKTsKICAgICAgICBjdXJyZW50TWV0aG9kU3ltID0gb2xkTWV0aG9kU3ltOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0RG9Mb29wKEpDRG9XaGlsZUxvb3AgdHJlZSkgewogICAgICAgIHRyZWUuYm9keSA9IHRyYW5zbGF0ZSh0cmVlLmJvZHkpOwogICAgICAgIHRyZWUuY29uZCA9IHRyYW5zbGF0ZSh0cmVlLmNvbmQsIHN5bXMuYm9vbGVhblR5cGUpOwogICAgICAgIHJlc3VsdCA9IHRyZWU7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRXaGlsZUxvb3AoSkNXaGlsZUxvb3AgdHJlZSkgewogICAgICAgIHRyZWUuY29uZCA9IHRyYW5zbGF0ZSh0cmVlLmNvbmQsIHN5bXMuYm9vbGVhblR5cGUpOwogICAgICAgIHRyZWUuYm9keSA9IHRyYW5zbGF0ZSh0cmVlLmJvZHkpOwogICAgICAgIHJlc3VsdCA9IHRyZWU7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRGb3JMb29wKEpDRm9yTG9vcCB0cmVlKSB7CiAgICAgICAgdHJlZS5pbml0ID0gdHJhbnNsYXRlKHRyZWUuaW5pdCk7CiAgICAgICAgaWYgKHRyZWUuY29uZCAhPSBudWxsKQogICAgICAgICAgICB0cmVlLmNvbmQgPSB0cmFuc2xhdGUodHJlZS5jb25kLCBzeW1zLmJvb2xlYW5UeXBlKTsKICAgICAgICB0cmVlLnN0ZXAgPSB0cmFuc2xhdGUodHJlZS5zdGVwKTsKICAgICAgICB0cmVlLmJvZHkgPSB0cmFuc2xhdGUodHJlZS5ib2R5KTsKICAgICAgICByZXN1bHQgPSB0cmVlOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0UmV0dXJuKEpDUmV0dXJuIHRyZWUpIHsKICAgICAgICBpZiAodHJlZS5leHByICE9IG51bGwpCiAgICAgICAgICAgIHRyZWUuZXhwciA9IHRyYW5zbGF0ZSh0cmVlLmV4cHIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlcy5lcmFzdXJlKGN1cnJlbnRNZXRob2REZWYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnJlc3R5cGUudHlwZSkpOwogICAgICAgIHJlc3VsdCA9IHRyZWU7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRTd2l0Y2goSkNTd2l0Y2ggdHJlZSkgewogICAgICAgIFR5cGUgc2Vsc3VwZXIgPSB0eXBlcy5zdXBlcnR5cGUodHJlZS5zZWxlY3Rvci50eXBlKTsKICAgICAgICBib29sZWFuIGVudW1Td2l0Y2ggPSBzZWxzdXBlciAhPSBudWxsICYmCiAgICAgICAgICAgICh0cmVlLnNlbGVjdG9yLnR5cGUudHN5bS5mbGFncygpICYgRU5VTSkgIT0gMDsKICAgICAgICBib29sZWFuIHN0cmluZ1N3aXRjaCA9IHNlbHN1cGVyICE9IG51bGwgJiYKICAgICAgICAgICAgdHlwZXMuaXNTYW1lVHlwZSh0cmVlLnNlbGVjdG9yLnR5cGUsIHN5bXMuc3RyaW5nVHlwZSk7CiAgICAgICAgVHlwZSB0YXJnZXQgPSBlbnVtU3dpdGNoID8gdHJlZS5zZWxlY3Rvci50eXBlIDoKICAgICAgICAgICAgKHN0cmluZ1N3aXRjaD8gc3ltcy5zdHJpbmdUeXBlIDogc3ltcy5pbnRUeXBlKTsKICAgICAgICB0cmVlLnNlbGVjdG9yID0gdHJhbnNsYXRlKHRyZWUuc2VsZWN0b3IsIHRhcmdldCk7CiAgICAgICAgdHJlZS5jYXNlcyA9IHRyYW5zbGF0ZUNhc2VzKHRyZWUuY2FzZXMpOwogICAgICAgIGlmIChlbnVtU3dpdGNoKSB7CiAgICAgICAgICAgIHJlc3VsdCA9IHZpc2l0RW51bVN3aXRjaCh0cmVlKTsKICAgICAgICB9IGVsc2UgaWYgKHN0cmluZ1N3aXRjaCkgewogICAgICAgICAgICByZXN1bHQgPSB2aXNpdFN0cmluZ1N3aXRjaCh0cmVlKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXN1bHQgPSB0cmVlOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgSkNUcmVlIHZpc2l0RW51bVN3aXRjaChKQ1N3aXRjaCB0cmVlKSB7CiAgICAgICAgVHlwZVN5bWJvbCBlbnVtU3ltID0gdHJlZS5zZWxlY3Rvci50eXBlLnRzeW07CiAgICAgICAgRW51bU1hcHBpbmcgbWFwID0gbWFwRm9yRW51bSh0cmVlLnBvcygpLCBlbnVtU3ltKTsKICAgICAgICBtYWtlX2F0KHRyZWUucG9zKCkpOwogICAgICAgIFN5bWJvbCBvcmRpbmFsTWV0aG9kID0gbG9va3VwTWV0aG9kKHRyZWUucG9zKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZXMub3JkaW5hbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmVlLnNlbGVjdG9yLnR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTGlzdC5uaWwoKSk7CiAgICAgICAgSkNBcnJheUFjY2VzcyBzZWxlY3RvciA9IG1ha2UuSW5kZXhlZChtYXAubWFwVmFyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFrZS5BcHAobWFrZS5TZWxlY3QodHJlZS5zZWxlY3RvciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yZGluYWxNZXRob2QpKSk7CiAgICAgICAgTGlzdEJ1ZmZlcjxKQ0Nhc2U+IGNhc2VzID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgIGZvciAoSkNDYXNlIGMgOiB0cmVlLmNhc2VzKSB7CiAgICAgICAgICAgIGlmIChjLnBhdCAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICBWYXJTeW1ib2wgbGFiZWwgPSAoVmFyU3ltYm9sKVRyZWVJbmZvLnN5bWJvbChjLnBhdCk7CiAgICAgICAgICAgICAgICBKQ0xpdGVyYWwgcGF0ID0gbWFwLmZvckNvbnN0YW50KGxhYmVsKTsKICAgICAgICAgICAgICAgIGNhc2VzLmFwcGVuZChtYWtlLkNhc2UocGF0LCBjLnN0YXRzKSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBjYXNlcy5hcHBlbmQoYyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgSkNTd2l0Y2ggZW51bVN3aXRjaCA9IG1ha2UuU3dpdGNoKHNlbGVjdG9yLCBjYXNlcy50b0xpc3QoKSk7CiAgICAgICAgcGF0Y2hUYXJnZXRzKGVudW1Td2l0Y2gsIHRyZWUsIGVudW1Td2l0Y2gpOwogICAgICAgIHJldHVybiBlbnVtU3dpdGNoOwogICAgfQoKICAgIHB1YmxpYyBKQ1RyZWUgdmlzaXRTdHJpbmdTd2l0Y2goSkNTd2l0Y2ggdHJlZSkgewogICAgICAgIExpc3Q8SkNDYXNlPiBjYXNlTGlzdCA9IHRyZWUuZ2V0Q2FzZXMoKTsKICAgICAgICBpbnQgYWx0ZXJuYXRpdmVzID0gY2FzZUxpc3Quc2l6ZSgpOwoKICAgICAgICBpZiAoYWx0ZXJuYXRpdmVzID09IDApIHsgLy8gU3RyYW5nZSBidXQgbGVnYWwgcG9zc2liaWxpdHkKICAgICAgICAgICAgcmV0dXJuIG1ha2UuYXQodHJlZS5wb3MoKSkuRXhlYyhhdHRyLm1ha2VOdWxsQ2hlY2sodHJlZS5nZXRFeHByZXNzaW9uKCkpKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBUaGUgZ2VuZXJhbCBhcHByb2FjaCB1c2VkIGlzIHRvIHRyYW5zbGF0ZSBhIHNpbmdsZQogICAgICAgICAgICAgKiBzdHJpbmcgc3dpdGNoIHN0YXRlbWVudCBpbnRvIGEgc2VyaWVzIG9mIHR3byBjaGFpbmVkCiAgICAgICAgICAgICAqIHN3aXRjaCBzdGF0ZW1lbnRzOiB0aGUgZmlyc3QgYSBzeW50aGVzaXplZCBzdGF0ZW1lbnQKICAgICAgICAgICAgICogc3dpdGNoaW5nIG9uIHRoZSBhcmd1bWVudCBzdHJpbmcncyBoYXNoIHZhbHVlIGFuZAogICAgICAgICAgICAgKiBjb21wdXRpbmcgYSBzdHJpbmcncyBwb3NpdGlvbiBpbiB0aGUgbGlzdCBvZiBvcmlnaW5hbAogICAgICAgICAgICAgKiBjYXNlIGxhYmVscywgaWYgYW55LCBmb2xsb3dlZCBieSBhIHNlY29uZCBzd2l0Y2ggb24gdGhlCiAgICAgICAgICAgICAqIGNvbXB1dGVkIGludGVnZXIgdmFsdWUuICBUaGUgc2Vjb25kIHN3aXRjaCBoYXMgdGhlIHNhbWUKICAgICAgICAgICAgICogY29kZSBzdHJ1Y3R1cmUgYXMgdGhlIG9yaWdpbmFsIHN0cmluZyBzd2l0Y2ggc3RhdGVtZW50CiAgICAgICAgICAgICAqIGV4Y2VwdCB0aGF0IHRoZSBzdHJpbmcgY2FzZSBsYWJlbHMgYXJlIHJlcGxhY2VkIHdpdGgKICAgICAgICAgICAgICogcG9zaXRpb25hbCBpbnRlZ2VyIGNvbnN0YW50cyBzdGFydGluZyBhdCAwLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBUaGUgZmlyc3Qgc3dpdGNoIHN0YXRlbWVudCBjYW4gYmUgdGhvdWdodCBvZiBhcyBhbgogICAgICAgICAgICAgKiBpbmxpbmVkIG1hcCBmcm9tIHN0cmluZ3MgdG8gdGhlaXIgcG9zaXRpb24gaW4gdGhlIGNhc2UKICAgICAgICAgICAgICogbGFiZWwgbGlzdC4gIEFuIGFsdGVybmF0ZSBpbXBsZW1lbnRhdGlvbiB3b3VsZCB1c2UgYW4KICAgICAgICAgICAgICogYWN0dWFsIE1hcCBmb3IgdGhpcyBwdXJwb3NlLCBhcyBkb25lIGZvciBlbnVtIHN3aXRjaGVzLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBXaXRoIHNvbWUgYWRkaXRpb25hbCBlZmZvcnQsIGl0IHdvdWxkIGJlIHBvc3NpYmxlIHRvCiAgICAgICAgICAgICAqIHVzZSBhIHNpbmdsZSBzd2l0Y2ggc3RhdGVtZW50IG9uIHRoZSBoYXNoIGNvZGUgb2YgdGhlCiAgICAgICAgICAgICAqIGFyZ3VtZW50LCBidXQgY2FyZSB3b3VsZCBuZWVkIHRvIGJlIHRha2VuIHRvIHByZXNlcnZlCiAgICAgICAgICAgICAqIHRoZSBwcm9wZXIgY29udHJvbCBmbG93IGluIHRoZSBwcmVzZW5jZSBvZiBoYXNoCiAgICAgICAgICAgICAqIGNvbGxpc2lvbnMgYW5kIG90aGVyIGNvbXBsaWNhdGlvbnMsIHN1Y2ggYXMKICAgICAgICAgICAgICogZmFsbHRocm91Z2hzLiAgU3dpdGNoIHN0YXRlbWVudHMgd2l0aCBvbmUgb3IgdHdvCiAgICAgICAgICAgICAqIGFsdGVybmF0aXZlcyBjb3VsZCBhbHNvIGJlIHNwZWNpYWxseSB0cmFuc2xhdGVkIGludG8KICAgICAgICAgICAgICogaWYtdGhlbiBzdGF0ZW1lbnRzIHRvIG9taXQgdGhlIGNvbXB1dGF0aW9uIG9mIHRoZSBoYXNoCiAgICAgICAgICAgICAqIGNvZGUuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIFRoZSBnZW5lcmF0ZWQgY29kZSBhc3N1bWVzIHRoYXQgdGhlIGhhc2hpbmcgYWxnb3JpdGhtCiAgICAgICAgICAgICAqIG9mIFN0cmluZyBpcyB0aGUgc2FtZSBpbiB0aGUgY29tcGlsYXRpb24gZW52aXJvbm1lbnQgYXMKICAgICAgICAgICAgICogaW4gdGhlIGVudmlyb25tZW50IHRoZSBjb2RlIHdpbGwgcnVuIGluLiAgVGhlIHN0cmluZwogICAgICAgICAgICAgKiBoYXNoaW5nIGFsZ29yaXRobSBpbiB0aGUgU0UgSkRLIGhhcyBiZWVuIHVuY2hhbmdlZAogICAgICAgICAgICAgKiBzaW5jZSBhdCBsZWFzdCBKREsgMS4yLiAgU2luY2UgdGhlIGFsZ29yaXRobSBoYXMgYmVlbgogICAgICAgICAgICAgKiBzcGVjaWZpZWQgc2luY2UgdGhhdCByZWxlYXNlIGFzIHdlbGwsIGl0IGlzIHZlcnkKICAgICAgICAgICAgICogdW5saWtlbHkgdG8gYmUgY2hhbmdlZCBpbiB0aGUgZnV0dXJlLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBEaWZmZXJlbnQgaGFzaGluZyBhbGdvcml0aG1zLCBzdWNoIGFzIHRoZSBsZW5ndGggb2YgdGhlCiAgICAgICAgICAgICAqIHN0cmluZ3Mgb3IgYSBwZXJmZWN0IGhhc2hpbmcgYWxnb3JpdGhtIG92ZXIgdGhlCiAgICAgICAgICAgICAqIHBhcnRpY3VsYXIgc2V0IG9mIGNhc2UgbGFiZWxzLCBjb3VsZCBwb3RlbnRpYWxseSBiZQogICAgICAgICAgICAgKiB1c2VkIGluc3RlYWQgb2YgU3RyaW5nLmhhc2hDb2RlLgogICAgICAgICAgICAgKi8KCiAgICAgICAgICAgIExpc3RCdWZmZXI8SkNTdGF0ZW1lbnQ+IHN0bXRMaXN0ID0gbmV3IExpc3RCdWZmZXI8PigpOwoKICAgICAgICAgICAgLy8gTWFwIGZyb20gU3RyaW5nIGNhc2UgbGFiZWxzIHRvIHRoZWlyIG9yaWdpbmFsIHBvc2l0aW9uIGluCiAgICAgICAgICAgIC8vIHRoZSBsaXN0IG9mIGNhc2UgbGFiZWxzLgogICAgICAgICAgICBNYXA8U3RyaW5nLCBJbnRlZ2VyPiBjYXNlTGFiZWxUb1Bvc2l0aW9uID0gbmV3IExpbmtlZEhhc2hNYXA8PihhbHRlcm5hdGl2ZXMgKyAxLCAxLjBmKTsKCiAgICAgICAgICAgIC8vIE1hcCBvZiBoYXNoIGNvZGVzIHRvIHRoZSBzdHJpbmcgY2FzZSBsYWJlbHMgaGF2aW5nIHRoYXQgaGFzaENvZGUuCiAgICAgICAgICAgIE1hcDxJbnRlZ2VyLCBTZXQ8U3RyaW5nPj4gaGFzaFRvU3RyaW5nID0gbmV3IExpbmtlZEhhc2hNYXA8PihhbHRlcm5hdGl2ZXMgKyAxLCAxLjBmKTsKCiAgICAgICAgICAgIGludCBjYXNlUG9zaXRpb24gPSAwOwogICAgICAgICAgICBmb3IoSkNDYXNlIG9uZUNhc2UgOiBjYXNlTGlzdCkgewogICAgICAgICAgICAgICAgSkNFeHByZXNzaW9uIGV4cHJlc3Npb24gPSBvbmVDYXNlLmdldEV4cHJlc3Npb24oKTsKCiAgICAgICAgICAgICAgICBpZiAoZXhwcmVzc2lvbiAhPSBudWxsKSB7IC8vIGV4cHJlc3Npb24gZm9yIGEgImRlZmF1bHQiIGNhc2UgaXMgbnVsbAogICAgICAgICAgICAgICAgICAgIFN0cmluZyBsYWJlbEV4cHIgPSAoU3RyaW5nKSBleHByZXNzaW9uLnR5cGUuY29uc3RWYWx1ZSgpOwogICAgICAgICAgICAgICAgICAgIEludGVnZXIgbWFwcGluZyA9IGNhc2VMYWJlbFRvUG9zaXRpb24ucHV0KGxhYmVsRXhwciwgY2FzZVBvc2l0aW9uKTsKICAgICAgICAgICAgICAgICAgICBBc3NlcnQuY2hlY2tOdWxsKG1hcHBpbmcpOwogICAgICAgICAgICAgICAgICAgIGludCBoYXNoQ29kZSA9IGxhYmVsRXhwci5oYXNoQ29kZSgpOwoKICAgICAgICAgICAgICAgICAgICBTZXQ8U3RyaW5nPiBzdHJpbmdTZXQgPSBoYXNoVG9TdHJpbmcuZ2V0KGhhc2hDb2RlKTsKICAgICAgICAgICAgICAgICAgICBpZiAoc3RyaW5nU2V0ID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nU2V0ID0gbmV3IExpbmtlZEhhc2hTZXQ8PigxLCAxLjBmKTsKICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nU2V0LmFkZChsYWJlbEV4cHIpOwogICAgICAgICAgICAgICAgICAgICAgICBoYXNoVG9TdHJpbmcucHV0KGhhc2hDb2RlLCBzdHJpbmdTZXQpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gYWRkZWQgPSBzdHJpbmdTZXQuYWRkKGxhYmVsRXhwcik7CiAgICAgICAgICAgICAgICAgICAgICAgIEFzc2VydC5jaGVjayhhZGRlZCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgY2FzZVBvc2l0aW9uKys7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIFN5bnRoZXNpemUgYSBzd2l0Y2ggc3RhdGVtZW50IHRoYXQgaGFzIHRoZSBlZmZlY3Qgb2YKICAgICAgICAgICAgLy8gbWFwcGluZyBmcm9tIGEgc3RyaW5nIHRvIHRoZSBpbnRlZ2VyIHBvc2l0aW9uIG9mIHRoYXQKICAgICAgICAgICAgLy8gc3RyaW5nIGluIHRoZSBsaXN0IG9mIGNhc2UgbGFiZWxzLiAgVGhpcyBpcyBkb25lIGJ5CiAgICAgICAgICAgIC8vIHN3aXRjaGluZyBvbiB0aGUgaGFzaENvZGUgb2YgdGhlIHN0cmluZyBmb2xsb3dlZCBieSBhbgogICAgICAgICAgICAvLyBpZi10aGVuLWVsc2UgY2hhaW4gY29tcGFyaW5nIHRoZSBpbnB1dCBmb3IgZXF1YWxpdHkKICAgICAgICAgICAgLy8gd2l0aCBhbGwgdGhlIGNhc2UgbGFiZWxzIGhhdmluZyB0aGF0IGhhc2ggdmFsdWUuCgogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBzJCA9IHRvcCBvZiBzdGFjazsKICAgICAgICAgICAgICogdG1wJCA9IC0xOwogICAgICAgICAgICAgKiBzd2l0Y2goJHMuaGFzaENvZGUoKSkgewogICAgICAgICAgICAgKiAgICAgY2FzZSBjYXNlTGFiZWwuaGFzaENvZGU6CiAgICAgICAgICAgICAqICAgICAgICAgaWYgKHMkLmVxdWFscygiY2FzZUxhYmVsXzEiKQogICAgICAgICAgICAgKiAgICAgICAgICAgdG1wJCA9IGNhc2VMYWJlbFRvUG9zaXRpb24oImNhc2VMYWJlbF8xIik7CiAgICAgICAgICAgICAqICAgICAgICAgZWxzZSBpZiAocyQuZXF1YWxzKCJjYXNlTGFiZWxfMiIpKQogICAgICAgICAgICAgKiAgICAgICAgICAgdG1wJCA9IGNhc2VMYWJlbFRvUG9zaXRpb24oImNhc2VMYWJlbF8yIik7CiAgICAgICAgICAgICAqICAgICAgICAgLi4uCiAgICAgICAgICAgICAqICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAqIC4uLgogICAgICAgICAgICAgKiB9CiAgICAgICAgICAgICAqLwoKICAgICAgICAgICAgVmFyU3ltYm9sIGRvbGxhcl9zID0gbmV3IFZhclN5bWJvbChGSU5BTHxTWU5USEVUSUMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZXMuZnJvbVN0cmluZygicyIgKyB0cmVlLnBvcyArIHRhcmdldC5zeW50aGV0aWNOYW1lQ2hhcigpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeW1zLnN0cmluZ1R5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudE1ldGhvZFN5bSk7CiAgICAgICAgICAgIHN0bXRMaXN0LmFwcGVuZChtYWtlLmF0KHRyZWUucG9zKCkpLlZhckRlZihkb2xsYXJfcywgdHJlZS5nZXRFeHByZXNzaW9uKCkpLnNldFR5cGUoZG9sbGFyX3MudHlwZSkpOwoKICAgICAgICAgICAgVmFyU3ltYm9sIGRvbGxhcl90bXAgPSBuZXcgVmFyU3ltYm9sKFNZTlRIRVRJQywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVzLmZyb21TdHJpbmcoInRtcCIgKyB0cmVlLnBvcyArIHRhcmdldC5zeW50aGV0aWNOYW1lQ2hhcigpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5bXMuaW50VHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRNZXRob2RTeW0pOwogICAgICAgICAgICBKQ1ZhcmlhYmxlRGVjbCBkb2xsYXJfdG1wX2RlZiA9CiAgICAgICAgICAgICAgICAoSkNWYXJpYWJsZURlY2wpbWFrZS5WYXJEZWYoZG9sbGFyX3RtcCwgbWFrZS5MaXRlcmFsKElOVCwgLTEpKS5zZXRUeXBlKGRvbGxhcl90bXAudHlwZSk7CiAgICAgICAgICAgIGRvbGxhcl90bXBfZGVmLmluaXQudHlwZSA9IGRvbGxhcl90bXAudHlwZSA9IHN5bXMuaW50VHlwZTsKICAgICAgICAgICAgc3RtdExpc3QuYXBwZW5kKGRvbGxhcl90bXBfZGVmKTsKICAgICAgICAgICAgTGlzdEJ1ZmZlcjxKQ0Nhc2U+IGNhc2VCdWZmZXIgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgIC8vIGhhc2hDb2RlIHdpbGwgdHJpZ2dlciBudWxsY2hlY2sgb24gb3JpZ2luYWwgc3dpdGNoIGV4cHJlc3Npb24KICAgICAgICAgICAgSkNNZXRob2RJbnZvY2F0aW9uIGhhc2hDb2RlQ2FsbCA9IG1ha2VDYWxsKG1ha2UuSWRlbnQoZG9sbGFyX3MpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZXMuaGFzaENvZGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0Lm5pbCgpKS5zZXRUeXBlKHN5bXMuaW50VHlwZSk7CiAgICAgICAgICAgIEpDU3dpdGNoIHN3aXRjaDEgPSBtYWtlLlN3aXRjaChoYXNoQ29kZUNhbGwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlQnVmZmVyLnRvTGlzdCgpKTsKICAgICAgICAgICAgZm9yKE1hcC5FbnRyeTxJbnRlZ2VyLCBTZXQ8U3RyaW5nPj4gZW50cnkgOiBoYXNoVG9TdHJpbmcuZW50cnlTZXQoKSkgewogICAgICAgICAgICAgICAgaW50IGhhc2hDb2RlID0gZW50cnkuZ2V0S2V5KCk7CiAgICAgICAgICAgICAgICBTZXQ8U3RyaW5nPiBzdHJpbmdzV2l0aEhhc2hDb2RlID0gZW50cnkuZ2V0VmFsdWUoKTsKICAgICAgICAgICAgICAgIEFzc2VydC5jaGVjayhzdHJpbmdzV2l0aEhhc2hDb2RlLnNpemUoKSA+PSAxKTsKCiAgICAgICAgICAgICAgICBKQ1N0YXRlbWVudCBlbHNlcGFydCA9IG51bGw7CiAgICAgICAgICAgICAgICBmb3IoU3RyaW5nIGNhc2VMYWJlbCA6IHN0cmluZ3NXaXRoSGFzaENvZGUgKSB7CiAgICAgICAgICAgICAgICAgICAgSkNNZXRob2RJbnZvY2F0aW9uIHN0cmluZ0VxdWFsc0NhbGwgPSBtYWtlQ2FsbChtYWtlLklkZW50KGRvbGxhcl9zKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVzLmVxdWFscywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExpc3Qub2YobWFrZS5MaXRlcmFsKGNhc2VMYWJlbCkpKTsKICAgICAgICAgICAgICAgICAgICBlbHNlcGFydCA9IG1ha2UuSWYoc3RyaW5nRXF1YWxzQ2FsbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFrZS5FeGVjKG1ha2UuQXNzaWduKG1ha2UuSWRlbnQoZG9sbGFyX3RtcCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYWtlLkxpdGVyYWwoY2FzZUxhYmVsVG9Qb3NpdGlvbi5nZXQoY2FzZUxhYmVsKSkpLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0VHlwZShkb2xsYXJfdG1wLnR5cGUpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZXBhcnQpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIExpc3RCdWZmZXI8SkNTdGF0ZW1lbnQ+IGxiID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgICAgICAgICAgSkNCcmVhayBicmVha1N0bXQgPSBtYWtlLkJyZWFrKG51bGwpOwogICAgICAgICAgICAgICAgYnJlYWtTdG10LnRhcmdldCA9IHN3aXRjaDE7CiAgICAgICAgICAgICAgICBsYi5hcHBlbmQoZWxzZXBhcnQpLmFwcGVuZChicmVha1N0bXQpOwoKICAgICAgICAgICAgICAgIGNhc2VCdWZmZXIuYXBwZW5kKG1ha2UuQ2FzZShtYWtlLkxpdGVyYWwoaGFzaENvZGUpLCBsYi50b0xpc3QoKSkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBzd2l0Y2gxLmNhc2VzID0gY2FzZUJ1ZmZlci50b0xpc3QoKTsKICAgICAgICAgICAgc3RtdExpc3QuYXBwZW5kKHN3aXRjaDEpOwoKICAgICAgICAgICAgLy8gTWFrZSBpc29tb3JwaGljIHN3aXRjaCB0cmVlIHJlcGxhY2luZyBzdHJpbmcgbGFiZWxzCiAgICAgICAgICAgIC8vIHdpdGggY29ycmVzcG9uZGluZyBpbnRlZ2VyIG9uZXMgZnJvbSB0aGUgbGFiZWwgdG8KICAgICAgICAgICAgLy8gcG9zaXRpb24gbWFwLgoKICAgICAgICAgICAgTGlzdEJ1ZmZlcjxKQ0Nhc2U+IGxiID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgICAgICBKQ1N3aXRjaCBzd2l0Y2gyID0gbWFrZS5Td2l0Y2gobWFrZS5JZGVudChkb2xsYXJfdG1wKSwgbGIudG9MaXN0KCkpOwogICAgICAgICAgICBmb3IoSkNDYXNlIG9uZUNhc2UgOiBjYXNlTGlzdCApIHsKICAgICAgICAgICAgICAgIC8vIFJld2lyZSB1cCBvbGQgdW5sYWJlbGVkIGJyZWFrIHN0YXRlbWVudHMgdG8gdGhlCiAgICAgICAgICAgICAgICAvLyByZXBsYWNlbWVudCBzd2l0Y2ggYmVpbmcgY3JlYXRlZC4KICAgICAgICAgICAgICAgIHBhdGNoVGFyZ2V0cyhvbmVDYXNlLCB0cmVlLCBzd2l0Y2gyKTsKCiAgICAgICAgICAgICAgICBib29sZWFuIGlzRGVmYXVsdCA9IChvbmVDYXNlLmdldEV4cHJlc3Npb24oKSA9PSBudWxsKTsKICAgICAgICAgICAgICAgIEpDRXhwcmVzc2lvbiBjYXNlRXhwcjsKICAgICAgICAgICAgICAgIGlmIChpc0RlZmF1bHQpCiAgICAgICAgICAgICAgICAgICAgY2FzZUV4cHIgPSBudWxsOwogICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgY2FzZUV4cHIgPSBtYWtlLkxpdGVyYWwoY2FzZUxhYmVsVG9Qb3NpdGlvbi5nZXQoKFN0cmluZylUcmVlSW5mby5za2lwUGFyZW5zKG9uZUNhc2UuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldEV4cHJlc3Npb24oKSkuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZS5jb25zdFZhbHVlKCkpKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBsYi5hcHBlbmQobWFrZS5DYXNlKGNhc2VFeHByLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbmVDYXNlLmdldFN0YXRlbWVudHMoKSkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBzd2l0Y2gyLmNhc2VzID0gbGIudG9MaXN0KCk7CiAgICAgICAgICAgIHN0bXRMaXN0LmFwcGVuZChzd2l0Y2gyKTsKCiAgICAgICAgICAgIHJldHVybiBtYWtlLkJsb2NrKDBMLCBzdG10TGlzdC50b0xpc3QoKSk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0TmV3QXJyYXkoSkNOZXdBcnJheSB0cmVlKSB7CiAgICAgICAgdHJlZS5lbGVtdHlwZSA9IHRyYW5zbGF0ZSh0cmVlLmVsZW10eXBlKTsKICAgICAgICBmb3IgKExpc3Q8SkNFeHByZXNzaW9uPiB0ID0gdHJlZS5kaW1zOyB0LnRhaWwgIT0gbnVsbDsgdCA9IHQudGFpbCkKICAgICAgICAgICAgaWYgKHQuaGVhZCAhPSBudWxsKSB0LmhlYWQgPSB0cmFuc2xhdGUodC5oZWFkLCBzeW1zLmludFR5cGUpOwogICAgICAgIHRyZWUuZWxlbXMgPSB0cmFuc2xhdGUodHJlZS5lbGVtcywgdHlwZXMuZWxlbXR5cGUodHJlZS50eXBlKSk7CiAgICAgICAgcmVzdWx0ID0gdHJlZTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdFNlbGVjdChKQ0ZpZWxkQWNjZXNzIHRyZWUpIHsKICAgICAgICAvLyBuZWVkIHRvIHNwZWNpYWwgY2FzZS1hY2Nlc3Mgb2YgdGhlIGZvcm0gQy5zdXBlci54CiAgICAgICAgLy8gdGhlc2Ugd2lsbCBhbHdheXMgbmVlZCBhbiBhY2Nlc3MgbWV0aG9kLCB1bmxlc3MgQwogICAgICAgIC8vIGlzIGEgZGVmYXVsdCBpbnRlcmZhY2Ugc3ViY2xhc3NlZCBieSB0aGUgY3VycmVudCBjbGFzcy4KICAgICAgICBib29sZWFuIHF1YWxpZmllZFN1cGVyQWNjZXNzID0KICAgICAgICAgICAgdHJlZS5zZWxlY3RlZC5oYXNUYWcoU0VMRUNUKSAmJgogICAgICAgICAgICBUcmVlSW5mby5uYW1lKHRyZWUuc2VsZWN0ZWQpID09IG5hbWVzLl9zdXBlciAmJgogICAgICAgICAgICAhdHlwZXMuaXNEaXJlY3RTdXBlckludGVyZmFjZSgoKEpDRmllbGRBY2Nlc3MpdHJlZS5zZWxlY3RlZCkuc2VsZWN0ZWQudHlwZS50c3ltLCBjdXJyZW50Q2xhc3MpOwogICAgICAgIHRyZWUuc2VsZWN0ZWQgPSB0cmFuc2xhdGUodHJlZS5zZWxlY3RlZCk7CiAgICAgICAgaWYgKHRyZWUubmFtZSA9PSBuYW1lcy5fY2xhc3MpIHsKICAgICAgICAgICAgcmVzdWx0ID0gY2xhc3NPZih0cmVlLnNlbGVjdGVkKTsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAodHJlZS5uYW1lID09IG5hbWVzLl9zdXBlciAmJgogICAgICAgICAgICAgICAgdHlwZXMuaXNEaXJlY3RTdXBlckludGVyZmFjZSh0cmVlLnNlbGVjdGVkLnR5cGUudHN5bSwgY3VycmVudENsYXNzKSkgewogICAgICAgICAgICAvL2RlZmF1bHQgc3VwZXIgY2FsbCEhIE5vdCBhIGNsYXNzaWMgcXVhbGlmaWVkIHN1cGVyIGNhbGwKICAgICAgICAgICAgVHlwZVN5bWJvbCBzdXBTeW0gPSB0cmVlLnNlbGVjdGVkLnR5cGUudHN5bTsKICAgICAgICAgICAgQXNzZXJ0LmNoZWNrTm9uTnVsbCh0eXBlcy5hc1N1cGVyKGN1cnJlbnRDbGFzcy50eXBlLCBzdXBTeW0pKTsKICAgICAgICAgICAgcmVzdWx0ID0gdHJlZTsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAodHJlZS5uYW1lID09IG5hbWVzLl90aGlzIHx8IHRyZWUubmFtZSA9PSBuYW1lcy5fc3VwZXIpIHsKICAgICAgICAgICAgcmVzdWx0ID0gbWFrZVRoaXModHJlZS5wb3MoKSwgdHJlZS5zZWxlY3RlZC50eXBlLnRzeW0pOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgICAgIHJlc3VsdCA9IGFjY2Vzcyh0cmVlLnN5bSwgdHJlZSwgZW5jbE9wLCBxdWFsaWZpZWRTdXBlckFjY2Vzcyk7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRMZXRFeHByKExldEV4cHIgdHJlZSkgewogICAgICAgIHRyZWUuZGVmcyA9IHRyYW5zbGF0ZVZhckRlZnModHJlZS5kZWZzKTsKICAgICAgICB0cmVlLmV4cHIgPSB0cmFuc2xhdGUodHJlZS5leHByLCB0cmVlLnR5cGUpOwogICAgICAgIHJlc3VsdCA9IHRyZWU7CiAgICB9CgogICAgLy8gVGhlcmUgb3VnaHQgdG8gYmUgbm90aGluZyB0byByZXdyaXRlIGhlcmU7CiAgICAvLyB3ZSBkb24ndCBnZW5lcmF0ZSBjb2RlLgogICAgcHVibGljIHZvaWQgdmlzaXRBbm5vdGF0aW9uKEpDQW5ub3RhdGlvbiB0cmVlKSB7CiAgICAgICAgcmVzdWx0ID0gdHJlZTsKICAgIH0KCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHZpc2l0VHJ5KEpDVHJ5IHRyZWUpIHsKICAgICAgICBpZiAodHJlZS5yZXNvdXJjZXMubm9uRW1wdHkoKSkgewogICAgICAgICAgICByZXN1bHQgPSBtYWtlVHdyVHJ5KHRyZWUpOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICBib29sZWFuIGhhc0JvZHkgPSB0cmVlLmJvZHkuZ2V0U3RhdGVtZW50cygpLm5vbkVtcHR5KCk7CiAgICAgICAgYm9vbGVhbiBoYXNDYXRjaGVycyA9IHRyZWUuY2F0Y2hlcnMubm9uRW1wdHkoKTsKICAgICAgICBib29sZWFuIGhhc0ZpbmFsbHkgPSB0cmVlLmZpbmFsaXplciAhPSBudWxsICYmCiAgICAgICAgICAgICAgICB0cmVlLmZpbmFsaXplci5nZXRTdGF0ZW1lbnRzKCkubm9uRW1wdHkoKTsKCiAgICAgICAgaWYgKCFoYXNDYXRjaGVycyAmJiAhaGFzRmluYWxseSkgewogICAgICAgICAgICByZXN1bHQgPSB0cmFuc2xhdGUodHJlZS5ib2R5KTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFoYXNCb2R5KSB7CiAgICAgICAgICAgIGlmIChoYXNGaW5hbGx5KSB7CiAgICAgICAgICAgICAgICByZXN1bHQgPSB0cmFuc2xhdGUodHJlZS5maW5hbGl6ZXIpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcmVzdWx0ID0gdHJhbnNsYXRlKHRyZWUuYm9keSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgLy8gbm8gb3B0aW1pemF0aW9ucyBwb3NzaWJsZQogICAgICAgIHN1cGVyLnZpc2l0VHJ5KHRyZWUpOwogICAgfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIG1haW4gbWV0aG9kCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKICAgIC8qKiBUcmFuc2xhdGUgYSB0b3BsZXZlbCBjbGFzcyBhbmQgcmV0dXJuIGEgbGlzdCBjb25zaXN0aW5nIG9mCiAgICAgKiAgdGhlIHRyYW5zbGF0ZWQgY2xhc3MgYW5kIHRyYW5zbGF0ZWQgdmVyc2lvbnMgb2YgYWxsIGlubmVyIGNsYXNzZXMuCiAgICAgKiAgQHBhcmFtIGVudiAgIFRoZSBhdHRyaWJ1dGlvbiBlbnZpcm9ubWVudCBjdXJyZW50IGF0IHRoZSBjbGFzcyBkZWZpbml0aW9uLgogICAgICogICAgICAgICAgICAgICBXZSBuZWVkIHRoaXMgZm9yIHJlc29sdmluZyBzb21lIGFkZGl0aW9uYWwgc3ltYm9scy4KICAgICAqICBAcGFyYW0gY2RlZiAgVGhlIHRyZWUgcmVwcmVzZW50aW5nIHRoZSBjbGFzcyBkZWZpbml0aW9uLgogICAgICovCiAgICBwdWJsaWMgTGlzdDxKQ1RyZWU+IHRyYW5zbGF0ZVRvcExldmVsQ2xhc3MoRW52PEF0dHJDb250ZXh0PiBlbnYsIEpDVHJlZSBjZGVmLCBUcmVlTWFrZXIgbWFrZSkgewogICAgICAgIExpc3RCdWZmZXI8SkNUcmVlPiB0cmFuc2xhdGVkID0gbnVsbDsKICAgICAgICB0cnkgewogICAgICAgICAgICBhdHRyRW52ID0gZW52OwogICAgICAgICAgICB0aGlzLm1ha2UgPSBtYWtlOwogICAgICAgICAgICBlbmRQb3NUYWJsZSA9IGVudi50b3BsZXZlbC5lbmRQb3NpdGlvbnM7CiAgICAgICAgICAgIGN1cnJlbnRDbGFzcyA9IG51bGw7CiAgICAgICAgICAgIGN1cnJlbnRNZXRob2REZWYgPSBudWxsOwogICAgICAgICAgICBvdXRlcm1vc3RDbGFzc0RlZiA9IChjZGVmLmhhc1RhZyhDTEFTU0RFRikpID8gKEpDQ2xhc3NEZWNsKWNkZWYgOiBudWxsOwogICAgICAgICAgICBvdXRlcm1vc3RNZW1iZXJEZWYgPSBudWxsOwogICAgICAgICAgICB0aGlzLnRyYW5zbGF0ZWQgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgIGNsYXNzZGVmcyA9IG5ldyBIYXNoTWFwPD4oKTsKICAgICAgICAgICAgYWN0dWFsU3ltYm9scyA9IG5ldyBIYXNoTWFwPD4oKTsKICAgICAgICAgICAgZnJlZXZhckNhY2hlID0gbmV3IEhhc2hNYXA8PigpOwogICAgICAgICAgICBwcm94aWVzID0gV3JpdGVhYmxlU2NvcGUuY3JlYXRlKHN5bXMubm9TeW1ib2wpOwogICAgICAgICAgICB0d3JWYXJzID0gV3JpdGVhYmxlU2NvcGUuY3JlYXRlKHN5bXMubm9TeW1ib2wpOwogICAgICAgICAgICBvdXRlclRoaXNTdGFjayA9IExpc3QubmlsKCk7CiAgICAgICAgICAgIGFjY2Vzc051bXMgPSBuZXcgSGFzaE1hcDw+KCk7CiAgICAgICAgICAgIGFjY2Vzc1N5bXMgPSBuZXcgSGFzaE1hcDw+KCk7CiAgICAgICAgICAgIGFjY2Vzc0NvbnN0cnMgPSBuZXcgSGFzaE1hcDw+KCk7CiAgICAgICAgICAgIGFjY2Vzc0NvbnN0clRhZ3MgPSBMaXN0Lm5pbCgpOwogICAgICAgICAgICBhY2Nlc3NlZCA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICAgICAgdHJhbnNsYXRlKGNkZWYsIChKQ0V4cHJlc3Npb24pbnVsbCk7CiAgICAgICAgICAgIGZvciAoTGlzdDxTeW1ib2w+IGwgPSBhY2Nlc3NlZC50b0xpc3QoKTsgbC5ub25FbXB0eSgpOyBsID0gbC50YWlsKQogICAgICAgICAgICAgICAgbWFrZUFjY2Vzc2libGUobC5oZWFkKTsKICAgICAgICAgICAgZm9yIChFbnVtTWFwcGluZyBtYXAgOiBlbnVtU3dpdGNoTWFwLnZhbHVlcygpKQogICAgICAgICAgICAgICAgbWFwLnRyYW5zbGF0ZSgpOwogICAgICAgICAgICBjaGVja0NvbmZsaWN0cyh0aGlzLnRyYW5zbGF0ZWQudG9MaXN0KCkpOwogICAgICAgICAgICBjaGVja0FjY2Vzc0NvbnN0cnVjdG9yVGFncygpOwogICAgICAgICAgICB0cmFuc2xhdGVkID0gdGhpcy50cmFuc2xhdGVkOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgIC8vIG5vdGUgdGhhdCByZWN1cnNpdmUgaW52b2NhdGlvbnMgb2YgdGhpcyBtZXRob2QgZmFpbCBoYXJkCiAgICAgICAgICAgIGF0dHJFbnYgPSBudWxsOwogICAgICAgICAgICB0aGlzLm1ha2UgPSBudWxsOwogICAgICAgICAgICBlbmRQb3NUYWJsZSA9IG51bGw7CiAgICAgICAgICAgIGN1cnJlbnRDbGFzcyA9IG51bGw7CiAgICAgICAgICAgIGN1cnJlbnRNZXRob2REZWYgPSBudWxsOwogICAgICAgICAgICBvdXRlcm1vc3RDbGFzc0RlZiA9IG51bGw7CiAgICAgICAgICAgIG91dGVybW9zdE1lbWJlckRlZiA9IG51bGw7CiAgICAgICAgICAgIHRoaXMudHJhbnNsYXRlZCA9IG51bGw7CiAgICAgICAgICAgIGNsYXNzZGVmcyA9IG51bGw7CiAgICAgICAgICAgIGFjdHVhbFN5bWJvbHMgPSBudWxsOwogICAgICAgICAgICBmcmVldmFyQ2FjaGUgPSBudWxsOwogICAgICAgICAgICBwcm94aWVzID0gbnVsbDsKICAgICAgICAgICAgb3V0ZXJUaGlzU3RhY2sgPSBudWxsOwogICAgICAgICAgICBhY2Nlc3NOdW1zID0gbnVsbDsKICAgICAgICAgICAgYWNjZXNzU3ltcyA9IG51bGw7CiAgICAgICAgICAgIGFjY2Vzc0NvbnN0cnMgPSBudWxsOwogICAgICAgICAgICBhY2Nlc3NDb25zdHJUYWdzID0gbnVsbDsKICAgICAgICAgICAgYWNjZXNzZWQgPSBudWxsOwogICAgICAgICAgICBlbnVtU3dpdGNoTWFwLmNsZWFyKCk7CiAgICAgICAgICAgIGFzc2VydGlvbnNEaXNhYmxlZENsYXNzQ2FjaGUgPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdHJhbnNsYXRlZC50b0xpc3QoKTsKICAgIH0KfQpQSwMECgAACAAABjupSvR7rDbKzAAAyswAACYAAABjb20vc3VuL3Rvb2xzL2phdmFjL2NvbXAvQW5ub3RhdGUuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwMywgMjAxNywgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLmphdmFjLmNvbXA7CgppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLio7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuQXR0cmlidXRlLkNvbXBvdW5kOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLkF0dHJpYnV0ZS5UeXBlQ29tcG91bmQ7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuU2NvcGUuV3JpdGVhYmxlU2NvcGU7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuU3ltYm9sLio7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuVHlwZU1ldGFkYXRhLkVudHJ5LktpbmQ7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnJlc291cmNlcy5Db21waWxlclByb3BlcnRpZXMuRXJyb3JzOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkpDVHJlZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5KQ1RyZWUuKjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5UcmVlSW5mbzsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5UcmVlTWFrZXI7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuVHJlZVNjYW5uZXI7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuKjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5KQ0RpYWdub3N0aWMuRGlhZ25vc3RpY1Bvc2l0aW9uOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkxpc3Q7CgppbXBvcnQgamF2YXgudG9vbHMuSmF2YUZpbGVPYmplY3Q7CmltcG9ydCBqYXZhLnV0aWwuKjsKCmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLkZsYWdzLlNZTlRIRVRJQzsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuS2luZHMuS2luZC5NREw7CmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLktpbmRzLktpbmQuTVRIOwppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5LaW5kcy5LaW5kLlBDSzsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuS2luZHMuS2luZC5WQVI7CmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlNjb3BlLkxvb2t1cEtpbmQuTk9OX1JFQ1VSU0lWRTsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuVHlwZVRhZy5BUlJBWTsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuVHlwZVRhZy5DTEFTUzsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuSkNUcmVlLlRhZy5BTk5PVEFUSU9OOwppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5KQ1RyZWUuVGFnLkFTU0lHTjsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuSkNUcmVlLlRhZy5JREVOVDsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuSkNUcmVlLlRhZy5ORVdBUlJBWTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5KQ0RpYWdub3N0aWMuRGlhZ25vc3RpY0ZsYWc7CgovKiogRW50ZXIgYW5ub3RhdGlvbnMgb250byBzeW1ib2xzIGFuZCB0eXBlcyAoYW5kIHRyZWVzKS4KICoKICogIFRoaXMgaXMgYWxzbyBhIHBzZXVkbyBzdGFnZSBpbiB0aGUgY29tcGlsZXIgdGFraW5nIGNhcmUgb2Ygc2NoZWR1bGluZyB3aGVuIGFubm90YXRpb25zIGFyZQogKiAgZW50ZXJlZC4KICoKICogIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqICBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqICBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogKiAgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPgogKi8KcHVibGljIGNsYXNzIEFubm90YXRlIHsKICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgQ29udGV4dC5LZXk8QW5ub3RhdGU+IGFubm90YXRlS2V5ID0gbmV3IENvbnRleHQuS2V5PD4oKTsKCiAgICBwdWJsaWMgc3RhdGljIEFubm90YXRlIGluc3RhbmNlKENvbnRleHQgY29udGV4dCkgewogICAgICAgIEFubm90YXRlIGluc3RhbmNlID0gY29udGV4dC5nZXQoYW5ub3RhdGVLZXkpOwogICAgICAgIGlmIChpbnN0YW5jZSA9PSBudWxsKQogICAgICAgICAgICBpbnN0YW5jZSA9IG5ldyBBbm5vdGF0ZShjb250ZXh0KTsKICAgICAgICByZXR1cm4gaW5zdGFuY2U7CiAgICB9CgogICAgcHJpdmF0ZSBmaW5hbCBBdHRyIGF0dHI7CiAgICBwcml2YXRlIGZpbmFsIENoZWNrIGNoazsKICAgIHByaXZhdGUgZmluYWwgQ29uc3RGb2xkIGNmb2xkZXI7CiAgICBwcml2YXRlIGZpbmFsIERlZmVycmVkTGludEhhbmRsZXIgZGVmZXJyZWRMaW50SGFuZGxlcjsKICAgIHByaXZhdGUgZmluYWwgRW50ZXIgZW50ZXI7CiAgICBwcml2YXRlIGZpbmFsIExpbnQgbGludDsKICAgIHByaXZhdGUgZmluYWwgTG9nIGxvZzsKICAgIHByaXZhdGUgZmluYWwgTmFtZXMgbmFtZXM7CiAgICBwcml2YXRlIGZpbmFsIFJlc29sdmUgcmVzb2x2ZTsKICAgIHByaXZhdGUgZmluYWwgVHJlZU1ha2VyIG1ha2U7CiAgICBwcml2YXRlIGZpbmFsIFN5bXRhYiBzeW1zOwogICAgcHJpdmF0ZSBmaW5hbCBUeXBlRW52cyB0eXBlRW52czsKICAgIHByaXZhdGUgZmluYWwgVHlwZXMgdHlwZXM7CgogICAgcHJpdmF0ZSBmaW5hbCBBdHRyaWJ1dGUgdGhlVW5maW5pc2hlZERlZmF1bHRWYWx1ZTsKICAgIHByaXZhdGUgZmluYWwgYm9vbGVhbiBhbGxvd1JlcGVhdGVkQW5ub3M7CiAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBzb3VyY2VOYW1lOwoKICAgIHByb3RlY3RlZCBBbm5vdGF0ZShDb250ZXh0IGNvbnRleHQpIHsKICAgICAgICBjb250ZXh0LnB1dChhbm5vdGF0ZUtleSwgdGhpcyk7CgogICAgICAgIGF0dHIgPSBBdHRyLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIGNoayA9IENoZWNrLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIGNmb2xkZXIgPSBDb25zdEZvbGQuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgZGVmZXJyZWRMaW50SGFuZGxlciA9IERlZmVycmVkTGludEhhbmRsZXIuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgZW50ZXIgPSBFbnRlci5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBsb2cgPSBMb2cuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgbGludCA9IExpbnQuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgbWFrZSA9IFRyZWVNYWtlci5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBuYW1lcyA9IE5hbWVzLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIHJlc29sdmUgPSBSZXNvbHZlLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIHN5bXMgPSBTeW10YWIuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgdHlwZUVudnMgPSBUeXBlRW52cy5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICB0eXBlcyA9IFR5cGVzLmluc3RhbmNlKGNvbnRleHQpOwoKICAgICAgICB0aGVVbmZpbmlzaGVkRGVmYXVsdFZhbHVlID0gIG5ldyBBdHRyaWJ1dGUuRXJyb3Ioc3ltcy5lcnJUeXBlKTsKCiAgICAgICAgU291cmNlIHNvdXJjZSA9IFNvdXJjZS5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBhbGxvd1JlcGVhdGVkQW5ub3MgPSBzb3VyY2UuYWxsb3dSZXBlYXRlZEFubm90YXRpb25zKCk7CiAgICAgICAgc291cmNlTmFtZSA9IHNvdXJjZS5uYW1lOwoKICAgICAgICBibG9ja0NvdW50ID0gMTsKICAgIH0KCiAgICAvKiogU2VtYXBob3JlIHRvIGRlbGF5IGFubm90YXRpb24gcHJvY2Vzc2luZyAqLwogICAgcHJpdmF0ZSBpbnQgYmxvY2tDb3VudCA9IDA7CgogICAgLyoqIENhbGxlZCB3aGVuIGFubm90YXRpb25zIHByb2Nlc3NpbmcgbmVlZHMgdG8gYmUgcG9zdHBvbmVkLiAqLwogICAgcHVibGljIHZvaWQgYmxvY2tBbm5vdGF0aW9ucygpIHsKICAgICAgICBibG9ja0NvdW50Kys7CiAgICB9CgogICAgLyoqIENhbGxlZCB3aGVuIGFubm90YXRpb24gcHJvY2Vzc2luZyBjYW4gYmUgcmVzdW1lZC4gKi8KICAgIHB1YmxpYyB2b2lkIHVuYmxvY2tBbm5vdGF0aW9ucygpIHsKICAgICAgICBibG9ja0NvdW50LS07CiAgICAgICAgaWYgKGJsb2NrQ291bnQgPT0gMCkKICAgICAgICAgICAgZmx1c2goKTsKICAgIH0KCiAgICAvKiogVmFyaWFudCB3aGljaCBhbGxvd3MgZm9yIGEgZGVsYXllZCBmbHVzaCBvZiBhbm5vdGF0aW9ucy4KICAgICAqIE5lZWRlZCBieSBDbGFzc1JlYWRlciAqLwogICAgcHVibGljIHZvaWQgdW5ibG9ja0Fubm90YXRpb25zTm9GbHVzaCgpIHsKICAgICAgICBibG9ja0NvdW50LS07CiAgICB9CgogICAgLyoqIGFyZSB3ZSBibG9ja2luZyBhbm5vdGF0aW9uIHByb2Nlc3Npbmc/ICovCiAgICBwdWJsaWMgYm9vbGVhbiBhbm5vdGF0aW9uc0Jsb2NrZWQoKSB7cmV0dXJuIGJsb2NrQ291bnQgPiAwOyB9CgogICAgcHVibGljIHZvaWQgZW50ZXJEb25lKCkgewogICAgICAgIHVuYmxvY2tBbm5vdGF0aW9ucygpOwogICAgfQoKICAgIHB1YmxpYyBMaXN0PFR5cGVDb21wb3VuZD4gZnJvbUFubm90YXRpb25zKExpc3Q8SkNBbm5vdGF0aW9uPiBhbm5vdGF0aW9ucykgewogICAgICAgIGlmIChhbm5vdGF0aW9ucy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmV0dXJuIExpc3QubmlsKCk7CiAgICAgICAgfQoKICAgICAgICBMaXN0QnVmZmVyPFR5cGVDb21wb3VuZD4gYnVmID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgIGZvciAoSkNBbm5vdGF0aW9uIGFubm8gOiBhbm5vdGF0aW9ucykgewogICAgICAgICAgICBBc3NlcnQuY2hlY2tOb25OdWxsKGFubm8uYXR0cmlidXRlKTsKICAgICAgICAgICAgYnVmLmFwcGVuZCgoVHlwZUNvbXBvdW5kKSBhbm5vLmF0dHJpYnV0ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWYudG9MaXN0KCk7CiAgICB9CgogICAgLyoqIEFubm90YXRlICh1c2VkIGZvciBldmVyeXRoaW5nIGVsc2UpICovCiAgICBwdWJsaWMgdm9pZCBub3JtYWwoUnVubmFibGUgcikgewogICAgICAgIHEuYXBwZW5kKHIpOwogICAgfQoKICAgIC8qKiBWYWxpZGF0ZSwgdHJpZ2dlcnMgYWZ0ZXIgJ25vcm1hbCcgKi8KICAgIHB1YmxpYyB2b2lkIHZhbGlkYXRlKFJ1bm5hYmxlIGEpIHsKICAgICAgICB2YWxpZGF0ZVEuYXBwZW5kKGEpOwogICAgfQoKICAgIC8qKiBGbHVzaCBhbGwgYW5ub3RhdGlvbiBxdWV1ZXMgKi8KICAgIHB1YmxpYyB2b2lkIGZsdXNoKCkgewogICAgICAgIGlmIChhbm5vdGF0aW9uc0Jsb2NrZWQoKSkgcmV0dXJuOwogICAgICAgIGlmIChpc0ZsdXNoaW5nKCkpIHJldHVybjsKCiAgICAgICAgc3RhcnRGbHVzaGluZygpOwogICAgICAgIHRyeSB7CiAgICAgICAgICAgIHdoaWxlIChxLm5vbkVtcHR5KCkpIHsKICAgICAgICAgICAgICAgIHEubmV4dCgpLnJ1bigpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHdoaWxlICh0eXBlc1Eubm9uRW1wdHkoKSkgewogICAgICAgICAgICAgICAgdHlwZXNRLm5leHQoKS5ydW4oKTsKICAgICAgICAgICAgfQogICAgICAgICAgICB3aGlsZSAoYWZ0ZXJUeXBlc1Eubm9uRW1wdHkoKSkgewogICAgICAgICAgICAgICAgYWZ0ZXJUeXBlc1EubmV4dCgpLnJ1bigpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHdoaWxlICh2YWxpZGF0ZVEubm9uRW1wdHkoKSkgewogICAgICAgICAgICAgICAgdmFsaWRhdGVRLm5leHQoKS5ydW4oKTsKICAgICAgICAgICAgfQogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgIGRvbmVGbHVzaGluZygpOwogICAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIExpc3RCdWZmZXI8UnVubmFibGU+IHEgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICBwcml2YXRlIExpc3RCdWZmZXI8UnVubmFibGU+IHZhbGlkYXRlUSA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKCiAgICBwcml2YXRlIGludCBmbHVzaENvdW50ID0gMDsKICAgIHByaXZhdGUgYm9vbGVhbiBpc0ZsdXNoaW5nKCkgeyByZXR1cm4gZmx1c2hDb3VudCA+IDA7IH0KICAgIHByaXZhdGUgdm9pZCBzdGFydEZsdXNoaW5nKCkgeyBmbHVzaENvdW50Kys7IH0KICAgIHByaXZhdGUgdm9pZCBkb25lRmx1c2hpbmcoKSB7IGZsdXNoQ291bnQtLTsgfQoKICAgIExpc3RCdWZmZXI8UnVubmFibGU+IHR5cGVzUSA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgIExpc3RCdWZmZXI8UnVubmFibGU+IGFmdGVyVHlwZXNRID0gbmV3IExpc3RCdWZmZXI8PigpOwoKCiAgICBwdWJsaWMgdm9pZCB0eXBlQW5ub3RhdGlvbihSdW5uYWJsZSBhKSB7CiAgICAgICAgdHlwZXNRLmFwcGVuZChhKTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCBhZnRlclR5cGVzKFJ1bm5hYmxlIGEpIHsKICAgICAgICBhZnRlclR5cGVzUS5hcHBlbmQoYSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBRdWV1ZSBhbm5vdGF0aW9ucyBmb3IgbGF0ZXIgYXR0cmlidXRpb24gYW5kIGVudGVyaW5nLiBUaGlzIGlzIHByb2JhYmx5IHRoZSBtZXRob2QgeW91IGFyZSBsb29raW5nIGZvci4KICAgICAqCiAgICAgKiBAcGFyYW0gYW5ub3RhdGlvbnMgdGhlIGxpc3Qgb2YgSkNBbm5vdGF0aW9ucyB0byBhdHRyaWJ1dGUgYW5kIGVudGVyCiAgICAgKiBAcGFyYW0gbG9jYWxFbnYgICAgdGhlIGVuY2xvc2luZyBlbnYKICAgICAqIEBwYXJhbSBzICAgICAgICAgICB0aHMgU3ltYm9sIG9uIHdoaWNoIHRvIGVudGVyIHRoZSBhbm5vdGF0aW9ucwogICAgICogQHBhcmFtIGRlZmVyUG9zICAgIHJlcG9ydCBlcnJvcnMgaGVyZQogICAgICovCiAgICBwdWJsaWMgdm9pZCBhbm5vdGF0ZUxhdGVyKExpc3Q8SkNBbm5vdGF0aW9uPiBhbm5vdGF0aW9ucywgRW52PEF0dHJDb250ZXh0PiBsb2NhbEVudiwKICAgICAgICAgICAgU3ltYm9sIHMsIERpYWdub3N0aWNQb3NpdGlvbiBkZWZlclBvcykKICAgIHsKICAgICAgICBpZiAoYW5ub3RhdGlvbnMuaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIHMucmVzZXRBbm5vdGF0aW9ucygpOyAvLyBtYXJrIEFubm90YXRpb25zIGFzIGluY29tcGxldGUgZm9yIG5vdwoKICAgICAgICBub3JtYWwoKCkgLT4gewogICAgICAgICAgICAvLyBQYWNrYWdlcyBhcmUgdW51c3VhbCwgaW4gdGhhdCB0aGV5IGFyZSB0aGUgb25seSB0eXBlIG9mIGRlY2xhcmF0aW9uIHRoYXQgY2FuIGxlZ2FsbHkgYXBwZWFyCiAgICAgICAgICAgIC8vIG1vcmUgdGhhbiBvbmNlIGluIGEgY29tcGlsYXRpb24sIGFuZCBpbiBhbGwgY2FzZXMgcmVmZXIgdG8gdGhlIHNhbWUgdW5kZXJseWluZyBzeW1ib2wuCiAgICAgICAgICAgIC8vIFRoaXMgbWVhbnMgdGhleSBhcmUgdGhlIG9ubHkga2luZCBvZiBkZWNsYXJhdGlvbiB0aGF0IHN5bnRhY3RpY2FsbHkgbWF5IGhhdmUgbXVsdGlwbGUgc2V0cwogICAgICAgICAgICAvLyBvZiBhbm5vdGF0aW9ucywgZWFjaCBvbiBhIGRpZmZlcmVudCBwYWNrYWdlIGRlY2xhcmF0aW9uLCBldmVuIHRob3VnaCB0aGF0IGlzIHVsdGltYXRlbHkKICAgICAgICAgICAgLy8gZm9yYmlkZGVuIGJ5IEpMUyA4IHNlY3Rpb24gNy40LgogICAgICAgICAgICAvLyBUaGUgY29yb2xsYXJ5IGhlcmUgaXMgdGhhdCBhbGwgb2YgdGhlIGFubm90YXRpb25zIG9uIGEgcGFja2FnZSBzeW1ib2wgbWF5IGhhdmUgYWxyZWFkeQogICAgICAgICAgICAvLyBiZWVuIGhhbmRsZWQsIG1lYW5pbmcgdGhhdCB0aGUgc2V0IG9mIGFubm90YXRpb25zIHBlbmRpbmcgY29tcGxldGlvbiBpcyBub3cgZW1wdHkuCiAgICAgICAgICAgIEFzc2VydC5jaGVjayhzLmtpbmQgPT0gUENLIHx8IHMuYW5ub3RhdGlvbnNQZW5kaW5nQ29tcGxldGlvbigpKTsKICAgICAgICAgICAgSmF2YUZpbGVPYmplY3QgcHJldiA9IGxvZy51c2VTb3VyY2UobG9jYWxFbnYudG9wbGV2ZWwuc291cmNlZmlsZSk7CiAgICAgICAgICAgIERpYWdub3N0aWNQb3NpdGlvbiBwcmV2TGludFBvcyA9CiAgICAgICAgICAgICAgICAgICAgZGVmZXJQb3MgIT0gbnVsbAogICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBkZWZlcnJlZExpbnRIYW5kbGVyLnNldFBvcyhkZWZlclBvcykKICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogZGVmZXJyZWRMaW50SGFuZGxlci5pbW1lZGlhdGUoKTsKICAgICAgICAgICAgTGludCBwcmV2TGludCA9IGRlZmVyUG9zICE9IG51bGwgPyBudWxsIDogY2hrLnNldExpbnQobGludCk7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBpZiAocy5oYXNBbm5vdGF0aW9ucygpICYmIGFubm90YXRpb25zLm5vbkVtcHR5KCkpCiAgICAgICAgICAgICAgICAgICAgbG9nLmVycm9yKGFubm90YXRpb25zLmhlYWQucG9zLCAiYWxyZWFkeS5hbm5vdGF0ZWQiLCBLaW5kcy5raW5kTmFtZShzKSwgcyk7CgogICAgICAgICAgICAgICAgQXNzZXJ0LmNoZWNrTm9uTnVsbChzLCAiU3ltYm9sIGFyZ3VtZW50IHRvIGFjdHVhbEVudGVyQW5ub3RhdGlvbnMgaXMgbnVsbCIpOwoKICAgICAgICAgICAgICAgIC8vIGZhbHNlIGlzIHBhc3NlZCBhcyBmaWZ0aCBwYXJhbWV0ZXIgc2luY2UgYW5ub3RhdGVMYXRlciBpcwogICAgICAgICAgICAgICAgLy8gbmV2ZXIgY2FsbGVkIGZvciBhIHR5cGUgcGFyYW1ldGVyCiAgICAgICAgICAgICAgICBhbm5vdGF0ZU5vdyhzLCBhbm5vdGF0aW9ucywgbG9jYWxFbnYsIGZhbHNlLCBmYWxzZSk7CiAgICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgICAgICBpZiAocHJldkxpbnQgIT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICBjaGsuc2V0TGludChwcmV2TGludCk7CiAgICAgICAgICAgICAgICBkZWZlcnJlZExpbnRIYW5kbGVyLnNldFBvcyhwcmV2TGludFBvcyk7CiAgICAgICAgICAgICAgICBsb2cudXNlU291cmNlKHByZXYpOwogICAgICAgICAgICB9CiAgICAgICAgfSk7CgogICAgICAgIHZhbGlkYXRlKCgpIC0+IHsgLy92YWxpZGF0ZSBhbm5vdGF0aW9ucwogICAgICAgICAgICBKYXZhRmlsZU9iamVjdCBwcmV2ID0gbG9nLnVzZVNvdXJjZShsb2NhbEVudi50b3BsZXZlbC5zb3VyY2VmaWxlKTsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIGNoay52YWxpZGF0ZUFubm90YXRpb25zKGFubm90YXRpb25zLCBzKTsKICAgICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgICAgIGxvZy51c2VTb3VyY2UocHJldik7CiAgICAgICAgICAgIH0KICAgICAgICB9KTsKICAgIH0KCgogICAgLyoqIFF1ZXVlIHByb2Nlc3Npbmcgb2YgYW4gYXR0cmlidXRlIGRlZmF1bHQgdmFsdWUuICovCiAgICBwdWJsaWMgdm9pZCBhbm5vdGF0ZURlZmF1bHRWYWx1ZUxhdGVyKEpDRXhwcmVzc2lvbiBkZWZhdWx0VmFsdWUsIEVudjxBdHRyQ29udGV4dD4gbG9jYWxFbnYsCiAgICAgICAgICAgIE1ldGhvZFN5bWJvbCBtLCBEaWFnbm9zdGljUG9zaXRpb24gZGVmZXJQb3MpCiAgICB7CiAgICAgICAgbm9ybWFsKCgpIC0+IHsKICAgICAgICAgICAgSmF2YUZpbGVPYmplY3QgcHJldiA9IGxvZy51c2VTb3VyY2UobG9jYWxFbnYudG9wbGV2ZWwuc291cmNlZmlsZSk7CiAgICAgICAgICAgIERpYWdub3N0aWNQb3NpdGlvbiBwcmV2TGludFBvcyA9IGRlZmVycmVkTGludEhhbmRsZXIuc2V0UG9zKGRlZmVyUG9zKTsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIGVudGVyRGVmYXVsdFZhbHVlKGRlZmF1bHRWYWx1ZSwgbG9jYWxFbnYsIG0pOwogICAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAgICAgZGVmZXJyZWRMaW50SGFuZGxlci5zZXRQb3MocHJldkxpbnRQb3MpOwogICAgICAgICAgICAgICAgbG9nLnVzZVNvdXJjZShwcmV2KTsKICAgICAgICAgICAgfQogICAgICAgIH0pOwoKICAgICAgICB2YWxpZGF0ZSgoKSAtPiB7IC8vdmFsaWRhdGUgYW5ub3RhdGlvbnMKICAgICAgICAgICAgSmF2YUZpbGVPYmplY3QgcHJldiA9IGxvZy51c2VTb3VyY2UobG9jYWxFbnYudG9wbGV2ZWwuc291cmNlZmlsZSk7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAvLyBpZiBkZWZhdWx0IHZhbHVlIGlzIGFuIGFubm90YXRpb24sIGNoZWNrIGl0IGlzIGEgd2VsbC1mb3JtZWQKICAgICAgICAgICAgICAgIC8vIGFubm90YXRpb24gdmFsdWUgKGUuZy4gbm8gZHVwbGljYXRlIHZhbHVlcywgbm8gbWlzc2luZyB2YWx1ZXMsIGV0Yy4pCiAgICAgICAgICAgICAgICBjaGsudmFsaWRhdGVBbm5vdGF0aW9uVHJlZShkZWZhdWx0VmFsdWUpOwogICAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAgICAgbG9nLnVzZVNvdXJjZShwcmV2KTsKICAgICAgICAgICAgfQogICAgICAgIH0pOwogICAgfQoKICAgIC8qKiBFbnRlciBhIGRlZmF1bHQgdmFsdWUgZm9yIGFuIGFubm90YXRpb24gZWxlbWVudC4gKi8KICAgIHByaXZhdGUgdm9pZCBlbnRlckRlZmF1bHRWYWx1ZShKQ0V4cHJlc3Npb24gZGVmYXVsdFZhbHVlLAogICAgICAgICAgICBFbnY8QXR0ckNvbnRleHQ+IGxvY2FsRW52LCBNZXRob2RTeW1ib2wgbSkgewogICAgICAgIG0uZGVmYXVsdFZhbHVlID0gYXR0cmlidXRlQW5ub3RhdGlvblZhbHVlKG0udHlwZS5nZXRSZXR1cm5UeXBlKCksIGRlZmF1bHRWYWx1ZSwgbG9jYWxFbnYpOwogICAgfQoKICAgIC8qKgogICAgICogR2F0aGVyIHVwIGFubm90YXRpb25zIGludG8gYSBtYXAgZnJvbSB0eXBlIHN5bWJvbHMgdG8gbGlzdHMgb2YgQ29tcG91bmQgYXR0cmlidXRlcywKICAgICAqIHRoZW4gY29udGludWUgb24gd2l0aCByZXBlYXRpbmcgYW5ub3RhdGlvbnMgcHJvY2Vzc2luZy4KICAgICAqLwogICAgcHJpdmF0ZSA8VCBleHRlbmRzIEF0dHJpYnV0ZS5Db21wb3VuZD4gdm9pZCBhbm5vdGF0ZU5vdyhTeW1ib2wgdG9Bbm5vdGF0ZSwKICAgICAgICAgICAgTGlzdDxKQ0Fubm90YXRpb24+IHdpdGhBbm5vdGF0aW9ucywgRW52PEF0dHJDb250ZXh0PiBlbnYsIGJvb2xlYW4gdHlwZUFubm90YXRpb25zLAogICAgICAgICAgICBib29sZWFuIGlzVHlwZVBhcmFtKQogICAgewogICAgICAgIE1hcDxUeXBlU3ltYm9sLCBMaXN0QnVmZmVyPFQ+PiBhbm5vdGF0ZWQgPSBuZXcgTGlua2VkSGFzaE1hcDw+KCk7CiAgICAgICAgTWFwPFQsIERpYWdub3N0aWNQb3NpdGlvbj4gcG9zID0gbmV3IEhhc2hNYXA8PigpOwoKICAgICAgICBmb3IgKExpc3Q8SkNBbm5vdGF0aW9uPiBhbCA9IHdpdGhBbm5vdGF0aW9uczsgIWFsLmlzRW1wdHkoKTsgYWwgPSBhbC50YWlsKSB7CiAgICAgICAgICAgIEpDQW5ub3RhdGlvbiBhID0gYWwuaGVhZDsKCiAgICAgICAgICAgIFQgYzsKICAgICAgICAgICAgaWYgKHR5cGVBbm5vdGF0aW9ucykgewogICAgICAgICAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCiAgICAgICAgICAgICAgICBUIHRtcCA9IChUKWF0dHJpYnV0ZVR5cGVBbm5vdGF0aW9uKGEsIHN5bXMuYW5ub3RhdGlvblR5cGUsIGVudik7CiAgICAgICAgICAgICAgICBjID0gdG1wOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCiAgICAgICAgICAgICAgICBUIHRtcCA9IChUKWF0dHJpYnV0ZUFubm90YXRpb24oYSwgc3ltcy5hbm5vdGF0aW9uVHlwZSwgZW52KTsKICAgICAgICAgICAgICAgIGMgPSB0bXA7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEFzc2VydC5jaGVja05vbk51bGwoYywgIkZhaWxlZCB0byBjcmVhdGUgYW5ub3RhdGlvbiIpOwoKICAgICAgICAgICAgaWYgKGFubm90YXRlZC5jb250YWluc0tleShhLnR5cGUudHN5bSkpIHsKICAgICAgICAgICAgICAgIGlmICghYWxsb3dSZXBlYXRlZEFubm9zKSB7CiAgICAgICAgICAgICAgICAgICAgbG9nLmVycm9yKERpYWdub3N0aWNGbGFnLlNPVVJDRV9MRVZFTCwgYS5wb3MoKSwgInJlcGVhdGFibGUuYW5ub3RhdGlvbnMubm90LnN1cHBvcnRlZC5pbi5zb3VyY2UiLCBzb3VyY2VOYW1lKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIExpc3RCdWZmZXI8VD4gbCA9IGFubm90YXRlZC5nZXQoYS50eXBlLnRzeW0pOwogICAgICAgICAgICAgICAgbCA9IGwuYXBwZW5kKGMpOwogICAgICAgICAgICAgICAgYW5ub3RhdGVkLnB1dChhLnR5cGUudHN5bSwgbCk7CiAgICAgICAgICAgICAgICBwb3MucHV0KGMsIGEucG9zKCkpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgYW5ub3RhdGVkLnB1dChhLnR5cGUudHN5bSwgTGlzdEJ1ZmZlci5vZihjKSk7CiAgICAgICAgICAgICAgICBwb3MucHV0KGMsIGEucG9zKCkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBOb3RlOiBARGVwcmVjYXRlZCBoYXMgbm8gZWZmZWN0IG9uIGxvY2FsIHZhcmlhYmxlcyBhbmQgcGFyYW1ldGVycwogICAgICAgICAgICBpZiAoIWMudHlwZS5pc0Vycm9uZW91cygpCiAgICAgICAgICAgICAgICAgICAgJiYgKHRvQW5ub3RhdGUua2luZCA9PSBNREwgfHwgdG9Bbm5vdGF0ZS5vd25lci5raW5kICE9IE1USCkKICAgICAgICAgICAgICAgICAgICAmJiB0eXBlcy5pc1NhbWVUeXBlKGMudHlwZSwgc3ltcy5kZXByZWNhdGVkVHlwZSkpIHsKICAgICAgICAgICAgICAgIHRvQW5ub3RhdGUuZmxhZ3NfZmllbGQgfD0gKEZsYWdzLkRFUFJFQ0FURUQgfCBGbGFncy5ERVBSRUNBVEVEX0FOTk9UQVRJT04pOwogICAgICAgICAgICAgICAgQXR0cmlidXRlIGZyID0gYy5tZW1iZXIobmFtZXMuZm9yUmVtb3ZhbCk7CiAgICAgICAgICAgICAgICBpZiAoZnIgaW5zdGFuY2VvZiBBdHRyaWJ1dGUuQ29uc3RhbnQpIHsKICAgICAgICAgICAgICAgICAgICBBdHRyaWJ1dGUuQ29uc3RhbnQgdiA9IChBdHRyaWJ1dGUuQ29uc3RhbnQpIGZyOwogICAgICAgICAgICAgICAgICAgIGlmICh2LnR5cGUgPT0gc3ltcy5ib29sZWFuVHlwZSAmJiAoKEludGVnZXIpIHYudmFsdWUpICE9IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgdG9Bbm5vdGF0ZS5mbGFnc19maWVsZCB8PSBGbGFncy5ERVBSRUNBVEVEX1JFTU9WQUw7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBMaXN0PFQ+IGJ1ZiA9IExpc3QubmlsKCk7CiAgICAgICAgZm9yIChMaXN0QnVmZmVyPFQ+IGxiIDogYW5ub3RhdGVkLnZhbHVlcygpKSB7CiAgICAgICAgICAgIGlmIChsYi5zaXplKCkgPT0gMSkgewogICAgICAgICAgICAgICAgYnVmID0gYnVmLnByZXBlbmQobGIuZmlyc3QoKSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBBbm5vdGF0aW9uQ29udGV4dDxUPiBjdHggPSBuZXcgQW5ub3RhdGlvbkNvbnRleHQ8PihlbnYsIGFubm90YXRlZCwgcG9zLCB0eXBlQW5ub3RhdGlvbnMpOwogICAgICAgICAgICAgICAgVCByZXMgPSBtYWtlQ29udGFpbmVyQW5ub3RhdGlvbihsYi50b0xpc3QoKSwgY3R4LCB0b0Fubm90YXRlLCBpc1R5cGVQYXJhbSk7CiAgICAgICAgICAgICAgICBpZiAocmVzICE9IG51bGwpCiAgICAgICAgICAgICAgICAgICAgYnVmID0gYnVmLnByZXBlbmQocmVzKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKHR5cGVBbm5vdGF0aW9ucykgewogICAgICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKICAgICAgICAgICAgTGlzdDxUeXBlQ29tcG91bmQ+IGF0dHJzID0gKExpc3Q8VHlwZUNvbXBvdW5kPilidWYucmV2ZXJzZSgpOwogICAgICAgICAgICB0b0Fubm90YXRlLmFwcGVuZFVuaXF1ZVR5cGVBdHRyaWJ1dGVzKGF0dHJzKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKICAgICAgICAgICAgTGlzdDxBdHRyaWJ1dGUuQ29tcG91bmQ+IGF0dHJzID0gIChMaXN0PEF0dHJpYnV0ZS5Db21wb3VuZD4pYnVmLnJldmVyc2UoKTsKICAgICAgICAgICAgdG9Bbm5vdGF0ZS5yZXNldEFubm90YXRpb25zKCk7CiAgICAgICAgICAgIHRvQW5ub3RhdGUuc2V0RGVjbGFyYXRpb25BdHRyaWJ1dGVzKGF0dHJzKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBBdHRyaWJ1dGUgYW5kIHN0b3JlIGEgc2VtYW50aWMgcmVwcmVzZW50YXRpb24gb2YgdGhlIGFubm90YXRpb24gdHJlZSB7QGNvZGUgdHJlZX0gaW50byB0aGUKICAgICAqIHRyZWUuYXR0cmlidXRlIGZpZWxkLgogICAgICoKICAgICAqIEBwYXJhbSB0cmVlIHRoZSB0cmVlIHJlcHJlc2VudGluZyBhbiBhbm5vdGF0aW9uCiAgICAgKiBAcGFyYW0gZXhwZWN0ZWRBbm5vdGF0aW9uVHlwZSB0aGUgZXhwZWN0ZWQgKHN1cGVyKXR5cGUgb2YgdGhlIGFubm90YXRpb24KICAgICAqIEBwYXJhbSBlbnYgdGhlIGN1cnJlbnQgZW52IGluIHdoZXJlIHRoZSBhbm5vdGF0aW9uIGluc3RhbmNlIGlzIGZvdW5kCiAgICAgKi8KICAgIHB1YmxpYyBBdHRyaWJ1dGUuQ29tcG91bmQgYXR0cmlidXRlQW5ub3RhdGlvbihKQ0Fubm90YXRpb24gdHJlZSwgVHlwZSBleHBlY3RlZEFubm90YXRpb25UeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVudjxBdHRyQ29udGV4dD4gZW52KQogICAgewogICAgICAgIC8vIFRoZSBhdHRyaWJ1dGUgbWlnaHQgaGF2ZSBiZWVuIGVudGVyZWQgaWYgaXQgaXMgVGFyZ2V0IG9yIFJlcGV0YWJsZQogICAgICAgIC8vIEJlY2F1c2UgVHJlZUNvcGllciBkb2VzIG5vdCBjb3B5IHR5cGUsIHJlZG8gdGhpcyBpZiB0eXBlIGlzIG51bGwKICAgICAgICBpZiAodHJlZS5hdHRyaWJ1dGUgIT0gbnVsbCAmJiB0cmVlLnR5cGUgIT0gbnVsbCkKICAgICAgICAgICAgcmV0dXJuIHRyZWUuYXR0cmlidXRlOwoKICAgICAgICBMaXN0PFBhaXI8TWV0aG9kU3ltYm9sLCBBdHRyaWJ1dGU+PiBlbGVtcyA9IGF0dHJpYnV0ZUFubm90YXRpb25WYWx1ZXModHJlZSwgZXhwZWN0ZWRBbm5vdGF0aW9uVHlwZSwgZW52KTsKICAgICAgICBBdHRyaWJ1dGUuQ29tcG91bmQgYWMgPSBuZXcgQXR0cmlidXRlLkNvbXBvdW5kKHRyZWUudHlwZSwgZWxlbXMpOwoKICAgICAgICByZXR1cm4gdHJlZS5hdHRyaWJ1dGUgPSBhYzsKICAgIH0KCiAgICAvKiogQXR0cmlidXRlIGFuZCBzdG9yZSBhIHNlbWFudGljIHJlcHJlc2VudGF0aW9uIG9mIHRoZSB0eXBlIGFubm90YXRpb24gdHJlZSB7QGNvZGUgdHJlZX0gaW50bwogICAgICogdGhlIHRyZWUuYXR0cmlidXRlIGZpZWxkLgogICAgICoKICAgICAqIEBwYXJhbSBhIHRoZSB0cmVlIHJlcHJlc2VudGluZyBhbiBhbm5vdGF0aW9uCiAgICAgKiBAcGFyYW0gZXhwZWN0ZWRBbm5vdGF0aW9uVHlwZSB0aGUgZXhwZWN0ZWQgKHN1cGVyKXR5cGUgb2YgdGhlIGFubm90YXRpb24KICAgICAqIEBwYXJhbSBlbnYgdGhlIHRoZSBjdXJyZW50IGVudiBpbiB3aGVyZSB0aGUgYW5ub3RhdGlvbiBpbnN0YW5jZSBpcyBmb3VuZAogICAgICovCiAgICBwdWJsaWMgQXR0cmlidXRlLlR5cGVDb21wb3VuZCBhdHRyaWJ1dGVUeXBlQW5ub3RhdGlvbihKQ0Fubm90YXRpb24gYSwgVHlwZSBleHBlY3RlZEFubm90YXRpb25UeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRW52PEF0dHJDb250ZXh0PiBlbnYpCiAgICB7CiAgICAgICAgLy8gVGhlIGF0dHJpYnV0ZSBtaWdodCBoYXZlIGJlZW4gZW50ZXJlZCBpZiBpdCBpcyBUYXJnZXQgb3IgUmVwZXRhYmxlCiAgICAgICAgLy8gQmVjYXVzZSBUcmVlQ29waWVyIGRvZXMgbm90IGNvcHkgdHlwZSwgcmVkbyB0aGlzIGlmIHR5cGUgaXMgbnVsbAogICAgICAgIGlmIChhLmF0dHJpYnV0ZSA9PSBudWxsIHx8IGEudHlwZSA9PSBudWxsIHx8ICEoYS5hdHRyaWJ1dGUgaW5zdGFuY2VvZiBBdHRyaWJ1dGUuVHlwZUNvbXBvdW5kKSkgewogICAgICAgICAgICAvLyBDcmVhdGUgYSBuZXcgVHlwZUNvbXBvdW5kCiAgICAgICAgICAgIExpc3Q8UGFpcjxNZXRob2RTeW1ib2wsQXR0cmlidXRlPj4gZWxlbXMgPQogICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZUFubm90YXRpb25WYWx1ZXMoYSwgZXhwZWN0ZWRBbm5vdGF0aW9uVHlwZSwgZW52KTsKCiAgICAgICAgICAgIEF0dHJpYnV0ZS5UeXBlQ29tcG91bmQgdGMgPQogICAgICAgICAgICAgICAgICAgIG5ldyBBdHRyaWJ1dGUuVHlwZUNvbXBvdW5kKGEudHlwZSwgZWxlbXMsIFR5cGVBbm5vdGF0aW9uUG9zaXRpb24udW5rbm93bik7CiAgICAgICAgICAgIGEuYXR0cmlidXRlID0gdGM7CiAgICAgICAgICAgIHJldHVybiB0YzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvLyBVc2UgYW4gZXhpc3RpbmcgVHlwZUNvbXBvdW5kCiAgICAgICAgICAgIHJldHVybiAoQXR0cmlidXRlLlR5cGVDb21wb3VuZClhLmF0dHJpYnV0ZTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiAgQXR0cmlidXRlIGFubm90YXRpb24gZWxlbWVudHMgY3JlYXRpbmcgYSBsaXN0IG9mIHBhaXJzIG9mIHRoZSBTeW1ib2wgcmVwcmVzZW50aW5nIHRoYXQKICAgICAqICBlbGVtZW50IGFuZCB0aGUgdmFsdWUgb2YgdGhhdCBlbGVtZW50IGFzIGFuIEF0dHJpYnV0ZS4gKi8KICAgIHByaXZhdGUgTGlzdDxQYWlyPE1ldGhvZFN5bWJvbCwgQXR0cmlidXRlPj4gYXR0cmlidXRlQW5ub3RhdGlvblZhbHVlcyhKQ0Fubm90YXRpb24gYSwKICAgICAgICAgICAgVHlwZSBleHBlY3RlZCwgRW52PEF0dHJDb250ZXh0PiBlbnYpCiAgICB7CiAgICAgICAgLy8gVGhlIGFubm90YXRpb24gbWlnaHQgaGF2ZSBoYWQgaXRzIHR5cGUgYXR0cmlidXRlZCAoYnV0IG5vdAogICAgICAgIC8vIGNoZWNrZWQpIGJ5IGF0dHIuYXR0cmliQW5ub3RhdGlvblR5cGVzIGR1cmluZyBNZW1iZXJFbnRlciwKICAgICAgICAvLyBpbiB3aGljaCBjYXNlIHdlIGRvIG5vdCBuZWVkIHRvIGRvIGl0IGFnYWluLgogICAgICAgIFR5cGUgYXQgPSAoYS5hbm5vdGF0aW9uVHlwZS50eXBlICE9IG51bGwgPwogICAgICAgICAgICAgICAgYS5hbm5vdGF0aW9uVHlwZS50eXBlIDogYXR0ci5hdHRyaWJUeXBlKGEuYW5ub3RhdGlvblR5cGUsIGVudikpOwogICAgICAgIGEudHlwZSA9IGNoay5jaGVja1R5cGUoYS5hbm5vdGF0aW9uVHlwZS5wb3MoKSwgYXQsIGV4cGVjdGVkKTsKCiAgICAgICAgYm9vbGVhbiBpc0Vycm9yID0gYS50eXBlLmlzRXJyb25lb3VzKCk7CiAgICAgICAgaWYgKCFhLnR5cGUudHN5bS5pc0Fubm90YXRpb25UeXBlKCkgJiYgIWlzRXJyb3IpIHsKICAgICAgICAgICAgbG9nLmVycm9yKGEuYW5ub3RhdGlvblR5cGUucG9zKCksCiAgICAgICAgICAgICAgICAgICAgIm5vdC5hbm5vdGF0aW9uLnR5cGUiLCBhLnR5cGUudG9TdHJpbmcoKSk7CiAgICAgICAgICAgIGlzRXJyb3IgPSB0cnVlOwogICAgICAgIH0KCiAgICAgICAgLy8gTGlzdCBvZiBuYW1lPXZhbHVlIHBhaXJzIChvciBpbXBsaWNpdCAidmFsdWU9IiBpZiBzaXplIDEpCiAgICAgICAgTGlzdDxKQ0V4cHJlc3Npb24+IGFyZ3MgPSBhLmFyZ3M7CgogICAgICAgIGJvb2xlYW4gZWxpZGVkVmFsdWUgPSBmYWxzZTsKICAgICAgICAvLyBzcGVjaWFsIGNhc2U6IGVsaWRlZCAidmFsdWU9IiBhc3N1bWVkCiAgICAgICAgaWYgKGFyZ3MubGVuZ3RoKCkgPT0gMSAmJiAhYXJncy5oZWFkLmhhc1RhZyhBU1NJR04pKSB7CiAgICAgICAgICAgIGFyZ3MuaGVhZCA9IG1ha2UuYXQoYXJncy5oZWFkLnBvcykuCiAgICAgICAgICAgICAgICAgICAgQXNzaWduKG1ha2UuSWRlbnQobmFtZXMudmFsdWUpLCBhcmdzLmhlYWQpOwogICAgICAgICAgICBlbGlkZWRWYWx1ZSA9IHRydWU7CiAgICAgICAgfQoKICAgICAgICBMaXN0QnVmZmVyPFBhaXI8TWV0aG9kU3ltYm9sLEF0dHJpYnV0ZT4+IGJ1ZiA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICBmb3IgKExpc3Q8SkNFeHByZXNzaW9uPiB0bCA9IGFyZ3M7IHRsLm5vbkVtcHR5KCk7IHRsID0gdGwudGFpbCkgewogICAgICAgICAgICBQYWlyPE1ldGhvZFN5bWJvbCwgQXR0cmlidXRlPiBwID0gYXR0cmlidXRlQW5ub3RhdGlvbk5hbWVWYWx1ZVBhaXIodGwuaGVhZCwgYS50eXBlLCBpc0Vycm9yLCBlbnYsIGVsaWRlZFZhbHVlKTsKICAgICAgICAgICAgaWYgKHAgIT0gbnVsbCAmJiAhcC5mc3QudHlwZS5pc0Vycm9uZW91cygpKQogICAgICAgICAgICAgICAgYnVmLmFwcGVuZChwKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1Zi50b0xpc3QoKTsKICAgIH0KCiAgICAvLyB3aGVyZQogICAgcHJpdmF0ZSBQYWlyPE1ldGhvZFN5bWJvbCwgQXR0cmlidXRlPiBhdHRyaWJ1dGVBbm5vdGF0aW9uTmFtZVZhbHVlUGFpcihKQ0V4cHJlc3Npb24gbmFtZVZhbHVlUGFpciwKICAgICAgICAgICAgVHlwZSB0aGlzQW5ub3RhdGlvblR5cGUsIGJvb2xlYW4gYmFkQW5ub3RhdGlvbiwgRW52PEF0dHJDb250ZXh0PiBlbnYsIGJvb2xlYW4gZWxpZGVkVmFsdWUpCiAgICB7CiAgICAgICAgaWYgKCFuYW1lVmFsdWVQYWlyLmhhc1RhZyhBU1NJR04pKSB7CiAgICAgICAgICAgIGxvZy5lcnJvcihuYW1lVmFsdWVQYWlyLnBvcygpLCAiYW5ub3RhdGlvbi52YWx1ZS5tdXN0LmJlLm5hbWUudmFsdWUiKTsKICAgICAgICAgICAgYXR0cmlidXRlQW5ub3RhdGlvblZhbHVlKG5hbWVWYWx1ZVBhaXIudHlwZSA9IHN5bXMuZXJyVHlwZSwgbmFtZVZhbHVlUGFpciwgZW52KTsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgICAgIEpDQXNzaWduIGFzc2lnbiA9IChKQ0Fzc2lnbiluYW1lVmFsdWVQYWlyOwogICAgICAgIGlmICghYXNzaWduLmxocy5oYXNUYWcoSURFTlQpKSB7CiAgICAgICAgICAgIGxvZy5lcnJvcihuYW1lVmFsdWVQYWlyLnBvcygpLCAiYW5ub3RhdGlvbi52YWx1ZS5tdXN0LmJlLm5hbWUudmFsdWUiKTsKICAgICAgICAgICAgYXR0cmlidXRlQW5ub3RhdGlvblZhbHVlKG5hbWVWYWx1ZVBhaXIudHlwZSA9IHN5bXMuZXJyVHlwZSwgbmFtZVZhbHVlUGFpciwgZW52KTsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICAvLyBSZXNvbHZlIGVsZW1lbnQgdG8gTWV0aG9kU3ltCiAgICAgICAgSkNJZGVudCBsZWZ0ID0gKEpDSWRlbnQpYXNzaWduLmxoczsKICAgICAgICBTeW1ib2wgbWV0aG9kID0gcmVzb2x2ZS5yZXNvbHZlUXVhbGlmaWVkTWV0aG9kKGVsaWRlZFZhbHVlID8gYXNzaWduLnJocy5wb3MoKSA6IGxlZnQucG9zKCksCiAgICAgICAgICAgICAgICBlbnYsIHRoaXNBbm5vdGF0aW9uVHlwZSwKICAgICAgICAgICAgICAgIGxlZnQubmFtZSwgTGlzdC5uaWwoKSwgbnVsbCk7CiAgICAgICAgbGVmdC5zeW0gPSBtZXRob2Q7CiAgICAgICAgbGVmdC50eXBlID0gbWV0aG9kLnR5cGU7CiAgICAgICAgaWYgKG1ldGhvZC5vd25lciAhPSB0aGlzQW5ub3RhdGlvblR5cGUudHN5bSAmJiAhYmFkQW5ub3RhdGlvbikKICAgICAgICAgICAgbG9nLmVycm9yKGxlZnQucG9zKCksICJuby5hbm5vdGF0aW9uLm1lbWJlciIsIGxlZnQubmFtZSwgdGhpc0Fubm90YXRpb25UeXBlKTsKICAgICAgICBUeXBlIHJlc3VsdFR5cGUgPSBtZXRob2QudHlwZS5nZXRSZXR1cm5UeXBlKCk7CgogICAgICAgIC8vIENvbXB1dGUgdmFsdWUgcGFydAogICAgICAgIEF0dHJpYnV0ZSB2YWx1ZSA9IGF0dHJpYnV0ZUFubm90YXRpb25WYWx1ZShyZXN1bHRUeXBlLCBhc3NpZ24ucmhzLCBlbnYpOwogICAgICAgIG5hbWVWYWx1ZVBhaXIudHlwZSA9IHJlc3VsdFR5cGU7CgogICAgICAgIHJldHVybiBtZXRob2QudHlwZS5pc0Vycm9uZW91cygpID8gbnVsbCA6IG5ldyBQYWlyPD4oKE1ldGhvZFN5bWJvbCltZXRob2QsIHZhbHVlKTsKCiAgICB9CgogICAgLyoqIEF0dHJpYnV0ZSBhbiBhbm5vdGF0aW9uIGVsZW1lbnQgdmFsdWUgKi8KICAgIHByaXZhdGUgQXR0cmlidXRlIGF0dHJpYnV0ZUFubm90YXRpb25WYWx1ZShUeXBlIGV4cGVjdGVkRWxlbWVudFR5cGUsIEpDRXhwcmVzc2lvbiB0cmVlLAogICAgICAgICAgICBFbnY8QXR0ckNvbnRleHQ+IGVudikKICAgIHsKICAgICAgICAvL2ZpcnN0LCB0cnkgY29tcGxldGluZyB0aGUgc3ltYm9sIGZvciB0aGUgYW5ub3RhdGlvbiB2YWx1ZSAtIGlmIGFjb21wbGV0aW9uCiAgICAgICAgLy9lcnJvciBpcyB0aHJvd24sIHdlIHNob3VsZCByZWNvdmVyIGdyYWNlZnVsbHksIGFuZCBkaXNwbGF5IGFuCiAgICAgICAgLy9vcmRpbmFyeSByZXNvbHV0aW9uIGRpYWdub3N0aWMuCiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgZXhwZWN0ZWRFbGVtZW50VHlwZS50c3ltLmNvbXBsZXRlKCk7CiAgICAgICAgfSBjYXRjaChDb21wbGV0aW9uRmFpbHVyZSBlKSB7CiAgICAgICAgICAgIGxvZy5lcnJvcih0cmVlLnBvcygpLCAiY2FudC5yZXNvbHZlIiwgS2luZHMua2luZE5hbWUoZS5zeW0pLCBlLnN5bSk7CiAgICAgICAgICAgIGV4cGVjdGVkRWxlbWVudFR5cGUgPSBzeW1zLmVyclR5cGU7CiAgICAgICAgfQoKICAgICAgICBpZiAoZXhwZWN0ZWRFbGVtZW50VHlwZS5oYXNUYWcoQVJSQVkpKSB7CiAgICAgICAgICAgIHJldHVybiBnZXRBbm5vdGF0aW9uQXJyYXlWYWx1ZShleHBlY3RlZEVsZW1lbnRUeXBlLCB0cmVlLCBlbnYpOwoKICAgICAgICB9CgogICAgICAgIC8vZXJyb3IgcmVjb3ZlcnkKICAgICAgICBpZiAodHJlZS5oYXNUYWcoTkVXQVJSQVkpKSB7CiAgICAgICAgICAgIGlmICghZXhwZWN0ZWRFbGVtZW50VHlwZS5pc0Vycm9uZW91cygpKQogICAgICAgICAgICAgICAgbG9nLmVycm9yKHRyZWUucG9zKCksICJhbm5vdGF0aW9uLnZhbHVlLm5vdC5hbGxvd2FibGUudHlwZSIpOwogICAgICAgICAgICBKQ05ld0FycmF5IG5hID0gKEpDTmV3QXJyYXkpdHJlZTsKICAgICAgICAgICAgaWYgKG5hLmVsZW10eXBlICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIGxvZy5lcnJvcihuYS5lbGVtdHlwZS5wb3MoKSwgIm5ldy5ub3QuYWxsb3dlZC5pbi5hbm5vdGF0aW9uIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZm9yIChMaXN0PEpDRXhwcmVzc2lvbj4gbCA9IG5hLmVsZW1zOyBsLm5vbkVtcHR5KCk7IGw9bC50YWlsKSB7CiAgICAgICAgICAgICAgICBhdHRyaWJ1dGVBbm5vdGF0aW9uVmFsdWUoc3ltcy5lcnJUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICBsLmhlYWQsCiAgICAgICAgICAgICAgICAgICAgICAgIGVudik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG5ldyBBdHRyaWJ1dGUuRXJyb3Ioc3ltcy5lcnJUeXBlKTsKICAgICAgICB9CgogICAgICAgIGlmIChleHBlY3RlZEVsZW1lbnRUeXBlLnRzeW0uaXNBbm5vdGF0aW9uVHlwZSgpKSB7CiAgICAgICAgICAgIGlmICh0cmVlLmhhc1RhZyhBTk5PVEFUSU9OKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGF0dHJpYnV0ZUFubm90YXRpb24oKEpDQW5ub3RhdGlvbil0cmVlLCBleHBlY3RlZEVsZW1lbnRUeXBlLCBlbnYpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgbG9nLmVycm9yKHRyZWUucG9zKCksICJhbm5vdGF0aW9uLnZhbHVlLm11c3QuYmUuYW5ub3RhdGlvbiIpOwogICAgICAgICAgICAgICAgZXhwZWN0ZWRFbGVtZW50VHlwZSA9IHN5bXMuZXJyVHlwZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy9lcnJvciByZWNvdmVyeQogICAgICAgIGlmICh0cmVlLmhhc1RhZyhBTk5PVEFUSU9OKSkgewogICAgICAgICAgICBpZiAoIWV4cGVjdGVkRWxlbWVudFR5cGUuaXNFcnJvbmVvdXMoKSkKICAgICAgICAgICAgICAgIGxvZy5lcnJvcih0cmVlLnBvcygpLCAiYW5ub3RhdGlvbi5ub3QudmFsaWQuZm9yLnR5cGUiLCBleHBlY3RlZEVsZW1lbnRUeXBlKTsKICAgICAgICAgICAgYXR0cmlidXRlQW5ub3RhdGlvbigoSkNBbm5vdGF0aW9uKXRyZWUsIHN5bXMuZXJyVHlwZSwgZW52KTsKICAgICAgICAgICAgcmV0dXJuIG5ldyBBdHRyaWJ1dGUuRXJyb3IoKChKQ0Fubm90YXRpb24pdHJlZSkuYW5ub3RhdGlvblR5cGUudHlwZSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoZXhwZWN0ZWRFbGVtZW50VHlwZS5pc1ByaW1pdGl2ZSgpIHx8CiAgICAgICAgICAgICAgICAodHlwZXMuaXNTYW1lVHlwZShleHBlY3RlZEVsZW1lbnRUeXBlLCBzeW1zLnN0cmluZ1R5cGUpICYmICFleHBlY3RlZEVsZW1lbnRUeXBlLmhhc1RhZyhUeXBlVGFnLkVSUk9SKSkpIHsKICAgICAgICAgICAgcmV0dXJuIGdldEFubm90YXRpb25QcmltaXRpdmVWYWx1ZShleHBlY3RlZEVsZW1lbnRUeXBlLCB0cmVlLCBlbnYpOwogICAgICAgIH0KCiAgICAgICAgaWYgKGV4cGVjdGVkRWxlbWVudFR5cGUudHN5bSA9PSBzeW1zLmNsYXNzVHlwZS50c3ltKSB7CiAgICAgICAgICAgIHJldHVybiBnZXRBbm5vdGF0aW9uQ2xhc3NWYWx1ZShleHBlY3RlZEVsZW1lbnRUeXBlLCB0cmVlLCBlbnYpOwogICAgICAgIH0KCiAgICAgICAgaWYgKGV4cGVjdGVkRWxlbWVudFR5cGUuaGFzVGFnKENMQVNTKSAmJgogICAgICAgICAgICAgICAgKGV4cGVjdGVkRWxlbWVudFR5cGUudHN5bS5mbGFncygpICYgRmxhZ3MuRU5VTSkgIT0gMCkgewogICAgICAgICAgICByZXR1cm4gZ2V0QW5ub3RhdGlvbkVudW1WYWx1ZShleHBlY3RlZEVsZW1lbnRUeXBlLCB0cmVlLCBlbnYpOwogICAgICAgIH0KCiAgICAgICAgLy9lcnJvciByZWNvdmVyeToKICAgICAgICBpZiAoIWV4cGVjdGVkRWxlbWVudFR5cGUuaXNFcnJvbmVvdXMoKSkKICAgICAgICAgICAgbG9nLmVycm9yKHRyZWUucG9zKCksICJhbm5vdGF0aW9uLnZhbHVlLm5vdC5hbGxvd2FibGUudHlwZSIpOwogICAgICAgIHJldHVybiBuZXcgQXR0cmlidXRlLkVycm9yKGF0dHIuYXR0cmliRXhwcih0cmVlLCBlbnYsIGV4cGVjdGVkRWxlbWVudFR5cGUpKTsKICAgIH0KCiAgICBwcml2YXRlIEF0dHJpYnV0ZSBnZXRBbm5vdGF0aW9uRW51bVZhbHVlKFR5cGUgZXhwZWN0ZWRFbGVtZW50VHlwZSwgSkNFeHByZXNzaW9uIHRyZWUsIEVudjxBdHRyQ29udGV4dD4gZW52KSB7CiAgICAgICAgVHlwZSByZXN1bHQgPSBhdHRyLmF0dHJpYkV4cHIodHJlZSwgZW52LCBleHBlY3RlZEVsZW1lbnRUeXBlKTsKICAgICAgICBTeW1ib2wgc3ltID0gVHJlZUluZm8uc3ltYm9sKHRyZWUpOwogICAgICAgIGlmIChzeW0gPT0gbnVsbCB8fAogICAgICAgICAgICAgICAgVHJlZUluZm8ubm9uc3RhdGljU2VsZWN0KHRyZWUpIHx8CiAgICAgICAgICAgICAgICBzeW0ua2luZCAhPSBWQVIgfHwKICAgICAgICAgICAgICAgIChzeW0uZmxhZ3MoKSAmIEZsYWdzLkVOVU0pID09IDApIHsKICAgICAgICAgICAgbG9nLmVycm9yKHRyZWUucG9zKCksICJlbnVtLmFubm90YXRpb24ubXVzdC5iZS5lbnVtLmNvbnN0YW50Iik7CiAgICAgICAgICAgIHJldHVybiBuZXcgQXR0cmlidXRlLkVycm9yKHJlc3VsdC5nZXRPcmlnaW5hbFR5cGUoKSk7CiAgICAgICAgfQogICAgICAgIFZhclN5bWJvbCBlbnVtZXJhdG9yID0gKFZhclN5bWJvbCkgc3ltOwogICAgICAgIHJldHVybiBuZXcgQXR0cmlidXRlLkVudW0oZXhwZWN0ZWRFbGVtZW50VHlwZSwgZW51bWVyYXRvcik7CiAgICB9CgogICAgcHJpdmF0ZSBBdHRyaWJ1dGUgZ2V0QW5ub3RhdGlvbkNsYXNzVmFsdWUoVHlwZSBleHBlY3RlZEVsZW1lbnRUeXBlLCBKQ0V4cHJlc3Npb24gdHJlZSwgRW52PEF0dHJDb250ZXh0PiBlbnYpIHsKICAgICAgICBUeXBlIHJlc3VsdCA9IGF0dHIuYXR0cmliRXhwcih0cmVlLCBlbnYsIGV4cGVjdGVkRWxlbWVudFR5cGUpOwogICAgICAgIGlmIChyZXN1bHQuaXNFcnJvbmVvdXMoKSkgewogICAgICAgICAgICAvLyBEb2VzIGl0IGxvb2sgbGlrZSBhbiB1bnJlc29sdmVkIGNsYXNzIGxpdGVyYWw/CiAgICAgICAgICAgIGlmIChUcmVlSW5mby5uYW1lKHRyZWUpID09IG5hbWVzLl9jbGFzcyAmJgogICAgICAgICAgICAgICAgICAgICgoSkNGaWVsZEFjY2VzcykgdHJlZSkuc2VsZWN0ZWQudHlwZS5pc0Vycm9uZW91cygpKSB7CiAgICAgICAgICAgICAgICBOYW1lIG4gPSAoKChKQ0ZpZWxkQWNjZXNzKSB0cmVlKS5zZWxlY3RlZCkudHlwZS50c3ltLmZsYXROYW1lKCk7CiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEF0dHJpYnV0ZS5VbnJlc29sdmVkQ2xhc3MoZXhwZWN0ZWRFbGVtZW50VHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgdHlwZXMuY3JlYXRlRXJyb3JUeXBlKG4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ltcy51bmtub3duU3ltYm9sLCBzeW1zLmNsYXNzVHlwZSkpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBBdHRyaWJ1dGUuRXJyb3IocmVzdWx0LmdldE9yaWdpbmFsVHlwZSgpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gQ2xhc3MgbGl0ZXJhbHMgbG9vayBsaWtlIGZpZWxkIGFjY2Vzc2VzIG9mIGEgZmllbGQgbmFtZWQgY2xhc3MKICAgICAgICAvLyBhdCB0aGUgdHJlZSBsZXZlbAogICAgICAgIGlmIChUcmVlSW5mby5uYW1lKHRyZWUpICE9IG5hbWVzLl9jbGFzcykgewogICAgICAgICAgICBsb2cuZXJyb3IodHJlZS5wb3MoKSwgImFubm90YXRpb24udmFsdWUubXVzdC5iZS5jbGFzcy5saXRlcmFsIik7CiAgICAgICAgICAgIHJldHVybiBuZXcgQXR0cmlidXRlLkVycm9yKHN5bXMuZXJyVHlwZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBuZXcgQXR0cmlidXRlLkNsYXNzKHR5cGVzLAogICAgICAgICAgICAgICAgKCgoSkNGaWVsZEFjY2VzcykgdHJlZSkuc2VsZWN0ZWQpLnR5cGUpOwogICAgfQoKICAgIHByaXZhdGUgQXR0cmlidXRlIGdldEFubm90YXRpb25QcmltaXRpdmVWYWx1ZShUeXBlIGV4cGVjdGVkRWxlbWVudFR5cGUsIEpDRXhwcmVzc2lvbiB0cmVlLCBFbnY8QXR0ckNvbnRleHQ+IGVudikgewogICAgICAgIFR5cGUgcmVzdWx0ID0gYXR0ci5hdHRyaWJFeHByKHRyZWUsIGVudiwgZXhwZWN0ZWRFbGVtZW50VHlwZSk7CiAgICAgICAgaWYgKHJlc3VsdC5pc0Vycm9uZW91cygpKQogICAgICAgICAgICByZXR1cm4gbmV3IEF0dHJpYnV0ZS5FcnJvcihyZXN1bHQuZ2V0T3JpZ2luYWxUeXBlKCkpOwogICAgICAgIGlmIChyZXN1bHQuY29uc3RWYWx1ZSgpID09IG51bGwpIHsKICAgICAgICAgICAgbG9nLmVycm9yKHRyZWUucG9zKCksICJhdHRyaWJ1dGUudmFsdWUubXVzdC5iZS5jb25zdGFudCIpOwogICAgICAgICAgICByZXR1cm4gbmV3IEF0dHJpYnV0ZS5FcnJvcihleHBlY3RlZEVsZW1lbnRUeXBlKTsKICAgICAgICB9CiAgICAgICAgcmVzdWx0ID0gY2ZvbGRlci5jb2VyY2UocmVzdWx0LCBleHBlY3RlZEVsZW1lbnRUeXBlKTsKICAgICAgICByZXR1cm4gbmV3IEF0dHJpYnV0ZS5Db25zdGFudChleHBlY3RlZEVsZW1lbnRUeXBlLCByZXN1bHQuY29uc3RWYWx1ZSgpKTsKICAgIH0KCiAgICBwcml2YXRlIEF0dHJpYnV0ZSBnZXRBbm5vdGF0aW9uQXJyYXlWYWx1ZShUeXBlIGV4cGVjdGVkRWxlbWVudFR5cGUsIEpDRXhwcmVzc2lvbiB0cmVlLCBFbnY8QXR0ckNvbnRleHQ+IGVudikgewogICAgICAgIC8vIFNwZWNpYWwgY2FzZSwgaW1wbGljaXQgYXJyYXkKICAgICAgICBpZiAoIXRyZWUuaGFzVGFnKE5FV0FSUkFZKSkgewogICAgICAgICAgICB0cmVlID0gbWFrZS5hdCh0cmVlLnBvcykuCiAgICAgICAgICAgICAgICAgICAgTmV3QXJyYXkobnVsbCwgTGlzdC5uaWwoKSwgTGlzdC5vZih0cmVlKSk7CiAgICAgICAgfQoKICAgICAgICBKQ05ld0FycmF5IG5hID0gKEpDTmV3QXJyYXkpdHJlZTsKICAgICAgICBpZiAobmEuZWxlbXR5cGUgIT0gbnVsbCkgewogICAgICAgICAgICBsb2cuZXJyb3IobmEuZWxlbXR5cGUucG9zKCksICJuZXcubm90LmFsbG93ZWQuaW4uYW5ub3RhdGlvbiIpOwogICAgICAgIH0KICAgICAgICBMaXN0QnVmZmVyPEF0dHJpYnV0ZT4gYnVmID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgIGZvciAoTGlzdDxKQ0V4cHJlc3Npb24+IGwgPSBuYS5lbGVtczsgbC5ub25FbXB0eSgpOyBsPWwudGFpbCkgewogICAgICAgICAgICBidWYuYXBwZW5kKGF0dHJpYnV0ZUFubm90YXRpb25WYWx1ZSh0eXBlcy5lbGVtdHlwZShleHBlY3RlZEVsZW1lbnRUeXBlKSwKICAgICAgICAgICAgICAgICAgICBsLmhlYWQsCiAgICAgICAgICAgICAgICAgICAgZW52KSk7CiAgICAgICAgfQogICAgICAgIG5hLnR5cGUgPSBleHBlY3RlZEVsZW1lbnRUeXBlOwogICAgICAgIHJldHVybiBuZXcgQXR0cmlidXRlLgogICAgICAgICAgICAgICAgQXJyYXkoZXhwZWN0ZWRFbGVtZW50VHlwZSwgYnVmLnRvQXJyYXkobmV3IEF0dHJpYnV0ZVtidWYubGVuZ3RoKCldKSk7CiAgICB9CgogICAgLyogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAgICAgKiBTdXBwb3J0IGZvciByZXBlYXRpbmcgYW5ub3RhdGlvbnMKICAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiAgICAvKioKICAgICAqIFRoaXMgY29udGV4dCBjb250YWlucyBhbGwgdGhlIGluZm9ybWF0aW9uIG5lZWRlZCB0byBzeW50aGVzaXplIG5ldwogICAgICogYW5ub3RhdGlvbnMgdHJlZXMgZm9yIHJlcGVhdGluZyBhbm5vdGF0aW9ucy4KICAgICAqLwogICAgcHJpdmF0ZSBjbGFzcyBBbm5vdGF0aW9uQ29udGV4dDxUIGV4dGVuZHMgQXR0cmlidXRlLkNvbXBvdW5kPiB7CiAgICAgICAgcHVibGljIGZpbmFsIEVudjxBdHRyQ29udGV4dD4gZW52OwogICAgICAgIHB1YmxpYyBmaW5hbCBNYXA8U3ltYm9sLlR5cGVTeW1ib2wsIExpc3RCdWZmZXI8VD4+IGFubm90YXRlZDsKICAgICAgICBwdWJsaWMgZmluYWwgTWFwPFQsIEpDRGlhZ25vc3RpYy5EaWFnbm9zdGljUG9zaXRpb24+IHBvczsKICAgICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc1R5cGVDb21wb3VuZDsKCiAgICAgICAgcHVibGljIEFubm90YXRpb25Db250ZXh0KEVudjxBdHRyQ29udGV4dD4gZW52LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYXA8U3ltYm9sLlR5cGVTeW1ib2wsIExpc3RCdWZmZXI8VD4+IGFubm90YXRlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWFwPFQsIEpDRGlhZ25vc3RpYy5EaWFnbm9zdGljUG9zaXRpb24+IHBvcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBpc1R5cGVDb21wb3VuZCkgewogICAgICAgICAgICBBc3NlcnQuY2hlY2tOb25OdWxsKGVudik7CiAgICAgICAgICAgIEFzc2VydC5jaGVja05vbk51bGwoYW5ub3RhdGVkKTsKICAgICAgICAgICAgQXNzZXJ0LmNoZWNrTm9uTnVsbChwb3MpOwoKICAgICAgICAgICAgdGhpcy5lbnYgPSBlbnY7CiAgICAgICAgICAgIHRoaXMuYW5ub3RhdGVkID0gYW5ub3RhdGVkOwogICAgICAgICAgICB0aGlzLnBvcyA9IHBvczsKICAgICAgICAgICAgdGhpcy5pc1R5cGVDb21wb3VuZCA9IGlzVHlwZUNvbXBvdW5kOwogICAgICAgIH0KICAgIH0KCiAgICAvKiBQcm9jZXNzIHJlcGVhdGVkIGFubm90YXRpb25zLiBUaGlzIG1ldGhvZCByZXR1cm5zIHRoZQogICAgICogc3ludGhlc2l6ZWQgY29udGFpbmVyIGFubm90YXRpb24gb3IgbnVsbCBJRkYgYWxsIHJlcGVhdGluZwogICAgICogYW5ub3RhdGlvbiBhcmUgaW52YWxpZC4gIFRoaXMgbWV0aG9kIHJlcG9ydHMgZXJyb3JzL3dhcm5pbmdzLgogICAgICovCiAgICBwcml2YXRlIDxUIGV4dGVuZHMgQXR0cmlidXRlLkNvbXBvdW5kPiBUIHByb2Nlc3NSZXBlYXRlZEFubm90YXRpb25zKExpc3Q8VD4gYW5ub3RhdGlvbnMsCiAgICAgICAgICAgIEFubm90YXRpb25Db250ZXh0PFQ+IGN0eCwgU3ltYm9sIG9uLCBib29sZWFuIGlzVHlwZVBhcmFtKQogICAgewogICAgICAgIFQgZmlyc3RPY2N1cnJlbmNlID0gYW5ub3RhdGlvbnMuaGVhZDsKICAgICAgICBMaXN0PEF0dHJpYnV0ZT4gcmVwZWF0ZWQgPSBMaXN0Lm5pbCgpOwogICAgICAgIFR5cGUgb3JpZ0Fubm9UeXBlID0gbnVsbDsKICAgICAgICBUeXBlIGFycmF5T2ZPcmlnQW5ub1R5cGUgPSBudWxsOwogICAgICAgIFR5cGUgdGFyZ2V0Q29udGFpbmVyVHlwZSA9IG51bGw7CiAgICAgICAgTWV0aG9kU3ltYm9sIGNvbnRhaW5lclZhbHVlU3ltYm9sID0gbnVsbDsKCiAgICAgICAgQXNzZXJ0LmNoZWNrKCFhbm5vdGF0aW9ucy5pc0VtcHR5KCkgJiYgIWFubm90YXRpb25zLnRhaWwuaXNFbXB0eSgpKTsgLy8gaS5lLiBzaXplKCkgPiAxCgogICAgICAgIGludCBjb3VudCA9IDA7CiAgICAgICAgZm9yIChMaXN0PFQ+IGFsID0gYW5ub3RhdGlvbnM7ICFhbC5pc0VtcHR5KCk7IGFsID0gYWwudGFpbCkgewogICAgICAgICAgICBjb3VudCsrOwoKICAgICAgICAgICAgLy8gVGhlcmUgbXVzdCBiZSBtb3JlIHRoYW4gYSBzaW5nbGUgYW5ubyBpbiB0aGUgYW5ub3RhdGlvbiBsaXN0CiAgICAgICAgICAgIEFzc2VydC5jaGVjayhjb3VudCA+IDEgfHwgIWFsLnRhaWwuaXNFbXB0eSgpKTsKCiAgICAgICAgICAgIFQgY3VycmVudEFubm8gPSBhbC5oZWFkOwoKICAgICAgICAgICAgb3JpZ0Fubm9UeXBlID0gY3VycmVudEFubm8udHlwZTsKICAgICAgICAgICAgaWYgKGFycmF5T2ZPcmlnQW5ub1R5cGUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgYXJyYXlPZk9yaWdBbm5vVHlwZSA9IHR5cGVzLm1ha2VBcnJheVR5cGUob3JpZ0Fubm9UeXBlKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gT25seSByZXBvcnQgZXJyb3JzIGlmIHRoaXMgaXNuJ3QgdGhlIGZpcnN0IG9jY3VycmVuY2UgSS5FLiBjb3VudCA+IDEKICAgICAgICAgICAgYm9vbGVhbiByZXBvcnRFcnJvciA9IGNvdW50ID4gMTsKICAgICAgICAgICAgVHlwZSBjdXJyZW50Q29udGFpbmVyVHlwZSA9IGdldENvbnRhaW5pbmdUeXBlKGN1cnJlbnRBbm5vLCBjdHgucG9zLmdldChjdXJyZW50QW5ubyksIHJlcG9ydEVycm9yKTsKICAgICAgICAgICAgaWYgKGN1cnJlbnRDb250YWluZXJUeXBlID09IG51bGwpIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIEFzc2VydCB0aGF0IHRoZSB0YXJnZXQgQ29udGFpbmVyIGlzID09IGZvciBhbGwgcmVwZWF0ZWQKICAgICAgICAgICAgLy8gYW5ub3Mgb2YgdGhlIHNhbWUgYW5ub3RhdGlvbiB0eXBlLCB0aGUgdHlwZXMgc2hvdWxkCiAgICAgICAgICAgIC8vIGNvbWUgZnJvbSB0aGUgc2FtZSBTeW1ib2wsIGkuZS4gYmUgJz09JwogICAgICAgICAgICBBc3NlcnQuY2hlY2sodGFyZ2V0Q29udGFpbmVyVHlwZSA9PSBudWxsIHx8IGN1cnJlbnRDb250YWluZXJUeXBlID09IHRhcmdldENvbnRhaW5lclR5cGUpOwogICAgICAgICAgICB0YXJnZXRDb250YWluZXJUeXBlID0gY3VycmVudENvbnRhaW5lclR5cGU7CgogICAgICAgICAgICBjb250YWluZXJWYWx1ZVN5bWJvbCA9IHZhbGlkYXRlQ29udGFpbmVyKHRhcmdldENvbnRhaW5lclR5cGUsIG9yaWdBbm5vVHlwZSwgY3R4LnBvcy5nZXQoY3VycmVudEFubm8pKTsKCiAgICAgICAgICAgIGlmIChjb250YWluZXJWYWx1ZVN5bWJvbCA9PSBudWxsKSB7IC8vIENoZWNrIG9mIENBIHR5cGUgZmFpbGVkCiAgICAgICAgICAgICAgICAvLyBlcnJvcnMgYXJlIGFscmVhZHkgcmVwb3J0ZWQKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXBlYXRlZCA9IHJlcGVhdGVkLnByZXBlbmQoY3VycmVudEFubm8pOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFyZXBlYXRlZC5pc0VtcHR5KCkgJiYgdGFyZ2V0Q29udGFpbmVyVHlwZSA9PSBudWxsKSB7CiAgICAgICAgICAgIGxvZy5lcnJvcihjdHgucG9zLmdldChhbm5vdGF0aW9ucy5oZWFkKSwgImR1cGxpY2F0ZS5hbm5vdGF0aW9uLmludmFsaWQucmVwZWF0ZWQiLCBvcmlnQW5ub1R5cGUpOwogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgIGlmICghcmVwZWF0ZWQuaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkID0gcmVwZWF0ZWQucmV2ZXJzZSgpOwogICAgICAgICAgICBEaWFnbm9zdGljUG9zaXRpb24gcG9zID0gY3R4LnBvcy5nZXQoZmlyc3RPY2N1cnJlbmNlKTsKICAgICAgICAgICAgVHJlZU1ha2VyIG0gPSBtYWtlLmF0KHBvcyk7CiAgICAgICAgICAgIFBhaXI8TWV0aG9kU3ltYm9sLCBBdHRyaWJ1dGU+IHAgPQogICAgICAgICAgICAgICAgICAgIG5ldyBQYWlyPE1ldGhvZFN5bWJvbCwgQXR0cmlidXRlPihjb250YWluZXJWYWx1ZVN5bWJvbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBBdHRyaWJ1dGUuQXJyYXkoYXJyYXlPZk9yaWdBbm5vVHlwZSwgcmVwZWF0ZWQpKTsKICAgICAgICAgICAgaWYgKGN0eC5pc1R5cGVDb21wb3VuZCkgewogICAgICAgICAgICAgICAgLyogVE9ETzogdGhlIGZvbGxvd2luZyBjb2RlIHdvdWxkIGJlIGNsZWFuZXI6CiAgICAgICAgICAgICAgICBBdHRyaWJ1dGUuVHlwZUNvbXBvdW5kIGF0ID0gbmV3IEF0dHJpYnV0ZS5UeXBlQ29tcG91bmQodGFyZ2V0Q29udGFpbmVyVHlwZSwgTGlzdC5vZihwKSwKICAgICAgICAgICAgICAgICAgICAgICAgKChBdHRyaWJ1dGUuVHlwZUNvbXBvdW5kKWFubm90YXRpb25zLmhlYWQpLnBvc2l0aW9uKTsKICAgICAgICAgICAgICAgIEpDVHlwZUFubm90YXRpb24gYW5ub1RyZWUgPSBtLlR5cGVBbm5vdGF0aW9uKGF0KTsKICAgICAgICAgICAgICAgIGF0ID0gYXR0cmlidXRlVHlwZUFubm90YXRpb24oYW5ub1RyZWUsIHRhcmdldENvbnRhaW5lclR5cGUsIGN0eC5lbnYpOwogICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIC8vIEhvd2V2ZXIsIHdlIGRpcmVjdGx5IGNvbnN0cnVjdCB0aGUgVHlwZUNvbXBvdW5kIHRvIGtlZXAgdGhlCiAgICAgICAgICAgICAgICAvLyBkaXJlY3QgcmVsYXRpb24gdG8gdGhlIGNvbnRhaW5lZCBUeXBlQ29tcG91bmRzLgogICAgICAgICAgICAgICAgQXR0cmlidXRlLlR5cGVDb21wb3VuZCBhdCA9IG5ldyBBdHRyaWJ1dGUuVHlwZUNvbXBvdW5kKHRhcmdldENvbnRhaW5lclR5cGUsIExpc3Qub2YocCksCiAgICAgICAgICAgICAgICAgICAgICAgICgoQXR0cmlidXRlLlR5cGVDb21wb3VuZClhbm5vdGF0aW9ucy5oZWFkKS5wb3NpdGlvbik7CgogICAgICAgICAgICAgICAgSkNBbm5vdGF0aW9uIGFubm9UcmVlID0gbS5UeXBlQW5ub3RhdGlvbihhdCk7CiAgICAgICAgICAgICAgICBpZiAoIWNoay52YWxpZGF0ZUFubm90YXRpb25EZWZlckVycm9ycyhhbm5vVHJlZSkpCiAgICAgICAgICAgICAgICAgICAgbG9nLmVycm9yKGFubm9UcmVlLnBvcygpLCBFcnJvcnMuRHVwbGljYXRlQW5ub3RhdGlvbkludmFsaWRSZXBlYXRlZChvcmlnQW5ub1R5cGUpKTsKCiAgICAgICAgICAgICAgICBpZiAoIWNoay5pc1R5cGVBbm5vdGF0aW9uKGFubm9UcmVlLCBpc1R5cGVQYXJhbSkpIHsKICAgICAgICAgICAgICAgICAgICBsb2cuZXJyb3IocG9zLCBpc1R5cGVQYXJhbSA/IEVycm9ycy5JbnZhbGlkUmVwZWF0YWJsZUFubm90YXRpb25Ob3RBcHBsaWNhYmxlKHRhcmdldENvbnRhaW5lclR5cGUsIG9uKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogRXJyb3JzLkludmFsaWRSZXBlYXRhYmxlQW5ub3RhdGlvbk5vdEFwcGxpY2FibGVJbkNvbnRleHQodGFyZ2V0Q29udGFpbmVyVHlwZSkpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGF0LnNldFN5bnRoZXNpemVkKHRydWUpOwoKICAgICAgICAgICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQogICAgICAgICAgICAgICAgVCB4ID0gKFQpIGF0OwogICAgICAgICAgICAgICAgcmV0dXJuIHg7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBBdHRyaWJ1dGUuQ29tcG91bmQgYyA9IG5ldyBBdHRyaWJ1dGUuQ29tcG91bmQodGFyZ2V0Q29udGFpbmVyVHlwZSwgTGlzdC5vZihwKSk7CiAgICAgICAgICAgICAgICBKQ0Fubm90YXRpb24gYW5ub1RyZWUgPSBtLkFubm90YXRpb24oYyk7CgogICAgICAgICAgICAgICAgaWYgKCFjaGsuYW5ub3RhdGlvbkFwcGxpY2FibGUoYW5ub1RyZWUsIG9uKSkgewogICAgICAgICAgICAgICAgICAgIGxvZy5lcnJvcihhbm5vVHJlZS5wb3MoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRXJyb3JzLkludmFsaWRSZXBlYXRhYmxlQW5ub3RhdGlvbk5vdEFwcGxpY2FibGUodGFyZ2V0Q29udGFpbmVyVHlwZSwgb24pKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoIWNoay52YWxpZGF0ZUFubm90YXRpb25EZWZlckVycm9ycyhhbm5vVHJlZSkpCiAgICAgICAgICAgICAgICAgICAgbG9nLmVycm9yKGFubm9UcmVlLnBvcygpLCAiZHVwbGljYXRlLmFubm90YXRpb24uaW52YWxpZC5yZXBlYXRlZCIsIG9yaWdBbm5vVHlwZSk7CgogICAgICAgICAgICAgICAgYyA9IGF0dHJpYnV0ZUFubm90YXRpb24oYW5ub1RyZWUsIHRhcmdldENvbnRhaW5lclR5cGUsIGN0eC5lbnYpOwogICAgICAgICAgICAgICAgYy5zZXRTeW50aGVzaXplZCh0cnVlKTsKCiAgICAgICAgICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKICAgICAgICAgICAgICAgIFQgeCA9IChUKSBjOwogICAgICAgICAgICAgICAgcmV0dXJuIHg7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gbnVsbDsgLy8gZXJyb3JzIHNob3VsZCBoYXZlIGJlZW4gcmVwb3J0ZWQgZWxzZXdoZXJlCiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogRmV0Y2hlcyB0aGUgYWN0dWFsIFR5cGUgdGhhdCBzaG91bGQgYmUgdGhlIGNvbnRhaW5pbmcgYW5ub3RhdGlvbi4KICAgICAqLwogICAgcHJpdmF0ZSBUeXBlIGdldENvbnRhaW5pbmdUeXBlKEF0dHJpYnV0ZS5Db21wb3VuZCBjdXJyZW50QW5ubywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEaWFnbm9zdGljUG9zaXRpb24gcG9zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gcmVwb3J0RXJyb3IpCiAgICB7CiAgICAgICAgVHlwZSBvcmlnQW5ub1R5cGUgPSBjdXJyZW50QW5uby50eXBlOwogICAgICAgIFR5cGVTeW1ib2wgb3JpZ0Fubm9EZWNsID0gb3JpZ0Fubm9UeXBlLnRzeW07CgogICAgICAgIC8vIEZldGNoIHRoZSBSZXBlYXRhYmxlIGFubm90YXRpb24gZnJvbSB0aGUgY3VycmVudAogICAgICAgIC8vIGFubm90YXRpb24ncyBkZWNsYXJhdGlvbiwgb3IgbnVsbCBpZiBpdCBoYXMgbm9uZQogICAgICAgIEF0dHJpYnV0ZS5Db21wb3VuZCBjYSA9IG9yaWdBbm5vRGVjbC5nZXRBbm5vdGF0aW9uVHlwZU1ldGFkYXRhKCkuZ2V0UmVwZWF0YWJsZSgpOwogICAgICAgIGlmIChjYSA9PSBudWxsKSB7IC8vIGhhcyBubyBSZXBlYXRhYmxlIGFubm90YXRpb24KICAgICAgICAgICAgaWYgKHJlcG9ydEVycm9yKQogICAgICAgICAgICAgICAgbG9nLmVycm9yKHBvcywgImR1cGxpY2F0ZS5hbm5vdGF0aW9uLm1pc3NpbmcuY29udGFpbmVyIiwgb3JpZ0Fubm9UeXBlLCBzeW1zLnJlcGVhdGFibGVUeXBlKTsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gZmlsdGVyU2FtZShleHRyYWN0Q29udGFpbmluZ1R5cGUoY2EsIHBvcywgb3JpZ0Fubm9EZWNsKSwKICAgICAgICAgICAgICAgIG9yaWdBbm5vVHlwZSk7CiAgICB9CgogICAgLy8gcmV0dXJucyBudWxsIGlmIHQgaXMgc2FtZSBhcyAncycsIHJldHVybnMgJ3QnIG90aGVyd2lzZQogICAgcHJpdmF0ZSBUeXBlIGZpbHRlclNhbWUoVHlwZSB0LCBUeXBlIHMpIHsKICAgICAgICBpZiAodCA9PSBudWxsIHx8IHMgPT0gbnVsbCkgewogICAgICAgICAgICByZXR1cm4gdDsKICAgICAgICB9CgogICAgICAgIHJldHVybiB0eXBlcy5pc1NhbWVUeXBlKHQsIHMpID8gbnVsbCA6IHQ7CiAgICB9CgogICAgLyoqIEV4dHJhY3QgdGhlIGFjdHVhbCBUeXBlIHRvIGJlIHVzZWQgZm9yIGEgY29udGFpbmluZyBhbm5vdGF0aW9uLiAqLwogICAgcHJpdmF0ZSBUeXBlIGV4dHJhY3RDb250YWluaW5nVHlwZShBdHRyaWJ1dGUuQ29tcG91bmQgY2EsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERpYWdub3N0aWNQb3NpdGlvbiBwb3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFR5cGVTeW1ib2wgYW5ub0RlY2wpCiAgICB7CiAgICAgICAgLy8gVGhlIG5leHQgdGhyZWUgY2hlY2tzIGNoZWNrIHRoYXQgdGhlIFJlcGVhdGFibGUgYW5ub3RhdGlvbgogICAgICAgIC8vIG9uIHRoZSBkZWNsYXJhdGlvbiBvZiB0aGUgYW5ub3RhdGlvbiB0eXBlIHRoYXQgaXMgcmVwZWF0aW5nIGlzCiAgICAgICAgLy8gdmFsaWQuCgogICAgICAgIC8vIFJlcGVhdGFibGUgbXVzdCBoYXZlIGF0IGxlYXN0IG9uZSBlbGVtZW50CiAgICAgICAgaWYgKGNhLnZhbHVlcy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgbG9nLmVycm9yKHBvcywgImludmFsaWQucmVwZWF0YWJsZS5hbm5vdGF0aW9uIiwgYW5ub0RlY2wpOwogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICAgICAgUGFpcjxNZXRob2RTeW1ib2wsQXR0cmlidXRlPiBwID0gY2EudmFsdWVzLmhlYWQ7CiAgICAgICAgTmFtZSBuYW1lID0gcC5mc3QubmFtZTsKICAgICAgICBpZiAobmFtZSAhPSBuYW1lcy52YWx1ZSkgeyAvLyBzaG91bGQgY29udGFpbiBvbmx5IG9uZSBlbGVtZW50LCBuYW1lZCAidmFsdWUiCiAgICAgICAgICAgIGxvZy5lcnJvcihwb3MsICJpbnZhbGlkLnJlcGVhdGFibGUuYW5ub3RhdGlvbiIsIGFubm9EZWNsKTsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgICAgIGlmICghKHAuc25kIGluc3RhbmNlb2YgQXR0cmlidXRlLkNsYXNzKSkgeyAvLyBjaGVjayB0aGF0IHRoZSB2YWx1ZSBvZiAidmFsdWUiIGlzIGFuIEF0dHJpYnV0ZS5DbGFzcwogICAgICAgICAgICBsb2cuZXJyb3IocG9zLCAiaW52YWxpZC5yZXBlYXRhYmxlLmFubm90YXRpb24iLCBhbm5vRGVjbCk7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICgoQXR0cmlidXRlLkNsYXNzKXAuc25kKS5nZXRWYWx1ZSgpOwogICAgfQoKICAgIC8qIFZhbGlkYXRlIHRoYXQgdGhlIHN1Z2dlc3RlZCB0YXJnZXRDb250YWluZXJUeXBlIFR5cGUgaXMgYSB2YWxpZAogICAgICogY29udGFpbmVyIHR5cGUgZm9yIHJlcGVhdGVkIGluc3RhbmNlcyBvZiBvcmlnaW5hbEFubm9UeXBlCiAgICAgKiBhbm5vdGF0aW9ucy4gUmV0dXJuIG51bGwgYW5kIHJlcG9ydCBlcnJvcnMgaWYgdGhpcyBpcyBub3QgdGhlCiAgICAgKiBjYXNlLCByZXR1cm4gdGhlIE1ldGhvZFN5bWJvbCBvZiB0aGUgdmFsdWUgZWxlbWVudCBpbgogICAgICogdGFyZ2V0Q29udGFpbmVyVHlwZSBpZiBpdCBpcyBzdWl0YWJsZSAodGhpcyBpcyBuZWVkZWQgdG8KICAgICAqIHN5bnRoZXNpemUgdGhlIGNvbnRhaW5lcikuICovCiAgICBwcml2YXRlIE1ldGhvZFN5bWJvbCB2YWxpZGF0ZUNvbnRhaW5lcihUeXBlIHRhcmdldENvbnRhaW5lclR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUeXBlIG9yaWdpbmFsQW5ub1R5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEaWFnbm9zdGljUG9zaXRpb24gcG9zKSB7CiAgICAgICAgTWV0aG9kU3ltYm9sIGNvbnRhaW5lclZhbHVlU3ltYm9sID0gbnVsbDsKICAgICAgICBib29sZWFuIGZhdGFsRXJyb3IgPSBmYWxzZTsKCiAgICAgICAgLy8gVmFsaWRhdGUgdGhhdCB0aGVyZSBpcyBhIChhbmQgb25seSAxKSB2YWx1ZSBtZXRob2QKICAgICAgICBTY29wZSBzY29wZSA9IHRhcmdldENvbnRhaW5lclR5cGUudHN5bS5tZW1iZXJzKCk7CiAgICAgICAgaW50IG5yX3ZhbHVlX2VsZW1zID0gMDsKICAgICAgICBib29sZWFuIGVycm9yID0gZmFsc2U7CiAgICAgICAgZm9yKFN5bWJvbCBlbG0gOiBzY29wZS5nZXRTeW1ib2xzQnlOYW1lKG5hbWVzLnZhbHVlKSkgewogICAgICAgICAgICBucl92YWx1ZV9lbGVtcysrOwoKICAgICAgICAgICAgaWYgKG5yX3ZhbHVlX2VsZW1zID09IDEgJiYKICAgICAgICAgICAgICAgICAgICBlbG0ua2luZCA9PSBNVEgpIHsKICAgICAgICAgICAgICAgIGNvbnRhaW5lclZhbHVlU3ltYm9sID0gKE1ldGhvZFN5bWJvbCllbG07CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBlcnJvciA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKGVycm9yKSB7CiAgICAgICAgICAgIGxvZy5lcnJvcihwb3MsCiAgICAgICAgICAgICAgICAgICAgImludmFsaWQucmVwZWF0YWJsZS5hbm5vdGF0aW9uLm11bHRpcGxlLnZhbHVlcyIsCiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0Q29udGFpbmVyVHlwZSwKICAgICAgICAgICAgICAgICAgICBucl92YWx1ZV9lbGVtcyk7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0gZWxzZSBpZiAobnJfdmFsdWVfZWxlbXMgPT0gMCkgewogICAgICAgICAgICBsb2cuZXJyb3IocG9zLAogICAgICAgICAgICAgICAgICAgICJpbnZhbGlkLnJlcGVhdGFibGUuYW5ub3RhdGlvbi5uby52YWx1ZSIsCiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0Q29udGFpbmVyVHlwZSk7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgLy8gdmFsaWRhdGUgdGhhdCB0aGUgJ3ZhbHVlJyBlbGVtZW50IGlzIGEgbWV0aG9kCiAgICAgICAgLy8gcHJvYmFibHkgImltcG9zc2libGUiIHRvIGZhaWwgdGhpcwogICAgICAgIGlmIChjb250YWluZXJWYWx1ZVN5bWJvbC5raW5kICE9IE1USCkgewogICAgICAgICAgICBsb2cuZXJyb3IocG9zLAogICAgICAgICAgICAgICAgICAgICJpbnZhbGlkLnJlcGVhdGFibGUuYW5ub3RhdGlvbi5pbnZhbGlkLnZhbHVlIiwKICAgICAgICAgICAgICAgICAgICB0YXJnZXRDb250YWluZXJUeXBlKTsKICAgICAgICAgICAgZmF0YWxFcnJvciA9IHRydWU7CiAgICAgICAgfQoKICAgICAgICAvLyB2YWxpZGF0ZSB0aGF0IHRoZSAndmFsdWUnIGVsZW1lbnQgaGFzIHRoZSBjb3JyZWN0IHJldHVybiB0eXBlCiAgICAgICAgLy8gaS5lLiBhcnJheSBvZiBvcmlnaW5hbCBhbm5vCiAgICAgICAgVHlwZSB2YWx1ZVJldFR5cGUgPSBjb250YWluZXJWYWx1ZVN5bWJvbC50eXBlLmdldFJldHVyblR5cGUoKTsKICAgICAgICBUeXBlIGV4cGVjdGVkVHlwZSA9IHR5cGVzLm1ha2VBcnJheVR5cGUob3JpZ2luYWxBbm5vVHlwZSk7CiAgICAgICAgaWYgKCEodHlwZXMuaXNBcnJheSh2YWx1ZVJldFR5cGUpICYmCiAgICAgICAgICAgICAgICB0eXBlcy5pc1NhbWVUeXBlKGV4cGVjdGVkVHlwZSwgdmFsdWVSZXRUeXBlKSkpIHsKICAgICAgICAgICAgbG9nLmVycm9yKHBvcywKICAgICAgICAgICAgICAgICAgICAiaW52YWxpZC5yZXBlYXRhYmxlLmFubm90YXRpb24udmFsdWUucmV0dXJuIiwKICAgICAgICAgICAgICAgICAgICB0YXJnZXRDb250YWluZXJUeXBlLAogICAgICAgICAgICAgICAgICAgIHZhbHVlUmV0VHlwZSwKICAgICAgICAgICAgICAgICAgICBleHBlY3RlZFR5cGUpOwogICAgICAgICAgICBmYXRhbEVycm9yID0gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBmYXRhbEVycm9yID8gbnVsbCA6IGNvbnRhaW5lclZhbHVlU3ltYm9sOwogICAgfQoKICAgIHByaXZhdGUgPFQgZXh0ZW5kcyBBdHRyaWJ1dGUuQ29tcG91bmQ+IFQgbWFrZUNvbnRhaW5lckFubm90YXRpb24oTGlzdDxUPiB0b0JlUmVwbGFjZWQsCiAgICAgICAgICAgIEFubm90YXRpb25Db250ZXh0PFQ+IGN0eCwgU3ltYm9sIHN5bSwgYm9vbGVhbiBpc1R5cGVQYXJhbSkKICAgIHsKICAgICAgICAvLyBQcm9jZXNzIHJlcGVhdGVkIGFubm90YXRpb25zCiAgICAgICAgVCB2YWxpZFJlcGVhdGVkID0KICAgICAgICAgICAgICAgIHByb2Nlc3NSZXBlYXRlZEFubm90YXRpb25zKHRvQmVSZXBsYWNlZCwgY3R4LCBzeW0sIGlzVHlwZVBhcmFtKTsKCiAgICAgICAgaWYgKHZhbGlkUmVwZWF0ZWQgIT0gbnVsbCkgewogICAgICAgICAgICAvLyBDaGVjayB0aGF0IHRoZSBjb250YWluZXIgaXNuJ3QgbWFudWFsbHkKICAgICAgICAgICAgLy8gcHJlc2VudCBhbG9uZyB3aXRoIHJlcGVhdGVkIGluc3RhbmNlcyBvZgogICAgICAgICAgICAvLyBpdHMgY29udGFpbmVkIGFubm90YXRpb24uCiAgICAgICAgICAgIExpc3RCdWZmZXI8VD4gbWFudWFsQ29udGFpbmVyID0gY3R4LmFubm90YXRlZC5nZXQodmFsaWRSZXBlYXRlZC50eXBlLnRzeW0pOwogICAgICAgICAgICBpZiAobWFudWFsQ29udGFpbmVyICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIGxvZy5lcnJvcihjdHgucG9zLmdldChtYW51YWxDb250YWluZXIuZmlyc3QoKSksCiAgICAgICAgICAgICAgICAgICAgICAgICJpbnZhbGlkLnJlcGVhdGFibGUuYW5ub3RhdGlvbi5yZXBlYXRlZC5hbmQuY29udGFpbmVyLnByZXNlbnQiLAogICAgICAgICAgICAgICAgICAgICAgICBtYW51YWxDb250YWluZXIuZmlyc3QoKS50eXBlLnRzeW0pOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBBIG51bGwgcmV0dXJuIHdpbGwgZGVsZXRlIHRoZSBQbGFjZWhvbGRlcgogICAgICAgIHJldHVybiB2YWxpZFJlcGVhdGVkOwogICAgfQoKICAgIC8qKioqKioqKioqKioqKioqKioqKgogICAgICogVHlwZSBhbm5vdGF0aW9ucyAqCiAgICAgKioqKioqKioqKioqKioqKioqKiovCgogICAgLyoqCiAgICAgKiBBdHRyaWJ1dGUgdGhlIGxpc3Qgb2YgYW5ub3RhdGlvbnMgYW5kIGVudGVyIHRoZW0gb250byBzLgogICAgICovCiAgICBwdWJsaWMgdm9pZCBlbnRlclR5cGVBbm5vdGF0aW9ucyhMaXN0PEpDQW5ub3RhdGlvbj4gYW5ub3RhdGlvbnMsIEVudjxBdHRyQ29udGV4dD4gZW52LAogICAgICAgICAgICBTeW1ib2wgcywgRGlhZ25vc3RpY1Bvc2l0aW9uIGRlZmVyUG9zLCBib29sZWFuIGlzVHlwZVBhcmFtKQogICAgewogICAgICAgIEFzc2VydC5jaGVja05vbk51bGwocywgIlN5bWJvbCBhcmd1bWVudCB0byBhY3R1YWxFbnRlclR5cGVBbm5vdGF0aW9ucyBpcyBudWwvIik7CiAgICAgICAgSmF2YUZpbGVPYmplY3QgcHJldiA9IGxvZy51c2VTb3VyY2UoZW52LnRvcGxldmVsLnNvdXJjZWZpbGUpOwogICAgICAgIERpYWdub3N0aWNQb3NpdGlvbiBwcmV2TGludFBvcyA9IG51bGw7CgogICAgICAgIGlmIChkZWZlclBvcyAhPSBudWxsKSB7CiAgICAgICAgICAgIHByZXZMaW50UG9zID0gZGVmZXJyZWRMaW50SGFuZGxlci5zZXRQb3MoZGVmZXJQb3MpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgICBhbm5vdGF0ZU5vdyhzLCBhbm5vdGF0aW9ucywgZW52LCB0cnVlLCBpc1R5cGVQYXJhbSk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgaWYgKHByZXZMaW50UG9zICE9IG51bGwpCiAgICAgICAgICAgICAgICBkZWZlcnJlZExpbnRIYW5kbGVyLnNldFBvcyhwcmV2TGludFBvcyk7CiAgICAgICAgICAgIGxvZy51c2VTb3VyY2UocHJldik7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogRW5xdWV1ZSB0cmVlIGZvciBzY2FubmluZyBvZiB0eXBlIGFubm90YXRpb25zLCBhdHRhY2hpbmcgdG8gdGhlIFN5bWJvbCBzeW0uCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHF1ZXVlU2NhblRyZWVBbmRUeXBlQW5ub3RhdGUoSkNUcmVlIHRyZWUsIEVudjxBdHRyQ29udGV4dD4gZW52LCBTeW1ib2wgc3ltLAogICAgICAgICAgICBEaWFnbm9zdGljUG9zaXRpb24gZGVmZXJQb3MpCiAgICB7CiAgICAgICAgQXNzZXJ0LmNoZWNrTm9uTnVsbChzeW0pOwogICAgICAgIG5vcm1hbCgoKSAtPiB0cmVlLmFjY2VwdChuZXcgVHlwZUFubm90YXRlKGVudiwgc3ltLCBkZWZlclBvcykpKTsKICAgIH0KCiAgICAvKioKICAgICAqIEFwcGx5IHRoZSBhbm5vdGF0aW9ucyB0byB0aGUgcGFydGljdWxhciB0eXBlLgogICAgICovCiAgICBwdWJsaWMgdm9pZCBhbm5vdGF0ZVR5cGVTZWNvbmRTdGFnZShKQ1RyZWUgdHJlZSwgTGlzdDxKQ0Fubm90YXRpb24+IGFubm90YXRpb25zLCBUeXBlIHN0b3JlQXQpIHsKICAgICAgICB0eXBlQW5ub3RhdGlvbigoKSAtPiB7CiAgICAgICAgICAgIExpc3Q8QXR0cmlidXRlLlR5cGVDb21wb3VuZD4gY29tcG91bmRzID0gZnJvbUFubm90YXRpb25zKGFubm90YXRpb25zKTsKICAgICAgICAgICAgQXNzZXJ0LmNoZWNrKGFubm90YXRpb25zLnNpemUoKSA9PSBjb21wb3VuZHMuc2l6ZSgpKTsKICAgICAgICAgICAgc3RvcmVBdC5nZXRNZXRhZGF0YU9mS2luZChLaW5kLkFOTk9UQVRJT05TKS5jb21iaW5lKG5ldyBUeXBlTWV0YWRhdGEuQW5ub3RhdGlvbnMoY29tcG91bmRzKSk7CiAgICAgICAgfSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBBcHBseSB0aGUgYW5ub3RhdGlvbnMgdG8gdGhlIHBhcnRpY3VsYXIgdHlwZS4KICAgICAqLwogICAgcHVibGljIHZvaWQgYW5ub3RhdGVUeXBlUGFyYW1ldGVyU2Vjb25kU3RhZ2UoSkNUcmVlIHRyZWUsIExpc3Q8SkNBbm5vdGF0aW9uPiBhbm5vdGF0aW9ucykgewogICAgICAgIHR5cGVBbm5vdGF0aW9uKCgpIC0+IHsKICAgICAgICAgICAgTGlzdDxBdHRyaWJ1dGUuVHlwZUNvbXBvdW5kPiBjb21wb3VuZHMgPSBmcm9tQW5ub3RhdGlvbnMoYW5ub3RhdGlvbnMpOwogICAgICAgICAgICBBc3NlcnQuY2hlY2soYW5ub3RhdGlvbnMuc2l6ZSgpID09IGNvbXBvdW5kcy5zaXplKCkpOwogICAgICAgIH0pOwogICAgfQoKICAgIC8qKgogICAgICogV2UgbmVlZCB0byB1c2UgYSBUcmVlU2Nhbm5lciwgYmVjYXVzZSBpdCBpcyBub3QgZW5vdWdoIHRvIHZpc2l0IHRoZSB0b3AtbGV2ZWwKICAgICAqIGFubm90YXRpb25zLiBXZSBhbHNvIG5lZWQgdG8gdmlzaXQgdHlwZSBhcmd1bWVudHMsIGV0Yy4KICAgICAqLwogICAgcHJpdmF0ZSBjbGFzcyBUeXBlQW5ub3RhdGUgZXh0ZW5kcyBUcmVlU2Nhbm5lciB7CiAgICAgICAgcHJpdmF0ZSBmaW5hbCBFbnY8QXR0ckNvbnRleHQ+IGVudjsKICAgICAgICBwcml2YXRlIGZpbmFsIFN5bWJvbCBzeW07CiAgICAgICAgcHJpdmF0ZSBEaWFnbm9zdGljUG9zaXRpb24gZGVmZXJQb3M7CgogICAgICAgIHB1YmxpYyBUeXBlQW5ub3RhdGUoRW52PEF0dHJDb250ZXh0PiBlbnYsIFN5bWJvbCBzeW0sIERpYWdub3N0aWNQb3NpdGlvbiBkZWZlclBvcykgewoKICAgICAgICAgICAgdGhpcy5lbnYgPSBlbnY7CiAgICAgICAgICAgIHRoaXMuc3ltID0gc3ltOwogICAgICAgICAgICB0aGlzLmRlZmVyUG9zID0gZGVmZXJQb3M7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdEFubm90YXRlZFR5cGUoSkNBbm5vdGF0ZWRUeXBlIHRyZWUpIHsKICAgICAgICAgICAgZW50ZXJUeXBlQW5ub3RhdGlvbnModHJlZS5hbm5vdGF0aW9ucywgZW52LCBzeW0sIGRlZmVyUG9zLCBmYWxzZSk7CiAgICAgICAgICAgIHNjYW4odHJlZS51bmRlcmx5aW5nVHlwZSk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdFR5cGVQYXJhbWV0ZXIoSkNUeXBlUGFyYW1ldGVyIHRyZWUpIHsKICAgICAgICAgICAgZW50ZXJUeXBlQW5ub3RhdGlvbnModHJlZS5hbm5vdGF0aW9ucywgZW52LCBzeW0sIGRlZmVyUG9zLCB0cnVlKTsKICAgICAgICAgICAgc2Nhbih0cmVlLmJvdW5kcyk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdE5ld0FycmF5KEpDTmV3QXJyYXkgdHJlZSkgewogICAgICAgICAgICBlbnRlclR5cGVBbm5vdGF0aW9ucyh0cmVlLmFubm90YXRpb25zLCBlbnYsIHN5bSwgZGVmZXJQb3MsIGZhbHNlKTsKICAgICAgICAgICAgZm9yIChMaXN0PEpDQW5ub3RhdGlvbj4gZGltQW5ub3MgOiB0cmVlLmRpbUFubm90YXRpb25zKQogICAgICAgICAgICAgICAgZW50ZXJUeXBlQW5ub3RhdGlvbnMoZGltQW5ub3MsIGVudiwgc3ltLCBkZWZlclBvcywgZmFsc2UpOwogICAgICAgICAgICBzY2FuKHRyZWUuZWxlbXR5cGUpOwogICAgICAgICAgICBzY2FuKHRyZWUuZWxlbXMpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRNZXRob2REZWYoSkNNZXRob2REZWNsIHRyZWUpIHsKICAgICAgICAgICAgc2Nhbih0cmVlLm1vZHMpOwogICAgICAgICAgICBzY2FuKHRyZWUucmVzdHlwZSk7CiAgICAgICAgICAgIHNjYW4odHJlZS50eXBhcmFtcyk7CiAgICAgICAgICAgIHNjYW4odHJlZS5yZWN2cGFyYW0pOwogICAgICAgICAgICBzY2FuKHRyZWUucGFyYW1zKTsKICAgICAgICAgICAgc2Nhbih0cmVlLnRocm93bik7CiAgICAgICAgICAgIHNjYW4odHJlZS5kZWZhdWx0VmFsdWUpOwogICAgICAgICAgICAvLyBEbyBub3QgYW5ub3RhdGUgdGhlIGJvZHksIGp1c3QgdGhlIHNpZ25hdHVyZS4KICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0VmFyRGVmKEpDVmFyaWFibGVEZWNsIHRyZWUpIHsKICAgICAgICAgICAgRGlhZ25vc3RpY1Bvc2l0aW9uIHByZXZQb3MgPSBkZWZlclBvczsKICAgICAgICAgICAgZGVmZXJQb3MgPSB0cmVlLnBvcygpOwogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgaWYgKHN5bSAhPSBudWxsICYmIHN5bS5raW5kID09IFZBUikgewogICAgICAgICAgICAgICAgICAgIC8vIERvbid0IHZpc2l0IGEgcGFyYW1ldGVyIG9uY2Ugd2hlbiB0aGUgc3ltIGlzIHRoZSBtZXRob2QKICAgICAgICAgICAgICAgICAgICAvLyBhbmQgb25jZSB3aGVuIHRoZSBzeW0gaXMgdGhlIHBhcmFtZXRlci4KICAgICAgICAgICAgICAgICAgICBzY2FuKHRyZWUubW9kcyk7CiAgICAgICAgICAgICAgICAgICAgc2Nhbih0cmVlLnZhcnR5cGUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgc2Nhbih0cmVlLmluaXQpOwogICAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAgICAgZGVmZXJQb3MgPSBwcmV2UG9zOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdENsYXNzRGVmKEpDQ2xhc3NEZWNsIHRyZWUpIHsKICAgICAgICAgICAgLy8gV2UgY2FuIG9ubHkgaGl0IGEgY2xhc3NkZWYgaWYgaXQgaXMgZGVjbGFyZWQgd2l0aGluCiAgICAgICAgICAgIC8vIGEgbWV0aG9kLiBJZ25vcmUgaXQgLSB0aGUgY2xhc3Mgd2lsbCBiZSB2aXNpdGVkCiAgICAgICAgICAgIC8vIHNlcGFyYXRlbHkgbGF0ZXIuCiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdE5ld0NsYXNzKEpDTmV3Q2xhc3MgdHJlZSkgewogICAgICAgICAgICBzY2FuKHRyZWUuZW5jbCk7CiAgICAgICAgICAgIHNjYW4odHJlZS50eXBlYXJncyk7CiAgICAgICAgICAgIHNjYW4odHJlZS5jbGF6eik7CiAgICAgICAgICAgIHNjYW4odHJlZS5hcmdzKTsKICAgICAgICAgICAgLy8gdGhlIGFub255bW91cyBjbGFzcyBpbnN0YW50aWF0aW9uIGlmIGFueSB3aWxsIGJlIHZpc2l0ZWQgc2VwYXJhdGVseS4KICAgICAgICB9CiAgICB9CgogICAgLyoqKioqKioqKioqKioqKioqKioqKgogICAgICogQ29tcGxldGVyIHN1cHBvcnQgKgogICAgICoqKioqKioqKioqKioqKioqKioqKi8KCiAgICBwcml2YXRlIEFubm90YXRpb25UeXBlQ29tcGxldGVyIHRoZVNvdXJjZUNvbXBsZXRlciA9IG5ldyBBbm5vdGF0aW9uVHlwZUNvbXBsZXRlcigpIHsKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCBjb21wbGV0ZShDbGFzc1N5bWJvbCBzeW0pIHRocm93cyBDb21wbGV0aW9uRmFpbHVyZSB7CiAgICAgICAgICAgIEVudjxBdHRyQ29udGV4dD4gY29udGV4dCA9IHR5cGVFbnZzLmdldChzeW0pOwogICAgICAgICAgICBBbm5vdGF0ZS50aGlzLmF0dHJpYnV0ZUFubm90YXRpb25UeXBlKGNvbnRleHQpOwogICAgICAgIH0KICAgIH07CgogICAgLyogTGFzdCBzdGFnZSBjb21wbGV0ZXIgdG8gZW50ZXIganVzdCBlbm91Z2ggYW5ub3RhdGlvbnMgdG8gaGF2ZSBhIHByb3RvdHlwZSBhbm5vdGF0aW9uIHR5cGUuCiAgICAgKiBUaGlzIGN1cnJlbnRseSBtZWFucyBlbnRlcmluZyBAVGFyZ2V0IGFuZCBAUmVwZXRhYmxlLgogICAgICovCiAgICBwdWJsaWMgQW5ub3RhdGlvblR5cGVDb21wbGV0ZXIgYW5ub3RhdGlvblR5cGVTb3VyY2VDb21wbGV0ZXIoKSB7CiAgICAgICAgcmV0dXJuIHRoZVNvdXJjZUNvbXBsZXRlcjsKICAgIH0KCiAgICBwcml2YXRlIHZvaWQgYXR0cmlidXRlQW5ub3RhdGlvblR5cGUoRW52PEF0dHJDb250ZXh0PiBlbnYpIHsKICAgICAgICBBc3NlcnQuY2hlY2soKChKQ0NsYXNzRGVjbCllbnYudHJlZSkuc3ltLmlzQW5ub3RhdGlvblR5cGUoKSwKICAgICAgICAgICAgICAgICJUcnlpbmcgdG8gYW5ub3RhdGlvbiB0eXBlIGNvbXBsZXRlIGEgbm9uLWFubm90YXRpb24gdHlwZSIpOwoKICAgICAgICBKYXZhRmlsZU9iamVjdCBwcmV2ID0gbG9nLnVzZVNvdXJjZShlbnYudG9wbGV2ZWwuc291cmNlZmlsZSk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgSkNDbGFzc0RlY2wgdHJlZSA9IChKQ0NsYXNzRGVjbCllbnYudHJlZTsKICAgICAgICAgICAgQW5ub3RhdGlvblR5cGVWaXNpdG9yIHYgPSBuZXcgQW5ub3RhdGlvblR5cGVWaXNpdG9yKGF0dHIsIGNoaywgc3ltcywgdHlwZUVudnMpOwogICAgICAgICAgICB2LnNjYW5Bbm5vdGF0aW9uVHlwZSh0cmVlKTsKICAgICAgICAgICAgdHJlZS5zeW0uZ2V0QW5ub3RhdGlvblR5cGVNZXRhZGF0YSgpLnNldFJlcGVhdGFibGUodi5yZXBlYXRhYmxlKTsKICAgICAgICAgICAgdHJlZS5zeW0uZ2V0QW5ub3RhdGlvblR5cGVNZXRhZGF0YSgpLnNldFRhcmdldCh2LnRhcmdldCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgbG9nLnVzZVNvdXJjZShwcmV2KTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIEF0dHJpYnV0ZSB1bmZpbmlzaGVkRGVmYXVsdFZhbHVlKCkgewogICAgICAgIHJldHVybiB0aGVVbmZpbmlzaGVkRGVmYXVsdFZhbHVlOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgaW50ZXJmYWNlIEFubm90YXRpb25UeXBlQ29tcGxldGVyIHsKICAgICAgICB2b2lkIGNvbXBsZXRlKENsYXNzU3ltYm9sIHN5bSkgdGhyb3dzIENvbXBsZXRpb25GYWlsdXJlOwogICAgfQoKICAgIC8qKiBWaXNpdG9yIHRvIGRldGVybWluZSBhIHByb3RvdHlwZSBhbm5vdGF0aW9uIHR5cGUgZm9yIGEgY2xhc3MgZGVjbGFyaW5nIGFuIGFubm90YXRpb24gdHlwZS4KICAgICAqCiAgICAgKiAgPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICAgICAqICBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAgICAgKiAgVGhpcyBjb2RlIGFuZCBpdHMgaW50ZXJuYWwgaW50ZXJmYWNlcyBhcmUgc3ViamVjdCB0byBjaGFuZ2Ugb3IKICAgICAqICBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+CiAgICAgKi8KICAgIHB1YmxpYyBjbGFzcyBBbm5vdGF0aW9uVHlwZVZpc2l0b3IgZXh0ZW5kcyBUcmVlU2Nhbm5lciB7CiAgICAgICAgcHJpdmF0ZSBFbnY8QXR0ckNvbnRleHQ+IGVudjsKCiAgICAgICAgcHJpdmF0ZSBmaW5hbCBBdHRyIGF0dHI7CiAgICAgICAgcHJpdmF0ZSBmaW5hbCBDaGVjayBjaGVjazsKICAgICAgICBwcml2YXRlIGZpbmFsIFN5bXRhYiB0YWI7CiAgICAgICAgcHJpdmF0ZSBmaW5hbCBUeXBlRW52cyB0eXBlRW52czsKCiAgICAgICAgcHJpdmF0ZSBDb21wb3VuZCB0YXJnZXQ7CiAgICAgICAgcHJpdmF0ZSBDb21wb3VuZCByZXBlYXRhYmxlOwoKICAgICAgICBwdWJsaWMgQW5ub3RhdGlvblR5cGVWaXNpdG9yKEF0dHIgYXR0ciwgQ2hlY2sgY2hlY2ssIFN5bXRhYiB0YWIsIFR5cGVFbnZzIHR5cGVFbnZzKSB7CiAgICAgICAgICAgIHRoaXMuYXR0ciA9IGF0dHI7CiAgICAgICAgICAgIHRoaXMuY2hlY2sgPSBjaGVjazsKICAgICAgICAgICAgdGhpcy50YWIgPSB0YWI7CiAgICAgICAgICAgIHRoaXMudHlwZUVudnMgPSB0eXBlRW52czsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBDb21wb3VuZCBnZXRSZXBlYXRhYmxlKCkgewogICAgICAgICAgICByZXR1cm4gcmVwZWF0YWJsZTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBDb21wb3VuZCBnZXRUYXJnZXQoKSB7CiAgICAgICAgICAgIHJldHVybiB0YXJnZXQ7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgdm9pZCBzY2FuQW5ub3RhdGlvblR5cGUoSkNDbGFzc0RlY2wgZGVjbCkgewogICAgICAgICAgICB2aXNpdENsYXNzRGVmKGRlY2wpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRDbGFzc0RlZihKQ0NsYXNzRGVjbCB0cmVlKSB7CiAgICAgICAgICAgIEVudjxBdHRyQ29udGV4dD4gcHJldkVudiA9IGVudjsKICAgICAgICAgICAgZW52ID0gdHlwZUVudnMuZ2V0KHRyZWUuc3ltKTsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIHNjYW4odHJlZS5tb2RzKTsgLy8gbG9vayBmb3IgcmVwZWF0YWJsZSBhbmQgdGFyZ2V0CiAgICAgICAgICAgICAgICAvLyBkb24ndCBkZXNjZW5kIGludG8gYm9keQogICAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAgICAgZW52ID0gcHJldkVudjsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRBbm5vdGF0aW9uKEpDQW5ub3RhdGlvbiB0cmVlKSB7CiAgICAgICAgICAgIFR5cGUgdCA9IHRyZWUuYW5ub3RhdGlvblR5cGUudHlwZTsKICAgICAgICAgICAgaWYgKHQgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgdCA9IGF0dHIuYXR0cmliVHlwZSh0cmVlLmFubm90YXRpb25UeXBlLCBlbnYpOwogICAgICAgICAgICAgICAgdHJlZS5hbm5vdGF0aW9uVHlwZS50eXBlID0gdCA9IGNoZWNrLmNoZWNrVHlwZSh0cmVlLmFubm90YXRpb25UeXBlLnBvcygpLCB0LCB0YWIuYW5ub3RhdGlvblR5cGUpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAodCA9PSB0YWIuYW5ub3RhdGlvblRhcmdldFR5cGUpIHsKICAgICAgICAgICAgICAgIHRhcmdldCA9IEFubm90YXRlLnRoaXMuYXR0cmlidXRlQW5ub3RhdGlvbih0cmVlLCB0YWIuYW5ub3RhdGlvblRhcmdldFR5cGUsIGVudik7CiAgICAgICAgICAgIH0gZWxzZSBpZiAodCA9PSB0YWIucmVwZWF0YWJsZVR5cGUpIHsKICAgICAgICAgICAgICAgIHJlcGVhdGFibGUgPSBBbm5vdGF0ZS50aGlzLmF0dHJpYnV0ZUFubm90YXRpb24odHJlZSwgdGFiLnJlcGVhdGFibGVUeXBlLCBlbnYpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKiBSZXByZXNlbnRzIHRoZSBzZW1hbnRpY3Mgb2YgYW4gQW5ub3RhdGlvbiBUeXBlLgogICAgICoKICAgICAqICA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogICAgICogIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24gcmlzay4KICAgICAqICBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogICAgICogIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBjbGFzcyBBbm5vdGF0aW9uVHlwZU1ldGFkYXRhIHsKICAgICAgICBmaW5hbCBDbGFzc1N5bWJvbCBtZXRhRGF0YUZvcjsKICAgICAgICBwcml2YXRlIENvbXBvdW5kIHRhcmdldDsKICAgICAgICBwcml2YXRlIENvbXBvdW5kIHJlcGVhdGFibGU7CiAgICAgICAgcHJpdmF0ZSBBbm5vdGF0aW9uVHlwZUNvbXBsZXRlciBhbm5vdGF0aW9uVHlwZUNvbXBsZXRlcjsKCiAgICAgICAgcHVibGljIEFubm90YXRpb25UeXBlTWV0YWRhdGEoQ2xhc3NTeW1ib2wgbWV0YURhdGFGb3IsIEFubm90YXRpb25UeXBlQ29tcGxldGVyIGFubm90YXRpb25UeXBlQ29tcGxldGVyKSB7CiAgICAgICAgICAgIHRoaXMubWV0YURhdGFGb3IgPSBtZXRhRGF0YUZvcjsKICAgICAgICAgICAgdGhpcy5hbm5vdGF0aW9uVHlwZUNvbXBsZXRlciA9IGFubm90YXRpb25UeXBlQ29tcGxldGVyOwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSB2b2lkIGluaXQoKSB7CiAgICAgICAgICAgIC8vIE1ha2Ugc3VyZSBtZXRhRGF0YUZvciBpcyBtZW1iZXIgZW50ZXJlZAogICAgICAgICAgICB3aGlsZSAoIW1ldGFEYXRhRm9yLmlzQ29tcGxldGVkKCkpCiAgICAgICAgICAgICAgICBtZXRhRGF0YUZvci5jb21wbGV0ZSgpOwoKICAgICAgICAgICAgaWYgKGFubm90YXRpb25UeXBlQ29tcGxldGVyICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIEFubm90YXRpb25UeXBlQ29tcGxldGVyIGMgPSBhbm5vdGF0aW9uVHlwZUNvbXBsZXRlcjsKICAgICAgICAgICAgICAgIGFubm90YXRpb25UeXBlQ29tcGxldGVyID0gbnVsbDsKICAgICAgICAgICAgICAgIGMuY29tcGxldGUobWV0YURhdGFGb3IpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgdm9pZCBjb21wbGV0ZSgpIHsKICAgICAgICAgICAgaW5pdCgpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIENvbXBvdW5kIGdldFJlcGVhdGFibGUoKSB7CiAgICAgICAgICAgIGluaXQoKTsKICAgICAgICAgICAgcmV0dXJuIHJlcGVhdGFibGU7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgdm9pZCBzZXRSZXBlYXRhYmxlKENvbXBvdW5kIHJlcGVhdGFibGUpIHsKICAgICAgICAgICAgQXNzZXJ0LmNoZWNrTnVsbCh0aGlzLnJlcGVhdGFibGUpOwogICAgICAgICAgICB0aGlzLnJlcGVhdGFibGUgPSByZXBlYXRhYmxlOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIENvbXBvdW5kIGdldFRhcmdldCgpIHsKICAgICAgICAgICAgaW5pdCgpOwogICAgICAgICAgICByZXR1cm4gdGFyZ2V0OwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHZvaWQgc2V0VGFyZ2V0KENvbXBvdW5kIHRhcmdldCkgewogICAgICAgICAgICBBc3NlcnQuY2hlY2tOdWxsKHRoaXMudGFyZ2V0KTsKICAgICAgICAgICAgICAgIHRoaXMudGFyZ2V0ID0gdGFyZ2V0OwogICAgICAgIH0KCiAgICAgICAgcHVibGljIFNldDxNZXRob2RTeW1ib2w+IGdldEFubm90YXRpb25FbGVtZW50cygpIHsKICAgICAgICAgICAgaW5pdCgpOwogICAgICAgICAgICBTZXQ8TWV0aG9kU3ltYm9sPiBtZW1iZXJzID0gbmV3IExpbmtlZEhhc2hTZXQ8PigpOwogICAgICAgICAgICBXcml0ZWFibGVTY29wZSBzID0gbWV0YURhdGFGb3IubWVtYmVycygpOwogICAgICAgICAgICBJdGVyYWJsZTxTeW1ib2w+IHNzID0gcy5nZXRTeW1ib2xzKE5PTl9SRUNVUlNJVkUpOwogICAgICAgICAgICBmb3IgKFN5bWJvbCBzeW0gOiBzcykKICAgICAgICAgICAgICAgIGlmIChzeW0ua2luZCA9PSBNVEggJiYKICAgICAgICAgICAgICAgICAgICAgICAgc3ltLm5hbWUgIT0gc3ltLm5hbWUudGFibGUubmFtZXMuY2xpbml0ICYmCiAgICAgICAgICAgICAgICAgICAgICAgIChzeW0uZmxhZ3MoKSAmIFNZTlRIRVRJQykgPT0gMCkKICAgICAgICAgICAgICAgICAgICBtZW1iZXJzLmFkZCgoTWV0aG9kU3ltYm9sKXN5bSk7CiAgICAgICAgICAgIHJldHVybiBtZW1iZXJzOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIFNldDxNZXRob2RTeW1ib2w+IGdldEFubm90YXRpb25FbGVtZW50c1dpdGhEZWZhdWx0KCkgewogICAgICAgICAgICBpbml0KCk7CiAgICAgICAgICAgIFNldDxNZXRob2RTeW1ib2w+IG1lbWJlcnMgPSBnZXRBbm5vdGF0aW9uRWxlbWVudHMoKTsKICAgICAgICAgICAgU2V0PE1ldGhvZFN5bWJvbD4gcmVzID0gbmV3IExpbmtlZEhhc2hTZXQ8PigpOwogICAgICAgICAgICBmb3IgKE1ldGhvZFN5bWJvbCBtIDogbWVtYmVycykKICAgICAgICAgICAgICAgIGlmIChtLmRlZmF1bHRWYWx1ZSAhPSBudWxsKQogICAgICAgICAgICAgICAgICAgIHJlcy5hZGQobSk7CiAgICAgICAgICAgIHJldHVybiByZXM7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewogICAgICAgICAgICByZXR1cm4gIkFubm90YXRpb24gdHlwZSBmb3I6ICIgKyBtZXRhRGF0YUZvcjsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBib29sZWFuIGlzTWV0YWRhdGFGb3JBbm5vdGF0aW9uVHlwZSgpIHsgcmV0dXJuIHRydWU7IH0KCiAgICAgICAgcHVibGljIHN0YXRpYyBBbm5vdGF0aW9uVHlwZU1ldGFkYXRhIG5vdEFuQW5ub3RhdGlvblR5cGUoKSB7CiAgICAgICAgICAgIHJldHVybiBOT1RfQU5fQU5OT1RBVElPTl9UWVBFOwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQW5ub3RhdGlvblR5cGVNZXRhZGF0YSBOT1RfQU5fQU5OT1RBVElPTl9UWVBFID0KICAgICAgICAgICAgICAgIG5ldyBBbm5vdGF0aW9uVHlwZU1ldGFkYXRhKG51bGwsIG51bGwpIHsKICAgICAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCBjb21wbGV0ZSgpIHsKICAgICAgICAgICAgICAgICAgICB9IC8vIGRvIG5vdGhpbmcKCiAgICAgICAgICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgICAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICJOb3QgYW4gYW5ub3RhdGlvbiB0eXBlIjsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICAgICAgICAgIHB1YmxpYyBTZXQ8TWV0aG9kU3ltYm9sPiBnZXRBbm5vdGF0aW9uRWxlbWVudHMoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgTGlua2VkSGFzaFNldDw+KDApOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgICAgICAgICAgcHVibGljIFNldDxNZXRob2RTeW1ib2w+IGdldEFubm90YXRpb25FbGVtZW50c1dpdGhEZWZhdWx0KCkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IExpbmtlZEhhc2hTZXQ8PigwKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICAgICAgICAgIHB1YmxpYyBib29sZWFuIGlzTWV0YWRhdGFGb3JBbm5vdGF0aW9uVHlwZSgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgICAgICAgICAgcHVibGljIENvbXBvdW5kIGdldFRhcmdldCgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgICAgICAgICBwdWJsaWMgQ29tcG91bmQgZ2V0UmVwZWF0YWJsZSgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCBuZXdSb3VuZCgpIHsKICAgICAgICBibG9ja0NvdW50ID0gMTsKICAgIH0KfQpQSwMECgAACAAABjupStLEpkkrGwMAKxsDACUAAABjb20vc3VuL3Rvb2xzL2phdmFjL2NvbXAvUmVzb2x2ZS5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAxOTk5LCAyMDE3LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuamF2YWMuY29tcDsKCmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmFwaS5Gb3JtYXR0YWJsZS5Mb2NhbGl6ZWRTdHJpbmc7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuKjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5TY29wZS5Xcml0ZWFibGVTY29wZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5TeW1ib2wuKjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5UeXBlLio7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvbXAuQXR0ci5SZXN1bHRJbmZvOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb21wLkNoZWNrLkNoZWNrQ29udGV4dDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29tcC5EZWZlcnJlZEF0dHIuQXR0ck1vZGU7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvbXAuRGVmZXJyZWRBdHRyLkRlZmVycmVkQXR0ckNvbnRleHQ7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvbXAuRGVmZXJyZWRBdHRyLkRlZmVycmVkVHlwZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29tcC5JbmZlci5GcmVlVHlwZUxpc3RlbmVyOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb21wLlJlc29sdmUuTWV0aG9kUmVzb2x1dGlvbkNvbnRleHQuQ2FuZGlkYXRlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb21wLlJlc29sdmUuTWV0aG9kUmVzb2x1dGlvbkRpYWdIZWxwZXIuVGVtcGxhdGU7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvbXAuUmVzb2x2ZS5SZWZlcmVuY2VMb29rdXBSZXN1bHQuU3RhdGljS2luZDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuanZtLio7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLm1haW4uT3B0aW9uOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5yZXNvdXJjZXMuQ29tcGlsZXJQcm9wZXJ0aWVzLkZyYWdtZW50czsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS4qOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkpDVHJlZS4qOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkpDVHJlZS5KQ01lbWJlclJlZmVyZW5jZS5SZWZlcmVuY2VLaW5kOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkpDVHJlZS5KQ1BvbHlFeHByZXNzaW9uLio7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuKjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5EZWZpbmVkQnkuQXBpOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkpDRGlhZ25vc3RpYy5EaWFnbm9zdGljRmxhZzsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5KQ0RpYWdub3N0aWMuRGlhZ25vc3RpY1Bvc2l0aW9uOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkpDRGlhZ25vc3RpYy5EaWFnbm9zdGljVHlwZTsKCmltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOwppbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb247CmltcG9ydCBqYXZhLnV0aWwuRW51bVNldDsKaW1wb3J0IGphdmEudXRpbC5IYXNoU2V0OwppbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOwppbXBvcnQgamF2YS51dGlsLkxpbmtlZEhhc2hNYXA7CmltcG9ydCBqYXZhLnV0aWwuTWFwOwppbXBvcnQgamF2YS51dGlsLlNldDsKaW1wb3J0IGphdmEudXRpbC5mdW5jdGlvbi5CaUZ1bmN0aW9uOwppbXBvcnQgamF2YS51dGlsLmZ1bmN0aW9uLkJpUHJlZGljYXRlOwppbXBvcnQgamF2YS51dGlsLmZ1bmN0aW9uLkZ1bmN0aW9uOwppbXBvcnQgamF2YS51dGlsLmZ1bmN0aW9uLlByZWRpY2F0ZTsKaW1wb3J0IGphdmEudXRpbC5zdHJlYW0uU3RyZWFtOwoKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC5FbGVtZW50VmlzaXRvcjsKCmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLkZsYWdzLio7CmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLkZsYWdzLkJMT0NLOwppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5GbGFncy5TVEFUSUM7CmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLktpbmRzLio7CmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLktpbmRzLktpbmQuKjsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuVHlwZVRhZy4qOwppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMuY29tcC5SZXNvbHZlLk1ldGhvZFJlc29sdXRpb25QaGFzZS4qOwppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5KQ1RyZWUuVGFnLio7CmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkl0ZXJhdG9ycy5jcmVhdGVDb21wb3VuZEl0ZXJhdG9yOwoKLyoqIEhlbHBlciBjbGFzcyBmb3IgbmFtZSByZXNvbHV0aW9uLCB1c2VkIG1vc3RseSBieSB0aGUgYXR0cmlidXRpb24gcGhhc2UuCiAqCiAqICA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiAgSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93biByaXNrLgogKiAgVGhpcyBjb2RlIGFuZCBpdHMgaW50ZXJuYWwgaW50ZXJmYWNlcyBhcmUgc3ViamVjdCB0byBjaGFuZ2Ugb3IKICogIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj4KICovCnB1YmxpYyBjbGFzcyBSZXNvbHZlIHsKICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgQ29udGV4dC5LZXk8UmVzb2x2ZT4gcmVzb2x2ZUtleSA9IG5ldyBDb250ZXh0LktleTw+KCk7CgogICAgTmFtZXMgbmFtZXM7CiAgICBMb2cgbG9nOwogICAgU3ltdGFiIHN5bXM7CiAgICBBdHRyIGF0dHI7CiAgICBEZWZlcnJlZEF0dHIgZGVmZXJyZWRBdHRyOwogICAgQ2hlY2sgY2hrOwogICAgSW5mZXIgaW5mZXI7CiAgICBDbGFzc0ZpbmRlciBmaW5kZXI7CiAgICBNb2R1bGVGaW5kZXIgbW9kdWxlRmluZGVyOwogICAgVHlwZXMgdHlwZXM7CiAgICBKQ0RpYWdub3N0aWMuRmFjdG9yeSBkaWFnczsKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGFsbG93TWV0aG9kSGFuZGxlczsKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGFsbG93RnVuY3Rpb25hbEludGVyZmFjZU1vc3RTcGVjaWZpYzsKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGFsbG93TW9kdWxlczsKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGNoZWNrVmFyYXJnc0FjY2Vzc0FmdGVyUmVzb2x1dGlvbjsKICAgIHByaXZhdGUgZmluYWwgYm9vbGVhbiBjb21wYWN0TWV0aG9kRGlhZ3M7CiAgICBmaW5hbCBFbnVtU2V0PFZlcmJvc2VSZXNvbHV0aW9uTW9kZT4gdmVyYm9zZVJlc29sdXRpb25Nb2RlOwoKICAgIFdyaXRlYWJsZVNjb3BlIHBvbHltb3JwaGljU2lnbmF0dXJlU2NvcGU7CgogICAgcHJvdGVjdGVkIFJlc29sdmUoQ29udGV4dCBjb250ZXh0KSB7CiAgICAgICAgY29udGV4dC5wdXQocmVzb2x2ZUtleSwgdGhpcyk7CiAgICAgICAgc3ltcyA9IFN5bXRhYi5pbnN0YW5jZShjb250ZXh0KTsKCiAgICAgICAgdmFyTm90Rm91bmQgPSBuZXcgU3ltYm9sTm90Rm91bmRFcnJvcihBQlNFTlRfVkFSKTsKICAgICAgICBtZXRob2ROb3RGb3VuZCA9IG5ldyBTeW1ib2xOb3RGb3VuZEVycm9yKEFCU0VOVF9NVEgpOwogICAgICAgIHR5cGVOb3RGb3VuZCA9IG5ldyBTeW1ib2xOb3RGb3VuZEVycm9yKEFCU0VOVF9UWVApOwogICAgICAgIHJlZmVyZW5jZU5vdEZvdW5kID0gbmV3IFJlZmVyZW5jZUxvb2t1cFJlc3VsdChtZXRob2ROb3RGb3VuZCwgbnVsbCk7CgogICAgICAgIG5hbWVzID0gTmFtZXMuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgbG9nID0gTG9nLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIGF0dHIgPSBBdHRyLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIGRlZmVycmVkQXR0ciA9IERlZmVycmVkQXR0ci5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBjaGsgPSBDaGVjay5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBpbmZlciA9IEluZmVyLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIGZpbmRlciA9IENsYXNzRmluZGVyLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIG1vZHVsZUZpbmRlciA9IE1vZHVsZUZpbmRlci5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICB0eXBlcyA9IFR5cGVzLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIGRpYWdzID0gSkNEaWFnbm9zdGljLkZhY3RvcnkuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgU291cmNlIHNvdXJjZSA9IFNvdXJjZS5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBPcHRpb25zIG9wdGlvbnMgPSBPcHRpb25zLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIGNvbXBhY3RNZXRob2REaWFncyA9IG9wdGlvbnMuaXNTZXQoT3B0aW9uLlhESUFHUywgImNvbXBhY3QiKSB8fAogICAgICAgICAgICAgICAgb3B0aW9ucy5pc1Vuc2V0KE9wdGlvbi5YRElBR1MpICYmIG9wdGlvbnMuaXNVbnNldCgicmF3RGlhZ25vc3RpY3MiKTsKICAgICAgICB2ZXJib3NlUmVzb2x1dGlvbk1vZGUgPSBWZXJib3NlUmVzb2x1dGlvbk1vZGUuZ2V0VmVyYm9zZVJlc29sdXRpb25Nb2RlKG9wdGlvbnMpOwogICAgICAgIFRhcmdldCB0YXJnZXQgPSBUYXJnZXQuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgYWxsb3dNZXRob2RIYW5kbGVzID0gdGFyZ2V0Lmhhc01ldGhvZEhhbmRsZXMoKTsKICAgICAgICBhbGxvd0Z1bmN0aW9uYWxJbnRlcmZhY2VNb3N0U3BlY2lmaWMgPSBzb3VyY2UuYWxsb3dGdW5jdGlvbmFsSW50ZXJmYWNlTW9zdFNwZWNpZmljKCk7CiAgICAgICAgY2hlY2tWYXJhcmdzQWNjZXNzQWZ0ZXJSZXNvbHV0aW9uID0KICAgICAgICAgICAgICAgIHNvdXJjZS5hbGxvd1Bvc3RBcHBsaWNhYmlsaXR5VmFyYXJnc0FjY2Vzc0NoZWNrKCk7CiAgICAgICAgcG9seW1vcnBoaWNTaWduYXR1cmVTY29wZSA9IFdyaXRlYWJsZVNjb3BlLmNyZWF0ZShzeW1zLm5vU3ltYm9sKTsKCiAgICAgICAgaW5hcHBsaWNhYmxlTWV0aG9kRXhjZXB0aW9uID0gbmV3IEluYXBwbGljYWJsZU1ldGhvZEV4Y2VwdGlvbihkaWFncyk7CgogICAgICAgIGFsbG93TW9kdWxlcyA9IHNvdXJjZS5hbGxvd01vZHVsZXMoKTsKICAgIH0KCiAgICAvKiogZXJyb3Igc3ltYm9scywgd2hpY2ggYXJlIHJldHVybmVkIHdoZW4gcmVzb2x1dGlvbiBmYWlscwogICAgICovCiAgICBwcml2YXRlIGZpbmFsIFN5bWJvbE5vdEZvdW5kRXJyb3IgdmFyTm90Rm91bmQ7CiAgICBwcml2YXRlIGZpbmFsIFN5bWJvbE5vdEZvdW5kRXJyb3IgbWV0aG9kTm90Rm91bmQ7CiAgICBwcml2YXRlIGZpbmFsIFN5bWJvbE5vdEZvdW5kRXJyb3IgdHlwZU5vdEZvdW5kOwoKICAgIC8qKiBlbXB0eSByZWZlcmVuY2UgbG9va3VwIHJlc3VsdCAqLwogICAgcHJpdmF0ZSBmaW5hbCBSZWZlcmVuY2VMb29rdXBSZXN1bHQgcmVmZXJlbmNlTm90Rm91bmQ7CgogICAgcHVibGljIHN0YXRpYyBSZXNvbHZlIGluc3RhbmNlKENvbnRleHQgY29udGV4dCkgewogICAgICAgIFJlc29sdmUgaW5zdGFuY2UgPSBjb250ZXh0LmdldChyZXNvbHZlS2V5KTsKICAgICAgICBpZiAoaW5zdGFuY2UgPT0gbnVsbCkKICAgICAgICAgICAgaW5zdGFuY2UgPSBuZXcgUmVzb2x2ZShjb250ZXh0KTsKICAgICAgICByZXR1cm4gaW5zdGFuY2U7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgU3ltYm9sIGJlc3RPZihTeW1ib2wgczEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN5bWJvbCBzMikgewogICAgICAgIHJldHVybiBzMS5raW5kLmJldHRlclRoYW4oczIua2luZCkgPyBzMSA6IHMyOwogICAgfQoKICAgIC8vIDxlZGl0b3ItZm9sZCBkZWZhdWx0c3RhdGU9ImNvbGxhcHNlZCIgZGVzYz0iVmVyYm9zZSByZXNvbHV0aW9uIGRpYWdub3N0aWNzIHN1cHBvcnQiPgogICAgZW51bSBWZXJib3NlUmVzb2x1dGlvbk1vZGUgewogICAgICAgIFNVQ0NFU1MoInN1Y2Nlc3MiKSwKICAgICAgICBGQUlMVVJFKCJmYWlsdXJlIiksCiAgICAgICAgQVBQTElDQUJMRSgiYXBwbGljYWJsZSIpLAogICAgICAgIElOQVBQTElDQUJMRSgiaW5hcHBsaWNhYmxlIiksCiAgICAgICAgREVGRVJSRURfSU5TVCgiZGVmZXJyZWQtaW5mZXJlbmNlIiksCiAgICAgICAgUFJFREVGKCJwcmVkZWYiKSwKICAgICAgICBPQkpFQ1RfSU5JVCgib2JqZWN0LWluaXQiKSwKICAgICAgICBJTlRFUk5BTCgiaW50ZXJuYWwiKTsKCiAgICAgICAgZmluYWwgU3RyaW5nIG9wdDsKCiAgICAgICAgcHJpdmF0ZSBWZXJib3NlUmVzb2x1dGlvbk1vZGUoU3RyaW5nIG9wdCkgewogICAgICAgICAgICB0aGlzLm9wdCA9IG9wdDsKICAgICAgICB9CgogICAgICAgIHN0YXRpYyBFbnVtU2V0PFZlcmJvc2VSZXNvbHV0aW9uTW9kZT4gZ2V0VmVyYm9zZVJlc29sdXRpb25Nb2RlKE9wdGlvbnMgb3B0cykgewogICAgICAgICAgICBTdHJpbmcgcyA9IG9wdHMuZ2V0KCJkZWJ1Zy52ZXJib3NlUmVzb2x1dGlvbiIpOwogICAgICAgICAgICBFbnVtU2V0PFZlcmJvc2VSZXNvbHV0aW9uTW9kZT4gcmVzID0gRW51bVNldC5ub25lT2YoVmVyYm9zZVJlc29sdXRpb25Nb2RlLmNsYXNzKTsKICAgICAgICAgICAgaWYgKHMgPT0gbnVsbCkgcmV0dXJuIHJlczsKICAgICAgICAgICAgaWYgKHMuY29udGFpbnMoImFsbCIpKSB7CiAgICAgICAgICAgICAgICByZXMgPSBFbnVtU2V0LmFsbE9mKFZlcmJvc2VSZXNvbHV0aW9uTW9kZS5jbGFzcyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgQ29sbGVjdGlvbjxTdHJpbmc+IGFyZ3MgPSBBcnJheXMuYXNMaXN0KHMuc3BsaXQoIiwiKSk7CiAgICAgICAgICAgIGZvciAoVmVyYm9zZVJlc29sdXRpb25Nb2RlIG1vZGUgOiB2YWx1ZXMoKSkgewogICAgICAgICAgICAgICAgaWYgKGFyZ3MuY29udGFpbnMobW9kZS5vcHQpKSB7CiAgICAgICAgICAgICAgICAgICAgcmVzLmFkZChtb2RlKTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoYXJncy5jb250YWlucygiLSIgKyBtb2RlLm9wdCkpIHsKICAgICAgICAgICAgICAgICAgICByZXMucmVtb3ZlKG1vZGUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiByZXM7CiAgICAgICAgfQogICAgfQoKICAgIHZvaWQgcmVwb3J0VmVyYm9zZVJlc29sdXRpb25EaWFnbm9zdGljKERpYWdub3N0aWNQb3NpdGlvbiBkcG9zLCBOYW1lIG5hbWUsIFR5cGUgc2l0ZSwKICAgICAgICAgICAgTGlzdDxUeXBlPiBhcmd0eXBlcywgTGlzdDxUeXBlPiB0eXBlYXJndHlwZXMsIFN5bWJvbCBiZXN0U29GYXIpIHsKICAgICAgICBib29sZWFuIHN1Y2Nlc3MgPSAhYmVzdFNvRmFyLmtpbmQuaXNSZXNvbHV0aW9uRXJyb3IoKTsKCiAgICAgICAgaWYgKHN1Y2Nlc3MgJiYgIXZlcmJvc2VSZXNvbHV0aW9uTW9kZS5jb250YWlucyhWZXJib3NlUmVzb2x1dGlvbk1vZGUuU1VDQ0VTUykpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0gZWxzZSBpZiAoIXN1Y2Nlc3MgJiYgIXZlcmJvc2VSZXNvbHV0aW9uTW9kZS5jb250YWlucyhWZXJib3NlUmVzb2x1dGlvbk1vZGUuRkFJTFVSRSkpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgaWYgKGJlc3RTb0Zhci5uYW1lID09IG5hbWVzLmluaXQgJiYKICAgICAgICAgICAgICAgIGJlc3RTb0Zhci5vd25lciA9PSBzeW1zLm9iamVjdFR5cGUudHN5bSAmJgogICAgICAgICAgICAgICAgIXZlcmJvc2VSZXNvbHV0aW9uTW9kZS5jb250YWlucyhWZXJib3NlUmVzb2x1dGlvbk1vZGUuT0JKRUNUX0lOSVQpKSB7CiAgICAgICAgICAgIHJldHVybjsgLy9za2lwIGRpYWdzIGZvciBPYmplY3QgY29uc3RydWN0b3IgcmVzb2x1dGlvbgogICAgICAgIH0gZWxzZSBpZiAoc2l0ZSA9PSBzeW1zLnByZWRlZkNsYXNzLnR5cGUgJiYKICAgICAgICAgICAgICAgICF2ZXJib3NlUmVzb2x1dGlvbk1vZGUuY29udGFpbnMoVmVyYm9zZVJlc29sdXRpb25Nb2RlLlBSRURFRikpIHsKICAgICAgICAgICAgcmV0dXJuOyAvL3NraXAgc3B1cmlvdXMgZGlhZ3MgZm9yIHByZWRlZiBzeW1ib2xzIChpLmUuIG9wZXJhdG9ycykKICAgICAgICB9IGVsc2UgaWYgKGN1cnJlbnRSZXNvbHV0aW9uQ29udGV4dC5pbnRlcm5hbFJlc29sdXRpb24gJiYKICAgICAgICAgICAgICAgICF2ZXJib3NlUmVzb2x1dGlvbk1vZGUuY29udGFpbnMoVmVyYm9zZVJlc29sdXRpb25Nb2RlLklOVEVSTkFMKSkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICBpbnQgcG9zID0gMDsKICAgICAgICBpbnQgbW9zdFNwZWNpZmljUG9zID0gLTE7CiAgICAgICAgTGlzdEJ1ZmZlcjxKQ0RpYWdub3N0aWM+IHN1YkRpYWdzID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgIGZvciAoQ2FuZGlkYXRlIGMgOiBjdXJyZW50UmVzb2x1dGlvbkNvbnRleHQuY2FuZGlkYXRlcykgewogICAgICAgICAgICBpZiAoY3VycmVudFJlc29sdXRpb25Db250ZXh0LnN0ZXAgIT0gYy5zdGVwIHx8CiAgICAgICAgICAgICAgICAgICAgKGMuaXNBcHBsaWNhYmxlKCkgJiYgIXZlcmJvc2VSZXNvbHV0aW9uTW9kZS5jb250YWlucyhWZXJib3NlUmVzb2x1dGlvbk1vZGUuQVBQTElDQUJMRSkpIHx8CiAgICAgICAgICAgICAgICAgICAgKCFjLmlzQXBwbGljYWJsZSgpICYmICF2ZXJib3NlUmVzb2x1dGlvbk1vZGUuY29udGFpbnMoVmVyYm9zZVJlc29sdXRpb25Nb2RlLklOQVBQTElDQUJMRSkpKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHN1YkRpYWdzLmFwcGVuZChjLmlzQXBwbGljYWJsZSgpID8KICAgICAgICAgICAgICAgICAgICAgICAgZ2V0VmVyYm9zZUFwcGxpY2FibGVDYW5kaWRhdGVEaWFnKHBvcywgYy5zeW0sIGMubXR5cGUpIDoKICAgICAgICAgICAgICAgICAgICAgICAgZ2V0VmVyYm9zZUluYXBwbGljYWJsZUNhbmRpZGF0ZURpYWcocG9zLCBjLnN5bSwgYy5kZXRhaWxzKSk7CiAgICAgICAgICAgICAgICBpZiAoYy5zeW0gPT0gYmVzdFNvRmFyKQogICAgICAgICAgICAgICAgICAgIG1vc3RTcGVjaWZpY1BvcyA9IHBvczsKICAgICAgICAgICAgICAgIHBvcysrOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIFN0cmluZyBrZXkgPSBzdWNjZXNzID8gInZlcmJvc2UucmVzb2x2ZS5tdWx0aSIgOiAidmVyYm9zZS5yZXNvbHZlLm11bHRpLjEiOwogICAgICAgIExpc3Q8VHlwZT4gYXJndHlwZXMyID0gYXJndHlwZXMubWFwKGRlZmVycmVkQXR0ci5uZXcgUmVjb3ZlcnlEZWZlcnJlZFR5cGVNYXAoQXR0ck1vZGUuU1BFQ1VMQVRJVkUsIGJlc3RTb0ZhciwgY3VycmVudFJlc29sdXRpb25Db250ZXh0LnN0ZXApKTsKICAgICAgICBKQ0RpYWdub3N0aWMgbWFpbiA9IGRpYWdzLm5vdGUobG9nLmN1cnJlbnRTb3VyY2UoKSwgZHBvcywga2V5LCBuYW1lLAogICAgICAgICAgICAgICAgc2l0ZS50c3ltLCBtb3N0U3BlY2lmaWNQb3MsIGN1cnJlbnRSZXNvbHV0aW9uQ29udGV4dC5zdGVwLAogICAgICAgICAgICAgICAgbWV0aG9kQXJndW1lbnRzKGFyZ3R5cGVzMiksCiAgICAgICAgICAgICAgICBtZXRob2RBcmd1bWVudHModHlwZWFyZ3R5cGVzKSk7CiAgICAgICAgSkNEaWFnbm9zdGljIGQgPSBuZXcgSkNEaWFnbm9zdGljLk11bHRpbGluZURpYWdub3N0aWMobWFpbiwgc3ViRGlhZ3MudG9MaXN0KCkpOwogICAgICAgIGxvZy5yZXBvcnQoZCk7CiAgICB9CgogICAgSkNEaWFnbm9zdGljIGdldFZlcmJvc2VBcHBsaWNhYmxlQ2FuZGlkYXRlRGlhZyhpbnQgcG9zLCBTeW1ib2wgc3ltLCBUeXBlIGluc3QpIHsKICAgICAgICBKQ0RpYWdub3N0aWMgc3ViRGlhZyA9IG51bGw7CiAgICAgICAgaWYgKHN5bS50eXBlLmhhc1RhZyhGT1JBTEwpKSB7CiAgICAgICAgICAgIHN1YkRpYWcgPSBkaWFncy5mcmFnbWVudCgicGFydGlhbC5pbnN0LnNpZyIsIGluc3QpOwogICAgICAgIH0KCiAgICAgICAgU3RyaW5nIGtleSA9IHN1YkRpYWcgPT0gbnVsbCA/CiAgICAgICAgICAgICAgICAiYXBwbGljYWJsZS5tZXRob2QuZm91bmQiIDoKICAgICAgICAgICAgICAgICJhcHBsaWNhYmxlLm1ldGhvZC5mb3VuZC4xIjsKCiAgICAgICAgcmV0dXJuIGRpYWdzLmZyYWdtZW50KGtleSwgcG9zLCBzeW0sIHN1YkRpYWcpOwogICAgfQoKICAgIEpDRGlhZ25vc3RpYyBnZXRWZXJib3NlSW5hcHBsaWNhYmxlQ2FuZGlkYXRlRGlhZyhpbnQgcG9zLCBTeW1ib2wgc3ltLCBKQ0RpYWdub3N0aWMgc3ViRGlhZykgewogICAgICAgIHJldHVybiBkaWFncy5mcmFnbWVudCgibm90LmFwcGxpY2FibGUubWV0aG9kLmZvdW5kIiwgcG9zLCBzeW0sIHN1YkRpYWcpOwogICAgfQogICAgLy8gPC9lZGl0b3ItZm9sZD4KCi8qICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJZGVudGlmaWVyIHJlc29sdXRpb24KICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgogICAgLyoqIEFuIGVudmlyb25tZW50IGlzICJzdGF0aWMiIGlmIGl0cyBzdGF0aWMgbGV2ZWwgaXMgZ3JlYXRlciB0aGFuCiAgICAgKiAgdGhlIG9uZSBvZiBpdHMgb3V0ZXIgZW52aXJvbm1lbnQKICAgICAqLwogICAgcHJvdGVjdGVkIHN0YXRpYyBib29sZWFuIGlzU3RhdGljKEVudjxBdHRyQ29udGV4dD4gZW52KSB7CiAgICAgICAgcmV0dXJuIGVudi5vdXRlciAhPSBudWxsICYmIGVudi5pbmZvLnN0YXRpY0xldmVsID4gZW52Lm91dGVyLmluZm8uc3RhdGljTGV2ZWw7CiAgICB9CgogICAgLyoqIEFuIGVudmlyb25tZW50IGlzIGFuICJpbml0aWFsaXplciIgaWYgaXQgaXMgYSBjb25zdHJ1Y3RvciBvcgogICAgICogIGFuIGluc3RhbmNlIGluaXRpYWxpemVyLgogICAgICovCiAgICBzdGF0aWMgYm9vbGVhbiBpc0luaXRpYWxpemVyKEVudjxBdHRyQ29udGV4dD4gZW52KSB7CiAgICAgICAgU3ltYm9sIG93bmVyID0gZW52LmluZm8uc2NvcGUub3duZXI7CiAgICAgICAgcmV0dXJuIG93bmVyLmlzQ29uc3RydWN0b3IoKSB8fAogICAgICAgICAgICBvd25lci5vd25lci5raW5kID09IFRZUCAmJgogICAgICAgICAgICAob3duZXIua2luZCA9PSBWQVIgfHwKICAgICAgICAgICAgIG93bmVyLmtpbmQgPT0gTVRIICYmIChvd25lci5mbGFncygpICYgQkxPQ0spICE9IDApICYmCiAgICAgICAgICAgIChvd25lci5mbGFncygpICYgU1RBVElDKSA9PSAwOwogICAgfQoKICAgIC8qKiBJcyBjbGFzcyBhY2Nlc3NpYmxlIGluIGdpdmVuIGV2aXJvbm1lbnQ/CiAgICAgKiAgQHBhcmFtIGVudiAgICBUaGUgY3VycmVudCBlbnZpcm9ubWVudC4KICAgICAqICBAcGFyYW0gYyAgICAgIFRoZSBjbGFzcyB3aG9zZSBhY2Nlc3NpYmlsaXR5IGlzIGNoZWNrZWQuCiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGlzQWNjZXNzaWJsZShFbnY8QXR0ckNvbnRleHQ+IGVudiwgVHlwZVN5bWJvbCBjKSB7CiAgICAgICAgcmV0dXJuIGlzQWNjZXNzaWJsZShlbnYsIGMsIGZhbHNlKTsKICAgIH0KCiAgICBwdWJsaWMgYm9vbGVhbiBpc0FjY2Vzc2libGUoRW52PEF0dHJDb250ZXh0PiBlbnYsIFR5cGVTeW1ib2wgYywgYm9vbGVhbiBjaGVja0lubmVyKSB7CgogICAgICAgIC8qIDE1LjkuNS4xOiBOb3RlIHRoYXQgaXQgaXMgcG9zc2libGUgZm9yIHRoZSBzaWduYXR1cmUgb2YgdGhlIGFub255bW91cyBjb25zdHJ1Y3RvcgogICAgICAgICAgIHRvIHJlZmVyIHRvIGFuIGluYWNjZXNzaWJsZSB0eXBlCiAgICAgICAgKi8KICAgICAgICBpZiAoZW52LmVuY2xNZXRob2QgIT0gbnVsbCAmJiAoZW52LmVuY2xNZXRob2QubW9kcy5mbGFncyAmIEFOT05DT05TVFIpICE9IDApCiAgICAgICAgICAgIHJldHVybiB0cnVlOwoKICAgICAgICBpZiAoZW52LmluZm8udmlzaXRpbmdTZXJ2aWNlSW1wbGVtZW50YXRpb24gJiYKICAgICAgICAgICAgZW52LnRvcGxldmVsLm1vZGxlID09IGMucGFja2dlKCkubW9kbGUpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICBib29sZWFuIGlzQWNjZXNzaWJsZSA9IGZhbHNlOwogICAgICAgIHN3aXRjaCAoKHNob3J0KShjLmZsYWdzKCkgJiBBY2Nlc3NGbGFncykpIHsKICAgICAgICAgICAgY2FzZSBQUklWQVRFOgogICAgICAgICAgICAgICAgaXNBY2Nlc3NpYmxlID0KICAgICAgICAgICAgICAgICAgICBlbnYuZW5jbENsYXNzLnN5bS5vdXRlcm1vc3RDbGFzcygpID09CiAgICAgICAgICAgICAgICAgICAgYy5vd25lci5vdXRlcm1vc3RDbGFzcygpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGlzQWNjZXNzaWJsZSA9CiAgICAgICAgICAgICAgICAgICAgZW52LnRvcGxldmVsLnBhY2tnZSA9PSBjLm93bmVyIC8vIGZhc3Qgc3BlY2lhbCBjYXNlCiAgICAgICAgICAgICAgICAgICAgfHwKICAgICAgICAgICAgICAgICAgICBlbnYudG9wbGV2ZWwucGFja2dlID09IGMucGFja2dlKCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgZGVmYXVsdDogLy8gZXJyb3IgcmVjb3ZlcnkKICAgICAgICAgICAgICAgIGlzQWNjZXNzaWJsZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBQVUJMSUM6CiAgICAgICAgICAgICAgICBpZiAoYWxsb3dNb2R1bGVzKSB7CiAgICAgICAgICAgICAgICAgICAgTW9kdWxlU3ltYm9sIGN1cnJNb2R1bGUgPSBlbnYudG9wbGV2ZWwubW9kbGU7CiAgICAgICAgICAgICAgICAgICAgY3Vyck1vZHVsZS5jb21wbGV0ZSgpOwogICAgICAgICAgICAgICAgICAgIFBhY2thZ2VTeW1ib2wgcCA9IGMucGFja2dlKCk7CiAgICAgICAgICAgICAgICAgICAgaXNBY2Nlc3NpYmxlID0KICAgICAgICAgICAgICAgICAgICAgICAgKGN1cnJNb2R1bGUgPT0gcC5tb2RsZSkgfHwgY3Vyck1vZHVsZS52aXNpYmxlUGFja2FnZXMuZ2V0KHAuZnVsbG5hbWUpID09IHAgfHwgcCA9PSBzeW1zLnJvb3RQYWNrYWdlOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBpc0FjY2Vzc2libGUgPSB0cnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgUFJPVEVDVEVEOgogICAgICAgICAgICAgICAgaXNBY2Nlc3NpYmxlID0KICAgICAgICAgICAgICAgICAgICBlbnYudG9wbGV2ZWwucGFja2dlID09IGMub3duZXIgLy8gZmFzdCBzcGVjaWFsIGNhc2UKICAgICAgICAgICAgICAgICAgICB8fAogICAgICAgICAgICAgICAgICAgIGVudi50b3BsZXZlbC5wYWNrZ2UgPT0gYy5wYWNrZ2UoKQogICAgICAgICAgICAgICAgICAgIHx8CiAgICAgICAgICAgICAgICAgICAgaXNJbm5lclN1YkNsYXNzKGVudi5lbmNsQ2xhc3Muc3ltLCBjLm93bmVyKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICByZXR1cm4gKGNoZWNrSW5uZXIgPT0gZmFsc2UgfHwgYy50eXBlLmdldEVuY2xvc2luZ1R5cGUoKSA9PSBUeXBlLm5vVHlwZSkgPwogICAgICAgICAgICBpc0FjY2Vzc2libGUgOgogICAgICAgICAgICBpc0FjY2Vzc2libGUgJiYgaXNBY2Nlc3NpYmxlKGVudiwgYy50eXBlLmdldEVuY2xvc2luZ1R5cGUoKSwgY2hlY2tJbm5lcik7CiAgICB9CiAgICAvL3doZXJlCiAgICAgICAgLyoqIElzIGdpdmVuIGNsYXNzIGEgc3ViY2xhc3Mgb2YgZ2l2ZW4gYmFzZSBjbGFzcywgb3IgYW4gaW5uZXIgY2xhc3MKICAgICAgICAgKiAgb2YgYSBzdWJjbGFzcz8KICAgICAgICAgKiAgUmV0dXJuIG51bGwgaWYgbm8gc3VjaCBjbGFzcyBleGlzdHMuCiAgICAgICAgICogIEBwYXJhbSBjICAgICBUaGUgY2xhc3Mgd2hpY2ggaXMgdGhlIHN1YmNsYXNzIG9yIGlzIGNvbnRhaW5lZCBpbiBpdC4KICAgICAgICAgKiAgQHBhcmFtIGJhc2UgIFRoZSBiYXNlIGNsYXNzCiAgICAgICAgICovCiAgICAgICAgcHJpdmF0ZSBib29sZWFuIGlzSW5uZXJTdWJDbGFzcyhDbGFzc1N5bWJvbCBjLCBTeW1ib2wgYmFzZSkgewogICAgICAgICAgICB3aGlsZSAoYyAhPSBudWxsICYmICFjLmlzU3ViQ2xhc3MoYmFzZSwgdHlwZXMpKSB7CiAgICAgICAgICAgICAgICBjID0gYy5vd25lci5lbmNsQ2xhc3MoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gYyAhPSBudWxsOwogICAgICAgIH0KCiAgICBib29sZWFuIGlzQWNjZXNzaWJsZShFbnY8QXR0ckNvbnRleHQ+IGVudiwgVHlwZSB0KSB7CiAgICAgICAgcmV0dXJuIGlzQWNjZXNzaWJsZShlbnYsIHQsIGZhbHNlKTsKICAgIH0KCiAgICBib29sZWFuIGlzQWNjZXNzaWJsZShFbnY8QXR0ckNvbnRleHQ+IGVudiwgVHlwZSB0LCBib29sZWFuIGNoZWNrSW5uZXIpIHsKICAgICAgICByZXR1cm4gKHQuaGFzVGFnKEFSUkFZKSkKICAgICAgICAgICAgPyBpc0FjY2Vzc2libGUoZW52LCB0eXBlcy5jdmFyVXBwZXJCb3VuZCh0eXBlcy5lbGVtdHlwZSh0KSkpCiAgICAgICAgICAgIDogaXNBY2Nlc3NpYmxlKGVudiwgdC50c3ltLCBjaGVja0lubmVyKTsKICAgIH0KCiAgICAvKiogSXMgc3ltYm9sIGFjY2Vzc2libGUgYXMgYSBtZW1iZXIgb2YgZ2l2ZW4gdHlwZSBpbiBnaXZlbiBlbnZpcm9ubWVudD8KICAgICAqICBAcGFyYW0gZW52ICAgIFRoZSBjdXJyZW50IGVudmlyb25tZW50LgogICAgICogIEBwYXJhbSBzaXRlICAgVGhlIHR5cGUgb2Ygd2hpY2ggdGhlIHRlc3RlZCBzeW1ib2wgaXMgcmVnYXJkZWQKICAgICAqICAgICAgICAgICAgICAgIGFzIGEgbWVtYmVyLgogICAgICogIEBwYXJhbSBzeW0gICAgVGhlIHN5bWJvbC4KICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gaXNBY2Nlc3NpYmxlKEVudjxBdHRyQ29udGV4dD4gZW52LCBUeXBlIHNpdGUsIFN5bWJvbCBzeW0pIHsKICAgICAgICByZXR1cm4gaXNBY2Nlc3NpYmxlKGVudiwgc2l0ZSwgc3ltLCBmYWxzZSk7CiAgICB9CiAgICBwdWJsaWMgYm9vbGVhbiBpc0FjY2Vzc2libGUoRW52PEF0dHJDb250ZXh0PiBlbnYsIFR5cGUgc2l0ZSwgU3ltYm9sIHN5bSwgYm9vbGVhbiBjaGVja0lubmVyKSB7CiAgICAgICAgaWYgKHN5bS5uYW1lID09IG5hbWVzLmluaXQgJiYgc3ltLm93bmVyICE9IHNpdGUudHN5bSkgcmV0dXJuIGZhbHNlOwoKICAgICAgICAvKiAxNS45LjUuMTogTm90ZSB0aGF0IGl0IGlzIHBvc3NpYmxlIGZvciB0aGUgc2lnbmF0dXJlIG9mIHRoZSBhbm9ueW1vdXMgY29uc3RydWN0b3IKICAgICAgICAgICB0byByZWZlciB0byBhbiBpbmFjY2Vzc2libGUgdHlwZQogICAgICAgICovCiAgICAgICAgaWYgKGVudi5lbmNsTWV0aG9kICE9IG51bGwgJiYgKGVudi5lbmNsTWV0aG9kLm1vZHMuZmxhZ3MgJiBBTk9OQ09OU1RSKSAhPSAwKQogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKCiAgICAgICAgaWYgKGVudi5pbmZvLnZpc2l0aW5nU2VydmljZUltcGxlbWVudGF0aW9uICYmCiAgICAgICAgICAgIGVudi50b3BsZXZlbC5tb2RsZSA9PSBzeW0ucGFja2dlKCkubW9kbGUpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICBzd2l0Y2ggKChzaG9ydCkoc3ltLmZsYWdzKCkgJiBBY2Nlc3NGbGFncykpIHsKICAgICAgICBjYXNlIFBSSVZBVEU6CiAgICAgICAgICAgIHJldHVybgogICAgICAgICAgICAgICAgKGVudi5lbmNsQ2xhc3Muc3ltID09IHN5bS5vd25lciAvLyBmYXN0IHNwZWNpYWwgY2FzZQogICAgICAgICAgICAgICAgIHx8CiAgICAgICAgICAgICAgICAgZW52LmVuY2xDbGFzcy5zeW0ub3V0ZXJtb3N0Q2xhc3MoKSA9PQogICAgICAgICAgICAgICAgIHN5bS5vd25lci5vdXRlcm1vc3RDbGFzcygpKQogICAgICAgICAgICAgICAgJiYKICAgICAgICAgICAgICAgIHN5bS5pc0luaGVyaXRlZEluKHNpdGUudHN5bSwgdHlwZXMpOwogICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgICAgICAgICAoZW52LnRvcGxldmVsLnBhY2tnZSA9PSBzeW0ub3duZXIub3duZXIgLy8gZmFzdCBzcGVjaWFsIGNhc2UKICAgICAgICAgICAgICAgICB8fAogICAgICAgICAgICAgICAgIGVudi50b3BsZXZlbC5wYWNrZ2UgPT0gc3ltLnBhY2tnZSgpKQogICAgICAgICAgICAgICAgJiYKICAgICAgICAgICAgICAgIGlzQWNjZXNzaWJsZShlbnYsIHNpdGUsIGNoZWNrSW5uZXIpCiAgICAgICAgICAgICAgICAmJgogICAgICAgICAgICAgICAgc3ltLmlzSW5oZXJpdGVkSW4oc2l0ZS50c3ltLCB0eXBlcykKICAgICAgICAgICAgICAgICYmCiAgICAgICAgICAgICAgICBub3RPdmVycmlkZGVuSW4oc2l0ZSwgc3ltKTsKICAgICAgICBjYXNlIFBST1RFQ1RFRDoKICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgICAgICAgICAoZW52LnRvcGxldmVsLnBhY2tnZSA9PSBzeW0ub3duZXIub3duZXIgLy8gZmFzdCBzcGVjaWFsIGNhc2UKICAgICAgICAgICAgICAgICB8fAogICAgICAgICAgICAgICAgIGVudi50b3BsZXZlbC5wYWNrZ2UgPT0gc3ltLnBhY2tnZSgpCiAgICAgICAgICAgICAgICAgfHwKICAgICAgICAgICAgICAgICBpc1Byb3RlY3RlZEFjY2Vzc2libGUoc3ltLCBlbnYuZW5jbENsYXNzLnN5bSwgc2l0ZSkKICAgICAgICAgICAgICAgICB8fAogICAgICAgICAgICAgICAgIC8vIE9LIHRvIHNlbGVjdCBpbnN0YW5jZSBtZXRob2Qgb3IgZmllbGQgZnJvbSAnc3VwZXInIG9yIHR5cGUgbmFtZQogICAgICAgICAgICAgICAgIC8vIChidXQgdHlwZSBuYW1lcyBzaG91bGQgYmUgZGlzYWxsb3dlZCBlbHNld2hlcmUhKQogICAgICAgICAgICAgICAgIGVudi5pbmZvLnNlbGVjdFN1cGVyICYmIChzeW0uZmxhZ3MoKSAmIFNUQVRJQykgPT0gMCAmJiBzeW0ua2luZCAhPSBUWVApCiAgICAgICAgICAgICAgICAmJgogICAgICAgICAgICAgICAgaXNBY2Nlc3NpYmxlKGVudiwgc2l0ZSwgY2hlY2tJbm5lcikKICAgICAgICAgICAgICAgICYmCiAgICAgICAgICAgICAgICBub3RPdmVycmlkZGVuSW4oc2l0ZSwgc3ltKTsKICAgICAgICBkZWZhdWx0OiAvLyB0aGlzIGNhc2UgaW5jbHVkZXMgZXJyb25lb3VzIGNvbWJpbmF0aW9ucyBhcyB3ZWxsCiAgICAgICAgICAgIHJldHVybiBpc0FjY2Vzc2libGUoZW52LCBzaXRlLCBjaGVja0lubmVyKSAmJiBub3RPdmVycmlkZGVuSW4oc2l0ZSwgc3ltKTsKICAgICAgICB9CiAgICB9CiAgICAvL3doZXJlCiAgICAvKiBgc3ltJyBpcyBhY2Nlc3NpYmxlIG9ubHkgaWYgbm90IG92ZXJyaWRkZW4gYnkKICAgICAqIGFub3RoZXIgc3ltYm9sIHdoaWNoIGlzIGEgbWVtYmVyIG9mIGBzaXRlJwogICAgICogKGJlY2F1c2UsIGlmIGl0IGlzIG92ZXJyaWRkZW4sIGBzeW0nIGlzIG5vdCBzdHJpY3RseQogICAgICogc3BlYWtpbmcgYSBtZW1iZXIgb2YgYHNpdGUnKS4gQSBwb2x5bW9ycGhpYyBzaWduYXR1cmUgbWV0aG9kCiAgICAgKiBjYW5ub3QgYmUgb3ZlcnJpZGRlbiAoZS5nLiBNSC5pbnZva2VFeGFjdChPYmplY3RbXSkpLgogICAgICovCiAgICBwcml2YXRlIGJvb2xlYW4gbm90T3ZlcnJpZGRlbkluKFR5cGUgc2l0ZSwgU3ltYm9sIHN5bSkgewogICAgICAgIGlmIChzeW0ua2luZCAhPSBNVEggfHwgc3ltLmlzQ29uc3RydWN0b3IoKSB8fCBzeW0uaXNTdGF0aWMoKSkKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIFN5bWJvbCBzMiA9ICgoTWV0aG9kU3ltYm9sKXN5bSkuaW1wbGVtZW50YXRpb24oc2l0ZS50c3ltLCB0eXBlcywgdHJ1ZSk7CiAgICAgICAgICAgIHJldHVybiAoczIgPT0gbnVsbCB8fCBzMiA9PSBzeW0gfHwgc3ltLm93bmVyID09IHMyLm93bmVyIHx8CiAgICAgICAgICAgICAgICAgICAgIXR5cGVzLmlzU3ViU2lnbmF0dXJlKHR5cGVzLm1lbWJlclR5cGUoc2l0ZSwgczIpLCB0eXBlcy5tZW1iZXJUeXBlKHNpdGUsIHN5bSkpKTsKICAgICAgICB9CiAgICB9CiAgICAvL3doZXJlCiAgICAgICAgLyoqIElzIGdpdmVuIHByb3RlY3RlZCBzeW1ib2wgYWNjZXNzaWJsZSBpZiBpdCBpcyBzZWxlY3RlZCBmcm9tIGdpdmVuIHNpdGUKICAgICAgICAgKiAgYW5kIHRoZSBzZWxlY3Rpb24gdGFrZXMgcGxhY2UgaW4gZ2l2ZW4gY2xhc3M/CiAgICAgICAgICogIEBwYXJhbSBzeW0gICAgIFRoZSBzeW1ib2wgd2l0aCBwcm90ZWN0ZWQgYWNjZXNzCiAgICAgICAgICogIEBwYXJhbSBjICAgICAgIFRoZSBjbGFzcyB3aGVyZSB0aGUgYWNjZXNzIHRha2VzIHBsYWNlCiAgICAgICAgICogIEBzaXRlICAgICAgICAgIFRoZSB0eXBlIG9mIHRoZSBxdWFsaWZpZXIKICAgICAgICAgKi8KICAgICAgICBwcml2YXRlCiAgICAgICAgYm9vbGVhbiBpc1Byb3RlY3RlZEFjY2Vzc2libGUoU3ltYm9sIHN5bSwgQ2xhc3NTeW1ib2wgYywgVHlwZSBzaXRlKSB7CiAgICAgICAgICAgIFR5cGUgbmV3U2l0ZSA9IHNpdGUuaGFzVGFnKFRZUEVWQVIpID8gc2l0ZS5nZXRVcHBlckJvdW5kKCkgOiBzaXRlOwogICAgICAgICAgICB3aGlsZSAoYyAhPSBudWxsICYmCiAgICAgICAgICAgICAgICAgICAhKGMuaXNTdWJDbGFzcyhzeW0ub3duZXIsIHR5cGVzKSAmJgogICAgICAgICAgICAgICAgICAgICAoYy5mbGFncygpICYgSU5URVJGQUNFKSA9PSAwICYmCiAgICAgICAgICAgICAgICAgICAgIC8vIEluIEpMUyAyZSA2LjYuMi4xLCB0aGUgc3ViY2xhc3MgcmVzdHJpY3Rpb24gYXBwbGllcwogICAgICAgICAgICAgICAgICAgICAvLyBvbmx5IHRvIGluc3RhbmNlIGZpZWxkcyBhbmQgbWV0aG9kcyAtLSB0eXBlcyBhcmUgZXhjbHVkZWQKICAgICAgICAgICAgICAgICAgICAgLy8gcmVnYXJkbGVzcyBvZiB3aGV0aGVyIHRoZXkgYXJlIGRlY2xhcmVkICdzdGF0aWMnIG9yIG5vdC4KICAgICAgICAgICAgICAgICAgICAgKChzeW0uZmxhZ3MoKSAmIFNUQVRJQykgIT0gMCB8fCBzeW0ua2luZCA9PSBUWVAgfHwgbmV3U2l0ZS50c3ltLmlzU3ViQ2xhc3MoYywgdHlwZXMpKSkpCiAgICAgICAgICAgICAgICBjID0gYy5vd25lci5lbmNsQ2xhc3MoKTsKICAgICAgICAgICAgcmV0dXJuIGMgIT0gbnVsbDsKICAgICAgICB9CgogICAgLyoqCiAgICAgKiBQZXJmb3JtcyBhIHJlY3Vyc2l2ZSBzY2FuIG9mIGEgdHlwZSBsb29raW5nIGZvciBhY2Nlc3NpYmlsaXR5IHByb2JsZW1zCiAgICAgKiBmcm9tIGN1cnJlbnQgYXR0cmlidXRpb24gZW52aXJvbm1lbnQKICAgICAqLwogICAgdm9pZCBjaGVja0FjY2Vzc2libGVUeXBlKEVudjxBdHRyQ29udGV4dD4gZW52LCBUeXBlIHQpIHsKICAgICAgICBhY2Nlc3NpYmlsaXR5Q2hlY2tlci52aXNpdCh0LCBlbnYpOwogICAgfQoKICAgIC8qKgogICAgICogQWNjZXNzaWJpbGl0eSB0eXBlLXZpc2l0b3IKICAgICAqLwogICAgVHlwZXMuU2ltcGxlVmlzaXRvcjxWb2lkLCBFbnY8QXR0ckNvbnRleHQ+PiBhY2Nlc3NpYmlsaXR5Q2hlY2tlciA9CiAgICAgICAgICAgIG5ldyBUeXBlcy5TaW1wbGVWaXNpdG9yPFZvaWQsIEVudjxBdHRyQ29udGV4dD4+KCkgewoKICAgICAgICB2b2lkIHZpc2l0KExpc3Q8VHlwZT4gdHMsIEVudjxBdHRyQ29udGV4dD4gZW52KSB7CiAgICAgICAgICAgIGZvciAoVHlwZSB0IDogdHMpIHsKICAgICAgICAgICAgICAgIHZpc2l0KHQsIGVudik7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHB1YmxpYyBWb2lkIHZpc2l0VHlwZShUeXBlIHQsIEVudjxBdHRyQ29udGV4dD4gZW52KSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFZvaWQgdmlzaXRBcnJheVR5cGUoQXJyYXlUeXBlIHQsIEVudjxBdHRyQ29udGV4dD4gZW52KSB7CiAgICAgICAgICAgIHZpc2l0KHQuZWxlbXR5cGUsIGVudik7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFZvaWQgdmlzaXRDbGFzc1R5cGUoQ2xhc3NUeXBlIHQsIEVudjxBdHRyQ29udGV4dD4gZW52KSB7CiAgICAgICAgICAgIHZpc2l0KHQuZ2V0VHlwZUFyZ3VtZW50cygpLCBlbnYpOwogICAgICAgICAgICBpZiAoIWlzQWNjZXNzaWJsZShlbnYsIHQsIHRydWUpKSB7CiAgICAgICAgICAgICAgICBhY2Nlc3NCYXNlKG5ldyBBY2Nlc3NFcnJvcihlbnYsIG51bGwsIHQudHN5bSksIGVudi50cmVlLnBvcygpLCBlbnYuZW5jbENsYXNzLnN5bSwgdCwgdC50c3ltLm5hbWUsIHRydWUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFZvaWQgdmlzaXRXaWxkY2FyZFR5cGUoV2lsZGNhcmRUeXBlIHQsIEVudjxBdHRyQ29udGV4dD4gZW52KSB7CiAgICAgICAgICAgIHZpc2l0KHQudHlwZSwgZW52KTsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgVm9pZCB2aXNpdE1ldGhvZFR5cGUoTWV0aG9kVHlwZSB0LCBFbnY8QXR0ckNvbnRleHQ+IGVudikgewogICAgICAgICAgICB2aXNpdCh0LmdldFBhcmFtZXRlclR5cGVzKCksIGVudik7CiAgICAgICAgICAgIHZpc2l0KHQuZ2V0UmV0dXJuVHlwZSgpLCBlbnYpOwogICAgICAgICAgICB2aXNpdCh0LmdldFRocm93blR5cGVzKCksIGVudik7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KICAgIH07CgogICAgLyoqIFRyeSB0byBpbnN0YW50aWF0ZSB0aGUgdHlwZSBvZiBhIG1ldGhvZCBzbyB0aGF0IGl0IGZpdHMKICAgICAqICBnaXZlbiB0eXBlIGFyZ3VtZW50cyBhbmQgYXJndW1lbnQgdHlwZXMuIElmIHN1Y2Nlc3NmdWwsIHJldHVybgogICAgICogIHRoZSBtZXRob2QncyBpbnN0YW50aWF0ZWQgdHlwZSwgZWxzZSByZXR1cm4gbnVsbC4KICAgICAqICBUaGUgaW5zdGFudGlhdGlvbiB3aWxsIHRha2UgaW50byBhY2NvdW50IGFuIGFkZGl0aW9uYWwgbGVhZGluZwogICAgICogIGZvcm1hbCBwYXJhbWV0ZXIgaWYgdGhlIG1ldGhvZCBpcyBhbiBpbnN0YW5jZSBtZXRob2Qgc2VlbiBhcyBhIG1lbWJlcgogICAgICogIG9mIGFuIHVuZGVyIGRldGVybWluZWQgc2l0ZS4gSW4gdGhpcyBjYXNlLCB3ZSB0cmVhdCBzaXRlIGFzIGFuIGFkZGl0aW9uYWwKICAgICAqICBwYXJhbWV0ZXIgYW5kIHRoZSBwYXJhbWV0ZXJzIG9mIHRoZSBjbGFzcyBjb250YWluaW5nIHRoZSBtZXRob2QgYXMKICAgICAqICBhZGRpdGlvbmFsIHR5cGUgdmFyaWFibGVzIHRoYXQgZ2V0IGluc3RhbnRpYXRlZC4KICAgICAqCiAgICAgKiAgQHBhcmFtIGVudiAgICAgICAgIFRoZSBjdXJyZW50IGVudmlyb25tZW50CiAgICAgKiAgQHBhcmFtIHNpdGUgICAgICAgIFRoZSB0eXBlIG9mIHdoaWNoIHRoZSBtZXRob2QgaXMgYSBtZW1iZXIuCiAgICAgKiAgQHBhcmFtIG0gICAgICAgICAgIFRoZSBtZXRob2Qgc3ltYm9sLgogICAgICogIEBwYXJhbSBhcmd0eXBlcyAgICBUaGUgaW52b2NhdGlvbidzIGdpdmVuIHZhbHVlIGFyZ3VtZW50cy4KICAgICAqICBAcGFyYW0gdHlwZWFyZ3R5cGVzICAgIFRoZSBpbnZvY2F0aW9uJ3MgZ2l2ZW4gdHlwZSBhcmd1bWVudHMuCiAgICAgKiAgQHBhcmFtIGFsbG93Qm94aW5nIEFsbG93IGJveGluZyBjb252ZXJzaW9ucyBvZiBhcmd1bWVudHMuCiAgICAgKiAgQHBhcmFtIHVzZVZhcmFyZ3MgQm94IHRyYWlsaW5nIGFyZ3VtZW50cyBpbnRvIGFuIGFycmF5IGZvciB2YXJhcmdzLgogICAgICovCiAgICBUeXBlIHJhd0luc3RhbnRpYXRlKEVudjxBdHRyQ29udGV4dD4gZW52LAogICAgICAgICAgICAgICAgICAgICAgICBUeXBlIHNpdGUsCiAgICAgICAgICAgICAgICAgICAgICAgIFN5bWJvbCBtLAogICAgICAgICAgICAgICAgICAgICAgICBSZXN1bHRJbmZvIHJlc3VsdEluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgIExpc3Q8VHlwZT4gYXJndHlwZXMsCiAgICAgICAgICAgICAgICAgICAgICAgIExpc3Q8VHlwZT4gdHlwZWFyZ3R5cGVzLAogICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGFsbG93Qm94aW5nLAogICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIHVzZVZhcmFyZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgIFdhcm5lciB3YXJuKSB0aHJvd3MgSW5mZXIuSW5mZXJlbmNlRXhjZXB0aW9uIHsKICAgICAgICBUeXBlIG10ID0gdHlwZXMubWVtYmVyVHlwZShzaXRlLCBtKTsKICAgICAgICAvLyB0dmFycyBpcyB0aGUgbGlzdCBvZiBmb3JtYWwgdHlwZSB2YXJpYWJsZXMgZm9yIHdoaWNoIHR5cGUgYXJndW1lbnRzCiAgICAgICAgLy8gbmVlZCB0byBpbmZlcnJlZC4KICAgICAgICBMaXN0PFR5cGU+IHR2YXJzID0gTGlzdC5uaWwoKTsKICAgICAgICBpZiAodHlwZWFyZ3R5cGVzID09IG51bGwpIHR5cGVhcmd0eXBlcyA9IExpc3QubmlsKCk7CiAgICAgICAgaWYgKCFtdC5oYXNUYWcoRk9SQUxMKSAmJiB0eXBlYXJndHlwZXMubm9uRW1wdHkoKSkgewogICAgICAgICAgICAvLyBUaGlzIGlzIG5vdCBhIHBvbHltb3JwaGljIG1ldGhvZCwgYnV0IHR5cGVhcmdzIGFyZSBzdXBwbGllZAogICAgICAgICAgICAvLyB3aGljaCBpcyBmaW5lLCBzZWUgSkxTIDE1LjEyLjIuMQogICAgICAgIH0gZWxzZSBpZiAobXQuaGFzVGFnKEZPUkFMTCkgJiYgdHlwZWFyZ3R5cGVzLm5vbkVtcHR5KCkpIHsKICAgICAgICAgICAgRm9yQWxsIHBtdCA9IChGb3JBbGwpIG10OwogICAgICAgICAgICBpZiAodHlwZWFyZ3R5cGVzLmxlbmd0aCgpICE9IHBtdC50dmFycy5sZW5ndGgoKSkKICAgICAgICAgICAgICAgICAvLyBub3QgZW5vdWdoIGFyZ3MKICAgICAgICAgICAgICAgIHRocm93IGluYXBwbGljYWJsZU1ldGhvZEV4Y2VwdGlvbi5zZXRNZXNzYWdlKCJ3cm9uZy5udW1iZXIudHlwZS5hcmdzIiwgSW50ZWdlci50b1N0cmluZyhwbXQudHZhcnMubGVuZ3RoKCkpKTsKICAgICAgICAgICAgLy8gQ2hlY2sgdHlwZSBhcmd1bWVudHMgYXJlIHdpdGhpbiBib3VuZHMKICAgICAgICAgICAgTGlzdDxUeXBlPiBmb3JtYWxzID0gcG10LnR2YXJzOwogICAgICAgICAgICBMaXN0PFR5cGU+IGFjdHVhbHMgPSB0eXBlYXJndHlwZXM7CiAgICAgICAgICAgIHdoaWxlIChmb3JtYWxzLm5vbkVtcHR5KCkgJiYgYWN0dWFscy5ub25FbXB0eSgpKSB7CiAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IGJvdW5kcyA9IHR5cGVzLnN1YnN0KHR5cGVzLmdldEJvdW5kcygoVHlwZVZhcilmb3JtYWxzLmhlYWQpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwbXQudHZhcnMsIHR5cGVhcmd0eXBlcyk7CiAgICAgICAgICAgICAgICBmb3IgKDsgYm91bmRzLm5vbkVtcHR5KCk7IGJvdW5kcyA9IGJvdW5kcy50YWlsKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCF0eXBlcy5pc1N1YnR5cGVVbmNoZWNrZWQoYWN0dWFscy5oZWFkLCBib3VuZHMuaGVhZCwgd2FybikpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IGluYXBwbGljYWJsZU1ldGhvZEV4Y2VwdGlvbi5zZXRNZXNzYWdlKCJleHBsaWNpdC5wYXJhbS5kby5ub3QuY29uZm9ybS50by5ib3VuZHMiLGFjdHVhbHMuaGVhZCwgYm91bmRzKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGZvcm1hbHMgPSBmb3JtYWxzLnRhaWw7CiAgICAgICAgICAgICAgICBhY3R1YWxzID0gYWN0dWFscy50YWlsOwogICAgICAgICAgICB9CiAgICAgICAgICAgIG10ID0gdHlwZXMuc3Vic3QocG10LnF0eXBlLCBwbXQudHZhcnMsIHR5cGVhcmd0eXBlcyk7CiAgICAgICAgfSBlbHNlIGlmIChtdC5oYXNUYWcoRk9SQUxMKSkgewogICAgICAgICAgICBGb3JBbGwgcG10ID0gKEZvckFsbCkgbXQ7CiAgICAgICAgICAgIExpc3Q8VHlwZT4gdHZhcnMxID0gdHlwZXMubmV3SW5zdGFuY2VzKHBtdC50dmFycyk7CiAgICAgICAgICAgIHR2YXJzID0gdHZhcnMuYXBwZW5kTGlzdCh0dmFyczEpOwogICAgICAgICAgICBtdCA9IHR5cGVzLnN1YnN0KHBtdC5xdHlwZSwgcG10LnR2YXJzLCB0dmFyczEpOwogICAgICAgIH0KCiAgICAgICAgLy8gZmluZCBvdXQgd2hldGhlciB3ZSBuZWVkIHRvIGdvIHRoZSBzbG93IHJvdXRlIHZpYSBpbmZlcgogICAgICAgIGJvb2xlYW4gaW5zdE5lZWRlZCA9IHR2YXJzLnRhaWwgIT0gbnVsbDsgLyppbmxpbmVkOiB0dmFycy5ub25FbXB0eSgpKi8KICAgICAgICBmb3IgKExpc3Q8VHlwZT4gbCA9IGFyZ3R5cGVzOwogICAgICAgICAgICAgbC50YWlsICE9IG51bGwvKmlubGluZWQ6IGwubm9uRW1wdHkoKSovICYmICFpbnN0TmVlZGVkOwogICAgICAgICAgICAgbCA9IGwudGFpbCkgewogICAgICAgICAgICBpZiAobC5oZWFkLmhhc1RhZyhGT1JBTEwpKSBpbnN0TmVlZGVkID0gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIGlmIChpbnN0TmVlZGVkKSB7CiAgICAgICAgICAgIHJldHVybiBpbmZlci5pbnN0YW50aWF0ZU1ldGhvZChlbnYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR2YXJzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoTWV0aG9kVHlwZSltdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0SW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKE1ldGhvZFN5bWJvbCltLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmd0eXBlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWxsb3dCb3hpbmcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVzZVZhcmFyZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRSZXNvbHV0aW9uQ29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2Fybik7CiAgICAgICAgfQoKICAgICAgICBEZWZlcnJlZEF0dHIuRGVmZXJyZWRBdHRyQ29udGV4dCBkYyA9IGN1cnJlbnRSZXNvbHV0aW9uQ29udGV4dC5kZWZlcnJlZEF0dHJDb250ZXh0KG0sIGluZmVyLmVtcHR5Q29udGV4dCwgcmVzdWx0SW5mbywgd2Fybik7CiAgICAgICAgY3VycmVudFJlc29sdXRpb25Db250ZXh0Lm1ldGhvZENoZWNrLmFyZ3VtZW50c0FjY2VwdGFibGUoZW52LCBkYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmd0eXBlcywgbXQuZ2V0UGFyYW1ldGVyVHlwZXMoKSwgd2Fybik7CiAgICAgICAgZGMuY29tcGxldGUoKTsKICAgICAgICByZXR1cm4gbXQ7CiAgICB9CgogICAgVHlwZSBjaGVja01ldGhvZChFbnY8QXR0ckNvbnRleHQ+IGVudiwKICAgICAgICAgICAgICAgICAgICAgVHlwZSBzaXRlLAogICAgICAgICAgICAgICAgICAgICBTeW1ib2wgbSwKICAgICAgICAgICAgICAgICAgICAgUmVzdWx0SW5mbyByZXN1bHRJbmZvLAogICAgICAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IGFyZ3R5cGVzLAogICAgICAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IHR5cGVhcmd0eXBlcywKICAgICAgICAgICAgICAgICAgICAgV2FybmVyIHdhcm4pIHsKICAgICAgICBNZXRob2RSZXNvbHV0aW9uQ29udGV4dCBwcmV2Q29udGV4dCA9IGN1cnJlbnRSZXNvbHV0aW9uQ29udGV4dDsKICAgICAgICB0cnkgewogICAgICAgICAgICBjdXJyZW50UmVzb2x1dGlvbkNvbnRleHQgPSBuZXcgTWV0aG9kUmVzb2x1dGlvbkNvbnRleHQoKTsKICAgICAgICAgICAgY3VycmVudFJlc29sdXRpb25Db250ZXh0LmF0dHJNb2RlID0gKHJlc3VsdEluZm8ucHQgPT0gSW5mZXIuYW55UG9seSkgPwogICAgICAgICAgICAgICAgICAgIEF0dHJNb2RlLlNQRUNVTEFUSVZFIDogRGVmZXJyZWRBdHRyLkF0dHJNb2RlLkNIRUNLOwogICAgICAgICAgICBpZiAoZW52LnRyZWUuaGFzVGFnKEpDVHJlZS5UYWcuUkVGRVJFTkNFKSkgewogICAgICAgICAgICAgICAgLy9tZXRob2QvY29uc3RydWN0b3IgcmVmZXJlbmNlcyBuZWVkIHNwZWNpYWwgY2hlY2sgY2xhc3MKICAgICAgICAgICAgICAgIC8vdG8gaGFuZGxlIGluZmVyZW5jZSB2YXJpYWJsZXMgaW4gJ2FyZ3R5cGVzJyAobWlnaHQgaGFwcGVuCiAgICAgICAgICAgICAgICAvL2R1cmluZyBhbiB1bnN0aWNraW5nIHJvdW5kKQogICAgICAgICAgICAgICAgY3VycmVudFJlc29sdXRpb25Db250ZXh0Lm1ldGhvZENoZWNrID0KICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE1ldGhvZFJlZmVyZW5jZUNoZWNrKHJlc3VsdEluZm8uY2hlY2tDb250ZXh0LmluZmVyZW5jZUNvbnRleHQoKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgTWV0aG9kUmVzb2x1dGlvblBoYXNlIHN0ZXAgPSBjdXJyZW50UmVzb2x1dGlvbkNvbnRleHQuc3RlcCA9IGVudi5pbmZvLnBlbmRpbmdSZXNvbHV0aW9uUGhhc2U7CiAgICAgICAgICAgIHJldHVybiByYXdJbnN0YW50aWF0ZShlbnYsIHNpdGUsIG0sIHJlc3VsdEluZm8sIGFyZ3R5cGVzLCB0eXBlYXJndHlwZXMsCiAgICAgICAgICAgICAgICAgICAgc3RlcC5pc0JveGluZ1JlcXVpcmVkKCksIHN0ZXAuaXNWYXJhcmdzUmVxdWlyZWQoKSwgd2Fybik7CiAgICAgICAgfQogICAgICAgIGZpbmFsbHkgewogICAgICAgICAgICBjdXJyZW50UmVzb2x1dGlvbkNvbnRleHQgPSBwcmV2Q29udGV4dDsKICAgICAgICB9CiAgICB9CgogICAgLyoqIFNhbWUgYnV0IHJldHVybnMgbnVsbCBpbnN0ZWFkIHRocm93aW5nIGEgTm9JbnN0YW5jZUV4Y2VwdGlvbgogICAgICovCiAgICBUeXBlIGluc3RhbnRpYXRlKEVudjxBdHRyQ29udGV4dD4gZW52LAogICAgICAgICAgICAgICAgICAgICBUeXBlIHNpdGUsCiAgICAgICAgICAgICAgICAgICAgIFN5bWJvbCBtLAogICAgICAgICAgICAgICAgICAgICBSZXN1bHRJbmZvIHJlc3VsdEluZm8sCiAgICAgICAgICAgICAgICAgICAgIExpc3Q8VHlwZT4gYXJndHlwZXMsCiAgICAgICAgICAgICAgICAgICAgIExpc3Q8VHlwZT4gdHlwZWFyZ3R5cGVzLAogICAgICAgICAgICAgICAgICAgICBib29sZWFuIGFsbG93Qm94aW5nLAogICAgICAgICAgICAgICAgICAgICBib29sZWFuIHVzZVZhcmFyZ3MsCiAgICAgICAgICAgICAgICAgICAgIFdhcm5lciB3YXJuKSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgcmV0dXJuIHJhd0luc3RhbnRpYXRlKGVudiwgc2l0ZSwgbSwgcmVzdWx0SW5mbywgYXJndHlwZXMsIHR5cGVhcmd0eXBlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFsbG93Qm94aW5nLCB1c2VWYXJhcmdzLCB3YXJuKTsKICAgICAgICB9IGNhdGNoIChJbmFwcGxpY2FibGVNZXRob2RFeGNlcHRpb24gZXgpIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogVGhpcyBpbnRlcmZhY2UgZGVmaW5lcyBhbiBlbnRyeSBwb2ludCB0aGF0IHNob3VsZCBiZSB1c2VkIHRvIHBlcmZvcm0gYQogICAgICogbWV0aG9kIGNoZWNrLiBBIG1ldGhvZCBjaGVjayB1c3VhbGx5IGNvbnNpc3QgaW4gZGV0ZXJtaW5pbmcgYXMgdG8gd2hldGhlcgogICAgICogYSBzZXQgb2YgdHlwZXMgKGFjdHVhbHMpIGlzIGNvbXBhdGlibGUgd2l0aCBhbm90aGVyIHNldCBvZiB0eXBlcyAoZm9ybWFscykuCiAgICAgKiBTaW5jZSB0aGUgbm90aW9uIG9mIGNvbXBhdGliaWxpdHkgY2FuIHZhcnkgZGVwZW5kaW5nIG9uIHRoZSBjaXJjdW1zdGFuY2VzLAogICAgICogdGhpcyBpbnRlcmZhY2VzIGFsbG93cyB0byBlYXNpbHkgYWRkIG5ldyBwbHVnZ2FibGUgbWV0aG9kIGNoZWNrIHJvdXRpbmVzLgogICAgICovCiAgICBpbnRlcmZhY2UgTWV0aG9kQ2hlY2sgewogICAgICAgIC8qKgogICAgICAgICAqIE1haW4gbWV0aG9kIGNoZWNrIHJvdXRpbmUuIEEgbWV0aG9kIGNoZWNrIHVzdWFsbHkgY29uc2lzdCBpbiBkZXRlcm1pbmluZwogICAgICAgICAqIGFzIHRvIHdoZXRoZXIgYSBzZXQgb2YgdHlwZXMgKGFjdHVhbHMpIGlzIGNvbXBhdGlibGUgd2l0aCBhbm90aGVyIHNldCBvZgogICAgICAgICAqIHR5cGVzIChmb3JtYWxzKS4gSWYgYW4gaW5jb21wYXRpYmlsaXR5IGlzIGZvdW5kLCBhbiB1bmNoZWNrZWQgZXhjZXB0aW9uCiAgICAgICAgICogaXMgYXNzdW1lZCB0byBiZSB0aHJvd24uCiAgICAgICAgICovCiAgICAgICAgdm9pZCBhcmd1bWVudHNBY2NlcHRhYmxlKEVudjxBdHRyQ29udGV4dD4gZW52LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERlZmVycmVkQXR0ckNvbnRleHQgZGVmZXJyZWRBdHRyQ29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IGFyZ3R5cGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExpc3Q8VHlwZT4gZm9ybWFscywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXYXJuZXIgd2Fybik7CgogICAgICAgIC8qKgogICAgICAgICAqIFJldHJpZXZlIHRoZSBtZXRob2QgY2hlY2sgb2JqZWN0IHRoYXQgd2lsbCBiZSB1c2VkIGR1cmluZyBhCiAgICAgICAgICogbW9zdCBzcGVjaWZpYyBjaGVjay4KICAgICAgICAgKi8KICAgICAgICBNZXRob2RDaGVjayBtb3N0U3BlY2lmaWNDaGVjayhMaXN0PFR5cGU+IGFjdHVhbHMpOwogICAgfQoKICAgIC8qKgogICAgICogSGVscGVyIGVudW0gZGVmaW5pbmcgYWxsIG1ldGhvZCBjaGVjayBkaWFnbm9zdGljcyAodXNlZCBieSByZXNvbHZlTWV0aG9kQ2hlY2spLgogICAgICovCiAgICBlbnVtIE1ldGhvZENoZWNrRGlhZyB7CiAgICAgICAgLyoqCiAgICAgICAgICogQWN0dWFscyBhbmQgZm9ybWFscyBkaWZmZXJzIGluIGxlbmd0aC4KICAgICAgICAgKi8KICAgICAgICBBUklUWV9NSVNNQVRDSCgiYXJnLmxlbmd0aC5taXNtYXRjaCIsICJpbmZlci5hcmcubGVuZ3RoLm1pc21hdGNoIiksCiAgICAgICAgLyoqCiAgICAgICAgICogQW4gYWN0dWFsIGlzIGluY29tcGF0aWJsZSB3aXRoIGEgZm9ybWFsLgogICAgICAgICAqLwogICAgICAgIEFSR19NSVNNQVRDSCgibm8uY29uZm9ybWluZy5hc3NpZ25tZW50LmV4aXN0cyIsICJpbmZlci5uby5jb25mb3JtaW5nLmFzc2lnbm1lbnQuZXhpc3RzIiksCiAgICAgICAgLyoqCiAgICAgICAgICogQW4gYWN0dWFsIGlzIGluY29tcGF0aWJsZSB3aXRoIHRoZSB2YXJhcmdzIGVsZW1lbnQgdHlwZS4KICAgICAgICAgKi8KICAgICAgICBWQVJBUkdfTUlTTUFUQ0goInZhcmFyZ3MuYXJndW1lbnQubWlzbWF0Y2giLCAiaW5mZXIudmFyYXJncy5hcmd1bWVudC5taXNtYXRjaCIpLAogICAgICAgIC8qKgogICAgICAgICAqIFRoZSB2YXJhcmdzIGVsZW1lbnQgdHlwZSBpcyBpbmFjY2Vzc2libGUuCiAgICAgICAgICovCiAgICAgICAgSU5BQ0NFU1NJQkxFX1ZBUkFSR1MoImluYWNjZXNzaWJsZS52YXJhcmdzLnR5cGUiLCAiaW5hY2Nlc3NpYmxlLnZhcmFyZ3MudHlwZSIpOwoKICAgICAgICBmaW5hbCBTdHJpbmcgYmFzaWNLZXk7CiAgICAgICAgZmluYWwgU3RyaW5nIGluZmVyS2V5OwoKICAgICAgICBNZXRob2RDaGVja0RpYWcoU3RyaW5nIGJhc2ljS2V5LCBTdHJpbmcgaW5mZXJLZXkpIHsKICAgICAgICAgICAgdGhpcy5iYXNpY0tleSA9IGJhc2ljS2V5OwogICAgICAgICAgICB0aGlzLmluZmVyS2V5ID0gaW5mZXJLZXk7CiAgICAgICAgfQoKICAgICAgICBTdHJpbmcgcmVnZXgoKSB7CiAgICAgICAgICAgIHJldHVybiBTdHJpbmcuZm9ybWF0KCIoW2Etel0qXFwuKSooJXN8JXMpIiwgYmFzaWNLZXksIGluZmVyS2V5KTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBEdW1teSBtZXRob2QgY2hlY2sgb2JqZWN0LiBBbGwgbWV0aG9kcyBhcmUgZGVlbWVkIGFwcGxpY2FibGUsIHJlZ2FyZGxlc3MKICAgICAqIG9mIHRoZWlyIGZvcm1hbCBwYXJhbWV0ZXIgdHlwZXMuCiAgICAgKi8KICAgIE1ldGhvZENoZWNrIG5pbE1ldGhvZENoZWNrID0gbmV3IE1ldGhvZENoZWNrKCkgewogICAgICAgIHB1YmxpYyB2b2lkIGFyZ3VtZW50c0FjY2VwdGFibGUoRW52PEF0dHJDb250ZXh0PiBlbnYsIERlZmVycmVkQXR0ckNvbnRleHQgZGVmZXJyZWRBdHRyQ29udGV4dCwgTGlzdDxUeXBlPiBhcmd0eXBlcywgTGlzdDxUeXBlPiBmb3JtYWxzLCBXYXJuZXIgd2FybikgewogICAgICAgICAgICAvL2RvIG5vdGhpbmcgLSBtZXRob2QgYWx3YXlzIGFwcGxpY2FibGUgcmVnYXJkbGVzcyBvZiBhY3R1YWxzCiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgTWV0aG9kQ2hlY2sgbW9zdFNwZWNpZmljQ2hlY2soTGlzdDxUeXBlPiBhY3R1YWxzKSB7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgIH07CgogICAgLyoqCiAgICAgKiBCYXNlIGNsYXNzIGZvciAncmVhbCcgbWV0aG9kIGNoZWNrcy4gVGhlIGNsYXNzIGRlZmluZXMgdGhlIGxvZ2ljIGZvcgogICAgICogaXRlcmF0aW5nIHRocm91Z2ggZm9ybWFscyBhbmQgYWN0dWFscyBhbmQgcHJvdmlkZXMgYW5kIGVudHJ5IHBvaW50CiAgICAgKiB0aGF0IGNhbiBiZSB1c2VkIGJ5IHN1YmNsYXNzZXMgaW4gb3JkZXIgdG8gZGVmaW5lIHRoZSBhY3R1YWwgY2hlY2sgbG9naWMuCiAgICAgKi8KICAgIGFic3RyYWN0IGNsYXNzIEFic3RyYWN0TWV0aG9kQ2hlY2sgaW1wbGVtZW50cyBNZXRob2RDaGVjayB7CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgYXJndW1lbnRzQWNjZXB0YWJsZShmaW5hbCBFbnY8QXR0ckNvbnRleHQ+IGVudiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRGVmZXJyZWRBdHRyQ29udGV4dCBkZWZlcnJlZEF0dHJDb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IGFyZ3R5cGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IGZvcm1hbHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdhcm5lciB3YXJuKSB7CiAgICAgICAgICAgIC8vc2hvdWxkIHdlIGV4cGFuZCBmb3JtYWxzPwogICAgICAgICAgICBib29sZWFuIHVzZVZhcmFyZ3MgPSBkZWZlcnJlZEF0dHJDb250ZXh0LnBoYXNlLmlzVmFyYXJnc1JlcXVpcmVkKCk7CiAgICAgICAgICAgIEpDVHJlZSBjYWxsVHJlZSA9IHRyZWVGb3JEaWFnbm9zdGljcyhlbnYpOwogICAgICAgICAgICBMaXN0PEpDRXhwcmVzc2lvbj4gdHJlZXMgPSBUcmVlSW5mby5hcmdzKGNhbGxUcmVlKTsKCiAgICAgICAgICAgIC8vaW5mZXJlbmNlIGNvbnRleHQgdXNlZCBkdXJpbmcgdGhpcyBtZXRob2QgY2hlY2sKICAgICAgICAgICAgSW5mZXJlbmNlQ29udGV4dCBpbmZlcmVuY2VDb250ZXh0ID0gZGVmZXJyZWRBdHRyQ29udGV4dC5pbmZlcmVuY2VDb250ZXh0OwoKICAgICAgICAgICAgVHlwZSB2YXJhcmdzRm9ybWFsID0gdXNlVmFyYXJncyA/IGZvcm1hbHMubGFzdCgpIDogbnVsbDsKCiAgICAgICAgICAgIGlmICh2YXJhcmdzRm9ybWFsID09IG51bGwgJiYKICAgICAgICAgICAgICAgICAgICBhcmd0eXBlcy5zaXplKCkgIT0gZm9ybWFscy5zaXplKCkpIHsKICAgICAgICAgICAgICAgIHJlcG9ydE1DKGNhbGxUcmVlLCBNZXRob2RDaGVja0RpYWcuQVJJVFlfTUlTTUFUQ0gsIGluZmVyZW5jZUNvbnRleHQpOyAvLyBub3QgZW5vdWdoIGFyZ3MKICAgICAgICAgICAgfQoKICAgICAgICAgICAgd2hpbGUgKGFyZ3R5cGVzLm5vbkVtcHR5KCkgJiYgZm9ybWFscy5oZWFkICE9IHZhcmFyZ3NGb3JtYWwpIHsKICAgICAgICAgICAgICAgIERpYWdub3N0aWNQb3NpdGlvbiBwb3MgPSB0cmVlcyAhPSBudWxsID8gdHJlZXMuaGVhZCA6IG51bGw7CiAgICAgICAgICAgICAgICBjaGVja0FyZyhwb3MsIGZhbHNlLCBhcmd0eXBlcy5oZWFkLCBmb3JtYWxzLmhlYWQsIGRlZmVycmVkQXR0ckNvbnRleHQsIHdhcm4pOwogICAgICAgICAgICAgICAgYXJndHlwZXMgPSBhcmd0eXBlcy50YWlsOwogICAgICAgICAgICAgICAgZm9ybWFscyA9IGZvcm1hbHMudGFpbDsKICAgICAgICAgICAgICAgIHRyZWVzID0gdHJlZXMgIT0gbnVsbCA/IHRyZWVzLnRhaWwgOiB0cmVlczsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKGZvcm1hbHMuaGVhZCAhPSB2YXJhcmdzRm9ybWFsKSB7CiAgICAgICAgICAgICAgICByZXBvcnRNQyhjYWxsVHJlZSwgTWV0aG9kQ2hlY2tEaWFnLkFSSVRZX01JU01BVENILCBpbmZlcmVuY2VDb250ZXh0KTsgLy8gbm90IGVub3VnaCBhcmdzCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICh1c2VWYXJhcmdzKSB7CiAgICAgICAgICAgICAgICAvL25vdGU6IGlmIGFwcGxpY2FiaWxpdHkgY2hlY2sgaXMgdHJpZ2dlcmVkIGJ5IG1vc3Qgc3BlY2lmaWMgdGVzdCwKICAgICAgICAgICAgICAgIC8vdGhlIGxhc3QgYXJndW1lbnQgb2YgYSB2YXJhcmdzIGlzIF9ub3RfIGFuIGFycmF5IHR5cGUgKHNlZSBKTFMgMTUuMTIuMi41KQogICAgICAgICAgICAgICAgZmluYWwgVHlwZSBlbHQgPSB0eXBlcy5lbGVtdHlwZSh2YXJhcmdzRm9ybWFsKTsKICAgICAgICAgICAgICAgIHdoaWxlIChhcmd0eXBlcy5ub25FbXB0eSgpKSB7CiAgICAgICAgICAgICAgICAgICAgRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcyA9IHRyZWVzICE9IG51bGwgPyB0cmVlcy5oZWFkIDogbnVsbDsKICAgICAgICAgICAgICAgICAgICBjaGVja0FyZyhwb3MsIHRydWUsIGFyZ3R5cGVzLmhlYWQsIGVsdCwgZGVmZXJyZWRBdHRyQ29udGV4dCwgd2Fybik7CiAgICAgICAgICAgICAgICAgICAgYXJndHlwZXMgPSBhcmd0eXBlcy50YWlsOwogICAgICAgICAgICAgICAgICAgIHRyZWVzID0gdHJlZXMgIT0gbnVsbCA/IHRyZWVzLnRhaWwgOiB0cmVlczsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgICAgIC8vIHdoZXJlCiAgICAgICAgICAgIHByaXZhdGUgSkNUcmVlIHRyZWVGb3JEaWFnbm9zdGljcyhFbnY8QXR0ckNvbnRleHQ+IGVudikgewogICAgICAgICAgICAgICAgcmV0dXJuIGVudi5pbmZvLnByZWZlcnJlZFRyZWVGb3JEaWFnbm9zdGljcyAhPSBudWxsID8gZW52LmluZm8ucHJlZmVycmVkVHJlZUZvckRpYWdub3N0aWNzIDogZW52LnRyZWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogRG9lcyB0aGUgYWN0dWFsIGFyZ3VtZW50IGNvbmZvcm1zIHRvIHRoZSBjb3JyZXNwb25kaW5nIGZvcm1hbD8KICAgICAgICAgKi8KICAgICAgICBhYnN0cmFjdCB2b2lkIGNoZWNrQXJnKERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIGJvb2xlYW4gdmFyYXJncywgVHlwZSBhY3R1YWwsIFR5cGUgZm9ybWFsLCBEZWZlcnJlZEF0dHJDb250ZXh0IGRlZmVycmVkQXR0ckNvbnRleHQsIFdhcm5lciB3YXJuKTsKCiAgICAgICAgcHJvdGVjdGVkIHZvaWQgcmVwb3J0TUMoRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcywgTWV0aG9kQ2hlY2tEaWFnIGRpYWcsIEluZmVyZW5jZUNvbnRleHQgaW5mZXJlbmNlQ29udGV4dCwgT2JqZWN0Li4uIGFyZ3MpIHsKICAgICAgICAgICAgYm9vbGVhbiBpbmZlckRpYWcgPSBpbmZlcmVuY2VDb250ZXh0ICE9IGluZmVyLmVtcHR5Q29udGV4dDsKICAgICAgICAgICAgSW5hcHBsaWNhYmxlTWV0aG9kRXhjZXB0aW9uIGV4ID0gaW5mZXJEaWFnID8KICAgICAgICAgICAgICAgICAgICBpbmZlci5pbmZlcmVuY2VFeGNlcHRpb24gOiBpbmFwcGxpY2FibGVNZXRob2RFeGNlcHRpb247CiAgICAgICAgICAgIGlmIChpbmZlckRpYWcgJiYgKCFkaWFnLmluZmVyS2V5LmVxdWFscyhkaWFnLmJhc2ljS2V5KSkpIHsKICAgICAgICAgICAgICAgIE9iamVjdFtdIGFyZ3MyID0gbmV3IE9iamVjdFthcmdzLmxlbmd0aCArIDFdOwogICAgICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShhcmdzLCAwLCBhcmdzMiwgMSwgYXJncy5sZW5ndGgpOwogICAgICAgICAgICAgICAgYXJnczJbMF0gPSBpbmZlcmVuY2VDb250ZXh0LmluZmVyZW5jZVZhcnMoKTsKICAgICAgICAgICAgICAgIGFyZ3MgPSBhcmdzMjsKICAgICAgICAgICAgfQogICAgICAgICAgICBTdHJpbmcga2V5ID0gaW5mZXJEaWFnID8gZGlhZy5pbmZlcktleSA6IGRpYWcuYmFzaWNLZXk7CiAgICAgICAgICAgIHRocm93IGV4LnNldE1lc3NhZ2UoZGlhZ3MuY3JlYXRlKERpYWdub3N0aWNUeXBlLkZSQUdNRU5ULCBsb2cuY3VycmVudFNvdXJjZSgpLCBwb3MsIGtleSwgYXJncykpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIE1ldGhvZENoZWNrIG1vc3RTcGVjaWZpY0NoZWNrKExpc3Q8VHlwZT4gYWN0dWFscykgewogICAgICAgICAgICByZXR1cm4gbmlsTWV0aG9kQ2hlY2s7CiAgICAgICAgfQoKICAgIH0KCiAgICAvKioKICAgICAqIEFyaXR5LWJhc2VkIG1ldGhvZCBjaGVjay4gQSBtZXRob2QgaXMgYXBwbGljYWJsZSBpZiB0aGUgbnVtYmVyIG9mIGFjdHVhbHMKICAgICAqIHN1cHBsaWVkIGNvbmZvcm1zIHRvIHRoZSBtZXRob2Qgc2lnbmF0dXJlLgogICAgICovCiAgICBNZXRob2RDaGVjayBhcml0eU1ldGhvZENoZWNrID0gbmV3IEFic3RyYWN0TWV0aG9kQ2hlY2soKSB7CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgdm9pZCBjaGVja0FyZyhEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBib29sZWFuIHZhcmFyZ3MsIFR5cGUgYWN0dWFsLCBUeXBlIGZvcm1hbCwgRGVmZXJyZWRBdHRyQ29udGV4dCBkZWZlcnJlZEF0dHJDb250ZXh0LCBXYXJuZXIgd2FybikgewogICAgICAgICAgICAvL2RvIG5vdGhpbmcgLSBhY3R1YWwgYWx3YXlzIGNvbXBhdGlibGUgdG8gZm9ybWFscwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKICAgICAgICAgICAgcmV0dXJuICJhcml0eU1ldGhvZENoZWNrIjsKICAgICAgICB9CiAgICB9OwoKICAgIExpc3Q8VHlwZT4gZHVtbXlBcmdzKGludCBsZW5ndGgpIHsKICAgICAgICBMaXN0QnVmZmVyPFR5cGU+IGJ1ZiA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICBmb3IgKGludCBpID0gMCA7IGkgPCBsZW5ndGggOyBpKyspIHsKICAgICAgICAgICAgYnVmLmFwcGVuZChUeXBlLm5vVHlwZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWYudG9MaXN0KCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBNYWluIG1ldGhvZCBhcHBsaWNhYmlsaXR5IHJvdXRpbmUuIEdpdmVuIGEgbGlzdCBvZiBhY3R1YWwgdHlwZXMgQSwKICAgICAqIGEgbGlzdCBvZiBmb3JtYWwgdHlwZXMgRiwgZGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSB0eXBlcyBpbiBBIGFyZQogICAgICogY29tcGF0aWJsZSAoYnkgbWV0aG9kIGludm9jYXRpb24gY29udmVyc2lvbikgd2l0aCB0aGUgdHlwZXMgaW4gRi4KICAgICAqCiAgICAgKiBTaW5jZSB0aGlzIHJvdXRpbmUgaXMgc2hhcmVkIGJldHdlZW4gb3ZlcmxvYWQgcmVzb2x1dGlvbiBhbmQgbWV0aG9kCiAgICAgKiB0eXBlLWluZmVyZW5jZSwgYSAocG9zc2libHkgZW1wdHkpIGluZmVyZW5jZSBjb250ZXh0IGlzIHVzZWQgdG8gY29udmVydAogICAgICogZm9ybWFsIHR5cGVzIHRvIHRoZSBjb3JyZXNwb25kaW5nICd1bmRldCcgZm9ybSBhaGVhZCBvZiBhIGNvbXBhdGliaWxpdHkKICAgICAqIGNoZWNrIHNvIHRoYXQgY29uc3RyYWludHMgY2FuIGJlIHByb3BhZ2F0ZWQgYW5kIGNvbGxlY3RlZC4KICAgICAqCiAgICAgKiBNb3Jlb3ZlciwgaWYgb25lIG9yIG1vcmUgdHlwZXMgaW4gQSBpcyBhIGRlZmVycmVkIHR5cGUsIHRoaXMgcm91dGluZSB1c2VzCiAgICAgKiBEZWZlcnJlZEF0dHIgaW4gb3JkZXIgdG8gcGVyZm9ybSBkZWZlcnJlZCBhdHRyaWJ1dGlvbi4gSWYgb25lIG9yIG1vcmUgYWN0dWFsCiAgICAgKiBkZWZlcnJlZCB0eXBlcyBhcmUgc3R1Y2ssIHRoZXkgYXJlIHBsYWNlZCBpbiBhIHF1ZXVlIGFuZCByZXZpc2l0ZWQgbGF0ZXIKICAgICAqIGFmdGVyIHRoZSByZW1haW5kZXIgb2YgdGhlIGFyZ3VtZW50cyBoYXZlIGJlZW4gc2Vlbi4gSWYgdGhpcyBpcyBub3Qgc3VmZmljaWVudAogICAgICogdG8gJ3Vuc3R1Y2snIHRoZSBhcmd1bWVudCwgYSBjeWNsaWMgaW5mZXJlbmNlIGVycm9yIGlzIGNhbGxlZCBvdXQuCiAgICAgKgogICAgICogQSBtZXRob2QgY2hlY2sgaGFuZGxlciAoc2VlIGFib3ZlKSBpcyB1c2VkIGluIG9yZGVyIHRvIHJlcG9ydCBlcnJvcnMuCiAgICAgKi8KICAgIE1ldGhvZENoZWNrIHJlc29sdmVNZXRob2RDaGVjayA9IG5ldyBBYnN0cmFjdE1ldGhvZENoZWNrKCkgewoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICB2b2lkIGNoZWNrQXJnKERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIGJvb2xlYW4gdmFyYXJncywgVHlwZSBhY3R1YWwsIFR5cGUgZm9ybWFsLCBEZWZlcnJlZEF0dHJDb250ZXh0IGRlZmVycmVkQXR0ckNvbnRleHQsIFdhcm5lciB3YXJuKSB7CiAgICAgICAgICAgIFJlc3VsdEluZm8gbXJlc3VsdCA9IG1ldGhvZENoZWNrUmVzdWx0KHZhcmFyZ3MsIGZvcm1hbCwgZGVmZXJyZWRBdHRyQ29udGV4dCwgd2Fybik7CiAgICAgICAgICAgIG1yZXN1bHQuY2hlY2socG9zLCBhY3R1YWwpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgYXJndW1lbnRzQWNjZXB0YWJsZShmaW5hbCBFbnY8QXR0ckNvbnRleHQ+IGVudiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRGVmZXJyZWRBdHRyQ29udGV4dCBkZWZlcnJlZEF0dHJDb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IGFyZ3R5cGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IGZvcm1hbHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdhcm5lciB3YXJuKSB7CiAgICAgICAgICAgIHN1cGVyLmFyZ3VtZW50c0FjY2VwdGFibGUoZW52LCBkZWZlcnJlZEF0dHJDb250ZXh0LCBhcmd0eXBlcywgZm9ybWFscywgd2Fybik7CiAgICAgICAgICAgIC8vIHNob3VsZCB3ZSBjaGVjayB2YXJhcmdzIGVsZW1lbnQgdHlwZSBhY2Nlc3NpYmlsaXR5PwogICAgICAgICAgICBpZiAoZGVmZXJyZWRBdHRyQ29udGV4dC5waGFzZS5pc1ZhcmFyZ3NSZXF1aXJlZCgpKSB7CiAgICAgICAgICAgICAgICBpZiAoZGVmZXJyZWRBdHRyQ29udGV4dC5tb2RlID09IEF0dHJNb2RlLkNIRUNLIHx8ICFjaGVja1ZhcmFyZ3NBY2Nlc3NBZnRlclJlc29sdXRpb24pIHsKICAgICAgICAgICAgICAgICAgICB2YXJhcmdzQWNjZXNzaWJsZShlbnYsIHR5cGVzLmVsZW10eXBlKGZvcm1hbHMubGFzdCgpKSwgZGVmZXJyZWRBdHRyQ29udGV4dC5pbmZlcmVuY2VDb250ZXh0KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogVGVzdCB0aGF0IHRoZSBydW50aW1lIGFycmF5IGVsZW1lbnQgdHlwZSBjb3JyZXNwb25kaW5nIHRvICd0JyBpcyBhY2Nlc3NpYmxlLiAgJ3QnIHNob3VsZCBiZSB0aGUKICAgICAgICAgKiB2YXJhcmdzIGVsZW1lbnQgdHlwZSBvZiBlaXRoZXIgdGhlIG1ldGhvZCBpbnZvY2F0aW9uIHR5cGUgc2lnbmF0dXJlIChhZnRlciBpbmZlcmVuY2UgY29tcGxldGVzKQogICAgICAgICAqIG9yIHRoZSBtZXRob2QgZGVjbGFyYXRpb24gc2lnbmF0dXJlIChiZWZvcmUgaW5mZXJlbmNlIGNvbXBsZXRlcykuCiAgICAgICAgICovCiAgICAgICAgcHJpdmF0ZSB2b2lkIHZhcmFyZ3NBY2Nlc3NpYmxlKGZpbmFsIEVudjxBdHRyQ29udGV4dD4gZW52LCBmaW5hbCBUeXBlIHQsIGZpbmFsIEluZmVyZW5jZUNvbnRleHQgaW5mZXJlbmNlQ29udGV4dCkgewogICAgICAgICAgICBpZiAoaW5mZXJlbmNlQ29udGV4dC5mcmVlKHQpKSB7CiAgICAgICAgICAgICAgICBpbmZlcmVuY2VDb250ZXh0LmFkZEZyZWVUeXBlTGlzdGVuZXIoTGlzdC5vZih0KSwKICAgICAgICAgICAgICAgICAgICAgICAgc29sdmVkQ29udGV4dCAtPiB2YXJhcmdzQWNjZXNzaWJsZShlbnYsIHNvbHZlZENvbnRleHQuYXNJbnN0VHlwZSh0KSwgc29sdmVkQ29udGV4dCkpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgaWYgKCFpc0FjY2Vzc2libGUoZW52LCB0eXBlcy5lcmFzdXJlKHQpKSkgewogICAgICAgICAgICAgICAgICAgIFN5bWJvbCBsb2NhdGlvbiA9IGVudi5lbmNsQ2xhc3Muc3ltOwogICAgICAgICAgICAgICAgICAgIHJlcG9ydE1DKGVudi50cmVlLCBNZXRob2RDaGVja0RpYWcuSU5BQ0NFU1NJQkxFX1ZBUkFSR1MsIGluZmVyZW5jZUNvbnRleHQsIHQsIEtpbmRzLmtpbmROYW1lKGxvY2F0aW9uKSwgbG9jYXRpb24pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIFJlc3VsdEluZm8gbWV0aG9kQ2hlY2tSZXN1bHQoZmluYWwgYm9vbGVhbiB2YXJhcmdzQ2hlY2ssIFR5cGUgdG8sCiAgICAgICAgICAgICAgICBmaW5hbCBEZWZlcnJlZEF0dHIuRGVmZXJyZWRBdHRyQ29udGV4dCBkZWZlcnJlZEF0dHJDb250ZXh0LCBXYXJuZXIgcnNXYXJuZXIpIHsKICAgICAgICAgICAgQ2hlY2tDb250ZXh0IGNoZWNrQ29udGV4dCA9IG5ldyBNZXRob2RDaGVja0NvbnRleHQoIWRlZmVycmVkQXR0ckNvbnRleHQucGhhc2UuaXNCb3hpbmdSZXF1aXJlZCgpLCBkZWZlcnJlZEF0dHJDb250ZXh0LCByc1dhcm5lcikgewogICAgICAgICAgICAgICAgTWV0aG9kQ2hlY2tEaWFnIG1ldGhvZERpYWcgPSB2YXJhcmdzQ2hlY2sgPwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXRob2RDaGVja0RpYWcuVkFSQVJHX01JU01BVENIIDogTWV0aG9kQ2hlY2tEaWFnLkFSR19NSVNNQVRDSDsKCiAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgICAgIHB1YmxpYyB2b2lkIHJlcG9ydChEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBKQ0RpYWdub3N0aWMgZGV0YWlscykgewogICAgICAgICAgICAgICAgICAgIHJlcG9ydE1DKHBvcywgbWV0aG9kRGlhZywgZGVmZXJyZWRBdHRyQ29udGV4dC5pbmZlcmVuY2VDb250ZXh0LCBkZXRhaWxzKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKICAgICAgICAgICAgcmV0dXJuIG5ldyBNZXRob2RSZXN1bHRJbmZvKHRvLCBjaGVja0NvbnRleHQpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIE1ldGhvZENoZWNrIG1vc3RTcGVjaWZpY0NoZWNrKExpc3Q8VHlwZT4gYWN0dWFscykgewogICAgICAgICAgICByZXR1cm4gbmV3IE1vc3RTcGVjaWZpY0NoZWNrKGFjdHVhbHMpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKICAgICAgICAgICAgcmV0dXJuICJyZXNvbHZlTWV0aG9kQ2hlY2siOwogICAgICAgIH0KICAgIH07CgogICAgLyoqCiAgICAgKiBUaGlzIGNsYXNzIGhhbmRsZXMgbWV0aG9kIHJlZmVyZW5jZSBhcHBsaWNhYmlsaXR5IGNoZWNrczsgc2luY2UgZHVyaW5nCiAgICAgKiB0aGVzZSBjaGVja3MgaXQncyBzb21ldGltZSBwb3NzaWJsZSB0byBoYXZlIGluZmVyZW5jZSB2YXJpYWJsZXMgb24KICAgICAqIHRoZSBhY3R1YWwgYXJndW1lbnQgdHlwZXMgbGlzdCwgdGhlIG1ldGhvZCBhcHBsaWNhYmlsaXR5IGNoZWNrIG11c3QgYmUKICAgICAqIGV4dGVuZGVkIHNvIHRoYXQgaW5mZXJlbmNlIHZhcmlhYmxlcyBhcmUgJ29wZW5lZCcgYXMgbmVlZGVkLgogICAgICovCiAgICBjbGFzcyBNZXRob2RSZWZlcmVuY2VDaGVjayBleHRlbmRzIEFic3RyYWN0TWV0aG9kQ2hlY2sgewoKICAgICAgICBJbmZlcmVuY2VDb250ZXh0IHBlbmRpbmdJbmZlcmVuY2VDb250ZXh0OwoKICAgICAgICBNZXRob2RSZWZlcmVuY2VDaGVjayhJbmZlcmVuY2VDb250ZXh0IHBlbmRpbmdJbmZlcmVuY2VDb250ZXh0KSB7CiAgICAgICAgICAgIHRoaXMucGVuZGluZ0luZmVyZW5jZUNvbnRleHQgPSBwZW5kaW5nSW5mZXJlbmNlQ29udGV4dDsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHZvaWQgY2hlY2tBcmcoRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcywgYm9vbGVhbiB2YXJhcmdzLCBUeXBlIGFjdHVhbCwgVHlwZSBmb3JtYWwsIERlZmVycmVkQXR0ckNvbnRleHQgZGVmZXJyZWRBdHRyQ29udGV4dCwgV2FybmVyIHdhcm4pIHsKICAgICAgICAgICAgUmVzdWx0SW5mbyBtcmVzdWx0ID0gbWV0aG9kQ2hlY2tSZXN1bHQodmFyYXJncywgZm9ybWFsLCBkZWZlcnJlZEF0dHJDb250ZXh0LCB3YXJuKTsKICAgICAgICAgICAgbXJlc3VsdC5jaGVjayhwb3MsIGFjdHVhbCk7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIFJlc3VsdEluZm8gbWV0aG9kQ2hlY2tSZXN1bHQoZmluYWwgYm9vbGVhbiB2YXJhcmdzQ2hlY2ssIFR5cGUgdG8sCiAgICAgICAgICAgICAgICBmaW5hbCBEZWZlcnJlZEF0dHIuRGVmZXJyZWRBdHRyQ29udGV4dCBkZWZlcnJlZEF0dHJDb250ZXh0LCBXYXJuZXIgcnNXYXJuZXIpIHsKICAgICAgICAgICAgQ2hlY2tDb250ZXh0IGNoZWNrQ29udGV4dCA9IG5ldyBNZXRob2RDaGVja0NvbnRleHQoIWRlZmVycmVkQXR0ckNvbnRleHQucGhhc2UuaXNCb3hpbmdSZXF1aXJlZCgpLCBkZWZlcnJlZEF0dHJDb250ZXh0LCByc1dhcm5lcikgewogICAgICAgICAgICAgICAgTWV0aG9kQ2hlY2tEaWFnIG1ldGhvZERpYWcgPSB2YXJhcmdzQ2hlY2sgPwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXRob2RDaGVja0RpYWcuVkFSQVJHX01JU01BVENIIDogTWV0aG9kQ2hlY2tEaWFnLkFSR19NSVNNQVRDSDsKCiAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgICAgIHB1YmxpYyBib29sZWFuIGNvbXBhdGlibGUoVHlwZSBmb3VuZCwgVHlwZSByZXEsIFdhcm5lciB3YXJuKSB7CiAgICAgICAgICAgICAgICAgICAgZm91bmQgPSBwZW5kaW5nSW5mZXJlbmNlQ29udGV4dC5hc1VuZGV0VmFyKGZvdW5kKTsKICAgICAgICAgICAgICAgICAgICBpZiAoZm91bmQuaGFzVGFnKFVOREVUVkFSKSAmJiByZXEuaXNQcmltaXRpdmUoKSkgewogICAgICAgICAgICAgICAgICAgICAgICByZXEgPSB0eXBlcy5ib3hlZENsYXNzKHJlcSkudHlwZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmNvbXBhdGlibGUoZm91bmQsIHJlcSwgd2Fybik7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCByZXBvcnQoRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcywgSkNEaWFnbm9zdGljIGRldGFpbHMpIHsKICAgICAgICAgICAgICAgICAgICByZXBvcnRNQyhwb3MsIG1ldGhvZERpYWcsIGRlZmVycmVkQXR0ckNvbnRleHQuaW5mZXJlbmNlQ29udGV4dCwgZGV0YWlscyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CiAgICAgICAgICAgIHJldHVybiBuZXcgTWV0aG9kUmVzdWx0SW5mbyh0bywgY2hlY2tDb250ZXh0KTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBNZXRob2RDaGVjayBtb3N0U3BlY2lmaWNDaGVjayhMaXN0PFR5cGU+IGFjdHVhbHMpIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyBNb3N0U3BlY2lmaWNDaGVjayhhY3R1YWxzKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CiAgICAgICAgICAgIHJldHVybiAiTWV0aG9kUmVmZXJlbmNlQ2hlY2siOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrIGNvbnRleHQgdG8gYmUgdXNlZCBkdXJpbmcgbWV0aG9kIGFwcGxpY2FiaWxpdHkgY2hlY2tzLiBBIG1ldGhvZCBjaGVjawogICAgICogY29udGV4dCBtaWdodCBjb250YWluIGluZmVyZW5jZSB2YXJpYWJsZXMuCiAgICAgKi8KICAgIGFic3RyYWN0IGNsYXNzIE1ldGhvZENoZWNrQ29udGV4dCBpbXBsZW1lbnRzIENoZWNrQ29udGV4dCB7CgogICAgICAgIGJvb2xlYW4gc3RyaWN0OwogICAgICAgIERlZmVycmVkQXR0ckNvbnRleHQgZGVmZXJyZWRBdHRyQ29udGV4dDsKICAgICAgICBXYXJuZXIgcnNXYXJuZXI7CgogICAgICAgIHB1YmxpYyBNZXRob2RDaGVja0NvbnRleHQoYm9vbGVhbiBzdHJpY3QsIERlZmVycmVkQXR0ckNvbnRleHQgZGVmZXJyZWRBdHRyQ29udGV4dCwgV2FybmVyIHJzV2FybmVyKSB7CiAgICAgICAgICAgdGhpcy5zdHJpY3QgPSBzdHJpY3Q7CiAgICAgICAgICAgdGhpcy5kZWZlcnJlZEF0dHJDb250ZXh0ID0gZGVmZXJyZWRBdHRyQ29udGV4dDsKICAgICAgICAgICB0aGlzLnJzV2FybmVyID0gcnNXYXJuZXI7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgYm9vbGVhbiBjb21wYXRpYmxlKFR5cGUgZm91bmQsIFR5cGUgcmVxLCBXYXJuZXIgd2FybikgewogICAgICAgICAgICBJbmZlcmVuY2VDb250ZXh0IGluZmVyZW5jZUNvbnRleHQgPSBkZWZlcnJlZEF0dHJDb250ZXh0LmluZmVyZW5jZUNvbnRleHQ7CiAgICAgICAgICAgIHJldHVybiBzdHJpY3QgPwogICAgICAgICAgICAgICAgICAgIHR5cGVzLmlzU3VidHlwZVVuY2hlY2tlZChpbmZlcmVuY2VDb250ZXh0LmFzVW5kZXRWYXIoZm91bmQpLCBpbmZlcmVuY2VDb250ZXh0LmFzVW5kZXRWYXIocmVxKSwgd2FybikgOgogICAgICAgICAgICAgICAgICAgIHR5cGVzLmlzQ29udmVydGlibGUoaW5mZXJlbmNlQ29udGV4dC5hc1VuZGV0VmFyKGZvdW5kKSwgaW5mZXJlbmNlQ29udGV4dC5hc1VuZGV0VmFyKHJlcSksIHdhcm4pOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHZvaWQgcmVwb3J0KERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIEpDRGlhZ25vc3RpYyBkZXRhaWxzKSB7CiAgICAgICAgICAgIHRocm93IGluYXBwbGljYWJsZU1ldGhvZEV4Y2VwdGlvbi5zZXRNZXNzYWdlKGRldGFpbHMpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIFdhcm5lciBjaGVja1dhcm5lcihEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBUeXBlIGZvdW5kLCBUeXBlIHJlcSkgewogICAgICAgICAgICByZXR1cm4gcnNXYXJuZXI7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgSW5mZXJlbmNlQ29udGV4dCBpbmZlcmVuY2VDb250ZXh0KCkgewogICAgICAgICAgICByZXR1cm4gZGVmZXJyZWRBdHRyQ29udGV4dC5pbmZlcmVuY2VDb250ZXh0OwogICAgICAgIH0KCiAgICAgICAgcHVibGljIERlZmVycmVkQXR0ckNvbnRleHQgZGVmZXJyZWRBdHRyQ29udGV4dCgpIHsKICAgICAgICAgICAgcmV0dXJuIGRlZmVycmVkQXR0ckNvbnRleHQ7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewogICAgICAgICAgICByZXR1cm4gIk1ldGhvZENoZWNrQ29udGV4dCI7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogUmVzdWx0SW5mbyBjbGFzcyB0byBiZSB1c2VkIGR1cmluZyBtZXRob2QgYXBwbGljYWJpbGl0eSBjaGVja3MuIENoZWNrCiAgICAgKiBmb3IgZGVmZXJyZWQgdHlwZXMgZ29lcyB0aHJvdWdoIHNwZWNpYWwgcGF0aC4KICAgICAqLwogICAgY2xhc3MgTWV0aG9kUmVzdWx0SW5mbyBleHRlbmRzIFJlc3VsdEluZm8gewoKICAgICAgICBwdWJsaWMgTWV0aG9kUmVzdWx0SW5mbyhUeXBlIHB0LCBDaGVja0NvbnRleHQgY2hlY2tDb250ZXh0KSB7CiAgICAgICAgICAgIGF0dHIuc3VwZXIoS2luZFNlbGVjdG9yLlZBTCwgcHQsIGNoZWNrQ29udGV4dCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwcm90ZWN0ZWQgVHlwZSBjaGVjayhEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBUeXBlIGZvdW5kKSB7CiAgICAgICAgICAgIGlmIChmb3VuZC5oYXNUYWcoREVGRVJSRUQpKSB7CiAgICAgICAgICAgICAgICBEZWZlcnJlZFR5cGUgZHQgPSAoRGVmZXJyZWRUeXBlKWZvdW5kOwogICAgICAgICAgICAgICAgcmV0dXJuIGR0LmNoZWNrKHRoaXMpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgVHlwZSB1UmVzdWx0ID0gVShmb3VuZCk7CiAgICAgICAgICAgICAgICBUeXBlIGNhcHR1cmVkVHlwZSA9IHBvcyA9PSBudWxsIHx8IHBvcy5nZXRUcmVlKCkgPT0gbnVsbCA/CiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVzLmNhcHR1cmUodVJlc3VsdCkgOgogICAgICAgICAgICAgICAgICAgICAgICBjaGVja0NvbnRleHQuaW5mZXJlbmNlQ29udGV4dCgpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY2FjaGVkQ2FwdHVyZShwb3MuZ2V0VHJlZSgpLCB1UmVzdWx0LCB0cnVlKTsKICAgICAgICAgICAgICAgIHJldHVybiBzdXBlci5jaGVjayhwb3MsIGNoay5jaGVja05vblZvaWQocG9zLCBjYXB0dXJlZFR5cGUpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogamF2YWMgaGFzIGEgbG9uZy1zdGFuZGluZyAnc2ltcGxpZmljYXRpb24nIChzZWUgNjM5MTk5NSk6CiAgICAgICAgICogZ2l2ZW4gYW4gYWN0dWFsIGFyZ3VtZW50IHR5cGUsIHRoZSBtZXRob2QgY2hlY2sgaXMgcGVyZm9ybWVkCiAgICAgICAgICogb24gaXRzIHVwcGVyIGJvdW5kLiBUaGlzIGxlYWRzIHRvIGluY29uc2lzdGVuY2llcyB3aGVuIGFuCiAgICAgICAgICogYXJndW1lbnQgdHlwZSBpcyBjaGVja2VkIGFnYWluc3QgaXRzZWxmLiBGb3IgZXhhbXBsZSwgZ2l2ZW4KICAgICAgICAgKiBhIHR5cGUtdmFyaWFibGUgVCwgaXQgaXMgbm90IHRydWUgdGhhdCB7QGNvZGUgVShUKSA8OiBUfSwKICAgICAgICAgKiBzbyB3ZSBuZWVkIHRvIGd1YXJkIGFnYWluc3QgdGhhdC4KICAgICAgICAgKi8KICAgICAgICBwcml2YXRlIFR5cGUgVShUeXBlIGZvdW5kKSB7CiAgICAgICAgICAgIHJldHVybiBmb3VuZCA9PSBwdCA/CiAgICAgICAgICAgICAgICAgICAgZm91bmQgOiB0eXBlcy5jdmFyVXBwZXJCb3VuZChmb3VuZCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwcm90ZWN0ZWQgTWV0aG9kUmVzdWx0SW5mbyBkdXAoVHlwZSBuZXdQdCkgewogICAgICAgICAgICByZXR1cm4gbmV3IE1ldGhvZFJlc3VsdEluZm8obmV3UHQsIGNoZWNrQ29udGV4dCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwcm90ZWN0ZWQgUmVzdWx0SW5mbyBkdXAoQ2hlY2tDb250ZXh0IG5ld0NvbnRleHQpIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyBNZXRob2RSZXN1bHRJbmZvKHB0LCBuZXdDb250ZXh0KTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHByb3RlY3RlZCBSZXN1bHRJbmZvIGR1cChUeXBlIG5ld1B0LCBDaGVja0NvbnRleHQgbmV3Q29udGV4dCkgewogICAgICAgICAgICByZXR1cm4gbmV3IE1ldGhvZFJlc3VsdEluZm8obmV3UHQsIG5ld0NvbnRleHQpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIE1vc3Qgc3BlY2lmaWMgbWV0aG9kIGFwcGxpY2FiaWxpdHkgcm91dGluZS4gR2l2ZW4gYSBsaXN0IG9mIGFjdHVhbCB0eXBlcyBBLAogICAgICogYSBsaXN0IG9mIGZvcm1hbCB0eXBlcyBGMSwgYW5kIGEgbGlzdCBvZiBmb3JtYWwgdHlwZXMgRjIsIHRoZSByb3V0aW5lIGRldGVybWluZXMKICAgICAqIGFzIHRvIHdoZXRoZXIgdGhlIHR5cGVzIGluIEYxIGNhbiBiZSBjb25zaWRlcmVkIG1vcmUgc3BlY2lmaWMgdGhhbiB0aG9zZSBpbiBGMiB3LnIudC4KICAgICAqIGFyZ3VtZW50IHR5cGVzIEEuCiAgICAgKi8KICAgIGNsYXNzIE1vc3RTcGVjaWZpY0NoZWNrIGltcGxlbWVudHMgTWV0aG9kQ2hlY2sgewoKICAgICAgICBMaXN0PFR5cGU+IGFjdHVhbHM7CgogICAgICAgIE1vc3RTcGVjaWZpY0NoZWNrKExpc3Q8VHlwZT4gYWN0dWFscykgewogICAgICAgICAgICB0aGlzLmFjdHVhbHMgPSBhY3R1YWxzOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgYXJndW1lbnRzQWNjZXB0YWJsZShmaW5hbCBFbnY8QXR0ckNvbnRleHQ+IGVudiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRGVmZXJyZWRBdHRyQ29udGV4dCBkZWZlcnJlZEF0dHJDb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IGZvcm1hbHMxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IGZvcm1hbHMyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXYXJuZXIgd2FybikgewogICAgICAgICAgICBmb3JtYWxzMiA9IGFkanVzdEFyZ3MoZm9ybWFsczIsIGRlZmVycmVkQXR0ckNvbnRleHQubXN5bSwgZm9ybWFsczEubGVuZ3RoKCksIGRlZmVycmVkQXR0ckNvbnRleHQucGhhc2UuaXNWYXJhcmdzUmVxdWlyZWQoKSk7CiAgICAgICAgICAgIHdoaWxlIChmb3JtYWxzMi5ub25FbXB0eSgpKSB7CiAgICAgICAgICAgICAgICBSZXN1bHRJbmZvIG1yZXN1bHQgPSBtZXRob2RDaGVja1Jlc3VsdChmb3JtYWxzMi5oZWFkLCBkZWZlcnJlZEF0dHJDb250ZXh0LCB3YXJuLCBhY3R1YWxzLmhlYWQpOwogICAgICAgICAgICAgICAgbXJlc3VsdC5jaGVjayhudWxsLCBmb3JtYWxzMS5oZWFkKTsKICAgICAgICAgICAgICAgIGZvcm1hbHMxID0gZm9ybWFsczEudGFpbDsKICAgICAgICAgICAgICAgIGZvcm1hbHMyID0gZm9ybWFsczIudGFpbDsKICAgICAgICAgICAgICAgIGFjdHVhbHMgPSBhY3R1YWxzLmlzRW1wdHkoKSA/IGFjdHVhbHMgOiBhY3R1YWxzLnRhaWw7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgLyoqCiAgICAgICAgKiBDcmVhdGUgYSBtZXRob2QgY2hlY2sgY29udGV4dCB0byBiZSB1c2VkIGR1cmluZyB0aGUgbW9zdCBzcGVjaWZpYyBhcHBsaWNhYmlsaXR5IGNoZWNrCiAgICAgICAgKi8KICAgICAgICBSZXN1bHRJbmZvIG1ldGhvZENoZWNrUmVzdWx0KFR5cGUgdG8sIERlZmVycmVkQXR0ci5EZWZlcnJlZEF0dHJDb250ZXh0IGRlZmVycmVkQXR0ckNvbnRleHQsCiAgICAgICAgICAgICAgIFdhcm5lciByc1dhcm5lciwgVHlwZSBhY3R1YWwpIHsKICAgICAgICAgICAgcmV0dXJuIGF0dHIubmV3IFJlc3VsdEluZm8oS2luZFNlbGVjdG9yLlZBTCwgdG8sCiAgICAgICAgICAgICAgICAgICBuZXcgTW9zdFNwZWNpZmljQ2hlY2tDb250ZXh0KGRlZmVycmVkQXR0ckNvbnRleHQsIHJzV2FybmVyLCBhY3R1YWwpKTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIFN1YmNsYXNzIG9mIG1ldGhvZCBjaGVjayBjb250ZXh0IGNsYXNzIHRoYXQgaW1wbGVtZW50cyBtb3N0IHNwZWNpZmljCiAgICAgICAgICogbWV0aG9kIGNvbnZlcnNpb24uIElmIHRoZSBhY3R1YWwgdHlwZSB1bmRlciBhbmFseXNpcyBpcyBhIGRlZmVycmVkIHR5cGUKICAgICAgICAgKiBhIGZ1bGwgYmxvd24gc3RydWN0dXJhbCBhbmFseXNpcyBpcyBjYXJyaWVkIG91dC4KICAgICAgICAgKi8KICAgICAgICBjbGFzcyBNb3N0U3BlY2lmaWNDaGVja0NvbnRleHQgZXh0ZW5kcyBNZXRob2RDaGVja0NvbnRleHQgewoKICAgICAgICAgICAgVHlwZSBhY3R1YWw7CgogICAgICAgICAgICBwdWJsaWMgTW9zdFNwZWNpZmljQ2hlY2tDb250ZXh0KERlZmVycmVkQXR0ckNvbnRleHQgZGVmZXJyZWRBdHRyQ29udGV4dCwgV2FybmVyIHJzV2FybmVyLCBUeXBlIGFjdHVhbCkgewogICAgICAgICAgICAgICAgc3VwZXIodHJ1ZSwgZGVmZXJyZWRBdHRyQ29udGV4dCwgcnNXYXJuZXIpOwogICAgICAgICAgICAgICAgdGhpcy5hY3R1YWwgPSBhY3R1YWw7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHB1YmxpYyBib29sZWFuIGNvbXBhdGlibGUoVHlwZSBmb3VuZCwgVHlwZSByZXEsIFdhcm5lciB3YXJuKSB7CiAgICAgICAgICAgICAgICBpZiAoYWxsb3dGdW5jdGlvbmFsSW50ZXJmYWNlTW9zdFNwZWNpZmljICYmCiAgICAgICAgICAgICAgICAgICAgICAgIHVucmVsYXRlZEZ1bmN0aW9uYWxJbnRlcmZhY2VzKGZvdW5kLCByZXEpICYmCiAgICAgICAgICAgICAgICAgICAgICAgIChhY3R1YWwgIT0gbnVsbCAmJiBhY3R1YWwuZ2V0VGFnKCkgPT0gREVGRVJSRUQpKSB7CiAgICAgICAgICAgICAgICAgICAgRGVmZXJyZWRUeXBlIGR0ID0gKERlZmVycmVkVHlwZSkgYWN0dWFsOwogICAgICAgICAgICAgICAgICAgIEpDVHJlZSBzcGVjdWxhdGl2ZVRyZWUgPSBkdC5zcGVjdWxhdGl2ZVRyZWUoZGVmZXJyZWRBdHRyQ29udGV4dCk7CiAgICAgICAgICAgICAgICAgICAgaWYgKHNwZWN1bGF0aXZlVHJlZSAhPSBkZWZlcnJlZEF0dHIuc3R1Y2tUcmVlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbmFsSW50ZXJmYWNlTW9zdFNwZWNpZmljKGZvdW5kLCByZXEsIHNwZWN1bGF0aXZlVHJlZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIGNvbXBhdGlibGVCeVN1YnR5cGluZyhmb3VuZCwgcmVxKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHJpdmF0ZSBib29sZWFuIGNvbXBhdGlibGVCeVN1YnR5cGluZyhUeXBlIGZvdW5kLCBUeXBlIHJlcSkgewogICAgICAgICAgICAgICAgaWYgKCFzdHJpY3QgJiYgZm91bmQuaXNQcmltaXRpdmUoKSAhPSByZXEuaXNQcmltaXRpdmUoKSkgewogICAgICAgICAgICAgICAgICAgIGZvdW5kID0gZm91bmQuaXNQcmltaXRpdmUoKSA/IHR5cGVzLmJveGVkQ2xhc3MoZm91bmQpLnR5cGUgOiB0eXBlcy51bmJveGVkVHlwZShmb3VuZCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gdHlwZXMuaXNTdWJ0eXBlTm9DYXB0dXJlKGZvdW5kLCBkZWZlcnJlZEF0dHJDb250ZXh0LmluZmVyZW5jZUNvbnRleHQuYXNVbmRldFZhcihyZXEpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyoqIFdoZXRoZXIge0Bjb2RlIHR9IGFuZCB7QGNvZGUgc30gYXJlIHVucmVsYXRlZCBmdW5jdGlvbmFsIGludGVyZmFjZSB0eXBlcy4gKi8KICAgICAgICAgICAgcHJpdmF0ZSBib29sZWFuIHVucmVsYXRlZEZ1bmN0aW9uYWxJbnRlcmZhY2VzKFR5cGUgdCwgVHlwZSBzKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHlwZXMuaXNGdW5jdGlvbmFsSW50ZXJmYWNlKHQudHN5bSkgJiYKICAgICAgICAgICAgICAgICAgICAgICB0eXBlcy5pc0Z1bmN0aW9uYWxJbnRlcmZhY2Uocy50c3ltKSAmJgogICAgICAgICAgICAgICAgICAgICAgIHVucmVsYXRlZEludGVyZmFjZXModCwgcyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qKiBXaGV0aGVyIHtAY29kZSB0fSBhbmQge0Bjb2RlIHN9IGFyZSB1bnJlbGF0ZWQgaW50ZXJmYWNlIHR5cGVzOyByZWN1cnMgb24gaW50ZXJzZWN0aW9ucy4gKiovCiAgICAgICAgICAgIHByaXZhdGUgYm9vbGVhbiB1bnJlbGF0ZWRJbnRlcmZhY2VzKFR5cGUgdCwgVHlwZSBzKSB7CiAgICAgICAgICAgICAgICBpZiAodC5pc0NvbXBvdW5kKCkpIHsKICAgICAgICAgICAgICAgICAgICBmb3IgKFR5cGUgdGkgOiB0eXBlcy5pbnRlcmZhY2VzKHQpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghdW5yZWxhdGVkSW50ZXJmYWNlcyh0aSwgcykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocy5pc0NvbXBvdW5kKCkpIHsKICAgICAgICAgICAgICAgICAgICBmb3IgKFR5cGUgc2kgOiB0eXBlcy5pbnRlcmZhY2VzKHMpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghdW5yZWxhdGVkSW50ZXJmYWNlcyh0LCBzaSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHR5cGVzLmFzU3VwZXIodCwgcy50c3ltKSA9PSBudWxsICYmIHR5cGVzLmFzU3VwZXIocywgdC50c3ltKSA9PSBudWxsOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICAvKiogUGFyYW1ldGVycyB7QGNvZGUgdH0gYW5kIHtAY29kZSBzfSBhcmUgdW5yZWxhdGVkIGZ1bmN0aW9uYWwgaW50ZXJmYWNlIHR5cGVzLiAqLwogICAgICAgICAgICBwcml2YXRlIGJvb2xlYW4gZnVuY3Rpb25hbEludGVyZmFjZU1vc3RTcGVjaWZpYyhUeXBlIHQsIFR5cGUgcywgSkNUcmVlIHRyZWUpIHsKICAgICAgICAgICAgICAgIFR5cGUgdERlc2MgPSB0eXBlcy5maW5kRGVzY3JpcHRvclR5cGUodHlwZXMuY2FwdHVyZSh0KSk7CiAgICAgICAgICAgICAgICBUeXBlIHREZXNjTm9DYXB0dXJlID0gdHlwZXMuZmluZERlc2NyaXB0b3JUeXBlKHQpOwogICAgICAgICAgICAgICAgVHlwZSBzRGVzYyA9IHR5cGVzLmZpbmREZXNjcmlwdG9yVHlwZShzKTsKICAgICAgICAgICAgICAgIGZpbmFsIExpc3Q8VHlwZT4gdFR5cGVQYXJhbXMgPSB0RGVzYy5nZXRUeXBlQXJndW1lbnRzKCk7CiAgICAgICAgICAgICAgICBmaW5hbCBMaXN0PFR5cGU+IHRUeXBlUGFyYW1zTm9DYXB0dXJlID0gdERlc2NOb0NhcHR1cmUuZ2V0VHlwZUFyZ3VtZW50cygpOwogICAgICAgICAgICAgICAgZmluYWwgTGlzdDxUeXBlPiBzVHlwZVBhcmFtcyA9IHNEZXNjLmdldFR5cGVBcmd1bWVudHMoKTsKCiAgICAgICAgICAgICAgICAvLyBjb21wYXJlIHR5cGUgcGFyYW1ldGVycwogICAgICAgICAgICAgICAgaWYgKHREZXNjLmhhc1RhZyhGT1JBTEwpICYmICF0eXBlcy5oYXNTYW1lQm91bmRzKChGb3JBbGwpIHREZXNjLCAoRm9yQWxsKSB0RGVzY05vQ2FwdHVyZSkpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvLyBjYW4ndCB1c2UgVHlwZXMuaGFzU2FtZUJvdW5kcyBvbiBzRGVzYyBiZWNhdXNlIGJvdW5kcyBtYXkgaGF2ZSBpdmFycwogICAgICAgICAgICAgICAgTGlzdDxUeXBlPiB0SXRlciA9IHRUeXBlUGFyYW1zOwogICAgICAgICAgICAgICAgTGlzdDxUeXBlPiBzSXRlciA9IHNUeXBlUGFyYW1zOwogICAgICAgICAgICAgICAgd2hpbGUgKHRJdGVyLm5vbkVtcHR5KCkgJiYgc0l0ZXIubm9uRW1wdHkoKSkgewogICAgICAgICAgICAgICAgICAgIFR5cGUgdEJvdW5kID0gdEl0ZXIuaGVhZC5nZXRVcHBlckJvdW5kKCk7CiAgICAgICAgICAgICAgICAgICAgVHlwZSBzQm91bmQgPSB0eXBlcy5zdWJzdChzSXRlci5oZWFkLmdldFVwcGVyQm91bmQoKSwgc1R5cGVQYXJhbXMsIHRUeXBlUGFyYW1zKTsKICAgICAgICAgICAgICAgICAgICBpZiAodEJvdW5kLmNvbnRhaW5zQW55KHRUeXBlUGFyYW1zKSAmJiBpbmZlcmVuY2VDb250ZXh0KCkuZnJlZShzQm91bmQpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKCF0eXBlcy5pc1NhbWVUeXBlKHRCb3VuZCwgaW5mZXJlbmNlQ29udGV4dCgpLmFzVW5kZXRWYXIoc0JvdW5kKSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB0SXRlciA9IHRJdGVyLnRhaWw7CiAgICAgICAgICAgICAgICAgICAgc0l0ZXIgPSBzSXRlci50YWlsOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCF0SXRlci5pc0VtcHR5KCkgfHwgIXNJdGVyLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBjb21wYXJlIHBhcmFtZXRlcnMKICAgICAgICAgICAgICAgIExpc3Q8VHlwZT4gdFBhcmFtcyA9IHREZXNjLmdldFBhcmFtZXRlclR5cGVzKCk7CiAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IHRQYXJhbXNOb0NhcHR1cmUgPSB0RGVzY05vQ2FwdHVyZS5nZXRQYXJhbWV0ZXJUeXBlcygpOwogICAgICAgICAgICAgICAgTGlzdDxUeXBlPiBzUGFyYW1zID0gc0Rlc2MuZ2V0UGFyYW1ldGVyVHlwZXMoKTsKICAgICAgICAgICAgICAgIHdoaWxlICh0UGFyYW1zLm5vbkVtcHR5KCkgJiYgdFBhcmFtc05vQ2FwdHVyZS5ub25FbXB0eSgpICYmIHNQYXJhbXMubm9uRW1wdHkoKSkgewogICAgICAgICAgICAgICAgICAgIFR5cGUgdFBhcmFtID0gdFBhcmFtcy5oZWFkOwogICAgICAgICAgICAgICAgICAgIFR5cGUgdFBhcmFtTm9DYXB0dXJlID0gdHlwZXMuc3Vic3QodFBhcmFtc05vQ2FwdHVyZS5oZWFkLCB0VHlwZVBhcmFtc05vQ2FwdHVyZSwgdFR5cGVQYXJhbXMpOwogICAgICAgICAgICAgICAgICAgIFR5cGUgc1BhcmFtID0gdHlwZXMuc3Vic3Qoc1BhcmFtcy5oZWFkLCBzVHlwZVBhcmFtcywgdFR5cGVQYXJhbXMpOwogICAgICAgICAgICAgICAgICAgIGlmICh0UGFyYW0uY29udGFpbnNBbnkodFR5cGVQYXJhbXMpICYmIGluZmVyZW5jZUNvbnRleHQoKS5mcmVlKHNQYXJhbSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoIXR5cGVzLmlzU3VidHlwZShpbmZlcmVuY2VDb250ZXh0KCkuYXNVbmRldFZhcihzUGFyYW0pLCB0UGFyYW0pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKCF0eXBlcy5pc1NhbWVUeXBlKHRQYXJhbU5vQ2FwdHVyZSwgaW5mZXJlbmNlQ29udGV4dCgpLmFzVW5kZXRWYXIoc1BhcmFtKSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB0UGFyYW1zID0gdFBhcmFtcy50YWlsOwogICAgICAgICAgICAgICAgICAgIHRQYXJhbXNOb0NhcHR1cmUgPSB0UGFyYW1zTm9DYXB0dXJlLnRhaWw7CiAgICAgICAgICAgICAgICAgICAgc1BhcmFtcyA9IHNQYXJhbXMudGFpbDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICghdFBhcmFtcy5pc0VtcHR5KCkgfHwgIXRQYXJhbXNOb0NhcHR1cmUuaXNFbXB0eSgpIHx8ICFzUGFyYW1zLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBjb21wYXJlIHJldHVybnMKICAgICAgICAgICAgICAgIFR5cGUgdFJldCA9IHREZXNjLmdldFJldHVyblR5cGUoKTsKICAgICAgICAgICAgICAgIFR5cGUgc1JldCA9IHR5cGVzLnN1YnN0KHNEZXNjLmdldFJldHVyblR5cGUoKSwgc1R5cGVQYXJhbXMsIHRUeXBlUGFyYW1zKTsKICAgICAgICAgICAgICAgIGlmICh0UmV0LmNvbnRhaW5zQW55KHRUeXBlUGFyYW1zKSAmJiBpbmZlcmVuY2VDb250ZXh0KCkuZnJlZShzUmV0KSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIE1vc3RTcGVjaWZpY0Z1bmN0aW9uUmV0dXJuQ2hlY2tlciBtc2MgPSBuZXcgTW9zdFNwZWNpZmljRnVuY3Rpb25SZXR1cm5DaGVja2VyKHRSZXQsIHNSZXQpOwogICAgICAgICAgICAgICAgbXNjLnNjYW4odHJlZSk7CiAgICAgICAgICAgICAgICByZXR1cm4gbXNjLnJlc3VsdDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIFRlc3RzIHdoZXRoZXIgb25lIGZ1bmN0aW9uYWwgaW50ZXJmYWNlIHR5cGUgY2FuIGJlIGNvbnNpZGVyZWQgbW9yZSBzcGVjaWZpYwogICAgICAgICAgICAgKiB0aGFuIGFub3RoZXIgdW5yZWxhdGVkIGZ1bmN0aW9uYWwgaW50ZXJmYWNlIHR5cGUgZm9yIHRoZSBzY2FubmVkIGV4cHJlc3Npb24uCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBjbGFzcyBNb3N0U3BlY2lmaWNGdW5jdGlvblJldHVybkNoZWNrZXIgZXh0ZW5kcyBEZWZlcnJlZEF0dHIuUG9seVNjYW5uZXIgewoKICAgICAgICAgICAgICAgIGZpbmFsIFR5cGUgdFJldDsKICAgICAgICAgICAgICAgIGZpbmFsIFR5cGUgc1JldDsKICAgICAgICAgICAgICAgIGJvb2xlYW4gcmVzdWx0OwoKICAgICAgICAgICAgICAgIC8qKiBQYXJhbWV0ZXJzIHtAY29kZSB0fSBhbmQge0Bjb2RlIHN9IGFyZSB1bnJlbGF0ZWQgZnVuY3Rpb25hbCBpbnRlcmZhY2UgdHlwZXMuICovCiAgICAgICAgICAgICAgICBNb3N0U3BlY2lmaWNGdW5jdGlvblJldHVybkNoZWNrZXIoVHlwZSB0UmV0LCBUeXBlIHNSZXQpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLnRSZXQgPSB0UmV0OwogICAgICAgICAgICAgICAgICAgIHRoaXMuc1JldCA9IHNSZXQ7CiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgICAgIHZvaWQgc2tpcChKQ1RyZWUgdHJlZSkgewogICAgICAgICAgICAgICAgICAgIHJlc3VsdCAmPSBmYWxzZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0Q29uZGl0aW9uYWwoSkNDb25kaXRpb25hbCB0cmVlKSB7CiAgICAgICAgICAgICAgICAgICAgc2Nhbihhc0V4cHIodHJlZS50cnVlcGFydCkpOwogICAgICAgICAgICAgICAgICAgIHNjYW4oYXNFeHByKHRyZWUuZmFsc2VwYXJ0KSk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdFJlZmVyZW5jZShKQ01lbWJlclJlZmVyZW5jZSB0cmVlKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHNSZXQuaGFzVGFnKFZPSUQpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCAmPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodFJldC5oYXNUYWcoVk9JRCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ICY9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodFJldC5pc1ByaW1pdGl2ZSgpICE9IHNSZXQuaXNQcmltaXRpdmUoKSkgewogICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIHJldFZhbElzUHJpbWl0aXZlID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmVlLnJlZlBvbHlLaW5kID09IFBvbHlLaW5kLlNUQU5EQUxPTkUgJiYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmVlLnN5bS50eXBlLmdldFJldHVyblR5cGUoKS5pc1ByaW1pdGl2ZSgpOwogICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQgJj0gKHJldFZhbElzUHJpbWl0aXZlID09IHRSZXQuaXNQcmltaXRpdmUoKSkgJiYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChyZXRWYWxJc1ByaW1pdGl2ZSAhPSBzUmV0LmlzUHJpbWl0aXZlKCkpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCAmPSBjb21wYXRpYmxlQnlTdWJ0eXBpbmcodFJldCwgc1JldCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICAgICAgcHVibGljIHZvaWQgdmlzaXRQYXJlbnMoSkNQYXJlbnMgdHJlZSkgewogICAgICAgICAgICAgICAgICAgIHNjYW4oYXNFeHByKHRyZWUuZXhwcikpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICAgICAgcHVibGljIHZvaWQgdmlzaXRMYW1iZGEoSkNMYW1iZGEgdHJlZSkgewogICAgICAgICAgICAgICAgICAgIGlmIChzUmV0Lmhhc1RhZyhWT0lEKSkgewogICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQgJj0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHRSZXQuaGFzVGFnKFZPSUQpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCAmPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBMaXN0PEpDRXhwcmVzc2lvbj4gbGFtYmRhUmVzdWx0cyA9IGxhbWJkYVJlc3VsdHModHJlZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghbGFtYmRhUmVzdWx0cy5pc0VtcHR5KCkgJiYgdW5yZWxhdGVkRnVuY3Rpb25hbEludGVyZmFjZXModFJldCwgc1JldCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoSkNFeHByZXNzaW9uIGV4cHIgOiBsYW1iZGFSZXN1bHRzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ICY9IGZ1bmN0aW9uYWxJbnRlcmZhY2VNb3N0U3BlY2lmaWModFJldCwgc1JldCwgZXhwcik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoIWxhbWJkYVJlc3VsdHMuaXNFbXB0eSgpICYmIHRSZXQuaXNQcmltaXRpdmUoKSAhPSBzUmV0LmlzUHJpbWl0aXZlKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoSkNFeHByZXNzaW9uIGV4cHIgOiBsYW1iZGFSZXN1bHRzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiByZXRWYWxJc1ByaW1pdGl2ZSA9IGV4cHIuaXNTdGFuZGFsb25lKCkgJiYgZXhwci50eXBlLmlzUHJpbWl0aXZlKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ICY9IChyZXRWYWxJc1ByaW1pdGl2ZSA9PSB0UmV0LmlzUHJpbWl0aXZlKCkpICYmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAocmV0VmFsSXNQcmltaXRpdmUgIT0gc1JldC5pc1ByaW1pdGl2ZSgpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCAmPSBjb21wYXRpYmxlQnlTdWJ0eXBpbmcodFJldCwgc1JldCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvL3doZXJlCgogICAgICAgICAgICAgICAgcHJpdmF0ZSBMaXN0PEpDRXhwcmVzc2lvbj4gbGFtYmRhUmVzdWx0cyhKQ0xhbWJkYSBsYW1iZGEpIHsKICAgICAgICAgICAgICAgICAgICBpZiAobGFtYmRhLmdldEJvZHlLaW5kKCkgPT0gSkNUcmVlLkpDTGFtYmRhLkJvZHlLaW5kLkVYUFJFU1NJT04pIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIExpc3Qub2YoYXNFeHByKChKQ0V4cHJlc3Npb24pIGxhbWJkYS5ib2R5KSk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgTGlzdEJ1ZmZlcjxKQ0V4cHJlc3Npb24+IGJ1ZmZlciA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICAgICAgICAgICAgICAgICAgRGVmZXJyZWRBdHRyLkxhbWJkYVJldHVyblNjYW5uZXIgbGFtYmRhU2Nhbm5lciA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IERlZmVycmVkQXR0ci5MYW1iZGFSZXR1cm5TY2FubmVyKCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHVibGljIHZvaWQgdmlzaXRSZXR1cm4oSkNSZXR1cm4gdHJlZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRyZWUuZXhwciAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZChhc0V4cHIodHJlZS5leHByKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgICAgICAgICBsYW1iZGFTY2FubmVyLnNjYW4obGFtYmRhLmJvZHkpOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYnVmZmVyLnRvTGlzdCgpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBwcml2YXRlIEpDRXhwcmVzc2lvbiBhc0V4cHIoSkNFeHByZXNzaW9uIGV4cHIpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoZXhwci50eXBlLmhhc1RhZyhERUZFUlJFRCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgSkNUcmVlIHNwZWN1bGF0aXZlVHJlZSA9ICgoRGVmZXJyZWRUeXBlKWV4cHIudHlwZSkuc3BlY3VsYXRpdmVUcmVlKGRlZmVycmVkQXR0ckNvbnRleHQpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3BlY3VsYXRpdmVUcmVlICE9IGRlZmVycmVkQXR0ci5zdHVja1RyZWUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cHIgPSAoSkNFeHByZXNzaW9uKXNwZWN1bGF0aXZlVHJlZTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICByZXR1cm4gZXhwcjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBNZXRob2RDaGVjayBtb3N0U3BlY2lmaWNDaGVjayhMaXN0PFR5cGU+IGFjdHVhbHMpIHsKICAgICAgICAgICAgQXNzZXJ0LmVycm9yKCJDYW5ub3QgZ2V0IGhlcmUhIik7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIEluYXBwbGljYWJsZU1ldGhvZEV4Y2VwdGlvbiBleHRlbmRzIFJ1bnRpbWVFeGNlcHRpb24gewogICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDA7CgogICAgICAgIEpDRGlhZ25vc3RpYyBkaWFnbm9zdGljOwogICAgICAgIEpDRGlhZ25vc3RpYy5GYWN0b3J5IGRpYWdzOwoKICAgICAgICBJbmFwcGxpY2FibGVNZXRob2RFeGNlcHRpb24oSkNEaWFnbm9zdGljLkZhY3RvcnkgZGlhZ3MpIHsKICAgICAgICAgICAgdGhpcy5kaWFnbm9zdGljID0gbnVsbDsKICAgICAgICAgICAgdGhpcy5kaWFncyA9IGRpYWdzOwogICAgICAgIH0KICAgICAgICBJbmFwcGxpY2FibGVNZXRob2RFeGNlcHRpb24gc2V0TWVzc2FnZSgpIHsKICAgICAgICAgICAgcmV0dXJuIHNldE1lc3NhZ2UoKEpDRGlhZ25vc3RpYyludWxsKTsKICAgICAgICB9CiAgICAgICAgSW5hcHBsaWNhYmxlTWV0aG9kRXhjZXB0aW9uIHNldE1lc3NhZ2UoU3RyaW5nIGtleSkgewogICAgICAgICAgICByZXR1cm4gc2V0TWVzc2FnZShrZXkgIT0gbnVsbCA/IGRpYWdzLmZyYWdtZW50KGtleSkgOiBudWxsKTsKICAgICAgICB9CiAgICAgICAgSW5hcHBsaWNhYmxlTWV0aG9kRXhjZXB0aW9uIHNldE1lc3NhZ2UoU3RyaW5nIGtleSwgT2JqZWN0Li4uIGFyZ3MpIHsKICAgICAgICAgICAgcmV0dXJuIHNldE1lc3NhZ2Uoa2V5ICE9IG51bGwgPyBkaWFncy5mcmFnbWVudChrZXksIGFyZ3MpIDogbnVsbCk7CiAgICAgICAgfQogICAgICAgIEluYXBwbGljYWJsZU1ldGhvZEV4Y2VwdGlvbiBzZXRNZXNzYWdlKEpDRGlhZ25vc3RpYyBkaWFnKSB7CiAgICAgICAgICAgIHRoaXMuZGlhZ25vc3RpYyA9IGRpYWc7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIEpDRGlhZ25vc3RpYyBnZXREaWFnbm9zdGljKCkgewogICAgICAgICAgICByZXR1cm4gZGlhZ25vc3RpYzsKICAgICAgICB9CiAgICB9CiAgICBwcml2YXRlIGZpbmFsIEluYXBwbGljYWJsZU1ldGhvZEV4Y2VwdGlvbiBpbmFwcGxpY2FibGVNZXRob2RFeGNlcHRpb247CgovKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogIFN5bWJvbCBsb29rdXAKICogIHRoZSBmb2xsb3dpbmcgbmFtaW5nIGNvbnZlbnRpb25zIGZvciBhcmd1bWVudHMgYXJlIHVzZWQKICoKICogICAgICAgZW52ICAgICAgaXMgdGhlIGVudmlyb25tZW50IHdoZXJlIHRoZSBzeW1ib2wgd2FzIG1lbnRpb25lZAogKiAgICAgICBzaXRlICAgICBpcyB0aGUgdHlwZSBvZiB3aGljaCB0aGUgc3ltYm9sIGlzIGEgbWVtYmVyCiAqICAgICAgIG5hbWUgICAgIGlzIHRoZSBzeW1ib2wncyBuYW1lCiAqICAgICAgICAgICAgICAgIGlmIG5vIGFyZ3VtZW50cyBhcmUgZ2l2ZW4KICogICAgICAgYXJndHlwZXMgYXJlIHRoZSB2YWx1ZSBhcmd1bWVudHMsIGlmIHdlIHNlYXJjaCBmb3IgYSBtZXRob2QKICoKICogIElmIG5vIHN5bWJvbCB3YXMgZm91bmQsIGEgUmVzb2x2ZUVycm9yIGRldGFpbGluZyB0aGUgcHJvYmxlbSBpcyByZXR1cm5lZC4KICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgogICAgLyoqIEZpbmQgZmllbGQuIFN5bnRoZXRpYyBmaWVsZHMgYXJlIGFsd2F5cyBza2lwcGVkLgogICAgICogIEBwYXJhbSBlbnYgICAgIFRoZSBjdXJyZW50IGVudmlyb25tZW50LgogICAgICogIEBwYXJhbSBzaXRlICAgIFRoZSBvcmlnaW5hbCB0eXBlIGZyb20gd2hlcmUgdGhlIHNlbGVjdGlvbiB0YWtlcyBwbGFjZS4KICAgICAqICBAcGFyYW0gbmFtZSAgICBUaGUgbmFtZSBvZiB0aGUgZmllbGQuCiAgICAgKiAgQHBhcmFtIGMgICAgICAgVGhlIGNsYXNzIHRvIHNlYXJjaCBmb3IgdGhlIGZpZWxkLiBUaGlzIGlzIGFsd2F5cwogICAgICogICAgICAgICAgICAgICAgIGEgc3VwZXJjbGFzcyBvciBpbXBsZW1lbnRlZCBpbnRlcmZhY2Ugb2Ygc2l0ZSdzIGNsYXNzLgogICAgICovCiAgICBTeW1ib2wgZmluZEZpZWxkKEVudjxBdHRyQ29udGV4dD4gZW52LAogICAgICAgICAgICAgICAgICAgICBUeXBlIHNpdGUsCiAgICAgICAgICAgICAgICAgICAgIE5hbWUgbmFtZSwKICAgICAgICAgICAgICAgICAgICAgVHlwZVN5bWJvbCBjKSB7CiAgICAgICAgd2hpbGUgKGMudHlwZS5oYXNUYWcoVFlQRVZBUikpCiAgICAgICAgICAgIGMgPSBjLnR5cGUuZ2V0VXBwZXJCb3VuZCgpLnRzeW07CiAgICAgICAgU3ltYm9sIGJlc3RTb0ZhciA9IHZhck5vdEZvdW5kOwogICAgICAgIFN5bWJvbCBzeW07CiAgICAgICAgZm9yIChTeW1ib2wgcyA6IGMubWVtYmVycygpLmdldFN5bWJvbHNCeU5hbWUobmFtZSkpIHsKICAgICAgICAgICAgaWYgKHMua2luZCA9PSBWQVIgJiYgKHMuZmxhZ3NfZmllbGQgJiBTWU5USEVUSUMpID09IDApIHsKICAgICAgICAgICAgICAgIHJldHVybiBpc0FjY2Vzc2libGUoZW52LCBzaXRlLCBzKQogICAgICAgICAgICAgICAgICAgID8gcyA6IG5ldyBBY2Nlc3NFcnJvcihlbnYsIHNpdGUsIHMpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIFR5cGUgc3QgPSB0eXBlcy5zdXBlcnR5cGUoYy50eXBlKTsKICAgICAgICBpZiAoc3QgIT0gbnVsbCAmJiAoc3QuaGFzVGFnKENMQVNTKSB8fCBzdC5oYXNUYWcoVFlQRVZBUikpKSB7CiAgICAgICAgICAgIHN5bSA9IGZpbmRGaWVsZChlbnYsIHNpdGUsIG5hbWUsIHN0LnRzeW0pOwogICAgICAgICAgICBiZXN0U29GYXIgPSBiZXN0T2YoYmVzdFNvRmFyLCBzeW0pOwogICAgICAgIH0KICAgICAgICBmb3IgKExpc3Q8VHlwZT4gbCA9IHR5cGVzLmludGVyZmFjZXMoYy50eXBlKTsKICAgICAgICAgICAgIGJlc3RTb0Zhci5raW5kICE9IEFNQklHVU9VUyAmJiBsLm5vbkVtcHR5KCk7CiAgICAgICAgICAgICBsID0gbC50YWlsKSB7CiAgICAgICAgICAgIHN5bSA9IGZpbmRGaWVsZChlbnYsIHNpdGUsIG5hbWUsIGwuaGVhZC50c3ltKTsKICAgICAgICAgICAgaWYgKGJlc3RTb0Zhci5leGlzdHMoKSAmJiBzeW0uZXhpc3RzKCkgJiYKICAgICAgICAgICAgICAgIHN5bS5vd25lciAhPSBiZXN0U29GYXIub3duZXIpCiAgICAgICAgICAgICAgICBiZXN0U29GYXIgPSBuZXcgQW1iaWd1aXR5RXJyb3IoYmVzdFNvRmFyLCBzeW0pOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBiZXN0U29GYXIgPSBiZXN0T2YoYmVzdFNvRmFyLCBzeW0pOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYmVzdFNvRmFyOwogICAgfQoKICAgIC8qKiBSZXNvbHZlIGEgZmllbGQgaWRlbnRpZmllciwgdGhyb3cgYSBmYXRhbCBlcnJvciBpZiBub3QgZm91bmQuCiAgICAgKiAgQHBhcmFtIHBvcyAgICAgICBUaGUgcG9zaXRpb24gdG8gdXNlIGZvciBlcnJvciByZXBvcnRpbmcuCiAgICAgKiAgQHBhcmFtIGVudiAgICAgICBUaGUgZW52aXJvbm1lbnQgY3VycmVudCBhdCB0aGUgbWV0aG9kIGludm9jYXRpb24uCiAgICAgKiAgQHBhcmFtIHNpdGUgICAgICBUaGUgdHlwZSBvZiB0aGUgcXVhbGlmeWluZyBleHByZXNzaW9uLCBpbiB3aGljaAogICAgICogICAgICAgICAgICAgICAgICAgaWRlbnRpZmllciBpcyBzZWFyY2hlZC4KICAgICAqICBAcGFyYW0gbmFtZSAgICAgIFRoZSBpZGVudGlmaWVyJ3MgbmFtZS4KICAgICAqLwogICAgcHVibGljIFZhclN5bWJvbCByZXNvbHZlSW50ZXJuYWxGaWVsZChEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBFbnY8QXR0ckNvbnRleHQ+IGVudiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVHlwZSBzaXRlLCBOYW1lIG5hbWUpIHsKICAgICAgICBTeW1ib2wgc3ltID0gZmluZEZpZWxkKGVudiwgc2l0ZSwgbmFtZSwgc2l0ZS50c3ltKTsKICAgICAgICBpZiAoc3ltLmtpbmQgPT0gVkFSKSByZXR1cm4gKFZhclN5bWJvbClzeW07CiAgICAgICAgZWxzZSB0aHJvdyBuZXcgRmF0YWxFcnJvcigKICAgICAgICAgICAgICAgICBkaWFncy5mcmFnbWVudCgiZmF0YWwuZXJyLmNhbnQubG9jYXRlLmZpZWxkIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lKSk7CiAgICB9CgogICAgLyoqIEZpbmQgdW5xdWFsaWZpZWQgdmFyaWFibGUgb3IgZmllbGQgd2l0aCBnaXZlbiBuYW1lLgogICAgICogIFN5bnRoZXRpYyBmaWVsZHMgYWx3YXlzIHNraXBwZWQuCiAgICAgKiAgQHBhcmFtIGVudiAgICAgVGhlIGN1cnJlbnQgZW52aXJvbm1lbnQuCiAgICAgKiAgQHBhcmFtIG5hbWUgICAgVGhlIG5hbWUgb2YgdGhlIHZhcmlhYmxlIG9yIGZpZWxkLgogICAgICovCiAgICBTeW1ib2wgZmluZFZhcihFbnY8QXR0ckNvbnRleHQ+IGVudiwgTmFtZSBuYW1lKSB7CiAgICAgICAgU3ltYm9sIGJlc3RTb0ZhciA9IHZhck5vdEZvdW5kOwogICAgICAgIEVudjxBdHRyQ29udGV4dD4gZW52MSA9IGVudjsKICAgICAgICBib29sZWFuIHN0YXRpY09ubHkgPSBmYWxzZTsKICAgICAgICB3aGlsZSAoZW52MS5vdXRlciAhPSBudWxsKSB7CiAgICAgICAgICAgIFN5bWJvbCBzeW0gPSBudWxsOwogICAgICAgICAgICBpZiAoaXNTdGF0aWMoZW52MSkpIHN0YXRpY09ubHkgPSB0cnVlOwogICAgICAgICAgICBmb3IgKFN5bWJvbCBzIDogZW52MS5pbmZvLnNjb3BlLmdldFN5bWJvbHNCeU5hbWUobmFtZSkpIHsKICAgICAgICAgICAgICAgIGlmIChzLmtpbmQgPT0gVkFSICYmIChzLmZsYWdzX2ZpZWxkICYgU1lOVEhFVElDKSA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgc3ltID0gczsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoc3ltID09IG51bGwpIHsKICAgICAgICAgICAgICAgIHN5bSA9IGZpbmRGaWVsZChlbnYxLCBlbnYxLmVuY2xDbGFzcy5zeW0udHlwZSwgbmFtZSwgZW52MS5lbmNsQ2xhc3Muc3ltKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoc3ltLmV4aXN0cygpKSB7CiAgICAgICAgICAgICAgICBpZiAoc3RhdGljT25seSAmJgogICAgICAgICAgICAgICAgICAgIHN5bS5raW5kID09IFZBUiAmJgogICAgICAgICAgICAgICAgICAgIHN5bS5vd25lci5raW5kID09IFRZUCAmJgogICAgICAgICAgICAgICAgICAgIChzeW0uZmxhZ3MoKSAmIFNUQVRJQykgPT0gMCkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFN0YXRpY0Vycm9yKHN5bSk7CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHN5bTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGJlc3RTb0ZhciA9IGJlc3RPZihiZXN0U29GYXIsIHN5bSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgoZW52MS5lbmNsQ2xhc3Muc3ltLmZsYWdzKCkgJiBTVEFUSUMpICE9IDApIHN0YXRpY09ubHkgPSB0cnVlOwogICAgICAgICAgICBlbnYxID0gZW52MS5vdXRlcjsKICAgICAgICB9CgogICAgICAgIFN5bWJvbCBzeW0gPSBmaW5kRmllbGQoZW52LCBzeW1zLnByZWRlZkNsYXNzLnR5cGUsIG5hbWUsIHN5bXMucHJlZGVmQ2xhc3MpOwogICAgICAgIGlmIChzeW0uZXhpc3RzKCkpCiAgICAgICAgICAgIHJldHVybiBzeW07CiAgICAgICAgaWYgKGJlc3RTb0Zhci5leGlzdHMoKSkKICAgICAgICAgICAgcmV0dXJuIGJlc3RTb0ZhcjsKCiAgICAgICAgU3ltYm9sIG9yaWdpbiA9IG51bGw7CiAgICAgICAgZm9yIChTY29wZSBzYyA6IG5ldyBTY29wZVtdIHsgZW52LnRvcGxldmVsLm5hbWVkSW1wb3J0U2NvcGUsIGVudi50b3BsZXZlbC5zdGFySW1wb3J0U2NvcGUgfSkgewogICAgICAgICAgICBmb3IgKFN5bWJvbCBjdXJyZW50U3ltYm9sIDogc2MuZ2V0U3ltYm9sc0J5TmFtZShuYW1lKSkgewogICAgICAgICAgICAgICAgaWYgKGN1cnJlbnRTeW1ib2wua2luZCAhPSBWQVIpCiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICAvLyBpbnZhcmlhbnQ6IHN5bS5raW5kID09IFN5bWJvbC5LaW5kLlZBUgogICAgICAgICAgICAgICAgaWYgKCFiZXN0U29GYXIua2luZC5pc1Jlc29sdXRpb25FcnJvcigpICYmCiAgICAgICAgICAgICAgICAgICAgY3VycmVudFN5bWJvbC5vd25lciAhPSBiZXN0U29GYXIub3duZXIpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBBbWJpZ3VpdHlFcnJvcihiZXN0U29GYXIsIGN1cnJlbnRTeW1ib2wpOwogICAgICAgICAgICAgICAgZWxzZSBpZiAoIWJlc3RTb0Zhci5raW5kLmJldHRlclRoYW4oVkFSKSkgewogICAgICAgICAgICAgICAgICAgIG9yaWdpbiA9IHNjLmdldE9yaWdpbihjdXJyZW50U3ltYm9sKS5vd25lcjsKICAgICAgICAgICAgICAgICAgICBiZXN0U29GYXIgPSBpc0FjY2Vzc2libGUoZW52LCBvcmlnaW4udHlwZSwgY3VycmVudFN5bWJvbCkKICAgICAgICAgICAgICAgICAgICAgICAgPyBjdXJyZW50U3ltYm9sIDogbmV3IEFjY2Vzc0Vycm9yKGVudiwgb3JpZ2luLnR5cGUsIGN1cnJlbnRTeW1ib2wpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChiZXN0U29GYXIuZXhpc3RzKCkpIGJyZWFrOwogICAgICAgIH0KICAgICAgICBpZiAoYmVzdFNvRmFyLmtpbmQgPT0gVkFSICYmIGJlc3RTb0Zhci5vd25lci50eXBlICE9IG9yaWdpbi50eXBlKQogICAgICAgICAgICByZXR1cm4gYmVzdFNvRmFyLmNsb25lKG9yaWdpbik7CiAgICAgICAgZWxzZQogICAgICAgICAgICByZXR1cm4gYmVzdFNvRmFyOwogICAgfQoKICAgIFdhcm5lciBub3RlV2FybmVyID0gbmV3IFdhcm5lcigpOwoKICAgIC8qKiBTZWxlY3QgdGhlIGJlc3QgbWV0aG9kIGZvciBhIGNhbGwgc2l0ZSBhbW9uZyB0d28gY2hvaWNlcy4KICAgICAqICBAcGFyYW0gZW52ICAgICAgICAgICAgICBUaGUgY3VycmVudCBlbnZpcm9ubWVudC4KICAgICAqICBAcGFyYW0gc2l0ZSAgICAgICAgICAgICBUaGUgb3JpZ2luYWwgdHlwZSBmcm9tIHdoZXJlIHRoZQogICAgICogICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGVjdGlvbiB0YWtlcyBwbGFjZS4KICAgICAqICBAcGFyYW0gYXJndHlwZXMgICAgICAgICBUaGUgaW52b2NhdGlvbidzIHZhbHVlIGFyZ3VtZW50cywKICAgICAqICBAcGFyYW0gdHlwZWFyZ3R5cGVzICAgICBUaGUgaW52b2NhdGlvbidzIHR5cGUgYXJndW1lbnRzLAogICAgICogIEBwYXJhbSBzeW0gICAgICAgICAgICAgIFByb3Bvc2VkIG5ldyBiZXN0IG1hdGNoLgogICAgICogIEBwYXJhbSBiZXN0U29GYXIgICAgICAgIFByZXZpb3VzbHkgZm91bmQgYmVzdCBtYXRjaC4KICAgICAqICBAcGFyYW0gYWxsb3dCb3hpbmcgQWxsb3cgYm94aW5nIGNvbnZlcnNpb25zIG9mIGFyZ3VtZW50cy4KICAgICAqICBAcGFyYW0gdXNlVmFyYXJncyBCb3ggdHJhaWxpbmcgYXJndW1lbnRzIGludG8gYW4gYXJyYXkgZm9yIHZhcmFyZ3MuCiAgICAgKi8KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJmYWxsdGhyb3VnaCIpCiAgICBTeW1ib2wgc2VsZWN0QmVzdChFbnY8QXR0ckNvbnRleHQ+IGVudiwKICAgICAgICAgICAgICAgICAgICAgIFR5cGUgc2l0ZSwKICAgICAgICAgICAgICAgICAgICAgIExpc3Q8VHlwZT4gYXJndHlwZXMsCiAgICAgICAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IHR5cGVhcmd0eXBlcywKICAgICAgICAgICAgICAgICAgICAgIFN5bWJvbCBzeW0sCiAgICAgICAgICAgICAgICAgICAgICBTeW1ib2wgYmVzdFNvRmFyLAogICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBhbGxvd0JveGluZywKICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gdXNlVmFyYXJncykgewogICAgICAgIGlmIChzeW0ua2luZCA9PSBFUlIgfHwKICAgICAgICAgICAgICAgICFzeW0uaXNJbmhlcml0ZWRJbihzaXRlLnRzeW0sIHR5cGVzKSkgewogICAgICAgICAgICByZXR1cm4gYmVzdFNvRmFyOwogICAgICAgIH0gZWxzZSBpZiAodXNlVmFyYXJncyAmJiAoc3ltLmZsYWdzKCkgJiBWQVJBUkdTKSA9PSAwKSB7CiAgICAgICAgICAgIHJldHVybiBiZXN0U29GYXIua2luZC5pc1Jlc29sdXRpb25FcnJvcigpID8KICAgICAgICAgICAgICAgICAgICBuZXcgQmFkVmFyYXJnc01ldGhvZCgoUmVzb2x2ZUVycm9yKWJlc3RTb0Zhci5iYXNlU3ltYm9sKCkpIDoKICAgICAgICAgICAgICAgICAgICBiZXN0U29GYXI7CiAgICAgICAgfQogICAgICAgIEFzc2VydC5jaGVjayghc3ltLmtpbmQuaXNSZXNvbHV0aW9uRXJyb3IoKSk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgdHlwZXMubm9XYXJuaW5ncy5jbGVhcigpOwogICAgICAgICAgICBUeXBlIG10ID0gcmF3SW5zdGFudGlhdGUoZW52LCBzaXRlLCBzeW0sIG51bGwsIGFyZ3R5cGVzLCB0eXBlYXJndHlwZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbGxvd0JveGluZywgdXNlVmFyYXJncywgdHlwZXMubm9XYXJuaW5ncyk7CiAgICAgICAgICAgIGN1cnJlbnRSZXNvbHV0aW9uQ29udGV4dC5hZGRBcHBsaWNhYmxlQ2FuZGlkYXRlKHN5bSwgbXQpOwogICAgICAgIH0gY2F0Y2ggKEluYXBwbGljYWJsZU1ldGhvZEV4Y2VwdGlvbiBleCkgewogICAgICAgICAgICBjdXJyZW50UmVzb2x1dGlvbkNvbnRleHQuYWRkSW5hcHBsaWNhYmxlQ2FuZGlkYXRlKHN5bSwgZXguZ2V0RGlhZ25vc3RpYygpKTsKICAgICAgICAgICAgc3dpdGNoIChiZXN0U29GYXIua2luZCkgewogICAgICAgICAgICAgICAgY2FzZSBBQlNFTlRfTVRIOgogICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgSW5hcHBsaWNhYmxlU3ltYm9sRXJyb3IoY3VycmVudFJlc29sdXRpb25Db250ZXh0KTsKICAgICAgICAgICAgICAgIGNhc2UgV1JPTkdfTVRIOgogICAgICAgICAgICAgICAgICAgIGJlc3RTb0ZhciA9IG5ldyBJbmFwcGxpY2FibGVTeW1ib2xzRXJyb3IoY3VycmVudFJlc29sdXRpb25Db250ZXh0KTsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGJlc3RTb0ZhcjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoIWlzQWNjZXNzaWJsZShlbnYsIHNpdGUsIHN5bSkpIHsKICAgICAgICAgICAgcmV0dXJuIChiZXN0U29GYXIua2luZCA9PSBBQlNFTlRfTVRIKQogICAgICAgICAgICAgICAgPyBuZXcgQWNjZXNzRXJyb3IoZW52LCBzaXRlLCBzeW0pCiAgICAgICAgICAgICAgICA6IGJlc3RTb0ZhcjsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIChiZXN0U29GYXIua2luZC5pc1Jlc29sdXRpb25FcnJvcigpICYmIGJlc3RTb0Zhci5raW5kICE9IEFNQklHVU9VUykKICAgICAgICAgICAgPyBzeW0KICAgICAgICAgICAgOiBtb3N0U3BlY2lmaWMoYXJndHlwZXMsIHN5bSwgYmVzdFNvRmFyLCBlbnYsIHNpdGUsIHVzZVZhcmFyZ3MpOwogICAgfQoKICAgIC8qIFJldHVybiB0aGUgbW9zdCBzcGVjaWZpYyBvZiB0aGUgdHdvIG1ldGhvZHMgZm9yIGEgY2FsbCwKICAgICAqICBnaXZlbiB0aGF0IGJvdGggYXJlIGFjY2Vzc2libGUgYW5kIGFwcGxpY2FibGUuCiAgICAgKiAgQHBhcmFtIG0xICAgICAgICAgICAgICAgQSBuZXcgY2FuZGlkYXRlIGZvciBtb3N0IHNwZWNpZmljLgogICAgICogIEBwYXJhbSBtMiAgICAgICAgICAgICAgIFRoZSBwcmV2aW91cyBtb3N0IHNwZWNpZmljIGNhbmRpZGF0ZS4KICAgICAqICBAcGFyYW0gZW52ICAgICAgICAgICAgICBUaGUgY3VycmVudCBlbnZpcm9ubWVudC4KICAgICAqICBAcGFyYW0gc2l0ZSAgICAgICAgICAgICBUaGUgb3JpZ2luYWwgdHlwZSBmcm9tIHdoZXJlIHRoZSBzZWxlY3Rpb24KICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICB0YWtlcyBwbGFjZS4KICAgICAqICBAcGFyYW0gYWxsb3dCb3hpbmcgQWxsb3cgYm94aW5nIGNvbnZlcnNpb25zIG9mIGFyZ3VtZW50cy4KICAgICAqICBAcGFyYW0gdXNlVmFyYXJncyBCb3ggdHJhaWxpbmcgYXJndW1lbnRzIGludG8gYW4gYXJyYXkgZm9yIHZhcmFyZ3MuCiAgICAgKi8KICAgIFN5bWJvbCBtb3N0U3BlY2lmaWMoTGlzdDxUeXBlPiBhcmd0eXBlcywgU3ltYm9sIG0xLAogICAgICAgICAgICAgICAgICAgICAgICBTeW1ib2wgbTIsCiAgICAgICAgICAgICAgICAgICAgICAgIEVudjxBdHRyQ29udGV4dD4gZW52LAogICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBUeXBlIHNpdGUsCiAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gdXNlVmFyYXJncykgewogICAgICAgIHN3aXRjaCAobTIua2luZCkgewogICAgICAgIGNhc2UgTVRIOgogICAgICAgICAgICBpZiAobTEgPT0gbTIpIHJldHVybiBtMTsKICAgICAgICAgICAgYm9vbGVhbiBtMVNpZ25hdHVyZU1vcmVTcGVjaWZpYyA9CiAgICAgICAgICAgICAgICAgICAgc2lnbmF0dXJlTW9yZVNwZWNpZmljKGFyZ3R5cGVzLCBlbnYsIHNpdGUsIG0xLCBtMiwgdXNlVmFyYXJncyk7CiAgICAgICAgICAgIGJvb2xlYW4gbTJTaWduYXR1cmVNb3JlU3BlY2lmaWMgPQogICAgICAgICAgICAgICAgICAgIHNpZ25hdHVyZU1vcmVTcGVjaWZpYyhhcmd0eXBlcywgZW52LCBzaXRlLCBtMiwgbTEsIHVzZVZhcmFyZ3MpOwogICAgICAgICAgICBpZiAobTFTaWduYXR1cmVNb3JlU3BlY2lmaWMgJiYgbTJTaWduYXR1cmVNb3JlU3BlY2lmaWMpIHsKICAgICAgICAgICAgICAgIFR5cGUgbXQxID0gdHlwZXMubWVtYmVyVHlwZShzaXRlLCBtMSk7CiAgICAgICAgICAgICAgICBUeXBlIG10MiA9IHR5cGVzLm1lbWJlclR5cGUoc2l0ZSwgbTIpOwogICAgICAgICAgICAgICAgaWYgKCF0eXBlcy5vdmVycmlkZUVxdWl2YWxlbnQobXQxLCBtdDIpKQogICAgICAgICAgICAgICAgICAgIHJldHVybiBhbWJpZ3VpdHlFcnJvcihtMSwgbTIpOwoKICAgICAgICAgICAgICAgIC8vIHNhbWUgc2lnbmF0dXJlOyBzZWxlY3QgKGEpIHRoZSBub24tYnJpZGdlIG1ldGhvZCwgb3IKICAgICAgICAgICAgICAgIC8vIChiKSB0aGUgb25lIHRoYXQgb3ZlcnJpZGVzIHRoZSBvdGhlciwgb3IgKGMpIHRoZSBjb25jcmV0ZQogICAgICAgICAgICAgICAgLy8gb25lLCBvciAoZCkgbWVyZ2UgYm90aCBhYnN0cmFjdCBzaWduYXR1cmVzCiAgICAgICAgICAgICAgICBpZiAoKG0xLmZsYWdzKCkgJiBCUklER0UpICE9IChtMi5mbGFncygpICYgQlJJREdFKSkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gKChtMS5mbGFncygpICYgQlJJREdFKSAhPSAwKSA/IG0yIDogbTE7CgogICAgICAgICAgICAgICAgLy8gaWYgb25lIG92ZXJyaWRlcyBvciBoaWRlcyB0aGUgb3RoZXIsIHVzZSBpdAogICAgICAgICAgICAgICAgVHlwZVN5bWJvbCBtMU93bmVyID0gKFR5cGVTeW1ib2wpbTEub3duZXI7CiAgICAgICAgICAgICAgICBUeXBlU3ltYm9sIG0yT3duZXIgPSAoVHlwZVN5bWJvbCltMi5vd25lcjsKICAgICAgICAgICAgICAgIGlmICh0eXBlcy5hc1N1cGVyKG0xT3duZXIudHlwZSwgbTJPd25lcikgIT0gbnVsbCAmJgogICAgICAgICAgICAgICAgICAgICgobTEub3duZXIuZmxhZ3NfZmllbGQgJiBJTlRFUkZBQ0UpID09IDAgfHwKICAgICAgICAgICAgICAgICAgICAgKG0yLm93bmVyLmZsYWdzX2ZpZWxkICYgSU5URVJGQUNFKSAhPSAwKSAmJgogICAgICAgICAgICAgICAgICAgIG0xLm92ZXJyaWRlcyhtMiwgbTFPd25lciwgdHlwZXMsIGZhbHNlKSkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbTE7CiAgICAgICAgICAgICAgICBpZiAodHlwZXMuYXNTdXBlcihtMk93bmVyLnR5cGUsIG0xT3duZXIpICE9IG51bGwgJiYKICAgICAgICAgICAgICAgICAgICAoKG0yLm93bmVyLmZsYWdzX2ZpZWxkICYgSU5URVJGQUNFKSA9PSAwIHx8CiAgICAgICAgICAgICAgICAgICAgIChtMS5vd25lci5mbGFnc19maWVsZCAmIElOVEVSRkFDRSkgIT0gMCkgJiYKICAgICAgICAgICAgICAgICAgICBtMi5vdmVycmlkZXMobTEsIG0yT3duZXIsIHR5cGVzLCBmYWxzZSkpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG0yOwogICAgICAgICAgICAgICAgYm9vbGVhbiBtMUFic3RyYWN0ID0gKG0xLmZsYWdzKCkgJiBBQlNUUkFDVCkgIT0gMDsKICAgICAgICAgICAgICAgIGJvb2xlYW4gbTJBYnN0cmFjdCA9IChtMi5mbGFncygpICYgQUJTVFJBQ1QpICE9IDA7CiAgICAgICAgICAgICAgICBpZiAobTFBYnN0cmFjdCAmJiAhbTJBYnN0cmFjdCkgcmV0dXJuIG0yOwogICAgICAgICAgICAgICAgaWYgKG0yQWJzdHJhY3QgJiYgIW0xQWJzdHJhY3QpIHJldHVybiBtMTsKICAgICAgICAgICAgICAgIC8vIGJvdGggYWJzdHJhY3Qgb3IgYm90aCBjb25jcmV0ZQogICAgICAgICAgICAgICAgcmV0dXJuIGFtYmlndWl0eUVycm9yKG0xLCBtMik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKG0xU2lnbmF0dXJlTW9yZVNwZWNpZmljKSByZXR1cm4gbTE7CiAgICAgICAgICAgIGlmIChtMlNpZ25hdHVyZU1vcmVTcGVjaWZpYykgcmV0dXJuIG0yOwogICAgICAgICAgICByZXR1cm4gYW1iaWd1aXR5RXJyb3IobTEsIG0yKTsKICAgICAgICBjYXNlIEFNQklHVU9VUzoKICAgICAgICAgICAgLy9jb21wYXJlIG0xIHRvIGFtYmlndW91cyBtZXRob2RzIGluIG0yCiAgICAgICAgICAgIEFtYmlndWl0eUVycm9yIGUgPSAoQW1iaWd1aXR5RXJyb3IpbTIuYmFzZVN5bWJvbCgpOwogICAgICAgICAgICBib29sZWFuIG0xTW9yZVNwZWNpZmljVGhhbkFueUFtYmlndW91cyA9IHRydWU7CiAgICAgICAgICAgIGJvb2xlYW4gYWxsQW1iaWd1b3VzTW9yZVNwZWNpZmljVGhhbk0xID0gdHJ1ZTsKICAgICAgICAgICAgZm9yIChTeW1ib2wgcyA6IGUuYW1iaWd1b3VzU3ltcykgewogICAgICAgICAgICAgICAgU3ltYm9sIG1vcmVTcGVjaWZpYyA9IG1vc3RTcGVjaWZpYyhhcmd0eXBlcywgbTEsIHMsIGVudiwgc2l0ZSwgdXNlVmFyYXJncyk7CiAgICAgICAgICAgICAgICBtMU1vcmVTcGVjaWZpY1RoYW5BbnlBbWJpZ3VvdXMgJj0gbW9yZVNwZWNpZmljID09IG0xOwogICAgICAgICAgICAgICAgYWxsQW1iaWd1b3VzTW9yZVNwZWNpZmljVGhhbk0xICY9IG1vcmVTcGVjaWZpYyA9PSBzOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChtMU1vcmVTcGVjaWZpY1RoYW5BbnlBbWJpZ3VvdXMpCiAgICAgICAgICAgICAgICByZXR1cm4gbTE7CiAgICAgICAgICAgIC8vaWYgbTEgaXMgbW9yZSBzcGVjaWZpYyB0aGFuIHNvbWUgYW1iaWd1b3VzIG1ldGhvZHMsIGJ1dCBvdGhlciBhbWJpZ3VvdXMgbWV0aG9kcyBhcmUKICAgICAgICAgICAgLy9tb3JlIHNwZWNpZmljIHRoYW4gbTEsIGFkZCBpdCBhcyBhIG5ldyBhbWJpZ3VvdXMgbWV0aG9kOgogICAgICAgICAgICBpZiAoIWFsbEFtYmlndW91c01vcmVTcGVjaWZpY1RoYW5NMSkKICAgICAgICAgICAgICAgIGUuYWRkQW1iaWd1b3VzU3ltYm9sKG0xKTsKICAgICAgICAgICAgcmV0dXJuIGU7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCk7CiAgICAgICAgfQogICAgfQogICAgLy93aGVyZQogICAgcHJpdmF0ZSBib29sZWFuIHNpZ25hdHVyZU1vcmVTcGVjaWZpYyhMaXN0PFR5cGU+IGFjdHVhbHMsIEVudjxBdHRyQ29udGV4dD4gZW52LCBUeXBlIHNpdGUsIFN5bWJvbCBtMSwgU3ltYm9sIG0yLCBib29sZWFuIHVzZVZhcmFyZ3MpIHsKICAgICAgICBub3RlV2FybmVyLmNsZWFyKCk7CiAgICAgICAgaW50IG1heExlbmd0aCA9IE1hdGgubWF4KAogICAgICAgICAgICAgICAgICAgICAgICAgICAgTWF0aC5tYXgobTEudHlwZS5nZXRQYXJhbWV0ZXJUeXBlcygpLmxlbmd0aCgpLCBhY3R1YWxzLmxlbmd0aCgpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG0yLnR5cGUuZ2V0UGFyYW1ldGVyVHlwZXMoKS5sZW5ndGgoKSk7CiAgICAgICAgTWV0aG9kUmVzb2x1dGlvbkNvbnRleHQgcHJldlJlc29sdXRpb25Db250ZXh0ID0gY3VycmVudFJlc29sdXRpb25Db250ZXh0OwogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGN1cnJlbnRSZXNvbHV0aW9uQ29udGV4dCA9IG5ldyBNZXRob2RSZXNvbHV0aW9uQ29udGV4dCgpOwogICAgICAgICAgICBjdXJyZW50UmVzb2x1dGlvbkNvbnRleHQuc3RlcCA9IHByZXZSZXNvbHV0aW9uQ29udGV4dC5zdGVwOwogICAgICAgICAgICBjdXJyZW50UmVzb2x1dGlvbkNvbnRleHQubWV0aG9kQ2hlY2sgPQogICAgICAgICAgICAgICAgICAgIHByZXZSZXNvbHV0aW9uQ29udGV4dC5tZXRob2RDaGVjay5tb3N0U3BlY2lmaWNDaGVjayhhY3R1YWxzKTsKICAgICAgICAgICAgVHlwZSBtc3QgPSBpbnN0YW50aWF0ZShlbnYsIHNpdGUsIG0yLCBudWxsLAogICAgICAgICAgICAgICAgICAgIGFkanVzdEFyZ3ModHlwZXMuY3Zhckxvd2VyQm91bmRzKHR5cGVzLm1lbWJlclR5cGUoc2l0ZSwgbTEpLmdldFBhcmFtZXRlclR5cGVzKCkpLCBtMSwgbWF4TGVuZ3RoLCB1c2VWYXJhcmdzKSwgbnVsbCwKICAgICAgICAgICAgICAgICAgICBmYWxzZSwgdXNlVmFyYXJncywgbm90ZVdhcm5lcik7CiAgICAgICAgICAgIHJldHVybiBtc3QgIT0gbnVsbCAmJgogICAgICAgICAgICAgICAgICAgICFub3RlV2FybmVyLmhhc0xpbnQoTGludC5MaW50Q2F0ZWdvcnkuVU5DSEVDS0VEKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICBjdXJyZW50UmVzb2x1dGlvbkNvbnRleHQgPSBwcmV2UmVzb2x1dGlvbkNvbnRleHQ7CiAgICAgICAgfQogICAgfQoKICAgIExpc3Q8VHlwZT4gYWRqdXN0QXJncyhMaXN0PFR5cGU+IGFyZ3MsIFN5bWJvbCBtc3ltLCBpbnQgbGVuZ3RoLCBib29sZWFuIGFsbG93VmFyYXJncykgewogICAgICAgIGlmICgobXN5bS5mbGFncygpICYgVkFSQVJHUykgIT0gMCAmJiBhbGxvd1ZhcmFyZ3MpIHsKICAgICAgICAgICAgVHlwZSB2YXJhcmdzRWxlbSA9IHR5cGVzLmVsZW10eXBlKGFyZ3MubGFzdCgpKTsKICAgICAgICAgICAgaWYgKHZhcmFyZ3NFbGVtID09IG51bGwpIHsKICAgICAgICAgICAgICAgIEFzc2VydC5lcnJvcigiQmFkIHZhcmFyZ3MgPSAiICsgYXJncy5sYXN0KCkgKyAiICIgKyBtc3ltKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBMaXN0PFR5cGU+IG5ld0FyZ3MgPSBhcmdzLnJldmVyc2UoKS50YWlsLnByZXBlbmQodmFyYXJnc0VsZW0pLnJldmVyc2UoKTsKICAgICAgICAgICAgd2hpbGUgKG5ld0FyZ3MubGVuZ3RoKCkgPCBsZW5ndGgpIHsKICAgICAgICAgICAgICAgIG5ld0FyZ3MgPSBuZXdBcmdzLmFwcGVuZChuZXdBcmdzLmxhc3QoKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG5ld0FyZ3M7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIGFyZ3M7CiAgICAgICAgfQogICAgfQogICAgLy93aGVyZQogICAgU3ltYm9sIGFtYmlndWl0eUVycm9yKFN5bWJvbCBtMSwgU3ltYm9sIG0yKSB7CiAgICAgICAgaWYgKCgobTEuZmxhZ3MoKSB8IG0yLmZsYWdzKCkpICYgQ0xBU0gpICE9IDApIHsKICAgICAgICAgICAgcmV0dXJuIChtMS5mbGFncygpICYgQ0xBU0gpID09IDAgPyBtMSA6IG0yOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiBuZXcgQW1iaWd1aXR5RXJyb3IobTEsIG0yKTsKICAgICAgICB9CiAgICB9CgogICAgU3ltYm9sIGZpbmRNZXRob2RJblNjb3BlKEVudjxBdHRyQ29udGV4dD4gZW52LAogICAgICAgICAgICBUeXBlIHNpdGUsCiAgICAgICAgICAgIE5hbWUgbmFtZSwKICAgICAgICAgICAgTGlzdDxUeXBlPiBhcmd0eXBlcywKICAgICAgICAgICAgTGlzdDxUeXBlPiB0eXBlYXJndHlwZXMsCiAgICAgICAgICAgIFNjb3BlIHNjLAogICAgICAgICAgICBTeW1ib2wgYmVzdFNvRmFyLAogICAgICAgICAgICBib29sZWFuIGFsbG93Qm94aW5nLAogICAgICAgICAgICBib29sZWFuIHVzZVZhcmFyZ3MsCiAgICAgICAgICAgIGJvb2xlYW4gYWJzdHJhY3RvaykgewogICAgICAgIGZvciAoU3ltYm9sIHMgOiBzYy5nZXRTeW1ib2xzQnlOYW1lKG5hbWUsIG5ldyBMb29rdXBGaWx0ZXIoYWJzdHJhY3RvaykpKSB7CiAgICAgICAgICAgIGJlc3RTb0ZhciA9IHNlbGVjdEJlc3QoZW52LCBzaXRlLCBhcmd0eXBlcywgdHlwZWFyZ3R5cGVzLCBzLAogICAgICAgICAgICAgICAgICAgIGJlc3RTb0ZhciwgYWxsb3dCb3hpbmcsIHVzZVZhcmFyZ3MpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYmVzdFNvRmFyOwogICAgfQogICAgLy93aGVyZQogICAgICAgIGNsYXNzIExvb2t1cEZpbHRlciBpbXBsZW1lbnRzIEZpbHRlcjxTeW1ib2w+IHsKCiAgICAgICAgICAgIGJvb2xlYW4gYWJzdHJhY3RPazsKCiAgICAgICAgICAgIExvb2t1cEZpbHRlcihib29sZWFuIGFic3RyYWN0T2spIHsKICAgICAgICAgICAgICAgIHRoaXMuYWJzdHJhY3RPayA9IGFic3RyYWN0T2s7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHB1YmxpYyBib29sZWFuIGFjY2VwdHMoU3ltYm9sIHMpIHsKICAgICAgICAgICAgICAgIGxvbmcgZmxhZ3MgPSBzLmZsYWdzKCk7CiAgICAgICAgICAgICAgICByZXR1cm4gcy5raW5kID09IE1USCAmJgogICAgICAgICAgICAgICAgICAgICAgICAoZmxhZ3MgJiBTWU5USEVUSUMpID09IDAgJiYKICAgICAgICAgICAgICAgICAgICAgICAgKGFic3RyYWN0T2sgfHwKICAgICAgICAgICAgICAgICAgICAgICAgKGZsYWdzICYgREVGQVVMVCkgIT0gMCB8fAogICAgICAgICAgICAgICAgICAgICAgICAoZmxhZ3MgJiBBQlNUUkFDVCkgPT0gMCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgLyoqIEZpbmQgYmVzdCBxdWFsaWZpZWQgbWV0aG9kIG1hdGNoaW5nIGdpdmVuIG5hbWUsIHR5cGUgYW5kIHZhbHVlCiAgICAgKiAgYXJndW1lbnRzLgogICAgICogIEBwYXJhbSBlbnYgICAgICAgVGhlIGN1cnJlbnQgZW52aXJvbm1lbnQuCiAgICAgKiAgQHBhcmFtIHNpdGUgICAgICBUaGUgb3JpZ2luYWwgdHlwZSBmcm9tIHdoZXJlIHRoZSBzZWxlY3Rpb24KICAgICAqICAgICAgICAgICAgICAgICAgIHRha2VzIHBsYWNlLgogICAgICogIEBwYXJhbSBuYW1lICAgICAgVGhlIG1ldGhvZCdzIG5hbWUuCiAgICAgKiAgQHBhcmFtIGFyZ3R5cGVzICBUaGUgbWV0aG9kJ3MgdmFsdWUgYXJndW1lbnRzLgogICAgICogIEBwYXJhbSB0eXBlYXJndHlwZXMgVGhlIG1ldGhvZCdzIHR5cGUgYXJndW1lbnRzCiAgICAgKiAgQHBhcmFtIGFsbG93Qm94aW5nIEFsbG93IGJveGluZyBjb252ZXJzaW9ucyBvZiBhcmd1bWVudHMuCiAgICAgKiAgQHBhcmFtIHVzZVZhcmFyZ3MgQm94IHRyYWlsaW5nIGFyZ3VtZW50cyBpbnRvIGFuIGFycmF5IGZvciB2YXJhcmdzLgogICAgICovCiAgICBTeW1ib2wgZmluZE1ldGhvZChFbnY8QXR0ckNvbnRleHQ+IGVudiwKICAgICAgICAgICAgICAgICAgICAgIFR5cGUgc2l0ZSwKICAgICAgICAgICAgICAgICAgICAgIE5hbWUgbmFtZSwKICAgICAgICAgICAgICAgICAgICAgIExpc3Q8VHlwZT4gYXJndHlwZXMsCiAgICAgICAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IHR5cGVhcmd0eXBlcywKICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gYWxsb3dCb3hpbmcsCiAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIHVzZVZhcmFyZ3MpIHsKICAgICAgICBTeW1ib2wgYmVzdFNvRmFyID0gbWV0aG9kTm90Rm91bmQ7CiAgICAgICAgYmVzdFNvRmFyID0gZmluZE1ldGhvZChlbnYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgc2l0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgIGFyZ3R5cGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVhcmd0eXBlcywKICAgICAgICAgICAgICAgICAgICAgICAgICBzaXRlLnRzeW0udHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICBiZXN0U29GYXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgYWxsb3dCb3hpbmcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgdXNlVmFyYXJncyk7CiAgICAgICAgcmV0dXJuIGJlc3RTb0ZhcjsKICAgIH0KICAgIC8vIHdoZXJlCiAgICBwcml2YXRlIFN5bWJvbCBmaW5kTWV0aG9kKEVudjxBdHRyQ29udGV4dD4gZW52LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUeXBlIHNpdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5hbWUgbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTGlzdDxUeXBlPiBhcmd0eXBlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTGlzdDxUeXBlPiB0eXBlYXJndHlwZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFR5cGUgaW50eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTeW1ib2wgYmVzdFNvRmFyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGFsbG93Qm94aW5nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIHVzZVZhcmFyZ3MpIHsKICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVuY2hlY2tlZCIsInJhd3R5cGVzIn0pCiAgICAgICAgTGlzdDxUeXBlPltdIGl0eXBlcyA9IChMaXN0PFR5cGU+W10pbmV3IExpc3RbXSB7IExpc3QuPFR5cGU+bmlsKCksIExpc3QuPFR5cGU+bmlsKCkgfTsKCiAgICAgICAgSW50ZXJmYWNlTG9va3VwUGhhc2UgaXBoYXNlID0gSW50ZXJmYWNlTG9va3VwUGhhc2UuQUJTVFJBQ1RfT0s7CiAgICAgICAgZm9yIChUeXBlU3ltYm9sIHMgOiBzdXBlcmNsYXNzZXMoaW50eXBlKSkgewogICAgICAgICAgICBiZXN0U29GYXIgPSBmaW5kTWV0aG9kSW5TY29wZShlbnYsIHNpdGUsIG5hbWUsIGFyZ3R5cGVzLCB0eXBlYXJndHlwZXMsCiAgICAgICAgICAgICAgICAgICAgcy5tZW1iZXJzKCksIGJlc3RTb0ZhciwgYWxsb3dCb3hpbmcsIHVzZVZhcmFyZ3MsIHRydWUpOwogICAgICAgICAgICBpZiAobmFtZSA9PSBuYW1lcy5pbml0KSByZXR1cm4gYmVzdFNvRmFyOwogICAgICAgICAgICBpcGhhc2UgPSAoaXBoYXNlID09IG51bGwpID8gbnVsbCA6IGlwaGFzZS51cGRhdGUocywgdGhpcyk7CiAgICAgICAgICAgIGlmIChpcGhhc2UgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgZm9yIChUeXBlIGl0eXBlIDogdHlwZXMuaW50ZXJmYWNlcyhzLnR5cGUpKSB7CiAgICAgICAgICAgICAgICAgICAgaXR5cGVzW2lwaGFzZS5vcmRpbmFsKCldID0gdHlwZXMudW5pb24odHlwZXMuY2xvc3VyZShpdHlwZSksIGl0eXBlc1tpcGhhc2Uub3JkaW5hbCgpXSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIFN5bWJvbCBjb25jcmV0ZSA9IGJlc3RTb0Zhci5raW5kLmlzVmFsaWQoKSAmJgogICAgICAgICAgICAgICAgKGJlc3RTb0Zhci5mbGFncygpICYgQUJTVFJBQ1QpID09IDAgPwogICAgICAgICAgICAgICAgYmVzdFNvRmFyIDogbWV0aG9kTm90Rm91bmQ7CgogICAgICAgIGZvciAoSW50ZXJmYWNlTG9va3VwUGhhc2UgaXBoYXNlMiA6IEludGVyZmFjZUxvb2t1cFBoYXNlLnZhbHVlcygpKSB7CiAgICAgICAgICAgIC8va2VlcCBzZWFyY2hpbmcgZm9yIGFic3RyYWN0IG1ldGhvZHMKICAgICAgICAgICAgZm9yIChUeXBlIGl0eXBlIDogaXR5cGVzW2lwaGFzZTIub3JkaW5hbCgpXSkgewogICAgICAgICAgICAgICAgaWYgKCFpdHlwZS5pc0ludGVyZmFjZSgpKSBjb250aW51ZTsgLy9za2lwIGoubC5PYmplY3QgKGluY2x1ZGVkIGJ5IFR5cGVzLmNsb3N1cmUoKSkKICAgICAgICAgICAgICAgIGlmIChpcGhhc2UyID09IEludGVyZmFjZUxvb2t1cFBoYXNlLkRFRkFVTFRfT0sgJiYKICAgICAgICAgICAgICAgICAgICAgICAgKGl0eXBlLnRzeW0uZmxhZ3MoKSAmIERFRkFVTFQpID09IDApIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgYmVzdFNvRmFyID0gZmluZE1ldGhvZEluU2NvcGUoZW52LCBzaXRlLCBuYW1lLCBhcmd0eXBlcywgdHlwZWFyZ3R5cGVzLAogICAgICAgICAgICAgICAgICAgICAgICBpdHlwZS50c3ltLm1lbWJlcnMoKSwgYmVzdFNvRmFyLCBhbGxvd0JveGluZywgdXNlVmFyYXJncywgdHJ1ZSk7CiAgICAgICAgICAgICAgICBpZiAoY29uY3JldGUgIT0gYmVzdFNvRmFyICYmCiAgICAgICAgICAgICAgICAgICAgY29uY3JldGUua2luZC5pc1ZhbGlkKCkgJiYKICAgICAgICAgICAgICAgICAgICBiZXN0U29GYXIua2luZC5pc1ZhbGlkKCkgJiYKICAgICAgICAgICAgICAgICAgICAgICAgdHlwZXMuaXNTdWJTaWduYXR1cmUoY29uY3JldGUudHlwZSwgYmVzdFNvRmFyLnR5cGUpKSB7CiAgICAgICAgICAgICAgICAgICAgLy90aGlzIGlzIGFuIGhhY2sgLSBhcyBqYXZhYyBkb2VzIG5vdCBkbyBmdWxsIG1lbWJlcnNoaXAgY2hlY2tzCiAgICAgICAgICAgICAgICAgICAgLy9tb3N0IHNwZWNpZmljIGVuZHMgdXAgY29tcGFyaW5nIGFic3RyYWN0IG1ldGhvZHMgdGhhdCBtaWdodCBoYXZlCiAgICAgICAgICAgICAgICAgICAgLy9iZWVuIGltcGxlbWVudGVkIGJ5IHNvbWUgY29uY3JldGUgbWV0aG9kIGluIGEgc3ViY2xhc3MgYW5kLAogICAgICAgICAgICAgICAgICAgIC8vYmVjYXVzZSBvZiByYXcgb3ZlcnJpZGUsIGl0IGlzIHBvc3NpYmxlIGZvciBhbiBhYnN0cmFjdCBtZXRob2QKICAgICAgICAgICAgICAgICAgICAvL3RvIGJlIG1vcmUgc3BlY2lmaWMgdGhhbiB0aGUgY29uY3JldGUgbWV0aG9kIC0gc28gd2UgbmVlZAogICAgICAgICAgICAgICAgICAgIC8vdG8gZXhwbGljaXRseSBjYWxsIHRoYXQgb3V0IChzZWUgQ1IgNjE3ODM2NSkKICAgICAgICAgICAgICAgICAgICBiZXN0U29GYXIgPSBjb25jcmV0ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gYmVzdFNvRmFyOwogICAgfQoKICAgIGVudW0gSW50ZXJmYWNlTG9va3VwUGhhc2UgewogICAgICAgIEFCU1RSQUNUX09LKCkgewogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgSW50ZXJmYWNlTG9va3VwUGhhc2UgdXBkYXRlKFN5bWJvbCBzLCBSZXNvbHZlIHJzKSB7CiAgICAgICAgICAgICAgICAvL1dlIHNob3VsZCBub3QgbG9vayBmb3IgYWJzdHJhY3QgbWV0aG9kcyBpZiByZWNlaXZlciBpcyBhIGNvbmNyZXRlIGNsYXNzCiAgICAgICAgICAgICAgICAvLyhhcyBjb25jcmV0ZSBjbGFzc2VzIGFyZSBleHBlY3RlZCB0byBpbXBsZW1lbnQgYWxsIGFic3RyYWN0cyBjb21pbmcKICAgICAgICAgICAgICAgIC8vZnJvbSBzdXBlcmludGVyZmFjZXMpCiAgICAgICAgICAgICAgICBpZiAoKHMuZmxhZ3MoKSAmIChBQlNUUkFDVCB8IElOVEVSRkFDRSB8IEVOVU0pKSAhPSAwKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBERUZBVUxUX09LOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBERUZBVUxUX09LKCkgewogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgSW50ZXJmYWNlTG9va3VwUGhhc2UgdXBkYXRlKFN5bWJvbCBzLCBSZXNvbHZlIHJzKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgICAgfQogICAgICAgIH07CgogICAgICAgIGFic3RyYWN0IEludGVyZmFjZUxvb2t1cFBoYXNlIHVwZGF0ZShTeW1ib2wgcywgUmVzb2x2ZSBycyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm4gYW4gSXRlcmFibGUgb2JqZWN0IHRvIHNjYW4gdGhlIHN1cGVyY2xhc3NlcyBvZiBhIGdpdmVuIHR5cGUuCiAgICAgKiBJdCdzIGNydWNpYWwgdGhhdCB0aGUgc2NhbiBpcyBkb25lIGxhemlseSwgYXMgd2UgZG9uJ3Qgd2FudCB0byBhY2NpZGVudGFsbHkKICAgICAqIGFjY2VzcyBtb3JlIHN1cGVydHlwZXMgdGhhbiBzdHJpY3RseSBuZWVkZWQgKGFzIHRoaXMgY291bGQgdHJpZ2dlciBjb21wbGV0aW9uCiAgICAgKiBlcnJvcnMgaWYgc29tZSBvZiB0aGUgbm90LW5lZWRlZCBzdXBlcnR5cGVzIGFyZSBtaXNzaW5nL2lsbC1mb3JtZWQpLgogICAgICovCiAgICBJdGVyYWJsZTxUeXBlU3ltYm9sPiBzdXBlcmNsYXNzZXMoZmluYWwgVHlwZSBpbnR5cGUpIHsKICAgICAgICByZXR1cm4gKCkgLT4gbmV3IEl0ZXJhdG9yPFR5cGVTeW1ib2w+KCkgewoKICAgICAgICAgICAgTGlzdDxUeXBlU3ltYm9sPiBzZWVuID0gTGlzdC5uaWwoKTsKICAgICAgICAgICAgVHlwZVN5bWJvbCBjdXJyZW50U3ltID0gc3ltYm9sRm9yKGludHlwZSk7CiAgICAgICAgICAgIFR5cGVTeW1ib2wgcHJldlN5bSA9IG51bGw7CgogICAgICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNOZXh0KCkgewogICAgICAgICAgICAgICAgaWYgKGN1cnJlbnRTeW0gPT0gc3ltcy5ub1N5bWJvbCkgewogICAgICAgICAgICAgICAgICAgIGN1cnJlbnRTeW0gPSBzeW1ib2xGb3IodHlwZXMuc3VwZXJ0eXBlKHByZXZTeW0udHlwZSkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIGN1cnJlbnRTeW0gIT0gbnVsbDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHVibGljIFR5cGVTeW1ib2wgbmV4dCgpIHsKICAgICAgICAgICAgICAgIHByZXZTeW0gPSBjdXJyZW50U3ltOwogICAgICAgICAgICAgICAgY3VycmVudFN5bSA9IHN5bXMubm9TeW1ib2w7CiAgICAgICAgICAgICAgICBBc3NlcnQuY2hlY2socHJldlN5bSAhPSBudWxsIHx8IHByZXZTeW0gIT0gc3ltcy5ub1N5bWJvbCk7CiAgICAgICAgICAgICAgICByZXR1cm4gcHJldlN5bTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHVibGljIHZvaWQgcmVtb3ZlKCkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIFR5cGVTeW1ib2wgc3ltYm9sRm9yKFR5cGUgdCkgewogICAgICAgICAgICAgICAgaWYgKCF0Lmhhc1RhZyhDTEFTUykgJiYKICAgICAgICAgICAgICAgICAgICAgICAgIXQuaGFzVGFnKFRZUEVWQVIpKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB0ID0gdHlwZXMuc2tpcFR5cGVWYXJzKHQsIGZhbHNlKTsKICAgICAgICAgICAgICAgIGlmIChzZWVuLmNvbnRhaW5zKHQudHN5bSkpIHsKICAgICAgICAgICAgICAgICAgICAvL2RlZ2VuZXJhdGUgY2FzZSBpbiB3aGljaCB3ZSBoYXZlIGEgY2lyY3VsYXIKICAgICAgICAgICAgICAgICAgICAvL2NsYXNzIGhpZXJhcmNoeSAtIGJlY2F1c2Ugb2YgaWxsLWZvcm1lZCBjbGFzc2ZpbGVzCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBzZWVuID0gc2Vlbi5wcmVwZW5kKHQudHN5bSk7CiAgICAgICAgICAgICAgICByZXR1cm4gdC50c3ltOwogICAgICAgICAgICB9CiAgICAgICAgfTsKICAgIH0KCiAgICAvKiogRmluZCB1bnF1YWxpZmllZCBtZXRob2QgbWF0Y2hpbmcgZ2l2ZW4gbmFtZSwgdHlwZSBhbmQgdmFsdWUgYXJndW1lbnRzLgogICAgICogIEBwYXJhbSBlbnYgICAgICAgVGhlIGN1cnJlbnQgZW52aXJvbm1lbnQuCiAgICAgKiAgQHBhcmFtIG5hbWUgICAgICBUaGUgbWV0aG9kJ3MgbmFtZS4KICAgICAqICBAcGFyYW0gYXJndHlwZXMgIFRoZSBtZXRob2QncyB2YWx1ZSBhcmd1bWVudHMuCiAgICAgKiAgQHBhcmFtIHR5cGVhcmd0eXBlcyAgVGhlIG1ldGhvZCdzIHR5cGUgYXJndW1lbnRzLgogICAgICogIEBwYXJhbSBhbGxvd0JveGluZyBBbGxvdyBib3hpbmcgY29udmVyc2lvbnMgb2YgYXJndW1lbnRzLgogICAgICogIEBwYXJhbSB1c2VWYXJhcmdzIEJveCB0cmFpbGluZyBhcmd1bWVudHMgaW50byBhbiBhcnJheSBmb3IgdmFyYXJncy4KICAgICAqLwogICAgU3ltYm9sIGZpbmRGdW4oRW52PEF0dHJDb250ZXh0PiBlbnYsIE5hbWUgbmFtZSwKICAgICAgICAgICAgICAgICAgIExpc3Q8VHlwZT4gYXJndHlwZXMsIExpc3Q8VHlwZT4gdHlwZWFyZ3R5cGVzLAogICAgICAgICAgICAgICAgICAgYm9vbGVhbiBhbGxvd0JveGluZywgYm9vbGVhbiB1c2VWYXJhcmdzKSB7CiAgICAgICAgU3ltYm9sIGJlc3RTb0ZhciA9IG1ldGhvZE5vdEZvdW5kOwogICAgICAgIEVudjxBdHRyQ29udGV4dD4gZW52MSA9IGVudjsKICAgICAgICBib29sZWFuIHN0YXRpY09ubHkgPSBmYWxzZTsKICAgICAgICB3aGlsZSAoZW52MS5vdXRlciAhPSBudWxsKSB7CiAgICAgICAgICAgIGlmIChpc1N0YXRpYyhlbnYxKSkgc3RhdGljT25seSA9IHRydWU7CiAgICAgICAgICAgIEFzc2VydC5jaGVjayhlbnYxLmluZm8ucHJlZmVycmVkVHJlZUZvckRpYWdub3N0aWNzID09IG51bGwpOwogICAgICAgICAgICBlbnYxLmluZm8ucHJlZmVycmVkVHJlZUZvckRpYWdub3N0aWNzID0gZW52LnRyZWU7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBTeW1ib2wgc3ltID0gZmluZE1ldGhvZCgKICAgICAgICAgICAgICAgICAgICBlbnYxLCBlbnYxLmVuY2xDbGFzcy5zeW0udHlwZSwgbmFtZSwgYXJndHlwZXMsIHR5cGVhcmd0eXBlcywKICAgICAgICAgICAgICAgICAgICBhbGxvd0JveGluZywgdXNlVmFyYXJncyk7CiAgICAgICAgICAgICAgICBpZiAoc3ltLmV4aXN0cygpKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHN0YXRpY09ubHkgJiYKICAgICAgICAgICAgICAgICAgICAgICAgc3ltLmtpbmQgPT0gTVRIICYmCiAgICAgICAgICAgICAgICAgICAgICAgIHN5bS5vd25lci5raW5kID09IFRZUCAmJgogICAgICAgICAgICAgICAgICAgICAgICAoc3ltLmZsYWdzKCkgJiBTVEFUSUMpID09IDApIHJldHVybiBuZXcgU3RhdGljRXJyb3Ioc3ltKTsKICAgICAgICAgICAgICAgICAgICBlbHNlIHJldHVybiBzeW07CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGJlc3RTb0ZhciA9IGJlc3RPZihiZXN0U29GYXIsIHN5bSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgICAgICBlbnYxLmluZm8ucHJlZmVycmVkVHJlZUZvckRpYWdub3N0aWNzID0gbnVsbDsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoKGVudjEuZW5jbENsYXNzLnN5bS5mbGFncygpICYgU1RBVElDKSAhPSAwKSBzdGF0aWNPbmx5ID0gdHJ1ZTsKICAgICAgICAgICAgZW52MSA9IGVudjEub3V0ZXI7CiAgICAgICAgfQoKICAgICAgICBTeW1ib2wgc3ltID0gZmluZE1ldGhvZChlbnYsIHN5bXMucHJlZGVmQ2xhc3MudHlwZSwgbmFtZSwgYXJndHlwZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZWFyZ3R5cGVzLCBhbGxvd0JveGluZywgdXNlVmFyYXJncyk7CiAgICAgICAgaWYgKHN5bS5leGlzdHMoKSkKICAgICAgICAgICAgcmV0dXJuIHN5bTsKCiAgICAgICAgZm9yIChTeW1ib2wgY3VycmVudFN5bSA6IGVudi50b3BsZXZlbC5uYW1lZEltcG9ydFNjb3BlLmdldFN5bWJvbHNCeU5hbWUobmFtZSkpIHsKICAgICAgICAgICAgU3ltYm9sIG9yaWdpbiA9IGVudi50b3BsZXZlbC5uYW1lZEltcG9ydFNjb3BlLmdldE9yaWdpbihjdXJyZW50U3ltKS5vd25lcjsKICAgICAgICAgICAgaWYgKGN1cnJlbnRTeW0ua2luZCA9PSBNVEgpIHsKICAgICAgICAgICAgICAgIGlmIChjdXJyZW50U3ltLm93bmVyLnR5cGUgIT0gb3JpZ2luLnR5cGUpCiAgICAgICAgICAgICAgICAgICAgY3VycmVudFN5bSA9IGN1cnJlbnRTeW0uY2xvbmUob3JpZ2luKTsKICAgICAgICAgICAgICAgIGlmICghaXNBY2Nlc3NpYmxlKGVudiwgb3JpZ2luLnR5cGUsIGN1cnJlbnRTeW0pKQogICAgICAgICAgICAgICAgICAgIGN1cnJlbnRTeW0gPSBuZXcgQWNjZXNzRXJyb3IoZW52LCBvcmlnaW4udHlwZSwgY3VycmVudFN5bSk7CiAgICAgICAgICAgICAgICBiZXN0U29GYXIgPSBzZWxlY3RCZXN0KGVudiwgb3JpZ2luLnR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyZ3R5cGVzLCB0eXBlYXJndHlwZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRTeW0sIGJlc3RTb0ZhciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWxsb3dCb3hpbmcsIHVzZVZhcmFyZ3MpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmIChiZXN0U29GYXIuZXhpc3RzKCkpCiAgICAgICAgICAgIHJldHVybiBiZXN0U29GYXI7CgogICAgICAgIGZvciAoU3ltYm9sIGN1cnJlbnRTeW0gOiBlbnYudG9wbGV2ZWwuc3RhckltcG9ydFNjb3BlLmdldFN5bWJvbHNCeU5hbWUobmFtZSkpIHsKICAgICAgICAgICAgU3ltYm9sIG9yaWdpbiA9IGVudi50b3BsZXZlbC5zdGFySW1wb3J0U2NvcGUuZ2V0T3JpZ2luKGN1cnJlbnRTeW0pLm93bmVyOwogICAgICAgICAgICBpZiAoY3VycmVudFN5bS5raW5kID09IE1USCkgewogICAgICAgICAgICAgICAgaWYgKGN1cnJlbnRTeW0ub3duZXIudHlwZSAhPSBvcmlnaW4udHlwZSkKICAgICAgICAgICAgICAgICAgICBjdXJyZW50U3ltID0gY3VycmVudFN5bS5jbG9uZShvcmlnaW4pOwogICAgICAgICAgICAgICAgaWYgKCFpc0FjY2Vzc2libGUoZW52LCBvcmlnaW4udHlwZSwgY3VycmVudFN5bSkpCiAgICAgICAgICAgICAgICAgICAgY3VycmVudFN5bSA9IG5ldyBBY2Nlc3NFcnJvcihlbnYsIG9yaWdpbi50eXBlLCBjdXJyZW50U3ltKTsKICAgICAgICAgICAgICAgIGJlc3RTb0ZhciA9IHNlbGVjdEJlc3QoZW52LCBvcmlnaW4udHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJndHlwZXMsIHR5cGVhcmd0eXBlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudFN5bSwgYmVzdFNvRmFyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbGxvd0JveGluZywgdXNlVmFyYXJncyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJlc3RTb0ZhcjsKICAgIH0KCiAgICAvKiogTG9hZCB0b3BsZXZlbCBvciBtZW1iZXIgY2xhc3Mgd2l0aCBnaXZlbiBmdWxseSBxdWFsaWZpZWQgbmFtZSBhbmQKICAgICAqICB2ZXJpZnkgdGhhdCBpdCBpcyBhY2Nlc3NpYmxlLgogICAgICogIEBwYXJhbSBlbnYgICAgICAgVGhlIGN1cnJlbnQgZW52aXJvbm1lbnQuCiAgICAgKiAgQHBhcmFtIG5hbWUgICAgICBUaGUgZnVsbHkgcXVhbGlmaWVkIG5hbWUgb2YgdGhlIGNsYXNzIHRvIGJlIGxvYWRlZC4KICAgICAqLwogICAgU3ltYm9sIGxvYWRDbGFzcyhFbnY8QXR0ckNvbnRleHQ+IGVudiwgTmFtZSBuYW1lLCBSZWNvdmVyeUxvYWRDbGFzcyByZWNvdmVyeUxvYWRDbGFzcykgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIENsYXNzU3ltYm9sIGMgPSBmaW5kZXIubG9hZENsYXNzKGVudi50b3BsZXZlbC5tb2RsZSwgbmFtZSk7CiAgICAgICAgICAgIHJldHVybiBpc0FjY2Vzc2libGUoZW52LCBjKSA/IGMgOiBuZXcgQWNjZXNzRXJyb3IoZW52LCBudWxsLCBjKTsKICAgICAgICB9IGNhdGNoIChDbGFzc0ZpbmRlci5CYWRDbGFzc0ZpbGUgZXJyKSB7CiAgICAgICAgICAgIHRocm93IGVycjsKICAgICAgICB9IGNhdGNoIChDb21wbGV0aW9uRmFpbHVyZSBleCkgewogICAgICAgICAgICBTeW1ib2wgY2FuZGlkYXRlID0gcmVjb3ZlcnlMb2FkQ2xhc3MubG9hZENsYXNzKGVudiwgbmFtZSk7CgogICAgICAgICAgICBpZiAoY2FuZGlkYXRlICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIHJldHVybiBjYW5kaWRhdGU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiB0eXBlTm90Rm91bmQ7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBpbnRlcmZhY2UgUmVjb3ZlcnlMb2FkQ2xhc3MgewogICAgICAgIFN5bWJvbCBsb2FkQ2xhc3MoRW52PEF0dHJDb250ZXh0PiBlbnYsIE5hbWUgbmFtZSk7CiAgICB9CgogICAgcHJpdmF0ZSBmaW5hbCBSZWNvdmVyeUxvYWRDbGFzcyBub1JlY292ZXJ5ID0gKGVudiwgbmFtZSkgLT4gbnVsbDsKCiAgICBwcml2YXRlIGZpbmFsIFJlY292ZXJ5TG9hZENsYXNzIGRvUmVjb3ZlcnlMb2FkQ2xhc3MgPSBuZXcgUmVjb3ZlcnlMb2FkQ2xhc3MoKSB7CiAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBTeW1ib2wgbG9hZENsYXNzKEVudjxBdHRyQ29udGV4dD4gZW52LCBOYW1lIG5hbWUpIHsKICAgICAgICAgICAgTGlzdDxOYW1lPiBjYW5kaWRhdGVzID0gQ29udmVydC5jbGFzc0NhbmRpZGF0ZXMobmFtZSk7CiAgICAgICAgICAgIHJldHVybiBsb29rdXBJbnZpc2libGVTeW1ib2woZW52LCBuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG4gLT4gKCkgLT4gY3JlYXRlQ29tcG91bmRJdGVyYXRvcihjYW5kaWRhdGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjIC0+IHN5bXMuZ2V0Q2xhc3Nlc0Zvck5hbWUoYykKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLml0ZXJhdG9yKCkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChtcywgbikgLT4gewogICAgICAgICAgICAgICAgZm9yIChOYW1lIGNhbmRpZGF0ZSA6IGNhbmRpZGF0ZXMpIHsKICAgICAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmluZGVyLmxvYWRDbGFzcyhtcywgY2FuZGlkYXRlKTsKICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChDb21wbGV0aW9uRmFpbHVyZSBjZikgewogICAgICAgICAgICAgICAgICAgICAgICAvL2lnbm9yZQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICB9LCBzeW0gLT4gc3ltLmtpbmQgPT0gS2luZC5UWVAsIGZhbHNlLCB0eXBlTm90Rm91bmQpOwogICAgICAgIH0KICAgIH07CgogICAgcHJpdmF0ZSBmaW5hbCBSZWNvdmVyeUxvYWRDbGFzcyBuYW1lZEltcG9ydFNjb3BlUmVjb3ZlcnkgPSAoZW52LCBuYW1lKSAtPiB7CiAgICAgICAgU2NvcGUgaW1wb3J0U2NvcGUgPSBlbnYudG9wbGV2ZWwubmFtZWRJbXBvcnRTY29wZTsKICAgICAgICBTeW1ib2wgZXhpc3RpbmcgPSBpbXBvcnRTY29wZS5maW5kRmlyc3QoQ29udmVydC5zaG9ydE5hbWUobmFtZSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5bSAtPiBzeW0ua2luZCA9PSBUWVAgJiYgc3ltLmZsYXROYW1lKCkgPT0gbmFtZSk7CgogICAgICAgIGlmIChleGlzdGluZyAhPSBudWxsKSB7CiAgICAgICAgICAgIHJldHVybiBuZXcgSW52aXNpYmxlU3ltYm9sRXJyb3IoZW52LCB0cnVlLCBleGlzdGluZyk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfTsKCiAgICBwcml2YXRlIGZpbmFsIFJlY292ZXJ5TG9hZENsYXNzIHN0YXJJbXBvcnRTY29wZVJlY292ZXJ5ID0gKGVudiwgbmFtZSkgLT4gewogICAgICAgIFNjb3BlIGltcG9ydFNjb3BlID0gZW52LnRvcGxldmVsLnN0YXJJbXBvcnRTY29wZTsKICAgICAgICBTeW1ib2wgZXhpc3RpbmcgPSBpbXBvcnRTY29wZS5maW5kRmlyc3QoQ29udmVydC5zaG9ydE5hbWUobmFtZSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5bSAtPiBzeW0ua2luZCA9PSBUWVAgJiYgc3ltLmZsYXROYW1lKCkgPT0gbmFtZSk7CgogICAgICAgIGlmIChleGlzdGluZyAhPSBudWxsKSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBleGlzdGluZyA9IGZpbmRlci5sb2FkQ2xhc3MoZXhpc3RpbmcucGFja2dlKCkubW9kbGUsIG5hbWUpOwoKICAgICAgICAgICAgICAgIHJldHVybiBuZXcgSW52aXNpYmxlU3ltYm9sRXJyb3IoZW52LCB0cnVlLCBleGlzdGluZyk7CiAgICAgICAgICAgIH0gY2F0Y2ggKENvbXBsZXRpb25GYWlsdXJlIGNmKSB7CiAgICAgICAgICAgICAgICAvL2lnbm9yZQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gbnVsbDsKICAgIH07CgogICAgU3ltYm9sIGxvb2t1cFBhY2thZ2UoRW52PEF0dHJDb250ZXh0PiBlbnYsIE5hbWUgbmFtZSkgewogICAgICAgIFBhY2thZ2VTeW1ib2wgcGFjayA9IHN5bXMubG9va3VwUGFja2FnZShlbnYudG9wbGV2ZWwubW9kbGUsIG5hbWUpOwoKICAgICAgICBpZiAoYWxsb3dNb2R1bGVzICYmIGlzSW1wb3J0T25EZW1hbmQoZW52LCBuYW1lKSkgewogICAgICAgICAgICBwYWNrLmNvbXBsZXRlKCk7CiAgICAgICAgICAgIGlmICghcGFjay5leGlzdHMoKSkgewogICAgICAgICAgICAgICAgTmFtZSBuYW1lQW5kRG90ID0gbmFtZS5hcHBlbmQoJy4nLCBuYW1lcy5lbXB0eSk7CiAgICAgICAgICAgICAgICBib29sZWFuIHByZWZpeE9mS25vd24gPQogICAgICAgICAgICAgICAgICAgICAgICBlbnYudG9wbGV2ZWwubW9kbGUudmlzaWJsZVBhY2thZ2VzLnZhbHVlcygpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuc3RyZWFtKCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5hbnlNYXRjaChwIC0+IHAuZnVsbG5hbWUuc3RhcnRzV2l0aChuYW1lQW5kRG90KSk7CgogICAgICAgICAgICAgICAgcmV0dXJuIGxvb2t1cEludmlzaWJsZVN5bWJvbChlbnYsIG5hbWUsIHN5bXM6OmdldFBhY2thZ2VzRm9yTmFtZSwgc3ltczo6ZW50ZXJQYWNrYWdlLCBzeW0gLT4gewogICAgICAgICAgICAgICAgICAgIHN5bS5jb21wbGV0ZSgpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBzeW0uZXhpc3RzKCk7CiAgICAgICAgICAgICAgICB9LCBwcmVmaXhPZktub3duLCBwYWNrKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHBhY2s7CiAgICB9CgogICAgcHJpdmF0ZSBib29sZWFuIGlzSW1wb3J0T25EZW1hbmQoRW52PEF0dHJDb250ZXh0PiBlbnYsIE5hbWUgbmFtZSkgewogICAgICAgIGlmICghZW52LnRyZWUuaGFzVGFnKElNUE9SVCkpCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKCiAgICAgICAgSkNUcmVlIHF1YWxpZCA9ICgoSkNJbXBvcnQpIGVudi50cmVlKS5xdWFsaWQ7CgogICAgICAgIGlmICghcXVhbGlkLmhhc1RhZyhTRUxFQ1QpKQogICAgICAgICAgICByZXR1cm4gZmFsc2U7CgogICAgICAgIGlmIChUcmVlSW5mby5uYW1lKHF1YWxpZCkgIT0gbmFtZXMuYXN0ZXJpc2spCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKCiAgICAgICAgcmV0dXJuIFRyZWVJbmZvLmZ1bGxOYW1lKCgoSkNGaWVsZEFjY2VzcykgcXVhbGlkKS5zZWxlY3RlZCkgPT0gbmFtZTsKICAgIH0KCiAgICBwcml2YXRlIDxTIGV4dGVuZHMgU3ltYm9sPiBTeW1ib2wgbG9va3VwSW52aXNpYmxlU3ltYm9sKEVudjxBdHRyQ29udGV4dD4gZW52LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOYW1lIG5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZ1bmN0aW9uPE5hbWUsIEl0ZXJhYmxlPFM+PiBnZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJpRnVuY3Rpb248TW9kdWxlU3ltYm9sLCBOYW1lLCBTPiBsb2FkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQcmVkaWNhdGU8Uz4gdmFsaWRhdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gc3VwcHJlc3NFcnJvciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3ltYm9sIGRlZmF1bHRSZXN1bHQpIHsKICAgICAgICAvL2V2ZW4gaWYgYSBjbGFzcy9wYWNrYWdlIGNhbm5vdCBiZSBmb3VuZCBpbiB0aGUgY3VycmVudCBtb2R1bGUgYW5kIGFtb25nIHBhY2thZ2VzIGluIG1vZHVsZXMKICAgICAgICAvL2l0IGRlcGVuZHMgb24gdGhhdCBhcmUgZXhwb3J0ZWQgZm9yIGFueSBvciB0aGlzIG1vZHVsZSwgdGhlIGNsYXNzL3BhY2thZ2UgbWF5IGV4aXN0IGludGVybmFsbHkKICAgICAgICAvL2luIHNvbWUgb2YgdGhlc2UgbW9kdWxlcywgb3IgbWF5IGV4aXN0IGluIGEgbW9kdWxlIG9uIHdoaWNoIHRoaXMgbW9kdWxlIGRvZXMgbm90IGRlcGVuZC4KICAgICAgICAvL1Byb3ZpZGUgYmV0dGVyIGRpYWdub3N0aWMgaW4gc3VjaCBjYXNlcyBieSBsb29raW5nIGZvciB0aGUgY2xhc3MgaW4gYW55IG1vZHVsZToKICAgICAgICBJdGVyYWJsZTw/IGV4dGVuZHMgUz4gY2FuZGlkYXRlcyA9IGdldC5hcHBseShuYW1lKTsKCiAgICAgICAgZm9yIChTIHN5bSA6IGNhbmRpZGF0ZXMpIHsKICAgICAgICAgICAgaWYgKHZhbGlkYXRlLnRlc3Qoc3ltKSkKICAgICAgICAgICAgICAgIHJldHVybiBjcmVhdGVJbnZpc2libGVTeW1ib2xFcnJvcihlbnYsIHN1cHByZXNzRXJyb3IsIHN5bSk7CiAgICAgICAgfQoKICAgICAgICBTZXQ8TW9kdWxlU3ltYm9sPiByZWNvdmVyYWJsZU1vZHVsZXMgPSBuZXcgSGFzaFNldDw+KHN5bXMuZ2V0QWxsTW9kdWxlcygpKTsKCiAgICAgICAgcmVjb3ZlcmFibGVNb2R1bGVzLnJlbW92ZShlbnYudG9wbGV2ZWwubW9kbGUpOwoKICAgICAgICBmb3IgKE1vZHVsZVN5bWJvbCBtcyA6IHJlY292ZXJhYmxlTW9kdWxlcykgewogICAgICAgICAgICAvL2F2b2lkIG92ZXJseSBlYWdlciBjb21wbGV0aW5nIGNsYXNzZXMgZnJvbSBzb3VyY2UtYmFzZWQgbW9kdWxlcywgYXMgdGhvc2UKICAgICAgICAgICAgLy9tYXkgbm90IGJlIGNvbXBsZXRhYmxlIHdpdGggdGhlIGN1cnJlbnQgY29tcGlsZXIgc2V0dGluZ3M6CiAgICAgICAgICAgIGlmIChtcy5zb3VyY2VMb2NhdGlvbiA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICBpZiAobXMuY2xhc3NMb2NhdGlvbiA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgbXMgPSBtb2R1bGVGaW5kZXIuZmluZE1vZHVsZShtcyk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKG1zLmtpbmQgIT0gRVJSKSB7CiAgICAgICAgICAgICAgICAgICAgUyBzeW0gPSBsb2FkLmFwcGx5KG1zLCBuYW1lKTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKHN5bSAhPSBudWxsICYmIHZhbGlkYXRlLnRlc3Qoc3ltKSkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gY3JlYXRlSW52aXNpYmxlU3ltYm9sRXJyb3IoZW52LCBzdXBwcmVzc0Vycm9yLCBzeW0pOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGRlZmF1bHRSZXN1bHQ7CiAgICB9CgogICAgcHJpdmF0ZSBTeW1ib2wgY3JlYXRlSW52aXNpYmxlU3ltYm9sRXJyb3IoRW52PEF0dHJDb250ZXh0PiBlbnYsIGJvb2xlYW4gc3VwcHJlc3NFcnJvciwgU3ltYm9sIHN5bSkgewogICAgICAgIGlmIChzeW1ib2xQYWNrYWdlVmlzaWJsZShlbnYsIHN5bSkpIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyBBY2Nlc3NFcnJvcihlbnYsIG51bGwsIHN5bSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyBJbnZpc2libGVTeW1ib2xFcnJvcihlbnYsIHN1cHByZXNzRXJyb3IsIHN5bSk7CiAgICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgYm9vbGVhbiBzeW1ib2xQYWNrYWdlVmlzaWJsZShFbnY8QXR0ckNvbnRleHQ+IGVudiwgU3ltYm9sIHN5bSkgewogICAgICAgIE1vZHVsZVN5bWJvbCBlbnZNb2QgPSBlbnYudG9wbGV2ZWwubW9kbGU7CiAgICAgICAgUGFja2FnZVN5bWJvbCBzeW1QYWNrID0gc3ltLnBhY2tnZSgpOwogICAgICAgIHJldHVybiBlbnZNb2QgPT0gc3ltUGFjay5tb2RsZSB8fAogICAgICAgICAgICAgICBlbnZNb2QudmlzaWJsZVBhY2thZ2VzLmNvbnRhaW5zS2V5KHN5bVBhY2suZnVsbG5hbWUpOwogICAgfQoKICAgIC8qKgogICAgICogRmluZCBhIHR5cGUgZGVjbGFyZWQgaW4gYSBzY29wZSAobm90IGluaGVyaXRlZCkuICBSZXR1cm4gbnVsbAogICAgICogaWYgbm9uZSBpcyBmb3VuZC4KICAgICAqICBAcGFyYW0gZW52ICAgICAgIFRoZSBjdXJyZW50IGVudmlyb25tZW50LgogICAgICogIEBwYXJhbSBzaXRlICAgICAgVGhlIG9yaWdpbmFsIHR5cGUgZnJvbSB3aGVyZSB0aGUgc2VsZWN0aW9uIHRha2VzCiAgICAgKiAgICAgICAgICAgICAgICAgICBwbGFjZS4KICAgICAqICBAcGFyYW0gbmFtZSAgICAgIFRoZSB0eXBlJ3MgbmFtZS4KICAgICAqICBAcGFyYW0gYyAgICAgICAgIFRoZSBjbGFzcyB0byBzZWFyY2ggZm9yIHRoZSBtZW1iZXIgdHlwZS4gVGhpcyBpcwogICAgICogICAgICAgICAgICAgICAgICAgYWx3YXlzIGEgc3VwZXJjbGFzcyBvciBpbXBsZW1lbnRlZCBpbnRlcmZhY2Ugb2YKICAgICAqICAgICAgICAgICAgICAgICAgIHNpdGUncyBjbGFzcy4KICAgICAqLwogICAgU3ltYm9sIGZpbmRJbW1lZGlhdGVNZW1iZXJUeXBlKEVudjxBdHRyQ29udGV4dD4gZW52LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFR5cGUgc2l0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOYW1lIG5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVHlwZVN5bWJvbCBjKSB7CiAgICAgICAgZm9yIChTeW1ib2wgc3ltIDogYy5tZW1iZXJzKCkuZ2V0U3ltYm9sc0J5TmFtZShuYW1lKSkgewogICAgICAgICAgICBpZiAoc3ltLmtpbmQgPT0gVFlQKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gaXNBY2Nlc3NpYmxlKGVudiwgc2l0ZSwgc3ltKQogICAgICAgICAgICAgICAgICAgID8gc3ltCiAgICAgICAgICAgICAgICAgICAgOiBuZXcgQWNjZXNzRXJyb3IoZW52LCBzaXRlLCBzeW0pOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiB0eXBlTm90Rm91bmQ7CiAgICB9CgogICAgLyoqIEZpbmQgYSBtZW1iZXIgdHlwZSBpbmhlcml0ZWQgZnJvbSBhIHN1cGVyY2xhc3Mgb3IgaW50ZXJmYWNlLgogICAgICogIEBwYXJhbSBlbnYgICAgICAgVGhlIGN1cnJlbnQgZW52aXJvbm1lbnQuCiAgICAgKiAgQHBhcmFtIHNpdGUgICAgICBUaGUgb3JpZ2luYWwgdHlwZSBmcm9tIHdoZXJlIHRoZSBzZWxlY3Rpb24gdGFrZXMKICAgICAqICAgICAgICAgICAgICAgICAgIHBsYWNlLgogICAgICogIEBwYXJhbSBuYW1lICAgICAgVGhlIHR5cGUncyBuYW1lLgogICAgICogIEBwYXJhbSBjICAgICAgICAgVGhlIGNsYXNzIHRvIHNlYXJjaCBmb3IgdGhlIG1lbWJlciB0eXBlLiBUaGlzIGlzCiAgICAgKiAgICAgICAgICAgICAgICAgICBhbHdheXMgYSBzdXBlcmNsYXNzIG9yIGltcGxlbWVudGVkIGludGVyZmFjZSBvZgogICAgICogICAgICAgICAgICAgICAgICAgc2l0ZSdzIGNsYXNzLgogICAgICovCiAgICBTeW1ib2wgZmluZEluaGVyaXRlZE1lbWJlclR5cGUoRW52PEF0dHJDb250ZXh0PiBlbnYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVHlwZSBzaXRlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5hbWUgbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUeXBlU3ltYm9sIGMpIHsKICAgICAgICBTeW1ib2wgYmVzdFNvRmFyID0gdHlwZU5vdEZvdW5kOwogICAgICAgIFN5bWJvbCBzeW07CiAgICAgICAgVHlwZSBzdCA9IHR5cGVzLnN1cGVydHlwZShjLnR5cGUpOwogICAgICAgIGlmIChzdCAhPSBudWxsICYmIHN0Lmhhc1RhZyhDTEFTUykpIHsKICAgICAgICAgICAgc3ltID0gZmluZE1lbWJlclR5cGUoZW52LCBzaXRlLCBuYW1lLCBzdC50c3ltKTsKICAgICAgICAgICAgYmVzdFNvRmFyID0gYmVzdE9mKGJlc3RTb0Zhciwgc3ltKTsKICAgICAgICB9CiAgICAgICAgZm9yIChMaXN0PFR5cGU+IGwgPSB0eXBlcy5pbnRlcmZhY2VzKGMudHlwZSk7CiAgICAgICAgICAgICBiZXN0U29GYXIua2luZCAhPSBBTUJJR1VPVVMgJiYgbC5ub25FbXB0eSgpOwogICAgICAgICAgICAgbCA9IGwudGFpbCkgewogICAgICAgICAgICBzeW0gPSBmaW5kTWVtYmVyVHlwZShlbnYsIHNpdGUsIG5hbWUsIGwuaGVhZC50c3ltKTsKICAgICAgICAgICAgaWYgKCFiZXN0U29GYXIua2luZC5pc1Jlc29sdXRpb25FcnJvcigpICYmCiAgICAgICAgICAgICAgICAhc3ltLmtpbmQuaXNSZXNvbHV0aW9uRXJyb3IoKSAmJgogICAgICAgICAgICAgICAgc3ltLm93bmVyICE9IGJlc3RTb0Zhci5vd25lcikKICAgICAgICAgICAgICAgIGJlc3RTb0ZhciA9IG5ldyBBbWJpZ3VpdHlFcnJvcihiZXN0U29GYXIsIHN5bSk7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIGJlc3RTb0ZhciA9IGJlc3RPZihiZXN0U29GYXIsIHN5bSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBiZXN0U29GYXI7CiAgICB9CgogICAgLyoqIEZpbmQgcXVhbGlmaWVkIG1lbWJlciB0eXBlLgogICAgICogIEBwYXJhbSBlbnYgICAgICAgVGhlIGN1cnJlbnQgZW52aXJvbm1lbnQuCiAgICAgKiAgQHBhcmFtIHNpdGUgICAgICBUaGUgb3JpZ2luYWwgdHlwZSBmcm9tIHdoZXJlIHRoZSBzZWxlY3Rpb24gdGFrZXMKICAgICAqICAgICAgICAgICAgICAgICAgIHBsYWNlLgogICAgICogIEBwYXJhbSBuYW1lICAgICAgVGhlIHR5cGUncyBuYW1lLgogICAgICogIEBwYXJhbSBjICAgICAgICAgVGhlIGNsYXNzIHRvIHNlYXJjaCBmb3IgdGhlIG1lbWJlciB0eXBlLiBUaGlzIGlzCiAgICAgKiAgICAgICAgICAgICAgICAgICBhbHdheXMgYSBzdXBlcmNsYXNzIG9yIGltcGxlbWVudGVkIGludGVyZmFjZSBvZgogICAgICogICAgICAgICAgICAgICAgICAgc2l0ZSdzIGNsYXNzLgogICAgICovCiAgICBTeW1ib2wgZmluZE1lbWJlclR5cGUoRW52PEF0dHJDb250ZXh0PiBlbnYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgVHlwZSBzaXRlLAogICAgICAgICAgICAgICAgICAgICAgICAgIE5hbWUgbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICBUeXBlU3ltYm9sIGMpIHsKICAgICAgICBTeW1ib2wgc3ltID0gZmluZEltbWVkaWF0ZU1lbWJlclR5cGUoZW52LCBzaXRlLCBuYW1lLCBjKTsKCiAgICAgICAgaWYgKHN5bSAhPSB0eXBlTm90Rm91bmQpCiAgICAgICAgICAgIHJldHVybiBzeW07CgogICAgICAgIHJldHVybiBmaW5kSW5oZXJpdGVkTWVtYmVyVHlwZShlbnYsIHNpdGUsIG5hbWUsIGMpOwoKICAgIH0KCiAgICAvKiogRmluZCBhIGdsb2JhbCB0eXBlIGluIGdpdmVuIHNjb3BlIGFuZCBsb2FkIGNvcnJlc3BvbmRpbmcgY2xhc3MuCiAgICAgKiAgQHBhcmFtIGVudiAgICAgICBUaGUgY3VycmVudCBlbnZpcm9ubWVudC4KICAgICAqICBAcGFyYW0gc2NvcGUgICAgIFRoZSBzY29wZSBpbiB3aGljaCB0byBsb29rIGZvciB0aGUgdHlwZS4KICAgICAqICBAcGFyYW0gbmFtZSAgICAgIFRoZSB0eXBlJ3MgbmFtZS4KICAgICAqLwogICAgU3ltYm9sIGZpbmRHbG9iYWxUeXBlKEVudjxBdHRyQ29udGV4dD4gZW52LCBTY29wZSBzY29wZSwgTmFtZSBuYW1lLCBSZWNvdmVyeUxvYWRDbGFzcyByZWNvdmVyeUxvYWRDbGFzcykgewogICAgICAgIFN5bWJvbCBiZXN0U29GYXIgPSB0eXBlTm90Rm91bmQ7CiAgICAgICAgZm9yIChTeW1ib2wgcyA6IHNjb3BlLmdldFN5bWJvbHNCeU5hbWUobmFtZSkpIHsKICAgICAgICAgICAgU3ltYm9sIHN5bSA9IGxvYWRDbGFzcyhlbnYsIHMuZmxhdE5hbWUoKSwgcmVjb3ZlcnlMb2FkQ2xhc3MpOwogICAgICAgICAgICBpZiAoYmVzdFNvRmFyLmtpbmQgPT0gVFlQICYmIHN5bS5raW5kID09IFRZUCAmJgogICAgICAgICAgICAgICAgYmVzdFNvRmFyICE9IHN5bSkKICAgICAgICAgICAgICAgIHJldHVybiBuZXcgQW1iaWd1aXR5RXJyb3IoYmVzdFNvRmFyLCBzeW0pOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBiZXN0U29GYXIgPSBiZXN0T2YoYmVzdFNvRmFyLCBzeW0pOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYmVzdFNvRmFyOwogICAgfQoKICAgIFN5bWJvbCBmaW5kVHlwZVZhcihFbnY8QXR0ckNvbnRleHQ+IGVudiwgTmFtZSBuYW1lLCBib29sZWFuIHN0YXRpY09ubHkpIHsKICAgICAgICBmb3IgKFN5bWJvbCBzeW0gOiBlbnYuaW5mby5zY29wZS5nZXRTeW1ib2xzQnlOYW1lKG5hbWUpKSB7CiAgICAgICAgICAgIGlmIChzeW0ua2luZCA9PSBUWVApIHsKICAgICAgICAgICAgICAgIGlmIChzdGF0aWNPbmx5ICYmCiAgICAgICAgICAgICAgICAgICAgc3ltLnR5cGUuaGFzVGFnKFRZUEVWQVIpICYmCiAgICAgICAgICAgICAgICAgICAgc3ltLm93bmVyLmtpbmQgPT0gVFlQKQogICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgU3RhdGljRXJyb3Ioc3ltKTsKICAgICAgICAgICAgICAgIHJldHVybiBzeW07CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHR5cGVOb3RGb3VuZDsKICAgIH0KCiAgICAvKiogRmluZCBhbiB1bnF1YWxpZmllZCB0eXBlIHN5bWJvbC4KICAgICAqICBAcGFyYW0gZW52ICAgICAgIFRoZSBjdXJyZW50IGVudmlyb25tZW50LgogICAgICogIEBwYXJhbSBuYW1lICAgICAgVGhlIHR5cGUncyBuYW1lLgogICAgICovCiAgICBTeW1ib2wgZmluZFR5cGUoRW52PEF0dHJDb250ZXh0PiBlbnYsIE5hbWUgbmFtZSkgewogICAgICAgIGlmIChuYW1lID09IG5hbWVzLmVtcHR5KQogICAgICAgICAgICByZXR1cm4gdHlwZU5vdEZvdW5kOyAvLyBkbyBub3QgYWxsb3cgaW5hZHZlcnRlbnQgImxvb2t1cCIgb2YgYW5vbnltb3VzIHR5cGVzCiAgICAgICAgU3ltYm9sIGJlc3RTb0ZhciA9IHR5cGVOb3RGb3VuZDsKICAgICAgICBTeW1ib2wgc3ltOwogICAgICAgIGJvb2xlYW4gc3RhdGljT25seSA9IGZhbHNlOwogICAgICAgIGZvciAoRW52PEF0dHJDb250ZXh0PiBlbnYxID0gZW52OyBlbnYxLm91dGVyICE9IG51bGw7IGVudjEgPSBlbnYxLm91dGVyKSB7CiAgICAgICAgICAgIGlmIChpc1N0YXRpYyhlbnYxKSkgc3RhdGljT25seSA9IHRydWU7CiAgICAgICAgICAgIC8vIEZpcnN0LCBsb29rIGZvciBhIHR5cGUgdmFyaWFibGUgYW5kIHRoZSBmaXJzdCBtZW1iZXIgdHlwZQogICAgICAgICAgICBmaW5hbCBTeW1ib2wgdHl2YXIgPSBmaW5kVHlwZVZhcihlbnYxLCBuYW1lLCBzdGF0aWNPbmx5KTsKICAgICAgICAgICAgc3ltID0gZmluZEltbWVkaWF0ZU1lbWJlclR5cGUoZW52MSwgZW52MS5lbmNsQ2xhc3Muc3ltLnR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUsIGVudjEuZW5jbENsYXNzLnN5bSk7CgogICAgICAgICAgICAvLyBSZXR1cm4gdGhlIHR5cGUgdmFyaWFibGUgaWYgd2UgaGF2ZSBpdCwgYW5kIGhhdmUgbm8KICAgICAgICAgICAgLy8gaW1tZWRpYXRlIG1lbWJlciwgT1IgdGhlIHR5cGUgdmFyaWFibGUgaXMgZm9yIGEgbWV0aG9kLgogICAgICAgICAgICBpZiAodHl2YXIgIT0gdHlwZU5vdEZvdW5kKSB7CiAgICAgICAgICAgICAgICBpZiAoZW52LmJhc2VDbGF1c2UgfHwgc3ltID09IHR5cGVOb3RGb3VuZCB8fAogICAgICAgICAgICAgICAgICAgICh0eXZhci5raW5kID09IFRZUCAmJiB0eXZhci5leGlzdHMoKSAmJgogICAgICAgICAgICAgICAgICAgICB0eXZhci5vd25lci5raW5kID09IE1USCkpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHl2YXI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIElmIHRoZSBlbnZpcm9ubWVudCBpcyBhIGNsYXNzIGRlZiwgZmluaXNoIHVwLAogICAgICAgICAgICAvLyBvdGhlcndpc2UsIGRvIHRoZSBlbnRpcmUgZmluZE1lbWJlclR5cGUKICAgICAgICAgICAgaWYgKHN5bSA9PSB0eXBlTm90Rm91bmQpCiAgICAgICAgICAgICAgICBzeW0gPSBmaW5kSW5oZXJpdGVkTWVtYmVyVHlwZShlbnYxLCBlbnYxLmVuY2xDbGFzcy5zeW0udHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUsIGVudjEuZW5jbENsYXNzLnN5bSk7CgogICAgICAgICAgICBpZiAoc3RhdGljT25seSAmJiBzeW0ua2luZCA9PSBUWVAgJiYKICAgICAgICAgICAgICAgIHN5bS50eXBlLmhhc1RhZyhDTEFTUykgJiYKICAgICAgICAgICAgICAgIHN5bS50eXBlLmdldEVuY2xvc2luZ1R5cGUoKS5oYXNUYWcoQ0xBU1MpICYmCiAgICAgICAgICAgICAgICBlbnYxLmVuY2xDbGFzcy5zeW0udHlwZS5pc1BhcmFtZXRlcml6ZWQoKSAmJgogICAgICAgICAgICAgICAgc3ltLnR5cGUuZ2V0RW5jbG9zaW5nVHlwZSgpLmlzUGFyYW1ldGVyaXplZCgpKQogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBTdGF0aWNFcnJvcihzeW0pOwogICAgICAgICAgICBlbHNlIGlmIChzeW0uZXhpc3RzKCkpIHJldHVybiBzeW07CiAgICAgICAgICAgIGVsc2UgYmVzdFNvRmFyID0gYmVzdE9mKGJlc3RTb0Zhciwgc3ltKTsKCiAgICAgICAgICAgIEpDQ2xhc3NEZWNsIGVuY2wgPSBlbnYxLmJhc2VDbGF1c2UgPyAoSkNDbGFzc0RlY2wpZW52MS50cmVlIDogZW52MS5lbmNsQ2xhc3M7CiAgICAgICAgICAgIGlmICgoZW5jbC5zeW0uZmxhZ3MoKSAmIFNUQVRJQykgIT0gMCkKICAgICAgICAgICAgICAgIHN0YXRpY09ubHkgPSB0cnVlOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFlbnYudHJlZS5oYXNUYWcoSU1QT1JUKSkgewogICAgICAgICAgICBzeW0gPSBmaW5kR2xvYmFsVHlwZShlbnYsIGVudi50b3BsZXZlbC5uYW1lZEltcG9ydFNjb3BlLCBuYW1lLCBuYW1lZEltcG9ydFNjb3BlUmVjb3ZlcnkpOwogICAgICAgICAgICBpZiAoc3ltLmV4aXN0cygpKSByZXR1cm4gc3ltOwogICAgICAgICAgICBlbHNlIGJlc3RTb0ZhciA9IGJlc3RPZihiZXN0U29GYXIsIHN5bSk7CgogICAgICAgICAgICBzeW0gPSBmaW5kR2xvYmFsVHlwZShlbnYsIGVudi50b3BsZXZlbC5wYWNrZ2UubWVtYmVycygpLCBuYW1lLCBub1JlY292ZXJ5KTsKICAgICAgICAgICAgaWYgKHN5bS5leGlzdHMoKSkgcmV0dXJuIHN5bTsKICAgICAgICAgICAgZWxzZSBiZXN0U29GYXIgPSBiZXN0T2YoYmVzdFNvRmFyLCBzeW0pOwoKICAgICAgICAgICAgc3ltID0gZmluZEdsb2JhbFR5cGUoZW52LCBlbnYudG9wbGV2ZWwuc3RhckltcG9ydFNjb3BlLCBuYW1lLCBzdGFySW1wb3J0U2NvcGVSZWNvdmVyeSk7CiAgICAgICAgICAgIGlmIChzeW0uZXhpc3RzKCkpIHJldHVybiBzeW07CiAgICAgICAgICAgIGVsc2UgYmVzdFNvRmFyID0gYmVzdE9mKGJlc3RTb0Zhciwgc3ltKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBiZXN0U29GYXI7CiAgICB9CgogICAgLyoqIEZpbmQgYW4gdW5xdWFsaWZpZWQgaWRlbnRpZmllciB3aGljaCBtYXRjaGVzIGEgc3BlY2lmaWVkIGtpbmQgc2V0LgogICAgICogIEBwYXJhbSBlbnYgICAgICAgVGhlIGN1cnJlbnQgZW52aXJvbm1lbnQuCiAgICAgKiAgQHBhcmFtIG5hbWUgICAgICBUaGUgaWRlbnRpZmllcidzIG5hbWUuCiAgICAgKiAgQHBhcmFtIGtpbmQgICAgICBJbmRpY2F0ZXMgdGhlIHBvc3NpYmxlIHN5bWJvbCBraW5kcwogICAgICogICAgICAgICAgICAgICAgICAgKGEgc3Vic2V0IG9mIFZBTCwgVFlQLCBQQ0spLgogICAgICovCiAgICBTeW1ib2wgZmluZElkZW50KEVudjxBdHRyQ29udGV4dD4gZW52LCBOYW1lIG5hbWUsIEtpbmRTZWxlY3RvciBraW5kKSB7CiAgICAgICAgU3ltYm9sIGJlc3RTb0ZhciA9IHR5cGVOb3RGb3VuZDsKICAgICAgICBTeW1ib2wgc3ltOwoKICAgICAgICBpZiAoa2luZC5jb250YWlucyhLaW5kU2VsZWN0b3IuVkFMKSkgewogICAgICAgICAgICBzeW0gPSBmaW5kVmFyKGVudiwgbmFtZSk7CiAgICAgICAgICAgIGlmIChzeW0uZXhpc3RzKCkpIHJldHVybiBzeW07CiAgICAgICAgICAgIGVsc2UgYmVzdFNvRmFyID0gYmVzdE9mKGJlc3RTb0Zhciwgc3ltKTsKICAgICAgICB9CgogICAgICAgIGlmIChraW5kLmNvbnRhaW5zKEtpbmRTZWxlY3Rvci5UWVApKSB7CiAgICAgICAgICAgIHN5bSA9IGZpbmRUeXBlKGVudiwgbmFtZSk7CgogICAgICAgICAgICBpZiAoc3ltLmV4aXN0cygpKSByZXR1cm4gc3ltOwogICAgICAgICAgICBlbHNlIGJlc3RTb0ZhciA9IGJlc3RPZihiZXN0U29GYXIsIHN5bSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoa2luZC5jb250YWlucyhLaW5kU2VsZWN0b3IuUENLKSkKICAgICAgICAgICAgcmV0dXJuIGxvb2t1cFBhY2thZ2UoZW52LCBuYW1lKTsKICAgICAgICBlbHNlIHJldHVybiBiZXN0U29GYXI7CiAgICB9CgogICAgLyoqIEZpbmQgYW4gaWRlbnRpZmllciBpbiBhIHBhY2thZ2Ugd2hpY2ggbWF0Y2hlcyBhIHNwZWNpZmllZCBraW5kIHNldC4KICAgICAqICBAcGFyYW0gZW52ICAgICAgIFRoZSBjdXJyZW50IGVudmlyb25tZW50LgogICAgICogIEBwYXJhbSBuYW1lICAgICAgVGhlIGlkZW50aWZpZXIncyBuYW1lLgogICAgICogIEBwYXJhbSBraW5kICAgICAgSW5kaWNhdGVzIHRoZSBwb3NzaWJsZSBzeW1ib2wga2luZHMKICAgICAqICAgICAgICAgICAgICAgICAgIChhIG5vbmVtcHR5IHN1YnNldCBvZiBUWVAsIFBDSykuCiAgICAgKi8KICAgIFN5bWJvbCBmaW5kSWRlbnRJblBhY2thZ2UoRW52PEF0dHJDb250ZXh0PiBlbnYsIFR5cGVTeW1ib2wgcGNrLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOYW1lIG5hbWUsIEtpbmRTZWxlY3RvciBraW5kKSB7CiAgICAgICAgTmFtZSBmdWxsbmFtZSA9IFR5cGVTeW1ib2wuZm9ybUZ1bGxOYW1lKG5hbWUsIHBjayk7CiAgICAgICAgU3ltYm9sIGJlc3RTb0ZhciA9IHR5cGVOb3RGb3VuZDsKICAgICAgICBpZiAoa2luZC5jb250YWlucyhLaW5kU2VsZWN0b3IuVFlQKSkgewogICAgICAgICAgICBSZWNvdmVyeUxvYWRDbGFzcyByZWNvdmVyeUxvYWRDbGFzcyA9CiAgICAgICAgICAgICAgICAgICAgYWxsb3dNb2R1bGVzICYmICFraW5kLmNvbnRhaW5zKEtpbmRTZWxlY3Rvci5QQ0spICYmCiAgICAgICAgICAgICAgICAgICAgIXBjay5leGlzdHMoKSAmJiAhZW52LmluZm8uaXNTcGVjdWxhdGl2ZSA/CiAgICAgICAgICAgICAgICAgICAgICAgIGRvUmVjb3ZlcnlMb2FkQ2xhc3MgOiBub1JlY292ZXJ5OwogICAgICAgICAgICBTeW1ib2wgc3ltID0gbG9hZENsYXNzKGVudiwgZnVsbG5hbWUsIHJlY292ZXJ5TG9hZENsYXNzKTsKICAgICAgICAgICAgaWYgKHN5bS5leGlzdHMoKSkgewogICAgICAgICAgICAgICAgLy8gZG9uJ3QgYWxsb3cgcHJvZ3JhbXMgdG8gdXNlIGZsYXRuYW1lcwogICAgICAgICAgICAgICAgaWYgKG5hbWUgPT0gc3ltLm5hbWUpIHJldHVybiBzeW07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBiZXN0U29GYXIgPSBiZXN0T2YoYmVzdFNvRmFyLCBzeW0pOwogICAgICAgIH0KICAgICAgICBpZiAoa2luZC5jb250YWlucyhLaW5kU2VsZWN0b3IuUENLKSkgewogICAgICAgICAgICByZXR1cm4gbG9va3VwUGFja2FnZShlbnYsIGZ1bGxuYW1lKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJlc3RTb0ZhcjsKICAgIH0KCiAgICAvKiogRmluZCBhbiBpZGVudGlmaWVyIGFtb25nIHRoZSBtZW1iZXJzIG9mIGEgZ2l2ZW4gdHlwZSBgc2l0ZScuCiAgICAgKiAgQHBhcmFtIGVudiAgICAgICBUaGUgY3VycmVudCBlbnZpcm9ubWVudC4KICAgICAqICBAcGFyYW0gc2l0ZSAgICAgIFRoZSB0eXBlIGNvbnRhaW5pbmcgdGhlIHN5bWJvbCB0byBiZSBmb3VuZC4KICAgICAqICBAcGFyYW0gbmFtZSAgICAgIFRoZSBpZGVudGlmaWVyJ3MgbmFtZS4KICAgICAqICBAcGFyYW0ga2luZCAgICAgIEluZGljYXRlcyB0aGUgcG9zc2libGUgc3ltYm9sIGtpbmRzCiAgICAgKiAgICAgICAgICAgICAgICAgICAoYSBzdWJzZXQgb2YgVkFMLCBUWVApLgogICAgICovCiAgICBTeW1ib2wgZmluZElkZW50SW5UeXBlKEVudjxBdHRyQ29udGV4dD4gZW52LCBUeXBlIHNpdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIE5hbWUgbmFtZSwgS2luZFNlbGVjdG9yIGtpbmQpIHsKICAgICAgICBTeW1ib2wgYmVzdFNvRmFyID0gdHlwZU5vdEZvdW5kOwogICAgICAgIFN5bWJvbCBzeW07CiAgICAgICAgaWYgKGtpbmQuY29udGFpbnMoS2luZFNlbGVjdG9yLlZBTCkpIHsKICAgICAgICAgICAgc3ltID0gZmluZEZpZWxkKGVudiwgc2l0ZSwgbmFtZSwgc2l0ZS50c3ltKTsKICAgICAgICAgICAgaWYgKHN5bS5leGlzdHMoKSkgcmV0dXJuIHN5bTsKICAgICAgICAgICAgZWxzZSBiZXN0U29GYXIgPSBiZXN0T2YoYmVzdFNvRmFyLCBzeW0pOwogICAgICAgIH0KCiAgICAgICAgaWYgKGtpbmQuY29udGFpbnMoS2luZFNlbGVjdG9yLlRZUCkpIHsKICAgICAgICAgICAgc3ltID0gZmluZE1lbWJlclR5cGUoZW52LCBzaXRlLCBuYW1lLCBzaXRlLnRzeW0pOwogICAgICAgICAgICBpZiAoc3ltLmV4aXN0cygpKSByZXR1cm4gc3ltOwogICAgICAgICAgICBlbHNlIGJlc3RTb0ZhciA9IGJlc3RPZihiZXN0U29GYXIsIHN5bSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBiZXN0U29GYXI7CiAgICB9CgovKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogIEFjY2VzcyBjaGVja2luZwogKiAgVGhlIGZvbGxvd2luZyBtZXRob2RzIGNvbnZlcnQgUmVzb2x2ZUVycm9ycyB0byBFcnJvclN5bWJvbHMsIGlzc3VpbmcKICogIGFuIGVycm9yIG1lc3NhZ2UgaW4gdGhlIHByb2Nlc3MKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgogICAgLyoqIElmIGBzeW0nIGlzIGEgYmFkIHN5bWJvbDogcmVwb3J0IGVycm9yIGFuZCByZXR1cm4gZXJyU3ltYm9sCiAgICAgKiAgZWxzZSBwYXNzIHRocm91Z2ggdW5jaGFuZ2VkLAogICAgICogIGFkZGl0aW9uYWwgYXJndW1lbnRzIGR1cGxpY2F0ZSB3aGF0IGhhcyBiZWVuIHVzZWQgaW4gdHJ5aW5nIHRvIGZpbmQgdGhlCiAgICAgKiAgc3ltYm9sIHtAbGl0ZXJhbCAoLS0+IGZseXdlaWdodCBwYXR0ZXJuKX0uIFRoaXMgaW1wcm92ZXMgcGVyZm9ybWFuY2Ugc2luY2Ugd2UKICAgICAqICBleHBlY3QgbWlzc2VzIHRvIGhhcHBlbiBmcmVxdWVudGx5LgogICAgICoKICAgICAqICBAcGFyYW0gc3ltICAgICAgIFRoZSBzeW1ib2wgdGhhdCB3YXMgZm91bmQsIG9yIGEgUmVzb2x2ZUVycm9yLgogICAgICogIEBwYXJhbSBwb3MgICAgICAgVGhlIHBvc2l0aW9uIHRvIHVzZSBmb3IgZXJyb3IgcmVwb3J0aW5nLgogICAgICogIEBwYXJhbSBsb2NhdGlvbiAgVGhlIHN5bWJvbCB0aGUgc2VydmVkIGFzIGEgY29udGV4dCBmb3IgdGhpcyBsb29rdXAKICAgICAqICBAcGFyYW0gc2l0ZSAgICAgIFRoZSBvcmlnaW5hbCB0eXBlIGZyb20gd2hlcmUgdGhlIHNlbGVjdGlvbiB0b29rIHBsYWNlLgogICAgICogIEBwYXJhbSBuYW1lICAgICAgVGhlIHN5bWJvbCdzIG5hbWUuCiAgICAgKiAgQHBhcmFtIHF1YWxpZmllZCBEaWQgd2UgZ2V0IGhlcmUgdGhyb3VnaCBhIHF1YWxpZmllZCBleHByZXNzaW9uIHJlc29sdXRpb24/CiAgICAgKiAgQHBhcmFtIGFyZ3R5cGVzICBUaGUgaW52b2NhdGlvbidzIHZhbHVlIGFyZ3VtZW50cywKICAgICAqICAgICAgICAgICAgICAgICAgIGlmIHdlIGxvb2tlZCBmb3IgYSBtZXRob2QuCiAgICAgKiAgQHBhcmFtIHR5cGVhcmd0eXBlcyAgVGhlIGludm9jYXRpb24ncyB0eXBlIGFyZ3VtZW50cywKICAgICAqICAgICAgICAgICAgICAgICAgIGlmIHdlIGxvb2tlZCBmb3IgYSBtZXRob2QuCiAgICAgKiAgQHBhcmFtIGxvZ1Jlc29sdmVIZWxwZXIgaGVscGVyIGNsYXNzIHVzZWQgdG8gbG9nIHJlc29sdmUgZXJyb3JzCiAgICAgKi8KICAgIFN5bWJvbCBhY2Nlc3NJbnRlcm5hbChTeW1ib2wgc3ltLAogICAgICAgICAgICAgICAgICBEaWFnbm9zdGljUG9zaXRpb24gcG9zLAogICAgICAgICAgICAgICAgICBTeW1ib2wgbG9jYXRpb24sCiAgICAgICAgICAgICAgICAgIFR5cGUgc2l0ZSwKICAgICAgICAgICAgICAgICAgTmFtZSBuYW1lLAogICAgICAgICAgICAgICAgICBib29sZWFuIHF1YWxpZmllZCwKICAgICAgICAgICAgICAgICAgTGlzdDxUeXBlPiBhcmd0eXBlcywKICAgICAgICAgICAgICAgICAgTGlzdDxUeXBlPiB0eXBlYXJndHlwZXMsCiAgICAgICAgICAgICAgICAgIExvZ1Jlc29sdmVIZWxwZXIgbG9nUmVzb2x2ZUhlbHBlcikgewogICAgICAgIGlmIChzeW0ua2luZC5pc1Jlc29sdXRpb25FcnJvcigpKSB7CiAgICAgICAgICAgIFJlc29sdmVFcnJvciBlcnJTeW0gPSAoUmVzb2x2ZUVycm9yKXN5bS5iYXNlU3ltYm9sKCk7CiAgICAgICAgICAgIHN5bSA9IGVyclN5bS5hY2Nlc3MobmFtZSwgcXVhbGlmaWVkID8gc2l0ZS50c3ltIDogc3ltcy5ub1N5bWJvbCk7CiAgICAgICAgICAgIGFyZ3R5cGVzID0gbG9nUmVzb2x2ZUhlbHBlci5nZXRBcmd1bWVudFR5cGVzKGVyclN5bSwgc3ltLCBuYW1lLCBhcmd0eXBlcyk7CiAgICAgICAgICAgIGlmIChsb2dSZXNvbHZlSGVscGVyLnJlc29sdmVEaWFnbm9zdGljTmVlZGVkKHNpdGUsIGFyZ3R5cGVzLCB0eXBlYXJndHlwZXMpKSB7CiAgICAgICAgICAgICAgICBsb2dSZXNvbHZlRXJyb3IoZXJyU3ltLCBwb3MsIGxvY2F0aW9uLCBzaXRlLCBuYW1lLCBhcmd0eXBlcywgdHlwZWFyZ3R5cGVzKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gc3ltOwogICAgfQoKICAgIC8qKgogICAgICogVmFyaWFudCBvZiB0aGUgZ2VuZXJhbGl6ZWQgYWNjZXNzIHJvdXRpbmUsIHRvIGJlIHVzZWQgZm9yIGdlbmVyYXRpbmcgbWV0aG9kCiAgICAgKiByZXNvbHV0aW9uIGRpYWdub3N0aWNzCiAgICAgKi8KICAgIFN5bWJvbCBhY2Nlc3NNZXRob2QoU3ltYm9sIHN5bSwKICAgICAgICAgICAgICAgICAgRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcywKICAgICAgICAgICAgICAgICAgU3ltYm9sIGxvY2F0aW9uLAogICAgICAgICAgICAgICAgICBUeXBlIHNpdGUsCiAgICAgICAgICAgICAgICAgIE5hbWUgbmFtZSwKICAgICAgICAgICAgICAgICAgYm9vbGVhbiBxdWFsaWZpZWQsCiAgICAgICAgICAgICAgICAgIExpc3Q8VHlwZT4gYXJndHlwZXMsCiAgICAgICAgICAgICAgICAgIExpc3Q8VHlwZT4gdHlwZWFyZ3R5cGVzKSB7CiAgICAgICAgcmV0dXJuIGFjY2Vzc0ludGVybmFsKHN5bSwgcG9zLCBsb2NhdGlvbiwgc2l0ZSwgbmFtZSwgcXVhbGlmaWVkLCBhcmd0eXBlcywgdHlwZWFyZ3R5cGVzLCBtZXRob2RMb2dSZXNvbHZlSGVscGVyKTsKICAgIH0KCiAgICAvKiogU2FtZSBhcyBvcmlnaW5hbCBhY2Nlc3NNZXRob2QoKSwgYnV0IHdpdGhvdXQgbG9jYXRpb24uCiAgICAgKi8KICAgIFN5bWJvbCBhY2Nlc3NNZXRob2QoU3ltYm9sIHN5bSwKICAgICAgICAgICAgICAgICAgRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcywKICAgICAgICAgICAgICAgICAgVHlwZSBzaXRlLAogICAgICAgICAgICAgICAgICBOYW1lIG5hbWUsCiAgICAgICAgICAgICAgICAgIGJvb2xlYW4gcXVhbGlmaWVkLAogICAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IGFyZ3R5cGVzLAogICAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IHR5cGVhcmd0eXBlcykgewogICAgICAgIHJldHVybiBhY2Nlc3NNZXRob2Qoc3ltLCBwb3MsIHNpdGUudHN5bSwgc2l0ZSwgbmFtZSwgcXVhbGlmaWVkLCBhcmd0eXBlcywgdHlwZWFyZ3R5cGVzKTsKICAgIH0KCiAgICAvKioKICAgICAqIFZhcmlhbnQgb2YgdGhlIGdlbmVyYWxpemVkIGFjY2VzcyByb3V0aW5lLCB0byBiZSB1c2VkIGZvciBnZW5lcmF0aW5nIHZhcmlhYmxlLAogICAgICogdHlwZSByZXNvbHV0aW9uIGRpYWdub3N0aWNzCiAgICAgKi8KICAgIFN5bWJvbCBhY2Nlc3NCYXNlKFN5bWJvbCBzeW0sCiAgICAgICAgICAgICAgICAgIERpYWdub3N0aWNQb3NpdGlvbiBwb3MsCiAgICAgICAgICAgICAgICAgIFN5bWJvbCBsb2NhdGlvbiwKICAgICAgICAgICAgICAgICAgVHlwZSBzaXRlLAogICAgICAgICAgICAgICAgICBOYW1lIG5hbWUsCiAgICAgICAgICAgICAgICAgIGJvb2xlYW4gcXVhbGlmaWVkKSB7CiAgICAgICAgcmV0dXJuIGFjY2Vzc0ludGVybmFsKHN5bSwgcG9zLCBsb2NhdGlvbiwgc2l0ZSwgbmFtZSwgcXVhbGlmaWVkLCBMaXN0Lm5pbCgpLCBudWxsLCBiYXNpY0xvZ1Jlc29sdmVIZWxwZXIpOwogICAgfQoKICAgIC8qKiBTYW1lIGFzIG9yaWdpbmFsIGFjY2Vzc0Jhc2UoKSwgYnV0IHdpdGhvdXQgbG9jYXRpb24uCiAgICAgKi8KICAgIFN5bWJvbCBhY2Nlc3NCYXNlKFN5bWJvbCBzeW0sCiAgICAgICAgICAgICAgICAgIERpYWdub3N0aWNQb3NpdGlvbiBwb3MsCiAgICAgICAgICAgICAgICAgIFR5cGUgc2l0ZSwKICAgICAgICAgICAgICAgICAgTmFtZSBuYW1lLAogICAgICAgICAgICAgICAgICBib29sZWFuIHF1YWxpZmllZCkgewogICAgICAgIHJldHVybiBhY2Nlc3NCYXNlKHN5bSwgcG9zLCBzaXRlLnRzeW0sIHNpdGUsIG5hbWUsIHF1YWxpZmllZCk7CiAgICB9CgogICAgaW50ZXJmYWNlIExvZ1Jlc29sdmVIZWxwZXIgewogICAgICAgIGJvb2xlYW4gcmVzb2x2ZURpYWdub3N0aWNOZWVkZWQoVHlwZSBzaXRlLCBMaXN0PFR5cGU+IGFyZ3R5cGVzLCBMaXN0PFR5cGU+IHR5cGVhcmd0eXBlcyk7CiAgICAgICAgTGlzdDxUeXBlPiBnZXRBcmd1bWVudFR5cGVzKFJlc29sdmVFcnJvciBlcnJTeW0sIFN5bWJvbCBhY2Nlc3NlZFN5bSwgTmFtZSBuYW1lLCBMaXN0PFR5cGU+IGFyZ3R5cGVzKTsKICAgIH0KCiAgICBMb2dSZXNvbHZlSGVscGVyIGJhc2ljTG9nUmVzb2x2ZUhlbHBlciA9IG5ldyBMb2dSZXNvbHZlSGVscGVyKCkgewogICAgICAgIHB1YmxpYyBib29sZWFuIHJlc29sdmVEaWFnbm9zdGljTmVlZGVkKFR5cGUgc2l0ZSwgTGlzdDxUeXBlPiBhcmd0eXBlcywgTGlzdDxUeXBlPiB0eXBlYXJndHlwZXMpIHsKICAgICAgICAgICAgcmV0dXJuICFzaXRlLmlzRXJyb25lb3VzKCk7CiAgICAgICAgfQogICAgICAgIHB1YmxpYyBMaXN0PFR5cGU+IGdldEFyZ3VtZW50VHlwZXMoUmVzb2x2ZUVycm9yIGVyclN5bSwgU3ltYm9sIGFjY2Vzc2VkU3ltLCBOYW1lIG5hbWUsIExpc3Q8VHlwZT4gYXJndHlwZXMpIHsKICAgICAgICAgICAgcmV0dXJuIGFyZ3R5cGVzOwogICAgICAgIH0KICAgIH07CgogICAgTG9nUmVzb2x2ZUhlbHBlciBtZXRob2RMb2dSZXNvbHZlSGVscGVyID0gbmV3IExvZ1Jlc29sdmVIZWxwZXIoKSB7CiAgICAgICAgcHVibGljIGJvb2xlYW4gcmVzb2x2ZURpYWdub3N0aWNOZWVkZWQoVHlwZSBzaXRlLCBMaXN0PFR5cGU+IGFyZ3R5cGVzLCBMaXN0PFR5cGU+IHR5cGVhcmd0eXBlcykgewogICAgICAgICAgICByZXR1cm4gIXNpdGUuaXNFcnJvbmVvdXMoKSAmJgogICAgICAgICAgICAgICAgICAgICAgICAhVHlwZS5pc0Vycm9uZW91cyhhcmd0eXBlcykgJiYKICAgICAgICAgICAgICAgICAgICAgICAgKHR5cGVhcmd0eXBlcyA9PSBudWxsIHx8ICFUeXBlLmlzRXJyb25lb3VzKHR5cGVhcmd0eXBlcykpOwogICAgICAgIH0KICAgICAgICBwdWJsaWMgTGlzdDxUeXBlPiBnZXRBcmd1bWVudFR5cGVzKFJlc29sdmVFcnJvciBlcnJTeW0sIFN5bWJvbCBhY2Nlc3NlZFN5bSwgTmFtZSBuYW1lLCBMaXN0PFR5cGU+IGFyZ3R5cGVzKSB7CiAgICAgICAgICAgIHJldHVybiBhcmd0eXBlcy5tYXAobmV3IFJlc29sdmVEZWZlcnJlZFJlY292ZXJ5TWFwKEF0dHJNb2RlLlNQRUNVTEFUSVZFLCBhY2Nlc3NlZFN5bSwgY3VycmVudFJlc29sdXRpb25Db250ZXh0LnN0ZXApKTsKICAgICAgICB9CiAgICB9OwoKICAgIGNsYXNzIFJlc29sdmVEZWZlcnJlZFJlY292ZXJ5TWFwIGV4dGVuZHMgRGVmZXJyZWRBdHRyLlJlY292ZXJ5RGVmZXJyZWRUeXBlTWFwIHsKCiAgICAgICAgcHVibGljIFJlc29sdmVEZWZlcnJlZFJlY292ZXJ5TWFwKEF0dHJNb2RlIG1vZGUsIFN5bWJvbCBtc3ltLCBNZXRob2RSZXNvbHV0aW9uUGhhc2Ugc3RlcCkgewogICAgICAgICAgICBkZWZlcnJlZEF0dHIuc3VwZXIobW9kZSwgbXN5bSwgc3RlcCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwcm90ZWN0ZWQgVHlwZSB0eXBlT2YoRGVmZXJyZWRUeXBlIGR0KSB7CiAgICAgICAgICAgIFR5cGUgcmVzID0gc3VwZXIudHlwZU9mKGR0KTsKICAgICAgICAgICAgaWYgKCFyZXMuaXNFcnJvbmVvdXMoKSkgewogICAgICAgICAgICAgICAgc3dpdGNoIChUcmVlSW5mby5za2lwUGFyZW5zKGR0LnRyZWUpLmdldFRhZygpKSB7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBMQU1CREE6CiAgICAgICAgICAgICAgICAgICAgY2FzZSBSRUZFUkVOQ0U6CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBkdDsKICAgICAgICAgICAgICAgICAgICBjYXNlIENPTkRFWFBSOgogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzID09IFR5cGUucmVjb3ZlcnlUeXBlID8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkdCA6IHJlczsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gcmVzOwogICAgICAgIH0KICAgIH0KCiAgICAvKiogQ2hlY2sgdGhhdCBzeW0gaXMgbm90IGFuIGFic3RyYWN0IG1ldGhvZC4KICAgICAqLwogICAgdm9pZCBjaGVja05vbkFic3RyYWN0KERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIFN5bWJvbCBzeW0pIHsKICAgICAgICBpZiAoKHN5bS5mbGFncygpICYgQUJTVFJBQ1QpICE9IDAgJiYgKHN5bS5mbGFncygpICYgREVGQVVMVCkgPT0gMCkKICAgICAgICAgICAgbG9nLmVycm9yKHBvcywgImFic3RyYWN0LmNhbnQuYmUuYWNjZXNzZWQuZGlyZWN0bHkiLAogICAgICAgICAgICAgICAgICAgICAga2luZE5hbWUoc3ltKSwgc3ltLCBzeW0ubG9jYXRpb24oKSk7CiAgICB9CgovKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogIE5hbWUgcmVzb2x1dGlvbgogKiAgTmFtaW5nIGNvbnZlbnRpb25zIGFyZSBhcyBmb3Igc3ltYm9sIGxvb2t1cAogKiAgVW5saWtlIHRoZSBmaW5kLi4uIG1ldGhvZHMgdGhlc2UgbWV0aG9kcyB3aWxsIHJlcG9ydCBhY2Nlc3MgZXJyb3JzCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKICAgIC8qKiBSZXNvbHZlIGFuIHVucXVhbGlmaWVkIChub24tbWV0aG9kKSBpZGVudGlmaWVyLgogICAgICogIEBwYXJhbSBwb3MgICAgICAgVGhlIHBvc2l0aW9uIHRvIHVzZSBmb3IgZXJyb3IgcmVwb3J0aW5nLgogICAgICogIEBwYXJhbSBlbnYgICAgICAgVGhlIGVudmlyb25tZW50IGN1cnJlbnQgYXQgdGhlIGlkZW50aWZpZXIgdXNlLgogICAgICogIEBwYXJhbSBuYW1lICAgICAgVGhlIGlkZW50aWZpZXIncyBuYW1lLgogICAgICogIEBwYXJhbSBraW5kICAgICAgVGhlIHNldCBvZiBhZG1pc3NpYmxlIHN5bWJvbCBraW5kcyBmb3IgdGhlIGlkZW50aWZpZXIuCiAgICAgKi8KICAgIFN5bWJvbCByZXNvbHZlSWRlbnQoRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcywgRW52PEF0dHJDb250ZXh0PiBlbnYsCiAgICAgICAgICAgICAgICAgICAgICAgIE5hbWUgbmFtZSwgS2luZFNlbGVjdG9yIGtpbmQpIHsKICAgICAgICByZXR1cm4gYWNjZXNzQmFzZSgKICAgICAgICAgICAgZmluZElkZW50KGVudiwgbmFtZSwga2luZCksCiAgICAgICAgICAgIHBvcywgZW52LmVuY2xDbGFzcy5zeW0udHlwZSwgbmFtZSwgZmFsc2UpOwogICAgfQoKICAgIC8qKiBSZXNvbHZlIGFuIHVucXVhbGlmaWVkIG1ldGhvZCBpZGVudGlmaWVyLgogICAgICogIEBwYXJhbSBwb3MgICAgICAgVGhlIHBvc2l0aW9uIHRvIHVzZSBmb3IgZXJyb3IgcmVwb3J0aW5nLgogICAgICogIEBwYXJhbSBlbnYgICAgICAgVGhlIGVudmlyb25tZW50IGN1cnJlbnQgYXQgdGhlIG1ldGhvZCBpbnZvY2F0aW9uLgogICAgICogIEBwYXJhbSBuYW1lICAgICAgVGhlIGlkZW50aWZpZXIncyBuYW1lLgogICAgICogIEBwYXJhbSBhcmd0eXBlcyAgVGhlIHR5cGVzIG9mIHRoZSBpbnZvY2F0aW9uJ3MgdmFsdWUgYXJndW1lbnRzLgogICAgICogIEBwYXJhbSB0eXBlYXJndHlwZXMgIFRoZSB0eXBlcyBvZiB0aGUgaW52b2NhdGlvbidzIHR5cGUgYXJndW1lbnRzLgogICAgICovCiAgICBTeW1ib2wgcmVzb2x2ZU1ldGhvZChEaWFnbm9zdGljUG9zaXRpb24gcG9zLAogICAgICAgICAgICAgICAgICAgICAgICAgRW52PEF0dHJDb250ZXh0PiBlbnYsCiAgICAgICAgICAgICAgICAgICAgICAgICBOYW1lIG5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IGFyZ3R5cGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgTGlzdDxUeXBlPiB0eXBlYXJndHlwZXMpIHsKICAgICAgICByZXR1cm4gbG9va3VwTWV0aG9kKGVudiwgcG9zLCBlbnYuZW5jbENsYXNzLnN5bSwgcmVzb2x2ZU1ldGhvZENoZWNrLAogICAgICAgICAgICAgICAgbmV3IEJhc2ljTG9va3VwSGVscGVyKG5hbWUsIGVudi5lbmNsQ2xhc3Muc3ltLnR5cGUsIGFyZ3R5cGVzLCB0eXBlYXJndHlwZXMpIHsKICAgICAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgICAgICAgICBTeW1ib2wgZG9Mb29rdXAoRW52PEF0dHJDb250ZXh0PiBlbnYsIE1ldGhvZFJlc29sdXRpb25QaGFzZSBwaGFzZSkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmluZEZ1bihlbnYsIG5hbWUsIGFyZ3R5cGVzLCB0eXBlYXJndHlwZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGhhc2UuaXNCb3hpbmdSZXF1aXJlZCgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBoYXNlLmlzVmFyYXJnc1JlcXVpcmVkKCkpOwogICAgICAgICAgICAgICAgICAgIH19KTsKICAgIH0KCiAgICAvKiogUmVzb2x2ZSBhIHF1YWxpZmllZCBtZXRob2QgaWRlbnRpZmllcgogICAgICogIEBwYXJhbSBwb3MgICAgICAgVGhlIHBvc2l0aW9uIHRvIHVzZSBmb3IgZXJyb3IgcmVwb3J0aW5nLgogICAgICogIEBwYXJhbSBlbnYgICAgICAgVGhlIGVudmlyb25tZW50IGN1cnJlbnQgYXQgdGhlIG1ldGhvZCBpbnZvY2F0aW9uLgogICAgICogIEBwYXJhbSBzaXRlICAgICAgVGhlIHR5cGUgb2YgdGhlIHF1YWxpZnlpbmcgZXhwcmVzc2lvbiwgaW4gd2hpY2gKICAgICAqICAgICAgICAgICAgICAgICAgIGlkZW50aWZpZXIgaXMgc2VhcmNoZWQuCiAgICAgKiAgQHBhcmFtIG5hbWUgICAgICBUaGUgaWRlbnRpZmllcidzIG5hbWUuCiAgICAgKiAgQHBhcmFtIGFyZ3R5cGVzICBUaGUgdHlwZXMgb2YgdGhlIGludm9jYXRpb24ncyB2YWx1ZSBhcmd1bWVudHMuCiAgICAgKiAgQHBhcmFtIHR5cGVhcmd0eXBlcyAgVGhlIHR5cGVzIG9mIHRoZSBpbnZvY2F0aW9uJ3MgdHlwZSBhcmd1bWVudHMuCiAgICAgKi8KICAgIFN5bWJvbCByZXNvbHZlUXVhbGlmaWVkTWV0aG9kKERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIEVudjxBdHRyQ29udGV4dD4gZW52LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVHlwZSBzaXRlLCBOYW1lIG5hbWUsIExpc3Q8VHlwZT4gYXJndHlwZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IHR5cGVhcmd0eXBlcykgewogICAgICAgIHJldHVybiByZXNvbHZlUXVhbGlmaWVkTWV0aG9kKHBvcywgZW52LCBzaXRlLnRzeW0sIHNpdGUsIG5hbWUsIGFyZ3R5cGVzLCB0eXBlYXJndHlwZXMpOwogICAgfQogICAgU3ltYm9sIHJlc29sdmVRdWFsaWZpZWRNZXRob2QoRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcywgRW52PEF0dHJDb250ZXh0PiBlbnYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTeW1ib2wgbG9jYXRpb24sIFR5cGUgc2l0ZSwgTmFtZSBuYW1lLCBMaXN0PFR5cGU+IGFyZ3R5cGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTGlzdDxUeXBlPiB0eXBlYXJndHlwZXMpIHsKICAgICAgICByZXR1cm4gcmVzb2x2ZVF1YWxpZmllZE1ldGhvZChuZXcgTWV0aG9kUmVzb2x1dGlvbkNvbnRleHQoKSwgcG9zLCBlbnYsIGxvY2F0aW9uLCBzaXRlLCBuYW1lLCBhcmd0eXBlcywgdHlwZWFyZ3R5cGVzKTsKICAgIH0KICAgIHByaXZhdGUgU3ltYm9sIHJlc29sdmVRdWFsaWZpZWRNZXRob2QoTWV0aG9kUmVzb2x1dGlvbkNvbnRleHQgcmVzb2x2ZUNvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBFbnY8QXR0ckNvbnRleHQ+IGVudiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN5bWJvbCBsb2NhdGlvbiwgVHlwZSBzaXRlLCBOYW1lIG5hbWUsIExpc3Q8VHlwZT4gYXJndHlwZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IHR5cGVhcmd0eXBlcykgewogICAgICAgIHJldHVybiBsb29rdXBNZXRob2QoZW52LCBwb3MsIGxvY2F0aW9uLCByZXNvbHZlQ29udGV4dCwgbmV3IEJhc2ljTG9va3VwSGVscGVyKG5hbWUsIHNpdGUsIGFyZ3R5cGVzLCB0eXBlYXJndHlwZXMpIHsKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIFN5bWJvbCBkb0xvb2t1cChFbnY8QXR0ckNvbnRleHQ+IGVudiwgTWV0aG9kUmVzb2x1dGlvblBoYXNlIHBoYXNlKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmluZE1ldGhvZChlbnYsIHNpdGUsIG5hbWUsIGFyZ3R5cGVzLCB0eXBlYXJndHlwZXMsCiAgICAgICAgICAgICAgICAgICAgICAgIHBoYXNlLmlzQm94aW5nUmVxdWlyZWQoKSwKICAgICAgICAgICAgICAgICAgICAgICAgcGhhc2UuaXNWYXJhcmdzUmVxdWlyZWQoKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIFN5bWJvbCBhY2Nlc3MoRW52PEF0dHJDb250ZXh0PiBlbnYsIERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIFN5bWJvbCBsb2NhdGlvbiwgU3ltYm9sIHN5bSkgewogICAgICAgICAgICAgICAgaWYgKHN5bS5raW5kLmlzUmVzb2x1dGlvbkVycm9yKCkpIHsKICAgICAgICAgICAgICAgICAgICBzeW0gPSBzdXBlci5hY2Nlc3MoZW52LCBwb3MsIGxvY2F0aW9uLCBzeW0pOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChhbGxvd01ldGhvZEhhbmRsZXMpIHsKICAgICAgICAgICAgICAgICAgICBNZXRob2RTeW1ib2wgbXN5bSA9IChNZXRob2RTeW1ib2wpc3ltOwogICAgICAgICAgICAgICAgICAgIGlmICgobXN5bS5mbGFncygpICYgU0lHTkFUVVJFX1BPTFlNT1JQSElDKSAhPSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmaW5kUG9seW1vcnBoaWNTaWduYXR1cmVJbnN0YW5jZShlbnYsIHN5bSwgYXJndHlwZXMpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBzeW07CiAgICAgICAgICAgIH0KICAgICAgICB9KTsKICAgIH0KCiAgICAvKiogRmluZCBvciBjcmVhdGUgYW4gaW1wbGljaXQgbWV0aG9kIG9mIGV4YWN0bHkgdGhlIGdpdmVuIHR5cGUgKGFmdGVyIGVyYXN1cmUpLgogICAgICogIFNlYXJjaGVzIGluIGEgc2lkZSB0YWJsZSwgbm90IHRoZSBtYWluIHNjb3BlIG9mIHRoZSBzaXRlLgogICAgICogIFRoaXMgZW11bGF0ZXMgdGhlIGxvb2t1cCBwcm9jZXNzIHJlcXVpcmVkIGJ5IEpTUiAyOTIgaW4gSlZNLgogICAgICogIEBwYXJhbSBlbnYgICAgICAgQXR0cmlidXRpb24gZW52aXJvbm1lbnQKICAgICAqICBAcGFyYW0gc3BNZXRob2QgIHNpZ25hdHVyZSBwb2x5bW9ycGhpYyBtZXRob2QgLSBpLmUuIE1ILmludm9rZUV4YWN0CiAgICAgKiAgQHBhcmFtIGFyZ3R5cGVzICBUaGUgcmVxdWlyZWQgYXJndW1lbnQgdHlwZXMKICAgICAqLwogICAgU3ltYm9sIGZpbmRQb2x5bW9ycGhpY1NpZ25hdHVyZUluc3RhbmNlKEVudjxBdHRyQ29udGV4dD4gZW52LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIFN5bWJvbCBzcE1ldGhvZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IGFyZ3R5cGVzKSB7CiAgICAgICAgVHlwZSBtdHlwZSA9IGluZmVyLmluc3RhbnRpYXRlUG9seW1vcnBoaWNTaWduYXR1cmVJbnN0YW5jZShlbnYsCiAgICAgICAgICAgICAgICAoTWV0aG9kU3ltYm9sKXNwTWV0aG9kLCBjdXJyZW50UmVzb2x1dGlvbkNvbnRleHQsIGFyZ3R5cGVzKTsKICAgICAgICBmb3IgKFN5bWJvbCBzeW0gOiBwb2x5bW9ycGhpY1NpZ25hdHVyZVNjb3BlLmdldFN5bWJvbHNCeU5hbWUoc3BNZXRob2QubmFtZSkpIHsKICAgICAgICAgICAgLy8gQ2hlY2sgdGhhdCB0aGVyZSBpcyBhbHJlYWR5IGEgbWV0aG9kIHN5bWJvbCBmb3IgdGhlIG1ldGhvZAogICAgICAgICAgICAvLyB0eXBlIGFuZCBvd25lcgogICAgICAgICAgICBpZiAodHlwZXMuaXNTYW1lVHlwZShtdHlwZSwgc3ltLnR5cGUpICYmCiAgICAgICAgICAgICAgICBzcE1ldGhvZC5vd25lciA9PSBzeW0ub3duZXIpIHsKICAgICAgICAgICAgICAgIHJldHVybiBzeW07CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIENyZWF0ZSB0aGUgZGVzaXJlZCBtZXRob2QKICAgICAgICAvLyBSZXRhaW4gc3RhdGljIG1vZGlmaWVyIGlzIHRvIHN1cHBvcnQgaW52b2NhdGlvbnMgdG8KICAgICAgICAvLyBNZXRob2RIYW5kbGUubGlua1RvKiBtZXRob2RzCiAgICAgICAgbG9uZyBmbGFncyA9IEFCU1RSQUNUIHwgSFlQT1RIRVRJQ0FMIHwKICAgICAgICAgICAgICAgICAgICAgc3BNZXRob2QuZmxhZ3MoKSAmIChGbGFncy5BY2Nlc3NGbGFncyB8IEZsYWdzLlNUQVRJQyk7CiAgICAgICAgU3ltYm9sIG1zeW0gPSBuZXcgTWV0aG9kU3ltYm9sKGZsYWdzLCBzcE1ldGhvZC5uYW1lLCBtdHlwZSwgc3BNZXRob2Qub3duZXIpIHsKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHB1YmxpYyBTeW1ib2wgYmFzZVN5bWJvbCgpIHsKICAgICAgICAgICAgICAgIHJldHVybiBzcE1ldGhvZDsKICAgICAgICAgICAgfQogICAgICAgIH07CiAgICAgICAgaWYgKCFtdHlwZS5pc0Vycm9uZW91cygpKSB7IC8vIENhY2hlIG9ubHkgaWYga29zaGVyLgogICAgICAgICAgICBwb2x5bW9ycGhpY1NpZ25hdHVyZVNjb3BlLmVudGVyKG1zeW0pOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbXN5bTsKICAgIH0KCiAgICAvKiogUmVzb2x2ZSBhIHF1YWxpZmllZCBtZXRob2QgaWRlbnRpZmllciwgdGhyb3cgYSBmYXRhbCBlcnJvciBpZiBub3QKICAgICAqICBmb3VuZC4KICAgICAqICBAcGFyYW0gcG9zICAgICAgIFRoZSBwb3NpdGlvbiB0byB1c2UgZm9yIGVycm9yIHJlcG9ydGluZy4KICAgICAqICBAcGFyYW0gZW52ICAgICAgIFRoZSBlbnZpcm9ubWVudCBjdXJyZW50IGF0IHRoZSBtZXRob2QgaW52b2NhdGlvbi4KICAgICAqICBAcGFyYW0gc2l0ZSAgICAgIFRoZSB0eXBlIG9mIHRoZSBxdWFsaWZ5aW5nIGV4cHJlc3Npb24sIGluIHdoaWNoCiAgICAgKiAgICAgICAgICAgICAgICAgICBpZGVudGlmaWVyIGlzIHNlYXJjaGVkLgogICAgICogIEBwYXJhbSBuYW1lICAgICAgVGhlIGlkZW50aWZpZXIncyBuYW1lLgogICAgICogIEBwYXJhbSBhcmd0eXBlcyAgVGhlIHR5cGVzIG9mIHRoZSBpbnZvY2F0aW9uJ3MgdmFsdWUgYXJndW1lbnRzLgogICAgICogIEBwYXJhbSB0eXBlYXJndHlwZXMgIFRoZSB0eXBlcyBvZiB0aGUgaW52b2NhdGlvbidzIHR5cGUgYXJndW1lbnRzLgogICAgICovCiAgICBwdWJsaWMgTWV0aG9kU3ltYm9sIHJlc29sdmVJbnRlcm5hbE1ldGhvZChEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBFbnY8QXR0ckNvbnRleHQ+IGVudiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFR5cGUgc2l0ZSwgTmFtZSBuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTGlzdDxUeXBlPiBhcmd0eXBlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExpc3Q8VHlwZT4gdHlwZWFyZ3R5cGVzKSB7CiAgICAgICAgTWV0aG9kUmVzb2x1dGlvbkNvbnRleHQgcmVzb2x2ZUNvbnRleHQgPSBuZXcgTWV0aG9kUmVzb2x1dGlvbkNvbnRleHQoKTsKICAgICAgICByZXNvbHZlQ29udGV4dC5pbnRlcm5hbFJlc29sdXRpb24gPSB0cnVlOwogICAgICAgIFN5bWJvbCBzeW0gPSByZXNvbHZlUXVhbGlmaWVkTWV0aG9kKHJlc29sdmVDb250ZXh0LCBwb3MsIGVudiwgc2l0ZS50c3ltLAogICAgICAgICAgICAgICAgc2l0ZSwgbmFtZSwgYXJndHlwZXMsIHR5cGVhcmd0eXBlcyk7CiAgICAgICAgaWYgKHN5bS5raW5kID09IE1USCkgcmV0dXJuIChNZXRob2RTeW1ib2wpc3ltOwogICAgICAgIGVsc2UgdGhyb3cgbmV3IEZhdGFsRXJyb3IoCiAgICAgICAgICAgICAgICAgZGlhZ3MuZnJhZ21lbnQoImZhdGFsLmVyci5jYW50LmxvY2F0ZS5tZXRoIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lKSk7CiAgICB9CgogICAgLyoqIFJlc29sdmUgY29uc3RydWN0b3IuCiAgICAgKiAgQHBhcmFtIHBvcyAgICAgICBUaGUgcG9zaXRpb24gdG8gdXNlIGZvciBlcnJvciByZXBvcnRpbmcuCiAgICAgKiAgQHBhcmFtIGVudiAgICAgICBUaGUgZW52aXJvbm1lbnQgY3VycmVudCBhdCB0aGUgY29uc3RydWN0b3IgaW52b2NhdGlvbi4KICAgICAqICBAcGFyYW0gc2l0ZSAgICAgIFRoZSB0eXBlIG9mIGNsYXNzIGZvciB3aGljaCBhIGNvbnN0cnVjdG9yIGlzIHNlYXJjaGVkLgogICAgICogIEBwYXJhbSBhcmd0eXBlcyAgVGhlIHR5cGVzIG9mIHRoZSBjb25zdHJ1Y3RvciBpbnZvY2F0aW9uJ3MgdmFsdWUKICAgICAqICAgICAgICAgICAgICAgICAgIGFyZ3VtZW50cy4KICAgICAqICBAcGFyYW0gdHlwZWFyZ3R5cGVzICBUaGUgdHlwZXMgb2YgdGhlIGNvbnN0cnVjdG9yIGludm9jYXRpb24ncyB0eXBlCiAgICAgKiAgICAgICAgICAgICAgICAgICBhcmd1bWVudHMuCiAgICAgKi8KICAgIFN5bWJvbCByZXNvbHZlQ29uc3RydWN0b3IoRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRW52PEF0dHJDb250ZXh0PiBlbnYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFR5cGUgc2l0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTGlzdDxUeXBlPiBhcmd0eXBlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTGlzdDxUeXBlPiB0eXBlYXJndHlwZXMpIHsKICAgICAgICByZXR1cm4gcmVzb2x2ZUNvbnN0cnVjdG9yKG5ldyBNZXRob2RSZXNvbHV0aW9uQ29udGV4dCgpLCBwb3MsIGVudiwgc2l0ZSwgYXJndHlwZXMsIHR5cGVhcmd0eXBlcyk7CiAgICB9CgogICAgcHJpdmF0ZSBTeW1ib2wgcmVzb2x2ZUNvbnN0cnVjdG9yKE1ldGhvZFJlc29sdXRpb25Db250ZXh0IHJlc29sdmVDb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBEaWFnbm9zdGljUG9zaXRpb24gcG9zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFbnY8QXR0ckNvbnRleHQ+IGVudiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVHlwZSBzaXRlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IGFyZ3R5cGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IHR5cGVhcmd0eXBlcykgewogICAgICAgIHJldHVybiBsb29rdXBNZXRob2QoZW52LCBwb3MsIHNpdGUudHN5bSwgcmVzb2x2ZUNvbnRleHQsIG5ldyBCYXNpY0xvb2t1cEhlbHBlcihuYW1lcy5pbml0LCBzaXRlLCBhcmd0eXBlcywgdHlwZWFyZ3R5cGVzKSB7CiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBTeW1ib2wgZG9Mb29rdXAoRW52PEF0dHJDb250ZXh0PiBlbnYsIE1ldGhvZFJlc29sdXRpb25QaGFzZSBwaGFzZSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZpbmRDb25zdHJ1Y3Rvcihwb3MsIGVudiwgc2l0ZSwgYXJndHlwZXMsIHR5cGVhcmd0eXBlcywKICAgICAgICAgICAgICAgICAgICAgICAgcGhhc2UuaXNCb3hpbmdSZXF1aXJlZCgpLAogICAgICAgICAgICAgICAgICAgICAgICBwaGFzZS5pc1ZhcmFyZ3NSZXF1aXJlZCgpKTsKICAgICAgICAgICAgfQogICAgICAgIH0pOwogICAgfQoKICAgIC8qKiBSZXNvbHZlIGEgY29uc3RydWN0b3IsIHRocm93IGEgZmF0YWwgZXJyb3IgaWYgbm90IGZvdW5kLgogICAgICogIEBwYXJhbSBwb3MgICAgICAgVGhlIHBvc2l0aW9uIHRvIHVzZSBmb3IgZXJyb3IgcmVwb3J0aW5nLgogICAgICogIEBwYXJhbSBlbnYgICAgICAgVGhlIGVudmlyb25tZW50IGN1cnJlbnQgYXQgdGhlIG1ldGhvZCBpbnZvY2F0aW9uLgogICAgICogIEBwYXJhbSBzaXRlICAgICAgVGhlIHR5cGUgdG8gYmUgY29uc3RydWN0ZWQuCiAgICAgKiAgQHBhcmFtIGFyZ3R5cGVzICBUaGUgdHlwZXMgb2YgdGhlIGludm9jYXRpb24ncyB2YWx1ZSBhcmd1bWVudHMuCiAgICAgKiAgQHBhcmFtIHR5cGVhcmd0eXBlcyAgVGhlIHR5cGVzIG9mIHRoZSBpbnZvY2F0aW9uJ3MgdHlwZSBhcmd1bWVudHMuCiAgICAgKi8KICAgIHB1YmxpYyBNZXRob2RTeW1ib2wgcmVzb2x2ZUludGVybmFsQ29uc3RydWN0b3IoRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcywgRW52PEF0dHJDb250ZXh0PiBlbnYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUeXBlIHNpdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IGFyZ3R5cGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTGlzdDxUeXBlPiB0eXBlYXJndHlwZXMpIHsKICAgICAgICBNZXRob2RSZXNvbHV0aW9uQ29udGV4dCByZXNvbHZlQ29udGV4dCA9IG5ldyBNZXRob2RSZXNvbHV0aW9uQ29udGV4dCgpOwogICAgICAgIHJlc29sdmVDb250ZXh0LmludGVybmFsUmVzb2x1dGlvbiA9IHRydWU7CiAgICAgICAgU3ltYm9sIHN5bSA9IHJlc29sdmVDb25zdHJ1Y3RvcihyZXNvbHZlQ29udGV4dCwgcG9zLCBlbnYsIHNpdGUsIGFyZ3R5cGVzLCB0eXBlYXJndHlwZXMpOwogICAgICAgIGlmIChzeW0ua2luZCA9PSBNVEgpIHJldHVybiAoTWV0aG9kU3ltYm9sKXN5bTsKICAgICAgICBlbHNlIHRocm93IG5ldyBGYXRhbEVycm9yKAogICAgICAgICAgICAgICAgIGRpYWdzLmZyYWdtZW50KCJmYXRhbC5lcnIuY2FudC5sb2NhdGUuY3RvciIsIHNpdGUpKTsKICAgIH0KCiAgICBTeW1ib2wgZmluZENvbnN0cnVjdG9yKERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIEVudjxBdHRyQ29udGV4dD4gZW52LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUeXBlIHNpdGUsIExpc3Q8VHlwZT4gYXJndHlwZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExpc3Q8VHlwZT4gdHlwZWFyZ3R5cGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGFsbG93Qm94aW5nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIHVzZVZhcmFyZ3MpIHsKICAgICAgICBTeW1ib2wgc3ltID0gZmluZE1ldGhvZChlbnYsIHNpdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVzLmluaXQsIGFyZ3R5cGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlYXJndHlwZXMsIGFsbG93Qm94aW5nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1c2VWYXJhcmdzKTsKICAgICAgICBjaGsuY2hlY2tEZXByZWNhdGVkKHBvcywgZW52LmluZm8uc2NvcGUub3duZXIsIHN5bSk7CiAgICAgICAgcmV0dXJuIHN5bTsKICAgIH0KCiAgICAvKiogUmVzb2x2ZSBjb25zdHJ1Y3RvciB1c2luZyBkaWFtb25kIGluZmVyZW5jZS4KICAgICAqICBAcGFyYW0gcG9zICAgICAgIFRoZSBwb3NpdGlvbiB0byB1c2UgZm9yIGVycm9yIHJlcG9ydGluZy4KICAgICAqICBAcGFyYW0gZW52ICAgICAgIFRoZSBlbnZpcm9ubWVudCBjdXJyZW50IGF0IHRoZSBjb25zdHJ1Y3RvciBpbnZvY2F0aW9uLgogICAgICogIEBwYXJhbSBzaXRlICAgICAgVGhlIHR5cGUgb2YgY2xhc3MgZm9yIHdoaWNoIGEgY29uc3RydWN0b3IgaXMgc2VhcmNoZWQuCiAgICAgKiAgICAgICAgICAgICAgICAgICBUaGUgc2NvcGUgb2YgdGhpcyBjbGFzcyBoYXMgYmVlbiB0b3VjaGVkIGluIGF0dHJpYnV0aW9uLgogICAgICogIEBwYXJhbSBhcmd0eXBlcyAgVGhlIHR5cGVzIG9mIHRoZSBjb25zdHJ1Y3RvciBpbnZvY2F0aW9uJ3MgdmFsdWUKICAgICAqICAgICAgICAgICAgICAgICAgIGFyZ3VtZW50cy4KICAgICAqICBAcGFyYW0gdHlwZWFyZ3R5cGVzICBUaGUgdHlwZXMgb2YgdGhlIGNvbnN0cnVjdG9yIGludm9jYXRpb24ncyB0eXBlCiAgICAgKiAgICAgICAgICAgICAgICAgICBhcmd1bWVudHMuCiAgICAgKi8KICAgIFN5bWJvbCByZXNvbHZlRGlhbW9uZChEaWFnbm9zdGljUG9zaXRpb24gcG9zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFbnY8QXR0ckNvbnRleHQ+IGVudiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVHlwZSBzaXRlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IGFyZ3R5cGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IHR5cGVhcmd0eXBlcykgewogICAgICAgIHJldHVybiBsb29rdXBNZXRob2QoZW52LCBwb3MsIHNpdGUudHN5bSwgcmVzb2x2ZU1ldGhvZENoZWNrLAogICAgICAgICAgICAgICAgbmV3IEJhc2ljTG9va3VwSGVscGVyKG5hbWVzLmluaXQsIHNpdGUsIGFyZ3R5cGVzLCB0eXBlYXJndHlwZXMpIHsKICAgICAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgICAgICAgICBTeW1ib2wgZG9Mb29rdXAoRW52PEF0dHJDb250ZXh0PiBlbnYsIE1ldGhvZFJlc29sdXRpb25QaGFzZSBwaGFzZSkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmluZERpYW1vbmQoZW52LCBzaXRlLCBhcmd0eXBlcywgdHlwZWFyZ3R5cGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBoYXNlLmlzQm94aW5nUmVxdWlyZWQoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwaGFzZS5pc1ZhcmFyZ3NSZXF1aXJlZCgpKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgICAgICAgICAgU3ltYm9sIGFjY2VzcyhFbnY8QXR0ckNvbnRleHQ+IGVudiwgRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcywgU3ltYm9sIGxvY2F0aW9uLCBTeW1ib2wgc3ltKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzeW0ua2luZC5pc1Jlc29sdXRpb25FcnJvcigpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3ltLmtpbmQgIT0gV1JPTkdfTVRIICYmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ltLmtpbmQgIT0gV1JPTkdfTVRIUykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5bSA9IHN1cGVyLmFjY2VzcyhlbnYsIHBvcywgbG9jYXRpb24sIHN5bSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIEpDRGlhZ25vc3RpYyBkZXRhaWxzID0gc3ltLmtpbmQgPT0gV1JPTkdfTVRIID8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKChJbmFwcGxpY2FibGVTeW1ib2xFcnJvcilzeW0uYmFzZVN5bWJvbCgpKS5lcnJDYW5kaWRhdGUoKS5zbmQgOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5bSA9IG5ldyBEaWFtb25kRXJyb3Ioc3ltLCBjdXJyZW50UmVzb2x1dGlvbkNvbnRleHQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5bSA9IGFjY2Vzc01ldGhvZChzeW0sIHBvcywgc2l0ZSwgbmFtZXMuaW5pdCwgdHJ1ZSwgYXJndHlwZXMsIHR5cGVhcmd0eXBlcyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW52LmluZm8ucGVuZGluZ1Jlc29sdXRpb25QaGFzZSA9IGN1cnJlbnRSZXNvbHV0aW9uQ29udGV4dC5zdGVwOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzeW07CiAgICAgICAgICAgICAgICAgICAgfX0pOwogICAgfQoKICAgIC8qKiBUaGlzIG1ldGhvZCBzY2FucyBhbGwgdGhlIGNvbnN0cnVjdG9yIHN5bWJvbCBpbiBhIGdpdmVuIGNsYXNzIHNjb3BlIC0KICAgICAqICBhc3N1bWluZyB0aGF0IHRoZSBvcmlnaW5hbCBzY29wZSBjb250YWlucyBhIGNvbnN0cnVjdG9yIG9mIHRoZSBraW5kOgogICAgICogIHtAY29kZSBGb28oWCB4LCBZIHkpfSwgd2hlcmUgWCxZIGFyZSBjbGFzcyB0eXBlLXZhcmlhYmxlcyBkZWNsYXJlZCBpbiBGb28sCiAgICAgKiAgYSBtZXRob2QgY2hlY2sgaXMgZXhlY3V0ZWQgYWdhaW5zdCB0aGUgbW9kaWZpZWQgY29uc3RydWN0b3IgdHlwZToKICAgICAqICB7QGNvZGUgPFgsWT5Gb288WCxZPihYIHgsIFkgeSl9LiBUaGlzIGlzIGNydWNpYWwgaW4gb3JkZXIgdG8gZW5hYmxlIGRpYW1vbmQKICAgICAqICBpbmZlcmVuY2UuIFRoZSBpbmZlcnJlZCByZXR1cm4gdHlwZSBvZiB0aGUgc3ludGhldGljIGNvbnN0cnVjdG9yIElTCiAgICAgKiAgdGhlIGluZmVycmVkIHR5cGUgZm9yIHRoZSBkaWFtb25kIG9wZXJhdG9yLgogICAgICovCiAgICBwcml2YXRlIFN5bWJvbCBmaW5kRGlhbW9uZChFbnY8QXR0ckNvbnRleHQ+IGVudiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVHlwZSBzaXRlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IGFyZ3R5cGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IHR5cGVhcmd0eXBlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBhbGxvd0JveGluZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiB1c2VWYXJhcmdzKSB7CiAgICAgICAgU3ltYm9sIGJlc3RTb0ZhciA9IG1ldGhvZE5vdEZvdW5kOwogICAgICAgIFR5cGVTeW1ib2wgdHN5bSA9IHNpdGUudHN5bS5pc0ludGVyZmFjZSgpID8gc3ltcy5vYmplY3RUeXBlLnRzeW0gOiBzaXRlLnRzeW07CiAgICAgICAgZm9yIChmaW5hbCBTeW1ib2wgc3ltIDogdHN5bS5tZW1iZXJzKCkuZ2V0U3ltYm9sc0J5TmFtZShuYW1lcy5pbml0KSkgewogICAgICAgICAgICAvLy0gU3lzdGVtLm91dC5wcmludGxuKCIgZSAiICsgZS5zeW0pOwogICAgICAgICAgICBpZiAoc3ltLmtpbmQgPT0gTVRIICYmCiAgICAgICAgICAgICAgICAoc3ltLmZsYWdzX2ZpZWxkICYgU1lOVEhFVElDKSA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgTGlzdDxUeXBlPiBvbGRQYXJhbXMgPSBzeW0udHlwZS5oYXNUYWcoRk9SQUxMKSA/CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKEZvckFsbClzeW0udHlwZSkudHZhcnMgOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgTGlzdC5uaWwoKTsKICAgICAgICAgICAgICAgICAgICBUeXBlIGNvbnN0clR5cGUgPSBuZXcgRm9yQWxsKHNpdGUudHN5bS50eXBlLmdldFR5cGVBcmd1bWVudHMoKS5hcHBlbmRMaXN0KG9sZFBhcmFtcyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlcy5jcmVhdGVNZXRob2RUeXBlV2l0aFJldHVybihzeW0udHlwZS5hc01ldGhvZFR5cGUoKSwgc2l0ZSkpOwogICAgICAgICAgICAgICAgICAgIE1ldGhvZFN5bWJvbCBuZXdDb25zdHIgPSBuZXcgTWV0aG9kU3ltYm9sKHN5bS5mbGFncygpLCBuYW1lcy5pbml0LCBjb25zdHJUeXBlLCBzaXRlLnRzeW0pIHsKICAgICAgICAgICAgICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgICAgICAgICAgICAgIHB1YmxpYyBTeW1ib2wgYmFzZVN5bWJvbCgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzeW07CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgICAgIGJlc3RTb0ZhciA9IHNlbGVjdEJlc3QoZW52LCBzaXRlLCBhcmd0eXBlcywgdHlwZWFyZ3R5cGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3Q29uc3RyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgYmVzdFNvRmFyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgYWxsb3dCb3hpbmcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1c2VWYXJhcmdzKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gYmVzdFNvRmFyOwogICAgfQoKICAgIFN5bWJvbCBnZXRNZW1iZXJSZWZlcmVuY2UoRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcywKICAgICAgICAgICAgRW52PEF0dHJDb250ZXh0PiBlbnYsCiAgICAgICAgICAgIEpDTWVtYmVyUmVmZXJlbmNlIHJlZmVyZW5jZVRyZWUsCiAgICAgICAgICAgIFR5cGUgc2l0ZSwKICAgICAgICAgICAgTmFtZSBuYW1lKSB7CgogICAgICAgIHNpdGUgPSB0eXBlcy5jYXB0dXJlKHNpdGUpOwoKICAgICAgICBSZWZlcmVuY2VMb29rdXBIZWxwZXIgbG9va3VwSGVscGVyID0gbWFrZVJlZmVyZW5jZUxvb2t1cEhlbHBlcigKICAgICAgICAgICAgICAgIHJlZmVyZW5jZVRyZWUsIHNpdGUsIG5hbWUsIExpc3QubmlsKCksIG51bGwsIFZBUkFSSVRZKTsKCiAgICAgICAgRW52PEF0dHJDb250ZXh0PiBuZXdFbnYgPSBlbnYuZHVwKGVudi50cmVlLCBlbnYuaW5mby5kdXAoKSk7CiAgICAgICAgU3ltYm9sIHN5bSA9IGxvb2t1cE1ldGhvZChuZXdFbnYsIGVudi50cmVlLnBvcygpLCBzaXRlLnRzeW0sCiAgICAgICAgICAgICAgICBuaWxNZXRob2RDaGVjaywgbG9va3VwSGVscGVyKTsKCiAgICAgICAgZW52LmluZm8ucGVuZGluZ1Jlc29sdXRpb25QaGFzZSA9IG5ld0Vudi5pbmZvLnBlbmRpbmdSZXNvbHV0aW9uUGhhc2U7CgogICAgICAgIHJldHVybiBzeW07CiAgICB9CgogICAgUmVmZXJlbmNlTG9va3VwSGVscGVyIG1ha2VSZWZlcmVuY2VMb29rdXBIZWxwZXIoSkNNZW1iZXJSZWZlcmVuY2UgcmVmZXJlbmNlVHJlZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFR5cGUgc2l0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5hbWUgbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExpc3Q8VHlwZT4gYXJndHlwZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IHR5cGVhcmd0eXBlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1ldGhvZFJlc29sdXRpb25QaGFzZSBtYXhQaGFzZSkgewogICAgICAgIGlmICghbmFtZS5lcXVhbHMobmFtZXMuaW5pdCkpIHsKICAgICAgICAgICAgLy9tZXRob2QgcmVmZXJlbmNlCiAgICAgICAgICAgIHJldHVybiBuZXcgTWV0aG9kUmVmZXJlbmNlTG9va3VwSGVscGVyKHJlZmVyZW5jZVRyZWUsIG5hbWUsIHNpdGUsIGFyZ3R5cGVzLCB0eXBlYXJndHlwZXMsIG1heFBoYXNlKTsKICAgICAgICB9IGVsc2UgaWYgKHNpdGUuaGFzVGFnKEFSUkFZKSkgewogICAgICAgICAgICAvL2FycmF5IGNvbnN0cnVjdG9yIHJlZmVyZW5jZQogICAgICAgICAgICByZXR1cm4gbmV3IEFycmF5Q29uc3RydWN0b3JSZWZlcmVuY2VMb29rdXBIZWxwZXIocmVmZXJlbmNlVHJlZSwgc2l0ZSwgYXJndHlwZXMsIHR5cGVhcmd0eXBlcywgbWF4UGhhc2UpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8vY2xhc3MgY29uc3RydWN0b3IgcmVmZXJlbmNlCiAgICAgICAgICAgIHJldHVybiBuZXcgQ29uc3RydWN0b3JSZWZlcmVuY2VMb29rdXBIZWxwZXIocmVmZXJlbmNlVHJlZSwgc2l0ZSwgYXJndHlwZXMsIHR5cGVhcmd0eXBlcywgbWF4UGhhc2UpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFJlc29sdXRpb24gb2YgbWVtYmVyIHJlZmVyZW5jZXMgaXMgdHlwaWNhbGx5IGRvbmUgYXMgYSBzaW5nbGUKICAgICAqIG92ZXJsb2FkIHJlc29sdXRpb24gc3RlcCwgd2hlcmUgdGhlIGFyZ3VtZW50IHR5cGVzIEEgYXJlIGluZmVycmVkIGZyb20KICAgICAqIHRoZSB0YXJnZXQgZnVuY3Rpb25hbCBkZXNjcmlwdG9yLgogICAgICoKICAgICAqIElmIHRoZSBtZW1iZXIgcmVmZXJlbmNlIGlzIGEgbWV0aG9kIHJlZmVyZW5jZSB3aXRoIGEgdHlwZSBxdWFsaWZpZXIsCiAgICAgKiBhIHR3by1zdGVwIGxvb2t1cCBwcm9jZXNzIGlzIHBlcmZvcm1lZC4gVGhlIGZpcnN0IHN0ZXAgdXNlcyB0aGUKICAgICAqIGV4cGVjdGVkIGFyZ3VtZW50IGxpc3QgQSwgd2hpbGUgdGhlIHNlY29uZCBzdGVwIGRpc2NhcmRzIHRoZSBmaXJzdAogICAgICogdHlwZSBmcm9tIEEgKHdoaWNoIGlzIHRyZWF0ZWQgYXMgYSByZWNlaXZlciB0eXBlKS4KICAgICAqCiAgICAgKiBUaGVyZSBhcmUgdHdvIGNhc2VzIGluIHdoaWNoIGluZmVyZW5jZSBpcyBwZXJmb3JtZWQ6IChpKSBpZiB0aGUgbWVtYmVyCiAgICAgKiByZWZlcmVuY2UgaXMgYSBjb25zdHJ1Y3RvciByZWZlcmVuY2UgYW5kIHRoZSBxdWFsaWZpZXIgdHlwZSBpcyByYXcgLSBpbgogICAgICogd2hpY2ggY2FzZSBkaWFtb25kIGluZmVyZW5jZSBpcyB1c2VkIHRvIGluZmVyIGEgcGFyYW1ldGVyaXphdGlvbiBmb3IgdGhlCiAgICAgKiB0eXBlIHF1YWxpZmllcjsgKGlpKSBpZiB0aGUgbWVtYmVyIHJlZmVyZW5jZSBpcyBhbiB1bmJvdW5kIHJlZmVyZW5jZQogICAgICogd2hlcmUgdGhlIHR5cGUgcXVhbGlmaWVyIGlzIHJhdyAtIGluIHRoYXQgY2FzZSwgZHVyaW5nIHRoZSB1bmJvdW5kIGxvb2t1cAogICAgICogdGhlIHJlY2VpdmVyIGFyZ3VtZW50IHR5cGUgaXMgdXNlZCB0byBpbmZlciBhbiBpbnN0YW50aWF0aW9uIGZvciB0aGUgcmF3CiAgICAgKiBxdWFsaWZpZXIgdHlwZS4KICAgICAqCiAgICAgKiBXaGVuIGEgbXVsdGktc3RlcCByZXNvbHV0aW9uIHByb2Nlc3MgaXMgZXhwbG9pdGVkLCB0aGUgcHJvY2VzcyBvZiBwaWNraW5nCiAgICAgKiB0aGUgcmVzdWx0aW5nIHN5bWJvbCBpcyBkZWxlZ2F0ZWQgdG8gYW4gaGVscGVyIGNsYXNzIHtAbGluayBjb20uc3VuLnRvb2xzLmphdmFjLmNvbXAuUmVzb2x2ZS5SZWZlcmVuY2VDaG9vc2VyfS4KICAgICAqCiAgICAgKiBUaGlzIHJvdXRpbmUgcmV0dXJucyBhIHBhaXIgKFQsUyksIHdoZXJlIFMgaXMgdGhlIG1lbWJlciByZWZlcmVuY2Ugc3ltYm9sLAogICAgICogYW5kIFQgaXMgdGhlIHR5cGUgb2YgdGhlIGNsYXNzIGluIHdoaWNoIFMgaXMgZGVmaW5lZC4gVGhpcyBpcyBuZWNlc3NhcnkgYXMKICAgICAqIHRoZSB0eXBlIFQgbWlnaHQgYmUgZHluYW1pY2FsbHkgaW5mZXJyZWQgKGkuZS4gaWYgY29uc3RydWN0b3IgcmVmZXJlbmNlCiAgICAgKiBoYXMgYSByYXcgcXVhbGlmaWVyKS4KICAgICAqLwogICAgUGFpcjxTeW1ib2wsIFJlZmVyZW5jZUxvb2t1cEhlbHBlcj4gcmVzb2x2ZU1lbWJlclJlZmVyZW5jZShFbnY8QXR0ckNvbnRleHQ+IGVudiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEpDTWVtYmVyUmVmZXJlbmNlIHJlZmVyZW5jZVRyZWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUeXBlIHNpdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOYW1lIG5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IGFyZ3R5cGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTGlzdDxUeXBlPiB0eXBlYXJndHlwZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXRob2RDaGVjayBtZXRob2RDaGVjaywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEluZmVyZW5jZUNvbnRleHQgaW5mZXJlbmNlQ29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlZmVyZW5jZUNob29zZXIgcmVmZXJlbmNlQ2hvb3NlcikgewoKICAgICAgICAvL3N0ZXAgMSAtIGJvdW5kIGxvb2t1cAogICAgICAgIFJlZmVyZW5jZUxvb2t1cEhlbHBlciBib3VuZExvb2t1cEhlbHBlciA9IG1ha2VSZWZlcmVuY2VMb29rdXBIZWxwZXIoCiAgICAgICAgICAgICAgICByZWZlcmVuY2VUcmVlLCBzaXRlLCBuYW1lLCBhcmd0eXBlcywgdHlwZWFyZ3R5cGVzLCBWQVJBUklUWSk7CiAgICAgICAgRW52PEF0dHJDb250ZXh0PiBib3VuZEVudiA9IGVudi5kdXAoZW52LnRyZWUsIGVudi5pbmZvLmR1cCgpKTsKICAgICAgICBNZXRob2RSZXNvbHV0aW9uQ29udGV4dCBib3VuZFNlYXJjaFJlc29sdmVDb250ZXh0ID0gbmV3IE1ldGhvZFJlc29sdXRpb25Db250ZXh0KCk7CiAgICAgICAgYm91bmRTZWFyY2hSZXNvbHZlQ29udGV4dC5tZXRob2RDaGVjayA9IG1ldGhvZENoZWNrOwogICAgICAgIFN5bWJvbCBib3VuZFN5bSA9IGxvb2t1cE1ldGhvZChib3VuZEVudiwgZW52LnRyZWUucG9zKCksCiAgICAgICAgICAgICAgICBzaXRlLnRzeW0sIGJvdW5kU2VhcmNoUmVzb2x2ZUNvbnRleHQsIGJvdW5kTG9va3VwSGVscGVyKTsKICAgICAgICBSZWZlcmVuY2VMb29rdXBSZXN1bHQgYm91bmRSZXMgPSBuZXcgUmVmZXJlbmNlTG9va3VwUmVzdWx0KGJvdW5kU3ltLCBib3VuZFNlYXJjaFJlc29sdmVDb250ZXh0KTsKCiAgICAgICAgLy9zdGVwIDIgLSB1bmJvdW5kIGxvb2t1cAogICAgICAgIFN5bWJvbCB1bmJvdW5kU3ltID0gbWV0aG9kTm90Rm91bmQ7CiAgICAgICAgRW52PEF0dHJDb250ZXh0PiB1bmJvdW5kRW52ID0gZW52LmR1cChlbnYudHJlZSwgZW52LmluZm8uZHVwKCkpOwogICAgICAgIFJlZmVyZW5jZUxvb2t1cEhlbHBlciB1bmJvdW5kTG9va3VwSGVscGVyID0gYm91bmRMb29rdXBIZWxwZXIudW5ib3VuZExvb2t1cChpbmZlcmVuY2VDb250ZXh0KTsKICAgICAgICBSZWZlcmVuY2VMb29rdXBSZXN1bHQgdW5ib3VuZFJlcyA9IHJlZmVyZW5jZU5vdEZvdW5kOwogICAgICAgIGlmICh1bmJvdW5kTG9va3VwSGVscGVyICE9IG51bGwpIHsKICAgICAgICAgICAgTWV0aG9kUmVzb2x1dGlvbkNvbnRleHQgdW5ib3VuZFNlYXJjaFJlc29sdmVDb250ZXh0ID0KICAgICAgICAgICAgICAgICAgICBuZXcgTWV0aG9kUmVzb2x1dGlvbkNvbnRleHQoKTsKICAgICAgICAgICAgdW5ib3VuZFNlYXJjaFJlc29sdmVDb250ZXh0Lm1ldGhvZENoZWNrID0gbWV0aG9kQ2hlY2s7CiAgICAgICAgICAgIHVuYm91bmRTeW0gPSBsb29rdXBNZXRob2QodW5ib3VuZEVudiwgZW52LnRyZWUucG9zKCksCiAgICAgICAgICAgICAgICAgICAgc2l0ZS50c3ltLCB1bmJvdW5kU2VhcmNoUmVzb2x2ZUNvbnRleHQsIHVuYm91bmRMb29rdXBIZWxwZXIpOwogICAgICAgICAgICB1bmJvdW5kUmVzID0gbmV3IFJlZmVyZW5jZUxvb2t1cFJlc3VsdCh1bmJvdW5kU3ltLCB1bmJvdW5kU2VhcmNoUmVzb2x2ZUNvbnRleHQpOwogICAgICAgIH0KCiAgICAgICAgLy9tZXJnZSByZXN1bHRzCiAgICAgICAgUGFpcjxTeW1ib2wsIFJlZmVyZW5jZUxvb2t1cEhlbHBlcj4gcmVzOwogICAgICAgIFN5bWJvbCBiZXN0U3ltID0gcmVmZXJlbmNlQ2hvb3Nlci5yZXN1bHQoYm91bmRSZXMsIHVuYm91bmRSZXMpOwogICAgICAgIHJlcyA9IG5ldyBQYWlyPD4oYmVzdFN5bSwKICAgICAgICAgICAgICAgIGJlc3RTeW0gPT0gdW5ib3VuZFN5bSA/IHVuYm91bmRMb29rdXBIZWxwZXIgOiBib3VuZExvb2t1cEhlbHBlcik7CiAgICAgICAgZW52LmluZm8ucGVuZGluZ1Jlc29sdXRpb25QaGFzZSA9IGJlc3RTeW0gPT0gdW5ib3VuZFN5bSA/CiAgICAgICAgICAgICAgICB1bmJvdW5kRW52LmluZm8ucGVuZGluZ1Jlc29sdXRpb25QaGFzZSA6CiAgICAgICAgICAgICAgICBib3VuZEVudi5pbmZvLnBlbmRpbmdSZXNvbHV0aW9uUGhhc2U7CgogICAgICAgIHJldHVybiByZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBUaGlzIGNsYXNzIGlzIHVzZWQgdG8gcmVwcmVzZW50IGEgbWV0aG9kIHJlZmVyZW5jZSBsb29rdXAgcmVzdWx0LiBJdCBrZWVwcyB0cmFjayBvZiB0d28KICAgICAqIHRoaW5nczogKGkpIHRoZSBzeW1ib2wgZm91bmQgZHVyaW5nIGEgbWV0aG9kIHJlZmVyZW5jZSBsb29rdXAgYW5kIChpaSkgdGhlIHN0YXRpYyBraW5kCiAgICAgKiBvZiB0aGUgbG9va3VwIChzZWUge0BsaW5rIGNvbS5zdW4udG9vbHMuamF2YWMuY29tcC5SZXNvbHZlLlJlZmVyZW5jZUxvb2t1cFJlc3VsdC5TdGF0aWNLaW5kfSkuCiAgICAgKi8KICAgIHN0YXRpYyBjbGFzcyBSZWZlcmVuY2VMb29rdXBSZXN1bHQgewoKICAgICAgICAvKioKICAgICAgICAgKiBTdGF0aWMga2luZCBhc3NvY2lhdGVkIHdpdGggYSBtZXRob2QgcmVmZXJlbmNlIGxvb2t1cC4gRXJyb25lb3VzIGxvb2t1cHMgZW5kIHVwIHdpdGgKICAgICAgICAgKiB0aGUgVU5ERUZJTkVEIGtpbmQ7IHN1Y2Nlc3NmdWwgbG9va3VwcyB3aWxsIGVuZCB1cCB3aXRoIGVpdGhlciBTVEFUSUMsIE5PTl9TVEFUSUMsCiAgICAgICAgICogZGVwZW5kaW5nIG9uIHdoZXRoZXIgYWxsIGFwcGxpY2FibGUgY2FuZGlkYXRlcyBhcmUgc3RhdGljIG9yIG5vbi1zdGF0aWMgbWV0aG9kcywKICAgICAgICAgKiByZXNwZWN0aXZlbHkuIElmIGEgc3VjY2Vzc2Z1bCBsb29rdXAgaGFzIGJvdGggc3RhdGljIGFuZCBub24tc3RhdGljIGFwcGxpY2FibGUgbWV0aG9kcywKICAgICAgICAgKiBpdHMga2luZCBpcyBzZXQgdG8gQk9USC4KICAgICAgICAgKi8KICAgICAgICBlbnVtIFN0YXRpY0tpbmQgewogICAgICAgICAgICBTVEFUSUMsCiAgICAgICAgICAgIE5PTl9TVEFUSUMsCiAgICAgICAgICAgIEJPVEgsCiAgICAgICAgICAgIFVOREVGSU5FRDsKCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBSZXRyaWV2ZSB0aGUgc3RhdGljIGtpbmQgYXNzb2NpYXRlZCB3aXRoIGEgZ2l2ZW4gKG1ldGhvZCkgc3ltYm9sLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgc3RhdGljIFN0YXRpY0tpbmQgZnJvbShTeW1ib2wgcykgewogICAgICAgICAgICAgICAgcmV0dXJuIHMuaXNTdGF0aWMoKSA/CiAgICAgICAgICAgICAgICAgICAgICAgIFNUQVRJQyA6IE5PTl9TVEFUSUM7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBNZXJnZSB0d28gc3RhdGljIGtpbmRzIHRvZ2V0aGVyLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgc3RhdGljIFN0YXRpY0tpbmQgcmVkdWNlKFN0YXRpY0tpbmQgc2sxLCBTdGF0aWNLaW5kIHNrMikgewogICAgICAgICAgICAgICAgaWYgKHNrMSA9PSBVTkRFRklORUQpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gc2syOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChzazIgPT0gVU5ERUZJTkVEKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHNrMTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHNrMSA9PSBzazIgPyBzazEgOiBCT1RIOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvKiogVGhlIHN0YXRpYyBraW5kLiAqLwogICAgICAgIFN0YXRpY0tpbmQgc3RhdGljS2luZDsKCiAgICAgICAgLyoqIFRoZSBsb29rdXAgcmVzdWx0LiAqLwogICAgICAgIFN5bWJvbCBzeW07CgogICAgICAgIFJlZmVyZW5jZUxvb2t1cFJlc3VsdChTeW1ib2wgc3ltLCBNZXRob2RSZXNvbHV0aW9uQ29udGV4dCByZXNvbHV0aW9uQ29udGV4dCkgewogICAgICAgICAgICB0aGlzLnN0YXRpY0tpbmQgPSBzdGF0aWNLaW5kKHN5bSwgcmVzb2x1dGlvbkNvbnRleHQpOwogICAgICAgICAgICB0aGlzLnN5bSA9IHN5bTsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgU3RhdGljS2luZCBzdGF0aWNLaW5kKFN5bWJvbCBzeW0sIE1ldGhvZFJlc29sdXRpb25Db250ZXh0IHJlc29sdXRpb25Db250ZXh0KSB7CiAgICAgICAgICAgIHN3aXRjaCAoc3ltLmtpbmQpIHsKICAgICAgICAgICAgICAgIGNhc2UgTVRIOgogICAgICAgICAgICAgICAgY2FzZSBBTUJJR1VPVVM6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdXRpb25Db250ZXh0LmNhbmRpZGF0ZXMuc3RyZWFtKCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5maWx0ZXIoYyAtPiBjLmlzQXBwbGljYWJsZSgpICYmIGMuc3RlcCA9PSByZXNvbHV0aW9uQ29udGV4dC5zdGVwKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgLm1hcChjIC0+IFN0YXRpY0tpbmQuZnJvbShjLnN5bSkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAucmVkdWNlKFN0YXRpY0tpbmQ6OnJlZHVjZSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5vckVsc2UoU3RhdGljS2luZC5VTkRFRklORUQpOwogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gU3RhdGljS2luZC5VTkRFRklORUQ7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIERvZXMgdGhpcyByZXN1bHQgY29ycmVzcG9uZHMgdG8gYSBzdWNjZXNzZnVsIGxvb2t1cCAoaS5lLiBvbmUgd2hlcmUgYSBtZXRob2QgaGFzIGJlZW4gZm91bmQ/KQogICAgICAgICAqLwogICAgICAgIGJvb2xlYW4gaXNTdWNjZXNzKCkgewogICAgICAgICAgICByZXR1cm4gc3RhdGljS2luZCAhPSBTdGF0aWNLaW5kLlVOREVGSU5FRDsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIERvZXMgdGhpcyByZXN1bHQgaGF2ZSBnaXZlbiBzdGF0aWMga2luZD8KICAgICAgICAgKi8KICAgICAgICBib29sZWFuIGhhc0tpbmQoU3RhdGljS2luZCBzaykgewogICAgICAgICAgICByZXR1cm4gdGhpcy5zdGF0aWNLaW5kID09IHNrOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogRXJyb3IgcmVjb3ZlcnkgaGVscGVyOiBjYW4gdGhpcyBsb29rdXAgcmVzdWx0IGJlIGlnbm9yZWQgKGZvciB0aGUgcHVycG9zZSBvZiByZXR1cm5pbmcKICAgICAgICAgKiBzb21lICdiZXR0ZXInIHJlc3VsdCkgPwogICAgICAgICAqLwogICAgICAgIGJvb2xlYW4gY2FuSWdub3JlKCkgewogICAgICAgICAgICBzd2l0Y2ggKHN5bS5raW5kKSB7CiAgICAgICAgICAgICAgICBjYXNlIEFCU0VOVF9NVEg6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICBjYXNlIFdST05HX01USDoKICAgICAgICAgICAgICAgICAgICBJbmFwcGxpY2FibGVTeW1ib2xFcnJvciBlcnJTeW0gPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgKEluYXBwbGljYWJsZVN5bWJvbEVycm9yKXN5bS5iYXNlU3ltYm9sKCk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBUZW1wbGF0ZShNZXRob2RDaGVja0RpYWcuQVJJVFlfTUlTTUFUQ0gucmVnZXgoKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5tYXRjaGVzKGVyclN5bS5lcnJDYW5kaWRhdGUoKS5zbmQpOwogICAgICAgICAgICAgICAgY2FzZSBXUk9OR19NVEhTOgogICAgICAgICAgICAgICAgICAgIEluYXBwbGljYWJsZVN5bWJvbHNFcnJvciBlcnJTeW1zID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIChJbmFwcGxpY2FibGVTeW1ib2xzRXJyb3Ipc3ltLmJhc2VTeW1ib2woKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZXJyU3ltcy5maWx0ZXJDYW5kaWRhdGVzKGVyclN5bXMubWFwQ2FuZGlkYXRlcygpKS5pc0VtcHR5KCk7CiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFRoaXMgYWJzdHJhY3QgY2xhc3MgZW1ib2RpZXMgdGhlIGxvZ2ljIHRoYXQgY29udmVydHMgb25lIChib3VuZCBsb29rdXApIG9yIHR3byAodW5ib3VuZCBsb29rdXApCiAgICAgKiB7QGNvZGUgUmVmZXJlbmNlTG9va3VwUmVzdWx0fSBvYmplY3RzIGludG8gYSAoQGNvZGUgU3ltYm9sKSwgd2hpY2ggaXMgdGhlbiByZWdhcmRlZCBhcyB0aGUKICAgICAqIHJlc3VsdCBvZiBtZXRob2QgcmVmZXJlbmNlIHJlc29sdXRpb24uCiAgICAgKi8KICAgIGFic3RyYWN0IGNsYXNzIFJlZmVyZW5jZUNob29zZXIgewogICAgICAgIC8qKgogICAgICAgICAqIEdlbmVyYXRlIGEgcmVzdWx0IGZyb20gYSBwYWlyIG9mIGxvb2t1cCByZXN1bHQgb2JqZWN0cy4gVGhpcyBtZXRob2QgZGVsZWdhdGVzIHRvIHRoZQogICAgICAgICAqIGFwcHJvcHJpYXRlIHJlc3VsdCBnZW5lcmF0aW9uIHJvdXRpbmUuCiAgICAgICAgICovCiAgICAgICAgU3ltYm9sIHJlc3VsdChSZWZlcmVuY2VMb29rdXBSZXN1bHQgYm91bmRSZXMsIFJlZmVyZW5jZUxvb2t1cFJlc3VsdCB1bmJvdW5kUmVzKSB7CiAgICAgICAgICAgIHJldHVybiB1bmJvdW5kUmVzICE9IHJlZmVyZW5jZU5vdEZvdW5kID8KICAgICAgICAgICAgICAgICAgICB1bmJvdW5kUmVzdWx0KGJvdW5kUmVzLCB1bmJvdW5kUmVzKSA6CiAgICAgICAgICAgICAgICAgICAgYm91bmRSZXN1bHQoYm91bmRSZXMpOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogR2VuZXJhdGUgYSBzeW1ib2wgZnJvbSBhIGdpdmVuIGJvdW5kIGxvb2t1cCByZXN1bHQuCiAgICAgICAgICovCiAgICAgICAgYWJzdHJhY3QgU3ltYm9sIGJvdW5kUmVzdWx0KFJlZmVyZW5jZUxvb2t1cFJlc3VsdCBib3VuZFJlcyk7CgogICAgICAgIC8qKgogICAgICAgICAqIEdlbmVyYXRlIGEgc3ltYm9sIGZyb20gYSBwYWlyIG9mIGJvdW5kL3VuYm91bmQgbG9va3VwIHJlc3VsdHMuCiAgICAgICAgICovCiAgICAgICAgYWJzdHJhY3QgU3ltYm9sIHVuYm91bmRSZXN1bHQoUmVmZXJlbmNlTG9va3VwUmVzdWx0IGJvdW5kUmVzLCBSZWZlcmVuY2VMb29rdXBSZXN1bHQgdW5ib3VuZFJlcyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBUaGlzIGNob29zZXIgaW1wbGVtZW50cyB0aGUgc2VsZWN0aW9uIHN0cmF0ZWd5IHVzZWQgZHVyaW5nIGEgZnVsbCBsb29rdXA7IHRoaXMgbG9naWMKICAgICAqIGlzIGRlc2NyaWJlZCBpbiBKTFMgU0UgOCAoMTUuMy4yKS4KICAgICAqLwogICAgUmVmZXJlbmNlQ2hvb3NlciBiYXNpY1JlZmVyZW5jZUNob29zZXIgPSBuZXcgUmVmZXJlbmNlQ2hvb3NlcigpIHsKCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgU3ltYm9sIGJvdW5kUmVzdWx0KFJlZmVyZW5jZUxvb2t1cFJlc3VsdCBib3VuZFJlcykgewogICAgICAgICAgICByZXR1cm4gIWJvdW5kUmVzLmlzU3VjY2VzcygpIHx8IGJvdW5kUmVzLmhhc0tpbmQoU3RhdGljS2luZC5OT05fU1RBVElDKSA/CiAgICAgICAgICAgICAgICAgICAgYm91bmRSZXMuc3ltIDogLy90aGUgc2VhcmNoIHByb2R1Y2VzIGEgbm9uLXN0YXRpYyBtZXRob2QKICAgICAgICAgICAgICAgICAgICBuZXcgQmFkTWV0aG9kUmVmZXJlbmNlRXJyb3IoYm91bmRSZXMuc3ltLCBmYWxzZSk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBTeW1ib2wgdW5ib3VuZFJlc3VsdChSZWZlcmVuY2VMb29rdXBSZXN1bHQgYm91bmRSZXMsIFJlZmVyZW5jZUxvb2t1cFJlc3VsdCB1bmJvdW5kUmVzKSB7CiAgICAgICAgICAgIGlmIChib3VuZFJlcy5oYXNLaW5kKFN0YXRpY0tpbmQuU1RBVElDKSAmJgogICAgICAgICAgICAgICAgICAgICghdW5ib3VuZFJlcy5pc1N1Y2Nlc3MoKSB8fCB1bmJvdW5kUmVzLmhhc0tpbmQoU3RhdGljS2luZC5TVEFUSUMpKSkgewogICAgICAgICAgICAgICAgLy90aGUgZmlyc3Qgc2VhcmNoIHByb2R1Y2VzIGEgc3RhdGljIG1ldGhvZCBhbmQgbm8gbm9uLXN0YXRpYyBtZXRob2QgaXMgYXBwbGljYWJsZQogICAgICAgICAgICAgICAgLy9kdXJpbmcgdGhlIHNlY29uZCBzZWFyY2gKICAgICAgICAgICAgICAgIHJldHVybiBib3VuZFJlcy5zeW07CiAgICAgICAgICAgIH0gZWxzZSBpZiAodW5ib3VuZFJlcy5oYXNLaW5kKFN0YXRpY0tpbmQuTk9OX1NUQVRJQykgJiYKICAgICAgICAgICAgICAgICAgICAoIWJvdW5kUmVzLmlzU3VjY2VzcygpIHx8IGJvdW5kUmVzLmhhc0tpbmQoU3RhdGljS2luZC5OT05fU1RBVElDKSkpIHsKICAgICAgICAgICAgICAgIC8vdGhlIHNlY29uZCBzZWFyY2ggcHJvZHVjZXMgYSBub24tc3RhdGljIG1ldGhvZCBhbmQgbm8gc3RhdGljIG1ldGhvZCBpcyBhcHBsaWNhYmxlCiAgICAgICAgICAgICAgICAvL2R1cmluZyB0aGUgZmlyc3Qgc2VhcmNoCiAgICAgICAgICAgICAgICByZXR1cm4gdW5ib3VuZFJlcy5zeW07CiAgICAgICAgICAgIH0gZWxzZSBpZiAoYm91bmRSZXMuaXNTdWNjZXNzKCkgJiYgdW5ib3VuZFJlcy5pc1N1Y2Nlc3MoKSkgewogICAgICAgICAgICAgICAgLy9ib3RoIHNlYXJjaGVzIHByb2R1Y2Ugc29tZSByZXN1bHQ7IGFtYmlndWl0eSAoZXJyb3IgcmVjb3ZlcnkpCiAgICAgICAgICAgICAgICByZXR1cm4gYW1iaWd1aXR5RXJyb3IoYm91bmRSZXMuc3ltLCB1bmJvdW5kUmVzLnN5bSk7CiAgICAgICAgICAgIH0gZWxzZSBpZiAoYm91bmRSZXMuaXNTdWNjZXNzKCkgfHwgdW5ib3VuZFJlcy5pc1N1Y2Nlc3MoKSkgewogICAgICAgICAgICAgICAgLy9Cb3RoIHNlYXJjaGVzIGZhaWxlZCB0byBwcm9kdWNlIGEgcmVzdWx0IHdpdGggY29ycmVjdCBzdGF0aWNuZXNzIChpLmUuIGZpcnN0IHNlYXJjaAogICAgICAgICAgICAgICAgLy9wcm9kdWNlcyBhbiBub24tc3RhdGljIG1ldGhvZCkuIEFsdGVybmF0aXZlbHksIGEgZ2l2ZW4gc2VhcmNoIHByb2R1Y2VkIGEgcmVzdWx0CiAgICAgICAgICAgICAgICAvL3dpdGggdGhlIHJpZ2h0IHN0YXRpY25lc3MsIGJ1dCB0aGUgb3RoZXIgc2VhcmNoIGhhcyBhcHBsaWNhYmxlIG1ldGhvZHMgd2l0aCB3cm9uZwogICAgICAgICAgICAgICAgLy9zdGF0aWNuZXNzIChlcnJvciByZWNvdmVyeSkKICAgICAgICAgICAgICAgIHJldHVybiBuZXcgQmFkTWV0aG9kUmVmZXJlbmNlRXJyb3IoYm91bmRSZXMuaXNTdWNjZXNzKCkgPyBib3VuZFJlcy5zeW0gOiB1bmJvdW5kUmVzLnN5bSwgdHJ1ZSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvL2JvdGggc2VhcmNoZXMgZmFpbCB0byBwcm9kdWNlIGEgcmVzdWx0IC0gcGljayAnYmV0dGVyJyBlcnJvciB1c2luZyBoZXVyaXN0aWNzIChlcnJvciByZWNvdmVyeSkKICAgICAgICAgICAgICAgIHJldHVybiAoYm91bmRSZXMuY2FuSWdub3JlKCkgJiYgIXVuYm91bmRSZXMuY2FuSWdub3JlKCkpID8KICAgICAgICAgICAgICAgICAgICAgICAgdW5ib3VuZFJlcy5zeW0gOiBib3VuZFJlcy5zeW07CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9OwoKICAgIC8qKgogICAgICogVGhpcyBjaG9vc2VyIGltcGxlbWVudHMgdGhlIHNlbGVjdGlvbiBzdHJhdGVneSB1c2VkIGR1cmluZyBhbiBhcml0eS1iYXNlZCBsb29rdXA7IHRoaXMgbG9naWMKICAgICAqIGlzIGRlc2NyaWJlZCBpbiBKTFMgU0UgOCAoMTUuMTIuMi4xKS4KICAgICAqLwogICAgUmVmZXJlbmNlQ2hvb3NlciBzdHJ1Y3R1cmFsUmVmZXJlbmNlQ2hvb3NlciA9IG5ldyBSZWZlcmVuY2VDaG9vc2VyKCkgewoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBTeW1ib2wgYm91bmRSZXN1bHQoUmVmZXJlbmNlTG9va3VwUmVzdWx0IGJvdW5kUmVzKSB7CiAgICAgICAgICAgIHJldHVybiAoIWJvdW5kUmVzLmlzU3VjY2VzcygpIHx8ICFib3VuZFJlcy5oYXNLaW5kKFN0YXRpY0tpbmQuU1RBVElDKSkgPwogICAgICAgICAgICAgICAgICAgIGJvdW5kUmVzLnN5bSA6IC8vdGhlIHNlYXJjaCBoYXMgYXQgbGVhc3Qgb25lIGFwcGxpY2FibGUgbm9uLXN0YXRpYyBtZXRob2QKICAgICAgICAgICAgICAgICAgICBuZXcgQmFkTWV0aG9kUmVmZXJlbmNlRXJyb3IoYm91bmRSZXMuc3ltLCBmYWxzZSk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBTeW1ib2wgdW5ib3VuZFJlc3VsdChSZWZlcmVuY2VMb29rdXBSZXN1bHQgYm91bmRSZXMsIFJlZmVyZW5jZUxvb2t1cFJlc3VsdCB1bmJvdW5kUmVzKSB7CiAgICAgICAgICAgIGlmIChib3VuZFJlcy5pc1N1Y2Nlc3MoKSAmJiAhYm91bmRSZXMuaGFzS2luZChTdGF0aWNLaW5kLk5PTl9TVEFUSUMpKSB7CiAgICAgICAgICAgICAgICAvL3RoZSBmaXJzdCBzZXJhY2ggaGFzIGF0IGxlYXN0IG9uZSBhcHBsaWNhYmxlIHN0YXRpYyBtZXRob2QKICAgICAgICAgICAgICAgIHJldHVybiBib3VuZFJlcy5zeW07CiAgICAgICAgICAgIH0gZWxzZSBpZiAodW5ib3VuZFJlcy5pc1N1Y2Nlc3MoKSAmJiAhdW5ib3VuZFJlcy5oYXNLaW5kKFN0YXRpY0tpbmQuU1RBVElDKSkgewogICAgICAgICAgICAgICAgLy90aGUgc2Vjb25kIHNlYXJjaCBoYXMgYXQgbGVhc3Qgb25lIGFwcGxpY2FibGUgbm9uLXN0YXRpYyBtZXRob2QKICAgICAgICAgICAgICAgIHJldHVybiB1bmJvdW5kUmVzLnN5bTsKICAgICAgICAgICAgfSBlbHNlIGlmIChib3VuZFJlcy5pc1N1Y2Nlc3MoKSB8fCB1bmJvdW5kUmVzLmlzU3VjY2VzcygpKSB7CiAgICAgICAgICAgICAgICAvL2VpdGhlciB0aGUgZmlyc3Qgc2VhcmNoIHByb2R1Y2VzIGEgbm9uLXN0YXRpYyBtZXRob2QsIG9yIHNlY29uZCBzZWFyY2ggcHJvZHVjZXMKICAgICAgICAgICAgICAgIC8vYSBub24tc3RhdGljIG1ldGhvZCAoZXJyb3IgcmVjb3ZlcnkpCiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEJhZE1ldGhvZFJlZmVyZW5jZUVycm9yKGJvdW5kUmVzLmlzU3VjY2VzcygpID8gYm91bmRSZXMuc3ltIDogdW5ib3VuZFJlcy5zeW0sIHRydWUpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgLy9ib3RoIHNlYXJjaGVzIGZhaWwgdG8gcHJvZHVjZSBhIHJlc3VsdCAtIHBpY2sgJ2JldHRlcicgZXJyb3IgdXNpbmcgaGV1cmlzdGljcyAoZXJyb3IgcmVjb3ZlcnkpCiAgICAgICAgICAgICAgICByZXR1cm4gKGJvdW5kUmVzLmNhbklnbm9yZSgpICYmICF1bmJvdW5kUmVzLmNhbklnbm9yZSgpKSA/CiAgICAgICAgICAgICAgICAgICAgICAgIHVuYm91bmRSZXMuc3ltIDogYm91bmRSZXMuc3ltOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfTsKCiAgICAvKioKICAgICAqIEhlbHBlciBmb3IgZGVmaW5pbmcgY3VzdG9tIG1ldGhvZC1saWtlIGxvb2t1cCBsb2dpYzsgYSBsb29rdXAgaGVscGVyCiAgICAgKiBwcm92aWRlcyBob29rcyBmb3IgKGkpIHRoZSBhY3R1YWwgbG9va3VwIGxvZ2ljIGFuZCAoaWkpIGFjY2Vzc2luZyB0aGUKICAgICAqIGxvb2t1cCByZXN1bHQgKHRoaXMgc3RlcCBtaWdodCByZXN1bHQgaW4gY29tcGlsZXIgZGlhZ25vc3RpY3MgdG8gYmUgZ2VuZXJhdGVkKQogICAgICovCiAgICBhYnN0cmFjdCBjbGFzcyBMb29rdXBIZWxwZXIgewoKICAgICAgICAvKiogbmFtZSBvZiB0aGUgc3ltYm9sIHRvIGxvb2t1cCAqLwogICAgICAgIE5hbWUgbmFtZTsKCiAgICAgICAgLyoqIGxvY2F0aW9uIGluIHdoaWNoIHRoZSBsb29rdXAgdGFrZXMgcGxhY2UgKi8KICAgICAgICBUeXBlIHNpdGU7CgogICAgICAgIC8qKiBhY3R1YWwgdHlwZXMgdXNlZCBkdXJpbmcgdGhlIGxvb2t1cCAqLwogICAgICAgIExpc3Q8VHlwZT4gYXJndHlwZXM7CgogICAgICAgIC8qKiB0eXBlIGFyZ3VtZW50cyB1c2VkIGR1cmluZyB0aGUgbG9va3VwICovCiAgICAgICAgTGlzdDxUeXBlPiB0eXBlYXJndHlwZXM7CgogICAgICAgIC8qKiBNYXggb3ZlcmxvYWQgcmVzb2x1dGlvbiBwaGFzZSBoYW5kbGVkIGJ5IHRoaXMgaGVscGVyICovCiAgICAgICAgTWV0aG9kUmVzb2x1dGlvblBoYXNlIG1heFBoYXNlOwoKICAgICAgICBMb29rdXBIZWxwZXIoTmFtZSBuYW1lLCBUeXBlIHNpdGUsIExpc3Q8VHlwZT4gYXJndHlwZXMsIExpc3Q8VHlwZT4gdHlwZWFyZ3R5cGVzLCBNZXRob2RSZXNvbHV0aW9uUGhhc2UgbWF4UGhhc2UpIHsKICAgICAgICAgICAgdGhpcy5uYW1lID0gbmFtZTsKICAgICAgICAgICAgdGhpcy5zaXRlID0gc2l0ZTsKICAgICAgICAgICAgdGhpcy5hcmd0eXBlcyA9IGFyZ3R5cGVzOwogICAgICAgICAgICB0aGlzLnR5cGVhcmd0eXBlcyA9IHR5cGVhcmd0eXBlczsKICAgICAgICAgICAgdGhpcy5tYXhQaGFzZSA9IG1heFBoYXNlOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogU2hvdWxkIGxvb2t1cCBzdG9wIGF0IGdpdmVuIHBoYXNlIHdpdGggZ2l2ZW4gcmVzdWx0CiAgICAgICAgICovCiAgICAgICAgZmluYWwgYm9vbGVhbiBzaG91bGRTdG9wKFN5bWJvbCBzeW0sIE1ldGhvZFJlc29sdXRpb25QaGFzZSBwaGFzZSkgewogICAgICAgICAgICByZXR1cm4gcGhhc2Uub3JkaW5hbCgpID4gbWF4UGhhc2Uub3JkaW5hbCgpIHx8CiAgICAgICAgICAgICAgICAhc3ltLmtpbmQuaXNSZXNvbHV0aW9uRXJyb3IoKSB8fCBzeW0ua2luZCA9PSBBTUJJR1VPVVM7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBTZWFyY2ggZm9yIGEgc3ltYm9sIHVuZGVyIGEgZ2l2ZW4gb3ZlcmxvYWQgcmVzb2x1dGlvbiBwaGFzZSAtIHRoaXMgbWV0aG9kCiAgICAgICAgICogaXMgdXN1YWxseSBjYWxsZWQgc2V2ZXJhbCB0aW1lcywgb25jZSBwZXIgZWFjaCBvdmVybG9hZCByZXNvbHV0aW9uIHBoYXNlCiAgICAgICAgICovCiAgICAgICAgYWJzdHJhY3QgU3ltYm9sIGxvb2t1cChFbnY8QXR0ckNvbnRleHQ+IGVudiwgTWV0aG9kUmVzb2x1dGlvblBoYXNlIHBoYXNlKTsKCiAgICAgICAgLyoqCiAgICAgICAgICogRHVtcCBvdmVybG9hZCByZXNvbHV0aW9uIGluZm8KICAgICAgICAgKi8KICAgICAgICB2b2lkIGRlYnVnKERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIFN5bWJvbCBzeW0pIHsKICAgICAgICAgICAgLy9kbyBub3RoaW5nCiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBWYWxpZGF0ZSB0aGUgcmVzdWx0IG9mIHRoZSBsb29rdXAKICAgICAgICAgKi8KICAgICAgICBhYnN0cmFjdCBTeW1ib2wgYWNjZXNzKEVudjxBdHRyQ29udGV4dD4gZW52LCBEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBTeW1ib2wgbG9jYXRpb24sIFN5bWJvbCBzeW0pOwogICAgfQoKICAgIGFic3RyYWN0IGNsYXNzIEJhc2ljTG9va3VwSGVscGVyIGV4dGVuZHMgTG9va3VwSGVscGVyIHsKCiAgICAgICAgQmFzaWNMb29rdXBIZWxwZXIoTmFtZSBuYW1lLCBUeXBlIHNpdGUsIExpc3Q8VHlwZT4gYXJndHlwZXMsIExpc3Q8VHlwZT4gdHlwZWFyZ3R5cGVzKSB7CiAgICAgICAgICAgIHRoaXMobmFtZSwgc2l0ZSwgYXJndHlwZXMsIHR5cGVhcmd0eXBlcywgTWV0aG9kUmVzb2x1dGlvblBoYXNlLlZBUkFSSVRZKTsKICAgICAgICB9CgogICAgICAgIEJhc2ljTG9va3VwSGVscGVyKE5hbWUgbmFtZSwgVHlwZSBzaXRlLCBMaXN0PFR5cGU+IGFyZ3R5cGVzLCBMaXN0PFR5cGU+IHR5cGVhcmd0eXBlcywgTWV0aG9kUmVzb2x1dGlvblBoYXNlIG1heFBoYXNlKSB7CiAgICAgICAgICAgIHN1cGVyKG5hbWUsIHNpdGUsIGFyZ3R5cGVzLCB0eXBlYXJndHlwZXMsIG1heFBoYXNlKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIGZpbmFsIFN5bWJvbCBsb29rdXAoRW52PEF0dHJDb250ZXh0PiBlbnYsIE1ldGhvZFJlc29sdXRpb25QaGFzZSBwaGFzZSkgewogICAgICAgICAgICBTeW1ib2wgc3ltID0gZG9Mb29rdXAoZW52LCBwaGFzZSk7CiAgICAgICAgICAgIGlmIChzeW0ua2luZCA9PSBBTUJJR1VPVVMpIHsKICAgICAgICAgICAgICAgIEFtYmlndWl0eUVycm9yIGFfZXJyID0gKEFtYmlndWl0eUVycm9yKXN5bS5iYXNlU3ltYm9sKCk7CiAgICAgICAgICAgICAgICBzeW0gPSBhX2Vyci5tZXJnZUFic3RyYWN0cyhzaXRlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gc3ltOwogICAgICAgIH0KCiAgICAgICAgYWJzdHJhY3QgU3ltYm9sIGRvTG9va3VwKEVudjxBdHRyQ29udGV4dD4gZW52LCBNZXRob2RSZXNvbHV0aW9uUGhhc2UgcGhhc2UpOwoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBTeW1ib2wgYWNjZXNzKEVudjxBdHRyQ29udGV4dD4gZW52LCBEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBTeW1ib2wgbG9jYXRpb24sIFN5bWJvbCBzeW0pIHsKICAgICAgICAgICAgaWYgKHN5bS5raW5kLmlzUmVzb2x1dGlvbkVycm9yKCkpIHsKICAgICAgICAgICAgICAgIC8vaWYgbm90aGluZyBpcyBmb3VuZCByZXR1cm4gdGhlICdmaXJzdCcgZXJyb3IKICAgICAgICAgICAgICAgIHN5bSA9IGFjY2Vzc01ldGhvZChzeW0sIHBvcywgbG9jYXRpb24sIHNpdGUsIG5hbWUsIHRydWUsIGFyZ3R5cGVzLCB0eXBlYXJndHlwZXMpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBzeW07CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICB2b2lkIGRlYnVnKERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIFN5bWJvbCBzeW0pIHsKICAgICAgICAgICAgcmVwb3J0VmVyYm9zZVJlc29sdXRpb25EaWFnbm9zdGljKHBvcywgbmFtZSwgc2l0ZSwgYXJndHlwZXMsIHR5cGVhcmd0eXBlcywgc3ltKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBIZWxwZXIgY2xhc3MgZm9yIG1lbWJlciByZWZlcmVuY2UgbG9va3VwLiBBIHJlZmVyZW5jZSBsb29rdXAgaGVscGVyCiAgICAgKiBkZWZpbmVzIHRoZSBiYXNpYyBsb2dpYyBmb3IgbWVtYmVyIHJlZmVyZW5jZSBsb29rdXA7IGEgbWV0aG9kIGdpdmVzCiAgICAgKiBhY2Nlc3MgdG8gYW4gJ3VuYm91bmQnIGhlbHBlciB1c2VkIHRvIHBlcmZvcm0gYW4gdW5ib3VuZCBtZW1iZXIKICAgICAqIHJlZmVyZW5jZSBsb29rdXAuCiAgICAgKi8KICAgIGFic3RyYWN0IGNsYXNzIFJlZmVyZW5jZUxvb2t1cEhlbHBlciBleHRlbmRzIExvb2t1cEhlbHBlciB7CgogICAgICAgIC8qKiBUaGUgbWVtYmVyIHJlZmVyZW5jZSB0cmVlICovCiAgICAgICAgSkNNZW1iZXJSZWZlcmVuY2UgcmVmZXJlbmNlVHJlZTsKCiAgICAgICAgUmVmZXJlbmNlTG9va3VwSGVscGVyKEpDTWVtYmVyUmVmZXJlbmNlIHJlZmVyZW5jZVRyZWUsIE5hbWUgbmFtZSwgVHlwZSBzaXRlLAogICAgICAgICAgICAgICAgTGlzdDxUeXBlPiBhcmd0eXBlcywgTGlzdDxUeXBlPiB0eXBlYXJndHlwZXMsIE1ldGhvZFJlc29sdXRpb25QaGFzZSBtYXhQaGFzZSkgewogICAgICAgICAgICBzdXBlcihuYW1lLCBzaXRlLCBhcmd0eXBlcywgdHlwZWFyZ3R5cGVzLCBtYXhQaGFzZSk7CiAgICAgICAgICAgIHRoaXMucmVmZXJlbmNlVHJlZSA9IHJlZmVyZW5jZVRyZWU7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBSZXR1cm5zIGFuIHVuYm91bmQgdmVyc2lvbiBvZiB0aGlzIGxvb2t1cCBoZWxwZXIuIEJ5IGRlZmF1bHQsIHRoaXMKICAgICAgICAgKiBtZXRob2QgcmV0dXJucyBhbiBkdW1teSBsb29rdXAgaGVscGVyLgogICAgICAgICAqLwogICAgICAgIFJlZmVyZW5jZUxvb2t1cEhlbHBlciB1bmJvdW5kTG9va3VwKEluZmVyZW5jZUNvbnRleHQgaW5mZXJlbmNlQ29udGV4dCkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIEdldCB0aGUga2luZCBvZiB0aGUgbWVtYmVyIHJlZmVyZW5jZQogICAgICAgICAqLwogICAgICAgIGFic3RyYWN0IEpDTWVtYmVyUmVmZXJlbmNlLlJlZmVyZW5jZUtpbmQgcmVmZXJlbmNlS2luZChTeW1ib2wgc3ltKTsKCiAgICAgICAgU3ltYm9sIGFjY2VzcyhFbnY8QXR0ckNvbnRleHQ+IGVudiwgRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcywgU3ltYm9sIGxvY2F0aW9uLCBTeW1ib2wgc3ltKSB7CiAgICAgICAgICAgIGlmIChzeW0ua2luZCA9PSBBTUJJR1VPVVMpIHsKICAgICAgICAgICAgICAgIEFtYmlndWl0eUVycm9yIGFfZXJyID0gKEFtYmlndWl0eUVycm9yKXN5bS5iYXNlU3ltYm9sKCk7CiAgICAgICAgICAgICAgICBzeW0gPSBhX2Vyci5tZXJnZUFic3RyYWN0cyhzaXRlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvL3NraXAgZXJyb3IgcmVwb3J0aW5nCiAgICAgICAgICAgIHJldHVybiBzeW07CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogSGVscGVyIGNsYXNzIGZvciBtZXRob2QgcmVmZXJlbmNlIGxvb2t1cC4gVGhlIGxvb2t1cCBsb2dpYyBpcyBiYXNlZAogICAgICogdXBvbiBSZXNvbHZlLmZpbmRNZXRob2Q7IGluIGNlcnRhaW4gY2FzZXMsIHRoaXMgaGVscGVyIGNsYXNzIGhhcyBhCiAgICAgKiBjb3JyZXNwb25kaW5nIHVuYm91bmQgaGVscGVyIGNsYXNzIChzZWUgVW5ib3VuZE1ldGhvZFJlZmVyZW5jZUxvb2t1cEhlbHBlcikuCiAgICAgKiBJbiBzdWNoIGNhc2VzLCBub24tc3RhdGljIGxvb2t1cCByZXN1bHRzIGFyZSB0aHJvd24gYXdheS4KICAgICAqLwogICAgY2xhc3MgTWV0aG9kUmVmZXJlbmNlTG9va3VwSGVscGVyIGV4dGVuZHMgUmVmZXJlbmNlTG9va3VwSGVscGVyIHsKCiAgICAgICAgLyoqIFRoZSBvcmlnaW5hbCBtZXRob2QgcmVmZXJlbmNlIGxvb2t1cCBzaXRlLiAqLwogICAgICAgIFR5cGUgb3JpZ2luYWxTaXRlOwoKICAgICAgICBNZXRob2RSZWZlcmVuY2VMb29rdXBIZWxwZXIoSkNNZW1iZXJSZWZlcmVuY2UgcmVmZXJlbmNlVHJlZSwgTmFtZSBuYW1lLCBUeXBlIHNpdGUsCiAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IGFyZ3R5cGVzLCBMaXN0PFR5cGU+IHR5cGVhcmd0eXBlcywgTWV0aG9kUmVzb2x1dGlvblBoYXNlIG1heFBoYXNlKSB7CiAgICAgICAgICAgIHN1cGVyKHJlZmVyZW5jZVRyZWUsIG5hbWUsIHR5cGVzLnNraXBUeXBlVmFycyhzaXRlLCB0cnVlKSwgYXJndHlwZXMsIHR5cGVhcmd0eXBlcywgbWF4UGhhc2UpOwogICAgICAgICAgICB0aGlzLm9yaWdpbmFsU2l0ZSA9IHNpdGU7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBmaW5hbCBTeW1ib2wgbG9va3VwKEVudjxBdHRyQ29udGV4dD4gZW52LCBNZXRob2RSZXNvbHV0aW9uUGhhc2UgcGhhc2UpIHsKICAgICAgICAgICAgcmV0dXJuIGZpbmRNZXRob2QoZW52LCBzaXRlLCBuYW1lLCBhcmd0eXBlcywgdHlwZWFyZ3R5cGVzLAogICAgICAgICAgICAgICAgICAgIHBoYXNlLmlzQm94aW5nUmVxdWlyZWQoKSwgcGhhc2UuaXNWYXJhcmdzUmVxdWlyZWQoKSk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBSZWZlcmVuY2VMb29rdXBIZWxwZXIgdW5ib3VuZExvb2t1cChJbmZlcmVuY2VDb250ZXh0IGluZmVyZW5jZUNvbnRleHQpIHsKICAgICAgICAgICAgaWYgKFRyZWVJbmZvLmlzU3RhdGljU2VsZWN0b3IocmVmZXJlbmNlVHJlZS5leHByLCBuYW1lcykpIHsKICAgICAgICAgICAgICAgIGlmIChhcmd0eXBlcy5ub25FbXB0eSgpICYmCiAgICAgICAgICAgICAgICAgICAgICAgIChhcmd0eXBlcy5oZWFkLmhhc1RhZyhOT05FKSB8fAogICAgICAgICAgICAgICAgICAgICAgICB0eXBlcy5pc1N1YnR5cGVVbmNoZWNrZWQoaW5mZXJlbmNlQ29udGV4dC5hc1VuZGV0VmFyKGFyZ3R5cGVzLmhlYWQpLCBvcmlnaW5hbFNpdGUpKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgVW5ib3VuZE1ldGhvZFJlZmVyZW5jZUxvb2t1cEhlbHBlcihyZWZlcmVuY2VUcmVlLCBuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JpZ2luYWxTaXRlLCBhcmd0eXBlcywgdHlwZWFyZ3R5cGVzLCBtYXhQaGFzZSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgUmVmZXJlbmNlTG9va3VwSGVscGVyKHJlZmVyZW5jZVRyZWUsIG5hbWUsIHNpdGUsIGFyZ3R5cGVzLCB0eXBlYXJndHlwZXMsIG1heFBoYXNlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICAgICAgICAgICAgICBSZWZlcmVuY2VMb29rdXBIZWxwZXIgdW5ib3VuZExvb2t1cChJbmZlcmVuY2VDb250ZXh0IGluZmVyZW5jZUNvbnRleHQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgICAgICAgICAgICAgU3ltYm9sIGxvb2t1cChFbnY8QXR0ckNvbnRleHQ+IGVudiwgTWV0aG9kUmVzb2x1dGlvblBoYXNlIHBoYXNlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbWV0aG9kTm90Rm91bmQ7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICAgICAgICAgICAgICBSZWZlcmVuY2VLaW5kIHJlZmVyZW5jZUtpbmQoU3ltYm9sIHN5bSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgQXNzZXJ0LmVycm9yKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICByZXR1cm4gc3VwZXIudW5ib3VuZExvb2t1cChpbmZlcmVuY2VDb250ZXh0KTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgUmVmZXJlbmNlS2luZCByZWZlcmVuY2VLaW5kKFN5bWJvbCBzeW0pIHsKICAgICAgICAgICAgaWYgKHN5bS5pc1N0YXRpYygpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gUmVmZXJlbmNlS2luZC5TVEFUSUM7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBOYW1lIHNlbE5hbWUgPSBUcmVlSW5mby5uYW1lKHJlZmVyZW5jZVRyZWUuZ2V0UXVhbGlmaWVyRXhwcmVzc2lvbigpKTsKICAgICAgICAgICAgICAgIHJldHVybiBzZWxOYW1lICE9IG51bGwgJiYgc2VsTmFtZSA9PSBuYW1lcy5fc3VwZXIgPwogICAgICAgICAgICAgICAgICAgICAgICBSZWZlcmVuY2VLaW5kLlNVUEVSIDoKICAgICAgICAgICAgICAgICAgICAgICAgUmVmZXJlbmNlS2luZC5CT1VORDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEhlbHBlciBjbGFzcyBmb3IgdW5ib3VuZCBtZXRob2QgcmVmZXJlbmNlIGxvb2t1cC4gRXNzZW50aWFsbHkgdGhlIHNhbWUKICAgICAqIGFzIHRoZSBiYXNpYyBtZXRob2QgcmVmZXJlbmNlIGxvb2t1cCBoZWxwZXI7IG1haW4gZGlmZmVyZW5jZSBpcyB0aGF0IHN0YXRpYwogICAgICogbG9va3VwIHJlc3VsdHMgYXJlIHRocm93biBhd2F5LiBJZiBxdWFsaWZpZXIgdHlwZSBpcyByYXcsIGFuIGF0dGVtcHQgdG8KICAgICAqIGluZmVyIGEgcGFyYW1ldGVyaXplZCB0eXBlIGlzIG1hZGUgdXNpbmcgdGhlIGZpcnN0IGFjdHVhbCBhcmd1bWVudCAodGhhdAogICAgICogd291bGQgb3RoZXJ3aXNlIGJlIGlnbm9yZWQgZHVyaW5nIHRoZSBsb29rdXApLgogICAgICovCiAgICBjbGFzcyBVbmJvdW5kTWV0aG9kUmVmZXJlbmNlTG9va3VwSGVscGVyIGV4dGVuZHMgTWV0aG9kUmVmZXJlbmNlTG9va3VwSGVscGVyIHsKCiAgICAgICAgVW5ib3VuZE1ldGhvZFJlZmVyZW5jZUxvb2t1cEhlbHBlcihKQ01lbWJlclJlZmVyZW5jZSByZWZlcmVuY2VUcmVlLCBOYW1lIG5hbWUsIFR5cGUgc2l0ZSwKICAgICAgICAgICAgICAgIExpc3Q8VHlwZT4gYXJndHlwZXMsIExpc3Q8VHlwZT4gdHlwZWFyZ3R5cGVzLCBNZXRob2RSZXNvbHV0aW9uUGhhc2UgbWF4UGhhc2UpIHsKICAgICAgICAgICAgc3VwZXIocmVmZXJlbmNlVHJlZSwgbmFtZSwgc2l0ZSwgYXJndHlwZXMudGFpbCwgdHlwZWFyZ3R5cGVzLCBtYXhQaGFzZSk7CiAgICAgICAgICAgIGlmIChzaXRlLmlzUmF3KCkgJiYgIWFyZ3R5cGVzLmhlYWQuaGFzVGFnKE5PTkUpKSB7CiAgICAgICAgICAgICAgICBUeXBlIGFzU3VwZXJTaXRlID0gdHlwZXMuYXNTdXBlcihhcmd0eXBlcy5oZWFkLCBzaXRlLnRzeW0pOwogICAgICAgICAgICAgICAgdGhpcy5zaXRlID0gdHlwZXMuc2tpcFR5cGVWYXJzKGFzU3VwZXJTaXRlLCB0cnVlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgUmVmZXJlbmNlTG9va3VwSGVscGVyIHVuYm91bmRMb29rdXAoSW5mZXJlbmNlQ29udGV4dCBpbmZlcmVuY2VDb250ZXh0KSB7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgUmVmZXJlbmNlS2luZCByZWZlcmVuY2VLaW5kKFN5bWJvbCBzeW0pIHsKICAgICAgICAgICAgcmV0dXJuIFJlZmVyZW5jZUtpbmQuVU5CT1VORDsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBIZWxwZXIgY2xhc3MgZm9yIGFycmF5IGNvbnN0cnVjdG9yIGxvb2t1cDsgYW4gYXJyYXkgY29uc3RydWN0b3IgbG9va3VwCiAgICAgKiBpcyBzaW11bGF0ZWQgYnkgbG9va2luZyB1cCBhIG1ldGhvZCB0aGF0IHJldHVybnMgdGhlIGFycmF5IHR5cGUgc3BlY2lmaWVkCiAgICAgKiBhcyBxdWFsaWZpZXIsIGFuZCB0aGF0IGFjY2VwdHMgYSBzaW5nbGUgaW50IHBhcmFtZXRlciAoc2l6ZSBvZiB0aGUgYXJyYXkpLgogICAgICovCiAgICBjbGFzcyBBcnJheUNvbnN0cnVjdG9yUmVmZXJlbmNlTG9va3VwSGVscGVyIGV4dGVuZHMgUmVmZXJlbmNlTG9va3VwSGVscGVyIHsKCiAgICAgICAgQXJyYXlDb25zdHJ1Y3RvclJlZmVyZW5jZUxvb2t1cEhlbHBlcihKQ01lbWJlclJlZmVyZW5jZSByZWZlcmVuY2VUcmVlLCBUeXBlIHNpdGUsIExpc3Q8VHlwZT4gYXJndHlwZXMsCiAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IHR5cGVhcmd0eXBlcywgTWV0aG9kUmVzb2x1dGlvblBoYXNlIG1heFBoYXNlKSB7CiAgICAgICAgICAgIHN1cGVyKHJlZmVyZW5jZVRyZWUsIG5hbWVzLmluaXQsIHNpdGUsIGFyZ3R5cGVzLCB0eXBlYXJndHlwZXMsIG1heFBoYXNlKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHByb3RlY3RlZCBTeW1ib2wgbG9va3VwKEVudjxBdHRyQ29udGV4dD4gZW52LCBNZXRob2RSZXNvbHV0aW9uUGhhc2UgcGhhc2UpIHsKICAgICAgICAgICAgV3JpdGVhYmxlU2NvcGUgc2MgPSBXcml0ZWFibGVTY29wZS5jcmVhdGUoc3ltcy5hcnJheUNsYXNzKTsKICAgICAgICAgICAgTWV0aG9kU3ltYm9sIGFycmF5Q29uc3RyID0gbmV3IE1ldGhvZFN5bWJvbChQVUJMSUMsIG5hbWUsIG51bGwsIHNpdGUudHN5bSk7CiAgICAgICAgICAgIGFycmF5Q29uc3RyLnR5cGUgPSBuZXcgTWV0aG9kVHlwZShMaXN0Lm9mKHN5bXMuaW50VHlwZSksIHNpdGUsIExpc3QubmlsKCksIHN5bXMubWV0aG9kQ2xhc3MpOwogICAgICAgICAgICBzYy5lbnRlcihhcnJheUNvbnN0cik7CiAgICAgICAgICAgIHJldHVybiBmaW5kTWV0aG9kSW5TY29wZShlbnYsIHNpdGUsIG5hbWUsIGFyZ3R5cGVzLCB0eXBlYXJndHlwZXMsIHNjLCBtZXRob2ROb3RGb3VuZCwgcGhhc2UuaXNCb3hpbmdSZXF1aXJlZCgpLCBwaGFzZS5pc1ZhcmFyZ3NSZXF1aXJlZCgpLCBmYWxzZSk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBSZWZlcmVuY2VLaW5kIHJlZmVyZW5jZUtpbmQoU3ltYm9sIHN5bSkgewogICAgICAgICAgICByZXR1cm4gUmVmZXJlbmNlS2luZC5BUlJBWV9DVE9SOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEhlbHBlciBjbGFzcyBmb3IgY29uc3RydWN0b3IgcmVmZXJlbmNlIGxvb2t1cC4gVGhlIGxvb2t1cCBsb2dpYyBpcyBiYXNlZAogICAgICogdXBvbiBlaXRoZXIgUmVzb2x2ZS5maW5kTWV0aG9kIG9yIFJlc29sdmUuZmluZERpYW1vbmQgLSBkZXBlbmRpbmcgb24KICAgICAqIHdoZXRoZXIgdGhlIGNvbnN0cnVjdG9yIHJlZmVyZW5jZSBuZWVkcyBkaWFtb25kIGluZmVyZW5jZSAodGhpcyBpcyB0aGUgY2FzZQogICAgICogaWYgdGhlIHF1YWxpZmllciB0eXBlIGlzIHJhdykuIEEgc3BlY2lhbCBlcnJvbmVvdXMgc3ltYm9sIGlzIHJldHVybmVkCiAgICAgKiBpZiB0aGUgbG9va3VwIHJldHVybnMgdGhlIGNvbnN0cnVjdG9yIG9mIGFuIGlubmVyIGNsYXNzIGFuZCB0aGVyZSdzIG5vCiAgICAgKiBlbmNsb3NpbmcgaW5zdGFuY2UgaW4gc2NvcGUuCiAgICAgKi8KICAgIGNsYXNzIENvbnN0cnVjdG9yUmVmZXJlbmNlTG9va3VwSGVscGVyIGV4dGVuZHMgUmVmZXJlbmNlTG9va3VwSGVscGVyIHsKCiAgICAgICAgYm9vbGVhbiBuZWVkc0luZmVyZW5jZTsKCiAgICAgICAgQ29uc3RydWN0b3JSZWZlcmVuY2VMb29rdXBIZWxwZXIoSkNNZW1iZXJSZWZlcmVuY2UgcmVmZXJlbmNlVHJlZSwgVHlwZSBzaXRlLCBMaXN0PFR5cGU+IGFyZ3R5cGVzLAogICAgICAgICAgICAgICAgTGlzdDxUeXBlPiB0eXBlYXJndHlwZXMsIE1ldGhvZFJlc29sdXRpb25QaGFzZSBtYXhQaGFzZSkgewogICAgICAgICAgICBzdXBlcihyZWZlcmVuY2VUcmVlLCBuYW1lcy5pbml0LCBzaXRlLCBhcmd0eXBlcywgdHlwZWFyZ3R5cGVzLCBtYXhQaGFzZSk7CiAgICAgICAgICAgIGlmIChzaXRlLmlzUmF3KCkpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2l0ZSA9IG5ldyBDbGFzc1R5cGUoc2l0ZS5nZXRFbmNsb3NpbmdUeXBlKCksIHNpdGUudHN5bS50eXBlLmdldFR5cGVBcmd1bWVudHMoKSwgc2l0ZS50c3ltLCBzaXRlLmdldE1ldGFkYXRhKCkpOwogICAgICAgICAgICAgICAgbmVlZHNJbmZlcmVuY2UgPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwcm90ZWN0ZWQgU3ltYm9sIGxvb2t1cChFbnY8QXR0ckNvbnRleHQ+IGVudiwgTWV0aG9kUmVzb2x1dGlvblBoYXNlIHBoYXNlKSB7CiAgICAgICAgICAgIFN5bWJvbCBzeW0gPSBuZWVkc0luZmVyZW5jZSA/CiAgICAgICAgICAgICAgICBmaW5kRGlhbW9uZChlbnYsIHNpdGUsIGFyZ3R5cGVzLCB0eXBlYXJndHlwZXMsIHBoYXNlLmlzQm94aW5nUmVxdWlyZWQoKSwgcGhhc2UuaXNWYXJhcmdzUmVxdWlyZWQoKSkgOgogICAgICAgICAgICAgICAgZmluZE1ldGhvZChlbnYsIHNpdGUsIG5hbWUsIGFyZ3R5cGVzLCB0eXBlYXJndHlwZXMsCiAgICAgICAgICAgICAgICAgICAgICAgIHBoYXNlLmlzQm94aW5nUmVxdWlyZWQoKSwgcGhhc2UuaXNWYXJhcmdzUmVxdWlyZWQoKSk7CiAgICAgICAgICAgIHJldHVybiBlbmNsb3NpbmdJbnN0YW5jZU1pc3NpbmcoZW52LCBzaXRlKSA/IG5ldyBCYWRDb25zdHJ1Y3RvclJlZmVyZW5jZUVycm9yKHN5bSkgOiBzeW07CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBSZWZlcmVuY2VLaW5kIHJlZmVyZW5jZUtpbmQoU3ltYm9sIHN5bSkgewogICAgICAgICAgICByZXR1cm4gc2l0ZS5nZXRFbmNsb3NpbmdUeXBlKCkuaGFzVGFnKE5PTkUpID8KICAgICAgICAgICAgICAgICAgICBSZWZlcmVuY2VLaW5kLlRPUExFVkVMIDogUmVmZXJlbmNlS2luZC5JTVBMSUNJVF9JTk5FUjsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBNYWluIG92ZXJsb2FkIHJlc29sdXRpb24gcm91dGluZS4gT24gZWFjaCBvdmVybG9hZCByZXNvbHV0aW9uIHN0ZXAsIGEKICAgICAqIGxvb2t1cCBoZWxwZXIgY2xhc3MgaXMgdXNlZCB0byBwZXJmb3JtIHRoZSBtZXRob2QvY29uc3RydWN0b3IgbG9va3VwOwogICAgICogYXQgdGhlIGVuZCBvZiB0aGUgbG9va3VwLCB0aGUgaGVscGVyIGlzIHVzZWQgdG8gdmFsaWRhdGUgdGhlIHJlc3VsdHMKICAgICAqICh0aGlzIGxhc3Qgc3RlcCBtaWdodCB0cmlnZ2VyIG92ZXJsb2FkIHJlc29sdXRpb24gZGlhZ25vc3RpY3MpLgogICAgICovCiAgICBTeW1ib2wgbG9va3VwTWV0aG9kKEVudjxBdHRyQ29udGV4dD4gZW52LCBEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBTeW1ib2wgbG9jYXRpb24sIE1ldGhvZENoZWNrIG1ldGhvZENoZWNrLCBMb29rdXBIZWxwZXIgbG9va3VwSGVscGVyKSB7CiAgICAgICAgTWV0aG9kUmVzb2x1dGlvbkNvbnRleHQgcmVzb2x2ZUNvbnRleHQgPSBuZXcgTWV0aG9kUmVzb2x1dGlvbkNvbnRleHQoKTsKICAgICAgICByZXNvbHZlQ29udGV4dC5tZXRob2RDaGVjayA9IG1ldGhvZENoZWNrOwogICAgICAgIHJldHVybiBsb29rdXBNZXRob2QoZW52LCBwb3MsIGxvY2F0aW9uLCByZXNvbHZlQ29udGV4dCwgbG9va3VwSGVscGVyKTsKICAgIH0KCiAgICBTeW1ib2wgbG9va3VwTWV0aG9kKEVudjxBdHRyQ29udGV4dD4gZW52LCBEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBTeW1ib2wgbG9jYXRpb24sCiAgICAgICAgICAgIE1ldGhvZFJlc29sdXRpb25Db250ZXh0IHJlc29sdmVDb250ZXh0LCBMb29rdXBIZWxwZXIgbG9va3VwSGVscGVyKSB7CiAgICAgICAgTWV0aG9kUmVzb2x1dGlvbkNvbnRleHQgcHJldlJlc29sdXRpb25Db250ZXh0ID0gY3VycmVudFJlc29sdXRpb25Db250ZXh0OwogICAgICAgIHRyeSB7CiAgICAgICAgICAgIFN5bWJvbCBiZXN0U29GYXIgPSBtZXRob2ROb3RGb3VuZDsKICAgICAgICAgICAgY3VycmVudFJlc29sdXRpb25Db250ZXh0ID0gcmVzb2x2ZUNvbnRleHQ7CiAgICAgICAgICAgIGZvciAoTWV0aG9kUmVzb2x1dGlvblBoYXNlIHBoYXNlIDogbWV0aG9kUmVzb2x1dGlvblN0ZXBzKSB7CiAgICAgICAgICAgICAgICBpZiAobG9va3VwSGVscGVyLnNob3VsZFN0b3AoYmVzdFNvRmFyLCBwaGFzZSkpCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBNZXRob2RSZXNvbHV0aW9uUGhhc2UgcHJldlBoYXNlID0gY3VycmVudFJlc29sdXRpb25Db250ZXh0LnN0ZXA7CiAgICAgICAgICAgICAgICBTeW1ib2wgcHJldkJlc3QgPSBiZXN0U29GYXI7CiAgICAgICAgICAgICAgICBjdXJyZW50UmVzb2x1dGlvbkNvbnRleHQuc3RlcCA9IHBoYXNlOwogICAgICAgICAgICAgICAgU3ltYm9sIHN5bSA9IGxvb2t1cEhlbHBlci5sb29rdXAoZW52LCBwaGFzZSk7CiAgICAgICAgICAgICAgICBsb29rdXBIZWxwZXIuZGVidWcocG9zLCBzeW0pOwogICAgICAgICAgICAgICAgYmVzdFNvRmFyID0gcGhhc2UubWVyZ2VSZXN1bHRzKGJlc3RTb0Zhciwgc3ltKTsKICAgICAgICAgICAgICAgIGVudi5pbmZvLnBlbmRpbmdSZXNvbHV0aW9uUGhhc2UgPSAocHJldkJlc3QgPT0gYmVzdFNvRmFyKSA/IHByZXZQaGFzZSA6IHBoYXNlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBsb29rdXBIZWxwZXIuYWNjZXNzKGVudiwgcG9zLCBsb2NhdGlvbiwgYmVzdFNvRmFyKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICBjdXJyZW50UmVzb2x1dGlvbkNvbnRleHQgPSBwcmV2UmVzb2x1dGlvbkNvbnRleHQ7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogUmVzb2x2ZSBgYy5uYW1lJyB3aGVyZSBuYW1lID09IHRoaXMgb3IgbmFtZSA9PSBzdXBlci4KICAgICAqIEBwYXJhbSBwb3MgICAgICAgICAgIFRoZSBwb3NpdGlvbiB0byB1c2UgZm9yIGVycm9yIHJlcG9ydGluZy4KICAgICAqIEBwYXJhbSBlbnYgICAgICAgICAgIFRoZSBlbnZpcm9ubWVudCBjdXJyZW50IGF0IHRoZSBleHByZXNzaW9uLgogICAgICogQHBhcmFtIGMgICAgICAgICAgICAgVGhlIHF1YWxpZmllci4KICAgICAqIEBwYXJhbSBuYW1lICAgICAgICAgIFRoZSBpZGVudGlmaWVyJ3MgbmFtZS4KICAgICAqLwogICAgU3ltYm9sIHJlc29sdmVTZWxmKERpYWdub3N0aWNQb3NpdGlvbiBwb3MsCiAgICAgICAgICAgICAgICAgICAgICAgRW52PEF0dHJDb250ZXh0PiBlbnYsCiAgICAgICAgICAgICAgICAgICAgICAgVHlwZVN5bWJvbCBjLAogICAgICAgICAgICAgICAgICAgICAgIE5hbWUgbmFtZSkgewogICAgICAgIEVudjxBdHRyQ29udGV4dD4gZW52MSA9IGVudjsKICAgICAgICBib29sZWFuIHN0YXRpY09ubHkgPSBmYWxzZTsKICAgICAgICB3aGlsZSAoZW52MS5vdXRlciAhPSBudWxsKSB7CiAgICAgICAgICAgIGlmIChpc1N0YXRpYyhlbnYxKSkgc3RhdGljT25seSA9IHRydWU7CiAgICAgICAgICAgIGlmIChlbnYxLmVuY2xDbGFzcy5zeW0gPT0gYykgewogICAgICAgICAgICAgICAgU3ltYm9sIHN5bSA9IGVudjEuaW5mby5zY29wZS5maW5kRmlyc3QobmFtZSk7CiAgICAgICAgICAgICAgICBpZiAoc3ltICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdGljT25seSkgc3ltID0gbmV3IFN0YXRpY0Vycm9yKHN5bSk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGFjY2Vzc0Jhc2Uoc3ltLCBwb3MsIGVudi5lbmNsQ2xhc3Muc3ltLnR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lLCB0cnVlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoKGVudjEuZW5jbENsYXNzLnN5bS5mbGFncygpICYgU1RBVElDKSAhPSAwKSBzdGF0aWNPbmx5ID0gdHJ1ZTsKICAgICAgICAgICAgZW52MSA9IGVudjEub3V0ZXI7CiAgICAgICAgfQogICAgICAgIGlmIChjLmlzSW50ZXJmYWNlKCkgJiYKICAgICAgICAgICAgbmFtZSA9PSBuYW1lcy5fc3VwZXIgJiYgIWlzU3RhdGljKGVudikgJiYKICAgICAgICAgICAgdHlwZXMuaXNEaXJlY3RTdXBlckludGVyZmFjZShjLCBlbnYuZW5jbENsYXNzLnN5bSkpIHsKICAgICAgICAgICAgLy90aGlzIG1pZ2h0IGJlIGEgZGVmYXVsdCBzdXBlciBjYWxsIGlmIG9uZSBvZiB0aGUgc3VwZXJpbnRlcmZhY2VzIGlzICdjJwogICAgICAgICAgICBmb3IgKFR5cGUgdCA6IHBydW5lSW50ZXJmYWNlcyhlbnYuZW5jbENsYXNzLnR5cGUpKSB7CiAgICAgICAgICAgICAgICBpZiAodC50c3ltID09IGMpIHsKICAgICAgICAgICAgICAgICAgICBlbnYuaW5mby5kZWZhdWx0U3VwZXJDYWxsU2l0ZSA9IHQ7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBWYXJTeW1ib2woMCwgbmFtZXMuX3N1cGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZXMuYXNTdXBlcihlbnYuZW5jbENsYXNzLnR5cGUsIGMpLCBlbnYuZW5jbENsYXNzLnN5bSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy9maW5kIGEgZGlyZWN0IHN1cGVyIHR5cGUgdGhhdCBpcyBhIHN1YnR5cGUgb2YgJ2MnCiAgICAgICAgICAgIGZvciAoVHlwZSBpIDogdHlwZXMuZGlyZWN0U3VwZXJ0eXBlcyhlbnYuZW5jbENsYXNzLnR5cGUpKSB7CiAgICAgICAgICAgICAgICBpZiAoaS50c3ltLmlzU3ViQ2xhc3MoYywgdHlwZXMpICYmIGkudHN5bSAhPSBjKSB7CiAgICAgICAgICAgICAgICAgICAgbG9nLmVycm9yKHBvcywgImlsbGVnYWwuZGVmYXVsdC5zdXBlci5jYWxsIiwgYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpYWdzLmZyYWdtZW50KCJyZWR1bmRhbnQuc3VwZXJ0eXBlIiwgYywgaSkpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBzeW1zLmVyclN5bWJvbDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBBc3NlcnQuZXJyb3IoKTsKICAgICAgICB9CiAgICAgICAgbG9nLmVycm9yKHBvcywgIm5vdC5lbmNsLmNsYXNzIiwgYyk7CiAgICAgICAgcmV0dXJuIHN5bXMuZXJyU3ltYm9sOwogICAgfQogICAgLy93aGVyZQogICAgcHJpdmF0ZSBMaXN0PFR5cGU+IHBydW5lSW50ZXJmYWNlcyhUeXBlIHQpIHsKICAgICAgICBMaXN0QnVmZmVyPFR5cGU+IHJlc3VsdCA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICBmb3IgKFR5cGUgdDEgOiB0eXBlcy5pbnRlcmZhY2VzKHQpKSB7CiAgICAgICAgICAgIGJvb2xlYW4gc2hvdWxkQWRkID0gdHJ1ZTsKICAgICAgICAgICAgZm9yIChUeXBlIHQyIDogdHlwZXMuZGlyZWN0U3VwZXJ0eXBlcyh0KSkgewogICAgICAgICAgICAgICAgaWYgKHQxICE9IHQyICYmIHR5cGVzLmlzU3VidHlwZU5vQ2FwdHVyZSh0MiwgdDEpKSB7CiAgICAgICAgICAgICAgICAgICAgc2hvdWxkQWRkID0gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHNob3VsZEFkZCkgewogICAgICAgICAgICAgICAgcmVzdWx0LmFwcGVuZCh0MSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdC50b0xpc3QoKTsKICAgIH0KCgogICAgLyoqCiAgICAgKiBSZXNvbHZlIGBjLnRoaXMnIGZvciBhbiBlbmNsb3NpbmcgY2xhc3MgYyB0aGF0IGNvbnRhaW5zIHRoZQogICAgICogbmFtZWQgbWVtYmVyLgogICAgICogQHBhcmFtIHBvcyAgICAgICAgICAgVGhlIHBvc2l0aW9uIHRvIHVzZSBmb3IgZXJyb3IgcmVwb3J0aW5nLgogICAgICogQHBhcmFtIGVudiAgICAgICAgICAgVGhlIGVudmlyb25tZW50IGN1cnJlbnQgYXQgdGhlIGV4cHJlc3Npb24uCiAgICAgKiBAcGFyYW0gbWVtYmVyICAgICAgICBUaGUgbWVtYmVyIHRoYXQgbXVzdCBiZSBjb250YWluZWQgaW4gdGhlIHJlc3VsdC4KICAgICAqLwogICAgU3ltYm9sIHJlc29sdmVTZWxmQ29udGFpbmluZyhEaWFnbm9zdGljUG9zaXRpb24gcG9zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFbnY8QXR0ckNvbnRleHQ+IGVudiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3ltYm9sIG1lbWJlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBpc1N1cGVyQ2FsbCkgewogICAgICAgIFN5bWJvbCBzeW0gPSByZXNvbHZlU2VsZkNvbnRhaW5pbmdJbnRlcm5hbChlbnYsIG1lbWJlciwgaXNTdXBlckNhbGwpOwogICAgICAgIGlmIChzeW0gPT0gbnVsbCkgewogICAgICAgICAgICBsb2cuZXJyb3IocG9zLCAiZW5jbC5jbGFzcy5yZXF1aXJlZCIsIG1lbWJlcik7CiAgICAgICAgICAgIHJldHVybiBzeW1zLmVyclN5bWJvbDsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gYWNjZXNzQmFzZShzeW0sIHBvcywgZW52LmVuY2xDbGFzcy5zeW0udHlwZSwgc3ltLm5hbWUsIHRydWUpOwogICAgICAgIH0KICAgIH0KCiAgICBib29sZWFuIGVuY2xvc2luZ0luc3RhbmNlTWlzc2luZyhFbnY8QXR0ckNvbnRleHQ+IGVudiwgVHlwZSB0eXBlKSB7CiAgICAgICAgaWYgKHR5cGUuaGFzVGFnKENMQVNTKSAmJiB0eXBlLmdldEVuY2xvc2luZ1R5cGUoKS5oYXNUYWcoQ0xBU1MpKSB7CiAgICAgICAgICAgIFN5bWJvbCBlbmNsID0gcmVzb2x2ZVNlbGZDb250YWluaW5nSW50ZXJuYWwoZW52LCB0eXBlLnRzeW0sIGZhbHNlKTsKICAgICAgICAgICAgcmV0dXJuIGVuY2wgPT0gbnVsbCB8fCBlbmNsLmtpbmQuaXNSZXNvbHV0aW9uRXJyb3IoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIHByaXZhdGUgU3ltYm9sIHJlc29sdmVTZWxmQ29udGFpbmluZ0ludGVybmFsKEVudjxBdHRyQ29udGV4dD4gZW52LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTeW1ib2wgbWVtYmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGlzU3VwZXJDYWxsKSB7CiAgICAgICAgTmFtZSBuYW1lID0gbmFtZXMuX3RoaXM7CiAgICAgICAgRW52PEF0dHJDb250ZXh0PiBlbnYxID0gaXNTdXBlckNhbGwgPyBlbnYub3V0ZXIgOiBlbnY7CiAgICAgICAgYm9vbGVhbiBzdGF0aWNPbmx5ID0gZmFsc2U7CiAgICAgICAgaWYgKGVudjEgIT0gbnVsbCkgewogICAgICAgICAgICB3aGlsZSAoZW52MSAhPSBudWxsICYmIGVudjEub3V0ZXIgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgaWYgKGlzU3RhdGljKGVudjEpKSBzdGF0aWNPbmx5ID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGlmIChlbnYxLmVuY2xDbGFzcy5zeW0uaXNTdWJDbGFzcyhtZW1iZXIub3duZXIuZW5jbENsYXNzKCksIHR5cGVzKSkgewogICAgICAgICAgICAgICAgICAgIFN5bWJvbCBzeW0gPSBlbnYxLmluZm8uc2NvcGUuZmluZEZpcnN0KG5hbWUpOwogICAgICAgICAgICAgICAgICAgIGlmIChzeW0gIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdGljT25seSkgc3ltID0gbmV3IFN0YXRpY0Vycm9yKHN5bSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzeW07CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKChlbnYxLmVuY2xDbGFzcy5zeW0uZmxhZ3MoKSAmIFNUQVRJQykgIT0gMCkKICAgICAgICAgICAgICAgICAgICBzdGF0aWNPbmx5ID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGVudjEgPSBlbnYxLm91dGVyOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIC8qKgogICAgICogUmVzb2x2ZSBhbiBhcHByb3ByaWF0ZSBpbXBsaWNpdCB0aGlzIGluc3RhbmNlIGZvciB0J3MgY29udGFpbmVyLgogICAgICogSkxTIDguOC41LjEgYW5kIDE1LjkuMgogICAgICovCiAgICBUeXBlIHJlc29sdmVJbXBsaWNpdFRoaXMoRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcywgRW52PEF0dHJDb250ZXh0PiBlbnYsIFR5cGUgdCkgewogICAgICAgIHJldHVybiByZXNvbHZlSW1wbGljaXRUaGlzKHBvcywgZW52LCB0LCBmYWxzZSk7CiAgICB9CgogICAgVHlwZSByZXNvbHZlSW1wbGljaXRUaGlzKERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIEVudjxBdHRyQ29udGV4dD4gZW52LCBUeXBlIHQsIGJvb2xlYW4gaXNTdXBlckNhbGwpIHsKICAgICAgICBUeXBlIHRoaXNUeXBlID0gKHQudHN5bS5vd25lci5raW5kLm1hdGNoZXMoS2luZFNlbGVjdG9yLlZBTF9NVEgpCiAgICAgICAgICAgICAgICAgICAgICAgICA/IHJlc29sdmVTZWxmKHBvcywgZW52LCB0LmdldEVuY2xvc2luZ1R5cGUoKS50c3ltLCBuYW1lcy5fdGhpcykKICAgICAgICAgICAgICAgICAgICAgICAgIDogcmVzb2x2ZVNlbGZDb250YWluaW5nKHBvcywgZW52LCB0LnRzeW0sIGlzU3VwZXJDYWxsKSkudHlwZTsKICAgICAgICBpZiAoZW52LmluZm8uaXNTZWxmQ2FsbCAmJiB0aGlzVHlwZS50c3ltID09IGVudi5lbmNsQ2xhc3Muc3ltKQogICAgICAgICAgICBsb2cuZXJyb3IocG9zLCAiY2FudC5yZWYuYmVmb3JlLmN0b3IuY2FsbGVkIiwgInRoaXMiKTsKICAgICAgICByZXR1cm4gdGhpc1R5cGU7CiAgICB9CgovKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogIFJlc29sdmVFcnJvciBjbGFzc2VzLCBpbmRpY2F0aW5nIGVycm9yIHNpdHVhdGlvbnMgd2hlbiBhY2Nlc3Npbmcgc3ltYm9scwogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiAgICAvL3VzZWQgYnkgVHJhbnNUeXBlcyB3aGVuIGNoZWNraW5nIHRhcmdldCB0eXBlIG9mIHN5bnRoZXRpYyBjYXN0CiAgICBwdWJsaWMgdm9pZCBsb2dBY2Nlc3NFcnJvckludGVybmFsKEVudjxBdHRyQ29udGV4dD4gZW52LCBKQ1RyZWUgdHJlZSwgVHlwZSB0eXBlKSB7CiAgICAgICAgQWNjZXNzRXJyb3IgZXJyb3IgPSBuZXcgQWNjZXNzRXJyb3IoZW52LCBlbnYuZW5jbENsYXNzLnR5cGUsIHR5cGUudHN5bSk7CiAgICAgICAgbG9nUmVzb2x2ZUVycm9yKGVycm9yLCB0cmVlLnBvcygpLCBlbnYuZW5jbENsYXNzLnN5bSwgZW52LmVuY2xDbGFzcy50eXBlLCBudWxsLCBudWxsLCBudWxsKTsKICAgIH0KICAgIC8vd2hlcmUKICAgIHByaXZhdGUgdm9pZCBsb2dSZXNvbHZlRXJyb3IoUmVzb2x2ZUVycm9yIGVycm9yLAogICAgICAgICAgICBEaWFnbm9zdGljUG9zaXRpb24gcG9zLAogICAgICAgICAgICBTeW1ib2wgbG9jYXRpb24sCiAgICAgICAgICAgIFR5cGUgc2l0ZSwKICAgICAgICAgICAgTmFtZSBuYW1lLAogICAgICAgICAgICBMaXN0PFR5cGU+IGFyZ3R5cGVzLAogICAgICAgICAgICBMaXN0PFR5cGU+IHR5cGVhcmd0eXBlcykgewogICAgICAgIEpDRGlhZ25vc3RpYyBkID0gZXJyb3IuZ2V0RGlhZ25vc3RpYyhKQ0RpYWdub3N0aWMuRGlhZ25vc3RpY1R5cGUuRVJST1IsCiAgICAgICAgICAgICAgICBwb3MsIGxvY2F0aW9uLCBzaXRlLCBuYW1lLCBhcmd0eXBlcywgdHlwZWFyZ3R5cGVzKTsKICAgICAgICBpZiAoZCAhPSBudWxsKSB7CiAgICAgICAgICAgIGQuc2V0RmxhZyhEaWFnbm9zdGljRmxhZy5SRVNPTFZFX0VSUk9SKTsKICAgICAgICAgICAgbG9nLnJlcG9ydChkKTsKICAgICAgICB9CiAgICB9CgogICAgcHJpdmF0ZSBmaW5hbCBMb2NhbGl6ZWRTdHJpbmcgbm9BcmdzID0gbmV3IExvY2FsaXplZFN0cmluZygiY29tcGlsZXIubWlzYy5uby5hcmdzIik7CgogICAgcHVibGljIE9iamVjdCBtZXRob2RBcmd1bWVudHMoTGlzdDxUeXBlPiBhcmd0eXBlcykgewogICAgICAgIGlmIChhcmd0eXBlcyA9PSBudWxsIHx8IGFyZ3R5cGVzLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXR1cm4gbm9BcmdzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIExpc3RCdWZmZXI8T2JqZWN0PiBkaWFnQXJncyA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICAgICAgZm9yIChUeXBlIHQgOiBhcmd0eXBlcykgewogICAgICAgICAgICAgICAgaWYgKHQuaGFzVGFnKERFRkVSUkVEKSkgewogICAgICAgICAgICAgICAgICAgIGRpYWdBcmdzLmFwcGVuZCgoKERlZmVycmVkQXR0ci5EZWZlcnJlZFR5cGUpdCkudHJlZSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGRpYWdBcmdzLmFwcGVuZCh0KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gZGlhZ0FyZ3M7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogUm9vdCBjbGFzcyBmb3IgcmVzb2x1dGlvbiBlcnJvcnMuIFN1YmNsYXNzIG9mIFJlc29sdmVFcnJvcgogICAgICogcmVwcmVzZW50IGEgZGlmZmVyZW50IGtpbmRzIG9mIHJlc29sdXRpb24gZXJyb3IgLSBhcyBzdWNoIHRoZXkgbXVzdAogICAgICogc3BlY2lmeSBob3cgdGhleSBtYXAgaW50byBjb25jcmV0ZSBjb21waWxlciBkaWFnbm9zdGljcy4KICAgICAqLwogICAgYWJzdHJhY3QgY2xhc3MgUmVzb2x2ZUVycm9yIGV4dGVuZHMgU3ltYm9sIHsKCiAgICAgICAgLyoqIFRoZSBuYW1lIG9mIHRoZSBraW5kIG9mIGVycm9yLCBmb3IgZGVidWdnaW5nIG9ubHkuICovCiAgICAgICAgZmluYWwgU3RyaW5nIGRlYnVnTmFtZTsKCiAgICAgICAgUmVzb2x2ZUVycm9yKEtpbmQga2luZCwgU3RyaW5nIGRlYnVnTmFtZSkgewogICAgICAgICAgICBzdXBlcihraW5kLCAwLCBudWxsLCBudWxsLCBudWxsKTsKICAgICAgICAgICAgdGhpcy5kZWJ1Z05hbWUgPSBkZWJ1Z05hbWU7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICAgICAgcHVibGljIDxSLCBQPiBSIGFjY2VwdChFbGVtZW50VmlzaXRvcjxSLCBQPiB2LCBQIHApIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewogICAgICAgICAgICByZXR1cm4gZGVidWdOYW1lOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gZXhpc3RzKCkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc1N0YXRpYygpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogQ3JlYXRlIGFuIGV4dGVybmFsIHJlcHJlc2VudGF0aW9uIGZvciB0aGlzIGVycm9uZW91cyBzeW1ib2wgdG8gYmUKICAgICAgICAgKiB1c2VkIGR1cmluZyBhdHRyaWJ1dGlvbiAtIGJ5IGRlZmF1bHQgdGhpcyByZXR1cm5zIHRoZSBzeW1ib2wgb2YgYQogICAgICAgICAqIGJyYW5kIG5ldyBlcnJvciB0eXBlIHdoaWNoIHN0b3JlcyB0aGUgb3JpZ2luYWwgdHlwZSBmb3VuZAogICAgICAgICAqIGR1cmluZyByZXNvbHV0aW9uLgogICAgICAgICAqCiAgICAgICAgICogQHBhcmFtIG5hbWUgICAgIHRoZSBuYW1lIHVzZWQgZHVyaW5nIHJlc29sdXRpb24KICAgICAgICAgKiBAcGFyYW0gbG9jYXRpb24gdGhlIGxvY2F0aW9uIGZyb20gd2hpY2ggdGhlIHN5bWJvbCBpcyBhY2Nlc3NlZAogICAgICAgICAqLwogICAgICAgIHByb3RlY3RlZCBTeW1ib2wgYWNjZXNzKE5hbWUgbmFtZSwgVHlwZVN5bWJvbCBsb2NhdGlvbikgewogICAgICAgICAgICByZXR1cm4gdHlwZXMuY3JlYXRlRXJyb3JUeXBlKG5hbWUsIGxvY2F0aW9uLCBzeW1zLmVyclN5bWJvbC50eXBlKS50c3ltOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogQ3JlYXRlIGEgZGlhZ25vc3RpYyByZXByZXNlbnRpbmcgdGhpcyByZXNvbHV0aW9uIGVycm9yLgogICAgICAgICAqCiAgICAgICAgICogQHBhcmFtIGRraW5kICAgICBUaGUga2luZCBvZiB0aGUgZGlhZ25vc3RpYyB0byBiZSBjcmVhdGVkIChlLmcgZXJyb3IpLgogICAgICAgICAqIEBwYXJhbSBwb3MgICAgICAgVGhlIHBvc2l0aW9uIHRvIGJlIHVzZWQgZm9yIGVycm9yIHJlcG9ydGluZy4KICAgICAgICAgKiBAcGFyYW0gc2l0ZSAgICAgIFRoZSBvcmlnaW5hbCB0eXBlIGZyb20gd2hlcmUgdGhlIHNlbGVjdGlvbiB0b29rIHBsYWNlLgogICAgICAgICAqIEBwYXJhbSBuYW1lICAgICAgVGhlIG5hbWUgb2YgdGhlIHN5bWJvbCB0byBiZSByZXNvbHZlZC4KICAgICAgICAgKiBAcGFyYW0gYXJndHlwZXMgIFRoZSBpbnZvY2F0aW9uJ3MgdmFsdWUgYXJndW1lbnRzLAogICAgICAgICAqICAgICAgICAgICAgICAgICAgaWYgd2UgbG9va2VkIGZvciBhIG1ldGhvZC4KICAgICAgICAgKiBAcGFyYW0gdHlwZWFyZ3R5cGVzICBUaGUgaW52b2NhdGlvbidzIHR5cGUgYXJndW1lbnRzLAogICAgICAgICAqICAgICAgICAgICAgICAgICAgICAgIGlmIHdlIGxvb2tlZCBmb3IgYSBtZXRob2QuCiAgICAgICAgICovCiAgICAgICAgYWJzdHJhY3QgSkNEaWFnbm9zdGljIGdldERpYWdub3N0aWMoSkNEaWFnbm9zdGljLkRpYWdub3N0aWNUeXBlIGRraW5kLAogICAgICAgICAgICAgICAgRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcywKICAgICAgICAgICAgICAgIFN5bWJvbCBsb2NhdGlvbiwKICAgICAgICAgICAgICAgIFR5cGUgc2l0ZSwKICAgICAgICAgICAgICAgIE5hbWUgbmFtZSwKICAgICAgICAgICAgICAgIExpc3Q8VHlwZT4gYXJndHlwZXMsCiAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IHR5cGVhcmd0eXBlcyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBUaGlzIGNsYXNzIGlzIHRoZSByb290IGNsYXNzIG9mIGFsbCByZXNvbHV0aW9uIGVycm9ycyBjYXVzZWQgYnkKICAgICAqIGFuIGludmFsaWQgc3ltYm9sIGJlaW5nIGZvdW5kIGR1cmluZyByZXNvbHV0aW9uLgogICAgICovCiAgICBhYnN0cmFjdCBjbGFzcyBJbnZhbGlkU3ltYm9sRXJyb3IgZXh0ZW5kcyBSZXNvbHZlRXJyb3IgewoKICAgICAgICAvKiogVGhlIGludmFsaWQgc3ltYm9sIGZvdW5kIGR1cmluZyByZXNvbHV0aW9uICovCiAgICAgICAgU3ltYm9sIHN5bTsKCiAgICAgICAgSW52YWxpZFN5bWJvbEVycm9yKEtpbmQga2luZCwgU3ltYm9sIHN5bSwgU3RyaW5nIGRlYnVnTmFtZSkgewogICAgICAgICAgICBzdXBlcihraW5kLCBkZWJ1Z05hbWUpOwogICAgICAgICAgICB0aGlzLnN5bSA9IHN5bTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBib29sZWFuIGV4aXN0cygpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewogICAgICAgICAgICAgcmV0dXJuIHN1cGVyLnRvU3RyaW5nKCkgKyAiIHdyb25nU3ltPSIgKyBzeW07CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgU3ltYm9sIGFjY2VzcyhOYW1lIG5hbWUsIFR5cGVTeW1ib2wgbG9jYXRpb24pIHsKICAgICAgICAgICAgaWYgKCFzeW0ua2luZC5pc1Jlc29sdXRpb25FcnJvcigpICYmIHN5bS5raW5kLm1hdGNoZXMoS2luZFNlbGVjdG9yLlRZUCkpCiAgICAgICAgICAgICAgICByZXR1cm4gdHlwZXMuY3JlYXRlRXJyb3JUeXBlKG5hbWUsIGxvY2F0aW9uLCBzeW0udHlwZSkudHN5bTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgcmV0dXJuIHN5bTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBJbnZhbGlkU3ltYm9sRXJyb3IgZXJyb3IgY2xhc3MgaW5kaWNhdGluZyB0aGF0IGEgc3ltYm9sIG1hdGNoaW5nIGEKICAgICAqIGdpdmVuIG5hbWUgZG9lcyBub3QgZXhpc3RzIGluIGEgZ2l2ZW4gc2l0ZS4KICAgICAqLwogICAgY2xhc3MgU3ltYm9sTm90Rm91bmRFcnJvciBleHRlbmRzIFJlc29sdmVFcnJvciB7CgogICAgICAgIFN5bWJvbE5vdEZvdW5kRXJyb3IoS2luZCBraW5kKSB7CiAgICAgICAgICAgIHRoaXMoa2luZCwgInN5bWJvbCBub3QgZm91bmQgZXJyb3IiKTsKICAgICAgICB9CgogICAgICAgIFN5bWJvbE5vdEZvdW5kRXJyb3IoS2luZCBraW5kLCBTdHJpbmcgZGVidWdOYW1lKSB7CiAgICAgICAgICAgIHN1cGVyKGtpbmQsIGRlYnVnTmFtZSk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBKQ0RpYWdub3N0aWMgZ2V0RGlhZ25vc3RpYyhKQ0RpYWdub3N0aWMuRGlhZ25vc3RpY1R5cGUgZGtpbmQsCiAgICAgICAgICAgICAgICBEaWFnbm9zdGljUG9zaXRpb24gcG9zLAogICAgICAgICAgICAgICAgU3ltYm9sIGxvY2F0aW9uLAogICAgICAgICAgICAgICAgVHlwZSBzaXRlLAogICAgICAgICAgICAgICAgTmFtZSBuYW1lLAogICAgICAgICAgICAgICAgTGlzdDxUeXBlPiBhcmd0eXBlcywKICAgICAgICAgICAgICAgIExpc3Q8VHlwZT4gdHlwZWFyZ3R5cGVzKSB7CiAgICAgICAgICAgIGFyZ3R5cGVzID0gYXJndHlwZXMgPT0gbnVsbCA/IExpc3QubmlsKCkgOiBhcmd0eXBlczsKICAgICAgICAgICAgdHlwZWFyZ3R5cGVzID0gdHlwZWFyZ3R5cGVzID09IG51bGwgPyBMaXN0Lm5pbCgpIDogdHlwZWFyZ3R5cGVzOwogICAgICAgICAgICBpZiAobmFtZSA9PSBuYW1lcy5lcnJvcikKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwoKICAgICAgICAgICAgYm9vbGVhbiBoYXNMb2NhdGlvbiA9IGZhbHNlOwogICAgICAgICAgICBpZiAobG9jYXRpb24gPT0gbnVsbCkgewogICAgICAgICAgICAgICAgbG9jYXRpb24gPSBzaXRlLnRzeW07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCFsb2NhdGlvbi5uYW1lLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgICAgaWYgKGxvY2F0aW9uLmtpbmQgPT0gUENLICYmICFzaXRlLnRzeW0uZXhpc3RzKCkpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGlhZ3MuY3JlYXRlKGRraW5kLCBsb2cuY3VycmVudFNvdXJjZSgpLCBwb3MsCiAgICAgICAgICAgICAgICAgICAgICAgICJkb2VzbnQuZXhpc3QiLCBsb2NhdGlvbik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBoYXNMb2NhdGlvbiA9ICFsb2NhdGlvbi5uYW1lLmVxdWFscyhuYW1lcy5fdGhpcykgJiYKICAgICAgICAgICAgICAgICAgICAgICAgIWxvY2F0aW9uLm5hbWUuZXF1YWxzKG5hbWVzLl9zdXBlcik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYm9vbGVhbiBpc0NvbnN0cnVjdG9yID0gbmFtZSA9PSBuYW1lcy5pbml0OwogICAgICAgICAgICBLaW5kTmFtZSBraW5kbmFtZSA9IGlzQ29uc3RydWN0b3IgPyBLaW5kTmFtZS5DT05TVFJVQ1RPUiA6IGtpbmQuYWJzZW50S2luZCgpOwogICAgICAgICAgICBOYW1lIGlkbmFtZSA9IGlzQ29uc3RydWN0b3IgPyBzaXRlLnRzeW0ubmFtZSA6IG5hbWU7CiAgICAgICAgICAgIFN0cmluZyBlcnJLZXkgPSBnZXRFcnJvcktleShraW5kbmFtZSwgdHlwZWFyZ3R5cGVzLm5vbkVtcHR5KCksIGhhc0xvY2F0aW9uKTsKICAgICAgICAgICAgaWYgKGhhc0xvY2F0aW9uKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZGlhZ3MuY3JlYXRlKGRraW5kLCBsb2cuY3VycmVudFNvdXJjZSgpLCBwb3MsCiAgICAgICAgICAgICAgICAgICAgICAgIGVycktleSwga2luZG5hbWUsIGlkbmFtZSwgLy9zeW1ib2wga2luZG5hbWUsIG5hbWUKICAgICAgICAgICAgICAgICAgICAgICAgdHlwZWFyZ3R5cGVzLCBhcmdzKGFyZ3R5cGVzKSwgLy90eXBlIHBhcmFtZXRlcnMgYW5kIGFyZ3VtZW50cyAoaWYgYW55KQogICAgICAgICAgICAgICAgICAgICAgICBnZXRMb2NhdGlvbkRpYWcobG9jYXRpb24sIHNpdGUpKTsgLy9sb2NhdGlvbiBraW5kbmFtZSwgdHlwZQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgcmV0dXJuIGRpYWdzLmNyZWF0ZShka2luZCwgbG9nLmN1cnJlbnRTb3VyY2UoKSwgcG9zLAogICAgICAgICAgICAgICAgICAgICAgICBlcnJLZXksIGtpbmRuYW1lLCBpZG5hbWUsIC8vc3ltYm9sIGtpbmRuYW1lLCBuYW1lCiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVhcmd0eXBlcywgYXJncyhhcmd0eXBlcykpOyAvL3R5cGUgcGFyYW1ldGVycyBhbmQgYXJndW1lbnRzIChpZiBhbnkpCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLy93aGVyZQogICAgICAgIHByaXZhdGUgT2JqZWN0IGFyZ3MoTGlzdDxUeXBlPiBhcmdzKSB7CiAgICAgICAgICAgIHJldHVybiBhcmdzLmlzRW1wdHkoKSA/IGFyZ3MgOiBtZXRob2RBcmd1bWVudHMoYXJncyk7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIFN0cmluZyBnZXRFcnJvcktleShLaW5kTmFtZSBraW5kbmFtZSwgYm9vbGVhbiBoYXNUeXBlQXJncywgYm9vbGVhbiBoYXNMb2NhdGlvbikgewogICAgICAgICAgICBTdHJpbmcga2V5ID0gImNhbnQucmVzb2x2ZSI7CiAgICAgICAgICAgIFN0cmluZyBzdWZmaXggPSBoYXNMb2NhdGlvbiA/ICIubG9jYXRpb24iIDogIiI7CiAgICAgICAgICAgIHN3aXRjaCAoa2luZG5hbWUpIHsKICAgICAgICAgICAgICAgIGNhc2UgTUVUSE9EOgogICAgICAgICAgICAgICAgY2FzZSBDT05TVFJVQ1RPUjogewogICAgICAgICAgICAgICAgICAgIHN1ZmZpeCArPSAiLmFyZ3MiOwogICAgICAgICAgICAgICAgICAgIHN1ZmZpeCArPSBoYXNUeXBlQXJncyA/ICIucGFyYW1zIiA6ICIiOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBrZXkgKyBzdWZmaXg7CiAgICAgICAgfQogICAgICAgIHByaXZhdGUgSkNEaWFnbm9zdGljIGdldExvY2F0aW9uRGlhZyhTeW1ib2wgbG9jYXRpb24sIFR5cGUgc2l0ZSkgewogICAgICAgICAgICBpZiAobG9jYXRpb24ua2luZCA9PSBWQVIpIHsKICAgICAgICAgICAgICAgIHJldHVybiBkaWFncy5mcmFnbWVudCgibG9jYXRpb24uMSIsCiAgICAgICAgICAgICAgICAgICAga2luZE5hbWUobG9jYXRpb24pLAogICAgICAgICAgICAgICAgICAgIGxvY2F0aW9uLAogICAgICAgICAgICAgICAgICAgIGxvY2F0aW9uLnR5cGUpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcmV0dXJuIGRpYWdzLmZyYWdtZW50KCJsb2NhdGlvbiIsCiAgICAgICAgICAgICAgICAgICAgdHlwZUtpbmROYW1lKHNpdGUpLAogICAgICAgICAgICAgICAgICAgIHNpdGUsCiAgICAgICAgICAgICAgICAgICAgbnVsbCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBJbnZhbGlkU3ltYm9sRXJyb3IgZXJyb3IgY2xhc3MgaW5kaWNhdGluZyB0aGF0IGEgZ2l2ZW4gc3ltYm9sCiAgICAgKiAoZWl0aGVyIGEgbWV0aG9kLCBhIGNvbnN0cnVjdG9yIG9yIGFuIG9wZXJhbmQpIGlzIG5vdCBhcHBsaWNhYmxlCiAgICAgKiBnaXZlbiBhbiBhY3R1YWwgYXJndW1lbnRzL3R5cGUgYXJndW1lbnQgbGlzdC4KICAgICAqLwogICAgY2xhc3MgSW5hcHBsaWNhYmxlU3ltYm9sRXJyb3IgZXh0ZW5kcyBSZXNvbHZlRXJyb3IgewoKICAgICAgICBwcm90ZWN0ZWQgTWV0aG9kUmVzb2x1dGlvbkNvbnRleHQgcmVzb2x2ZUNvbnRleHQ7CgogICAgICAgIEluYXBwbGljYWJsZVN5bWJvbEVycm9yKE1ldGhvZFJlc29sdXRpb25Db250ZXh0IGNvbnRleHQpIHsKICAgICAgICAgICAgdGhpcyhXUk9OR19NVEgsICJpbmFwcGxpY2FibGUgc3ltYm9sIGVycm9yIiwgY29udGV4dCk7CiAgICAgICAgfQoKICAgICAgICBwcm90ZWN0ZWQgSW5hcHBsaWNhYmxlU3ltYm9sRXJyb3IoS2luZCBraW5kLCBTdHJpbmcgZGVidWdOYW1lLCBNZXRob2RSZXNvbHV0aW9uQ29udGV4dCBjb250ZXh0KSB7CiAgICAgICAgICAgIHN1cGVyKGtpbmQsIGRlYnVnTmFtZSk7CiAgICAgICAgICAgIHRoaXMucmVzb2x2ZUNvbnRleHQgPSBjb250ZXh0OwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKICAgICAgICAgICAgcmV0dXJuIHN1cGVyLnRvU3RyaW5nKCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgYm9vbGVhbiBleGlzdHMoKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgSkNEaWFnbm9zdGljIGdldERpYWdub3N0aWMoSkNEaWFnbm9zdGljLkRpYWdub3N0aWNUeXBlIGRraW5kLAogICAgICAgICAgICAgICAgRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcywKICAgICAgICAgICAgICAgIFN5bWJvbCBsb2NhdGlvbiwKICAgICAgICAgICAgICAgIFR5cGUgc2l0ZSwKICAgICAgICAgICAgICAgIE5hbWUgbmFtZSwKICAgICAgICAgICAgICAgIExpc3Q8VHlwZT4gYXJndHlwZXMsCiAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IHR5cGVhcmd0eXBlcykgewogICAgICAgICAgICBpZiAobmFtZSA9PSBuYW1lcy5lcnJvcikKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwoKICAgICAgICAgICAgUGFpcjxTeW1ib2wsIEpDRGlhZ25vc3RpYz4gYyA9IGVyckNhbmRpZGF0ZSgpOwogICAgICAgICAgICBpZiAoY29tcGFjdE1ldGhvZERpYWdzKSB7CiAgICAgICAgICAgICAgICBKQ0RpYWdub3N0aWMgc2ltcGxlRGlhZyA9CiAgICAgICAgICAgICAgICAgICAgTWV0aG9kUmVzb2x1dGlvbkRpYWdIZWxwZXIucmV3cml0ZShkaWFncywgcG9zLCBsb2cuY3VycmVudFNvdXJjZSgpLCBka2luZCwgYy5zbmQpOwogICAgICAgICAgICAgICAgaWYgKHNpbXBsZURpYWcgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBzaW1wbGVEaWFnOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIFN5bWJvbCB3cyA9IGMuZnN0LmFzTWVtYmVyT2Yoc2l0ZSwgdHlwZXMpOwogICAgICAgICAgICByZXR1cm4gZGlhZ3MuY3JlYXRlKGRraW5kLCBsb2cuY3VycmVudFNvdXJjZSgpLCBwb3MsCiAgICAgICAgICAgICAgICAgICAgICAiY2FudC5hcHBseS5zeW1ib2wiLAogICAgICAgICAgICAgICAgICAgICAga2luZE5hbWUod3MpLAogICAgICAgICAgICAgICAgICAgICAgd3MubmFtZSA9PSBuYW1lcy5pbml0ID8gd3Mub3duZXIubmFtZSA6IHdzLm5hbWUsCiAgICAgICAgICAgICAgICAgICAgICBtZXRob2RBcmd1bWVudHMod3MudHlwZS5nZXRQYXJhbWV0ZXJUeXBlcygpKSwKICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZEFyZ3VtZW50cyhhcmd0eXBlcyksCiAgICAgICAgICAgICAgICAgICAgICBraW5kTmFtZSh3cy5vd25lciksCiAgICAgICAgICAgICAgICAgICAgICB3cy5vd25lci50eXBlLAogICAgICAgICAgICAgICAgICAgICAgYy5zbmQpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFN5bWJvbCBhY2Nlc3MoTmFtZSBuYW1lLCBUeXBlU3ltYm9sIGxvY2F0aW9uKSB7CiAgICAgICAgICAgIHJldHVybiB0eXBlcy5jcmVhdGVFcnJvclR5cGUobmFtZSwgbG9jYXRpb24sIHN5bXMuZXJyU3ltYm9sLnR5cGUpLnRzeW07CiAgICAgICAgfQoKICAgICAgICBwcm90ZWN0ZWQgUGFpcjxTeW1ib2wsIEpDRGlhZ25vc3RpYz4gZXJyQ2FuZGlkYXRlKCkgewogICAgICAgICAgICBDYW5kaWRhdGUgYmVzdFNvRmFyID0gbnVsbDsKICAgICAgICAgICAgZm9yIChDYW5kaWRhdGUgYyA6IHJlc29sdmVDb250ZXh0LmNhbmRpZGF0ZXMpIHsKICAgICAgICAgICAgICAgIGlmIChjLmlzQXBwbGljYWJsZSgpKSBjb250aW51ZTsKICAgICAgICAgICAgICAgIGJlc3RTb0ZhciA9IGM7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgQXNzZXJ0LmNoZWNrTm9uTnVsbChiZXN0U29GYXIpOwogICAgICAgICAgICByZXR1cm4gbmV3IFBhaXI8PihiZXN0U29GYXIuc3ltLCBiZXN0U29GYXIuZGV0YWlscyk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogUmVzb2x2ZUVycm9yIGVycm9yIGNsYXNzIGluZGljYXRpbmcgdGhhdCBhIHN5bWJvbCAoZWl0aGVyIG1ldGhvZHMsIGNvbnN0cnVjdG9ycyBvciBvcGVyYW5kKQogICAgICogaXMgbm90IGFwcGxpY2FibGUgZ2l2ZW4gYW4gYWN0dWFsIGFyZ3VtZW50cy90eXBlIGFyZ3VtZW50IGxpc3QuCiAgICAgKi8KICAgIGNsYXNzIEluYXBwbGljYWJsZVN5bWJvbHNFcnJvciBleHRlbmRzIEluYXBwbGljYWJsZVN5bWJvbEVycm9yIHsKCiAgICAgICAgSW5hcHBsaWNhYmxlU3ltYm9sc0Vycm9yKE1ldGhvZFJlc29sdXRpb25Db250ZXh0IGNvbnRleHQpIHsKICAgICAgICAgICAgc3VwZXIoV1JPTkdfTVRIUywgImluYXBwbGljYWJsZSBzeW1ib2xzIiwgY29udGV4dCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBKQ0RpYWdub3N0aWMgZ2V0RGlhZ25vc3RpYyhKQ0RpYWdub3N0aWMuRGlhZ25vc3RpY1R5cGUgZGtpbmQsCiAgICAgICAgICAgICAgICBEaWFnbm9zdGljUG9zaXRpb24gcG9zLAogICAgICAgICAgICAgICAgU3ltYm9sIGxvY2F0aW9uLAogICAgICAgICAgICAgICAgVHlwZSBzaXRlLAogICAgICAgICAgICAgICAgTmFtZSBuYW1lLAogICAgICAgICAgICAgICAgTGlzdDxUeXBlPiBhcmd0eXBlcywKICAgICAgICAgICAgICAgIExpc3Q8VHlwZT4gdHlwZWFyZ3R5cGVzKSB7CiAgICAgICAgICAgIE1hcDxTeW1ib2wsIEpDRGlhZ25vc3RpYz4gY2FuZGlkYXRlc01hcCA9IG1hcENhbmRpZGF0ZXMoKTsKICAgICAgICAgICAgTWFwPFN5bWJvbCwgSkNEaWFnbm9zdGljPiBmaWx0ZXJlZENhbmRpZGF0ZXMgPSBjb21wYWN0TWV0aG9kRGlhZ3MgPwogICAgICAgICAgICAgICAgICAgIGZpbHRlckNhbmRpZGF0ZXMoY2FuZGlkYXRlc01hcCkgOgogICAgICAgICAgICAgICAgICAgIG1hcENhbmRpZGF0ZXMoKTsKICAgICAgICAgICAgaWYgKGZpbHRlcmVkQ2FuZGlkYXRlcy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICAgIGZpbHRlcmVkQ2FuZGlkYXRlcyA9IGNhbmRpZGF0ZXNNYXA7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYm9vbGVhbiB0cnVuY2F0ZWREaWFnID0gY2FuZGlkYXRlc01hcC5zaXplKCkgIT0gZmlsdGVyZWRDYW5kaWRhdGVzLnNpemUoKTsKICAgICAgICAgICAgaWYgKGZpbHRlcmVkQ2FuZGlkYXRlcy5zaXplKCkgPiAxKSB7CiAgICAgICAgICAgICAgICBKQ0RpYWdub3N0aWMgZXJyID0gZGlhZ3MuY3JlYXRlKGRraW5kLAogICAgICAgICAgICAgICAgICAgICAgICBudWxsLAogICAgICAgICAgICAgICAgICAgICAgICB0cnVuY2F0ZWREaWFnID8KICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVudW1TZXQub2YoRGlhZ25vc3RpY0ZsYWcuQ09NUFJFU1NFRCkgOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgRW51bVNldC5ub25lT2YoRGlhZ25vc3RpY0ZsYWcuY2xhc3MpLAogICAgICAgICAgICAgICAgICAgICAgICBsb2cuY3VycmVudFNvdXJjZSgpLAogICAgICAgICAgICAgICAgICAgICAgICBwb3MsCiAgICAgICAgICAgICAgICAgICAgICAgICJjYW50LmFwcGx5LnN5bWJvbHMiLAogICAgICAgICAgICAgICAgICAgICAgICBuYW1lID09IG5hbWVzLmluaXQgPyBLaW5kTmFtZS5DT05TVFJVQ1RPUiA6IGtpbmQuYWJzZW50S2luZCgpLAogICAgICAgICAgICAgICAgICAgICAgICBuYW1lID09IG5hbWVzLmluaXQgPyBzaXRlLnRzeW0ubmFtZSA6IG5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZEFyZ3VtZW50cyhhcmd0eXBlcykpOwogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBKQ0RpYWdub3N0aWMuTXVsdGlsaW5lRGlhZ25vc3RpYyhlcnIsIGNhbmRpZGF0ZURldGFpbHMoZmlsdGVyZWRDYW5kaWRhdGVzLCBzaXRlKSk7CiAgICAgICAgICAgIH0gZWxzZSBpZiAoZmlsdGVyZWRDYW5kaWRhdGVzLnNpemUoKSA9PSAxKSB7CiAgICAgICAgICAgICAgICBNYXAuRW50cnk8U3ltYm9sLCBKQ0RpYWdub3N0aWM+IF9lID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXJlZENhbmRpZGF0ZXMuZW50cnlTZXQoKS5pdGVyYXRvcigpLm5leHQoKTsKICAgICAgICAgICAgICAgIGZpbmFsIFBhaXI8U3ltYm9sLCBKQ0RpYWdub3N0aWM+IHAgPSBuZXcgUGFpcjw+KF9lLmdldEtleSgpLCBfZS5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIEpDRGlhZ25vc3RpYyBkID0gbmV3IEluYXBwbGljYWJsZVN5bWJvbEVycm9yKHJlc29sdmVDb250ZXh0KSB7CiAgICAgICAgICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgICAgICAgICAgcHJvdGVjdGVkIFBhaXI8U3ltYm9sLCBKQ0RpYWdub3N0aWM+IGVyckNhbmRpZGF0ZSgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHA7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfS5nZXREaWFnbm9zdGljKGRraW5kLCBwb3MsCiAgICAgICAgICAgICAgICAgICAgbG9jYXRpb24sIHNpdGUsIG5hbWUsIGFyZ3R5cGVzLCB0eXBlYXJndHlwZXMpOwogICAgICAgICAgICAgICAgaWYgKHRydW5jYXRlZERpYWcpIHsKICAgICAgICAgICAgICAgICAgICBkLnNldEZsYWcoRGlhZ25vc3RpY0ZsYWcuQ09NUFJFU1NFRCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gZDsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHJldHVybiBuZXcgU3ltYm9sTm90Rm91bmRFcnJvcihBQlNFTlRfTVRIKS5nZXREaWFnbm9zdGljKGRraW5kLCBwb3MsCiAgICAgICAgICAgICAgICAgICAgbG9jYXRpb24sIHNpdGUsIG5hbWUsIGFyZ3R5cGVzLCB0eXBlYXJndHlwZXMpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8vd2hlcmUKICAgICAgICAgICAgcHJpdmF0ZSBNYXA8U3ltYm9sLCBKQ0RpYWdub3N0aWM+IG1hcENhbmRpZGF0ZXMoKSB7CiAgICAgICAgICAgICAgICBNYXA8U3ltYm9sLCBKQ0RpYWdub3N0aWM+IGNhbmRpZGF0ZXMgPSBuZXcgTGlua2VkSGFzaE1hcDw+KCk7CiAgICAgICAgICAgICAgICBmb3IgKENhbmRpZGF0ZSBjIDogcmVzb2x2ZUNvbnRleHQuY2FuZGlkYXRlcykgewogICAgICAgICAgICAgICAgICAgIGlmIChjLmlzQXBwbGljYWJsZSgpKSBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICBjYW5kaWRhdGVzLnB1dChjLnN5bSwgYy5kZXRhaWxzKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBjYW5kaWRhdGVzOwogICAgICAgICAgICB9CgogICAgICAgICAgICBNYXA8U3ltYm9sLCBKQ0RpYWdub3N0aWM+IGZpbHRlckNhbmRpZGF0ZXMoTWFwPFN5bWJvbCwgSkNEaWFnbm9zdGljPiBjYW5kaWRhdGVzTWFwKSB7CiAgICAgICAgICAgICAgICBNYXA8U3ltYm9sLCBKQ0RpYWdub3N0aWM+IGNhbmRpZGF0ZXMgPSBuZXcgTGlua2VkSGFzaE1hcDw+KCk7CiAgICAgICAgICAgICAgICBmb3IgKE1hcC5FbnRyeTxTeW1ib2wsIEpDRGlhZ25vc3RpYz4gX2VudHJ5IDogY2FuZGlkYXRlc01hcC5lbnRyeVNldCgpKSB7CiAgICAgICAgICAgICAgICAgICAgSkNEaWFnbm9zdGljIGQgPSBfZW50cnkuZ2V0VmFsdWUoKTsKICAgICAgICAgICAgICAgICAgICBpZiAoIW5ldyBUZW1wbGF0ZShNZXRob2RDaGVja0RpYWcuQVJJVFlfTUlTTUFUQ0gucmVnZXgoKSkubWF0Y2hlcyhkKSkgewogICAgICAgICAgICAgICAgICAgICAgICBjYW5kaWRhdGVzLnB1dChfZW50cnkuZ2V0S2V5KCksIGQpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBjYW5kaWRhdGVzOwogICAgICAgICAgICB9CgogICAgICAgICAgICBwcml2YXRlIExpc3Q8SkNEaWFnbm9zdGljPiBjYW5kaWRhdGVEZXRhaWxzKE1hcDxTeW1ib2wsIEpDRGlhZ25vc3RpYz4gY2FuZGlkYXRlc01hcCwgVHlwZSBzaXRlKSB7CiAgICAgICAgICAgICAgICBMaXN0PEpDRGlhZ25vc3RpYz4gZGV0YWlscyA9IExpc3QubmlsKCk7CiAgICAgICAgICAgICAgICBmb3IgKE1hcC5FbnRyeTxTeW1ib2wsIEpDRGlhZ25vc3RpYz4gX2VudHJ5IDogY2FuZGlkYXRlc01hcC5lbnRyeVNldCgpKSB7CiAgICAgICAgICAgICAgICAgICAgU3ltYm9sIHN5bSA9IF9lbnRyeS5nZXRLZXkoKTsKICAgICAgICAgICAgICAgICAgICBKQ0RpYWdub3N0aWMgZGV0YWlsRGlhZyA9IGRpYWdzLmZyYWdtZW50KCJpbmFwcGxpY2FibGUubWV0aG9kIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEtpbmRzLmtpbmROYW1lKHN5bSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeW0ubG9jYXRpb24oc2l0ZSwgdHlwZXMpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ltLmFzTWVtYmVyT2Yoc2l0ZSwgdHlwZXMpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgX2VudHJ5LmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgICAgIGRldGFpbHMgPSBkZXRhaWxzLnByZXBlbmQoZGV0YWlsRGlhZyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvL3R5cGljYWxseSBtZW1iZXJzIGFyZSB2aXNpdGVkIGluIHJldmVyc2Ugb3JkZXIgKHNlZSBTY29wZSkKICAgICAgICAgICAgICAgIC8vc28gd2UgbmVlZCB0byByZXZlcnNlIHRoZSBjYW5kaWRhdGUgbGlzdCBzbyB0aGF0IGNhbmRpZGF0ZXMKICAgICAgICAgICAgICAgIC8vY29uZm9ybSB0byBzb3VyY2Ugb3JkZXIKICAgICAgICAgICAgICAgIHJldHVybiBkZXRhaWxzOwogICAgICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBEaWFtb25kRXJyb3IgZXJyb3IgY2xhc3MgaW5kaWNhdGluZyB0aGF0IGEgY29uc3RydWN0b3Igc3ltYm9sIGlzIG5vdCBhcHBsaWNhYmxlCiAgICAgKiBnaXZlbiBhbiBhY3R1YWwgYXJndW1lbnRzL3R5cGUgYXJndW1lbnQgbGlzdCB1c2luZyBkaWFtb25kIGluZmVyZW5jZS4KICAgICAqLwogICAgY2xhc3MgRGlhbW9uZEVycm9yIGV4dGVuZHMgSW5hcHBsaWNhYmxlU3ltYm9sRXJyb3IgewoKICAgICAgICBTeW1ib2wgc3ltOwoKICAgICAgICBwdWJsaWMgRGlhbW9uZEVycm9yKFN5bWJvbCBzeW0sIE1ldGhvZFJlc29sdXRpb25Db250ZXh0IGNvbnRleHQpIHsKICAgICAgICAgICAgc3VwZXIoc3ltLmtpbmQsICJkaWFtb25kRXJyb3IiLCBjb250ZXh0KTsKICAgICAgICAgICAgdGhpcy5zeW0gPSBzeW07CiAgICAgICAgfQoKICAgICAgICBKQ0RpYWdub3N0aWMgZ2V0RGV0YWlscygpIHsKICAgICAgICAgICAgcmV0dXJuIChzeW0ua2luZCA9PSBXUk9OR19NVEgpID8KICAgICAgICAgICAgICAgICAgICAoKEluYXBwbGljYWJsZVN5bWJvbEVycm9yKXN5bS5iYXNlU3ltYm9sKCkpLmVyckNhbmRpZGF0ZSgpLnNuZCA6CiAgICAgICAgICAgICAgICAgICAgbnVsbDsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIEpDRGlhZ25vc3RpYyBnZXREaWFnbm9zdGljKERpYWdub3N0aWNUeXBlIGRraW5kLCBEaWFnbm9zdGljUG9zaXRpb24gcG9zLAogICAgICAgICAgICAgICAgU3ltYm9sIGxvY2F0aW9uLCBUeXBlIHNpdGUsIE5hbWUgbmFtZSwgTGlzdDxUeXBlPiBhcmd0eXBlcywgTGlzdDxUeXBlPiB0eXBlYXJndHlwZXMpIHsKICAgICAgICAgICAgSkNEaWFnbm9zdGljIGRldGFpbHMgPSBnZXREZXRhaWxzKCk7CiAgICAgICAgICAgIGlmIChkZXRhaWxzICE9IG51bGwgJiYgY29tcGFjdE1ldGhvZERpYWdzKSB7CiAgICAgICAgICAgICAgICBKQ0RpYWdub3N0aWMgc2ltcGxlRGlhZyA9CiAgICAgICAgICAgICAgICAgICAgICAgIE1ldGhvZFJlc29sdXRpb25EaWFnSGVscGVyLnJld3JpdGUoZGlhZ3MsIHBvcywgbG9nLmN1cnJlbnRTb3VyY2UoKSwgZGtpbmQsIGRldGFpbHMpOwogICAgICAgICAgICAgICAgaWYgKHNpbXBsZURpYWcgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBzaW1wbGVEaWFnOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIFN0cmluZyBrZXkgPSBkZXRhaWxzID09IG51bGwgPwogICAgICAgICAgICAgICAgImNhbnQuYXBwbHkuZGlhbW9uZCIgOgogICAgICAgICAgICAgICAgImNhbnQuYXBwbHkuZGlhbW9uZC4xIjsKICAgICAgICAgICAgcmV0dXJuIGRpYWdzLmNyZWF0ZShka2luZCwgbG9nLmN1cnJlbnRTb3VyY2UoKSwgcG9zLCBrZXksCiAgICAgICAgICAgICAgICAgICAgZGlhZ3MuZnJhZ21lbnQoImRpYW1vbmQiLCBzaXRlLnRzeW0pLCBkZXRhaWxzKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBBbiBJbnZhbGlkU3ltYm9sRXJyb3IgZXJyb3IgY2xhc3MgaW5kaWNhdGluZyB0aGF0IGEgc3ltYm9sIGlzIG5vdAogICAgICogYWNjZXNzaWJsZSBmcm9tIGEgZ2l2ZW4gc2l0ZQogICAgICovCiAgICBjbGFzcyBBY2Nlc3NFcnJvciBleHRlbmRzIEludmFsaWRTeW1ib2xFcnJvciB7CgogICAgICAgIHByaXZhdGUgRW52PEF0dHJDb250ZXh0PiBlbnY7CiAgICAgICAgcHJpdmF0ZSBUeXBlIHNpdGU7CgogICAgICAgIEFjY2Vzc0Vycm9yKEVudjxBdHRyQ29udGV4dD4gZW52LCBUeXBlIHNpdGUsIFN5bWJvbCBzeW0pIHsKICAgICAgICAgICAgc3VwZXIoSElEREVOLCBzeW0sICJhY2Nlc3MgZXJyb3IiKTsKICAgICAgICAgICAgdGhpcy5lbnYgPSBlbnY7CiAgICAgICAgICAgIHRoaXMuc2l0ZSA9IHNpdGU7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgYm9vbGVhbiBleGlzdHMoKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIEpDRGlhZ25vc3RpYyBnZXREaWFnbm9zdGljKEpDRGlhZ25vc3RpYy5EaWFnbm9zdGljVHlwZSBka2luZCwKICAgICAgICAgICAgICAgIERpYWdub3N0aWNQb3NpdGlvbiBwb3MsCiAgICAgICAgICAgICAgICBTeW1ib2wgbG9jYXRpb24sCiAgICAgICAgICAgICAgICBUeXBlIHNpdGUsCiAgICAgICAgICAgICAgICBOYW1lIG5hbWUsCiAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IGFyZ3R5cGVzLAogICAgICAgICAgICAgICAgTGlzdDxUeXBlPiB0eXBlYXJndHlwZXMpIHsKICAgICAgICAgICAgaWYgKHN5bS5vd25lci50eXBlLmhhc1RhZyhFUlJPUikpCiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKCiAgICAgICAgICAgIGlmIChzeW0ubmFtZSA9PSBuYW1lcy5pbml0ICYmIHN5bS5vd25lciAhPSBzaXRlLnRzeW0pIHsKICAgICAgICAgICAgICAgIHJldHVybiBuZXcgU3ltYm9sTm90Rm91bmRFcnJvcihBQlNFTlRfTVRIKS5nZXREaWFnbm9zdGljKGRraW5kLAogICAgICAgICAgICAgICAgICAgICAgICBwb3MsIGxvY2F0aW9uLCBzaXRlLCBuYW1lLCBhcmd0eXBlcywgdHlwZWFyZ3R5cGVzKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmICgoc3ltLmZsYWdzKCkgJiBQVUJMSUMpICE9IDAKICAgICAgICAgICAgICAgIHx8IChlbnYgIT0gbnVsbCAmJiB0aGlzLnNpdGUgIT0gbnVsbAogICAgICAgICAgICAgICAgICAgICYmICFpc0FjY2Vzc2libGUoZW52LCB0aGlzLnNpdGUpKSkgewogICAgICAgICAgICAgICAgaWYgKHN5bS5vd25lci5raW5kID09IFBDSykgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBkaWFncy5jcmVhdGUoZGtpbmQsIGxvZy5jdXJyZW50U291cmNlKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb3MsICJub3QuZGVmLmFjY2Vzcy5wYWNrYWdlLmNhbnQuYWNjZXNzIiwKICAgICAgICAgICAgICAgICAgICAgICAgc3ltLCBzeW0ubG9jYXRpb24oKSwgaW5hY2Nlc3NpYmxlUGFja2FnZVJlYXNvbihlbnYsIHN5bS5wYWNrZ2UoKSkpOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmICggICBzeW0ucGFja2dlKCkgIT0gc3ltcy5yb290UGFja2FnZQogICAgICAgICAgICAgICAgICAgICAgICAgICAmJiAhc3ltYm9sUGFja2FnZVZpc2libGUoZW52LCBzeW0pKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRpYWdzLmNyZWF0ZShka2luZCwgbG9nLmN1cnJlbnRTb3VyY2UoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvcywgIm5vdC5kZWYuYWNjZXNzLmNsYXNzLmludGYuY2FudC5hY2Nlc3MucmVhc29uIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5bSwgc3ltLmxvY2F0aW9uKCksIHN5bS5sb2NhdGlvbigpLnBhY2tnZSgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5hY2Nlc3NpYmxlUGFja2FnZVJlYXNvbihlbnYsIHN5bS5wYWNrZ2UoKSkpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGlhZ3MuY3JlYXRlKGRraW5kLCBsb2cuY3VycmVudFNvdXJjZSgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9zLCAibm90LmRlZi5hY2Nlc3MuY2xhc3MuaW50Zi5jYW50LmFjY2VzcyIsCiAgICAgICAgICAgICAgICAgICAgICAgIHN5bSwgc3ltLmxvY2F0aW9uKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKChzeW0uZmxhZ3MoKSAmIChQUklWQVRFIHwgUFJPVEVDVEVEKSkgIT0gMCkgewogICAgICAgICAgICAgICAgcmV0dXJuIGRpYWdzLmNyZWF0ZShka2luZCwgbG9nLmN1cnJlbnRTb3VyY2UoKSwKICAgICAgICAgICAgICAgICAgICAgICAgcG9zLCAicmVwb3J0LmFjY2VzcyIsIHN5bSwKICAgICAgICAgICAgICAgICAgICAgICAgYXNGbGFnU2V0KHN5bS5mbGFncygpICYgKFBSSVZBVEUgfCBQUk9URUNURUQpKSwKICAgICAgICAgICAgICAgICAgICAgICAgc3ltLmxvY2F0aW9uKCkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgcmV0dXJuIGRpYWdzLmNyZWF0ZShka2luZCwgbG9nLmN1cnJlbnRTb3VyY2UoKSwKICAgICAgICAgICAgICAgICAgICAgICAgcG9zLCAibm90LmRlZi5wdWJsaWMuY2FudC5hY2Nlc3MiLCBzeW0sIHN5bS5sb2NhdGlvbigpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBTdHJpbmcgdG9TdHJpbmcoVHlwZSB0eXBlKSB7CiAgICAgICAgICAgIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigpOwogICAgICAgICAgICBzYi5hcHBlbmQodHlwZSk7CiAgICAgICAgICAgIGlmICh0eXBlICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIHNiLmFwcGVuZCgiW3RzeW06IikuYXBwZW5kKHR5cGUudHN5bSk7CiAgICAgICAgICAgICAgICBpZiAodHlwZS50c3ltICE9IG51bGwpCiAgICAgICAgICAgICAgICAgICAgc2IuYXBwZW5kKCJwYWNrZ2U6IikuYXBwZW5kKHR5cGUudHN5bS5wYWNrZ2UoKSk7CiAgICAgICAgICAgICAgICBzYi5hcHBlbmQoIl0iKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gc2IudG9TdHJpbmcoKTsKICAgICAgICB9CiAgICB9CgogICAgY2xhc3MgSW52aXNpYmxlU3ltYm9sRXJyb3IgZXh0ZW5kcyBJbnZhbGlkU3ltYm9sRXJyb3IgewoKICAgICAgICBwcml2YXRlIGZpbmFsIEVudjxBdHRyQ29udGV4dD4gZW52OwogICAgICAgIHByaXZhdGUgZmluYWwgYm9vbGVhbiBzdXBwcmVzc0Vycm9yOwoKICAgICAgICBJbnZpc2libGVTeW1ib2xFcnJvcihFbnY8QXR0ckNvbnRleHQ+IGVudiwgYm9vbGVhbiBzdXBwcmVzc0Vycm9yLCBTeW1ib2wgc3ltKSB7CiAgICAgICAgICAgIHN1cGVyKEhJRERFTiwgc3ltLCAiaW52aXNpYmxlIGNsYXNzIGVycm9yIik7CiAgICAgICAgICAgIHRoaXMuZW52ID0gZW52OwogICAgICAgICAgICB0aGlzLnN1cHByZXNzRXJyb3IgPSBzdXBwcmVzc0Vycm9yOwogICAgICAgICAgICB0aGlzLm5hbWUgPSBzeW0ubmFtZTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIEpDRGlhZ25vc3RpYyBnZXREaWFnbm9zdGljKEpDRGlhZ25vc3RpYy5EaWFnbm9zdGljVHlwZSBka2luZCwKICAgICAgICAgICAgICAgIERpYWdub3N0aWNQb3NpdGlvbiBwb3MsCiAgICAgICAgICAgICAgICBTeW1ib2wgbG9jYXRpb24sCiAgICAgICAgICAgICAgICBUeXBlIHNpdGUsCiAgICAgICAgICAgICAgICBOYW1lIG5hbWUsCiAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IGFyZ3R5cGVzLAogICAgICAgICAgICAgICAgTGlzdDxUeXBlPiB0eXBlYXJndHlwZXMpIHsKICAgICAgICAgICAgaWYgKHN1cHByZXNzRXJyb3IpCiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKCiAgICAgICAgICAgIGlmIChzeW0ua2luZCA9PSBQQ0spIHsKICAgICAgICAgICAgICAgIEpDRGlhZ25vc3RpYyBkZXRhaWxzID0gaW5hY2Nlc3NpYmxlUGFja2FnZVJlYXNvbihlbnYsIHN5bS5wYWNrZ2UoKSk7CiAgICAgICAgICAgICAgICByZXR1cm4gZGlhZ3MuY3JlYXRlKGRraW5kLCBsb2cuY3VycmVudFNvdXJjZSgpLAogICAgICAgICAgICAgICAgICAgICAgICBwb3MsICJwYWNrYWdlLm5vdC52aXNpYmxlIiwgc3ltLCBkZXRhaWxzKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgSkNEaWFnbm9zdGljIGRldGFpbHMgPSBpbmFjY2Vzc2libGVQYWNrYWdlUmVhc29uKGVudiwgc3ltLnBhY2tnZSgpKTsKCiAgICAgICAgICAgIGlmIChwb3MuZ2V0VHJlZSgpICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIFN5bWJvbCBvID0gc3ltOwogICAgICAgICAgICAgICAgSkNUcmVlIHRyZWUgPSBwb3MuZ2V0VHJlZSgpOwoKICAgICAgICAgICAgICAgIHdoaWxlIChvLmtpbmQgIT0gUENLICYmIHRyZWUuaGFzVGFnKFNFTEVDVCkpIHsKICAgICAgICAgICAgICAgICAgICBvID0gby5vd25lcjsKICAgICAgICAgICAgICAgICAgICB0cmVlID0gKChKQ0ZpZWxkQWNjZXNzKSB0cmVlKS5zZWxlY3RlZDsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoby5raW5kID09IFBDSykgewogICAgICAgICAgICAgICAgICAgIHBvcyA9IHRyZWUucG9zKCk7CgogICAgICAgICAgICAgICAgICAgIHJldHVybiBkaWFncy5jcmVhdGUoZGtpbmQsIGxvZy5jdXJyZW50U291cmNlKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb3MsICJwYWNrYWdlLm5vdC52aXNpYmxlIiwgbywgZGV0YWlscyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBkaWFncy5jcmVhdGUoZGtpbmQsIGxvZy5jdXJyZW50U291cmNlKCksCiAgICAgICAgICAgICAgICAgICAgcG9zLCAibm90LmRlZi5hY2Nlc3MucGFja2FnZS5jYW50LmFjY2VzcyIsIHN5bSwgc3ltLnBhY2tnZSgpLCBkZXRhaWxzKTsKICAgICAgICB9CiAgICB9CgogICAgSkNEaWFnbm9zdGljIGluYWNjZXNzaWJsZVBhY2thZ2VSZWFzb24oRW52PEF0dHJDb250ZXh0PiBlbnYsIFBhY2thZ2VTeW1ib2wgc3ltKSB7CiAgICAgICAgLy9ubyBkZXBlbmRlbmN5OgogICAgICAgIGlmICghZW52LnRvcGxldmVsLm1vZGxlLnJlYWRNb2R1bGVzLmNvbnRhaW5zKHN5bS5tb2RsZSkpIHsKICAgICAgICAgICAgLy9kb2VzIG5vdCByZWFkOgogICAgICAgICAgICBpZiAoc3ltLm1vZGxlICE9IHN5bXMudW5uYW1lZE1vZHVsZSkgewogICAgICAgICAgICAgICAgaWYgKGVudi50b3BsZXZlbC5tb2RsZSAhPSBzeW1zLnVubmFtZWRNb2R1bGUpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGlhZ3MuZnJhZ21lbnQoRnJhZ21lbnRzLk5vdERlZkFjY2Vzc0RvZXNOb3RSZWFkKGVudi50b3BsZXZlbC5tb2RsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5bSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5bS5tb2RsZSkpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGlhZ3MuZnJhZ21lbnQoRnJhZ21lbnRzLk5vdERlZkFjY2Vzc0RvZXNOb3RSZWFkRnJvbVVubmFtZWQoc3ltLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeW0ubW9kbGUpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHJldHVybiBkaWFncy5mcmFnbWVudChGcmFnbWVudHMuTm90RGVmQWNjZXNzRG9lc05vdFJlYWRVbm5hbWVkKHN5bSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVudi50b3BsZXZlbC5tb2RsZSkpOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgaWYgKHN5bS5wYWNrZ2UoKS5tb2RsZS5leHBvcnRzLnN0cmVhbSgpLmFueU1hdGNoKGUgLT4gZS5wYWNrZ2UgPT0gc3ltKSkgewogICAgICAgICAgICAgICAgLy9ub3QgZXhwb3J0ZWQgdG8gdGhpcyBtb2R1bGU6CiAgICAgICAgICAgICAgICBpZiAoZW52LnRvcGxldmVsLm1vZGxlICE9IHN5bXMudW5uYW1lZE1vZHVsZSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBkaWFncy5mcmFnbWVudChGcmFnbWVudHMuTm90RGVmQWNjZXNzTm90RXhwb3J0ZWRUb01vZHVsZShzeW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5bS5tb2RsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW52LnRvcGxldmVsLm1vZGxlKSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBkaWFncy5mcmFnbWVudChGcmFnbWVudHMuTm90RGVmQWNjZXNzTm90RXhwb3J0ZWRUb01vZHVsZUZyb21Vbm5hbWVkKHN5bSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeW0ubW9kbGUpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIC8vbm90IGV4cG9ydGVkOgogICAgICAgICAgICAgICAgaWYgKGVudi50b3BsZXZlbC5tb2RsZSAhPSBzeW1zLnVubmFtZWRNb2R1bGUpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGlhZ3MuZnJhZ21lbnQoRnJhZ21lbnRzLk5vdERlZkFjY2Vzc05vdEV4cG9ydGVkKHN5bSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5bS5tb2RsZSkpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGlhZ3MuZnJhZ21lbnQoRnJhZ21lbnRzLk5vdERlZkFjY2Vzc05vdEV4cG9ydGVkRnJvbVVubmFtZWQoc3ltLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeW0ubW9kbGUpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEludmFsaWRTeW1ib2xFcnJvciBlcnJvciBjbGFzcyBpbmRpY2F0aW5nIHRoYXQgYW4gaW5zdGFuY2UgbWVtYmVyCiAgICAgKiBoYXMgZXJyb25lb3VzbHkgYmVlbiBhY2Nlc3NlZCBmcm9tIGEgc3RhdGljIGNvbnRleHQuCiAgICAgKi8KICAgIGNsYXNzIFN0YXRpY0Vycm9yIGV4dGVuZHMgSW52YWxpZFN5bWJvbEVycm9yIHsKCiAgICAgICAgU3RhdGljRXJyb3IoU3ltYm9sIHN5bSkgewogICAgICAgICAgICBzdXBlcihTVEFUSUNFUlIsIHN5bSwgInN0YXRpYyBlcnJvciIpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgSkNEaWFnbm9zdGljIGdldERpYWdub3N0aWMoSkNEaWFnbm9zdGljLkRpYWdub3N0aWNUeXBlIGRraW5kLAogICAgICAgICAgICAgICAgRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcywKICAgICAgICAgICAgICAgIFN5bWJvbCBsb2NhdGlvbiwKICAgICAgICAgICAgICAgIFR5cGUgc2l0ZSwKICAgICAgICAgICAgICAgIE5hbWUgbmFtZSwKICAgICAgICAgICAgICAgIExpc3Q8VHlwZT4gYXJndHlwZXMsCiAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IHR5cGVhcmd0eXBlcykgewogICAgICAgICAgICBTeW1ib2wgZXJyU3ltID0gKChzeW0ua2luZCA9PSBUWVAgJiYgc3ltLnR5cGUuaGFzVGFnKENMQVNTKSkKICAgICAgICAgICAgICAgID8gdHlwZXMuZXJhc3VyZShzeW0udHlwZSkudHN5bQogICAgICAgICAgICAgICAgOiBzeW0pOwogICAgICAgICAgICByZXR1cm4gZGlhZ3MuY3JlYXRlKGRraW5kLCBsb2cuY3VycmVudFNvdXJjZSgpLCBwb3MsCiAgICAgICAgICAgICAgICAgICAgIm5vbi1zdGF0aWMuY2FudC5iZS5yZWYiLCBraW5kTmFtZShzeW0pLCBlcnJTeW0pOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEludmFsaWRTeW1ib2xFcnJvciBlcnJvciBjbGFzcyBpbmRpY2F0aW5nIHRoYXQgYSBwYWlyIG9mIHN5bWJvbHMKICAgICAqIChlaXRoZXIgbWV0aG9kcywgY29uc3RydWN0b3JzIG9yIG9wZXJhbmRzKSBhcmUgYW1iaWd1b3VzCiAgICAgKiBnaXZlbiBhbiBhY3R1YWwgYXJndW1lbnRzL3R5cGUgYXJndW1lbnQgbGlzdC4KICAgICAqLwogICAgY2xhc3MgQW1iaWd1aXR5RXJyb3IgZXh0ZW5kcyBSZXNvbHZlRXJyb3IgewoKICAgICAgICAvKiogVGhlIG90aGVyIG1heGltYWxseSBzcGVjaWZpYyBzeW1ib2wgKi8KICAgICAgICBMaXN0PFN5bWJvbD4gYW1iaWd1b3VzU3ltcyA9IExpc3QubmlsKCk7CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBib29sZWFuIGV4aXN0cygpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICBBbWJpZ3VpdHlFcnJvcihTeW1ib2wgc3ltMSwgU3ltYm9sIHN5bTIpIHsKICAgICAgICAgICAgc3VwZXIoQU1CSUdVT1VTLCAiYW1iaWd1aXR5IGVycm9yIik7CiAgICAgICAgICAgIGFtYmlndW91c1N5bXMgPSBmbGF0dGVuKHN5bTIpLmFwcGVuZExpc3QoZmxhdHRlbihzeW0xKSk7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIExpc3Q8U3ltYm9sPiBmbGF0dGVuKFN5bWJvbCBzeW0pIHsKICAgICAgICAgICAgaWYgKHN5bS5raW5kID09IEFNQklHVU9VUykgewogICAgICAgICAgICAgICAgcmV0dXJuICgoQW1iaWd1aXR5RXJyb3Ipc3ltLmJhc2VTeW1ib2woKSkuYW1iaWd1b3VzU3ltczsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHJldHVybiBMaXN0Lm9mKHN5bSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEFtYmlndWl0eUVycm9yIGFkZEFtYmlndW91c1N5bWJvbChTeW1ib2wgcykgewogICAgICAgICAgICBhbWJpZ3VvdXNTeW1zID0gYW1iaWd1b3VzU3ltcy5wcmVwZW5kKHMpOwogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIEpDRGlhZ25vc3RpYyBnZXREaWFnbm9zdGljKEpDRGlhZ25vc3RpYy5EaWFnbm9zdGljVHlwZSBka2luZCwKICAgICAgICAgICAgICAgIERpYWdub3N0aWNQb3NpdGlvbiBwb3MsCiAgICAgICAgICAgICAgICBTeW1ib2wgbG9jYXRpb24sCiAgICAgICAgICAgICAgICBUeXBlIHNpdGUsCiAgICAgICAgICAgICAgICBOYW1lIG5hbWUsCiAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IGFyZ3R5cGVzLAogICAgICAgICAgICAgICAgTGlzdDxUeXBlPiB0eXBlYXJndHlwZXMpIHsKICAgICAgICAgICAgTGlzdDxTeW1ib2w+IGRpYWdTeW1zID0gYW1iaWd1b3VzU3ltcy5yZXZlcnNlKCk7CiAgICAgICAgICAgIFN5bWJvbCBzMSA9IGRpYWdTeW1zLmhlYWQ7CiAgICAgICAgICAgIFN5bWJvbCBzMiA9IGRpYWdTeW1zLnRhaWwuaGVhZDsKICAgICAgICAgICAgTmFtZSBzbmFtZSA9IHMxLm5hbWU7CiAgICAgICAgICAgIGlmIChzbmFtZSA9PSBuYW1lcy5pbml0KSBzbmFtZSA9IHMxLm93bmVyLm5hbWU7CiAgICAgICAgICAgIHJldHVybiBkaWFncy5jcmVhdGUoZGtpbmQsIGxvZy5jdXJyZW50U291cmNlKCksCiAgICAgICAgICAgICAgICAgICAgcG9zLCAicmVmLmFtYmlndW91cyIsIHNuYW1lLAogICAgICAgICAgICAgICAgICAgIGtpbmROYW1lKHMxKSwKICAgICAgICAgICAgICAgICAgICBzMSwKICAgICAgICAgICAgICAgICAgICBzMS5sb2NhdGlvbihzaXRlLCB0eXBlcyksCiAgICAgICAgICAgICAgICAgICAga2luZE5hbWUoczIpLAogICAgICAgICAgICAgICAgICAgIHMyLAogICAgICAgICAgICAgICAgICAgIHMyLmxvY2F0aW9uKHNpdGUsIHR5cGVzKSk7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBJZiBtdWx0aXBsZSBhcHBsaWNhYmxlIG1ldGhvZHMgYXJlIGZvdW5kIGR1cmluZyBvdmVybG9hZCBhbmQgbm9uZSBvZiB0aGVtCiAgICAgICAgICogaXMgbW9yZSBzcGVjaWZpYyB0aGFuIHRoZSBvdGhlcnMsIGF0dGVtcHQgdG8gbWVyZ2UgdGhlaXIgc2lnbmF0dXJlcy4KICAgICAgICAgKi8KICAgICAgICBTeW1ib2wgbWVyZ2VBYnN0cmFjdHMoVHlwZSBzaXRlKSB7CiAgICAgICAgICAgIExpc3Q8U3ltYm9sPiBhbWJpZ3VvdXNJbk9yZGVyID0gYW1iaWd1b3VzU3ltcy5yZXZlcnNlKCk7CiAgICAgICAgICAgIHJldHVybiB0eXBlcy5tZXJnZUFic3RyYWN0cyhhbWJpZ3VvdXNJbk9yZGVyLCBzaXRlLCB0cnVlKS5vckVsc2UodGhpcyk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwcm90ZWN0ZWQgU3ltYm9sIGFjY2VzcyhOYW1lIG5hbWUsIFR5cGVTeW1ib2wgbG9jYXRpb24pIHsKICAgICAgICAgICAgU3ltYm9sIGZpcnN0QW1iaWd1aXR5ID0gYW1iaWd1b3VzU3ltcy5sYXN0KCk7CiAgICAgICAgICAgIHJldHVybiBmaXJzdEFtYmlndWl0eS5raW5kID09IFRZUCA/CiAgICAgICAgICAgICAgICAgICAgdHlwZXMuY3JlYXRlRXJyb3JUeXBlKG5hbWUsIGxvY2F0aW9uLCBmaXJzdEFtYmlndWl0eS50eXBlKS50c3ltIDoKICAgICAgICAgICAgICAgICAgICBmaXJzdEFtYmlndWl0eTsKICAgICAgICB9CiAgICB9CgogICAgY2xhc3MgQmFkVmFyYXJnc01ldGhvZCBleHRlbmRzIFJlc29sdmVFcnJvciB7CgogICAgICAgIFJlc29sdmVFcnJvciBkZWxlZ2F0ZWRFcnJvcjsKCiAgICAgICAgQmFkVmFyYXJnc01ldGhvZChSZXNvbHZlRXJyb3IgZGVsZWdhdGVkRXJyb3IpIHsKICAgICAgICAgICAgc3VwZXIoZGVsZWdhdGVkRXJyb3Iua2luZCwgImJhZFZhcmFyZ3MiKTsKICAgICAgICAgICAgdGhpcy5kZWxlZ2F0ZWRFcnJvciA9IGRlbGVnYXRlZEVycm9yOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFN5bWJvbCBiYXNlU3ltYm9sKCkgewogICAgICAgICAgICByZXR1cm4gZGVsZWdhdGVkRXJyb3IuYmFzZVN5bWJvbCgpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHJvdGVjdGVkIFN5bWJvbCBhY2Nlc3MoTmFtZSBuYW1lLCBUeXBlU3ltYm9sIGxvY2F0aW9uKSB7CiAgICAgICAgICAgIHJldHVybiBkZWxlZ2F0ZWRFcnJvci5hY2Nlc3MobmFtZSwgbG9jYXRpb24pOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gZXhpc3RzKCkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIEpDRGlhZ25vc3RpYyBnZXREaWFnbm9zdGljKERpYWdub3N0aWNUeXBlIGRraW5kLCBEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBTeW1ib2wgbG9jYXRpb24sIFR5cGUgc2l0ZSwgTmFtZSBuYW1lLCBMaXN0PFR5cGU+IGFyZ3R5cGVzLCBMaXN0PFR5cGU+IHR5cGVhcmd0eXBlcykgewogICAgICAgICAgICByZXR1cm4gZGVsZWdhdGVkRXJyb3IuZ2V0RGlhZ25vc3RpYyhka2luZCwgcG9zLCBsb2NhdGlvbiwgc2l0ZSwgbmFtZSwgYXJndHlwZXMsIHR5cGVhcmd0eXBlcyk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQmFkTWV0aG9kUmVmZXJlbmNlRXJyb3IgZXJyb3IgY2xhc3MgaW5kaWNhdGluZyB0aGF0IGEgbWV0aG9kIHJlZmVyZW5jZSBzeW1ib2wgaGFzIGJlZW4gZm91bmQsCiAgICAgKiBidXQgd2l0aCB0aGUgd3Jvbmcgc3RhdGljbmVzcy4KICAgICAqLwogICAgY2xhc3MgQmFkTWV0aG9kUmVmZXJlbmNlRXJyb3IgZXh0ZW5kcyBTdGF0aWNFcnJvciB7CgogICAgICAgIGJvb2xlYW4gdW5ib3VuZExvb2t1cDsKCiAgICAgICAgcHVibGljIEJhZE1ldGhvZFJlZmVyZW5jZUVycm9yKFN5bWJvbCBzeW0sIGJvb2xlYW4gdW5ib3VuZExvb2t1cCkgewogICAgICAgICAgICBzdXBlcihzeW0pOwogICAgICAgICAgICB0aGlzLnVuYm91bmRMb29rdXAgPSB1bmJvdW5kTG9va3VwOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgSkNEaWFnbm9zdGljIGdldERpYWdub3N0aWMoRGlhZ25vc3RpY1R5cGUgZGtpbmQsIERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIFN5bWJvbCBsb2NhdGlvbiwgVHlwZSBzaXRlLCBOYW1lIG5hbWUsIExpc3Q8VHlwZT4gYXJndHlwZXMsIExpc3Q8VHlwZT4gdHlwZWFyZ3R5cGVzKSB7CiAgICAgICAgICAgIGZpbmFsIFN0cmluZyBrZXk7CiAgICAgICAgICAgIGlmICghdW5ib3VuZExvb2t1cCkgewogICAgICAgICAgICAgICAga2V5ID0gImJhZC5zdGF0aWMubWV0aG9kLmluLmJvdW5kLmxvb2t1cCI7CiAgICAgICAgICAgIH0gZWxzZSBpZiAoc3ltLmlzU3RhdGljKCkpIHsKICAgICAgICAgICAgICAgIGtleSA9ICJiYWQuc3RhdGljLm1ldGhvZC5pbi51bmJvdW5kLmxvb2t1cCI7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBrZXkgPSAiYmFkLmluc3RhbmNlLm1ldGhvZC5pbi51bmJvdW5kLmxvb2t1cCI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHN5bS5raW5kLmlzUmVzb2x1dGlvbkVycm9yKCkgPwogICAgICAgICAgICAgICAgICAgICgoUmVzb2x2ZUVycm9yKXN5bSkuZ2V0RGlhZ25vc3RpYyhka2luZCwgcG9zLCBsb2NhdGlvbiwgc2l0ZSwgbmFtZSwgYXJndHlwZXMsIHR5cGVhcmd0eXBlcykgOgogICAgICAgICAgICAgICAgICAgIGRpYWdzLmNyZWF0ZShka2luZCwgbG9nLmN1cnJlbnRTb3VyY2UoKSwgcG9zLCBrZXksIEtpbmRzLmtpbmROYW1lKHN5bSksIHN5bSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQmFkQ29uc3RydWN0b3JSZWZlcmVuY2VFcnJvciBlcnJvciBjbGFzcyBpbmRpY2F0aW5nIHRoYXQgYSBjb25zdHJ1Y3RvciByZWZlcmVuY2Ugc3ltYm9sIGhhcyBiZWVuIGZvdW5kLAogICAgICogYnV0IHBvaW50aW5nIHRvIGEgY2xhc3MgZm9yIHdoaWNoIGFuIGVuY2xvc2luZyBpbnN0YW5jZSBpcyBub3QgYXZhaWxhYmxlLgogICAgICovCiAgICBjbGFzcyBCYWRDb25zdHJ1Y3RvclJlZmVyZW5jZUVycm9yIGV4dGVuZHMgSW52YWxpZFN5bWJvbEVycm9yIHsKCiAgICAgICAgcHVibGljIEJhZENvbnN0cnVjdG9yUmVmZXJlbmNlRXJyb3IoU3ltYm9sIHN5bSkgewogICAgICAgICAgICBzdXBlcihNSVNTSU5HX0VOQ0wsIHN5bSwgIkJhZENvbnN0cnVjdG9yUmVmZXJlbmNlRXJyb3IiKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIEpDRGlhZ25vc3RpYyBnZXREaWFnbm9zdGljKERpYWdub3N0aWNUeXBlIGRraW5kLCBEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBTeW1ib2wgbG9jYXRpb24sIFR5cGUgc2l0ZSwgTmFtZSBuYW1lLCBMaXN0PFR5cGU+IGFyZ3R5cGVzLCBMaXN0PFR5cGU+IHR5cGVhcmd0eXBlcykgewogICAgICAgICAgIHJldHVybiBkaWFncy5jcmVhdGUoZGtpbmQsIGxvZy5jdXJyZW50U291cmNlKCksIHBvcywKICAgICAgICAgICAgICAgICJjYW50LmFjY2Vzcy5pbm5lci5jbHMuY29uc3RyIiwgc2l0ZS50c3ltLm5hbWUsIGFyZ3R5cGVzLCBzaXRlLmdldEVuY2xvc2luZ1R5cGUoKSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogSGVscGVyIGNsYXNzIGZvciBtZXRob2QgcmVzb2x1dGlvbiBkaWFnbm9zdGljIHNpbXBsaWZpY2F0aW9uLgogICAgICogQ2VydGFpbiByZXNvbHV0aW9uIGRpYWdub3N0aWMgYXJlIHJld3JpdHRlbiBhcyBzaW1wbGVyIGRpYWdub3N0aWMKICAgICAqIHdoZXJlIHRoZSBlbmNsb3NpbmcgcmVzb2x1dGlvbiBkaWFnbm9zdGljIChpLmUuICdpbmFwcGxpY2FibGUgbWV0aG9kJykKICAgICAqIGlzIHN0cmlwcGVkIGF3YXksIGFzIGl0IGRvZXNuJ3QgY2FycnkgYWRkaXRpb25hbCBpbmZvLiBUaGUgbG9naWMKICAgICAqIGZvciBtYXRjaGluZyBhIGdpdmVuIGRpYWdub3N0aWMgaXMgZ2l2ZW4gaW4gdGVybXMgb2YgYSB0ZW1wbGF0ZQogICAgICogaGllcmFyY2h5OiBhIGRpYWdub3N0aWMgdGVtcGxhdGUgY2FuIGJlIHNwZWNpZmllZCBwcm9ncmFtbWF0aWNhbGx5LAogICAgICogc28gdGhhdCBvbmx5IGNlcnRhaW4gZGlhZ25vc3RpY3MgYXJlIG1hdGNoZWQuIEVhY2ggdGVtcGxldGUgaXMgdGhlbgogICAgICogYXNzb2NpYXRlZCB3aXRoIGEgcmV3cml0ZXIgb2JqZWN0IHRoYXQgY2FycmllcyBvdXQgdGhlIHRhc2sgb2YgcmV3dGl0aW5nCiAgICAgKiB0aGUgZGlhZ25vc3RpYyB0byBhIHNpbXBsZXIgb25lLgogICAgICovCiAgICBzdGF0aWMgY2xhc3MgTWV0aG9kUmVzb2x1dGlvbkRpYWdIZWxwZXIgewoKICAgICAgICAvKioKICAgICAgICAgKiBBIGRpYWdub3N0aWMgcmV3cml0ZXIgdHJhbnNmb3JtcyBhIG1ldGhvZCByZXNvbHV0aW9uIGRpYWdub3N0aWMKICAgICAgICAgKiBpbnRvIGEgc2ltcGxlciBvbmUKICAgICAgICAgKi8KICAgICAgICBpbnRlcmZhY2UgRGlhZ25vc3RpY1Jld3JpdGVyIHsKICAgICAgICAgICAgSkNEaWFnbm9zdGljIHJld3JpdGVEaWFnbm9zdGljKEpDRGlhZ25vc3RpYy5GYWN0b3J5IGRpYWdzLAogICAgICAgICAgICAgICAgICAgIERpYWdub3N0aWNQb3NpdGlvbiBwcmVmZXJlZFBvcywgRGlhZ25vc3RpY1NvdXJjZSBwcmVmZXJyZWRTb3VyY2UsCiAgICAgICAgICAgICAgICAgICAgRGlhZ25vc3RpY1R5cGUgcHJlZmVycmVkS2luZCwgSkNEaWFnbm9zdGljIGQpOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogQSBkaWFnbm9zdGljIHRlbXBsYXRlIGlzIG1hZGUgdXAgb2YgdHdvIGluZ3JlZGllbnRzOiAoaSkgYSByZWd1bGFyCiAgICAgICAgICogZXhwcmVzc2lvbiBmb3IgbWF0Y2hpbmcgYSBkaWFnbm9zdGljIGtleSBhbmQgKGlpKSBhIGxpc3Qgb2Ygc3ViLXRlbXBsYXRlcwogICAgICAgICAqIGZvciBtYXRjaGluZyBkaWFnbm9zdGljIGFyZ3VtZW50cy4KICAgICAgICAgKi8KICAgICAgICBzdGF0aWMgY2xhc3MgVGVtcGxhdGUgewoKICAgICAgICAgICAgLyoqIHJlZ2V4IHVzZWQgdG8gbWF0Y2ggZGlhZyBrZXkgKi8KICAgICAgICAgICAgU3RyaW5nIHJlZ2V4OwoKICAgICAgICAgICAgLyoqIHRlbXBsYXRlcyB1c2VkIHRvIG1hdGNoIGRpYWdub3N0aWMgYXJncyAqLwogICAgICAgICAgICBUZW1wbGF0ZVtdIHN1YlRlbXBsYXRlczsKCiAgICAgICAgICAgIFRlbXBsYXRlKFN0cmluZyBrZXksIFRlbXBsYXRlLi4uIHN1YlRlbXBsYXRlcykgewogICAgICAgICAgICAgICAgdGhpcy5yZWdleCA9IGtleTsKICAgICAgICAgICAgICAgIHRoaXMuc3ViVGVtcGxhdGVzID0gc3ViVGVtcGxhdGVzOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSByZWdleCBtYXRjaGVzIHRoZSBkaWFnbm9zdGljIGtleSBhbmQgaWYKICAgICAgICAgICAgICogYWxsIGRpYWdub3N0aWMgYXJndW1lbnRzIGFyZSBtYXRjaGVzIGJ5IGNvcnJlc3BvbmRpbmcgc3ViLXRlbXBsYXRlcy4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIGJvb2xlYW4gbWF0Y2hlcyhPYmplY3QgbykgewogICAgICAgICAgICAgICAgSkNEaWFnbm9zdGljIGQgPSAoSkNEaWFnbm9zdGljKW87CiAgICAgICAgICAgICAgICBPYmplY3RbXSBhcmdzID0gZC5nZXRBcmdzKCk7CiAgICAgICAgICAgICAgICBpZiAoIWQuZ2V0Q29kZSgpLm1hdGNoZXMocmVnZXgpIHx8CiAgICAgICAgICAgICAgICAgICAgICAgIHN1YlRlbXBsYXRlcy5sZW5ndGggIT0gZC5nZXRBcmdzKCkubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhcmdzLmxlbmd0aCA7IGkrKykgewogICAgICAgICAgICAgICAgICAgIGlmICghc3ViVGVtcGxhdGVzW2ldLm1hdGNoZXMoYXJnc1tpXSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBDb21tb24gcmV3cml0ZXIgZm9yIGFsbCBhcmd1bWVudCBtaXNtYXRjaCBzaW1wbGlmaWNhdGlvbnMuCiAgICAgICAgICovCiAgICAgICAgc3RhdGljIGNsYXNzIEFyZ01pc21hdGNoUmV3cml0ZXIgaW1wbGVtZW50cyBEaWFnbm9zdGljUmV3cml0ZXIgewoKICAgICAgICAgICAgLyoqIHRoZSBpbmRleCBvZiB0aGUgc3ViZGlhZ25vc3RpYyB0byBiZSB1c2VkIGFzIHByaW1hcnkuICovCiAgICAgICAgICAgIGludCBjYXVzZUluZGV4OwoKICAgICAgICAgICAgcHVibGljIEFyZ01pc21hdGNoUmV3cml0ZXIoaW50IGNhdXNlSW5kZXgpIHsKICAgICAgICAgICAgICAgIHRoaXMuY2F1c2VJbmRleCA9IGNhdXNlSW5kZXg7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgSkNEaWFnbm9zdGljIHJld3JpdGVEaWFnbm9zdGljKEpDRGlhZ25vc3RpYy5GYWN0b3J5IGRpYWdzLAogICAgICAgICAgICAgICAgICAgIERpYWdub3N0aWNQb3NpdGlvbiBwcmVmZXJlZFBvcywgRGlhZ25vc3RpY1NvdXJjZSBwcmVmZXJyZWRTb3VyY2UsCiAgICAgICAgICAgICAgICAgICAgRGlhZ25vc3RpY1R5cGUgcHJlZmVycmVkS2luZCwgSkNEaWFnbm9zdGljIGQpIHsKICAgICAgICAgICAgICAgIEpDRGlhZ25vc3RpYyBjYXVzZSA9IChKQ0RpYWdub3N0aWMpZC5nZXRBcmdzKClbY2F1c2VJbmRleF07CiAgICAgICAgICAgICAgICBEaWFnbm9zdGljUG9zaXRpb24gcG9zID0gZC5nZXREaWFnbm9zdGljUG9zaXRpb24oKTsKICAgICAgICAgICAgICAgIGlmIChwb3MgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIHBvcyA9IHByZWZlcmVkUG9zOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIGRpYWdzLmNyZWF0ZShwcmVmZXJyZWRLaW5kLCBwcmVmZXJyZWRTb3VyY2UsIHBvcywKICAgICAgICAgICAgICAgICAgICAgICAgInByb2IuZm91bmQucmVxIiwgY2F1c2UpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvKiogYSBkdW1teSB0ZW1wbGF0ZSB0aGF0IG1hdGNoIGFueSBkaWFnbm9zdGljIGFyZ3VtZW50ICovCiAgICAgICAgc3RhdGljIGZpbmFsIFRlbXBsYXRlIHNraXAgPSBuZXcgVGVtcGxhdGUoIiIpIHsKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIGJvb2xlYW4gbWF0Y2hlcyhPYmplY3QgZCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9OwoKICAgICAgICAvKiogdGVtcGxhdGUgZm9yIG1hdGNoaW5nIGluZmVyZW5jZS1mcmVlIGFyZ3VtZW50cyBtaXNtYXRjaCBmYWlsdXJlcyAqLwogICAgICAgIHN0YXRpYyBmaW5hbCBUZW1wbGF0ZSBhcmdNaXNtYXRjaFRlbXBsYXRlID0gbmV3IFRlbXBsYXRlKE1ldGhvZENoZWNrRGlhZy5BUkdfTUlTTUFUQ0gucmVnZXgoKSwgc2tpcCk7CgogICAgICAgIC8qKiB0ZW1wbGF0ZSBmb3IgbWF0Y2hpbmcgaW5mZXJlbmNlIHJlbGF0ZWQgYXJndW1lbnRzIG1pc21hdGNoIGZhaWx1cmVzICovCiAgICAgICAgc3RhdGljIGZpbmFsIFRlbXBsYXRlIGluZmVyQXJnTWlzbWF0Y2hUZW1wbGF0ZSA9IG5ldyBUZW1wbGF0ZShNZXRob2RDaGVja0RpYWcuQVJHX01JU01BVENILnJlZ2V4KCksIHNraXAsIHNraXApIHsKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIGJvb2xlYW4gbWF0Y2hlcyhPYmplY3QgbykgewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5tYXRjaGVzKG8pKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgSkNEaWFnbm9zdGljIGQgPSAoSkNEaWFnbm9zdGljKW87CiAgICAgICAgICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKICAgICAgICAgICAgICAgIExpc3Q8VHlwZT4gdHZhcnMgPSAoTGlzdDxUeXBlPilkLmdldEFyZ3MoKVswXTsKICAgICAgICAgICAgICAgIHJldHVybiAhY29udGFpbnNBbnkoZCwgdHZhcnMpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBCaVByZWRpY2F0ZTxPYmplY3QsIExpc3Q8VHlwZT4+IGNvbnRhaW5zUHJlZGljYXRlID0gKG8sIHRzKSAtPiB7CiAgICAgICAgICAgICAgICBpZiAobyBpbnN0YW5jZW9mIFR5cGUpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gKChUeXBlKW8pLmNvbnRhaW5zQW55KHRzKTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAobyBpbnN0YW5jZW9mIEpDRGlhZ25vc3RpYykgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBjb250YWluc0FueSgoSkNEaWFnbm9zdGljKW8sIHRzKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwoKICAgICAgICAgICAgYm9vbGVhbiBjb250YWluc0FueShKQ0RpYWdub3N0aWMgZCwgTGlzdDxUeXBlPiB0cykgewogICAgICAgICAgICAgICAgcmV0dXJuIFN0cmVhbS5vZihkLmdldEFyZ3MoKSkKICAgICAgICAgICAgICAgICAgICAgICAgLmFueU1hdGNoKG8gLT4gY29udGFpbnNQcmVkaWNhdGUudGVzdChvLCB0cykpOwogICAgICAgICAgICB9CiAgICAgICAgfTsKCiAgICAgICAgLyoqIHJld3JpdGVyIG1hcCB1c2VkIGZvciBtZXRob2QgcmVzb2x1dGlvbiBzaW1wbGlmaWNhdGlvbiAqLwogICAgICAgIHN0YXRpYyBmaW5hbCBNYXA8VGVtcGxhdGUsIERpYWdub3N0aWNSZXdyaXRlcj4gcmV3cml0ZXJzID0gbmV3IExpbmtlZEhhc2hNYXA8PigpOwoKICAgICAgICBzdGF0aWMgewogICAgICAgICAgICByZXdyaXRlcnMucHV0KGFyZ01pc21hdGNoVGVtcGxhdGUsIG5ldyBBcmdNaXNtYXRjaFJld3JpdGVyKDApKTsKICAgICAgICAgICAgcmV3cml0ZXJzLnB1dChpbmZlckFyZ01pc21hdGNoVGVtcGxhdGUsIG5ldyBBcmdNaXNtYXRjaFJld3JpdGVyKDEpKTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIE1haW4gZW50cnkgcG9pbnQgZm9yIGRpYWdub3N0aWMgcmV3cml0aW5nIC0gZ2l2ZW4gYSBkaWFnbm9zdGljLCBzZWUgaWYgYW55IHRlbXBsYXRlcyBtYXRjaGVzIGl0LAogICAgICAgICAqIGFuZCByZXdyaXRlIGl0IGFjY29yZGluZ2x5LgogICAgICAgICAqLwogICAgICAgIHN0YXRpYyBKQ0RpYWdub3N0aWMgcmV3cml0ZShKQ0RpYWdub3N0aWMuRmFjdG9yeSBkaWFncywgRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcywgRGlhZ25vc3RpY1NvdXJjZSBzb3VyY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERpYWdub3N0aWNUeXBlIGRraW5kLCBKQ0RpYWdub3N0aWMgZCkgewogICAgICAgICAgICBmb3IgKE1hcC5FbnRyeTxUZW1wbGF0ZSwgRGlhZ25vc3RpY1Jld3JpdGVyPiBfZW50cnkgOiByZXdyaXRlcnMuZW50cnlTZXQoKSkgewogICAgICAgICAgICAgICAgaWYgKF9lbnRyeS5nZXRLZXkoKS5tYXRjaGVzKGQpKSB7CiAgICAgICAgICAgICAgICAgICAgSkNEaWFnbm9zdGljIHNpbXBsZURpYWcgPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgX2VudHJ5LmdldFZhbHVlKCkucmV3cml0ZURpYWdub3N0aWMoZGlhZ3MsIHBvcywgc291cmNlLCBka2luZCwgZCk7CiAgICAgICAgICAgICAgICAgICAgc2ltcGxlRGlhZy5zZXRGbGFnKERpYWdub3N0aWNGbGFnLkNPTVBSRVNTRUQpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBzaW1wbGVEaWFnOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KICAgIH0KCiAgICBlbnVtIE1ldGhvZFJlc29sdXRpb25QaGFzZSB7CiAgICAgICAgQkFTSUMoZmFsc2UsIGZhbHNlKSwKICAgICAgICBCT1godHJ1ZSwgZmFsc2UpLAogICAgICAgIFZBUkFSSVRZKHRydWUsIHRydWUpIHsKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHB1YmxpYyBTeW1ib2wgbWVyZ2VSZXN1bHRzKFN5bWJvbCBiZXN0U29GYXIsIFN5bWJvbCBzeW0pIHsKICAgICAgICAgICAgICAgIC8vQ2hlY2sgaW52YXJpYW50cyAoc2VlIHtAY29kZSBMb29rdXBIZWxwZXIuc2hvdWxkU3RvcH0pCiAgICAgICAgICAgICAgICBBc3NlcnQuY2hlY2soYmVzdFNvRmFyLmtpbmQuaXNSZXNvbHV0aW9uRXJyb3IoKSAmJiBiZXN0U29GYXIua2luZCAhPSBBTUJJR1VPVVMpOwogICAgICAgICAgICAgICAgaWYgKCFzeW0ua2luZC5pc1Jlc29sdXRpb25FcnJvcigpKSB7CiAgICAgICAgICAgICAgICAgICAgLy92YXJhcmdzIHJlc29sdXRpb24gc3VjY2Vzc2Z1bAogICAgICAgICAgICAgICAgICAgIHJldHVybiBzeW07CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIC8vcGljayBiZXN0IGVycm9yCiAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChiZXN0U29GYXIua2luZCkgewogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFdST05HX01USDoKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBXUk9OR19NVEhTOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9PdmVycmlkZSBwcmV2aW91cyBlcnJvcnMgaWYgdGhleSB3ZXJlIGNhdXNlZCBieSBhcmd1bWVudCBtaXNtYXRjaC4KICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vVGhpcyBnZW5lcmFsbHkgbWVhbnMgcHJlZmVycmluZyBjdXJyZW50IHN5bWJvbHMgLSBidXQgd2UgbmVlZCB0byBwYXkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vYXR0ZW50aW9uIHRvIHRoZSBmYWN0IHRoYXQgdGhlIHZhcmFyZ3MgbG9va3VwIHJldHVybnMgJ2xlc3MnIGNhbmRpZGF0ZXMKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vdGhhbiB0aGUgcHJldmlvdXMgcm91bmRzLCBhbmQgYWRqdXN0IHRoYXQgYWNjb3JkaW5nbHkuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKHN5bS5raW5kKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBXUk9OR19NVEg6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vaWYgdGhlIHByZXZpb3VzIHJvdW5kIG1hdGNoZWQgbW9yZSB0aGFuIG9uZSBtZXRob2QsIHJldHVybiB0aGF0CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vcmVzdWx0IGluc3RlYWQKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGJlc3RTb0Zhci5raW5kID09IFdST05HX01USFMgPwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJlc3RTb0ZhciA6IHN5bTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIEFCU0VOVF9NVEg6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vZG8gbm90IG92ZXJyaWRlIGVycm9uZW91cyBzeW1ib2wgaWYgdGhlIGFyaXR5IGxvb2t1cCBkaWQgbm90CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vbWF0Y2ggYW55IG1ldGhvZAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYmVzdFNvRmFyOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgV1JPTkdfTVRIUzoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3NhZmUgdG8gb3ZlcnJpZGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHN5bTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vb3RoZXJ3aXNlLCByZXR1cm4gZmlyc3QgZXJyb3IKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBiZXN0U29GYXI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfTsKCiAgICAgICAgZmluYWwgYm9vbGVhbiBpc0JveGluZ1JlcXVpcmVkOwogICAgICAgIGZpbmFsIGJvb2xlYW4gaXNWYXJhcmdzUmVxdWlyZWQ7CgogICAgICAgIE1ldGhvZFJlc29sdXRpb25QaGFzZShib29sZWFuIGlzQm94aW5nUmVxdWlyZWQsIGJvb2xlYW4gaXNWYXJhcmdzUmVxdWlyZWQpIHsKICAgICAgICAgICB0aGlzLmlzQm94aW5nUmVxdWlyZWQgPSBpc0JveGluZ1JlcXVpcmVkOwogICAgICAgICAgIHRoaXMuaXNWYXJhcmdzUmVxdWlyZWQgPSBpc1ZhcmFyZ3NSZXF1aXJlZDsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBib29sZWFuIGlzQm94aW5nUmVxdWlyZWQoKSB7CiAgICAgICAgICAgIHJldHVybiBpc0JveGluZ1JlcXVpcmVkOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIGJvb2xlYW4gaXNWYXJhcmdzUmVxdWlyZWQoKSB7CiAgICAgICAgICAgIHJldHVybiBpc1ZhcmFyZ3NSZXF1aXJlZDsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBTeW1ib2wgbWVyZ2VSZXN1bHRzKFN5bWJvbCBwcmV2LCBTeW1ib2wgc3ltKSB7CiAgICAgICAgICAgIHJldHVybiBzeW07CiAgICAgICAgfQogICAgfQoKICAgIGZpbmFsIExpc3Q8TWV0aG9kUmVzb2x1dGlvblBoYXNlPiBtZXRob2RSZXNvbHV0aW9uU3RlcHMgPSBMaXN0Lm9mKEJBU0lDLCBCT1gsIFZBUkFSSVRZKTsKCiAgICAvKioKICAgICAqIEEgcmVzb2x1dGlvbiBjb250ZXh0IGlzIHVzZWQgdG8ga2VlcCB0cmFjayBvZiBpbnRlcm1lZGlhdGUgcmVzdWx0cyBvZgogICAgICogb3ZlcmxvYWQgcmVzb2x1dGlvbiwgc3VjaCBhcyBsaXN0IG9mIG1ldGhvZCB0aGF0IGFyZSBub3QgYXBwbGljYWJsZQogICAgICogKHVzZWQgdG8gZ2VuZXJhdGUgbW9yZSBwcmVjaXNlIGRpYWdub3N0aWNzKSBhbmQgc28gb24uIFJlc29sdXRpb24gY29udGV4dHMKICAgICAqIGNhbiBiZSBuZXN0ZWQgLSB0aGlzIG1lYW5zIHRoYXQgd2hlbiBlYWNoIG92ZXJsb2FkIHJlc29sdXRpb24gcm91dGluZSBzaG91bGQKICAgICAqIHdvcmsgd2l0aGluIHRoZSByZXNvbHV0aW9uIGNvbnRleHQgaXQgY3JlYXRlZC4KICAgICAqLwogICAgY2xhc3MgTWV0aG9kUmVzb2x1dGlvbkNvbnRleHQgewoKICAgICAgICBwcml2YXRlIExpc3Q8Q2FuZGlkYXRlPiBjYW5kaWRhdGVzID0gTGlzdC5uaWwoKTsKCiAgICAgICAgTWV0aG9kUmVzb2x1dGlvblBoYXNlIHN0ZXAgPSBudWxsOwoKICAgICAgICBNZXRob2RDaGVjayBtZXRob2RDaGVjayA9IHJlc29sdmVNZXRob2RDaGVjazsKCiAgICAgICAgcHJpdmF0ZSBib29sZWFuIGludGVybmFsUmVzb2x1dGlvbiA9IGZhbHNlOwogICAgICAgIHByaXZhdGUgRGVmZXJyZWRBdHRyLkF0dHJNb2RlIGF0dHJNb2RlID0gRGVmZXJyZWRBdHRyLkF0dHJNb2RlLlNQRUNVTEFUSVZFOwoKICAgICAgICB2b2lkIGFkZEluYXBwbGljYWJsZUNhbmRpZGF0ZShTeW1ib2wgc3ltLCBKQ0RpYWdub3N0aWMgZGV0YWlscykgewogICAgICAgICAgICBDYW5kaWRhdGUgYyA9IG5ldyBDYW5kaWRhdGUoY3VycmVudFJlc29sdXRpb25Db250ZXh0LnN0ZXAsIHN5bSwgZGV0YWlscywgbnVsbCk7CiAgICAgICAgICAgIGNhbmRpZGF0ZXMgPSBjYW5kaWRhdGVzLmFwcGVuZChjKTsKICAgICAgICB9CgogICAgICAgIHZvaWQgYWRkQXBwbGljYWJsZUNhbmRpZGF0ZShTeW1ib2wgc3ltLCBUeXBlIG10eXBlKSB7CiAgICAgICAgICAgIENhbmRpZGF0ZSBjID0gbmV3IENhbmRpZGF0ZShjdXJyZW50UmVzb2x1dGlvbkNvbnRleHQuc3RlcCwgc3ltLCBudWxsLCBtdHlwZSk7CiAgICAgICAgICAgIGNhbmRpZGF0ZXMgPSBjYW5kaWRhdGVzLmFwcGVuZChjKTsKICAgICAgICB9CgogICAgICAgIERlZmVycmVkQXR0ckNvbnRleHQgZGVmZXJyZWRBdHRyQ29udGV4dChTeW1ib2wgc3ltLCBJbmZlcmVuY2VDb250ZXh0IGluZmVyZW5jZUNvbnRleHQsIFJlc3VsdEluZm8gcGVuZGluZ1Jlc3VsdCwgV2FybmVyIHdhcm4pIHsKICAgICAgICAgICAgRGVmZXJyZWRBdHRyQ29udGV4dCBwYXJlbnQgPSAocGVuZGluZ1Jlc3VsdCA9PSBudWxsKQogICAgICAgICAgICAgICAgPyBkZWZlcnJlZEF0dHIuZW1wdHlEZWZlcnJlZEF0dHJDb250ZXh0CiAgICAgICAgICAgICAgICA6IHBlbmRpbmdSZXN1bHQuY2hlY2tDb250ZXh0LmRlZmVycmVkQXR0ckNvbnRleHQoKTsKICAgICAgICAgICAgcmV0dXJuIGRlZmVycmVkQXR0ci5uZXcgRGVmZXJyZWRBdHRyQ29udGV4dChhdHRyTW9kZSwgc3ltLCBzdGVwLAogICAgICAgICAgICAgICAgICAgIGluZmVyZW5jZUNvbnRleHQsIHBhcmVudCwgd2Fybik7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBUaGlzIGNsYXNzIHJlcHJlc2VudHMgYW4gb3ZlcmxvYWQgcmVzb2x1dGlvbiBjYW5kaWRhdGUuIFRoZXJlIGFyZSB0d28KICAgICAgICAgKiBraW5kcyBvZiBjYW5kaWRhdGVzOiBhcHBsaWNhYmxlIG1ldGhvZHMgYW5kIGluYXBwbGljYWJsZSBtZXRob2RzOwogICAgICAgICAqIGFwcGxpY2FibGUgbWV0aG9kcyBoYXZlIGEgcG9pbnRlciB0byB0aGUgaW5zdGFudGlhdGVkIG1ldGhvZCB0eXBlLAogICAgICAgICAqIHdoaWxlIGluYXBwbGljYWJsZSBjYW5kaWRhdGVzIGNvbnRhaW4gZnVydGhlciBkZXRhaWxzIGFib3V0IHRoZQogICAgICAgICAqIHJlYXNvbiB3aHkgdGhlIG1ldGhvZCBoYXMgYmVlbiBjb25zaWRlcmVkIGluYXBwbGljYWJsZS4KICAgICAgICAgKi8KICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygib3ZlcnJpZGVzIikKICAgICAgICBjbGFzcyBDYW5kaWRhdGUgewoKICAgICAgICAgICAgZmluYWwgTWV0aG9kUmVzb2x1dGlvblBoYXNlIHN0ZXA7CiAgICAgICAgICAgIGZpbmFsIFN5bWJvbCBzeW07CiAgICAgICAgICAgIGZpbmFsIEpDRGlhZ25vc3RpYyBkZXRhaWxzOwogICAgICAgICAgICBmaW5hbCBUeXBlIG10eXBlOwoKICAgICAgICAgICAgcHJpdmF0ZSBDYW5kaWRhdGUoTWV0aG9kUmVzb2x1dGlvblBoYXNlIHN0ZXAsIFN5bWJvbCBzeW0sIEpDRGlhZ25vc3RpYyBkZXRhaWxzLCBUeXBlIG10eXBlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnN0ZXAgPSBzdGVwOwogICAgICAgICAgICAgICAgdGhpcy5zeW0gPSBzeW07CiAgICAgICAgICAgICAgICB0aGlzLmRldGFpbHMgPSBkZXRhaWxzOwogICAgICAgICAgICAgICAgdGhpcy5tdHlwZSA9IG10eXBlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvKSB7CiAgICAgICAgICAgICAgICBpZiAobyBpbnN0YW5jZW9mIENhbmRpZGF0ZSkgewogICAgICAgICAgICAgICAgICAgIFN5bWJvbCBzMSA9IHRoaXMuc3ltOwogICAgICAgICAgICAgICAgICAgIFN5bWJvbCBzMiA9ICgoQ2FuZGlkYXRlKW8pLnN5bTsKICAgICAgICAgICAgICAgICAgICBpZiAgKChzMSAhPSBzMiAmJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgKHMxLm92ZXJyaWRlcyhzMiwgczEub3duZXIudHlwZS50c3ltLCB0eXBlcywgZmFsc2UpIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoczIub3ZlcnJpZGVzKHMxLCBzMi5vd25lci50eXBlLnRzeW0sIHR5cGVzLCBmYWxzZSkpKSkgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoczEuaXNDb25zdHJ1Y3RvcigpIHx8IHMyLmlzQ29uc3RydWN0b3IoKSkgJiYgczEub3duZXIgIT0gczIub3duZXIpKQogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgYm9vbGVhbiBpc0FwcGxpY2FibGUoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gbXR5cGUgIT0gbnVsbDsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgRGVmZXJyZWRBdHRyLkF0dHJNb2RlIGF0dHJNb2RlKCkgewogICAgICAgICAgICByZXR1cm4gYXR0ck1vZGU7CiAgICAgICAgfQoKICAgICAgICBib29sZWFuIGludGVybmFsKCkgewogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxSZXNvbHV0aW9uOwogICAgICAgIH0KICAgIH0KCiAgICBNZXRob2RSZXNvbHV0aW9uQ29udGV4dCBjdXJyZW50UmVzb2x1dGlvbkNvbnRleHQgPSBudWxsOwp9ClBLAwQKAAAIAAAGO6lK1L00mhFLAAARSwAAJgAAAGNvbS9zdW4vdG9vbHMvamF2YWMvY29tcC9BbmFseXplci5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDE0LCAyMDE1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuamF2YWMuY29tcDsKCmltcG9ydCBjb20uc3VuLnNvdXJjZS50cmVlLkxhbWJkYUV4cHJlc3Npb25UcmVlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlNvdXJjZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5UeXBlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlR5cGVzOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb21wLkFyZ3VtZW50QXR0ci5Mb2NhbENhY2hlQ29udGV4dDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5KQ1RyZWU7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuSkNUcmVlLkpDQmxvY2s7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuSkNUcmVlLkpDQ2xhc3NEZWNsOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkpDVHJlZS5KQ0RvV2hpbGVMb29wOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkpDVHJlZS5KQ0VuaGFuY2VkRm9yTG9vcDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5KQ1RyZWUuSkNGb3JMb29wOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkpDVHJlZS5KQ0lmOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkpDVHJlZS5KQ0xhbWJkYTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5KQ1RyZWUuSkNMYW1iZGEuUGFyYW1ldGVyS2luZDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5KQ1RyZWUuSkNNZXRob2REZWNsOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkpDVHJlZS5KQ01ldGhvZEludm9jYXRpb247CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuSkNUcmVlLkpDTmV3Q2xhc3M7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuSkNUcmVlLkpDU3RhdGVtZW50OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkpDVHJlZS5KQ1N3aXRjaDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5KQ1RyZWUuSkNUeXBlQXBwbHk7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuSkNUcmVlLkpDVmFyaWFibGVEZWNsOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkpDVHJlZS5KQ1doaWxlTG9vcDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5KQ1RyZWUuVGFnOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLlRyZWVDb3BpZXI7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuVHJlZUluZm87CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuVHJlZU1ha2VyOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLlRyZWVTY2FubmVyOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkNvbnRleHQ7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuRGVmaW5lZEJ5OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkRlZmluZWRCeS5BcGk7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuSkNEaWFnbm9zdGljOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkpDRGlhZ25vc3RpYy5EaWFnbm9zdGljVHlwZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5MaXN0OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkxpc3RCdWZmZXI7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuTG9nOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLk5hbWVzOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLk9wdGlvbnM7CgppbXBvcnQgamF2YS51dGlsLkVudW1TZXQ7CmltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKaW1wb3J0IGphdmEudXRpbC5NYXA7CmltcG9ydCBqYXZhLnV0aWwuZnVuY3Rpb24uUHJlZGljYXRlOwoKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuRmxhZ3MuR0VORVJBVEVEQ09OU1RSOwppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5GbGFncy5TWU5USEVUSUM7CmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlR5cGVUYWcuQ0xBU1M7CmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkpDVHJlZS5UYWcuQVBQTFk7CmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkpDVHJlZS5UYWcuTUVUSE9EREVGOwppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5KQ1RyZWUuVGFnLk5FV0NMQVNTOwppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5KQ1RyZWUuVGFnLlRZUEVBUFBMWTsKCi8qKgogKiBIZWxwZXIgY2xhc3MgZm9yIGRlZmluaW5nIGN1c3RvbSBjb2RlIGFuYWx5c2lzLCBzdWNoIGFzIGZpbmRpbmcgaW5zdGFuY2UgY3JlYXRpb24gZXhwcmVzc2lvbgogKiB0aGF0IGNhbiBiZW5lZml0IGZyb20gZGlhbW9uZCBzeW50YXguCiAqLwpwdWJsaWMgY2xhc3MgQW5hbHl6ZXIgewogICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBDb250ZXh0LktleTxBbmFseXplcj4gYW5hbHl6ZXJLZXkgPSBuZXcgQ29udGV4dC5LZXk8PigpOwoKICAgIGZpbmFsIFR5cGVzIHR5cGVzOwogICAgZmluYWwgTG9nIGxvZzsKICAgIGZpbmFsIEF0dHIgYXR0cjsKICAgIGZpbmFsIERlZmVycmVkQXR0ciBkZWZlcnJlZEF0dHI7CiAgICBmaW5hbCBBcmd1bWVudEF0dHIgYXJndW1lbnRBdHRyOwogICAgZmluYWwgVHJlZU1ha2VyIG1ha2U7CiAgICBmaW5hbCBOYW1lcyBuYW1lczsKICAgIHByaXZhdGUgZmluYWwgYm9vbGVhbiBhbGxvd0RpYW1vbmRXaXRoQW5vbnltb3VzQ2xhc3NDcmVhdGlvbjsKCiAgICBmaW5hbCBFbnVtU2V0PEFuYWx5emVyTW9kZT4gYW5hbHl6ZXJNb2RlczsKCiAgICBwdWJsaWMgc3RhdGljIEFuYWx5emVyIGluc3RhbmNlKENvbnRleHQgY29udGV4dCkgewogICAgICAgIEFuYWx5emVyIGluc3RhbmNlID0gY29udGV4dC5nZXQoYW5hbHl6ZXJLZXkpOwogICAgICAgIGlmIChpbnN0YW5jZSA9PSBudWxsKQogICAgICAgICAgICBpbnN0YW5jZSA9IG5ldyBBbmFseXplcihjb250ZXh0KTsKICAgICAgICByZXR1cm4gaW5zdGFuY2U7CiAgICB9CgogICAgcHJvdGVjdGVkIEFuYWx5emVyKENvbnRleHQgY29udGV4dCkgewogICAgICAgIGNvbnRleHQucHV0KGFuYWx5emVyS2V5LCB0aGlzKTsKICAgICAgICB0eXBlcyA9IFR5cGVzLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIGxvZyA9IExvZy5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBhdHRyID0gQXR0ci5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBkZWZlcnJlZEF0dHIgPSBEZWZlcnJlZEF0dHIuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgYXJndW1lbnRBdHRyID0gQXJndW1lbnRBdHRyLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIG1ha2UgPSBUcmVlTWFrZXIuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgbmFtZXMgPSBOYW1lcy5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBPcHRpb25zIG9wdGlvbnMgPSBPcHRpb25zLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIFN0cmluZyBmaW5kT3B0ID0gb3B0aW9ucy5nZXQoImZpbmQiKTsKICAgICAgICAvL3BhcnNlIG1vZGVzCiAgICAgICAgU291cmNlIHNvdXJjZSA9IFNvdXJjZS5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBhbGxvd0RpYW1vbmRXaXRoQW5vbnltb3VzQ2xhc3NDcmVhdGlvbiA9IHNvdXJjZS5hbGxvd0RpYW1vbmRXaXRoQW5vbnltb3VzQ2xhc3NDcmVhdGlvbigpOwogICAgICAgIGFuYWx5emVyTW9kZXMgPSBBbmFseXplck1vZGUuZ2V0QW5hbHl6ZXJNb2RlcyhmaW5kT3B0LCBzb3VyY2UpOwogICAgfQoKICAgIC8qKgogICAgICogVGhpcyBlbnVtIGRlZmluZXMgc3VwcG9ydGVkIGFuYWx5emVyIG1vZGVzLCBhcyB3ZWxsIGFzIGRlZmluaW5nIHRoZSBsb2dpYyBmb3IgZGVjb2RpbmcKICAgICAqIHRoZSB7QGNvZGUgLVhEZmluZH0gb3B0aW9uLgogICAgICovCiAgICBlbnVtIEFuYWx5emVyTW9kZSB7CiAgICAgICAgRElBTU9ORCgiZGlhbW9uZCIsIFNvdXJjZTo6YWxsb3dEaWFtb25kKSwKICAgICAgICBMQU1CREEoImxhbWJkYSIsIFNvdXJjZTo6YWxsb3dMYW1iZGEpLAogICAgICAgIE1FVEhPRCgibWV0aG9kIiwgU291cmNlOjphbGxvd0dyYXBoSW5mZXJlbmNlKTsKCiAgICAgICAgZmluYWwgU3RyaW5nIG9wdDsKICAgICAgICBmaW5hbCBQcmVkaWNhdGU8U291cmNlPiBzb3VyY2VGaWx0ZXI7CgogICAgICAgIEFuYWx5emVyTW9kZShTdHJpbmcgb3B0LCBQcmVkaWNhdGU8U291cmNlPiBzb3VyY2VGaWx0ZXIpIHsKICAgICAgICAgICAgdGhpcy5vcHQgPSBvcHQ7CiAgICAgICAgICAgIHRoaXMuc291cmNlRmlsdGVyID0gc291cmNlRmlsdGVyOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogVGhpcyBtZXRob2QgaXMgdXNlZCB0byBwYXJzZSB0aGUge0Bjb2RlIGZpbmR9IG9wdGlvbi4KICAgICAgICAgKiBQb3NzaWJsZSBtb2RlcyBhcmUgc2VwYXJhdGVkIGJ5IGNvbG9uOyBhIG1vZGUgY2FuIGJlIGV4Y2x1ZGVkIGJ5CiAgICAgICAgICogcHJlcGVuZGluZyAnLScgdG8gaXRzIG5hbWUuIEZpbmFsbHksIHRoZSBzcGVjaWFsIG1vZGUgJ2FsbCcgY2FuIGJlIHVzZWQgdG8KICAgICAgICAgKiBhZGQgYWxsIG1vZGVzIHRvIHRoZSByZXN1bHRpbmcgZW51bS4KICAgICAgICAgKi8KICAgICAgICBzdGF0aWMgRW51bVNldDxBbmFseXplck1vZGU+IGdldEFuYWx5emVyTW9kZXMoU3RyaW5nIG9wdCwgU291cmNlIHNvdXJjZSkgewogICAgICAgICAgICBpZiAob3B0ID09IG51bGwpIHsKICAgICAgICAgICAgICAgIHJldHVybiBFbnVtU2V0Lm5vbmVPZihBbmFseXplck1vZGUuY2xhc3MpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIExpc3Q8U3RyaW5nPiBtb2RlcyA9IExpc3QuZnJvbShvcHQuc3BsaXQoIiwiKSk7CiAgICAgICAgICAgIEVudW1TZXQ8QW5hbHl6ZXJNb2RlPiByZXMgPSBFbnVtU2V0Lm5vbmVPZihBbmFseXplck1vZGUuY2xhc3MpOwogICAgICAgICAgICBpZiAobW9kZXMuY29udGFpbnMoImFsbCIpKSB7CiAgICAgICAgICAgICAgICByZXMgPSBFbnVtU2V0LmFsbE9mKEFuYWx5emVyTW9kZS5jbGFzcyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZm9yIChBbmFseXplck1vZGUgbW9kZSA6IHZhbHVlcygpKSB7CiAgICAgICAgICAgICAgICBpZiAobW9kZXMuY29udGFpbnMobW9kZS5vcHQpKSB7CiAgICAgICAgICAgICAgICAgICAgcmVzLmFkZChtb2RlKTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAobW9kZXMuY29udGFpbnMoIi0iICsgbW9kZS5vcHQpIHx8ICFtb2RlLnNvdXJjZUZpbHRlci50ZXN0KHNvdXJjZSkpIHsKICAgICAgICAgICAgICAgICAgICByZXMucmVtb3ZlKG1vZGUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiByZXM7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQSBzdGF0ZW1lbnQgYW5hbHl6ZXIgaXMgYSB3b3JrLXVuaXQgdGhhdCBtYXRjaGVzIGNlcnRhaW4gQVNUIG5vZGVzIChvZiBnaXZlbiB0eXBlIHtAY29kZSBTfSksCiAgICAgKiByZXdyaXRlcyB0aGVtIHRvIGRpZmZlcmVudCBBU1Qgbm9kZXMgKG9mIHR5cGUge0Bjb2RlIFR9KSBhbmQgdGhlbiBnZW5lcmF0ZXMgc29tZSBtZWFuaW5nZnVsCiAgICAgKiBtZXNzYWdlcyBpbiBjYXNlIHRoZSBhbmFseXNpcyBoYXMgYmVlbiBzdWNjZXNzZnVsLgogICAgICovCiAgICBhYnN0cmFjdCBjbGFzcyBTdGF0ZW1lbnRBbmFseXplcjxTIGV4dGVuZHMgSkNUcmVlLCBUIGV4dGVuZHMgSkNUcmVlPiB7CgogICAgICAgIEFuYWx5emVyTW9kZSBtb2RlOwogICAgICAgIEpDVHJlZS5UYWcgdGFnOwoKICAgICAgICBTdGF0ZW1lbnRBbmFseXplcihBbmFseXplck1vZGUgbW9kZSwgVGFnIHRhZykgewogICAgICAgICAgICB0aGlzLm1vZGUgPSBtb2RlOwogICAgICAgICAgICB0aGlzLnRhZyA9IHRhZzsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIElzIHRoaXMgYW5hbHl6ZXIgYWxsb3dlZCB0byBydW4/CiAgICAgICAgICovCiAgICAgICAgYm9vbGVhbiBpc0VuYWJsZWQoKSB7CiAgICAgICAgICAgIHJldHVybiBhbmFseXplck1vZGVzLmNvbnRhaW5zKG1vZGUpOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogU2hvdWxkIHRoaXMgYW5hbHl6ZXIgYmUgcmV3cml0aW5nIHRoZSBnaXZlbiB0cmVlPwogICAgICAgICAqLwogICAgICAgIGFic3RyYWN0IGJvb2xlYW4gbWF0Y2goUyB0cmVlKTsKCiAgICAgICAgLyoqCiAgICAgICAgICogUmV3cml0ZSBhIGdpdmVuIEFTVCBub2RlIGludG8gYSBuZXcgb25lCiAgICAgICAgICovCiAgICAgICAgYWJzdHJhY3QgVCBtYXAoUyBvbGRUcmVlLCBTIG5ld1RyZWUpOwoKICAgICAgICAvKioKICAgICAgICAgKiBFbnRyeS1wb2ludCBmb3IgY29tcGFyaW5nIHJlc3VsdHMgYW5kIGdlbmVyYXRpbmcgZGlhZ25vc3RpY3MuCiAgICAgICAgICovCiAgICAgICAgYWJzdHJhY3Qgdm9pZCBwcm9jZXNzKFMgb2xkVHJlZSwgVCBuZXdUcmVlLCBib29sZWFuIGhhc0Vycm9ycyk7CgogICAgfQoKICAgIC8qKgogICAgICogVGhpcyBhbmFseXplciBjaGVja3MgaWYgZ2VuZXJpYyBpbnN0YW5jZSBjcmVhdGlvbiBleHByZXNzaW9uIGNhbiB1c2UgZGlhbW9uZCBzeW50YXguCiAgICAgKi8KICAgIGNsYXNzIERpYW1vbmRJbml0aWFsaXplciBleHRlbmRzIFN0YXRlbWVudEFuYWx5emVyPEpDTmV3Q2xhc3MsIEpDTmV3Q2xhc3M+IHsKCiAgICAgICAgRGlhbW9uZEluaXRpYWxpemVyKCkgewogICAgICAgICAgICBzdXBlcihBbmFseXplck1vZGUuRElBTU9ORCwgTkVXQ0xBU1MpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgYm9vbGVhbiBtYXRjaChKQ05ld0NsYXNzIHRyZWUpIHsKICAgICAgICAgICAgcmV0dXJuIHRyZWUuY2xhenouaGFzVGFnKFRZUEVBUFBMWSkgJiYKICAgICAgICAgICAgICAgICAgICAhVHJlZUluZm8uaXNEaWFtb25kKHRyZWUpICYmCiAgICAgICAgICAgICAgICAgICAgKHRyZWUuZGVmID09IG51bGwgfHwgYWxsb3dEaWFtb25kV2l0aEFub255bW91c0NsYXNzQ3JlYXRpb24pOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgSkNOZXdDbGFzcyBtYXAoSkNOZXdDbGFzcyBvbGRUcmVlLCBKQ05ld0NsYXNzIG5ld1RyZWUpIHsKICAgICAgICAgICAgaWYgKG5ld1RyZWUuY2xhenouaGFzVGFnKFRZUEVBUFBMWSkpIHsKICAgICAgICAgICAgICAgICgoSkNUeXBlQXBwbHkpbmV3VHJlZS5jbGF6eikuYXJndW1lbnRzID0gTGlzdC5uaWwoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gbmV3VHJlZTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHZvaWQgcHJvY2VzcyhKQ05ld0NsYXNzIG9sZFRyZWUsIEpDTmV3Q2xhc3MgbmV3VHJlZSwgYm9vbGVhbiBoYXNFcnJvcnMpIHsKICAgICAgICAgICAgaWYgKCFoYXNFcnJvcnMpIHsKICAgICAgICAgICAgICAgIExpc3Q8VHlwZT4gaW5mZXJyZWRBcmdzLCBleHBsaWNpdEFyZ3M7CiAgICAgICAgICAgICAgICBpZiAob2xkVHJlZS5kZWYgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIGluZmVycmVkQXJncyA9IG5ld1RyZWUuZGVmLmltcGxlbWVudGluZy5ub25FbXB0eSgpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBuZXdUcmVlLmRlZi5pbXBsZW1lbnRpbmcuZ2V0KDApLnR5cGUuZ2V0VHlwZUFyZ3VtZW50cygpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBuZXdUcmVlLmRlZi5leHRlbmRpbmcudHlwZS5nZXRUeXBlQXJndW1lbnRzKCk7CiAgICAgICAgICAgICAgICAgICAgZXhwbGljaXRBcmdzID0gb2xkVHJlZS5kZWYuaW1wbGVtZW50aW5nLm5vbkVtcHR5KCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IG9sZFRyZWUuZGVmLmltcGxlbWVudGluZy5nZXQoMCkudHlwZS5nZXRUeXBlQXJndW1lbnRzKCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IG9sZFRyZWUuZGVmLmV4dGVuZGluZy50eXBlLmdldFR5cGVBcmd1bWVudHMoKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgaW5mZXJyZWRBcmdzID0gbmV3VHJlZS50eXBlLmdldFR5cGVBcmd1bWVudHMoKTsKICAgICAgICAgICAgICAgICAgICBleHBsaWNpdEFyZ3MgPSBvbGRUcmVlLnR5cGUuZ2V0VHlwZUFyZ3VtZW50cygpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZm9yIChUeXBlIHQgOiBpbmZlcnJlZEFyZ3MpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoIXR5cGVzLmlzU2FtZVR5cGUodCwgZXhwbGljaXRBcmdzLmhlYWQpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZXhwbGljaXRBcmdzID0gZXhwbGljaXRBcmdzLnRhaWw7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvL2V4YWN0IG1hdGNoCiAgICAgICAgICAgICAgICBsb2cud2FybmluZyhvbGRUcmVlLmNsYXp6LCAiZGlhbW9uZC5yZWR1bmRhbnQuYXJncyIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogVGhpcyBhbmFseXplciBjaGVja3MgaWYgYW5vbnltb3VzIGluc3RhbmNlIGNyZWF0aW9uIGV4cHJlc3Npb24gY2FuIHJlcGxhY2VkIGJ5IGxhbWJkYS4KICAgICAqLwogICAgY2xhc3MgTGFtYmRhQW5hbHl6ZXIgZXh0ZW5kcyBTdGF0ZW1lbnRBbmFseXplcjxKQ05ld0NsYXNzLCBKQ0xhbWJkYT4gewoKICAgICAgICBMYW1iZGFBbmFseXplcigpIHsKICAgICAgICAgICAgc3VwZXIoQW5hbHl6ZXJNb2RlLkxBTUJEQSwgTkVXQ0xBU1MpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgYm9vbGVhbiBtYXRjaCAoSkNOZXdDbGFzcyB0cmVlKXsKICAgICAgICAgICAgVHlwZSBjbGF6enR5cGUgPSB0cmVlLmNsYXp6LnR5cGU7CiAgICAgICAgICAgIHJldHVybiB0cmVlLmRlZiAhPSBudWxsICYmCiAgICAgICAgICAgICAgICAgICAgY2xhenp0eXBlLmhhc1RhZyhDTEFTUykgJiYKICAgICAgICAgICAgICAgICAgICB0eXBlcy5pc0Z1bmN0aW9uYWxJbnRlcmZhY2UoY2xhenp0eXBlLnRzeW0pICYmCiAgICAgICAgICAgICAgICAgICAgZGVjbHModHJlZS5kZWYpLmxlbmd0aCgpID09IDE7CiAgICAgICAgfQogICAgICAgIC8vd2hlcmUKICAgICAgICAgICAgcHJpdmF0ZSBMaXN0PEpDVHJlZT4gZGVjbHMoSkNDbGFzc0RlY2wgZGVjbCkgewogICAgICAgICAgICAgICAgTGlzdEJ1ZmZlcjxKQ1RyZWU+IGRlY2xzID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgICAgICAgICAgZm9yIChKQ1RyZWUgdCA6IGRlY2wuZGVmcykgewogICAgICAgICAgICAgICAgICAgIGlmICh0Lmhhc1RhZyhNRVRIT0RERUYpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIEpDTWV0aG9kRGVjbCBtZCA9IChKQ01ldGhvZERlY2wpdDsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKChtZC5nZXRNb2RpZmllcnMoKS5mbGFncyAmIEdFTkVSQVRFRENPTlNUUikgPT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVjbHMuYWRkKG1kKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGRlY2xzLmFkZCh0KTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gZGVjbHMudG9MaXN0KCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgSkNMYW1iZGEgbWFwIChKQ05ld0NsYXNzIG9sZFRyZWUsIEpDTmV3Q2xhc3MgbmV3VHJlZSl7CiAgICAgICAgICAgIEpDTWV0aG9kRGVjbCBtZCA9IChKQ01ldGhvZERlY2wpZGVjbHMobmV3VHJlZS5kZWYpLmhlYWQ7CiAgICAgICAgICAgIExpc3Q8SkNWYXJpYWJsZURlY2w+IHBhcmFtcyA9IG1kLnBhcmFtczsKICAgICAgICAgICAgSkNCbG9jayBib2R5ID0gbWQuYm9keTsKICAgICAgICAgICAgcmV0dXJuIG1ha2UuTGFtYmRhKHBhcmFtcywgYm9keSk7CiAgICAgICAgfQogICAgICAgIEBPdmVycmlkZQogICAgICAgIHZvaWQgcHJvY2VzcyAoSkNOZXdDbGFzcyBvbGRUcmVlLCBKQ0xhbWJkYSBuZXdUcmVlLCBib29sZWFuIGhhc0Vycm9ycyl7CiAgICAgICAgICAgIGlmICghaGFzRXJyb3JzKSB7CiAgICAgICAgICAgICAgICBsb2cud2FybmluZyhvbGRUcmVlLmRlZiwgInBvdGVudGlhbC5sYW1iZGEuZm91bmQiKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFRoaXMgYW5hbHl6ZXIgY2hlY2tzIGlmIGdlbmVyaWMgbWV0aG9kIGNhbGwgaGFzIHJlZHVuZGFudCB0eXBlIGFyZ3VtZW50cy4KICAgICAqLwogICAgY2xhc3MgUmVkdW5kYW50VHlwZUFyZ0FuYWx5emVyIGV4dGVuZHMgU3RhdGVtZW50QW5hbHl6ZXI8SkNNZXRob2RJbnZvY2F0aW9uLCBKQ01ldGhvZEludm9jYXRpb24+IHsKCiAgICAgICAgUmVkdW5kYW50VHlwZUFyZ0FuYWx5emVyKCkgewogICAgICAgICAgICBzdXBlcihBbmFseXplck1vZGUuTUVUSE9ELCBBUFBMWSk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBib29sZWFuIG1hdGNoIChKQ01ldGhvZEludm9jYXRpb24gdHJlZSl7CiAgICAgICAgICAgIHJldHVybiB0cmVlLnR5cGVhcmdzICE9IG51bGwgJiYKICAgICAgICAgICAgICAgICAgICB0cmVlLnR5cGVhcmdzLm5vbkVtcHR5KCk7CiAgICAgICAgfQogICAgICAgIEBPdmVycmlkZQogICAgICAgIEpDTWV0aG9kSW52b2NhdGlvbiBtYXAgKEpDTWV0aG9kSW52b2NhdGlvbiBvbGRUcmVlLCBKQ01ldGhvZEludm9jYXRpb24gbmV3VHJlZSl7CiAgICAgICAgICAgIG5ld1RyZWUudHlwZWFyZ3MgPSBMaXN0Lm5pbCgpOwogICAgICAgICAgICByZXR1cm4gbmV3VHJlZTsKICAgICAgICB9CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgdm9pZCBwcm9jZXNzIChKQ01ldGhvZEludm9jYXRpb24gb2xkVHJlZSwgSkNNZXRob2RJbnZvY2F0aW9uIG5ld1RyZWUsIGJvb2xlYW4gaGFzRXJyb3JzKXsKICAgICAgICAgICAgaWYgKCFoYXNFcnJvcnMpIHsKICAgICAgICAgICAgICAgIC8vZXhhY3QgbWF0Y2gKICAgICAgICAgICAgICAgIGxvZy53YXJuaW5nKG9sZFRyZWUsICJtZXRob2QucmVkdW5kYW50LnR5cGVhcmdzIik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bmNoZWNrZWQiLCAicmF3dHlwZXMifSkKICAgIFN0YXRlbWVudEFuYWx5emVyPEpDVHJlZSwgSkNUcmVlPltdIGFuYWx5emVycyA9IG5ldyBTdGF0ZW1lbnRBbmFseXplcltdIHsKICAgICAgICAgICAgbmV3IERpYW1vbmRJbml0aWFsaXplcigpLAogICAgICAgICAgICBuZXcgTGFtYmRhQW5hbHl6ZXIoKSwKICAgICAgICAgICAgbmV3IFJlZHVuZGFudFR5cGVBcmdBbmFseXplcigpCiAgICB9OwoKICAgIC8qKgogICAgICogQW5hbHl6ZSBhbiBBU1Qgbm9kZSBpZiBuZWVkZWQuCiAgICAgKi8KICAgIHZvaWQgYW5hbHl6ZUlmTmVlZGVkKEpDVHJlZSB0cmVlLCBFbnY8QXR0ckNvbnRleHQ+IGVudikgewogICAgICAgIGlmICghYW5hbHl6ZXJNb2Rlcy5pc0VtcHR5KCkgJiYKICAgICAgICAgICAgICAgICFlbnYuaW5mby5pc1NwZWN1bGF0aXZlICYmCiAgICAgICAgICAgICAgICBUcmVlSW5mby5pc1N0YXRlbWVudCh0cmVlKSkgewogICAgICAgICAgICBKQ1N0YXRlbWVudCBzdG10ID0gKEpDU3RhdGVtZW50KXRyZWU7CiAgICAgICAgICAgIGFuYWx5emUoc3RtdCwgZW52KTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBBbmFseXplIGFuIEFTVCBub2RlOyB0aGlzIGludm9sdmVzIGNvbGxlY3RpbmcgYSBsaXN0IG9mIGFsbCB0aGUgbm9kZXMgdGhhdCBuZWVkcyByZXdyaXRpbmcsCiAgICAgKiBhbmQgc3BlY3VsYXRpdmVseSB0eXBlLWNoZWNrIHRoZSByZXdyaXR0ZW4gY29kZSB0byBjb21wYXJlIHJlc3VsdHMgYWdhaW5zdCBwcmV2aW91c2x5IGF0dHJpYnV0ZWQgY29kZS4KICAgICAqLwogICAgdm9pZCBhbmFseXplKEpDU3RhdGVtZW50IHN0YXRlbWVudCwgRW52PEF0dHJDb250ZXh0PiBlbnYpIHsKICAgICAgICBBbmFseXNpc0NvbnRleHQgY29udGV4dCA9IG5ldyBBbmFseXNpc0NvbnRleHQoKTsKICAgICAgICBTdGF0ZW1lbnRTY2FubmVyIHN0YXRlbWVudFNjYW5uZXIgPSBuZXcgU3RhdGVtZW50U2Nhbm5lcihjb250ZXh0KTsKICAgICAgICBzdGF0ZW1lbnRTY2FubmVyLnNjYW4oc3RhdGVtZW50KTsKCiAgICAgICAgaWYgKCFjb250ZXh0LnRyZWVzVG9BbmFseXplci5pc0VtcHR5KCkpIHsKCiAgICAgICAgICAgIC8vYWRkIGEgYmxvY2sgdG8gaG9pc3QgcG90ZW50aWFsIGRhbmdsaW5nIHZhcmlhYmxlIGRlY2xhcmF0aW9ucwogICAgICAgICAgICBKQ0Jsb2NrIGZha2VCbG9jayA9IG1ha2UuQmxvY2soU1lOVEhFVElDLCBMaXN0Lm9mKHN0YXRlbWVudCkpOwoKICAgICAgICAgICAgVHJlZU1hcHBlciB0cmVlTWFwcGVyID0gbmV3IFRyZWVNYXBwZXIoY29udGV4dCk7CiAgICAgICAgICAgIC8vVE9ETzogdG8gZnVydGhlciByZWZpbmUgdGhlIGFuYWx5c2lzLCB0cnkgYWxsIHJld3JpdGluZyBjb21iaW5hdGlvbnMKICAgICAgICAgICAgTG9jYWxDYWNoZUNvbnRleHQgbG9jYWxDYWNoZUNvbnRleHQgPSBhcmd1bWVudEF0dHIud2l0aExvY2FsQ2FjaGVDb250ZXh0KCk7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBkZWZlcnJlZEF0dHIuYXR0cmliU3BlY3VsYXRpdmUoZmFrZUJsb2NrLCBlbnYsIGF0dHIuc3RhdEluZm8sIHRyZWVNYXBwZXIsCiAgICAgICAgICAgICAgICAgICAgICAgIHQgLT4gbmV3IEFuYWx5emVEZWZlcnJlZERpYWdIYW5kbGVyKGNvbnRleHQpKTsKICAgICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgICAgIGxvY2FsQ2FjaGVDb250ZXh0LmxlYXZlKCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGNvbnRleHQudHJlZU1hcC5lbnRyeVNldCgpLmZvckVhY2goZSAtPiB7CiAgICAgICAgICAgICAgICBjb250ZXh0LnRyZWVzVG9BbmFseXplci5nZXQoZS5nZXRLZXkoKSkKICAgICAgICAgICAgICAgICAgICAgICAgLnByb2Nlc3MoZS5nZXRLZXkoKSwgZS5nZXRWYWx1ZSgpLCBjb250ZXh0LmVycm9ycy5ub25FbXB0eSgpKTsKICAgICAgICAgICAgfSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogU2ltcGxlIGRlZmVycmVkIGRpYWdub3N0aWMgaGFuZGxlciB3aGljaCBmaWx0ZXJzIG91dCBhbGwgbWVzc2FnZXMgYW5kIGtlZXAgdHJhY2sgb2YgZXJyb3JzLgogICAgICovCiAgICBjbGFzcyBBbmFseXplRGVmZXJyZWREaWFnSGFuZGxlciBleHRlbmRzIExvZy5EZWZlcnJlZERpYWdub3N0aWNIYW5kbGVyIHsKICAgICAgICBBbmFseXNpc0NvbnRleHQgY29udGV4dDsKCiAgICAgICAgcHVibGljIEFuYWx5emVEZWZlcnJlZERpYWdIYW5kbGVyKEFuYWx5c2lzQ29udGV4dCBjb250ZXh0KSB7CiAgICAgICAgICAgIHN1cGVyKGxvZywgZCAtPiB7CiAgICAgICAgICAgICAgICBpZiAoZC5nZXRUeXBlKCkgPT0gRGlhZ25vc3RpY1R5cGUuRVJST1IpIHsKICAgICAgICAgICAgICAgICAgICBjb250ZXh0LmVycm9ycy5hZGQoZCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIHRoaXMuY29udGV4dCA9IGNvbnRleHQ7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogVGhpcyBjbGFzcyBpcyB1c2VkIHRvIHBhc3MgYXJvdW5kIGNvbnRleHR1YWwgaW5mb3JtYXRpb24gYmV3dGVlbiBhbmFseXplciBjbGFzc2VzLCBzdWNoIGFzCiAgICAgKiB0cmVlcyB0byBiZSByZXdyaXR0ZW4sIGVycm9ycyBvY2N1cnJlZCBkdXJpbmcgdGhlIHNwZWN1bGF0aXZlIGF0dHJpYnV0aW9uIHN0ZXAsIGV0Yy4KICAgICAqLwogICAgY2xhc3MgQW5hbHlzaXNDb250ZXh0IHsKICAgICAgICAvKiogTWFwIGZyb20gdHJlZXMgdG8gYW5hbHl6ZXJzLiAqLwogICAgICAgIE1hcDxKQ1RyZWUsIFN0YXRlbWVudEFuYWx5emVyPEpDVHJlZSwgSkNUcmVlPj4gdHJlZXNUb0FuYWx5emVyID0gbmV3IEhhc2hNYXA8PigpOwoKICAgICAgICAvKiogTWFwIGZyb20gb3JpZ2luYWwgQVNUIG5vZGVzIHRvIHJld3JpdHRlbiBBU1Qgbm9kZXMgKi8KICAgICAgICBNYXA8SkNUcmVlLCBKQ1RyZWU+IHRyZWVNYXAgPSBuZXcgSGFzaE1hcDw+KCk7CgogICAgICAgIC8qKiBFcnJvcnMgaW4gcmV3cml0dGVuIHRyZWUgKi8KICAgICAgICBMaXN0QnVmZmVyPEpDRGlhZ25vc3RpYz4gZXJyb3JzID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgfQoKICAgIC8qKgogICAgICogU3ViY2xhc3Mgb2Yge0BsaW5rIGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5UcmVlU2Nhbm5lcn0gd2hpY2ggdmlzaXQgQVNULW5vZGVzIHcvbyBjcm9zc2luZwogICAgICogc3RhdGVtZW50IGJvdW5kYXJpZXMuCiAgICAgKi8KICAgIGNsYXNzIFN0YXRlbWVudFNjYW5uZXIgZXh0ZW5kcyBUcmVlU2Nhbm5lciB7CgogICAgICAgIC8qKiBjb250ZXh0ICovCiAgICAgICAgQW5hbHlzaXNDb250ZXh0IGNvbnRleHQ7CgogICAgICAgIFN0YXRlbWVudFNjYW5uZXIoQW5hbHlzaXNDb250ZXh0IGNvbnRleHQpIHsKICAgICAgICAgICAgdGhpcy5jb250ZXh0ID0gY29udGV4dDsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQogICAgICAgIHB1YmxpYyB2b2lkIHNjYW4oSkNUcmVlIHRyZWUpIHsKICAgICAgICAgICAgaWYgKHRyZWUgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgZm9yIChTdGF0ZW1lbnRBbmFseXplcjxKQ1RyZWUsIEpDVHJlZT4gYW5hbHl6ZXIgOiBhbmFseXplcnMpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoYW5hbHl6ZXIuaXNFbmFibGVkKCkgJiYKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyZWUuaGFzVGFnKGFuYWx5emVyLnRhZykgJiYKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFuYWx5emVyLm1hdGNoKHRyZWUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHQudHJlZXNUb0FuYWx5emVyLnB1dCh0cmVlLCBhbmFseXplcik7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOyAvL1RPRE86IGNvdmVyIGNhc2VzIHdoZXJlIG11bHRpcGxlIG1hdGNoaW5nIGFuYWx5emVycyBhcmUgZm91bmQKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc3VwZXIuc2Nhbih0cmVlKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0Q2xhc3NEZWYoSkNDbGFzc0RlY2wgdHJlZSkgewogICAgICAgICAgICAvL2RvIG5vdGhpbmcgKHByZXZlbnRzIHNlZWluZyBzYW1lIHN0dWZmIHR3aWNlCiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdE1ldGhvZERlZihKQ01ldGhvZERlY2wgdHJlZSkgewogICAgICAgICAgICAvL2RvIG5vdGhpbmcgKHByZXZlbnRzIHNlZWluZyBzYW1lIHN0dWZmIHR3aWNlCiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdEJsb2NrKEpDQmxvY2sgdHJlZSkgewogICAgICAgICAgICAvL2RvIG5vdGhpbmcgKHByZXZlbnRzIHNlZWluZyBzYW1lIHN0dWZmIHR3aWNlCiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdFN3aXRjaChKQ1N3aXRjaCB0cmVlKSB7CiAgICAgICAgICAgIHNjYW4odHJlZS5nZXRFeHByZXNzaW9uKCkpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRGb3JMb29wKEpDRm9yTG9vcCB0cmVlKSB7CiAgICAgICAgICAgIHNjYW4odHJlZS5nZXRJbml0aWFsaXplcigpKTsKICAgICAgICAgICAgc2Nhbih0cmVlLmdldENvbmRpdGlvbigpKTsKICAgICAgICAgICAgc2Nhbih0cmVlLmdldFVwZGF0ZSgpKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0Rm9yZWFjaExvb3AoSkNFbmhhbmNlZEZvckxvb3AgdHJlZSkgewogICAgICAgICAgICBzY2FuKHRyZWUuZ2V0RXhwcmVzc2lvbigpKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0V2hpbGVMb29wKEpDV2hpbGVMb29wIHRyZWUpIHsKICAgICAgICAgICAgc2Nhbih0cmVlLmdldENvbmRpdGlvbigpKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0RG9Mb29wKEpDRG9XaGlsZUxvb3AgdHJlZSkgewogICAgICAgICAgICBzY2FuKHRyZWUuZ2V0Q29uZGl0aW9uKCkpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRJZihKQ0lmIHRyZWUpIHsKICAgICAgICAgICAgc2Nhbih0cmVlLmdldENvbmRpdGlvbigpKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBTdWJjbGFzcyBvZiBUcmVlQ29waWVyIHRoYXQgbWFwcyBub2RlcyBtYXRjaGVkIGJ5IGFuYWx5emVycyBvbnRvIG5ldyBBU1Qgbm9kZXMuCiAgICAgKi8KICAgIGNsYXNzIFRyZWVNYXBwZXIgZXh0ZW5kcyBUcmVlQ29waWVyPFZvaWQ+IHsKCiAgICAgICAgQW5hbHlzaXNDb250ZXh0IGNvbnRleHQ7CgogICAgICAgIFRyZWVNYXBwZXIoQW5hbHlzaXNDb250ZXh0IGNvbnRleHQpIHsKICAgICAgICAgICAgc3VwZXIobWFrZSk7CiAgICAgICAgICAgIHRoaXMuY29udGV4dCA9IGNvbnRleHQ7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKICAgICAgICBwdWJsaWMgPFogZXh0ZW5kcyBKQ1RyZWU+IFogY29weShaIHRyZWUsIFZvaWQgX3VudXNlZCkgewogICAgICAgICAgICBaIG5ld1RyZWUgPSBzdXBlci5jb3B5KHRyZWUsIF91bnVzZWQpOwogICAgICAgICAgICBTdGF0ZW1lbnRBbmFseXplcjxKQ1RyZWUsIEpDVHJlZT4gYW5hbHl6ZXIgPSBjb250ZXh0LnRyZWVzVG9BbmFseXplci5nZXQodHJlZSk7CiAgICAgICAgICAgIGlmIChhbmFseXplciAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICBuZXdUcmVlID0gKFopYW5hbHl6ZXIubWFwKHRyZWUsIG5ld1RyZWUpOwogICAgICAgICAgICAgICAgY29udGV4dC50cmVlTWFwLnB1dCh0cmVlLCBuZXdUcmVlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gbmV3VHJlZTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBKQ1RyZWUgdmlzaXRMYW1iZGFFeHByZXNzaW9uKExhbWJkYUV4cHJlc3Npb25UcmVlIG5vZGUsIFZvaWQgX3VudXNlZCkgewogICAgICAgICAgICBKQ0xhbWJkYSBvbGRMYW1iZGEgPSAoSkNMYW1iZGEpbm9kZTsKICAgICAgICAgICAgSkNMYW1iZGEgbmV3TGFtYmRhID0gKEpDTGFtYmRhKXN1cGVyLnZpc2l0TGFtYmRhRXhwcmVzc2lvbihub2RlLCBfdW51c2VkKTsKICAgICAgICAgICAgaWYgKG9sZExhbWJkYS5wYXJhbUtpbmQgPT0gUGFyYW1ldGVyS2luZC5JTVBMSUNJVCkgewogICAgICAgICAgICAgICAgLy9yZXNldCBpbXBsaWNpdCBsYW1iZGEgcGFyYW1ldGVycyAod2hvc2UgdHlwZSBtaWdodCBoYXZlIGJlZW4gc2V0IGR1cmluZyBhdHRyKQogICAgICAgICAgICAgICAgbmV3TGFtYmRhLnBhcmFtS2luZCA9IFBhcmFtZXRlcktpbmQuSU1QTElDSVQ7CiAgICAgICAgICAgICAgICBuZXdMYW1iZGEucGFyYW1zLmZvckVhY2gocCAtPiBwLnZhcnR5cGUgPSBudWxsKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gbmV3TGFtYmRhOwogICAgICAgIH0KICAgIH0KfQpQSwMECgAACAAABjupSi0V665ibgIAYm4CACMAAABjb20vc3VuL3Rvb2xzL2phdmFjL2NvbXAvQ2hlY2suamF2YS8qCiAqIENvcHlyaWdodCAoYykgMTk5OSwgMjAxNywgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLmphdmFjLmNvbXA7CgppbXBvcnQgamF2YS51dGlsLio7CgppbXBvcnQgamF2YXgudG9vbHMuSmF2YUZpbGVNYW5hZ2VyOwoKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS4qOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLkF0dHJpYnV0ZS5Db21wb3VuZDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5EaXJlY3RpdmUuRXhwb3J0c0RpcmVjdGl2ZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5EaXJlY3RpdmUuUmVxdWlyZXNEaXJlY3RpdmU7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvbXAuQW5ub3RhdGUuQW5ub3RhdGlvblR5cGVNZXRhZGF0YTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuanZtLio7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnJlc291cmNlcy5Db21waWxlclByb3BlcnRpZXMuRXJyb3JzOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5yZXNvdXJjZXMuQ29tcGlsZXJQcm9wZXJ0aWVzLkZyYWdtZW50czsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMucmVzb3VyY2VzLkNvbXBpbGVyUHJvcGVydGllcy5XYXJuaW5nczsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS4qOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLio7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuSkNEaWFnbm9zdGljLkRpYWdub3N0aWNGbGFnOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkpDRGlhZ25vc3RpYy5EaWFnbm9zdGljUG9zaXRpb247CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuTGlzdDsKCmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuTGludDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5MaW50LkxpbnRDYXRlZ29yeTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5TY29wZS5Xcml0ZWFibGVTY29wZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5UeXBlLio7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuU3ltYm9sLio7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvbXAuRGVmZXJyZWRBdHRyLkRlZmVycmVkQXR0ckNvbnRleHQ7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvbXAuSW5mZXIuRnJlZVR5cGVMaXN0ZW5lcjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5KQ1RyZWUuKjsKCmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLkZsYWdzLio7CmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLkZsYWdzLkFOTk9UQVRJT047CmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLkZsYWdzLlNZTkNIUk9OSVpFRDsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuS2luZHMuKjsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuS2luZHMuS2luZC4qOwppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5TY29wZS5Mb29rdXBLaW5kLk5PTl9SRUNVUlNJVkU7CmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlR5cGVUYWcuKjsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuVHlwZVRhZy5XSUxEQ0FSRDsKCmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkpDVHJlZS5UYWcuKjsKCi8qKiBUeXBlIGNoZWNraW5nIGhlbHBlciBjbGFzcyBmb3IgdGhlIGF0dHJpYnV0aW9uIHBoYXNlLgogKgogKiAgPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24gcmlzay4KICogIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yCiAqICBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+CiAqLwpwdWJsaWMgY2xhc3MgQ2hlY2sgewogICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBDb250ZXh0LktleTxDaGVjaz4gY2hlY2tLZXkgPSBuZXcgQ29udGV4dC5LZXk8PigpOwoKICAgIHByaXZhdGUgZmluYWwgTmFtZXMgbmFtZXM7CiAgICBwcml2YXRlIGZpbmFsIExvZyBsb2c7CiAgICBwcml2YXRlIGZpbmFsIFJlc29sdmUgcnM7CiAgICBwcml2YXRlIGZpbmFsIFN5bXRhYiBzeW1zOwogICAgcHJpdmF0ZSBmaW5hbCBFbnRlciBlbnRlcjsKICAgIHByaXZhdGUgZmluYWwgRGVmZXJyZWRBdHRyIGRlZmVycmVkQXR0cjsKICAgIHByaXZhdGUgZmluYWwgSW5mZXIgaW5mZXI7CiAgICBwcml2YXRlIGZpbmFsIFR5cGVzIHR5cGVzOwogICAgcHJpdmF0ZSBmaW5hbCBUeXBlQW5ub3RhdGlvbnMgdHlwZUFubm90YXRpb25zOwogICAgcHJpdmF0ZSBmaW5hbCBKQ0RpYWdub3N0aWMuRmFjdG9yeSBkaWFnczsKICAgIHByaXZhdGUgZmluYWwgSmF2YUZpbGVNYW5hZ2VyIGZpbGVNYW5hZ2VyOwogICAgcHJpdmF0ZSBmaW5hbCBTb3VyY2Ugc291cmNlOwogICAgcHJpdmF0ZSBmaW5hbCBQcm9maWxlIHByb2ZpbGU7CiAgICBwcml2YXRlIGZpbmFsIGJvb2xlYW4gd2Fybk9uQW55QWNjZXNzVG9NZW1iZXJzOwoKICAgIC8vIFRoZSBzZXQgb2YgbGludCBvcHRpb25zIGN1cnJlbnRseSBpbiBlZmZlY3QuIEl0IGlzIGluaXRpYWxpemVkCiAgICAvLyBmcm9tIHRoZSBjb250ZXh0LCBhbmQgdGhlbiBpcyBzZXQvcmVzZXQgYXMgbmVlZGVkIGJ5IEF0dHIgYXMgaXQKICAgIC8vIHZpc2l0cyBhbGwgdGhlIHZhcmlvdXMgcGFydHMgb2YgdGhlIHRyZWVzIGR1cmluZyBhdHRyaWJ1dGlvbi4KICAgIHByaXZhdGUgTGludCBsaW50OwoKICAgIC8vIFRoZSBtZXRob2QgYmVpbmcgYW5hbHl6ZWQgaW4gQXR0ciAtIGl0IGlzIHNldC9yZXNldCBhcyBuZWVkZWQgYnkKICAgIC8vIEF0dHIgYXMgaXQgdmlzaXRzIG5ldyBtZXRob2QgZGVjbGFyYXRpb25zLgogICAgcHJpdmF0ZSBNZXRob2RTeW1ib2wgbWV0aG9kOwoKICAgIHB1YmxpYyBzdGF0aWMgQ2hlY2sgaW5zdGFuY2UoQ29udGV4dCBjb250ZXh0KSB7CiAgICAgICAgQ2hlY2sgaW5zdGFuY2UgPSBjb250ZXh0LmdldChjaGVja0tleSk7CiAgICAgICAgaWYgKGluc3RhbmNlID09IG51bGwpCiAgICAgICAgICAgIGluc3RhbmNlID0gbmV3IENoZWNrKGNvbnRleHQpOwogICAgICAgIHJldHVybiBpbnN0YW5jZTsKICAgIH0KCiAgICBwcm90ZWN0ZWQgQ2hlY2soQ29udGV4dCBjb250ZXh0KSB7CiAgICAgICAgY29udGV4dC5wdXQoY2hlY2tLZXksIHRoaXMpOwoKICAgICAgICBuYW1lcyA9IE5hbWVzLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIGRmbHRUYXJnZXRNZXRhID0gbmV3IE5hbWVbXSB7IG5hbWVzLlBBQ0tBR0UsIG5hbWVzLlRZUEUsCiAgICAgICAgICAgIG5hbWVzLkZJRUxELCBuYW1lcy5NRVRIT0QsIG5hbWVzLkNPTlNUUlVDVE9SLAogICAgICAgICAgICBuYW1lcy5BTk5PVEFUSU9OX1RZUEUsIG5hbWVzLkxPQ0FMX1ZBUklBQkxFLCBuYW1lcy5QQVJBTUVURVJ9OwogICAgICAgIGxvZyA9IExvZy5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBycyA9IFJlc29sdmUuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgc3ltcyA9IFN5bXRhYi5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBlbnRlciA9IEVudGVyLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIGRlZmVycmVkQXR0ciA9IERlZmVycmVkQXR0ci5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBpbmZlciA9IEluZmVyLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIHR5cGVzID0gVHlwZXMuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgdHlwZUFubm90YXRpb25zID0gVHlwZUFubm90YXRpb25zLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIGRpYWdzID0gSkNEaWFnbm9zdGljLkZhY3RvcnkuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgT3B0aW9ucyBvcHRpb25zID0gT3B0aW9ucy5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBsaW50ID0gTGludC5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBmaWxlTWFuYWdlciA9IGNvbnRleHQuZ2V0KEphdmFGaWxlTWFuYWdlci5jbGFzcyk7CgogICAgICAgIHNvdXJjZSA9IFNvdXJjZS5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBhbGxvd1NpbXBsaWZpZWRWYXJhcmdzID0gc291cmNlLmFsbG93U2ltcGxpZmllZFZhcmFyZ3MoKTsKICAgICAgICBhbGxvd0RlZmF1bHRNZXRob2RzID0gc291cmNlLmFsbG93RGVmYXVsdE1ldGhvZHMoKTsKICAgICAgICBhbGxvd1N0cmljdE1ldGhvZENsYXNoQ2hlY2sgPSBzb3VyY2UuYWxsb3dTdHJpY3RNZXRob2RDbGFzaENoZWNrKCk7CiAgICAgICAgYWxsb3dQcml2YXRlU2FmZVZhcmFyZ3MgPSBzb3VyY2UuYWxsb3dQcml2YXRlU2FmZVZhcmFyZ3MoKTsKICAgICAgICBhbGxvd0RpYW1vbmRXaXRoQW5vbnltb3VzQ2xhc3NDcmVhdGlvbiA9IHNvdXJjZS5hbGxvd0RpYW1vbmRXaXRoQW5vbnltb3VzQ2xhc3NDcmVhdGlvbigpOwogICAgICAgIHdhcm5PbkFueUFjY2Vzc1RvTWVtYmVycyA9IG9wdGlvbnMuaXNTZXQoIndhcm5PbkFjY2Vzc1RvTWVtYmVycyIpOwoKICAgICAgICBUYXJnZXQgdGFyZ2V0ID0gVGFyZ2V0Lmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIHN5bnRoZXRpY05hbWVDaGFyID0gdGFyZ2V0LnN5bnRoZXRpY05hbWVDaGFyKCk7CgogICAgICAgIHByb2ZpbGUgPSBQcm9maWxlLmluc3RhbmNlKGNvbnRleHQpOwoKICAgICAgICBib29sZWFuIHZlcmJvc2VEZXByZWNhdGVkID0gbGludC5pc0VuYWJsZWQoTGludENhdGVnb3J5LkRFUFJFQ0FUSU9OKTsKICAgICAgICBib29sZWFuIHZlcmJvc2VSZW1vdmFsID0gbGludC5pc0VuYWJsZWQoTGludENhdGVnb3J5LlJFTU9WQUwpOwogICAgICAgIGJvb2xlYW4gdmVyYm9zZVVuY2hlY2tlZCA9IGxpbnQuaXNFbmFibGVkKExpbnRDYXRlZ29yeS5VTkNIRUNLRUQpOwogICAgICAgIGJvb2xlYW4gZW5mb3JjZU1hbmRhdG9yeVdhcm5pbmdzID0gdHJ1ZTsKCiAgICAgICAgZGVwcmVjYXRpb25IYW5kbGVyID0gbmV3IE1hbmRhdG9yeVdhcm5pbmdIYW5kbGVyKGxvZywgdmVyYm9zZURlcHJlY2F0ZWQsCiAgICAgICAgICAgICAgICBlbmZvcmNlTWFuZGF0b3J5V2FybmluZ3MsICJkZXByZWNhdGVkIiwgTGludENhdGVnb3J5LkRFUFJFQ0FUSU9OKTsKICAgICAgICByZW1vdmFsSGFuZGxlciA9IG5ldyBNYW5kYXRvcnlXYXJuaW5nSGFuZGxlcihsb2csIHZlcmJvc2VSZW1vdmFsLAogICAgICAgICAgICAgICAgZW5mb3JjZU1hbmRhdG9yeVdhcm5pbmdzLCAicmVtb3ZhbCIsIExpbnRDYXRlZ29yeS5SRU1PVkFMKTsKICAgICAgICB1bmNoZWNrZWRIYW5kbGVyID0gbmV3IE1hbmRhdG9yeVdhcm5pbmdIYW5kbGVyKGxvZywgdmVyYm9zZVVuY2hlY2tlZCwKICAgICAgICAgICAgICAgIGVuZm9yY2VNYW5kYXRvcnlXYXJuaW5ncywgInVuY2hlY2tlZCIsIExpbnRDYXRlZ29yeS5VTkNIRUNLRUQpOwogICAgICAgIHN1bkFwaUhhbmRsZXIgPSBuZXcgTWFuZGF0b3J5V2FybmluZ0hhbmRsZXIobG9nLCBmYWxzZSwKICAgICAgICAgICAgICAgIGVuZm9yY2VNYW5kYXRvcnlXYXJuaW5ncywgInN1bmFwaSIsIG51bGwpOwoKICAgICAgICBkZWZlcnJlZExpbnRIYW5kbGVyID0gRGVmZXJyZWRMaW50SGFuZGxlci5pbnN0YW5jZShjb250ZXh0KTsKICAgIH0KCiAgICAvKiogU3dpdGNoOiBzaW1wbGlmaWVkIHZhcmFyZ3MgZW5hYmxlZD8KICAgICAqLwogICAgYm9vbGVhbiBhbGxvd1NpbXBsaWZpZWRWYXJhcmdzOwoKICAgIC8qKiBTd2l0Y2g6IGRlZmF1bHQgbWV0aG9kcyBlbmFibGVkPwogICAgICovCiAgICBib29sZWFuIGFsbG93RGVmYXVsdE1ldGhvZHM7CgogICAgLyoqIFN3aXRjaDogc2hvdWxkIHVucmVsYXRlZCByZXR1cm4gdHlwZXMgdHJpZ2dlciBhIG1ldGhvZCBjbGFzaD8KICAgICAqLwogICAgYm9vbGVhbiBhbGxvd1N0cmljdE1ldGhvZENsYXNoQ2hlY2s7CgogICAgLyoqIFN3aXRjaDogY2FuIHRoZSBAU2FmZVZhcmFyZ3MgYW5ub3RhdGlvbiBiZSBhcHBsaWVkIHRvIHByaXZhdGUgbWV0aG9kcz8KICAgICAqLwogICAgYm9vbGVhbiBhbGxvd1ByaXZhdGVTYWZlVmFyYXJnczsKCiAgICAvKiogU3dpdGNoOiBjYW4gZGlhbW9uZCBpbmZlcmVuY2UgYmUgdXNlZCBpbiBhbm9ueW1vdXMgaW5zdGFuY2UgY3JlYXRpb24gPwogICAgICovCiAgICBib29sZWFuIGFsbG93RGlhbW9uZFdpdGhBbm9ueW1vdXNDbGFzc0NyZWF0aW9uOwoKICAgIC8qKiBDaGFyYWN0ZXIgZm9yIHN5bnRoZXRpYyBuYW1lcwogICAgICovCiAgICBjaGFyIHN5bnRoZXRpY05hbWVDaGFyOwoKICAgIC8qKiBBIHRhYmxlIG1hcHBpbmcgZmxhdCBuYW1lcyBvZiBhbGwgY29tcGlsZWQgY2xhc3NlcyBmb3IgZWFjaCBtb2R1bGUgaW4gdGhpcyBydW4KICAgICAqICB0byB0aGVpciBzeW1ib2xzOyBtYWludGFpbmVkIGZyb20gb3V0c2lkZS4KICAgICAqLwogICAgcHJpdmF0ZSBNYXA8UGFpcjxNb2R1bGVTeW1ib2wsIE5hbWU+LENsYXNzU3ltYm9sPiBjb21waWxlZCA9IG5ldyBIYXNoTWFwPD4oKTsKCiAgICAvKiogQSBoYW5kbGVyIGZvciBtZXNzYWdlcyBhYm91dCBkZXByZWNhdGVkIHVzYWdlLgogICAgICovCiAgICBwcml2YXRlIE1hbmRhdG9yeVdhcm5pbmdIYW5kbGVyIGRlcHJlY2F0aW9uSGFuZGxlcjsKCiAgICAvKiogQSBoYW5kbGVyIGZvciBtZXNzYWdlcyBhYm91dCBkZXByZWNhdGVkLWZvci1yZW1vdmFsIHVzYWdlLgogICAgICovCiAgICBwcml2YXRlIE1hbmRhdG9yeVdhcm5pbmdIYW5kbGVyIHJlbW92YWxIYW5kbGVyOwoKICAgIC8qKiBBIGhhbmRsZXIgZm9yIG1lc3NhZ2VzIGFib3V0IHVuY2hlY2tlZCBvciB1bnNhZmUgdXNhZ2UuCiAgICAgKi8KICAgIHByaXZhdGUgTWFuZGF0b3J5V2FybmluZ0hhbmRsZXIgdW5jaGVja2VkSGFuZGxlcjsKCiAgICAvKiogQSBoYW5kbGVyIGZvciBtZXNzYWdlcyBhYm91dCB1c2luZyBwcm9wcmlldGFyeSBBUEkuCiAgICAgKi8KICAgIHByaXZhdGUgTWFuZGF0b3J5V2FybmluZ0hhbmRsZXIgc3VuQXBpSGFuZGxlcjsKCiAgICAvKiogQSBoYW5kbGVyIGZvciBkZWZlcnJlZCBsaW50IHdhcm5pbmdzLgogICAgICovCiAgICBwcml2YXRlIERlZmVycmVkTGludEhhbmRsZXIgZGVmZXJyZWRMaW50SGFuZGxlcjsKCi8qICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRXJyb3JzIGFuZCBXYXJuaW5ncwogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgogICAgTGludCBzZXRMaW50KExpbnQgbmV3TGludCkgewogICAgICAgIExpbnQgcHJldiA9IGxpbnQ7CiAgICAgICAgbGludCA9IG5ld0xpbnQ7CiAgICAgICAgcmV0dXJuIHByZXY7CiAgICB9CgogICAgTWV0aG9kU3ltYm9sIHNldE1ldGhvZChNZXRob2RTeW1ib2wgbmV3TWV0aG9kKSB7CiAgICAgICAgTWV0aG9kU3ltYm9sIHByZXYgPSBtZXRob2Q7CiAgICAgICAgbWV0aG9kID0gbmV3TWV0aG9kOwogICAgICAgIHJldHVybiBwcmV2OwogICAgfQoKICAgIC8qKiBXYXJuIGFib3V0IGRlcHJlY2F0ZWQgc3ltYm9sLgogICAgICogIEBwYXJhbSBwb3MgICAgICAgIFBvc2l0aW9uIHRvIGJlIHVzZWQgZm9yIGVycm9yIHJlcG9ydGluZy4KICAgICAqICBAcGFyYW0gc3ltICAgICAgICBUaGUgZGVwcmVjYXRlZCBzeW1ib2wuCiAgICAgKi8KICAgIHZvaWQgd2FybkRlcHJlY2F0ZWQoRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcywgU3ltYm9sIHN5bSkgewogICAgICAgIGlmIChzeW0uaXNEZXByZWNhdGVkRm9yUmVtb3ZhbCgpKSB7CiAgICAgICAgICAgIGlmICghbGludC5pc1N1cHByZXNzZWQoTGludENhdGVnb3J5LlJFTU9WQUwpKSB7CiAgICAgICAgICAgICAgICBpZiAoc3ltLmtpbmQgPT0gTURMKSB7CiAgICAgICAgICAgICAgICAgICAgcmVtb3ZhbEhhbmRsZXIucmVwb3J0KHBvcywgImhhcy5iZWVuLmRlcHJlY2F0ZWQuZm9yLnJlbW92YWwubW9kdWxlIiwgc3ltKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgcmVtb3ZhbEhhbmRsZXIucmVwb3J0KHBvcywgImhhcy5iZWVuLmRlcHJlY2F0ZWQuZm9yLnJlbW92YWwiLCBzeW0sIHN5bS5sb2NhdGlvbigpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSBpZiAoIWxpbnQuaXNTdXBwcmVzc2VkKExpbnRDYXRlZ29yeS5ERVBSRUNBVElPTikpIHsKICAgICAgICAgICAgaWYgKHN5bS5raW5kID09IE1ETCkgewogICAgICAgICAgICAgICAgZGVwcmVjYXRpb25IYW5kbGVyLnJlcG9ydChwb3MsICJoYXMuYmVlbi5kZXByZWNhdGVkLm1vZHVsZSIsIHN5bSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBkZXByZWNhdGlvbkhhbmRsZXIucmVwb3J0KHBvcywgImhhcy5iZWVuLmRlcHJlY2F0ZWQiLCBzeW0sIHN5bS5sb2NhdGlvbigpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKiogV2FybiBhYm91dCB1bmNoZWNrZWQgb3BlcmF0aW9uLgogICAgICogIEBwYXJhbSBwb3MgICAgICAgIFBvc2l0aW9uIHRvIGJlIHVzZWQgZm9yIGVycm9yIHJlcG9ydGluZy4KICAgICAqICBAcGFyYW0gbXNnICAgICAgICBBIHN0cmluZyBkZXNjcmliaW5nIHRoZSBwcm9ibGVtLgogICAgICovCiAgICBwdWJsaWMgdm9pZCB3YXJuVW5jaGVja2VkKERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIFN0cmluZyBtc2csIE9iamVjdC4uLiBhcmdzKSB7CiAgICAgICAgaWYgKCFsaW50LmlzU3VwcHJlc3NlZChMaW50Q2F0ZWdvcnkuVU5DSEVDS0VEKSkKICAgICAgICAgICAgdW5jaGVja2VkSGFuZGxlci5yZXBvcnQocG9zLCBtc2csIGFyZ3MpOwogICAgfQoKICAgIC8qKiBXYXJuIGFib3V0IHVuc2FmZSB2YXJhcmcgbWV0aG9kIGRlY2wuCiAgICAgKiAgQHBhcmFtIHBvcyAgICAgICAgUG9zaXRpb24gdG8gYmUgdXNlZCBmb3IgZXJyb3IgcmVwb3J0aW5nLgogICAgICovCiAgICB2b2lkIHdhcm5VbnNhZmVWYXJhcmcoRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcywgU3RyaW5nIGtleSwgT2JqZWN0Li4uIGFyZ3MpIHsKICAgICAgICBpZiAobGludC5pc0VuYWJsZWQoTGludENhdGVnb3J5LlZBUkFSR1MpICYmIGFsbG93U2ltcGxpZmllZFZhcmFyZ3MpCiAgICAgICAgICAgIGxvZy53YXJuaW5nKExpbnRDYXRlZ29yeS5WQVJBUkdTLCBwb3MsIGtleSwgYXJncyk7CiAgICB9CgogICAgcHVibGljIHZvaWQgd2FyblN0YXRpYyhEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBTdHJpbmcgbXNnLCBPYmplY3QuLi4gYXJncykgewogICAgICAgIGlmIChsaW50LmlzRW5hYmxlZChMaW50Q2F0ZWdvcnkuU1RBVElDKSkKICAgICAgICAgICAgbG9nLndhcm5pbmcoTGludENhdGVnb3J5LlNUQVRJQywgcG9zLCBtc2csIGFyZ3MpOwogICAgfQoKICAgIC8qKiBXYXJuIGFib3V0IGRpdmlzaW9uIGJ5IGludGVnZXIgY29uc3RhbnQgemVyby4KICAgICAqICBAcGFyYW0gcG9zICAgICAgICBQb3NpdGlvbiB0byBiZSB1c2VkIGZvciBlcnJvciByZXBvcnRpbmcuCiAgICAgKi8KICAgIHZvaWQgd2FybkRpdlplcm8oRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcykgewogICAgICAgIGlmIChsaW50LmlzRW5hYmxlZChMaW50Q2F0ZWdvcnkuRElWWkVSTykpCiAgICAgICAgICAgIGxvZy53YXJuaW5nKExpbnRDYXRlZ29yeS5ESVZaRVJPLCBwb3MsICJkaXYuemVybyIpOwogICAgfQoKICAgIC8qKgogICAgICogUmVwb3J0IGFueSBkZWZlcnJlZCBkaWFnbm9zdGljcy4KICAgICAqLwogICAgcHVibGljIHZvaWQgcmVwb3J0RGVmZXJyZWREaWFnbm9zdGljcygpIHsKICAgICAgICBkZXByZWNhdGlvbkhhbmRsZXIucmVwb3J0RGVmZXJyZWREaWFnbm9zdGljKCk7CiAgICAgICAgcmVtb3ZhbEhhbmRsZXIucmVwb3J0RGVmZXJyZWREaWFnbm9zdGljKCk7CiAgICAgICAgdW5jaGVja2VkSGFuZGxlci5yZXBvcnREZWZlcnJlZERpYWdub3N0aWMoKTsKICAgICAgICBzdW5BcGlIYW5kbGVyLnJlcG9ydERlZmVycmVkRGlhZ25vc3RpYygpOwogICAgfQoKCiAgICAvKiogUmVwb3J0IGEgZmFpbHVyZSB0byBjb21wbGV0ZSBhIGNsYXNzLgogICAgICogIEBwYXJhbSBwb3MgICAgICAgIFBvc2l0aW9uIHRvIGJlIHVzZWQgZm9yIGVycm9yIHJlcG9ydGluZy4KICAgICAqICBAcGFyYW0gZXggICAgICAgICBUaGUgZmFpbHVyZSB0byByZXBvcnQuCiAgICAgKi8KICAgIHB1YmxpYyBUeXBlIGNvbXBsZXRpb25FcnJvcihEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBDb21wbGV0aW9uRmFpbHVyZSBleCkgewogICAgICAgIGxvZy5lcnJvcihKQ0RpYWdub3N0aWMuRGlhZ25vc3RpY0ZsYWcuTk9OX0RFRkVSUkFCTEUsIHBvcywgImNhbnQuYWNjZXNzIiwgZXguc3ltLCBleC5nZXREZXRhaWxWYWx1ZSgpKTsKICAgICAgICBpZiAoZXggaW5zdGFuY2VvZiBDbGFzc0ZpbmRlci5CYWRDbGFzc0ZpbGUpIHRocm93IG5ldyBBYm9ydCgpOwogICAgICAgIGVsc2UgcmV0dXJuIHN5bXMuZXJyVHlwZTsKICAgIH0KCiAgICAvKiogUmVwb3J0IGFuIGVycm9yIHRoYXQgd3JvbmcgdHlwZSB0YWcgd2FzIGZvdW5kLgogICAgICogIEBwYXJhbSBwb3MgICAgICAgIFBvc2l0aW9uIHRvIGJlIHVzZWQgZm9yIGVycm9yIHJlcG9ydGluZy4KICAgICAqICBAcGFyYW0gcmVxdWlyZWQgICBBbiBpbnRlcm5hdGlvbmFsaXplZCBzdHJpbmcgZGVzY3JpYmluZyB0aGUgdHlwZSB0YWcKICAgICAqICAgICAgICAgICAgICAgICAgICByZXF1aXJlZC4KICAgICAqICBAcGFyYW0gZm91bmQgICAgICBUaGUgdHlwZSB0aGF0IHdhcyBmb3VuZC4KICAgICAqLwogICAgVHlwZSB0eXBlVGFnRXJyb3IoRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcywgT2JqZWN0IHJlcXVpcmVkLCBPYmplY3QgZm91bmQpIHsKICAgICAgICAvLyB0aGlzIGVycm9yIHVzZWQgdG8gYmUgcmFpc2VkIGJ5IHRoZSBwYXJzZXIsCiAgICAgICAgLy8gYnV0IGhhcyBiZWVuIGRlbGF5ZWQgdG8gdGhpcyBwb2ludDoKICAgICAgICBpZiAoZm91bmQgaW5zdGFuY2VvZiBUeXBlICYmICgoVHlwZSlmb3VuZCkuaGFzVGFnKFZPSUQpKSB7CiAgICAgICAgICAgIGxvZy5lcnJvcihwb3MsICJpbGxlZ2FsLnN0YXJ0Lm9mLnR5cGUiKTsKICAgICAgICAgICAgcmV0dXJuIHN5bXMuZXJyVHlwZTsKICAgICAgICB9CiAgICAgICAgbG9nLmVycm9yKHBvcywgInR5cGUuZm91bmQucmVxIiwgZm91bmQsIHJlcXVpcmVkKTsKICAgICAgICByZXR1cm4gdHlwZXMuY3JlYXRlRXJyb3JUeXBlKGZvdW5kIGluc3RhbmNlb2YgVHlwZSA/IChUeXBlKWZvdW5kIDogc3ltcy5lcnJUeXBlKTsKICAgIH0KCiAgICAvKiogUmVwb3J0IGFuIGVycm9yIHRoYXQgc3ltYm9sIGNhbm5vdCBiZSByZWZlcmVuY2VkIGJlZm9yZSBzdXBlcgogICAgICogIGhhcyBiZWVuIGNhbGxlZC4KICAgICAqICBAcGFyYW0gcG9zICAgICAgICBQb3NpdGlvbiB0byBiZSB1c2VkIGZvciBlcnJvciByZXBvcnRpbmcuCiAgICAgKiAgQHBhcmFtIHN5bSAgICAgICAgVGhlIHJlZmVyZW5jZWQgc3ltYm9sLgogICAgICovCiAgICB2b2lkIGVhcmx5UmVmRXJyb3IoRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcywgU3ltYm9sIHN5bSkgewogICAgICAgIGxvZy5lcnJvcihwb3MsICJjYW50LnJlZi5iZWZvcmUuY3Rvci5jYWxsZWQiLCBzeW0pOwogICAgfQoKICAgIC8qKiBSZXBvcnQgZHVwbGljYXRlIGRlY2xhcmF0aW9uIGVycm9yLgogICAgICovCiAgICB2b2lkIGR1cGxpY2F0ZUVycm9yKERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIFN5bWJvbCBzeW0pIHsKICAgICAgICBpZiAoIXN5bS50eXBlLmlzRXJyb25lb3VzKCkpIHsKICAgICAgICAgICAgU3ltYm9sIGxvY2F0aW9uID0gc3ltLmxvY2F0aW9uKCk7CiAgICAgICAgICAgIGlmIChsb2NhdGlvbi5raW5kID09IE1USCAmJgogICAgICAgICAgICAgICAgICAgICgoTWV0aG9kU3ltYm9sKWxvY2F0aW9uKS5pc1N0YXRpY09ySW5zdGFuY2VJbml0KCkpIHsKICAgICAgICAgICAgICAgIGxvZy5lcnJvcihwb3MsICJhbHJlYWR5LmRlZmluZWQuaW4uY2xpbml0Iiwga2luZE5hbWUoc3ltKSwgc3ltLAogICAgICAgICAgICAgICAgICAgICAgICBraW5kTmFtZShzeW0ubG9jYXRpb24oKSksIGtpbmROYW1lKHN5bS5sb2NhdGlvbigpLmVuY2xDbGFzcygpKSwKICAgICAgICAgICAgICAgICAgICAgICAgc3ltLmxvY2F0aW9uKCkuZW5jbENsYXNzKCkpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgbG9nLmVycm9yKHBvcywgImFscmVhZHkuZGVmaW5lZCIsIGtpbmROYW1lKHN5bSksIHN5bSwKICAgICAgICAgICAgICAgICAgICAgICAga2luZE5hbWUoc3ltLmxvY2F0aW9uKCkpLCBzeW0ubG9jYXRpb24oKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqIFJlcG9ydCBhcnJheS92YXJhcmdzIGR1cGxpY2F0ZSBkZWNsYXJhdGlvbgogICAgICovCiAgICB2b2lkIHZhcmFyZ3NEdXBsaWNhdGVFcnJvcihEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBTeW1ib2wgc3ltMSwgU3ltYm9sIHN5bTIpIHsKICAgICAgICBpZiAoIXN5bTEudHlwZS5pc0Vycm9uZW91cygpICYmICFzeW0yLnR5cGUuaXNFcnJvbmVvdXMoKSkgewogICAgICAgICAgICBsb2cuZXJyb3IocG9zLCAiYXJyYXkuYW5kLnZhcmFyZ3MiLCBzeW0xLCBzeW0yLCBzeW0yLmxvY2F0aW9uKCkpOwogICAgICAgIH0KICAgIH0KCi8qICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBkdXBsaWNhdGUgZGVjbGFyYXRpb24gY2hlY2tpbmcKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgogICAgLyoqIENoZWNrIHRoYXQgdmFyaWFibGUgZG9lcyBub3QgaGlkZSB2YXJpYWJsZSB3aXRoIHNhbWUgbmFtZSBpbgogICAgICogIGltbWVkaWF0ZWx5IGVuY2xvc2luZyBsb2NhbCBzY29wZS4KICAgICAqICBAcGFyYW0gcG9zICAgICAgICAgICBQb3NpdGlvbiBmb3IgZXJyb3IgcmVwb3J0aW5nLgogICAgICogIEBwYXJhbSB2ICAgICAgICAgICAgIFRoZSBzeW1ib2wuCiAgICAgKiAgQHBhcmFtIHMgICAgICAgICAgICAgVGhlIHNjb3BlLgogICAgICovCiAgICB2b2lkIGNoZWNrVHJhbnNwYXJlbnRWYXIoRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcywgVmFyU3ltYm9sIHYsIFNjb3BlIHMpIHsKICAgICAgICBmb3IgKFN5bWJvbCBzeW0gOiBzLmdldFN5bWJvbHNCeU5hbWUodi5uYW1lKSkgewogICAgICAgICAgICBpZiAoc3ltLm93bmVyICE9IHYub3duZXIpIGJyZWFrOwogICAgICAgICAgICBpZiAoc3ltLmtpbmQgPT0gVkFSICYmCiAgICAgICAgICAgICAgICBzeW0ub3duZXIua2luZC5tYXRjaGVzKEtpbmRTZWxlY3Rvci5WQUxfTVRIKSAmJgogICAgICAgICAgICAgICAgdi5uYW1lICE9IG5hbWVzLmVycm9yKSB7CiAgICAgICAgICAgICAgICBkdXBsaWNhdGVFcnJvcihwb3MsIHN5bSk7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqIENoZWNrIHRoYXQgYSBjbGFzcyBvciBpbnRlcmZhY2UgZG9lcyBub3QgaGlkZSBhIGNsYXNzIG9yCiAgICAgKiAgaW50ZXJmYWNlIHdpdGggc2FtZSBuYW1lIGluIGltbWVkaWF0ZWx5IGVuY2xvc2luZyBsb2NhbCBzY29wZS4KICAgICAqICBAcGFyYW0gcG9zICAgICAgICAgICBQb3NpdGlvbiBmb3IgZXJyb3IgcmVwb3J0aW5nLgogICAgICogIEBwYXJhbSBjICAgICAgICAgICAgIFRoZSBzeW1ib2wuCiAgICAgKiAgQHBhcmFtIHMgICAgICAgICAgICAgVGhlIHNjb3BlLgogICAgICovCiAgICB2b2lkIGNoZWNrVHJhbnNwYXJlbnRDbGFzcyhEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBDbGFzc1N5bWJvbCBjLCBTY29wZSBzKSB7CiAgICAgICAgZm9yIChTeW1ib2wgc3ltIDogcy5nZXRTeW1ib2xzQnlOYW1lKGMubmFtZSkpIHsKICAgICAgICAgICAgaWYgKHN5bS5vd25lciAhPSBjLm93bmVyKSBicmVhazsKICAgICAgICAgICAgaWYgKHN5bS5raW5kID09IFRZUCAmJiAhc3ltLnR5cGUuaGFzVGFnKFRZUEVWQVIpICYmCiAgICAgICAgICAgICAgICBzeW0ub3duZXIua2luZC5tYXRjaGVzKEtpbmRTZWxlY3Rvci5WQUxfTVRIKSAmJgogICAgICAgICAgICAgICAgYy5uYW1lICE9IG5hbWVzLmVycm9yKSB7CiAgICAgICAgICAgICAgICBkdXBsaWNhdGVFcnJvcihwb3MsIHN5bSk7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqIENoZWNrIHRoYXQgY2xhc3MgZG9lcyBub3QgaGF2ZSB0aGUgc2FtZSBuYW1lIGFzIG9uZSBvZgogICAgICogIGl0cyBlbmNsb3NpbmcgY2xhc3Nlcywgb3IgYXMgYSBjbGFzcyBkZWZpbmVkIGluIGl0cyBlbmNsb3Npbmcgc2NvcGUuCiAgICAgKiAgcmV0dXJuIHRydWUgaWYgY2xhc3MgaXMgdW5pcXVlIGluIGl0cyBlbmNsb3Npbmcgc2NvcGUuCiAgICAgKiAgQHBhcmFtIHBvcyAgICAgICAgICAgUG9zaXRpb24gZm9yIGVycm9yIHJlcG9ydGluZy4KICAgICAqICBAcGFyYW0gbmFtZSAgICAgICAgICBUaGUgY2xhc3MgbmFtZS4KICAgICAqICBAcGFyYW0gcyAgICAgICAgICAgICBUaGUgZW5jbG9zaW5nIHNjb3BlLgogICAgICovCiAgICBib29sZWFuIGNoZWNrVW5pcXVlQ2xhc3NOYW1lKERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIE5hbWUgbmFtZSwgU2NvcGUgcykgewogICAgICAgIGZvciAoU3ltYm9sIHN5bSA6IHMuZ2V0U3ltYm9sc0J5TmFtZShuYW1lLCBOT05fUkVDVVJTSVZFKSkgewogICAgICAgICAgICBpZiAoc3ltLmtpbmQgPT0gVFlQICYmIHN5bS5uYW1lICE9IG5hbWVzLmVycm9yKSB7CiAgICAgICAgICAgICAgICBkdXBsaWNhdGVFcnJvcihwb3MsIHN5bSk7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZm9yIChTeW1ib2wgc3ltID0gcy5vd25lcjsgc3ltICE9IG51bGw7IHN5bSA9IHN5bS5vd25lcikgewogICAgICAgICAgICBpZiAoc3ltLmtpbmQgPT0gVFlQICYmIHN5bS5uYW1lID09IG5hbWUgJiYgc3ltLm5hbWUgIT0gbmFtZXMuZXJyb3IpIHsKICAgICAgICAgICAgICAgIGR1cGxpY2F0ZUVycm9yKHBvcywgc3ltKTsKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKLyogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBDbGFzcyBuYW1lIGdlbmVyYXRpb24KICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKCiAgICBwcml2YXRlIE1hcDxQYWlyPE5hbWUsIE5hbWU+LCBJbnRlZ2VyPiBsb2NhbENsYXNzTmFtZUluZGV4ZXMgPSBuZXcgSGFzaE1hcDw+KCk7CgogICAgLyoqIFJldHVybiBuYW1lIG9mIGxvY2FsIGNsYXNzLgogICAgICogIFRoaXMgaXMgb2YgdGhlIGZvcm0gICB7QGNvZGUgPGVuY2xDbGFzcz4gJCBuIDxjbGFzc25hbWU+IH0KICAgICAqICB3aGVyZQogICAgICogICAgZW5jbENsYXNzIGlzIHRoZSBmbGF0IG5hbWUgb2YgdGhlIGVuY2xvc2luZyBjbGFzcywKICAgICAqICAgIGNsYXNzbmFtZSBpcyB0aGUgc2ltcGxlIG5hbWUgb2YgdGhlIGxvY2FsIGNsYXNzCiAgICAgKi8KICAgIE5hbWUgbG9jYWxDbGFzc05hbWUoQ2xhc3NTeW1ib2wgYykgewogICAgICAgIE5hbWUgZW5jbEZsYXRuYW1lID0gYy5vd25lci5lbmNsQ2xhc3MoKS5mbGF0bmFtZTsKICAgICAgICBTdHJpbmcgZW5jbEZsYXRuYW1lU3RyID0gZW5jbEZsYXRuYW1lLnRvU3RyaW5nKCk7CiAgICAgICAgUGFpcjxOYW1lLCBOYW1lPiBrZXkgPSBuZXcgUGFpcjw+KGVuY2xGbGF0bmFtZSwgYy5uYW1lKTsKICAgICAgICBJbnRlZ2VyIGluZGV4ID0gbG9jYWxDbGFzc05hbWVJbmRleGVzLmdldChrZXkpOwogICAgICAgIGZvciAoaW50IGkgPSAoaW5kZXggPT0gbnVsbCkgPyAxIDogaW5kZXg7IDsgaSsrKSB7CiAgICAgICAgICAgIE5hbWUgZmxhdG5hbWUgPSBuYW1lcy5mcm9tU3RyaW5nKGVuY2xGbGF0bmFtZVN0cgogICAgICAgICAgICAgICAgICAgICsgc3ludGhldGljTmFtZUNoYXIgKyBpICsgYy5uYW1lKTsKICAgICAgICAgICAgaWYgKGdldENvbXBpbGVkKGMucGFja2dlKCkubW9kbGUsIGZsYXRuYW1lKSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICBsb2NhbENsYXNzTmFtZUluZGV4ZXMucHV0KGtleSwgaSArIDEpOwogICAgICAgICAgICAgICAgcmV0dXJuIGZsYXRuYW1lOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIHZvaWQgY2xlYXJMb2NhbENsYXNzTmFtZUluZGV4ZXMoQ2xhc3NTeW1ib2wgYykgewogICAgICAgIGlmIChjLm93bmVyICE9IG51bGwgJiYgYy5vd25lci5raW5kICE9IE5JTCkgewogICAgICAgICAgICBsb2NhbENsYXNzTmFtZUluZGV4ZXMucmVtb3ZlKG5ldyBQYWlyPD4oCiAgICAgICAgICAgICAgICAgICAgYy5vd25lci5lbmNsQ2xhc3MoKS5mbGF0bmFtZSwgYy5uYW1lKSk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyB2b2lkIG5ld1JvdW5kKCkgewogICAgICAgIGNvbXBpbGVkLmNsZWFyKCk7CiAgICAgICAgbG9jYWxDbGFzc05hbWVJbmRleGVzLmNsZWFyKCk7CiAgICB9CgogICAgcHVibGljIHZvaWQgcHV0Q29tcGlsZWQoQ2xhc3NTeW1ib2wgY3N5bSkgewogICAgICAgIGNvbXBpbGVkLnB1dChQYWlyLm9mKGNzeW0ucGFja2dlKCkubW9kbGUsIGNzeW0uZmxhdG5hbWUpLCBjc3ltKTsKICAgIH0KCiAgICBwdWJsaWMgQ2xhc3NTeW1ib2wgZ2V0Q29tcGlsZWQoQ2xhc3NTeW1ib2wgY3N5bSkgewogICAgICAgIHJldHVybiBjb21waWxlZC5nZXQoUGFpci5vZihjc3ltLnBhY2tnZSgpLm1vZGxlLCBjc3ltLmZsYXRuYW1lKSk7CiAgICB9CgogICAgcHVibGljIENsYXNzU3ltYm9sIGdldENvbXBpbGVkKE1vZHVsZVN5bWJvbCBtc3ltLCBOYW1lIGZsYXRuYW1lKSB7CiAgICAgICAgcmV0dXJuIGNvbXBpbGVkLmdldChQYWlyLm9mKG1zeW0sIGZsYXRuYW1lKSk7CiAgICB9CgogICAgcHVibGljIHZvaWQgcmVtb3ZlQ29tcGlsZWQoQ2xhc3NTeW1ib2wgY3N5bSkgewogICAgICAgIGNvbXBpbGVkLnJlbW92ZShQYWlyLm9mKGNzeW0ucGFja2dlKCkubW9kbGUsIGNzeW0uZmxhdG5hbWUpKTsKICAgIH0KCi8qICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogVHlwZSBDaGVja2luZwogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgogICAgLyoqCiAgICAgKiBBIGNoZWNrIGNvbnRleHQgaXMgYW4gb2JqZWN0IHRoYXQgY2FuIGJlIHVzZWQgdG8gcGVyZm9ybSBjb21wYXRpYmlsaXR5CiAgICAgKiBjaGVja3MgLSBkZXBlbmRpbmcgb24gdGhlIGNoZWNrIGNvbnRleHQsIG1lYW5pbmcgb2YgJ2NvbXBhdGliaWxpdHknIG1pZ2h0CiAgICAgKiB2YXJ5IHNpZ25pZmljYW50bHkuCiAgICAgKi8KICAgIHB1YmxpYyBpbnRlcmZhY2UgQ2hlY2tDb250ZXh0IHsKICAgICAgICAvKioKICAgICAgICAgKiBJcyB0eXBlICdmb3VuZCcgY29tcGF0aWJsZSB3aXRoIHR5cGUgJ3JlcScgaW4gZ2l2ZW4gY29udGV4dAogICAgICAgICAqLwogICAgICAgIGJvb2xlYW4gY29tcGF0aWJsZShUeXBlIGZvdW5kLCBUeXBlIHJlcSwgV2FybmVyIHdhcm4pOwogICAgICAgIC8qKgogICAgICAgICAqIFJlcG9ydCBhIGNoZWNrIGVycm9yCiAgICAgICAgICovCiAgICAgICAgdm9pZCByZXBvcnQoRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcywgSkNEaWFnbm9zdGljIGRldGFpbHMpOwogICAgICAgIC8qKgogICAgICAgICAqIE9idGFpbiBhIHdhcm5lciBmb3IgdGhpcyBjaGVjayBjb250ZXh0CiAgICAgICAgICovCiAgICAgICAgcHVibGljIFdhcm5lciBjaGVja1dhcm5lcihEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBUeXBlIGZvdW5kLCBUeXBlIHJlcSk7CgogICAgICAgIHB1YmxpYyBJbmZlcmVuY2VDb250ZXh0IGluZmVyZW5jZUNvbnRleHQoKTsKCiAgICAgICAgcHVibGljIERlZmVycmVkQXR0ci5EZWZlcnJlZEF0dHJDb250ZXh0IGRlZmVycmVkQXR0ckNvbnRleHQoKTsKICAgIH0KCiAgICAvKioKICAgICAqIFRoaXMgY2xhc3MgcmVwcmVzZW50IGEgY2hlY2sgY29udGV4dCB0aGF0IGlzIG5lc3RlZCB3aXRoaW4gYW5vdGhlciBjaGVjawogICAgICogY29udGV4dCAtIHVzZWZ1bCB0byBjaGVjayBzdWItZXhwcmVzc2lvbnMuIFRoZSBkZWZhdWx0IGJlaGF2aW9yIHNpbXBseQogICAgICogcmVkaXJlY3RzIGFsbCBtZXRob2QgY2FsbHMgdG8gdGhlIGVuY2xvc2luZyBjaGVjayBjb250ZXh0IGxldmVyYWdpbmcKICAgICAqIHRoZSBmb3J3YXJkaW5nIHBhdHRlcm4uCiAgICAgKi8KICAgIHN0YXRpYyBjbGFzcyBOZXN0ZWRDaGVja0NvbnRleHQgaW1wbGVtZW50cyBDaGVja0NvbnRleHQgewogICAgICAgIENoZWNrQ29udGV4dCBlbmNsb3NpbmdDb250ZXh0OwoKICAgICAgICBOZXN0ZWRDaGVja0NvbnRleHQoQ2hlY2tDb250ZXh0IGVuY2xvc2luZ0NvbnRleHQpIHsKICAgICAgICAgICAgdGhpcy5lbmNsb3NpbmdDb250ZXh0ID0gZW5jbG9zaW5nQ29udGV4dDsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBib29sZWFuIGNvbXBhdGlibGUoVHlwZSBmb3VuZCwgVHlwZSByZXEsIFdhcm5lciB3YXJuKSB7CiAgICAgICAgICAgIHJldHVybiBlbmNsb3NpbmdDb250ZXh0LmNvbXBhdGlibGUoZm91bmQsIHJlcSwgd2Fybik7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgdm9pZCByZXBvcnQoRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcywgSkNEaWFnbm9zdGljIGRldGFpbHMpIHsKICAgICAgICAgICAgZW5jbG9zaW5nQ29udGV4dC5yZXBvcnQocG9zLCBkZXRhaWxzKTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBXYXJuZXIgY2hlY2tXYXJuZXIoRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcywgVHlwZSBmb3VuZCwgVHlwZSByZXEpIHsKICAgICAgICAgICAgcmV0dXJuIGVuY2xvc2luZ0NvbnRleHQuY2hlY2tXYXJuZXIocG9zLCBmb3VuZCwgcmVxKTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBJbmZlcmVuY2VDb250ZXh0IGluZmVyZW5jZUNvbnRleHQoKSB7CiAgICAgICAgICAgIHJldHVybiBlbmNsb3NpbmdDb250ZXh0LmluZmVyZW5jZUNvbnRleHQoKTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBEZWZlcnJlZEF0dHJDb250ZXh0IGRlZmVycmVkQXR0ckNvbnRleHQoKSB7CiAgICAgICAgICAgIHJldHVybiBlbmNsb3NpbmdDb250ZXh0LmRlZmVycmVkQXR0ckNvbnRleHQoKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBDaGVjayBjb250ZXh0IHRvIGJlIHVzZWQgd2hlbiBldmFsdWF0aW5nIGFzc2lnbm1lbnQvcmV0dXJuIHN0YXRlbWVudHMKICAgICAqLwogICAgQ2hlY2tDb250ZXh0IGJhc2ljSGFuZGxlciA9IG5ldyBDaGVja0NvbnRleHQoKSB7CiAgICAgICAgcHVibGljIHZvaWQgcmVwb3J0KERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIEpDRGlhZ25vc3RpYyBkZXRhaWxzKSB7CiAgICAgICAgICAgIGxvZy5lcnJvcihwb3MsICJwcm9iLmZvdW5kLnJlcSIsIGRldGFpbHMpOwogICAgICAgIH0KICAgICAgICBwdWJsaWMgYm9vbGVhbiBjb21wYXRpYmxlKFR5cGUgZm91bmQsIFR5cGUgcmVxLCBXYXJuZXIgd2FybikgewogICAgICAgICAgICByZXR1cm4gdHlwZXMuaXNBc3NpZ25hYmxlKGZvdW5kLCByZXEsIHdhcm4pOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIFdhcm5lciBjaGVja1dhcm5lcihEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBUeXBlIGZvdW5kLCBUeXBlIHJlcSkgewogICAgICAgICAgICByZXR1cm4gY29udmVydFdhcm5lcihwb3MsIGZvdW5kLCByZXEpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIEluZmVyZW5jZUNvbnRleHQgaW5mZXJlbmNlQ29udGV4dCgpIHsKICAgICAgICAgICAgcmV0dXJuIGluZmVyLmVtcHR5Q29udGV4dDsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBEZWZlcnJlZEF0dHJDb250ZXh0IGRlZmVycmVkQXR0ckNvbnRleHQoKSB7CiAgICAgICAgICAgIHJldHVybiBkZWZlcnJlZEF0dHIuZW1wdHlEZWZlcnJlZEF0dHJDb250ZXh0OwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKICAgICAgICAgICAgcmV0dXJuICJDaGVja0NvbnRleHQ6IGJhc2ljSGFuZGxlciI7CiAgICAgICAgfQogICAgfTsKCiAgICAvKiogQ2hlY2sgdGhhdCBhIGdpdmVuIHR5cGUgaXMgYXNzaWduYWJsZSB0byBhIGdpdmVuIHByb3RvLXR5cGUuCiAgICAgKiAgSWYgaXQgaXMsIHJldHVybiB0aGUgdHlwZSwgb3RoZXJ3aXNlIHJldHVybiBlcnJUeXBlLgogICAgICogIEBwYXJhbSBwb3MgICAgICAgIFBvc2l0aW9uIHRvIGJlIHVzZWQgZm9yIGVycm9yIHJlcG9ydGluZy4KICAgICAqICBAcGFyYW0gZm91bmQgICAgICBUaGUgdHlwZSB0aGF0IHdhcyBmb3VuZC4KICAgICAqICBAcGFyYW0gcmVxICAgICAgICBUaGUgdHlwZSB0aGF0IHdhcyByZXF1aXJlZC4KICAgICAqLwogICAgcHVibGljIFR5cGUgY2hlY2tUeXBlKERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIFR5cGUgZm91bmQsIFR5cGUgcmVxKSB7CiAgICAgICAgcmV0dXJuIGNoZWNrVHlwZShwb3MsIGZvdW5kLCByZXEsIGJhc2ljSGFuZGxlcik7CiAgICB9CgogICAgVHlwZSBjaGVja1R5cGUoZmluYWwgRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcywgZmluYWwgVHlwZSBmb3VuZCwgZmluYWwgVHlwZSByZXEsIGZpbmFsIENoZWNrQ29udGV4dCBjaGVja0NvbnRleHQpIHsKICAgICAgICBmaW5hbCBJbmZlcmVuY2VDb250ZXh0IGluZmVyZW5jZUNvbnRleHQgPSBjaGVja0NvbnRleHQuaW5mZXJlbmNlQ29udGV4dCgpOwogICAgICAgIGlmIChpbmZlcmVuY2VDb250ZXh0LmZyZWUocmVxKSB8fCBpbmZlcmVuY2VDb250ZXh0LmZyZWUoZm91bmQpKSB7CiAgICAgICAgICAgIGluZmVyZW5jZUNvbnRleHQuYWRkRnJlZVR5cGVMaXN0ZW5lcihMaXN0Lm9mKHJlcSwgZm91bmQpLAogICAgICAgICAgICAgICAgICAgIHNvbHZlZENvbnRleHQgLT4gY2hlY2tUeXBlKHBvcywgc29sdmVkQ29udGV4dC5hc0luc3RUeXBlKGZvdW5kKSwgc29sdmVkQ29udGV4dC5hc0luc3RUeXBlKHJlcSksIGNoZWNrQ29udGV4dCkpOwogICAgICAgIH0KICAgICAgICBpZiAocmVxLmhhc1RhZyhFUlJPUikpCiAgICAgICAgICAgIHJldHVybiByZXE7CiAgICAgICAgaWYgKHJlcS5oYXNUYWcoTk9ORSkpCiAgICAgICAgICAgIHJldHVybiBmb3VuZDsKICAgICAgICBpZiAoY2hlY2tDb250ZXh0LmNvbXBhdGlibGUoZm91bmQsIHJlcSwgY2hlY2tDb250ZXh0LmNoZWNrV2FybmVyKHBvcywgZm91bmQsIHJlcSkpKSB7CiAgICAgICAgICAgIHJldHVybiBmb3VuZDsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBpZiAoZm91bmQuaXNOdW1lcmljKCkgJiYgcmVxLmlzTnVtZXJpYygpKSB7CiAgICAgICAgICAgICAgICBjaGVja0NvbnRleHQucmVwb3J0KHBvcywgZGlhZ3MuZnJhZ21lbnQoInBvc3NpYmxlLmxvc3Mub2YucHJlY2lzaW9uIiwgZm91bmQsIHJlcSkpOwogICAgICAgICAgICAgICAgcmV0dXJuIHR5cGVzLmNyZWF0ZUVycm9yVHlwZShmb3VuZCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY2hlY2tDb250ZXh0LnJlcG9ydChwb3MsIGRpYWdzLmZyYWdtZW50KCJpbmNvbnZlcnRpYmxlLnR5cGVzIiwgZm91bmQsIHJlcSkpOwogICAgICAgICAgICByZXR1cm4gdHlwZXMuY3JlYXRlRXJyb3JUeXBlKGZvdW5kKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqIENoZWNrIHRoYXQgYSBnaXZlbiB0eXBlIGNhbiBiZSBjYXN0IHRvIGEgZ2l2ZW4gdGFyZ2V0IHR5cGUuCiAgICAgKiAgUmV0dXJuIHRoZSByZXN1bHQgb2YgdGhlIGNhc3QuCiAgICAgKiAgQHBhcmFtIHBvcyAgICAgICAgUG9zaXRpb24gdG8gYmUgdXNlZCBmb3IgZXJyb3IgcmVwb3J0aW5nLgogICAgICogIEBwYXJhbSBmb3VuZCAgICAgIFRoZSB0eXBlIHRoYXQgaXMgYmVpbmcgY2FzdC4KICAgICAqICBAcGFyYW0gcmVxICAgICAgICBUaGUgdGFyZ2V0IHR5cGUgb2YgdGhlIGNhc3QuCiAgICAgKi8KICAgIFR5cGUgY2hlY2tDYXN0YWJsZShEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBUeXBlIGZvdW5kLCBUeXBlIHJlcSkgewogICAgICAgIHJldHVybiBjaGVja0Nhc3RhYmxlKHBvcywgZm91bmQsIHJlcSwgYmFzaWNIYW5kbGVyKTsKICAgIH0KICAgIFR5cGUgY2hlY2tDYXN0YWJsZShEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBUeXBlIGZvdW5kLCBUeXBlIHJlcSwgQ2hlY2tDb250ZXh0IGNoZWNrQ29udGV4dCkgewogICAgICAgIGlmICh0eXBlcy5pc0Nhc3RhYmxlKGZvdW5kLCByZXEsIGNhc3RXYXJuZXIocG9zLCBmb3VuZCwgcmVxKSkpIHsKICAgICAgICAgICAgcmV0dXJuIHJlcTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBjaGVja0NvbnRleHQucmVwb3J0KHBvcywgZGlhZ3MuZnJhZ21lbnQoImluY29udmVydGlibGUudHlwZXMiLCBmb3VuZCwgcmVxKSk7CiAgICAgICAgICAgIHJldHVybiB0eXBlcy5jcmVhdGVFcnJvclR5cGUoZm91bmQpOwogICAgICAgIH0KICAgIH0KCiAgICAvKiogQ2hlY2sgZm9yIHJlZHVuZGFudCBjYXN0cyAoaS5lLiB3aGVyZSBzb3VyY2UgdHlwZSBpcyBhIHN1YnR5cGUgb2YgdGFyZ2V0IHR5cGUpCiAgICAgKiBUaGUgcHJvYmxlbSBzaG91bGQgb25seSBiZSByZXBvcnRlZCBmb3Igbm9uLTI5MiBjYXN0CiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIGNoZWNrUmVkdW5kYW50Q2FzdChFbnY8QXR0ckNvbnRleHQ+IGVudiwgZmluYWwgSkNUeXBlQ2FzdCB0cmVlKSB7CiAgICAgICAgaWYgKCF0cmVlLnR5cGUuaXNFcnJvbmVvdXMoKQogICAgICAgICAgICAgICAgJiYgdHlwZXMuaXNTYW1lVHlwZSh0cmVlLmV4cHIudHlwZSwgdHJlZS5jbGF6ei50eXBlKQogICAgICAgICAgICAgICAgJiYgIShpZ25vcmVBbm5vdGF0ZWRDYXN0cyAmJiBUcmVlSW5mby5jb250YWluc1R5cGVBbm5vdGF0aW9uKHRyZWUuY2xhenopKQogICAgICAgICAgICAgICAgJiYgIWlzMjkydGFyZ2V0VHlwZUNhc3QodHJlZSkpIHsKICAgICAgICAgICAgZGVmZXJyZWRMaW50SGFuZGxlci5yZXBvcnQoKCkgLT4gewogICAgICAgICAgICAgICAgaWYgKGxpbnQuaXNFbmFibGVkKExpbnRDYXRlZ29yeS5DQVNUKSkKICAgICAgICAgICAgICAgICAgICBsb2cud2FybmluZyhMaW50Q2F0ZWdvcnkuQ0FTVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyZWUucG9zKCksICJyZWR1bmRhbnQuY2FzdCIsIHRyZWUuY2xhenoudHlwZSk7CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KICAgIH0KICAgIC8vd2hlcmUKICAgICAgICBwcml2YXRlIGJvb2xlYW4gaXMyOTJ0YXJnZXRUeXBlQ2FzdChKQ1R5cGVDYXN0IHRyZWUpIHsKICAgICAgICAgICAgYm9vbGVhbiBpczI5MnRhcmdldFR5cGVDYXN0ID0gZmFsc2U7CiAgICAgICAgICAgIEpDRXhwcmVzc2lvbiBleHByID0gVHJlZUluZm8uc2tpcFBhcmVucyh0cmVlLmV4cHIpOwogICAgICAgICAgICBpZiAoZXhwci5oYXNUYWcoQVBQTFkpKSB7CiAgICAgICAgICAgICAgICBKQ01ldGhvZEludm9jYXRpb24gYXBwbHkgPSAoSkNNZXRob2RJbnZvY2F0aW9uKWV4cHI7CiAgICAgICAgICAgICAgICBTeW1ib2wgc3ltID0gVHJlZUluZm8uc3ltYm9sKGFwcGx5Lm1ldGgpOwogICAgICAgICAgICAgICAgaXMyOTJ0YXJnZXRUeXBlQ2FzdCA9IHN5bSAhPSBudWxsICYmCiAgICAgICAgICAgICAgICAgICAgc3ltLmtpbmQgPT0gTVRIICYmCiAgICAgICAgICAgICAgICAgICAgKHN5bS5mbGFncygpICYgSFlQT1RIRVRJQ0FMKSAhPSAwOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBpczI5MnRhcmdldFR5cGVDYXN0OwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbiBpZ25vcmVBbm5vdGF0ZWRDYXN0cyA9IHRydWU7CgogICAgLyoqIENoZWNrIHRoYXQgYSB0eXBlIGlzIHdpdGhpbiBzb21lIGJvdW5kcy4KICAgICAqCiAgICAgKiAgVXNlZCBpbiBUeXBlQXBwbHkgdG8gdmVyaWZ5IHRoYXQsIGUuZy4sIFggaW4ge0Bjb2RlIFY8WD59IGlzIGEgdmFsaWQKICAgICAqICB0eXBlIGFyZ3VtZW50LgogICAgICogIEBwYXJhbSBhICAgICAgICAgICAgIFRoZSB0eXBlIHRoYXQgc2hvdWxkIGJlIGJvdW5kZWQgYnkgYnMuCiAgICAgKiAgQHBhcmFtIGJvdW5kICAgICAgICAgVGhlIGJvdW5kLgogICAgICovCiAgICBwcml2YXRlIGJvb2xlYW4gY2hlY2tFeHRlbmRzKFR5cGUgYSwgVHlwZSBib3VuZCkgewogICAgICAgICBpZiAoYS5pc1VuYm91bmQoKSkgewogICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgIH0gZWxzZSBpZiAoIWEuaGFzVGFnKFdJTERDQVJEKSkgewogICAgICAgICAgICAgYSA9IHR5cGVzLmN2YXJVcHBlckJvdW5kKGEpOwogICAgICAgICAgICAgcmV0dXJuIHR5cGVzLmlzU3VidHlwZShhLCBib3VuZCk7CiAgICAgICAgIH0gZWxzZSBpZiAoYS5pc0V4dGVuZHNCb3VuZCgpKSB7CiAgICAgICAgICAgICByZXR1cm4gdHlwZXMuaXNDYXN0YWJsZShib3VuZCwgdHlwZXMud2lsZFVwcGVyQm91bmQoYSksIHR5cGVzLm5vV2FybmluZ3MpOwogICAgICAgICB9IGVsc2UgaWYgKGEuaXNTdXBlckJvdW5kKCkpIHsKICAgICAgICAgICAgIHJldHVybiAhdHlwZXMubm90U29mdFN1YnR5cGUodHlwZXMud2lsZExvd2VyQm91bmQoYSksIGJvdW5kKTsKICAgICAgICAgfQogICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICB9CgogICAgLyoqIENoZWNrIHRoYXQgdHlwZSBpcyBkaWZmZXJlbnQgZnJvbSAndm9pZCcuCiAgICAgKiAgQHBhcmFtIHBvcyAgICAgICAgICAgUG9zaXRpb24gdG8gYmUgdXNlZCBmb3IgZXJyb3IgcmVwb3J0aW5nLgogICAgICogIEBwYXJhbSB0ICAgICAgICAgICAgIFRoZSB0eXBlIHRvIGJlIGNoZWNrZWQuCiAgICAgKi8KICAgIFR5cGUgY2hlY2tOb25Wb2lkKERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIFR5cGUgdCkgewogICAgICAgIGlmICh0Lmhhc1RhZyhWT0lEKSkgewogICAgICAgICAgICBsb2cuZXJyb3IocG9zLCAidm9pZC5ub3QuYWxsb3dlZC5oZXJlIik7CiAgICAgICAgICAgIHJldHVybiB0eXBlcy5jcmVhdGVFcnJvclR5cGUodCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIHQ7CiAgICAgICAgfQogICAgfQoKICAgIFR5cGUgY2hlY2tDbGFzc09yQXJyYXlUeXBlKERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIFR5cGUgdCkgewogICAgICAgIGlmICghdC5oYXNUYWcoQ0xBU1MpICYmICF0Lmhhc1RhZyhBUlJBWSkgJiYgIXQuaGFzVGFnKEVSUk9SKSkgewogICAgICAgICAgICByZXR1cm4gdHlwZVRhZ0Vycm9yKHBvcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaWFncy5mcmFnbWVudCgidHlwZS5yZXEuY2xhc3MuYXJyYXkiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhc1R5cGVQYXJhbSh0KSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIHQ7CiAgICAgICAgfQogICAgfQoKICAgIC8qKiBDaGVjayB0aGF0IHR5cGUgaXMgYSBjbGFzcyBvciBpbnRlcmZhY2UgdHlwZS4KICAgICAqICBAcGFyYW0gcG9zICAgICAgICAgICBQb3NpdGlvbiB0byBiZSB1c2VkIGZvciBlcnJvciByZXBvcnRpbmcuCiAgICAgKiAgQHBhcmFtIHQgICAgICAgICAgICAgVGhlIHR5cGUgdG8gYmUgY2hlY2tlZC4KICAgICAqLwogICAgVHlwZSBjaGVja0NsYXNzVHlwZShEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBUeXBlIHQpIHsKICAgICAgICBpZiAoIXQuaGFzVGFnKENMQVNTKSAmJiAhdC5oYXNUYWcoRVJST1IpKSB7CiAgICAgICAgICAgIHJldHVybiB0eXBlVGFnRXJyb3IocG9zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpYWdzLmZyYWdtZW50KCJ0eXBlLnJlcS5jbGFzcyIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFzVHlwZVBhcmFtKHQpKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gdDsKICAgICAgICB9CiAgICB9CiAgICAvL3doZXJlCiAgICAgICAgcHJpdmF0ZSBPYmplY3QgYXNUeXBlUGFyYW0oVHlwZSB0KSB7CiAgICAgICAgICAgIHJldHVybiAodC5oYXNUYWcoVFlQRVZBUikpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gZGlhZ3MuZnJhZ21lbnQoInR5cGUucGFyYW1ldGVyIiwgdCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiB0OwogICAgICAgIH0KCiAgICAvKiogQ2hlY2sgdGhhdCB0eXBlIGlzIGEgdmFsaWQgcXVhbGlmaWVyIGZvciBhIGNvbnN0cnVjdG9yIHJlZmVyZW5jZSBleHByZXNzaW9uCiAgICAgKi8KICAgIFR5cGUgY2hlY2tDb25zdHJ1Y3RvclJlZlR5cGUoRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcywgVHlwZSB0KSB7CiAgICAgICAgdCA9IGNoZWNrQ2xhc3NPckFycmF5VHlwZShwb3MsIHQpOwogICAgICAgIGlmICh0Lmhhc1RhZyhDTEFTUykpIHsKICAgICAgICAgICAgaWYgKCh0LnRzeW0uZmxhZ3MoKSAmIChBQlNUUkFDVCB8IElOVEVSRkFDRSkpICE9IDApIHsKICAgICAgICAgICAgICAgIGxvZy5lcnJvcihwb3MsICJhYnN0cmFjdC5jYW50LmJlLmluc3RhbnRpYXRlZCIsIHQudHN5bSk7CiAgICAgICAgICAgICAgICB0ID0gdHlwZXMuY3JlYXRlRXJyb3JUeXBlKHQpOwogICAgICAgICAgICB9IGVsc2UgaWYgKCh0LnRzeW0uZmxhZ3MoKSAmIEVOVU0pICE9IDApIHsKICAgICAgICAgICAgICAgIGxvZy5lcnJvcihwb3MsICJlbnVtLmNhbnQuYmUuaW5zdGFudGlhdGVkIik7CiAgICAgICAgICAgICAgICB0ID0gdHlwZXMuY3JlYXRlRXJyb3JUeXBlKHQpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdCA9IGNoZWNrQ2xhc3NUeXBlKHBvcywgdCwgdHJ1ZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgaWYgKHQuaGFzVGFnKEFSUkFZKSkgewogICAgICAgICAgICBpZiAoIXR5cGVzLmlzUmVpZmlhYmxlKCgoQXJyYXlUeXBlKXQpLmVsZW10eXBlKSkgewogICAgICAgICAgICAgICAgbG9nLmVycm9yKHBvcywgImdlbmVyaWMuYXJyYXkuY3JlYXRpb24iKTsKICAgICAgICAgICAgICAgIHQgPSB0eXBlcy5jcmVhdGVFcnJvclR5cGUodCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHQ7CiAgICB9CgogICAgLyoqIENoZWNrIHRoYXQgdHlwZSBpcyBhIGNsYXNzIG9yIGludGVyZmFjZSB0eXBlLgogICAgICogIEBwYXJhbSBwb3MgICAgICAgICAgIFBvc2l0aW9uIHRvIGJlIHVzZWQgZm9yIGVycm9yIHJlcG9ydGluZy4KICAgICAqICBAcGFyYW0gdCAgICAgICAgICAgICBUaGUgdHlwZSB0byBiZSBjaGVja2VkLgogICAgICogIEBwYXJhbSBub0JvdW5kcyAgICBUcnVlIGlmIHR5cGUgYm91bmRzIGFyZSBpbGxlZ2FsIGhlcmUuCiAgICAgKi8KICAgIFR5cGUgY2hlY2tDbGFzc1R5cGUoRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcywgVHlwZSB0LCBib29sZWFuIG5vQm91bmRzKSB7CiAgICAgICAgdCA9IGNoZWNrQ2xhc3NUeXBlKHBvcywgdCk7CiAgICAgICAgaWYgKG5vQm91bmRzICYmIHQuaXNQYXJhbWV0ZXJpemVkKCkpIHsKICAgICAgICAgICAgTGlzdDxUeXBlPiBhcmdzID0gdC5nZXRUeXBlQXJndW1lbnRzKCk7CiAgICAgICAgICAgIHdoaWxlIChhcmdzLm5vbkVtcHR5KCkpIHsKICAgICAgICAgICAgICAgIGlmIChhcmdzLmhlYWQuaGFzVGFnKFdJTERDQVJEKSkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHlwZVRhZ0Vycm9yKHBvcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpYWdzLmZyYWdtZW50KCJ0eXBlLnJlcS5leGFjdCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJncy5oZWFkKTsKICAgICAgICAgICAgICAgIGFyZ3MgPSBhcmdzLnRhaWw7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHQ7CiAgICB9CgogICAgLyoqIENoZWNrIHRoYXQgdHlwZSBpcyBhIHJlZmVyZW5jZSB0eXBlLCBpLmUuIGEgY2xhc3MsIGludGVyZmFjZSBvciBhcnJheSB0eXBlCiAgICAgKiAgb3IgYSB0eXBlIHZhcmlhYmxlLgogICAgICogIEBwYXJhbSBwb3MgICAgICAgICAgIFBvc2l0aW9uIHRvIGJlIHVzZWQgZm9yIGVycm9yIHJlcG9ydGluZy4KICAgICAqICBAcGFyYW0gdCAgICAgICAgICAgICBUaGUgdHlwZSB0byBiZSBjaGVja2VkLgogICAgICovCiAgICBUeXBlIGNoZWNrUmVmVHlwZShEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBUeXBlIHQpIHsKICAgICAgICBpZiAodC5pc1JlZmVyZW5jZSgpKQogICAgICAgICAgICByZXR1cm4gdDsKICAgICAgICBlbHNlCiAgICAgICAgICAgIHJldHVybiB0eXBlVGFnRXJyb3IocG9zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpYWdzLmZyYWdtZW50KCJ0eXBlLnJlcS5yZWYiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0KTsKICAgIH0KCiAgICAvKiogQ2hlY2sgdGhhdCBlYWNoIHR5cGUgaXMgYSByZWZlcmVuY2UgdHlwZSwgaS5lLiBhIGNsYXNzLCBpbnRlcmZhY2Ugb3IgYXJyYXkgdHlwZQogICAgICogIG9yIGEgdHlwZSB2YXJpYWJsZS4KICAgICAqICBAcGFyYW0gdHJlZXMgICAgICAgICBPcmlnaW5hbCB0cmVlcywgdXNlZCBmb3IgZXJyb3IgcmVwb3J0aW5nLgogICAgICogIEBwYXJhbSB0eXBlcyAgICAgICAgIFRoZSB0eXBlcyB0byBiZSBjaGVja2VkLgogICAgICovCiAgICBMaXN0PFR5cGU+IGNoZWNrUmVmVHlwZXMoTGlzdDxKQ0V4cHJlc3Npb24+IHRyZWVzLCBMaXN0PFR5cGU+IHR5cGVzKSB7CiAgICAgICAgTGlzdDxKQ0V4cHJlc3Npb24+IHRsID0gdHJlZXM7CiAgICAgICAgZm9yIChMaXN0PFR5cGU+IGwgPSB0eXBlczsgbC5ub25FbXB0eSgpOyBsID0gbC50YWlsKSB7CiAgICAgICAgICAgIGwuaGVhZCA9IGNoZWNrUmVmVHlwZSh0bC5oZWFkLnBvcygpLCBsLmhlYWQpOwogICAgICAgICAgICB0bCA9IHRsLnRhaWw7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0eXBlczsKICAgIH0KCiAgICAvKiogQ2hlY2sgdGhhdCB0eXBlIGlzIGEgbnVsbCBvciByZWZlcmVuY2UgdHlwZS4KICAgICAqICBAcGFyYW0gcG9zICAgICAgICAgICBQb3NpdGlvbiB0byBiZSB1c2VkIGZvciBlcnJvciByZXBvcnRpbmcuCiAgICAgKiAgQHBhcmFtIHQgICAgICAgICAgICAgVGhlIHR5cGUgdG8gYmUgY2hlY2tlZC4KICAgICAqLwogICAgVHlwZSBjaGVja051bGxPclJlZlR5cGUoRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcywgVHlwZSB0KSB7CiAgICAgICAgaWYgKHQuaXNSZWZlcmVuY2UoKSB8fCB0Lmhhc1RhZyhCT1QpKQogICAgICAgICAgICByZXR1cm4gdDsKICAgICAgICBlbHNlCiAgICAgICAgICAgIHJldHVybiB0eXBlVGFnRXJyb3IocG9zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpYWdzLmZyYWdtZW50KCJ0eXBlLnJlcS5yZWYiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0KTsKICAgIH0KCiAgICAvKiogQ2hlY2sgdGhhdCBmbGFnIHNldCBkb2VzIG5vdCBjb250YWluIGVsZW1lbnRzIG9mIHR3byBjb25mbGljdGluZyBzZXRzLiBzCiAgICAgKiAgUmV0dXJuIHRydWUgaWYgaXQgZG9lc24ndC4KICAgICAqICBAcGFyYW0gcG9zICAgICAgICAgICBQb3NpdGlvbiB0byBiZSB1c2VkIGZvciBlcnJvciByZXBvcnRpbmcuCiAgICAgKiAgQHBhcmFtIGZsYWdzICAgICAgICAgVGhlIHNldCBvZiBmbGFncyB0byBiZSBjaGVja2VkLgogICAgICogIEBwYXJhbSBzZXQxICAgICAgICAgIENvbmZsaWN0aW5nIGZsYWdzIHNldCAjMS4KICAgICAqICBAcGFyYW0gc2V0MiAgICAgICAgICBDb25mbGljdGluZyBmbGFncyBzZXQgIzIuCiAgICAgKi8KICAgIGJvb2xlYW4gY2hlY2tEaXNqb2ludChEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBsb25nIGZsYWdzLCBsb25nIHNldDEsIGxvbmcgc2V0MikgewogICAgICAgIGlmICgoZmxhZ3MgJiBzZXQxKSAhPSAwICYmIChmbGFncyAmIHNldDIpICE9IDApIHsKICAgICAgICAgICAgbG9nLmVycm9yKHBvcywKICAgICAgICAgICAgICAgICAgICAgICJpbGxlZ2FsLmNvbWJpbmF0aW9uLm9mLm1vZGlmaWVycyIsCiAgICAgICAgICAgICAgICAgICAgICBhc0ZsYWdTZXQoVHJlZUluZm8uZmlyc3RGbGFnKGZsYWdzICYgc2V0MSkpLAogICAgICAgICAgICAgICAgICAgICAgYXNGbGFnU2V0KFRyZWVJbmZvLmZpcnN0RmxhZyhmbGFncyAmIHNldDIpKSk7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9IGVsc2UKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgLyoqIENoZWNrIHRoYXQgdXNhZ2Ugb2YgZGlhbW9uZCBvcGVyYXRvciBpcyBjb3JyZWN0IChpLmUuIGRpYW1vbmQgc2hvdWxkIG5vdAogICAgICogYmUgdXNlZCB3aXRoIG5vbi1nZW5lcmljIGNsYXNzZXMgb3IgaW4gYW5vbnltb3VzIGNsYXNzIGNyZWF0aW9uIGV4cHJlc3Npb25zKQogICAgICovCiAgICBUeXBlIGNoZWNrRGlhbW9uZChKQ05ld0NsYXNzIHRyZWUsIFR5cGUgdCkgewogICAgICAgIGlmICghVHJlZUluZm8uaXNEaWFtb25kKHRyZWUpIHx8CiAgICAgICAgICAgICAgICB0LmlzRXJyb25lb3VzKCkpIHsKICAgICAgICAgICAgcmV0dXJuIGNoZWNrQ2xhc3NUeXBlKHRyZWUuY2xhenoucG9zKCksIHQsIHRydWUpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGlmICh0cmVlLmRlZiAhPSBudWxsICYmICFhbGxvd0RpYW1vbmRXaXRoQW5vbnltb3VzQ2xhc3NDcmVhdGlvbikgewogICAgICAgICAgICAgICAgbG9nLmVycm9yKERpYWdub3N0aWNGbGFnLlNPVVJDRV9MRVZFTCwgdHJlZS5jbGF6ei5wb3MoKSwKICAgICAgICAgICAgICAgICAgICAgICAgRXJyb3JzLkNhbnRBcHBseURpYW1vbmQxKHQsIEZyYWdtZW50cy5EaWFtb25kQW5kQW5vbkNsYXNzTm90U3VwcG9ydGVkSW5Tb3VyY2Uoc291cmNlLm5hbWUpKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHQudHN5bS50eXBlLmdldFR5cGVBcmd1bWVudHMoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICAgIGxvZy5lcnJvcih0cmVlLmNsYXp6LnBvcygpLAogICAgICAgICAgICAgICAgICAgICJjYW50LmFwcGx5LmRpYW1vbmQuMSIsCiAgICAgICAgICAgICAgICAgICAgdCwgZGlhZ3MuZnJhZ21lbnQoImRpYW1vbmQubm9uLmdlbmVyaWMiLCB0KSk7CiAgICAgICAgICAgICAgICByZXR1cm4gdHlwZXMuY3JlYXRlRXJyb3JUeXBlKHQpOwogICAgICAgICAgICB9IGVsc2UgaWYgKHRyZWUudHlwZWFyZ3MgIT0gbnVsbCAmJgogICAgICAgICAgICAgICAgICAgIHRyZWUudHlwZWFyZ3Mubm9uRW1wdHkoKSkgewogICAgICAgICAgICAgICAgbG9nLmVycm9yKHRyZWUuY2xhenoucG9zKCksCiAgICAgICAgICAgICAgICAgICAgImNhbnQuYXBwbHkuZGlhbW9uZC4xIiwKICAgICAgICAgICAgICAgICAgICB0LCBkaWFncy5mcmFnbWVudCgiZGlhbW9uZC5hbmQuZXhwbGljaXQucGFyYW1zIiwgdCkpOwogICAgICAgICAgICAgICAgcmV0dXJuIHR5cGVzLmNyZWF0ZUVycm9yVHlwZSh0KTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHJldHVybiB0OwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKiBDaGVjayB0aGF0IHRoZSB0eXBlIGluZmVycmVkIHVzaW5nIHRoZSBkaWFtb25kIG9wZXJhdG9yIGRvZXMgbm90IGNvbnRhaW4KICAgICAqICBub24tZGVub3RhYmxlIHR5cGVzIHN1Y2ggYXMgY2FwdHVyZWQgdHlwZXMgb3IgaW50ZXJzZWN0aW9uIHR5cGVzLgogICAgICogIEBwYXJhbSB0IHRoZSB0eXBlIGluZmVycmVkIHVzaW5nIHRoZSBkaWFtb25kIG9wZXJhdG9yCiAgICAgKiAgQHJldHVybiAgdGhlIChwb3NzaWJseSBlbXB0eSkgbGlzdCBvZiBub24tZGVub3RhYmxlIHR5cGVzLgogICAgICovCiAgICBMaXN0PFR5cGU+IGNoZWNrRGlhbW9uZERlbm90YWJsZShDbGFzc1R5cGUgdCkgewogICAgICAgIExpc3RCdWZmZXI8VHlwZT4gYnVmID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgIGZvciAoVHlwZSBhcmcgOiB0LmFsbHBhcmFtcygpKSB7CiAgICAgICAgICAgIGlmICghZGlhbW9uZFR5cGVDaGVja2VyLnZpc2l0KGFyZywgbnVsbCkpIHsKICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQoYXJnKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVmLnRvTGlzdCgpOwogICAgfQogICAgICAgIC8vIHdoZXJlCgogICAgICAgIC8qKiBkaWFtb25kVHlwZUNoZWNrZXI6IEEgdHlwZSB2aXNpdG9yIHRoYXQgZGVzY2VuZHMgZG93biB0aGUgZ2l2ZW4gdHlwZSBsb29raW5nIGZvciBub24tZGVub3RhYmxlCiAgICAgICAgICogIHR5cGVzLiBUaGUgdmlzaXQgbWV0aG9kcyByZXR1cm4gZmFsc2UgYXMgc29vbiBhcyBhIG5vbi1kZW5vdGFibGUgdHlwZSBpcyBlbmNvdW50ZXJlZCBhbmQgdHJ1ZQogICAgICAgICAqICBvdGhlcndpc2UuCiAgICAgICAgICovCiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVHlwZXMuU2ltcGxlVmlzaXRvcjxCb29sZWFuLCBWb2lkPiBkaWFtb25kVHlwZUNoZWNrZXIgPSBuZXcgVHlwZXMuU2ltcGxlVmlzaXRvcjxCb29sZWFuLCBWb2lkPigpIHsKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHB1YmxpYyBCb29sZWFuIHZpc2l0VHlwZShUeXBlIHQsIFZvaWQgcykgewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHB1YmxpYyBCb29sZWFuIHZpc2l0Q2xhc3NUeXBlKENsYXNzVHlwZSB0LCBWb2lkIHMpIHsKICAgICAgICAgICAgICAgIGlmICh0LmlzQ29tcG91bmQoKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGZvciAoVHlwZSB0YXJnIDogdC5hbGxwYXJhbXMoKSkgewogICAgICAgICAgICAgICAgICAgIGlmICghdmlzaXQodGFyZywgcykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHVibGljIEJvb2xlYW4gdmlzaXRUeXBlVmFyKFR5cGVWYXIgdCwgVm9pZCBzKSB7CiAgICAgICAgICAgICAgICAvKiBBbnkgdHlwZSB2YXJpYWJsZSBtZW50aW9uZWQgaW4gdGhlIGluZmVycmVkIHR5cGUgbXVzdCBoYXZlIGJlZW4gZGVjbGFyZWQgYXMgYSB0eXBlIHBhcmFtZXRlcgogICAgICAgICAgICAgICAgICAoaS5lIGNhbm5vdCBoYXZlIGJlZW4gcHJvZHVjZWQgYnkgaW5mZXJlbmNlICgxOC40KSkKICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICByZXR1cm4gdC50c3ltLm93bmVyLnR5cGUuZ2V0VHlwZUFyZ3VtZW50cygpLmNvbnRhaW5zKHQpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHVibGljIEJvb2xlYW4gdmlzaXRDYXB0dXJlZFR5cGUoQ2FwdHVyZWRUeXBlIHQsIFZvaWQgcykgewogICAgICAgICAgICAgICAgLyogQW55IHR5cGUgdmFyaWFibGUgbWVudGlvbmVkIGluIHRoZSBpbmZlcnJlZCB0eXBlIG11c3QgaGF2ZSBiZWVuIGRlY2xhcmVkIGFzIGEgdHlwZSBwYXJhbWV0ZXIKICAgICAgICAgICAgICAgICAgKGkuZSBjYW5ub3QgaGF2ZSBiZWVuIHByb2R1Y2VkIGJ5IGNhcHR1cmUgY29udmVyc2lvbiAoNS4xLjEwKSkKICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgQm9vbGVhbiB2aXNpdEFycmF5VHlwZShBcnJheVR5cGUgdCwgVm9pZCBzKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdmlzaXQodC5lbGVtdHlwZSwgcyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgQm9vbGVhbiB2aXNpdFdpbGRjYXJkVHlwZShXaWxkY2FyZFR5cGUgdCwgVm9pZCBzKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdmlzaXQodC50eXBlLCBzKTsKICAgICAgICAgICAgfQogICAgICAgIH07CgogICAgdm9pZCBjaGVja1ZhcmFyZ3NNZXRob2REZWNsKEVudjxBdHRyQ29udGV4dD4gZW52LCBKQ01ldGhvZERlY2wgdHJlZSkgewogICAgICAgIE1ldGhvZFN5bWJvbCBtID0gdHJlZS5zeW07CiAgICAgICAgaWYgKCFhbGxvd1NpbXBsaWZpZWRWYXJhcmdzKSByZXR1cm47CiAgICAgICAgYm9vbGVhbiBoYXNUcnVzdE1lQW5ubyA9IG0uYXR0cmlidXRlKHN5bXMudHJ1c3RNZVR5cGUudHN5bSkgIT0gbnVsbDsKICAgICAgICBUeXBlIHZhcmFyZ0VsZW1UeXBlID0gbnVsbDsKICAgICAgICBpZiAobS5pc1ZhckFyZ3MoKSkgewogICAgICAgICAgICB2YXJhcmdFbGVtVHlwZSA9IHR5cGVzLmVsZW10eXBlKHRyZWUucGFyYW1zLmxhc3QoKS50eXBlKTsKICAgICAgICB9CiAgICAgICAgaWYgKGhhc1RydXN0TWVBbm5vICYmICFpc1RydXN0TWVBbGxvd2VkT25NZXRob2QobSkpIHsKICAgICAgICAgICAgaWYgKHZhcmFyZ0VsZW1UeXBlICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIGxvZy5lcnJvcih0cmVlLAogICAgICAgICAgICAgICAgICAgICAgICAidmFyYXJncy5pbnZhbGlkLnRydXN0bWUuYW5ubyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgc3ltcy50cnVzdE1lVHlwZS50c3ltLAogICAgICAgICAgICAgICAgICAgICAgICAgIGFsbG93UHJpdmF0ZVNhZmVWYXJhcmdzID8KICAgICAgICAgICAgICAgICAgICAgICAgICBkaWFncy5mcmFnbWVudCgidmFyYXJncy50cnVzdG1lLm9uLnZpcnR1YWwudmFyYXJncyIsIG0pIDoKICAgICAgICAgICAgICAgICAgICAgICAgICBkaWFncy5mcmFnbWVudCgidmFyYXJncy50cnVzdG1lLm9uLnZpcnR1YWwudmFyYXJncy5maW5hbC5vbmx5IiwgbSkpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgbG9nLmVycm9yKHRyZWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAidmFyYXJncy5pbnZhbGlkLnRydXN0bWUuYW5ubyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeW1zLnRydXN0TWVUeXBlLnRzeW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaWFncy5mcmFnbWVudCgidmFyYXJncy50cnVzdG1lLm9uLm5vbi52YXJhcmdzLm1ldGgiLCBtKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgaWYgKGhhc1RydXN0TWVBbm5vICYmIHZhcmFyZ0VsZW1UeXBlICE9IG51bGwgJiYKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVzLmlzUmVpZmlhYmxlKHZhcmFyZ0VsZW1UeXBlKSkgewogICAgICAgICAgICB3YXJuVW5zYWZlVmFyYXJnKHRyZWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAidmFyYXJncy5yZWR1bmRhbnQudHJ1c3RtZS5hbm5vIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5bXMudHJ1c3RNZVR5cGUudHN5bSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpYWdzLmZyYWdtZW50KCJ2YXJhcmdzLnRydXN0bWUub24ucmVpZmlhYmxlLnZhcmFyZ3MiLCB2YXJhcmdFbGVtVHlwZSkpOwogICAgICAgIH0KICAgICAgICBlbHNlIGlmICghaGFzVHJ1c3RNZUFubm8gJiYgdmFyYXJnRWxlbVR5cGUgIT0gbnVsbCAmJgogICAgICAgICAgICAgICAgIXR5cGVzLmlzUmVpZmlhYmxlKHZhcmFyZ0VsZW1UeXBlKSkgewogICAgICAgICAgICB3YXJuVW5jaGVja2VkKHRyZWUucGFyYW1zLmhlYWQucG9zKCksICJ1bmNoZWNrZWQudmFyYXJncy5ub24ucmVpZmlhYmxlLnR5cGUiLCB2YXJhcmdFbGVtVHlwZSk7CiAgICAgICAgfQogICAgfQogICAgLy93aGVyZQogICAgICAgIHByaXZhdGUgYm9vbGVhbiBpc1RydXN0TWVBbGxvd2VkT25NZXRob2QoU3ltYm9sIHMpIHsKICAgICAgICAgICAgcmV0dXJuIChzLmZsYWdzKCkgJiBWQVJBUkdTKSAhPSAwICYmCiAgICAgICAgICAgICAgICAocy5pc0NvbnN0cnVjdG9yKCkgfHwKICAgICAgICAgICAgICAgICAgICAocy5mbGFncygpICYgKFNUQVRJQyB8IEZJTkFMIHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChhbGxvd1ByaXZhdGVTYWZlVmFyYXJncyA/IFBSSVZBVEUgOiAwKSApKSAhPSAwKTsKICAgICAgICB9CgogICAgVHlwZSBjaGVja01ldGhvZChmaW5hbCBUeXBlIG10eXBlLAogICAgICAgICAgICBmaW5hbCBTeW1ib2wgc3ltLAogICAgICAgICAgICBmaW5hbCBFbnY8QXR0ckNvbnRleHQ+IGVudiwKICAgICAgICAgICAgZmluYWwgTGlzdDxKQ0V4cHJlc3Npb24+IGFyZ3RyZWVzLAogICAgICAgICAgICBmaW5hbCBMaXN0PFR5cGU+IGFyZ3R5cGVzLAogICAgICAgICAgICBmaW5hbCBib29sZWFuIHVzZVZhcmFyZ3MsCiAgICAgICAgICAgIEluZmVyZW5jZUNvbnRleHQgaW5mZXJlbmNlQ29udGV4dCkgewogICAgICAgIC8vIFN5c3RlbS5vdXQucHJpbnRsbigiY2FsbCAgIDogIiArIGVudi50cmVlKTsKICAgICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oIm1ldGhvZCA6ICIgKyBvd250eXBlKTsKICAgICAgICAvLyBTeXN0ZW0ub3V0LnByaW50bG4oImFjdHVhbHM6ICIgKyBhcmd0eXBlcyk7CiAgICAgICAgaWYgKGluZmVyZW5jZUNvbnRleHQuZnJlZShtdHlwZSkpIHsKICAgICAgICAgICAgaW5mZXJlbmNlQ29udGV4dC5hZGRGcmVlVHlwZUxpc3RlbmVyKExpc3Qub2YobXR5cGUpLAogICAgICAgICAgICAgICAgICAgIHNvbHZlZENvbnRleHQgLT4gY2hlY2tNZXRob2Qoc29sdmVkQ29udGV4dC5hc0luc3RUeXBlKG10eXBlKSwgc3ltLCBlbnYsIGFyZ3RyZWVzLCBhcmd0eXBlcywgdXNlVmFyYXJncywgc29sdmVkQ29udGV4dCkpOwogICAgICAgICAgICByZXR1cm4gbXR5cGU7CiAgICAgICAgfQogICAgICAgIFR5cGUgb3dudHlwZSA9IG10eXBlOwogICAgICAgIExpc3Q8VHlwZT4gZm9ybWFscyA9IG93bnR5cGUuZ2V0UGFyYW1ldGVyVHlwZXMoKTsKICAgICAgICBMaXN0PFR5cGU+IG5vbkluZmVycmVkID0gc3ltLnR5cGUuZ2V0UGFyYW1ldGVyVHlwZXMoKTsKICAgICAgICBpZiAobm9uSW5mZXJyZWQubGVuZ3RoKCkgIT0gZm9ybWFscy5sZW5ndGgoKSkgbm9uSW5mZXJyZWQgPSBmb3JtYWxzOwogICAgICAgIFR5cGUgbGFzdCA9IHVzZVZhcmFyZ3MgPyBmb3JtYWxzLmxhc3QoKSA6IG51bGw7CiAgICAgICAgaWYgKHN5bS5uYW1lID09IG5hbWVzLmluaXQgJiYgc3ltLm93bmVyID09IHN5bXMuZW51bVN5bSkgewogICAgICAgICAgICBmb3JtYWxzID0gZm9ybWFscy50YWlsLnRhaWw7CiAgICAgICAgICAgIG5vbkluZmVycmVkID0gbm9uSW5mZXJyZWQudGFpbC50YWlsOwogICAgICAgIH0KICAgICAgICBMaXN0PEpDRXhwcmVzc2lvbj4gYXJncyA9IGFyZ3RyZWVzOwogICAgICAgIGlmIChhcmdzICE9IG51bGwpIHsKICAgICAgICAgICAgLy90aGlzIGlzIG51bGwgd2hlbiB0eXBlLWNoZWNraW5nIGEgbWV0aG9kIHJlZmVyZW5jZQogICAgICAgICAgICB3aGlsZSAoZm9ybWFscy5oZWFkICE9IGxhc3QpIHsKICAgICAgICAgICAgICAgIEpDVHJlZSBhcmcgPSBhcmdzLmhlYWQ7CiAgICAgICAgICAgICAgICBXYXJuZXIgd2FybiA9IGNvbnZlcnRXYXJuZXIoYXJnLnBvcygpLCBhcmcudHlwZSwgbm9uSW5mZXJyZWQuaGVhZCk7CiAgICAgICAgICAgICAgICBhc3NlcnRDb252ZXJ0aWJsZShhcmcsIGFyZy50eXBlLCBmb3JtYWxzLmhlYWQsIHdhcm4pOwogICAgICAgICAgICAgICAgYXJncyA9IGFyZ3MudGFpbDsKICAgICAgICAgICAgICAgIGZvcm1hbHMgPSBmb3JtYWxzLnRhaWw7CiAgICAgICAgICAgICAgICBub25JbmZlcnJlZCA9IG5vbkluZmVycmVkLnRhaWw7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHVzZVZhcmFyZ3MpIHsKICAgICAgICAgICAgICAgIFR5cGUgdmFyQXJnID0gdHlwZXMuZWxlbXR5cGUobGFzdCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoYXJncy50YWlsICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICBKQ1RyZWUgYXJnID0gYXJncy5oZWFkOwogICAgICAgICAgICAgICAgICAgIFdhcm5lciB3YXJuID0gY29udmVydFdhcm5lcihhcmcucG9zKCksIGFyZy50eXBlLCB2YXJBcmcpOwogICAgICAgICAgICAgICAgICAgIGFzc2VydENvbnZlcnRpYmxlKGFyZywgYXJnLnR5cGUsIHZhckFyZywgd2Fybik7CiAgICAgICAgICAgICAgICAgICAgYXJncyA9IGFyZ3MudGFpbDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIGlmICgoc3ltLmZsYWdzKCkgJiAoVkFSQVJHUyB8IFNJR05BVFVSRV9QT0xZTU9SUEhJQykpID09IFZBUkFSR1MpIHsKICAgICAgICAgICAgICAgIC8vIG5vbi12YXJhcmdzIGNhbGwgdG8gdmFyYXJncyBtZXRob2QKICAgICAgICAgICAgICAgIFR5cGUgdmFyUGFyYW0gPSBvd250eXBlLmdldFBhcmFtZXRlclR5cGVzKCkubGFzdCgpOwogICAgICAgICAgICAgICAgVHlwZSBsYXN0QXJnID0gYXJndHlwZXMubGFzdCgpOwogICAgICAgICAgICAgICAgaWYgKHR5cGVzLmlzU3VidHlwZVVuY2hlY2tlZChsYXN0QXJnLCB0eXBlcy5lbGVtdHlwZSh2YXJQYXJhbSkpICYmCiAgICAgICAgICAgICAgICAgICAgIXR5cGVzLmlzU2FtZVR5cGUodHlwZXMuZXJhc3VyZSh2YXJQYXJhbSksIHR5cGVzLmVyYXN1cmUobGFzdEFyZykpKQogICAgICAgICAgICAgICAgICAgIGxvZy53YXJuaW5nKGFyZ3RyZWVzLmxhc3QoKS5wb3MoKSwgImluZXhhY3Qubm9uLXZhcmFyZ3MuY2FsbCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZXMuZWxlbXR5cGUodmFyUGFyYW0pLCB2YXJQYXJhbSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKHVzZVZhcmFyZ3MpIHsKICAgICAgICAgICAgVHlwZSBhcmd0eXBlID0gb3dudHlwZS5nZXRQYXJhbWV0ZXJUeXBlcygpLmxhc3QoKTsKICAgICAgICAgICAgaWYgKCF0eXBlcy5pc1JlaWZpYWJsZShhcmd0eXBlKSAmJgogICAgICAgICAgICAgICAgKCFhbGxvd1NpbXBsaWZpZWRWYXJhcmdzIHx8CiAgICAgICAgICAgICAgICAgc3ltLmJhc2VTeW1ib2woKS5hdHRyaWJ1dGUoc3ltcy50cnVzdE1lVHlwZS50c3ltKSA9PSBudWxsIHx8CiAgICAgICAgICAgICAgICAgIWlzVHJ1c3RNZUFsbG93ZWRPbk1ldGhvZChzeW0pKSkgewogICAgICAgICAgICAgICAgd2FyblVuY2hlY2tlZChlbnYudHJlZS5wb3MoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ1bmNoZWNrZWQuZ2VuZXJpYy5hcnJheS5jcmVhdGlvbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmd0eXBlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoKHN5bS5iYXNlU3ltYm9sKCkuZmxhZ3MoKSAmIFNJR05BVFVSRV9QT0xZTU9SUEhJQykgPT0gMCkgewogICAgICAgICAgICAgICAgVHJlZUluZm8uc2V0VmFyYXJnc0VsZW1lbnQoZW52LnRyZWUsIHR5cGVzLmVsZW10eXBlKGFyZ3R5cGUpKTsKICAgICAgICAgICAgfQogICAgICAgICB9CiAgICAgICAgIHJldHVybiBvd250eXBlOwogICAgfQogICAgLy93aGVyZQogICAgcHJpdmF0ZSB2b2lkIGFzc2VydENvbnZlcnRpYmxlKEpDVHJlZSB0cmVlLCBUeXBlIGFjdHVhbCwgVHlwZSBmb3JtYWwsIFdhcm5lciB3YXJuKSB7CiAgICAgICAgaWYgKHR5cGVzLmlzQ29udmVydGlibGUoYWN0dWFsLCBmb3JtYWwsIHdhcm4pKQogICAgICAgICAgICByZXR1cm47CgogICAgICAgIGlmIChmb3JtYWwuaXNDb21wb3VuZCgpCiAgICAgICAgICAgICYmIHR5cGVzLmlzU3VidHlwZShhY3R1YWwsIHR5cGVzLnN1cGVydHlwZShmb3JtYWwpKQogICAgICAgICAgICAmJiB0eXBlcy5pc1N1YnR5cGVVbmNoZWNrZWQoYWN0dWFsLCB0eXBlcy5pbnRlcmZhY2VzKGZvcm1hbCksIHdhcm4pKQogICAgICAgICAgICByZXR1cm47CiAgICB9CgogICAgLyoqCiAgICAgKiBDaGVjayB0aGF0IHR5cGUgJ3QnIGlzIGEgdmFsaWQgaW5zdGFudGlhdGlvbiBvZiBhIGdlbmVyaWMgY2xhc3MKICAgICAqIChzZWUgSkxTIDQuNSkKICAgICAqCiAgICAgKiBAcGFyYW0gdCBjbGFzcyB0eXBlIHRvIGJlIGNoZWNrZWQKICAgICAqIEByZXR1cm4gdHJ1ZSBpZiAndCcgaXMgd2VsbC1mb3JtZWQKICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gY2hlY2tWYWxpZEdlbmVyaWNUeXBlKFR5cGUgdCkgewogICAgICAgIHJldHVybiBmaXJzdEluY29tcGF0aWJsZVR5cGVBcmcodCkgPT0gbnVsbDsKICAgIH0KICAgIC8vV0hFUkUKICAgICAgICBwcml2YXRlIFR5cGUgZmlyc3RJbmNvbXBhdGlibGVUeXBlQXJnKFR5cGUgdHlwZSkgewogICAgICAgICAgICBMaXN0PFR5cGU+IGZvcm1hbHMgPSB0eXBlLnRzeW0udHlwZS5hbGxwYXJhbXMoKTsKICAgICAgICAgICAgTGlzdDxUeXBlPiBhY3R1YWxzID0gdHlwZS5hbGxwYXJhbXMoKTsKICAgICAgICAgICAgTGlzdDxUeXBlPiBhcmdzID0gdHlwZS5nZXRUeXBlQXJndW1lbnRzKCk7CiAgICAgICAgICAgIExpc3Q8VHlwZT4gZm9ybXMgPSB0eXBlLnRzeW0udHlwZS5nZXRUeXBlQXJndW1lbnRzKCk7CiAgICAgICAgICAgIExpc3RCdWZmZXI8VHlwZT4gYm91bmRzX2J1ZiA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKCiAgICAgICAgICAgIC8vIEZvciBtYXRjaGluZyBwYWlycyBvZiBhY3R1YWwgYXJndW1lbnQgdHlwZXMgYGEnIGFuZAogICAgICAgICAgICAvLyBmb3JtYWwgdHlwZSBwYXJhbWV0ZXJzIHdpdGggZGVjbGFyZWQgYm91bmQgYGInIC4uLgogICAgICAgICAgICB3aGlsZSAoYXJncy5ub25FbXB0eSgpICYmIGZvcm1zLm5vbkVtcHR5KCkpIHsKICAgICAgICAgICAgICAgIC8vIGV4YWN0IHR5cGUgYXJndW1lbnRzIG5lZWRzIHRvIGtub3cgdGhlaXIKICAgICAgICAgICAgICAgIC8vIGJvdW5kcyAoZm9yIHVwcGVyIGFuZCBsb3dlciBib3VuZAogICAgICAgICAgICAgICAgLy8gY2FsY3VsYXRpb25zKS4gIFNvIHdlIGNyZWF0ZSBuZXcgYm91bmRzIHdoZXJlCiAgICAgICAgICAgICAgICAvLyB0eXBlLXBhcmFtZXRlcnMgYXJlIHJlcGxhY2VkIHdpdGggYWN0dWFscyBhcmd1bWVudCB0eXBlcy4KICAgICAgICAgICAgICAgIGJvdW5kc19idWYuYXBwZW5kKHR5cGVzLnN1YnN0KGZvcm1zLmhlYWQuZ2V0VXBwZXJCb3VuZCgpLCBmb3JtYWxzLCBhY3R1YWxzKSk7CiAgICAgICAgICAgICAgICBhcmdzID0gYXJncy50YWlsOwogICAgICAgICAgICAgICAgZm9ybXMgPSBmb3Jtcy50YWlsOwogICAgICAgICAgICB9CgogICAgICAgICAgICBhcmdzID0gdHlwZS5nZXRUeXBlQXJndW1lbnRzKCk7CiAgICAgICAgICAgIExpc3Q8VHlwZT4gdHZhcnNfY2FwID0gdHlwZXMuc3Vic3RCb3VuZHMoZm9ybWFscywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JtYWxzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVzLmNhcHR1cmUodHlwZSkuYWxscGFyYW1zKCkpOwogICAgICAgICAgICB3aGlsZSAoYXJncy5ub25FbXB0eSgpICYmIHR2YXJzX2NhcC5ub25FbXB0eSgpKSB7CiAgICAgICAgICAgICAgICAvLyBMZXQgdGhlIGFjdHVhbCBhcmd1bWVudHMga25vdyB0aGVpciBib3VuZAogICAgICAgICAgICAgICAgYXJncy5oZWFkLndpdGhUeXBlVmFyKChUeXBlVmFyKXR2YXJzX2NhcC5oZWFkKTsKICAgICAgICAgICAgICAgIGFyZ3MgPSBhcmdzLnRhaWw7CiAgICAgICAgICAgICAgICB0dmFyc19jYXAgPSB0dmFyc19jYXAudGFpbDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgYXJncyA9IHR5cGUuZ2V0VHlwZUFyZ3VtZW50cygpOwogICAgICAgICAgICBMaXN0PFR5cGU+IGJvdW5kcyA9IGJvdW5kc19idWYudG9MaXN0KCk7CgogICAgICAgICAgICB3aGlsZSAoYXJncy5ub25FbXB0eSgpICYmIGJvdW5kcy5ub25FbXB0eSgpKSB7CiAgICAgICAgICAgICAgICBUeXBlIGFjdHVhbCA9IGFyZ3MuaGVhZDsKICAgICAgICAgICAgICAgIGlmICghaXNUeXBlQXJnRXJyb25lb3VzKGFjdHVhbCkgJiYKICAgICAgICAgICAgICAgICAgICAgICAgIWJvdW5kcy5oZWFkLmlzRXJyb25lb3VzKCkgJiYKICAgICAgICAgICAgICAgICAgICAgICAgIWNoZWNrRXh0ZW5kcyhhY3R1YWwsIGJvdW5kcy5oZWFkKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBhcmdzLmhlYWQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBhcmdzID0gYXJncy50YWlsOwogICAgICAgICAgICAgICAgYm91bmRzID0gYm91bmRzLnRhaWw7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGFyZ3MgPSB0eXBlLmdldFR5cGVBcmd1bWVudHMoKTsKICAgICAgICAgICAgYm91bmRzID0gYm91bmRzX2J1Zi50b0xpc3QoKTsKCiAgICAgICAgICAgIGZvciAoVHlwZSBhcmcgOiB0eXBlcy5jYXB0dXJlKHR5cGUpLmdldFR5cGVBcmd1bWVudHMoKSkgewogICAgICAgICAgICAgICAgaWYgKGFyZy5oYXNUYWcoVFlQRVZBUikgJiYKICAgICAgICAgICAgICAgICAgICAgICAgYXJnLmdldFVwcGVyQm91bmQoKS5pc0Vycm9uZW91cygpICYmCiAgICAgICAgICAgICAgICAgICAgICAgICFib3VuZHMuaGVhZC5pc0Vycm9uZW91cygpICYmCiAgICAgICAgICAgICAgICAgICAgICAgICFpc1R5cGVBcmdFcnJvbmVvdXMoYXJncy5oZWFkKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBhcmdzLmhlYWQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBib3VuZHMgPSBib3VuZHMudGFpbDsKICAgICAgICAgICAgICAgIGFyZ3MgPSBhcmdzLnRhaWw7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgICAvL3doZXJlCiAgICAgICAgYm9vbGVhbiBpc1R5cGVBcmdFcnJvbmVvdXMoVHlwZSB0KSB7CiAgICAgICAgICAgIHJldHVybiBpc1R5cGVBcmdFcnJvbmVvdXMudmlzaXQodCk7CiAgICAgICAgfQoKICAgICAgICBUeXBlcy5VbmFyeVZpc2l0b3I8Qm9vbGVhbj4gaXNUeXBlQXJnRXJyb25lb3VzID0gbmV3IFR5cGVzLlVuYXJ5VmlzaXRvcjxCb29sZWFuPigpIHsKICAgICAgICAgICAgcHVibGljIEJvb2xlYW4gdmlzaXRUeXBlKFR5cGUgdCwgVm9pZCBzKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdC5pc0Vycm9uZW91cygpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgQm9vbGVhbiB2aXNpdFR5cGVWYXIoVHlwZVZhciB0LCBWb2lkIHMpIHsKICAgICAgICAgICAgICAgIHJldHVybiB2aXNpdCh0LmdldFVwcGVyQm91bmQoKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHB1YmxpYyBCb29sZWFuIHZpc2l0Q2FwdHVyZWRUeXBlKENhcHR1cmVkVHlwZSB0LCBWb2lkIHMpIHsKICAgICAgICAgICAgICAgIHJldHVybiB2aXNpdCh0LmdldFVwcGVyQm91bmQoKSkgfHwKICAgICAgICAgICAgICAgICAgICAgICAgdmlzaXQodC5nZXRMb3dlckJvdW5kKCkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgQm9vbGVhbiB2aXNpdFdpbGRjYXJkVHlwZShXaWxkY2FyZFR5cGUgdCwgVm9pZCBzKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdmlzaXQodC50eXBlKTsKICAgICAgICAgICAgfQogICAgICAgIH07CgogICAgLyoqIENoZWNrIHRoYXQgZ2l2ZW4gbW9kaWZpZXJzIGFyZSBsZWdhbCBmb3IgZ2l2ZW4gc3ltYm9sIGFuZAogICAgICogIHJldHVybiBtb2RpZmllcnMgdG9nZXRoZXIgd2l0aCBhbnkgaW1wbGljaXQgbW9kaWZpZXJzIGZvciB0aGF0IHN5bWJvbC4KICAgICAqICBXYXJuaW5nOiB3ZSBjYW4ndCB1c2UgZmxhZ3MoKSBoZXJlIHNpbmNlIHRoaXMgbWV0aG9kCiAgICAgKiAgaXMgY2FsbGVkIGR1cmluZyBjbGFzcyBlbnRlciwgd2hlbiBmbGFncygpIHdvdWxkIGNhdXNlIGEgcHJlbWF0dXJlCiAgICAgKiAgY29tcGxldGlvbi4KICAgICAqICBAcGFyYW0gcG9zICAgICAgICAgICBQb3NpdGlvbiB0byBiZSB1c2VkIGZvciBlcnJvciByZXBvcnRpbmcuCiAgICAgKiAgQHBhcmFtIGZsYWdzICAgICAgICAgVGhlIHNldCBvZiBtb2RpZmllcnMgZ2l2ZW4gaW4gYSBkZWZpbml0aW9uLgogICAgICogIEBwYXJhbSBzeW0gICAgICAgICAgIFRoZSBkZWZpbmVkIHN5bWJvbC4KICAgICAqLwogICAgbG9uZyBjaGVja0ZsYWdzKERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIGxvbmcgZmxhZ3MsIFN5bWJvbCBzeW0sIEpDVHJlZSB0cmVlKSB7CiAgICAgICAgbG9uZyBtYXNrOwogICAgICAgIGxvbmcgaW1wbGljaXQgPSAwOwoKICAgICAgICBzd2l0Y2ggKHN5bS5raW5kKSB7CiAgICAgICAgY2FzZSBWQVI6CiAgICAgICAgICAgIGlmIChUcmVlSW5mby5pc1JlY2VpdmVyUGFyYW0odHJlZSkpCiAgICAgICAgICAgICAgICBtYXNrID0gUmVjZWl2ZXJQYXJhbUZsYWdzOwogICAgICAgICAgICBlbHNlIGlmIChzeW0ub3duZXIua2luZCAhPSBUWVApCiAgICAgICAgICAgICAgICBtYXNrID0gTG9jYWxWYXJGbGFnczsKICAgICAgICAgICAgZWxzZSBpZiAoKHN5bS5vd25lci5mbGFnc19maWVsZCAmIElOVEVSRkFDRSkgIT0gMCkKICAgICAgICAgICAgICAgIG1hc2sgPSBpbXBsaWNpdCA9IEludGVyZmFjZVZhckZsYWdzOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBtYXNrID0gVmFyRmxhZ3M7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgTVRIOgogICAgICAgICAgICBpZiAoc3ltLm5hbWUgPT0gbmFtZXMuaW5pdCkgewogICAgICAgICAgICAgICAgaWYgKChzeW0ub3duZXIuZmxhZ3NfZmllbGQgJiBFTlVNKSAhPSAwKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gZW51bSBjb25zdHJ1Y3RvcnMgY2Fubm90IGJlIGRlY2xhcmVkIHB1YmxpYyBvcgogICAgICAgICAgICAgICAgICAgIC8vIHByb3RlY3RlZCBhbmQgbXVzdCBiZSBpbXBsaWNpdGx5IG9yIGV4cGxpY2l0bHkKICAgICAgICAgICAgICAgICAgICAvLyBwcml2YXRlCiAgICAgICAgICAgICAgICAgICAgaW1wbGljaXQgPSBQUklWQVRFOwogICAgICAgICAgICAgICAgICAgIG1hc2sgPSBQUklWQVRFOwogICAgICAgICAgICAgICAgfSBlbHNlCiAgICAgICAgICAgICAgICAgICAgbWFzayA9IENvbnN0cnVjdG9yRmxhZ3M7CiAgICAgICAgICAgIH0gIGVsc2UgaWYgKChzeW0ub3duZXIuZmxhZ3NfZmllbGQgJiBJTlRFUkZBQ0UpICE9IDApIHsKICAgICAgICAgICAgICAgIGlmICgoc3ltLm93bmVyLmZsYWdzX2ZpZWxkICYgQU5OT1RBVElPTikgIT0gMCkgewogICAgICAgICAgICAgICAgICAgIG1hc2sgPSBBbm5vdGF0aW9uVHlwZUVsZW1lbnRNYXNrOwogICAgICAgICAgICAgICAgICAgIGltcGxpY2l0ID0gUFVCTElDIHwgQUJTVFJBQ1Q7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKChmbGFncyAmIChERUZBVUxUIHwgU1RBVElDIHwgUFJJVkFURSkpICE9IDApIHsKICAgICAgICAgICAgICAgICAgICBtYXNrID0gSW50ZXJmYWNlTWV0aG9kTWFzazsKICAgICAgICAgICAgICAgICAgICBpbXBsaWNpdCA9IChmbGFncyAmIFBSSVZBVEUpICE9IDAgPyAwIDogUFVCTElDOwogICAgICAgICAgICAgICAgICAgIGlmICgoZmxhZ3MgJiBERUZBVUxUKSAhPSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGltcGxpY2l0IHw9IEFCU1RSQUNUOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgbWFzayA9IGltcGxpY2l0ID0gSW50ZXJmYWNlTWV0aG9kRmxhZ3M7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBtYXNrID0gTWV0aG9kRmxhZ3M7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gSW1wbHkgU1RSSUNURlAgaWYgb3duZXIgaGFzIFNUUklDVEZQIHNldC4KICAgICAgICAgICAgaWYgKCgoZmxhZ3N8aW1wbGljaXQpICYgRmxhZ3MuQUJTVFJBQ1QpID09IDAgfHwKICAgICAgICAgICAgICAgICgoZmxhZ3MpICYgRmxhZ3MuREVGQVVMVCkgIT0gMCkKICAgICAgICAgICAgICAgIGltcGxpY2l0IHw9IHN5bS5vd25lci5mbGFnc19maWVsZCAmIFNUUklDVEZQOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFRZUDoKICAgICAgICAgICAgaWYgKHN5bS5pc0xvY2FsKCkpIHsKICAgICAgICAgICAgICAgIG1hc2sgPSBMb2NhbENsYXNzRmxhZ3M7CiAgICAgICAgICAgICAgICBpZiAoKHN5bS5vd25lci5mbGFnc19maWVsZCAmIFNUQVRJQykgPT0gMCAmJgogICAgICAgICAgICAgICAgICAgIChmbGFncyAmIEVOVU0pICE9IDApCiAgICAgICAgICAgICAgICAgICAgbG9nLmVycm9yKHBvcywgImVudW1zLm11c3QuYmUuc3RhdGljIik7CiAgICAgICAgICAgIH0gZWxzZSBpZiAoc3ltLm93bmVyLmtpbmQgPT0gVFlQKSB7CiAgICAgICAgICAgICAgICBtYXNrID0gTWVtYmVyQ2xhc3NGbGFnczsKICAgICAgICAgICAgICAgIGlmIChzeW0ub3duZXIub3duZXIua2luZCA9PSBQQ0sgfHwKICAgICAgICAgICAgICAgICAgICAoc3ltLm93bmVyLmZsYWdzX2ZpZWxkICYgU1RBVElDKSAhPSAwKQogICAgICAgICAgICAgICAgICAgIG1hc2sgfD0gU1RBVElDOwogICAgICAgICAgICAgICAgZWxzZSBpZiAoKGZsYWdzICYgRU5VTSkgIT0gMCkKICAgICAgICAgICAgICAgICAgICBsb2cuZXJyb3IocG9zLCAiZW51bXMubXVzdC5iZS5zdGF0aWMiKTsKICAgICAgICAgICAgICAgIC8vIE5lc3RlZCBpbnRlcmZhY2VzIGFuZCBlbnVtcyBhcmUgYWx3YXlzIFNUQVRJQyAoU3BlYyA/Pz8pCiAgICAgICAgICAgICAgICBpZiAoKGZsYWdzICYgKElOVEVSRkFDRSB8IEVOVU0pKSAhPSAwICkgaW1wbGljaXQgPSBTVEFUSUM7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBtYXNrID0gQ2xhc3NGbGFnczsKICAgICAgICAgICAgfQogICAgICAgICAgICAvLyBJbnRlcmZhY2VzIGFyZSBhbHdheXMgQUJTVFJBQ1QKICAgICAgICAgICAgaWYgKChmbGFncyAmIElOVEVSRkFDRSkgIT0gMCkgaW1wbGljaXQgfD0gQUJTVFJBQ1Q7CgogICAgICAgICAgICBpZiAoKGZsYWdzICYgRU5VTSkgIT0gMCkgewogICAgICAgICAgICAgICAgLy8gZW51bXMgY2FuJ3QgYmUgZGVjbGFyZWQgYWJzdHJhY3Qgb3IgZmluYWwKICAgICAgICAgICAgICAgIG1hc2sgJj0gfihBQlNUUkFDVCB8IEZJTkFMKTsKICAgICAgICAgICAgICAgIGltcGxpY2l0IHw9IGltcGxpY2l0RW51bUZpbmFsRmxhZyh0cmVlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvLyBJbXBseSBTVFJJQ1RGUCBpZiBvd25lciBoYXMgU1RSSUNURlAgc2V0LgogICAgICAgICAgICBpbXBsaWNpdCB8PSBzeW0ub3duZXIuZmxhZ3NfZmllbGQgJiBTVFJJQ1RGUDsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCk7CiAgICAgICAgfQogICAgICAgIGxvbmcgaWxsZWdhbCA9IGZsYWdzICYgRXh0ZW5kZWRTdGFuZGFyZEZsYWdzICYgfm1hc2s7CiAgICAgICAgaWYgKGlsbGVnYWwgIT0gMCkgewogICAgICAgICAgICBpZiAoKGlsbGVnYWwgJiBJTlRFUkZBQ0UpICE9IDApIHsKICAgICAgICAgICAgICAgIGxvZy5lcnJvcihwb3MsICJpbnRmLm5vdC5hbGxvd2VkLmhlcmUiKTsKICAgICAgICAgICAgICAgIG1hc2sgfD0gSU5URVJGQUNFOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgbG9nLmVycm9yKHBvcywKICAgICAgICAgICAgICAgICAgICAgICAgICAibW9kLm5vdC5hbGxvd2VkLmhlcmUiLCBhc0ZsYWdTZXQoaWxsZWdhbCkpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKChzeW0ua2luZCA9PSBUWVAgfHwKICAgICAgICAgICAgICAgICAgLy8gSVNTVUU6IERpc2FsbG93aW5nIGFic3RyYWN0JnByaXZhdGUgaXMgbm8gbG9uZ2VyIGFwcHJvcHJpYXRlCiAgICAgICAgICAgICAgICAgIC8vIGluIHRoZSBwcmVzZW5jZSBvZiBpbm5lciBjbGFzc2VzLiBTaG91bGQgaXQgYmUgZGVsZXRlZCBoZXJlPwogICAgICAgICAgICAgICAgICBjaGVja0Rpc2pvaW50KHBvcywgZmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQUJTVFJBQ1QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUFJJVkFURSB8IFNUQVRJQyB8IERFRkFVTFQpKQogICAgICAgICAgICAgICAgICYmCiAgICAgICAgICAgICAgICAgY2hlY2tEaXNqb2ludChwb3MsIGZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNUQVRJQyB8IFBSSVZBVEUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgREVGQVVMVCkKICAgICAgICAgICAgICAgICAmJgogICAgICAgICAgICAgICAgIGNoZWNrRGlzam9pbnQocG9zLCBmbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFCU1RSQUNUIHwgSU5URVJGQUNFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRklOQUwgfCBOQVRJVkUgfCBTWU5DSFJPTklaRUQpCiAgICAgICAgICAgICAgICAgJiYKICAgICAgICAgICAgICAgICBjaGVja0Rpc2pvaW50KHBvcywgZmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQVUJMSUMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQUklWQVRFIHwgUFJPVEVDVEVEKQogICAgICAgICAgICAgICAgICYmCiAgICAgICAgICAgICAgICAgY2hlY2tEaXNqb2ludChwb3MsIGZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUFJJVkFURSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBVQkxJQyB8IFBST1RFQ1RFRCkKICAgICAgICAgICAgICAgICAmJgogICAgICAgICAgICAgICAgIGNoZWNrRGlzam9pbnQocG9zLCBmbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZJTkFMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVk9MQVRJTEUpCiAgICAgICAgICAgICAgICAgJiYKICAgICAgICAgICAgICAgICAoc3ltLmtpbmQgPT0gVFlQIHx8CiAgICAgICAgICAgICAgICAgIGNoZWNrRGlzam9pbnQocG9zLCBmbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBQlNUUkFDVCB8IE5BVElWRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTVFJJQ1RGUCkpKSB7CiAgICAgICAgICAgIC8vIHNraXAKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZsYWdzICYgKG1hc2sgfCB+RXh0ZW5kZWRTdGFuZGFyZEZsYWdzKSB8IGltcGxpY2l0OwogICAgfQoKCiAgICAvKiogRGV0ZXJtaW5lIGlmIHRoaXMgZW51bSBzaG91bGQgYmUgaW1wbGljaXRseSBmaW5hbC4KICAgICAqCiAgICAgKiAgSWYgdGhlIGVudW0gaGFzIG5vIHNwZWNpYWxpemVkIGVudW0gY29udGFudHMsIGl0IGlzIGZpbmFsLgogICAgICoKICAgICAqICBJZiB0aGUgZW51bSBkb2VzIGhhdmUgc3BlY2lhbGl6ZWQgZW51bSBjb250YW50cywgaXQgaXMKICAgICAqICA8aT5ub3Q8L2k+IGZpbmFsLgogICAgICovCiAgICBwcml2YXRlIGxvbmcgaW1wbGljaXRFbnVtRmluYWxGbGFnKEpDVHJlZSB0cmVlKSB7CiAgICAgICAgaWYgKCF0cmVlLmhhc1RhZyhDTEFTU0RFRikpIHJldHVybiAwOwogICAgICAgIGNsYXNzIFNwZWNpYWxUcmVlVmlzaXRvciBleHRlbmRzIEpDVHJlZS5WaXNpdG9yIHsKICAgICAgICAgICAgYm9vbGVhbiBzcGVjaWFsaXplZDsKICAgICAgICAgICAgU3BlY2lhbFRyZWVWaXNpdG9yKCkgewogICAgICAgICAgICAgICAgdGhpcy5zcGVjaWFsaXplZCA9IGZhbHNlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHVibGljIHZvaWQgdmlzaXRUcmVlKEpDVHJlZSB0cmVlKSB7IC8qIG5vLW9wICovIH0KCiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdFZhckRlZihKQ1ZhcmlhYmxlRGVjbCB0cmVlKSB7CiAgICAgICAgICAgICAgICBpZiAoKHRyZWUubW9kcy5mbGFncyAmIEVOVU0pICE9IDApIHsKICAgICAgICAgICAgICAgICAgICBpZiAodHJlZS5pbml0IGluc3RhbmNlb2YgSkNOZXdDbGFzcyAmJgogICAgICAgICAgICAgICAgICAgICAgICAoKEpDTmV3Q2xhc3MpIHRyZWUuaW5pdCkuZGVmICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgc3BlY2lhbGl6ZWQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgU3BlY2lhbFRyZWVWaXNpdG9yIHN0cyA9IG5ldyBTcGVjaWFsVHJlZVZpc2l0b3IoKTsKICAgICAgICBKQ0NsYXNzRGVjbCBjZGVmID0gKEpDQ2xhc3NEZWNsKSB0cmVlOwogICAgICAgIGZvciAoSkNUcmVlIGRlZnM6IGNkZWYuZGVmcykgewogICAgICAgICAgICBkZWZzLmFjY2VwdChzdHMpOwogICAgICAgICAgICBpZiAoc3RzLnNwZWNpYWxpemVkKSByZXR1cm4gMDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIEZJTkFMOwogICAgfQoKLyogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBUeXBlIFZhbGlkYXRpb24KICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKICAgIC8qKiBWYWxpZGF0ZSBhIHR5cGUgZXhwcmVzc2lvbi4gVGhhdCBpcywKICAgICAqICBjaGVjayB0aGF0IGFsbCB0eXBlIGFyZ3VtZW50cyBvZiBhIHBhcmFtZXRyaWMgdHlwZSBhcmUgd2l0aGluCiAgICAgKiAgdGhlaXIgYm91bmRzLiBUaGlzIG11c3QgYmUgZG9uZSBpbiBhIHNlY29uZCBwaGFzZSBhZnRlciB0eXBlIGF0dHJpYnV0aW9uCiAgICAgKiAgc2luY2UgYSBjbGFzcyBtaWdodCBoYXZlIGEgc3ViY2xhc3MgYXMgdHlwZSBwYXJhbWV0ZXIgYm91bmQuIEUuZzoKICAgICAqCiAgICAgKiAgPHByZT57QGNvZGUKICAgICAqICBjbGFzcyBCPEEgZXh0ZW5kcyBDPiB7IC4uLiB9CiAgICAgKiAgY2xhc3MgQyBleHRlbmRzIEI8Qz4geyAuLi4gfQogICAgICogIH08L3ByZT4KICAgICAqCiAgICAgKiAgYW5kIHdlIGNhbid0IG1ha2Ugc3VyZSB0aGF0IHRoZSBib3VuZCBpcyBhbHJlYWR5IGF0dHJpYnV0ZWQgYmVjYXVzZQogICAgICogIG9mIHBvc3NpYmxlIGN5Y2xlcy4KICAgICAqCiAgICAgKiBWaXNpdG9yIG1ldGhvZDogVmFsaWRhdGUgYSB0eXBlIGV4cHJlc3Npb24sIGlmIGl0IGlzIG5vdCBudWxsLCBjYXRjaGluZwogICAgICogIGFuZCByZXBvcnRpbmcgYW55IGNvbXBsZXRpb24gZmFpbHVyZXMuCiAgICAgKi8KICAgIHZvaWQgdmFsaWRhdGUoSkNUcmVlIHRyZWUsIEVudjxBdHRyQ29udGV4dD4gZW52KSB7CiAgICAgICAgdmFsaWRhdGUodHJlZSwgZW52LCB0cnVlKTsKICAgIH0KICAgIHZvaWQgdmFsaWRhdGUoSkNUcmVlIHRyZWUsIEVudjxBdHRyQ29udGV4dD4gZW52LCBib29sZWFuIGNoZWNrUmF3KSB7CiAgICAgICAgbmV3IFZhbGlkYXRvcihlbnYpLnZhbGlkYXRlVHJlZSh0cmVlLCBjaGVja1JhdywgdHJ1ZSk7CiAgICB9CgogICAgLyoqIFZpc2l0b3IgbWV0aG9kOiBWYWxpZGF0ZSBhIGxpc3Qgb2YgdHlwZSBleHByZXNzaW9ucy4KICAgICAqLwogICAgdm9pZCB2YWxpZGF0ZShMaXN0PD8gZXh0ZW5kcyBKQ1RyZWU+IHRyZWVzLCBFbnY8QXR0ckNvbnRleHQ+IGVudikgewogICAgICAgIGZvciAoTGlzdDw/IGV4dGVuZHMgSkNUcmVlPiBsID0gdHJlZXM7IGwubm9uRW1wdHkoKTsgbCA9IGwudGFpbCkKICAgICAgICAgICAgdmFsaWRhdGUobC5oZWFkLCBlbnYpOwogICAgfQoKICAgIC8qKiBBIHZpc2l0b3IgY2xhc3MgZm9yIHR5cGUgdmFsaWRhdGlvbi4KICAgICAqLwogICAgY2xhc3MgVmFsaWRhdG9yIGV4dGVuZHMgSkNUcmVlLlZpc2l0b3IgewoKICAgICAgICBib29sZWFuIGNoZWNrUmF3OwogICAgICAgIGJvb2xlYW4gaXNPdXRlcjsKICAgICAgICBFbnY8QXR0ckNvbnRleHQ+IGVudjsKCiAgICAgICAgVmFsaWRhdG9yKEVudjxBdHRyQ29udGV4dD4gZW52KSB7CiAgICAgICAgICAgIHRoaXMuZW52ID0gZW52OwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRUeXBlQXJyYXkoSkNBcnJheVR5cGVUcmVlIHRyZWUpIHsKICAgICAgICAgICAgdmFsaWRhdGVUcmVlKHRyZWUuZWxlbXR5cGUsIGNoZWNrUmF3LCBpc091dGVyKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0VHlwZUFwcGx5KEpDVHlwZUFwcGx5IHRyZWUpIHsKICAgICAgICAgICAgaWYgKHRyZWUudHlwZS5oYXNUYWcoQ0xBU1MpKSB7CiAgICAgICAgICAgICAgICBMaXN0PEpDRXhwcmVzc2lvbj4gYXJncyA9IHRyZWUuYXJndW1lbnRzOwogICAgICAgICAgICAgICAgTGlzdDxUeXBlPiBmb3JtcyA9IHRyZWUudHlwZS50c3ltLnR5cGUuZ2V0VHlwZUFyZ3VtZW50cygpOwoKICAgICAgICAgICAgICAgIFR5cGUgaW5jb21wYXRpYmxlQXJnID0gZmlyc3RJbmNvbXBhdGlibGVUeXBlQXJnKHRyZWUudHlwZSk7CiAgICAgICAgICAgICAgICBpZiAoaW5jb21wYXRpYmxlQXJnICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICBmb3IgKEpDVHJlZSBhcmcgOiB0cmVlLmFyZ3VtZW50cykgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXJnLnR5cGUgPT0gaW5jb21wYXRpYmxlQXJnKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2cuZXJyb3IoYXJnLCAibm90LndpdGhpbi5ib3VuZHMiLCBpbmNvbXBhdGlibGVBcmcsIGZvcm1zLmhlYWQpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGZvcm1zID0gZm9ybXMudGFpbDsKICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBmb3JtcyA9IHRyZWUudHlwZS50c3ltLnR5cGUuZ2V0VHlwZUFyZ3VtZW50cygpOwoKICAgICAgICAgICAgICAgIGJvb2xlYW4gaXNfamF2YV9sYW5nX0NsYXNzID0gdHJlZS50eXBlLnRzeW0uZmxhdE5hbWUoKSA9PSBuYW1lcy5qYXZhX2xhbmdfQ2xhc3M7CgogICAgICAgICAgICAgICAgLy8gRm9yIG1hdGNoaW5nIHBhaXJzIG9mIGFjdHVhbCBhcmd1bWVudCB0eXBlcyBgYScgYW5kCiAgICAgICAgICAgICAgICAvLyBmb3JtYWwgdHlwZSBwYXJhbWV0ZXJzIHdpdGggZGVjbGFyZWQgYm91bmQgYGInIC4uLgogICAgICAgICAgICAgICAgd2hpbGUgKGFyZ3Mubm9uRW1wdHkoKSAmJiBmb3Jtcy5ub25FbXB0eSgpKSB7CiAgICAgICAgICAgICAgICAgICAgdmFsaWRhdGVUcmVlKGFyZ3MuaGVhZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICEoaXNPdXRlciAmJiBpc19qYXZhX2xhbmdfQ2xhc3MpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFsc2UpOwogICAgICAgICAgICAgICAgICAgIGFyZ3MgPSBhcmdzLnRhaWw7CiAgICAgICAgICAgICAgICAgICAgZm9ybXMgPSBmb3Jtcy50YWlsOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIENoZWNrIHRoYXQgdGhpcyB0eXBlIGlzIGVpdGhlciBmdWxseSBwYXJhbWV0ZXJpemVkLCBvcgogICAgICAgICAgICAgICAgLy8gbm90IHBhcmFtZXRlcml6ZWQgYXQgYWxsLgogICAgICAgICAgICAgICAgaWYgKHRyZWUudHlwZS5nZXRFbmNsb3NpbmdUeXBlKCkuaXNSYXcoKSkKICAgICAgICAgICAgICAgICAgICBsb2cuZXJyb3IodHJlZS5wb3MoKSwgImltcHJvcGVybHkuZm9ybWVkLnR5cGUuaW5uZXIucmF3LnBhcmFtIik7CiAgICAgICAgICAgICAgICBpZiAodHJlZS5jbGF6ei5oYXNUYWcoU0VMRUNUKSkKICAgICAgICAgICAgICAgICAgICB2aXNpdFNlbGVjdEludGVybmFsKChKQ0ZpZWxkQWNjZXNzKXRyZWUuY2xhenopOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdFR5cGVQYXJhbWV0ZXIoSkNUeXBlUGFyYW1ldGVyIHRyZWUpIHsKICAgICAgICAgICAgdmFsaWRhdGVUcmVlcyh0cmVlLmJvdW5kcywgdHJ1ZSwgaXNPdXRlcik7CiAgICAgICAgICAgIGNoZWNrQ2xhc3NCb3VuZHModHJlZS5wb3MoKSwgdHJlZS50eXBlKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0V2lsZGNhcmQoSkNXaWxkY2FyZCB0cmVlKSB7CiAgICAgICAgICAgIGlmICh0cmVlLmlubmVyICE9IG51bGwpCiAgICAgICAgICAgICAgICB2YWxpZGF0ZVRyZWUodHJlZS5pbm5lciwgdHJ1ZSwgaXNPdXRlcik7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdFNlbGVjdChKQ0ZpZWxkQWNjZXNzIHRyZWUpIHsKICAgICAgICAgICAgaWYgKHRyZWUudHlwZS5oYXNUYWcoQ0xBU1MpKSB7CiAgICAgICAgICAgICAgICB2aXNpdFNlbGVjdEludGVybmFsKHRyZWUpOwoKICAgICAgICAgICAgICAgIC8vIENoZWNrIHRoYXQgdGhpcyB0eXBlIGlzIGVpdGhlciBmdWxseSBwYXJhbWV0ZXJpemVkLCBvcgogICAgICAgICAgICAgICAgLy8gbm90IHBhcmFtZXRlcml6ZWQgYXQgYWxsLgogICAgICAgICAgICAgICAgaWYgKHRyZWUuc2VsZWN0ZWQudHlwZS5pc1BhcmFtZXRlcml6ZWQoKSAmJiB0cmVlLnR5cGUudHN5bS50eXBlLmdldFR5cGVBcmd1bWVudHMoKS5ub25FbXB0eSgpKQogICAgICAgICAgICAgICAgICAgIGxvZy5lcnJvcih0cmVlLnBvcygpLCAiaW1wcm9wZXJseS5mb3JtZWQudHlwZS5wYXJhbS5taXNzaW5nIik7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0U2VsZWN0SW50ZXJuYWwoSkNGaWVsZEFjY2VzcyB0cmVlKSB7CiAgICAgICAgICAgIGlmICh0cmVlLnR5cGUudHN5bS5pc1N0YXRpYygpICYmCiAgICAgICAgICAgICAgICB0cmVlLnNlbGVjdGVkLnR5cGUuaXNQYXJhbWV0ZXJpemVkKCkpIHsKICAgICAgICAgICAgICAgIC8vIFRoZSBlbmNsb3NpbmcgdHlwZSBpcyBub3QgYSBjbGFzcywgc28gd2UgYXJlCiAgICAgICAgICAgICAgICAvLyBsb29raW5nIGF0IGEgc3RhdGljIG1lbWJlciB0eXBlLiAgSG93ZXZlciwgdGhlCiAgICAgICAgICAgICAgICAvLyBxdWFsaWZ5aW5nIGV4cHJlc3Npb24gaXMgcGFyYW1ldGVyaXplZC4KICAgICAgICAgICAgICAgIGxvZy5lcnJvcih0cmVlLnBvcygpLCAiY2FudC5zZWxlY3Quc3RhdGljLmNsYXNzLmZyb20ucGFyYW0udHlwZSIpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgLy8gb3RoZXJ3aXNlIHZhbGlkYXRlIHRoZSByZXN0IG9mIHRoZSBleHByZXNzaW9uCiAgICAgICAgICAgICAgICB0cmVlLnNlbGVjdGVkLmFjY2VwdCh0aGlzKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRBbm5vdGF0ZWRUeXBlKEpDQW5ub3RhdGVkVHlwZSB0cmVlKSB7CiAgICAgICAgICAgIHRyZWUudW5kZXJseWluZ1R5cGUuYWNjZXB0KHRoaXMpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRUeXBlSWRlbnQoSkNQcmltaXRpdmVUeXBlVHJlZSB0aGF0KSB7CiAgICAgICAgICAgIGlmICh0aGF0LnR5cGUuaGFzVGFnKFR5cGVUYWcuVk9JRCkpIHsKICAgICAgICAgICAgICAgIGxvZy5lcnJvcih0aGF0LnBvcygpLCAidm9pZC5ub3QuYWxsb3dlZC5oZXJlIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc3VwZXIudmlzaXRUeXBlSWRlbnQodGhhdCk7CiAgICAgICAgfQoKICAgICAgICAvKiogRGVmYXVsdCB2aXNpdG9yIG1ldGhvZDogZG8gbm90aGluZy4KICAgICAgICAgKi8KICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdFRyZWUoSkNUcmVlIHRyZWUpIHsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyB2b2lkIHZhbGlkYXRlVHJlZShKQ1RyZWUgdHJlZSwgYm9vbGVhbiBjaGVja1JhdywgYm9vbGVhbiBpc091dGVyKSB7CiAgICAgICAgICAgIGlmICh0cmVlICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIGJvb2xlYW4gcHJldkNoZWNrUmF3ID0gdGhpcy5jaGVja1JhdzsKICAgICAgICAgICAgICAgIHRoaXMuY2hlY2tSYXcgPSBjaGVja1JhdzsKICAgICAgICAgICAgICAgIHRoaXMuaXNPdXRlciA9IGlzT3V0ZXI7CgogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICB0cmVlLmFjY2VwdCh0aGlzKTsKICAgICAgICAgICAgICAgICAgICBpZiAoY2hlY2tSYXcpCiAgICAgICAgICAgICAgICAgICAgICAgIGNoZWNrUmF3KHRyZWUsIGVudik7CiAgICAgICAgICAgICAgICB9IGNhdGNoIChDb21wbGV0aW9uRmFpbHVyZSBleCkgewogICAgICAgICAgICAgICAgICAgIGNvbXBsZXRpb25FcnJvcih0cmVlLnBvcygpLCBleCk7CiAgICAgICAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAgICAgICAgIHRoaXMuY2hlY2tSYXcgPSBwcmV2Q2hlY2tSYXc7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHB1YmxpYyB2b2lkIHZhbGlkYXRlVHJlZXMoTGlzdDw/IGV4dGVuZHMgSkNUcmVlPiB0cmVlcywgYm9vbGVhbiBjaGVja1JhdywgYm9vbGVhbiBpc091dGVyKSB7CiAgICAgICAgICAgIGZvciAoTGlzdDw/IGV4dGVuZHMgSkNUcmVlPiBsID0gdHJlZXM7IGwubm9uRW1wdHkoKTsgbCA9IGwudGFpbCkKICAgICAgICAgICAgICAgIHZhbGlkYXRlVHJlZShsLmhlYWQsIGNoZWNrUmF3LCBpc091dGVyKTsKICAgICAgICB9CiAgICB9CgogICAgdm9pZCBjaGVja1JhdyhKQ1RyZWUgdHJlZSwgRW52PEF0dHJDb250ZXh0PiBlbnYpIHsKICAgICAgICBpZiAobGludC5pc0VuYWJsZWQoTGludENhdGVnb3J5LlJBVykgJiYKICAgICAgICAgICAgdHJlZS50eXBlLmhhc1RhZyhDTEFTUykgJiYKICAgICAgICAgICAgIVRyZWVJbmZvLmlzRGlhbW9uZCh0cmVlKSAmJgogICAgICAgICAgICAhd2l0aGluQW5vbkNvbnN0cihlbnYpICYmCiAgICAgICAgICAgIHRyZWUudHlwZS5pc1JhdygpKSB7CiAgICAgICAgICAgIGxvZy53YXJuaW5nKExpbnRDYXRlZ29yeS5SQVcsCiAgICAgICAgICAgICAgICAgICAgdHJlZS5wb3MoKSwgInJhdy5jbGFzcy51c2UiLCB0cmVlLnR5cGUsIHRyZWUudHlwZS50c3ltLnR5cGUpOwogICAgICAgIH0KICAgIH0KICAgIC8vd2hlcmUKICAgICAgICBwcml2YXRlIGJvb2xlYW4gd2l0aGluQW5vbkNvbnN0cihFbnY8QXR0ckNvbnRleHQ+IGVudikgewogICAgICAgICAgICByZXR1cm4gZW52LmVuY2xDbGFzcy5uYW1lLmlzRW1wdHkoKSAmJgogICAgICAgICAgICAgICAgICAgIGVudi5lbmNsTWV0aG9kICE9IG51bGwgJiYgZW52LmVuY2xNZXRob2QubmFtZSA9PSBuYW1lcy5pbml0OwogICAgICAgIH0KCi8qICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRXhjZXB0aW9uIGNoZWNraW5nCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiAgICAvKiBUaGUgZm9sbG93aW5nIG1ldGhvZHMgdHJlYXQgY2xhc3NlcyBhcyBzZXRzIHRoYXQgY29udGFpbgogICAgICogdGhlIGNsYXNzIGl0c2VsZiBhbmQgYWxsIHRoZWlyIHN1YmNsYXNzZXMKICAgICAqLwoKICAgIC8qKiBJcyBnaXZlbiB0eXBlIGEgc3VidHlwZSBvZiBzb21lIG9mIHRoZSB0eXBlcyBpbiBnaXZlbiBsaXN0PwogICAgICovCiAgICBib29sZWFuIHN1YnNldChUeXBlIHQsIExpc3Q8VHlwZT4gdHMpIHsKICAgICAgICBmb3IgKExpc3Q8VHlwZT4gbCA9IHRzOyBsLm5vbkVtcHR5KCk7IGwgPSBsLnRhaWwpCiAgICAgICAgICAgIGlmICh0eXBlcy5pc1N1YnR5cGUodCwgbC5oZWFkKSkgcmV0dXJuIHRydWU7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIC8qKiBJcyBnaXZlbiB0eXBlIGEgc3VidHlwZSBvciBzdXBlcnR5cGUgb2YKICAgICAqICBzb21lIG9mIHRoZSB0eXBlcyBpbiBnaXZlbiBsaXN0PwogICAgICovCiAgICBib29sZWFuIGludGVyc2VjdHMoVHlwZSB0LCBMaXN0PFR5cGU+IHRzKSB7CiAgICAgICAgZm9yIChMaXN0PFR5cGU+IGwgPSB0czsgbC5ub25FbXB0eSgpOyBsID0gbC50YWlsKQogICAgICAgICAgICBpZiAodHlwZXMuaXNTdWJ0eXBlKHQsIGwuaGVhZCkgfHwgdHlwZXMuaXNTdWJ0eXBlKGwuaGVhZCwgdCkpIHJldHVybiB0cnVlOwogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICAvKiogQWRkIHR5cGUgc2V0IHRvIGdpdmVuIHR5cGUgbGlzdCwgdW5sZXNzIGl0IGlzIGEgc3ViY2xhc3Mgb2Ygc29tZSBjbGFzcwogICAgICogIGluIHRoZSBsaXN0LgogICAgICovCiAgICBMaXN0PFR5cGU+IGluY2woVHlwZSB0LCBMaXN0PFR5cGU+IHRzKSB7CiAgICAgICAgcmV0dXJuIHN1YnNldCh0LCB0cykgPyB0cyA6IGV4Y2wodCwgdHMpLnByZXBlbmQodCk7CiAgICB9CgogICAgLyoqIFJlbW92ZSB0eXBlIHNldCBmcm9tIHR5cGUgc2V0IGxpc3QuCiAgICAgKi8KICAgIExpc3Q8VHlwZT4gZXhjbChUeXBlIHQsIExpc3Q8VHlwZT4gdHMpIHsKICAgICAgICBpZiAodHMuaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJldHVybiB0czsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBMaXN0PFR5cGU+IHRzMSA9IGV4Y2wodCwgdHMudGFpbCk7CiAgICAgICAgICAgIGlmICh0eXBlcy5pc1N1YnR5cGUodHMuaGVhZCwgdCkpIHJldHVybiB0czE7CiAgICAgICAgICAgIGVsc2UgaWYgKHRzMSA9PSB0cy50YWlsKSByZXR1cm4gdHM7CiAgICAgICAgICAgIGVsc2UgcmV0dXJuIHRzMS5wcmVwZW5kKHRzLmhlYWQpOwogICAgICAgIH0KICAgIH0KCiAgICAvKiogRm9ybSB0aGUgdW5pb24gb2YgdHdvIHR5cGUgc2V0IGxpc3RzLgogICAgICovCiAgICBMaXN0PFR5cGU+IHVuaW9uKExpc3Q8VHlwZT4gdHMxLCBMaXN0PFR5cGU+IHRzMikgewogICAgICAgIExpc3Q8VHlwZT4gdHMgPSB0czE7CiAgICAgICAgZm9yIChMaXN0PFR5cGU+IGwgPSB0czI7IGwubm9uRW1wdHkoKTsgbCA9IGwudGFpbCkKICAgICAgICAgICAgdHMgPSBpbmNsKGwuaGVhZCwgdHMpOwogICAgICAgIHJldHVybiB0czsKICAgIH0KCiAgICAvKiogRm9ybSB0aGUgZGlmZmVyZW5jZSBvZiB0d28gdHlwZSBsaXN0cy4KICAgICAqLwogICAgTGlzdDxUeXBlPiBkaWZmKExpc3Q8VHlwZT4gdHMxLCBMaXN0PFR5cGU+IHRzMikgewogICAgICAgIExpc3Q8VHlwZT4gdHMgPSB0czE7CiAgICAgICAgZm9yIChMaXN0PFR5cGU+IGwgPSB0czI7IGwubm9uRW1wdHkoKTsgbCA9IGwudGFpbCkKICAgICAgICAgICAgdHMgPSBleGNsKGwuaGVhZCwgdHMpOwogICAgICAgIHJldHVybiB0czsKICAgIH0KCiAgICAvKiogRm9ybSB0aGUgaW50ZXJzZWN0aW9uIG9mIHR3byB0eXBlIGxpc3RzLgogICAgICovCiAgICBwdWJsaWMgTGlzdDxUeXBlPiBpbnRlcnNlY3QoTGlzdDxUeXBlPiB0czEsIExpc3Q8VHlwZT4gdHMyKSB7CiAgICAgICAgTGlzdDxUeXBlPiB0cyA9IExpc3QubmlsKCk7CiAgICAgICAgZm9yIChMaXN0PFR5cGU+IGwgPSB0czE7IGwubm9uRW1wdHkoKTsgbCA9IGwudGFpbCkKICAgICAgICAgICAgaWYgKHN1YnNldChsLmhlYWQsIHRzMikpIHRzID0gaW5jbChsLmhlYWQsIHRzKTsKICAgICAgICBmb3IgKExpc3Q8VHlwZT4gbCA9IHRzMjsgbC5ub25FbXB0eSgpOyBsID0gbC50YWlsKQogICAgICAgICAgICBpZiAoc3Vic2V0KGwuaGVhZCwgdHMxKSkgdHMgPSBpbmNsKGwuaGVhZCwgdHMpOwogICAgICAgIHJldHVybiB0czsKICAgIH0KCiAgICAvKiogSXMgZXhjIGFuIGV4Y2VwdGlvbiBzeW1ib2wgdGhhdCBuZWVkIG5vdCBiZSBkZWNsYXJlZD8KICAgICAqLwogICAgYm9vbGVhbiBpc1VuY2hlY2tlZChDbGFzc1N5bWJvbCBleGMpIHsKICAgICAgICByZXR1cm4KICAgICAgICAgICAgZXhjLmtpbmQgPT0gRVJSIHx8CiAgICAgICAgICAgIGV4Yy5pc1N1YkNsYXNzKHN5bXMuZXJyb3JUeXBlLnRzeW0sIHR5cGVzKSB8fAogICAgICAgICAgICBleGMuaXNTdWJDbGFzcyhzeW1zLnJ1bnRpbWVFeGNlcHRpb25UeXBlLnRzeW0sIHR5cGVzKTsKICAgIH0KCiAgICAvKiogSXMgZXhjIGFuIGV4Y2VwdGlvbiB0eXBlIHRoYXQgbmVlZCBub3QgYmUgZGVjbGFyZWQ/CiAgICAgKi8KICAgIGJvb2xlYW4gaXNVbmNoZWNrZWQoVHlwZSBleGMpIHsKICAgICAgICByZXR1cm4KICAgICAgICAgICAgKGV4Yy5oYXNUYWcoVFlQRVZBUikpID8gaXNVbmNoZWNrZWQodHlwZXMuc3VwZXJ0eXBlKGV4YykpIDoKICAgICAgICAgICAgKGV4Yy5oYXNUYWcoQ0xBU1MpKSA/IGlzVW5jaGVja2VkKChDbGFzc1N5bWJvbClleGMudHN5bSkgOgogICAgICAgICAgICBleGMuaGFzVGFnKEJPVCk7CiAgICB9CgogICAgLyoqIFNhbWUsIGJ1dCBoYW5kbGluZyBjb21wbGV0aW9uIGZhaWx1cmVzLgogICAgICovCiAgICBib29sZWFuIGlzVW5jaGVja2VkKERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIFR5cGUgZXhjKSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgcmV0dXJuIGlzVW5jaGVja2VkKGV4Yyk7CiAgICAgICAgfSBjYXRjaCAoQ29tcGxldGlvbkZhaWx1cmUgZXgpIHsKICAgICAgICAgICAgY29tcGxldGlvbkVycm9yKHBvcywgZXgpOwogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICB9CgogICAgLyoqIElzIGV4YyBoYW5kbGVkIGJ5IGdpdmVuIGV4Y2VwdGlvbiBsaXN0PwogICAgICovCiAgICBib29sZWFuIGlzSGFuZGxlZChUeXBlIGV4YywgTGlzdDxUeXBlPiBoYW5kbGVkKSB7CiAgICAgICAgcmV0dXJuIGlzVW5jaGVja2VkKGV4YykgfHwgc3Vic2V0KGV4YywgaGFuZGxlZCk7CiAgICB9CgogICAgLyoqIFJldHVybiBhbGwgZXhjZXB0aW9ucyBpbiB0aHJvd24gbGlzdCB0aGF0IGFyZSBub3QgaW4gaGFuZGxlZCBsaXN0LgogICAgICogIEBwYXJhbSB0aHJvd24gICAgIFRoZSBsaXN0IG9mIHRocm93biBleGNlcHRpb25zLgogICAgICogIEBwYXJhbSBoYW5kbGVkICAgIFRoZSBsaXN0IG9mIGhhbmRsZWQgZXhjZXB0aW9ucy4KICAgICAqLwogICAgTGlzdDxUeXBlPiB1bmhhbmRsZWQoTGlzdDxUeXBlPiB0aHJvd24sIExpc3Q8VHlwZT4gaGFuZGxlZCkgewogICAgICAgIExpc3Q8VHlwZT4gdW5oYW5kbGVkID0gTGlzdC5uaWwoKTsKICAgICAgICBmb3IgKExpc3Q8VHlwZT4gbCA9IHRocm93bjsgbC5ub25FbXB0eSgpOyBsID0gbC50YWlsKQogICAgICAgICAgICBpZiAoIWlzSGFuZGxlZChsLmhlYWQsIGhhbmRsZWQpKSB1bmhhbmRsZWQgPSB1bmhhbmRsZWQucHJlcGVuZChsLmhlYWQpOwogICAgICAgIHJldHVybiB1bmhhbmRsZWQ7CiAgICB9CgovKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIE92ZXJyaWRpbmcvSW1wbGVtZW50YXRpb24gY2hlY2tpbmcKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKICAgIC8qKiBUaGUgbGV2ZWwgb2YgYWNjZXNzIHByb3RlY3Rpb24gZ2l2ZW4gYnkgYSBmbGFnIHNldCwKICAgICAqICB3aGVyZSBQUklWQVRFIGlzIGhpZ2hlc3QgYW5kIFBVQkxJQyBpcyBsb3dlc3QuCiAgICAgKi8KICAgIHN0YXRpYyBpbnQgcHJvdGVjdGlvbihsb25nIGZsYWdzKSB7CiAgICAgICAgc3dpdGNoICgoc2hvcnQpKGZsYWdzICYgQWNjZXNzRmxhZ3MpKSB7CiAgICAgICAgY2FzZSBQUklWQVRFOiByZXR1cm4gMzsKICAgICAgICBjYXNlIFBST1RFQ1RFRDogcmV0dXJuIDE7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICBjYXNlIFBVQkxJQzogcmV0dXJuIDA7CiAgICAgICAgY2FzZSAwOiByZXR1cm4gMjsKICAgICAgICB9CiAgICB9CgogICAgLyoqIEEgY3VzdG9taXplZCAiY2Fubm90IG92ZXJyaWRlIiBlcnJvciBtZXNzYWdlLgogICAgICogIEBwYXJhbSBtICAgICAgVGhlIG92ZXJyaWRpbmcgbWV0aG9kLgogICAgICogIEBwYXJhbSBvdGhlciAgVGhlIG92ZXJyaWRkZW4gbWV0aG9kLgogICAgICogIEByZXR1cm4gICAgICAgQW4gaW50ZXJuYXRpb25hbGl6ZWQgc3RyaW5nLgogICAgICovCiAgICBPYmplY3QgY2Fubm90T3ZlcnJpZGUoTWV0aG9kU3ltYm9sIG0sIE1ldGhvZFN5bWJvbCBvdGhlcikgewogICAgICAgIFN0cmluZyBrZXk7CiAgICAgICAgaWYgKChvdGhlci5vd25lci5mbGFncygpICYgSU5URVJGQUNFKSA9PSAwKQogICAgICAgICAgICBrZXkgPSAiY2FudC5vdmVycmlkZSI7CiAgICAgICAgZWxzZSBpZiAoKG0ub3duZXIuZmxhZ3MoKSAmIElOVEVSRkFDRSkgPT0gMCkKICAgICAgICAgICAga2V5ID0gImNhbnQuaW1wbGVtZW50IjsKICAgICAgICBlbHNlCiAgICAgICAgICAgIGtleSA9ICJjbGFzaGVzLndpdGgiOwogICAgICAgIHJldHVybiBkaWFncy5mcmFnbWVudChrZXksIG0sIG0ubG9jYXRpb24oKSwgb3RoZXIsIG90aGVyLmxvY2F0aW9uKCkpOwogICAgfQoKICAgIC8qKiBBIGN1c3RvbWl6ZWQgIm92ZXJyaWRlIiB3YXJuaW5nIG1lc3NhZ2UuCiAgICAgKiAgQHBhcmFtIG0gICAgICBUaGUgb3ZlcnJpZGluZyBtZXRob2QuCiAgICAgKiAgQHBhcmFtIG90aGVyICBUaGUgb3ZlcnJpZGRlbiBtZXRob2QuCiAgICAgKiAgQHJldHVybiAgICAgICBBbiBpbnRlcm5hdGlvbmFsaXplZCBzdHJpbmcuCiAgICAgKi8KICAgIE9iamVjdCB1bmNoZWNrZWRPdmVycmlkZXMoTWV0aG9kU3ltYm9sIG0sIE1ldGhvZFN5bWJvbCBvdGhlcikgewogICAgICAgIFN0cmluZyBrZXk7CiAgICAgICAgaWYgKChvdGhlci5vd25lci5mbGFncygpICYgSU5URVJGQUNFKSA9PSAwKQogICAgICAgICAgICBrZXkgPSAidW5jaGVja2VkLm92ZXJyaWRlIjsKICAgICAgICBlbHNlIGlmICgobS5vd25lci5mbGFncygpICYgSU5URVJGQUNFKSA9PSAwKQogICAgICAgICAgICBrZXkgPSAidW5jaGVja2VkLmltcGxlbWVudCI7CiAgICAgICAgZWxzZQogICAgICAgICAgICBrZXkgPSAidW5jaGVja2VkLmNsYXNoLndpdGgiOwogICAgICAgIHJldHVybiBkaWFncy5mcmFnbWVudChrZXksIG0sIG0ubG9jYXRpb24oKSwgb3RoZXIsIG90aGVyLmxvY2F0aW9uKCkpOwogICAgfQoKICAgIC8qKiBBIGN1c3RvbWl6ZWQgIm92ZXJyaWRlIiB3YXJuaW5nIG1lc3NhZ2UuCiAgICAgKiAgQHBhcmFtIG0gICAgICBUaGUgb3ZlcnJpZGluZyBtZXRob2QuCiAgICAgKiAgQHBhcmFtIG90aGVyICBUaGUgb3ZlcnJpZGRlbiBtZXRob2QuCiAgICAgKiAgQHJldHVybiAgICAgICBBbiBpbnRlcm5hdGlvbmFsaXplZCBzdHJpbmcuCiAgICAgKi8KICAgIE9iamVjdCB2YXJhcmdzT3ZlcnJpZGVzKE1ldGhvZFN5bWJvbCBtLCBNZXRob2RTeW1ib2wgb3RoZXIpIHsKICAgICAgICBTdHJpbmcga2V5OwogICAgICAgIGlmICgob3RoZXIub3duZXIuZmxhZ3MoKSAmIElOVEVSRkFDRSkgPT0gMCkKICAgICAgICAgICAga2V5ID0gInZhcmFyZ3Mub3ZlcnJpZGUiOwogICAgICAgIGVsc2UgIGlmICgobS5vd25lci5mbGFncygpICYgSU5URVJGQUNFKSA9PSAwKQogICAgICAgICAgICBrZXkgPSAidmFyYXJncy5pbXBsZW1lbnQiOwogICAgICAgIGVsc2UKICAgICAgICAgICAga2V5ID0gInZhcmFyZ3MuY2xhc2gud2l0aCI7CiAgICAgICAgcmV0dXJuIGRpYWdzLmZyYWdtZW50KGtleSwgbSwgbS5sb2NhdGlvbigpLCBvdGhlciwgb3RoZXIubG9jYXRpb24oKSk7CiAgICB9CgogICAgLyoqIENoZWNrIHRoYXQgdGhpcyBtZXRob2QgY29uZm9ybXMgd2l0aCBvdmVycmlkZGVuIG1ldGhvZCAnb3RoZXInLgogICAgICogIHdoZXJlIGBvcmlnaW4nIGlzIHRoZSBjbGFzcyB3aGVyZSBjaGVja2luZyBzdGFydGVkLgogICAgICogIENvbXBsaWNhdGlvbnM6CiAgICAgKiAgKDEpIERvIG5vdCBjaGVjayBvdmVycmlkaW5nIG9mIHN5bnRoZXRpYyBtZXRob2RzCiAgICAgKiAgICAgIChyZWFzb246IHRoZXkgbWlnaHQgYmUgZmluYWwpLgogICAgICogICAgICB0b2RvOiBjaGVjayB3aGV0aGVyIHRoaXMgaXMgc3RpbGwgbmVjZXNzYXJ5LgogICAgICogICgyKSBBZG1pdCB0aGUgY2FzZSB3aGVyZSBhbiBpbnRlcmZhY2UgcHJveHkgdGhyb3dzIGZld2VyIGV4Y2VwdGlvbnMKICAgICAqICAgICAgdGhhbiB0aGUgbWV0aG9kIGl0IGltcGxlbWVudHMuIEF1Z21lbnQgdGhlIHByb3h5IG1ldGhvZHMgd2l0aCB0aGUKICAgICAqICAgICAgdW5kZWNsYXJlZCBleGNlcHRpb25zIGluIHRoaXMgY2FzZS4KICAgICAqICAoMykgV2hlbiBnZW5lcmljcyBhcmUgZW5hYmxlZCwgYWRtaXQgdGhlIGNhc2Ugd2hlcmUgYW4gaW50ZXJmYWNlIHByb3h5CiAgICAgKiAgICAgIGhhcyBhIHJlc3VsdCB0eXBlCiAgICAgKiAgICAgIGV4dGVuZGVkIGJ5IHRoZSByZXN1bHQgdHlwZSBvZiB0aGUgbWV0aG9kIGl0IGltcGxlbWVudHMuCiAgICAgKiAgICAgIENoYW5nZSB0aGUgcHJveGllcyByZXN1bHQgdHlwZSB0byB0aGUgc21hbGxlciB0eXBlIGluIHRoaXMgY2FzZS4KICAgICAqCiAgICAgKiAgQHBhcmFtIHRyZWUgICAgICAgICBUaGUgdHJlZSBmcm9tIHdoaWNoIHBvc2l0aW9ucwogICAgICogICAgICAgICAgICAgICAgICAgICAgYXJlIGV4dHJhY3RlZCBmb3IgZXJyb3JzLgogICAgICogIEBwYXJhbSBtICAgICAgICAgICAgVGhlIG92ZXJyaWRpbmcgbWV0aG9kLgogICAgICogIEBwYXJhbSBvdGhlciAgICAgICAgVGhlIG92ZXJyaWRkZW4gbWV0aG9kLgogICAgICogIEBwYXJhbSBvcmlnaW4gICAgICAgVGhlIGNsYXNzIG9mIHdoaWNoIHRoZSBvdmVycmlkaW5nIG1ldGhvZAogICAgICogICAgICAgICAgICAgICAgICAgICAgaXMgYSBtZW1iZXIuCiAgICAgKi8KICAgIHZvaWQgY2hlY2tPdmVycmlkZShKQ1RyZWUgdHJlZSwKICAgICAgICAgICAgICAgICAgICAgICBNZXRob2RTeW1ib2wgbSwKICAgICAgICAgICAgICAgICAgICAgICBNZXRob2RTeW1ib2wgb3RoZXIsCiAgICAgICAgICAgICAgICAgICAgICAgQ2xhc3NTeW1ib2wgb3JpZ2luKSB7CiAgICAgICAgLy8gRG9uJ3QgY2hlY2sgb3ZlcnJpZGluZyBvZiBzeW50aGV0aWMgbWV0aG9kcyBvciBieSBicmlkZ2UgbWV0aG9kcy4KICAgICAgICBpZiAoKG0uZmxhZ3MoKSAmIChTWU5USEVUSUN8QlJJREdFKSkgIT0gMCB8fCAob3RoZXIuZmxhZ3MoKSAmIFNZTlRIRVRJQykgIT0gMCkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICAvLyBFcnJvciBpZiBzdGF0aWMgbWV0aG9kIG92ZXJyaWRlcyBpbnN0YW5jZSBtZXRob2QgKEpMUyA4LjQuNi4yKS4KICAgICAgICBpZiAoKG0uZmxhZ3MoKSAmIFNUQVRJQykgIT0gMCAmJgogICAgICAgICAgICAgICAgICAgKG90aGVyLmZsYWdzKCkgJiBTVEFUSUMpID09IDApIHsKICAgICAgICAgICAgbG9nLmVycm9yKFRyZWVJbmZvLmRpYWdub3N0aWNQb3NpdGlvbkZvcihtLCB0cmVlKSwgIm92ZXJyaWRlLnN0YXRpYyIsCiAgICAgICAgICAgICAgICAgICAgICBjYW5ub3RPdmVycmlkZShtLCBvdGhlcikpOwogICAgICAgICAgICBtLmZsYWdzX2ZpZWxkIHw9IEJBRF9PVkVSUklERTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgLy8gRXJyb3IgaWYgaW5zdGFuY2UgbWV0aG9kIG92ZXJyaWRlcyBzdGF0aWMgb3IgZmluYWwKICAgICAgICAvLyBtZXRob2QgKEpMUyA4LjQuNi4xKS4KICAgICAgICBpZiAoKG90aGVyLmZsYWdzKCkgJiBGSU5BTCkgIT0gMCB8fAogICAgICAgICAgICAgICAgIChtLmZsYWdzKCkgJiBTVEFUSUMpID09IDAgJiYKICAgICAgICAgICAgICAgICAob3RoZXIuZmxhZ3MoKSAmIFNUQVRJQykgIT0gMCkgewogICAgICAgICAgICBsb2cuZXJyb3IoVHJlZUluZm8uZGlhZ25vc3RpY1Bvc2l0aW9uRm9yKG0sIHRyZWUpLCAib3ZlcnJpZGUubWV0aCIsCiAgICAgICAgICAgICAgICAgICAgICBjYW5ub3RPdmVycmlkZShtLCBvdGhlciksCiAgICAgICAgICAgICAgICAgICAgICBhc0ZsYWdTZXQob3RoZXIuZmxhZ3MoKSAmIChGSU5BTCB8IFNUQVRJQykpKTsKICAgICAgICAgICAgbS5mbGFnc19maWVsZCB8PSBCQURfT1ZFUlJJREU7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIGlmICgobS5vd25lci5mbGFncygpICYgQU5OT1RBVElPTikgIT0gMCkgewogICAgICAgICAgICAvLyBoYW5kbGVkIGluIHZhbGlkYXRlQW5ub3RhdGlvbk1ldGhvZAogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICAvLyBFcnJvciBpZiBvdmVycmlkaW5nIG1ldGhvZCBoYXMgd2Vha2VyIGFjY2VzcyAoSkxTIDguNC42LjMpLgogICAgICAgIGlmIChwcm90ZWN0aW9uKG0uZmxhZ3MoKSkgPiBwcm90ZWN0aW9uKG90aGVyLmZsYWdzKCkpKSB7CiAgICAgICAgICAgIGxvZy5lcnJvcihUcmVlSW5mby5kaWFnbm9zdGljUG9zaXRpb25Gb3IobSwgdHJlZSksICJvdmVycmlkZS53ZWFrZXIuYWNjZXNzIiwKICAgICAgICAgICAgICAgICAgICAgIGNhbm5vdE92ZXJyaWRlKG0sIG90aGVyKSwKICAgICAgICAgICAgICAgICAgICAgIChvdGhlci5mbGFncygpICYgQWNjZXNzRmxhZ3MpID09IDAgPwogICAgICAgICAgICAgICAgICAgICAgICAgICJwYWNrYWdlIiA6CiAgICAgICAgICAgICAgICAgICAgICAgICAgYXNGbGFnU2V0KG90aGVyLmZsYWdzKCkgJiBBY2Nlc3NGbGFncykpOwogICAgICAgICAgICBtLmZsYWdzX2ZpZWxkIHw9IEJBRF9PVkVSUklERTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgVHlwZSBtdCA9IHR5cGVzLm1lbWJlclR5cGUob3JpZ2luLnR5cGUsIG0pOwogICAgICAgIFR5cGUgb3QgPSB0eXBlcy5tZW1iZXJUeXBlKG9yaWdpbi50eXBlLCBvdGhlcik7CiAgICAgICAgLy8gRXJyb3IgaWYgb3ZlcnJpZGluZyByZXN1bHQgdHlwZSBpcyBkaWZmZXJlbnQKICAgICAgICAvLyAob3IsIGluIHRoZSBjYXNlIG9mIGdlbmVyaWNzIG1vZGUsIG5vdCBhIHN1YnR5cGUpIG9mCiAgICAgICAgLy8gb3ZlcnJpZGRlbiByZXN1bHQgdHlwZS4gV2UgaGF2ZSB0byByZW5hbWUgYW55IHR5cGUgcGFyYW1ldGVycwogICAgICAgIC8vIGJlZm9yZSBjb21wYXJpbmcgdHlwZXMuCiAgICAgICAgTGlzdDxUeXBlPiBtdHZhcnMgPSBtdC5nZXRUeXBlQXJndW1lbnRzKCk7CiAgICAgICAgTGlzdDxUeXBlPiBvdHZhcnMgPSBvdC5nZXRUeXBlQXJndW1lbnRzKCk7CiAgICAgICAgVHlwZSBtdHJlcyA9IG10LmdldFJldHVyblR5cGUoKTsKICAgICAgICBUeXBlIG90cmVzID0gdHlwZXMuc3Vic3Qob3QuZ2V0UmV0dXJuVHlwZSgpLCBvdHZhcnMsIG10dmFycyk7CgogICAgICAgIG92ZXJyaWRlV2FybmVyLmNsZWFyKCk7CiAgICAgICAgYm9vbGVhbiByZXN1bHRUeXBlc09LID0KICAgICAgICAgICAgdHlwZXMucmV0dXJuVHlwZVN1YnN0aXR1dGFibGUobXQsIG90LCBvdHJlcywgb3ZlcnJpZGVXYXJuZXIpOwogICAgICAgIGlmICghcmVzdWx0VHlwZXNPSykgewogICAgICAgICAgICBpZiAoKG0uZmxhZ3MoKSAmIFNUQVRJQykgIT0gMCAmJiAob3RoZXIuZmxhZ3MoKSAmIFNUQVRJQykgIT0gMCkgewogICAgICAgICAgICAgICAgbG9nLmVycm9yKFRyZWVJbmZvLmRpYWdub3N0aWNQb3NpdGlvbkZvcihtLCB0cmVlKSwKICAgICAgICAgICAgICAgICAgICAgICAgRXJyb3JzLk92ZXJyaWRlSW5jb21wYXRpYmxlUmV0KEZyYWdtZW50cy5DYW50SGlkZShtLCBtLmxvY2F0aW9uKCksIG90aGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3RoZXIubG9jYXRpb24oKSksIG10cmVzLCBvdHJlcykpOwogICAgICAgICAgICAgICAgbS5mbGFnc19maWVsZCB8PSBCQURfT1ZFUlJJREU7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBsb2cuZXJyb3IoVHJlZUluZm8uZGlhZ25vc3RpY1Bvc2l0aW9uRm9yKG0sIHRyZWUpLAogICAgICAgICAgICAgICAgICAgICAgICAib3ZlcnJpZGUuaW5jb21wYXRpYmxlLnJldCIsCiAgICAgICAgICAgICAgICAgICAgICAgIGNhbm5vdE92ZXJyaWRlKG0sIG90aGVyKSwKICAgICAgICAgICAgICAgICAgICAgICAgbXRyZXMsIG90cmVzKTsKICAgICAgICAgICAgICAgIG0uZmxhZ3NfZmllbGQgfD0gQkFEX09WRVJSSURFOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9IGVsc2UgaWYgKG92ZXJyaWRlV2FybmVyLmhhc05vblNpbGVudExpbnQoTGludENhdGVnb3J5LlVOQ0hFQ0tFRCkpIHsKICAgICAgICAgICAgd2FyblVuY2hlY2tlZChUcmVlSW5mby5kaWFnbm9zdGljUG9zaXRpb25Gb3IobSwgdHJlZSksCiAgICAgICAgICAgICAgICAgICAgIm92ZXJyaWRlLnVuY2hlY2tlZC5yZXQiLAogICAgICAgICAgICAgICAgICAgIHVuY2hlY2tlZE92ZXJyaWRlcyhtLCBvdGhlciksCiAgICAgICAgICAgICAgICAgICAgbXRyZXMsIG90cmVzKTsKICAgICAgICB9CgogICAgICAgIC8vIEVycm9yIGlmIG92ZXJyaWRpbmcgbWV0aG9kIHRocm93cyBhbiBleGNlcHRpb24gbm90IHJlcG9ydGVkCiAgICAgICAgLy8gYnkgb3ZlcnJpZGRlbiBtZXRob2QuCiAgICAgICAgTGlzdDxUeXBlPiBvdHRocm93biA9IHR5cGVzLnN1YnN0KG90LmdldFRocm93blR5cGVzKCksIG90dmFycywgbXR2YXJzKTsKICAgICAgICBMaXN0PFR5cGU+IHVuaGFuZGxlZEVyYXNlZCA9IHVuaGFuZGxlZChtdC5nZXRUaHJvd25UeXBlcygpLCB0eXBlcy5lcmFzdXJlKG90dGhyb3duKSk7CiAgICAgICAgTGlzdDxUeXBlPiB1bmhhbmRsZWRVbmVyYXNlZCA9IHVuaGFuZGxlZChtdC5nZXRUaHJvd25UeXBlcygpLCBvdHRocm93bik7CiAgICAgICAgaWYgKHVuaGFuZGxlZEVyYXNlZC5ub25FbXB0eSgpKSB7CiAgICAgICAgICAgIGxvZy5lcnJvcihUcmVlSW5mby5kaWFnbm9zdGljUG9zaXRpb25Gb3IobSwgdHJlZSksCiAgICAgICAgICAgICAgICAgICAgICAib3ZlcnJpZGUubWV0aC5kb2VzbnQudGhyb3ciLAogICAgICAgICAgICAgICAgICAgICAgY2Fubm90T3ZlcnJpZGUobSwgb3RoZXIpLAogICAgICAgICAgICAgICAgICAgICAgdW5oYW5kbGVkVW5lcmFzZWQuaGVhZCk7CiAgICAgICAgICAgIG0uZmxhZ3NfZmllbGQgfD0gQkFEX09WRVJSSURFOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKHVuaGFuZGxlZFVuZXJhc2VkLm5vbkVtcHR5KCkpIHsKICAgICAgICAgICAgd2FyblVuY2hlY2tlZChUcmVlSW5mby5kaWFnbm9zdGljUG9zaXRpb25Gb3IobSwgdHJlZSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIm92ZXJyaWRlLnVuY2hlY2tlZC50aHJvd24iLAogICAgICAgICAgICAgICAgICAgICAgICAgY2Fubm90T3ZlcnJpZGUobSwgb3RoZXIpLAogICAgICAgICAgICAgICAgICAgICAgICAgdW5oYW5kbGVkVW5lcmFzZWQuaGVhZCk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIC8vIE9wdGlvbmFsIHdhcm5pbmcgaWYgdmFyYXJncyBkb24ndCBhZ3JlZQogICAgICAgIGlmICgoKChtLmZsYWdzKCkgXiBvdGhlci5mbGFncygpKSAmIEZsYWdzLlZBUkFSR1MpICE9IDApCiAgICAgICAgICAgICYmIGxpbnQuaXNFbmFibGVkKExpbnRDYXRlZ29yeS5PVkVSUklERVMpKSB7CiAgICAgICAgICAgIGxvZy53YXJuaW5nKFRyZWVJbmZvLmRpYWdub3N0aWNQb3NpdGlvbkZvcihtLCB0cmVlKSwKICAgICAgICAgICAgICAgICAgICAgICAgKChtLmZsYWdzKCkgJiBGbGFncy5WQVJBUkdTKSAhPSAwKQogICAgICAgICAgICAgICAgICAgICAgICA/ICJvdmVycmlkZS52YXJhcmdzLm1pc3NpbmciCiAgICAgICAgICAgICAgICAgICAgICAgIDogIm92ZXJyaWRlLnZhcmFyZ3MuZXh0cmEiLAogICAgICAgICAgICAgICAgICAgICAgICB2YXJhcmdzT3ZlcnJpZGVzKG0sIG90aGVyKSk7CiAgICAgICAgfQoKICAgICAgICAvLyBXYXJuIGlmIGluc3RhbmNlIG1ldGhvZCBvdmVycmlkZXMgYnJpZGdlIG1ldGhvZCAoY29tcGlsZXIgc3BlYyA/PykKICAgICAgICBpZiAoKG90aGVyLmZsYWdzKCkgJiBCUklER0UpICE9IDApIHsKICAgICAgICAgICAgbG9nLndhcm5pbmcoVHJlZUluZm8uZGlhZ25vc3RpY1Bvc2l0aW9uRm9yKG0sIHRyZWUpLCAib3ZlcnJpZGUuYnJpZGdlIiwKICAgICAgICAgICAgICAgICAgICAgICAgdW5jaGVja2VkT3ZlcnJpZGVzKG0sIG90aGVyKSk7CiAgICAgICAgfQoKICAgICAgICAvLyBXYXJuIGlmIGEgZGVwcmVjYXRlZCBtZXRob2Qgb3ZlcnJpZGRlbiBieSBhIG5vbi1kZXByZWNhdGVkIG9uZS4KICAgICAgICBpZiAoIWlzRGVwcmVjYXRlZE92ZXJyaWRlSWdub3JhYmxlKG90aGVyLCBvcmlnaW4pKSB7CiAgICAgICAgICAgIExpbnQgcHJldkxpbnQgPSBzZXRMaW50KGxpbnQuYXVnbWVudChtKSk7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBjaGVja0RlcHJlY2F0ZWQoVHJlZUluZm8uZGlhZ25vc3RpY1Bvc2l0aW9uRm9yKG0sIHRyZWUpLCBtLCBvdGhlcik7CiAgICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgICAgICBzZXRMaW50KHByZXZMaW50KTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIC8vIHdoZXJlCiAgICAgICAgcHJpdmF0ZSBib29sZWFuIGlzRGVwcmVjYXRlZE92ZXJyaWRlSWdub3JhYmxlKE1ldGhvZFN5bWJvbCBtLCBDbGFzc1N5bWJvbCBvcmlnaW4pIHsKICAgICAgICAgICAgLy8gSWYgdGhlIG1ldGhvZCwgbSwgaXMgZGVmaW5lZCBpbiBhbiBpbnRlcmZhY2UsIHRoZW4gaWdub3JlIHRoZSBpc3N1ZSBpZiB0aGUgbWV0aG9kCiAgICAgICAgICAgIC8vIGlzIG9ubHkgaW5oZXJpdGVkIHZpYSBhIHN1cGVydHlwZSBhbmQgYWxzbyBpbXBsZW1lbnRlZCBpbiB0aGUgc3VwZXJ0eXBlLAogICAgICAgICAgICAvLyBiZWNhdXNlIGluIHRoYXQgY2FzZSwgd2Ugd2lsbCByZWRpc2NvdmVyIHRoZSBpc3N1ZSB3aGVuIGV4YW1pbmluZyB0aGUgbWV0aG9kCiAgICAgICAgICAgIC8vIGluIHRoZSBzdXBlcnR5cGUuCiAgICAgICAgICAgIC8vIElmIHRoZSBtZXRob2QsIG0sIGlzIG5vdCBkZWZpbmVkIGluIGFuIGludGVyZmFjZSwgdGhlbiB0aGUgb25seSB0aW1lIHdlIG5lZWQgdG8KICAgICAgICAgICAgLy8gYWRkcmVzcyB0aGUgaXNzdWUgaXMgd2hlbiB0aGUgbWV0aG9kIGlzIHRoZSBzdXBlcnR5cGUgaW1wbGVtZW1lbnRhdGlvbjogYW55IG90aGVyCiAgICAgICAgICAgIC8vIGNhc2UsIHdlIHdpbGwgaGF2ZSBkZWFsdCB3aXRoIHdoZW4gZXhhbWluaW5nIHRoZSBzdXBlcnR5cGUgY2xhc3NlcwogICAgICAgICAgICBDbGFzc1N5bWJvbCBtYyA9IG0uZW5jbENsYXNzKCk7CiAgICAgICAgICAgIFR5cGUgc3QgPSB0eXBlcy5zdXBlcnR5cGUob3JpZ2luLnR5cGUpOwogICAgICAgICAgICBpZiAoIXN0Lmhhc1RhZyhDTEFTUykpCiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgTWV0aG9kU3ltYm9sIHN0aW1wbCA9IG0uaW1wbGVtZW50YXRpb24oKENsYXNzU3ltYm9sKXN0LnRzeW0sIHR5cGVzLCBmYWxzZSk7CgogICAgICAgICAgICBpZiAobWMgIT0gbnVsbCAmJiAoKG1jLmZsYWdzKCkgJiBJTlRFUkZBQ0UpICE9IDApKSB7CiAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IGludGZzID0gdHlwZXMuaW50ZXJmYWNlcyhvcmlnaW4udHlwZSk7CiAgICAgICAgICAgICAgICByZXR1cm4gKGludGZzLmNvbnRhaW5zKG1jLnR5cGUpID8gZmFsc2UgOiAoc3RpbXBsICE9IG51bGwpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICByZXR1cm4gKHN0aW1wbCAhPSBtKTsKICAgICAgICB9CgoKICAgIC8vIHVzZWQgdG8gY2hlY2sgaWYgdGhlcmUgd2VyZSBhbnkgdW5jaGVja2VkIGNvbnZlcnNpb25zCiAgICBXYXJuZXIgb3ZlcnJpZGVXYXJuZXIgPSBuZXcgV2FybmVyKCk7CgogICAgLyoqIENoZWNrIHRoYXQgYSBjbGFzcyBkb2VzIG5vdCBpbmhlcml0IHR3byBjb25jcmV0ZSBtZXRob2RzCiAgICAgKiAgd2l0aCB0aGUgc2FtZSBzaWduYXR1cmUuCiAgICAgKiAgQHBhcmFtIHBvcyAgICAgICAgICBQb3NpdGlvbiB0byBiZSB1c2VkIGZvciBlcnJvciByZXBvcnRpbmcuCiAgICAgKiAgQHBhcmFtIHNpdGUgICAgICAgICBUaGUgY2xhc3MgdHlwZSB0byBiZSBjaGVja2VkLgogICAgICovCiAgICBwdWJsaWMgdm9pZCBjaGVja0NvbXBhdGlibGVDb25jcmV0ZXMoRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcywgVHlwZSBzaXRlKSB7CiAgICAgICAgVHlwZSBzdXAgPSB0eXBlcy5zdXBlcnR5cGUoc2l0ZSk7CiAgICAgICAgaWYgKCFzdXAuaGFzVGFnKENMQVNTKSkgcmV0dXJuOwoKICAgICAgICBmb3IgKFR5cGUgdDEgPSBzdXA7CiAgICAgICAgICAgICB0MS5oYXNUYWcoQ0xBU1MpICYmIHQxLnRzeW0udHlwZS5pc1BhcmFtZXRlcml6ZWQoKTsKICAgICAgICAgICAgIHQxID0gdHlwZXMuc3VwZXJ0eXBlKHQxKSkgewogICAgICAgICAgICBmb3IgKFN5bWJvbCBzMSA6IHQxLnRzeW0ubWVtYmVycygpLmdldFN5bWJvbHMoTk9OX1JFQ1VSU0lWRSkpIHsKICAgICAgICAgICAgICAgIGlmIChzMS5raW5kICE9IE1USCB8fAogICAgICAgICAgICAgICAgICAgIChzMS5mbGFncygpICYgKFNUQVRJQ3xTWU5USEVUSUN8QlJJREdFKSkgIT0gMCB8fAogICAgICAgICAgICAgICAgICAgICFzMS5pc0luaGVyaXRlZEluKHNpdGUudHN5bSwgdHlwZXMpIHx8CiAgICAgICAgICAgICAgICAgICAgKChNZXRob2RTeW1ib2wpczEpLmltcGxlbWVudGF0aW9uKHNpdGUudHN5bSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRydWUpICE9IHMxKQogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgVHlwZSBzdDEgPSB0eXBlcy5tZW1iZXJUeXBlKHQxLCBzMSk7CiAgICAgICAgICAgICAgICBpbnQgczFBcmdzTGVuZ3RoID0gc3QxLmdldFBhcmFtZXRlclR5cGVzKCkubGVuZ3RoKCk7CiAgICAgICAgICAgICAgICBpZiAoc3QxID09IHMxLnR5cGUpIGNvbnRpbnVlOwoKICAgICAgICAgICAgICAgIGZvciAoVHlwZSB0MiA9IHN1cDsKICAgICAgICAgICAgICAgICAgICAgdDIuaGFzVGFnKENMQVNTKTsKICAgICAgICAgICAgICAgICAgICAgdDIgPSB0eXBlcy5zdXBlcnR5cGUodDIpKSB7CiAgICAgICAgICAgICAgICAgICAgZm9yIChTeW1ib2wgczIgOiB0Mi50c3ltLm1lbWJlcnMoKS5nZXRTeW1ib2xzQnlOYW1lKHMxLm5hbWUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzMiA9PSBzMSB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgczIua2luZCAhPSBNVEggfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIChzMi5mbGFncygpICYgKFNUQVRJQ3xTWU5USEVUSUN8QlJJREdFKSkgIT0gMCB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgczIudHlwZS5nZXRQYXJhbWV0ZXJUeXBlcygpLmxlbmd0aCgpICE9IHMxQXJnc0xlbmd0aCB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIXMyLmlzSW5oZXJpdGVkSW4oc2l0ZS50c3ltLCB0eXBlcykgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoTWV0aG9kU3ltYm9sKXMyKS5pbXBsZW1lbnRhdGlvbihzaXRlLnRzeW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ1ZSkgIT0gczIpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICAgICAgVHlwZSBzdDIgPSB0eXBlcy5tZW1iZXJUeXBlKHQyLCBzMik7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlcy5vdmVycmlkZUVxdWl2YWxlbnQoc3QxLCBzdDIpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9nLmVycm9yKHBvcywgImNvbmNyZXRlLmluaGVyaXRhbmNlLmNvbmZsaWN0IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzMSwgdDEsIHMyLCB0Miwgc3VwKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqIENoZWNrIHRoYXQgY2xhc3NlcyAob3IgaW50ZXJmYWNlcykgZG8gbm90IGVhY2ggZGVmaW5lIGFuIGFic3RyYWN0CiAgICAgKiAgbWV0aG9kIHdpdGggc2FtZSBuYW1lIGFuZCBhcmd1bWVudHMgYnV0IGluY29tcGF0aWJsZSByZXR1cm4gdHlwZXMuCiAgICAgKiAgQHBhcmFtIHBvcyAgICAgICAgICBQb3NpdGlvbiB0byBiZSB1c2VkIGZvciBlcnJvciByZXBvcnRpbmcuCiAgICAgKiAgQHBhcmFtIHQxICAgICAgICAgICBUaGUgZmlyc3QgYXJndW1lbnQgdHlwZS4KICAgICAqICBAcGFyYW0gdDIgICAgICAgICAgIFRoZSBzZWNvbmQgYXJndW1lbnQgdHlwZS4KICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gY2hlY2tDb21wYXRpYmxlQWJzdHJhY3RzKERpYWdub3N0aWNQb3NpdGlvbiBwb3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVHlwZSB0MSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUeXBlIHQyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFR5cGUgc2l0ZSkgewogICAgICAgIGlmICgoc2l0ZS50c3ltLmZsYWdzKCkgJiBDT01QT1VORCkgIT0gMCkgewogICAgICAgICAgICAvLyBzcGVjaWFsIGNhc2UgZm9yIGludGVyc2VjdGlvbnM6IG5lZWQgdG8gZWxpbWluYXRlIHdpbGRjYXJkcyBpbiBzdXBlcnR5cGVzCiAgICAgICAgICAgIHQxID0gdHlwZXMuY2FwdHVyZSh0MSk7CiAgICAgICAgICAgIHQyID0gdHlwZXMuY2FwdHVyZSh0Mik7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaXJzdEluY29tcGF0aWJpbGl0eShwb3MsIHQxLCB0Miwgc2l0ZSkgPT0gbnVsbDsKICAgIH0KCiAgICAvKiogUmV0dXJuIHRoZSBmaXJzdCBtZXRob2Qgd2hpY2ggaXMgZGVmaW5lZCB3aXRoIHNhbWUgYXJncwogICAgICogIGJ1dCBkaWZmZXJlbnQgcmV0dXJuIHR5cGVzIGluIHR3byBnaXZlbiBpbnRlcmZhY2VzLCBvciBudWxsIGlmIG5vbmUKICAgICAqICBleGlzdHMuCiAgICAgKiAgQHBhcmFtIHQxICAgICBUaGUgZmlyc3QgdHlwZS4KICAgICAqICBAcGFyYW0gdDIgICAgIFRoZSBzZWNvbmQgdHlwZS4KICAgICAqICBAcGFyYW0gc2l0ZSAgIFRoZSBtb3N0IGRlcml2ZWQgdHlwZS4KICAgICAqICBAcmV0dXJucyBzeW1ib2wgZnJvbSB0MiB0aGF0IGNvbmZsaWN0cyB3aXRoIG9uZSBpbiB0MS4KICAgICAqLwogICAgcHJpdmF0ZSBTeW1ib2wgZmlyc3RJbmNvbXBhdGliaWxpdHkoRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcywgVHlwZSB0MSwgVHlwZSB0MiwgVHlwZSBzaXRlKSB7CiAgICAgICAgTWFwPFR5cGVTeW1ib2wsVHlwZT4gaW50ZXJmYWNlczEgPSBuZXcgSGFzaE1hcDw+KCk7CiAgICAgICAgY2xvc3VyZSh0MSwgaW50ZXJmYWNlczEpOwogICAgICAgIE1hcDxUeXBlU3ltYm9sLFR5cGU+IGludGVyZmFjZXMyOwogICAgICAgIGlmICh0MSA9PSB0MikKICAgICAgICAgICAgaW50ZXJmYWNlczIgPSBpbnRlcmZhY2VzMTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIGNsb3N1cmUodDIsIGludGVyZmFjZXMxLCBpbnRlcmZhY2VzMiA9IG5ldyBIYXNoTWFwPD4oKSk7CgogICAgICAgIGZvciAoVHlwZSB0MyA6IGludGVyZmFjZXMxLnZhbHVlcygpKSB7CiAgICAgICAgICAgIGZvciAoVHlwZSB0NCA6IGludGVyZmFjZXMyLnZhbHVlcygpKSB7CiAgICAgICAgICAgICAgICBTeW1ib2wgcyA9IGZpcnN0RGlyZWN0SW5jb21wYXRpYmlsaXR5KHBvcywgdDMsIHQ0LCBzaXRlKTsKICAgICAgICAgICAgICAgIGlmIChzICE9IG51bGwpIHJldHVybiBzOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIC8qKiBDb21wdXRlIGFsbCB0aGUgc3VwZXJ0eXBlcyBvZiB0LCBpbmRleGVkIGJ5IHR5cGUgc3ltYm9sLiAqLwogICAgcHJpdmF0ZSB2b2lkIGNsb3N1cmUoVHlwZSB0LCBNYXA8VHlwZVN5bWJvbCxUeXBlPiB0eXBlTWFwKSB7CiAgICAgICAgaWYgKCF0Lmhhc1RhZyhDTEFTUykpIHJldHVybjsKICAgICAgICBpZiAodHlwZU1hcC5wdXQodC50c3ltLCB0KSA9PSBudWxsKSB7CiAgICAgICAgICAgIGNsb3N1cmUodHlwZXMuc3VwZXJ0eXBlKHQpLCB0eXBlTWFwKTsKICAgICAgICAgICAgZm9yIChUeXBlIGkgOiB0eXBlcy5pbnRlcmZhY2VzKHQpKQogICAgICAgICAgICAgICAgY2xvc3VyZShpLCB0eXBlTWFwKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqIENvbXB1dGUgYWxsIHRoZSBzdXBlcnR5cGVzIG9mIHQsIGluZGV4ZWQgYnkgdHlwZSBzeW1ib2wgKGV4Y2VwdCB0aGlzZSBpbiB0eXBlc1NraXApLiAqLwogICAgcHJpdmF0ZSB2b2lkIGNsb3N1cmUoVHlwZSB0LCBNYXA8VHlwZVN5bWJvbCxUeXBlPiB0eXBlc1NraXAsIE1hcDxUeXBlU3ltYm9sLFR5cGU+IHR5cGVNYXApIHsKICAgICAgICBpZiAoIXQuaGFzVGFnKENMQVNTKSkgcmV0dXJuOwogICAgICAgIGlmICh0eXBlc1NraXAuZ2V0KHQudHN5bSkgIT0gbnVsbCkgcmV0dXJuOwogICAgICAgIGlmICh0eXBlTWFwLnB1dCh0LnRzeW0sIHQpID09IG51bGwpIHsKICAgICAgICAgICAgY2xvc3VyZSh0eXBlcy5zdXBlcnR5cGUodCksIHR5cGVzU2tpcCwgdHlwZU1hcCk7CiAgICAgICAgICAgIGZvciAoVHlwZSBpIDogdHlwZXMuaW50ZXJmYWNlcyh0KSkKICAgICAgICAgICAgICAgIGNsb3N1cmUoaSwgdHlwZXNTa2lwLCB0eXBlTWFwKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqIFJldHVybiB0aGUgZmlyc3QgbWV0aG9kIGluIHQyIHRoYXQgY29uZmxpY3RzIHdpdGggYSBtZXRob2QgZnJvbSB0MS4gKi8KICAgIHByaXZhdGUgU3ltYm9sIGZpcnN0RGlyZWN0SW5jb21wYXRpYmlsaXR5KERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIFR5cGUgdDEsIFR5cGUgdDIsIFR5cGUgc2l0ZSkgewogICAgICAgIGZvciAoU3ltYm9sIHMxIDogdDEudHN5bS5tZW1iZXJzKCkuZ2V0U3ltYm9scyhOT05fUkVDVVJTSVZFKSkgewogICAgICAgICAgICBUeXBlIHN0MSA9IG51bGw7CiAgICAgICAgICAgIGlmIChzMS5raW5kICE9IE1USCB8fCAhczEuaXNJbmhlcml0ZWRJbihzaXRlLnRzeW0sIHR5cGVzKSB8fAogICAgICAgICAgICAgICAgICAgIChzMS5mbGFncygpICYgU1lOVEhFVElDKSAhPSAwKSBjb250aW51ZTsKICAgICAgICAgICAgU3ltYm9sIGltcGwgPSAoKE1ldGhvZFN5bWJvbClzMSkuaW1wbGVtZW50YXRpb24oc2l0ZS50c3ltLCB0eXBlcywgZmFsc2UpOwogICAgICAgICAgICBpZiAoaW1wbCAhPSBudWxsICYmIChpbXBsLmZsYWdzKCkgJiBBQlNUUkFDVCkgPT0gMCkgY29udGludWU7CiAgICAgICAgICAgIGZvciAoU3ltYm9sIHMyIDogdDIudHN5bS5tZW1iZXJzKCkuZ2V0U3ltYm9sc0J5TmFtZShzMS5uYW1lKSkgewogICAgICAgICAgICAgICAgaWYgKHMxID09IHMyKSBjb250aW51ZTsKICAgICAgICAgICAgICAgIGlmIChzMi5raW5kICE9IE1USCB8fCAhczIuaXNJbmhlcml0ZWRJbihzaXRlLnRzeW0sIHR5cGVzKSB8fAogICAgICAgICAgICAgICAgICAgICAgICAoczIuZmxhZ3MoKSAmIFNZTlRIRVRJQykgIT0gMCkgY29udGludWU7CiAgICAgICAgICAgICAgICBpZiAoc3QxID09IG51bGwpIHN0MSA9IHR5cGVzLm1lbWJlclR5cGUodDEsIHMxKTsKICAgICAgICAgICAgICAgIFR5cGUgc3QyID0gdHlwZXMubWVtYmVyVHlwZSh0MiwgczIpOwogICAgICAgICAgICAgICAgaWYgKHR5cGVzLm92ZXJyaWRlRXF1aXZhbGVudChzdDEsIHN0MikpIHsKICAgICAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IHR2YXJzMSA9IHN0MS5nZXRUeXBlQXJndW1lbnRzKCk7CiAgICAgICAgICAgICAgICAgICAgTGlzdDxUeXBlPiB0dmFyczIgPSBzdDIuZ2V0VHlwZUFyZ3VtZW50cygpOwogICAgICAgICAgICAgICAgICAgIFR5cGUgcnQxID0gc3QxLmdldFJldHVyblR5cGUoKTsKICAgICAgICAgICAgICAgICAgICBUeXBlIHJ0MiA9IHR5cGVzLnN1YnN0KHN0Mi5nZXRSZXR1cm5UeXBlKCksIHR2YXJzMiwgdHZhcnMxKTsKICAgICAgICAgICAgICAgICAgICBib29sZWFuIGNvbXBhdCA9CiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVzLmlzU2FtZVR5cGUocnQxLCBydDIpIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICFydDEuaXNQcmltaXRpdmVPclZvaWQoKSAmJgogICAgICAgICAgICAgICAgICAgICAgICAhcnQyLmlzUHJpbWl0aXZlT3JWb2lkKCkgJiYKICAgICAgICAgICAgICAgICAgICAgICAgKHR5cGVzLmNvdmFyaWFudFJldHVyblR5cGUocnQxLCBydDIsIHR5cGVzLm5vV2FybmluZ3MpIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlcy5jb3ZhcmlhbnRSZXR1cm5UeXBlKHJ0MiwgcnQxLCB0eXBlcy5ub1dhcm5pbmdzKSkgfHwKICAgICAgICAgICAgICAgICAgICAgICAgIGNoZWNrQ29tbW9uT3ZlcnJpZGVySW4oczEsczIsc2l0ZSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKCFjb21wYXQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgbG9nLmVycm9yKHBvcywgInR5cGVzLmluY29tcGF0aWJsZS5kaWZmLnJldCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0MSwgdDIsIHMyLm5hbWUgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgIigiICsgdHlwZXMubWVtYmVyVHlwZSh0MiwgczIpLmdldFBhcmFtZXRlclR5cGVzKCkgKyAiKSIpOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gczI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjaGVja05hbWVDbGFzaCgoQ2xhc3NTeW1ib2wpc2l0ZS50c3ltLCBzMSwgczIpICYmCiAgICAgICAgICAgICAgICAgICAgICAgICFjaGVja0NvbW1vbk92ZXJyaWRlckluKHMxLCBzMiwgc2l0ZSkpIHsKICAgICAgICAgICAgICAgICAgICBsb2cuZXJyb3IocG9zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIm5hbWUuY2xhc2guc2FtZS5lcmFzdXJlLm5vLm92ZXJyaWRlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHMxLCBzMS5sb2NhdGlvbigpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgczIsIHMyLmxvY2F0aW9uKCkpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBzMjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIC8vV0hFUkUKICAgIGJvb2xlYW4gY2hlY2tDb21tb25PdmVycmlkZXJJbihTeW1ib2wgczEsIFN5bWJvbCBzMiwgVHlwZSBzaXRlKSB7CiAgICAgICAgTWFwPFR5cGVTeW1ib2wsVHlwZT4gc3VwZXJ0eXBlcyA9IG5ldyBIYXNoTWFwPD4oKTsKICAgICAgICBUeXBlIHN0MSA9IHR5cGVzLm1lbWJlclR5cGUoc2l0ZSwgczEpOwogICAgICAgIFR5cGUgc3QyID0gdHlwZXMubWVtYmVyVHlwZShzaXRlLCBzMik7CiAgICAgICAgY2xvc3VyZShzaXRlLCBzdXBlcnR5cGVzKTsKICAgICAgICBmb3IgKFR5cGUgdCA6IHN1cGVydHlwZXMudmFsdWVzKCkpIHsKICAgICAgICAgICAgZm9yIChTeW1ib2wgczMgOiB0LnRzeW0ubWVtYmVycygpLmdldFN5bWJvbHNCeU5hbWUoczEubmFtZSkpIHsKICAgICAgICAgICAgICAgIGlmIChzMyA9PSBzMSB8fCBzMyA9PSBzMiB8fCBzMy5raW5kICE9IE1USCB8fCAoczMuZmxhZ3MoKSAmIChCUklER0V8U1lOVEhFVElDKSkgIT0gMCkgY29udGludWU7CiAgICAgICAgICAgICAgICBUeXBlIHN0MyA9IHR5cGVzLm1lbWJlclR5cGUoc2l0ZSxzMyk7CiAgICAgICAgICAgICAgICBpZiAodHlwZXMub3ZlcnJpZGVFcXVpdmFsZW50KHN0Mywgc3QxKSAmJgogICAgICAgICAgICAgICAgICAgICAgICB0eXBlcy5vdmVycmlkZUVxdWl2YWxlbnQoc3QzLCBzdDIpICYmCiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVzLnJldHVyblR5cGVTdWJzdGl0dXRhYmxlKHN0Mywgc3QxKSAmJgogICAgICAgICAgICAgICAgICAgICAgICB0eXBlcy5yZXR1cm5UeXBlU3Vic3RpdHV0YWJsZShzdDMsIHN0MikpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgLyoqIENoZWNrIHRoYXQgYSBnaXZlbiBtZXRob2QgY29uZm9ybXMgd2l0aCBhbnkgbWV0aG9kIGl0IG92ZXJyaWRlcy4KICAgICAqICBAcGFyYW0gdHJlZSAgICAgICAgIFRoZSB0cmVlIGZyb20gd2hpY2ggcG9zaXRpb25zIGFyZSBleHRyYWN0ZWQKICAgICAqICAgICAgICAgICAgICAgICAgICAgIGZvciBlcnJvcnMuCiAgICAgKiAgQHBhcmFtIG0gICAgICAgICAgICBUaGUgb3ZlcnJpZGluZyBtZXRob2QuCiAgICAgKi8KICAgIHZvaWQgY2hlY2tPdmVycmlkZShFbnY8QXR0ckNvbnRleHQ+IGVudiwgSkNNZXRob2REZWNsIHRyZWUsIE1ldGhvZFN5bWJvbCBtKSB7CiAgICAgICAgQ2xhc3NTeW1ib2wgb3JpZ2luID0gKENsYXNzU3ltYm9sKW0ub3duZXI7CiAgICAgICAgaWYgKChvcmlnaW4uZmxhZ3MoKSAmIEVOVU0pICE9IDAgJiYgbmFtZXMuZmluYWxpemUuZXF1YWxzKG0ubmFtZSkpCiAgICAgICAgICAgIGlmIChtLm92ZXJyaWRlcyhzeW1zLmVudW1GaW5hbEZpbmFsaXplLCBvcmlnaW4sIHR5cGVzLCBmYWxzZSkpIHsKICAgICAgICAgICAgICAgIGxvZy5lcnJvcih0cmVlLnBvcygpLCAiZW51bS5uby5maW5hbGl6ZSIpOwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CiAgICAgICAgZm9yIChUeXBlIHQgPSBvcmlnaW4udHlwZTsgdC5oYXNUYWcoQ0xBU1MpOwogICAgICAgICAgICAgdCA9IHR5cGVzLnN1cGVydHlwZSh0KSkgewogICAgICAgICAgICBpZiAodCAhPSBvcmlnaW4udHlwZSkgewogICAgICAgICAgICAgICAgY2hlY2tPdmVycmlkZSh0cmVlLCB0LCBvcmlnaW4sIG0pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGZvciAoVHlwZSB0MiA6IHR5cGVzLmludGVyZmFjZXModCkpIHsKICAgICAgICAgICAgICAgIGNoZWNrT3ZlcnJpZGUodHJlZSwgdDIsIG9yaWdpbiwgbSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGZpbmFsIGJvb2xlYW4gZXhwbGljaXRPdmVycmlkZSA9IG0uYXR0cmlidXRlKHN5bXMub3ZlcnJpZGVUeXBlLnRzeW0pICE9IG51bGw7CiAgICAgICAgLy8gQ2hlY2sgaWYgdGhpcyBtZXRob2QgbXVzdCBvdmVycmlkZSBhIHN1cGVyIG1ldGhvZCBkdWUgdG8gYmVpbmcgYW5ub3RhdGVkIHdpdGggQE92ZXJyaWRlCiAgICAgICAgLy8gb3IgYnkgdmlydHVlIG9mIGJlaW5nIGEgbWVtYmVyIG9mIGEgZGlhbW9uZCBpbmZlcnJlZCBhbm9ueW1vdXMgY2xhc3MuIExhdHRlciBjYXNlIGlzIHRvCiAgICAgICAgLy8gYmUgdHJlYXRlZCAiYXMgaWYgYXMgdGhleSB3ZXJlIGFubm90YXRlZCIgd2l0aCBAT3ZlcnJpZGUuCiAgICAgICAgYm9vbGVhbiBtdXN0T3ZlcnJpZGUgPSBleHBsaWNpdE92ZXJyaWRlIHx8CiAgICAgICAgICAgICAgICAoZW52LmluZm8uaXNBbm9ueW1vdXNEaWFtb25kICYmICFtLmlzQ29uc3RydWN0b3IoKSAmJiAhbS5pc1ByaXZhdGUoKSk7CiAgICAgICAgaWYgKG11c3RPdmVycmlkZSAmJiAhaXNPdmVycmlkZXIobSkpIHsKICAgICAgICAgICAgRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcyA9IHRyZWUucG9zKCk7CiAgICAgICAgICAgIGZvciAoSkNBbm5vdGF0aW9uIGEgOiB0cmVlLmdldE1vZGlmaWVycygpLmFubm90YXRpb25zKSB7CiAgICAgICAgICAgICAgICBpZiAoYS5hbm5vdGF0aW9uVHlwZS50eXBlLnRzeW0gPT0gc3ltcy5vdmVycmlkZVR5cGUudHN5bSkgewogICAgICAgICAgICAgICAgICAgIHBvcyA9IGEucG9zKCk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgbG9nLmVycm9yKHBvcywKICAgICAgICAgICAgICAgICAgICAgIGV4cGxpY2l0T3ZlcnJpZGUgPyBFcnJvcnMuTWV0aG9kRG9lc05vdE92ZXJyaWRlU3VwZXJjbGFzcyA6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRXJyb3JzLkFub255bW91c0RpYW1vbmRNZXRob2REb2VzTm90T3ZlcnJpZGVTdXBlcmNsYXNzKEZyYWdtZW50cy5EaWFtb25kQW5vbnltb3VzTWV0aG9kc0ltcGxpY2l0bHlPdmVycmlkZSkpOwogICAgICAgIH0KICAgIH0KCiAgICB2b2lkIGNoZWNrT3ZlcnJpZGUoSkNUcmVlIHRyZWUsIFR5cGUgc2l0ZSwgQ2xhc3NTeW1ib2wgb3JpZ2luLCBNZXRob2RTeW1ib2wgbSkgewogICAgICAgIFR5cGVTeW1ib2wgYyA9IHNpdGUudHN5bTsKICAgICAgICBmb3IgKFN5bWJvbCBzeW0gOiBjLm1lbWJlcnMoKS5nZXRTeW1ib2xzQnlOYW1lKG0ubmFtZSkpIHsKICAgICAgICAgICAgaWYgKG0ub3ZlcnJpZGVzKHN5bSwgb3JpZ2luLCB0eXBlcywgZmFsc2UpKSB7CiAgICAgICAgICAgICAgICBpZiAoKHN5bS5mbGFncygpICYgQUJTVFJBQ1QpID09IDApIHsKICAgICAgICAgICAgICAgICAgICBjaGVja092ZXJyaWRlKHRyZWUsIG0sIChNZXRob2RTeW1ib2wpc3ltLCBvcmlnaW4pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgRmlsdGVyPFN5bWJvbD4gZXF1YWxzSGFzQ29kZUZpbHRlciA9IHMgLT4gTWV0aG9kU3ltYm9sLmltcGxlbWVudGF0aW9uX2ZpbHRlci5hY2NlcHRzKHMpICYmCiAgICAgICAgICAgIChzLmZsYWdzKCkgJiBCQURfT1ZFUlJJREUpID09IDA7CgogICAgcHVibGljIHZvaWQgY2hlY2tDbGFzc092ZXJyaWRlRXF1YWxzQW5kSGFzaElmTmVlZGVkKERpYWdub3N0aWNQb3NpdGlvbiBwb3MsCiAgICAgICAgICAgIENsYXNzU3ltYm9sIHNvbWVDbGFzcykgewogICAgICAgIC8qIEF0IHByZXNlbnQsIGFubm90YXRpb25zIGNhbm5vdCBwb3NzaWJseSBoYXZlIGEgbWV0aG9kIHRoYXQgaXMgb3ZlcnJpZGUKICAgICAgICAgKiBlcXVpdmFsZW50IHdpdGggT2JqZWN0LmVxdWFscyhPYmplY3QpIGJ1dCBpbiBhbnkgY2FzZSB0aGUgY29uZGl0aW9uIGlzCiAgICAgICAgICogZmluZSBmb3IgY29tcGxldGVuZXNzLgogICAgICAgICAqLwogICAgICAgIGlmIChzb21lQ2xhc3MgPT0gKENsYXNzU3ltYm9sKXN5bXMub2JqZWN0VHlwZS50c3ltIHx8CiAgICAgICAgICAgIHNvbWVDbGFzcy5pc0ludGVyZmFjZSgpIHx8IHNvbWVDbGFzcy5pc0VudW0oKSB8fAogICAgICAgICAgICAoc29tZUNsYXNzLmZsYWdzKCkgJiBBTk5PVEFUSU9OKSAhPSAwIHx8CiAgICAgICAgICAgIChzb21lQ2xhc3MuZmxhZ3MoKSAmIEFCU1RSQUNUKSAhPSAwKSByZXR1cm47CiAgICAgICAgLy9hbm9ueW1vdXMgaW5uZXIgY2xhc3NlcyBpbXBsZW1lbnRpbmcgaW50ZXJmYWNlcyBuZWVkIGVzcGVjaWFsIHRyZWF0bWVudAogICAgICAgIGlmIChzb21lQ2xhc3MuaXNBbm9ueW1vdXMoKSkgewogICAgICAgICAgICBMaXN0PFR5cGU+IGludGVyZmFjZXMgPSAgdHlwZXMuaW50ZXJmYWNlcyhzb21lQ2xhc3MudHlwZSk7CiAgICAgICAgICAgIGlmIChpbnRlcmZhY2VzICE9IG51bGwgJiYgIWludGVyZmFjZXMuaXNFbXB0eSgpICYmCiAgICAgICAgICAgICAgICBpbnRlcmZhY2VzLmhlYWQudHN5bSA9PSBzeW1zLmNvbXBhcmF0b3JUeXBlLnRzeW0pIHJldHVybjsKICAgICAgICB9CiAgICAgICAgY2hlY2tDbGFzc092ZXJyaWRlRXF1YWxzQW5kSGFzaChwb3MsIHNvbWVDbGFzcyk7CiAgICB9CgogICAgcHJpdmF0ZSB2b2lkIGNoZWNrQ2xhc3NPdmVycmlkZUVxdWFsc0FuZEhhc2goRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcywKICAgICAgICAgICAgQ2xhc3NTeW1ib2wgc29tZUNsYXNzKSB7CiAgICAgICAgaWYgKGxpbnQuaXNFbmFibGVkKExpbnRDYXRlZ29yeS5PVkVSUklERVMpKSB7CiAgICAgICAgICAgIE1ldGhvZFN5bWJvbCBlcXVhbHNBdE9iamVjdCA9IChNZXRob2RTeW1ib2wpc3ltcy5vYmplY3RUeXBlCiAgICAgICAgICAgICAgICAgICAgLnRzeW0ubWVtYmVycygpLmZpbmRGaXJzdChuYW1lcy5lcXVhbHMpOwogICAgICAgICAgICBNZXRob2RTeW1ib2wgaGFzaENvZGVBdE9iamVjdCA9IChNZXRob2RTeW1ib2wpc3ltcy5vYmplY3RUeXBlCiAgICAgICAgICAgICAgICAgICAgLnRzeW0ubWVtYmVycygpLmZpbmRGaXJzdChuYW1lcy5oYXNoQ29kZSk7CiAgICAgICAgICAgIGJvb2xlYW4gb3ZlcnJpZGVzRXF1YWxzID0gdHlwZXMuaW1wbGVtZW50YXRpb24oZXF1YWxzQXRPYmplY3QsCiAgICAgICAgICAgICAgICBzb21lQ2xhc3MsIGZhbHNlLCBlcXVhbHNIYXNDb2RlRmlsdGVyKS5vd25lciA9PSBzb21lQ2xhc3M7CiAgICAgICAgICAgIGJvb2xlYW4gb3ZlcnJpZGVzSGFzaENvZGUgPSB0eXBlcy5pbXBsZW1lbnRhdGlvbihoYXNoQ29kZUF0T2JqZWN0LAogICAgICAgICAgICAgICAgc29tZUNsYXNzLCBmYWxzZSwgZXF1YWxzSGFzQ29kZUZpbHRlcikgIT0gaGFzaENvZGVBdE9iamVjdDsKCiAgICAgICAgICAgIGlmIChvdmVycmlkZXNFcXVhbHMgJiYgIW92ZXJyaWRlc0hhc2hDb2RlKSB7CiAgICAgICAgICAgICAgICBsb2cud2FybmluZyhMaW50Q2F0ZWdvcnkuT1ZFUlJJREVTLCBwb3MsCiAgICAgICAgICAgICAgICAgICAgICAgICJvdmVycmlkZS5lcXVhbHMuYnV0Lm5vdC5oYXNoY29kZSIsIHNvbWVDbGFzcyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHZvaWQgY2hlY2tNb2R1bGVOYW1lIChKQ01vZHVsZURlY2wgdHJlZSkgewogICAgICAgIE5hbWUgbW9kdWxlTmFtZSA9IHRyZWUuc3ltLm5hbWU7CiAgICAgICAgQXNzZXJ0LmNoZWNrTm9uTnVsbChtb2R1bGVOYW1lKTsKICAgICAgICBpZiAobGludC5pc0VuYWJsZWQoTGludENhdGVnb3J5Lk1PRFVMRSkpIHsKICAgICAgICAgICAgU3RyaW5nIG1vZHVsZU5hbWVTdHJpbmcgPSBtb2R1bGVOYW1lLnRvU3RyaW5nKCk7CiAgICAgICAgICAgIGludCBuYW1lTGVuZ3RoID0gbW9kdWxlTmFtZVN0cmluZy5sZW5ndGgoKTsKICAgICAgICAgICAgaWYgKG5hbWVMZW5ndGggPiAwICYmIENoYXJhY3Rlci5pc0RpZ2l0KG1vZHVsZU5hbWVTdHJpbmcuY2hhckF0KG5hbWVMZW5ndGggLSAxKSkpIHsKICAgICAgICAgICAgICAgIGxvZy53YXJuaW5nKExpbnQuTGludENhdGVnb3J5Lk1PRFVMRSwgdHJlZS5xdWFsSWQucG9zKCksIFdhcm5pbmdzLlBvb3JDaG9pY2VGb3JNb2R1bGVOYW1lKG1vZHVsZU5hbWUpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIGJvb2xlYW4gY2hlY2tOYW1lQ2xhc2goQ2xhc3NTeW1ib2wgb3JpZ2luLCBTeW1ib2wgczEsIFN5bWJvbCBzMikgewogICAgICAgIENsYXNoRmlsdGVyIGNmID0gbmV3IENsYXNoRmlsdGVyKG9yaWdpbi50eXBlKTsKICAgICAgICByZXR1cm4gKGNmLmFjY2VwdHMoczEpICYmCiAgICAgICAgICAgICAgICBjZi5hY2NlcHRzKHMyKSAmJgogICAgICAgICAgICAgICAgdHlwZXMuaGFzU2FtZUFyZ3MoczEuZXJhc3VyZSh0eXBlcyksIHMyLmVyYXN1cmUodHlwZXMpKSk7CiAgICB9CgoKICAgIC8qKiBDaGVjayB0aGF0IGFsbCBhYnN0cmFjdCBtZW1iZXJzIG9mIGdpdmVuIGNsYXNzIGhhdmUgZGVmaW5pdGlvbnMuCiAgICAgKiAgQHBhcmFtIHBvcyAgICAgICAgICBQb3NpdGlvbiB0byBiZSB1c2VkIGZvciBlcnJvciByZXBvcnRpbmcuCiAgICAgKiAgQHBhcmFtIGMgICAgICAgICAgICBUaGUgY2xhc3MuCiAgICAgKi8KICAgIHZvaWQgY2hlY2tBbGxEZWZpbmVkKERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIENsYXNzU3ltYm9sIGMpIHsKICAgICAgICBNZXRob2RTeW1ib2wgdW5kZWYgPSB0eXBlcy5maXJzdFVuaW1wbGVtZW50ZWRBYnN0cmFjdChjKTsKICAgICAgICBpZiAodW5kZWYgIT0gbnVsbCkgewogICAgICAgICAgICBNZXRob2RTeW1ib2wgdW5kZWYxID0KICAgICAgICAgICAgICAgIG5ldyBNZXRob2RTeW1ib2wodW5kZWYuZmxhZ3MoKSwgdW5kZWYubmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZXMubWVtYmVyVHlwZShjLnR5cGUsIHVuZGVmKSwgdW5kZWYub3duZXIpOwogICAgICAgICAgICBsb2cuZXJyb3IocG9zLCAiZG9lcy5ub3Qub3ZlcnJpZGUuYWJzdHJhY3QiLAogICAgICAgICAgICAgICAgICAgICAgYywgdW5kZWYxLCB1bmRlZjEubG9jYXRpb24oKSk7CiAgICAgICAgfQogICAgfQoKICAgIHZvaWQgY2hlY2tOb25DeWNsaWNEZWNsKEpDQ2xhc3NEZWNsIHRyZWUpIHsKICAgICAgICBDeWNsZUNoZWNrZXIgY2MgPSBuZXcgQ3ljbGVDaGVja2VyKCk7CiAgICAgICAgY2Muc2Nhbih0cmVlKTsKICAgICAgICBpZiAoIWNjLmVycm9yRm91bmQgJiYgIWNjLnBhcnRpYWxDaGVjaykgewogICAgICAgICAgICB0cmVlLnN5bS5mbGFnc19maWVsZCB8PSBBQ1lDTElDOwogICAgICAgIH0KICAgIH0KCiAgICBjbGFzcyBDeWNsZUNoZWNrZXIgZXh0ZW5kcyBUcmVlU2Nhbm5lciB7CgogICAgICAgIExpc3Q8U3ltYm9sPiBzZWVuQ2xhc3NlcyA9IExpc3QubmlsKCk7CiAgICAgICAgYm9vbGVhbiBlcnJvckZvdW5kID0gZmFsc2U7CiAgICAgICAgYm9vbGVhbiBwYXJ0aWFsQ2hlY2sgPSBmYWxzZTsKCiAgICAgICAgcHJpdmF0ZSB2b2lkIGNoZWNrU3ltYm9sKERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIFN5bWJvbCBzeW0pIHsKICAgICAgICAgICAgaWYgKHN5bSAhPSBudWxsICYmIHN5bS5raW5kID09IFRZUCkgewogICAgICAgICAgICAgICAgRW52PEF0dHJDb250ZXh0PiBjbGFzc0VudiA9IGVudGVyLmdldEVudigoVHlwZVN5bWJvbClzeW0pOwogICAgICAgICAgICAgICAgaWYgKGNsYXNzRW52ICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICBEaWFnbm9zdGljU291cmNlIHByZXZTb3VyY2UgPSBsb2cuY3VycmVudFNvdXJjZSgpOwogICAgICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGxvZy51c2VTb3VyY2UoY2xhc3NFbnYudG9wbGV2ZWwuc291cmNlZmlsZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHNjYW4oY2xhc3NFbnYudHJlZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGZpbmFsbHkgewogICAgICAgICAgICAgICAgICAgICAgICBsb2cudXNlU291cmNlKHByZXZTb3VyY2UuZ2V0RmlsZSgpKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHN5bS5raW5kID09IFRZUCkgewogICAgICAgICAgICAgICAgICAgIGNoZWNrQ2xhc3MocG9zLCBzeW0sIExpc3QubmlsKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgLy9ub3QgY29tcGxldGVkIHlldAogICAgICAgICAgICAgICAgcGFydGlhbENoZWNrID0gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRTZWxlY3QoSkNGaWVsZEFjY2VzcyB0cmVlKSB7CiAgICAgICAgICAgIHN1cGVyLnZpc2l0U2VsZWN0KHRyZWUpOwogICAgICAgICAgICBjaGVja1N5bWJvbCh0cmVlLnBvcygpLCB0cmVlLnN5bSk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdElkZW50KEpDSWRlbnQgdHJlZSkgewogICAgICAgICAgICBjaGVja1N5bWJvbCh0cmVlLnBvcygpLCB0cmVlLnN5bSk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdFR5cGVBcHBseShKQ1R5cGVBcHBseSB0cmVlKSB7CiAgICAgICAgICAgIHNjYW4odHJlZS5jbGF6eik7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdFR5cGVBcnJheShKQ0FycmF5VHlwZVRyZWUgdHJlZSkgewogICAgICAgICAgICBzY2FuKHRyZWUuZWxlbXR5cGUpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRDbGFzc0RlZihKQ0NsYXNzRGVjbCB0cmVlKSB7CiAgICAgICAgICAgIExpc3Q8SkNUcmVlPiBzdXBlcnR5cGVzID0gTGlzdC5uaWwoKTsKICAgICAgICAgICAgaWYgKHRyZWUuZ2V0RXh0ZW5kc0NsYXVzZSgpICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIHN1cGVydHlwZXMgPSBzdXBlcnR5cGVzLnByZXBlbmQodHJlZS5nZXRFeHRlbmRzQ2xhdXNlKCkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICh0cmVlLmdldEltcGxlbWVudHNDbGF1c2UoKSAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICBmb3IgKEpDVHJlZSBpbnRmIDogdHJlZS5nZXRJbXBsZW1lbnRzQ2xhdXNlKCkpIHsKICAgICAgICAgICAgICAgICAgICBzdXBlcnR5cGVzID0gc3VwZXJ0eXBlcy5wcmVwZW5kKGludGYpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGNoZWNrQ2xhc3ModHJlZS5wb3MoKSwgdHJlZS5zeW0sIHN1cGVydHlwZXMpOwogICAgICAgIH0KCiAgICAgICAgdm9pZCBjaGVja0NsYXNzKERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIFN5bWJvbCBjLCBMaXN0PEpDVHJlZT4gc3VwZXJ0eXBlcykgewogICAgICAgICAgICBpZiAoKGMuZmxhZ3NfZmllbGQgJiBBQ1lDTElDKSAhPSAwKQogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICBpZiAoc2VlbkNsYXNzZXMuY29udGFpbnMoYykpIHsKICAgICAgICAgICAgICAgIGVycm9yRm91bmQgPSB0cnVlOwogICAgICAgICAgICAgICAgbm90ZUN5Y2xpYyhwb3MsIChDbGFzc1N5bWJvbCljKTsKICAgICAgICAgICAgfSBlbHNlIGlmICghYy50eXBlLmlzRXJyb25lb3VzKCkpIHsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgc2VlbkNsYXNzZXMgPSBzZWVuQ2xhc3Nlcy5wcmVwZW5kKGMpOwogICAgICAgICAgICAgICAgICAgIGlmIChjLnR5cGUuaGFzVGFnKENMQVNTKSkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3VwZXJ0eXBlcy5ub25FbXB0eSgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY2FuKHN1cGVydHlwZXMpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2xhc3NUeXBlIGN0ID0gKENsYXNzVHlwZSljLnR5cGU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY3Quc3VwZXJ0eXBlX2ZpZWxkID09IG51bGwgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3QuaW50ZXJmYWNlc19maWVsZCA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9ub3QgY29tcGxldGVkIHlldAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcnRpYWxDaGVjayA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tTeW1ib2wocG9zLCBjdC5zdXBlcnR5cGVfZmllbGQudHN5bSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKFR5cGUgaW50ZiA6IGN0LmludGVyZmFjZXNfZmllbGQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGVja1N5bWJvbChwb3MsIGludGYudHN5bSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGMub3duZXIua2luZCA9PSBUWVApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoZWNrU3ltYm9sKHBvcywgYy5vd25lcik7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAgICAgICAgIHNlZW5DbGFzc2VzID0gc2VlbkNsYXNzZXMudGFpbDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKiogQ2hlY2sgZm9yIGN5Y2xpYyByZWZlcmVuY2VzLiBJc3N1ZSBhbiBlcnJvciBpZiB0aGUKICAgICAqICBzeW1ib2wgb2YgdGhlIHR5cGUgcmVmZXJyZWQgdG8gaGFzIGEgTE9DS0VEIGZsYWcgc2V0LgogICAgICoKICAgICAqICBAcGFyYW0gcG9zICAgICAgUG9zaXRpb24gdG8gYmUgdXNlZCBmb3IgZXJyb3IgcmVwb3J0aW5nLgogICAgICogIEBwYXJhbSB0ICAgICAgICBUaGUgdHlwZSByZWZlcnJlZCB0by4KICAgICAqLwogICAgdm9pZCBjaGVja05vbkN5Y2xpYyhEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBUeXBlIHQpIHsKICAgICAgICBjaGVja05vbkN5Y2xpY0ludGVybmFsKHBvcywgdCk7CiAgICB9CgoKICAgIHZvaWQgY2hlY2tOb25DeWNsaWMoRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcywgVHlwZVZhciB0KSB7CiAgICAgICAgY2hlY2tOb25DeWNsaWMxKHBvcywgdCwgTGlzdC5uaWwoKSk7CiAgICB9CgogICAgcHJpdmF0ZSB2b2lkIGNoZWNrTm9uQ3ljbGljMShEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBUeXBlIHQsIExpc3Q8VHlwZVZhcj4gc2VlbikgewogICAgICAgIGZpbmFsIFR5cGVWYXIgdHY7CiAgICAgICAgaWYgICh0Lmhhc1RhZyhUWVBFVkFSKSAmJiAodC50c3ltLmZsYWdzKCkgJiBVTkFUVFJJQlVURUQpICE9IDApCiAgICAgICAgICAgIHJldHVybjsKICAgICAgICBpZiAoc2Vlbi5jb250YWlucyh0KSkgewogICAgICAgICAgICB0diA9IChUeXBlVmFyKXQ7CiAgICAgICAgICAgIHR2LmJvdW5kID0gdHlwZXMuY3JlYXRlRXJyb3JUeXBlKHQpOwogICAgICAgICAgICBsb2cuZXJyb3IocG9zLCAiY3ljbGljLmluaGVyaXRhbmNlIiwgdCk7CiAgICAgICAgfSBlbHNlIGlmICh0Lmhhc1RhZyhUWVBFVkFSKSkgewogICAgICAgICAgICB0diA9IChUeXBlVmFyKXQ7CiAgICAgICAgICAgIHNlZW4gPSBzZWVuLnByZXBlbmQodHYpOwogICAgICAgICAgICBmb3IgKFR5cGUgYiA6IHR5cGVzLmdldEJvdW5kcyh0dikpCiAgICAgICAgICAgICAgICBjaGVja05vbkN5Y2xpYzEocG9zLCBiLCBzZWVuKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqIENoZWNrIGZvciBjeWNsaWMgcmVmZXJlbmNlcy4gSXNzdWUgYW4gZXJyb3IgaWYgdGhlCiAgICAgKiAgc3ltYm9sIG9mIHRoZSB0eXBlIHJlZmVycmVkIHRvIGhhcyBhIExPQ0tFRCBmbGFnIHNldC4KICAgICAqCiAgICAgKiAgQHBhcmFtIHBvcyAgICAgIFBvc2l0aW9uIHRvIGJlIHVzZWQgZm9yIGVycm9yIHJlcG9ydGluZy4KICAgICAqICBAcGFyYW0gdCAgICAgICAgVGhlIHR5cGUgcmVmZXJyZWQgdG8uCiAgICAgKiAgQHJldHVybnMgICAgICAgIFRydWUgaWYgdGhlIGNoZWNrIGNvbXBsZXRlZCBvbiBhbGwgYXR0cmlidXRlZCBjbGFzc2VzCiAgICAgKi8KICAgIHByaXZhdGUgYm9vbGVhbiBjaGVja05vbkN5Y2xpY0ludGVybmFsKERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIFR5cGUgdCkgewogICAgICAgIGJvb2xlYW4gY29tcGxldGUgPSB0cnVlOyAvLyB3YXMgdGhlIGNoZWNrIGNvbXBsZXRlPwogICAgICAgIC8vLSBTeXN0ZW0uZXJyLnByaW50bG4oImNoZWNrTm9uQ3ljbGljSW50ZXJuYWwoIit0KyIpOyIpOy8vREVCVUcKICAgICAgICBTeW1ib2wgYyA9IHQudHN5bTsKICAgICAgICBpZiAoKGMuZmxhZ3NfZmllbGQgJiBBQ1lDTElDKSAhPSAwKSByZXR1cm4gdHJ1ZTsKCiAgICAgICAgaWYgKChjLmZsYWdzX2ZpZWxkICYgTE9DS0VEKSAhPSAwKSB7CiAgICAgICAgICAgIG5vdGVDeWNsaWMocG9zLCAoQ2xhc3NTeW1ib2wpYyk7CiAgICAgICAgfSBlbHNlIGlmICghYy50eXBlLmlzRXJyb25lb3VzKCkpIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIGMuZmxhZ3NfZmllbGQgfD0gTE9DS0VEOwogICAgICAgICAgICAgICAgaWYgKGMudHlwZS5oYXNUYWcoQ0xBU1MpKSB7CiAgICAgICAgICAgICAgICAgICAgQ2xhc3NUeXBlIGNsYXp6ID0gKENsYXNzVHlwZSljLnR5cGU7CiAgICAgICAgICAgICAgICAgICAgaWYgKGNsYXp6LmludGVyZmFjZXNfZmllbGQgIT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChMaXN0PFR5cGU+IGw9Y2xhenouaW50ZXJmYWNlc19maWVsZDsgbC5ub25FbXB0eSgpOyBsPWwudGFpbCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBsZXRlICY9IGNoZWNrTm9uQ3ljbGljSW50ZXJuYWwocG9zLCBsLmhlYWQpOwogICAgICAgICAgICAgICAgICAgIGlmIChjbGF6ei5zdXBlcnR5cGVfZmllbGQgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICBUeXBlIHN0ID0gY2xhenouc3VwZXJ0eXBlX2ZpZWxkOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3QgIT0gbnVsbCAmJiBzdC5oYXNUYWcoQ0xBU1MpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tcGxldGUgJj0gY2hlY2tOb25DeWNsaWNJbnRlcm5hbChwb3MsIHN0KTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKGMub3duZXIua2luZCA9PSBUWVApCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBsZXRlICY9IGNoZWNrTm9uQ3ljbGljSW50ZXJuYWwocG9zLCBjLm93bmVyLnR5cGUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAgICAgYy5mbGFnc19maWVsZCAmPSB+TE9DS0VEOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmIChjb21wbGV0ZSkKICAgICAgICAgICAgY29tcGxldGUgPSAoKGMuZmxhZ3NfZmllbGQgJiBVTkFUVFJJQlVURUQpID09IDApICYmIGMuaXNDb21wbGV0ZWQoKTsKICAgICAgICBpZiAoY29tcGxldGUpIGMuZmxhZ3NfZmllbGQgfD0gQUNZQ0xJQzsKICAgICAgICByZXR1cm4gY29tcGxldGU7CiAgICB9CgogICAgLyoqIE5vdGUgdGhhdCB3ZSBmb3VuZCBhbiBpbmhlcml0YW5jZSBjeWNsZS4gKi8KICAgIHByaXZhdGUgdm9pZCBub3RlQ3ljbGljKERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIENsYXNzU3ltYm9sIGMpIHsKICAgICAgICBsb2cuZXJyb3IocG9zLCAiY3ljbGljLmluaGVyaXRhbmNlIiwgYyk7CiAgICAgICAgZm9yIChMaXN0PFR5cGU+IGw9dHlwZXMuaW50ZXJmYWNlcyhjLnR5cGUpOyBsLm5vbkVtcHR5KCk7IGw9bC50YWlsKQogICAgICAgICAgICBsLmhlYWQgPSB0eXBlcy5jcmVhdGVFcnJvclR5cGUoKENsYXNzU3ltYm9sKWwuaGVhZC50c3ltLCBUeXBlLm5vVHlwZSk7CiAgICAgICAgVHlwZSBzdCA9IHR5cGVzLnN1cGVydHlwZShjLnR5cGUpOwogICAgICAgIGlmIChzdC5oYXNUYWcoQ0xBU1MpKQogICAgICAgICAgICAoKENsYXNzVHlwZSljLnR5cGUpLnN1cGVydHlwZV9maWVsZCA9IHR5cGVzLmNyZWF0ZUVycm9yVHlwZSgoQ2xhc3NTeW1ib2wpc3QudHN5bSwgVHlwZS5ub1R5cGUpOwogICAgICAgIGMudHlwZSA9IHR5cGVzLmNyZWF0ZUVycm9yVHlwZShjLCBjLnR5cGUpOwogICAgICAgIGMuZmxhZ3NfZmllbGQgfD0gQUNZQ0xJQzsKICAgIH0KCiAgICAvKiogQ2hlY2sgdGhhdCBhbGwgbWV0aG9kcyB3aGljaCBpbXBsZW1lbnQgc29tZQogICAgICogIG1ldGhvZCBjb25mb3JtIHRvIHRoZSBtZXRob2QgdGhleSBpbXBsZW1lbnQuCiAgICAgKiAgQHBhcmFtIHRyZWUgICAgICAgICBUaGUgY2xhc3MgZGVmaW5pdGlvbiB3aG9zZSBtZW1iZXJzIGFyZSBjaGVja2VkLgogICAgICovCiAgICB2b2lkIGNoZWNrSW1wbGVtZW50YXRpb25zKEpDQ2xhc3NEZWNsIHRyZWUpIHsKICAgICAgICBjaGVja0ltcGxlbWVudGF0aW9ucyh0cmVlLCB0cmVlLnN5bSwgdHJlZS5zeW0pOwogICAgfQogICAgLy93aGVyZQogICAgICAgIC8qKiBDaGVjayB0aGF0IGFsbCBtZXRob2RzIHdoaWNoIGltcGxlbWVudCBzb21lCiAgICAgICAgICogIG1ldGhvZCBpbiBgaWMnIGNvbmZvcm0gdG8gdGhlIG1ldGhvZCB0aGV5IGltcGxlbWVudC4KICAgICAgICAgKi8KICAgICAgICB2b2lkIGNoZWNrSW1wbGVtZW50YXRpb25zKEpDVHJlZSB0cmVlLCBDbGFzc1N5bWJvbCBvcmlnaW4sIENsYXNzU3ltYm9sIGljKSB7CiAgICAgICAgICAgIGZvciAoTGlzdDxUeXBlPiBsID0gdHlwZXMuY2xvc3VyZShpYy50eXBlKTsgbC5ub25FbXB0eSgpOyBsID0gbC50YWlsKSB7CiAgICAgICAgICAgICAgICBDbGFzc1N5bWJvbCBsYyA9IChDbGFzc1N5bWJvbClsLmhlYWQudHN5bTsKICAgICAgICAgICAgICAgIGlmICgobGMuZmxhZ3MoKSAmIEFCU1RSQUNUKSAhPSAwKSB7CiAgICAgICAgICAgICAgICAgICAgZm9yIChTeW1ib2wgc3ltIDogbGMubWVtYmVycygpLmdldFN5bWJvbHMoTk9OX1JFQ1VSU0lWRSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN5bS5raW5kID09IE1USCAmJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgKHN5bS5mbGFncygpICYgKFNUQVRJQ3xBQlNUUkFDVCkpID09IEFCU1RSQUNUKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXRob2RTeW1ib2wgYWJzbWV0aCA9IChNZXRob2RTeW1ib2wpc3ltOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgTWV0aG9kU3ltYm9sIGltcGxtZXRoID0gYWJzbWV0aC5pbXBsZW1lbnRhdGlvbihvcmlnaW4sIHR5cGVzLCBmYWxzZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW1wbG1ldGggIT0gbnVsbCAmJiBpbXBsbWV0aCAhPSBhYnNtZXRoICYmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGltcGxtZXRoLm93bmVyLmZsYWdzKCkgJiBJTlRFUkZBQ0UpID09CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG9yaWdpbi5mbGFncygpICYgSU5URVJGQUNFKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGRvbid0IGNoZWNrIGlmIGltcGxtZXRoIGlzIGluIGEgY2xhc3MsIHlldAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG9yaWdpbiBpcyBhbiBpbnRlcmZhY2UuIFRoaXMgY2FzZSBhcmlzZXMgb25seQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGlmIGltcGxtZXRoIGlzIGRlY2xhcmVkIGluIE9iamVjdC4gVGhlIHJlYXNvbiBpcwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRoYXQgaW50ZXJmYWNlcyByZWFsbHkgZG9uJ3QgaW5oZXJpdCBmcm9tCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gT2JqZWN0IGl0J3MganVzdCB0aGF0IHRoZSBjb21waWxlciByZXByZXNlbnRzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhpbmdzIHRoYXQgd2F5LgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoZWNrT3ZlcnJpZGUodHJlZSwgaW1wbG1ldGgsIGFic21ldGgsIG9yaWdpbik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgLyoqIENoZWNrIHRoYXQgYWxsIGFic3RyYWN0IG1ldGhvZHMgaW1wbGVtZW50ZWQgYnkgYSBjbGFzcyBhcmUKICAgICAqICBtdXR1YWxseSBjb21wYXRpYmxlLgogICAgICogIEBwYXJhbSBwb3MgICAgICAgICAgUG9zaXRpb24gdG8gYmUgdXNlZCBmb3IgZXJyb3IgcmVwb3J0aW5nLgogICAgICogIEBwYXJhbSBjICAgICAgICAgICAgVGhlIGNsYXNzIHdob3NlIGludGVyZmFjZXMgYXJlIGNoZWNrZWQuCiAgICAgKi8KICAgIHZvaWQgY2hlY2tDb21wYXRpYmxlU3VwZXJ0eXBlcyhEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBUeXBlIGMpIHsKICAgICAgICBMaXN0PFR5cGU+IHN1cGVydHlwZXMgPSB0eXBlcy5pbnRlcmZhY2VzKGMpOwogICAgICAgIFR5cGUgc3VwZXJ0eXBlID0gdHlwZXMuc3VwZXJ0eXBlKGMpOwogICAgICAgIGlmIChzdXBlcnR5cGUuaGFzVGFnKENMQVNTKSAmJgogICAgICAgICAgICAoc3VwZXJ0eXBlLnRzeW0uZmxhZ3MoKSAmIEFCU1RSQUNUKSAhPSAwKQogICAgICAgICAgICBzdXBlcnR5cGVzID0gc3VwZXJ0eXBlcy5wcmVwZW5kKHN1cGVydHlwZSk7CiAgICAgICAgZm9yIChMaXN0PFR5cGU+IGwgPSBzdXBlcnR5cGVzOyBsLm5vbkVtcHR5KCk7IGwgPSBsLnRhaWwpIHsKICAgICAgICAgICAgaWYgKCFsLmhlYWQuZ2V0VHlwZUFyZ3VtZW50cygpLmlzRW1wdHkoKSAmJgogICAgICAgICAgICAgICAgIWNoZWNrQ29tcGF0aWJsZUFic3RyYWN0cyhwb3MsIGwuaGVhZCwgbC5oZWFkLCBjKSkKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgZm9yIChMaXN0PFR5cGU+IG0gPSBzdXBlcnR5cGVzOyBtICE9IGw7IG0gPSBtLnRhaWwpCiAgICAgICAgICAgICAgICBpZiAoIWNoZWNrQ29tcGF0aWJsZUFic3RyYWN0cyhwb3MsIGwuaGVhZCwgbS5oZWFkLCBjKSkKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIGNoZWNrQ29tcGF0aWJsZUNvbmNyZXRlcyhwb3MsIGMpOwogICAgfQoKICAgIHZvaWQgY2hlY2tDb25mbGljdHMoRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcywgU3ltYm9sIHN5bSwgVHlwZVN5bWJvbCBjKSB7CiAgICAgICAgZm9yIChUeXBlIGN0ID0gYy50eXBlOyBjdCAhPSBUeXBlLm5vVHlwZSA7IGN0ID0gdHlwZXMuc3VwZXJ0eXBlKGN0KSkgewogICAgICAgICAgICBmb3IgKFN5bWJvbCBzeW0yIDogY3QudHN5bS5tZW1iZXJzKCkuZ2V0U3ltYm9sc0J5TmFtZShzeW0ubmFtZSwgTk9OX1JFQ1VSU0lWRSkpIHsKICAgICAgICAgICAgICAgIC8vIFZNIGFsbG93cyBtZXRob2RzIGFuZCB2YXJpYWJsZXMgd2l0aCBkaWZmZXJpbmcgdHlwZXMKICAgICAgICAgICAgICAgIGlmIChzeW0ua2luZCA9PSBzeW0yLmtpbmQgJiYKICAgICAgICAgICAgICAgICAgICB0eXBlcy5pc1NhbWVUeXBlKHR5cGVzLmVyYXN1cmUoc3ltLnR5cGUpLCB0eXBlcy5lcmFzdXJlKHN5bTIudHlwZSkpICYmCiAgICAgICAgICAgICAgICAgICAgc3ltICE9IHN5bTIgJiYKICAgICAgICAgICAgICAgICAgICAoc3ltLmZsYWdzKCkgJiBGbGFncy5TWU5USEVUSUMpICE9IChzeW0yLmZsYWdzKCkgJiBGbGFncy5TWU5USEVUSUMpICYmCiAgICAgICAgICAgICAgICAgICAgKHN5bS5mbGFncygpICYgQlJJREdFKSA9PSAwICYmIChzeW0yLmZsYWdzKCkgJiBCUklER0UpID09IDApIHsKICAgICAgICAgICAgICAgICAgICBzeW50aGV0aWNFcnJvcihwb3MsIChzeW0yLmZsYWdzKCkgJiBTWU5USEVUSUMpID09IDAgPyBzeW0yIDogc3ltKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqIENoZWNrIHRoYXQgYWxsIG5vbi1vdmVycmlkZSBlcXVpdmFsZW50IG1ldGhvZHMgYWNjZXNzaWJsZSBmcm9tICdzaXRlJwogICAgICogIGFyZSBtdXR1YWxseSBjb21wYXRpYmxlIChKTFMgOC40LjgvOS40LjEpLgogICAgICoKICAgICAqICBAcGFyYW0gcG9zICBQb3NpdGlvbiB0byBiZSB1c2VkIGZvciBlcnJvciByZXBvcnRpbmcuCiAgICAgKiAgQHBhcmFtIHNpdGUgVGhlIGNsYXNzIHdob3NlIG1ldGhvZHMgYXJlIGNoZWNrZWQuCiAgICAgKiAgQHBhcmFtIHN5bSAgVGhlIG1ldGhvZCBzeW1ib2wgdG8gYmUgY2hlY2tlZC4KICAgICAqLwogICAgdm9pZCBjaGVja092ZXJyaWRlQ2xhc2hlcyhEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBUeXBlIHNpdGUsIE1ldGhvZFN5bWJvbCBzeW0pIHsKICAgICAgICAgQ2xhc2hGaWx0ZXIgY2YgPSBuZXcgQ2xhc2hGaWx0ZXIoc2l0ZSk7CiAgICAgICAgLy9mb3IgZWFjaCBtZXRob2QgbTEgdGhhdCBpcyBvdmVycmlkZGVuIChkaXJlY3RseSBvciBpbmRpcmVjdGx5KQogICAgICAgIC8vYnkgbWV0aG9kICdzeW0nIGluICdzaXRlJy4uLgoKICAgICAgICBMaXN0PE1ldGhvZFN5bWJvbD4gcG90ZW50aWFsbHlBbWJpZ3VvdXNMaXN0ID0gTGlzdC5uaWwoKTsKICAgICAgICBib29sZWFuIG92ZXJyaWRlc0FueSA9IGZhbHNlOwogICAgICAgIGZvciAoU3ltYm9sIG0xIDogdHlwZXMubWVtYmVyc0Nsb3N1cmUoc2l0ZSwgZmFsc2UpLmdldFN5bWJvbHNCeU5hbWUoc3ltLm5hbWUsIGNmKSkgewogICAgICAgICAgICBpZiAoIXN5bS5vdmVycmlkZXMobTEsIHNpdGUudHN5bSwgdHlwZXMsIGZhbHNlKSkgewogICAgICAgICAgICAgICAgaWYgKG0xID09IHN5bSkgewogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmICghb3ZlcnJpZGVzQW55KSB7CiAgICAgICAgICAgICAgICAgICAgcG90ZW50aWFsbHlBbWJpZ3VvdXNMaXN0ID0gcG90ZW50aWFsbHlBbWJpZ3VvdXNMaXN0LnByZXBlbmQoKE1ldGhvZFN5bWJvbCltMSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKG0xICE9IHN5bSkgewogICAgICAgICAgICAgICAgb3ZlcnJpZGVzQW55ID0gdHJ1ZTsKICAgICAgICAgICAgICAgIHBvdGVudGlhbGx5QW1iaWd1b3VzTGlzdCA9IExpc3QubmlsKCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vLi4uY2hlY2sgZWFjaCBtZXRob2QgbTIgdGhhdCBpcyBhIG1lbWJlciBvZiAnc2l0ZScKICAgICAgICAgICAgZm9yIChTeW1ib2wgbTIgOiB0eXBlcy5tZW1iZXJzQ2xvc3VyZShzaXRlLCBmYWxzZSkuZ2V0U3ltYm9sc0J5TmFtZShzeW0ubmFtZSwgY2YpKSB7CiAgICAgICAgICAgICAgICBpZiAobTIgPT0gbTEpIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgLy9pZiAoaSkgdGhlIHNpZ25hdHVyZSBvZiAnc3ltJyBpcyBub3QgYSBzdWJzaWduYXR1cmUgb2YgbTEgKHNlZW4gYXMKICAgICAgICAgICAgICAgIC8vYSBtZW1iZXIgb2YgJ3NpdGUnKSBhbmQgKGlpKSBtMSBoYXMgdGhlIHNhbWUgZXJhc3VyZSBhcyBtMiwgaXNzdWUgYW4gZXJyb3IKICAgICAgICAgICAgICAgIGlmICghdHlwZXMuaXNTdWJTaWduYXR1cmUoc3ltLnR5cGUsIHR5cGVzLm1lbWJlclR5cGUoc2l0ZSwgbTIpLCBhbGxvd1N0cmljdE1ldGhvZENsYXNoQ2hlY2spICYmCiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVzLmhhc1NhbWVBcmdzKG0yLmVyYXN1cmUodHlwZXMpLCBtMS5lcmFzdXJlKHR5cGVzKSkpIHsKICAgICAgICAgICAgICAgICAgICBzeW0uZmxhZ3NfZmllbGQgfD0gQ0xBU0g7CiAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGtleSA9IG0xID09IHN5bSA/CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAibmFtZS5jbGFzaC5zYW1lLmVyYXN1cmUubm8ub3ZlcnJpZGUiIDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJuYW1lLmNsYXNoLnNhbWUuZXJhc3VyZS5uby5vdmVycmlkZS4xIjsKICAgICAgICAgICAgICAgICAgICBsb2cuZXJyb3IocG9zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAga2V5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ltLCBzeW0ubG9jYXRpb24oKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG0yLCBtMi5sb2NhdGlvbigpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbTEsIG0xLmxvY2F0aW9uKCkpOwogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCFvdmVycmlkZXNBbnkpIHsKICAgICAgICAgICAgZm9yIChNZXRob2RTeW1ib2wgbTogcG90ZW50aWFsbHlBbWJpZ3VvdXNMaXN0KSB7CiAgICAgICAgICAgICAgICBjaGVja1BvdGVudGlhbGx5QW1iaWd1b3VzT3ZlcmxvYWRzKHBvcywgc2l0ZSwgc3ltLCBtKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKiogQ2hlY2sgdGhhdCBhbGwgc3RhdGljIG1ldGhvZHMgYWNjZXNzaWJsZSBmcm9tICdzaXRlJyBhcmUKICAgICAqICBtdXR1YWxseSBjb21wYXRpYmxlIChKTFMgOC40LjgpLgogICAgICoKICAgICAqICBAcGFyYW0gcG9zICBQb3NpdGlvbiB0byBiZSB1c2VkIGZvciBlcnJvciByZXBvcnRpbmcuCiAgICAgKiAgQHBhcmFtIHNpdGUgVGhlIGNsYXNzIHdob3NlIG1ldGhvZHMgYXJlIGNoZWNrZWQuCiAgICAgKiAgQHBhcmFtIHN5bSAgVGhlIG1ldGhvZCBzeW1ib2wgdG8gYmUgY2hlY2tlZC4KICAgICAqLwogICAgdm9pZCBjaGVja0hpZGVDbGFzaGVzKERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIFR5cGUgc2l0ZSwgTWV0aG9kU3ltYm9sIHN5bSkgewogICAgICAgIENsYXNoRmlsdGVyIGNmID0gbmV3IENsYXNoRmlsdGVyKHNpdGUpOwogICAgICAgIC8vZm9yIGVhY2ggbWV0aG9kIG0xIHRoYXQgaXMgYSBtZW1iZXIgb2YgJ3NpdGUnLi4uCiAgICAgICAgZm9yIChTeW1ib2wgcyA6IHR5cGVzLm1lbWJlcnNDbG9zdXJlKHNpdGUsIHRydWUpLmdldFN5bWJvbHNCeU5hbWUoc3ltLm5hbWUsIGNmKSkgewogICAgICAgICAgICAvL2lmIChpKSB0aGUgc2lnbmF0dXJlIG9mICdzeW0nIGlzIG5vdCBhIHN1YnNpZ25hdHVyZSBvZiBtMSAoc2VlbiBhcwogICAgICAgICAgICAvL2EgbWVtYmVyIG9mICdzaXRlJykgYW5kIChpaSkgJ3N5bScgaGFzIHRoZSBzYW1lIGVyYXN1cmUgYXMgbTEsIGlzc3VlIGFuIGVycm9yCiAgICAgICAgICAgIGlmICghdHlwZXMuaXNTdWJTaWduYXR1cmUoc3ltLnR5cGUsIHR5cGVzLm1lbWJlclR5cGUoc2l0ZSwgcyksIGFsbG93U3RyaWN0TWV0aG9kQ2xhc2hDaGVjaykpIHsKICAgICAgICAgICAgICAgIGlmICh0eXBlcy5oYXNTYW1lQXJncyhzLmVyYXN1cmUodHlwZXMpLCBzeW0uZXJhc3VyZSh0eXBlcykpKSB7CiAgICAgICAgICAgICAgICAgICAgbG9nLmVycm9yKHBvcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJuYW1lLmNsYXNoLnNhbWUuZXJhc3VyZS5uby5oaWRlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5bSwgc3ltLmxvY2F0aW9uKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzLCBzLmxvY2F0aW9uKCkpOwogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgY2hlY2tQb3RlbnRpYWxseUFtYmlndW91c092ZXJsb2Fkcyhwb3MsIHNpdGUsIHN5bSwgKE1ldGhvZFN5bWJvbClzKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICB9CiAgICAgfQoKICAgICAvL3doZXJlCiAgICAgcHJpdmF0ZSBjbGFzcyBDbGFzaEZpbHRlciBpbXBsZW1lbnRzIEZpbHRlcjxTeW1ib2w+IHsKCiAgICAgICAgIFR5cGUgc2l0ZTsKCiAgICAgICAgIENsYXNoRmlsdGVyKFR5cGUgc2l0ZSkgewogICAgICAgICAgICAgdGhpcy5zaXRlID0gc2l0ZTsKICAgICAgICAgfQoKICAgICAgICAgYm9vbGVhbiBzaG91bGRTa2lwKFN5bWJvbCBzKSB7CiAgICAgICAgICAgICByZXR1cm4gKHMuZmxhZ3MoKSAmIENMQVNIKSAhPSAwICYmCiAgICAgICAgICAgICAgICBzLm93bmVyID09IHNpdGUudHN5bTsKICAgICAgICAgfQoKICAgICAgICAgcHVibGljIGJvb2xlYW4gYWNjZXB0cyhTeW1ib2wgcykgewogICAgICAgICAgICAgcmV0dXJuIHMua2luZCA9PSBNVEggJiYKICAgICAgICAgICAgICAgICAgICAgKHMuZmxhZ3MoKSAmIFNZTlRIRVRJQykgPT0gMCAmJgogICAgICAgICAgICAgICAgICAgICAhc2hvdWxkU2tpcChzKSAmJgogICAgICAgICAgICAgICAgICAgICBzLmlzSW5oZXJpdGVkSW4oc2l0ZS50c3ltLCB0eXBlcykgJiYKICAgICAgICAgICAgICAgICAgICAgIXMuaXNDb25zdHJ1Y3RvcigpOwogICAgICAgICB9CiAgICAgfQoKICAgIHZvaWQgY2hlY2tEZWZhdWx0TWV0aG9kQ2xhc2hlcyhEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBUeXBlIHNpdGUpIHsKICAgICAgICBEZWZhdWx0TWV0aG9kQ2xhc2hGaWx0ZXIgZGNmID0gbmV3IERlZmF1bHRNZXRob2RDbGFzaEZpbHRlcihzaXRlKTsKICAgICAgICBmb3IgKFN5bWJvbCBtIDogdHlwZXMubWVtYmVyc0Nsb3N1cmUoc2l0ZSwgZmFsc2UpLmdldFN5bWJvbHMoZGNmKSkgewogICAgICAgICAgICBBc3NlcnQuY2hlY2sobS5raW5kID09IE1USCk7CiAgICAgICAgICAgIExpc3Q8TWV0aG9kU3ltYm9sPiBwcm92ID0gdHlwZXMuaW50ZXJmYWNlQ2FuZGlkYXRlcyhzaXRlLCAoTWV0aG9kU3ltYm9sKW0pOwogICAgICAgICAgICBpZiAocHJvdi5zaXplKCkgPiAxKSB7CiAgICAgICAgICAgICAgICBMaXN0QnVmZmVyPFN5bWJvbD4gYWJzdHJhY3RzID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgICAgICAgICAgTGlzdEJ1ZmZlcjxTeW1ib2w+IGRlZmF1bHRzID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgICAgICAgICAgZm9yIChNZXRob2RTeW1ib2wgcHJvdlN5bSA6IHByb3YpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoKHByb3ZTeW0uZmxhZ3MoKSAmIERFRkFVTFQpICE9IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdHMgPSBkZWZhdWx0cy5hcHBlbmQocHJvdlN5bSk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICgocHJvdlN5bS5mbGFncygpICYgQUJTVFJBQ1QpICE9IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgYWJzdHJhY3RzID0gYWJzdHJhY3RzLmFwcGVuZChwcm92U3ltKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKGRlZmF1bHRzLm5vbkVtcHR5KCkgJiYgZGVmYXVsdHMuc2l6ZSgpICsgYWJzdHJhY3RzLnNpemUoKSA+PSAyKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vc3Ryb25nIHNlbWFudGljcyAtIGlzc3VlIGFuIGVycm9yIGlmIHR3byBzaWJsaW5nIGludGVyZmFjZXMKICAgICAgICAgICAgICAgICAgICAgICAgLy9oYXZlIHR3byBvdmVycmlkZS1lcXVpdmFsZW50IGRlZmF1bHRzIC0gb3IgaWYgb25lIGlzIGFic3RyYWN0CiAgICAgICAgICAgICAgICAgICAgICAgIC8vYW5kIHRoZSBvdGhlciBpcyBkZWZhdWx0CiAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBlcnJLZXk7CiAgICAgICAgICAgICAgICAgICAgICAgIFN5bWJvbCBzMSA9IGRlZmF1bHRzLmZpcnN0KCk7CiAgICAgICAgICAgICAgICAgICAgICAgIFN5bWJvbCBzMjsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRlZmF1bHRzLnNpemUoKSA+IDEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycktleSA9ICJ0eXBlcy5pbmNvbXBhdGlibGUudW5yZWxhdGVkLmRlZmF1bHRzIjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHMyID0gZGVmYXVsdHMudG9MaXN0KCkudGFpbC5oZWFkOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyS2V5ID0gInR5cGVzLmluY29tcGF0aWJsZS5hYnN0cmFjdC5kZWZhdWx0IjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHMyID0gYWJzdHJhY3RzLmZpcnN0KCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgbG9nLmVycm9yKHBvcywgZXJyS2V5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEtpbmRzLmtpbmROYW1lKHNpdGUudHN5bSksIHNpdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbS5uYW1lLCB0eXBlcy5tZW1iZXJUeXBlKHNpdGUsIG0pLmdldFBhcmFtZXRlclR5cGVzKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgczEubG9jYXRpb24oKSwgczIubG9jYXRpb24oKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvL3doZXJlCiAgICAgcHJpdmF0ZSBjbGFzcyBEZWZhdWx0TWV0aG9kQ2xhc2hGaWx0ZXIgaW1wbGVtZW50cyBGaWx0ZXI8U3ltYm9sPiB7CgogICAgICAgICBUeXBlIHNpdGU7CgogICAgICAgICBEZWZhdWx0TWV0aG9kQ2xhc2hGaWx0ZXIoVHlwZSBzaXRlKSB7CiAgICAgICAgICAgICB0aGlzLnNpdGUgPSBzaXRlOwogICAgICAgICB9CgogICAgICAgICBwdWJsaWMgYm9vbGVhbiBhY2NlcHRzKFN5bWJvbCBzKSB7CiAgICAgICAgICAgICByZXR1cm4gcy5raW5kID09IE1USCAmJgogICAgICAgICAgICAgICAgICAgICAocy5mbGFncygpICYgREVGQVVMVCkgIT0gMCAmJgogICAgICAgICAgICAgICAgICAgICBzLmlzSW5oZXJpdGVkSW4oc2l0ZS50c3ltLCB0eXBlcykgJiYKICAgICAgICAgICAgICAgICAgICAgIXMuaXNDb25zdHJ1Y3RvcigpOwogICAgICAgICB9CiAgICAgfQoKICAgIC8qKgogICAgICAqIFJlcG9ydCB3YXJuaW5ncyBmb3IgcG90ZW50aWFsbHkgYW1iaWd1b3VzIG1ldGhvZCBkZWNsYXJhdGlvbnMuIFR3byBkZWNsYXJhdGlvbnMKICAgICAgKiBhcmUgcG90ZW50aWFsbHkgYW1iaWd1b3VzIGlmIHRoZXkgZmVhdHVyZSB0d28gdW5yZWxhdGVkIGZ1bmN0aW9uYWwgaW50ZXJmYWNlCiAgICAgICogaW4gc2FtZSBhcmd1bWVudCBwb3NpdGlvbiAoaW4gd2hpY2ggY2FzZSwgYSBjYWxsIHNpdGUgcGFzc2luZyBhbiBpbXBsaWNpdAogICAgICAqIGxhbWJkYSB3b3VsZCBiZSBhbWJpZ3VvdXMpLgogICAgICAqLwogICAgdm9pZCBjaGVja1BvdGVudGlhbGx5QW1iaWd1b3VzT3ZlcmxvYWRzKERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIFR5cGUgc2l0ZSwKICAgICAgICAgICAgTWV0aG9kU3ltYm9sIG1zeW0xLCBNZXRob2RTeW1ib2wgbXN5bTIpIHsKICAgICAgICBpZiAobXN5bTEgIT0gbXN5bTIgJiYKICAgICAgICAgICAgICAgIGFsbG93RGVmYXVsdE1ldGhvZHMgJiYKICAgICAgICAgICAgICAgIGxpbnQuaXNFbmFibGVkKExpbnRDYXRlZ29yeS5PVkVSTE9BRFMpICYmCiAgICAgICAgICAgICAgICAobXN5bTEuZmxhZ3MoKSAmIFBPVEVOVElBTExZX0FNQklHVU9VUykgPT0gMCAmJgogICAgICAgICAgICAgICAgKG1zeW0yLmZsYWdzKCkgJiBQT1RFTlRJQUxMWV9BTUJJR1VPVVMpID09IDApIHsKICAgICAgICAgICAgVHlwZSBtdDEgPSB0eXBlcy5tZW1iZXJUeXBlKHNpdGUsIG1zeW0xKTsKICAgICAgICAgICAgVHlwZSBtdDIgPSB0eXBlcy5tZW1iZXJUeXBlKHNpdGUsIG1zeW0yKTsKICAgICAgICAgICAgLy9pZiBib3RoIGdlbmVyaWMgbWV0aG9kcywgYWRqdXN0IHR5cGUgdmFyaWFibGVzCiAgICAgICAgICAgIGlmIChtdDEuaGFzVGFnKEZPUkFMTCkgJiYgbXQyLmhhc1RhZyhGT1JBTEwpICYmCiAgICAgICAgICAgICAgICAgICAgdHlwZXMuaGFzU2FtZUJvdW5kcygoRm9yQWxsKW10MSwgKEZvckFsbCltdDIpKSB7CiAgICAgICAgICAgICAgICBtdDIgPSB0eXBlcy5zdWJzdChtdDIsICgoRm9yQWxsKW10MikudHZhcnMsICgoRm9yQWxsKW10MSkudHZhcnMpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vZXhwYW5kIHZhcmFyZ3MgbWV0aG9kcyBpZiBuZWVkZWQKICAgICAgICAgICAgaW50IG1heExlbmd0aCA9IE1hdGgubWF4KG10MS5nZXRQYXJhbWV0ZXJUeXBlcygpLmxlbmd0aCgpLCBtdDIuZ2V0UGFyYW1ldGVyVHlwZXMoKS5sZW5ndGgoKSk7CiAgICAgICAgICAgIExpc3Q8VHlwZT4gYXJnczEgPSBycy5hZGp1c3RBcmdzKG10MS5nZXRQYXJhbWV0ZXJUeXBlcygpLCBtc3ltMSwgbWF4TGVuZ3RoLCB0cnVlKTsKICAgICAgICAgICAgTGlzdDxUeXBlPiBhcmdzMiA9IHJzLmFkanVzdEFyZ3MobXQyLmdldFBhcmFtZXRlclR5cGVzKCksIG1zeW0yLCBtYXhMZW5ndGgsIHRydWUpOwogICAgICAgICAgICAvL2lmIGFyaXRpZXMgZG9uJ3QgbWF0Y2gsIGV4aXQKICAgICAgICAgICAgaWYgKGFyZ3MxLmxlbmd0aCgpICE9IGFyZ3MyLmxlbmd0aCgpKSByZXR1cm47CiAgICAgICAgICAgIGJvb2xlYW4gcG90ZW50aWFsbHlBbWJpZ3VvdXMgPSBmYWxzZTsKICAgICAgICAgICAgd2hpbGUgKGFyZ3MxLm5vbkVtcHR5KCkgJiYgYXJnczIubm9uRW1wdHkoKSkgewogICAgICAgICAgICAgICAgVHlwZSBzID0gYXJnczEuaGVhZDsKICAgICAgICAgICAgICAgIFR5cGUgdCA9IGFyZ3MyLmhlYWQ7CiAgICAgICAgICAgICAgICBpZiAoIXR5cGVzLmlzU3VidHlwZSh0LCBzKSAmJiAhdHlwZXMuaXNTdWJ0eXBlKHMsIHQpKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVzLmlzRnVuY3Rpb25hbEludGVyZmFjZShzKSAmJiB0eXBlcy5pc0Z1bmN0aW9uYWxJbnRlcmZhY2UodCkgJiYKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVzLmZpbmREZXNjcmlwdG9yVHlwZShzKS5nZXRQYXJhbWV0ZXJUeXBlcygpLmxlbmd0aCgpID4gMCAmJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZXMuZmluZERlc2NyaXB0b3JUeXBlKHMpLmdldFBhcmFtZXRlclR5cGVzKCkubGVuZ3RoKCkgPT0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVzLmZpbmREZXNjcmlwdG9yVHlwZSh0KS5nZXRQYXJhbWV0ZXJUeXBlcygpLmxlbmd0aCgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHBvdGVudGlhbGx5QW1iaWd1b3VzID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBhcmdzMSA9IGFyZ3MxLnRhaWw7CiAgICAgICAgICAgICAgICBhcmdzMiA9IGFyZ3MyLnRhaWw7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHBvdGVudGlhbGx5QW1iaWd1b3VzKSB7CiAgICAgICAgICAgICAgICAvL3dlIGZvdW5kIHR3byBpbmNvbXBhdGlibGUgZnVuY3Rpb25hbCBpbnRlcmZhY2VzIHdpdGggc2FtZSBhcml0eQogICAgICAgICAgICAgICAgLy90aGlzIG1lYW5zIGEgY2FsbCBzaXRlIHBhc3NpbmcgYW4gaW1wbGljaXQgbGFtYmRhIHdvdWxkIGJlIGFtYmlnaXVvdXMKICAgICAgICAgICAgICAgIG1zeW0xLmZsYWdzX2ZpZWxkIHw9IFBPVEVOVElBTExZX0FNQklHVU9VUzsKICAgICAgICAgICAgICAgIG1zeW0yLmZsYWdzX2ZpZWxkIHw9IFBPVEVOVElBTExZX0FNQklHVU9VUzsKICAgICAgICAgICAgICAgIGxvZy53YXJuaW5nKExpbnRDYXRlZ29yeS5PVkVSTE9BRFMsIHBvcywgInBvdGVudGlhbGx5LmFtYmlndW91cy5vdmVybG9hZCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtc3ltMSwgbXN5bTEubG9jYXRpb24oKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1zeW0yLCBtc3ltMi5sb2NhdGlvbigpKTsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICB2b2lkIGNoZWNrQWNjZXNzRnJvbVNlcmlhbGl6YWJsZUVsZW1lbnQoZmluYWwgSkNUcmVlIHRyZWUsIGJvb2xlYW4gaXNMYW1iZGEpIHsKICAgICAgICBpZiAod2Fybk9uQW55QWNjZXNzVG9NZW1iZXJzIHx8CiAgICAgICAgICAgIChsaW50LmlzRW5hYmxlZChMaW50Q2F0ZWdvcnkuU0VSSUFMKSAmJgogICAgICAgICAgICAhbGludC5pc1N1cHByZXNzZWQoTGludENhdGVnb3J5LlNFUklBTCkgJiYKICAgICAgICAgICAgaXNMYW1iZGEpKSB7CiAgICAgICAgICAgIFN5bWJvbCBzeW0gPSBUcmVlSW5mby5zeW1ib2wodHJlZSk7CiAgICAgICAgICAgIGlmICghc3ltLmtpbmQubWF0Y2hlcyhLaW5kU2VsZWN0b3IuVkFMX01USCkpIHsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKHN5bS5raW5kID09IFZBUikgewogICAgICAgICAgICAgICAgaWYgKChzeW0uZmxhZ3MoKSAmIFBBUkFNRVRFUikgIT0gMCB8fAogICAgICAgICAgICAgICAgICAgIHN5bS5pc0xvY2FsKCkgfHwKICAgICAgICAgICAgICAgICAgICBzeW0ubmFtZSA9PSBuYW1lcy5fdGhpcyB8fAogICAgICAgICAgICAgICAgICAgIHN5bS5uYW1lID09IG5hbWVzLl9zdXBlcikgewogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCF0eXBlcy5pc1N1YnR5cGUoc3ltLm93bmVyLnR5cGUsIHN5bXMuc2VyaWFsaXphYmxlVHlwZSkgJiYKICAgICAgICAgICAgICAgIGlzRWZmZWN0aXZlbHlOb25QdWJsaWMoc3ltKSkgewogICAgICAgICAgICAgICAgaWYgKGlzTGFtYmRhKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGJlbG9uZ3NUb1Jlc3RyaWN0ZWRQYWNrYWdlKHN5bSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgbG9nLndhcm5pbmcoTGludENhdGVnb3J5LlNFUklBTCwgdHJlZS5wb3MoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJhY2Nlc3MudG8ubWVtYmVyLmZyb20uc2VyaWFsaXphYmxlLmxhbWJkYSIsIHN5bSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBsb2cud2FybmluZyh0cmVlLnBvcygpLAogICAgICAgICAgICAgICAgICAgICAgICAiYWNjZXNzLnRvLm1lbWJlci5mcm9tLnNlcmlhbGl6YWJsZS5lbGVtZW50Iiwgc3ltKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIGJvb2xlYW4gaXNFZmZlY3RpdmVseU5vblB1YmxpYyhTeW1ib2wgc3ltKSB7CiAgICAgICAgaWYgKHN5bS5wYWNrZ2UoKSA9PSBzeW1zLnJvb3RQYWNrYWdlKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIHdoaWxlIChzeW0ua2luZCAhPSBQQ0spIHsKICAgICAgICAgICAgaWYgKChzeW0uZmxhZ3MoKSAmIFBVQkxJQykgPT0gMCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc3ltID0gc3ltLm93bmVyOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgcHJpdmF0ZSBib29sZWFuIGJlbG9uZ3NUb1Jlc3RyaWN0ZWRQYWNrYWdlKFN5bWJvbCBzeW0pIHsKICAgICAgICBTdHJpbmcgZnVsbE5hbWUgPSBzeW0ucGFja2dlKCkuZnVsbG5hbWUudG9TdHJpbmcoKTsKICAgICAgICByZXR1cm4gZnVsbE5hbWUuc3RhcnRzV2l0aCgiamF2YS4iKSB8fAogICAgICAgICAgICAgICAgZnVsbE5hbWUuc3RhcnRzV2l0aCgiamF2YXguIikgfHwKICAgICAgICAgICAgICAgIGZ1bGxOYW1lLnN0YXJ0c1dpdGgoInN1bi4iKSB8fAogICAgICAgICAgICAgICAgZnVsbE5hbWUuY29udGFpbnMoIi5pbnRlcm5hbC4iKTsKICAgIH0KCiAgICAvKiogUmVwb3J0IGEgY29uZmxpY3QgYmV0d2VlbiBhIHVzZXIgc3ltYm9sIGFuZCBhIHN5bnRoZXRpYyBzeW1ib2wuCiAgICAgKi8KICAgIHByaXZhdGUgdm9pZCBzeW50aGV0aWNFcnJvcihEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBTeW1ib2wgc3ltKSB7CiAgICAgICAgaWYgKCFzeW0udHlwZS5pc0Vycm9uZW91cygpKSB7CiAgICAgICAgICAgIGxvZy5lcnJvcihwb3MsICJzeW50aGV0aWMubmFtZS5jb25mbGljdCIsIHN5bSwgc3ltLmxvY2F0aW9uKCkpOwogICAgICAgIH0KICAgIH0KCiAgICAvKiogQ2hlY2sgdGhhdCBjbGFzcyBjIGRvZXMgbm90IGltcGxlbWVudCBkaXJlY3RseSBvciBpbmRpcmVjdGx5CiAgICAgKiAgdGhlIHNhbWUgcGFyYW1ldGVyaXplZCBpbnRlcmZhY2Ugd2l0aCB0d28gZGlmZmVyZW50IGFyZ3VtZW50IGxpc3RzLgogICAgICogIEBwYXJhbSBwb3MgICAgICAgICAgUG9zaXRpb24gdG8gYmUgdXNlZCBmb3IgZXJyb3IgcmVwb3J0aW5nLgogICAgICogIEBwYXJhbSB0eXBlICAgICAgICAgVGhlIHR5cGUgd2hvc2UgaW50ZXJmYWNlcyBhcmUgY2hlY2tlZC4KICAgICAqLwogICAgdm9pZCBjaGVja0NsYXNzQm91bmRzKERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIFR5cGUgdHlwZSkgewogICAgICAgIGNoZWNrQ2xhc3NCb3VuZHMocG9zLCBuZXcgSGFzaE1hcDxUeXBlU3ltYm9sLFR5cGU+KCksIHR5cGUpOwogICAgfQovL3doZXJlCiAgICAgICAgLyoqIEVudGVyIGFsbCBpbnRlcmZhY2VzIG9mIHR5cGUgYHR5cGUnIGludG8gdGhlIGhhc2ggdGFibGUgYHNlZW5zb2ZhcicKICAgICAgICAgKiAgd2l0aCB0aGVpciBjbGFzcyBzeW1ib2wgYXMga2V5IGFuZCB0aGVpciB0eXBlIGFzIHZhbHVlLiBNYWtlCiAgICAgICAgICogIHN1cmUgbm8gY2xhc3MgaXMgZW50ZXJlZCB3aXRoIHR3byBkaWZmZXJlbnQgdHlwZXMuCiAgICAgICAgICovCiAgICAgICAgdm9pZCBjaGVja0NsYXNzQm91bmRzKERpYWdub3N0aWNQb3NpdGlvbiBwb3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1hcDxUeXBlU3ltYm9sLFR5cGU+IHNlZW5zb2ZhciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVHlwZSB0eXBlKSB7CiAgICAgICAgICAgIGlmICh0eXBlLmlzRXJyb25lb3VzKCkpIHJldHVybjsKICAgICAgICAgICAgZm9yIChMaXN0PFR5cGU+IGwgPSB0eXBlcy5pbnRlcmZhY2VzKHR5cGUpOyBsLm5vbkVtcHR5KCk7IGwgPSBsLnRhaWwpIHsKICAgICAgICAgICAgICAgIFR5cGUgaXQgPSBsLmhlYWQ7CiAgICAgICAgICAgICAgICBUeXBlIG9sZGl0ID0gc2VlbnNvZmFyLnB1dChpdC50c3ltLCBpdCk7CiAgICAgICAgICAgICAgICBpZiAob2xkaXQgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIExpc3Q8VHlwZT4gb2xkcGFyYW1zID0gb2xkaXQuYWxscGFyYW1zKCk7CiAgICAgICAgICAgICAgICAgICAgTGlzdDxUeXBlPiBuZXdwYXJhbXMgPSBpdC5hbGxwYXJhbXMoKTsKICAgICAgICAgICAgICAgICAgICBpZiAoIXR5cGVzLmNvbnRhaW5zVHlwZUVxdWl2YWxlbnQob2xkcGFyYW1zLCBuZXdwYXJhbXMpKQogICAgICAgICAgICAgICAgICAgICAgICBsb2cuZXJyb3IocG9zLCAiY2FudC5pbmhlcml0LmRpZmYuYXJnIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0LnRzeW0sIFR5cGUudG9TdHJpbmcob2xkcGFyYW1zKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFR5cGUudG9TdHJpbmcobmV3cGFyYW1zKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBjaGVja0NsYXNzQm91bmRzKHBvcywgc2VlbnNvZmFyLCBpdCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgVHlwZSBzdCA9IHR5cGVzLnN1cGVydHlwZSh0eXBlKTsKICAgICAgICAgICAgaWYgKHN0ICE9IFR5cGUubm9UeXBlKSBjaGVja0NsYXNzQm91bmRzKHBvcywgc2VlbnNvZmFyLCBzdCk7CiAgICAgICAgfQoKICAgIC8qKiBFbnRlciBpbnRlcmZhY2UgaW50byBpbnRvIHNldC4KICAgICAqICBJZiBpdCBleGlzdGVkIGFscmVhZHksIGlzc3VlIGEgInJlcGVhdGVkIGludGVyZmFjZSIgZXJyb3IuCiAgICAgKi8KICAgIHZvaWQgY2hlY2tOb3RSZXBlYXRlZChEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBUeXBlIGl0LCBTZXQ8VHlwZT4gaXRzKSB7CiAgICAgICAgaWYgKGl0cy5jb250YWlucyhpdCkpCiAgICAgICAgICAgIGxvZy5lcnJvcihwb3MsICJyZXBlYXRlZC5pbnRlcmZhY2UiKTsKICAgICAgICBlbHNlIHsKICAgICAgICAgICAgaXRzLmFkZChpdCk7CiAgICAgICAgfQogICAgfQoKLyogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBDaGVjayBhbm5vdGF0aW9ucwogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgogICAgLyoqCiAgICAgKiBSZWN1cnNpdmVseSB2YWxpZGF0ZSBhbm5vdGF0aW9ucyB2YWx1ZXMKICAgICAqLwogICAgdm9pZCB2YWxpZGF0ZUFubm90YXRpb25UcmVlKEpDVHJlZSB0cmVlKSB7CiAgICAgICAgY2xhc3MgQW5ub3RhdGlvblZhbGlkYXRvciBleHRlbmRzIFRyZWVTY2FubmVyIHsKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0QW5ub3RhdGlvbihKQ0Fubm90YXRpb24gdHJlZSkgewogICAgICAgICAgICAgICAgaWYgKCF0cmVlLnR5cGUuaXNFcnJvbmVvdXMoKSkgewogICAgICAgICAgICAgICAgICAgIHN1cGVyLnZpc2l0QW5ub3RhdGlvbih0cmVlKTsKICAgICAgICAgICAgICAgICAgICB2YWxpZGF0ZUFubm90YXRpb24odHJlZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgdHJlZS5hY2NlcHQobmV3IEFubm90YXRpb25WYWxpZGF0b3IoKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiAge0BsaXRlcmFsCiAgICAgKiAgQW5ub3RhdGlvbiB0eXBlcyBhcmUgcmVzdHJpY3RlZCB0byBwcmltaXRpdmVzLCBTdHJpbmcsIGFuCiAgICAgKiAgZW51bSwgYW4gYW5ub3RhdGlvbiwgQ2xhc3MsIENsYXNzPD8+LCBDbGFzczw/IGV4dGVuZHMKICAgICAqICBBbnl0aGluZz4sIGFycmF5cyBvZiB0aGUgcHJlY2VkaW5nLgogICAgICogIH0KICAgICAqLwogICAgdm9pZCB2YWxpZGF0ZUFubm90YXRpb25UeXBlKEpDVHJlZSByZXN0eXBlKSB7CiAgICAgICAgLy8gcmVzdHlwZSBtYXkgYmUgbnVsbCBpZiBhbiBlcnJvciBvY2N1cnJlZCwgc28gZG9uJ3QgYm90aGVyIHZhbGlkYXRpbmcgaXQKICAgICAgICBpZiAocmVzdHlwZSAhPSBudWxsKSB7CiAgICAgICAgICAgIHZhbGlkYXRlQW5ub3RhdGlvblR5cGUocmVzdHlwZS5wb3MoKSwgcmVzdHlwZS50eXBlKTsKICAgICAgICB9CiAgICB9CgogICAgdm9pZCB2YWxpZGF0ZUFubm90YXRpb25UeXBlKERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIFR5cGUgdHlwZSkgewogICAgICAgIGlmICh0eXBlLmlzUHJpbWl0aXZlKCkpIHJldHVybjsKICAgICAgICBpZiAodHlwZXMuaXNTYW1lVHlwZSh0eXBlLCBzeW1zLnN0cmluZ1R5cGUpKSByZXR1cm47CiAgICAgICAgaWYgKCh0eXBlLnRzeW0uZmxhZ3MoKSAmIEZsYWdzLkVOVU0pICE9IDApIHJldHVybjsKICAgICAgICBpZiAoKHR5cGUudHN5bS5mbGFncygpICYgRmxhZ3MuQU5OT1RBVElPTikgIT0gMCkgcmV0dXJuOwogICAgICAgIGlmICh0eXBlcy5jdmFyTG93ZXJCb3VuZCh0eXBlKS50c3ltID09IHN5bXMuY2xhc3NUeXBlLnRzeW0pIHJldHVybjsKICAgICAgICBpZiAodHlwZXMuaXNBcnJheSh0eXBlKSAmJiAhdHlwZXMuaXNBcnJheSh0eXBlcy5lbGVtdHlwZSh0eXBlKSkpIHsKICAgICAgICAgICAgdmFsaWRhdGVBbm5vdGF0aW9uVHlwZShwb3MsIHR5cGVzLmVsZW10eXBlKHR5cGUpKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICBsb2cuZXJyb3IocG9zLCAiaW52YWxpZC5hbm5vdGF0aW9uLm1lbWJlci50eXBlIik7CiAgICB9CgogICAgLyoqCiAgICAgKiAiSXQgaXMgYWxzbyBhIGNvbXBpbGUtdGltZSBlcnJvciBpZiBhbnkgbWV0aG9kIGRlY2xhcmVkIGluIGFuCiAgICAgKiBhbm5vdGF0aW9uIHR5cGUgaGFzIGEgc2lnbmF0dXJlIHRoYXQgaXMgb3ZlcnJpZGUtZXF1aXZhbGVudCB0bwogICAgICogdGhhdCBvZiBhbnkgcHVibGljIG9yIHByb3RlY3RlZCBtZXRob2QgZGVjbGFyZWQgaW4gY2xhc3MgT2JqZWN0CiAgICAgKiBvciBpbiB0aGUgaW50ZXJmYWNlIGFubm90YXRpb24uQW5ub3RhdGlvbi4iCiAgICAgKgogICAgICogQGpscyA5LjYgQW5ub3RhdGlvbiBUeXBlcwogICAgICovCiAgICB2b2lkIHZhbGlkYXRlQW5ub3RhdGlvbk1ldGhvZChEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBNZXRob2RTeW1ib2wgbSkgewogICAgICAgIGZvciAoVHlwZSBzdXAgPSBzeW1zLmFubm90YXRpb25UeXBlOyBzdXAuaGFzVGFnKENMQVNTKTsgc3VwID0gdHlwZXMuc3VwZXJ0eXBlKHN1cCkpIHsKICAgICAgICAgICAgU2NvcGUgcyA9IHN1cC50c3ltLm1lbWJlcnMoKTsKICAgICAgICAgICAgZm9yIChTeW1ib2wgc3ltIDogcy5nZXRTeW1ib2xzQnlOYW1lKG0ubmFtZSkpIHsKICAgICAgICAgICAgICAgIGlmIChzeW0ua2luZCA9PSBNVEggJiYKICAgICAgICAgICAgICAgICAgICAoc3ltLmZsYWdzKCkgJiAoUFVCTElDIHwgUFJPVEVDVEVEKSkgIT0gMCAmJgogICAgICAgICAgICAgICAgICAgIHR5cGVzLm92ZXJyaWRlRXF1aXZhbGVudChtLnR5cGUsIHN5bS50eXBlKSkKICAgICAgICAgICAgICAgICAgICBsb2cuZXJyb3IocG9zLCAiaW50Zi5hbm5vdGF0aW9uLm1lbWJlci5jbGFzaCIsIHN5bSwgc3VwKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKiogQ2hlY2sgdGhlIGFubm90YXRpb25zIG9mIGEgc3ltYm9sLgogICAgICovCiAgICBwdWJsaWMgdm9pZCB2YWxpZGF0ZUFubm90YXRpb25zKExpc3Q8SkNBbm5vdGF0aW9uPiBhbm5vdGF0aW9ucywgU3ltYm9sIHMpIHsKICAgICAgICBmb3IgKEpDQW5ub3RhdGlvbiBhIDogYW5ub3RhdGlvbnMpCiAgICAgICAgICAgIHZhbGlkYXRlQW5ub3RhdGlvbihhLCBzKTsKICAgIH0KCiAgICAvKiogQ2hlY2sgdGhlIHR5cGUgYW5ub3RhdGlvbnMuCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHZhbGlkYXRlVHlwZUFubm90YXRpb25zKExpc3Q8SkNBbm5vdGF0aW9uPiBhbm5vdGF0aW9ucywgYm9vbGVhbiBpc1R5cGVQYXJhbWV0ZXIpIHsKICAgICAgICBmb3IgKEpDQW5ub3RhdGlvbiBhIDogYW5ub3RhdGlvbnMpCiAgICAgICAgICAgIHZhbGlkYXRlVHlwZUFubm90YXRpb24oYSwgaXNUeXBlUGFyYW1ldGVyKTsKICAgIH0KCiAgICAvKiogQ2hlY2sgYW4gYW5ub3RhdGlvbiBvZiBhIHN5bWJvbC4KICAgICAqLwogICAgcHJpdmF0ZSB2b2lkIHZhbGlkYXRlQW5ub3RhdGlvbihKQ0Fubm90YXRpb24gYSwgU3ltYm9sIHMpIHsKICAgICAgICB2YWxpZGF0ZUFubm90YXRpb25UcmVlKGEpOwoKICAgICAgICBpZiAoYS50eXBlLnRzeW0uaXNBbm5vdGF0aW9uVHlwZSgpICYmICFhbm5vdGF0aW9uQXBwbGljYWJsZShhLCBzKSkKICAgICAgICAgICAgbG9nLmVycm9yKGEucG9zKCksICJhbm5vdGF0aW9uLnR5cGUubm90LmFwcGxpY2FibGUiKTsKCiAgICAgICAgaWYgKGEuYW5ub3RhdGlvblR5cGUudHlwZS50c3ltID09IHN5bXMuZnVuY3Rpb25hbEludGVyZmFjZVR5cGUudHN5bSkgewogICAgICAgICAgICBpZiAocy5raW5kICE9IFRZUCkgewogICAgICAgICAgICAgICAgbG9nLmVycm9yKGEucG9zKCksICJiYWQuZnVuY3Rpb25hbC5pbnRmLmFubm8iKTsKICAgICAgICAgICAgfSBlbHNlIGlmICghcy5pc0ludGVyZmFjZSgpIHx8IChzLmZsYWdzKCkgJiBBTk5PVEFUSU9OKSAhPSAwKSB7CiAgICAgICAgICAgICAgICBsb2cuZXJyb3IoYS5wb3MoKSwgImJhZC5mdW5jdGlvbmFsLmludGYuYW5uby4xIiwgZGlhZ3MuZnJhZ21lbnQoIm5vdC5hLmZ1bmN0aW9uYWwuaW50ZiIsIHMpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2YWxpZGF0ZVR5cGVBbm5vdGF0aW9uKEpDQW5ub3RhdGlvbiBhLCBib29sZWFuIGlzVHlwZVBhcmFtZXRlcikgewogICAgICAgIEFzc2VydC5jaGVja05vbk51bGwoYS50eXBlKTsKICAgICAgICB2YWxpZGF0ZUFubm90YXRpb25UcmVlKGEpOwoKICAgICAgICBpZiAoYS5oYXNUYWcoVFlQRV9BTk5PVEFUSU9OKSAmJgogICAgICAgICAgICAgICAgIWEuYW5ub3RhdGlvblR5cGUudHlwZS5pc0Vycm9uZW91cygpICYmCiAgICAgICAgICAgICAgICAhaXNUeXBlQW5ub3RhdGlvbihhLCBpc1R5cGVQYXJhbWV0ZXIpKSB7CiAgICAgICAgICAgIGxvZy5lcnJvcihhLnBvcygpLCBFcnJvcnMuQW5ub3RhdGlvblR5cGVOb3RBcHBsaWNhYmxlVG9UeXBlKGEudHlwZSkpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFZhbGlkYXRlIHRoZSBwcm9wb3NlZCBjb250YWluZXIgJ3JlcGVhdGFibGUnIG9uIHRoZQogICAgICogYW5ub3RhdGlvbiB0eXBlIHN5bWJvbCAncycuIFJlcG9ydCBlcnJvcnMgYXQgcG9zaXRpb24KICAgICAqICdwb3MnLgogICAgICoKICAgICAqIEBwYXJhbSBzIFRoZSAoYW5ub3RhdGlvbil0eXBlIGRlY2xhcmF0aW9uIGFubm90YXRlZCB3aXRoIGEgQFJlcGVhdGFibGUKICAgICAqIEBwYXJhbSByZXBlYXRhYmxlIHRoZSBAUmVwZWF0YWJsZSBvbiAncycKICAgICAqIEBwYXJhbSBwb3Mgd2hlcmUgdG8gcmVwb3J0IGVycm9ycwogICAgICovCiAgICBwdWJsaWMgdm9pZCB2YWxpZGF0ZVJlcGVhdGFibGUoVHlwZVN5bWJvbCBzLCBBdHRyaWJ1dGUuQ29tcG91bmQgcmVwZWF0YWJsZSwgRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcykgewogICAgICAgIEFzc2VydC5jaGVjayh0eXBlcy5pc1NhbWVUeXBlKHJlcGVhdGFibGUudHlwZSwgc3ltcy5yZXBlYXRhYmxlVHlwZSkpOwoKICAgICAgICBUeXBlIHQgPSBudWxsOwogICAgICAgIExpc3Q8UGFpcjxNZXRob2RTeW1ib2wsQXR0cmlidXRlPj4gbCA9IHJlcGVhdGFibGUudmFsdWVzOwogICAgICAgIGlmICghbC5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgQXNzZXJ0LmNoZWNrKGwuaGVhZC5mc3QubmFtZSA9PSBuYW1lcy52YWx1ZSk7CiAgICAgICAgICAgIHQgPSAoKEF0dHJpYnV0ZS5DbGFzcylsLmhlYWQuc25kKS5nZXRWYWx1ZSgpOwogICAgICAgIH0KCiAgICAgICAgaWYgKHQgPT0gbnVsbCkgewogICAgICAgICAgICAvLyBlcnJvcnMgc2hvdWxkIGFscmVhZHkgaGF2ZSBiZWVuIHJlcG9ydGVkIGR1cmluZyBBbm5vdGF0ZQogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICB2YWxpZGF0ZVZhbHVlKHQudHN5bSwgcywgcG9zKTsKICAgICAgICB2YWxpZGF0ZVJldGVudGlvbih0LnRzeW0sIHMsIHBvcyk7CiAgICAgICAgdmFsaWRhdGVEb2N1bWVudGVkKHQudHN5bSwgcywgcG9zKTsKICAgICAgICB2YWxpZGF0ZUluaGVyaXRlZCh0LnRzeW0sIHMsIHBvcyk7CiAgICAgICAgdmFsaWRhdGVUYXJnZXQodC50c3ltLCBzLCBwb3MpOwogICAgICAgIHZhbGlkYXRlRGVmYXVsdCh0LnRzeW0sIHBvcyk7CiAgICB9CgogICAgcHJpdmF0ZSB2b2lkIHZhbGlkYXRlVmFsdWUoVHlwZVN5bWJvbCBjb250YWluZXIsIFR5cGVTeW1ib2wgY29udGFpbmVkLCBEaWFnbm9zdGljUG9zaXRpb24gcG9zKSB7CiAgICAgICAgU3ltYm9sIHN5bSA9IGNvbnRhaW5lci5tZW1iZXJzKCkuZmluZEZpcnN0KG5hbWVzLnZhbHVlKTsKICAgICAgICBpZiAoc3ltICE9IG51bGwgJiYgc3ltLmtpbmQgPT0gTVRIKSB7CiAgICAgICAgICAgIE1ldGhvZFN5bWJvbCBtID0gKE1ldGhvZFN5bWJvbCkgc3ltOwogICAgICAgICAgICBUeXBlIHJldCA9IG0uZ2V0UmV0dXJuVHlwZSgpOwogICAgICAgICAgICBpZiAoIShyZXQuaGFzVGFnKEFSUkFZKSAmJiB0eXBlcy5pc1NhbWVUeXBlKCgoQXJyYXlUeXBlKXJldCkuZWxlbXR5cGUsIGNvbnRhaW5lZC50eXBlKSkpIHsKICAgICAgICAgICAgICAgIGxvZy5lcnJvcihwb3MsICJpbnZhbGlkLnJlcGVhdGFibGUuYW5ub3RhdGlvbi52YWx1ZS5yZXR1cm4iLAogICAgICAgICAgICAgICAgICAgICAgICBjb250YWluZXIsIHJldCwgdHlwZXMubWFrZUFycmF5VHlwZShjb250YWluZWQudHlwZSkpOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgbG9nLmVycm9yKHBvcywgImludmFsaWQucmVwZWF0YWJsZS5hbm5vdGF0aW9uLm5vLnZhbHVlIiwgY29udGFpbmVyKTsKICAgICAgICB9CiAgICB9CgogICAgcHJpdmF0ZSB2b2lkIHZhbGlkYXRlUmV0ZW50aW9uKFR5cGVTeW1ib2wgY29udGFpbmVyLCBUeXBlU3ltYm9sIGNvbnRhaW5lZCwgRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcykgewogICAgICAgIEF0dHJpYnV0ZS5SZXRlbnRpb25Qb2xpY3kgY29udGFpbmVyUmV0ZW50aW9uID0gdHlwZXMuZ2V0UmV0ZW50aW9uKGNvbnRhaW5lcik7CiAgICAgICAgQXR0cmlidXRlLlJldGVudGlvblBvbGljeSBjb250YWluZWRSZXRlbnRpb24gPSB0eXBlcy5nZXRSZXRlbnRpb24oY29udGFpbmVkKTsKCiAgICAgICAgYm9vbGVhbiBlcnJvciA9IGZhbHNlOwogICAgICAgIHN3aXRjaCAoY29udGFpbmVkUmV0ZW50aW9uKSB7CiAgICAgICAgY2FzZSBSVU5USU1FOgogICAgICAgICAgICBpZiAoY29udGFpbmVyUmV0ZW50aW9uICE9IEF0dHJpYnV0ZS5SZXRlbnRpb25Qb2xpY3kuUlVOVElNRSkgewogICAgICAgICAgICAgICAgZXJyb3IgPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgQ0xBU1M6CiAgICAgICAgICAgIGlmIChjb250YWluZXJSZXRlbnRpb24gPT0gQXR0cmlidXRlLlJldGVudGlvblBvbGljeS5TT1VSQ0UpICB7CiAgICAgICAgICAgICAgICBlcnJvciA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKGVycm9yICkgewogICAgICAgICAgICBsb2cuZXJyb3IocG9zLCAiaW52YWxpZC5yZXBlYXRhYmxlLmFubm90YXRpb24ucmV0ZW50aW9uIiwKICAgICAgICAgICAgICAgICAgICAgIGNvbnRhaW5lciwgY29udGFpbmVyUmV0ZW50aW9uLAogICAgICAgICAgICAgICAgICAgICAgY29udGFpbmVkLCBjb250YWluZWRSZXRlbnRpb24pOwogICAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIHZvaWQgdmFsaWRhdGVEb2N1bWVudGVkKFN5bWJvbCBjb250YWluZXIsIFN5bWJvbCBjb250YWluZWQsIERpYWdub3N0aWNQb3NpdGlvbiBwb3MpIHsKICAgICAgICBpZiAoY29udGFpbmVkLmF0dHJpYnV0ZShzeW1zLmRvY3VtZW50ZWRUeXBlLnRzeW0pICE9IG51bGwpIHsKICAgICAgICAgICAgaWYgKGNvbnRhaW5lci5hdHRyaWJ1dGUoc3ltcy5kb2N1bWVudGVkVHlwZS50c3ltKSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICBsb2cuZXJyb3IocG9zLCAiaW52YWxpZC5yZXBlYXRhYmxlLmFubm90YXRpb24ubm90LmRvY3VtZW50ZWQiLCBjb250YWluZXIsIGNvbnRhaW5lZCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgcHJpdmF0ZSB2b2lkIHZhbGlkYXRlSW5oZXJpdGVkKFN5bWJvbCBjb250YWluZXIsIFN5bWJvbCBjb250YWluZWQsIERpYWdub3N0aWNQb3NpdGlvbiBwb3MpIHsKICAgICAgICBpZiAoY29udGFpbmVkLmF0dHJpYnV0ZShzeW1zLmluaGVyaXRlZFR5cGUudHN5bSkgIT0gbnVsbCkgewogICAgICAgICAgICBpZiAoY29udGFpbmVyLmF0dHJpYnV0ZShzeW1zLmluaGVyaXRlZFR5cGUudHN5bSkgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgbG9nLmVycm9yKHBvcywgImludmFsaWQucmVwZWF0YWJsZS5hbm5vdGF0aW9uLm5vdC5pbmhlcml0ZWQiLCBjb250YWluZXIsIGNvbnRhaW5lZCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgcHJpdmF0ZSB2b2lkIHZhbGlkYXRlVGFyZ2V0KFR5cGVTeW1ib2wgY29udGFpbmVyLCBUeXBlU3ltYm9sIGNvbnRhaW5lZCwgRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcykgewogICAgICAgIC8vIFRoZSBzZXQgb2YgdGFyZ2V0cyB0aGUgY29udGFpbmVyIGlzIGFwcGxpY2FibGUgdG8gbXVzdCBiZSBhIHN1YnNldAogICAgICAgIC8vICh3aXRoIHJlc3BlY3QgdG8gYW5ub3RhdGlvbiB0YXJnZXQgc2VtYW50aWNzKSBvZiB0aGUgc2V0IG9mIHRhcmdldHMKICAgICAgICAvLyB0aGUgY29udGFpbmVkIGlzIGFwcGxpY2FibGUgdG8uIFRoZSB0YXJnZXQgc2V0cyBtYXkgYmUgaW1wbGljaXQgb3IKICAgICAgICAvLyBleHBsaWNpdC4KCiAgICAgICAgU2V0PE5hbWU+IGNvbnRhaW5lclRhcmdldHM7CiAgICAgICAgQXR0cmlidXRlLkFycmF5IGNvbnRhaW5lclRhcmdldCA9IGdldEF0dHJpYnV0ZVRhcmdldEF0dHJpYnV0ZShjb250YWluZXIpOwogICAgICAgIGlmIChjb250YWluZXJUYXJnZXQgPT0gbnVsbCkgewogICAgICAgICAgICBjb250YWluZXJUYXJnZXRzID0gZ2V0RGVmYXVsdFRhcmdldFNldCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGNvbnRhaW5lclRhcmdldHMgPSBuZXcgSGFzaFNldDw+KCk7CiAgICAgICAgICAgIGZvciAoQXR0cmlidXRlIGFwcCA6IGNvbnRhaW5lclRhcmdldC52YWx1ZXMpIHsKICAgICAgICAgICAgICAgIGlmICghKGFwcCBpbnN0YW5jZW9mIEF0dHJpYnV0ZS5FbnVtKSkgewogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOyAvLyByZWNvdmVyeQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgQXR0cmlidXRlLkVudW0gZSA9IChBdHRyaWJ1dGUuRW51bSlhcHA7CiAgICAgICAgICAgICAgICBjb250YWluZXJUYXJnZXRzLmFkZChlLnZhbHVlLm5hbWUpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBTZXQ8TmFtZT4gY29udGFpbmVkVGFyZ2V0czsKICAgICAgICBBdHRyaWJ1dGUuQXJyYXkgY29udGFpbmVkVGFyZ2V0ID0gZ2V0QXR0cmlidXRlVGFyZ2V0QXR0cmlidXRlKGNvbnRhaW5lZCk7CiAgICAgICAgaWYgKGNvbnRhaW5lZFRhcmdldCA9PSBudWxsKSB7CiAgICAgICAgICAgIGNvbnRhaW5lZFRhcmdldHMgPSBnZXREZWZhdWx0VGFyZ2V0U2V0KCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgY29udGFpbmVkVGFyZ2V0cyA9IG5ldyBIYXNoU2V0PD4oKTsKICAgICAgICAgICAgZm9yIChBdHRyaWJ1dGUgYXBwIDogY29udGFpbmVkVGFyZ2V0LnZhbHVlcykgewogICAgICAgICAgICAgICAgaWYgKCEoYXBwIGluc3RhbmNlb2YgQXR0cmlidXRlLkVudW0pKSB7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7IC8vIHJlY292ZXJ5CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBBdHRyaWJ1dGUuRW51bSBlID0gKEF0dHJpYnV0ZS5FbnVtKWFwcDsKICAgICAgICAgICAgICAgIGNvbnRhaW5lZFRhcmdldHMuYWRkKGUudmFsdWUubmFtZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICghaXNUYXJnZXRTdWJzZXRPZihjb250YWluZXJUYXJnZXRzLCBjb250YWluZWRUYXJnZXRzKSkgewogICAgICAgICAgICBsb2cuZXJyb3IocG9zLCAiaW52YWxpZC5yZXBlYXRhYmxlLmFubm90YXRpb24uaW5jb21wYXRpYmxlLnRhcmdldCIsIGNvbnRhaW5lciwgY29udGFpbmVkKTsKICAgICAgICB9CiAgICB9CgogICAgLyogZ2V0IGEgc2V0IG9mIG5hbWVzIGZvciB0aGUgZGVmYXVsdCB0YXJnZXQgKi8KICAgIHByaXZhdGUgU2V0PE5hbWU+IGdldERlZmF1bHRUYXJnZXRTZXQoKSB7CiAgICAgICAgaWYgKGRlZmF1bHRUYXJnZXRzID09IG51bGwpIHsKICAgICAgICAgICAgU2V0PE5hbWU+IHRhcmdldHMgPSBuZXcgSGFzaFNldDw+KCk7CiAgICAgICAgICAgIHRhcmdldHMuYWRkKG5hbWVzLkFOTk9UQVRJT05fVFlQRSk7CiAgICAgICAgICAgIHRhcmdldHMuYWRkKG5hbWVzLkNPTlNUUlVDVE9SKTsKICAgICAgICAgICAgdGFyZ2V0cy5hZGQobmFtZXMuRklFTEQpOwogICAgICAgICAgICB0YXJnZXRzLmFkZChuYW1lcy5MT0NBTF9WQVJJQUJMRSk7CiAgICAgICAgICAgIHRhcmdldHMuYWRkKG5hbWVzLk1FVEhPRCk7CiAgICAgICAgICAgIHRhcmdldHMuYWRkKG5hbWVzLlBBQ0tBR0UpOwogICAgICAgICAgICB0YXJnZXRzLmFkZChuYW1lcy5QQVJBTUVURVIpOwogICAgICAgICAgICB0YXJnZXRzLmFkZChuYW1lcy5UWVBFKTsKCiAgICAgICAgICAgIGRlZmF1bHRUYXJnZXRzID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZVNldCh0YXJnZXRzKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBkZWZhdWx0VGFyZ2V0czsKICAgIH0KICAgIHByaXZhdGUgU2V0PE5hbWU+IGRlZmF1bHRUYXJnZXRzOwoKCiAgICAvKiogQ2hlY2tzIHRoYXQgcyBpcyBhIHN1YnNldCBvZiB0LCB3aXRoIHJlc3BlY3QgdG8gRWxlbWVudFR5cGUKICAgICAqIHNlbWFudGljcywgc3BlY2lmaWNhbGx5IHtBTk5PVEFUSU9OX1RZUEV9IGlzIGEgc3Vic2V0IG9mIHtUWVBFfSwKICAgICAqIGFuZCB7VFlQRV9VU0V9IGNvdmVycyB0aGUgc2V0IHtBTk5PVEFUSU9OX1RZUEUsIFRZUEUsIFRZUEVfVVNFLAogICAgICogVFlQRV9QQVJBTUVURVJ9LgogICAgICovCiAgICBwcml2YXRlIGJvb2xlYW4gaXNUYXJnZXRTdWJzZXRPZihTZXQ8TmFtZT4gcywgU2V0PE5hbWU+IHQpIHsKICAgICAgICAvLyBDaGVjayB0aGF0IGFsbCBlbGVtZW50cyBpbiBzIGFyZSBwcmVzZW50IGluIHQKICAgICAgICBmb3IgKE5hbWUgbjIgOiBzKSB7CiAgICAgICAgICAgIGJvb2xlYW4gY3VycmVudEVsZW1lbnRPayA9IGZhbHNlOwogICAgICAgICAgICBmb3IgKE5hbWUgbjEgOiB0KSB7CiAgICAgICAgICAgICAgICBpZiAobjEgPT0gbjIpIHsKICAgICAgICAgICAgICAgICAgICBjdXJyZW50RWxlbWVudE9rID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAobjEgPT0gbmFtZXMuVFlQRSAmJiBuMiA9PSBuYW1lcy5BTk5PVEFUSU9OX1RZUEUpIHsKICAgICAgICAgICAgICAgICAgICBjdXJyZW50RWxlbWVudE9rID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAobjEgPT0gbmFtZXMuVFlQRV9VU0UgJiYKICAgICAgICAgICAgICAgICAgICAgICAgKG4yID09IG5hbWVzLlRZUEUgfHwKICAgICAgICAgICAgICAgICAgICAgICAgIG4yID09IG5hbWVzLkFOTk9UQVRJT05fVFlQRSB8fAogICAgICAgICAgICAgICAgICAgICAgICAgbjIgPT0gbmFtZXMuVFlQRV9QQVJBTUVURVIpKSB7CiAgICAgICAgICAgICAgICAgICAgY3VycmVudEVsZW1lbnRPayA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCFjdXJyZW50RWxlbWVudE9rKQogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBwcml2YXRlIHZvaWQgdmFsaWRhdGVEZWZhdWx0KFN5bWJvbCBjb250YWluZXIsIERpYWdub3N0aWNQb3NpdGlvbiBwb3MpIHsKICAgICAgICAvLyB2YWxpZGF0ZSB0aGF0IGFsbCBvdGhlciBlbGVtZW50cyBvZiBjb250YWluaW5nIHR5cGUgaGFzIGRlZmF1bHRzCiAgICAgICAgU2NvcGUgc2NvcGUgPSBjb250YWluZXIubWVtYmVycygpOwogICAgICAgIGZvcihTeW1ib2wgZWxtIDogc2NvcGUuZ2V0U3ltYm9scygpKSB7CiAgICAgICAgICAgIGlmIChlbG0ubmFtZSAhPSBuYW1lcy52YWx1ZSAmJgogICAgICAgICAgICAgICAgZWxtLmtpbmQgPT0gTVRIICYmCiAgICAgICAgICAgICAgICAoKE1ldGhvZFN5bWJvbCllbG0pLmRlZmF1bHRWYWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICBsb2cuZXJyb3IocG9zLAogICAgICAgICAgICAgICAgICAgICAgICAgICJpbnZhbGlkLnJlcGVhdGFibGUuYW5ub3RhdGlvbi5lbGVtLm5vbmRlZmF1bHQiLAogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRhaW5lciwKICAgICAgICAgICAgICAgICAgICAgICAgICBlbG0pOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKiBJcyBzIGEgbWV0aG9kIHN5bWJvbCB0aGF0IG92ZXJyaWRlcyBhIG1ldGhvZCBpbiBhIHN1cGVyY2xhc3M/ICovCiAgICBib29sZWFuIGlzT3ZlcnJpZGVyKFN5bWJvbCBzKSB7CiAgICAgICAgaWYgKHMua2luZCAhPSBNVEggfHwgcy5pc1N0YXRpYygpKQogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgTWV0aG9kU3ltYm9sIG0gPSAoTWV0aG9kU3ltYm9sKXM7CiAgICAgICAgVHlwZVN5bWJvbCBvd25lciA9IChUeXBlU3ltYm9sKW0ub3duZXI7CiAgICAgICAgZm9yIChUeXBlIHN1cCA6IHR5cGVzLmNsb3N1cmUob3duZXIudHlwZSkpIHsKICAgICAgICAgICAgaWYgKHN1cCA9PSBvd25lci50eXBlKQogICAgICAgICAgICAgICAgY29udGludWU7IC8vIHNraXAgInRoaXMiCiAgICAgICAgICAgIFNjb3BlIHNjb3BlID0gc3VwLnRzeW0ubWVtYmVycygpOwogICAgICAgICAgICBmb3IgKFN5bWJvbCBzeW0gOiBzY29wZS5nZXRTeW1ib2xzQnlOYW1lKG0ubmFtZSkpIHsKICAgICAgICAgICAgICAgIGlmICghc3ltLmlzU3RhdGljKCkgJiYgbS5vdmVycmlkZXMoc3ltLCBvd25lciwgdHlwZXMsIHRydWUpKQogICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICAvKiogSXMgdGhlIGFubm90YXRpb24gYXBwbGljYWJsZSB0byB0eXBlcz8gKi8KICAgIHByb3RlY3RlZCBib29sZWFuIGlzVHlwZUFubm90YXRpb24oSkNBbm5vdGF0aW9uIGEsIGJvb2xlYW4gaXNUeXBlUGFyYW1ldGVyKSB7CiAgICAgICAgTGlzdDxBdHRyaWJ1dGU+IHRhcmdldHMgPSB0eXBlQW5ub3RhdGlvbnMuYW5ub3RhdGlvblRhcmdldHMoYS5hbm5vdGF0aW9uVHlwZS50eXBlLnRzeW0pOwogICAgICAgIHJldHVybiAodGFyZ2V0cyA9PSBudWxsKSA/CiAgICAgICAgICAgICAgICBmYWxzZSA6CiAgICAgICAgICAgICAgICB0YXJnZXRzLnN0cmVhbSgpCiAgICAgICAgICAgICAgICAgICAgICAgIC5hbnlNYXRjaChhdHRyIC0+IGlzVHlwZUFubm90YXRpb24oYXR0ciwgaXNUeXBlUGFyYW1ldGVyKSk7CiAgICB9CiAgICAvL3doZXJlCiAgICAgICAgYm9vbGVhbiBpc1R5cGVBbm5vdGF0aW9uKEF0dHJpYnV0ZSBhLCBib29sZWFuIGlzVHlwZVBhcmFtZXRlcikgewogICAgICAgICAgICBBdHRyaWJ1dGUuRW51bSBlID0gKEF0dHJpYnV0ZS5FbnVtKWE7CiAgICAgICAgICAgIHJldHVybiAoZS52YWx1ZS5uYW1lID09IG5hbWVzLlRZUEVfVVNFIHx8CiAgICAgICAgICAgICAgICAgICAgKGlzVHlwZVBhcmFtZXRlciAmJiBlLnZhbHVlLm5hbWUgPT0gbmFtZXMuVFlQRV9QQVJBTUVURVIpKTsKICAgICAgICB9CgogICAgLyoqIElzIHRoZSBhbm5vdGF0aW9uIGFwcGxpY2FibGUgdG8gdGhlIHN5bWJvbD8gKi8KICAgIGJvb2xlYW4gYW5ub3RhdGlvbkFwcGxpY2FibGUoSkNBbm5vdGF0aW9uIGEsIFN5bWJvbCBzKSB7CiAgICAgICAgQXR0cmlidXRlLkFycmF5IGFyciA9IGdldEF0dHJpYnV0ZVRhcmdldEF0dHJpYnV0ZShhLmFubm90YXRpb25UeXBlLnR5cGUudHN5bSk7CiAgICAgICAgTmFtZVtdIHRhcmdldHM7CgogICAgICAgIGlmIChhcnIgPT0gbnVsbCkgewogICAgICAgICAgICB0YXJnZXRzID0gZGVmYXVsdFRhcmdldE1ldGFJbmZvKGEsIHMpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8vIFRPRE86IGNhbiB3ZSBvcHRpbWl6ZSB0aGlzPwogICAgICAgICAgICB0YXJnZXRzID0gbmV3IE5hbWVbYXJyLnZhbHVlcy5sZW5ndGhdOwogICAgICAgICAgICBmb3IgKGludCBpPTA7IGk8YXJyLnZhbHVlcy5sZW5ndGg7ICsraSkgewogICAgICAgICAgICAgICAgQXR0cmlidXRlIGFwcCA9IGFyci52YWx1ZXNbaV07CiAgICAgICAgICAgICAgICBpZiAoIShhcHAgaW5zdGFuY2VvZiBBdHRyaWJ1dGUuRW51bSkpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsgLy8gcmVjb3ZlcnkKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIEF0dHJpYnV0ZS5FbnVtIGUgPSAoQXR0cmlidXRlLkVudW0pIGFwcDsKICAgICAgICAgICAgICAgIHRhcmdldHNbaV0gPSBlLnZhbHVlLm5hbWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZm9yIChOYW1lIHRhcmdldCA6IHRhcmdldHMpIHsKICAgICAgICAgICAgaWYgKHRhcmdldCA9PSBuYW1lcy5UWVBFKSB7CiAgICAgICAgICAgICAgICBpZiAocy5raW5kID09IFRZUCkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfSBlbHNlIGlmICh0YXJnZXQgPT0gbmFtZXMuRklFTEQpIHsKICAgICAgICAgICAgICAgIGlmIChzLmtpbmQgPT0gVkFSICYmIHMub3duZXIua2luZCAhPSBNVEgpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0gZWxzZSBpZiAodGFyZ2V0ID09IG5hbWVzLk1FVEhPRCkgewogICAgICAgICAgICAgICAgaWYgKHMua2luZCA9PSBNVEggJiYgIXMuaXNDb25zdHJ1Y3RvcigpKQogICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9IGVsc2UgaWYgKHRhcmdldCA9PSBuYW1lcy5QQVJBTUVURVIpIHsKICAgICAgICAgICAgICAgIGlmIChzLmtpbmQgPT0gVkFSICYmIHMub3duZXIua2luZCA9PSBNVEggJiYKICAgICAgICAgICAgICAgICAgICAgIChzLmZsYWdzKCkgJiBQQVJBTUVURVIpICE9IDApIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIGlmICh0YXJnZXQgPT0gbmFtZXMuQ09OU1RSVUNUT1IpIHsKICAgICAgICAgICAgICAgIGlmIChzLmtpbmQgPT0gTVRIICYmIHMuaXNDb25zdHJ1Y3RvcigpKQogICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9IGVsc2UgaWYgKHRhcmdldCA9PSBuYW1lcy5MT0NBTF9WQVJJQUJMRSkgewogICAgICAgICAgICAgICAgaWYgKHMua2luZCA9PSBWQVIgJiYgcy5vd25lci5raW5kID09IE1USCAmJgogICAgICAgICAgICAgICAgICAgICAgKHMuZmxhZ3MoKSAmIFBBUkFNRVRFUikgPT0gMCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgaWYgKHRhcmdldCA9PSBuYW1lcy5BTk5PVEFUSU9OX1RZUEUpIHsKICAgICAgICAgICAgICAgIGlmIChzLmtpbmQgPT0gVFlQICYmIChzLmZsYWdzKCkgJiBBTk5PVEFUSU9OKSAhPSAwKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSBpZiAodGFyZ2V0ID09IG5hbWVzLlBBQ0tBR0UpIHsKICAgICAgICAgICAgICAgIGlmIChzLmtpbmQgPT0gUENLKQogICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9IGVsc2UgaWYgKHRhcmdldCA9PSBuYW1lcy5UWVBFX1VTRSkgewogICAgICAgICAgICAgICAgaWYgKHMua2luZCA9PSBUWVAgfHwgcy5raW5kID09IFZBUiB8fAogICAgICAgICAgICAgICAgICAgICAgICAocy5raW5kID09IE1USCAmJiAhcy5pc0NvbnN0cnVjdG9yKCkgJiYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAhcy50eXBlLmdldFJldHVyblR5cGUoKS5oYXNUYWcoVk9JRCkpIHx8CiAgICAgICAgICAgICAgICAgICAgICAgIChzLmtpbmQgPT0gTVRIICYmIHMuaXNDb25zdHJ1Y3RvcigpKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgaWYgKHRhcmdldCA9PSBuYW1lcy5UWVBFX1BBUkFNRVRFUikgewogICAgICAgICAgICAgICAgaWYgKHMua2luZCA9PSBUWVAgJiYgcy50eXBlLmhhc1RhZyhUWVBFVkFSKSkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfSBlbHNlCiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsgLy8gVW5rbm93biBFbGVtZW50VHlwZS4gVGhpcyBzaG91bGQgYmUgYW4gZXJyb3IgYXQgZGVjbGFyYXRpb24gc2l0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBhc3N1bWUgYXBwbGljYWJsZS4KICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKCiAgICBBdHRyaWJ1dGUuQXJyYXkgZ2V0QXR0cmlidXRlVGFyZ2V0QXR0cmlidXRlKFR5cGVTeW1ib2wgcykgewogICAgICAgIEF0dHJpYnV0ZS5Db21wb3VuZCBhdFRhcmdldCA9IHMuZ2V0QW5ub3RhdGlvblR5cGVNZXRhZGF0YSgpLmdldFRhcmdldCgpOwogICAgICAgIGlmIChhdFRhcmdldCA9PSBudWxsKSByZXR1cm4gbnVsbDsgLy8gb2ssIGlzIGFwcGxpY2FibGUKICAgICAgICBBdHRyaWJ1dGUgYXRWYWx1ZSA9IGF0VGFyZ2V0Lm1lbWJlcihuYW1lcy52YWx1ZSk7CiAgICAgICAgaWYgKCEoYXRWYWx1ZSBpbnN0YW5jZW9mIEF0dHJpYnV0ZS5BcnJheSkpIHJldHVybiBudWxsOyAvLyBlcnJvciByZWNvdmVyeQogICAgICAgIHJldHVybiAoQXR0cmlidXRlLkFycmF5KSBhdFZhbHVlOwogICAgfQoKICAgIHByaXZhdGUgZmluYWwgTmFtZVtdIGRmbHRUYXJnZXRNZXRhOwogICAgcHJpdmF0ZSBOYW1lW10gZGVmYXVsdFRhcmdldE1ldGFJbmZvKEpDQW5ub3RhdGlvbiBhLCBTeW1ib2wgcykgewogICAgICAgIHJldHVybiBkZmx0VGFyZ2V0TWV0YTsKICAgIH0KCiAgICAvKiogQ2hlY2sgYW4gYW5ub3RhdGlvbiB2YWx1ZS4KICAgICAqCiAgICAgKiBAcGFyYW0gYSBUaGUgYW5ub3RhdGlvbiB0cmVlIHRvIGNoZWNrCiAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhpcyBhbm5vdGF0aW9uIHRyZWUgaXMgdmFsaWQsIG90aGVyd2lzZSBmYWxzZQogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiB2YWxpZGF0ZUFubm90YXRpb25EZWZlckVycm9ycyhKQ0Fubm90YXRpb24gYSkgewogICAgICAgIGJvb2xlYW4gcmVzID0gZmFsc2U7CiAgICAgICAgZmluYWwgTG9nLkRpYWdub3N0aWNIYW5kbGVyIGRpYWdIYW5kbGVyID0gbmV3IExvZy5EaXNjYXJkRGlhZ25vc3RpY0hhbmRsZXIobG9nKTsKICAgICAgICB0cnkgewogICAgICAgICAgICByZXMgPSB2YWxpZGF0ZUFubm90YXRpb24oYSk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgbG9nLnBvcERpYWdub3N0aWNIYW5kbGVyKGRpYWdIYW5kbGVyKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlczsKICAgIH0KCiAgICBwcml2YXRlIGJvb2xlYW4gdmFsaWRhdGVBbm5vdGF0aW9uKEpDQW5ub3RhdGlvbiBhKSB7CiAgICAgICAgYm9vbGVhbiBpc1ZhbGlkID0gdHJ1ZTsKICAgICAgICBBbm5vdGF0aW9uVHlwZU1ldGFkYXRhIG1ldGFkYXRhID0gYS5hbm5vdGF0aW9uVHlwZS50eXBlLnRzeW0uZ2V0QW5ub3RhdGlvblR5cGVNZXRhZGF0YSgpOwoKICAgICAgICAvLyBjb2xsZWN0IGFuIGludmVudG9yeSBvZiB0aGUgYW5ub3RhdGlvbiBlbGVtZW50cwogICAgICAgIFNldDxNZXRob2RTeW1ib2w+IGVsZW1lbnRzID0gbWV0YWRhdGEuZ2V0QW5ub3RhdGlvbkVsZW1lbnRzKCk7CgogICAgICAgIC8vIHJlbW92ZSB0aGUgb25lcyB0aGF0IGFyZSBhc3NpZ25lZCB2YWx1ZXMKICAgICAgICBmb3IgKEpDVHJlZSBhcmcgOiBhLmFyZ3MpIHsKICAgICAgICAgICAgaWYgKCFhcmcuaGFzVGFnKEFTU0lHTikpIGNvbnRpbnVlOyAvLyByZWNvdmVyeQogICAgICAgICAgICBKQ0Fzc2lnbiBhc3NpZ24gPSAoSkNBc3NpZ24pYXJnOwogICAgICAgICAgICBTeW1ib2wgbSA9IFRyZWVJbmZvLnN5bWJvbChhc3NpZ24ubGhzKTsKICAgICAgICAgICAgaWYgKG0gPT0gbnVsbCB8fCBtLnR5cGUuaXNFcnJvbmVvdXMoKSkgY29udGludWU7CiAgICAgICAgICAgIGlmICghZWxlbWVudHMucmVtb3ZlKG0pKSB7CiAgICAgICAgICAgICAgICBpc1ZhbGlkID0gZmFsc2U7CiAgICAgICAgICAgICAgICBsb2cuZXJyb3IoYXNzaWduLmxocy5wb3MoKSwgImR1cGxpY2F0ZS5hbm5vdGF0aW9uLm1lbWJlci52YWx1ZSIsCiAgICAgICAgICAgICAgICAgICAgICAgIG0ubmFtZSwgYS50eXBlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gYWxsIHRoZSByZW1haW5pbmcgb25lcyBiZXR0ZXIgaGF2ZSBkZWZhdWx0IHZhbHVlcwogICAgICAgIExpc3Q8TmFtZT4gbWlzc2luZ0RlZmF1bHRzID0gTGlzdC5uaWwoKTsKICAgICAgICBTZXQ8TWV0aG9kU3ltYm9sPiBtZW1iZXJzV2l0aERlZmF1bHQgPSBtZXRhZGF0YS5nZXRBbm5vdGF0aW9uRWxlbWVudHNXaXRoRGVmYXVsdCgpOwogICAgICAgIGZvciAoTWV0aG9kU3ltYm9sIG0gOiBlbGVtZW50cykgewogICAgICAgICAgICBpZiAobS50eXBlLmlzRXJyb25lb3VzKCkpCiAgICAgICAgICAgICAgICBjb250aW51ZTsKCiAgICAgICAgICAgIGlmICghbWVtYmVyc1dpdGhEZWZhdWx0LmNvbnRhaW5zKG0pKQogICAgICAgICAgICAgICAgbWlzc2luZ0RlZmF1bHRzID0gbWlzc2luZ0RlZmF1bHRzLmFwcGVuZChtLm5hbWUpOwogICAgICAgIH0KICAgICAgICBtaXNzaW5nRGVmYXVsdHMgPSBtaXNzaW5nRGVmYXVsdHMucmV2ZXJzZSgpOwogICAgICAgIGlmIChtaXNzaW5nRGVmYXVsdHMubm9uRW1wdHkoKSkgewogICAgICAgICAgICBpc1ZhbGlkID0gZmFsc2U7CiAgICAgICAgICAgIFN0cmluZyBrZXkgPSAobWlzc2luZ0RlZmF1bHRzLnNpemUoKSA+IDEpCiAgICAgICAgICAgICAgICAgICAgPyAiYW5ub3RhdGlvbi5taXNzaW5nLmRlZmF1bHQudmFsdWUuMSIKICAgICAgICAgICAgICAgICAgICA6ICJhbm5vdGF0aW9uLm1pc3NpbmcuZGVmYXVsdC52YWx1ZSI7CiAgICAgICAgICAgIGxvZy5lcnJvcihhLnBvcygpLCBrZXksIGEudHlwZSwgbWlzc2luZ0RlZmF1bHRzKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBpc1ZhbGlkICYmIHZhbGlkYXRlVGFyZ2V0QW5ub3RhdGlvblZhbHVlKGEpOwogICAgfQoKICAgIC8qIFZhbGlkYXRlIHRoZSBzcGVjaWFsIGphdmEubGFuZy5hbm5vdGF0aW9uLlRhcmdldCBhbm5vdGF0aW9uICovCiAgICBib29sZWFuIHZhbGlkYXRlVGFyZ2V0QW5ub3RhdGlvblZhbHVlKEpDQW5ub3RhdGlvbiBhKSB7CiAgICAgICAgLy8gc3BlY2lhbCBjYXNlOiBqYXZhLmxhbmcuYW5ub3RhdGlvbi5UYXJnZXQgbXVzdCBub3QgaGF2ZQogICAgICAgIC8vIHJlcGVhdGVkIHZhbHVlcyBpbiBpdHMgdmFsdWUgbWVtYmVyCiAgICAgICAgaWYgKGEuYW5ub3RhdGlvblR5cGUudHlwZS50c3ltICE9IHN5bXMuYW5ub3RhdGlvblRhcmdldFR5cGUudHN5bSB8fAogICAgICAgICAgICAgICAgYS5hcmdzLnRhaWwgPT0gbnVsbCkKICAgICAgICAgICAgcmV0dXJuIHRydWU7CgogICAgICAgIGJvb2xlYW4gaXNWYWxpZCA9IHRydWU7CiAgICAgICAgaWYgKCFhLmFyZ3MuaGVhZC5oYXNUYWcoQVNTSUdOKSkgcmV0dXJuIGZhbHNlOyAvLyBlcnJvciByZWNvdmVyeQogICAgICAgIEpDQXNzaWduIGFzc2lnbiA9IChKQ0Fzc2lnbikgYS5hcmdzLmhlYWQ7CiAgICAgICAgU3ltYm9sIG0gPSBUcmVlSW5mby5zeW1ib2woYXNzaWduLmxocyk7CiAgICAgICAgaWYgKG0ubmFtZSAhPSBuYW1lcy52YWx1ZSkgcmV0dXJuIGZhbHNlOwogICAgICAgIEpDVHJlZSByaHMgPSBhc3NpZ24ucmhzOwogICAgICAgIGlmICghcmhzLmhhc1RhZyhORVdBUlJBWSkpIHJldHVybiBmYWxzZTsKICAgICAgICBKQ05ld0FycmF5IG5hID0gKEpDTmV3QXJyYXkpIHJoczsKICAgICAgICBTZXQ8U3ltYm9sPiB0YXJnZXRzID0gbmV3IEhhc2hTZXQ8PigpOwogICAgICAgIGZvciAoSkNUcmVlIGVsZW0gOiBuYS5lbGVtcykgewogICAgICAgICAgICBpZiAoIXRhcmdldHMuYWRkKFRyZWVJbmZvLnN5bWJvbChlbGVtKSkpIHsKICAgICAgICAgICAgICAgIGlzVmFsaWQgPSBmYWxzZTsKICAgICAgICAgICAgICAgIGxvZy5lcnJvcihlbGVtLnBvcygpLCAicmVwZWF0ZWQuYW5ub3RhdGlvbi50YXJnZXQiKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gaXNWYWxpZDsKICAgIH0KCiAgICB2b2lkIGNoZWNrRGVwcmVjYXRlZEFubm90YXRpb24oRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcywgU3ltYm9sIHMpIHsKICAgICAgICBpZiAobGludC5pc0VuYWJsZWQoTGludENhdGVnb3J5LkRFUF9BTk4pICYmIHMuaXNEZXByZWNhdGFibGVWaWFBbm5vdGF0aW9uKCkgJiYKICAgICAgICAgICAgKHMuZmxhZ3MoKSAmIERFUFJFQ0FURUQpICE9IDAgJiYKICAgICAgICAgICAgIXN5bXMuZGVwcmVjYXRlZFR5cGUuaXNFcnJvbmVvdXMoKSAmJgogICAgICAgICAgICBzLmF0dHJpYnV0ZShzeW1zLmRlcHJlY2F0ZWRUeXBlLnRzeW0pID09IG51bGwpIHsKICAgICAgICAgICAgbG9nLndhcm5pbmcoTGludENhdGVnb3J5LkRFUF9BTk4sCiAgICAgICAgICAgICAgICAgICAgcG9zLCAibWlzc2luZy5kZXByZWNhdGVkLmFubm90YXRpb24iKTsKICAgICAgICB9CiAgICAgICAgLy8gTm90ZTogQERlcHJlY2F0ZWQgaGFzIG5vIGVmZmVjdCBvbiBsb2NhbCB2YXJpYWJsZXMsIHBhcmFtZXRlcnMgYW5kIHBhY2thZ2UgZGVjbHMuCiAgICAgICAgaWYgKGxpbnQuaXNFbmFibGVkKExpbnRDYXRlZ29yeS5ERVBSRUNBVElPTikgJiYgIXMuaXNEZXByZWNhdGFibGVWaWFBbm5vdGF0aW9uKCkpIHsKICAgICAgICAgICAgaWYgKCFzeW1zLmRlcHJlY2F0ZWRUeXBlLmlzRXJyb25lb3VzKCkgJiYgcy5hdHRyaWJ1dGUoc3ltcy5kZXByZWNhdGVkVHlwZS50c3ltKSAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICBsb2cud2FybmluZyhMaW50Q2F0ZWdvcnkuREVQUkVDQVRJT04sIHBvcywKICAgICAgICAgICAgICAgICAgICAgICAgImRlcHJlY2F0ZWQuYW5ub3RhdGlvbi5oYXMubm8uZWZmZWN0IiwgS2luZHMua2luZE5hbWUocykpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIHZvaWQgY2hlY2tEZXByZWNhdGVkKGZpbmFsIERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIGZpbmFsIFN5bWJvbCBvdGhlciwgZmluYWwgU3ltYm9sIHMpIHsKICAgICAgICBpZiAoIChzLmlzRGVwcmVjYXRlZEZvclJlbW92YWwoKQogICAgICAgICAgICAgICAgfHwgcy5pc0RlcHJlY2F0ZWQoKSAmJiAhb3RoZXIuaXNEZXByZWNhdGVkKCkpCiAgICAgICAgICAgICAgICAmJiAocy5vdXRlcm1vc3RDbGFzcygpICE9IG90aGVyLm91dGVybW9zdENsYXNzKCkgfHwgcy5vdXRlcm1vc3RDbGFzcygpID09IG51bGwpKSB7CiAgICAgICAgICAgIGRlZmVycmVkTGludEhhbmRsZXIucmVwb3J0KCgpIC0+IHdhcm5EZXByZWNhdGVkKHBvcywgcykpOwogICAgICAgIH0KICAgIH0KCiAgICB2b2lkIGNoZWNrU3VuQVBJKGZpbmFsIERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIGZpbmFsIFN5bWJvbCBzKSB7CiAgICAgICAgaWYgKChzLmZsYWdzKCkgJiBQUk9QUklFVEFSWSkgIT0gMCkgewogICAgICAgICAgICBkZWZlcnJlZExpbnRIYW5kbGVyLnJlcG9ydCgoKSAtPiB7CiAgICAgICAgICAgICAgICBsb2cubWFuZGF0b3J5V2FybmluZyhwb3MsICJzdW4ucHJvcHJpZXRhcnkiLCBzKTsKICAgICAgICAgICAgfSk7CiAgICAgICAgfQogICAgfQoKICAgIHZvaWQgY2hlY2tQcm9maWxlKGZpbmFsIERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIGZpbmFsIFN5bWJvbCBzKSB7CiAgICAgICAgaWYgKHByb2ZpbGUgIT0gUHJvZmlsZS5ERUZBVUxUICYmIChzLmZsYWdzKCkgJiBOT1RfSU5fUFJPRklMRSkgIT0gMCkgewogICAgICAgICAgICBsb2cuZXJyb3IocG9zLCAibm90LmluLnByb2ZpbGUiLCBzLCBwcm9maWxlKTsKICAgICAgICB9CiAgICB9CgovKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIENoZWNrIGZvciByZWN1cnNpdmUgYW5ub3RhdGlvbiBlbGVtZW50cy4KICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKICAgIC8qKiBDaGVjayBmb3IgY3ljbGVzIGluIHRoZSBncmFwaCBvZiBhbm5vdGF0aW9uIGVsZW1lbnRzLgogICAgICovCiAgICB2b2lkIGNoZWNrTm9uQ3ljbGljRWxlbWVudHMoSkNDbGFzc0RlY2wgdHJlZSkgewogICAgICAgIGlmICgodHJlZS5zeW0uZmxhZ3NfZmllbGQgJiBBTk5PVEFUSU9OKSA9PSAwKSByZXR1cm47CiAgICAgICAgQXNzZXJ0LmNoZWNrKCh0cmVlLnN5bS5mbGFnc19maWVsZCAmIExPQ0tFRCkgPT0gMCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgdHJlZS5zeW0uZmxhZ3NfZmllbGQgfD0gTE9DS0VEOwogICAgICAgICAgICBmb3IgKEpDVHJlZSBkZWYgOiB0cmVlLmRlZnMpIHsKICAgICAgICAgICAgICAgIGlmICghZGVmLmhhc1RhZyhNRVRIT0RERUYpKSBjb250aW51ZTsKICAgICAgICAgICAgICAgIEpDTWV0aG9kRGVjbCBtZXRoID0gKEpDTWV0aG9kRGVjbClkZWY7CiAgICAgICAgICAgICAgICBjaGVja0Fubm90YXRpb25SZXNUeXBlKG1ldGgucG9zKCksIG1ldGgucmVzdHlwZS50eXBlKTsKICAgICAgICAgICAgfQogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgIHRyZWUuc3ltLmZsYWdzX2ZpZWxkICY9IH5MT0NLRUQ7CiAgICAgICAgICAgIHRyZWUuc3ltLmZsYWdzX2ZpZWxkIHw9IEFDWUNMSUNfQU5OOwogICAgICAgIH0KICAgIH0KCiAgICB2b2lkIGNoZWNrTm9uQ3ljbGljRWxlbWVudHNJbnRlcm5hbChEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBUeXBlU3ltYm9sIHRzeW0pIHsKICAgICAgICBpZiAoKHRzeW0uZmxhZ3NfZmllbGQgJiBBQ1lDTElDX0FOTikgIT0gMCkKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIGlmICgodHN5bS5mbGFnc19maWVsZCAmIExPQ0tFRCkgIT0gMCkgewogICAgICAgICAgICBsb2cuZXJyb3IocG9zLCAiY3ljbGljLmFubm90YXRpb24uZWxlbWVudCIpOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICAgIHRzeW0uZmxhZ3NfZmllbGQgfD0gTE9DS0VEOwogICAgICAgICAgICBmb3IgKFN5bWJvbCBzIDogdHN5bS5tZW1iZXJzKCkuZ2V0U3ltYm9scyhOT05fUkVDVVJTSVZFKSkgewogICAgICAgICAgICAgICAgaWYgKHMua2luZCAhPSBNVEgpCiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICBjaGVja0Fubm90YXRpb25SZXNUeXBlKHBvcywgKChNZXRob2RTeW1ib2wpcykudHlwZS5nZXRSZXR1cm5UeXBlKCkpOwogICAgICAgICAgICB9CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgdHN5bS5mbGFnc19maWVsZCAmPSB+TE9DS0VEOwogICAgICAgICAgICB0c3ltLmZsYWdzX2ZpZWxkIHw9IEFDWUNMSUNfQU5OOwogICAgICAgIH0KICAgIH0KCiAgICB2b2lkIGNoZWNrQW5ub3RhdGlvblJlc1R5cGUoRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcywgVHlwZSB0eXBlKSB7CiAgICAgICAgc3dpdGNoICh0eXBlLmdldFRhZygpKSB7CiAgICAgICAgY2FzZSBDTEFTUzoKICAgICAgICAgICAgaWYgKCh0eXBlLnRzeW0uZmxhZ3MoKSAmIEFOTk9UQVRJT04pICE9IDApCiAgICAgICAgICAgICAgICBjaGVja05vbkN5Y2xpY0VsZW1lbnRzSW50ZXJuYWwocG9zLCB0eXBlLnRzeW0pOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIEFSUkFZOgogICAgICAgICAgICBjaGVja0Fubm90YXRpb25SZXNUeXBlKHBvcywgdHlwZXMuZWxlbXR5cGUodHlwZSkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBicmVhazsgLy8gaW50IGV0YwogICAgICAgIH0KICAgIH0KCi8qICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ2hlY2sgZm9yIGN5Y2xlcyBpbiB0aGUgY29uc3RydWN0b3IgY2FsbCBncmFwaC4KICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKICAgIC8qKiBDaGVjayBmb3IgY3ljbGVzIGluIHRoZSBncmFwaCBvZiBjb25zdHJ1Y3RvcnMgY2FsbGluZyBvdGhlcgogICAgICogIGNvbnN0cnVjdG9ycy4KICAgICAqLwogICAgdm9pZCBjaGVja0N5Y2xpY0NvbnN0cnVjdG9ycyhKQ0NsYXNzRGVjbCB0cmVlKSB7CiAgICAgICAgTWFwPFN5bWJvbCxTeW1ib2w+IGNhbGxNYXAgPSBuZXcgSGFzaE1hcDw+KCk7CgogICAgICAgIC8vIGVudGVyIGVhY2ggY29uc3RydWN0b3IgdGhpcy1jYWxsIGludG8gdGhlIG1hcAogICAgICAgIGZvciAoTGlzdDxKQ1RyZWU+IGwgPSB0cmVlLmRlZnM7IGwubm9uRW1wdHkoKTsgbCA9IGwudGFpbCkgewogICAgICAgICAgICBKQ01ldGhvZEludm9jYXRpb24gYXBwID0gVHJlZUluZm8uZmlyc3RDb25zdHJ1Y3RvckNhbGwobC5oZWFkKTsKICAgICAgICAgICAgaWYgKGFwcCA9PSBudWxsKSBjb250aW51ZTsKICAgICAgICAgICAgSkNNZXRob2REZWNsIG1ldGggPSAoSkNNZXRob2REZWNsKSBsLmhlYWQ7CiAgICAgICAgICAgIGlmIChUcmVlSW5mby5uYW1lKGFwcC5tZXRoKSA9PSBuYW1lcy5fdGhpcykgewogICAgICAgICAgICAgICAgY2FsbE1hcC5wdXQobWV0aC5zeW0sIFRyZWVJbmZvLnN5bWJvbChhcHAubWV0aCkpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgbWV0aC5zeW0uZmxhZ3NfZmllbGQgfD0gQUNZQ0xJQzsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gQ2hlY2sgZm9yIGN5Y2xlcyBpbiB0aGUgbWFwCiAgICAgICAgU3ltYm9sW10gY3RvcnMgPSBuZXcgU3ltYm9sWzBdOwogICAgICAgIGN0b3JzID0gY2FsbE1hcC5rZXlTZXQoKS50b0FycmF5KGN0b3JzKTsKICAgICAgICBmb3IgKFN5bWJvbCBjYWxsZXIgOiBjdG9ycykgewogICAgICAgICAgICBjaGVja0N5Y2xpY0NvbnN0cnVjdG9yKHRyZWUsIGNhbGxlciwgY2FsbE1hcCk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKiBMb29rIGluIHRoZSBtYXAgdG8gc2VlIGlmIHRoZSBnaXZlbiBjb25zdHJ1Y3RvciBpcyBwYXJ0IG9mIGEKICAgICAqICBjYWxsIGN5Y2xlLgogICAgICovCiAgICBwcml2YXRlIHZvaWQgY2hlY2tDeWNsaWNDb25zdHJ1Y3RvcihKQ0NsYXNzRGVjbCB0cmVlLCBTeW1ib2wgY3RvciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1hcDxTeW1ib2wsU3ltYm9sPiBjYWxsTWFwKSB7CiAgICAgICAgaWYgKGN0b3IgIT0gbnVsbCAmJiAoY3Rvci5mbGFnc19maWVsZCAmIEFDWUNMSUMpID09IDApIHsKICAgICAgICAgICAgaWYgKChjdG9yLmZsYWdzX2ZpZWxkICYgTE9DS0VEKSAhPSAwKSB7CiAgICAgICAgICAgICAgICBsb2cuZXJyb3IoVHJlZUluZm8uZGlhZ25vc3RpY1Bvc2l0aW9uRm9yKGN0b3IsIHRyZWUpLAogICAgICAgICAgICAgICAgICAgICAgICAgICJyZWN1cnNpdmUuY3Rvci5pbnZvY2F0aW9uIik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBjdG9yLmZsYWdzX2ZpZWxkIHw9IExPQ0tFRDsKICAgICAgICAgICAgICAgIGNoZWNrQ3ljbGljQ29uc3RydWN0b3IodHJlZSwgY2FsbE1hcC5yZW1vdmUoY3RvciksIGNhbGxNYXApOwogICAgICAgICAgICAgICAgY3Rvci5mbGFnc19maWVsZCAmPSB+TE9DS0VEOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGN0b3IuZmxhZ3NfZmllbGQgfD0gQUNZQ0xJQzsKICAgICAgICB9CiAgICB9CgovKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIE1pc2NlbGxhbmVvdXMKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKICAgIC8qKgogICAgICogIENoZWNrIGZvciBkaXZpc2lvbiBieSBpbnRlZ2VyIGNvbnN0YW50IHplcm8KICAgICAqICBAcGFyYW0gcG9zICAgICAgICAgICBQb3NpdGlvbiBmb3IgZXJyb3IgcmVwb3J0aW5nLgogICAgICogIEBwYXJhbSBvcGVyYXRvciAgICAgIFRoZSBvcGVyYXRvciBmb3IgdGhlIGV4cHJlc3Npb24KICAgICAqICBAcGFyYW0gb3BlcmFuZCAgICAgICBUaGUgcmlnaHQgaGFuZCBvcGVyYW5kIGZvciB0aGUgZXhwcmVzc2lvbgogICAgICovCiAgICB2b2lkIGNoZWNrRGl2WmVybyhmaW5hbCBEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBTeW1ib2wgb3BlcmF0b3IsIFR5cGUgb3BlcmFuZCkgewogICAgICAgIGlmIChvcGVyYW5kLmNvbnN0VmFsdWUoKSAhPSBudWxsCiAgICAgICAgICAgICYmIG9wZXJhbmQuZ2V0VGFnKCkuaXNTdWJSYW5nZU9mKExPTkcpCiAgICAgICAgICAgICYmICgoTnVtYmVyKSAob3BlcmFuZC5jb25zdFZhbHVlKCkpKS5sb25nVmFsdWUoKSA9PSAwKSB7CiAgICAgICAgICAgIGludCBvcGMgPSAoKE9wZXJhdG9yU3ltYm9sKW9wZXJhdG9yKS5vcGNvZGU7CiAgICAgICAgICAgIGlmIChvcGMgPT0gQnl0ZUNvZGVzLmlkaXYgfHwgb3BjID09IEJ5dGVDb2Rlcy5pbW9kCiAgICAgICAgICAgICAgICB8fCBvcGMgPT0gQnl0ZUNvZGVzLmxkaXYgfHwgb3BjID09IEJ5dGVDb2Rlcy5sbW9kKSB7CiAgICAgICAgICAgICAgICBkZWZlcnJlZExpbnRIYW5kbGVyLnJlcG9ydCgoKSAtPiB3YXJuRGl2WmVybyhwb3MpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrIGZvciBlbXB0eSBzdGF0ZW1lbnRzIGFmdGVyIGlmCiAgICAgKi8KICAgIHZvaWQgY2hlY2tFbXB0eUlmKEpDSWYgdHJlZSkgewogICAgICAgIGlmICh0cmVlLnRoZW5wYXJ0Lmhhc1RhZyhTS0lQKSAmJiB0cmVlLmVsc2VwYXJ0ID09IG51bGwgJiYKICAgICAgICAgICAgICAgIGxpbnQuaXNFbmFibGVkKExpbnRDYXRlZ29yeS5FTVBUWSkpCiAgICAgICAgICAgIGxvZy53YXJuaW5nKExpbnRDYXRlZ29yeS5FTVBUWSwgdHJlZS50aGVucGFydC5wb3MoKSwgImVtcHR5LmlmIik7CiAgICB9CgogICAgLyoqIENoZWNrIHRoYXQgc3ltYm9sIGlzIHVuaXF1ZSBpbiBnaXZlbiBzY29wZS4KICAgICAqICBAcGFyYW0gcG9zICAgICAgICAgICBQb3NpdGlvbiBmb3IgZXJyb3IgcmVwb3J0aW5nLgogICAgICogIEBwYXJhbSBzeW0gICAgICAgICAgIFRoZSBzeW1ib2wuCiAgICAgKiAgQHBhcmFtIHMgICAgICAgICAgICAgVGhlIHNjb3BlLgogICAgICovCiAgICBib29sZWFuIGNoZWNrVW5pcXVlKERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIFN5bWJvbCBzeW0sIFNjb3BlIHMpIHsKICAgICAgICBpZiAoc3ltLnR5cGUuaXNFcnJvbmVvdXMoKSkKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgaWYgKHN5bS5vd25lci5uYW1lID09IG5hbWVzLmFueSkgcmV0dXJuIGZhbHNlOwogICAgICAgIGZvciAoU3ltYm9sIGJ5TmFtZSA6IHMuZ2V0U3ltYm9sc0J5TmFtZShzeW0ubmFtZSwgTk9OX1JFQ1VSU0lWRSkpIHsKICAgICAgICAgICAgaWYgKHN5bSAhPSBieU5hbWUgJiYKICAgICAgICAgICAgICAgICAgICAoYnlOYW1lLmZsYWdzKCkgJiBDTEFTSCkgPT0gMCAmJgogICAgICAgICAgICAgICAgICAgIHN5bS5raW5kID09IGJ5TmFtZS5raW5kICYmCiAgICAgICAgICAgICAgICAgICAgc3ltLm5hbWUgIT0gbmFtZXMuZXJyb3IgJiYKICAgICAgICAgICAgICAgICAgICAoc3ltLmtpbmQgIT0gTVRIIHx8CiAgICAgICAgICAgICAgICAgICAgIHR5cGVzLmhhc1NhbWVBcmdzKHN5bS50eXBlLCBieU5hbWUudHlwZSkgfHwKICAgICAgICAgICAgICAgICAgICAgdHlwZXMuaGFzU2FtZUFyZ3ModHlwZXMuZXJhc3VyZShzeW0udHlwZSksIHR5cGVzLmVyYXN1cmUoYnlOYW1lLnR5cGUpKSkpIHsKICAgICAgICAgICAgICAgIGlmICgoc3ltLmZsYWdzKCkgJiBWQVJBUkdTKSAhPSAoYnlOYW1lLmZsYWdzKCkgJiBWQVJBUkdTKSkgewogICAgICAgICAgICAgICAgICAgIHZhcmFyZ3NEdXBsaWNhdGVFcnJvcihwb3MsIHN5bSwgYnlOYW1lKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoc3ltLmtpbmQgPT0gTVRIICYmICF0eXBlcy5oYXNTYW1lQXJncyhzeW0udHlwZSwgYnlOYW1lLnR5cGUsIGZhbHNlKSkgewogICAgICAgICAgICAgICAgICAgIGR1cGxpY2F0ZUVyYXN1cmVFcnJvcihwb3MsIHN5bSwgYnlOYW1lKTsKICAgICAgICAgICAgICAgICAgICBzeW0uZmxhZ3NfZmllbGQgfD0gQ0xBU0g7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGR1cGxpY2F0ZUVycm9yKHBvcywgYnlOYW1lKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgLyoqIFJlcG9ydCBkdXBsaWNhdGUgZGVjbGFyYXRpb24gZXJyb3IuCiAgICAgKi8KICAgIHZvaWQgZHVwbGljYXRlRXJhc3VyZUVycm9yKERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIFN5bWJvbCBzeW0xLCBTeW1ib2wgc3ltMikgewogICAgICAgIGlmICghc3ltMS50eXBlLmlzRXJyb25lb3VzKCkgJiYgIXN5bTIudHlwZS5pc0Vycm9uZW91cygpKSB7CiAgICAgICAgICAgIGxvZy5lcnJvcihwb3MsICJuYW1lLmNsYXNoLnNhbWUuZXJhc3VyZSIsIHN5bTEsIHN5bTIpOwogICAgICAgIH0KICAgIH0KCiAgICAvKipDaGVjayB0aGF0IHR5cGVzIGltcG9ydGVkIHRocm91Z2ggdGhlIG9yZGluYXJ5IGltcG9ydHMgZG9uJ3QgY2xhc2ggd2l0aCB0eXBlcyBpbXBvcnRlZAogICAgICogYnkgb3RoZXIgKHN0YXRpYyBvciBvcmRpbmFyeSkgaW1wb3J0cy4gTm90ZSB0aGF0IHR3byBzdGF0aWMgaW1wb3J0cyBtYXkgaW1wb3J0IHR3byBjbGFzaGluZwogICAgICogdHlwZXMgd2l0aG91dCBhbiBlcnJvciBvbiB0aGUgaW1wb3J0cy4KICAgICAqIEBwYXJhbSB0b3BsZXZlbCAgICAgICBUaGUgdG9wbGV2ZWwgdHJlZSBmb3Igd2hpY2ggdGhlIHRlc3Qgc2hvdWxkIGJlIHBlcmZvcm1lZC4KICAgICAqLwogICAgdm9pZCBjaGVja0ltcG9ydHNVbmlxdWUoSkNDb21waWxhdGlvblVuaXQgdG9wbGV2ZWwpIHsKICAgICAgICBXcml0ZWFibGVTY29wZSBvcmRpbmFsbHlJbXBvcnRlZFNvRmFyID0gV3JpdGVhYmxlU2NvcGUuY3JlYXRlKHRvcGxldmVsLnBhY2tnZSk7CiAgICAgICAgV3JpdGVhYmxlU2NvcGUgc3RhdGljYWxseUltcG9ydGVkU29GYXIgPSBXcml0ZWFibGVTY29wZS5jcmVhdGUodG9wbGV2ZWwucGFja2dlKTsKICAgICAgICBXcml0ZWFibGVTY29wZSB0b3BMZXZlbFNjb3BlID0gdG9wbGV2ZWwudG9wbGV2ZWxTY29wZTsKCiAgICAgICAgZm9yIChKQ1RyZWUgZGVmIDogdG9wbGV2ZWwuZGVmcykgewogICAgICAgICAgICBpZiAoIWRlZi5oYXNUYWcoSU1QT1JUKSkKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwoKICAgICAgICAgICAgSkNJbXBvcnQgaW1wID0gKEpDSW1wb3J0KSBkZWY7CgogICAgICAgICAgICBpZiAoaW1wLmltcG9ydFNjb3BlID09IG51bGwpCiAgICAgICAgICAgICAgICBjb250aW51ZTsKCiAgICAgICAgICAgIGZvciAoU3ltYm9sIHN5bSA6IGltcC5pbXBvcnRTY29wZS5nZXRTeW1ib2xzKHN5bSAtPiBzeW0ua2luZCA9PSBUWVApKSB7CiAgICAgICAgICAgICAgICBpZiAoaW1wLmlzU3RhdGljKCkpIHsKICAgICAgICAgICAgICAgICAgICBjaGVja1VuaXF1ZUltcG9ydChpbXAucG9zKCksIG9yZGluYWxseUltcG9ydGVkU29GYXIsIHN0YXRpY2FsbHlJbXBvcnRlZFNvRmFyLCB0b3BMZXZlbFNjb3BlLCBzeW0sIHRydWUpOwogICAgICAgICAgICAgICAgICAgIHN0YXRpY2FsbHlJbXBvcnRlZFNvRmFyLmVudGVyKHN5bSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGNoZWNrVW5pcXVlSW1wb3J0KGltcC5wb3MoKSwgb3JkaW5hbGx5SW1wb3J0ZWRTb0Zhciwgc3RhdGljYWxseUltcG9ydGVkU29GYXIsIHRvcExldmVsU2NvcGUsIHN5bSwgZmFsc2UpOwogICAgICAgICAgICAgICAgICAgIG9yZGluYWxseUltcG9ydGVkU29GYXIuZW50ZXIoc3ltKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgaW1wLmltcG9ydFNjb3BlID0gbnVsbDsKICAgICAgICB9CiAgICB9CgogICAgLyoqIENoZWNrIHRoYXQgc2luZ2xlLXR5cGUgaW1wb3J0IGlzIG5vdCBhbHJlYWR5IGltcG9ydGVkIG9yIHRvcC1sZXZlbCBkZWZpbmVkLAogICAgICogIGJ1dCBtYWtlIGFuIGV4Y2VwdGlvbiBmb3IgdHdvIHNpbmdsZS10eXBlIGltcG9ydHMgd2hpY2ggZGVub3RlIHRoZSBzYW1lIHR5cGUuCiAgICAgKiAgQHBhcmFtIHBvcyAgICAgICAgICAgICAgICAgICAgIFBvc2l0aW9uIGZvciBlcnJvciByZXBvcnRpbmcuCiAgICAgKiAgQHBhcmFtIG9yZGluYWxseUltcG9ydGVkU29GYXIgIEEgU2NvcGUgY29udGFpbmluZyB0eXBlcyBpbXBvcnRlZCBzbyBmYXIgdGhyb3VnaAogICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmRpbmFyeSBpbXBvcnRzLgogICAgICogIEBwYXJhbSBzdGF0aWNhbGx5SW1wb3J0ZWRTb0ZhciBBIFNjb3BlIGNvbnRhaW5pbmcgdHlwZXMgaW1wb3J0ZWQgc28gZmFyIHRocm91Z2gKICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdGljIGltcG9ydHMuCiAgICAgKiAgQHBhcmFtIHRvcExldmVsU2NvcGUgICAgICAgICAgIFRoZSBjdXJyZW50IGZpbGUncyB0b3AtbGV2ZWwgU2NvcGUKICAgICAqICBAcGFyYW0gc3ltICAgICAgICAgICAgICAgICAgICAgVGhlIHN5bWJvbC4KICAgICAqICBAcGFyYW0gc3RhdGljSW1wb3J0ICAgICAgICAgICAgV2hldGhlciBvciBub3QgdGhpcyB3YXMgYSBzdGF0aWMgaW1wb3J0CiAgICAgKi8KICAgIHByaXZhdGUgYm9vbGVhbiBjaGVja1VuaXF1ZUltcG9ydChEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBTY29wZSBvcmRpbmFsbHlJbXBvcnRlZFNvRmFyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNjb3BlIHN0YXRpY2FsbHlJbXBvcnRlZFNvRmFyLCBTY29wZSB0b3BMZXZlbFNjb3BlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN5bWJvbCBzeW0sIGJvb2xlYW4gc3RhdGljSW1wb3J0KSB7CiAgICAgICAgRmlsdGVyPFN5bWJvbD4gZHVwbGljYXRlcyA9IGNhbmRpZGF0ZSAtPiBjYW5kaWRhdGUgIT0gc3ltICYmICFjYW5kaWRhdGUudHlwZS5pc0Vycm9uZW91cygpOwogICAgICAgIFN5bWJvbCBjbGFzaGluZyA9IG9yZGluYWxseUltcG9ydGVkU29GYXIuZmluZEZpcnN0KHN5bS5uYW1lLCBkdXBsaWNhdGVzKTsKICAgICAgICBpZiAoY2xhc2hpbmcgPT0gbnVsbCAmJiAhc3RhdGljSW1wb3J0KSB7CiAgICAgICAgICAgIGNsYXNoaW5nID0gc3RhdGljYWxseUltcG9ydGVkU29GYXIuZmluZEZpcnN0KHN5bS5uYW1lLCBkdXBsaWNhdGVzKTsKICAgICAgICB9CiAgICAgICAgaWYgKGNsYXNoaW5nICE9IG51bGwpIHsKICAgICAgICAgICAgaWYgKHN0YXRpY0ltcG9ydCkKICAgICAgICAgICAgICAgIGxvZy5lcnJvcihwb3MsICJhbHJlYWR5LmRlZmluZWQuc3RhdGljLnNpbmdsZS5pbXBvcnQiLCBjbGFzaGluZyk7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIGxvZy5lcnJvcihwb3MsICJhbHJlYWR5LmRlZmluZWQuc2luZ2xlLmltcG9ydCIsIGNsYXNoaW5nKTsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICBjbGFzaGluZyA9IHRvcExldmVsU2NvcGUuZmluZEZpcnN0KHN5bS5uYW1lLCBkdXBsaWNhdGVzKTsKICAgICAgICBpZiAoY2xhc2hpbmcgIT0gbnVsbCkgewogICAgICAgICAgICBsb2cuZXJyb3IocG9zLCAiYWxyZWFkeS5kZWZpbmVkLnRoaXMudW5pdCIsIGNsYXNoaW5nKTsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICAvKiogQ2hlY2sgdGhhdCBhIHF1YWxpZmllZCBuYW1lIGlzIGluIGNhbm9uaWNhbCBmb3JtIChmb3IgaW1wb3J0IGRlY2xzKS4KICAgICAqLwogICAgcHVibGljIHZvaWQgY2hlY2tDYW5vbmljYWwoSkNUcmVlIHRyZWUpIHsKICAgICAgICBpZiAoIWlzQ2Fub25pY2FsKHRyZWUpKQogICAgICAgICAgICBsb2cuZXJyb3IodHJlZS5wb3MoKSwgImltcG9ydC5yZXF1aXJlcy5jYW5vbmljYWwiLAogICAgICAgICAgICAgICAgICAgICAgVHJlZUluZm8uc3ltYm9sKHRyZWUpKTsKICAgIH0KICAgICAgICAvLyB3aGVyZQogICAgICAgIHByaXZhdGUgYm9vbGVhbiBpc0Nhbm9uaWNhbChKQ1RyZWUgdHJlZSkgewogICAgICAgICAgICB3aGlsZSAodHJlZS5oYXNUYWcoU0VMRUNUKSkgewogICAgICAgICAgICAgICAgSkNGaWVsZEFjY2VzcyBzID0gKEpDRmllbGRBY2Nlc3MpIHRyZWU7CiAgICAgICAgICAgICAgICBpZiAocy5zeW0ub3duZXIubmFtZSAhPSBUcmVlSW5mby5zeW1ib2wocy5zZWxlY3RlZCkubmFtZSkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB0cmVlID0gcy5zZWxlY3RlZDsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgLyoqIENoZWNrIHRoYXQgYW4gYXV4aWxpYXJ5IGNsYXNzIGlzIG5vdCBhY2Nlc3NlZCBmcm9tIGFueSBvdGhlciBmaWxlIHRoYW4gaXRzIG93bi4KICAgICAqLwogICAgdm9pZCBjaGVja0ZvckJhZEF1eGlsaWFyeUNsYXNzQWNjZXNzKERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIEVudjxBdHRyQ29udGV4dD4gZW52LCBDbGFzc1N5bWJvbCBjKSB7CiAgICAgICAgaWYgKGxpbnQuaXNFbmFibGVkKExpbnQuTGludENhdGVnb3J5LkFVWElMSUFSWUNMQVNTKSAmJgogICAgICAgICAgICAoYy5mbGFncygpICYgQVVYSUxJQVJZKSAhPSAwICYmCiAgICAgICAgICAgIHJzLmlzQWNjZXNzaWJsZShlbnYsIGMpICYmCiAgICAgICAgICAgICFmaWxlTWFuYWdlci5pc1NhbWVGaWxlKGMuc291cmNlZmlsZSwgZW52LnRvcGxldmVsLnNvdXJjZWZpbGUpKQogICAgICAgIHsKICAgICAgICAgICAgbG9nLndhcm5pbmcocG9zLCAiYXV4aWxpYXJ5LmNsYXNzLmFjY2Vzc2VkLmZyb20ub3V0c2lkZS5vZi5pdHMuc291cmNlLmZpbGUiLAogICAgICAgICAgICAgICAgICAgICAgICBjLCBjLnNvdXJjZWZpbGUpOwogICAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIGNsYXNzIENvbnZlcnNpb25XYXJuZXIgZXh0ZW5kcyBXYXJuZXIgewogICAgICAgIGZpbmFsIFN0cmluZyB1bmNoZWNrZWRLZXk7CiAgICAgICAgZmluYWwgVHlwZSBmb3VuZDsKICAgICAgICBmaW5hbCBUeXBlIGV4cGVjdGVkOwogICAgICAgIHB1YmxpYyBDb252ZXJzaW9uV2FybmVyKERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIFN0cmluZyB1bmNoZWNrZWRLZXksIFR5cGUgZm91bmQsIFR5cGUgZXhwZWN0ZWQpIHsKICAgICAgICAgICAgc3VwZXIocG9zKTsKICAgICAgICAgICAgdGhpcy51bmNoZWNrZWRLZXkgPSB1bmNoZWNrZWRLZXk7CiAgICAgICAgICAgIHRoaXMuZm91bmQgPSBmb3VuZDsKICAgICAgICAgICAgdGhpcy5leHBlY3RlZCA9IGV4cGVjdGVkOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgd2FybihMaW50Q2F0ZWdvcnkgbGludCkgewogICAgICAgICAgICBib29sZWFuIHdhcm5lZCA9IHRoaXMud2FybmVkOwogICAgICAgICAgICBzdXBlci53YXJuKGxpbnQpOwogICAgICAgICAgICBpZiAod2FybmVkKSByZXR1cm47IC8vIHN1cHByZXNzIHJlZHVuZGFudCBkaWFnbm9zdGljcwogICAgICAgICAgICBzd2l0Y2ggKGxpbnQpIHsKICAgICAgICAgICAgICAgIGNhc2UgVU5DSEVDS0VEOgogICAgICAgICAgICAgICAgICAgIENoZWNrLnRoaXMud2FyblVuY2hlY2tlZChwb3MoKSwgInByb2IuZm91bmQucmVxIiwgZGlhZ3MuZnJhZ21lbnQodW5jaGVja2VkS2V5KSwgZm91bmQsIGV4cGVjdGVkKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgVkFSQVJHUzoKICAgICAgICAgICAgICAgICAgICBpZiAobWV0aG9kICE9IG51bGwgJiYKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZC5hdHRyaWJ1dGUoc3ltcy50cnVzdE1lVHlwZS50c3ltKSAhPSBudWxsICYmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc1RydXN0TWVBbGxvd2VkT25NZXRob2QobWV0aG9kKSAmJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgIXR5cGVzLmlzUmVpZmlhYmxlKG1ldGhvZC50eXBlLmdldFBhcmFtZXRlclR5cGVzKCkubGFzdCgpKSkgewogICAgICAgICAgICAgICAgICAgICAgICBDaGVjay50aGlzLndhcm5VbnNhZmVWYXJhcmcocG9zKCksICJ2YXJhcmdzLnVuc2FmZS51c2UudmFyYXJncy5wYXJhbSIsIG1ldGhvZC5wYXJhbXMubGFzdCgpKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigiVW5leHBlY3RlZCBsaW50OiAiICsgbGludCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgcHVibGljIFdhcm5lciBjYXN0V2FybmVyKERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIFR5cGUgZm91bmQsIFR5cGUgZXhwZWN0ZWQpIHsKICAgICAgICByZXR1cm4gbmV3IENvbnZlcnNpb25XYXJuZXIocG9zLCAidW5jaGVja2VkLmNhc3QudG8udHlwZSIsIGZvdW5kLCBleHBlY3RlZCk7CiAgICB9CgogICAgcHVibGljIFdhcm5lciBjb252ZXJ0V2FybmVyKERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIFR5cGUgZm91bmQsIFR5cGUgZXhwZWN0ZWQpIHsKICAgICAgICByZXR1cm4gbmV3IENvbnZlcnNpb25XYXJuZXIocG9zLCAidW5jaGVja2VkLmFzc2lnbiIsIGZvdW5kLCBleHBlY3RlZCk7CiAgICB9CgogICAgcHVibGljIHZvaWQgY2hlY2tGdW5jdGlvbmFsSW50ZXJmYWNlKEpDQ2xhc3NEZWNsIHRyZWUsIENsYXNzU3ltYm9sIGNzKSB7CiAgICAgICAgQ29tcG91bmQgZnVuY3Rpb25hbFR5cGUgPSBjcy5hdHRyaWJ1dGUoc3ltcy5mdW5jdGlvbmFsSW50ZXJmYWNlVHlwZS50c3ltKTsKCiAgICAgICAgaWYgKGZ1bmN0aW9uYWxUeXBlICE9IG51bGwpIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIHR5cGVzLmZpbmREZXNjcmlwdG9yU3ltYm9sKChUeXBlU3ltYm9sKWNzKTsKICAgICAgICAgICAgfSBjYXRjaCAoVHlwZXMuRnVuY3Rpb25EZXNjcmlwdG9yTG9va3VwRXJyb3IgZXgpIHsKICAgICAgICAgICAgICAgIERpYWdub3N0aWNQb3NpdGlvbiBwb3MgPSB0cmVlLnBvcygpOwogICAgICAgICAgICAgICAgZm9yIChKQ0Fubm90YXRpb24gYSA6IHRyZWUuZ2V0TW9kaWZpZXJzKCkuYW5ub3RhdGlvbnMpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoYS5hbm5vdGF0aW9uVHlwZS50eXBlLnRzeW0gPT0gc3ltcy5mdW5jdGlvbmFsSW50ZXJmYWNlVHlwZS50c3ltKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHBvcyA9IGEucG9zKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGxvZy5lcnJvcihwb3MsICJiYWQuZnVuY3Rpb25hbC5pbnRmLmFubm8uMSIsIGV4LmdldERpYWdub3N0aWMoKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHZvaWQgY2hlY2tJbXBvcnRzUmVzb2x2YWJsZShmaW5hbCBKQ0NvbXBpbGF0aW9uVW5pdCB0b3BsZXZlbCkgewogICAgICAgIGZvciAoZmluYWwgSkNJbXBvcnQgaW1wIDogdG9wbGV2ZWwuZ2V0SW1wb3J0cygpKSB7CiAgICAgICAgICAgIGlmICghaW1wLnN0YXRpY0ltcG9ydCB8fCAhaW1wLnF1YWxpZC5oYXNUYWcoU0VMRUNUKSkKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICBmaW5hbCBKQ0ZpZWxkQWNjZXNzIHNlbGVjdCA9IChKQ0ZpZWxkQWNjZXNzKSBpbXAucXVhbGlkOwogICAgICAgICAgICBmaW5hbCBTeW1ib2wgb3JpZ2luOwogICAgICAgICAgICBpZiAoc2VsZWN0Lm5hbWUgPT0gbmFtZXMuYXN0ZXJpc2sgfHwgKG9yaWdpbiA9IFRyZWVJbmZvLnN5bWJvbChzZWxlY3Quc2VsZWN0ZWQpKSA9PSBudWxsIHx8IG9yaWdpbi5raW5kICE9IFRZUCkKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwoKICAgICAgICAgICAgVHlwZVN5bWJvbCBzaXRlID0gKFR5cGVTeW1ib2wpIFRyZWVJbmZvLnN5bWJvbChzZWxlY3Quc2VsZWN0ZWQpOwogICAgICAgICAgICBpZiAoIWNoZWNrVHlwZUNvbnRhaW5zSW1wb3J0YWJsZUVsZW1lbnQoc2l0ZSwgc2l0ZSwgdG9wbGV2ZWwucGFja2dlLCBzZWxlY3QubmFtZSwgbmV3IEhhc2hTZXQ8U3ltYm9sPigpKSkgewogICAgICAgICAgICAgICAgbG9nLmVycm9yKGltcC5wb3MoKSwgImNhbnQucmVzb2x2ZS5sb2NhdGlvbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgS2luZE5hbWUuU1RBVElDLAogICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGVjdC5uYW1lLCBMaXN0LjxUeXBlPm5pbCgpLCBMaXN0LjxUeXBlPm5pbCgpLAogICAgICAgICAgICAgICAgICAgICAgICAgIEtpbmRzLnR5cGVLaW5kTmFtZShUcmVlSW5mby5zeW1ib2woc2VsZWN0LnNlbGVjdGVkKS50eXBlKSwKICAgICAgICAgICAgICAgICAgICAgICAgICBUcmVlSW5mby5zeW1ib2woc2VsZWN0LnNlbGVjdGVkKS50eXBlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvLyBDaGVjayB0aGF0IHBhY2thZ2VzIGltcG9ydGVkIGFyZSBpbiBzY29wZSAoSkxTIDcuNC4zLCA2LjMsIDYuNS4zLjEsIDYuNS4zLjIpCiAgICBwdWJsaWMgdm9pZCBjaGVja0ltcG9ydGVkUGFja2FnZXNPYnNlcnZhYmxlKGZpbmFsIEpDQ29tcGlsYXRpb25Vbml0IHRvcGxldmVsKSB7CiAgICAgICAgT1VURVI6IGZvciAoSkNJbXBvcnQgaW1wIDogdG9wbGV2ZWwuZ2V0SW1wb3J0cygpKSB7CiAgICAgICAgICAgIGlmICghaW1wLnN0YXRpY0ltcG9ydCAmJiBUcmVlSW5mby5uYW1lKGltcC5xdWFsaWQpID09IG5hbWVzLmFzdGVyaXNrKSB7CiAgICAgICAgICAgICAgICBUeXBlU3ltYm9sIHRzeW0gPSAoKEpDRmllbGRBY2Nlc3MpaW1wLnF1YWxpZCkuc2VsZWN0ZWQudHlwZS50c3ltOwogICAgICAgICAgICAgICAgaWYgKHRvcGxldmVsLm1vZGxlLnZpc2libGVQYWNrYWdlcyAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgLy9UT0RPIC0gdW5jbGVhcjogc2VsZWN0cyBsaWtlIGphdmF4Liogd2lsbCBnZXQgcmVzb2x2ZWQgZnJvbSB0aGUgY3VycmVudCBtb2R1bGUKICAgICAgICAgICAgICAgICAgICAvLyhhcyBqYXZheCBpcyBub3QgYW4gZXhwb3J0ZWQgcGFja2FnZSBmcm9tIGFueSBtb2R1bGUpLiBBbmQgYXMgamF2YXggaW4gdGhlIGN1cnJlbnQKICAgICAgICAgICAgICAgICAgICAvL21vZHVsZSB0eXBpY2FsbHkgZG9lcyBub3QgY29udGFpbiBhbnkgY2xhc3NlcyBvciBzdWJwYWNrYWdlcywgd2UgbmVlZCB0byBnbyB0aHJvdWdoCiAgICAgICAgICAgICAgICAgICAgLy90aGUgdmlzaWJsZSBwYWNrYWdlcyB0byBmaW5kIGEgc3ViLXBhY2thZ2U6CiAgICAgICAgICAgICAgICAgICAgZm9yIChQYWNrYWdlU3ltYm9sIGtub3duIDogdG9wbGV2ZWwubW9kbGUudmlzaWJsZVBhY2thZ2VzLnZhbHVlcygpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChDb252ZXJ0LnBhY2thZ2VQYXJ0KGtub3duLmZ1bGxuYW1lKSA9PSB0c3ltLmZsYXROYW1lKCkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZSBPVVRFUjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAodHN5bS5raW5kID09IFBDSyAmJiB0c3ltLm1lbWJlcnMoKS5pc0VtcHR5KCkgJiYgIXRzeW0uZXhpc3RzKCkpIHsKICAgICAgICAgICAgICAgICAgICBsb2cuZXJyb3IoRGlhZ25vc3RpY0ZsYWcuUkVTT0xWRV9FUlJPUiwgaW1wLnBvcywgImRvZXNudC5leGlzdCIsIHRzeW0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgYm9vbGVhbiBjaGVja1R5cGVDb250YWluc0ltcG9ydGFibGVFbGVtZW50KFR5cGVTeW1ib2wgdHN5bSwgVHlwZVN5bWJvbCBvcmlnaW4sIFBhY2thZ2VTeW1ib2wgcGFja2dlLCBOYW1lIG5hbWUsIFNldDxTeW1ib2w+IHByb2Nlc3NlZCkgewogICAgICAgIGlmICh0c3ltID09IG51bGwgfHwgIXByb2Nlc3NlZC5hZGQodHN5bSkpCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKCiAgICAgICAgICAgIC8vIGFsc28gc2VhcmNoIHRocm91Z2ggaW5oZXJpdGVkIG5hbWVzCiAgICAgICAgaWYgKGNoZWNrVHlwZUNvbnRhaW5zSW1wb3J0YWJsZUVsZW1lbnQodHlwZXMuc3VwZXJ0eXBlKHRzeW0udHlwZSkudHN5bSwgb3JpZ2luLCBwYWNrZ2UsIG5hbWUsIHByb2Nlc3NlZCkpCiAgICAgICAgICAgIHJldHVybiB0cnVlOwoKICAgICAgICBmb3IgKFR5cGUgdCA6IHR5cGVzLmludGVyZmFjZXModHN5bS50eXBlKSkKICAgICAgICAgICAgaWYgKGNoZWNrVHlwZUNvbnRhaW5zSW1wb3J0YWJsZUVsZW1lbnQodC50c3ltLCBvcmlnaW4sIHBhY2tnZSwgbmFtZSwgcHJvY2Vzc2VkKSkKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwoKICAgICAgICBmb3IgKFN5bWJvbCBzeW0gOiB0c3ltLm1lbWJlcnMoKS5nZXRTeW1ib2xzQnlOYW1lKG5hbWUpKSB7CiAgICAgICAgICAgIGlmIChzeW0uaXNTdGF0aWMoKSAmJgogICAgICAgICAgICAgICAgaW1wb3J0QWNjZXNzaWJsZShzeW0sIHBhY2tnZSkgJiYKICAgICAgICAgICAgICAgIHN5bS5pc01lbWJlck9mKG9yaWdpbiwgdHlwZXMpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIC8vIGlzIHRoZSBzeW0gYWNjZXNzaWJsZSBldmVyeXdoZXJlIGluIHBhY2tnZT8KICAgIHB1YmxpYyBib29sZWFuIGltcG9ydEFjY2Vzc2libGUoU3ltYm9sIHN5bSwgUGFja2FnZVN5bWJvbCBwYWNrZ2UpIHsKICAgICAgICB0cnkgewogICAgICAgICAgICBpbnQgZmxhZ3MgPSAoaW50KShzeW0uZmxhZ3MoKSAmIEFjY2Vzc0ZsYWdzKTsKICAgICAgICAgICAgc3dpdGNoIChmbGFncykgewogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBjYXNlIFBVQkxJQzoKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICBjYXNlIFBSSVZBVEU6CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgY2FzZSBQUk9URUNURUQ6CiAgICAgICAgICAgICAgICByZXR1cm4gc3ltLnBhY2tnZSgpID09IHBhY2tnZTsKICAgICAgICAgICAgfQogICAgICAgIH0gY2F0Y2ggKENsYXNzRmluZGVyLkJhZENsYXNzRmlsZSBlcnIpIHsKICAgICAgICAgICAgdGhyb3cgZXJyOwogICAgICAgIH0gY2F0Y2ggKENvbXBsZXRpb25GYWlsdXJlIGV4KSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHZvaWQgY2hlY2tMZWFrc05vdEFjY2Vzc2libGUoRW52PEF0dHJDb250ZXh0PiBlbnYsIEpDQ2xhc3NEZWNsIGNoZWNrKSB7CiAgICAgICAgSkNDb21waWxhdGlvblVuaXQgdG9wbGV2ZWwgPSBlbnYudG9wbGV2ZWw7CgogICAgICAgIGlmICggICB0b3BsZXZlbC5tb2RsZSA9PSBzeW1zLnVubmFtZWRNb2R1bGUKICAgICAgICAgICAgfHwgdG9wbGV2ZWwubW9kbGUgPT0gc3ltcy5ub01vZHVsZQogICAgICAgICAgICB8fCAoY2hlY2suc3ltLmZsYWdzKCkgJiBDT01QT1VORCkgIT0gMCkgewogICAgICAgICAgICByZXR1cm4gOwogICAgICAgIH0KCiAgICAgICAgRXhwb3J0c0RpcmVjdGl2ZSBjdXJyZW50RXhwb3J0ID0gZmluZEV4cG9ydCh0b3BsZXZlbC5wYWNrZ2UpOwoKICAgICAgICBpZiAoICAgY3VycmVudEV4cG9ydCA9PSBudWxsIC8vbm90IGV4cG9ydGVkCiAgICAgICAgICAgIHx8IGN1cnJlbnRFeHBvcnQubW9kdWxlcyAhPSBudWxsKSAvL2Rvbid0IGNoZWNrIGNsYXNzZXMgaW4gcXVhbGlmaWVkIGV4cG9ydAogICAgICAgICAgICByZXR1cm4gOwoKICAgICAgICBuZXcgVHJlZVNjYW5uZXIoKSB7CiAgICAgICAgICAgIExpbnQgbGludCA9IGVudi5pbmZvLmxpbnQ7CiAgICAgICAgICAgIGJvb2xlYW4gaW5TdXBlclR5cGU7CgogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHVibGljIHZvaWQgdmlzaXRCbG9jayhKQ0Jsb2NrIHRyZWUpIHsKICAgICAgICAgICAgfQogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHVibGljIHZvaWQgdmlzaXRNZXRob2REZWYoSkNNZXRob2REZWNsIHRyZWUpIHsKICAgICAgICAgICAgICAgIGlmICghaXNBUElTeW1ib2wodHJlZS5zeW0pKQogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIExpbnQgcHJldkxpbnQgPSBsaW50OwogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICBsaW50ID0gbGludC5hdWdtZW50KHRyZWUuc3ltKTsKICAgICAgICAgICAgICAgICAgICBpZiAobGludC5pc0VuYWJsZWQoTGludENhdGVnb3J5LkVYUE9SVFMpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHN1cGVyLnZpc2l0TWV0aG9kRGVmKHRyZWUpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgICAgICAgICAgbGludCA9IHByZXZMaW50OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdFZhckRlZihKQ1ZhcmlhYmxlRGVjbCB0cmVlKSB7CiAgICAgICAgICAgICAgICBpZiAoIWlzQVBJU3ltYm9sKHRyZWUuc3ltKSAmJiB0cmVlLnN5bS5vd25lci5raW5kICE9IE1USCkKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICBMaW50IHByZXZMaW50ID0gbGludDsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgbGludCA9IGxpbnQuYXVnbWVudCh0cmVlLnN5bSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKGxpbnQuaXNFbmFibGVkKExpbnRDYXRlZ29yeS5FWFBPUlRTKSkgewogICAgICAgICAgICAgICAgICAgICAgICBzY2FuKHRyZWUubW9kcyk7CiAgICAgICAgICAgICAgICAgICAgICAgIHNjYW4odHJlZS52YXJ0eXBlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAgICAgICAgIGxpbnQgPSBwcmV2TGludDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHVibGljIHZvaWQgdmlzaXRDbGFzc0RlZihKQ0NsYXNzRGVjbCB0cmVlKSB7CiAgICAgICAgICAgICAgICBpZiAodHJlZSAhPSBjaGVjaykKICAgICAgICAgICAgICAgICAgICByZXR1cm4gOwoKICAgICAgICAgICAgICAgIGlmICghaXNBUElTeW1ib2wodHJlZS5zeW0pKQogICAgICAgICAgICAgICAgICAgIHJldHVybiA7CgogICAgICAgICAgICAgICAgTGludCBwcmV2TGludCA9IGxpbnQ7CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIGxpbnQgPSBsaW50LmF1Z21lbnQodHJlZS5zeW0pOwogICAgICAgICAgICAgICAgICAgIGlmIChsaW50LmlzRW5hYmxlZChMaW50Q2F0ZWdvcnkuRVhQT1JUUykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgc2Nhbih0cmVlLm1vZHMpOwogICAgICAgICAgICAgICAgICAgICAgICBzY2FuKHRyZWUudHlwYXJhbXMpOwogICAgICAgICAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5TdXBlclR5cGUgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Nhbih0cmVlLmV4dGVuZGluZyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY2FuKHRyZWUuaW1wbGVtZW50aW5nKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluU3VwZXJUeXBlID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgc2Nhbih0cmVlLmRlZnMpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgICAgICAgICAgbGludCA9IHByZXZMaW50OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdFR5cGVBcHBseShKQ1R5cGVBcHBseSB0cmVlKSB7CiAgICAgICAgICAgICAgICBzY2FuKHRyZWUuY2xhenopOwogICAgICAgICAgICAgICAgYm9vbGVhbiBvbGRJblN1cGVyVHlwZSA9IGluU3VwZXJUeXBlOwogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICBpblN1cGVyVHlwZSA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgIHNjYW4odHJlZS5hcmd1bWVudHMpOwogICAgICAgICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgICAgICAgICBpblN1cGVyVHlwZSA9IG9sZEluU3VwZXJUeXBlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdElkZW50KEpDSWRlbnQgdHJlZSkgewogICAgICAgICAgICAgICAgU3ltYm9sIHN5bSA9IFRyZWVJbmZvLnN5bWJvbCh0cmVlKTsKICAgICAgICAgICAgICAgIGlmIChzeW0ua2luZCA9PSBUWVAgJiYgIXN5bS50eXBlLmhhc1RhZyhUWVBFVkFSKSkgewogICAgICAgICAgICAgICAgICAgIGNoZWNrVmlzaWJsZSh0cmVlLnBvcygpLCBzeW0sIHRvcGxldmVsLnBhY2tnZSwgaW5TdXBlclR5cGUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHVibGljIHZvaWQgdmlzaXRTZWxlY3QoSkNGaWVsZEFjY2VzcyB0cmVlKSB7CiAgICAgICAgICAgICAgICBTeW1ib2wgc3ltID0gVHJlZUluZm8uc3ltYm9sKHRyZWUpOwogICAgICAgICAgICAgICAgU3ltYm9sIHNpdGVzeW0gPSBUcmVlSW5mby5zeW1ib2wodHJlZS5zZWxlY3RlZCk7CiAgICAgICAgICAgICAgICBpZiAoc3ltLmtpbmQgPT0gVFlQICYmIHNpdGVzeW0ua2luZCA9PSBQQ0spIHsKICAgICAgICAgICAgICAgICAgICBjaGVja1Zpc2libGUodHJlZS5wb3MoKSwgc3ltLCB0b3BsZXZlbC5wYWNrZ2UsIGluU3VwZXJUeXBlKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgc3VwZXIudmlzaXRTZWxlY3QodHJlZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdEFubm90YXRpb24oSkNBbm5vdGF0aW9uIHRyZWUpIHsKICAgICAgICAgICAgICAgIGlmICh0cmVlLmF0dHJpYnV0ZS50eXBlLnRzeW0uZ2V0QW5ub3RhdGlvbihqYXZhLmxhbmcuYW5ub3RhdGlvbi5Eb2N1bWVudGVkLmNsYXNzKSAhPSBudWxsKQogICAgICAgICAgICAgICAgICAgIHN1cGVyLnZpc2l0QW5ub3RhdGlvbih0cmVlKTsKICAgICAgICAgICAgfQoKICAgICAgICB9LnNjYW4oY2hlY2spOwogICAgfQogICAgICAgIC8vd2hlcmU6CiAgICAgICAgcHJpdmF0ZSBFeHBvcnRzRGlyZWN0aXZlIGZpbmRFeHBvcnQoUGFja2FnZVN5bWJvbCBwYWNrKSB7CiAgICAgICAgICAgIGZvciAoRXhwb3J0c0RpcmVjdGl2ZSBkIDogcGFjay5tb2RsZS5leHBvcnRzKSB7CiAgICAgICAgICAgICAgICBpZiAoZC5wYWNrZ2UgPT0gcGFjaykKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgICAgIHByaXZhdGUgYm9vbGVhbiBpc0FQSVN5bWJvbChTeW1ib2wgc3ltKSB7CiAgICAgICAgICAgIHdoaWxlIChzeW0ua2luZCAhPSBQQ0spIHsKICAgICAgICAgICAgICAgIGlmICgoc3ltLmZsYWdzKCkgJiBGbGFncy5QVUJMSUMpID09IDAgJiYgKHN5bS5mbGFncygpICYgRmxhZ3MuUFJPVEVDVEVEKSA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgc3ltID0gc3ltLm93bmVyOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KICAgICAgICBwcml2YXRlIHZvaWQgY2hlY2tWaXNpYmxlKERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIFN5bWJvbCB3aGF0LCBQYWNrYWdlU3ltYm9sIGluUGFja2FnZSwgYm9vbGVhbiBpblN1cGVyVHlwZSkgewogICAgICAgICAgICBpZiAoIWlzQVBJU3ltYm9sKHdoYXQpICYmICFpblN1cGVyVHlwZSkgeyAvL3BhY2thZ2UgcHJpdmF0ZS9wcml2YXRlIGVsZW1lbnQKICAgICAgICAgICAgICAgIGxvZy53YXJuaW5nKExpbnRDYXRlZ29yeS5FWFBPUlRTLCBwb3MsIFdhcm5pbmdzLkxlYWtzTm90QWNjZXNzaWJsZShraW5kTmFtZSh3aGF0KSwgd2hhdCwgd2hhdC5wYWNrZ2UoKS5tb2RsZSkpOwogICAgICAgICAgICAgICAgcmV0dXJuIDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgUGFja2FnZVN5bWJvbCB3aGF0UGFja2FnZSA9IHdoYXQucGFja2dlKCk7CiAgICAgICAgICAgIEV4cG9ydHNEaXJlY3RpdmUgd2hhdEV4cG9ydCA9IGZpbmRFeHBvcnQod2hhdFBhY2thZ2UpOwogICAgICAgICAgICBFeHBvcnRzRGlyZWN0aXZlIGluRXhwb3J0ID0gZmluZEV4cG9ydChpblBhY2thZ2UpOwoKICAgICAgICAgICAgaWYgKHdoYXRFeHBvcnQgPT0gbnVsbCkgeyAvL3BhY2thZ2Ugbm90IGV4cG9ydGVkOgogICAgICAgICAgICAgICAgbG9nLndhcm5pbmcoTGludENhdGVnb3J5LkVYUE9SVFMsIHBvcywgV2FybmluZ3MuTGVha3NOb3RBY2Nlc3NpYmxlVW5leHBvcnRlZChraW5kTmFtZSh3aGF0KSwgd2hhdCwgd2hhdC5wYWNrZ2UoKS5tb2RsZSkpOwogICAgICAgICAgICAgICAgcmV0dXJuIDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKHdoYXRFeHBvcnQubW9kdWxlcyAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICBpZiAoaW5FeHBvcnQubW9kdWxlcyA9PSBudWxsIHx8ICF3aGF0RXhwb3J0Lm1vZHVsZXMuY29udGFpbnNBbGwoaW5FeHBvcnQubW9kdWxlcykpIHsKICAgICAgICAgICAgICAgICAgICBsb2cud2FybmluZyhMaW50Q2F0ZWdvcnkuRVhQT1JUUywgcG9zLCBXYXJuaW5ncy5MZWFrc05vdEFjY2Vzc2libGVVbmV4cG9ydGVkUXVhbGlmaWVkKGtpbmROYW1lKHdoYXQpLCB3aGF0LCB3aGF0LnBhY2tnZSgpLm1vZGxlKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICh3aGF0UGFja2FnZS5tb2RsZSAhPSBpblBhY2thZ2UubW9kbGUgJiYgd2hhdFBhY2thZ2UubW9kbGUgIT0gc3ltcy5qYXZhX2Jhc2UpIHsKICAgICAgICAgICAgICAgIC8vY2hlY2sgdGhhdCByZWxhdGl2ZVRvLm1vZGxlIHJlcXVpcmVzIHRyYW5zaXRpdmUgd2hhdC5tb2RsZSwgc29tZWhvdzoKICAgICAgICAgICAgICAgIExpc3Q8TW9kdWxlU3ltYm9sPiB0b2RvID0gTGlzdC5vZihpblBhY2thZ2UubW9kbGUpOwoKICAgICAgICAgICAgICAgIHdoaWxlICh0b2RvLm5vbkVtcHR5KCkpIHsKICAgICAgICAgICAgICAgICAgICBNb2R1bGVTeW1ib2wgY3VycmVudCA9IHRvZG8uaGVhZDsKICAgICAgICAgICAgICAgICAgICB0b2RvID0gdG9kby50YWlsOwogICAgICAgICAgICAgICAgICAgIGlmIChjdXJyZW50ID09IHdoYXRQYWNrYWdlLm1vZGxlKQogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gOyAvL09LCiAgICAgICAgICAgICAgICAgICAgZm9yIChSZXF1aXJlc0RpcmVjdGl2ZSByZXEgOiBjdXJyZW50LnJlcXVpcmVzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXEuaXNUcmFuc2l0aXZlKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvZG8gPSB0b2RvLnByZXBlbmQocmVxLm1vZHVsZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgbG9nLndhcm5pbmcoTGludENhdGVnb3J5LkVYUE9SVFMsIHBvcywgV2FybmluZ3MuTGVha3NOb3RBY2Nlc3NpYmxlTm90UmVxdWlyZWRUcmFuc2l0aXZlKGtpbmROYW1lKHdoYXQpLCB3aGF0LCB3aGF0LnBhY2tnZSgpLm1vZGxlKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgdm9pZCBjaGVja01vZHVsZUV4aXN0cyhmaW5hbCBEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBNb2R1bGVTeW1ib2wgbXN5bSkgewogICAgICAgIGlmIChtc3ltLmtpbmQgIT0gTURMKSB7CiAgICAgICAgICAgIGRlZmVycmVkTGludEhhbmRsZXIucmVwb3J0KCgpIC0+IHsKICAgICAgICAgICAgICAgIGlmIChsaW50LmlzRW5hYmxlZChMaW50Q2F0ZWdvcnkuTU9EVUxFKSkKICAgICAgICAgICAgICAgICAgICBsb2cud2FybmluZyhMaW50Q2F0ZWdvcnkuTU9EVUxFLCBwb3MsIFdhcm5pbmdzLk1vZHVsZU5vdEZvdW5kKG1zeW0pKTsKICAgICAgICAgICAgfSk7CiAgICAgICAgfQogICAgfQoKICAgIHZvaWQgY2hlY2tQYWNrYWdlRXhpc3RzRm9yT3BlbnMoZmluYWwgRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcywgUGFja2FnZVN5bWJvbCBwYWNrZ2UpIHsKICAgICAgICBpZiAocGFja2dlLm1lbWJlcnMoKS5pc0VtcHR5KCkgJiYKICAgICAgICAgICAgKChwYWNrZ2UuZmxhZ3MoKSAmIEZsYWdzLkhBU19SRVNPVVJDRSkgPT0gMCkpIHsKICAgICAgICAgICAgZGVmZXJyZWRMaW50SGFuZGxlci5yZXBvcnQoKCkgLT4gewogICAgICAgICAgICAgICAgaWYgKGxpbnQuaXNFbmFibGVkKExpbnRDYXRlZ29yeS5PUEVOUykpCiAgICAgICAgICAgICAgICAgICAgbG9nLndhcm5pbmcocG9zLCBXYXJuaW5ncy5QYWNrYWdlRW1wdHlPck5vdEZvdW5kKHBhY2tnZSkpOwogICAgICAgICAgICB9KTsKICAgICAgICB9CiAgICB9Cgp9ClBLAwQKAAAIAAAGO6lK3cgcohqhAAAaoQAAKAAAAGNvbS9zdW4vdG9vbHMvamF2YWMvY29tcC9UcmFuc1R5cGVzLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDE5OTksIDIwMTUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhYy5jb21wOwoKaW1wb3J0IGphdmEudXRpbC4qOwoKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS4qOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLkF0dHJpYnV0ZS5UeXBlQ29tcG91bmQ7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuU3ltYm9sLio7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuKjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5KQ1RyZWUuKjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5KQ1RyZWUuSkNNZW1iZXJSZWZlcmVuY2UuUmVmZXJlbmNlS2luZDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC4qOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkpDRGlhZ25vc3RpYy5EaWFnbm9zdGljUG9zaXRpb247CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuTGlzdDsKCmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLkZsYWdzLio7CmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLktpbmRzLktpbmQuKjsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuU2NvcGUuTG9va3VwS2luZC5OT05fUkVDVVJTSVZFOwppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5UeXBlVGFnLkNMQVNTOwppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5UeXBlVGFnLlRZUEVWQVI7CmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlR5cGVUYWcuVk9JRDsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmNvbXAuQ29tcGlsZVN0YXRlcy5Db21waWxlU3RhdGU7CgovKiogVGhpcyBwYXNzIHRyYW5zbGF0ZXMgR2VuZXJpYyBKYXZhIHRvIGNvbnZlbnRpb25hbCBKYXZhLgogKgogKiAgPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24gcmlzay4KICogIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yCiAqICBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+CiAqLwpwdWJsaWMgY2xhc3MgVHJhbnNUeXBlcyBleHRlbmRzIFRyZWVUcmFuc2xhdG9yIHsKICAgIC8qKiBUaGUgY29udGV4dCBrZXkgZm9yIHRoZSBUcmFuc1R5cGVzIHBoYXNlLiAqLwogICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBDb250ZXh0LktleTxUcmFuc1R5cGVzPiB0cmFuc1R5cGVzS2V5ID0gbmV3IENvbnRleHQuS2V5PD4oKTsKCiAgICAvKiogR2V0IHRoZSBpbnN0YW5jZSBmb3IgdGhpcyBjb250ZXh0LiAqLwogICAgcHVibGljIHN0YXRpYyBUcmFuc1R5cGVzIGluc3RhbmNlKENvbnRleHQgY29udGV4dCkgewogICAgICAgIFRyYW5zVHlwZXMgaW5zdGFuY2UgPSBjb250ZXh0LmdldCh0cmFuc1R5cGVzS2V5KTsKICAgICAgICBpZiAoaW5zdGFuY2UgPT0gbnVsbCkKICAgICAgICAgICAgaW5zdGFuY2UgPSBuZXcgVHJhbnNUeXBlcyhjb250ZXh0KTsKICAgICAgICByZXR1cm4gaW5zdGFuY2U7CiAgICB9CgogICAgcHJpdmF0ZSBOYW1lcyBuYW1lczsKICAgIHByaXZhdGUgTG9nIGxvZzsKICAgIHByaXZhdGUgU3ltdGFiIHN5bXM7CiAgICBwcml2YXRlIFRyZWVNYWtlciBtYWtlOwogICAgcHJpdmF0ZSBFbnRlciBlbnRlcjsKICAgIHByaXZhdGUgVHlwZXMgdHlwZXM7CiAgICBwcml2YXRlIEFubm90YXRlIGFubm90YXRlOwogICAgcHJpdmF0ZSBmaW5hbCBSZXNvbHZlIHJlc29sdmU7CiAgICBwcml2YXRlIGZpbmFsIENvbXBpbGVTdGF0ZXMgY29tcGlsZVN0YXRlczsKCiAgICAvKiogU3dpdGNoOiBpcyBjb21wbGV4IGdyYXBoIGluZmVyZW5jZSBzdXBwb3J0ZWQ/ICovCiAgICBwcml2YXRlIGZpbmFsIGJvb2xlYW4gYWxsb3dHcmFwaEluZmVyZW5jZTsKCiAgICAvKiogU3dpdGNoOiBhcmUgZGVmYXVsdCBtZXRob2RzIHN1cHBvcnRlZD8gKi8KICAgIHByaXZhdGUgZmluYWwgYm9vbGVhbiBhbGxvd0ludGVyZmFjZUJyaWRnZXM7CgogICAgcHJpdmF0ZSBmaW5hbCBib29sZWFuIHNraXBEdXBsaWNhdGVCcmlkZ2VzOwoKICAgIHByb3RlY3RlZCBUcmFuc1R5cGVzKENvbnRleHQgY29udGV4dCkgewogICAgICAgIGNvbnRleHQucHV0KHRyYW5zVHlwZXNLZXksIHRoaXMpOwogICAgICAgIGNvbXBpbGVTdGF0ZXMgPSBDb21waWxlU3RhdGVzLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIG5hbWVzID0gTmFtZXMuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgbG9nID0gTG9nLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIHN5bXMgPSBTeW10YWIuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgZW50ZXIgPSBFbnRlci5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBicmlkZ2VTcGFucyA9IG5ldyBIYXNoTWFwPD4oKTsKICAgICAgICB0eXBlcyA9IFR5cGVzLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIG1ha2UgPSBUcmVlTWFrZXIuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgcmVzb2x2ZSA9IFJlc29sdmUuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgU291cmNlIHNvdXJjZSA9IFNvdXJjZS5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBhbGxvd0ludGVyZmFjZUJyaWRnZXMgPSBzb3VyY2UuYWxsb3dEZWZhdWx0TWV0aG9kcygpOwogICAgICAgIGFsbG93R3JhcGhJbmZlcmVuY2UgPSBzb3VyY2UuYWxsb3dHcmFwaEluZmVyZW5jZSgpOwogICAgICAgIHNraXBEdXBsaWNhdGVCcmlkZ2VzID0gT3B0aW9ucy5pbnN0YW5jZShjb250ZXh0KS5nZXRCb29sZWFuKCJza2lwRHVwbGljYXRlQnJpZGdlcyIsIGZhbHNlKTsKICAgICAgICBhbm5vdGF0ZSA9IEFubm90YXRlLmluc3RhbmNlKGNvbnRleHQpOwogICAgfQoKICAgIC8qKiBBIGhhc2h0YWJsZSBtYXBwaW5nIGJyaWRnZSBtZXRob2RzIHRvIHRoZSBwYWlyIG9mIG1ldGhvZHMgdGhleSBicmlkZ2UuCiAgICAgKiAgVGhlIGJyaWRnZSBvdmVycmlkZXMgdGhlIGZpcnN0IG9mIHRoZSBwYWlyIGFmdGVyIHR5cGUgZXJhc3VyZSBhbmQgZGVmbGVjdHMKICAgICAqICB0byB0aGUgc2Vjb25kIG9mIHRoZSBwYWlyICh3aGljaCBkaWZmZXJzIGluIHR5cGUgZXJhc3VyZSBmcm9tIHRoZSBvbmUKICAgICAqICBpdCBvdmVycmlkZXMgdGhlcmVieSBuZWNlc3NpdGF0aW5nIHRoZSBicmlkZ2UpCiAgICAgKi8KICAgIE1hcDxNZXRob2RTeW1ib2wsIFBhaXI8TWV0aG9kU3ltYm9sLCBNZXRob2RTeW1ib2w+PiBicmlkZ2VTcGFuczsKCiAgICAvKiogQ29uc3RydWN0IGFuIGF0dHJpYnV0ZWQgdHJlZSBmb3IgYSBjYXN0IG9mIGV4cHJlc3Npb24gdG8gdGFyZ2V0IHR5cGUsCiAgICAgKiAgdW5sZXNzIGl0IGFscmVhZHkgaGFzIHByZWNpc2VseSB0aGF0IHR5cGUuCiAgICAgKiAgQHBhcmFtIHRyZWUgICAgVGhlIGV4cHJlc3Npb24gdHJlZS4KICAgICAqICBAcGFyYW0gdGFyZ2V0ICBUaGUgdGFyZ2V0IHR5cGUuCiAgICAgKi8KICAgIEpDRXhwcmVzc2lvbiBjYXN0KEpDRXhwcmVzc2lvbiB0cmVlLCBUeXBlIHRhcmdldCkgewogICAgICAgIGludCBvbGRwb3MgPSBtYWtlLnBvczsKICAgICAgICBtYWtlLmF0KHRyZWUucG9zKTsKICAgICAgICBpZiAoIXR5cGVzLmlzU2FtZVR5cGUodHJlZS50eXBlLCB0YXJnZXQpKSB7CiAgICAgICAgICAgIGlmICghcmVzb2x2ZS5pc0FjY2Vzc2libGUoZW52LCB0YXJnZXQudHN5bSkpCiAgICAgICAgICAgICAgICByZXNvbHZlLmxvZ0FjY2Vzc0Vycm9ySW50ZXJuYWwoZW52LCB0cmVlLCB0YXJnZXQpOwogICAgICAgICAgICB0cmVlID0gbWFrZS5UeXBlQ2FzdChtYWtlLlR5cGUodGFyZ2V0KSwgdHJlZSkuc2V0VHlwZSh0YXJnZXQpOwogICAgICAgIH0KICAgICAgICBtYWtlLnBvcyA9IG9sZHBvczsKICAgICAgICByZXR1cm4gdHJlZTsKICAgIH0KCiAgICAvKiogQ29uc3RydWN0IGFuIGF0dHJpYnV0ZWQgdHJlZSB0byBjb2VyY2UgYW4gZXhwcmVzc2lvbiB0byBzb21lIGVyYXNlZAogICAgICogIHRhcmdldCB0eXBlLCB1bmxlc3MgdGhlIGV4cHJlc3Npb24gaXMgYWxyZWFkeSBhc3NpZ25hYmxlIHRvIHRoYXQgdHlwZS4KICAgICAqICBJZiB0YXJnZXQgdHlwZSBpcyBhIGNvbnN0YW50IHR5cGUsIHVzZSBpdHMgYmFzZSB0eXBlIGluc3RlYWQuCiAgICAgKiAgQHBhcmFtIHRyZWUgICAgVGhlIGV4cHJlc3Npb24gdHJlZS4KICAgICAqICBAcGFyYW0gdGFyZ2V0ICBUaGUgdGFyZ2V0IHR5cGUuCiAgICAgKi8KICAgIHB1YmxpYyBKQ0V4cHJlc3Npb24gY29lcmNlKEVudjxBdHRyQ29udGV4dD4gZW52LCBKQ0V4cHJlc3Npb24gdHJlZSwgVHlwZSB0YXJnZXQpIHsKICAgICAgICBFbnY8QXR0ckNvbnRleHQ+IHByZXZFbnYgPSB0aGlzLmVudjsKICAgICAgICB0cnkgewogICAgICAgICAgICB0aGlzLmVudiA9IGVudjsKICAgICAgICAgICAgcmV0dXJuIGNvZXJjZSh0cmVlLCB0YXJnZXQpOwogICAgICAgIH0KICAgICAgICBmaW5hbGx5IHsKICAgICAgICAgICAgdGhpcy5lbnYgPSBwcmV2RW52OwogICAgICAgIH0KICAgIH0KICAgIEpDRXhwcmVzc2lvbiBjb2VyY2UoSkNFeHByZXNzaW9uIHRyZWUsIFR5cGUgdGFyZ2V0KSB7CiAgICAgICAgVHlwZSBidGFyZ2V0ID0gdGFyZ2V0LmJhc2VUeXBlKCk7CiAgICAgICAgaWYgKHRyZWUudHlwZS5pc1ByaW1pdGl2ZSgpID09IHRhcmdldC5pc1ByaW1pdGl2ZSgpKSB7CiAgICAgICAgICAgIHJldHVybiB0eXBlcy5pc0Fzc2lnbmFibGUodHJlZS50eXBlLCBidGFyZ2V0LCB0eXBlcy5ub1dhcm5pbmdzKQogICAgICAgICAgICAgICAgPyB0cmVlCiAgICAgICAgICAgICAgICA6IGNhc3QodHJlZSwgYnRhcmdldCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0cmVlOwogICAgfQoKICAgIC8qKiBHaXZlbiBhbiBlcmFzZWQgcmVmZXJlbmNlIHR5cGUsIGFzc3VtZSB0aGlzIHR5cGUgYXMgdGhlIHRyZWUncyB0eXBlLgogICAgICogIFRoZW4sIGNvZXJjZSB0byBzb21lIGdpdmVuIHRhcmdldCB0eXBlIHVubGVzcyB0YXJnZXQgdHlwZSBpcyBudWxsLgogICAgICogIFRoaXMgb3BlcmF0aW9uIGlzIHVzZWQgaW4gc2l0dWF0aW9ucyBsaWtlIHRoZSBmb2xsb3dpbmc6CiAgICAgKgogICAgICogIDxwcmU+e0Bjb2RlCiAgICAgKiAgY2xhc3MgQ2VsbDxBPiB7IEEgdmFsdWU7IH0KICAgICAqICAuLi4KICAgICAqICBDZWxsPEludGVnZXI+IGNlbGw7CiAgICAgKiAgSW50ZWdlciB4ID0gY2VsbC52YWx1ZTsKICAgICAqICB9PC9wcmU+CiAgICAgKgogICAgICogIFNpbmNlIHRoZSBlcmFzdXJlIG9mIENlbGwudmFsdWUgaXMgT2JqZWN0LCBidXQgdGhlIHR5cGUKICAgICAqICBvZiBjZWxsLnZhbHVlIGluIHRoZSBhc3NpZ25tZW50IGlzIEludGVnZXIsIHdlIG5lZWQgdG8KICAgICAqICBhZGp1c3QgdGhlIG9yaWdpbmFsIHR5cGUgb2YgY2VsbC52YWx1ZSB0byBPYmplY3QsIGFuZCBpbnNlcnQKICAgICAqICBhIGNhc3QgdG8gSW50ZWdlci4gVGhhdCBpcywgdGhlIGxhc3QgYXNzaWdubWVudCBiZWNvbWVzOgogICAgICoKICAgICAqICA8cHJlPntAY29kZQogICAgICogIEludGVnZXIgeCA9IChJbnRlZ2VyKWNlbGwudmFsdWU7CiAgICAgKiAgfTwvcHJlPgogICAgICoKICAgICAqICBAcGFyYW0gdHJlZSAgICAgICBUaGUgZXhwcmVzc2lvbiB0cmVlIHdob3NlIHR5cGUgbWlnaHQgbmVlZCBhZGp1c3RtZW50LgogICAgICogIEBwYXJhbSBlcmFzZWRUeXBlIFRoZSBleHByZXNzaW9uJ3MgdHlwZSBhZnRlciBlcmFzdXJlLgogICAgICogIEBwYXJhbSB0YXJnZXQgICAgIFRoZSB0YXJnZXQgdHlwZSwgd2hpY2ggaXMgdXN1YWxseSB0aGUgZXJhc3VyZSBvZiB0aGUKICAgICAqICAgICAgICAgICAgICAgICAgICBleHByZXNzaW9uJ3Mgb3JpZ2luYWwgdHlwZS4KICAgICAqLwogICAgSkNFeHByZXNzaW9uIHJldHlwZShKQ0V4cHJlc3Npb24gdHJlZSwgVHlwZSBlcmFzZWRUeXBlLCBUeXBlIHRhcmdldCkgewovLyAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigicmV0eXBlICIgKyB0cmVlICsgIiB0byAiICsgZXJhc2VkVHlwZSk7Ly9ERUJVRwogICAgICAgIGlmICghZXJhc2VkVHlwZS5pc1ByaW1pdGl2ZSgpKSB7CiAgICAgICAgICAgIGlmICh0YXJnZXQgIT0gbnVsbCAmJiB0YXJnZXQuaXNQcmltaXRpdmUoKSkgewogICAgICAgICAgICAgICAgdGFyZ2V0ID0gZXJhc3VyZSh0cmVlLnR5cGUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHRyZWUudHlwZSA9IGVyYXNlZFR5cGU7CiAgICAgICAgICAgIGlmICh0YXJnZXQgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgcmV0dXJuIGNvZXJjZSh0cmVlLCB0YXJnZXQpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiB0cmVlOwogICAgfQoKICAgIC8qKiBUcmFuc2xhdGUgbWV0aG9kIGFyZ3VtZW50IGxpc3QsIGNhc3RpbmcgZWFjaCBhcmd1bWVudAogICAgICogIHRvIGl0cyBjb3JyZXNwb25kaW5nIHR5cGUgaW4gYSBsaXN0IG9mIHRhcmdldCB0eXBlcy4KICAgICAqICBAcGFyYW0gX2FyZ3MgICAgICAgICAgICBUaGUgbWV0aG9kIGFyZ3VtZW50IGxpc3QuCiAgICAgKiAgQHBhcmFtIHBhcmFtZXRlcnMgICAgICAgVGhlIGxpc3Qgb2YgdGFyZ2V0IHR5cGVzLgogICAgICogIEBwYXJhbSB2YXJhcmdzRWxlbWVudCAgIFRoZSBlcmFzdXJlIG9mIHRoZSB2YXJhcmdzIGVsZW1lbnQgdHlwZSwKICAgICAqICBvciBudWxsIGlmIHRyYW5zbGF0aW5nIGEgbm9uLXZhcmFyZ3MgaW52b2NhdGlvbgogICAgICovCiAgICA8VCBleHRlbmRzIEpDVHJlZT4gTGlzdDxUPiB0cmFuc2xhdGVBcmdzKExpc3Q8VD4gX2FyZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IHBhcmFtZXRlcnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUeXBlIHZhcmFyZ3NFbGVtZW50KSB7CiAgICAgICAgaWYgKHBhcmFtZXRlcnMuaXNFbXB0eSgpKSByZXR1cm4gX2FyZ3M7CiAgICAgICAgTGlzdDxUPiBhcmdzID0gX2FyZ3M7CiAgICAgICAgd2hpbGUgKHBhcmFtZXRlcnMudGFpbC5ub25FbXB0eSgpKSB7CiAgICAgICAgICAgIGFyZ3MuaGVhZCA9IHRyYW5zbGF0ZShhcmdzLmhlYWQsIHBhcmFtZXRlcnMuaGVhZCk7CiAgICAgICAgICAgIGFyZ3MgPSBhcmdzLnRhaWw7CiAgICAgICAgICAgIHBhcmFtZXRlcnMgPSBwYXJhbWV0ZXJzLnRhaWw7CiAgICAgICAgfQogICAgICAgIFR5cGUgcGFyYW1ldGVyID0gcGFyYW1ldGVycy5oZWFkOwogICAgICAgIEFzc2VydC5jaGVjayh2YXJhcmdzRWxlbWVudCAhPSBudWxsIHx8IGFyZ3MubGVuZ3RoKCkgPT0gMSk7CiAgICAgICAgaWYgKHZhcmFyZ3NFbGVtZW50ICE9IG51bGwpIHsKICAgICAgICAgICAgd2hpbGUgKGFyZ3Mubm9uRW1wdHkoKSkgewogICAgICAgICAgICAgICAgYXJncy5oZWFkID0gdHJhbnNsYXRlKGFyZ3MuaGVhZCwgdmFyYXJnc0VsZW1lbnQpOwogICAgICAgICAgICAgICAgYXJncyA9IGFyZ3MudGFpbDsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGFyZ3MuaGVhZCA9IHRyYW5zbGF0ZShhcmdzLmhlYWQsIHBhcmFtZXRlcik7CiAgICAgICAgfQogICAgICAgIHJldHVybiBfYXJnczsKICAgIH0KCiAgICBwdWJsaWMgPFQgZXh0ZW5kcyBKQ1RyZWU+IExpc3Q8VD4gdHJhbnNsYXRlQXJncyhMaXN0PFQ+IF9hcmdzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTGlzdDxUeXBlPiBwYXJhbWV0ZXJzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVHlwZSB2YXJhcmdzRWxlbWVudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVudjxBdHRyQ29udGV4dD4gbG9jYWxFbnYpIHsKICAgICAgICBFbnY8QXR0ckNvbnRleHQ+IHByZXZFbnYgPSBlbnY7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgZW52ID0gbG9jYWxFbnY7CiAgICAgICAgICAgIHJldHVybiB0cmFuc2xhdGVBcmdzKF9hcmdzLCBwYXJhbWV0ZXJzLCB2YXJhcmdzRWxlbWVudCk7CiAgICAgICAgfQogICAgICAgIGZpbmFsbHkgewogICAgICAgICAgICBlbnYgPSBwcmV2RW52OwogICAgICAgIH0KICAgIH0KCiAgICAvKiogQWRkIGEgYnJpZGdlIGRlZmluaXRpb24gYW5kIGVudGVyIGNvcnJlc3BvbmRpbmcgbWV0aG9kIHN5bWJvbCBpbgogICAgICogIGxvY2FsIHNjb3BlIG9mIG9yaWdpbi4KICAgICAqCiAgICAgKiAgQHBhcmFtIHBvcyAgICAgVGhlIHNvdXJjZSBjb2RlIHBvc2l0aW9uIHRvIGJlIHVzZWQgZm9yIHRoZSBkZWZpbml0aW9uLgogICAgICogIEBwYXJhbSBtZXRoICAgIFRoZSBtZXRob2QgZm9yIHdoaWNoIGEgYnJpZGdlIG5lZWRzIHRvIGJlIGFkZGVkCiAgICAgKiAgQHBhcmFtIGltcGwgICAgVGhhdCBtZXRob2QncyBpbXBsZW1lbnRhdGlvbiAocG9zc2libHkgdGhlIG1ldGhvZCBpdHNlbGYpCiAgICAgKiAgQHBhcmFtIG9yaWdpbiAgVGhlIGNsYXNzIHRvIHdoaWNoIHRoZSBicmlkZ2Ugd2lsbCBiZSBhZGRlZAogICAgICogIEBwYXJhbSBoeXBvdGhldGljYWwKICAgICAqICAgICAgICAgICAgICAgICBUcnVlIGlmIHRoZSBicmlkZ2UgbWV0aG9kIGlzIG5vdCBzdHJpY3RseSBuZWNlc3NhcnkgaW4gdGhlCiAgICAgKiAgICAgICAgICAgICAgICAgYmluYXJ5LCBidXQgaXMgcmVwcmVzZW50ZWQgaW4gdGhlIHN5bWJvbCB0YWJsZSB0byBkZXRlY3QKICAgICAqICAgICAgICAgICAgICAgICBlcmFzdXJlIGNsYXNoZXMuCiAgICAgKiAgQHBhcmFtIGJyaWRnZXMgVGhlIGxpc3QgYnVmZmVyIHRvIHdoaWNoIHRoZSBicmlkZ2Ugd2lsbCBiZSBhZGRlZAogICAgICovCiAgICB2b2lkIGFkZEJyaWRnZShEaWFnbm9zdGljUG9zaXRpb24gcG9zLAogICAgICAgICAgICAgICAgICAgTWV0aG9kU3ltYm9sIG1ldGgsCiAgICAgICAgICAgICAgICAgICBNZXRob2RTeW1ib2wgaW1wbCwKICAgICAgICAgICAgICAgICAgIENsYXNzU3ltYm9sIG9yaWdpbiwKICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gaHlwb3RoZXRpY2FsLAogICAgICAgICAgICAgICAgICAgTGlzdEJ1ZmZlcjxKQ1RyZWU+IGJyaWRnZXMpIHsKICAgICAgICBtYWtlLmF0KHBvcyk7CiAgICAgICAgVHlwZSBvcmlnVHlwZSA9IHR5cGVzLm1lbWJlclR5cGUob3JpZ2luLnR5cGUsIG1ldGgpOwogICAgICAgIFR5cGUgb3JpZ0VyYXN1cmUgPSBlcmFzdXJlKG9yaWdUeXBlKTsKCiAgICAgICAgLy8gQ3JlYXRlIGEgYnJpZGdlIG1ldGhvZCBzeW1ib2wgYW5kIGEgYnJpZGdlIGRlZmluaXRpb24gd2l0aG91dCBhIGJvZHkuCiAgICAgICAgVHlwZSBicmlkZ2VUeXBlID0gbWV0aC5lcmFzdXJlKHR5cGVzKTsKICAgICAgICBsb25nIGZsYWdzID0gaW1wbC5mbGFncygpICYgQWNjZXNzRmxhZ3MgfCBTWU5USEVUSUMgfCBCUklER0UgfAogICAgICAgICAgICAgICAgKG9yaWdpbi5pc0ludGVyZmFjZSgpID8gREVGQVVMVCA6IDApOwogICAgICAgIGlmIChoeXBvdGhldGljYWwpIGZsYWdzIHw9IEhZUE9USEVUSUNBTDsKICAgICAgICBNZXRob2RTeW1ib2wgYnJpZGdlID0gbmV3IE1ldGhvZFN5bWJvbChmbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRoLm5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJpZGdlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmlnaW4pOwogICAgICAgIC8qIG9uY2UgSkRLLTY5OTY0MTUgaXMgc29sdmVkIGl0IHNob3VsZCBiZSBjaGVja2VkIGlmIHRoaXMgYXBwcm9hY2ggY2FuCiAgICAgICAgICogYmUgYXBwbGllZCB0byBtZXRob2QgYWRkT3ZlcnJpZGVCcmlkZ2VzSWZOZWVkZWQKICAgICAgICAgKi8KICAgICAgICBicmlkZ2UucGFyYW1zID0gY3JlYXRlQnJpZGdlUGFyYW1zKGltcGwsIGJyaWRnZSwgYnJpZGdlVHlwZSk7CiAgICAgICAgYnJpZGdlLnNldEF0dHJpYnV0ZXMoaW1wbCk7CgogICAgICAgIGlmICghaHlwb3RoZXRpY2FsKSB7CiAgICAgICAgICAgIEpDTWV0aG9kRGVjbCBtZCA9IG1ha2UuTWV0aG9kRGVmKGJyaWRnZSwgbnVsbCk7CgogICAgICAgICAgICAvLyBUaGUgYnJpZGdlIGNhbGxzIHRoaXMuaW1wbCguLiksIGlmIHdlIGhhdmUgYW4gaW1wbGVtZW50YXRpb24KICAgICAgICAgICAgLy8gaW4gdGhlIGN1cnJlbnQgY2xhc3MsIHN1cGVyLmltcGwoLi4uKSBvdGhlcndpc2UuCiAgICAgICAgICAgIEpDRXhwcmVzc2lvbiByZWNlaXZlciA9IChpbXBsLm93bmVyID09IG9yaWdpbikKICAgICAgICAgICAgICAgID8gbWFrZS5UaGlzKG9yaWdpbi5lcmFzdXJlKHR5cGVzKSkKICAgICAgICAgICAgICAgIDogbWFrZS5TdXBlcih0eXBlcy5zdXBlcnR5cGUob3JpZ2luLnR5cGUpLnRzeW0uZXJhc3VyZSh0eXBlcyksIG9yaWdpbik7CgogICAgICAgICAgICAvLyBUaGUgdHlwZSByZXR1cm5lZCBmcm9tIHRoZSBvcmlnaW5hbCBtZXRob2QuCiAgICAgICAgICAgIFR5cGUgY2FsbHR5cGUgPSBlcmFzdXJlKGltcGwudHlwZS5nZXRSZXR1cm5UeXBlKCkpOwoKICAgICAgICAgICAgLy8gQ29uc3RydWN0IGEgY2FsbCBvZiAgdGhpcy5pbXBsKHBhcmFtcyksIG9yIHN1cGVyLmltcGwocGFyYW1zKSwKICAgICAgICAgICAgLy8gY2FzdGluZyBwYXJhbXMgYW5kIHBvc3NpYmx5IHJlc3VsdHMgYXMgbmVlZGVkLgogICAgICAgICAgICBKQ0V4cHJlc3Npb24gY2FsbCA9CiAgICAgICAgICAgICAgICBtYWtlLkFwcGx5KAogICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsLAogICAgICAgICAgICAgICAgICAgICAgICAgICBtYWtlLlNlbGVjdChyZWNlaXZlciwgaW1wbCkuc2V0VHlwZShjYWxsdHlwZSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zbGF0ZUFyZ3MobWFrZS5JZGVudHMobWQucGFyYW1zKSwgb3JpZ0VyYXN1cmUuZ2V0UGFyYW1ldGVyVHlwZXMoKSwgbnVsbCkpCiAgICAgICAgICAgICAgICAuc2V0VHlwZShjYWxsdHlwZSk7CiAgICAgICAgICAgIEpDU3RhdGVtZW50IHN0YXQgPSAob3JpZ0VyYXN1cmUuZ2V0UmV0dXJuVHlwZSgpLmhhc1RhZyhWT0lEKSkKICAgICAgICAgICAgICAgID8gbWFrZS5FeGVjKGNhbGwpCiAgICAgICAgICAgICAgICA6IG1ha2UuUmV0dXJuKGNvZXJjZShjYWxsLCBicmlkZ2VUeXBlLmdldFJldHVyblR5cGUoKSkpOwogICAgICAgICAgICBtZC5ib2R5ID0gbWFrZS5CbG9jaygwLCBMaXN0Lm9mKHN0YXQpKTsKCiAgICAgICAgICAgIC8vIEFkZCBicmlkZ2UgdG8gYGJyaWRnZXMnIGJ1ZmZlcgogICAgICAgICAgICBicmlkZ2VzLmFwcGVuZChtZCk7CiAgICAgICAgfQoKICAgICAgICAvLyBBZGQgYnJpZGdlIHRvIHNjb3BlIG9mIGVuY2xvc2luZyBjbGFzcyBhbmQga2VlcCB0cmFjayBvZiB0aGUgYnJpZGdlIHNwYW4uCiAgICAgICAgb3JpZ2luLm1lbWJlcnMoKS5lbnRlcihicmlkZ2UpOwogICAgICAgIGJyaWRnZVNwYW5zLnB1dChicmlkZ2UsIG5ldyBQYWlyPD4obWV0aCwgaW1wbCkpOwogICAgfQoKICAgIHByaXZhdGUgTGlzdDxWYXJTeW1ib2w+IGNyZWF0ZUJyaWRnZVBhcmFtcyhNZXRob2RTeW1ib2wgaW1wbCwgTWV0aG9kU3ltYm9sIGJyaWRnZSwKICAgICAgICAgICAgVHlwZSBicmlkZ2VUeXBlKSB7CiAgICAgICAgTGlzdDxWYXJTeW1ib2w+IGJyaWRnZVBhcmFtcyA9IG51bGw7CiAgICAgICAgaWYgKGltcGwucGFyYW1zICE9IG51bGwpIHsKICAgICAgICAgICAgYnJpZGdlUGFyYW1zID0gTGlzdC5uaWwoKTsKICAgICAgICAgICAgTGlzdDxWYXJTeW1ib2w+IGltcGxQYXJhbXMgPSBpbXBsLnBhcmFtczsKICAgICAgICAgICAgVHlwZS5NZXRob2RUeXBlIG1UeXBlID0gKFR5cGUuTWV0aG9kVHlwZSlicmlkZ2VUeXBlOwogICAgICAgICAgICBMaXN0PFR5cGU+IGFyZ1R5cGVzID0gbVR5cGUuYXJndHlwZXM7CiAgICAgICAgICAgIHdoaWxlIChpbXBsUGFyYW1zLm5vbkVtcHR5KCkgJiYgYXJnVHlwZXMubm9uRW1wdHkoKSkgewogICAgICAgICAgICAgICAgVmFyU3ltYm9sIHBhcmFtID0gbmV3IFZhclN5bWJvbChpbXBsUGFyYW1zLmhlYWQuZmxhZ3MoKSB8IFNZTlRIRVRJQyB8IFBBUkFNRVRFUiwKICAgICAgICAgICAgICAgICAgICAgICAgaW1wbFBhcmFtcy5oZWFkLm5hbWUsIGFyZ1R5cGVzLmhlYWQsIGJyaWRnZSk7CiAgICAgICAgICAgICAgICBwYXJhbS5zZXRBdHRyaWJ1dGVzKGltcGxQYXJhbXMuaGVhZCk7CiAgICAgICAgICAgICAgICBicmlkZ2VQYXJhbXMgPSBicmlkZ2VQYXJhbXMuYXBwZW5kKHBhcmFtKTsKICAgICAgICAgICAgICAgIGltcGxQYXJhbXMgPSBpbXBsUGFyYW1zLnRhaWw7CiAgICAgICAgICAgICAgICBhcmdUeXBlcyA9IGFyZ1R5cGVzLnRhaWw7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJyaWRnZVBhcmFtczsKICAgIH0KCiAgICAvKiogQWRkIGJyaWRnZSBpZiBnaXZlbiBzeW1ib2wgaXMgYSBub24tcHJpdmF0ZSwgbm9uLXN0YXRpYyBtZW1iZXIKICAgICAqICBvZiB0aGUgZ2l2ZW4gY2xhc3MsIHdoaWNoIGlzIGVpdGhlciBkZWZpbmVkIGluIHRoZSBjbGFzcyBvciBub24tZmluYWwKICAgICAqICBpbmhlcml0ZWQsIGFuZCBvbmUgb2YgdGhlIHR3byBmb2xsb3dpbmcgY29uZGl0aW9ucyBob2xkczoKICAgICAqICAxLiBUaGUgbWV0aG9kJ3MgdHlwZSBjaGFuZ2VzIGluIHRoZSBnaXZlbiBjbGFzcywgYXMgY29tcGFyZWQgdG8gdGhlCiAgICAgKiAgICAgY2xhc3Mgd2hlcmUgdGhlIHN5bWJvbCB3YXMgZGVmaW5lZCwgKGluIHRoaXMgY2FzZQogICAgICogICAgIHdlIGhhdmUgZXh0ZW5kZWQgYSBwYXJhbWV0ZXJpemVkIGNsYXNzIHdpdGggbm9uLXRyaXZpYWwgcGFyYW1ldGVycykuCiAgICAgKiAgMi4gVGhlIG1ldGhvZCBoYXMgYW4gaW1wbGVtZW50YXRpb24gd2l0aCBhIGRpZmZlcmVudCBlcmFzZWQgcmV0dXJuIHR5cGUuCiAgICAgKiAgICAgKGluIHRoaXMgY2FzZSB3ZSBoYXZlIHVzZWQgY28tdmFyaWFudCByZXR1cm5zKS4KICAgICAqICBJZiBhIGJyaWRnZSBhbHJlYWR5IGV4aXN0cyBpbiBzb21lIG90aGVyIGNsYXNzLCBubyBuZXcgYnJpZGdlIGlzIGFkZGVkLgogICAgICogIEluc3RlYWQsIGl0IGlzIGNoZWNrZWQgdGhhdCB0aGUgYnJpZGdlIHN5bWJvbCBvdmVycmlkZXMgdGhlIG1ldGhvZCBzeW1ib2wuCiAgICAgKiAgKFNwZWMgPz8/KS4KICAgICAqICB0b2RvOiB3aGF0IGFib3V0IGJyaWRnZXMgZm9yIHByaXZhdGVzPz8/CiAgICAgKgogICAgICogIEBwYXJhbSBwb3MgICAgIFRoZSBzb3VyY2UgY29kZSBwb3NpdGlvbiB0byBiZSB1c2VkIGZvciB0aGUgZGVmaW5pdGlvbi4KICAgICAqICBAcGFyYW0gc3ltICAgICBUaGUgc3ltYm9sIGZvciB3aGljaCBhIGJyaWRnZSBtaWdodCBoYXZlIHRvIGJlIGFkZGVkLgogICAgICogIEBwYXJhbSBvcmlnaW4gIFRoZSBjbGFzcyBpbiB3aGljaCB0aGUgYnJpZGdlIHdvdWxkIGdvLgogICAgICogIEBwYXJhbSBicmlkZ2VzIFRoZSBsaXN0IGJ1ZmZlciB0byB3aGljaCB0aGUgYnJpZGdlIHdvdWxkIGJlIGFkZGVkLgogICAgICovCiAgICB2b2lkIGFkZEJyaWRnZUlmTmVlZGVkKERpYWdub3N0aWNQb3NpdGlvbiBwb3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFN5bWJvbCBzeW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgIENsYXNzU3ltYm9sIG9yaWdpbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgTGlzdEJ1ZmZlcjxKQ1RyZWU+IGJyaWRnZXMpIHsKICAgICAgICBpZiAoc3ltLmtpbmQgPT0gTVRIICYmCiAgICAgICAgICAgIHN5bS5uYW1lICE9IG5hbWVzLmluaXQgJiYKICAgICAgICAgICAgKHN5bS5mbGFncygpICYgKFBSSVZBVEUgfCBTVEFUSUMpKSA9PSAwICYmCiAgICAgICAgICAgIChzeW0uZmxhZ3MoKSAmIFNZTlRIRVRJQykgIT0gU1lOVEhFVElDICYmCiAgICAgICAgICAgIHN5bS5pc01lbWJlck9mKG9yaWdpbiwgdHlwZXMpKQogICAgICAgIHsKICAgICAgICAgICAgTWV0aG9kU3ltYm9sIG1ldGggPSAoTWV0aG9kU3ltYm9sKXN5bTsKICAgICAgICAgICAgTWV0aG9kU3ltYm9sIGJyaWRnZSA9IG1ldGguYmluYXJ5SW1wbGVtZW50YXRpb24ob3JpZ2luLCB0eXBlcyk7CiAgICAgICAgICAgIE1ldGhvZFN5bWJvbCBpbXBsID0gbWV0aC5pbXBsZW1lbnRhdGlvbihvcmlnaW4sIHR5cGVzLCB0cnVlKTsKICAgICAgICAgICAgaWYgKGJyaWRnZSA9PSBudWxsIHx8CiAgICAgICAgICAgICAgICBicmlkZ2UgPT0gbWV0aCB8fAogICAgICAgICAgICAgICAgKGltcGwgIT0gbnVsbCAmJiAhYnJpZGdlLm93bmVyLmlzU3ViQ2xhc3MoaW1wbC5vd25lciwgdHlwZXMpKSkgewogICAgICAgICAgICAgICAgLy8gTm8gYnJpZGdlIHdhcyBhZGRlZCB5ZXQuCiAgICAgICAgICAgICAgICBpZiAoaW1wbCAhPSBudWxsICYmIGlzQnJpZGdlTmVlZGVkKG1ldGgsIGltcGwsIG9yaWdpbi50eXBlKSkgewogICAgICAgICAgICAgICAgICAgIGFkZEJyaWRnZShwb3MsIG1ldGgsIGltcGwsIG9yaWdpbiwgYnJpZGdlPT1pbXBsLCBicmlkZ2VzKTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaW1wbCA9PSBtZXRoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICYmIGltcGwub3duZXIgIT0gb3JpZ2luCiAgICAgICAgICAgICAgICAgICAgICAgICAgICYmIChpbXBsLmZsYWdzKCkgJiBGSU5BTCkgPT0gMAogICAgICAgICAgICAgICAgICAgICAgICAgICAmJiAobWV0aC5mbGFncygpICYgKEFCU1RSQUNUfFBVQkxJQykpID09IFBVQkxJQwogICAgICAgICAgICAgICAgICAgICAgICAgICAmJiAob3JpZ2luLmZsYWdzKCkgJiBQVUJMSUMpID4gKGltcGwub3duZXIuZmxhZ3MoKSAmIFBVQkxJQykpIHsKICAgICAgICAgICAgICAgICAgICAvLyB0aGlzIGlzIHRvIHdvcmsgYXJvdW5kIGEgaG9ycmlibGUgYnV0IHBlcm1hbmVudAogICAgICAgICAgICAgICAgICAgIC8vIHJlZmxlY3Rpb24gZGVzaWduIGVycm9yLgogICAgICAgICAgICAgICAgICAgIGFkZEJyaWRnZShwb3MsIG1ldGgsIGltcGwsIG9yaWdpbiwgZmFsc2UsIGJyaWRnZXMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgaWYgKChicmlkZ2UuZmxhZ3MoKSAmIFNZTlRIRVRJQykgPT0gU1lOVEhFVElDKSB7CiAgICAgICAgICAgICAgICBmaW5hbCBQYWlyPE1ldGhvZFN5bWJvbCwgTWV0aG9kU3ltYm9sPiBicmlkZ2VTcGFuID0gYnJpZGdlU3BhbnMuZ2V0KGJyaWRnZSk7CiAgICAgICAgICAgICAgICBNZXRob2RTeW1ib2wgb3RoZXIgPSBicmlkZ2VTcGFuID09IG51bGwgPyBudWxsIDogYnJpZGdlU3Bhbi5mc3Q7CiAgICAgICAgICAgICAgICBpZiAob3RoZXIgIT0gbnVsbCAmJiBvdGhlciAhPSBtZXRoKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGltcGwgPT0gbnVsbCB8fCAhaW1wbC5vdmVycmlkZXMob3RoZXIsIG9yaWdpbiwgdHlwZXMsIHRydWUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIElzIGJyaWRnZSBlZmZlY3RpdmVseSBhbHNvIHRoZSBicmlkZ2UgZm9yIGBtZXRoJywgaWYgc28gbm8gY2xhc2guCiAgICAgICAgICAgICAgICAgICAgICAgIE1ldGhvZFN5bWJvbCB0YXJnZXQgPSBicmlkZ2VTcGFuID09IG51bGwgPyBudWxsIDogYnJpZGdlU3Bhbi5zbmQ7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0YXJnZXQgPT0gbnVsbCB8fCAhdGFyZ2V0Lm92ZXJyaWRlcyhtZXRoLCBvcmlnaW4sIHR5cGVzLCB0cnVlLCBmYWxzZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEJyaWRnZSBmb3Igb3RoZXIgc3ltYm9sIHBhaXIgd2FzIGFkZGVkCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2cuZXJyb3IocG9zLCAibmFtZS5jbGFzaC5zYW1lLmVyYXN1cmUubm8ub3ZlcnJpZGUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdGhlciwgb3RoZXIubG9jYXRpb24ob3JpZ2luLnR5cGUsIHR5cGVzKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0aCwgbWV0aC5sb2NhdGlvbihvcmlnaW4udHlwZSwgdHlwZXMpKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIGlmICghYnJpZGdlLm92ZXJyaWRlcyhtZXRoLCBvcmlnaW4sIHR5cGVzLCB0cnVlKSkgewogICAgICAgICAgICAgICAgLy8gQWNjaWRlbnRhbCBiaW5hcnkgb3ZlcnJpZGUgd2l0aG91dCBzb3VyY2Ugb3ZlcnJpZGUuCiAgICAgICAgICAgICAgICBpZiAoYnJpZGdlLm93bmVyID09IG9yaWdpbiB8fAogICAgICAgICAgICAgICAgICAgIHR5cGVzLmFzU3VwZXIoYnJpZGdlLm93bmVyLnR5cGUsIG1ldGgub3duZXIpID09IG51bGwpCiAgICAgICAgICAgICAgICAgICAgLy8gRG9uJ3QgZGlhZ25vc2UgdGhlIHByb2JsZW0gaWYgaXQgd291bGQgYWxyZWFkeQogICAgICAgICAgICAgICAgICAgIC8vIGhhdmUgYmVlbiByZXBvcnRlZCBpbiB0aGUgc3VwZXJjbGFzcwogICAgICAgICAgICAgICAgICAgIGxvZy5lcnJvcihwb3MsICJuYW1lLmNsYXNoLnNhbWUuZXJhc3VyZS5uby5vdmVycmlkZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyaWRnZSwgYnJpZGdlLmxvY2F0aW9uKG9yaWdpbi50eXBlLCB0eXBlcyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGgsICBtZXRoLmxvY2F0aW9uKG9yaWdpbi50eXBlLCB0eXBlcykpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgLy8gd2hlcmUKCiAgICAgICAgLyoqCiAgICAgICAgICogQHBhcmFtIG1ldGhvZCBUaGUgc3ltYm9sIGZvciB3aGljaCBhIGJyaWRnZSBtaWdodCBoYXZlIHRvIGJlIGFkZGVkCiAgICAgICAgICogQHBhcmFtIGltcGwgVGhlIGltcGxlbWVudGF0aW9uIG9mIG1ldGhvZAogICAgICAgICAqIEBwYXJhbSBkZXN0IFRoZSB0eXBlIGluIHdoaWNoIHRoZSBicmlkZ2Ugd291bGQgZ28KICAgICAgICAgKi8KICAgICAgICBwcml2YXRlIGJvb2xlYW4gaXNCcmlkZ2VOZWVkZWQoTWV0aG9kU3ltYm9sIG1ldGhvZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWV0aG9kU3ltYm9sIGltcGwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFR5cGUgZGVzdCkgewogICAgICAgICAgICBpZiAoaW1wbCAhPSBtZXRob2QpIHsKICAgICAgICAgICAgICAgIGlmIChza2lwQnJpZGdlKG1ldGhvZCwgaW1wbCwgZGVzdCkpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvLyBJZiBlaXRoZXIgbWV0aG9kIG9yIGltcGwgaGF2ZSBkaWZmZXJlbnQgZXJhc3VyZXMgYXMKICAgICAgICAgICAgICAgIC8vIG1lbWJlcnMgb2YgZGVzdCwgYSBicmlkZ2UgaXMgbmVlZGVkLgogICAgICAgICAgICAgICAgVHlwZSBtZXRob2RfZXJhc3VyZSA9IG1ldGhvZC5lcmFzdXJlKHR5cGVzKTsKICAgICAgICAgICAgICAgIGlmICghaXNTYW1lTWVtYmVyV2hlbkVyYXNlZChkZXN0LCBtZXRob2QsIG1ldGhvZF9lcmFzdXJlKSkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgIFR5cGUgaW1wbF9lcmFzdXJlID0gaW1wbC5lcmFzdXJlKHR5cGVzKTsKICAgICAgICAgICAgICAgIGlmICghaXNTYW1lTWVtYmVyV2hlbkVyYXNlZChkZXN0LCBpbXBsLCBpbXBsX2VyYXN1cmUpKQogICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwoKICAgICAgICAgICAgICAgIC8qIEJvdHRvbSBsaW5lOiBBIGJyaWRnZSBpcyBuZWVkZWQgaWYgdGhlIGVyYXN1cmUgb2YgdGhlIGltcGxlbWVudGF0aW9uCiAgICAgICAgICAgICAgICAgICBpcyBkaWZmZXJlbnQgZnJvbSB0aGF0IG9mIHRoZSBtZXRob2QgdGhhdCBpdCBvdmVycmlkZXMuCiAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgcmV0dXJuICF0eXBlcy5pc1NhbWVUeXBlKGltcGxfZXJhc3VyZSwgbWV0aG9kX2VyYXN1cmUpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAvLyBtZXRob2QgYW5kIGltcGwgYXJlIHRoZSBzYW1lLi4uCiAgICAgICAgICAgICAgICBpZiAoKG1ldGhvZC5mbGFncygpICYgQUJTVFJBQ1QpICE9IDApIHsKICAgICAgICAgICAgICAgICAgICAvLyAuLi5hbmQgYWJzdHJhY3Qgc28gYSBicmlkZ2UgaXMgbm90IG5lZWRlZC4KICAgICAgICAgICAgICAgICAgICAvLyBDb25jcmV0ZSBzdWJjbGFzc2VzIHdpbGwgYnJpZGdlIGFzIG5lZWRlZC4KICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gVGhlIGVyYXN1cmUgb2YgdGhlIHJldHVybiB0eXBlIGlzIGFsd2F5cyB0aGUgc2FtZQogICAgICAgICAgICAgICAgLy8gZm9yIHRoZSBzYW1lIHN5bWJvbC4gIFJlZHVjaW5nIHRoZSB0aHJlZSB0ZXN0cyBpbgogICAgICAgICAgICAgICAgLy8gdGhlIG90aGVyIGJyYW5jaCB0byBqdXN0IG9uZToKICAgICAgICAgICAgICAgIHJldHVybiAhaXNTYW1lTWVtYmVyV2hlbkVyYXNlZChkZXN0LCBtZXRob2QsIG1ldGhvZC5lcmFzdXJlKHR5cGVzKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogTG9va3VwIHRoZSBtZXRob2QgYXMgYSBtZW1iZXIgb2YgdGhlIHR5cGUuICBDb21wYXJlIHRoZQogICAgICAgICAqIGVyYXN1cmVzLgogICAgICAgICAqIEBwYXJhbSB0eXBlIHRoZSBjbGFzcyB3aGVyZSB0byBsb29rIGZvciB0aGUgbWV0aG9kCiAgICAgICAgICogQHBhcmFtIG1ldGhvZCB0aGUgbWV0aG9kIHRvIGxvb2sgZm9yIGluIGNsYXNzCiAgICAgICAgICogQHBhcmFtIGVyYXN1cmUgdGhlIGVyYXN1cmUgb2YgbWV0aG9kCiAgICAgICAgICovCiAgICAgICAgcHJpdmF0ZSBib29sZWFuIGlzU2FtZU1lbWJlcldoZW5FcmFzZWQoVHlwZSB0eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1ldGhvZFN5bWJvbCBtZXRob2QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVHlwZSBlcmFzdXJlKSB7CiAgICAgICAgICAgIHJldHVybiB0eXBlcy5pc1NhbWVUeXBlKGVyYXN1cmUodHlwZXMubWVtYmVyVHlwZSh0eXBlLCBtZXRob2QpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJhc3VyZSk7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIFJldHVybnMgdHJ1ZSBpZiBhIGJyaWRnZSBzaG91bGQgYmUgc2tpcHBlZCBiZWNhdXNlIHdlIGV4cGVjdCBpdCB0byBiZSBkZWNsYXJlZCBpbgogICAgICAgICAqIGEgc3VwZXItdHlwZS4KICAgICAgICAgKgogICAgICAgICAqIEBwYXJhbSBtZXRob2QgVGhlIHN5bWJvbCBmb3Igd2hpY2ggYSBicmlkZ2UgbWlnaHQgaGF2ZSB0byBiZSBhZGRlZAogICAgICAgICAqIEBwYXJhbSBpbXBsIFRoZSBpbXBsZW1lbnRhdGlvbiBvZiBtZXRob2QKICAgICAgICAgKiBAcGFyYW0gZGVzdCBUaGUgdHlwZSBpbiB3aGljaCB0aGUgYnJpZGdlIHdvdWxkIGdvCiAgICAgICAgICovCiAgICAgICAgcHJpdmF0ZSBib29sZWFuIHNraXBCcmlkZ2UoTWV0aG9kU3ltYm9sIG1ldGhvZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXRob2RTeW1ib2wgaW1wbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUeXBlIGRlc3QpIHsKICAgICAgICAgICAgaWYgKCFza2lwRHVwbGljYXRlQnJpZGdlcykgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChkZXN0LnRzeW0gPT0gaW1wbC5vd25lcikgewogICAgICAgICAgICAgICAgLy8gdGhlIG1ldGhvZCBpcyBpbXBsZW1lbnRlZCBpbiB0aGUgY3VycmVudCBjbGFzczsgd2UgbmVlZCB0byBicmlkZ2UgaXQgaGVyZQogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICghdHlwZXMuaXNTdWJ0eXBlKAogICAgICAgICAgICAgICAgICAgIHR5cGVzLmVyYXN1cmUoaW1wbC5vd25lci50eXBlKSwgdHlwZXMuZXJhc3VyZShtZXRob2Qub3duZXIudHlwZSkpKSB7CiAgICAgICAgICAgICAgICAvLyB0aGUgbWV0aG9kIGlzIGltcGxlbWVudGVkIGluIHNvbWUgc3VwZXJ0eXBlIHRoYXQgaXMgbm90IGEgc3VidHlwZSBvZgogICAgICAgICAgICAgICAgLy8gdGhlIGRlY2xhcmluZyB0eXBlLCBzbyB0aGUgYnJpZGdlIHdpbGwgbm90IGhhdmUgYmVlbiBjcmVhdGVkIGluIHRoZQogICAgICAgICAgICAgICAgLy8gaW1wbGVtZW50aW5nIGNsYXNzCiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCFpbXBsLm92ZXJyaWRlcyhtZXRob2QsIChUeXBlU3ltYm9sKSBpbXBsLm93bmVyLCB0eXBlcywgdHJ1ZSkpIHsKICAgICAgICAgICAgICAgIC8vIHRoZSBtZXRob2QgaXMgaW1wbGVtZW50aW5nIGluIGEgc3VwZXJ0eXBlIHRoYXQgaXMgYWxzbyBhIHN1YnR5cGUKICAgICAgICAgICAgICAgIC8vIG9mIHRoZSBkZWNsYXJpbmcgdHlwZSwgYnV0IHRoZSBtZXRob2QncyBzaWduYXR1cmUgaW4gdGhlIGltcGxlbWVudGluZwogICAgICAgICAgICAgICAgLy8gY2xhc3MgZG9lcyBub3Qgb3ZlcnJpZGUgaXRzIHNpZ25hdHVyZSBpbiB0aGUgZGVjbGFyaW5nIGNsYXNzCiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gd2UgZG9uJ3QgbmVlZCB0byBjb25zaWRlciB2aXNpYmlsaXR5IGZvciBhY2Nlc3NpYmlsaXR5IGJyaWRnZXMsIGJlY2F1c2UKICAgICAgICAgICAgLy8gdGhhdCBoYXBwZW5zIG9uIGEgc2VwYXJhdGUgY29kZSBwYXRoCiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICB2b2lkIGFkZEJyaWRnZXMoRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcywKICAgICAgICAgICAgICAgICAgICBUeXBlU3ltYm9sIGksCiAgICAgICAgICAgICAgICAgICAgQ2xhc3NTeW1ib2wgb3JpZ2luLAogICAgICAgICAgICAgICAgICAgIExpc3RCdWZmZXI8SkNUcmVlPiBicmlkZ2VzKSB7CiAgICAgICAgZm9yIChTeW1ib2wgc3ltIDogaS5tZW1iZXJzKCkuZ2V0U3ltYm9scyhOT05fUkVDVVJTSVZFKSkKICAgICAgICAgICAgYWRkQnJpZGdlSWZOZWVkZWQocG9zLCBzeW0sIG9yaWdpbiwgYnJpZGdlcyk7CiAgICAgICAgZm9yIChMaXN0PFR5cGU+IGwgPSB0eXBlcy5pbnRlcmZhY2VzKGkudHlwZSk7IGwubm9uRW1wdHkoKTsgbCA9IGwudGFpbCkKICAgICAgICAgICAgYWRkQnJpZGdlcyhwb3MsIGwuaGVhZC50c3ltLCBvcmlnaW4sIGJyaWRnZXMpOwogICAgfQoKICAgIC8qKiBBZGQgYWxsIG5lY2Vzc2FyeSBicmlkZ2VzIHRvIHNvbWUgY2xhc3MgYXBwZW5kaW5nIHRoZW0gdG8gbGlzdCBidWZmZXIuCiAgICAgKiAgQHBhcmFtIHBvcyAgICAgVGhlIHNvdXJjZSBjb2RlIHBvc2l0aW9uIHRvIGJlIHVzZWQgZm9yIHRoZSBicmlkZ2VzLgogICAgICogIEBwYXJhbSBvcmlnaW4gIFRoZSBjbGFzcyBpbiB3aGljaCB0aGUgYnJpZGdlcyBnby4KICAgICAqICBAcGFyYW0gYnJpZGdlcyBUaGUgbGlzdCBidWZmZXIgdG8gd2hpY2ggdGhlIGJyaWRnZXMgYXJlIGFkZGVkLgogICAgICovCiAgICB2b2lkIGFkZEJyaWRnZXMoRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcywgQ2xhc3NTeW1ib2wgb3JpZ2luLCBMaXN0QnVmZmVyPEpDVHJlZT4gYnJpZGdlcykgewogICAgICAgIFR5cGUgc3QgPSB0eXBlcy5zdXBlcnR5cGUob3JpZ2luLnR5cGUpOwogICAgICAgIHdoaWxlIChzdC5oYXNUYWcoQ0xBU1MpKSB7Ci8vICAgICAgICAgIGlmIChpc1NwZWNpYWxpemF0aW9uKHN0KSkKICAgICAgICAgICAgYWRkQnJpZGdlcyhwb3MsIHN0LnRzeW0sIG9yaWdpbiwgYnJpZGdlcyk7CiAgICAgICAgICAgIHN0ID0gdHlwZXMuc3VwZXJ0eXBlKHN0KTsKICAgICAgICB9CiAgICAgICAgZm9yIChMaXN0PFR5cGU+IGwgPSB0eXBlcy5pbnRlcmZhY2VzKG9yaWdpbi50eXBlKTsgbC5ub25FbXB0eSgpOyBsID0gbC50YWlsKQovLyAgICAgICAgICBpZiAoaXNTcGVjaWFsaXphdGlvbihsLmhlYWQpKQogICAgICAgICAgICBhZGRCcmlkZ2VzKHBvcywgbC5oZWFkLnRzeW0sIG9yaWdpbiwgYnJpZGdlcyk7CiAgICB9CgovKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogVmlzaXRvciBtZXRob2RzCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKICAgIC8qKiBWaXNpdG9yIGFyZ3VtZW50OiBwcm90by10eXBlLgogICAgICovCiAgICBwcml2YXRlIFR5cGUgcHQ7CgogICAgLyoqIFZpc2l0b3IgbWV0aG9kOiBwZXJmb3JtIGEgdHlwZSB0cmFuc2xhdGlvbiBvbiB0cmVlLgogICAgICovCiAgICBwdWJsaWMgPFQgZXh0ZW5kcyBKQ1RyZWU+IFQgdHJhbnNsYXRlKFQgdHJlZSwgVHlwZSBwdCkgewogICAgICAgIFR5cGUgcHJldlB0ID0gdGhpcy5wdDsKICAgICAgICB0cnkgewogICAgICAgICAgICB0aGlzLnB0ID0gcHQ7CiAgICAgICAgICAgIHJldHVybiB0cmFuc2xhdGUodHJlZSk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgdGhpcy5wdCA9IHByZXZQdDsKICAgICAgICB9CiAgICB9CgogICAgLyoqIFZpc2l0b3IgbWV0aG9kOiBwZXJmb3JtIGEgdHlwZSB0cmFuc2xhdGlvbiBvbiBsaXN0IG9mIHRyZWVzLgogICAgICovCiAgICBwdWJsaWMgPFQgZXh0ZW5kcyBKQ1RyZWU+IExpc3Q8VD4gdHJhbnNsYXRlKExpc3Q8VD4gdHJlZXMsIFR5cGUgcHQpIHsKICAgICAgICBUeXBlIHByZXZQdCA9IHRoaXMucHQ7CiAgICAgICAgTGlzdDxUPiByZXM7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgdGhpcy5wdCA9IHB0OwogICAgICAgICAgICByZXMgPSB0cmFuc2xhdGUodHJlZXMpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgIHRoaXMucHQgPSBwcmV2UHQ7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXM7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRDbGFzc0RlZihKQ0NsYXNzRGVjbCB0cmVlKSB7CiAgICAgICAgdHJhbnNsYXRlQ2xhc3ModHJlZS5zeW0pOwogICAgICAgIHJlc3VsdCA9IHRyZWU7CiAgICB9CgogICAgSkNUcmVlIGN1cnJlbnRNZXRob2QgPSBudWxsOwogICAgcHVibGljIHZvaWQgdmlzaXRNZXRob2REZWYoSkNNZXRob2REZWNsIHRyZWUpIHsKICAgICAgICBKQ1RyZWUgcHJldmlvdXNNZXRob2QgPSBjdXJyZW50TWV0aG9kOwogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGN1cnJlbnRNZXRob2QgPSB0cmVlOwogICAgICAgICAgICB0cmVlLnJlc3R5cGUgPSB0cmFuc2xhdGUodHJlZS5yZXN0eXBlLCBudWxsKTsKICAgICAgICAgICAgdHJlZS50eXBhcmFtcyA9IExpc3QubmlsKCk7CiAgICAgICAgICAgIHRyZWUucGFyYW1zID0gdHJhbnNsYXRlVmFyRGVmcyh0cmVlLnBhcmFtcyk7CiAgICAgICAgICAgIHRyZWUucmVjdnBhcmFtID0gdHJhbnNsYXRlKHRyZWUucmVjdnBhcmFtLCBudWxsKTsKICAgICAgICAgICAgdHJlZS50aHJvd24gPSB0cmFuc2xhdGUodHJlZS50aHJvd24sIG51bGwpOwogICAgICAgICAgICB0cmVlLmJvZHkgPSB0cmFuc2xhdGUodHJlZS5ib2R5LCB0cmVlLnN5bS5lcmFzdXJlKHR5cGVzKS5nZXRSZXR1cm5UeXBlKCkpOwogICAgICAgICAgICB0cmVlLnR5cGUgPSBlcmFzdXJlKHRyZWUudHlwZSk7CiAgICAgICAgICAgIHJlc3VsdCA9IHRyZWU7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgY3VycmVudE1ldGhvZCA9IHByZXZpb3VzTWV0aG9kOwogICAgICAgIH0KCiAgICAgICAgLy8gQ2hlY2sgdGhhdCB3ZSBkbyBub3QgaW50cm9kdWNlIGEgbmFtZSBjbGFzaCBieSBlcmFzaW5nIHR5cGVzLgogICAgICAgIGZvciAoU3ltYm9sIHN5bSA6IHRyZWUuc3ltLm93bmVyLm1lbWJlcnMoKS5nZXRTeW1ib2xzQnlOYW1lKHRyZWUubmFtZSkpIHsKICAgICAgICAgICAgaWYgKHN5bSAhPSB0cmVlLnN5bSAmJgogICAgICAgICAgICAgICAgdHlwZXMuaXNTYW1lVHlwZShlcmFzdXJlKHN5bS50eXBlKSwgdHJlZS50eXBlKSkgewogICAgICAgICAgICAgICAgbG9nLmVycm9yKHRyZWUucG9zKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIm5hbWUuY2xhc2guc2FtZS5lcmFzdXJlIiwgdHJlZS5zeW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgc3ltKTsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdFZhckRlZihKQ1ZhcmlhYmxlRGVjbCB0cmVlKSB7CiAgICAgICAgdHJlZS52YXJ0eXBlID0gdHJhbnNsYXRlKHRyZWUudmFydHlwZSwgbnVsbCk7CiAgICAgICAgdHJlZS5pbml0ID0gdHJhbnNsYXRlKHRyZWUuaW5pdCwgdHJlZS5zeW0uZXJhc3VyZSh0eXBlcykpOwogICAgICAgIHRyZWUudHlwZSA9IGVyYXN1cmUodHJlZS50eXBlKTsKICAgICAgICByZXN1bHQgPSB0cmVlOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0RG9Mb29wKEpDRG9XaGlsZUxvb3AgdHJlZSkgewogICAgICAgIHRyZWUuYm9keSA9IHRyYW5zbGF0ZSh0cmVlLmJvZHkpOwogICAgICAgIHRyZWUuY29uZCA9IHRyYW5zbGF0ZSh0cmVlLmNvbmQsIHN5bXMuYm9vbGVhblR5cGUpOwogICAgICAgIHJlc3VsdCA9IHRyZWU7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRXaGlsZUxvb3AoSkNXaGlsZUxvb3AgdHJlZSkgewogICAgICAgIHRyZWUuY29uZCA9IHRyYW5zbGF0ZSh0cmVlLmNvbmQsIHN5bXMuYm9vbGVhblR5cGUpOwogICAgICAgIHRyZWUuYm9keSA9IHRyYW5zbGF0ZSh0cmVlLmJvZHkpOwogICAgICAgIHJlc3VsdCA9IHRyZWU7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRGb3JMb29wKEpDRm9yTG9vcCB0cmVlKSB7CiAgICAgICAgdHJlZS5pbml0ID0gdHJhbnNsYXRlKHRyZWUuaW5pdCwgbnVsbCk7CiAgICAgICAgaWYgKHRyZWUuY29uZCAhPSBudWxsKQogICAgICAgICAgICB0cmVlLmNvbmQgPSB0cmFuc2xhdGUodHJlZS5jb25kLCBzeW1zLmJvb2xlYW5UeXBlKTsKICAgICAgICB0cmVlLnN0ZXAgPSB0cmFuc2xhdGUodHJlZS5zdGVwLCBudWxsKTsKICAgICAgICB0cmVlLmJvZHkgPSB0cmFuc2xhdGUodHJlZS5ib2R5KTsKICAgICAgICByZXN1bHQgPSB0cmVlOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0Rm9yZWFjaExvb3AoSkNFbmhhbmNlZEZvckxvb3AgdHJlZSkgewogICAgICAgIHRyZWUudmFyID0gdHJhbnNsYXRlKHRyZWUudmFyLCBudWxsKTsKICAgICAgICBUeXBlIGl0ZXJhYmxlVHlwZSA9IHRyZWUuZXhwci50eXBlOwogICAgICAgIHRyZWUuZXhwciA9IHRyYW5zbGF0ZSh0cmVlLmV4cHIsIGVyYXN1cmUodHJlZS5leHByLnR5cGUpKTsKICAgICAgICBpZiAodHlwZXMuZWxlbXR5cGUodHJlZS5leHByLnR5cGUpID09IG51bGwpCiAgICAgICAgICAgIHRyZWUuZXhwci50eXBlID0gaXRlcmFibGVUeXBlOyAvLyBwcmVzZXJ2ZSB0eXBlIGZvciBMb3dlcgogICAgICAgIHRyZWUuYm9keSA9IHRyYW5zbGF0ZSh0cmVlLmJvZHkpOwogICAgICAgIHJlc3VsdCA9IHRyZWU7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRMYW1iZGEoSkNMYW1iZGEgdHJlZSkgewogICAgICAgIEpDVHJlZSBwcmV2TWV0aG9kID0gY3VycmVudE1ldGhvZDsKICAgICAgICB0cnkgewogICAgICAgICAgICBjdXJyZW50TWV0aG9kID0gbnVsbDsKICAgICAgICAgICAgdHJlZS5wYXJhbXMgPSB0cmFuc2xhdGUodHJlZS5wYXJhbXMpOwogICAgICAgICAgICB0cmVlLmJvZHkgPSB0cmFuc2xhdGUodHJlZS5ib2R5LCB0cmVlLmJvZHkudHlwZT09bnVsbD8gbnVsbCA6IGVyYXN1cmUodHJlZS5ib2R5LnR5cGUpKTsKICAgICAgICAgICAgdHJlZS50eXBlID0gZXJhc3VyZSh0cmVlLnR5cGUpOwogICAgICAgICAgICByZXN1bHQgPSB0cmVlOwogICAgICAgIH0KICAgICAgICBmaW5hbGx5IHsKICAgICAgICAgICAgY3VycmVudE1ldGhvZCA9IHByZXZNZXRob2Q7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0U3dpdGNoKEpDU3dpdGNoIHRyZWUpIHsKICAgICAgICBUeXBlIHNlbHN1cGVyID0gdHlwZXMuc3VwZXJ0eXBlKHRyZWUuc2VsZWN0b3IudHlwZSk7CiAgICAgICAgYm9vbGVhbiBlbnVtU3dpdGNoID0gc2Vsc3VwZXIgIT0gbnVsbCAmJgogICAgICAgICAgICBzZWxzdXBlci50c3ltID09IHN5bXMuZW51bVN5bTsKICAgICAgICBUeXBlIHRhcmdldCA9IGVudW1Td2l0Y2ggPyBlcmFzdXJlKHRyZWUuc2VsZWN0b3IudHlwZSkgOiBzeW1zLmludFR5cGU7CiAgICAgICAgdHJlZS5zZWxlY3RvciA9IHRyYW5zbGF0ZSh0cmVlLnNlbGVjdG9yLCB0YXJnZXQpOwogICAgICAgIHRyZWUuY2FzZXMgPSB0cmFuc2xhdGVDYXNlcyh0cmVlLmNhc2VzKTsKICAgICAgICByZXN1bHQgPSB0cmVlOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0Q2FzZShKQ0Nhc2UgdHJlZSkgewogICAgICAgIHRyZWUucGF0ID0gdHJhbnNsYXRlKHRyZWUucGF0LCBudWxsKTsKICAgICAgICB0cmVlLnN0YXRzID0gdHJhbnNsYXRlKHRyZWUuc3RhdHMpOwogICAgICAgIHJlc3VsdCA9IHRyZWU7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRTeW5jaHJvbml6ZWQoSkNTeW5jaHJvbml6ZWQgdHJlZSkgewogICAgICAgIHRyZWUubG9jayA9IHRyYW5zbGF0ZSh0cmVlLmxvY2ssIGVyYXN1cmUodHJlZS5sb2NrLnR5cGUpKTsKICAgICAgICB0cmVlLmJvZHkgPSB0cmFuc2xhdGUodHJlZS5ib2R5KTsKICAgICAgICByZXN1bHQgPSB0cmVlOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0VHJ5KEpDVHJ5IHRyZWUpIHsKICAgICAgICB0cmVlLnJlc291cmNlcyA9IHRyYW5zbGF0ZSh0cmVlLnJlc291cmNlcywgc3ltcy5hdXRvQ2xvc2VhYmxlVHlwZSk7CiAgICAgICAgdHJlZS5ib2R5ID0gdHJhbnNsYXRlKHRyZWUuYm9keSk7CiAgICAgICAgdHJlZS5jYXRjaGVycyA9IHRyYW5zbGF0ZUNhdGNoZXJzKHRyZWUuY2F0Y2hlcnMpOwogICAgICAgIHRyZWUuZmluYWxpemVyID0gdHJhbnNsYXRlKHRyZWUuZmluYWxpemVyKTsKICAgICAgICByZXN1bHQgPSB0cmVlOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0Q29uZGl0aW9uYWwoSkNDb25kaXRpb25hbCB0cmVlKSB7CiAgICAgICAgdHJlZS5jb25kID0gdHJhbnNsYXRlKHRyZWUuY29uZCwgc3ltcy5ib29sZWFuVHlwZSk7CiAgICAgICAgdHJlZS50cnVlcGFydCA9IHRyYW5zbGF0ZSh0cmVlLnRydWVwYXJ0LCBlcmFzdXJlKHRyZWUudHlwZSkpOwogICAgICAgIHRyZWUuZmFsc2VwYXJ0ID0gdHJhbnNsYXRlKHRyZWUuZmFsc2VwYXJ0LCBlcmFzdXJlKHRyZWUudHlwZSkpOwogICAgICAgIHRyZWUudHlwZSA9IGVyYXN1cmUodHJlZS50eXBlKTsKICAgICAgICByZXN1bHQgPSByZXR5cGUodHJlZSwgdHJlZS50eXBlLCBwdCk7CiAgICB9CgogICBwdWJsaWMgdm9pZCB2aXNpdElmKEpDSWYgdHJlZSkgewogICAgICAgIHRyZWUuY29uZCA9IHRyYW5zbGF0ZSh0cmVlLmNvbmQsIHN5bXMuYm9vbGVhblR5cGUpOwogICAgICAgIHRyZWUudGhlbnBhcnQgPSB0cmFuc2xhdGUodHJlZS50aGVucGFydCk7CiAgICAgICAgdHJlZS5lbHNlcGFydCA9IHRyYW5zbGF0ZSh0cmVlLmVsc2VwYXJ0KTsKICAgICAgICByZXN1bHQgPSB0cmVlOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0RXhlYyhKQ0V4cHJlc3Npb25TdGF0ZW1lbnQgdHJlZSkgewogICAgICAgIHRyZWUuZXhwciA9IHRyYW5zbGF0ZSh0cmVlLmV4cHIsIG51bGwpOwogICAgICAgIHJlc3VsdCA9IHRyZWU7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRSZXR1cm4oSkNSZXR1cm4gdHJlZSkgewogICAgICAgIHRyZWUuZXhwciA9IHRyYW5zbGF0ZSh0cmVlLmV4cHIsIGN1cnJlbnRNZXRob2QgIT0gbnVsbCA/IHR5cGVzLmVyYXN1cmUoY3VycmVudE1ldGhvZC50eXBlKS5nZXRSZXR1cm5UeXBlKCkgOiBudWxsKTsKICAgICAgICByZXN1bHQgPSB0cmVlOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0VGhyb3coSkNUaHJvdyB0cmVlKSB7CiAgICAgICAgdHJlZS5leHByID0gdHJhbnNsYXRlKHRyZWUuZXhwciwgZXJhc3VyZSh0cmVlLmV4cHIudHlwZSkpOwogICAgICAgIHJlc3VsdCA9IHRyZWU7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRBc3NlcnQoSkNBc3NlcnQgdHJlZSkgewogICAgICAgIHRyZWUuY29uZCA9IHRyYW5zbGF0ZSh0cmVlLmNvbmQsIHN5bXMuYm9vbGVhblR5cGUpOwogICAgICAgIGlmICh0cmVlLmRldGFpbCAhPSBudWxsKQogICAgICAgICAgICB0cmVlLmRldGFpbCA9IHRyYW5zbGF0ZSh0cmVlLmRldGFpbCwgZXJhc3VyZSh0cmVlLmRldGFpbC50eXBlKSk7CiAgICAgICAgcmVzdWx0ID0gdHJlZTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdEFwcGx5KEpDTWV0aG9kSW52b2NhdGlvbiB0cmVlKSB7CiAgICAgICAgdHJlZS5tZXRoID0gdHJhbnNsYXRlKHRyZWUubWV0aCwgbnVsbCk7CiAgICAgICAgU3ltYm9sIG1ldGggPSBUcmVlSW5mby5zeW1ib2wodHJlZS5tZXRoKTsKICAgICAgICBUeXBlIG10ID0gbWV0aC5lcmFzdXJlKHR5cGVzKTsKICAgICAgICBib29sZWFuIHVzZUluc3RhbnRpYXRlZFB0QXJncyA9CiAgICAgICAgICAgICAgICBhbGxvd0dyYXBoSW5mZXJlbmNlICYmICF0eXBlcy5pc1NpZ25hdHVyZVBvbHltb3JwaGljKChNZXRob2RTeW1ib2wpbWV0aC5iYXNlU3ltYm9sKCkpOwogICAgICAgIExpc3Q8VHlwZT4gYXJndHlwZXMgPSB1c2VJbnN0YW50aWF0ZWRQdEFyZ3MgPwogICAgICAgICAgICAgICAgdHJlZS5tZXRoLnR5cGUuZ2V0UGFyYW1ldGVyVHlwZXMoKSA6CiAgICAgICAgICAgICAgICBtdC5nZXRQYXJhbWV0ZXJUeXBlcygpOwogICAgICAgIGlmIChtZXRoLm5hbWUgPT0gbmFtZXMuaW5pdCAmJiBtZXRoLm93bmVyID09IHN5bXMuZW51bVN5bSkKICAgICAgICAgICAgYXJndHlwZXMgPSBhcmd0eXBlcy50YWlsLnRhaWw7CiAgICAgICAgaWYgKHRyZWUudmFyYXJnc0VsZW1lbnQgIT0gbnVsbCkKICAgICAgICAgICAgdHJlZS52YXJhcmdzRWxlbWVudCA9IHR5cGVzLmVyYXN1cmUodHJlZS52YXJhcmdzRWxlbWVudCk7CiAgICAgICAgZWxzZQogICAgICAgICAgICBpZiAodHJlZS5hcmdzLmxlbmd0aCgpICE9IGFyZ3R5cGVzLmxlbmd0aCgpKSB7CiAgICAgICAgICAgICAgICBsb2cuZXJyb3IodHJlZS5wb3MoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm1ldGhvZC5pbnZva2VkLndpdGguaW5jb3JyZWN0Lm51bWJlci5hcmd1bWVudHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmVlLmFyZ3MubGVuZ3RoKCksIGFyZ3R5cGVzLmxlbmd0aCgpKTsKICAgICAgICAgICAgfQogICAgICAgIHRyZWUuYXJncyA9IHRyYW5zbGF0ZUFyZ3ModHJlZS5hcmdzLCBhcmd0eXBlcywgdHJlZS52YXJhcmdzRWxlbWVudCk7CgogICAgICAgIHRyZWUudHlwZSA9IHR5cGVzLmVyYXN1cmUodHJlZS50eXBlKTsKICAgICAgICAvLyBJbnNlcnQgY2FzdHMgb2YgbWV0aG9kIGludm9jYXRpb24gcmVzdWx0cyBhcyBuZWVkZWQuCiAgICAgICAgcmVzdWx0ID0gcmV0eXBlKHRyZWUsIG10LmdldFJldHVyblR5cGUoKSwgcHQpOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0TmV3Q2xhc3MoSkNOZXdDbGFzcyB0cmVlKSB7CiAgICAgICAgaWYgKHRyZWUuZW5jbCAhPSBudWxsKQogICAgICAgICAgICB0cmVlLmVuY2wgPSB0cmFuc2xhdGUodHJlZS5lbmNsLCBlcmFzdXJlKHRyZWUuZW5jbC50eXBlKSk7CgogICAgICAgIFR5cGUgZXJhc2VkQ29uc3RydWN0b3JUeXBlID0gdHJlZS5jb25zdHJ1Y3RvclR5cGUgIT0gbnVsbCA/CiAgICAgICAgICAgICAgICBlcmFzdXJlKHRyZWUuY29uc3RydWN0b3JUeXBlKSA6CiAgICAgICAgICAgICAgICBudWxsOwoKICAgICAgICBMaXN0PFR5cGU+IGFyZ3R5cGVzID0gZXJhc2VkQ29uc3RydWN0b3JUeXBlICE9IG51bGwgJiYgYWxsb3dHcmFwaEluZmVyZW5jZSA/CiAgICAgICAgICAgICAgICBlcmFzZWRDb25zdHJ1Y3RvclR5cGUuZ2V0UGFyYW1ldGVyVHlwZXMoKSA6CiAgICAgICAgICAgICAgICB0cmVlLmNvbnN0cnVjdG9yLmVyYXN1cmUodHlwZXMpLmdldFBhcmFtZXRlclR5cGVzKCk7CgogICAgICAgIHRyZWUuY2xhenogPSB0cmFuc2xhdGUodHJlZS5jbGF6eiwgbnVsbCk7CiAgICAgICAgaWYgKHRyZWUudmFyYXJnc0VsZW1lbnQgIT0gbnVsbCkKICAgICAgICAgICAgdHJlZS52YXJhcmdzRWxlbWVudCA9IHR5cGVzLmVyYXN1cmUodHJlZS52YXJhcmdzRWxlbWVudCk7CiAgICAgICAgdHJlZS5hcmdzID0gdHJhbnNsYXRlQXJncygKICAgICAgICAgICAgdHJlZS5hcmdzLCBhcmd0eXBlcywgdHJlZS52YXJhcmdzRWxlbWVudCk7CiAgICAgICAgdHJlZS5kZWYgPSB0cmFuc2xhdGUodHJlZS5kZWYsIG51bGwpOwogICAgICAgIGlmIChlcmFzZWRDb25zdHJ1Y3RvclR5cGUgIT0gbnVsbCkKICAgICAgICAgICAgdHJlZS5jb25zdHJ1Y3RvclR5cGUgPSBlcmFzZWRDb25zdHJ1Y3RvclR5cGU7CiAgICAgICAgdHJlZS50eXBlID0gZXJhc3VyZSh0cmVlLnR5cGUpOwogICAgICAgIHJlc3VsdCA9IHRyZWU7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXROZXdBcnJheShKQ05ld0FycmF5IHRyZWUpIHsKICAgICAgICB0cmVlLmVsZW10eXBlID0gdHJhbnNsYXRlKHRyZWUuZWxlbXR5cGUsIG51bGwpOwogICAgICAgIHRyYW5zbGF0ZSh0cmVlLmRpbXMsIHN5bXMuaW50VHlwZSk7CiAgICAgICAgaWYgKHRyZWUudHlwZSAhPSBudWxsKSB7CiAgICAgICAgICAgIHRyZWUuZWxlbXMgPSB0cmFuc2xhdGUodHJlZS5lbGVtcywgZXJhc3VyZSh0eXBlcy5lbGVtdHlwZSh0cmVlLnR5cGUpKSk7CiAgICAgICAgICAgIHRyZWUudHlwZSA9IGVyYXN1cmUodHJlZS50eXBlKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB0cmVlLmVsZW1zID0gdHJhbnNsYXRlKHRyZWUuZWxlbXMsIG51bGwpOwogICAgICAgIH0KCiAgICAgICAgcmVzdWx0ID0gdHJlZTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdFBhcmVucyhKQ1BhcmVucyB0cmVlKSB7CiAgICAgICAgdHJlZS5leHByID0gdHJhbnNsYXRlKHRyZWUuZXhwciwgcHQpOwogICAgICAgIHRyZWUudHlwZSA9IGVyYXN1cmUodHJlZS5leHByLnR5cGUpOwogICAgICAgIHJlc3VsdCA9IHRyZWU7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRBc3NpZ24oSkNBc3NpZ24gdHJlZSkgewogICAgICAgIHRyZWUubGhzID0gdHJhbnNsYXRlKHRyZWUubGhzLCBudWxsKTsKICAgICAgICB0cmVlLnJocyA9IHRyYW5zbGF0ZSh0cmVlLnJocywgZXJhc3VyZSh0cmVlLmxocy50eXBlKSk7CiAgICAgICAgdHJlZS50eXBlID0gZXJhc3VyZSh0cmVlLmxocy50eXBlKTsKICAgICAgICByZXN1bHQgPSByZXR5cGUodHJlZSwgdHJlZS50eXBlLCBwdCk7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRBc3NpZ25vcChKQ0Fzc2lnbk9wIHRyZWUpIHsKICAgICAgICB0cmVlLmxocyA9IHRyYW5zbGF0ZSh0cmVlLmxocywgbnVsbCk7CiAgICAgICAgdHJlZS5yaHMgPSB0cmFuc2xhdGUodHJlZS5yaHMsIHRyZWUub3BlcmF0b3IudHlwZS5nZXRQYXJhbWV0ZXJUeXBlcygpLnRhaWwuaGVhZCk7CiAgICAgICAgdHJlZS50eXBlID0gZXJhc3VyZSh0cmVlLnR5cGUpOwogICAgICAgIHJlc3VsdCA9IHRyZWU7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRVbmFyeShKQ1VuYXJ5IHRyZWUpIHsKICAgICAgICB0cmVlLmFyZyA9IHRyYW5zbGF0ZSh0cmVlLmFyZywgKHRyZWUuZ2V0VGFnKCkgPT0gVGFnLk5VTExDSEspCiAgICAgICAgICAgID8gdHJlZS50eXBlCiAgICAgICAgICAgIDogdHJlZS5vcGVyYXRvci50eXBlLmdldFBhcmFtZXRlclR5cGVzKCkuaGVhZCk7CiAgICAgICAgcmVzdWx0ID0gdHJlZTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdEJpbmFyeShKQ0JpbmFyeSB0cmVlKSB7CiAgICAgICAgdHJlZS5saHMgPSB0cmFuc2xhdGUodHJlZS5saHMsIHRyZWUub3BlcmF0b3IudHlwZS5nZXRQYXJhbWV0ZXJUeXBlcygpLmhlYWQpOwogICAgICAgIHRyZWUucmhzID0gdHJhbnNsYXRlKHRyZWUucmhzLCB0cmVlLm9wZXJhdG9yLnR5cGUuZ2V0UGFyYW1ldGVyVHlwZXMoKS50YWlsLmhlYWQpOwogICAgICAgIHJlc3VsdCA9IHRyZWU7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRBbm5vdGF0ZWRUeXBlKEpDQW5ub3RhdGVkVHlwZSB0cmVlKSB7CiAgICAgICAgLy8gRm9yIG5vdywgd2UgbmVlZCB0byBrZWVwIHRoZSBhbm5vdGF0aW9ucyBpbiB0aGUgdHJlZSBiZWNhdXNlIG9mIHRoZSBjdXJyZW50CiAgICAgICAgLy8gTXVsdGlDYXRjaCBpbXBsZW1lbnRhdGlvbiB3cnQgdHlwZSBhbm5vdGF0aW9ucwogICAgICAgIExpc3Q8VHlwZUNvbXBvdW5kPiBtaXJyb3JzID0gYW5ub3RhdGUuZnJvbUFubm90YXRpb25zKHRyZWUuYW5ub3RhdGlvbnMpOwogICAgICAgIHRyZWUudW5kZXJseWluZ1R5cGUgPSB0cmFuc2xhdGUodHJlZS51bmRlcmx5aW5nVHlwZSk7CiAgICAgICAgdHJlZS50eXBlID0gdHJlZS51bmRlcmx5aW5nVHlwZS50eXBlLmFubm90YXRlZFR5cGUobWlycm9ycyk7CiAgICAgICAgcmVzdWx0ID0gdHJlZTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdFR5cGVDYXN0KEpDVHlwZUNhc3QgdHJlZSkgewogICAgICAgIHRyZWUuY2xhenogPSB0cmFuc2xhdGUodHJlZS5jbGF6eiwgbnVsbCk7CiAgICAgICAgVHlwZSBvcmlnaW5hbFRhcmdldCA9IHRyZWUudHlwZTsKICAgICAgICB0cmVlLnR5cGUgPSBlcmFzdXJlKHRyZWUudHlwZSk7CiAgICAgICAgSkNFeHByZXNzaW9uIG5ld0V4cHJlc3Npb24gPSB0cmFuc2xhdGUodHJlZS5leHByLCB0cmVlLnR5cGUpOwogICAgICAgIGlmIChuZXdFeHByZXNzaW9uICE9IHRyZWUuZXhwcikgewogICAgICAgICAgICBKQ1R5cGVDYXN0IHR5cGVDYXN0ID0gbmV3RXhwcmVzc2lvbi5oYXNUYWcoVGFnLlRZUEVDQVNUKQogICAgICAgICAgICAgICAgPyAoSkNUeXBlQ2FzdCkgbmV3RXhwcmVzc2lvbgogICAgICAgICAgICAgICAgOiBudWxsOwogICAgICAgICAgICB0cmVlLmV4cHIgPSB0eXBlQ2FzdCAhPSBudWxsICYmIHR5cGVzLmlzU2FtZVR5cGUodHlwZUNhc3QudHlwZSwgb3JpZ2luYWxUYXJnZXQsIHRydWUpCiAgICAgICAgICAgICAgICA/IHR5cGVDYXN0LmV4cHIKICAgICAgICAgICAgICAgIDogbmV3RXhwcmVzc2lvbjsKICAgICAgICB9CiAgICAgICAgaWYgKG9yaWdpbmFsVGFyZ2V0LmlzSW50ZXJzZWN0aW9uKCkpIHsKICAgICAgICAgICAgVHlwZS5JbnRlcnNlY3Rpb25DbGFzc1R5cGUgaWN0ID0gKFR5cGUuSW50ZXJzZWN0aW9uQ2xhc3NUeXBlKW9yaWdpbmFsVGFyZ2V0OwogICAgICAgICAgICBmb3IgKFR5cGUgYyA6IGljdC5nZXRFeHBsaWNpdENvbXBvbmVudHMoKSkgewogICAgICAgICAgICAgICAgVHlwZSBlYyA9IGVyYXN1cmUoYyk7CiAgICAgICAgICAgICAgICBpZiAoIXR5cGVzLmlzU2FtZVR5cGUoZWMsIHRyZWUudHlwZSkpIHsKICAgICAgICAgICAgICAgICAgICB0cmVlLmV4cHIgPSBjb2VyY2UodHJlZS5leHByLCBlYyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmVzdWx0ID0gdHJlZTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdFR5cGVUZXN0KEpDSW5zdGFuY2VPZiB0cmVlKSB7CiAgICAgICAgdHJlZS5leHByID0gdHJhbnNsYXRlKHRyZWUuZXhwciwgbnVsbCk7CiAgICAgICAgdHJlZS5jbGF6eiA9IHRyYW5zbGF0ZSh0cmVlLmNsYXp6LCBudWxsKTsKICAgICAgICByZXN1bHQgPSB0cmVlOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0SW5kZXhlZChKQ0FycmF5QWNjZXNzIHRyZWUpIHsKICAgICAgICB0cmVlLmluZGV4ZWQgPSB0cmFuc2xhdGUodHJlZS5pbmRleGVkLCBlcmFzdXJlKHRyZWUuaW5kZXhlZC50eXBlKSk7CiAgICAgICAgdHJlZS5pbmRleCA9IHRyYW5zbGF0ZSh0cmVlLmluZGV4LCBzeW1zLmludFR5cGUpOwoKICAgICAgICAvLyBJbnNlcnQgY2FzdHMgb2YgaW5kZXhlZCBleHByZXNzaW9ucyBhcyBuZWVkZWQuCiAgICAgICAgcmVzdWx0ID0gcmV0eXBlKHRyZWUsIHR5cGVzLmVsZW10eXBlKHRyZWUuaW5kZXhlZC50eXBlKSwgcHQpOwogICAgfQoKICAgIC8vIFRoZXJlIG91Z2h0IHRvIGJlIG5vdGhpbmcgdG8gcmV3cml0ZSBoZXJlOwogICAgLy8gd2UgZG9uJ3QgZ2VuZXJhdGUgY29kZS4KICAgIHB1YmxpYyB2b2lkIHZpc2l0QW5ub3RhdGlvbihKQ0Fubm90YXRpb24gdHJlZSkgewogICAgICAgIHJlc3VsdCA9IHRyZWU7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRJZGVudChKQ0lkZW50IHRyZWUpIHsKICAgICAgICBUeXBlIGV0ID0gdHJlZS5zeW0uZXJhc3VyZSh0eXBlcyk7CgogICAgICAgIC8vIE1hcCB0eXBlIHZhcmlhYmxlcyB0byB0aGVpciBib3VuZHMuCiAgICAgICAgaWYgKHRyZWUuc3ltLmtpbmQgPT0gVFlQICYmIHRyZWUuc3ltLnR5cGUuaGFzVGFnKFRZUEVWQVIpKSB7CiAgICAgICAgICAgIHJlc3VsdCA9IG1ha2UuYXQodHJlZS5wb3MpLlR5cGUoZXQpOwogICAgICAgIH0gZWxzZQogICAgICAgIC8vIE1hcCBjb25zdGFudHMgZXhwcmVzc2lvbnMgdG8gdGhlbXNlbHZlcy4KICAgICAgICBpZiAodHJlZS50eXBlLmNvbnN0VmFsdWUoKSAhPSBudWxsKSB7CiAgICAgICAgICAgIHJlc3VsdCA9IHRyZWU7CiAgICAgICAgfQogICAgICAgIC8vIEluc2VydCBjYXN0cyBvZiB2YXJpYWJsZSB1c2VzIGFzIG5lZWRlZC4KICAgICAgICBlbHNlIGlmICh0cmVlLnN5bS5raW5kID09IFZBUikgewogICAgICAgICAgICByZXN1bHQgPSByZXR5cGUodHJlZSwgZXQsIHB0KTsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIHRyZWUudHlwZSA9IGVyYXN1cmUodHJlZS50eXBlKTsKICAgICAgICAgICAgcmVzdWx0ID0gdHJlZTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRTZWxlY3QoSkNGaWVsZEFjY2VzcyB0cmVlKSB7CiAgICAgICAgVHlwZSB0ID0gdHlwZXMuc2tpcFR5cGVWYXJzKHRyZWUuc2VsZWN0ZWQudHlwZSwgZmFsc2UpOwogICAgICAgIGlmICh0LmlzQ29tcG91bmQoKSkgewogICAgICAgICAgICB0cmVlLnNlbGVjdGVkID0gY29lcmNlKAogICAgICAgICAgICAgICAgdHJhbnNsYXRlKHRyZWUuc2VsZWN0ZWQsIGVyYXN1cmUodHJlZS5zZWxlY3RlZC50eXBlKSksCiAgICAgICAgICAgICAgICBlcmFzdXJlKHRyZWUuc3ltLm93bmVyLnR5cGUpKTsKICAgICAgICB9IGVsc2UKICAgICAgICAgICAgdHJlZS5zZWxlY3RlZCA9IHRyYW5zbGF0ZSh0cmVlLnNlbGVjdGVkLCBlcmFzdXJlKHQpKTsKCiAgICAgICAgLy8gTWFwIGNvbnN0YW50cyBleHByZXNzaW9ucyB0byB0aGVtc2VsdmVzLgogICAgICAgIGlmICh0cmVlLnR5cGUuY29uc3RWYWx1ZSgpICE9IG51bGwpIHsKICAgICAgICAgICAgcmVzdWx0ID0gdHJlZTsKICAgICAgICB9CiAgICAgICAgLy8gSW5zZXJ0IGNhc3RzIG9mIHZhcmlhYmxlIHVzZXMgYXMgbmVlZGVkLgogICAgICAgIGVsc2UgaWYgKHRyZWUuc3ltLmtpbmQgPT0gVkFSKSB7CiAgICAgICAgICAgIHJlc3VsdCA9IHJldHlwZSh0cmVlLCB0cmVlLnN5bS5lcmFzdXJlKHR5cGVzKSwgcHQpOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgdHJlZS50eXBlID0gZXJhc3VyZSh0cmVlLnR5cGUpOwogICAgICAgICAgICByZXN1bHQgPSB0cmVlOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdFJlZmVyZW5jZShKQ01lbWJlclJlZmVyZW5jZSB0cmVlKSB7CiAgICAgICAgVHlwZSB0ID0gdHlwZXMuc2tpcFR5cGVWYXJzKHRyZWUuZXhwci50eXBlLCBmYWxzZSk7CiAgICAgICAgVHlwZSByZWNlaXZlclRhcmdldCA9IHQuaXNDb21wb3VuZCgpID8gZXJhc3VyZSh0cmVlLnN5bS5vd25lci50eXBlKSA6IGVyYXN1cmUodCk7CiAgICAgICAgaWYgKHRyZWUua2luZCA9PSBSZWZlcmVuY2VLaW5kLlVOQk9VTkQpIHsKICAgICAgICAgICAgdHJlZS5leHByID0gbWFrZS5UeXBlKHJlY2VpdmVyVGFyZ2V0KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB0cmVlLmV4cHIgPSB0cmFuc2xhdGUodHJlZS5leHByLCByZWNlaXZlclRhcmdldCk7CiAgICAgICAgfQoKICAgICAgICB0cmVlLnR5cGUgPSBlcmFzdXJlKHRyZWUudHlwZSk7CiAgICAgICAgaWYgKHRyZWUudmFyYXJnc0VsZW1lbnQgIT0gbnVsbCkKICAgICAgICAgICAgdHJlZS52YXJhcmdzRWxlbWVudCA9IGVyYXN1cmUodHJlZS52YXJhcmdzRWxlbWVudCk7CiAgICAgICAgcmVzdWx0ID0gdHJlZTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdFR5cGVBcnJheShKQ0FycmF5VHlwZVRyZWUgdHJlZSkgewogICAgICAgIHRyZWUuZWxlbXR5cGUgPSB0cmFuc2xhdGUodHJlZS5lbGVtdHlwZSwgbnVsbCk7CiAgICAgICAgdHJlZS50eXBlID0gZXJhc3VyZSh0cmVlLnR5cGUpOwogICAgICAgIHJlc3VsdCA9IHRyZWU7CiAgICB9CgogICAgLyoqIFZpc2l0b3IgbWV0aG9kIGZvciBwYXJhbWV0ZXJpemVkIHR5cGVzLgogICAgICovCiAgICBwdWJsaWMgdm9pZCB2aXNpdFR5cGVBcHBseShKQ1R5cGVBcHBseSB0cmVlKSB7CiAgICAgICAgSkNUcmVlIGNsYXp6ID0gdHJhbnNsYXRlKHRyZWUuY2xhenosIG51bGwpOwogICAgICAgIHJlc3VsdCA9IGNsYXp6OwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0VHlwZUludGVyc2VjdGlvbihKQ1R5cGVJbnRlcnNlY3Rpb24gdHJlZSkgewogICAgICAgIHRyZWUuYm91bmRzID0gdHJhbnNsYXRlKHRyZWUuYm91bmRzLCBudWxsKTsKICAgICAgICB0cmVlLnR5cGUgPSBlcmFzdXJlKHRyZWUudHlwZSk7CiAgICAgICAgcmVzdWx0ID0gdHJlZTsKICAgIH0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiB1dGlsaXR5IG1ldGhvZHMKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgogICAgcHJpdmF0ZSBUeXBlIGVyYXN1cmUoVHlwZSB0KSB7CiAgICAgICAgcmV0dXJuIHR5cGVzLmVyYXN1cmUodCk7CiAgICB9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogbWFpbiBtZXRob2QKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgogICAgcHJpdmF0ZSBFbnY8QXR0ckNvbnRleHQ+IGVudjsKCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgc3RhdGVQcmV2aW91c1RvRmxvd0Fzc2VydE1zZyA9CiAgICAgICAgICAgICJUaGUgY3VycmVudCBjb21waWxlIHN0YXRlIFslc10gb2YgY2xhc3MgJXMgaXMgcHJldmlvdXMgdG8gRkxPVyI7CgogICAgdm9pZCB0cmFuc2xhdGVDbGFzcyhDbGFzc1N5bWJvbCBjKSB7CiAgICAgICAgVHlwZSBzdCA9IHR5cGVzLnN1cGVydHlwZShjLnR5cGUpOwogICAgICAgIC8vIHByb2Nlc3Mgc3VwZXJjbGFzcyBiZWZvcmUgZGVyaXZlZAogICAgICAgIGlmIChzdC5oYXNUYWcoQ0xBU1MpKSB7CiAgICAgICAgICAgIHRyYW5zbGF0ZUNsYXNzKChDbGFzc1N5bWJvbClzdC50c3ltKTsKICAgICAgICB9CgogICAgICAgIEVudjxBdHRyQ29udGV4dD4gbXlFbnYgPSBlbnRlci5nZXRFbnYoYyk7CiAgICAgICAgaWYgKG15RW52ID09IG51bGwgfHwgKGMuZmxhZ3NfZmllbGQgJiBUWVBFX1RSQU5TTEFURUQpICE9IDApIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICBjLmZsYWdzX2ZpZWxkIHw9IFRZUEVfVFJBTlNMQVRFRDsKCiAgICAgICAgLyogIFRoZSB0d28gYXNzZXJ0aW9ucyBiZWxvdyBhcmUgc2V0IGZvciBlYXJseSBkZXRlY3Rpb24gb2YgYW55IGF0dGVtcHQKICAgICAgICAgKiAgdG8gdHJhbnNsYXRlIGEgY2xhc3MgdGhhdDoKICAgICAgICAgKgogICAgICAgICAqICAxKSBoYXMgbm8gY29tcGlsZSBzdGF0ZSBiZWluZyBpdCB0aGUgbW9zdCBvdXRlciBjbGFzcy4KICAgICAgICAgKiAgICAgV2UgYWNjZXB0IHRoaXMgY29uZGl0aW9uIGZvciBpbm5lciBjbGFzc2VzLgogICAgICAgICAqCiAgICAgICAgICogIDIpIGhhcyBhIGNvbXBpbGUgc3RhdGUgd2hpY2ggaXMgcHJldmlvdXMgdG8gRmxvdyBzdGF0ZS4KICAgICAgICAgKi8KICAgICAgICBib29sZWFuIGVudkhhc0NvbXBTdGF0ZSA9IGNvbXBpbGVTdGF0ZXMuZ2V0KG15RW52KSAhPSBudWxsOwogICAgICAgIGlmICghZW52SGFzQ29tcFN0YXRlICYmIGMub3V0ZXJtb3N0Q2xhc3MoKSA9PSBjKSB7CiAgICAgICAgICAgIEFzc2VydC5lcnJvcigiTm8gaW5mbyBmb3Igb3V0ZXJtb3N0IGNsYXNzOiAiICsgbXlFbnYuZW5jbENsYXNzLnN5bSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoZW52SGFzQ29tcFN0YXRlICYmCiAgICAgICAgICAgICAgICBDb21waWxlU3RhdGUuRkxPVy5pc0FmdGVyKGNvbXBpbGVTdGF0ZXMuZ2V0KG15RW52KSkpIHsKICAgICAgICAgICAgQXNzZXJ0LmVycm9yKFN0cmluZy5mb3JtYXQoc3RhdGVQcmV2aW91c1RvRmxvd0Fzc2VydE1zZywKICAgICAgICAgICAgICAgICAgICBjb21waWxlU3RhdGVzLmdldChteUVudiksIG15RW52LmVuY2xDbGFzcy5zeW0pKTsKICAgICAgICB9CgogICAgICAgIEVudjxBdHRyQ29udGV4dD4gb2xkRW52ID0gZW52OwogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGVudiA9IG15RW52OwogICAgICAgICAgICAvLyBjbGFzcyBoYXMgbm90IGJlZW4gdHJhbnNsYXRlZCB5ZXQKCiAgICAgICAgICAgIFRyZWVNYWtlciBzYXZlZE1ha2UgPSBtYWtlOwogICAgICAgICAgICBUeXBlIHNhdmVkUHQgPSBwdDsKICAgICAgICAgICAgbWFrZSA9IG1ha2UuZm9yVG9wbGV2ZWwoZW52LnRvcGxldmVsKTsKICAgICAgICAgICAgcHQgPSBudWxsOwogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgSkNDbGFzc0RlY2wgdHJlZSA9IChKQ0NsYXNzRGVjbCkgZW52LnRyZWU7CiAgICAgICAgICAgICAgICB0cmVlLnR5cGFyYW1zID0gTGlzdC5uaWwoKTsKICAgICAgICAgICAgICAgIHN1cGVyLnZpc2l0Q2xhc3NEZWYodHJlZSk7CiAgICAgICAgICAgICAgICBtYWtlLmF0KHRyZWUucG9zKTsKICAgICAgICAgICAgICAgIExpc3RCdWZmZXI8SkNUcmVlPiBicmlkZ2VzID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgICAgICAgICAgaWYgKGFsbG93SW50ZXJmYWNlQnJpZGdlcyB8fCAodHJlZS5zeW0uZmxhZ3MoKSAmIElOVEVSRkFDRSkgPT0gMCkgewogICAgICAgICAgICAgICAgICAgIGFkZEJyaWRnZXModHJlZS5wb3MoKSwgYywgYnJpZGdlcyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB0cmVlLmRlZnMgPSBicmlkZ2VzLnRvTGlzdCgpLnByZXBlbmRMaXN0KHRyZWUuZGVmcyk7CiAgICAgICAgICAgICAgICB0cmVlLnR5cGUgPSBlcmFzdXJlKHRyZWUudHlwZSk7CiAgICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgICAgICBtYWtlID0gc2F2ZWRNYWtlOwogICAgICAgICAgICAgICAgcHQgPSBzYXZlZFB0OwogICAgICAgICAgICB9CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgZW52ID0gb2xkRW52OwogICAgICAgIH0KICAgIH0KCiAgICAvKiogVHJhbnNsYXRlIGEgdG9wbGV2ZWwgY2xhc3MgZGVmaW5pdGlvbi4KICAgICAqICBAcGFyYW0gY2RlZiAgICBUaGUgZGVmaW5pdGlvbiB0byBiZSB0cmFuc2xhdGVkLgogICAgICovCiAgICBwdWJsaWMgSkNUcmVlIHRyYW5zbGF0ZVRvcExldmVsQ2xhc3MoSkNUcmVlIGNkZWYsIFRyZWVNYWtlciBtYWtlKSB7CiAgICAgICAgLy8gbm90ZSB0aGF0IHRoaXMgbWV0aG9kIGRvZXMgTk9UIHN1cHBvcnQgcmVjdXJzaW9uLgogICAgICAgIHRoaXMubWFrZSA9IG1ha2U7CiAgICAgICAgcHQgPSBudWxsOwogICAgICAgIHJldHVybiB0cmFuc2xhdGUoY2RlZiwgbnVsbCk7CiAgICB9Cn0KUEsDBAoAAAgAAAY7qUo4Kf8acGMDAHBjAwAiAAAAY29tL3N1bi90b29scy9qYXZhYy9jb21wL0F0dHIuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMTk5OSwgMjAxNywgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLmphdmFjLmNvbXA7CgppbXBvcnQgamF2YS51dGlsLio7CgppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5lbGVtZW50LkVsZW1lbnRLaW5kOwppbXBvcnQgamF2YXgudG9vbHMuSmF2YUZpbGVPYmplY3Q7CgppbXBvcnQgY29tLnN1bi5zb3VyY2UudHJlZS5JZGVudGlmaWVyVHJlZTsKaW1wb3J0IGNvbS5zdW4uc291cmNlLnRyZWUuTWVtYmVyUmVmZXJlbmNlVHJlZS5SZWZlcmVuY2VNb2RlOwppbXBvcnQgY29tLnN1bi5zb3VyY2UudHJlZS5NZW1iZXJTZWxlY3RUcmVlOwppbXBvcnQgY29tLnN1bi5zb3VyY2UudHJlZS5UcmVlVmlzaXRvcjsKaW1wb3J0IGNvbS5zdW4uc291cmNlLnV0aWwuU2ltcGxlVHJlZVZpc2l0b3I7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuKjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5EaXJlY3RpdmUuUmVxdWlyZXNGbGFnOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLkxpbnQuTGludENhdGVnb3J5OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlNjb3BlLldyaXRlYWJsZVNjb3BlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlN5bWJvbC4qOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlR5cGUuKjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5UeXBlTWV0YWRhdGEuQW5ub3RhdGlvbnM7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuVHlwZXMuRnVuY3Rpb25EZXNjcmlwdG9yTG9va3VwRXJyb3I7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvbXAuQXJndW1lbnRBdHRyLkxvY2FsQ2FjaGVDb250ZXh0OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb21wLkNoZWNrLkNoZWNrQ29udGV4dDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29tcC5EZWZlcnJlZEF0dHIuQXR0ck1vZGU7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvbXAuSW5mZXIuRnJlZVR5cGVMaXN0ZW5lcjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuanZtLio7CmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5yZXNvdXJjZXMuQ29tcGlsZXJQcm9wZXJ0aWVzLkZyYWdtZW50cy5EaWFtb25kOwppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMucmVzb3VyY2VzLkNvbXBpbGVyUHJvcGVydGllcy5GcmFnbWVudHMuRGlhbW9uZEludmFsaWRBcmc7CmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5yZXNvdXJjZXMuQ29tcGlsZXJQcm9wZXJ0aWVzLkZyYWdtZW50cy5EaWFtb25kSW52YWxpZEFyZ3M7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnJlc291cmNlcy5Db21waWxlclByb3BlcnRpZXMuRXJyb3JzOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5yZXNvdXJjZXMuQ29tcGlsZXJQcm9wZXJ0aWVzLkZyYWdtZW50czsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS4qOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkpDVHJlZS4qOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkpDVHJlZS5KQ1BvbHlFeHByZXNzaW9uLio7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuKjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5EZWZpbmVkQnkuQXBpOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkpDRGlhZ25vc3RpYy5EaWFnbm9zdGljUG9zaXRpb247CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuSkNEaWFnbm9zdGljLkZyYWdtZW50OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkxpc3Q7CgppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5GbGFncy4qOwppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5GbGFncy5BTk5PVEFUSU9OOwppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5GbGFncy5CTE9DSzsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuS2luZHMuKjsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuS2luZHMuS2luZC4qOwppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5UeXBlVGFnLio7CmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlR5cGVUYWcuV0lMRENBUkQ7CmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkpDVHJlZS5UYWcuKjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5KQ0RpYWdub3N0aWMuRGlhZ25vc3RpY0ZsYWc7CgovKiogVGhpcyBpcyB0aGUgbWFpbiBjb250ZXh0LWRlcGVuZGVudCBhbmFseXNpcyBwaGFzZSBpbiBHSkMuIEl0CiAqICBlbmNvbXBhc3NlcyBuYW1lIHJlc29sdXRpb24sIHR5cGUgY2hlY2tpbmcgYW5kIGNvbnN0YW50IGZvbGRpbmcgYXMKICogIHN1YnRhc2tzLiBTb21lIHN1YnRhc2tzIGludm9sdmUgYXV4aWxpYXJ5IGNsYXNzZXMuCiAqICBAc2VlIENoZWNrCiAqICBAc2VlIFJlc29sdmUKICogIEBzZWUgQ29uc3RGb2xkCiAqICBAc2VlIEluZmVyCiAqCiAqICA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiAgSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93biByaXNrLgogKiAgVGhpcyBjb2RlIGFuZCBpdHMgaW50ZXJuYWwgaW50ZXJmYWNlcyBhcmUgc3ViamVjdCB0byBjaGFuZ2Ugb3IKICogIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj4KICovCnB1YmxpYyBjbGFzcyBBdHRyIGV4dGVuZHMgSkNUcmVlLlZpc2l0b3IgewogICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBDb250ZXh0LktleTxBdHRyPiBhdHRyS2V5ID0gbmV3IENvbnRleHQuS2V5PD4oKTsKCiAgICBmaW5hbCBOYW1lcyBuYW1lczsKICAgIGZpbmFsIExvZyBsb2c7CiAgICBmaW5hbCBTeW10YWIgc3ltczsKICAgIGZpbmFsIFJlc29sdmUgcnM7CiAgICBmaW5hbCBPcGVyYXRvcnMgb3BlcmF0b3JzOwogICAgZmluYWwgSW5mZXIgaW5mZXI7CiAgICBmaW5hbCBBbmFseXplciBhbmFseXplcjsKICAgIGZpbmFsIERlZmVycmVkQXR0ciBkZWZlcnJlZEF0dHI7CiAgICBmaW5hbCBDaGVjayBjaGs7CiAgICBmaW5hbCBGbG93IGZsb3c7CiAgICBmaW5hbCBNZW1iZXJFbnRlciBtZW1iZXJFbnRlcjsKICAgIGZpbmFsIFR5cGVFbnRlciB0eXBlRW50ZXI7CiAgICBmaW5hbCBUcmVlTWFrZXIgbWFrZTsKICAgIGZpbmFsIENvbnN0Rm9sZCBjZm9sZGVyOwogICAgZmluYWwgRW50ZXIgZW50ZXI7CiAgICBmaW5hbCBUYXJnZXQgdGFyZ2V0OwogICAgZmluYWwgVHlwZXMgdHlwZXM7CiAgICBmaW5hbCBKQ0RpYWdub3N0aWMuRmFjdG9yeSBkaWFnczsKICAgIGZpbmFsIFR5cGVBbm5vdGF0aW9ucyB0eXBlQW5ub3RhdGlvbnM7CiAgICBmaW5hbCBEZWZlcnJlZExpbnRIYW5kbGVyIGRlZmVycmVkTGludEhhbmRsZXI7CiAgICBmaW5hbCBUeXBlRW52cyB0eXBlRW52czsKICAgIGZpbmFsIERlcGVuZGVuY2llcyBkZXBlbmRlbmNpZXM7CiAgICBmaW5hbCBBbm5vdGF0ZSBhbm5vdGF0ZTsKICAgIGZpbmFsIEFyZ3VtZW50QXR0ciBhcmd1bWVudEF0dHI7CgogICAgcHVibGljIHN0YXRpYyBBdHRyIGluc3RhbmNlKENvbnRleHQgY29udGV4dCkgewogICAgICAgIEF0dHIgaW5zdGFuY2UgPSBjb250ZXh0LmdldChhdHRyS2V5KTsKICAgICAgICBpZiAoaW5zdGFuY2UgPT0gbnVsbCkKICAgICAgICAgICAgaW5zdGFuY2UgPSBuZXcgQXR0cihjb250ZXh0KTsKICAgICAgICByZXR1cm4gaW5zdGFuY2U7CiAgICB9CgogICAgcHJvdGVjdGVkIEF0dHIoQ29udGV4dCBjb250ZXh0KSB7CiAgICAgICAgY29udGV4dC5wdXQoYXR0cktleSwgdGhpcyk7CgogICAgICAgIG5hbWVzID0gTmFtZXMuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgbG9nID0gTG9nLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIHN5bXMgPSBTeW10YWIuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgcnMgPSBSZXNvbHZlLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIG9wZXJhdG9ycyA9IE9wZXJhdG9ycy5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBjaGsgPSBDaGVjay5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBmbG93ID0gRmxvdy5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBtZW1iZXJFbnRlciA9IE1lbWJlckVudGVyLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIHR5cGVFbnRlciA9IFR5cGVFbnRlci5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBtYWtlID0gVHJlZU1ha2VyLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIGVudGVyID0gRW50ZXIuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgaW5mZXIgPSBJbmZlci5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBhbmFseXplciA9IEFuYWx5emVyLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIGRlZmVycmVkQXR0ciA9IERlZmVycmVkQXR0ci5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBjZm9sZGVyID0gQ29uc3RGb2xkLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIHRhcmdldCA9IFRhcmdldC5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICB0eXBlcyA9IFR5cGVzLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIGRpYWdzID0gSkNEaWFnbm9zdGljLkZhY3RvcnkuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgYW5ub3RhdGUgPSBBbm5vdGF0ZS5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICB0eXBlQW5ub3RhdGlvbnMgPSBUeXBlQW5ub3RhdGlvbnMuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgZGVmZXJyZWRMaW50SGFuZGxlciA9IERlZmVycmVkTGludEhhbmRsZXIuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgdHlwZUVudnMgPSBUeXBlRW52cy5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBkZXBlbmRlbmNpZXMgPSBEZXBlbmRlbmNpZXMuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgYXJndW1lbnRBdHRyID0gQXJndW1lbnRBdHRyLmluc3RhbmNlKGNvbnRleHQpOwoKICAgICAgICBPcHRpb25zIG9wdGlvbnMgPSBPcHRpb25zLmluc3RhbmNlKGNvbnRleHQpOwoKICAgICAgICBTb3VyY2Ugc291cmNlID0gU291cmNlLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIGFsbG93U3RyaW5nc0luU3dpdGNoID0gc291cmNlLmFsbG93U3RyaW5nc0luU3dpdGNoKCk7CiAgICAgICAgYWxsb3dQb2x5ID0gc291cmNlLmFsbG93UG9seSgpOwogICAgICAgIGFsbG93VHlwZUFubm9zID0gc291cmNlLmFsbG93VHlwZUFubm90YXRpb25zKCk7CiAgICAgICAgYWxsb3dMYW1iZGEgPSBzb3VyY2UuYWxsb3dMYW1iZGEoKTsKICAgICAgICBhbGxvd0RlZmF1bHRNZXRob2RzID0gc291cmNlLmFsbG93RGVmYXVsdE1ldGhvZHMoKTsKICAgICAgICBhbGxvd1N0YXRpY0ludGVyZmFjZU1ldGhvZHMgPSBzb3VyY2UuYWxsb3dTdGF0aWNJbnRlcmZhY2VNZXRob2RzKCk7CiAgICAgICAgc291cmNlTmFtZSA9IHNvdXJjZS5uYW1lOwogICAgICAgIHVzZUJlZm9yZURlY2xhcmF0aW9uV2FybmluZyA9IG9wdGlvbnMuaXNTZXQoInVzZUJlZm9yZURlY2xhcmF0aW9uV2FybmluZyIpOwoKICAgICAgICBzdGF0SW5mbyA9IG5ldyBSZXN1bHRJbmZvKEtpbmRTZWxlY3Rvci5OSUwsIFR5cGUubm9UeXBlKTsKICAgICAgICB2YXJBc3NpZ25tZW50SW5mbyA9IG5ldyBSZXN1bHRJbmZvKEtpbmRTZWxlY3Rvci5BU0csIFR5cGUubm9UeXBlKTsKICAgICAgICB1bmtub3duRXhwckluZm8gPSBuZXcgUmVzdWx0SW5mbyhLaW5kU2VsZWN0b3IuVkFMLCBUeXBlLm5vVHlwZSk7CiAgICAgICAgbWV0aG9kQXR0ckluZm8gPSBuZXcgTWV0aG9kQXR0ckluZm8oKTsKICAgICAgICB1bmtub3duVHlwZUluZm8gPSBuZXcgUmVzdWx0SW5mbyhLaW5kU2VsZWN0b3IuVFlQLCBUeXBlLm5vVHlwZSk7CiAgICAgICAgdW5rbm93blR5cGVFeHBySW5mbyA9IG5ldyBSZXN1bHRJbmZvKEtpbmRTZWxlY3Rvci5WQUxfVFlQLCBUeXBlLm5vVHlwZSk7CiAgICAgICAgcmVjb3ZlcnlJbmZvID0gbmV3IFJlY292ZXJ5SW5mbyhkZWZlcnJlZEF0dHIuZW1wdHlEZWZlcnJlZEF0dHJDb250ZXh0KTsKICAgIH0KCiAgICAvKiogU3dpdGNoOiBzdXBwb3J0IHRhcmdldC10eXBpbmcgaW5mZXJlbmNlCiAgICAgKi8KICAgIGJvb2xlYW4gYWxsb3dQb2x5OwoKICAgIC8qKiBTd2l0Y2g6IHN1cHBvcnQgdHlwZSBhbm5vdGF0aW9ucy4KICAgICAqLwogICAgYm9vbGVhbiBhbGxvd1R5cGVBbm5vczsKCiAgICAvKiogU3dpdGNoOiBzdXBwb3J0IGxhbWJkYSBleHByZXNzaW9ucyA/CiAgICAgKi8KICAgIGJvb2xlYW4gYWxsb3dMYW1iZGE7CgogICAgLyoqIFN3aXRjaDogc3VwcG9ydCBkZWZhdWx0IG1ldGhvZHMgPwogICAgICovCiAgICBib29sZWFuIGFsbG93RGVmYXVsdE1ldGhvZHM7CgogICAgLyoqIFN3aXRjaDogc3RhdGljIGludGVyZmFjZSBtZXRob2RzIGVuYWJsZWQ/CiAgICAgKi8KICAgIGJvb2xlYW4gYWxsb3dTdGF0aWNJbnRlcmZhY2VNZXRob2RzOwoKICAgIC8qKgogICAgICogU3dpdGNoOiB3YXJuIGFib3V0IHVzZSBvZiB2YXJpYWJsZSBiZWZvcmUgZGVjbGFyYXRpb24/CiAgICAgKiBSRkU6IDY0MjU1OTQKICAgICAqLwogICAgYm9vbGVhbiB1c2VCZWZvcmVEZWNsYXJhdGlvbldhcm5pbmc7CgogICAgLyoqCiAgICAgKiBTd2l0Y2g6IGFsbG93IHN0cmluZ3MgaW4gc3dpdGNoPwogICAgICovCiAgICBib29sZWFuIGFsbG93U3RyaW5nc0luU3dpdGNoOwoKICAgIC8qKgogICAgICogU3dpdGNoOiBuYW1lIG9mIHNvdXJjZSBsZXZlbDsgdXNlZCBmb3IgZXJyb3IgcmVwb3J0aW5nLgogICAgICovCiAgICBTdHJpbmcgc291cmNlTmFtZTsKCiAgICAvKiogQ2hlY2sga2luZCBhbmQgdHlwZSBvZiBnaXZlbiB0cmVlIGFnYWluc3QgcHJvdG9raW5kIGFuZCBwcm90b3R5cGUuCiAgICAgKiAgSWYgY2hlY2sgc3VjY2VlZHMsIHN0b3JlIHR5cGUgaW4gdHJlZSBhbmQgcmV0dXJuIGl0LgogICAgICogIElmIGNoZWNrIGZhaWxzLCBzdG9yZSBlcnJUeXBlIGluIHRyZWUgYW5kIHJldHVybiBpdC4KICAgICAqICBObyBjaGVja3MgYXJlIHBlcmZvcm1lZCBpZiB0aGUgcHJvdG90eXBlIGlzIGEgbWV0aG9kIHR5cGUuCiAgICAgKiAgSXQgaXMgbm90IG5lY2Vzc2FyeSBpbiB0aGlzIGNhc2Ugc2luY2Ugd2Uga25vdyB0aGF0IGtpbmQgYW5kIHR5cGUKICAgICAqICBhcmUgY29ycmVjdC4KICAgICAqCiAgICAgKiAgQHBhcmFtIHRyZWUgICAgIFRoZSB0cmVlIHdob3NlIGtpbmQgYW5kIHR5cGUgaXMgY2hlY2tlZAogICAgICogIEBwYXJhbSBmb3VuZCAgICBUaGUgY29tcHV0ZWQgdHlwZSBvZiB0aGUgdHJlZQogICAgICogIEBwYXJhbSBvd25raW5kICBUaGUgY29tcHV0ZWQga2luZCBvZiB0aGUgdHJlZQogICAgICogIEBwYXJhbSByZXN1bHRJbmZvICBUaGUgZXhwZWN0ZWQgcmVzdWx0IG9mIHRoZSB0cmVlCiAgICAgKi8KICAgIFR5cGUgY2hlY2soZmluYWwgSkNUcmVlIHRyZWUsCiAgICAgICAgICAgICAgIGZpbmFsIFR5cGUgZm91bmQsCiAgICAgICAgICAgICAgIGZpbmFsIEtpbmRTZWxlY3RvciBvd25raW5kLAogICAgICAgICAgICAgICBmaW5hbCBSZXN1bHRJbmZvIHJlc3VsdEluZm8pIHsKICAgICAgICBJbmZlcmVuY2VDb250ZXh0IGluZmVyZW5jZUNvbnRleHQgPSByZXN1bHRJbmZvLmNoZWNrQ29udGV4dC5pbmZlcmVuY2VDb250ZXh0KCk7CiAgICAgICAgVHlwZSBvd250eXBlOwogICAgICAgIGJvb2xlYW4gc2hvdWxkQ2hlY2sgPSAhZm91bmQuaGFzVGFnKEVSUk9SKSAmJgogICAgICAgICAgICAgICAgIXJlc3VsdEluZm8ucHQuaGFzVGFnKE1FVEhPRCkgJiYKICAgICAgICAgICAgICAgICFyZXN1bHRJbmZvLnB0Lmhhc1RhZyhGT1JBTEwpOwogICAgICAgIGlmIChzaG91bGRDaGVjayAmJiAhb3dua2luZC5zdWJzZXQocmVzdWx0SW5mby5wa2luZCkpIHsKICAgICAgICAgICAgbG9nLmVycm9yKHRyZWUucG9zKCksICJ1bmV4cGVjdGVkLnR5cGUiLAogICAgICAgICAgICByZXN1bHRJbmZvLnBraW5kLmtpbmROYW1lcygpLAogICAgICAgICAgICBvd25raW5kLmtpbmROYW1lcygpKTsKICAgICAgICAgICAgb3dudHlwZSA9IHR5cGVzLmNyZWF0ZUVycm9yVHlwZShmb3VuZCk7CiAgICAgICAgfSBlbHNlIGlmIChhbGxvd1BvbHkgJiYgaW5mZXJlbmNlQ29udGV4dC5mcmVlKGZvdW5kKSkgewogICAgICAgICAgICAvL2RlbGF5IHRoZSBjaGVjayBpZiB0aGVyZSBhcmUgaW5mZXJlbmNlIHZhcmlhYmxlcyBpbiB0aGUgZm91bmQgdHlwZQogICAgICAgICAgICAvL3RoaXMgbWVhbnMgd2UgYXJlIGRlYWxpbmcgd2l0aCBhIHBhcnRpYWxseSBpbmZlcnJlZCBwb2x5IGV4cHJlc3Npb24KICAgICAgICAgICAgb3dudHlwZSA9IHNob3VsZENoZWNrID8gcmVzdWx0SW5mby5wdCA6IGZvdW5kOwogICAgICAgICAgICBpZiAocmVzdWx0SW5mby5jaGVja01vZGUuaW5zdGFsbFBvc3RJbmZlcmVuY2VIb29rKCkpIHsKICAgICAgICAgICAgICAgIGluZmVyZW5jZUNvbnRleHQuYWRkRnJlZVR5cGVMaXN0ZW5lcihMaXN0Lm9mKGZvdW5kKSwKICAgICAgICAgICAgICAgICAgICAgICAgaW5zdGFudGlhdGVkQ29udGV4dCAtPiB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZXN1bHRJbmZvIHBlbmRpbmdSZXN1bHQgPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHRJbmZvLmR1cChpbmZlcmVuY2VDb250ZXh0LmFzSW5zdFR5cGUocmVzdWx0SW5mby5wdCkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2sodHJlZSwgaW5mZXJlbmNlQ29udGV4dC5hc0luc3RUeXBlKGZvdW5kKSwgb3dua2luZCwgcGVuZGluZ1Jlc3VsdCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgb3dudHlwZSA9IHNob3VsZENoZWNrID8KICAgICAgICAgICAgcmVzdWx0SW5mby5jaGVjayh0cmVlLCBmb3VuZCkgOgogICAgICAgICAgICBmb3VuZDsKICAgICAgICB9CiAgICAgICAgaWYgKHJlc3VsdEluZm8uY2hlY2tNb2RlLnVwZGF0ZVRyZWVUeXBlKCkpIHsKICAgICAgICAgICAgdHJlZS50eXBlID0gb3dudHlwZTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG93bnR5cGU7CiAgICB9CgogICAgLyoqIElzIGdpdmVuIGJsYW5rIGZpbmFsIHZhcmlhYmxlIGFzc2lnbmFibGUsIGkuZS4gaW4gYSBzY29wZSB3aGVyZSBpdAogICAgICogIG1heSBiZSBhc3NpZ25lZCB0byBldmVuIHRob3VnaCBpdCBpcyBmaW5hbD8KICAgICAqICBAcGFyYW0gdiAgICAgIFRoZSBibGFuayBmaW5hbCB2YXJpYWJsZS4KICAgICAqICBAcGFyYW0gZW52ICAgIFRoZSBjdXJyZW50IGVudmlyb25tZW50LgogICAgICovCiAgICBib29sZWFuIGlzQXNzaWduYWJsZUFzQmxhbmtGaW5hbChWYXJTeW1ib2wgdiwgRW52PEF0dHJDb250ZXh0PiBlbnYpIHsKICAgICAgICBTeW1ib2wgb3duZXIgPSBlbnYuaW5mby5zY29wZS5vd25lcjsKICAgICAgICAgICAvLyBvd25lciByZWZlcnMgdG8gdGhlIGlubmVybW9zdCB2YXJpYWJsZSwgbWV0aG9kIG9yCiAgICAgICAgICAgLy8gaW5pdGlhbGl6ZXIgYmxvY2sgZGVjbGFyYXRpb24gYXQgdGhpcyBwb2ludC4KICAgICAgICByZXR1cm4KICAgICAgICAgICAgdi5vd25lciA9PSBvd25lcgogICAgICAgICAgICB8fAogICAgICAgICAgICAoKG93bmVyLm5hbWUgPT0gbmFtZXMuaW5pdCB8fCAgICAvLyBpLmUuIHdlIGFyZSBpbiBhIGNvbnN0cnVjdG9yCiAgICAgICAgICAgICAgb3duZXIua2luZCA9PSBWQVIgfHwgICAgICAgICAgIC8vIGkuZS4gd2UgYXJlIGluIGEgdmFyaWFibGUgaW5pdGlhbGl6ZXIKICAgICAgICAgICAgICAob3duZXIuZmxhZ3MoKSAmIEJMT0NLKSAhPSAwKSAgLy8gaS5lLiB3ZSBhcmUgaW4gYW4gaW5pdGlhbGl6ZXIgYmxvY2sKICAgICAgICAgICAgICYmCiAgICAgICAgICAgICB2Lm93bmVyID09IG93bmVyLm93bmVyCiAgICAgICAgICAgICAmJgogICAgICAgICAgICAgKCh2LmZsYWdzKCkgJiBTVEFUSUMpICE9IDApID09IFJlc29sdmUuaXNTdGF0aWMoZW52KSk7CiAgICB9CgogICAgLyoqIENoZWNrIHRoYXQgdmFyaWFibGUgY2FuIGJlIGFzc2lnbmVkIHRvLgogICAgICogIEBwYXJhbSBwb3MgICAgVGhlIGN1cnJlbnQgc291cmNlIGNvZGUgcG9zaXRpb24uCiAgICAgKiAgQHBhcmFtIHYgICAgICBUaGUgYXNzaWduZWQgdmFyaWFibGUKICAgICAqICBAcGFyYW0gYmFzZSAgIElmIHRoZSB2YXJpYWJsZSBpcyByZWZlcnJlZCB0byBpbiBhIFNlbGVjdCwgdGhlIHBhcnQKICAgICAqICAgICAgICAgICAgICAgIHRvIHRoZSBsZWZ0IG9mIHRoZSBgLicsIG51bGwgb3RoZXJ3aXNlLgogICAgICogIEBwYXJhbSBlbnYgICAgVGhlIGN1cnJlbnQgZW52aXJvbm1lbnQuCiAgICAgKi8KICAgIHZvaWQgY2hlY2tBc3NpZ25hYmxlKERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIFZhclN5bWJvbCB2LCBKQ1RyZWUgYmFzZSwgRW52PEF0dHJDb250ZXh0PiBlbnYpIHsKICAgICAgICBpZiAodi5uYW1lID09IG5hbWVzLl90aGlzKSB7CiAgICAgICAgICAgIGxvZy5lcnJvcihwb3MsIEVycm9ycy5DYW50QXNzaWduVmFsVG9UaGlzKTsKICAgICAgICB9IGVsc2UgaWYgKCh2LmZsYWdzKCkgJiBGSU5BTCkgIT0gMCAmJgogICAgICAgICAgICAoKHYuZmxhZ3MoKSAmIEhBU0lOSVQpICE9IDAKICAgICAgICAgICAgIHx8CiAgICAgICAgICAgICAhKChiYXNlID09IG51bGwgfHwKICAgICAgICAgICAgICAgKGJhc2UuaGFzVGFnKElERU5UKSAmJiBUcmVlSW5mby5uYW1lKGJhc2UpID09IG5hbWVzLl90aGlzKSkgJiYKICAgICAgICAgICAgICAgaXNBc3NpZ25hYmxlQXNCbGFua0ZpbmFsKHYsIGVudikpKSkgewogICAgICAgICAgICBpZiAodi5pc1Jlc291cmNlVmFyaWFibGUoKSkgeyAvL1RXUiByZXNvdXJjZQogICAgICAgICAgICAgICAgbG9nLmVycm9yKHBvcywgInRyeS5yZXNvdXJjZS5tYXkubm90LmJlLmFzc2lnbmVkIiwgdik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBsb2cuZXJyb3IocG9zLCAiY2FudC5hc3NpZ24udmFsLnRvLmZpbmFsLnZhciIsIHYpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKiBEb2VzIHRyZWUgcmVwcmVzZW50IGEgc3RhdGljIHJlZmVyZW5jZSB0byBhbiBpZGVudGlmaWVyPwogICAgICogIEl0IGlzIGFzc3VtZWQgdGhhdCB0cmVlIGlzIGVpdGhlciBhIFNFTEVDVCBvciBhbiBJREVOVC4KICAgICAqICBXZSBoYXZlIHRvIHdlZWQgb3V0IHNlbGVjdHMgZnJvbSBub24tdHlwZSBuYW1lcyBoZXJlLgogICAgICogIEBwYXJhbSB0cmVlICAgIFRoZSBjYW5kaWRhdGUgdHJlZS4KICAgICAqLwogICAgYm9vbGVhbiBpc1N0YXRpY1JlZmVyZW5jZShKQ1RyZWUgdHJlZSkgewogICAgICAgIGlmICh0cmVlLmhhc1RhZyhTRUxFQ1QpKSB7CiAgICAgICAgICAgIFN5bWJvbCBsc3ltID0gVHJlZUluZm8uc3ltYm9sKCgoSkNGaWVsZEFjY2VzcykgdHJlZSkuc2VsZWN0ZWQpOwogICAgICAgICAgICBpZiAobHN5bSA9PSBudWxsIHx8IGxzeW0ua2luZCAhPSBUWVApIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICAvKiogSXMgdGhpcyBzeW1ib2wgYSB0eXBlPwogICAgICovCiAgICBzdGF0aWMgYm9vbGVhbiBpc1R5cGUoU3ltYm9sIHN5bSkgewogICAgICAgIHJldHVybiBzeW0gIT0gbnVsbCAmJiBzeW0ua2luZCA9PSBUWVA7CiAgICB9CgogICAgLyoqIFRoZSBjdXJyZW50IGB0aGlzJyBzeW1ib2wuCiAgICAgKiAgQHBhcmFtIGVudiAgICBUaGUgY3VycmVudCBlbnZpcm9ubWVudC4KICAgICAqLwogICAgU3ltYm9sIHRoaXNTeW0oRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcywgRW52PEF0dHJDb250ZXh0PiBlbnYpIHsKICAgICAgICByZXR1cm4gcnMucmVzb2x2ZVNlbGYocG9zLCBlbnYsIGVudi5lbmNsQ2xhc3Muc3ltLCBuYW1lcy5fdGhpcyk7CiAgICB9CgogICAgLyoqIEF0dHJpYnV0ZSBhIHBhcnNlZCBpZGVudGlmaWVyLgogICAgICogQHBhcmFtIHRyZWUgUGFyc2VkIGlkZW50aWZpZXIgbmFtZQogICAgICogQHBhcmFtIHRvcExldmVsIFRoZSB0b3BsZXZlbCB0byB1c2UKICAgICAqLwogICAgcHVibGljIFN5bWJvbCBhdHRyaWJJZGVudChKQ1RyZWUgdHJlZSwgSkNDb21waWxhdGlvblVuaXQgdG9wTGV2ZWwpIHsKICAgICAgICBFbnY8QXR0ckNvbnRleHQ+IGxvY2FsRW52ID0gZW50ZXIudG9wTGV2ZWxFbnYodG9wTGV2ZWwpOwogICAgICAgIGxvY2FsRW52LmVuY2xDbGFzcyA9IG1ha2UuQ2xhc3NEZWYobWFrZS5Nb2RpZmllcnMoMCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeW1zLmVyclN5bWJvbC5uYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCwgbnVsbCwgbnVsbCwgbnVsbCk7CiAgICAgICAgbG9jYWxFbnYuZW5jbENsYXNzLnN5bSA9IHN5bXMuZXJyU3ltYm9sOwogICAgICAgIHJldHVybiBhdHRyaWJJZGVudCh0cmVlLCBsb2NhbEVudik7CiAgICB9CgogICAgLyoqIEF0dHJpYnV0ZSBhIHBhcnNlZCBpZGVudGlmaWVyLgogICAgICogQHBhcmFtIHRyZWUgUGFyc2VkIGlkZW50aWZpZXIgbmFtZQogICAgICogQHBhcmFtIGVudiBUaGUgZW52IHRvIHVzZQogICAgICovCiAgICBwdWJsaWMgU3ltYm9sIGF0dHJpYklkZW50KEpDVHJlZSB0cmVlLCBFbnY8QXR0ckNvbnRleHQ+IGVudikgewogICAgICAgIHJldHVybiB0cmVlLmFjY2VwdChpZGVudEF0dHJpYnV0ZXIsIGVudik7CiAgICB9CiAgICAvLyB3aGVyZQogICAgICAgIHByaXZhdGUgVHJlZVZpc2l0b3I8U3ltYm9sLEVudjxBdHRyQ29udGV4dD4+IGlkZW50QXR0cmlidXRlciA9IG5ldyBJZGVudEF0dHJpYnV0ZXIoKTsKICAgICAgICBwcml2YXRlIGNsYXNzIElkZW50QXR0cmlidXRlciBleHRlbmRzIFNpbXBsZVRyZWVWaXNpdG9yPFN5bWJvbCxFbnY8QXR0ckNvbnRleHQ+PiB7CiAgICAgICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgICAgICBwdWJsaWMgU3ltYm9sIHZpc2l0TWVtYmVyU2VsZWN0KE1lbWJlclNlbGVjdFRyZWUgbm9kZSwgRW52PEF0dHJDb250ZXh0PiBlbnYpIHsKICAgICAgICAgICAgICAgIFN5bWJvbCBzaXRlID0gdmlzaXQobm9kZS5nZXRFeHByZXNzaW9uKCksIGVudik7CiAgICAgICAgICAgICAgICBpZiAoc2l0ZS5raW5kID09IEVSUiB8fCBzaXRlLmtpbmQgPT0gQUJTRU5UX1RZUCB8fCBzaXRlLmtpbmQgPT0gSElEREVOKQogICAgICAgICAgICAgICAgICAgIHJldHVybiBzaXRlOwogICAgICAgICAgICAgICAgTmFtZSBuYW1lID0gKE5hbWUpbm9kZS5nZXRJZGVudGlmaWVyKCk7CiAgICAgICAgICAgICAgICBpZiAoc2l0ZS5raW5kID09IFBDSykgewogICAgICAgICAgICAgICAgICAgIGVudi50b3BsZXZlbC5wYWNrZ2UgPSAoUGFja2FnZVN5bWJvbClzaXRlOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBycy5maW5kSWRlbnRJblBhY2thZ2UoZW52LCAoVHlwZVN5bWJvbClzaXRlLCBuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgS2luZFNlbGVjdG9yLlRZUF9QQ0spOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBlbnYuZW5jbENsYXNzLnN5bSA9IChDbGFzc1N5bWJvbClzaXRlOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBycy5maW5kTWVtYmVyVHlwZShlbnYsIHNpdGUuYXNUeXBlKCksIG5hbWUsIChUeXBlU3ltYm9sKXNpdGUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICAgICAgcHVibGljIFN5bWJvbCB2aXNpdElkZW50aWZpZXIoSWRlbnRpZmllclRyZWUgbm9kZSwgRW52PEF0dHJDb250ZXh0PiBlbnYpIHsKICAgICAgICAgICAgICAgIHJldHVybiBycy5maW5kSWRlbnQoZW52LCAoTmFtZSlub2RlLmdldE5hbWUoKSwgS2luZFNlbGVjdG9yLlRZUF9QQ0spOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgIHB1YmxpYyBUeXBlIGNvZXJjZShUeXBlIGV0eXBlLCBUeXBlIHR0eXBlKSB7CiAgICAgICAgcmV0dXJuIGNmb2xkZXIuY29lcmNlKGV0eXBlLCB0dHlwZSk7CiAgICB9CgogICAgcHVibGljIFR5cGUgYXR0cmliVHlwZShKQ1RyZWUgbm9kZSwgVHlwZVN5bWJvbCBzeW0pIHsKICAgICAgICBFbnY8QXR0ckNvbnRleHQ+IGVudiA9IHR5cGVFbnZzLmdldChzeW0pOwogICAgICAgIEVudjxBdHRyQ29udGV4dD4gbG9jYWxFbnYgPSBlbnYuZHVwKG5vZGUsIGVudi5pbmZvLmR1cCgpKTsKICAgICAgICByZXR1cm4gYXR0cmliVHJlZShub2RlLCBsb2NhbEVudiwgdW5rbm93blR5cGVJbmZvKTsKICAgIH0KCiAgICBwdWJsaWMgVHlwZSBhdHRyaWJJbXBvcnRRdWFsaWZpZXIoSkNJbXBvcnQgdHJlZSwgRW52PEF0dHJDb250ZXh0PiBlbnYpIHsKICAgICAgICAvLyBBdHRyaWJ1dGUgcXVhbGlmeWluZyBwYWNrYWdlIG9yIGNsYXNzLgogICAgICAgIEpDRmllbGRBY2Nlc3MgcyA9IChKQ0ZpZWxkQWNjZXNzKXRyZWUucXVhbGlkOwogICAgICAgIHJldHVybiBhdHRyaWJUcmVlKHMuc2VsZWN0ZWQsIGVudiwKICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgUmVzdWx0SW5mbyh0cmVlLnN0YXRpY0ltcG9ydCA/CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgS2luZFNlbGVjdG9yLlRZUCA6IEtpbmRTZWxlY3Rvci5UWVBfUENLLAogICAgICAgICAgICAgICAgICAgICAgIFR5cGUubm9UeXBlKSk7CiAgICB9CgogICAgcHVibGljIEVudjxBdHRyQ29udGV4dD4gYXR0cmliRXhwclRvVHJlZShKQ1RyZWUgZXhwciwgRW52PEF0dHJDb250ZXh0PiBlbnYsIEpDVHJlZSB0cmVlKSB7CiAgICAgICAgYnJlYWtUcmVlID0gdHJlZTsKICAgICAgICBKYXZhRmlsZU9iamVjdCBwcmV2ID0gbG9nLnVzZVNvdXJjZShlbnYudG9wbGV2ZWwuc291cmNlZmlsZSk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgYXR0cmliRXhwcihleHByLCBlbnYpOwogICAgICAgIH0gY2F0Y2ggKEJyZWFrQXR0ciBiKSB7CiAgICAgICAgICAgIHJldHVybiBiLmVudjsKICAgICAgICB9IGNhdGNoIChBc3NlcnRpb25FcnJvciBhZSkgewogICAgICAgICAgICBpZiAoYWUuZ2V0Q2F1c2UoKSBpbnN0YW5jZW9mIEJyZWFrQXR0cikgewogICAgICAgICAgICAgICAgcmV0dXJuICgoQnJlYWtBdHRyKShhZS5nZXRDYXVzZSgpKSkuZW52OwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdGhyb3cgYWU7CiAgICAgICAgICAgIH0KICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICBicmVha1RyZWUgPSBudWxsOwogICAgICAgICAgICBsb2cudXNlU291cmNlKHByZXYpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZW52OwogICAgfQoKICAgIHB1YmxpYyBFbnY8QXR0ckNvbnRleHQ+IGF0dHJpYlN0YXRUb1RyZWUoSkNUcmVlIHN0bXQsIEVudjxBdHRyQ29udGV4dD4gZW52LCBKQ1RyZWUgdHJlZSkgewogICAgICAgIGJyZWFrVHJlZSA9IHRyZWU7CiAgICAgICAgSmF2YUZpbGVPYmplY3QgcHJldiA9IGxvZy51c2VTb3VyY2UoZW52LnRvcGxldmVsLnNvdXJjZWZpbGUpOwogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGF0dHJpYlN0YXQoc3RtdCwgZW52KTsKICAgICAgICB9IGNhdGNoIChCcmVha0F0dHIgYikgewogICAgICAgICAgICByZXR1cm4gYi5lbnY7CiAgICAgICAgfSBjYXRjaCAoQXNzZXJ0aW9uRXJyb3IgYWUpIHsKICAgICAgICAgICAgaWYgKGFlLmdldENhdXNlKCkgaW5zdGFuY2VvZiBCcmVha0F0dHIpIHsKICAgICAgICAgICAgICAgIHJldHVybiAoKEJyZWFrQXR0cikoYWUuZ2V0Q2F1c2UoKSkpLmVudjsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHRocm93IGFlOwogICAgICAgICAgICB9CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgYnJlYWtUcmVlID0gbnVsbDsKICAgICAgICAgICAgbG9nLnVzZVNvdXJjZShwcmV2KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGVudjsKICAgIH0KCiAgICBwcml2YXRlIEpDVHJlZSBicmVha1RyZWUgPSBudWxsOwoKICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIEJyZWFrQXR0ciBleHRlbmRzIFJ1bnRpbWVFeGNlcHRpb24gewogICAgICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNjkyNDc3MTEzMDQwNTQ0NjQwNUw7CiAgICAgICAgcHJpdmF0ZSBFbnY8QXR0ckNvbnRleHQ+IGVudjsKICAgICAgICBwcml2YXRlIEJyZWFrQXR0cihFbnY8QXR0ckNvbnRleHQ+IGVudikgewogICAgICAgICAgICB0aGlzLmVudiA9IGVudjsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBNb2RlIGNvbnRyb2xsaW5nIGJlaGF2aW9yIG9mIEF0dHIuQ2hlY2sKICAgICAqLwogICAgZW51bSBDaGVja01vZGUgewoKICAgICAgICBOT1JNQUwsCgogICAgICAgIE5PX1RSRUVfVVBEQVRFIHsgICAgIC8vIE1vZGUgc2lnbmFsbGluZyAnZmFrZSBjaGVjaycgLSBza2lwIHRyZWUgdXBkYXRlCiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgYm9vbGVhbiB1cGRhdGVUcmVlVHlwZSgpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgTk9fSU5GRVJFTkNFX0hPT0sgeyAvLyBNb2RlIHNpZ25hbGxpbmcgdGhhdCBjYWxsZXIgd2lsbCBtYW5hZ2UgZnJlZSB0eXBlcyBpbiB0cmVlIGRlY29yYXRpb25zLgogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHVibGljIGJvb2xlYW4gaW5zdGFsbFBvc3RJbmZlcmVuY2VIb29rKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfTsKCiAgICAgICAgcHVibGljIGJvb2xlYW4gdXBkYXRlVHJlZVR5cGUoKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KICAgICAgICBwdWJsaWMgYm9vbGVhbiBpbnN0YWxsUG9zdEluZmVyZW5jZUhvb2soKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KICAgIH0KCgogICAgY2xhc3MgUmVzdWx0SW5mbyB7CiAgICAgICAgZmluYWwgS2luZFNlbGVjdG9yIHBraW5kOwogICAgICAgIGZpbmFsIFR5cGUgcHQ7CiAgICAgICAgZmluYWwgQ2hlY2tDb250ZXh0IGNoZWNrQ29udGV4dDsKICAgICAgICBmaW5hbCBDaGVja01vZGUgY2hlY2tNb2RlOwoKICAgICAgICBSZXN1bHRJbmZvKEtpbmRTZWxlY3RvciBwa2luZCwgVHlwZSBwdCkgewogICAgICAgICAgICB0aGlzKHBraW5kLCBwdCwgY2hrLmJhc2ljSGFuZGxlciwgQ2hlY2tNb2RlLk5PUk1BTCk7CiAgICAgICAgfQoKICAgICAgICBSZXN1bHRJbmZvKEtpbmRTZWxlY3RvciBwa2luZCwgVHlwZSBwdCwgQ2hlY2tNb2RlIGNoZWNrTW9kZSkgewogICAgICAgICAgICB0aGlzKHBraW5kLCBwdCwgY2hrLmJhc2ljSGFuZGxlciwgY2hlY2tNb2RlKTsKICAgICAgICB9CgogICAgICAgIHByb3RlY3RlZCBSZXN1bHRJbmZvKEtpbmRTZWxlY3RvciBwa2luZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUeXBlIHB0LCBDaGVja0NvbnRleHQgY2hlY2tDb250ZXh0KSB7CiAgICAgICAgICAgIHRoaXMocGtpbmQsIHB0LCBjaGVja0NvbnRleHQsIENoZWNrTW9kZS5OT1JNQUwpOwogICAgICAgIH0KCiAgICAgICAgcHJvdGVjdGVkIFJlc3VsdEluZm8oS2luZFNlbGVjdG9yIHBraW5kLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFR5cGUgcHQsIENoZWNrQ29udGV4dCBjaGVja0NvbnRleHQsIENoZWNrTW9kZSBjaGVja01vZGUpIHsKICAgICAgICAgICAgdGhpcy5wa2luZCA9IHBraW5kOwogICAgICAgICAgICB0aGlzLnB0ID0gcHQ7CiAgICAgICAgICAgIHRoaXMuY2hlY2tDb250ZXh0ID0gY2hlY2tDb250ZXh0OwogICAgICAgICAgICB0aGlzLmNoZWNrTW9kZSA9IGNoZWNrTW9kZTsKICAgICAgICB9CgogICAgICAgIHByb3RlY3RlZCB2b2lkIGF0dHIoSkNUcmVlIHRyZWUsIEVudjxBdHRyQ29udGV4dD4gZW52KSB7CiAgICAgICAgICAgIHRyZWUuYWNjZXB0KEF0dHIudGhpcyk7CiAgICAgICAgfQoKICAgICAgICBwcm90ZWN0ZWQgVHlwZSBjaGVjayhmaW5hbCBEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBmaW5hbCBUeXBlIGZvdW5kKSB7CiAgICAgICAgICAgIHJldHVybiBjaGsuY2hlY2tUeXBlKHBvcywgZm91bmQsIHB0LCBjaGVja0NvbnRleHQpOwogICAgICAgIH0KCiAgICAgICAgcHJvdGVjdGVkIFJlc3VsdEluZm8gZHVwKFR5cGUgbmV3UHQpIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyBSZXN1bHRJbmZvKHBraW5kLCBuZXdQdCwgY2hlY2tDb250ZXh0LCBjaGVja01vZGUpOwogICAgICAgIH0KCiAgICAgICAgcHJvdGVjdGVkIFJlc3VsdEluZm8gZHVwKENoZWNrQ29udGV4dCBuZXdDb250ZXh0KSB7CiAgICAgICAgICAgIHJldHVybiBuZXcgUmVzdWx0SW5mbyhwa2luZCwgcHQsIG5ld0NvbnRleHQsIGNoZWNrTW9kZSk7CiAgICAgICAgfQoKICAgICAgICBwcm90ZWN0ZWQgUmVzdWx0SW5mbyBkdXAoVHlwZSBuZXdQdCwgQ2hlY2tDb250ZXh0IG5ld0NvbnRleHQpIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyBSZXN1bHRJbmZvKHBraW5kLCBuZXdQdCwgbmV3Q29udGV4dCwgY2hlY2tNb2RlKTsKICAgICAgICB9CgogICAgICAgIHByb3RlY3RlZCBSZXN1bHRJbmZvIGR1cChUeXBlIG5ld1B0LCBDaGVja0NvbnRleHQgbmV3Q29udGV4dCwgQ2hlY2tNb2RlIG5ld01vZGUpIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyBSZXN1bHRJbmZvKHBraW5kLCBuZXdQdCwgbmV3Q29udGV4dCwgbmV3TW9kZSk7CiAgICAgICAgfQoKICAgICAgICBwcm90ZWN0ZWQgUmVzdWx0SW5mbyBkdXAoQ2hlY2tNb2RlIG5ld01vZGUpIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyBSZXN1bHRJbmZvKHBraW5kLCBwdCwgY2hlY2tDb250ZXh0LCBuZXdNb2RlKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CiAgICAgICAgICAgIGlmIChwdCAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gcHQudG9TdHJpbmcoKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHJldHVybiAiIjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBjbGFzcyBNZXRob2RBdHRySW5mbyBleHRlbmRzIFJlc3VsdEluZm8gewogICAgICAgIHB1YmxpYyBNZXRob2RBdHRySW5mbygpIHsKICAgICAgICAgICAgdGhpcyhjaGsuYmFzaWNIYW5kbGVyKTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBNZXRob2RBdHRySW5mbyhDaGVja0NvbnRleHQgY2hlY2tDb250ZXh0KSB7CiAgICAgICAgICAgIHN1cGVyKEtpbmRTZWxlY3Rvci5WQUwsIEluZmVyLmFueVBvbHksIGNoZWNrQ29udGV4dCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwcm90ZWN0ZWQgdm9pZCBhdHRyKEpDVHJlZSB0cmVlLCBFbnY8QXR0ckNvbnRleHQ+IGVudikgewogICAgICAgICAgICByZXN1bHQgPSBhcmd1bWVudEF0dHIuYXR0cmliQXJnKHRyZWUsIGVudik7CiAgICAgICAgfQoKICAgICAgICBwcm90ZWN0ZWQgUmVzdWx0SW5mbyBkdXAoVHlwZSBuZXdQdCkgewogICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCk7CiAgICAgICAgfQoKICAgICAgICBwcm90ZWN0ZWQgUmVzdWx0SW5mbyBkdXAoQ2hlY2tDb250ZXh0IG5ld0NvbnRleHQpIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyBNZXRob2RBdHRySW5mbyhuZXdDb250ZXh0KTsKICAgICAgICB9CgogICAgICAgIHByb3RlY3RlZCBSZXN1bHRJbmZvIGR1cChUeXBlIG5ld1B0LCBDaGVja0NvbnRleHQgbmV3Q29udGV4dCkgewogICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCk7CiAgICAgICAgfQoKICAgICAgICBwcm90ZWN0ZWQgUmVzdWx0SW5mbyBkdXAoVHlwZSBuZXdQdCwgQ2hlY2tDb250ZXh0IG5ld0NvbnRleHQsIENoZWNrTW9kZSBuZXdNb2RlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oKTsKICAgICAgICB9CgogICAgICAgIHByb3RlY3RlZCBSZXN1bHRJbmZvIGR1cChDaGVja01vZGUgbmV3TW9kZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgfQoKICAgIGNsYXNzIFJlY292ZXJ5SW5mbyBleHRlbmRzIFJlc3VsdEluZm8gewoKICAgICAgICBwdWJsaWMgUmVjb3ZlcnlJbmZvKGZpbmFsIERlZmVycmVkQXR0ci5EZWZlcnJlZEF0dHJDb250ZXh0IGRlZmVycmVkQXR0ckNvbnRleHQpIHsKICAgICAgICAgICAgc3VwZXIoS2luZFNlbGVjdG9yLlZBTCwgVHlwZS5yZWNvdmVyeVR5cGUsCiAgICAgICAgICAgICAgICAgIG5ldyBDaGVjay5OZXN0ZWRDaGVja0NvbnRleHQoY2hrLmJhc2ljSGFuZGxlcikgewogICAgICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgICAgICBwdWJsaWMgRGVmZXJyZWRBdHRyLkRlZmVycmVkQXR0ckNvbnRleHQgZGVmZXJyZWRBdHRyQ29udGV4dCgpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGVmZXJyZWRBdHRyQ29udGV4dDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICAgICAgcHVibGljIGJvb2xlYW4gY29tcGF0aWJsZShUeXBlIGZvdW5kLCBUeXBlIHJlcSwgV2FybmVyIHdhcm4pIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICAgICAgcHVibGljIHZvaWQgcmVwb3J0KERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIEpDRGlhZ25vc3RpYyBkZXRhaWxzKSB7CiAgICAgICAgICAgICAgICAgICAgY2hrLmJhc2ljSGFuZGxlci5yZXBvcnQocG9zLCBkZXRhaWxzKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgfQogICAgfQoKICAgIGZpbmFsIFJlc3VsdEluZm8gc3RhdEluZm87CiAgICBmaW5hbCBSZXN1bHRJbmZvIHZhckFzc2lnbm1lbnRJbmZvOwogICAgZmluYWwgUmVzdWx0SW5mbyBtZXRob2RBdHRySW5mbzsKICAgIGZpbmFsIFJlc3VsdEluZm8gdW5rbm93bkV4cHJJbmZvOwogICAgZmluYWwgUmVzdWx0SW5mbyB1bmtub3duVHlwZUluZm87CiAgICBmaW5hbCBSZXN1bHRJbmZvIHVua25vd25UeXBlRXhwckluZm87CiAgICBmaW5hbCBSZXN1bHRJbmZvIHJlY292ZXJ5SW5mbzsKCiAgICBUeXBlIHB0KCkgewogICAgICAgIHJldHVybiByZXN1bHRJbmZvLnB0OwogICAgfQoKICAgIEtpbmRTZWxlY3RvciBwa2luZCgpIHsKICAgICAgICByZXR1cm4gcmVzdWx0SW5mby5wa2luZDsKICAgIH0KCi8qICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBWaXNpdG9yIG1ldGhvZHMKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgogICAgLyoqIFZpc2l0b3IgYXJndW1lbnQ6IHRoZSBjdXJyZW50IGVudmlyb25tZW50LgogICAgICovCiAgICBFbnY8QXR0ckNvbnRleHQ+IGVudjsKCiAgICAvKiogVmlzaXRvciBhcmd1bWVudDogdGhlIGN1cnJlbnRseSBleHBlY3RlZCBhdHRyaWJ1dGlvbiByZXN1bHQuCiAgICAgKi8KICAgIFJlc3VsdEluZm8gcmVzdWx0SW5mbzsKCiAgICAvKiogVmlzaXRvciByZXN1bHQ6IHRoZSBjb21wdXRlZCB0eXBlLgogICAgICovCiAgICBUeXBlIHJlc3VsdDsKCiAgICAvKiogVmlzaXRvciBtZXRob2Q6IGF0dHJpYnV0ZSBhIHRyZWUsIGNhdGNoaW5nIGFueSBjb21wbGV0aW9uIGZhaWx1cmUKICAgICAqICBleGNlcHRpb25zLiBSZXR1cm4gdGhlIHRyZWUncyB0eXBlLgogICAgICoKICAgICAqICBAcGFyYW0gdHJlZSAgICBUaGUgdHJlZSB0byBiZSB2aXNpdGVkLgogICAgICogIEBwYXJhbSBlbnYgICAgIFRoZSBlbnZpcm9ubWVudCB2aXNpdG9yIGFyZ3VtZW50LgogICAgICogIEBwYXJhbSByZXN1bHRJbmZvICAgVGhlIHJlc3VsdCBpbmZvIHZpc2l0b3IgYXJndW1lbnQuCiAgICAgKi8KICAgIFR5cGUgYXR0cmliVHJlZShKQ1RyZWUgdHJlZSwgRW52PEF0dHJDb250ZXh0PiBlbnYsIFJlc3VsdEluZm8gcmVzdWx0SW5mbykgewogICAgICAgIEVudjxBdHRyQ29udGV4dD4gcHJldkVudiA9IHRoaXMuZW52OwogICAgICAgIFJlc3VsdEluZm8gcHJldlJlc3VsdCA9IHRoaXMucmVzdWx0SW5mbzsKICAgICAgICB0cnkgewogICAgICAgICAgICB0aGlzLmVudiA9IGVudjsKICAgICAgICAgICAgdGhpcy5yZXN1bHRJbmZvID0gcmVzdWx0SW5mbzsKICAgICAgICAgICAgcmVzdWx0SW5mby5hdHRyKHRyZWUsIGVudik7CiAgICAgICAgICAgIGlmICh0cmVlID09IGJyZWFrVHJlZSAmJgogICAgICAgICAgICAgICAgICAgIHJlc3VsdEluZm8uY2hlY2tDb250ZXh0LmRlZmVycmVkQXR0ckNvbnRleHQoKS5tb2RlID09IEF0dHJNb2RlLkNIRUNLKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQnJlYWtBdHRyKGNvcHlFbnYoZW52KSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9IGNhdGNoIChDb21wbGV0aW9uRmFpbHVyZSBleCkgewogICAgICAgICAgICB0cmVlLnR5cGUgPSBzeW1zLmVyclR5cGU7CiAgICAgICAgICAgIHJldHVybiBjaGsuY29tcGxldGlvbkVycm9yKHRyZWUucG9zKCksIGV4KTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICB0aGlzLmVudiA9IHByZXZFbnY7CiAgICAgICAgICAgIHRoaXMucmVzdWx0SW5mbyA9IHByZXZSZXN1bHQ7CiAgICAgICAgfQogICAgfQoKICAgIEVudjxBdHRyQ29udGV4dD4gY29weUVudihFbnY8QXR0ckNvbnRleHQ+IGVudikgewogICAgICAgIEVudjxBdHRyQ29udGV4dD4gbmV3RW52ID0KICAgICAgICAgICAgICAgIGVudi5kdXAoZW52LnRyZWUsIGVudi5pbmZvLmR1cChjb3B5U2NvcGUoZW52LmluZm8uc2NvcGUpKSk7CiAgICAgICAgaWYgKG5ld0Vudi5vdXRlciAhPSBudWxsKSB7CiAgICAgICAgICAgIG5ld0Vudi5vdXRlciA9IGNvcHlFbnYobmV3RW52Lm91dGVyKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG5ld0VudjsKICAgIH0KCiAgICBXcml0ZWFibGVTY29wZSBjb3B5U2NvcGUoV3JpdGVhYmxlU2NvcGUgc2MpIHsKICAgICAgICBXcml0ZWFibGVTY29wZSBuZXdTY29wZSA9IFdyaXRlYWJsZVNjb3BlLmNyZWF0ZShzYy5vd25lcik7CiAgICAgICAgTGlzdDxTeW1ib2w+IGVsZW1zTGlzdCA9IExpc3QubmlsKCk7CiAgICAgICAgZm9yIChTeW1ib2wgc3ltIDogc2MuZ2V0U3ltYm9scygpKSB7CiAgICAgICAgICAgIGVsZW1zTGlzdCA9IGVsZW1zTGlzdC5wcmVwZW5kKHN5bSk7CiAgICAgICAgfQogICAgICAgIGZvciAoU3ltYm9sIHMgOiBlbGVtc0xpc3QpIHsKICAgICAgICAgICAgbmV3U2NvcGUuZW50ZXIocyk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBuZXdTY29wZTsKICAgIH0KCiAgICAvKiogRGVyaXZlZCB2aXNpdG9yIG1ldGhvZDogYXR0cmlidXRlIGFuIGV4cHJlc3Npb24gdHJlZS4KICAgICAqLwogICAgcHVibGljIFR5cGUgYXR0cmliRXhwcihKQ1RyZWUgdHJlZSwgRW52PEF0dHJDb250ZXh0PiBlbnYsIFR5cGUgcHQpIHsKICAgICAgICByZXR1cm4gYXR0cmliVHJlZSh0cmVlLCBlbnYsIG5ldyBSZXN1bHRJbmZvKEtpbmRTZWxlY3Rvci5WQUwsICFwdC5oYXNUYWcoRVJST1IpID8gcHQgOiBUeXBlLm5vVHlwZSkpOwogICAgfQoKICAgIC8qKiBEZXJpdmVkIHZpc2l0b3IgbWV0aG9kOiBhdHRyaWJ1dGUgYW4gZXhwcmVzc2lvbiB0cmVlIHdpdGgKICAgICAqICBubyBjb25zdHJhaW50cyBvbiB0aGUgY29tcHV0ZWQgdHlwZS4KICAgICAqLwogICAgcHVibGljIFR5cGUgYXR0cmliRXhwcihKQ1RyZWUgdHJlZSwgRW52PEF0dHJDb250ZXh0PiBlbnYpIHsKICAgICAgICByZXR1cm4gYXR0cmliVHJlZSh0cmVlLCBlbnYsIHVua25vd25FeHBySW5mbyk7CiAgICB9CgogICAgLyoqIERlcml2ZWQgdmlzaXRvciBtZXRob2Q6IGF0dHJpYnV0ZSBhIHR5cGUgdHJlZS4KICAgICAqLwogICAgcHVibGljIFR5cGUgYXR0cmliVHlwZShKQ1RyZWUgdHJlZSwgRW52PEF0dHJDb250ZXh0PiBlbnYpIHsKICAgICAgICBUeXBlIHJlc3VsdCA9IGF0dHJpYlR5cGUodHJlZSwgZW52LCBUeXBlLm5vVHlwZSk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KCiAgICAvKiogRGVyaXZlZCB2aXNpdG9yIG1ldGhvZDogYXR0cmlidXRlIGEgdHlwZSB0cmVlLgogICAgICovCiAgICBUeXBlIGF0dHJpYlR5cGUoSkNUcmVlIHRyZWUsIEVudjxBdHRyQ29udGV4dD4gZW52LCBUeXBlIHB0KSB7CiAgICAgICAgVHlwZSByZXN1bHQgPSBhdHRyaWJUcmVlKHRyZWUsIGVudiwgbmV3IFJlc3VsdEluZm8oS2luZFNlbGVjdG9yLlRZUCwgcHQpKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgfQoKICAgIC8qKiBEZXJpdmVkIHZpc2l0b3IgbWV0aG9kOiBhdHRyaWJ1dGUgYSBzdGF0ZW1lbnQgb3IgZGVmaW5pdGlvbiB0cmVlLgogICAgICovCiAgICBwdWJsaWMgVHlwZSBhdHRyaWJTdGF0KEpDVHJlZSB0cmVlLCBFbnY8QXR0ckNvbnRleHQ+IGVudikgewogICAgICAgIEVudjxBdHRyQ29udGV4dD4gYW5hbHl6ZUVudiA9CiAgICAgICAgICAgICAgICBlbnYuZHVwKHRyZWUsIGVudi5pbmZvLmR1cChlbnYuaW5mby5zY29wZS5kdXBVbnNoYXJlZChlbnYuaW5mby5zY29wZS5vd25lcikpKTsKICAgICAgICB0cnkgewogICAgICAgICAgICByZXR1cm4gYXR0cmliVHJlZSh0cmVlLCBlbnYsIHN0YXRJbmZvKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICBhbmFseXplci5hbmFseXplSWZOZWVkZWQodHJlZSwgYW5hbHl6ZUVudik7CiAgICAgICAgfQogICAgfQoKICAgIC8qKiBBdHRyaWJ1dGUgYSBsaXN0IG9mIGV4cHJlc3Npb25zLCByZXR1cm5pbmcgYSBsaXN0IG9mIHR5cGVzLgogICAgICovCiAgICBMaXN0PFR5cGU+IGF0dHJpYkV4cHJzKExpc3Q8SkNFeHByZXNzaW9uPiB0cmVlcywgRW52PEF0dHJDb250ZXh0PiBlbnYsIFR5cGUgcHQpIHsKICAgICAgICBMaXN0QnVmZmVyPFR5cGU+IHRzID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgIGZvciAoTGlzdDxKQ0V4cHJlc3Npb24+IGwgPSB0cmVlczsgbC5ub25FbXB0eSgpOyBsID0gbC50YWlsKQogICAgICAgICAgICB0cy5hcHBlbmQoYXR0cmliRXhwcihsLmhlYWQsIGVudiwgcHQpKTsKICAgICAgICByZXR1cm4gdHMudG9MaXN0KCk7CiAgICB9CgogICAgLyoqIEF0dHJpYnV0ZSBhIGxpc3Qgb2Ygc3RhdGVtZW50cywgcmV0dXJuaW5nIG5vdGhpbmcuCiAgICAgKi8KICAgIDxUIGV4dGVuZHMgSkNUcmVlPiB2b2lkIGF0dHJpYlN0YXRzKExpc3Q8VD4gdHJlZXMsIEVudjxBdHRyQ29udGV4dD4gZW52KSB7CiAgICAgICAgZm9yIChMaXN0PFQ+IGwgPSB0cmVlczsgbC5ub25FbXB0eSgpOyBsID0gbC50YWlsKQogICAgICAgICAgICBhdHRyaWJTdGF0KGwuaGVhZCwgZW52KTsKICAgIH0KCiAgICAvKiogQXR0cmlidXRlIHRoZSBhcmd1bWVudHMgaW4gYSBtZXRob2QgY2FsbCwgcmV0dXJuaW5nIHRoZSBtZXRob2Qga2luZC4KICAgICAqLwogICAgS2luZFNlbGVjdG9yIGF0dHJpYkFyZ3MoS2luZFNlbGVjdG9yIGluaXRpYWxLaW5kLCBMaXN0PEpDRXhwcmVzc2lvbj4gdHJlZXMsIEVudjxBdHRyQ29udGV4dD4gZW52LCBMaXN0QnVmZmVyPFR5cGU+IGFyZ3R5cGVzKSB7CiAgICAgICAgS2luZFNlbGVjdG9yIGtpbmQgPSBpbml0aWFsS2luZDsKICAgICAgICBmb3IgKEpDRXhwcmVzc2lvbiBhcmcgOiB0cmVlcykgewogICAgICAgICAgICBUeXBlIGFyZ3R5cGUgPSBjaGsuY2hlY2tOb25Wb2lkKGFyZywgYXR0cmliVHJlZShhcmcsIGVudiwgYWxsb3dQb2x5ID8gbWV0aG9kQXR0ckluZm8gOiB1bmtub3duRXhwckluZm8pKTsKICAgICAgICAgICAgaWYgKGFyZ3R5cGUuaGFzVGFnKERFRkVSUkVEKSkgewogICAgICAgICAgICAgICAga2luZCA9IEtpbmRTZWxlY3Rvci5vZihLaW5kU2VsZWN0b3IuUE9MWSwga2luZCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYXJndHlwZXMuYXBwZW5kKGFyZ3R5cGUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4ga2luZDsKICAgIH0KCiAgICAvKiogQXR0cmlidXRlIGEgdHlwZSBhcmd1bWVudCBsaXN0LCByZXR1cm5pbmcgYSBsaXN0IG9mIHR5cGVzLgogICAgICogIENhbGxlciBpcyByZXNwb25zaWJsZSBmb3IgY2FsbGluZyBjaGVja1JlZlR5cGVzLgogICAgICovCiAgICBMaXN0PFR5cGU+IGF0dHJpYkFueVR5cGVzKExpc3Q8SkNFeHByZXNzaW9uPiB0cmVlcywgRW52PEF0dHJDb250ZXh0PiBlbnYpIHsKICAgICAgICBMaXN0QnVmZmVyPFR5cGU+IGFyZ3R5cGVzID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgIGZvciAoTGlzdDxKQ0V4cHJlc3Npb24+IGwgPSB0cmVlczsgbC5ub25FbXB0eSgpOyBsID0gbC50YWlsKQogICAgICAgICAgICBhcmd0eXBlcy5hcHBlbmQoYXR0cmliVHlwZShsLmhlYWQsIGVudikpOwogICAgICAgIHJldHVybiBhcmd0eXBlcy50b0xpc3QoKTsKICAgIH0KCiAgICAvKiogQXR0cmlidXRlIGEgdHlwZSBhcmd1bWVudCBsaXN0LCByZXR1cm5pbmcgYSBsaXN0IG9mIHR5cGVzLgogICAgICogIENoZWNrIHRoYXQgYWxsIHRoZSB0eXBlcyBhcmUgcmVmZXJlbmNlcy4KICAgICAqLwogICAgTGlzdDxUeXBlPiBhdHRyaWJUeXBlcyhMaXN0PEpDRXhwcmVzc2lvbj4gdHJlZXMsIEVudjxBdHRyQ29udGV4dD4gZW52KSB7CiAgICAgICAgTGlzdDxUeXBlPiB0eXBlcyA9IGF0dHJpYkFueVR5cGVzKHRyZWVzLCBlbnYpOwogICAgICAgIHJldHVybiBjaGsuY2hlY2tSZWZUeXBlcyh0cmVlcywgdHlwZXMpOwogICAgfQoKICAgIC8qKgogICAgICogQXR0cmlidXRlIHR5cGUgdmFyaWFibGVzIChvZiBnZW5lcmljIGNsYXNzZXMgb3IgbWV0aG9kcykuCiAgICAgKiBDb21wb3VuZCB0eXBlcyBhcmUgYXR0cmlidXRlZCBsYXRlciBpbiBhdHRyaWJCb3VuZHMuCiAgICAgKiBAcGFyYW0gdHlwYXJhbXMgdGhlIHR5cGUgdmFyaWFibGVzIHRvIGVudGVyCiAgICAgKiBAcGFyYW0gZW52ICAgICAgdGhlIGN1cnJlbnQgZW52aXJvbm1lbnQKICAgICAqLwogICAgdm9pZCBhdHRyaWJUeXBlVmFyaWFibGVzKExpc3Q8SkNUeXBlUGFyYW1ldGVyPiB0eXBhcmFtcywgRW52PEF0dHJDb250ZXh0PiBlbnYpIHsKICAgICAgICBmb3IgKEpDVHlwZVBhcmFtZXRlciB0dmFyIDogdHlwYXJhbXMpIHsKICAgICAgICAgICAgVHlwZVZhciBhID0gKFR5cGVWYXIpdHZhci50eXBlOwogICAgICAgICAgICBhLnRzeW0uZmxhZ3NfZmllbGQgfD0gVU5BVFRSSUJVVEVEOwogICAgICAgICAgICBhLmJvdW5kID0gVHlwZS5ub1R5cGU7CiAgICAgICAgICAgIGlmICghdHZhci5ib3VuZHMuaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IGJvdW5kcyA9IExpc3Qub2YoYXR0cmliVHlwZSh0dmFyLmJvdW5kcy5oZWFkLCBlbnYpKTsKICAgICAgICAgICAgICAgIGZvciAoSkNFeHByZXNzaW9uIGJvdW5kIDogdHZhci5ib3VuZHMudGFpbCkKICAgICAgICAgICAgICAgICAgICBib3VuZHMgPSBib3VuZHMucHJlcGVuZChhdHRyaWJUeXBlKGJvdW5kLCBlbnYpKTsKICAgICAgICAgICAgICAgIHR5cGVzLnNldEJvdW5kcyhhLCBib3VuZHMucmV2ZXJzZSgpKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIC8vIGlmIG5vIGJvdW5kcyBhcmUgZ2l2ZW4sIGFzc3VtZSBhIHNpbmdsZSBib3VuZCBvZgogICAgICAgICAgICAgICAgLy8gamF2YS5sYW5nLk9iamVjdC4KICAgICAgICAgICAgICAgIHR5cGVzLnNldEJvdW5kcyhhLCBMaXN0Lm9mKHN5bXMub2JqZWN0VHlwZSkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGEudHN5bS5mbGFnc19maWVsZCAmPSB+VU5BVFRSSUJVVEVEOwogICAgICAgIH0KICAgICAgICBmb3IgKEpDVHlwZVBhcmFtZXRlciB0dmFyIDogdHlwYXJhbXMpIHsKICAgICAgICAgICAgY2hrLmNoZWNrTm9uQ3ljbGljKHR2YXIucG9zKCksIChUeXBlVmFyKXR2YXIudHlwZSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQXR0cmlidXRlIHRoZSB0eXBlIHJlZmVyZW5jZXMgaW4gYSBsaXN0IG9mIGFubm90YXRpb25zLgogICAgICovCiAgICB2b2lkIGF0dHJpYkFubm90YXRpb25UeXBlcyhMaXN0PEpDQW5ub3RhdGlvbj4gYW5ub3RhdGlvbnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFbnY8QXR0ckNvbnRleHQ+IGVudikgewogICAgICAgIGZvciAoTGlzdDxKQ0Fubm90YXRpb24+IGFsID0gYW5ub3RhdGlvbnM7IGFsLm5vbkVtcHR5KCk7IGFsID0gYWwudGFpbCkgewogICAgICAgICAgICBKQ0Fubm90YXRpb24gYSA9IGFsLmhlYWQ7CiAgICAgICAgICAgIGF0dHJpYlR5cGUoYS5hbm5vdGF0aW9uVHlwZSwgZW52KTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBBdHRyaWJ1dGUgYSAibGF6eSBjb25zdGFudCB2YWx1ZSIuCiAgICAgKiAgQHBhcmFtIGVudiAgICAgICAgIFRoZSBlbnYgZm9yIHRoZSBjb25zdCB2YWx1ZQogICAgICogIEBwYXJhbSB2YXJpYWJsZSAgICBUaGUgaW5pdGlhbGl6ZXIgZm9yIHRoZSBjb25zdCB2YWx1ZQogICAgICogIEBwYXJhbSB0eXBlICAgICAgICBUaGUgZXhwZWN0ZWQgdHlwZSwgb3IgbnVsbAogICAgICogIEBzZWUgVmFyU3ltYm9sI3NldExhenlDb25zdFZhbHVlCiAgICAgKi8KICAgIHB1YmxpYyBPYmplY3QgYXR0cmliTGF6eUNvbnN0YW50VmFsdWUoRW52PEF0dHJDb250ZXh0PiBlbnYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSkNWYXJpYWJsZURlY2wgdmFyaWFibGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVHlwZSB0eXBlKSB7CgogICAgICAgIERpYWdub3N0aWNQb3NpdGlvbiBwcmV2TGludFBvcwogICAgICAgICAgICAgICAgPSBkZWZlcnJlZExpbnRIYW5kbGVyLnNldFBvcyh2YXJpYWJsZS5wb3MoKSk7CgogICAgICAgIGZpbmFsIEphdmFGaWxlT2JqZWN0IHByZXZTb3VyY2UgPSBsb2cudXNlU291cmNlKGVudi50b3BsZXZlbC5zb3VyY2VmaWxlKTsKICAgICAgICB0cnkgewogICAgICAgICAgICBUeXBlIGl0eXBlID0gYXR0cmliRXhwcih2YXJpYWJsZS5pbml0LCBlbnYsIHR5cGUpOwogICAgICAgICAgICBpZiAoaXR5cGUuY29uc3RWYWx1ZSgpICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIHJldHVybiBjb2VyY2UoaXR5cGUsIHR5cGUpLmNvbnN0VmFsdWUoKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICB9CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgbG9nLnVzZVNvdXJjZShwcmV2U291cmNlKTsKICAgICAgICAgICAgZGVmZXJyZWRMaW50SGFuZGxlci5zZXRQb3MocHJldkxpbnRQb3MpOwogICAgICAgIH0KICAgIH0KCiAgICAvKiogQXR0cmlidXRlIHR5cGUgcmVmZXJlbmNlIGluIGFuIGBleHRlbmRzJyBvciBgaW1wbGVtZW50cycgY2xhdXNlLgogICAgICogIFN1cGVydHlwZXMgb2YgYW5vbnltb3VzIGlubmVyIGNsYXNzZXMgYXJlIHVzdWFsbHkgYWxyZWFkeSBhdHRyaWJ1dGVkLgogICAgICoKICAgICAqICBAcGFyYW0gdHJlZSAgICAgICAgICAgICAgVGhlIHRyZWUgbWFraW5nIHVwIHRoZSB0eXBlIHJlZmVyZW5jZS4KICAgICAqICBAcGFyYW0gZW52ICAgICAgICAgICAgICAgVGhlIGVudmlyb25tZW50IGN1cnJlbnQgYXQgdGhlIHJlZmVyZW5jZS4KICAgICAqICBAcGFyYW0gY2xhc3NFeHBlY3RlZCAgICAgdHJ1ZSBpZiBvbmx5IGEgY2xhc3MgaXMgZXhwZWN0ZWQgaGVyZS4KICAgICAqICBAcGFyYW0gaW50ZXJmYWNlRXhwZWN0ZWQgdHJ1ZSBpZiBvbmx5IGFuIGludGVyZmFjZSBpcyBleHBlY3RlZCBoZXJlLgogICAgICovCiAgICBUeXBlIGF0dHJpYkJhc2UoSkNUcmVlIHRyZWUsCiAgICAgICAgICAgICAgICAgICAgRW52PEF0dHJDb250ZXh0PiBlbnYsCiAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBjbGFzc0V4cGVjdGVkLAogICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gaW50ZXJmYWNlRXhwZWN0ZWQsCiAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBjaGVja0V4dGVuc2libGUpIHsKICAgICAgICBUeXBlIHQgPSB0cmVlLnR5cGUgIT0gbnVsbCA/CiAgICAgICAgICAgIHRyZWUudHlwZSA6CiAgICAgICAgICAgIGF0dHJpYlR5cGUodHJlZSwgZW52KTsKICAgICAgICByZXR1cm4gY2hlY2tCYXNlKHQsIHRyZWUsIGVudiwgY2xhc3NFeHBlY3RlZCwgaW50ZXJmYWNlRXhwZWN0ZWQsIGNoZWNrRXh0ZW5zaWJsZSk7CiAgICB9CiAgICBUeXBlIGNoZWNrQmFzZShUeXBlIHQsCiAgICAgICAgICAgICAgICAgICBKQ1RyZWUgdHJlZSwKICAgICAgICAgICAgICAgICAgIEVudjxBdHRyQ29udGV4dD4gZW52LAogICAgICAgICAgICAgICAgICAgYm9vbGVhbiBjbGFzc0V4cGVjdGVkLAogICAgICAgICAgICAgICAgICAgYm9vbGVhbiBpbnRlcmZhY2VFeHBlY3RlZCwKICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gY2hlY2tFeHRlbnNpYmxlKSB7CiAgICAgICAgZmluYWwgRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcyA9IHRyZWUuaGFzVGFnKFRZUEVBUFBMWSkgPwogICAgICAgICAgICAgICAgKCgoSkNUeXBlQXBwbHkpIHRyZWUpLmNsYXp6KS5wb3MoKSA6IHRyZWUucG9zKCk7CiAgICAgICAgaWYgKHQudHN5bS5pc0Fub255bW91cygpKSB7CiAgICAgICAgICAgIGxvZy5lcnJvcihwb3MsICJjYW50LmluaGVyaXQuZnJvbS5hbm9uIik7CiAgICAgICAgICAgIHJldHVybiB0eXBlcy5jcmVhdGVFcnJvclR5cGUodCk7CiAgICAgICAgfQogICAgICAgIGlmICh0LmlzRXJyb25lb3VzKCkpCiAgICAgICAgICAgIHJldHVybiB0OwogICAgICAgIGlmICh0Lmhhc1RhZyhUWVBFVkFSKSAmJiAhY2xhc3NFeHBlY3RlZCAmJiAhaW50ZXJmYWNlRXhwZWN0ZWQpIHsKICAgICAgICAgICAgLy8gY2hlY2sgdGhhdCB0eXBlIHZhcmlhYmxlIGlzIGFscmVhZHkgdmlzaWJsZQogICAgICAgICAgICBpZiAodC5nZXRVcHBlckJvdW5kKCkgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgbG9nLmVycm9yKHBvcywgImlsbGVnYWwuZm9yd2FyZC5yZWYiKTsKICAgICAgICAgICAgICAgIHJldHVybiB0eXBlcy5jcmVhdGVFcnJvclR5cGUodCk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB0ID0gY2hrLmNoZWNrQ2xhc3NUeXBlKHBvcywgdCwgY2hlY2tFeHRlbnNpYmxlKTsKICAgICAgICB9CiAgICAgICAgaWYgKGludGVyZmFjZUV4cGVjdGVkICYmICh0LnRzeW0uZmxhZ3MoKSAmIElOVEVSRkFDRSkgPT0gMCkgewogICAgICAgICAgICBsb2cuZXJyb3IocG9zLCAiaW50Zi5leHBlY3RlZC5oZXJlIik7CiAgICAgICAgICAgIC8vIHJldHVybiBlcnJUeXBlIGlzIG5lY2Vzc2FyeSBzaW5jZSBvdGhlcndpc2UgdGhlcmUgbWlnaHQKICAgICAgICAgICAgLy8gYmUgdW5kZXRlY3RlZCBjeWNsZXMgd2hpY2ggY2F1c2UgYXR0cmlidXRpb24gdG8gbG9vcAogICAgICAgICAgICByZXR1cm4gdHlwZXMuY3JlYXRlRXJyb3JUeXBlKHQpOwogICAgICAgIH0gZWxzZSBpZiAoY2hlY2tFeHRlbnNpYmxlICYmCiAgICAgICAgICAgICAgICAgICBjbGFzc0V4cGVjdGVkICYmCiAgICAgICAgICAgICAgICAgICAodC50c3ltLmZsYWdzKCkgJiBJTlRFUkZBQ0UpICE9IDApIHsKICAgICAgICAgICAgbG9nLmVycm9yKHBvcywgIm5vLmludGYuZXhwZWN0ZWQuaGVyZSIpOwogICAgICAgICAgICByZXR1cm4gdHlwZXMuY3JlYXRlRXJyb3JUeXBlKHQpOwogICAgICAgIH0KICAgICAgICBpZiAoY2hlY2tFeHRlbnNpYmxlICYmCiAgICAgICAgICAgICgodC50c3ltLmZsYWdzKCkgJiBGSU5BTCkgIT0gMCkpIHsKICAgICAgICAgICAgbG9nLmVycm9yKHBvcywKICAgICAgICAgICAgICAgICAgICAgICJjYW50LmluaGVyaXQuZnJvbS5maW5hbCIsIHQudHN5bSk7CiAgICAgICAgfQogICAgICAgIGNoay5jaGVja05vbkN5Y2xpYyhwb3MsIHQpOwogICAgICAgIHJldHVybiB0OwogICAgfQoKICAgIFR5cGUgYXR0cmliSWRlbnRBc0VudW1UeXBlKEVudjxBdHRyQ29udGV4dD4gZW52LCBKQ0lkZW50IGlkKSB7CiAgICAgICAgQXNzZXJ0LmNoZWNrKChlbnYuZW5jbENsYXNzLnN5bS5mbGFncygpICYgRU5VTSkgIT0gMCk7CiAgICAgICAgaWQudHlwZSA9IGVudi5pbmZvLnNjb3BlLm93bmVyLmVuY2xDbGFzcygpLnR5cGU7CiAgICAgICAgaWQuc3ltID0gZW52LmluZm8uc2NvcGUub3duZXIuZW5jbENsYXNzKCk7CiAgICAgICAgcmV0dXJuIGlkLnR5cGU7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRDbGFzc0RlZihKQ0NsYXNzRGVjbCB0cmVlKSB7CiAgICAgICAgT3B0aW9uYWw8QXJndW1lbnRBdHRyLkxvY2FsQ2FjaGVDb250ZXh0PiBsb2NhbENhY2hlQ29udGV4dCA9CiAgICAgICAgICAgICAgICBPcHRpb25hbC5vZk51bGxhYmxlKGVudi5pbmZvLmlzU3BlY3VsYXRpdmUgPwogICAgICAgICAgICAgICAgICAgICAgICBhcmd1bWVudEF0dHIud2l0aExvY2FsQ2FjaGVDb250ZXh0KCkgOiBudWxsKTsKICAgICAgICB0cnkgewogICAgICAgICAgICAvLyBMb2NhbCBhbmQgYW5vbnltb3VzIGNsYXNzZXMgaGF2ZSBub3QgYmVlbiBlbnRlcmVkIHlldCwgc28gd2UgbmVlZCB0bwogICAgICAgICAgICAvLyBkbyBpdCBub3cuCiAgICAgICAgICAgIGlmIChlbnYuaW5mby5zY29wZS5vd25lci5raW5kLm1hdGNoZXMoS2luZFNlbGVjdG9yLlZBTF9NVEgpKSB7CiAgICAgICAgICAgICAgICBlbnRlci5jbGFzc0VudGVyKHRyZWUsIGVudik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvLyBJZiB0aGlzIGNsYXNzIGRlY2xhcmF0aW9uIGlzIHBhcnQgb2YgYSBjbGFzcyBsZXZlbCBhbm5vdGF0aW9uLAogICAgICAgICAgICAgICAgLy8gYXMgaW4gQE15QW5ubyhuZXcgT2JqZWN0KCkge30pIGNsYXNzIE15Q2xhc3Mge30sIGVudGVyIGl0IGluCiAgICAgICAgICAgICAgICAvLyBvcmRlciB0byBzaW1wbGlmeSBsYXRlciBzdGVwcyBhbmQgYWxsb3cgZm9yIHNlbnNpYmxlIGVycm9yCiAgICAgICAgICAgICAgICAvLyBtZXNzYWdlcy4KICAgICAgICAgICAgICAgIGlmIChlbnYudHJlZS5oYXNUYWcoTkVXQ0xBU1MpICYmIFRyZWVJbmZvLmlzSW5Bbm5vdGF0aW9uKGVudiwgdHJlZSkpCiAgICAgICAgICAgICAgICAgICAgZW50ZXIuY2xhc3NFbnRlcih0cmVlLCBlbnYpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBDbGFzc1N5bWJvbCBjID0gdHJlZS5zeW07CiAgICAgICAgICAgIGlmIChjID09IG51bGwpIHsKICAgICAgICAgICAgICAgIC8vIGV4aXQgaW4gY2FzZSBzb21ldGhpbmcgZHJhc3RpYyB3ZW50IHdyb25nIGR1cmluZyBlbnRlci4KICAgICAgICAgICAgICAgIHJlc3VsdCA9IG51bGw7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvLyBtYWtlIHN1cmUgY2xhc3MgaGFzIGJlZW4gY29tcGxldGVkOgogICAgICAgICAgICAgICAgYy5jb21wbGV0ZSgpOwoKICAgICAgICAgICAgICAgIC8vIElmIHRoaXMgY2xhc3MgYXBwZWFycyBhcyBhbiBhbm9ueW1vdXMgY2xhc3MKICAgICAgICAgICAgICAgIC8vIGluIGEgc3VwZXJjbGFzcyBjb25zdHJ1Y3RvciBjYWxsCiAgICAgICAgICAgICAgICAvLyBkaXNhYmxlIGltcGxpY2l0IG91dGVyIGluc3RhbmNlIGZyb20gYmVpbmcgcGFzc2VkLgogICAgICAgICAgICAgICAgLy8gKFRoaXMgd291bGQgYmUgYW4gaWxsZWdhbCBhY2Nlc3MgdG8gInRoaXMgYmVmb3JlIHN1cGVyIikuCiAgICAgICAgICAgICAgICBpZiAoZW52LmluZm8uaXNTZWxmQ2FsbCAmJgogICAgICAgICAgICAgICAgICAgICAgICBlbnYudHJlZS5oYXNUYWcoTkVXQ0xBU1MpKSB7CiAgICAgICAgICAgICAgICAgICAgYy5mbGFnc19maWVsZCB8PSBOT09VVEVSVEhJUzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGF0dHJpYkNsYXNzKHRyZWUucG9zKCksIGMpOwogICAgICAgICAgICAgICAgcmVzdWx0ID0gdHJlZS50eXBlID0gYy50eXBlOwogICAgICAgICAgICB9CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgbG9jYWxDYWNoZUNvbnRleHQuaWZQcmVzZW50KExvY2FsQ2FjaGVDb250ZXh0OjpsZWF2ZSk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0TWV0aG9kRGVmKEpDTWV0aG9kRGVjbCB0cmVlKSB7CiAgICAgICAgTWV0aG9kU3ltYm9sIG0gPSB0cmVlLnN5bTsKICAgICAgICBib29sZWFuIGlzRGVmYXVsdE1ldGhvZCA9IChtLmZsYWdzKCkgJiBERUZBVUxUKSAhPSAwOwoKICAgICAgICBMaW50IGxpbnQgPSBlbnYuaW5mby5saW50LmF1Z21lbnQobSk7CiAgICAgICAgTGludCBwcmV2TGludCA9IGNoay5zZXRMaW50KGxpbnQpOwogICAgICAgIE1ldGhvZFN5bWJvbCBwcmV2TWV0aG9kID0gY2hrLnNldE1ldGhvZChtKTsKICAgICAgICB0cnkgewogICAgICAgICAgICBkZWZlcnJlZExpbnRIYW5kbGVyLmZsdXNoKHRyZWUucG9zKCkpOwogICAgICAgICAgICBjaGsuY2hlY2tEZXByZWNhdGVkQW5ub3RhdGlvbih0cmVlLnBvcygpLCBtKTsKCgogICAgICAgICAgICAvLyBDcmVhdGUgYSBuZXcgZW52aXJvbm1lbnQgd2l0aCBsb2NhbCBzY29wZQogICAgICAgICAgICAvLyBmb3IgYXR0cmlidXRpbmcgdGhlIG1ldGhvZC4KICAgICAgICAgICAgRW52PEF0dHJDb250ZXh0PiBsb2NhbEVudiA9IG1lbWJlckVudGVyLm1ldGhvZEVudih0cmVlLCBlbnYpOwogICAgICAgICAgICBsb2NhbEVudi5pbmZvLmxpbnQgPSBsaW50OwoKICAgICAgICAgICAgYXR0cmliU3RhdHModHJlZS50eXBhcmFtcywgbG9jYWxFbnYpOwoKICAgICAgICAgICAgLy8gSWYgd2Ugb3ZlcnJpZGUgYW55IG90aGVyIG1ldGhvZHMsIGNoZWNrIHRoYXQgd2UgZG8gc28gcHJvcGVybHkuCiAgICAgICAgICAgIC8vIEpMUyA/Pz8KICAgICAgICAgICAgaWYgKG0uaXNTdGF0aWMoKSkgewogICAgICAgICAgICAgICAgY2hrLmNoZWNrSGlkZUNsYXNoZXModHJlZS5wb3MoKSwgZW52LmVuY2xDbGFzcy50eXBlLCBtKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGNoay5jaGVja092ZXJyaWRlQ2xhc2hlcyh0cmVlLnBvcygpLCBlbnYuZW5jbENsYXNzLnR5cGUsIG0pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGNoay5jaGVja092ZXJyaWRlKGVudiwgdHJlZSwgbSk7CgogICAgICAgICAgICBpZiAoaXNEZWZhdWx0TWV0aG9kICYmIHR5cGVzLm92ZXJyaWRlc09iamVjdE1ldGhvZChtLmVuY2xDbGFzcygpLCBtKSkgewogICAgICAgICAgICAgICAgbG9nLmVycm9yKHRyZWUsICJkZWZhdWx0Lm92ZXJyaWRlcy5vYmplY3QubWVtYmVyIiwgbS5uYW1lLCBLaW5kcy5raW5kTmFtZShtLmxvY2F0aW9uKCkpLCBtLmxvY2F0aW9uKCkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBFbnRlciBhbGwgdHlwZSBwYXJhbWV0ZXJzIGludG8gdGhlIGxvY2FsIG1ldGhvZCBzY29wZS4KICAgICAgICAgICAgZm9yIChMaXN0PEpDVHlwZVBhcmFtZXRlcj4gbCA9IHRyZWUudHlwYXJhbXM7IGwubm9uRW1wdHkoKTsgbCA9IGwudGFpbCkKICAgICAgICAgICAgICAgIGxvY2FsRW52LmluZm8uc2NvcGUuZW50ZXJJZkFic2VudChsLmhlYWQudHlwZS50c3ltKTsKCiAgICAgICAgICAgIENsYXNzU3ltYm9sIG93bmVyID0gZW52LmVuY2xDbGFzcy5zeW07CiAgICAgICAgICAgIGlmICgob3duZXIuZmxhZ3MoKSAmIEFOTk9UQVRJT04pICE9IDAgJiYKICAgICAgICAgICAgICAgICAgICB0cmVlLnBhcmFtcy5ub25FbXB0eSgpKQogICAgICAgICAgICAgICAgbG9nLmVycm9yKHRyZWUucGFyYW1zLmhlYWQucG9zKCksCiAgICAgICAgICAgICAgICAgICAgICAgICJpbnRmLmFubm90YXRpb24ubWVtYmVycy5jYW50LmhhdmUucGFyYW1zIik7CgogICAgICAgICAgICAvLyBBdHRyaWJ1dGUgYWxsIHZhbHVlIHBhcmFtZXRlcnMuCiAgICAgICAgICAgIGZvciAoTGlzdDxKQ1ZhcmlhYmxlRGVjbD4gbCA9IHRyZWUucGFyYW1zOyBsLm5vbkVtcHR5KCk7IGwgPSBsLnRhaWwpIHsKICAgICAgICAgICAgICAgIGF0dHJpYlN0YXQobC5oZWFkLCBsb2NhbEVudik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGNoay5jaGVja1ZhcmFyZ3NNZXRob2REZWNsKGxvY2FsRW52LCB0cmVlKTsKCiAgICAgICAgICAgIC8vIENoZWNrIHRoYXQgdHlwZSBwYXJhbWV0ZXJzIGFyZSB3ZWxsLWZvcm1lZC4KICAgICAgICAgICAgY2hrLnZhbGlkYXRlKHRyZWUudHlwYXJhbXMsIGxvY2FsRW52KTsKCiAgICAgICAgICAgIC8vIENoZWNrIHRoYXQgcmVzdWx0IHR5cGUgaXMgd2VsbC1mb3JtZWQuCiAgICAgICAgICAgIGlmICh0cmVlLnJlc3R5cGUgIT0gbnVsbCAmJiAhdHJlZS5yZXN0eXBlLnR5cGUuaGFzVGFnKFZPSUQpKQogICAgICAgICAgICAgICAgY2hrLnZhbGlkYXRlKHRyZWUucmVzdHlwZSwgbG9jYWxFbnYpOwoKICAgICAgICAgICAgLy8gQ2hlY2sgdGhhdCByZWNlaXZlciB0eXBlIGlzIHdlbGwtZm9ybWVkLgogICAgICAgICAgICBpZiAodHJlZS5yZWN2cGFyYW0gIT0gbnVsbCkgewogICAgICAgICAgICAgICAgLy8gVXNlIGEgbmV3IGVudmlyb25tZW50IHRvIGNoZWNrIHRoZSByZWNlaXZlciBwYXJhbWV0ZXIuCiAgICAgICAgICAgICAgICAvLyBPdGhlcndpc2UgSSBnZXQgIm1pZ2h0IG5vdCBoYXZlIGJlZW4gaW5pdGlhbGl6ZWQiIGVycm9ycy4KICAgICAgICAgICAgICAgIC8vIElzIHRoZXJlIGEgYmV0dGVyIHdheT8KICAgICAgICAgICAgICAgIEVudjxBdHRyQ29udGV4dD4gbmV3RW52ID0gbWVtYmVyRW50ZXIubWV0aG9kRW52KHRyZWUsIGVudik7CiAgICAgICAgICAgICAgICBhdHRyaWJUeXBlKHRyZWUucmVjdnBhcmFtLCBuZXdFbnYpOwogICAgICAgICAgICAgICAgY2hrLnZhbGlkYXRlKHRyZWUucmVjdnBhcmFtLCBuZXdFbnYpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBhbm5vdGF0aW9uIG1ldGhvZCBjaGVja3MKICAgICAgICAgICAgaWYgKChvd25lci5mbGFncygpICYgQU5OT1RBVElPTikgIT0gMCkgewogICAgICAgICAgICAgICAgLy8gYW5ub3RhdGlvbiBtZXRob2QgY2Fubm90IGhhdmUgdGhyb3dzIGNsYXVzZQogICAgICAgICAgICAgICAgaWYgKHRyZWUudGhyb3duLm5vbkVtcHR5KCkpIHsKICAgICAgICAgICAgICAgICAgICBsb2cuZXJyb3IodHJlZS50aHJvd24uaGVhZC5wb3MoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0aHJvd3Mubm90LmFsbG93ZWQuaW4uaW50Zi5hbm5vdGF0aW9uIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvLyBhbm5vdGF0aW9uIG1ldGhvZCBjYW5ub3QgZGVjbGFyZSB0eXBlLXBhcmFtZXRlcnMKICAgICAgICAgICAgICAgIGlmICh0cmVlLnR5cGFyYW1zLm5vbkVtcHR5KCkpIHsKICAgICAgICAgICAgICAgICAgICBsb2cuZXJyb3IodHJlZS50eXBhcmFtcy5oZWFkLnBvcygpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgImludGYuYW5ub3RhdGlvbi5tZW1iZXJzLmNhbnQuaGF2ZS50eXBlLnBhcmFtcyIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgLy8gdmFsaWRhdGUgYW5ub3RhdGlvbiBtZXRob2QncyByZXR1cm4gdHlwZSAoY291bGQgYmUgYW4gYW5ub3RhdGlvbiB0eXBlKQogICAgICAgICAgICAgICAgY2hrLnZhbGlkYXRlQW5ub3RhdGlvblR5cGUodHJlZS5yZXN0eXBlKTsKICAgICAgICAgICAgICAgIC8vIGVuc3VyZSB0aGF0IGFubm90YXRpb24gbWV0aG9kIGRvZXMgbm90IGNsYXNoIHdpdGggbWVtYmVycyBvZiBPYmplY3QvQW5ub3RhdGlvbgogICAgICAgICAgICAgICAgY2hrLnZhbGlkYXRlQW5ub3RhdGlvbk1ldGhvZCh0cmVlLnBvcygpLCBtKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZm9yIChMaXN0PEpDRXhwcmVzc2lvbj4gbCA9IHRyZWUudGhyb3duOyBsLm5vbkVtcHR5KCk7IGwgPSBsLnRhaWwpCiAgICAgICAgICAgICAgICBjaGsuY2hlY2tUeXBlKGwuaGVhZC5wb3MoKSwgbC5oZWFkLnR5cGUsIHN5bXMudGhyb3dhYmxlVHlwZSk7CgogICAgICAgICAgICBpZiAodHJlZS5ib2R5ID09IG51bGwpIHsKICAgICAgICAgICAgICAgIC8vIEVtcHR5IGJvZGllcyBhcmUgb25seSBhbGxvd2VkIGZvcgogICAgICAgICAgICAgICAgLy8gYWJzdHJhY3QsIG5hdGl2ZSwgb3IgaW50ZXJmYWNlIG1ldGhvZHMsIG9yIGZvciBtZXRob2RzCiAgICAgICAgICAgICAgICAvLyBpbiBhIHJldHJvZml0IHNpZ25hdHVyZSBjbGFzcy4KICAgICAgICAgICAgICAgIGlmICh0cmVlLmRlZmF1bHRWYWx1ZSAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKChvd25lci5mbGFncygpICYgQU5OT1RBVElPTikgPT0gMCkKICAgICAgICAgICAgICAgICAgICAgICAgbG9nLmVycm9yKHRyZWUucG9zKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZGVmYXVsdC5hbGxvd2VkLmluLmludGYuYW5ub3RhdGlvbi5tZW1iZXIiKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChpc0RlZmF1bHRNZXRob2QgfHwgKHRyZWUuc3ltLmZsYWdzKCkgJiAoQUJTVFJBQ1QgfCBOQVRJVkUpKSA9PSAwKQogICAgICAgICAgICAgICAgICAgIGxvZy5lcnJvcih0cmVlLnBvcygpLCAibWlzc2luZy5tZXRoLmJvZHkub3IuZGVjbC5hYnN0cmFjdCIpOwogICAgICAgICAgICB9IGVsc2UgaWYgKCh0cmVlLnN5bS5mbGFncygpICYgKEFCU1RSQUNUfERFRkFVTFR8UFJJVkFURSkpID09IEFCU1RSQUNUKSB7CiAgICAgICAgICAgICAgICBpZiAoKG93bmVyLmZsYWdzKCkgJiBJTlRFUkZBQ0UpICE9IDApIHsKICAgICAgICAgICAgICAgICAgICBsb2cuZXJyb3IodHJlZS5ib2R5LnBvcygpLCAiaW50Zi5tZXRoLmNhbnQuaGF2ZS5ib2R5Iik7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGxvZy5lcnJvcih0cmVlLnBvcygpLCAiYWJzdHJhY3QubWV0aC5jYW50LmhhdmUuYm9keSIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgaWYgKCh0cmVlLm1vZHMuZmxhZ3MgJiBOQVRJVkUpICE9IDApIHsKICAgICAgICAgICAgICAgIGxvZy5lcnJvcih0cmVlLnBvcygpLCAibmF0aXZlLm1ldGguY2FudC5oYXZlLmJvZHkiKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIC8vIEFkZCBhbiBpbXBsaWNpdCBzdXBlcigpIGNhbGwgdW5sZXNzIGFuIGV4cGxpY2l0IGNhbGwgdG8KICAgICAgICAgICAgICAgIC8vIHN1cGVyKC4uLikgb3IgdGhpcyguLi4pIGlzIGdpdmVuCiAgICAgICAgICAgICAgICAvLyBvciB3ZSBhcmUgY29tcGlsaW5nIGNsYXNzIGphdmEubGFuZy5PYmplY3QuCiAgICAgICAgICAgICAgICBpZiAodHJlZS5uYW1lID09IG5hbWVzLmluaXQgJiYgb3duZXIudHlwZSAhPSBzeW1zLm9iamVjdFR5cGUpIHsKICAgICAgICAgICAgICAgICAgICBKQ0Jsb2NrIGJvZHkgPSB0cmVlLmJvZHk7CiAgICAgICAgICAgICAgICAgICAgaWYgKGJvZHkuc3RhdHMuaXNFbXB0eSgpIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAhVHJlZUluZm8uaXNTZWxmQ2FsbChib2R5LnN0YXRzLmhlYWQpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGJvZHkuc3RhdHMgPSBib2R5LnN0YXRzLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZXBlbmQodHlwZUVudGVyLlN1cGVyQ2FsbChtYWtlLmF0KGJvZHkucG9zKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExpc3QubmlsKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0Lm5pbCgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFsc2UpKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKChlbnYuZW5jbENsYXNzLnN5bS5mbGFncygpICYgRU5VTSkgIT0gMCAmJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgKHRyZWUubW9kcy5mbGFncyAmIEdFTkVSQVRFRENPTlNUUikgPT0gMCAmJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgVHJlZUluZm8uaXNTdXBlckNhbGwoYm9keS5zdGF0cy5oZWFkKSkgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBlbnVtIGNvbnN0cnVjdG9ycyBhcmUgbm90IGFsbG93ZWQgdG8gY2FsbCBzdXBlcgogICAgICAgICAgICAgICAgICAgICAgICAvLyBkaXJlY3RseSwgc28gbWFrZSBzdXJlIHRoZXJlIGFyZW4ndCBhbnkgc3VwZXIgY2FsbHMKICAgICAgICAgICAgICAgICAgICAgICAgLy8gaW4gZW51bSBjb25zdHJ1Y3RvcnMsIGV4Y2VwdCBpbiB0aGUgY29tcGlsZXIKICAgICAgICAgICAgICAgICAgICAgICAgLy8gZ2VuZXJhdGVkIG9uZS4KICAgICAgICAgICAgICAgICAgICAgICAgbG9nLmVycm9yKHRyZWUuYm9keS5zdGF0cy5oZWFkLnBvcygpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJjYWxsLnRvLnN1cGVyLm5vdC5hbGxvd2VkLmluLmVudW0uY3RvciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW52LmVuY2xDbGFzcy5zeW0pOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBBdHRyaWJ1dGUgYWxsIHR5cGUgYW5ub3RhdGlvbnMgaW4gdGhlIGJvZHkKICAgICAgICAgICAgICAgIGFubm90YXRlLnF1ZXVlU2NhblRyZWVBbmRUeXBlQW5ub3RhdGUodHJlZS5ib2R5LCBsb2NhbEVudiwgbSwgbnVsbCk7CiAgICAgICAgICAgICAgICBhbm5vdGF0ZS5mbHVzaCgpOwoKICAgICAgICAgICAgICAgIC8vIEF0dHJpYnV0ZSBtZXRob2QgYm9keS4KICAgICAgICAgICAgICAgIGF0dHJpYlN0YXQodHJlZS5ib2R5LCBsb2NhbEVudik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGxvY2FsRW52LmluZm8uc2NvcGUubGVhdmUoKTsKICAgICAgICAgICAgcmVzdWx0ID0gdHJlZS50eXBlID0gbS50eXBlOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgIGNoay5zZXRMaW50KHByZXZMaW50KTsKICAgICAgICAgICAgY2hrLnNldE1ldGhvZChwcmV2TWV0aG9kKTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRWYXJEZWYoSkNWYXJpYWJsZURlY2wgdHJlZSkgewogICAgICAgIC8vIExvY2FsIHZhcmlhYmxlcyBoYXZlIG5vdCBiZWVuIGVudGVyZWQgeWV0LCBzbyB3ZSBuZWVkIHRvIGRvIGl0IG5vdzoKICAgICAgICBpZiAoZW52LmluZm8uc2NvcGUub3duZXIua2luZCA9PSBNVEgpIHsKICAgICAgICAgICAgaWYgKHRyZWUuc3ltICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIC8vIHBhcmFtZXRlcnMgaGF2ZSBhbHJlYWR5IGJlZW4gZW50ZXJlZAogICAgICAgICAgICAgICAgZW52LmluZm8uc2NvcGUuZW50ZXIodHJlZS5zeW0pOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICBhbm5vdGF0ZS5ibG9ja0Fubm90YXRpb25zKCk7CiAgICAgICAgICAgICAgICAgICAgbWVtYmVyRW50ZXIubWVtYmVyRW50ZXIodHJlZSwgZW52KTsKICAgICAgICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgICAgICAgICAgYW5ub3RhdGUudW5ibG9ja0Fubm90YXRpb25zKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBpZiAodHJlZS5pbml0ICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIC8vIEZpZWxkIGluaXRpYWxpemVyIGV4cHJlc3Npb24gbmVlZCB0byBiZSBlbnRlcmVkLgogICAgICAgICAgICAgICAgYW5ub3RhdGUucXVldWVTY2FuVHJlZUFuZFR5cGVBbm5vdGF0ZSh0cmVlLmluaXQsIGVudiwgdHJlZS5zeW0sIHRyZWUucG9zKCkpOwogICAgICAgICAgICAgICAgYW5ub3RhdGUuZmx1c2goKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgVmFyU3ltYm9sIHYgPSB0cmVlLnN5bTsKICAgICAgICBMaW50IGxpbnQgPSBlbnYuaW5mby5saW50LmF1Z21lbnQodik7CiAgICAgICAgTGludCBwcmV2TGludCA9IGNoay5zZXRMaW50KGxpbnQpOwoKICAgICAgICAvLyBDaGVjayB0aGF0IHRoZSB2YXJpYWJsZSdzIGRlY2xhcmVkIHR5cGUgaXMgd2VsbC1mb3JtZWQuCiAgICAgICAgYm9vbGVhbiBpc0ltcGxpY2l0TGFtYmRhUGFyYW1ldGVyID0gZW52LnRyZWUuaGFzVGFnKExBTUJEQSkgJiYKICAgICAgICAgICAgICAgICgoSkNMYW1iZGEpZW52LnRyZWUpLnBhcmFtS2luZCA9PSBKQ0xhbWJkYS5QYXJhbWV0ZXJLaW5kLklNUExJQ0lUICYmCiAgICAgICAgICAgICAgICAodHJlZS5zeW0uZmxhZ3MoKSAmIFBBUkFNRVRFUikgIT0gMDsKICAgICAgICBjaGsudmFsaWRhdGUodHJlZS52YXJ0eXBlLCBlbnYsICFpc0ltcGxpY2l0TGFtYmRhUGFyYW1ldGVyKTsKCiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgdi5nZXRDb25zdFZhbHVlKCk7IC8vIGVuc3VyZSBjb21waWxlLXRpbWUgY29uc3RhbnQgaW5pdGlhbGl6ZXIgaXMgZXZhbHVhdGVkCiAgICAgICAgICAgIGRlZmVycmVkTGludEhhbmRsZXIuZmx1c2godHJlZS5wb3MoKSk7CiAgICAgICAgICAgIGNoay5jaGVja0RlcHJlY2F0ZWRBbm5vdGF0aW9uKHRyZWUucG9zKCksIHYpOwoKICAgICAgICAgICAgaWYgKHRyZWUuaW5pdCAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICBpZiAoKHYuZmxhZ3NfZmllbGQgJiBGSU5BTCkgPT0gMCB8fAogICAgICAgICAgICAgICAgICAgICFtZW1iZXJFbnRlci5uZWVkc0xhenlDb25zdFZhbHVlKHRyZWUuaW5pdCkpIHsKICAgICAgICAgICAgICAgICAgICAvLyBOb3QgYSBjb21waWxlLXRpbWUgY29uc3RhbnQKICAgICAgICAgICAgICAgICAgICAvLyBBdHRyaWJ1dGUgaW5pdGlhbGl6ZXIgaW4gYSBuZXcgZW52aXJvbm1lbnQKICAgICAgICAgICAgICAgICAgICAvLyB3aXRoIHRoZSBkZWNsYXJlZCB2YXJpYWJsZSBhcyBvd25lci4KICAgICAgICAgICAgICAgICAgICAvLyBDaGVjayB0aGF0IGluaXRpYWxpemVyIGNvbmZvcm1zIHRvIHZhcmlhYmxlJ3MgZGVjbGFyZWQgdHlwZS4KICAgICAgICAgICAgICAgICAgICBFbnY8QXR0ckNvbnRleHQ+IGluaXRFbnYgPSBtZW1iZXJFbnRlci5pbml0RW52KHRyZWUsIGVudik7CiAgICAgICAgICAgICAgICAgICAgaW5pdEVudi5pbmZvLmxpbnQgPSBsaW50OwogICAgICAgICAgICAgICAgICAgIC8vIEluIG9yZGVyIHRvIGNhdGNoIHNlbGYtcmVmZXJlbmNlcywgd2Ugc2V0IHRoZSB2YXJpYWJsZSdzCiAgICAgICAgICAgICAgICAgICAgLy8gZGVjbGFyYXRpb24gcG9zaXRpb24gdG8gbWF4aW1hbCBwb3NzaWJsZSB2YWx1ZSwgZWZmZWN0aXZlbHkKICAgICAgICAgICAgICAgICAgICAvLyBtYXJraW5nIHRoZSB2YXJpYWJsZSBhcyB1bmRlZmluZWQuCiAgICAgICAgICAgICAgICAgICAgaW5pdEVudi5pbmZvLmVuY2xWYXIgPSB2OwogICAgICAgICAgICAgICAgICAgIGF0dHJpYkV4cHIodHJlZS5pbml0LCBpbml0RW52LCB2LnR5cGUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJlc3VsdCA9IHRyZWUudHlwZSA9IHYudHlwZTsKICAgICAgICB9CiAgICAgICAgZmluYWxseSB7CiAgICAgICAgICAgIGNoay5zZXRMaW50KHByZXZMaW50KTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRTa2lwKEpDU2tpcCB0cmVlKSB7CiAgICAgICAgcmVzdWx0ID0gbnVsbDsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdEJsb2NrKEpDQmxvY2sgdHJlZSkgewogICAgICAgIGlmIChlbnYuaW5mby5zY29wZS5vd25lci5raW5kID09IFRZUCkgewogICAgICAgICAgICAvLyBCbG9jayBpcyBhIHN0YXRpYyBvciBpbnN0YW5jZSBpbml0aWFsaXplcjsKICAgICAgICAgICAgLy8gbGV0IHRoZSBvd25lciBvZiB0aGUgZW52aXJvbm1lbnQgYmUgYSBmcmVzaGx5CiAgICAgICAgICAgIC8vIGNyZWF0ZWQgQkxPQ0stbWV0aG9kLgogICAgICAgICAgICBTeW1ib2wgZmFrZU93bmVyID0KICAgICAgICAgICAgICAgIG5ldyBNZXRob2RTeW1ib2wodHJlZS5mbGFncyB8IEJMT0NLIHwKICAgICAgICAgICAgICAgICAgICBlbnYuaW5mby5zY29wZS5vd25lci5mbGFncygpICYgU1RSSUNURlAsIG5hbWVzLmVtcHR5LCBudWxsLAogICAgICAgICAgICAgICAgICAgIGVudi5pbmZvLnNjb3BlLm93bmVyKTsKICAgICAgICAgICAgZmluYWwgRW52PEF0dHJDb250ZXh0PiBsb2NhbEVudiA9CiAgICAgICAgICAgICAgICBlbnYuZHVwKHRyZWUsIGVudi5pbmZvLmR1cChlbnYuaW5mby5zY29wZS5kdXBVbnNoYXJlZChmYWtlT3duZXIpKSk7CgogICAgICAgICAgICBpZiAoKHRyZWUuZmxhZ3MgJiBTVEFUSUMpICE9IDApIGxvY2FsRW52LmluZm8uc3RhdGljTGV2ZWwrKzsKICAgICAgICAgICAgLy8gQXR0cmlidXRlIGFsbCB0eXBlIGFubm90YXRpb25zIGluIHRoZSBibG9jawogICAgICAgICAgICBhbm5vdGF0ZS5xdWV1ZVNjYW5UcmVlQW5kVHlwZUFubm90YXRlKHRyZWUsIGxvY2FsRW52LCBsb2NhbEVudi5pbmZvLnNjb3BlLm93bmVyLCBudWxsKTsKICAgICAgICAgICAgYW5ub3RhdGUuZmx1c2goKTsKICAgICAgICAgICAgYXR0cmliU3RhdHModHJlZS5zdGF0cywgbG9jYWxFbnYpOwoKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLy8gU3RvcmUgaW5pdCBhbmQgY2xpbml0IHR5cGUgYW5ub3RhdGlvbnMgd2l0aCB0aGUgQ2xhc3NTeW1ib2wKICAgICAgICAgICAgICAgIC8vIHRvIGFsbG93IG91dHB1dCBpbiBHZW4ubm9ybWFsaXplRGVmcy4KICAgICAgICAgICAgICAgIENsYXNzU3ltYm9sIGNzID0gKENsYXNzU3ltYm9sKWVudi5pbmZvLnNjb3BlLm93bmVyOwogICAgICAgICAgICAgICAgTGlzdDxBdHRyaWJ1dGUuVHlwZUNvbXBvdW5kPiB0YXMgPSBsb2NhbEVudi5pbmZvLnNjb3BlLm93bmVyLmdldFJhd1R5cGVBdHRyaWJ1dGVzKCk7CiAgICAgICAgICAgICAgICBpZiAoKHRyZWUuZmxhZ3MgJiBTVEFUSUMpICE9IDApIHsKICAgICAgICAgICAgICAgICAgICBjcy5hcHBlbmRDbGFzc0luaXRUeXBlQXR0cmlidXRlcyh0YXMpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBjcy5hcHBlbmRJbml0VHlwZUF0dHJpYnV0ZXModGFzKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8vIENyZWF0ZSBhIG5ldyBsb2NhbCBlbnZpcm9ubWVudCB3aXRoIGEgbG9jYWwgc2NvcGUuCiAgICAgICAgICAgIEVudjxBdHRyQ29udGV4dD4gbG9jYWxFbnYgPQogICAgICAgICAgICAgICAgZW52LmR1cCh0cmVlLCBlbnYuaW5mby5kdXAoZW52LmluZm8uc2NvcGUuZHVwKCkpKTsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIGF0dHJpYlN0YXRzKHRyZWUuc3RhdHMsIGxvY2FsRW52KTsKICAgICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgICAgIGxvY2FsRW52LmluZm8uc2NvcGUubGVhdmUoKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXN1bHQgPSBudWxsOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0RG9Mb29wKEpDRG9XaGlsZUxvb3AgdHJlZSkgewogICAgICAgIGF0dHJpYlN0YXQodHJlZS5ib2R5LCBlbnYuZHVwKHRyZWUpKTsKICAgICAgICBhdHRyaWJFeHByKHRyZWUuY29uZCwgZW52LCBzeW1zLmJvb2xlYW5UeXBlKTsKICAgICAgICByZXN1bHQgPSBudWxsOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0V2hpbGVMb29wKEpDV2hpbGVMb29wIHRyZWUpIHsKICAgICAgICBhdHRyaWJFeHByKHRyZWUuY29uZCwgZW52LCBzeW1zLmJvb2xlYW5UeXBlKTsKICAgICAgICBhdHRyaWJTdGF0KHRyZWUuYm9keSwgZW52LmR1cCh0cmVlKSk7CiAgICAgICAgcmVzdWx0ID0gbnVsbDsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdEZvckxvb3AoSkNGb3JMb29wIHRyZWUpIHsKICAgICAgICBFbnY8QXR0ckNvbnRleHQ+IGxvb3BFbnYgPQogICAgICAgICAgICBlbnYuZHVwKGVudi50cmVlLCBlbnYuaW5mby5kdXAoZW52LmluZm8uc2NvcGUuZHVwKCkpKTsKICAgICAgICB0cnkgewogICAgICAgICAgICBhdHRyaWJTdGF0cyh0cmVlLmluaXQsIGxvb3BFbnYpOwogICAgICAgICAgICBpZiAodHJlZS5jb25kICE9IG51bGwpIGF0dHJpYkV4cHIodHJlZS5jb25kLCBsb29wRW52LCBzeW1zLmJvb2xlYW5UeXBlKTsKICAgICAgICAgICAgbG9vcEVudi50cmVlID0gdHJlZTsgLy8gYmVmb3JlLCB3ZSB3ZXJlIG5vdCBpbiBsb29wIQogICAgICAgICAgICBhdHRyaWJTdGF0cyh0cmVlLnN0ZXAsIGxvb3BFbnYpOwogICAgICAgICAgICBhdHRyaWJTdGF0KHRyZWUuYm9keSwgbG9vcEVudik7CiAgICAgICAgICAgIHJlc3VsdCA9IG51bGw7CiAgICAgICAgfQogICAgICAgIGZpbmFsbHkgewogICAgICAgICAgICBsb29wRW52LmluZm8uc2NvcGUubGVhdmUoKTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRGb3JlYWNoTG9vcChKQ0VuaGFuY2VkRm9yTG9vcCB0cmVlKSB7CiAgICAgICAgRW52PEF0dHJDb250ZXh0PiBsb29wRW52ID0KICAgICAgICAgICAgZW52LmR1cChlbnYudHJlZSwgZW52LmluZm8uZHVwKGVudi5pbmZvLnNjb3BlLmR1cCgpKSk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgLy90aGUgRm9ybWFsIFBhcmFtZXRlciBvZiBhIGZvci1lYWNoIGxvb3AgaXMgbm90IGluIHRoZSBzY29wZSB3aGVuCiAgICAgICAgICAgIC8vYXR0cmlidXRpbmcgdGhlIGZvci1lYWNoIGV4cHJlc3Npb247IHdlIG1pbWljayB0aGlzIGJ5IGF0dHJpYnV0aW5nCiAgICAgICAgICAgIC8vdGhlIGZvci1lYWNoIGV4cHJlc3Npb24gZmlyc3QgKGFnYWluc3Qgb3JpZ2luYWwgc2NvcGUpLgogICAgICAgICAgICBUeXBlIGV4cHJUeXBlID0gdHlwZXMuY3ZhclVwcGVyQm91bmQoYXR0cmliRXhwcih0cmVlLmV4cHIsIGxvb3BFbnYpKTsKICAgICAgICAgICAgYXR0cmliU3RhdCh0cmVlLnZhciwgbG9vcEVudik7CiAgICAgICAgICAgIGNoay5jaGVja05vblZvaWQodHJlZS5wb3MoKSwgZXhwclR5cGUpOwogICAgICAgICAgICBUeXBlIGVsZW10eXBlID0gdHlwZXMuZWxlbXR5cGUoZXhwclR5cGUpOyAvLyBwZXJoYXBzIGV4cHIgaXMgYW4gYXJyYXk/CiAgICAgICAgICAgIGlmIChlbGVtdHlwZSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAvLyBvciBwZXJoYXBzIGV4cHIgaW1wbGVtZW50cyBJdGVyYWJsZTxUPj8KICAgICAgICAgICAgICAgIFR5cGUgYmFzZSA9IHR5cGVzLmFzU3VwZXIoZXhwclR5cGUsIHN5bXMuaXRlcmFibGVUeXBlLnRzeW0pOwogICAgICAgICAgICAgICAgaWYgKGJhc2UgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIGxvZy5lcnJvcih0cmVlLmV4cHIucG9zKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZm9yZWFjaC5ub3QuYXBwbGljYWJsZS50by50eXBlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cHJUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlhZ3MuZnJhZ21lbnQoInR5cGUucmVxLmFycmF5Lm9yLml0ZXJhYmxlIikpOwogICAgICAgICAgICAgICAgICAgIGVsZW10eXBlID0gdHlwZXMuY3JlYXRlRXJyb3JUeXBlKGV4cHJUeXBlKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgTGlzdDxUeXBlPiBpdGVyYWJsZVBhcmFtcyA9IGJhc2UuYWxscGFyYW1zKCk7CiAgICAgICAgICAgICAgICAgICAgZWxlbXR5cGUgPSBpdGVyYWJsZVBhcmFtcy5pc0VtcHR5KCkKICAgICAgICAgICAgICAgICAgICAgICAgPyBzeW1zLm9iamVjdFR5cGUKICAgICAgICAgICAgICAgICAgICAgICAgOiB0eXBlcy53aWxkVXBwZXJCb3VuZChpdGVyYWJsZVBhcmFtcy5oZWFkKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBjaGsuY2hlY2tUeXBlKHRyZWUuZXhwci5wb3MoKSwgZWxlbXR5cGUsIHRyZWUudmFyLnN5bS50eXBlKTsKICAgICAgICAgICAgbG9vcEVudi50cmVlID0gdHJlZTsgLy8gYmVmb3JlLCB3ZSB3ZXJlIG5vdCBpbiBsb29wIQogICAgICAgICAgICBhdHRyaWJTdGF0KHRyZWUuYm9keSwgbG9vcEVudik7CiAgICAgICAgICAgIHJlc3VsdCA9IG51bGw7CiAgICAgICAgfQogICAgICAgIGZpbmFsbHkgewogICAgICAgICAgICBsb29wRW52LmluZm8uc2NvcGUubGVhdmUoKTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRMYWJlbGxlZChKQ0xhYmVsZWRTdGF0ZW1lbnQgdHJlZSkgewogICAgICAgIC8vIENoZWNrIHRoYXQgbGFiZWwgaXMgbm90IHVzZWQgaW4gYW4gZW5jbG9zaW5nIHN0YXRlbWVudAogICAgICAgIEVudjxBdHRyQ29udGV4dD4gZW52MSA9IGVudjsKICAgICAgICB3aGlsZSAoZW52MSAhPSBudWxsICYmICFlbnYxLnRyZWUuaGFzVGFnKENMQVNTREVGKSkgewogICAgICAgICAgICBpZiAoZW52MS50cmVlLmhhc1RhZyhMQUJFTExFRCkgJiYKICAgICAgICAgICAgICAgICgoSkNMYWJlbGVkU3RhdGVtZW50KSBlbnYxLnRyZWUpLmxhYmVsID09IHRyZWUubGFiZWwpIHsKICAgICAgICAgICAgICAgIGxvZy5lcnJvcih0cmVlLnBvcygpLCAibGFiZWwuYWxyZWFkeS5pbi51c2UiLAogICAgICAgICAgICAgICAgICAgICAgICAgIHRyZWUubGFiZWwpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZW52MSA9IGVudjEubmV4dDsKICAgICAgICB9CgogICAgICAgIGF0dHJpYlN0YXQodHJlZS5ib2R5LCBlbnYuZHVwKHRyZWUpKTsKICAgICAgICByZXN1bHQgPSBudWxsOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0U3dpdGNoKEpDU3dpdGNoIHRyZWUpIHsKICAgICAgICBUeXBlIHNlbHR5cGUgPSBhdHRyaWJFeHByKHRyZWUuc2VsZWN0b3IsIGVudik7CgogICAgICAgIEVudjxBdHRyQ29udGV4dD4gc3dpdGNoRW52ID0KICAgICAgICAgICAgZW52LmR1cCh0cmVlLCBlbnYuaW5mby5kdXAoZW52LmluZm8uc2NvcGUuZHVwKCkpKTsKCiAgICAgICAgdHJ5IHsKCiAgICAgICAgICAgIGJvb2xlYW4gZW51bVN3aXRjaCA9IChzZWx0eXBlLnRzeW0uZmxhZ3MoKSAmIEZsYWdzLkVOVU0pICE9IDA7CiAgICAgICAgICAgIGJvb2xlYW4gc3RyaW5nU3dpdGNoID0gdHlwZXMuaXNTYW1lVHlwZShzZWx0eXBlLCBzeW1zLnN0cmluZ1R5cGUpOwogICAgICAgICAgICBpZiAoc3RyaW5nU3dpdGNoICYmICFhbGxvd1N0cmluZ3NJblN3aXRjaCkgewogICAgICAgICAgICAgICAgbG9nLmVycm9yKERpYWdub3N0aWNGbGFnLlNPVVJDRV9MRVZFTCwgdHJlZS5zZWxlY3Rvci5wb3MoKSwgInN0cmluZy5zd2l0Y2gubm90LnN1cHBvcnRlZC5pbi5zb3VyY2UiLCBzb3VyY2VOYW1lKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoIWVudW1Td2l0Y2ggJiYgIXN0cmluZ1N3aXRjaCkKICAgICAgICAgICAgICAgIHNlbHR5cGUgPSBjaGsuY2hlY2tUeXBlKHRyZWUuc2VsZWN0b3IucG9zKCksIHNlbHR5cGUsIHN5bXMuaW50VHlwZSk7CgogICAgICAgICAgICAvLyBBdHRyaWJ1dGUgYWxsIGNhc2VzIGFuZAogICAgICAgICAgICAvLyBjaGVjayB0aGF0IHRoZXJlIGFyZSBubyBkdXBsaWNhdGUgY2FzZSBsYWJlbHMgb3IgZGVmYXVsdCBjbGF1c2VzLgogICAgICAgICAgICBTZXQ8T2JqZWN0PiBsYWJlbHMgPSBuZXcgSGFzaFNldDw+KCk7IC8vIFRoZSBzZXQgb2YgY2FzZSBsYWJlbHMuCiAgICAgICAgICAgIGJvb2xlYW4gaGFzRGVmYXVsdCA9IGZhbHNlOyAgICAgIC8vIElzIHRoZXJlIGEgZGVmYXVsdCBsYWJlbD8KICAgICAgICAgICAgZm9yIChMaXN0PEpDQ2FzZT4gbCA9IHRyZWUuY2FzZXM7IGwubm9uRW1wdHkoKTsgbCA9IGwudGFpbCkgewogICAgICAgICAgICAgICAgSkNDYXNlIGMgPSBsLmhlYWQ7CiAgICAgICAgICAgICAgICBpZiAoYy5wYXQgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIGlmIChlbnVtU3dpdGNoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIFN5bWJvbCBzeW0gPSBlbnVtQ29uc3RhbnQoYy5wYXQsIHNlbHR5cGUpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3ltID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZy5lcnJvcihjLnBhdC5wb3MoKSwgImVudW0ubGFiZWwubXVzdC5iZS51bnF1YWxpZmllZC5lbnVtIik7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoIWxhYmVscy5hZGQoc3ltKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9nLmVycm9yKGMucG9zKCksICJkdXBsaWNhdGUuY2FzZS5sYWJlbCIpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgVHlwZSBwYXR0eXBlID0gYXR0cmliRXhwcihjLnBhdCwgc3dpdGNoRW52LCBzZWx0eXBlKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFwYXR0eXBlLmhhc1RhZyhFUlJPUikpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwYXR0eXBlLmNvbnN0VmFsdWUoKSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9nLmVycm9yKGMucGF0LnBvcygpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoc3RyaW5nU3dpdGNoID8gInN0cmluZy5jb25zdC5yZXEiIDogImNvbnN0LmV4cHIucmVxIikpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICghbGFiZWxzLmFkZChwYXR0eXBlLmNvbnN0VmFsdWUoKSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2cuZXJyb3IoYy5wb3MoKSwgImR1cGxpY2F0ZS5jYXNlLmxhYmVsIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGhhc0RlZmF1bHQpIHsKICAgICAgICAgICAgICAgICAgICBsb2cuZXJyb3IoYy5wb3MoKSwgImR1cGxpY2F0ZS5kZWZhdWx0LmxhYmVsIik7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGhhc0RlZmF1bHQgPSB0cnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgRW52PEF0dHJDb250ZXh0PiBjYXNlRW52ID0KICAgICAgICAgICAgICAgICAgICBzd2l0Y2hFbnYuZHVwKGMsIGVudi5pbmZvLmR1cChzd2l0Y2hFbnYuaW5mby5zY29wZS5kdXAoKSkpOwogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICBhdHRyaWJTdGF0cyhjLnN0YXRzLCBjYXNlRW52KTsKICAgICAgICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgICAgICAgICAgY2FzZUVudi5pbmZvLnNjb3BlLmxlYXZlKCk7CiAgICAgICAgICAgICAgICAgICAgYWRkVmFycyhjLnN0YXRzLCBzd2l0Y2hFbnYuaW5mby5zY29wZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJlc3VsdCA9IG51bGw7CiAgICAgICAgfQogICAgICAgIGZpbmFsbHkgewogICAgICAgICAgICBzd2l0Y2hFbnYuaW5mby5zY29wZS5sZWF2ZSgpOwogICAgICAgIH0KICAgIH0KICAgIC8vIHdoZXJlCiAgICAgICAgLyoqIEFkZCBhbnkgdmFyaWFibGVzIGRlZmluZWQgaW4gc3RhdHMgdG8gdGhlIHN3aXRjaCBzY29wZS4gKi8KICAgICAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGFkZFZhcnMoTGlzdDxKQ1N0YXRlbWVudD4gc3RhdHMsIFdyaXRlYWJsZVNjb3BlIHN3aXRjaFNjb3BlKSB7CiAgICAgICAgICAgIGZvciAoO3N0YXRzLm5vbkVtcHR5KCk7IHN0YXRzID0gc3RhdHMudGFpbCkgewogICAgICAgICAgICAgICAgSkNUcmVlIHN0YXQgPSBzdGF0cy5oZWFkOwogICAgICAgICAgICAgICAgaWYgKHN0YXQuaGFzVGFnKFZBUkRFRikpCiAgICAgICAgICAgICAgICAgICAgc3dpdGNoU2NvcGUuZW50ZXIoKChKQ1ZhcmlhYmxlRGVjbCkgc3RhdCkuc3ltKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIC8vIHdoZXJlCiAgICAvKiogUmV0dXJuIHRoZSBzZWxlY3RlZCBlbnVtZXJhdGlvbiBjb25zdGFudCBzeW1ib2wsIG9yIG51bGwuICovCiAgICBwcml2YXRlIFN5bWJvbCBlbnVtQ29uc3RhbnQoSkNUcmVlIHRyZWUsIFR5cGUgZW51bVR5cGUpIHsKICAgICAgICBpZiAodHJlZS5oYXNUYWcoSURFTlQpKSB7CiAgICAgICAgICAgIEpDSWRlbnQgaWRlbnQgPSAoSkNJZGVudCl0cmVlOwogICAgICAgICAgICBOYW1lIG5hbWUgPSBpZGVudC5uYW1lOwogICAgICAgICAgICBmb3IgKFN5bWJvbCBzeW0gOiBlbnVtVHlwZS50c3ltLm1lbWJlcnMoKS5nZXRTeW1ib2xzQnlOYW1lKG5hbWUpKSB7CiAgICAgICAgICAgICAgICBpZiAoc3ltLmtpbmQgPT0gVkFSKSB7CiAgICAgICAgICAgICAgICAgICAgU3ltYm9sIHMgPSBpZGVudC5zeW0gPSBzeW07CiAgICAgICAgICAgICAgICAgICAgKChWYXJTeW1ib2wpcykuZ2V0Q29uc3RWYWx1ZSgpOyAvLyBlbnN1cmUgaW5pdGlhbGl6ZXIgaXMgZXZhbHVhdGVkCiAgICAgICAgICAgICAgICAgICAgaWRlbnQudHlwZSA9IHMudHlwZTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gKChzLmZsYWdzX2ZpZWxkICYgRmxhZ3MuRU5VTSkgPT0gMCkKICAgICAgICAgICAgICAgICAgICAgICAgPyBudWxsIDogczsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdFN5bmNocm9uaXplZChKQ1N5bmNocm9uaXplZCB0cmVlKSB7CiAgICAgICAgY2hrLmNoZWNrUmVmVHlwZSh0cmVlLnBvcygpLCBhdHRyaWJFeHByKHRyZWUubG9jaywgZW52KSk7CiAgICAgICAgYXR0cmliU3RhdCh0cmVlLmJvZHksIGVudik7CiAgICAgICAgcmVzdWx0ID0gbnVsbDsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdFRyeShKQ1RyeSB0cmVlKSB7CiAgICAgICAgLy8gQ3JlYXRlIGEgbmV3IGxvY2FsIGVudmlyb25tZW50IHdpdGggYSBsb2NhbAogICAgICAgIEVudjxBdHRyQ29udGV4dD4gbG9jYWxFbnYgPSBlbnYuZHVwKHRyZWUsIGVudi5pbmZvLmR1cChlbnYuaW5mby5zY29wZS5kdXAoKSkpOwogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGJvb2xlYW4gaXNUcnlXaXRoUmVzb3VyY2UgPSB0cmVlLnJlc291cmNlcy5ub25FbXB0eSgpOwogICAgICAgICAgICAvLyBDcmVhdGUgYSBuZXN0ZWQgZW52aXJvbm1lbnQgZm9yIGF0dHJpYnV0aW5nIHRoZSB0cnkgYmxvY2sgaWYgbmVlZGVkCiAgICAgICAgICAgIEVudjxBdHRyQ29udGV4dD4gdHJ5RW52ID0gaXNUcnlXaXRoUmVzb3VyY2UgPwogICAgICAgICAgICAgICAgZW52LmR1cCh0cmVlLCBsb2NhbEVudi5pbmZvLmR1cChsb2NhbEVudi5pbmZvLnNjb3BlLmR1cCgpKSkgOgogICAgICAgICAgICAgICAgbG9jYWxFbnY7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAvLyBBdHRyaWJ1dGUgcmVzb3VyY2UgZGVjbGFyYXRpb25zCiAgICAgICAgICAgICAgICBmb3IgKEpDVHJlZSByZXNvdXJjZSA6IHRyZWUucmVzb3VyY2VzKSB7CiAgICAgICAgICAgICAgICAgICAgQ2hlY2tDb250ZXh0IHR3ckNvbnRleHQgPSBuZXcgQ2hlY2suTmVzdGVkQ2hlY2tDb250ZXh0KHJlc3VsdEluZm8uY2hlY2tDb250ZXh0KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCByZXBvcnQoRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcywgSkNEaWFnbm9zdGljIGRldGFpbHMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoay5iYXNpY0hhbmRsZXIucmVwb3J0KHBvcywgZGlhZ3MuZnJhZ21lbnQoInRyeS5ub3QuYXBwbGljYWJsZS50by50eXBlIiwgZGV0YWlscykpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgICAgICAgICBSZXN1bHRJbmZvIHR3clJlc3VsdCA9CiAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBSZXN1bHRJbmZvKEtpbmRTZWxlY3Rvci5WQVIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5bXMuYXV0b0Nsb3NlYWJsZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR3ckNvbnRleHQpOwogICAgICAgICAgICAgICAgICAgIGlmIChyZXNvdXJjZS5oYXNUYWcoVkFSREVGKSkgewogICAgICAgICAgICAgICAgICAgICAgICBhdHRyaWJTdGF0KHJlc291cmNlLCB0cnlFbnYpOwogICAgICAgICAgICAgICAgICAgICAgICB0d3JSZXN1bHQuY2hlY2socmVzb3VyY2UsIHJlc291cmNlLnR5cGUpOwoKICAgICAgICAgICAgICAgICAgICAgICAgLy9jaGVjayB0aGF0IHJlc291cmNlIHR5cGUgY2Fubm90IHRocm93IEludGVycnVwdGVkRXhjZXB0aW9uCiAgICAgICAgICAgICAgICAgICAgICAgIGNoZWNrQXV0b0Nsb3NlYWJsZShyZXNvdXJjZS5wb3MoKSwgbG9jYWxFbnYsIHJlc291cmNlLnR5cGUpOwoKICAgICAgICAgICAgICAgICAgICAgICAgVmFyU3ltYm9sIHZhciA9ICgoSkNWYXJpYWJsZURlY2wpIHJlc291cmNlKS5zeW07CiAgICAgICAgICAgICAgICAgICAgICAgIHZhci5zZXREYXRhKEVsZW1lbnRLaW5kLlJFU09VUkNFX1ZBUklBQkxFKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBhdHRyaWJUcmVlKHJlc291cmNlLCB0cnlFbnYsIHR3clJlc3VsdCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgLy8gQXR0cmlidXRlIGJvZHkKICAgICAgICAgICAgICAgIGF0dHJpYlN0YXQodHJlZS5ib2R5LCB0cnlFbnYpOwogICAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAgICAgaWYgKGlzVHJ5V2l0aFJlc291cmNlKQogICAgICAgICAgICAgICAgICAgIHRyeUVudi5pbmZvLnNjb3BlLmxlYXZlKCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIEF0dHJpYnV0ZSBjYXRjaCBjbGF1c2VzCiAgICAgICAgICAgIGZvciAoTGlzdDxKQ0NhdGNoPiBsID0gdHJlZS5jYXRjaGVyczsgbC5ub25FbXB0eSgpOyBsID0gbC50YWlsKSB7CiAgICAgICAgICAgICAgICBKQ0NhdGNoIGMgPSBsLmhlYWQ7CiAgICAgICAgICAgICAgICBFbnY8QXR0ckNvbnRleHQ+IGNhdGNoRW52ID0KICAgICAgICAgICAgICAgICAgICBsb2NhbEVudi5kdXAoYywgbG9jYWxFbnYuaW5mby5kdXAobG9jYWxFbnYuaW5mby5zY29wZS5kdXAoKSkpOwogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICBUeXBlIGN0eXBlID0gYXR0cmliU3RhdChjLnBhcmFtLCBjYXRjaEVudik7CiAgICAgICAgICAgICAgICAgICAgaWYgKFRyZWVJbmZvLmlzTXVsdGlDYXRjaChjKSkgewogICAgICAgICAgICAgICAgICAgICAgICAvL211bHRpLWNhdGNoIHBhcmFtZXRlciBpcyBpbXBsaWNpdGx5IG1hcmtlZCBhcyBmaW5hbAogICAgICAgICAgICAgICAgICAgICAgICBjLnBhcmFtLnN5bS5mbGFnc19maWVsZCB8PSBGSU5BTCB8IFVOSU9OOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoYy5wYXJhbS5zeW0ua2luZCA9PSBWQVIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgYy5wYXJhbS5zeW0uc2V0RGF0YShFbGVtZW50S2luZC5FWENFUFRJT05fUEFSQU1FVEVSKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgY2hrLmNoZWNrVHlwZShjLnBhcmFtLnZhcnR5cGUucG9zKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGsuY2hlY2tDbGFzc1R5cGUoYy5wYXJhbS52YXJ0eXBlLnBvcygpLCBjdHlwZSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeW1zLnRocm93YWJsZVR5cGUpOwogICAgICAgICAgICAgICAgICAgIGF0dHJpYlN0YXQoYy5ib2R5LCBjYXRjaEVudik7CiAgICAgICAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAgICAgICAgIGNhdGNoRW52LmluZm8uc2NvcGUubGVhdmUoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gQXR0cmlidXRlIGZpbmFsaXplcgogICAgICAgICAgICBpZiAodHJlZS5maW5hbGl6ZXIgIT0gbnVsbCkgYXR0cmliU3RhdCh0cmVlLmZpbmFsaXplciwgbG9jYWxFbnYpOwogICAgICAgICAgICByZXN1bHQgPSBudWxsOwogICAgICAgIH0KICAgICAgICBmaW5hbGx5IHsKICAgICAgICAgICAgbG9jYWxFbnYuaW5mby5zY29wZS5sZWF2ZSgpOwogICAgICAgIH0KICAgIH0KCiAgICB2b2lkIGNoZWNrQXV0b0Nsb3NlYWJsZShEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBFbnY8QXR0ckNvbnRleHQ+IGVudiwgVHlwZSByZXNvdXJjZSkgewogICAgICAgIGlmICghcmVzb3VyY2UuaXNFcnJvbmVvdXMoKSAmJgogICAgICAgICAgICB0eXBlcy5hc1N1cGVyKHJlc291cmNlLCBzeW1zLmF1dG9DbG9zZWFibGVUeXBlLnRzeW0pICE9IG51bGwgJiYKICAgICAgICAgICAgIXR5cGVzLmlzU2FtZVR5cGUocmVzb3VyY2UsIHN5bXMuYXV0b0Nsb3NlYWJsZVR5cGUpKSB7IC8vIERvbid0IGVtaXQgd2FybmluZyBmb3IgQXV0b0Nsb3NlYWJsZSBpdHNlbGYKICAgICAgICAgICAgU3ltYm9sIGNsb3NlID0gc3ltcy5ub1N5bWJvbDsKICAgICAgICAgICAgTG9nLkRpYWdub3N0aWNIYW5kbGVyIGRpc2NhcmRIYW5kbGVyID0gbmV3IExvZy5EaXNjYXJkRGlhZ25vc3RpY0hhbmRsZXIobG9nKTsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIGNsb3NlID0gcnMucmVzb2x2ZVF1YWxpZmllZE1ldGhvZChwb3MsCiAgICAgICAgICAgICAgICAgICAgICAgIGVudiwKICAgICAgICAgICAgICAgICAgICAgICAgdHlwZXMuc2tpcFR5cGVWYXJzKHJlc291cmNlLCBmYWxzZSksCiAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVzLmNsb3NlLAogICAgICAgICAgICAgICAgICAgICAgICBMaXN0Lm5pbCgpLAogICAgICAgICAgICAgICAgICAgICAgICBMaXN0Lm5pbCgpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBmaW5hbGx5IHsKICAgICAgICAgICAgICAgIGxvZy5wb3BEaWFnbm9zdGljSGFuZGxlcihkaXNjYXJkSGFuZGxlcik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGNsb3NlLmtpbmQgPT0gTVRIICYmCiAgICAgICAgICAgICAgICAgICAgY2xvc2Uub3ZlcnJpZGVzKHN5bXMuYXV0b0Nsb3NlYWJsZUNsb3NlLCByZXNvdXJjZS50c3ltLCB0eXBlcywgdHJ1ZSkgJiYKICAgICAgICAgICAgICAgICAgICBjaGsuaXNIYW5kbGVkKHN5bXMuaW50ZXJydXB0ZWRFeGNlcHRpb25UeXBlLCB0eXBlcy5tZW1iZXJUeXBlKHJlc291cmNlLCBjbG9zZSkuZ2V0VGhyb3duVHlwZXMoKSkgJiYKICAgICAgICAgICAgICAgICAgICBlbnYuaW5mby5saW50LmlzRW5hYmxlZChMaW50Q2F0ZWdvcnkuVFJZKSkgewogICAgICAgICAgICAgICAgbG9nLndhcm5pbmcoTGludENhdGVnb3J5LlRSWSwgcG9zLCAidHJ5LnJlc291cmNlLnRocm93cy5pbnRlcnJ1cHRlZC5leGMiLCByZXNvdXJjZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRDb25kaXRpb25hbChKQ0NvbmRpdGlvbmFsIHRyZWUpIHsKICAgICAgICBUeXBlIGNvbmR0eXBlID0gYXR0cmliRXhwcih0cmVlLmNvbmQsIGVudiwgc3ltcy5ib29sZWFuVHlwZSk7CgogICAgICAgIHRyZWUucG9seUtpbmQgPSAoIWFsbG93UG9seSB8fAogICAgICAgICAgICAgICAgcHQoKS5oYXNUYWcoTk9ORSkgJiYgcHQoKSAhPSBUeXBlLnJlY292ZXJ5VHlwZSAmJiBwdCgpICE9IEluZmVyLmFueVBvbHkgfHwKICAgICAgICAgICAgICAgIGlzQm9vbGVhbk9yTnVtZXJpYyhlbnYsIHRyZWUpKSA/CiAgICAgICAgICAgICAgICBQb2x5S2luZC5TVEFOREFMT05FIDogUG9seUtpbmQuUE9MWTsKCiAgICAgICAgaWYgKHRyZWUucG9seUtpbmQgPT0gUG9seUtpbmQuUE9MWSAmJiByZXN1bHRJbmZvLnB0Lmhhc1RhZyhWT0lEKSkgewogICAgICAgICAgICAvL3RoaXMgbWVhbnMgd2UgYXJlIHJldHVybmluZyBhIHBvbHkgY29uZGl0aW9uYWwgZnJvbSB2b2lkLWNvbXBhdGlibGUgbGFtYmRhIGV4cHJlc3Npb24KICAgICAgICAgICAgcmVzdWx0SW5mby5jaGVja0NvbnRleHQucmVwb3J0KHRyZWUsIGRpYWdzLmZyYWdtZW50KCJjb25kaXRpb25hbC50YXJnZXQuY2FudC5iZS52b2lkIikpOwogICAgICAgICAgICByZXN1bHQgPSB0cmVlLnR5cGUgPSB0eXBlcy5jcmVhdGVFcnJvclR5cGUocmVzdWx0SW5mby5wdCk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIFJlc3VsdEluZm8gY29uZEluZm8gPSB0cmVlLnBvbHlLaW5kID09IFBvbHlLaW5kLlNUQU5EQUxPTkUgPwogICAgICAgICAgICAgICAgdW5rbm93bkV4cHJJbmZvIDoKICAgICAgICAgICAgICAgIHJlc3VsdEluZm8uZHVwKGNvbmRpdGlvbmFsQ29udGV4dChyZXN1bHRJbmZvLmNoZWNrQ29udGV4dCkpOwoKICAgICAgICBUeXBlIHRydWV0eXBlID0gYXR0cmliVHJlZSh0cmVlLnRydWVwYXJ0LCBlbnYsIGNvbmRJbmZvKTsKICAgICAgICBUeXBlIGZhbHNldHlwZSA9IGF0dHJpYlRyZWUodHJlZS5mYWxzZXBhcnQsIGVudiwgY29uZEluZm8pOwoKICAgICAgICBUeXBlIG93bnR5cGUgPSAodHJlZS5wb2x5S2luZCA9PSBQb2x5S2luZC5TVEFOREFMT05FKSA/IGNvbmRUeXBlKHRyZWUsIHRydWV0eXBlLCBmYWxzZXR5cGUpIDogcHQoKTsKICAgICAgICBpZiAoY29uZHR5cGUuY29uc3RWYWx1ZSgpICE9IG51bGwgJiYKICAgICAgICAgICAgICAgIHRydWV0eXBlLmNvbnN0VmFsdWUoKSAhPSBudWxsICYmCiAgICAgICAgICAgICAgICBmYWxzZXR5cGUuY29uc3RWYWx1ZSgpICE9IG51bGwgJiYKICAgICAgICAgICAgICAgICFvd250eXBlLmhhc1RhZyhOT05FKSkgewogICAgICAgICAgICAvL2NvbnN0YW50IGZvbGRpbmcKICAgICAgICAgICAgb3dudHlwZSA9IGNmb2xkZXIuY29lcmNlKGNvbmR0eXBlLmlzVHJ1ZSgpID8gdHJ1ZXR5cGUgOiBmYWxzZXR5cGUsIG93bnR5cGUpOwogICAgICAgIH0KICAgICAgICByZXN1bHQgPSBjaGVjayh0cmVlLCBvd250eXBlLCBLaW5kU2VsZWN0b3IuVkFMLCByZXN1bHRJbmZvKTsKICAgIH0KICAgIC8vd2hlcmUKICAgICAgICBwcml2YXRlIGJvb2xlYW4gaXNCb29sZWFuT3JOdW1lcmljKEVudjxBdHRyQ29udGV4dD4gZW52LCBKQ0V4cHJlc3Npb24gdHJlZSkgewogICAgICAgICAgICBzd2l0Y2ggKHRyZWUuZ2V0VGFnKCkpIHsKICAgICAgICAgICAgICAgIGNhc2UgTElURVJBTDogcmV0dXJuICgoSkNMaXRlcmFsKXRyZWUpLnR5cGV0YWcuaXNTdWJSYW5nZU9mKERPVUJMRSkgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKChKQ0xpdGVyYWwpdHJlZSkudHlwZXRhZyA9PSBCT09MRUFOIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoSkNMaXRlcmFsKXRyZWUpLnR5cGV0YWcgPT0gQk9UOwogICAgICAgICAgICAgICAgY2FzZSBMQU1CREE6IGNhc2UgUkVGRVJFTkNFOiByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICBjYXNlIFBBUkVOUzogcmV0dXJuIGlzQm9vbGVhbk9yTnVtZXJpYyhlbnYsICgoSkNQYXJlbnMpdHJlZSkuZXhwcik7CiAgICAgICAgICAgICAgICBjYXNlIENPTkRFWFBSOgogICAgICAgICAgICAgICAgICAgIEpDQ29uZGl0aW9uYWwgY29uZFRyZWUgPSAoSkNDb25kaXRpb25hbCl0cmVlOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBpc0Jvb2xlYW5Pck51bWVyaWMoZW52LCBjb25kVHJlZS50cnVlcGFydCkgJiYKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzQm9vbGVhbk9yTnVtZXJpYyhlbnYsIGNvbmRUcmVlLmZhbHNlcGFydCk7CiAgICAgICAgICAgICAgICBjYXNlIEFQUExZOgogICAgICAgICAgICAgICAgICAgIEpDTWV0aG9kSW52b2NhdGlvbiBzcGVjdWxhdGl2ZU1ldGhvZFRyZWUgPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgKEpDTWV0aG9kSW52b2NhdGlvbilkZWZlcnJlZEF0dHIuYXR0cmliU3BlY3VsYXRpdmUodHJlZSwgZW52LCB1bmtub3duRXhwckluZm8pOwogICAgICAgICAgICAgICAgICAgIFN5bWJvbCBtc3ltID0gVHJlZUluZm8uc3ltYm9sKHNwZWN1bGF0aXZlTWV0aG9kVHJlZS5tZXRoKTsKICAgICAgICAgICAgICAgICAgICBUeXBlIHJlY2VpdmVyVHlwZSA9IHNwZWN1bGF0aXZlTWV0aG9kVHJlZS5tZXRoLmhhc1RhZyhJREVOVCkgPwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZW52LmVuY2xDbGFzcy50eXBlIDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoSkNGaWVsZEFjY2VzcylzcGVjdWxhdGl2ZU1ldGhvZFRyZWUubWV0aCkuc2VsZWN0ZWQudHlwZTsKICAgICAgICAgICAgICAgICAgICBUeXBlIG93bnR5cGUgPSB0eXBlcy5tZW1iZXJUeXBlKHJlY2VpdmVyVHlwZSwgbXN5bSkuZ2V0UmV0dXJuVHlwZSgpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBwcmltaXRpdmVPckJveGVkKG93bnR5cGUpOwogICAgICAgICAgICAgICAgY2FzZSBORVdDTEFTUzoKICAgICAgICAgICAgICAgICAgICBKQ0V4cHJlc3Npb24gY2xhc3NOYW1lID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZUNsYXNzUGFyYW1zLnRyYW5zbGF0ZSgoKEpDTmV3Q2xhc3MpdHJlZSkuY2xhenopOwogICAgICAgICAgICAgICAgICAgIEpDRXhwcmVzc2lvbiBzcGVjdWxhdGl2ZU5ld0NsYXNzVHJlZSA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoSkNFeHByZXNzaW9uKWRlZmVycmVkQXR0ci5hdHRyaWJTcGVjdWxhdGl2ZShjbGFzc05hbWUsIGVudiwgdW5rbm93blR5cGVJbmZvKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gcHJpbWl0aXZlT3JCb3hlZChzcGVjdWxhdGl2ZU5ld0NsYXNzVHJlZS50eXBlKTsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgVHlwZSBzcGVjdWxhdGl2ZVR5cGUgPSBkZWZlcnJlZEF0dHIuYXR0cmliU3BlY3VsYXRpdmUodHJlZSwgZW52LCB1bmtub3duRXhwckluZm8pLnR5cGU7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHByaW1pdGl2ZU9yQm94ZWQoc3BlY3VsYXRpdmVUeXBlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvL3doZXJlCiAgICAgICAgICAgIGJvb2xlYW4gcHJpbWl0aXZlT3JCb3hlZChUeXBlIHQpIHsKICAgICAgICAgICAgICAgIHJldHVybiAoIXQuaGFzVGFnKFRZUEVWQVIpICYmIHR5cGVzLnVuYm94ZWRUeXBlT3JUeXBlKHQpLmlzUHJpbWl0aXZlKCkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBUcmVlVHJhbnNsYXRvciByZW1vdmVDbGFzc1BhcmFtcyA9IG5ldyBUcmVlVHJhbnNsYXRvcigpIHsKICAgICAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICAgICAgcHVibGljIHZvaWQgdmlzaXRUeXBlQXBwbHkoSkNUeXBlQXBwbHkgdHJlZSkgewogICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IHRyYW5zbGF0ZSh0cmVlLmNsYXp6KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKCiAgICAgICAgQ2hlY2tDb250ZXh0IGNvbmRpdGlvbmFsQ29udGV4dChDaGVja0NvbnRleHQgY2hlY2tDb250ZXh0KSB7CiAgICAgICAgICAgIHJldHVybiBuZXcgQ2hlY2suTmVzdGVkQ2hlY2tDb250ZXh0KGNoZWNrQ29udGV4dCkgewogICAgICAgICAgICAgICAgLy90aGlzIHdpbGwgdXNlIGVuY2xvc2luZyBjaGVjayBjb250ZXh0IHRvIGNoZWNrIGNvbXBhdGliaWxpdHkgb2YKICAgICAgICAgICAgICAgIC8vc3ViZXhwcmVzc2lvbiBhZ2FpbnN0IHRhcmdldCB0eXBlOyBpZiB3ZSBhcmUgaW4gYSBtZXRob2QgY2hlY2sgY29udGV4dCwKICAgICAgICAgICAgICAgIC8vZGVwZW5kaW5nIG9uIHdoZXRoZXIgYm94aW5nIGlzIGFsbG93ZWQsIHdlIGNvdWxkIGhhdmUgaW5jb21wYXRpYmlsaXRpZXMKICAgICAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICAgICAgcHVibGljIHZvaWQgcmVwb3J0KERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIEpDRGlhZ25vc3RpYyBkZXRhaWxzKSB7CiAgICAgICAgICAgICAgICAgICAgZW5jbG9zaW5nQ29udGV4dC5yZXBvcnQocG9zLCBkaWFncy5mcmFnbWVudCgiaW5jb21wYXRpYmxlLnR5cGUuaW4uY29uZGl0aW9uYWwiLCBkZXRhaWxzKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CiAgICAgICAgfQoKICAgICAgICAvKiogQ29tcHV0ZSB0aGUgdHlwZSBvZiBhIGNvbmRpdGlvbmFsIGV4cHJlc3Npb24sIGFmdGVyCiAgICAgICAgICogIGNoZWNraW5nIHRoYXQgaXQgZXhpc3RzLiAgU2VlIEpMUyAxNS4yNS4gRG9lcyBub3QgdGFrZSBpbnRvCiAgICAgICAgICogIGFjY291bnQgdGhlIHNwZWNpYWwgY2FzZSB3aGVyZSBjb25kaXRpb24gYW5kIGJvdGggYXJtcwogICAgICAgICAqICBhcmUgY29uc3RhbnRzLgogICAgICAgICAqCiAgICAgICAgICogIEBwYXJhbSBwb3MgICAgICBUaGUgc291cmNlIHBvc2l0aW9uIHRvIGJlIHVzZWQgZm9yIGVycm9yCiAgICAgICAgICogICAgICAgICAgICAgICAgICBkaWFnbm9zdGljcy4KICAgICAgICAgKiAgQHBhcmFtIHRoZW50eXBlIFRoZSB0eXBlIG9mIHRoZSBleHByZXNzaW9uJ3MgdGhlbi1wYXJ0LgogICAgICAgICAqICBAcGFyYW0gZWxzZXR5cGUgVGhlIHR5cGUgb2YgdGhlIGV4cHJlc3Npb24ncyBlbHNlLXBhcnQuCiAgICAgICAgICovCiAgICAgICAgVHlwZSBjb25kVHlwZShEaWFnbm9zdGljUG9zaXRpb24gcG9zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVHlwZSB0aGVudHlwZSwgVHlwZSBlbHNldHlwZSkgewogICAgICAgICAgICAvLyBJZiBzYW1lIHR5cGUsIHRoYXQgaXMgdGhlIHJlc3VsdAogICAgICAgICAgICBpZiAodHlwZXMuaXNTYW1lVHlwZSh0aGVudHlwZSwgZWxzZXR5cGUpKQogICAgICAgICAgICAgICAgcmV0dXJuIHRoZW50eXBlLmJhc2VUeXBlKCk7CgogICAgICAgICAgICBUeXBlIHRoZW5VbmJveGVkID0gKHRoZW50eXBlLmlzUHJpbWl0aXZlKCkpCiAgICAgICAgICAgICAgICA/IHRoZW50eXBlIDogdHlwZXMudW5ib3hlZFR5cGUodGhlbnR5cGUpOwogICAgICAgICAgICBUeXBlIGVsc2VVbmJveGVkID0gKGVsc2V0eXBlLmlzUHJpbWl0aXZlKCkpCiAgICAgICAgICAgICAgICA/IGVsc2V0eXBlIDogdHlwZXMudW5ib3hlZFR5cGUoZWxzZXR5cGUpOwoKICAgICAgICAgICAgLy8gT3RoZXJ3aXNlLCBpZiBib3RoIGFybXMgY2FuIGJlIGNvbnZlcnRlZCB0byBhIG51bWVyaWMKICAgICAgICAgICAgLy8gdHlwZSwgcmV0dXJuIHRoZSBsZWFzdCBudW1lcmljIHR5cGUgdGhhdCBmaXRzIGJvdGggYXJtcwogICAgICAgICAgICAvLyAoaS5lLiByZXR1cm4gbGFyZ2VyIG9mIHRoZSB0d28sIG9yIHJldHVybiBpbnQgaWYgb25lCiAgICAgICAgICAgIC8vIGFybSBpcyBzaG9ydCwgdGhlIG90aGVyIGlzIGNoYXIpLgogICAgICAgICAgICBpZiAodGhlblVuYm94ZWQuaXNQcmltaXRpdmUoKSAmJiBlbHNlVW5ib3hlZC5pc1ByaW1pdGl2ZSgpKSB7CiAgICAgICAgICAgICAgICAvLyBJZiBvbmUgYXJtIGhhcyBhbiBpbnRlZ2VyIHN1YnJhbmdlIHR5cGUgKGkuZS4sIGJ5dGUsCiAgICAgICAgICAgICAgICAvLyBzaG9ydCwgb3IgY2hhciksIGFuZCB0aGUgb3RoZXIgaXMgYW4gaW50ZWdlciBjb25zdGFudAogICAgICAgICAgICAgICAgLy8gdGhhdCBmaXRzIGludG8gdGhlIHN1YnJhbmdlLCByZXR1cm4gdGhlIHN1YnJhbmdlIHR5cGUuCiAgICAgICAgICAgICAgICBpZiAodGhlblVuYm94ZWQuZ2V0VGFnKCkuaXNTdHJpY3RTdWJSYW5nZU9mKElOVCkgJiYKICAgICAgICAgICAgICAgICAgICBlbHNlVW5ib3hlZC5oYXNUYWcoSU5UKSAmJgogICAgICAgICAgICAgICAgICAgIHR5cGVzLmlzQXNzaWduYWJsZShlbHNlVW5ib3hlZCwgdGhlblVuYm94ZWQpKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoZW5VbmJveGVkLmJhc2VUeXBlKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoZWxzZVVuYm94ZWQuZ2V0VGFnKCkuaXNTdHJpY3RTdWJSYW5nZU9mKElOVCkgJiYKICAgICAgICAgICAgICAgICAgICB0aGVuVW5ib3hlZC5oYXNUYWcoSU5UKSAmJgogICAgICAgICAgICAgICAgICAgIHR5cGVzLmlzQXNzaWduYWJsZSh0aGVuVW5ib3hlZCwgZWxzZVVuYm94ZWQpKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGVsc2VVbmJveGVkLmJhc2VUeXBlKCk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgZm9yIChUeXBlVGFnIHRhZyA6IHByaW1pdGl2ZVRhZ3MpIHsKICAgICAgICAgICAgICAgICAgICBUeXBlIGNhbmRpZGF0ZSA9IHN5bXMudHlwZU9mVGFnW3RhZy5vcmRpbmFsKCldOwogICAgICAgICAgICAgICAgICAgIGlmICh0eXBlcy5pc1N1YnR5cGUodGhlblVuYm94ZWQsIGNhbmRpZGF0ZSkgJiYKICAgICAgICAgICAgICAgICAgICAgICAgdHlwZXMuaXNTdWJ0eXBlKGVsc2VVbmJveGVkLCBjYW5kaWRhdGUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjYW5kaWRhdGU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBUaG9zZSB3ZXJlIGFsbCB0aGUgY2FzZXMgdGhhdCBjb3VsZCByZXN1bHQgaW4gYSBwcmltaXRpdmUKICAgICAgICAgICAgaWYgKHRoZW50eXBlLmlzUHJpbWl0aXZlKCkpCiAgICAgICAgICAgICAgICB0aGVudHlwZSA9IHR5cGVzLmJveGVkQ2xhc3ModGhlbnR5cGUpLnR5cGU7CiAgICAgICAgICAgIGlmIChlbHNldHlwZS5pc1ByaW1pdGl2ZSgpKQogICAgICAgICAgICAgICAgZWxzZXR5cGUgPSB0eXBlcy5ib3hlZENsYXNzKGVsc2V0eXBlKS50eXBlOwoKICAgICAgICAgICAgaWYgKHR5cGVzLmlzU3VidHlwZSh0aGVudHlwZSwgZWxzZXR5cGUpKQogICAgICAgICAgICAgICAgcmV0dXJuIGVsc2V0eXBlLmJhc2VUeXBlKCk7CiAgICAgICAgICAgIGlmICh0eXBlcy5pc1N1YnR5cGUoZWxzZXR5cGUsIHRoZW50eXBlKSkKICAgICAgICAgICAgICAgIHJldHVybiB0aGVudHlwZS5iYXNlVHlwZSgpOwoKICAgICAgICAgICAgaWYgKHRoZW50eXBlLmhhc1RhZyhWT0lEKSB8fCBlbHNldHlwZS5oYXNUYWcoVk9JRCkpIHsKICAgICAgICAgICAgICAgIGxvZy5lcnJvcihwb3MsICJuZWl0aGVyLmNvbmRpdGlvbmFsLnN1YnR5cGUiLAogICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW50eXBlLCBlbHNldHlwZSk7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhlbnR5cGUuYmFzZVR5cGUoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gYm90aCBhcmUga25vd24gdG8gYmUgcmVmZXJlbmNlIHR5cGVzLiAgVGhlIHJlc3VsdCBpcwogICAgICAgICAgICAvLyBsdWIodGhlbnR5cGUsZWxzZXR5cGUpLiBUaGlzIGNhbm5vdCBmYWlsLCBhcyBpdCB3aWxsCiAgICAgICAgICAgIC8vIGFsd2F5cyBiZSBwb3NzaWJsZSB0byBpbmZlciAiT2JqZWN0IiBpZiBub3RoaW5nIGJldHRlci4KICAgICAgICAgICAgcmV0dXJuIHR5cGVzLmx1Yih0aGVudHlwZS5iYXNlVHlwZSgpLCBlbHNldHlwZS5iYXNlVHlwZSgpKTsKICAgICAgICB9CgogICAgZmluYWwgc3RhdGljIFR5cGVUYWdbXSBwcmltaXRpdmVUYWdzID0gbmV3IFR5cGVUYWdbXXsKICAgICAgICBCWVRFLAogICAgICAgIENIQVIsCiAgICAgICAgU0hPUlQsCiAgICAgICAgSU5ULAogICAgICAgIExPTkcsCiAgICAgICAgRkxPQVQsCiAgICAgICAgRE9VQkxFLAogICAgICAgIEJPT0xFQU4sCiAgICB9OwoKICAgIHB1YmxpYyB2b2lkIHZpc2l0SWYoSkNJZiB0cmVlKSB7CiAgICAgICAgYXR0cmliRXhwcih0cmVlLmNvbmQsIGVudiwgc3ltcy5ib29sZWFuVHlwZSk7CiAgICAgICAgYXR0cmliU3RhdCh0cmVlLnRoZW5wYXJ0LCBlbnYpOwogICAgICAgIGlmICh0cmVlLmVsc2VwYXJ0ICE9IG51bGwpCiAgICAgICAgICAgIGF0dHJpYlN0YXQodHJlZS5lbHNlcGFydCwgZW52KTsKICAgICAgICBjaGsuY2hlY2tFbXB0eUlmKHRyZWUpOwogICAgICAgIHJlc3VsdCA9IG51bGw7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRFeGVjKEpDRXhwcmVzc2lvblN0YXRlbWVudCB0cmVlKSB7CiAgICAgICAgLy9hIGZyZXNoIGVudmlyb25tZW50IGlzIHJlcXVpcmVkIGZvciAyOTIgaW5mZXJlbmNlIHRvIHdvcmsgcHJvcGVybHkgLS0tCiAgICAgICAgLy9zZWUgSW5mZXIuaW5zdGFudGlhdGVQb2x5bW9ycGhpY1NpZ25hdHVyZUluc3RhbmNlKCkKICAgICAgICBFbnY8QXR0ckNvbnRleHQ+IGxvY2FsRW52ID0gZW52LmR1cCh0cmVlKTsKICAgICAgICBhdHRyaWJFeHByKHRyZWUuZXhwciwgbG9jYWxFbnYpOwogICAgICAgIHJlc3VsdCA9IG51bGw7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRCcmVhayhKQ0JyZWFrIHRyZWUpIHsKICAgICAgICB0cmVlLnRhcmdldCA9IGZpbmRKdW1wVGFyZ2V0KHRyZWUucG9zKCksIHRyZWUuZ2V0VGFnKCksIHRyZWUubGFiZWwsIGVudik7CiAgICAgICAgcmVzdWx0ID0gbnVsbDsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdENvbnRpbnVlKEpDQ29udGludWUgdHJlZSkgewogICAgICAgIHRyZWUudGFyZ2V0ID0gZmluZEp1bXBUYXJnZXQodHJlZS5wb3MoKSwgdHJlZS5nZXRUYWcoKSwgdHJlZS5sYWJlbCwgZW52KTsKICAgICAgICByZXN1bHQgPSBudWxsOwogICAgfQogICAgLy93aGVyZQogICAgICAgIC8qKiBSZXR1cm4gdGhlIHRhcmdldCBvZiBhIGJyZWFrIG9yIGNvbnRpbnVlIHN0YXRlbWVudCwgaWYgaXQgZXhpc3RzLAogICAgICAgICAqICByZXBvcnQgYW4gZXJyb3IgaWYgbm90LgogICAgICAgICAqICBOb3RlOiBUaGUgdGFyZ2V0IG9mIGEgbGFiZWxsZWQgYnJlYWsgb3IgY29udGludWUgaXMgdGhlCiAgICAgICAgICogIChub24tbGFiZWxsZWQpIHN0YXRlbWVudCB0cmVlIHJlZmVycmVkIHRvIGJ5IHRoZSBsYWJlbCwKICAgICAgICAgKiAgbm90IHRoZSB0cmVlIHJlcHJlc2VudGluZyB0aGUgbGFiZWxsZWQgc3RhdGVtZW50IGl0c2VsZi4KICAgICAgICAgKgogICAgICAgICAqICBAcGFyYW0gcG9zICAgICBUaGUgcG9zaXRpb24gdG8gYmUgdXNlZCBmb3IgZXJyb3IgZGlhZ25vc3RpY3MKICAgICAgICAgKiAgQHBhcmFtIHRhZyAgICAgVGhlIHRhZyBvZiB0aGUganVtcCBzdGF0ZW1lbnQuIFRoaXMgaXMgZWl0aGVyCiAgICAgICAgICogICAgICAgICAgICAgICAgIFRyZWUuQlJFQUsgb3IgVHJlZS5DT05USU5VRS4KICAgICAgICAgKiAgQHBhcmFtIGxhYmVsICAgVGhlIGxhYmVsIG9mIHRoZSBqdW1wIHN0YXRlbWVudCwgb3IgbnVsbCBpZiBubwogICAgICAgICAqICAgICAgICAgICAgICAgICBsYWJlbCBpcyBnaXZlbi4KICAgICAgICAgKiAgQHBhcmFtIGVudiAgICAgVGhlIGVudmlyb25tZW50IGN1cnJlbnQgYXQgdGhlIGp1bXAgc3RhdGVtZW50LgogICAgICAgICAqLwogICAgICAgIHByaXZhdGUgSkNUcmVlIGZpbmRKdW1wVGFyZ2V0KERpYWdub3N0aWNQb3NpdGlvbiBwb3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEpDVHJlZS5UYWcgdGFnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOYW1lIGxhYmVsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFbnY8QXR0ckNvbnRleHQ+IGVudikgewogICAgICAgICAgICAvLyBTZWFyY2ggZW52aXJvbm1lbnRzIG91dHdhcmRzIGZyb20gdGhlIHBvaW50IG9mIGp1bXAuCiAgICAgICAgICAgIEVudjxBdHRyQ29udGV4dD4gZW52MSA9IGVudjsKICAgICAgICAgICAgTE9PUDoKICAgICAgICAgICAgd2hpbGUgKGVudjEgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgc3dpdGNoIChlbnYxLnRyZWUuZ2V0VGFnKCkpIHsKICAgICAgICAgICAgICAgICAgICBjYXNlIExBQkVMTEVEOgogICAgICAgICAgICAgICAgICAgICAgICBKQ0xhYmVsZWRTdGF0ZW1lbnQgbGFiZWxsZWQgPSAoSkNMYWJlbGVkU3RhdGVtZW50KWVudjEudHJlZTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGxhYmVsID09IGxhYmVsbGVkLmxhYmVsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBJZiBqdW1wIGlzIGEgY29udGludWUsIGNoZWNrIHRoYXQgdGFyZ2V0IGlzIGEgbG9vcC4KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0YWcgPT0gQ09OVElOVUUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWxhYmVsbGVkLmJvZHkuaGFzVGFnKERPTE9PUCkgJiYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICFsYWJlbGxlZC5ib2R5Lmhhc1RhZyhXSElMRUxPT1ApICYmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAhbGFiZWxsZWQuYm9keS5oYXNUYWcoRk9STE9PUCkgJiYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICFsYWJlbGxlZC5ib2R5Lmhhc1RhZyhGT1JFQUNITE9PUCkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZy5lcnJvcihwb3MsICJub3QubG9vcC5sYWJlbCIsIGxhYmVsKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBGb3VuZCBsYWJlbGxlZCBzdGF0ZW1lbnQgdGFyZ2V0LCBub3cgZ28gaW53YXJkcwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRvIG5leHQgbm9uLWxhYmVsbGVkIHRyZWUuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFRyZWVJbmZvLnJlZmVyZW5jZWRTdGF0ZW1lbnQobGFiZWxsZWQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbGFiZWxsZWQ7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBET0xPT1A6CiAgICAgICAgICAgICAgICAgICAgY2FzZSBXSElMRUxPT1A6CiAgICAgICAgICAgICAgICAgICAgY2FzZSBGT1JMT09QOgogICAgICAgICAgICAgICAgICAgIGNhc2UgRk9SRUFDSExPT1A6CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChsYWJlbCA9PSBudWxsKSByZXR1cm4gZW52MS50cmVlOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICBjYXNlIFNXSVRDSDoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGxhYmVsID09IG51bGwgJiYgdGFnID09IEJSRUFLKSByZXR1cm4gZW52MS50cmVlOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICBjYXNlIExBTUJEQToKICAgICAgICAgICAgICAgICAgICBjYXNlIE1FVEhPRERFRjoKICAgICAgICAgICAgICAgICAgICBjYXNlIENMQVNTREVGOgogICAgICAgICAgICAgICAgICAgICAgICBicmVhayBMT09QOwogICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbnYxID0gZW52MS5uZXh0OwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChsYWJlbCAhPSBudWxsKQogICAgICAgICAgICAgICAgbG9nLmVycm9yKHBvcywgInVuZGVmLmxhYmVsIiwgbGFiZWwpOwogICAgICAgICAgICBlbHNlIGlmICh0YWcgPT0gQ09OVElOVUUpCiAgICAgICAgICAgICAgICBsb2cuZXJyb3IocG9zLCAiY29udC5vdXRzaWRlLmxvb3AiKTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgbG9nLmVycm9yKHBvcywgImJyZWFrLm91dHNpZGUuc3dpdGNoLmxvb3AiKTsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0UmV0dXJuKEpDUmV0dXJuIHRyZWUpIHsKICAgICAgICAvLyBDaGVjayB0aGF0IHRoZXJlIGlzIGFuIGVuY2xvc2luZyBtZXRob2Qgd2hpY2ggaXMKICAgICAgICAvLyBuZXN0ZWQgd2l0aGluIHRoYW4gdGhlIGVuY2xvc2luZyBjbGFzcy4KICAgICAgICBpZiAoZW52LmluZm8ucmV0dXJuUmVzdWx0ID09IG51bGwpIHsKICAgICAgICAgICAgbG9nLmVycm9yKHRyZWUucG9zKCksICJyZXQub3V0c2lkZS5tZXRoIik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLy8gQXR0cmlidXRlIHJldHVybiBleHByZXNzaW9uLCBpZiBpdCBleGlzdHMsIGFuZCBjaGVjayB0aGF0CiAgICAgICAgICAgIC8vIGl0IGNvbmZvcm1zIHRvIHJlc3VsdCB0eXBlIG9mIGVuY2xvc2luZyBtZXRob2QuCiAgICAgICAgICAgIGlmICh0cmVlLmV4cHIgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgaWYgKGVudi5pbmZvLnJldHVyblJlc3VsdC5wdC5oYXNUYWcoVk9JRCkpIHsKICAgICAgICAgICAgICAgICAgICBlbnYuaW5mby5yZXR1cm5SZXN1bHQuY2hlY2tDb250ZXh0LnJlcG9ydCh0cmVlLmV4cHIucG9zKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpYWdzLmZyYWdtZW50KCJ1bmV4cGVjdGVkLnJldC52YWwiKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBhdHRyaWJUcmVlKHRyZWUuZXhwciwgZW52LCBlbnYuaW5mby5yZXR1cm5SZXN1bHQpOwogICAgICAgICAgICB9IGVsc2UgaWYgKCFlbnYuaW5mby5yZXR1cm5SZXN1bHQucHQuaGFzVGFnKFZPSUQpICYmCiAgICAgICAgICAgICAgICAgICAgIWVudi5pbmZvLnJldHVyblJlc3VsdC5wdC5oYXNUYWcoTk9ORSkpIHsKICAgICAgICAgICAgICAgIGVudi5pbmZvLnJldHVyblJlc3VsdC5jaGVja0NvbnRleHQucmVwb3J0KHRyZWUucG9zKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpYWdzLmZyYWdtZW50KCJtaXNzaW5nLnJldC52YWwiKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmVzdWx0ID0gbnVsbDsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdFRocm93KEpDVGhyb3cgdHJlZSkgewogICAgICAgIFR5cGUgb3dudHlwZSA9IGF0dHJpYkV4cHIodHJlZS5leHByLCBlbnYsIGFsbG93UG9seSA/IFR5cGUubm9UeXBlIDogc3ltcy50aHJvd2FibGVUeXBlKTsKICAgICAgICBpZiAoYWxsb3dQb2x5KSB7CiAgICAgICAgICAgIGNoay5jaGVja1R5cGUodHJlZSwgb3dudHlwZSwgc3ltcy50aHJvd2FibGVUeXBlKTsKICAgICAgICB9CiAgICAgICAgcmVzdWx0ID0gbnVsbDsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdEFzc2VydChKQ0Fzc2VydCB0cmVlKSB7CiAgICAgICAgYXR0cmliRXhwcih0cmVlLmNvbmQsIGVudiwgc3ltcy5ib29sZWFuVHlwZSk7CiAgICAgICAgaWYgKHRyZWUuZGV0YWlsICE9IG51bGwpIHsKICAgICAgICAgICAgY2hrLmNoZWNrTm9uVm9pZCh0cmVlLmRldGFpbC5wb3MoKSwgYXR0cmliRXhwcih0cmVlLmRldGFpbCwgZW52KSk7CiAgICAgICAgfQogICAgICAgIHJlc3VsdCA9IG51bGw7CiAgICB9CgogICAgIC8qKiBWaXNpdG9yIG1ldGhvZCBmb3IgbWV0aG9kIGludm9jYXRpb25zLgogICAgICogIE5PVEU6IFRoZSBtZXRob2QgcGFydCBvZiBhbiBhcHBsaWNhdGlvbiB3aWxsIGhhdmUgaW4gaXRzIHR5cGUgZmllbGQKICAgICAqICAgICAgICB0aGUgcmV0dXJuIHR5cGUgb2YgdGhlIG1ldGhvZCwgbm90IHRoZSBtZXRob2QncyB0eXBlIGl0c2VsZiEKICAgICAqLwogICAgcHVibGljIHZvaWQgdmlzaXRBcHBseShKQ01ldGhvZEludm9jYXRpb24gdHJlZSkgewogICAgICAgIC8vIFRoZSBsb2NhbCBlbnZpcm9ubWVudCBvZiBhIG1ldGhvZCBhcHBsaWNhdGlvbiBpcwogICAgICAgIC8vIGEgbmV3IGVudmlyb25tZW50IG5lc3RlZCBpbiB0aGUgY3VycmVudCBvbmUuCiAgICAgICAgRW52PEF0dHJDb250ZXh0PiBsb2NhbEVudiA9IGVudi5kdXAodHJlZSwgZW52LmluZm8uZHVwKCkpOwoKICAgICAgICAvLyBUaGUgdHlwZXMgb2YgdGhlIGFjdHVhbCBtZXRob2QgYXJndW1lbnRzLgogICAgICAgIExpc3Q8VHlwZT4gYXJndHlwZXM7CgogICAgICAgIC8vIFRoZSB0eXBlcyBvZiB0aGUgYWN0dWFsIG1ldGhvZCB0eXBlIGFyZ3VtZW50cy4KICAgICAgICBMaXN0PFR5cGU+IHR5cGVhcmd0eXBlcyA9IG51bGw7CgogICAgICAgIE5hbWUgbWV0aE5hbWUgPSBUcmVlSW5mby5uYW1lKHRyZWUubWV0aCk7CgogICAgICAgIGJvb2xlYW4gaXNDb25zdHJ1Y3RvckNhbGwgPQogICAgICAgICAgICBtZXRoTmFtZSA9PSBuYW1lcy5fdGhpcyB8fCBtZXRoTmFtZSA9PSBuYW1lcy5fc3VwZXI7CgogICAgICAgIExpc3RCdWZmZXI8VHlwZT4gYXJndHlwZXNCdWYgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgaWYgKGlzQ29uc3RydWN0b3JDYWxsKSB7CiAgICAgICAgICAgIC8vIFdlIGFyZSBzZWVpbmcgYSAuLi50aGlzKC4uLikgb3IgLi4uc3VwZXIoLi4uKSBjYWxsLgogICAgICAgICAgICAvLyBDaGVjayB0aGF0IHRoaXMgaXMgdGhlIGZpcnN0IHN0YXRlbWVudCBpbiBhIGNvbnN0cnVjdG9yLgogICAgICAgICAgICBpZiAoY2hlY2tGaXJzdENvbnN0cnVjdG9yU3RhdCh0cmVlLCBlbnYpKSB7CgogICAgICAgICAgICAgICAgLy8gUmVjb3JkIHRoZSBmYWN0CiAgICAgICAgICAgICAgICAvLyB0aGF0IHRoaXMgaXMgYSBjb25zdHJ1Y3RvciBjYWxsICh1c2luZyBpc1NlbGZDYWxsKS4KICAgICAgICAgICAgICAgIGxvY2FsRW52LmluZm8uaXNTZWxmQ2FsbCA9IHRydWU7CgogICAgICAgICAgICAgICAgLy8gQXR0cmlidXRlIGFyZ3VtZW50cywgeWllbGRpbmcgbGlzdCBvZiBhcmd1bWVudCB0eXBlcy4KICAgICAgICAgICAgICAgIEtpbmRTZWxlY3RvciBraW5kID0gYXR0cmliQXJncyhLaW5kU2VsZWN0b3IuTVRILCB0cmVlLmFyZ3MsIGxvY2FsRW52LCBhcmd0eXBlc0J1Zik7CiAgICAgICAgICAgICAgICBhcmd0eXBlcyA9IGFyZ3R5cGVzQnVmLnRvTGlzdCgpOwogICAgICAgICAgICAgICAgdHlwZWFyZ3R5cGVzID0gYXR0cmliVHlwZXModHJlZS50eXBlYXJncywgbG9jYWxFbnYpOwoKICAgICAgICAgICAgICAgIC8vIFZhcmlhYmxlIGBzaXRlJyBwb2ludHMgdG8gdGhlIGNsYXNzIGluIHdoaWNoIHRoZSBjYWxsZWQKICAgICAgICAgICAgICAgIC8vIGNvbnN0cnVjdG9yIGlzIGRlZmluZWQuCiAgICAgICAgICAgICAgICBUeXBlIHNpdGUgPSBlbnYuZW5jbENsYXNzLnN5bS50eXBlOwogICAgICAgICAgICAgICAgaWYgKG1ldGhOYW1lID09IG5hbWVzLl9zdXBlcikgewogICAgICAgICAgICAgICAgICAgIGlmIChzaXRlID09IHN5bXMub2JqZWN0VHlwZSkgewogICAgICAgICAgICAgICAgICAgICAgICBsb2cuZXJyb3IodHJlZS5tZXRoLnBvcygpLCAibm8uc3VwZXJjbGFzcyIsIHNpdGUpOwogICAgICAgICAgICAgICAgICAgICAgICBzaXRlID0gdHlwZXMuY3JlYXRlRXJyb3JUeXBlKHN5bXMub2JqZWN0VHlwZSk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgc2l0ZSA9IHR5cGVzLnN1cGVydHlwZShzaXRlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKHNpdGUuaGFzVGFnKENMQVNTKSkgewogICAgICAgICAgICAgICAgICAgIFR5cGUgZW5jbCA9IHNpdGUuZ2V0RW5jbG9zaW5nVHlwZSgpOwogICAgICAgICAgICAgICAgICAgIHdoaWxlIChlbmNsICE9IG51bGwgJiYgZW5jbC5oYXNUYWcoVFlQRVZBUikpCiAgICAgICAgICAgICAgICAgICAgICAgIGVuY2wgPSBlbmNsLmdldFVwcGVyQm91bmQoKTsKICAgICAgICAgICAgICAgICAgICBpZiAoZW5jbC5oYXNUYWcoQ0xBU1MpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHdlIGFyZSBjYWxsaW5nIGEgbmVzdGVkIGNsYXNzCgogICAgICAgICAgICAgICAgICAgICAgICBpZiAodHJlZS5tZXRoLmhhc1RhZyhTRUxFQ1QpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBKQ1RyZWUgcXVhbGlmaWVyID0gKChKQ0ZpZWxkQWNjZXNzKSB0cmVlLm1ldGgpLnNlbGVjdGVkOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdlIGFyZSBzZWVpbmcgYSBwcmVmaXhlZCBjYWxsLCBvZiB0aGUgZm9ybQogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gICAgIDxleHByPi5zdXBlciguLi4pLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ2hlY2sgdGhhdCB0aGUgcHJlZml4IGV4cHJlc3Npb24gY29uZm9ybXMKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRvIHRoZSBvdXRlciBpbnN0YW5jZSB0eXBlIG9mIHRoZSBjbGFzcy4KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoay5jaGVja1JlZlR5cGUocXVhbGlmaWVyLnBvcygpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRyaWJFeHByKHF1YWxpZmllciwgbG9jYWxFbnYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5jbCkpOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKG1ldGhOYW1lID09IG5hbWVzLl9zdXBlcikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gcXVhbGlmaWVyIG9taXR0ZWQ7IGNoZWNrIGZvciBleGlzdGVuY2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG9mIGFuIGFwcHJvcHJpYXRlIGltcGxpY2l0IHF1YWxpZmllci4KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJzLnJlc29sdmVJbXBsaWNpdFRoaXModHJlZS5tZXRoLnBvcygpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2NhbEVudiwgc2l0ZSwgdHJ1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHRyZWUubWV0aC5oYXNUYWcoU0VMRUNUKSkgewogICAgICAgICAgICAgICAgICAgICAgICBsb2cuZXJyb3IodHJlZS5tZXRoLnBvcygpLCAiaWxsZWdhbC5xdWFsLm5vdC5pY2xzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpdGUudHN5bSk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAvLyBpZiB3ZSdyZSBjYWxsaW5nIGEgamF2YS5sYW5nLkVudW0gY29uc3RydWN0b3IsCiAgICAgICAgICAgICAgICAgICAgLy8gcHJlZml4IHRoZSBpbXBsaWNpdCBTdHJpbmcgYW5kIGludCBwYXJhbWV0ZXJzCiAgICAgICAgICAgICAgICAgICAgaWYgKHNpdGUudHN5bSA9PSBzeW1zLmVudW1TeW0pCiAgICAgICAgICAgICAgICAgICAgICAgIGFyZ3R5cGVzID0gYXJndHlwZXMucHJlcGVuZChzeW1zLmludFR5cGUpLnByZXBlbmQoc3ltcy5zdHJpbmdUeXBlKTsKCiAgICAgICAgICAgICAgICAgICAgLy8gUmVzb2x2ZSB0aGUgY2FsbGVkIGNvbnN0cnVjdG9yIHVuZGVyIHRoZSBhc3N1bXB0aW9uCiAgICAgICAgICAgICAgICAgICAgLy8gdGhhdCB3ZSBhcmUgcmVmZXJyaW5nIHRvIGEgc3VwZXJjbGFzcyBpbnN0YW5jZSBvZiB0aGUKICAgICAgICAgICAgICAgICAgICAvLyBjdXJyZW50IGluc3RhbmNlIChKTFMgPz8/KS4KICAgICAgICAgICAgICAgICAgICBib29sZWFuIHNlbGVjdFN1cGVyUHJldiA9IGxvY2FsRW52LmluZm8uc2VsZWN0U3VwZXI7CiAgICAgICAgICAgICAgICAgICAgbG9jYWxFbnYuaW5mby5zZWxlY3RTdXBlciA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgbG9jYWxFbnYuaW5mby5wZW5kaW5nUmVzb2x1dGlvblBoYXNlID0gbnVsbDsKICAgICAgICAgICAgICAgICAgICBTeW1ib2wgc3ltID0gcnMucmVzb2x2ZUNvbnN0cnVjdG9yKAogICAgICAgICAgICAgICAgICAgICAgICB0cmVlLm1ldGgucG9zKCksIGxvY2FsRW52LCBzaXRlLCBhcmd0eXBlcywgdHlwZWFyZ3R5cGVzKTsKICAgICAgICAgICAgICAgICAgICBsb2NhbEVudi5pbmZvLnNlbGVjdFN1cGVyID0gc2VsZWN0U3VwZXJQcmV2OwoKICAgICAgICAgICAgICAgICAgICAvLyBTZXQgbWV0aG9kIHN5bWJvbCB0byByZXNvbHZlZCBjb25zdHJ1Y3Rvci4uLgogICAgICAgICAgICAgICAgICAgIFRyZWVJbmZvLnNldFN5bWJvbCh0cmVlLm1ldGgsIHN5bSk7CgogICAgICAgICAgICAgICAgICAgIC8vIC4uLmFuZCBjaGVjayB0aGF0IGl0IGlzIGxlZ2FsIGluIHRoZSBjdXJyZW50IGNvbnRleHQuCiAgICAgICAgICAgICAgICAgICAgLy8gKHRoaXMgd2lsbCBhbHNvIHNldCB0aGUgdHJlZSdzIHR5cGUpCiAgICAgICAgICAgICAgICAgICAgVHlwZSBtcHQgPSBuZXdNZXRob2RUZW1wbGF0ZShyZXN1bHRJbmZvLnB0LCBhcmd0eXBlcywgdHlwZWFyZ3R5cGVzKTsKICAgICAgICAgICAgICAgICAgICBjaGVja0lkKHRyZWUubWV0aCwgc2l0ZSwgc3ltLCBsb2NhbEVudiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBSZXN1bHRJbmZvKGtpbmQsIG1wdCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgLy8gT3RoZXJ3aXNlLCBgc2l0ZScgaXMgYW4gZXJyb3IgdHlwZSBhbmQgd2UgZG8gbm90aGluZwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJlc3VsdCA9IHRyZWUudHlwZSA9IHN5bXMudm9pZFR5cGU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLy8gT3RoZXJ3aXNlLCB3ZSBhcmUgc2VlaW5nIGEgcmVndWxhciBtZXRob2QgY2FsbC4KICAgICAgICAgICAgLy8gQXR0cmlidXRlIHRoZSBhcmd1bWVudHMsIHlpZWxkaW5nIGxpc3Qgb2YgYXJndW1lbnQgdHlwZXMsIC4uLgogICAgICAgICAgICBLaW5kU2VsZWN0b3Iga2luZCA9IGF0dHJpYkFyZ3MoS2luZFNlbGVjdG9yLlZBTCwgdHJlZS5hcmdzLCBsb2NhbEVudiwgYXJndHlwZXNCdWYpOwogICAgICAgICAgICBhcmd0eXBlcyA9IGFyZ3R5cGVzQnVmLnRvTGlzdCgpOwogICAgICAgICAgICB0eXBlYXJndHlwZXMgPSBhdHRyaWJBbnlUeXBlcyh0cmVlLnR5cGVhcmdzLCBsb2NhbEVudik7CgogICAgICAgICAgICAvLyAuLi4gYW5kIGF0dHJpYnV0ZSB0aGUgbWV0aG9kIHVzaW5nIGFzIGEgcHJvdG90eXBlIGEgbWV0aG9kdHlwZQogICAgICAgICAgICAvLyB3aG9zZSBmb3JtYWwgYXJndW1lbnQgdHlwZXMgaXMgZXhhY3RseSB0aGUgbGlzdCBvZiBhY3R1YWwKICAgICAgICAgICAgLy8gYXJndW1lbnRzICh0aGlzIHdpbGwgYWxzbyBzZXQgdGhlIG1ldGhvZCBzeW1ib2wpLgogICAgICAgICAgICBUeXBlIG1wdCA9IG5ld01ldGhvZFRlbXBsYXRlKHJlc3VsdEluZm8ucHQsIGFyZ3R5cGVzLCB0eXBlYXJndHlwZXMpOwogICAgICAgICAgICBsb2NhbEVudi5pbmZvLnBlbmRpbmdSZXNvbHV0aW9uUGhhc2UgPSBudWxsOwogICAgICAgICAgICBUeXBlIG10eXBlID0gYXR0cmliVHJlZSh0cmVlLm1ldGgsIGxvY2FsRW52LCBuZXcgUmVzdWx0SW5mbyhraW5kLCBtcHQsIHJlc3VsdEluZm8uY2hlY2tDb250ZXh0KSk7CgogICAgICAgICAgICAvLyBDb21wdXRlIHRoZSByZXN1bHQgdHlwZS4KICAgICAgICAgICAgVHlwZSByZXN0eXBlID0gbXR5cGUuZ2V0UmV0dXJuVHlwZSgpOwogICAgICAgICAgICBpZiAocmVzdHlwZS5oYXNUYWcoV0lMRENBUkQpKQogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKG10eXBlKTsKCiAgICAgICAgICAgIFR5cGUgcXVhbGlmaWVyID0gKHRyZWUubWV0aC5oYXNUYWcoU0VMRUNUKSkKICAgICAgICAgICAgICAgICAgICA/ICgoSkNGaWVsZEFjY2VzcykgdHJlZS5tZXRoKS5zZWxlY3RlZC50eXBlCiAgICAgICAgICAgICAgICAgICAgOiBlbnYuZW5jbENsYXNzLnN5bS50eXBlOwogICAgICAgICAgICBTeW1ib2wgbXN5bSA9IFRyZWVJbmZvLnN5bWJvbCh0cmVlLm1ldGgpOwogICAgICAgICAgICByZXN0eXBlID0gYWRqdXN0TWV0aG9kUmV0dXJuVHlwZShtc3ltLCBxdWFsaWZpZXIsIG1ldGhOYW1lLCBhcmd0eXBlcywgcmVzdHlwZSk7CgogICAgICAgICAgICBjaGsuY2hlY2tSZWZUeXBlcyh0cmVlLnR5cGVhcmdzLCB0eXBlYXJndHlwZXMpOwoKICAgICAgICAgICAgLy8gQ2hlY2sgdGhhdCB2YWx1ZSBvZiByZXN1bHRpbmcgdHlwZSBpcyBhZG1pc3NpYmxlIGluIHRoZQogICAgICAgICAgICAvLyBjdXJyZW50IGNvbnRleHQuICBBbHNvLCBjYXB0dXJlIHRoZSByZXR1cm4gdHlwZQogICAgICAgICAgICBUeXBlIGNhcHR1cmVkUmVzID0gcmVzdWx0SW5mby5jaGVja0NvbnRleHQuaW5mZXJlbmNlQ29udGV4dCgpLmNhY2hlZENhcHR1cmUodHJlZSwgcmVzdHlwZSwgdHJ1ZSk7CiAgICAgICAgICAgIHJlc3VsdCA9IGNoZWNrKHRyZWUsIGNhcHR1cmVkUmVzLCBLaW5kU2VsZWN0b3IuVkFMLCByZXN1bHRJbmZvKTsKICAgICAgICB9CiAgICAgICAgY2hrLnZhbGlkYXRlKHRyZWUudHlwZWFyZ3MsIGxvY2FsRW52KTsKICAgIH0KICAgIC8vd2hlcmUKICAgICAgICBUeXBlIGFkanVzdE1ldGhvZFJldHVyblR5cGUoU3ltYm9sIG1zeW0sIFR5cGUgcXVhbGlmaWVyVHlwZSwgTmFtZSBtZXRob2ROYW1lLCBMaXN0PFR5cGU+IGFyZ3R5cGVzLCBUeXBlIHJlc3R5cGUpIHsKICAgICAgICAgICAgaWYgKG1zeW0gIT0gbnVsbCAmJgogICAgICAgICAgICAgICAgICAgIG1zeW0ub3duZXIgPT0gc3ltcy5vYmplY3RUeXBlLnRzeW0gJiYKICAgICAgICAgICAgICAgICAgICBtZXRob2ROYW1lID09IG5hbWVzLmdldENsYXNzICYmCiAgICAgICAgICAgICAgICAgICAgYXJndHlwZXMuaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgICAvLyBhcyBhIHNwZWNpYWwgY2FzZSwgeC5nZXRDbGFzcygpIGhhcyB0eXBlIENsYXNzPD8gZXh0ZW5kcyB8WHw+CiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IENsYXNzVHlwZShyZXN0eXBlLmdldEVuY2xvc2luZ1R5cGUoKSwKICAgICAgICAgICAgICAgICAgICAgICAgTGlzdC5vZihuZXcgV2lsZGNhcmRUeXBlKHR5cGVzLmVyYXN1cmUocXVhbGlmaWVyVHlwZSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQm91bmRLaW5kLkVYVEVORFMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ltcy5ib3VuZENsYXNzKSksCiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3R5cGUudHN5bSwKICAgICAgICAgICAgICAgICAgICAgICAgcmVzdHlwZS5nZXRNZXRhZGF0YSgpKTsKICAgICAgICAgICAgfSBlbHNlIGlmIChtc3ltICE9IG51bGwgJiYKICAgICAgICAgICAgICAgICAgICBtc3ltLm93bmVyID09IHN5bXMuYXJyYXlDbGFzcyAmJgogICAgICAgICAgICAgICAgICAgIG1ldGhvZE5hbWUgPT0gbmFtZXMuY2xvbmUgJiYKICAgICAgICAgICAgICAgICAgICB0eXBlcy5pc0FycmF5KHF1YWxpZmllclR5cGUpKSB7CiAgICAgICAgICAgICAgICAvLyBhcyBhIHNwZWNpYWwgY2FzZSwgYXJyYXkuY2xvbmUoKSBoYXMgYSByZXN1bHQgdGhhdCBpcwogICAgICAgICAgICAgICAgLy8gdGhlIHNhbWUgYXMgc3RhdGljIHR5cGUgb2YgdGhlIGFycmF5IGJlaW5nIGNsb25lZAogICAgICAgICAgICAgICAgcmV0dXJuIHF1YWxpZmllclR5cGU7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdHlwZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLyoqIENoZWNrIHRoYXQgZ2l2ZW4gYXBwbGljYXRpb24gbm9kZSBhcHBlYXJzIGFzIGZpcnN0IHN0YXRlbWVudAogICAgICAgICAqICBpbiBhIGNvbnN0cnVjdG9yIGNhbGwuCiAgICAgICAgICogIEBwYXJhbSB0cmVlICAgVGhlIGFwcGxpY2F0aW9uIG5vZGUKICAgICAgICAgKiAgQHBhcmFtIGVudiAgICBUaGUgZW52aXJvbm1lbnQgY3VycmVudCBhdCB0aGUgYXBwbGljYXRpb24uCiAgICAgICAgICovCiAgICAgICAgYm9vbGVhbiBjaGVja0ZpcnN0Q29uc3RydWN0b3JTdGF0KEpDTWV0aG9kSW52b2NhdGlvbiB0cmVlLCBFbnY8QXR0ckNvbnRleHQ+IGVudikgewogICAgICAgICAgICBKQ01ldGhvZERlY2wgZW5jbE1ldGhvZCA9IGVudi5lbmNsTWV0aG9kOwogICAgICAgICAgICBpZiAoZW5jbE1ldGhvZCAhPSBudWxsICYmIGVuY2xNZXRob2QubmFtZSA9PSBuYW1lcy5pbml0KSB7CiAgICAgICAgICAgICAgICBKQ0Jsb2NrIGJvZHkgPSBlbmNsTWV0aG9kLmJvZHk7CiAgICAgICAgICAgICAgICBpZiAoYm9keS5zdGF0cy5oZWFkLmhhc1RhZyhFWEVDKSAmJgogICAgICAgICAgICAgICAgICAgICgoSkNFeHByZXNzaW9uU3RhdGVtZW50KSBib2R5LnN0YXRzLmhlYWQpLmV4cHIgPT0gdHJlZSkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBsb2cuZXJyb3IodHJlZS5wb3MoKSwiY2FsbC5tdXN0LmJlLmZpcnN0LnN0bXQuaW4uY3RvciIsCiAgICAgICAgICAgICAgICAgICAgICBUcmVlSW5mby5uYW1lKHRyZWUubWV0aCkpOwogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICAvKiogT2J0YWluIGEgbWV0aG9kIHR5cGUgd2l0aCBnaXZlbiBhcmd1bWVudCB0eXBlcy4KICAgICAgICAgKi8KICAgICAgICBUeXBlIG5ld01ldGhvZFRlbXBsYXRlKFR5cGUgcmVzdHlwZSwgTGlzdDxUeXBlPiBhcmd0eXBlcywgTGlzdDxUeXBlPiB0eXBlYXJndHlwZXMpIHsKICAgICAgICAgICAgTWV0aG9kVHlwZSBtdCA9IG5ldyBNZXRob2RUeXBlKGFyZ3R5cGVzLCByZXN0eXBlLCBMaXN0Lm5pbCgpLCBzeW1zLm1ldGhvZENsYXNzKTsKICAgICAgICAgICAgcmV0dXJuICh0eXBlYXJndHlwZXMgPT0gbnVsbCkgPyBtdCA6IChUeXBlKW5ldyBGb3JBbGwodHlwZWFyZ3R5cGVzLCBtdCk7CiAgICAgICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0TmV3Q2xhc3MoZmluYWwgSkNOZXdDbGFzcyB0cmVlKSB7CiAgICAgICAgVHlwZSBvd250eXBlID0gdHlwZXMuY3JlYXRlRXJyb3JUeXBlKHRyZWUudHlwZSk7CgogICAgICAgIC8vIFRoZSBsb2NhbCBlbnZpcm9ubWVudCBvZiBhIGNsYXNzIGNyZWF0aW9uIGlzCiAgICAgICAgLy8gYSBuZXcgZW52aXJvbm1lbnQgbmVzdGVkIGluIHRoZSBjdXJyZW50IG9uZS4KICAgICAgICBFbnY8QXR0ckNvbnRleHQ+IGxvY2FsRW52ID0gZW52LmR1cCh0cmVlLCBlbnYuaW5mby5kdXAoKSk7CgogICAgICAgIC8vIFRoZSBhbm9ueW1vdXMgaW5uZXIgY2xhc3MgZGVmaW5pdGlvbiBvZiB0aGUgbmV3IGV4cHJlc3Npb24sCiAgICAgICAgLy8gaWYgb25lIGlzIGRlZmluZWQgYnkgaXQuCiAgICAgICAgSkNDbGFzc0RlY2wgY2RlZiA9IHRyZWUuZGVmOwoKICAgICAgICAvLyBJZiBlbmNsb3NpbmcgY2xhc3MgaXMgZ2l2ZW4sIGF0dHJpYnV0ZSBpdCwgYW5kCiAgICAgICAgLy8gY29tcGxldGUgY2xhc3MgbmFtZSB0byBiZSBmdWxseSBxdWFsaWZpZWQKICAgICAgICBKQ0V4cHJlc3Npb24gY2xhenogPSB0cmVlLmNsYXp6OyAvLyBDbGFzcyBmaWVsZCBmb2xsb3dpbmcgbmV3CiAgICAgICAgSkNFeHByZXNzaW9uIGNsYXp6aWQ7ICAgICAgICAgICAgLy8gSWRlbnRpZmllciBpbiBjbGFzcyBmaWVsZAogICAgICAgIEpDQW5ub3RhdGVkVHlwZSBhbm5vY2xhenppZDsgICAgIC8vIEFubm90YXRlZCB0eXBlIGVuY2xvc2luZyBjbGF6emlkCiAgICAgICAgYW5ub2NsYXp6aWQgPSBudWxsOwoKICAgICAgICBpZiAoY2xhenouaGFzVGFnKFRZUEVBUFBMWSkpIHsKICAgICAgICAgICAgY2xhenppZCA9ICgoSkNUeXBlQXBwbHkpIGNsYXp6KS5jbGF6ejsKICAgICAgICAgICAgaWYgKGNsYXp6aWQuaGFzVGFnKEFOTk9UQVRFRF9UWVBFKSkgewogICAgICAgICAgICAgICAgYW5ub2NsYXp6aWQgPSAoSkNBbm5vdGF0ZWRUeXBlKSBjbGF6emlkOwogICAgICAgICAgICAgICAgY2xhenppZCA9IGFubm9jbGF6emlkLnVuZGVybHlpbmdUeXBlOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgaWYgKGNsYXp6Lmhhc1RhZyhBTk5PVEFURURfVFlQRSkpIHsKICAgICAgICAgICAgICAgIGFubm9jbGF6emlkID0gKEpDQW5ub3RhdGVkVHlwZSkgY2xheno7CiAgICAgICAgICAgICAgICBjbGF6emlkID0gYW5ub2NsYXp6aWQudW5kZXJseWluZ1R5cGU7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBjbGF6emlkID0gY2xheno7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEpDRXhwcmVzc2lvbiBjbGF6emlkMSA9IGNsYXp6aWQ7IC8vIFRoZSBzYW1lIGluIGZ1bGx5IHF1YWxpZmllZCBmb3JtCgogICAgICAgIGlmICh0cmVlLmVuY2wgIT0gbnVsbCkgewogICAgICAgICAgICAvLyBXZSBhcmUgc2VlaW5nIGEgcXVhbGlmaWVkIG5ldywgb2YgdGhlIGZvcm0KICAgICAgICAgICAgLy8gICAgPGV4cHI+Lm5ldyBDIDwuLi4+ICguLi4pIC4uLgogICAgICAgICAgICAvLyBJbiB0aGlzIGNhc2UsIHdlIGxldCBjbGF6eiBzdGFuZCBmb3IgdGhlIG5hbWUgb2YgdGhlCiAgICAgICAgICAgIC8vIGFsbG9jYXRlZCBjbGFzcyBDIHByZWZpeGVkIHdpdGggdGhlIHR5cGUgb2YgdGhlIHF1YWxpZmllcgogICAgICAgICAgICAvLyBleHByZXNzaW9uLCBzbyB0aGF0IHdlIGNhbgogICAgICAgICAgICAvLyByZXNvbHZlIGl0IHdpdGggc3RhbmRhcmQgdGVjaG5pcXVlcyBsYXRlci4gSS5lLiwgaWYKICAgICAgICAgICAgLy8gPGV4cHI+IGhhcyB0eXBlIFQsIHRoZW4gPGV4cHI+Lm5ldyBDIDwuLi4+ICguLi4pCiAgICAgICAgICAgIC8vIHlpZWxkcyBhIGNsYXp6IFQuQy4KICAgICAgICAgICAgVHlwZSBlbmNsdHlwZSA9IGNoay5jaGVja1JlZlR5cGUodHJlZS5lbmNsLnBvcygpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRyaWJFeHByKHRyZWUuZW5jbCwgZW52KSk7CiAgICAgICAgICAgIC8vIFRPRE8gMzA4OiBpbiA8ZXhwcj4ubmV3IEMsIGRvIHdlIGFsc28gd2FudCB0byBhZGQgdGhlIHR5cGUgYW5ub3RhdGlvbnMKICAgICAgICAgICAgLy8gZnJvbSBleHByIHRvIHRoZSBjb21iaW5lZCB0eXBlLCBvciBub3Q/IFllcywgZG8gdGhpcy4KICAgICAgICAgICAgY2xhenppZDEgPSBtYWtlLmF0KGNsYXp6LnBvcykuU2VsZWN0KG1ha2UuVHlwZShlbmNsdHlwZSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKEpDSWRlbnQpIGNsYXp6aWQpLm5hbWUpOwoKICAgICAgICAgICAgRW5kUG9zVGFibGUgZW5kUG9zVGFibGUgPSB0aGlzLmVudi50b3BsZXZlbC5lbmRQb3NpdGlvbnM7CiAgICAgICAgICAgIGVuZFBvc1RhYmxlLnN0b3JlRW5kKGNsYXp6aWQxLCB0cmVlLmdldEVuZFBvc2l0aW9uKGVuZFBvc1RhYmxlKSk7CiAgICAgICAgICAgIGlmIChjbGF6ei5oYXNUYWcoQU5OT1RBVEVEX1RZUEUpKSB7CiAgICAgICAgICAgICAgICBKQ0Fubm90YXRlZFR5cGUgYW5ub1R5cGUgPSAoSkNBbm5vdGF0ZWRUeXBlKSBjbGF6ejsKICAgICAgICAgICAgICAgIExpc3Q8SkNBbm5vdGF0aW9uPiBhbm5vcyA9IGFubm9UeXBlLmFubm90YXRpb25zOwoKICAgICAgICAgICAgICAgIGlmIChhbm5vVHlwZS51bmRlcmx5aW5nVHlwZS5oYXNUYWcoVFlQRUFQUExZKSkgewogICAgICAgICAgICAgICAgICAgIGNsYXp6aWQxID0gbWFrZS5hdCh0cmVlLnBvcykuCiAgICAgICAgICAgICAgICAgICAgICAgIFR5cGVBcHBseShjbGF6emlkMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoSkNUeXBlQXBwbHkpIGNsYXp6KS5hcmd1bWVudHMpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGNsYXp6aWQxID0gbWFrZS5hdCh0cmVlLnBvcykuCiAgICAgICAgICAgICAgICAgICAgQW5ub3RhdGVkVHlwZShhbm5vcywgY2xhenppZDEpOwogICAgICAgICAgICB9IGVsc2UgaWYgKGNsYXp6Lmhhc1RhZyhUWVBFQVBQTFkpKSB7CiAgICAgICAgICAgICAgICBjbGF6emlkMSA9IG1ha2UuYXQodHJlZS5wb3MpLgogICAgICAgICAgICAgICAgICAgIFR5cGVBcHBseShjbGF6emlkMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKChKQ1R5cGVBcHBseSkgY2xhenopLmFyZ3VtZW50cyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGNsYXp6ID0gY2xhenppZDE7CiAgICAgICAgfQoKICAgICAgICAvLyBBdHRyaWJ1dGUgY2xhenogZXhwcmVzc2lvbiBhbmQgc3RvcmUKICAgICAgICAvLyBzeW1ib2wgKyB0eXBlIGJhY2sgaW50byB0aGUgYXR0cmlidXRlZCB0cmVlLgogICAgICAgIFR5cGUgY2xhenp0eXBlOwoKICAgICAgICB0cnkgewogICAgICAgICAgICBlbnYuaW5mby5pc05ld0NsYXNzID0gdHJ1ZTsKICAgICAgICAgICAgY2xhenp0eXBlID0gVHJlZUluZm8uaXNFbnVtSW5pdChlbnYudHJlZSkgPwogICAgICAgICAgICAgICAgYXR0cmliSWRlbnRBc0VudW1UeXBlKGVudiwgKEpDSWRlbnQpY2xhenopIDoKICAgICAgICAgICAgICAgIGF0dHJpYlR5cGUoY2xhenosIGVudik7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgZW52LmluZm8uaXNOZXdDbGFzcyA9IGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgY2xhenp0eXBlID0gY2hrLmNoZWNrRGlhbW9uZCh0cmVlLCBjbGF6enR5cGUpOwogICAgICAgIGNoay52YWxpZGF0ZShjbGF6eiwgbG9jYWxFbnYpOwogICAgICAgIGlmICh0cmVlLmVuY2wgIT0gbnVsbCkgewogICAgICAgICAgICAvLyBXZSBoYXZlIHRvIHdvcmsgaW4gdGhpcyBjYXNlIHRvIHN0b3JlCiAgICAgICAgICAgIC8vIHN5bWJvbCArIHR5cGUgYmFjayBpbnRvIHRoZSBhdHRyaWJ1dGVkIHRyZWUuCiAgICAgICAgICAgIHRyZWUuY2xhenoudHlwZSA9IGNsYXp6dHlwZTsKICAgICAgICAgICAgVHJlZUluZm8uc2V0U3ltYm9sKGNsYXp6aWQsIFRyZWVJbmZvLnN5bWJvbChjbGF6emlkMSkpOwogICAgICAgICAgICBjbGF6emlkLnR5cGUgPSAoKEpDSWRlbnQpIGNsYXp6aWQpLnN5bS50eXBlOwogICAgICAgICAgICBpZiAoYW5ub2NsYXp6aWQgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgYW5ub2NsYXp6aWQudHlwZSA9IGNsYXp6aWQudHlwZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoIWNsYXp6dHlwZS5pc0Vycm9uZW91cygpKSB7CiAgICAgICAgICAgICAgICBpZiAoY2RlZiAhPSBudWxsICYmIGNsYXp6dHlwZS50c3ltLmlzSW50ZXJmYWNlKCkpIHsKICAgICAgICAgICAgICAgICAgICBsb2cuZXJyb3IodHJlZS5lbmNsLnBvcygpLCAiYW5vbi5jbGFzcy5pbXBsLmludGYubm8ucXVhbC5mb3IubmV3Iik7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGNsYXp6dHlwZS50c3ltLmlzU3RhdGljKCkpIHsKICAgICAgICAgICAgICAgICAgICBsb2cuZXJyb3IodHJlZS5lbmNsLnBvcygpLCAicXVhbGlmaWVkLm5ldy5vZi5zdGF0aWMuY2xhc3MiLCBjbGF6enR5cGUudHN5bSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgaWYgKCFjbGF6enR5cGUudHN5bS5pc0ludGVyZmFjZSgpICYmCiAgICAgICAgICAgICAgICAgICBjbGF6enR5cGUuZ2V0RW5jbG9zaW5nVHlwZSgpLmhhc1RhZyhDTEFTUykpIHsKICAgICAgICAgICAgLy8gQ2hlY2sgZm9yIHRoZSBleGlzdGVuY2Ugb2YgYW4gYXByb3BvcyBvdXRlciBpbnN0YW5jZQogICAgICAgICAgICBycy5yZXNvbHZlSW1wbGljaXRUaGlzKHRyZWUucG9zKCksIGVudiwgY2xhenp0eXBlKTsKICAgICAgICB9CgogICAgICAgIC8vIEF0dHJpYnV0ZSBjb25zdHJ1Y3RvciBhcmd1bWVudHMuCiAgICAgICAgTGlzdEJ1ZmZlcjxUeXBlPiBhcmd0eXBlc0J1ZiA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICBmaW5hbCBLaW5kU2VsZWN0b3IgcGtpbmQgPQogICAgICAgICAgICBhdHRyaWJBcmdzKEtpbmRTZWxlY3Rvci5WQUwsIHRyZWUuYXJncywgbG9jYWxFbnYsIGFyZ3R5cGVzQnVmKTsKICAgICAgICBMaXN0PFR5cGU+IGFyZ3R5cGVzID0gYXJndHlwZXNCdWYudG9MaXN0KCk7CiAgICAgICAgTGlzdDxUeXBlPiB0eXBlYXJndHlwZXMgPSBhdHRyaWJUeXBlcyh0cmVlLnR5cGVhcmdzLCBsb2NhbEVudik7CgogICAgICAgIC8vIElmIHdlIGhhdmUgbWFkZSBubyBtaXN0YWtlcyBpbiB0aGUgY2xhc3MgdHlwZS4uLgogICAgICAgIGlmIChjbGF6enR5cGUuaGFzVGFnKENMQVNTKSkgewogICAgICAgICAgICAvLyBFbnVtcyBtYXkgbm90IGJlIGluc3RhbnRpYXRlZCBleGNlcHQgaW1wbGljaXRseQogICAgICAgICAgICBpZiAoKGNsYXp6dHlwZS50c3ltLmZsYWdzX2ZpZWxkICYgRmxhZ3MuRU5VTSkgIT0gMCAmJgogICAgICAgICAgICAgICAgKCFlbnYudHJlZS5oYXNUYWcoVkFSREVGKSB8fAogICAgICAgICAgICAgICAgICgoKEpDVmFyaWFibGVEZWNsKSBlbnYudHJlZSkubW9kcy5mbGFncyAmIEZsYWdzLkVOVU0pID09IDAgfHwKICAgICAgICAgICAgICAgICAoKEpDVmFyaWFibGVEZWNsKSBlbnYudHJlZSkuaW5pdCAhPSB0cmVlKSkKICAgICAgICAgICAgICAgIGxvZy5lcnJvcih0cmVlLnBvcygpLCAiZW51bS5jYW50LmJlLmluc3RhbnRpYXRlZCIpOwoKICAgICAgICAgICAgYm9vbGVhbiBpc1NwZWN1bGF0aXZlRGlhbW9uZEluZmVyZW5jZVJvdW5kID0gVHJlZUluZm8uaXNEaWFtb25kKHRyZWUpICYmCiAgICAgICAgICAgICAgICAgICAgcmVzdWx0SW5mby5jaGVja0NvbnRleHQuZGVmZXJyZWRBdHRyQ29udGV4dCgpLm1vZGUgPT0gRGVmZXJyZWRBdHRyLkF0dHJNb2RlLlNQRUNVTEFUSVZFOwogICAgICAgICAgICBib29sZWFuIHNraXBOb25EaWFtb25kUGF0aCA9IGZhbHNlOwogICAgICAgICAgICAvLyBDaGVjayB0aGF0IGNsYXNzIGlzIG5vdCBhYnN0cmFjdAogICAgICAgICAgICBpZiAoY2RlZiA9PSBudWxsICYmICFpc1NwZWN1bGF0aXZlRGlhbW9uZEluZmVyZW5jZVJvdW5kICYmIC8vIGNsYXNzIGJvZHkgbWF5IGJlIG51bGxlZCBvdXQgaW4gc3BlY3VsYXRpdmUgdHJlZSBjb3B5CiAgICAgICAgICAgICAgICAoY2xhenp0eXBlLnRzeW0uZmxhZ3MoKSAmIChBQlNUUkFDVCB8IElOVEVSRkFDRSkpICE9IDApIHsKICAgICAgICAgICAgICAgIGxvZy5lcnJvcih0cmVlLnBvcygpLCAiYWJzdHJhY3QuY2FudC5iZS5pbnN0YW50aWF0ZWQiLAogICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXp6dHlwZS50c3ltKTsKICAgICAgICAgICAgICAgIHNraXBOb25EaWFtb25kUGF0aCA9IHRydWU7CiAgICAgICAgICAgIH0gZWxzZSBpZiAoY2RlZiAhPSBudWxsICYmIGNsYXp6dHlwZS50c3ltLmlzSW50ZXJmYWNlKCkpIHsKICAgICAgICAgICAgICAgIC8vIENoZWNrIHRoYXQgbm8gY29uc3RydWN0b3IgYXJndW1lbnRzIGFyZSBnaXZlbiB0bwogICAgICAgICAgICAgICAgLy8gYW5vbnltb3VzIGNsYXNzZXMgaW1wbGVtZW50aW5nIGFuIGludGVyZmFjZQogICAgICAgICAgICAgICAgaWYgKCFhcmd0eXBlcy5pc0VtcHR5KCkpCiAgICAgICAgICAgICAgICAgICAgbG9nLmVycm9yKHRyZWUuYXJncy5oZWFkLnBvcygpLCAiYW5vbi5jbGFzcy5pbXBsLmludGYubm8uYXJncyIpOwoKICAgICAgICAgICAgICAgIGlmICghdHlwZWFyZ3R5cGVzLmlzRW1wdHkoKSkKICAgICAgICAgICAgICAgICAgICBsb2cuZXJyb3IodHJlZS50eXBlYXJncy5oZWFkLnBvcygpLCAiYW5vbi5jbGFzcy5pbXBsLmludGYubm8udHlwZWFyZ3MiKTsKCiAgICAgICAgICAgICAgICAvLyBFcnJvciByZWNvdmVyeTogcHJldGVuZCBubyBhcmd1bWVudHMgd2VyZSBzdXBwbGllZC4KICAgICAgICAgICAgICAgIGFyZ3R5cGVzID0gTGlzdC5uaWwoKTsKICAgICAgICAgICAgICAgIHR5cGVhcmd0eXBlcyA9IExpc3QubmlsKCk7CiAgICAgICAgICAgICAgICBza2lwTm9uRGlhbW9uZFBhdGggPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChUcmVlSW5mby5pc0RpYW1vbmQodHJlZSkpIHsKICAgICAgICAgICAgICAgIENsYXNzVHlwZSBzaXRlID0gbmV3IENsYXNzVHlwZShjbGF6enR5cGUuZ2V0RW5jbG9zaW5nVHlwZSgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhenp0eXBlLnRzeW0udHlwZS5nZXRUeXBlQXJndW1lbnRzKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhenp0eXBlLnRzeW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhenp0eXBlLmdldE1ldGFkYXRhKCkpOwoKICAgICAgICAgICAgICAgIEVudjxBdHRyQ29udGV4dD4gZGlhbW9uZEVudiA9IGxvY2FsRW52LmR1cCh0cmVlKTsKICAgICAgICAgICAgICAgIGRpYW1vbmRFbnYuaW5mby5zZWxlY3RTdXBlciA9IGNkZWYgIT0gbnVsbDsKICAgICAgICAgICAgICAgIGRpYW1vbmRFbnYuaW5mby5wZW5kaW5nUmVzb2x1dGlvblBoYXNlID0gbnVsbDsKCiAgICAgICAgICAgICAgICAvL2lmIHRoZSB0eXBlIG9mIHRoZSBpbnN0YW5jZSBjcmVhdGlvbiBleHByZXNzaW9uIGlzIGEgY2xhc3MgdHlwZQogICAgICAgICAgICAgICAgLy9hcHBseSBtZXRob2QgcmVzb2x1dGlvbiBpbmZlcmVuY2UgKEpMUyAxNS4xMi4yLjcpLiBUaGUgcmV0dXJuIHR5cGUKICAgICAgICAgICAgICAgIC8vb2YgdGhlIHJlc29sdmVkIGNvbnN0cnVjdG9yIHdpbGwgYmUgYSBwYXJ0aWFsbHkgaW5zdGFudGlhdGVkIHR5cGUKICAgICAgICAgICAgICAgIFN5bWJvbCBjb25zdHJ1Y3RvciA9IHJzLnJlc29sdmVEaWFtb25kKHRyZWUucG9zKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaWFtb25kRW52LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyZ3R5cGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZWFyZ3R5cGVzKTsKICAgICAgICAgICAgICAgIHRyZWUuY29uc3RydWN0b3IgPSBjb25zdHJ1Y3Rvci5iYXNlU3ltYm9sKCk7CgogICAgICAgICAgICAgICAgZmluYWwgVHlwZVN5bWJvbCBjc3ltID0gY2xhenp0eXBlLnRzeW07CiAgICAgICAgICAgICAgICBSZXN1bHRJbmZvIGRpYW1vbmRSZXN1bHQgPSBuZXcgUmVzdWx0SW5mbyhwa2luZCwgbmV3TWV0aG9kVGVtcGxhdGUocmVzdWx0SW5mby5wdCwgYXJndHlwZXMsIHR5cGVhcmd0eXBlcyksCiAgICAgICAgICAgICAgICAgICAgICAgIGRpYW1vbmRDb250ZXh0KHRyZWUsIGNzeW0sIHJlc3VsdEluZm8uY2hlY2tDb250ZXh0KSwgQ2hlY2tNb2RlLk5PX1RSRUVfVVBEQVRFKTsKICAgICAgICAgICAgICAgIFR5cGUgY29uc3RydWN0b3JUeXBlID0gdHJlZS5jb25zdHJ1Y3RvclR5cGUgPSB0eXBlcy5jcmVhdGVFcnJvclR5cGUoY2xhenp0eXBlKTsKICAgICAgICAgICAgICAgIGNvbnN0cnVjdG9yVHlwZSA9IGNoZWNrSWQodHJlZSwgc2l0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgY29uc3RydWN0b3IsCiAgICAgICAgICAgICAgICAgICAgICAgIGRpYW1vbmRFbnYsCiAgICAgICAgICAgICAgICAgICAgICAgIGRpYW1vbmRSZXN1bHQpOwoKICAgICAgICAgICAgICAgIHRyZWUuY2xhenoudHlwZSA9IHR5cGVzLmNyZWF0ZUVycm9yVHlwZShjbGF6enR5cGUpOwogICAgICAgICAgICAgICAgaWYgKCFjb25zdHJ1Y3RvclR5cGUuaXNFcnJvbmVvdXMoKSkgewogICAgICAgICAgICAgICAgICAgIHRyZWUuY2xhenoudHlwZSA9IGNsYXp6LnR5cGUgPSBjb25zdHJ1Y3RvclR5cGUuZ2V0UmV0dXJuVHlwZSgpOwogICAgICAgICAgICAgICAgICAgIHRyZWUuY29uc3RydWN0b3JUeXBlID0gdHlwZXMuY3JlYXRlTWV0aG9kVHlwZVdpdGhSZXR1cm4oY29uc3RydWN0b3JUeXBlLCBzeW1zLnZvaWRUeXBlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGNsYXp6dHlwZSA9IGNoay5jaGVja0NsYXNzVHlwZSh0cmVlLmNsYXp6LCB0cmVlLmNsYXp6LnR5cGUsIHRydWUpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBSZXNvbHZlIHRoZSBjYWxsZWQgY29uc3RydWN0b3IgdW5kZXIgdGhlIGFzc3VtcHRpb24KICAgICAgICAgICAgLy8gdGhhdCB3ZSBhcmUgcmVmZXJyaW5nIHRvIGEgc3VwZXJjbGFzcyBpbnN0YW5jZSBvZiB0aGUKICAgICAgICAgICAgLy8gY3VycmVudCBpbnN0YW5jZSAoSkxTID8/PykuCiAgICAgICAgICAgIGVsc2UgaWYgKCFza2lwTm9uRGlhbW9uZFBhdGgpIHsKICAgICAgICAgICAgICAgIC8vdGhlIGZvbGxvd2luZyBjb2RlIGFsdGVycyBzb21lIG9mIHRoZSBmaWVsZHMgaW4gdGhlIGN1cnJlbnQKICAgICAgICAgICAgICAgIC8vQXR0ckNvbnRleHQgLSBoZW5jZSwgdGhlIGN1cnJlbnQgY29udGV4dCBtdXN0IGJlIGR1cCdlZCBpbgogICAgICAgICAgICAgICAgLy9vcmRlciB0byBhdm9pZCBkb3duc3RyZWFtIGZhaWx1cmVzCiAgICAgICAgICAgICAgICBFbnY8QXR0ckNvbnRleHQ+IHJzRW52ID0gbG9jYWxFbnYuZHVwKHRyZWUpOwogICAgICAgICAgICAgICAgcnNFbnYuaW5mby5zZWxlY3RTdXBlciA9IGNkZWYgIT0gbnVsbDsKICAgICAgICAgICAgICAgIHJzRW52LmluZm8ucGVuZGluZ1Jlc29sdXRpb25QaGFzZSA9IG51bGw7CiAgICAgICAgICAgICAgICB0cmVlLmNvbnN0cnVjdG9yID0gcnMucmVzb2x2ZUNvbnN0cnVjdG9yKAogICAgICAgICAgICAgICAgICAgIHRyZWUucG9zKCksIHJzRW52LCBjbGF6enR5cGUsIGFyZ3R5cGVzLCB0eXBlYXJndHlwZXMpOwogICAgICAgICAgICAgICAgaWYgKGNkZWYgPT0gbnVsbCkgeyAvL2RvIG5vdCBjaGVjayB0d2ljZSEKICAgICAgICAgICAgICAgICAgICB0cmVlLmNvbnN0cnVjdG9yVHlwZSA9IGNoZWNrSWQodHJlZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXp6dHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyZWUuY29uc3RydWN0b3IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICByc0VudiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBSZXN1bHRJbmZvKHBraW5kLCBuZXdNZXRob2RUZW1wbGF0ZShzeW1zLnZvaWRUeXBlLCBhcmd0eXBlcywgdHlwZWFyZ3R5cGVzKSwgQ2hlY2tNb2RlLk5PX1RSRUVfVVBEQVRFKSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKHJzRW52LmluZm8ubGFzdFJlc29sdmVWYXJhcmdzKCkpCiAgICAgICAgICAgICAgICAgICAgICAgIEFzc2VydC5jaGVjayh0cmVlLmNvbnN0cnVjdG9yVHlwZS5pc0Vycm9uZW91cygpIHx8IHRyZWUudmFyYXJnc0VsZW1lbnQgIT0gbnVsbCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChjZGVmICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIHZpc2l0QW5vbnltb3VzQ2xhc3NEZWZpbml0aW9uKHRyZWUsIGNsYXp6LCBjbGF6enR5cGUsIGNkZWYsIGxvY2FsRW52LCBhcmd0eXBlcywgdHlwZWFyZ3R5cGVzLCBwa2luZCk7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICh0cmVlLmNvbnN0cnVjdG9yICE9IG51bGwgJiYgdHJlZS5jb25zdHJ1Y3Rvci5raW5kID09IE1USCkKICAgICAgICAgICAgICAgIG93bnR5cGUgPSBjbGF6enR5cGU7CiAgICAgICAgfQogICAgICAgIHJlc3VsdCA9IGNoZWNrKHRyZWUsIG93bnR5cGUsIEtpbmRTZWxlY3Rvci5WQUwsIHJlc3VsdEluZm8pOwogICAgICAgIEluZmVyZW5jZUNvbnRleHQgaW5mZXJlbmNlQ29udGV4dCA9IHJlc3VsdEluZm8uY2hlY2tDb250ZXh0LmluZmVyZW5jZUNvbnRleHQoKTsKICAgICAgICBpZiAodHJlZS5jb25zdHJ1Y3RvclR5cGUgIT0gbnVsbCAmJiBpbmZlcmVuY2VDb250ZXh0LmZyZWUodHJlZS5jb25zdHJ1Y3RvclR5cGUpKSB7CiAgICAgICAgICAgIC8vd2UgbmVlZCB0byB3YWl0IGZvciBpbmZlcmVuY2UgdG8gZmluaXNoIGFuZCB0aGVuIHJlcGxhY2UgaW5mZXJlbmNlIHZhcnMgaW4gdGhlIGNvbnN0cnVjdG9yIHR5cGUKICAgICAgICAgICAgaW5mZXJlbmNlQ29udGV4dC5hZGRGcmVlVHlwZUxpc3RlbmVyKExpc3Qub2YodHJlZS5jb25zdHJ1Y3RvclR5cGUpLAogICAgICAgICAgICAgICAgICAgIGluc3RhbnRpYXRlZENvbnRleHQgLT4gewogICAgICAgICAgICAgICAgICAgICAgICB0cmVlLmNvbnN0cnVjdG9yVHlwZSA9IGluc3RhbnRpYXRlZENvbnRleHQuYXNJbnN0VHlwZSh0cmVlLmNvbnN0cnVjdG9yVHlwZSk7CiAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgfQogICAgICAgIGNoay52YWxpZGF0ZSh0cmVlLnR5cGVhcmdzLCBsb2NhbEVudik7CiAgICB9CgogICAgICAgIC8vIHdoZXJlCiAgICAgICAgcHJpdmF0ZSB2b2lkIHZpc2l0QW5vbnltb3VzQ2xhc3NEZWZpbml0aW9uKEpDTmV3Q2xhc3MgdHJlZSwgSkNFeHByZXNzaW9uIGNsYXp6LCBUeXBlIGNsYXp6dHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSkNDbGFzc0RlY2wgY2RlZiwgRW52PEF0dHJDb250ZXh0PiBsb2NhbEVudiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTGlzdDxUeXBlPiBhcmd0eXBlcywgTGlzdDxUeXBlPiB0eXBlYXJndHlwZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEtpbmRTZWxlY3RvciBwa2luZCkgewogICAgICAgICAgICAvLyBXZSBhcmUgc2VlaW5nIGFuIGFub255bW91cyBjbGFzcyBpbnN0YW5jZSBjcmVhdGlvbi4KICAgICAgICAgICAgLy8gSW4gdGhpcyBjYXNlLCB0aGUgY2xhc3MgaW5zdGFuY2UgY3JlYXRpb24KICAgICAgICAgICAgLy8gZXhwcmVzc2lvbgogICAgICAgICAgICAvLwogICAgICAgICAgICAvLyAgICBFLm5ldyA8dHlwZWFyZ3MxPkM8dHlwYXJnczI+KGFyZ3MpIHsgLi4uIH0KICAgICAgICAgICAgLy8KICAgICAgICAgICAgLy8gaXMgcmVwcmVzZW50ZWQgaW50ZXJuYWxseSBhcwogICAgICAgICAgICAvLwogICAgICAgICAgICAvLyAgICBFIC4gbmV3IDx0eXBlYXJnczE+Qzx0eXBhcmdzMj4oYXJncykgKCBjbGFzcyA8ZW1wdHktbmFtZT4geyAuLi4gfSApICAuCiAgICAgICAgICAgIC8vCiAgICAgICAgICAgIC8vIFRoaXMgZXhwcmVzc2lvbiBpcyB0aGVuICp0cmFuc2Zvcm1lZCogYXMgZm9sbG93czoKICAgICAgICAgICAgLy8KICAgICAgICAgICAgLy8gKDEpIGFkZCBhbiBleHRlbmRzIG9yIGltcGxlbWVudHMgY2xhdXNlCiAgICAgICAgICAgIC8vICgyKSBhZGQgYSBjb25zdHJ1Y3Rvci4KICAgICAgICAgICAgLy8KICAgICAgICAgICAgLy8gRm9yIGluc3RhbmNlLCBpZiBDIGlzIGEgY2xhc3MsIGFuZCBFVCBpcyB0aGUgdHlwZSBvZiBFLAogICAgICAgICAgICAvLyB0aGUgZXhwcmVzc2lvbgogICAgICAgICAgICAvLwogICAgICAgICAgICAvLyAgICBFLm5ldyA8dHlwZWFyZ3MxPkM8dHlwYXJnczI+KGFyZ3MpIHsgLi4uIH0KICAgICAgICAgICAgLy8KICAgICAgICAgICAgLy8gaXMgdHJhbnNsYXRlZCB0byAod2hlcmUgWCBpcyBhIGZyZXNoIG5hbWUgYW5kIHR5cGFyYW1zIGlzIHRoZQogICAgICAgICAgICAvLyBwYXJhbWV0ZXIgbGlzdCBvZiB0aGUgc3VwZXIgY29uc3RydWN0b3IpOgogICAgICAgICAgICAvLwogICAgICAgICAgICAvLyAgIG5ldyA8dHlwZWFyZ3MxPlgoPCpudWxsY2hrKj5FLCBhcmdzKSB3aGVyZQogICAgICAgICAgICAvLyAgICAgWCBleHRlbmRzIEM8dHlwYXJnczI+IHsKICAgICAgICAgICAgLy8gICAgICAgPHR5cGFyYW1zPiBYKEVUIGUsIGFyZ3MpIHsKICAgICAgICAgICAgLy8gICAgICAgICBlLjx0eXBlYXJnczE+c3VwZXIoYXJncykKICAgICAgICAgICAgLy8gICAgICAgfQogICAgICAgICAgICAvLyAgICAgICAuLi4KICAgICAgICAgICAgLy8gICAgIH0KICAgICAgICAgICAgSW5mZXJlbmNlQ29udGV4dCBpbmZlcmVuY2VDb250ZXh0ID0gcmVzdWx0SW5mby5jaGVja0NvbnRleHQuaW5mZXJlbmNlQ29udGV4dCgpOwogICAgICAgICAgICBmaW5hbCBib29sZWFuIGlzRGlhbW9uZCA9IFRyZWVJbmZvLmlzRGlhbW9uZCh0cmVlKTsKICAgICAgICAgICAgaWYgKGlzRGlhbW9uZAogICAgICAgICAgICAgICAgICAgICYmICgodHJlZS5jb25zdHJ1Y3RvclR5cGUgIT0gbnVsbCAmJiBpbmZlcmVuY2VDb250ZXh0LmZyZWUodHJlZS5jb25zdHJ1Y3RvclR5cGUpKQogICAgICAgICAgICAgICAgICAgIHx8ICh0cmVlLmNsYXp6LnR5cGUgIT0gbnVsbCAmJiBpbmZlcmVuY2VDb250ZXh0LmZyZWUodHJlZS5jbGF6ei50eXBlKSkpKSB7CiAgICAgICAgICAgICAgICBmaW5hbCBSZXN1bHRJbmZvIHJlc3VsdEluZm9Gb3JDbGFzc0RlZmluaXRpb24gPSB0aGlzLnJlc3VsdEluZm87CiAgICAgICAgICAgICAgICBpbmZlcmVuY2VDb250ZXh0LmFkZEZyZWVUeXBlTGlzdGVuZXIoTGlzdC5vZih0cmVlLmNvbnN0cnVjdG9yVHlwZSwgdHJlZS5jbGF6ei50eXBlKSwKICAgICAgICAgICAgICAgICAgICAgICAgaW5zdGFudGlhdGVkQ29udGV4dCAtPiB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmVlLmNvbnN0cnVjdG9yVHlwZSA9IGluc3RhbnRpYXRlZENvbnRleHQuYXNJbnN0VHlwZSh0cmVlLmNvbnN0cnVjdG9yVHlwZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmVlLmNsYXp6LnR5cGUgPSBjbGF6ei50eXBlID0gaW5zdGFudGlhdGVkQ29udGV4dC5hc0luc3RUeXBlKGNsYXp6LnR5cGUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVzdWx0SW5mbyBwcmV2UmVzdWx0ID0gdGhpcy5yZXN1bHRJbmZvOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlc3VsdEluZm8gPSByZXN1bHRJbmZvRm9yQ2xhc3NEZWZpbml0aW9uOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpc2l0QW5vbnltb3VzQ2xhc3NEZWZpbml0aW9uKHRyZWUsIGNsYXp6LCBjbGF6ei50eXBlLCBjZGVmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2NhbEVudiwgYXJndHlwZXMsIHR5cGVhcmd0eXBlcywgcGtpbmQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlc3VsdEluZm8gPSBwcmV2UmVzdWx0OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGlmIChpc0RpYW1vbmQgJiYgY2xhenp0eXBlLmhhc1RhZyhDTEFTUykpIHsKICAgICAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IGludmFsaWREaWFtb25kQXJncyA9IGNoay5jaGVja0RpYW1vbmREZW5vdGFibGUoKENsYXNzVHlwZSljbGF6enR5cGUpOwogICAgICAgICAgICAgICAgICAgIGlmICghY2xhenp0eXBlLmlzRXJyb25lb3VzKCkgJiYgaW52YWxpZERpYW1vbmRBcmdzLm5vbkVtcHR5KCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gT25lIG9yIG1vcmUgdHlwZXMgaW5mZXJyZWQgaW4gdGhlIHByZXZpb3VzIHN0ZXBzIGlzIG5vbi1kZW5vdGFibGUuCiAgICAgICAgICAgICAgICAgICAgICAgIEZyYWdtZW50IGZyYWdtZW50ID0gRGlhbW9uZChjbGF6enR5cGUudHN5bSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGxvZy5lcnJvcih0cmVlLmNsYXp6LnBvcygpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVycm9ycy5DYW50QXBwbHlEaWFtb25kMSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZyYWdtZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW52YWxpZERpYW1vbmRBcmdzLnNpemUoKSA+IDEgPwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEaWFtb25kSW52YWxpZEFyZ3MoaW52YWxpZERpYW1vbmRBcmdzLCBmcmFnbWVudCkgOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEaWFtb25kSW52YWxpZEFyZyhpbnZhbGlkRGlhbW9uZEFyZ3MsIGZyYWdtZW50KSkpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAvLyBGb3IgPD4oKXt9LCBpbmZlcnJlZCB0eXBlcyBtdXN0IGFsc28gYmUgYWNjZXNzaWJsZS4KICAgICAgICAgICAgICAgICAgICBmb3IgKFR5cGUgdCA6IGNsYXp6dHlwZS5nZXRUeXBlQXJndW1lbnRzKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcnMuY2hlY2tBY2Nlc3NpYmxlVHlwZShlbnYsIHQpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBJZiB3ZSBhbHJlYWR5IGVycm9yZWQsIGJlIGNhcmVmdWwgdG8gYXZvaWQgYSBmdXJ0aGVyIGF2YWxhbmNoZS4gRXJyb3JUeXBlIGFuc3dlcnMKICAgICAgICAgICAgICAgIC8vIGZhbHNlIGZvciBpc0ludGVyZmFjZSBjYWxsIGV2ZW4gd2hlbiB0aGUgb3JpZ2luYWwgdHlwZSBpcyBhbiBpbnRlcmZhY2UuCiAgICAgICAgICAgICAgICBib29sZWFuIGltcGxlbWVudGluZyA9IGNsYXp6dHlwZS50c3ltLmlzSW50ZXJmYWNlKCkgfHwKICAgICAgICAgICAgICAgICAgICAgICAgY2xhenp0eXBlLmlzRXJyb25lb3VzKCkgJiYgY2xhenp0eXBlLmdldE9yaWdpbmFsVHlwZSgpLnRzeW0uaXNJbnRlcmZhY2UoKTsKCiAgICAgICAgICAgICAgICBpZiAoaW1wbGVtZW50aW5nKSB7CiAgICAgICAgICAgICAgICAgICAgY2RlZi5pbXBsZW1lbnRpbmcgPSBMaXN0Lm9mKGNsYXp6KTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgY2RlZi5leHRlbmRpbmcgPSBjbGF6ejsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAocmVzdWx0SW5mby5jaGVja0NvbnRleHQuZGVmZXJyZWRBdHRyQ29udGV4dCgpLm1vZGUgPT0gRGVmZXJyZWRBdHRyLkF0dHJNb2RlLkNIRUNLICYmCiAgICAgICAgICAgICAgICAgICAgaXNTZXJpYWxpemFibGUoY2xhenp0eXBlKSkgewogICAgICAgICAgICAgICAgICAgIGxvY2FsRW52LmluZm8uaXNTZXJpYWxpemFibGUgPSB0cnVlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGF0dHJpYlN0YXQoY2RlZiwgbG9jYWxFbnYpOwoKICAgICAgICAgICAgICAgIExpc3Q8VHlwZT4gZmluYWxhcmd0eXBlczsKICAgICAgICAgICAgICAgIC8vIElmIGFuIG91dGVyIGluc3RhbmNlIGlzIGdpdmVuLAogICAgICAgICAgICAgICAgLy8gcHJlZml4IGl0IHRvIHRoZSBjb25zdHJ1Y3RvciBhcmd1bWVudHMKICAgICAgICAgICAgICAgIC8vIGFuZCBkZWxldGUgaXQgZnJvbSB0aGUgbmV3IGV4cHJlc3Npb24KICAgICAgICAgICAgICAgIGlmICh0cmVlLmVuY2wgIT0gbnVsbCAmJiAhY2xhenp0eXBlLnRzeW0uaXNJbnRlcmZhY2UoKSkgewogICAgICAgICAgICAgICAgICAgIHRyZWUuYXJncyA9IHRyZWUuYXJncy5wcmVwZW5kKG1ha2VOdWxsQ2hlY2sodHJlZS5lbmNsKSk7CiAgICAgICAgICAgICAgICAgICAgZmluYWxhcmd0eXBlcyA9IGFyZ3R5cGVzLnByZXBlbmQodHJlZS5lbmNsLnR5cGUpOwogICAgICAgICAgICAgICAgICAgIHRyZWUuZW5jbCA9IG51bGw7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGZpbmFsYXJndHlwZXMgPSBhcmd0eXBlczsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBSZWFzc2lnbiBjbGF6enR5cGUgYW5kIHJlY29tcHV0ZSBjb25zdHJ1Y3Rvci4gQXMgdGhpcyBuZWNlc3NhcmlseSBpbnZvbHZlcwogICAgICAgICAgICAgICAgLy8gYW5vdGhlciBhdHRyaWJ1dGlvbiBwYXNzIGZvciBkZWZlcnJlZCB0eXBlcyBpbiB0aGUgY2FzZSBvZiA8PiwgcmVwbGljYXRlCiAgICAgICAgICAgICAgICAvLyB0aGVtLiBPcmlnaW5hbCBhcmd1bWVudHMgaGF2ZSByaWdodCBkZWNvcmF0aW9ucyBhbHJlYWR5LgogICAgICAgICAgICAgICAgaWYgKGlzRGlhbW9uZCAmJiBwa2luZC5jb250YWlucyhLaW5kU2VsZWN0b3IuUE9MWSkpIHsKICAgICAgICAgICAgICAgICAgICBmaW5hbGFyZ3R5cGVzID0gZmluYWxhcmd0eXBlcy5tYXAoZGVmZXJyZWRBdHRyLmRlZmVycmVkQ29waWVyKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBjbGF6enR5cGUgPSBjZGVmLnN5bS50eXBlOwogICAgICAgICAgICAgICAgU3ltYm9sIHN5bSA9IHRyZWUuY29uc3RydWN0b3IgPSBycy5yZXNvbHZlQ29uc3RydWN0b3IoCiAgICAgICAgICAgICAgICAgICAgICAgIHRyZWUucG9zKCksIGxvY2FsRW52LCBjbGF6enR5cGUsIGZpbmFsYXJndHlwZXMsIHR5cGVhcmd0eXBlcyk7CiAgICAgICAgICAgICAgICBBc3NlcnQuY2hlY2soIXN5bS5raW5kLmlzUmVzb2x1dGlvbkVycm9yKCkpOwogICAgICAgICAgICAgICAgdHJlZS5jb25zdHJ1Y3RvciA9IHN5bTsKICAgICAgICAgICAgICAgIHRyZWUuY29uc3RydWN0b3JUeXBlID0gY2hlY2tJZCh0cmVlLAogICAgICAgICAgICAgICAgICAgICAgICBjbGF6enR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgIHRyZWUuY29uc3RydWN0b3IsCiAgICAgICAgICAgICAgICAgICAgICAgIGxvY2FsRW52LAogICAgICAgICAgICAgICAgICAgICAgICBuZXcgUmVzdWx0SW5mbyhwa2luZCwgbmV3TWV0aG9kVGVtcGxhdGUoc3ltcy52b2lkVHlwZSwgZmluYWxhcmd0eXBlcywgdHlwZWFyZ3R5cGVzKSwgQ2hlY2tNb2RlLk5PX1RSRUVfVVBEQVRFKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgVHlwZSBvd250eXBlID0gKHRyZWUuY29uc3RydWN0b3IgIT0gbnVsbCAmJiB0cmVlLmNvbnN0cnVjdG9yLmtpbmQgPT0gTVRIKSA/CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhenp0eXBlIDogdHlwZXMuY3JlYXRlRXJyb3JUeXBlKHRyZWUudHlwZSk7CiAgICAgICAgICAgIHJlc3VsdCA9IGNoZWNrKHRyZWUsIG93bnR5cGUsIEtpbmRTZWxlY3Rvci5WQUwsIHJlc3VsdEluZm8uZHVwKENoZWNrTW9kZS5OT19JTkZFUkVOQ0VfSE9PSykpOwogICAgICAgICAgICBjaGsudmFsaWRhdGUodHJlZS50eXBlYXJncywgbG9jYWxFbnYpOwogICAgICAgIH0KCiAgICAgICAgQ2hlY2tDb250ZXh0IGRpYW1vbmRDb250ZXh0KEpDTmV3Q2xhc3MgY2xhenosIFR5cGVTeW1ib2wgdHN5bSwgQ2hlY2tDb250ZXh0IGNoZWNrQ29udGV4dCkgewogICAgICAgICAgICByZXR1cm4gbmV3IENoZWNrLk5lc3RlZENoZWNrQ29udGV4dChjaGVja0NvbnRleHQpIHsKICAgICAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICAgICAgcHVibGljIHZvaWQgcmVwb3J0KERpYWdub3N0aWNQb3NpdGlvbiBfdW51c2VkLCBKQ0RpYWdub3N0aWMgZGV0YWlscykgewogICAgICAgICAgICAgICAgICAgIGVuY2xvc2luZ0NvbnRleHQucmVwb3J0KGNsYXp6LmNsYXp6LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlhZ3MuZnJhZ21lbnQoImNhbnQuYXBwbHkuZGlhbW9uZC4xIiwgZGlhZ3MuZnJhZ21lbnQoImRpYW1vbmQiLCB0c3ltKSwgZGV0YWlscykpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwogICAgICAgIH0KCiAgICAvKiogTWFrZSBhbiBhdHRyaWJ1dGVkIG51bGwgY2hlY2sgdHJlZS4KICAgICAqLwogICAgcHVibGljIEpDRXhwcmVzc2lvbiBtYWtlTnVsbENoZWNrKEpDRXhwcmVzc2lvbiBhcmcpIHsKICAgICAgICAvLyBvcHRpbWl6YXRpb246IG5ldyBPdXRlcigpIGNhbiBuZXZlciBiZSBudWxsOyBza2lwIG51bGwgY2hlY2sKICAgICAgICBpZiAoYXJnLmdldFRhZygpID09IE5FV0NMQVNTKQogICAgICAgICAgICByZXR1cm4gYXJnOwogICAgICAgIC8vIG9wdGltaXphdGlvbjogWC50aGlzIGlzIG5ldmVyIG51bGw7IHNraXAgbnVsbCBjaGVjawogICAgICAgIE5hbWUgbmFtZSA9IFRyZWVJbmZvLm5hbWUoYXJnKTsKICAgICAgICBpZiAobmFtZSA9PSBuYW1lcy5fdGhpcyB8fCBuYW1lID09IG5hbWVzLl9zdXBlcikgcmV0dXJuIGFyZzsKCiAgICAgICAgSkNUcmVlLlRhZyBvcHRhZyA9IE5VTExDSEs7CiAgICAgICAgSkNVbmFyeSB0cmVlID0gbWFrZS5hdChhcmcucG9zKS5VbmFyeShvcHRhZywgYXJnKTsKICAgICAgICB0cmVlLm9wZXJhdG9yID0gb3BlcmF0b3JzLnJlc29sdmVVbmFyeShhcmcsIG9wdGFnLCBhcmcudHlwZSk7CiAgICAgICAgdHJlZS50eXBlID0gYXJnLnR5cGU7CiAgICAgICAgcmV0dXJuIHRyZWU7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXROZXdBcnJheShKQ05ld0FycmF5IHRyZWUpIHsKICAgICAgICBUeXBlIG93bnR5cGUgPSB0eXBlcy5jcmVhdGVFcnJvclR5cGUodHJlZS50eXBlKTsKICAgICAgICBFbnY8QXR0ckNvbnRleHQ+IGxvY2FsRW52ID0gZW52LmR1cCh0cmVlKTsKICAgICAgICBUeXBlIGVsZW10eXBlOwogICAgICAgIGlmICh0cmVlLmVsZW10eXBlICE9IG51bGwpIHsKICAgICAgICAgICAgZWxlbXR5cGUgPSBhdHRyaWJUeXBlKHRyZWUuZWxlbXR5cGUsIGxvY2FsRW52KTsKICAgICAgICAgICAgY2hrLnZhbGlkYXRlKHRyZWUuZWxlbXR5cGUsIGxvY2FsRW52KTsKICAgICAgICAgICAgb3dudHlwZSA9IGVsZW10eXBlOwogICAgICAgICAgICBmb3IgKExpc3Q8SkNFeHByZXNzaW9uPiBsID0gdHJlZS5kaW1zOyBsLm5vbkVtcHR5KCk7IGwgPSBsLnRhaWwpIHsKICAgICAgICAgICAgICAgIGF0dHJpYkV4cHIobC5oZWFkLCBsb2NhbEVudiwgc3ltcy5pbnRUeXBlKTsKICAgICAgICAgICAgICAgIG93bnR5cGUgPSBuZXcgQXJyYXlUeXBlKG93bnR5cGUsIHN5bXMuYXJyYXlDbGFzcyk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvLyB3ZSBhcmUgc2VlaW5nIGFuIHVudHlwZWQgYWdncmVnYXRlIHsgLi4uIH0KICAgICAgICAgICAgLy8gdGhpcyBpcyBhbGxvd2VkIG9ubHkgaWYgdGhlIHByb3RvdHlwZSBpcyBhbiBhcnJheQogICAgICAgICAgICBpZiAocHQoKS5oYXNUYWcoQVJSQVkpKSB7CiAgICAgICAgICAgICAgICBlbGVtdHlwZSA9IHR5cGVzLmVsZW10eXBlKHB0KCkpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgaWYgKCFwdCgpLmhhc1RhZyhFUlJPUikpIHsKICAgICAgICAgICAgICAgICAgICBsb2cuZXJyb3IodHJlZS5wb3MoKSwgImlsbGVnYWwuaW5pdGlhbGl6ZXIuZm9yLnR5cGUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwdCgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsZW10eXBlID0gdHlwZXMuY3JlYXRlRXJyb3JUeXBlKHB0KCkpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmICh0cmVlLmVsZW1zICE9IG51bGwpIHsKICAgICAgICAgICAgYXR0cmliRXhwcnModHJlZS5lbGVtcywgbG9jYWxFbnYsIGVsZW10eXBlKTsKICAgICAgICAgICAgb3dudHlwZSA9IG5ldyBBcnJheVR5cGUoZWxlbXR5cGUsIHN5bXMuYXJyYXlDbGFzcyk7CiAgICAgICAgfQogICAgICAgIGlmICghdHlwZXMuaXNSZWlmaWFibGUoZWxlbXR5cGUpKQogICAgICAgICAgICBsb2cuZXJyb3IodHJlZS5wb3MoKSwgImdlbmVyaWMuYXJyYXkuY3JlYXRpb24iKTsKICAgICAgICByZXN1bHQgPSBjaGVjayh0cmVlLCBvd250eXBlLCBLaW5kU2VsZWN0b3IuVkFMLCByZXN1bHRJbmZvKTsKICAgIH0KCiAgICAvKgogICAgICogQSBsYW1iZGEgZXhwcmVzc2lvbiBjYW4gb25seSBiZSBhdHRyaWJ1dGVkIHdoZW4gYSB0YXJnZXQtdHlwZSBpcyBhdmFpbGFibGUuCiAgICAgKiBJbiBhZGRpdGlvbiwgaWYgdGhlIHRhcmdldC10eXBlIGlzIHRoYXQgb2YgYSBmdW5jdGlvbmFsIGludGVyZmFjZSB3aG9zZQogICAgICogZGVzY3JpcHRvciBjb250YWlucyBpbmZlcmVuY2UgdmFyaWFibGVzIGluIGFyZ3VtZW50IHBvc2l0aW9uIHRoZSBsYW1iZGEgZXhwcmVzc2lvbgogICAgICogaXMgJ3N0dWNrJyAoc2VlIERlZmVycmVkQXR0cikuCiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIHZvaWQgdmlzaXRMYW1iZGEoZmluYWwgSkNMYW1iZGEgdGhhdCkgewogICAgICAgIGlmIChwdCgpLmlzRXJyb25lb3VzKCkgfHwgKHB0KCkuaGFzVGFnKE5PTkUpICYmIHB0KCkgIT0gVHlwZS5yZWNvdmVyeVR5cGUpKSB7CiAgICAgICAgICAgIGlmIChwdCgpLmhhc1RhZyhOT05FKSkgewogICAgICAgICAgICAgICAgLy9sYW1iZGEgb25seSBhbGxvd2VkIGluIGFzc2lnbm1lbnQgb3IgbWV0aG9kIGludm9jYXRpb24vY2FzdCBjb250ZXh0CiAgICAgICAgICAgICAgICBsb2cuZXJyb3IodGhhdC5wb3MoKSwgInVuZXhwZWN0ZWQubGFtYmRhIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmVzdWx0ID0gdGhhdC50eXBlID0gdHlwZXMuY3JlYXRlRXJyb3JUeXBlKHB0KCkpOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIC8vY3JlYXRlIGFuIGVudmlyb25tZW50IGZvciBhdHRyaWJ1dGlvbiBvZiB0aGUgbGFtYmRhIGV4cHJlc3Npb24KICAgICAgICBmaW5hbCBFbnY8QXR0ckNvbnRleHQ+IGxvY2FsRW52ID0gbGFtYmRhRW52KHRoYXQsIGVudik7CiAgICAgICAgYm9vbGVhbiBuZWVkc1JlY292ZXJ5ID0KICAgICAgICAgICAgICAgIHJlc3VsdEluZm8uY2hlY2tDb250ZXh0LmRlZmVycmVkQXR0ckNvbnRleHQoKS5tb2RlID09IERlZmVycmVkQXR0ci5BdHRyTW9kZS5DSEVDSzsKICAgICAgICB0cnkgewogICAgICAgICAgICBpZiAobmVlZHNSZWNvdmVyeSAmJiBpc1NlcmlhbGl6YWJsZShwdCgpKSkgewogICAgICAgICAgICAgICAgbG9jYWxFbnYuaW5mby5pc1NlcmlhbGl6YWJsZSA9IHRydWU7CiAgICAgICAgICAgICAgICBsb2NhbEVudi5pbmZvLmlzTGFtYmRhID0gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBMaXN0PFR5cGU+IGV4cGxpY2l0UGFyYW1UeXBlcyA9IG51bGw7CiAgICAgICAgICAgIGlmICh0aGF0LnBhcmFtS2luZCA9PSBKQ0xhbWJkYS5QYXJhbWV0ZXJLaW5kLkVYUExJQ0lUKSB7CiAgICAgICAgICAgICAgICAvL2F0dHJpYnV0ZSBsYW1iZGEgcGFyYW1ldGVycwogICAgICAgICAgICAgICAgYXR0cmliU3RhdHModGhhdC5wYXJhbXMsIGxvY2FsRW52KTsKICAgICAgICAgICAgICAgIGV4cGxpY2l0UGFyYW1UeXBlcyA9IFRyZWVJbmZvLnR5cGVzKHRoYXQucGFyYW1zKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgVGFyZ2V0SW5mbyB0YXJnZXRJbmZvID0gZ2V0VGFyZ2V0SW5mbyh0aGF0LCByZXN1bHRJbmZvLCBleHBsaWNpdFBhcmFtVHlwZXMpOwogICAgICAgICAgICBUeXBlIGN1cnJlbnRUYXJnZXQgPSB0YXJnZXRJbmZvLnRhcmdldDsKICAgICAgICAgICAgVHlwZSBsYW1iZGFUeXBlID0gdGFyZ2V0SW5mby5kZXNjcmlwdG9yOwoKICAgICAgICAgICAgaWYgKGN1cnJlbnRUYXJnZXQuaXNFcnJvbmVvdXMoKSkgewogICAgICAgICAgICAgICAgcmVzdWx0ID0gdGhhdC50eXBlID0gY3VycmVudFRhcmdldDsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgc2V0RnVuY3Rpb25hbEluZm8obG9jYWxFbnYsIHRoYXQsIHB0KCksIGxhbWJkYVR5cGUsIGN1cnJlbnRUYXJnZXQsIHJlc3VsdEluZm8uY2hlY2tDb250ZXh0KTsKCiAgICAgICAgICAgIGlmIChsYW1iZGFUeXBlLmhhc1RhZyhGT1JBTEwpKSB7CiAgICAgICAgICAgICAgICAvL2xhbWJkYSBleHByZXNzaW9uIHRhcmdldCBkZXNjIGNhbm5vdCBiZSBhIGdlbmVyaWMgbWV0aG9kCiAgICAgICAgICAgICAgICByZXN1bHRJbmZvLmNoZWNrQ29udGV4dC5yZXBvcnQodGhhdCwgZGlhZ3MuZnJhZ21lbnQoImludmFsaWQuZ2VuZXJpYy5sYW1iZGEudGFyZ2V0IiwKICAgICAgICAgICAgICAgICAgICAgICAgbGFtYmRhVHlwZSwga2luZE5hbWUoY3VycmVudFRhcmdldC50c3ltKSwgY3VycmVudFRhcmdldC50c3ltKSk7CiAgICAgICAgICAgICAgICByZXN1bHQgPSB0aGF0LnR5cGUgPSB0eXBlcy5jcmVhdGVFcnJvclR5cGUocHQoKSk7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICh0aGF0LnBhcmFtS2luZCA9PSBKQ0xhbWJkYS5QYXJhbWV0ZXJLaW5kLklNUExJQ0lUKSB7CiAgICAgICAgICAgICAgICAvL2FkZCBwYXJhbSB0eXBlIGluZm8gaW4gdGhlIEFTVAogICAgICAgICAgICAgICAgTGlzdDxUeXBlPiBhY3R1YWxzID0gbGFtYmRhVHlwZS5nZXRQYXJhbWV0ZXJUeXBlcygpOwogICAgICAgICAgICAgICAgTGlzdDxKQ1ZhcmlhYmxlRGVjbD4gcGFyYW1zID0gdGhhdC5wYXJhbXM7CgogICAgICAgICAgICAgICAgYm9vbGVhbiBhcml0eU1pc21hdGNoID0gZmFsc2U7CgogICAgICAgICAgICAgICAgd2hpbGUgKHBhcmFtcy5ub25FbXB0eSgpKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGFjdHVhbHMuaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vbm90IGVub3VnaCBhY3R1YWxzIHRvIHBlcmZvcm0gbGFtYmRhIHBhcmFtZXRlciBpbmZlcmVuY2UKICAgICAgICAgICAgICAgICAgICAgICAgYXJpdHlNaXNtYXRjaCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIC8vcmVzZXQgcHJldmlvdXNseSBzZXQgaW5mbwogICAgICAgICAgICAgICAgICAgIFR5cGUgYXJnVHlwZSA9IGFyaXR5TWlzbWF0Y2ggPwogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ltcy5lcnJUeXBlIDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFjdHVhbHMuaGVhZDsKICAgICAgICAgICAgICAgICAgICBwYXJhbXMuaGVhZC52YXJ0eXBlID0gbWFrZS5hdChwYXJhbXMuaGVhZCkuVHlwZShhcmdUeXBlKTsKICAgICAgICAgICAgICAgICAgICBwYXJhbXMuaGVhZC5zeW0gPSBudWxsOwogICAgICAgICAgICAgICAgICAgIGFjdHVhbHMgPSBhY3R1YWxzLmlzRW1wdHkoKSA/CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhY3R1YWxzIDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFjdHVhbHMudGFpbDsKICAgICAgICAgICAgICAgICAgICBwYXJhbXMgPSBwYXJhbXMudGFpbDsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvL2F0dHJpYnV0ZSBsYW1iZGEgcGFyYW1ldGVycwogICAgICAgICAgICAgICAgYXR0cmliU3RhdHModGhhdC5wYXJhbXMsIGxvY2FsRW52KTsKCiAgICAgICAgICAgICAgICBpZiAoYXJpdHlNaXNtYXRjaCkgewogICAgICAgICAgICAgICAgICAgIHJlc3VsdEluZm8uY2hlY2tDb250ZXh0LnJlcG9ydCh0aGF0LCBkaWFncy5mcmFnbWVudCgiaW5jb21wYXRpYmxlLmFyZy50eXBlcy5pbi5sYW1iZGEiKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IHRoYXQudHlwZSA9IHR5cGVzLmNyZWF0ZUVycm9yVHlwZShjdXJyZW50VGFyZ2V0KTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICAvL2Zyb20gdGhpcyBwb2ludCBvbiwgbm8gcmVjb3ZlcnkgaXMgbmVlZGVkOyBpZiB3ZSBhcmUgaW4gYXNzaWdubWVudCBjb250ZXh0CiAgICAgICAgICAgIC8vd2Ugd2lsbCBiZSBhYmxlIHRvIGF0dHJpYnV0ZSB0aGUgd2hvbGUgbGFtYmRhIGJvZHksIHJlZ2FyZGxlc3Mgb2YgZXJyb3JzOwogICAgICAgICAgICAvL2lmIHdlIGFyZSBpbiBhICdjaGVjaycgbWV0aG9kIGNvbnRleHQsIGFuZCB0aGUgbGFtYmRhIGlzIG5vdCBjb21wYXRpYmxlCiAgICAgICAgICAgIC8vd2l0aCB0aGUgdGFyZ2V0LXR5cGUsIGl0IHdpbGwgYmUgcmVjb3ZlcmVkIGFueXdheSBpbiBBdHRyLmNoZWNrSWQKICAgICAgICAgICAgbmVlZHNSZWNvdmVyeSA9IGZhbHNlOwoKICAgICAgICAgICAgUmVzdWx0SW5mbyBib2R5UmVzdWx0SW5mbyA9IGxvY2FsRW52LmluZm8ucmV0dXJuUmVzdWx0ID0KICAgICAgICAgICAgICAgICAgICBsYW1iZGFCb2R5UmVzdWx0KHRoYXQsIGxhbWJkYVR5cGUsIHJlc3VsdEluZm8pOwoKICAgICAgICAgICAgaWYgKHRoYXQuZ2V0Qm9keUtpbmQoKSA9PSBKQ0xhbWJkYS5Cb2R5S2luZC5FWFBSRVNTSU9OKSB7CiAgICAgICAgICAgICAgICBhdHRyaWJUcmVlKHRoYXQuZ2V0Qm9keSgpLCBsb2NhbEVudiwgYm9keVJlc3VsdEluZm8pOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgSkNCbG9jayBib2R5ID0gKEpDQmxvY2spdGhhdC5ib2R5OwogICAgICAgICAgICAgICAgYXR0cmliU3RhdHMoYm9keS5zdGF0cywgbG9jYWxFbnYpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXN1bHQgPSBjaGVjayh0aGF0LCBjdXJyZW50VGFyZ2V0LCBLaW5kU2VsZWN0b3IuVkFMLCByZXN1bHRJbmZvKTsKCiAgICAgICAgICAgIGJvb2xlYW4gaXNTcGVjdWxhdGl2ZVJvdW5kID0KICAgICAgICAgICAgICAgICAgICByZXN1bHRJbmZvLmNoZWNrQ29udGV4dC5kZWZlcnJlZEF0dHJDb250ZXh0KCkubW9kZSA9PSBEZWZlcnJlZEF0dHIuQXR0ck1vZGUuU1BFQ1VMQVRJVkU7CgogICAgICAgICAgICBwcmVGbG93KHRoYXQpOwogICAgICAgICAgICBmbG93LmFuYWx5emVMYW1iZGEoZW52LCB0aGF0LCBtYWtlLCBpc1NwZWN1bGF0aXZlUm91bmQpOwoKICAgICAgICAgICAgdGhhdC50eXBlID0gY3VycmVudFRhcmdldDsgLy9hdm9pZHMgcmVjb3ZlcnkgYXQgdGhpcyBzdGFnZQogICAgICAgICAgICBjaGVja0xhbWJkYUNvbXBhdGlibGUodGhhdCwgbGFtYmRhVHlwZSwgcmVzdWx0SW5mby5jaGVja0NvbnRleHQpOwoKICAgICAgICAgICAgaWYgKCFpc1NwZWN1bGF0aXZlUm91bmQpIHsKICAgICAgICAgICAgICAgIC8vYWRkIHRocm93biB0eXBlcyBhcyBib3VuZHMgdG8gdGhlIHRocm93biB0eXBlcyBmcmVlIHZhcmlhYmxlcyBpZiBuZWVkZWQ6CiAgICAgICAgICAgICAgICBpZiAocmVzdWx0SW5mby5jaGVja0NvbnRleHQuaW5mZXJlbmNlQ29udGV4dCgpLmZyZWUobGFtYmRhVHlwZS5nZXRUaHJvd25UeXBlcygpKSkgewogICAgICAgICAgICAgICAgICAgIExpc3Q8VHlwZT4gaW5mZXJyZWRUaHJvd25UeXBlcyA9IGZsb3cuYW5hbHl6ZUxhbWJkYVRocm93blR5cGVzKGVudiwgdGhhdCwgbWFrZSk7CiAgICAgICAgICAgICAgICAgICAgTGlzdDxUeXBlPiB0aHJvd25UeXBlcyA9IHJlc3VsdEluZm8uY2hlY2tDb250ZXh0LmluZmVyZW5jZUNvbnRleHQoKS5hc1VuZGV0VmFycyhsYW1iZGFUeXBlLmdldFRocm93blR5cGVzKCkpOwoKICAgICAgICAgICAgICAgICAgICBjaGsudW5oYW5kbGVkKGluZmVycmVkVGhyb3duVHlwZXMsIHRocm93blR5cGVzKTsKCiAgICAgICAgICAgICAgICAgICAgLy8xOC4yLjU6ICJJbiBhZGRpdGlvbiwgZm9yIGFsbCBqICgxIDw9IGogPD0gbiksIHRoZSBjb25zdHJhaW50IHJlZHVjZXMgdG8gdGhlIGJvdW5kIHRocm93cyBFaiIKICAgICAgICAgICAgICAgICAgICB0aHJvd25UeXBlcy5zdHJlYW0oKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgLmZpbHRlcih0IC0+IHQuaGFzVGFnKFVOREVUVkFSKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5mb3JFYWNoKHQgLT4gKChVbmRldFZhcil0KS5zZXRUaHJvdygpKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBjaGVja0FjY2Vzc2libGVUeXBlcyh0aGF0LCBsb2NhbEVudiwgcmVzdWx0SW5mby5jaGVja0NvbnRleHQuaW5mZXJlbmNlQ29udGV4dCgpLCBsYW1iZGFUeXBlLCBjdXJyZW50VGFyZ2V0KTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXN1bHQgPSBjaGVjayh0aGF0LCBjdXJyZW50VGFyZ2V0LCBLaW5kU2VsZWN0b3IuVkFMLCByZXN1bHRJbmZvKTsKICAgICAgICB9IGNhdGNoIChUeXBlcy5GdW5jdGlvbkRlc2NyaXB0b3JMb29rdXBFcnJvciBleCkgewogICAgICAgICAgICBKQ0RpYWdub3N0aWMgY2F1c2UgPSBleC5nZXREaWFnbm9zdGljKCk7CiAgICAgICAgICAgIHJlc3VsdEluZm8uY2hlY2tDb250ZXh0LnJlcG9ydCh0aGF0LCBjYXVzZSk7CiAgICAgICAgICAgIHJlc3VsdCA9IHRoYXQudHlwZSA9IHR5cGVzLmNyZWF0ZUVycm9yVHlwZShwdCgpKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0gY2F0Y2ggKFRocm93YWJsZSB0KSB7CiAgICAgICAgICAgIC8vd2hlbiBhbiB1bmV4cGVjdGVkIGV4Y2VwdGlvbiBoYXBwZW5zLCBhdm9pZCBhdHRlbXB0cyB0byBhdHRyaWJ1dGUgdGhlIHNhbWUgdHJlZSBhZ2FpbgogICAgICAgICAgICAvL2FzIHRoYXQgd291bGQgbGlrZWx5IGNhdXNlIHRoZSBzYW1lIGV4Y2VwdGlvbiBhZ2Fpbi4KICAgICAgICAgICAgbmVlZHNSZWNvdmVyeSA9IGZhbHNlOwogICAgICAgICAgICB0aHJvdyB0OwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgIGxvY2FsRW52LmluZm8uc2NvcGUubGVhdmUoKTsKICAgICAgICAgICAgaWYgKG5lZWRzUmVjb3ZlcnkpIHsKICAgICAgICAgICAgICAgIGF0dHJpYlRyZWUodGhhdCwgZW52LCByZWNvdmVyeUluZm8pOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgLy93aGVyZQogICAgICAgIGNsYXNzIFRhcmdldEluZm8gewogICAgICAgICAgICBUeXBlIHRhcmdldDsKICAgICAgICAgICAgVHlwZSBkZXNjcmlwdG9yOwoKICAgICAgICAgICAgcHVibGljIFRhcmdldEluZm8oVHlwZSB0YXJnZXQsIFR5cGUgZGVzY3JpcHRvcikgewogICAgICAgICAgICAgICAgdGhpcy50YXJnZXQgPSB0YXJnZXQ7CiAgICAgICAgICAgICAgICB0aGlzLmRlc2NyaXB0b3IgPSBkZXNjcmlwdG9yOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBUYXJnZXRJbmZvIGdldFRhcmdldEluZm8oSkNQb2x5RXhwcmVzc2lvbiB0aGF0LCBSZXN1bHRJbmZvIHJlc3VsdEluZm8sIExpc3Q8VHlwZT4gZXhwbGljaXRQYXJhbVR5cGVzKSB7CiAgICAgICAgICAgIFR5cGUgbGFtYmRhVHlwZTsKICAgICAgICAgICAgVHlwZSBjdXJyZW50VGFyZ2V0ID0gcmVzdWx0SW5mby5wdDsKICAgICAgICAgICAgaWYgKHJlc3VsdEluZm8ucHQgIT0gVHlwZS5yZWNvdmVyeVR5cGUpIHsKICAgICAgICAgICAgICAgIC8qIFdlIG5lZWQgdG8gYWRqdXN0IHRoZSB0YXJnZXQuIElmIHRoZSB0YXJnZXQgaXMgYW4KICAgICAgICAgICAgICAgICAqIGludGVyc2VjdGlvbiB0eXBlLCBmb3IgZXhhbXBsZTogU0FNICYgSTEgJiBJMiAuLi4KICAgICAgICAgICAgICAgICAqIHRoZSB0YXJnZXQgd2lsbCBiZSB1cGRhdGVkIHRvIFNBTQogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBjdXJyZW50VGFyZ2V0ID0gdGFyZ2V0Q2hlY2tlci52aXNpdChjdXJyZW50VGFyZ2V0LCB0aGF0KTsKICAgICAgICAgICAgICAgIGlmIChleHBsaWNpdFBhcmFtVHlwZXMgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIGN1cnJlbnRUYXJnZXQgPSBpbmZlci5pbnN0YW50aWF0ZUZ1bmN0aW9uYWxJbnRlcmZhY2UodGhhdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRUYXJnZXQsIGV4cGxpY2l0UGFyYW1UeXBlcywgcmVzdWx0SW5mby5jaGVja0NvbnRleHQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgY3VycmVudFRhcmdldCA9IHR5cGVzLnJlbW92ZVdpbGRjYXJkcyhjdXJyZW50VGFyZ2V0KTsKICAgICAgICAgICAgICAgIGxhbWJkYVR5cGUgPSB0eXBlcy5maW5kRGVzY3JpcHRvclR5cGUoY3VycmVudFRhcmdldCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBjdXJyZW50VGFyZ2V0ID0gVHlwZS5yZWNvdmVyeVR5cGU7CiAgICAgICAgICAgICAgICBsYW1iZGFUeXBlID0gZmFsbGJhY2tEZXNjcmlwdG9yVHlwZSh0aGF0KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAodGhhdC5oYXNUYWcoTEFNQkRBKSAmJiBsYW1iZGFUeXBlLmhhc1RhZyhGT1JBTEwpKSB7CiAgICAgICAgICAgICAgICAvL2xhbWJkYSBleHByZXNzaW9uIHRhcmdldCBkZXNjIGNhbm5vdCBiZSBhIGdlbmVyaWMgbWV0aG9kCiAgICAgICAgICAgICAgICByZXN1bHRJbmZvLmNoZWNrQ29udGV4dC5yZXBvcnQodGhhdCwgZGlhZ3MuZnJhZ21lbnQoImludmFsaWQuZ2VuZXJpYy5sYW1iZGEudGFyZ2V0IiwKICAgICAgICAgICAgICAgICAgICAgICAgbGFtYmRhVHlwZSwga2luZE5hbWUoY3VycmVudFRhcmdldC50c3ltKSwgY3VycmVudFRhcmdldC50c3ltKSk7CiAgICAgICAgICAgICAgICBjdXJyZW50VGFyZ2V0ID0gdHlwZXMuY3JlYXRlRXJyb3JUeXBlKHB0KCkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBuZXcgVGFyZ2V0SW5mbyhjdXJyZW50VGFyZ2V0LCBsYW1iZGFUeXBlKTsKICAgICAgICB9CgogICAgICAgIHZvaWQgcHJlRmxvdyhKQ0xhbWJkYSB0cmVlKSB7CiAgICAgICAgICAgIG5ldyBQb3N0QXR0ckFuYWx5emVyKCkgewogICAgICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCBzY2FuKEpDVHJlZSB0cmVlKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHRyZWUgPT0gbnVsbCB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKHRyZWUudHlwZSAhPSBudWxsICYmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmVlLnR5cGUgPT0gVHlwZS5zdHVja1R5cGUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vZG9uJ3QgdG91Y2ggc3R1Y2sgZXhwcmVzc2lvbnMhCiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgc3VwZXIuc2Nhbih0cmVlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfS5zY2FuKHRyZWUpOwogICAgICAgIH0KCiAgICAgICAgVHlwZXMuTWFwVmlzaXRvcjxEaWFnbm9zdGljUG9zaXRpb24+IHRhcmdldENoZWNrZXIgPSBuZXcgVHlwZXMuTWFwVmlzaXRvcjxEaWFnbm9zdGljUG9zaXRpb24+KCkgewoKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHB1YmxpYyBUeXBlIHZpc2l0Q2xhc3NUeXBlKENsYXNzVHlwZSB0LCBEaWFnbm9zdGljUG9zaXRpb24gcG9zKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdC5pc0ludGVyc2VjdGlvbigpID8KICAgICAgICAgICAgICAgICAgICAgICAgdmlzaXRJbnRlcnNlY3Rpb25DbGFzc1R5cGUoKEludGVyc2VjdGlvbkNsYXNzVHlwZSl0LCBwb3MpIDogdDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHVibGljIFR5cGUgdmlzaXRJbnRlcnNlY3Rpb25DbGFzc1R5cGUoSW50ZXJzZWN0aW9uQ2xhc3NUeXBlIGljdCwgRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcykgewogICAgICAgICAgICAgICAgU3ltYm9sIGRlc2MgPSB0eXBlcy5maW5kRGVzY3JpcHRvclN5bWJvbChtYWtlTm90aW9uYWxJbnRlcmZhY2UoaWN0KSk7CiAgICAgICAgICAgICAgICBUeXBlIHRhcmdldCA9IG51bGw7CiAgICAgICAgICAgICAgICBmb3IgKFR5cGUgYm91bmQgOiBpY3QuZ2V0RXhwbGljaXRDb21wb25lbnRzKCkpIHsKICAgICAgICAgICAgICAgICAgICBUeXBlU3ltYm9sIGJvdW5kU3ltID0gYm91bmQudHN5bTsKICAgICAgICAgICAgICAgICAgICBpZiAodHlwZXMuaXNGdW5jdGlvbmFsSW50ZXJmYWNlKGJvdW5kU3ltKSAmJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZXMuZmluZERlc2NyaXB0b3JTeW1ib2woYm91bmRTeW0pID09IGRlc2MpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0ID0gYm91bmQ7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICghYm91bmRTeW0uaXNJbnRlcmZhY2UoKSB8fCAoYm91bmRTeW0uZmxhZ3MoKSAmIEFOTk9UQVRJT04pICE9IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy9ib3VuZCBtdXN0IGJlIGFuIGludGVyZmFjZQogICAgICAgICAgICAgICAgICAgICAgICByZXBvcnRJbnRlcnNlY3Rpb25FcnJvcihwb3MsICJub3QuYW4uaW50Zi5jb21wb25lbnQiLCBib3VuZFN5bSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIHRhcmdldCAhPSBudWxsID8KICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0IDoKICAgICAgICAgICAgICAgICAgICAgICAgaWN0LmdldEV4cGxpY2l0Q29tcG9uZW50cygpLmhlYWQ7IC8vZXJyb3IgcmVjb3ZlcnkKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHJpdmF0ZSBUeXBlU3ltYm9sIG1ha2VOb3Rpb25hbEludGVyZmFjZShJbnRlcnNlY3Rpb25DbGFzc1R5cGUgaWN0KSB7CiAgICAgICAgICAgICAgICBMaXN0QnVmZmVyPFR5cGU+IHRhcmdzID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgICAgICAgICAgTGlzdEJ1ZmZlcjxUeXBlPiBzdXBlcnR5cGVzID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgICAgICAgICAgZm9yIChUeXBlIGkgOiBpY3QuaW50ZXJmYWNlc19maWVsZCkgewogICAgICAgICAgICAgICAgICAgIGlmIChpLmlzUGFyYW1ldGVyaXplZCgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdzLmFwcGVuZExpc3QoaS50c3ltLnR5cGUuYWxscGFyYW1zKCkpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBzdXBlcnR5cGVzLmFwcGVuZChpLnRzeW0udHlwZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBJbnRlcnNlY3Rpb25DbGFzc1R5cGUgbm90aW9uYWxJbnRmID0gdHlwZXMubWFrZUludGVyc2VjdGlvblR5cGUoc3VwZXJ0eXBlcy50b0xpc3QoKSk7CiAgICAgICAgICAgICAgICBub3Rpb25hbEludGYuYWxscGFyYW1zX2ZpZWxkID0gdGFyZ3MudG9MaXN0KCk7CiAgICAgICAgICAgICAgICBub3Rpb25hbEludGYudHN5bS5mbGFnc19maWVsZCB8PSBJTlRFUkZBQ0U7CiAgICAgICAgICAgICAgICByZXR1cm4gbm90aW9uYWxJbnRmLnRzeW07CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHByaXZhdGUgdm9pZCByZXBvcnRJbnRlcnNlY3Rpb25FcnJvcihEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBTdHJpbmcga2V5LCBPYmplY3QuLi4gYXJncykgewogICAgICAgICAgICAgICAgcmVzdWx0SW5mby5jaGVja0NvbnRleHQucmVwb3J0KHBvcywgZGlhZ3MuZnJhZ21lbnQoImJhZC5pbnRlcnNlY3Rpb24udGFyZ2V0LmZvci5mdW5jdGlvbmFsLmV4cHIiLAogICAgICAgICAgICAgICAgICAgICAgICBkaWFncy5mcmFnbWVudChrZXksIGFyZ3MpKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9OwoKICAgICAgICBwcml2YXRlIFR5cGUgZmFsbGJhY2tEZXNjcmlwdG9yVHlwZShKQ0V4cHJlc3Npb24gdHJlZSkgewogICAgICAgICAgICBzd2l0Y2ggKHRyZWUuZ2V0VGFnKCkpIHsKICAgICAgICAgICAgICAgIGNhc2UgTEFNQkRBOgogICAgICAgICAgICAgICAgICAgIEpDTGFtYmRhIGxhbWJkYSA9IChKQ0xhbWJkYSl0cmVlOwogICAgICAgICAgICAgICAgICAgIExpc3Q8VHlwZT4gYXJndHlwZXMgPSBMaXN0Lm5pbCgpOwogICAgICAgICAgICAgICAgICAgIGZvciAoSkNWYXJpYWJsZURlY2wgcGFyYW0gOiBsYW1iZGEucGFyYW1zKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGFyZ3R5cGVzID0gcGFyYW0udmFydHlwZSAhPSBudWxsID8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmd0eXBlcy5hcHBlbmQocGFyYW0udmFydHlwZS50eXBlKSA6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJndHlwZXMuYXBwZW5kKHN5bXMuZXJyVHlwZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgTWV0aG9kVHlwZShhcmd0eXBlcywgVHlwZS5yZWNvdmVyeVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0Lm9mKHN5bXMudGhyb3dhYmxlVHlwZSksIHN5bXMubWV0aG9kQ2xhc3MpOwogICAgICAgICAgICAgICAgY2FzZSBSRUZFUkVOQ0U6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBNZXRob2RUeXBlKExpc3QubmlsKCksIFR5cGUucmVjb3ZlcnlUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgTGlzdC5vZihzeW1zLnRocm93YWJsZVR5cGUpLCBzeW1zLm1ldGhvZENsYXNzKTsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgQXNzZXJ0LmVycm9yKCJDYW5ub3QgZ2V0IGhlcmUhIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIHZvaWQgY2hlY2tBY2Nlc3NpYmxlVHlwZXMoZmluYWwgRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcywgZmluYWwgRW52PEF0dHJDb250ZXh0PiBlbnYsCiAgICAgICAgICAgICAgICBmaW5hbCBJbmZlcmVuY2VDb250ZXh0IGluZmVyZW5jZUNvbnRleHQsIGZpbmFsIFR5cGUuLi4gdHMpIHsKICAgICAgICAgICAgY2hlY2tBY2Nlc3NpYmxlVHlwZXMocG9zLCBlbnYsIGluZmVyZW5jZUNvbnRleHQsIExpc3QuZnJvbSh0cykpOwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSB2b2lkIGNoZWNrQWNjZXNzaWJsZVR5cGVzKGZpbmFsIERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIGZpbmFsIEVudjxBdHRyQ29udGV4dD4gZW52LAogICAgICAgICAgICAgICAgZmluYWwgSW5mZXJlbmNlQ29udGV4dCBpbmZlcmVuY2VDb250ZXh0LCBmaW5hbCBMaXN0PFR5cGU+IHRzKSB7CiAgICAgICAgICAgIGlmIChpbmZlcmVuY2VDb250ZXh0LmZyZWUodHMpKSB7CiAgICAgICAgICAgICAgICBpbmZlcmVuY2VDb250ZXh0LmFkZEZyZWVUeXBlTGlzdGVuZXIodHMsCiAgICAgICAgICAgICAgICAgICAgICAgIHNvbHZlZENvbnRleHQgLT4gY2hlY2tBY2Nlc3NpYmxlVHlwZXMocG9zLCBlbnYsIHNvbHZlZENvbnRleHQsIHNvbHZlZENvbnRleHQuYXNJbnN0VHlwZXModHMpKSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBmb3IgKFR5cGUgdCA6IHRzKSB7CiAgICAgICAgICAgICAgICAgICAgcnMuY2hlY2tBY2Nlc3NpYmxlVHlwZShlbnYsIHQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBMYW1iZGEvbWV0aG9kIHJlZmVyZW5jZSBoYXZlIGEgc3BlY2lhbCBjaGVjayBjb250ZXh0IHRoYXQgZW5zdXJlcwogICAgICAgICAqIHRoYXQgaS5lLiBhIGxhbWJkYSByZXR1cm4gdHlwZSBpcyBjb21wYXRpYmxlIHdpdGggdGhlIGV4cGVjdGVkCiAgICAgICAgICogdHlwZSBhY2NvcmRpbmcgdG8gYm90aCB0aGUgaW5oZXJpdGVkIGNvbnRleHQgYW5kIHRoZSBhc3NpZ25tZW50CiAgICAgICAgICogY29udGV4dC4KICAgICAgICAgKi8KICAgICAgICBjbGFzcyBGdW5jdGlvbmFsUmV0dXJuQ29udGV4dCBleHRlbmRzIENoZWNrLk5lc3RlZENoZWNrQ29udGV4dCB7CgogICAgICAgICAgICBGdW5jdGlvbmFsUmV0dXJuQ29udGV4dChDaGVja0NvbnRleHQgZW5jbG9zaW5nQ29udGV4dCkgewogICAgICAgICAgICAgICAgc3VwZXIoZW5jbG9zaW5nQ29udGV4dCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgYm9vbGVhbiBjb21wYXRpYmxlKFR5cGUgZm91bmQsIFR5cGUgcmVxLCBXYXJuZXIgd2FybikgewogICAgICAgICAgICAgICAgLy9yZXR1cm4gdHlwZSBtdXN0IGJlIGNvbXBhdGlibGUgaW4gYm90aCBjdXJyZW50IGNvbnRleHQgYW5kIGFzc2lnbm1lbnQgY29udGV4dAogICAgICAgICAgICAgICAgcmV0dXJuIGNoay5iYXNpY0hhbmRsZXIuY29tcGF0aWJsZShpbmZlcmVuY2VDb250ZXh0KCkuYXNVbmRldFZhcihmb3VuZCksIGluZmVyZW5jZUNvbnRleHQoKS5hc1VuZGV0VmFyKHJlcSksIHdhcm4pOwogICAgICAgICAgICB9CgogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHVibGljIHZvaWQgcmVwb3J0KERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIEpDRGlhZ25vc3RpYyBkZXRhaWxzKSB7CiAgICAgICAgICAgICAgICBlbmNsb3NpbmdDb250ZXh0LnJlcG9ydChwb3MsIGRpYWdzLmZyYWdtZW50KCJpbmNvbXBhdGlibGUucmV0LnR5cGUuaW4ubGFtYmRhIiwgZGV0YWlscykpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBjbGFzcyBFeHByZXNzaW9uTGFtYmRhUmV0dXJuQ29udGV4dCBleHRlbmRzIEZ1bmN0aW9uYWxSZXR1cm5Db250ZXh0IHsKCiAgICAgICAgICAgIEpDRXhwcmVzc2lvbiBleHByOwogICAgICAgICAgICBib29sZWFuIGV4cFN0bXRFeHBlY3RlZDsKCiAgICAgICAgICAgIEV4cHJlc3Npb25MYW1iZGFSZXR1cm5Db250ZXh0KEpDRXhwcmVzc2lvbiBleHByLCBDaGVja0NvbnRleHQgZW5jbG9zaW5nQ29udGV4dCkgewogICAgICAgICAgICAgICAgc3VwZXIoZW5jbG9zaW5nQ29udGV4dCk7CiAgICAgICAgICAgICAgICB0aGlzLmV4cHIgPSBleHByOwogICAgICAgICAgICB9CgogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHVibGljIHZvaWQgcmVwb3J0KERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIEpDRGlhZ25vc3RpYyBkZXRhaWxzKSB7CiAgICAgICAgICAgICAgICBpZiAoZXhwU3RtdEV4cGVjdGVkKSB7CiAgICAgICAgICAgICAgICAgICAgZW5jbG9zaW5nQ29udGV4dC5yZXBvcnQocG9zLCBkaWFncy5mcmFnbWVudChGcmFnbWVudHMuU3RhdEV4cHJFeHBlY3RlZCkpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBzdXBlci5yZXBvcnQocG9zLCBkZXRhaWxzKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHB1YmxpYyBib29sZWFuIGNvbXBhdGlibGUoVHlwZSBmb3VuZCwgVHlwZSByZXEsIFdhcm5lciB3YXJuKSB7CiAgICAgICAgICAgICAgICAvL2Egdm9pZCByZXR1cm4gaXMgY29tcGF0aWJsZSB3aXRoIGFuIGV4cHJlc3Npb24gc3RhdGVtZW50IGxhbWJkYQogICAgICAgICAgICAgICAgaWYgKHJlcS5oYXNUYWcoVk9JRCkpIHsKICAgICAgICAgICAgICAgICAgICBleHBTdG10RXhwZWN0ZWQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBUcmVlSW5mby5pc0V4cHJlc3Npb25TdGF0ZW1lbnQoZXhwcik7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBzdXBlci5jb21wYXRpYmxlKGZvdW5kLCByZXEsIHdhcm4pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBSZXN1bHRJbmZvIGxhbWJkYUJvZHlSZXN1bHQoSkNMYW1iZGEgdGhhdCwgVHlwZSBkZXNjcmlwdG9yLCBSZXN1bHRJbmZvIHJlc3VsdEluZm8pIHsKICAgICAgICAgICAgRnVuY3Rpb25hbFJldHVybkNvbnRleHQgZnVuY0NvbnRleHQgPSB0aGF0LmdldEJvZHlLaW5kKCkgPT0gSkNMYW1iZGEuQm9keUtpbmQuRVhQUkVTU0lPTiA/CiAgICAgICAgICAgICAgICAgICAgbmV3IEV4cHJlc3Npb25MYW1iZGFSZXR1cm5Db250ZXh0KChKQ0V4cHJlc3Npb24pdGhhdC5nZXRCb2R5KCksIHJlc3VsdEluZm8uY2hlY2tDb250ZXh0KSA6CiAgICAgICAgICAgICAgICAgICAgbmV3IEZ1bmN0aW9uYWxSZXR1cm5Db250ZXh0KHJlc3VsdEluZm8uY2hlY2tDb250ZXh0KTsKCiAgICAgICAgICAgIHJldHVybiBkZXNjcmlwdG9yLmdldFJldHVyblR5cGUoKSA9PSBUeXBlLnJlY292ZXJ5VHlwZSA/CiAgICAgICAgICAgICAgICAgICAgcmVjb3ZlcnlJbmZvIDoKICAgICAgICAgICAgICAgICAgICBuZXcgUmVzdWx0SW5mbyhLaW5kU2VsZWN0b3IuVkFMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVzY3JpcHRvci5nZXRSZXR1cm5UeXBlKCksIGZ1bmNDb250ZXh0KTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICogTGFtYmRhIGNvbXBhdGliaWxpdHkuIENoZWNrIHRoYXQgZ2l2ZW4gcmV0dXJuIHR5cGVzLCB0aHJvd24gdHlwZXMsIHBhcmFtZXRlciB0eXBlcwogICAgICAgICogYXJlIGNvbXBhdGlibGUgd2l0aCB0aGUgZXhwZWN0ZWQgZnVuY3Rpb25hbCBpbnRlcmZhY2UgZGVzY3JpcHRvci4gVGhpcyBtZWFucyB0aGF0OgogICAgICAgICogKGkpIHBhcmFtZXRlciB0eXBlcyBtdXN0IGJlIGlkZW50aWNhbCB0byB0aG9zZSBvZiB0aGUgdGFyZ2V0IGRlc2NyaXB0b3I7IChpaSkgcmV0dXJuCiAgICAgICAgKiB0eXBlcyBtdXN0IGJlIGNvbXBhdGlibGUgd2l0aCB0aGUgcmV0dXJuIHR5cGUgb2YgdGhlIGV4cGVjdGVkIGRlc2NyaXB0b3IuCiAgICAgICAgKi8KICAgICAgICB2b2lkIGNoZWNrTGFtYmRhQ29tcGF0aWJsZShKQ0xhbWJkYSB0cmVlLCBUeXBlIGRlc2NyaXB0b3IsIENoZWNrQ29udGV4dCBjaGVja0NvbnRleHQpIHsKICAgICAgICAgICAgVHlwZSByZXR1cm5UeXBlID0gY2hlY2tDb250ZXh0LmluZmVyZW5jZUNvbnRleHQoKS5hc1VuZGV0VmFyKGRlc2NyaXB0b3IuZ2V0UmV0dXJuVHlwZSgpKTsKCiAgICAgICAgICAgIC8vcmV0dXJuIHZhbHVlcyBoYXZlIGFscmVhZHkgYmVlbiBjaGVja2VkIC0gYnV0IGlmIGxhbWJkYSBoYXMgbm8gcmV0dXJuCiAgICAgICAgICAgIC8vdmFsdWVzLCB3ZSBtdXN0IGVuc3VyZSB0aGF0IHZvaWQvdmFsdWUgY29tcGF0aWJpbGl0eSBpcyBjb3JyZWN0OwogICAgICAgICAgICAvL3RoaXMgYW1vdW50cyBhdCBjaGVja2luZyB0aGF0LCBpZiBhIGxhbWJkYSBib2R5IGNhbiBjb21wbGV0ZSBub3JtYWxseSwKICAgICAgICAgICAgLy90aGUgZGVzY3JpcHRvcidzIHJldHVybiB0eXBlIG11c3QgYmUgdm9pZAogICAgICAgICAgICBpZiAodHJlZS5nZXRCb2R5S2luZCgpID09IEpDTGFtYmRhLkJvZHlLaW5kLlNUQVRFTUVOVCAmJiB0cmVlLmNhbkNvbXBsZXRlTm9ybWFsbHkgJiYKICAgICAgICAgICAgICAgICAgICAhcmV0dXJuVHlwZS5oYXNUYWcoVk9JRCkgJiYgcmV0dXJuVHlwZSAhPSBUeXBlLnJlY292ZXJ5VHlwZSkgewogICAgICAgICAgICAgICAgY2hlY2tDb250ZXh0LnJlcG9ydCh0cmVlLCBkaWFncy5mcmFnbWVudCgiaW5jb21wYXRpYmxlLnJldC50eXBlLmluLmxhbWJkYSIsCiAgICAgICAgICAgICAgICAgICAgICAgIGRpYWdzLmZyYWdtZW50KCJtaXNzaW5nLnJldC52YWwiLCByZXR1cm5UeXBlKSkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBMaXN0PFR5cGU+IGFyZ1R5cGVzID0gY2hlY2tDb250ZXh0LmluZmVyZW5jZUNvbnRleHQoKS5hc1VuZGV0VmFycyhkZXNjcmlwdG9yLmdldFBhcmFtZXRlclR5cGVzKCkpOwogICAgICAgICAgICBpZiAoIXR5cGVzLmlzU2FtZVR5cGVzKGFyZ1R5cGVzLCBUcmVlSW5mby50eXBlcyh0cmVlLnBhcmFtcykpKSB7CiAgICAgICAgICAgICAgICBjaGVja0NvbnRleHQucmVwb3J0KHRyZWUsIGRpYWdzLmZyYWdtZW50KCJpbmNvbXBhdGlibGUuYXJnLnR5cGVzLmluLmxhbWJkYSIpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLyogTWFwIHRvIGhvbGQgJ2Zha2UnIGNsaW5pdCBtZXRob2RzLiBJZiBhIGxhbWJkYSBpcyB1c2VkIHRvIGluaXRpYWxpemUgYQogICAgICAgICAqIHN0YXRpYyBmaWVsZCBhbmQgdGhhdCBsYW1iZGEgaGFzIHR5cGUgYW5ub3RhdGlvbnMsIHRoZXNlIGFubm90YXRpb25zIHdpbGwKICAgICAgICAgKiBhbHNvIGJlIHN0b3JlZCBhdCB0aGVzZSBmYWtlIGNsaW5pdCBtZXRob2RzLgogICAgICAgICAqCiAgICAgICAgICogTGFtYmRhVG9NZXRob2QgYWxzbyB1c2UgZmFrZSBjbGluaXQgbWV0aG9kcyBzbyB0aGV5IGNhbiBiZSByZXVzZWQuCiAgICAgICAgICogQWxzbyBhcyBMVE0gaXMgYSBwaGFzZSBzdWJzZXF1ZW50IHRvIGF0dHJpYnV0aW9uLCB0aGUgbWV0aG9kcyBmcm9tCiAgICAgICAgICogY2xpbml0cyBjYW4gYmUgc2FmZWx5IHJlbW92ZWQgYnkgTFRNIHRvIHNhdmUgbWVtb3J5LgogICAgICAgICAqLwogICAgICAgIHByaXZhdGUgTWFwPENsYXNzU3ltYm9sLCBNZXRob2RTeW1ib2w+IGNsaW5pdHMgPSBuZXcgSGFzaE1hcDw+KCk7CgogICAgICAgIHB1YmxpYyBNZXRob2RTeW1ib2wgcmVtb3ZlQ2xpbml0KENsYXNzU3ltYm9sIHN5bSkgewogICAgICAgICAgICByZXR1cm4gY2xpbml0cy5yZW1vdmUoc3ltKTsKICAgICAgICB9CgogICAgICAgIC8qIFRoaXMgbWV0aG9kIHJldHVybnMgYW4gZW52aXJvbm1lbnQgdG8gYmUgdXNlZCB0byBhdHRyaWJ1dGUgYSBsYW1iZGEKICAgICAgICAgKiBleHByZXNzaW9uLgogICAgICAgICAqCiAgICAgICAgICogVGhlIG93bmVyIG9mIHRoaXMgZW52aXJvbm1lbnQgaXMgYSBtZXRob2Qgc3ltYm9sLiBJZiB0aGUgY3VycmVudCBvd25lcgogICAgICAgICAqIGlzIG5vdCBhIG1ldGhvZCwgZm9yIGV4YW1wbGUgaWYgdGhlIGxhbWJkYSBpcyB1c2VkIHRvIGluaXRpYWxpemUKICAgICAgICAgKiBhIGZpZWxkLCB0aGVuIGlmIHRoZSBmaWVsZCBpczoKICAgICAgICAgKgogICAgICAgICAqIC0gYW4gaW5zdGFuY2UgZmllbGQsIHdlIHVzZSB0aGUgZmlyc3QgY29uc3RydWN0b3IuCiAgICAgICAgICogLSBhIHN0YXRpYyBmaWVsZCwgd2UgY3JlYXRlIGEgZmFrZSBjbGluaXQgbWV0aG9kLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBFbnY8QXR0ckNvbnRleHQ+IGxhbWJkYUVudihKQ0xhbWJkYSB0aGF0LCBFbnY8QXR0ckNvbnRleHQ+IGVudikgewogICAgICAgICAgICBFbnY8QXR0ckNvbnRleHQ+IGxhbWJkYUVudjsKICAgICAgICAgICAgU3ltYm9sIG93bmVyID0gZW52LmluZm8uc2NvcGUub3duZXI7CiAgICAgICAgICAgIGlmIChvd25lci5raW5kID09IFZBUiAmJiBvd25lci5vd25lci5raW5kID09IFRZUCkgewogICAgICAgICAgICAgICAgLy9maWVsZCBpbml0aWFsaXplcgogICAgICAgICAgICAgICAgQ2xhc3NTeW1ib2wgZW5jbENsYXNzID0gb3duZXIuZW5jbENsYXNzKCk7CiAgICAgICAgICAgICAgICBTeW1ib2wgbmV3U2NvcGVPd25lciA9IGVudi5pbmZvLnNjb3BlLm93bmVyOwogICAgICAgICAgICAgICAgLyogaWYgdGhlIGZpZWxkIGlzbid0IHN0YXRpYywgdGhlbiB3ZSBjYW4gZ2V0IHRoZSBmaXJzdCBjb25zdHJ1Y3RvcgogICAgICAgICAgICAgICAgICogYW5kIHVzZSBpdCBhcyB0aGUgb3duZXIgb2YgdGhlIGVudmlyb25tZW50LiBUaGlzIGlzIHdoYXQKICAgICAgICAgICAgICAgICAqIExUTSBjb2RlIGlzIGRvaW5nIHRvIGxvb2sgZm9yIHR5cGUgYW5ub3RhdGlvbnMgc28gd2UgYXJlIGZpbmUuCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIGlmICgob3duZXIuZmxhZ3MoKSAmIFNUQVRJQykgPT0gMCkgewogICAgICAgICAgICAgICAgICAgIGZvciAoU3ltYm9sIHMgOiBlbmNsQ2xhc3MubWVtYmVyc19maWVsZC5nZXRTeW1ib2xzQnlOYW1lKG5hbWVzLmluaXQpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIG5ld1Njb3BlT3duZXIgPSBzOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIC8qIGlmIHRoZSBmaWVsZCBpcyBzdGF0aWMgdGhlbiB3ZSBuZWVkIHRvIGNyZWF0ZSBhIGZha2UgY2xpbml0CiAgICAgICAgICAgICAgICAgICAgICogbWV0aG9kLCB0aGlzIG1ldGhvZCBjYW4gbGF0ZXIgYmUgcmV1c2VkIGJ5IExUTS4KICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICBNZXRob2RTeW1ib2wgY2xpbml0ID0gY2xpbml0cy5nZXQoZW5jbENsYXNzKTsKICAgICAgICAgICAgICAgICAgICBpZiAoY2xpbml0ID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgVHlwZSBjbGluaXRUeXBlID0gbmV3IE1ldGhvZFR5cGUoTGlzdC5uaWwoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeW1zLnZvaWRUeXBlLCBMaXN0Lm5pbCgpLCBzeW1zLm1ldGhvZENsYXNzKTsKICAgICAgICAgICAgICAgICAgICAgICAgY2xpbml0ID0gbmV3IE1ldGhvZFN5bWJvbChTVEFUSUMgfCBTWU5USEVUSUMgfCBQUklWQVRFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVzLmNsaW5pdCwgY2xpbml0VHlwZSwgZW5jbENsYXNzKTsKICAgICAgICAgICAgICAgICAgICAgICAgY2xpbml0LnBhcmFtcyA9IExpc3QubmlsKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGNsaW5pdHMucHV0KGVuY2xDbGFzcywgY2xpbml0KTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgbmV3U2NvcGVPd25lciA9IGNsaW5pdDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGxhbWJkYUVudiA9IGVudi5kdXAodGhhdCwgZW52LmluZm8uZHVwKGVudi5pbmZvLnNjb3BlLmR1cFVuc2hhcmVkKG5ld1Njb3BlT3duZXIpKSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBsYW1iZGFFbnYgPSBlbnYuZHVwKHRoYXQsIGVudi5pbmZvLmR1cChlbnYuaW5mby5zY29wZS5kdXAoKSkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBsYW1iZGFFbnY7CiAgICAgICAgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIHZvaWQgdmlzaXRSZWZlcmVuY2UoZmluYWwgSkNNZW1iZXJSZWZlcmVuY2UgdGhhdCkgewogICAgICAgIGlmIChwdCgpLmlzRXJyb25lb3VzKCkgfHwgKHB0KCkuaGFzVGFnKE5PTkUpICYmIHB0KCkgIT0gVHlwZS5yZWNvdmVyeVR5cGUpKSB7CiAgICAgICAgICAgIGlmIChwdCgpLmhhc1RhZyhOT05FKSkgewogICAgICAgICAgICAgICAgLy9tZXRob2QgcmVmZXJlbmNlIG9ubHkgYWxsb3dlZCBpbiBhc3NpZ25tZW50IG9yIG1ldGhvZCBpbnZvY2F0aW9uL2Nhc3QgY29udGV4dAogICAgICAgICAgICAgICAgbG9nLmVycm9yKHRoYXQucG9zKCksICJ1bmV4cGVjdGVkLm1yZWYiKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXN1bHQgPSB0aGF0LnR5cGUgPSB0eXBlcy5jcmVhdGVFcnJvclR5cGUocHQoKSk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgZmluYWwgRW52PEF0dHJDb250ZXh0PiBsb2NhbEVudiA9IGVudi5kdXAodGhhdCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgLy9hdHRyaWJ1dGUgbWVtYmVyIHJlZmVyZW5jZSBxdWFsaWZpZXIgLSBpZiB0aGlzIGlzIGEgY29uc3RydWN0b3IKICAgICAgICAgICAgLy9yZWZlcmVuY2UsIHRoZSBleHBlY3RlZCBraW5kIG11c3QgYmUgYSB0eXBlCiAgICAgICAgICAgIFR5cGUgZXhwclR5cGUgPSBhdHRyaWJUcmVlKHRoYXQuZXhwciwgZW52LCBtZW1iZXJSZWZlcmVuY2VRdWFsaWZpZXJSZXN1bHQodGhhdCkpOwoKICAgICAgICAgICAgaWYgKHRoYXQuZ2V0TW9kZSgpID09IEpDTWVtYmVyUmVmZXJlbmNlLlJlZmVyZW5jZU1vZGUuTkVXKSB7CiAgICAgICAgICAgICAgICBleHByVHlwZSA9IGNoay5jaGVja0NvbnN0cnVjdG9yUmVmVHlwZSh0aGF0LmV4cHIsIGV4cHJUeXBlKTsKICAgICAgICAgICAgICAgIGlmICghZXhwclR5cGUuaXNFcnJvbmVvdXMoKSAmJgogICAgICAgICAgICAgICAgICAgIGV4cHJUeXBlLmlzUmF3KCkgJiYKICAgICAgICAgICAgICAgICAgICB0aGF0LnR5cGVhcmdzICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICBsb2cuZXJyb3IodGhhdC5leHByLnBvcygpLCAiaW52YWxpZC5tcmVmIiwgS2luZHMua2luZE5hbWUodGhhdC5nZXRNb2RlKCkpLAogICAgICAgICAgICAgICAgICAgICAgICBkaWFncy5mcmFnbWVudCgibXJlZi5pbmZlci5hbmQuZXhwbGljaXQucGFyYW1zIikpOwogICAgICAgICAgICAgICAgICAgIGV4cHJUeXBlID0gdHlwZXMuY3JlYXRlRXJyb3JUeXBlKGV4cHJUeXBlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKGV4cHJUeXBlLmlzRXJyb25lb3VzKCkpIHsKICAgICAgICAgICAgICAgIC8vaWYgdGhlIHF1YWxpZmllciBleHByZXNzaW9uIGNvbnRhaW5zIHByb2JsZW1zLAogICAgICAgICAgICAgICAgLy9naXZlIHVwIGF0dHJpYnV0aW9uIG9mIG1ldGhvZCByZWZlcmVuY2UKICAgICAgICAgICAgICAgIHJlc3VsdCA9IHRoYXQudHlwZSA9IGV4cHJUeXBlOwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoVHJlZUluZm8uaXNTdGF0aWNTZWxlY3Rvcih0aGF0LmV4cHIsIG5hbWVzKSkgewogICAgICAgICAgICAgICAgLy9pZiB0aGUgcXVhbGlmaWVyIGlzIGEgdHlwZSwgdmFsaWRhdGUgaXQ7IHJhdyB3YXJuaW5nIGNoZWNrIGlzCiAgICAgICAgICAgICAgICAvL29taXR0ZWQgYXMgd2UgZG9uJ3Qga25vdyBhdCB0aGlzIHN0YWdlIGFzIHRvIHdoZXRoZXIgdGhpcyBpcyBhCiAgICAgICAgICAgICAgICAvL3JhdyBzZWxlY3RvciAoYmVjYXVzZSBvZiBpbmZlcmVuY2UpCiAgICAgICAgICAgICAgICBjaGsudmFsaWRhdGUodGhhdC5leHByLCBlbnYsIGZhbHNlKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIFN5bWJvbCBsaHNTeW0gPSBUcmVlSW5mby5zeW1ib2wodGhhdC5leHByKTsKICAgICAgICAgICAgICAgIGxvY2FsRW52LmluZm8uc2VsZWN0U3VwZXIgPSBsaHNTeW0gIT0gbnVsbCAmJiBsaHNTeW0ubmFtZSA9PSBuYW1lcy5fc3VwZXI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy9hdHRyaWIgdHlwZS1hcmd1bWVudHMKICAgICAgICAgICAgTGlzdDxUeXBlPiB0eXBlYXJndHlwZXMgPSBMaXN0Lm5pbCgpOwogICAgICAgICAgICBpZiAodGhhdC50eXBlYXJncyAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICB0eXBlYXJndHlwZXMgPSBhdHRyaWJUeXBlcyh0aGF0LnR5cGVhcmdzLCBsb2NhbEVudik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGJvb2xlYW4gaXNUYXJnZXRTZXJpYWxpemFibGUgPQogICAgICAgICAgICAgICAgICAgIHJlc3VsdEluZm8uY2hlY2tDb250ZXh0LmRlZmVycmVkQXR0ckNvbnRleHQoKS5tb2RlID09IERlZmVycmVkQXR0ci5BdHRyTW9kZS5DSEVDSyAmJgogICAgICAgICAgICAgICAgICAgIGlzU2VyaWFsaXphYmxlKHB0KCkpOwogICAgICAgICAgICBUYXJnZXRJbmZvIHRhcmdldEluZm8gPSBnZXRUYXJnZXRJbmZvKHRoYXQsIHJlc3VsdEluZm8sIG51bGwpOwogICAgICAgICAgICBUeXBlIGN1cnJlbnRUYXJnZXQgPSB0YXJnZXRJbmZvLnRhcmdldDsKICAgICAgICAgICAgVHlwZSBkZXNjID0gdGFyZ2V0SW5mby5kZXNjcmlwdG9yOwoKICAgICAgICAgICAgc2V0RnVuY3Rpb25hbEluZm8obG9jYWxFbnYsIHRoYXQsIHB0KCksIGRlc2MsIGN1cnJlbnRUYXJnZXQsIHJlc3VsdEluZm8uY2hlY2tDb250ZXh0KTsKICAgICAgICAgICAgTGlzdDxUeXBlPiBhcmd0eXBlcyA9IGRlc2MuZ2V0UGFyYW1ldGVyVHlwZXMoKTsKICAgICAgICAgICAgUmVzb2x2ZS5NZXRob2RDaGVjayByZWZlcmVuY2VDaGVjayA9IHJzLnJlc29sdmVNZXRob2RDaGVjazsKCiAgICAgICAgICAgIGlmIChyZXN1bHRJbmZvLmNoZWNrQ29udGV4dC5pbmZlcmVuY2VDb250ZXh0KCkuZnJlZShhcmd0eXBlcykpIHsKICAgICAgICAgICAgICAgIHJlZmVyZW5jZUNoZWNrID0gcnMubmV3IE1ldGhvZFJlZmVyZW5jZUNoZWNrKHJlc3VsdEluZm8uY2hlY2tDb250ZXh0LmluZmVyZW5jZUNvbnRleHQoKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIFBhaXI8U3ltYm9sLCBSZXNvbHZlLlJlZmVyZW5jZUxvb2t1cEhlbHBlcj4gcmVmUmVzdWx0ID0gbnVsbDsKICAgICAgICAgICAgTGlzdDxUeXBlPiBzYXZlZF91bmRldCA9IHJlc3VsdEluZm8uY2hlY2tDb250ZXh0LmluZmVyZW5jZUNvbnRleHQoKS5zYXZlKCk7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICByZWZSZXN1bHQgPSBycy5yZXNvbHZlTWVtYmVyUmVmZXJlbmNlKGxvY2FsRW52LCB0aGF0LCB0aGF0LmV4cHIudHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgdGhhdC5uYW1lLCBhcmd0eXBlcywgdHlwZWFyZ3R5cGVzLCByZWZlcmVuY2VDaGVjaywKICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0SW5mby5jaGVja0NvbnRleHQuaW5mZXJlbmNlQ29udGV4dCgpLCBycy5iYXNpY1JlZmVyZW5jZUNob29zZXIpOwogICAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAgICAgcmVzdWx0SW5mby5jaGVja0NvbnRleHQuaW5mZXJlbmNlQ29udGV4dCgpLnJvbGxiYWNrKHNhdmVkX3VuZGV0KTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgU3ltYm9sIHJlZlN5bSA9IHJlZlJlc3VsdC5mc3Q7CiAgICAgICAgICAgIFJlc29sdmUuUmVmZXJlbmNlTG9va3VwSGVscGVyIGxvb2t1cEhlbHBlciA9IHJlZlJlc3VsdC5zbmQ7CgogICAgICAgICAgICAvKiogdGhpcyBzd2l0Y2ggd2lsbCBuZWVkIHRvIGdvIGF3YXkgYW5kIGJlIHJlcGxhY2VkIGJ5IHRoZSBuZXcgUkVTT0xVVElPTl9UQVJHRVQgdGVzdGluZwogICAgICAgICAgICAgKiAgSkRLLTgwNzU1NDEKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGlmIChyZWZTeW0ua2luZCAhPSBNVEgpIHsKICAgICAgICAgICAgICAgIGJvb2xlYW4gdGFyZ2V0RXJyb3I7CiAgICAgICAgICAgICAgICBzd2l0Y2ggKHJlZlN5bS5raW5kKSB7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBBQlNFTlRfTVRIOgogICAgICAgICAgICAgICAgICAgIGNhc2UgTUlTU0lOR19FTkNMOgogICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXRFcnJvciA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICBjYXNlIFdST05HX01USDoKICAgICAgICAgICAgICAgICAgICBjYXNlIFdST05HX01USFM6CiAgICAgICAgICAgICAgICAgICAgY2FzZSBBTUJJR1VPVVM6CiAgICAgICAgICAgICAgICAgICAgY2FzZSBISURERU46CiAgICAgICAgICAgICAgICAgICAgY2FzZSBTVEFUSUNFUlI6CiAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldEVycm9yID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgICAgQXNzZXJ0LmVycm9yKCJ1bmV4cGVjdGVkIHJlc3VsdCBraW5kICIgKyByZWZTeW0ua2luZCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldEVycm9yID0gZmFsc2U7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgSkNEaWFnbm9zdGljIGRldGFpbHNEaWFnID0gKChSZXNvbHZlLlJlc29sdmVFcnJvcilyZWZTeW0uYmFzZVN5bWJvbCgpKS5nZXREaWFnbm9zdGljKEpDRGlhZ25vc3RpYy5EaWFnbm9zdGljVHlwZS5GUkFHTUVOVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGF0LCBleHByVHlwZS50c3ltLCBleHByVHlwZSwgdGhhdC5uYW1lLCBhcmd0eXBlcywgdHlwZWFyZ3R5cGVzKTsKCiAgICAgICAgICAgICAgICBKQ0RpYWdub3N0aWMuRGlhZ25vc3RpY1R5cGUgZGlhZ0tpbmQgPSB0YXJnZXRFcnJvciA/CiAgICAgICAgICAgICAgICAgICAgICAgIEpDRGlhZ25vc3RpYy5EaWFnbm9zdGljVHlwZS5GUkFHTUVOVCA6IEpDRGlhZ25vc3RpYy5EaWFnbm9zdGljVHlwZS5FUlJPUjsKCiAgICAgICAgICAgICAgICBKQ0RpYWdub3N0aWMgZGlhZyA9IGRpYWdzLmNyZWF0ZShkaWFnS2luZCwgbG9nLmN1cnJlbnRTb3VyY2UoKSwgdGhhdCwKICAgICAgICAgICAgICAgICAgICAgICAgImludmFsaWQubXJlZiIsIEtpbmRzLmtpbmROYW1lKHRoYXQuZ2V0TW9kZSgpKSwgZGV0YWlsc0RpYWcpOwoKICAgICAgICAgICAgICAgIGlmICh0YXJnZXRFcnJvciAmJiBjdXJyZW50VGFyZ2V0ID09IFR5cGUucmVjb3ZlcnlUeXBlKSB7CiAgICAgICAgICAgICAgICAgICAgLy9hIHRhcmdldCBlcnJvciBkb2Vzbid0IG1ha2Ugc2Vuc2UgZHVyaW5nIHJlY292ZXJ5IHN0YWdlCiAgICAgICAgICAgICAgICAgICAgLy9hcyB3ZSBkb24ndCBrbm93IHdoYXQgYWN0dWFsIHBhcmFtZXRlciB0eXBlcyBhcmUKICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSB0aGF0LnR5cGUgPSBjdXJyZW50VGFyZ2V0OwogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHRhcmdldEVycm9yKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdEluZm8uY2hlY2tDb250ZXh0LnJlcG9ydCh0aGF0LCBkaWFnKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBsb2cucmVwb3J0KGRpYWcpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSB0aGF0LnR5cGUgPSB0eXBlcy5jcmVhdGVFcnJvclR5cGUoY3VycmVudFRhcmdldCk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICB0aGF0LnN5bSA9IHJlZlN5bS5iYXNlU3ltYm9sKCk7CiAgICAgICAgICAgIHRoYXQua2luZCA9IGxvb2t1cEhlbHBlci5yZWZlcmVuY2VLaW5kKHRoYXQuc3ltKTsKICAgICAgICAgICAgdGhhdC5vd25lckFjY2Vzc2libGUgPSBycy5pc0FjY2Vzc2libGUobG9jYWxFbnYsIHRoYXQuc3ltLmVuY2xDbGFzcygpKTsKCiAgICAgICAgICAgIGlmIChkZXNjLmdldFJldHVyblR5cGUoKSA9PSBUeXBlLnJlY292ZXJ5VHlwZSkgewogICAgICAgICAgICAgICAgLy8gc3RvcCBoZXJlCiAgICAgICAgICAgICAgICByZXN1bHQgPSB0aGF0LnR5cGUgPSBjdXJyZW50VGFyZ2V0OwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoIWVudi5pbmZvLmlzU3BlY3VsYXRpdmUgJiYgdGhhdC5nZXRNb2RlKCkgPT0gSkNNZW1iZXJSZWZlcmVuY2UuUmVmZXJlbmNlTW9kZS5ORVcpIHsKICAgICAgICAgICAgICAgIFR5cGUgZW5jbG9zaW5nVHlwZSA9IGV4cHJUeXBlLmdldEVuY2xvc2luZ1R5cGUoKTsKICAgICAgICAgICAgICAgIGlmIChlbmNsb3NpbmdUeXBlICE9IG51bGwgJiYgZW5jbG9zaW5nVHlwZS5oYXNUYWcoQ0xBU1MpKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gQ2hlY2sgZm9yIHRoZSBleGlzdGVuY2Ugb2YgYW4gYXByb3ByaWF0ZSBvdXRlciBpbnN0YW5jZQogICAgICAgICAgICAgICAgICAgIHJzLnJlc29sdmVJbXBsaWNpdFRoaXModGhhdC5wb3MoKSwgZW52LCBleHByVHlwZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChyZXN1bHRJbmZvLmNoZWNrQ29udGV4dC5kZWZlcnJlZEF0dHJDb250ZXh0KCkubW9kZSA9PSBBdHRyTW9kZS5DSEVDSykgewoKICAgICAgICAgICAgICAgIGlmICh0aGF0LmdldE1vZGUoKSA9PSBSZWZlcmVuY2VNb2RlLklOVk9LRSAmJgogICAgICAgICAgICAgICAgICAgICAgICBUcmVlSW5mby5pc1N0YXRpY1NlbGVjdG9yKHRoYXQuZXhwciwgbmFtZXMpICYmCiAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQua2luZC5pc1VuYm91bmQoKSAmJgogICAgICAgICAgICAgICAgICAgICAgICAhZGVzYy5nZXRQYXJhbWV0ZXJUeXBlcygpLmhlYWQuaXNQYXJhbWV0ZXJpemVkKCkpIHsKICAgICAgICAgICAgICAgICAgICBjaGsuY2hlY2tSYXcodGhhdC5leHByLCBsb2NhbEVudik7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKHRoYXQuc3ltLmlzU3RhdGljKCkgJiYgVHJlZUluZm8uaXNTdGF0aWNTZWxlY3Rvcih0aGF0LmV4cHIsIG5hbWVzKSAmJgogICAgICAgICAgICAgICAgICAgICAgICBleHByVHlwZS5nZXRUeXBlQXJndW1lbnRzKCkubm9uRW1wdHkoKSkgewogICAgICAgICAgICAgICAgICAgIC8vc3RhdGljIHJlZiB3aXRoIGNsYXNzIHR5cGUtYXJncwogICAgICAgICAgICAgICAgICAgIGxvZy5lcnJvcih0aGF0LmV4cHIucG9zKCksICJpbnZhbGlkLm1yZWYiLCBLaW5kcy5raW5kTmFtZSh0aGF0LmdldE1vZGUoKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaWFncy5mcmFnbWVudCgic3RhdGljLm1yZWYud2l0aC50YXJncyIpKTsKICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSB0aGF0LnR5cGUgPSB0eXBlcy5jcmVhdGVFcnJvclR5cGUoY3VycmVudFRhcmdldCk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmICghcmVmU3ltLmlzU3RhdGljKCkgJiYgdGhhdC5raW5kID09IEpDTWVtYmVyUmVmZXJlbmNlLlJlZmVyZW5jZUtpbmQuU1VQRVIpIHsKICAgICAgICAgICAgICAgICAgICAvLyBDaGVjayB0aGF0IHN1cGVyLXF1YWxpZmllZCBzeW1ib2xzIGFyZSBub3QgYWJzdHJhY3QgKEpMUykKICAgICAgICAgICAgICAgICAgICBycy5jaGVja05vbkFic3RyYWN0KHRoYXQucG9zKCksIHRoYXQuc3ltKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoaXNUYXJnZXRTZXJpYWxpemFibGUpIHsKICAgICAgICAgICAgICAgICAgICBjaGsuY2hlY2tBY2Nlc3NGcm9tU2VyaWFsaXphYmxlRWxlbWVudCh0aGF0LCB0cnVlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgUmVzdWx0SW5mbyBjaGVja0luZm8gPQogICAgICAgICAgICAgICAgICAgIHJlc3VsdEluZm8uZHVwKG5ld01ldGhvZFRlbXBsYXRlKAogICAgICAgICAgICAgICAgICAgICAgICBkZXNjLmdldFJldHVyblR5cGUoKS5oYXNUYWcoVk9JRCkgPyBUeXBlLm5vVHlwZSA6IGRlc2MuZ2V0UmV0dXJuVHlwZSgpLAogICAgICAgICAgICAgICAgICAgICAgICB0aGF0LmtpbmQuaXNVbmJvdW5kKCkgPyBhcmd0eXBlcy50YWlsIDogYXJndHlwZXMsIHR5cGVhcmd0eXBlcyksCiAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBGdW5jdGlvbmFsUmV0dXJuQ29udGV4dChyZXN1bHRJbmZvLmNoZWNrQ29udGV4dCksIENoZWNrTW9kZS5OT19UUkVFX1VQREFURSk7CgogICAgICAgICAgICBUeXBlIHJlZlR5cGUgPSBjaGVja0lkKHRoYXQsIGxvb2t1cEhlbHBlci5zaXRlLCByZWZTeW0sIGxvY2FsRW52LCBjaGVja0luZm8pOwoKICAgICAgICAgICAgaWYgKHRoYXQua2luZC5pc1VuYm91bmQoKSAmJgogICAgICAgICAgICAgICAgICAgIHJlc3VsdEluZm8uY2hlY2tDb250ZXh0LmluZmVyZW5jZUNvbnRleHQoKS5mcmVlKGFyZ3R5cGVzLmhlYWQpKSB7CiAgICAgICAgICAgICAgICAvL3JlLWdlbmVyYXRlIGluZmVyZW5jZSBjb25zdHJhaW50cyBmb3IgdW5ib3VuZCByZWNlaXZlcgogICAgICAgICAgICAgICAgaWYgKCF0eXBlcy5pc1N1YnR5cGUocmVzdWx0SW5mby5jaGVja0NvbnRleHQuaW5mZXJlbmNlQ29udGV4dCgpLmFzVW5kZXRWYXIoYXJndHlwZXMuaGVhZCksIGV4cHJUeXBlKSkgewogICAgICAgICAgICAgICAgICAgIC8vY2Fubm90IGhhcHBlbiBhcyB0aGlzIGhhcyBhbHJlYWR5IGJlZW4gY2hlY2tlZCAtIHdlIGp1c3QgbmVlZAogICAgICAgICAgICAgICAgICAgIC8vdG8gcmVnZW5lcmF0ZSB0aGUgaW5mZXJlbmNlIGNvbnN0cmFpbnRzLCBhcyB0aGF0IGhhcyBiZWVuIGxvc3QKICAgICAgICAgICAgICAgICAgICAvL2FzIGEgcmVzdWx0IG9mIHRoZSBjYWxsIHRvIGluZmVyZW5jZUNvbnRleHQuc2F2ZSgpCiAgICAgICAgICAgICAgICAgICAgQXNzZXJ0LmVycm9yKCJDYW4ndCBnZXQgaGVyZSIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoIXJlZlR5cGUuaXNFcnJvbmVvdXMoKSkgewogICAgICAgICAgICAgICAgcmVmVHlwZSA9IHR5cGVzLmNyZWF0ZU1ldGhvZFR5cGVXaXRoUmV0dXJuKHJlZlR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgIGFkanVzdE1ldGhvZFJldHVyblR5cGUocmVmU3ltLCBsb29rdXBIZWxwZXIuc2l0ZSwgdGhhdC5uYW1lLCBjaGVja0luZm8ucHQuZ2V0UGFyYW1ldGVyVHlwZXMoKSwgcmVmVHlwZS5nZXRSZXR1cm5UeXBlKCkpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy9nbyBhaGVhZCB3aXRoIHN0YW5kYXJkIG1ldGhvZCByZWZlcmVuY2UgY29tcGF0aWJpbGl0eSBjaGVjayAtIG5vdGUgdGhhdCBwYXJhbSBjaGVjawogICAgICAgICAgICAvL2lzIGEgbm8tb3AgKGFzIHRoaXMgaGFzIGJlZW4gdGFrZW4gY2FyZSBkdXJpbmcgbWV0aG9kIGFwcGxpY2FiaWxpdHkpCiAgICAgICAgICAgIGJvb2xlYW4gaXNTcGVjdWxhdGl2ZVJvdW5kID0KICAgICAgICAgICAgICAgICAgICByZXN1bHRJbmZvLmNoZWNrQ29udGV4dC5kZWZlcnJlZEF0dHJDb250ZXh0KCkubW9kZSA9PSBEZWZlcnJlZEF0dHIuQXR0ck1vZGUuU1BFQ1VMQVRJVkU7CgogICAgICAgICAgICB0aGF0LnR5cGUgPSBjdXJyZW50VGFyZ2V0OyAvL2F2b2lkcyByZWNvdmVyeSBhdCB0aGlzIHN0YWdlCiAgICAgICAgICAgIGNoZWNrUmVmZXJlbmNlQ29tcGF0aWJsZSh0aGF0LCBkZXNjLCByZWZUeXBlLCByZXN1bHRJbmZvLmNoZWNrQ29udGV4dCwgaXNTcGVjdWxhdGl2ZVJvdW5kKTsKICAgICAgICAgICAgaWYgKCFpc1NwZWN1bGF0aXZlUm91bmQpIHsKICAgICAgICAgICAgICAgIGNoZWNrQWNjZXNzaWJsZVR5cGVzKHRoYXQsIGxvY2FsRW52LCByZXN1bHRJbmZvLmNoZWNrQ29udGV4dC5pbmZlcmVuY2VDb250ZXh0KCksIGRlc2MsIGN1cnJlbnRUYXJnZXQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJlc3VsdCA9IGNoZWNrKHRoYXQsIGN1cnJlbnRUYXJnZXQsIEtpbmRTZWxlY3Rvci5WQUwsIHJlc3VsdEluZm8pOwogICAgICAgIH0gY2F0Y2ggKFR5cGVzLkZ1bmN0aW9uRGVzY3JpcHRvckxvb2t1cEVycm9yIGV4KSB7CiAgICAgICAgICAgIEpDRGlhZ25vc3RpYyBjYXVzZSA9IGV4LmdldERpYWdub3N0aWMoKTsKICAgICAgICAgICAgcmVzdWx0SW5mby5jaGVja0NvbnRleHQucmVwb3J0KHRoYXQsIGNhdXNlKTsKICAgICAgICAgICAgcmVzdWx0ID0gdGhhdC50eXBlID0gdHlwZXMuY3JlYXRlRXJyb3JUeXBlKHB0KCkpOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgfQogICAgLy93aGVyZQogICAgICAgIFJlc3VsdEluZm8gbWVtYmVyUmVmZXJlbmNlUXVhbGlmaWVyUmVzdWx0KEpDTWVtYmVyUmVmZXJlbmNlIHRyZWUpIHsKICAgICAgICAgICAgLy9pZiB0aGlzIGlzIGEgY29uc3RydWN0b3IgcmVmZXJlbmNlLCB0aGUgZXhwZWN0ZWQga2luZCBtdXN0IGJlIGEgdHlwZQogICAgICAgICAgICByZXR1cm4gbmV3IFJlc3VsdEluZm8odHJlZS5nZXRNb2RlKCkgPT0gUmVmZXJlbmNlTW9kZS5JTlZPS0UgPwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgS2luZFNlbGVjdG9yLlZBTF9UWVAgOiBLaW5kU2VsZWN0b3IuVFlQLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVHlwZS5ub1R5cGUpOwogICAgICAgIH0KCgogICAgQFN1cHByZXNzV2FybmluZ3MoImZhbGx0aHJvdWdoIikKICAgIHZvaWQgY2hlY2tSZWZlcmVuY2VDb21wYXRpYmxlKEpDTWVtYmVyUmVmZXJlbmNlIHRyZWUsIFR5cGUgZGVzY3JpcHRvciwgVHlwZSByZWZUeXBlLCBDaGVja0NvbnRleHQgY2hlY2tDb250ZXh0LCBib29sZWFuIHNwZWN1bGF0aXZlQXR0cikgewogICAgICAgIEluZmVyZW5jZUNvbnRleHQgaW5mZXJlbmNlQ29udGV4dCA9IGNoZWNrQ29udGV4dC5pbmZlcmVuY2VDb250ZXh0KCk7CiAgICAgICAgVHlwZSByZXR1cm5UeXBlID0gaW5mZXJlbmNlQ29udGV4dC5hc1VuZGV0VmFyKGRlc2NyaXB0b3IuZ2V0UmV0dXJuVHlwZSgpKTsKCiAgICAgICAgVHlwZSByZXNUeXBlOwogICAgICAgIHN3aXRjaCAodHJlZS5nZXRNb2RlKCkpIHsKICAgICAgICAgICAgY2FzZSBORVc6CiAgICAgICAgICAgICAgICBpZiAoIXRyZWUuZXhwci50eXBlLmlzUmF3KCkpIHsKICAgICAgICAgICAgICAgICAgICByZXNUeXBlID0gdHJlZS5leHByLnR5cGU7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICByZXNUeXBlID0gcmVmVHlwZS5nZXRSZXR1cm5UeXBlKCk7CiAgICAgICAgfQoKICAgICAgICBUeXBlIGluY29tcGF0aWJsZVJldHVyblR5cGUgPSByZXNUeXBlOwoKICAgICAgICBpZiAocmV0dXJuVHlwZS5oYXNUYWcoVk9JRCkpIHsKICAgICAgICAgICAgaW5jb21wYXRpYmxlUmV0dXJuVHlwZSA9IG51bGw7CiAgICAgICAgfQoKICAgICAgICBpZiAoIXJldHVyblR5cGUuaGFzVGFnKFZPSUQpICYmICFyZXNUeXBlLmhhc1RhZyhWT0lEKSkgewogICAgICAgICAgICBpZiAocmVzVHlwZS5pc0Vycm9uZW91cygpIHx8CiAgICAgICAgICAgICAgICAgICAgbmV3IEZ1bmN0aW9uYWxSZXR1cm5Db250ZXh0KGNoZWNrQ29udGV4dCkuY29tcGF0aWJsZShyZXNUeXBlLCByZXR1cm5UeXBlLCB0eXBlcy5ub1dhcm5pbmdzKSkgewogICAgICAgICAgICAgICAgaW5jb21wYXRpYmxlUmV0dXJuVHlwZSA9IG51bGw7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmIChpbmNvbXBhdGlibGVSZXR1cm5UeXBlICE9IG51bGwpIHsKICAgICAgICAgICAgY2hlY2tDb250ZXh0LnJlcG9ydCh0cmVlLCBkaWFncy5mcmFnbWVudCgiaW5jb21wYXRpYmxlLnJldC50eXBlLmluLm1yZWYiLAogICAgICAgICAgICAgICAgICAgIGRpYWdzLmZyYWdtZW50KCJpbmNvbnZlcnRpYmxlLnR5cGVzIiwgcmVzVHlwZSwgZGVzY3JpcHRvci5nZXRSZXR1cm5UeXBlKCkpKSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgaWYgKGluZmVyZW5jZUNvbnRleHQuZnJlZShyZWZUeXBlKSkgewogICAgICAgICAgICAgICAgLy8gd2UgbmVlZCB0byB3YWl0IGZvciBpbmZlcmVuY2UgdG8gZmluaXNoIGFuZCB0aGVuIHJlcGxhY2UgaW5mZXJlbmNlIHZhcnMgaW4gdGhlIHJlZmVyZW50IHR5cGUKICAgICAgICAgICAgICAgIGluZmVyZW5jZUNvbnRleHQuYWRkRnJlZVR5cGVMaXN0ZW5lcihMaXN0Lm9mKHJlZlR5cGUpLAogICAgICAgICAgICAgICAgICAgICAgICBpbnN0YW50aWF0ZWRDb250ZXh0IC0+IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyZWUucmVmZXJlbnRUeXBlID0gaW5zdGFudGlhdGVkQ29udGV4dC5hc0luc3RUeXBlKHJlZlR5cGUpOwogICAgICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHRyZWUucmVmZXJlbnRUeXBlID0gcmVmVHlwZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCFzcGVjdWxhdGl2ZUF0dHIpIHsKICAgICAgICAgICAgTGlzdDxUeXBlPiB0aHJvd25UeXBlcyA9IGluZmVyZW5jZUNvbnRleHQuYXNVbmRldFZhcnMoZGVzY3JpcHRvci5nZXRUaHJvd25UeXBlcygpKTsKICAgICAgICAgICAgaWYgKGNoay51bmhhbmRsZWQocmVmVHlwZS5nZXRUaHJvd25UeXBlcygpLCB0aHJvd25UeXBlcykubm9uRW1wdHkoKSkgewogICAgICAgICAgICAgICAgbG9nLmVycm9yKHRyZWUsICJpbmNvbXBhdGlibGUudGhyb3duLnR5cGVzLmluLm1yZWYiLCByZWZUeXBlLmdldFRocm93blR5cGVzKCkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vMTguMi41OiAiSW4gYWRkaXRpb24sIGZvciBhbGwgaiAoMSA8PSBqIDw9IG4pLCB0aGUgY29uc3RyYWludCByZWR1Y2VzIHRvIHRoZSBib3VuZCB0aHJvd3MgRWoiCiAgICAgICAgICAgIHRocm93blR5cGVzLnN0cmVhbSgpCiAgICAgICAgICAgICAgICAgICAgLmZpbHRlcih0IC0+IHQuaGFzVGFnKFVOREVUVkFSKSkKICAgICAgICAgICAgICAgICAgICAuZm9yRWFjaCh0IC0+ICgoVW5kZXRWYXIpdCkuc2V0VGhyb3coKSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogU2V0IGZ1bmN0aW9uYWwgdHlwZSBpbmZvIG9uIHRoZSB1bmRlcmx5aW5nIEFTVC4gTm90ZTogYXMgdGhlIHRhcmdldCBkZXNjcmlwdG9yCiAgICAgKiBtaWdodCBjb250YWluIGluZmVyZW5jZSB2YXJpYWJsZXMsIHdlIG1pZ2h0IG5lZWQgdG8gcmVnaXN0ZXIgYW4gaG9vayBpbiB0aGUKICAgICAqIGN1cnJlbnQgaW5mZXJlbmNlIGNvbnRleHQuCiAgICAgKi8KICAgIHByaXZhdGUgdm9pZCBzZXRGdW5jdGlvbmFsSW5mbyhmaW5hbCBFbnY8QXR0ckNvbnRleHQ+IGVudiwgZmluYWwgSkNGdW5jdGlvbmFsRXhwcmVzc2lvbiBmRXhwciwKICAgICAgICAgICAgZmluYWwgVHlwZSBwdCwgZmluYWwgVHlwZSBkZXNjcmlwdG9yVHlwZSwgZmluYWwgVHlwZSBwcmltYXJ5VGFyZ2V0LCBmaW5hbCBDaGVja0NvbnRleHQgY2hlY2tDb250ZXh0KSB7CiAgICAgICAgaWYgKGNoZWNrQ29udGV4dC5pbmZlcmVuY2VDb250ZXh0KCkuZnJlZShkZXNjcmlwdG9yVHlwZSkpIHsKICAgICAgICAgICAgY2hlY2tDb250ZXh0LmluZmVyZW5jZUNvbnRleHQoKS5hZGRGcmVlVHlwZUxpc3RlbmVyKExpc3Qub2YocHQsIGRlc2NyaXB0b3JUeXBlKSwKICAgICAgICAgICAgICAgICAgICBpbmZlcmVuY2VDb250ZXh0IC0+IHNldEZ1bmN0aW9uYWxJbmZvKGVudiwgZkV4cHIsIHB0LCBpbmZlcmVuY2VDb250ZXh0LmFzSW5zdFR5cGUoZGVzY3JpcHRvclR5cGUpLAogICAgICAgICAgICAgICAgICAgIGluZmVyZW5jZUNvbnRleHQuYXNJbnN0VHlwZShwcmltYXJ5VGFyZ2V0KSwgY2hlY2tDb250ZXh0KSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgTGlzdEJ1ZmZlcjxUeXBlPiB0YXJnZXRzID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgICAgICBpZiAocHQuaGFzVGFnKENMQVNTKSkgewogICAgICAgICAgICAgICAgaWYgKHB0LmlzQ29tcG91bmQoKSkgewogICAgICAgICAgICAgICAgICAgIHRhcmdldHMuYXBwZW5kKHR5cGVzLnJlbW92ZVdpbGRjYXJkcyhwcmltYXJ5VGFyZ2V0KSk7IC8vdGhpcyBnb2VzIGZpcnN0CiAgICAgICAgICAgICAgICAgICAgZm9yIChUeXBlIHQgOiAoKEludGVyc2VjdGlvbkNsYXNzVHlwZSlwdCgpKS5pbnRlcmZhY2VzX2ZpZWxkKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0ICE9IHByaW1hcnlUYXJnZXQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldHMuYXBwZW5kKHR5cGVzLnJlbW92ZVdpbGRjYXJkcyh0KSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHRhcmdldHMuYXBwZW5kKHR5cGVzLnJlbW92ZVdpbGRjYXJkcyhwcmltYXJ5VGFyZ2V0KSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZkV4cHIudGFyZ2V0cyA9IHRhcmdldHMudG9MaXN0KCk7CiAgICAgICAgICAgIGlmIChjaGVja0NvbnRleHQuZGVmZXJyZWRBdHRyQ29udGV4dCgpLm1vZGUgPT0gRGVmZXJyZWRBdHRyLkF0dHJNb2RlLkNIRUNLICYmCiAgICAgICAgICAgICAgICAgICAgcHQgIT0gVHlwZS5yZWNvdmVyeVR5cGUpIHsKICAgICAgICAgICAgICAgIC8vY2hlY2sgdGhhdCBmdW5jdGlvbmFsIGludGVyZmFjZSBjbGFzcyBpcyB3ZWxsLWZvcm1lZAogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICAvKiBUeXBlcy5tYWtlRnVuY3Rpb25hbEludGVyZmFjZUNsYXNzKCkgbWF5IHRocm93IGFuIGV4Y2VwdGlvbgogICAgICAgICAgICAgICAgICAgICAqIHdoZW4gaXQncyBleGVjdXRlZCBwb3N0LWluZmVyZW5jZS4gU2VlIHRoZSBsaXN0ZW5lciBjb2RlCiAgICAgICAgICAgICAgICAgICAgICogYWJvdmUuCiAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgQ2xhc3NTeW1ib2wgY3N5bSA9IHR5cGVzLm1ha2VGdW5jdGlvbmFsSW50ZXJmYWNlQ2xhc3MoZW52LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZXMuZW1wdHksIExpc3Qub2YoZkV4cHIudGFyZ2V0cy5oZWFkKSwgQUJTVFJBQ1QpOwogICAgICAgICAgICAgICAgICAgIGlmIChjc3ltICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY2hrLmNoZWNrSW1wbGVtZW50YXRpb25zKGVudi50cmVlLCBjc3ltLCBjc3ltKTsKICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vcGVyZm9ybSBhbiBhZGRpdGlvbmFsIGZ1bmN0aW9uYWwgaW50ZXJmYWNlIGNoZWNrIG9uIHRoZSBzeW50aGV0aWMgY2xhc3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2FzIHRoZXJlIG1heSBiZSBzcHVyaW91cyBlcnJvcnMgZm9yIHJhdyB0YXJnZXRzIC0gYmVjYXVzZSBvZiBleGlzdGluZyBpc3N1ZXMKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vd2l0aCBtZW1iZXJzaGlwIGFuZCBpbmhlcml0YW5jZSAoc2VlIEpESy04MDc0NTcwKS4KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNzeW0uZmxhZ3NfZmllbGQgfD0gSU5URVJGQUNFOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZXMuZmluZERlc2NyaXB0b3JUeXBlKGNzeW0udHlwZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEZ1bmN0aW9uRGVzY3JpcHRvckxvb2t1cEVycm9yIGVycikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0SW5mby5jaGVja0NvbnRleHQucmVwb3J0KGZFeHByLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaWFncy5mcmFnbWVudChGcmFnbWVudHMuTm9TdWl0YWJsZUZ1bmN0aW9uYWxJbnRmSW5zdChmRXhwci50YXJnZXRzLmhlYWQpKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGNhdGNoIChUeXBlcy5GdW5jdGlvbkRlc2NyaXB0b3JMb29rdXBFcnJvciBleCkgewogICAgICAgICAgICAgICAgICAgIEpDRGlhZ25vc3RpYyBjYXVzZSA9IGV4LmdldERpYWdub3N0aWMoKTsKICAgICAgICAgICAgICAgICAgICByZXN1bHRJbmZvLmNoZWNrQ29udGV4dC5yZXBvcnQoZW52LnRyZWUsIGNhdXNlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdFBhcmVucyhKQ1BhcmVucyB0cmVlKSB7CiAgICAgICAgVHlwZSBvd250eXBlID0gYXR0cmliVHJlZSh0cmVlLmV4cHIsIGVudiwgcmVzdWx0SW5mbyk7CiAgICAgICAgcmVzdWx0ID0gY2hlY2sodHJlZSwgb3dudHlwZSwgcGtpbmQoKSwgcmVzdWx0SW5mbyk7CiAgICAgICAgU3ltYm9sIHN5bSA9IFRyZWVJbmZvLnN5bWJvbCh0cmVlKTsKICAgICAgICBpZiAoc3ltICE9IG51bGwgJiYgc3ltLmtpbmQubWF0Y2hlcyhLaW5kU2VsZWN0b3IuVFlQX1BDSykpCiAgICAgICAgICAgIGxvZy5lcnJvcih0cmVlLnBvcygpLCAiaWxsZWdhbC5zdGFydC5vZi50eXBlIik7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRBc3NpZ24oSkNBc3NpZ24gdHJlZSkgewogICAgICAgIFR5cGUgb3dudHlwZSA9IGF0dHJpYlRyZWUodHJlZS5saHMsIGVudi5kdXAodHJlZSksIHZhckFzc2lnbm1lbnRJbmZvKTsKICAgICAgICBUeXBlIGNhcHR1cmVkVHlwZSA9IGNhcHR1cmUob3dudHlwZSk7CiAgICAgICAgYXR0cmliRXhwcih0cmVlLnJocywgZW52LCBvd250eXBlKTsKICAgICAgICByZXN1bHQgPSBjaGVjayh0cmVlLCBjYXB0dXJlZFR5cGUsIEtpbmRTZWxlY3Rvci5WQUwsIHJlc3VsdEluZm8pOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0QXNzaWdub3AoSkNBc3NpZ25PcCB0cmVlKSB7CiAgICAgICAgLy8gQXR0cmlidXRlIGFyZ3VtZW50cy4KICAgICAgICBUeXBlIG93bnR5cGUgPSBhdHRyaWJUcmVlKHRyZWUubGhzLCBlbnYsIHZhckFzc2lnbm1lbnRJbmZvKTsKICAgICAgICBUeXBlIG9wZXJhbmQgPSBhdHRyaWJFeHByKHRyZWUucmhzLCBlbnYpOwogICAgICAgIC8vIEZpbmQgb3BlcmF0b3IuCiAgICAgICAgU3ltYm9sIG9wZXJhdG9yID0gdHJlZS5vcGVyYXRvciA9IG9wZXJhdG9ycy5yZXNvbHZlQmluYXJ5KHRyZWUsIHRyZWUuZ2V0VGFnKCkubm9Bc3NpZ25PcCgpLCBvd250eXBlLCBvcGVyYW5kKTsKICAgICAgICBpZiAob3BlcmF0b3IgIT0gb3BlcmF0b3JzLm5vT3BTeW1ib2wgJiYKICAgICAgICAgICAgICAgICFvd250eXBlLmlzRXJyb25lb3VzKCkgJiYKICAgICAgICAgICAgICAgICFvcGVyYW5kLmlzRXJyb25lb3VzKCkpIHsKICAgICAgICAgICAgY2hrLmNoZWNrRGl2WmVybyh0cmVlLnJocy5wb3MoKSwgb3BlcmF0b3IsIG9wZXJhbmQpOwogICAgICAgICAgICBjaGsuY2hlY2tDYXN0YWJsZSh0cmVlLnJocy5wb3MoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3BlcmF0b3IudHlwZS5nZXRSZXR1cm5UeXBlKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG93bnR5cGUpOwogICAgICAgIH0KICAgICAgICByZXN1bHQgPSBjaGVjayh0cmVlLCBvd250eXBlLCBLaW5kU2VsZWN0b3IuVkFMLCByZXN1bHRJbmZvKTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdFVuYXJ5KEpDVW5hcnkgdHJlZSkgewogICAgICAgIC8vIEF0dHJpYnV0ZSBhcmd1bWVudHMuCiAgICAgICAgVHlwZSBhcmd0eXBlID0gKHRyZWUuZ2V0VGFnKCkuaXNJbmNPckRlY1VuYXJ5T3AoKSkKICAgICAgICAgICAgPyBhdHRyaWJUcmVlKHRyZWUuYXJnLCBlbnYsIHZhckFzc2lnbm1lbnRJbmZvKQogICAgICAgICAgICA6IGNoay5jaGVja05vblZvaWQodHJlZS5hcmcucG9zKCksIGF0dHJpYkV4cHIodHJlZS5hcmcsIGVudikpOwoKICAgICAgICAvLyBGaW5kIG9wZXJhdG9yLgogICAgICAgIFN5bWJvbCBvcGVyYXRvciA9IHRyZWUub3BlcmF0b3IgPSBvcGVyYXRvcnMucmVzb2x2ZVVuYXJ5KHRyZWUsIHRyZWUuZ2V0VGFnKCksIGFyZ3R5cGUpOwogICAgICAgIFR5cGUgb3dudHlwZSA9IHR5cGVzLmNyZWF0ZUVycm9yVHlwZSh0cmVlLnR5cGUpOwogICAgICAgIGlmIChvcGVyYXRvciAhPSBvcGVyYXRvcnMubm9PcFN5bWJvbCAmJgogICAgICAgICAgICAgICAgIWFyZ3R5cGUuaXNFcnJvbmVvdXMoKSkgewogICAgICAgICAgICBvd250eXBlID0gKHRyZWUuZ2V0VGFnKCkuaXNJbmNPckRlY1VuYXJ5T3AoKSkKICAgICAgICAgICAgICAgID8gdHJlZS5hcmcudHlwZQogICAgICAgICAgICAgICAgOiBvcGVyYXRvci50eXBlLmdldFJldHVyblR5cGUoKTsKICAgICAgICAgICAgaW50IG9wYyA9ICgoT3BlcmF0b3JTeW1ib2wpb3BlcmF0b3IpLm9wY29kZTsKCiAgICAgICAgICAgIC8vIElmIHRoZSBhcmd1bWVudCBpcyBjb25zdGFudCwgZm9sZCBpdC4KICAgICAgICAgICAgaWYgKGFyZ3R5cGUuY29uc3RWYWx1ZSgpICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIFR5cGUgY3R5cGUgPSBjZm9sZGVyLmZvbGQxKG9wYywgYXJndHlwZSk7CiAgICAgICAgICAgICAgICBpZiAoY3R5cGUgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIG93bnR5cGUgPSBjZm9sZGVyLmNvZXJjZShjdHlwZSwgb3dudHlwZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmVzdWx0ID0gY2hlY2sodHJlZSwgb3dudHlwZSwgS2luZFNlbGVjdG9yLlZBTCwgcmVzdWx0SW5mbyk7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRCaW5hcnkoSkNCaW5hcnkgdHJlZSkgewogICAgICAgIC8vIEF0dHJpYnV0ZSBhcmd1bWVudHMuCiAgICAgICAgVHlwZSBsZWZ0ID0gY2hrLmNoZWNrTm9uVm9pZCh0cmVlLmxocy5wb3MoKSwgYXR0cmliRXhwcih0cmVlLmxocywgZW52KSk7CiAgICAgICAgVHlwZSByaWdodCA9IGNoay5jaGVja05vblZvaWQodHJlZS5yaHMucG9zKCksIGF0dHJpYkV4cHIodHJlZS5yaHMsIGVudikpOwogICAgICAgIC8vIEZpbmQgb3BlcmF0b3IuCiAgICAgICAgU3ltYm9sIG9wZXJhdG9yID0gdHJlZS5vcGVyYXRvciA9IG9wZXJhdG9ycy5yZXNvbHZlQmluYXJ5KHRyZWUsIHRyZWUuZ2V0VGFnKCksIGxlZnQsIHJpZ2h0KTsKICAgICAgICBUeXBlIG93bnR5cGUgPSB0eXBlcy5jcmVhdGVFcnJvclR5cGUodHJlZS50eXBlKTsKICAgICAgICBpZiAob3BlcmF0b3IgIT0gb3BlcmF0b3JzLm5vT3BTeW1ib2wgJiYKICAgICAgICAgICAgICAgICFsZWZ0LmlzRXJyb25lb3VzKCkgJiYKICAgICAgICAgICAgICAgICFyaWdodC5pc0Vycm9uZW91cygpKSB7CiAgICAgICAgICAgIG93bnR5cGUgPSBvcGVyYXRvci50eXBlLmdldFJldHVyblR5cGUoKTsKICAgICAgICAgICAgaW50IG9wYyA9ICgoT3BlcmF0b3JTeW1ib2wpb3BlcmF0b3IpLm9wY29kZTsKICAgICAgICAgICAgLy8gSWYgYm90aCBhcmd1bWVudHMgYXJlIGNvbnN0YW50cywgZm9sZCB0aGVtLgogICAgICAgICAgICBpZiAobGVmdC5jb25zdFZhbHVlKCkgIT0gbnVsbCAmJiByaWdodC5jb25zdFZhbHVlKCkgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgVHlwZSBjdHlwZSA9IGNmb2xkZXIuZm9sZDIob3BjLCBsZWZ0LCByaWdodCk7CiAgICAgICAgICAgICAgICBpZiAoY3R5cGUgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIG93bnR5cGUgPSBjZm9sZGVyLmNvZXJjZShjdHlwZSwgb3dudHlwZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIENoZWNrIHRoYXQgYXJndW1lbnQgdHlwZXMgb2YgYSByZWZlcmVuY2UgPT0sICE9IGFyZQogICAgICAgICAgICAvLyBjYXN0YWJsZSB0byBlYWNoIG90aGVyLCAoSkxTIDE1LjIxKS4gIE5vdGU6IHVuYm94aW5nCiAgICAgICAgICAgIC8vIGNvbXBhcmlzb25zIHdpbGwgbm90IGhhdmUgYW4gYWNtcCogb3BjIGF0IHRoaXMgcG9pbnQuCiAgICAgICAgICAgIGlmICgob3BjID09IEJ5dGVDb2Rlcy5pZl9hY21wZXEgfHwgb3BjID09IEJ5dGVDb2Rlcy5pZl9hY21wbmUpKSB7CiAgICAgICAgICAgICAgICBpZiAoIXR5cGVzLmlzQ2FzdGFibGUobGVmdCwgcmlnaHQsIG5ldyBXYXJuZXIodHJlZS5wb3MoKSkpKSB7CiAgICAgICAgICAgICAgICAgICAgbG9nLmVycm9yKHRyZWUucG9zKCksICJpbmNvbXBhcmFibGUudHlwZXMiLCBsZWZ0LCByaWdodCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGNoay5jaGVja0Rpdlplcm8odHJlZS5yaHMucG9zKCksIG9wZXJhdG9yLCByaWdodCk7CiAgICAgICAgfQogICAgICAgIHJlc3VsdCA9IGNoZWNrKHRyZWUsIG93bnR5cGUsIEtpbmRTZWxlY3Rvci5WQUwsIHJlc3VsdEluZm8pOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0VHlwZUNhc3QoZmluYWwgSkNUeXBlQ2FzdCB0cmVlKSB7CiAgICAgICAgVHlwZSBjbGF6enR5cGUgPSBhdHRyaWJUeXBlKHRyZWUuY2xhenosIGVudik7CiAgICAgICAgY2hrLnZhbGlkYXRlKHRyZWUuY2xhenosIGVudiwgZmFsc2UpOwogICAgICAgIC8vYSBmcmVzaCBlbnZpcm9ubWVudCBpcyByZXF1aXJlZCBmb3IgMjkyIGluZmVyZW5jZSB0byB3b3JrIHByb3Blcmx5IC0tLQogICAgICAgIC8vc2VlIEluZmVyLmluc3RhbnRpYXRlUG9seW1vcnBoaWNTaWduYXR1cmVJbnN0YW5jZSgpCiAgICAgICAgRW52PEF0dHJDb250ZXh0PiBsb2NhbEVudiA9IGVudi5kdXAodHJlZSk7CiAgICAgICAgLy9zaG91bGQgd2UgcHJvcGFnYXRlIHRoZSB0YXJnZXQgdHlwZT8KICAgICAgICBmaW5hbCBSZXN1bHRJbmZvIGNhc3RJbmZvOwogICAgICAgIEpDRXhwcmVzc2lvbiBleHByID0gVHJlZUluZm8uc2tpcFBhcmVucyh0cmVlLmV4cHIpOwogICAgICAgIGJvb2xlYW4gaXNQb2x5ID0gYWxsb3dQb2x5ICYmIChleHByLmhhc1RhZyhMQU1CREEpIHx8IGV4cHIuaGFzVGFnKFJFRkVSRU5DRSkpOwogICAgICAgIGlmIChpc1BvbHkpIHsKICAgICAgICAgICAgLy9leHByZXNzaW9uIGlzIGEgcG9seSAtIHdlIG5lZWQgdG8gcHJvcGFnYXRlIHRhcmdldCB0eXBlIGluZm8KICAgICAgICAgICAgY2FzdEluZm8gPSBuZXcgUmVzdWx0SW5mbyhLaW5kU2VsZWN0b3IuVkFMLCBjbGF6enR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IENoZWNrLk5lc3RlZENoZWNrQ29udGV4dChyZXN1bHRJbmZvLmNoZWNrQ29udGV4dCkgewogICAgICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgICAgICBwdWJsaWMgYm9vbGVhbiBjb21wYXRpYmxlKFR5cGUgZm91bmQsIFR5cGUgcmVxLCBXYXJuZXIgd2FybikgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB0eXBlcy5pc0Nhc3RhYmxlKGZvdW5kLCByZXEsIHdhcm4pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvL3N0YW5kYWxvbmUgY2FzdCAtIHRhcmdldC10eXBlIGluZm8gaXMgbm90IHByb3BhZ2F0ZWQKICAgICAgICAgICAgY2FzdEluZm8gPSB1bmtub3duRXhwckluZm87CiAgICAgICAgfQogICAgICAgIFR5cGUgZXhwcnR5cGUgPSBhdHRyaWJUcmVlKHRyZWUuZXhwciwgbG9jYWxFbnYsIGNhc3RJbmZvKTsKICAgICAgICBUeXBlIG93bnR5cGUgPSBpc1BvbHkgPyBjbGF6enR5cGUgOiBjaGsuY2hlY2tDYXN0YWJsZSh0cmVlLmV4cHIucG9zKCksIGV4cHJ0eXBlLCBjbGF6enR5cGUpOwogICAgICAgIGlmIChleHBydHlwZS5jb25zdFZhbHVlKCkgIT0gbnVsbCkKICAgICAgICAgICAgb3dudHlwZSA9IGNmb2xkZXIuY29lcmNlKGV4cHJ0eXBlLCBvd250eXBlKTsKICAgICAgICByZXN1bHQgPSBjaGVjayh0cmVlLCBjYXB0dXJlKG93bnR5cGUpLCBLaW5kU2VsZWN0b3IuVkFMLCByZXN1bHRJbmZvKTsKICAgICAgICBpZiAoIWlzUG9seSkKICAgICAgICAgICAgY2hrLmNoZWNrUmVkdW5kYW50Q2FzdChsb2NhbEVudiwgdHJlZSk7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRUeXBlVGVzdChKQ0luc3RhbmNlT2YgdHJlZSkgewogICAgICAgIFR5cGUgZXhwcnR5cGUgPSBjaGsuY2hlY2tOdWxsT3JSZWZUeXBlKAogICAgICAgICAgICAgICAgdHJlZS5leHByLnBvcygpLCBhdHRyaWJFeHByKHRyZWUuZXhwciwgZW52KSk7CiAgICAgICAgVHlwZSBjbGF6enR5cGUgPSBhdHRyaWJUeXBlKHRyZWUuY2xhenosIGVudik7CiAgICAgICAgaWYgKCFjbGF6enR5cGUuaGFzVGFnKFRZUEVWQVIpKSB7CiAgICAgICAgICAgIGNsYXp6dHlwZSA9IGNoay5jaGVja0NsYXNzT3JBcnJheVR5cGUodHJlZS5jbGF6ei5wb3MoKSwgY2xhenp0eXBlKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFjbGF6enR5cGUuaXNFcnJvbmVvdXMoKSAmJiAhdHlwZXMuaXNSZWlmaWFibGUoY2xhenp0eXBlKSkgewogICAgICAgICAgICBsb2cuZXJyb3IodHJlZS5jbGF6ei5wb3MoKSwgImlsbGVnYWwuZ2VuZXJpYy50eXBlLmZvci5pbnN0b2YiKTsKICAgICAgICAgICAgY2xhenp0eXBlID0gdHlwZXMuY3JlYXRlRXJyb3JUeXBlKGNsYXp6dHlwZSk7CiAgICAgICAgfQogICAgICAgIGNoay52YWxpZGF0ZSh0cmVlLmNsYXp6LCBlbnYsIGZhbHNlKTsKICAgICAgICBjaGsuY2hlY2tDYXN0YWJsZSh0cmVlLmV4cHIucG9zKCksIGV4cHJ0eXBlLCBjbGF6enR5cGUpOwogICAgICAgIHJlc3VsdCA9IGNoZWNrKHRyZWUsIHN5bXMuYm9vbGVhblR5cGUsIEtpbmRTZWxlY3Rvci5WQUwsIHJlc3VsdEluZm8pOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0SW5kZXhlZChKQ0FycmF5QWNjZXNzIHRyZWUpIHsKICAgICAgICBUeXBlIG93bnR5cGUgPSB0eXBlcy5jcmVhdGVFcnJvclR5cGUodHJlZS50eXBlKTsKICAgICAgICBUeXBlIGF0eXBlID0gYXR0cmliRXhwcih0cmVlLmluZGV4ZWQsIGVudik7CiAgICAgICAgYXR0cmliRXhwcih0cmVlLmluZGV4LCBlbnYsIHN5bXMuaW50VHlwZSk7CiAgICAgICAgaWYgKHR5cGVzLmlzQXJyYXkoYXR5cGUpKQogICAgICAgICAgICBvd250eXBlID0gdHlwZXMuZWxlbXR5cGUoYXR5cGUpOwogICAgICAgIGVsc2UgaWYgKCFhdHlwZS5oYXNUYWcoRVJST1IpKQogICAgICAgICAgICBsb2cuZXJyb3IodHJlZS5wb3MoKSwgImFycmF5LnJlcS5idXQuZm91bmQiLCBhdHlwZSk7CiAgICAgICAgaWYgKCFwa2luZCgpLmNvbnRhaW5zKEtpbmRTZWxlY3Rvci5WQUwpKQogICAgICAgICAgICBvd250eXBlID0gY2FwdHVyZShvd250eXBlKTsKICAgICAgICByZXN1bHQgPSBjaGVjayh0cmVlLCBvd250eXBlLCBLaW5kU2VsZWN0b3IuVkFSLCByZXN1bHRJbmZvKTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdElkZW50KEpDSWRlbnQgdHJlZSkgewogICAgICAgIFN5bWJvbCBzeW07CgogICAgICAgIC8vIEZpbmQgc3ltYm9sCiAgICAgICAgaWYgKHB0KCkuaGFzVGFnKE1FVEhPRCkgfHwgcHQoKS5oYXNUYWcoRk9SQUxMKSkgewogICAgICAgICAgICAvLyBJZiB3ZSBhcmUgbG9va2luZyBmb3IgYSBtZXRob2QsIHRoZSBwcm90b3R5cGUgYHB0JyB3aWxsIGJlIGEKICAgICAgICAgICAgLy8gbWV0aG9kIHR5cGUgd2l0aCB0aGUgdHlwZSBvZiB0aGUgY2FsbCdzIGFyZ3VtZW50cyBhcyBwYXJhbWV0ZXJzLgogICAgICAgICAgICBlbnYuaW5mby5wZW5kaW5nUmVzb2x1dGlvblBoYXNlID0gbnVsbDsKICAgICAgICAgICAgc3ltID0gcnMucmVzb2x2ZU1ldGhvZCh0cmVlLnBvcygpLCBlbnYsIHRyZWUubmFtZSwgcHQoKS5nZXRQYXJhbWV0ZXJUeXBlcygpLCBwdCgpLmdldFR5cGVBcmd1bWVudHMoKSk7CiAgICAgICAgfSBlbHNlIGlmICh0cmVlLnN5bSAhPSBudWxsICYmIHRyZWUuc3ltLmtpbmQgIT0gVkFSKSB7CiAgICAgICAgICAgIHN5bSA9IHRyZWUuc3ltOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHN5bSA9IHJzLnJlc29sdmVJZGVudCh0cmVlLnBvcygpLCBlbnYsIHRyZWUubmFtZSwgcGtpbmQoKSk7CiAgICAgICAgfQogICAgICAgIHRyZWUuc3ltID0gc3ltOwoKICAgICAgICAvLyAoMSkgQWxzbyBmaW5kIHRoZSBlbnZpcm9ubWVudCBjdXJyZW50IGZvciB0aGUgY2xhc3Mgd2hlcmUKICAgICAgICAvLyAgICAgc3ltIGlzIGRlZmluZWQgKGBzeW1FbnYnKS4KICAgICAgICAvLyBPbmx5IGZvciBwcmUtdGlnZXIgdmVyc2lvbnMgKDEuNCBhbmQgZWFybGllcik6CiAgICAgICAgLy8gKDIpIEFsc28gZGV0ZXJtaW5lIHdoZXRoZXIgd2UgYWNjZXNzIHN5bWJvbCBvdXQgb2YgYW4gYW5vbnltb3VzCiAgICAgICAgLy8gICAgIGNsYXNzIGluIGEgdGhpcyBvciBzdXBlciBjYWxsLiAgVGhpcyBpcyBpbGxlZ2FsIGZvciBpbnN0YW5jZQogICAgICAgIC8vICAgICBtZW1iZXJzIHNpbmNlIHN1Y2ggY2xhc3NlcyBkb24ndCBjYXJyeSBhIHRoaXMkbiBsaW5rLgogICAgICAgIC8vICAgICAoYG5vT3V0ZXJUaGlzUGF0aCcpLgogICAgICAgIEVudjxBdHRyQ29udGV4dD4gc3ltRW52ID0gZW52OwogICAgICAgIGJvb2xlYW4gbm9PdXRlclRoaXNQYXRoID0gZmFsc2U7CiAgICAgICAgaWYgKGVudi5lbmNsQ2xhc3Muc3ltLm93bmVyLmtpbmQgIT0gUENLICYmIC8vIHdlIGFyZSBpbiBhbiBpbm5lciBjbGFzcwogICAgICAgICAgICBzeW0ua2luZC5tYXRjaGVzKEtpbmRTZWxlY3Rvci5WQUxfTVRIKSAmJgogICAgICAgICAgICBzeW0ub3duZXIua2luZCA9PSBUWVAgJiYKICAgICAgICAgICAgdHJlZS5uYW1lICE9IG5hbWVzLl90aGlzICYmIHRyZWUubmFtZSAhPSBuYW1lcy5fc3VwZXIpIHsKCiAgICAgICAgICAgIC8vIEZpbmQgZW52aXJvbm1lbnQgaW4gd2hpY2ggaWRlbnRpZmllciBpcyBkZWZpbmVkLgogICAgICAgICAgICB3aGlsZSAoc3ltRW52Lm91dGVyICE9IG51bGwgJiYKICAgICAgICAgICAgICAgICAgICFzeW0uaXNNZW1iZXJPZihzeW1FbnYuZW5jbENsYXNzLnN5bSwgdHlwZXMpKSB7CiAgICAgICAgICAgICAgICBpZiAoKHN5bUVudi5lbmNsQ2xhc3Muc3ltLmZsYWdzKCkgJiBOT09VVEVSVEhJUykgIT0gMCkKICAgICAgICAgICAgICAgICAgICBub091dGVyVGhpc1BhdGggPSBmYWxzZTsKICAgICAgICAgICAgICAgIHN5bUVudiA9IHN5bUVudi5vdXRlcjsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gSWYgc3ltYm9sIGlzIGEgdmFyaWFibGUsIC4uLgogICAgICAgIGlmIChzeW0ua2luZCA9PSBWQVIpIHsKICAgICAgICAgICAgVmFyU3ltYm9sIHYgPSAoVmFyU3ltYm9sKXN5bTsKCiAgICAgICAgICAgIC8vIC4uLiwgZXZhbHVhdGUgaXRzIGluaXRpYWxpemVyLCBpZiBpdCBoYXMgb25lLCBhbmQgY2hlY2sgZm9yCiAgICAgICAgICAgIC8vIGlsbGVnYWwgZm9yd2FyZCByZWZlcmVuY2UuCiAgICAgICAgICAgIGNoZWNrSW5pdCh0cmVlLCBlbnYsIHYsIGZhbHNlKTsKCiAgICAgICAgICAgIC8vIElmIHdlIGFyZSBleHBlY3RpbmcgYSB2YXJpYWJsZSAoYXMgb3Bwb3NlZCB0byBhIHZhbHVlKSwgY2hlY2sKICAgICAgICAgICAgLy8gdGhhdCB0aGUgdmFyaWFibGUgaXMgYXNzaWduYWJsZSBpbiB0aGUgY3VycmVudCBlbnZpcm9ubWVudC4KICAgICAgICAgICAgaWYgKEtpbmRTZWxlY3Rvci5BU0cuc3Vic2V0KHBraW5kKCkpKQogICAgICAgICAgICAgICAgY2hlY2tBc3NpZ25hYmxlKHRyZWUucG9zKCksIHYsIG51bGwsIGVudik7CiAgICAgICAgfQoKICAgICAgICAvLyBJbiBhIGNvbnN0cnVjdG9yIGJvZHksCiAgICAgICAgLy8gaWYgc3ltYm9sIGlzIGEgZmllbGQgb3IgaW5zdGFuY2UgbWV0aG9kLCBjaGVjayB0aGF0IGl0IGlzCiAgICAgICAgLy8gbm90IGFjY2Vzc2VkIGJlZm9yZSB0aGUgc3VwZXJ0eXBlIGNvbnN0cnVjdG9yIGlzIGNhbGxlZC4KICAgICAgICBpZiAoKHN5bUVudi5pbmZvLmlzU2VsZkNhbGwgfHwgbm9PdXRlclRoaXNQYXRoKSAmJgogICAgICAgICAgICBzeW0ua2luZC5tYXRjaGVzKEtpbmRTZWxlY3Rvci5WQUxfTVRIKSAmJgogICAgICAgICAgICBzeW0ub3duZXIua2luZCA9PSBUWVAgJiYKICAgICAgICAgICAgKHN5bS5mbGFncygpICYgU1RBVElDKSA9PSAwKSB7CiAgICAgICAgICAgIGNoay5lYXJseVJlZkVycm9yKHRyZWUucG9zKCksIHN5bS5raW5kID09IFZBUiA/CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5bSA6IHRoaXNTeW0odHJlZS5wb3MoKSwgZW52KSk7CiAgICAgICAgfQogICAgICAgIEVudjxBdHRyQ29udGV4dD4gZW52MSA9IGVudjsKICAgICAgICBpZiAoc3ltLmtpbmQgIT0gRVJSICYmIHN5bS5raW5kICE9IFRZUCAmJgogICAgICAgICAgICBzeW0ub3duZXIgIT0gbnVsbCAmJiBzeW0ub3duZXIgIT0gZW52MS5lbmNsQ2xhc3Muc3ltKSB7CiAgICAgICAgICAgIC8vIElmIHRoZSBmb3VuZCBzeW1ib2wgaXMgaW5hY2Nlc3NpYmxlLCB0aGVuIGl0IGlzCiAgICAgICAgICAgIC8vIGFjY2Vzc2VkIHRocm91Z2ggYW4gZW5jbG9zaW5nIGluc3RhbmNlLiAgTG9jYXRlIHRoaXMKICAgICAgICAgICAgLy8gZW5jbG9zaW5nIGluc3RhbmNlOgogICAgICAgICAgICB3aGlsZSAoZW52MS5vdXRlciAhPSBudWxsICYmICFycy5pc0FjY2Vzc2libGUoZW52LCBlbnYxLmVuY2xDbGFzcy5zeW0udHlwZSwgc3ltKSkKICAgICAgICAgICAgICAgIGVudjEgPSBlbnYxLm91dGVyOwogICAgICAgIH0KCiAgICAgICAgaWYgKGVudi5pbmZvLmlzU2VyaWFsaXphYmxlKSB7CiAgICAgICAgICAgIGNoay5jaGVja0FjY2Vzc0Zyb21TZXJpYWxpemFibGVFbGVtZW50KHRyZWUsIGVudi5pbmZvLmlzTGFtYmRhKTsKICAgICAgICB9CgogICAgICAgIHJlc3VsdCA9IGNoZWNrSWQodHJlZSwgZW52MS5lbmNsQ2xhc3Muc3ltLnR5cGUsIHN5bSwgZW52LCByZXN1bHRJbmZvKTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdFNlbGVjdChKQ0ZpZWxkQWNjZXNzIHRyZWUpIHsKICAgICAgICAvLyBEZXRlcm1pbmUgdGhlIGV4cGVjdGVkIGtpbmQgb2YgdGhlIHF1YWxpZmllciBleHByZXNzaW9uLgogICAgICAgIEtpbmRTZWxlY3RvciBza2luZCA9IEtpbmRTZWxlY3Rvci5OSUw7CiAgICAgICAgaWYgKHRyZWUubmFtZSA9PSBuYW1lcy5fdGhpcyB8fCB0cmVlLm5hbWUgPT0gbmFtZXMuX3N1cGVyIHx8CiAgICAgICAgICAgICAgICB0cmVlLm5hbWUgPT0gbmFtZXMuX2NsYXNzKQogICAgICAgIHsKICAgICAgICAgICAgc2tpbmQgPSBLaW5kU2VsZWN0b3IuVFlQOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGlmIChwa2luZCgpLmNvbnRhaW5zKEtpbmRTZWxlY3Rvci5QQ0spKQogICAgICAgICAgICAgICAgc2tpbmQgPSBLaW5kU2VsZWN0b3Iub2Yoc2tpbmQsIEtpbmRTZWxlY3Rvci5QQ0spOwogICAgICAgICAgICBpZiAocGtpbmQoKS5jb250YWlucyhLaW5kU2VsZWN0b3IuVFlQKSkKICAgICAgICAgICAgICAgIHNraW5kID0gS2luZFNlbGVjdG9yLm9mKHNraW5kLCBLaW5kU2VsZWN0b3IuVFlQLCBLaW5kU2VsZWN0b3IuUENLKTsKICAgICAgICAgICAgaWYgKHBraW5kKCkuY29udGFpbnMoS2luZFNlbGVjdG9yLlZBTF9NVEgpKQogICAgICAgICAgICAgICAgc2tpbmQgPSBLaW5kU2VsZWN0b3Iub2Yoc2tpbmQsIEtpbmRTZWxlY3Rvci5WQUwsIEtpbmRTZWxlY3Rvci5UWVApOwogICAgICAgIH0KCiAgICAgICAgLy8gQXR0cmlidXRlIHRoZSBxdWFsaWZpZXIgZXhwcmVzc2lvbiwgYW5kIGRldGVybWluZSBpdHMgc3ltYm9sIChpZiBhbnkpLgogICAgICAgIFR5cGUgc2l0ZSA9IGF0dHJpYlRyZWUodHJlZS5zZWxlY3RlZCwgZW52LCBuZXcgUmVzdWx0SW5mbyhza2luZCwgVHlwZS5ub1R5cGUpKTsKICAgICAgICBpZiAoIXBraW5kKCkuY29udGFpbnMoS2luZFNlbGVjdG9yLlRZUF9QQ0spKQogICAgICAgICAgICBzaXRlID0gY2FwdHVyZShzaXRlKTsgLy8gQ2FwdHVyZSBmaWVsZCBhY2Nlc3MKCiAgICAgICAgLy8gZG9uJ3QgYWxsb3cgVC5jbGFzcyBUW10uY2xhc3MsIGV0YwogICAgICAgIGlmIChza2luZCA9PSBLaW5kU2VsZWN0b3IuVFlQKSB7CiAgICAgICAgICAgIFR5cGUgZWx0ID0gc2l0ZTsKICAgICAgICAgICAgd2hpbGUgKGVsdC5oYXNUYWcoQVJSQVkpKQogICAgICAgICAgICAgICAgZWx0ID0gKChBcnJheVR5cGUpZWx0KS5lbGVtdHlwZTsKICAgICAgICAgICAgaWYgKGVsdC5oYXNUYWcoVFlQRVZBUikpIHsKICAgICAgICAgICAgICAgIGxvZy5lcnJvcih0cmVlLnBvcygpLCAidHlwZS52YXIuY2FudC5iZS5kZXJlZiIpOwogICAgICAgICAgICAgICAgcmVzdWx0ID0gdHJlZS50eXBlID0gdHlwZXMuY3JlYXRlRXJyb3JUeXBlKHRyZWUubmFtZSwgc2l0ZS50c3ltLCBzaXRlKTsKICAgICAgICAgICAgICAgIHRyZWUuc3ltID0gdHJlZS50eXBlLnRzeW07CiAgICAgICAgICAgICAgICByZXR1cm4gOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBJZiBxdWFsaWZpZXIgc3ltYm9sIGlzIGEgdHlwZSBvciBgc3VwZXInLCBhc3NlcnQgYHNlbGVjdFN1cGVyJwogICAgICAgIC8vIGZvciB0aGUgc2VsZWN0aW9uLiBUaGlzIGlzIHJlbGV2YW50IGZvciBkZXRlcm1pbmluZyB3aGV0aGVyCiAgICAgICAgLy8gcHJvdGVjdGVkIHN5bWJvbHMgYXJlIGFjY2Vzc2libGUuCiAgICAgICAgU3ltYm9sIHNpdGVzeW0gPSBUcmVlSW5mby5zeW1ib2wodHJlZS5zZWxlY3RlZCk7CiAgICAgICAgYm9vbGVhbiBzZWxlY3RTdXBlclByZXYgPSBlbnYuaW5mby5zZWxlY3RTdXBlcjsKICAgICAgICBlbnYuaW5mby5zZWxlY3RTdXBlciA9CiAgICAgICAgICAgIHNpdGVzeW0gIT0gbnVsbCAmJgogICAgICAgICAgICBzaXRlc3ltLm5hbWUgPT0gbmFtZXMuX3N1cGVyOwoKICAgICAgICAvLyBEZXRlcm1pbmUgdGhlIHN5bWJvbCByZXByZXNlbnRlZCBieSB0aGUgc2VsZWN0aW9uLgogICAgICAgIGVudi5pbmZvLnBlbmRpbmdSZXNvbHV0aW9uUGhhc2UgPSBudWxsOwogICAgICAgIFN5bWJvbCBzeW0gPSBzZWxlY3RTeW0odHJlZSwgc2l0ZXN5bSwgc2l0ZSwgZW52LCByZXN1bHRJbmZvKTsKICAgICAgICBpZiAoc3ltLmtpbmQgPT0gVkFSICYmIHN5bS5uYW1lICE9IG5hbWVzLl9zdXBlciAmJiBlbnYuaW5mby5kZWZhdWx0U3VwZXJDYWxsU2l0ZSAhPSBudWxsKSB7CiAgICAgICAgICAgIGxvZy5lcnJvcih0cmVlLnNlbGVjdGVkLnBvcygpLCAibm90LmVuY2wuY2xhc3MiLCBzaXRlLnRzeW0pOwogICAgICAgICAgICBzeW0gPSBzeW1zLmVyclN5bWJvbDsKICAgICAgICB9CiAgICAgICAgaWYgKHN5bS5leGlzdHMoKSAmJiAhaXNUeXBlKHN5bSkgJiYgcGtpbmQoKS5jb250YWlucyhLaW5kU2VsZWN0b3IuVFlQX1BDSykpIHsKICAgICAgICAgICAgc2l0ZSA9IGNhcHR1cmUoc2l0ZSk7CiAgICAgICAgICAgIHN5bSA9IHNlbGVjdFN5bSh0cmVlLCBzaXRlc3ltLCBzaXRlLCBlbnYsIHJlc3VsdEluZm8pOwogICAgICAgIH0KICAgICAgICBib29sZWFuIHZhckFyZ3MgPSBlbnYuaW5mby5sYXN0UmVzb2x2ZVZhcmFyZ3MoKTsKICAgICAgICB0cmVlLnN5bSA9IHN5bTsKCiAgICAgICAgaWYgKHNpdGUuaGFzVGFnKFRZUEVWQVIpICYmICFpc1R5cGUoc3ltKSAmJiBzeW0ua2luZCAhPSBFUlIpIHsKICAgICAgICAgICAgc2l0ZSA9IHR5cGVzLnNraXBUeXBlVmFycyhzaXRlLCB0cnVlKTsKICAgICAgICB9CgogICAgICAgIC8vIElmIHRoYXQgc3ltYm9sIGlzIGEgdmFyaWFibGUsIC4uLgogICAgICAgIGlmIChzeW0ua2luZCA9PSBWQVIpIHsKICAgICAgICAgICAgVmFyU3ltYm9sIHYgPSAoVmFyU3ltYm9sKXN5bTsKCiAgICAgICAgICAgIC8vIC4uLiwgZXZhbHVhdGUgaXRzIGluaXRpYWxpemVyLCBpZiBpdCBoYXMgb25lLCBhbmQgY2hlY2sgZm9yCiAgICAgICAgICAgIC8vIGlsbGVnYWwgZm9yd2FyZCByZWZlcmVuY2UuCiAgICAgICAgICAgIGNoZWNrSW5pdCh0cmVlLCBlbnYsIHYsIHRydWUpOwoKICAgICAgICAgICAgLy8gSWYgd2UgYXJlIGV4cGVjdGluZyBhIHZhcmlhYmxlIChhcyBvcHBvc2VkIHRvIGEgdmFsdWUpLCBjaGVjawogICAgICAgICAgICAvLyB0aGF0IHRoZSB2YXJpYWJsZSBpcyBhc3NpZ25hYmxlIGluIHRoZSBjdXJyZW50IGVudmlyb25tZW50LgogICAgICAgICAgICBpZiAoS2luZFNlbGVjdG9yLkFTRy5zdWJzZXQocGtpbmQoKSkpCiAgICAgICAgICAgICAgICBjaGVja0Fzc2lnbmFibGUodHJlZS5wb3MoKSwgdiwgdHJlZS5zZWxlY3RlZCwgZW52KTsKICAgICAgICB9CgogICAgICAgIGlmIChzaXRlc3ltICE9IG51bGwgJiYKICAgICAgICAgICAgICAgIHNpdGVzeW0ua2luZCA9PSBWQVIgJiYKICAgICAgICAgICAgICAgICgoVmFyU3ltYm9sKXNpdGVzeW0pLmlzUmVzb3VyY2VWYXJpYWJsZSgpICYmCiAgICAgICAgICAgICAgICBzeW0ua2luZCA9PSBNVEggJiYKICAgICAgICAgICAgICAgIHN5bS5uYW1lLmVxdWFscyhuYW1lcy5jbG9zZSkgJiYKICAgICAgICAgICAgICAgIHN5bS5vdmVycmlkZXMoc3ltcy5hdXRvQ2xvc2VhYmxlQ2xvc2UsIHNpdGVzeW0udHlwZS50c3ltLCB0eXBlcywgdHJ1ZSkgJiYKICAgICAgICAgICAgICAgIGVudi5pbmZvLmxpbnQuaXNFbmFibGVkKExpbnRDYXRlZ29yeS5UUlkpKSB7CiAgICAgICAgICAgIGxvZy53YXJuaW5nKExpbnRDYXRlZ29yeS5UUlksIHRyZWUsICJ0cnkuZXhwbGljaXQuY2xvc2UuY2FsbCIpOwogICAgICAgIH0KCiAgICAgICAgLy8gRGlzYWxsb3cgc2VsZWN0aW5nIGEgdHlwZSBmcm9tIGFuIGV4cHJlc3Npb24KICAgICAgICBpZiAoaXNUeXBlKHN5bSkgJiYgKHNpdGVzeW0gPT0gbnVsbCB8fCAhc2l0ZXN5bS5raW5kLm1hdGNoZXMoS2luZFNlbGVjdG9yLlRZUF9QQ0spKSkgewogICAgICAgICAgICB0cmVlLnR5cGUgPSBjaGVjayh0cmVlLnNlbGVjdGVkLCBwdCgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXRlc3ltID09IG51bGwgPwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEtpbmRTZWxlY3Rvci5WQUwgOiBzaXRlc3ltLmtpbmQudG9TZWxlY3RvcigpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgUmVzdWx0SW5mbyhLaW5kU2VsZWN0b3IuVFlQX1BDSywgcHQoKSkpOwogICAgICAgIH0KCiAgICAgICAgaWYgKGlzVHlwZShzaXRlc3ltKSkgewogICAgICAgICAgICBpZiAoc3ltLm5hbWUgPT0gbmFtZXMuX3RoaXMpIHsKICAgICAgICAgICAgICAgIC8vIElmIGBDJyBpcyB0aGUgY3VycmVudGx5IGNvbXBpbGVkIGNsYXNzLCBjaGVjayB0aGF0CiAgICAgICAgICAgICAgICAvLyBDLnRoaXMnIGRvZXMgbm90IGFwcGVhciBpbiBhIGNhbGwgdG8gYSBzdXBlciguLi4pCiAgICAgICAgICAgICAgICBpZiAoZW52LmluZm8uaXNTZWxmQ2FsbCAmJgogICAgICAgICAgICAgICAgICAgIHNpdGUudHN5bSA9PSBlbnYuZW5jbENsYXNzLnN5bSkgewogICAgICAgICAgICAgICAgICAgIGNoay5lYXJseVJlZkVycm9yKHRyZWUucG9zKCksIHN5bSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvLyBDaGVjayBpZiB0eXBlLXF1YWxpZmllZCBmaWVsZHMgb3IgbWV0aG9kcyBhcmUgc3RhdGljIChKTFMpCiAgICAgICAgICAgICAgICBpZiAoKHN5bS5mbGFncygpICYgU1RBVElDKSA9PSAwICYmCiAgICAgICAgICAgICAgICAgICAgc3ltLm5hbWUgIT0gbmFtZXMuX3N1cGVyICYmCiAgICAgICAgICAgICAgICAgICAgKHN5bS5raW5kID09IFZBUiB8fCBzeW0ua2luZCA9PSBNVEgpKSB7CiAgICAgICAgICAgICAgICAgICAgcnMuYWNjZXNzQmFzZShycy5uZXcgU3RhdGljRXJyb3Ioc3ltKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJlZS5wb3MoKSwgc2l0ZSwgc3ltLm5hbWUsIHRydWUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICghYWxsb3dTdGF0aWNJbnRlcmZhY2VNZXRob2RzICYmIHNpdGVzeW0uaXNJbnRlcmZhY2UoKSAmJgogICAgICAgICAgICAgICAgICAgIHN5bS5pc1N0YXRpYygpICYmIHN5bS5raW5kID09IE1USCkgewogICAgICAgICAgICAgICAgbG9nLmVycm9yKERpYWdub3N0aWNGbGFnLlNPVVJDRV9MRVZFTCwgdHJlZS5wb3MoKSwgInN0YXRpYy5pbnRmLm1ldGhvZC5pbnZva2Uubm90LnN1cHBvcnRlZC5pbi5zb3VyY2UiLCBzb3VyY2VOYW1lKTsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSBpZiAoc3ltLmtpbmQgIT0gRVJSICYmCiAgICAgICAgICAgICAgICAgICAoc3ltLmZsYWdzKCkgJiBTVEFUSUMpICE9IDAgJiYKICAgICAgICAgICAgICAgICAgIHN5bS5uYW1lICE9IG5hbWVzLl9jbGFzcykgewogICAgICAgICAgICAvLyBJZiB0aGUgcXVhbGlmaWVkIGl0ZW0gaXMgbm90IGEgdHlwZSBhbmQgdGhlIHNlbGVjdGVkIGl0ZW0gaXMgc3RhdGljLCByZXBvcnQKICAgICAgICAgICAgLy8gYSB3YXJuaW5nLiBNYWtlIGFsbG93YW5jZSBmb3IgdGhlIGNsYXNzIG9mIGFuIGFycmF5IHR5cGUgZS5nLiBPYmplY3RbXS5jbGFzcykKICAgICAgICAgICAgY2hrLndhcm5TdGF0aWModHJlZSwgInN0YXRpYy5ub3QucXVhbGlmaWVkLmJ5LnR5cGUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICBzeW0ua2luZC5raW5kTmFtZSgpLCBzeW0ub3duZXIpOwogICAgICAgIH0KCiAgICAgICAgLy8gSWYgd2UgYXJlIHNlbGVjdGluZyBhbiBpbnN0YW5jZSBtZW1iZXIgdmlhIGEgYHN1cGVyJywgLi4uCiAgICAgICAgaWYgKGVudi5pbmZvLnNlbGVjdFN1cGVyICYmIChzeW0uZmxhZ3MoKSAmIFNUQVRJQykgPT0gMCkgewoKICAgICAgICAgICAgLy8gQ2hlY2sgdGhhdCBzdXBlci1xdWFsaWZpZWQgc3ltYm9scyBhcmUgbm90IGFic3RyYWN0IChKTFMpCiAgICAgICAgICAgIHJzLmNoZWNrTm9uQWJzdHJhY3QodHJlZS5wb3MoKSwgc3ltKTsKCiAgICAgICAgICAgIGlmIChzaXRlLmlzUmF3KCkpIHsKICAgICAgICAgICAgICAgIC8vIERldGVybWluZSBhcmd1bWVudCB0eXBlcyBmb3Igc2l0ZS4KICAgICAgICAgICAgICAgIFR5cGUgc2l0ZTEgPSB0eXBlcy5hc1N1cGVyKGVudi5lbmNsQ2xhc3Muc3ltLnR5cGUsIHNpdGUudHN5bSk7CiAgICAgICAgICAgICAgICBpZiAoc2l0ZTEgIT0gbnVsbCkgc2l0ZSA9IHNpdGUxOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoZW52LmluZm8uaXNTZXJpYWxpemFibGUpIHsKICAgICAgICAgICAgY2hrLmNoZWNrQWNjZXNzRnJvbVNlcmlhbGl6YWJsZUVsZW1lbnQodHJlZSwgZW52LmluZm8uaXNMYW1iZGEpOwogICAgICAgIH0KCiAgICAgICAgZW52LmluZm8uc2VsZWN0U3VwZXIgPSBzZWxlY3RTdXBlclByZXY7CiAgICAgICAgcmVzdWx0ID0gY2hlY2tJZCh0cmVlLCBzaXRlLCBzeW0sIGVudiwgcmVzdWx0SW5mbyk7CiAgICB9CiAgICAvL3doZXJlCiAgICAgICAgLyoqIERldGVybWluZSBzeW1ib2wgcmVmZXJlbmNlZCBieSBhIFNlbGVjdCBleHByZXNzaW9uLAogICAgICAgICAqCiAgICAgICAgICogIEBwYXJhbSB0cmVlICAgVGhlIHNlbGVjdCB0cmVlLgogICAgICAgICAqICBAcGFyYW0gc2l0ZSAgIFRoZSB0eXBlIG9mIHRoZSBzZWxlY3RlZCBleHByZXNzaW9uLAogICAgICAgICAqICBAcGFyYW0gZW52ICAgIFRoZSBjdXJyZW50IGVudmlyb25tZW50LgogICAgICAgICAqICBAcGFyYW0gcmVzdWx0SW5mbyBUaGUgY3VycmVudCByZXN1bHQuCiAgICAgICAgICovCiAgICAgICAgcHJpdmF0ZSBTeW1ib2wgc2VsZWN0U3ltKEpDRmllbGRBY2Nlc3MgdHJlZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3ltYm9sIGxvY2F0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUeXBlIHNpdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVudjxBdHRyQ29udGV4dD4gZW52LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZXN1bHRJbmZvIHJlc3VsdEluZm8pIHsKICAgICAgICAgICAgRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcyA9IHRyZWUucG9zKCk7CiAgICAgICAgICAgIE5hbWUgbmFtZSA9IHRyZWUubmFtZTsKICAgICAgICAgICAgc3dpdGNoIChzaXRlLmdldFRhZygpKSB7CiAgICAgICAgICAgIGNhc2UgUEFDS0FHRToKICAgICAgICAgICAgICAgIHJldHVybiBycy5hY2Nlc3NCYXNlKAogICAgICAgICAgICAgICAgICAgIHJzLmZpbmRJZGVudEluUGFja2FnZShlbnYsIHNpdGUudHN5bSwgbmFtZSwgcmVzdWx0SW5mby5wa2luZCksCiAgICAgICAgICAgICAgICAgICAgcG9zLCBsb2NhdGlvbiwgc2l0ZSwgbmFtZSwgdHJ1ZSk7CiAgICAgICAgICAgIGNhc2UgQVJSQVk6CiAgICAgICAgICAgIGNhc2UgQ0xBU1M6CiAgICAgICAgICAgICAgICBpZiAocmVzdWx0SW5mby5wdC5oYXNUYWcoTUVUSE9EKSB8fCByZXN1bHRJbmZvLnB0Lmhhc1RhZyhGT1JBTEwpKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJzLnJlc29sdmVRdWFsaWZpZWRNZXRob2QoCiAgICAgICAgICAgICAgICAgICAgICAgIHBvcywgZW52LCBsb2NhdGlvbiwgc2l0ZSwgbmFtZSwgcmVzdWx0SW5mby5wdC5nZXRQYXJhbWV0ZXJUeXBlcygpLCByZXN1bHRJbmZvLnB0LmdldFR5cGVBcmd1bWVudHMoKSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKG5hbWUgPT0gbmFtZXMuX3RoaXMgfHwgbmFtZSA9PSBuYW1lcy5fc3VwZXIpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gcnMucmVzb2x2ZVNlbGYocG9zLCBlbnYsIHNpdGUudHN5bSwgbmFtZSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKG5hbWUgPT0gbmFtZXMuX2NsYXNzKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gSW4gdGhpcyBjYXNlLCB3ZSBoYXZlIGFscmVhZHkgbWFkZSBzdXJlIGluCiAgICAgICAgICAgICAgICAgICAgLy8gdmlzaXRTZWxlY3QgdGhhdCBxdWFsaWZpZXIgZXhwcmVzc2lvbiBpcyBhIHR5cGUuCiAgICAgICAgICAgICAgICAgICAgVHlwZSB0ID0gc3ltcy5jbGFzc1R5cGU7CiAgICAgICAgICAgICAgICAgICAgTGlzdDxUeXBlPiB0eXBlYXJncyA9IExpc3Qub2YodHlwZXMuZXJhc3VyZShzaXRlKSk7CiAgICAgICAgICAgICAgICAgICAgdCA9IG5ldyBDbGFzc1R5cGUodC5nZXRFbmNsb3NpbmdUeXBlKCksIHR5cGVhcmdzLCB0LnRzeW0pOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgVmFyU3ltYm9sKAogICAgICAgICAgICAgICAgICAgICAgICBTVEFUSUMgfCBQVUJMSUMgfCBGSU5BTCwgbmFtZXMuX2NsYXNzLCB0LCBzaXRlLnRzeW0pOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAvLyBXZSBhcmUgc2VlaW5nIGEgcGxhaW4gaWRlbnRpZmllciBhcyBzZWxlY3Rvci4KICAgICAgICAgICAgICAgICAgICBTeW1ib2wgc3ltID0gcnMuZmluZElkZW50SW5UeXBlKGVudiwgc2l0ZSwgbmFtZSwgcmVzdWx0SW5mby5wa2luZCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHN5bSA9IHJzLmFjY2Vzc0Jhc2Uoc3ltLCBwb3MsIGxvY2F0aW9uLCBzaXRlLCBuYW1lLCB0cnVlKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3ltOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICBjYXNlIFdJTERDQVJEOgogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKHRyZWUpOwogICAgICAgICAgICBjYXNlIFRZUEVWQVI6CiAgICAgICAgICAgICAgICAvLyBOb3JtYWxseSwgc2l0ZS5nZXRVcHBlckJvdW5kKCkgc2hvdWxkbid0IGJlIG51bGwuCiAgICAgICAgICAgICAgICAvLyBJdCBzaG91bGQgb25seSBoYXBwZW4gZHVyaW5nIG1lbWJlckVudGVyL2F0dHJpYkJhc2UKICAgICAgICAgICAgICAgIC8vIHdoZW4gZGV0ZXJtaW5pbmcgdGhlIHN1cGVyIHR5cGUgd2hpY2ggKm11c3QqIGJlYWMKICAgICAgICAgICAgICAgIC8vIGRvbmUgYmVmb3JlIGF0dHJpYnV0aW5nIHRoZSB0eXBlIHZhcmlhYmxlcy4gIEluCiAgICAgICAgICAgICAgICAvLyBvdGhlciB3b3Jkcywgd2UgYXJlIHNlZWluZyB0aGlzIGlsbGVnYWwgcHJvZ3JhbToKICAgICAgICAgICAgICAgIC8vIGNsYXNzIEI8VD4gZXh0ZW5kcyBBPFQuZm9vPiB7fQogICAgICAgICAgICAgICAgU3ltYm9sIHN5bSA9IChzaXRlLmdldFVwcGVyQm91bmQoKSAhPSBudWxsKQogICAgICAgICAgICAgICAgICAgID8gc2VsZWN0U3ltKHRyZWUsIGxvY2F0aW9uLCBjYXB0dXJlKHNpdGUuZ2V0VXBwZXJCb3VuZCgpKSwgZW52LCByZXN1bHRJbmZvKQogICAgICAgICAgICAgICAgICAgIDogbnVsbDsKICAgICAgICAgICAgICAgIGlmIChzeW0gPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIGxvZy5lcnJvcihwb3MsICJ0eXBlLnZhci5jYW50LmJlLmRlcmVmIik7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHN5bXMuZXJyU3ltYm9sOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBTeW1ib2wgc3ltMiA9IChzeW0uZmxhZ3MoKSAmIEZsYWdzLlBSSVZBVEUpICE9IDAgPwogICAgICAgICAgICAgICAgICAgICAgICBycy5uZXcgQWNjZXNzRXJyb3IoZW52LCBzaXRlLCBzeW0pIDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeW07CiAgICAgICAgICAgICAgICAgICAgcnMuYWNjZXNzQmFzZShzeW0yLCBwb3MsIGxvY2F0aW9uLCBzaXRlLCBuYW1lLCB0cnVlKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3ltOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICBjYXNlIEVSUk9SOgogICAgICAgICAgICAgICAgLy8gcHJlc2VydmUgaWRlbnRpZmllciBuYW1lcyB0aHJvdWdoIGVycm9ycwogICAgICAgICAgICAgICAgcmV0dXJuIHR5cGVzLmNyZWF0ZUVycm9yVHlwZShuYW1lLCBzaXRlLnRzeW0sIHNpdGUpLnRzeW07CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAvLyBUaGUgcXVhbGlmaWVyIGV4cHJlc3Npb24gaXMgb2YgYSBwcmltaXRpdmUgdHlwZSAtLSBvbmx5CiAgICAgICAgICAgICAgICAvLyAuY2xhc3MgaXMgYWxsb3dlZCBmb3IgdGhlc2UuCiAgICAgICAgICAgICAgICBpZiAobmFtZSA9PSBuYW1lcy5fY2xhc3MpIHsKICAgICAgICAgICAgICAgICAgICAvLyBJbiB0aGlzIGNhc2UsIHdlIGhhdmUgYWxyZWFkeSBtYWRlIHN1cmUgaW4gU2VsZWN0IHRoYXQKICAgICAgICAgICAgICAgICAgICAvLyBxdWFsaWZpZXIgZXhwcmVzc2lvbiBpcyBhIHR5cGUuCiAgICAgICAgICAgICAgICAgICAgVHlwZSB0ID0gc3ltcy5jbGFzc1R5cGU7CiAgICAgICAgICAgICAgICAgICAgVHlwZSBhcmcgPSB0eXBlcy5ib3hlZENsYXNzKHNpdGUpLnR5cGU7CiAgICAgICAgICAgICAgICAgICAgdCA9IG5ldyBDbGFzc1R5cGUodC5nZXRFbmNsb3NpbmdUeXBlKCksIExpc3Qub2YoYXJnKSwgdC50c3ltKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFZhclN5bWJvbCgKICAgICAgICAgICAgICAgICAgICAgICAgU1RBVElDIHwgUFVCTElDIHwgRklOQUwsIG5hbWVzLl9jbGFzcywgdCwgc2l0ZS50c3ltKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgbG9nLmVycm9yKHBvcywgImNhbnQuZGVyZWYiLCBzaXRlKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3ltcy5lcnJTeW1ib2w7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8qKiBEZXRlcm1pbmUgdHlwZSBvZiBpZGVudGlmaWVyIG9yIHNlbGVjdCBleHByZXNzaW9uIGFuZCBjaGVjayB0aGF0CiAgICAgICAgICogICgxKSB0aGUgcmVmZXJlbmNlZCBzeW1ib2wgaXMgbm90IGRlcHJlY2F0ZWQKICAgICAgICAgKiAgKDIpIHRoZSBzeW1ib2wncyB0eXBlIGlzIHNhZmUgKEBzZWUgY2hlY2tTYWZlKQogICAgICAgICAqICAoMykgaWYgc3ltYm9sIGlzIGEgdmFyaWFibGUsIGNoZWNrIHRoYXQgaXRzIHR5cGUgYW5kIGtpbmQgYXJlCiAgICAgICAgICogICAgICBjb21wYXRpYmxlIHdpdGggdGhlIHByb3RvdHlwZSBhbmQgcHJvdG9raW5kLgogICAgICAgICAqICAoNCkgaWYgc3ltYm9sIGlzIGFuIGluc3RhbmNlIGZpZWxkIG9mIGEgcmF3IHR5cGUsCiAgICAgICAgICogICAgICB3aGljaCBpcyBiZWluZyBhc3NpZ25lZCB0bywgaXNzdWUgYW4gdW5jaGVja2VkIHdhcm5pbmcgaWYgaXRzCiAgICAgICAgICogICAgICB0eXBlIGNoYW5nZXMgdW5kZXIgZXJhc3VyZS4KICAgICAgICAgKiAgKDUpIGlmIHN5bWJvbCBpcyBhbiBpbnN0YW5jZSBtZXRob2Qgb2YgYSByYXcgdHlwZSwgaXNzdWUgYW4KICAgICAgICAgKiAgICAgIHVuY2hlY2tlZCB3YXJuaW5nIGlmIGl0cyBhcmd1bWVudCB0eXBlcyBjaGFuZ2UgdW5kZXIgZXJhc3VyZS4KICAgICAgICAgKiAgSWYgY2hlY2tzIHN1Y2NlZWQ6CiAgICAgICAgICogICAgSWYgc3ltYm9sIGlzIGEgY29uc3RhbnQsIHJldHVybiBpdHMgY29uc3RhbnQgdHlwZQogICAgICAgICAqICAgIGVsc2UgaWYgc3ltYm9sIGlzIGEgbWV0aG9kLCByZXR1cm4gaXRzIHJlc3VsdCB0eXBlCiAgICAgICAgICogICAgb3RoZXJ3aXNlIHJldHVybiBpdHMgdHlwZS4KICAgICAgICAgKiAgT3RoZXJ3aXNlIHJldHVybiBlcnJUeXBlLgogICAgICAgICAqCiAgICAgICAgICogIEBwYXJhbSB0cmVlICAgICAgIFRoZSBzeW50YXggdHJlZSByZXByZXNlbnRpbmcgdGhlIGlkZW50aWZpZXIKICAgICAgICAgKiAgQHBhcmFtIHNpdGUgICAgICAgSWYgdGhpcyBpcyBhIHNlbGVjdCwgdGhlIHR5cGUgb2YgdGhlIHNlbGVjdGVkCiAgICAgICAgICogICAgICAgICAgICAgICAgICAgIGV4cHJlc3Npb24sIG90aGVyd2lzZSB0aGUgdHlwZSBvZiB0aGUgY3VycmVudCBjbGFzcy4KICAgICAgICAgKiAgQHBhcmFtIHN5bSAgICAgICAgVGhlIHN5bWJvbCByZXByZXNlbnRpbmcgdGhlIGlkZW50aWZpZXIuCiAgICAgICAgICogIEBwYXJhbSBlbnYgICAgICAgIFRoZSBjdXJyZW50IGVudmlyb25tZW50LgogICAgICAgICAqICBAcGFyYW0gcmVzdWx0SW5mbyAgICBUaGUgZXhwZWN0ZWQgcmVzdWx0CiAgICAgICAgICovCiAgICAgICAgVHlwZSBjaGVja0lkKEpDVHJlZSB0cmVlLAogICAgICAgICAgICAgICAgICAgICBUeXBlIHNpdGUsCiAgICAgICAgICAgICAgICAgICAgIFN5bWJvbCBzeW0sCiAgICAgICAgICAgICAgICAgICAgIEVudjxBdHRyQ29udGV4dD4gZW52LAogICAgICAgICAgICAgICAgICAgICBSZXN1bHRJbmZvIHJlc3VsdEluZm8pIHsKICAgICAgICAgICAgcmV0dXJuIChyZXN1bHRJbmZvLnB0Lmhhc1RhZyhGT1JBTEwpIHx8IHJlc3VsdEluZm8ucHQuaGFzVGFnKE1FVEhPRCkpID8KICAgICAgICAgICAgICAgICAgICBjaGVja01ldGhvZElkKHRyZWUsIHNpdGUsIHN5bSwgZW52LCByZXN1bHRJbmZvKSA6CiAgICAgICAgICAgICAgICAgICAgY2hlY2tJZEludGVybmFsKHRyZWUsIHNpdGUsIHN5bSwgcmVzdWx0SW5mby5wdCwgZW52LCByZXN1bHRJbmZvKTsKICAgICAgICB9CgogICAgICAgIFR5cGUgY2hlY2tNZXRob2RJZChKQ1RyZWUgdHJlZSwKICAgICAgICAgICAgICAgICAgICAgVHlwZSBzaXRlLAogICAgICAgICAgICAgICAgICAgICBTeW1ib2wgc3ltLAogICAgICAgICAgICAgICAgICAgICBFbnY8QXR0ckNvbnRleHQ+IGVudiwKICAgICAgICAgICAgICAgICAgICAgUmVzdWx0SW5mbyByZXN1bHRJbmZvKSB7CiAgICAgICAgICAgIGJvb2xlYW4gaXNQb2x5bW9yaGljU2lnbmF0dXJlID0KICAgICAgICAgICAgICAgIChzeW0uYmFzZVN5bWJvbCgpLmZsYWdzKCkgJiBTSUdOQVRVUkVfUE9MWU1PUlBISUMpICE9IDA7CiAgICAgICAgICAgIHJldHVybiBpc1BvbHltb3JoaWNTaWduYXR1cmUgPwogICAgICAgICAgICAgICAgICAgIGNoZWNrU2lnUG9seU1ldGhvZElkKHRyZWUsIHNpdGUsIHN5bSwgZW52LCByZXN1bHRJbmZvKSA6CiAgICAgICAgICAgICAgICAgICAgY2hlY2tNZXRob2RJZEludGVybmFsKHRyZWUsIHNpdGUsIHN5bSwgZW52LCByZXN1bHRJbmZvKTsKICAgICAgICB9CgogICAgICAgIFR5cGUgY2hlY2tTaWdQb2x5TWV0aG9kSWQoSkNUcmVlIHRyZWUsCiAgICAgICAgICAgICAgICAgICAgIFR5cGUgc2l0ZSwKICAgICAgICAgICAgICAgICAgICAgU3ltYm9sIHN5bSwKICAgICAgICAgICAgICAgICAgICAgRW52PEF0dHJDb250ZXh0PiBlbnYsCiAgICAgICAgICAgICAgICAgICAgIFJlc3VsdEluZm8gcmVzdWx0SW5mbykgewogICAgICAgICAgICAvL3JlY292ZXIgb3JpZ2luYWwgc3ltYm9sIGZvciBzaWduYXR1cmUgcG9seW1vcnBoaWMgbWV0aG9kcwogICAgICAgICAgICBjaGVja01ldGhvZElkSW50ZXJuYWwodHJlZSwgc2l0ZSwgc3ltLmJhc2VTeW1ib2woKSwgZW52LCByZXN1bHRJbmZvKTsKICAgICAgICAgICAgZW52LmluZm8ucGVuZGluZ1Jlc29sdXRpb25QaGFzZSA9IFJlc29sdmUuTWV0aG9kUmVzb2x1dGlvblBoYXNlLkJBU0lDOwogICAgICAgICAgICByZXR1cm4gc3ltLnR5cGU7CiAgICAgICAgfQoKICAgICAgICBUeXBlIGNoZWNrTWV0aG9kSWRJbnRlcm5hbChKQ1RyZWUgdHJlZSwKICAgICAgICAgICAgICAgICAgICAgVHlwZSBzaXRlLAogICAgICAgICAgICAgICAgICAgICBTeW1ib2wgc3ltLAogICAgICAgICAgICAgICAgICAgICBFbnY8QXR0ckNvbnRleHQ+IGVudiwKICAgICAgICAgICAgICAgICAgICAgUmVzdWx0SW5mbyByZXN1bHRJbmZvKSB7CiAgICAgICAgICAgIGlmIChyZXN1bHRJbmZvLnBraW5kLmNvbnRhaW5zKEtpbmRTZWxlY3Rvci5QT0xZKSkgewogICAgICAgICAgICAgICAgVHlwZSBwdCA9IHJlc3VsdEluZm8ucHQubWFwKGRlZmVycmVkQXR0ci5uZXcgUmVjb3ZlcnlEZWZlcnJlZFR5cGVNYXAoQXR0ck1vZGUuU1BFQ1VMQVRJVkUsIHN5bSwgZW52LmluZm8ucGVuZGluZ1Jlc29sdXRpb25QaGFzZSkpOwogICAgICAgICAgICAgICAgVHlwZSBvd250eXBlID0gY2hlY2tJZEludGVybmFsKHRyZWUsIHNpdGUsIHN5bSwgcHQsIGVudiwgcmVzdWx0SW5mbyk7CiAgICAgICAgICAgICAgICByZXN1bHRJbmZvLnB0Lm1hcChkZWZlcnJlZEF0dHIubmV3IFJlY292ZXJ5RGVmZXJyZWRUeXBlTWFwKEF0dHJNb2RlLkNIRUNLLCBzeW0sIGVudi5pbmZvLnBlbmRpbmdSZXNvbHV0aW9uUGhhc2UpKTsKICAgICAgICAgICAgICAgIHJldHVybiBvd250eXBlOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcmV0dXJuIGNoZWNrSWRJbnRlcm5hbCh0cmVlLCBzaXRlLCBzeW0sIHJlc3VsdEluZm8ucHQsIGVudiwgcmVzdWx0SW5mbyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIFR5cGUgY2hlY2tJZEludGVybmFsKEpDVHJlZSB0cmVlLAogICAgICAgICAgICAgICAgICAgICBUeXBlIHNpdGUsCiAgICAgICAgICAgICAgICAgICAgIFN5bWJvbCBzeW0sCiAgICAgICAgICAgICAgICAgICAgIFR5cGUgcHQsCiAgICAgICAgICAgICAgICAgICAgIEVudjxBdHRyQ29udGV4dD4gZW52LAogICAgICAgICAgICAgICAgICAgICBSZXN1bHRJbmZvIHJlc3VsdEluZm8pIHsKICAgICAgICAgICAgaWYgKHB0LmlzRXJyb25lb3VzKCkpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0eXBlcy5jcmVhdGVFcnJvclR5cGUoc2l0ZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgVHlwZSBvd250eXBlOyAvLyBUaGUgY29tcHV0ZWQgdHlwZSBvZiB0aGlzIGlkZW50aWZpZXIgb2NjdXJyZW5jZS4KICAgICAgICAgICAgc3dpdGNoIChzeW0ua2luZCkgewogICAgICAgICAgICBjYXNlIFRZUDoKICAgICAgICAgICAgICAgIC8vIEZvciB0eXBlcywgdGhlIGNvbXB1dGVkIHR5cGUgZXF1YWxzIHRoZSBzeW1ib2wncyB0eXBlLAogICAgICAgICAgICAgICAgLy8gZXhjZXB0IGZvciB0d28gc2l0dWF0aW9uczoKICAgICAgICAgICAgICAgIG93bnR5cGUgPSBzeW0udHlwZTsKICAgICAgICAgICAgICAgIGlmIChvd250eXBlLmhhc1RhZyhDTEFTUykpIHsKICAgICAgICAgICAgICAgICAgICBjaGsuY2hlY2tGb3JCYWRBdXhpbGlhcnlDbGFzc0FjY2Vzcyh0cmVlLnBvcygpLCBlbnYsIChDbGFzc1N5bWJvbClzeW0pOwogICAgICAgICAgICAgICAgICAgIFR5cGUgb3duT3V0ZXIgPSBvd250eXBlLmdldEVuY2xvc2luZ1R5cGUoKTsKCiAgICAgICAgICAgICAgICAgICAgLy8gKGEpIElmIHRoZSBzeW1ib2wncyB0eXBlIGlzIHBhcmFtZXRlcml6ZWQsIGVyYXNlIGl0CiAgICAgICAgICAgICAgICAgICAgLy8gYmVjYXVzZSBubyB0eXBlIHBhcmFtZXRlcnMgd2VyZSBnaXZlbi4KICAgICAgICAgICAgICAgICAgICAvLyBXZSByZWNvdmVyIGdlbmVyaWMgb3V0ZXIgdHlwZSBsYXRlciBpbiB2aXNpdFR5cGVBcHBseS4KICAgICAgICAgICAgICAgICAgICBpZiAob3dudHlwZS50c3ltLnR5cGUuZ2V0VHlwZUFyZ3VtZW50cygpLm5vbkVtcHR5KCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgb3dudHlwZSA9IHR5cGVzLmVyYXN1cmUob3dudHlwZSk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAvLyAoYikgSWYgdGhlIHN5bWJvbCdzIHR5cGUgaXMgYW4gaW5uZXIgY2xhc3MsIHRoZW4KICAgICAgICAgICAgICAgICAgICAvLyB3ZSBoYXZlIHRvIGludGVycHJldCBpdHMgb3V0ZXIgdHlwZSBhcyBhIHN1cGVyY2xhc3MKICAgICAgICAgICAgICAgICAgICAvLyBvZiB0aGUgc2l0ZSB0eXBlLiBFeGFtcGxlOgogICAgICAgICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICAgICAgICAgLy8gY2xhc3MgVHJlZTxBPiB7IGNsYXNzIFZpc2l0b3IgeyAuLi4gfSB9CiAgICAgICAgICAgICAgICAgICAgLy8gY2xhc3MgUG9pbnRUcmVlIGV4dGVuZHMgVHJlZTxQb2ludD4geyAuLi4gfQogICAgICAgICAgICAgICAgICAgIC8vIC4uLlBvaW50VHJlZS5WaXNpdG9yLi4uCiAgICAgICAgICAgICAgICAgICAgLy8KICAgICAgICAgICAgICAgICAgICAvLyBUaGVuIHRoZSB0eXBlIG9mIHRoZSBsYXN0IGV4cHJlc3Npb24gYWJvdmUgaXMKICAgICAgICAgICAgICAgICAgICAvLyBUcmVlPFBvaW50Pi5WaXNpdG9yLgogICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKG93bk91dGVyLmhhc1RhZyhDTEFTUykgJiYgc2l0ZSAhPSBvd25PdXRlcikgewogICAgICAgICAgICAgICAgICAgICAgICBUeXBlIG5vcm1PdXRlciA9IHNpdGU7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChub3JtT3V0ZXIuaGFzVGFnKENMQVNTKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9ybU91dGVyID0gdHlwZXMuYXNFbmNsb3NpbmdTdXBlcihzaXRlLCBvd25PdXRlci50c3ltKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBpZiAobm9ybU91dGVyID09IG51bGwpIC8vIHBlcmhhcHMgZnJvbSBhbiBpbXBvcnQKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vcm1PdXRlciA9IHR5cGVzLmVyYXN1cmUob3duT3V0ZXIpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAobm9ybU91dGVyICE9IG93bk91dGVyKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgb3dudHlwZSA9IG5ldyBDbGFzc1R5cGUoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9ybU91dGVyLCBMaXN0Lm5pbCgpLCBvd250eXBlLnRzeW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3dudHlwZS5nZXRNZXRhZGF0YSgpKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBWQVI6CiAgICAgICAgICAgICAgICBWYXJTeW1ib2wgdiA9IChWYXJTeW1ib2wpc3ltOwogICAgICAgICAgICAgICAgLy8gVGVzdCAoNCk6IGlmIHN5bWJvbCBpcyBhbiBpbnN0YW5jZSBmaWVsZCBvZiBhIHJhdyB0eXBlLAogICAgICAgICAgICAgICAgLy8gd2hpY2ggaXMgYmVpbmcgYXNzaWduZWQgdG8sIGlzc3VlIGFuIHVuY2hlY2tlZCB3YXJuaW5nIGlmCiAgICAgICAgICAgICAgICAvLyBpdHMgdHlwZSBjaGFuZ2VzIHVuZGVyIGVyYXN1cmUuCiAgICAgICAgICAgICAgICBpZiAoS2luZFNlbGVjdG9yLkFTRy5zdWJzZXQocGtpbmQoKSkgJiYKICAgICAgICAgICAgICAgICAgICB2Lm93bmVyLmtpbmQgPT0gVFlQICYmCiAgICAgICAgICAgICAgICAgICAgKHYuZmxhZ3MoKSAmIFNUQVRJQykgPT0gMCAmJgogICAgICAgICAgICAgICAgICAgIChzaXRlLmhhc1RhZyhDTEFTUykgfHwgc2l0ZS5oYXNUYWcoVFlQRVZBUikpKSB7CiAgICAgICAgICAgICAgICAgICAgVHlwZSBzID0gdHlwZXMuYXNPdXRlclN1cGVyKHNpdGUsIHYub3duZXIpOwogICAgICAgICAgICAgICAgICAgIGlmIChzICE9IG51bGwgJiYKICAgICAgICAgICAgICAgICAgICAgICAgcy5pc1JhdygpICYmCiAgICAgICAgICAgICAgICAgICAgICAgICF0eXBlcy5pc1NhbWVUeXBlKHYudHlwZSwgdi5lcmFzdXJlKHR5cGVzKSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY2hrLndhcm5VbmNoZWNrZWQodHJlZS5wb3MoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInVuY2hlY2tlZC5hc3NpZ24udG8udmFyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdiwgcyk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgLy8gVGhlIGNvbXB1dGVkIHR5cGUgb2YgYSB2YXJpYWJsZSBpcyB0aGUgdHlwZSBvZiB0aGUKICAgICAgICAgICAgICAgIC8vIHZhcmlhYmxlIHN5bWJvbCwgdGFrZW4gYXMgYSBtZW1iZXIgb2YgdGhlIHNpdGUgdHlwZS4KICAgICAgICAgICAgICAgIG93bnR5cGUgPSAoc3ltLm93bmVyLmtpbmQgPT0gVFlQICYmCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5bS5uYW1lICE9IG5hbWVzLl90aGlzICYmIHN5bS5uYW1lICE9IG5hbWVzLl9zdXBlcikKICAgICAgICAgICAgICAgICAgICA/IHR5cGVzLm1lbWJlclR5cGUoc2l0ZSwgc3ltKQogICAgICAgICAgICAgICAgICAgIDogc3ltLnR5cGU7CgogICAgICAgICAgICAgICAgLy8gSWYgdGhlIHZhcmlhYmxlIGlzIGEgY29uc3RhbnQsIHJlY29yZCBjb25zdGFudCB2YWx1ZSBpbgogICAgICAgICAgICAgICAgLy8gY29tcHV0ZWQgdHlwZS4KICAgICAgICAgICAgICAgIGlmICh2LmdldENvbnN0VmFsdWUoKSAhPSBudWxsICYmIGlzU3RhdGljUmVmZXJlbmNlKHRyZWUpKQogICAgICAgICAgICAgICAgICAgIG93bnR5cGUgPSBvd250eXBlLmNvbnN0VHlwZSh2LmdldENvbnN0VmFsdWUoKSk7CgogICAgICAgICAgICAgICAgaWYgKHJlc3VsdEluZm8ucGtpbmQgPT0gS2luZFNlbGVjdG9yLlZBTCkgewogICAgICAgICAgICAgICAgICAgIG93bnR5cGUgPSBjYXB0dXJlKG93bnR5cGUpOyAvLyBjYXB0dXJlICJuYW1lcyBhcyBleHByZXNzaW9ucyIKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIE1USDogewogICAgICAgICAgICAgICAgb3dudHlwZSA9IGNoZWNrTWV0aG9kKHNpdGUsIHN5bSwKICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFJlc3VsdEluZm8ocmVzdWx0SW5mby5wa2luZCwgcmVzdWx0SW5mby5wdC5nZXRSZXR1cm5UeXBlKCksIHJlc3VsdEluZm8uY2hlY2tDb250ZXh0KSwKICAgICAgICAgICAgICAgICAgICAgICAgZW52LCBUcmVlSW5mby5hcmdzKGVudi50cmVlKSwgcmVzdWx0SW5mby5wdC5nZXRQYXJhbWV0ZXJUeXBlcygpLAogICAgICAgICAgICAgICAgICAgICAgICByZXN1bHRJbmZvLnB0LmdldFR5cGVBcmd1bWVudHMoKSk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBjYXNlIFBDSzogY2FzZSBFUlI6CiAgICAgICAgICAgICAgICBvd250eXBlID0gc3ltLnR5cGU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigidW5leHBlY3RlZCBraW5kOiAiICsgc3ltLmtpbmQgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgaW4gdHJlZSAiICsgdHJlZSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIEVtaXQgYSBgZGVwcmVjYXRpb24nIHdhcm5pbmcgaWYgc3ltYm9sIGlzIGRlcHJlY2F0ZWQuCiAgICAgICAgICAgIC8vIChmb3IgY29uc3RydWN0b3JzIChidXQgbm90IGZvciBjb25zdHJ1Y3RvciByZWZlcmVuY2VzKSwgdGhlIGVycm9yCiAgICAgICAgICAgIC8vIHdhcyBnaXZlbiB3aGVuIHRoZSBjb25zdHJ1Y3RvciB3YXMgcmVzb2x2ZWQpCgogICAgICAgICAgICBpZiAoc3ltLm5hbWUgIT0gbmFtZXMuaW5pdCB8fCB0cmVlLmhhc1RhZyhSRUZFUkVOQ0UpKSB7CiAgICAgICAgICAgICAgICBjaGsuY2hlY2tEZXByZWNhdGVkKHRyZWUucG9zKCksIGVudi5pbmZvLnNjb3BlLm93bmVyLCBzeW0pOwogICAgICAgICAgICAgICAgY2hrLmNoZWNrU3VuQVBJKHRyZWUucG9zKCksIHN5bSk7CiAgICAgICAgICAgICAgICBjaGsuY2hlY2tQcm9maWxlKHRyZWUucG9zKCksIHN5bSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIElmIHN5bWJvbCBpcyBhIHZhcmlhYmxlLCBjaGVjayB0aGF0IGl0cyB0eXBlIGFuZAogICAgICAgICAgICAvLyBraW5kIGFyZSBjb21wYXRpYmxlIHdpdGggdGhlIHByb3RvdHlwZSBhbmQgcHJvdG9raW5kLgogICAgICAgICAgICByZXR1cm4gY2hlY2sodHJlZSwgb3dudHlwZSwgc3ltLmtpbmQudG9TZWxlY3RvcigpLCByZXN1bHRJbmZvKTsKICAgICAgICB9CgogICAgICAgIC8qKiBDaGVjayB0aGF0IHZhcmlhYmxlIGlzIGluaXRpYWxpemVkIGFuZCBldmFsdWF0ZSB0aGUgdmFyaWFibGUncwogICAgICAgICAqICBpbml0aWFsaXplciwgaWYgbm90IHlldCBkb25lLiBBbHNvIGNoZWNrIHRoYXQgdmFyaWFibGUgaXMgbm90CiAgICAgICAgICogIHJlZmVyZW5jZWQgYmVmb3JlIGl0IGlzIGRlZmluZWQuCiAgICAgICAgICogIEBwYXJhbSB0cmVlICAgIFRoZSB0cmVlIG1ha2luZyB1cCB0aGUgdmFyaWFibGUgcmVmZXJlbmNlLgogICAgICAgICAqICBAcGFyYW0gZW52ICAgICBUaGUgY3VycmVudCBlbnZpcm9ubWVudC4KICAgICAgICAgKiAgQHBhcmFtIHYgICAgICAgVGhlIHZhcmlhYmxlJ3Mgc3ltYm9sLgogICAgICAgICAqLwogICAgICAgIHByaXZhdGUgdm9pZCBjaGVja0luaXQoSkNUcmVlIHRyZWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFbnY8QXR0ckNvbnRleHQ+IGVudiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZhclN5bWJvbCB2LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBvbmx5V2FybmluZykgewogICAgICAgICAgICAvLyBBIGZvcndhcmQgcmVmZXJlbmNlIGlzIGRpYWdub3NlZCBpZiB0aGUgZGVjbGFyYXRpb24gcG9zaXRpb24KICAgICAgICAgICAgLy8gb2YgdGhlIHZhcmlhYmxlIGlzIGdyZWF0ZXIgdGhhbiB0aGUgY3VycmVudCB0cmVlIHBvc2l0aW9uCiAgICAgICAgICAgIC8vIGFuZCB0aGUgdHJlZSBhbmQgdmFyaWFibGUgZGVmaW5pdGlvbiBvY2N1ciBpbiB0aGUgc2FtZSBjbGFzcwogICAgICAgICAgICAvLyBkZWZpbml0aW9uLiAgTm90ZSB0aGF0IHdyaXRlcyBkb24ndCBjb3VudCBhcyByZWZlcmVuY2VzLgogICAgICAgICAgICAvLyBUaGlzIGNoZWNrIGFwcGxpZXMgb25seSB0byBjbGFzcyBhbmQgaW5zdGFuY2UKICAgICAgICAgICAgLy8gdmFyaWFibGVzLiAgTG9jYWwgdmFyaWFibGVzIGZvbGxvdyBkaWZmZXJlbnQgc2NvcGUgcnVsZXMsCiAgICAgICAgICAgIC8vIGFuZCBhcmUgc3ViamVjdCB0byBkZWZpbml0ZSBhc3NpZ25tZW50IGNoZWNraW5nLgogICAgICAgICAgICBFbnY8QXR0ckNvbnRleHQ+IGluaXRFbnYgPSBlbmNsb3NpbmdJbml0RW52KGVudik7CiAgICAgICAgICAgIGlmIChpbml0RW52ICE9IG51bGwgJiYKICAgICAgICAgICAgICAgIChpbml0RW52LmluZm8uZW5jbFZhciA9PSB2IHx8IHYucG9zID4gdHJlZS5wb3MpICYmCiAgICAgICAgICAgICAgICB2Lm93bmVyLmtpbmQgPT0gVFlQICYmCiAgICAgICAgICAgICAgICB2Lm93bmVyID09IGVudi5pbmZvLnNjb3BlLm93bmVyLmVuY2xDbGFzcygpICYmCiAgICAgICAgICAgICAgICAoKHYuZmxhZ3MoKSAmIFNUQVRJQykgIT0gMCkgPT0gUmVzb2x2ZS5pc1N0YXRpYyhlbnYpICYmCiAgICAgICAgICAgICAgICAoIWVudi50cmVlLmhhc1RhZyhBU1NJR04pIHx8CiAgICAgICAgICAgICAgICAgVHJlZUluZm8uc2tpcFBhcmVucygoKEpDQXNzaWduKSBlbnYudHJlZSkubGhzKSAhPSB0cmVlKSkgewogICAgICAgICAgICAgICAgU3RyaW5nIHN1ZmZpeCA9IChpbml0RW52LmluZm8uZW5jbFZhciA9PSB2KSA/CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInNlbGYucmVmIiA6ICJmb3J3YXJkLnJlZiI7CiAgICAgICAgICAgICAgICBpZiAoIW9ubHlXYXJuaW5nIHx8IGlzU3RhdGljRW51bUZpZWxkKHYpKSB7CiAgICAgICAgICAgICAgICAgICAgbG9nLmVycm9yKHRyZWUucG9zKCksICJpbGxlZ2FsLiIgKyBzdWZmaXgpOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmICh1c2VCZWZvcmVEZWNsYXJhdGlvbldhcm5pbmcpIHsKICAgICAgICAgICAgICAgICAgICBsb2cud2FybmluZyh0cmVlLnBvcygpLCBzdWZmaXgsIHYpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICB2LmdldENvbnN0VmFsdWUoKTsgLy8gZW5zdXJlIGluaXRpYWxpemVyIGlzIGV2YWx1YXRlZAoKICAgICAgICAgICAgY2hlY2tFbnVtSW5pdGlhbGl6ZXIodHJlZSwgZW52LCB2KTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIFJldHVybnMgdGhlIGVuY2xvc2luZyBpbml0IGVudmlyb25tZW50IGFzc29jaWF0ZWQgd2l0aCB0aGlzIGVudiAoaWYgYW55KS4gQW4gaW5pdCBlbnYKICAgICAgICAgKiBjYW4gYmUgZWl0aGVyIGEgZmllbGQgZGVjbGFyYXRpb24gZW52IG9yIGEgc3RhdGljL2luc3RhbmNlIGluaXRpYWxpemVyIGVudi4KICAgICAgICAgKi8KICAgICAgICBFbnY8QXR0ckNvbnRleHQ+IGVuY2xvc2luZ0luaXRFbnYoRW52PEF0dHJDb250ZXh0PiBlbnYpIHsKICAgICAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgICAgICAgIHN3aXRjaCAoZW52LnRyZWUuZ2V0VGFnKCkpIHsKICAgICAgICAgICAgICAgICAgICBjYXNlIFZBUkRFRjoKICAgICAgICAgICAgICAgICAgICAgICAgSkNWYXJpYWJsZURlY2wgdmRlY2wgPSAoSkNWYXJpYWJsZURlY2wpZW52LnRyZWU7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2ZGVjbC5zeW0ub3duZXIua2luZCA9PSBUWVApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vZmllbGQKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBlbnY7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBCTE9DSzoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVudi5uZXh0LnRyZWUuaGFzVGFnKENMQVNTREVGKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9pbnN0YW5jZS9zdGF0aWMgaW5pdGlhbGl6ZXIKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBlbnY7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBNRVRIT0RERUY6CiAgICAgICAgICAgICAgICAgICAgY2FzZSBDTEFTU0RFRjoKICAgICAgICAgICAgICAgICAgICBjYXNlIFRPUExFVkVMOgogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIEFzc2VydC5jaGVja05vbk51bGwoZW52Lm5leHQpOwogICAgICAgICAgICAgICAgZW52ID0gZW52Lm5leHQ7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIENoZWNrIGZvciBpbGxlZ2FsIHJlZmVyZW5jZXMgdG8gc3RhdGljIG1lbWJlcnMgb2YgZW51bS4gIEluCiAgICAgICAgICogYW4gZW51bSB0eXBlLCBjb25zdHJ1Y3RvcnMgYW5kIGluaXRpYWxpemVycyBtYXkgbm90CiAgICAgICAgICogcmVmZXJlbmNlIGl0cyBzdGF0aWMgbWVtYmVycyB1bmxlc3MgdGhleSBhcmUgY29uc3RhbnQuCiAgICAgICAgICoKICAgICAgICAgKiBAcGFyYW0gdHJlZSAgICBUaGUgdHJlZSBtYWtpbmcgdXAgdGhlIHZhcmlhYmxlIHJlZmVyZW5jZS4KICAgICAgICAgKiBAcGFyYW0gZW52ICAgICBUaGUgY3VycmVudCBlbnZpcm9ubWVudC4KICAgICAgICAgKiBAcGFyYW0gdiAgICAgICBUaGUgdmFyaWFibGUncyBzeW1ib2wuCiAgICAgICAgICogQGpscyAgc2VjdGlvbiA4LjkgRW51bXMKICAgICAgICAgKi8KICAgICAgICBwcml2YXRlIHZvaWQgY2hlY2tFbnVtSW5pdGlhbGl6ZXIoSkNUcmVlIHRyZWUsIEVudjxBdHRyQ29udGV4dD4gZW52LCBWYXJTeW1ib2wgdikgewogICAgICAgICAgICAvLyBKTFM6CiAgICAgICAgICAgIC8vCiAgICAgICAgICAgIC8vICJJdCBpcyBhIGNvbXBpbGUtdGltZSBlcnJvciB0byByZWZlcmVuY2UgYSBzdGF0aWMgZmllbGQKICAgICAgICAgICAgLy8gb2YgYW4gZW51bSB0eXBlIHRoYXQgaXMgbm90IGEgY29tcGlsZS10aW1lIGNvbnN0YW50CiAgICAgICAgICAgIC8vICgxNS4yOCkgZnJvbSBjb25zdHJ1Y3RvcnMsIGluc3RhbmNlIGluaXRpYWxpemVyIGJsb2NrcywKICAgICAgICAgICAgLy8gb3IgaW5zdGFuY2UgdmFyaWFibGUgaW5pdGlhbGl6ZXIgZXhwcmVzc2lvbnMgb2YgdGhhdAogICAgICAgICAgICAvLyB0eXBlLiBJdCBpcyBhIGNvbXBpbGUtdGltZSBlcnJvciBmb3IgdGhlIGNvbnN0cnVjdG9ycywKICAgICAgICAgICAgLy8gaW5zdGFuY2UgaW5pdGlhbGl6ZXIgYmxvY2tzLCBvciBpbnN0YW5jZSB2YXJpYWJsZQogICAgICAgICAgICAvLyBpbml0aWFsaXplciBleHByZXNzaW9ucyBvZiBhbiBlbnVtIGNvbnN0YW50IGUgdG8gcmVmZXIKICAgICAgICAgICAgLy8gdG8gaXRzZWxmIG9yIHRvIGFuIGVudW0gY29uc3RhbnQgb2YgdGhlIHNhbWUgdHlwZSB0aGF0CiAgICAgICAgICAgIC8vIGlzIGRlY2xhcmVkIHRvIHRoZSByaWdodCBvZiBlLiIKICAgICAgICAgICAgaWYgKGlzU3RhdGljRW51bUZpZWxkKHYpKSB7CiAgICAgICAgICAgICAgICBDbGFzc1N5bWJvbCBlbmNsQ2xhc3MgPSBlbnYuaW5mby5zY29wZS5vd25lci5lbmNsQ2xhc3MoKTsKCiAgICAgICAgICAgICAgICBpZiAoZW5jbENsYXNzID09IG51bGwgfHwgZW5jbENsYXNzLm93bmVyID09IG51bGwpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwoKICAgICAgICAgICAgICAgIC8vIFNlZSBpZiB0aGUgZW5jbG9zaW5nIGNsYXNzIGlzIHRoZSBlbnVtIChvciBhCiAgICAgICAgICAgICAgICAvLyBzdWJjbGFzcyB0aGVyZW9mKSBkZWNsYXJpbmcgdi4gIElmIG5vdCwgdGhpcwogICAgICAgICAgICAgICAgLy8gcmVmZXJlbmNlIGlzIE9LLgogICAgICAgICAgICAgICAgaWYgKHYub3duZXIgIT0gZW5jbENsYXNzICYmICF0eXBlcy5pc1N1YnR5cGUoZW5jbENsYXNzLnR5cGUsIHYub3duZXIudHlwZSkpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwoKICAgICAgICAgICAgICAgIC8vIElmIHRoZSByZWZlcmVuY2UgaXNuJ3QgZnJvbSBhbiBpbml0aWFsaXplciwgdGhlbgogICAgICAgICAgICAgICAgLy8gdGhlIHJlZmVyZW5jZSBpcyBPSy4KICAgICAgICAgICAgICAgIGlmICghUmVzb2x2ZS5pc0luaXRpYWxpemVyKGVudikpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwoKICAgICAgICAgICAgICAgIGxvZy5lcnJvcih0cmVlLnBvcygpLCAiaWxsZWdhbC5lbnVtLnN0YXRpYy5yZWYiKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLyoqIElzIHRoZSBnaXZlbiBzeW1ib2wgYSBzdGF0aWMsIG5vbi1jb25zdGFudCBmaWVsZCBvZiBhbiBFbnVtPwogICAgICAgICAqICBOb3RlOiBlbnVtIGxpdGVyYWxzIHNob3VsZCBub3QgYmUgcmVnYXJkZWQgYXMgc3VjaAogICAgICAgICAqLwogICAgICAgIHByaXZhdGUgYm9vbGVhbiBpc1N0YXRpY0VudW1GaWVsZChWYXJTeW1ib2wgdikgewogICAgICAgICAgICByZXR1cm4gRmxhZ3MuaXNFbnVtKHYub3duZXIpICYmCiAgICAgICAgICAgICAgICAgICBGbGFncy5pc1N0YXRpYyh2KSAmJgogICAgICAgICAgICAgICAgICAgIUZsYWdzLmlzQ29uc3RhbnQodikgJiYKICAgICAgICAgICAgICAgICAgIHYubmFtZSAhPSBuYW1lcy5fY2xhc3M7CiAgICAgICAgfQoKICAgIC8qKgogICAgICogQ2hlY2sgdGhhdCBtZXRob2QgYXJndW1lbnRzIGNvbmZvcm0gdG8gaXRzIGluc3RhbnRpYXRpb24uCiAgICAgKiovCiAgICBwdWJsaWMgVHlwZSBjaGVja01ldGhvZChUeXBlIHNpdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBTeW1ib2wgc3ltLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVzdWx0SW5mbyByZXN1bHRJbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgRW52PEF0dHJDb250ZXh0PiBlbnYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBMaXN0PEpDRXhwcmVzc2lvbj4gYXJndHJlZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IGFyZ3R5cGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgTGlzdDxUeXBlPiB0eXBlYXJndHlwZXMpIHsKICAgICAgICAvLyBUZXN0ICg1KTogaWYgc3ltYm9sIGlzIGFuIGluc3RhbmNlIG1ldGhvZCBvZiBhIHJhdyB0eXBlLCBpc3N1ZQogICAgICAgIC8vIGFuIHVuY2hlY2tlZCB3YXJuaW5nIGlmIGl0cyBhcmd1bWVudCB0eXBlcyBjaGFuZ2UgdW5kZXIgZXJhc3VyZS4KICAgICAgICBpZiAoKHN5bS5mbGFncygpICYgU1RBVElDKSA9PSAwICYmCiAgICAgICAgICAgIChzaXRlLmhhc1RhZyhDTEFTUykgfHwgc2l0ZS5oYXNUYWcoVFlQRVZBUikpKSB7CiAgICAgICAgICAgIFR5cGUgcyA9IHR5cGVzLmFzT3V0ZXJTdXBlcihzaXRlLCBzeW0ub3duZXIpOwogICAgICAgICAgICBpZiAocyAhPSBudWxsICYmIHMuaXNSYXcoKSAmJgogICAgICAgICAgICAgICAgIXR5cGVzLmlzU2FtZVR5cGVzKHN5bS50eXBlLmdldFBhcmFtZXRlclR5cGVzKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ltLmVyYXN1cmUodHlwZXMpLmdldFBhcmFtZXRlclR5cGVzKCkpKSB7CiAgICAgICAgICAgICAgICBjaGsud2FyblVuY2hlY2tlZChlbnYudHJlZS5wb3MoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ1bmNoZWNrZWQuY2FsbC5tYnIub2YucmF3LnR5cGUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ltLCBzKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKGVudi5pbmZvLmRlZmF1bHRTdXBlckNhbGxTaXRlICE9IG51bGwpIHsKICAgICAgICAgICAgZm9yIChUeXBlIHN1cCA6IHR5cGVzLmludGVyZmFjZXMoZW52LmVuY2xDbGFzcy50eXBlKS5wcmVwZW5kKHR5cGVzLnN1cGVydHlwZSgoZW52LmVuY2xDbGFzcy50eXBlKSkpKSB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cC50c3ltLmlzU3ViQ2xhc3Moc3ltLmVuY2xDbGFzcygpLCB0eXBlcykgfHwKICAgICAgICAgICAgICAgICAgICAgICAgdHlwZXMuaXNTYW1lVHlwZShzdXAsIGVudi5pbmZvLmRlZmF1bHRTdXBlckNhbGxTaXRlKSkgY29udGludWU7CiAgICAgICAgICAgICAgICBMaXN0PE1ldGhvZFN5bWJvbD4gaWNhbmRfc3VwID0KICAgICAgICAgICAgICAgICAgICAgICAgdHlwZXMuaW50ZXJmYWNlQ2FuZGlkYXRlcyhzdXAsIChNZXRob2RTeW1ib2wpc3ltKTsKICAgICAgICAgICAgICAgIGlmIChpY2FuZF9zdXAubm9uRW1wdHkoKSAmJgogICAgICAgICAgICAgICAgICAgICAgICBpY2FuZF9zdXAuaGVhZCAhPSBzeW0gJiYKICAgICAgICAgICAgICAgICAgICAgICAgaWNhbmRfc3VwLmhlYWQub3ZlcnJpZGVzKHN5bSwgaWNhbmRfc3VwLmhlYWQuZW5jbENsYXNzKCksIHR5cGVzLCB0cnVlKSkgewogICAgICAgICAgICAgICAgICAgIGxvZy5lcnJvcihlbnYudHJlZS5wb3MoKSwgImlsbGVnYWwuZGVmYXVsdC5zdXBlci5jYWxsIiwgZW52LmluZm8uZGVmYXVsdFN1cGVyQ2FsbFNpdGUsCiAgICAgICAgICAgICAgICAgICAgICAgIGRpYWdzLmZyYWdtZW50KCJvdmVycmlkZGVuLmRlZmF1bHQiLCBzeW0sIHN1cCkpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVudi5pbmZvLmRlZmF1bHRTdXBlckNhbGxTaXRlID0gbnVsbDsKICAgICAgICB9CgogICAgICAgIGlmIChzeW0uaXNTdGF0aWMoKSAmJiBzaXRlLmlzSW50ZXJmYWNlKCkgJiYgZW52LnRyZWUuaGFzVGFnKEFQUExZKSkgewogICAgICAgICAgICBKQ01ldGhvZEludm9jYXRpb24gYXBwID0gKEpDTWV0aG9kSW52b2NhdGlvbillbnYudHJlZTsKICAgICAgICAgICAgaWYgKGFwcC5tZXRoLmhhc1RhZyhTRUxFQ1QpICYmCiAgICAgICAgICAgICAgICAgICAgIVRyZWVJbmZvLmlzU3RhdGljU2VsZWN0b3IoKChKQ0ZpZWxkQWNjZXNzKWFwcC5tZXRoKS5zZWxlY3RlZCwgbmFtZXMpKSB7CiAgICAgICAgICAgICAgICBsb2cuZXJyb3IoZW52LnRyZWUucG9zKCksICJpbGxlZ2FsLnN0YXRpYy5pbnRmLm1ldGguY2FsbCIsIHNpdGUpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBDb21wdXRlIHRoZSBpZGVudGlmaWVyJ3MgaW5zdGFudGlhdGVkIHR5cGUuCiAgICAgICAgLy8gRm9yIG1ldGhvZHMsIHdlIG5lZWQgdG8gY29tcHV0ZSB0aGUgaW5zdGFuY2UgdHlwZSBieQogICAgICAgIC8vIFJlc29sdmUuaW5zdGFudGlhdGUgZnJvbSB0aGUgc3ltYm9sJ3MgdHlwZSBhcyB3ZWxsIGFzCiAgICAgICAgLy8gYW55IHR5cGUgYXJndW1lbnRzIGFuZCB2YWx1ZSBhcmd1bWVudHMuCiAgICAgICAgV2FybmVyIG5vdGVXYXJuZXIgPSBuZXcgV2FybmVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgVHlwZSBvd250eXBlID0gcnMuY2hlY2tNZXRob2QoCiAgICAgICAgICAgICAgICAgICAgZW52LAogICAgICAgICAgICAgICAgICAgIHNpdGUsCiAgICAgICAgICAgICAgICAgICAgc3ltLAogICAgICAgICAgICAgICAgICAgIHJlc3VsdEluZm8sCiAgICAgICAgICAgICAgICAgICAgYXJndHlwZXMsCiAgICAgICAgICAgICAgICAgICAgdHlwZWFyZ3R5cGVzLAogICAgICAgICAgICAgICAgICAgIG5vdGVXYXJuZXIpOwoKICAgICAgICAgICAgRGVmZXJyZWRBdHRyLkRlZmVycmVkVHlwZU1hcCBjaGVja0RlZmVycmVkTWFwID0KICAgICAgICAgICAgICAgIGRlZmVycmVkQXR0ci5uZXcgRGVmZXJyZWRUeXBlTWFwKERlZmVycmVkQXR0ci5BdHRyTW9kZS5DSEVDSywgc3ltLCBlbnYuaW5mby5wZW5kaW5nUmVzb2x1dGlvblBoYXNlKTsKCiAgICAgICAgICAgIGFyZ3R5cGVzID0gYXJndHlwZXMubWFwKGNoZWNrRGVmZXJyZWRNYXApOwoKICAgICAgICAgICAgaWYgKG5vdGVXYXJuZXIuaGFzTm9uU2lsZW50TGludChMaW50Q2F0ZWdvcnkuVU5DSEVDS0VEKSkgewogICAgICAgICAgICAgICAgY2hrLndhcm5VbmNoZWNrZWQoZW52LnRyZWUucG9zKCksCiAgICAgICAgICAgICAgICAgICAgICAgICJ1bmNoZWNrZWQubWV0aC5pbnZvY2F0aW9uLmFwcGxpZWQiLAogICAgICAgICAgICAgICAgICAgICAgICBraW5kTmFtZShzeW0pLAogICAgICAgICAgICAgICAgICAgICAgICBzeW0ubmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgcnMubWV0aG9kQXJndW1lbnRzKHN5bS50eXBlLmdldFBhcmFtZXRlclR5cGVzKCkpLAogICAgICAgICAgICAgICAgICAgICAgICBycy5tZXRob2RBcmd1bWVudHMoYXJndHlwZXMubWFwKGNoZWNrRGVmZXJyZWRNYXApKSwKICAgICAgICAgICAgICAgICAgICAgICAga2luZE5hbWUoc3ltLmxvY2F0aW9uKCkpLAogICAgICAgICAgICAgICAgICAgICAgICBzeW0ubG9jYXRpb24oKSk7CiAgICAgICAgICAgICAgICBpZiAocmVzdWx0SW5mby5wdCAhPSBJbmZlci5hbnlQb2x5IHx8CiAgICAgICAgICAgICAgICAgICAgICAgICFvd250eXBlLmhhc1RhZyhNRVRIT0QpIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICFvd250eXBlLmlzUGFydGlhbCgpKSB7CiAgICAgICAgICAgICAgICAgICAgLy9pZiB0aGlzIGlzIG5vdCBhIHBhcnRpYWxseSBpbmZlcnJlZCBtZXRob2QgdHlwZSwgZXJhc2UgcmV0dXJuIHR5cGUuIE90aGVyd2lzZSwKICAgICAgICAgICAgICAgICAgICAvL2VyYXN1cmUgaXMgY2FycmllZCBvdXQgaW4gUGFydGlhbGx5SW5mZXJyZWRNZXRob2RUeXBlLmNoZWNrKCkuCiAgICAgICAgICAgICAgICAgICAgb3dudHlwZSA9IG5ldyBNZXRob2RUeXBlKG93bnR5cGUuZ2V0UGFyYW1ldGVyVHlwZXMoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVzLmVyYXN1cmUob3dudHlwZS5nZXRSZXR1cm5UeXBlKCkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZXMuZXJhc3VyZShvd250eXBlLmdldFRocm93blR5cGVzKCkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ltcy5tZXRob2RDbGFzcyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIFBvbHlLaW5kIHBraW5kID0gKHN5bS50eXBlLmhhc1RhZyhGT1JBTEwpICYmCiAgICAgICAgICAgICAgICAgc3ltLnR5cGUuZ2V0UmV0dXJuVHlwZSgpLmNvbnRhaW5zQW55KCgoRm9yQWxsKXN5bS50eXBlKS50dmFycykpID8KICAgICAgICAgICAgICAgICBQb2x5S2luZC5QT0xZIDogUG9seUtpbmQuU1RBTkRBTE9ORTsKICAgICAgICAgICAgVHJlZUluZm8uc2V0UG9seUtpbmQoZW52LnRyZWUsIHBraW5kKTsKCiAgICAgICAgICAgIHJldHVybiAocmVzdWx0SW5mby5wdCA9PSBJbmZlci5hbnlQb2x5KSA/CiAgICAgICAgICAgICAgICAgICAgb3dudHlwZSA6CiAgICAgICAgICAgICAgICAgICAgY2hrLmNoZWNrTWV0aG9kKG93bnR5cGUsIHN5bSwgZW52LCBhcmd0cmVlcywgYXJndHlwZXMsIGVudi5pbmZvLmxhc3RSZXNvbHZlVmFyYXJncygpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0SW5mby5jaGVja0NvbnRleHQuaW5mZXJlbmNlQ29udGV4dCgpKTsKICAgICAgICB9IGNhdGNoIChJbmZlci5JbmZlcmVuY2VFeGNlcHRpb24gZXgpIHsKICAgICAgICAgICAgLy9pbnZhbGlkIHRhcmdldCB0eXBlIC0gcHJvcGFnYXRlIGV4Y2VwdGlvbiBvdXR3YXJkcyBvciByZXBvcnQgZXJyb3IKICAgICAgICAgICAgLy9kZXBlbmRpbmcgb24gdGhlIGN1cnJlbnQgY2hlY2sgY29udGV4dAogICAgICAgICAgICByZXN1bHRJbmZvLmNoZWNrQ29udGV4dC5yZXBvcnQoZW52LnRyZWUucG9zKCksIGV4LmdldERpYWdub3N0aWMoKSk7CiAgICAgICAgICAgIHJldHVybiB0eXBlcy5jcmVhdGVFcnJvclR5cGUoc2l0ZSk7CiAgICAgICAgfSBjYXRjaCAoUmVzb2x2ZS5JbmFwcGxpY2FibGVNZXRob2RFeGNlcHRpb24gZXgpIHsKICAgICAgICAgICAgZmluYWwgSkNEaWFnbm9zdGljIGRpYWcgPSBleC5nZXREaWFnbm9zdGljKCk7CiAgICAgICAgICAgIFJlc29sdmUuSW5hcHBsaWNhYmxlU3ltYm9sRXJyb3IgZXJyU3ltID0gcnMubmV3IEluYXBwbGljYWJsZVN5bWJvbEVycm9yKG51bGwpIHsKICAgICAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICAgICAgcHJvdGVjdGVkIFBhaXI8U3ltYm9sLCBKQ0RpYWdub3N0aWM+IGVyckNhbmRpZGF0ZSgpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFBhaXI8PihzeW0sIGRpYWcpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwogICAgICAgICAgICBMaXN0PFR5cGU+IGFyZ3R5cGVzMiA9IGFyZ3R5cGVzLm1hcCgKICAgICAgICAgICAgICAgICAgICBycy5uZXcgUmVzb2x2ZURlZmVycmVkUmVjb3ZlcnlNYXAoQXR0ck1vZGUuQ0hFQ0ssIHN5bSwgZW52LmluZm8ucGVuZGluZ1Jlc29sdXRpb25QaGFzZSkpOwogICAgICAgICAgICBKQ0RpYWdub3N0aWMgZXJyRGlhZyA9IGVyclN5bS5nZXREaWFnbm9zdGljKEpDRGlhZ25vc3RpYy5EaWFnbm9zdGljVHlwZS5FUlJPUiwKICAgICAgICAgICAgICAgICAgICBlbnYudHJlZSwgc3ltLCBzaXRlLCBzeW0ubmFtZSwgYXJndHlwZXMyLCB0eXBlYXJndHlwZXMpOwogICAgICAgICAgICBsb2cucmVwb3J0KGVyckRpYWcpOwogICAgICAgICAgICByZXR1cm4gdHlwZXMuY3JlYXRlRXJyb3JUeXBlKHNpdGUpOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdExpdGVyYWwoSkNMaXRlcmFsIHRyZWUpIHsKICAgICAgICByZXN1bHQgPSBjaGVjayh0cmVlLCBsaXRUeXBlKHRyZWUudHlwZXRhZykuY29uc3RUeXBlKHRyZWUudmFsdWUpLAogICAgICAgICAgICAgICAgS2luZFNlbGVjdG9yLlZBTCwgcmVzdWx0SW5mbyk7CiAgICB9CiAgICAvL3doZXJlCiAgICAvKiogUmV0dXJuIHRoZSB0eXBlIG9mIGEgbGl0ZXJhbCB3aXRoIGdpdmVuIHR5cGUgdGFnLgogICAgICovCiAgICBUeXBlIGxpdFR5cGUoVHlwZVRhZyB0YWcpIHsKICAgICAgICByZXR1cm4gKHRhZyA9PSBDTEFTUykgPyBzeW1zLnN0cmluZ1R5cGUgOiBzeW1zLnR5cGVPZlRhZ1t0YWcub3JkaW5hbCgpXTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdFR5cGVJZGVudChKQ1ByaW1pdGl2ZVR5cGVUcmVlIHRyZWUpIHsKICAgICAgICByZXN1bHQgPSBjaGVjayh0cmVlLCBzeW1zLnR5cGVPZlRhZ1t0cmVlLnR5cGV0YWcub3JkaW5hbCgpXSwgS2luZFNlbGVjdG9yLlRZUCwgcmVzdWx0SW5mbyk7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRUeXBlQXJyYXkoSkNBcnJheVR5cGVUcmVlIHRyZWUpIHsKICAgICAgICBUeXBlIGV0eXBlID0gYXR0cmliVHlwZSh0cmVlLmVsZW10eXBlLCBlbnYpOwogICAgICAgIFR5cGUgdHlwZSA9IG5ldyBBcnJheVR5cGUoZXR5cGUsIHN5bXMuYXJyYXlDbGFzcyk7CiAgICAgICAgcmVzdWx0ID0gY2hlY2sodHJlZSwgdHlwZSwgS2luZFNlbGVjdG9yLlRZUCwgcmVzdWx0SW5mbyk7CiAgICB9CgogICAgLyoqIFZpc2l0b3IgbWV0aG9kIGZvciBwYXJhbWV0ZXJpemVkIHR5cGVzLgogICAgICogIEJvdW5kIGNoZWNraW5nIGlzIGxlZnQgdW50aWwgbGF0ZXIsIHNpbmNlIHR5cGVzIGFyZSBhdHRyaWJ1dGVkCiAgICAgKiAgYmVmb3JlIHN1cGVydHlwZSBzdHJ1Y3R1cmUgaXMgY29tcGxldGVseSBrbm93bgogICAgICovCiAgICBwdWJsaWMgdm9pZCB2aXNpdFR5cGVBcHBseShKQ1R5cGVBcHBseSB0cmVlKSB7CiAgICAgICAgVHlwZSBvd250eXBlID0gdHlwZXMuY3JlYXRlRXJyb3JUeXBlKHRyZWUudHlwZSk7CgogICAgICAgIC8vIEF0dHJpYnV0ZSBmdW5jdG9yIHBhcnQgb2YgYXBwbGljYXRpb24gYW5kIG1ha2Ugc3VyZSBpdCdzIGEgY2xhc3MuCiAgICAgICAgVHlwZSBjbGF6enR5cGUgPSBjaGsuY2hlY2tDbGFzc1R5cGUodHJlZS5jbGF6ei5wb3MoKSwgYXR0cmliVHlwZSh0cmVlLmNsYXp6LCBlbnYpKTsKCiAgICAgICAgLy8gQXR0cmlidXRlIHR5cGUgcGFyYW1ldGVycwogICAgICAgIExpc3Q8VHlwZT4gYWN0dWFscyA9IGF0dHJpYlR5cGVzKHRyZWUuYXJndW1lbnRzLCBlbnYpOwoKICAgICAgICBpZiAoY2xhenp0eXBlLmhhc1RhZyhDTEFTUykpIHsKICAgICAgICAgICAgTGlzdDxUeXBlPiBmb3JtYWxzID0gY2xhenp0eXBlLnRzeW0udHlwZS5nZXRUeXBlQXJndW1lbnRzKCk7CiAgICAgICAgICAgIGlmIChhY3R1YWxzLmlzRW1wdHkoKSkgLy9kaWFtb25kCiAgICAgICAgICAgICAgICBhY3R1YWxzID0gZm9ybWFsczsKCiAgICAgICAgICAgIGlmIChhY3R1YWxzLmxlbmd0aCgpID09IGZvcm1hbHMubGVuZ3RoKCkpIHsKICAgICAgICAgICAgICAgIExpc3Q8VHlwZT4gYSA9IGFjdHVhbHM7CiAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IGYgPSBmb3JtYWxzOwogICAgICAgICAgICAgICAgd2hpbGUgKGEubm9uRW1wdHkoKSkgewogICAgICAgICAgICAgICAgICAgIGEuaGVhZCA9IGEuaGVhZC53aXRoVHlwZVZhcihmLmhlYWQpOwogICAgICAgICAgICAgICAgICAgIGEgPSBhLnRhaWw7CiAgICAgICAgICAgICAgICAgICAgZiA9IGYudGFpbDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIC8vIENvbXB1dGUgdGhlIHByb3BlciBnZW5lcmljIG91dGVyCiAgICAgICAgICAgICAgICBUeXBlIGNsYXp6T3V0ZXIgPSBjbGF6enR5cGUuZ2V0RW5jbG9zaW5nVHlwZSgpOwogICAgICAgICAgICAgICAgaWYgKGNsYXp6T3V0ZXIuaGFzVGFnKENMQVNTKSkgewogICAgICAgICAgICAgICAgICAgIFR5cGUgc2l0ZTsKICAgICAgICAgICAgICAgICAgICBKQ0V4cHJlc3Npb24gY2xhenogPSBUcmVlSW5mby50eXBlSW4odHJlZS5jbGF6eik7CiAgICAgICAgICAgICAgICAgICAgaWYgKGNsYXp6Lmhhc1RhZyhJREVOVCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgc2l0ZSA9IGVudi5lbmNsQ2xhc3Muc3ltLnR5cGU7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjbGF6ei5oYXNUYWcoU0VMRUNUKSkgewogICAgICAgICAgICAgICAgICAgICAgICBzaXRlID0gKChKQ0ZpZWxkQWNjZXNzKSBjbGF6eikuc2VsZWN0ZWQudHlwZTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCIiK3RyZWUpOwogICAgICAgICAgICAgICAgICAgIGlmIChjbGF6ek91dGVyLmhhc1RhZyhDTEFTUykgJiYgc2l0ZSAhPSBjbGF6ek91dGVyKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzaXRlLmhhc1RhZyhDTEFTUykpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXRlID0gdHlwZXMuYXNPdXRlclN1cGVyKHNpdGUsIGNsYXp6T3V0ZXIudHN5bSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzaXRlID09IG51bGwpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXRlID0gdHlwZXMuZXJhc3VyZShjbGF6ek91dGVyKTsKICAgICAgICAgICAgICAgICAgICAgICAgY2xhenpPdXRlciA9IHNpdGU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgb3dudHlwZSA9IG5ldyBDbGFzc1R5cGUoY2xhenpPdXRlciwgYWN0dWFscywgY2xhenp0eXBlLnRzeW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGF6enR5cGUuZ2V0TWV0YWRhdGEoKSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBpZiAoZm9ybWFscy5sZW5ndGgoKSAhPSAwKSB7CiAgICAgICAgICAgICAgICAgICAgbG9nLmVycm9yKHRyZWUucG9zKCksICJ3cm9uZy5udW1iZXIudHlwZS5hcmdzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW50ZWdlci50b1N0cmluZyhmb3JtYWxzLmxlbmd0aCgpKSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGxvZy5lcnJvcih0cmVlLnBvcygpLCAidHlwZS5kb2VzbnQudGFrZS5wYXJhbXMiLCBjbGF6enR5cGUudHN5bSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBvd250eXBlID0gdHlwZXMuY3JlYXRlRXJyb3JUeXBlKHRyZWUudHlwZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmVzdWx0ID0gY2hlY2sodHJlZSwgb3dudHlwZSwgS2luZFNlbGVjdG9yLlRZUCwgcmVzdWx0SW5mbyk7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRUeXBlVW5pb24oSkNUeXBlVW5pb24gdHJlZSkgewogICAgICAgIExpc3RCdWZmZXI8VHlwZT4gbXVsdGljYXRjaFR5cGVzID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgIExpc3RCdWZmZXI8VHlwZT4gYWxsX211bHRpY2F0Y2hUeXBlcyA9IG51bGw7IC8vIGxhenksIG9ubHkgaWYgbmVlZGVkCiAgICAgICAgZm9yIChKQ0V4cHJlc3Npb24gdHlwZVRyZWUgOiB0cmVlLmFsdGVybmF0aXZlcykgewogICAgICAgICAgICBUeXBlIGN0eXBlID0gYXR0cmliVHlwZSh0eXBlVHJlZSwgZW52KTsKICAgICAgICAgICAgY3R5cGUgPSBjaGsuY2hlY2tUeXBlKHR5cGVUcmVlLnBvcygpLAogICAgICAgICAgICAgICAgICAgICAgICAgIGNoay5jaGVja0NsYXNzVHlwZSh0eXBlVHJlZS5wb3MoKSwgY3R5cGUpLAogICAgICAgICAgICAgICAgICAgICAgICAgIHN5bXMudGhyb3dhYmxlVHlwZSk7CiAgICAgICAgICAgIGlmICghY3R5cGUuaXNFcnJvbmVvdXMoKSkgewogICAgICAgICAgICAgICAgLy9jaGVjayB0aGF0IGFsdGVybmF0aXZlcyBvZiBhIHVuaW9uIHR5cGUgYXJlIHBhaXJ3aXNlCiAgICAgICAgICAgICAgICAvL3VucmVsYXRlZCB3LnIudC4gc3VidHlwaW5nCiAgICAgICAgICAgICAgICBpZiAoY2hrLmludGVyc2VjdHMoY3R5cGUsICBtdWx0aWNhdGNoVHlwZXMudG9MaXN0KCkpKSB7CiAgICAgICAgICAgICAgICAgICAgZm9yIChUeXBlIHQgOiBtdWx0aWNhdGNoVHlwZXMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBzdWIgPSB0eXBlcy5pc1N1YnR5cGUoY3R5cGUsIHQpOwogICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIHN1cCA9IHR5cGVzLmlzU3VidHlwZSh0LCBjdHlwZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdWIgfHwgc3VwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2Fzc3VtZSAnYScgPDogJ2InCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBUeXBlIGEgPSBzdWIgPyBjdHlwZSA6IHQ7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBUeXBlIGIgPSBzdWIgPyB0IDogY3R5cGU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2cuZXJyb3IodHlwZVRyZWUucG9zKCksICJtdWx0aWNhdGNoLnR5cGVzLm11c3QuYmUuZGlzam9pbnQiLCBhLCBiKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIG11bHRpY2F0Y2hUeXBlcy5hcHBlbmQoY3R5cGUpOwogICAgICAgICAgICAgICAgaWYgKGFsbF9tdWx0aWNhdGNoVHlwZXMgIT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICBhbGxfbXVsdGljYXRjaFR5cGVzLmFwcGVuZChjdHlwZSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBpZiAoYWxsX211bHRpY2F0Y2hUeXBlcyA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgYWxsX211bHRpY2F0Y2hUeXBlcyA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICAgICAgICAgICAgICBhbGxfbXVsdGljYXRjaFR5cGVzLmFwcGVuZExpc3QobXVsdGljYXRjaFR5cGVzKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGFsbF9tdWx0aWNhdGNoVHlwZXMuYXBwZW5kKGN0eXBlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBUeXBlIHQgPSBjaGVjayh0cmVlLCB0eXBlcy5sdWIobXVsdGljYXRjaFR5cGVzLnRvTGlzdCgpKSwKICAgICAgICAgICAgICAgIEtpbmRTZWxlY3Rvci5UWVAsIHJlc3VsdEluZm8uZHVwKENoZWNrTW9kZS5OT19UUkVFX1VQREFURSkpOwogICAgICAgIGlmICh0Lmhhc1RhZyhDTEFTUykpIHsKICAgICAgICAgICAgTGlzdDxUeXBlPiBhbHRlcm5hdGl2ZXMgPQogICAgICAgICAgICAgICAgKChhbGxfbXVsdGljYXRjaFR5cGVzID09IG51bGwpID8gbXVsdGljYXRjaFR5cGVzIDogYWxsX211bHRpY2F0Y2hUeXBlcykudG9MaXN0KCk7CiAgICAgICAgICAgIHQgPSBuZXcgVW5pb25DbGFzc1R5cGUoKENsYXNzVHlwZSkgdCwgYWx0ZXJuYXRpdmVzKTsKICAgICAgICB9CiAgICAgICAgdHJlZS50eXBlID0gcmVzdWx0ID0gdDsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdFR5cGVJbnRlcnNlY3Rpb24oSkNUeXBlSW50ZXJzZWN0aW9uIHRyZWUpIHsKICAgICAgICBhdHRyaWJUeXBlcyh0cmVlLmJvdW5kcywgZW52KTsKICAgICAgICB0cmVlLnR5cGUgPSByZXN1bHQgPSBjaGVja0ludGVyc2VjdGlvbih0cmVlLCB0cmVlLmJvdW5kcyk7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRUeXBlUGFyYW1ldGVyKEpDVHlwZVBhcmFtZXRlciB0cmVlKSB7CiAgICAgICAgVHlwZVZhciB0eXBlVmFyID0gKFR5cGVWYXIpIHRyZWUudHlwZTsKCiAgICAgICAgaWYgKHRyZWUuYW5ub3RhdGlvbnMgIT0gbnVsbCAmJiB0cmVlLmFubm90YXRpb25zLm5vbkVtcHR5KCkpIHsKICAgICAgICAgICAgYW5ub3RhdGUuYW5ub3RhdGVUeXBlUGFyYW1ldGVyU2Vjb25kU3RhZ2UodHJlZSwgdHJlZS5hbm5vdGF0aW9ucyk7CiAgICAgICAgfQoKICAgICAgICBpZiAoIXR5cGVWYXIuYm91bmQuaXNFcnJvbmVvdXMoKSkgewogICAgICAgICAgICAvL2ZpeHVwIHR5cGUtcGFyYW1ldGVyIGJvdW5kIGNvbXB1dGVkIGluICdhdHRyaWJUeXBlVmFyaWFibGVzJwogICAgICAgICAgICB0eXBlVmFyLmJvdW5kID0gY2hlY2tJbnRlcnNlY3Rpb24odHJlZSwgdHJlZS5ib3VuZHMpOwogICAgICAgIH0KICAgIH0KCiAgICBUeXBlIGNoZWNrSW50ZXJzZWN0aW9uKEpDVHJlZSB0cmVlLCBMaXN0PEpDRXhwcmVzc2lvbj4gYm91bmRzKSB7CiAgICAgICAgU2V0PFR5cGU+IGJvdW5kU2V0ID0gbmV3IEhhc2hTZXQ8PigpOwogICAgICAgIGlmIChib3VuZHMubm9uRW1wdHkoKSkgewogICAgICAgICAgICAvLyBhY2NlcHQgY2xhc3Mgb3IgaW50ZXJmYWNlIG9yIHR5cGV2YXIgYXMgZmlyc3QgYm91bmQuCiAgICAgICAgICAgIGJvdW5kcy5oZWFkLnR5cGUgPSBjaGVja0Jhc2UoYm91bmRzLmhlYWQudHlwZSwgYm91bmRzLmhlYWQsIGVudiwgZmFsc2UsIGZhbHNlLCBmYWxzZSk7CiAgICAgICAgICAgIGJvdW5kU2V0LmFkZCh0eXBlcy5lcmFzdXJlKGJvdW5kcy5oZWFkLnR5cGUpKTsKICAgICAgICAgICAgaWYgKGJvdW5kcy5oZWFkLnR5cGUuaXNFcnJvbmVvdXMoKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGJvdW5kcy5oZWFkLnR5cGU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAoYm91bmRzLmhlYWQudHlwZS5oYXNUYWcoVFlQRVZBUikpIHsKICAgICAgICAgICAgICAgIC8vIGlmIGZpcnN0IGJvdW5kIHdhcyBhIHR5cGV2YXIsIGRvIG5vdCBhY2NlcHQgZnVydGhlciBib3VuZHMuCiAgICAgICAgICAgICAgICBpZiAoYm91bmRzLnRhaWwubm9uRW1wdHkoKSkgewogICAgICAgICAgICAgICAgICAgIGxvZy5lcnJvcihib3VuZHMudGFpbC5oZWFkLnBvcygpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidHlwZS52YXIubWF5Lm5vdC5iZS5mb2xsb3dlZC5ieS5vdGhlci5ib3VuZHMiKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gYm91bmRzLmhlYWQudHlwZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIC8vIGlmIGZpcnN0IGJvdW5kIHdhcyBhIGNsYXNzIG9yIGludGVyZmFjZSwgYWNjZXB0IG9ubHkgaW50ZXJmYWNlcwogICAgICAgICAgICAgICAgLy8gYXMgZnVydGhlciBib3VuZHMuCiAgICAgICAgICAgICAgICBmb3IgKEpDRXhwcmVzc2lvbiBib3VuZCA6IGJvdW5kcy50YWlsKSB7CiAgICAgICAgICAgICAgICAgICAgYm91bmQudHlwZSA9IGNoZWNrQmFzZShib3VuZC50eXBlLCBib3VuZCwgZW52LCBmYWxzZSwgdHJ1ZSwgZmFsc2UpOwogICAgICAgICAgICAgICAgICAgIGlmIChib3VuZC50eXBlLmlzRXJyb25lb3VzKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgYm91bmRzID0gTGlzdC5vZihib3VuZCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGJvdW5kLnR5cGUuaGFzVGFnKENMQVNTKSkgewogICAgICAgICAgICAgICAgICAgICAgICBjaGsuY2hlY2tOb3RSZXBlYXRlZChib3VuZC5wb3MoKSwgdHlwZXMuZXJhc3VyZShib3VuZC50eXBlKSwgYm91bmRTZXQpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKGJvdW5kcy5sZW5ndGgoKSA9PSAwKSB7CiAgICAgICAgICAgIHJldHVybiBzeW1zLm9iamVjdFR5cGU7CiAgICAgICAgfSBlbHNlIGlmIChib3VuZHMubGVuZ3RoKCkgPT0gMSkgewogICAgICAgICAgICByZXR1cm4gYm91bmRzLmhlYWQudHlwZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBUeXBlIG93bnR5cGUgPSB0eXBlcy5tYWtlSW50ZXJzZWN0aW9uVHlwZShUcmVlSW5mby50eXBlcyhib3VuZHMpKTsKICAgICAgICAgICAgLy8gLi4uIHRoZSB2YXJpYWJsZSdzIGJvdW5kIGlzIGEgY2xhc3MgdHlwZSBmbGFnZ2VkIENPTVBPVU5ECiAgICAgICAgICAgIC8vIChzZWUgY29tbWVudCBmb3IgVHlwZVZhci5ib3VuZCkuCiAgICAgICAgICAgIC8vIEluIHRoaXMgY2FzZSwgZ2VuZXJhdGUgYSBjbGFzcyB0cmVlIHRoYXQgcmVwcmVzZW50cyB0aGUKICAgICAgICAgICAgLy8gYm91bmQgY2xhc3MsIC4uLgogICAgICAgICAgICBKQ0V4cHJlc3Npb24gZXh0ZW5kaW5nOwogICAgICAgICAgICBMaXN0PEpDRXhwcmVzc2lvbj4gaW1wbGVtZW50aW5nOwogICAgICAgICAgICBpZiAoIWJvdW5kcy5oZWFkLnR5cGUuaXNJbnRlcmZhY2UoKSkgewogICAgICAgICAgICAgICAgZXh0ZW5kaW5nID0gYm91bmRzLmhlYWQ7CiAgICAgICAgICAgICAgICBpbXBsZW1lbnRpbmcgPSBib3VuZHMudGFpbDsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGV4dGVuZGluZyA9IG51bGw7CiAgICAgICAgICAgICAgICBpbXBsZW1lbnRpbmcgPSBib3VuZHM7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgSkNDbGFzc0RlY2wgY2QgPSBtYWtlLmF0KHRyZWUpLkNsYXNzRGVmKAogICAgICAgICAgICAgICAgbWFrZS5Nb2RpZmllcnMoUFVCTElDIHwgQUJTVFJBQ1QpLAogICAgICAgICAgICAgICAgbmFtZXMuZW1wdHksIExpc3QubmlsKCksCiAgICAgICAgICAgICAgICBleHRlbmRpbmcsIGltcGxlbWVudGluZywgTGlzdC5uaWwoKSk7CgogICAgICAgICAgICBDbGFzc1N5bWJvbCBjID0gKENsYXNzU3ltYm9sKW93bnR5cGUudHN5bTsKICAgICAgICAgICAgQXNzZXJ0LmNoZWNrKChjLmZsYWdzKCkgJiBDT01QT1VORCkgIT0gMCk7CiAgICAgICAgICAgIGNkLnN5bSA9IGM7CiAgICAgICAgICAgIGMuc291cmNlZmlsZSA9IGVudi50b3BsZXZlbC5zb3VyY2VmaWxlOwoKICAgICAgICAgICAgLy8gLi4uIGFuZCBhdHRyaWJ1dGUgdGhlIGJvdW5kIGNsYXNzCiAgICAgICAgICAgIGMuZmxhZ3NfZmllbGQgfD0gVU5BVFRSSUJVVEVEOwogICAgICAgICAgICBFbnY8QXR0ckNvbnRleHQ+IGNlbnYgPSBlbnRlci5jbGFzc0VudihjZCwgZW52KTsKICAgICAgICAgICAgdHlwZUVudnMucHV0KGMsIGNlbnYpOwogICAgICAgICAgICBhdHRyaWJDbGFzcyhjKTsKICAgICAgICAgICAgcmV0dXJuIG93bnR5cGU7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0V2lsZGNhcmQoSkNXaWxkY2FyZCB0cmVlKSB7CiAgICAgICAgLy8tIFN5c3RlbS5lcnIucHJpbnRsbigidmlzaXRXaWxkY2FyZCgiK3RyZWUrIik7Iik7Ly9ERUJVRwogICAgICAgIFR5cGUgdHlwZSA9ICh0cmVlLmtpbmQua2luZCA9PSBCb3VuZEtpbmQuVU5CT1VORCkKICAgICAgICAgICAgPyBzeW1zLm9iamVjdFR5cGUKICAgICAgICAgICAgOiBhdHRyaWJUeXBlKHRyZWUuaW5uZXIsIGVudik7CiAgICAgICAgcmVzdWx0ID0gY2hlY2sodHJlZSwgbmV3IFdpbGRjYXJkVHlwZShjaGsuY2hlY2tSZWZUeXBlKHRyZWUucG9zKCksIHR5cGUpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJlZS5raW5kLmtpbmQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeW1zLmJvdW5kQ2xhc3MpLAogICAgICAgICAgICAgICAgS2luZFNlbGVjdG9yLlRZUCwgcmVzdWx0SW5mbyk7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRBbm5vdGF0aW9uKEpDQW5ub3RhdGlvbiB0cmVlKSB7CiAgICAgICAgQXNzZXJ0LmVycm9yKCJzaG91bGQgYmUgaGFuZGxlZCBpbiBhbm5vdGF0ZSIpOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0QW5ub3RhdGVkVHlwZShKQ0Fubm90YXRlZFR5cGUgdHJlZSkgewogICAgICAgIGF0dHJpYkFubm90YXRpb25UeXBlcyh0cmVlLmFubm90YXRpb25zLCBlbnYpOwogICAgICAgIFR5cGUgdW5kZXJseWluZ1R5cGUgPSBhdHRyaWJUeXBlKHRyZWUudW5kZXJseWluZ1R5cGUsIGVudik7CiAgICAgICAgVHlwZSBhbm5vdGF0ZWRUeXBlID0gdW5kZXJseWluZ1R5cGUuYW5ub3RhdGVkVHlwZShBbm5vdGF0aW9ucy5UT19CRV9TRVQpOwoKICAgICAgICBpZiAoIWVudi5pbmZvLmlzTmV3Q2xhc3MpCiAgICAgICAgICAgIGFubm90YXRlLmFubm90YXRlVHlwZVNlY29uZFN0YWdlKHRyZWUsIHRyZWUuYW5ub3RhdGlvbnMsIGFubm90YXRlZFR5cGUpOwogICAgICAgIHJlc3VsdCA9IHRyZWUudHlwZSA9IGFubm90YXRlZFR5cGU7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRFcnJvbmVvdXMoSkNFcnJvbmVvdXMgdHJlZSkgewogICAgICAgIGlmICh0cmVlLmVycnMgIT0gbnVsbCkKICAgICAgICAgICAgZm9yIChKQ1RyZWUgZXJyIDogdHJlZS5lcnJzKQogICAgICAgICAgICAgICAgYXR0cmliVHJlZShlcnIsIGVudiwgbmV3IFJlc3VsdEluZm8oS2luZFNlbGVjdG9yLkVSUiwgcHQoKSkpOwogICAgICAgIHJlc3VsdCA9IHRyZWUudHlwZSA9IHN5bXMuZXJyVHlwZTsKICAgIH0KCiAgICAvKiogRGVmYXVsdCB2aXNpdG9yIG1ldGhvZCBmb3IgYWxsIG90aGVyIHRyZWVzLgogICAgICovCiAgICBwdWJsaWMgdm9pZCB2aXNpdFRyZWUoSkNUcmVlIHRyZWUpIHsKICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoKTsKICAgIH0KCiAgICAvKioKICAgICAqIEF0dHJpYnV0ZSBhbiBlbnYgZm9yIGVpdGhlciBhIHRvcCBsZXZlbCB0cmVlIG9yIGNsYXNzIG9yIG1vZHVsZSBkZWNsYXJhdGlvbi4KICAgICAqLwogICAgcHVibGljIHZvaWQgYXR0cmliKEVudjxBdHRyQ29udGV4dD4gZW52KSB7CiAgICAgICAgc3dpdGNoIChlbnYudHJlZS5nZXRUYWcoKSkgewogICAgICAgICAgICBjYXNlIE1PRFVMRURFRjoKICAgICAgICAgICAgICAgIGF0dHJpYk1vZHVsZShlbnYudHJlZS5wb3MoKSwgKChKQ01vZHVsZURlY2wpZW52LnRyZWUpLnN5bSk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBUT1BMRVZFTDoKICAgICAgICAgICAgICAgIGF0dHJpYlRvcExldmVsKGVudik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBQQUNLQUdFREVGOgogICAgICAgICAgICAgICAgYXR0cmliUGFja2FnZShlbnYudHJlZS5wb3MoKSwgKChKQ1BhY2thZ2VEZWNsKSBlbnYudHJlZSkucGFja2dlKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgYXR0cmliQ2xhc3MoZW52LnRyZWUucG9zKCksIGVudi5lbmNsQ2xhc3Muc3ltKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBBdHRyaWJ1dGUgYSB0b3AgbGV2ZWwgdHJlZS4gVGhlc2UgdHJlZXMgYXJlIGVuY291bnRlcmVkIHdoZW4gdGhlCiAgICAgKiBwYWNrYWdlIGRlY2xhcmF0aW9uIGhhcyBhbm5vdGF0aW9ucy4KICAgICAqLwogICAgcHVibGljIHZvaWQgYXR0cmliVG9wTGV2ZWwoRW52PEF0dHJDb250ZXh0PiBlbnYpIHsKICAgICAgICBKQ0NvbXBpbGF0aW9uVW5pdCB0b3BsZXZlbCA9IGVudi50b3BsZXZlbDsKICAgICAgICB0cnkgewogICAgICAgICAgICBhbm5vdGF0ZS5mbHVzaCgpOwogICAgICAgIH0gY2F0Y2ggKENvbXBsZXRpb25GYWlsdXJlIGV4KSB7CiAgICAgICAgICAgIGNoay5jb21wbGV0aW9uRXJyb3IodG9wbGV2ZWwucG9zKCksIGV4KTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHZvaWQgYXR0cmliUGFja2FnZShEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBQYWNrYWdlU3ltYm9sIHApIHsKICAgICAgICB0cnkgewogICAgICAgICAgICBhbm5vdGF0ZS5mbHVzaCgpOwogICAgICAgICAgICBhdHRyaWJQYWNrYWdlKHApOwogICAgICAgIH0gY2F0Y2ggKENvbXBsZXRpb25GYWlsdXJlIGV4KSB7CiAgICAgICAgICAgIGNoay5jb21wbGV0aW9uRXJyb3IocG9zLCBleCk7CiAgICAgICAgfQogICAgfQoKICAgIHZvaWQgYXR0cmliUGFja2FnZShQYWNrYWdlU3ltYm9sIHApIHsKICAgICAgICBFbnY8QXR0ckNvbnRleHQ+IGVudiA9IHR5cGVFbnZzLmdldChwKTsKICAgICAgICBjaGsuY2hlY2tEZXByZWNhdGVkQW5ub3RhdGlvbigoKEpDUGFja2FnZURlY2wpIGVudi50cmVlKS5waWQucG9zKCksIHApOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIGF0dHJpYk1vZHVsZShEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBNb2R1bGVTeW1ib2wgbSkgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGFubm90YXRlLmZsdXNoKCk7CiAgICAgICAgICAgIGF0dHJpYk1vZHVsZShtKTsKICAgICAgICB9IGNhdGNoIChDb21wbGV0aW9uRmFpbHVyZSBleCkgewogICAgICAgICAgICBjaGsuY29tcGxldGlvbkVycm9yKHBvcywgZXgpOwogICAgICAgIH0KICAgIH0KCiAgICB2b2lkIGF0dHJpYk1vZHVsZShNb2R1bGVTeW1ib2wgbSkgewogICAgICAgIC8vIEdldCBlbnZpcm9ubWVudCBjdXJyZW50IGF0IHRoZSBwb2ludCBvZiBtb2R1bGUgZGVmaW5pdGlvbi4KICAgICAgICBFbnY8QXR0ckNvbnRleHQ+IGVudiA9IGVudGVyLnR5cGVFbnZzLmdldChtKTsKICAgICAgICBhdHRyaWJTdGF0KGVudi50cmVlLCBlbnYpOwogICAgfQoKICAgIC8qKiBNYWluIG1ldGhvZDogYXR0cmlidXRlIGNsYXNzIGRlZmluaXRpb24gYXNzb2NpYXRlZCB3aXRoIGdpdmVuIGNsYXNzIHN5bWJvbC4KICAgICAqICByZXBvcnRpbmcgY29tcGxldGlvbiBmYWlsdXJlcyBhdCB0aGUgZ2l2ZW4gcG9zaXRpb24uCiAgICAgKiAgQHBhcmFtIHBvcyBUaGUgc291cmNlIHBvc2l0aW9uIGF0IHdoaWNoIGNvbXBsZXRpb24gZXJyb3JzIGFyZSB0byBiZQogICAgICogICAgICAgICAgICAgcmVwb3J0ZWQuCiAgICAgKiAgQHBhcmFtIGMgICBUaGUgY2xhc3Mgc3ltYm9sIHdob3NlIGRlZmluaXRpb24gd2lsbCBiZSBhdHRyaWJ1dGVkLgogICAgICovCiAgICBwdWJsaWMgdm9pZCBhdHRyaWJDbGFzcyhEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBDbGFzc1N5bWJvbCBjKSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgYW5ub3RhdGUuZmx1c2goKTsKICAgICAgICAgICAgYXR0cmliQ2xhc3MoYyk7CiAgICAgICAgfSBjYXRjaCAoQ29tcGxldGlvbkZhaWx1cmUgZXgpIHsKICAgICAgICAgICAgY2hrLmNvbXBsZXRpb25FcnJvcihwb3MsIGV4KTsKICAgICAgICB9CiAgICB9CgogICAgLyoqIEF0dHJpYnV0ZSBjbGFzcyBkZWZpbml0aW9uIGFzc29jaWF0ZWQgd2l0aCBnaXZlbiBjbGFzcyBzeW1ib2wuCiAgICAgKiAgQHBhcmFtIGMgICBUaGUgY2xhc3Mgc3ltYm9sIHdob3NlIGRlZmluaXRpb24gd2lsbCBiZSBhdHRyaWJ1dGVkLgogICAgICovCiAgICB2b2lkIGF0dHJpYkNsYXNzKENsYXNzU3ltYm9sIGMpIHRocm93cyBDb21wbGV0aW9uRmFpbHVyZSB7CiAgICAgICAgaWYgKGMudHlwZS5oYXNUYWcoRVJST1IpKSByZXR1cm47CgogICAgICAgIC8vIENoZWNrIGZvciBjeWNsZXMgaW4gdGhlIGluaGVyaXRhbmNlIGdyYXBoLCB3aGljaCBjYW4gYXJpc2UgZnJvbQogICAgICAgIC8vIGlsbC1mb3JtZWQgY2xhc3MgZmlsZXMuCiAgICAgICAgY2hrLmNoZWNrTm9uQ3ljbGljKG51bGwsIGMudHlwZSk7CgogICAgICAgIFR5cGUgc3QgPSB0eXBlcy5zdXBlcnR5cGUoYy50eXBlKTsKICAgICAgICBpZiAoKGMuZmxhZ3NfZmllbGQgJiBGbGFncy5DT01QT1VORCkgPT0gMCkgewogICAgICAgICAgICAvLyBGaXJzdCwgYXR0cmlidXRlIHN1cGVyY2xhc3MuCiAgICAgICAgICAgIGlmIChzdC5oYXNUYWcoQ0xBU1MpKQogICAgICAgICAgICAgICAgYXR0cmliQ2xhc3MoKENsYXNzU3ltYm9sKXN0LnRzeW0pOwoKICAgICAgICAgICAgLy8gTmV4dCBhdHRyaWJ1dGUgb3duZXIsIGlmIGl0IGlzIGEgY2xhc3MuCiAgICAgICAgICAgIGlmIChjLm93bmVyLmtpbmQgPT0gVFlQICYmIGMub3duZXIudHlwZS5oYXNUYWcoQ0xBU1MpKQogICAgICAgICAgICAgICAgYXR0cmliQ2xhc3MoKENsYXNzU3ltYm9sKWMub3duZXIpOwogICAgICAgIH0KCiAgICAgICAgLy8gVGhlIHByZXZpb3VzIG9wZXJhdGlvbnMgbWlnaHQgaGF2ZSBhdHRyaWJ1dGVkIHRoZSBjdXJyZW50IGNsYXNzCiAgICAgICAgLy8gaWYgdGhlcmUgd2FzIGEgY3ljbGUuIFNvIHdlIHRlc3QgZmlyc3Qgd2hldGhlciB0aGUgY2xhc3MgaXMgc3RpbGwKICAgICAgICAvLyBVTkFUVFJJQlVURUQuCiAgICAgICAgaWYgKChjLmZsYWdzX2ZpZWxkICYgVU5BVFRSSUJVVEVEKSAhPSAwKSB7CiAgICAgICAgICAgIGMuZmxhZ3NfZmllbGQgJj0gflVOQVRUUklCVVRFRDsKCiAgICAgICAgICAgIC8vIEdldCBlbnZpcm9ubWVudCBjdXJyZW50IGF0IHRoZSBwb2ludCBvZiBjbGFzcyBkZWZpbml0aW9uLgogICAgICAgICAgICBFbnY8QXR0ckNvbnRleHQ+IGVudiA9IHR5cGVFbnZzLmdldChjKTsKCiAgICAgICAgICAgIC8vIFRoZSBpbmZvLmxpbnQgZmllbGQgaW4gdGhlIGVudnMgc3RvcmVkIGluIHR5cGVFbnZzIGlzIGRlbGliZXJhdGVseSB1bmluaXRpYWxpemVkLAogICAgICAgICAgICAvLyBiZWNhdXNlIHRoZSBhbm5vdGF0aW9ucyB3ZXJlIG5vdCBhdmFpbGFibGUgYXQgdGhlIHRpbWUgdGhlIGVudiB3YXMgY3JlYXRlZC4gVGhlcmVmb3JlLAogICAgICAgICAgICAvLyB3ZSBsb29rIHVwIHRoZSBlbnZpcm9ubWVudCBjaGFpbiBmb3IgdGhlIGZpcnN0IGVuY2xvc2luZyBlbnZpcm9ubWVudCBmb3Igd2hpY2ggdGhlCiAgICAgICAgICAgIC8vIGxpbnQgdmFsdWUgaXMgc2V0LiBUeXBpY2FsbHksIHRoaXMgaXMgdGhlIHBhcmVudCBlbnYsIGJ1dCBtaWdodCBiZSBmdXJ0aGVyIGlmIHRoZXJlCiAgICAgICAgICAgIC8vIGFyZSBhbnkgZW52cyBjcmVhdGVkIGFzIGEgcmVzdWx0IG9mIFR5cGVQYXJhbWV0ZXIgbm9kZXMuCiAgICAgICAgICAgIEVudjxBdHRyQ29udGV4dD4gbGludEVudiA9IGVudjsKICAgICAgICAgICAgd2hpbGUgKGxpbnRFbnYuaW5mby5saW50ID09IG51bGwpCiAgICAgICAgICAgICAgICBsaW50RW52ID0gbGludEVudi5uZXh0OwoKICAgICAgICAgICAgLy8gSGF2aW5nIGZvdW5kIHRoZSBlbmNsb3NpbmcgbGludCB2YWx1ZSwgd2UgY2FuIGluaXRpYWxpemUgdGhlIGxpbnQgdmFsdWUgZm9yIHRoaXMgY2xhc3MKICAgICAgICAgICAgZW52LmluZm8ubGludCA9IGxpbnRFbnYuaW5mby5saW50LmF1Z21lbnQoYyk7CgogICAgICAgICAgICBMaW50IHByZXZMaW50ID0gY2hrLnNldExpbnQoZW52LmluZm8ubGludCk7CiAgICAgICAgICAgIEphdmFGaWxlT2JqZWN0IHByZXYgPSBsb2cudXNlU291cmNlKGMuc291cmNlZmlsZSk7CiAgICAgICAgICAgIFJlc3VsdEluZm8gcHJldlJldHVyblJlcyA9IGVudi5pbmZvLnJldHVyblJlc3VsdDsKCiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBkZWZlcnJlZExpbnRIYW5kbGVyLmZsdXNoKGVudi50cmVlKTsKICAgICAgICAgICAgICAgIGVudi5pbmZvLnJldHVyblJlc3VsdCA9IG51bGw7CiAgICAgICAgICAgICAgICAvLyBqYXZhLmxhbmcuRW51bSBtYXkgbm90IGJlIHN1YmNsYXNzZWQgYnkgYSBub24tZW51bQogICAgICAgICAgICAgICAgaWYgKHN0LnRzeW0gPT0gc3ltcy5lbnVtU3ltICYmCiAgICAgICAgICAgICAgICAgICAgKChjLmZsYWdzX2ZpZWxkICYgKEZsYWdzLkVOVU18RmxhZ3MuQ09NUE9VTkQpKSA9PSAwKSkKICAgICAgICAgICAgICAgICAgICBsb2cuZXJyb3IoZW52LnRyZWUucG9zKCksICJlbnVtLm5vLnN1YmNsYXNzaW5nIik7CgogICAgICAgICAgICAgICAgLy8gRW51bXMgbWF5IG5vdCBiZSBleHRlbmRlZCBieSBzb3VyY2UtbGV2ZWwgY2xhc3NlcwogICAgICAgICAgICAgICAgaWYgKHN0LnRzeW0gIT0gbnVsbCAmJgogICAgICAgICAgICAgICAgICAgICgoc3QudHN5bS5mbGFnc19maWVsZCAmIEZsYWdzLkVOVU0pICE9IDApICYmCiAgICAgICAgICAgICAgICAgICAgKChjLmZsYWdzX2ZpZWxkICYgKEZsYWdzLkVOVU0gfCBGbGFncy5DT01QT1VORCkpID09IDApKSB7CiAgICAgICAgICAgICAgICAgICAgbG9nLmVycm9yKGVudi50cmVlLnBvcygpLCAiZW51bS50eXBlcy5ub3QuZXh0ZW5zaWJsZSIpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmIChpc1NlcmlhbGl6YWJsZShjLnR5cGUpKSB7CiAgICAgICAgICAgICAgICAgICAgZW52LmluZm8uaXNTZXJpYWxpemFibGUgPSB0cnVlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGF0dHJpYkNsYXNzQm9keShlbnYsIGMpOwoKICAgICAgICAgICAgICAgIGNoay5jaGVja0RlcHJlY2F0ZWRBbm5vdGF0aW9uKGVudi50cmVlLnBvcygpLCBjKTsKICAgICAgICAgICAgICAgIGNoay5jaGVja0NsYXNzT3ZlcnJpZGVFcXVhbHNBbmRIYXNoSWZOZWVkZWQoZW52LnRyZWUucG9zKCksIGMpOwogICAgICAgICAgICAgICAgY2hrLmNoZWNrRnVuY3Rpb25hbEludGVyZmFjZSgoSkNDbGFzc0RlY2wpIGVudi50cmVlLCBjKTsKICAgICAgICAgICAgICAgIGNoay5jaGVja0xlYWtzTm90QWNjZXNzaWJsZShlbnYsIChKQ0NsYXNzRGVjbCkgZW52LnRyZWUpOwogICAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAgICAgZW52LmluZm8ucmV0dXJuUmVzdWx0ID0gcHJldlJldHVyblJlczsKICAgICAgICAgICAgICAgIGxvZy51c2VTb3VyY2UocHJldik7CiAgICAgICAgICAgICAgICBjaGsuc2V0TGludChwcmV2TGludCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0SW1wb3J0KEpDSW1wb3J0IHRyZWUpIHsKICAgICAgICAvLyBub3RoaW5nIHRvIGRvCiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRNb2R1bGVEZWYoSkNNb2R1bGVEZWNsIHRyZWUpIHsKICAgICAgICB0cmVlLnN5bS5jb21wbGV0ZVVzZXNQcm92aWRlcygpOwogICAgICAgIE1vZHVsZVN5bWJvbCBtc3ltID0gdHJlZS5zeW07CiAgICAgICAgTGludCBsaW50ID0gZW52Lm91dGVyLmluZm8ubGludCA9IGVudi5vdXRlci5pbmZvLmxpbnQuYXVnbWVudChtc3ltKTsKICAgICAgICBMaW50IHByZXZMaW50ID0gY2hrLnNldExpbnQobGludCk7CiAgICAgICAgY2hrLmNoZWNrTW9kdWxlTmFtZSh0cmVlKTsKICAgICAgICBjaGsuY2hlY2tEZXByZWNhdGVkQW5ub3RhdGlvbih0cmVlLCBtc3ltKTsKCiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgZGVmZXJyZWRMaW50SGFuZGxlci5mbHVzaCh0cmVlLnBvcygpKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICBjaGsuc2V0TGludChwcmV2TGludCk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKiBGaW5pc2ggdGhlIGF0dHJpYnV0aW9uIG9mIGEgY2xhc3MuICovCiAgICBwcml2YXRlIHZvaWQgYXR0cmliQ2xhc3NCb2R5KEVudjxBdHRyQ29udGV4dD4gZW52LCBDbGFzc1N5bWJvbCBjKSB7CiAgICAgICAgSkNDbGFzc0RlY2wgdHJlZSA9IChKQ0NsYXNzRGVjbCllbnYudHJlZTsKICAgICAgICBBc3NlcnQuY2hlY2soYyA9PSB0cmVlLnN5bSk7CgogICAgICAgIC8vIFZhbGlkYXRlIHR5cGUgcGFyYW1ldGVycywgc3VwZXJ0eXBlIGFuZCBpbnRlcmZhY2VzLgogICAgICAgIGF0dHJpYlN0YXRzKHRyZWUudHlwYXJhbXMsIGVudik7CiAgICAgICAgaWYgKCFjLmlzQW5vbnltb3VzKCkpIHsKICAgICAgICAgICAgLy9hbHJlYWR5IGNoZWNrZWQgaWYgYW5vbnltb3VzCiAgICAgICAgICAgIGNoay52YWxpZGF0ZSh0cmVlLnR5cGFyYW1zLCBlbnYpOwogICAgICAgICAgICBjaGsudmFsaWRhdGUodHJlZS5leHRlbmRpbmcsIGVudik7CiAgICAgICAgICAgIGNoay52YWxpZGF0ZSh0cmVlLmltcGxlbWVudGluZywgZW52KTsKICAgICAgICB9CgogICAgICAgIGMubWFya0Fic3RyYWN0SWZOZWVkZWQodHlwZXMpOwoKICAgICAgICAvLyBJZiB0aGlzIGlzIGEgbm9uLWFic3RyYWN0IGNsYXNzLCBjaGVjayB0aGF0IGl0IGhhcyBubyBhYnN0cmFjdAogICAgICAgIC8vIG1ldGhvZHMgb3IgdW5pbXBsZW1lbnRlZCBtZXRob2RzIG9mIGFuIGltcGxlbWVudGVkIGludGVyZmFjZS4KICAgICAgICBpZiAoKGMuZmxhZ3MoKSAmIChBQlNUUkFDVCB8IElOVEVSRkFDRSkpID09IDApIHsKICAgICAgICAgICAgY2hrLmNoZWNrQWxsRGVmaW5lZCh0cmVlLnBvcygpLCBjKTsKICAgICAgICB9CgogICAgICAgIGlmICgoYy5mbGFncygpICYgQU5OT1RBVElPTikgIT0gMCkgewogICAgICAgICAgICBpZiAodHJlZS5pbXBsZW1lbnRpbmcubm9uRW1wdHkoKSkKICAgICAgICAgICAgICAgIGxvZy5lcnJvcih0cmVlLmltcGxlbWVudGluZy5oZWFkLnBvcygpLAogICAgICAgICAgICAgICAgICAgICAgICAgICJjYW50LmV4dGVuZC5pbnRmLmFubm90YXRpb24iKTsKICAgICAgICAgICAgaWYgKHRyZWUudHlwYXJhbXMubm9uRW1wdHkoKSkKICAgICAgICAgICAgICAgIGxvZy5lcnJvcih0cmVlLnR5cGFyYW1zLmhlYWQucG9zKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgImludGYuYW5ub3RhdGlvbi5jYW50LmhhdmUudHlwZS5wYXJhbXMiKTsKCiAgICAgICAgICAgIC8vIElmIHRoaXMgYW5ub3RhdGlvbiB0eXBlIGhhcyBhIEBSZXBlYXRhYmxlLCB2YWxpZGF0ZQogICAgICAgICAgICBBdHRyaWJ1dGUuQ29tcG91bmQgcmVwZWF0YWJsZSA9IGMuZ2V0QW5ub3RhdGlvblR5cGVNZXRhZGF0YSgpLmdldFJlcGVhdGFibGUoKTsKICAgICAgICAgICAgLy8gSWYgdGhpcyBhbm5vdGF0aW9uIHR5cGUgaGFzIGEgQFJlcGVhdGFibGUsIHZhbGlkYXRlCiAgICAgICAgICAgIGlmIChyZXBlYXRhYmxlICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIC8vIGdldCBkaWFnbm9zdGljIHBvc2l0aW9uIGZvciBlcnJvciByZXBvcnRpbmcKICAgICAgICAgICAgICAgIERpYWdub3N0aWNQb3NpdGlvbiBjYlBvcyA9IGdldERpYWdub3N0aWNQb3NpdGlvbih0cmVlLCByZXBlYXRhYmxlLnR5cGUpOwogICAgICAgICAgICAgICAgQXNzZXJ0LmNoZWNrTm9uTnVsbChjYlBvcyk7CgogICAgICAgICAgICAgICAgY2hrLnZhbGlkYXRlUmVwZWF0YWJsZShjLCByZXBlYXRhYmxlLCBjYlBvcyk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvLyBDaGVjayB0aGF0IGFsbCBleHRlbmRlZCBjbGFzc2VzIGFuZCBpbnRlcmZhY2VzCiAgICAgICAgICAgIC8vIGFyZSBjb21wYXRpYmxlIChpLmUuIG5vIHR3byBkZWZpbmUgbWV0aG9kcyB3aXRoIHNhbWUgYXJndW1lbnRzCiAgICAgICAgICAgIC8vIHlldCBkaWZmZXJlbnQgcmV0dXJuIHR5cGVzKS4gIChKTFMgOC40LjYuMykKICAgICAgICAgICAgY2hrLmNoZWNrQ29tcGF0aWJsZVN1cGVydHlwZXModHJlZS5wb3MoKSwgYy50eXBlKTsKICAgICAgICAgICAgaWYgKGFsbG93RGVmYXVsdE1ldGhvZHMpIHsKICAgICAgICAgICAgICAgIGNoay5jaGVja0RlZmF1bHRNZXRob2RDbGFzaGVzKHRyZWUucG9zKCksIGMudHlwZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIENoZWNrIHRoYXQgY2xhc3MgZG9lcyBub3QgaW1wb3J0IHRoZSBzYW1lIHBhcmFtZXRlcml6ZWQgaW50ZXJmYWNlCiAgICAgICAgLy8gd2l0aCB0d28gZGlmZmVyZW50IGFyZ3VtZW50IGxpc3RzLgogICAgICAgIGNoay5jaGVja0NsYXNzQm91bmRzKHRyZWUucG9zKCksIGMudHlwZSk7CgogICAgICAgIHRyZWUudHlwZSA9IGMudHlwZTsKCiAgICAgICAgZm9yIChMaXN0PEpDVHlwZVBhcmFtZXRlcj4gbCA9IHRyZWUudHlwYXJhbXM7CiAgICAgICAgICAgICBsLm5vbkVtcHR5KCk7IGwgPSBsLnRhaWwpIHsKICAgICAgICAgICAgIEFzc2VydC5jaGVja05vbk51bGwoZW52LmluZm8uc2NvcGUuZmluZEZpcnN0KGwuaGVhZC5uYW1lKSk7CiAgICAgICAgfQoKICAgICAgICAvLyBDaGVjayB0aGF0IGEgZ2VuZXJpYyBjbGFzcyBkb2Vzbid0IGV4dGVuZCBUaHJvd2FibGUKICAgICAgICBpZiAoIWMudHlwZS5hbGxwYXJhbXMoKS5pc0VtcHR5KCkgJiYgdHlwZXMuaXNTdWJ0eXBlKGMudHlwZSwgc3ltcy50aHJvd2FibGVUeXBlKSkKICAgICAgICAgICAgbG9nLmVycm9yKHRyZWUuZXh0ZW5kaW5nLnBvcygpLCAiZ2VuZXJpYy50aHJvd2FibGUiKTsKCiAgICAgICAgLy8gQ2hlY2sgdGhhdCBhbGwgbWV0aG9kcyB3aGljaCBpbXBsZW1lbnQgc29tZQogICAgICAgIC8vIG1ldGhvZCBjb25mb3JtIHRvIHRoZSBtZXRob2QgdGhleSBpbXBsZW1lbnQuCiAgICAgICAgY2hrLmNoZWNrSW1wbGVtZW50YXRpb25zKHRyZWUpOwoKICAgICAgICAvL2NoZWNrIHRoYXQgYSByZXNvdXJjZSBpbXBsZW1lbnRpbmcgQXV0b0Nsb3NlYWJsZSBjYW5ub3QgdGhyb3cgSW50ZXJydXB0ZWRFeGNlcHRpb24KICAgICAgICBjaGVja0F1dG9DbG9zZWFibGUodHJlZS5wb3MoKSwgZW52LCBjLnR5cGUpOwoKICAgICAgICBmb3IgKExpc3Q8SkNUcmVlPiBsID0gdHJlZS5kZWZzOyBsLm5vbkVtcHR5KCk7IGwgPSBsLnRhaWwpIHsKICAgICAgICAgICAgLy8gQXR0cmlidXRlIGRlY2xhcmF0aW9uCiAgICAgICAgICAgIGF0dHJpYlN0YXQobC5oZWFkLCBlbnYpOwogICAgICAgICAgICAvLyBDaGVjayB0aGF0IGRlY2xhcmF0aW9ucyBpbiBpbm5lciBjbGFzc2VzIGFyZSBub3Qgc3RhdGljIChKTFMgOC4xLjIpCiAgICAgICAgICAgIC8vIE1ha2UgYW4gZXhjZXB0aW9uIGZvciBzdGF0aWMgY29uc3RhbnRzLgogICAgICAgICAgICBpZiAoYy5vd25lci5raW5kICE9IFBDSyAmJgogICAgICAgICAgICAgICAgKChjLmZsYWdzKCkgJiBTVEFUSUMpID09IDAgfHwgYy5uYW1lID09IG5hbWVzLmVtcHR5KSAmJgogICAgICAgICAgICAgICAgKFRyZWVJbmZvLmZsYWdzKGwuaGVhZCkgJiAoU1RBVElDIHwgSU5URVJGQUNFKSkgIT0gMCkgewogICAgICAgICAgICAgICAgU3ltYm9sIHN5bSA9IG51bGw7CiAgICAgICAgICAgICAgICBpZiAobC5oZWFkLmhhc1RhZyhWQVJERUYpKSBzeW0gPSAoKEpDVmFyaWFibGVEZWNsKSBsLmhlYWQpLnN5bTsKICAgICAgICAgICAgICAgIGlmIChzeW0gPT0gbnVsbCB8fAogICAgICAgICAgICAgICAgICAgIHN5bS5raW5kICE9IFZBUiB8fAogICAgICAgICAgICAgICAgICAgICgoVmFyU3ltYm9sKSBzeW0pLmdldENvbnN0VmFsdWUoKSA9PSBudWxsKQogICAgICAgICAgICAgICAgICAgIGxvZy5lcnJvcihsLmhlYWQucG9zKCksICJpY2xzLmNhbnQuaGF2ZS5zdGF0aWMuZGVjbCIsIGMpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBDaGVjayBmb3IgY3ljbGVzIGFtb25nIG5vbi1pbml0aWFsIGNvbnN0cnVjdG9ycy4KICAgICAgICBjaGsuY2hlY2tDeWNsaWNDb25zdHJ1Y3RvcnModHJlZSk7CgogICAgICAgIC8vIENoZWNrIGZvciBjeWNsZXMgYW1vbmcgYW5ub3RhdGlvbiBlbGVtZW50cy4KICAgICAgICBjaGsuY2hlY2tOb25DeWNsaWNFbGVtZW50cyh0cmVlKTsKCiAgICAgICAgLy8gQ2hlY2sgZm9yIHByb3BlciB1c2Ugb2Ygc2VyaWFsVmVyc2lvblVJRAogICAgICAgIGlmIChlbnYuaW5mby5saW50LmlzRW5hYmxlZChMaW50Q2F0ZWdvcnkuU0VSSUFMKQogICAgICAgICAgICAgICAgJiYgaXNTZXJpYWxpemFibGUoYy50eXBlKQogICAgICAgICAgICAgICAgJiYgKGMuZmxhZ3MoKSAmIEZsYWdzLkVOVU0pID09IDAKICAgICAgICAgICAgICAgICYmICFjLmlzQW5vbnltb3VzKCkKICAgICAgICAgICAgICAgICYmIGNoZWNrRm9yU2VyaWFsKGMpKSB7CiAgICAgICAgICAgIGNoZWNrU2VyaWFsVmVyc2lvblVJRCh0cmVlLCBjKTsKICAgICAgICB9CiAgICAgICAgaWYgKGFsbG93VHlwZUFubm9zKSB7CiAgICAgICAgICAgIC8vIENvcnJlY3RseSBvcmdhbml6ZSB0aGUgcG9zdGlvbnMgb2YgdGhlIHR5cGUgYW5ub3RhdGlvbnMKICAgICAgICAgICAgdHlwZUFubm90YXRpb25zLm9yZ2FuaXplVHlwZUFubm90YXRpb25zQm9kaWVzKHRyZWUpOwoKICAgICAgICAgICAgLy8gQ2hlY2sgdHlwZSBhbm5vdGF0aW9ucyBhcHBsaWNhYmlsaXR5IHJ1bGVzCiAgICAgICAgICAgIHZhbGlkYXRlVHlwZUFubm90YXRpb25zKHRyZWUsIGZhbHNlKTsKICAgICAgICB9CiAgICB9CiAgICAgICAgLy8gd2hlcmUKICAgICAgICBib29sZWFuIGNoZWNrRm9yU2VyaWFsKENsYXNzU3ltYm9sIGMpIHsKICAgICAgICAgICAgaWYgKChjLmZsYWdzKCkgJiBBQlNUUkFDVCkgPT0gMCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICByZXR1cm4gYy5tZW1iZXJzKCkuYW55TWF0Y2goYW55Tm9uQWJzdHJhY3RPckRlZmF1bHRNZXRob2QpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEZpbHRlcjxTeW1ib2w+IGFueU5vbkFic3RyYWN0T3JEZWZhdWx0TWV0aG9kID0gcyAtPgogICAgICAgICAgICAgICAgcy5raW5kID09IE1USCAmJiAocy5mbGFncygpICYgKERFRkFVTFQgfCBBQlNUUkFDVCkpICE9IEFCU1RSQUNUOwoKICAgICAgICAvKiogZ2V0IGEgZGlhZ25vc3RpYyBwb3NpdGlvbiBmb3IgYW4gYXR0cmlidXRlIG9mIFR5cGUgdCwgb3IgbnVsbCBpZiBhdHRyaWJ1dGUgbWlzc2luZyAqLwogICAgICAgIHByaXZhdGUgRGlhZ25vc3RpY1Bvc2l0aW9uIGdldERpYWdub3N0aWNQb3NpdGlvbihKQ0NsYXNzRGVjbCB0cmVlLCBUeXBlIHQpIHsKICAgICAgICAgICAgZm9yKExpc3Q8SkNBbm5vdGF0aW9uPiBhbCA9IHRyZWUubW9kcy5hbm5vdGF0aW9uczsgIWFsLmlzRW1wdHkoKTsgYWwgPSBhbC50YWlsKSB7CiAgICAgICAgICAgICAgICBpZiAodHlwZXMuaXNTYW1lVHlwZShhbC5oZWFkLmFubm90YXRpb25UeXBlLnR5cGUsIHQpKQogICAgICAgICAgICAgICAgICAgIHJldHVybiBhbC5oZWFkLnBvcygpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgIC8qKiBjaGVjayBpZiBhIHR5cGUgaXMgYSBzdWJ0eXBlIG9mIFNlcmlhbGl6YWJsZSwgaWYgdGhhdCBpcyBhdmFpbGFibGUuICovCiAgICAgICAgYm9vbGVhbiBpc1NlcmlhbGl6YWJsZShUeXBlIHQpIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIHN5bXMuc2VyaWFsaXphYmxlVHlwZS5jb21wbGV0ZSgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGNhdGNoIChDb21wbGV0aW9uRmFpbHVyZSBlKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHR5cGVzLmlzU3VidHlwZSh0LCBzeW1zLnNlcmlhbGl6YWJsZVR5cGUpOwogICAgICAgIH0KCiAgICAgICAgLyoqIENoZWNrIHRoYXQgYW4gYXBwcm9wcmlhdGUgc2VyaWFsVmVyc2lvblVJRCBtZW1iZXIgaXMgZGVmaW5lZC4gKi8KICAgICAgICBwcml2YXRlIHZvaWQgY2hlY2tTZXJpYWxWZXJzaW9uVUlEKEpDQ2xhc3NEZWNsIHRyZWUsIENsYXNzU3ltYm9sIGMpIHsKCiAgICAgICAgICAgIC8vIGNoZWNrIGZvciBwcmVzZW5jZSBvZiBzZXJpYWxWZXJzaW9uVUlECiAgICAgICAgICAgIFZhclN5bWJvbCBzdnVpZCA9IG51bGw7CiAgICAgICAgICAgIGZvciAoU3ltYm9sIHN5bSA6IGMubWVtYmVycygpLmdldFN5bWJvbHNCeU5hbWUobmFtZXMuc2VyaWFsVmVyc2lvblVJRCkpIHsKICAgICAgICAgICAgICAgIGlmIChzeW0ua2luZCA9PSBWQVIpIHsKICAgICAgICAgICAgICAgICAgICBzdnVpZCA9IChWYXJTeW1ib2wpc3ltOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoc3Z1aWQgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgbG9nLndhcm5pbmcoTGludENhdGVnb3J5LlNFUklBTCwKICAgICAgICAgICAgICAgICAgICAgICAgdHJlZS5wb3MoKSwgIm1pc3NpbmcuU1ZVSUQiLCBjKTsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gY2hlY2sgdGhhdCBpdCBpcyBzdGF0aWMgZmluYWwKICAgICAgICAgICAgaWYgKChzdnVpZC5mbGFncygpICYgKFNUQVRJQyB8IEZJTkFMKSkgIT0KICAgICAgICAgICAgICAgIChTVEFUSUMgfCBGSU5BTCkpCiAgICAgICAgICAgICAgICBsb2cud2FybmluZyhMaW50Q2F0ZWdvcnkuU0VSSUFMLAogICAgICAgICAgICAgICAgICAgICAgICBUcmVlSW5mby5kaWFnbm9zdGljUG9zaXRpb25Gb3Ioc3Z1aWQsIHRyZWUpLCAiaW1wcm9wZXIuU1ZVSUQiLCBjKTsKCiAgICAgICAgICAgIC8vIGNoZWNrIHRoYXQgaXQgaXMgbG9uZwogICAgICAgICAgICBlbHNlIGlmICghc3Z1aWQudHlwZS5oYXNUYWcoTE9ORykpCiAgICAgICAgICAgICAgICBsb2cud2FybmluZyhMaW50Q2F0ZWdvcnkuU0VSSUFMLAogICAgICAgICAgICAgICAgICAgICAgICBUcmVlSW5mby5kaWFnbm9zdGljUG9zaXRpb25Gb3Ioc3Z1aWQsIHRyZWUpLCAibG9uZy5TVlVJRCIsIGMpOwoKICAgICAgICAgICAgLy8gY2hlY2sgY29uc3RhbnQKICAgICAgICAgICAgZWxzZSBpZiAoc3Z1aWQuZ2V0Q29uc3RWYWx1ZSgpID09IG51bGwpCiAgICAgICAgICAgICAgICBsb2cud2FybmluZyhMaW50Q2F0ZWdvcnkuU0VSSUFMLAogICAgICAgICAgICAgICAgICAgICAgICBUcmVlSW5mby5kaWFnbm9zdGljUG9zaXRpb25Gb3Ioc3Z1aWQsIHRyZWUpLCAiY29uc3RhbnQuU1ZVSUQiLCBjKTsKICAgICAgICB9CgogICAgcHJpdmF0ZSBUeXBlIGNhcHR1cmUoVHlwZSB0eXBlKSB7CiAgICAgICAgcmV0dXJuIHR5cGVzLmNhcHR1cmUodHlwZSk7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmFsaWRhdGVUeXBlQW5ub3RhdGlvbnMoSkNUcmVlIHRyZWUsIGJvb2xlYW4gc2lnT25seSkgewogICAgICAgIHRyZWUuYWNjZXB0KG5ldyBUeXBlQW5ub3RhdGlvbnNWYWxpZGF0b3Ioc2lnT25seSkpOwogICAgfQogICAgLy93aGVyZQogICAgcHJpdmF0ZSBmaW5hbCBjbGFzcyBUeXBlQW5ub3RhdGlvbnNWYWxpZGF0b3IgZXh0ZW5kcyBUcmVlU2Nhbm5lciB7CgogICAgICAgIHByaXZhdGUgZmluYWwgYm9vbGVhbiBzaWdPbmx5OwogICAgICAgIHB1YmxpYyBUeXBlQW5ub3RhdGlvbnNWYWxpZGF0b3IoYm9vbGVhbiBzaWdPbmx5KSB7CiAgICAgICAgICAgIHRoaXMuc2lnT25seSA9IHNpZ09ubHk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdEFubm90YXRpb24oSkNBbm5vdGF0aW9uIHRyZWUpIHsKICAgICAgICAgICAgY2hrLnZhbGlkYXRlVHlwZUFubm90YXRpb24odHJlZSwgZmFsc2UpOwogICAgICAgICAgICBzdXBlci52aXNpdEFubm90YXRpb24odHJlZSk7CiAgICAgICAgfQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0QW5ub3RhdGVkVHlwZShKQ0Fubm90YXRlZFR5cGUgdHJlZSkgewogICAgICAgICAgICBpZiAoIXRyZWUudW5kZXJseWluZ1R5cGUudHlwZS5pc0Vycm9uZW91cygpKSB7CiAgICAgICAgICAgICAgICBzdXBlci52aXNpdEFubm90YXRlZFR5cGUodHJlZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRUeXBlUGFyYW1ldGVyKEpDVHlwZVBhcmFtZXRlciB0cmVlKSB7CiAgICAgICAgICAgIGNoay52YWxpZGF0ZVR5cGVBbm5vdGF0aW9ucyh0cmVlLmFubm90YXRpb25zLCB0cnVlKTsKICAgICAgICAgICAgc2Nhbih0cmVlLmJvdW5kcyk7CiAgICAgICAgICAgIC8vIERvbid0IGNhbGwgc3VwZXIuCiAgICAgICAgICAgIC8vIFRoaXMgaXMgbmVlZGVkIGJlY2F1c2UgYWJvdmUgd2UgY2FsbCB2YWxpZGF0ZVR5cGVBbm5vdGF0aW9uIHdpdGgKICAgICAgICAgICAgLy8gZmFsc2UsIHdoaWNoIHdvdWxkIGZvcmJpZCBhbm5vdGF0aW9ucyBvbiB0eXBlIHBhcmFtZXRlcnMuCiAgICAgICAgICAgIC8vIHN1cGVyLnZpc2l0VHlwZVBhcmFtZXRlcih0cmVlKTsKICAgICAgICB9CiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRNZXRob2REZWYoSkNNZXRob2REZWNsIHRyZWUpIHsKICAgICAgICAgICAgaWYgKHRyZWUucmVjdnBhcmFtICE9IG51bGwgJiYKICAgICAgICAgICAgICAgICAgICAhdHJlZS5yZWN2cGFyYW0udmFydHlwZS50eXBlLmlzRXJyb25lb3VzKCkpIHsKICAgICAgICAgICAgICAgIGNoZWNrRm9yRGVjbGFyYXRpb25Bbm5vdGF0aW9ucyh0cmVlLnJlY3ZwYXJhbS5tb2RzLmFubm90YXRpb25zLAogICAgICAgICAgICAgICAgICAgICAgICB0cmVlLnJlY3ZwYXJhbS52YXJ0eXBlLnR5cGUudHN5bSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHRyZWUucmVzdHlwZSAhPSBudWxsICYmIHRyZWUucmVzdHlwZS50eXBlICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIHZhbGlkYXRlQW5ub3RhdGVkVHlwZSh0cmVlLnJlc3R5cGUsIHRyZWUucmVzdHlwZS50eXBlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoc2lnT25seSkgewogICAgICAgICAgICAgICAgc2Nhbih0cmVlLm1vZHMpOwogICAgICAgICAgICAgICAgc2Nhbih0cmVlLnJlc3R5cGUpOwogICAgICAgICAgICAgICAgc2Nhbih0cmVlLnR5cGFyYW1zKTsKICAgICAgICAgICAgICAgIHNjYW4odHJlZS5yZWN2cGFyYW0pOwogICAgICAgICAgICAgICAgc2Nhbih0cmVlLnBhcmFtcyk7CiAgICAgICAgICAgICAgICBzY2FuKHRyZWUudGhyb3duKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHNjYW4odHJlZS5kZWZhdWx0VmFsdWUpOwogICAgICAgICAgICAgICAgc2Nhbih0cmVlLmJvZHkpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0VmFyRGVmKGZpbmFsIEpDVmFyaWFibGVEZWNsIHRyZWUpIHsKICAgICAgICAgICAgLy9TeXN0ZW0uZXJyLnByaW50bG4oInZhbGlkYXRlVHlwZUFubm90YXRpb25zLnZpc2l0VmFyRGVmICIgKyB0cmVlKTsKICAgICAgICAgICAgaWYgKHRyZWUuc3ltICE9IG51bGwgJiYgdHJlZS5zeW0udHlwZSAhPSBudWxsKQogICAgICAgICAgICAgICAgdmFsaWRhdGVBbm5vdGF0ZWRUeXBlKHRyZWUudmFydHlwZSwgdHJlZS5zeW0udHlwZSk7CiAgICAgICAgICAgIHNjYW4odHJlZS5tb2RzKTsKICAgICAgICAgICAgc2Nhbih0cmVlLnZhcnR5cGUpOwogICAgICAgICAgICBpZiAoIXNpZ09ubHkpIHsKICAgICAgICAgICAgICAgIHNjYW4odHJlZS5pbml0KTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdFR5cGVDYXN0KEpDVHlwZUNhc3QgdHJlZSkgewogICAgICAgICAgICBpZiAodHJlZS5jbGF6eiAhPSBudWxsICYmIHRyZWUuY2xhenoudHlwZSAhPSBudWxsKQogICAgICAgICAgICAgICAgdmFsaWRhdGVBbm5vdGF0ZWRUeXBlKHRyZWUuY2xhenosIHRyZWUuY2xhenoudHlwZSk7CiAgICAgICAgICAgIHN1cGVyLnZpc2l0VHlwZUNhc3QodHJlZSk7CiAgICAgICAgfQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0VHlwZVRlc3QoSkNJbnN0YW5jZU9mIHRyZWUpIHsKICAgICAgICAgICAgaWYgKHRyZWUuY2xhenogIT0gbnVsbCAmJiB0cmVlLmNsYXp6LnR5cGUgIT0gbnVsbCkKICAgICAgICAgICAgICAgIHZhbGlkYXRlQW5ub3RhdGVkVHlwZSh0cmVlLmNsYXp6LCB0cmVlLmNsYXp6LnR5cGUpOwogICAgICAgICAgICBzdXBlci52aXNpdFR5cGVUZXN0KHRyZWUpOwogICAgICAgIH0KICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdE5ld0NsYXNzKEpDTmV3Q2xhc3MgdHJlZSkgewogICAgICAgICAgICBpZiAodHJlZS5jbGF6eiAhPSBudWxsICYmIHRyZWUuY2xhenoudHlwZSAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICBpZiAodHJlZS5jbGF6ei5oYXNUYWcoQU5OT1RBVEVEX1RZUEUpKSB7CiAgICAgICAgICAgICAgICAgICAgY2hlY2tGb3JEZWNsYXJhdGlvbkFubm90YXRpb25zKCgoSkNBbm5vdGF0ZWRUeXBlKSB0cmVlLmNsYXp6KS5hbm5vdGF0aW9ucywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyZWUuY2xhenoudHlwZS50c3ltKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICh0cmVlLmRlZiAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgY2hlY2tGb3JEZWNsYXJhdGlvbkFubm90YXRpb25zKHRyZWUuZGVmLm1vZHMuYW5ub3RhdGlvbnMsIHRyZWUuY2xhenoudHlwZS50c3ltKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB2YWxpZGF0ZUFubm90YXRlZFR5cGUodHJlZS5jbGF6eiwgdHJlZS5jbGF6ei50eXBlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBzdXBlci52aXNpdE5ld0NsYXNzKHRyZWUpOwogICAgICAgIH0KICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdE5ld0FycmF5KEpDTmV3QXJyYXkgdHJlZSkgewogICAgICAgICAgICBpZiAodHJlZS5lbGVtdHlwZSAhPSBudWxsICYmIHRyZWUuZWxlbXR5cGUudHlwZSAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICBpZiAodHJlZS5lbGVtdHlwZS5oYXNUYWcoQU5OT1RBVEVEX1RZUEUpKSB7CiAgICAgICAgICAgICAgICAgICAgY2hlY2tGb3JEZWNsYXJhdGlvbkFubm90YXRpb25zKCgoSkNBbm5vdGF0ZWRUeXBlKSB0cmVlLmVsZW10eXBlKS5hbm5vdGF0aW9ucywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyZWUuZWxlbXR5cGUudHlwZS50c3ltKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHZhbGlkYXRlQW5ub3RhdGVkVHlwZSh0cmVlLmVsZW10eXBlLCB0cmVlLmVsZW10eXBlLnR5cGUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHN1cGVyLnZpc2l0TmV3QXJyYXkodHJlZSk7CiAgICAgICAgfQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0Q2xhc3NEZWYoSkNDbGFzc0RlY2wgdHJlZSkgewogICAgICAgICAgICAvL1N5c3RlbS5lcnIucHJpbnRsbigidmFsaWRhdGVUeXBlQW5ub3RhdGlvbnMudmlzaXRDbGFzc0RlZiAiICsgdHJlZSk7CiAgICAgICAgICAgIGlmIChzaWdPbmx5KSB7CiAgICAgICAgICAgICAgICBzY2FuKHRyZWUubW9kcyk7CiAgICAgICAgICAgICAgICBzY2FuKHRyZWUudHlwYXJhbXMpOwogICAgICAgICAgICAgICAgc2Nhbih0cmVlLmV4dGVuZGluZyk7CiAgICAgICAgICAgICAgICBzY2FuKHRyZWUuaW1wbGVtZW50aW5nKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBmb3IgKEpDVHJlZSBtZW1iZXIgOiB0cmVlLmRlZnMpIHsKICAgICAgICAgICAgICAgIGlmIChtZW1iZXIuaGFzVGFnKFRhZy5DTEFTU0RFRikpIHsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHNjYW4obWVtYmVyKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdEJsb2NrKEpDQmxvY2sgdHJlZSkgewogICAgICAgICAgICBpZiAoIXNpZ09ubHkpIHsKICAgICAgICAgICAgICAgIHNjYW4odHJlZS5zdGF0cyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8qIEkgd291bGQgd2FudCB0byBtb2RlbCB0aGlzIGFmdGVyCiAgICAgICAgICogY29tLnN1bi50b29scy5qYXZhYy5jb21wLkNoZWNrLlZhbGlkYXRvci52aXNpdFNlbGVjdEludGVybmFsKEpDRmllbGRBY2Nlc3MpCiAgICAgICAgICogYW5kIG92ZXJyaWRlIHZpc2l0U2VsZWN0IGFuZCB2aXNpdFR5cGVBcHBseS4KICAgICAgICAgKiBIb3dldmVyLCB3ZSBvbmx5IHNldCB0aGUgYW5ub3RhdGVkIHR5cGUgaW4gdGhlIHRvcC1sZXZlbCB0eXBlCiAgICAgICAgICogb2YgdGhlIHN5bWJvbC4KICAgICAgICAgKiBUaGVyZWZvcmUsIHdlIG5lZWQgdG8gb3ZlcnJpZGUgZWFjaCBpbmRpdmlkdWFsIGxvY2F0aW9uIHdoZXJlIGEgdHlwZQogICAgICAgICAqIGNhbiBvY2N1ci4KICAgICAgICAgKi8KICAgICAgICBwcml2YXRlIHZvaWQgdmFsaWRhdGVBbm5vdGF0ZWRUeXBlKGZpbmFsIEpDVHJlZSBlcnJ0cmVlLCBmaW5hbCBUeXBlIHR5cGUpIHsKICAgICAgICAgICAgLy9TeXN0ZW0uZXJyLnByaW50bG4oIkF0dHIudmFsaWRhdGVBbm5vdGF0ZWRUeXBlOiAiICsgZXJydHJlZSArICIgdHlwZTogIiArIHR5cGUpOwoKICAgICAgICAgICAgaWYgKHR5cGUuaXNQcmltaXRpdmVPclZvaWQoKSkgewogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CgogICAgICAgICAgICBKQ1RyZWUgZW5jbFRyID0gZXJydHJlZTsKICAgICAgICAgICAgVHlwZSBlbmNsVHkgPSB0eXBlOwoKICAgICAgICAgICAgYm9vbGVhbiByZXBlYXQgPSB0cnVlOwogICAgICAgICAgICB3aGlsZSAocmVwZWF0KSB7CiAgICAgICAgICAgICAgICBpZiAoZW5jbFRyLmhhc1RhZyhUWVBFQVBQTFkpKSB7CiAgICAgICAgICAgICAgICAgICAgTGlzdDxUeXBlPiB0eWFyZ3MgPSBlbmNsVHkuZ2V0VHlwZUFyZ3VtZW50cygpOwogICAgICAgICAgICAgICAgICAgIExpc3Q8SkNFeHByZXNzaW9uPiB0cmFyZ3MgPSAoKEpDVHlwZUFwcGx5KWVuY2xUcikuZ2V0VHlwZUFyZ3VtZW50cygpOwogICAgICAgICAgICAgICAgICAgIGlmICh0cmFyZ3MubGVuZ3RoKCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIE5vdGhpbmcgdG8gZG8gZm9yIGRpYW1vbmRzCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eWFyZ3MubGVuZ3RoKCkgPT0gdHJhcmdzLmxlbmd0aCgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHR5YXJncy5sZW5ndGgoKTsgKytpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsaWRhdGVBbm5vdGF0ZWRUeXBlKHRyYXJncy5nZXQoaSksIHR5YXJncy5nZXQoaSkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIElmIHRoZSBsZW5ndGhzIGRvbid0IG1hdGNoLCBpdCdzIGVpdGhlciBhIGRpYW1vbmQKICAgICAgICAgICAgICAgICAgICAgICAgLy8gb3Igc29tZSBuZXN0ZWQgdHlwZSB0aGF0IHJlZHVuZGFudGx5IHByb3ZpZGVzCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHR5cGUgYXJndW1lbnRzIGluIHRoZSB0cmVlLgogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gTG9vayBhdCB0aGUgY2xhenogcGFydCBvZiBhIGdlbmVyaWMgdHlwZQogICAgICAgICAgICAgICAgICAgIGVuY2xUciA9ICgoSkNUcmVlLkpDVHlwZUFwcGx5KWVuY2xUcikuY2xheno7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKGVuY2xUci5oYXNUYWcoU0VMRUNUKSkgewogICAgICAgICAgICAgICAgICAgIGVuY2xUciA9ICgoSkNUcmVlLkpDRmllbGRBY2Nlc3MpZW5jbFRyKS5nZXRFeHByZXNzaW9uKCk7CiAgICAgICAgICAgICAgICAgICAgaWYgKGVuY2xUeSAhPSBudWxsICYmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAhZW5jbFR5Lmhhc1RhZyhOT05FKSkgewogICAgICAgICAgICAgICAgICAgICAgICBlbmNsVHkgPSBlbmNsVHkuZ2V0RW5jbG9zaW5nVHlwZSgpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZW5jbFRyLmhhc1RhZyhBTk5PVEFURURfVFlQRSkpIHsKICAgICAgICAgICAgICAgICAgICBKQ0Fubm90YXRlZFR5cGUgYXQgPSAoSkNUcmVlLkpDQW5ub3RhdGVkVHlwZSkgZW5jbFRyOwogICAgICAgICAgICAgICAgICAgIGlmIChlbmNsVHkgPT0gbnVsbCB8fCBlbmNsVHkuaGFzVGFnKE5PTkUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhdC5nZXRBbm5vdGF0aW9ucygpLnNpemUoKSA9PSAxKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2cuZXJyb3IoYXQudW5kZXJseWluZ1R5cGUucG9zKCksICJjYW50LnR5cGUuYW5ub3RhdGUuc2NvcGluZy4xIiwgYXQuZ2V0QW5ub3RhdGlvbnMoKS5oZWFkLmF0dHJpYnV0ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0QnVmZmVyPEF0dHJpYnV0ZS5Db21wb3VuZD4gY29tcHMgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKEpDQW5ub3RhdGlvbiBhbiA6IGF0LmdldEFubm90YXRpb25zKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21wcy5hZGQoYW4uYXR0cmlidXRlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZy5lcnJvcihhdC51bmRlcmx5aW5nVHlwZS5wb3MoKSwgImNhbnQudHlwZS5hbm5vdGF0ZS5zY29waW5nIiwgY29tcHMudG9MaXN0KCkpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIHJlcGVhdCA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbmNsVHIgPSBhdC51bmRlcmx5aW5nVHlwZTsKICAgICAgICAgICAgICAgICAgICAvLyBlbmNsVHkgZG9lc24ndCBuZWVkIHRvIGJlIGNoYW5nZWQKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZW5jbFRyLmhhc1RhZyhJREVOVCkpIHsKICAgICAgICAgICAgICAgICAgICByZXBlYXQgPSBmYWxzZTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZW5jbFRyLmhhc1RhZyhKQ1RyZWUuVGFnLldJTERDQVJEKSkgewogICAgICAgICAgICAgICAgICAgIEpDV2lsZGNhcmQgd2MgPSAoSkNXaWxkY2FyZCkgZW5jbFRyOwogICAgICAgICAgICAgICAgICAgIGlmICh3Yy5nZXRLaW5kKCkgPT0gSkNUcmVlLktpbmQuRVhURU5EU19XSUxEQ0FSRCkgewogICAgICAgICAgICAgICAgICAgICAgICB2YWxpZGF0ZUFubm90YXRlZFR5cGUod2MuZ2V0Qm91bmQoKSwgKChXaWxkY2FyZFR5cGUpZW5jbFR5KS5nZXRFeHRlbmRzQm91bmQoKSk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICh3Yy5nZXRLaW5kKCkgPT0gSkNUcmVlLktpbmQuU1VQRVJfV0lMRENBUkQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFsaWRhdGVBbm5vdGF0ZWRUeXBlKHdjLmdldEJvdW5kKCksICgoV2lsZGNhcmRUeXBlKWVuY2xUeSkuZ2V0U3VwZXJCb3VuZCgpKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBOb3RoaW5nIHRvIGRvIGZvciBVTkJPVU5ECiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHJlcGVhdCA9IGZhbHNlOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChlbmNsVHIuaGFzVGFnKFRZUEVBUlJBWSkpIHsKICAgICAgICAgICAgICAgICAgICBKQ0FycmF5VHlwZVRyZWUgYXJ0ID0gKEpDQXJyYXlUeXBlVHJlZSkgZW5jbFRyOwogICAgICAgICAgICAgICAgICAgIHZhbGlkYXRlQW5ub3RhdGVkVHlwZShhcnQuZ2V0VHlwZSgpLCAoKEFycmF5VHlwZSllbmNsVHkpLmdldENvbXBvbmVudFR5cGUoKSk7CiAgICAgICAgICAgICAgICAgICAgcmVwZWF0ID0gZmFsc2U7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGVuY2xUci5oYXNUYWcoVFlQRVVOSU9OKSkgewogICAgICAgICAgICAgICAgICAgIEpDVHlwZVVuaW9uIHV0ID0gKEpDVHlwZVVuaW9uKSBlbmNsVHI7CiAgICAgICAgICAgICAgICAgICAgZm9yIChKQ1RyZWUgdCA6IHV0LmdldFR5cGVBbHRlcm5hdGl2ZXMoKSkgewogICAgICAgICAgICAgICAgICAgICAgICB2YWxpZGF0ZUFubm90YXRlZFR5cGUodCwgdC50eXBlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgcmVwZWF0ID0gZmFsc2U7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGVuY2xUci5oYXNUYWcoVFlQRUlOVEVSU0VDVElPTikpIHsKICAgICAgICAgICAgICAgICAgICBKQ1R5cGVJbnRlcnNlY3Rpb24gaXQgPSAoSkNUeXBlSW50ZXJzZWN0aW9uKSBlbmNsVHI7CiAgICAgICAgICAgICAgICAgICAgZm9yIChKQ1RyZWUgdCA6IGl0LmdldEJvdW5kcygpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhbGlkYXRlQW5ub3RhdGVkVHlwZSh0LCB0LnR5cGUpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICByZXBlYXQgPSBmYWxzZTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZW5jbFRyLmdldEtpbmQoKSA9PSBKQ1RyZWUuS2luZC5QUklNSVRJVkVfVFlQRSB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICBlbmNsVHIuZ2V0S2luZCgpID09IEpDVHJlZS5LaW5kLkVSUk9ORU9VUykgewogICAgICAgICAgICAgICAgICAgIHJlcGVhdCA9IGZhbHNlOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBBc3NlcnQuZXJyb3IoIlVuZXhwZWN0ZWQgdHJlZTogIiArIGVuY2xUciArICIgd2l0aCBraW5kOiAiICsgZW5jbFRyLmdldEtpbmQoKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiIHdpdGhpbjogIisgZXJydHJlZSArICIgd2l0aCBraW5kOiAiICsgZXJydHJlZS5nZXRLaW5kKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIHZvaWQgY2hlY2tGb3JEZWNsYXJhdGlvbkFubm90YXRpb25zKExpc3Q8PyBleHRlbmRzIEpDQW5ub3RhdGlvbj4gYW5ub3RhdGlvbnMsCiAgICAgICAgICAgICAgICBTeW1ib2wgc3ltKSB7CiAgICAgICAgICAgIC8vIEVuc3VyZSB0aGF0IG5vIGRlY2xhcmF0aW9uIGFubm90YXRpb25zIGFyZSBwcmVzZW50LgogICAgICAgICAgICAvLyBOb3RlIHRoYXQgYSB0cmVlIHR5cGUgbWlnaHQgYmUgYW4gQW5ub3RhdGVkVHlwZSB3aXRoCiAgICAgICAgICAgIC8vIGVtcHR5IGFubm90YXRpb25zLCBpZiBvbmx5IGRlY2xhcmF0aW9uIGFubm90YXRpb25zIHdlcmUgZ2l2ZW4uCiAgICAgICAgICAgIC8vIFRoaXMgbWV0aG9kIHdpbGwgcmFpc2UgYW4gZXJyb3IgZm9yIHN1Y2ggYSB0eXBlLgogICAgICAgICAgICBmb3IgKEpDQW5ub3RhdGlvbiBhaSA6IGFubm90YXRpb25zKSB7CiAgICAgICAgICAgICAgICBpZiAoIWFpLnR5cGUuaXNFcnJvbmVvdXMoKSAmJgogICAgICAgICAgICAgICAgICAgICAgICB0eXBlQW5ub3RhdGlvbnMuYW5ub3RhdGlvblRhcmdldFR5cGUoYWkuYXR0cmlidXRlLCBzeW0pID09IFR5cGVBbm5vdGF0aW9ucy5Bbm5vdGF0aW9uVHlwZS5ERUNMQVJBVElPTikgewogICAgICAgICAgICAgICAgICAgIGxvZy5lcnJvcihhaS5wb3MoKSwgRXJyb3JzLkFubm90YXRpb25UeXBlTm90QXBwbGljYWJsZVRvVHlwZShhaS50eXBlKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLy8gPGVkaXRvci1mb2xkIGRlc2M9InBvc3QtYXR0cmlidXRpb24gdmlzaXRvciI+CgogICAgLyoqCiAgICAgKiBIYW5kbGUgbWlzc2luZyB0eXBlcy9zeW1ib2xzIGluIGFuIEFTVC4gVGhpcyByb3V0aW5lIGlzIHVzZWZ1bCB3aGVuCiAgICAgKiB0aGUgY29tcGlsZXIgaGFzIGVuY291bnRlcmVkIHNvbWUgZXJyb3JzICh3aGljaCBtaWdodCBoYXZlIGVuZGVkIHVwCiAgICAgKiB0ZXJtaW5hdGluZyBhdHRyaWJ1dGlvbiBhYnJ1cHRseSk7IGlmIHRoZSBjb21waWxlciBpcyB1c2VkIGluIGZhaWwtb3ZlcgogICAgICogbW9kZSAoZS5nLiBieSBhbiBJREUpIGFuZCB0aGUgQVNUIGNvbnRhaW5zIHNlbWFudGljIGVycm9ycywgdGhpcyByb3V0aW5lCiAgICAgKiBwcmV2ZW50cyBOUEUgdG8gYmUgcHJvZ2FnYXRlZCBkdXJpbmcgc3Vic2VxdWVudCBjb21waWxhdGlvbiBzdGVwcy4KICAgICAqLwogICAgcHVibGljIHZvaWQgcG9zdEF0dHIoSkNUcmVlIHRyZWUpIHsKICAgICAgICBuZXcgUG9zdEF0dHJBbmFseXplcigpLnNjYW4odHJlZSk7CiAgICB9CgogICAgY2xhc3MgUG9zdEF0dHJBbmFseXplciBleHRlbmRzIFRyZWVTY2FubmVyIHsKCiAgICAgICAgcHJpdmF0ZSB2b2lkIGluaXRUeXBlSWZOZWVkZWQoSkNUcmVlIHRoYXQpIHsKICAgICAgICAgICAgaWYgKHRoYXQudHlwZSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICBpZiAodGhhdC5oYXNUYWcoTUVUSE9EREVGKSkgewogICAgICAgICAgICAgICAgICAgIHRoYXQudHlwZSA9IGR1bW15TWV0aG9kVHlwZSgoSkNNZXRob2REZWNsKXRoYXQpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICB0aGF0LnR5cGUgPSBzeW1zLnVua25vd25UeXBlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvKiBDb25zdHJ1Y3QgYSBkdW1teSBtZXRob2QgdHlwZS4gSWYgd2UgaGF2ZSBhIG1ldGhvZCBkZWNsYXJhdGlvbiwKICAgICAgICAgKiBhbmQgdGhlIGRlY2xhcmVkIHJldHVybiB0eXBlIGlzIHZvaWQsIHRoZW4gdXNlIHRoYXQgcmV0dXJuIHR5cGUKICAgICAgICAgKiBpbnN0ZWFkIG9mIFVOS05PV04gdG8gYXZvaWQgc3B1cmlvdXMgZXJyb3IgbWVzc2FnZXMgaW4gbGFtYmRhCiAgICAgICAgICogYm9kaWVzIChzZWU6SkRLLTgwNDE3MDQpLgogICAgICAgICAqLwogICAgICAgIHByaXZhdGUgVHlwZSBkdW1teU1ldGhvZFR5cGUoSkNNZXRob2REZWNsIG1kKSB7CiAgICAgICAgICAgIFR5cGUgcmVzdHlwZSA9IHN5bXMudW5rbm93blR5cGU7CiAgICAgICAgICAgIGlmIChtZCAhPSBudWxsICYmIG1kLnJlc3R5cGUuaGFzVGFnKFRZUEVJREVOVCkpIHsKICAgICAgICAgICAgICAgIEpDUHJpbWl0aXZlVHlwZVRyZWUgcHJpbSA9IChKQ1ByaW1pdGl2ZVR5cGVUcmVlKW1kLnJlc3R5cGU7CiAgICAgICAgICAgICAgICBpZiAocHJpbS50eXBldGFnID09IFZPSUQpCiAgICAgICAgICAgICAgICAgICAgcmVzdHlwZSA9IHN5bXMudm9pZFR5cGU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG5ldyBNZXRob2RUeXBlKExpc3QubmlsKCksIHJlc3R5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0Lm5pbCgpLCBzeW1zLm1ldGhvZENsYXNzKTsKICAgICAgICB9CiAgICAgICAgcHJpdmF0ZSBUeXBlIGR1bW15TWV0aG9kVHlwZSgpIHsKICAgICAgICAgICAgcmV0dXJuIGR1bW15TWV0aG9kVHlwZShudWxsKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHNjYW4oSkNUcmVlIHRyZWUpIHsKICAgICAgICAgICAgaWYgKHRyZWUgPT0gbnVsbCkgcmV0dXJuOwogICAgICAgICAgICBpZiAodHJlZSBpbnN0YW5jZW9mIEpDRXhwcmVzc2lvbikgewogICAgICAgICAgICAgICAgaW5pdFR5cGVJZk5lZWRlZCh0cmVlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBzdXBlci5zY2FuKHRyZWUpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRJZGVudChKQ0lkZW50IHRoYXQpIHsKICAgICAgICAgICAgaWYgKHRoYXQuc3ltID09IG51bGwpIHsKICAgICAgICAgICAgICAgIHRoYXQuc3ltID0gc3ltcy51bmtub3duU3ltYm9sOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdFNlbGVjdChKQ0ZpZWxkQWNjZXNzIHRoYXQpIHsKICAgICAgICAgICAgaWYgKHRoYXQuc3ltID09IG51bGwpIHsKICAgICAgICAgICAgICAgIHRoYXQuc3ltID0gc3ltcy51bmtub3duU3ltYm9sOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHN1cGVyLnZpc2l0U2VsZWN0KHRoYXQpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRDbGFzc0RlZihKQ0NsYXNzRGVjbCB0aGF0KSB7CiAgICAgICAgICAgIGluaXRUeXBlSWZOZWVkZWQodGhhdCk7CiAgICAgICAgICAgIGlmICh0aGF0LnN5bSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICB0aGF0LnN5bSA9IG5ldyBDbGFzc1N5bWJvbCgwLCB0aGF0Lm5hbWUsIHRoYXQudHlwZSwgc3ltcy5ub1N5bWJvbCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc3VwZXIudmlzaXRDbGFzc0RlZih0aGF0KTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0TWV0aG9kRGVmKEpDTWV0aG9kRGVjbCB0aGF0KSB7CiAgICAgICAgICAgIGluaXRUeXBlSWZOZWVkZWQodGhhdCk7CiAgICAgICAgICAgIGlmICh0aGF0LnN5bSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICB0aGF0LnN5bSA9IG5ldyBNZXRob2RTeW1ib2woMCwgdGhhdC5uYW1lLCB0aGF0LnR5cGUsIHN5bXMubm9TeW1ib2wpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHN1cGVyLnZpc2l0TWV0aG9kRGVmKHRoYXQpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRWYXJEZWYoSkNWYXJpYWJsZURlY2wgdGhhdCkgewogICAgICAgICAgICBpbml0VHlwZUlmTmVlZGVkKHRoYXQpOwogICAgICAgICAgICBpZiAodGhhdC5zeW0gPT0gbnVsbCkgewogICAgICAgICAgICAgICAgdGhhdC5zeW0gPSBuZXcgVmFyU3ltYm9sKDAsIHRoYXQubmFtZSwgdGhhdC50eXBlLCBzeW1zLm5vU3ltYm9sKTsKICAgICAgICAgICAgICAgIHRoYXQuc3ltLmFkciA9IDA7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHRoYXQudmFydHlwZSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICB0aGF0LnZhcnR5cGUgPSBtYWtlLkVycm9uZW91cygpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHN1cGVyLnZpc2l0VmFyRGVmKHRoYXQpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXROZXdDbGFzcyhKQ05ld0NsYXNzIHRoYXQpIHsKICAgICAgICAgICAgaWYgKHRoYXQuY29uc3RydWN0b3IgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgdGhhdC5jb25zdHJ1Y3RvciA9IG5ldyBNZXRob2RTeW1ib2woMCwgbmFtZXMuaW5pdCwKICAgICAgICAgICAgICAgICAgICAgICAgZHVtbXlNZXRob2RUeXBlKCksIHN5bXMubm9TeW1ib2wpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICh0aGF0LmNvbnN0cnVjdG9yVHlwZSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICB0aGF0LmNvbnN0cnVjdG9yVHlwZSA9IHN5bXMudW5rbm93blR5cGU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc3VwZXIudmlzaXROZXdDbGFzcyh0aGF0KTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0QXNzaWdub3AoSkNBc3NpZ25PcCB0aGF0KSB7CiAgICAgICAgICAgIGlmICh0aGF0Lm9wZXJhdG9yID09IG51bGwpIHsKICAgICAgICAgICAgICAgIHRoYXQub3BlcmF0b3IgPSBuZXcgT3BlcmF0b3JTeW1ib2wobmFtZXMuZW1wdHksIGR1bW15TWV0aG9kVHlwZSgpLAogICAgICAgICAgICAgICAgICAgICAgICAtMSwgc3ltcy5ub1N5bWJvbCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc3VwZXIudmlzaXRBc3NpZ25vcCh0aGF0KTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0QmluYXJ5KEpDQmluYXJ5IHRoYXQpIHsKICAgICAgICAgICAgaWYgKHRoYXQub3BlcmF0b3IgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgdGhhdC5vcGVyYXRvciA9IG5ldyBPcGVyYXRvclN5bWJvbChuYW1lcy5lbXB0eSwgZHVtbXlNZXRob2RUeXBlKCksCiAgICAgICAgICAgICAgICAgICAgICAgIC0xLCBzeW1zLm5vU3ltYm9sKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBzdXBlci52aXNpdEJpbmFyeSh0aGF0KTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0VW5hcnkoSkNVbmFyeSB0aGF0KSB7CiAgICAgICAgICAgIGlmICh0aGF0Lm9wZXJhdG9yID09IG51bGwpIHsKICAgICAgICAgICAgICAgIHRoYXQub3BlcmF0b3IgPSBuZXcgT3BlcmF0b3JTeW1ib2wobmFtZXMuZW1wdHksIGR1bW15TWV0aG9kVHlwZSgpLAogICAgICAgICAgICAgICAgICAgICAgICAtMSwgc3ltcy5ub1N5bWJvbCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc3VwZXIudmlzaXRVbmFyeSh0aGF0KTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0TGFtYmRhKEpDTGFtYmRhIHRoYXQpIHsKICAgICAgICAgICAgc3VwZXIudmlzaXRMYW1iZGEodGhhdCk7CiAgICAgICAgICAgIGlmICh0aGF0LnRhcmdldHMgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgdGhhdC50YXJnZXRzID0gTGlzdC5uaWwoKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRSZWZlcmVuY2UoSkNNZW1iZXJSZWZlcmVuY2UgdGhhdCkgewogICAgICAgICAgICBzdXBlci52aXNpdFJlZmVyZW5jZSh0aGF0KTsKICAgICAgICAgICAgaWYgKHRoYXQuc3ltID09IG51bGwpIHsKICAgICAgICAgICAgICAgIHRoYXQuc3ltID0gbmV3IE1ldGhvZFN5bWJvbCgwLCBuYW1lcy5lbXB0eSwgZHVtbXlNZXRob2RUeXBlKCksCiAgICAgICAgICAgICAgICAgICAgICAgIHN5bXMubm9TeW1ib2wpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICh0aGF0LnRhcmdldHMgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgdGhhdC50YXJnZXRzID0gTGlzdC5uaWwoKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIC8vIDwvZWRpdG9yLWZvbGQ+CgogICAgcHVibGljIHZvaWQgc2V0UGFja2FnZVN5bWJvbHMoSkNFeHByZXNzaW9uIHBpZCwgU3ltYm9sIHBrZykgewogICAgICAgIG5ldyBUcmVlU2Nhbm5lcigpIHsKICAgICAgICAgICAgU3ltYm9sIHBhY2tnZSA9IHBrZzsKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0SWRlbnQoSkNJZGVudCB0aGF0KSB7CiAgICAgICAgICAgICAgICB0aGF0LnN5bSA9IHBhY2tnZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0U2VsZWN0KEpDRmllbGRBY2Nlc3MgdGhhdCkgewogICAgICAgICAgICAgICAgdGhhdC5zeW0gPSBwYWNrZ2U7CiAgICAgICAgICAgICAgICBwYWNrZ2UgPSBwYWNrZ2Uub3duZXI7CiAgICAgICAgICAgICAgICBzdXBlci52aXNpdFNlbGVjdCh0aGF0KTsKICAgICAgICAgICAgfQogICAgICAgIH0uc2NhbihwaWQpOwogICAgfQoKfQpQSwMECgAACAAABjupSmYFBj3nawAA52sAACoAAABjb20vc3VuL3Rvb2xzL2phdmFjL2NvbXAvQXJndW1lbnRBdHRyLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhYy5jb21wOwoKaW1wb3J0IGNvbS5zdW4uc291cmNlLnRyZWUuTGFtYmRhRXhwcmVzc2lvblRyZWUuQm9keUtpbmQ7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuRmxhZ3M7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuU3ltYm9sOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlN5bXRhYjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5UeXBlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlR5cGVzLkZ1bmN0aW9uRGVzY3JpcHRvckxvb2t1cEVycm9yOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb21wLkF0dHIuUmVzdWx0SW5mbzsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29tcC5BdHRyLlRhcmdldEluZm87CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvbXAuQ2hlY2suQ2hlY2tDb250ZXh0OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb21wLkRlZmVycmVkQXR0ci5BdHRyTW9kZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29tcC5EZWZlcnJlZEF0dHIuRGVmZXJyZWRBdHRyQ29udGV4dDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29tcC5EZWZlcnJlZEF0dHIuRGVmZXJyZWRUeXBlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb21wLkRlZmVycmVkQXR0ci5EZWZlcnJlZFR5cGVDb21wbGV0ZXI7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvbXAuRGVmZXJyZWRBdHRyLkxhbWJkYVJldHVyblNjYW5uZXI7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvbXAuSW5mZXIuUGFydGlhbGx5SW5mZXJyZWRNZXRob2RUeXBlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb21wLlJlc29sdmUuTWV0aG9kUmVzb2x1dGlvblBoYXNlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkpDVHJlZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5KQ1RyZWUuSkNDb25kaXRpb25hbDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5KQ1RyZWUuSkNFeHByZXNzaW9uOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkpDVHJlZS5KQ0xhbWJkYTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5KQ1RyZWUuSkNMYW1iZGEuUGFyYW1ldGVyS2luZDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5KQ1RyZWUuSkNNZW1iZXJSZWZlcmVuY2U7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuSkNUcmVlLkpDTWV0aG9kSW52b2NhdGlvbjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5KQ1RyZWUuSkNOZXdDbGFzczsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5KQ1RyZWUuSkNQYXJlbnM7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuSkNUcmVlLkpDUmV0dXJuOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLlRyZWVDb3BpZXI7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuVHJlZUluZm87CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuQXNzZXJ0OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkNvbnRleHQ7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuRGlhZ25vc3RpY1NvdXJjZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5KQ0RpYWdub3N0aWMuRGlhZ25vc3RpY1Bvc2l0aW9uOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkxpc3Q7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuTGlzdEJ1ZmZlcjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5Mb2c7CgppbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CmltcG9ydCBqYXZhLnV0aWwuTGlua2VkSGFzaE1hcDsKaW1wb3J0IGphdmEudXRpbC5NYXA7CmltcG9ydCBqYXZhLnV0aWwuT3B0aW9uYWw7CmltcG9ydCBqYXZhLnV0aWwuZnVuY3Rpb24uRnVuY3Rpb247CmltcG9ydCBqYXZhLnV0aWwuZnVuY3Rpb24uU3VwcGxpZXI7CgppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5UeXBlVGFnLkFSUkFZOwppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5UeXBlVGFnLkRFRkVSUkVEOwppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5UeXBlVGFnLkZPUkFMTDsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuVHlwZVRhZy5NRVRIT0Q7CmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlR5cGVUYWcuVk9JRDsKCi8qKgogKiBUaGlzIGNsYXNzIHBlcmZvcm1zIGF0dHJpYnV0aW9uIG9mIG1ldGhvZC9jb25zdHJ1Y3RvciBhcmd1bWVudHMgd2hlbiB0YXJnZXQtdHlwaW5nIGlzIGVuYWJsZWQKICogKHNvdXJjZSA+PSA4KTsgZm9yIGVhY2ggYXJndW1lbnQgdGhhdCBpcyBwb3RlbnRpYWxseSBhIHBvbHkgZXhwcmVzc2lvbiwgdGhpcyBjbGFzcyBidWlsZHMKICogYSByaWNoIHJlcHJlc2VudGF0aW9uIChzZWUge0BsaW5rIEFyZ3VtZW50VHlwZX0gd2hpY2ggY2FuIHRoZW4gYmUgdXNlZCBmb3IgcGVyZm9ybWluZyBmYXN0IG92ZXJsb2FkCiAqIGNoZWNrcyB3aXRob3V0IHJlcXVpcmluZyBtdWx0aXBsZSBhdHRyaWJ1dGlvbiBwYXNzZXMgb3ZlciB0aGUgc2FtZSBjb2RlLgogKgogKiBUaGUgYXR0cmlidXRpb24gc3RyYXRlZ3kgZm9yIGEgZ2l2ZW4gbWV0aG9kL2NvbnN0cnVjdG9yIGFyZ3VtZW50IEEgaXMgYXMgZm9sbG93czoKICoKICogLSBpZiBBIGlzIHBvdGVudGlhbGx5IGEgcG9seSBleHByZXNzaW9uIChpLmUuIGRpYW1vbmQgaW5zdGFuY2UgY3JlYXRpb24gZXhwcmVzc2lvbiksIGEgc3BlY3VsYXRpdmUKICogcGFzcyBvdmVyIEEgaXMgcGVyZm9ybWVkOyB0aGUgcmVzdWx0cyBvZiBzdWNoIHNwZWN1bGF0aXZlIGF0dHJpYnV0aW9uIGFyZSB0aGVuIHNhdmVkIGluIGEgc3BlY2lhbAogKiB0eXBlLCBzbyB0aGF0IGVuY2xvc2luZyBvdmVybG9hZCByZXNvbHV0aW9uIGNhbiBiZSBjYXJyaWVkIGJ5IHNpbXBseSBjaGVja2luZyBjb21wYXRpYmlsaXR5IGFnYWluc3QgdGhlCiAqIHR5cGUgZGV0ZXJtaW5lZCBkdXJpbmcgdGhpcyBzcGVjdWxhdGl2ZSBwYXNzLgogKgogKiAtIGlmIEEgaXMgYSBzdGFuZGFsb25lIGV4cHJlc3Npb24sIHJlZ3VsYXIgYXRyaWJ1dHRpb24gdGFrZXMgcGxhY2UuCiAqCiAqIFRvIG1pbmltaXplIHRoZSBzcGVjdWxhdGl2ZSB3b3JrLCBhIGNhY2hlIGlzIHVzZWQsIHNvIHRoYXQgYWxyZWFkeSBjb21wdXRlZCBhcmd1bWVudCB0eXBlcwogKiBhc3NvY2lhdGVkIHdpdGggYSBnaXZlbiB1bmlxdWUgc291cmNlIGxvY2F0aW9uIGFyZSBuZXZlciByZWNvbXB1dGVkIG11bHRpcGxlIHRpbWVzLgogKi8KcHVibGljIGNsYXNzIEFyZ3VtZW50QXR0ciBleHRlbmRzIEpDVHJlZS5WaXNpdG9yIHsKCiAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIENvbnRleHQuS2V5PEFyZ3VtZW50QXR0cj4gbWV0aG9kQXR0cktleSA9IG5ldyBDb250ZXh0LktleTw+KCk7CgogICAgcHJpdmF0ZSBmaW5hbCBEZWZlcnJlZEF0dHIgZGVmZXJyZWRBdHRyOwogICAgcHJpdmF0ZSBmaW5hbCBBdHRyIGF0dHI7CiAgICBwcml2YXRlIGZpbmFsIFN5bXRhYiBzeW1zOwogICAgcHJpdmF0ZSBmaW5hbCBMb2cgbG9nOwoKICAgIC8qKiBBdHRyaWJ1dGlvbiBlbnZpcm9ubWVudCB0byBiZSB1c2VkLiAqLwogICAgcHJpdmF0ZSBFbnY8QXR0ckNvbnRleHQ+IGVudjsKCiAgICAvKiogUmVzdWx0IG9mIG1ldGhvZCBhdHRyaWJ1dGlvbi4gKi8KICAgIHByaXZhdGUgVHlwZSByZXN1bHQ7CgogICAgLyoqIENhY2hlIGZvciBhcmd1bWVudCB0eXBlczsgYmVoYXZpb3IgaXMgaW5mbHVlbmNlcyBieSB0aGUgY3VycnJlbnRseSBzZWxlY3RlZCBjYWNoZSBwb2xpY3kuICovCiAgICBNYXA8VW5pcXVlUG9zLCBBcmd1bWVudFR5cGU8Pz4+IGFyZ3VtZW50VHlwZUNhY2hlID0gbmV3IExpbmtlZEhhc2hNYXA8PigpOwoKICAgIHB1YmxpYyBzdGF0aWMgQXJndW1lbnRBdHRyIGluc3RhbmNlKENvbnRleHQgY29udGV4dCkgewogICAgICAgIEFyZ3VtZW50QXR0ciBpbnN0YW5jZSA9IGNvbnRleHQuZ2V0KG1ldGhvZEF0dHJLZXkpOwogICAgICAgIGlmIChpbnN0YW5jZSA9PSBudWxsKQogICAgICAgICAgICBpbnN0YW5jZSA9IG5ldyBBcmd1bWVudEF0dHIoY29udGV4dCk7CiAgICAgICAgcmV0dXJuIGluc3RhbmNlOwogICAgfQoKICAgIHByb3RlY3RlZCBBcmd1bWVudEF0dHIoQ29udGV4dCBjb250ZXh0KSB7CiAgICAgICAgY29udGV4dC5wdXQobWV0aG9kQXR0cktleSwgdGhpcyk7CiAgICAgICAgZGVmZXJyZWRBdHRyID0gRGVmZXJyZWRBdHRyLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIGF0dHIgPSBBdHRyLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIHN5bXMgPSBTeW10YWIuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgbG9nID0gTG9nLmluc3RhbmNlKGNvbnRleHQpOwogICAgfQoKICAgIC8qKgogICAgICogU2V0IHRoZSByZXN1bHRzIG9mIG1ldGhvZCBhdHRyaWJ1dGlvbi4KICAgICAqLwogICAgdm9pZCBzZXRSZXN1bHQoSkNFeHByZXNzaW9uIHRyZWUsIFR5cGUgdHlwZSkgewogICAgICAgIHJlc3VsdCA9IHR5cGU7CiAgICAgICAgaWYgKGVudi5pbmZvLmlzU3BlY3VsYXRpdmUpIHsKICAgICAgICAgICAgLy9pZiB3ZSBhcmUgaW4gYSBzcGVjdWxhdGl2ZSBicmFuY2ggd2UgY2FuIHNhdmUgdGhlIHR5cGUgaW4gdGhlIHRyZWUgaXRzZWxmCiAgICAgICAgICAgIC8vYXMgdGhlcmUncyBubyByaXNrIG9mIHBvbGx1dGluZyB0aGUgb3JpZ2luYWwgdHJlZS4KICAgICAgICAgICAgdHJlZS50eXBlID0gcmVzdWx0OwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrcyBhIHR5cGUgaW4gdGhlIHNwZWN1bGF0aXZlIHRyZWUgYWdhaW5zdCBhIGdpdmVuIHJlc3VsdDsgdGhlIHR5cGUgY2FuIGJlIGVpdGhlciBhIHBsYWluCiAgICAgKiB0eXBlIG9yIGFuIGFyZ3VtZW50IHR5cGUsaW4gd2hpY2ggY2FzZSBhIG1vcmUgY29tcGxleCBjaGVjayBpcyByZXF1aXJlZC4KICAgICAqLwogICAgVHlwZSBjaGVja1NwZWN1bGF0aXZlKEpDRXhwcmVzc2lvbiBleHByLCBSZXN1bHRJbmZvIHJlc3VsdEluZm8pIHsKICAgICAgICByZXR1cm4gY2hlY2tTcGVjdWxhdGl2ZShleHByLCBleHByLnR5cGUsIHJlc3VsdEluZm8pOwogICAgfQoKICAgIC8qKgogICAgICogQ2hlY2tzIGEgdHlwZSBpbiB0aGUgc3BlY3VsYXRpdmUgdHJlZSBhZ2FpbnN0IGEgZ2l2ZW4gcmVzdWx0OyB0aGUgdHlwZSBjYW4gYmUgZWl0aGVyIGEgcGxhaW4KICAgICAqIHR5cGUgb3IgYW4gYXJndW1lbnQgdHlwZSxpbiB3aGljaCBjYXNlIGEgbW9yZSBjb21wbGV4IGNoZWNrIGlzIHJlcXVpcmVkLgogICAgICovCiAgICBUeXBlIGNoZWNrU3BlY3VsYXRpdmUoRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcywgVHlwZSB0LCBSZXN1bHRJbmZvIHJlc3VsdEluZm8pIHsKICAgICAgICBpZiAodC5oYXNUYWcoREVGRVJSRUQpKSB7CiAgICAgICAgICAgIHJldHVybiAoKERlZmVycmVkVHlwZSl0KS5jaGVjayhyZXN1bHRJbmZvKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gcmVzdWx0SW5mby5jaGVjayhwb3MsIHQpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgYSBsb2NhbCBjYWNoaW5nIGNvbnRleHQgaW4gd2hpY2ggYXJndW1lbnQgdHlwZXMgY2FuIHNhZmVseSBiZSBjYWNoZWQgd2l0aG91dAogICAgICogdGhlIHJpc2sgb2YgcG9sbHV0aW5nIGVuY2xvc2luZyBjb250ZXh0cy4gVGhpcyBpcyB1c2VmdWwgd2hlbiBhdHRlbXB0aW5nIHNwZWN1bGF0aXZlCiAgICAgKiBhdHRyaWJ1dGlvbiBvZiBwb3RlbnRpYWxseSBlcnJvbmVvdXMgZXhwcmVzc2lvbnMsIHdoaWNoIGNvdWxkIGVuZCB1cCBwb2xsdXRpbmcgdGhlIGNhY2hlLgogICAgICovCiAgICBMb2NhbENhY2hlQ29udGV4dCB3aXRoTG9jYWxDYWNoZUNvbnRleHQoKSB7CiAgICAgICAgcmV0dXJuIG5ldyBMb2NhbENhY2hlQ29udGV4dCgpOwogICAgfQoKICAgIC8qKgogICAgICogTG9jYWwgY2FjaGUgY29udGV4dDsgdGhpcyBjbGFzcyBrZWVwcyB0cmFjayBvZiB0aGUgcHJldmlvdXMgY2FjaGUgYW5kIHJldmVydHMgdG8gaXQKICAgICAqIHdoZW4gdGhlIHtAbGluayBMb2NhbENhY2hlQ29udGV4dCNsZWF2ZSgpfSBtZXRob2QgaXMgY2FsbGVkLgogICAgICovCiAgICBjbGFzcyBMb2NhbENhY2hlQ29udGV4dCB7CiAgICAgICAgTWFwPFVuaXF1ZVBvcywgQXJndW1lbnRUeXBlPD8+PiBwcmV2Q2FjaGU7CgogICAgICAgIHB1YmxpYyBMb2NhbENhY2hlQ29udGV4dCgpIHsKICAgICAgICAgICAgdGhpcy5wcmV2Q2FjaGUgPSBhcmd1bWVudFR5cGVDYWNoZTsKICAgICAgICAgICAgYXJndW1lbnRUeXBlQ2FjaGUgPSBuZXcgSGFzaE1hcDw+KCk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgdm9pZCBsZWF2ZSgpIHsKICAgICAgICAgICAgYXJndW1lbnRUeXBlQ2FjaGUgPSBwcmV2Q2FjaGU7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogTWFpbiBlbnRyeSBwb2ludCBmb3IgYXR0cmlidXRpbmcgYW4gYXJndW1lbnQgd2l0aCBnaXZlbiB0cmVlIGFuZCBhdHRyaWJ1dGlvbiBlbnZpcm9ubWVudC4KICAgICAqLwogICAgVHlwZSBhdHRyaWJBcmcoSkNUcmVlIHRyZWUsIEVudjxBdHRyQ29udGV4dD4gZW52KSB7CiAgICAgICAgRW52PEF0dHJDb250ZXh0PiBwcmV2RW52ID0gdGhpcy5lbnY7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgdGhpcy5lbnYgPSBlbnY7CiAgICAgICAgICAgIHRyZWUuYWNjZXB0KHRoaXMpOwogICAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgIHRoaXMuZW52ID0gcHJldkVudjsKICAgICAgICB9CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB2aXNpdFRyZWUoSkNUcmVlIHRoYXQpIHsKICAgICAgICAvL2RlbGVnYXRlcyB0byBBdHRyCiAgICAgICAgdGhhdC5hY2NlcHQoYXR0cik7CiAgICAgICAgcmVzdWx0ID0gYXR0ci5yZXN1bHQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBQcm9jZXNzIGEgbWV0aG9kIGFyZ3VtZW50OyB0aGlzIG1ldGhvZCB0YWtlcyBjYXJlIG9mIHBlcmZvcm1pbmcgYSBzcGVjdWxhdGl2ZSBwYXNzIG92ZXIgdGhlCiAgICAgKiBhcmd1bWVudCB0cmVlIGFuZCBjYWxsaW5nIGEgd2VsbC1kZWZpbmVkIGVudHJ5IHBvaW50IHRvIGJ1aWxkIHRoZSBhcmd1bWVudCB0eXBlIGFzc29jaWF0ZWQKICAgICAqIHdpdGggc3VjaCB0cmVlLgogICAgICovCiAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKICAgIDxUIGV4dGVuZHMgSkNFeHByZXNzaW9uLCBaIGV4dGVuZHMgQXJndW1lbnRUeXBlPFQ+PiB2b2lkIHByb2Nlc3NBcmcoVCB0aGF0LCBGdW5jdGlvbjxULCBaPiBhcmd1bWVudFR5cGVGYWN0b3J5KSB7CiAgICAgICAgVW5pcXVlUG9zIHBvcyA9IG5ldyBVbmlxdWVQb3ModGhhdCk7CiAgICAgICAgcHJvY2Vzc0FyZyh0aGF0LCAoKSAtPiB7CiAgICAgICAgICAgIFQgc3BlY3VsYXRpdmVUcmVlID0gKFQpZGVmZXJyZWRBdHRyLmF0dHJpYlNwZWN1bGF0aXZlKHRoYXQsIGVudiwgYXR0ci5uZXcgTWV0aG9kQXR0ckluZm8oKSB7CiAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgICAgIHByb3RlY3RlZCB2b2lkIGF0dHIoSkNUcmVlIHRyZWUsIEVudjxBdHRyQ29udGV4dD4gZW52KSB7CiAgICAgICAgICAgICAgICAgICAgLy9hdm9pZCBzcGVjdWxhdGl2ZSBhdHRyaWJ1dGlvbiBsb29wcwogICAgICAgICAgICAgICAgICAgIGlmICghbmV3IFVuaXF1ZVBvcyh0cmVlKS5lcXVhbHMocG9zKSkgewogICAgICAgICAgICAgICAgICAgICAgICBzdXBlci5hdHRyKHRyZWUsIGVudik7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmlzaXRUcmVlKHRyZWUpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIHJldHVybiBhcmd1bWVudFR5cGVGYWN0b3J5LmFwcGx5KHNwZWN1bGF0aXZlVHJlZSk7CiAgICAgICAgfSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBQcm9jZXNzIGEgbWV0aG9kIGFyZ3VtZW50OyB0aGlzIG1ldGhvZCBhbGxvd3MgdGhlIGNhbGxlciB0byBzcGVjaWZ5IGEgY3VzdG9tIHNwZWN1bGF0aXZlIGF0dHJpYnV0aW9uCiAgICAgKiBsb2dpYyAodGhpcyBpcyB1c2VkIGUuZy4gZm9yIGxhbWJkYXMpLgogICAgICovCiAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKICAgIDxUIGV4dGVuZHMgSkNFeHByZXNzaW9uLCBaIGV4dGVuZHMgQXJndW1lbnRUeXBlPFQ+PiB2b2lkIHByb2Nlc3NBcmcoVCB0aGF0LCBTdXBwbGllcjxaPiBhcmd1bWVudFR5cGVGYWN0b3J5KSB7CiAgICAgICAgVW5pcXVlUG9zIHBvcyA9IG5ldyBVbmlxdWVQb3ModGhhdCk7CiAgICAgICAgWiBjYWNoZWQgPSAoWilhcmd1bWVudFR5cGVDYWNoZS5nZXQocG9zKTsKICAgICAgICBpZiAoY2FjaGVkICE9IG51bGwpIHsKICAgICAgICAgICAgLy9kdXAgZXhpc3Rpbmcgc3BlY3VsYXRpdmUgdHlwZQogICAgICAgICAgICBzZXRSZXN1bHQodGhhdCwgY2FjaGVkLmR1cCh0aGF0LCBlbnYpKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBaIHJlcyA9IGFyZ3VtZW50VHlwZUZhY3RvcnkuZ2V0KCk7CiAgICAgICAgICAgIGFyZ3VtZW50VHlwZUNhY2hlLnB1dChwb3MsIHJlcyk7CiAgICAgICAgICAgIHNldFJlc3VsdCh0aGF0LCByZXMpOwogICAgICAgIH0KICAgIH0KCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHZpc2l0UGFyZW5zKEpDUGFyZW5zIHRoYXQpIHsKICAgICAgICBwcm9jZXNzQXJnKHRoYXQsIHNwZWN1bGF0aXZlVHJlZSAtPiBuZXcgUGFyZW5zVHlwZSh0aGF0LCBlbnYsIHNwZWN1bGF0aXZlVHJlZSkpOwogICAgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIHZvaWQgdmlzaXRDb25kaXRpb25hbChKQ0NvbmRpdGlvbmFsIHRoYXQpIHsKICAgICAgICBwcm9jZXNzQXJnKHRoYXQsIHNwZWN1bGF0aXZlVHJlZSAtPiBuZXcgQ29uZGl0aW9uYWxUeXBlKHRoYXQsIGVudiwgc3BlY3VsYXRpdmVUcmVlKSk7CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB2aXNpdFJlZmVyZW5jZShKQ01lbWJlclJlZmVyZW5jZSB0cmVlKSB7CiAgICAgICAgLy9wZXJmb3JtIGFyaXR5LWJhc2VkIGNoZWNrCiAgICAgICAgRW52PEF0dHJDb250ZXh0PiBsb2NhbEVudiA9IGVudi5kdXAodHJlZSk7CiAgICAgICAgSkNFeHByZXNzaW9uIGV4cHJUcmVlID0gKEpDRXhwcmVzc2lvbilkZWZlcnJlZEF0dHIuYXR0cmliU3BlY3VsYXRpdmUodHJlZS5nZXRRdWFsaWZpZXJFeHByZXNzaW9uKCksIGxvY2FsRW52LAogICAgICAgICAgICAgICAgYXR0ci5tZW1iZXJSZWZlcmVuY2VRdWFsaWZpZXJSZXN1bHQodHJlZSkpOwogICAgICAgIEpDTWVtYmVyUmVmZXJlbmNlIG1yZWYyID0gbmV3IFRyZWVDb3BpZXI8Vm9pZD4oYXR0ci5tYWtlKS5jb3B5KHRyZWUpOwogICAgICAgIG1yZWYyLmV4cHIgPSBleHByVHJlZTsKICAgICAgICBTeW1ib2wgbGhzU3ltID0gVHJlZUluZm8uc3ltYm9sKGV4cHJUcmVlKTsKICAgICAgICBsb2NhbEVudi5pbmZvLnNlbGVjdFN1cGVyID0gbGhzU3ltICE9IG51bGwgJiYgbGhzU3ltLm5hbWUgPT0gbGhzU3ltLm5hbWUudGFibGUubmFtZXMuX3N1cGVyOwogICAgICAgIFN5bWJvbCByZXMgPQogICAgICAgICAgICAgICAgYXR0ci5ycy5nZXRNZW1iZXJSZWZlcmVuY2UodHJlZSwgbG9jYWxFbnYsIG1yZWYyLAogICAgICAgICAgICAgICAgICAgICAgICBleHByVHJlZS50eXBlLCB0cmVlLm5hbWUpOwogICAgICAgIGlmICghcmVzLmtpbmQuaXNSZXNvbHV0aW9uRXJyb3IoKSkgewogICAgICAgICAgICB0cmVlLnN5bSA9IHJlczsKICAgICAgICB9CiAgICAgICAgaWYgKHJlcy5raW5kLmlzUmVzb2x1dGlvblRhcmdldEVycm9yKCkgfHwKICAgICAgICAgICAgICAgIHJlcy50eXBlICE9IG51bGwgJiYgcmVzLnR5cGUuaGFzVGFnKEZPUkFMTCkgfHwKICAgICAgICAgICAgICAgIChyZXMuZmxhZ3MoKSAmIEZsYWdzLlZBUkFSR1MpICE9IDAgfHwKICAgICAgICAgICAgICAgIChUcmVlSW5mby5pc1N0YXRpY1NlbGVjdG9yKGV4cHJUcmVlLCB0cmVlLm5hbWUudGFibGUubmFtZXMpICYmCiAgICAgICAgICAgICAgICBleHByVHJlZS50eXBlLmlzUmF3KCkgJiYgIWV4cHJUcmVlLnR5cGUuaGFzVGFnKEFSUkFZKSkpIHsKICAgICAgICAgICAgdHJlZS5vdmVybG9hZEtpbmQgPSBKQ01lbWJlclJlZmVyZW5jZS5PdmVybG9hZEtpbmQuT1ZFUkxPQURFRDsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB0cmVlLm92ZXJsb2FkS2luZCA9IEpDTWVtYmVyUmVmZXJlbmNlLk92ZXJsb2FkS2luZC5VTk9WRVJMT0FERUQ7CiAgICAgICAgfQogICAgICAgIC8vcmV0dXJuIGEgcGxhaW4gb2xkIGRlZmVycmVkIHR5cGUgZm9yIHRoaXMKICAgICAgICBzZXRSZXN1bHQodHJlZSwgZGVmZXJyZWRBdHRyLm5ldyBEZWZlcnJlZFR5cGUodHJlZSwgZW52KSk7CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB2aXNpdExhbWJkYShKQ0xhbWJkYSB0aGF0KSB7CiAgICAgICAgaWYgKHRoYXQucGFyYW1LaW5kID09IFBhcmFtZXRlcktpbmQuRVhQTElDSVQpIHsKICAgICAgICAgICAgLy9pZiBsYW1iZGEgaXMgZXhwbGljaXQsIHdlIGNhbiBzYXZlIGluZm8gaW4gdGhlIGNvcnJlc3BvbmRpbmcgYXJndW1lbnQgdHlwZQogICAgICAgICAgICBwcm9jZXNzQXJnKHRoYXQsICgpIC0+IHsKICAgICAgICAgICAgICAgIEpDTGFtYmRhIHNwZWN1bGF0aXZlTGFtYmRhID0KICAgICAgICAgICAgICAgICAgICAgICAgZGVmZXJyZWRBdHRyLmF0dHJpYlNwZWN1bGF0aXZlTGFtYmRhKHRoYXQsIGVudiwgYXR0ci5tZXRob2RBdHRySW5mbyk7CiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEV4cGxpY2l0TGFtYmRhVHlwZSh0aGF0LCBlbnYsIHNwZWN1bGF0aXZlTGFtYmRhKTsKICAgICAgICAgICAgfSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLy9vdGhlcndpc2UganVzdCB1c2UgYSBkZWZlcnJlZCB0eXBlCiAgICAgICAgICAgIHNldFJlc3VsdCh0aGF0LCBkZWZlcnJlZEF0dHIubmV3IERlZmVycmVkVHlwZSh0aGF0LCBlbnYpKTsKICAgICAgICB9CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB2aXNpdEFwcGx5KEpDTWV0aG9kSW52b2NhdGlvbiB0aGF0KSB7CiAgICAgICAgaWYgKHRoYXQuZ2V0VHlwZUFyZ3VtZW50cygpLmlzRW1wdHkoKSkgewogICAgICAgICAgICBwcm9jZXNzQXJnKHRoYXQsIHNwZWN1bGF0aXZlVHJlZSAtPiBuZXcgUmVzb2x2ZWRNZXRob2RUeXBlKHRoYXQsIGVudiwgc3BlY3VsYXRpdmVUcmVlKSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLy9ub3QgYSBwb2x5IGV4cHJlc3Npb24sIGp1c3QgY2FsbCBBdHRyCiAgICAgICAgICAgIHNldFJlc3VsdCh0aGF0LCBhdHRyLmF0dHJpYlRyZWUodGhhdCwgZW52LCBhdHRyLnVua25vd25FeHBySW5mbykpOwogICAgICAgIH0KICAgIH0KCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHZpc2l0TmV3Q2xhc3MoSkNOZXdDbGFzcyB0aGF0KSB7CiAgICAgICAgaWYgKFRyZWVJbmZvLmlzRGlhbW9uZCh0aGF0KSkgewogICAgICAgICAgICBwcm9jZXNzQXJnKHRoYXQsIHNwZWN1bGF0aXZlVHJlZSAtPiBuZXcgUmVzb2x2ZWRDb25zdHJ1Y3RvclR5cGUodGhhdCwgZW52LCBzcGVjdWxhdGl2ZVRyZWUpKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvL25vdCBhIHBvbHkgZXhwcmVzc2lvbiwganVzdCBjYWxsIEF0dHIKICAgICAgICAgICAgc2V0UmVzdWx0KHRoYXQsIGF0dHIuYXR0cmliVHJlZSh0aGF0LCBlbnYsIGF0dHIudW5rbm93bkV4cHJJbmZvKSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQW4gYXJndW1lbnQgdHlwZSBpcyBzaW1pbGFyIHRvIGEgcGxhaW4gZGVmZXJyZWQgdHlwZTsgdGhlIG1vc3QgaW1wb3J0YW50IGRpZmZlcmVuY2UgaXMgdGhhdAogICAgICogdGhlIGNvbXBsZXRpb24gbG9naWMgYXNzb2NpYXRlZCB3aXRoIGFyZ3VtZW50IHR5cGVzIGFsbG93cyBzcGVjdWxhdGl2ZSBhdHRyaWJ1dGlvbiB0byBiZSBza2lwcGVkCiAgICAgKiBkdXJpbmcgb3ZlcmxvYWQgcmVzb2x1dGlvbiAtIHRoYXQgaXMsIGFuIGFyZ3VtZW50IHR5cGUgYWx3YXlzIGhhcyBlbm91Z2ggaW5mb3JtYXRpb24gdG8KICAgICAqIHBlcmZvcm0gYW4gb3ZlcmxvYWQgY2hlY2sgd2l0aG91dCB0aGUgbmVlZCBvZiBjYWxsaW5nIGJhY2sgdG8gQXR0ci4gVGhpcyBleHRyYSBpbmZvcm1hdGlvbgogICAgICogaXMgdHlwaWNhbGx5IHN0b3JlZCBpbiB0aGUgZm9ybSBvZiBhIHNwZWN1bGF0aXZlIHRyZWUuCiAgICAgKi8KICAgIGFic3RyYWN0IGNsYXNzIEFyZ3VtZW50VHlwZTxUIGV4dGVuZHMgSkNFeHByZXNzaW9uPiBleHRlbmRzIERlZmVycmVkVHlwZSBpbXBsZW1lbnRzIERlZmVycmVkVHlwZUNvbXBsZXRlciB7CgogICAgICAgIC8qKiBUaGUgc3BlY3VsYXRpdmUgdHJlZSBjYXJyeWluZyB0eXBlIGluZm9ybWF0aW9uLiAqLwogICAgICAgIFQgc3BlY3VsYXRpdmVUcmVlOwoKICAgICAgICAvKiogVHlwZXMgYXNzb2NpYXRlZCB3aXRoIHRoaXMgYXJndW1lbnQgKG9uZSB0eXBlIHBlciBwb3NzaWJsZSB0YXJnZXQgcmVzdWx0KS4gKi8KICAgICAgICBNYXA8UmVzdWx0SW5mbywgVHlwZT4gc3BlY3VsYXRpdmVUeXBlczsKCiAgICAgICAgcHVibGljIEFyZ3VtZW50VHlwZShKQ0V4cHJlc3Npb24gdHJlZSwgRW52PEF0dHJDb250ZXh0PiBlbnYsIFQgc3BlY3VsYXRpdmVUcmVlLCBNYXA8UmVzdWx0SW5mbywgVHlwZT4gc3BlY3VsYXRpdmVUeXBlcykgewogICAgICAgICAgICBkZWZlcnJlZEF0dHIuc3VwZXIodHJlZSwgZW52KTsKICAgICAgICAgICAgdGhpcy5zcGVjdWxhdGl2ZVRyZWUgPSBzcGVjdWxhdGl2ZVRyZWU7CiAgICAgICAgICAgIHRoaXMuc3BlY3VsYXRpdmVUeXBlcyA9IHNwZWN1bGF0aXZlVHlwZXM7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBmaW5hbCBEZWZlcnJlZFR5cGVDb21wbGV0ZXIgY29tcGxldGVyKCkgewogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIGZpbmFsIHB1YmxpYyBUeXBlIGNvbXBsZXRlKERlZmVycmVkVHlwZSBkdCwgUmVzdWx0SW5mbyByZXN1bHRJbmZvLCBEZWZlcnJlZEF0dHJDb250ZXh0IGRlZmVycmVkQXR0ckNvbnRleHQpIHsKICAgICAgICAgICAgQXNzZXJ0LmNoZWNrKGR0ID09IHRoaXMpOwogICAgICAgICAgICBpZiAoZGVmZXJyZWRBdHRyQ29udGV4dC5tb2RlID09IEF0dHJNb2RlLlNQRUNVTEFUSVZFKSB7CiAgICAgICAgICAgICAgICBUeXBlIHQgPSAocmVzdWx0SW5mby5wdCA9PSBUeXBlLnJlY292ZXJ5VHlwZSkgPwogICAgICAgICAgICAgICAgICAgICAgICBkZWZlcnJlZEF0dHIuYmFzaWNDb21wbGV0ZXIuY29tcGxldGUoZHQsIHJlc3VsdEluZm8sIGRlZmVycmVkQXR0ckNvbnRleHQpIDoKICAgICAgICAgICAgICAgICAgICAgICAgb3ZlcmxvYWRDaGVjayhyZXN1bHRJbmZvLCBkZWZlcnJlZEF0dHJDb250ZXh0KTsKICAgICAgICAgICAgICAgIHNwZWN1bGF0aXZlVHlwZXMucHV0KHJlc3VsdEluZm8sIHQpOwogICAgICAgICAgICAgICAgcmV0dXJuIHQ7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBpZiAoIWVudi5pbmZvLmlzU3BlY3VsYXRpdmUpIHsKICAgICAgICAgICAgICAgICAgICBhcmd1bWVudFR5cGVDYWNoZS5yZW1vdmUobmV3IFVuaXF1ZVBvcyhkdC50cmVlKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gZGVmZXJyZWRBdHRyLmJhc2ljQ29tcGxldGVyLmNvbXBsZXRlKGR0LCByZXN1bHRJbmZvLCBkZWZlcnJlZEF0dHJDb250ZXh0KTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgVHlwZSBzcGVjdWxhdGl2ZVR5cGUoU3ltYm9sIG1zeW0sIE1ldGhvZFJlc29sdXRpb25QaGFzZSBwaGFzZSkgewogICAgICAgICAgICBpZiAocGVydGluZW50VG9BcHBsaWNhYmlsaXR5KSB7CiAgICAgICAgICAgICAgICBmb3IgKE1hcC5FbnRyeTxSZXN1bHRJbmZvLCBUeXBlPiBfZW50cnkgOiBzcGVjdWxhdGl2ZVR5cGVzLmVudHJ5U2V0KCkpIHsKICAgICAgICAgICAgICAgICAgICBEZWZlcnJlZEF0dHJDb250ZXh0IGRlZmVycmVkQXR0ckNvbnRleHQgPSBfZW50cnkuZ2V0S2V5KCkuY2hlY2tDb250ZXh0LmRlZmVycmVkQXR0ckNvbnRleHQoKTsKICAgICAgICAgICAgICAgICAgICBpZiAoZGVmZXJyZWRBdHRyQ29udGV4dC5waGFzZSA9PSBwaGFzZSAmJiBkZWZlcnJlZEF0dHJDb250ZXh0Lm1zeW0gPT0gbXN5bSkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gX2VudHJ5LmdldFZhbHVlKCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIFR5cGUubm9UeXBlOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcmV0dXJuIHN1cGVyLnNwZWN1bGF0aXZlVHlwZShtc3ltLCBwaGFzZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIEpDVHJlZSBzcGVjdWxhdGl2ZVRyZWUoRGVmZXJyZWRBdHRyQ29udGV4dCBkZWZlcnJlZEF0dHJDb250ZXh0KSB7CiAgICAgICAgICAgIHJldHVybiBwZXJ0aW5lbnRUb0FwcGxpY2FiaWxpdHkgPyBzcGVjdWxhdGl2ZVRyZWUgOiBzdXBlci5zcGVjdWxhdGl2ZVRyZWUoZGVmZXJyZWRBdHRyQ29udGV4dCk7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBQZXJmb3JtcyBhbiBvdmVybG9hZCBjaGVjayBhZ2FpbnN0IGEgZ2l2ZW4gdGFyZ2V0IHJlc3VsdC4KICAgICAgICAgKi8KICAgICAgICBhYnN0cmFjdCBUeXBlIG92ZXJsb2FkQ2hlY2soUmVzdWx0SW5mbyByZXN1bHRJbmZvLCBEZWZlcnJlZEF0dHJDb250ZXh0IGRlZmVycmVkQXR0ckNvbnRleHQpOwoKICAgICAgICAvKioKICAgICAgICAgKiBDcmVhdGVzIGEgY29weSBvZiB0aGlzIGFyZ3VtZW50IHR5cGUgd2l0aCBnaXZlbiB0cmVlIGFuZCBlbnZpcm9ubWVudC4KICAgICAgICAgKi8KICAgICAgICBhYnN0cmFjdCBBcmd1bWVudFR5cGU8VD4gZHVwKFQgdHJlZSwgRW52PEF0dHJDb250ZXh0PiBlbnYpOwogICAgfQoKICAgIC8qKgogICAgICogQXJndW1lbnQgdHlwZSBmb3IgcGFyZW50aGVzaXplZCBleHByZXNzaW9uLgogICAgICovCiAgICBjbGFzcyBQYXJlbnNUeXBlIGV4dGVuZHMgQXJndW1lbnRUeXBlPEpDUGFyZW5zPiB7CiAgICAgICAgUGFyZW5zVHlwZShKQ0V4cHJlc3Npb24gdHJlZSwgRW52PEF0dHJDb250ZXh0PiBlbnYsIEpDUGFyZW5zIHNwZWN1bGF0aXZlUGFyZW5zKSB7CiAgICAgICAgICAgIHRoaXModHJlZSwgZW52LCBzcGVjdWxhdGl2ZVBhcmVucywgbmV3IEhhc2hNYXA8PigpKTsKICAgICAgICB9CgogICAgICAgIFBhcmVuc1R5cGUoSkNFeHByZXNzaW9uIHRyZWUsIEVudjxBdHRyQ29udGV4dD4gZW52LCBKQ1BhcmVucyBzcGVjdWxhdGl2ZVBhcmVucywgTWFwPFJlc3VsdEluZm8sIFR5cGU+IHNwZWN1bGF0aXZlVHlwZXMpIHsKICAgICAgICAgICBzdXBlcih0cmVlLCBlbnYsIHNwZWN1bGF0aXZlUGFyZW5zLCBzcGVjdWxhdGl2ZVR5cGVzKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIFR5cGUgb3ZlcmxvYWRDaGVjayhSZXN1bHRJbmZvIHJlc3VsdEluZm8sIERlZmVycmVkQXR0ckNvbnRleHQgZGVmZXJyZWRBdHRyQ29udGV4dCkgewogICAgICAgICAgICByZXR1cm4gY2hlY2tTcGVjdWxhdGl2ZShzcGVjdWxhdGl2ZVRyZWUuZXhwciwgcmVzdWx0SW5mbyk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBBcmd1bWVudFR5cGU8SkNQYXJlbnM+IGR1cChKQ1BhcmVucyB0cmVlLCBFbnY8QXR0ckNvbnRleHQ+IGVudikgewogICAgICAgICAgICByZXR1cm4gbmV3IFBhcmVuc1R5cGUodHJlZSwgZW52LCBzcGVjdWxhdGl2ZVRyZWUsIHNwZWN1bGF0aXZlVHlwZXMpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEFyZ3VtZW50IHR5cGUgZm9yIGNvbmRpdGlvbmFscy4KICAgICAqLwogICAgY2xhc3MgQ29uZGl0aW9uYWxUeXBlIGV4dGVuZHMgQXJndW1lbnRUeXBlPEpDQ29uZGl0aW9uYWw+IHsKICAgICAgICBDb25kaXRpb25hbFR5cGUoSkNFeHByZXNzaW9uIHRyZWUsIEVudjxBdHRyQ29udGV4dD4gZW52LCBKQ0NvbmRpdGlvbmFsIHNwZWN1bGF0aXZlQ29uZCkgewogICAgICAgICAgICB0aGlzKHRyZWUsIGVudiwgc3BlY3VsYXRpdmVDb25kLCBuZXcgSGFzaE1hcDw+KCkpOwogICAgICAgIH0KCiAgICAgICAgQ29uZGl0aW9uYWxUeXBlKEpDRXhwcmVzc2lvbiB0cmVlLCBFbnY8QXR0ckNvbnRleHQ+IGVudiwgSkNDb25kaXRpb25hbCBzcGVjdWxhdGl2ZUNvbmQsIE1hcDxSZXN1bHRJbmZvLCBUeXBlPiBzcGVjdWxhdGl2ZVR5cGVzKSB7CiAgICAgICAgICAgc3VwZXIodHJlZSwgZW52LCBzcGVjdWxhdGl2ZUNvbmQsIHNwZWN1bGF0aXZlVHlwZXMpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgVHlwZSBvdmVybG9hZENoZWNrKFJlc3VsdEluZm8gcmVzdWx0SW5mbywgRGVmZXJyZWRBdHRyQ29udGV4dCBkZWZlcnJlZEF0dHJDb250ZXh0KSB7CiAgICAgICAgICAgIFJlc3VsdEluZm8gbG9jYWxJbmZvID0gcmVzdWx0SW5mby5kdXAoYXR0ci5jb25kaXRpb25hbENvbnRleHQocmVzdWx0SW5mby5jaGVja0NvbnRleHQpKTsKICAgICAgICAgICAgaWYgKHNwZWN1bGF0aXZlVHJlZS5pc1N0YW5kYWxvbmUoKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGxvY2FsSW5mby5jaGVjayhzcGVjdWxhdGl2ZVRyZWUsIHNwZWN1bGF0aXZlVHJlZS50eXBlKTsKICAgICAgICAgICAgfSBlbHNlIGlmIChyZXN1bHRJbmZvLnB0Lmhhc1RhZyhWT0lEKSkgewogICAgICAgICAgICAgICAgLy90aGlzIG1lYW5zIHdlIGFyZSByZXR1cm5pbmcgYSBwb2x5IGNvbmRpdGlvbmFsIGZyb20gdm9pZC1jb21wYXRpYmxlIGxhbWJkYSBleHByZXNzaW9uCiAgICAgICAgICAgICAgICByZXN1bHRJbmZvLmNoZWNrQ29udGV4dC5yZXBvcnQodHJlZSwgYXR0ci5kaWFncy5mcmFnbWVudCgiY29uZGl0aW9uYWwudGFyZ2V0LmNhbnQuYmUudm9pZCIpKTsKICAgICAgICAgICAgICAgIHJldHVybiBhdHRyLnR5cGVzLmNyZWF0ZUVycm9yVHlwZShyZXN1bHRJbmZvLnB0KTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIC8vcG9seQogICAgICAgICAgICAgICAgY2hlY2tTcGVjdWxhdGl2ZShzcGVjdWxhdGl2ZVRyZWUudHJ1ZXBhcnQsIGxvY2FsSW5mbyk7CiAgICAgICAgICAgICAgICBjaGVja1NwZWN1bGF0aXZlKHNwZWN1bGF0aXZlVHJlZS5mYWxzZXBhcnQsIGxvY2FsSW5mbyk7CiAgICAgICAgICAgICAgICByZXR1cm4gbG9jYWxJbmZvLnB0OwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBBcmd1bWVudFR5cGU8SkNDb25kaXRpb25hbD4gZHVwKEpDQ29uZGl0aW9uYWwgdHJlZSwgRW52PEF0dHJDb250ZXh0PiBlbnYpIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyBDb25kaXRpb25hbFR5cGUodHJlZSwgZW52LCBzcGVjdWxhdGl2ZVRyZWUsIHNwZWN1bGF0aXZlVHlwZXMpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEFyZ3VtZW50IHR5cGUgZm9yIGV4cGxpY2l0IGxhbWJkYXMuCiAgICAgKi8KICAgIGNsYXNzIEV4cGxpY2l0TGFtYmRhVHlwZSBleHRlbmRzIEFyZ3VtZW50VHlwZTxKQ0xhbWJkYT4gewoKICAgICAgICAvKiogTGlzdCBvZiBhcmd1bWVudCB0eXBlcyAobGF6aWx5IHBvcHVsYXRlZCkuICovCiAgICAgICAgT3B0aW9uYWw8TGlzdDxUeXBlPj4gYXJndHlwZXMgPSBPcHRpb25hbC5lbXB0eSgpOwoKICAgICAgICAvKiogTGlzdCBvZiByZXR1cm4gZXhwcmVzc2lvbnMgKGxhemlseSBwb3B1bGF0ZWQpLiAqLwogICAgICAgIE9wdGlvbmFsPExpc3Q8SkNSZXR1cm4+PiByZXR1cm5FeHByZXNzaW9ucyA9IE9wdGlvbmFsLmVtcHR5KCk7CgogICAgICAgIEV4cGxpY2l0TGFtYmRhVHlwZShKQ0xhbWJkYSBvcmlnaW5hbExhbWJkYSwgRW52PEF0dHJDb250ZXh0PiBlbnYsIEpDTGFtYmRhIHNwZWN1bGF0aXZlTGFtYmRhKSB7CiAgICAgICAgICAgIHRoaXMob3JpZ2luYWxMYW1iZGEsIGVudiwgc3BlY3VsYXRpdmVMYW1iZGEsIG5ldyBIYXNoTWFwPD4oKSk7CiAgICAgICAgfQoKICAgICAgICBFeHBsaWNpdExhbWJkYVR5cGUoSkNMYW1iZGEgb3JpZ2luYWxMYW1iZGEsIEVudjxBdHRyQ29udGV4dD4gZW52LCBKQ0xhbWJkYSBzcGVjdWxhdGl2ZUxhbWJkYSwgTWFwPFJlc3VsdEluZm8sIFR5cGU+IHNwZWN1bGF0aXZlVHlwZXMpIHsKICAgICAgICAgICAgc3VwZXIob3JpZ2luYWxMYW1iZGEsIGVudiwgc3BlY3VsYXRpdmVMYW1iZGEsIHNwZWN1bGF0aXZlVHlwZXMpOwogICAgICAgIH0KCiAgICAgICAgLyoqIENvbXB1dGUgYXJndW1lbnQgdHlwZXMgKGlmIG5lZWRlZCkuICovCiAgICAgICAgTGlzdDxUeXBlPiBhcmd0eXBlcygpIHsKICAgICAgICAgICAgcmV0dXJuIGFyZ3R5cGVzLm9yRWxzZUdldCgoKSAtPiB7CiAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IHJlcyA9IFRyZWVJbmZvLnR5cGVzKHNwZWN1bGF0aXZlVHJlZS5wYXJhbXMpOwogICAgICAgICAgICAgICAgYXJndHlwZXMgPSBPcHRpb25hbC5vZihyZXMpOwogICAgICAgICAgICAgICAgcmV0dXJuIHJlczsKICAgICAgICAgICAgfSk7CiAgICAgICAgfQoKICAgICAgICAvKiogQ29tcHV0ZSByZXR1cm4gZXhwcmVzc2lvbnMgKGlmIG5lZWRlZCkuICovCiAgICAgICAgTGlzdDxKQ1JldHVybj4gcmV0dXJuRXhwcmVzc2lvbnMoKSB7CiAgICAgICAgICAgIHJldHVybiByZXR1cm5FeHByZXNzaW9ucy5vckVsc2VHZXQoKCkgLT4gewogICAgICAgICAgICAgICAgZmluYWwgTGlzdDxKQ1JldHVybj4gcmVzOwogICAgICAgICAgICAgICAgaWYgKHNwZWN1bGF0aXZlVHJlZS5nZXRCb2R5S2luZCgpID09IEJvZHlLaW5kLkVYUFJFU1NJT04pIHsKICAgICAgICAgICAgICAgICAgICByZXMgPSBMaXN0Lm9mKGF0dHIubWFrZS5SZXR1cm4oKEpDRXhwcmVzc2lvbilzcGVjdWxhdGl2ZVRyZWUuYm9keSkpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBMaXN0QnVmZmVyPEpDUmV0dXJuPiByZXR1cm5FeHByZXNzaW9ucyA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICAgICAgICAgICAgICBuZXcgTGFtYmRhUmV0dXJuU2Nhbm5lcigpIHsKICAgICAgICAgICAgICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgICAgICAgICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0UmV0dXJuKEpDUmV0dXJuIHRyZWUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybkV4cHJlc3Npb25zLmFkZCh0cmVlKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0uc2NhbihzcGVjdWxhdGl2ZVRyZWUuYm9keSk7CiAgICAgICAgICAgICAgICAgICAgcmVzID0gcmV0dXJuRXhwcmVzc2lvbnMudG9MaXN0KCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm5FeHByZXNzaW9ucyA9IE9wdGlvbmFsLm9mKHJlcyk7CiAgICAgICAgICAgICAgICByZXR1cm4gcmVzOwogICAgICAgICAgICB9KTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIFR5cGUgb3ZlcmxvYWRDaGVjayhSZXN1bHRJbmZvIHJlc3VsdEluZm8sIERlZmVycmVkQXR0ckNvbnRleHQgZGVmZXJyZWRBdHRyQ29udGV4dCkgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgLy9jb21wdXRlIHRhcmdldC10eXBlOyB0aGlzIGxvZ2ljIGNvdWxkIGJlIHNoYXJlZCB3aXRoIEF0dHIKICAgICAgICAgICAgICAgIFRhcmdldEluZm8gdGFyZ2V0SW5mbyA9IGF0dHIuZ2V0VGFyZ2V0SW5mbyhzcGVjdWxhdGl2ZVRyZWUsIHJlc3VsdEluZm8sIGFyZ3R5cGVzKCkpOwogICAgICAgICAgICAgICAgVHlwZSBsYW1iZGFUeXBlID0gdGFyZ2V0SW5mby5kZXNjcmlwdG9yOwogICAgICAgICAgICAgICAgVHlwZSBjdXJyZW50VGFyZ2V0ID0gdGFyZ2V0SW5mby50YXJnZXQ7CiAgICAgICAgICAgICAgICAvL2NoZWNrIGNvbXBhdGliaWxpdHkKICAgICAgICAgICAgICAgIGNoZWNrTGFtYmRhQ29tcGF0aWJsZShsYW1iZGFUeXBlLCByZXN1bHRJbmZvKTsKICAgICAgICAgICAgICAgIHJldHVybiBjdXJyZW50VGFyZ2V0OwogICAgICAgICAgICB9IGNhdGNoIChGdW5jdGlvbkRlc2NyaXB0b3JMb29rdXBFcnJvciBleCkgewogICAgICAgICAgICAgICAgcmVzdWx0SW5mby5jaGVja0NvbnRleHQucmVwb3J0KG51bGwsIGV4LmdldERpYWdub3N0aWMoKSk7CiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsgLy9jYW5ub3QgZ2V0IGhlcmUKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLyoqIENoZWNrIGxhbWJkYSBhZ2FpbnN0IGdpdmVuIHRhcmdldCByZXN1bHQgKi8KICAgICAgICBwcml2YXRlIHZvaWQgY2hlY2tMYW1iZGFDb21wYXRpYmxlKFR5cGUgZGVzY3JpcHRvciwgUmVzdWx0SW5mbyByZXN1bHRJbmZvKSB7CiAgICAgICAgICAgIENoZWNrQ29udGV4dCBjaGVja0NvbnRleHQgPSByZXN1bHRJbmZvLmNoZWNrQ29udGV4dDsKICAgICAgICAgICAgUmVzdWx0SW5mbyBib2R5UmVzdWx0SW5mbyA9IGF0dHIubGFtYmRhQm9keVJlc3VsdChzcGVjdWxhdGl2ZVRyZWUsIGRlc2NyaXB0b3IsIHJlc3VsdEluZm8pOwogICAgICAgICAgICBmb3IgKEpDUmV0dXJuIHJldCA6IHJldHVybkV4cHJlc3Npb25zKCkpIHsKICAgICAgICAgICAgICAgIFR5cGUgdCA9IGdldFJldHVyblR5cGUocmV0KTsKICAgICAgICAgICAgICAgIGlmIChzcGVjdWxhdGl2ZVRyZWUuZ2V0Qm9keUtpbmQoKSA9PSBCb2R5S2luZC5FWFBSRVNTSU9OIHx8ICF0Lmhhc1RhZyhWT0lEKSkgewogICAgICAgICAgICAgICAgICAgIGNoZWNrU3BlY3VsYXRpdmUocmV0LmV4cHIsIHQsIGJvZHlSZXN1bHRJbmZvKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgYXR0ci5jaGVja0xhbWJkYUNvbXBhdGlibGUoc3BlY3VsYXRpdmVUcmVlLCBkZXNjcmlwdG9yLCBjaGVja0NvbnRleHQpOwogICAgICAgIH0KCiAgICAgICAgLyoqIEdldCB0aGUgdHlwZSBhc3NvY2lhdGVkIHdpdGggZ2l2ZW4gcmV0dXJuIGV4cHJlc3Npb24uICovCiAgICAgICAgVHlwZSBnZXRSZXR1cm5UeXBlKEpDUmV0dXJuIHJldCkgewogICAgICAgICAgICBpZiAocmV0LmV4cHIgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHN5bXMudm9pZFR5cGU7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICByZXR1cm4gcmV0LmV4cHIudHlwZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgQXJndW1lbnRUeXBlPEpDTGFtYmRhPiBkdXAoSkNMYW1iZGEgdHJlZSwgRW52PEF0dHJDb250ZXh0PiBlbnYpIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyBFeHBsaWNpdExhbWJkYVR5cGUodHJlZSwgZW52LCBzcGVjdWxhdGl2ZVRyZWUsIHNwZWN1bGF0aXZlVHlwZXMpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEFyZ3VtZW50IHR5cGUgZm9yIG1ldGhvZHMvY29uc3RydWN0b3JzLgogICAgICovCiAgICBhYnN0cmFjdCBjbGFzcyBSZXNvbHZlZE1lbWJlclR5cGU8RSBleHRlbmRzIEpDRXhwcmVzc2lvbj4gZXh0ZW5kcyBBcmd1bWVudFR5cGU8RT4gewoKICAgICAgICBwdWJsaWMgUmVzb2x2ZWRNZW1iZXJUeXBlKEpDRXhwcmVzc2lvbiB0cmVlLCBFbnY8QXR0ckNvbnRleHQ+IGVudiwgRSBzcGVjdWxhdGl2ZU1ldGhvZCwgTWFwPFJlc3VsdEluZm8sIFR5cGU+IHNwZWN1bGF0aXZlVHlwZXMpIHsKICAgICAgICAgICAgc3VwZXIodHJlZSwgZW52LCBzcGVjdWxhdGl2ZU1ldGhvZCwgc3BlY3VsYXRpdmVUeXBlcyk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBUeXBlIG92ZXJsb2FkQ2hlY2soUmVzdWx0SW5mbyByZXN1bHRJbmZvLCBEZWZlcnJlZEF0dHJDb250ZXh0IGRlZmVycmVkQXR0ckNvbnRleHQpIHsKICAgICAgICAgICAgVHlwZSBtdHlwZSA9IG1ldGhvZFR5cGUoKTsKICAgICAgICAgICAgUmVzdWx0SW5mbyBsb2NhbEluZm8gPSByZXN1bHRJbmZvKHJlc3VsdEluZm8pOwogICAgICAgICAgICBpZiAobXR5cGUgIT0gbnVsbCAmJiBtdHlwZS5oYXNUYWcoTUVUSE9EKSAmJiBtdHlwZS5pc1BhcnRpYWwoKSkgewogICAgICAgICAgICAgICAgVHlwZSB0ID0gKChQYXJ0aWFsbHlJbmZlcnJlZE1ldGhvZFR5cGUpbXR5cGUpLmNoZWNrKGxvY2FsSW5mbyk7CiAgICAgICAgICAgICAgICBpZiAoIWRlZmVycmVkQXR0ckNvbnRleHQuaW5mZXJlbmNlQ29udGV4dC5mcmVlKGxvY2FsSW5mby5wdCkpIHsKICAgICAgICAgICAgICAgICAgICBzcGVjdWxhdGl2ZVR5cGVzLnB1dChsb2NhbEluZm8sIHQpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBsb2NhbEluZm8uY2hlY2sodHJlZS5wb3MoKSwgdCk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB0OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgVHlwZSB0ID0gbG9jYWxJbmZvLmNoZWNrKHRyZWUucG9zKCksIHNwZWN1bGF0aXZlVHJlZS50eXBlKTsKICAgICAgICAgICAgICAgIHNwZWN1bGF0aXZlVHlwZXMucHV0KGxvY2FsSW5mbywgdCk7CiAgICAgICAgICAgICAgICByZXR1cm4gdDsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogR2V0IHRoZSByZXN1bHQgaW5mbyB0byBiZSB1c2VkIGZvciBwZXJmb3JtaW5nIGFuIG92ZXJsb2FkIGNoZWNrLgogICAgICAgICAqLwogICAgICAgIGFic3RyYWN0IFJlc3VsdEluZm8gcmVzdWx0SW5mbyhSZXN1bHRJbmZvIHJlc3VsdEluZm8pOwoKICAgICAgICAvKioKICAgICAgICAgKiBHZXQgdGhlIG1ldGhvZCB0eXBlIHRvIGJlIHVzZWQgZm9yIHBlcmZvcm1pbmcgYW4gb3ZlcmxvYWQgY2hlY2suCiAgICAgICAgICovCiAgICAgICAgYWJzdHJhY3QgVHlwZSBtZXRob2RUeXBlKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBBcmd1bWVudCB0eXBlIGZvciBtZXRob2RzLgogICAgICovCiAgICBjbGFzcyBSZXNvbHZlZE1ldGhvZFR5cGUgZXh0ZW5kcyBSZXNvbHZlZE1lbWJlclR5cGU8SkNNZXRob2RJbnZvY2F0aW9uPiB7CgogICAgICAgIHB1YmxpYyBSZXNvbHZlZE1ldGhvZFR5cGUoSkNFeHByZXNzaW9uIHRyZWUsIEVudjxBdHRyQ29udGV4dD4gZW52LCBKQ01ldGhvZEludm9jYXRpb24gc3BlY3VsYXRpdmVUcmVlKSB7CiAgICAgICAgICAgIHRoaXModHJlZSwgZW52LCBzcGVjdWxhdGl2ZVRyZWUsIG5ldyBIYXNoTWFwPD4oKSk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgUmVzb2x2ZWRNZXRob2RUeXBlKEpDRXhwcmVzc2lvbiB0cmVlLCBFbnY8QXR0ckNvbnRleHQ+IGVudiwgSkNNZXRob2RJbnZvY2F0aW9uIHNwZWN1bGF0aXZlVHJlZSwgTWFwPFJlc3VsdEluZm8sIFR5cGU+IHNwZWN1bGF0aXZlVHlwZXMpIHsKICAgICAgICAgICAgc3VwZXIodHJlZSwgZW52LCBzcGVjdWxhdGl2ZVRyZWUsIHNwZWN1bGF0aXZlVHlwZXMpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgUmVzdWx0SW5mbyByZXN1bHRJbmZvKFJlc3VsdEluZm8gcmVzdWx0SW5mbykgewogICAgICAgICAgICByZXR1cm4gcmVzdWx0SW5mbzsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIFR5cGUgbWV0aG9kVHlwZSgpIHsKICAgICAgICAgICAgcmV0dXJuIHNwZWN1bGF0aXZlVHJlZS5tZXRoLnR5cGU7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBBcmd1bWVudFR5cGU8SkNNZXRob2RJbnZvY2F0aW9uPiBkdXAoSkNNZXRob2RJbnZvY2F0aW9uIHRyZWUsIEVudjxBdHRyQ29udGV4dD4gZW52KSB7CiAgICAgICAgICAgIHJldHVybiBuZXcgUmVzb2x2ZWRNZXRob2RUeXBlKHRyZWUsIGVudiwgc3BlY3VsYXRpdmVUcmVlLCBzcGVjdWxhdGl2ZVR5cGVzKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBBcmd1bWVudCB0eXBlIGZvciBjb25zdHJ1Y3RvcnMuCiAgICAgKi8KICAgIGNsYXNzIFJlc29sdmVkQ29uc3RydWN0b3JUeXBlIGV4dGVuZHMgUmVzb2x2ZWRNZW1iZXJUeXBlPEpDTmV3Q2xhc3M+IHsKCiAgICAgICAgcHVibGljIFJlc29sdmVkQ29uc3RydWN0b3JUeXBlKEpDRXhwcmVzc2lvbiB0cmVlLCBFbnY8QXR0ckNvbnRleHQ+IGVudiwgSkNOZXdDbGFzcyBzcGVjdWxhdGl2ZVRyZWUpIHsKICAgICAgICAgICAgdGhpcyh0cmVlLCBlbnYsIHNwZWN1bGF0aXZlVHJlZSwgbmV3IEhhc2hNYXA8PigpKTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBSZXNvbHZlZENvbnN0cnVjdG9yVHlwZShKQ0V4cHJlc3Npb24gdHJlZSwgRW52PEF0dHJDb250ZXh0PiBlbnYsIEpDTmV3Q2xhc3Mgc3BlY3VsYXRpdmVUcmVlLCBNYXA8UmVzdWx0SW5mbywgVHlwZT4gc3BlY3VsYXRpdmVUeXBlcykgewogICAgICAgICAgICBzdXBlcih0cmVlLCBlbnYsIHNwZWN1bGF0aXZlVHJlZSwgc3BlY3VsYXRpdmVUeXBlcyk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBSZXN1bHRJbmZvIHJlc3VsdEluZm8oUmVzdWx0SW5mbyByZXN1bHRJbmZvKSB7CiAgICAgICAgICAgIHJldHVybiByZXN1bHRJbmZvLmR1cChhdHRyLmRpYW1vbmRDb250ZXh0KHNwZWN1bGF0aXZlVHJlZSwgc3BlY3VsYXRpdmVUcmVlLmNsYXp6LnR5cGUudHN5bSwgcmVzdWx0SW5mby5jaGVja0NvbnRleHQpKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIFR5cGUgbWV0aG9kVHlwZSgpIHsKICAgICAgICAgICAgcmV0dXJuIChzcGVjdWxhdGl2ZVRyZWUuY29uc3RydWN0b3JUeXBlICE9IG51bGwpID8KICAgICAgICAgICAgICAgICAgICBzcGVjdWxhdGl2ZVRyZWUuY29uc3RydWN0b3JUeXBlLmJhc2VUeXBlKCkgOiBzeW1zLmVyclR5cGU7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBBcmd1bWVudFR5cGU8SkNOZXdDbGFzcz4gZHVwKEpDTmV3Q2xhc3MgdHJlZSwgRW52PEF0dHJDb250ZXh0PiBlbnYpIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyBSZXNvbHZlZENvbnN0cnVjdG9yVHlwZSh0cmVlLCBlbnYsIHNwZWN1bGF0aXZlVHJlZSwgc3BlY3VsYXRpdmVUeXBlcyk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQW4gaW5zdGFuY2Ugb2YgdGhpcyBjbGFzcyByZXByZXNlbnRzIGEgdW5pcXVlIHBvc2l0aW9uIGluIGEgY29tcGlsYXRpb24gdW5pdC4gQSB1bmlxdWUKICAgICAqIHBvc2l0aW9uIGlzIG1hZGUgdXAgb2YgKGkpIGEgdW5pcXVlIHBvc2l0aW9uIGluIGEgc291cmNlIGZpbGUgKGNoYXIgb2Zmc2V0KSBhbmQgKGlpKQogICAgICogYSBzb3VyY2UgZmlsZSBpbmZvLgogICAgICovCiAgICBjbGFzcyBVbmlxdWVQb3MgewoKICAgICAgICAvKiogQ2hhciBvZmZzZXQuICovCiAgICAgICAgaW50IHBvczsKCiAgICAgICAgLyoqIFNvdXJjZSBpbmZvLiAqLwogICAgICAgIERpYWdub3N0aWNTb3VyY2Ugc291cmNlOwoKICAgICAgICBVbmlxdWVQb3MoSkNUcmVlIHRyZWUpIHsKICAgICAgICAgICAgdGhpcy5wb3MgPSB0cmVlLnBvczsKICAgICAgICAgICAgdGhpcy5zb3VyY2UgPSBsb2cuY3VycmVudFNvdXJjZSgpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgICAgICAgcmV0dXJuIHBvcyA8PCAxNiArIHNvdXJjZS5oYXNoQ29kZSgpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmopIHsKICAgICAgICAgICAgaWYgKG9iaiBpbnN0YW5jZW9mIFVuaXF1ZVBvcykgewogICAgICAgICAgICAgICAgVW5pcXVlUG9zIHRoYXQgPSAoVW5pcXVlUG9zKW9iajsKICAgICAgICAgICAgICAgIHJldHVybiBwb3MgPT0gdGhhdC5wb3MgJiYgc291cmNlID09IHRoYXQuc291cmNlOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewogICAgICAgICAgICByZXR1cm4gc291cmNlLmdldEZpbGUoKS5nZXROYW1lKCkgKyAiIEAgIiArIHNvdXJjZS5nZXRMaW5lTnVtYmVyKHBvcyk7CiAgICAgICAgfQogICAgfQp9ClBLAwQKAAAIAAAGO6lK3/72DW0+AABtPgAAJwAAAGNvbS9zdW4vdG9vbHMvamF2YWMvY29tcC9Db25zdEZvbGQuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMTk5OSwgMjAxMywgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLmphdmFjLmNvbXA7CgppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLio7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmp2bS4qOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLio7CgppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5UeXBlVGFnLkJPT0xFQU47CgppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMuanZtLkJ5dGVDb2Rlcy4qOwoKLyoqIEhlbHBlciBjbGFzcyBmb3IgY29uc3RhbnQgZm9sZGluZywgdXNlZCBieSB0aGUgYXR0cmlidXRpb24gcGhhc2UuCiAqICBUaGlzIGNsYXNzIGlzIG1hcmtlZCBzdHJpY3RmcCBhcyBtYW5kYXRlZCBieSBKTFMgMTUuNC4KICoKICogIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqICBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqICBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogKiAgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPgogKi8Kc3RyaWN0ZnAgY2xhc3MgQ29uc3RGb2xkIHsKICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgQ29udGV4dC5LZXk8Q29uc3RGb2xkPiBjb25zdEZvbGRLZXkgPSBuZXcgQ29udGV4dC5LZXk8PigpOwoKICAgIHByaXZhdGUgU3ltdGFiIHN5bXM7CgogICAgcHVibGljIHN0YXRpYyBDb25zdEZvbGQgaW5zdGFuY2UoQ29udGV4dCBjb250ZXh0KSB7CiAgICAgICAgQ29uc3RGb2xkIGluc3RhbmNlID0gY29udGV4dC5nZXQoY29uc3RGb2xkS2V5KTsKICAgICAgICBpZiAoaW5zdGFuY2UgPT0gbnVsbCkKICAgICAgICAgICAgaW5zdGFuY2UgPSBuZXcgQ29uc3RGb2xkKGNvbnRleHQpOwogICAgICAgIHJldHVybiBpbnN0YW5jZTsKICAgIH0KCiAgICBwcml2YXRlIENvbnN0Rm9sZChDb250ZXh0IGNvbnRleHQpIHsKICAgICAgICBjb250ZXh0LnB1dChjb25zdEZvbGRLZXksIHRoaXMpOwoKICAgICAgICBzeW1zID0gU3ltdGFiLmluc3RhbmNlKGNvbnRleHQpOwogICAgfQoKICAgIHN0YXRpYyBmaW5hbCBJbnRlZ2VyIG1pbnVzT25lID0gLTE7CiAgICBzdGF0aWMgZmluYWwgSW50ZWdlciB6ZXJvICAgICA9IDA7CiAgICBzdGF0aWMgZmluYWwgSW50ZWdlciBvbmUgICAgICA9IDE7CgogICAvKiogQ29udmVydCBib29sZWFuIHRvIGludGVnZXIgKHRydWUgPSAxLCBmYWxzZSA9IDApLgogICAgKi8KICAgIHByaXZhdGUgc3RhdGljIEludGVnZXIgYjJpKGJvb2xlYW4gYikgewogICAgICAgIHJldHVybiBiID8gb25lIDogemVybzsKICAgIH0KICAgIHByaXZhdGUgc3RhdGljIGludCBpbnRWYWx1ZShPYmplY3QgeCkgeyByZXR1cm4gKChOdW1iZXIpeCkuaW50VmFsdWUoKTsgfQogICAgcHJpdmF0ZSBzdGF0aWMgbG9uZyBsb25nVmFsdWUoT2JqZWN0IHgpIHsgcmV0dXJuICgoTnVtYmVyKXgpLmxvbmdWYWx1ZSgpOyB9CiAgICBwcml2YXRlIHN0YXRpYyBmbG9hdCBmbG9hdFZhbHVlKE9iamVjdCB4KSB7IHJldHVybiAoKE51bWJlcil4KS5mbG9hdFZhbHVlKCk7IH0KICAgIHByaXZhdGUgc3RhdGljIGRvdWJsZSBkb3VibGVWYWx1ZShPYmplY3QgeCkgeyByZXR1cm4gKChOdW1iZXIpeCkuZG91YmxlVmFsdWUoKTsgfQoKICAgIC8qKiBGb2xkIGJpbmFyeSBvciB1bmFyeSBvcGVyYXRpb24sIHJldHVybmluZyBjb25zdGFudCB0eXBlIHJlZmxlY3RpbmcgdGhlCiAgICAgKiAgb3BlcmF0aW9ucyByZXN1bHQuIFJldHVybiBudWxsIGlmIGZvbGQgZmFpbGVkIGR1ZSB0byBhbgogICAgICogIGFyaXRobWV0aWMgZXhjZXB0aW9uLgogICAgICogIEBwYXJhbSBvcGNvZGUgICAgVGhlIG9wZXJhdGlvbidzIG9wY29kZSBpbnN0cnVjdGlvbiAodXN1YWxseSBhIGJ5dGUgY29kZSksCiAgICAgKiAgICAgICAgICAgICAgICAgICBhcyBlbnRlcmVkIGJ5IGNsYXNzIFN5bXRhYi4KICAgICAqICBAcGFyYW0gYXJndHlwZXMgIFRoZSBvcGVyYXRpb24ncyBhcmd1bWVudCB0eXBlcyAoYSBsaXN0IG9mIGxlbmd0aCAxIG9yIDIpLgogICAgICogICAgICAgICAgICAgICAgICAgQXJndW1lbnQgdHlwZXMgYXJlIGFzc3VtZWQgdG8gaGF2ZSBub24tbnVsbCBjb25zdFZhbHVlJ3MuCiAgICAgKi8KICAgIFR5cGUgZm9sZChpbnQgb3Bjb2RlLCBMaXN0PFR5cGU+IGFyZ3R5cGVzKSB7CiAgICAgICAgaW50IGFyZ0NvdW50ID0gYXJndHlwZXMubGVuZ3RoKCk7CiAgICAgICAgaWYgKGFyZ0NvdW50ID09IDEpCiAgICAgICAgICAgIHJldHVybiBmb2xkMShvcGNvZGUsIGFyZ3R5cGVzLmhlYWQpOwogICAgICAgIGVsc2UgaWYgKGFyZ0NvdW50ID09IDIpCiAgICAgICAgICAgIHJldHVybiBmb2xkMihvcGNvZGUsIGFyZ3R5cGVzLmhlYWQsIGFyZ3R5cGVzLnRhaWwuaGVhZCk7CiAgICAgICAgZWxzZQogICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoKTsKICAgIH0KCiAgICAvKiogRm9sZCB1bmFyeSBvcGVyYXRpb24uCiAgICAgKiAgQHBhcmFtIG9wY29kZSAgICBUaGUgb3BlcmF0aW9uJ3Mgb3Bjb2RlIGluc3RydWN0aW9uICh1c3VhbGx5IGEgYnl0ZSBjb2RlKSwKICAgICAqICAgICAgICAgICAgICAgICAgIGFzIGVudGVyZWQgYnkgY2xhc3MgU3ltdGFiLgogICAgICogICAgICAgICAgICAgICAgICAgb3Bjb2RlJ3MgaWZlcSB0byBpZmdlIGFyZSBmb3IgcG9zdHByb2Nlc3NpbmcKICAgICAqICAgICAgICAgICAgICAgICAgIHhjbXA7IGlmeHggcGFpcnMgb2YgaW5zdHJ1Y3Rpb25zLgogICAgICogIEBwYXJhbSBvcGVyYW5kICAgVGhlIG9wZXJhdGlvbidzIG9wZXJhbmQgdHlwZS4KICAgICAqICAgICAgICAgICAgICAgICAgIEFyZ3VtZW50IHR5cGVzIGFyZSBhc3N1bWVkIHRvIGhhdmUgbm9uLW51bGwgY29uc3RWYWx1ZSdzLgogICAgICovCiAgICBUeXBlIGZvbGQxKGludCBvcGNvZGUsIFR5cGUgb3BlcmFuZCkgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIE9iamVjdCBvZCA9IG9wZXJhbmQuY29uc3RWYWx1ZSgpOwogICAgICAgICAgICBzd2l0Y2ggKG9wY29kZSkgewogICAgICAgICAgICBjYXNlIG5vcDoKICAgICAgICAgICAgICAgIHJldHVybiBvcGVyYW5kOwogICAgICAgICAgICBjYXNlIGluZWc6IC8vIHVuYXJ5IC0KICAgICAgICAgICAgICAgIHJldHVybiBzeW1zLmludFR5cGUuY29uc3RUeXBlKC1pbnRWYWx1ZShvZCkpOwogICAgICAgICAgICBjYXNlIGl4b3I6IC8vIH4KICAgICAgICAgICAgICAgIHJldHVybiBzeW1zLmludFR5cGUuY29uc3RUeXBlKH5pbnRWYWx1ZShvZCkpOwogICAgICAgICAgICBjYXNlIGJvb2xfbm90OiAvLyAhCiAgICAgICAgICAgICAgICByZXR1cm4gc3ltcy5ib29sZWFuVHlwZS5jb25zdFR5cGUoYjJpKGludFZhbHVlKG9kKSA9PSAwKSk7CiAgICAgICAgICAgIGNhc2UgaWZlcToKICAgICAgICAgICAgICAgIHJldHVybiBzeW1zLmJvb2xlYW5UeXBlLmNvbnN0VHlwZShiMmkoaW50VmFsdWUob2QpID09IDApKTsKICAgICAgICAgICAgY2FzZSBpZm5lOgogICAgICAgICAgICAgICAgcmV0dXJuIHN5bXMuYm9vbGVhblR5cGUuY29uc3RUeXBlKGIyaShpbnRWYWx1ZShvZCkgIT0gMCkpOwogICAgICAgICAgICBjYXNlIGlmbHQ6CiAgICAgICAgICAgICAgICByZXR1cm4gc3ltcy5ib29sZWFuVHlwZS5jb25zdFR5cGUoYjJpKGludFZhbHVlKG9kKSA8IDApKTsKICAgICAgICAgICAgY2FzZSBpZmd0OgogICAgICAgICAgICAgICAgcmV0dXJuIHN5bXMuYm9vbGVhblR5cGUuY29uc3RUeXBlKGIyaShpbnRWYWx1ZShvZCkgPiAwKSk7CiAgICAgICAgICAgIGNhc2UgaWZsZToKICAgICAgICAgICAgICAgIHJldHVybiBzeW1zLmJvb2xlYW5UeXBlLmNvbnN0VHlwZShiMmkoaW50VmFsdWUob2QpIDw9IDApKTsKICAgICAgICAgICAgY2FzZSBpZmdlOgogICAgICAgICAgICAgICAgcmV0dXJuIHN5bXMuYm9vbGVhblR5cGUuY29uc3RUeXBlKGIyaShpbnRWYWx1ZShvZCkgPj0gMCkpOwoKICAgICAgICAgICAgY2FzZSBsbmVnOiAvLyB1bmFyeSAtCiAgICAgICAgICAgICAgICByZXR1cm4gc3ltcy5sb25nVHlwZS5jb25zdFR5cGUoTG9uZy52YWx1ZU9mKC1sb25nVmFsdWUob2QpKSk7CiAgICAgICAgICAgIGNhc2UgbHhvcjogLy8gfgogICAgICAgICAgICAgICAgcmV0dXJuIHN5bXMubG9uZ1R5cGUuY29uc3RUeXBlKExvbmcudmFsdWVPZih+bG9uZ1ZhbHVlKG9kKSkpOwoKICAgICAgICAgICAgY2FzZSBmbmVnOiAvLyB1bmFyeSAtCiAgICAgICAgICAgICAgICByZXR1cm4gc3ltcy5mbG9hdFR5cGUuY29uc3RUeXBlKEZsb2F0LnZhbHVlT2YoLWZsb2F0VmFsdWUob2QpKSk7CgogICAgICAgICAgICBjYXNlIGRuZWc6IC8vIH4KICAgICAgICAgICAgICAgIHJldHVybiBzeW1zLmRvdWJsZVR5cGUuY29uc3RUeXBlKERvdWJsZS52YWx1ZU9mKC1kb3VibGVWYWx1ZShvZCkpKTsKCiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgfQogICAgICAgIH0gY2F0Y2ggKEFyaXRobWV0aWNFeGNlcHRpb24gZSkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICB9CgogICAgLyoqIEZvbGQgYmluYXJ5IG9wZXJhdGlvbi4KICAgICAqICBAcGFyYW0gb3Bjb2RlICAgIFRoZSBvcGVyYXRpb24ncyBvcGNvZGUgaW5zdHJ1Y3Rpb24gKHVzdWFsbHkgYSBieXRlIGNvZGUpLAogICAgICogICAgICAgICAgICAgICAgICAgYXMgZW50ZXJlZCBieSBjbGFzcyBTeW10YWIuCiAgICAgKiAgICAgICAgICAgICAgICAgICBvcGNvZGUncyBpZmVxIHRvIGlmZ2UgYXJlIGZvciBwb3N0cHJvY2Vzc2luZwogICAgICogICAgICAgICAgICAgICAgICAgeGNtcDsgaWZ4eCBwYWlycyBvZiBpbnN0cnVjdGlvbnMuCiAgICAgKiAgQHBhcmFtIGxlZnQgICAgICBUaGUgdHlwZSBvZiB0aGUgb3BlcmF0aW9uJ3MgbGVmdCBvcGVyYW5kLgogICAgICogIEBwYXJhbSByaWdodCAgICAgVGhlIHR5cGUgb2YgdGhlIG9wZXJhdGlvbidzIHJpZ2h0IG9wZXJhbmQuCiAgICAgKi8KICAgIFR5cGUgZm9sZDIoaW50IG9wY29kZSwgVHlwZSBsZWZ0LCBUeXBlIHJpZ2h0KSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgaWYgKG9wY29kZSA+IEJ5dGVDb2Rlcy5wcmVNYXNrKSB7CiAgICAgICAgICAgICAgICAvLyB3ZSBhcmUgc2VlaW5nIGEgY29tcG9zaXRlIGluc3RydWN0aW9uIG9mIHRoZSBmb3JtIHhjbXA7IGlmeHguCiAgICAgICAgICAgICAgICAvLyBJbiB0aGlzIGNhc2UgZm9sZCBib3RoIGluc3RydWN0aW9ucyBzZXBhcmF0ZWx5LgogICAgICAgICAgICAgICAgVHlwZSB0MSA9IGZvbGQyKG9wY29kZSA+PiBCeXRlQ29kZXMucHJlU2hpZnQsIGxlZnQsIHJpZ2h0KTsKICAgICAgICAgICAgICAgIHJldHVybiAodDEuY29uc3RWYWx1ZSgpID09IG51bGwpID8gdDEKICAgICAgICAgICAgICAgICAgICA6IGZvbGQxKG9wY29kZSAmIEJ5dGVDb2Rlcy5wcmVNYXNrLCB0MSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBPYmplY3QgbCA9IGxlZnQuY29uc3RWYWx1ZSgpOwogICAgICAgICAgICAgICAgT2JqZWN0IHIgPSByaWdodC5jb25zdFZhbHVlKCk7CiAgICAgICAgICAgICAgICBzd2l0Y2ggKG9wY29kZSkgewogICAgICAgICAgICAgICAgY2FzZSBpYWRkOgogICAgICAgICAgICAgICAgICAgIHJldHVybiBzeW1zLmludFR5cGUuY29uc3RUeXBlKGludFZhbHVlKGwpICsgaW50VmFsdWUocikpOwogICAgICAgICAgICAgICAgY2FzZSBpc3ViOgogICAgICAgICAgICAgICAgICAgIHJldHVybiBzeW1zLmludFR5cGUuY29uc3RUeXBlKGludFZhbHVlKGwpIC0gaW50VmFsdWUocikpOwogICAgICAgICAgICAgICAgY2FzZSBpbXVsOgogICAgICAgICAgICAgICAgICAgIHJldHVybiBzeW1zLmludFR5cGUuY29uc3RUeXBlKGludFZhbHVlKGwpICogaW50VmFsdWUocikpOwogICAgICAgICAgICAgICAgY2FzZSBpZGl2OgogICAgICAgICAgICAgICAgICAgIHJldHVybiBzeW1zLmludFR5cGUuY29uc3RUeXBlKGludFZhbHVlKGwpIC8gaW50VmFsdWUocikpOwogICAgICAgICAgICAgICAgY2FzZSBpbW9kOgogICAgICAgICAgICAgICAgICAgIHJldHVybiBzeW1zLmludFR5cGUuY29uc3RUeXBlKGludFZhbHVlKGwpICUgaW50VmFsdWUocikpOwogICAgICAgICAgICAgICAgY2FzZSBpYW5kOgogICAgICAgICAgICAgICAgICAgIHJldHVybiAobGVmdC5oYXNUYWcoQk9PTEVBTikKICAgICAgICAgICAgICAgICAgICAgID8gc3ltcy5ib29sZWFuVHlwZSA6IHN5bXMuaW50VHlwZSkKICAgICAgICAgICAgICAgICAgICAgIC5jb25zdFR5cGUoaW50VmFsdWUobCkgJiBpbnRWYWx1ZShyKSk7CiAgICAgICAgICAgICAgICBjYXNlIGJvb2xfYW5kOgogICAgICAgICAgICAgICAgICAgIHJldHVybiBzeW1zLmJvb2xlYW5UeXBlLmNvbnN0VHlwZShiMmkoKGludFZhbHVlKGwpICYgaW50VmFsdWUocikpICE9IDApKTsKICAgICAgICAgICAgICAgIGNhc2UgaW9yOgogICAgICAgICAgICAgICAgICAgIHJldHVybiAobGVmdC5oYXNUYWcoQk9PTEVBTikKICAgICAgICAgICAgICAgICAgICAgID8gc3ltcy5ib29sZWFuVHlwZSA6IHN5bXMuaW50VHlwZSkKICAgICAgICAgICAgICAgICAgICAgIC5jb25zdFR5cGUoaW50VmFsdWUobCkgfCBpbnRWYWx1ZShyKSk7CiAgICAgICAgICAgICAgICBjYXNlIGJvb2xfb3I6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHN5bXMuYm9vbGVhblR5cGUuY29uc3RUeXBlKGIyaSgoaW50VmFsdWUobCkgfCBpbnRWYWx1ZShyKSkgIT0gMCkpOwogICAgICAgICAgICAgICAgY2FzZSBpeG9yOgogICAgICAgICAgICAgICAgICAgIHJldHVybiAobGVmdC5oYXNUYWcoQk9PTEVBTikKICAgICAgICAgICAgICAgICAgICAgID8gc3ltcy5ib29sZWFuVHlwZSA6IHN5bXMuaW50VHlwZSkKICAgICAgICAgICAgICAgICAgICAgIC5jb25zdFR5cGUoaW50VmFsdWUobCkgXiBpbnRWYWx1ZShyKSk7CiAgICAgICAgICAgICAgICBjYXNlIGlzaGw6IGNhc2UgaXNobGw6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHN5bXMuaW50VHlwZS5jb25zdFR5cGUoaW50VmFsdWUobCkgPDwgaW50VmFsdWUocikpOwogICAgICAgICAgICAgICAgY2FzZSBpc2hyOiBjYXNlIGlzaHJsOgogICAgICAgICAgICAgICAgICAgIHJldHVybiBzeW1zLmludFR5cGUuY29uc3RUeXBlKGludFZhbHVlKGwpID4+IGludFZhbHVlKHIpKTsKICAgICAgICAgICAgICAgIGNhc2UgaXVzaHI6IGNhc2UgaXVzaHJsOgogICAgICAgICAgICAgICAgICAgIHJldHVybiBzeW1zLmludFR5cGUuY29uc3RUeXBlKGludFZhbHVlKGwpID4+PiBpbnRWYWx1ZShyKSk7CiAgICAgICAgICAgICAgICBjYXNlIGlmX2ljbXBlcToKICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3ltcy5ib29sZWFuVHlwZS5jb25zdFR5cGUoCiAgICAgICAgICAgICAgICAgICAgICAgIGIyaShpbnRWYWx1ZShsKSA9PSBpbnRWYWx1ZShyKSkpOwogICAgICAgICAgICAgICAgY2FzZSBpZl9pY21wbmU6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHN5bXMuYm9vbGVhblR5cGUuY29uc3RUeXBlKAogICAgICAgICAgICAgICAgICAgICAgICBiMmkoaW50VmFsdWUobCkgIT0gaW50VmFsdWUocikpKTsKICAgICAgICAgICAgICAgIGNhc2UgaWZfaWNtcGx0OgogICAgICAgICAgICAgICAgICAgIHJldHVybiBzeW1zLmJvb2xlYW5UeXBlLmNvbnN0VHlwZSgKICAgICAgICAgICAgICAgICAgICAgICAgYjJpKGludFZhbHVlKGwpIDwgaW50VmFsdWUocikpKTsKICAgICAgICAgICAgICAgIGNhc2UgaWZfaWNtcGd0OgogICAgICAgICAgICAgICAgICAgIHJldHVybiBzeW1zLmJvb2xlYW5UeXBlLmNvbnN0VHlwZSgKICAgICAgICAgICAgICAgICAgICAgICAgYjJpKGludFZhbHVlKGwpID4gaW50VmFsdWUocikpKTsKICAgICAgICAgICAgICAgIGNhc2UgaWZfaWNtcGxlOgogICAgICAgICAgICAgICAgICAgIHJldHVybiBzeW1zLmJvb2xlYW5UeXBlLmNvbnN0VHlwZSgKICAgICAgICAgICAgICAgICAgICAgICAgYjJpKGludFZhbHVlKGwpIDw9IGludFZhbHVlKHIpKSk7CiAgICAgICAgICAgICAgICBjYXNlIGlmX2ljbXBnZToKICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3ltcy5ib29sZWFuVHlwZS5jb25zdFR5cGUoCiAgICAgICAgICAgICAgICAgICAgICAgIGIyaShpbnRWYWx1ZShsKSA+PSBpbnRWYWx1ZShyKSkpOwoKICAgICAgICAgICAgICAgIGNhc2UgbGFkZDoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3ltcy5sb25nVHlwZS5jb25zdFR5cGUoCiAgICAgICAgICAgICAgICAgICAgICAgIExvbmcudmFsdWVPZihsb25nVmFsdWUobCkgKyBsb25nVmFsdWUocikpKTsKICAgICAgICAgICAgICAgIGNhc2UgbHN1YjoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3ltcy5sb25nVHlwZS5jb25zdFR5cGUoCiAgICAgICAgICAgICAgICAgICAgICAgIExvbmcudmFsdWVPZihsb25nVmFsdWUobCkgLSBsb25nVmFsdWUocikpKTsKICAgICAgICAgICAgICAgIGNhc2UgbG11bDoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3ltcy5sb25nVHlwZS5jb25zdFR5cGUoCiAgICAgICAgICAgICAgICAgICAgICAgIExvbmcudmFsdWVPZihsb25nVmFsdWUobCkgKiBsb25nVmFsdWUocikpKTsKICAgICAgICAgICAgICAgIGNhc2UgbGRpdjoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3ltcy5sb25nVHlwZS5jb25zdFR5cGUoCiAgICAgICAgICAgICAgICAgICAgICAgIExvbmcudmFsdWVPZihsb25nVmFsdWUobCkgLyBsb25nVmFsdWUocikpKTsKICAgICAgICAgICAgICAgIGNhc2UgbG1vZDoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3ltcy5sb25nVHlwZS5jb25zdFR5cGUoCiAgICAgICAgICAgICAgICAgICAgICAgIExvbmcudmFsdWVPZihsb25nVmFsdWUobCkgJSBsb25nVmFsdWUocikpKTsKICAgICAgICAgICAgICAgIGNhc2UgbGFuZDoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3ltcy5sb25nVHlwZS5jb25zdFR5cGUoCiAgICAgICAgICAgICAgICAgICAgICAgIExvbmcudmFsdWVPZihsb25nVmFsdWUobCkgJiBsb25nVmFsdWUocikpKTsKICAgICAgICAgICAgICAgIGNhc2UgbG9yOgogICAgICAgICAgICAgICAgICAgIHJldHVybiBzeW1zLmxvbmdUeXBlLmNvbnN0VHlwZSgKICAgICAgICAgICAgICAgICAgICAgICAgTG9uZy52YWx1ZU9mKGxvbmdWYWx1ZShsKSB8IGxvbmdWYWx1ZShyKSkpOwogICAgICAgICAgICAgICAgY2FzZSBseG9yOgogICAgICAgICAgICAgICAgICAgIHJldHVybiBzeW1zLmxvbmdUeXBlLmNvbnN0VHlwZSgKICAgICAgICAgICAgICAgICAgICAgICAgTG9uZy52YWx1ZU9mKGxvbmdWYWx1ZShsKSBeIGxvbmdWYWx1ZShyKSkpOwogICAgICAgICAgICAgICAgY2FzZSBsc2hsOiBjYXNlIGxzaGxsOgogICAgICAgICAgICAgICAgICAgIHJldHVybiBzeW1zLmxvbmdUeXBlLmNvbnN0VHlwZSgKICAgICAgICAgICAgICAgICAgICAgICAgTG9uZy52YWx1ZU9mKGxvbmdWYWx1ZShsKSA8PCBpbnRWYWx1ZShyKSkpOwogICAgICAgICAgICAgICAgY2FzZSBsc2hyOiBjYXNlIGxzaHJsOgogICAgICAgICAgICAgICAgICAgIHJldHVybiBzeW1zLmxvbmdUeXBlLmNvbnN0VHlwZSgKICAgICAgICAgICAgICAgICAgICAgICAgTG9uZy52YWx1ZU9mKGxvbmdWYWx1ZShsKSA+PiBpbnRWYWx1ZShyKSkpOwogICAgICAgICAgICAgICAgY2FzZSBsdXNocjoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3ltcy5sb25nVHlwZS5jb25zdFR5cGUoCiAgICAgICAgICAgICAgICAgICAgICAgIExvbmcudmFsdWVPZihsb25nVmFsdWUobCkgPj4+IGludFZhbHVlKHIpKSk7CiAgICAgICAgICAgICAgICBjYXNlIGxjbXA6CiAgICAgICAgICAgICAgICAgICAgaWYgKGxvbmdWYWx1ZShsKSA8IGxvbmdWYWx1ZShyKSkKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHN5bXMuaW50VHlwZS5jb25zdFR5cGUobWludXNPbmUpOwogICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGxvbmdWYWx1ZShsKSA+IGxvbmdWYWx1ZShyKSkKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHN5bXMuaW50VHlwZS5jb25zdFR5cGUob25lKTsKICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzeW1zLmludFR5cGUuY29uc3RUeXBlKHplcm8pOwogICAgICAgICAgICAgICAgY2FzZSBmYWRkOgogICAgICAgICAgICAgICAgICAgIHJldHVybiBzeW1zLmZsb2F0VHlwZS5jb25zdFR5cGUoCiAgICAgICAgICAgICAgICAgICAgICAgIEZsb2F0LnZhbHVlT2YoZmxvYXRWYWx1ZShsKSArIGZsb2F0VmFsdWUocikpKTsKICAgICAgICAgICAgICAgIGNhc2UgZnN1YjoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3ltcy5mbG9hdFR5cGUuY29uc3RUeXBlKAogICAgICAgICAgICAgICAgICAgICAgICBGbG9hdC52YWx1ZU9mKGZsb2F0VmFsdWUobCkgLSBmbG9hdFZhbHVlKHIpKSk7CiAgICAgICAgICAgICAgICBjYXNlIGZtdWw6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHN5bXMuZmxvYXRUeXBlLmNvbnN0VHlwZSgKICAgICAgICAgICAgICAgICAgICAgICAgRmxvYXQudmFsdWVPZihmbG9hdFZhbHVlKGwpICogZmxvYXRWYWx1ZShyKSkpOwogICAgICAgICAgICAgICAgY2FzZSBmZGl2OgogICAgICAgICAgICAgICAgICAgIHJldHVybiBzeW1zLmZsb2F0VHlwZS5jb25zdFR5cGUoCiAgICAgICAgICAgICAgICAgICAgICAgIEZsb2F0LnZhbHVlT2YoZmxvYXRWYWx1ZShsKSAvIGZsb2F0VmFsdWUocikpKTsKICAgICAgICAgICAgICAgIGNhc2UgZm1vZDoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3ltcy5mbG9hdFR5cGUuY29uc3RUeXBlKAogICAgICAgICAgICAgICAgICAgICAgICBGbG9hdC52YWx1ZU9mKGZsb2F0VmFsdWUobCkgJSBmbG9hdFZhbHVlKHIpKSk7CiAgICAgICAgICAgICAgICBjYXNlIGZjbXBnOiBjYXNlIGZjbXBsOgogICAgICAgICAgICAgICAgICAgIGlmIChmbG9hdFZhbHVlKGwpIDwgZmxvYXRWYWx1ZShyKSkKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHN5bXMuaW50VHlwZS5jb25zdFR5cGUobWludXNPbmUpOwogICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGZsb2F0VmFsdWUobCkgPiBmbG9hdFZhbHVlKHIpKQogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3ltcy5pbnRUeXBlLmNvbnN0VHlwZShvbmUpOwogICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGZsb2F0VmFsdWUobCkgPT0gZmxvYXRWYWx1ZShyKSkKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHN5bXMuaW50VHlwZS5jb25zdFR5cGUoemVybyk7CiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAob3Bjb2RlID09IGZjbXBnKQogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3ltcy5pbnRUeXBlLmNvbnN0VHlwZShvbmUpOwogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHN5bXMuaW50VHlwZS5jb25zdFR5cGUobWludXNPbmUpOwogICAgICAgICAgICAgICAgY2FzZSBkYWRkOgogICAgICAgICAgICAgICAgICAgIHJldHVybiBzeW1zLmRvdWJsZVR5cGUuY29uc3RUeXBlKAogICAgICAgICAgICAgICAgICAgICAgICBEb3VibGUudmFsdWVPZihkb3VibGVWYWx1ZShsKSArIGRvdWJsZVZhbHVlKHIpKSk7CiAgICAgICAgICAgICAgICBjYXNlIGRzdWI6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHN5bXMuZG91YmxlVHlwZS5jb25zdFR5cGUoCiAgICAgICAgICAgICAgICAgICAgICAgIERvdWJsZS52YWx1ZU9mKGRvdWJsZVZhbHVlKGwpIC0gZG91YmxlVmFsdWUocikpKTsKICAgICAgICAgICAgICAgIGNhc2UgZG11bDoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3ltcy5kb3VibGVUeXBlLmNvbnN0VHlwZSgKICAgICAgICAgICAgICAgICAgICAgICAgRG91YmxlLnZhbHVlT2YoZG91YmxlVmFsdWUobCkgKiBkb3VibGVWYWx1ZShyKSkpOwogICAgICAgICAgICAgICAgY2FzZSBkZGl2OgogICAgICAgICAgICAgICAgICAgIHJldHVybiBzeW1zLmRvdWJsZVR5cGUuY29uc3RUeXBlKAogICAgICAgICAgICAgICAgICAgICAgICBEb3VibGUudmFsdWVPZihkb3VibGVWYWx1ZShsKSAvIGRvdWJsZVZhbHVlKHIpKSk7CiAgICAgICAgICAgICAgICBjYXNlIGRtb2Q6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHN5bXMuZG91YmxlVHlwZS5jb25zdFR5cGUoCiAgICAgICAgICAgICAgICAgICAgICAgIERvdWJsZS52YWx1ZU9mKGRvdWJsZVZhbHVlKGwpICUgZG91YmxlVmFsdWUocikpKTsKICAgICAgICAgICAgICAgIGNhc2UgZGNtcGc6IGNhc2UgZGNtcGw6CiAgICAgICAgICAgICAgICAgICAgaWYgKGRvdWJsZVZhbHVlKGwpIDwgZG91YmxlVmFsdWUocikpCiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzeW1zLmludFR5cGUuY29uc3RUeXBlKG1pbnVzT25lKTsKICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChkb3VibGVWYWx1ZShsKSA+IGRvdWJsZVZhbHVlKHIpKQogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3ltcy5pbnRUeXBlLmNvbnN0VHlwZShvbmUpOwogICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGRvdWJsZVZhbHVlKGwpID09IGRvdWJsZVZhbHVlKHIpKQogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3ltcy5pbnRUeXBlLmNvbnN0VHlwZSh6ZXJvKTsKICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChvcGNvZGUgPT0gZGNtcGcpCiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzeW1zLmludFR5cGUuY29uc3RUeXBlKG9uZSk7CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3ltcy5pbnRUeXBlLmNvbnN0VHlwZShtaW51c09uZSk7CiAgICAgICAgICAgICAgICBjYXNlIGlmX2FjbXBlcToKICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3ltcy5ib29sZWFuVHlwZS5jb25zdFR5cGUoYjJpKGwuZXF1YWxzKHIpKSk7CiAgICAgICAgICAgICAgICBjYXNlIGlmX2FjbXBuZToKICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3ltcy5ib29sZWFuVHlwZS5jb25zdFR5cGUoYjJpKCFsLmVxdWFscyhyKSkpOwogICAgICAgICAgICAgICAgY2FzZSBzdHJpbmdfYWRkOgogICAgICAgICAgICAgICAgICAgIHJldHVybiBzeW1zLnN0cmluZ1R5cGUuY29uc3RUeXBlKAogICAgICAgICAgICAgICAgICAgICAgICBsZWZ0LnN0cmluZ1ZhbHVlKCkgKyByaWdodC5zdHJpbmdWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9IGNhdGNoIChBcml0aG1ldGljRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgfQoKICAgIC8qKiBDb2VyY2UgY29uc3RhbnQgdHlwZSB0byB0YXJnZXQgdHlwZS4KICAgICAqICBAcGFyYW0gZXR5cGUgICAgICBUaGUgc291cmNlIHR5cGUgb2YgdGhlIGNvZXJjaW9uLAogICAgICogICAgICAgICAgICAgICAgICAgIHdoaWNoIGlzIGFzc3VtZWQgdG8gYmUgYSBjb25zdGFudCB0eXBlIGNvbXBhdGlibGUgd2l0aAogICAgICogICAgICAgICAgICAgICAgICAgIHR0eXBlLgogICAgICogIEBwYXJhbSB0dHlwZSAgICAgIFRoZSB0YXJnZXQgdHlwZSBvZiB0aGUgY29lcmNpb24uCiAgICAgKi8KICAgICBUeXBlIGNvZXJjZShUeXBlIGV0eXBlLCBUeXBlIHR0eXBlKSB7CiAgICAgICAgIC8vIFdBUyBpZiAoZXR5cGUuYmFzZVR5cGUoKSA9PSB0dHlwZS5iYXNlVHlwZSgpKQogICAgICAgICBpZiAoZXR5cGUudHN5bS50eXBlID09IHR0eXBlLnRzeW0udHlwZSkKICAgICAgICAgICAgIHJldHVybiBldHlwZTsKICAgICAgICAgaWYgKGV0eXBlLmlzTnVtZXJpYygpKSB7CiAgICAgICAgICAgICBPYmplY3QgbiA9IGV0eXBlLmNvbnN0VmFsdWUoKTsKICAgICAgICAgICAgIHN3aXRjaCAodHR5cGUuZ2V0VGFnKCkpIHsKICAgICAgICAgICAgIGNhc2UgQllURToKICAgICAgICAgICAgICAgICByZXR1cm4gc3ltcy5ieXRlVHlwZS5jb25zdFR5cGUoMCArIChieXRlKWludFZhbHVlKG4pKTsKICAgICAgICAgICAgIGNhc2UgQ0hBUjoKICAgICAgICAgICAgICAgICByZXR1cm4gc3ltcy5jaGFyVHlwZS5jb25zdFR5cGUoMCArIChjaGFyKWludFZhbHVlKG4pKTsKICAgICAgICAgICAgIGNhc2UgU0hPUlQ6CiAgICAgICAgICAgICAgICAgcmV0dXJuIHN5bXMuc2hvcnRUeXBlLmNvbnN0VHlwZSgwICsgKHNob3J0KWludFZhbHVlKG4pKTsKICAgICAgICAgICAgIGNhc2UgSU5UOgogICAgICAgICAgICAgICAgIHJldHVybiBzeW1zLmludFR5cGUuY29uc3RUeXBlKGludFZhbHVlKG4pKTsKICAgICAgICAgICAgIGNhc2UgTE9ORzoKICAgICAgICAgICAgICAgICByZXR1cm4gc3ltcy5sb25nVHlwZS5jb25zdFR5cGUobG9uZ1ZhbHVlKG4pKTsKICAgICAgICAgICAgIGNhc2UgRkxPQVQ6CiAgICAgICAgICAgICAgICAgcmV0dXJuIHN5bXMuZmxvYXRUeXBlLmNvbnN0VHlwZShmbG9hdFZhbHVlKG4pKTsKICAgICAgICAgICAgIGNhc2UgRE9VQkxFOgogICAgICAgICAgICAgICAgIHJldHVybiBzeW1zLmRvdWJsZVR5cGUuY29uc3RUeXBlKGRvdWJsZVZhbHVlKG4pKTsKICAgICAgICAgICAgIH0KICAgICAgICAgfQogICAgICAgICByZXR1cm4gdHR5cGU7CiAgICAgfQp9ClBLAwQKAAAIAADSfU1KIG1Fxy0HAAAtBwAALAAAAGNvbS9zdW4vdG9vbHMvamF2YWMvY29tcC9BdHRyQ29udGV4dEVudi5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDAwLCAyMDA1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuamF2YWMuY29tcDsKCmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuSkNUcmVlOwoKCi8qKiB7QGNvZGUgRW52PEE+fSBzcGVjaWFsaXplZCBhcyB7QGNvZGUgRW52PEF0dHJDb250ZXh0Pn0KICoKICogIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqICBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqICBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogKiAgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPgogKi8KcHVibGljIGNsYXNzIEF0dHJDb250ZXh0RW52IGV4dGVuZHMgRW52PEF0dHJDb250ZXh0PiB7CgogICAgLyoqIENyZWF0ZSBhbiBvdXRlcm1vc3QgZW52aXJvbm1lbnQgZm9yIGEgZ2l2ZW4gKHRvcGxldmVsKXRyZWUsCiAgICAgKiAgd2l0aCBhIGdpdmVuIGluZm8gZmllbGQuCiAgICAgKi8KICAgIHB1YmxpYyBBdHRyQ29udGV4dEVudihKQ1RyZWUgdHJlZSwgQXR0ckNvbnRleHQgaW5mbykgewogICAgICAgIHN1cGVyKHRyZWUsIGluZm8pOwogICAgfQp9ClBLAwQKAAAIAADSfU1K/eEM6qMUAACjFAAAIQAAAGNvbS9zdW4vdG9vbHMvamF2YWMvY29tcC9FbnYuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMTk5OSwgMjAxMywgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLmphdmFjLmNvbXA7CgppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLio7CmltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CmltcG9ydCBqYXZhLnV0aWwuTm9TdWNoRWxlbWVudEV4Y2VwdGlvbjsKCi8qKiBBIGNsYXNzIGZvciBlbnZpcm9ubWVudHMsIGluc3RhbmNlcyBvZiB3aGljaCBhcmUgcGFzc2VkIGFzCiAqICBhcmd1bWVudHMgdG8gdHJlZSB2aXNpdG9ycy4gIEVudmlyb25tZW50cyByZWZlciB0byBpbXBvcnRhbnQgYW5jZXN0b3JzCiAqICBvZiB0aGUgc3VidHJlZSB0aGF0J3MgY3VycmVudGx5IHZpc2l0ZWQsIHN1Y2ggYXMgdGhlIGVuY2xvc2luZyBtZXRob2QsCiAqICB0aGUgZW5jbG9zaW5nIGNsYXNzLCBvciB0aGUgZW5jbG9zaW5nIHRvcGxldmVsIG5vZGUuIFRoZXkgYWxzbyBjb250YWluCiAqICBhIGdlbmVyaWMgY29tcG9uZW50LCByZXByZXNlbnRlZCBhcyBhIHR5cGUgcGFyYW1ldGVyLCB0byBjYXJyeSBmdXJ0aGVyCiAqICBpbmZvcm1hdGlvbiBzcGVjaWZpYyB0byBpbmRpdmlkdWFsIHBhc3Nlcy4KICoKICogIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqICBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqICBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogKiAgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPgogKi8KcHVibGljIGNsYXNzIEVudjxBPiBpbXBsZW1lbnRzIEl0ZXJhYmxlPEVudjxBPj4gewoKICAgIC8qKiBUaGUgbmV4dCBlbmNsb3NpbmcgZW52aXJvbm1lbnQuCiAgICAgKi8KICAgIHB1YmxpYyBFbnY8QT4gbmV4dDsKCiAgICAvKiogVGhlIGVudmlyb25tZW50IGVuY2xvc2luZyB0aGUgY3VycmVudCBjbGFzcy4KICAgICAqLwogICAgcHVibGljIEVudjxBPiBvdXRlcjsKCiAgICAvKiogVGhlIHRyZWUgd2l0aCB3aGljaCB0aGlzIGVudmlyb25tZW50IGlzIGFzc29jaWF0ZWQuCiAgICAgKi8KICAgIHB1YmxpYyBKQ1RyZWUgdHJlZTsKCiAgICAvKiogVGhlIGVuY2xvc2luZyB0b3BsZXZlbCB0cmVlLgogICAgICovCiAgICBwdWJsaWMgSkNUcmVlLkpDQ29tcGlsYXRpb25Vbml0IHRvcGxldmVsOwoKICAgIC8qKiBUaGUgbmV4dCBlbmNsb3NpbmcgY2xhc3MgZGVmaW5pdGlvbi4KICAgICAqLwogICAgcHVibGljIEpDVHJlZS5KQ0NsYXNzRGVjbCBlbmNsQ2xhc3M7CgogICAgLyoqIFRoZSBuZXh0IGVuY2xvc2luZyBtZXRob2QgZGVmaW5pdGlvbi4KICAgICAqLwogICAgcHVibGljIEpDVHJlZS5KQ01ldGhvZERlY2wgZW5jbE1ldGhvZDsKCiAgICAvKiogQSBnZW5lcmljIGZpZWxkIGZvciBmdXJ0aGVyIGluZm9ybWF0aW9uLgogICAgICovCiAgICBwdWJsaWMgQSBpbmZvOwoKICAgIC8qKiBJcyB0aGlzIGFuIGVudmlyb25tZW50IGZvciBldmFsdWF0aW5nIGEgYmFzZSBjbGF1c2U/CiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGJhc2VDbGF1c2UgPSBmYWxzZTsKCiAgICAvKiogQ3JlYXRlIGFuIG91dGVybW9zdCBlbnZpcm9ubWVudCBmb3IgYSBnaXZlbiAodG9wbGV2ZWwpdHJlZSwKICAgICAqICB3aXRoIGEgZ2l2ZW4gaW5mbyBmaWVsZC4KICAgICAqLwogICAgcHVibGljIEVudihKQ1RyZWUgdHJlZSwgQSBpbmZvKSB7CiAgICAgICAgdGhpcy5uZXh0ID0gbnVsbDsKICAgICAgICB0aGlzLm91dGVyID0gbnVsbDsKICAgICAgICB0aGlzLnRyZWUgPSB0cmVlOwogICAgICAgIHRoaXMudG9wbGV2ZWwgPSBudWxsOwogICAgICAgIHRoaXMuZW5jbENsYXNzID0gbnVsbDsKICAgICAgICB0aGlzLmVuY2xNZXRob2QgPSBudWxsOwogICAgICAgIHRoaXMuaW5mbyA9IGluZm87CiAgICB9CgogICAgLyoqIER1cGxpY2F0ZSB0aGlzIGVudmlyb25tZW50LCB1cGRhdGluZyB3aXRoIGdpdmVuIHRyZWUgYW5kIGluZm8sCiAgICAgKiAgYW5kIGNvcHlpbmcgYWxsIG90aGVyIGZpZWxkcy4KICAgICAqLwogICAgcHVibGljIEVudjxBPiBkdXAoSkNUcmVlIHRyZWUsIEEgaW5mbykgewogICAgICAgIHJldHVybiBkdXB0byhuZXcgRW52PD4odHJlZSwgaW5mbykpOwogICAgfQoKICAgIC8qKiBEdXBsaWNhdGUgdGhpcyBlbnZpcm9ubWVudCBpbnRvIGEgZ2l2ZW4gRW52aXJvbm1lbnQsCiAgICAgKiAgdXNpbmcgaXRzIHRyZWUgYW5kIGluZm8sIGFuZCBjb3B5aW5nIGFsbCBvdGhlciBmaWVsZHMuCiAgICAgKi8KICAgIHB1YmxpYyBFbnY8QT4gZHVwdG8oRW52PEE+IHRoYXQpIHsKICAgICAgICB0aGF0Lm5leHQgPSB0aGlzOwogICAgICAgIHRoYXQub3V0ZXIgPSB0aGlzLm91dGVyOwogICAgICAgIHRoYXQudG9wbGV2ZWwgPSB0aGlzLnRvcGxldmVsOwogICAgICAgIHRoYXQuZW5jbENsYXNzID0gdGhpcy5lbmNsQ2xhc3M7CiAgICAgICAgdGhhdC5lbmNsTWV0aG9kID0gdGhpcy5lbmNsTWV0aG9kOwogICAgICAgIHJldHVybiB0aGF0OwogICAgfQoKICAgIC8qKiBEdXBsaWNhdGUgdGhpcyBlbnZpcm9ubWVudCwgdXBkYXRpbmcgd2l0aCBnaXZlbiB0cmVlLAogICAgICogIGFuZCBjb3B5aW5nIGFsbCBvdGhlciBmaWVsZHMuCiAgICAgKi8KICAgIHB1YmxpYyBFbnY8QT4gZHVwKEpDVHJlZSB0cmVlKSB7CiAgICAgICAgcmV0dXJuIGR1cCh0cmVlLCB0aGlzLmluZm8pOwogICAgfQoKICAgIC8qKiBSZXR1cm4gY2xvc2VzdCBlbmNsb3NpbmcgZW52aXJvbm1lbnQgd2hpY2ggcG9pbnRzIHRvIGEgdHJlZSB3aXRoIGdpdmVuIHRhZy4KICAgICAqLwogICAgcHVibGljIEVudjxBPiBlbmNsb3NpbmcoSkNUcmVlLlRhZyB0YWcpIHsKICAgICAgICBFbnY8QT4gZW52MSA9IHRoaXM7CiAgICAgICAgd2hpbGUgKGVudjEgIT0gbnVsbCAmJiAhZW52MS50cmVlLmhhc1RhZyh0YWcpKSBlbnYxID0gZW52MS5uZXh0OwogICAgICAgIHJldHVybiBlbnYxOwogICAgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKICAgICAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKICAgICAgICBzYi5hcHBlbmQoIkVudlsiKS5hcHBlbmQoaW5mbyk7Ci8vICAgICAgICBpZiAoZW5jbE1ldGhvZCAhPSBudWxsKQovLyAgICAgICAgICAgIHNiLmFwcGVuZCgiLGVuY2xNZXRob2Q9IikuYXBwZW5kKFByZXR0eS50b1NpbXBsZVN0cmluZyhlbmNsTWV0aG9kKSk7Ci8vICAgICAgICBpZiAoZW5jbENsYXNzICE9IG51bGwpCi8vICAgICAgICAgICAgc2IuYXBwZW5kKCIsZW5jbENsYXNzPSIpLmFwcGVuZChQcmV0dHkudG9TaW1wbGVTdHJpbmcoZW5jbENsYXNzKSk7CiAgICAgICAgaWYgKG91dGVyICE9IG51bGwpCiAgICAgICAgICAgIHNiLmFwcGVuZCgiLG91dGVyPSIpLmFwcGVuZChvdXRlcik7CiAgICAgICAgc2IuYXBwZW5kKCJdIik7CiAgICAgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7CiAgICB9CgogICAgcHVibGljIEl0ZXJhdG9yPEVudjxBPj4gaXRlcmF0b3IoKSB7CiAgICAgICAgcmV0dXJuIG5ldyBJdGVyYXRvcjxFbnY8QT4+KCkgewogICAgICAgICAgICBFbnY8QT4gbmV4dCA9IEVudi50aGlzOwogICAgICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNOZXh0KCkgewogICAgICAgICAgICAgICAgcmV0dXJuIG5leHQub3V0ZXIgIT0gbnVsbDsKICAgICAgICAgICAgfQogICAgICAgICAgICBwdWJsaWMgRW52PEE+IG5leHQoKSB7CiAgICAgICAgICAgICAgICBpZiAoaGFzTmV4dCgpKSB7CiAgICAgICAgICAgICAgICAgICAgRW52PEE+IGN1cnJlbnQgPSBuZXh0OwogICAgICAgICAgICAgICAgICAgIG5leHQgPSBjdXJyZW50Lm91dGVyOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBjdXJyZW50OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaEVsZW1lbnRFeGNlcHRpb24oKTsKCiAgICAgICAgICAgIH0KICAgICAgICAgICAgcHVibGljIHZvaWQgcmVtb3ZlKCkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CiAgICAgICAgICAgIH0KICAgICAgICB9OwogICAgfQp9ClBLAwQKAAAIAAAGO6lK4dm+WHsLAQB7CwEAJQAAAGNvbS9zdW4vdG9vbHMvamF2YWMvY29tcC9Nb2R1bGVzLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDksIDIwMTcsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuamF2YWMuY29tcDsKCmltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwppbXBvcnQgamF2YS51dGlsLkFycmF5czsKaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uOwppbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOwppbXBvcnQgamF2YS51dGlsLkVudW1TZXQ7CmltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKaW1wb3J0IGphdmEudXRpbC5IYXNoU2V0OwppbXBvcnQgamF2YS51dGlsLkxpbmtlZEhhc2hNYXA7CmltcG9ydCBqYXZhLnV0aWwuTGlua2VkSGFzaFNldDsKaW1wb3J0IGphdmEudXRpbC5NYXA7CmltcG9ydCBqYXZhLnV0aWwuU2V0OwppbXBvcnQgamF2YS51dGlsLmZ1bmN0aW9uLkNvbnN1bWVyOwppbXBvcnQgamF2YS51dGlsLmZ1bmN0aW9uLlByZWRpY2F0ZTsKaW1wb3J0IGphdmEudXRpbC5yZWdleC5NYXRjaGVyOwppbXBvcnQgamF2YS51dGlsLnJlZ2V4LlBhdHRlcm47CmltcG9ydCBqYXZhLnV0aWwuc3RyZWFtLkNvbGxlY3RvcnM7CmltcG9ydCBqYXZhLnV0aWwuc3RyZWFtLlN0cmVhbTsKCmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLlNvdXJjZVZlcnNpb247CmltcG9ydCBqYXZheC50b29scy5KYXZhRmlsZU1hbmFnZXI7CmltcG9ydCBqYXZheC50b29scy5KYXZhRmlsZU1hbmFnZXIuTG9jYXRpb247CmltcG9ydCBqYXZheC50b29scy5KYXZhRmlsZU9iamVjdDsKaW1wb3J0IGphdmF4LnRvb2xzLkphdmFGaWxlT2JqZWN0LktpbmQ7CmltcG9ydCBqYXZheC50b29scy5TdGFuZGFyZExvY2F0aW9uOwoKaW1wb3J0IGNvbS5zdW4uc291cmNlLnRyZWUuTW9kdWxlVHJlZS5Nb2R1bGVLaW5kOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLkNsYXNzRmluZGVyOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLkRlZmVycmVkTGludEhhbmRsZXI7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuRGlyZWN0aXZlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLkRpcmVjdGl2ZS5FeHBvcnRzRGlyZWN0aXZlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLkRpcmVjdGl2ZS5FeHBvcnRzRmxhZzsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5EaXJlY3RpdmUuT3BlbnNEaXJlY3RpdmU7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuRGlyZWN0aXZlLk9wZW5zRmxhZzsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5EaXJlY3RpdmUuUmVxdWlyZXNEaXJlY3RpdmU7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuRGlyZWN0aXZlLlJlcXVpcmVzRmxhZzsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5EaXJlY3RpdmUuVXNlc0RpcmVjdGl2ZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5GbGFnczsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5MaW50LkxpbnRDYXRlZ29yeTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5Nb2R1bGVGaW5kZXI7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuU291cmNlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlN5bWJvbDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5TeW1ib2wuQ2xhc3NTeW1ib2w7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuU3ltYm9sLkNvbXBsZXRlcjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5TeW1ib2wuQ29tcGxldGlvbkZhaWx1cmU7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuU3ltYm9sLk1ldGhvZFN5bWJvbDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5TeW1ib2wuTW9kdWxlRmxhZ3M7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuU3ltYm9sLk1vZHVsZVN5bWJvbDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5TeW1ib2wuUGFja2FnZVN5bWJvbDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5TeW10YWI7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuVHlwZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5UeXBlczsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuanZtLkNsYXNzV3JpdGVyOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5qdm0uSk5JV3JpdGVyOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5tYWluLk9wdGlvbjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMucmVzb3VyY2VzLkNvbXBpbGVyUHJvcGVydGllcy5FcnJvcnM7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnJlc291cmNlcy5Db21waWxlclByb3BlcnRpZXMuV2FybmluZ3M7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuSkNUcmVlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkpDVHJlZS5KQ0NvbXBpbGF0aW9uVW5pdDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5KQ1RyZWUuSkNEaXJlY3RpdmU7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuSkNUcmVlLkpDRXhwb3J0czsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5KQ1RyZWUuSkNFeHByZXNzaW9uOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkpDVHJlZS5KQ01vZHVsZURlY2w7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuSkNUcmVlLkpDT3BlbnM7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuSkNUcmVlLkpDUGFja2FnZURlY2w7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuSkNUcmVlLkpDUHJvdmlkZXM7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuSkNUcmVlLkpDUmVxdWlyZXM7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuSkNUcmVlLkpDVXNlczsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5KQ1RyZWUuVGFnOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLlRyZWVJbmZvOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkFib3J0OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkFzc2VydDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5Db250ZXh0OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkpDRGlhZ25vc3RpYzsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5KQ0RpYWdub3N0aWMuRGlhZ25vc3RpY1Bvc2l0aW9uOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkxpc3Q7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuTGlzdEJ1ZmZlcjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5Mb2c7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuTmFtZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5OYW1lczsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5PcHRpb25zOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLlBvc2l0aW9uOwoKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuRmxhZ3MuQUJTVFJBQ1Q7CmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLkZsYWdzLkVOVU07CmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLkZsYWdzLlBVQkxJQzsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuRmxhZ3MuVU5BVFRSSUJVVEVEOwppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5LaW5kcy5LaW5kLkVSUjsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuS2luZHMuS2luZC5NREw7CmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLktpbmRzLktpbmQuTVRIOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlN5bWJvbC5Nb2R1bGVSZXNvbHV0aW9uRmxhZ3M7CmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlR5cGVUYWcuQ0xBU1M7CgovKioKICogIFRPRE86IGZpbGwgaW4KICoKICogIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqICBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqICBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogKiAgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPgogKi8KcHVibGljIGNsYXNzIE1vZHVsZXMgZXh0ZW5kcyBKQ1RyZWUuVmlzaXRvciB7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgQUxMX1NZU1RFTSA9ICJBTEwtU1lTVEVNIjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBBTExfTU9EVUxFX1BBVEggPSAiQUxMLU1PRFVMRS1QQVRIIjsKCiAgICBwcml2YXRlIGZpbmFsIExvZyBsb2c7CiAgICBwcml2YXRlIGZpbmFsIE5hbWVzIG5hbWVzOwogICAgcHJpdmF0ZSBmaW5hbCBTeW10YWIgc3ltczsKICAgIHByaXZhdGUgZmluYWwgQXR0ciBhdHRyOwogICAgcHJpdmF0ZSBmaW5hbCBDaGVjayBjaGs7CiAgICBwcml2YXRlIGZpbmFsIERlZmVycmVkTGludEhhbmRsZXIgZGVmZXJyZWRMaW50SGFuZGxlcjsKICAgIHByaXZhdGUgZmluYWwgVHlwZUVudnMgdHlwZUVudnM7CiAgICBwcml2YXRlIGZpbmFsIFR5cGVzIHR5cGVzOwogICAgcHJpdmF0ZSBmaW5hbCBKYXZhRmlsZU1hbmFnZXIgZmlsZU1hbmFnZXI7CiAgICBwcml2YXRlIGZpbmFsIE1vZHVsZUZpbmRlciBtb2R1bGVGaW5kZXI7CiAgICBwcml2YXRlIGZpbmFsIFNvdXJjZSBzb3VyY2U7CiAgICBwcml2YXRlIGZpbmFsIGJvb2xlYW4gYWxsb3dNb2R1bGVzOwoKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIG11bHRpTW9kdWxlTW9kZTsKCiAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBsZWdhY3lNb2R1bGVPdmVycmlkZTsKCiAgICBwcml2YXRlIGZpbmFsIE5hbWUgamF2YV9zZTsKICAgIHByaXZhdGUgZmluYWwgTmFtZSBqYXZhXzsKCiAgICBNb2R1bGVTeW1ib2wgZGVmYXVsdE1vZHVsZTsKCiAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBhZGRFeHBvcnRzT3B0OwogICAgcHJpdmF0ZSBNYXA8TW9kdWxlU3ltYm9sLCBTZXQ8RXhwb3J0c0RpcmVjdGl2ZT4+IGFkZEV4cG9ydHM7CiAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBhZGRSZWFkc09wdDsKICAgIHByaXZhdGUgTWFwPE1vZHVsZVN5bWJvbCwgU2V0PFJlcXVpcmVzRGlyZWN0aXZlPj4gYWRkUmVhZHM7CiAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBhZGRNb2RzT3B0OwogICAgcHJpdmF0ZSBmaW5hbCBTZXQ8U3RyaW5nPiBleHRyYUFkZE1vZHMgPSBuZXcgSGFzaFNldDw+KCk7CiAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBsaW1pdE1vZHNPcHQ7CiAgICBwcml2YXRlIGZpbmFsIFNldDxTdHJpbmc+IGV4dHJhTGltaXRNb2RzID0gbmV3IEhhc2hTZXQ8PigpOwogICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgbW9kdWxlVmVyc2lvbk9wdDsKCiAgICBwcml2YXRlIGZpbmFsIGJvb2xlYW4gbGludE9wdGlvbnM7CgogICAgcHJpdmF0ZSBTZXQ8TW9kdWxlU3ltYm9sPiByb290TW9kdWxlcyA9IG51bGw7CiAgICBwcml2YXRlIGZpbmFsIFNldDxNb2R1bGVTeW1ib2w+IHdhcm5lZE1pc3NpbmcgPSBuZXcgSGFzaFNldDw+KCk7CgogICAgcHVibGljIHN0YXRpYyBNb2R1bGVzIGluc3RhbmNlKENvbnRleHQgY29udGV4dCkgewogICAgICAgIE1vZHVsZXMgaW5zdGFuY2UgPSBjb250ZXh0LmdldChNb2R1bGVzLmNsYXNzKTsKICAgICAgICBpZiAoaW5zdGFuY2UgPT0gbnVsbCkKICAgICAgICAgICAgaW5zdGFuY2UgPSBuZXcgTW9kdWxlcyhjb250ZXh0KTsKICAgICAgICByZXR1cm4gaW5zdGFuY2U7CiAgICB9CgogICAgcHJvdGVjdGVkIE1vZHVsZXMoQ29udGV4dCBjb250ZXh0KSB7CiAgICAgICAgY29udGV4dC5wdXQoTW9kdWxlcy5jbGFzcywgdGhpcyk7CiAgICAgICAgbG9nID0gTG9nLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIG5hbWVzID0gTmFtZXMuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgc3ltcyA9IFN5bXRhYi5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBhdHRyID0gQXR0ci5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBjaGsgPSBDaGVjay5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBkZWZlcnJlZExpbnRIYW5kbGVyID0gRGVmZXJyZWRMaW50SGFuZGxlci5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICB0eXBlRW52cyA9IFR5cGVFbnZzLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIG1vZHVsZUZpbmRlciA9IE1vZHVsZUZpbmRlci5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICB0eXBlcyA9IFR5cGVzLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIGZpbGVNYW5hZ2VyID0gY29udGV4dC5nZXQoSmF2YUZpbGVNYW5hZ2VyLmNsYXNzKTsKICAgICAgICBzb3VyY2UgPSBTb3VyY2UuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgYWxsb3dNb2R1bGVzID0gc291cmNlLmFsbG93TW9kdWxlcygpOwogICAgICAgIE9wdGlvbnMgb3B0aW9ucyA9IE9wdGlvbnMuaW5zdGFuY2UoY29udGV4dCk7CgogICAgICAgIGxpbnRPcHRpb25zID0gb3B0aW9ucy5pc1Vuc2V0KE9wdGlvbi5YTElOVF9DVVNUT00sICItIiArIExpbnRDYXRlZ29yeS5PUFRJT05TLm9wdGlvbik7CgogICAgICAgIGxlZ2FjeU1vZHVsZU92ZXJyaWRlID0gb3B0aW9ucy5nZXQoT3B0aW9uLlhNT0RVTEUpOwoKICAgICAgICBtdWx0aU1vZHVsZU1vZGUgPSBmaWxlTWFuYWdlci5oYXNMb2NhdGlvbihTdGFuZGFyZExvY2F0aW9uLk1PRFVMRV9TT1VSQ0VfUEFUSCk7CiAgICAgICAgQ2xhc3NXcml0ZXIgY2xhc3NXcml0ZXIgPSBDbGFzc1dyaXRlci5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBjbGFzc1dyaXRlci5tdWx0aU1vZHVsZU1vZGUgPSBtdWx0aU1vZHVsZU1vZGU7CiAgICAgICAgSk5JV3JpdGVyIGpuaVdyaXRlciA9IEpOSVdyaXRlci5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBqbmlXcml0ZXIubXVsdGlNb2R1bGVNb2RlID0gbXVsdGlNb2R1bGVNb2RlOwoKICAgICAgICBqYXZhX3NlID0gbmFtZXMuZnJvbVN0cmluZygiamF2YS5zZSIpOwogICAgICAgIGphdmFfID0gbmFtZXMuZnJvbVN0cmluZygiamF2YS4iKTsKCiAgICAgICAgYWRkRXhwb3J0c09wdCA9IG9wdGlvbnMuZ2V0KE9wdGlvbi5BRERfRVhQT1JUUyk7CiAgICAgICAgYWRkUmVhZHNPcHQgPSBvcHRpb25zLmdldChPcHRpb24uQUREX1JFQURTKTsKICAgICAgICBhZGRNb2RzT3B0ID0gb3B0aW9ucy5nZXQoT3B0aW9uLkFERF9NT0RVTEVTKTsKICAgICAgICBsaW1pdE1vZHNPcHQgPSBvcHRpb25zLmdldChPcHRpb24uTElNSVRfTU9EVUxFUyk7CiAgICAgICAgbW9kdWxlVmVyc2lvbk9wdCA9IG9wdGlvbnMuZ2V0KE9wdGlvbi5NT0RVTEVfVkVSU0lPTik7CiAgICB9CgogICAgaW50IGRlcHRoID0gLTE7CiAgICBwcml2YXRlIHZvaWQgZHByaW50bG4oU3RyaW5nIG1zZykgewogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVwdGg7IGkrKykKICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludCgiICAiKTsKICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4obXNnKTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCBhZGRFeHRyYUFkZE1vZHVsZXMoU3RyaW5nLi4uIGV4dHJhcykgewogICAgICAgIGV4dHJhQWRkTW9kcy5hZGRBbGwoQXJyYXlzLmFzTGlzdChleHRyYXMpKTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCBhZGRFeHRyYUxpbWl0TW9kdWxlcyhTdHJpbmcuLi4gZXh0cmFzKSB7CiAgICAgICAgZXh0cmFMaW1pdE1vZHMuYWRkQWxsKEFycmF5cy5hc0xpc3QoZXh0cmFzKSk7CiAgICB9CgogICAgYm9vbGVhbiBpbkluaXRNb2R1bGVzOwogICAgcHVibGljIHZvaWQgaW5pdE1vZHVsZXMoTGlzdDxKQ0NvbXBpbGF0aW9uVW5pdD4gdHJlZXMpIHsKICAgICAgICBBc3NlcnQuY2hlY2soIWluSW5pdE1vZHVsZXMpOwogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGluSW5pdE1vZHVsZXMgPSB0cnVlOwogICAgICAgICAgICBBc3NlcnQuY2hlY2tOdWxsKHJvb3RNb2R1bGVzKTsKICAgICAgICAgICAgZW50ZXIodHJlZXMsIG1vZHVsZXMgLT4gewogICAgICAgICAgICAgICAgQXNzZXJ0LmNoZWNrTnVsbChyb290TW9kdWxlcyk7CiAgICAgICAgICAgICAgICBBc3NlcnQuY2hlY2tOdWxsKGFsbE1vZHVsZXMpOwogICAgICAgICAgICAgICAgdGhpcy5yb290TW9kdWxlcyA9IG1vZHVsZXM7CiAgICAgICAgICAgICAgICBzZXR1cEFsbE1vZHVsZXMoKTsgLy9pbml0aWFsaXplIHRoZSBtb2R1bGUgZ3JhcGgKICAgICAgICAgICAgICAgIEFzc2VydC5jaGVja05vbk51bGwoYWxsTW9kdWxlcyk7CiAgICAgICAgICAgICAgICBpbkluaXRNb2R1bGVzID0gZmFsc2U7CiAgICAgICAgICAgIH0sIG51bGwpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgIGluSW5pdE1vZHVsZXMgPSBmYWxzZTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIGJvb2xlYW4gZW50ZXIoTGlzdDxKQ0NvbXBpbGF0aW9uVW5pdD4gdHJlZXMsIENsYXNzU3ltYm9sIGMpIHsKICAgICAgICBBc3NlcnQuY2hlY2socm9vdE1vZHVsZXMgIT0gbnVsbCB8fCBpbkluaXRNb2R1bGVzIHx8ICFhbGxvd01vZHVsZXMpOwogICAgICAgIHJldHVybiBlbnRlcih0cmVlcywgbW9kdWxlcyAtPiB7fSwgYyk7CiAgICB9CgogICAgcHJpdmF0ZSBib29sZWFuIGVudGVyKExpc3Q8SkNDb21waWxhdGlvblVuaXQ+IHRyZWVzLCBDb25zdW1lcjxTZXQ8TW9kdWxlU3ltYm9sPj4gaW5pdCwgQ2xhc3NTeW1ib2wgYykgewogICAgICAgIGlmICghYWxsb3dNb2R1bGVzKSB7CiAgICAgICAgICAgIGZvciAoSkNDb21waWxhdGlvblVuaXQgdHJlZTogdHJlZXMpIHsKICAgICAgICAgICAgICAgIHRyZWUubW9kbGUgPSBzeW1zLm5vTW9kdWxlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGRlZmF1bHRNb2R1bGUgPSBzeW1zLm5vTW9kdWxlOwogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIGludCBzdGFydEVycm9ycyA9IGxvZy5uZXJyb3JzOwoKICAgICAgICBkZXB0aCsrOwogICAgICAgIHRyeSB7CiAgICAgICAgICAgIC8vIHNjYW4gdHJlZXMgZm9yIG1vZHVsZSBkZWZzCiAgICAgICAgICAgIFNldDxNb2R1bGVTeW1ib2w+IHJvb3RzID0gZW50ZXJNb2R1bGVzKHRyZWVzLCBjKTsKCiAgICAgICAgICAgIHNldENvbXBpbGF0aW9uVW5pdE1vZHVsZXModHJlZXMsIHJvb3RzLCBjKTsKCiAgICAgICAgICAgIGluaXQuYWNjZXB0KHJvb3RzKTsKCiAgICAgICAgICAgIGZvciAoTW9kdWxlU3ltYm9sIG1zeW06IHJvb3RzKSB7CiAgICAgICAgICAgICAgICBtc3ltLmNvbXBsZXRlKCk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGNhdGNoIChDb21wbGV0aW9uRmFpbHVyZSBleCkgewogICAgICAgICAgICBsb2cuZXJyb3IoSkNEaWFnbm9zdGljLkRpYWdub3N0aWNGbGFnLk5PTl9ERUZFUlJBQkxFLCBQb3NpdGlvbi5OT1BPUywgImNhbnQuYWNjZXNzIiwgZXguc3ltLCBleC5nZXREZXRhaWxWYWx1ZSgpKTsKICAgICAgICAgICAgaWYgKGV4IGluc3RhbmNlb2YgQ2xhc3NGaW5kZXIuQmFkQ2xhc3NGaWxlKSB0aHJvdyBuZXcgQWJvcnQoKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICBkZXB0aC0tOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIChsb2cubmVycm9ycyA9PSBzdGFydEVycm9ycyk7CiAgICB9CgogICAgcHVibGljIENvbXBsZXRlciBnZXRDb21wbGV0ZXIoKSB7CiAgICAgICAgcmV0dXJuIG1haW5Db21wbGV0ZXI7CiAgICB9CgogICAgcHVibGljIE1vZHVsZVN5bWJvbCBnZXREZWZhdWx0TW9kdWxlKCkgewogICAgICAgIHJldHVybiBkZWZhdWx0TW9kdWxlOwogICAgfQoKICAgIHB1YmxpYyBib29sZWFuIG1vZHVsZXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gYWxsTW9kdWxlcyAhPSBudWxsOwogICAgfQoKICAgIHByaXZhdGUgU2V0PE1vZHVsZVN5bWJvbD4gZW50ZXJNb2R1bGVzKExpc3Q8SkNDb21waWxhdGlvblVuaXQ+IHRyZWVzLCBDbGFzc1N5bWJvbCBjKSB7CiAgICAgICAgU2V0PE1vZHVsZVN5bWJvbD4gbW9kdWxlcyA9IG5ldyBMaW5rZWRIYXNoU2V0PD4oKTsKICAgICAgICBmb3IgKEpDQ29tcGlsYXRpb25Vbml0IHRyZWUgOiB0cmVlcykgewogICAgICAgICAgICBKYXZhRmlsZU9iamVjdCBwcmV2ID0gbG9nLnVzZVNvdXJjZSh0cmVlLnNvdXJjZWZpbGUpOwogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgZW50ZXJNb2R1bGUodHJlZSwgYywgbW9kdWxlcyk7CiAgICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgICAgICBsb2cudXNlU291cmNlKHByZXYpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBtb2R1bGVzOwogICAgfQoKCiAgICBwcml2YXRlIHZvaWQgZW50ZXJNb2R1bGUoSkNDb21waWxhdGlvblVuaXQgdG9wbGV2ZWwsIENsYXNzU3ltYm9sIGMsIFNldDxNb2R1bGVTeW1ib2w+IG1vZHVsZXMpIHsKICAgICAgICBib29sZWFuIGlzTW9kdWxlSW5mbyA9IHRvcGxldmVsLnNvdXJjZWZpbGUuaXNOYW1lQ29tcGF0aWJsZSgibW9kdWxlLWluZm8iLCBLaW5kLlNPVVJDRSk7CiAgICAgICAgYm9vbGVhbiBpc01vZHVsZURlY2wgPSB0b3BsZXZlbC5nZXRNb2R1bGVEZWNsKCkgIT0gbnVsbDsKICAgICAgICBpZiAoaXNNb2R1bGVEZWNsKSB7CiAgICAgICAgICAgIEpDTW9kdWxlRGVjbCBkZWNsID0gdG9wbGV2ZWwuZ2V0TW9kdWxlRGVjbCgpOwogICAgICAgICAgICBpZiAoIWlzTW9kdWxlSW5mbykgewogICAgICAgICAgICAgICAgbG9nLmVycm9yKGRlY2wucG9zKCksIEVycm9ycy5Nb2R1bGVEZWNsU2JJbk1vZHVsZUluZm9KYXZhKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBOYW1lIG5hbWUgPSBUcmVlSW5mby5mdWxsTmFtZShkZWNsLnF1YWxJZCk7CiAgICAgICAgICAgIE1vZHVsZVN5bWJvbCBzeW07CiAgICAgICAgICAgIGlmIChjICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIHN5bSA9IChNb2R1bGVTeW1ib2wpIGMub3duZXI7CiAgICAgICAgICAgICAgICBBc3NlcnQuY2hlY2tOb25OdWxsKHN5bS5uYW1lKTsKICAgICAgICAgICAgICAgIE5hbWUgdHJlZU5hbWUgPSBUcmVlSW5mby5mdWxsTmFtZShkZWNsLnF1YWxJZCk7CiAgICAgICAgICAgICAgICBpZiAoc3ltLm5hbWUgIT0gdHJlZU5hbWUpIHsKICAgICAgICAgICAgICAgICAgICBsb2cuZXJyb3IoZGVjbC5wb3MoKSwgRXJyb3JzLk1vZHVsZU5hbWVNaXNtYXRjaChuYW1lLCBzeW0ubmFtZSkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgc3ltID0gc3ltcy5lbnRlck1vZHVsZShuYW1lKTsKICAgICAgICAgICAgICAgIGlmIChzeW0ubW9kdWxlX2luZm8uc291cmNlZmlsZSAhPSBudWxsICYmIHN5bS5tb2R1bGVfaW5mby5zb3VyY2VmaWxlICE9IHRvcGxldmVsLnNvdXJjZWZpbGUpIHsKICAgICAgICAgICAgICAgICAgICBsb2cuZXJyb3IoZGVjbC5wb3MoKSwgRXJyb3JzLkR1cGxpY2F0ZU1vZHVsZShzeW0pKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc3ltLmNvbXBsZXRlciA9IGdldFNvdXJjZUNvbXBsZXRlcih0b3BsZXZlbCk7CiAgICAgICAgICAgIHN5bS5tb2R1bGVfaW5mby5zb3VyY2VmaWxlID0gdG9wbGV2ZWwuc291cmNlZmlsZTsKICAgICAgICAgICAgZGVjbC5zeW0gPSBzeW07CgogICAgICAgICAgICBpZiAobXVsdGlNb2R1bGVNb2RlIHx8IG1vZHVsZXMuaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgICBtb2R1bGVzLmFkZChzeW0pOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgbG9nLmVycm9yKHRvcGxldmVsLnBvcygpLCBFcnJvcnMuVG9vTWFueU1vZHVsZXMpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBFbnY8QXR0ckNvbnRleHQ+IHByb3Zpc2lvbmFsRW52ID0gbmV3IEVudjw+KGRlY2wsIG51bGwpOwoKICAgICAgICAgICAgcHJvdmlzaW9uYWxFbnYudG9wbGV2ZWwgPSB0b3BsZXZlbDsKICAgICAgICAgICAgdHlwZUVudnMucHV0KHN5bSwgcHJvdmlzaW9uYWxFbnYpOwogICAgICAgIH0gZWxzZSBpZiAoaXNNb2R1bGVJbmZvKSB7CiAgICAgICAgICAgIGlmIChtdWx0aU1vZHVsZU1vZGUpIHsKICAgICAgICAgICAgICAgIEpDVHJlZSB0cmVlID0gdG9wbGV2ZWwuZGVmcy5pc0VtcHR5KCkgPyB0b3BsZXZlbCA6IHRvcGxldmVsLmRlZnMuaGVhZDsKICAgICAgICAgICAgICAgIGxvZy5lcnJvcih0cmVlLnBvcygpLCBFcnJvcnMuRXhwZWN0ZWRNb2R1bGUpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgdm9pZCBzZXRDb21waWxhdGlvblVuaXRNb2R1bGVzKExpc3Q8SkNDb21waWxhdGlvblVuaXQ+IHRyZWVzLCBTZXQ8TW9kdWxlU3ltYm9sPiByb290TW9kdWxlcywgQ2xhc3NTeW1ib2wgYykgewogICAgICAgIC8vIHVwZGF0ZSB0aGUgbW9kdWxlIGZvciBlYWNoIGNvbXBpbGF0aW9uIHVuaXQKICAgICAgICBpZiAobXVsdGlNb2R1bGVNb2RlKSB7CiAgICAgICAgICAgIGNoZWNrTm9BbGxNb2R1bGVQYXRoKCk7CiAgICAgICAgICAgIGZvciAoSkNDb21waWxhdGlvblVuaXQgdHJlZTogdHJlZXMpIHsKICAgICAgICAgICAgICAgIGlmICh0cmVlLmRlZnMuaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgICAgICAgdHJlZS5tb2RsZSA9IHN5bXMudW5uYW1lZE1vZHVsZTsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBKYXZhRmlsZU9iamVjdCBwcmV2ID0gbG9nLnVzZVNvdXJjZSh0cmVlLnNvdXJjZWZpbGUpOwogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICBMb2NhdGlvbiBtc3Bsb2NuID0gZ2V0TW9kdWxlTG9jYXRpb24odHJlZSk7CiAgICAgICAgICAgICAgICAgICAgTG9jYXRpb24gcGxvY24gPSBmaWxlTWFuYWdlci5oYXNMb2NhdGlvbihTdGFuZGFyZExvY2F0aW9uLlBBVENIX01PRFVMRV9QQVRIKSA/CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlTWFuYWdlci5nZXRMb2NhdGlvbkZvck1vZHVsZShTdGFuZGFyZExvY2F0aW9uLlBBVENIX01PRFVMRV9QQVRILAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJlZS5zb3VyY2VmaWxlKSA6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsOwoKICAgICAgICAgICAgICAgICAgICBpZiAocGxvY24gIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICBOYW1lIG5hbWUgPSBuYW1lcy5mcm9tU3RyaW5nKGZpbGVNYW5hZ2VyLmluZmVyTW9kdWxlTmFtZShwbG9jbikpOwogICAgICAgICAgICAgICAgICAgICAgICBNb2R1bGVTeW1ib2wgbXN5bSA9IG1vZHVsZUZpbmRlci5maW5kTW9kdWxlKG5hbWUpOwogICAgICAgICAgICAgICAgICAgICAgICB0cmVlLm1vZGxlID0gbXN5bTsKICAgICAgICAgICAgICAgICAgICAgICAgcm9vdE1vZHVsZXMuYWRkKG1zeW0pOwoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG1zcGxvY24gIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgTmFtZSBtc3BuYW1lID0gbmFtZXMuZnJvbVN0cmluZyhmaWxlTWFuYWdlci5pbmZlck1vZHVsZU5hbWUobXNwbG9jbikpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5hbWUgIT0gbXNwbmFtZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZy5lcnJvcih0cmVlLnBvcygpLCBFcnJvcnMuRmlsZVBhdGNoZWRBbmRNc3AobmFtZSwgbXNwbmFtZSkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChtc3Bsb2NuICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRyZWUuZ2V0TW9kdWxlRGVjbCgpICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEphdmFGaWxlT2JqZWN0IGNhbm9uaWNhbCA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVNYW5hZ2VyLmdldEphdmFGaWxlRm9ySW5wdXQobXNwbG9jbiwgIm1vZHVsZS1pbmZvIiwgS2luZC5TT1VSQ0UpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNhbm9uaWNhbCA9PSBudWxsIHx8ICFmaWxlTWFuYWdlci5pc1NhbWVGaWxlKGNhbm9uaWNhbCwgdHJlZS5zb3VyY2VmaWxlKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZy5lcnJvcih0cmVlLnBvcygpLCBFcnJvcnMuTW9kdWxlTm90Rm91bmRPbk1vZHVsZVNvdXJjZVBhdGgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIE5hbWUgbmFtZSA9IG5hbWVzLmZyb21TdHJpbmcoZmlsZU1hbmFnZXIuaW5mZXJNb2R1bGVOYW1lKG1zcGxvY24pKTsKICAgICAgICAgICAgICAgICAgICAgICAgTW9kdWxlU3ltYm9sIG1zeW07CiAgICAgICAgICAgICAgICAgICAgICAgIEpDTW9kdWxlRGVjbCBkZWNsID0gdHJlZS5nZXRNb2R1bGVEZWNsKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkZWNsICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1zeW0gPSBkZWNsLnN5bTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChtc3ltLm5hbWUgIT0gbmFtZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZy5lcnJvcihkZWNsLnF1YWxJZCwgRXJyb3JzLk1vZHVsZU5hbWVNaXNtYXRjaChtc3ltLm5hbWUsIG5hbWUpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0cmVlLmdldFBhY2thZ2UoKSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9nLmVycm9yKHRyZWUucG9zKCksIEVycm9ycy5Vbm5hbWVkUGtnTm90QWxsb3dlZE5hbWVkTW9kdWxlcyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtc3ltID0gc3ltcy5lbnRlck1vZHVsZShuYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBpZiAobXN5bS5zb3VyY2VMb2NhdGlvbiA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtc3ltLnNvdXJjZUxvY2F0aW9uID0gbXNwbG9jbjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmaWxlTWFuYWdlci5oYXNMb2NhdGlvbihTdGFuZGFyZExvY2F0aW9uLkNMQVNTX09VVFBVVCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtc3ltLmNsYXNzTG9jYXRpb24gPSBmaWxlTWFuYWdlci5nZXRMb2NhdGlvbkZvck1vZHVsZSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0YW5kYXJkTG9jYXRpb24uQ0xBU1NfT1VUUFVULCBtc3ltLm5hbWUudG9TdHJpbmcoKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgdHJlZS5tb2RsZSA9IG1zeW07CiAgICAgICAgICAgICAgICAgICAgICAgIHJvb3RNb2R1bGVzLmFkZChtc3ltKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGMgIT0gbnVsbCAmJiBjLnBhY2tnZSgpLm1vZGxlID09IHN5bXMudW5uYW1lZE1vZHVsZSkgewogICAgICAgICAgICAgICAgICAgICAgICB0cmVlLm1vZGxlID0gc3ltcy51bm5hbWVkTW9kdWxlOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0cmVlLmdldE1vZHVsZURlY2woKSAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2cuZXJyb3IodHJlZS5wb3MoKSwgRXJyb3JzLk1vZHVsZU5vdEZvdW5kT25Nb2R1bGVTb3VyY2VQYXRoKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZy5lcnJvcih0cmVlLnBvcygpLCBFcnJvcnMuTm90SW5Nb2R1bGVPbk1vZHVsZVNvdXJjZVBhdGgpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIHRyZWUubW9kbGUgPSBzeW1zLmVyck1vZHVsZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGUpOyAvLyBGSVhNRQogICAgICAgICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgICAgICAgICBsb2cudXNlU291cmNlKHByZXYpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChzeW1zLnVubmFtZWRNb2R1bGUuc291cmNlTG9jYXRpb24gPT0gbnVsbCkgewogICAgICAgICAgICAgICAgc3ltcy51bm5hbWVkTW9kdWxlLmNvbXBsZXRlciA9IGdldFVubmFtZWRNb2R1bGVDb21wbGV0ZXIoKTsKICAgICAgICAgICAgICAgIHN5bXMudW5uYW1lZE1vZHVsZS5zb3VyY2VMb2NhdGlvbiA9IFN0YW5kYXJkTG9jYXRpb24uU09VUkNFX1BBVEg7CiAgICAgICAgICAgICAgICBzeW1zLnVubmFtZWRNb2R1bGUuY2xhc3NMb2NhdGlvbiA9IFN0YW5kYXJkTG9jYXRpb24uQ0xBU1NfUEFUSDsKICAgICAgICAgICAgfQogICAgICAgICAgICBkZWZhdWx0TW9kdWxlID0gc3ltcy51bm5hbWVkTW9kdWxlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIE1vZHVsZVN5bWJvbCBtb2R1bGUgPSBudWxsOwogICAgICAgICAgICBpZiAoZGVmYXVsdE1vZHVsZSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICBTdHJpbmcgbW9kdWxlT3ZlcnJpZGUgPSBzaW5nbGVNb2R1bGVPdmVycmlkZSh0cmVlcyk7CiAgICAgICAgICAgICAgICBzd2l0Y2ggKHJvb3RNb2R1bGVzLnNpemUoKSkgewogICAgICAgICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdE1vZHVsZSA9IG1vZHVsZUZpbmRlci5maW5kU2luZ2xlTW9kdWxlKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkZWZhdWx0TW9kdWxlID09IHN5bXMudW5uYW1lZE1vZHVsZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG1vZHVsZU92ZXJyaWRlICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGVja05vQWxsTW9kdWxlUGF0aCgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHRNb2R1bGUgPSBtb2R1bGVGaW5kZXIuZmluZE1vZHVsZShuYW1lcy5mcm9tU3RyaW5nKG1vZHVsZU92ZXJyaWRlKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGxlZ2FjeU1vZHVsZU92ZXJyaWRlICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdE1vZHVsZS5zb3VyY2VMb2NhdGlvbiA9IFN0YW5kYXJkTG9jYXRpb24uU09VUkNFX1BBVEg7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHRNb2R1bGUucGF0Y2hPdXRwdXRMb2NhdGlvbiA9IFN0YW5kYXJkTG9jYXRpb24uQ0xBU1NfT1VUUFVUOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBRdWVzdGlvbjogd2h5IG5vdCBkbyBmaW5kQWxsTW9kdWxlcyBhbmQgaW5pdFZpc2libGVQYWNrYWdlcyBoZXJlPwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGkuZS4gYm9keSBvZiB1bm5hbWVkTW9kdWxlQ29tcGxldGVyCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdE1vZHVsZS5jb21wbGV0ZXIgPSBnZXRVbm5hbWVkTW9kdWxlQ29tcGxldGVyKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdE1vZHVsZS5zb3VyY2VMb2NhdGlvbiA9IFN0YW5kYXJkTG9jYXRpb24uU09VUkNFX1BBVEg7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdE1vZHVsZS5jbGFzc0xvY2F0aW9uID0gU3RhbmRhcmRMb2NhdGlvbi5DTEFTU19QQVRIOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tTcGVjaWZpZWRNb2R1bGUodHJlZXMsIG1vZHVsZU92ZXJyaWRlLCBFcnJvcnMuTW9kdWxlSW5mb1dpdGhQYXRjaGVkTW9kdWxlQ2xhc3NvdXRwdXQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tOb0FsbE1vZHVsZVBhdGgoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHRNb2R1bGUuY29tcGxldGUoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFF1ZXN0aW9uOiB3aHkgbm90IGRvIGNvbXBsZXRlTW9kdWxlIGhlcmU/CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0TW9kdWxlLmNvbXBsZXRlciA9IHN5bSAtPiBjb21wbGV0ZU1vZHVsZSgoTW9kdWxlU3ltYm9sKSBzeW0pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdE1vZHVsZS5zb3VyY2VMb2NhdGlvbiA9IFN0YW5kYXJkTG9jYXRpb24uU09VUkNFX1BBVEg7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgcm9vdE1vZHVsZXMuYWRkKGRlZmF1bHRNb2R1bGUpOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICBjYXNlIDE6CiAgICAgICAgICAgICAgICAgICAgICAgIGNoZWNrU3BlY2lmaWVkTW9kdWxlKHRyZWVzLCBtb2R1bGVPdmVycmlkZSwgRXJyb3JzLk1vZHVsZUluZm9XaXRoUGF0Y2hlZE1vZHVsZVNvdXJjZXBhdGgpOwogICAgICAgICAgICAgICAgICAgICAgICBjaGVja05vQWxsTW9kdWxlUGF0aCgpOwogICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0TW9kdWxlID0gcm9vdE1vZHVsZXMuaXRlcmF0b3IoKS5uZXh0KCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHRNb2R1bGUuc291cmNlTG9jYXRpb24gPSBTdGFuZGFyZExvY2F0aW9uLlNPVVJDRV9QQVRIOwogICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0TW9kdWxlLmNsYXNzTG9jYXRpb24gPSBTdGFuZGFyZExvY2F0aW9uLkNMQVNTX09VVFBVVDsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgICAgQXNzZXJ0LmVycm9yKCJ0b28gbWFueSBtb2R1bGVzIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSBpZiAocm9vdE1vZHVsZXMuc2l6ZSgpID09IDEgJiYgZGVmYXVsdE1vZHVsZSA9PSByb290TW9kdWxlcy5pdGVyYXRvcigpLm5leHQoKSkgewogICAgICAgICAgICAgICAgZGVmYXVsdE1vZHVsZS5jb21wbGV0ZSgpOwogICAgICAgICAgICAgICAgZGVmYXVsdE1vZHVsZS5jb21wbGV0ZXIgPSBzeW0gLT4gY29tcGxldGVNb2R1bGUoKE1vZHVsZVN5bWJvbCkgc3ltKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIEFzc2VydC5jaGVjayhyb290TW9kdWxlcy5pc0VtcHR5KCkpOwogICAgICAgICAgICAgICAgU3RyaW5nIG1vZHVsZU92ZXJyaWRlID0gc2luZ2xlTW9kdWxlT3ZlcnJpZGUodHJlZXMpOwogICAgICAgICAgICAgICAgaWYgKG1vZHVsZU92ZXJyaWRlICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICBtb2R1bGUgPSBtb2R1bGVGaW5kZXIuZmluZE1vZHVsZShuYW1lcy5mcm9tU3RyaW5nKG1vZHVsZU92ZXJyaWRlKSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIG1vZHVsZSA9IGRlZmF1bHRNb2R1bGU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByb290TW9kdWxlcy5hZGQobW9kdWxlKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKGRlZmF1bHRNb2R1bGUgIT0gc3ltcy51bm5hbWVkTW9kdWxlKSB7CiAgICAgICAgICAgICAgICBzeW1zLnVubmFtZWRNb2R1bGUuY29tcGxldGVyID0gZ2V0VW5uYW1lZE1vZHVsZUNvbXBsZXRlcigpOwogICAgICAgICAgICAgICAgc3ltcy51bm5hbWVkTW9kdWxlLmNsYXNzTG9jYXRpb24gPSBTdGFuZGFyZExvY2F0aW9uLkNMQVNTX1BBVEg7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChtb2R1bGUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgbW9kdWxlID0gZGVmYXVsdE1vZHVsZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZm9yIChKQ0NvbXBpbGF0aW9uVW5pdCB0cmVlOiB0cmVlcykgewogICAgICAgICAgICAgICAgdHJlZS5tb2RsZSA9IG1vZHVsZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIFN0cmluZyBzaW5nbGVNb2R1bGVPdmVycmlkZShMaXN0PEpDQ29tcGlsYXRpb25Vbml0PiB0cmVlcykgewogICAgICAgIGlmICghZmlsZU1hbmFnZXIuaGFzTG9jYXRpb24oU3RhbmRhcmRMb2NhdGlvbi5QQVRDSF9NT0RVTEVfUEFUSCkpIHsKICAgICAgICAgICAgcmV0dXJuIGxlZ2FjeU1vZHVsZU92ZXJyaWRlOwogICAgICAgIH0KCiAgICAgICAgU2V0PFN0cmluZz4gb3ZlcnJpZGUgPSBuZXcgTGlua2VkSGFzaFNldDw+KCk7CiAgICAgICAgZm9yIChKQ0NvbXBpbGF0aW9uVW5pdCB0cmVlIDogdHJlZXMpIHsKICAgICAgICAgICAgSmF2YUZpbGVPYmplY3QgZm8gPSB0cmVlLnNvdXJjZWZpbGU7CgogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgTG9jYXRpb24gbG9jID0KICAgICAgICAgICAgICAgICAgICAgICAgZmlsZU1hbmFnZXIuZ2V0TG9jYXRpb25Gb3JNb2R1bGUoU3RhbmRhcmRMb2NhdGlvbi5QQVRDSF9NT0RVTEVfUEFUSCwgZm8pOwoKICAgICAgICAgICAgICAgIGlmIChsb2MgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIG92ZXJyaWRlLmFkZChmaWxlTWFuYWdlci5pbmZlck1vZHVsZU5hbWUobG9jKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXgpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBzd2l0Y2ggKG92ZXJyaWRlLnNpemUoKSkgewogICAgICAgICAgICBjYXNlIDA6IHJldHVybiBsZWdhY3lNb2R1bGVPdmVycmlkZTsKICAgICAgICAgICAgY2FzZSAxOiByZXR1cm4gb3ZlcnJpZGUuaXRlcmF0b3IoKS5uZXh0KCk7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICBsb2cuZXJyb3IoRXJyb3JzLlRvb01hbnlQYXRjaGVkTW9kdWxlcyhvdmVycmlkZSkpOwogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogRGV0ZXJtaW5lIHRoZSBsb2NhdGlvbiBmb3IgdGhlIG1vZHVsZSBvbiB0aGUgbW9kdWxlIHNvdXJjZSBwYXRoCiAgICAgKiBvciBzb3VyY2Ugb3V0cHV0IGRpcmVjdG9yeSB3aGljaCBjb250YWlucyBhIGdpdmVuIENvbXBpbGF0aW9uVW5pdC4KICAgICAqIElmIHRoZSBzb3VyY2Ugb3V0cHV0IGRpcmVjdG9yeSBpcyB1bnNldCwgdGhlIGNsYXNzIG91dHB1dCBkaXJlY3RvcnkKICAgICAqIHdpbGwgYmUgY2hlY2tlZCBpbnN0ZWFkLgogICAgICoge0Bjb2RlIG51bGx9IGlzIHJldHVybmVkIGlmIG5vIHN1Y2ggbW9kdWxlIGNhbiBiZSBmb3VuZC4KICAgICAqIEBwYXJhbSB0cmVlIHRoZSBjb21waWxhdGlvbiB1bml0IHRyZWUKICAgICAqIEByZXR1cm4gdGhlIGxvY2F0aW9uIGZvciB0aGUgZW5jbG9zaW5nIG1vZHVsZQogICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiB0aGVyZSBpcyBhIHByb2JsZW0gd2hpbGUgc2VhcmNoaW5nIGZvciB0aGUgbW9kdWxlLgogICAgICovCiAgICBwcml2YXRlIExvY2F0aW9uIGdldE1vZHVsZUxvY2F0aW9uKEpDQ29tcGlsYXRpb25Vbml0IHRyZWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgSmF2YUZpbGVPYmplY3QgZm8gPSB0cmVlLnNvdXJjZWZpbGU7CgogICAgICAgIExvY2F0aW9uIGxvYyA9CiAgICAgICAgICAgICAgICBmaWxlTWFuYWdlci5nZXRMb2NhdGlvbkZvck1vZHVsZShTdGFuZGFyZExvY2F0aW9uLk1PRFVMRV9TT1VSQ0VfUEFUSCwgZm8pOwogICAgICAgIGlmIChsb2MgPT0gbnVsbCkgewogICAgICAgICAgICBMb2NhdGlvbiBzb3VyY2VPdXRwdXQgPSBmaWxlTWFuYWdlci5oYXNMb2NhdGlvbihTdGFuZGFyZExvY2F0aW9uLlNPVVJDRV9PVVRQVVQpID8KICAgICAgICAgICAgICAgICAgICBTdGFuZGFyZExvY2F0aW9uLlNPVVJDRV9PVVRQVVQgOiBTdGFuZGFyZExvY2F0aW9uLkNMQVNTX09VVFBVVDsKICAgICAgICAgICAgbG9jID0KICAgICAgICAgICAgICAgIGZpbGVNYW5hZ2VyLmdldExvY2F0aW9uRm9yTW9kdWxlKHNvdXJjZU91dHB1dCwgZm8pOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbG9jOwogICAgfQoKICAgIHByaXZhdGUgdm9pZCBjaGVja1NwZWNpZmllZE1vZHVsZShMaXN0PEpDQ29tcGlsYXRpb25Vbml0PiB0cmVlcywgU3RyaW5nIG1vZHVsZU92ZXJyaWRlLCBKQ0RpYWdub3N0aWMuRXJyb3IgZXJyb3IpIHsKICAgICAgICBpZiAobW9kdWxlT3ZlcnJpZGUgIT0gbnVsbCkgewogICAgICAgICAgICBKYXZhRmlsZU9iamVjdCBwcmV2ID0gbG9nLnVzZVNvdXJjZSh0cmVlcy5oZWFkLnNvdXJjZWZpbGUpOwogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgbG9nLmVycm9yKHRyZWVzLmhlYWQucG9zKCksIGVycm9yKTsKICAgICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgICAgIGxvZy51c2VTb3VyY2UocHJldik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgcHJpdmF0ZSB2b2lkIGNoZWNrTm9BbGxNb2R1bGVQYXRoKCkgewogICAgICAgIGlmIChhZGRNb2RzT3B0ICE9IG51bGwgJiYgQXJyYXlzLmFzTGlzdChhZGRNb2RzT3B0LnNwbGl0KCIsIikpLmNvbnRhaW5zKEFMTF9NT0RVTEVfUEFUSCkpIHsKICAgICAgICAgICAgbG9nLmVycm9yKEVycm9ycy5BZGRtb2RzQWxsTW9kdWxlUGF0aEludmFsaWQpOwogICAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIGZpbmFsIENvbXBsZXRlciBtYWluQ29tcGxldGVyID0gbmV3IENvbXBsZXRlcigpIHsKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCBjb21wbGV0ZShTeW1ib2wgc3ltKSB0aHJvd3MgQ29tcGxldGlvbkZhaWx1cmUgewogICAgICAgICAgICBNb2R1bGVTeW1ib2wgbXN5bSA9IG1vZHVsZUZpbmRlci5maW5kTW9kdWxlKChNb2R1bGVTeW1ib2wpIHN5bSk7CgogICAgICAgICAgICBpZiAobXN5bS5raW5kID09IEVSUikgewogICAgICAgICAgICAgICAgLy9tYWtlIHN1cmUgdGhlIG1vZHVsZSBpcyBpbml0aWFsaXplZDoKICAgICAgICAgICAgICAgIG1zeW0uZGlyZWN0aXZlcyA9IExpc3QubmlsKCk7CiAgICAgICAgICAgICAgICBtc3ltLmV4cG9ydHMgPSBMaXN0Lm5pbCgpOwogICAgICAgICAgICAgICAgbXN5bS5wcm92aWRlcyA9IExpc3QubmlsKCk7CiAgICAgICAgICAgICAgICBtc3ltLnJlcXVpcmVzID0gTGlzdC5uaWwoKTsKICAgICAgICAgICAgICAgIG1zeW0udXNlcyA9IExpc3QubmlsKCk7CiAgICAgICAgICAgIH0gZWxzZSBpZiAoKG1zeW0uZmxhZ3NfZmllbGQgJiBGbGFncy5BVVRPTUFUSUNfTU9EVUxFKSAhPSAwKSB7CiAgICAgICAgICAgICAgICBzZXR1cEF1dG9tYXRpY01vZHVsZShtc3ltKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIG1zeW0ubW9kdWxlX2luZm8uY29tcGxldGUoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gSWYgbW9kdWxlLWluZm8gY29tZXMgZnJvbSBhIC5qYXZhIGZpbGUsIHRoZSB1bmRlcmx5aW5nCiAgICAgICAgICAgIC8vIGNhbGwgb2YgY2xhc3NGaW5kZXIuZmlsbEluIHdpbGwgaGF2ZSBjYWxsZWQgdGhyb3VnaCB0aGUKICAgICAgICAgICAgLy8gc291cmNlIGNvbXBsZXRlciwgdG8gRW50ZXIsIGFuZCB0aGVuIHRvIE1vZHVsZXMuZW50ZXIsCiAgICAgICAgICAgIC8vIHdoaWNoIHdpbGwgY2FsbCBjb21wbGV0ZU1vZHVsZS4KICAgICAgICAgICAgLy8gQnV0LCBpZiBtb2R1bGUtaW5mbyBjb21lcyBmcm9tIGEgLmNsYXNzIGZpbGUsIHRoZSB1bmRlcmx5aW5nCiAgICAgICAgICAgIC8vIGNhbGwgb2YgY2xhc3NGaW5kZXIuZmlsbEluIHdpbGwganVzdCBjYWxsIENsYXNzUmVhZGVyIHRvIHJlYWQKICAgICAgICAgICAgLy8gdGhlIC5jbGFzcyBmaWxlLCBhbmQgc28gd2UgY2FsbCBjb21wbGV0ZU1vZHVsZSBoZXJlLgogICAgICAgICAgICBpZiAobXN5bS5tb2R1bGVfaW5mby5jbGFzc2ZpbGUgPT0gbnVsbCB8fCBtc3ltLm1vZHVsZV9pbmZvLmNsYXNzZmlsZS5nZXRLaW5kKCkgPT0gS2luZC5DTEFTUykgewogICAgICAgICAgICAgICAgY29tcGxldGVNb2R1bGUobXN5bSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CiAgICAgICAgICAgIHJldHVybiAibWFpbkNvbXBsZXRlciI7CiAgICAgICAgfQogICAgfTsKCiAgICBwcml2YXRlIHZvaWQgc2V0dXBBdXRvbWF0aWNNb2R1bGUoTW9kdWxlU3ltYm9sIG1zeW0pIHRocm93cyBDb21wbGV0aW9uRmFpbHVyZSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgTGlzdEJ1ZmZlcjxEaXJlY3RpdmU+IGRpcmVjdGl2ZXMgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgIExpc3RCdWZmZXI8RXhwb3J0c0RpcmVjdGl2ZT4gZXhwb3J0cyA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICAgICAgU2V0PFN0cmluZz4gc2VlblBhY2thZ2VzID0gbmV3IEhhc2hTZXQ8PigpOwoKICAgICAgICAgICAgZm9yIChKYXZhRmlsZU9iamVjdCBjbGF6eiA6IGZpbGVNYW5hZ2VyLmxpc3QobXN5bS5jbGFzc0xvY2F0aW9uLCAiIiwgRW51bVNldC5vZihLaW5kLkNMQVNTKSwgdHJ1ZSkpIHsKICAgICAgICAgICAgICAgIFN0cmluZyBiaW5OYW1lID0gZmlsZU1hbmFnZXIuaW5mZXJCaW5hcnlOYW1lKG1zeW0uY2xhc3NMb2NhdGlvbiwgY2xhenopOwogICAgICAgICAgICAgICAgU3RyaW5nIHBhY2sgPSBiaW5OYW1lLmxhc3RJbmRleE9mKCcuJykgIT0gKC0xKSA/IGJpbk5hbWUuc3Vic3RyaW5nKDAsIGJpbk5hbWUubGFzdEluZGV4T2YoJy4nKSkgOiAiIjsgLy91bm5hbWVkIHBhY2thZ2U/Pz8/CiAgICAgICAgICAgICAgICBpZiAoc2VlblBhY2thZ2VzLmFkZChwYWNrKSkgewogICAgICAgICAgICAgICAgICAgIEV4cG9ydHNEaXJlY3RpdmUgZCA9IG5ldyBFeHBvcnRzRGlyZWN0aXZlKHN5bXMuZW50ZXJQYWNrYWdlKG1zeW0sIG5hbWVzLmZyb21TdHJpbmcocGFjaykpLCBudWxsKTsKICAgICAgICAgICAgICAgICAgICAvL1RPRE86IG9wZW5zPwogICAgICAgICAgICAgICAgICAgIGRpcmVjdGl2ZXMuYWRkKGQpOwogICAgICAgICAgICAgICAgICAgIGV4cG9ydHMuYWRkKGQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBtc3ltLmV4cG9ydHMgPSBleHBvcnRzLnRvTGlzdCgpOwogICAgICAgICAgICBtc3ltLnByb3ZpZGVzID0gTGlzdC5uaWwoKTsKICAgICAgICAgICAgbXN5bS5yZXF1aXJlcyA9IExpc3QubmlsKCk7CiAgICAgICAgICAgIG1zeW0udXNlcyA9IExpc3QubmlsKCk7CiAgICAgICAgICAgIG1zeW0uZGlyZWN0aXZlcyA9IGRpcmVjdGl2ZXMudG9MaXN0KCk7CiAgICAgICAgICAgIG1zeW0uZmxhZ3NfZmllbGQgfD0gRmxhZ3MuQUNZQ0xJQzsKICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgewogICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKGV4KTsKICAgICAgICB9CiAgICB9CgogICAgcHJpdmF0ZSB2b2lkIGNvbXBsZXRlQXV0b21hdGljTW9kdWxlKE1vZHVsZVN5bWJvbCBtc3ltKSB0aHJvd3MgQ29tcGxldGlvbkZhaWx1cmUgewogICAgICAgIExpc3RCdWZmZXI8RGlyZWN0aXZlPiBkaXJlY3RpdmVzID0gbmV3IExpc3RCdWZmZXI8PigpOwoKICAgICAgICBkaXJlY3RpdmVzLmFkZEFsbChtc3ltLmRpcmVjdGl2ZXMpOwoKICAgICAgICBMaXN0QnVmZmVyPFJlcXVpcmVzRGlyZWN0aXZlPiByZXF1aXJlcyA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKCiAgICAgICAgZm9yIChNb2R1bGVTeW1ib2wgbXMgOiBhbGxNb2R1bGVzKCkpIHsKICAgICAgICAgICAgaWYgKG1zID09IHN5bXMudW5uYW1lZE1vZHVsZSB8fCBtcyA9PSBtc3ltKQogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIFNldDxSZXF1aXJlc0ZsYWc+IGZsYWdzID0gKG1zLmZsYWdzX2ZpZWxkICYgRmxhZ3MuQVVUT01BVElDX01PRFVMRSkgIT0gMCA/CiAgICAgICAgICAgICAgICAgICAgRW51bVNldC5vZihSZXF1aXJlc0ZsYWcuVFJBTlNJVElWRSkgOiBFbnVtU2V0Lm5vbmVPZihSZXF1aXJlc0ZsYWcuY2xhc3MpOwogICAgICAgICAgICBSZXF1aXJlc0RpcmVjdGl2ZSBkID0gbmV3IFJlcXVpcmVzRGlyZWN0aXZlKG1zLCBmbGFncyk7CiAgICAgICAgICAgIGRpcmVjdGl2ZXMuYWRkKGQpOwogICAgICAgICAgICByZXF1aXJlcy5hZGQoZCk7CiAgICAgICAgfQoKICAgICAgICBSZXF1aXJlc0RpcmVjdGl2ZSByZXF1aXJlc1VubmFtZWQgPSBuZXcgUmVxdWlyZXNEaXJlY3RpdmUoc3ltcy51bm5hbWVkTW9kdWxlKTsKICAgICAgICBkaXJlY3RpdmVzLmFkZChyZXF1aXJlc1VubmFtZWQpOwogICAgICAgIHJlcXVpcmVzLmFkZChyZXF1aXJlc1VubmFtZWQpOwoKICAgICAgICBtc3ltLnJlcXVpcmVzID0gcmVxdWlyZXMudG9MaXN0KCk7CiAgICAgICAgbXN5bS5kaXJlY3RpdmVzID0gZGlyZWN0aXZlcy50b0xpc3QoKTsKICAgIH0KCiAgICBwcml2YXRlIENvbXBsZXRlciBnZXRTb3VyY2VDb21wbGV0ZXIoSkNDb21waWxhdGlvblVuaXQgdHJlZSkgewogICAgICAgIHJldHVybiBuZXcgQ29tcGxldGVyKCkgewogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHVibGljIHZvaWQgY29tcGxldGUoU3ltYm9sIHN5bSkgdGhyb3dzIENvbXBsZXRpb25GYWlsdXJlIHsKICAgICAgICAgICAgICAgIE1vZHVsZVN5bWJvbCBtc3ltID0gKE1vZHVsZVN5bWJvbCkgc3ltOwogICAgICAgICAgICAgICAgbXN5bS5mbGFnc19maWVsZCB8PSBVTkFUVFJJQlVURUQ7CiAgICAgICAgICAgICAgICBNb2R1bGVWaXNpdG9yIHYgPSBuZXcgTW9kdWxlVmlzaXRvcigpOwogICAgICAgICAgICAgICAgSmF2YUZpbGVPYmplY3QgcHJldiA9IGxvZy51c2VTb3VyY2UodHJlZS5zb3VyY2VmaWxlKTsKICAgICAgICAgICAgICAgIEpDTW9kdWxlRGVjbCBtb2R1bGVEZWNsID0gdHJlZS5nZXRNb2R1bGVEZWNsKCk7CiAgICAgICAgICAgICAgICBEaWFnbm9zdGljUG9zaXRpb24gcHJldkxpbnRQb3MgPSBkZWZlcnJlZExpbnRIYW5kbGVyLnNldFBvcyhtb2R1bGVEZWNsLnBvcygpKTsKCiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIG1vZHVsZURlY2wuYWNjZXB0KHYpOwogICAgICAgICAgICAgICAgICAgIGNvbXBsZXRlTW9kdWxlKG1zeW0pOwogICAgICAgICAgICAgICAgICAgIGNoZWNrQ3ljbGljRGVwZW5kZW5jaWVzKG1vZHVsZURlY2wpOwogICAgICAgICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgICAgICAgICBsb2cudXNlU291cmNlKHByZXYpOwogICAgICAgICAgICAgICAgICAgIGRlZmVycmVkTGludEhhbmRsZXIuc2V0UG9zKHByZXZMaW50UG9zKTsKICAgICAgICAgICAgICAgICAgICBtc3ltLmZsYWdzX2ZpZWxkICY9IH5VTkFUVFJJQlVURUQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewogICAgICAgICAgICAgICAgcmV0dXJuICJTb3VyY2VDb21wbGV0ZXI6ICIgKyB0cmVlLnNvdXJjZWZpbGUuZ2V0TmFtZSgpOwogICAgICAgICAgICB9CgogICAgICAgIH07CiAgICB9CgogICAgcHVibGljIGJvb2xlYW4gaXNSb290TW9kdWxlKE1vZHVsZVN5bWJvbCBtb2R1bGUpIHsKICAgICAgICBBc3NlcnQuY2hlY2tOb25OdWxsKHJvb3RNb2R1bGVzKTsKICAgICAgICByZXR1cm4gcm9vdE1vZHVsZXMuY29udGFpbnMobW9kdWxlKTsKICAgIH0KCiAgICBjbGFzcyBNb2R1bGVWaXNpdG9yIGV4dGVuZHMgSkNUcmVlLlZpc2l0b3IgewogICAgICAgIHByaXZhdGUgTW9kdWxlU3ltYm9sIHN5bTsKICAgICAgICBwcml2YXRlIGZpbmFsIFNldDxNb2R1bGVTeW1ib2w+IGFsbFJlcXVpcmVzID0gbmV3IEhhc2hTZXQ8PigpOwogICAgICAgIHByaXZhdGUgZmluYWwgTWFwPFBhY2thZ2VTeW1ib2wsTGlzdDxFeHBvcnRzRGlyZWN0aXZlPj4gYWxsRXhwb3J0cyA9IG5ldyBIYXNoTWFwPD4oKTsKICAgICAgICBwcml2YXRlIGZpbmFsIE1hcDxQYWNrYWdlU3ltYm9sLExpc3Q8T3BlbnNEaXJlY3RpdmU+PiBhbGxPcGVucyA9IG5ldyBIYXNoTWFwPD4oKTsKCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRNb2R1bGVEZWYoSkNNb2R1bGVEZWNsIHRyZWUpIHsKICAgICAgICAgICAgc3ltID0gQXNzZXJ0LmNoZWNrTm9uTnVsbCh0cmVlLnN5bSk7CgogICAgICAgICAgICBpZiAodHJlZS5nZXRNb2R1bGVUeXBlKCkgPT0gTW9kdWxlS2luZC5PUEVOKSB7CiAgICAgICAgICAgICAgICBzeW0uZmxhZ3MuYWRkKE1vZHVsZUZsYWdzLk9QRU4pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHN5bS5mbGFnc19maWVsZCB8PSAodHJlZS5tb2RzLmZsYWdzICYgRmxhZ3MuREVQUkVDQVRFRCk7CgogICAgICAgICAgICBzeW0ucmVxdWlyZXMgPSBMaXN0Lm5pbCgpOwogICAgICAgICAgICBzeW0uZXhwb3J0cyA9IExpc3QubmlsKCk7CiAgICAgICAgICAgIHN5bS5vcGVucyA9IExpc3QubmlsKCk7CiAgICAgICAgICAgIHRyZWUuZGlyZWN0aXZlcy5mb3JFYWNoKHQgLT4gdC5hY2NlcHQodGhpcykpOwogICAgICAgICAgICBzeW0ucmVxdWlyZXMgPSBzeW0ucmVxdWlyZXMucmV2ZXJzZSgpOwogICAgICAgICAgICBzeW0uZXhwb3J0cyA9IHN5bS5leHBvcnRzLnJldmVyc2UoKTsKICAgICAgICAgICAgc3ltLm9wZW5zID0gc3ltLm9wZW5zLnJldmVyc2UoKTsKICAgICAgICAgICAgZW5zdXJlSmF2YUJhc2UoKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0UmVxdWlyZXMoSkNSZXF1aXJlcyB0cmVlKSB7CiAgICAgICAgICAgIE1vZHVsZVN5bWJvbCBtc3ltID0gbG9va3VwTW9kdWxlKHRyZWUubW9kdWxlTmFtZSk7CiAgICAgICAgICAgIGlmIChtc3ltLmtpbmQgIT0gTURMKSB7CiAgICAgICAgICAgICAgICBsb2cuZXJyb3IodHJlZS5tb2R1bGVOYW1lLnBvcygpLCBFcnJvcnMuTW9kdWxlTm90Rm91bmQobXN5bSkpOwogICAgICAgICAgICAgICAgd2FybmVkTWlzc2luZy5hZGQobXN5bSk7CiAgICAgICAgICAgIH0gZWxzZSBpZiAoYWxsUmVxdWlyZXMuY29udGFpbnMobXN5bSkpIHsKICAgICAgICAgICAgICAgIGxvZy5lcnJvcih0cmVlLm1vZHVsZU5hbWUucG9zKCksIEVycm9ycy5EdXBsaWNhdGVSZXF1aXJlcyhtc3ltKSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBhbGxSZXF1aXJlcy5hZGQobXN5bSk7CiAgICAgICAgICAgICAgICBTZXQ8UmVxdWlyZXNGbGFnPiBmbGFncyA9IEVudW1TZXQubm9uZU9mKFJlcXVpcmVzRmxhZy5jbGFzcyk7CiAgICAgICAgICAgICAgICBpZiAodHJlZS5pc1RyYW5zaXRpdmUpCiAgICAgICAgICAgICAgICAgICAgZmxhZ3MuYWRkKFJlcXVpcmVzRmxhZy5UUkFOU0lUSVZFKTsKICAgICAgICAgICAgICAgIGlmICh0cmVlLmlzU3RhdGljUGhhc2UpCiAgICAgICAgICAgICAgICAgICAgZmxhZ3MuYWRkKFJlcXVpcmVzRmxhZy5TVEFUSUNfUEhBU0UpOwogICAgICAgICAgICAgICAgUmVxdWlyZXNEaXJlY3RpdmUgZCA9IG5ldyBSZXF1aXJlc0RpcmVjdGl2ZShtc3ltLCBmbGFncyk7CiAgICAgICAgICAgICAgICB0cmVlLmRpcmVjdGl2ZSA9IGQ7CiAgICAgICAgICAgICAgICBzeW0ucmVxdWlyZXMgPSBzeW0ucmVxdWlyZXMucHJlcGVuZChkKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRFeHBvcnRzKEpDRXhwb3J0cyB0cmVlKSB7CiAgICAgICAgICAgIE5hbWUgbmFtZSA9IFRyZWVJbmZvLmZ1bGxOYW1lKHRyZWUucXVhbGlkKTsKICAgICAgICAgICAgUGFja2FnZVN5bWJvbCBwYWNrZ2UgPSBzeW1zLmVudGVyUGFja2FnZShzeW0sIG5hbWUpOwogICAgICAgICAgICBhdHRyLnNldFBhY2thZ2VTeW1ib2xzKHRyZWUucXVhbGlkLCBwYWNrZ2UpOwoKICAgICAgICAgICAgTGlzdDxFeHBvcnRzRGlyZWN0aXZlPiBleHBvcnRzRm9yUGFja2FnZSA9IGFsbEV4cG9ydHMuY29tcHV0ZUlmQWJzZW50KHBhY2tnZSwgcCAtPiBMaXN0Lm5pbCgpKTsKICAgICAgICAgICAgZm9yIChFeHBvcnRzRGlyZWN0aXZlIGQgOiBleHBvcnRzRm9yUGFja2FnZSkgewogICAgICAgICAgICAgICAgcmVwb3J0RXhwb3J0c0NvbmZsaWN0KHRyZWUsIHBhY2tnZSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIExpc3Q8TW9kdWxlU3ltYm9sPiB0b01vZHVsZXMgPSBudWxsOwogICAgICAgICAgICBpZiAodHJlZS5tb2R1bGVOYW1lcyAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICBTZXQ8TW9kdWxlU3ltYm9sPiB0byA9IG5ldyBMaW5rZWRIYXNoU2V0PD4oKTsKICAgICAgICAgICAgICAgIGZvciAoSkNFeHByZXNzaW9uIG46IHRyZWUubW9kdWxlTmFtZXMpIHsKICAgICAgICAgICAgICAgICAgICBNb2R1bGVTeW1ib2wgbXN5bSA9IGxvb2t1cE1vZHVsZShuKTsKICAgICAgICAgICAgICAgICAgICBjaGsuY2hlY2tNb2R1bGVFeGlzdHMobi5wb3MoKSwgbXN5bSk7CiAgICAgICAgICAgICAgICAgICAgZm9yIChFeHBvcnRzRGlyZWN0aXZlIGQgOiBleHBvcnRzRm9yUGFja2FnZSkgewogICAgICAgICAgICAgICAgICAgICAgICBjaGVja0R1cGxpY2F0ZUV4cG9ydHNUb01vZHVsZShuLCBtc3ltLCBkKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKCF0by5hZGQobXN5bSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmVwb3J0RXhwb3J0c0NvbmZsaWN0VG9Nb2R1bGUobiwgbXN5bSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdG9Nb2R1bGVzID0gTGlzdC5mcm9tKHRvKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKHRvTW9kdWxlcyA9PSBudWxsIHx8ICF0b01vZHVsZXMuaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgICBTZXQ8RXhwb3J0c0ZsYWc+IGZsYWdzID0gRW51bVNldC5ub25lT2YoRXhwb3J0c0ZsYWcuY2xhc3MpOwogICAgICAgICAgICAgICAgRXhwb3J0c0RpcmVjdGl2ZSBkID0gbmV3IEV4cG9ydHNEaXJlY3RpdmUocGFja2dlLCB0b01vZHVsZXMsIGZsYWdzKTsKICAgICAgICAgICAgICAgIHN5bS5leHBvcnRzID0gc3ltLmV4cG9ydHMucHJlcGVuZChkKTsKICAgICAgICAgICAgICAgIHRyZWUuZGlyZWN0aXZlID0gZDsKCiAgICAgICAgICAgICAgICBhbGxFeHBvcnRzLnB1dChwYWNrZ2UsIGV4cG9ydHNGb3JQYWNrYWdlLnByZXBlbmQoZCkpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIHZvaWQgcmVwb3J0RXhwb3J0c0NvbmZsaWN0KEpDRXhwb3J0cyB0cmVlLCBQYWNrYWdlU3ltYm9sIHBhY2tnZSkgewogICAgICAgICAgICBsb2cuZXJyb3IodHJlZS5xdWFsaWQucG9zKCksIEVycm9ycy5Db25mbGljdGluZ0V4cG9ydHMocGFja2dlKSk7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIHZvaWQgY2hlY2tEdXBsaWNhdGVFeHBvcnRzVG9Nb2R1bGUoSkNFeHByZXNzaW9uIG5hbWUsIE1vZHVsZVN5bWJvbCBtc3ltLAogICAgICAgICAgICAgICAgRXhwb3J0c0RpcmVjdGl2ZSBkKSB7CiAgICAgICAgICAgIGlmIChkLm1vZHVsZXMgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgZm9yIChNb2R1bGVTeW1ib2wgb3RoZXIgOiBkLm1vZHVsZXMpIHsKICAgICAgICAgICAgICAgICAgICBpZiAobXN5bSA9PSBvdGhlcikgewogICAgICAgICAgICAgICAgICAgICAgICByZXBvcnRFeHBvcnRzQ29uZmxpY3RUb01vZHVsZShuYW1lLCBtc3ltKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHByaXZhdGUgdm9pZCByZXBvcnRFeHBvcnRzQ29uZmxpY3RUb01vZHVsZShKQ0V4cHJlc3Npb24gbmFtZSwgTW9kdWxlU3ltYm9sIG1zeW0pIHsKICAgICAgICAgICAgbG9nLmVycm9yKG5hbWUucG9zKCksIEVycm9ycy5Db25mbGljdGluZ0V4cG9ydHNUb01vZHVsZShtc3ltKSk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdE9wZW5zKEpDT3BlbnMgdHJlZSkgewogICAgICAgICAgICBOYW1lIG5hbWUgPSBUcmVlSW5mby5mdWxsTmFtZSh0cmVlLnF1YWxpZCk7CiAgICAgICAgICAgIFBhY2thZ2VTeW1ib2wgcGFja2dlID0gc3ltcy5lbnRlclBhY2thZ2Uoc3ltLCBuYW1lKTsKICAgICAgICAgICAgYXR0ci5zZXRQYWNrYWdlU3ltYm9scyh0cmVlLnF1YWxpZCwgcGFja2dlKTsKCiAgICAgICAgICAgIGlmIChzeW0uZmxhZ3MuY29udGFpbnMoTW9kdWxlRmxhZ3MuT1BFTikpIHsKICAgICAgICAgICAgICAgIGxvZy5lcnJvcih0cmVlLnBvcygpLCBFcnJvcnMuTm9PcGVuc1VubGVzc1N0cm9uZyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgTGlzdDxPcGVuc0RpcmVjdGl2ZT4gb3BlbnNGb3JQYWNrYWdlID0gYWxsT3BlbnMuY29tcHV0ZUlmQWJzZW50KHBhY2tnZSwgcCAtPiBMaXN0Lm5pbCgpKTsKICAgICAgICAgICAgZm9yIChPcGVuc0RpcmVjdGl2ZSBkIDogb3BlbnNGb3JQYWNrYWdlKSB7CiAgICAgICAgICAgICAgICByZXBvcnRPcGVuc0NvbmZsaWN0KHRyZWUsIHBhY2tnZSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIExpc3Q8TW9kdWxlU3ltYm9sPiB0b01vZHVsZXMgPSBudWxsOwogICAgICAgICAgICBpZiAodHJlZS5tb2R1bGVOYW1lcyAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICBTZXQ8TW9kdWxlU3ltYm9sPiB0byA9IG5ldyBMaW5rZWRIYXNoU2V0PD4oKTsKICAgICAgICAgICAgICAgIGZvciAoSkNFeHByZXNzaW9uIG46IHRyZWUubW9kdWxlTmFtZXMpIHsKICAgICAgICAgICAgICAgICAgICBNb2R1bGVTeW1ib2wgbXN5bSA9IGxvb2t1cE1vZHVsZShuKTsKICAgICAgICAgICAgICAgICAgICBjaGsuY2hlY2tNb2R1bGVFeGlzdHMobi5wb3MoKSwgbXN5bSk7CiAgICAgICAgICAgICAgICAgICAgZm9yIChPcGVuc0RpcmVjdGl2ZSBkIDogb3BlbnNGb3JQYWNrYWdlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNoZWNrRHVwbGljYXRlT3BlbnNUb01vZHVsZShuLCBtc3ltLCBkKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKCF0by5hZGQobXN5bSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmVwb3J0T3BlbnNDb25mbGljdFRvTW9kdWxlKG4sIG1zeW0pOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHRvTW9kdWxlcyA9IExpc3QuZnJvbSh0byk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICh0b01vZHVsZXMgPT0gbnVsbCB8fCAhdG9Nb2R1bGVzLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgICAgU2V0PE9wZW5zRmxhZz4gZmxhZ3MgPSBFbnVtU2V0Lm5vbmVPZihPcGVuc0ZsYWcuY2xhc3MpOwogICAgICAgICAgICAgICAgT3BlbnNEaXJlY3RpdmUgZCA9IG5ldyBPcGVuc0RpcmVjdGl2ZShwYWNrZ2UsIHRvTW9kdWxlcywgZmxhZ3MpOwogICAgICAgICAgICAgICAgc3ltLm9wZW5zID0gc3ltLm9wZW5zLnByZXBlbmQoZCk7CiAgICAgICAgICAgICAgICB0cmVlLmRpcmVjdGl2ZSA9IGQ7CgogICAgICAgICAgICAgICAgYWxsT3BlbnMucHV0KHBhY2tnZSwgb3BlbnNGb3JQYWNrYWdlLnByZXBlbmQoZCkpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIHZvaWQgcmVwb3J0T3BlbnNDb25mbGljdChKQ09wZW5zIHRyZWUsIFBhY2thZ2VTeW1ib2wgcGFja2dlKSB7CiAgICAgICAgICAgIGxvZy5lcnJvcih0cmVlLnF1YWxpZC5wb3MoKSwgRXJyb3JzLkNvbmZsaWN0aW5nT3BlbnMocGFja2dlKSk7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIHZvaWQgY2hlY2tEdXBsaWNhdGVPcGVuc1RvTW9kdWxlKEpDRXhwcmVzc2lvbiBuYW1lLCBNb2R1bGVTeW1ib2wgbXN5bSwKICAgICAgICAgICAgICAgIE9wZW5zRGlyZWN0aXZlIGQpIHsKICAgICAgICAgICAgaWYgKGQubW9kdWxlcyAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICBmb3IgKE1vZHVsZVN5bWJvbCBvdGhlciA6IGQubW9kdWxlcykgewogICAgICAgICAgICAgICAgICAgIGlmIChtc3ltID09IG90aGVyKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydE9wZW5zQ29uZmxpY3RUb01vZHVsZShuYW1lLCBtc3ltKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHByaXZhdGUgdm9pZCByZXBvcnRPcGVuc0NvbmZsaWN0VG9Nb2R1bGUoSkNFeHByZXNzaW9uIG5hbWUsIE1vZHVsZVN5bWJvbCBtc3ltKSB7CiAgICAgICAgICAgIGxvZy5lcnJvcihuYW1lLnBvcygpLCBFcnJvcnMuQ29uZmxpY3RpbmdPcGVuc1RvTW9kdWxlKG1zeW0pKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0UHJvdmlkZXMoSkNQcm92aWRlcyB0cmVlKSB7IH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRVc2VzKEpDVXNlcyB0cmVlKSB7IH0KCiAgICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZUphdmFCYXNlKCkgewogICAgICAgICAgICBpZiAoc3ltLm5hbWUgPT0gbmFtZXMuamF2YV9iYXNlKQogICAgICAgICAgICAgICAgcmV0dXJuOwoKICAgICAgICAgICAgZm9yIChSZXF1aXJlc0RpcmVjdGl2ZSBkOiBzeW0ucmVxdWlyZXMpIHsKICAgICAgICAgICAgICAgIGlmIChkLm1vZHVsZS5uYW1lID09IG5hbWVzLmphdmFfYmFzZSkKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIE1vZHVsZVN5bWJvbCBqYXZhX2Jhc2UgPSBzeW1zLmVudGVyTW9kdWxlKG5hbWVzLmphdmFfYmFzZSk7CiAgICAgICAgICAgIERpcmVjdGl2ZS5SZXF1aXJlc0RpcmVjdGl2ZSBkID0KICAgICAgICAgICAgICAgICAgICBuZXcgRGlyZWN0aXZlLlJlcXVpcmVzRGlyZWN0aXZlKGphdmFfYmFzZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVudW1TZXQub2YoRGlyZWN0aXZlLlJlcXVpcmVzRmxhZy5NQU5EQVRFRCkpOwogICAgICAgICAgICBzeW0ucmVxdWlyZXMgPSBzeW0ucmVxdWlyZXMucHJlcGVuZChkKTsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgTW9kdWxlU3ltYm9sIGxvb2t1cE1vZHVsZShKQ0V4cHJlc3Npb24gbW9kdWxlTmFtZSkgewogICAgICAgICAgICBOYW1lIG5hbWUgPSBUcmVlSW5mby5mdWxsTmFtZShtb2R1bGVOYW1lKTsKICAgICAgICAgICAgTW9kdWxlU3ltYm9sIG1zeW0gPSBtb2R1bGVGaW5kZXIuZmluZE1vZHVsZShuYW1lKTsKICAgICAgICAgICAgVHJlZUluZm8uc2V0U3ltYm9sKG1vZHVsZU5hbWUsIG1zeW0pOwogICAgICAgICAgICByZXR1cm4gbXN5bTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIENvbXBsZXRlciBnZXRVc2VzUHJvdmlkZXNDb21wbGV0ZXIoKSB7CiAgICAgICAgcmV0dXJuIHN5bSAtPiB7CiAgICAgICAgICAgIE1vZHVsZVN5bWJvbCBtc3ltID0gKE1vZHVsZVN5bWJvbCkgc3ltOwoKICAgICAgICAgICAgbXN5bS5jb21wbGV0ZSgpOwoKICAgICAgICAgICAgRW52PEF0dHJDb250ZXh0PiBlbnYgPSB0eXBlRW52cy5nZXQobXN5bSk7CiAgICAgICAgICAgIFVzZXNQcm92aWRlc1Zpc2l0b3IgdiA9IG5ldyBVc2VzUHJvdmlkZXNWaXNpdG9yKG1zeW0sIGVudik7CiAgICAgICAgICAgIEphdmFGaWxlT2JqZWN0IHByZXYgPSBsb2cudXNlU291cmNlKGVudi50b3BsZXZlbC5zb3VyY2VmaWxlKTsKICAgICAgICAgICAgSkNNb2R1bGVEZWNsIGRlY2wgPSBlbnYudG9wbGV2ZWwuZ2V0TW9kdWxlRGVjbCgpOwogICAgICAgICAgICBEaWFnbm9zdGljUG9zaXRpb24gcHJldkxpbnRQb3MgPSBkZWZlcnJlZExpbnRIYW5kbGVyLnNldFBvcyhkZWNsLnBvcygpKTsKCiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBkZWNsLmFjY2VwdCh2KTsKICAgICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgICAgIGxvZy51c2VTb3VyY2UocHJldik7CiAgICAgICAgICAgICAgICBkZWZlcnJlZExpbnRIYW5kbGVyLnNldFBvcyhwcmV2TGludFBvcyk7CiAgICAgICAgICAgIH0KICAgICAgICB9OwogICAgfQoKICAgIGNsYXNzIFVzZXNQcm92aWRlc1Zpc2l0b3IgZXh0ZW5kcyBKQ1RyZWUuVmlzaXRvciB7CiAgICAgICAgcHJpdmF0ZSBmaW5hbCBNb2R1bGVTeW1ib2wgbXN5bTsKICAgICAgICBwcml2YXRlIGZpbmFsIEVudjxBdHRyQ29udGV4dD4gZW52OwoKICAgICAgICBwcml2YXRlIGZpbmFsIFNldDxDbGFzc1N5bWJvbD4gYWxsVXNlcyA9IG5ldyBIYXNoU2V0PD4oKTsKICAgICAgICBwcml2YXRlIGZpbmFsIE1hcDxDbGFzc1N5bWJvbCwgU2V0PENsYXNzU3ltYm9sPj4gYWxsUHJvdmlkZXMgPSBuZXcgSGFzaE1hcDw+KCk7CgogICAgICAgIHB1YmxpYyBVc2VzUHJvdmlkZXNWaXNpdG9yKE1vZHVsZVN5bWJvbCBtc3ltLCBFbnY8QXR0ckNvbnRleHQ+IGVudikgewogICAgICAgICAgICB0aGlzLm1zeW0gPSBtc3ltOwogICAgICAgICAgICB0aGlzLmVudiA9IGVudjsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdE1vZHVsZURlZihKQ01vZHVsZURlY2wgdHJlZSkgewogICAgICAgICAgICBtc3ltLmRpcmVjdGl2ZXMgPSBMaXN0Lm5pbCgpOwogICAgICAgICAgICBtc3ltLnByb3ZpZGVzID0gTGlzdC5uaWwoKTsKICAgICAgICAgICAgbXN5bS51c2VzID0gTGlzdC5uaWwoKTsKICAgICAgICAgICAgdHJlZS5kaXJlY3RpdmVzLmZvckVhY2godCAtPiB0LmFjY2VwdCh0aGlzKSk7CiAgICAgICAgICAgIG1zeW0uZGlyZWN0aXZlcyA9IG1zeW0uZGlyZWN0aXZlcy5yZXZlcnNlKCk7CiAgICAgICAgICAgIG1zeW0ucHJvdmlkZXMgPSBtc3ltLnByb3ZpZGVzLnJldmVyc2UoKTsKICAgICAgICAgICAgbXN5bS51c2VzID0gbXN5bS51c2VzLnJldmVyc2UoKTsKCiAgICAgICAgICAgIGlmIChtc3ltLnJlcXVpcmVzLm5vbkVtcHR5KCkgJiYgbXN5bS5yZXF1aXJlcy5oZWFkLmZsYWdzLmNvbnRhaW5zKFJlcXVpcmVzRmxhZy5NQU5EQVRFRCkpCiAgICAgICAgICAgICAgICBtc3ltLmRpcmVjdGl2ZXMgPSBtc3ltLmRpcmVjdGl2ZXMucHJlcGVuZChtc3ltLnJlcXVpcmVzLmhlYWQpOwoKICAgICAgICAgICAgbXN5bS5kaXJlY3RpdmVzID0gbXN5bS5kaXJlY3RpdmVzLmFwcGVuZExpc3QoTGlzdC5mcm9tKGFkZFJlYWRzLmdldE9yRGVmYXVsdChtc3ltLCBDb2xsZWN0aW9ucy5lbXB0eVNldCgpKSkpOwoKICAgICAgICAgICAgY2hlY2tGb3JDb3JyZWN0bmVzcygpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRFeHBvcnRzKEpDRXhwb3J0cyB0cmVlKSB7CiAgICAgICAgICAgIGlmICh0cmVlLmRpcmVjdGl2ZS5wYWNrZ2UubWVtYmVycygpLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgICAgbG9nLmVycm9yKHRyZWUucXVhbGlkLnBvcygpLCBFcnJvcnMuUGFja2FnZUVtcHR5T3JOb3RGb3VuZCh0cmVlLmRpcmVjdGl2ZS5wYWNrZ2UpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBtc3ltLmRpcmVjdGl2ZXMgPSBtc3ltLmRpcmVjdGl2ZXMucHJlcGVuZCh0cmVlLmRpcmVjdGl2ZSk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdE9wZW5zKEpDT3BlbnMgdHJlZSkgewogICAgICAgICAgICBjaGsuY2hlY2tQYWNrYWdlRXhpc3RzRm9yT3BlbnModHJlZS5xdWFsaWQsIHRyZWUuZGlyZWN0aXZlLnBhY2tnZSk7CiAgICAgICAgICAgIG1zeW0uZGlyZWN0aXZlcyA9IG1zeW0uZGlyZWN0aXZlcy5wcmVwZW5kKHRyZWUuZGlyZWN0aXZlKTsKICAgICAgICB9CgogICAgICAgIE1ldGhvZFN5bWJvbCBub0FyZ3NDb25zdHJ1Y3RvcihDbGFzc1N5bWJvbCB0c3ltKSB7CiAgICAgICAgICAgIGZvciAoU3ltYm9sIHN5bSA6IHRzeW0ubWVtYmVycygpLmdldFN5bWJvbHNCeU5hbWUobmFtZXMuaW5pdCkpIHsKICAgICAgICAgICAgICAgIE1ldGhvZFN5bWJvbCBtU3ltID0gKE1ldGhvZFN5bWJvbClzeW07CiAgICAgICAgICAgICAgICBpZiAobVN5bS5wYXJhbXMoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbVN5bTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgIE1ldGhvZFN5bWJvbCBmYWN0b3J5TWV0aG9kKENsYXNzU3ltYm9sIHRzeW0pIHsKICAgICAgICAgICAgZm9yIChTeW1ib2wgc3ltIDogdHN5bS5tZW1iZXJzKCkuZ2V0U3ltYm9sc0J5TmFtZShuYW1lcy5wcm92aWRlciwgc3ltIC0+IHN5bS5raW5kID09IE1USCkpIHsKICAgICAgICAgICAgICAgIE1ldGhvZFN5bWJvbCBtU3ltID0gKE1ldGhvZFN5bWJvbClzeW07CiAgICAgICAgICAgICAgICBpZiAobVN5bS5pc1N0YXRpYygpICYmIChtU3ltLmZsYWdzKCkgJiBGbGFncy5QVUJMSUMpICE9IDAgJiYgbVN5bS5wYXJhbXMoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbVN5bTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgIE1hcDxEaXJlY3RpdmUuUHJvdmlkZXNEaXJlY3RpdmUsIEpDUHJvdmlkZXM+IGRpcmVjdGl2ZVRvVHJlZU1hcCA9IG5ldyBIYXNoTWFwPD4oKTsKCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRQcm92aWRlcyhKQ1Byb3ZpZGVzIHRyZWUpIHsKICAgICAgICAgICAgVHlwZSBzdCA9IGF0dHIuYXR0cmliVHlwZSh0cmVlLnNlcnZpY2VOYW1lLCBlbnYsIHN5bXMub2JqZWN0VHlwZSk7CiAgICAgICAgICAgIENsYXNzU3ltYm9sIHNlcnZpY2UgPSAoQ2xhc3NTeW1ib2wpIHN0LnRzeW07CiAgICAgICAgICAgIGlmIChhbGxQcm92aWRlcy5jb250YWluc0tleShzZXJ2aWNlKSkgewogICAgICAgICAgICAgICAgbG9nLmVycm9yKHRyZWUuc2VydmljZU5hbWUucG9zKCksIEVycm9ycy5SZXBlYXRlZFByb3ZpZGVzRm9yU2VydmljZShzZXJ2aWNlKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgTGlzdEJ1ZmZlcjxDbGFzc1N5bWJvbD4gaW1wbHMgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgIGZvciAoSkNFeHByZXNzaW9uIGltcGxOYW1lIDogdHJlZS5pbXBsTmFtZXMpIHsKICAgICAgICAgICAgICAgIFR5cGUgaXQ7CiAgICAgICAgICAgICAgICBib29sZWFuIHByZXZWaXNpdGluZ1NlcnZpY2VJbXBsZW1lbnRhdGlvbiA9IGVudi5pbmZvLnZpc2l0aW5nU2VydmljZUltcGxlbWVudGF0aW9uOwogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICBlbnYuaW5mby52aXNpdGluZ1NlcnZpY2VJbXBsZW1lbnRhdGlvbiA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgaXQgPSBhdHRyLmF0dHJpYlR5cGUoaW1wbE5hbWUsIGVudiwgc3ltcy5vYmplY3RUeXBlKTsKICAgICAgICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgICAgICAgICAgZW52LmluZm8udmlzaXRpbmdTZXJ2aWNlSW1wbGVtZW50YXRpb24gPSBwcmV2VmlzaXRpbmdTZXJ2aWNlSW1wbGVtZW50YXRpb247CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBDbGFzc1N5bWJvbCBpbXBsID0gKENsYXNzU3ltYm9sKSBpdC50c3ltOwogICAgICAgICAgICAgICAgaWYgKChpbXBsLmZsYWdzX2ZpZWxkICYgUFVCTElDKSA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgbG9nLmVycm9yKGltcGxOYW1lLnBvcygpLCBFcnJvcnMuTm90RGVmUHVibGljKGltcGwsIGltcGwubG9jYXRpb24oKSkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgLy9maW5kIHByb3ZpZGVyIGZhY3Rvcnk6CiAgICAgICAgICAgICAgICBNZXRob2RTeW1ib2wgZmFjdG9yeSA9IGZhY3RvcnlNZXRob2QoaW1wbCk7CiAgICAgICAgICAgICAgICBpZiAoZmFjdG9yeSAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgVHlwZSByZXR1cm5UeXBlID0gZmFjdG9yeS50eXBlLmdldFJldHVyblR5cGUoKTsKICAgICAgICAgICAgICAgICAgICBpZiAoIXR5cGVzLmlzU3VidHlwZShyZXR1cm5UeXBlLCBzdCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgbG9nLmVycm9yKGltcGxOYW1lLnBvcygpLCBFcnJvcnMuU2VydmljZUltcGxlbWVudGF0aW9uUHJvdmlkZXJSZXR1cm5NdXN0QmVTdWJ0eXBlT2ZTZXJ2aWNlSW50ZXJmYWNlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGlmICghdHlwZXMuaXNTdWJ0eXBlKGl0LCBzdCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgbG9nLmVycm9yKGltcGxOYW1lLnBvcygpLCBFcnJvcnMuU2VydmljZUltcGxlbWVudGF0aW9uTXVzdEJlU3VidHlwZU9mU2VydmljZUludGVyZmFjZSk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICgoaW1wbC5mbGFncygpICYgQUJTVFJBQ1QpICE9IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgbG9nLmVycm9yKGltcGxOYW1lLnBvcygpLCBFcnJvcnMuU2VydmljZUltcGxlbWVudGF0aW9uSXNBYnN0cmFjdChpbXBsKSk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChpbXBsLmlzSW5uZXIoKSkgewogICAgICAgICAgICAgICAgICAgICAgICBsb2cuZXJyb3IoaW1wbE5hbWUucG9zKCksIEVycm9ycy5TZXJ2aWNlSW1wbGVtZW50YXRpb25Jc0lubmVyKGltcGwpKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBNZXRob2RTeW1ib2wgY29uc3RyID0gbm9BcmdzQ29uc3RydWN0b3IoaW1wbCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb25zdHIgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9nLmVycm9yKGltcGxOYW1lLnBvcygpLCBFcnJvcnMuU2VydmljZUltcGxlbWVudGF0aW9uRG9lc250SGF2ZUFOb0FyZ3NDb25zdHJ1Y3RvcihpbXBsKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoKGNvbnN0ci5mbGFncygpICYgUFVCTElDKSA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2cuZXJyb3IoaW1wbE5hbWUucG9zKCksIEVycm9ycy5TZXJ2aWNlSW1wbGVtZW50YXRpb25Ob0FyZ3NDb25zdHJ1Y3Rvck5vdFB1YmxpYyhpbXBsKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoaXQuaGFzVGFnKENMQVNTKSkgewogICAgICAgICAgICAgICAgICAgIGlmIChhbGxQcm92aWRlcy5jb21wdXRlSWZBYnNlbnQoc2VydmljZSwgcyAtPiBuZXcgSGFzaFNldDw+KCkpLmFkZChpbXBsKSkgewogICAgICAgICAgICAgICAgICAgICAgICBpbXBscy5hcHBlbmQoaW1wbCk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgbG9nLmVycm9yKGltcGxOYW1lLnBvcygpLCBFcnJvcnMuRHVwbGljYXRlUHJvdmlkZXMoc2VydmljZSwgaW1wbCkpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoc3QuaGFzVGFnKENMQVNTKSAmJiAhaW1wbHMuaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgICBEaXJlY3RpdmUuUHJvdmlkZXNEaXJlY3RpdmUgZCA9IG5ldyBEaXJlY3RpdmUuUHJvdmlkZXNEaXJlY3RpdmUoc2VydmljZSwgaW1wbHMudG9MaXN0KCkpOwogICAgICAgICAgICAgICAgbXN5bS5wcm92aWRlcyA9IG1zeW0ucHJvdmlkZXMucHJlcGVuZChkKTsKICAgICAgICAgICAgICAgIG1zeW0uZGlyZWN0aXZlcyA9IG1zeW0uZGlyZWN0aXZlcy5wcmVwZW5kKGQpOwogICAgICAgICAgICAgICAgZGlyZWN0aXZlVG9UcmVlTWFwLnB1dChkLCB0cmVlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRSZXF1aXJlcyhKQ1JlcXVpcmVzIHRyZWUpIHsKICAgICAgICAgICAgaWYgKHRyZWUuZGlyZWN0aXZlICE9IG51bGwgJiYgYWxsTW9kdWxlcygpLmNvbnRhaW5zKHRyZWUuZGlyZWN0aXZlLm1vZHVsZSkpIHsKICAgICAgICAgICAgICAgIGNoay5jaGVja0RlcHJlY2F0ZWQodHJlZS5tb2R1bGVOYW1lLnBvcygpLCBtc3ltLCB0cmVlLmRpcmVjdGl2ZS5tb2R1bGUpOwogICAgICAgICAgICAgICAgbXN5bS5kaXJlY3RpdmVzID0gbXN5bS5kaXJlY3RpdmVzLnByZXBlbmQodHJlZS5kaXJlY3RpdmUpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdFVzZXMoSkNVc2VzIHRyZWUpIHsKICAgICAgICAgICAgVHlwZSBzdCA9IGF0dHIuYXR0cmliVHlwZSh0cmVlLnF1YWxpZCwgZW52LCBzeW1zLm9iamVjdFR5cGUpOwogICAgICAgICAgICBTeW1ib2wgc3ltID0gVHJlZUluZm8uc3ltYm9sKHRyZWUucXVhbGlkKTsKICAgICAgICAgICAgaWYgKChzeW0uZmxhZ3MoKSAmIEVOVU0pICE9IDApIHsKICAgICAgICAgICAgICAgIGxvZy5lcnJvcih0cmVlLnF1YWxpZC5wb3MoKSwgRXJyb3JzLlNlcnZpY2VEZWZpbml0aW9uSXNFbnVtKHN0LnRzeW0pKTsKICAgICAgICAgICAgfSBlbHNlIGlmIChzdC5oYXNUYWcoQ0xBU1MpKSB7CiAgICAgICAgICAgICAgICBDbGFzc1N5bWJvbCBzZXJ2aWNlID0gKENsYXNzU3ltYm9sKSBzdC50c3ltOwogICAgICAgICAgICAgICAgaWYgKGFsbFVzZXMuYWRkKHNlcnZpY2UpKSB7CiAgICAgICAgICAgICAgICAgICAgRGlyZWN0aXZlLlVzZXNEaXJlY3RpdmUgZCA9IG5ldyBEaXJlY3RpdmUuVXNlc0RpcmVjdGl2ZShzZXJ2aWNlKTsKICAgICAgICAgICAgICAgICAgICBtc3ltLnVzZXMgPSBtc3ltLnVzZXMucHJlcGVuZChkKTsKICAgICAgICAgICAgICAgICAgICBtc3ltLmRpcmVjdGl2ZXMgPSBtc3ltLmRpcmVjdGl2ZXMucHJlcGVuZChkKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgbG9nLmVycm9yKHRyZWUucG9zKCksIEVycm9ycy5EdXBsaWNhdGVVc2VzKHNlcnZpY2UpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSB2b2lkIGNoZWNrRm9yQ29ycmVjdG5lc3MoKSB7CiAgICAgICAgICAgIGZvciAoRGlyZWN0aXZlLlByb3ZpZGVzRGlyZWN0aXZlIHByb3ZpZGVzIDogbXN5bS5wcm92aWRlcykgewogICAgICAgICAgICAgICAgSkNQcm92aWRlcyB0cmVlID0gZGlyZWN0aXZlVG9UcmVlTWFwLmdldChwcm92aWRlcyk7CiAgICAgICAgICAgICAgICBmb3IgKENsYXNzU3ltYm9sIGltcGwgOiBwcm92aWRlcy5pbXBscykgewogICAgICAgICAgICAgICAgICAgIC8qIFRoZSBpbXBsZW1lbnRhdGlvbiBtdXN0IGJlIGRlZmluZWQgaW4gdGhlIHNhbWUgbW9kdWxlIGFzIHRoZSBwcm92aWRlcyBkaXJlY3RpdmUKICAgICAgICAgICAgICAgICAgICAgKiAoZWxzZSwgZXJyb3IpCiAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgUGFja2FnZVN5bWJvbCBpbXBsZW1lbnRhdGlvbkRlZmluaW5nUGFja2FnZSA9IGltcGwucGFja2dlKCk7CiAgICAgICAgICAgICAgICAgICAgaWYgKGltcGxlbWVudGF0aW9uRGVmaW5pbmdQYWNrYWdlLm1vZGxlICE9IG1zeW0pIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gVE9ETzogc2hvdWxkIHVzZSB0cmVlIGZvciB0aGUgaW1wbGVudGF0aW9uIG5hbWUsIG5vdCB0aGUgZW50aXJlIHByb3ZpZGVzIHRyZWUKICAgICAgICAgICAgICAgICAgICAgICAgLy8gVE9ETzogc2hvdWxkIGltcHJvdmUgZXJyb3IgbWVzc2FnZSB0byBpZGVudGlmeSB0aGUgaW1wbGVtZW50YXRpb24gdHlwZQogICAgICAgICAgICAgICAgICAgICAgICBsb2cuZXJyb3IodHJlZS5wb3MoKSwgRXJyb3JzLlNlcnZpY2VJbXBsZW1lbnRhdGlvbk5vdEluUmlnaHRNb2R1bGUoaW1wbGVtZW50YXRpb25EZWZpbmluZ1BhY2thZ2UubW9kbGUpKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8qIFRoZXJlIGlzIG5vIGluaGVyZW50IHJlcXVpcmVtZW50IHRoYXQgbW9kdWxlIHRoYXQgcHJvdmlkZXMgYSBzZXJ2aWNlIHNob3VsZCBhY3R1YWxseQogICAgICAgICAgICAgICAgICAgICAqIHVzZSBpdCBpdHNlbGYuIEhvd2V2ZXIsIGl0IGlzIGEgcG9pbnRsZXNzIGRlY2xhcmF0aW9uIGlmIHRoZSBzZXJ2aWNlIHBhY2thZ2UgaXMgbm90CiAgICAgICAgICAgICAgICAgICAgICogZXhwb3J0ZWQgYW5kIHRoZXJlIGlzIG5vIHVzZXMgZm9yIHRoZSBzZXJ2aWNlLgogICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgIFBhY2thZ2VTeW1ib2wgaW50ZXJmYWNlRGVjbGFyaW5nUGFja2FnZSA9IHByb3ZpZGVzLnNlcnZpY2UucGFja2dlKCk7CiAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBpc0ludGVyZmFjZURlY2xhcmVkSW5DdXJyZW50TW9kdWxlID0gaW50ZXJmYWNlRGVjbGFyaW5nUGFja2FnZS5tb2RsZSA9PSBtc3ltOwogICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gaXNJbnRlcmZhY2VFeHBvcnRlZEZyb21BUmVhZGFibGVNb2R1bGUgPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgbXN5bS52aXNpYmxlUGFja2FnZXMuZ2V0KGludGVyZmFjZURlY2xhcmluZ1BhY2thZ2UuZnVsbG5hbWUpID09IGludGVyZmFjZURlY2xhcmluZ1BhY2thZ2U7CiAgICAgICAgICAgICAgICAgICAgaWYgKGlzSW50ZXJmYWNlRGVjbGFyZWRJbkN1cnJlbnRNb2R1bGUgJiYgIWlzSW50ZXJmYWNlRXhwb3J0ZWRGcm9tQVJlYWRhYmxlTW9kdWxlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIG9rIHRoZSBpbnRlcmZhY2UgaXMgZGVjbGFyZWQgaW4gdGhpcyBtb2R1bGUuIExldCdzIGNoZWNrIGlmIGl0J3MgZXhwb3J0ZWQKICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiB3YXJuID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChFeHBvcnRzRGlyZWN0aXZlIGV4cG9ydCA6IG1zeW0uZXhwb3J0cykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGludGVyZmFjZURlY2xhcmluZ1BhY2thZ2UgPT0gZXhwb3J0LnBhY2tnZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdhcm4gPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBpZiAod2FybikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChVc2VzRGlyZWN0aXZlIHVzZXMgOiBtc3ltLnVzZXMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocHJvdmlkZXMuc2VydmljZSA9PSB1c2VzLnNlcnZpY2UpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2FybiA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHdhcm4pIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZy53YXJuaW5nKHRyZWUucG9zKCksIFdhcm5pbmdzLlNlcnZpY2VQcm92aWRlZEJ1dE5vdEV4cG9ydGVkT3JVc2VkKHByb3ZpZGVzLnNlcnZpY2UpKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIFNldDxNb2R1bGVTeW1ib2w+IGFsbE1vZHVsZXM7CgogICAgcHVibGljIFNldDxNb2R1bGVTeW1ib2w+IGFsbE1vZHVsZXMoKSB7CiAgICAgICAgQXNzZXJ0LmNoZWNrTm9uTnVsbChhbGxNb2R1bGVzKTsKICAgICAgICByZXR1cm4gYWxsTW9kdWxlczsKICAgIH0KCiAgICBwcml2YXRlIHZvaWQgc2V0dXBBbGxNb2R1bGVzKCkgewogICAgICAgIEFzc2VydC5jaGVja05vbk51bGwocm9vdE1vZHVsZXMpOwogICAgICAgIEFzc2VydC5jaGVja051bGwoYWxsTW9kdWxlcyk7CgogICAgICAgIFNldDxNb2R1bGVTeW1ib2w+IG9ic2VydmFibGU7CgogICAgICAgIGlmIChsaW1pdE1vZHNPcHQgPT0gbnVsbCAmJiBleHRyYUxpbWl0TW9kcy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgb2JzZXJ2YWJsZSA9IG51bGw7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgU2V0PE1vZHVsZVN5bWJvbD4gbGltaXRNb2RzID0gbmV3IEhhc2hTZXQ8PigpOwogICAgICAgICAgICBpZiAobGltaXRNb2RzT3B0ICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIGZvciAoU3RyaW5nIGxpbWl0IDogbGltaXRNb2RzT3B0LnNwbGl0KCIsIikpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoIWlzVmFsaWROYW1lKGxpbWl0KSkKICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICAgICAgbGltaXRNb2RzLmFkZChzeW1zLmVudGVyTW9kdWxlKG5hbWVzLmZyb21TdHJpbmcobGltaXQpKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZm9yIChTdHJpbmcgbGltaXQgOiBleHRyYUxpbWl0TW9kcykgewogICAgICAgICAgICAgICAgbGltaXRNb2RzLmFkZChzeW1zLmVudGVyTW9kdWxlKG5hbWVzLmZyb21TdHJpbmcobGltaXQpKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgb2JzZXJ2YWJsZSA9IGNvbXB1dGVUcmFuc2l0aXZlQ2xvc3VyZShsaW1pdE1vZHMsIG51bGwpOwogICAgICAgICAgICBvYnNlcnZhYmxlLmFkZEFsbChyb290TW9kdWxlcyk7CiAgICAgICAgICAgIGlmIChsaW50T3B0aW9ucykgewogICAgICAgICAgICAgICAgZm9yIChNb2R1bGVTeW1ib2wgbXN5bSA6IGxpbWl0TW9kcykgewogICAgICAgICAgICAgICAgICAgIGlmICghb2JzZXJ2YWJsZS5jb250YWlucyhtc3ltKSkgewogICAgICAgICAgICAgICAgICAgICAgICBsb2cud2FybmluZyhMaW50Q2F0ZWdvcnkuT1BUSU9OUywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXYXJuaW5ncy5Nb2R1bGVGb3JPcHRpb25Ob3RGb3VuZChPcHRpb24uTElNSVRfTU9EVUxFUywgbXN5bSkpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgUHJlZGljYXRlPE1vZHVsZVN5bWJvbD4gb2JzZXJ2YWJsZVByZWQgPSBzeW0gLT4KICAgICAgICAgICAgIChvYnNlcnZhYmxlID09IG51bGwpID8gKG1vZHVsZUZpbmRlci5maW5kTW9kdWxlKHN5bSkua2luZCAhPSBFUlIpIDogb2JzZXJ2YWJsZS5jb250YWlucyhzeW0pOwogICAgICAgIFByZWRpY2F0ZTxNb2R1bGVTeW1ib2w+IHN5c3RlbU1vZHVsZVByZWQgPSBzeW0gLT4gKHN5bS5mbGFncygpICYgRmxhZ3MuU1lTVEVNX01PRFVMRSkgIT0gMDsKICAgICAgICBQcmVkaWNhdGU8TW9kdWxlU3ltYm9sPiBub0luY3ViYXRvclByZWQgPSBzeW0gLT4gewogICAgICAgICAgICBzeW0uY29tcGxldGUoKTsKICAgICAgICAgICAgcmV0dXJuICFzeW0ucmVzb2x1dGlvbkZsYWdzLmNvbnRhaW5zKE1vZHVsZVJlc29sdXRpb25GbGFncy5ET19OT1RfUkVTT0xWRV9CWV9ERUZBVUxUKTsKICAgICAgICB9OwogICAgICAgIFNldDxNb2R1bGVTeW1ib2w+IGVuYWJsZWRSb290ID0gbmV3IExpbmtlZEhhc2hTZXQ8PigpOwoKICAgICAgICBpZiAocm9vdE1vZHVsZXMuY29udGFpbnMoc3ltcy51bm5hbWVkTW9kdWxlKSkgewogICAgICAgICAgICBNb2R1bGVTeW1ib2wgamF2YVNFID0gc3ltcy5nZXRNb2R1bGUoamF2YV9zZSk7CiAgICAgICAgICAgIFByZWRpY2F0ZTxNb2R1bGVTeW1ib2w+IGpka01vZHVsZVByZWQ7CgogICAgICAgICAgICBpZiAoamF2YVNFICE9IG51bGwgJiYgKG9ic2VydmFibGUgPT0gbnVsbCB8fCBvYnNlcnZhYmxlLmNvbnRhaW5zKGphdmFTRSkpKSB7CiAgICAgICAgICAgICAgICBqZGtNb2R1bGVQcmVkID0gc3ltIC0+IHsKICAgICAgICAgICAgICAgICAgICBzeW0uY29tcGxldGUoKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gICAhc3ltLm5hbWUuc3RhcnRzV2l0aChqYXZhXykKICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgc3ltLmV4cG9ydHMuc3RyZWFtKCkuYW55TWF0Y2goZSAtPiBlLm1vZHVsZXMgPT0gbnVsbCk7CiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgZW5hYmxlZFJvb3QuYWRkKGphdmFTRSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBqZGtNb2R1bGVQcmVkID0gc3ltIC0+IHRydWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGZvciAoTW9kdWxlU3ltYm9sIHN5bSA6IG5ldyBIYXNoU2V0PD4oc3ltcy5nZXRBbGxNb2R1bGVzKCkpKSB7CiAgICAgICAgICAgICAgICBpZiAoc3lzdGVtTW9kdWxlUHJlZC50ZXN0KHN5bSkgJiYgb2JzZXJ2YWJsZVByZWQudGVzdChzeW0pICYmIGpka01vZHVsZVByZWQudGVzdChzeW0pICYmIG5vSW5jdWJhdG9yUHJlZC50ZXN0KHN5bSkpIHsKICAgICAgICAgICAgICAgICAgICBlbmFibGVkUm9vdC5hZGQoc3ltKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgZW5hYmxlZFJvb3QuYWRkQWxsKHJvb3RNb2R1bGVzKTsKCiAgICAgICAgaWYgKGFkZE1vZHNPcHQgIT0gbnVsbCB8fCAhZXh0cmFBZGRNb2RzLmlzRW1wdHkoKSkgewogICAgICAgICAgICBTZXQ8U3RyaW5nPiBmdWxsQWRkTW9kcyA9IG5ldyBIYXNoU2V0PD4oKTsKICAgICAgICAgICAgZnVsbEFkZE1vZHMuYWRkQWxsKGV4dHJhQWRkTW9kcyk7CgogICAgICAgICAgICBpZiAoYWRkTW9kc09wdCAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICBmdWxsQWRkTW9kcy5hZGRBbGwoQXJyYXlzLmFzTGlzdChhZGRNb2RzT3B0LnNwbGl0KCIsIikpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZm9yIChTdHJpbmcgYWRkZWQgOiBmdWxsQWRkTW9kcykgewogICAgICAgICAgICAgICAgU3RyZWFtPE1vZHVsZVN5bWJvbD4gbW9kdWxlczsKICAgICAgICAgICAgICAgIHN3aXRjaCAoYWRkZWQpIHsKICAgICAgICAgICAgICAgICAgICBjYXNlIEFMTF9TWVNURU06CiAgICAgICAgICAgICAgICAgICAgICAgIG1vZHVsZXMgPSBuZXcgSGFzaFNldDw+KHN5bXMuZ2V0QWxsTW9kdWxlcygpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5zdHJlYW0oKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5maWx0ZXIoc3lzdGVtTW9kdWxlUHJlZC5hbmQob2JzZXJ2YWJsZVByZWQpLmFuZChub0luY3ViYXRvclByZWQpKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBBTExfTU9EVUxFX1BBVEg6CiAgICAgICAgICAgICAgICAgICAgICAgIG1vZHVsZXMgPSBuZXcgSGFzaFNldDw+KHN5bXMuZ2V0QWxsTW9kdWxlcygpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5zdHJlYW0oKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5maWx0ZXIoc3lzdGVtTW9kdWxlUHJlZC5uZWdhdGUoKS5hbmQob2JzZXJ2YWJsZVByZWQpKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFpc1ZhbGlkTmFtZShhZGRlZCkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICAgICAgbW9kdWxlcyA9IFN0cmVhbS5vZihzeW1zLmVudGVyTW9kdWxlKG5hbWVzLmZyb21TdHJpbmcoYWRkZWQpKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgbW9kdWxlcy5mb3JFYWNoKHN5bSAtPiB7CiAgICAgICAgICAgICAgICAgICAgZW5hYmxlZFJvb3QuYWRkKHN5bSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKG9ic2VydmFibGUgIT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICAgICAgb2JzZXJ2YWJsZS5hZGQoc3ltKTsKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBTZXQ8TW9kdWxlU3ltYm9sPiByZXN1bHQgPSBjb21wdXRlVHJhbnNpdGl2ZUNsb3N1cmUoZW5hYmxlZFJvb3QsIG9ic2VydmFibGUpOwoKICAgICAgICByZXN1bHQuYWRkKHN5bXMudW5uYW1lZE1vZHVsZSk7CgogICAgICAgIFN0cmluZyBpbmN1YmF0aW5nTW9kdWxlcyA9IHJlc3VsdC5zdHJlYW0oKQogICAgICAgICAgICAgICAgLmZpbHRlcihtc3ltIC0+IG1zeW0ucmVzb2x1dGlvbkZsYWdzLmNvbnRhaW5zKE1vZHVsZVJlc29sdXRpb25GbGFncy5XQVJOX0lOQ1VCQVRJTkcpKQogICAgICAgICAgICAgICAgLm1hcChtc3ltIC0+IG1zeW0ubmFtZS50b1N0cmluZygpKQogICAgICAgICAgICAgICAgLmNvbGxlY3QoQ29sbGVjdG9ycy5qb2luaW5nKCIsIikpOwoKICAgICAgICBpZiAoIWluY3ViYXRpbmdNb2R1bGVzLmlzRW1wdHkoKSkgewogICAgICAgICAgICBsb2cud2FybmluZyhXYXJuaW5ncy5JbmN1YmF0aW5nTW9kdWxlcyhpbmN1YmF0aW5nTW9kdWxlcykpOwogICAgICAgIH0KCiAgICAgICAgYWxsTW9kdWxlcyA9IHJlc3VsdDsKCiAgICAgICAgLy9hZGQgbW9kdWxlIHZlcnNpb25zIGZyb20gb3B0aW9ucywgaWYgYW55OgogICAgICAgIGlmIChtb2R1bGVWZXJzaW9uT3B0ICE9IG51bGwpIHsKICAgICAgICAgICAgTmFtZSB2ZXJzaW9uID0gbmFtZXMuZnJvbVN0cmluZyhtb2R1bGVWZXJzaW9uT3B0KTsKICAgICAgICAgICAgcm9vdE1vZHVsZXMuZm9yRWFjaChtIC0+IG0udmVyc2lvbiA9IHZlcnNpb24pOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgYm9vbGVhbiBpc0luTW9kdWxlR3JhcGgoTW9kdWxlU3ltYm9sIG1zeW0pIHsKICAgICAgICByZXR1cm4gYWxsTW9kdWxlcyA9PSBudWxsIHx8IGFsbE1vZHVsZXMuY29udGFpbnMobXN5bSk7CiAgICB9CgogICAgcHJpdmF0ZSBTZXQ8TW9kdWxlU3ltYm9sPiBjb21wdXRlVHJhbnNpdGl2ZUNsb3N1cmUoU2V0PD8gZXh0ZW5kcyBNb2R1bGVTeW1ib2w+IGJhc2UsIFNldDxNb2R1bGVTeW1ib2w+IG9ic2VydmFibGUpIHsKICAgICAgICBMaXN0PE1vZHVsZVN5bWJvbD4gcHJpbWFyeVRvZG8gPSBMaXN0Lm5pbCgpOwogICAgICAgIExpc3Q8TW9kdWxlU3ltYm9sPiBzZWNvbmRhcnlUb2RvID0gTGlzdC5uaWwoKTsKCiAgICAgICAgZm9yIChNb2R1bGVTeW1ib2wgbXMgOiBiYXNlKSB7CiAgICAgICAgICAgIHByaW1hcnlUb2RvID0gcHJpbWFyeVRvZG8ucHJlcGVuZChtcyk7CiAgICAgICAgfQoKICAgICAgICBTZXQ8TW9kdWxlU3ltYm9sPiByZXN1bHQgPSBuZXcgTGlua2VkSGFzaFNldDw+KCk7CiAgICAgICAgcmVzdWx0LmFkZChzeW1zLmphdmFfYmFzZSk7CgogICAgICAgIHdoaWxlIChwcmltYXJ5VG9kby5ub25FbXB0eSgpIHx8IHNlY29uZGFyeVRvZG8ubm9uRW1wdHkoKSkgewogICAgICAgICAgICBNb2R1bGVTeW1ib2wgY3VycmVudDsKICAgICAgICAgICAgYm9vbGVhbiBpc1ByaW1hcnlUb2RvOwogICAgICAgICAgICBpZiAocHJpbWFyeVRvZG8ubm9uRW1wdHkoKSkgewogICAgICAgICAgICAgICAgY3VycmVudCA9IHByaW1hcnlUb2RvLmhlYWQ7CiAgICAgICAgICAgICAgICBwcmltYXJ5VG9kbyA9IHByaW1hcnlUb2RvLnRhaWw7CiAgICAgICAgICAgICAgICBpc1ByaW1hcnlUb2RvID0gdHJ1ZTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGN1cnJlbnQgPSBzZWNvbmRhcnlUb2RvLmhlYWQ7CiAgICAgICAgICAgICAgICBzZWNvbmRhcnlUb2RvID0gc2Vjb25kYXJ5VG9kby50YWlsOwogICAgICAgICAgICAgICAgaXNQcmltYXJ5VG9kbyA9IGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChvYnNlcnZhYmxlICE9IG51bGwgJiYgIW9ic2VydmFibGUuY29udGFpbnMoY3VycmVudCkpCiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgaWYgKCFyZXN1bHQuYWRkKGN1cnJlbnQpIHx8IGN1cnJlbnQgPT0gc3ltcy51bm5hbWVkTW9kdWxlIHx8ICgoY3VycmVudC5mbGFnc19maWVsZCAmIEZsYWdzLkFVVE9NQVRJQ19NT0RVTEUpICE9IDApKQogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIGN1cnJlbnQuY29tcGxldGUoKTsKICAgICAgICAgICAgaWYgKGN1cnJlbnQua2luZCA9PSBFUlIgJiYgaXNQcmltYXJ5VG9kbyAmJiB3YXJuZWRNaXNzaW5nLmFkZChjdXJyZW50KSkgewogICAgICAgICAgICAgICAgbG9nLmVycm9yKEVycm9ycy5Nb2R1bGVOb3RGb3VuZChjdXJyZW50KSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZm9yIChSZXF1aXJlc0RpcmVjdGl2ZSByZCA6IGN1cnJlbnQucmVxdWlyZXMpIHsKICAgICAgICAgICAgICAgIGlmIChyZC5tb2R1bGUgPT0gc3ltcy5qYXZhX2Jhc2UpIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgaWYgKChyZC5pc1RyYW5zaXRpdmUoKSAmJiBpc1ByaW1hcnlUb2RvKSB8fCBiYXNlLmNvbnRhaW5zKGN1cnJlbnQpKSB7CiAgICAgICAgICAgICAgICAgICAgcHJpbWFyeVRvZG8gPSBwcmltYXJ5VG9kby5wcmVwZW5kKHJkLm1vZHVsZSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHNlY29uZGFyeVRvZG8gPSBzZWNvbmRhcnlUb2RvLnByZXBlbmQocmQubW9kdWxlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KCiAgICBwdWJsaWMgTW9kdWxlU3ltYm9sIGdldE9ic2VydmFibGVNb2R1bGUoTmFtZSBuYW1lKSB7CiAgICAgICAgTW9kdWxlU3ltYm9sIG1vZCA9IHN5bXMuZ2V0TW9kdWxlKG5hbWUpOwoKICAgICAgICBpZiAoYWxsTW9kdWxlcygpLmNvbnRhaW5zKG1vZCkpIHsKICAgICAgICAgICAgcmV0dXJuIG1vZDsKICAgICAgICB9CgogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIHByaXZhdGUgQ29tcGxldGVyIGdldFVubmFtZWRNb2R1bGVDb21wbGV0ZXIoKSB7CiAgICAgICAgbW9kdWxlRmluZGVyLmZpbmRBbGxNb2R1bGVzKCk7CiAgICAgICAgcmV0dXJuIG5ldyBTeW1ib2wuQ29tcGxldGVyKCkgewogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHVibGljIHZvaWQgY29tcGxldGUoU3ltYm9sIHN5bSkgdGhyb3dzIENvbXBsZXRpb25GYWlsdXJlIHsKICAgICAgICAgICAgICAgIGlmIChpbkluaXRNb2R1bGVzKSB7CiAgICAgICAgICAgICAgICAgICAgc3ltLmNvbXBsZXRlciA9IHRoaXM7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIE1vZHVsZVN5bWJvbCBtc3ltID0gKE1vZHVsZVN5bWJvbCkgc3ltOwogICAgICAgICAgICAgICAgU2V0PE1vZHVsZVN5bWJvbD4gYWxsTW9kdWxlcyA9IG5ldyBIYXNoU2V0PD4oYWxsTW9kdWxlcygpKTsKICAgICAgICAgICAgICAgIGFsbE1vZHVsZXMucmVtb3ZlKHN5bXMudW5uYW1lZE1vZHVsZSk7CiAgICAgICAgICAgICAgICBmb3IgKE1vZHVsZVN5bWJvbCBtIDogYWxsTW9kdWxlcykgewogICAgICAgICAgICAgICAgICAgIG0uY29tcGxldGUoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGluaXRWaXNpYmxlUGFja2FnZXMobXN5bSwgYWxsTW9kdWxlcyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewogICAgICAgICAgICAgICAgcmV0dXJuICJ1bm5hbWVkTW9kdWxlIENvbXBsZXRlciI7CiAgICAgICAgICAgIH0KICAgICAgICB9OwogICAgfQoKICAgIHByaXZhdGUgZmluYWwgTWFwPE1vZHVsZVN5bWJvbCwgU2V0PE1vZHVsZVN5bWJvbD4+IHJlcXVpcmVzVHJhbnNpdGl2ZUNhY2hlID0gbmV3IEhhc2hNYXA8PigpOwoKICAgIHByaXZhdGUgdm9pZCBjb21wbGV0ZU1vZHVsZShNb2R1bGVTeW1ib2wgbXN5bSkgewogICAgICAgIGlmIChpbkluaXRNb2R1bGVzKSB7CiAgICAgICAgICAgIG1zeW0uY29tcGxldGVyID0gc3ltIC0+IGNvbXBsZXRlTW9kdWxlKG1zeW0pOwogICAgICAgICAgICByZXR1cm4gOwogICAgICAgIH0KCiAgICAgICAgaWYgKChtc3ltLmZsYWdzX2ZpZWxkICYgRmxhZ3MuQVVUT01BVElDX01PRFVMRSkgIT0gMCkgewogICAgICAgICAgICBjb21wbGV0ZUF1dG9tYXRpY01vZHVsZShtc3ltKTsKICAgICAgICB9CgogICAgICAgIEFzc2VydC5jaGVja05vbk51bGwobXN5bS5yZXF1aXJlcyk7CgogICAgICAgIGluaXRBZGRSZWFkcygpOwoKICAgICAgICBtc3ltLnJlcXVpcmVzID0gbXN5bS5yZXF1aXJlcy5hcHBlbmRMaXN0KExpc3QuZnJvbShhZGRSZWFkcy5nZXRPckRlZmF1bHQobXN5bSwgQ29sbGVjdGlvbnMuZW1wdHlTZXQoKSkpKTsKCiAgICAgICAgTGlzdDxSZXF1aXJlc0RpcmVjdGl2ZT4gcmVxdWlyZXMgPSBtc3ltLnJlcXVpcmVzOwoKICAgICAgICB3aGlsZSAocmVxdWlyZXMubm9uRW1wdHkoKSkgewogICAgICAgICAgICBpZiAoIWFsbE1vZHVsZXMoKS5jb250YWlucyhyZXF1aXJlcy5oZWFkLm1vZHVsZSkpIHsKICAgICAgICAgICAgICAgIEVudjxBdHRyQ29udGV4dD4gZW52ID0gdHlwZUVudnMuZ2V0KG1zeW0pOwogICAgICAgICAgICAgICAgaWYgKGVudiAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgSmF2YUZpbGVPYmplY3Qgb3JpZ1NvdXJjZSA9IGxvZy51c2VTb3VyY2UoZW52LnRvcGxldmVsLnNvdXJjZWZpbGUpOwogICAgICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGxvZy5lcnJvcigvKlhYWCovZW52LnRyZWUsIEVycm9ycy5Nb2R1bGVOb3RGb3VuZChyZXF1aXJlcy5oZWFkLm1vZHVsZSkpOwogICAgICAgICAgICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGxvZy51c2VTb3VyY2Uob3JpZ1NvdXJjZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBBc3NlcnQuY2hlY2soKG1zeW0uZmxhZ3MoKSAmIEZsYWdzLkFVVE9NQVRJQ19NT0RVTEUpID09IDApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgbXN5bS5yZXF1aXJlcyA9IExpc3QuZmlsdGVyKG1zeW0ucmVxdWlyZXMsIHJlcXVpcmVzLmhlYWQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJlcXVpcmVzID0gcmVxdWlyZXMudGFpbDsKICAgICAgICB9CgogICAgICAgIFNldDxNb2R1bGVTeW1ib2w+IHJlYWRhYmxlID0gbmV3IExpbmtlZEhhc2hTZXQ8PigpOwogICAgICAgIFNldDxNb2R1bGVTeW1ib2w+IHJlcXVpcmVzVHJhbnNpdGl2ZSA9IG5ldyBIYXNoU2V0PD4oKTsKCiAgICAgICAgZm9yIChSZXF1aXJlc0RpcmVjdGl2ZSBkIDogbXN5bS5yZXF1aXJlcykgewogICAgICAgICAgICBkLm1vZHVsZS5jb21wbGV0ZSgpOwogICAgICAgICAgICByZWFkYWJsZS5hZGQoZC5tb2R1bGUpOwogICAgICAgICAgICBTZXQ8TW9kdWxlU3ltYm9sPiBzID0gcmV0cmlldmVSZXF1aXJlc1RyYW5zaXRpdmUoZC5tb2R1bGUpOwogICAgICAgICAgICBBc3NlcnQuY2hlY2tOb25OdWxsKHMsICgpIC0+ICJubyBlbnRyeSBpbiBjYWNoZSBmb3IgIiArIGQubW9kdWxlKTsKICAgICAgICAgICAgcmVhZGFibGUuYWRkQWxsKHMpOwogICAgICAgICAgICBpZiAoZC5mbGFncy5jb250YWlucyhSZXF1aXJlc0ZsYWcuVFJBTlNJVElWRSkpIHsKICAgICAgICAgICAgICAgIHJlcXVpcmVzVHJhbnNpdGl2ZS5hZGQoZC5tb2R1bGUpOwogICAgICAgICAgICAgICAgcmVxdWlyZXNUcmFuc2l0aXZlLmFkZEFsbChzKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmVxdWlyZXNUcmFuc2l0aXZlQ2FjaGUucHV0KG1zeW0sIHJlcXVpcmVzVHJhbnNpdGl2ZSk7CiAgICAgICAgaW5pdFZpc2libGVQYWNrYWdlcyhtc3ltLCByZWFkYWJsZSk7CiAgICAgICAgZm9yIChFeHBvcnRzRGlyZWN0aXZlIGQ6IG1zeW0uZXhwb3J0cykgewogICAgICAgICAgICBpZiAoZC5wYWNrZ2UgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgZC5wYWNrZ2UubW9kbGUgPSBtc3ltOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgIH0KCiAgICBwcml2YXRlIFNldDxNb2R1bGVTeW1ib2w+IHJldHJpZXZlUmVxdWlyZXNUcmFuc2l0aXZlKE1vZHVsZVN5bWJvbCBtc3ltKSB7CiAgICAgICAgU2V0PE1vZHVsZVN5bWJvbD4gcmVxdWlyZXNUcmFuc2l0aXZlID0gcmVxdWlyZXNUcmFuc2l0aXZlQ2FjaGUuZ2V0KG1zeW0pOwoKICAgICAgICBpZiAocmVxdWlyZXNUcmFuc2l0aXZlID09IG51bGwpIHsKICAgICAgICAgICAgLy90aGUgbW9kdWxlIGdyYXBoIG1heSBjb250YWluIGN5Y2xlcyBpbnZvbHZpbmcgYXV0b21hdGljIG1vZHVsZXMgb3IgLS1hZGQtcmVhZHMgZWRnZXMKICAgICAgICAgICAgcmVxdWlyZXNUcmFuc2l0aXZlID0gbmV3IEhhc2hTZXQ8PigpOwoKICAgICAgICAgICAgU2V0PE1vZHVsZVN5bWJvbD4gc2VlbiA9IG5ldyBIYXNoU2V0PD4oKTsKICAgICAgICAgICAgTGlzdDxNb2R1bGVTeW1ib2w+IHRvZG8gPSBMaXN0Lm9mKG1zeW0pOwoKICAgICAgICAgICAgd2hpbGUgKHRvZG8ubm9uRW1wdHkoKSkgewogICAgICAgICAgICAgICAgTW9kdWxlU3ltYm9sIGN1cnJlbnQgPSB0b2RvLmhlYWQ7CiAgICAgICAgICAgICAgICB0b2RvID0gdG9kby50YWlsOwogICAgICAgICAgICAgICAgaWYgKCFzZWVuLmFkZChjdXJyZW50KSkKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIHJlcXVpcmVzVHJhbnNpdGl2ZS5hZGQoY3VycmVudCk7CiAgICAgICAgICAgICAgICBjdXJyZW50LmNvbXBsZXRlKCk7CiAgICAgICAgICAgICAgICBJdGVyYWJsZTw/IGV4dGVuZHMgUmVxdWlyZXNEaXJlY3RpdmU+IHJlcXVpcmVzOwogICAgICAgICAgICAgICAgaWYgKGN1cnJlbnQgIT0gc3ltcy51bm5hbWVkTW9kdWxlKSB7CiAgICAgICAgICAgICAgICAgICAgQXNzZXJ0LmNoZWNrTm9uTnVsbChjdXJyZW50LnJlcXVpcmVzLCAoKSAtPiBjdXJyZW50ICsgIi5yZXF1aXJlcyA9PSBudWxsOyAiICsgbXN5bSk7CiAgICAgICAgICAgICAgICAgICAgcmVxdWlyZXMgPSBjdXJyZW50LnJlcXVpcmVzOwogICAgICAgICAgICAgICAgICAgIGZvciAoUmVxdWlyZXNEaXJlY3RpdmUgcmQgOiByZXF1aXJlcykgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAocmQuaXNUcmFuc2l0aXZlKCkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b2RvID0gdG9kby5wcmVwZW5kKHJkLm1vZHVsZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBmb3IgKE1vZHVsZVN5bWJvbCBtb2QgOiBhbGxNb2R1bGVzKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdG9kbyA9IHRvZG8ucHJlcGVuZChtb2QpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmVxdWlyZXNUcmFuc2l0aXZlLnJlbW92ZShtc3ltKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiByZXF1aXJlc1RyYW5zaXRpdmU7CiAgICB9CgogICAgcHJpdmF0ZSB2b2lkIGluaXRWaXNpYmxlUGFja2FnZXMoTW9kdWxlU3ltYm9sIG1zeW0sIENvbGxlY3Rpb248TW9kdWxlU3ltYm9sPiByZWFkYWJsZSkgewogICAgICAgIGluaXRBZGRFeHBvcnRzKCk7CgogICAgICAgIG1zeW0udmlzaWJsZVBhY2thZ2VzID0gbmV3IExpbmtlZEhhc2hNYXA8PigpOwogICAgICAgIG1zeW0ucmVhZE1vZHVsZXMgPSBuZXcgSGFzaFNldDw+KHJlYWRhYmxlKTsKCiAgICAgICAgTWFwPE5hbWUsIE1vZHVsZVN5bWJvbD4gc2VlbiA9IG5ldyBIYXNoTWFwPD4oKTsKCiAgICAgICAgZm9yIChNb2R1bGVTeW1ib2wgcm0gOiByZWFkYWJsZSkgewogICAgICAgICAgICBpZiAocm0gPT0gc3ltcy51bm5hbWVkTW9kdWxlKQogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIGFkZFZpc2libGVQYWNrYWdlcyhtc3ltLCBzZWVuLCBybSwgcm0uZXhwb3J0cyk7CiAgICAgICAgfQoKICAgICAgICBhZGRFeHBvcnRzLmZvckVhY2goKGV4cG9ydHNGcm9tLCBleHBvcnRzKSAtPiB7CiAgICAgICAgICAgIGFkZFZpc2libGVQYWNrYWdlcyhtc3ltLCBzZWVuLCBleHBvcnRzRnJvbSwgZXhwb3J0cyk7CiAgICAgICAgfSk7CiAgICB9CgogICAgcHJpdmF0ZSB2b2lkIGFkZFZpc2libGVQYWNrYWdlcyhNb2R1bGVTeW1ib2wgbXN5bSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWFwPE5hbWUsIE1vZHVsZVN5bWJvbD4gc2VlblBhY2thZ2VzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNb2R1bGVTeW1ib2wgZXhwb3J0c0Zyb20sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbGxlY3Rpb248RXhwb3J0c0RpcmVjdGl2ZT4gZXhwb3J0cykgewogICAgICAgIGZvciAoRXhwb3J0c0RpcmVjdGl2ZSBkIDogZXhwb3J0cykgewogICAgICAgICAgICBpZiAoZC5tb2R1bGVzID09IG51bGwgfHwgZC5tb2R1bGVzLmNvbnRhaW5zKG1zeW0pKSB7CiAgICAgICAgICAgICAgICBOYW1lIHBhY2thZ2VOYW1lID0gZC5wYWNrZ2UuZnVsbG5hbWU7CiAgICAgICAgICAgICAgICBNb2R1bGVTeW1ib2wgcHJldmlvdXNNb2R1bGUgPSBzZWVuUGFja2FnZXMuZ2V0KHBhY2thZ2VOYW1lKTsKCiAgICAgICAgICAgICAgICBpZiAocHJldmlvdXNNb2R1bGUgIT0gbnVsbCAmJiBwcmV2aW91c01vZHVsZSAhPSBleHBvcnRzRnJvbSkgewogICAgICAgICAgICAgICAgICAgIEVudjxBdHRyQ29udGV4dD4gZW52ID0gdHlwZUVudnMuZ2V0KG1zeW0pOwogICAgICAgICAgICAgICAgICAgIEphdmFGaWxlT2JqZWN0IG9yaWdTb3VyY2UgPSBlbnYgIT0gbnVsbCA/IGxvZy51c2VTb3VyY2UoZW52LnRvcGxldmVsLnNvdXJjZWZpbGUpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogbnVsbDsKICAgICAgICAgICAgICAgICAgICBEaWFnbm9zdGljUG9zaXRpb24gcG9zID0gZW52ICE9IG51bGwgPyBlbnYudHJlZS5wb3MoKSA6IG51bGw7CiAgICAgICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICAgICAgbG9nLmVycm9yKHBvcywgRXJyb3JzLlBhY2thZ2VDbGFzaEZyb21SZXF1aXJlcyhtc3ltLCBwYWNrYWdlTmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZXZpb3VzTW9kdWxlLCBleHBvcnRzRnJvbSkpOwogICAgICAgICAgICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlbnYgIT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZy51c2VTb3VyY2Uob3JpZ1NvdXJjZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHNlZW5QYWNrYWdlcy5wdXQocGFja2FnZU5hbWUsIGV4cG9ydHNGcm9tKTsKICAgICAgICAgICAgICAgIG1zeW0udmlzaWJsZVBhY2thZ2VzLnB1dChkLnBhY2tnZS5mdWxsbmFtZSwgZC5wYWNrZ2UpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgdm9pZCBpbml0QWRkRXhwb3J0cygpIHsKICAgICAgICBpZiAoYWRkRXhwb3J0cyAhPSBudWxsKQogICAgICAgICAgICByZXR1cm47CgogICAgICAgIGFkZEV4cG9ydHMgPSBuZXcgTGlua2VkSGFzaE1hcDw+KCk7CiAgICAgICAgU2V0PE1vZHVsZVN5bWJvbD4gdW5rbm93bk1vZHVsZXMgPSBuZXcgSGFzaFNldDw+KCk7CgogICAgICAgIGlmIChhZGRFeHBvcnRzT3B0ID09IG51bGwpCiAgICAgICAgICAgIHJldHVybjsKCiAgICAgICAgUGF0dGVybiBlcCA9IFBhdHRlcm4uY29tcGlsZSgiKFteL10rKS8oW149XSspPSguKikiKTsKICAgICAgICBmb3IgKFN0cmluZyBzOiBhZGRFeHBvcnRzT3B0LnNwbGl0KCJcMCsiKSkgewogICAgICAgICAgICBpZiAocy5pc0VtcHR5KCkpCiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgTWF0Y2hlciBlbSA9IGVwLm1hdGNoZXIocyk7CiAgICAgICAgICAgIGlmICghZW0ubWF0Y2hlcygpKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gVGVybWlub2xvZ3kgY29tZXMgZnJvbQogICAgICAgICAgICAvLyAgLS1hZGQtZXhwb3J0cyBtb2R1bGUvcGFja2FnZT10YXJnZXQsLi4uCiAgICAgICAgICAgIC8vIENvbXBhcmUgdG8KICAgICAgICAgICAgLy8gIG1vZHVsZSBtb2R1bGUgeyBleHBvcnRzIHBhY2thZ2UgdG8gdGFyZ2V0LCAuLi4gfQogICAgICAgICAgICBTdHJpbmcgbW9kdWxlTmFtZSA9IGVtLmdyb3VwKDEpOwogICAgICAgICAgICBTdHJpbmcgcGFja2FnZU5hbWUgPSBlbS5ncm91cCgyKTsKICAgICAgICAgICAgU3RyaW5nIHRhcmdldE5hbWVzID0gZW0uZ3JvdXAoMyk7CgogICAgICAgICAgICBpZiAoIWlzVmFsaWROYW1lKG1vZHVsZU5hbWUpKQogICAgICAgICAgICAgICAgY29udGludWU7CgogICAgICAgICAgICBNb2R1bGVTeW1ib2wgbXN5bSA9IHN5bXMuZW50ZXJNb2R1bGUobmFtZXMuZnJvbVN0cmluZyhtb2R1bGVOYW1lKSk7CiAgICAgICAgICAgIGlmICghaXNLbm93bk1vZHVsZShtc3ltLCB1bmtub3duTW9kdWxlcykpCiAgICAgICAgICAgICAgICBjb250aW51ZTsKCiAgICAgICAgICAgIGlmICghaXNWYWxpZE5hbWUocGFja2FnZU5hbWUpKQogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIFBhY2thZ2VTeW1ib2wgcCA9IHN5bXMuZW50ZXJQYWNrYWdlKG1zeW0sIG5hbWVzLmZyb21TdHJpbmcocGFja2FnZU5hbWUpKTsKICAgICAgICAgICAgcC5tb2RsZSA9IG1zeW07ICAvLyBUT0RPOiBkbyB3ZSBuZWVkIHRoaXM/CgogICAgICAgICAgICBMaXN0PE1vZHVsZVN5bWJvbD4gdGFyZ2V0TW9kdWxlcyA9IExpc3QubmlsKCk7CiAgICAgICAgICAgIGZvciAoU3RyaW5nIHRvTW9kdWxlIDogdGFyZ2V0TmFtZXMuc3BsaXQoIlsgLF0rIikpIHsKICAgICAgICAgICAgICAgIE1vZHVsZVN5bWJvbCBtOwogICAgICAgICAgICAgICAgaWYgKHRvTW9kdWxlLmVxdWFscygiQUxMLVVOTkFNRUQiKSkgewogICAgICAgICAgICAgICAgICAgIG0gPSBzeW1zLnVubmFtZWRNb2R1bGU7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGlmICghaXNWYWxpZE5hbWUodG9Nb2R1bGUpKQogICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICBtID0gc3ltcy5lbnRlck1vZHVsZShuYW1lcy5mcm9tU3RyaW5nKHRvTW9kdWxlKSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKCFpc0tub3duTW9kdWxlKG0sIHVua25vd25Nb2R1bGVzKSkKICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB0YXJnZXRNb2R1bGVzID0gdGFyZ2V0TW9kdWxlcy5wcmVwZW5kKG0pOwogICAgICAgICAgICB9CgogICAgICAgICAgICBTZXQ8RXhwb3J0c0RpcmVjdGl2ZT4gZXh0cmEgPSBhZGRFeHBvcnRzLmNvbXB1dGVJZkFic2VudChtc3ltLCBfeCAtPiBuZXcgTGlua2VkSGFzaFNldDw+KCkpOwogICAgICAgICAgICBFeHBvcnRzRGlyZWN0aXZlIGQgPSBuZXcgRXhwb3J0c0RpcmVjdGl2ZShwLCB0YXJnZXRNb2R1bGVzKTsKICAgICAgICAgICAgZXh0cmEuYWRkKGQpOwogICAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIGJvb2xlYW4gaXNLbm93bk1vZHVsZShNb2R1bGVTeW1ib2wgbXN5bSwgU2V0PE1vZHVsZVN5bWJvbD4gdW5rbm93bk1vZHVsZXMpIHsKICAgICAgICBpZiAoYWxsTW9kdWxlcy5jb250YWlucyhtc3ltKSkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIGlmICghdW5rbm93bk1vZHVsZXMuY29udGFpbnMobXN5bSkpIHsKICAgICAgICAgICAgaWYgKGxpbnRPcHRpb25zKSB7CiAgICAgICAgICAgICAgICBsb2cud2FybmluZyhMaW50Q2F0ZWdvcnkuT1BUSU9OUywKICAgICAgICAgICAgICAgICAgICAgICAgV2FybmluZ3MuTW9kdWxlRm9yT3B0aW9uTm90Rm91bmQoT3B0aW9uLkFERF9FWFBPUlRTLCBtc3ltKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdW5rbm93bk1vZHVsZXMuYWRkKG1zeW0pOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgcHJpdmF0ZSB2b2lkIGluaXRBZGRSZWFkcygpIHsKICAgICAgICBpZiAoYWRkUmVhZHMgIT0gbnVsbCkKICAgICAgICAgICAgcmV0dXJuOwoKICAgICAgICBhZGRSZWFkcyA9IG5ldyBMaW5rZWRIYXNoTWFwPD4oKTsKCiAgICAgICAgaWYgKGFkZFJlYWRzT3B0ID09IG51bGwpCiAgICAgICAgICAgIHJldHVybjsKCiAgICAgICAgUGF0dGVybiBycCA9IFBhdHRlcm4uY29tcGlsZSgiKFtePV0rKT0oLiopIik7CiAgICAgICAgZm9yIChTdHJpbmcgcyA6IGFkZFJlYWRzT3B0LnNwbGl0KCJcMCsiKSkgewogICAgICAgICAgICBpZiAocy5pc0VtcHR5KCkpCiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgTWF0Y2hlciBybSA9IHJwLm1hdGNoZXIocyk7CiAgICAgICAgICAgIGlmICghcm0ubWF0Y2hlcygpKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gVGVybWlub2xvZ3kgY29tZXMgZnJvbQogICAgICAgICAgICAvLyAgLS1hZGQtcmVhZHMgc291cmNlLW1vZHVsZT10YXJnZXQtbW9kdWxlLC4uLgogICAgICAgICAgICAvLyBDb21wYXJlIHRvCiAgICAgICAgICAgIC8vICBtb2R1bGUgc291cmNlLW1vZHVsZSB7IHJlcXVpcmVzIHRhcmdldC1tb2R1bGU7IC4uLiB9CiAgICAgICAgICAgIFN0cmluZyBzb3VyY2VOYW1lID0gcm0uZ3JvdXAoMSk7CiAgICAgICAgICAgIFN0cmluZyB0YXJnZXROYW1lcyA9IHJtLmdyb3VwKDIpOwoKICAgICAgICAgICAgaWYgKCFpc1ZhbGlkTmFtZShzb3VyY2VOYW1lKSkKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwoKICAgICAgICAgICAgTW9kdWxlU3ltYm9sIG1zeW0gPSBzeW1zLmVudGVyTW9kdWxlKG5hbWVzLmZyb21TdHJpbmcoc291cmNlTmFtZSkpOwogICAgICAgICAgICBpZiAoIWFsbE1vZHVsZXMuY29udGFpbnMobXN5bSkpIHsKICAgICAgICAgICAgICAgIGlmIChsaW50T3B0aW9ucykgewogICAgICAgICAgICAgICAgICAgIGxvZy53YXJuaW5nKFdhcm5pbmdzLk1vZHVsZUZvck9wdGlvbk5vdEZvdW5kKE9wdGlvbi5BRERfUkVBRFMsIG1zeW0pKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBmb3IgKFN0cmluZyB0YXJnZXROYW1lIDogdGFyZ2V0TmFtZXMuc3BsaXQoIlsgLF0rIiwgLTEpKSB7CiAgICAgICAgICAgICAgICBNb2R1bGVTeW1ib2wgdGFyZ2V0TW9kdWxlOwogICAgICAgICAgICAgICAgaWYgKHRhcmdldE5hbWUuZXF1YWxzKCJBTEwtVU5OQU1FRCIpKSB7CiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0TW9kdWxlID0gc3ltcy51bm5hbWVkTW9kdWxlOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBpZiAoIWlzVmFsaWROYW1lKHRhcmdldE5hbWUpKQogICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICB0YXJnZXRNb2R1bGUgPSBzeW1zLmVudGVyTW9kdWxlKG5hbWVzLmZyb21TdHJpbmcodGFyZ2V0TmFtZSkpOwogICAgICAgICAgICAgICAgICAgIGlmICghYWxsTW9kdWxlcy5jb250YWlucyh0YXJnZXRNb2R1bGUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChsaW50T3B0aW9ucykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9nLndhcm5pbmcoTGludENhdGVnb3J5Lk9QVElPTlMsIFdhcm5pbmdzLk1vZHVsZUZvck9wdGlvbk5vdEZvdW5kKE9wdGlvbi5BRERfUkVBRFMsIHRhcmdldE1vZHVsZSkpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGFkZFJlYWRzLmNvbXB1dGVJZkFic2VudChtc3ltLCBtIC0+IG5ldyBIYXNoU2V0PD4oKSkKICAgICAgICAgICAgICAgICAgICAgICAgLmFkZChuZXcgUmVxdWlyZXNEaXJlY3RpdmUodGFyZ2V0TW9kdWxlLCBFbnVtU2V0Lm9mKFJlcXVpcmVzRmxhZy5FWFRSQSkpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIHZvaWQgY2hlY2tDeWNsaWNEZXBlbmRlbmNpZXMoSkNNb2R1bGVEZWNsIG1vZCkgewogICAgICAgIGZvciAoSkNEaXJlY3RpdmUgZCA6IG1vZC5kaXJlY3RpdmVzKSB7CiAgICAgICAgICAgIEpDUmVxdWlyZXMgcmQ7CiAgICAgICAgICAgIGlmICghZC5oYXNUYWcoVGFnLlJFUVVJUkVTKSB8fCAocmQgPSAoSkNSZXF1aXJlcykgZCkuZGlyZWN0aXZlID09IG51bGwpCiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgU2V0PE1vZHVsZVN5bWJvbD4gbm9uU3ludGhldGljRGVwcyA9IG5ldyBIYXNoU2V0PD4oKTsKICAgICAgICAgICAgTGlzdDxNb2R1bGVTeW1ib2w+IHF1ZXVlID0gTGlzdC5vZihyZC5kaXJlY3RpdmUubW9kdWxlKTsKICAgICAgICAgICAgd2hpbGUgKHF1ZXVlLm5vbkVtcHR5KCkpIHsKICAgICAgICAgICAgICAgIE1vZHVsZVN5bWJvbCBjdXJyZW50ID0gcXVldWUuaGVhZDsKICAgICAgICAgICAgICAgIHF1ZXVlID0gcXVldWUudGFpbDsKICAgICAgICAgICAgICAgIGlmICghbm9uU3ludGhldGljRGVwcy5hZGQoY3VycmVudCkpCiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICBjdXJyZW50LmNvbXBsZXRlKCk7CiAgICAgICAgICAgICAgICBpZiAoKGN1cnJlbnQuZmxhZ3MoKSAmIEZsYWdzLkFDWUNMSUMpICE9IDApCiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICBBc3NlcnQuY2hlY2tOb25OdWxsKGN1cnJlbnQucmVxdWlyZXMsIGN1cnJlbnQ6OnRvU3RyaW5nKTsKICAgICAgICAgICAgICAgIGZvciAoUmVxdWlyZXNEaXJlY3RpdmUgZGVwIDogY3VycmVudC5yZXF1aXJlcykgewogICAgICAgICAgICAgICAgICAgIGlmICghZGVwLmZsYWdzLmNvbnRhaW5zKFJlcXVpcmVzRmxhZy5FWFRSQSkpCiAgICAgICAgICAgICAgICAgICAgICAgIHF1ZXVlID0gcXVldWUucHJlcGVuZChkZXAubW9kdWxlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAobm9uU3ludGhldGljRGVwcy5jb250YWlucyhtb2Quc3ltKSkgewogICAgICAgICAgICAgICAgbG9nLmVycm9yKHJkLm1vZHVsZU5hbWUucG9zKCksIEVycm9ycy5DeWNsaWNSZXF1aXJlcyhyZC5kaXJlY3RpdmUubW9kdWxlKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgbW9kLnN5bS5mbGFnc19maWVsZCB8PSBGbGFncy5BQ1lDTElDOwogICAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIGJvb2xlYW4gaXNWYWxpZE5hbWUoQ2hhclNlcXVlbmNlIG5hbWUpIHsKICAgICAgICByZXR1cm4gU291cmNlVmVyc2lvbi5pc05hbWUobmFtZSwgU291cmNlLnRvU291cmNlVmVyc2lvbihzb3VyY2UpKTsKICAgIH0KCiAgICAvLyBERUJVRwogICAgcHJpdmF0ZSBTdHJpbmcgdG9TdHJpbmcoTW9kdWxlU3ltYm9sIG1zeW0pIHsKICAgICAgICByZXR1cm4gbXN5bS5uYW1lICsgIlsiCiAgICAgICAgICAgICAgICArICJraW5kOiIgKyBtc3ltLmtpbmQgKyAiOyIKICAgICAgICAgICAgICAgICsgImxvY246IiArIHRvU3RyaW5nKG1zeW0uc291cmNlTG9jYXRpb24pICsgIiwiICsgdG9TdHJpbmcobXN5bS5jbGFzc0xvY2F0aW9uKSArICI7IgogICAgICAgICAgICAgICAgKyAiaW5mbzoiICsgdG9TdHJpbmcobXN5bS5tb2R1bGVfaW5mby5zb3VyY2VmaWxlKSArICIsIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgKyB0b1N0cmluZyhtc3ltLm1vZHVsZV9pbmZvLmNsYXNzZmlsZSkgKyAiLCIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgbXN5bS5tb2R1bGVfaW5mby5jb21wbGV0ZXIKICAgICAgICAgICAgICAgICsgIl0iOwogICAgfQoKICAgIC8vIERFQlVHCiAgICBTdHJpbmcgdG9TdHJpbmcoTG9jYXRpb24gbG9jbikgewogICAgICAgIHJldHVybiAobG9jbiA9PSBudWxsKSA/ICItLSIgOiBsb2NuLmdldE5hbWUoKTsKICAgIH0KCiAgICAvLyBERUJVRwogICAgU3RyaW5nIHRvU3RyaW5nKEphdmFGaWxlT2JqZWN0IGZvKSB7CiAgICAgICAgcmV0dXJuIChmbyA9PSBudWxsKSA/ICItLSIgOiBmby5nZXROYW1lKCk7CiAgICB9CgogICAgcHVibGljIHZvaWQgbmV3Um91bmQoKSB7CiAgICAgICAgYWxsTW9kdWxlcyA9IG51bGw7CiAgICAgICAgcm9vdE1vZHVsZXMgPSBudWxsOwogICAgICAgIHdhcm5lZE1pc3NpbmcuY2xlYXIoKTsKICAgIH0KfQpQSwMECgAACAAA0n1NSspkr7mxDAAAsQwAACsAAABjb20vc3VuL3Rvb2xzL2phdmFjL2NvbXAvQ29tcGlsZVN0YXRlcy5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDEzLCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuamF2YWMuY29tcDsKCmltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKCmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuQ29udGV4dDsKCi8qKiBQYXJ0aWFsIG1hcCB0byByZWNvcmQgd2hpY2ggY29tcGlsZXIgcGhhc2VzIGhhdmUgYmVlbiBleGVjdXRlZAogKiAgZm9yIGVhY2ggY29tcGlsYXRpb24gdW5pdC4gVXNlZCBmb3IgQVRUUiBhbmQgRkxPVyBwaGFzZXMuCiAqCiAqICA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiAgSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93biByaXNrLgogKiAgVGhpcyBjb2RlIGFuZCBpdHMgaW50ZXJuYWwgaW50ZXJmYWNlcyBhcmUgc3ViamVjdCB0byBjaGFuZ2Ugb3IKICogIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj4KICovCnB1YmxpYyBjbGFzcyBDb21waWxlU3RhdGVzIGV4dGVuZHMgSGFzaE1hcDxFbnY8QXR0ckNvbnRleHQ+LCBDb21waWxlU3RhdGVzLkNvbXBpbGVTdGF0ZT4gewogICAgLyoqIFRoZSBjb250ZXh0IGtleSBmb3IgdGhlIGNvbXBpbGUgc3RhdGVzLiAqLwogICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBDb250ZXh0LktleTxDb21waWxlU3RhdGVzPiBjb21waWxlU3RhdGVzS2V5ID0gbmV3IENvbnRleHQuS2V5PD4oKTsKCiAgICAvKiogR2V0IHRoZSBDb21waWxlU3RhdGVzIGluc3RhbmNlIGZvciB0aGlzIGNvbnRleHQuICovCiAgICBwdWJsaWMgc3RhdGljIENvbXBpbGVTdGF0ZXMgaW5zdGFuY2UoQ29udGV4dCBjb250ZXh0KSB7CiAgICAgICAgQ29tcGlsZVN0YXRlcyBpbnN0YW5jZSA9IGNvbnRleHQuZ2V0KGNvbXBpbGVTdGF0ZXNLZXkpOwogICAgICAgIGlmIChpbnN0YW5jZSA9PSBudWxsKSB7CiAgICAgICAgICAgIGluc3RhbmNlID0gbmV3IENvbXBpbGVTdGF0ZXMoY29udGV4dCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBpbnN0YW5jZTsKICAgIH0KCiAgICAvKiogT3JkZXJlZCBsaXN0IG9mIGNvbXBpbGVyIHBoYXNlcyBmb3IgZWFjaCBjb21waWxhdGlvbiB1bml0LiAqLwogICAgcHVibGljIGVudW0gQ29tcGlsZVN0YXRlIHsKICAgICAgICBJTklUKDApLAogICAgICAgIFBBUlNFKDEpLAogICAgICAgIEVOVEVSKDIpLAogICAgICAgIFBST0NFU1MoMyksCiAgICAgICAgQVRUUig0KSwKICAgICAgICBGTE9XKDUpLAogICAgICAgIFRSQU5TVFlQRVMoNiksCiAgICAgICAgVU5MQU1CREEoNyksCiAgICAgICAgTE9XRVIoOCksCiAgICAgICAgR0VORVJBVEUoOSk7CgogICAgICAgIENvbXBpbGVTdGF0ZShpbnQgdmFsdWUpIHsKICAgICAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlOwogICAgICAgIH0KICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc0FmdGVyKENvbXBpbGVTdGF0ZSBvdGhlcikgewogICAgICAgICAgICByZXR1cm4gdmFsdWUgPiBvdGhlci52YWx1ZTsKICAgICAgICB9CiAgICAgICAgcHVibGljIHN0YXRpYyBDb21waWxlU3RhdGUgbWF4KENvbXBpbGVTdGF0ZSBhLCBDb21waWxlU3RhdGUgYikgewogICAgICAgICAgICByZXR1cm4gYS52YWx1ZSA+IGIudmFsdWUgPyBhIDogYjsKICAgICAgICB9CiAgICAgICAgcHJpdmF0ZSBmaW5hbCBpbnQgdmFsdWU7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMTgxMjI2NzUyNDE0MDQyNDQzM0w7CgogICAgcHJvdGVjdGVkIENvbnRleHQgY29udGV4dDsKCiAgICBwdWJsaWMgQ29tcGlsZVN0YXRlcyhDb250ZXh0IGNvbnRleHQpIHsKICAgICAgICB0aGlzLmNvbnRleHQgPSBjb250ZXh0OwogICAgICAgIGNvbnRleHQucHV0KGNvbXBpbGVTdGF0ZXNLZXksIHRoaXMpOwogICAgfQoKICAgIHB1YmxpYyBib29sZWFuIGlzRG9uZShFbnY8QXR0ckNvbnRleHQ+IGVudiwgQ29tcGlsZVN0YXRlIGNzKSB7CiAgICAgICAgQ29tcGlsZVN0YXRlIGVjcyA9IGdldChlbnYpOwogICAgICAgIHJldHVybiAoZWNzICE9IG51bGwpICYmICFjcy5pc0FmdGVyKGVjcyk7CiAgICB9Cn0KUEsDBAoAAAgAAAY7qUr82TWRJ4wBACeMAQAsAAAAY29tL3N1bi90b29scy9qYXZhYy9jb21wL0xhbWJkYVRvTWV0aG9kLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTAsIDIwMTYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhYy5jb21wOwoKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS4qOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkpDVHJlZS4qOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkpDVHJlZS5KQ01lbWJlclJlZmVyZW5jZS5SZWZlcmVuY2VLaW5kOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLlRyZWVNYWtlcjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5UcmVlVHJhbnNsYXRvcjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5BdHRyaWJ1dGU7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuU2NvcGUuV3JpdGVhYmxlU2NvcGU7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuU3ltYm9sOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlN5bWJvbC5DbGFzc1N5bWJvbDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5TeW1ib2wuRHluYW1pY01ldGhvZFN5bWJvbDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5TeW1ib2wuTWV0aG9kU3ltYm9sOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlN5bWJvbC5UeXBlU3ltYm9sOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlN5bWJvbC5WYXJTeW1ib2w7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuU3ltdGFiOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlR5cGU7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuVHlwZS5NZXRob2RUeXBlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlR5cGUuVHlwZVZhcjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5UeXBlczsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29tcC5MYW1iZGFUb01ldGhvZC5MYW1iZGFBbmFseXplclByZXByb2Nlc3Nvci4qOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb21wLkxvd2VyLkJhc2ljRnJlZVZhckNvbGxlY3RvcjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuanZtLio7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuKjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5KQ0RpYWdub3N0aWMuRGlhZ25vc3RpY1Bvc2l0aW9uOwppbXBvcnQgY29tLnN1bi5zb3VyY2UudHJlZS5NZW1iZXJSZWZlcmVuY2VUcmVlLlJlZmVyZW5jZU1vZGU7CgppbXBvcnQgamF2YS51dGlsLkVudW1NYXA7CmltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKaW1wb3J0IGphdmEudXRpbC5IYXNoU2V0OwppbXBvcnQgamF2YS51dGlsLkxpbmtlZEhhc2hNYXA7CmltcG9ydCBqYXZhLnV0aWwuTWFwOwppbXBvcnQgamF2YS51dGlsLlNldDsKaW1wb3J0IGphdmEudXRpbC5mdW5jdGlvbi5Db25zdW1lcjsKaW1wb3J0IGphdmEudXRpbC5mdW5jdGlvbi5TdXBwbGllcjsKCmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5jb21wLkxhbWJkYVRvTWV0aG9kLkxhbWJkYVN5bWJvbEtpbmQuKjsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuRmxhZ3MuKjsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuS2luZHMuS2luZC4qOwppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5UeXBlVGFnLio7CmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkpDVHJlZS5UYWcuKjsKCmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuRWxlbWVudEtpbmQ7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLnR5cGUuVHlwZUtpbmQ7CgppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5tYWluLk9wdGlvbjsKCi8qKgogKiBUaGlzIHBhc3MgZGVzdWdhcnMgbGFtYmRhIGV4cHJlc3Npb25zIGludG8gc3RhdGljIG1ldGhvZHMKICoKICogIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqICBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqICBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogKiAgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPgogKi8KcHVibGljIGNsYXNzIExhbWJkYVRvTWV0aG9kIGV4dGVuZHMgVHJlZVRyYW5zbGF0b3IgewoKICAgIHByaXZhdGUgQXR0ciBhdHRyOwogICAgcHJpdmF0ZSBKQ0RpYWdub3N0aWMuRmFjdG9yeSBkaWFnczsKICAgIHByaXZhdGUgTG9nIGxvZzsKICAgIHByaXZhdGUgTG93ZXIgbG93ZXI7CiAgICBwcml2YXRlIE5hbWVzIG5hbWVzOwogICAgcHJpdmF0ZSBTeW10YWIgc3ltczsKICAgIHByaXZhdGUgUmVzb2x2ZSByczsKICAgIHByaXZhdGUgT3BlcmF0b3JzIG9wZXJhdG9yczsKICAgIHByaXZhdGUgVHJlZU1ha2VyIG1ha2U7CiAgICBwcml2YXRlIFR5cGVzIHR5cGVzOwogICAgcHJpdmF0ZSBUcmFuc1R5cGVzIHRyYW5zVHlwZXM7CiAgICBwcml2YXRlIEVudjxBdHRyQ29udGV4dD4gYXR0ckVudjsKCiAgICAvKiogdGhlIGFuYWx5emVyIHNjYW5uZXIgKi8KICAgIHByaXZhdGUgTGFtYmRhQW5hbHl6ZXJQcmVwcm9jZXNzb3IgYW5hbHl6ZXI7CgogICAgLyoqIG1hcCBmcm9tIGxhbWJkYSB0cmVlcyB0byB0cmFuc2xhdGlvbiBjb250ZXh0cyAqLwogICAgcHJpdmF0ZSBNYXA8SkNUcmVlLCBUcmFuc2xhdGlvbkNvbnRleHQ8Pz4+IGNvbnRleHRNYXA7CgogICAgLyoqIGN1cnJlbnQgdHJhbnNsYXRpb24gY29udGV4dCAodmlzaXRvciBhcmd1bWVudCkgKi8KICAgIHByaXZhdGUgVHJhbnNsYXRpb25Db250ZXh0PD8+IGNvbnRleHQ7CgogICAgLyoqIGluZm8gYWJvdXQgdGhlIGN1cnJlbnQgY2xhc3MgYmVpbmcgcHJvY2Vzc2VkICovCiAgICBwcml2YXRlIEtsYXNzSW5mbyBrSW5mbzsKCiAgICAvKiogZHVtcCBzdGF0aXN0aWNzIGFib3V0IGxhbWJkYSBjb2RlIGdlbmVyYXRpb24gKi8KICAgIHByaXZhdGUgZmluYWwgYm9vbGVhbiBkdW1wTGFtYmRhVG9NZXRob2RTdGF0czsKCiAgICAvKiogZm9yY2Ugc2VyaWFsaXphYmxlIHJlcHJlc2VudGF0aW9uLCBmb3Igc3RyZXNzIHRlc3RpbmcgKiovCiAgICBwcml2YXRlIGZpbmFsIGJvb2xlYW4gZm9yY2VTZXJpYWxpemFibGU7CgogICAgLyoqIEZsYWcgZm9yIGFsdGVybmF0ZSBtZXRhZmFjdG9yaWVzIGluZGljYXRpbmcgdGhlIGxhbWJkYSBvYmplY3QgaXMgaW50ZW5kZWQgdG8gYmUgc2VyaWFsaXphYmxlICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGTEFHX1NFUklBTElaQUJMRSA9IDEgPDwgMDsKCiAgICAvKiogRmxhZyBmb3IgYWx0ZXJuYXRlIG1ldGFmYWN0b3JpZXMgaW5kaWNhdGluZyB0aGUgbGFtYmRhIG9iamVjdCBoYXMgbXVsdGlwbGUgdGFyZ2V0cyAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRkxBR19NQVJLRVJTID0gMSA8PCAxOwoKICAgIC8qKiBGbGFnIGZvciBhbHRlcm5hdGUgbWV0YWZhY3RvcmllcyBpbmRpY2F0aW5nIHRoZSBsYW1iZGEgb2JqZWN0IHJlcXVpcmVzIG11bHRpcGxlIGJyaWRnZXMgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZMQUdfQlJJREdFUyA9IDEgPDwgMjsKCiAgICAvLyA8ZWRpdG9yLWZvbGQgZGVmYXVsdHN0YXRlPSJjb2xsYXBzZWQiIGRlc2M9Ikluc3RhbnRpYXRpbmciPgogICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBDb250ZXh0LktleTxMYW1iZGFUb01ldGhvZD4gdW5sYW1iZGFLZXkgPSBuZXcgQ29udGV4dC5LZXk8PigpOwoKICAgIHB1YmxpYyBzdGF0aWMgTGFtYmRhVG9NZXRob2QgaW5zdGFuY2UoQ29udGV4dCBjb250ZXh0KSB7CiAgICAgICAgTGFtYmRhVG9NZXRob2QgaW5zdGFuY2UgPSBjb250ZXh0LmdldCh1bmxhbWJkYUtleSk7CiAgICAgICAgaWYgKGluc3RhbmNlID09IG51bGwpIHsKICAgICAgICAgICAgaW5zdGFuY2UgPSBuZXcgTGFtYmRhVG9NZXRob2QoY29udGV4dCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBpbnN0YW5jZTsKICAgIH0KICAgIHByaXZhdGUgTGFtYmRhVG9NZXRob2QoQ29udGV4dCBjb250ZXh0KSB7CiAgICAgICAgY29udGV4dC5wdXQodW5sYW1iZGFLZXksIHRoaXMpOwogICAgICAgIGRpYWdzID0gSkNEaWFnbm9zdGljLkZhY3RvcnkuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgbG9nID0gTG9nLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIGxvd2VyID0gTG93ZXIuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgbmFtZXMgPSBOYW1lcy5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBzeW1zID0gU3ltdGFiLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIHJzID0gUmVzb2x2ZS5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBvcGVyYXRvcnMgPSBPcGVyYXRvcnMuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgbWFrZSA9IFRyZWVNYWtlci5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICB0eXBlcyA9IFR5cGVzLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIHRyYW5zVHlwZXMgPSBUcmFuc1R5cGVzLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIGFuYWx5emVyID0gbmV3IExhbWJkYUFuYWx5emVyUHJlcHJvY2Vzc29yKCk7CiAgICAgICAgT3B0aW9ucyBvcHRpb25zID0gT3B0aW9ucy5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBkdW1wTGFtYmRhVG9NZXRob2RTdGF0cyA9IG9wdGlvbnMuaXNTZXQoImRlYnVnLmR1bXBMYW1iZGFUb01ldGhvZFN0YXRzIik7CiAgICAgICAgYXR0ciA9IEF0dHIuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgZm9yY2VTZXJpYWxpemFibGUgPSBvcHRpb25zLmlzU2V0KCJmb3JjZVNlcmlhbGl6YWJsZSIpOwogICAgfQogICAgLy8gPC9lZGl0b3ItZm9sZD4KCiAgICBwcml2YXRlIGNsYXNzIEtsYXNzSW5mbyB7CgogICAgICAgIC8qKgogICAgICAgICAqIGxpc3Qgb2YgbWV0aG9kcyB0byBhcHBlbmQKICAgICAgICAgKi8KICAgICAgICBwcml2YXRlIExpc3RCdWZmZXI8SkNUcmVlPiBhcHBlbmRlZE1ldGhvZExpc3Q7CgogICAgICAgIC8qKgogICAgICAgICAqIGxpc3Qgb2YgZGVzZXJpYWxpemF0aW9uIGNhc2VzCiAgICAgICAgICovCiAgICAgICAgcHJpdmF0ZSBmaW5hbCBNYXA8U3RyaW5nLCBMaXN0QnVmZmVyPEpDU3RhdGVtZW50Pj4gZGVzZXJpYWxpemVDYXNlczsKCiAgICAgICAvKioKICAgICAgICAgKiBkZXNlcmlhbGl6ZSBtZXRob2Qgc3ltYm9sCiAgICAgICAgICovCiAgICAgICAgcHJpdmF0ZSBmaW5hbCBNZXRob2RTeW1ib2wgZGVzZXJNZXRob2RTeW07CgogICAgICAgIC8qKgogICAgICAgICAqIGRlc2VyaWFsaXplIG1ldGhvZCBwYXJhbWV0ZXIgc3ltYm9sCiAgICAgICAgICovCiAgICAgICAgcHJpdmF0ZSBmaW5hbCBWYXJTeW1ib2wgZGVzZXJQYXJhbVN5bTsKCiAgICAgICAgcHJpdmF0ZSBmaW5hbCBKQ0NsYXNzRGVjbCBjbGF6ejsKCiAgICAgICAgcHJpdmF0ZSBLbGFzc0luZm8oSkNDbGFzc0RlY2wgY2xhenopIHsKICAgICAgICAgICAgdGhpcy5jbGF6eiA9IGNsYXp6OwogICAgICAgICAgICBhcHBlbmRlZE1ldGhvZExpc3QgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgIGRlc2VyaWFsaXplQ2FzZXMgPSBuZXcgSGFzaE1hcDw+KCk7CiAgICAgICAgICAgIE1ldGhvZFR5cGUgdHlwZSA9IG5ldyBNZXRob2RUeXBlKExpc3Qub2Yoc3ltcy5zZXJpYWxpemVkTGFtYmRhVHlwZSksIHN5bXMub2JqZWN0VHlwZSwKICAgICAgICAgICAgICAgICAgICBMaXN0Lm5pbCgpLCBzeW1zLm1ldGhvZENsYXNzKTsKICAgICAgICAgICAgZGVzZXJNZXRob2RTeW0gPSBtYWtlUHJpdmF0ZVN5bnRoZXRpY01ldGhvZChTVEFUSUMsIG5hbWVzLmRlc2VyaWFsaXplTGFtYmRhLCB0eXBlLCBjbGF6ei5zeW0pOwogICAgICAgICAgICBkZXNlclBhcmFtU3ltID0gbmV3IFZhclN5bWJvbChGSU5BTCwgbmFtZXMuZnJvbVN0cmluZygibGFtYmRhIiksCiAgICAgICAgICAgICAgICAgICAgc3ltcy5zZXJpYWxpemVkTGFtYmRhVHlwZSwgZGVzZXJNZXRob2RTeW0pOwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSB2b2lkIGFkZE1ldGhvZChKQ1RyZWUgZGVjbCkgewogICAgICAgICAgICBhcHBlbmRlZE1ldGhvZExpc3QgPSBhcHBlbmRlZE1ldGhvZExpc3QucHJlcGVuZChkZWNsKTsKICAgICAgICB9CiAgICB9CgogICAgLy8gPGVkaXRvci1mb2xkIGRlZmF1bHRzdGF0ZT0iY29sbGFwc2VkIiBkZXNjPSJ0cmFuc2xhdGUgbWV0aG9kcyI+CiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyA8VCBleHRlbmRzIEpDVHJlZT4gVCB0cmFuc2xhdGUoVCB0cmVlKSB7CiAgICAgICAgVHJhbnNsYXRpb25Db250ZXh0PD8+IG5ld0NvbnRleHQgPSBjb250ZXh0TWFwLmdldCh0cmVlKTsKICAgICAgICByZXR1cm4gdHJhbnNsYXRlKHRyZWUsIG5ld0NvbnRleHQgIT0gbnVsbCA/IG5ld0NvbnRleHQgOiBjb250ZXh0KTsKICAgIH0KCiAgICA8VCBleHRlbmRzIEpDVHJlZT4gVCB0cmFuc2xhdGUoVCB0cmVlLCBUcmFuc2xhdGlvbkNvbnRleHQ8Pz4gbmV3Q29udGV4dCkgewogICAgICAgIFRyYW5zbGF0aW9uQ29udGV4dDw/PiBwcmV2Q29udGV4dCA9IGNvbnRleHQ7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgY29udGV4dCA9IG5ld0NvbnRleHQ7CiAgICAgICAgICAgIHJldHVybiBzdXBlci50cmFuc2xhdGUodHJlZSk7CiAgICAgICAgfQogICAgICAgIGZpbmFsbHkgewogICAgICAgICAgICBjb250ZXh0ID0gcHJldkNvbnRleHQ7CiAgICAgICAgfQogICAgfQoKICAgIDxUIGV4dGVuZHMgSkNUcmVlPiBMaXN0PFQ+IHRyYW5zbGF0ZShMaXN0PFQ+IHRyZWVzLCBUcmFuc2xhdGlvbkNvbnRleHQ8Pz4gbmV3Q29udGV4dCkgewogICAgICAgIExpc3RCdWZmZXI8VD4gYnVmID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgIGZvciAoVCB0cmVlIDogdHJlZXMpIHsKICAgICAgICAgICAgYnVmLmFwcGVuZCh0cmFuc2xhdGUodHJlZSwgbmV3Q29udGV4dCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVmLnRvTGlzdCgpOwogICAgfQoKICAgIHB1YmxpYyBKQ1RyZWUgdHJhbnNsYXRlVG9wTGV2ZWxDbGFzcyhFbnY8QXR0ckNvbnRleHQ+IGVudiwgSkNUcmVlIGNkZWYsIFRyZWVNYWtlciBtYWtlKSB7CiAgICAgICAgdGhpcy5tYWtlID0gbWFrZTsKICAgICAgICB0aGlzLmF0dHJFbnYgPSBlbnY7CiAgICAgICAgdGhpcy5jb250ZXh0ID0gbnVsbDsKICAgICAgICB0aGlzLmNvbnRleHRNYXAgPSBuZXcgSGFzaE1hcDw+KCk7CiAgICAgICAgcmV0dXJuIHRyYW5zbGF0ZShjZGVmKTsKICAgIH0KICAgIC8vIDwvZWRpdG9yLWZvbGQ+CgogICAgLy8gPGVkaXRvci1mb2xkIGRlZmF1bHRzdGF0ZT0iY29sbGFwc2VkIiBkZXNjPSJ2aXNpdG9yIG1ldGhvZHMiPgogICAgLyoqCiAgICAgKiBWaXNpdCBhIGNsYXNzLgogICAgICogTWFpbnRhaW4gdGhlIHRyYW5zbGF0ZWRNZXRob2RMaXN0IGFjcm9zcyBuZXN0ZWQgY2xhc3Nlcy4KICAgICAqIEFwcGVuZCB0aGUgdHJhbnNsYXRlZE1ldGhvZExpc3QgdG8gdGhlIGNsYXNzIGFmdGVyIGl0IGlzIHRyYW5zbGF0ZWQuCiAgICAgKiBAcGFyYW0gdHJlZQogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHZpc2l0Q2xhc3NEZWYoSkNDbGFzc0RlY2wgdHJlZSkgewogICAgICAgIGlmICh0cmVlLnN5bS5vd25lci5raW5kID09IFBDSykgewogICAgICAgICAgICAvL2FuYWx5emUgY2xhc3MKICAgICAgICAgICAgdHJlZSA9IGFuYWx5emVyLmFuYWx5emVBbmRQcmVwcm9jZXNzQ2xhc3ModHJlZSk7CiAgICAgICAgfQogICAgICAgIEtsYXNzSW5mbyBwcmV2S2xhc3NJbmZvID0ga0luZm87CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAga0luZm8gPSBuZXcgS2xhc3NJbmZvKHRyZWUpOwogICAgICAgICAgICBzdXBlci52aXNpdENsYXNzRGVmKHRyZWUpOwogICAgICAgICAgICBpZiAoIWtJbmZvLmRlc2VyaWFsaXplQ2FzZXMuaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgICBpbnQgcHJldlBvcyA9IG1ha2UucG9zOwogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICBtYWtlLmF0KHRyZWUpOwogICAgICAgICAgICAgICAgICAgIGtJbmZvLmFkZE1ldGhvZChtYWtlRGVzZXJpYWxpemVNZXRob2QodHJlZS5zeW0pKTsKICAgICAgICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgICAgICAgICAgbWFrZS5hdChwcmV2UG9zKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICAvL2FkZCBhbGwgdHJhbnNsYXRlZCBpbnN0YW5jZSBtZXRob2RzIGhlcmUKICAgICAgICAgICAgTGlzdDxKQ1RyZWU+IG5ld01ldGhvZHMgPSBrSW5mby5hcHBlbmRlZE1ldGhvZExpc3QudG9MaXN0KCk7CiAgICAgICAgICAgIHRyZWUuZGVmcyA9IHRyZWUuZGVmcy5hcHBlbmRMaXN0KG5ld01ldGhvZHMpOwogICAgICAgICAgICBmb3IgKEpDVHJlZSBsYW1iZGEgOiBuZXdNZXRob2RzKSB7CiAgICAgICAgICAgICAgICB0cmVlLnN5bS5tZW1iZXJzKCkuZW50ZXIoKChKQ01ldGhvZERlY2wpbGFtYmRhKS5zeW0pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJlc3VsdCA9IHRyZWU7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAga0luZm8gPSBwcmV2S2xhc3NJbmZvOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFRyYW5zbGF0ZSBhIGxhbWJkYSBpbnRvIGEgbWV0aG9kIHRvIGJlIGluc2VydGVkIGludG8gdGhlIGNsYXNzLgogICAgICogVGhlbiByZXBsYWNlIHRoZSBsYW1iZGEgc2l0ZSB3aXRoIGFuIGludm9rZWR5bmFtaWMgY2FsbCBvZiB0byBsYW1iZGEKICAgICAqIG1ldGEtZmFjdG9yeSwgd2hpY2ggd2lsbCB1c2UgdGhlIGxhbWJkYSBtZXRob2QuCiAgICAgKiBAcGFyYW0gdHJlZQogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHZpc2l0TGFtYmRhKEpDTGFtYmRhIHRyZWUpIHsKICAgICAgICBMYW1iZGFUcmFuc2xhdGlvbkNvbnRleHQgbG9jYWxDb250ZXh0ID0gKExhbWJkYVRyYW5zbGF0aW9uQ29udGV4dCljb250ZXh0OwogICAgICAgIE1ldGhvZFN5bWJvbCBzeW0gPSBsb2NhbENvbnRleHQudHJhbnNsYXRlZFN5bTsKICAgICAgICBNZXRob2RUeXBlIGxhbWJkYVR5cGUgPSAoTWV0aG9kVHlwZSkgc3ltLnR5cGU7CgogICAgICAgIHsgICAvKiBUeXBlIGFubm90YXRpb24gbWFuYWdlbWVudDogQmFzZWQgb24gd2hlcmUgdGhlIGxhbWJkYSBmZWF0dXJlcywgdHlwZSBhbm5vdGF0aW9ucyB0aGF0CiAgICAgICAgICAgICAgIGFyZSBpbnRlcmlvciB0byBpdCwgbWF5IGF0IHRoaXMgcG9pbnQgYmUgYXR0YWNoZWQgdG8gdGhlIGVuY2xvc2luZyBtZXRob2QsIG9yIHRoZSBmaXJzdAogICAgICAgICAgICAgICBjb25zdHJ1Y3RvciBpbiB0aGUgY2xhc3MsIG9yIGluIHRoZSBlbmNsb3NpbmcgY2xhc3Mgc3ltYm9sIG9yIGluIHRoZSBmaWVsZCB3aG9zZQogICAgICAgICAgICAgICBpbml0aWFsaXplciBpcyB0aGUgbGFtYmRhLiBJbiBhbnkgZXZlbnQsIGdhdGhlciB1cCB0aGUgYW5ub3RhdGlvbnMgdGhhdCBiZWxvbmcgdG8gdGhlCiAgICAgICAgICAgICAgIGxhbWJkYSBhbmQgYXR0YWNoIGl0IHRvIHRoZSBpbXBsZW1lbnRhdGlvbiBtZXRob2QuCiAgICAgICAgICAgICovCgogICAgICAgICAgICBTeW1ib2wgb3duZXIgPSBsb2NhbENvbnRleHQub3duZXI7CiAgICAgICAgICAgIGFwcG9ydGlvblR5cGVBbm5vdGF0aW9ucyh0cmVlLAogICAgICAgICAgICAgICAgICAgIG93bmVyOjpnZXRSYXdUeXBlQXR0cmlidXRlcywKICAgICAgICAgICAgICAgICAgICBvd25lcjo6c2V0VHlwZUF0dHJpYnV0ZXMsCiAgICAgICAgICAgICAgICAgICAgc3ltOjpzZXRUeXBlQXR0cmlidXRlcyk7CgoKICAgICAgICAgICAgYm9vbGVhbiBpbml0OwogICAgICAgICAgICBpZiAoKGluaXQgPSAob3duZXIubmFtZSA9PSBuYW1lcy5pbml0KSkgfHwgb3duZXIubmFtZSA9PSBuYW1lcy5jbGluaXQpIHsKICAgICAgICAgICAgICAgIG93bmVyID0gb3duZXIub3duZXI7CiAgICAgICAgICAgICAgICBhcHBvcnRpb25UeXBlQW5ub3RhdGlvbnModHJlZSwKICAgICAgICAgICAgICAgICAgICAgICAgaW5pdCA/IG93bmVyOjpnZXRJbml0VHlwZUF0dHJpYnV0ZXMgOiBvd25lcjo6Z2V0Q2xhc3NJbml0VHlwZUF0dHJpYnV0ZXMsCiAgICAgICAgICAgICAgICAgICAgICAgIGluaXQgPyBvd25lcjo6c2V0SW5pdFR5cGVBdHRyaWJ1dGVzIDogb3duZXI6OnNldENsYXNzSW5pdFR5cGVBdHRyaWJ1dGVzLAogICAgICAgICAgICAgICAgICAgICAgICBzeW06OmFwcGVuZFVuaXF1ZVR5cGVBdHRyaWJ1dGVzKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAobG9jYWxDb250ZXh0LnNlbGYgIT0gbnVsbCAmJiBsb2NhbENvbnRleHQuc2VsZi5nZXRLaW5kKCkgPT0gRWxlbWVudEtpbmQuRklFTEQpIHsKICAgICAgICAgICAgICAgIG93bmVyID0gbG9jYWxDb250ZXh0LnNlbGY7CiAgICAgICAgICAgICAgICBhcHBvcnRpb25UeXBlQW5ub3RhdGlvbnModHJlZSwKICAgICAgICAgICAgICAgICAgICAgICAgb3duZXI6OmdldFJhd1R5cGVBdHRyaWJ1dGVzLAogICAgICAgICAgICAgICAgICAgICAgICBvd25lcjo6c2V0VHlwZUF0dHJpYnV0ZXMsCiAgICAgICAgICAgICAgICAgICAgICAgIHN5bTo6YXBwZW5kVW5pcXVlVHlwZUF0dHJpYnV0ZXMpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvL2NyZWF0ZSB0aGUgbWV0aG9kIGRlY2xhcmF0aW9uIGhvaXN0aW5nIHRoZSBsYW1iZGEgYm9keQogICAgICAgIEpDTWV0aG9kRGVjbCBsYW1iZGFEZWNsID0gbWFrZS5NZXRob2REZWYobWFrZS5Nb2RpZmllcnMoc3ltLmZsYWdzX2ZpZWxkKSwKICAgICAgICAgICAgICAgIHN5bS5uYW1lLAogICAgICAgICAgICAgICAgbWFrZS5RdWFsSWRlbnQobGFtYmRhVHlwZS5nZXRSZXR1cm5UeXBlKCkudHN5bSksCiAgICAgICAgICAgICAgICBMaXN0Lm5pbCgpLAogICAgICAgICAgICAgICAgbG9jYWxDb250ZXh0LnN5bnRoZXRpY1BhcmFtcywKICAgICAgICAgICAgICAgIGxhbWJkYVR5cGUuZ2V0VGhyb3duVHlwZXMoKSA9PSBudWxsID8KICAgICAgICAgICAgICAgICAgICBMaXN0Lm5pbCgpIDoKICAgICAgICAgICAgICAgICAgICBtYWtlLlR5cGVzKGxhbWJkYVR5cGUuZ2V0VGhyb3duVHlwZXMoKSksCiAgICAgICAgICAgICAgICBudWxsLAogICAgICAgICAgICAgICAgbnVsbCk7CiAgICAgICAgbGFtYmRhRGVjbC5zeW0gPSBzeW07CiAgICAgICAgbGFtYmRhRGVjbC50eXBlID0gbGFtYmRhVHlwZTsKCiAgICAgICAgLy90cmFuc2xhdGUgbGFtYmRhIGJvZHkKICAgICAgICAvL0FzIHRoZSBsYW1iZGEgYm9keSBpcyB0cmFuc2xhdGVkLCBhbGwgcmVmZXJlbmNlcyB0byBsYW1iZGEgbG9jYWxzLAogICAgICAgIC8vY2FwdHVyZWQgdmFyaWFibGVzLCBlbmNsb3NpbmcgbWVtYmVycyBhcmUgYWRqdXN0ZWQgYWNjb3JkaW5nbHkKICAgICAgICAvL3RvIHJlZmVyIHRvIHRoZSBzdGF0aWMgbWV0aG9kIHBhcmFtZXRlcnMgKHJhdGhlciB0aGFuIGkuZS4gYWNlc3NpbmcgdG8KICAgICAgICAvL2NhcHR1cmVkIG1lbWJlcnMgZGlyZWN0bHkpLgogICAgICAgIGxhbWJkYURlY2wuYm9keSA9IHRyYW5zbGF0ZShtYWtlTGFtYmRhQm9keSh0cmVlLCBsYW1iZGFEZWNsKSk7CgogICAgICAgIC8vQWRkIHRoZSBtZXRob2QgdG8gdGhlIGxpc3Qgb2YgbWV0aG9kcyB0byBiZSBhZGRlZCB0byB0aGlzIGNsYXNzLgogICAgICAgIGtJbmZvLmFkZE1ldGhvZChsYW1iZGFEZWNsKTsKCiAgICAgICAgLy9ub3cgdGhhdCB3ZSBoYXZlIGdlbmVyYXRlZCBhIG1ldGhvZCBmb3IgdGhlIGxhbWJkYSBleHByZXNzaW9uLAogICAgICAgIC8vd2UgY2FuIHRyYW5zbGF0ZSB0aGUgbGFtYmRhIGludG8gYSBtZXRob2QgcmVmZXJlbmNlIHBvaW50aW5nIHRvIHRoZSBuZXdseQogICAgICAgIC8vY3JlYXRlZCBtZXRob2QuCiAgICAgICAgLy8KICAgICAgICAvL05vdGUgdGhhdCB3ZSBuZWVkIHRvIGFkanVzdCB0aGUgbWV0aG9kIGhhbmRsZSBzbyB0aGF0IGl0IHdpbGwgbWF0Y2ggdGhlCiAgICAgICAgLy9zaWduYXR1cmUgb2YgdGhlIFNBTSBkZXNjcmlwdG9yIC0gdGhpcyBtZWFucyB0aGF0IHRoZSBtZXRob2QgcmVmZXJlbmNlCiAgICAgICAgLy9zaG91bGQgYmUgYWRkZWQgdGhlIGZvbGxvd2luZyBzeW50aGV0aWMgYXJndW1lbnRzOgogICAgICAgIC8vCiAgICAgICAgLy8gKiB0aGUgInRoaXMiIGFyZ3VtZW50IGlmIGl0IGlzIGFuIGluc3RhbmNlIG1ldGhvZAogICAgICAgIC8vICogZW5jbG9zaW5nIGxvY2FscyBjYXB0dXJlZCBieSB0aGUgbGFtYmRhIGV4cHJlc3Npb24KCiAgICAgICAgTGlzdEJ1ZmZlcjxKQ0V4cHJlc3Npb24+IHN5bnRoZXRpY0luaXRzID0gbmV3IExpc3RCdWZmZXI8PigpOwoKICAgICAgICBpZiAobG9jYWxDb250ZXh0Lm1ldGhvZFJlZmVyZW5jZVJlY2VpdmVyICE9IG51bGwpIHsKICAgICAgICAgICAgc3ludGhldGljSW5pdHMuYXBwZW5kKGxvY2FsQ29udGV4dC5tZXRob2RSZWZlcmVuY2VSZWNlaXZlcik7CiAgICAgICAgfSBlbHNlIGlmICghc3ltLmlzU3RhdGljKCkpIHsKICAgICAgICAgICAgc3ludGhldGljSW5pdHMuYXBwZW5kKG1ha2VUaGlzKAogICAgICAgICAgICAgICAgICAgIHN5bS5vd25lci5lbmNsQ2xhc3MoKS5hc1R5cGUoKSwKICAgICAgICAgICAgICAgICAgICBsb2NhbENvbnRleHQub3duZXIuZW5jbENsYXNzKCkpKTsKICAgICAgICB9CgogICAgICAgIC8vYWRkIGNhcHR1cmVkIGxvY2FscwogICAgICAgIGZvciAoU3ltYm9sIGZ2IDogbG9jYWxDb250ZXh0LmdldFN5bWJvbE1hcChDQVBUVVJFRF9WQVIpLmtleVNldCgpKSB7CiAgICAgICAgICAgIGlmIChmdiAhPSBsb2NhbENvbnRleHQuc2VsZikgewogICAgICAgICAgICAgICAgSkNUcmVlIGNhcHR1cmVkX2xvY2FsID0gbWFrZS5JZGVudChmdikuc2V0VHlwZShmdi50eXBlKTsKICAgICAgICAgICAgICAgIHN5bnRoZXRpY0luaXRzLmFwcGVuZCgoSkNFeHByZXNzaW9uKSBjYXB0dXJlZF9sb2NhbCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLy8gYWRkIGNhcHR1cmVkIG91dGVyIHRoaXMgaW5zdGFuY2VzICh1c2VkIG9ubHkgd2hlbiBgdGhpcycgY2FwdHVyZSBpdHNlbGYgaXMgaWxsZWdhbCkKICAgICAgICBmb3IgKFN5bWJvbCBmdiA6IGxvY2FsQ29udGV4dC5nZXRTeW1ib2xNYXAoQ0FQVFVSRURfT1VURVJfVEhJUykua2V5U2V0KCkpIHsKICAgICAgICAgICAgSkNUcmVlIGNhcHR1cmVkX2xvY2FsID0gbWFrZS5RdWFsVGhpcyhmdi50eXBlKTsKICAgICAgICAgICAgc3ludGhldGljSW5pdHMuYXBwZW5kKChKQ0V4cHJlc3Npb24pIGNhcHR1cmVkX2xvY2FsKTsKICAgICAgICB9CgogICAgICAgIC8vdGhlbiwgZGV0ZXJtaW5lIHRoZSBhcmd1bWVudHMgdG8gdGhlIGluZHkgY2FsbAogICAgICAgIExpc3Q8SkNFeHByZXNzaW9uPiBpbmR5X2FyZ3MgPSB0cmFuc2xhdGUoc3ludGhldGljSW5pdHMudG9MaXN0KCksIGxvY2FsQ29udGV4dC5wcmV2KTsKCiAgICAgICAgLy9idWlsZCBhIHNhbSBpbnN0YW5jZSB1c2luZyBhbiBpbmR5IGNhbGwgdG8gdGhlIG1ldGEtZmFjdG9yeQogICAgICAgIGludCByZWZLaW5kID0gcmVmZXJlbmNlS2luZChzeW0pOwoKICAgICAgICAvL2NvbnZlcnQgdG8gYW4gaW52b2tlZHluYW1pYyBjYWxsCiAgICAgICAgcmVzdWx0ID0gbWFrZU1ldGFmYWN0b3J5SW5keUNhbGwoY29udGV4dCwgcmVmS2luZCwgc3ltLCBpbmR5X2FyZ3MpOwogICAgfQoKICAgIC8vIHdoZXJlCiAgICAgICAgLy8gUmVhc3NpZ24gdHlwZSBhbm5vdGF0aW9ucyBmcm9tIHRoZSBzb3VyY2UgdGhhdCBzaG91bGQgcmVhbGx5IGJlbG9uZyB0byB0aGUgbGFtYmRhCiAgICAgICAgcHJpdmF0ZSB2b2lkIGFwcG9ydGlvblR5cGVBbm5vdGF0aW9ucyhKQ0xhbWJkYSB0cmVlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3VwcGxpZXI8TGlzdDxBdHRyaWJ1dGUuVHlwZUNvbXBvdW5kPj4gc291cmNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29uc3VtZXI8TGlzdDxBdHRyaWJ1dGUuVHlwZUNvbXBvdW5kPj4gb3duZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb25zdW1lcjxMaXN0PEF0dHJpYnV0ZS5UeXBlQ29tcG91bmQ+PiBsYW1iZGEpIHsKCiAgICAgICAgICAgIExpc3RCdWZmZXI8QXR0cmlidXRlLlR5cGVDb21wb3VuZD4gb3duZXJUeXBlQW5ub3MgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgIExpc3RCdWZmZXI8QXR0cmlidXRlLlR5cGVDb21wb3VuZD4gbGFtYmRhVHlwZUFubm9zID0gbmV3IExpc3RCdWZmZXI8PigpOwoKICAgICAgICAgICAgZm9yIChBdHRyaWJ1dGUuVHlwZUNvbXBvdW5kIHRjIDogc291cmNlLmdldCgpKSB7CiAgICAgICAgICAgICAgICBpZiAodGMucG9zaXRpb24ub25MYW1iZGEgPT0gdHJlZSkgewogICAgICAgICAgICAgICAgICAgIGxhbWJkYVR5cGVBbm5vcy5hcHBlbmQodGMpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBvd25lclR5cGVBbm5vcy5hcHBlbmQodGMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChsYW1iZGFUeXBlQW5ub3Mubm9uRW1wdHkoKSkgewogICAgICAgICAgICAgICAgb3duZXIuYWNjZXB0KG93bmVyVHlwZUFubm9zLnRvTGlzdCgpKTsKICAgICAgICAgICAgICAgIGxhbWJkYS5hY2NlcHQobGFtYmRhVHlwZUFubm9zLnRvTGlzdCgpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICBwcml2YXRlIEpDSWRlbnQgbWFrZVRoaXMoVHlwZSB0eXBlLCBTeW1ib2wgb3duZXIpIHsKICAgICAgICBWYXJTeW1ib2wgX3RoaXMgPSBuZXcgVmFyU3ltYm9sKFBBUkFNRVRFUiB8IEZJTkFMIHwgU1lOVEhFVElDLAogICAgICAgICAgICAgICAgbmFtZXMuX3RoaXMsCiAgICAgICAgICAgICAgICB0eXBlLAogICAgICAgICAgICAgICAgb3duZXIpOwogICAgICAgIHJldHVybiBtYWtlLklkZW50KF90aGlzKTsKICAgIH0KCiAgICAvKioKICAgICAqIFRyYW5zbGF0ZSBhIG1ldGhvZCByZWZlcmVuY2UgaW50byBhbiBpbnZva2VkeW5hbWljIGNhbGwgdG8gdGhlCiAgICAgKiBtZXRhLWZhY3RvcnkuCiAgICAgKiBAcGFyYW0gdHJlZQogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHZpc2l0UmVmZXJlbmNlKEpDTWVtYmVyUmVmZXJlbmNlIHRyZWUpIHsKICAgICAgICBSZWZlcmVuY2VUcmFuc2xhdGlvbkNvbnRleHQgbG9jYWxDb250ZXh0ID0gKFJlZmVyZW5jZVRyYW5zbGF0aW9uQ29udGV4dCljb250ZXh0OwoKICAgICAgICAvL2ZpcnN0IGRldGVybWluZSB0aGUgbWV0aG9kIHN5bWJvbCB0byBiZSB1c2VkIHRvIGdlbmVyYXRlIHRoZSBzYW0gaW5zdGFuY2UKICAgICAgICAvL3RoaXMgaXMgZWl0aGVyIHRoZSBtZXRob2QgcmVmZXJlbmNlIHN5bWJvbCwgb3IgdGhlIGJyaWRnZWQgcmVmZXJlbmNlIHN5bWJvbAogICAgICAgIFN5bWJvbCByZWZTeW0gPSBsb2NhbENvbnRleHQuaXNTaWduYXR1cmVQb2x5bW9ycGhpYygpCiAgICAgICAgICAgICAgICA/IGxvY2FsQ29udGV4dC5zaWdQb2x5U3ltCiAgICAgICAgICAgICAgICA6IHRyZWUuc3ltOwoKICAgICAgICAvL3RoZSBxdWFsaWZ5aW5nIGV4cHJlc3Npb24gaXMgdHJlYXRlZCBhcyBhIHNwZWNpYWwgY2FwdHVyZWQgYXJnCiAgICAgICAgSkNFeHByZXNzaW9uIGluaXQ7CiAgICAgICAgc3dpdGNoKHRyZWUua2luZCkgewoKICAgICAgICAgICAgY2FzZSBJTVBMSUNJVF9JTk5FUjogICAgLyoqIElubmVyIDo6IG5ldyAqLwogICAgICAgICAgICBjYXNlIFNVUEVSOiAgICAgICAgICAgICAvKiogc3VwZXIgOjogaW5zdE1ldGhvZCAqLwogICAgICAgICAgICAgICAgaW5pdCA9IG1ha2VUaGlzKAogICAgICAgICAgICAgICAgICAgIGxvY2FsQ29udGV4dC5vd25lci5lbmNsQ2xhc3MoKS5hc1R5cGUoKSwKICAgICAgICAgICAgICAgICAgICBsb2NhbENvbnRleHQub3duZXIuZW5jbENsYXNzKCkpOwogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIEJPVU5EOiAgICAgICAgICAgICAvKiogRXhwciA6OiBpbnN0TWV0aG9kICovCiAgICAgICAgICAgICAgICBpbml0ID0gdHJlZS5nZXRRdWFsaWZpZXJFeHByZXNzaW9uKCk7CiAgICAgICAgICAgICAgICBpbml0ID0gYXR0ci5tYWtlTnVsbENoZWNrKGluaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIFVOQk9VTkQ6ICAgICAgICAgICAvKiogVHlwZSA6OiBpbnN0TWV0aG9kICovCiAgICAgICAgICAgIGNhc2UgU1RBVElDOiAgICAgICAgICAgIC8qKiBUeXBlIDo6IHN0YXRpY01ldGhvZCAqLwogICAgICAgICAgICBjYXNlIFRPUExFVkVMOiAgICAgICAgICAvKiogVG9wIGxldmVsIDo6IG5ldyAqLwogICAgICAgICAgICBjYXNlIEFSUkFZX0NUT1I6ICAgICAgICAvKiogQXJyYXlUeXBlIDo6IG5ldyAqLwogICAgICAgICAgICAgICAgaW5pdCA9IG51bGw7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcigiU2hvdWxkIG5vdCBoYXZlIGFuIGludmFsaWQga2luZCIpOwogICAgICAgIH0KCiAgICAgICAgTGlzdDxKQ0V4cHJlc3Npb24+IGluZHlfYXJncyA9IGluaXQ9PW51bGw/IExpc3QubmlsKCkgOiB0cmFuc2xhdGUoTGlzdC5vZihpbml0KSwgbG9jYWxDb250ZXh0LnByZXYpOwoKCiAgICAgICAgLy9idWlsZCBhIHNhbSBpbnN0YW5jZSB1c2luZyBhbiBpbmR5IGNhbGwgdG8gdGhlIG1ldGEtZmFjdG9yeQogICAgICAgIHJlc3VsdCA9IG1ha2VNZXRhZmFjdG9yeUluZHlDYWxsKGxvY2FsQ29udGV4dCwgbG9jYWxDb250ZXh0LnJlZmVyZW5jZUtpbmQoKSwgcmVmU3ltLCBpbmR5X2FyZ3MpOwogICAgfQoKICAgIC8qKgogICAgICogVHJhbnNsYXRlIGlkZW50aWZpZXJzIHdpdGhpbiBhIGxhbWJkYSB0byB0aGUgbWFwcGVkIGlkZW50aWZpZXIKICAgICAqIEBwYXJhbSB0cmVlCiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIHZvaWQgdmlzaXRJZGVudChKQ0lkZW50IHRyZWUpIHsKICAgICAgICBpZiAoY29udGV4dCA9PSBudWxsIHx8ICFhbmFseXplci5sYW1iZGFJZGVudFN5bWJvbEZpbHRlcih0cmVlLnN5bSkpIHsKICAgICAgICAgICAgc3VwZXIudmlzaXRJZGVudCh0cmVlKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBpbnQgcHJldlBvcyA9IG1ha2UucG9zOwogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgbWFrZS5hdCh0cmVlKTsKCiAgICAgICAgICAgICAgICBMYW1iZGFUcmFuc2xhdGlvbkNvbnRleHQgbGFtYmRhQ29udGV4dCA9IChMYW1iZGFUcmFuc2xhdGlvbkNvbnRleHQpIGNvbnRleHQ7CiAgICAgICAgICAgICAgICBKQ1RyZWUgbHRyZWUgPSBsYW1iZGFDb250ZXh0LnRyYW5zbGF0ZSh0cmVlKTsKICAgICAgICAgICAgICAgIGlmIChsdHJlZSAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gbHRyZWU7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIC8vYWNjZXNzIHRvIHVudHJhbnNsYXRlZCBzeW1ib2xzIChpLmUuIGNvbXBpbGUtdGltZSBjb25zdGFudHMsCiAgICAgICAgICAgICAgICAgICAgLy9tZW1iZXJzIGRlZmluZWQgaW5zaWRlIHRoZSBsYW1iZGEgYm9keSwgZXRjLikgKQogICAgICAgICAgICAgICAgICAgIHN1cGVyLnZpc2l0SWRlbnQodHJlZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgICAgICBtYWtlLmF0KHByZXZQb3MpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogVHJhbnNsYXRlIHF1YWxpZmllZCBgdGhpcycgcmVmZXJlbmNlcyB3aXRoaW4gYSBsYW1iZGEgdG8gdGhlIG1hcHBlZCBpZGVudGlmaWVyCiAgICAgKiBAcGFyYW0gdHJlZQogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHZpc2l0U2VsZWN0KEpDRmllbGRBY2Nlc3MgdHJlZSkgewogICAgICAgIGlmIChjb250ZXh0ID09IG51bGwgfHwgIWFuYWx5emVyLmxhbWJkYUZpZWxkQWNjZXNzRmlsdGVyKHRyZWUpKSB7CiAgICAgICAgICAgIHN1cGVyLnZpc2l0U2VsZWN0KHRyZWUpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGludCBwcmV2UG9zID0gbWFrZS5wb3M7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBtYWtlLmF0KHRyZWUpOwoKICAgICAgICAgICAgICAgIExhbWJkYVRyYW5zbGF0aW9uQ29udGV4dCBsYW1iZGFDb250ZXh0ID0gKExhbWJkYVRyYW5zbGF0aW9uQ29udGV4dCkgY29udGV4dDsKICAgICAgICAgICAgICAgIEpDVHJlZSBsdHJlZSA9IGxhbWJkYUNvbnRleHQudHJhbnNsYXRlKHRyZWUpOwogICAgICAgICAgICAgICAgaWYgKGx0cmVlICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBsdHJlZTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgc3VwZXIudmlzaXRTZWxlY3QodHJlZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgICAgICBtYWtlLmF0KHByZXZQb3MpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIHZvaWQgdmlzaXRWYXJEZWYoSkNWYXJpYWJsZURlY2wgdHJlZSkgewogICAgICAgIExhbWJkYVRyYW5zbGF0aW9uQ29udGV4dCBsYW1iZGFDb250ZXh0ID0gKExhbWJkYVRyYW5zbGF0aW9uQ29udGV4dCljb250ZXh0OwogICAgICAgIGlmIChjb250ZXh0ICE9IG51bGwgJiYgbGFtYmRhQ29udGV4dC5nZXRTeW1ib2xNYXAoTE9DQUxfVkFSKS5jb250YWluc0tleSh0cmVlLnN5bSkpIHsKICAgICAgICAgICAgdHJlZS5pbml0ID0gdHJhbnNsYXRlKHRyZWUuaW5pdCk7CiAgICAgICAgICAgIHRyZWUuc3ltID0gKFZhclN5bWJvbCkgbGFtYmRhQ29udGV4dC5nZXRTeW1ib2xNYXAoTE9DQUxfVkFSKS5nZXQodHJlZS5zeW0pOwogICAgICAgICAgICByZXN1bHQgPSB0cmVlOwogICAgICAgIH0gZWxzZSBpZiAoY29udGV4dCAhPSBudWxsICYmIGxhbWJkYUNvbnRleHQuZ2V0U3ltYm9sTWFwKFRZUEVfVkFSKS5jb250YWluc0tleSh0cmVlLnN5bSkpIHsKICAgICAgICAgICAgSkNFeHByZXNzaW9uIGluaXQgPSB0cmFuc2xhdGUodHJlZS5pbml0KTsKICAgICAgICAgICAgVmFyU3ltYm9sIHhzeW0gPSAoVmFyU3ltYm9sKWxhbWJkYUNvbnRleHQuZ2V0U3ltYm9sTWFwKFRZUEVfVkFSKS5nZXQodHJlZS5zeW0pOwogICAgICAgICAgICBpbnQgcHJldlBvcyA9IG1ha2UucG9zOwogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgcmVzdWx0ID0gbWFrZS5hdCh0cmVlKS5WYXJEZWYoeHN5bSwgaW5pdCk7CiAgICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgICAgICBtYWtlLmF0KHByZXZQb3MpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIFJlcGxhY2UgdGhlIGVudGVyZWQgc3ltYm9sIGZvciB0aGlzIHZhcmlhYmxlCiAgICAgICAgICAgIFdyaXRlYWJsZVNjb3BlIHNjID0gdHJlZS5zeW0ub3duZXIubWVtYmVycygpOwogICAgICAgICAgICBpZiAoc2MgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgc2MucmVtb3ZlKHRyZWUuc3ltKTsKICAgICAgICAgICAgICAgIHNjLmVudGVyKHhzeW0pOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc3VwZXIudmlzaXRWYXJEZWYodHJlZSk7CiAgICAgICAgfQogICAgfQoKICAgIC8vIDwvZWRpdG9yLWZvbGQ+CgogICAgLy8gPGVkaXRvci1mb2xkIGRlZmF1bHRzdGF0ZT0iY29sbGFwc2VkIiBkZXNjPSJUcmFuc2xhdGlvbiBoZWxwZXIgbWV0aG9kcyI+CgogICAgcHJpdmF0ZSBKQ0Jsb2NrIG1ha2VMYW1iZGFCb2R5KEpDTGFtYmRhIHRyZWUsIEpDTWV0aG9kRGVjbCBsYW1iZGFNZXRob2REZWNsKSB7CiAgICAgICAgcmV0dXJuIHRyZWUuZ2V0Qm9keUtpbmQoKSA9PSBKQ0xhbWJkYS5Cb2R5S2luZC5FWFBSRVNTSU9OID8KICAgICAgICAgICAgICAgIG1ha2VMYW1iZGFFeHByZXNzaW9uQm9keSgoSkNFeHByZXNzaW9uKXRyZWUuYm9keSwgbGFtYmRhTWV0aG9kRGVjbCkgOgogICAgICAgICAgICAgICAgbWFrZUxhbWJkYVN0YXRlbWVudEJvZHkoKEpDQmxvY2spdHJlZS5ib2R5LCBsYW1iZGFNZXRob2REZWNsLCB0cmVlLmNhbkNvbXBsZXRlTm9ybWFsbHkpOwogICAgfQoKICAgIHByaXZhdGUgSkNCbG9jayBtYWtlTGFtYmRhRXhwcmVzc2lvbkJvZHkoSkNFeHByZXNzaW9uIGV4cHIsIEpDTWV0aG9kRGVjbCBsYW1iZGFNZXRob2REZWNsKSB7CiAgICAgICAgVHlwZSByZXN0eXBlID0gbGFtYmRhTWV0aG9kRGVjbC50eXBlLmdldFJldHVyblR5cGUoKTsKICAgICAgICBib29sZWFuIGlzTGFtYmRhX3ZvaWQgPSBleHByLnR5cGUuaGFzVGFnKFZPSUQpOwogICAgICAgIGJvb2xlYW4gaXNUYXJnZXRfdm9pZCA9IHJlc3R5cGUuaGFzVGFnKFZPSUQpOwogICAgICAgIGJvb2xlYW4gaXNUYXJnZXRfVm9pZCA9IHR5cGVzLmlzU2FtZVR5cGUocmVzdHlwZSwgdHlwZXMuYm94ZWRDbGFzcyhzeW1zLnZvaWRUeXBlKS50eXBlKTsKICAgICAgICBpbnQgcHJldlBvcyA9IG1ha2UucG9zOwogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGlmIChpc1RhcmdldF92b2lkKSB7CiAgICAgICAgICAgICAgICAvL3RhcmdldCBpcyB2b2lkOgogICAgICAgICAgICAgICAgLy8gQk9EWTsKICAgICAgICAgICAgICAgIEpDU3RhdGVtZW50IHN0YXQgPSBtYWtlLmF0KGV4cHIpLkV4ZWMoZXhwcik7CiAgICAgICAgICAgICAgICByZXR1cm4gbWFrZS5CbG9jaygwLCBMaXN0Lm9mKHN0YXQpKTsKICAgICAgICAgICAgfSBlbHNlIGlmIChpc0xhbWJkYV92b2lkICYmIGlzVGFyZ2V0X1ZvaWQpIHsKICAgICAgICAgICAgICAgIC8vdm9pZCB0byBWb2lkIGNvbnZlcnNpb246CiAgICAgICAgICAgICAgICAvLyBCT0RZOyByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgIExpc3RCdWZmZXI8SkNTdGF0ZW1lbnQ+IHN0YXRzID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgICAgICAgICAgc3RhdHMuYXBwZW5kKG1ha2UuYXQoZXhwcikuRXhlYyhleHByKSk7CiAgICAgICAgICAgICAgICBzdGF0cy5hcHBlbmQobWFrZS5SZXR1cm4obWFrZS5MaXRlcmFsKEJPVCwgbnVsbCkuc2V0VHlwZShzeW1zLmJvdFR5cGUpKSk7CiAgICAgICAgICAgICAgICByZXR1cm4gbWFrZS5CbG9jaygwLCBzdGF0cy50b0xpc3QoKSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvL25vbi12b2lkIHRvIG5vbi12b2lkIGNvbnZlcnNpb246CiAgICAgICAgICAgICAgICAvLyByZXR1cm4gKFRZUEUpQk9EWTsKICAgICAgICAgICAgICAgIEpDRXhwcmVzc2lvbiByZXRFeHByID0gdHJhbnNUeXBlcy5jb2VyY2UoYXR0ckVudiwgZXhwciwgcmVzdHlwZSk7CiAgICAgICAgICAgICAgICByZXR1cm4gbWFrZS5hdChyZXRFeHByKS5CbG9jaygwLCBMaXN0Lm9mKG1ha2UuUmV0dXJuKHJldEV4cHIpKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICBtYWtlLmF0KHByZXZQb3MpOwogICAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIEpDQmxvY2sgbWFrZUxhbWJkYVN0YXRlbWVudEJvZHkoSkNCbG9jayBibG9jaywgZmluYWwgSkNNZXRob2REZWNsIGxhbWJkYU1ldGhvZERlY2wsIGJvb2xlYW4gY29tcGxldGVOb3JtYWxseSkgewogICAgICAgIGZpbmFsIFR5cGUgcmVzdHlwZSA9IGxhbWJkYU1ldGhvZERlY2wudHlwZS5nZXRSZXR1cm5UeXBlKCk7CiAgICAgICAgZmluYWwgYm9vbGVhbiBpc1RhcmdldF92b2lkID0gcmVzdHlwZS5oYXNUYWcoVk9JRCk7CiAgICAgICAgYm9vbGVhbiBpc1RhcmdldF9Wb2lkID0gdHlwZXMuaXNTYW1lVHlwZShyZXN0eXBlLCB0eXBlcy5ib3hlZENsYXNzKHN5bXMudm9pZFR5cGUpLnR5cGUpOwoKICAgICAgICBjbGFzcyBMYW1iZGFCb2R5VHJhbnNsYXRvciBleHRlbmRzIFRyZWVUcmFuc2xhdG9yIHsKCiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdENsYXNzRGVmKEpDQ2xhc3NEZWNsIHRyZWUpIHsKICAgICAgICAgICAgICAgIC8vZG8gTk9UIHJlY3Vyc2Ugb24gYW55IGlubmVyIGNsYXNzZXMKICAgICAgICAgICAgICAgIHJlc3VsdCA9IHRyZWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdExhbWJkYShKQ0xhbWJkYSB0cmVlKSB7CiAgICAgICAgICAgICAgICAvL2RvIE5PVCByZWN1cnNlIG9uIGFueSBuZXN0ZWQgbGFtYmRhcwogICAgICAgICAgICAgICAgcmVzdWx0ID0gdHJlZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0UmV0dXJuKEpDUmV0dXJuIHRyZWUpIHsKICAgICAgICAgICAgICAgIGJvb2xlYW4gaXNMYW1iZGFfdm9pZCA9IHRyZWUuZXhwciA9PSBudWxsOwogICAgICAgICAgICAgICAgaWYgKGlzVGFyZ2V0X3ZvaWQgJiYgIWlzTGFtYmRhX3ZvaWQpIHsKICAgICAgICAgICAgICAgICAgICAvL1ZvaWQgdG8gdm9pZCBjb252ZXJzaW9uOgogICAgICAgICAgICAgICAgICAgIC8vIHsgVFlQRSAkbG9jID0gUkVULUVYUFI7IHJldHVybjsgfQogICAgICAgICAgICAgICAgICAgIFZhclN5bWJvbCBsb2MgPSBtYWtlU3ludGhldGljVmFyKDAsIG5hbWVzLmZyb21TdHJpbmcoIiRsb2MiKSwgdHJlZS5leHByLnR5cGUsIGxhbWJkYU1ldGhvZERlY2wuc3ltKTsKICAgICAgICAgICAgICAgICAgICBKQ1ZhcmlhYmxlRGVjbCB2YXJEZWYgPSBtYWtlLlZhckRlZihsb2MsIHRyZWUuZXhwcik7CiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gbWFrZS5CbG9jaygwLCBMaXN0Lm9mKHZhckRlZiwgbWFrZS5SZXR1cm4obnVsbCkpKTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoIWlzVGFyZ2V0X3ZvaWQgfHwgIWlzTGFtYmRhX3ZvaWQpIHsKICAgICAgICAgICAgICAgICAgICAvL25vbi12b2lkIHRvIG5vbi12b2lkIGNvbnZlcnNpb246CiAgICAgICAgICAgICAgICAgICAgLy8gcmV0dXJuIChUWVBFKVJFVC1FWFBSOwogICAgICAgICAgICAgICAgICAgIHRyZWUuZXhwciA9IHRyYW5zVHlwZXMuY29lcmNlKGF0dHJFbnYsIHRyZWUuZXhwciwgcmVzdHlwZSk7CiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gdHJlZTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gdHJlZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEpDQmxvY2sgdHJhbnNfYmxvY2sgPSBuZXcgTGFtYmRhQm9keVRyYW5zbGF0b3IoKS50cmFuc2xhdGUoYmxvY2spOwogICAgICAgIGlmIChjb21wbGV0ZU5vcm1hbGx5ICYmIGlzVGFyZ2V0X1ZvaWQpIHsKICAgICAgICAgICAgLy90aGVyZSdzIG5vIHJldHVybiBzdGF0ZW1lbnQgYW5kIHRoZSBsYW1iZGEgKHBvc3NpYmx5IGluZmVycmVkKQogICAgICAgICAgICAvL3JldHVybiB0eXBlIGlzIGphdmEubGFuZy5Wb2lkOyBlbWl0IGEgc3ludGhldGljIHJldHVybiBzdGF0ZW1lbnQKICAgICAgICAgICAgdHJhbnNfYmxvY2suc3RhdHMgPSB0cmFuc19ibG9jay5zdGF0cy5hcHBlbmQobWFrZS5SZXR1cm4obWFrZS5MaXRlcmFsKEJPVCwgbnVsbCkuc2V0VHlwZShzeW1zLmJvdFR5cGUpKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0cmFuc19ibG9jazsKICAgIH0KCiAgICBwcml2YXRlIEpDTWV0aG9kRGVjbCBtYWtlRGVzZXJpYWxpemVNZXRob2QoU3ltYm9sIGtTeW0pIHsKICAgICAgICBMaXN0QnVmZmVyPEpDQ2FzZT4gY2FzZXMgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgTGlzdEJ1ZmZlcjxKQ0JyZWFrPiBicmVha3MgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgZm9yIChNYXAuRW50cnk8U3RyaW5nLCBMaXN0QnVmZmVyPEpDU3RhdGVtZW50Pj4gZW50cnkgOiBrSW5mby5kZXNlcmlhbGl6ZUNhc2VzLmVudHJ5U2V0KCkpIHsKICAgICAgICAgICAgSkNCcmVhayBiciA9IG1ha2UuQnJlYWsobnVsbCk7CiAgICAgICAgICAgIGJyZWFrcy5hZGQoYnIpOwogICAgICAgICAgICBMaXN0PEpDU3RhdGVtZW50PiBzdG10cyA9IGVudHJ5LmdldFZhbHVlKCkuYXBwZW5kKGJyKS50b0xpc3QoKTsKICAgICAgICAgICAgY2FzZXMuYWRkKG1ha2UuQ2FzZShtYWtlLkxpdGVyYWwoZW50cnkuZ2V0S2V5KCkpLCBzdG10cykpOwogICAgICAgIH0KICAgICAgICBKQ1N3aXRjaCBzdyA9IG1ha2UuU3dpdGNoKGRlc2VyR2V0dGVyKCJnZXRJbXBsTWV0aG9kTmFtZSIsIHN5bXMuc3RyaW5nVHlwZSksIGNhc2VzLnRvTGlzdCgpKTsKICAgICAgICBmb3IgKEpDQnJlYWsgYnIgOiBicmVha3MpIHsKICAgICAgICAgICAgYnIudGFyZ2V0ID0gc3c7CiAgICAgICAgfQogICAgICAgIEpDQmxvY2sgYm9keSA9IG1ha2UuQmxvY2soMEwsIExpc3Qub2YoCiAgICAgICAgICAgICAgICBzdywKICAgICAgICAgICAgICAgIG1ha2UuVGhyb3cobWFrZU5ld0NsYXNzKAogICAgICAgICAgICAgICAgICAgIHN5bXMuaWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uVHlwZSwKICAgICAgICAgICAgICAgICAgICBMaXN0Lm9mKG1ha2UuTGl0ZXJhbCgiSW52YWxpZCBsYW1iZGEgZGVzZXJpYWxpemF0aW9uIikpKSkpKTsKICAgICAgICBKQ01ldGhvZERlY2wgZGVzZXIgPSBtYWtlLk1ldGhvZERlZihtYWtlLk1vZGlmaWVycyhrSW5mby5kZXNlck1ldGhvZFN5bS5mbGFncygpKSwKICAgICAgICAgICAgICAgICAgICAgICAgbmFtZXMuZGVzZXJpYWxpemVMYW1iZGEsCiAgICAgICAgICAgICAgICAgICAgICAgIG1ha2UuUXVhbElkZW50KGtJbmZvLmRlc2VyTWV0aG9kU3ltLmdldFJldHVyblR5cGUoKS50c3ltKSwKICAgICAgICAgICAgICAgICAgICAgICAgTGlzdC5uaWwoKSwKICAgICAgICAgICAgICAgICAgICAgICAgTGlzdC5vZihtYWtlLlZhckRlZihrSW5mby5kZXNlclBhcmFtU3ltLCBudWxsKSksCiAgICAgICAgICAgICAgICAgICAgICAgIExpc3QubmlsKCksCiAgICAgICAgICAgICAgICAgICAgICAgIGJvZHksCiAgICAgICAgICAgICAgICAgICAgICAgIG51bGwpOwogICAgICAgIGRlc2VyLnN5bSA9IGtJbmZvLmRlc2VyTWV0aG9kU3ltOwogICAgICAgIGRlc2VyLnR5cGUgPSBrSW5mby5kZXNlck1ldGhvZFN5bS50eXBlOwogICAgICAgIC8vU3lzdGVtLmVyci5wcmludGYoIkRFU0VSOiAnJXMnXG4iLCBkZXNlcik7CiAgICAgICAgcmV0dXJuIGRlc2VyOwogICAgfQoKICAgIC8qKiBNYWtlIGFuIGF0dHJpYnV0ZWQgY2xhc3MgaW5zdGFuY2UgY3JlYXRpb24gZXhwcmVzc2lvbi4KICAgICAqICBAcGFyYW0gY3R5cGUgICAgVGhlIGNsYXNzIHR5cGUuCiAgICAgKiAgQHBhcmFtIGFyZ3MgICAgIFRoZSBjb25zdHJ1Y3RvciBhcmd1bWVudHMuCiAgICAgKiAgQHBhcmFtIGNvbnMgICAgIFRoZSBjb25zdHJ1Y3RvciBzeW1ib2wKICAgICAqLwogICAgSkNOZXdDbGFzcyBtYWtlTmV3Q2xhc3MoVHlwZSBjdHlwZSwgTGlzdDxKQ0V4cHJlc3Npb24+IGFyZ3MsIFN5bWJvbCBjb25zKSB7CiAgICAgICAgSkNOZXdDbGFzcyB0cmVlID0gbWFrZS5OZXdDbGFzcyhudWxsLAogICAgICAgICAgICBudWxsLCBtYWtlLlF1YWxJZGVudChjdHlwZS50c3ltKSwgYXJncywgbnVsbCk7CiAgICAgICAgdHJlZS5jb25zdHJ1Y3RvciA9IGNvbnM7CiAgICAgICAgdHJlZS50eXBlID0gY3R5cGU7CiAgICAgICAgcmV0dXJuIHRyZWU7CiAgICB9CgogICAgLyoqIE1ha2UgYW4gYXR0cmlidXRlZCBjbGFzcyBpbnN0YW5jZSBjcmVhdGlvbiBleHByZXNzaW9uLgogICAgICogIEBwYXJhbSBjdHlwZSAgICBUaGUgY2xhc3MgdHlwZS4KICAgICAqICBAcGFyYW0gYXJncyAgICAgVGhlIGNvbnN0cnVjdG9yIGFyZ3VtZW50cy4KICAgICAqLwogICAgSkNOZXdDbGFzcyBtYWtlTmV3Q2xhc3MoVHlwZSBjdHlwZSwgTGlzdDxKQ0V4cHJlc3Npb24+IGFyZ3MpIHsKICAgICAgICByZXR1cm4gbWFrZU5ld0NsYXNzKGN0eXBlLCBhcmdzLAogICAgICAgICAgICAgICAgcnMucmVzb2x2ZUNvbnN0cnVjdG9yKG51bGwsIGF0dHJFbnYsIGN0eXBlLCBUcmVlSW5mby50eXBlcyhhcmdzKSwgTGlzdC5uaWwoKSkpOwogICAgIH0KCiAgICBwcml2YXRlIHZvaWQgYWRkRGVzZXJpYWxpemF0aW9uQ2FzZShpbnQgaW1wbE1ldGhvZEtpbmQsIFN5bWJvbCByZWZTeW0sIFR5cGUgdGFyZ2V0VHlwZSwgTWV0aG9kU3ltYm9sIHNhbVN5bSwKICAgICAgICAgICAgRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcywgTGlzdDxPYmplY3Q+IHN0YXRpY0FyZ3MsIE1ldGhvZFR5cGUgaW5keVR5cGUpIHsKICAgICAgICBTdHJpbmcgZnVuY3Rpb25hbEludGVyZmFjZUNsYXNzID0gY2xhc3NTaWcodGFyZ2V0VHlwZSk7CiAgICAgICAgU3RyaW5nIGZ1bmN0aW9uYWxJbnRlcmZhY2VNZXRob2ROYW1lID0gc2FtU3ltLmdldFNpbXBsZU5hbWUoKS50b1N0cmluZygpOwogICAgICAgIFN0cmluZyBmdW5jdGlvbmFsSW50ZXJmYWNlTWV0aG9kU2lnbmF0dXJlID0gdHlwZVNpZyh0eXBlcy5lcmFzdXJlKHNhbVN5bS50eXBlKSk7CiAgICAgICAgU3RyaW5nIGltcGxDbGFzcyA9IGNsYXNzU2lnKHR5cGVzLmVyYXN1cmUocmVmU3ltLm93bmVyLnR5cGUpKTsKICAgICAgICBTdHJpbmcgaW1wbE1ldGhvZE5hbWUgPSByZWZTeW0uZ2V0UXVhbGlmaWVkTmFtZSgpLnRvU3RyaW5nKCk7CiAgICAgICAgU3RyaW5nIGltcGxNZXRob2RTaWduYXR1cmUgPSB0eXBlU2lnKHR5cGVzLmVyYXN1cmUocmVmU3ltLnR5cGUpKTsKCiAgICAgICAgSkNFeHByZXNzaW9uIGtpbmRUZXN0ID0gZXFUZXN0KHN5bXMuaW50VHlwZSwgZGVzZXJHZXR0ZXIoImdldEltcGxNZXRob2RLaW5kIiwgc3ltcy5pbnRUeXBlKSwgbWFrZS5MaXRlcmFsKGltcGxNZXRob2RLaW5kKSk7CiAgICAgICAgTGlzdEJ1ZmZlcjxKQ0V4cHJlc3Npb24+IHNlckFyZ3MgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgaW50IGkgPSAwOwogICAgICAgIGZvciAoVHlwZSB0IDogaW5keVR5cGUuZ2V0UGFyYW1ldGVyVHlwZXMoKSkgewogICAgICAgICAgICBMaXN0PEpDRXhwcmVzc2lvbj4gaW5kZXhBc0FyZyA9IG5ldyBMaXN0QnVmZmVyPEpDRXhwcmVzc2lvbj4oKS5hcHBlbmQobWFrZS5MaXRlcmFsKGkpKS50b0xpc3QoKTsKICAgICAgICAgICAgTGlzdDxUeXBlPiBhcmdUeXBlcyA9IG5ldyBMaXN0QnVmZmVyPFR5cGU+KCkuYXBwZW5kKHN5bXMuaW50VHlwZSkudG9MaXN0KCk7CiAgICAgICAgICAgIHNlckFyZ3MuYWRkKG1ha2UuVHlwZUNhc3QodHlwZXMuZXJhc3VyZSh0KSwgZGVzZXJHZXR0ZXIoImdldENhcHR1cmVkQXJnIiwgc3ltcy5vYmplY3RUeXBlLCBhcmdUeXBlcywgaW5kZXhBc0FyZykpKTsKICAgICAgICAgICAgKytpOwogICAgICAgIH0KICAgICAgICBKQ1N0YXRlbWVudCBzdG10ID0gbWFrZS5JZigKICAgICAgICAgICAgICAgIGRlc2VyVGVzdChkZXNlclRlc3QoZGVzZXJUZXN0KGRlc2VyVGVzdChkZXNlclRlc3QoCiAgICAgICAgICAgICAgICAgICAga2luZFRlc3QsCiAgICAgICAgICAgICAgICAgICAgImdldEZ1bmN0aW9uYWxJbnRlcmZhY2VDbGFzcyIsIGZ1bmN0aW9uYWxJbnRlcmZhY2VDbGFzcyksCiAgICAgICAgICAgICAgICAgICAgImdldEZ1bmN0aW9uYWxJbnRlcmZhY2VNZXRob2ROYW1lIiwgZnVuY3Rpb25hbEludGVyZmFjZU1ldGhvZE5hbWUpLAogICAgICAgICAgICAgICAgICAgICJnZXRGdW5jdGlvbmFsSW50ZXJmYWNlTWV0aG9kU2lnbmF0dXJlIiwgZnVuY3Rpb25hbEludGVyZmFjZU1ldGhvZFNpZ25hdHVyZSksCiAgICAgICAgICAgICAgICAgICAgImdldEltcGxDbGFzcyIsIGltcGxDbGFzcyksCiAgICAgICAgICAgICAgICAgICAgImdldEltcGxNZXRob2RTaWduYXR1cmUiLCBpbXBsTWV0aG9kU2lnbmF0dXJlKSwKICAgICAgICAgICAgICAgIG1ha2UuUmV0dXJuKG1ha2VJbmR5Q2FsbCgKICAgICAgICAgICAgICAgICAgICBwb3MsCiAgICAgICAgICAgICAgICAgICAgc3ltcy5sYW1iZGFNZXRhZmFjdG9yeSwKICAgICAgICAgICAgICAgICAgICBuYW1lcy5hbHRNZXRhZmFjdG9yeSwKICAgICAgICAgICAgICAgICAgICBzdGF0aWNBcmdzLCBpbmR5VHlwZSwgc2VyQXJncy50b0xpc3QoKSwgc2FtU3ltLm5hbWUpKSwKICAgICAgICAgICAgICAgIG51bGwpOwogICAgICAgIExpc3RCdWZmZXI8SkNTdGF0ZW1lbnQ+IHN0bXRzID0ga0luZm8uZGVzZXJpYWxpemVDYXNlcy5nZXQoaW1wbE1ldGhvZE5hbWUpOwogICAgICAgIGlmIChzdG10cyA9PSBudWxsKSB7CiAgICAgICAgICAgIHN0bXRzID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgICAgICBrSW5mby5kZXNlcmlhbGl6ZUNhc2VzLnB1dChpbXBsTWV0aG9kTmFtZSwgc3RtdHMpOwogICAgICAgIH0KICAgICAgICAvKioqKgogICAgICAgIFN5c3RlbS5lcnIucHJpbnRmKCIrKysrKysrKysrKysrKysrK1xuIik7CiAgICAgICAgU3lzdGVtLmVyci5wcmludGYoIipmdW5jdGlvbmFsSW50ZXJmYWNlQ2xhc3M6ICclcydcbiIsIGZ1bmN0aW9uYWxJbnRlcmZhY2VDbGFzcyk7CiAgICAgICAgU3lzdGVtLmVyci5wcmludGYoIipmdW5jdGlvbmFsSW50ZXJmYWNlTWV0aG9kTmFtZTogJyVzJ1xuIiwgZnVuY3Rpb25hbEludGVyZmFjZU1ldGhvZE5hbWUpOwogICAgICAgIFN5c3RlbS5lcnIucHJpbnRmKCIqZnVuY3Rpb25hbEludGVyZmFjZU1ldGhvZFNpZ25hdHVyZTogJyVzJ1xuIiwgZnVuY3Rpb25hbEludGVyZmFjZU1ldGhvZFNpZ25hdHVyZSk7CiAgICAgICAgU3lzdGVtLmVyci5wcmludGYoIippbXBsTWV0aG9kS2luZDogJWRcbiIsIGltcGxNZXRob2RLaW5kKTsKICAgICAgICBTeXN0ZW0uZXJyLnByaW50ZigiKmltcGxDbGFzczogJyVzJ1xuIiwgaW1wbENsYXNzKTsKICAgICAgICBTeXN0ZW0uZXJyLnByaW50ZigiKmltcGxNZXRob2ROYW1lOiAnJXMnXG4iLCBpbXBsTWV0aG9kTmFtZSk7CiAgICAgICAgU3lzdGVtLmVyci5wcmludGYoIippbXBsTWV0aG9kU2lnbmF0dXJlOiAnJXMnXG4iLCBpbXBsTWV0aG9kU2lnbmF0dXJlKTsKICAgICAgICAqKioqLwogICAgICAgIHN0bXRzLmFwcGVuZChzdG10KTsKICAgIH0KCiAgICBwcml2YXRlIEpDRXhwcmVzc2lvbiBlcVRlc3QoVHlwZSBhcmdUeXBlLCBKQ0V4cHJlc3Npb24gYXJnMSwgSkNFeHByZXNzaW9uIGFyZzIpIHsKICAgICAgICBKQ0JpbmFyeSB0ZXN0RXhwciA9IG1ha2UuQmluYXJ5KEpDVHJlZS5UYWcuRVEsIGFyZzEsIGFyZzIpOwogICAgICAgIHRlc3RFeHByLm9wZXJhdG9yID0gb3BlcmF0b3JzLnJlc29sdmVCaW5hcnkodGVzdEV4cHIsIEpDVHJlZS5UYWcuRVEsIGFyZ1R5cGUsIGFyZ1R5cGUpOwogICAgICAgIHRlc3RFeHByLnNldFR5cGUoc3ltcy5ib29sZWFuVHlwZSk7CiAgICAgICAgcmV0dXJuIHRlc3RFeHByOwogICAgfQoKICAgIHByaXZhdGUgSkNFeHByZXNzaW9uIGRlc2VyVGVzdChKQ0V4cHJlc3Npb24gcHJldiwgU3RyaW5nIGZ1bmMsIFN0cmluZyBsaXQpIHsKICAgICAgICBNZXRob2RUeXBlIGVxbXQgPSBuZXcgTWV0aG9kVHlwZShMaXN0Lm9mKHN5bXMub2JqZWN0VHlwZSksIHN5bXMuYm9vbGVhblR5cGUsIExpc3QubmlsKCksIHN5bXMubWV0aG9kQ2xhc3MpOwogICAgICAgIFN5bWJvbCBlcXN5bSA9IHJzLnJlc29sdmVRdWFsaWZpZWRNZXRob2QobnVsbCwgYXR0ckVudiwgc3ltcy5vYmplY3RUeXBlLCBuYW1lcy5lcXVhbHMsIExpc3Qub2Yoc3ltcy5vYmplY3RUeXBlKSwgTGlzdC5uaWwoKSk7CiAgICAgICAgSkNNZXRob2RJbnZvY2F0aW9uIGVxdGVzdCA9IG1ha2UuQXBwbHkoCiAgICAgICAgICAgICAgICBMaXN0Lm5pbCgpLAogICAgICAgICAgICAgICAgbWFrZS5TZWxlY3QoZGVzZXJHZXR0ZXIoZnVuYywgc3ltcy5zdHJpbmdUeXBlKSwgZXFzeW0pLnNldFR5cGUoZXFtdCksCiAgICAgICAgICAgICAgICBMaXN0Lm9mKG1ha2UuTGl0ZXJhbChsaXQpKSk7CiAgICAgICAgZXF0ZXN0LnNldFR5cGUoc3ltcy5ib29sZWFuVHlwZSk7CiAgICAgICAgSkNCaW5hcnkgY29tcG91bmQgPSBtYWtlLkJpbmFyeShKQ1RyZWUuVGFnLkFORCwgcHJldiwgZXF0ZXN0KTsKICAgICAgICBjb21wb3VuZC5vcGVyYXRvciA9IG9wZXJhdG9ycy5yZXNvbHZlQmluYXJ5KGNvbXBvdW5kLCBKQ1RyZWUuVGFnLkFORCwgc3ltcy5ib29sZWFuVHlwZSwgc3ltcy5ib29sZWFuVHlwZSk7CiAgICAgICAgY29tcG91bmQuc2V0VHlwZShzeW1zLmJvb2xlYW5UeXBlKTsKICAgICAgICByZXR1cm4gY29tcG91bmQ7CiAgICB9CgogICAgcHJpdmF0ZSBKQ0V4cHJlc3Npb24gZGVzZXJHZXR0ZXIoU3RyaW5nIGZ1bmMsIFR5cGUgdHlwZSkgewogICAgICAgIHJldHVybiBkZXNlckdldHRlcihmdW5jLCB0eXBlLCBMaXN0Lm5pbCgpLCBMaXN0Lm5pbCgpKTsKICAgIH0KCiAgICBwcml2YXRlIEpDRXhwcmVzc2lvbiBkZXNlckdldHRlcihTdHJpbmcgZnVuYywgVHlwZSB0eXBlLCBMaXN0PFR5cGU+IGFyZ1R5cGVzLCBMaXN0PEpDRXhwcmVzc2lvbj4gYXJncykgewogICAgICAgIE1ldGhvZFR5cGUgZ2V0bXQgPSBuZXcgTWV0aG9kVHlwZShhcmdUeXBlcywgdHlwZSwgTGlzdC5uaWwoKSwgc3ltcy5tZXRob2RDbGFzcyk7CiAgICAgICAgU3ltYm9sIGdldHN5bSA9IHJzLnJlc29sdmVRdWFsaWZpZWRNZXRob2QobnVsbCwgYXR0ckVudiwgc3ltcy5zZXJpYWxpemVkTGFtYmRhVHlwZSwgbmFtZXMuZnJvbVN0cmluZyhmdW5jKSwgYXJnVHlwZXMsIExpc3QubmlsKCkpOwogICAgICAgIHJldHVybiBtYWtlLkFwcGx5KAogICAgICAgICAgICAgICAgICAgIExpc3QubmlsKCksCiAgICAgICAgICAgICAgICAgICAgbWFrZS5TZWxlY3QobWFrZS5JZGVudChrSW5mby5kZXNlclBhcmFtU3ltKS5zZXRUeXBlKHN5bXMuc2VyaWFsaXplZExhbWJkYVR5cGUpLCBnZXRzeW0pLnNldFR5cGUoZ2V0bXQpLAogICAgICAgICAgICAgICAgICAgIGFyZ3MpLnNldFR5cGUodHlwZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDcmVhdGUgbmV3IHN5bnRoZXRpYyBtZXRob2Qgd2l0aCBnaXZlbiBmbGFncywgbmFtZSwgdHlwZSwgb3duZXIKICAgICAqLwogICAgcHJpdmF0ZSBNZXRob2RTeW1ib2wgbWFrZVByaXZhdGVTeW50aGV0aWNNZXRob2QobG9uZyBmbGFncywgTmFtZSBuYW1lLCBUeXBlIHR5cGUsIFN5bWJvbCBvd25lcikgewogICAgICAgIHJldHVybiBuZXcgTWV0aG9kU3ltYm9sKGZsYWdzIHwgU1lOVEhFVElDIHwgUFJJVkFURSwgbmFtZSwgdHlwZSwgb3duZXIpOwogICAgfQoKICAgIC8qKgogICAgICogQ3JlYXRlIG5ldyBzeW50aGV0aWMgdmFyaWFibGUgd2l0aCBnaXZlbiBmbGFncywgbmFtZSwgdHlwZSwgb3duZXIKICAgICAqLwogICAgcHJpdmF0ZSBWYXJTeW1ib2wgbWFrZVN5bnRoZXRpY1Zhcihsb25nIGZsYWdzLCBTdHJpbmcgbmFtZSwgVHlwZSB0eXBlLCBTeW1ib2wgb3duZXIpIHsKICAgICAgICByZXR1cm4gbWFrZVN5bnRoZXRpY1ZhcihmbGFncywgbmFtZXMuZnJvbVN0cmluZyhuYW1lKSwgdHlwZSwgb3duZXIpOwogICAgfQoKICAgIC8qKgogICAgICogQ3JlYXRlIG5ldyBzeW50aGV0aWMgdmFyaWFibGUgd2l0aCBnaXZlbiBmbGFncywgbmFtZSwgdHlwZSwgb3duZXIKICAgICAqLwogICAgcHJpdmF0ZSBWYXJTeW1ib2wgbWFrZVN5bnRoZXRpY1Zhcihsb25nIGZsYWdzLCBOYW1lIG5hbWUsIFR5cGUgdHlwZSwgU3ltYm9sIG93bmVyKSB7CiAgICAgICAgcmV0dXJuIG5ldyBWYXJTeW1ib2woZmxhZ3MgfCBTWU5USEVUSUMsIG5hbWUsIHR5cGUsIG93bmVyKTsKICAgIH0KCiAgICAvKioKICAgICAqIFNldCB2YXJhcmdzRWxlbWVudCBmaWVsZCBvbiBhIGdpdmVuIHRyZWUgKG11c3QgYmUgZWl0aGVyIGEgbmV3IGNsYXNzIHRyZWUKICAgICAqIG9yIGEgbWV0aG9kIGNhbGwgdHJlZSkKICAgICAqLwogICAgcHJpdmF0ZSB2b2lkIHNldFZhcmFyZ3NJZk5lZWRlZChKQ1RyZWUgdHJlZSwgVHlwZSB2YXJhcmdzRWxlbWVudCkgewogICAgICAgIGlmICh2YXJhcmdzRWxlbWVudCAhPSBudWxsKSB7CiAgICAgICAgICAgIHN3aXRjaCAodHJlZS5nZXRUYWcoKSkgewogICAgICAgICAgICAgICAgY2FzZSBBUFBMWTogKChKQ01ldGhvZEludm9jYXRpb24pdHJlZSkudmFyYXJnc0VsZW1lbnQgPSB2YXJhcmdzRWxlbWVudDsgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIE5FV0NMQVNTOiAoKEpDTmV3Q2xhc3MpdHJlZSkudmFyYXJnc0VsZW1lbnQgPSB2YXJhcmdzRWxlbWVudDsgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIFRZUEVDQVNUOiBzZXRWYXJhcmdzSWZOZWVkZWQoKChKQ1R5cGVDYXN0KSB0cmVlKS5leHByLCB2YXJhcmdzRWxlbWVudCk7IGJyZWFrOwogICAgICAgICAgICAgICAgZGVmYXVsdDogdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBDb252ZXJ0IG1ldGhvZC9jb25zdHJ1Y3RvciBhcmd1bWVudHMgYnkgaW5zZXJ0aW5nIGFwcHJvcHJpYXRlIGNhc3QKICAgICAqIGFzIHJlcXVpcmVkIGJ5IHR5cGUtZXJhc3VyZSAtIHRoaXMgaXMgbmVlZGVkIHdoZW4gYnJpZGdpbmcgYSBsYW1iZGEvbWV0aG9kCiAgICAgKiByZWZlcmVuY2UsIGFzIHRoZSBicmlkZ2VkIHNpZ25hdHVyZSBtaWdodCByZXF1aXJlIGRvd25jYXN0IHRvIGJlIGNvbXBhdGlibGUKICAgICAqIHdpdGggdGhlIGdlbmVyYXRlZCBzaWduYXR1cmUuCiAgICAgKi8KICAgIHByaXZhdGUgTGlzdDxKQ0V4cHJlc3Npb24+IGNvbnZlcnRBcmdzKFN5bWJvbCBtZXRoLCBMaXN0PEpDRXhwcmVzc2lvbj4gYXJncywgVHlwZSB2YXJhcmdzRWxlbWVudCkgewogICAgICAgQXNzZXJ0LmNoZWNrKG1ldGgua2luZCA9PSBNVEgpOwogICAgICAgTGlzdDxUeXBlPiBmb3JtYWxzID0gdHlwZXMuZXJhc3VyZShtZXRoLnR5cGUpLmdldFBhcmFtZXRlclR5cGVzKCk7CiAgICAgICBpZiAodmFyYXJnc0VsZW1lbnQgIT0gbnVsbCkgewogICAgICAgICAgIEFzc2VydC5jaGVjaygobWV0aC5mbGFncygpICYgVkFSQVJHUykgIT0gMCk7CiAgICAgICB9CiAgICAgICByZXR1cm4gdHJhbnNUeXBlcy50cmFuc2xhdGVBcmdzKGFyZ3MsIGZvcm1hbHMsIHZhcmFyZ3NFbGVtZW50LCBhdHRyRW52KTsKICAgIH0KCiAgICAvLyA8L2VkaXRvci1mb2xkPgoKICAgIC8qKgogICAgICogQ29udmVydHMgYSBtZXRob2QgcmVmZXJlbmNlIHdoaWNoIGNhbm5vdCBiZSB1c2VkIGRpcmVjdGx5IGludG8gYSBsYW1iZGEKICAgICAqLwogICAgcHJpdmF0ZSBjbGFzcyBNZW1iZXJSZWZlcmVuY2VUb0xhbWJkYSB7CgogICAgICAgIHByaXZhdGUgZmluYWwgSkNNZW1iZXJSZWZlcmVuY2UgdHJlZTsKICAgICAgICBwcml2YXRlIGZpbmFsIFJlZmVyZW5jZVRyYW5zbGF0aW9uQ29udGV4dCBsb2NhbENvbnRleHQ7CiAgICAgICAgcHJpdmF0ZSBmaW5hbCBTeW1ib2wgb3duZXI7CiAgICAgICAgcHJpdmF0ZSBmaW5hbCBMaXN0QnVmZmVyPEpDRXhwcmVzc2lvbj4gYXJncyA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICBwcml2YXRlIGZpbmFsIExpc3RCdWZmZXI8SkNWYXJpYWJsZURlY2w+IHBhcmFtcyA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKCiAgICAgICAgcHJpdmF0ZSBKQ0V4cHJlc3Npb24gcmVjZWl2ZXJFeHByZXNzaW9uID0gbnVsbDsKCiAgICAgICAgTWVtYmVyUmVmZXJlbmNlVG9MYW1iZGEoSkNNZW1iZXJSZWZlcmVuY2UgdHJlZSwgUmVmZXJlbmNlVHJhbnNsYXRpb25Db250ZXh0IGxvY2FsQ29udGV4dCwgU3ltYm9sIG93bmVyKSB7CiAgICAgICAgICAgIHRoaXMudHJlZSA9IHRyZWU7CiAgICAgICAgICAgIHRoaXMubG9jYWxDb250ZXh0ID0gbG9jYWxDb250ZXh0OwogICAgICAgICAgICB0aGlzLm93bmVyID0gb3duZXI7CiAgICAgICAgfQoKICAgICAgICBKQ0xhbWJkYSBsYW1iZGEoKSB7CiAgICAgICAgICAgIGludCBwcmV2UG9zID0gbWFrZS5wb3M7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBtYWtlLmF0KHRyZWUpOwoKICAgICAgICAgICAgICAgIC8vYm9keSBnZW5lcmF0aW9uIC0gdGhpcyBjYW4gYmUgZWl0aGVyIGEgbWV0aG9kIGNhbGwgb3IgYQogICAgICAgICAgICAgICAgLy9uZXcgaW5zdGFuY2UgY3JlYXRpb24gZXhwcmVzc2lvbiwgZGVwZW5kaW5nIG9uIHRoZSBtZW1iZXIgcmVmZXJlbmNlIGtpbmQKICAgICAgICAgICAgICAgIFZhclN5bWJvbCByY3ZyID0gYWRkUGFyYW1ldGVyc1JldHVyblJlY2VpdmVyKCk7CiAgICAgICAgICAgICAgICBKQ0V4cHJlc3Npb24gZXhwciA9ICh0cmVlLmdldE1vZGUoKSA9PSBSZWZlcmVuY2VNb2RlLklOVk9LRSkKICAgICAgICAgICAgICAgICAgICAgICAgPyBleHByZXNzaW9uSW52b2tlKHJjdnIpCiAgICAgICAgICAgICAgICAgICAgICAgIDogZXhwcmVzc2lvbk5ldygpOwoKICAgICAgICAgICAgICAgIEpDTGFtYmRhIHNsYW0gPSBtYWtlLkxhbWJkYShwYXJhbXMudG9MaXN0KCksIGV4cHIpOwogICAgICAgICAgICAgICAgc2xhbS50YXJnZXRzID0gdHJlZS50YXJnZXRzOwogICAgICAgICAgICAgICAgc2xhbS50eXBlID0gdHJlZS50eXBlOwogICAgICAgICAgICAgICAgc2xhbS5wb3MgPSB0cmVlLnBvczsKICAgICAgICAgICAgICAgIHJldHVybiBzbGFtOwogICAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAgICAgbWFrZS5hdChwcmV2UG9zKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogR2VuZXJhdGUgdGhlIHBhcmFtZXRlciBsaXN0IGZvciB0aGUgY29udmVydGVkIG1lbWJlciByZWZlcmVuY2UuCiAgICAgICAgICoKICAgICAgICAgKiBAcmV0dXJuIFRoZSByZWNlaXZlciB2YXJpYWJsZSBzeW1ib2wsIGlmIGFueQogICAgICAgICAqLwogICAgICAgIFZhclN5bWJvbCBhZGRQYXJhbWV0ZXJzUmV0dXJuUmVjZWl2ZXIoKSB7CiAgICAgICAgICAgIFR5cGUgc2FtRGVzYyA9IGxvY2FsQ29udGV4dC5icmlkZ2VkUmVmU2lnKCk7CiAgICAgICAgICAgIExpc3Q8VHlwZT4gc2FtUFR5cGVzID0gc2FtRGVzYy5nZXRQYXJhbWV0ZXJUeXBlcygpOwogICAgICAgICAgICBMaXN0PFR5cGU+IGRlc2NQVHlwZXMgPSB0cmVlLmdldERlc2NyaXB0b3JUeXBlKHR5cGVzKS5nZXRQYXJhbWV0ZXJUeXBlcygpOwoKICAgICAgICAgICAgLy8gRGV0ZXJtaW5lIHRoZSByZWNlaXZlciwgaWYgYW55CiAgICAgICAgICAgIFZhclN5bWJvbCByY3ZyOwogICAgICAgICAgICBzd2l0Y2ggKHRyZWUua2luZCkgewogICAgICAgICAgICAgICAgY2FzZSBCT1VORDoKICAgICAgICAgICAgICAgICAgICAvLyBUaGUgcmVjZWl2ZXIgaXMgZXhwbGljaXQgaW4gdGhlIG1ldGhvZCByZWZlcmVuY2UKICAgICAgICAgICAgICAgICAgICByY3ZyID0gYWRkUGFyYW1ldGVyKCJyZWMkIiwgdHJlZS5nZXRRdWFsaWZpZXJFeHByZXNzaW9uKCkudHlwZSwgZmFsc2UpOwogICAgICAgICAgICAgICAgICAgIHJlY2VpdmVyRXhwcmVzc2lvbiA9IGF0dHIubWFrZU51bGxDaGVjayh0cmVlLmdldFF1YWxpZmllckV4cHJlc3Npb24oKSk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIFVOQk9VTkQ6CiAgICAgICAgICAgICAgICAgICAgLy8gVGhlIHJlY2VpdmVyIGlzIHRoZSBmaXJzdCBwYXJhbWV0ZXIsIGV4dHJhY3QgaXQgYW5kCiAgICAgICAgICAgICAgICAgICAgLy8gYWRqdXN0IHRoZSBTQU0gYW5kIHVuZXJhc2VkIHR5cGUgbGlzdHMgYWNjb3JkaW5nbHkKICAgICAgICAgICAgICAgICAgICByY3ZyID0gYWRkUGFyYW1ldGVyKCJyZWMkIiwgc2FtRGVzYy5nZXRQYXJhbWV0ZXJUeXBlcygpLmhlYWQsIGZhbHNlKTsKICAgICAgICAgICAgICAgICAgICBzYW1QVHlwZXMgPSBzYW1QVHlwZXMudGFpbDsKICAgICAgICAgICAgICAgICAgICBkZXNjUFR5cGVzID0gZGVzY1BUeXBlcy50YWlsOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICByY3ZyID0gbnVsbDsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBMaXN0PFR5cGU+IGltcGxQVHlwZXMgPSB0cmVlLnN5bS50eXBlLmdldFBhcmFtZXRlclR5cGVzKCk7CiAgICAgICAgICAgIGludCBpbXBsU2l6ZSA9IGltcGxQVHlwZXMuc2l6ZSgpOwogICAgICAgICAgICBpbnQgc2FtU2l6ZSA9IHNhbVBUeXBlcy5zaXplKCk7CiAgICAgICAgICAgIC8vIExhc3QgcGFyYW1ldGVyIHRvIGNvcHkgZnJvbSByZWZlcmVuY2VkIG1ldGhvZCwgZXhjbHVkZSBmaW5hbCB2YXIgYXJncwogICAgICAgICAgICBpbnQgbGFzdCA9IGxvY2FsQ29udGV4dC5uZWVkc1ZhckFyZ3NDb252ZXJzaW9uKCkgPyBpbXBsU2l6ZSAtIDEgOiBpbXBsU2l6ZTsKCiAgICAgICAgICAgIC8vIEZhaWxzYWZlIC0tIGFzc3VyZSBtYXRjaC11cAogICAgICAgICAgICBib29sZWFuIGNoZWNrRm9ySW50ZXJzZWN0aW9uID0gdHJlZS52YXJhcmdzRWxlbWVudCAhPSBudWxsIHx8IGltcGxTaXplID09IGRlc2NQVHlwZXMuc2l6ZSgpOwoKICAgICAgICAgICAgLy8gVXNlIHBhcmFtZXRlciB0eXBlcyBvZiB0aGUgaW1wbGVtZW50YXRpb24gbWV0aG9kIHVubGVzcyB0aGUgdW5lcmFzZWQKICAgICAgICAgICAgLy8gU0FNIHBhcmFtZXRlciB0eXBlIGlzIGFuIGludGVyc2VjdGlvbiB0eXBlLCBpbiB0aGF0IGNhc2UgdXNlIHRoZQogICAgICAgICAgICAvLyBlcmFzZWQgU0FNIHBhcmFtZXRlciB0eXBlIHNvIHRoYXQgdGhlIHN1cGVydHlwZSByZWxhdGlvbnNoaXAKICAgICAgICAgICAgLy8gdGhlIGltcGxlbWVudGF0aW9uIG1ldGhvZCBwYXJhbWV0ZXJzIGlzIG5vdCBvYnNjdXJlZC4KICAgICAgICAgICAgLy8gTm90ZTogaW4gdGhpcyBsb29wLCB0aGUgbGlzdHMgaW1wbFBUeXBlcywgc2FtUFR5cGVzLCBhbmQgZGVzY1BUeXBlcwogICAgICAgICAgICAvLyBhcmUgdXNlZCBhcyBwb2ludGVycyB0byB0aGUgY3VycmVudCBwYXJhbWV0ZXIgdHlwZSBpbmZvcm1hdGlvbgogICAgICAgICAgICAvLyBhbmQgYXJlIHRodXMgbm90IHVzYWJsZSBhZnRlcndhcmRzLgogICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaW1wbFBUeXBlcy5ub25FbXB0eSgpICYmIGkgPCBsYXN0OyArK2kpIHsKICAgICAgICAgICAgICAgIC8vIEJ5IGRlZmF1bHQgdXNlIHRoZSBpbXBsZW1lbnRhdGlvbiBtZXRob2QgcGFybWV0ZXIgdHlwZQogICAgICAgICAgICAgICAgVHlwZSBwYXJtVHlwZSA9IGltcGxQVHlwZXMuaGVhZDsKICAgICAgICAgICAgICAgIC8vIElmIHRoZSB1bmVyYXNlZCBwYXJhbWV0ZXIgdHlwZSBpcyBhIHR5cGUgdmFyaWFibGUgd2hvc2UKICAgICAgICAgICAgICAgIC8vIGJvdW5kIGlzIGFuIGludGVyc2VjdGlvbiAoZWcuIDxUIGV4dGVuZHMgQSAmIEI+KSB0aGVuCiAgICAgICAgICAgICAgICAvLyB1c2UgdGhlIFNBTSBwYXJhbWV0ZXIgdHlwZQogICAgICAgICAgICAgICAgaWYgKGNoZWNrRm9ySW50ZXJzZWN0aW9uICYmIGRlc2NQVHlwZXMuaGVhZC5nZXRLaW5kKCkgPT0gVHlwZUtpbmQuVFlQRVZBUikgewogICAgICAgICAgICAgICAgICAgIFR5cGVWYXIgdHYgPSAoVHlwZVZhcikgZGVzY1BUeXBlcy5oZWFkOwogICAgICAgICAgICAgICAgICAgIGlmICh0di5ib3VuZC5nZXRLaW5kKCkgPT0gVHlwZUtpbmQuSU5URVJTRUNUSU9OKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHBhcm1UeXBlID0gc2FtUFR5cGVzLmhlYWQ7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYWRkUGFyYW1ldGVyKCJ4JCIgKyBpLCBwYXJtVHlwZSwgdHJ1ZSk7CgogICAgICAgICAgICAgICAgLy8gQWR2YW5jZSB0byB0aGUgbmV4dCBwYXJhbWV0ZXIKICAgICAgICAgICAgICAgIGltcGxQVHlwZXMgPSBpbXBsUFR5cGVzLnRhaWw7CiAgICAgICAgICAgICAgICBzYW1QVHlwZXMgPSBzYW1QVHlwZXMudGFpbDsKICAgICAgICAgICAgICAgIGRlc2NQVHlwZXMgPSBkZXNjUFR5cGVzLnRhaWw7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gRmxhdHRlbiBvdXQgdGhlIHZhciBhcmdzCiAgICAgICAgICAgIGZvciAoaW50IGkgPSBsYXN0OyBpIDwgc2FtU2l6ZTsgKytpKSB7CiAgICAgICAgICAgICAgICBhZGRQYXJhbWV0ZXIoInh2YSQiICsgaSwgdHJlZS52YXJhcmdzRWxlbWVudCwgdHJ1ZSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiByY3ZyOwogICAgICAgIH0KCiAgICAgICAgSkNFeHByZXNzaW9uIGdldFJlY2VpdmVyRXhwcmVzc2lvbigpIHsKICAgICAgICAgICAgcmV0dXJuIHJlY2VpdmVyRXhwcmVzc2lvbjsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgSkNFeHByZXNzaW9uIG1ha2VSZWNlaXZlcihWYXJTeW1ib2wgcmN2cikgewogICAgICAgICAgICBpZiAocmN2ciA9PSBudWxsKSByZXR1cm4gbnVsbDsKICAgICAgICAgICAgSkNFeHByZXNzaW9uIHJjdnJFeHByID0gbWFrZS5JZGVudChyY3ZyKTsKICAgICAgICAgICAgVHlwZSByY3ZyVHlwZSA9IHRyZWUub3duZXJBY2Nlc3NpYmxlID8gdHJlZS5zeW0uZW5jbENsYXNzKCkudHlwZSA6IHRyZWUuZXhwci50eXBlOwogICAgICAgICAgICBpZiAocmN2clR5cGUgPT0gc3ltcy5hcnJheUNsYXNzLnR5cGUpIHsKICAgICAgICAgICAgICAgIC8vIE1hcCB0aGUgcmVjZWl2ZXIgdHlwZSB0byB0aGUgYWN0dWFsbHkgdHlwZSwgbm90IGp1c3QgImFycmF5IgogICAgICAgICAgICAgICAgcmN2clR5cGUgPSB0cmVlLmdldFF1YWxpZmllckV4cHJlc3Npb24oKS50eXBlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICghcmN2ci50eXBlLnRzeW0uaXNTdWJDbGFzcyhyY3ZyVHlwZS50c3ltLCB0eXBlcykpIHsKICAgICAgICAgICAgICAgIHJjdnJFeHByID0gbWFrZS5UeXBlQ2FzdChtYWtlLlR5cGUocmN2clR5cGUpLCByY3ZyRXhwcikuc2V0VHlwZShyY3ZyVHlwZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHJjdnJFeHByOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogZGV0ZXJtaW5lIHRoZSByZWNlaXZlciBvZiB0aGUgbWV0aG9kIGNhbGwgLSB0aGUgcmVjZWl2ZXIgY2FuCiAgICAgICAgICogYmUgYSB0eXBlIHF1YWxpZmllciwgdGhlIHN5bnRoZXRpYyByZWNlaXZlciBwYXJhbWV0ZXIgb3IgJ3N1cGVyJy4KICAgICAgICAgKi8KICAgICAgICBwcml2YXRlIEpDRXhwcmVzc2lvbiBleHByZXNzaW9uSW52b2tlKFZhclN5bWJvbCByY3ZyKSB7CiAgICAgICAgICAgIEpDRXhwcmVzc2lvbiBxdWFsaWZpZXIgPQogICAgICAgICAgICAgICAgICAgIChyY3ZyICE9IG51bGwpID8KICAgICAgICAgICAgICAgICAgICAgICAgbWFrZVJlY2VpdmVyKHJjdnIpIDoKICAgICAgICAgICAgICAgICAgICAgICAgdHJlZS5nZXRRdWFsaWZpZXJFeHByZXNzaW9uKCk7CgogICAgICAgICAgICAvL2NyZWF0ZSB0aGUgcXVhbGlmaWVyIGV4cHJlc3Npb24KICAgICAgICAgICAgSkNGaWVsZEFjY2VzcyBzZWxlY3QgPSBtYWtlLlNlbGVjdChxdWFsaWZpZXIsIHRyZWUuc3ltLm5hbWUpOwogICAgICAgICAgICBzZWxlY3Quc3ltID0gdHJlZS5zeW07CiAgICAgICAgICAgIHNlbGVjdC50eXBlID0gdHJlZS5zeW0uZXJhc3VyZSh0eXBlcyk7CgogICAgICAgICAgICAvL2NyZWF0ZSB0aGUgbWV0aG9kIGNhbGwgZXhwcmVzc2lvbgogICAgICAgICAgICBKQ0V4cHJlc3Npb24gYXBwbHkgPSBtYWtlLkFwcGx5KExpc3QubmlsKCksIHNlbGVjdCwKICAgICAgICAgICAgICAgICAgICBjb252ZXJ0QXJncyh0cmVlLnN5bSwgYXJncy50b0xpc3QoKSwgdHJlZS52YXJhcmdzRWxlbWVudCkpLgogICAgICAgICAgICAgICAgICAgIHNldFR5cGUodHJlZS5zeW0uZXJhc3VyZSh0eXBlcykuZ2V0UmV0dXJuVHlwZSgpKTsKCiAgICAgICAgICAgIGFwcGx5ID0gdHJhbnNUeXBlcy5jb2VyY2UoYXR0ckVudiwgYXBwbHksCiAgICAgICAgICAgICAgICAgICAgdHlwZXMuZXJhc3VyZShsb2NhbENvbnRleHQudHJlZS5yZWZlcmVudFR5cGUuZ2V0UmV0dXJuVHlwZSgpKSk7CgogICAgICAgICAgICBzZXRWYXJhcmdzSWZOZWVkZWQoYXBwbHksIHRyZWUudmFyYXJnc0VsZW1lbnQpOwogICAgICAgICAgICByZXR1cm4gYXBwbHk7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBMYW1iZGEgYm9keSB0byB1c2UgZm9yIGEgJ25ldycuCiAgICAgICAgICovCiAgICAgICAgcHJpdmF0ZSBKQ0V4cHJlc3Npb24gZXhwcmVzc2lvbk5ldygpIHsKICAgICAgICAgICAgaWYgKHRyZWUua2luZCA9PSBSZWZlcmVuY2VLaW5kLkFSUkFZX0NUT1IpIHsKICAgICAgICAgICAgICAgIC8vY3JlYXRlIHRoZSBhcnJheSBjcmVhdGlvbiBleHByZXNzaW9uCiAgICAgICAgICAgICAgICBKQ05ld0FycmF5IG5ld0FyciA9IG1ha2UuTmV3QXJyYXkoCiAgICAgICAgICAgICAgICAgICAgICAgIG1ha2UuVHlwZSh0eXBlcy5lbGVtdHlwZSh0cmVlLmdldFF1YWxpZmllckV4cHJlc3Npb24oKS50eXBlKSksCiAgICAgICAgICAgICAgICAgICAgICAgIExpc3Qub2YobWFrZS5JZGVudChwYXJhbXMuZmlyc3QoKSkpLAogICAgICAgICAgICAgICAgICAgICAgICBudWxsKTsKICAgICAgICAgICAgICAgIG5ld0Fyci50eXBlID0gdHJlZS5nZXRRdWFsaWZpZXJFeHByZXNzaW9uKCkudHlwZTsKICAgICAgICAgICAgICAgIHJldHVybiBuZXdBcnI7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvL2NyZWF0ZSB0aGUgaW5zdGFuY2UgY3JlYXRpb24gZXhwcmVzc2lvbgogICAgICAgICAgICAgICAgLy9ub3RlIHRoYXQgbWV0aG9kIHJlZmVyZW5jZSBzeW50YXggZG9lcyBub3QgYWxsb3cgYW4gZXhwbGljaXQKICAgICAgICAgICAgICAgIC8vZW5jbG9zaW5nIGNsYXNzIChzbyB0aGUgZW5jbG9zaW5nIGNsYXNzIGlzIG51bGwpCiAgICAgICAgICAgICAgICBKQ05ld0NsYXNzIG5ld0NsYXNzID0gbWFrZS5OZXdDbGFzcyhudWxsLAogICAgICAgICAgICAgICAgICAgICAgICBMaXN0Lm5pbCgpLAogICAgICAgICAgICAgICAgICAgICAgICBtYWtlLlR5cGUodHJlZS5nZXRRdWFsaWZpZXJFeHByZXNzaW9uKCkudHlwZSksCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnZlcnRBcmdzKHRyZWUuc3ltLCBhcmdzLnRvTGlzdCgpLCB0cmVlLnZhcmFyZ3NFbGVtZW50KSwKICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCk7CiAgICAgICAgICAgICAgICBuZXdDbGFzcy5jb25zdHJ1Y3RvciA9IHRyZWUuc3ltOwogICAgICAgICAgICAgICAgbmV3Q2xhc3MuY29uc3RydWN0b3JUeXBlID0gdHJlZS5zeW0uZXJhc3VyZSh0eXBlcyk7CiAgICAgICAgICAgICAgICBuZXdDbGFzcy50eXBlID0gdHJlZS5nZXRRdWFsaWZpZXJFeHByZXNzaW9uKCkudHlwZTsKICAgICAgICAgICAgICAgIHNldFZhcmFyZ3NJZk5lZWRlZChuZXdDbGFzcywgdHJlZS52YXJhcmdzRWxlbWVudCk7CiAgICAgICAgICAgICAgICByZXR1cm4gbmV3Q2xhc3M7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHByaXZhdGUgVmFyU3ltYm9sIGFkZFBhcmFtZXRlcihTdHJpbmcgbmFtZSwgVHlwZSBwLCBib29sZWFuIGdlbkFyZykgewogICAgICAgICAgICBWYXJTeW1ib2wgdnN5bSA9IG5ldyBWYXJTeW1ib2woUEFSQU1FVEVSIHwgU1lOVEhFVElDLCBuYW1lcy5mcm9tU3RyaW5nKG5hbWUpLCBwLCBvd25lcik7CiAgICAgICAgICAgIHZzeW0ucG9zID0gdHJlZS5wb3M7CiAgICAgICAgICAgIHBhcmFtcy5hcHBlbmQobWFrZS5WYXJEZWYodnN5bSwgbnVsbCkpOwogICAgICAgICAgICBpZiAoZ2VuQXJnKSB7CiAgICAgICAgICAgICAgICBhcmdzLmFwcGVuZChtYWtlLklkZW50KHZzeW0pKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gdnN5bTsKICAgICAgICB9CiAgICB9CgogICAgcHJpdmF0ZSBNZXRob2RUeXBlIHR5cGVUb01ldGhvZFR5cGUoVHlwZSBtdCkgewogICAgICAgIFR5cGUgdHlwZSA9IHR5cGVzLmVyYXN1cmUobXQpOwogICAgICAgIHJldHVybiBuZXcgTWV0aG9kVHlwZSh0eXBlLmdldFBhcmFtZXRlclR5cGVzKCksCiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUuZ2V0UmV0dXJuVHlwZSgpLAogICAgICAgICAgICAgICAgICAgICAgICB0eXBlLmdldFRocm93blR5cGVzKCksCiAgICAgICAgICAgICAgICAgICAgICAgIHN5bXMubWV0aG9kQ2xhc3MpOwogICAgfQoKICAgIC8qKgogICAgICogR2VuZXJhdGUgYW4gaW5keSBtZXRob2QgY2FsbCB0byB0aGUgbWV0YSBmYWN0b3J5CiAgICAgKi8KICAgIHByaXZhdGUgSkNFeHByZXNzaW9uIG1ha2VNZXRhZmFjdG9yeUluZHlDYWxsKFRyYW5zbGF0aW9uQ29udGV4dDw/PiBjb250ZXh0LAogICAgICAgICAgICBpbnQgcmVmS2luZCwgU3ltYm9sIHJlZlN5bSwgTGlzdDxKQ0V4cHJlc3Npb24+IGluZHlfYXJncykgewogICAgICAgIEpDRnVuY3Rpb25hbEV4cHJlc3Npb24gdHJlZSA9IGNvbnRleHQudHJlZTsKICAgICAgICAvL2RldGVybWluZSB0aGUgc3RhdGljIGJzbSBhcmdzCiAgICAgICAgTWV0aG9kU3ltYm9sIHNhbVN5bSA9IChNZXRob2RTeW1ib2wpIHR5cGVzLmZpbmREZXNjcmlwdG9yU3ltYm9sKHRyZWUudHlwZS50c3ltKTsKICAgICAgICBMaXN0PE9iamVjdD4gc3RhdGljQXJncyA9IExpc3Qub2YoCiAgICAgICAgICAgICAgICB0eXBlVG9NZXRob2RUeXBlKHNhbVN5bS50eXBlKSwKICAgICAgICAgICAgICAgIG5ldyBQb29sLk1ldGhvZEhhbmRsZShyZWZLaW5kLCByZWZTeW0sIHR5cGVzKSwKICAgICAgICAgICAgICAgIHR5cGVUb01ldGhvZFR5cGUodHJlZS5nZXREZXNjcmlwdG9yVHlwZSh0eXBlcykpKTsKCiAgICAgICAgLy9jb21wdXRlZCBpbmR5IGFyZyB0eXBlcwogICAgICAgIExpc3RCdWZmZXI8VHlwZT4gaW5keV9hcmdzX3R5cGVzID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgIGZvciAoSkNFeHByZXNzaW9uIGFyZyA6IGluZHlfYXJncykgewogICAgICAgICAgICBpbmR5X2FyZ3NfdHlwZXMuYXBwZW5kKGFyZy50eXBlKTsKICAgICAgICB9CgogICAgICAgIC8vZmluYWxseSwgY29tcHV0ZSB0aGUgdHlwZSBvZiB0aGUgaW5keSBjYWxsCiAgICAgICAgTWV0aG9kVHlwZSBpbmR5VHlwZSA9IG5ldyBNZXRob2RUeXBlKGluZHlfYXJnc190eXBlcy50b0xpc3QoKSwKICAgICAgICAgICAgICAgIHRyZWUudHlwZSwKICAgICAgICAgICAgICAgIExpc3QubmlsKCksCiAgICAgICAgICAgICAgICBzeW1zLm1ldGhvZENsYXNzKTsKCiAgICAgICAgTmFtZSBtZXRhZmFjdG9yeU5hbWUgPSBjb250ZXh0Lm5lZWRzQWx0TWV0YWZhY3RvcnkoKSA/CiAgICAgICAgICAgICAgICBuYW1lcy5hbHRNZXRhZmFjdG9yeSA6IG5hbWVzLm1ldGFmYWN0b3J5OwoKICAgICAgICBpZiAoY29udGV4dC5uZWVkc0FsdE1ldGFmYWN0b3J5KCkpIHsKICAgICAgICAgICAgTGlzdEJ1ZmZlcjxPYmplY3Q+IG1hcmtlcnMgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgIGZvciAoVHlwZSB0IDogdHJlZS50YXJnZXRzLnRhaWwpIHsKICAgICAgICAgICAgICAgIGlmICh0LnRzeW0gIT0gc3ltcy5zZXJpYWxpemFibGVUeXBlLnRzeW0pIHsKICAgICAgICAgICAgICAgICAgICBtYXJrZXJzLmFwcGVuZCh0LnRzeW0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGludCBmbGFncyA9IGNvbnRleHQuaXNTZXJpYWxpemFibGUoKSA/IEZMQUdfU0VSSUFMSVpBQkxFIDogMDsKICAgICAgICAgICAgYm9vbGVhbiBoYXNNYXJrZXJzID0gbWFya2Vycy5ub25FbXB0eSgpOwogICAgICAgICAgICBib29sZWFuIGhhc0JyaWRnZXMgPSBjb250ZXh0LmJyaWRnZXMubm9uRW1wdHkoKTsKICAgICAgICAgICAgaWYgKGhhc01hcmtlcnMpIHsKICAgICAgICAgICAgICAgIGZsYWdzIHw9IEZMQUdfTUFSS0VSUzsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoaGFzQnJpZGdlcykgewogICAgICAgICAgICAgICAgZmxhZ3MgfD0gRkxBR19CUklER0VTOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHN0YXRpY0FyZ3MgPSBzdGF0aWNBcmdzLmFwcGVuZChmbGFncyk7CiAgICAgICAgICAgIGlmIChoYXNNYXJrZXJzKSB7CiAgICAgICAgICAgICAgICBzdGF0aWNBcmdzID0gc3RhdGljQXJncy5hcHBlbmQobWFya2Vycy5sZW5ndGgoKSk7CiAgICAgICAgICAgICAgICBzdGF0aWNBcmdzID0gc3RhdGljQXJncy5hcHBlbmRMaXN0KG1hcmtlcnMudG9MaXN0KCkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChoYXNCcmlkZ2VzKSB7CiAgICAgICAgICAgICAgICBzdGF0aWNBcmdzID0gc3RhdGljQXJncy5hcHBlbmQoY29udGV4dC5icmlkZ2VzLmxlbmd0aCgpIC0gMSk7CiAgICAgICAgICAgICAgICBmb3IgKFN5bWJvbCBzIDogY29udGV4dC5icmlkZ2VzKSB7CiAgICAgICAgICAgICAgICAgICAgVHlwZSBzX2VyYXN1cmUgPSBzLmVyYXN1cmUodHlwZXMpOwogICAgICAgICAgICAgICAgICAgIGlmICghdHlwZXMuaXNTYW1lVHlwZShzX2VyYXN1cmUsIHNhbVN5bS5lcmFzdXJlKHR5cGVzKSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgc3RhdGljQXJncyA9IHN0YXRpY0FyZ3MuYXBwZW5kKHMuZXJhc3VyZSh0eXBlcykpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoY29udGV4dC5pc1NlcmlhbGl6YWJsZSgpKSB7CiAgICAgICAgICAgICAgICBpbnQgcHJldlBvcyA9IG1ha2UucG9zOwogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICBtYWtlLmF0KGtJbmZvLmNsYXp6KTsKICAgICAgICAgICAgICAgICAgICBhZGREZXNlcmlhbGl6YXRpb25DYXNlKHJlZktpbmQsIHJlZlN5bSwgdHJlZS50eXBlLCBzYW1TeW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmVlLCBzdGF0aWNBcmdzLCBpbmR5VHlwZSk7CiAgICAgICAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAgICAgICAgIG1ha2UuYXQocHJldlBvcyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBtYWtlSW5keUNhbGwodHJlZSwgc3ltcy5sYW1iZGFNZXRhZmFjdG9yeSwgbWV0YWZhY3RvcnlOYW1lLCBzdGF0aWNBcmdzLCBpbmR5VHlwZSwgaW5keV9hcmdzLCBzYW1TeW0ubmFtZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZW5lcmF0ZSBhbiBpbmR5IG1ldGhvZCBjYWxsIHdpdGggZ2l2ZW4gbmFtZSwgdHlwZSBhbmQgc3RhdGljIGJvb3RzdHJhcAogICAgICogYXJndW1lbnRzIHR5cGVzCiAgICAgKi8KICAgIHByaXZhdGUgSkNFeHByZXNzaW9uIG1ha2VJbmR5Q2FsbChEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBUeXBlIHNpdGUsIE5hbWUgYnNtTmFtZSwKICAgICAgICAgICAgTGlzdDxPYmplY3Q+IHN0YXRpY0FyZ3MsIE1ldGhvZFR5cGUgaW5keVR5cGUsIExpc3Q8SkNFeHByZXNzaW9uPiBpbmR5QXJncywKICAgICAgICAgICAgTmFtZSBtZXRoTmFtZSkgewogICAgICAgIGludCBwcmV2UG9zID0gbWFrZS5wb3M7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgbWFrZS5hdChwb3MpOwogICAgICAgICAgICBMaXN0PFR5cGU+IGJzbV9zdGF0aWNBcmdzID0gTGlzdC5vZihzeW1zLm1ldGhvZEhhbmRsZUxvb2t1cFR5cGUsCiAgICAgICAgICAgICAgICAgICAgc3ltcy5zdHJpbmdUeXBlLAogICAgICAgICAgICAgICAgICAgIHN5bXMubWV0aG9kVHlwZVR5cGUpLmFwcGVuZExpc3QoYnNtU3RhdGljQXJnVG9UeXBlcyhzdGF0aWNBcmdzKSk7CgogICAgICAgICAgICBTeW1ib2wgYnNtID0gcnMucmVzb2x2ZUludGVybmFsTWV0aG9kKHBvcywgYXR0ckVudiwgc2l0ZSwKICAgICAgICAgICAgICAgICAgICBic21OYW1lLCBic21fc3RhdGljQXJncywgTGlzdC5uaWwoKSk7CgogICAgICAgICAgICBEeW5hbWljTWV0aG9kU3ltYm9sIGR5blN5bSA9CiAgICAgICAgICAgICAgICAgICAgbmV3IER5bmFtaWNNZXRob2RTeW1ib2wobWV0aE5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ltcy5ub1N5bWJvbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBic20uaXNTdGF0aWMoKSA/CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENsYXNzRmlsZS5SRUZfaW52b2tlU3RhdGljIDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2xhc3NGaWxlLlJFRl9pbnZva2VWaXJ0dWFsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChNZXRob2RTeW1ib2wpYnNtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZHlUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRpY0FyZ3MudG9BcnJheSgpKTsKCiAgICAgICAgICAgIEpDRmllbGRBY2Nlc3MgcXVhbGlmaWVyID0gbWFrZS5TZWxlY3QobWFrZS5RdWFsSWRlbnQoc2l0ZS50c3ltKSwgYnNtTmFtZSk7CiAgICAgICAgICAgIHF1YWxpZmllci5zeW0gPSBkeW5TeW07CiAgICAgICAgICAgIHF1YWxpZmllci50eXBlID0gaW5keVR5cGUuZ2V0UmV0dXJuVHlwZSgpOwoKICAgICAgICAgICAgSkNNZXRob2RJbnZvY2F0aW9uIHByb3h5Q2FsbCA9IG1ha2UuQXBwbHkoTGlzdC5uaWwoKSwgcXVhbGlmaWVyLCBpbmR5QXJncyk7CiAgICAgICAgICAgIHByb3h5Q2FsbC50eXBlID0gaW5keVR5cGUuZ2V0UmV0dXJuVHlwZSgpOwogICAgICAgICAgICByZXR1cm4gcHJveHlDYWxsOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgIG1ha2UuYXQocHJldlBvcyk7CiAgICAgICAgfQogICAgfQogICAgLy93aGVyZQogICAgcHJpdmF0ZSBMaXN0PFR5cGU+IGJzbVN0YXRpY0FyZ1RvVHlwZXMoTGlzdDxPYmplY3Q+IGFyZ3MpIHsKICAgICAgICBMaXN0QnVmZmVyPFR5cGU+IGFyZ3R5cGVzID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgIGZvciAoT2JqZWN0IGFyZyA6IGFyZ3MpIHsKICAgICAgICAgICAgYXJndHlwZXMuYXBwZW5kKGJzbVN0YXRpY0FyZ1RvVHlwZShhcmcpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGFyZ3R5cGVzLnRvTGlzdCgpOwogICAgfQoKICAgIHByaXZhdGUgVHlwZSBic21TdGF0aWNBcmdUb1R5cGUoT2JqZWN0IGFyZykgewogICAgICAgIEFzc2VydC5jaGVja05vbk51bGwoYXJnKTsKICAgICAgICBpZiAoYXJnIGluc3RhbmNlb2YgQ2xhc3NTeW1ib2wpIHsKICAgICAgICAgICAgcmV0dXJuIHN5bXMuY2xhc3NUeXBlOwogICAgICAgIH0gZWxzZSBpZiAoYXJnIGluc3RhbmNlb2YgSW50ZWdlcikgewogICAgICAgICAgICByZXR1cm4gc3ltcy5pbnRUeXBlOwogICAgICAgIH0gZWxzZSBpZiAoYXJnIGluc3RhbmNlb2YgTG9uZykgewogICAgICAgICAgICByZXR1cm4gc3ltcy5sb25nVHlwZTsKICAgICAgICB9IGVsc2UgaWYgKGFyZyBpbnN0YW5jZW9mIEZsb2F0KSB7CiAgICAgICAgICAgIHJldHVybiBzeW1zLmZsb2F0VHlwZTsKICAgICAgICB9IGVsc2UgaWYgKGFyZyBpbnN0YW5jZW9mIERvdWJsZSkgewogICAgICAgICAgICByZXR1cm4gc3ltcy5kb3VibGVUeXBlOwogICAgICAgIH0gZWxzZSBpZiAoYXJnIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICAgIHJldHVybiBzeW1zLnN0cmluZ1R5cGU7CiAgICAgICAgfSBlbHNlIGlmIChhcmcgaW5zdGFuY2VvZiBQb29sLk1ldGhvZEhhbmRsZSkgewogICAgICAgICAgICByZXR1cm4gc3ltcy5tZXRob2RIYW5kbGVUeXBlOwogICAgICAgIH0gZWxzZSBpZiAoYXJnIGluc3RhbmNlb2YgTWV0aG9kVHlwZSkgewogICAgICAgICAgICByZXR1cm4gc3ltcy5tZXRob2RUeXBlVHlwZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBBc3NlcnQuZXJyb3IoImJhZCBzdGF0aWMgYXJnICIgKyBhcmcuZ2V0Q2xhc3MoKSk7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEdldCB0aGUgb3Bjb2RlIGFzc29jaWF0ZWQgd2l0aCB0aGlzIG1ldGhvZCByZWZlcmVuY2UKICAgICAqLwogICAgcHJpdmF0ZSBpbnQgcmVmZXJlbmNlS2luZChTeW1ib2wgcmVmU3ltKSB7CiAgICAgICAgaWYgKHJlZlN5bS5pc0NvbnN0cnVjdG9yKCkpIHsKICAgICAgICAgICAgcmV0dXJuIENsYXNzRmlsZS5SRUZfbmV3SW52b2tlU3BlY2lhbDsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBpZiAocmVmU3ltLmlzU3RhdGljKCkpIHsKICAgICAgICAgICAgICAgIHJldHVybiBDbGFzc0ZpbGUuUkVGX2ludm9rZVN0YXRpYzsKICAgICAgICAgICAgfSBlbHNlIGlmICgocmVmU3ltLmZsYWdzKCkgJiBQUklWQVRFKSAhPSAwKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gQ2xhc3NGaWxlLlJFRl9pbnZva2VTcGVjaWFsOwogICAgICAgICAgICB9IGVsc2UgaWYgKHJlZlN5bS5lbmNsQ2xhc3MoKS5pc0ludGVyZmFjZSgpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gQ2xhc3NGaWxlLlJFRl9pbnZva2VJbnRlcmZhY2U7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICByZXR1cm4gQ2xhc3NGaWxlLlJFRl9pbnZva2VWaXJ0dWFsOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8vIDxlZGl0b3ItZm9sZCBkZWZhdWx0c3RhdGU9ImNvbGxhcHNlZCIgZGVzYz0iTGFtYmRhL3JlZmVyZW5jZSBhbmFseXplciI+CiAgICAvKioKICAgICAqIFRoaXMgdmlzaXRvciBjb2xsZWN0cyBpbmZvcm1hdGlvbiBhYm91dCB0cmFuc2xhdGlvbiBvZiBhIGxhbWJkYSBleHByZXNzaW9uLgogICAgICogTW9yZSBzcGVjaWZpY2FsbHksIGl0IGtlZXBzIHRyYWNrIG9mIHRoZSBlbmNsb3NpbmcgY29udGV4dHMgYW5kIGNhcHR1cmVkIGxvY2FscwogICAgICogYWNjZXNzZWQgYnkgdGhlIGxhbWJkYSBiZWluZyB0cmFuc2xhdGVkIChhcyB3ZWxsIGFzIG90aGVyIHVzZWZ1bCBpbmZvKS4KICAgICAqIEl0IGFsc28gdHJhbnNsYXRlcyBhd2F5IHByb2JsZW1zIGZvciBMYW1iZGFUb01ldGhvZC4KICAgICAqLwogICAgY2xhc3MgTGFtYmRhQW5hbHl6ZXJQcmVwcm9jZXNzb3IgZXh0ZW5kcyBUcmVlVHJhbnNsYXRvciB7CgogICAgICAgIC8qKiB0aGUgZnJhbWUgc3RhY2sgLSB1c2VkIHRvIHJlY29uc3RydWN0IHRyYW5zbGF0aW9uIGluZm8gYWJvdXQgZW5jbG9zaW5nIHNjb3BlcyAqLwogICAgICAgIHByaXZhdGUgTGlzdDxGcmFtZT4gZnJhbWVTdGFjazsKCiAgICAgICAgLyoqCiAgICAgICAgICoga2VlcCB0aGUgY291bnQgb2YgbGFtYmRhIGV4cHJlc3Npb24gKHVzZWQgdG8gZ2VuZXJhdGUgdW5hbWJpZ3VvdXMKICAgICAgICAgKiBuYW1lcykKICAgICAgICAgKi8KICAgICAgICBwcml2YXRlIGludCBsYW1iZGFDb3VudCA9IDA7CgogICAgICAgIC8qKgogICAgICAgICAqIExpc3Qgb2YgdHlwZXMgdW5kZXJnb2luZyBjb25zdHJ1Y3Rpb24gdmlhIGV4cGxpY2l0IGNvbnN0cnVjdG9yIGNoYWluaW5nLgogICAgICAgICAqLwogICAgICAgIHByaXZhdGUgTGlzdDxDbGFzc1N5bWJvbD4gdHlwZXNVbmRlckNvbnN0cnVjdGlvbjsKCiAgICAgICAgLyoqCiAgICAgICAgICoga2VlcCB0aGUgY291bnQgb2YgbGFtYmRhIGV4cHJlc3Npb24gZGVmaW5lZCBpbiBnaXZlbiBjb250ZXh0ICh1c2VkIHRvCiAgICAgICAgICogZ2VuZXJhdGUgdW5hbWJpZ3VvdXMgbmFtZXMgZm9yIHNlcmlhbGl6YWJsZSBsYW1iZGFzKQogICAgICAgICAqLwogICAgICAgIHByaXZhdGUgY2xhc3MgU3ludGhldGljTWV0aG9kTmFtZUNvdW50ZXIgewogICAgICAgICAgICBwcml2YXRlIE1hcDxTdHJpbmcsIEludGVnZXI+IG1hcCA9IG5ldyBIYXNoTWFwPD4oKTsKICAgICAgICAgICAgaW50IGdldEluZGV4KFN0cmluZ0J1aWxkZXIgYnVmKSB7CiAgICAgICAgICAgICAgICBTdHJpbmcgdGVtcCA9IGJ1Zi50b1N0cmluZygpOwogICAgICAgICAgICAgICAgSW50ZWdlciBjb3VudCA9IG1hcC5nZXQodGVtcCk7CiAgICAgICAgICAgICAgICBpZiAoY291bnQgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIGNvdW50ID0gMDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICsrY291bnQ7CiAgICAgICAgICAgICAgICBtYXAucHV0KHRlbXAsIGNvdW50KTsKICAgICAgICAgICAgICAgIHJldHVybiBjb3VudDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBwcml2YXRlIFN5bnRoZXRpY01ldGhvZE5hbWVDb3VudGVyIHN5bnRoZXRpY01ldGhvZE5hbWVDb3VudHMgPQogICAgICAgICAgICAgICAgbmV3IFN5bnRoZXRpY01ldGhvZE5hbWVDb3VudGVyKCk7CgogICAgICAgIHByaXZhdGUgTWFwPFN5bWJvbCwgSkNDbGFzc0RlY2w+IGxvY2FsQ2xhc3NEZWZzOwoKICAgICAgICAvKioKICAgICAgICAgKiBtYXBzIGZvciBmYWtlIGNsaW5pdCBzeW1ib2xzIHRvIGJlIHVzZWQgYXMgb3duZXJzIG9mIGxhbWJkYSBvY2N1cnJpbmcgaW4KICAgICAgICAgKiBhIHN0YXRpYyB2YXIgaW5pdCBjb250ZXh0CiAgICAgICAgICovCiAgICAgICAgcHJpdmF0ZSBNYXA8Q2xhc3NTeW1ib2wsIFN5bWJvbD4gY2xpbml0cyA9IG5ldyBIYXNoTWFwPD4oKTsKCiAgICAgICAgcHJpdmF0ZSBKQ0NsYXNzRGVjbCBhbmFseXplQW5kUHJlcHJvY2Vzc0NsYXNzKEpDQ2xhc3NEZWNsIHRyZWUpIHsKICAgICAgICAgICAgZnJhbWVTdGFjayA9IExpc3QubmlsKCk7CiAgICAgICAgICAgIHR5cGVzVW5kZXJDb25zdHJ1Y3Rpb24gPSBMaXN0Lm5pbCgpOwogICAgICAgICAgICBsb2NhbENsYXNzRGVmcyA9IG5ldyBIYXNoTWFwPD4oKTsKICAgICAgICAgICAgcmV0dXJuIHRyYW5zbGF0ZSh0cmVlKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0QXBwbHkoSkNNZXRob2RJbnZvY2F0aW9uIHRyZWUpIHsKICAgICAgICAgICAgTGlzdDxDbGFzc1N5bWJvbD4gcHJldmlvdXNOYXNjZW50VHlwZXMgPSB0eXBlc1VuZGVyQ29uc3RydWN0aW9uOwogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgTmFtZSBtZXRoTmFtZSA9IFRyZWVJbmZvLm5hbWUodHJlZS5tZXRoKTsKICAgICAgICAgICAgICAgIGlmIChtZXRoTmFtZSA9PSBuYW1lcy5fdGhpcyB8fCBtZXRoTmFtZSA9PSBuYW1lcy5fc3VwZXIpIHsKICAgICAgICAgICAgICAgICAgICB0eXBlc1VuZGVyQ29uc3RydWN0aW9uID0gdHlwZXNVbmRlckNvbnN0cnVjdGlvbi5wcmVwZW5kKGN1cnJlbnRDbGFzcygpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHN1cGVyLnZpc2l0QXBwbHkodHJlZSk7CiAgICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgICAgICB0eXBlc1VuZGVyQ29uc3RydWN0aW9uID0gcHJldmlvdXNOYXNjZW50VHlwZXM7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgICAgIC8vIHdoZXJlCiAgICAgICAgICAgIHByaXZhdGUgQ2xhc3NTeW1ib2wgY3VycmVudENsYXNzKCkgewogICAgICAgICAgICAgICAgZm9yIChGcmFtZSBmcmFtZSA6IGZyYW1lU3RhY2spIHsKICAgICAgICAgICAgICAgICAgICBpZiAoZnJhbWUudHJlZS5oYXNUYWcoSkNUcmVlLlRhZy5DTEFTU0RFRikpIHsKICAgICAgICAgICAgICAgICAgICAgICAgSkNDbGFzc0RlY2wgY2RlZiA9IChKQ0NsYXNzRGVjbCkgZnJhbWUudHJlZTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNkZWYuc3ltOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0QmxvY2soSkNCbG9jayB0cmVlKSB7CiAgICAgICAgICAgIExpc3Q8RnJhbWU+IHByZXZTdGFjayA9IGZyYW1lU3RhY2s7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBpZiAoZnJhbWVTdGFjay5ub25FbXB0eSgpICYmIGZyYW1lU3RhY2suaGVhZC50cmVlLmhhc1RhZyhDTEFTU0RFRikpIHsKICAgICAgICAgICAgICAgICAgICBmcmFtZVN0YWNrID0gZnJhbWVTdGFjay5wcmVwZW5kKG5ldyBGcmFtZSh0cmVlKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBzdXBlci52aXNpdEJsb2NrKHRyZWUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGZpbmFsbHkgewogICAgICAgICAgICAgICAgZnJhbWVTdGFjayA9IHByZXZTdGFjazsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRDbGFzc0RlZihKQ0NsYXNzRGVjbCB0cmVlKSB7CiAgICAgICAgICAgIExpc3Q8RnJhbWU+IHByZXZTdGFjayA9IGZyYW1lU3RhY2s7CiAgICAgICAgICAgIGludCBwcmV2TGFtYmRhQ291bnQgPSBsYW1iZGFDb3VudDsKICAgICAgICAgICAgU3ludGhldGljTWV0aG9kTmFtZUNvdW50ZXIgcHJldlN5bnRoZXRpY01ldGhvZE5hbWVDb3VudHMgPQogICAgICAgICAgICAgICAgICAgIHN5bnRoZXRpY01ldGhvZE5hbWVDb3VudHM7CiAgICAgICAgICAgIE1hcDxDbGFzc1N5bWJvbCwgU3ltYm9sPiBwcmV2Q2xpbml0cyA9IGNsaW5pdHM7CiAgICAgICAgICAgIERpYWdub3N0aWNTb3VyY2UgcHJldlNvdXJjZSA9IGxvZy5jdXJyZW50U291cmNlKCk7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBsb2cudXNlU291cmNlKHRyZWUuc3ltLnNvdXJjZWZpbGUpOwogICAgICAgICAgICAgICAgbGFtYmRhQ291bnQgPSAwOwogICAgICAgICAgICAgICAgc3ludGhldGljTWV0aG9kTmFtZUNvdW50cyA9IG5ldyBTeW50aGV0aWNNZXRob2ROYW1lQ291bnRlcigpOwogICAgICAgICAgICAgICAgcHJldkNsaW5pdHMgPSBuZXcgSGFzaE1hcDw+KCk7CiAgICAgICAgICAgICAgICBpZiAodHJlZS5zeW0ub3duZXIua2luZCA9PSBNVEgpIHsKICAgICAgICAgICAgICAgICAgICBsb2NhbENsYXNzRGVmcy5wdXQodHJlZS5zeW0sIHRyZWUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKGRpcmVjdGx5RW5jbG9zaW5nTGFtYmRhKCkgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIHRyZWUuc3ltLm93bmVyID0gb3duZXIoKTsKICAgICAgICAgICAgICAgICAgICBpZiAodHJlZS5zeW0uaGFzT3V0ZXJJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vaWYgYSBjbGFzcyBpcyBkZWZpbmVkIHdpdGhpbiBhIGxhbWJkYSwgdGhlIGxhbWJkYSBtdXN0IGNhcHR1cmUKICAgICAgICAgICAgICAgICAgICAgICAgLy9pdHMgZW5jbG9zaW5nIGluc3RhbmNlIChpZiBhbnkpCiAgICAgICAgICAgICAgICAgICAgICAgIFRyYW5zbGF0aW9uQ29udGV4dDw/PiBsb2NhbENvbnRleHQgPSBjb250ZXh0KCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIFR5cGVTeW1ib2wgb3V0ZXJJbnN0YW5jZVN5bWJvbCA9IHRyZWUuc3ltLnR5cGUuZ2V0RW5jbG9zaW5nVHlwZSgpLnRzeW07CiAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChsb2NhbENvbnRleHQgIT0gbnVsbCAmJiAhbG9jYWxDb250ZXh0Lm93bmVyLmlzU3RhdGljKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChsb2NhbENvbnRleHQudHJlZS5oYXNUYWcoTEFNQkRBKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEpDVHJlZSBibG9jayA9IGNhcHR1cmVkRGVjbChsb2NhbENvbnRleHQuZGVwdGgsIG91dGVySW5zdGFuY2VTeW1ib2wpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChibG9jayA9PSBudWxsKSBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKExhbWJkYVRyYW5zbGF0aW9uQ29udGV4dClsb2NhbENvbnRleHQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuYWRkU3ltYm9sKG91dGVySW5zdGFuY2VTeW1ib2wsIENBUFRVUkVEX1RISVMpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9jYWxDb250ZXh0ID0gbG9jYWxDb250ZXh0LnByZXY7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBmcmFtZVN0YWNrID0gZnJhbWVTdGFjay5wcmVwZW5kKG5ldyBGcmFtZSh0cmVlKSk7CiAgICAgICAgICAgICAgICBzdXBlci52aXNpdENsYXNzRGVmKHRyZWUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGZpbmFsbHkgewogICAgICAgICAgICAgICAgbG9nLnVzZVNvdXJjZShwcmV2U291cmNlLmdldEZpbGUoKSk7CiAgICAgICAgICAgICAgICBmcmFtZVN0YWNrID0gcHJldlN0YWNrOwogICAgICAgICAgICAgICAgbGFtYmRhQ291bnQgPSBwcmV2TGFtYmRhQ291bnQ7CiAgICAgICAgICAgICAgICBzeW50aGV0aWNNZXRob2ROYW1lQ291bnRzID0gcHJldlN5bnRoZXRpY01ldGhvZE5hbWVDb3VudHM7CiAgICAgICAgICAgICAgICBjbGluaXRzID0gcHJldkNsaW5pdHM7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0SWRlbnQoSkNJZGVudCB0cmVlKSB7CiAgICAgICAgICAgIGlmIChjb250ZXh0KCkgIT0gbnVsbCAmJiBsYW1iZGFJZGVudFN5bWJvbEZpbHRlcih0cmVlLnN5bSkpIHsKICAgICAgICAgICAgICAgIGlmICh0cmVlLnN5bS5raW5kID09IFZBUiAmJgogICAgICAgICAgICAgICAgICAgICAgICB0cmVlLnN5bS5vd25lci5raW5kID09IE1USCAmJgogICAgICAgICAgICAgICAgICAgICAgICB0cmVlLnR5cGUuY29uc3RWYWx1ZSgpID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICBUcmFuc2xhdGlvbkNvbnRleHQ8Pz4gbG9jYWxDb250ZXh0ID0gY29udGV4dCgpOwogICAgICAgICAgICAgICAgICAgIHdoaWxlIChsb2NhbENvbnRleHQgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAobG9jYWxDb250ZXh0LnRyZWUuZ2V0VGFnKCkgPT0gTEFNQkRBKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBKQ1RyZWUgYmxvY2sgPSBjYXB0dXJlZERlY2wobG9jYWxDb250ZXh0LmRlcHRoLCB0cmVlLnN5bSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYmxvY2sgPT0gbnVsbCkgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKExhbWJkYVRyYW5zbGF0aW9uQ29udGV4dClsb2NhbENvbnRleHQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5hZGRTeW1ib2wodHJlZS5zeW0sIENBUFRVUkVEX1ZBUik7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgbG9jYWxDb250ZXh0ID0gbG9jYWxDb250ZXh0LnByZXY7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIGlmICh0cmVlLnN5bS5vd25lci5raW5kID09IFRZUCkgewogICAgICAgICAgICAgICAgICAgIFRyYW5zbGF0aW9uQ29udGV4dDw/PiBsb2NhbENvbnRleHQgPSBjb250ZXh0KCk7CiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGxvY2FsQ29udGV4dCAhPSBudWxsICAmJiAhbG9jYWxDb250ZXh0Lm93bmVyLmlzU3RhdGljKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGxvY2FsQ29udGV4dC50cmVlLmhhc1RhZyhMQU1CREEpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBKQ1RyZWUgYmxvY2sgPSBjYXB0dXJlZERlY2wobG9jYWxDb250ZXh0LmRlcHRoLCB0cmVlLnN5bSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYmxvY2sgPT0gbnVsbCkgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKGJsb2NrLmdldFRhZygpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBDTEFTU0RFRjoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSkNDbGFzc0RlY2wgY2RlY2wgPSAoSkNDbGFzc0RlY2wpYmxvY2s7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoTGFtYmRhVHJhbnNsYXRpb25Db250ZXh0KWxvY2FsQ29udGV4dCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuYWRkU3ltYm9sKGNkZWNsLnN5bSwgQ0FQVFVSRURfVEhJUyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFzc2VydC5lcnJvcigiYmFkIGJsb2NrIGtpbmQiKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBsb2NhbENvbnRleHQgPSBsb2NhbENvbnRleHQucHJldjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc3VwZXIudmlzaXRJZGVudCh0cmVlKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0TGFtYmRhKEpDTGFtYmRhIHRyZWUpIHsKICAgICAgICAgICAgYW5hbHl6ZUxhbWJkYSh0cmVlLCAibGFtYmRhLnN0YXQiKTsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgdm9pZCBhbmFseXplTGFtYmRhKEpDTGFtYmRhIHRyZWUsIEpDRXhwcmVzc2lvbiBtZXRob2RSZWZlcmVuY2VSZWNlaXZlcikgewogICAgICAgICAgICAvLyBUcmFuc2xhdGlvbiBvZiB0aGUgcmVjZWl2ZXIgZXhwcmVzc2lvbiBtdXN0IG9jY3VyIGZpcnN0CiAgICAgICAgICAgIEpDRXhwcmVzc2lvbiByY3ZyID0gdHJhbnNsYXRlKG1ldGhvZFJlZmVyZW5jZVJlY2VpdmVyKTsKICAgICAgICAgICAgTGFtYmRhVHJhbnNsYXRpb25Db250ZXh0IGNvbnRleHQgPSBhbmFseXplTGFtYmRhKHRyZWUsICJtcmVmLnN0YXQuMSIpOwogICAgICAgICAgICBpZiAocmN2ciAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICBjb250ZXh0Lm1ldGhvZFJlZmVyZW5jZVJlY2VpdmVyID0gcmN2cjsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBMYW1iZGFUcmFuc2xhdGlvbkNvbnRleHQgYW5hbHl6ZUxhbWJkYShKQ0xhbWJkYSB0cmVlLCBTdHJpbmcgc3RhdEtleSkgewogICAgICAgICAgICBMaXN0PEZyYW1lPiBwcmV2U3RhY2sgPSBmcmFtZVN0YWNrOwogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgTGFtYmRhVHJhbnNsYXRpb25Db250ZXh0IGNvbnRleHQgPSBuZXcgTGFtYmRhVHJhbnNsYXRpb25Db250ZXh0KHRyZWUpOwogICAgICAgICAgICAgICAgZnJhbWVTdGFjayA9IGZyYW1lU3RhY2sucHJlcGVuZChuZXcgRnJhbWUodHJlZSkpOwogICAgICAgICAgICAgICAgZm9yIChKQ1ZhcmlhYmxlRGVjbCBwYXJhbSA6IHRyZWUucGFyYW1zKSB7CiAgICAgICAgICAgICAgICAgICAgY29udGV4dC5hZGRTeW1ib2wocGFyYW0uc3ltLCBQQVJBTSk7CiAgICAgICAgICAgICAgICAgICAgZnJhbWVTdGFjay5oZWFkLmFkZExvY2FsKHBhcmFtLnN5bSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBjb250ZXh0TWFwLnB1dCh0cmVlLCBjb250ZXh0KTsKICAgICAgICAgICAgICAgIHN1cGVyLnZpc2l0TGFtYmRhKHRyZWUpOwogICAgICAgICAgICAgICAgY29udGV4dC5jb21wbGV0ZSgpOwogICAgICAgICAgICAgICAgaWYgKGR1bXBMYW1iZGFUb01ldGhvZFN0YXRzKSB7CiAgICAgICAgICAgICAgICAgICAgbG9nLm5vdGUodHJlZSwgc3RhdEtleSwgY29udGV4dC5uZWVkc0FsdE1ldGFmYWN0b3J5KCksIGNvbnRleHQudHJhbnNsYXRlZFN5bSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gY29udGV4dDsKICAgICAgICAgICAgfQogICAgICAgICAgICBmaW5hbGx5IHsKICAgICAgICAgICAgICAgIGZyYW1lU3RhY2sgPSBwcmV2U3RhY2s7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0TWV0aG9kRGVmKEpDTWV0aG9kRGVjbCB0cmVlKSB7CiAgICAgICAgICAgIExpc3Q8RnJhbWU+IHByZXZTdGFjayA9IGZyYW1lU3RhY2s7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBmcmFtZVN0YWNrID0gZnJhbWVTdGFjay5wcmVwZW5kKG5ldyBGcmFtZSh0cmVlKSk7CiAgICAgICAgICAgICAgICBzdXBlci52aXNpdE1ldGhvZERlZih0cmVlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBmaW5hbGx5IHsKICAgICAgICAgICAgICAgIGZyYW1lU3RhY2sgPSBwcmV2U3RhY2s7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0TmV3Q2xhc3MoSkNOZXdDbGFzcyB0cmVlKSB7CiAgICAgICAgICAgIFR5cGVTeW1ib2wgZGVmID0gdHJlZS50eXBlLnRzeW07CiAgICAgICAgICAgIGJvb2xlYW4gaW5SZWZlcmVuY2VkQ2xhc3MgPSBjdXJyZW50bHlJbkNsYXNzKGRlZik7CiAgICAgICAgICAgIGJvb2xlYW4gaXNMb2NhbCA9IGRlZi5pc0xvY2FsKCk7CiAgICAgICAgICAgIGlmICgoaW5SZWZlcmVuY2VkQ2xhc3MgJiYgaXNMb2NhbCB8fCBsYW1iZGFOZXdDbGFzc0ZpbHRlcihjb250ZXh0KCksIHRyZWUpKSkgewogICAgICAgICAgICAgICAgVHJhbnNsYXRpb25Db250ZXh0PD8+IGxvY2FsQ29udGV4dCA9IGNvbnRleHQoKTsKICAgICAgICAgICAgICAgIGZpbmFsIFR5cGVTeW1ib2wgb3V0ZXJJbnN0YW5jZVN5bWJvbCA9IHRyZWUudHlwZS5nZXRFbmNsb3NpbmdUeXBlKCkudHN5bTsKICAgICAgICAgICAgICAgIHdoaWxlIChsb2NhbENvbnRleHQgIT0gbnVsbCAgJiYgIWxvY2FsQ29udGV4dC5vd25lci5pc1N0YXRpYygpKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGxvY2FsQ29udGV4dC50cmVlLmhhc1RhZyhMQU1CREEpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvdXRlckluc3RhbmNlU3ltYm9sICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEpDVHJlZSBibG9jayA9IGNhcHR1cmVkRGVjbChsb2NhbENvbnRleHQuZGVwdGgsIG91dGVySW5zdGFuY2VTeW1ib2wpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGJsb2NrID09IG51bGwpIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICgoTGFtYmRhVHJhbnNsYXRpb25Db250ZXh0KWxvY2FsQ29udGV4dCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuYWRkU3ltYm9sKG91dGVySW5zdGFuY2VTeW1ib2wsIENBUFRVUkVEX1RISVMpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBsb2NhbENvbnRleHQgPSBsb2NhbENvbnRleHQucHJldjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoY29udGV4dCgpICE9IG51bGwgJiYgIWluUmVmZXJlbmNlZENsYXNzICYmIGlzTG9jYWwpIHsKICAgICAgICAgICAgICAgIExhbWJkYVRyYW5zbGF0aW9uQ29udGV4dCBsYW1iZGFDb250ZXh0ID0gKExhbWJkYVRyYW5zbGF0aW9uQ29udGV4dCljb250ZXh0KCk7CiAgICAgICAgICAgICAgICBjYXB0dXJlTG9jYWxDbGFzc0RlZnMoZGVmLCBsYW1iZGFDb250ZXh0KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBzdXBlci52aXNpdE5ld0NsYXNzKHRyZWUpOwogICAgICAgIH0KICAgICAgICAvL3doZXJlCiAgICAgICAgICAgIHZvaWQgY2FwdHVyZUxvY2FsQ2xhc3NEZWZzKFN5bWJvbCBjc3ltLCBmaW5hbCBMYW1iZGFUcmFuc2xhdGlvbkNvbnRleHQgbGFtYmRhQ29udGV4dCkgewogICAgICAgICAgICAgICAgSkNDbGFzc0RlY2wgbG9jYWxDRGVmID0gbG9jYWxDbGFzc0RlZnMuZ2V0KGNzeW0pOwogICAgICAgICAgICAgICAgaWYgKGxvY2FsQ0RlZiAhPSBudWxsICYmIGxhbWJkYUNvbnRleHQuZnJlZVZhclByb2Nlc3NlZExvY2FsQ2xhc3Nlcy5hZGQoY3N5bSkpIHsKICAgICAgICAgICAgICAgICAgICBCYXNpY0ZyZWVWYXJDb2xsZWN0b3IgZnZjID0gbG93ZXIubmV3IEJhc2ljRnJlZVZhckNvbGxlY3RvcigpIHsKICAgICAgICAgICAgICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgYWRkRnJlZVZhcnMoQ2xhc3NTeW1ib2wgYykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FwdHVyZUxvY2FsQ2xhc3NEZWZzKGMsIGxhbWJkYUNvbnRleHQpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICAgICAgICAgICAgICB2b2lkIHZpc2l0U3ltYm9sKFN5bWJvbCBzeW0pIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzeW0ua2luZCA9PSBWQVIgJiYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ltLm93bmVyLmtpbmQgPT0gTVRIICYmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoVmFyU3ltYm9sKXN5bSkuZ2V0Q29uc3RWYWx1ZSgpID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUcmFuc2xhdGlvbkNvbnRleHQ8Pz4gbG9jYWxDb250ZXh0ID0gY29udGV4dCgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChsb2NhbENvbnRleHQgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobG9jYWxDb250ZXh0LnRyZWUuZ2V0VGFnKCkgPT0gTEFNQkRBKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBKQ1RyZWUgYmxvY2sgPSBjYXB0dXJlZERlY2wobG9jYWxDb250ZXh0LmRlcHRoLCBzeW0pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGJsb2NrID09IG51bGwpIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKChMYW1iZGFUcmFuc2xhdGlvbkNvbnRleHQpbG9jYWxDb250ZXh0KS5hZGRTeW1ib2woc3ltLCBDQVBUVVJFRF9WQVIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvY2FsQ29udGV4dCA9IGxvY2FsQ29udGV4dC5wcmV2OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICAgICAgZnZjLnNjYW4obG9jYWxDRGVmKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLy93aGVyZQogICAgICAgIGJvb2xlYW4gY3VycmVudGx5SW5DbGFzcyhTeW1ib2wgY3N5bSkgewogICAgICAgICAgICBmb3IgKEZyYW1lIGZyYW1lIDogZnJhbWVTdGFjaykgewogICAgICAgICAgICAgICAgaWYgKGZyYW1lLnRyZWUuaGFzVGFnKEpDVHJlZS5UYWcuQ0xBU1NERUYpKSB7CiAgICAgICAgICAgICAgICAgICAgSkNDbGFzc0RlY2wgY2RlZiA9IChKQ0NsYXNzRGVjbCkgZnJhbWUudHJlZTsKICAgICAgICAgICAgICAgICAgICBpZiAoY2RlZi5zeW0gPT0gY3N5bSkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogTWV0aG9kIHJlZmVyZW5jZXMgdG8gbG9jYWwgY2xhc3MgY29uc3RydWN0b3JzLCBtYXksIGlmIHRoZSBsb2NhbAogICAgICAgICAqIGNsYXNzIHJlZmVyZW5jZXMgbG9jYWwgdmFyaWFibGVzLCBoYXZlIGltcGxpY2l0IGNvbnN0cnVjdG9yCiAgICAgICAgICogcGFyYW1ldGVycyBhZGRlZCBpbiBMb3dlcjsgQXMgYSByZXN1bHQsIHRoZSBpbnZva2VkeW5hbWljIGJvb3RzdHJhcAogICAgICAgICAqIGluZm9ybWF0aW9uIGFkZGVkIGluIHRoZSBMYW1iZGFUb01ldGhvZCBwYXNzIHdpbGwgaGF2ZSB0aGUgd3JvbmcKICAgICAgICAgKiBzaWduYXR1cmUuIEhvb2tzIGJldHdlZW4gTG93ZXIgYW5kIExhbWJkYVRvTWV0aG9kIGhhdmUgYmVlbiBhZGRlZCB0bwogICAgICAgICAqIGhhbmRsZSBub3JtYWwgIm5ldyIgaW4gdGhpcyBjYXNlLiBUaGlzIHZpc2l0b3IgY29udmVydHMgcG90ZW50aWFsbHkKICAgICAgICAgKiBhZmZlY3RlZCBtZXRob2QgcmVmZXJlbmNlcyBpbnRvIGEgbGFtYmRhIGNvbnRhaW5pbmcgYSBub3JtYWwKICAgICAgICAgKiBleHByZXNzaW9uLgogICAgICAgICAqCiAgICAgICAgICogQHBhcmFtIHRyZWUKICAgICAgICAgKi8KICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdFJlZmVyZW5jZShKQ01lbWJlclJlZmVyZW5jZSB0cmVlKSB7CiAgICAgICAgICAgIFJlZmVyZW5jZVRyYW5zbGF0aW9uQ29udGV4dCByY29udGV4dCA9IG5ldyBSZWZlcmVuY2VUcmFuc2xhdGlvbkNvbnRleHQodHJlZSk7CiAgICAgICAgICAgIGNvbnRleHRNYXAucHV0KHRyZWUsIHJjb250ZXh0KTsKICAgICAgICAgICAgaWYgKHJjb250ZXh0Lm5lZWRzQ29udmVyc2lvblRvTGFtYmRhKCkpIHsKICAgICAgICAgICAgICAgICAvLyBDb252ZXJ0IHRvIGEgbGFtYmRhLCBhbmQgcHJvY2VzcyBhcyBzdWNoCiAgICAgICAgICAgICAgICBNZW1iZXJSZWZlcmVuY2VUb0xhbWJkYSBjb252ID0gbmV3IE1lbWJlclJlZmVyZW5jZVRvTGFtYmRhKHRyZWUsIHJjb250ZXh0LCBvd25lcigpKTsKICAgICAgICAgICAgICAgIGFuYWx5emVMYW1iZGEoY29udi5sYW1iZGEoKSwgY29udi5nZXRSZWNlaXZlckV4cHJlc3Npb24oKSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBzdXBlci52aXNpdFJlZmVyZW5jZSh0cmVlKTsKICAgICAgICAgICAgICAgIGlmIChkdW1wTGFtYmRhVG9NZXRob2RTdGF0cykgewogICAgICAgICAgICAgICAgICAgIGxvZy5ub3RlKHRyZWUsICJtcmVmLnN0YXQiLCByY29udGV4dC5uZWVkc0FsdE1ldGFmYWN0b3J5KCksIG51bGwpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdFNlbGVjdChKQ0ZpZWxkQWNjZXNzIHRyZWUpIHsKICAgICAgICAgICAgaWYgKGNvbnRleHQoKSAhPSBudWxsICYmIHRyZWUuc3ltLmtpbmQgPT0gVkFSICYmCiAgICAgICAgICAgICAgICAgICAgICAgICh0cmVlLnN5bS5uYW1lID09IG5hbWVzLl90aGlzIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICB0cmVlLnN5bS5uYW1lID09IG5hbWVzLl9zdXBlcikpIHsKICAgICAgICAgICAgICAgIC8vIEEgc2VsZWN0IG9mIHRoaXMgb3Igc3VwZXIgbWVhbnMsIGlmIHdlIGFyZSBpbiBhIGxhbWJkYSwKICAgICAgICAgICAgICAgIC8vIHdlIG11Y2ggaGF2ZSBhbiBpbnN0YW5jZSBjb250ZXh0CiAgICAgICAgICAgICAgICBUcmFuc2xhdGlvbkNvbnRleHQ8Pz4gbG9jYWxDb250ZXh0ID0gY29udGV4dCgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGxvY2FsQ29udGV4dCAhPSBudWxsICAmJiAhbG9jYWxDb250ZXh0Lm93bmVyLmlzU3RhdGljKCkpIHsKICAgICAgICAgICAgICAgICAgICBpZiAobG9jYWxDb250ZXh0LnRyZWUuaGFzVGFnKExBTUJEQSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgSkNDbGFzc0RlY2wgY2xhenogPSAoSkNDbGFzc0RlY2wpY2FwdHVyZWREZWNsKGxvY2FsQ29udGV4dC5kZXB0aCwgdHJlZS5zeW0pOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoY2xhenogPT0gbnVsbCkgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgICgoTGFtYmRhVHJhbnNsYXRpb25Db250ZXh0KWxvY2FsQ29udGV4dCkuYWRkU3ltYm9sKGNsYXp6LnN5bSwgQ0FQVFVSRURfVEhJUyk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGxvY2FsQ29udGV4dCA9IGxvY2FsQ29udGV4dC5wcmV2OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHN1cGVyLnZpc2l0U2VsZWN0KHRyZWUpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRWYXJEZWYoSkNWYXJpYWJsZURlY2wgdHJlZSkgewogICAgICAgICAgICBUcmFuc2xhdGlvbkNvbnRleHQ8Pz4gY29udGV4dCA9IGNvbnRleHQoKTsKICAgICAgICAgICAgTGFtYmRhVHJhbnNsYXRpb25Db250ZXh0IGx0YyA9IChjb250ZXh0ICE9IG51bGwgJiYgY29udGV4dCBpbnN0YW5jZW9mIExhbWJkYVRyYW5zbGF0aW9uQ29udGV4dCk/CiAgICAgICAgICAgICAgICAgICAgKExhbWJkYVRyYW5zbGF0aW9uQ29udGV4dCljb250ZXh0IDoKICAgICAgICAgICAgICAgICAgICBudWxsOwogICAgICAgICAgICBpZiAobHRjICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIGlmIChmcmFtZVN0YWNrLmhlYWQudHJlZS5oYXNUYWcoTEFNQkRBKSkgewogICAgICAgICAgICAgICAgICAgIGx0Yy5hZGRTeW1ib2wodHJlZS5zeW0sIExPQ0FMX1ZBUik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvLyBDaGVjayBmb3IgdHlwZSB2YXJpYWJsZXMgKGluY2x1ZGluZyBhcyB0eXBlIGFyZ3VtZW50cykuCiAgICAgICAgICAgICAgICAvLyBJZiB0aGV5IG9jY3VyIHdpdGhpbiBjbGFzcyBuZXN0ZWQgaW4gYSBsYW1iZGEsIG1hcmsgZm9yIGVyYXN1cmUKICAgICAgICAgICAgICAgIFR5cGUgdHlwZSA9IHRyZWUuc3ltLmFzVHlwZSgpOwogICAgICAgICAgICAgICAgaWYgKGluQ2xhc3NXaXRoaW5MYW1iZGEoKSAmJiAhdHlwZXMuaXNTYW1lVHlwZSh0eXBlcy5lcmFzdXJlKHR5cGUpLCB0eXBlKSkgewogICAgICAgICAgICAgICAgICAgIGx0Yy5hZGRTeW1ib2wodHJlZS5zeW0sIFRZUEVfVkFSKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgTGlzdDxGcmFtZT4gcHJldlN0YWNrID0gZnJhbWVTdGFjazsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIGlmICh0cmVlLnN5bS5vd25lci5raW5kID09IE1USCkgewogICAgICAgICAgICAgICAgICAgIGZyYW1lU3RhY2suaGVhZC5hZGRMb2NhbCh0cmVlLnN5bSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBmcmFtZVN0YWNrID0gZnJhbWVTdGFjay5wcmVwZW5kKG5ldyBGcmFtZSh0cmVlKSk7CiAgICAgICAgICAgICAgICBzdXBlci52aXNpdFZhckRlZih0cmVlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBmaW5hbGx5IHsKICAgICAgICAgICAgICAgIGZyYW1lU3RhY2sgPSBwcmV2U3RhY2s7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIFJldHVybiBhIHZhbGlkIG93bmVyIGdpdmVuIHRoZSBjdXJyZW50IGRlY2xhcmF0aW9uIHN0YWNrCiAgICAgICAgICogKHJlcXVpcmVkIHRvIHNraXAgc3ludGhldGljIGxhbWJkYSBzeW1ib2xzKQogICAgICAgICAqLwogICAgICAgIHByaXZhdGUgU3ltYm9sIG93bmVyKCkgewogICAgICAgICAgICByZXR1cm4gb3duZXIoZmFsc2UpOwogICAgICAgIH0KCiAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoImZhbGx0aHJvdWdoIikKICAgICAgICBwcml2YXRlIFN5bWJvbCBvd25lcihib29sZWFuIHNraXBMYW1iZGEpIHsKICAgICAgICAgICAgTGlzdDxGcmFtZT4gZnJhbWVTdGFjazIgPSBmcmFtZVN0YWNrOwogICAgICAgICAgICB3aGlsZSAoZnJhbWVTdGFjazIubm9uRW1wdHkoKSkgewogICAgICAgICAgICAgICAgc3dpdGNoIChmcmFtZVN0YWNrMi5oZWFkLnRyZWUuZ2V0VGFnKCkpIHsKICAgICAgICAgICAgICAgICAgICBjYXNlIFZBUkRFRjoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCgoSkNWYXJpYWJsZURlY2wpZnJhbWVTdGFjazIuaGVhZC50cmVlKS5zeW0uaXNMb2NhbCgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcmFtZVN0YWNrMiA9IGZyYW1lU3RhY2syLnRhaWw7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBKQ0NsYXNzRGVjbCBjZGVjbCA9IChKQ0NsYXNzRGVjbClmcmFtZVN0YWNrMi50YWlsLmhlYWQudHJlZTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGluaXRTeW0oY2RlY2wuc3ltLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoSkNWYXJpYWJsZURlY2wpZnJhbWVTdGFjazIuaGVhZC50cmVlKS5zeW0uZmxhZ3MoKSAmIFNUQVRJQyk7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBCTE9DSzoKICAgICAgICAgICAgICAgICAgICAgICAgSkNDbGFzc0RlY2wgY2RlY2wyID0gKEpDQ2xhc3NEZWNsKWZyYW1lU3RhY2syLnRhaWwuaGVhZC50cmVlOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaW5pdFN5bShjZGVjbDIuc3ltLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoSkNCbG9jaylmcmFtZVN0YWNrMi5oZWFkLnRyZWUpLmZsYWdzICYgU1RBVElDKTsKICAgICAgICAgICAgICAgICAgICBjYXNlIENMQVNTREVGOgogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKChKQ0NsYXNzRGVjbClmcmFtZVN0YWNrMi5oZWFkLnRyZWUpLnN5bTsKICAgICAgICAgICAgICAgICAgICBjYXNlIE1FVEhPRERFRjoKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICgoSkNNZXRob2REZWNsKWZyYW1lU3RhY2syLmhlYWQudHJlZSkuc3ltOwogICAgICAgICAgICAgICAgICAgIGNhc2UgTEFNQkRBOgogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXNraXBMYW1iZGEpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKChMYW1iZGFUcmFuc2xhdGlvbkNvbnRleHQpY29udGV4dE1hcAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZ2V0KGZyYW1lU3RhY2syLmhlYWQudHJlZSkpLnRyYW5zbGF0ZWRTeW07CiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgICAgZnJhbWVTdGFjazIgPSBmcmFtZVN0YWNrMi50YWlsOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIEFzc2VydC5lcnJvcigpOwogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgU3ltYm9sIGluaXRTeW0oQ2xhc3NTeW1ib2wgY3N5bSwgbG9uZyBmbGFncykgewogICAgICAgICAgICBib29sZWFuIGlzU3RhdGljID0gKGZsYWdzICYgU1RBVElDKSAhPSAwOwogICAgICAgICAgICBpZiAoaXNTdGF0aWMpIHsKICAgICAgICAgICAgICAgIC8qIHN0YXRpYyBjbGluaXRzIGFyZSBnZW5lcmF0ZWQgaW4gR2VuLCBzbyB3ZSBuZWVkIHRvIHVzZSBhIGZha2UKICAgICAgICAgICAgICAgICAqIG9uZS4gQXR0ciBjcmVhdGVzIGEgZmFrZSBjbGluaXQgbWV0aG9kIHdoaWxlIGF0dHJpYnV0aW5nCiAgICAgICAgICAgICAgICAgKiBsYW1iZGEgZXhwcmVzc2lvbnMgdXNlZCBhcyBpbml0aWFsaXplcnMgb2Ygc3RhdGljIGZpZWxkcywgc28KICAgICAgICAgICAgICAgICAqIGxldCdzIHVzZSB0aGF0IG9uZS4KICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgTWV0aG9kU3ltYm9sIGNsaW5pdCA9IGF0dHIucmVtb3ZlQ2xpbml0KGNzeW0pOwogICAgICAgICAgICAgICAgaWYgKGNsaW5pdCAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgY2xpbml0cy5wdXQoY3N5bSwgY2xpbml0KTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gY2xpbml0OwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8qIGlmIG5vIGNsaW5pdCBpcyBmb3VuZCBhdCBBdHRyLCB0aGVuIGxldCdzIHRyeSBhdCBjbGluaXRzLgogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBjbGluaXQgPSAoTWV0aG9kU3ltYm9sKWNsaW5pdHMuZ2V0KGNzeW0pOwogICAgICAgICAgICAgICAgaWYgKGNsaW5pdCA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgLyogbm8gbHVjaywgbGV0J3MgY3JlYXRlIGEgbmV3IG9uZQogICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgIGNsaW5pdCA9IG1ha2VQcml2YXRlU3ludGhldGljTWV0aG9kKFNUQVRJQywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVzLmNsaW5pdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBNZXRob2RUeXBlKExpc3QubmlsKCksIHN5bXMudm9pZFR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTGlzdC5uaWwoKSwgc3ltcy5tZXRob2RDbGFzcyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjc3ltKTsKICAgICAgICAgICAgICAgICAgICBjbGluaXRzLnB1dChjc3ltLCBjbGluaXQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIGNsaW5pdDsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIC8vZ2V0IHRoZSBmaXJzdCBjb25zdHJ1Y3RvciBhbmQgdHJlYXQgaXQgYXMgdGhlIGluc3RhbmNlIGluaXQgc3ltCiAgICAgICAgICAgICAgICBmb3IgKFN5bWJvbCBzIDogY3N5bS5tZW1iZXJzX2ZpZWxkLmdldFN5bWJvbHNCeU5hbWUobmFtZXMuaW5pdCkpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gczsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBBc3NlcnQuZXJyb3IoImluaXQgbm90IGZvdW5kIik7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBKQ1RyZWUgZGlyZWN0bHlFbmNsb3NpbmdMYW1iZGEoKSB7CiAgICAgICAgICAgIGlmIChmcmFtZVN0YWNrLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgTGlzdDxGcmFtZT4gZnJhbWVTdGFjazIgPSBmcmFtZVN0YWNrOwogICAgICAgICAgICB3aGlsZSAoZnJhbWVTdGFjazIubm9uRW1wdHkoKSkgewogICAgICAgICAgICAgICAgc3dpdGNoIChmcmFtZVN0YWNrMi5oZWFkLnRyZWUuZ2V0VGFnKCkpIHsKICAgICAgICAgICAgICAgICAgICBjYXNlIENMQVNTREVGOgogICAgICAgICAgICAgICAgICAgIGNhc2UgTUVUSE9EREVGOgogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgICAgICBjYXNlIExBTUJEQToKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZyYW1lU3RhY2syLmhlYWQudHJlZTsKICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgICAgICBmcmFtZVN0YWNrMiA9IGZyYW1lU3RhY2syLnRhaWw7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgQXNzZXJ0LmVycm9yKCk7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBib29sZWFuIGluQ2xhc3NXaXRoaW5MYW1iZGEoKSB7CiAgICAgICAgICAgIGlmIChmcmFtZVN0YWNrLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIExpc3Q8RnJhbWU+IGZyYW1lU3RhY2syID0gZnJhbWVTdGFjazsKICAgICAgICAgICAgYm9vbGVhbiBjbGFzc0ZvdW5kID0gZmFsc2U7CiAgICAgICAgICAgIHdoaWxlIChmcmFtZVN0YWNrMi5ub25FbXB0eSgpKSB7CiAgICAgICAgICAgICAgICBzd2l0Y2ggKGZyYW1lU3RhY2syLmhlYWQudHJlZS5nZXRUYWcoKSkgewogICAgICAgICAgICAgICAgICAgIGNhc2UgTEFNQkRBOgogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gY2xhc3NGb3VuZDsKICAgICAgICAgICAgICAgICAgICBjYXNlIENMQVNTREVGOgogICAgICAgICAgICAgICAgICAgICAgICBjbGFzc0ZvdW5kID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgZnJhbWVTdGFjazIgPSBmcmFtZVN0YWNrMi50YWlsOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgICAgICBmcmFtZVN0YWNrMiA9IGZyYW1lU3RhY2syLnRhaWw7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gTm8gbGFtYmRhCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIFJldHVybiB0aGUgZGVjbGFyYXRpb24gY29ycmVzcG9uZGluZyB0byBhIHN5bWJvbCBpbiB0aGUgZW5jbG9zaW5nCiAgICAgICAgICogc2NvcGU7IHRoZSBkZXB0aCBwYXJhbWV0ZXIgaXMgdXNlZCB0byBmaWx0ZXIgb3V0IHN5bWJvbHMgZGVmaW5lZAogICAgICAgICAqIGluIG5lc3RlZCBzY29wZXMgKHdoaWNoIGRvIG5vdCBuZWVkIHRvIHVuZGVyZ28gY2FwdHVyZSkuCiAgICAgICAgICovCiAgICAgICAgcHJpdmF0ZSBKQ1RyZWUgY2FwdHVyZWREZWNsKGludCBkZXB0aCwgU3ltYm9sIHN5bSkgewogICAgICAgICAgICBpbnQgY3VycmVudERlcHRoID0gZnJhbWVTdGFjay5zaXplKCkgLSAxOwogICAgICAgICAgICBmb3IgKEZyYW1lIGJsb2NrIDogZnJhbWVTdGFjaykgewogICAgICAgICAgICAgICAgc3dpdGNoIChibG9jay50cmVlLmdldFRhZygpKSB7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBDTEFTU0RFRjoKICAgICAgICAgICAgICAgICAgICAgICAgQ2xhc3NTeW1ib2wgY2xhenogPSAoKEpDQ2xhc3NEZWNsKWJsb2NrLnRyZWUpLnN5bTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNsYXp6LmlzU3ViQ2xhc3Moc3ltLCB0eXBlcykgfHwgc3ltLmlzTWVtYmVyT2YoY2xhenosIHR5cGVzKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGN1cnJlbnREZXB0aCA+IGRlcHRoID8gbnVsbCA6IGJsb2NrLnRyZWU7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBWQVJERUY6CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgoKEpDVmFyaWFibGVEZWNsKWJsb2NrLnRyZWUpLnN5bSA9PSBzeW0gJiYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeW0ub3duZXIua2luZCA9PSBNVEgpIHsgLy9vbmx5IGxvY2FscyBhcmUgY2FwdHVyZWQKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjdXJyZW50RGVwdGggPiBkZXB0aCA/IG51bGwgOiBibG9jay50cmVlOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgQkxPQ0s6CiAgICAgICAgICAgICAgICAgICAgY2FzZSBNRVRIT0RERUY6CiAgICAgICAgICAgICAgICAgICAgY2FzZSBMQU1CREE6CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChibG9jay5sb2NhbHMgIT0gbnVsbCAmJiBibG9jay5sb2NhbHMuY29udGFpbnMoc3ltKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGN1cnJlbnREZXB0aCA+IGRlcHRoID8gbnVsbCA6IGJsb2NrLnRyZWU7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgICAgQXNzZXJ0LmVycm9yKCJiYWQgZGVjbCBraW5kICIgKyBibG9jay50cmVlLmdldFRhZygpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGN1cnJlbnREZXB0aC0tOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBUcmFuc2xhdGlvbkNvbnRleHQ8Pz4gY29udGV4dCgpIHsKICAgICAgICAgICAgZm9yIChGcmFtZSBmcmFtZSA6IGZyYW1lU3RhY2spIHsKICAgICAgICAgICAgICAgIFRyYW5zbGF0aW9uQ29udGV4dDw/PiBjb250ZXh0ID0gY29udGV4dE1hcC5nZXQoZnJhbWUudHJlZSk7CiAgICAgICAgICAgICAgICBpZiAoY29udGV4dCAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNvbnRleHQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiAgVGhpcyBpcyB1c2VkIHRvIGZpbHRlciBvdXQgdGhvc2UgaWRlbnRpZmllcnMgdGhhdCBuZWVkcyB0byBiZSBhZGp1c3RlZAogICAgICAgICAqICB3aGVuIHRyYW5zbGF0aW5nIGF3YXkgbGFtYmRhIGV4cHJlc3Npb25zCiAgICAgICAgICovCiAgICAgICAgcHJpdmF0ZSBib29sZWFuIGxhbWJkYUlkZW50U3ltYm9sRmlsdGVyKFN5bWJvbCBzeW0pIHsKICAgICAgICAgICAgcmV0dXJuIChzeW0ua2luZCA9PSBWQVIgfHwgc3ltLmtpbmQgPT0gTVRIKQogICAgICAgICAgICAgICAgICAgICYmICFzeW0uaXNTdGF0aWMoKQogICAgICAgICAgICAgICAgICAgICYmIHN5bS5uYW1lICE9IG5hbWVzLmluaXQ7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiAgVGhpcyBpcyB1c2VkIHRvIGZpbHRlciBvdXQgdGhvc2Ugc2VsZWN0IG5vZGVzIHRoYXQgbmVlZCB0byBiZSBhZGp1c3RlZAogICAgICAgICAqICB3aGVuIHRyYW5zbGF0aW5nIGF3YXkgbGFtYmRhIGV4cHJlc3Npb25zIC0gYXQgdGhlIG1vbWVudCwgdGhpcyBpcyB0aGUKICAgICAgICAgKiAgc2V0IG9mIG5vZGVzIHRoYXQgc2VsZWN0IGB0aGlzJyAocXVhbGlmaWVkIHRoaXMpCiAgICAgICAgICovCiAgICAgICAgcHJpdmF0ZSBib29sZWFuIGxhbWJkYUZpZWxkQWNjZXNzRmlsdGVyKEpDRmllbGRBY2Nlc3MgZkFjY2VzcykgewogICAgICAgICAgICBMYW1iZGFUcmFuc2xhdGlvbkNvbnRleHQgbGFtYmRhQ29udGV4dCA9CiAgICAgICAgICAgICAgICAgICAgY29udGV4dCBpbnN0YW5jZW9mIExhbWJkYVRyYW5zbGF0aW9uQ29udGV4dCA/CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoTGFtYmRhVHJhbnNsYXRpb25Db250ZXh0KSBjb250ZXh0IDogbnVsbDsKICAgICAgICAgICAgcmV0dXJuIGxhbWJkYUNvbnRleHQgIT0gbnVsbAogICAgICAgICAgICAgICAgICAgICYmICFmQWNjZXNzLnN5bS5pc1N0YXRpYygpCiAgICAgICAgICAgICAgICAgICAgJiYgZkFjY2Vzcy5uYW1lID09IG5hbWVzLl90aGlzCiAgICAgICAgICAgICAgICAgICAgJiYgKGZBY2Nlc3Muc3ltLm93bmVyLmtpbmQgPT0gVFlQKQogICAgICAgICAgICAgICAgICAgICYmICFsYW1iZGFDb250ZXh0LnRyYW5zbGF0ZWRTeW1ib2xzLmdldChDQVBUVVJFRF9PVVRFUl9USElTKS5pc0VtcHR5KCk7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBUaGlzIGlzIHVzZWQgdG8gZmlsdGVyIG91dCB0aG9zZSBuZXcgY2xhc3MgZXhwcmVzc2lvbnMgdGhhdCBuZWVkIHRvCiAgICAgICAgICogYmUgcXVhbGlmaWVkIHdpdGggYW4gZW5jbG9zaW5nIHRyZWUKICAgICAgICAgKi8KICAgICAgICBwcml2YXRlIGJvb2xlYW4gbGFtYmRhTmV3Q2xhc3NGaWx0ZXIoVHJhbnNsYXRpb25Db250ZXh0PD8+IGNvbnRleHQsIEpDTmV3Q2xhc3MgdHJlZSkgewogICAgICAgICAgICBpZiAoY29udGV4dCAhPSBudWxsCiAgICAgICAgICAgICAgICAgICAgJiYgdHJlZS5lbmNsID09IG51bGwKICAgICAgICAgICAgICAgICAgICAmJiB0cmVlLmRlZiA9PSBudWxsCiAgICAgICAgICAgICAgICAgICAgJiYgIXRyZWUudHlwZS5nZXRFbmNsb3NpbmdUeXBlKCkuaGFzVGFnKE5PTkUpKSB7CiAgICAgICAgICAgICAgICBUeXBlIGVuY2wgPSB0cmVlLnR5cGUuZ2V0RW5jbG9zaW5nVHlwZSgpOwogICAgICAgICAgICAgICAgVHlwZSBjdXJyZW50ID0gY29udGV4dC5vd25lci5lbmNsQ2xhc3MoKS50eXBlOwogICAgICAgICAgICAgICAgd2hpbGUgKCFjdXJyZW50Lmhhc1RhZyhOT05FKSkgewogICAgICAgICAgICAgICAgICAgIGlmIChjdXJyZW50LnRzeW0uaXNTdWJDbGFzcyhlbmNsLnRzeW0sIHR5cGVzKSkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgY3VycmVudCA9IGN1cnJlbnQuZ2V0RW5jbG9zaW5nVHlwZSgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIGNsYXNzIEZyYW1lIHsKICAgICAgICAgICAgZmluYWwgSkNUcmVlIHRyZWU7CiAgICAgICAgICAgIExpc3Q8U3ltYm9sPiBsb2NhbHM7CgogICAgICAgICAgICBwdWJsaWMgRnJhbWUoSkNUcmVlIHRyZWUpIHsKICAgICAgICAgICAgICAgIHRoaXMudHJlZSA9IHRyZWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHZvaWQgYWRkTG9jYWwoU3ltYm9sIHN5bSkgewogICAgICAgICAgICAgICAgaWYgKGxvY2FscyA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgbG9jYWxzID0gTGlzdC5uaWwoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGxvY2FscyA9IGxvY2Fscy5wcmVwZW5kKHN5bSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIFRoaXMgY2xhc3MgaXMgdXNlZCB0byBzdG9yZSBpbXBvcnRhbnQgaW5mb3JtYXRpb24gcmVnYXJkaW5nIHRyYW5zbGF0aW9uIG9mCiAgICAgICAgICogbGFtYmRhIGV4cHJlc3Npb24vbWV0aG9kIHJlZmVyZW5jZXMgKHNlZSBzdWJjbGFzc2VzKS4KICAgICAgICAgKi8KICAgICAgICBhYnN0cmFjdCBjbGFzcyBUcmFuc2xhdGlvbkNvbnRleHQ8VCBleHRlbmRzIEpDRnVuY3Rpb25hbEV4cHJlc3Npb24+IHsKCiAgICAgICAgICAgIC8qKiB0aGUgdW5kZXJseWluZyAodW50cmFuc2xhdGVkKSB0cmVlICovCiAgICAgICAgICAgIGZpbmFsIFQgdHJlZTsKCiAgICAgICAgICAgIC8qKiBwb2ludHMgdG8gdGhlIGFkanVzdGVkIGVuY2xvc2luZyBzY29wZSBpbiB3aGljaCB0aGlzIGxhbWJkYS9tcmVmIGV4cHJlc3Npb24gb2NjdXJzICovCiAgICAgICAgICAgIGZpbmFsIFN5bWJvbCBvd25lcjsKCiAgICAgICAgICAgIC8qKiB0aGUgZGVwdGggb2YgdGhpcyBsYW1iZGEgZXhwcmVzc2lvbiBpbiB0aGUgZnJhbWUgc3RhY2sgKi8KICAgICAgICAgICAgZmluYWwgaW50IGRlcHRoOwoKICAgICAgICAgICAgLyoqIHRoZSBlbmNsb3NpbmcgdHJhbnNsYXRpb24gY29udGV4dCAoc2V0IGZvciBuZXN0ZWQgbGFtYmRhcy9tcmVmKSAqLwogICAgICAgICAgICBmaW5hbCBUcmFuc2xhdGlvbkNvbnRleHQ8Pz4gcHJldjsKCiAgICAgICAgICAgIC8qKiBsaXN0IG9mIG1ldGhvZHMgdG8gYmUgYnJpZGdlZCBieSB0aGUgbWV0YS1mYWN0b3J5ICovCiAgICAgICAgICAgIGZpbmFsIExpc3Q8U3ltYm9sPiBicmlkZ2VzOwoKICAgICAgICAgICAgVHJhbnNsYXRpb25Db250ZXh0KFQgdHJlZSkgewogICAgICAgICAgICAgICAgdGhpcy50cmVlID0gdHJlZTsKICAgICAgICAgICAgICAgIHRoaXMub3duZXIgPSBvd25lcih0cnVlKTsKICAgICAgICAgICAgICAgIHRoaXMuZGVwdGggPSBmcmFtZVN0YWNrLnNpemUoKSAtIDE7CiAgICAgICAgICAgICAgICB0aGlzLnByZXYgPSBjb250ZXh0KCk7CiAgICAgICAgICAgICAgICBDbGFzc1N5bWJvbCBjc3ltID0KICAgICAgICAgICAgICAgICAgICAgICAgdHlwZXMubWFrZUZ1bmN0aW9uYWxJbnRlcmZhY2VDbGFzcyhhdHRyRW52LCBuYW1lcy5lbXB0eSwgdHJlZS50YXJnZXRzLCBBQlNUUkFDVCB8IElOVEVSRkFDRSk7CiAgICAgICAgICAgICAgICB0aGlzLmJyaWRnZXMgPSB0eXBlcy5mdW5jdGlvbmFsSW50ZXJmYWNlQnJpZGdlcyhjc3ltKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyoqIGRvZXMgdGhpcyBmdW5jdGlvbmFsIGV4cHJlc3Npb24gbmVlZCB0byBiZSBjcmVhdGVkIHVzaW5nIGFsdGVybmF0ZSBtZXRhZmFjdG9yeT8gKi8KICAgICAgICAgICAgYm9vbGVhbiBuZWVkc0FsdE1ldGFmYWN0b3J5KCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRyZWUudGFyZ2V0cy5sZW5ndGgoKSA+IDEgfHwKICAgICAgICAgICAgICAgICAgICAgICAgaXNTZXJpYWxpemFibGUoKSB8fAogICAgICAgICAgICAgICAgICAgICAgICBicmlkZ2VzLmxlbmd0aCgpID4gMTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyoqIGRvZXMgdGhpcyBmdW5jdGlvbmFsIGV4cHJlc3Npb24gcmVxdWlyZSBzZXJpYWxpemF0aW9uIHN1cHBvcnQ/ICovCiAgICAgICAgICAgIGJvb2xlYW4gaXNTZXJpYWxpemFibGUoKSB7CiAgICAgICAgICAgICAgICBpZiAoZm9yY2VTZXJpYWxpemFibGUpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGZvciAoVHlwZSB0YXJnZXQgOiB0cmVlLnRhcmdldHMpIHsKICAgICAgICAgICAgICAgICAgICBpZiAodHlwZXMuYXNTdXBlcih0YXJnZXQsIHN5bXMuc2VyaWFsaXphYmxlVHlwZS50c3ltKSAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIEByZXR1cm4gTmFtZSBvZiB0aGUgZW5jbG9zaW5nIG1ldGhvZCB0byBiZSBmb2xkZWQgaW50byBzeW50aGV0aWMKICAgICAgICAgICAgICogbWV0aG9kIG5hbWUKICAgICAgICAgICAgICovCiAgICAgICAgICAgIFN0cmluZyBlbmNsb3NpbmdNZXRob2ROYW1lKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHN5bnRoZXRpY01ldGhvZE5hbWVDb21wb25lbnQob3duZXIubmFtZSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBAcmV0dXJuIE1ldGhvZCBuYW1lIGluIGEgZm9ybSB0aGF0IGNhbiBiZSBmb2xkZWQgaW50byBhCiAgICAgICAgICAgICAqIGNvbXBvbmVudCBvZiBhIHN5bnRoZXRpYyBtZXRob2QgbmFtZQogICAgICAgICAgICAgKi8KICAgICAgICAgICAgU3RyaW5nIHN5bnRoZXRpY01ldGhvZE5hbWVDb21wb25lbnQoTmFtZSBuYW1lKSB7CiAgICAgICAgICAgICAgICBpZiAobmFtZSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICJudWxsIjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIFN0cmluZyBtZXRob2ROYW1lID0gbmFtZS50b1N0cmluZygpOwogICAgICAgICAgICAgICAgaWYgKG1ldGhvZE5hbWUuZXF1YWxzKCI8Y2xpbml0PiIpKSB7CiAgICAgICAgICAgICAgICAgICAgbWV0aG9kTmFtZSA9ICJzdGF0aWMiOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChtZXRob2ROYW1lLmVxdWFscygiPGluaXQ+IikpIHsKICAgICAgICAgICAgICAgICAgICBtZXRob2ROYW1lID0gIm5ldyI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gbWV0aG9kTmFtZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogVGhpcyBjbGFzcyByZXRhaW5zIGFsbCB0aGUgdXNlZnVsIGluZm9ybWF0aW9uIGFib3V0IGEgbGFtYmRhIGV4cHJlc3Npb247CiAgICAgICAgICogdGhlIGNvbnRlbnRzIG9mIHRoaXMgY2xhc3MgYXJlIGZpbGxlZCBieSB0aGUgTGFtYmRhQW5hbHl6ZXIgdmlzaXRvciwKICAgICAgICAgKiBhbmQgdGhlIHVzZWQgYnkgdGhlIG1haW4gdHJhbnNsYXRpb24gcm91dGluZXMgaW4gb3JkZXIgdG8gYWRqdXN0IHJlZmVyZW5jZXMKICAgICAgICAgKiB0byBjYXB0dXJlZCBsb2NhbHMvbWVtYmVycywgZXRjLgogICAgICAgICAqLwogICAgICAgIGNsYXNzIExhbWJkYVRyYW5zbGF0aW9uQ29udGV4dCBleHRlbmRzIFRyYW5zbGF0aW9uQ29udGV4dDxKQ0xhbWJkYT4gewoKICAgICAgICAgICAgLyoqIHZhcmlhYmxlIGluIHRoZSBlbmNsb3NpbmcgY29udGV4dCB0byB3aGljaCB0aGlzIGxhbWJkYSBpcyBhc3NpZ25lZCAqLwogICAgICAgICAgICBmaW5hbCBTeW1ib2wgc2VsZjsKCiAgICAgICAgICAgIC8qKiB2YXJpYWJsZSBpbiB0aGUgZW5jbG9zaW5nIGNvbnRleHQgdG8gd2hpY2ggdGhpcyBsYW1iZGEgaXMgYXNzaWduZWQgKi8KICAgICAgICAgICAgZmluYWwgU3ltYm9sIGFzc2lnbmVkVG87CgogICAgICAgICAgICBNYXA8TGFtYmRhU3ltYm9sS2luZCwgTWFwPFN5bWJvbCwgU3ltYm9sPj4gdHJhbnNsYXRlZFN5bWJvbHM7CgogICAgICAgICAgICAvKiogdGhlIHN5bnRoZXRpYyBzeW1ib2wgZm9yIHRoZSBtZXRob2QgaG9pc3RpbmcgdGhlIHRyYW5zbGF0ZWQgbGFtYmRhICovCiAgICAgICAgICAgIE1ldGhvZFN5bWJvbCB0cmFuc2xhdGVkU3ltOwoKICAgICAgICAgICAgTGlzdDxKQ1ZhcmlhYmxlRGVjbD4gc3ludGhldGljUGFyYW1zOwoKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIHRvIHByZXZlbnQgcmVjdXJzaW9uLCB0cmFjayBsb2NhbCBjbGFzc2VzIHByb2Nlc3NlZAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgZmluYWwgU2V0PFN5bWJvbD4gZnJlZVZhclByb2Nlc3NlZExvY2FsQ2xhc3NlczsKCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBGb3IgbWV0aG9kIHJlZmVyZW5jZXMgY29udmVydGVkIHRvIGxhbWJkYXMuICBUaGUgbWV0aG9kCiAgICAgICAgICAgICAqIHJlZmVyZW5jZSByZWNlaXZlciBleHByZXNzaW9uLiBNdXN0IGJlIHRyZWF0ZWQgbGlrZSBhIGNhcHR1cmVkCiAgICAgICAgICAgICAqIHZhcmlhYmxlLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgSkNFeHByZXNzaW9uIG1ldGhvZFJlZmVyZW5jZVJlY2VpdmVyOwoKICAgICAgICAgICAgTGFtYmRhVHJhbnNsYXRpb25Db250ZXh0KEpDTGFtYmRhIHRyZWUpIHsKICAgICAgICAgICAgICAgIHN1cGVyKHRyZWUpOwogICAgICAgICAgICAgICAgRnJhbWUgZnJhbWUgPSBmcmFtZVN0YWNrLmhlYWQ7CiAgICAgICAgICAgICAgICBzd2l0Y2ggKGZyYW1lLnRyZWUuZ2V0VGFnKCkpIHsKICAgICAgICAgICAgICAgICAgICBjYXNlIFZBUkRFRjoKICAgICAgICAgICAgICAgICAgICAgICAgYXNzaWduZWRUbyA9IHNlbGYgPSAoKEpDVmFyaWFibGVEZWNsKSBmcmFtZS50cmVlKS5zeW07CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgQVNTSUdOOgogICAgICAgICAgICAgICAgICAgICAgICBzZWxmID0gbnVsbDsKICAgICAgICAgICAgICAgICAgICAgICAgYXNzaWduZWRUbyA9IFRyZWVJbmZvLnN5bWJvbCgoKEpDQXNzaWduKSBmcmFtZS50cmVlKS5nZXRWYXJpYWJsZSgpKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgICAgYXNzaWduZWRUbyA9IHNlbGYgPSBudWxsOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gVGhpcyBzeW1ib2wgd2lsbCBiZSBmaWxsZWQtaW4gaW4gY29tcGxldGUKICAgICAgICAgICAgICAgIHRoaXMudHJhbnNsYXRlZFN5bSA9IG1ha2VQcml2YXRlU3ludGhldGljTWV0aG9kKDAsIG51bGwsIG51bGwsIG93bmVyLmVuY2xDbGFzcygpKTsKCiAgICAgICAgICAgICAgICB0cmFuc2xhdGVkU3ltYm9scyA9IG5ldyBFbnVtTWFwPD4oTGFtYmRhU3ltYm9sS2luZC5jbGFzcyk7CgogICAgICAgICAgICAgICAgdHJhbnNsYXRlZFN5bWJvbHMucHV0KFBBUkFNLCBuZXcgTGlua2VkSGFzaE1hcDxTeW1ib2wsIFN5bWJvbD4oKSk7CiAgICAgICAgICAgICAgICB0cmFuc2xhdGVkU3ltYm9scy5wdXQoTE9DQUxfVkFSLCBuZXcgTGlua2VkSGFzaE1hcDxTeW1ib2wsIFN5bWJvbD4oKSk7CiAgICAgICAgICAgICAgICB0cmFuc2xhdGVkU3ltYm9scy5wdXQoQ0FQVFVSRURfVkFSLCBuZXcgTGlua2VkSGFzaE1hcDxTeW1ib2wsIFN5bWJvbD4oKSk7CiAgICAgICAgICAgICAgICB0cmFuc2xhdGVkU3ltYm9scy5wdXQoQ0FQVFVSRURfVEhJUywgbmV3IExpbmtlZEhhc2hNYXA8U3ltYm9sLCBTeW1ib2w+KCkpOwogICAgICAgICAgICAgICAgdHJhbnNsYXRlZFN5bWJvbHMucHV0KENBUFRVUkVEX09VVEVSX1RISVMsIG5ldyBMaW5rZWRIYXNoTWFwPFN5bWJvbCwgU3ltYm9sPigpKTsKICAgICAgICAgICAgICAgIHRyYW5zbGF0ZWRTeW1ib2xzLnB1dChUWVBFX1ZBUiwgbmV3IExpbmtlZEhhc2hNYXA8U3ltYm9sLCBTeW1ib2w+KCkpOwoKICAgICAgICAgICAgICAgIGZyZWVWYXJQcm9jZXNzZWRMb2NhbENsYXNzZXMgPSBuZXcgSGFzaFNldDw+KCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAvKioKICAgICAgICAgICAgICogRm9yIGEgc2VyaWFsaXphYmxlIGxhbWJkYSwgZ2VuZXJhdGUgYSBkaXNhbWJpZ3VhdGluZyBzdHJpbmcKICAgICAgICAgICAgICogd2hpY2ggbWF4aW1pemVzIHN0YWJpbGl0eSBhY3Jvc3MgZGVzZXJpYWxpemF0aW9uLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcmV0dXJuIFN0cmluZyB0byBkaWZmZXJlbnRpYXRlIHN5bnRoZXRpYyBsYW1iZGEgbWV0aG9kIG5hbWVzCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBwcml2YXRlIFN0cmluZyBzZXJpYWxpemVkTGFtYmRhRGlzYW1iaWd1YXRpb24oKSB7CiAgICAgICAgICAgICAgICBTdHJpbmdCdWlsZGVyIGJ1ZiA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CiAgICAgICAgICAgICAgICAvLyBBcHBlbmQgdGhlIGVuY2xvc2luZyBtZXRob2Qgc2lnbmF0dXJlIHRvIGRpZmZlcmVudGlhdGUKICAgICAgICAgICAgICAgIC8vIG92ZXJsb2FkZWQgZW5jbG9zaW5nIG1ldGhvZHMuICBGb3IgbGFtYmRhcyBlbmNsb3NlZCBpbgogICAgICAgICAgICAgICAgLy8gbGFtYmRhcywgdGhlIGdlbmVyYXRlZCBsYW1iZGEgbWV0aG9kIHdpbGwgbm90IGhhdmUgdHlwZSB5ZXQsCiAgICAgICAgICAgICAgICAvLyBidXQgdGhlIGVuY2xvc2luZyBtZXRob2QncyBuYW1lIHdpbGwgaGF2ZSBiZWVuIGdlbmVyYXRlZAogICAgICAgICAgICAgICAgLy8gd2l0aCB0aGlzIHNhbWUgbWV0aG9kLCBzbyBpdCB3aWxsIGJlIHVuaXF1ZSBhbmQgbmV2ZXIgYmUKICAgICAgICAgICAgICAgIC8vIG92ZXJsb2FkZWQuCiAgICAgICAgICAgICAgICBBc3NlcnQuY2hlY2soCiAgICAgICAgICAgICAgICAgICAgICAgIG93bmVyLnR5cGUgIT0gbnVsbCB8fAogICAgICAgICAgICAgICAgICAgICAgICBkaXJlY3RseUVuY2xvc2luZ0xhbWJkYSgpICE9IG51bGwpOwogICAgICAgICAgICAgICAgaWYgKG93bmVyLnR5cGUgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQodHlwZVNpZyhvd25lci50eXBlKSk7CiAgICAgICAgICAgICAgICAgICAgYnVmLmFwcGVuZCgiOiIpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIEFkZCB0YXJnZXQgdHlwZSBpbmZvCiAgICAgICAgICAgICAgICBidWYuYXBwZW5kKHR5cGVzLmZpbmREZXNjcmlwdG9yU3ltYm9sKHRyZWUudHlwZS50c3ltKS5vd25lci5mbGF0TmFtZSgpKTsKICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQoIiAiKTsKCiAgICAgICAgICAgICAgICAvLyBBZGQgdmFyaWFibGUgYXNzaWduZWQgdG8KICAgICAgICAgICAgICAgIGlmIChhc3NpZ25lZFRvICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICBidWYuYXBwZW5kKGFzc2lnbmVkVG8uZmxhdE5hbWUoKSk7CiAgICAgICAgICAgICAgICAgICAgYnVmLmFwcGVuZCgiPSIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgLy9hZGQgY2FwdHVyZWQgbG9jYWxzIGluZm86IHR5cGUsIG5hbWUsIG9yZGVyCiAgICAgICAgICAgICAgICBmb3IgKFN5bWJvbCBmdiA6IGdldFN5bWJvbE1hcChDQVBUVVJFRF9WQVIpLmtleVNldCgpKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGZ2ICE9IHNlbGYpIHsKICAgICAgICAgICAgICAgICAgICAgICAgYnVmLmFwcGVuZCh0eXBlU2lnKGZ2LnR5cGUpKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnVmLmFwcGVuZCgiICIpOwogICAgICAgICAgICAgICAgICAgICAgICBidWYuYXBwZW5kKGZ2LmZsYXROYW1lKCkpOwogICAgICAgICAgICAgICAgICAgICAgICBidWYuYXBwZW5kKCIsIik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHJldHVybiBidWYudG9TdHJpbmcoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIEZvciBhIG5vbi1zZXJpYWxpemFibGUgbGFtYmRhLCBnZW5lcmF0ZSBhIHNpbXBsZSBtZXRob2QuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEByZXR1cm4gTmFtZSB0byB1c2UgZm9yIHRoZSBzeW50aGV0aWMgbGFtYmRhIG1ldGhvZCBuYW1lCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBwcml2YXRlIE5hbWUgbGFtYmRhTmFtZSgpIHsKICAgICAgICAgICAgICAgIHJldHVybiBuYW1lcy5sYW1iZGEuYXBwZW5kKG5hbWVzLmZyb21TdHJpbmcoZW5jbG9zaW5nTWV0aG9kTmFtZSgpICsgIiQiICsgbGFtYmRhQ291bnQrKykpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogRm9yIGEgc2VyaWFsaXphYmxlIGxhbWJkYSwgZ2VuZXJhdGUgYSBtZXRob2QgbmFtZSB3aGljaCBtYXhpbWl6ZXMKICAgICAgICAgICAgICogbmFtZSBzdGFiaWxpdHkgYWNyb3NzIGRlc2VyaWFsaXphdGlvbi4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHJldHVybiBOYW1lIHRvIHVzZSBmb3IgdGhlIHN5bnRoZXRpYyBsYW1iZGEgbWV0aG9kIG5hbWUKICAgICAgICAgICAgICovCiAgICAgICAgICAgIHByaXZhdGUgTmFtZSBzZXJpYWxpemVkTGFtYmRhTmFtZSgpIHsKICAgICAgICAgICAgICAgIFN0cmluZ0J1aWxkZXIgYnVmID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQobmFtZXMubGFtYmRhKTsKICAgICAgICAgICAgICAgIC8vIEFwcGVuZCB0aGUgbmFtZSBvZiB0aGUgbWV0aG9kIGVuY2xvc2luZyB0aGUgbGFtYmRhLgogICAgICAgICAgICAgICAgYnVmLmFwcGVuZChlbmNsb3NpbmdNZXRob2ROYW1lKCkpOwogICAgICAgICAgICAgICAgYnVmLmFwcGVuZCgnJCcpOwogICAgICAgICAgICAgICAgLy8gQXBwZW5kIGEgaGFzaCBvZiB0aGUgZGlzYW1iaWd1YXRpbmcgc3RyaW5nIDogZW5jbG9zaW5nIG1ldGhvZAogICAgICAgICAgICAgICAgLy8gc2lnbmF0dXJlLCBldGMuCiAgICAgICAgICAgICAgICBTdHJpbmcgZGlzYW0gPSBzZXJpYWxpemVkTGFtYmRhRGlzYW1iaWd1YXRpb24oKTsKICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQoSW50ZWdlci50b0hleFN0cmluZyhkaXNhbS5oYXNoQ29kZSgpKSk7CiAgICAgICAgICAgICAgICBidWYuYXBwZW5kKCckJyk7CiAgICAgICAgICAgICAgICAvLyBUaGUgYWJvdmUgYXBwZW5kZWQgbmFtZSBjb21wb25lbnRzIG1heSBub3QgYmUgdW5pcXVlLCBhcHBlbmQKICAgICAgICAgICAgICAgIC8vIGEgY291bnQgYmFzZWQgb24gdGhlIGFib3ZlIG5hbWUgY29tcG9uZW50cy4KICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQoc3ludGhldGljTWV0aG9kTmFtZUNvdW50cy5nZXRJbmRleChidWYpKTsKICAgICAgICAgICAgICAgIFN0cmluZyByZXN1bHQgPSBidWYudG9TdHJpbmcoKTsKICAgICAgICAgICAgICAgIC8vU3lzdGVtLmVyci5wcmludGYoInNlcmlhbGl6ZWRMYW1iZGFOYW1lOiAlcyAtLSAlc1xuIiwgcmVzdWx0LCBkaXNhbSk7CiAgICAgICAgICAgICAgICByZXR1cm4gbmFtZXMuZnJvbVN0cmluZyhyZXN1bHQpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogVHJhbnNsYXRlIGEgc3ltYm9sIG9mIGEgZ2l2ZW4ga2luZCBpbnRvIHNvbWV0aGluZyBzdWl0YWJsZSBmb3IgdGhlCiAgICAgICAgICAgICAqIHN5bnRoZXRpYyBsYW1iZGEgYm9keQogICAgICAgICAgICAgKi8KICAgICAgICAgICAgU3ltYm9sIHRyYW5zbGF0ZShmaW5hbCBTeW1ib2wgc3ltLCBMYW1iZGFTeW1ib2xLaW5kIHNraW5kKSB7CiAgICAgICAgICAgICAgICBTeW1ib2wgcmV0OwogICAgICAgICAgICAgICAgc3dpdGNoIChza2luZCkgewogICAgICAgICAgICAgICAgICAgIGNhc2UgQ0FQVFVSRURfVEhJUzoKICAgICAgICAgICAgICAgICAgICAgICAgcmV0ID0gc3ltOyAgLy8gc2VsZiByZXByZXNlbnRlZAogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICBjYXNlIFRZUEVfVkFSOgogICAgICAgICAgICAgICAgICAgICAgICAvLyBKdXN0IGVyYXNlIHRoZSB0eXBlIHZhcgogICAgICAgICAgICAgICAgICAgICAgICByZXQgPSBuZXcgVmFyU3ltYm9sKHN5bS5mbGFncygpLCBzeW0ubmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlcy5lcmFzdXJlKHN5bS50eXBlKSwgc3ltLm93bmVyKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRoaXMgaW5mb3JtYXRpb24gc2hvdWxkIGFsc28gYmUga2VwdCBmb3IgTFZUIGdlbmVyYXRpb24gYXQgR2VuCiAgICAgICAgICAgICAgICAgICAgICAgICAqIGEgU3ltYm9sIHdpdGggcG9zIDwgc3RhcnRQb3Mgd29uJ3QgYmUgdHJhY2tlZC4KICAgICAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgICAgICgoVmFyU3ltYm9sKXJldCkucG9zID0gKChWYXJTeW1ib2wpc3ltKS5wb3M7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgQ0FQVFVSRURfVkFSOgogICAgICAgICAgICAgICAgICAgICAgICByZXQgPSBuZXcgVmFyU3ltYm9sKFNZTlRIRVRJQyB8IEZJTkFMIHwgUEFSQU1FVEVSLCBzeW0ubmFtZSwgdHlwZXMuZXJhc3VyZShzeW0udHlwZSksIHRyYW5zbGF0ZWRTeW0pIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgcHVibGljIFN5bWJvbCBiYXNlU3ltYm9sKCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8va2VlcCBtYXBwaW5nIHdpdGggb3JpZ2luYWwgY2FwdHVyZWQgc3ltYm9sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHN5bTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBDQVBUVVJFRF9PVVRFUl9USElTOgogICAgICAgICAgICAgICAgICAgICAgICBOYW1lIG5hbWUgPSBuYW1lcy5mcm9tU3RyaW5nKG5ldyBTdHJpbmcoc3ltLmZsYXROYW1lKCkudG9TdHJpbmcoKS5yZXBsYWNlKCcuJywgJyQnKSArIG5hbWVzLmRvbGxhclRoaXMpKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0ID0gbmV3IFZhclN5bWJvbChTWU5USEVUSUMgfCBGSU5BTCB8IFBBUkFNRVRFUiwgbmFtZSwgdHlwZXMuZXJhc3VyZShzeW0udHlwZSksIHRyYW5zbGF0ZWRTeW0pIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgcHVibGljIFN5bWJvbCBiYXNlU3ltYm9sKCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8va2VlcCBtYXBwaW5nIHdpdGggb3JpZ2luYWwgY2FwdHVyZWQgc3ltYm9sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHN5bTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBMT0NBTF9WQVI6CiAgICAgICAgICAgICAgICAgICAgICAgIHJldCA9IG5ldyBWYXJTeW1ib2woc3ltLmZsYWdzKCkgJiBGSU5BTCwgc3ltLm5hbWUsIHN5bS50eXBlLCB0cmFuc2xhdGVkU3ltKTsKICAgICAgICAgICAgICAgICAgICAgICAgKChWYXJTeW1ib2wpIHJldCkucG9zID0gKChWYXJTeW1ib2wpIHN5bSkucG9zOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICBjYXNlIFBBUkFNOgogICAgICAgICAgICAgICAgICAgICAgICByZXQgPSBuZXcgVmFyU3ltYm9sKChzeW0uZmxhZ3MoKSAmIEZJTkFMKSB8IFBBUkFNRVRFUiwgc3ltLm5hbWUsIHR5cGVzLmVyYXN1cmUoc3ltLnR5cGUpLCB0cmFuc2xhdGVkU3ltKTsKICAgICAgICAgICAgICAgICAgICAgICAgKChWYXJTeW1ib2wpIHJldCkucG9zID0gKChWYXJTeW1ib2wpIHN5bSkucG9zOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgICAgICBBc3NlcnQuZXJyb3Ioc2tpbmQubmFtZSgpKTsKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAocmV0ICE9IHN5bSkgewogICAgICAgICAgICAgICAgICAgIHJldC5zZXREZWNsYXJhdGlvbkF0dHJpYnV0ZXMoc3ltLmdldFJhd0F0dHJpYnV0ZXMoKSk7CiAgICAgICAgICAgICAgICAgICAgcmV0LnNldFR5cGVBdHRyaWJ1dGVzKHN5bS5nZXRSYXdUeXBlQXR0cmlidXRlcygpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHZvaWQgYWRkU3ltYm9sKFN5bWJvbCBzeW0sIExhbWJkYVN5bWJvbEtpbmQgc2tpbmQpIHsKICAgICAgICAgICAgICAgIGlmIChza2luZCA9PSBDQVBUVVJFRF9USElTICYmIHN5bSAhPSBudWxsICYmIHN5bS5raW5kID09IFRZUCAmJiAhdHlwZXNVbmRlckNvbnN0cnVjdGlvbi5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICAgICAgICBDbGFzc1N5bWJvbCBjdXJyZW50Q2xhc3MgPSBjdXJyZW50Q2xhc3MoKTsKICAgICAgICAgICAgICAgICAgICBpZiAoY3VycmVudENsYXNzICE9IG51bGwgJiYgdHlwZXNVbmRlckNvbnN0cnVjdGlvbi5jb250YWlucyhjdXJyZW50Q2xhc3MpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHJlZmVyZW5jZSBtdXN0IGJlIHRvIGVuY2xvc2luZyBvdXRlciBpbnN0YW5jZSwgbXV0YXRlIGNhcHR1cmUga2luZC4KICAgICAgICAgICAgICAgICAgICAgICAgQXNzZXJ0LmNoZWNrKHN5bSAhPSBjdXJyZW50Q2xhc3MpOyAvLyBzaG91bGQgaGF2ZSBiZWVuIGNhdWdodCByaWdodCBpbiBBdHRyCiAgICAgICAgICAgICAgICAgICAgICAgIHNraW5kID0gQ0FQVFVSRURfT1VURVJfVEhJUzsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBNYXA8U3ltYm9sLCBTeW1ib2w+IHRyYW5zTWFwID0gZ2V0U3ltYm9sTWFwKHNraW5kKTsKICAgICAgICAgICAgICAgIGlmICghdHJhbnNNYXAuY29udGFpbnNLZXkoc3ltKSkgewogICAgICAgICAgICAgICAgICAgIHRyYW5zTWFwLnB1dChzeW0sIHRyYW5zbGF0ZShzeW0sIHNraW5kKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIE1hcDxTeW1ib2wsIFN5bWJvbD4gZ2V0U3ltYm9sTWFwKExhbWJkYVN5bWJvbEtpbmQgc2tpbmQpIHsKICAgICAgICAgICAgICAgIE1hcDxTeW1ib2wsIFN5bWJvbD4gbSA9IHRyYW5zbGF0ZWRTeW1ib2xzLmdldChza2luZCk7CiAgICAgICAgICAgICAgICBBc3NlcnQuY2hlY2tOb25OdWxsKG0pOwogICAgICAgICAgICAgICAgcmV0dXJuIG07CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEpDVHJlZSB0cmFuc2xhdGUoSkNJZGVudCBsYW1iZGFJZGVudCkgewogICAgICAgICAgICAgICAgZm9yIChMYW1iZGFTeW1ib2xLaW5kIGtpbmQgOiBMYW1iZGFTeW1ib2xLaW5kLnZhbHVlcygpKSB7CiAgICAgICAgICAgICAgICAgICAgTWFwPFN5bWJvbCwgU3ltYm9sPiBtID0gZ2V0U3ltYm9sTWFwKGtpbmQpOwogICAgICAgICAgICAgICAgICAgIHN3aXRjaChraW5kKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobS5jb250YWluc0tleShsYW1iZGFJZGVudC5zeW0pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3ltYm9sIHRTeW0gPSBtLmdldChsYW1iZGFJZGVudC5zeW0pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEpDVHJlZSB0ID0gbWFrZS5JZGVudCh0U3ltKS5zZXRUeXBlKGxhbWJkYUlkZW50LnR5cGUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRTeW0uc2V0VHlwZUF0dHJpYnV0ZXMobGFtYmRhSWRlbnQuc3ltLmdldFJhd1R5cGVBdHRyaWJ1dGVzKCkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgQ0FQVFVSRURfT1VURVJfVEhJUzoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChsYW1iZGFJZGVudC5zeW0ub3duZXIua2luZCA9PSBUWVAgJiYgbS5jb250YWluc0tleShsYW1iZGFJZGVudC5zeW0ub3duZXIpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVHJhbnNmb3JtIG91dGVyIGluc3RhbmNlIHZhcmlhYmxlIHJlZmVyZW5jZXMgYW5jaG9yaW5nIHRoZW0gdG8gdGhlIGNhcHR1cmVkIHN5bnRoZXRpYy4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTeW1ib2wgdFN5bSA9IG0uZ2V0KGxhbWJkYUlkZW50LnN5bS5vd25lcik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSkNFeHByZXNzaW9uIHQgPSBtYWtlLklkZW50KHRTeW0pLnNldFR5cGUobGFtYmRhSWRlbnQuc3ltLm93bmVyLnR5cGUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRTeW0uc2V0VHlwZUF0dHJpYnV0ZXMobGFtYmRhSWRlbnQuc3ltLm93bmVyLmdldFJhd1R5cGVBdHRyaWJ1dGVzKCkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHQgPSBtYWtlLlNlbGVjdCh0LCBsYW1iZGFJZGVudC5uYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0LnNldFR5cGUobGFtYmRhSWRlbnQudHlwZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVHJlZUluZm8uc2V0U3ltYm9sKHQsIGxhbWJkYUlkZW50LnN5bSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHQ7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyogVHJhbnNsYXRlIGF3YXkgcXVhbGlmaWVkIHRoaXMgZXhwcmVzc2lvbnMsIGFuY2hvcmluZyB0aGVtIHRvIHN5bnRoZXRpYyBwYXJhbWV0ZXJzIHRoYXQKICAgICAgICAgICAgICAgY2FwdHVyZSB0aGUgcXVhbGlmaWVkIHRoaXMgaGFuZGxlLiBgZmllbGRBY2Nlc3MnIGlzIGd1YXJhbnRlZWQgdG8gb25lIHN1Y2guCiAgICAgICAgICAgICovCiAgICAgICAgICAgIHB1YmxpYyBKQ1RyZWUgdHJhbnNsYXRlKEpDRmllbGRBY2Nlc3MgZmllbGRBY2Nlc3MpIHsKICAgICAgICAgICAgICAgIEFzc2VydC5jaGVjayhmaWVsZEFjY2Vzcy5uYW1lID09IG5hbWVzLl90aGlzKTsKICAgICAgICAgICAgICAgIE1hcDxTeW1ib2wsIFN5bWJvbD4gbSA9IHRyYW5zbGF0ZWRTeW1ib2xzLmdldChMYW1iZGFTeW1ib2xLaW5kLkNBUFRVUkVEX09VVEVSX1RISVMpOwogICAgICAgICAgICAgICAgaWYgKG0uY29udGFpbnNLZXkoZmllbGRBY2Nlc3Muc3ltLm93bmVyKSkgewogICAgICAgICAgICAgICAgICAgIFN5bWJvbCB0U3ltID0gbS5nZXQoZmllbGRBY2Nlc3Muc3ltLm93bmVyKTsKICAgICAgICAgICAgICAgICAgICBKQ0V4cHJlc3Npb24gdCA9IG1ha2UuSWRlbnQodFN5bSkuc2V0VHlwZShmaWVsZEFjY2Vzcy5zeW0ub3duZXIudHlwZSk7CiAgICAgICAgICAgICAgICAgICAgdFN5bS5zZXRUeXBlQXR0cmlidXRlcyhmaWVsZEFjY2Vzcy5zeW0ub3duZXIuZ2V0UmF3VHlwZUF0dHJpYnV0ZXMoKSk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIFRoZSB0cmFuc2xhdGVkU3ltIGlzIG5vdCBjb21wbGV0ZS9hY2N1cmF0ZSB1bnRpbCB0aGUgYW5hbHlzaXMgaXMKICAgICAgICAgICAgICogZmluaXNoZWQuICBPbmNlIHRoZSBhbmFseXNpcyBpcyBmaW5pc2hlZCwgdGhlIHRyYW5zbGF0ZWRTeW0gaXMKICAgICAgICAgICAgICogImNvbXBsZXRlZCIgLS0gdXBkYXRlZCB3aXRoIHR5cGUgaW5mb3JtYXRpb24sIGFjY2VzcyBtb2RpZmllcnMsCiAgICAgICAgICAgICAqIGFuZCBmdWxsIHBhcmFtZXRlciBsaXN0LgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgdm9pZCBjb21wbGV0ZSgpIHsKICAgICAgICAgICAgICAgIGlmIChzeW50aGV0aWNQYXJhbXMgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJvb2xlYW4gaW5JbnRlcmZhY2UgPSB0cmFuc2xhdGVkU3ltLm93bmVyLmlzSW50ZXJmYWNlKCk7CiAgICAgICAgICAgICAgICBib29sZWFuIHRoaXNSZWZlcmVuY2VkID0gIWdldFN5bWJvbE1hcChDQVBUVVJFRF9USElTKS5pc0VtcHR5KCk7CgogICAgICAgICAgICAgICAgLy8gSWYgaW5zdGFuY2UgYWNjZXNzIGlzbid0IG5lZWRlZCwgbWFrZSBpdCBzdGF0aWMuCiAgICAgICAgICAgICAgICAvLyBJbnRlcmZhY2UgaW5zdGFuY2UgbWV0aG9kcyBtdXN0IGJlIGRlZmF1bHQgbWV0aG9kcy4KICAgICAgICAgICAgICAgIC8vIExhbWJkYSBtZXRob2RzIGFyZSBwcml2YXRlIHN5bnRoZXRpYy4KICAgICAgICAgICAgICAgIC8vIEluaGVyaXQgQUNDX1NUUklDVCBmcm9tIHRoZSBlbmNsb3NpbmcgbWV0aG9kLCBvciwgZm9yIGNsaW5pdCwKICAgICAgICAgICAgICAgIC8vIGZyb20gdGhlIGNsYXNzLgogICAgICAgICAgICAgICAgdHJhbnNsYXRlZFN5bS5mbGFnc19maWVsZCA9IFNZTlRIRVRJQyB8IExBTUJEQV9NRVRIT0QgfAogICAgICAgICAgICAgICAgICAgICAgICBvd25lci5mbGFnc19maWVsZCAmIFNUUklDVEZQIHwKICAgICAgICAgICAgICAgICAgICAgICAgb3duZXIub3duZXIuZmxhZ3NfZmllbGQgJiBTVFJJQ1RGUCB8CiAgICAgICAgICAgICAgICAgICAgICAgIFBSSVZBVEUgfAogICAgICAgICAgICAgICAgICAgICAgICAodGhpc1JlZmVyZW5jZWQ/IChpbkludGVyZmFjZT8gREVGQVVMVCA6IDApIDogU1RBVElDKTsKCiAgICAgICAgICAgICAgICAvL2NvbXB1dGUgc3ludGhldGljIHBhcmFtcwogICAgICAgICAgICAgICAgTGlzdEJ1ZmZlcjxKQ1ZhcmlhYmxlRGVjbD4gcGFyYW1zID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgICAgICAgICAgTGlzdEJ1ZmZlcjxWYXJTeW1ib2w+IHBhcmFtZXRlclN5bWJvbHMgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CgogICAgICAgICAgICAgICAgLy8gVGhlIHNpZ25hdHVyZSBvZiB0aGUgbWV0aG9kIGlzIGF1Z21lbnRlZCB3aXRoIHRoZSBmb2xsb3dpbmcKICAgICAgICAgICAgICAgIC8vIHN5bnRoZXRpYyBwYXJhbWV0ZXJzOgogICAgICAgICAgICAgICAgLy8KICAgICAgICAgICAgICAgIC8vIDEpIHJlZmVyZW5jZSB0byBlbmNsb3NpbmcgY29udGV4dHMgY2FwdHVyZWQgYnkgdGhlIGxhbWJkYSBleHByZXNzaW9uCiAgICAgICAgICAgICAgICAvLyAyKSBlbmNsb3NpbmcgbG9jYWxzIGNhcHR1cmVkIGJ5IHRoZSBsYW1iZGEgZXhwcmVzc2lvbgogICAgICAgICAgICAgICAgZm9yIChTeW1ib2wgdGhpc1N5bSA6IGdldFN5bWJvbE1hcChDQVBUVVJFRF9WQVIpLnZhbHVlcygpKSB7CiAgICAgICAgICAgICAgICAgICAgcGFyYW1zLmFwcGVuZChtYWtlLlZhckRlZigoVmFyU3ltYm9sKSB0aGlzU3ltLCBudWxsKSk7CiAgICAgICAgICAgICAgICAgICAgcGFyYW1ldGVyU3ltYm9scy5hcHBlbmQoKFZhclN5bWJvbCkgdGhpc1N5bSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBmb3IgKFN5bWJvbCB0aGlzU3ltIDogZ2V0U3ltYm9sTWFwKENBUFRVUkVEX09VVEVSX1RISVMpLnZhbHVlcygpKSB7CiAgICAgICAgICAgICAgICAgICAgcGFyYW1zLmFwcGVuZChtYWtlLlZhckRlZigoVmFyU3ltYm9sKSB0aGlzU3ltLCBudWxsKSk7CiAgICAgICAgICAgICAgICAgICAgcGFyYW1ldGVyU3ltYm9scy5hcHBlbmQoKFZhclN5bWJvbCkgdGhpc1N5bSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBmb3IgKFN5bWJvbCB0aGlzU3ltIDogZ2V0U3ltYm9sTWFwKFBBUkFNKS52YWx1ZXMoKSkgewogICAgICAgICAgICAgICAgICAgIHBhcmFtcy5hcHBlbmQobWFrZS5WYXJEZWYoKFZhclN5bWJvbCkgdGhpc1N5bSwgbnVsbCkpOwogICAgICAgICAgICAgICAgICAgIHBhcmFtZXRlclN5bWJvbHMuYXBwZW5kKChWYXJTeW1ib2wpIHRoaXNTeW0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgc3ludGhldGljUGFyYW1zID0gcGFyYW1zLnRvTGlzdCgpOwoKICAgICAgICAgICAgICAgIHRyYW5zbGF0ZWRTeW0ucGFyYW1zID0gcGFyYW1ldGVyU3ltYm9scy50b0xpc3QoKTsKCiAgICAgICAgICAgICAgICAvLyBDb21wdXRlIGFuZCBzZXQgdGhlIGxhbWJkYSBuYW1lCiAgICAgICAgICAgICAgICB0cmFuc2xhdGVkU3ltLm5hbWUgPSBpc1NlcmlhbGl6YWJsZSgpCiAgICAgICAgICAgICAgICAgICAgICAgID8gc2VyaWFsaXplZExhbWJkYU5hbWUoKQogICAgICAgICAgICAgICAgICAgICAgICA6IGxhbWJkYU5hbWUoKTsKCiAgICAgICAgICAgICAgICAvL3ByZXBlbmQgc3ludGhldGljIGFyZ3MgdG8gdHJhbnNsYXRlZCBsYW1iZGEgbWV0aG9kIHNpZ25hdHVyZQogICAgICAgICAgICAgICAgdHJhbnNsYXRlZFN5bS50eXBlID0gdHlwZXMuY3JlYXRlTWV0aG9kVHlwZVdpdGhQYXJhbWV0ZXJzKAogICAgICAgICAgICAgICAgICAgICAgICBnZW5lcmF0ZWRMYW1iZGFTaWcoKSwKICAgICAgICAgICAgICAgICAgICAgICAgVHJlZUluZm8udHlwZXMoc3ludGhldGljUGFyYW1zKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIFR5cGUgZ2VuZXJhdGVkTGFtYmRhU2lnKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHR5cGVzLmVyYXN1cmUodHJlZS5nZXREZXNjcmlwdG9yVHlwZSh0eXBlcykpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBUaGlzIGNsYXNzIHJldGFpbnMgYWxsIHRoZSB1c2VmdWwgaW5mb3JtYXRpb24gYWJvdXQgYSBtZXRob2QgcmVmZXJlbmNlOwogICAgICAgICAqIHRoZSBjb250ZW50cyBvZiB0aGlzIGNsYXNzIGFyZSBmaWxsZWQgYnkgdGhlIExhbWJkYUFuYWx5emVyIHZpc2l0b3IsCiAgICAgICAgICogYW5kIHRoZSB1c2VkIGJ5IHRoZSBtYWluIHRyYW5zbGF0aW9uIHJvdXRpbmVzIGluIG9yZGVyIHRvIGFkanVzdCBtZXRob2QKICAgICAgICAgKiByZWZlcmVuY2VzIChpLmUuIGluIGNhc2UgYSBicmlkZ2UgaXMgbmVlZGVkKQogICAgICAgICAqLwogICAgICAgIGZpbmFsIGNsYXNzIFJlZmVyZW5jZVRyYW5zbGF0aW9uQ29udGV4dCBleHRlbmRzIFRyYW5zbGF0aW9uQ29udGV4dDxKQ01lbWJlclJlZmVyZW5jZT4gewoKICAgICAgICAgICAgZmluYWwgYm9vbGVhbiBpc1N1cGVyOwogICAgICAgICAgICBmaW5hbCBTeW1ib2wgc2lnUG9seVN5bTsKCiAgICAgICAgICAgIFJlZmVyZW5jZVRyYW5zbGF0aW9uQ29udGV4dChKQ01lbWJlclJlZmVyZW5jZSB0cmVlKSB7CiAgICAgICAgICAgICAgICBzdXBlcih0cmVlKTsKICAgICAgICAgICAgICAgIHRoaXMuaXNTdXBlciA9IHRyZWUuaGFzS2luZChSZWZlcmVuY2VLaW5kLlNVUEVSKTsKICAgICAgICAgICAgICAgIHRoaXMuc2lnUG9seVN5bSA9IGlzU2lnbmF0dXJlUG9seW1vcnBoaWMoKQogICAgICAgICAgICAgICAgICAgICAgICA/IG1ha2VQcml2YXRlU3ludGhldGljTWV0aG9kKHRyZWUuc3ltLmZsYWdzKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmVlLnN5bS5uYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJpZGdlZFJlZlNpZygpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJlZS5zeW0uZW5jbENsYXNzKCkpCiAgICAgICAgICAgICAgICAgICAgICAgIDogbnVsbDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIEdldCB0aGUgb3Bjb2RlIGFzc29jaWF0ZWQgd2l0aCB0aGlzIG1ldGhvZCByZWZlcmVuY2UKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGludCByZWZlcmVuY2VLaW5kKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIExhbWJkYVRvTWV0aG9kLnRoaXMucmVmZXJlbmNlS2luZCh0cmVlLnN5bSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGJvb2xlYW4gbmVlZHNWYXJBcmdzQ29udmVyc2lvbigpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0cmVlLnZhcmFyZ3NFbGVtZW50ICE9IG51bGw7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBAcmV0dXJuIElzIHRoaXMgYW4gYXJyYXkgb3BlcmF0aW9uIGxpa2UgY2xvbmUoKQogICAgICAgICAgICAgKi8KICAgICAgICAgICAgYm9vbGVhbiBpc0FycmF5T3AoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJlZS5zeW0ub3duZXIgPT0gc3ltcy5hcnJheUNsYXNzOwogICAgICAgICAgICB9CgogICAgICAgICAgICBib29sZWFuIHJlY2VpdmVyQWNjZXNzaWJsZSgpIHsKICAgICAgICAgICAgICAgIC8vaGFjayBuZWVkZWQgdG8gd29ya2Fyb3VuZCAyOTIgYnVnICg3MDg3NjU4KQogICAgICAgICAgICAgICAgLy93aGVuIDI5MiBpc3N1ZSBpcyBmaXhlZCB3ZSBzaG91bGQgcmVtb3ZlIHRoaXMgYW5kIGNoYW5nZSB0aGUgYmFja2VuZAogICAgICAgICAgICAgICAgLy9jb2RlIHRvIGFsd2F5cyBnZW5lcmF0ZSBhIG1ldGhvZCBoYW5kbGUgdG8gYW4gYWNjZXNzaWJsZSBtZXRob2QKICAgICAgICAgICAgICAgIHJldHVybiB0cmVlLm93bmVyQWNjZXNzaWJsZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIFRoZSBWTSBkb2VzIG5vdCBzdXBwb3J0IGFjY2VzcyBhY3Jvc3MgbmVzdGVkIGNsYXNzZXMgKDgwMTAzMTkpLgogICAgICAgICAgICAgKiBXZXJlIHRoYXQgZXZlciB0byBjaGFuZ2UsIHRoaXMgc2hvdWxkIGJlIHJlbW92ZWQuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBib29sZWFuIGlzUHJpdmF0ZUluT3RoZXJDbGFzcygpIHsKICAgICAgICAgICAgICAgIHJldHVybiAgKHRyZWUuc3ltLmZsYWdzKCkgJiBQUklWQVRFKSAhPSAwICYmCiAgICAgICAgICAgICAgICAgICAgICAgICF0eXBlcy5pc1NhbWVUeXBlKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlcy5lcmFzdXJlKHRyZWUuc3ltLmVuY2xDbGFzcygpLmFzVHlwZSgpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZXMuZXJhc3VyZShvd25lci5lbmNsQ2xhc3MoKS5hc1R5cGUoKSkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBib29sZWFuIGlzUHJvdGVjdGVkSW5TdXBlckNsYXNzT2ZFbmNsb3NpbmdDbGFzc0luT3RoZXJQYWNrYWdlKCkgewogICAgICAgICAgICAgICAgcmV0dXJuICgodHJlZS5zeW0uZmxhZ3MoKSAmIFBST1RFQ1RFRCkgIT0gMCAmJgogICAgICAgICAgICAgICAgICAgICAgICB0cmVlLnN5bS5wYWNrZ2UoKSAhPSBvd25lci5wYWNrZ2UoKSAmJgogICAgICAgICAgICAgICAgICAgICAgICAhb3duZXIuZW5jbENsYXNzKCkuaXNTdWJDbGFzcyh0cmVlLnN5bS5vd25lciwgdHlwZXMpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIFNpZ25hdHVyZSBwb2x5bW9ycGhpYyBtZXRob2RzIG5lZWQgc3BlY2lhbCBoYW5kbGluZy4KICAgICAgICAgICAgICogZS5nLiBNZXRob2RIYW5kbGUuaW52b2tlKCkgTWV0aG9kSGFuZGxlLmludm9rZUV4YWN0KCkKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGZpbmFsIGJvb2xlYW4gaXNTaWduYXR1cmVQb2x5bW9ycGhpYygpIHsKICAgICAgICAgICAgICAgIHJldHVybiAgdHJlZS5zeW0ua2luZCA9PSBNVEggJiYKICAgICAgICAgICAgICAgICAgICAgICAgdHlwZXMuaXNTaWduYXR1cmVQb2x5bW9ycGhpYygoTWV0aG9kU3ltYm9sKXRyZWUuc3ltKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIEVyYXN1cmUgZGVzdHJveXMgdGhlIGltcGxlbWVudGF0aW9uIHBhcmFtZXRlciBzdWJ0eXBlCiAgICAgICAgICAgICAqIHJlbGF0aW9uc2hpcCBmb3IgaW50ZXJzZWN0aW9uIHR5cGVzCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBib29sZWFuIGludGVyZmFjZVBhcmFtZXRlcklzSW50ZXJzZWN0aW9uVHlwZSgpIHsKICAgICAgICAgICAgICAgIExpc3Q8VHlwZT4gdGwgPSB0cmVlLmdldERlc2NyaXB0b3JUeXBlKHR5cGVzKS5nZXRQYXJhbWV0ZXJUeXBlcygpOwogICAgICAgICAgICAgICAgZm9yICg7IHRsLm5vbkVtcHR5KCk7IHRsID0gdGwudGFpbCkgewogICAgICAgICAgICAgICAgICAgIFR5cGUgcHQgPSB0bC5oZWFkOwogICAgICAgICAgICAgICAgICAgIGlmIChwdC5nZXRLaW5kKCkgPT0gVHlwZUtpbmQuVFlQRVZBUikgewogICAgICAgICAgICAgICAgICAgICAgICBUeXBlVmFyIHR2ID0gKFR5cGVWYXIpIHB0OwogICAgICAgICAgICAgICAgICAgICAgICBpZiAodHYuYm91bmQuZ2V0S2luZCgpID09IFR5cGVLaW5kLklOVEVSU0VDVElPTikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBEb2VzIHRoaXMgcmVmZXJlbmNlIG5lZWQgdG8gYmUgY29udmVydGVkIHRvIGEgbGFtYmRhCiAgICAgICAgICAgICAqIChpLmUuIHZhciBhcmdzIG5lZWQgdG8gYmUgZXhwYW5kZWQgb3IgInN1cGVyIiBpcyB1c2VkKQogICAgICAgICAgICAgKi8KICAgICAgICAgICAgZmluYWwgYm9vbGVhbiBuZWVkc0NvbnZlcnNpb25Ub0xhbWJkYSgpIHsKICAgICAgICAgICAgICAgIHJldHVybiBpbnRlcmZhY2VQYXJhbWV0ZXJJc0ludGVyc2VjdGlvblR5cGUoKSB8fAogICAgICAgICAgICAgICAgICAgICAgICBpc1N1cGVyIHx8CiAgICAgICAgICAgICAgICAgICAgICAgIG5lZWRzVmFyQXJnc0NvbnZlcnNpb24oKSB8fAogICAgICAgICAgICAgICAgICAgICAgICBpc0FycmF5T3AoKSB8fAogICAgICAgICAgICAgICAgICAgICAgICBpc1ByaXZhdGVJbk90aGVyQ2xhc3MoKSB8fAogICAgICAgICAgICAgICAgICAgICAgICBpc1Byb3RlY3RlZEluU3VwZXJDbGFzc09mRW5jbG9zaW5nQ2xhc3NJbk90aGVyUGFja2FnZSgpIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICFyZWNlaXZlckFjY2Vzc2libGUoKSB8fAogICAgICAgICAgICAgICAgICAgICAgICAodHJlZS5nZXRNb2RlKCkgPT0gUmVmZXJlbmNlTW9kZS5ORVcgJiYKICAgICAgICAgICAgICAgICAgICAgICAgICB0cmVlLmtpbmQgIT0gUmVmZXJlbmNlS2luZC5BUlJBWV9DVE9SICYmCiAgICAgICAgICAgICAgICAgICAgICAgICAgKHRyZWUuc3ltLm93bmVyLmlzTG9jYWwoKSB8fCB0cmVlLnN5bS5vd25lci5pc0lubmVyKCkpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgVHlwZSBnZW5lcmF0ZWRSZWZTaWcoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHlwZXMuZXJhc3VyZSh0cmVlLnN5bS50eXBlKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgVHlwZSBicmlkZ2VkUmVmU2lnKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHR5cGVzLmVyYXN1cmUodHlwZXMuZmluZERlc2NyaXB0b3JTeW1ib2wodHJlZS50YXJnZXRzLmhlYWQudHN5bSkudHlwZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICAvLyA8L2VkaXRvci1mb2xkPgoKICAgIC8qCiAgICAgKiBUaGVzZSBrZXlzIHByb3ZpZGUgbWFwcGluZ3MgZm9yIHZhcmlvdXMgdHJhbnNsYXRlZCBsYW1iZGEgc3ltYm9scwogICAgICogYW5kIHRoZSBwcmV2YWlsaW5nIG9yZGVyIG11c3QgYmUgbWFpbnRhaW5lZC4KICAgICAqLwogICAgZW51bSBMYW1iZGFTeW1ib2xLaW5kIHsKICAgICAgICBQQVJBTSwgICAgICAgICAgLy8gb3JpZ2luYWwgdG8gdHJhbnNsYXRlZCBsYW1iZGEgcGFyYW1ldGVycwogICAgICAgIExPQ0FMX1ZBUiwgICAgICAvLyBvcmlnaW5hbCB0byB0cmFuc2xhdGVkIGxhbWJkYSBsb2NhbHMKICAgICAgICBDQVBUVVJFRF9WQVIsICAgLy8gdmFyaWFibGVzIGluIGVuY2xvc2luZyBzY29wZSB0byB0cmFuc2xhdGVkIHN5bnRoZXRpYyBwYXJhbWV0ZXJzCiAgICAgICAgQ0FQVFVSRURfVEhJUywgIC8vIGNsYXNzIHN5bWJvbHMgdG8gdHJhbnNsYXRlZCBzeW50aGV0aWMgcGFyYW1ldGVycyAoZm9yIGNhcHR1cmVkIG1lbWJlciBhY2Nlc3MpCiAgICAgICAgQ0FQVFVSRURfT1VURVJfVEhJUywgLy8gdXNlZCB3aGVuIGB0aGlzJyBjYXB0dXJlIGlzIGlsbGVnYWwsIGJ1dCBvdXRlciB0aGlzIGNhcHR1cmUgaXMgbGVnaXQgKEpESy04MTI5NzQwKQogICAgICAgIFRZUEVfVkFSICAgICAgIC8vIG9yaWdpbmFsIHRvIHRyYW5zbGF0ZWQgbGFtYmRhIHR5cGUgdmFyaWFibGVzCiAgICB9CgogICAgLyoqCiAgICAgKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAgICAgKiBTaWduYXR1cmUgR2VuZXJhdGlvbgogICAgICogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogICAgICovCgogICAgcHJpdmF0ZSBTdHJpbmcgdHlwZVNpZyhUeXBlIHR5cGUpIHsKICAgICAgICBMMk1TaWduYXR1cmVHZW5lcmF0b3Igc2cgPSBuZXcgTDJNU2lnbmF0dXJlR2VuZXJhdG9yKCk7CiAgICAgICAgc2cuYXNzZW1ibGVTaWcodHlwZSk7CiAgICAgICAgcmV0dXJuIHNnLnRvU3RyaW5nKCk7CiAgICB9CgogICAgcHJpdmF0ZSBTdHJpbmcgY2xhc3NTaWcoVHlwZSB0eXBlKSB7CiAgICAgICAgTDJNU2lnbmF0dXJlR2VuZXJhdG9yIHNnID0gbmV3IEwyTVNpZ25hdHVyZUdlbmVyYXRvcigpOwogICAgICAgIHNnLmFzc2VtYmxlQ2xhc3NTaWcodHlwZSk7CiAgICAgICAgcmV0dXJuIHNnLnRvU3RyaW5nKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBTaWduYXR1cmUgR2VuZXJhdGlvbgogICAgICovCiAgICBwcml2YXRlIGNsYXNzIEwyTVNpZ25hdHVyZUdlbmVyYXRvciBleHRlbmRzIFR5cGVzLlNpZ25hdHVyZUdlbmVyYXRvciB7CgogICAgICAgIC8qKgogICAgICAgICAqIEFuIG91dHB1dCBidWZmZXIgZm9yIHR5cGUgc2lnbmF0dXJlcy4KICAgICAgICAgKi8KICAgICAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKCiAgICAgICAgTDJNU2lnbmF0dXJlR2VuZXJhdG9yKCkgewogICAgICAgICAgICBzdXBlcih0eXBlcyk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwcm90ZWN0ZWQgdm9pZCBhcHBlbmQoY2hhciBjaCkgewogICAgICAgICAgICBzYi5hcHBlbmQoY2gpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHJvdGVjdGVkIHZvaWQgYXBwZW5kKGJ5dGVbXSBiYSkgewogICAgICAgICAgICBzYi5hcHBlbmQobmV3IFN0cmluZyhiYSkpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHJvdGVjdGVkIHZvaWQgYXBwZW5kKE5hbWUgbmFtZSkgewogICAgICAgICAgICBzYi5hcHBlbmQobmFtZS50b1N0cmluZygpKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CiAgICAgICAgICAgIHJldHVybiBzYi50b1N0cmluZygpOwogICAgICAgIH0KICAgIH0KfQpQSwMECgAACAAABjupSopN6NAIUAAACFAAAC4AAABjb20vc3VuL3Rvb2xzL2phdmFjL2NvbXAvSW5mZXJlbmNlQ29udGV4dC5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDE1LCAyMDE2LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuamF2YWMuY29tcDsKCmltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbnM7CmltcG9ydCBqYXZhLnV0aWwuRW51bVNldDsKaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOwppbXBvcnQgamF2YS51dGlsLkhhc2hTZXQ7CmltcG9ydCBqYXZhLnV0aWwuTGlua2VkSGFzaE1hcDsKaW1wb3J0IGphdmEudXRpbC5NYXA7CmltcG9ydCBqYXZhLnV0aWwuU2V0OwoKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5UeXBlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlR5cGUuQXJyYXlUeXBlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlR5cGUuQ2xhc3NUeXBlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlR5cGUuVHlwZVZhcjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5UeXBlLlVuZGV0VmFyOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlR5cGUuVW5kZXRWYXIuSW5mZXJlbmNlQm91bmQ7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuVHlwZS5XaWxkY2FyZFR5cGU7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuVHlwZVRhZzsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5UeXBlczsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29tcC5JbmZlci5GcmVlVHlwZUxpc3RlbmVyOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb21wLkluZmVyLkdyYXBoU29sdmVyOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb21wLkluZmVyLkdyYXBoU3RyYXRlZ3k7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvbXAuSW5mZXIuSW5mZXJlbmNlRXhjZXB0aW9uOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb21wLkluZmVyLkluZmVyZW5jZVN0ZXA7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuSkNUcmVlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkFzc2VydDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5GaWx0ZXI7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuTGlzdDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5MaXN0QnVmZmVyOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLldhcm5lcjsKCi8qKgogKiBBbiBpbmZlcmVuY2UgY29udGV4dCBrZWVwcyB0cmFjayBvZiB0aGUgc2V0IG9mIHZhcmlhYmxlcyB0aGF0IGFyZSBmcmVlCiAqIGluIHRoZSBjdXJyZW50IGNvbnRleHQuIEl0IHByb3ZpZGVzIHV0aWxpdHkgbWV0aG9kcyBmb3Igb3BlbmluZy9jbG9zaW5nCiAqIHR5cGVzIHRvIHRoZWlyIGNvcnJlc3BvbmRpbmcgZnJlZS9jbG9zZWQgZm9ybXMuIEl0IGFsc28gcHJvdmlkZSBob29rcyBmb3IKICogYXR0YWNoaW5nIGRlZmVycmVkIHBvc3QtaW5mZXJlbmNlIGFjdGlvbiAoc2VlIFBlbmRpbmdDaGVjaykuIEZpbmFsbHksCiAqIGl0IGNhbiBiZSB1c2VkIGFzIGFuIGVudHJ5IHBvaW50IGZvciBwZXJmb3JtaW5nIHVwcGVyL2xvd2VyIGJvdW5kIGluZmVyZW5jZQogKiAoc2VlIEluZmVyZW5jZUtpbmQpLgogKgogKiA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yCiAqIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj4KICovCnB1YmxpYyBjbGFzcyBJbmZlcmVuY2VDb250ZXh0IHsKCiAgICAvKiogbGlzdCBvZiBpbmZlcmVuY2UgdmFycyBhcyB1bmRldCB2YXJzICovCiAgICBMaXN0PFR5cGU+IHVuZGV0dmFyczsKCiAgICBUeXBlIHVwZGF0ZShUeXBlIHQpIHsKICAgICAgICByZXR1cm4gdDsKICAgIH0KCiAgICAvKiogbGlzdCBvZiBpbmZlcmVuY2UgdmFycyBpbiB0aGlzIGNvbnRleHQgKi8KICAgIExpc3Q8VHlwZT4gaW5mZXJlbmNldmFyczsKCiAgICBNYXA8RnJlZVR5cGVMaXN0ZW5lciwgTGlzdDxUeXBlPj4gZnJlZVR5cGVMaXN0ZW5lcnMgPSBuZXcgTGlua2VkSGFzaE1hcDw+KCk7CgogICAgVHlwZXMgdHlwZXM7CiAgICBJbmZlciBpbmZlcjsKCiAgICBwdWJsaWMgSW5mZXJlbmNlQ29udGV4dChJbmZlciBpbmZlciwgTGlzdDxUeXBlPiBpbmZlcmVuY2V2YXJzKSB7CiAgICAgICAgdGhpcyhpbmZlciwgaW5mZXJlbmNldmFycywgaW5mZXJlbmNldmFycy5tYXAoaW5mZXIuZnJvbVR5cGVWYXJGdW4pKTsKICAgIH0KCiAgICBwdWJsaWMgSW5mZXJlbmNlQ29udGV4dChJbmZlciBpbmZlciwgTGlzdDxUeXBlPiBpbmZlcmVuY2V2YXJzLCBMaXN0PFR5cGU+IHVuZGV0dmFycykgewogICAgICAgIHRoaXMuaW5mZXJlbmNldmFycyA9IGluZmVyZW5jZXZhcnM7CiAgICAgICAgdGhpcy51bmRldHZhcnMgPSB1bmRldHZhcnM7CiAgICAgICAgdGhpcy5pbmZlciA9IGluZmVyOwogICAgICAgIHRoaXMudHlwZXMgPSBpbmZlci50eXBlczsKICAgIH0KCiAgICAvKioKICAgICAqIGFkZCBhIG5ldyBpbmZlcmVuY2UgdmFyIHRvIHRoaXMgaW5mZXJlbmNlIGNvbnRleHQKICAgICAqLwogICAgdm9pZCBhZGRWYXIoVHlwZVZhciB0KSB7CiAgICAgICAgdGhpcy51bmRldHZhcnMgPSB0aGlzLnVuZGV0dmFycy5wcmVwZW5kKGluZmVyLmZyb21UeXBlVmFyRnVuLmFwcGx5KHQpKTsKICAgICAgICB0aGlzLmluZmVyZW5jZXZhcnMgPSB0aGlzLmluZmVyZW5jZXZhcnMucHJlcGVuZCh0KTsKICAgIH0KCiAgICAvKioKICAgICAqIHJldHVybnMgdGhlIGxpc3Qgb2YgZnJlZSB2YXJpYWJsZXMgKGFzIHR5cGUtdmFyaWFibGVzKSBpbiB0aGlzCiAgICAgKiBpbmZlcmVuY2UgY29udGV4dAogICAgICovCiAgICBMaXN0PFR5cGU+IGluZmVyZW5jZVZhcnMoKSB7CiAgICAgICAgcmV0dXJuIGluZmVyZW5jZXZhcnM7CiAgICB9CgogICAgLyoqCiAgICAgKiByZXR1cm5zIHRoZSBsaXN0IG9mIHVuZGV0ZXJtaW5lZCB2YXJpYWJsZXMgaW4gdGhpcyBpbmZlcmVuY2UgY29udGV4dAogICAgICovCiAgICBwdWJsaWMgTGlzdDxUeXBlPiB1bmRldFZhcnMoKSB7CiAgICAgICAgcmV0dXJuIHVuZGV0dmFyczsKICAgIH0KCiAgICAvKioKICAgICAqIHJldHVybnMgdGhlIGxpc3Qgb2YgdW5pbnN0YW50aWF0ZWQgdmFyaWFibGVzIChhcyB0eXBlLXZhcmlhYmxlcykgaW4gdGhpcwogICAgICogaW5mZXJlbmNlIGNvbnRleHQKICAgICAqLwogICAgTGlzdDxUeXBlPiByZXN0dmFycygpIHsKICAgICAgICByZXR1cm4gZmlsdGVyVmFycyh1diAtPiB1di5nZXRJbnN0KCkgPT0gbnVsbCk7CiAgICB9CgogICAgLyoqCiAgICAgKiByZXR1cm5zIHRoZSBsaXN0IG9mIGluc3RhbnRpYXRlZCB2YXJpYWJsZXMgKGFzIHR5cGUtdmFyaWFibGVzKSBpbiB0aGlzCiAgICAgKiBpbmZlcmVuY2UgY29udGV4dAogICAgICovCiAgICBMaXN0PFR5cGU+IGluc3R2YXJzKCkgewogICAgICAgIHJldHVybiBmaWx0ZXJWYXJzKHV2IC0+IHV2LmdldEluc3QoKSAhPSBudWxsKTsKICAgIH0KCiAgICAvKioKICAgICAqIEdldCBsaXN0IG9mIGJvdW5kZWQgaW5mZXJlbmNlIHZhcmlhYmxlcyAod2hlcmUgYm91bmQgaXMgb3RoZXIgdGhhbgogICAgICogZGVjbGFyZWQgYm91bmRzKS4KICAgICAqLwogICAgZmluYWwgTGlzdDxUeXBlPiBib3VuZGVkVmFycygpIHsKICAgICAgICByZXR1cm4gZmlsdGVyVmFycyh1diAtPiB1di5nZXRCb3VuZHMoSW5mZXJlbmNlQm91bmQuVVBQRVIpCiAgICAgICAgICAgICAgICAgLmRpZmYodXYuZ2V0RGVjbGFyZWRCb3VuZHMoKSkKICAgICAgICAgICAgICAgICAuYXBwZW5kTGlzdCh1di5nZXRCb3VuZHMoSW5mZXJlbmNlQm91bmQuRVEsIEluZmVyZW5jZUJvdW5kLkxPV0VSKSkubm9uRW1wdHkoKSk7CiAgICB9CgogICAgLyogUmV0dXJucyB0aGUgY29ycmVzcG9uZGluZyBpbmZlcmVuY2UgdmFyaWFibGVzLgogICAgICovCiAgICBwcml2YXRlIExpc3Q8VHlwZT4gZmlsdGVyVmFycyhGaWx0ZXI8VW5kZXRWYXI+IGZ1KSB7CiAgICAgICAgTGlzdEJ1ZmZlcjxUeXBlPiByZXMgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgZm9yIChUeXBlIHQgOiB1bmRldHZhcnMpIHsKICAgICAgICAgICAgVW5kZXRWYXIgdXYgPSAoVW5kZXRWYXIpdDsKICAgICAgICAgICAgaWYgKGZ1LmFjY2VwdHModXYpKSB7CiAgICAgICAgICAgICAgICByZXMuYXBwZW5kKHV2LnF0eXBlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzLnRvTGlzdCgpOwogICAgfQoKICAgIC8qKgogICAgICogaXMgdGhpcyB0eXBlIGZyZWU/CiAgICAgKi8KICAgIGZpbmFsIGJvb2xlYW4gZnJlZShUeXBlIHQpIHsKICAgICAgICByZXR1cm4gdC5jb250YWluc0FueShpbmZlcmVuY2V2YXJzKTsKICAgIH0KCiAgICBmaW5hbCBib29sZWFuIGZyZWUoTGlzdDxUeXBlPiB0cykgewogICAgICAgIGZvciAoVHlwZSB0IDogdHMpIHsKICAgICAgICAgICAgaWYgKGZyZWUodCkpIHJldHVybiB0cnVlOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgbGlzdCBvZiBmcmVlIHZhcmlhYmxlcyBpbiBhIGdpdmVuIHR5cGUKICAgICAqLwogICAgZmluYWwgTGlzdDxUeXBlPiBmcmVlVmFyc0luKFR5cGUgdCkgewogICAgICAgIExpc3RCdWZmZXI8VHlwZT4gYnVmID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgIGZvciAoVHlwZSBpdiA6IGluZmVyZW5jZVZhcnMoKSkgewogICAgICAgICAgICBpZiAodC5jb250YWlucyhpdikpIHsKICAgICAgICAgICAgICAgIGJ1Zi5hZGQoaXYpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWYudG9MaXN0KCk7CiAgICB9CgogICAgZmluYWwgTGlzdDxUeXBlPiBmcmVlVmFyc0luKExpc3Q8VHlwZT4gdHMpIHsKICAgICAgICBMaXN0QnVmZmVyPFR5cGU+IGJ1ZiA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICBmb3IgKFR5cGUgdCA6IHRzKSB7CiAgICAgICAgICAgIGJ1Zi5hcHBlbmRMaXN0KGZyZWVWYXJzSW4odCkpOwogICAgICAgIH0KICAgICAgICBMaXN0QnVmZmVyPFR5cGU+IGJ1ZjIgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgZm9yIChUeXBlIHQgOiBidWYpIHsKICAgICAgICAgICAgaWYgKCFidWYyLmNvbnRhaW5zKHQpKSB7CiAgICAgICAgICAgICAgICBidWYyLmFkZCh0KTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVmMi50b0xpc3QoKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJlcGxhY2UgYWxsIGZyZWUgdmFyaWFibGVzIGluIGEgZ2l2ZW4gdHlwZSB3aXRoIGNvcnJlc3BvbmRpbmcKICAgICAqIHVuZGV0IHZhcnMgKHVzZWQgYWhlYWQgb2Ygc3VidHlwaW5nL2NvbXBhdGliaWxpdHkgY2hlY2tzIHRvIGFsbG93IHByb3BhZ2F0aW9uCiAgICAgKiBvZiBpbmZlcmVuY2UgY29uc3RyYWludHMpLgogICAgICovCiAgICBwdWJsaWMgZmluYWwgVHlwZSBhc1VuZGV0VmFyKFR5cGUgdCkgewogICAgICAgIHJldHVybiB0eXBlcy5zdWJzdCh0LCBpbmZlcmVuY2V2YXJzLCB1bmRldHZhcnMpOwogICAgfQoKICAgIGZpbmFsIExpc3Q8VHlwZT4gYXNVbmRldFZhcnMoTGlzdDxUeXBlPiB0cykgewogICAgICAgIExpc3RCdWZmZXI8VHlwZT4gYnVmID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgIGZvciAoVHlwZSB0IDogdHMpIHsKICAgICAgICAgICAgYnVmLmFwcGVuZChhc1VuZGV0VmFyKHQpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1Zi50b0xpc3QoKTsKICAgIH0KCiAgICBMaXN0PFR5cGU+IGluc3RUeXBlcygpIHsKICAgICAgICBMaXN0QnVmZmVyPFR5cGU+IGJ1ZiA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICBmb3IgKFR5cGUgdCA6IHVuZGV0dmFycykgewogICAgICAgICAgICBVbmRldFZhciB1diA9IChVbmRldFZhcil0OwogICAgICAgICAgICBidWYuYXBwZW5kKHV2LmdldEluc3QoKSAhPSBudWxsID8gdXYuZ2V0SW5zdCgpIDogdXYucXR5cGUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVmLnRvTGlzdCgpOwogICAgfQoKICAgIC8qKgogICAgICogUmVwbGFjZSBhbGwgZnJlZSB2YXJpYWJsZXMgaW4gYSBnaXZlbiB0eXBlIHdpdGggY29ycmVzcG9uZGluZwogICAgICogaW5zdGFudGlhdGVkIHR5cGVzIC0gaWYgb25lIG9yIG1vcmUgZnJlZSB2YXJpYWJsZSBoYXMgbm90IGJlZW4KICAgICAqIGZ1bGx5IGluc3RhbnRpYXRlZCwgaXQgd2lsbCBzdGlsbCBiZSBhdmFpbGFibGUgaW4gdGhlIHJlc3VsdGluZyB0eXBlLgogICAgICovCiAgICBUeXBlIGFzSW5zdFR5cGUoVHlwZSB0KSB7CiAgICAgICAgcmV0dXJuIHR5cGVzLnN1YnN0KHQsIGluZmVyZW5jZXZhcnMsIGluc3RUeXBlcygpKTsKICAgIH0KCiAgICBMaXN0PFR5cGU+IGFzSW5zdFR5cGVzKExpc3Q8VHlwZT4gdHMpIHsKICAgICAgICBMaXN0QnVmZmVyPFR5cGU+IGJ1ZiA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICBmb3IgKFR5cGUgdCA6IHRzKSB7CiAgICAgICAgICAgIGJ1Zi5hcHBlbmQoYXNJbnN0VHlwZSh0KSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWYudG9MaXN0KCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBBZGQgY3VzdG9tIGhvb2sgZm9yIHBlcmZvcm1pbmcgcG9zdC1pbmZlcmVuY2UgYWN0aW9uCiAgICAgKi8KICAgIHZvaWQgYWRkRnJlZVR5cGVMaXN0ZW5lcihMaXN0PFR5cGU+IHR5cGVzLCBGcmVlVHlwZUxpc3RlbmVyIGZ0bCkgewogICAgICAgIGZyZWVUeXBlTGlzdGVuZXJzLnB1dChmdGwsIGZyZWVWYXJzSW4odHlwZXMpKTsKICAgIH0KCiAgICAvKioKICAgICAqIE1hcmsgdGhlIGluZmVyZW5jZSBjb250ZXh0IGFzIGNvbXBsZXRlIGFuZCB0cmlnZ2VyIGV2YWx1YXRpb24KICAgICAqIG9mIGFsbCBkZWZlcnJlZCBjaGVja3MuCiAgICAgKi8KICAgIHZvaWQgbm90aWZ5Q2hhbmdlKCkgewogICAgICAgIG5vdGlmeUNoYW5nZShpbmZlcmVuY2V2YXJzLmRpZmYocmVzdHZhcnMoKSkpOwogICAgfQoKICAgIHZvaWQgbm90aWZ5Q2hhbmdlKExpc3Q8VHlwZT4gaW5mZXJyZWRWYXJzKSB7CiAgICAgICAgSW5mZXJlbmNlRXhjZXB0aW9uIHRocm93bkV4ID0gbnVsbDsKICAgICAgICBmb3IgKE1hcC5FbnRyeTxGcmVlVHlwZUxpc3RlbmVyLCBMaXN0PFR5cGU+PiBlbnRyeSA6CiAgICAgICAgICAgICAgICBuZXcgTGlua2VkSGFzaE1hcDw+KGZyZWVUeXBlTGlzdGVuZXJzKS5lbnRyeVNldCgpKSB7CiAgICAgICAgICAgIGlmICghVHlwZS5jb250YWluc0FueShlbnRyeS5nZXRWYWx1ZSgpLCBpbmZlcmVuY2V2YXJzLmRpZmYoaW5mZXJyZWRWYXJzKSkpIHsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgZW50cnkuZ2V0S2V5KCkudHlwZXNJbmZlcnJlZCh0aGlzKTsKICAgICAgICAgICAgICAgICAgICBmcmVlVHlwZUxpc3RlbmVycy5yZW1vdmUoZW50cnkuZ2V0S2V5KCkpOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoSW5mZXJlbmNlRXhjZXB0aW9uIGV4KSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHRocm93bkV4ID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3duRXggPSBleDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLy9pbmZlcmVuY2UgZXhjZXB0aW9uIG11bHRpcGxleGluZyAtIHByZXNlbnQgYW55IGluZmVyZW5jZSBleGNlcHRpb24KICAgICAgICAvL3Rocm93biB3aGVuIHByb2Nlc3NpbmcgbGlzdGVuZXJzIGFzIGEgc2luZ2xlIG9uZQogICAgICAgIGlmICh0aHJvd25FeCAhPSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IHRocm93bkV4OwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFNhdmUgdGhlIHN0YXRlIG9mIHRoaXMgaW5mZXJlbmNlIGNvbnRleHQKICAgICAqLwogICAgcHVibGljIExpc3Q8VHlwZT4gc2F2ZSgpIHsKICAgICAgICBMaXN0QnVmZmVyPFR5cGU+IGJ1ZiA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICBmb3IgKFR5cGUgdCA6IHVuZGV0dmFycykgewogICAgICAgICAgICBidWYuYWRkKCgoVW5kZXRWYXIpdCkuZHVwKGluZmVyLnR5cGVzKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWYudG9MaXN0KCk7CiAgICB9CgogICAgLyoqIFJlc3RvcmUgdGhlIHN0YXRlIG9mIHRoaXMgaW5mZXJlbmNlIGNvbnRleHQgdG8gdGhlIHByZXZpb3VzIGtub3duIGNoZWNrcG9pbnQuCiAgICAqICBDb25zaWRlciB0aGF0IHRoZSBudW1iZXIgb2Ygc2F2ZWQgdW5kZXRlcm1pbmVkIHZhcmlhYmxlcyBjYW4gYmUgZGlmZmVyZW50IHRvIHRoZSBjdXJyZW50CiAgICAqICBhbW91bnQuIFRoaXMgaXMgYmVjYXVzZSBuZXcgY2FwdHVyZWQgdmFyaWFibGVzIGNvdWxkIGhhdmUgYmVlbiBhZGRlZC4KICAgICovCiAgICBwdWJsaWMgdm9pZCByb2xsYmFjayhMaXN0PFR5cGU+IHNhdmVkX3VuZGV0KSB7CiAgICAgICAgQXNzZXJ0LmNoZWNrKHNhdmVkX3VuZGV0ICE9IG51bGwpOwogICAgICAgIC8vcmVzdG9yZSBib3VuZHMgKG5vdGU6IHdlIG5lZWQgdG8gcHJlc2VydmUgdGhlIG9sZCBpbnN0YW5jZXMpCiAgICAgICAgTGlzdEJ1ZmZlcjxUeXBlPiBuZXdVbmRldFZhcnMgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgTGlzdEJ1ZmZlcjxUeXBlPiBuZXdJbmZlcmVuY2VWYXJzID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgIHdoaWxlIChzYXZlZF91bmRldC5ub25FbXB0eSgpICYmIHVuZGV0dmFycy5ub25FbXB0eSgpKSB7CiAgICAgICAgICAgIFVuZGV0VmFyIHV2ID0gKFVuZGV0VmFyKXVuZGV0dmFycy5oZWFkOwogICAgICAgICAgICBVbmRldFZhciB1dl9zYXZlZCA9IChVbmRldFZhcilzYXZlZF91bmRldC5oZWFkOwogICAgICAgICAgICBpZiAodXYucXR5cGUgPT0gdXZfc2F2ZWQucXR5cGUpIHsKICAgICAgICAgICAgICAgIHV2X3NhdmVkLmR1cFRvKHV2LCB0eXBlcyk7CiAgICAgICAgICAgICAgICB1bmRldHZhcnMgPSB1bmRldHZhcnMudGFpbDsKICAgICAgICAgICAgICAgIHNhdmVkX3VuZGV0ID0gc2F2ZWRfdW5kZXQudGFpbDsKICAgICAgICAgICAgICAgIG5ld1VuZGV0VmFycy5hZGQodXYpOwogICAgICAgICAgICAgICAgbmV3SW5mZXJlbmNlVmFycy5hZGQodXYucXR5cGUpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdW5kZXR2YXJzID0gdW5kZXR2YXJzLnRhaWw7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgdW5kZXR2YXJzID0gbmV3VW5kZXRWYXJzLnRvTGlzdCgpOwogICAgICAgIGluZmVyZW5jZXZhcnMgPSBuZXdJbmZlcmVuY2VWYXJzLnRvTGlzdCgpOwogICAgfQoKICAgIC8qKgogICAgICogQ29weSB2YXJpYWJsZSBpbiB0aGlzIGluZmVyZW5jZSBjb250ZXh0IHRvIHRoZSBnaXZlbiBjb250ZXh0CiAgICAgKi8KICAgIHZvaWQgZHVwVG8oZmluYWwgSW5mZXJlbmNlQ29udGV4dCB0aGF0KSB7CiAgICAgICAgZHVwVG8odGhhdCwgZmFsc2UpOwogICAgfQoKICAgIHZvaWQgZHVwVG8oZmluYWwgSW5mZXJlbmNlQ29udGV4dCB0aGF0LCBib29sZWFuIGNsb25lKSB7CiAgICAgICAgdGhhdC5pbmZlcmVuY2V2YXJzID0gdGhhdC5pbmZlcmVuY2V2YXJzLmFwcGVuZExpc3QoaW5mZXJlbmNldmFycy5kaWZmKHRoYXQuaW5mZXJlbmNldmFycykpOwogICAgICAgIExpc3Q8VHlwZT4gdW5kZXRzVG9Qcm9wYWdhdGUgPSBjbG9uZSA/IHNhdmUoKSA6IHVuZGV0dmFyczsKICAgICAgICB0aGF0LnVuZGV0dmFycyA9IHRoYXQudW5kZXR2YXJzLmFwcGVuZExpc3QodW5kZXRzVG9Qcm9wYWdhdGUuZGlmZih0aGF0LnVuZGV0dmFycykpOyAvL3Byb3BhZ2F0ZSBjbG9uZWQgdW5kZXQhIQogICAgICAgIC8vc2V0IHVwIGxpc3RlbmVycyB0byBub3RpZnkgb3JpZ2luYWwgaW5mZXJlbmNlIGNvbnRleHRzIGFzCiAgICAgICAgLy9wcm9wYWdhdGVkIHZhcnMgYXJlIGluZmVycmVkIGluIG5ldyBjb250ZXh0CiAgICAgICAgZm9yIChUeXBlIHQgOiBpbmZlcmVuY2V2YXJzKSB7CiAgICAgICAgICAgIHRoYXQuZnJlZVR5cGVMaXN0ZW5lcnMucHV0KGluZmVyZW5jZUNvbnRleHQgLT4gSW5mZXJlbmNlQ29udGV4dC50aGlzLm5vdGlmeUNoYW5nZSgpLCBMaXN0Lm9mKHQpKTsKICAgICAgICB9CiAgICB9CgogICAgSW5mZXJlbmNlQ29udGV4dCBtaW4oTGlzdDxUeXBlPiByb290cywgYm9vbGVhbiBzaG91bGRTb2x2ZSwgV2FybmVyIHdhcm4pIHsKICAgICAgICBSZWFjaGFiaWxpdHlWaXNpdG9yIHJ2ID0gbmV3IFJlYWNoYWJpbGl0eVZpc2l0b3IoKTsKICAgICAgICBydi5zY2FuKHJvb3RzKTsKICAgICAgICBpZiAocnYubWluLnNpemUoKSA9PSBpbmZlcmVuY2V2YXJzLmxlbmd0aCgpKSB7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgTGlzdDxUeXBlPiBtaW5WYXJzID0gTGlzdC5mcm9tKHJ2Lm1pbik7CiAgICAgICAgTGlzdDxUeXBlPiByZWR1bmRhbnRWYXJzID0gaW5mZXJlbmNldmFycy5kaWZmKG1pblZhcnMpOwoKICAgICAgICAvL2NvbXB1dGUgbmV3IHVuZGV0IHZhcmlhYmxlcyAoYm91bmRzIGFzc29jaWF0ZWQgdG8gcmVkdW5kYW50IHZhcmlhYmxlcyBhcmUgZHJvcHBlZCkKICAgICAgICBMaXN0QnVmZmVyPFR5cGU+IG1pblVuZGV0VmFycyA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICBmb3IgKFR5cGUgbWluVmFyIDogbWluVmFycykgewogICAgICAgICAgICBVbmRldFZhciB1diA9IChVbmRldFZhcilhc1VuZGV0VmFyKG1pblZhcik7CiAgICAgICAgICAgIEFzc2VydC5jaGVjayh1di5pbmNvcnBvcmF0aW9uQWN0aW9ucy5zaXplKCkgPT0gMCk7CiAgICAgICAgICAgIFVuZGV0VmFyIHV2MiA9IG5ldyBVbmRldFZhcigoVHlwZVZhciltaW5WYXIsIGluZmVyLmluY29ycG9yYXRpb25FbmdpbmUoKSwgdHlwZXMpOwogICAgICAgICAgICBmb3IgKEluZmVyZW5jZUJvdW5kIGliIDogSW5mZXJlbmNlQm91bmQudmFsdWVzKCkpIHsKICAgICAgICAgICAgICAgIExpc3Q8VHlwZT4gbmV3Qm91bmRzID0gdXYuZ2V0Qm91bmRzKGliKS5zdHJlYW0oKQogICAgICAgICAgICAgICAgICAgICAgICAuZmlsdGVyKGIgLT4gIXJlZHVuZGFudFZhcnMuY29udGFpbnMoYikpCiAgICAgICAgICAgICAgICAgICAgICAgIC5jb2xsZWN0KExpc3QuY29sbGVjdG9yKCkpOwogICAgICAgICAgICAgICAgdXYyLnNldEJvdW5kcyhpYiwgbmV3Qm91bmRzKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBtaW5VbmRldFZhcnMuYWRkKHV2Mik7CiAgICAgICAgfQoKICAgICAgICAvL2NvbXB1dGUgbmV3IG1pbmltYWwgaW5mZXJlbmNlIGNvbnRleHQKICAgICAgICBJbmZlcmVuY2VDb250ZXh0IG1pbkNvbnRleHQgPSBuZXcgSW5mZXJlbmNlQ29udGV4dChpbmZlciwgbWluVmFycywgbWluVW5kZXRWYXJzLnRvTGlzdCgpKTsKICAgICAgICBmb3IgKFR5cGUgdCA6IG1pbkNvbnRleHQuaW5mZXJlbmNldmFycykgewogICAgICAgICAgICAvL2FkZCBsaXN0ZW5lciB0aGF0IGZvcndhcmRzIG5vdGlmaWNhdGlvbnMgdG8gb3JpZ2luYWwgY29udGV4dAogICAgICAgICAgICBtaW5Db250ZXh0LmFkZEZyZWVUeXBlTGlzdGVuZXIoTGlzdC5vZih0KSwgKGluZmVyZW5jZUNvbnRleHQpIC0+IHsKICAgICAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IGRlcFZhcnMgPSBMaXN0LmZyb20ocnYubWluTWFwLmdldCh0KSk7CiAgICAgICAgICAgICAgICAgICAgc29sdmUoZGVwVmFycywgd2Fybik7CiAgICAgICAgICAgICAgICAgICAgbm90aWZ5Q2hhbmdlKCk7CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KICAgICAgICBpZiAoc2hvdWxkU29sdmUpIHsKICAgICAgICAgICAgLy9zb2x2ZSBkZWZpbml0aXZlbHkgdW5yZWFjaGFibGUgdmFyaWFibGVzCiAgICAgICAgICAgIExpc3Q8VHlwZT4gdW5yZWFjaGFibGVWYXJzID0gcmVkdW5kYW50VmFycy5kaWZmKExpc3QuZnJvbShydi5lcXVpdikpOwogICAgICAgICAgICBzb2x2ZSh1bnJlYWNoYWJsZVZhcnMsIHdhcm4pOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWluQ29udGV4dDsKICAgIH0KCiAgICBjbGFzcyBSZWFjaGFiaWxpdHlWaXNpdG9yIGV4dGVuZHMgVHlwZXMuVW5hcnlWaXNpdG9yPFZvaWQ+IHsKCiAgICAgICAgU2V0PFR5cGU+IGVxdWl2ID0gbmV3IEhhc2hTZXQ8PigpOwogICAgICAgIFNldDxUeXBlPiBtaW4gPSBuZXcgSGFzaFNldDw+KCk7CiAgICAgICAgTWFwPFR5cGUsIFNldDxUeXBlPj4gbWluTWFwID0gbmV3IEhhc2hNYXA8PigpOwoKICAgICAgICB2b2lkIHNjYW4oTGlzdDxUeXBlPiByb290cykgewogICAgICAgICAgICByb290cy5zdHJlYW0oKS5mb3JFYWNoKHRoaXM6OnZpc2l0KTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBWb2lkIHZpc2l0VHlwZShUeXBlIHQsIFZvaWQgX3VudXNlZCkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBWb2lkIHZpc2l0VW5kZXRWYXIoVW5kZXRWYXIgdCwgVm9pZCBfdW51c2VkKSB7CiAgICAgICAgICAgIGlmIChtaW4uYWRkKHQucXR5cGUpKSB7CiAgICAgICAgICAgICAgICBTZXQ8VHlwZT4gZGVwcyA9IG1pbk1hcC5nZXRPckRlZmF1bHQodC5xdHlwZSwgbmV3IEhhc2hTZXQ8PihDb2xsZWN0aW9ucy5zaW5nbGV0b24odC5xdHlwZSkpKTsKICAgICAgICAgICAgICAgIGZvciAoSW5mZXJlbmNlQm91bmQgYm91bmRLaW5kIDogSW5mZXJlbmNlQm91bmQudmFsdWVzKCkpIHsKICAgICAgICAgICAgICAgICAgICBmb3IgKFR5cGUgYiA6IHQuZ2V0Qm91bmRzKGJvdW5kS2luZCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgVHlwZSB1bmRldCA9IGFzVW5kZXRWYXIoYik7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghdW5kZXQuaGFzVGFnKFR5cGVUYWcuVU5ERVRWQVIpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aXNpdCh1bmRldCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNFcXVpdih0LCBiLCBib3VuZEtpbmQpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXBzLmFkZChiKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVxdWl2LmFkZChiKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpc2l0KHVuZGV0KTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIG1pbk1hcC5wdXQodC5xdHlwZSwgZGVwcyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgVm9pZCB2aXNpdFdpbGRjYXJkVHlwZShXaWxkY2FyZFR5cGUgdCwgVm9pZCBfdW51c2VkKSB7CiAgICAgICAgICAgIHJldHVybiB2aXNpdCh0LnR5cGUpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFZvaWQgdmlzaXRUeXBlVmFyKFR5cGVWYXIgdCwgVm9pZCBhVm9pZCkgewogICAgICAgICAgICBUeXBlIHVuZGV0ID0gYXNVbmRldFZhcih0KTsKICAgICAgICAgICAgaWYgKHVuZGV0Lmhhc1RhZyhUeXBlVGFnLlVOREVUVkFSKSkgewogICAgICAgICAgICAgICAgdmlzaXRVbmRldFZhcigoVW5kZXRWYXIpdW5kZXQsIG51bGwpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFZvaWQgdmlzaXRBcnJheVR5cGUoQXJyYXlUeXBlIHQsIFZvaWQgX3VudXNlZCkgewogICAgICAgICAgICByZXR1cm4gdmlzaXQodC5lbGVtdHlwZSk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgVm9pZCB2aXNpdENsYXNzVHlwZShDbGFzc1R5cGUgdCwgVm9pZCBfdW51c2VkKSB7CiAgICAgICAgICAgIHZpc2l0KHQuZ2V0RW5jbG9zaW5nVHlwZSgpKTsKICAgICAgICAgICAgZm9yIChUeXBlIHRhcmcgOiB0LmdldFR5cGVBcmd1bWVudHMoKSkgewogICAgICAgICAgICAgICAgdmlzaXQodGFyZyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICBib29sZWFuIGlzRXF1aXYoVW5kZXRWYXIgZnJvbSwgVHlwZSB0LCBJbmZlcmVuY2VCb3VuZCBib3VuZEtpbmQpIHsKICAgICAgICAgICAgVW5kZXRWYXIgdXYgPSAoVW5kZXRWYXIpYXNVbmRldFZhcih0KTsKICAgICAgICAgICAgZm9yIChJbmZlcmVuY2VCb3VuZCBpYiA6IEluZmVyZW5jZUJvdW5kLnZhbHVlcygpKSB7CiAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IGIxID0gZnJvbS5nZXRCb3VuZHMoaWIpOwogICAgICAgICAgICAgICAgaWYgKGliID09IGJvdW5kS2luZCkgewogICAgICAgICAgICAgICAgICAgIGIxID0gYjEuZGlmZihMaXN0Lm9mKHQpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIExpc3Q8VHlwZT4gYjIgPSB1di5nZXRCb3VuZHMoaWIpOwogICAgICAgICAgICAgICAgaWYgKGliID09IGJvdW5kS2luZC5jb21wbGVtZW50KCkpIHsKICAgICAgICAgICAgICAgICAgICBiMiA9IGIyLmRpZmYoTGlzdC5vZihmcm9tLnF0eXBlKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoIWIxLmNvbnRhaW5zQWxsKGIyKSB8fCAhYjIuY29udGFpbnNBbGwoYjEpKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFNvbHZlIHdpdGggZ2l2ZW4gZ3JhcGggc3RyYXRlZ3kuCiAgICAgKi8KICAgIHByaXZhdGUgdm9pZCBzb2x2ZShHcmFwaFN0cmF0ZWd5IHNzLCBXYXJuZXIgd2FybikgewogICAgICAgIEdyYXBoU29sdmVyIHMgPSBpbmZlci5uZXcgR3JhcGhTb2x2ZXIodGhpcywgd2Fybik7CiAgICAgICAgcy5zb2x2ZShzcyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBTb2x2ZSBhbGwgdmFyaWFibGVzIGluIHRoaXMgY29udGV4dC4KICAgICAqLwogICAgcHVibGljIHZvaWQgc29sdmUoV2FybmVyIHdhcm4pIHsKICAgICAgICBzb2x2ZShpbmZlci5uZXcgTGVhZlNvbHZlcigpIHsKICAgICAgICAgICAgcHVibGljIGJvb2xlYW4gZG9uZSgpIHsKICAgICAgICAgICAgICAgIHJldHVybiByZXN0dmFycygpLmlzRW1wdHkoKTsKICAgICAgICAgICAgfQogICAgICAgIH0sIHdhcm4pOwogICAgfQoKICAgIC8qKgogICAgICogU29sdmUgYWxsIHZhcmlhYmxlcyBpbiB0aGUgZ2l2ZW4gbGlzdC4KICAgICAqLwogICAgcHVibGljIHZvaWQgc29sdmUoZmluYWwgTGlzdDxUeXBlPiB2YXJzLCBXYXJuZXIgd2FybikgewogICAgICAgIHNvbHZlKGluZmVyLm5ldyBCZXN0TGVhZlNvbHZlcih2YXJzKSB7CiAgICAgICAgICAgIHB1YmxpYyBib29sZWFuIGRvbmUoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gIWZyZWUoYXNJbnN0VHlwZXModmFycykpOwogICAgICAgICAgICB9CiAgICAgICAgfSwgd2Fybik7CiAgICB9CgogICAgLyoqCiAgICAgKiBTb2x2ZSBhdCBsZWFzdCBvbmUgdmFyaWFibGUgaW4gZ2l2ZW4gbGlzdC4KICAgICAqLwogICAgcHVibGljIHZvaWQgc29sdmVBbnkoTGlzdDxUeXBlPiB2YXJzVG9Tb2x2ZSwgV2FybmVyIHdhcm4pIHsKICAgICAgICBzb2x2ZShpbmZlci5uZXcgQmVzdExlYWZTb2x2ZXIodmFyc1RvU29sdmUuaW50ZXJzZWN0KHJlc3R2YXJzKCkpKSB7CiAgICAgICAgICAgIHB1YmxpYyBib29sZWFuIGRvbmUoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gaW5zdHZhcnMoKS5pbnRlcnNlY3QodmFyc1RvU29sdmUpLm5vbkVtcHR5KCk7CiAgICAgICAgICAgIH0KICAgICAgICB9LCB3YXJuKTsKICAgIH0KCiAgICAvKioKICAgICAqIEFwcGx5IGEgc2V0IG9mIGluZmVyZW5jZSBzdGVwcwogICAgICovCiAgICBwcml2YXRlIExpc3Q8VHlwZT4gc29sdmVCYXNpYyhFbnVtU2V0PEluZmVyZW5jZVN0ZXA+IHN0ZXBzKSB7CiAgICAgICAgcmV0dXJuIHNvbHZlQmFzaWMoaW5mZXJlbmNldmFycywgc3RlcHMpOwogICAgfQoKICAgIExpc3Q8VHlwZT4gc29sdmVCYXNpYyhMaXN0PFR5cGU+IHZhcnNUb1NvbHZlLCBFbnVtU2V0PEluZmVyZW5jZVN0ZXA+IHN0ZXBzKSB7CiAgICAgICAgTGlzdEJ1ZmZlcjxUeXBlPiBzb2x2ZWRWYXJzID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgIGZvciAoVHlwZSB0IDogdmFyc1RvU29sdmUuaW50ZXJzZWN0KHJlc3R2YXJzKCkpKSB7CiAgICAgICAgICAgIFVuZGV0VmFyIHV2ID0gKFVuZGV0VmFyKWFzVW5kZXRWYXIodCk7CiAgICAgICAgICAgIGZvciAoSW5mZXJlbmNlU3RlcCBzdGVwIDogc3RlcHMpIHsKICAgICAgICAgICAgICAgIGlmIChzdGVwLmFjY2VwdHModXYsIHRoaXMpKSB7CiAgICAgICAgICAgICAgICAgICAgdXYuc2V0SW5zdChzdGVwLnNvbHZlKHV2LCB0aGlzKSk7CiAgICAgICAgICAgICAgICAgICAgc29sdmVkVmFycy5hZGQodXYucXR5cGUpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBzb2x2ZWRWYXJzLnRvTGlzdCgpOwogICAgfQoKICAgIC8qKgogICAgICogSW5zdGFudGlhdGUgaW5mZXJlbmNlIHZhcmlhYmxlcyBpbiBsZWdhY3kgbW9kZSAoSkxTIDE1LjEyLjIuNywgMTUuMTIuMi44KS4KICAgICAqIER1cmluZyBvdmVybG9hZCByZXNvbHV0aW9uLCBpbnN0YW50aWF0aW9uIGlzIGRvbmUgYnkgZG9pbmcgYSBwYXJ0aWFsCiAgICAgKiBpbmZlcmVuY2UgcHJvY2VzcyB1c2luZyBlcS9sb3dlciBib3VuZCBpbnN0YW50aWF0aW9uLiBEdXJpbmcgY2hlY2ssCiAgICAgKiB3ZSBhbHNvIGluc3RhbnRpYXRlIGFueSByZW1haW5pbmcgdmFycyBieSByZXBlYXRlZGx5IHVzaW5nIGVxL3VwcGVyCiAgICAgKiBpbnN0YW50aWF0aW9uLCB1bnRpbCBhbGwgdmFyaWFibGVzIGFyZSBzb2x2ZWQuCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHNvbHZlTGVnYWN5KGJvb2xlYW4gcGFydGlhbCwgV2FybmVyIHdhcm4sIEVudW1TZXQ8SW5mZXJlbmNlU3RlcD4gc3RlcHMpIHsKICAgICAgICB3aGlsZSAodHJ1ZSkgewogICAgICAgICAgICBMaXN0PFR5cGU+IHNvbHZlZFZhcnMgPSBzb2x2ZUJhc2ljKHN0ZXBzKTsKICAgICAgICAgICAgaWYgKHJlc3R2YXJzKCkuaXNFbXB0eSgpIHx8IHBhcnRpYWwpIHsKICAgICAgICAgICAgICAgIC8vYWxsIHZhcmlhYmxlcyBoYXZlIGJlZW4gaW5zdGFudGlhdGVkIC0gZXhpdAogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gZWxzZSBpZiAoc29sdmVkVmFycy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICAgIC8vc29tZSB2YXJpYWJsZXMgY291bGQgbm90IGJlIGluc3RhbnRpYXRlZCBiZWNhdXNlIG9mIGN5Y2xlcyBpbgogICAgICAgICAgICAgICAgLy91cHBlciBib3VuZHMgLSBwcm92aWRlIGEgKHBvc3NpYmx5IHJlY3Vyc2l2ZSkgZGVmYXVsdCBpbnN0YW50aWF0aW9uCiAgICAgICAgICAgICAgICBpbmZlci5pbnN0YW50aWF0ZUFzVW5pbmZlcnJlZFZhcnMocmVzdHZhcnMoKSwgdGhpcyk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIC8vc29tZSB2YXJpYWJsZXMgaGF2ZSBiZWVuIGluc3RhbnRpYXRlZCAtIHJlcGxhY2UgbmV3bHkgaW5zdGFudGlhdGVkCiAgICAgICAgICAgICAgICAvL3ZhcmlhYmxlcyBpbiByZW1haW5pbmcgdXBwZXIgYm91bmRzIGFuZCBjb250aW51ZQogICAgICAgICAgICAgICAgZm9yIChUeXBlIHQgOiB1bmRldHZhcnMpIHsKICAgICAgICAgICAgICAgICAgICBVbmRldFZhciB1diA9IChVbmRldFZhcil0OwogICAgICAgICAgICAgICAgICAgIHV2LnN1YnN0Qm91bmRzKHNvbHZlZFZhcnMsIGFzSW5zdFR5cGVzKHNvbHZlZFZhcnMpLCB0eXBlcyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaW5mZXIuZG9JbmNvcnBvcmF0aW9uKHRoaXMsIHdhcm4pOwogICAgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKICAgICAgICByZXR1cm4gIkluZmVyZW5jZSB2YXJzOiAiICsgaW5mZXJlbmNldmFycyArICdcbicgKwogICAgICAgICAgICAgICAiVW5kZXQgdmFyczogIiArIHVuZGV0dmFyczsKICAgIH0KCiAgICAvKiBNZXRob2QgVHlwZXMuY2FwdHVyZSgpIGdlbmVyYXRlcyBhIG5ldyB0eXBlIGV2ZXJ5IHRpbWUgaXQncyBhcHBsaWVkCiAgICAgKiB0byBhIHdpbGRjYXJkIHBhcmFtZXRlcml6ZWQgdHlwZS4gVGhpcyBpcyBpbnRlbmRlZCBmdW5jdGlvbmFsaXR5IGJ1dAogICAgICogdGhlcmUgYXJlIHNvbWUgY2FzZXMgd2hlbiB3aGF0IHlvdSBuZWVkIGlzIG5vdCB0byBnZW5lcmF0ZSBhIG5ldwogICAgICogY2FwdHVyZWQgdHlwZSBidXQgdG8gY2hlY2sgdGhhdCBhIHByZXZpb3VzbHkgZ2VuZXJhdGVkIGNhcHR1cmVkIHR5cGUKICAgICAqIGlzIGNvcnJlY3QuIFRoZXJlIGFyZSBjYXNlcyB3aGVuIGNhY2hpbmcgYSBjYXB0dXJlZCB0eXBlIGZvciBsYXRlcgogICAgICogcmV1c2UgaXMgc291bmQuIEluIGdlbmVyYWwgdHdvIGNhcHR1cmVzIGZyb20gdGhlIHNhbWUgQVNUIGFyZSBlcXVhbC4KICAgICAqIFRoaXMgaXMgd2h5IHRoZSB0cmVlIGlzIHVzZWQgYXMgdGhlIGtleSBvZiB0aGUgbWFwIGJlbG93LiBUaGlzIG1hcAogICAgICogc3RvcmVzIGEgVHlwZSBwZXIgQVNULgogICAgICovCiAgICBNYXA8SkNUcmVlLCBUeXBlPiBjYXB0dXJlVHlwZUNhY2hlID0gbmV3IEhhc2hNYXA8PigpOwoKICAgIFR5cGUgY2FjaGVkQ2FwdHVyZShKQ1RyZWUgdHJlZSwgVHlwZSB0LCBib29sZWFuIHJlYWRPbmx5KSB7CiAgICAgICAgVHlwZSBjYXB0dXJlZCA9IGNhcHR1cmVUeXBlQ2FjaGUuZ2V0KHRyZWUpOwogICAgICAgIGlmIChjYXB0dXJlZCAhPSBudWxsKSB7CiAgICAgICAgICAgIHJldHVybiBjYXB0dXJlZDsKICAgICAgICB9CgogICAgICAgIFR5cGUgcmVzdWx0ID0gdHlwZXMuY2FwdHVyZSh0KTsKICAgICAgICBpZiAocmVzdWx0ICE9IHQgJiYgIXJlYWRPbmx5KSB7IC8vIHRoZW4gdCBpcyBhIHdpbGRjYXJkIHBhcmFtZXRlcml6ZWQgdHlwZQogICAgICAgICAgICBjYXB0dXJlVHlwZUNhY2hlLnB1dCh0cmVlLCByZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgfQp9ClBLAwQKAAAIAAAGO6lKAAAAAAAAAAAAAAAAHQAAAGNvbS9zdW4vdG9vbHMvamF2YWMvcGxhdGZvcm0vUEsDBAoAAAgAAAY7qUoDu+OmsQwAALEMAAAvAAAAY29tL3N1bi90b29scy9qYXZhYy9wbGF0Zm9ybS9QbGF0Zm9ybVV0aWxzLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhYy5wbGF0Zm9ybTsKCmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLm1haW4uQXJndW1lbnRzOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5wbGF0Zm9ybS5QbGF0Zm9ybVByb3ZpZGVyLlBsYXRmb3JtTm90U3VwcG9ydGVkOwppbXBvcnQgamF2YS51dGlsLk9wdGlvbmFsOwppbXBvcnQgamF2YS51dGlsLlNlcnZpY2VMb2FkZXI7CmltcG9ydCBqYXZhLnV0aWwuc3RyZWFtLlN0cmVhbVN1cHBvcnQ7CgovKiogSW50ZXJuYWwgdXRpbGl0aWVzIHRvIHdvcmsgd2l0aCBQbGF0Zm9ybURlc2NyaXB0aW9ucy4KICoKICogIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqICBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqICBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogKiAgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPgogKi8KcHVibGljIGNsYXNzIFBsYXRmb3JtVXRpbHMgewoKICAgIHB1YmxpYyBzdGF0aWMgUGxhdGZvcm1EZXNjcmlwdGlvbiBsb29rdXBQbGF0Zm9ybURlc2NyaXB0aW9uKFN0cmluZyBwbGF0Zm9ybVN0cmluZykgewogICAgICAgIGludCBzZXBhcmF0b3IgPSBwbGF0Zm9ybVN0cmluZy5pbmRleE9mKCI6Iik7CiAgICAgICAgU3RyaW5nIHBsYXRmb3JtUHJvdmlkZXJOYW1lID0KICAgICAgICAgICAgICAgIHNlcGFyYXRvciAhPSAoLTEpID8gcGxhdGZvcm1TdHJpbmcuc3Vic3RyaW5nKDAsIHNlcGFyYXRvcikgOiBwbGF0Zm9ybVN0cmluZzsKICAgICAgICBTdHJpbmcgcGxhdGZvcm1PcHRpb25zID0KICAgICAgICAgICAgICAgIHNlcGFyYXRvciAhPSAoLTEpID8gcGxhdGZvcm1TdHJpbmcuc3Vic3RyaW5nKHNlcGFyYXRvciArIDEpIDogIiI7CiAgICAgICAgSXRlcmFibGU8UGxhdGZvcm1Qcm92aWRlcj4gcHJvdmlkZXJzID0KICAgICAgICAgICAgICAgIFNlcnZpY2VMb2FkZXIubG9hZChQbGF0Zm9ybVByb3ZpZGVyLmNsYXNzLCBBcmd1bWVudHMuY2xhc3MuZ2V0Q2xhc3NMb2FkZXIoKSk7CgogICAgICAgIHJldHVybiBTdHJlYW1TdXBwb3J0LnN0cmVhbShwcm92aWRlcnMuc3BsaXRlcmF0b3IoKSwgZmFsc2UpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZmlsdGVyKHByb3ZpZGVyIC0+IFN0cmVhbVN1cHBvcnQuc3RyZWFtKHByb3ZpZGVyLmdldFN1cHBvcnRlZFBsYXRmb3JtTmFtZXMoKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5zcGxpdGVyYXRvcigpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWxzZSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5hbnlNYXRjaChwbGF0Zm9ybVByb3ZpZGVyTmFtZTo6ZXF1YWxzKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5maW5kRmlyc3QoKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgLmZsYXRNYXAocHJvdmlkZXIgLT4gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBPcHRpb25hbC5vZihwcm92aWRlci5nZXRQbGF0Zm9ybShwbGF0Zm9ybVByb3ZpZGVyTmFtZSwgcGxhdGZvcm1PcHRpb25zKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoUGxhdGZvcm1Ob3RTdXBwb3J0ZWQgcG5zKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBPcHRpb25hbC5lbXB0eSgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAub3JFbHNlKG51bGwpOwogICAgfQoKfQpQSwMECgAACAAABjupSgpd+J4FBgAABQYAAC4AAABjb20vc3VuL3Rvb2xzL2phdmFjL3BsYXRmb3JtL3BhY2thZ2UtaW5mby5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDE1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgovKioKICogIEFuIGludGVybmFsIEFQSSBmb3IgcGx1Z2dpbmcgaW4gLS1yZWxlYXNlIGltcGxlbWVudGF0aW9ucy4KICoKICogIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqICBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqICBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogKiAgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPgogKi8KcGFja2FnZSBjb20uc3VuLnRvb2xzLmphdmFjLnBsYXRmb3JtOwpQSwMECgAACAAABjupSrt8JBRoGQAAaBkAADUAAABjb20vc3VuL3Rvb2xzL2phdmFjL3BsYXRmb3JtL0pES1BsYXRmb3JtUHJvdmlkZXIuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAxNCwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLmphdmFjLnBsYXRmb3JtOwoKaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CmltcG9ydCBqYXZhLm5pby5maWxlLkRpcmVjdG9yeVN0cmVhbTsKaW1wb3J0IGphdmEubmlvLmZpbGUuRmlsZVN5c3RlbTsKaW1wb3J0IGphdmEubmlvLmZpbGUuRmlsZVN5c3RlbXM7CmltcG9ydCBqYXZhLm5pby5maWxlLkZpbGVzOwppbXBvcnQgamF2YS5uaW8uZmlsZS5QYXRoOwppbXBvcnQgamF2YS5uaW8uZmlsZS5QYXRoczsKaW1wb3J0IGphdmEubmlvLmZpbGUuUHJvdmlkZXJOb3RGb3VuZEV4Y2VwdGlvbjsKaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CmltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbjsKaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOwppbXBvcnQgamF2YS51dGlsLkxpc3Q7CmltcG9ydCBqYXZhLnV0aWwuTWFwOwppbXBvcnQgamF2YS51dGlsLlNldDsKaW1wb3J0IGphdmEudXRpbC5UcmVlU2V0OwoKaW1wb3J0IGphdmF4LmFubm90YXRpb24ucHJvY2Vzc2luZy5Qcm9jZXNzb3I7CgppbXBvcnQgY29tLnN1bi5zb3VyY2UudXRpbC5QbHVnaW47CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmp2bS5UYXJnZXQ7CgovKiogUGxhdGZvcm1Qcm92aWRlciBmb3IgSkRLIE4uCiAqCiAqICA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiAgSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93biByaXNrLgogKiAgVGhpcyBjb2RlIGFuZCBpdHMgaW50ZXJuYWwgaW50ZXJmYWNlcyBhcmUgc3ViamVjdCB0byBjaGFuZ2Ugb3IKICogIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj4KICovCnB1YmxpYyBjbGFzcyBKREtQbGF0Zm9ybVByb3ZpZGVyIGltcGxlbWVudHMgUGxhdGZvcm1Qcm92aWRlciB7CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgSXRlcmFibGU8U3RyaW5nPiBnZXRTdXBwb3J0ZWRQbGF0Zm9ybU5hbWVzKCkgewogICAgICAgIHJldHVybiBTVVBQT1JURURfSkFWQV9QTEFURk9STV9WRVJTSU9OUzsKICAgIH0KCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBQbGF0Zm9ybURlc2NyaXB0aW9uIGdldFBsYXRmb3JtKFN0cmluZyBwbGF0Zm9ybU5hbWUsIFN0cmluZyBvcHRpb25zKSB7CiAgICAgICAgcmV0dXJuIG5ldyBQbGF0Zm9ybURlc2NyaXB0aW9uSW1wbChwbGF0Zm9ybU5hbWUpOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZ1tdIHN5bWJvbEZpbGVMb2NhdGlvbiA9IHsgImxpYiIsICJjdC5zeW0iIH07CgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU2V0PFN0cmluZz4gU1VQUE9SVEVEX0pBVkFfUExBVEZPUk1fVkVSU0lPTlM7CgogICAgc3RhdGljIHsKICAgICAgICBTVVBQT1JURURfSkFWQV9QTEFURk9STV9WRVJTSU9OUyA9IG5ldyBUcmVlU2V0PD4oKTsKICAgICAgICBQYXRoIGN0U3ltRmlsZSA9IGZpbmRDdFN5bSgpOwogICAgICAgIGlmIChGaWxlcy5leGlzdHMoY3RTeW1GaWxlKSkgewogICAgICAgICAgICB0cnkgKEZpbGVTeXN0ZW0gZnMgPSBGaWxlU3lzdGVtcy5uZXdGaWxlU3lzdGVtKGN0U3ltRmlsZSwgbnVsbCk7CiAgICAgICAgICAgICAgICAgRGlyZWN0b3J5U3RyZWFtPFBhdGg+IGRpciA9CiAgICAgICAgICAgICAgICAgICAgICAgICBGaWxlcy5uZXdEaXJlY3RvcnlTdHJlYW0oZnMuZ2V0Um9vdERpcmVjdG9yaWVzKCkuaXRlcmF0b3IoKS5uZXh0KCkpKSB7CiAgICAgICAgICAgICAgICBmb3IgKFBhdGggc2VjdGlvbiA6IGRpcikgewogICAgICAgICAgICAgICAgICAgIGZvciAoY2hhciB2ZXIgOiBzZWN0aW9uLmdldEZpbGVOYW1lKCkudG9TdHJpbmcoKS50b0NoYXJBcnJheSgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyB2ZXJTdHJpbmcgPSBDaGFyYWN0ZXIudG9TdHJpbmcodmVyKTsKICAgICAgICAgICAgICAgICAgICAgICAgVGFyZ2V0IHQgPSBUYXJnZXQubG9va3VwKHZlclN0cmluZyk7CgogICAgICAgICAgICAgICAgICAgICAgICBpZiAodCAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBTVVBQT1JURURfSkFWQV9QTEFURk9STV9WRVJTSU9OUy5hZGQodGFyZ2V0TnVtZXJpY1ZlcnNpb24odCkpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiB8IFByb3ZpZGVyTm90Rm91bmRFeGNlcHRpb24gZXgpIHsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBTVVBQT1JURURfSkFWQV9QTEFURk9STV9WRVJTSU9OUy5hZGQodGFyZ2V0TnVtZXJpY1ZlcnNpb24oVGFyZ2V0LkRFRkFVTFQpKTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgdGFyZ2V0TnVtZXJpY1ZlcnNpb24oVGFyZ2V0IHRhcmdldCkgewogICAgICAgIHJldHVybiBJbnRlZ2VyLnRvU3RyaW5nKHRhcmdldC5vcmRpbmFsKCkgLSBUYXJnZXQuSkRLMV8xLm9yZGluYWwoKSArIDEpOwogICAgfQoKICAgIHN0YXRpYyBjbGFzcyBQbGF0Zm9ybURlc2NyaXB0aW9uSW1wbCBpbXBsZW1lbnRzIFBsYXRmb3JtRGVzY3JpcHRpb24gewoKICAgICAgICBwcml2YXRlIGZpbmFsIE1hcDxQYXRoLCBGaWxlU3lzdGVtPiBjdFN5bTJGaWxlU3lzdGVtID0gbmV3IEhhc2hNYXA8PigpOwogICAgICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIHZlcnNpb247CgogICAgICAgIFBsYXRmb3JtRGVzY3JpcHRpb25JbXBsKFN0cmluZyB2ZXJzaW9uKSB7CiAgICAgICAgICAgIHRoaXMudmVyc2lvbiA9IHZlcnNpb247CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQ29sbGVjdGlvbjxQYXRoPiBnZXRQbGF0Zm9ybVBhdGgoKSB7CiAgICAgICAgICAgIGlmIChUYXJnZXQubG9va3VwKHZlcnNpb24pID09IFRhcmdldC5ERUZBVUxUKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgTGlzdDxQYXRoPiBwYXRocyA9IG5ldyBBcnJheUxpc3Q8PigpOwogICAgICAgICAgICBQYXRoIGZpbGUgPSBmaW5kQ3RTeW0oKTsKICAgICAgICAgICAgLy8gZmlsZSA9PSAke2pkay5ob21lfS9saWIvY3Quc3ltCiAgICAgICAgICAgIGlmIChGaWxlcy5leGlzdHMoZmlsZSkpIHsKICAgICAgICAgICAgICAgIEZpbGVTeXN0ZW0gZnMgPSBjdFN5bTJGaWxlU3lzdGVtLmdldChmaWxlKTsKICAgICAgICAgICAgICAgIGlmIChmcyA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICAgICAgY3RTeW0yRmlsZVN5c3RlbS5wdXQoZmlsZSwgZnMgPSBGaWxlU3lzdGVtcy5uZXdGaWxlU3lzdGVtKGZpbGUsIG51bGwpKTsKICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgewogICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKGV4KTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBQYXRoIHJvb3QgPSBmcy5nZXRSb290RGlyZWN0b3JpZXMoKS5pdGVyYXRvcigpLm5leHQoKTsKICAgICAgICAgICAgICAgIHRyeSAoRGlyZWN0b3J5U3RyZWFtPFBhdGg+IGRpciA9IEZpbGVzLm5ld0RpcmVjdG9yeVN0cmVhbShyb290KSkgewogICAgICAgICAgICAgICAgICAgIGZvciAoUGF0aCBzZWN0aW9uIDogZGlyKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzZWN0aW9uLmdldEZpbGVOYW1lKCkudG9TdHJpbmcoKS5jb250YWlucyh2ZXJzaW9uKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcGF0aHMuYWRkKHNlY3Rpb24pOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKGV4KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oIkNhbm5vdCBmaW5kIGN0LnN5bSEiKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gcGF0aHM7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgU3RyaW5nIGdldFNvdXJjZVZlcnNpb24oKSB7CiAgICAgICAgICAgIHJldHVybiB2ZXJzaW9uOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFN0cmluZyBnZXRUYXJnZXRWZXJzaW9uKCkgewogICAgICAgICAgICByZXR1cm4gdmVyc2lvbjsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBMaXN0PFBsdWdpbkluZm88UHJvY2Vzc29yPj4gZ2V0QW5ub3RhdGlvblByb2Nlc3NvcnMoKSB7CiAgICAgICAgICAgIHJldHVybiBDb2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBMaXN0PFBsdWdpbkluZm88UGx1Z2luPj4gZ2V0UGx1Z2lucygpIHsKICAgICAgICAgICAgcmV0dXJuIENvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIExpc3Q8U3RyaW5nPiBnZXRBZGRpdGlvbmFsT3B0aW9ucygpIHsKICAgICAgICAgICAgcmV0dXJuIENvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgICAgICBmb3IgKEZpbGVTeXN0ZW0gZnMgOiBjdFN5bTJGaWxlU3lzdGVtLnZhbHVlcygpKSB7CiAgICAgICAgICAgICAgICBmcy5jbG9zZSgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGN0U3ltMkZpbGVTeXN0ZW0uY2xlYXIoKTsKICAgICAgICB9CgogICAgfQoKICAgIHN0YXRpYyBQYXRoIGZpbmRDdFN5bSgpIHsKICAgICAgICBTdHJpbmcgamF2YUhvbWUgPSBTeXN0ZW0uZ2V0UHJvcGVydHkoImphdmEuaG9tZSIpOwogICAgICAgIFBhdGggZmlsZSA9IFBhdGhzLmdldChqYXZhSG9tZSk7CiAgICAgICAgLy8gZmlsZSA9PSAke2pkay5ob21lfQogICAgICAgIGZvciAoU3RyaW5nIG5hbWUgOiBzeW1ib2xGaWxlTG9jYXRpb24pCiAgICAgICAgICAgIGZpbGUgPSBmaWxlLnJlc29sdmUobmFtZSk7CiAgICAgICAgcmV0dXJuIGZpbGU7CiAgICB9Cgp9ClBLAwQKAAAIAAAGO6lKjJ9UCvkJAAD5CQAAMgAAAGNvbS9zdW4vdG9vbHMvamF2YWMvcGxhdGZvcm0vUGxhdGZvcm1Qcm92aWRlci5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDE0LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuamF2YWMucGxhdGZvcm07CgovKiogQSBjb2xsZWN0aW9uIG9mIHBsYXRmb3JtIGRlc2NyaXB0aW9ucyB0aGF0IGNhbiBiZSBzZWxlY3RlZCB1c2luZyB7QGNvZGUgLS1yZWxlYXNlIG5hbWV9CiAqICBjb21tYW5kIGxpbmUgb3B0aW9uLgogKiAgUmVnaXN0ZXIgaW4ge0Bjb2RlIE1FVEEtSU5GL3NlcnZpY2VzL2NvbS5zdW4udG9vbHMuamF2YWMucGxhdGZvcm0uUGxhdGZvcm1Qcm92aWRlcn0uCiAqCiAqICA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiAgSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93biByaXNrLgogKiAgVGhpcyBjb2RlIGFuZCBpdHMgaW50ZXJuYWwgaW50ZXJmYWNlcyBhcmUgc3ViamVjdCB0byBjaGFuZ2Ugb3IKICogIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj4KICovCnB1YmxpYyBpbnRlcmZhY2UgUGxhdGZvcm1Qcm92aWRlciB7CgogICAgLyoqTmFtZXMgb2YgcGxhdGZvcm1zIHN1cHBvcnRlZCBieSB0aGlzIHByb3ZpZGVyLiBFYWNoIHJldHVybmVkIG5hbWUgY2FuIGJlIHVzZWQgYXMgdGhlIGtleSBmb3IgLS1yZWxlYXNlLgogICAgICoKICAgICAqIEByZXR1cm4gdGhlIHBsYXRmb3JtIGtleXMKICAgICAqLwogICAgSXRlcmFibGU8U3RyaW5nPiBnZXRTdXBwb3J0ZWRQbGF0Zm9ybU5hbWVzKCk7CgogICAgLyoqQ3JlYXRlIGEgZGVzY3JpcHRpb24gb2YgYSBzZWxlY3RlZCBwbGF0Zm9ybS4KICAgICAqCiAgICAgKiBAcGFyYW0gcGxhdGZvcm1OYW1lIHRoZSBuYW1lIG9mIHRoZSBzZWxlY3RlZCBwbGF0Zm9ybQogICAgICogQHBhcmFtIG9wdGlvbnMgYWRkaXRpb25hbCBwYXJhbWV0ZXIsIHdoaWNoIGNhbiBiZSBzcGVjaWZpZWQgYWZ0ZXIgJzonIG9uIHRoZSBjb21tYW5kIGxpbmUKICAgICAqIEByZXR1cm4gYSBQbGF0Zm9ybURlc2NyaXB0aW9uCiAgICAgKiBAdGhyb3dzIFBsYXRmb3JtTm90U3VwcG9ydGVkIGlmIHRoZSBnaXZlbiBwbGF0Zm9ybSBpcyBub3Qgc3VwcG9ydGVkCiAgICAgKi8KICAgIFBsYXRmb3JtRGVzY3JpcHRpb24gZ2V0UGxhdGZvcm0oU3RyaW5nIHBsYXRmb3JtTmFtZSwgU3RyaW5nIG9wdGlvbnMpIHRocm93cyBQbGF0Zm9ybU5vdFN1cHBvcnRlZDsKCiAgICAvKipUaHJvdyBpZiB0aGUgZ2l2ZW4gcGxhdGZvcm0gaXMgbm90IHN1cHBvcnRlZC4KICAgICAqLwogICAgcHVibGljIGNsYXNzIFBsYXRmb3JtTm90U3VwcG9ydGVkIGV4dGVuZHMgRXhjZXB0aW9uIHsKICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxTDsKICAgIH0KCn0KUEsDBAoAAAgAAAY7qUo8H7T6VRAAAFUQAAA1AAAAY29tL3N1bi90b29scy9qYXZhYy9wbGF0Zm9ybS9QbGF0Zm9ybURlc2NyaXB0aW9uLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTQsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhYy5wbGF0Zm9ybTsKCmltcG9ydCBqYXZhLmlvLkNsb3NlYWJsZTsKaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CmltcG9ydCBqYXZhLm5pby5maWxlLlBhdGg7CmltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbjsKaW1wb3J0IGphdmEudXRpbC5MaXN0OwppbXBvcnQgamF2YS51dGlsLk1hcDsKCmltcG9ydCBqYXZheC5hbm5vdGF0aW9uLnByb2Nlc3NpbmcuUHJvY2Vzc29yOwoKaW1wb3J0IGNvbS5zdW4uc291cmNlLnV0aWwuUGx1Z2luOwoKLyoqQSBkZXNjcmlwdGlvbiBvZiBzZXR0aW5ncyBuZWVkZWQgZm9yIGEgcGFydGljdWxhciB7QGNvZGUgLS1yZWxlYXNlIG5hbWV9IG9wdGlvbi4KICoKICogIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqICBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqICBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogKiAgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPgogKi8KcHVibGljIGludGVyZmFjZSBQbGF0Zm9ybURlc2NyaXB0aW9uIGV4dGVuZHMgQ2xvc2VhYmxlIHsKCiAgICAvKipSZXR1cm5zIHBhdGhzIHRoYXQgc2hvdWxkIGJlIHVzZWQgYXMgdGhlIGN1cnJlbnQgcGxhdGZvcm0ncyBib290Y2xhc3NwYXRoLCBvciBudWxsIGlmCiAgICAgKiB0aGUgZGVmYXVsdCBzaG91bGQgYmUgdXNlZC4KICAgICAqCiAgICAgKiBAcmV0dXJuIHRoZSBjdXJyZW50IHBsYXRmb3JtcydzIGJvb3RjbGFzc3BhdGgsIG9yIG51bGwgZm9yIGRlZmF1bHQKICAgICAqLwogICAgQ29sbGVjdGlvbjxQYXRoPiBnZXRQbGF0Zm9ybVBhdGgoKTsKCiAgICAvKipSZXR1cm5zIHRoZSBzb3VyY2UgdmVyc2lvbiB0aGF0IHNob3VsZCBiZSBzZWxlY3RlZC4KICAgICAqIEVxdWl2YWxlbnQgdG8ge0Bjb2RlIC1zb3VyY2UgTn0gb24gdGhlIGNvbW1hbmQgbGluZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIHRoZSByZXF1aXJlZCBzb3VyY2UgdmVyc2lvbgogICAgICovCiAgICBTdHJpbmcgZ2V0U291cmNlVmVyc2lvbigpOwoKICAgIC8qKlJldHVybnMgdGhlIHRhcmdldCB2ZXJzaW9uIHRoYXQgc2hvdWxkIGJlIHNlbGVjdGVkLgogICAgICogRXF1aXZhbGVudCB0byB7QGNvZGUgLXRhcmdldCBOfSBvbiB0aGUgY29tbWFuZCBsaW5lLgogICAgICoKICAgICAqIEByZXR1cm4gdGhlIHJlcXVpcmVkIHRhcmdldCB2ZXJzaW9uCiAgICAgKi8KICAgIFN0cmluZyBnZXRUYXJnZXRWZXJzaW9uKCk7CgogICAgLyoqUmV0dXJucyB0aGUgZGVzY3JpcHRpb24gb2YgYW5ub3RhdGlvbiBQcm9jZXNzb3Igb3IgamF2YWMgUGx1Z2luIHRoYXQgc2hvdWxkIGJlIGVuYWJsZWQKICAgICAqIGluIHRoZSBjdXJyZW50IGphdmFjIHJ1bi4KICAgICAqCiAgICAgKiBAcGFyYW0gPFQ+IGVpdGhlciBQcm9jZXNzb3Igb3IgUGx1Z2luCiAgICAgKi8KICAgIGludGVyZmFjZSBQbHVnaW5JbmZvPFQ+IHsKCiAgICAgICAgLyoqUmV0dXJucyB0aGUgbmFtZSBvZiB0aGUgUHJvY2Vzc29yIG9yIFBsdWdpbi4KICAgICAgICAgKgogICAgICAgICAqIEByZXR1cm4gbmFtZSBvZiB0aGUgUHJvY2Vzc29yIG9yIFBsdWdpbi4KICAgICAgICAgKi8KICAgICAgICBTdHJpbmcgZ2V0TmFtZSgpOwoKICAgICAgICAvKipSZXR1cm5zIHRoZSBvcHRpb25zIGZvciB0aGUgUHJvY2Vzc29yIG9yIFBsdWdpbi4gRm9yIHBsdWdpbiwgdGhlIG1hcCB3aWxsIGJlIGNvbnZlcnRlZCB0byBhIGNvbGxlY3Rpb24KICAgICAgICAgKiBieSBjb25jYXRlbmF0aW5nIHRoZSBtYXAncyBrZXlzLCB0aGUgJz0nIHNpZ24gYW5kIHRoZSBtYXAncyB2YWx1ZXMuCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqIEByZXR1cm4gdGhlIG9wdGlvbnMKICAgICAgICAgKi8KICAgICAgICBNYXA8U3RyaW5nLCBTdHJpbmc+IGdldE9wdGlvbnMoKTsKCiAgICAgICAgLyoqUmV0dXJucyB0aGUgUHJvY2Vzc29yIG9yIFBsdWdpbiBpbnN0YW5jZS4KICAgICAgICAgKgogICAgICAgICAqIEByZXR1cm4gdGhlIFByb2Nlc3NvciBvciBQbHVnaW4gaW5zdGFuY2UuCiAgICAgICAgICovCiAgICAgICAgVCBnZXRQbHVnaW4oKTsKICAgIH0KCiAgICAvKipSZXR1cm5zIHRoZSBhbm5vdGF0aW9uIFByb2Nlc3NvcnMgdGhhdCBzaG91bGQgYmUgZW5hYmxlZCBpbiB0aGUgY3VycmVudCBqYXZhYyBydW4uCiAgICAgKgogICAgICogQHJldHVybiBhbm5vdGF0aW9uIFByb2Nlc3NvcnMKICAgICAqLwogICAgTGlzdDxQbHVnaW5JbmZvPFByb2Nlc3Nvcj4+IGdldEFubm90YXRpb25Qcm9jZXNzb3JzKCk7CgogICAgLyoqUmV0dXJucyB0aGUgamF2YWMgUGx1Z2lucyB0aGF0IHNob3VsZCBiZSBlbmFibGVkIGluIHRoZSBjdXJyZW50IGphdmFjIHJ1bi4KICAgICAqCiAgICAgKiBAcmV0dXJuIGphdmFjIFBsdWdpbnMKICAgICAqLwogICAgTGlzdDxQbHVnaW5JbmZvPFBsdWdpbj4+IGdldFBsdWdpbnMoKTsKCiAgICAvKipSZXR1cm5zIHRoZSBhZGRpdGlvbmFsIGNvbW1hbmQgbGluZSBvcHRpb25zIHRoYXQgc2hvdWxkIGJlIHBhc3NlZCB0byBqYXZhYy4KICAgICAqCiAgICAgKiBAcmV0dXJuIGFkZGl0aW9uYWwgY29tbWFuZCBsaW5lIG9wdGlvbnMKICAgICAqLwogICAgTGlzdDxTdHJpbmc+IGdldEFkZGl0aW9uYWxPcHRpb25zKCk7CgogICAgLyoqUGVyZm9ybSBjbGVhbnVwIGZvciB0aGlzIFBsYXRmb3JtUHJvdmlkZXIgLSB0aGlzIGluc3RhbmNlIHdvbid0IGJlIHVzZWQgYWZ0ZXIgdGhpcyBtZXRob2QKICAgICAqIGlzIGNhbGxlZC4KICAgICAqCiAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIHVuZXhwZWN0ZWQgcHJvYmxlbXMgb2NjdXIgZHVyaW5nIGNsb3NpbmcgdGhpcyBwcm92aWRlcgogICAgICovCiAgICB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uOwp9ClBLAwQKAAAIAAAGO6lKAAAAAAAAAAAAAAAAGQAAAGNvbS9zdW4vdG9vbHMvamF2YWMvdHJlZS9QSwMECgAACAAABjupShvcMV4PlwEAD5cBACQAAABjb20vc3VuL3Rvb2xzL2phdmFjL3RyZWUvSkNUcmVlLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDE5OTksIDIwMTYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhYy50cmVlOwoKaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CmltcG9ydCBqYXZhLmlvLlN0cmluZ1dyaXRlcjsKaW1wb3J0IGphdmEudXRpbC4qOwoKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC5Nb2RpZmllcjsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwudHlwZS5UeXBlS2luZDsKaW1wb3J0IGphdmF4LnRvb2xzLkphdmFGaWxlT2JqZWN0OwoKaW1wb3J0IGNvbS5zdW4uc291cmNlLnRyZWUuKjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS4qOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLkRpcmVjdGl2ZS5SZXF1aXJlc0RpcmVjdGl2ZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5TY29wZS4qOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlN5bWJvbC4qOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLio7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuRGVmaW5lZEJ5LkFwaTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5KQ0RpYWdub3N0aWMuRGlhZ25vc3RpY1Bvc2l0aW9uOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkxpc3Q7CgppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5KQ1RyZWUuVGFnLio7CgppbXBvcnQgamF2YXgudG9vbHMuSmF2YUZpbGVNYW5hZ2VyLkxvY2F0aW9uOwoKaW1wb3J0IGNvbS5zdW4uc291cmNlLnRyZWUuTW9kdWxlVHJlZS5Nb2R1bGVLaW5kOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLkRpcmVjdGl2ZS5FeHBvcnRzRGlyZWN0aXZlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLkRpcmVjdGl2ZS5PcGVuc0RpcmVjdGl2ZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5UeXBlLk1vZHVsZVR5cGU7CgovKioKICogUm9vdCBjbGFzcyBmb3IgYWJzdHJhY3Qgc3ludGF4IHRyZWUgbm9kZXMuIEl0IHByb3ZpZGVzIGRlZmluaXRpb25zCiAqIGZvciBzcGVjaWZpYyB0cmVlIG5vZGVzIGFzIHN1YmNsYXNzZXMgbmVzdGVkIGluc2lkZS4KICoKICogPHA+RWFjaCBzdWJjbGFzcyBpcyBoaWdobHkgc3RhbmRhcmRpemVkLiAgSXQgZ2VuZXJhbGx5IGNvbnRhaW5zCiAqIG9ubHkgdHJlZSBmaWVsZHMgZm9yIHRoZSBzeW50YWN0aWMgc3ViY29tcG9uZW50cyBvZiB0aGUgbm9kZS4gIFNvbWUKICogY2xhc3NlcyB0aGF0IHJlcHJlc2VudCBpZGVudGlmaWVyIHVzZXMgb3IgZGVmaW5pdGlvbnMgYWxzbyBkZWZpbmUgYQogKiBTeW1ib2wgZmllbGQgdGhhdCBkZW5vdGVzIHRoZSByZXByZXNlbnRlZCBpZGVudGlmaWVyLiAgQ2xhc3NlcyBmb3IKICogbm9uLWxvY2FsIGp1bXBzIGFsc28gY2FycnkgdGhlIGp1bXAgdGFyZ2V0IGFzIGEgZmllbGQuICBUaGUgcm9vdAogKiBjbGFzcyBUcmVlIGl0c2VsZiBkZWZpbmVzIGZpZWxkcyBmb3IgdGhlIHRyZWUncyB0eXBlIGFuZCBwb3NpdGlvbi4KICogTm8gb3RoZXIgZmllbGRzIGFyZSBrZXB0IGluIGEgdHJlZSBub2RlOyBpbnN0ZWFkIHBhcmFtZXRlcnMgYXJlCiAqIHBhc3NlZCB0byBtZXRob2RzIGFjY2Vzc2luZyB0aGUgbm9kZS4KICoKICogPHA+RXhjZXB0IGZvciB0aGUgbWV0aG9kcyBkZWZpbmVkIGJ5IGNvbS5zdW4uc291cmNlLCB0aGUgb25seQogKiBtZXRob2QgZGVmaW5lZCBpbiBzdWJjbGFzc2VzIGlzIGB2aXNpdCcgd2hpY2ggYXBwbGllcyBhIGdpdmVuCiAqIHZpc2l0b3IgdG8gdGhlIHRyZWUuIFRoZSBhY3R1YWwgdHJlZSBwcm9jZXNzaW5nIGlzIGRvbmUgYnkgdmlzaXRvcgogKiBjbGFzc2VzIGluIG90aGVyIHBhY2thZ2VzLiBUaGUgYWJzdHJhY3QgY2xhc3MgVmlzaXRvciwgYXMgd2VsbCBhcwogKiBhbiBGYWN0b3J5IGludGVyZmFjZSBmb3IgdHJlZXMsIGFyZSBkZWZpbmVkIGFzIGlubmVyIGNsYXNzZXMgaW4KICogVHJlZS4KICoKICogPHA+VG8gYXZvaWQgYW1iaWd1aXRpZXMgd2l0aCB0aGUgVHJlZSBBUEkgaW4gY29tLnN1bi5zb3VyY2UgYWxsIHN1YgogKiBjbGFzc2VzIHNob3VsZCwgYnkgY29udmVudGlvbiwgc3RhcnQgd2l0aCBKQyAoamF2YWMpLgogKgogKiA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yCiAqIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj4KICoKICogQHNlZSBUcmVlTWFrZXIKICogQHNlZSBUcmVlSW5mbwogKiBAc2VlIFRyZWVUcmFuc2xhdG9yCiAqIEBzZWUgUHJldHR5CiAqLwpwdWJsaWMgYWJzdHJhY3QgY2xhc3MgSkNUcmVlIGltcGxlbWVudHMgVHJlZSwgQ2xvbmVhYmxlLCBEaWFnbm9zdGljUG9zaXRpb24gewoKICAgIC8qIFRyZWUgdGFnIHZhbHVlcywgaWRlbnRpZnlpbmcga2luZHMgb2YgdHJlZXMgKi8KICAgIHB1YmxpYyBlbnVtIFRhZyB7CiAgICAgICAgLyoqIEZvciBtZXRob2RzIHRoYXQgcmV0dXJuIGFuIGludmFsaWQgdGFnIGlmIGEgZ2l2ZW4gY29uZGl0aW9uIGlzIG5vdCBtZXQKICAgICAgICAgKi8KICAgICAgICBOT19UQUcsCgogICAgICAgIC8qKiBUb3BsZXZlbCBub2Rlcywgb2YgdHlwZSBUb3BMZXZlbCwgcmVwcmVzZW50aW5nIGVudGlyZSBzb3VyY2UgZmlsZXMuCiAgICAgICAgKi8KICAgICAgICBUT1BMRVZFTCwKCiAgICAgICAgLyoqIFBhY2thZ2UgbGV2ZWwgZGVmaW5pdGlvbnMuCiAgICAgICAgICovCiAgICAgICAgUEFDS0FHRURFRiwKCiAgICAgICAgLyoqIEltcG9ydCBjbGF1c2VzLCBvZiB0eXBlIEltcG9ydC4KICAgICAgICAgKi8KICAgICAgICBJTVBPUlQsCgogICAgICAgIC8qKiBDbGFzcyBkZWZpbml0aW9ucywgb2YgdHlwZSBDbGFzc0RlZi4KICAgICAgICAgKi8KICAgICAgICBDTEFTU0RFRiwKCiAgICAgICAgLyoqIE1ldGhvZCBkZWZpbml0aW9ucywgb2YgdHlwZSBNZXRob2REZWYuCiAgICAgICAgICovCiAgICAgICAgTUVUSE9EREVGLAoKICAgICAgICAvKiogVmFyaWFibGUgZGVmaW5pdGlvbnMsIG9mIHR5cGUgVmFyRGVmLgogICAgICAgICAqLwogICAgICAgIFZBUkRFRiwKCiAgICAgICAgLyoqIFRoZSBuby1vcCBzdGF0ZW1lbnQgIjsiLCBvZiB0eXBlIFNraXAKICAgICAgICAgKi8KICAgICAgICBTS0lQLAoKICAgICAgICAvKiogQmxvY2tzLCBvZiB0eXBlIEJsb2NrLgogICAgICAgICAqLwogICAgICAgIEJMT0NLLAoKICAgICAgICAvKiogRG8td2hpbGUgbG9vcHMsIG9mIHR5cGUgRG9Mb29wLgogICAgICAgICAqLwogICAgICAgIERPTE9PUCwKCiAgICAgICAgLyoqIFdoaWxlLWxvb3BzLCBvZiB0eXBlIFdoaWxlTG9vcC4KICAgICAgICAgKi8KICAgICAgICBXSElMRUxPT1AsCgogICAgICAgIC8qKiBGb3ItbG9vcHMsIG9mIHR5cGUgRm9yTG9vcC4KICAgICAgICAgKi8KICAgICAgICBGT1JMT09QLAoKICAgICAgICAvKiogRm9yZWFjaC1sb29wcywgb2YgdHlwZSBGb3JlYWNoTG9vcC4KICAgICAgICAgKi8KICAgICAgICBGT1JFQUNITE9PUCwKCiAgICAgICAgLyoqIExhYmVsbGVkIHN0YXRlbWVudHMsIG9mIHR5cGUgTGFiZWxsZWQuCiAgICAgICAgICovCiAgICAgICAgTEFCRUxMRUQsCgogICAgICAgIC8qKiBTd2l0Y2ggc3RhdGVtZW50cywgb2YgdHlwZSBTd2l0Y2guCiAgICAgICAgICovCiAgICAgICAgU1dJVENILAoKICAgICAgICAvKiogQ2FzZSBwYXJ0cyBpbiBzd2l0Y2ggc3RhdGVtZW50cywgb2YgdHlwZSBDYXNlLgogICAgICAgICAqLwogICAgICAgIENBU0UsCgogICAgICAgIC8qKiBTeW5jaHJvbml6ZWQgc3RhdGVtZW50cywgb2YgdHlwZSBTeW5jaG9uaXplZC4KICAgICAgICAgKi8KICAgICAgICBTWU5DSFJPTklaRUQsCgogICAgICAgIC8qKiBUcnkgc3RhdGVtZW50cywgb2YgdHlwZSBUcnkuCiAgICAgICAgICovCiAgICAgICAgVFJZLAoKICAgICAgICAvKiogQ2F0Y2ggY2xhdXNlcyBpbiB0cnkgc3RhdGVtZW50cywgb2YgdHlwZSBDYXRjaC4KICAgICAgICAgKi8KICAgICAgICBDQVRDSCwKCiAgICAgICAgLyoqIENvbmRpdGlvbmFsIGV4cHJlc3Npb25zLCBvZiB0eXBlIENvbmRpdGlvbmFsLgogICAgICAgICAqLwogICAgICAgIENPTkRFWFBSLAoKICAgICAgICAvKiogQ29uZGl0aW9uYWwgc3RhdGVtZW50cywgb2YgdHlwZSBJZi4KICAgICAgICAgKi8KICAgICAgICBJRiwKCiAgICAgICAgLyoqIEV4cHJlc3Npb24gc3RhdGVtZW50cywgb2YgdHlwZSBFeGVjLgogICAgICAgICAqLwogICAgICAgIEVYRUMsCgogICAgICAgIC8qKiBCcmVhayBzdGF0ZW1lbnRzLCBvZiB0eXBlIEJyZWFrLgogICAgICAgICAqLwogICAgICAgIEJSRUFLLAoKICAgICAgICAvKiogQ29udGludWUgc3RhdGVtZW50cywgb2YgdHlwZSBDb250aW51ZS4KICAgICAgICAgKi8KICAgICAgICBDT05USU5VRSwKCiAgICAgICAgLyoqIFJldHVybiBzdGF0ZW1lbnRzLCBvZiB0eXBlIFJldHVybi4KICAgICAgICAgKi8KICAgICAgICBSRVRVUk4sCgogICAgICAgIC8qKiBUaHJvdyBzdGF0ZW1lbnRzLCBvZiB0eXBlIFRocm93LgogICAgICAgICAqLwogICAgICAgIFRIUk9XLAoKICAgICAgICAvKiogQXNzZXJ0IHN0YXRlbWVudHMsIG9mIHR5cGUgQXNzZXJ0LgogICAgICAgICAqLwogICAgICAgIEFTU0VSVCwKCiAgICAgICAgLyoqIE1ldGhvZCBpbnZvY2F0aW9uIGV4cHJlc3Npb25zLCBvZiB0eXBlIEFwcGx5LgogICAgICAgICAqLwogICAgICAgIEFQUExZLAoKICAgICAgICAvKiogQ2xhc3MgaW5zdGFuY2UgY3JlYXRpb24gZXhwcmVzc2lvbnMsIG9mIHR5cGUgTmV3Q2xhc3MuCiAgICAgICAgICovCiAgICAgICAgTkVXQ0xBU1MsCgogICAgICAgIC8qKiBBcnJheSBjcmVhdGlvbiBleHByZXNzaW9ucywgb2YgdHlwZSBOZXdBcnJheS4KICAgICAgICAgKi8KICAgICAgICBORVdBUlJBWSwKCiAgICAgICAgLyoqIExhbWJkYSBleHByZXNzaW9uLCBvZiB0eXBlIExhbWJkYS4KICAgICAgICAgKi8KICAgICAgICBMQU1CREEsCgogICAgICAgIC8qKiBQYXJlbnRoZXNpemVkIHN1YmV4cHJlc3Npb25zLCBvZiB0eXBlIFBhcmVucy4KICAgICAgICAgKi8KICAgICAgICBQQVJFTlMsCgogICAgICAgIC8qKiBBc3NpZ25tZW50IGV4cHJlc3Npb25zLCBvZiB0eXBlIEFzc2lnbi4KICAgICAgICAgKi8KICAgICAgICBBU1NJR04sCgogICAgICAgIC8qKiBUeXBlIGNhc3QgZXhwcmVzc2lvbnMsIG9mIHR5cGUgVHlwZUNhc3QuCiAgICAgICAgICovCiAgICAgICAgVFlQRUNBU1QsCgogICAgICAgIC8qKiBUeXBlIHRlc3QgZXhwcmVzc2lvbnMsIG9mIHR5cGUgVHlwZVRlc3QuCiAgICAgICAgICovCiAgICAgICAgVFlQRVRFU1QsCgogICAgICAgIC8qKiBJbmRleGVkIGFycmF5IGV4cHJlc3Npb25zLCBvZiB0eXBlIEluZGV4ZWQuCiAgICAgICAgICovCiAgICAgICAgSU5ERVhFRCwKCiAgICAgICAgLyoqIFNlbGVjdGlvbnMsIG9mIHR5cGUgU2VsZWN0LgogICAgICAgICAqLwogICAgICAgIFNFTEVDVCwKCiAgICAgICAgLyoqIE1lbWJlciByZWZlcmVuY2VzLCBvZiB0eXBlIFJlZmVyZW5jZS4KICAgICAgICAgKi8KICAgICAgICBSRUZFUkVOQ0UsCgogICAgICAgIC8qKiBTaW1wbGUgaWRlbnRpZmllcnMsIG9mIHR5cGUgSWRlbnQuCiAgICAgICAgICovCiAgICAgICAgSURFTlQsCgogICAgICAgIC8qKiBMaXRlcmFscywgb2YgdHlwZSBMaXRlcmFsLgogICAgICAgICAqLwogICAgICAgIExJVEVSQUwsCgogICAgICAgIC8qKiBCYXNpYyB0eXBlIGlkZW50aWZpZXJzLCBvZiB0eXBlIFR5cGVJZGVudC4KICAgICAgICAgKi8KICAgICAgICBUWVBFSURFTlQsCgogICAgICAgIC8qKiBBcnJheSB0eXBlcywgb2YgdHlwZSBUeXBlQXJyYXkuCiAgICAgICAgICovCiAgICAgICAgVFlQRUFSUkFZLAoKICAgICAgICAvKiogUGFyYW1ldGVyaXplZCB0eXBlcywgb2YgdHlwZSBUeXBlQXBwbHkuCiAgICAgICAgICovCiAgICAgICAgVFlQRUFQUExZLAoKICAgICAgICAvKiogVW5pb24gdHlwZXMsIG9mIHR5cGUgVHlwZVVuaW9uLgogICAgICAgICAqLwogICAgICAgIFRZUEVVTklPTiwKCiAgICAgICAgLyoqIEludGVyc2VjdGlvbiB0eXBlcywgb2YgdHlwZSBUeXBlSW50ZXJzZWN0aW9uLgogICAgICAgICAqLwogICAgICAgIFRZUEVJTlRFUlNFQ1RJT04sCgogICAgICAgIC8qKiBGb3JtYWwgdHlwZSBwYXJhbWV0ZXJzLCBvZiB0eXBlIFR5cGVQYXJhbWV0ZXIuCiAgICAgICAgICovCiAgICAgICAgVFlQRVBBUkFNRVRFUiwKCiAgICAgICAgLyoqIFR5cGUgYXJndW1lbnQuCiAgICAgICAgICovCiAgICAgICAgV0lMRENBUkQsCgogICAgICAgIC8qKiBCb3VuZCBraW5kOiBleHRlbmRzLCBzdXBlciwgZXhhY3QsIG9yIHVuYm91bmQKICAgICAgICAgKi8KICAgICAgICBUWVBFQk9VTkRLSU5ELAoKICAgICAgICAvKiogbWV0YWRhdGE6IEFubm90YXRpb24uCiAgICAgICAgICovCiAgICAgICAgQU5OT1RBVElPTiwKCiAgICAgICAgLyoqIG1ldGFkYXRhOiBUeXBlIGFubm90YXRpb24uCiAgICAgICAgICovCiAgICAgICAgVFlQRV9BTk5PVEFUSU9OLAoKICAgICAgICAvKiogbWV0YWRhdGE6IE1vZGlmaWVycwogICAgICAgICAqLwogICAgICAgIE1PRElGSUVSUywKCiAgICAgICAgLyoqIEFuIGFubm90YXRlZCB0eXBlIHRyZWUuCiAgICAgICAgICovCiAgICAgICAgQU5OT1RBVEVEX1RZUEUsCgogICAgICAgIC8qKiBFcnJvciB0cmVlcywgb2YgdHlwZSBFcnJvbmVvdXMuCiAgICAgICAgICovCiAgICAgICAgRVJST05FT1VTLAoKICAgICAgICAvKiogVW5hcnkgb3BlcmF0b3JzLCBvZiB0eXBlIFVuYXJ5LgogICAgICAgICAqLwogICAgICAgIFBPUywgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICsKICAgICAgICBORUcsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAtCiAgICAgICAgTk9ULCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gIQogICAgICAgIENPTVBMLCAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIH4KICAgICAgICBQUkVJTkMsICAgICAgICAgICAgICAgICAgICAgICAgICAvLyArKyBfCiAgICAgICAgUFJFREVDLCAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gLS0gXwogICAgICAgIFBPU1RJTkMsICAgICAgICAgICAgICAgICAgICAgICAgIC8vIF8gKysKICAgICAgICBQT1NUREVDLCAgICAgICAgICAgICAgICAgICAgICAgICAvLyBfIC0tCgogICAgICAgIC8qKiB1bmFyeSBvcGVyYXRvciBmb3IgbnVsbCByZWZlcmVuY2UgY2hlY2tzLCBvbmx5IHVzZWQgaW50ZXJuYWxseS4KICAgICAgICAgKi8KICAgICAgICBOVUxMQ0hLLAoKICAgICAgICAvKiogQmluYXJ5IG9wZXJhdG9ycywgb2YgdHlwZSBCaW5hcnkuCiAgICAgICAgICovCiAgICAgICAgT1IsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gfHwKICAgICAgICBBTkQsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAmJgogICAgICAgIEJJVE9SLCAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHwKICAgICAgICBCSVRYT1IsICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBeCiAgICAgICAgQklUQU5ELCAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gJgogICAgICAgIEVRLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vID09CiAgICAgICAgTkUsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gIT0KICAgICAgICBMVCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyA8CiAgICAgICAgR1QsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gPgogICAgICAgIExFLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIDw9CiAgICAgICAgR0UsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gPj0KICAgICAgICBTTCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyA8PAogICAgICAgIFNSLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vID4+CiAgICAgICAgVVNSLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gPj4+CiAgICAgICAgUExVUywgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gKwogICAgICAgIE1JTlVTLCAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIC0KICAgICAgICBNVUwsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAqCiAgICAgICAgRElWLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gLwogICAgICAgIE1PRCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICUKCiAgICAgICAgLyoqIEFzc2lnbm1lbnQgb3BlcmF0b3JzLCBvZiB0eXBlIEFzc2lnbm9wLgogICAgICAgICAqLwogICAgICAgIEJJVE9SX0FTRyhCSVRPUiksICAgICAgICAgICAgICAgIC8vIHw9CiAgICAgICAgQklUWE9SX0FTRyhCSVRYT1IpLCAgICAgICAgICAgICAgLy8gXj0KICAgICAgICBCSVRBTkRfQVNHKEJJVEFORCksICAgICAgICAgICAgICAvLyAmPQoKICAgICAgICBTTF9BU0coU0wpLCAgICAgICAgICAgICAgICAgICAgICAvLyA8PD0KICAgICAgICBTUl9BU0coU1IpLCAgICAgICAgICAgICAgICAgICAgICAvLyA+Pj0KICAgICAgICBVU1JfQVNHKFVTUiksICAgICAgICAgICAgICAgICAgICAvLyA+Pj49CiAgICAgICAgUExVU19BU0coUExVUyksICAgICAgICAgICAgICAgICAgLy8gKz0KICAgICAgICBNSU5VU19BU0coTUlOVVMpLCAgICAgICAgICAgICAgICAvLyAtPQogICAgICAgIE1VTF9BU0coTVVMKSwgICAgICAgICAgICAgICAgICAgIC8vICo9CiAgICAgICAgRElWX0FTRyhESVYpLCAgICAgICAgICAgICAgICAgICAgLy8gLz0KICAgICAgICBNT0RfQVNHKE1PRCksICAgICAgICAgICAgICAgICAgICAvLyAlPQoKICAgICAgICBNT0RVTEVERUYsCiAgICAgICAgRVhQT1JUUywKICAgICAgICBPUEVOUywKICAgICAgICBQUk9WSURFUywKICAgICAgICBSRVFVSVJFUywKICAgICAgICBVU0VTLAoKICAgICAgICAvKiogQSBzeW50aGV0aWMgbGV0IGV4cHJlc3Npb24sIG9mIHR5cGUgTGV0RXhwci4KICAgICAgICAgKi8KICAgICAgICBMRVRFWFBSOyAgICAgICAgICAgICAgICAgICAgICAgICAvLyBhbGEgc2NoZW1lCgogICAgICAgIHByaXZhdGUgZmluYWwgVGFnIG5vQXNzaWduVGFnOwoKICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgbnVtYmVyT2ZPcGVyYXRvcnMgPSBNT0Qub3JkaW5hbCgpIC0gUE9TLm9yZGluYWwoKSArIDE7CgogICAgICAgIHByaXZhdGUgVGFnKFRhZyBub0Fzc2lnblRhZykgewogICAgICAgICAgICB0aGlzLm5vQXNzaWduVGFnID0gbm9Bc3NpZ25UYWc7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIFRhZygpIHsKICAgICAgICAgICAgdGhpcyhudWxsKTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBzdGF0aWMgaW50IGdldE51bWJlck9mT3BlcmF0b3JzKCkgewogICAgICAgICAgICByZXR1cm4gbnVtYmVyT2ZPcGVyYXRvcnM7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgVGFnIG5vQXNzaWduT3AoKSB7CiAgICAgICAgICAgIGlmIChub0Fzc2lnblRhZyAhPSBudWxsKQogICAgICAgICAgICAgICAgcmV0dXJuIG5vQXNzaWduVGFnOwogICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoIm5vQXNzaWduT3AoKSBtZXRob2QgaXMgbm90IGF2YWlsYWJsZSBmb3Igbm9uIGFzc2lnbm1lbnQgdGFncyIpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIGJvb2xlYW4gaXNQb3N0VW5hcnlPcCgpIHsKICAgICAgICAgICAgcmV0dXJuICh0aGlzID09IFBPU1RJTkMgfHwgdGhpcyA9PSBQT1NUREVDKTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBib29sZWFuIGlzSW5jT3JEZWNVbmFyeU9wKCkgewogICAgICAgICAgICByZXR1cm4gKHRoaXMgPT0gUFJFSU5DIHx8IHRoaXMgPT0gUFJFREVDIHx8IHRoaXMgPT0gUE9TVElOQyB8fCB0aGlzID09IFBPU1RERUMpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIGJvb2xlYW4gaXNBc3NpZ25vcCgpIHsKICAgICAgICAgICAgcmV0dXJuIG5vQXNzaWduVGFnICE9IG51bGw7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgaW50IG9wZXJhdG9ySW5kZXgoKSB7CiAgICAgICAgICAgIHJldHVybiAodGhpcy5vcmRpbmFsKCkgLSBQT1Mub3JkaW5hbCgpKTsKICAgICAgICB9CiAgICB9CgogICAgLyogVGhlIChlbmNvZGVkKSBwb3NpdGlvbiBpbiB0aGUgc291cmNlIGZpbGUuIEBzZWUgdXRpbC5Qb3NpdGlvbi4KICAgICAqLwogICAgcHVibGljIGludCBwb3M7CgogICAgLyogVGhlIHR5cGUgb2YgdGhpcyBub2RlLgogICAgICovCiAgICBwdWJsaWMgVHlwZSB0eXBlOwoKICAgIC8qIFRoZSB0YWcgb2YgdGhpcyBub2RlIC0tIG9uZSBvZiB0aGUgY29uc3RhbnRzIGRlY2xhcmVkIGFib3ZlLgogICAgICovCiAgICBwdWJsaWMgYWJzdHJhY3QgVGFnIGdldFRhZygpOwoKICAgIC8qIFJldHVybnMgdHJ1ZSBpZiB0aGUgdGFnIG9mIHRoaXMgbm9kZSBpcyBlcXVhbHMgdG8gdGFnLgogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNUYWcoVGFnIHRhZykgewogICAgICAgIHJldHVybiB0YWcgPT0gZ2V0VGFnKCk7CiAgICB9CgogICAgLyoqIENvbnZlcnQgYSB0cmVlIHRvIGEgcHJldHR5LXByaW50ZWQgc3RyaW5nLiAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewogICAgICAgIFN0cmluZ1dyaXRlciBzID0gbmV3IFN0cmluZ1dyaXRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICAgIG5ldyBQcmV0dHkocywgZmFsc2UpLnByaW50RXhwcih0aGlzKTsKICAgICAgICB9CiAgICAgICAgY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgLy8gc2hvdWxkIG5ldmVyIGhhcHBlbiwgYmVjYXVzZSBTdHJpbmdXcml0ZXIgaXMgZGVmaW5lZAogICAgICAgICAgICAvLyBuZXZlciB0byB0aHJvdyBhbnkgSU9FeGNlcHRpb25zCiAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHMudG9TdHJpbmcoKTsKICAgIH0KCiAgICAvKiogU2V0IHBvc2l0aW9uIGZpZWxkIGFuZCByZXR1cm4gdGhpcyB0cmVlLgogICAgICovCiAgICBwdWJsaWMgSkNUcmVlIHNldFBvcyhpbnQgcG9zKSB7CiAgICAgICAgdGhpcy5wb3MgPSBwb3M7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CgogICAgLyoqIFNldCB0eXBlIGZpZWxkIGFuZCByZXR1cm4gdGhpcyB0cmVlLgogICAgICovCiAgICBwdWJsaWMgSkNUcmVlIHNldFR5cGUoVHlwZSB0eXBlKSB7CiAgICAgICAgdGhpcy50eXBlID0gdHlwZTsKICAgICAgICByZXR1cm4gdGhpczsKICAgIH0KCiAgICAvKiogVmlzaXQgdGhpcyB0cmVlIHdpdGggYSBnaXZlbiB2aXNpdG9yLgogICAgICovCiAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBhY2NlcHQoVmlzaXRvciB2KTsKCiAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIGFic3RyYWN0IDxSLEQ+IFIgYWNjZXB0KFRyZWVWaXNpdG9yPFIsRD4gdiwgRCBkKTsKCiAgICAvKiogUmV0dXJuIGEgc2hhbGxvdyBjb3B5IG9mIHRoaXMgdHJlZS4KICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgT2JqZWN0IGNsb25lKCkgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICAgIH0gY2F0Y2goQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihlKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqIEdldCBhIGRlZmF1bHQgcG9zaXRpb24gZm9yIHRoaXMgdHJlZSBub2RlLgogICAgICovCiAgICBwdWJsaWMgRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcygpIHsKICAgICAgICByZXR1cm4gdGhpczsKICAgIH0KCiAgICAvLyBmb3IgZGVmYXVsdCBEaWFnbm9zdGljUG9zaXRpb24KICAgIHB1YmxpYyBKQ1RyZWUgZ2V0VHJlZSgpIHsKICAgICAgICByZXR1cm4gdGhpczsKICAgIH0KCiAgICAvLyBmb3IgZGVmYXVsdCBEaWFnbm9zdGljUG9zaXRpb24KICAgIHB1YmxpYyBpbnQgZ2V0U3RhcnRQb3NpdGlvbigpIHsKICAgICAgICByZXR1cm4gVHJlZUluZm8uZ2V0U3RhcnRQb3ModGhpcyk7CiAgICB9CgogICAgLy8gZm9yIGRlZmF1bHQgRGlhZ25vc3RpY1Bvc2l0aW9uCiAgICBwdWJsaWMgaW50IGdldFByZWZlcnJlZFBvc2l0aW9uKCkgewogICAgICAgIHJldHVybiBwb3M7CiAgICB9CgogICAgLy8gZm9yIGRlZmF1bHQgRGlhZ25vc3RpY1Bvc2l0aW9uCiAgICBwdWJsaWMgaW50IGdldEVuZFBvc2l0aW9uKEVuZFBvc1RhYmxlIGVuZFBvc1RhYmxlKSB7CiAgICAgICAgcmV0dXJuIFRyZWVJbmZvLmdldEVuZFBvcyh0aGlzLCBlbmRQb3NUYWJsZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBFdmVyeXRoaW5nIGluIG9uZSBzb3VyY2UgZmlsZSBpcyBrZXB0IGluIGEge0BsaW5rcGxhaW4gSkNDb21waWxhdGlvblVuaXR9IHN0cnVjdHVyZS4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBjbGFzcyBKQ0NvbXBpbGF0aW9uVW5pdCBleHRlbmRzIEpDVHJlZSBpbXBsZW1lbnRzIENvbXBpbGF0aW9uVW5pdFRyZWUgewogICAgICAgIC8qKiBBbGwgZGVmaW5pdGlvbnMgaW4gdGhpcyBmaWxlIChDbGFzc0RlZiwgSW1wb3J0LCBhbmQgU2tpcCkgKi8KICAgICAgICBwdWJsaWMgTGlzdDxKQ1RyZWU+IGRlZnM7CiAgICAgICAgLyoqIFRoZSBzb3VyY2UgZmlsZSBuYW1lLiAqLwogICAgICAgIHB1YmxpYyBKYXZhRmlsZU9iamVjdCBzb3VyY2VmaWxlOwogICAgICAgIC8qKiBUaGUgbW9kdWxlIHRvIHdoaWNoIHRoaXMgY29tcGlsYXRpb24gdW5pdCBiZWxvbmdzLiAqLwogICAgICAgIHB1YmxpYyBNb2R1bGVTeW1ib2wgbW9kbGU7CiAgICAgICAgLyoqIFRoZSBsb2NhdGlvbiBpbiB3aGljaCB0aGlzIGNvbXBpbGF0aW9uIHVuaXQgd2FzIGZvdW5kLiAqLwogICAgICAgIHB1YmxpYyBMb2NhdGlvbiBsb2NuOwogICAgICAgIC8qKiBUaGUgcGFja2FnZSB0byB3aGljaCB0aGlzIGNvbXBpbGF0aW9uIHVuaXQgYmVsb25ncy4gKi8KICAgICAgICBwdWJsaWMgUGFja2FnZVN5bWJvbCBwYWNrZ2U7CiAgICAgICAgLyoqIEEgc2NvcGUgY29udGFpbmluZyB0b3AgbGV2ZWwgY2xhc3Nlcy4gKi8KICAgICAgICBwdWJsaWMgV3JpdGVhYmxlU2NvcGUgdG9wbGV2ZWxTY29wZTsKICAgICAgICAvKiogQSBzY29wZSBmb3IgYWxsIG5hbWVkIGltcG9ydHMuICovCiAgICAgICAgcHVibGljIE5hbWVkSW1wb3J0U2NvcGUgbmFtZWRJbXBvcnRTY29wZTsKICAgICAgICAvKiogQSBzY29wZSBmb3IgYWxsIGltcG9ydC1vbi1kZW1hbmRzLiAqLwogICAgICAgIHB1YmxpYyBTdGFySW1wb3J0U2NvcGUgc3RhckltcG9ydFNjb3BlOwogICAgICAgIC8qKiBMaW5lIHN0YXJ0aW5nIHBvc2l0aW9ucywgZGVmaW5lZCBvbmx5IGlmIG9wdGlvbiAtZyBpcyBzZXQuICovCiAgICAgICAgcHVibGljIFBvc2l0aW9uLkxpbmVNYXAgbGluZU1hcCA9IG51bGw7CiAgICAgICAgLyoqIEEgdGFibGUgdGhhdCBzdG9yZXMgYWxsIGRvY3VtZW50YXRpb24gY29tbWVudHMgaW5kZXhlZCBieSB0aGUgdHJlZQogICAgICAgICAqIG5vZGVzIHRoZXkgcmVmZXIgdG8uIGRlZmluZWQgb25seSBpZiBvcHRpb24gLXMgaXMgc2V0LiAqLwogICAgICAgIHB1YmxpYyBEb2NDb21tZW50VGFibGUgZG9jQ29tbWVudHMgPSBudWxsOwogICAgICAgIC8qIEFuIG9iamVjdCBlbmNhcHN1bGF0aW5nIGVuZGluZyBwb3NpdGlvbnMgb2Ygc291cmNlIHJhbmdlcyBpbmRleGVkIGJ5CiAgICAgICAgICogdGhlIHRyZWUgbm9kZXMgdGhleSBiZWxvbmcgdG8uIERlZmluZWQgb25seSBpZiBvcHRpb24gLVhqY292IGlzIHNldC4gKi8KICAgICAgICBwdWJsaWMgRW5kUG9zVGFibGUgZW5kUG9zaXRpb25zID0gbnVsbDsKICAgICAgICBwcm90ZWN0ZWQgSkNDb21waWxhdGlvblVuaXQoTGlzdDxKQ1RyZWU+IGRlZnMpIHsKICAgICAgICAgICAgdGhpcy5kZWZzID0gZGVmczsKICAgICAgICB9CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgeyB2LnZpc2l0VG9wTGV2ZWwodGhpcyk7IH0KCiAgICAgICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgS2luZCBnZXRLaW5kKCkgeyByZXR1cm4gS2luZC5DT01QSUxBVElPTl9VTklUOyB9CgogICAgICAgIHB1YmxpYyBKQ01vZHVsZURlY2wgZ2V0TW9kdWxlRGVjbCgpIHsKICAgICAgICAgICAgZm9yIChKQ1RyZWUgdHJlZSA6IGRlZnMpIHsKICAgICAgICAgICAgICAgIGlmICh0cmVlLmhhc1RhZyhNT0RVTEVERUYpKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChKQ01vZHVsZURlY2wpIHRyZWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgSkNQYWNrYWdlRGVjbCBnZXRQYWNrYWdlKCkgewogICAgICAgICAgICAvLyBQYWNrYWdlRGVjbCBtdXN0IGJlIHRoZSBmaXJzdCBlbnRyeSBpZiBpdCBleGlzdHMKICAgICAgICAgICAgaWYgKCFkZWZzLmlzRW1wdHkoKSAmJiBkZWZzLmhlYWQuaGFzVGFnKFBBQ0tBR0VERUYpKQogICAgICAgICAgICAgICAgcmV0dXJuIChKQ1BhY2thZ2VEZWNsKWRlZnMuaGVhZDsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIExpc3Q8SkNBbm5vdGF0aW9uPiBnZXRQYWNrYWdlQW5ub3RhdGlvbnMoKSB7CiAgICAgICAgICAgIEpDUGFja2FnZURlY2wgcGQgPSBnZXRQYWNrYWdlKCk7CiAgICAgICAgICAgIHJldHVybiBwZCAhPSBudWxsID8gcGQuZ2V0QW5ub3RhdGlvbnMoKSA6IExpc3QubmlsKCk7CiAgICAgICAgfQogICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIEV4cHJlc3Npb25UcmVlIGdldFBhY2thZ2VOYW1lKCkgewogICAgICAgICAgICBKQ1BhY2thZ2VEZWNsIHBkID0gZ2V0UGFja2FnZSgpOwogICAgICAgICAgICByZXR1cm4gcGQgIT0gbnVsbCA/IHBkLmdldFBhY2thZ2VOYW1lKCkgOiBudWxsOwogICAgICAgIH0KCiAgICAgICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgTGlzdDxKQ0ltcG9ydD4gZ2V0SW1wb3J0cygpIHsKICAgICAgICAgICAgTGlzdEJ1ZmZlcjxKQ0ltcG9ydD4gaW1wb3J0cyA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICAgICAgZm9yIChKQ1RyZWUgdHJlZSA6IGRlZnMpIHsKICAgICAgICAgICAgICAgIGlmICh0cmVlLmhhc1RhZyhJTVBPUlQpKQogICAgICAgICAgICAgICAgICAgIGltcG9ydHMuYXBwZW5kKChKQ0ltcG9ydCl0cmVlKTsKICAgICAgICAgICAgICAgIGVsc2UgaWYgKCF0cmVlLmhhc1RhZyhQQUNLQUdFREVGKSAmJiAhdHJlZS5oYXNUYWcoU0tJUCkpCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGltcG9ydHMudG9MaXN0KCk7CiAgICAgICAgfQogICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIEphdmFGaWxlT2JqZWN0IGdldFNvdXJjZUZpbGUoKSB7CiAgICAgICAgICAgIHJldHVybiBzb3VyY2VmaWxlOwogICAgICAgIH0KICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBQb3NpdGlvbi5MaW5lTWFwIGdldExpbmVNYXAoKSB7CiAgICAgICAgICAgIHJldHVybiBsaW5lTWFwOwogICAgICAgIH0KICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBMaXN0PEpDVHJlZT4gZ2V0VHlwZURlY2xzKCkgewogICAgICAgICAgICBMaXN0PEpDVHJlZT4gdHlwZURlZnM7CiAgICAgICAgICAgIGZvciAodHlwZURlZnMgPSBkZWZzOyAhdHlwZURlZnMuaXNFbXB0eSgpOyB0eXBlRGVmcyA9IHR5cGVEZWZzLnRhaWwpCiAgICAgICAgICAgICAgICBpZiAoIXR5cGVEZWZzLmhlYWQuaGFzVGFnKFBBQ0tBR0VERUYpICYmICF0eXBlRGVmcy5oZWFkLmhhc1RhZyhJTVBPUlQpKQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICByZXR1cm4gdHlwZURlZnM7CiAgICAgICAgfQogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyA8UixEPiBSIGFjY2VwdChUcmVlVmlzaXRvcjxSLEQ+IHYsIEQgZCkgewogICAgICAgICAgICByZXR1cm4gdi52aXNpdENvbXBpbGF0aW9uVW5pdCh0aGlzLCBkKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBUYWcgZ2V0VGFnKCkgewogICAgICAgICAgICByZXR1cm4gVE9QTEVWRUw7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogUGFja2FnZSBkZWZpbml0aW9uLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIEpDUGFja2FnZURlY2wgZXh0ZW5kcyBKQ1RyZWUgaW1wbGVtZW50cyBQYWNrYWdlVHJlZSB7CiAgICAgICAgcHVibGljIExpc3Q8SkNBbm5vdGF0aW9uPiBhbm5vdGF0aW9uczsKICAgICAgICAvKiogVGhlIHRyZWUgcmVwcmVzZW50aW5nIHRoZSBwYWNrYWdlIGNsYXVzZS4gKi8KICAgICAgICBwdWJsaWMgSkNFeHByZXNzaW9uIHBpZDsKICAgICAgICBwdWJsaWMgUGFja2FnZVN5bWJvbCBwYWNrZ2U7CiAgICAgICAgcHVibGljIEpDUGFja2FnZURlY2woTGlzdDxKQ0Fubm90YXRpb24+IGFubm90YXRpb25zLCBKQ0V4cHJlc3Npb24gcGlkKSB7CiAgICAgICAgICAgIHRoaXMuYW5ub3RhdGlvbnMgPSBhbm5vdGF0aW9uczsKICAgICAgICAgICAgdGhpcy5waWQgPSBwaWQ7CiAgICAgICAgfQogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsgdi52aXNpdFBhY2thZ2VEZWYodGhpcyk7IH0KICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBLaW5kIGdldEtpbmQoKSB7CiAgICAgICAgICAgIHJldHVybiBLaW5kLlBBQ0tBR0U7CiAgICAgICAgfQogICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIExpc3Q8SkNBbm5vdGF0aW9uPiBnZXRBbm5vdGF0aW9ucygpIHsKICAgICAgICAgICAgcmV0dXJuIGFubm90YXRpb25zOwogICAgICAgIH0KICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBKQ0V4cHJlc3Npb24gZ2V0UGFja2FnZU5hbWUoKSB7CiAgICAgICAgICAgIHJldHVybiBwaWQ7CiAgICAgICAgfQogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyA8UixEPiBSIGFjY2VwdChUcmVlVmlzaXRvcjxSLEQ+IHYsIEQgZCkgewogICAgICAgICAgICByZXR1cm4gdi52aXNpdFBhY2thZ2UodGhpcywgZCk7CiAgICAgICAgfQogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBUYWcgZ2V0VGFnKCkgewogICAgICAgICAgICByZXR1cm4gUEFDS0FHRURFRjsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBBbiBpbXBvcnQgY2xhdXNlLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIEpDSW1wb3J0IGV4dGVuZHMgSkNUcmVlIGltcGxlbWVudHMgSW1wb3J0VHJlZSB7CiAgICAgICAgcHVibGljIGJvb2xlYW4gc3RhdGljSW1wb3J0OwogICAgICAgIC8qKiBUaGUgaW1wb3J0ZWQgY2xhc3MoZXMpLiAqLwogICAgICAgIHB1YmxpYyBKQ1RyZWUgcXVhbGlkOwogICAgICAgIHB1YmxpYyBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuU2NvcGUgaW1wb3J0U2NvcGU7CiAgICAgICAgcHJvdGVjdGVkIEpDSW1wb3J0KEpDVHJlZSBxdWFsaWQsIGJvb2xlYW4gaW1wb3J0U3RhdGljKSB7CiAgICAgICAgICAgIHRoaXMucXVhbGlkID0gcXVhbGlkOwogICAgICAgICAgICB0aGlzLnN0YXRpY0ltcG9ydCA9IGltcG9ydFN0YXRpYzsKICAgICAgICB9CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgeyB2LnZpc2l0SW1wb3J0KHRoaXMpOyB9CgogICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIGJvb2xlYW4gaXNTdGF0aWMoKSB7IHJldHVybiBzdGF0aWNJbXBvcnQ7IH0KICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBKQ1RyZWUgZ2V0UXVhbGlmaWVkSWRlbnRpZmllcigpIHsgcmV0dXJuIHF1YWxpZDsgfQoKICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBLaW5kIGdldEtpbmQoKSB7IHJldHVybiBLaW5kLklNUE9SVDsgfQogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyA8UixEPiBSIGFjY2VwdChUcmVlVmlzaXRvcjxSLEQ+IHYsIEQgZCkgewogICAgICAgICAgICByZXR1cm4gdi52aXNpdEltcG9ydCh0aGlzLCBkKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBUYWcgZ2V0VGFnKCkgewogICAgICAgICAgICByZXR1cm4gSU1QT1JUOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGFic3RyYWN0IGNsYXNzIEpDU3RhdGVtZW50IGV4dGVuZHMgSkNUcmVlIGltcGxlbWVudHMgU3RhdGVtZW50VHJlZSB7CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIEpDU3RhdGVtZW50IHNldFR5cGUoVHlwZSB0eXBlKSB7CiAgICAgICAgICAgIHN1cGVyLnNldFR5cGUodHlwZSk7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgSkNTdGF0ZW1lbnQgc2V0UG9zKGludCBwb3MpIHsKICAgICAgICAgICAgc3VwZXIuc2V0UG9zKHBvcyk7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGFic3RyYWN0IGNsYXNzIEpDRXhwcmVzc2lvbiBleHRlbmRzIEpDVHJlZSBpbXBsZW1lbnRzIEV4cHJlc3Npb25UcmVlIHsKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgSkNFeHByZXNzaW9uIHNldFR5cGUoVHlwZSB0eXBlKSB7CiAgICAgICAgICAgIHN1cGVyLnNldFR5cGUodHlwZSk7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgSkNFeHByZXNzaW9uIHNldFBvcyhpbnQgcG9zKSB7CiAgICAgICAgICAgIHN1cGVyLnNldFBvcyhwb3MpOwogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBib29sZWFuIGlzUG9seSgpIHsgcmV0dXJuIGZhbHNlOyB9CiAgICAgICAgcHVibGljIGJvb2xlYW4gaXNTdGFuZGFsb25lKCkgeyByZXR1cm4gdHJ1ZTsgfQogICAgfQoKICAgIC8qKgogICAgICogQ29tbW9uIHN1cGVydHlwZSBmb3IgYWxsIHBvbHkgZXhwcmVzc2lvbiB0cmVlcyAobGFtYmRhLCBtZXRob2QgcmVmZXJlbmNlcywKICAgICAqIGNvbmRpdGlvbmFscywgbWV0aG9kIGFuZCBjb25zdHJ1Y3RvciBjYWxscykKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBhYnN0cmFjdCBjbGFzcyBKQ1BvbHlFeHByZXNzaW9uIGV4dGVuZHMgSkNFeHByZXNzaW9uIHsKCiAgICAgICAgLyoqCiAgICAgICAgICogQSBwb2x5IGV4cHJlc3Npb24gY2FuIG9ubHkgYmUgdHJ1bHkgJ3BvbHknIGluIGNlcnRhaW4gY29udGV4dHMKICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgZW51bSBQb2x5S2luZCB7CiAgICAgICAgICAgIC8qKiBwb2x5IGV4cHJlc3Npb24gdG8gYmUgdHJlYXRlZCBhcyBhIHN0YW5kYWxvbmUgZXhwcmVzc2lvbiAqLwogICAgICAgICAgICBTVEFOREFMT05FLAogICAgICAgICAgICAvKiogdHJ1ZSBwb2x5IGV4cHJlc3Npb24gKi8KICAgICAgICAgICAgUE9MWQogICAgICAgIH0KCiAgICAgICAgLyoqIGlzIHRoaXMgcG9seSBleHByZXNzaW9uIGEgJ3RydWUnIHBvbHkgZXhwcmVzc2lvbj8gKi8KICAgICAgICBwdWJsaWMgUG9seUtpbmQgcG9seUtpbmQ7CgogICAgICAgIEBPdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBpc1BvbHkoKSB7IHJldHVybiBwb2x5S2luZCA9PSBQb2x5S2luZC5QT0xZOyB9CiAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGlzU3RhbmRhbG9uZSgpIHsgcmV0dXJuIHBvbHlLaW5kID09IFBvbHlLaW5kLlNUQU5EQUxPTkU7IH0KICAgIH0KCiAgICAvKioKICAgICAqIENvbW1vbiBzdXBlcnR5cGUgZm9yIGFsbCBmdW5jdGlvbmFsIGV4cHJlc3Npb24gdHJlZXMgKGxhbWJkYSBhbmQgbWV0aG9kIHJlZmVyZW5jZXMpCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgYWJzdHJhY3QgY2xhc3MgSkNGdW5jdGlvbmFsRXhwcmVzc2lvbiBleHRlbmRzIEpDUG9seUV4cHJlc3Npb24gewoKICAgICAgICBwdWJsaWMgSkNGdW5jdGlvbmFsRXhwcmVzc2lvbigpIHsKICAgICAgICAgICAgLy9hIGZ1bmN0aW9uYWwgZXhwcmVzc2lvbiBpcyBhbHdheXMgYSAndHJ1ZScgcG9seQogICAgICAgICAgICBwb2x5S2luZCA9IFBvbHlLaW5kLlBPTFk7CiAgICAgICAgfQoKICAgICAgICAvKiogbGlzdCBvZiB0YXJnZXQgdHlwZXMgaW5mZXJyZWQgZm9yIHRoaXMgZnVuY3Rpb25hbCBleHByZXNzaW9uLiAqLwogICAgICAgIHB1YmxpYyBMaXN0PFR5cGU+IHRhcmdldHM7CgogICAgICAgIHB1YmxpYyBUeXBlIGdldERlc2NyaXB0b3JUeXBlKFR5cGVzIHR5cGVzKSB7CiAgICAgICAgICAgIHJldHVybiB0YXJnZXRzLm5vbkVtcHR5KCkgPyB0eXBlcy5maW5kRGVzY3JpcHRvclR5cGUodGFyZ2V0cy5oZWFkKSA6IHR5cGVzLmNyZWF0ZUVycm9yVHlwZShudWxsKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBBIGNsYXNzIGRlZmluaXRpb24uCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgSkNDbGFzc0RlY2wgZXh0ZW5kcyBKQ1N0YXRlbWVudCBpbXBsZW1lbnRzIENsYXNzVHJlZSB7CiAgICAgICAgLyoqIHRoZSBtb2RpZmllcnMgKi8KICAgICAgICBwdWJsaWMgSkNNb2RpZmllcnMgbW9kczsKICAgICAgICAvKiogdGhlIG5hbWUgb2YgdGhlIGNsYXNzICovCiAgICAgICAgcHVibGljIE5hbWUgbmFtZTsKICAgICAgICAvKiogZm9ybWFsIGNsYXNzIHBhcmFtZXRlcnMgKi8KICAgICAgICBwdWJsaWMgTGlzdDxKQ1R5cGVQYXJhbWV0ZXI+IHR5cGFyYW1zOwogICAgICAgIC8qKiB0aGUgY2xhc3NlcyB0aGlzIGNsYXNzIGV4dGVuZHMgKi8KICAgICAgICBwdWJsaWMgSkNFeHByZXNzaW9uIGV4dGVuZGluZzsKICAgICAgICAvKiogdGhlIGludGVyZmFjZXMgaW1wbGVtZW50ZWQgYnkgdGhpcyBjbGFzcyAqLwogICAgICAgIHB1YmxpYyBMaXN0PEpDRXhwcmVzc2lvbj4gaW1wbGVtZW50aW5nOwogICAgICAgIC8qKiBhbGwgdmFyaWFibGVzIGFuZCBtZXRob2RzIGRlZmluZWQgaW4gdGhpcyBjbGFzcyAqLwogICAgICAgIHB1YmxpYyBMaXN0PEpDVHJlZT4gZGVmczsKICAgICAgICAvKiogdGhlIHN5bWJvbCAqLwogICAgICAgIHB1YmxpYyBDbGFzc1N5bWJvbCBzeW07CiAgICAgICAgcHJvdGVjdGVkIEpDQ2xhc3NEZWNsKEpDTW9kaWZpZXJzIG1vZHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIE5hbWUgbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgTGlzdDxKQ1R5cGVQYXJhbWV0ZXI+IHR5cGFyYW1zLAogICAgICAgICAgICAgICAgICAgICAgICAgICBKQ0V4cHJlc3Npb24gZXh0ZW5kaW5nLAogICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0PEpDRXhwcmVzc2lvbj4gaW1wbGVtZW50aW5nLAogICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0PEpDVHJlZT4gZGVmcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2xhc3NTeW1ib2wgc3ltKQogICAgICAgIHsKICAgICAgICAgICAgdGhpcy5tb2RzID0gbW9kczsKICAgICAgICAgICAgdGhpcy5uYW1lID0gbmFtZTsKICAgICAgICAgICAgdGhpcy50eXBhcmFtcyA9IHR5cGFyYW1zOwogICAgICAgICAgICB0aGlzLmV4dGVuZGluZyA9IGV4dGVuZGluZzsKICAgICAgICAgICAgdGhpcy5pbXBsZW1lbnRpbmcgPSBpbXBsZW1lbnRpbmc7CiAgICAgICAgICAgIHRoaXMuZGVmcyA9IGRlZnM7CiAgICAgICAgICAgIHRoaXMuc3ltID0gc3ltOwogICAgICAgIH0KICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7IHYudmlzaXRDbGFzc0RlZih0aGlzKTsgfQoKICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBLaW5kIGdldEtpbmQoKSB7CiAgICAgICAgICAgIGlmICgobW9kcy5mbGFncyAmIEZsYWdzLkFOTk9UQVRJT04pICE9IDApCiAgICAgICAgICAgICAgICByZXR1cm4gS2luZC5BTk5PVEFUSU9OX1RZUEU7CiAgICAgICAgICAgIGVsc2UgaWYgKChtb2RzLmZsYWdzICYgRmxhZ3MuSU5URVJGQUNFKSAhPSAwKQogICAgICAgICAgICAgICAgcmV0dXJuIEtpbmQuSU5URVJGQUNFOwogICAgICAgICAgICBlbHNlIGlmICgobW9kcy5mbGFncyAmIEZsYWdzLkVOVU0pICE9IDApCiAgICAgICAgICAgICAgICByZXR1cm4gS2luZC5FTlVNOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICByZXR1cm4gS2luZC5DTEFTUzsKICAgICAgICB9CgogICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIEpDTW9kaWZpZXJzIGdldE1vZGlmaWVycygpIHsgcmV0dXJuIG1vZHM7IH0KICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBOYW1lIGdldFNpbXBsZU5hbWUoKSB7IHJldHVybiBuYW1lOyB9CiAgICAgICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgTGlzdDxKQ1R5cGVQYXJhbWV0ZXI+IGdldFR5cGVQYXJhbWV0ZXJzKCkgewogICAgICAgICAgICByZXR1cm4gdHlwYXJhbXM7CiAgICAgICAgfQogICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIEpDRXhwcmVzc2lvbiBnZXRFeHRlbmRzQ2xhdXNlKCkgeyByZXR1cm4gZXh0ZW5kaW5nOyB9CiAgICAgICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgTGlzdDxKQ0V4cHJlc3Npb24+IGdldEltcGxlbWVudHNDbGF1c2UoKSB7CiAgICAgICAgICAgIHJldHVybiBpbXBsZW1lbnRpbmc7CiAgICAgICAgfQogICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIExpc3Q8SkNUcmVlPiBnZXRNZW1iZXJzKCkgewogICAgICAgICAgICByZXR1cm4gZGVmczsKICAgICAgICB9CiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIDxSLEQ+IFIgYWNjZXB0KFRyZWVWaXNpdG9yPFIsRD4gdiwgRCBkKSB7CiAgICAgICAgICAgIHJldHVybiB2LnZpc2l0Q2xhc3ModGhpcywgZCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgVGFnIGdldFRhZygpIHsKICAgICAgICAgICAgcmV0dXJuIENMQVNTREVGOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEEgbWV0aG9kIGRlZmluaXRpb24uCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgSkNNZXRob2REZWNsIGV4dGVuZHMgSkNUcmVlIGltcGxlbWVudHMgTWV0aG9kVHJlZSB7CiAgICAgICAgLyoqIG1ldGhvZCBtb2RpZmllcnMgKi8KICAgICAgICBwdWJsaWMgSkNNb2RpZmllcnMgbW9kczsKICAgICAgICAvKiogbWV0aG9kIG5hbWUgKi8KICAgICAgICBwdWJsaWMgTmFtZSBuYW1lOwogICAgICAgIC8qKiB0eXBlIG9mIG1ldGhvZCByZXR1cm4gdmFsdWUgKi8KICAgICAgICBwdWJsaWMgSkNFeHByZXNzaW9uIHJlc3R5cGU7CiAgICAgICAgLyoqIHR5cGUgcGFyYW1ldGVycyAqLwogICAgICAgIHB1YmxpYyBMaXN0PEpDVHlwZVBhcmFtZXRlcj4gdHlwYXJhbXM7CiAgICAgICAgLyoqIHJlY2VpdmVyIHBhcmFtZXRlciAqLwogICAgICAgIHB1YmxpYyBKQ1ZhcmlhYmxlRGVjbCByZWN2cGFyYW07CiAgICAgICAgLyoqIHZhbHVlIHBhcmFtZXRlcnMgKi8KICAgICAgICBwdWJsaWMgTGlzdDxKQ1ZhcmlhYmxlRGVjbD4gcGFyYW1zOwogICAgICAgIC8qKiBleGNlcHRpb25zIHRocm93biBieSB0aGlzIG1ldGhvZCAqLwogICAgICAgIHB1YmxpYyBMaXN0PEpDRXhwcmVzc2lvbj4gdGhyb3duOwogICAgICAgIC8qKiBzdGF0ZW1lbnRzIGluIHRoZSBtZXRob2QgKi8KICAgICAgICBwdWJsaWMgSkNCbG9jayBib2R5OwogICAgICAgIC8qKiBkZWZhdWx0IHZhbHVlLCBmb3IgYW5ub3RhdGlvbiB0eXBlcyAqLwogICAgICAgIHB1YmxpYyBKQ0V4cHJlc3Npb24gZGVmYXVsdFZhbHVlOwogICAgICAgIC8qKiBtZXRob2Qgc3ltYm9sICovCiAgICAgICAgcHVibGljIE1ldGhvZFN5bWJvbCBzeW07CiAgICAgICAgcHJvdGVjdGVkIEpDTWV0aG9kRGVjbChKQ01vZGlmaWVycyBtb2RzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgTmFtZSBuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgSkNFeHByZXNzaW9uIHJlc3R5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0PEpDVHlwZVBhcmFtZXRlcj4gdHlwYXJhbXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBKQ1ZhcmlhYmxlRGVjbCByZWN2cGFyYW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0PEpDVmFyaWFibGVEZWNsPiBwYXJhbXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0PEpDRXhwcmVzc2lvbj4gdGhyb3duLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgSkNCbG9jayBib2R5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgSkNFeHByZXNzaW9uIGRlZmF1bHRWYWx1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1ldGhvZFN5bWJvbCBzeW0pCiAgICAgICAgewogICAgICAgICAgICB0aGlzLm1vZHMgPSBtb2RzOwogICAgICAgICAgICB0aGlzLm5hbWUgPSBuYW1lOwogICAgICAgICAgICB0aGlzLnJlc3R5cGUgPSByZXN0eXBlOwogICAgICAgICAgICB0aGlzLnR5cGFyYW1zID0gdHlwYXJhbXM7CiAgICAgICAgICAgIHRoaXMucGFyYW1zID0gcGFyYW1zOwogICAgICAgICAgICB0aGlzLnJlY3ZwYXJhbSA9IHJlY3ZwYXJhbTsKICAgICAgICAgICAgLy8gVE9ETzogZG8gc29tZXRoaW5nIHNwZWNpYWwgaWYgdGhlIGdpdmVuIHR5cGUgaXMgbnVsbD8KICAgICAgICAgICAgLy8gcmVjZWl2ZXIgIT0gbnVsbCA/IHJlY2VpdmVyIDogTGlzdC48SkNUeXBlQW5ub3RhdGlvbj5uaWwoKSk7CiAgICAgICAgICAgIHRoaXMudGhyb3duID0gdGhyb3duOwogICAgICAgICAgICB0aGlzLmJvZHkgPSBib2R5OwogICAgICAgICAgICB0aGlzLmRlZmF1bHRWYWx1ZSA9IGRlZmF1bHRWYWx1ZTsKICAgICAgICAgICAgdGhpcy5zeW0gPSBzeW07CiAgICAgICAgfQogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsgdi52aXNpdE1ldGhvZERlZih0aGlzKTsgfQoKICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBLaW5kIGdldEtpbmQoKSB7IHJldHVybiBLaW5kLk1FVEhPRDsgfQogICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIEpDTW9kaWZpZXJzIGdldE1vZGlmaWVycygpIHsgcmV0dXJuIG1vZHM7IH0KICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBOYW1lIGdldE5hbWUoKSB7IHJldHVybiBuYW1lOyB9CiAgICAgICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgSkNUcmVlIGdldFJldHVyblR5cGUoKSB7IHJldHVybiByZXN0eXBlOyB9CiAgICAgICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgTGlzdDxKQ1R5cGVQYXJhbWV0ZXI+IGdldFR5cGVQYXJhbWV0ZXJzKCkgewogICAgICAgICAgICByZXR1cm4gdHlwYXJhbXM7CiAgICAgICAgfQogICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIExpc3Q8SkNWYXJpYWJsZURlY2w+IGdldFBhcmFtZXRlcnMoKSB7CiAgICAgICAgICAgIHJldHVybiBwYXJhbXM7CiAgICAgICAgfQogICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIEpDVmFyaWFibGVEZWNsIGdldFJlY2VpdmVyUGFyYW1ldGVyKCkgeyByZXR1cm4gcmVjdnBhcmFtOyB9CiAgICAgICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgTGlzdDxKQ0V4cHJlc3Npb24+IGdldFRocm93cygpIHsKICAgICAgICAgICAgcmV0dXJuIHRocm93bjsKICAgICAgICB9CiAgICAgICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgSkNCbG9jayBnZXRCb2R5KCkgeyByZXR1cm4gYm9keTsgfQogICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIEpDVHJlZSBnZXREZWZhdWx0VmFsdWUoKSB7IC8vIGZvciBhbm5vdGF0aW9uIHR5cGVzCiAgICAgICAgICAgIHJldHVybiBkZWZhdWx0VmFsdWU7CiAgICAgICAgfQogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyA8UixEPiBSIGFjY2VwdChUcmVlVmlzaXRvcjxSLEQ+IHYsIEQgZCkgewogICAgICAgICAgICByZXR1cm4gdi52aXNpdE1ldGhvZCh0aGlzLCBkKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBUYWcgZ2V0VGFnKCkgewogICAgICAgICAgICByZXR1cm4gTUVUSE9EREVGOwogICAgICAgIH0KICB9CgogICAgLyoqCiAgICAgKiBBIHZhcmlhYmxlIGRlZmluaXRpb24uCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgSkNWYXJpYWJsZURlY2wgZXh0ZW5kcyBKQ1N0YXRlbWVudCBpbXBsZW1lbnRzIFZhcmlhYmxlVHJlZSB7CiAgICAgICAgLyoqIHZhcmlhYmxlIG1vZGlmaWVycyAqLwogICAgICAgIHB1YmxpYyBKQ01vZGlmaWVycyBtb2RzOwogICAgICAgIC8qKiB2YXJpYWJsZSBuYW1lICovCiAgICAgICAgcHVibGljIE5hbWUgbmFtZTsKICAgICAgICAvKiogdmFyaWFibGUgbmFtZSBleHByZXNzaW9uICovCiAgICAgICAgcHVibGljIEpDRXhwcmVzc2lvbiBuYW1lZXhwcjsKICAgICAgICAvKiogdHlwZSBvZiB0aGUgdmFyaWFibGUgKi8KICAgICAgICBwdWJsaWMgSkNFeHByZXNzaW9uIHZhcnR5cGU7CiAgICAgICAgLyoqIHZhcmlhYmxlJ3MgaW5pdGlhbCB2YWx1ZSAqLwogICAgICAgIHB1YmxpYyBKQ0V4cHJlc3Npb24gaW5pdDsKICAgICAgICAvKiogc3ltYm9sICovCiAgICAgICAgcHVibGljIFZhclN5bWJvbCBzeW07CgogICAgICAgIHByb3RlY3RlZCBKQ1ZhcmlhYmxlRGVjbChKQ01vZGlmaWVycyBtb2RzLAogICAgICAgICAgICAgICAgICAgICAgICAgTmFtZSBuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgSkNFeHByZXNzaW9uIHZhcnR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICBKQ0V4cHJlc3Npb24gaW5pdCwKICAgICAgICAgICAgICAgICAgICAgICAgIFZhclN5bWJvbCBzeW0pIHsKICAgICAgICAgICAgdGhpcy5tb2RzID0gbW9kczsKICAgICAgICAgICAgdGhpcy5uYW1lID0gbmFtZTsKICAgICAgICAgICAgdGhpcy52YXJ0eXBlID0gdmFydHlwZTsKICAgICAgICAgICAgdGhpcy5pbml0ID0gaW5pdDsKICAgICAgICAgICAgdGhpcy5zeW0gPSBzeW07CiAgICAgICAgfQoKICAgICAgICBwcm90ZWN0ZWQgSkNWYXJpYWJsZURlY2woSkNNb2RpZmllcnMgbW9kcywKICAgICAgICAgICAgICAgICAgICAgICAgIEpDRXhwcmVzc2lvbiBuYW1lZXhwciwKICAgICAgICAgICAgICAgICAgICAgICAgIEpDRXhwcmVzc2lvbiB2YXJ0eXBlKSB7CiAgICAgICAgICAgIHRoaXMobW9kcywgbnVsbCwgdmFydHlwZSwgbnVsbCwgbnVsbCk7CiAgICAgICAgICAgIHRoaXMubmFtZWV4cHIgPSBuYW1lZXhwcjsKICAgICAgICAgICAgaWYgKG5hbWVleHByLmhhc1RhZyhUYWcuSURFTlQpKSB7CiAgICAgICAgICAgICAgICB0aGlzLm5hbWUgPSAoKEpDSWRlbnQpbmFtZWV4cHIpLm5hbWU7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvLyBPbmx5IG90aGVyIG9wdGlvbiBpcyBxdWFsaWZpZWQgbmFtZSB4LnkudGhpczsKICAgICAgICAgICAgICAgIHRoaXMubmFtZSA9ICgoSkNGaWVsZEFjY2VzcyluYW1lZXhwcikubmFtZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgeyB2LnZpc2l0VmFyRGVmKHRoaXMpOyB9CgogICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIEtpbmQgZ2V0S2luZCgpIHsgcmV0dXJuIEtpbmQuVkFSSUFCTEU7IH0KICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBKQ01vZGlmaWVycyBnZXRNb2RpZmllcnMoKSB7IHJldHVybiBtb2RzOyB9CiAgICAgICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgTmFtZSBnZXROYW1lKCkgeyByZXR1cm4gbmFtZTsgfQogICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIEpDRXhwcmVzc2lvbiBnZXROYW1lRXhwcmVzc2lvbigpIHsgcmV0dXJuIG5hbWVleHByOyB9CiAgICAgICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgSkNUcmVlIGdldFR5cGUoKSB7IHJldHVybiB2YXJ0eXBlOyB9CiAgICAgICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgSkNFeHByZXNzaW9uIGdldEluaXRpYWxpemVyKCkgewogICAgICAgICAgICByZXR1cm4gaW5pdDsKICAgICAgICB9CiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIDxSLEQ+IFIgYWNjZXB0KFRyZWVWaXNpdG9yPFIsRD4gdiwgRCBkKSB7CiAgICAgICAgICAgIHJldHVybiB2LnZpc2l0VmFyaWFibGUodGhpcywgZCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgVGFnIGdldFRhZygpIHsKICAgICAgICAgICAgcmV0dXJuIFZBUkRFRjsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBBIG5vLW9wIHN0YXRlbWVudCAiOyIuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgSkNTa2lwIGV4dGVuZHMgSkNTdGF0ZW1lbnQgaW1wbGVtZW50cyBFbXB0eVN0YXRlbWVudFRyZWUgewogICAgICAgIHByb3RlY3RlZCBKQ1NraXAoKSB7CiAgICAgICAgfQogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsgdi52aXNpdFNraXAodGhpcyk7IH0KCiAgICAgICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgS2luZCBnZXRLaW5kKCkgeyByZXR1cm4gS2luZC5FTVBUWV9TVEFURU1FTlQ7IH0KICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgPFIsRD4gUiBhY2NlcHQoVHJlZVZpc2l0b3I8UixEPiB2LCBEIGQpIHsKICAgICAgICAgICAgcmV0dXJuIHYudmlzaXRFbXB0eVN0YXRlbWVudCh0aGlzLCBkKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBUYWcgZ2V0VGFnKCkgewogICAgICAgICAgICByZXR1cm4gU0tJUDsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBBIHN0YXRlbWVudCBibG9jay4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBjbGFzcyBKQ0Jsb2NrIGV4dGVuZHMgSkNTdGF0ZW1lbnQgaW1wbGVtZW50cyBCbG9ja1RyZWUgewogICAgICAgIC8qKiBmbGFncyAqLwogICAgICAgIHB1YmxpYyBsb25nIGZsYWdzOwogICAgICAgIC8qKiBzdGF0ZW1lbnRzICovCiAgICAgICAgcHVibGljIExpc3Q8SkNTdGF0ZW1lbnQ+IHN0YXRzOwogICAgICAgIC8qKiBQb3NpdGlvbiBvZiBjbG9zaW5nIGJyYWNlLCBvcHRpb25hbC4gKi8KICAgICAgICBwdWJsaWMgaW50IGVuZHBvcyA9IFBvc2l0aW9uLk5PUE9TOwogICAgICAgIHByb3RlY3RlZCBKQ0Jsb2NrKGxvbmcgZmxhZ3MsIExpc3Q8SkNTdGF0ZW1lbnQ+IHN0YXRzKSB7CiAgICAgICAgICAgIHRoaXMuc3RhdHMgPSBzdGF0czsKICAgICAgICAgICAgdGhpcy5mbGFncyA9IGZsYWdzOwogICAgICAgIH0KICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7IHYudmlzaXRCbG9jayh0aGlzKTsgfQoKICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBLaW5kIGdldEtpbmQoKSB7IHJldHVybiBLaW5kLkJMT0NLOyB9CiAgICAgICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgTGlzdDxKQ1N0YXRlbWVudD4gZ2V0U3RhdGVtZW50cygpIHsKICAgICAgICAgICAgcmV0dXJuIHN0YXRzOwogICAgICAgIH0KICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBib29sZWFuIGlzU3RhdGljKCkgeyByZXR1cm4gKGZsYWdzICYgRmxhZ3MuU1RBVElDKSAhPSAwOyB9CiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIDxSLEQ+IFIgYWNjZXB0KFRyZWVWaXNpdG9yPFIsRD4gdiwgRCBkKSB7CiAgICAgICAgICAgIHJldHVybiB2LnZpc2l0QmxvY2sodGhpcywgZCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgVGFnIGdldFRhZygpIHsKICAgICAgICAgICAgcmV0dXJuIEJMT0NLOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEEgZG8gbG9vcAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIEpDRG9XaGlsZUxvb3AgZXh0ZW5kcyBKQ1N0YXRlbWVudCBpbXBsZW1lbnRzIERvV2hpbGVMb29wVHJlZSB7CiAgICAgICAgcHVibGljIEpDU3RhdGVtZW50IGJvZHk7CiAgICAgICAgcHVibGljIEpDRXhwcmVzc2lvbiBjb25kOwogICAgICAgIHByb3RlY3RlZCBKQ0RvV2hpbGVMb29wKEpDU3RhdGVtZW50IGJvZHksIEpDRXhwcmVzc2lvbiBjb25kKSB7CiAgICAgICAgICAgIHRoaXMuYm9keSA9IGJvZHk7CiAgICAgICAgICAgIHRoaXMuY29uZCA9IGNvbmQ7CiAgICAgICAgfQogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsgdi52aXNpdERvTG9vcCh0aGlzKTsgfQoKICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBLaW5kIGdldEtpbmQoKSB7IHJldHVybiBLaW5kLkRPX1dISUxFX0xPT1A7IH0KICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBKQ0V4cHJlc3Npb24gZ2V0Q29uZGl0aW9uKCkgeyByZXR1cm4gY29uZDsgfQogICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIEpDU3RhdGVtZW50IGdldFN0YXRlbWVudCgpIHsgcmV0dXJuIGJvZHk7IH0KICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgPFIsRD4gUiBhY2NlcHQoVHJlZVZpc2l0b3I8UixEPiB2LCBEIGQpIHsKICAgICAgICAgICAgcmV0dXJuIHYudmlzaXREb1doaWxlTG9vcCh0aGlzLCBkKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBUYWcgZ2V0VGFnKCkgewogICAgICAgICAgICByZXR1cm4gRE9MT09QOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEEgd2hpbGUgbG9vcAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIEpDV2hpbGVMb29wIGV4dGVuZHMgSkNTdGF0ZW1lbnQgaW1wbGVtZW50cyBXaGlsZUxvb3BUcmVlIHsKICAgICAgICBwdWJsaWMgSkNFeHByZXNzaW9uIGNvbmQ7CiAgICAgICAgcHVibGljIEpDU3RhdGVtZW50IGJvZHk7CiAgICAgICAgcHJvdGVjdGVkIEpDV2hpbGVMb29wKEpDRXhwcmVzc2lvbiBjb25kLCBKQ1N0YXRlbWVudCBib2R5KSB7CiAgICAgICAgICAgIHRoaXMuY29uZCA9IGNvbmQ7CiAgICAgICAgICAgIHRoaXMuYm9keSA9IGJvZHk7CiAgICAgICAgfQogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsgdi52aXNpdFdoaWxlTG9vcCh0aGlzKTsgfQoKICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBLaW5kIGdldEtpbmQoKSB7IHJldHVybiBLaW5kLldISUxFX0xPT1A7IH0KICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBKQ0V4cHJlc3Npb24gZ2V0Q29uZGl0aW9uKCkgeyByZXR1cm4gY29uZDsgfQogICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIEpDU3RhdGVtZW50IGdldFN0YXRlbWVudCgpIHsgcmV0dXJuIGJvZHk7IH0KICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgPFIsRD4gUiBhY2NlcHQoVHJlZVZpc2l0b3I8UixEPiB2LCBEIGQpIHsKICAgICAgICAgICAgcmV0dXJuIHYudmlzaXRXaGlsZUxvb3AodGhpcywgZCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgVGFnIGdldFRhZygpIHsKICAgICAgICAgICAgcmV0dXJuIFdISUxFTE9PUDsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBBIGZvciBsb29wLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIEpDRm9yTG9vcCBleHRlbmRzIEpDU3RhdGVtZW50IGltcGxlbWVudHMgRm9yTG9vcFRyZWUgewogICAgICAgIHB1YmxpYyBMaXN0PEpDU3RhdGVtZW50PiBpbml0OwogICAgICAgIHB1YmxpYyBKQ0V4cHJlc3Npb24gY29uZDsKICAgICAgICBwdWJsaWMgTGlzdDxKQ0V4cHJlc3Npb25TdGF0ZW1lbnQ+IHN0ZXA7CiAgICAgICAgcHVibGljIEpDU3RhdGVtZW50IGJvZHk7CiAgICAgICAgcHJvdGVjdGVkIEpDRm9yTG9vcChMaXN0PEpDU3RhdGVtZW50PiBpbml0LAogICAgICAgICAgICAgICAgICAgICAgICAgIEpDRXhwcmVzc2lvbiBjb25kLAogICAgICAgICAgICAgICAgICAgICAgICAgIExpc3Q8SkNFeHByZXNzaW9uU3RhdGVtZW50PiB1cGRhdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgSkNTdGF0ZW1lbnQgYm9keSkKICAgICAgICB7CiAgICAgICAgICAgIHRoaXMuaW5pdCA9IGluaXQ7CiAgICAgICAgICAgIHRoaXMuY29uZCA9IGNvbmQ7CiAgICAgICAgICAgIHRoaXMuc3RlcCA9IHVwZGF0ZTsKICAgICAgICAgICAgdGhpcy5ib2R5ID0gYm9keTsKICAgICAgICB9CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgeyB2LnZpc2l0Rm9yTG9vcCh0aGlzKTsgfQoKICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBLaW5kIGdldEtpbmQoKSB7IHJldHVybiBLaW5kLkZPUl9MT09QOyB9CiAgICAgICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgSkNFeHByZXNzaW9uIGdldENvbmRpdGlvbigpIHsgcmV0dXJuIGNvbmQ7IH0KICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBKQ1N0YXRlbWVudCBnZXRTdGF0ZW1lbnQoKSB7IHJldHVybiBib2R5OyB9CiAgICAgICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgTGlzdDxKQ1N0YXRlbWVudD4gZ2V0SW5pdGlhbGl6ZXIoKSB7CiAgICAgICAgICAgIHJldHVybiBpbml0OwogICAgICAgIH0KICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBMaXN0PEpDRXhwcmVzc2lvblN0YXRlbWVudD4gZ2V0VXBkYXRlKCkgewogICAgICAgICAgICByZXR1cm4gc3RlcDsKICAgICAgICB9CiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIDxSLEQ+IFIgYWNjZXB0KFRyZWVWaXNpdG9yPFIsRD4gdiwgRCBkKSB7CiAgICAgICAgICAgIHJldHVybiB2LnZpc2l0Rm9yTG9vcCh0aGlzLCBkKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBUYWcgZ2V0VGFnKCkgewogICAgICAgICAgICByZXR1cm4gRk9STE9PUDsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBUaGUgZW5oYW5jZWQgZm9yIGxvb3AuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgSkNFbmhhbmNlZEZvckxvb3AgZXh0ZW5kcyBKQ1N0YXRlbWVudCBpbXBsZW1lbnRzIEVuaGFuY2VkRm9yTG9vcFRyZWUgewogICAgICAgIHB1YmxpYyBKQ1ZhcmlhYmxlRGVjbCB2YXI7CiAgICAgICAgcHVibGljIEpDRXhwcmVzc2lvbiBleHByOwogICAgICAgIHB1YmxpYyBKQ1N0YXRlbWVudCBib2R5OwogICAgICAgIHByb3RlY3RlZCBKQ0VuaGFuY2VkRm9yTG9vcChKQ1ZhcmlhYmxlRGVjbCB2YXIsIEpDRXhwcmVzc2lvbiBleHByLCBKQ1N0YXRlbWVudCBib2R5KSB7CiAgICAgICAgICAgIHRoaXMudmFyID0gdmFyOwogICAgICAgICAgICB0aGlzLmV4cHIgPSBleHByOwogICAgICAgICAgICB0aGlzLmJvZHkgPSBib2R5OwogICAgICAgIH0KICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7IHYudmlzaXRGb3JlYWNoTG9vcCh0aGlzKTsgfQoKICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBLaW5kIGdldEtpbmQoKSB7IHJldHVybiBLaW5kLkVOSEFOQ0VEX0ZPUl9MT09QOyB9CiAgICAgICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgSkNWYXJpYWJsZURlY2wgZ2V0VmFyaWFibGUoKSB7IHJldHVybiB2YXI7IH0KICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBKQ0V4cHJlc3Npb24gZ2V0RXhwcmVzc2lvbigpIHsgcmV0dXJuIGV4cHI7IH0KICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBKQ1N0YXRlbWVudCBnZXRTdGF0ZW1lbnQoKSB7IHJldHVybiBib2R5OyB9CiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIDxSLEQ+IFIgYWNjZXB0KFRyZWVWaXNpdG9yPFIsRD4gdiwgRCBkKSB7CiAgICAgICAgICAgIHJldHVybiB2LnZpc2l0RW5oYW5jZWRGb3JMb29wKHRoaXMsIGQpOwogICAgICAgIH0KICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgVGFnIGdldFRhZygpIHsKICAgICAgICAgICAgcmV0dXJuIEZPUkVBQ0hMT09QOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEEgbGFiZWxsZWQgZXhwcmVzc2lvbiBvciBzdGF0ZW1lbnQuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgSkNMYWJlbGVkU3RhdGVtZW50IGV4dGVuZHMgSkNTdGF0ZW1lbnQgaW1wbGVtZW50cyBMYWJlbGVkU3RhdGVtZW50VHJlZSB7CiAgICAgICAgcHVibGljIE5hbWUgbGFiZWw7CiAgICAgICAgcHVibGljIEpDU3RhdGVtZW50IGJvZHk7CiAgICAgICAgcHJvdGVjdGVkIEpDTGFiZWxlZFN0YXRlbWVudChOYW1lIGxhYmVsLCBKQ1N0YXRlbWVudCBib2R5KSB7CiAgICAgICAgICAgIHRoaXMubGFiZWwgPSBsYWJlbDsKICAgICAgICAgICAgdGhpcy5ib2R5ID0gYm9keTsKICAgICAgICB9CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgeyB2LnZpc2l0TGFiZWxsZWQodGhpcyk7IH0KICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBLaW5kIGdldEtpbmQoKSB7IHJldHVybiBLaW5kLkxBQkVMRURfU1RBVEVNRU5UOyB9CiAgICAgICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgTmFtZSBnZXRMYWJlbCgpIHsgcmV0dXJuIGxhYmVsOyB9CiAgICAgICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgSkNTdGF0ZW1lbnQgZ2V0U3RhdGVtZW50KCkgeyByZXR1cm4gYm9keTsgfQogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyA8UixEPiBSIGFjY2VwdChUcmVlVmlzaXRvcjxSLEQ+IHYsIEQgZCkgewogICAgICAgICAgICByZXR1cm4gdi52aXNpdExhYmVsZWRTdGF0ZW1lbnQodGhpcywgZCk7CiAgICAgICAgfQogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBUYWcgZ2V0VGFnKCkgewogICAgICAgICAgICByZXR1cm4gTEFCRUxMRUQ7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQSAic3dpdGNoICggKSB7IH0iIGNvbnN0cnVjdGlvbi4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBjbGFzcyBKQ1N3aXRjaCBleHRlbmRzIEpDU3RhdGVtZW50IGltcGxlbWVudHMgU3dpdGNoVHJlZSB7CiAgICAgICAgcHVibGljIEpDRXhwcmVzc2lvbiBzZWxlY3RvcjsKICAgICAgICBwdWJsaWMgTGlzdDxKQ0Nhc2U+IGNhc2VzOwogICAgICAgIHByb3RlY3RlZCBKQ1N3aXRjaChKQ0V4cHJlc3Npb24gc2VsZWN0b3IsIExpc3Q8SkNDYXNlPiBjYXNlcykgewogICAgICAgICAgICB0aGlzLnNlbGVjdG9yID0gc2VsZWN0b3I7CiAgICAgICAgICAgIHRoaXMuY2FzZXMgPSBjYXNlczsKICAgICAgICB9CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgeyB2LnZpc2l0U3dpdGNoKHRoaXMpOyB9CgogICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIEtpbmQgZ2V0S2luZCgpIHsgcmV0dXJuIEtpbmQuU1dJVENIOyB9CiAgICAgICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgSkNFeHByZXNzaW9uIGdldEV4cHJlc3Npb24oKSB7IHJldHVybiBzZWxlY3RvcjsgfQogICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIExpc3Q8SkNDYXNlPiBnZXRDYXNlcygpIHsgcmV0dXJuIGNhc2VzOyB9CiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIDxSLEQ+IFIgYWNjZXB0KFRyZWVWaXNpdG9yPFIsRD4gdiwgRCBkKSB7CiAgICAgICAgICAgIHJldHVybiB2LnZpc2l0U3dpdGNoKHRoaXMsIGQpOwogICAgICAgIH0KICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgVGFnIGdldFRhZygpIHsKICAgICAgICAgICAgcmV0dXJuIFNXSVRDSDsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBBICJjYXNlICA6IiBvZiBhIHN3aXRjaC4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBjbGFzcyBKQ0Nhc2UgZXh0ZW5kcyBKQ1N0YXRlbWVudCBpbXBsZW1lbnRzIENhc2VUcmVlIHsKICAgICAgICBwdWJsaWMgSkNFeHByZXNzaW9uIHBhdDsKICAgICAgICBwdWJsaWMgTGlzdDxKQ1N0YXRlbWVudD4gc3RhdHM7CiAgICAgICAgcHJvdGVjdGVkIEpDQ2FzZShKQ0V4cHJlc3Npb24gcGF0LCBMaXN0PEpDU3RhdGVtZW50PiBzdGF0cykgewogICAgICAgICAgICB0aGlzLnBhdCA9IHBhdDsKICAgICAgICAgICAgdGhpcy5zdGF0cyA9IHN0YXRzOwogICAgICAgIH0KICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7IHYudmlzaXRDYXNlKHRoaXMpOyB9CgogICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIEtpbmQgZ2V0S2luZCgpIHsgcmV0dXJuIEtpbmQuQ0FTRTsgfQogICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIEpDRXhwcmVzc2lvbiBnZXRFeHByZXNzaW9uKCkgeyByZXR1cm4gcGF0OyB9CiAgICAgICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgTGlzdDxKQ1N0YXRlbWVudD4gZ2V0U3RhdGVtZW50cygpIHsgcmV0dXJuIHN0YXRzOyB9CiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIDxSLEQ+IFIgYWNjZXB0KFRyZWVWaXNpdG9yPFIsRD4gdiwgRCBkKSB7CiAgICAgICAgICAgIHJldHVybiB2LnZpc2l0Q2FzZSh0aGlzLCBkKTsKICAgICAgICB9CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFRhZyBnZXRUYWcoKSB7CiAgICAgICAgICAgIHJldHVybiBDQVNFOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEEgc3luY2hyb25pemVkIGJsb2NrLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIEpDU3luY2hyb25pemVkIGV4dGVuZHMgSkNTdGF0ZW1lbnQgaW1wbGVtZW50cyBTeW5jaHJvbml6ZWRUcmVlIHsKICAgICAgICBwdWJsaWMgSkNFeHByZXNzaW9uIGxvY2s7CiAgICAgICAgcHVibGljIEpDQmxvY2sgYm9keTsKICAgICAgICBwcm90ZWN0ZWQgSkNTeW5jaHJvbml6ZWQoSkNFeHByZXNzaW9uIGxvY2ssIEpDQmxvY2sgYm9keSkgewogICAgICAgICAgICB0aGlzLmxvY2sgPSBsb2NrOwogICAgICAgICAgICB0aGlzLmJvZHkgPSBib2R5OwogICAgICAgIH0KICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7IHYudmlzaXRTeW5jaHJvbml6ZWQodGhpcyk7IH0KCiAgICAgICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgS2luZCBnZXRLaW5kKCkgeyByZXR1cm4gS2luZC5TWU5DSFJPTklaRUQ7IH0KICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBKQ0V4cHJlc3Npb24gZ2V0RXhwcmVzc2lvbigpIHsgcmV0dXJuIGxvY2s7IH0KICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBKQ0Jsb2NrIGdldEJsb2NrKCkgeyByZXR1cm4gYm9keTsgfQogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyA8UixEPiBSIGFjY2VwdChUcmVlVmlzaXRvcjxSLEQ+IHYsIEQgZCkgewogICAgICAgICAgICByZXR1cm4gdi52aXNpdFN5bmNocm9uaXplZCh0aGlzLCBkKTsKICAgICAgICB9CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFRhZyBnZXRUYWcoKSB7CiAgICAgICAgICAgIHJldHVybiBTWU5DSFJPTklaRUQ7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQSAidHJ5IHsgfSBjYXRjaCAoICkgeyB9IGZpbmFsbHkgeyB9IiBibG9jay4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBjbGFzcyBKQ1RyeSBleHRlbmRzIEpDU3RhdGVtZW50IGltcGxlbWVudHMgVHJ5VHJlZSB7CiAgICAgICAgcHVibGljIEpDQmxvY2sgYm9keTsKICAgICAgICBwdWJsaWMgTGlzdDxKQ0NhdGNoPiBjYXRjaGVyczsKICAgICAgICBwdWJsaWMgSkNCbG9jayBmaW5hbGl6ZXI7CiAgICAgICAgcHVibGljIExpc3Q8SkNUcmVlPiByZXNvdXJjZXM7CiAgICAgICAgcHVibGljIGJvb2xlYW4gZmluYWxseUNhbkNvbXBsZXRlTm9ybWFsbHk7CiAgICAgICAgcHJvdGVjdGVkIEpDVHJ5KExpc3Q8SkNUcmVlPiByZXNvdXJjZXMsCiAgICAgICAgICAgICAgICAgICAgICAgIEpDQmxvY2sgYm9keSwKICAgICAgICAgICAgICAgICAgICAgICAgTGlzdDxKQ0NhdGNoPiBjYXRjaGVycywKICAgICAgICAgICAgICAgICAgICAgICAgSkNCbG9jayBmaW5hbGl6ZXIpIHsKICAgICAgICAgICAgdGhpcy5ib2R5ID0gYm9keTsKICAgICAgICAgICAgdGhpcy5jYXRjaGVycyA9IGNhdGNoZXJzOwogICAgICAgICAgICB0aGlzLmZpbmFsaXplciA9IGZpbmFsaXplcjsKICAgICAgICAgICAgdGhpcy5yZXNvdXJjZXMgPSByZXNvdXJjZXM7CiAgICAgICAgfQogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsgdi52aXNpdFRyeSh0aGlzKTsgfQoKICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBLaW5kIGdldEtpbmQoKSB7IHJldHVybiBLaW5kLlRSWTsgfQogICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIEpDQmxvY2sgZ2V0QmxvY2soKSB7IHJldHVybiBib2R5OyB9CiAgICAgICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgTGlzdDxKQ0NhdGNoPiBnZXRDYXRjaGVzKCkgewogICAgICAgICAgICByZXR1cm4gY2F0Y2hlcnM7CiAgICAgICAgfQogICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIEpDQmxvY2sgZ2V0RmluYWxseUJsb2NrKCkgeyByZXR1cm4gZmluYWxpemVyOyB9CiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIDxSLEQ+IFIgYWNjZXB0KFRyZWVWaXNpdG9yPFIsRD4gdiwgRCBkKSB7CiAgICAgICAgICAgIHJldHVybiB2LnZpc2l0VHJ5KHRoaXMsIGQpOwogICAgICAgIH0KICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgTGlzdDxKQ1RyZWU+IGdldFJlc291cmNlcygpIHsKICAgICAgICAgICAgcmV0dXJuIHJlc291cmNlczsKICAgICAgICB9CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFRhZyBnZXRUYWcoKSB7CiAgICAgICAgICAgIHJldHVybiBUUlk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQSBjYXRjaCBibG9jay4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBjbGFzcyBKQ0NhdGNoIGV4dGVuZHMgSkNUcmVlIGltcGxlbWVudHMgQ2F0Y2hUcmVlIHsKICAgICAgICBwdWJsaWMgSkNWYXJpYWJsZURlY2wgcGFyYW07CiAgICAgICAgcHVibGljIEpDQmxvY2sgYm9keTsKICAgICAgICBwcm90ZWN0ZWQgSkNDYXRjaChKQ1ZhcmlhYmxlRGVjbCBwYXJhbSwgSkNCbG9jayBib2R5KSB7CiAgICAgICAgICAgIHRoaXMucGFyYW0gPSBwYXJhbTsKICAgICAgICAgICAgdGhpcy5ib2R5ID0gYm9keTsKICAgICAgICB9CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgeyB2LnZpc2l0Q2F0Y2godGhpcyk7IH0KCiAgICAgICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgS2luZCBnZXRLaW5kKCkgeyByZXR1cm4gS2luZC5DQVRDSDsgfQogICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIEpDVmFyaWFibGVEZWNsIGdldFBhcmFtZXRlcigpIHsgcmV0dXJuIHBhcmFtOyB9CiAgICAgICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgSkNCbG9jayBnZXRCbG9jaygpIHsgcmV0dXJuIGJvZHk7IH0KICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgPFIsRD4gUiBhY2NlcHQoVHJlZVZpc2l0b3I8UixEPiB2LCBEIGQpIHsKICAgICAgICAgICAgcmV0dXJuIHYudmlzaXRDYXRjaCh0aGlzLCBkKTsKICAgICAgICB9CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFRhZyBnZXRUYWcoKSB7CiAgICAgICAgICAgIHJldHVybiBDQVRDSDsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBBICggKSA/ICggKSA6ICggKSBjb25kaXRpb25hbCBleHByZXNzaW9uCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgSkNDb25kaXRpb25hbCBleHRlbmRzIEpDUG9seUV4cHJlc3Npb24gaW1wbGVtZW50cyBDb25kaXRpb25hbEV4cHJlc3Npb25UcmVlIHsKICAgICAgICBwdWJsaWMgSkNFeHByZXNzaW9uIGNvbmQ7CiAgICAgICAgcHVibGljIEpDRXhwcmVzc2lvbiB0cnVlcGFydDsKICAgICAgICBwdWJsaWMgSkNFeHByZXNzaW9uIGZhbHNlcGFydDsKICAgICAgICBwcm90ZWN0ZWQgSkNDb25kaXRpb25hbChKQ0V4cHJlc3Npb24gY29uZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSkNFeHByZXNzaW9uIHRydWVwYXJ0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBKQ0V4cHJlc3Npb24gZmFsc2VwYXJ0KQogICAgICAgIHsKICAgICAgICAgICAgdGhpcy5jb25kID0gY29uZDsKICAgICAgICAgICAgdGhpcy50cnVlcGFydCA9IHRydWVwYXJ0OwogICAgICAgICAgICB0aGlzLmZhbHNlcGFydCA9IGZhbHNlcGFydDsKICAgICAgICB9CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgeyB2LnZpc2l0Q29uZGl0aW9uYWwodGhpcyk7IH0KCiAgICAgICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgS2luZCBnZXRLaW5kKCkgeyByZXR1cm4gS2luZC5DT05ESVRJT05BTF9FWFBSRVNTSU9OOyB9CiAgICAgICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgSkNFeHByZXNzaW9uIGdldENvbmRpdGlvbigpIHsgcmV0dXJuIGNvbmQ7IH0KICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBKQ0V4cHJlc3Npb24gZ2V0VHJ1ZUV4cHJlc3Npb24oKSB7IHJldHVybiB0cnVlcGFydDsgfQogICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIEpDRXhwcmVzc2lvbiBnZXRGYWxzZUV4cHJlc3Npb24oKSB7IHJldHVybiBmYWxzZXBhcnQ7IH0KICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgPFIsRD4gUiBhY2NlcHQoVHJlZVZpc2l0b3I8UixEPiB2LCBEIGQpIHsKICAgICAgICAgICAgcmV0dXJuIHYudmlzaXRDb25kaXRpb25hbEV4cHJlc3Npb24odGhpcywgZCk7CiAgICAgICAgfQogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBUYWcgZ2V0VGFnKCkgewogICAgICAgICAgICByZXR1cm4gQ09OREVYUFI7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQW4gImlmICggKSB7IH0gZWxzZSB7IH0iIGJsb2NrCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgSkNJZiBleHRlbmRzIEpDU3RhdGVtZW50IGltcGxlbWVudHMgSWZUcmVlIHsKICAgICAgICBwdWJsaWMgSkNFeHByZXNzaW9uIGNvbmQ7CiAgICAgICAgcHVibGljIEpDU3RhdGVtZW50IHRoZW5wYXJ0OwogICAgICAgIHB1YmxpYyBKQ1N0YXRlbWVudCBlbHNlcGFydDsKICAgICAgICBwcm90ZWN0ZWQgSkNJZihKQ0V4cHJlc3Npb24gY29uZCwKICAgICAgICAgICAgICAgICAgICAgSkNTdGF0ZW1lbnQgdGhlbnBhcnQsCiAgICAgICAgICAgICAgICAgICAgIEpDU3RhdGVtZW50IGVsc2VwYXJ0KQogICAgICAgIHsKICAgICAgICAgICAgdGhpcy5jb25kID0gY29uZDsKICAgICAgICAgICAgdGhpcy50aGVucGFydCA9IHRoZW5wYXJ0OwogICAgICAgICAgICB0aGlzLmVsc2VwYXJ0ID0gZWxzZXBhcnQ7CiAgICAgICAgfQogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsgdi52aXNpdElmKHRoaXMpOyB9CgogICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIEtpbmQgZ2V0S2luZCgpIHsgcmV0dXJuIEtpbmQuSUY7IH0KICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBKQ0V4cHJlc3Npb24gZ2V0Q29uZGl0aW9uKCkgeyByZXR1cm4gY29uZDsgfQogICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIEpDU3RhdGVtZW50IGdldFRoZW5TdGF0ZW1lbnQoKSB7IHJldHVybiB0aGVucGFydDsgfQogICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIEpDU3RhdGVtZW50IGdldEVsc2VTdGF0ZW1lbnQoKSB7IHJldHVybiBlbHNlcGFydDsgfQogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyA8UixEPiBSIGFjY2VwdChUcmVlVmlzaXRvcjxSLEQ+IHYsIEQgZCkgewogICAgICAgICAgICByZXR1cm4gdi52aXNpdElmKHRoaXMsIGQpOwogICAgICAgIH0KICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgVGFnIGdldFRhZygpIHsKICAgICAgICAgICAgcmV0dXJuIElGOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIGFuIGV4cHJlc3Npb24gc3RhdGVtZW50CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgSkNFeHByZXNzaW9uU3RhdGVtZW50IGV4dGVuZHMgSkNTdGF0ZW1lbnQgaW1wbGVtZW50cyBFeHByZXNzaW9uU3RhdGVtZW50VHJlZSB7CiAgICAgICAgLyoqIGV4cHJlc3Npb24gc3RydWN0dXJlICovCiAgICAgICAgcHVibGljIEpDRXhwcmVzc2lvbiBleHByOwogICAgICAgIHByb3RlY3RlZCBKQ0V4cHJlc3Npb25TdGF0ZW1lbnQoSkNFeHByZXNzaW9uIGV4cHIpCiAgICAgICAgewogICAgICAgICAgICB0aGlzLmV4cHIgPSBleHByOwogICAgICAgIH0KICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7IHYudmlzaXRFeGVjKHRoaXMpOyB9CgogICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIEtpbmQgZ2V0S2luZCgpIHsgcmV0dXJuIEtpbmQuRVhQUkVTU0lPTl9TVEFURU1FTlQ7IH0KICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBKQ0V4cHJlc3Npb24gZ2V0RXhwcmVzc2lvbigpIHsgcmV0dXJuIGV4cHI7IH0KICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgPFIsRD4gUiBhY2NlcHQoVHJlZVZpc2l0b3I8UixEPiB2LCBEIGQpIHsKICAgICAgICAgICAgcmV0dXJuIHYudmlzaXRFeHByZXNzaW9uU3RhdGVtZW50KHRoaXMsIGQpOwogICAgICAgIH0KICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgVGFnIGdldFRhZygpIHsKICAgICAgICAgICAgcmV0dXJuIEVYRUM7CiAgICAgICAgfQoKICAgICAgICAvKiogQ29udmVydCBhIGV4cHJlc3Npb24tc3RhdGVtZW50IHRyZWUgdG8gYSBwcmV0dHktcHJpbnRlZCBzdHJpbmcuICovCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKICAgICAgICAgICAgU3RyaW5nV3JpdGVyIHMgPSBuZXcgU3RyaW5nV3JpdGVyKCk7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBuZXcgUHJldHR5KHMsIGZhbHNlKS5wcmludFN0YXQodGhpcyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgICAgIC8vIHNob3VsZCBuZXZlciBoYXBwZW4sIGJlY2F1c2UgU3RyaW5nV3JpdGVyIGlzIGRlZmluZWQKICAgICAgICAgICAgICAgIC8vIG5ldmVyIHRvIHRocm93IGFueSBJT0V4Y2VwdGlvbnMKICAgICAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gcy50b1N0cmluZygpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEEgYnJlYWsgZnJvbSBhIGxvb3Agb3Igc3dpdGNoLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIEpDQnJlYWsgZXh0ZW5kcyBKQ1N0YXRlbWVudCBpbXBsZW1lbnRzIEJyZWFrVHJlZSB7CiAgICAgICAgcHVibGljIE5hbWUgbGFiZWw7CiAgICAgICAgcHVibGljIEpDVHJlZSB0YXJnZXQ7CiAgICAgICAgcHJvdGVjdGVkIEpDQnJlYWsoTmFtZSBsYWJlbCwgSkNUcmVlIHRhcmdldCkgewogICAgICAgICAgICB0aGlzLmxhYmVsID0gbGFiZWw7CiAgICAgICAgICAgIHRoaXMudGFyZ2V0ID0gdGFyZ2V0OwogICAgICAgIH0KICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7IHYudmlzaXRCcmVhayh0aGlzKTsgfQoKICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBLaW5kIGdldEtpbmQoKSB7IHJldHVybiBLaW5kLkJSRUFLOyB9CiAgICAgICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgTmFtZSBnZXRMYWJlbCgpIHsgcmV0dXJuIGxhYmVsOyB9CiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIDxSLEQ+IFIgYWNjZXB0KFRyZWVWaXNpdG9yPFIsRD4gdiwgRCBkKSB7CiAgICAgICAgICAgIHJldHVybiB2LnZpc2l0QnJlYWsodGhpcywgZCk7CiAgICAgICAgfQogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBUYWcgZ2V0VGFnKCkgewogICAgICAgICAgICByZXR1cm4gQlJFQUs7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQSBjb250aW51ZSBvZiBhIGxvb3AuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgSkNDb250aW51ZSBleHRlbmRzIEpDU3RhdGVtZW50IGltcGxlbWVudHMgQ29udGludWVUcmVlIHsKICAgICAgICBwdWJsaWMgTmFtZSBsYWJlbDsKICAgICAgICBwdWJsaWMgSkNUcmVlIHRhcmdldDsKICAgICAgICBwcm90ZWN0ZWQgSkNDb250aW51ZShOYW1lIGxhYmVsLCBKQ1RyZWUgdGFyZ2V0KSB7CiAgICAgICAgICAgIHRoaXMubGFiZWwgPSBsYWJlbDsKICAgICAgICAgICAgdGhpcy50YXJnZXQgPSB0YXJnZXQ7CiAgICAgICAgfQogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsgdi52aXNpdENvbnRpbnVlKHRoaXMpOyB9CgogICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIEtpbmQgZ2V0S2luZCgpIHsgcmV0dXJuIEtpbmQuQ09OVElOVUU7IH0KICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBOYW1lIGdldExhYmVsKCkgeyByZXR1cm4gbGFiZWw7IH0KICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgPFIsRD4gUiBhY2NlcHQoVHJlZVZpc2l0b3I8UixEPiB2LCBEIGQpIHsKICAgICAgICAgICAgcmV0dXJuIHYudmlzaXRDb250aW51ZSh0aGlzLCBkKTsKICAgICAgICB9CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFRhZyBnZXRUYWcoKSB7CiAgICAgICAgICAgIHJldHVybiBDT05USU5VRTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBBIHJldHVybiBzdGF0ZW1lbnQuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgSkNSZXR1cm4gZXh0ZW5kcyBKQ1N0YXRlbWVudCBpbXBsZW1lbnRzIFJldHVyblRyZWUgewogICAgICAgIHB1YmxpYyBKQ0V4cHJlc3Npb24gZXhwcjsKICAgICAgICBwcm90ZWN0ZWQgSkNSZXR1cm4oSkNFeHByZXNzaW9uIGV4cHIpIHsKICAgICAgICAgICAgdGhpcy5leHByID0gZXhwcjsKICAgICAgICB9CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgeyB2LnZpc2l0UmV0dXJuKHRoaXMpOyB9CgogICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIEtpbmQgZ2V0S2luZCgpIHsgcmV0dXJuIEtpbmQuUkVUVVJOOyB9CiAgICAgICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgSkNFeHByZXNzaW9uIGdldEV4cHJlc3Npb24oKSB7IHJldHVybiBleHByOyB9CiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIDxSLEQ+IFIgYWNjZXB0KFRyZWVWaXNpdG9yPFIsRD4gdiwgRCBkKSB7CiAgICAgICAgICAgIHJldHVybiB2LnZpc2l0UmV0dXJuKHRoaXMsIGQpOwogICAgICAgIH0KICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgVGFnIGdldFRhZygpIHsKICAgICAgICAgICAgcmV0dXJuIFJFVFVSTjsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBBIHRocm93IHN0YXRlbWVudC4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBjbGFzcyBKQ1Rocm93IGV4dGVuZHMgSkNTdGF0ZW1lbnQgaW1wbGVtZW50cyBUaHJvd1RyZWUgewogICAgICAgIHB1YmxpYyBKQ0V4cHJlc3Npb24gZXhwcjsKICAgICAgICBwcm90ZWN0ZWQgSkNUaHJvdyhKQ0V4cHJlc3Npb24gZXhwcikgewogICAgICAgICAgICB0aGlzLmV4cHIgPSBleHByOwogICAgICAgIH0KICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7IHYudmlzaXRUaHJvdyh0aGlzKTsgfQoKICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBLaW5kIGdldEtpbmQoKSB7IHJldHVybiBLaW5kLlRIUk9XOyB9CiAgICAgICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgSkNFeHByZXNzaW9uIGdldEV4cHJlc3Npb24oKSB7IHJldHVybiBleHByOyB9CiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIDxSLEQ+IFIgYWNjZXB0KFRyZWVWaXNpdG9yPFIsRD4gdiwgRCBkKSB7CiAgICAgICAgICAgIHJldHVybiB2LnZpc2l0VGhyb3codGhpcywgZCk7CiAgICAgICAgfQogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBUYWcgZ2V0VGFnKCkgewogICAgICAgICAgICByZXR1cm4gVEhST1c7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQW4gYXNzZXJ0IHN0YXRlbWVudC4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBjbGFzcyBKQ0Fzc2VydCBleHRlbmRzIEpDU3RhdGVtZW50IGltcGxlbWVudHMgQXNzZXJ0VHJlZSB7CiAgICAgICAgcHVibGljIEpDRXhwcmVzc2lvbiBjb25kOwogICAgICAgIHB1YmxpYyBKQ0V4cHJlc3Npb24gZGV0YWlsOwogICAgICAgIHByb3RlY3RlZCBKQ0Fzc2VydChKQ0V4cHJlc3Npb24gY29uZCwgSkNFeHByZXNzaW9uIGRldGFpbCkgewogICAgICAgICAgICB0aGlzLmNvbmQgPSBjb25kOwogICAgICAgICAgICB0aGlzLmRldGFpbCA9IGRldGFpbDsKICAgICAgICB9CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgeyB2LnZpc2l0QXNzZXJ0KHRoaXMpOyB9CgogICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIEtpbmQgZ2V0S2luZCgpIHsgcmV0dXJuIEtpbmQuQVNTRVJUOyB9CiAgICAgICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgSkNFeHByZXNzaW9uIGdldENvbmRpdGlvbigpIHsgcmV0dXJuIGNvbmQ7IH0KICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBKQ0V4cHJlc3Npb24gZ2V0RGV0YWlsKCkgeyByZXR1cm4gZGV0YWlsOyB9CiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIDxSLEQ+IFIgYWNjZXB0KFRyZWVWaXNpdG9yPFIsRD4gdiwgRCBkKSB7CiAgICAgICAgICAgIHJldHVybiB2LnZpc2l0QXNzZXJ0KHRoaXMsIGQpOwogICAgICAgIH0KICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgVGFnIGdldFRhZygpIHsKICAgICAgICAgICAgcmV0dXJuIEFTU0VSVDsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBBIG1ldGhvZCBpbnZvY2F0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgSkNNZXRob2RJbnZvY2F0aW9uIGV4dGVuZHMgSkNQb2x5RXhwcmVzc2lvbiBpbXBsZW1lbnRzIE1ldGhvZEludm9jYXRpb25UcmVlIHsKICAgICAgICBwdWJsaWMgTGlzdDxKQ0V4cHJlc3Npb24+IHR5cGVhcmdzOwogICAgICAgIHB1YmxpYyBKQ0V4cHJlc3Npb24gbWV0aDsKICAgICAgICBwdWJsaWMgTGlzdDxKQ0V4cHJlc3Npb24+IGFyZ3M7CiAgICAgICAgcHVibGljIFR5cGUgdmFyYXJnc0VsZW1lbnQ7CiAgICAgICAgcHJvdGVjdGVkIEpDTWV0aG9kSW52b2NhdGlvbihMaXN0PEpDRXhwcmVzc2lvbj4gdHlwZWFyZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgIEpDRXhwcmVzc2lvbiBtZXRoLAogICAgICAgICAgICAgICAgICAgICAgICBMaXN0PEpDRXhwcmVzc2lvbj4gYXJncykKICAgICAgICB7CiAgICAgICAgICAgIHRoaXMudHlwZWFyZ3MgPSAodHlwZWFyZ3MgPT0gbnVsbCkgPyBMaXN0Lm5pbCgpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiB0eXBlYXJnczsKICAgICAgICAgICAgdGhpcy5tZXRoID0gbWV0aDsKICAgICAgICAgICAgdGhpcy5hcmdzID0gYXJnczsKICAgICAgICB9CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgeyB2LnZpc2l0QXBwbHkodGhpcyk7IH0KCiAgICAgICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgS2luZCBnZXRLaW5kKCkgeyByZXR1cm4gS2luZC5NRVRIT0RfSU5WT0NBVElPTjsgfQogICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIExpc3Q8SkNFeHByZXNzaW9uPiBnZXRUeXBlQXJndW1lbnRzKCkgewogICAgICAgICAgICByZXR1cm4gdHlwZWFyZ3M7CiAgICAgICAgfQogICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIEpDRXhwcmVzc2lvbiBnZXRNZXRob2RTZWxlY3QoKSB7IHJldHVybiBtZXRoOyB9CiAgICAgICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgTGlzdDxKQ0V4cHJlc3Npb24+IGdldEFyZ3VtZW50cygpIHsKICAgICAgICAgICAgcmV0dXJuIGFyZ3M7CiAgICAgICAgfQogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyA8UixEPiBSIGFjY2VwdChUcmVlVmlzaXRvcjxSLEQ+IHYsIEQgZCkgewogICAgICAgICAgICByZXR1cm4gdi52aXNpdE1ldGhvZEludm9jYXRpb24odGhpcywgZCk7CiAgICAgICAgfQogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBKQ01ldGhvZEludm9jYXRpb24gc2V0VHlwZShUeXBlIHR5cGUpIHsKICAgICAgICAgICAgc3VwZXIuc2V0VHlwZSh0eXBlKTsKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBUYWcgZ2V0VGFnKCkgewogICAgICAgICAgICByZXR1cm4oQVBQTFkpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEEgbmV3KC4uLikgb3BlcmF0aW9uLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIEpDTmV3Q2xhc3MgZXh0ZW5kcyBKQ1BvbHlFeHByZXNzaW9uIGltcGxlbWVudHMgTmV3Q2xhc3NUcmVlIHsKICAgICAgICBwdWJsaWMgSkNFeHByZXNzaW9uIGVuY2w7CiAgICAgICAgcHVibGljIExpc3Q8SkNFeHByZXNzaW9uPiB0eXBlYXJnczsKICAgICAgICBwdWJsaWMgSkNFeHByZXNzaW9uIGNsYXp6OwogICAgICAgIHB1YmxpYyBMaXN0PEpDRXhwcmVzc2lvbj4gYXJnczsKICAgICAgICBwdWJsaWMgSkNDbGFzc0RlY2wgZGVmOwogICAgICAgIHB1YmxpYyBTeW1ib2wgY29uc3RydWN0b3I7CiAgICAgICAgcHVibGljIFR5cGUgdmFyYXJnc0VsZW1lbnQ7CiAgICAgICAgcHVibGljIFR5cGUgY29uc3RydWN0b3JUeXBlOwogICAgICAgIHByb3RlY3RlZCBKQ05ld0NsYXNzKEpDRXhwcmVzc2lvbiBlbmNsLAogICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0PEpDRXhwcmVzc2lvbj4gdHlwZWFyZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIEpDRXhwcmVzc2lvbiBjbGF6eiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgTGlzdDxKQ0V4cHJlc3Npb24+IGFyZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIEpDQ2xhc3NEZWNsIGRlZikKICAgICAgICB7CiAgICAgICAgICAgIHRoaXMuZW5jbCA9IGVuY2w7CiAgICAgICAgICAgIHRoaXMudHlwZWFyZ3MgPSAodHlwZWFyZ3MgPT0gbnVsbCkgPyBMaXN0Lm5pbCgpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiB0eXBlYXJnczsKICAgICAgICAgICAgdGhpcy5jbGF6eiA9IGNsYXp6OwogICAgICAgICAgICB0aGlzLmFyZ3MgPSBhcmdzOwogICAgICAgICAgICB0aGlzLmRlZiA9IGRlZjsKICAgICAgICB9CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgeyB2LnZpc2l0TmV3Q2xhc3ModGhpcyk7IH0KCiAgICAgICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgS2luZCBnZXRLaW5kKCkgeyByZXR1cm4gS2luZC5ORVdfQ0xBU1M7IH0KICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBKQ0V4cHJlc3Npb24gZ2V0RW5jbG9zaW5nRXhwcmVzc2lvbigpIHsgLy8gZXhwci5uZXcgQzwgLi4uID4gKCAuLi4gKQogICAgICAgICAgICByZXR1cm4gZW5jbDsKICAgICAgICB9CiAgICAgICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgTGlzdDxKQ0V4cHJlc3Npb24+IGdldFR5cGVBcmd1bWVudHMoKSB7CiAgICAgICAgICAgIHJldHVybiB0eXBlYXJnczsKICAgICAgICB9CiAgICAgICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgSkNFeHByZXNzaW9uIGdldElkZW50aWZpZXIoKSB7IHJldHVybiBjbGF6ejsgfQogICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIExpc3Q8SkNFeHByZXNzaW9uPiBnZXRBcmd1bWVudHMoKSB7CiAgICAgICAgICAgIHJldHVybiBhcmdzOwogICAgICAgIH0KICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBKQ0NsYXNzRGVjbCBnZXRDbGFzc0JvZHkoKSB7IHJldHVybiBkZWY7IH0KICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgPFIsRD4gUiBhY2NlcHQoVHJlZVZpc2l0b3I8UixEPiB2LCBEIGQpIHsKICAgICAgICAgICAgcmV0dXJuIHYudmlzaXROZXdDbGFzcyh0aGlzLCBkKTsKICAgICAgICB9CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFRhZyBnZXRUYWcoKSB7CiAgICAgICAgICAgIHJldHVybiBORVdDTEFTUzsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBBIG5ld1suLi5dIG9wZXJhdGlvbi4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBjbGFzcyBKQ05ld0FycmF5IGV4dGVuZHMgSkNFeHByZXNzaW9uIGltcGxlbWVudHMgTmV3QXJyYXlUcmVlIHsKICAgICAgICBwdWJsaWMgSkNFeHByZXNzaW9uIGVsZW10eXBlOwogICAgICAgIHB1YmxpYyBMaXN0PEpDRXhwcmVzc2lvbj4gZGltczsKICAgICAgICAvLyB0eXBlIGFubm90YXRpb25zIG9uIGlubmVyLW1vc3QgY29tcG9uZW50CiAgICAgICAgcHVibGljIExpc3Q8SkNBbm5vdGF0aW9uPiBhbm5vdGF0aW9uczsKICAgICAgICAvLyB0eXBlIGFubm90YXRpb25zIG9uIGRpbWVuc2lvbnMKICAgICAgICBwdWJsaWMgTGlzdDxMaXN0PEpDQW5ub3RhdGlvbj4+IGRpbUFubm90YXRpb25zOwogICAgICAgIHB1YmxpYyBMaXN0PEpDRXhwcmVzc2lvbj4gZWxlbXM7CiAgICAgICAgcHJvdGVjdGVkIEpDTmV3QXJyYXkoSkNFeHByZXNzaW9uIGVsZW10eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0PEpDRXhwcmVzc2lvbj4gZGltcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgTGlzdDxKQ0V4cHJlc3Npb24+IGVsZW1zKQogICAgICAgIHsKICAgICAgICAgICAgdGhpcy5lbGVtdHlwZSA9IGVsZW10eXBlOwogICAgICAgICAgICB0aGlzLmRpbXMgPSBkaW1zOwogICAgICAgICAgICB0aGlzLmFubm90YXRpb25zID0gTGlzdC5uaWwoKTsKICAgICAgICAgICAgdGhpcy5kaW1Bbm5vdGF0aW9ucyA9IExpc3QubmlsKCk7CiAgICAgICAgICAgIHRoaXMuZWxlbXMgPSBlbGVtczsKICAgICAgICB9CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgeyB2LnZpc2l0TmV3QXJyYXkodGhpcyk7IH0KCiAgICAgICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgS2luZCBnZXRLaW5kKCkgeyByZXR1cm4gS2luZC5ORVdfQVJSQVk7IH0KICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBKQ0V4cHJlc3Npb24gZ2V0VHlwZSgpIHsgcmV0dXJuIGVsZW10eXBlOyB9CiAgICAgICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgTGlzdDxKQ0V4cHJlc3Npb24+IGdldERpbWVuc2lvbnMoKSB7CiAgICAgICAgICAgIHJldHVybiBkaW1zOwogICAgICAgIH0KICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBMaXN0PEpDRXhwcmVzc2lvbj4gZ2V0SW5pdGlhbGl6ZXJzKCkgewogICAgICAgICAgICByZXR1cm4gZWxlbXM7CiAgICAgICAgfQogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyA8UixEPiBSIGFjY2VwdChUcmVlVmlzaXRvcjxSLEQ+IHYsIEQgZCkgewogICAgICAgICAgICByZXR1cm4gdi52aXNpdE5ld0FycmF5KHRoaXMsIGQpOwogICAgICAgIH0KICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgVGFnIGdldFRhZygpIHsKICAgICAgICAgICAgcmV0dXJuIE5FV0FSUkFZOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIExpc3Q8SkNBbm5vdGF0aW9uPiBnZXRBbm5vdGF0aW9ucygpIHsKICAgICAgICAgICAgcmV0dXJuIGFubm90YXRpb25zOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIExpc3Q8TGlzdDxKQ0Fubm90YXRpb24+PiBnZXREaW1Bbm5vdGF0aW9ucygpIHsKICAgICAgICAgICAgcmV0dXJuIGRpbUFubm90YXRpb25zOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEEgbGFtYmRhIGV4cHJlc3Npb24uCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgSkNMYW1iZGEgZXh0ZW5kcyBKQ0Z1bmN0aW9uYWxFeHByZXNzaW9uIGltcGxlbWVudHMgTGFtYmRhRXhwcmVzc2lvblRyZWUgewoKICAgICAgICBwdWJsaWMgZW51bSBQYXJhbWV0ZXJLaW5kIHsKICAgICAgICAgICAgSU1QTElDSVQsCiAgICAgICAgICAgIEVYUExJQ0lUCiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgTGlzdDxKQ1ZhcmlhYmxlRGVjbD4gcGFyYW1zOwogICAgICAgIHB1YmxpYyBKQ1RyZWUgYm9keTsKICAgICAgICBwdWJsaWMgYm9vbGVhbiBjYW5Db21wbGV0ZU5vcm1hbGx5ID0gdHJ1ZTsKICAgICAgICBwdWJsaWMgUGFyYW1ldGVyS2luZCBwYXJhbUtpbmQ7CgogICAgICAgIHB1YmxpYyBKQ0xhbWJkYShMaXN0PEpDVmFyaWFibGVEZWNsPiBwYXJhbXMsCiAgICAgICAgICAgICAgICAgICAgICAgIEpDVHJlZSBib2R5KSB7CiAgICAgICAgICAgIHRoaXMucGFyYW1zID0gcGFyYW1zOwogICAgICAgICAgICB0aGlzLmJvZHkgPSBib2R5OwogICAgICAgICAgICBpZiAocGFyYW1zLmlzRW1wdHkoKSB8fAogICAgICAgICAgICAgICAgcGFyYW1zLmhlYWQudmFydHlwZSAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICBwYXJhbUtpbmQgPSBQYXJhbWV0ZXJLaW5kLkVYUExJQ0lUOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcGFyYW1LaW5kID0gUGFyYW1ldGVyS2luZC5JTVBMSUNJVDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgVGFnIGdldFRhZygpIHsKICAgICAgICAgICAgcmV0dXJuIExBTUJEQTsKICAgICAgICB9CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgewogICAgICAgICAgICB2LnZpc2l0TGFtYmRhKHRoaXMpOwogICAgICAgIH0KICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgPFIsIEQ+IFIgYWNjZXB0KFRyZWVWaXNpdG9yPFIsIEQ+IHYsIEQgZCkgewogICAgICAgICAgICByZXR1cm4gdi52aXNpdExhbWJkYUV4cHJlc3Npb24odGhpcywgZCk7CiAgICAgICAgfQogICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIEtpbmQgZ2V0S2luZCgpIHsKICAgICAgICAgICAgcmV0dXJuIEtpbmQuTEFNQkRBX0VYUFJFU1NJT047CiAgICAgICAgfQogICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIEpDVHJlZSBnZXRCb2R5KCkgewogICAgICAgICAgICByZXR1cm4gYm9keTsKICAgICAgICB9CiAgICAgICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIFZhcmlhYmxlVHJlZT4gZ2V0UGFyYW1ldGVycygpIHsKICAgICAgICAgICAgcmV0dXJuIHBhcmFtczsKICAgICAgICB9CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIEpDTGFtYmRhIHNldFR5cGUoVHlwZSB0eXBlKSB7CiAgICAgICAgICAgIHN1cGVyLnNldFR5cGUodHlwZSk7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgQm9keUtpbmQgZ2V0Qm9keUtpbmQoKSB7CiAgICAgICAgICAgIHJldHVybiBib2R5Lmhhc1RhZyhCTE9DSykgPwogICAgICAgICAgICAgICAgICAgIEJvZHlLaW5kLlNUQVRFTUVOVCA6CiAgICAgICAgICAgICAgICAgICAgQm9keUtpbmQuRVhQUkVTU0lPTjsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBBIHBhcmVudGhlc2l6ZWQgc3ViZXhwcmVzc2lvbiAoIC4uLiApCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgSkNQYXJlbnMgZXh0ZW5kcyBKQ0V4cHJlc3Npb24gaW1wbGVtZW50cyBQYXJlbnRoZXNpemVkVHJlZSB7CiAgICAgICAgcHVibGljIEpDRXhwcmVzc2lvbiBleHByOwogICAgICAgIHByb3RlY3RlZCBKQ1BhcmVucyhKQ0V4cHJlc3Npb24gZXhwcikgewogICAgICAgICAgICB0aGlzLmV4cHIgPSBleHByOwogICAgICAgIH0KICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7IHYudmlzaXRQYXJlbnModGhpcyk7IH0KCiAgICAgICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgS2luZCBnZXRLaW5kKCkgeyByZXR1cm4gS2luZC5QQVJFTlRIRVNJWkVEOyB9CiAgICAgICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgSkNFeHByZXNzaW9uIGdldEV4cHJlc3Npb24oKSB7IHJldHVybiBleHByOyB9CiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIDxSLEQ+IFIgYWNjZXB0KFRyZWVWaXNpdG9yPFIsRD4gdiwgRCBkKSB7CiAgICAgICAgICAgIHJldHVybiB2LnZpc2l0UGFyZW50aGVzaXplZCh0aGlzLCBkKTsKICAgICAgICB9CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFRhZyBnZXRUYWcoKSB7CiAgICAgICAgICAgIHJldHVybiBQQVJFTlM7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQSBhc3NpZ25tZW50IHdpdGggIj0iLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIEpDQXNzaWduIGV4dGVuZHMgSkNFeHByZXNzaW9uIGltcGxlbWVudHMgQXNzaWdubWVudFRyZWUgewogICAgICAgIHB1YmxpYyBKQ0V4cHJlc3Npb24gbGhzOwogICAgICAgIHB1YmxpYyBKQ0V4cHJlc3Npb24gcmhzOwogICAgICAgIHByb3RlY3RlZCBKQ0Fzc2lnbihKQ0V4cHJlc3Npb24gbGhzLCBKQ0V4cHJlc3Npb24gcmhzKSB7CiAgICAgICAgICAgIHRoaXMubGhzID0gbGhzOwogICAgICAgICAgICB0aGlzLnJocyA9IHJoczsKICAgICAgICB9CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgeyB2LnZpc2l0QXNzaWduKHRoaXMpOyB9CgogICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIEtpbmQgZ2V0S2luZCgpIHsgcmV0dXJuIEtpbmQuQVNTSUdOTUVOVDsgfQogICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIEpDRXhwcmVzc2lvbiBnZXRWYXJpYWJsZSgpIHsgcmV0dXJuIGxoczsgfQogICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIEpDRXhwcmVzc2lvbiBnZXRFeHByZXNzaW9uKCkgeyByZXR1cm4gcmhzOyB9CiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIDxSLEQ+IFIgYWNjZXB0KFRyZWVWaXNpdG9yPFIsRD4gdiwgRCBkKSB7CiAgICAgICAgICAgIHJldHVybiB2LnZpc2l0QXNzaWdubWVudCh0aGlzLCBkKTsKICAgICAgICB9CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFRhZyBnZXRUYWcoKSB7CiAgICAgICAgICAgIHJldHVybiBBU1NJR047CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgYWJzdHJhY3QgY2xhc3MgSkNPcGVyYXRvckV4cHJlc3Npb24gZXh0ZW5kcyBKQ0V4cHJlc3Npb24gewogICAgICAgIHB1YmxpYyBlbnVtIE9wZXJhbmRQb3MgewogICAgICAgICAgICBMRUZULAogICAgICAgICAgICBSSUdIVAogICAgICAgIH0KCiAgICAgICAgcHJvdGVjdGVkIFRhZyBvcGNvZGU7CiAgICAgICAgcHVibGljIE9wZXJhdG9yU3ltYm9sIG9wZXJhdG9yOwoKICAgICAgICBwdWJsaWMgT3BlcmF0b3JTeW1ib2wgZ2V0T3BlcmF0b3IoKSB7CiAgICAgICAgICAgIHJldHVybiBvcGVyYXRvcjsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBUYWcgZ2V0VGFnKCkgewogICAgICAgICAgICByZXR1cm4gb3Bjb2RlOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIGFic3RyYWN0IEpDRXhwcmVzc2lvbiBnZXRPcGVyYW5kKE9wZXJhbmRQb3MgcG9zKTsKICAgIH0KCiAgICAvKioKICAgICAqIEFuIGFzc2lnbm1lbnQgd2l0aCAiKz0iLCAifD0iIC4uLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIEpDQXNzaWduT3AgZXh0ZW5kcyBKQ09wZXJhdG9yRXhwcmVzc2lvbiBpbXBsZW1lbnRzIENvbXBvdW5kQXNzaWdubWVudFRyZWUgewogICAgICAgIHB1YmxpYyBKQ0V4cHJlc3Npb24gbGhzOwogICAgICAgIHB1YmxpYyBKQ0V4cHJlc3Npb24gcmhzOwogICAgICAgIHByb3RlY3RlZCBKQ0Fzc2lnbk9wKFRhZyBvcGNvZGUsIEpDVHJlZSBsaHMsIEpDVHJlZSByaHMsIE9wZXJhdG9yU3ltYm9sIG9wZXJhdG9yKSB7CiAgICAgICAgICAgIHRoaXMub3Bjb2RlID0gb3Bjb2RlOwogICAgICAgICAgICB0aGlzLmxocyA9IChKQ0V4cHJlc3Npb24pbGhzOwogICAgICAgICAgICB0aGlzLnJocyA9IChKQ0V4cHJlc3Npb24pcmhzOwogICAgICAgICAgICB0aGlzLm9wZXJhdG9yID0gb3BlcmF0b3I7CiAgICAgICAgfQogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsgdi52aXNpdEFzc2lnbm9wKHRoaXMpOyB9CgogICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIEtpbmQgZ2V0S2luZCgpIHsgcmV0dXJuIFRyZWVJbmZvLnRhZ1RvS2luZChnZXRUYWcoKSk7IH0KICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBKQ0V4cHJlc3Npb24gZ2V0VmFyaWFibGUoKSB7IHJldHVybiBsaHM7IH0KICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBKQ0V4cHJlc3Npb24gZ2V0RXhwcmVzc2lvbigpIHsgcmV0dXJuIHJoczsgfQogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyA8UixEPiBSIGFjY2VwdChUcmVlVmlzaXRvcjxSLEQ+IHYsIEQgZCkgewogICAgICAgICAgICByZXR1cm4gdi52aXNpdENvbXBvdW5kQXNzaWdubWVudCh0aGlzLCBkKTsKICAgICAgICB9CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIEpDRXhwcmVzc2lvbiBnZXRPcGVyYW5kKE9wZXJhbmRQb3MgcG9zKSB7CiAgICAgICAgICAgIHJldHVybiBwb3MgPT0gT3BlcmFuZFBvcy5MRUZUID8gbGhzIDogcmhzOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEEgdW5hcnkgb3BlcmF0aW9uLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIEpDVW5hcnkgZXh0ZW5kcyBKQ09wZXJhdG9yRXhwcmVzc2lvbiBpbXBsZW1lbnRzIFVuYXJ5VHJlZSB7CiAgICAgICAgcHVibGljIEpDRXhwcmVzc2lvbiBhcmc7CiAgICAgICAgcHJvdGVjdGVkIEpDVW5hcnkoVGFnIG9wY29kZSwgSkNFeHByZXNzaW9uIGFyZykgewogICAgICAgICAgICB0aGlzLm9wY29kZSA9IG9wY29kZTsKICAgICAgICAgICAgdGhpcy5hcmcgPSBhcmc7CiAgICAgICAgfQogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsgdi52aXNpdFVuYXJ5KHRoaXMpOyB9CgogICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIEtpbmQgZ2V0S2luZCgpIHsgcmV0dXJuIFRyZWVJbmZvLnRhZ1RvS2luZChnZXRUYWcoKSk7IH0KICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBKQ0V4cHJlc3Npb24gZ2V0RXhwcmVzc2lvbigpIHsgcmV0dXJuIGFyZzsgfQogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyA8UixEPiBSIGFjY2VwdChUcmVlVmlzaXRvcjxSLEQ+IHYsIEQgZCkgewogICAgICAgICAgICByZXR1cm4gdi52aXNpdFVuYXJ5KHRoaXMsIGQpOwogICAgICAgIH0KICAgICAgICBwdWJsaWMgdm9pZCBzZXRUYWcoVGFnIHRhZykgewogICAgICAgICAgICBvcGNvZGUgPSB0YWc7CiAgICAgICAgfQogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBKQ0V4cHJlc3Npb24gZ2V0T3BlcmFuZChPcGVyYW5kUG9zIHBvcykgewogICAgICAgICAgICByZXR1cm4gYXJnOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEEgYmluYXJ5IG9wZXJhdGlvbi4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBjbGFzcyBKQ0JpbmFyeSBleHRlbmRzIEpDT3BlcmF0b3JFeHByZXNzaW9uIGltcGxlbWVudHMgQmluYXJ5VHJlZSB7CiAgICAgICAgcHVibGljIEpDRXhwcmVzc2lvbiBsaHM7CiAgICAgICAgcHVibGljIEpDRXhwcmVzc2lvbiByaHM7CiAgICAgICAgcHJvdGVjdGVkIEpDQmluYXJ5KFRhZyBvcGNvZGUsCiAgICAgICAgICAgICAgICAgICAgICAgICBKQ0V4cHJlc3Npb24gbGhzLAogICAgICAgICAgICAgICAgICAgICAgICAgSkNFeHByZXNzaW9uIHJocywKICAgICAgICAgICAgICAgICAgICAgICAgIE9wZXJhdG9yU3ltYm9sIG9wZXJhdG9yKSB7CiAgICAgICAgICAgIHRoaXMub3Bjb2RlID0gb3Bjb2RlOwogICAgICAgICAgICB0aGlzLmxocyA9IGxoczsKICAgICAgICAgICAgdGhpcy5yaHMgPSByaHM7CiAgICAgICAgICAgIHRoaXMub3BlcmF0b3IgPSBvcGVyYXRvcjsKICAgICAgICB9CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgeyB2LnZpc2l0QmluYXJ5KHRoaXMpOyB9CgogICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIEtpbmQgZ2V0S2luZCgpIHsgcmV0dXJuIFRyZWVJbmZvLnRhZ1RvS2luZChnZXRUYWcoKSk7IH0KICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBKQ0V4cHJlc3Npb24gZ2V0TGVmdE9wZXJhbmQoKSB7IHJldHVybiBsaHM7IH0KICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBKQ0V4cHJlc3Npb24gZ2V0UmlnaHRPcGVyYW5kKCkgeyByZXR1cm4gcmhzOyB9CiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIDxSLEQ+IFIgYWNjZXB0KFRyZWVWaXNpdG9yPFIsRD4gdiwgRCBkKSB7CiAgICAgICAgICAgIHJldHVybiB2LnZpc2l0QmluYXJ5KHRoaXMsIGQpOwogICAgICAgIH0KICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgSkNFeHByZXNzaW9uIGdldE9wZXJhbmQoT3BlcmFuZFBvcyBwb3MpIHsKICAgICAgICAgICAgcmV0dXJuIHBvcyA9PSBPcGVyYW5kUG9zLkxFRlQgPyBsaHMgOiByaHM7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQSB0eXBlIGNhc3QuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgSkNUeXBlQ2FzdCBleHRlbmRzIEpDRXhwcmVzc2lvbiBpbXBsZW1lbnRzIFR5cGVDYXN0VHJlZSB7CiAgICAgICAgcHVibGljIEpDVHJlZSBjbGF6ejsKICAgICAgICBwdWJsaWMgSkNFeHByZXNzaW9uIGV4cHI7CiAgICAgICAgcHJvdGVjdGVkIEpDVHlwZUNhc3QoSkNUcmVlIGNsYXp6LCBKQ0V4cHJlc3Npb24gZXhwcikgewogICAgICAgICAgICB0aGlzLmNsYXp6ID0gY2xheno7CiAgICAgICAgICAgIHRoaXMuZXhwciA9IGV4cHI7CiAgICAgICAgfQogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsgdi52aXNpdFR5cGVDYXN0KHRoaXMpOyB9CgogICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIEtpbmQgZ2V0S2luZCgpIHsgcmV0dXJuIEtpbmQuVFlQRV9DQVNUOyB9CiAgICAgICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgSkNUcmVlIGdldFR5cGUoKSB7IHJldHVybiBjbGF6ejsgfQogICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIEpDRXhwcmVzc2lvbiBnZXRFeHByZXNzaW9uKCkgeyByZXR1cm4gZXhwcjsgfQogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyA8UixEPiBSIGFjY2VwdChUcmVlVmlzaXRvcjxSLEQ+IHYsIEQgZCkgewogICAgICAgICAgICByZXR1cm4gdi52aXNpdFR5cGVDYXN0KHRoaXMsIGQpOwogICAgICAgIH0KICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgVGFnIGdldFRhZygpIHsKICAgICAgICAgICAgcmV0dXJuIFRZUEVDQVNUOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEEgdHlwZSB0ZXN0LgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIEpDSW5zdGFuY2VPZiBleHRlbmRzIEpDRXhwcmVzc2lvbiBpbXBsZW1lbnRzIEluc3RhbmNlT2ZUcmVlIHsKICAgICAgICBwdWJsaWMgSkNFeHByZXNzaW9uIGV4cHI7CiAgICAgICAgcHVibGljIEpDVHJlZSBjbGF6ejsKICAgICAgICBwcm90ZWN0ZWQgSkNJbnN0YW5jZU9mKEpDRXhwcmVzc2lvbiBleHByLCBKQ1RyZWUgY2xhenopIHsKICAgICAgICAgICAgdGhpcy5leHByID0gZXhwcjsKICAgICAgICAgICAgdGhpcy5jbGF6eiA9IGNsYXp6OwogICAgICAgIH0KICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7IHYudmlzaXRUeXBlVGVzdCh0aGlzKTsgfQoKICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBLaW5kIGdldEtpbmQoKSB7IHJldHVybiBLaW5kLklOU1RBTkNFX09GOyB9CiAgICAgICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgSkNUcmVlIGdldFR5cGUoKSB7IHJldHVybiBjbGF6ejsgfQogICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIEpDRXhwcmVzc2lvbiBnZXRFeHByZXNzaW9uKCkgeyByZXR1cm4gZXhwcjsgfQogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyA8UixEPiBSIGFjY2VwdChUcmVlVmlzaXRvcjxSLEQ+IHYsIEQgZCkgewogICAgICAgICAgICByZXR1cm4gdi52aXNpdEluc3RhbmNlT2YodGhpcywgZCk7CiAgICAgICAgfQogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBUYWcgZ2V0VGFnKCkgewogICAgICAgICAgICByZXR1cm4gVFlQRVRFU1Q7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQW4gYXJyYXkgc2VsZWN0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgSkNBcnJheUFjY2VzcyBleHRlbmRzIEpDRXhwcmVzc2lvbiBpbXBsZW1lbnRzIEFycmF5QWNjZXNzVHJlZSB7CiAgICAgICAgcHVibGljIEpDRXhwcmVzc2lvbiBpbmRleGVkOwogICAgICAgIHB1YmxpYyBKQ0V4cHJlc3Npb24gaW5kZXg7CiAgICAgICAgcHJvdGVjdGVkIEpDQXJyYXlBY2Nlc3MoSkNFeHByZXNzaW9uIGluZGV4ZWQsIEpDRXhwcmVzc2lvbiBpbmRleCkgewogICAgICAgICAgICB0aGlzLmluZGV4ZWQgPSBpbmRleGVkOwogICAgICAgICAgICB0aGlzLmluZGV4ID0gaW5kZXg7CiAgICAgICAgfQogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsgdi52aXNpdEluZGV4ZWQodGhpcyk7IH0KCiAgICAgICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgS2luZCBnZXRLaW5kKCkgeyByZXR1cm4gS2luZC5BUlJBWV9BQ0NFU1M7IH0KICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBKQ0V4cHJlc3Npb24gZ2V0RXhwcmVzc2lvbigpIHsgcmV0dXJuIGluZGV4ZWQ7IH0KICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBKQ0V4cHJlc3Npb24gZ2V0SW5kZXgoKSB7IHJldHVybiBpbmRleDsgfQogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyA8UixEPiBSIGFjY2VwdChUcmVlVmlzaXRvcjxSLEQ+IHYsIEQgZCkgewogICAgICAgICAgICByZXR1cm4gdi52aXNpdEFycmF5QWNjZXNzKHRoaXMsIGQpOwogICAgICAgIH0KICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgVGFnIGdldFRhZygpIHsKICAgICAgICAgICAgcmV0dXJuIElOREVYRUQ7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogU2VsZWN0cyB0aHJvdWdoIHBhY2thZ2VzIGFuZCBjbGFzc2VzCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgSkNGaWVsZEFjY2VzcyBleHRlbmRzIEpDRXhwcmVzc2lvbiBpbXBsZW1lbnRzIE1lbWJlclNlbGVjdFRyZWUgewogICAgICAgIC8qKiBzZWxlY3RlZCBUcmVlIGhpZXJhcmNoeSAqLwogICAgICAgIHB1YmxpYyBKQ0V4cHJlc3Npb24gc2VsZWN0ZWQ7CiAgICAgICAgLyoqIG5hbWUgb2YgZmllbGQgdG8gc2VsZWN0IHRocnUgKi8KICAgICAgICBwdWJsaWMgTmFtZSBuYW1lOwogICAgICAgIC8qKiBzeW1ib2wgb2YgdGhlIHNlbGVjdGVkIGNsYXNzICovCiAgICAgICAgcHVibGljIFN5bWJvbCBzeW07CiAgICAgICAgcHJvdGVjdGVkIEpDRmllbGRBY2Nlc3MoSkNFeHByZXNzaW9uIHNlbGVjdGVkLCBOYW1lIG5hbWUsIFN5bWJvbCBzeW0pIHsKICAgICAgICAgICAgdGhpcy5zZWxlY3RlZCA9IHNlbGVjdGVkOwogICAgICAgICAgICB0aGlzLm5hbWUgPSBuYW1lOwogICAgICAgICAgICB0aGlzLnN5bSA9IHN5bTsKICAgICAgICB9CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgeyB2LnZpc2l0U2VsZWN0KHRoaXMpOyB9CgogICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIEtpbmQgZ2V0S2luZCgpIHsgcmV0dXJuIEtpbmQuTUVNQkVSX1NFTEVDVDsgfQogICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIEpDRXhwcmVzc2lvbiBnZXRFeHByZXNzaW9uKCkgeyByZXR1cm4gc2VsZWN0ZWQ7IH0KICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgPFIsRD4gUiBhY2NlcHQoVHJlZVZpc2l0b3I8UixEPiB2LCBEIGQpIHsKICAgICAgICAgICAgcmV0dXJuIHYudmlzaXRNZW1iZXJTZWxlY3QodGhpcywgZCk7CiAgICAgICAgfQogICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIE5hbWUgZ2V0SWRlbnRpZmllcigpIHsgcmV0dXJuIG5hbWU7IH0KICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgVGFnIGdldFRhZygpIHsKICAgICAgICAgICAgcmV0dXJuIFNFTEVDVDsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBTZWxlY3RzIGEgbWVtYmVyIGV4cHJlc3Npb24uCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgSkNNZW1iZXJSZWZlcmVuY2UgZXh0ZW5kcyBKQ0Z1bmN0aW9uYWxFeHByZXNzaW9uIGltcGxlbWVudHMgTWVtYmVyUmVmZXJlbmNlVHJlZSB7CgogICAgICAgIHB1YmxpYyBSZWZlcmVuY2VNb2RlIG1vZGU7CiAgICAgICAgcHVibGljIFJlZmVyZW5jZUtpbmQga2luZDsKICAgICAgICBwdWJsaWMgTmFtZSBuYW1lOwogICAgICAgIHB1YmxpYyBKQ0V4cHJlc3Npb24gZXhwcjsKICAgICAgICBwdWJsaWMgTGlzdDxKQ0V4cHJlc3Npb24+IHR5cGVhcmdzOwogICAgICAgIHB1YmxpYyBTeW1ib2wgc3ltOwogICAgICAgIHB1YmxpYyBUeXBlIHZhcmFyZ3NFbGVtZW50OwogICAgICAgIHB1YmxpYyBQb2x5S2luZCByZWZQb2x5S2luZDsKICAgICAgICBwdWJsaWMgYm9vbGVhbiBvd25lckFjY2Vzc2libGU7CiAgICAgICAgcHVibGljIE92ZXJsb2FkS2luZCBvdmVybG9hZEtpbmQ7CiAgICAgICAgcHVibGljIFR5cGUgcmVmZXJlbnRUeXBlOwoKICAgICAgICBwdWJsaWMgZW51bSBPdmVybG9hZEtpbmQgewogICAgICAgICAgICBPVkVSTE9BREVELAogICAgICAgICAgICBVTk9WRVJMT0FERUQKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIEphdmFjLWRlcGVuZGVudCBjbGFzc2lmaWNhdGlvbiBmb3IgbWVtYmVyIHJlZmVyZW5jZXMsIGJhc2VkCiAgICAgICAgICogb24gcmVsZXZhbnQgcHJvcGVydGllcyB3LnIudC4gY29kZS1nZW5lcmF0aW9uCiAgICAgICAgICovCiAgICAgICAgcHVibGljIGVudW0gUmVmZXJlbmNlS2luZCB7CiAgICAgICAgICAgIC8qKiBzdXBlciAjIGluc3RNZXRob2QgKi8KICAgICAgICAgICAgU1VQRVIoUmVmZXJlbmNlTW9kZS5JTlZPS0UsIGZhbHNlKSwKICAgICAgICAgICAgLyoqIFR5cGUgIyBpbnN0TWV0aG9kICovCiAgICAgICAgICAgIFVOQk9VTkQoUmVmZXJlbmNlTW9kZS5JTlZPS0UsIHRydWUpLAogICAgICAgICAgICAvKiogVHlwZSAjIHN0YXRpY01ldGhvZCAqLwogICAgICAgICAgICBTVEFUSUMoUmVmZXJlbmNlTW9kZS5JTlZPS0UsIGZhbHNlKSwKICAgICAgICAgICAgLyoqIEV4cHIgIyBpbnN0TWV0aG9kICovCiAgICAgICAgICAgIEJPVU5EKFJlZmVyZW5jZU1vZGUuSU5WT0tFLCBmYWxzZSksCiAgICAgICAgICAgIC8qKiBJbm5lciAjIG5ldyAqLwogICAgICAgICAgICBJTVBMSUNJVF9JTk5FUihSZWZlcmVuY2VNb2RlLk5FVywgZmFsc2UpLAogICAgICAgICAgICAvKiogVG9wbGV2ZWwgIyBuZXcgKi8KICAgICAgICAgICAgVE9QTEVWRUwoUmVmZXJlbmNlTW9kZS5ORVcsIGZhbHNlKSwKICAgICAgICAgICAgLyoqIEFycmF5VHlwZSAjIG5ldyAqLwogICAgICAgICAgICBBUlJBWV9DVE9SKFJlZmVyZW5jZU1vZGUuTkVXLCBmYWxzZSk7CgogICAgICAgICAgICBmaW5hbCBSZWZlcmVuY2VNb2RlIG1vZGU7CiAgICAgICAgICAgIGZpbmFsIGJvb2xlYW4gdW5ib3VuZDsKCiAgICAgICAgICAgIHByaXZhdGUgUmVmZXJlbmNlS2luZChSZWZlcmVuY2VNb2RlIG1vZGUsIGJvb2xlYW4gdW5ib3VuZCkgewogICAgICAgICAgICAgICAgdGhpcy5tb2RlID0gbW9kZTsKICAgICAgICAgICAgICAgIHRoaXMudW5ib3VuZCA9IHVuYm91bmQ7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHB1YmxpYyBib29sZWFuIGlzVW5ib3VuZCgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB1bmJvdW5kOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwcm90ZWN0ZWQgSkNNZW1iZXJSZWZlcmVuY2UoUmVmZXJlbmNlTW9kZSBtb2RlLCBOYW1lIG5hbWUsIEpDRXhwcmVzc2lvbiBleHByLCBMaXN0PEpDRXhwcmVzc2lvbj4gdHlwZWFyZ3MpIHsKICAgICAgICAgICAgdGhpcy5tb2RlID0gbW9kZTsKICAgICAgICAgICAgdGhpcy5uYW1lID0gbmFtZTsKICAgICAgICAgICAgdGhpcy5leHByID0gZXhwcjsKICAgICAgICAgICAgdGhpcy50eXBlYXJncyA9IHR5cGVhcmdzOwogICAgICAgIH0KICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7IHYudmlzaXRSZWZlcmVuY2UodGhpcyk7IH0KCiAgICAgICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgS2luZCBnZXRLaW5kKCkgeyByZXR1cm4gS2luZC5NRU1CRVJfUkVGRVJFTkNFOyB9CiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIFJlZmVyZW5jZU1vZGUgZ2V0TW9kZSgpIHsgcmV0dXJuIG1vZGU7IH0KICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgSkNFeHByZXNzaW9uIGdldFF1YWxpZmllckV4cHJlc3Npb24oKSB7IHJldHVybiBleHByOyB9CiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIE5hbWUgZ2V0TmFtZSgpIHsgcmV0dXJuIG5hbWU7IH0KICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgTGlzdDxKQ0V4cHJlc3Npb24+IGdldFR5cGVBcmd1bWVudHMoKSB7IHJldHVybiB0eXBlYXJnczsgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgPFIsRD4gUiBhY2NlcHQoVHJlZVZpc2l0b3I8UixEPiB2LCBEIGQpIHsKICAgICAgICAgICAgcmV0dXJuIHYudmlzaXRNZW1iZXJSZWZlcmVuY2UodGhpcywgZCk7CiAgICAgICAgfQogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBUYWcgZ2V0VGFnKCkgewogICAgICAgICAgICByZXR1cm4gUkVGRVJFTkNFOwogICAgICAgIH0KICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNLaW5kKFJlZmVyZW5jZUtpbmQga2luZCkgewogICAgICAgICAgICByZXR1cm4gdGhpcy5raW5kID09IGtpbmQ7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQW4gaWRlbnRpZmllcgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIEpDSWRlbnQgZXh0ZW5kcyBKQ0V4cHJlc3Npb24gaW1wbGVtZW50cyBJZGVudGlmaWVyVHJlZSB7CiAgICAgICAgLyoqIHRoZSBuYW1lICovCiAgICAgICAgcHVibGljIE5hbWUgbmFtZTsKICAgICAgICAvKiogdGhlIHN5bWJvbCAqLwogICAgICAgIHB1YmxpYyBTeW1ib2wgc3ltOwogICAgICAgIHByb3RlY3RlZCBKQ0lkZW50KE5hbWUgbmFtZSwgU3ltYm9sIHN5bSkgewogICAgICAgICAgICB0aGlzLm5hbWUgPSBuYW1lOwogICAgICAgICAgICB0aGlzLnN5bSA9IHN5bTsKICAgICAgICB9CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgeyB2LnZpc2l0SWRlbnQodGhpcyk7IH0KCiAgICAgICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgS2luZCBnZXRLaW5kKCkgeyByZXR1cm4gS2luZC5JREVOVElGSUVSOyB9CiAgICAgICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgTmFtZSBnZXROYW1lKCkgeyByZXR1cm4gbmFtZTsgfQogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyA8UixEPiBSIGFjY2VwdChUcmVlVmlzaXRvcjxSLEQ+IHYsIEQgZCkgewogICAgICAgICAgICByZXR1cm4gdi52aXNpdElkZW50aWZpZXIodGhpcywgZCk7CiAgICAgICAgfQogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBUYWcgZ2V0VGFnKCkgewogICAgICAgICAgICByZXR1cm4gSURFTlQ7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQSBjb25zdGFudCB2YWx1ZSBnaXZlbiBsaXRlcmFsbHkuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgSkNMaXRlcmFsIGV4dGVuZHMgSkNFeHByZXNzaW9uIGltcGxlbWVudHMgTGl0ZXJhbFRyZWUgewogICAgICAgIHB1YmxpYyBUeXBlVGFnIHR5cGV0YWc7CiAgICAgICAgLyoqIHZhbHVlIHJlcHJlc2VudGF0aW9uICovCiAgICAgICAgcHVibGljIE9iamVjdCB2YWx1ZTsKICAgICAgICBwcm90ZWN0ZWQgSkNMaXRlcmFsKFR5cGVUYWcgdHlwZXRhZywgT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICAgIHRoaXMudHlwZXRhZyA9IHR5cGV0YWc7CiAgICAgICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTsKICAgICAgICB9CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgeyB2LnZpc2l0TGl0ZXJhbCh0aGlzKTsgfQoKICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBLaW5kIGdldEtpbmQoKSB7CiAgICAgICAgICAgIHJldHVybiB0eXBldGFnLmdldEtpbmRMaXRlcmFsKCk7CiAgICAgICAgfQoKICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBPYmplY3QgZ2V0VmFsdWUoKSB7CiAgICAgICAgICAgIHN3aXRjaCAodHlwZXRhZykgewogICAgICAgICAgICAgICAgY2FzZSBCT09MRUFOOgogICAgICAgICAgICAgICAgICAgIGludCBiaSA9IChJbnRlZ2VyKSB2YWx1ZTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gKGJpICE9IDApOwogICAgICAgICAgICAgICAgY2FzZSBDSEFSOgogICAgICAgICAgICAgICAgICAgIGludCBjaSA9IChJbnRlZ2VyKSB2YWx1ZTsKICAgICAgICAgICAgICAgICAgICBjaGFyIGMgPSAoY2hhcikgY2k7CiAgICAgICAgICAgICAgICAgICAgaWYgKGMgIT0gY2kpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigiYmFkIHZhbHVlIGZvciBjaGFyIGxpdGVyYWwiKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gYzsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyA8UixEPiBSIGFjY2VwdChUcmVlVmlzaXRvcjxSLEQ+IHYsIEQgZCkgewogICAgICAgICAgICByZXR1cm4gdi52aXNpdExpdGVyYWwodGhpcywgZCk7CiAgICAgICAgfQogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBKQ0xpdGVyYWwgc2V0VHlwZShUeXBlIHR5cGUpIHsKICAgICAgICAgICAgc3VwZXIuc2V0VHlwZSh0eXBlKTsKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBUYWcgZ2V0VGFnKCkgewogICAgICAgICAgICByZXR1cm4gTElURVJBTDsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBJZGVudGlmaWVzIGEgYmFzaWMgdHlwZS4KICAgICAqIEBzZWUgVHlwZVRhZwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIEpDUHJpbWl0aXZlVHlwZVRyZWUgZXh0ZW5kcyBKQ0V4cHJlc3Npb24gaW1wbGVtZW50cyBQcmltaXRpdmVUeXBlVHJlZSB7CiAgICAgICAgLyoqIHRoZSBiYXNpYyB0eXBlIGlkICovCiAgICAgICAgcHVibGljIFR5cGVUYWcgdHlwZXRhZzsKICAgICAgICBwcm90ZWN0ZWQgSkNQcmltaXRpdmVUeXBlVHJlZShUeXBlVGFnIHR5cGV0YWcpIHsKICAgICAgICAgICAgdGhpcy50eXBldGFnID0gdHlwZXRhZzsKICAgICAgICB9CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgeyB2LnZpc2l0VHlwZUlkZW50KHRoaXMpOyB9CgogICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIEtpbmQgZ2V0S2luZCgpIHsgcmV0dXJuIEtpbmQuUFJJTUlUSVZFX1RZUEU7IH0KICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBUeXBlS2luZCBnZXRQcmltaXRpdmVUeXBlS2luZCgpIHsKICAgICAgICAgICAgcmV0dXJuIHR5cGV0YWcuZ2V0UHJpbWl0aXZlVHlwZUtpbmQoKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyA8UixEPiBSIGFjY2VwdChUcmVlVmlzaXRvcjxSLEQ+IHYsIEQgZCkgewogICAgICAgICAgICByZXR1cm4gdi52aXNpdFByaW1pdGl2ZVR5cGUodGhpcywgZCk7CiAgICAgICAgfQogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBUYWcgZ2V0VGFnKCkgewogICAgICAgICAgICByZXR1cm4gVFlQRUlERU5UOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEFuIGFycmF5IHR5cGUsIEFbXQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIEpDQXJyYXlUeXBlVHJlZSBleHRlbmRzIEpDRXhwcmVzc2lvbiBpbXBsZW1lbnRzIEFycmF5VHlwZVRyZWUgewogICAgICAgIHB1YmxpYyBKQ0V4cHJlc3Npb24gZWxlbXR5cGU7CiAgICAgICAgcHJvdGVjdGVkIEpDQXJyYXlUeXBlVHJlZShKQ0V4cHJlc3Npb24gZWxlbXR5cGUpIHsKICAgICAgICAgICAgdGhpcy5lbGVtdHlwZSA9IGVsZW10eXBlOwogICAgICAgIH0KICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7IHYudmlzaXRUeXBlQXJyYXkodGhpcyk7IH0KCiAgICAgICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgS2luZCBnZXRLaW5kKCkgeyByZXR1cm4gS2luZC5BUlJBWV9UWVBFOyB9CiAgICAgICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgSkNUcmVlIGdldFR5cGUoKSB7IHJldHVybiBlbGVtdHlwZTsgfQogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyA8UixEPiBSIGFjY2VwdChUcmVlVmlzaXRvcjxSLEQ+IHYsIEQgZCkgewogICAgICAgICAgICByZXR1cm4gdi52aXNpdEFycmF5VHlwZSh0aGlzLCBkKTsKICAgICAgICB9CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFRhZyBnZXRUYWcoKSB7CiAgICAgICAgICAgIHJldHVybiBUWVBFQVJSQVk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQSBwYXJhbWV0ZXJpemVkIHR5cGUsIHtAbGl0ZXJhbCBUPC4uLj59CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgSkNUeXBlQXBwbHkgZXh0ZW5kcyBKQ0V4cHJlc3Npb24gaW1wbGVtZW50cyBQYXJhbWV0ZXJpemVkVHlwZVRyZWUgewogICAgICAgIHB1YmxpYyBKQ0V4cHJlc3Npb24gY2xheno7CiAgICAgICAgcHVibGljIExpc3Q8SkNFeHByZXNzaW9uPiBhcmd1bWVudHM7CiAgICAgICAgcHJvdGVjdGVkIEpDVHlwZUFwcGx5KEpDRXhwcmVzc2lvbiBjbGF6eiwgTGlzdDxKQ0V4cHJlc3Npb24+IGFyZ3VtZW50cykgewogICAgICAgICAgICB0aGlzLmNsYXp6ID0gY2xheno7CiAgICAgICAgICAgIHRoaXMuYXJndW1lbnRzID0gYXJndW1lbnRzOwogICAgICAgIH0KICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7IHYudmlzaXRUeXBlQXBwbHkodGhpcyk7IH0KCiAgICAgICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgS2luZCBnZXRLaW5kKCkgeyByZXR1cm4gS2luZC5QQVJBTUVURVJJWkVEX1RZUEU7IH0KICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBKQ1RyZWUgZ2V0VHlwZSgpIHsgcmV0dXJuIGNsYXp6OyB9CiAgICAgICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgTGlzdDxKQ0V4cHJlc3Npb24+IGdldFR5cGVBcmd1bWVudHMoKSB7CiAgICAgICAgICAgIHJldHVybiBhcmd1bWVudHM7CiAgICAgICAgfQogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyA8UixEPiBSIGFjY2VwdChUcmVlVmlzaXRvcjxSLEQ+IHYsIEQgZCkgewogICAgICAgICAgICByZXR1cm4gdi52aXNpdFBhcmFtZXRlcml6ZWRUeXBlKHRoaXMsIGQpOwogICAgICAgIH0KICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgVGFnIGdldFRhZygpIHsKICAgICAgICAgICAgcmV0dXJuIFRZUEVBUFBMWTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBBIHVuaW9uIHR5cGUsIFQxIHwgVDIgfCAuLi4gVG4gKHVzZWQgaW4gbXVsdGljYXRjaCBzdGF0ZW1lbnRzKQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIEpDVHlwZVVuaW9uIGV4dGVuZHMgSkNFeHByZXNzaW9uIGltcGxlbWVudHMgVW5pb25UeXBlVHJlZSB7CgogICAgICAgIHB1YmxpYyBMaXN0PEpDRXhwcmVzc2lvbj4gYWx0ZXJuYXRpdmVzOwoKICAgICAgICBwcm90ZWN0ZWQgSkNUeXBlVW5pb24oTGlzdDxKQ0V4cHJlc3Npb24+IGNvbXBvbmVudHMpIHsKICAgICAgICAgICAgdGhpcy5hbHRlcm5hdGl2ZXMgPSBjb21wb25lbnRzOwogICAgICAgIH0KICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7IHYudmlzaXRUeXBlVW5pb24odGhpcyk7IH0KCiAgICAgICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgS2luZCBnZXRLaW5kKCkgeyByZXR1cm4gS2luZC5VTklPTl9UWVBFOyB9CgogICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIExpc3Q8SkNFeHByZXNzaW9uPiBnZXRUeXBlQWx0ZXJuYXRpdmVzKCkgewogICAgICAgICAgICByZXR1cm4gYWx0ZXJuYXRpdmVzOwogICAgICAgIH0KICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgPFIsRD4gUiBhY2NlcHQoVHJlZVZpc2l0b3I8UixEPiB2LCBEIGQpIHsKICAgICAgICAgICAgcmV0dXJuIHYudmlzaXRVbmlvblR5cGUodGhpcywgZCk7CiAgICAgICAgfQogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBUYWcgZ2V0VGFnKCkgewogICAgICAgICAgICByZXR1cm4gVFlQRVVOSU9OOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEFuIGludGVyc2VjdGlvbiB0eXBlLCB7QGNvZGUgVDEgJiBUMiAmIC4uLiBUbn0gKHVzZWQgaW4gY2FzdCBleHByZXNzaW9ucykKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBjbGFzcyBKQ1R5cGVJbnRlcnNlY3Rpb24gZXh0ZW5kcyBKQ0V4cHJlc3Npb24gaW1wbGVtZW50cyBJbnRlcnNlY3Rpb25UeXBlVHJlZSB7CgogICAgICAgIHB1YmxpYyBMaXN0PEpDRXhwcmVzc2lvbj4gYm91bmRzOwoKICAgICAgICBwcm90ZWN0ZWQgSkNUeXBlSW50ZXJzZWN0aW9uKExpc3Q8SkNFeHByZXNzaW9uPiBib3VuZHMpIHsKICAgICAgICAgICAgdGhpcy5ib3VuZHMgPSBib3VuZHM7CiAgICAgICAgfQogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsgdi52aXNpdFR5cGVJbnRlcnNlY3Rpb24odGhpcyk7IH0KCiAgICAgICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgS2luZCBnZXRLaW5kKCkgeyByZXR1cm4gS2luZC5JTlRFUlNFQ1RJT05fVFlQRTsgfQoKICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBMaXN0PEpDRXhwcmVzc2lvbj4gZ2V0Qm91bmRzKCkgewogICAgICAgICAgICByZXR1cm4gYm91bmRzOwogICAgICAgIH0KICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgPFIsRD4gUiBhY2NlcHQoVHJlZVZpc2l0b3I8UixEPiB2LCBEIGQpIHsKICAgICAgICAgICAgcmV0dXJuIHYudmlzaXRJbnRlcnNlY3Rpb25UeXBlKHRoaXMsIGQpOwogICAgICAgIH0KICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgVGFnIGdldFRhZygpIHsKICAgICAgICAgICAgcmV0dXJuIFRZUEVJTlRFUlNFQ1RJT047CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQSBmb3JtYWwgY2xhc3MgcGFyYW1ldGVyLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIEpDVHlwZVBhcmFtZXRlciBleHRlbmRzIEpDVHJlZSBpbXBsZW1lbnRzIFR5cGVQYXJhbWV0ZXJUcmVlIHsKICAgICAgICAvKiogbmFtZSAqLwogICAgICAgIHB1YmxpYyBOYW1lIG5hbWU7CiAgICAgICAgLyoqIGJvdW5kcyAqLwogICAgICAgIHB1YmxpYyBMaXN0PEpDRXhwcmVzc2lvbj4gYm91bmRzOwogICAgICAgIC8qKiB0eXBlIGFubm90YXRpb25zIG9uIHR5cGUgcGFyYW1ldGVyICovCiAgICAgICAgcHVibGljIExpc3Q8SkNBbm5vdGF0aW9uPiBhbm5vdGF0aW9uczsKICAgICAgICBwcm90ZWN0ZWQgSkNUeXBlUGFyYW1ldGVyKE5hbWUgbmFtZSwgTGlzdDxKQ0V4cHJlc3Npb24+IGJvdW5kcywgTGlzdDxKQ0Fubm90YXRpb24+IGFubm90YXRpb25zKSB7CiAgICAgICAgICAgIHRoaXMubmFtZSA9IG5hbWU7CiAgICAgICAgICAgIHRoaXMuYm91bmRzID0gYm91bmRzOwogICAgICAgICAgICB0aGlzLmFubm90YXRpb25zID0gYW5ub3RhdGlvbnM7CiAgICAgICAgfQogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsgdi52aXNpdFR5cGVQYXJhbWV0ZXIodGhpcyk7IH0KCiAgICAgICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgS2luZCBnZXRLaW5kKCkgeyByZXR1cm4gS2luZC5UWVBFX1BBUkFNRVRFUjsgfQogICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIE5hbWUgZ2V0TmFtZSgpIHsgcmV0dXJuIG5hbWU7IH0KICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBMaXN0PEpDRXhwcmVzc2lvbj4gZ2V0Qm91bmRzKCkgewogICAgICAgICAgICByZXR1cm4gYm91bmRzOwogICAgICAgIH0KICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBMaXN0PEpDQW5ub3RhdGlvbj4gZ2V0QW5ub3RhdGlvbnMoKSB7CiAgICAgICAgICAgIHJldHVybiBhbm5vdGF0aW9uczsKICAgICAgICB9CiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIDxSLEQ+IFIgYWNjZXB0KFRyZWVWaXNpdG9yPFIsRD4gdiwgRCBkKSB7CiAgICAgICAgICAgIHJldHVybiB2LnZpc2l0VHlwZVBhcmFtZXRlcih0aGlzLCBkKTsKICAgICAgICB9CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFRhZyBnZXRUYWcoKSB7CiAgICAgICAgICAgIHJldHVybiBUWVBFUEFSQU1FVEVSOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIEpDV2lsZGNhcmQgZXh0ZW5kcyBKQ0V4cHJlc3Npb24gaW1wbGVtZW50cyBXaWxkY2FyZFRyZWUgewogICAgICAgIHB1YmxpYyBUeXBlQm91bmRLaW5kIGtpbmQ7CiAgICAgICAgcHVibGljIEpDVHJlZSBpbm5lcjsKICAgICAgICBwcm90ZWN0ZWQgSkNXaWxkY2FyZChUeXBlQm91bmRLaW5kIGtpbmQsIEpDVHJlZSBpbm5lcikgewogICAgICAgICAgICB0aGlzLmtpbmQgPSBBc3NlcnQuY2hlY2tOb25OdWxsKGtpbmQpOwogICAgICAgICAgICB0aGlzLmlubmVyID0gaW5uZXI7CiAgICAgICAgfQogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsgdi52aXNpdFdpbGRjYXJkKHRoaXMpOyB9CgogICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIEtpbmQgZ2V0S2luZCgpIHsKICAgICAgICAgICAgc3dpdGNoIChraW5kLmtpbmQpIHsKICAgICAgICAgICAgY2FzZSBVTkJPVU5EOgogICAgICAgICAgICAgICAgcmV0dXJuIEtpbmQuVU5CT1VOREVEX1dJTERDQVJEOwogICAgICAgICAgICBjYXNlIEVYVEVORFM6CiAgICAgICAgICAgICAgICByZXR1cm4gS2luZC5FWFRFTkRTX1dJTERDQVJEOwogICAgICAgICAgICBjYXNlIFNVUEVSOgogICAgICAgICAgICAgICAgcmV0dXJuIEtpbmQuU1VQRVJfV0lMRENBUkQ7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoIlVua25vd24gd2lsZGNhcmQgYm91bmQgIiArIGtpbmQpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIEpDVHJlZSBnZXRCb3VuZCgpIHsgcmV0dXJuIGlubmVyOyB9CiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIDxSLEQ+IFIgYWNjZXB0KFRyZWVWaXNpdG9yPFIsRD4gdiwgRCBkKSB7CiAgICAgICAgICAgIHJldHVybiB2LnZpc2l0V2lsZGNhcmQodGhpcywgZCk7CiAgICAgICAgfQogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBUYWcgZ2V0VGFnKCkgewogICAgICAgICAgICByZXR1cm4gVGFnLldJTERDQVJEOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIFR5cGVCb3VuZEtpbmQgZXh0ZW5kcyBKQ1RyZWUgewogICAgICAgIHB1YmxpYyBCb3VuZEtpbmQga2luZDsKICAgICAgICBwcm90ZWN0ZWQgVHlwZUJvdW5kS2luZChCb3VuZEtpbmQga2luZCkgewogICAgICAgICAgICB0aGlzLmtpbmQgPSBraW5kOwogICAgICAgIH0KICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7IHYudmlzaXRUeXBlQm91bmRLaW5kKHRoaXMpOyB9CgogICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIEtpbmQgZ2V0S2luZCgpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCJUeXBlQm91bmRLaW5kIGlzIG5vdCBwYXJ0IG9mIGEgcHVibGljIEFQSSIpOwogICAgICAgIH0KICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgPFIsRD4gUiBhY2NlcHQoVHJlZVZpc2l0b3I8UixEPiB2LCBEIGQpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCJUeXBlQm91bmRLaW5kIGlzIG5vdCBwYXJ0IG9mIGEgcHVibGljIEFQSSIpOwogICAgICAgIH0KICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgVGFnIGdldFRhZygpIHsKICAgICAgICAgICAgcmV0dXJuIFRZUEVCT1VOREtJTkQ7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgSkNBbm5vdGF0aW9uIGV4dGVuZHMgSkNFeHByZXNzaW9uIGltcGxlbWVudHMgQW5ub3RhdGlvblRyZWUgewogICAgICAgIC8vIEVpdGhlciBUYWcuQU5OT1RBVElPTiBvciBUYWcuVFlQRV9BTk5PVEFUSU9OCiAgICAgICAgcHJpdmF0ZSBUYWcgdGFnOwoKICAgICAgICBwdWJsaWMgSkNUcmVlIGFubm90YXRpb25UeXBlOwogICAgICAgIHB1YmxpYyBMaXN0PEpDRXhwcmVzc2lvbj4gYXJnczsKICAgICAgICBwdWJsaWMgQXR0cmlidXRlLkNvbXBvdW5kIGF0dHJpYnV0ZTsKCiAgICAgICAgcHJvdGVjdGVkIEpDQW5ub3RhdGlvbihUYWcgdGFnLCBKQ1RyZWUgYW5ub3RhdGlvblR5cGUsIExpc3Q8SkNFeHByZXNzaW9uPiBhcmdzKSB7CiAgICAgICAgICAgIHRoaXMudGFnID0gdGFnOwogICAgICAgICAgICB0aGlzLmFubm90YXRpb25UeXBlID0gYW5ub3RhdGlvblR5cGU7CiAgICAgICAgICAgIHRoaXMuYXJncyA9IGFyZ3M7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7IHYudmlzaXRBbm5vdGF0aW9uKHRoaXMpOyB9CgogICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIEtpbmQgZ2V0S2luZCgpIHsgcmV0dXJuIFRyZWVJbmZvLnRhZ1RvS2luZChnZXRUYWcoKSk7IH0KCiAgICAgICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgSkNUcmVlIGdldEFubm90YXRpb25UeXBlKCkgeyByZXR1cm4gYW5ub3RhdGlvblR5cGU7IH0KICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBMaXN0PEpDRXhwcmVzc2lvbj4gZ2V0QXJndW1lbnRzKCkgewogICAgICAgICAgICByZXR1cm4gYXJnczsKICAgICAgICB9CiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIDxSLEQ+IFIgYWNjZXB0KFRyZWVWaXNpdG9yPFIsRD4gdiwgRCBkKSB7CiAgICAgICAgICAgIHJldHVybiB2LnZpc2l0QW5ub3RhdGlvbih0aGlzLCBkKTsKICAgICAgICB9CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFRhZyBnZXRUYWcoKSB7CiAgICAgICAgICAgIHJldHVybiB0YWc7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgSkNNb2RpZmllcnMgZXh0ZW5kcyBKQ1RyZWUgaW1wbGVtZW50cyBjb20uc3VuLnNvdXJjZS50cmVlLk1vZGlmaWVyc1RyZWUgewogICAgICAgIHB1YmxpYyBsb25nIGZsYWdzOwogICAgICAgIHB1YmxpYyBMaXN0PEpDQW5ub3RhdGlvbj4gYW5ub3RhdGlvbnM7CiAgICAgICAgcHJvdGVjdGVkIEpDTW9kaWZpZXJzKGxvbmcgZmxhZ3MsIExpc3Q8SkNBbm5vdGF0aW9uPiBhbm5vdGF0aW9ucykgewogICAgICAgICAgICB0aGlzLmZsYWdzID0gZmxhZ3M7CiAgICAgICAgICAgIHRoaXMuYW5ub3RhdGlvbnMgPSBhbm5vdGF0aW9uczsKICAgICAgICB9CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgeyB2LnZpc2l0TW9kaWZpZXJzKHRoaXMpOyB9CgogICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIEtpbmQgZ2V0S2luZCgpIHsgcmV0dXJuIEtpbmQuTU9ESUZJRVJTOyB9CiAgICAgICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgU2V0PE1vZGlmaWVyPiBnZXRGbGFncygpIHsKICAgICAgICAgICAgcmV0dXJuIEZsYWdzLmFzTW9kaWZpZXJTZXQoZmxhZ3MpOwogICAgICAgIH0KICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBMaXN0PEpDQW5ub3RhdGlvbj4gZ2V0QW5ub3RhdGlvbnMoKSB7CiAgICAgICAgICAgIHJldHVybiBhbm5vdGF0aW9uczsKICAgICAgICB9CiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIDxSLEQ+IFIgYWNjZXB0KFRyZWVWaXNpdG9yPFIsRD4gdiwgRCBkKSB7CiAgICAgICAgICAgIHJldHVybiB2LnZpc2l0TW9kaWZpZXJzKHRoaXMsIGQpOwogICAgICAgIH0KICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgVGFnIGdldFRhZygpIHsKICAgICAgICAgICAgcmV0dXJuIE1PRElGSUVSUzsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjbGFzcyBKQ0Fubm90YXRlZFR5cGUgZXh0ZW5kcyBKQ0V4cHJlc3Npb24gaW1wbGVtZW50cyBjb20uc3VuLnNvdXJjZS50cmVlLkFubm90YXRlZFR5cGVUcmVlIHsKICAgICAgICAvLyB0eXBlIGFubm90YXRpb25zCiAgICAgICAgcHVibGljIExpc3Q8SkNBbm5vdGF0aW9uPiBhbm5vdGF0aW9uczsKICAgICAgICBwdWJsaWMgSkNFeHByZXNzaW9uIHVuZGVybHlpbmdUeXBlOwoKICAgICAgICBwcm90ZWN0ZWQgSkNBbm5vdGF0ZWRUeXBlKExpc3Q8SkNBbm5vdGF0aW9uPiBhbm5vdGF0aW9ucywgSkNFeHByZXNzaW9uIHVuZGVybHlpbmdUeXBlKSB7CiAgICAgICAgICAgIEFzc2VydC5jaGVjayhhbm5vdGF0aW9ucyAhPSBudWxsICYmIGFubm90YXRpb25zLm5vbkVtcHR5KCkpOwogICAgICAgICAgICB0aGlzLmFubm90YXRpb25zID0gYW5ub3RhdGlvbnM7CiAgICAgICAgICAgIHRoaXMudW5kZXJseWluZ1R5cGUgPSB1bmRlcmx5aW5nVHlwZTsKICAgICAgICB9CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgeyB2LnZpc2l0QW5ub3RhdGVkVHlwZSh0aGlzKTsgfQoKICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBLaW5kIGdldEtpbmQoKSB7IHJldHVybiBLaW5kLkFOTk9UQVRFRF9UWVBFOyB9CiAgICAgICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgTGlzdDxKQ0Fubm90YXRpb24+IGdldEFubm90YXRpb25zKCkgewogICAgICAgICAgICByZXR1cm4gYW5ub3RhdGlvbnM7CiAgICAgICAgfQogICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIEpDRXhwcmVzc2lvbiBnZXRVbmRlcmx5aW5nVHlwZSgpIHsKICAgICAgICAgICAgcmV0dXJuIHVuZGVybHlpbmdUeXBlOwogICAgICAgIH0KICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgPFIsRD4gUiBhY2NlcHQoVHJlZVZpc2l0b3I8UixEPiB2LCBEIGQpIHsKICAgICAgICAgICAgcmV0dXJuIHYudmlzaXRBbm5vdGF0ZWRUeXBlKHRoaXMsIGQpOwogICAgICAgIH0KICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgVGFnIGdldFRhZygpIHsKICAgICAgICAgICAgcmV0dXJuIEFOTk9UQVRFRF9UWVBFOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGFic3RyYWN0IGNsYXNzIEpDRGlyZWN0aXZlIGV4dGVuZHMgSkNUcmVlCiAgICAgICAgaW1wbGVtZW50cyBEaXJlY3RpdmVUcmVlIHsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIEpDTW9kdWxlRGVjbCBleHRlbmRzIEpDVHJlZSBpbXBsZW1lbnRzIE1vZHVsZVRyZWUgewogICAgICAgIHB1YmxpYyBKQ01vZGlmaWVycyBtb2RzOwogICAgICAgIHB1YmxpYyBNb2R1bGVUeXBlIHR5cGU7CiAgICAgICAgcHJpdmF0ZSBmaW5hbCBNb2R1bGVLaW5kIGtpbmQ7CiAgICAgICAgcHVibGljIEpDRXhwcmVzc2lvbiBxdWFsSWQ7CiAgICAgICAgcHVibGljIExpc3Q8SkNEaXJlY3RpdmU+IGRpcmVjdGl2ZXM7CiAgICAgICAgcHVibGljIE1vZHVsZVN5bWJvbCBzeW07CgogICAgICAgIHByb3RlY3RlZCBKQ01vZHVsZURlY2woSkNNb2RpZmllcnMgbW9kcywgTW9kdWxlS2luZCBraW5kLAogICAgICAgICAgICAgICAgSkNFeHByZXNzaW9uIHF1YWxJZCwgTGlzdDxKQ0RpcmVjdGl2ZT4gZGlyZWN0aXZlcykgewogICAgICAgICAgICB0aGlzLm1vZHMgPSBtb2RzOwogICAgICAgICAgICB0aGlzLmtpbmQgPSBraW5kOwogICAgICAgICAgICB0aGlzLnF1YWxJZCA9IHF1YWxJZDsKICAgICAgICAgICAgdGhpcy5kaXJlY3RpdmVzID0gZGlyZWN0aXZlczsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsgdi52aXNpdE1vZHVsZURlZih0aGlzKTsgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgS2luZCBnZXRLaW5kKCkgewogICAgICAgICAgICByZXR1cm4gS2luZC5NT0RVTEU7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgTGlzdDw/IGV4dGVuZHMgQW5ub3RhdGlvblRyZWU+IGdldEFubm90YXRpb25zKCkgewogICAgICAgICAgICByZXR1cm4gbW9kcy5hbm5vdGF0aW9uczsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBNb2R1bGVLaW5kIGdldE1vZHVsZVR5cGUoKSB7CiAgICAgICAgICAgIHJldHVybiBraW5kOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIEpDRXhwcmVzc2lvbiBnZXROYW1lKCkgewogICAgICAgICAgICByZXR1cm4gcXVhbElkOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIExpc3Q8SkNEaXJlY3RpdmU+IGdldERpcmVjdGl2ZXMoKSB7CiAgICAgICAgICAgIHJldHVybiBkaXJlY3RpdmVzOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIDxSLCBEPiBSIGFjY2VwdChUcmVlVmlzaXRvcjxSLCBEPiB2LCBEIGQpIHsKICAgICAgICAgICAgcmV0dXJuIHYudmlzaXRNb2R1bGUodGhpcywgZCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgVGFnIGdldFRhZygpIHsKICAgICAgICAgICAgcmV0dXJuIE1PRFVMRURFRjsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjbGFzcyBKQ0V4cG9ydHMgZXh0ZW5kcyBKQ0RpcmVjdGl2ZQogICAgICAgICAgICBpbXBsZW1lbnRzIEV4cG9ydHNUcmVlIHsKICAgICAgICBwdWJsaWMgSkNFeHByZXNzaW9uIHF1YWxpZDsKICAgICAgICBwdWJsaWMgTGlzdDxKQ0V4cHJlc3Npb24+IG1vZHVsZU5hbWVzOwogICAgICAgIHB1YmxpYyBFeHBvcnRzRGlyZWN0aXZlIGRpcmVjdGl2ZTsKCiAgICAgICAgcHJvdGVjdGVkIEpDRXhwb3J0cyhKQ0V4cHJlc3Npb24gcXVhbElkLCBMaXN0PEpDRXhwcmVzc2lvbj4gbW9kdWxlTmFtZXMpIHsKICAgICAgICAgICAgdGhpcy5xdWFsaWQgPSBxdWFsSWQ7CiAgICAgICAgICAgIHRoaXMubW9kdWxlTmFtZXMgPSBtb2R1bGVOYW1lczsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsgdi52aXNpdEV4cG9ydHModGhpcyk7IH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIEtpbmQgZ2V0S2luZCgpIHsKICAgICAgICAgICAgcmV0dXJuIEtpbmQuRVhQT1JUUzsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBKQ0V4cHJlc3Npb24gZ2V0UGFja2FnZU5hbWUoKSB7CiAgICAgICAgICAgIHJldHVybiBxdWFsaWQ7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgTGlzdDxKQ0V4cHJlc3Npb24+IGdldE1vZHVsZU5hbWVzKCkgewogICAgICAgICAgICByZXR1cm4gbW9kdWxlTmFtZXM7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgPFIsIEQ+IFIgYWNjZXB0KFRyZWVWaXNpdG9yPFIsIEQ+IHYsIEQgZCkgewogICAgICAgICAgICByZXR1cm4gdi52aXNpdEV4cG9ydHModGhpcywgZCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgVGFnIGdldFRhZygpIHsKICAgICAgICAgICAgcmV0dXJuIFRhZy5FWFBPUlRTOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIEpDT3BlbnMgZXh0ZW5kcyBKQ0RpcmVjdGl2ZQogICAgICAgICAgICBpbXBsZW1lbnRzIE9wZW5zVHJlZSB7CiAgICAgICAgcHVibGljIEpDRXhwcmVzc2lvbiBxdWFsaWQ7CiAgICAgICAgcHVibGljIExpc3Q8SkNFeHByZXNzaW9uPiBtb2R1bGVOYW1lczsKICAgICAgICBwdWJsaWMgT3BlbnNEaXJlY3RpdmUgZGlyZWN0aXZlOwoKICAgICAgICBwcm90ZWN0ZWQgSkNPcGVucyhKQ0V4cHJlc3Npb24gcXVhbElkLCBMaXN0PEpDRXhwcmVzc2lvbj4gbW9kdWxlTmFtZXMpIHsKICAgICAgICAgICAgdGhpcy5xdWFsaWQgPSBxdWFsSWQ7CiAgICAgICAgICAgIHRoaXMubW9kdWxlTmFtZXMgPSBtb2R1bGVOYW1lczsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsgdi52aXNpdE9wZW5zKHRoaXMpOyB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBLaW5kIGdldEtpbmQoKSB7CiAgICAgICAgICAgIHJldHVybiBLaW5kLk9QRU5TOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIEpDRXhwcmVzc2lvbiBnZXRQYWNrYWdlTmFtZSgpIHsKICAgICAgICAgICAgcmV0dXJuIHF1YWxpZDsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBMaXN0PEpDRXhwcmVzc2lvbj4gZ2V0TW9kdWxlTmFtZXMoKSB7CiAgICAgICAgICAgIHJldHVybiBtb2R1bGVOYW1lczsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyA8UiwgRD4gUiBhY2NlcHQoVHJlZVZpc2l0b3I8UiwgRD4gdiwgRCBkKSB7CiAgICAgICAgICAgIHJldHVybiB2LnZpc2l0T3BlbnModGhpcywgZCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgVGFnIGdldFRhZygpIHsKICAgICAgICAgICAgcmV0dXJuIFRhZy5PUEVOUzsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjbGFzcyBKQ1Byb3ZpZGVzIGV4dGVuZHMgSkNEaXJlY3RpdmUKICAgICAgICAgICAgaW1wbGVtZW50cyBQcm92aWRlc1RyZWUgewogICAgICAgIHB1YmxpYyBKQ0V4cHJlc3Npb24gc2VydmljZU5hbWU7CiAgICAgICAgcHVibGljIExpc3Q8SkNFeHByZXNzaW9uPiBpbXBsTmFtZXM7CgogICAgICAgIHByb3RlY3RlZCBKQ1Byb3ZpZGVzKEpDRXhwcmVzc2lvbiBzZXJ2aWNlTmFtZSwgTGlzdDxKQ0V4cHJlc3Npb24+IGltcGxOYW1lcykgewogICAgICAgICAgICB0aGlzLnNlcnZpY2VOYW1lID0gc2VydmljZU5hbWU7CiAgICAgICAgICAgIHRoaXMuaW1wbE5hbWVzID0gaW1wbE5hbWVzOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgeyB2LnZpc2l0UHJvdmlkZXModGhpcyk7IH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIEtpbmQgZ2V0S2luZCgpIHsKICAgICAgICAgICAgcmV0dXJuIEtpbmQuUFJPVklERVM7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgPFIsIEQ+IFIgYWNjZXB0KFRyZWVWaXNpdG9yPFIsIEQ+IHYsIEQgZCkgewogICAgICAgICAgICByZXR1cm4gdi52aXNpdFByb3ZpZGVzKHRoaXMsIGQpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIEpDRXhwcmVzc2lvbiBnZXRTZXJ2aWNlTmFtZSgpIHsKICAgICAgICAgICAgcmV0dXJuIHNlcnZpY2VOYW1lOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIExpc3Q8SkNFeHByZXNzaW9uPiBnZXRJbXBsZW1lbnRhdGlvbk5hbWVzKCkgewogICAgICAgICAgICByZXR1cm4gaW1wbE5hbWVzOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFRhZyBnZXRUYWcoKSB7CiAgICAgICAgICAgIHJldHVybiBQUk9WSURFUzsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjbGFzcyBKQ1JlcXVpcmVzIGV4dGVuZHMgSkNEaXJlY3RpdmUKICAgICAgICAgICAgaW1wbGVtZW50cyBSZXF1aXJlc1RyZWUgewogICAgICAgIHB1YmxpYyBib29sZWFuIGlzVHJhbnNpdGl2ZTsKICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc1N0YXRpY1BoYXNlOwogICAgICAgIHB1YmxpYyBKQ0V4cHJlc3Npb24gbW9kdWxlTmFtZTsKICAgICAgICBwdWJsaWMgUmVxdWlyZXNEaXJlY3RpdmUgZGlyZWN0aXZlOwoKICAgICAgICBwcm90ZWN0ZWQgSkNSZXF1aXJlcyhib29sZWFuIGlzVHJhbnNpdGl2ZSwgYm9vbGVhbiBpc1N0YXRpY1BoYXNlLCBKQ0V4cHJlc3Npb24gbW9kdWxlTmFtZSkgewogICAgICAgICAgICB0aGlzLmlzVHJhbnNpdGl2ZSA9IGlzVHJhbnNpdGl2ZTsKICAgICAgICAgICAgdGhpcy5pc1N0YXRpY1BoYXNlID0gaXNTdGF0aWNQaGFzZTsKICAgICAgICAgICAgdGhpcy5tb2R1bGVOYW1lID0gbW9kdWxlTmFtZTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsgdi52aXNpdFJlcXVpcmVzKHRoaXMpOyB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBLaW5kIGdldEtpbmQoKSB7CiAgICAgICAgICAgIHJldHVybiBLaW5kLlJFUVVJUkVTOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIDxSLCBEPiBSIGFjY2VwdChUcmVlVmlzaXRvcjxSLCBEPiB2LCBEIGQpIHsKICAgICAgICAgICAgcmV0dXJuIHYudmlzaXRSZXF1aXJlcyh0aGlzLCBkKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBib29sZWFuIGlzVHJhbnNpdGl2ZSgpIHsKICAgICAgICAgICAgcmV0dXJuIGlzVHJhbnNpdGl2ZTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBib29sZWFuIGlzU3RhdGljKCkgewogICAgICAgICAgICByZXR1cm4gaXNTdGF0aWNQaGFzZTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBKQ0V4cHJlc3Npb24gZ2V0TW9kdWxlTmFtZSgpIHsKICAgICAgICAgICAgcmV0dXJuIG1vZHVsZU5hbWU7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgVGFnIGdldFRhZygpIHsKICAgICAgICAgICAgcmV0dXJuIFJFUVVJUkVTOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIEpDVXNlcyBleHRlbmRzIEpDRGlyZWN0aXZlCiAgICAgICAgICAgIGltcGxlbWVudHMgVXNlc1RyZWUgewogICAgICAgIHB1YmxpYyBKQ0V4cHJlc3Npb24gcXVhbGlkOwoKICAgICAgICBwcm90ZWN0ZWQgSkNVc2VzKEpDRXhwcmVzc2lvbiBxdWFsSWQpIHsKICAgICAgICAgICAgdGhpcy5xdWFsaWQgPSBxdWFsSWQ7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7IHYudmlzaXRVc2VzKHRoaXMpOyB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBLaW5kIGdldEtpbmQoKSB7CiAgICAgICAgICAgIHJldHVybiBLaW5kLlVTRVM7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgSkNFeHByZXNzaW9uIGdldFNlcnZpY2VOYW1lKCkgewogICAgICAgICAgICByZXR1cm4gcXVhbGlkOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIDxSLCBEPiBSIGFjY2VwdChUcmVlVmlzaXRvcjxSLCBEPiB2LCBEIGQpIHsKICAgICAgICAgICAgcmV0dXJuIHYudmlzaXRVc2VzKHRoaXMsIGQpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFRhZyBnZXRUYWcoKSB7CiAgICAgICAgICAgIHJldHVybiBVU0VTOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIEpDRXJyb25lb3VzIGV4dGVuZHMgSkNFeHByZXNzaW9uCiAgICAgICAgICAgIGltcGxlbWVudHMgRXJyb25lb3VzVHJlZSB7CiAgICAgICAgcHVibGljIExpc3Q8PyBleHRlbmRzIEpDVHJlZT4gZXJyczsKICAgICAgICBwcm90ZWN0ZWQgSkNFcnJvbmVvdXMoTGlzdDw/IGV4dGVuZHMgSkNUcmVlPiBlcnJzKSB7CiAgICAgICAgICAgIHRoaXMuZXJycyA9IGVycnM7CiAgICAgICAgfQogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsgdi52aXNpdEVycm9uZW91cyh0aGlzKTsgfQoKICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBLaW5kIGdldEtpbmQoKSB7IHJldHVybiBLaW5kLkVSUk9ORU9VUzsgfQoKICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBMaXN0PD8gZXh0ZW5kcyBKQ1RyZWU+IGdldEVycm9yVHJlZXMoKSB7CiAgICAgICAgICAgIHJldHVybiBlcnJzOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIDxSLEQ+IFIgYWNjZXB0KFRyZWVWaXNpdG9yPFIsRD4gdiwgRCBkKSB7CiAgICAgICAgICAgIHJldHVybiB2LnZpc2l0RXJyb25lb3VzKHRoaXMsIGQpOwogICAgICAgIH0KICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgVGFnIGdldFRhZygpIHsKICAgICAgICAgICAgcmV0dXJuIEVSUk9ORU9VUzsKICAgICAgICB9CiAgICB9CgogICAgLyoqIChsZXQgaW50IHggPSAzOyBpbiB4KzIpICovCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIExldEV4cHIgZXh0ZW5kcyBKQ0V4cHJlc3Npb24gewogICAgICAgIHB1YmxpYyBMaXN0PEpDVmFyaWFibGVEZWNsPiBkZWZzOwogICAgICAgIHB1YmxpYyBKQ0V4cHJlc3Npb24gZXhwcjsKICAgICAgICBwcm90ZWN0ZWQgTGV0RXhwcihMaXN0PEpDVmFyaWFibGVEZWNsPiBkZWZzLCBKQ0V4cHJlc3Npb24gZXhwcikgewogICAgICAgICAgICB0aGlzLmRlZnMgPSBkZWZzOwogICAgICAgICAgICB0aGlzLmV4cHIgPSBleHByOwogICAgICAgIH0KICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7IHYudmlzaXRMZXRFeHByKHRoaXMpOyB9CgogICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIEtpbmQgZ2V0S2luZCgpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCJMZXRFeHByIGlzIG5vdCBwYXJ0IG9mIGEgcHVibGljIEFQSSIpOwogICAgICAgIH0KICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgPFIsRD4gUiBhY2NlcHQoVHJlZVZpc2l0b3I8UixEPiB2LCBEIGQpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCJMZXRFeHByIGlzIG5vdCBwYXJ0IG9mIGEgcHVibGljIEFQSSIpOwogICAgICAgIH0KICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgVGFnIGdldFRhZygpIHsKICAgICAgICAgICAgcmV0dXJuIExFVEVYUFI7CiAgICAgICAgfQogICAgfQoKICAgIC8qKiBBbiBpbnRlcmZhY2UgZm9yIHRyZWUgZmFjdG9yaWVzCiAgICAgKi8KICAgIHB1YmxpYyBpbnRlcmZhY2UgRmFjdG9yeSB7CiAgICAgICAgSkNDb21waWxhdGlvblVuaXQgVG9wTGV2ZWwoTGlzdDxKQ1RyZWU+IGRlZnMpOwogICAgICAgIEpDUGFja2FnZURlY2wgUGFja2FnZURlY2woTGlzdDxKQ0Fubm90YXRpb24+IGFubm90YXRpb25zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSkNFeHByZXNzaW9uIHBpZCk7CiAgICAgICAgSkNJbXBvcnQgSW1wb3J0KEpDVHJlZSBxdWFsaWQsIGJvb2xlYW4gc3RhdGljSW1wb3J0KTsKICAgICAgICBKQ0NsYXNzRGVjbCBDbGFzc0RlZihKQ01vZGlmaWVycyBtb2RzLAogICAgICAgICAgICAgICAgICAgICAgICAgIE5hbWUgbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0PEpDVHlwZVBhcmFtZXRlcj4gdHlwYXJhbXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgSkNFeHByZXNzaW9uIGV4dGVuZGluZywKICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0PEpDRXhwcmVzc2lvbj4gaW1wbGVtZW50aW5nLAogICAgICAgICAgICAgICAgICAgICAgICAgIExpc3Q8SkNUcmVlPiBkZWZzKTsKICAgICAgICBKQ01ldGhvZERlY2wgTWV0aG9kRGVmKEpDTW9kaWZpZXJzIG1vZHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBOYW1lIG5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBKQ0V4cHJlc3Npb24gcmVzdHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIExpc3Q8SkNUeXBlUGFyYW1ldGVyPiB0eXBhcmFtcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEpDVmFyaWFibGVEZWNsIHJlY3ZwYXJhbSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIExpc3Q8SkNWYXJpYWJsZURlY2w+IHBhcmFtcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIExpc3Q8SkNFeHByZXNzaW9uPiB0aHJvd24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBKQ0Jsb2NrIGJvZHksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBKQ0V4cHJlc3Npb24gZGVmYXVsdFZhbHVlKTsKICAgICAgICBKQ1ZhcmlhYmxlRGVjbCBWYXJEZWYoSkNNb2RpZmllcnMgbW9kcywKICAgICAgICAgICAgICAgICAgICAgIE5hbWUgbmFtZSwKICAgICAgICAgICAgICAgICAgICAgIEpDRXhwcmVzc2lvbiB2YXJ0eXBlLAogICAgICAgICAgICAgICAgICAgICAgSkNFeHByZXNzaW9uIGluaXQpOwogICAgICAgIEpDU2tpcCBTa2lwKCk7CiAgICAgICAgSkNCbG9jayBCbG9jayhsb25nIGZsYWdzLCBMaXN0PEpDU3RhdGVtZW50PiBzdGF0cyk7CiAgICAgICAgSkNEb1doaWxlTG9vcCBEb0xvb3AoSkNTdGF0ZW1lbnQgYm9keSwgSkNFeHByZXNzaW9uIGNvbmQpOwogICAgICAgIEpDV2hpbGVMb29wIFdoaWxlTG9vcChKQ0V4cHJlc3Npb24gY29uZCwgSkNTdGF0ZW1lbnQgYm9keSk7CiAgICAgICAgSkNGb3JMb29wIEZvckxvb3AoTGlzdDxKQ1N0YXRlbWVudD4gaW5pdCwKICAgICAgICAgICAgICAgICAgICAgICAgSkNFeHByZXNzaW9uIGNvbmQsCiAgICAgICAgICAgICAgICAgICAgICAgIExpc3Q8SkNFeHByZXNzaW9uU3RhdGVtZW50PiBzdGVwLAogICAgICAgICAgICAgICAgICAgICAgICBKQ1N0YXRlbWVudCBib2R5KTsKICAgICAgICBKQ0VuaGFuY2VkRm9yTG9vcCBGb3JlYWNoTG9vcChKQ1ZhcmlhYmxlRGVjbCB2YXIsIEpDRXhwcmVzc2lvbiBleHByLCBKQ1N0YXRlbWVudCBib2R5KTsKICAgICAgICBKQ0xhYmVsZWRTdGF0ZW1lbnQgTGFiZWxsZWQoTmFtZSBsYWJlbCwgSkNTdGF0ZW1lbnQgYm9keSk7CiAgICAgICAgSkNTd2l0Y2ggU3dpdGNoKEpDRXhwcmVzc2lvbiBzZWxlY3RvciwgTGlzdDxKQ0Nhc2U+IGNhc2VzKTsKICAgICAgICBKQ0Nhc2UgQ2FzZShKQ0V4cHJlc3Npb24gcGF0LCBMaXN0PEpDU3RhdGVtZW50PiBzdGF0cyk7CiAgICAgICAgSkNTeW5jaHJvbml6ZWQgU3luY2hyb25pemVkKEpDRXhwcmVzc2lvbiBsb2NrLCBKQ0Jsb2NrIGJvZHkpOwogICAgICAgIEpDVHJ5IFRyeShKQ0Jsb2NrIGJvZHksIExpc3Q8SkNDYXRjaD4gY2F0Y2hlcnMsIEpDQmxvY2sgZmluYWxpemVyKTsKICAgICAgICBKQ1RyeSBUcnkoTGlzdDxKQ1RyZWU+IHJlc291cmNlcywKICAgICAgICAgICAgICAgICAgSkNCbG9jayBib2R5LAogICAgICAgICAgICAgICAgICBMaXN0PEpDQ2F0Y2g+IGNhdGNoZXJzLAogICAgICAgICAgICAgICAgICBKQ0Jsb2NrIGZpbmFsaXplcik7CiAgICAgICAgSkNDYXRjaCBDYXRjaChKQ1ZhcmlhYmxlRGVjbCBwYXJhbSwgSkNCbG9jayBib2R5KTsKICAgICAgICBKQ0NvbmRpdGlvbmFsIENvbmRpdGlvbmFsKEpDRXhwcmVzc2lvbiBjb25kLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEpDRXhwcmVzc2lvbiB0aGVucGFydCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBKQ0V4cHJlc3Npb24gZWxzZXBhcnQpOwogICAgICAgIEpDSWYgSWYoSkNFeHByZXNzaW9uIGNvbmQsIEpDU3RhdGVtZW50IHRoZW5wYXJ0LCBKQ1N0YXRlbWVudCBlbHNlcGFydCk7CiAgICAgICAgSkNFeHByZXNzaW9uU3RhdGVtZW50IEV4ZWMoSkNFeHByZXNzaW9uIGV4cHIpOwogICAgICAgIEpDQnJlYWsgQnJlYWsoTmFtZSBsYWJlbCk7CiAgICAgICAgSkNDb250aW51ZSBDb250aW51ZShOYW1lIGxhYmVsKTsKICAgICAgICBKQ1JldHVybiBSZXR1cm4oSkNFeHByZXNzaW9uIGV4cHIpOwogICAgICAgIEpDVGhyb3cgVGhyb3coSkNFeHByZXNzaW9uIGV4cHIpOwogICAgICAgIEpDQXNzZXJ0IEFzc2VydChKQ0V4cHJlc3Npb24gY29uZCwgSkNFeHByZXNzaW9uIGRldGFpbCk7CiAgICAgICAgSkNNZXRob2RJbnZvY2F0aW9uIEFwcGx5KExpc3Q8SkNFeHByZXNzaW9uPiB0eXBlYXJncywKICAgICAgICAgICAgICAgICAgICBKQ0V4cHJlc3Npb24gZm4sCiAgICAgICAgICAgICAgICAgICAgTGlzdDxKQ0V4cHJlc3Npb24+IGFyZ3MpOwogICAgICAgIEpDTmV3Q2xhc3MgTmV3Q2xhc3MoSkNFeHByZXNzaW9uIGVuY2wsCiAgICAgICAgICAgICAgICAgICAgICAgICAgTGlzdDxKQ0V4cHJlc3Npb24+IHR5cGVhcmdzLAogICAgICAgICAgICAgICAgICAgICAgICAgIEpDRXhwcmVzc2lvbiBjbGF6eiwKICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0PEpDRXhwcmVzc2lvbj4gYXJncywKICAgICAgICAgICAgICAgICAgICAgICAgICBKQ0NsYXNzRGVjbCBkZWYpOwogICAgICAgIEpDTmV3QXJyYXkgTmV3QXJyYXkoSkNFeHByZXNzaW9uIGVsZW10eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgIExpc3Q8SkNFeHByZXNzaW9uPiBkaW1zLAogICAgICAgICAgICAgICAgICAgICAgICAgIExpc3Q8SkNFeHByZXNzaW9uPiBlbGVtcyk7CiAgICAgICAgSkNQYXJlbnMgUGFyZW5zKEpDRXhwcmVzc2lvbiBleHByKTsKICAgICAgICBKQ0Fzc2lnbiBBc3NpZ24oSkNFeHByZXNzaW9uIGxocywgSkNFeHByZXNzaW9uIHJocyk7CiAgICAgICAgSkNBc3NpZ25PcCBBc3NpZ25vcChUYWcgb3Bjb2RlLCBKQ1RyZWUgbGhzLCBKQ1RyZWUgcmhzKTsKICAgICAgICBKQ1VuYXJ5IFVuYXJ5KFRhZyBvcGNvZGUsIEpDRXhwcmVzc2lvbiBhcmcpOwogICAgICAgIEpDQmluYXJ5IEJpbmFyeShUYWcgb3Bjb2RlLCBKQ0V4cHJlc3Npb24gbGhzLCBKQ0V4cHJlc3Npb24gcmhzKTsKICAgICAgICBKQ1R5cGVDYXN0IFR5cGVDYXN0KEpDVHJlZSBleHByLCBKQ0V4cHJlc3Npb24gdHlwZSk7CiAgICAgICAgSkNJbnN0YW5jZU9mIFR5cGVUZXN0KEpDRXhwcmVzc2lvbiBleHByLCBKQ1RyZWUgY2xhenopOwogICAgICAgIEpDQXJyYXlBY2Nlc3MgSW5kZXhlZChKQ0V4cHJlc3Npb24gaW5kZXhlZCwgSkNFeHByZXNzaW9uIGluZGV4KTsKICAgICAgICBKQ0ZpZWxkQWNjZXNzIFNlbGVjdChKQ0V4cHJlc3Npb24gc2VsZWN0ZWQsIE5hbWUgc2VsZWN0b3IpOwogICAgICAgIEpDSWRlbnQgSWRlbnQoTmFtZSBpZG5hbWUpOwogICAgICAgIEpDTGl0ZXJhbCBMaXRlcmFsKFR5cGVUYWcgdGFnLCBPYmplY3QgdmFsdWUpOwogICAgICAgIEpDUHJpbWl0aXZlVHlwZVRyZWUgVHlwZUlkZW50KFR5cGVUYWcgdHlwZXRhZyk7CiAgICAgICAgSkNBcnJheVR5cGVUcmVlIFR5cGVBcnJheShKQ0V4cHJlc3Npb24gZWxlbXR5cGUpOwogICAgICAgIEpDVHlwZUFwcGx5IFR5cGVBcHBseShKQ0V4cHJlc3Npb24gY2xhenosIExpc3Q8SkNFeHByZXNzaW9uPiBhcmd1bWVudHMpOwogICAgICAgIEpDVHlwZVBhcmFtZXRlciBUeXBlUGFyYW1ldGVyKE5hbWUgbmFtZSwgTGlzdDxKQ0V4cHJlc3Npb24+IGJvdW5kcyk7CiAgICAgICAgSkNXaWxkY2FyZCBXaWxkY2FyZChUeXBlQm91bmRLaW5kIGtpbmQsIEpDVHJlZSB0eXBlKTsKICAgICAgICBUeXBlQm91bmRLaW5kIFR5cGVCb3VuZEtpbmQoQm91bmRLaW5kIGtpbmQpOwogICAgICAgIEpDQW5ub3RhdGlvbiBBbm5vdGF0aW9uKEpDVHJlZSBhbm5vdGF0aW9uVHlwZSwgTGlzdDxKQ0V4cHJlc3Npb24+IGFyZ3MpOwogICAgICAgIEpDTW9kaWZpZXJzIE1vZGlmaWVycyhsb25nIGZsYWdzLCBMaXN0PEpDQW5ub3RhdGlvbj4gYW5ub3RhdGlvbnMpOwogICAgICAgIEpDRXJyb25lb3VzIEVycm9uZW91cyhMaXN0PD8gZXh0ZW5kcyBKQ1RyZWU+IGVycnMpOwogICAgICAgIEpDTW9kdWxlRGVjbCBNb2R1bGVEZWYoSkNNb2RpZmllcnMgbW9kcywgTW9kdWxlS2luZCBraW5kLCBKQ0V4cHJlc3Npb24gcXVhbElkLCBMaXN0PEpDRGlyZWN0aXZlPiBkaXJlY3RpdmVzKTsKICAgICAgICBKQ0V4cG9ydHMgRXhwb3J0cyhKQ0V4cHJlc3Npb24gcXVhbElkLCBMaXN0PEpDRXhwcmVzc2lvbj4gbW9kdWxlTmFtZXMpOwogICAgICAgIEpDT3BlbnMgT3BlbnMoSkNFeHByZXNzaW9uIHF1YWxJZCwgTGlzdDxKQ0V4cHJlc3Npb24+IG1vZHVsZU5hbWVzKTsKICAgICAgICBKQ1Byb3ZpZGVzIFByb3ZpZGVzKEpDRXhwcmVzc2lvbiBzZXJ2aWNlTmFtZSwgTGlzdDxKQ0V4cHJlc3Npb24+IGltcGxOYW1lcyk7CiAgICAgICAgSkNSZXF1aXJlcyBSZXF1aXJlcyhib29sZWFuIGlzVHJhbnNpdGl2ZSwgYm9vbGVhbiBpc1N0YXRpY1BoYXNlLCBKQ0V4cHJlc3Npb24gcXVhbElkKTsKICAgICAgICBKQ1VzZXMgVXNlcyhKQ0V4cHJlc3Npb24gcXVhbElkKTsKICAgICAgICBMZXRFeHByIExldEV4cHIoTGlzdDxKQ1ZhcmlhYmxlRGVjbD4gZGVmcywgSkNFeHByZXNzaW9uIGV4cHIpOwogICAgfQoKICAgIC8qKiBBIGdlbmVyaWMgdmlzaXRvciBjbGFzcyBmb3IgdHJlZXMuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgYWJzdHJhY3QgY2xhc3MgVmlzaXRvciB7CiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRUb3BMZXZlbChKQ0NvbXBpbGF0aW9uVW5pdCB0aGF0KSAgICB7IHZpc2l0VHJlZSh0aGF0KTsgfQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0UGFja2FnZURlZihKQ1BhY2thZ2VEZWNsIHRoYXQpICAgICAgeyB2aXNpdFRyZWUodGhhdCk7IH0KICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdEltcG9ydChKQ0ltcG9ydCB0aGF0KSAgICAgICAgICAgICAgIHsgdmlzaXRUcmVlKHRoYXQpOyB9CiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRDbGFzc0RlZihKQ0NsYXNzRGVjbCB0aGF0KSAgICAgICAgICB7IHZpc2l0VHJlZSh0aGF0KTsgfQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0TWV0aG9kRGVmKEpDTWV0aG9kRGVjbCB0aGF0KSAgICAgICAgeyB2aXNpdFRyZWUodGhhdCk7IH0KICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdFZhckRlZihKQ1ZhcmlhYmxlRGVjbCB0aGF0KSAgICAgICAgIHsgdmlzaXRUcmVlKHRoYXQpOyB9CiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRTa2lwKEpDU2tpcCB0aGF0KSAgICAgICAgICAgICAgICAgICB7IHZpc2l0VHJlZSh0aGF0KTsgfQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0QmxvY2soSkNCbG9jayB0aGF0KSAgICAgICAgICAgICAgICAgeyB2aXNpdFRyZWUodGhhdCk7IH0KICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdERvTG9vcChKQ0RvV2hpbGVMb29wIHRoYXQpICAgICAgICAgIHsgdmlzaXRUcmVlKHRoYXQpOyB9CiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRXaGlsZUxvb3AoSkNXaGlsZUxvb3AgdGhhdCkgICAgICAgICB7IHZpc2l0VHJlZSh0aGF0KTsgfQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0Rm9yTG9vcChKQ0Zvckxvb3AgdGhhdCkgICAgICAgICAgICAgeyB2aXNpdFRyZWUodGhhdCk7IH0KICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdEZvcmVhY2hMb29wKEpDRW5oYW5jZWRGb3JMb29wIHRoYXQpIHsgdmlzaXRUcmVlKHRoYXQpOyB9CiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRMYWJlbGxlZChKQ0xhYmVsZWRTdGF0ZW1lbnQgdGhhdCkgICB7IHZpc2l0VHJlZSh0aGF0KTsgfQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0U3dpdGNoKEpDU3dpdGNoIHRoYXQpICAgICAgICAgICAgICAgeyB2aXNpdFRyZWUodGhhdCk7IH0KICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdENhc2UoSkNDYXNlIHRoYXQpICAgICAgICAgICAgICAgICAgIHsgdmlzaXRUcmVlKHRoYXQpOyB9CiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRTeW5jaHJvbml6ZWQoSkNTeW5jaHJvbml6ZWQgdGhhdCkgICB7IHZpc2l0VHJlZSh0aGF0KTsgfQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0VHJ5KEpDVHJ5IHRoYXQpICAgICAgICAgICAgICAgICAgICAgeyB2aXNpdFRyZWUodGhhdCk7IH0KICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdENhdGNoKEpDQ2F0Y2ggdGhhdCkgICAgICAgICAgICAgICAgIHsgdmlzaXRUcmVlKHRoYXQpOyB9CiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRDb25kaXRpb25hbChKQ0NvbmRpdGlvbmFsIHRoYXQpICAgICB7IHZpc2l0VHJlZSh0aGF0KTsgfQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0SWYoSkNJZiB0aGF0KSAgICAgICAgICAgICAgICAgICAgICAgeyB2aXNpdFRyZWUodGhhdCk7IH0KICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdEV4ZWMoSkNFeHByZXNzaW9uU3RhdGVtZW50IHRoYXQpICAgIHsgdmlzaXRUcmVlKHRoYXQpOyB9CiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRCcmVhayhKQ0JyZWFrIHRoYXQpICAgICAgICAgICAgICAgICB7IHZpc2l0VHJlZSh0aGF0KTsgfQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0Q29udGludWUoSkNDb250aW51ZSB0aGF0KSAgICAgICAgICAgeyB2aXNpdFRyZWUodGhhdCk7IH0KICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdFJldHVybihKQ1JldHVybiB0aGF0KSAgICAgICAgICAgICAgIHsgdmlzaXRUcmVlKHRoYXQpOyB9CiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRUaHJvdyhKQ1Rocm93IHRoYXQpICAgICAgICAgICAgICAgICB7IHZpc2l0VHJlZSh0aGF0KTsgfQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0QXNzZXJ0KEpDQXNzZXJ0IHRoYXQpICAgICAgICAgICAgICAgeyB2aXNpdFRyZWUodGhhdCk7IH0KICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdEFwcGx5KEpDTWV0aG9kSW52b2NhdGlvbiB0aGF0KSAgICAgIHsgdmlzaXRUcmVlKHRoYXQpOyB9CiAgICAgICAgcHVibGljIHZvaWQgdmlzaXROZXdDbGFzcyhKQ05ld0NsYXNzIHRoYXQpICAgICAgICAgICB7IHZpc2l0VHJlZSh0aGF0KTsgfQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0TmV3QXJyYXkoSkNOZXdBcnJheSB0aGF0KSAgICAgICAgICAgeyB2aXNpdFRyZWUodGhhdCk7IH0KICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdExhbWJkYShKQ0xhbWJkYSB0aGF0KSAgICAgICAgICAgICAgIHsgdmlzaXRUcmVlKHRoYXQpOyB9CiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRQYXJlbnMoSkNQYXJlbnMgdGhhdCkgICAgICAgICAgICAgICB7IHZpc2l0VHJlZSh0aGF0KTsgfQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0QXNzaWduKEpDQXNzaWduIHRoYXQpICAgICAgICAgICAgICAgeyB2aXNpdFRyZWUodGhhdCk7IH0KICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdEFzc2lnbm9wKEpDQXNzaWduT3AgdGhhdCkgICAgICAgICAgIHsgdmlzaXRUcmVlKHRoYXQpOyB9CiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRVbmFyeShKQ1VuYXJ5IHRoYXQpICAgICAgICAgICAgICAgICB7IHZpc2l0VHJlZSh0aGF0KTsgfQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0QmluYXJ5KEpDQmluYXJ5IHRoYXQpICAgICAgICAgICAgICAgeyB2aXNpdFRyZWUodGhhdCk7IH0KICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdFR5cGVDYXN0KEpDVHlwZUNhc3QgdGhhdCkgICAgICAgICAgIHsgdmlzaXRUcmVlKHRoYXQpOyB9CiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRUeXBlVGVzdChKQ0luc3RhbmNlT2YgdGhhdCkgICAgICAgICB7IHZpc2l0VHJlZSh0aGF0KTsgfQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0SW5kZXhlZChKQ0FycmF5QWNjZXNzIHRoYXQpICAgICAgICAgeyB2aXNpdFRyZWUodGhhdCk7IH0KICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdFNlbGVjdChKQ0ZpZWxkQWNjZXNzIHRoYXQpICAgICAgICAgIHsgdmlzaXRUcmVlKHRoYXQpOyB9CiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRSZWZlcmVuY2UoSkNNZW1iZXJSZWZlcmVuY2UgdGhhdCkgICB7IHZpc2l0VHJlZSh0aGF0KTsgfQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0SWRlbnQoSkNJZGVudCB0aGF0KSAgICAgICAgICAgICAgICAgeyB2aXNpdFRyZWUodGhhdCk7IH0KICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdExpdGVyYWwoSkNMaXRlcmFsIHRoYXQpICAgICAgICAgICAgIHsgdmlzaXRUcmVlKHRoYXQpOyB9CiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRUeXBlSWRlbnQoSkNQcmltaXRpdmVUeXBlVHJlZSB0aGF0KSB7IHZpc2l0VHJlZSh0aGF0KTsgfQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0VHlwZUFycmF5KEpDQXJyYXlUeXBlVHJlZSB0aGF0KSAgICAgeyB2aXNpdFRyZWUodGhhdCk7IH0KICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdFR5cGVBcHBseShKQ1R5cGVBcHBseSB0aGF0KSAgICAgICAgIHsgdmlzaXRUcmVlKHRoYXQpOyB9CiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRUeXBlVW5pb24oSkNUeXBlVW5pb24gdGhhdCkgICAgICAgICB7IHZpc2l0VHJlZSh0aGF0KTsgfQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0VHlwZUludGVyc2VjdGlvbihKQ1R5cGVJbnRlcnNlY3Rpb24gdGhhdCkgIHsgdmlzaXRUcmVlKHRoYXQpOyB9CiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRUeXBlUGFyYW1ldGVyKEpDVHlwZVBhcmFtZXRlciB0aGF0KSB7IHZpc2l0VHJlZSh0aGF0KTsgfQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0V2lsZGNhcmQoSkNXaWxkY2FyZCB0aGF0KSAgICAgICAgICAgeyB2aXNpdFRyZWUodGhhdCk7IH0KICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdFR5cGVCb3VuZEtpbmQoVHlwZUJvdW5kS2luZCB0aGF0KSAgIHsgdmlzaXRUcmVlKHRoYXQpOyB9CiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRBbm5vdGF0aW9uKEpDQW5ub3RhdGlvbiB0aGF0KSAgICAgICB7IHZpc2l0VHJlZSh0aGF0KTsgfQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0TW9kaWZpZXJzKEpDTW9kaWZpZXJzIHRoYXQpICAgICAgICAgeyB2aXNpdFRyZWUodGhhdCk7IH0KICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdEFubm90YXRlZFR5cGUoSkNBbm5vdGF0ZWRUeXBlIHRoYXQpIHsgdmlzaXRUcmVlKHRoYXQpOyB9CiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRFcnJvbmVvdXMoSkNFcnJvbmVvdXMgdGhhdCkgICAgICAgICB7IHZpc2l0VHJlZSh0aGF0KTsgfQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0TW9kdWxlRGVmKEpDTW9kdWxlRGVjbCB0aGF0KSAgICAgICAgeyB2aXNpdFRyZWUodGhhdCk7IH0KICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdEV4cG9ydHMoSkNFeHBvcnRzIHRoYXQpICAgICAgICAgICAgIHsgdmlzaXRUcmVlKHRoYXQpOyB9CiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRPcGVucyhKQ09wZW5zIHRoYXQpICAgICAgICAgICAgICAgICB7IHZpc2l0VHJlZSh0aGF0KTsgfQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0UHJvdmlkZXMoSkNQcm92aWRlcyB0aGF0KSAgICAgICAgICAgeyB2aXNpdFRyZWUodGhhdCk7IH0KICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdFJlcXVpcmVzKEpDUmVxdWlyZXMgdGhhdCkgICAgICAgICAgIHsgdmlzaXRUcmVlKHRoYXQpOyB9CiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRVc2VzKEpDVXNlcyB0aGF0KSAgICAgICAgICAgICAgICAgICB7IHZpc2l0VHJlZSh0aGF0KTsgfQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0TGV0RXhwcihMZXRFeHByIHRoYXQpICAgICAgICAgICAgICAgeyB2aXNpdFRyZWUodGhhdCk7IH0KCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRUcmVlKEpDVHJlZSB0aGF0KSAgICAgICAgICAgICAgICAgICB7IEFzc2VydC5lcnJvcigpOyB9CiAgICB9Cgp9ClBLAwQKAAAIAAAGO6lKFYJdOkNGAABDRgAAJwAAAGNvbS9zdW4vdG9vbHMvamF2YWMvdHJlZS9Eb2NQcmV0dHkuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMTk5OSwgMjAxNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWU7CgppbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKaW1wb3J0IGphdmEuaW8uV3JpdGVyOwppbXBvcnQgamF2YS51dGlsLkxpc3Q7CgppbXBvcnQgY29tLnN1bi5zb3VyY2UuZG9jdHJlZS4qOwppbXBvcnQgY29tLnN1bi5zb3VyY2UuZG9jdHJlZS5BdHRyaWJ1dGVUcmVlLlZhbHVlS2luZDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5Db252ZXJ0OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkRlZmluZWRCeTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5EZWZpbmVkQnkuQXBpOwoKLyoqCiAqIFByaW50cyBvdXQgYSBkb2MgY29tbWVudCB0cmVlLgogKgogKiAgPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24gcmlzay4KICogIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yCiAqICBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+CiAqLwpwdWJsaWMgY2xhc3MgRG9jUHJldHR5IGltcGxlbWVudHMgRG9jVHJlZVZpc2l0b3I8Vm9pZCxWb2lkPiB7CgogICAgLyoqCiAgICAgKiBUaGUgb3V0cHV0IHN0cmVhbSBvbiB3aGljaCB0cmVlcyBhcmUgcHJpbnRlZC4KICAgICAqLwogICAgZmluYWwgV3JpdGVyIG91dDsKCiAgICAvKioKICAgICAqIFRoZSBsZWZ0IG1hcmdpbi4KICAgICAqLwogICAgaW50IGxtYXJnaW4gPSAwOwoKICAgIHB1YmxpYyBEb2NQcmV0dHkoV3JpdGVyIG91dCkgewogICAgICAgIHRoaXMub3V0ID0gb3V0OwogICAgfQoKICAgIC8qKiBWaXNpdG9yIG1ldGhvZDogcHJpbnQgZXhwcmVzc2lvbiB0cmVlLgogICAgICovCiAgICBwdWJsaWMgdm9pZCBwcmludChEb2NUcmVlIHRyZWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgaWYgKHRyZWUgPT0gbnVsbCkKICAgICAgICAgICAgICAgIHByaW50KCIvKm1pc3NpbmcqLyIpOwogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIHRyZWUuYWNjZXB0KHRoaXMsIG51bGwpOwogICAgICAgICAgICB9CiAgICAgICAgfSBjYXRjaCAoVW5jaGVja2VkSU9FeGNlcHRpb24gZXgpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKGV4LmdldE1lc3NhZ2UoKSwgZXgpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFByaW50IHN0cmluZywgcmVwbGFjaW5nIGFsbCBub24tYXNjaWkgY2hhcmFjdGVyIHdpdGggdW5pY29kZSBlc2NhcGVzLgogICAgICovCiAgICBwcm90ZWN0ZWQgdm9pZCBwcmludChPYmplY3QgcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICBvdXQud3JpdGUoQ29udmVydC5lc2NhcGVVbmljb2RlKHMudG9TdHJpbmcoKSkpOwogICAgfQoKICAgIC8qKgogICAgICogUHJpbnQgbGlzdC4KICAgICAqLwogICAgcHVibGljIHZvaWQgcHJpbnQoTGlzdDw/IGV4dGVuZHMgRG9jVHJlZT4gbGlzdCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICBmb3IgKERvY1RyZWUgdDogbGlzdCkgewogICAgICAgICAgICBwcmludCh0KTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBQcmludCBsaXN0Liwgd2l0aCBzZXBhcmF0b3JzCiAgICAgKi8KICAgIHByb3RlY3RlZCB2b2lkIHByaW50KExpc3Q8PyBleHRlbmRzIERvY1RyZWU+IGxpc3QsIFN0cmluZyBzZXApIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGxpc3QuaXNFbXB0eSgpKQogICAgICAgICAgICByZXR1cm47CiAgICAgICAgYm9vbGVhbiBmaXJzdCA9IHRydWU7CiAgICAgICAgZm9yIChEb2NUcmVlIHQ6IGxpc3QpIHsKICAgICAgICAgICAgaWYgKCFmaXJzdCkKICAgICAgICAgICAgICAgIHByaW50KHNlcCk7CiAgICAgICAgICAgIHByaW50KHQpOwogICAgICAgICAgICBmaXJzdCA9IGZhbHNlOwogICAgICAgIH0KICAgIH0KCiAgICAvKiogUHJpbnQgbmV3IGxpbmUuCiAgICAgKi8KICAgIHByb3RlY3RlZCB2b2lkIHByaW50bG4oKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgIG91dC53cml0ZShsaW5lU2VwKTsKICAgIH0KCiAgICBwcm90ZWN0ZWQgdm9pZCBwcmludFRhZ05hbWUoRG9jVHJlZSBub2RlKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgIG91dC53cml0ZSgiQCIpOwogICAgICAgIG91dC53cml0ZShub2RlLmdldEtpbmQoKS50YWdOYW1lKTsKICAgIH0KCiAgICBmaW5hbCBTdHJpbmcgbGluZVNlcCA9IFN5c3RlbS5nZXRQcm9wZXJ0eSgibGluZS5zZXBhcmF0b3IiKTsKCiAgICAvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICAgICAqIFRyYXZlcnNhbCBtZXRob2RzCiAgICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiAgICAvKiogRXhjZXB0aW9uIHRvIHByb3BhZ2F0ZSBJT0V4Y2VwdGlvbiB0aHJvdWdoIHZpc2l0WFhYIG1ldGhvZHMgKi8KICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIFVuY2hlY2tlZElPRXhjZXB0aW9uIGV4dGVuZHMgRXJyb3IgewogICAgICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNDAzMjY5MjY3OTE1ODQyNDc1MUw7CiAgICAgICAgVW5jaGVja2VkSU9FeGNlcHRpb24oSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICBzdXBlcihlLmdldE1lc3NhZ2UoKSwgZSk7CiAgICAgICAgfQogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIFZvaWQgdmlzaXRBdHRyaWJ1dGUoQXR0cmlidXRlVHJlZSBub2RlLCBWb2lkIHApIHsKICAgICAgICB0cnkgewogICAgICAgICAgICBwcmludChub2RlLmdldE5hbWUoKSk7CiAgICAgICAgICAgIFN0cmluZyBxdW90ZTsKICAgICAgICAgICAgc3dpdGNoIChub2RlLmdldFZhbHVlS2luZCgpKSB7CiAgICAgICAgICAgICAgICBjYXNlIEVNUFRZOgogICAgICAgICAgICAgICAgICAgIHF1b3RlID0gbnVsbDsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgVU5RVU9URUQ6CiAgICAgICAgICAgICAgICAgICAgcXVvdGUgPSAiIjsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgU0lOR0xFOgogICAgICAgICAgICAgICAgICAgIHF1b3RlID0gIiciOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBET1VCTEU6CiAgICAgICAgICAgICAgICAgICAgcXVvdGUgPSAiXCIiOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAocXVvdGUgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgcHJpbnQoIj0iICsgcXVvdGUpOwogICAgICAgICAgICAgICAgcHJpbnQobm9kZS5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIHByaW50KHF1b3RlKTsKICAgICAgICAgICAgfQogICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFVuY2hlY2tlZElPRXhjZXB0aW9uKGUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBWb2lkIHZpc2l0QXV0aG9yKEF1dGhvclRyZWUgbm9kZSwgVm9pZCBwKSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgcHJpbnRUYWdOYW1lKG5vZGUpOwogICAgICAgICAgICBwcmludCgiICIpOwogICAgICAgICAgICBwcmludChub2RlLmdldE5hbWUoKSk7CiAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgVW5jaGVja2VkSU9FeGNlcHRpb24oZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIFZvaWQgdmlzaXRDb21tZW50KENvbW1lbnRUcmVlIG5vZGUsIFZvaWQgcCkgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIHByaW50KG5vZGUuZ2V0Qm9keSgpKTsKICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBVbmNoZWNrZWRJT0V4Y2VwdGlvbihlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICBwdWJsaWMgVm9pZCB2aXNpdERlcHJlY2F0ZWQoRGVwcmVjYXRlZFRyZWUgbm9kZSwgVm9pZCBwKSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgcHJpbnRUYWdOYW1lKG5vZGUpOwogICAgICAgICAgICBpZiAoIW5vZGUuZ2V0Qm9keSgpLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgICAgcHJpbnQoIiAiKTsKICAgICAgICAgICAgICAgIHByaW50KG5vZGUuZ2V0Qm9keSgpKTsKICAgICAgICAgICAgfQogICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFVuY2hlY2tlZElPRXhjZXB0aW9uKGUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBWb2lkIHZpc2l0RG9jQ29tbWVudChEb2NDb21tZW50VHJlZSBub2RlLCBWb2lkIHApIHsKICAgICAgICB0cnkgewogICAgICAgICAgICBMaXN0PD8gZXh0ZW5kcyBEb2NUcmVlPiBiID0gbm9kZS5nZXRGdWxsQm9keSgpOwogICAgICAgICAgICBMaXN0PD8gZXh0ZW5kcyBEb2NUcmVlPiB0ID0gbm9kZS5nZXRCbG9ja1RhZ3MoKTsKICAgICAgICAgICAgcHJpbnQoYik7CiAgICAgICAgICAgIGlmICghYi5pc0VtcHR5KCkgJiYgIXQuaXNFbXB0eSgpKQogICAgICAgICAgICAgICAgcHJpbnQoIlxuIik7CiAgICAgICAgICAgIHByaW50KHQsICJcbiIpOwogICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFVuY2hlY2tlZElPRXhjZXB0aW9uKGUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBWb2lkIHZpc2l0RG9jUm9vdChEb2NSb290VHJlZSBub2RlLCBWb2lkIHApIHsKICAgICAgICB0cnkgewogICAgICAgICAgICBwcmludCgieyIpOwogICAgICAgICAgICBwcmludFRhZ05hbWUobm9kZSk7CiAgICAgICAgICAgIHByaW50KCJ9Iik7CiAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgVW5jaGVja2VkSU9FeGNlcHRpb24oZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIFZvaWQgdmlzaXRFbmRFbGVtZW50KEVuZEVsZW1lbnRUcmVlIG5vZGUsIFZvaWQgcCkgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIHByaW50KCI8LyIpOwogICAgICAgICAgICBwcmludChub2RlLmdldE5hbWUoKSk7CiAgICAgICAgICAgIHByaW50KCI+Iik7CiAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgVW5jaGVja2VkSU9FeGNlcHRpb24oZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIFZvaWQgdmlzaXRFbnRpdHkoRW50aXR5VHJlZSBub2RlLCBWb2lkIHApIHsKICAgICAgICB0cnkgewogICAgICAgICAgICBwcmludCgiJiIpOwogICAgICAgICAgICBwcmludChub2RlLmdldE5hbWUoKSk7CiAgICAgICAgICAgIHByaW50KCI7Iik7CiAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgVW5jaGVja2VkSU9FeGNlcHRpb24oZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIFZvaWQgdmlzaXRFcnJvbmVvdXMoRXJyb25lb3VzVHJlZSBub2RlLCBWb2lkIHApIHsKICAgICAgICB0cnkgewogICAgICAgICAgICBwcmludChub2RlLmdldEJvZHkoKSk7CiAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgVW5jaGVja2VkSU9FeGNlcHRpb24oZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIFZvaWQgdmlzaXRIaWRkZW4oSGlkZGVuVHJlZSBub2RlLCBWb2lkIHApIHsKICAgICAgICB0cnkgewogICAgICAgICAgICBwcmludFRhZ05hbWUobm9kZSk7CiAgICAgICAgICAgIGlmICghbm9kZS5nZXRCb2R5KCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgICBwcmludCgiICIpOwogICAgICAgICAgICAgICAgcHJpbnQobm9kZS5nZXRCb2R5KCkpOwogICAgICAgICAgICB9CiAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgVW5jaGVja2VkSU9FeGNlcHRpb24oZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIFZvaWQgdmlzaXRJZGVudGlmaWVyKElkZW50aWZpZXJUcmVlIG5vZGUsIFZvaWQgcCkgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIHByaW50KG5vZGUuZ2V0TmFtZSgpKTsKICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBVbmNoZWNrZWRJT0V4Y2VwdGlvbihlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICBwdWJsaWMgVm9pZCB2aXNpdEluZGV4KEluZGV4VHJlZSBub2RlLCBWb2lkIHApIHsKICAgICAgICB0cnkgewogICAgICAgICAgICBwcmludCgieyIpOwogICAgICAgICAgICBwcmludFRhZ05hbWUobm9kZSk7CiAgICAgICAgICAgIHByaW50KCIgIik7CiAgICAgICAgICAgIHByaW50KG5vZGUuZ2V0U2VhcmNoVGVybSgpKTsKICAgICAgICAgICAgaWYgKCFub2RlLmdldERlc2NyaXB0aW9uKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgICBwcmludCgiICIpOwogICAgICAgICAgICAgICAgcHJpbnQobm9kZS5nZXREZXNjcmlwdGlvbigpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBwcmludCgifSIpOwogICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFVuY2hlY2tlZElPRXhjZXB0aW9uKGUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBWb2lkIHZpc2l0SW5oZXJpdERvYyhJbmhlcml0RG9jVHJlZSBub2RlLCBWb2lkIHApIHsKICAgICAgICB0cnkgewogICAgICAgICAgICBwcmludCgieyIpOwogICAgICAgICAgICBwcmludFRhZ05hbWUobm9kZSk7CiAgICAgICAgICAgIHByaW50KCJ9Iik7CiAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgVW5jaGVja2VkSU9FeGNlcHRpb24oZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIFZvaWQgdmlzaXRMaW5rKExpbmtUcmVlIG5vZGUsIFZvaWQgcCkgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIHByaW50KCJ7Iik7CiAgICAgICAgICAgIHByaW50VGFnTmFtZShub2RlKTsKICAgICAgICAgICAgcHJpbnQoIiAiKTsKICAgICAgICAgICAgcHJpbnQobm9kZS5nZXRSZWZlcmVuY2UoKSk7CiAgICAgICAgICAgIGlmICghbm9kZS5nZXRMYWJlbCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgICAgcHJpbnQoIiAiKTsKICAgICAgICAgICAgICAgIHByaW50KG5vZGUuZ2V0TGFiZWwoKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcHJpbnQoIn0iKTsKICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBVbmNoZWNrZWRJT0V4Y2VwdGlvbihlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICBwdWJsaWMgVm9pZCB2aXNpdExpdGVyYWwoTGl0ZXJhbFRyZWUgbm9kZSwgVm9pZCBwKSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgcHJpbnQoInsiKTsKICAgICAgICAgICAgcHJpbnRUYWdOYW1lKG5vZGUpOwogICAgICAgICAgICBTdHJpbmcgYm9keSA9IG5vZGUuZ2V0Qm9keSgpLmdldEJvZHkoKTsKICAgICAgICAgICAgaWYgKCFib2R5LmlzRW1wdHkoKSAmJiAhQ2hhcmFjdGVyLmlzV2hpdGVzcGFjZShib2R5LmNoYXJBdCgwKSkpIHsKICAgICAgICAgICAgICAgIHByaW50KCIgIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcHJpbnQobm9kZS5nZXRCb2R5KCkpOwogICAgICAgICAgICBwcmludCgifSIpOwogICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFVuY2hlY2tlZElPRXhjZXB0aW9uKGUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBWb2lkIHZpc2l0UGFyYW0oUGFyYW1UcmVlIG5vZGUsIFZvaWQgcCkgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIHByaW50VGFnTmFtZShub2RlKTsKICAgICAgICAgICAgcHJpbnQoIiAiKTsKICAgICAgICAgICAgaWYgKG5vZGUuaXNUeXBlUGFyYW1ldGVyKCkpIHByaW50KCI8Iik7CiAgICAgICAgICAgIHByaW50KG5vZGUuZ2V0TmFtZSgpKTsKICAgICAgICAgICAgaWYgKG5vZGUuaXNUeXBlUGFyYW1ldGVyKCkpIHByaW50KCI+Iik7CiAgICAgICAgICAgIGlmICghbm9kZS5nZXREZXNjcmlwdGlvbigpLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgICAgcHJpbnQoIiAiKTsKICAgICAgICAgICAgICAgIHByaW50KG5vZGUuZ2V0RGVzY3JpcHRpb24oKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBVbmNoZWNrZWRJT0V4Y2VwdGlvbihlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICBwdWJsaWMgVm9pZCB2aXNpdFByb3ZpZGVzKFByb3ZpZGVzVHJlZSBub2RlLCBWb2lkIHApIHsKICAgICAgICB0cnkgewogICAgICAgICAgICBwcmludFRhZ05hbWUobm9kZSk7CiAgICAgICAgICAgIHByaW50KCIgIik7CiAgICAgICAgICAgIHByaW50KG5vZGUuZ2V0U2VydmljZVR5cGUoKSk7CiAgICAgICAgICAgIGlmICghbm9kZS5nZXREZXNjcmlwdGlvbigpLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgICAgcHJpbnQoIiAiKTsKICAgICAgICAgICAgICAgIHByaW50KG5vZGUuZ2V0RGVzY3JpcHRpb24oKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBVbmNoZWNrZWRJT0V4Y2VwdGlvbihlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICBwdWJsaWMgVm9pZCB2aXNpdFJlZmVyZW5jZShSZWZlcmVuY2VUcmVlIG5vZGUsIFZvaWQgcCkgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIHByaW50KG5vZGUuZ2V0U2lnbmF0dXJlKCkpOwogICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFVuY2hlY2tlZElPRXhjZXB0aW9uKGUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBWb2lkIHZpc2l0UmV0dXJuKFJldHVyblRyZWUgbm9kZSwgVm9pZCBwKSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgcHJpbnRUYWdOYW1lKG5vZGUpOwogICAgICAgICAgICBwcmludCgiICIpOwogICAgICAgICAgICBwcmludChub2RlLmdldERlc2NyaXB0aW9uKCkpOwogICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFVuY2hlY2tlZElPRXhjZXB0aW9uKGUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBWb2lkIHZpc2l0U2VlKFNlZVRyZWUgbm9kZSwgVm9pZCBwKSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgcHJpbnRUYWdOYW1lKG5vZGUpOwogICAgICAgICAgICBib29sZWFuIGZpcnN0ID0gdHJ1ZTsKICAgICAgICAgICAgYm9vbGVhbiBuZWVkU2VwID0gdHJ1ZTsKICAgICAgICAgICAgZm9yIChEb2NUcmVlIHQ6IG5vZGUuZ2V0UmVmZXJlbmNlKCkpIHsKICAgICAgICAgICAgICAgIGlmIChuZWVkU2VwKSBwcmludCgiICIpOwogICAgICAgICAgICAgICAgbmVlZFNlcCA9IChmaXJzdCAmJiAodCBpbnN0YW5jZW9mIFJlZmVyZW5jZVRyZWUpKTsKICAgICAgICAgICAgICAgIGZpcnN0ID0gZmFsc2U7CiAgICAgICAgICAgICAgICBwcmludCh0KTsKICAgICAgICAgICAgfQogICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFVuY2hlY2tlZElPRXhjZXB0aW9uKGUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBWb2lkIHZpc2l0U2VyaWFsKFNlcmlhbFRyZWUgbm9kZSwgVm9pZCBwKSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgcHJpbnRUYWdOYW1lKG5vZGUpOwogICAgICAgICAgICBpZiAoIW5vZGUuZ2V0RGVzY3JpcHRpb24oKS5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICAgIHByaW50KCIgIik7CiAgICAgICAgICAgICAgICBwcmludChub2RlLmdldERlc2NyaXB0aW9uKCkpOwogICAgICAgICAgICB9CiAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgVW5jaGVja2VkSU9FeGNlcHRpb24oZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIFZvaWQgdmlzaXRTZXJpYWxEYXRhKFNlcmlhbERhdGFUcmVlIG5vZGUsIFZvaWQgcCkgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIHByaW50VGFnTmFtZShub2RlKTsKICAgICAgICAgICAgaWYgKCFub2RlLmdldERlc2NyaXB0aW9uKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgICBwcmludCgiICIpOwogICAgICAgICAgICAgICAgcHJpbnQobm9kZS5nZXREZXNjcmlwdGlvbigpKTsKICAgICAgICAgICAgfQogICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFVuY2hlY2tlZElPRXhjZXB0aW9uKGUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBWb2lkIHZpc2l0U2VyaWFsRmllbGQoU2VyaWFsRmllbGRUcmVlIG5vZGUsIFZvaWQgcCkgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIHByaW50VGFnTmFtZShub2RlKTsKICAgICAgICAgICAgcHJpbnQoIiAiKTsKICAgICAgICAgICAgcHJpbnQobm9kZS5nZXROYW1lKCkpOwogICAgICAgICAgICBwcmludCgiICIpOwogICAgICAgICAgICBwcmludChub2RlLmdldFR5cGUoKSk7CiAgICAgICAgICAgIGlmICghbm9kZS5nZXREZXNjcmlwdGlvbigpLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgICAgcHJpbnQoIiAiKTsKICAgICAgICAgICAgICAgIHByaW50KG5vZGUuZ2V0RGVzY3JpcHRpb24oKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBVbmNoZWNrZWRJT0V4Y2VwdGlvbihlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICBwdWJsaWMgVm9pZCB2aXNpdFNpbmNlKFNpbmNlVHJlZSBub2RlLCBWb2lkIHApIHsKICAgICAgICB0cnkgewogICAgICAgICAgICBwcmludFRhZ05hbWUobm9kZSk7CiAgICAgICAgICAgIHByaW50KCIgIik7CiAgICAgICAgICAgIHByaW50KG5vZGUuZ2V0Qm9keSgpKTsKICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBVbmNoZWNrZWRJT0V4Y2VwdGlvbihlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICBwdWJsaWMgVm9pZCB2aXNpdFN0YXJ0RWxlbWVudChTdGFydEVsZW1lbnRUcmVlIG5vZGUsIFZvaWQgcCkgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIHByaW50KCI8Iik7CiAgICAgICAgICAgIHByaW50KG5vZGUuZ2V0TmFtZSgpKTsKICAgICAgICAgICAgTGlzdDw/IGV4dGVuZHMgRG9jVHJlZT4gYXR0cnMgPSBub2RlLmdldEF0dHJpYnV0ZXMoKTsKICAgICAgICAgICAgaWYgKCFhdHRycy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICAgIHByaW50KCIgIik7CiAgICAgICAgICAgICAgICBwcmludChhdHRycyk7CiAgICAgICAgICAgICAgICBEb2NUcmVlIGxhc3QgPSBub2RlLmdldEF0dHJpYnV0ZXMoKS5nZXQoYXR0cnMuc2l6ZSgpIC0gMSk7CiAgICAgICAgICAgICAgICBpZiAobm9kZS5pc1NlbGZDbG9zaW5nKCkgJiYgbGFzdCBpbnN0YW5jZW9mIEF0dHJpYnV0ZVRyZWUKICAgICAgICAgICAgICAgICAgICAgICAgJiYgKChBdHRyaWJ1dGVUcmVlKSBsYXN0KS5nZXRWYWx1ZUtpbmQoKSA9PSBWYWx1ZUtpbmQuVU5RVU9URUQpCiAgICAgICAgICAgICAgICAgICAgcHJpbnQoIiAiKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAobm9kZS5pc1NlbGZDbG9zaW5nKCkpCiAgICAgICAgICAgICAgICBwcmludCgiLyIpOwogICAgICAgICAgICBwcmludCgiPiIpOwogICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFVuY2hlY2tlZElPRXhjZXB0aW9uKGUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBWb2lkIHZpc2l0VGV4dChUZXh0VHJlZSBub2RlLCBWb2lkIHApIHsKICAgICAgICB0cnkgewogICAgICAgICAgICBwcmludChub2RlLmdldEJvZHkoKSk7CiAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgVW5jaGVja2VkSU9FeGNlcHRpb24oZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIFZvaWQgdmlzaXRUaHJvd3MoVGhyb3dzVHJlZSBub2RlLCBWb2lkIHApIHsKICAgICAgICB0cnkgewogICAgICAgICAgICBwcmludFRhZ05hbWUobm9kZSk7CiAgICAgICAgICAgIHByaW50KCIgIik7CiAgICAgICAgICAgIHByaW50KG5vZGUuZ2V0RXhjZXB0aW9uTmFtZSgpKTsKICAgICAgICAgICAgaWYgKCFub2RlLmdldERlc2NyaXB0aW9uKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgICBwcmludCgiICIpOwogICAgICAgICAgICAgICAgcHJpbnQobm9kZS5nZXREZXNjcmlwdGlvbigpKTsKICAgICAgICAgICAgfQogICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFVuY2hlY2tlZElPRXhjZXB0aW9uKGUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBWb2lkIHZpc2l0VW5rbm93bkJsb2NrVGFnKFVua25vd25CbG9ja1RhZ1RyZWUgbm9kZSwgVm9pZCBwKSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgcHJpbnQoIkAiKTsKICAgICAgICAgICAgcHJpbnQobm9kZS5nZXRUYWdOYW1lKCkpOwogICAgICAgICAgICBwcmludCgiICIpOwogICAgICAgICAgICBwcmludChub2RlLmdldENvbnRlbnQoKSk7CiAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgVW5jaGVja2VkSU9FeGNlcHRpb24oZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIFZvaWQgdmlzaXRVbmtub3duSW5saW5lVGFnKFVua25vd25JbmxpbmVUYWdUcmVlIG5vZGUsIFZvaWQgcCkgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIHByaW50KCJ7Iik7CiAgICAgICAgICAgIHByaW50KCJAIik7CiAgICAgICAgICAgIHByaW50KG5vZGUuZ2V0VGFnTmFtZSgpKTsKICAgICAgICAgICAgcHJpbnQoIiAiKTsKICAgICAgICAgICAgcHJpbnQobm9kZS5nZXRDb250ZW50KCkpOwogICAgICAgICAgICBwcmludCgifSIpOwogICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFVuY2hlY2tlZElPRXhjZXB0aW9uKGUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBWb2lkIHZpc2l0VXNlcyhVc2VzVHJlZSBub2RlLCBWb2lkIHApIHsKICAgICAgICB0cnkgewogICAgICAgICAgICBwcmludFRhZ05hbWUobm9kZSk7CiAgICAgICAgICAgIHByaW50KCIgIik7CiAgICAgICAgICAgIHByaW50KG5vZGUuZ2V0U2VydmljZVR5cGUoKSk7CiAgICAgICAgICAgIGlmICghbm9kZS5nZXREZXNjcmlwdGlvbigpLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgICAgcHJpbnQoIiAiKTsKICAgICAgICAgICAgICAgIHByaW50KG5vZGUuZ2V0RGVzY3JpcHRpb24oKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBVbmNoZWNrZWRJT0V4Y2VwdGlvbihlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICBwdWJsaWMgVm9pZCB2aXNpdFZhbHVlKFZhbHVlVHJlZSBub2RlLCBWb2lkIHApIHsKICAgICAgICB0cnkgewogICAgICAgICAgICBwcmludCgieyIpOwogICAgICAgICAgICBwcmludFRhZ05hbWUobm9kZSk7CiAgICAgICAgICAgIGlmIChub2RlLmdldFJlZmVyZW5jZSgpICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIHByaW50KCIgIik7CiAgICAgICAgICAgICAgICBwcmludChub2RlLmdldFJlZmVyZW5jZSgpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBwcmludCgifSIpOwogICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFVuY2hlY2tlZElPRXhjZXB0aW9uKGUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBWb2lkIHZpc2l0VmVyc2lvbihWZXJzaW9uVHJlZSBub2RlLCBWb2lkIHApIHsKICAgICAgICB0cnkgewogICAgICAgICAgICBwcmludFRhZ05hbWUobm9kZSk7CiAgICAgICAgICAgIHByaW50KCIgIik7CiAgICAgICAgICAgIHByaW50KG5vZGUuZ2V0Qm9keSgpKTsKICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBVbmNoZWNrZWRJT0V4Y2VwdGlvbihlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICBwdWJsaWMgVm9pZCB2aXNpdE90aGVyKERvY1RyZWUgbm9kZSwgVm9pZCBwKSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgcHJpbnQoIihVTktOT1dOOiAiICsgbm9kZSArICIpIik7CiAgICAgICAgICAgIHByaW50bG4oKTsKICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBVbmNoZWNrZWRJT0V4Y2VwdGlvbihlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9Cn0KUEsDBAoAAAgAAAY7qUrRAHupWWcAAFlnAAAqAAAAY29tL3N1bi90b29scy9qYXZhYy90cmVlL0RvY1RyZWVNYWtlci5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDExLCAyMDE2LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuamF2YWMudHJlZTsKCmltcG9ydCBqYXZhLnRleHQuQnJlYWtJdGVyYXRvcjsKaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CmltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbjsKaW1wb3J0IGphdmEudXRpbC5FbnVtU2V0OwppbXBvcnQgamF2YS51dGlsLkxpc3Q7CmltcG9ydCBqYXZhLnV0aWwuTGlzdEl0ZXJhdG9yOwoKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC5OYW1lOwppbXBvcnQgamF2YXgudG9vbHMuRGlhZ25vc3RpYzsKaW1wb3J0IGphdmF4LnRvb2xzLkphdmFGaWxlT2JqZWN0OwoKaW1wb3J0IGNvbS5zdW4uc291cmNlLmRvY3RyZWUuQXR0cmlidXRlVHJlZS5WYWx1ZUtpbmQ7CmltcG9ydCBjb20uc3VuLnNvdXJjZS5kb2N0cmVlLkRvY1RyZWU7CmltcG9ydCBjb20uc3VuLnNvdXJjZS5kb2N0cmVlLkRvY1RyZWUuS2luZDsKaW1wb3J0IGNvbS5zdW4uc291cmNlLmRvY3RyZWUuRW5kRWxlbWVudFRyZWU7CmltcG9ydCBjb20uc3VuLnNvdXJjZS5kb2N0cmVlLklkZW50aWZpZXJUcmVlOwppbXBvcnQgY29tLnN1bi5zb3VyY2UuZG9jdHJlZS5SZWZlcmVuY2VUcmVlOwppbXBvcnQgY29tLnN1bi5zb3VyY2UuZG9jdHJlZS5TdGFydEVsZW1lbnRUcmVlOwppbXBvcnQgY29tLnN1bi5zb3VyY2UuZG9jdHJlZS5UZXh0VHJlZTsKaW1wb3J0IGNvbS5zdW4uc291cmNlLmRvY3RyZWUuUHJvdmlkZXNUcmVlOwppbXBvcnQgY29tLnN1bi5zb3VyY2UuZG9jdHJlZS5Vc2VzVHJlZTsKaW1wb3J0IGNvbS5zdW4uc291cmNlLnV0aWwuRG9jVHJlZUZhY3Rvcnk7CmltcG9ydCBjb20uc3VuLnRvb2xzLmRvY2xpbnQuSHRtbFRhZzsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuYXBpLkphdmFjVHJlZXM7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnBhcnNlci5QYXJzZXJGYWN0b3J5OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5wYXJzZXIuUmVmZXJlbmNlUGFyc2VyOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5wYXJzZXIuVG9rZW5zLkNvbW1lbnQ7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnBhcnNlci5Ub2tlbnMuQ29tbWVudC5Db21tZW50U3R5bGU7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuRENUcmVlLkRDQXR0cmlidXRlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkRDVHJlZS5EQ0F1dGhvcjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5EQ1RyZWUuRENDb21tZW50OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkRDVHJlZS5EQ0RlcHJlY2F0ZWQ7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuRENUcmVlLkRDRG9jQ29tbWVudDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5EQ1RyZWUuRENEb2NSb290OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkRDVHJlZS5EQ0VuZEVsZW1lbnQ7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuRENUcmVlLkRDRW50aXR5OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkRDVHJlZS5EQ0Vycm9uZW91czsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5EQ1RyZWUuRENIaWRkZW47CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuRENUcmVlLkRDSWRlbnRpZmllcjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5EQ1RyZWUuRENJbmRleDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5EQ1RyZWUuRENJbmhlcml0RG9jOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkRDVHJlZS5EQ0xpbms7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuRENUcmVlLkRDTGl0ZXJhbDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5EQ1RyZWUuRENQYXJhbTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5EQ1RyZWUuRENQcm92aWRlczsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5EQ1RyZWUuRENSZWZlcmVuY2U7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuRENUcmVlLkRDUmV0dXJuOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkRDVHJlZS5EQ1NlZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5EQ1RyZWUuRENTZXJpYWw7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuRENUcmVlLkRDU2VyaWFsRGF0YTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5EQ1RyZWUuRENTZXJpYWxGaWVsZDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5EQ1RyZWUuRENTaW5jZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5EQ1RyZWUuRENTdGFydEVsZW1lbnQ7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuRENUcmVlLkRDVGV4dDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5EQ1RyZWUuRENUaHJvd3M7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuRENUcmVlLkRDVW5rbm93bkJsb2NrVGFnOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkRDVHJlZS5EQ1Vua25vd25JbmxpbmVUYWc7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuRENUcmVlLkRDVXNlczsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5EQ1RyZWUuRENWYWx1ZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5EQ1RyZWUuRENWZXJzaW9uOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkNvbnRleHQ7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuRGVmaW5lZEJ5OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkRlZmluZWRCeS5BcGk7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuRGlhZ25vc3RpY1NvdXJjZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5KQ0RpYWdub3N0aWM7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuSkNEaWFnbm9zdGljLkRpYWdub3N0aWNQb3NpdGlvbjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5MaXN0QnVmZmVyOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLlBhaXI7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuUG9zaXRpb247CgppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuZG9jbGludC5IdG1sVGFnLio7CgovKioKICoKICogIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqICBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqICBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogKiAgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPgogKi8KcHVibGljIGNsYXNzIERvY1RyZWVNYWtlciBpbXBsZW1lbnRzIERvY1RyZWVGYWN0b3J5IHsKCiAgICAvKiogVGhlIGNvbnRleHQga2V5IGZvciB0aGUgdHJlZSBmYWN0b3J5LiAqLwogICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBDb250ZXh0LktleTxEb2NUcmVlTWFrZXI+IHRyZWVNYWtlcktleSA9IG5ldyBDb250ZXh0LktleTw+KCk7CgogICAgLy8gQSBzdWJzZXQgb2YgYmxvY2sgdGFncywgd2hpY2ggYWN0cyBhcyBzZW50ZW5jZSBicmVha2VycywgYXBwZWFyaW5nCiAgICAvLyBhbnl3aGVyZSBidXQgdGhlIHplcm8ndGggcG9zaXRpb24gaW4gdGhlIGZpcnN0IHNlbnRlbmNlLgogICAgZmluYWwgRW51bVNldDxIdG1sVGFnPiBzZW50ZW5jZUJyZWFrVGFnczsKCiAgICAvKiogR2V0IHRoZSBUcmVlTWFrZXIgaW5zdGFuY2UuICovCiAgICBwdWJsaWMgc3RhdGljIERvY1RyZWVNYWtlciBpbnN0YW5jZShDb250ZXh0IGNvbnRleHQpIHsKICAgICAgICBEb2NUcmVlTWFrZXIgaW5zdGFuY2UgPSBjb250ZXh0LmdldCh0cmVlTWFrZXJLZXkpOwogICAgICAgIGlmIChpbnN0YW5jZSA9PSBudWxsKQogICAgICAgICAgICBpbnN0YW5jZSA9IG5ldyBEb2NUcmVlTWFrZXIoY29udGV4dCk7CiAgICAgICAgcmV0dXJuIGluc3RhbmNlOwogICAgfQoKICAgIC8qKiBUaGUgcG9zaXRpb24gYXQgd2hpY2ggc3Vic2VxdWVudCB0cmVlcyB3aWxsIGJlIGNyZWF0ZWQuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgcG9zID0gUG9zaXRpb24uTk9QT1M7CgogICAgLyoqIEFjY2VzcyB0byBkaWFnIGZhY3RvcnkgZm9yIEVycm9uZW91c1RyZWVzLiAqLwogICAgcHJpdmF0ZSBmaW5hbCBKQ0RpYWdub3N0aWMuRmFjdG9yeSBkaWFnczsKCiAgICBwcml2YXRlIGZpbmFsIEphdmFjVHJlZXMgdHJlZXM7CgogICAgLyoqIFV0aWxpdHkgY2xhc3MgdG8gcGFyc2UgcmVmZXJlbmNlIHNpZ25hdHVyZXMuICovCiAgICBwcml2YXRlIGZpbmFsIFJlZmVyZW5jZVBhcnNlciByZWZlcmVuY2VQYXJzZXI7CgogICAgLyoqIENyZWF0ZSBhIHRyZWUgbWFrZXIgd2l0aCBOT1BPUyBhcyBpbml0aWFsIHBvc2l0aW9uLgogICAgICovCiAgICBwcm90ZWN0ZWQgRG9jVHJlZU1ha2VyKENvbnRleHQgY29udGV4dCkgewogICAgICAgIGNvbnRleHQucHV0KHRyZWVNYWtlcktleSwgdGhpcyk7CiAgICAgICAgZGlhZ3MgPSBKQ0RpYWdub3N0aWMuRmFjdG9yeS5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICB0aGlzLnBvcyA9IFBvc2l0aW9uLk5PUE9TOwogICAgICAgIHRyZWVzID0gSmF2YWNUcmVlcy5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICByZWZlcmVuY2VQYXJzZXIgPSBuZXcgUmVmZXJlbmNlUGFyc2VyKFBhcnNlckZhY3RvcnkuaW5zdGFuY2UoY29udGV4dCkpOwogICAgICAgIHNlbnRlbmNlQnJlYWtUYWdzID0gRW51bVNldC5vZihIMSwgSDIsIEgzLCBINCwgSDUsIEg2LCBQUkUsIFApOwogICAgfQoKICAgIC8qKiBSZWFzc2lnbiBjdXJyZW50IHBvc2l0aW9uLgogICAgICovCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBEb2NUcmVlTWFrZXIgYXQoaW50IHBvcykgewogICAgICAgIHRoaXMucG9zID0gcG9zOwogICAgICAgIHJldHVybiB0aGlzOwogICAgfQoKICAgIC8qKiBSZWFzc2lnbiBjdXJyZW50IHBvc2l0aW9uLgogICAgICovCiAgICBwdWJsaWMgRG9jVHJlZU1ha2VyIGF0KERpYWdub3N0aWNQb3NpdGlvbiBwb3MpIHsKICAgICAgICB0aGlzLnBvcyA9IChwb3MgPT0gbnVsbCA/IFBvc2l0aW9uLk5PUE9TIDogcG9zLmdldFN0YXJ0UG9zaXRpb24oKSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICBwdWJsaWMgRENBdHRyaWJ1dGUgbmV3QXR0cmlidXRlVHJlZShqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuTmFtZSBuYW1lLCBWYWx1ZUtpbmQgdmtpbmQsIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBEb2NUcmVlPiB2YWx1ZSkgewogICAgICAgIERDQXR0cmlidXRlIHRyZWUgPSBuZXcgRENBdHRyaWJ1dGUobmFtZSwgdmtpbmQsIGNhc3QodmFsdWUpKTsKICAgICAgICB0cmVlLnBvcyA9IHBvczsKICAgICAgICByZXR1cm4gdHJlZTsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBEQ0F1dGhvciBuZXdBdXRob3JUcmVlKGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBEb2NUcmVlPiBuYW1lKSB7CiAgICAgICAgRENBdXRob3IgdHJlZSA9IG5ldyBEQ0F1dGhvcihjYXN0KG5hbWUpKTsKICAgICAgICB0cmVlLnBvcyA9IHBvczsKICAgICAgICByZXR1cm4gdHJlZTsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBEQ0xpdGVyYWwgbmV3Q29kZVRyZWUoVGV4dFRyZWUgdGV4dCkgewogICAgICAgIERDTGl0ZXJhbCB0cmVlID0gbmV3IERDTGl0ZXJhbChLaW5kLkNPREUsIChEQ1RleHQpIHRleHQpOwogICAgICAgIHRyZWUucG9zID0gcG9zOwogICAgICAgIHJldHVybiB0cmVlOwogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIERDQ29tbWVudCBuZXdDb21tZW50VHJlZShTdHJpbmcgdGV4dCkgewogICAgICAgIERDQ29tbWVudCB0cmVlID0gbmV3IERDQ29tbWVudCh0ZXh0KTsKICAgICAgICB0cmVlLnBvcyA9IHBvczsKICAgICAgICByZXR1cm4gdHJlZTsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBEQ0RlcHJlY2F0ZWQgbmV3RGVwcmVjYXRlZFRyZWUoTGlzdDw/IGV4dGVuZHMgRG9jVHJlZT4gdGV4dCkgewogICAgICAgIERDRGVwcmVjYXRlZCB0cmVlID0gbmV3IERDRGVwcmVjYXRlZChjYXN0KHRleHQpKTsKICAgICAgICB0cmVlLnBvcyA9IHBvczsKICAgICAgICByZXR1cm4gdHJlZTsKICAgIH0KCiAgICBwdWJsaWMgRENEb2NDb21tZW50IG5ld0RvY0NvbW1lbnRUcmVlKENvbW1lbnQgY29tbWVudCwgTGlzdDw/IGV4dGVuZHMgRG9jVHJlZT4gZnVsbEJvZHksIExpc3Q8PyBleHRlbmRzIERvY1RyZWU+IHRhZ3MpIHsKICAgICAgICBQYWlyPExpc3Q8RENUcmVlPiwgTGlzdDxEQ1RyZWU+PiBwYWlyID0gc3BsaXRCb2R5KGZ1bGxCb2R5KTsKICAgICAgICBEQ0RvY0NvbW1lbnQgdHJlZSA9IG5ldyBEQ0RvY0NvbW1lbnQoY29tbWVudCwgY2FzdChmdWxsQm9keSksIHBhaXIuZnN0LCBwYWlyLnNuZCwgY2FzdCh0YWdzKSk7CiAgICAgICAgdHJlZS5wb3MgPSBwb3M7CiAgICAgICAgcmV0dXJuIHRyZWU7CiAgICB9CgogICAgLyoKICAgICAqIFByaW1hcmlseSB0byBwcm9kdWNlIGEgRG9jQ29tbWVuVHJlZSB3aGVuIGdpdmVuIGEKICAgICAqIGZpcnN0IHNlbnRlbmNlIGFuZCBhIGJvZHksIHRoaXMgaXMgdXNlZnVsLCBpbiBjYXNlcwogICAgICogd2hlcmUgdGhlIHRyZWVzIGFyZSBiZWluZyBzeW50aGVzaXplZCBieSBhIHRvb2wuCiAgICAgKi8KICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIERDRG9jQ29tbWVudCBuZXdEb2NDb21tZW50VHJlZShMaXN0PD8gZXh0ZW5kcyBEb2NUcmVlPiBmdWxsQm9keSwgTGlzdDw/IGV4dGVuZHMgRG9jVHJlZT4gdGFncykgewogICAgICAgIExpc3RCdWZmZXI8RENUcmVlPiBsYiA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICBsYi5hZGRBbGwoY2FzdChmdWxsQm9keSkpOwogICAgICAgIExpc3Q8RENUcmVlPiBmQm9keSA9IGxiLnRvTGlzdCgpOwoKICAgICAgICAvLyBBIGR1bW15IGNvbW1lbnQgdG8ga2VlcCB0aGUgZGlhZ25vc3RpY3MgbG9naWMgaGFwcHkuCiAgICAgICAgQ29tbWVudCBjID0gbmV3IENvbW1lbnQoKSB7CiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgU3RyaW5nIGdldFRleHQoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHB1YmxpYyBpbnQgZ2V0U291cmNlUG9zKGludCBpbmRleCkgewogICAgICAgICAgICAgICAgcmV0dXJuIFBvc2l0aW9uLk5PUE9TOwogICAgICAgICAgICB9CgogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHVibGljIENvbW1lbnRTdHlsZSBnZXRTdHlsZSgpIHsKICAgICAgICAgICAgICAgIHJldHVybiBDb21tZW50U3R5bGUuSkFWQURPQzsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHB1YmxpYyBib29sZWFuIGlzRGVwcmVjYXRlZCgpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgIH07CiAgICAgICAgUGFpcjxMaXN0PERDVHJlZT4sIExpc3Q8RENUcmVlPj4gcGFpciA9IHNwbGl0Qm9keShmdWxsQm9keSk7CiAgICAgICAgRENEb2NDb21tZW50IHRyZWUgPSBuZXcgRENEb2NDb21tZW50KGMsIGZCb2R5LCBwYWlyLmZzdCwgcGFpci5zbmQsIGNhc3QodGFncykpOwogICAgICAgIHJldHVybiB0cmVlOwogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIERDRG9jUm9vdCBuZXdEb2NSb290VHJlZSgpIHsKICAgICAgICBEQ0RvY1Jvb3QgdHJlZSA9IG5ldyBEQ0RvY1Jvb3QoKTsKICAgICAgICB0cmVlLnBvcyA9IHBvczsKICAgICAgICByZXR1cm4gdHJlZTsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBEQ0VuZEVsZW1lbnQgbmV3RW5kRWxlbWVudFRyZWUoTmFtZSBuYW1lKSB7CiAgICAgICAgRENFbmRFbGVtZW50IHRyZWUgPSBuZXcgRENFbmRFbGVtZW50KG5hbWUpOwogICAgICAgIHRyZWUucG9zID0gcG9zOwogICAgICAgIHJldHVybiB0cmVlOwogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIERDRW50aXR5IG5ld0VudGl0eVRyZWUoTmFtZSBuYW1lKSB7CiAgICAgICAgRENFbnRpdHkgdHJlZSA9IG5ldyBEQ0VudGl0eShuYW1lKTsKICAgICAgICB0cmVlLnBvcyA9IHBvczsKICAgICAgICByZXR1cm4gdHJlZTsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBEQ0Vycm9uZW91cyBuZXdFcnJvbmVvdXNUcmVlKFN0cmluZyB0ZXh0LCBEaWFnbm9zdGljPEphdmFGaWxlT2JqZWN0PiBkaWFnKSB7CiAgICAgICAgRENFcnJvbmVvdXMgdHJlZSA9IG5ldyBEQ0Vycm9uZW91cyh0ZXh0LCAoSkNEaWFnbm9zdGljKSBkaWFnKTsKICAgICAgICB0cmVlLnBvcyA9IHBvczsKICAgICAgICByZXR1cm4gdHJlZTsKICAgIH0KCiAgICBwdWJsaWMgRENFcnJvbmVvdXMgbmV3RXJyb25lb3VzVHJlZShTdHJpbmcgdGV4dCwgRGlhZ25vc3RpY1NvdXJjZSBkaWFnU291cmNlLCBTdHJpbmcgY29kZSwgT2JqZWN0Li4uIGFyZ3MpIHsKICAgICAgICBEQ0Vycm9uZW91cyB0cmVlID0gbmV3IERDRXJyb25lb3VzKHRleHQsIGRpYWdzLCBkaWFnU291cmNlLCBjb2RlLCBhcmdzKTsKICAgICAgICB0cmVlLnBvcyA9IHBvczsKICAgICAgICByZXR1cm4gdHJlZTsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBEQ1Rocm93cyBuZXdFeGNlcHRpb25UcmVlKFJlZmVyZW5jZVRyZWUgbmFtZSwgTGlzdDw/IGV4dGVuZHMgRG9jVHJlZT4gZGVzY3JpcHRpb24pIHsKICAgICAgICAvLyBUT0RPOiB2ZXJpZnkgdGhlIHJlZmVyZW5jZSBpcyBqdXN0IHRvIGEgdHlwZSAobm90IGEgZmllbGQgb3IgbWV0aG9kKQogICAgICAgIERDVGhyb3dzIHRyZWUgPSBuZXcgRENUaHJvd3MoS2luZC5FWENFUFRJT04sIChEQ1JlZmVyZW5jZSkgbmFtZSwgY2FzdChkZXNjcmlwdGlvbikpOwogICAgICAgIHRyZWUucG9zID0gcG9zOwogICAgICAgIHJldHVybiB0cmVlOwogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIERDSGlkZGVuIG5ld0hpZGRlblRyZWUoTGlzdDw/IGV4dGVuZHMgRG9jVHJlZT4gdGV4dCkgewogICAgICAgIERDSGlkZGVuIHRyZWUgPSBuZXcgRENIaWRkZW4oY2FzdCh0ZXh0KSk7CiAgICAgICAgdHJlZS5wb3MgPSBwb3M7CiAgICAgICAgcmV0dXJuIHRyZWU7CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICBwdWJsaWMgRENJZGVudGlmaWVyIG5ld0lkZW50aWZpZXJUcmVlKE5hbWUgbmFtZSkgewogICAgICAgIERDSWRlbnRpZmllciB0cmVlID0gbmV3IERDSWRlbnRpZmllcihuYW1lKTsKICAgICAgICB0cmVlLnBvcyA9IHBvczsKICAgICAgICByZXR1cm4gdHJlZTsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBEQ0luZGV4IG5ld0luZGV4VHJlZShEb2NUcmVlIHRlcm0sIExpc3Q8PyBleHRlbmRzIERvY1RyZWU+IGRlc2NyaXB0aW9uKSB7CiAgICAgICAgRENJbmRleCB0cmVlID0gbmV3IERDSW5kZXgoKERDVHJlZSkgdGVybSwgY2FzdChkZXNjcmlwdGlvbikpOwogICAgICAgIHRyZWUucG9zID0gcG9zOwogICAgICAgIHJldHVybiB0cmVlOwogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIERDSW5oZXJpdERvYyBuZXdJbmhlcml0RG9jVHJlZSgpIHsKICAgICAgICBEQ0luaGVyaXREb2MgdHJlZSA9IG5ldyBEQ0luaGVyaXREb2MoKTsKICAgICAgICB0cmVlLnBvcyA9IHBvczsKICAgICAgICByZXR1cm4gdHJlZTsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBEQ0xpbmsgbmV3TGlua1RyZWUoUmVmZXJlbmNlVHJlZSByZWYsIExpc3Q8PyBleHRlbmRzIERvY1RyZWU+IGxhYmVsKSB7CiAgICAgICAgRENMaW5rIHRyZWUgPSBuZXcgRENMaW5rKEtpbmQuTElOSywgKERDUmVmZXJlbmNlKSByZWYsIGNhc3QobGFiZWwpKTsKICAgICAgICB0cmVlLnBvcyA9IHBvczsKICAgICAgICByZXR1cm4gdHJlZTsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBEQ0xpbmsgbmV3TGlua1BsYWluVHJlZShSZWZlcmVuY2VUcmVlIHJlZiwgTGlzdDw/IGV4dGVuZHMgRG9jVHJlZT4gbGFiZWwpIHsKICAgICAgICBEQ0xpbmsgdHJlZSA9IG5ldyBEQ0xpbmsoS2luZC5MSU5LX1BMQUlOLCAoRENSZWZlcmVuY2UpIHJlZiwgY2FzdChsYWJlbCkpOwogICAgICAgIHRyZWUucG9zID0gcG9zOwogICAgICAgIHJldHVybiB0cmVlOwogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIERDTGl0ZXJhbCBuZXdMaXRlcmFsVHJlZShUZXh0VHJlZSB0ZXh0KSB7CiAgICAgICAgRENMaXRlcmFsIHRyZWUgPSBuZXcgRENMaXRlcmFsKEtpbmQuTElURVJBTCwgKERDVGV4dCkgdGV4dCk7CiAgICAgICAgdHJlZS5wb3MgPSBwb3M7CiAgICAgICAgcmV0dXJuIHRyZWU7CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICBwdWJsaWMgRENQYXJhbSBuZXdQYXJhbVRyZWUoYm9vbGVhbiBpc1R5cGVQYXJhbWV0ZXIsIElkZW50aWZpZXJUcmVlIG5hbWUsIExpc3Q8PyBleHRlbmRzIERvY1RyZWU+IGRlc2NyaXB0aW9uKSB7CiAgICAgICAgRENQYXJhbSB0cmVlID0gbmV3IERDUGFyYW0oaXNUeXBlUGFyYW1ldGVyLCAoRENJZGVudGlmaWVyKSBuYW1lLCBjYXN0KGRlc2NyaXB0aW9uKSk7CiAgICAgICAgdHJlZS5wb3MgPSBwb3M7CiAgICAgICAgcmV0dXJuIHRyZWU7CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICBwdWJsaWMgRENQcm92aWRlcyBuZXdQcm92aWRlc1RyZWUoUmVmZXJlbmNlVHJlZSBuYW1lLCBMaXN0PD8gZXh0ZW5kcyBEb2NUcmVlPiBkZXNjcmlwdGlvbikgewogICAgICAgIERDUHJvdmlkZXMgdHJlZSA9IG5ldyBEQ1Byb3ZpZGVzKChEQ1JlZmVyZW5jZSkgbmFtZSwgY2FzdChkZXNjcmlwdGlvbikpOwogICAgICAgIHRyZWUucG9zID0gcG9zOwogICAgICAgIHJldHVybiB0cmVlOwogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIERDUmVmZXJlbmNlIG5ld1JlZmVyZW5jZVRyZWUoU3RyaW5nIHNpZ25hdHVyZSkgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIFJlZmVyZW5jZVBhcnNlci5SZWZlcmVuY2UgcmVmID0gcmVmZXJlbmNlUGFyc2VyLnBhcnNlKHNpZ25hdHVyZSk7CiAgICAgICAgICAgIERDUmVmZXJlbmNlIHRyZWUgPSBuZXcgRENSZWZlcmVuY2Uoc2lnbmF0dXJlLCByZWYucXVhbEV4cHIsIHJlZi5tZW1iZXIsIHJlZi5wYXJhbVR5cGVzKTsKICAgICAgICAgICAgdHJlZS5wb3MgPSBwb3M7CiAgICAgICAgICAgIHJldHVybiB0cmVlOwogICAgICAgIH0gY2F0Y2ggKFJlZmVyZW5jZVBhcnNlci5QYXJzZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oImludmFsaWQgc2lnbmF0dXJlIiwgZSk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBEQ1JlZmVyZW5jZSBuZXdSZWZlcmVuY2VUcmVlKFN0cmluZyBzaWduYXR1cmUsIEpDVHJlZSBxdWFsRXhwciwgTmFtZSBtZW1iZXIsIExpc3Q8SkNUcmVlPiBwYXJhbVR5cGVzKSB7CiAgICAgICAgRENSZWZlcmVuY2UgdHJlZSA9IG5ldyBEQ1JlZmVyZW5jZShzaWduYXR1cmUsIHF1YWxFeHByLCBtZW1iZXIsIHBhcmFtVHlwZXMpOwogICAgICAgIHRyZWUucG9zID0gcG9zOwogICAgICAgIHJldHVybiB0cmVlOwogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIERDUmV0dXJuIG5ld1JldHVyblRyZWUoTGlzdDw/IGV4dGVuZHMgRG9jVHJlZT4gZGVzY3JpcHRpb24pIHsKICAgICAgICBEQ1JldHVybiB0cmVlID0gbmV3IERDUmV0dXJuKGNhc3QoZGVzY3JpcHRpb24pKTsKICAgICAgICB0cmVlLnBvcyA9IHBvczsKICAgICAgICByZXR1cm4gdHJlZTsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBEQ1NlZSBuZXdTZWVUcmVlKExpc3Q8PyBleHRlbmRzIERvY1RyZWU+IHJlZmVyZW5jZSkgewogICAgICAgIERDU2VlIHRyZWUgPSBuZXcgRENTZWUoY2FzdChyZWZlcmVuY2UpKTsKICAgICAgICB0cmVlLnBvcyA9IHBvczsKICAgICAgICByZXR1cm4gdHJlZTsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBEQ1NlcmlhbCBuZXdTZXJpYWxUcmVlKExpc3Q8PyBleHRlbmRzIERvY1RyZWU+IGRlc2NyaXB0aW9uKSB7CiAgICAgICAgRENTZXJpYWwgdHJlZSA9IG5ldyBEQ1NlcmlhbChjYXN0KGRlc2NyaXB0aW9uKSk7CiAgICAgICAgdHJlZS5wb3MgPSBwb3M7CiAgICAgICAgcmV0dXJuIHRyZWU7CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICBwdWJsaWMgRENTZXJpYWxEYXRhIG5ld1NlcmlhbERhdGFUcmVlKExpc3Q8PyBleHRlbmRzIERvY1RyZWU+IGRlc2NyaXB0aW9uKSB7CiAgICAgICAgRENTZXJpYWxEYXRhIHRyZWUgPSBuZXcgRENTZXJpYWxEYXRhKGNhc3QoZGVzY3JpcHRpb24pKTsKICAgICAgICB0cmVlLnBvcyA9IHBvczsKICAgICAgICByZXR1cm4gdHJlZTsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBEQ1NlcmlhbEZpZWxkIG5ld1NlcmlhbEZpZWxkVHJlZShJZGVudGlmaWVyVHJlZSBuYW1lLCBSZWZlcmVuY2VUcmVlIHR5cGUsIExpc3Q8PyBleHRlbmRzIERvY1RyZWU+IGRlc2NyaXB0aW9uKSB7CiAgICAgICAgRENTZXJpYWxGaWVsZCB0cmVlID0gbmV3IERDU2VyaWFsRmllbGQoKERDSWRlbnRpZmllcikgbmFtZSwgKERDUmVmZXJlbmNlKSB0eXBlLCBjYXN0KGRlc2NyaXB0aW9uKSk7CiAgICAgICAgdHJlZS5wb3MgPSBwb3M7CiAgICAgICAgcmV0dXJuIHRyZWU7CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICBwdWJsaWMgRENTaW5jZSBuZXdTaW5jZVRyZWUoTGlzdDw/IGV4dGVuZHMgRG9jVHJlZT4gdGV4dCkgewogICAgICAgIERDU2luY2UgdHJlZSA9IG5ldyBEQ1NpbmNlKGNhc3QodGV4dCkpOwogICAgICAgIHRyZWUucG9zID0gcG9zOwogICAgICAgIHJldHVybiB0cmVlOwogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIERDU3RhcnRFbGVtZW50IG5ld1N0YXJ0RWxlbWVudFRyZWUoTmFtZSBuYW1lLCBMaXN0PD8gZXh0ZW5kcyBEb2NUcmVlPiBhdHRycywgYm9vbGVhbiBzZWxmQ2xvc2luZykgewogICAgICAgIERDU3RhcnRFbGVtZW50IHRyZWUgPSBuZXcgRENTdGFydEVsZW1lbnQobmFtZSwgY2FzdChhdHRycyksIHNlbGZDbG9zaW5nKTsKICAgICAgICB0cmVlLnBvcyA9IHBvczsKICAgICAgICByZXR1cm4gdHJlZTsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBEQ1RleHQgbmV3VGV4dFRyZWUoU3RyaW5nIHRleHQpIHsKICAgICAgICBEQ1RleHQgdHJlZSA9IG5ldyBEQ1RleHQodGV4dCk7CiAgICAgICAgdHJlZS5wb3MgPSBwb3M7CiAgICAgICAgcmV0dXJuIHRyZWU7CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICBwdWJsaWMgRENUaHJvd3MgbmV3VGhyb3dzVHJlZShSZWZlcmVuY2VUcmVlIG5hbWUsIExpc3Q8PyBleHRlbmRzIERvY1RyZWU+IGRlc2NyaXB0aW9uKSB7CiAgICAgICAgLy8gVE9ETzogdmVyaWZ5IHRoZSByZWZlcmVuY2UgaXMganVzdCB0byBhIHR5cGUgKG5vdCBhIGZpZWxkIG9yIG1ldGhvZCkKICAgICAgICBEQ1Rocm93cyB0cmVlID0gbmV3IERDVGhyb3dzKEtpbmQuVEhST1dTLCAoRENSZWZlcmVuY2UpIG5hbWUsIGNhc3QoZGVzY3JpcHRpb24pKTsKICAgICAgICB0cmVlLnBvcyA9IHBvczsKICAgICAgICByZXR1cm4gdHJlZTsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBEQ1Vua25vd25CbG9ja1RhZyBuZXdVbmtub3duQmxvY2tUYWdUcmVlKE5hbWUgbmFtZSwgTGlzdDw/IGV4dGVuZHMgRG9jVHJlZT4gY29udGVudCkgewogICAgICAgIERDVW5rbm93bkJsb2NrVGFnIHRyZWUgPSBuZXcgRENVbmtub3duQmxvY2tUYWcobmFtZSwgY2FzdChjb250ZW50KSk7CiAgICAgICAgdHJlZS5wb3MgPSBwb3M7CiAgICAgICAgcmV0dXJuIHRyZWU7CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICBwdWJsaWMgRENVbmtub3duSW5saW5lVGFnIG5ld1Vua25vd25JbmxpbmVUYWdUcmVlKE5hbWUgbmFtZSwgTGlzdDw/IGV4dGVuZHMgRG9jVHJlZT4gY29udGVudCkgewogICAgICAgIERDVW5rbm93bklubGluZVRhZyB0cmVlID0gbmV3IERDVW5rbm93bklubGluZVRhZyhuYW1lLCBjYXN0KGNvbnRlbnQpKTsKICAgICAgICB0cmVlLnBvcyA9IHBvczsKICAgICAgICByZXR1cm4gdHJlZTsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBEQ1VzZXMgbmV3VXNlc1RyZWUoUmVmZXJlbmNlVHJlZSBuYW1lLCBMaXN0PD8gZXh0ZW5kcyBEb2NUcmVlPiBkZXNjcmlwdGlvbikgewogICAgICAgIERDVXNlcyB0cmVlID0gbmV3IERDVXNlcygoRENSZWZlcmVuY2UpIG5hbWUsIGNhc3QoZGVzY3JpcHRpb24pKTsKICAgICAgICB0cmVlLnBvcyA9IHBvczsKICAgICAgICByZXR1cm4gdHJlZTsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBEQ1ZhbHVlIG5ld1ZhbHVlVHJlZShSZWZlcmVuY2VUcmVlIHJlZikgewogICAgICAgIC8vIFRPRE86IHZlcmlmeSB0aGUgcmVmZXJlbmNlIGlzIHRvIGEgY29uc3RhbnQgdmFsdWUKICAgICAgICBEQ1ZhbHVlIHRyZWUgPSBuZXcgRENWYWx1ZSgoRENSZWZlcmVuY2UpIHJlZik7CiAgICAgICAgdHJlZS5wb3MgPSBwb3M7CiAgICAgICAgcmV0dXJuIHRyZWU7CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICBwdWJsaWMgRENWZXJzaW9uIG5ld1ZlcnNpb25UcmVlKExpc3Q8PyBleHRlbmRzIERvY1RyZWU+IHRleHQpIHsKICAgICAgICBEQ1ZlcnNpb24gdHJlZSA9IG5ldyBEQ1ZlcnNpb24oY2FzdCh0ZXh0KSk7CiAgICAgICAgdHJlZS5wb3MgPSBwb3M7CiAgICAgICAgcmV0dXJuIHRyZWU7CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8RG9jVHJlZT4gZ2V0Rmlyc3RTZW50ZW5jZShqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgRG9jVHJlZT4gbGlzdCkgewogICAgICAgIFBhaXI8TGlzdDxEQ1RyZWU+LCBMaXN0PERDVHJlZT4+IHBhaXIgPSBzcGxpdEJvZHkobGlzdCk7CiAgICAgICAgcmV0dXJuIG5ldyBBcnJheUxpc3Q8PihwYWlyLmZzdCk7CiAgICB9CgogICAgLyoKICAgICAqIEJyZWFrcyB1cCB0aGUgYm9keSB0YWdzIGludG8gdGhlIGZpcnN0IHNlbnRlbmNlIGFuZCBpdHMgc3VjY2Vzc29ycy4KICAgICAqIFRoZSBmaXJzdCBzZW50ZW5jZSBpcyBkZXRlcm1pbmVkIHdpdGggdGhlIHByZXNlbmNlIG9mIGEgcGVyaW9kLAogICAgICogYmxvY2sgdGFnLCBvciBhIHNlbnRlbmNlIGJyZWFrLCBhcyByZXR1cm5lZCBieSB0aGUgQnJlYWtJdGVyYXRvci4KICAgICAqIFRyYWlsaW5nIHdoaXRlc3BhY2VzIGFyZSB0cmltbWVkLgogICAgICovCiAgICBwcml2YXRlIFBhaXI8TGlzdDxEQ1RyZWU+LCBMaXN0PERDVHJlZT4+IHNwbGl0Qm9keShDb2xsZWN0aW9uPD8gZXh0ZW5kcyBEb2NUcmVlPiBsaXN0KSB7CiAgICAgICAgLy8gcG9zIGlzIG1vZGlmaWVkIGFzIHdlIGNyZWF0ZSB0cmVlcywgdGhlcmVmb3JlCiAgICAgICAgLy8gd2Ugc2F2ZSB0aGUgcG9zIGFuZCByZXN0b3JlIGl0IGxhdGVyLgogICAgICAgIGZpbmFsIGludCBzYXZlZHBvcyA9IHRoaXMucG9zOwogICAgICAgIHRyeSB7CiAgICAgICAgICAgIExpc3RCdWZmZXI8RENUcmVlPiBib2R5ID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgICAgICAvLyBzcGxpdCBib2R5IGludG8gZmlyc3Qgc2VudGVuY2UgYW5kIGJvZHkKICAgICAgICAgICAgTGlzdEJ1ZmZlcjxEQ1RyZWU+IGZzID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgICAgICBpZiAobGlzdC5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICAgIHJldHVybiBuZXcgUGFpcjw+KGZzLnRvTGlzdCgpLCBib2R5LnRvTGlzdCgpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBib29sZWFuIGZvdW5kRmlyc3RTZW50ZW5jZSA9IGZhbHNlOwogICAgICAgICAgICBBcnJheUxpc3Q8RG9jVHJlZT4gYWxpc3QgPSBuZXcgQXJyYXlMaXN0PD4obGlzdCk7CiAgICAgICAgICAgIExpc3RJdGVyYXRvcjxEb2NUcmVlPiBpdHIgPSBhbGlzdC5saXN0SXRlcmF0b3IoKTsKICAgICAgICAgICAgd2hpbGUgKGl0ci5oYXNOZXh0KCkpIHsKICAgICAgICAgICAgICAgIGJvb2xlYW4gaXNGaXJzdCA9ICFpdHIuaGFzUHJldmlvdXMoKTsKICAgICAgICAgICAgICAgIERvY1RyZWUgZHQgPSBpdHIubmV4dCgpOwogICAgICAgICAgICAgICAgaW50IHNwb3MgPSAoKERDVHJlZSkgZHQpLnBvczsKICAgICAgICAgICAgICAgIGlmIChmb3VuZEZpcnN0U2VudGVuY2UpIHsKICAgICAgICAgICAgICAgICAgICBib2R5LmFkZCgoRENUcmVlKSBkdCk7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBzd2l0Y2ggKGR0LmdldEtpbmQoKSkgewogICAgICAgICAgICAgICAgICAgIGNhc2UgVEVYVDoKICAgICAgICAgICAgICAgICAgICAgICAgRENUZXh0IHR0ID0gKERDVGV4dCkgZHQ7CiAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBzID0gdHQuZ2V0Qm9keSgpOwogICAgICAgICAgICAgICAgICAgICAgICBEb2NUcmVlIHBlZWtlZE5leHQgPSBpdHIuaGFzTmV4dCgpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBhbGlzdC5nZXQoaXRyLm5leHRJbmRleCgpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogbnVsbDsKICAgICAgICAgICAgICAgICAgICAgICAgaW50IHNicmVhayA9IGdldFNlbnRlbmNlQnJlYWsocywgcGVla2VkTmV4dCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzYnJlYWsgPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzID0gcmVtb3ZlVHJhaWxpbmdXaGl0ZXNwYWNlKHMuc3Vic3RyaW5nKDAsIHNicmVhaykpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgRENUZXh0IHRleHQgPSB0aGlzLmF0KHNwb3MpLm5ld1RleHRUcmVlKHMpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZnMuYWRkKHRleHQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZm91bmRGaXJzdFNlbnRlbmNlID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBud1BvcyA9IHNraXBXaGl0ZVNwYWNlKHR0LmdldEJvZHkoKSwgc2JyZWFrKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChud1BvcyA+IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEQ1RleHQgdGV4dDIgPSB0aGlzLmF0KHNwb3MgKyBud1BvcykubmV3VGV4dFRyZWUodHQuZ2V0Qm9keSgpLnN1YnN0cmluZyhud1BvcykpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvZHkuYWRkKHRleHQyKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGl0ci5oYXNOZXh0KCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGlmIHRoZSBuZXh0IGRvY3RyZWUgaXMgYSBicmVhaywgcmVtb3ZlIHRyYWlsaW5nIHNwYWNlcwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcGVla2VkTmV4dCA9IGFsaXN0LmdldChpdHIubmV4dEluZGV4KCkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBzYnJrID0gaXNTZW50ZW5jZUJyZWFrKHBlZWtlZE5leHQsIGZhbHNlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzYnJrKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRG9jVHJlZSBuZXh0ID0gaXRyLm5leHQoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzID0gcmVtb3ZlVHJhaWxpbmdXaGl0ZXNwYWNlKHMpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERDVGV4dCB0ZXh0ID0gdGhpcy5hdChzcG9zKS5uZXdUZXh0VHJlZShzKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcy5hZGQodGV4dCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9keS5hZGQoKERDVHJlZSkgbmV4dCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm91bmRGaXJzdFNlbnRlbmNlID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNTZW50ZW5jZUJyZWFrKGR0LCBpc0ZpcnN0KSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9keS5hZGQoKERDVHJlZSkgZHQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZm91bmRGaXJzdFNlbnRlbmNlID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZnMuYWRkKChEQ1RyZWUpIGR0KTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gbmV3IFBhaXI8Pihmcy50b0xpc3QoKSwgYm9keS50b0xpc3QoKSk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgdGhpcy5wb3MgPSBzYXZlZHBvczsKICAgICAgICB9CiAgICB9CgogICAgcHJpdmF0ZSBib29sZWFuIGlzVGV4dFRyZWUoRG9jVHJlZSB0cmVlKSB7CiAgICAgICAgcmV0dXJuIHRyZWUuZ2V0S2luZCgpID09IEtpbmQuVEVYVDsKICAgIH0KCiAgICAvKgogICAgICogQ29tcHV0ZXMgdGhlIGZpcnN0IHNlbnRlbmNlIGJyZWFrLCBhIHNpbXBsZSBkb3Qtc3BhY2UgYWxnb3JpdGhtLgogICAgICovCiAgICBwcml2YXRlIGludCBkZWZhdWx0U2VudGVuY2VCcmVhayhTdHJpbmcgcykgewogICAgICAgIC8vIHNjYW4gZm9yIHBlcmlvZCBmb2xsb3dlZCBieSB3aGl0ZXNwYWNlCiAgICAgICAgaW50IHBlcmlvZCA9IC0xOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcy5sZW5ndGgoKTsgaSsrKSB7CiAgICAgICAgICAgIHN3aXRjaCAocy5jaGFyQXQoaSkpIHsKICAgICAgICAgICAgICAgIGNhc2UgJy4nOgogICAgICAgICAgICAgICAgICAgIHBlcmlvZCA9IGk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSAnICc6CiAgICAgICAgICAgICAgICBjYXNlICdcZic6CiAgICAgICAgICAgICAgICBjYXNlICdcbic6CiAgICAgICAgICAgICAgICBjYXNlICdccic6CiAgICAgICAgICAgICAgICBjYXNlICdcdCc6CiAgICAgICAgICAgICAgICAgICAgaWYgKHBlcmlvZCA+PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgIHBlcmlvZCA9IC0xOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiAtMTsKICAgIH0KCiAgICAvKgogICAgICogQ29tcHV0ZXMgdGhlIGZpcnN0IHNlbnRlbmNlLCBpZiB1c2luZyBhIGRlZmF1bHQgYnJlYWtlciwKICAgICAqIHRoZSBicmVhayBpcyByZXR1cm5lZCwgaWYgbm90IHRoZW4gYSAtMSwgaW5kaWNhdGluZyB0aGF0CiAgICAgKiBtb3JlIGRvY3RyZWUgZWxlbWVudHMgYXJlIHJlcXVpcmVkIHRvIGJlIGV4YW1pbmVkLgogICAgICoKICAgICAqIEJyZWFrSXRlcmF0b3IubmV4dCBwb2ludHMgdG8gdGhlIHRoZSBzdGFydCBvZiB0aGUgZm9sbG93aW5nIHNlbnRlbmNlLAogICAgICogYW5kIGRvZXMgbm90IHByb3ZpZGUgYW4gZWFzeSB3YXkgdG8gZGlzYW1iaWd1YXRlIGJldHdlZW4gInNlbnRlbmNlIGJyZWFrIiwKICAgICAqICJwb3NzaWJsZSBzZW50ZW5jZSBicmVhayIgYW5kICJub3QgYSBzZW50ZW5jZSBicmVhayIgYXQgdGhlIGVuZCBvZiB0aGUgaW5wdXQuCiAgICAgKiBGb3IgZXhhbXBsZSwgQnJlYWtJdGVyYXRvci5uZXh0IHJldHVybnMgdGhlIGluZGV4IGZvciB0aGUgZW5kCiAgICAgKiBvZiB0aGUgc3RyaW5nIGZvciBhbGwgb2YgdGhlc2UgZXhhbXBsZXMsCiAgICAgKiB1c2luZyB2ZXJ0aWNhbCBiYXJzIHRvIGRlbGltaXQgdGhlIGJvdW5kcyBvZiB0aGUgZXhhbXBsZSB0ZXh0CiAgICAgKiB8QWJjfCAgICAgICAgKG5vdCBhIHZhbGlkIGVuZCBvZiBzZW50ZW5jZSBicmVhaywgaWYgZm9sbG93ZWQgYnkgbW9yZSB0ZXh0KQogICAgICogfEFiYy58ICAgICAgIChtYXliZSBhIHZhbGlkIGVuZCBvZiBzZW50ZW5jZSBicmVhaywgZGVwZW5kaW5nIG9uIHRoZSBmb2xsb3dpbmcgdGV4dCkKICAgICAqIHxBYmMuIHwgICAgICAobWF5YmUgYSB2YWxpZCBlbmQgb2Ygc2VudGVuY2UgYnJlYWssIGRlcGVuZGluZyBvbiB0aGUgZm9sbG93aW5nIHRleHQpCiAgICAgKiB8IkFiYy4iIHwgICAgKG1heWJlIGEgdmFsaWQgZW5kIG9mIHNlbnRlbmNlIGJyZWFrLCBkZXBlbmRpbmcgb24gdGhlIGZvbGxvd2luZyB0ZXh0KQogICAgICogfEFiYy4gIHwgICAgIChkZWZpbml0ZWx5IGEgdmFsaWQgZW5kIG9mIHNlbnRlbmNlIGJyZWFrKQogICAgICogfCJBYmMuIiAgfCAgIChkZWZpbml0ZWx5IGEgdmFsaWQgZW5kIG9mIHNlbnRlbmNlIGJyZWFrKQogICAgICogVGhlcmVmb3JlLCB3ZSBoYXZlIHRvIHByb2JlIGZ1cnRoZXIgdG8gZGV0ZXJtaW5lIHdoZXRoZXIKICAgICAqIHRoZXJlIHJlYWxseSBpcyBhIHNlbnRlbmNlIGJyZWFrIG9yIG5vdCBhdCB0aGUgZW5kIG9mIHRoaXMgcnVuIG9mIHRleHQuCiAgICAgKi8KICAgIHByaXZhdGUgaW50IGdldFNlbnRlbmNlQnJlYWsoU3RyaW5nIHMsIERvY1RyZWUgZHQpIHsKICAgICAgICBCcmVha0l0ZXJhdG9yIGJyZWFrSXRlcmF0b3IgPSB0cmVlcy5nZXRCcmVha0l0ZXJhdG9yKCk7CiAgICAgICAgaWYgKGJyZWFrSXRlcmF0b3IgPT0gbnVsbCkgewogICAgICAgICAgICByZXR1cm4gZGVmYXVsdFNlbnRlbmNlQnJlYWsocyk7CiAgICAgICAgfQogICAgICAgIGJyZWFrSXRlcmF0b3Iuc2V0VGV4dChzKTsKICAgICAgICBmaW5hbCBpbnQgc2JyayA9IGJyZWFrSXRlcmF0b3IubmV4dCgpOwogICAgICAgIC8vIFRoaXMgaXMgdGhlIGxhc3QgZG9jdHJlZSwgZm91bmQgdGhlIGRyb2lkIHdlIGFyZSBsb29raW5nIGZvcgogICAgICAgIGlmIChkdCA9PSBudWxsKSB7CiAgICAgICAgICAgIHJldHVybiBzYnJrOwogICAgICAgIH0KCiAgICAgICAgLy8gSWYgdGhlIGJyZWFrIGlzIHdlbGwgd2l0aGluIHRoZSBzcGFuIG9mIHRoZSBzdHJpbmcgaWUuIG5vdAogICAgICAgIC8vIGF0IEVPTCwgdGhlbiB3ZSBoYXZlIGEgY2xlYXIgYnJlYWsuCiAgICAgICAgaWYgKHNicmsgPCBzLmxlbmd0aCgpIC0gMSkgewogICAgICAgICAgICByZXR1cm4gc2JyazsKICAgICAgICB9CgogICAgICAgIGlmIChpc1RleHRUcmVlKGR0KSkgewogICAgICAgICAgICAvLyBUd28gYWRqYWNlbnQgdGV4dCB0cmVlcywgYSBjb3JuZXIgY2FzZSwgcGVyaGFwcwogICAgICAgICAgICAvLyBwcm9kdWNlZCBieSBhIHRvb2wgc3ludGhlc2l6aW5nIGEgZG9jdHJlZS4gSW4KICAgICAgICAgICAgLy8gdGhpcyBjYXNlLCBkb2VzIHRoZSBicmVhayBsaWUgd2l0aGluIHRoZSBmaXJzdCBzcGFuLAogICAgICAgICAgICAvLyB0aGVuIHdlIGhhdmUgdGhlIGRyb2lkLCBvdGhlcndpc2UgYWxsb3cgdGhlIGNhbGxlcnMKICAgICAgICAgICAgLy8gbG9naWMgdG8gaGFuZGxlIHRoZSBicmVhayBpbiB0aGUgYWRqYWNlbnQgZG9jdHJlZS4KICAgICAgICAgICAgVGV4dFRyZWUgdHRuZXh0ID0gKFRleHRUcmVlKSBkdDsKICAgICAgICAgICAgU3RyaW5nIGNvbWJpbmVkID0gcyArIHR0bmV4dC5nZXRCb2R5KCk7CiAgICAgICAgICAgIGJyZWFrSXRlcmF0b3Iuc2V0VGV4dChjb21iaW5lZCk7CiAgICAgICAgICAgIGludCBzYnJrMiA9IGJyZWFrSXRlcmF0b3IubmV4dCgpOwogICAgICAgICAgICBpZiAoc2JyayA8IHNicmsyKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gc2JyazsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gSXMgdGhlIGFkamFjZW50IHRyZWUgYSBzZW50ZW5jZSBicmVha2VyID8KICAgICAgICBpZiAoaXNTZW50ZW5jZUJyZWFrKGR0LCBmYWxzZSkpIHsKICAgICAgICAgICAgcmV0dXJuIHNicms7CiAgICAgICAgfQoKICAgICAgICAvLyBBdCB0aGlzIHBvaW50IHRoZSBhZGphY2VudCB0cmVlIGlzIGVpdGhlciBhIGphdmFkb2MgdGFnICh7QC4uKSwKICAgICAgICAvLyBodG1sIHRhZyAoPC4uKSBvciBhbiBlbnRpdHkgKCYuLikuIFBlcmZvcm0gYSBsaXRtdXMgdGVzdCwgYnkKICAgICAgICAvLyBjb25jYXRlbmF0aW5nIGEgc2VudGVuY2UsIHRvIHZhbGlkYXRlIHRoZSBicmVhayBlYXJsaWVyIGlkZW50aWZpZWQuCiAgICAgICAgU3RyaW5nIGNvbWJpbmVkID0gcyArICJEdW1teSBTZW50ZW5jZS4iOwogICAgICAgIGJyZWFrSXRlcmF0b3Iuc2V0VGV4dChjb21iaW5lZCk7CiAgICAgICAgaW50IHNicmsyID0gYnJlYWtJdGVyYXRvci5uZXh0KCk7CiAgICAgICAgaWYgKHNicmsyIDw9IHNicmspIHsKICAgICAgICAgICAgcmV0dXJuIHNicmsyOwogICAgICAgIH0KICAgICAgICByZXR1cm4gLTE7IC8vIGluZGV0ZXJtaW5hdGUgYXQgdGhpcyB0aW1lCiAgICB9CgogICAgcHJpdmF0ZSBib29sZWFuIGlzU2VudGVuY2VCcmVhayhqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuTmFtZSB0YWdOYW1lKSB7CiAgICAgICAgcmV0dXJuIHNlbnRlbmNlQnJlYWtUYWdzLmNvbnRhaW5zKGdldCh0YWdOYW1lKSk7CiAgICB9CgogICAgcHJpdmF0ZSBib29sZWFuIGlzU2VudGVuY2VCcmVhayhEb2NUcmVlIGR0LCBib29sZWFuIGlzRmlyc3REb2NUcmVlKSB7CiAgICAgICAgc3dpdGNoIChkdC5nZXRLaW5kKCkpIHsKICAgICAgICAgICAgY2FzZSBTVEFSVF9FTEVNRU5UOgogICAgICAgICAgICAgICAgICAgIFN0YXJ0RWxlbWVudFRyZWUgc2V0ID0gKFN0YXJ0RWxlbWVudFRyZWUpZHQ7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICFpc0ZpcnN0RG9jVHJlZSAmJiAoKERDVHJlZSkgZHQpLnBvcyA+IDEgJiYgaXNTZW50ZW5jZUJyZWFrKHNldC5nZXROYW1lKCkpOwogICAgICAgICAgICBjYXNlIEVORF9FTEVNRU5UOgogICAgICAgICAgICAgICAgICAgIEVuZEVsZW1lbnRUcmVlIGVldCA9IChFbmRFbGVtZW50VHJlZSlkdDsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gIWlzRmlyc3REb2NUcmVlICYmICgoRENUcmVlKSBkdCkucG9zID4gMSAmJiBpc1NlbnRlbmNlQnJlYWsoZWV0LmdldE5hbWUoKSk7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgfQoKICAgIC8qCiAgICAgKiBSZXR1cm5zIHRoZSBwb3NpdGlvbiBvZiB0aGUgdGhlIGZpcnN0IG5vbi13aGl0ZSBzcGFjZQogICAgICovCiAgICBwcml2YXRlIGludCBza2lwV2hpdGVTcGFjZShTdHJpbmcgcywgaW50IHN0YXJ0KSB7CiAgICAgICAgZm9yIChpbnQgaSA9IHN0YXJ0OyBpIDwgcy5sZW5ndGgoKTsgaSsrKSB7CiAgICAgICAgICAgIGNoYXIgYyA9IHMuY2hhckF0KGkpOwogICAgICAgICAgICBpZiAoIUNoYXJhY3Rlci5pc1doaXRlc3BhY2UoYykpIHsKICAgICAgICAgICAgICAgIHJldHVybiBpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiAtMTsKICAgIH0KCiAgICBwcml2YXRlIFN0cmluZyByZW1vdmVUcmFpbGluZ1doaXRlc3BhY2UoU3RyaW5nIHMpIHsKICAgICAgICBmb3IgKGludCBpID0gcy5sZW5ndGgoKSAtIDEgOyBpID49IDAgOyBpLS0pIHsKICAgICAgICAgICAgY2hhciBjaCA9IHMuY2hhckF0KGkpOwogICAgICAgICAgICBpZiAoIUNoYXJhY3Rlci5pc1doaXRlc3BhY2UoY2gpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gcy5zdWJzdHJpbmcoMCwgaSArIDEpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgfQoKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQogICAgcHJpdmF0ZSBMaXN0PERDVHJlZT4gY2FzdChMaXN0PD8gZXh0ZW5kcyBEb2NUcmVlPiBsaXN0KSB7CiAgICAgICAgcmV0dXJuIChMaXN0PERDVHJlZT4pIGxpc3Q7CiAgICB9Cn0KUEsDBAoAAAgAAAY7qUo3hVmjdVMAAHVTAAAoAAAAY29tL3N1bi90b29scy9qYXZhYy90cmVlL1RyZWVDb3BpZXIuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNiwgMjAxNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWU7CgppbXBvcnQgY29tLnN1bi5zb3VyY2UudHJlZS4qOwppbXBvcnQgY29tLnN1bi5zb3VyY2UudHJlZS5UcmVlLktpbmQ7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuSkNUcmVlLio7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuRGVmaW5lZEJ5OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkRlZmluZWRCeS5BcGk7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuTGlzdDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5MaXN0QnVmZmVyOwoKLyoqCiAqIENyZWF0ZXMgYSBjb3B5IG9mIGEgdHJlZSwgdXNpbmcgYSBnaXZlbiBUcmVlTWFrZXIuCiAqIE5hbWVzLCBsaXRlcmFsIHZhbHVlcywgZXRjIGFyZSBzaGFyZWQgd2l0aCB0aGUgb3JpZ2luYWwuCiAqCiAqICA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiAgSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93biByaXNrLgogKiAgVGhpcyBjb2RlIGFuZCBpdHMgaW50ZXJuYWwgaW50ZXJmYWNlcyBhcmUgc3ViamVjdCB0byBjaGFuZ2Ugb3IKICogIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj4KICovCnB1YmxpYyBjbGFzcyBUcmVlQ29waWVyPFA+IGltcGxlbWVudHMgVHJlZVZpc2l0b3I8SkNUcmVlLFA+IHsKICAgIHByaXZhdGUgVHJlZU1ha2VyIE07CgogICAgLyoqIENyZWF0ZXMgYSBuZXcgaW5zdGFuY2Ugb2YgVHJlZUNvcGllciAqLwogICAgcHVibGljIFRyZWVDb3BpZXIoVHJlZU1ha2VyIE0pIHsKICAgICAgICB0aGlzLk0gPSBNOwogICAgfQoKICAgIHB1YmxpYyA8VCBleHRlbmRzIEpDVHJlZT4gVCBjb3B5KFQgdHJlZSkgewogICAgICAgIHJldHVybiBjb3B5KHRyZWUsIG51bGwpOwogICAgfQoKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQogICAgcHVibGljIDxUIGV4dGVuZHMgSkNUcmVlPiBUIGNvcHkoVCB0cmVlLCBQIHApIHsKICAgICAgICBpZiAodHJlZSA9PSBudWxsKQogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICByZXR1cm4gKFQpICh0cmVlLmFjY2VwdCh0aGlzLCBwKSk7CiAgICB9CgogICAgcHVibGljIDxUIGV4dGVuZHMgSkNUcmVlPiBMaXN0PFQ+IGNvcHkoTGlzdDxUPiB0cmVlcykgewogICAgICAgIHJldHVybiBjb3B5KHRyZWVzLCBudWxsKTsKICAgIH0KCiAgICBwdWJsaWMgPFQgZXh0ZW5kcyBKQ1RyZWU+IExpc3Q8VD4gY29weShMaXN0PFQ+IHRyZWVzLCBQIHApIHsKICAgICAgICBpZiAodHJlZXMgPT0gbnVsbCkKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgTGlzdEJ1ZmZlcjxUPiBsYiA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICBmb3IgKFQgdHJlZTogdHJlZXMpCiAgICAgICAgICAgIGxiLmFwcGVuZChjb3B5KHRyZWUsIHApKTsKICAgICAgICByZXR1cm4gbGIudG9MaXN0KCk7CiAgICB9CgogICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBKQ1RyZWUgdmlzaXRBbm5vdGF0ZWRUeXBlKEFubm90YXRlZFR5cGVUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIEpDQW5ub3RhdGVkVHlwZSB0ID0gKEpDQW5ub3RhdGVkVHlwZSkgbm9kZTsKICAgICAgICBMaXN0PEpDQW5ub3RhdGlvbj4gYW5ub3RhdGlvbnMgPSBjb3B5KHQuYW5ub3RhdGlvbnMsIHApOwogICAgICAgIEpDRXhwcmVzc2lvbiB1bmRlcmx5aW5nVHlwZSA9IGNvcHkodC51bmRlcmx5aW5nVHlwZSwgcCk7CiAgICAgICAgcmV0dXJuIE0uYXQodC5wb3MpLkFubm90YXRlZFR5cGUoYW5ub3RhdGlvbnMsIHVuZGVybHlpbmdUeXBlKTsKICAgIH0KCiAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIEpDVHJlZSB2aXNpdEFubm90YXRpb24oQW5ub3RhdGlvblRyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgSkNBbm5vdGF0aW9uIHQgPSAoSkNBbm5vdGF0aW9uKSBub2RlOwogICAgICAgIEpDVHJlZSBhbm5vdGF0aW9uVHlwZSA9IGNvcHkodC5hbm5vdGF0aW9uVHlwZSwgcCk7CiAgICAgICAgTGlzdDxKQ0V4cHJlc3Npb24+IGFyZ3MgPSBjb3B5KHQuYXJncywgcCk7CiAgICAgICAgaWYgKHQuZ2V0S2luZCgpID09IFRyZWUuS2luZC5UWVBFX0FOTk9UQVRJT04pIHsKICAgICAgICAgICAgSkNBbm5vdGF0aW9uIG5ld1RBID0gTS5hdCh0LnBvcykuVHlwZUFubm90YXRpb24oYW5ub3RhdGlvblR5cGUsIGFyZ3MpOwogICAgICAgICAgICBuZXdUQS5hdHRyaWJ1dGUgPSB0LmF0dHJpYnV0ZTsKICAgICAgICAgICAgcmV0dXJuIG5ld1RBOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIEpDQW5ub3RhdGlvbiBuZXdUID0gTS5hdCh0LnBvcykuQW5ub3RhdGlvbihhbm5vdGF0aW9uVHlwZSwgYXJncyk7CiAgICAgICAgICAgIG5ld1QuYXR0cmlidXRlID0gdC5hdHRyaWJ1dGU7CiAgICAgICAgICAgIHJldHVybiBuZXdUOwogICAgICAgIH0KICAgIH0KCiAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIEpDVHJlZSB2aXNpdEFzc2VydChBc3NlcnRUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIEpDQXNzZXJ0IHQgPSAoSkNBc3NlcnQpIG5vZGU7CiAgICAgICAgSkNFeHByZXNzaW9uIGNvbmQgPSBjb3B5KHQuY29uZCwgcCk7CiAgICAgICAgSkNFeHByZXNzaW9uIGRldGFpbCA9IGNvcHkodC5kZXRhaWwsIHApOwogICAgICAgIHJldHVybiBNLmF0KHQucG9zKS5Bc3NlcnQoY29uZCwgZGV0YWlsKTsKICAgIH0KCiAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIEpDVHJlZSB2aXNpdEFzc2lnbm1lbnQoQXNzaWdubWVudFRyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgSkNBc3NpZ24gdCA9IChKQ0Fzc2lnbikgbm9kZTsKICAgICAgICBKQ0V4cHJlc3Npb24gbGhzID0gY29weSh0LmxocywgcCk7CiAgICAgICAgSkNFeHByZXNzaW9uIHJocyA9IGNvcHkodC5yaHMsIHApOwogICAgICAgIHJldHVybiBNLmF0KHQucG9zKS5Bc3NpZ24obGhzLCByaHMpOwogICAgfQoKICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICBwdWJsaWMgSkNUcmVlIHZpc2l0Q29tcG91bmRBc3NpZ25tZW50KENvbXBvdW5kQXNzaWdubWVudFRyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgSkNBc3NpZ25PcCB0ID0gKEpDQXNzaWduT3ApIG5vZGU7CiAgICAgICAgSkNUcmVlIGxocyA9IGNvcHkodC5saHMsIHApOwogICAgICAgIEpDVHJlZSByaHMgPSBjb3B5KHQucmhzLCBwKTsKICAgICAgICByZXR1cm4gTS5hdCh0LnBvcykuQXNzaWdub3AodC5nZXRUYWcoKSwgbGhzLCByaHMpOwogICAgfQoKICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICBwdWJsaWMgSkNUcmVlIHZpc2l0QmluYXJ5KEJpbmFyeVRyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgSkNCaW5hcnkgdCA9IChKQ0JpbmFyeSkgbm9kZTsKICAgICAgICBKQ0V4cHJlc3Npb24gbGhzID0gY29weSh0LmxocywgcCk7CiAgICAgICAgSkNFeHByZXNzaW9uIHJocyA9IGNvcHkodC5yaHMsIHApOwogICAgICAgIHJldHVybiBNLmF0KHQucG9zKS5CaW5hcnkodC5nZXRUYWcoKSwgbGhzLCByaHMpOwogICAgfQoKICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICBwdWJsaWMgSkNUcmVlIHZpc2l0QmxvY2soQmxvY2tUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIEpDQmxvY2sgdCA9IChKQ0Jsb2NrKSBub2RlOwogICAgICAgIExpc3Q8SkNTdGF0ZW1lbnQ+IHN0YXRzID0gY29weSh0LnN0YXRzLCBwKTsKICAgICAgICByZXR1cm4gTS5hdCh0LnBvcykuQmxvY2sodC5mbGFncywgc3RhdHMpOwogICAgfQoKICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICBwdWJsaWMgSkNUcmVlIHZpc2l0QnJlYWsoQnJlYWtUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIEpDQnJlYWsgdCA9IChKQ0JyZWFrKSBub2RlOwogICAgICAgIHJldHVybiBNLmF0KHQucG9zKS5CcmVhayh0LmxhYmVsKTsKICAgIH0KCiAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIEpDVHJlZSB2aXNpdENhc2UoQ2FzZVRyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgSkNDYXNlIHQgPSAoSkNDYXNlKSBub2RlOwogICAgICAgIEpDRXhwcmVzc2lvbiBwYXQgPSBjb3B5KHQucGF0LCBwKTsKICAgICAgICBMaXN0PEpDU3RhdGVtZW50PiBzdGF0cyA9IGNvcHkodC5zdGF0cywgcCk7CiAgICAgICAgcmV0dXJuIE0uYXQodC5wb3MpLkNhc2UocGF0LCBzdGF0cyk7CiAgICB9CgogICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBKQ1RyZWUgdmlzaXRDYXRjaChDYXRjaFRyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgSkNDYXRjaCB0ID0gKEpDQ2F0Y2gpIG5vZGU7CiAgICAgICAgSkNWYXJpYWJsZURlY2wgcGFyYW0gPSBjb3B5KHQucGFyYW0sIHApOwogICAgICAgIEpDQmxvY2sgYm9keSA9IGNvcHkodC5ib2R5LCBwKTsKICAgICAgICByZXR1cm4gTS5hdCh0LnBvcykuQ2F0Y2gocGFyYW0sIGJvZHkpOwogICAgfQoKICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICBwdWJsaWMgSkNUcmVlIHZpc2l0Q2xhc3MoQ2xhc3NUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIEpDQ2xhc3NEZWNsIHQgPSAoSkNDbGFzc0RlY2wpIG5vZGU7CiAgICAgICAgSkNNb2RpZmllcnMgbW9kcyA9IGNvcHkodC5tb2RzLCBwKTsKICAgICAgICBMaXN0PEpDVHlwZVBhcmFtZXRlcj4gdHlwYXJhbXMgPSBjb3B5KHQudHlwYXJhbXMsIHApOwogICAgICAgIEpDRXhwcmVzc2lvbiBleHRlbmRpbmcgPSBjb3B5KHQuZXh0ZW5kaW5nLCBwKTsKICAgICAgICBMaXN0PEpDRXhwcmVzc2lvbj4gaW1wbGVtZW50aW5nID0gY29weSh0LmltcGxlbWVudGluZywgcCk7CiAgICAgICAgTGlzdDxKQ1RyZWU+IGRlZnMgPSBjb3B5KHQuZGVmcywgcCk7CiAgICAgICAgcmV0dXJuIE0uYXQodC5wb3MpLkNsYXNzRGVmKG1vZHMsIHQubmFtZSwgdHlwYXJhbXMsIGV4dGVuZGluZywgaW1wbGVtZW50aW5nLCBkZWZzKTsKICAgIH0KCiAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIEpDVHJlZSB2aXNpdENvbmRpdGlvbmFsRXhwcmVzc2lvbihDb25kaXRpb25hbEV4cHJlc3Npb25UcmVlIG5vZGUsIFAgcCkgewogICAgICAgIEpDQ29uZGl0aW9uYWwgdCA9IChKQ0NvbmRpdGlvbmFsKSBub2RlOwogICAgICAgIEpDRXhwcmVzc2lvbiBjb25kID0gY29weSh0LmNvbmQsIHApOwogICAgICAgIEpDRXhwcmVzc2lvbiB0cnVlcGFydCA9IGNvcHkodC50cnVlcGFydCwgcCk7CiAgICAgICAgSkNFeHByZXNzaW9uIGZhbHNlcGFydCA9IGNvcHkodC5mYWxzZXBhcnQsIHApOwogICAgICAgIHJldHVybiBNLmF0KHQucG9zKS5Db25kaXRpb25hbChjb25kLCB0cnVlcGFydCwgZmFsc2VwYXJ0KTsKICAgIH0KCiAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIEpDVHJlZSB2aXNpdENvbnRpbnVlKENvbnRpbnVlVHJlZSBub2RlLCBQIHApIHsKICAgICAgICBKQ0NvbnRpbnVlIHQgPSAoSkNDb250aW51ZSkgbm9kZTsKICAgICAgICByZXR1cm4gTS5hdCh0LnBvcykuQ29udGludWUodC5sYWJlbCk7CiAgICB9CgogICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBKQ1RyZWUgdmlzaXREb1doaWxlTG9vcChEb1doaWxlTG9vcFRyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgSkNEb1doaWxlTG9vcCB0ID0gKEpDRG9XaGlsZUxvb3ApIG5vZGU7CiAgICAgICAgSkNTdGF0ZW1lbnQgYm9keSA9IGNvcHkodC5ib2R5LCBwKTsKICAgICAgICBKQ0V4cHJlc3Npb24gY29uZCA9IGNvcHkodC5jb25kLCBwKTsKICAgICAgICByZXR1cm4gTS5hdCh0LnBvcykuRG9Mb29wKGJvZHksIGNvbmQpOwogICAgfQoKICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICBwdWJsaWMgSkNUcmVlIHZpc2l0RXJyb25lb3VzKEVycm9uZW91c1RyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgSkNFcnJvbmVvdXMgdCA9IChKQ0Vycm9uZW91cykgbm9kZTsKICAgICAgICBMaXN0PD8gZXh0ZW5kcyBKQ1RyZWU+IGVycnMgPSBjb3B5KHQuZXJycywgcCk7CiAgICAgICAgcmV0dXJuIE0uYXQodC5wb3MpLkVycm9uZW91cyhlcnJzKTsKICAgIH0KCiAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIEpDVHJlZSB2aXNpdEV4cHJlc3Npb25TdGF0ZW1lbnQoRXhwcmVzc2lvblN0YXRlbWVudFRyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgSkNFeHByZXNzaW9uU3RhdGVtZW50IHQgPSAoSkNFeHByZXNzaW9uU3RhdGVtZW50KSBub2RlOwogICAgICAgIEpDRXhwcmVzc2lvbiBleHByID0gY29weSh0LmV4cHIsIHApOwogICAgICAgIHJldHVybiBNLmF0KHQucG9zKS5FeGVjKGV4cHIpOwogICAgfQoKICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICBwdWJsaWMgSkNUcmVlIHZpc2l0RW5oYW5jZWRGb3JMb29wKEVuaGFuY2VkRm9yTG9vcFRyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgSkNFbmhhbmNlZEZvckxvb3AgdCA9IChKQ0VuaGFuY2VkRm9yTG9vcCkgbm9kZTsKICAgICAgICBKQ1ZhcmlhYmxlRGVjbCB2YXIgPSBjb3B5KHQudmFyLCBwKTsKICAgICAgICBKQ0V4cHJlc3Npb24gZXhwciA9IGNvcHkodC5leHByLCBwKTsKICAgICAgICBKQ1N0YXRlbWVudCBib2R5ID0gY29weSh0LmJvZHksIHApOwogICAgICAgIHJldHVybiBNLmF0KHQucG9zKS5Gb3JlYWNoTG9vcCh2YXIsIGV4cHIsIGJvZHkpOwogICAgfQoKICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICBwdWJsaWMgSkNUcmVlIHZpc2l0Rm9yTG9vcChGb3JMb29wVHJlZSBub2RlLCBQIHApIHsKICAgICAgICBKQ0Zvckxvb3AgdCA9IChKQ0Zvckxvb3ApIG5vZGU7CiAgICAgICAgTGlzdDxKQ1N0YXRlbWVudD4gaW5pdCA9IGNvcHkodC5pbml0LCBwKTsKICAgICAgICBKQ0V4cHJlc3Npb24gY29uZCA9IGNvcHkodC5jb25kLCBwKTsKICAgICAgICBMaXN0PEpDRXhwcmVzc2lvblN0YXRlbWVudD4gc3RlcCA9IGNvcHkodC5zdGVwLCBwKTsKICAgICAgICBKQ1N0YXRlbWVudCBib2R5ID0gY29weSh0LmJvZHksIHApOwogICAgICAgIHJldHVybiBNLmF0KHQucG9zKS5Gb3JMb29wKGluaXQsIGNvbmQsIHN0ZXAsIGJvZHkpOwogICAgfQoKICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICBwdWJsaWMgSkNUcmVlIHZpc2l0SWRlbnRpZmllcihJZGVudGlmaWVyVHJlZSBub2RlLCBQIHApIHsKICAgICAgICBKQ0lkZW50IHQgPSAoSkNJZGVudCkgbm9kZTsKICAgICAgICByZXR1cm4gTS5hdCh0LnBvcykuSWRlbnQodC5uYW1lKTsKICAgIH0KCiAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIEpDVHJlZSB2aXNpdElmKElmVHJlZSBub2RlLCBQIHApIHsKICAgICAgICBKQ0lmIHQgPSAoSkNJZikgbm9kZTsKICAgICAgICBKQ0V4cHJlc3Npb24gY29uZCA9IGNvcHkodC5jb25kLCBwKTsKICAgICAgICBKQ1N0YXRlbWVudCB0aGVucGFydCA9IGNvcHkodC50aGVucGFydCwgcCk7CiAgICAgICAgSkNTdGF0ZW1lbnQgZWxzZXBhcnQgPSBjb3B5KHQuZWxzZXBhcnQsIHApOwogICAgICAgIHJldHVybiBNLmF0KHQucG9zKS5JZihjb25kLCB0aGVucGFydCwgZWxzZXBhcnQpOwogICAgfQoKICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICBwdWJsaWMgSkNUcmVlIHZpc2l0SW1wb3J0KEltcG9ydFRyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgSkNJbXBvcnQgdCA9IChKQ0ltcG9ydCkgbm9kZTsKICAgICAgICBKQ1RyZWUgcXVhbGlkID0gY29weSh0LnF1YWxpZCwgcCk7CiAgICAgICAgcmV0dXJuIE0uYXQodC5wb3MpLkltcG9ydChxdWFsaWQsIHQuc3RhdGljSW1wb3J0KTsKICAgIH0KCiAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIEpDVHJlZSB2aXNpdEFycmF5QWNjZXNzKEFycmF5QWNjZXNzVHJlZSBub2RlLCBQIHApIHsKICAgICAgICBKQ0FycmF5QWNjZXNzIHQgPSAoSkNBcnJheUFjY2Vzcykgbm9kZTsKICAgICAgICBKQ0V4cHJlc3Npb24gaW5kZXhlZCA9IGNvcHkodC5pbmRleGVkLCBwKTsKICAgICAgICBKQ0V4cHJlc3Npb24gaW5kZXggPSBjb3B5KHQuaW5kZXgsIHApOwogICAgICAgIHJldHVybiBNLmF0KHQucG9zKS5JbmRleGVkKGluZGV4ZWQsIGluZGV4KTsKICAgIH0KCiAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIEpDVHJlZSB2aXNpdExhYmVsZWRTdGF0ZW1lbnQoTGFiZWxlZFN0YXRlbWVudFRyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgSkNMYWJlbGVkU3RhdGVtZW50IHQgPSAoSkNMYWJlbGVkU3RhdGVtZW50KSBub2RlOwogICAgICAgIEpDU3RhdGVtZW50IGJvZHkgPSBjb3B5KHQuYm9keSwgcCk7CiAgICAgICAgcmV0dXJuIE0uYXQodC5wb3MpLkxhYmVsbGVkKHQubGFiZWwsIGJvZHkpOwogICAgfQoKICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICBwdWJsaWMgSkNUcmVlIHZpc2l0TGl0ZXJhbChMaXRlcmFsVHJlZSBub2RlLCBQIHApIHsKICAgICAgICBKQ0xpdGVyYWwgdCA9IChKQ0xpdGVyYWwpIG5vZGU7CiAgICAgICAgcmV0dXJuIE0uYXQodC5wb3MpLkxpdGVyYWwodC50eXBldGFnLCB0LnZhbHVlKTsKICAgIH0KCiAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIEpDVHJlZSB2aXNpdE1ldGhvZChNZXRob2RUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIEpDTWV0aG9kRGVjbCB0ICA9IChKQ01ldGhvZERlY2wpIG5vZGU7CiAgICAgICAgSkNNb2RpZmllcnMgbW9kcyA9IGNvcHkodC5tb2RzLCBwKTsKICAgICAgICBKQ0V4cHJlc3Npb24gcmVzdHlwZSA9IGNvcHkodC5yZXN0eXBlLCBwKTsKICAgICAgICBMaXN0PEpDVHlwZVBhcmFtZXRlcj4gdHlwYXJhbXMgPSBjb3B5KHQudHlwYXJhbXMsIHApOwogICAgICAgIExpc3Q8SkNWYXJpYWJsZURlY2w+IHBhcmFtcyA9IGNvcHkodC5wYXJhbXMsIHApOwogICAgICAgIEpDVmFyaWFibGVEZWNsIHJlY3ZwYXJhbSA9IGNvcHkodC5yZWN2cGFyYW0sIHApOwogICAgICAgIExpc3Q8SkNFeHByZXNzaW9uPiB0aHJvd24gPSBjb3B5KHQudGhyb3duLCBwKTsKICAgICAgICBKQ0Jsb2NrIGJvZHkgPSBjb3B5KHQuYm9keSwgcCk7CiAgICAgICAgSkNFeHByZXNzaW9uIGRlZmF1bHRWYWx1ZSA9IGNvcHkodC5kZWZhdWx0VmFsdWUsIHApOwogICAgICAgIHJldHVybiBNLmF0KHQucG9zKS5NZXRob2REZWYobW9kcywgdC5uYW1lLCByZXN0eXBlLCB0eXBhcmFtcywgcmVjdnBhcmFtLCBwYXJhbXMsIHRocm93biwgYm9keSwgZGVmYXVsdFZhbHVlKTsKICAgIH0KCiAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIEpDVHJlZSB2aXNpdE1ldGhvZEludm9jYXRpb24oTWV0aG9kSW52b2NhdGlvblRyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgSkNNZXRob2RJbnZvY2F0aW9uIHQgPSAoSkNNZXRob2RJbnZvY2F0aW9uKSBub2RlOwogICAgICAgIExpc3Q8SkNFeHByZXNzaW9uPiB0eXBlYXJncyA9IGNvcHkodC50eXBlYXJncywgcCk7CiAgICAgICAgSkNFeHByZXNzaW9uIG1ldGggPSBjb3B5KHQubWV0aCwgcCk7CiAgICAgICAgTGlzdDxKQ0V4cHJlc3Npb24+IGFyZ3MgPSBjb3B5KHQuYXJncywgcCk7CiAgICAgICAgcmV0dXJuIE0uYXQodC5wb3MpLkFwcGx5KHR5cGVhcmdzLCBtZXRoLCBhcmdzKTsKICAgIH0KCiAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIEpDVHJlZSB2aXNpdE1vZGlmaWVycyhNb2RpZmllcnNUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIEpDTW9kaWZpZXJzIHQgPSAoSkNNb2RpZmllcnMpIG5vZGU7CiAgICAgICAgTGlzdDxKQ0Fubm90YXRpb24+IGFubm90YXRpb25zID0gY29weSh0LmFubm90YXRpb25zLCBwKTsKICAgICAgICByZXR1cm4gTS5hdCh0LnBvcykuTW9kaWZpZXJzKHQuZmxhZ3MsIGFubm90YXRpb25zKTsKICAgIH0KCiAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIEpDVHJlZSB2aXNpdE5ld0FycmF5KE5ld0FycmF5VHJlZSBub2RlLCBQIHApIHsKICAgICAgICBKQ05ld0FycmF5IHQgPSAoSkNOZXdBcnJheSkgbm9kZTsKICAgICAgICBKQ0V4cHJlc3Npb24gZWxlbXR5cGUgPSBjb3B5KHQuZWxlbXR5cGUsIHApOwogICAgICAgIExpc3Q8SkNFeHByZXNzaW9uPiBkaW1zID0gY29weSh0LmRpbXMsIHApOwogICAgICAgIExpc3Q8SkNFeHByZXNzaW9uPiBlbGVtcyA9IGNvcHkodC5lbGVtcywgcCk7CiAgICAgICAgcmV0dXJuIE0uYXQodC5wb3MpLk5ld0FycmF5KGVsZW10eXBlLCBkaW1zLCBlbGVtcyk7CiAgICB9CgogICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBKQ1RyZWUgdmlzaXROZXdDbGFzcyhOZXdDbGFzc1RyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgSkNOZXdDbGFzcyB0ID0gKEpDTmV3Q2xhc3MpIG5vZGU7CiAgICAgICAgSkNFeHByZXNzaW9uIGVuY2wgPSBjb3B5KHQuZW5jbCwgcCk7CiAgICAgICAgTGlzdDxKQ0V4cHJlc3Npb24+IHR5cGVhcmdzID0gY29weSh0LnR5cGVhcmdzLCBwKTsKICAgICAgICBKQ0V4cHJlc3Npb24gY2xhenogPSBjb3B5KHQuY2xhenosIHApOwogICAgICAgIExpc3Q8SkNFeHByZXNzaW9uPiBhcmdzID0gY29weSh0LmFyZ3MsIHApOwogICAgICAgIEpDQ2xhc3NEZWNsIGRlZiA9IGNvcHkodC5kZWYsIHApOwogICAgICAgIHJldHVybiBNLmF0KHQucG9zKS5OZXdDbGFzcyhlbmNsLCB0eXBlYXJncywgY2xhenosIGFyZ3MsIGRlZik7CiAgICB9CgogICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBKQ1RyZWUgdmlzaXRMYW1iZGFFeHByZXNzaW9uKExhbWJkYUV4cHJlc3Npb25UcmVlIG5vZGUsIFAgcCkgewogICAgICAgIEpDTGFtYmRhIHQgPSAoSkNMYW1iZGEpIG5vZGU7CiAgICAgICAgTGlzdDxKQ1ZhcmlhYmxlRGVjbD4gcGFyYW1zID0gY29weSh0LnBhcmFtcywgcCk7CiAgICAgICAgSkNUcmVlIGJvZHkgPSBjb3B5KHQuYm9keSwgcCk7CiAgICAgICAgcmV0dXJuIE0uYXQodC5wb3MpLkxhbWJkYShwYXJhbXMsIGJvZHkpOwogICAgfQoKICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICBwdWJsaWMgSkNUcmVlIHZpc2l0UGFyZW50aGVzaXplZChQYXJlbnRoZXNpemVkVHJlZSBub2RlLCBQIHApIHsKICAgICAgICBKQ1BhcmVucyB0ID0gKEpDUGFyZW5zKSBub2RlOwogICAgICAgIEpDRXhwcmVzc2lvbiBleHByID0gY29weSh0LmV4cHIsIHApOwogICAgICAgIHJldHVybiBNLmF0KHQucG9zKS5QYXJlbnMoZXhwcik7CiAgICB9CgogICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBKQ1RyZWUgdmlzaXRSZXR1cm4oUmV0dXJuVHJlZSBub2RlLCBQIHApIHsKICAgICAgICBKQ1JldHVybiB0ID0gKEpDUmV0dXJuKSBub2RlOwogICAgICAgIEpDRXhwcmVzc2lvbiBleHByID0gY29weSh0LmV4cHIsIHApOwogICAgICAgIHJldHVybiBNLmF0KHQucG9zKS5SZXR1cm4oZXhwcik7CiAgICB9CgogICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBKQ1RyZWUgdmlzaXRNZW1iZXJTZWxlY3QoTWVtYmVyU2VsZWN0VHJlZSBub2RlLCBQIHApIHsKICAgICAgICBKQ0ZpZWxkQWNjZXNzIHQgPSAoSkNGaWVsZEFjY2Vzcykgbm9kZTsKICAgICAgICBKQ0V4cHJlc3Npb24gc2VsZWN0ZWQgPSBjb3B5KHQuc2VsZWN0ZWQsIHApOwogICAgICAgIHJldHVybiBNLmF0KHQucG9zKS5TZWxlY3Qoc2VsZWN0ZWQsIHQubmFtZSk7CiAgICB9CgogICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBKQ1RyZWUgdmlzaXRNZW1iZXJSZWZlcmVuY2UoTWVtYmVyUmVmZXJlbmNlVHJlZSBub2RlLCBQIHApIHsKICAgICAgICBKQ01lbWJlclJlZmVyZW5jZSB0ID0gKEpDTWVtYmVyUmVmZXJlbmNlKSBub2RlOwogICAgICAgIEpDRXhwcmVzc2lvbiBleHByID0gY29weSh0LmV4cHIsIHApOwogICAgICAgIExpc3Q8SkNFeHByZXNzaW9uPiB0eXBlYXJncyA9IGNvcHkodC50eXBlYXJncywgcCk7CiAgICAgICAgcmV0dXJuIE0uYXQodC5wb3MpLlJlZmVyZW5jZSh0Lm1vZGUsIHQubmFtZSwgZXhwciwgdHlwZWFyZ3MpOwogICAgfQoKICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICBwdWJsaWMgSkNUcmVlIHZpc2l0RW1wdHlTdGF0ZW1lbnQoRW1wdHlTdGF0ZW1lbnRUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIEpDU2tpcCB0ID0gKEpDU2tpcCkgbm9kZTsKICAgICAgICByZXR1cm4gTS5hdCh0LnBvcykuU2tpcCgpOwogICAgfQoKICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICBwdWJsaWMgSkNUcmVlIHZpc2l0U3dpdGNoKFN3aXRjaFRyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgSkNTd2l0Y2ggdCA9IChKQ1N3aXRjaCkgbm9kZTsKICAgICAgICBKQ0V4cHJlc3Npb24gc2VsZWN0b3IgPSBjb3B5KHQuc2VsZWN0b3IsIHApOwogICAgICAgIExpc3Q8SkNDYXNlPiBjYXNlcyA9IGNvcHkodC5jYXNlcywgcCk7CiAgICAgICAgcmV0dXJuIE0uYXQodC5wb3MpLlN3aXRjaChzZWxlY3RvciwgY2FzZXMpOwogICAgfQoKICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICBwdWJsaWMgSkNUcmVlIHZpc2l0U3luY2hyb25pemVkKFN5bmNocm9uaXplZFRyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgSkNTeW5jaHJvbml6ZWQgdCA9IChKQ1N5bmNocm9uaXplZCkgbm9kZTsKICAgICAgICBKQ0V4cHJlc3Npb24gbG9jayA9IGNvcHkodC5sb2NrLCBwKTsKICAgICAgICBKQ0Jsb2NrIGJvZHkgPSBjb3B5KHQuYm9keSwgcCk7CiAgICAgICAgcmV0dXJuIE0uYXQodC5wb3MpLlN5bmNocm9uaXplZChsb2NrLCBib2R5KTsKICAgIH0KCiAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIEpDVHJlZSB2aXNpdFRocm93KFRocm93VHJlZSBub2RlLCBQIHApIHsKICAgICAgICBKQ1Rocm93IHQgPSAoSkNUaHJvdykgbm9kZTsKICAgICAgICBKQ0V4cHJlc3Npb24gZXhwciA9IGNvcHkodC5leHByLCBwKTsKICAgICAgICByZXR1cm4gTS5hdCh0LnBvcykuVGhyb3coZXhwcik7CiAgICB9CgogICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBKQ1RyZWUgdmlzaXRDb21waWxhdGlvblVuaXQoQ29tcGlsYXRpb25Vbml0VHJlZSBub2RlLCBQIHApIHsKICAgICAgICBKQ0NvbXBpbGF0aW9uVW5pdCB0ID0gKEpDQ29tcGlsYXRpb25Vbml0KSBub2RlOwogICAgICAgIExpc3Q8SkNUcmVlPiBkZWZzID0gY29weSh0LmRlZnMsIHApOwogICAgICAgIHJldHVybiBNLmF0KHQucG9zKS5Ub3BMZXZlbChkZWZzKTsKICAgIH0KCiAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIEpDVHJlZSB2aXNpdFBhY2thZ2UoUGFja2FnZVRyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgSkNQYWNrYWdlRGVjbCB0ID0gKEpDUGFja2FnZURlY2wpIG5vZGU7CiAgICAgICAgTGlzdDxKQ0Fubm90YXRpb24+IGFubm90YXRpb25zID0gY29weSh0LmFubm90YXRpb25zLCBwKTsKICAgICAgICBKQ0V4cHJlc3Npb24gcGlkID0gY29weSh0LnBpZCwgcCk7CiAgICAgICAgcmV0dXJuIE0uYXQodC5wb3MpLlBhY2thZ2VEZWNsKGFubm90YXRpb25zLCBwaWQpOwogICAgfQoKICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICBwdWJsaWMgSkNUcmVlIHZpc2l0VHJ5KFRyeVRyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgSkNUcnkgdCA9IChKQ1RyeSkgbm9kZTsKICAgICAgICBMaXN0PEpDVHJlZT4gcmVzb3VyY2VzID0gY29weSh0LnJlc291cmNlcywgcCk7CiAgICAgICAgSkNCbG9jayBib2R5ID0gY29weSh0LmJvZHksIHApOwogICAgICAgIExpc3Q8SkNDYXRjaD4gY2F0Y2hlcnMgPSBjb3B5KHQuY2F0Y2hlcnMsIHApOwogICAgICAgIEpDQmxvY2sgZmluYWxpemVyID0gY29weSh0LmZpbmFsaXplciwgcCk7CiAgICAgICAgcmV0dXJuIE0uYXQodC5wb3MpLlRyeShyZXNvdXJjZXMsIGJvZHksIGNhdGNoZXJzLCBmaW5hbGl6ZXIpOwogICAgfQoKICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICBwdWJsaWMgSkNUcmVlIHZpc2l0UGFyYW1ldGVyaXplZFR5cGUoUGFyYW1ldGVyaXplZFR5cGVUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIEpDVHlwZUFwcGx5IHQgPSAoSkNUeXBlQXBwbHkpIG5vZGU7CiAgICAgICAgSkNFeHByZXNzaW9uIGNsYXp6ID0gY29weSh0LmNsYXp6LCBwKTsKICAgICAgICBMaXN0PEpDRXhwcmVzc2lvbj4gYXJndW1lbnRzID0gY29weSh0LmFyZ3VtZW50cywgcCk7CiAgICAgICAgcmV0dXJuIE0uYXQodC5wb3MpLlR5cGVBcHBseShjbGF6eiwgYXJndW1lbnRzKTsKICAgIH0KCiAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIEpDVHJlZSB2aXNpdFVuaW9uVHlwZShVbmlvblR5cGVUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIEpDVHlwZVVuaW9uIHQgPSAoSkNUeXBlVW5pb24pIG5vZGU7CiAgICAgICAgTGlzdDxKQ0V4cHJlc3Npb24+IGNvbXBvbmVudHMgPSBjb3B5KHQuYWx0ZXJuYXRpdmVzLCBwKTsKICAgICAgICByZXR1cm4gTS5hdCh0LnBvcykuVHlwZVVuaW9uKGNvbXBvbmVudHMpOwogICAgfQoKICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICBwdWJsaWMgSkNUcmVlIHZpc2l0SW50ZXJzZWN0aW9uVHlwZShJbnRlcnNlY3Rpb25UeXBlVHJlZSBub2RlLCBQIHApIHsKICAgICAgICBKQ1R5cGVJbnRlcnNlY3Rpb24gdCA9IChKQ1R5cGVJbnRlcnNlY3Rpb24pIG5vZGU7CiAgICAgICAgTGlzdDxKQ0V4cHJlc3Npb24+IGJvdW5kcyA9IGNvcHkodC5ib3VuZHMsIHApOwogICAgICAgIHJldHVybiBNLmF0KHQucG9zKS5UeXBlSW50ZXJzZWN0aW9uKGJvdW5kcyk7CiAgICB9CgogICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBKQ1RyZWUgdmlzaXRBcnJheVR5cGUoQXJyYXlUeXBlVHJlZSBub2RlLCBQIHApIHsKICAgICAgICBKQ0FycmF5VHlwZVRyZWUgdCA9IChKQ0FycmF5VHlwZVRyZWUpIG5vZGU7CiAgICAgICAgSkNFeHByZXNzaW9uIGVsZW10eXBlID0gY29weSh0LmVsZW10eXBlLCBwKTsKICAgICAgICByZXR1cm4gTS5hdCh0LnBvcykuVHlwZUFycmF5KGVsZW10eXBlKTsKICAgIH0KCiAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIEpDVHJlZSB2aXNpdFR5cGVDYXN0KFR5cGVDYXN0VHJlZSBub2RlLCBQIHApIHsKICAgICAgICBKQ1R5cGVDYXN0IHQgPSAoSkNUeXBlQ2FzdCkgbm9kZTsKICAgICAgICBKQ1RyZWUgY2xhenogPSBjb3B5KHQuY2xhenosIHApOwogICAgICAgIEpDRXhwcmVzc2lvbiBleHByID0gY29weSh0LmV4cHIsIHApOwogICAgICAgIHJldHVybiBNLmF0KHQucG9zKS5UeXBlQ2FzdChjbGF6eiwgZXhwcik7CiAgICB9CgogICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBKQ1RyZWUgdmlzaXRQcmltaXRpdmVUeXBlKFByaW1pdGl2ZVR5cGVUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIEpDUHJpbWl0aXZlVHlwZVRyZWUgdCA9IChKQ1ByaW1pdGl2ZVR5cGVUcmVlKSBub2RlOwogICAgICAgIHJldHVybiBNLmF0KHQucG9zKS5UeXBlSWRlbnQodC50eXBldGFnKTsKICAgIH0KCiAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIEpDVHJlZSB2aXNpdFR5cGVQYXJhbWV0ZXIoVHlwZVBhcmFtZXRlclRyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgSkNUeXBlUGFyYW1ldGVyIHQgPSAoSkNUeXBlUGFyYW1ldGVyKSBub2RlOwogICAgICAgIExpc3Q8SkNBbm5vdGF0aW9uPiBhbm5vcyA9IGNvcHkodC5hbm5vdGF0aW9ucywgcCk7CiAgICAgICAgTGlzdDxKQ0V4cHJlc3Npb24+IGJvdW5kcyA9IGNvcHkodC5ib3VuZHMsIHApOwogICAgICAgIHJldHVybiBNLmF0KHQucG9zKS5UeXBlUGFyYW1ldGVyKHQubmFtZSwgYm91bmRzLCBhbm5vcyk7CiAgICB9CgogICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBKQ1RyZWUgdmlzaXRJbnN0YW5jZU9mKEluc3RhbmNlT2ZUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIEpDSW5zdGFuY2VPZiB0ID0gKEpDSW5zdGFuY2VPZikgbm9kZTsKICAgICAgICBKQ0V4cHJlc3Npb24gZXhwciA9IGNvcHkodC5leHByLCBwKTsKICAgICAgICBKQ1RyZWUgY2xhenogPSBjb3B5KHQuY2xhenosIHApOwogICAgICAgIHJldHVybiBNLmF0KHQucG9zKS5UeXBlVGVzdChleHByLCBjbGF6eik7CiAgICB9CgogICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBKQ1RyZWUgdmlzaXRVbmFyeShVbmFyeVRyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgSkNVbmFyeSB0ID0gKEpDVW5hcnkpIG5vZGU7CiAgICAgICAgSkNFeHByZXNzaW9uIGFyZyA9IGNvcHkodC5hcmcsIHApOwogICAgICAgIHJldHVybiBNLmF0KHQucG9zKS5VbmFyeSh0LmdldFRhZygpLCBhcmcpOwogICAgfQoKICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICBwdWJsaWMgSkNUcmVlIHZpc2l0VmFyaWFibGUoVmFyaWFibGVUcmVlIG5vZGUsIFAgcCkgewogICAgICAgIEpDVmFyaWFibGVEZWNsIHQgPSAoSkNWYXJpYWJsZURlY2wpIG5vZGU7CiAgICAgICAgSkNNb2RpZmllcnMgbW9kcyA9IGNvcHkodC5tb2RzLCBwKTsKICAgICAgICBKQ0V4cHJlc3Npb24gdmFydHlwZSA9IGNvcHkodC52YXJ0eXBlLCBwKTsKICAgICAgICBpZiAodC5uYW1lZXhwciA9PSBudWxsKSB7CiAgICAgICAgICAgIEpDRXhwcmVzc2lvbiBpbml0ID0gY29weSh0LmluaXQsIHApOwogICAgICAgICAgICByZXR1cm4gTS5hdCh0LnBvcykuVmFyRGVmKG1vZHMsIHQubmFtZSwgdmFydHlwZSwgaW5pdCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgSkNFeHByZXNzaW9uIG5hbWVleHByID0gY29weSh0Lm5hbWVleHByLCBwKTsKICAgICAgICAgICAgcmV0dXJuIE0uYXQodC5wb3MpLlJlY2VpdmVyVmFyRGVmKG1vZHMsIG5hbWVleHByLCB2YXJ0eXBlKTsKICAgICAgICB9CiAgICB9CgogICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBKQ1RyZWUgdmlzaXRXaGlsZUxvb3AoV2hpbGVMb29wVHJlZSBub2RlLCBQIHApIHsKICAgICAgICBKQ1doaWxlTG9vcCB0ID0gKEpDV2hpbGVMb29wKSBub2RlOwogICAgICAgIEpDU3RhdGVtZW50IGJvZHkgPSBjb3B5KHQuYm9keSwgcCk7CiAgICAgICAgSkNFeHByZXNzaW9uIGNvbmQgPSBjb3B5KHQuY29uZCwgcCk7CiAgICAgICAgcmV0dXJuIE0uYXQodC5wb3MpLldoaWxlTG9vcChjb25kLCBib2R5KTsKICAgIH0KCiAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIEpDVHJlZSB2aXNpdFdpbGRjYXJkKFdpbGRjYXJkVHJlZSBub2RlLCBQIHApIHsKICAgICAgICBKQ1dpbGRjYXJkIHQgPSAoSkNXaWxkY2FyZCkgbm9kZTsKICAgICAgICBUeXBlQm91bmRLaW5kIGtpbmQgPSBNLmF0KHQua2luZC5wb3MpLlR5cGVCb3VuZEtpbmQodC5raW5kLmtpbmQpOwogICAgICAgIEpDVHJlZSBpbm5lciA9IGNvcHkodC5pbm5lciwgcCk7CiAgICAgICAgcmV0dXJuIE0uYXQodC5wb3MpLldpbGRjYXJkKGtpbmQsIGlubmVyKTsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBKQ1RyZWUgdmlzaXRNb2R1bGUoTW9kdWxlVHJlZSBub2RlLCBQIHApIHsKICAgICAgICBKQ01vZHVsZURlY2wgdCA9IChKQ01vZHVsZURlY2wpIG5vZGU7CiAgICAgICAgSkNNb2RpZmllcnMgbW9kcyA9IGNvcHkodC5tb2RzLCBwKTsKICAgICAgICBKQ0V4cHJlc3Npb24gcXVhbElkID0gY29weSh0LnF1YWxJZCk7CiAgICAgICAgTGlzdDxKQ0RpcmVjdGl2ZT4gZGlyZWN0aXZlcyA9IGNvcHkodC5kaXJlY3RpdmVzKTsKICAgICAgICByZXR1cm4gTS5hdCh0LnBvcykuTW9kdWxlRGVmKG1vZHMsIHQuZ2V0TW9kdWxlVHlwZSgpLCBxdWFsSWQsIGRpcmVjdGl2ZXMpOwogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIEpDRXhwb3J0cyB2aXNpdEV4cG9ydHMoRXhwb3J0c1RyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgSkNFeHBvcnRzIHQgPSAoSkNFeHBvcnRzKSBub2RlOwogICAgICAgIEpDRXhwcmVzc2lvbiBxdWFsSWQgPSBjb3B5KHQucXVhbGlkLCBwKTsKICAgICAgICBMaXN0PEpDRXhwcmVzc2lvbj4gbW9kdWxlTmFtZXMgPSBjb3B5KHQubW9kdWxlTmFtZXMsIHApOwogICAgICAgIHJldHVybiBNLmF0KHQucG9zKS5FeHBvcnRzKHF1YWxJZCwgbW9kdWxlTmFtZXMpOwogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIEpDT3BlbnMgdmlzaXRPcGVucyhPcGVuc1RyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgSkNPcGVucyB0ID0gKEpDT3BlbnMpIG5vZGU7CiAgICAgICAgSkNFeHByZXNzaW9uIHF1YWxJZCA9IGNvcHkodC5xdWFsaWQsIHApOwogICAgICAgIExpc3Q8SkNFeHByZXNzaW9uPiBtb2R1bGVOYW1lcyA9IGNvcHkodC5tb2R1bGVOYW1lcywgcCk7CiAgICAgICAgcmV0dXJuIE0uYXQodC5wb3MpLk9wZW5zKHF1YWxJZCwgbW9kdWxlTmFtZXMpOwogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIEpDUHJvdmlkZXMgdmlzaXRQcm92aWRlcyhQcm92aWRlc1RyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgSkNQcm92aWRlcyB0ID0gKEpDUHJvdmlkZXMpIG5vZGU7CiAgICAgICAgSkNFeHByZXNzaW9uIHNlcnZpY2VOYW1lID0gY29weSh0LnNlcnZpY2VOYW1lLCBwKTsKICAgICAgICBMaXN0PEpDRXhwcmVzc2lvbj4gaW1wbE5hbWVzID0gY29weSh0LmltcGxOYW1lcywgcCk7CiAgICAgICAgcmV0dXJuIE0uYXQodC5wb3MpLlByb3ZpZGVzKHNlcnZpY2VOYW1lLCBpbXBsTmFtZXMpOwogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIEpDUmVxdWlyZXMgdmlzaXRSZXF1aXJlcyhSZXF1aXJlc1RyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgSkNSZXF1aXJlcyB0ID0gKEpDUmVxdWlyZXMpIG5vZGU7CiAgICAgICAgSkNFeHByZXNzaW9uIG1vZHVsZU5hbWUgPSBjb3B5KHQubW9kdWxlTmFtZSwgcCk7CiAgICAgICAgcmV0dXJuIE0uYXQodC5wb3MpLlJlcXVpcmVzKHQuaXNUcmFuc2l0aXZlLCB0LmlzU3RhdGljUGhhc2UsIG1vZHVsZU5hbWUpOwogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIEpDVXNlcyB2aXNpdFVzZXMoVXNlc1RyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgSkNVc2VzIHQgPSAoSkNVc2VzKSBub2RlOwogICAgICAgIEpDRXhwcmVzc2lvbiBzZXJ2aWNlTmFtZSA9IGNvcHkodC5xdWFsaWQsIHApOwogICAgICAgIHJldHVybiBNLmF0KHQucG9zKS5Vc2VzKHNlcnZpY2VOYW1lKTsKICAgIH0KCiAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIEpDVHJlZSB2aXNpdE90aGVyKFRyZWUgbm9kZSwgUCBwKSB7CiAgICAgICAgSkNUcmVlIHRyZWUgPSAoSkNUcmVlKSBub2RlOwogICAgICAgIHN3aXRjaCAodHJlZS5nZXRUYWcoKSkgewogICAgICAgICAgICBjYXNlIExFVEVYUFI6IHsKICAgICAgICAgICAgICAgIExldEV4cHIgdCA9IChMZXRFeHByKSBub2RlOwogICAgICAgICAgICAgICAgTGlzdDxKQ1ZhcmlhYmxlRGVjbD4gZGVmcyA9IGNvcHkodC5kZWZzLCBwKTsKICAgICAgICAgICAgICAgIEpDRXhwcmVzc2lvbiBleHByID0gY29weSh0LmV4cHIsIHApOwogICAgICAgICAgICAgICAgcmV0dXJuIE0uYXQodC5wb3MpLkxldEV4cHIoZGVmcywgZXhwcik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigidW5rbm93biB0cmVlIHRhZzogIiArIHRyZWUuZ2V0VGFnKCkpOwogICAgICAgIH0KICAgIH0KCn0KUEsDBAoAAAgAAAY7qUrU/e0w86QAAPOkAAAmAAAAY29tL3N1bi90b29scy9qYXZhYy90cmVlL1RyZWVJbmZvLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDE5OTksIDIwMTYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhYy50cmVlOwoKCgppbXBvcnQgY29tLnN1bi5zb3VyY2UudHJlZS5UcmVlOwppbXBvcnQgY29tLnN1bi5zb3VyY2UudXRpbC5UcmVlUGF0aDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS4qOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb21wLkF0dHJDb250ZXh0OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb21wLkVudjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5KQ1RyZWUuKjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5KQ1RyZWUuSkNQb2x5RXhwcmVzc2lvbi4qOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLio7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuSkNEaWFnbm9zdGljLkRpYWdub3N0aWNQb3NpdGlvbjsKCmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLkZsYWdzLio7CmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLktpbmRzLktpbmQuKjsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuVHlwZVRhZy5CT1Q7CmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkpDVHJlZS5UYWcuKjsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuSkNUcmVlLlRhZy5CTE9DSzsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuSkNUcmVlLlRhZy5TWU5DSFJPTklaRUQ7CgppbXBvcnQgamF2YXgudG9vbHMuSmF2YUZpbGVPYmplY3Q7CgppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5KQ1RyZWUuSkNPcGVyYXRvckV4cHJlc3Npb24uT3BlcmFuZFBvcy5MRUZUOwppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5KQ1RyZWUuSkNPcGVyYXRvckV4cHJlc3Npb24uT3BlcmFuZFBvcy5SSUdIVDsKCi8qKiBVdGlsaXR5IGNsYXNzIGNvbnRhaW5pbmcgaW5zcGVjdG9yIG1ldGhvZHMgZm9yIHRyZWVzLgogKgogKiAgPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24gcmlzay4KICogIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yCiAqICBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+CiAqLwpwdWJsaWMgY2xhc3MgVHJlZUluZm8gewoKICAgIHB1YmxpYyBzdGF0aWMgTGlzdDxKQ0V4cHJlc3Npb24+IGFyZ3MoSkNUcmVlIHQpIHsKICAgICAgICBzd2l0Y2ggKHQuZ2V0VGFnKCkpIHsKICAgICAgICAgICAgY2FzZSBBUFBMWToKICAgICAgICAgICAgICAgIHJldHVybiAoKEpDTWV0aG9kSW52b2NhdGlvbil0KS5hcmdzOwogICAgICAgICAgICBjYXNlIE5FV0NMQVNTOgogICAgICAgICAgICAgICAgcmV0dXJuICgoSkNOZXdDbGFzcyl0KS5hcmdzOwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgfQoKICAgIC8qKiBJcyB0cmVlIGEgY29uc3RydWN0b3IgZGVjbGFyYXRpb24/CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc0NvbnN0cnVjdG9yKEpDVHJlZSB0cmVlKSB7CiAgICAgICAgaWYgKHRyZWUuaGFzVGFnKE1FVEhPRERFRikpIHsKICAgICAgICAgICAgTmFtZSBuYW1lID0gKChKQ01ldGhvZERlY2wpIHRyZWUpLm5hbWU7CiAgICAgICAgICAgIHJldHVybiBuYW1lID09IG5hbWUudGFibGUubmFtZXMuaW5pdDsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc1JlY2VpdmVyUGFyYW0oSkNUcmVlIHRyZWUpIHsKICAgICAgICBpZiAodHJlZS5oYXNUYWcoVkFSREVGKSkgewogICAgICAgICAgICByZXR1cm4gKChKQ1ZhcmlhYmxlRGVjbCl0cmVlKS5uYW1lZXhwciAhPSBudWxsOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICB9CgogICAgLyoqIElzIHRoZXJlIGEgY29uc3RydWN0b3IgZGVjbGFyYXRpb24gaW4gdGhlIGdpdmVuIGxpc3Qgb2YgdHJlZXM/CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBoYXNDb25zdHJ1Y3RvcnMoTGlzdDxKQ1RyZWU+IHRyZWVzKSB7CiAgICAgICAgZm9yIChMaXN0PEpDVHJlZT4gbCA9IHRyZWVzOyBsLm5vbkVtcHR5KCk7IGwgPSBsLnRhaWwpCiAgICAgICAgICAgIGlmIChpc0NvbnN0cnVjdG9yKGwuaGVhZCkpIHJldHVybiB0cnVlOwogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNNdWx0aUNhdGNoKEpDQ2F0Y2ggY2F0Y2hDbGF1c2UpIHsKICAgICAgICByZXR1cm4gY2F0Y2hDbGF1c2UucGFyYW0udmFydHlwZS5oYXNUYWcoVFlQRVVOSU9OKTsKICAgIH0KCiAgICAvKiogSXMgc3RhdGVtZW50IGFuIGluaXRpYWxpemVyIGZvciBhIHN5bnRoZXRpYyBmaWVsZD8KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzU3ludGhldGljSW5pdChKQ1RyZWUgc3RhdCkgewogICAgICAgIGlmIChzdGF0Lmhhc1RhZyhFWEVDKSkgewogICAgICAgICAgICBKQ0V4cHJlc3Npb25TdGF0ZW1lbnQgZXhlYyA9IChKQ0V4cHJlc3Npb25TdGF0ZW1lbnQpc3RhdDsKICAgICAgICAgICAgaWYgKGV4ZWMuZXhwci5oYXNUYWcoQVNTSUdOKSkgewogICAgICAgICAgICAgICAgSkNBc3NpZ24gYXNzaWduID0gKEpDQXNzaWduKWV4ZWMuZXhwcjsKICAgICAgICAgICAgICAgIGlmIChhc3NpZ24ubGhzLmhhc1RhZyhTRUxFQ1QpKSB7CiAgICAgICAgICAgICAgICAgICAgSkNGaWVsZEFjY2VzcyBzZWxlY3QgPSAoSkNGaWVsZEFjY2Vzcylhc3NpZ24ubGhzOwogICAgICAgICAgICAgICAgICAgIGlmIChzZWxlY3Quc3ltICE9IG51bGwgJiYKICAgICAgICAgICAgICAgICAgICAgICAgKHNlbGVjdC5zeW0uZmxhZ3MoKSAmIFNZTlRIRVRJQykgIT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICBOYW1lIHNlbGVjdGVkID0gbmFtZShzZWxlY3Quc2VsZWN0ZWQpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2VsZWN0ZWQgIT0gbnVsbCAmJiBzZWxlY3RlZCA9PSBzZWxlY3RlZC50YWJsZS5uYW1lcy5fdGhpcykKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgLyoqIElmIHRoZSBleHByZXNzaW9uIGlzIGEgbWV0aG9kIGNhbGwsIHJldHVybiB0aGUgbWV0aG9kIG5hbWUsIG51bGwKICAgICAqICBvdGhlcndpc2UuICovCiAgICBwdWJsaWMgc3RhdGljIE5hbWUgY2FsbGVkTWV0aG9kTmFtZShKQ1RyZWUgdHJlZSkgewogICAgICAgIGlmICh0cmVlLmhhc1RhZyhFWEVDKSkgewogICAgICAgICAgICBKQ0V4cHJlc3Npb25TdGF0ZW1lbnQgZXhlYyA9IChKQ0V4cHJlc3Npb25TdGF0ZW1lbnQpdHJlZTsKICAgICAgICAgICAgaWYgKGV4ZWMuZXhwci5oYXNUYWcoQVBQTFkpKSB7CiAgICAgICAgICAgICAgICBOYW1lIG1uYW1lID0gVHJlZUluZm8ubmFtZSgoKEpDTWV0aG9kSW52b2NhdGlvbikgZXhlYy5leHByKS5tZXRoKTsKICAgICAgICAgICAgICAgIHJldHVybiBtbmFtZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICAvKiogSXMgdGhpcyBhIGNhbGwgdG8gdGhpcyBvciBzdXBlcj8KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzU2VsZkNhbGwoSkNUcmVlIHRyZWUpIHsKICAgICAgICBOYW1lIG5hbWUgPSBjYWxsZWRNZXRob2ROYW1lKHRyZWUpOwogICAgICAgIGlmIChuYW1lICE9IG51bGwpIHsKICAgICAgICAgICAgTmFtZXMgbmFtZXMgPSBuYW1lLnRhYmxlLm5hbWVzOwogICAgICAgICAgICByZXR1cm4gbmFtZT09bmFtZXMuX3RoaXMgfHwgbmFtZT09bmFtZXMuX3N1cGVyOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICB9CgogICAgLyoqIElzIHRoaXMgYSBjYWxsIHRvIHN1cGVyPwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNTdXBlckNhbGwoSkNUcmVlIHRyZWUpIHsKICAgICAgICBOYW1lIG5hbWUgPSBjYWxsZWRNZXRob2ROYW1lKHRyZWUpOwogICAgICAgIGlmIChuYW1lICE9IG51bGwpIHsKICAgICAgICAgICAgTmFtZXMgbmFtZXMgPSBuYW1lLnRhYmxlLm5hbWVzOwogICAgICAgICAgICByZXR1cm4gbmFtZT09bmFtZXMuX3N1cGVyOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICB9CgogICAgLyoqIElzIHRoaXMgYSBjb25zdHJ1Y3RvciB3aG9zZSBmaXJzdCAobm9uLXN5bnRoZXRpYykgc3RhdGVtZW50IGlzIG5vdAogICAgICogIG9mIHRoZSBmb3JtIHRoaXMoLi4uKT8KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzSW5pdGlhbENvbnN0cnVjdG9yKEpDVHJlZSB0cmVlKSB7CiAgICAgICAgSkNNZXRob2RJbnZvY2F0aW9uIGFwcCA9IGZpcnN0Q29uc3RydWN0b3JDYWxsKHRyZWUpOwogICAgICAgIGlmIChhcHAgPT0gbnVsbCkgcmV0dXJuIGZhbHNlOwogICAgICAgIE5hbWUgbWV0aCA9IG5hbWUoYXBwLm1ldGgpOwogICAgICAgIHJldHVybiBtZXRoID09IG51bGwgfHwgbWV0aCAhPSBtZXRoLnRhYmxlLm5hbWVzLl90aGlzOwogICAgfQoKICAgIC8qKiBSZXR1cm4gdGhlIGZpcnN0IGNhbGwgaW4gYSBjb25zdHJ1Y3RvciBkZWZpbml0aW9uLiAqLwogICAgcHVibGljIHN0YXRpYyBKQ01ldGhvZEludm9jYXRpb24gZmlyc3RDb25zdHJ1Y3RvckNhbGwoSkNUcmVlIHRyZWUpIHsKICAgICAgICBpZiAoIXRyZWUuaGFzVGFnKE1FVEhPRERFRikpIHJldHVybiBudWxsOwogICAgICAgIEpDTWV0aG9kRGVjbCBtZCA9IChKQ01ldGhvZERlY2wpIHRyZWU7CiAgICAgICAgTmFtZXMgbmFtZXMgPSBtZC5uYW1lLnRhYmxlLm5hbWVzOwogICAgICAgIGlmIChtZC5uYW1lICE9IG5hbWVzLmluaXQpIHJldHVybiBudWxsOwogICAgICAgIGlmIChtZC5ib2R5ID09IG51bGwpIHJldHVybiBudWxsOwogICAgICAgIExpc3Q8SkNTdGF0ZW1lbnQ+IHN0YXRzID0gbWQuYm9keS5zdGF0czsKICAgICAgICAvLyBTeW50aGV0aWMgaW5pdGlhbGl6YXRpb25zIGNhbiBhcHBlYXIgYmVmb3JlIHRoZSBzdXBlciBjYWxsLgogICAgICAgIHdoaWxlIChzdGF0cy5ub25FbXB0eSgpICYmIGlzU3ludGhldGljSW5pdChzdGF0cy5oZWFkKSkKICAgICAgICAgICAgc3RhdHMgPSBzdGF0cy50YWlsOwogICAgICAgIGlmIChzdGF0cy5pc0VtcHR5KCkpIHJldHVybiBudWxsOwogICAgICAgIGlmICghc3RhdHMuaGVhZC5oYXNUYWcoRVhFQykpIHJldHVybiBudWxsOwogICAgICAgIEpDRXhwcmVzc2lvblN0YXRlbWVudCBleGVjID0gKEpDRXhwcmVzc2lvblN0YXRlbWVudCkgc3RhdHMuaGVhZDsKICAgICAgICBpZiAoIWV4ZWMuZXhwci5oYXNUYWcoQVBQTFkpKSByZXR1cm4gbnVsbDsKICAgICAgICByZXR1cm4gKEpDTWV0aG9kSW52b2NhdGlvbilleGVjLmV4cHI7CiAgICB9CgogICAgLyoqIFJldHVybiB0cnVlIGlmIGEgdHJlZSByZXByZXNlbnRzIGEgZGlhbW9uZCBuZXcgZXhwci4gKi8KICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc0RpYW1vbmQoSkNUcmVlIHRyZWUpIHsKICAgICAgICBzd2l0Y2godHJlZS5nZXRUYWcoKSkgewogICAgICAgICAgICBjYXNlIFRZUEVBUFBMWTogcmV0dXJuICgoSkNUeXBlQXBwbHkpdHJlZSkuZ2V0VHlwZUFyZ3VtZW50cygpLmlzRW1wdHkoKTsKICAgICAgICAgICAgY2FzZSBORVdDTEFTUzogcmV0dXJuIGlzRGlhbW9uZCgoKEpDTmV3Q2xhc3MpdHJlZSkuY2xhenopOwogICAgICAgICAgICBjYXNlIEFOTk9UQVRFRF9UWVBFOiByZXR1cm4gaXNEaWFtb25kKCgoSkNBbm5vdGF0ZWRUeXBlKXRyZWUpLnVuZGVybHlpbmdUeXBlKTsKICAgICAgICAgICAgZGVmYXVsdDogcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgIH0KCiAgICAvKiogUmV0dXJuIHRydWUgaWYgdGhlIGdpdmVuIHRyZWUgcmVwcmVzZW50cyBhIHR5cGUgZWxpZGVkIGFub255bW91cyBjbGFzcyBpbnN0YW5jZSBjcmVhdGlvbi4gKi8KICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc0Fub255bW91c0RpYW1vbmQoSkNUcmVlIHRyZWUpIHsKICAgICAgICBzd2l0Y2godHJlZS5nZXRUYWcoKSkgewogICAgICAgICAgICBjYXNlIE5FV0NMQVNTOiAgewogICAgICAgICAgICAgICAgSkNOZXdDbGFzcyBuYyA9IChKQ05ld0NsYXNzKXRyZWU7CiAgICAgICAgICAgICAgICByZXR1cm4gbmMuZGVmICE9IG51bGwgJiYgaXNEaWFtb25kKG5jLmNsYXp6KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBjYXNlIEFOTk9UQVRFRF9UWVBFOiByZXR1cm4gaXNBbm9ueW1vdXNEaWFtb25kKCgoSkNBbm5vdGF0ZWRUeXBlKXRyZWUpLnVuZGVybHlpbmdUeXBlKTsKICAgICAgICAgICAgZGVmYXVsdDogcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNFbnVtSW5pdChKQ1RyZWUgdHJlZSkgewogICAgICAgIHN3aXRjaCAodHJlZS5nZXRUYWcoKSkgewogICAgICAgICAgICBjYXNlIFZBUkRFRjoKICAgICAgICAgICAgICAgIHJldHVybiAoKChKQ1ZhcmlhYmxlRGVjbCl0cmVlKS5tb2RzLmZsYWdzICYgRU5VTSkgIT0gMDsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICB9CgogICAgLyoqIHNldCAncG9seUtpbmQnIG9uIGdpdmVuIHRyZWUgKi8KICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBzZXRQb2x5S2luZChKQ1RyZWUgdHJlZSwgUG9seUtpbmQgcGtpbmQpIHsKICAgICAgICBzd2l0Y2ggKHRyZWUuZ2V0VGFnKCkpIHsKICAgICAgICAgICAgY2FzZSBBUFBMWToKICAgICAgICAgICAgICAgICgoSkNNZXRob2RJbnZvY2F0aW9uKXRyZWUpLnBvbHlLaW5kID0gcGtpbmQ7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBORVdDTEFTUzoKICAgICAgICAgICAgICAgICgoSkNOZXdDbGFzcyl0cmVlKS5wb2x5S2luZCA9IHBraW5kOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgUkVGRVJFTkNFOgogICAgICAgICAgICAgICAgKChKQ01lbWJlclJlZmVyZW5jZSl0cmVlKS5yZWZQb2x5S2luZCA9IHBraW5kOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoIlVuZXhwZWN0ZWQgdHJlZTogIiArIHRyZWUpOwogICAgICAgIH0KICAgIH0KCiAgICAvKiogc2V0ICd2YXJhcmdzRWxlbWVudCcgb24gZ2l2ZW4gdHJlZSAqLwogICAgcHVibGljIHN0YXRpYyB2b2lkIHNldFZhcmFyZ3NFbGVtZW50KEpDVHJlZSB0cmVlLCBUeXBlIHZhcmFyZ3NFbGVtZW50KSB7CiAgICAgICAgc3dpdGNoICh0cmVlLmdldFRhZygpKSB7CiAgICAgICAgICAgIGNhc2UgQVBQTFk6CiAgICAgICAgICAgICAgICAoKEpDTWV0aG9kSW52b2NhdGlvbil0cmVlKS52YXJhcmdzRWxlbWVudCA9IHZhcmFyZ3NFbGVtZW50OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgTkVXQ0xBU1M6CiAgICAgICAgICAgICAgICAoKEpDTmV3Q2xhc3MpdHJlZSkudmFyYXJnc0VsZW1lbnQgPSB2YXJhcmdzRWxlbWVudDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFJFRkVSRU5DRToKICAgICAgICAgICAgICAgICgoSkNNZW1iZXJSZWZlcmVuY2UpdHJlZSkudmFyYXJnc0VsZW1lbnQgPSB2YXJhcmdzRWxlbWVudDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCJVbmV4cGVjdGVkIHRyZWU6ICIgKyB0cmVlKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqIFJldHVybiB0cnVlIGlmIHRoZSB0cmVlIGNvcnJlc3BvbmRzIHRvIGFuIGV4cHJlc3Npb24gc3RhdGVtZW50ICovCiAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNFeHByZXNzaW9uU3RhdGVtZW50KEpDRXhwcmVzc2lvbiB0cmVlKSB7CiAgICAgICAgc3dpdGNoKHRyZWUuZ2V0VGFnKCkpIHsKICAgICAgICAgICAgY2FzZSBQUkVJTkM6IGNhc2UgUFJFREVDOgogICAgICAgICAgICBjYXNlIFBPU1RJTkM6IGNhc2UgUE9TVERFQzoKICAgICAgICAgICAgY2FzZSBBU1NJR046CiAgICAgICAgICAgIGNhc2UgQklUT1JfQVNHOiBjYXNlIEJJVFhPUl9BU0c6IGNhc2UgQklUQU5EX0FTRzoKICAgICAgICAgICAgY2FzZSBTTF9BU0c6IGNhc2UgU1JfQVNHOiBjYXNlIFVTUl9BU0c6CiAgICAgICAgICAgIGNhc2UgUExVU19BU0c6IGNhc2UgTUlOVVNfQVNHOgogICAgICAgICAgICBjYXNlIE1VTF9BU0c6IGNhc2UgRElWX0FTRzogY2FzZSBNT0RfQVNHOgogICAgICAgICAgICBjYXNlIEFQUExZOiBjYXNlIE5FV0NMQVNTOgogICAgICAgICAgICBjYXNlIEVSUk9ORU9VUzoKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgIH0KCiAgICAvKiogUmV0dXJuIHRydWUgaWYgdGhlIHRyZWUgY29ycmVzcG9uZHMgdG8gYSBzdGF0ZW1lbnQgKi8KICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc1N0YXRlbWVudChKQ1RyZWUgdHJlZSkgewogICAgICAgIHJldHVybiAodHJlZSBpbnN0YW5jZW9mIEpDU3RhdGVtZW50KSAmJgogICAgICAgICAgICAgICAgIXRyZWUuaGFzVGFnKENMQVNTREVGKSAmJgogICAgICAgICAgICAgICAgIXRyZWUuaGFzVGFnKFRhZy5CTE9DSykgJiYKICAgICAgICAgICAgICAgICF0cmVlLmhhc1RhZyhNRVRIT0RERUYpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJuIHRydWUgaWYgdGhlIEFTVCBjb3JyZXNwb25kcyB0byBhIHN0YXRpYyBzZWxlY3Qgb2YgdGhlIGtpbmQgQS5CCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc1N0YXRpY1NlbGVjdG9yKEpDVHJlZSBiYXNlLCBOYW1lcyBuYW1lcykgewogICAgICAgIGlmIChiYXNlID09IG51bGwpCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICBzd2l0Y2ggKGJhc2UuZ2V0VGFnKCkpIHsKICAgICAgICAgICAgY2FzZSBJREVOVDoKICAgICAgICAgICAgICAgIEpDSWRlbnQgaWQgPSAoSkNJZGVudCliYXNlOwogICAgICAgICAgICAgICAgcmV0dXJuIGlkLm5hbWUgIT0gbmFtZXMuX3RoaXMgJiYKICAgICAgICAgICAgICAgICAgICAgICAgaWQubmFtZSAhPSBuYW1lcy5fc3VwZXIgJiYKICAgICAgICAgICAgICAgICAgICAgICAgaXNTdGF0aWNTeW0oYmFzZSk7CiAgICAgICAgICAgIGNhc2UgU0VMRUNUOgogICAgICAgICAgICAgICAgcmV0dXJuIGlzU3RhdGljU3ltKGJhc2UpICYmCiAgICAgICAgICAgICAgICAgICAgaXNTdGF0aWNTZWxlY3RvcigoKEpDRmllbGRBY2Nlc3MpYmFzZSkuc2VsZWN0ZWQsIG5hbWVzKTsKICAgICAgICAgICAgY2FzZSBUWVBFQVBQTFk6CiAgICAgICAgICAgIGNhc2UgVFlQRUFSUkFZOgogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIGNhc2UgQU5OT1RBVEVEX1RZUEU6CiAgICAgICAgICAgICAgICByZXR1cm4gaXNTdGF0aWNTZWxlY3RvcigoKEpDQW5ub3RhdGVkVHlwZSliYXNlKS51bmRlcmx5aW5nVHlwZSwgbmFtZXMpOwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgIH0KICAgIC8vd2hlcmUKICAgICAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGlzU3RhdGljU3ltKEpDVHJlZSB0cmVlKSB7CiAgICAgICAgICAgIFN5bWJvbCBzeW0gPSBzeW1ib2wodHJlZSk7CiAgICAgICAgICAgIHJldHVybiAoc3ltLmtpbmQgPT0gVFlQIHx8IHN5bS5raW5kID09IFBDSyk7CiAgICAgICAgfQoKICAgIC8qKiBSZXR1cm4gdHJ1ZSBpZiBhIHRyZWUgcmVwcmVzZW50cyB0aGUgbnVsbCBsaXRlcmFsLiAqLwogICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzTnVsbChKQ1RyZWUgdHJlZSkgewogICAgICAgIGlmICghdHJlZS5oYXNUYWcoTElURVJBTCkpCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICBKQ0xpdGVyYWwgbGl0ID0gKEpDTGl0ZXJhbCkgdHJlZTsKICAgICAgICByZXR1cm4gKGxpdC50eXBldGFnID09IEJPVCk7CiAgICB9CgogICAgLyoqIFJldHVybiB0cnVlIGlmZiB0aGlzIHRyZWUgaXMgYSBjaGlsZCBvZiBzb21lIGFubm90YXRpb24uICovCiAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNJbkFubm90YXRpb24oRW52PD8+IGVudiwgSkNUcmVlIHRyZWUpIHsKICAgICAgICBUcmVlUGF0aCB0cCA9IFRyZWVQYXRoLmdldFBhdGgoZW52LnRvcGxldmVsLCB0cmVlKTsKICAgICAgICBpZiAodHAgIT0gbnVsbCkgewogICAgICAgICAgICBmb3IgKFRyZWUgdCA6IHRwKSB7CiAgICAgICAgICAgICAgICBpZiAodC5nZXRLaW5kKCkgPT0gVHJlZS5LaW5kLkFOTk9UQVRJT04pCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldENvbW1lbnRUZXh0KEVudjw/PiBlbnYsIEpDVHJlZSB0cmVlKSB7CiAgICAgICAgRG9jQ29tbWVudFRhYmxlIGRvY0NvbW1lbnRzID0gKHRyZWUuaGFzVGFnKEpDVHJlZS5UYWcuVE9QTEVWRUwpKQogICAgICAgICAgICAgICAgPyAoKEpDQ29tcGlsYXRpb25Vbml0KSB0cmVlKS5kb2NDb21tZW50cwogICAgICAgICAgICAgICAgOiBlbnYudG9wbGV2ZWwuZG9jQ29tbWVudHM7CiAgICAgICAgcmV0dXJuIChkb2NDb21tZW50cyA9PSBudWxsKSA/IG51bGwgOiBkb2NDb21tZW50cy5nZXRDb21tZW50VGV4dCh0cmVlKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIERDVHJlZS5EQ0RvY0NvbW1lbnQgZ2V0Q29tbWVudFRyZWUoRW52PD8+IGVudiwgSkNUcmVlIHRyZWUpIHsKICAgICAgICBEb2NDb21tZW50VGFibGUgZG9jQ29tbWVudHMgPSAodHJlZS5oYXNUYWcoSkNUcmVlLlRhZy5UT1BMRVZFTCkpCiAgICAgICAgICAgICAgICA/ICgoSkNDb21waWxhdGlvblVuaXQpIHRyZWUpLmRvY0NvbW1lbnRzCiAgICAgICAgICAgICAgICA6IGVudi50b3BsZXZlbC5kb2NDb21tZW50czsKICAgICAgICByZXR1cm4gKGRvY0NvbW1lbnRzID09IG51bGwpID8gbnVsbCA6IGRvY0NvbW1lbnRzLmdldENvbW1lbnRUcmVlKHRyZWUpOwogICAgfQoKICAgIC8qKiBUaGUgcG9zaXRpb24gb2YgdGhlIGZpcnN0IHN0YXRlbWVudCBpbiBhIGJsb2NrLCBvciB0aGUgcG9zaXRpb24gb2YKICAgICAqICB0aGUgYmxvY2sgaXRzZWxmIGlmIGl0IGlzIGVtcHR5LgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGludCBmaXJzdFN0YXRQb3MoSkNUcmVlIHRyZWUpIHsKICAgICAgICBpZiAodHJlZS5oYXNUYWcoQkxPQ0spICYmICgoSkNCbG9jaykgdHJlZSkuc3RhdHMubm9uRW1wdHkoKSkKICAgICAgICAgICAgcmV0dXJuICgoSkNCbG9jaykgdHJlZSkuc3RhdHMuaGVhZC5wb3M7CiAgICAgICAgZWxzZQogICAgICAgICAgICByZXR1cm4gdHJlZS5wb3M7CiAgICB9CgogICAgLyoqIFRoZSBlbmQgcG9zaXRpb24gb2YgZ2l2ZW4gdHJlZSwgaWYgaXQgaXMgYSBibG9jayB3aXRoCiAgICAgKiAgZGVmaW5lZCBlbmRwb3MuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgaW50IGVuZFBvcyhKQ1RyZWUgdHJlZSkgewogICAgICAgIGlmICh0cmVlLmhhc1RhZyhCTE9DSykgJiYgKChKQ0Jsb2NrKSB0cmVlKS5lbmRwb3MgIT0gUG9zaXRpb24uTk9QT1MpCiAgICAgICAgICAgIHJldHVybiAoKEpDQmxvY2spIHRyZWUpLmVuZHBvczsKICAgICAgICBlbHNlIGlmICh0cmVlLmhhc1RhZyhTWU5DSFJPTklaRUQpKQogICAgICAgICAgICByZXR1cm4gZW5kUG9zKCgoSkNTeW5jaHJvbml6ZWQpIHRyZWUpLmJvZHkpOwogICAgICAgIGVsc2UgaWYgKHRyZWUuaGFzVGFnKFRSWSkpIHsKICAgICAgICAgICAgSkNUcnkgdCA9IChKQ1RyeSkgdHJlZTsKICAgICAgICAgICAgcmV0dXJuIGVuZFBvcygodC5maW5hbGl6ZXIgIT0gbnVsbCkgPyB0LmZpbmFsaXplcgogICAgICAgICAgICAgICAgICAgICAgICAgIDogKHQuY2F0Y2hlcnMubm9uRW1wdHkoKSA/IHQuY2F0Y2hlcnMubGFzdCgpLmJvZHkgOiB0LmJvZHkpKTsKICAgICAgICB9IGVsc2UKICAgICAgICAgICAgcmV0dXJuIHRyZWUucG9zOwogICAgfQoKCiAgICAvKiogR2V0IHRoZSBzdGFydCBwb3NpdGlvbiBmb3IgYSB0cmVlIG5vZGUuICBUaGUgc3RhcnQgcG9zaXRpb24gaXMKICAgICAqIGRlZmluZWQgdG8gYmUgdGhlIHBvc2l0aW9uIG9mIHRoZSBmaXJzdCBjaGFyYWN0ZXIgb2YgdGhlIGZpcnN0CiAgICAgKiB0b2tlbiBvZiB0aGUgbm9kZSdzIHNvdXJjZSB0ZXh0LgogICAgICogQHBhcmFtIHRyZWUgIFRoZSB0cmVlIG5vZGUKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBpbnQgZ2V0U3RhcnRQb3MoSkNUcmVlIHRyZWUpIHsKICAgICAgICBpZiAodHJlZSA9PSBudWxsKQogICAgICAgICAgICByZXR1cm4gUG9zaXRpb24uTk9QT1M7CgogICAgICAgIHN3aXRjaCh0cmVlLmdldFRhZygpKSB7CiAgICAgICAgICAgIGNhc2UgTU9EVUxFREVGOiB7CiAgICAgICAgICAgICAgICBKQ01vZHVsZURlY2wgbWQgPSAoSkNNb2R1bGVEZWNsKXRyZWU7CiAgICAgICAgICAgICAgICByZXR1cm4gbWQubW9kcy5hbm5vdGF0aW9ucy5pc0VtcHR5KCkgPyBtZC5wb3MgOgogICAgICAgICAgICAgICAgICAgICAgIG1kLm1vZHMuYW5ub3RhdGlvbnMuaGVhZC5wb3M7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY2FzZSBQQUNLQUdFREVGOiB7CiAgICAgICAgICAgICAgICBKQ1BhY2thZ2VEZWNsIHBkID0gKEpDUGFja2FnZURlY2wpdHJlZTsKICAgICAgICAgICAgICAgIHJldHVybiBwZC5hbm5vdGF0aW9ucy5pc0VtcHR5KCkgPyBwZC5wb3MgOgogICAgICAgICAgICAgICAgICAgICAgIHBkLmFubm90YXRpb25zLmhlYWQucG9zOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGNhc2UgQVBQTFk6CiAgICAgICAgICAgICAgICByZXR1cm4gZ2V0U3RhcnRQb3MoKChKQ01ldGhvZEludm9jYXRpb24pIHRyZWUpLm1ldGgpOwogICAgICAgICAgICBjYXNlIEFTU0lHTjoKICAgICAgICAgICAgICAgIHJldHVybiBnZXRTdGFydFBvcygoKEpDQXNzaWduKSB0cmVlKS5saHMpOwogICAgICAgICAgICBjYXNlIEJJVE9SX0FTRzogY2FzZSBCSVRYT1JfQVNHOiBjYXNlIEJJVEFORF9BU0c6CiAgICAgICAgICAgIGNhc2UgU0xfQVNHOiBjYXNlIFNSX0FTRzogY2FzZSBVU1JfQVNHOgogICAgICAgICAgICBjYXNlIFBMVVNfQVNHOiBjYXNlIE1JTlVTX0FTRzogY2FzZSBNVUxfQVNHOgogICAgICAgICAgICBjYXNlIERJVl9BU0c6IGNhc2UgTU9EX0FTRzoKICAgICAgICAgICAgY2FzZSBPUjogY2FzZSBBTkQ6IGNhc2UgQklUT1I6CiAgICAgICAgICAgIGNhc2UgQklUWE9SOiBjYXNlIEJJVEFORDogY2FzZSBFUToKICAgICAgICAgICAgY2FzZSBORTogY2FzZSBMVDogY2FzZSBHVDoKICAgICAgICAgICAgY2FzZSBMRTogY2FzZSBHRTogY2FzZSBTTDoKICAgICAgICAgICAgY2FzZSBTUjogY2FzZSBVU1I6IGNhc2UgUExVUzoKICAgICAgICAgICAgY2FzZSBNSU5VUzogY2FzZSBNVUw6IGNhc2UgRElWOgogICAgICAgICAgICBjYXNlIE1PRDoKICAgICAgICAgICAgY2FzZSBQT1NUSU5DOgogICAgICAgICAgICBjYXNlIFBPU1RERUM6CiAgICAgICAgICAgICAgICByZXR1cm4gZ2V0U3RhcnRQb3MoKChKQ09wZXJhdG9yRXhwcmVzc2lvbikgdHJlZSkuZ2V0T3BlcmFuZChMRUZUKSk7CiAgICAgICAgICAgIGNhc2UgQ0xBU1NERUY6IHsKICAgICAgICAgICAgICAgIEpDQ2xhc3NEZWNsIG5vZGUgPSAoSkNDbGFzc0RlY2wpdHJlZTsKICAgICAgICAgICAgICAgIGlmIChub2RlLm1vZHMucG9zICE9IFBvc2l0aW9uLk5PUE9TKQogICAgICAgICAgICAgICAgICAgIHJldHVybiBub2RlLm1vZHMucG9zOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY2FzZSBDT05ERVhQUjoKICAgICAgICAgICAgICAgIHJldHVybiBnZXRTdGFydFBvcygoKEpDQ29uZGl0aW9uYWwpIHRyZWUpLmNvbmQpOwogICAgICAgICAgICBjYXNlIEVYRUM6CiAgICAgICAgICAgICAgICByZXR1cm4gZ2V0U3RhcnRQb3MoKChKQ0V4cHJlc3Npb25TdGF0ZW1lbnQpIHRyZWUpLmV4cHIpOwogICAgICAgICAgICBjYXNlIElOREVYRUQ6CiAgICAgICAgICAgICAgICByZXR1cm4gZ2V0U3RhcnRQb3MoKChKQ0FycmF5QWNjZXNzKSB0cmVlKS5pbmRleGVkKTsKICAgICAgICAgICAgY2FzZSBNRVRIT0RERUY6IHsKICAgICAgICAgICAgICAgIEpDTWV0aG9kRGVjbCBub2RlID0gKEpDTWV0aG9kRGVjbCl0cmVlOwogICAgICAgICAgICAgICAgaWYgKG5vZGUubW9kcy5wb3MgIT0gUG9zaXRpb24uTk9QT1MpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5vZGUubW9kcy5wb3M7CiAgICAgICAgICAgICAgICBpZiAobm9kZS50eXBhcmFtcy5ub25FbXB0eSgpKSAvLyBMaXN0Lm5pbCgpIHVzZWQgZm9yIG5vIHR5cGFyYW1zCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGdldFN0YXJ0UG9zKG5vZGUudHlwYXJhbXMuaGVhZCk7CiAgICAgICAgICAgICAgICByZXR1cm4gbm9kZS5yZXN0eXBlID09IG51bGwgPyBub2RlLnBvcyA6IGdldFN0YXJ0UG9zKG5vZGUucmVzdHlwZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY2FzZSBTRUxFQ1Q6CiAgICAgICAgICAgICAgICByZXR1cm4gZ2V0U3RhcnRQb3MoKChKQ0ZpZWxkQWNjZXNzKSB0cmVlKS5zZWxlY3RlZCk7CiAgICAgICAgICAgIGNhc2UgVFlQRUFQUExZOgogICAgICAgICAgICAgICAgcmV0dXJuIGdldFN0YXJ0UG9zKCgoSkNUeXBlQXBwbHkpIHRyZWUpLmNsYXp6KTsKICAgICAgICAgICAgY2FzZSBUWVBFQVJSQVk6CiAgICAgICAgICAgICAgICByZXR1cm4gZ2V0U3RhcnRQb3MoKChKQ0FycmF5VHlwZVRyZWUpIHRyZWUpLmVsZW10eXBlKTsKICAgICAgICAgICAgY2FzZSBUWVBFVEVTVDoKICAgICAgICAgICAgICAgIHJldHVybiBnZXRTdGFydFBvcygoKEpDSW5zdGFuY2VPZikgdHJlZSkuZXhwcik7CiAgICAgICAgICAgIGNhc2UgQU5OT1RBVEVEX1RZUEU6IHsKICAgICAgICAgICAgICAgIEpDQW5ub3RhdGVkVHlwZSBub2RlID0gKEpDQW5ub3RhdGVkVHlwZSkgdHJlZTsKICAgICAgICAgICAgICAgIGlmIChub2RlLmFubm90YXRpb25zLm5vbkVtcHR5KCkpIHsKICAgICAgICAgICAgICAgICAgICBpZiAobm9kZS51bmRlcmx5aW5nVHlwZS5oYXNUYWcoVFlQRUFSUkFZKSB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZS51bmRlcmx5aW5nVHlwZS5oYXNUYWcoU0VMRUNUKSkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZ2V0U3RhcnRQb3Mobm9kZS51bmRlcmx5aW5nVHlwZSk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGdldFN0YXJ0UG9zKG5vZGUuYW5ub3RhdGlvbnMuaGVhZCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZ2V0U3RhcnRQb3Mobm9kZS51bmRlcmx5aW5nVHlwZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY2FzZSBORVdDTEFTUzogewogICAgICAgICAgICAgICAgSkNOZXdDbGFzcyBub2RlID0gKEpDTmV3Q2xhc3MpdHJlZTsKICAgICAgICAgICAgICAgIGlmIChub2RlLmVuY2wgIT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZ2V0U3RhcnRQb3Mobm9kZS5lbmNsKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGNhc2UgVkFSREVGOiB7CiAgICAgICAgICAgICAgICBKQ1ZhcmlhYmxlRGVjbCBub2RlID0gKEpDVmFyaWFibGVEZWNsKXRyZWU7CiAgICAgICAgICAgICAgICBpZiAobm9kZS5tb2RzLnBvcyAhPSBQb3NpdGlvbi5OT1BPUykgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBub2RlLm1vZHMucG9zOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChub2RlLnZhcnR5cGUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIC8vaWYgdGhlcmUncyBubyB0eXBlIChwYXJ0aWFsbHkgdHlwZWQgbGFtYmRhIHBhcmFtZXRlcikKICAgICAgICAgICAgICAgICAgICAvL3NpbXBseSByZXR1cm4gbm9kZSBwb3NpdGlvbgogICAgICAgICAgICAgICAgICAgIHJldHVybiBub2RlLnBvczsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGdldFN0YXJ0UG9zKG5vZGUudmFydHlwZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY2FzZSBFUlJPTkVPVVM6IHsKICAgICAgICAgICAgICAgIEpDRXJyb25lb3VzIG5vZGUgPSAoSkNFcnJvbmVvdXMpdHJlZTsKICAgICAgICAgICAgICAgIGlmIChub2RlLmVycnMgIT0gbnVsbCAmJiBub2RlLmVycnMubm9uRW1wdHkoKSkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZ2V0U3RhcnRQb3Mobm9kZS5lcnJzLmhlYWQpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiB0cmVlLnBvczsKICAgIH0KCiAgICAvKiogVGhlIGVuZCBwb3NpdGlvbiBvZiBnaXZlbiB0cmVlLCBnaXZlbiAgYSB0YWJsZSBvZiBlbmQgcG9zaXRpb25zIGdlbmVyYXRlZCBieSB0aGUgcGFyc2VyCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgaW50IGdldEVuZFBvcyhKQ1RyZWUgdHJlZSwgRW5kUG9zVGFibGUgZW5kUG9zVGFibGUpIHsKICAgICAgICBpZiAodHJlZSA9PSBudWxsKQogICAgICAgICAgICByZXR1cm4gUG9zaXRpb24uTk9QT1M7CgogICAgICAgIGlmIChlbmRQb3NUYWJsZSA9PSBudWxsKSB7CiAgICAgICAgICAgIC8vIGZhbGwgYmFjayBvbiBsaW1pdGVkIGluZm8gaW4gdGhlIHRyZWUKICAgICAgICAgICAgcmV0dXJuIGVuZFBvcyh0cmVlKTsKICAgICAgICB9CgogICAgICAgIGludCBtYXBQb3MgPSBlbmRQb3NUYWJsZS5nZXRFbmRQb3ModHJlZSk7CiAgICAgICAgaWYgKG1hcFBvcyAhPSBQb3NpdGlvbi5OT1BPUykKICAgICAgICAgICAgcmV0dXJuIG1hcFBvczsKCiAgICAgICAgc3dpdGNoKHRyZWUuZ2V0VGFnKCkpIHsKICAgICAgICAgICAgY2FzZSBCSVRPUl9BU0c6IGNhc2UgQklUWE9SX0FTRzogY2FzZSBCSVRBTkRfQVNHOgogICAgICAgICAgICBjYXNlIFNMX0FTRzogY2FzZSBTUl9BU0c6IGNhc2UgVVNSX0FTRzoKICAgICAgICAgICAgY2FzZSBQTFVTX0FTRzogY2FzZSBNSU5VU19BU0c6IGNhc2UgTVVMX0FTRzoKICAgICAgICAgICAgY2FzZSBESVZfQVNHOiBjYXNlIE1PRF9BU0c6CiAgICAgICAgICAgIGNhc2UgT1I6IGNhc2UgQU5EOiBjYXNlIEJJVE9SOgogICAgICAgICAgICBjYXNlIEJJVFhPUjogY2FzZSBCSVRBTkQ6IGNhc2UgRVE6CiAgICAgICAgICAgIGNhc2UgTkU6IGNhc2UgTFQ6IGNhc2UgR1Q6CiAgICAgICAgICAgIGNhc2UgTEU6IGNhc2UgR0U6IGNhc2UgU0w6CiAgICAgICAgICAgIGNhc2UgU1I6IGNhc2UgVVNSOiBjYXNlIFBMVVM6CiAgICAgICAgICAgIGNhc2UgTUlOVVM6IGNhc2UgTVVMOiBjYXNlIERJVjoKICAgICAgICAgICAgY2FzZSBNT0Q6CiAgICAgICAgICAgIGNhc2UgUE9TOgogICAgICAgICAgICBjYXNlIE5FRzoKICAgICAgICAgICAgY2FzZSBOT1Q6CiAgICAgICAgICAgIGNhc2UgQ09NUEw6CiAgICAgICAgICAgIGNhc2UgUFJFSU5DOgogICAgICAgICAgICBjYXNlIFBSRURFQzoKICAgICAgICAgICAgICAgIHJldHVybiBnZXRFbmRQb3MoKChKQ09wZXJhdG9yRXhwcmVzc2lvbikgdHJlZSkuZ2V0T3BlcmFuZChSSUdIVCksIGVuZFBvc1RhYmxlKTsKICAgICAgICAgICAgY2FzZSBDQVNFOgogICAgICAgICAgICAgICAgcmV0dXJuIGdldEVuZFBvcygoKEpDQ2FzZSkgdHJlZSkuc3RhdHMubGFzdCgpLCBlbmRQb3NUYWJsZSk7CiAgICAgICAgICAgIGNhc2UgQ0FUQ0g6CiAgICAgICAgICAgICAgICByZXR1cm4gZ2V0RW5kUG9zKCgoSkNDYXRjaCkgdHJlZSkuYm9keSwgZW5kUG9zVGFibGUpOwogICAgICAgICAgICBjYXNlIENPTkRFWFBSOgogICAgICAgICAgICAgICAgcmV0dXJuIGdldEVuZFBvcygoKEpDQ29uZGl0aW9uYWwpIHRyZWUpLmZhbHNlcGFydCwgZW5kUG9zVGFibGUpOwogICAgICAgICAgICBjYXNlIEZPUkxPT1A6CiAgICAgICAgICAgICAgICByZXR1cm4gZ2V0RW5kUG9zKCgoSkNGb3JMb29wKSB0cmVlKS5ib2R5LCBlbmRQb3NUYWJsZSk7CiAgICAgICAgICAgIGNhc2UgRk9SRUFDSExPT1A6CiAgICAgICAgICAgICAgICByZXR1cm4gZ2V0RW5kUG9zKCgoSkNFbmhhbmNlZEZvckxvb3ApIHRyZWUpLmJvZHksIGVuZFBvc1RhYmxlKTsKICAgICAgICAgICAgY2FzZSBJRjogewogICAgICAgICAgICAgICAgSkNJZiBub2RlID0gKEpDSWYpdHJlZTsKICAgICAgICAgICAgICAgIGlmIChub2RlLmVsc2VwYXJ0ID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZ2V0RW5kUG9zKG5vZGUudGhlbnBhcnQsIGVuZFBvc1RhYmxlKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGdldEVuZFBvcyhub2RlLmVsc2VwYXJ0LCBlbmRQb3NUYWJsZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY2FzZSBMQUJFTExFRDoKICAgICAgICAgICAgICAgIHJldHVybiBnZXRFbmRQb3MoKChKQ0xhYmVsZWRTdGF0ZW1lbnQpIHRyZWUpLmJvZHksIGVuZFBvc1RhYmxlKTsKICAgICAgICAgICAgY2FzZSBNT0RJRklFUlM6CiAgICAgICAgICAgICAgICByZXR1cm4gZ2V0RW5kUG9zKCgoSkNNb2RpZmllcnMpIHRyZWUpLmFubm90YXRpb25zLmxhc3QoKSwgZW5kUG9zVGFibGUpOwogICAgICAgICAgICBjYXNlIFNZTkNIUk9OSVpFRDoKICAgICAgICAgICAgICAgIHJldHVybiBnZXRFbmRQb3MoKChKQ1N5bmNocm9uaXplZCkgdHJlZSkuYm9keSwgZW5kUG9zVGFibGUpOwogICAgICAgICAgICBjYXNlIFRPUExFVkVMOgogICAgICAgICAgICAgICAgcmV0dXJuIGdldEVuZFBvcygoKEpDQ29tcGlsYXRpb25Vbml0KSB0cmVlKS5kZWZzLmxhc3QoKSwgZW5kUG9zVGFibGUpOwogICAgICAgICAgICBjYXNlIFRSWTogewogICAgICAgICAgICAgICAgSkNUcnkgbm9kZSA9IChKQ1RyeSl0cmVlOwogICAgICAgICAgICAgICAgaWYgKG5vZGUuZmluYWxpemVyICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZ2V0RW5kUG9zKG5vZGUuZmluYWxpemVyLCBlbmRQb3NUYWJsZSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCFub2RlLmNhdGNoZXJzLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBnZXRFbmRQb3Mobm9kZS5jYXRjaGVycy5sYXN0KCksIGVuZFBvc1RhYmxlKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGdldEVuZFBvcyhub2RlLmJvZHksIGVuZFBvc1RhYmxlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBjYXNlIFdJTERDQVJEOgogICAgICAgICAgICAgICAgcmV0dXJuIGdldEVuZFBvcygoKEpDV2lsZGNhcmQpIHRyZWUpLmlubmVyLCBlbmRQb3NUYWJsZSk7CiAgICAgICAgICAgIGNhc2UgVFlQRUNBU1Q6CiAgICAgICAgICAgICAgICByZXR1cm4gZ2V0RW5kUG9zKCgoSkNUeXBlQ2FzdCkgdHJlZSkuZXhwciwgZW5kUG9zVGFibGUpOwogICAgICAgICAgICBjYXNlIFRZUEVURVNUOgogICAgICAgICAgICAgICAgcmV0dXJuIGdldEVuZFBvcygoKEpDSW5zdGFuY2VPZikgdHJlZSkuY2xhenosIGVuZFBvc1RhYmxlKTsKICAgICAgICAgICAgY2FzZSBXSElMRUxPT1A6CiAgICAgICAgICAgICAgICByZXR1cm4gZ2V0RW5kUG9zKCgoSkNXaGlsZUxvb3ApIHRyZWUpLmJvZHksIGVuZFBvc1RhYmxlKTsKICAgICAgICAgICAgY2FzZSBBTk5PVEFURURfVFlQRToKICAgICAgICAgICAgICAgIHJldHVybiBnZXRFbmRQb3MoKChKQ0Fubm90YXRlZFR5cGUpIHRyZWUpLnVuZGVybHlpbmdUeXBlLCBlbmRQb3NUYWJsZSk7CiAgICAgICAgICAgIGNhc2UgRVJST05FT1VTOiB7CiAgICAgICAgICAgICAgICBKQ0Vycm9uZW91cyBub2RlID0gKEpDRXJyb25lb3VzKXRyZWU7CiAgICAgICAgICAgICAgICBpZiAobm9kZS5lcnJzICE9IG51bGwgJiYgbm9kZS5lcnJzLm5vbkVtcHR5KCkpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGdldEVuZFBvcyhub2RlLmVycnMubGFzdCgpLCBlbmRQb3NUYWJsZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIFBvc2l0aW9uLk5PUE9TOwogICAgfQoKCiAgICAvKiogQSBEaWFnbm9zdGljUG9zaXRpb24gd2l0aCB0aGUgcHJlZmVycmVkIHBvc2l0aW9uIHNldCB0byB0aGUKICAgICAqICBlbmQgcG9zaXRpb24gb2YgZ2l2ZW4gdHJlZSwgaWYgaXQgaXMgYSBibG9jayB3aXRoCiAgICAgKiAgZGVmaW5lZCBlbmRwb3MuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgRGlhZ25vc3RpY1Bvc2l0aW9uIGRpYWdFbmRQb3MoZmluYWwgSkNUcmVlIHRyZWUpIHsKICAgICAgICBmaW5hbCBpbnQgZW5kUG9zID0gVHJlZUluZm8uZW5kUG9zKHRyZWUpOwogICAgICAgIHJldHVybiBuZXcgRGlhZ25vc3RpY1Bvc2l0aW9uKCkgewogICAgICAgICAgICBwdWJsaWMgSkNUcmVlIGdldFRyZWUoKSB7IHJldHVybiB0cmVlOyB9CiAgICAgICAgICAgIHB1YmxpYyBpbnQgZ2V0U3RhcnRQb3NpdGlvbigpIHsgcmV0dXJuIFRyZWVJbmZvLmdldFN0YXJ0UG9zKHRyZWUpOyB9CiAgICAgICAgICAgIHB1YmxpYyBpbnQgZ2V0UHJlZmVycmVkUG9zaXRpb24oKSB7IHJldHVybiBlbmRQb3M7IH0KICAgICAgICAgICAgcHVibGljIGludCBnZXRFbmRQb3NpdGlvbihFbmRQb3NUYWJsZSBlbmRQb3NUYWJsZSkgewogICAgICAgICAgICAgICAgcmV0dXJuIFRyZWVJbmZvLmdldEVuZFBvcyh0cmVlLCBlbmRQb3NUYWJsZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9OwogICAgfQoKICAgIC8qKiBUaGUgcG9zaXRpb24gb2YgdGhlIGZpbmFsaXplciBvZiBnaXZlbiB0cnkvc3luY2hyb25pemVkIHN0YXRlbWVudC4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBpbnQgZmluYWxpemVyUG9zKEpDVHJlZSB0cmVlKSB7CiAgICAgICAgaWYgKHRyZWUuaGFzVGFnKFRSWSkpIHsKICAgICAgICAgICAgSkNUcnkgdCA9IChKQ1RyeSkgdHJlZTsKICAgICAgICAgICAgQXNzZXJ0LmNoZWNrTm9uTnVsbCh0LmZpbmFsaXplcik7CiAgICAgICAgICAgIHJldHVybiBmaXJzdFN0YXRQb3ModC5maW5hbGl6ZXIpOwogICAgICAgIH0gZWxzZSBpZiAodHJlZS5oYXNUYWcoU1lOQ0hST05JWkVEKSkgewogICAgICAgICAgICByZXR1cm4gZW5kUG9zKCgoSkNTeW5jaHJvbml6ZWQpIHRyZWUpLmJvZHkpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigpOwogICAgICAgIH0KICAgIH0KCiAgICAvKiogRmluZCB0aGUgcG9zaXRpb24gZm9yIHJlcG9ydGluZyBhbiBlcnJvciBhYm91dCBhIHN5bWJvbCwgd2hlcmUKICAgICAqICB0aGF0IHN5bWJvbCBpcyBkZWZpbmVkIHNvbWV3aGVyZSBpbiB0aGUgZ2l2ZW4gdHJlZS4gKi8KICAgIHB1YmxpYyBzdGF0aWMgaW50IHBvc2l0aW9uRm9yKGZpbmFsIFN5bWJvbCBzeW0sIGZpbmFsIEpDVHJlZSB0cmVlKSB7CiAgICAgICAgSkNUcmVlIGRlY2wgPSBkZWNsYXJhdGlvbkZvcihzeW0sIHRyZWUpOwogICAgICAgIHJldHVybiAoKGRlY2wgIT0gbnVsbCkgPyBkZWNsIDogdHJlZSkucG9zOwogICAgfQoKICAgIC8qKiBGaW5kIHRoZSBwb3NpdGlvbiBmb3IgcmVwb3J0aW5nIGFuIGVycm9yIGFib3V0IGEgc3ltYm9sLCB3aGVyZQogICAgICogIHRoYXQgc3ltYm9sIGlzIGRlZmluZWQgc29tZXdoZXJlIGluIHRoZSBnaXZlbiB0cmVlLiAqLwogICAgcHVibGljIHN0YXRpYyBEaWFnbm9zdGljUG9zaXRpb24gZGlhZ25vc3RpY1Bvc2l0aW9uRm9yKGZpbmFsIFN5bWJvbCBzeW0sIGZpbmFsIEpDVHJlZSB0cmVlKSB7CiAgICAgICAgSkNUcmVlIGRlY2wgPSBkZWNsYXJhdGlvbkZvcihzeW0sIHRyZWUpOwogICAgICAgIHJldHVybiAoKGRlY2wgIT0gbnVsbCkgPyBkZWNsIDogdHJlZSkucG9zKCk7CiAgICB9CgogICAgLyoqIEZpbmQgdGhlIGRlY2xhcmF0aW9uIGZvciBhIHN5bWJvbCwgd2hlcmUKICAgICAqICB0aGF0IHN5bWJvbCBpcyBkZWZpbmVkIHNvbWV3aGVyZSBpbiB0aGUgZ2l2ZW4gdHJlZS4gKi8KICAgIHB1YmxpYyBzdGF0aWMgSkNUcmVlIGRlY2xhcmF0aW9uRm9yKGZpbmFsIFN5bWJvbCBzeW0sIGZpbmFsIEpDVHJlZSB0cmVlKSB7CiAgICAgICAgY2xhc3MgRGVjbFNjYW5uZXIgZXh0ZW5kcyBUcmVlU2Nhbm5lciB7CiAgICAgICAgICAgIEpDVHJlZSByZXN1bHQgPSBudWxsOwogICAgICAgICAgICBwdWJsaWMgdm9pZCBzY2FuKEpDVHJlZSB0cmVlKSB7CiAgICAgICAgICAgICAgICBpZiAodHJlZSE9bnVsbCAmJiByZXN1bHQ9PW51bGwpCiAgICAgICAgICAgICAgICAgICAgdHJlZS5hY2NlcHQodGhpcyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcHVibGljIHZvaWQgdmlzaXRUb3BMZXZlbChKQ0NvbXBpbGF0aW9uVW5pdCB0aGF0KSB7CiAgICAgICAgICAgICAgICBpZiAodGhhdC5wYWNrZ2UgPT0gc3ltKSByZXN1bHQgPSB0aGF0OwogICAgICAgICAgICAgICAgZWxzZSBzdXBlci52aXNpdFRvcExldmVsKHRoYXQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0TW9kdWxlRGVmKEpDTW9kdWxlRGVjbCB0aGF0KSB7CiAgICAgICAgICAgICAgICBpZiAodGhhdC5zeW0gPT0gc3ltKSByZXN1bHQgPSB0aGF0OwogICAgICAgICAgICAgICAgLy8gbm8gbmVlZCB0byBzY2FuIHdpdGhpbiBtb2R1bGUgZGVjbGFyYXRpb24KICAgICAgICAgICAgfQogICAgICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdFBhY2thZ2VEZWYoSkNQYWNrYWdlRGVjbCB0aGF0KSB7CiAgICAgICAgICAgICAgICBpZiAodGhhdC5wYWNrZ2UgPT0gc3ltKSByZXN1bHQgPSB0aGF0OwogICAgICAgICAgICAgICAgZWxzZSBzdXBlci52aXNpdFBhY2thZ2VEZWYodGhhdCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcHVibGljIHZvaWQgdmlzaXRDbGFzc0RlZihKQ0NsYXNzRGVjbCB0aGF0KSB7CiAgICAgICAgICAgICAgICBpZiAodGhhdC5zeW0gPT0gc3ltKSByZXN1bHQgPSB0aGF0OwogICAgICAgICAgICAgICAgZWxzZSBzdXBlci52aXNpdENsYXNzRGVmKHRoYXQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0TWV0aG9kRGVmKEpDTWV0aG9kRGVjbCB0aGF0KSB7CiAgICAgICAgICAgICAgICBpZiAodGhhdC5zeW0gPT0gc3ltKSByZXN1bHQgPSB0aGF0OwogICAgICAgICAgICAgICAgZWxzZSBzdXBlci52aXNpdE1ldGhvZERlZih0aGF0KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdFZhckRlZihKQ1ZhcmlhYmxlRGVjbCB0aGF0KSB7CiAgICAgICAgICAgICAgICBpZiAodGhhdC5zeW0gPT0gc3ltKSByZXN1bHQgPSB0aGF0OwogICAgICAgICAgICAgICAgZWxzZSBzdXBlci52aXNpdFZhckRlZih0aGF0KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdFR5cGVQYXJhbWV0ZXIoSkNUeXBlUGFyYW1ldGVyIHRoYXQpIHsKICAgICAgICAgICAgICAgIGlmICh0aGF0LnR5cGUgIT0gbnVsbCAmJiB0aGF0LnR5cGUudHN5bSA9PSBzeW0pIHJlc3VsdCA9IHRoYXQ7CiAgICAgICAgICAgICAgICBlbHNlIHN1cGVyLnZpc2l0VHlwZVBhcmFtZXRlcih0aGF0KTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBEZWNsU2Nhbm5lciBzID0gbmV3IERlY2xTY2FubmVyKCk7CiAgICAgICAgdHJlZS5hY2NlcHQocyk7CiAgICAgICAgcmV0dXJuIHMucmVzdWx0OwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgRW52PEF0dHJDb250ZXh0PiBzY29wZUZvcihKQ1RyZWUgbm9kZSwgSkNDb21waWxhdGlvblVuaXQgdW5pdCkgewogICAgICAgIHJldHVybiBzY29wZUZvcihwYXRoRm9yKG5vZGUsIHVuaXQpKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIEVudjxBdHRyQ29udGV4dD4gc2NvcGVGb3IoTGlzdDxKQ1RyZWU+IHBhdGgpIHsKICAgICAgICAvLyBUT0RPOiBub3QgaW1wbGVtZW50ZWQgeWV0CiAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJub3QgaW1wbGVtZW50ZWQgeWV0Iik7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBMaXN0PEpDVHJlZT4gcGF0aEZvcihmaW5hbCBKQ1RyZWUgbm9kZSwgZmluYWwgSkNDb21waWxhdGlvblVuaXQgdW5pdCkgewogICAgICAgIGNsYXNzIFJlc3VsdCBleHRlbmRzIEVycm9yIHsKICAgICAgICAgICAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC01OTQyMDg4MjM0NTk0OTA1NjI1TDsKICAgICAgICAgICAgTGlzdDxKQ1RyZWU+IHBhdGg7CiAgICAgICAgICAgIFJlc3VsdChMaXN0PEpDVHJlZT4gcGF0aCkgewogICAgICAgICAgICAgICAgdGhpcy5wYXRoID0gcGF0aDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBjbGFzcyBQYXRoRmluZGVyIGV4dGVuZHMgVHJlZVNjYW5uZXIgewogICAgICAgICAgICBMaXN0PEpDVHJlZT4gcGF0aCA9IExpc3QubmlsKCk7CiAgICAgICAgICAgIHB1YmxpYyB2b2lkIHNjYW4oSkNUcmVlIHRyZWUpIHsKICAgICAgICAgICAgICAgIGlmICh0cmVlICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICBwYXRoID0gcGF0aC5wcmVwZW5kKHRyZWUpOwogICAgICAgICAgICAgICAgICAgIGlmICh0cmVlID09IG5vZGUpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBSZXN1bHQocGF0aCk7CiAgICAgICAgICAgICAgICAgICAgc3VwZXIuc2Nhbih0cmVlKTsKICAgICAgICAgICAgICAgICAgICBwYXRoID0gcGF0aC50YWlsOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICAgIG5ldyBQYXRoRmluZGVyKCkuc2Nhbih1bml0KTsKICAgICAgICB9IGNhdGNoIChSZXN1bHQgcmVzdWx0KSB7CiAgICAgICAgICAgIHJldHVybiByZXN1bHQucGF0aDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIExpc3QubmlsKCk7CiAgICB9CgogICAgLyoqIFJldHVybiB0aGUgc3RhdGVtZW50IHJlZmVyZW5jZWQgYnkgYSBsYWJlbC4KICAgICAqICBJZiB0aGUgbGFiZWwgcmVmZXJzIHRvIGEgbG9vcCBvciBzd2l0Y2gsIHJldHVybiB0aGF0IHN3aXRjaAogICAgICogIG90aGVyd2lzZSByZXR1cm4gdGhlIGxhYmVsbGVkIHN0YXRlbWVudCBpdHNlbGYKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBKQ1RyZWUgcmVmZXJlbmNlZFN0YXRlbWVudChKQ0xhYmVsZWRTdGF0ZW1lbnQgdHJlZSkgewogICAgICAgIEpDVHJlZSB0ID0gdHJlZTsKICAgICAgICBkbyB0ID0gKChKQ0xhYmVsZWRTdGF0ZW1lbnQpIHQpLmJvZHk7CiAgICAgICAgd2hpbGUgKHQuaGFzVGFnKExBQkVMTEVEKSk7CiAgICAgICAgc3dpdGNoICh0LmdldFRhZygpKSB7CiAgICAgICAgY2FzZSBET0xPT1A6IGNhc2UgV0hJTEVMT09QOiBjYXNlIEZPUkxPT1A6IGNhc2UgRk9SRUFDSExPT1A6IGNhc2UgU1dJVENIOgogICAgICAgICAgICByZXR1cm4gdDsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICByZXR1cm4gdHJlZTsKICAgICAgICB9CiAgICB9CgogICAgLyoqIFNraXAgcGFyZW5zIGFuZCByZXR1cm4gdGhlIGVuY2xvc2VkIGV4cHJlc3Npb24KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBKQ0V4cHJlc3Npb24gc2tpcFBhcmVucyhKQ0V4cHJlc3Npb24gdHJlZSkgewogICAgICAgIHdoaWxlICh0cmVlLmhhc1RhZyhQQVJFTlMpKSB7CiAgICAgICAgICAgIHRyZWUgPSAoKEpDUGFyZW5zKSB0cmVlKS5leHByOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdHJlZTsKICAgIH0KCiAgICAvKiogU2tpcCBwYXJlbnMgYW5kIHJldHVybiB0aGUgZW5jbG9zZWQgZXhwcmVzc2lvbgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIEpDVHJlZSBza2lwUGFyZW5zKEpDVHJlZSB0cmVlKSB7CiAgICAgICAgaWYgKHRyZWUuaGFzVGFnKFBBUkVOUykpCiAgICAgICAgICAgIHJldHVybiBza2lwUGFyZW5zKChKQ1BhcmVucyl0cmVlKTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIHJldHVybiB0cmVlOwogICAgfQoKICAgIC8qKiBSZXR1cm4gdGhlIHR5cGVzIG9mIGEgbGlzdCBvZiB0cmVlcy4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBMaXN0PFR5cGU+IHR5cGVzKExpc3Q8PyBleHRlbmRzIEpDVHJlZT4gdHJlZXMpIHsKICAgICAgICBMaXN0QnVmZmVyPFR5cGU+IHRzID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgIGZvciAoTGlzdDw/IGV4dGVuZHMgSkNUcmVlPiBsID0gdHJlZXM7IGwubm9uRW1wdHkoKTsgbCA9IGwudGFpbCkKICAgICAgICAgICAgdHMuYXBwZW5kKGwuaGVhZC50eXBlKTsKICAgICAgICByZXR1cm4gdHMudG9MaXN0KCk7CiAgICB9CgogICAgLyoqIElmIHRoaXMgdHJlZSBpcyBhbiBpZGVudGlmaWVyIG9yIGEgZmllbGQgb3IgYSBwYXJhbWV0ZXJpemVkIHR5cGUsCiAgICAgKiAgcmV0dXJuIGl0cyBuYW1lLCBvdGhlcndpc2UgcmV0dXJuIG51bGwuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgTmFtZSBuYW1lKEpDVHJlZSB0cmVlKSB7CiAgICAgICAgc3dpdGNoICh0cmVlLmdldFRhZygpKSB7CiAgICAgICAgY2FzZSBJREVOVDoKICAgICAgICAgICAgcmV0dXJuICgoSkNJZGVudCkgdHJlZSkubmFtZTsKICAgICAgICBjYXNlIFNFTEVDVDoKICAgICAgICAgICAgcmV0dXJuICgoSkNGaWVsZEFjY2VzcykgdHJlZSkubmFtZTsKICAgICAgICBjYXNlIFRZUEVBUFBMWToKICAgICAgICAgICAgcmV0dXJuIG5hbWUoKChKQ1R5cGVBcHBseSkgdHJlZSkuY2xhenopOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KICAgIH0KCiAgICAvKiogSWYgdGhpcyB0cmVlIGlzIGEgcXVhbGlmaWVkIGlkZW50aWZpZXIsIGl0cyByZXR1cm4gZnVsbHkgcXVhbGlmaWVkIG5hbWUsCiAgICAgKiAgb3RoZXJ3aXNlIHJldHVybiBudWxsLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIE5hbWUgZnVsbE5hbWUoSkNUcmVlIHRyZWUpIHsKICAgICAgICB0cmVlID0gc2tpcFBhcmVucyh0cmVlKTsKICAgICAgICBzd2l0Y2ggKHRyZWUuZ2V0VGFnKCkpIHsKICAgICAgICBjYXNlIElERU5UOgogICAgICAgICAgICByZXR1cm4gKChKQ0lkZW50KSB0cmVlKS5uYW1lOwogICAgICAgIGNhc2UgU0VMRUNUOgogICAgICAgICAgICBOYW1lIHNuYW1lID0gZnVsbE5hbWUoKChKQ0ZpZWxkQWNjZXNzKSB0cmVlKS5zZWxlY3RlZCk7CiAgICAgICAgICAgIHJldHVybiBzbmFtZSA9PSBudWxsID8gbnVsbCA6IHNuYW1lLmFwcGVuZCgnLicsIG5hbWUodHJlZSkpOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIFN5bWJvbCBzeW1ib2xGb3IoSkNUcmVlIG5vZGUpIHsKICAgICAgICBTeW1ib2wgc3ltID0gc3ltYm9sRm9ySW1wbChub2RlKTsKCiAgICAgICAgcmV0dXJuIHN5bSAhPSBudWxsID8gc3ltLmJhc2VTeW1ib2woKSA6IG51bGw7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgU3ltYm9sIHN5bWJvbEZvckltcGwoSkNUcmVlIG5vZGUpIHsKICAgICAgICBub2RlID0gc2tpcFBhcmVucyhub2RlKTsKICAgICAgICBzd2l0Y2ggKG5vZGUuZ2V0VGFnKCkpIHsKICAgICAgICBjYXNlIFRPUExFVkVMOgogICAgICAgICAgICBKQ0NvbXBpbGF0aW9uVW5pdCBjdXQgPSAoSkNDb21waWxhdGlvblVuaXQpIG5vZGU7CiAgICAgICAgICAgIEpDTW9kdWxlRGVjbCBtb2R1bGVEZWNsID0gY3V0LmdldE1vZHVsZURlY2woKTsKICAgICAgICAgICAgaWYgKGlzTW9kdWxlSW5mbyhjdXQpICYmIG1vZHVsZURlY2wgIT0gbnVsbCkKICAgICAgICAgICAgICAgIHJldHVybiBzeW1ib2xGb3IobW9kdWxlRGVjbCk7CiAgICAgICAgICAgIHJldHVybiBjdXQucGFja2dlOwogICAgICAgIGNhc2UgTU9EVUxFREVGOgogICAgICAgICAgICByZXR1cm4gKChKQ01vZHVsZURlY2wpIG5vZGUpLnN5bTsKICAgICAgICBjYXNlIFBBQ0tBR0VERUY6CiAgICAgICAgICAgIHJldHVybiAoKEpDUGFja2FnZURlY2wpIG5vZGUpLnBhY2tnZTsKICAgICAgICBjYXNlIENMQVNTREVGOgogICAgICAgICAgICByZXR1cm4gKChKQ0NsYXNzRGVjbCkgbm9kZSkuc3ltOwogICAgICAgIGNhc2UgTUVUSE9EREVGOgogICAgICAgICAgICByZXR1cm4gKChKQ01ldGhvZERlY2wpIG5vZGUpLnN5bTsKICAgICAgICBjYXNlIFZBUkRFRjoKICAgICAgICAgICAgcmV0dXJuICgoSkNWYXJpYWJsZURlY2wpIG5vZGUpLnN5bTsKICAgICAgICBjYXNlIElERU5UOgogICAgICAgICAgICByZXR1cm4gKChKQ0lkZW50KSBub2RlKS5zeW07CiAgICAgICAgY2FzZSBTRUxFQ1Q6CiAgICAgICAgICAgIHJldHVybiAoKEpDRmllbGRBY2Nlc3MpIG5vZGUpLnN5bTsKICAgICAgICBjYXNlIFJFRkVSRU5DRToKICAgICAgICAgICAgcmV0dXJuICgoSkNNZW1iZXJSZWZlcmVuY2UpIG5vZGUpLnN5bTsKICAgICAgICBjYXNlIE5FV0NMQVNTOgogICAgICAgICAgICByZXR1cm4gKChKQ05ld0NsYXNzKSBub2RlKS5jb25zdHJ1Y3RvcjsKICAgICAgICBjYXNlIEFQUExZOgogICAgICAgICAgICByZXR1cm4gc3ltYm9sRm9yKCgoSkNNZXRob2RJbnZvY2F0aW9uKSBub2RlKS5tZXRoKTsKICAgICAgICBjYXNlIFRZUEVBUFBMWToKICAgICAgICAgICAgcmV0dXJuIHN5bWJvbEZvcigoKEpDVHlwZUFwcGx5KSBub2RlKS5jbGF6eik7CiAgICAgICAgY2FzZSBBTk5PVEFUSU9OOgogICAgICAgIGNhc2UgVFlQRV9BTk5PVEFUSU9OOgogICAgICAgIGNhc2UgVFlQRVBBUkFNRVRFUjoKICAgICAgICAgICAgaWYgKG5vZGUudHlwZSAhPSBudWxsKQogICAgICAgICAgICAgICAgcmV0dXJuIG5vZGUudHlwZS50c3ltOwogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzRGVjbGFyYXRpb24oSkNUcmVlIG5vZGUpIHsKICAgICAgICBub2RlID0gc2tpcFBhcmVucyhub2RlKTsKICAgICAgICBzd2l0Y2ggKG5vZGUuZ2V0VGFnKCkpIHsKICAgICAgICBjYXNlIFBBQ0tBR0VERUY6CiAgICAgICAgY2FzZSBDTEFTU0RFRjoKICAgICAgICBjYXNlIE1FVEhPRERFRjoKICAgICAgICBjYXNlIFZBUkRFRjoKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgIH0KCiAgICAvKiogSWYgdGhpcyB0cmVlIGlzIGFuIGlkZW50aWZpZXIgb3IgYSBmaWVsZCwgcmV0dXJuIGl0cyBzeW1ib2wsCiAgICAgKiAgb3RoZXJ3aXNlIHJldHVybiBudWxsLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIFN5bWJvbCBzeW1ib2woSkNUcmVlIHRyZWUpIHsKICAgICAgICB0cmVlID0gc2tpcFBhcmVucyh0cmVlKTsKICAgICAgICBzd2l0Y2ggKHRyZWUuZ2V0VGFnKCkpIHsKICAgICAgICBjYXNlIElERU5UOgogICAgICAgICAgICByZXR1cm4gKChKQ0lkZW50KSB0cmVlKS5zeW07CiAgICAgICAgY2FzZSBTRUxFQ1Q6CiAgICAgICAgICAgIHJldHVybiAoKEpDRmllbGRBY2Nlc3MpIHRyZWUpLnN5bTsKICAgICAgICBjYXNlIFRZUEVBUFBMWToKICAgICAgICAgICAgcmV0dXJuIHN5bWJvbCgoKEpDVHlwZUFwcGx5KSB0cmVlKS5jbGF6eik7CiAgICAgICAgY2FzZSBBTk5PVEFURURfVFlQRToKICAgICAgICAgICAgcmV0dXJuIHN5bWJvbCgoKEpDQW5ub3RhdGVkVHlwZSkgdHJlZSkudW5kZXJseWluZ1R5cGUpOwogICAgICAgIGNhc2UgUkVGRVJFTkNFOgogICAgICAgICAgICByZXR1cm4gKChKQ01lbWJlclJlZmVyZW5jZSkgdHJlZSkuc3ltOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KICAgIH0KCiAgICAvKiogUmV0dXJuIHRydWUgaWYgdGhpcyBpcyBhIG5vbnN0YXRpYyBzZWxlY3Rpb24uICovCiAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gbm9uc3RhdGljU2VsZWN0KEpDVHJlZSB0cmVlKSB7CiAgICAgICAgdHJlZSA9IHNraXBQYXJlbnModHJlZSk7CiAgICAgICAgaWYgKCF0cmVlLmhhc1RhZyhTRUxFQ1QpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgSkNGaWVsZEFjY2VzcyBzID0gKEpDRmllbGRBY2Nlc3MpIHRyZWU7CiAgICAgICAgU3ltYm9sIGUgPSBzeW1ib2wocy5zZWxlY3RlZCk7CiAgICAgICAgcmV0dXJuIGUgPT0gbnVsbCB8fCAoZS5raW5kICE9IFBDSyAmJiBlLmtpbmQgIT0gVFlQKTsKICAgIH0KCiAgICAvKiogSWYgdGhpcyB0cmVlIGlzIGFuIGlkZW50aWZpZXIgb3IgYSBmaWVsZCwgc2V0IGl0cyBzeW1ib2wsIG90aGVyd2lzZSBza2lwLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIHZvaWQgc2V0U3ltYm9sKEpDVHJlZSB0cmVlLCBTeW1ib2wgc3ltKSB7CiAgICAgICAgdHJlZSA9IHNraXBQYXJlbnModHJlZSk7CiAgICAgICAgc3dpdGNoICh0cmVlLmdldFRhZygpKSB7CiAgICAgICAgY2FzZSBJREVOVDoKICAgICAgICAgICAgKChKQ0lkZW50KSB0cmVlKS5zeW0gPSBzeW07IGJyZWFrOwogICAgICAgIGNhc2UgU0VMRUNUOgogICAgICAgICAgICAoKEpDRmllbGRBY2Nlc3MpIHRyZWUpLnN5bSA9IHN5bTsgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICB9CiAgICB9CgogICAgLyoqIElmIHRoaXMgdHJlZSBpcyBhIGRlY2xhcmF0aW9uIG9yIGEgYmxvY2ssIHJldHVybiBpdHMgZmxhZ3MgZmllbGQsCiAgICAgKiAgb3RoZXJ3aXNlIHJldHVybiAwLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGxvbmcgZmxhZ3MoSkNUcmVlIHRyZWUpIHsKICAgICAgICBzd2l0Y2ggKHRyZWUuZ2V0VGFnKCkpIHsKICAgICAgICBjYXNlIFZBUkRFRjoKICAgICAgICAgICAgcmV0dXJuICgoSkNWYXJpYWJsZURlY2wpIHRyZWUpLm1vZHMuZmxhZ3M7CiAgICAgICAgY2FzZSBNRVRIT0RERUY6CiAgICAgICAgICAgIHJldHVybiAoKEpDTWV0aG9kRGVjbCkgdHJlZSkubW9kcy5mbGFnczsKICAgICAgICBjYXNlIENMQVNTREVGOgogICAgICAgICAgICByZXR1cm4gKChKQ0NsYXNzRGVjbCkgdHJlZSkubW9kcy5mbGFnczsKICAgICAgICBjYXNlIEJMT0NLOgogICAgICAgICAgICByZXR1cm4gKChKQ0Jsb2NrKSB0cmVlKS5mbGFnczsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CiAgICB9CgogICAgLyoqIFJldHVybiBmaXJzdCAoc21hbGxlc3QpIGZsYWcgaW4gYGZsYWdzJzoKICAgICAqICBwcmU6IGZsYWdzICE9IDAKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBsb25nIGZpcnN0RmxhZyhsb25nIGZsYWdzKSB7CiAgICAgICAgbG9uZyBmbGFnID0gMTsKICAgICAgICB3aGlsZSAoKGZsYWcgJiBmbGFncyAmIEV4dGVuZGVkU3RhbmRhcmRGbGFncykgPT0gMCkKICAgICAgICAgICAgZmxhZyA9IGZsYWcgPDwgMTsKICAgICAgICByZXR1cm4gZmxhZzsKICAgIH0KCiAgICAvKiogUmV0dXJuIGZsYWdzIGFzIGEgc3RyaW5nLCBzZXBhcmF0ZWQgYnkgIiAiLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBmbGFnTmFtZXMobG9uZyBmbGFncykgewogICAgICAgIHJldHVybiBGbGFncy50b1N0cmluZyhmbGFncyAmIEV4dGVuZGVkU3RhbmRhcmRGbGFncykudHJpbSgpOwogICAgfQoKICAgIC8qKiBPcGVyYXRvciBwcmVjZWRlbmNlcyB2YWx1ZXMuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50CiAgICAgICAgbm90RXhwcmVzc2lvbiA9IC0xLCAgIC8vIG5vdCBhbiBleHByZXNzaW9uCiAgICAgICAgbm9QcmVjID0gMCwgICAgICAgICAgIC8vIG5vIGVuY2xvc2luZyBleHByZXNzaW9uCiAgICAgICAgYXNzaWduUHJlYyA9IDEsCiAgICAgICAgYXNzaWdub3BQcmVjID0gMiwKICAgICAgICBjb25kUHJlYyA9IDMsCiAgICAgICAgb3JQcmVjID0gNCwKICAgICAgICBhbmRQcmVjID0gNSwKICAgICAgICBiaXRvclByZWMgPSA2LAogICAgICAgIGJpdHhvclByZWMgPSA3LAogICAgICAgIGJpdGFuZFByZWMgPSA4LAogICAgICAgIGVxUHJlYyA9IDksCiAgICAgICAgb3JkUHJlYyA9IDEwLAogICAgICAgIHNoaWZ0UHJlYyA9IDExLAogICAgICAgIGFkZFByZWMgPSAxMiwKICAgICAgICBtdWxQcmVjID0gMTMsCiAgICAgICAgcHJlZml4UHJlYyA9IDE0LAogICAgICAgIHBvc3RmaXhQcmVjID0gMTUsCiAgICAgICAgcHJlY0NvdW50ID0gMTY7CgoKICAgIC8qKiBNYXAgb3BlcmF0b3JzIHRvIHRoZWlyIHByZWNlZGVuY2UgbGV2ZWxzLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGludCBvcFByZWMoSkNUcmVlLlRhZyBvcCkgewogICAgICAgIHN3aXRjaChvcCkgewogICAgICAgIGNhc2UgUE9TOgogICAgICAgIGNhc2UgTkVHOgogICAgICAgIGNhc2UgTk9UOgogICAgICAgIGNhc2UgQ09NUEw6CiAgICAgICAgY2FzZSBQUkVJTkM6CiAgICAgICAgY2FzZSBQUkVERUM6IHJldHVybiBwcmVmaXhQcmVjOwogICAgICAgIGNhc2UgUE9TVElOQzoKICAgICAgICBjYXNlIFBPU1RERUM6CiAgICAgICAgY2FzZSBOVUxMQ0hLOiByZXR1cm4gcG9zdGZpeFByZWM7CiAgICAgICAgY2FzZSBBU1NJR046IHJldHVybiBhc3NpZ25QcmVjOwogICAgICAgIGNhc2UgQklUT1JfQVNHOgogICAgICAgIGNhc2UgQklUWE9SX0FTRzoKICAgICAgICBjYXNlIEJJVEFORF9BU0c6CiAgICAgICAgY2FzZSBTTF9BU0c6CiAgICAgICAgY2FzZSBTUl9BU0c6CiAgICAgICAgY2FzZSBVU1JfQVNHOgogICAgICAgIGNhc2UgUExVU19BU0c6CiAgICAgICAgY2FzZSBNSU5VU19BU0c6CiAgICAgICAgY2FzZSBNVUxfQVNHOgogICAgICAgIGNhc2UgRElWX0FTRzoKICAgICAgICBjYXNlIE1PRF9BU0c6IHJldHVybiBhc3NpZ25vcFByZWM7CiAgICAgICAgY2FzZSBPUjogcmV0dXJuIG9yUHJlYzsKICAgICAgICBjYXNlIEFORDogcmV0dXJuIGFuZFByZWM7CiAgICAgICAgY2FzZSBFUToKICAgICAgICBjYXNlIE5FOiByZXR1cm4gZXFQcmVjOwogICAgICAgIGNhc2UgTFQ6CiAgICAgICAgY2FzZSBHVDoKICAgICAgICBjYXNlIExFOgogICAgICAgIGNhc2UgR0U6IHJldHVybiBvcmRQcmVjOwogICAgICAgIGNhc2UgQklUT1I6IHJldHVybiBiaXRvclByZWM7CiAgICAgICAgY2FzZSBCSVRYT1I6IHJldHVybiBiaXR4b3JQcmVjOwogICAgICAgIGNhc2UgQklUQU5EOiByZXR1cm4gYml0YW5kUHJlYzsKICAgICAgICBjYXNlIFNMOgogICAgICAgIGNhc2UgU1I6CiAgICAgICAgY2FzZSBVU1I6IHJldHVybiBzaGlmdFByZWM7CiAgICAgICAgY2FzZSBQTFVTOgogICAgICAgIGNhc2UgTUlOVVM6IHJldHVybiBhZGRQcmVjOwogICAgICAgIGNhc2UgTVVMOgogICAgICAgIGNhc2UgRElWOgogICAgICAgIGNhc2UgTU9EOiByZXR1cm4gbXVsUHJlYzsKICAgICAgICBjYXNlIFRZUEVURVNUOiByZXR1cm4gb3JkUHJlYzsKICAgICAgICBkZWZhdWx0OiB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoKTsKICAgICAgICB9CiAgICB9CgogICAgc3RhdGljIFRyZWUuS2luZCB0YWdUb0tpbmQoSkNUcmVlLlRhZyB0YWcpIHsKICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgIC8vIFBvc3RmaXggZXhwcmVzc2lvbnMKICAgICAgICBjYXNlIFBPU1RJTkM6ICAgICAgICAgICAvLyBfICsrCiAgICAgICAgICAgIHJldHVybiBUcmVlLktpbmQuUE9TVEZJWF9JTkNSRU1FTlQ7CiAgICAgICAgY2FzZSBQT1NUREVDOiAgICAgICAgICAgLy8gXyAtLQogICAgICAgICAgICByZXR1cm4gVHJlZS5LaW5kLlBPU1RGSVhfREVDUkVNRU5UOwoKICAgICAgICAvLyBVbmFyeSBvcGVyYXRvcnMKICAgICAgICBjYXNlIFBSRUlOQzogICAgICAgICAgICAvLyArKyBfCiAgICAgICAgICAgIHJldHVybiBUcmVlLktpbmQuUFJFRklYX0lOQ1JFTUVOVDsKICAgICAgICBjYXNlIFBSRURFQzogICAgICAgICAgICAvLyAtLSBfCiAgICAgICAgICAgIHJldHVybiBUcmVlLktpbmQuUFJFRklYX0RFQ1JFTUVOVDsKICAgICAgICBjYXNlIFBPUzogICAgICAgICAgICAgICAvLyArCiAgICAgICAgICAgIHJldHVybiBUcmVlLktpbmQuVU5BUllfUExVUzsKICAgICAgICBjYXNlIE5FRzogICAgICAgICAgICAgICAvLyAtCiAgICAgICAgICAgIHJldHVybiBUcmVlLktpbmQuVU5BUllfTUlOVVM7CiAgICAgICAgY2FzZSBDT01QTDogICAgICAgICAgICAgLy8gfgogICAgICAgICAgICByZXR1cm4gVHJlZS5LaW5kLkJJVFdJU0VfQ09NUExFTUVOVDsKICAgICAgICBjYXNlIE5PVDogICAgICAgICAgICAgICAvLyAhCiAgICAgICAgICAgIHJldHVybiBUcmVlLktpbmQuTE9HSUNBTF9DT01QTEVNRU5UOwoKICAgICAgICAvLyBCaW5hcnkgb3BlcmF0b3JzCgogICAgICAgIC8vIE11bHRpcGxpY2F0aXZlIG9wZXJhdG9ycwogICAgICAgIGNhc2UgTVVMOiAgICAgICAgICAgICAgIC8vICoKICAgICAgICAgICAgcmV0dXJuIFRyZWUuS2luZC5NVUxUSVBMWTsKICAgICAgICBjYXNlIERJVjogICAgICAgICAgICAgICAvLyAvCiAgICAgICAgICAgIHJldHVybiBUcmVlLktpbmQuRElWSURFOwogICAgICAgIGNhc2UgTU9EOiAgICAgICAgICAgICAgIC8vICUKICAgICAgICAgICAgcmV0dXJuIFRyZWUuS2luZC5SRU1BSU5ERVI7CgogICAgICAgIC8vIEFkZGl0aXZlIG9wZXJhdG9ycwogICAgICAgIGNhc2UgUExVUzogICAgICAgICAgICAgIC8vICsKICAgICAgICAgICAgcmV0dXJuIFRyZWUuS2luZC5QTFVTOwogICAgICAgIGNhc2UgTUlOVVM6ICAgICAgICAgICAgIC8vIC0KICAgICAgICAgICAgcmV0dXJuIFRyZWUuS2luZC5NSU5VUzsKCiAgICAgICAgLy8gU2hpZnQgb3BlcmF0b3JzCiAgICAgICAgY2FzZSBTTDogICAgICAgICAgICAgICAgLy8gPDwKICAgICAgICAgICAgcmV0dXJuIFRyZWUuS2luZC5MRUZUX1NISUZUOwogICAgICAgIGNhc2UgU1I6ICAgICAgICAgICAgICAgIC8vID4+CiAgICAgICAgICAgIHJldHVybiBUcmVlLktpbmQuUklHSFRfU0hJRlQ7CiAgICAgICAgY2FzZSBVU1I6ICAgICAgICAgICAgICAgLy8gPj4+CiAgICAgICAgICAgIHJldHVybiBUcmVlLktpbmQuVU5TSUdORURfUklHSFRfU0hJRlQ7CgogICAgICAgIC8vIFJlbGF0aW9uYWwgb3BlcmF0b3JzCiAgICAgICAgY2FzZSBMVDogICAgICAgICAgICAgICAgLy8gPAogICAgICAgICAgICByZXR1cm4gVHJlZS5LaW5kLkxFU1NfVEhBTjsKICAgICAgICBjYXNlIEdUOiAgICAgICAgICAgICAgICAvLyA+CiAgICAgICAgICAgIHJldHVybiBUcmVlLktpbmQuR1JFQVRFUl9USEFOOwogICAgICAgIGNhc2UgTEU6ICAgICAgICAgICAgICAgIC8vIDw9CiAgICAgICAgICAgIHJldHVybiBUcmVlLktpbmQuTEVTU19USEFOX0VRVUFMOwogICAgICAgIGNhc2UgR0U6ICAgICAgICAgICAgICAgIC8vID49CiAgICAgICAgICAgIHJldHVybiBUcmVlLktpbmQuR1JFQVRFUl9USEFOX0VRVUFMOwoKICAgICAgICAvLyBFcXVhbGl0eSBvcGVyYXRvcnMKICAgICAgICBjYXNlIEVROiAgICAgICAgICAgICAgICAvLyA9PQogICAgICAgICAgICByZXR1cm4gVHJlZS5LaW5kLkVRVUFMX1RPOwogICAgICAgIGNhc2UgTkU6ICAgICAgICAgICAgICAgIC8vICE9CiAgICAgICAgICAgIHJldHVybiBUcmVlLktpbmQuTk9UX0VRVUFMX1RPOwoKICAgICAgICAvLyBCaXR3aXNlIGFuZCBsb2dpY2FsIG9wZXJhdG9ycwogICAgICAgIGNhc2UgQklUQU5EOiAgICAgICAgICAgIC8vICYKICAgICAgICAgICAgcmV0dXJuIFRyZWUuS2luZC5BTkQ7CiAgICAgICAgY2FzZSBCSVRYT1I6ICAgICAgICAgICAgLy8gXgogICAgICAgICAgICByZXR1cm4gVHJlZS5LaW5kLlhPUjsKICAgICAgICBjYXNlIEJJVE9SOiAgICAgICAgICAgICAvLyB8CiAgICAgICAgICAgIHJldHVybiBUcmVlLktpbmQuT1I7CgogICAgICAgIC8vIENvbmRpdGlvbmFsIG9wZXJhdG9ycwogICAgICAgIGNhc2UgQU5EOiAgICAgICAgICAgICAgIC8vICYmCiAgICAgICAgICAgIHJldHVybiBUcmVlLktpbmQuQ09ORElUSU9OQUxfQU5EOwogICAgICAgIGNhc2UgT1I6ICAgICAgICAgICAgICAgIC8vIHx8CiAgICAgICAgICAgIHJldHVybiBUcmVlLktpbmQuQ09ORElUSU9OQUxfT1I7CgogICAgICAgIC8vIEFzc2lnbm1lbnQgb3BlcmF0b3JzCiAgICAgICAgY2FzZSBNVUxfQVNHOiAgICAgICAgICAgLy8gKj0KICAgICAgICAgICAgcmV0dXJuIFRyZWUuS2luZC5NVUxUSVBMWV9BU1NJR05NRU5UOwogICAgICAgIGNhc2UgRElWX0FTRzogICAgICAgICAgIC8vIC89CiAgICAgICAgICAgIHJldHVybiBUcmVlLktpbmQuRElWSURFX0FTU0lHTk1FTlQ7CiAgICAgICAgY2FzZSBNT0RfQVNHOiAgICAgICAgICAgLy8gJT0KICAgICAgICAgICAgcmV0dXJuIFRyZWUuS2luZC5SRU1BSU5ERVJfQVNTSUdOTUVOVDsKICAgICAgICBjYXNlIFBMVVNfQVNHOiAgICAgICAgICAvLyArPQogICAgICAgICAgICByZXR1cm4gVHJlZS5LaW5kLlBMVVNfQVNTSUdOTUVOVDsKICAgICAgICBjYXNlIE1JTlVTX0FTRzogICAgICAgICAvLyAtPQogICAgICAgICAgICByZXR1cm4gVHJlZS5LaW5kLk1JTlVTX0FTU0lHTk1FTlQ7CiAgICAgICAgY2FzZSBTTF9BU0c6ICAgICAgICAgICAgLy8gPDw9CiAgICAgICAgICAgIHJldHVybiBUcmVlLktpbmQuTEVGVF9TSElGVF9BU1NJR05NRU5UOwogICAgICAgIGNhc2UgU1JfQVNHOiAgICAgICAgICAgIC8vID4+PQogICAgICAgICAgICByZXR1cm4gVHJlZS5LaW5kLlJJR0hUX1NISUZUX0FTU0lHTk1FTlQ7CiAgICAgICAgY2FzZSBVU1JfQVNHOiAgICAgICAgICAgLy8gPj4+PQogICAgICAgICAgICByZXR1cm4gVHJlZS5LaW5kLlVOU0lHTkVEX1JJR0hUX1NISUZUX0FTU0lHTk1FTlQ7CiAgICAgICAgY2FzZSBCSVRBTkRfQVNHOiAgICAgICAgLy8gJj0KICAgICAgICAgICAgcmV0dXJuIFRyZWUuS2luZC5BTkRfQVNTSUdOTUVOVDsKICAgICAgICBjYXNlIEJJVFhPUl9BU0c6ICAgICAgICAvLyBePQogICAgICAgICAgICByZXR1cm4gVHJlZS5LaW5kLlhPUl9BU1NJR05NRU5UOwogICAgICAgIGNhc2UgQklUT1JfQVNHOiAgICAgICAgIC8vIHw9CiAgICAgICAgICAgIHJldHVybiBUcmVlLktpbmQuT1JfQVNTSUdOTUVOVDsKCiAgICAgICAgLy8gTnVsbCBjaGVjayAoaW1wbGVtZW50YXRpb24gZGV0YWlsKSwgZm9yIGV4YW1wbGUsIF9fLmdldENsYXNzKCkKICAgICAgICBjYXNlIE5VTExDSEs6CiAgICAgICAgICAgIHJldHVybiBUcmVlLktpbmQuT1RIRVI7CgogICAgICAgIGNhc2UgQU5OT1RBVElPTjoKICAgICAgICAgICAgcmV0dXJuIFRyZWUuS2luZC5BTk5PVEFUSU9OOwogICAgICAgIGNhc2UgVFlQRV9BTk5PVEFUSU9OOgogICAgICAgICAgICByZXR1cm4gVHJlZS5LaW5kLlRZUEVfQU5OT1RBVElPTjsKCiAgICAgICAgY2FzZSBFWFBPUlRTOgogICAgICAgICAgICByZXR1cm4gVHJlZS5LaW5kLkVYUE9SVFM7CiAgICAgICAgY2FzZSBPUEVOUzoKICAgICAgICAgICAgcmV0dXJuIFRyZWUuS2luZC5PUEVOUzsKCiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgdW5kZXJseWluZyB0eXBlIG9mIHRoZSB0cmVlIGlmIGl0IGlzIGFuIGFubm90YXRlZCB0eXBlLAogICAgICogb3IgdGhlIHRyZWUgaXRzZWxmIG90aGVyd2lzZS4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBKQ0V4cHJlc3Npb24gdHlwZUluKEpDRXhwcmVzc2lvbiB0cmVlKSB7CiAgICAgICAgc3dpdGNoICh0cmVlLmdldFRhZygpKSB7CiAgICAgICAgY2FzZSBBTk5PVEFURURfVFlQRToKICAgICAgICAgICAgcmV0dXJuICgoSkNBbm5vdGF0ZWRUeXBlKXRyZWUpLnVuZGVybHlpbmdUeXBlOwogICAgICAgIGNhc2UgSURFTlQ6IC8qIHNpbXBsZSBuYW1lcyAqLwogICAgICAgIGNhc2UgVFlQRUlERU5UOiAvKiBwcmltaXRpdmUgbmFtZSAqLwogICAgICAgIGNhc2UgU0VMRUNUOiAvKiBxdWFsaWZpZWQgbmFtZSAqLwogICAgICAgIGNhc2UgVFlQRUFSUkFZOiAvKiBhcnJheSB0eXBlcyAqLwogICAgICAgIGNhc2UgV0lMRENBUkQ6IC8qIHdpbGQgY2FyZHMgKi8KICAgICAgICBjYXNlIFRZUEVQQVJBTUVURVI6IC8qIHR5cGUgcGFyYW1ldGVycyAqLwogICAgICAgIGNhc2UgVFlQRUFQUExZOiAvKiBwYXJhbWV0ZXJpemVkIHR5cGVzICovCiAgICAgICAgY2FzZSBFUlJPTkVPVVM6IC8qIGVycm9yIHRyZWUgVE9ETzogbmVlZGVkIGZvciBCYWRDYXN0IEpTUjMwOCB0ZXN0IGNhc2UuIEJldHRlciB3YXk/ICovCiAgICAgICAgICAgIHJldHVybiB0cmVlOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigiVW5leHBlY3RlZCB0eXBlIHRyZWU6ICIgKyB0cmVlKTsKICAgICAgICB9CiAgICB9CgogICAgLyogUmV0dXJuIHRoZSBpbm5lci1tb3N0IHR5cGUgb2YgYSB0eXBlIHRyZWUuCiAgICAgKiBGb3IgYW4gYXJyYXkgdGhhdCBjb250YWlucyBhbiBhbm5vdGF0ZWQgdHlwZSwgcmV0dXJuIHRoYXQgYW5ub3RhdGVkIHR5cGUuCiAgICAgKiBUT0RPOiBjdXJyZW50bHkgb25seSB1c2VkIGJ5IFByZXR0eS4gRGVzY3JpYmUgYmVoYXZpb3IgYmV0dGVyLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIEpDVHJlZSBpbm5lcm1vc3RUeXBlKEpDVHJlZSB0eXBlKSB7CiAgICAgICAgSkNUcmVlIGxhc3RBbm5vdGF0ZWRUeXBlID0gbnVsbDsKICAgICAgICBKQ1RyZWUgY3VyID0gdHlwZTsKICAgICAgICBsb29wOiB3aGlsZSAodHJ1ZSkgewogICAgICAgICAgICBzd2l0Y2ggKGN1ci5nZXRUYWcoKSkgewogICAgICAgICAgICBjYXNlIFRZUEVBUlJBWToKICAgICAgICAgICAgICAgIGxhc3RBbm5vdGF0ZWRUeXBlID0gbnVsbDsKICAgICAgICAgICAgICAgIGN1ciA9ICgoSkNBcnJheVR5cGVUcmVlKWN1cikuZWxlbXR5cGU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBXSUxEQ0FSRDoKICAgICAgICAgICAgICAgIGxhc3RBbm5vdGF0ZWRUeXBlID0gbnVsbDsKICAgICAgICAgICAgICAgIGN1ciA9ICgoSkNXaWxkY2FyZCljdXIpLmlubmVyOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgQU5OT1RBVEVEX1RZUEU6CiAgICAgICAgICAgICAgICBsYXN0QW5ub3RhdGVkVHlwZSA9IGN1cjsKICAgICAgICAgICAgICAgIGN1ciA9ICgoSkNBbm5vdGF0ZWRUeXBlKWN1cikudW5kZXJseWluZ1R5cGU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIGJyZWFrIGxvb3A7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKGxhc3RBbm5vdGF0ZWRUeXBlIT1udWxsKSB7CiAgICAgICAgICAgIHJldHVybiBsYXN0QW5ub3RhdGVkVHlwZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gY3VyOwogICAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBUeXBlQW5ub3RhdGlvbkZpbmRlciBleHRlbmRzIFRyZWVTY2FubmVyIHsKICAgICAgICBwdWJsaWMgYm9vbGVhbiBmb3VuZFR5cGVBbm5vID0gZmFsc2U7CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHNjYW4oSkNUcmVlIHRyZWUpIHsKICAgICAgICAgICAgaWYgKGZvdW5kVHlwZUFubm8gfHwgdHJlZSA9PSBudWxsKQogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICBzdXBlci5zY2FuKHRyZWUpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRBbm5vdGF0aW9uKEpDQW5ub3RhdGlvbiB0cmVlKSB7CiAgICAgICAgICAgIGZvdW5kVHlwZUFubm8gPSBmb3VuZFR5cGVBbm5vIHx8IHRyZWUuaGFzVGFnKFRZUEVfQU5OT1RBVElPTik7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBjb250YWluc1R5cGVBbm5vdGF0aW9uKEpDVHJlZSBlKSB7CiAgICAgICAgVHlwZUFubm90YXRpb25GaW5kZXIgZmluZGVyID0gbmV3IFR5cGVBbm5vdGF0aW9uRmluZGVyKCk7CiAgICAgICAgZmluZGVyLnNjYW4oZSk7CiAgICAgICAgcmV0dXJuIGZpbmRlci5mb3VuZFR5cGVBbm5vOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc01vZHVsZUluZm8oSkNDb21waWxhdGlvblVuaXQgdHJlZSkgewogICAgICAgIHJldHVybiB0cmVlLnNvdXJjZWZpbGUuaXNOYW1lQ29tcGF0aWJsZSgibW9kdWxlLWluZm8iLCBKYXZhRmlsZU9iamVjdC5LaW5kLlNPVVJDRSkKICAgICAgICAgICAgICAgICYmIHRyZWUuZ2V0TW9kdWxlRGVjbCgpICE9IG51bGw7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBKQ01vZHVsZURlY2wgZ2V0TW9kdWxlKEpDQ29tcGlsYXRpb25Vbml0IHQpIHsKICAgICAgICBpZiAodC5kZWZzLm5vbkVtcHR5KCkpIHsKICAgICAgICAgICAgSkNUcmVlIGRlZiA9IHQuZGVmcy5oZWFkOwogICAgICAgICAgICBpZiAoZGVmLmhhc1RhZyhNT0RVTEVERUYpKQogICAgICAgICAgICAgICAgcmV0dXJuIChKQ01vZHVsZURlY2wpIGRlZjsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzUGFja2FnZUluZm8oSkNDb21waWxhdGlvblVuaXQgdHJlZSkgewogICAgICAgIHJldHVybiB0cmVlLnNvdXJjZWZpbGUuaXNOYW1lQ29tcGF0aWJsZSgicGFja2FnZS1pbmZvIiwgSmF2YUZpbGVPYmplY3QuS2luZC5TT1VSQ0UpOwogICAgfQp9ClBLAwQKAAAIAAAGO6lKG5docj+SAAA/kgAAJwAAAGNvbS9zdW4vdG9vbHMvamF2YWMvdHJlZS9UcmVlTWFrZXIuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMTk5OSwgMjAxNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWU7CgppbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOwoKaW1wb3J0IGNvbS5zdW4uc291cmNlLnRyZWUuTW9kdWxlVHJlZS5Nb2R1bGVLaW5kOwppbXBvcnQgY29tLnN1bi5zb3VyY2UudHJlZS5UcmVlLktpbmQ7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuKjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5TeW1ib2wuKjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5UeXBlLio7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuKjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5KQ0RpYWdub3N0aWMuRGlhZ25vc3RpY1Bvc2l0aW9uOwoKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5KQ1RyZWUuKjsKCmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLkZsYWdzLio7CmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLktpbmRzLktpbmQuKjsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuVHlwZVRhZy4qOwoKLyoqIEZhY3RvcnkgY2xhc3MgZm9yIHRyZWVzLgogKgogKiAgPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24gcmlzay4KICogIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yCiAqICBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+CiAqLwpwdWJsaWMgY2xhc3MgVHJlZU1ha2VyIGltcGxlbWVudHMgSkNUcmVlLkZhY3RvcnkgewoKICAgIC8qKiBUaGUgY29udGV4dCBrZXkgZm9yIHRoZSB0cmVlIGZhY3RvcnkuICovCiAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIENvbnRleHQuS2V5PFRyZWVNYWtlcj4gdHJlZU1ha2VyS2V5ID0gbmV3IENvbnRleHQuS2V5PD4oKTsKCiAgICAvKiogR2V0IHRoZSBUcmVlTWFrZXIgaW5zdGFuY2UuICovCiAgICBwdWJsaWMgc3RhdGljIFRyZWVNYWtlciBpbnN0YW5jZShDb250ZXh0IGNvbnRleHQpIHsKICAgICAgICBUcmVlTWFrZXIgaW5zdGFuY2UgPSBjb250ZXh0LmdldCh0cmVlTWFrZXJLZXkpOwogICAgICAgIGlmIChpbnN0YW5jZSA9PSBudWxsKQogICAgICAgICAgICBpbnN0YW5jZSA9IG5ldyBUcmVlTWFrZXIoY29udGV4dCk7CiAgICAgICAgcmV0dXJuIGluc3RhbmNlOwogICAgfQoKICAgIC8qKiBUaGUgcG9zaXRpb24gYXQgd2hpY2ggc3Vic2VxdWVudCB0cmVlcyB3aWxsIGJlIGNyZWF0ZWQuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgcG9zID0gUG9zaXRpb24uTk9QT1M7CgogICAgLyoqIFRoZSB0b3BsZXZlbCB0cmVlIHRvIHdoaWNoIGNyZWF0ZWQgdHJlZXMgYmVsb25nLgogICAgICovCiAgICBwdWJsaWMgSkNDb21waWxhdGlvblVuaXQgdG9wbGV2ZWw7CgogICAgLyoqIFRoZSBjdXJyZW50IG5hbWUgdGFibGUuICovCiAgICBOYW1lcyBuYW1lczsKCiAgICBUeXBlcyB0eXBlczsKCiAgICAvKiogVGhlIGN1cnJlbnQgc3ltYm9sIHRhYmxlLiAqLwogICAgU3ltdGFiIHN5bXM7CgogICAgLyoqIENyZWF0ZSBhIHRyZWUgbWFrZXIgd2l0aCBudWxsIHRvcGxldmVsIGFuZCBOT1BPUyBhcyBpbml0aWFsIHBvc2l0aW9uLgogICAgICovCiAgICBwcm90ZWN0ZWQgVHJlZU1ha2VyKENvbnRleHQgY29udGV4dCkgewogICAgICAgIGNvbnRleHQucHV0KHRyZWVNYWtlcktleSwgdGhpcyk7CiAgICAgICAgdGhpcy5wb3MgPSBQb3NpdGlvbi5OT1BPUzsKICAgICAgICB0aGlzLnRvcGxldmVsID0gbnVsbDsKICAgICAgICB0aGlzLm5hbWVzID0gTmFtZXMuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgdGhpcy5zeW1zID0gU3ltdGFiLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIHRoaXMudHlwZXMgPSBUeXBlcy5pbnN0YW5jZShjb250ZXh0KTsKICAgIH0KCiAgICAvKiogQ3JlYXRlIGEgdHJlZSBtYWtlciB3aXRoIGEgZ2l2ZW4gdG9wbGV2ZWwgYW5kIEZJUlNUUE9TIGFzIGluaXRpYWwgcG9zaXRpb24uCiAgICAgKi8KICAgIHByb3RlY3RlZCBUcmVlTWFrZXIoSkNDb21waWxhdGlvblVuaXQgdG9wbGV2ZWwsIE5hbWVzIG5hbWVzLCBUeXBlcyB0eXBlcywgU3ltdGFiIHN5bXMpIHsKICAgICAgICB0aGlzLnBvcyA9IFBvc2l0aW9uLkZJUlNUUE9TOwogICAgICAgIHRoaXMudG9wbGV2ZWwgPSB0b3BsZXZlbDsKICAgICAgICB0aGlzLm5hbWVzID0gbmFtZXM7CiAgICAgICAgdGhpcy50eXBlcyA9IHR5cGVzOwogICAgICAgIHRoaXMuc3ltcyA9IHN5bXM7CiAgICB9CgogICAgLyoqIENyZWF0ZSBhIG5ldyB0cmVlIG1ha2VyIGZvciBhIGdpdmVuIHRvcGxldmVsLgogICAgICovCiAgICBwdWJsaWMgVHJlZU1ha2VyIGZvclRvcGxldmVsKEpDQ29tcGlsYXRpb25Vbml0IHRvcGxldmVsKSB7CiAgICAgICAgcmV0dXJuIG5ldyBUcmVlTWFrZXIodG9wbGV2ZWwsIG5hbWVzLCB0eXBlcywgc3ltcyk7CiAgICB9CgogICAgLyoqIFJlYXNzaWduIGN1cnJlbnQgcG9zaXRpb24uCiAgICAgKi8KICAgIHB1YmxpYyBUcmVlTWFrZXIgYXQoaW50IHBvcykgewogICAgICAgIHRoaXMucG9zID0gcG9zOwogICAgICAgIHJldHVybiB0aGlzOwogICAgfQoKICAgIC8qKiBSZWFzc2lnbiBjdXJyZW50IHBvc2l0aW9uLgogICAgICovCiAgICBwdWJsaWMgVHJlZU1ha2VyIGF0KERpYWdub3N0aWNQb3NpdGlvbiBwb3MpIHsKICAgICAgICB0aGlzLnBvcyA9IChwb3MgPT0gbnVsbCA/IFBvc2l0aW9uLk5PUE9TIDogcG9zLmdldFN0YXJ0UG9zaXRpb24oKSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBDcmVhdGUgZ2l2ZW4gdHJlZSBub2RlIGF0IGN1cnJlbnQgcG9zaXRpb24uCiAgICAgKiBAcGFyYW0gZGVmcyBhIGxpc3Qgb2YgUGFja2FnZURlZiwgQ2xhc3NEZWYsIEltcG9ydCwgYW5kIFNraXAKICAgICAqLwogICAgcHVibGljIEpDQ29tcGlsYXRpb25Vbml0IFRvcExldmVsKExpc3Q8SkNUcmVlPiBkZWZzKSB7CiAgICAgICAgZm9yIChKQ1RyZWUgbm9kZSA6IGRlZnMpCiAgICAgICAgICAgIEFzc2VydC5jaGVjayhub2RlIGluc3RhbmNlb2YgSkNDbGFzc0RlY2wKICAgICAgICAgICAgICAgIHx8IG5vZGUgaW5zdGFuY2VvZiBKQ1BhY2thZ2VEZWNsCiAgICAgICAgICAgICAgICB8fCBub2RlIGluc3RhbmNlb2YgSkNJbXBvcnQKICAgICAgICAgICAgICAgIHx8IG5vZGUgaW5zdGFuY2VvZiBKQ01vZHVsZURlY2wKICAgICAgICAgICAgICAgIHx8IG5vZGUgaW5zdGFuY2VvZiBKQ1NraXAKICAgICAgICAgICAgICAgIHx8IG5vZGUgaW5zdGFuY2VvZiBKQ0Vycm9uZW91cwogICAgICAgICAgICAgICAgfHwgKG5vZGUgaW5zdGFuY2VvZiBKQ0V4cHJlc3Npb25TdGF0ZW1lbnQKICAgICAgICAgICAgICAgICAgICAmJiAoKEpDRXhwcmVzc2lvblN0YXRlbWVudClub2RlKS5leHByIGluc3RhbmNlb2YgSkNFcnJvbmVvdXMpLAogICAgICAgICAgICAgICAgICAgICgpIC0+IG5vZGUuZ2V0Q2xhc3MoKS5nZXRTaW1wbGVOYW1lKCkpOwogICAgICAgIEpDQ29tcGlsYXRpb25Vbml0IHRyZWUgPSBuZXcgSkNDb21waWxhdGlvblVuaXQoZGVmcyk7CiAgICAgICAgdHJlZS5wb3MgPSBwb3M7CiAgICAgICAgcmV0dXJuIHRyZWU7CiAgICB9CgogICAgcHVibGljIEpDUGFja2FnZURlY2wgUGFja2FnZURlY2woTGlzdDxKQ0Fubm90YXRpb24+IGFubm90YXRpb25zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSkNFeHByZXNzaW9uIHBpZCkgewogICAgICAgIEFzc2VydC5jaGVja05vbk51bGwoYW5ub3RhdGlvbnMpOwogICAgICAgIEFzc2VydC5jaGVja05vbk51bGwocGlkKTsKICAgICAgICBKQ1BhY2thZ2VEZWNsIHRyZWUgPSBuZXcgSkNQYWNrYWdlRGVjbChhbm5vdGF0aW9ucywgcGlkKTsKICAgICAgICB0cmVlLnBvcyA9IHBvczsKICAgICAgICByZXR1cm4gdHJlZTsKICAgIH0KCiAgICBwdWJsaWMgSkNJbXBvcnQgSW1wb3J0KEpDVHJlZSBxdWFsaWQsIGJvb2xlYW4gaW1wb3J0U3RhdGljKSB7CiAgICAgICAgSkNJbXBvcnQgdHJlZSA9IG5ldyBKQ0ltcG9ydChxdWFsaWQsIGltcG9ydFN0YXRpYyk7CiAgICAgICAgdHJlZS5wb3MgPSBwb3M7CiAgICAgICAgcmV0dXJuIHRyZWU7CiAgICB9CgogICAgcHVibGljIEpDQ2xhc3NEZWNsIENsYXNzRGVmKEpDTW9kaWZpZXJzIG1vZHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTmFtZSBuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExpc3Q8SkNUeXBlUGFyYW1ldGVyPiB0eXBhcmFtcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBKQ0V4cHJlc3Npb24gZXh0ZW5kaW5nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExpc3Q8SkNFeHByZXNzaW9uPiBpbXBsZW1lbnRpbmcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTGlzdDxKQ1RyZWU+IGRlZnMpCiAgICB7CiAgICAgICAgSkNDbGFzc0RlY2wgdHJlZSA9IG5ldyBKQ0NsYXNzRGVjbChtb2RzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGFyYW1zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5kaW5nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW1wbGVtZW50aW5nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVmcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwpOwogICAgICAgIHRyZWUucG9zID0gcG9zOwogICAgICAgIHJldHVybiB0cmVlOwogICAgfQoKICAgIHB1YmxpYyBKQ01ldGhvZERlY2wgTWV0aG9kRGVmKEpDTW9kaWZpZXJzIG1vZHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOYW1lIG5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBKQ0V4cHJlc3Npb24gcmVzdHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExpc3Q8SkNUeXBlUGFyYW1ldGVyPiB0eXBhcmFtcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExpc3Q8SkNWYXJpYWJsZURlY2w+IHBhcmFtcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExpc3Q8SkNFeHByZXNzaW9uPiB0aHJvd24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBKQ0Jsb2NrIGJvZHksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBKQ0V4cHJlc3Npb24gZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgcmV0dXJuIE1ldGhvZERlZigKICAgICAgICAgICAgICAgIG1vZHMsIG5hbWUsIHJlc3R5cGUsIHR5cGFyYW1zLCBudWxsLCBwYXJhbXMsCiAgICAgICAgICAgICAgICB0aHJvd24sIGJvZHksIGRlZmF1bHRWYWx1ZSk7CiAgICB9CgogICAgcHVibGljIEpDTWV0aG9kRGVjbCBNZXRob2REZWYoSkNNb2RpZmllcnMgbW9kcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5hbWUgbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEpDRXhwcmVzc2lvbiByZXN0eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTGlzdDxKQ1R5cGVQYXJhbWV0ZXI+IHR5cGFyYW1zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSkNWYXJpYWJsZURlY2wgcmVjdnBhcmFtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTGlzdDxKQ1ZhcmlhYmxlRGVjbD4gcGFyYW1zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTGlzdDxKQ0V4cHJlc3Npb24+IHRocm93biwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEpDQmxvY2sgYm9keSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEpDRXhwcmVzc2lvbiBkZWZhdWx0VmFsdWUpCiAgICB7CiAgICAgICAgSkNNZXRob2REZWNsIHRyZWUgPSBuZXcgSkNNZXRob2REZWNsKG1vZHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3R5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGFyYW1zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWN2cGFyYW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3duLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib2R5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0VmFsdWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwpOwogICAgICAgIHRyZWUucG9zID0gcG9zOwogICAgICAgIHJldHVybiB0cmVlOwogICAgfQoKICAgIHB1YmxpYyBKQ1ZhcmlhYmxlRGVjbCBWYXJEZWYoSkNNb2RpZmllcnMgbW9kcywgTmFtZSBuYW1lLCBKQ0V4cHJlc3Npb24gdmFydHlwZSwgSkNFeHByZXNzaW9uIGluaXQpIHsKICAgICAgICBKQ1ZhcmlhYmxlRGVjbCB0cmVlID0gbmV3IEpDVmFyaWFibGVEZWNsKG1vZHMsIG5hbWUsIHZhcnR5cGUsIGluaXQsIG51bGwpOwogICAgICAgIHRyZWUucG9zID0gcG9zOwogICAgICAgIHJldHVybiB0cmVlOwogICAgfQoKICAgIHB1YmxpYyBKQ1ZhcmlhYmxlRGVjbCBSZWNlaXZlclZhckRlZihKQ01vZGlmaWVycyBtb2RzLCBKQ0V4cHJlc3Npb24gbmFtZSwgSkNFeHByZXNzaW9uIHZhcnR5cGUpIHsKICAgICAgICBKQ1ZhcmlhYmxlRGVjbCB0cmVlID0gbmV3IEpDVmFyaWFibGVEZWNsKG1vZHMsIG5hbWUsIHZhcnR5cGUpOwogICAgICAgIHRyZWUucG9zID0gcG9zOwogICAgICAgIHJldHVybiB0cmVlOwogICAgfQoKICAgIHB1YmxpYyBKQ1NraXAgU2tpcCgpIHsKICAgICAgICBKQ1NraXAgdHJlZSA9IG5ldyBKQ1NraXAoKTsKICAgICAgICB0cmVlLnBvcyA9IHBvczsKICAgICAgICByZXR1cm4gdHJlZTsKICAgIH0KCiAgICBwdWJsaWMgSkNCbG9jayBCbG9jayhsb25nIGZsYWdzLCBMaXN0PEpDU3RhdGVtZW50PiBzdGF0cykgewogICAgICAgIEpDQmxvY2sgdHJlZSA9IG5ldyBKQ0Jsb2NrKGZsYWdzLCBzdGF0cyk7CiAgICAgICAgdHJlZS5wb3MgPSBwb3M7CiAgICAgICAgcmV0dXJuIHRyZWU7CiAgICB9CgogICAgcHVibGljIEpDRG9XaGlsZUxvb3AgRG9Mb29wKEpDU3RhdGVtZW50IGJvZHksIEpDRXhwcmVzc2lvbiBjb25kKSB7CiAgICAgICAgSkNEb1doaWxlTG9vcCB0cmVlID0gbmV3IEpDRG9XaGlsZUxvb3AoYm9keSwgY29uZCk7CiAgICAgICAgdHJlZS5wb3MgPSBwb3M7CiAgICAgICAgcmV0dXJuIHRyZWU7CiAgICB9CgogICAgcHVibGljIEpDV2hpbGVMb29wIFdoaWxlTG9vcChKQ0V4cHJlc3Npb24gY29uZCwgSkNTdGF0ZW1lbnQgYm9keSkgewogICAgICAgIEpDV2hpbGVMb29wIHRyZWUgPSBuZXcgSkNXaGlsZUxvb3AoY29uZCwgYm9keSk7CiAgICAgICAgdHJlZS5wb3MgPSBwb3M7CiAgICAgICAgcmV0dXJuIHRyZWU7CiAgICB9CgogICAgcHVibGljIEpDRm9yTG9vcCBGb3JMb29wKExpc3Q8SkNTdGF0ZW1lbnQ+IGluaXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIEpDRXhwcmVzc2lvbiBjb25kLAogICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0PEpDRXhwcmVzc2lvblN0YXRlbWVudD4gc3RlcCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgSkNTdGF0ZW1lbnQgYm9keSkKICAgIHsKICAgICAgICBKQ0Zvckxvb3AgdHJlZSA9IG5ldyBKQ0Zvckxvb3AoaW5pdCwgY29uZCwgc3RlcCwgYm9keSk7CiAgICAgICAgdHJlZS5wb3MgPSBwb3M7CiAgICAgICAgcmV0dXJuIHRyZWU7CiAgICB9CgogICAgcHVibGljIEpDRW5oYW5jZWRGb3JMb29wIEZvcmVhY2hMb29wKEpDVmFyaWFibGVEZWNsIHZhciwgSkNFeHByZXNzaW9uIGV4cHIsIEpDU3RhdGVtZW50IGJvZHkpIHsKICAgICAgICBKQ0VuaGFuY2VkRm9yTG9vcCB0cmVlID0gbmV3IEpDRW5oYW5jZWRGb3JMb29wKHZhciwgZXhwciwgYm9keSk7CiAgICAgICAgdHJlZS5wb3MgPSBwb3M7CiAgICAgICAgcmV0dXJuIHRyZWU7CiAgICB9CgogICAgcHVibGljIEpDTGFiZWxlZFN0YXRlbWVudCBMYWJlbGxlZChOYW1lIGxhYmVsLCBKQ1N0YXRlbWVudCBib2R5KSB7CiAgICAgICAgSkNMYWJlbGVkU3RhdGVtZW50IHRyZWUgPSBuZXcgSkNMYWJlbGVkU3RhdGVtZW50KGxhYmVsLCBib2R5KTsKICAgICAgICB0cmVlLnBvcyA9IHBvczsKICAgICAgICByZXR1cm4gdHJlZTsKICAgIH0KCiAgICBwdWJsaWMgSkNTd2l0Y2ggU3dpdGNoKEpDRXhwcmVzc2lvbiBzZWxlY3RvciwgTGlzdDxKQ0Nhc2U+IGNhc2VzKSB7CiAgICAgICAgSkNTd2l0Y2ggdHJlZSA9IG5ldyBKQ1N3aXRjaChzZWxlY3RvciwgY2FzZXMpOwogICAgICAgIHRyZWUucG9zID0gcG9zOwogICAgICAgIHJldHVybiB0cmVlOwogICAgfQoKICAgIHB1YmxpYyBKQ0Nhc2UgQ2FzZShKQ0V4cHJlc3Npb24gcGF0LCBMaXN0PEpDU3RhdGVtZW50PiBzdGF0cykgewogICAgICAgIEpDQ2FzZSB0cmVlID0gbmV3IEpDQ2FzZShwYXQsIHN0YXRzKTsKICAgICAgICB0cmVlLnBvcyA9IHBvczsKICAgICAgICByZXR1cm4gdHJlZTsKICAgIH0KCiAgICBwdWJsaWMgSkNTeW5jaHJvbml6ZWQgU3luY2hyb25pemVkKEpDRXhwcmVzc2lvbiBsb2NrLCBKQ0Jsb2NrIGJvZHkpIHsKICAgICAgICBKQ1N5bmNocm9uaXplZCB0cmVlID0gbmV3IEpDU3luY2hyb25pemVkKGxvY2ssIGJvZHkpOwogICAgICAgIHRyZWUucG9zID0gcG9zOwogICAgICAgIHJldHVybiB0cmVlOwogICAgfQoKICAgIHB1YmxpYyBKQ1RyeSBUcnkoSkNCbG9jayBib2R5LCBMaXN0PEpDQ2F0Y2g+IGNhdGNoZXJzLCBKQ0Jsb2NrIGZpbmFsaXplcikgewogICAgICAgIHJldHVybiBUcnkoTGlzdC5uaWwoKSwgYm9keSwgY2F0Y2hlcnMsIGZpbmFsaXplcik7CiAgICB9CgogICAgcHVibGljIEpDVHJ5IFRyeShMaXN0PEpDVHJlZT4gcmVzb3VyY2VzLAogICAgICAgICAgICAgICAgICAgICBKQ0Jsb2NrIGJvZHksCiAgICAgICAgICAgICAgICAgICAgIExpc3Q8SkNDYXRjaD4gY2F0Y2hlcnMsCiAgICAgICAgICAgICAgICAgICAgIEpDQmxvY2sgZmluYWxpemVyKSB7CiAgICAgICAgSkNUcnkgdHJlZSA9IG5ldyBKQ1RyeShyZXNvdXJjZXMsIGJvZHksIGNhdGNoZXJzLCBmaW5hbGl6ZXIpOwogICAgICAgIHRyZWUucG9zID0gcG9zOwogICAgICAgIHJldHVybiB0cmVlOwogICAgfQoKICAgIHB1YmxpYyBKQ0NhdGNoIENhdGNoKEpDVmFyaWFibGVEZWNsIHBhcmFtLCBKQ0Jsb2NrIGJvZHkpIHsKICAgICAgICBKQ0NhdGNoIHRyZWUgPSBuZXcgSkNDYXRjaChwYXJhbSwgYm9keSk7CiAgICAgICAgdHJlZS5wb3MgPSBwb3M7CiAgICAgICAgcmV0dXJuIHRyZWU7CiAgICB9CgogICAgcHVibGljIEpDQ29uZGl0aW9uYWwgQ29uZGl0aW9uYWwoSkNFeHByZXNzaW9uIGNvbmQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSkNFeHByZXNzaW9uIHRoZW5wYXJ0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEpDRXhwcmVzc2lvbiBlbHNlcGFydCkKICAgIHsKICAgICAgICBKQ0NvbmRpdGlvbmFsIHRyZWUgPSBuZXcgSkNDb25kaXRpb25hbChjb25kLCB0aGVucGFydCwgZWxzZXBhcnQpOwogICAgICAgIHRyZWUucG9zID0gcG9zOwogICAgICAgIHJldHVybiB0cmVlOwogICAgfQoKICAgIHB1YmxpYyBKQ0lmIElmKEpDRXhwcmVzc2lvbiBjb25kLCBKQ1N0YXRlbWVudCB0aGVucGFydCwgSkNTdGF0ZW1lbnQgZWxzZXBhcnQpIHsKICAgICAgICBKQ0lmIHRyZWUgPSBuZXcgSkNJZihjb25kLCB0aGVucGFydCwgZWxzZXBhcnQpOwogICAgICAgIHRyZWUucG9zID0gcG9zOwogICAgICAgIHJldHVybiB0cmVlOwogICAgfQoKICAgIHB1YmxpYyBKQ0V4cHJlc3Npb25TdGF0ZW1lbnQgRXhlYyhKQ0V4cHJlc3Npb24gZXhwcikgewogICAgICAgIEpDRXhwcmVzc2lvblN0YXRlbWVudCB0cmVlID0gbmV3IEpDRXhwcmVzc2lvblN0YXRlbWVudChleHByKTsKICAgICAgICB0cmVlLnBvcyA9IHBvczsKICAgICAgICByZXR1cm4gdHJlZTsKICAgIH0KCiAgICBwdWJsaWMgSkNCcmVhayBCcmVhayhOYW1lIGxhYmVsKSB7CiAgICAgICAgSkNCcmVhayB0cmVlID0gbmV3IEpDQnJlYWsobGFiZWwsIG51bGwpOwogICAgICAgIHRyZWUucG9zID0gcG9zOwogICAgICAgIHJldHVybiB0cmVlOwogICAgfQoKICAgIHB1YmxpYyBKQ0NvbnRpbnVlIENvbnRpbnVlKE5hbWUgbGFiZWwpIHsKICAgICAgICBKQ0NvbnRpbnVlIHRyZWUgPSBuZXcgSkNDb250aW51ZShsYWJlbCwgbnVsbCk7CiAgICAgICAgdHJlZS5wb3MgPSBwb3M7CiAgICAgICAgcmV0dXJuIHRyZWU7CiAgICB9CgogICAgcHVibGljIEpDUmV0dXJuIFJldHVybihKQ0V4cHJlc3Npb24gZXhwcikgewogICAgICAgIEpDUmV0dXJuIHRyZWUgPSBuZXcgSkNSZXR1cm4oZXhwcik7CiAgICAgICAgdHJlZS5wb3MgPSBwb3M7CiAgICAgICAgcmV0dXJuIHRyZWU7CiAgICB9CgogICAgcHVibGljIEpDVGhyb3cgVGhyb3coSkNFeHByZXNzaW9uIGV4cHIpIHsKICAgICAgICBKQ1Rocm93IHRyZWUgPSBuZXcgSkNUaHJvdyhleHByKTsKICAgICAgICB0cmVlLnBvcyA9IHBvczsKICAgICAgICByZXR1cm4gdHJlZTsKICAgIH0KCiAgICBwdWJsaWMgSkNBc3NlcnQgQXNzZXJ0KEpDRXhwcmVzc2lvbiBjb25kLCBKQ0V4cHJlc3Npb24gZGV0YWlsKSB7CiAgICAgICAgSkNBc3NlcnQgdHJlZSA9IG5ldyBKQ0Fzc2VydChjb25kLCBkZXRhaWwpOwogICAgICAgIHRyZWUucG9zID0gcG9zOwogICAgICAgIHJldHVybiB0cmVlOwogICAgfQoKICAgIHB1YmxpYyBKQ01ldGhvZEludm9jYXRpb24gQXBwbHkoTGlzdDxKQ0V4cHJlc3Npb24+IHR5cGVhcmdzLAogICAgICAgICAgICAgICAgICAgICAgIEpDRXhwcmVzc2lvbiBmbiwKICAgICAgICAgICAgICAgICAgICAgICBMaXN0PEpDRXhwcmVzc2lvbj4gYXJncykKICAgIHsKICAgICAgICBKQ01ldGhvZEludm9jYXRpb24gdHJlZSA9IG5ldyBKQ01ldGhvZEludm9jYXRpb24odHlwZWFyZ3MsIGZuLCBhcmdzKTsKICAgICAgICB0cmVlLnBvcyA9IHBvczsKICAgICAgICByZXR1cm4gdHJlZTsKICAgIH0KCiAgICBwdWJsaWMgSkNOZXdDbGFzcyBOZXdDbGFzcyhKQ0V4cHJlc3Npb24gZW5jbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0PEpDRXhwcmVzc2lvbj4gdHlwZWFyZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSkNFeHByZXNzaW9uIGNsYXp6LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIExpc3Q8SkNFeHByZXNzaW9uPiBhcmdzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIEpDQ2xhc3NEZWNsIGRlZikKICAgIHsKICAgICAgICBKQ05ld0NsYXNzIHRyZWUgPSBuZXcgSkNOZXdDbGFzcyhlbmNsLCB0eXBlYXJncywgY2xhenosIGFyZ3MsIGRlZik7CiAgICAgICAgdHJlZS5wb3MgPSBwb3M7CiAgICAgICAgcmV0dXJuIHRyZWU7CiAgICB9CgogICAgcHVibGljIEpDTmV3QXJyYXkgTmV3QXJyYXkoSkNFeHByZXNzaW9uIGVsZW10eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIExpc3Q8SkNFeHByZXNzaW9uPiBkaW1zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIExpc3Q8SkNFeHByZXNzaW9uPiBlbGVtcykKICAgIHsKICAgICAgICBKQ05ld0FycmF5IHRyZWUgPSBuZXcgSkNOZXdBcnJheShlbGVtdHlwZSwgZGltcywgZWxlbXMpOwogICAgICAgIHRyZWUucG9zID0gcG9zOwogICAgICAgIHJldHVybiB0cmVlOwogICAgfQoKICAgIHB1YmxpYyBKQ0xhbWJkYSBMYW1iZGEoTGlzdDxKQ1ZhcmlhYmxlRGVjbD4gcGFyYW1zLAogICAgICAgICAgICAgICAgICAgICAgICAgICBKQ1RyZWUgYm9keSkKICAgIHsKICAgICAgICBKQ0xhbWJkYSB0cmVlID0gbmV3IEpDTGFtYmRhKHBhcmFtcywgYm9keSk7CiAgICAgICAgdHJlZS5wb3MgPSBwb3M7CiAgICAgICAgcmV0dXJuIHRyZWU7CiAgICB9CgogICAgcHVibGljIEpDUGFyZW5zIFBhcmVucyhKQ0V4cHJlc3Npb24gZXhwcikgewogICAgICAgIEpDUGFyZW5zIHRyZWUgPSBuZXcgSkNQYXJlbnMoZXhwcik7CiAgICAgICAgdHJlZS5wb3MgPSBwb3M7CiAgICAgICAgcmV0dXJuIHRyZWU7CiAgICB9CgogICAgcHVibGljIEpDQXNzaWduIEFzc2lnbihKQ0V4cHJlc3Npb24gbGhzLCBKQ0V4cHJlc3Npb24gcmhzKSB7CiAgICAgICAgSkNBc3NpZ24gdHJlZSA9IG5ldyBKQ0Fzc2lnbihsaHMsIHJocyk7CiAgICAgICAgdHJlZS5wb3MgPSBwb3M7CiAgICAgICAgcmV0dXJuIHRyZWU7CiAgICB9CgogICAgcHVibGljIEpDQXNzaWduT3AgQXNzaWdub3AoSkNUcmVlLlRhZyBvcGNvZGUsIEpDVHJlZSBsaHMsIEpDVHJlZSByaHMpIHsKICAgICAgICBKQ0Fzc2lnbk9wIHRyZWUgPSBuZXcgSkNBc3NpZ25PcChvcGNvZGUsIGxocywgcmhzLCBudWxsKTsKICAgICAgICB0cmVlLnBvcyA9IHBvczsKICAgICAgICByZXR1cm4gdHJlZTsKICAgIH0KCiAgICBwdWJsaWMgSkNVbmFyeSBVbmFyeShKQ1RyZWUuVGFnIG9wY29kZSwgSkNFeHByZXNzaW9uIGFyZykgewogICAgICAgIEpDVW5hcnkgdHJlZSA9IG5ldyBKQ1VuYXJ5KG9wY29kZSwgYXJnKTsKICAgICAgICB0cmVlLnBvcyA9IHBvczsKICAgICAgICByZXR1cm4gdHJlZTsKICAgIH0KCiAgICBwdWJsaWMgSkNCaW5hcnkgQmluYXJ5KEpDVHJlZS5UYWcgb3Bjb2RlLCBKQ0V4cHJlc3Npb24gbGhzLCBKQ0V4cHJlc3Npb24gcmhzKSB7CiAgICAgICAgSkNCaW5hcnkgdHJlZSA9IG5ldyBKQ0JpbmFyeShvcGNvZGUsIGxocywgcmhzLCBudWxsKTsKICAgICAgICB0cmVlLnBvcyA9IHBvczsKICAgICAgICByZXR1cm4gdHJlZTsKICAgIH0KCiAgICBwdWJsaWMgSkNUeXBlQ2FzdCBUeXBlQ2FzdChKQ1RyZWUgY2xhenosIEpDRXhwcmVzc2lvbiBleHByKSB7CiAgICAgICAgSkNUeXBlQ2FzdCB0cmVlID0gbmV3IEpDVHlwZUNhc3QoY2xhenosIGV4cHIpOwogICAgICAgIHRyZWUucG9zID0gcG9zOwogICAgICAgIHJldHVybiB0cmVlOwogICAgfQoKICAgIHB1YmxpYyBKQ0luc3RhbmNlT2YgVHlwZVRlc3QoSkNFeHByZXNzaW9uIGV4cHIsIEpDVHJlZSBjbGF6eikgewogICAgICAgIEpDSW5zdGFuY2VPZiB0cmVlID0gbmV3IEpDSW5zdGFuY2VPZihleHByLCBjbGF6eik7CiAgICAgICAgdHJlZS5wb3MgPSBwb3M7CiAgICAgICAgcmV0dXJuIHRyZWU7CiAgICB9CgogICAgcHVibGljIEpDQXJyYXlBY2Nlc3MgSW5kZXhlZChKQ0V4cHJlc3Npb24gaW5kZXhlZCwgSkNFeHByZXNzaW9uIGluZGV4KSB7CiAgICAgICAgSkNBcnJheUFjY2VzcyB0cmVlID0gbmV3IEpDQXJyYXlBY2Nlc3MoaW5kZXhlZCwgaW5kZXgpOwogICAgICAgIHRyZWUucG9zID0gcG9zOwogICAgICAgIHJldHVybiB0cmVlOwogICAgfQoKICAgIHB1YmxpYyBKQ0ZpZWxkQWNjZXNzIFNlbGVjdChKQ0V4cHJlc3Npb24gc2VsZWN0ZWQsIE5hbWUgc2VsZWN0b3IpIHsKICAgICAgICBKQ0ZpZWxkQWNjZXNzIHRyZWUgPSBuZXcgSkNGaWVsZEFjY2VzcyhzZWxlY3RlZCwgc2VsZWN0b3IsIG51bGwpOwogICAgICAgIHRyZWUucG9zID0gcG9zOwogICAgICAgIHJldHVybiB0cmVlOwogICAgfQoKICAgIHB1YmxpYyBKQ01lbWJlclJlZmVyZW5jZSBSZWZlcmVuY2UoSkNNZW1iZXJSZWZlcmVuY2UuUmVmZXJlbmNlTW9kZSBtb2RlLCBOYW1lIG5hbWUsCiAgICAgICAgICAgIEpDRXhwcmVzc2lvbiBleHByLCBMaXN0PEpDRXhwcmVzc2lvbj4gdHlwZWFyZ3MpIHsKICAgICAgICBKQ01lbWJlclJlZmVyZW5jZSB0cmVlID0gbmV3IEpDTWVtYmVyUmVmZXJlbmNlKG1vZGUsIG5hbWUsIGV4cHIsIHR5cGVhcmdzKTsKICAgICAgICB0cmVlLnBvcyA9IHBvczsKICAgICAgICByZXR1cm4gdHJlZTsKICAgIH0KCiAgICBwdWJsaWMgSkNJZGVudCBJZGVudChOYW1lIG5hbWUpIHsKICAgICAgICBKQ0lkZW50IHRyZWUgPSBuZXcgSkNJZGVudChuYW1lLCBudWxsKTsKICAgICAgICB0cmVlLnBvcyA9IHBvczsKICAgICAgICByZXR1cm4gdHJlZTsKICAgIH0KCiAgICBwdWJsaWMgSkNMaXRlcmFsIExpdGVyYWwoVHlwZVRhZyB0YWcsIE9iamVjdCB2YWx1ZSkgewogICAgICAgIEpDTGl0ZXJhbCB0cmVlID0gbmV3IEpDTGl0ZXJhbCh0YWcsIHZhbHVlKTsKICAgICAgICB0cmVlLnBvcyA9IHBvczsKICAgICAgICByZXR1cm4gdHJlZTsKICAgIH0KCiAgICBwdWJsaWMgSkNQcmltaXRpdmVUeXBlVHJlZSBUeXBlSWRlbnQoVHlwZVRhZyB0eXBldGFnKSB7CiAgICAgICAgSkNQcmltaXRpdmVUeXBlVHJlZSB0cmVlID0gbmV3IEpDUHJpbWl0aXZlVHlwZVRyZWUodHlwZXRhZyk7CiAgICAgICAgdHJlZS5wb3MgPSBwb3M7CiAgICAgICAgcmV0dXJuIHRyZWU7CiAgICB9CgogICAgcHVibGljIEpDQXJyYXlUeXBlVHJlZSBUeXBlQXJyYXkoSkNFeHByZXNzaW9uIGVsZW10eXBlKSB7CiAgICAgICAgSkNBcnJheVR5cGVUcmVlIHRyZWUgPSBuZXcgSkNBcnJheVR5cGVUcmVlKGVsZW10eXBlKTsKICAgICAgICB0cmVlLnBvcyA9IHBvczsKICAgICAgICByZXR1cm4gdHJlZTsKICAgIH0KCiAgICBwdWJsaWMgSkNUeXBlQXBwbHkgVHlwZUFwcGx5KEpDRXhwcmVzc2lvbiBjbGF6eiwgTGlzdDxKQ0V4cHJlc3Npb24+IGFyZ3VtZW50cykgewogICAgICAgIEpDVHlwZUFwcGx5IHRyZWUgPSBuZXcgSkNUeXBlQXBwbHkoY2xhenosIGFyZ3VtZW50cyk7CiAgICAgICAgdHJlZS5wb3MgPSBwb3M7CiAgICAgICAgcmV0dXJuIHRyZWU7CiAgICB9CgogICAgcHVibGljIEpDVHlwZVVuaW9uIFR5cGVVbmlvbihMaXN0PEpDRXhwcmVzc2lvbj4gY29tcG9uZW50cykgewogICAgICAgIEpDVHlwZVVuaW9uIHRyZWUgPSBuZXcgSkNUeXBlVW5pb24oY29tcG9uZW50cyk7CiAgICAgICAgdHJlZS5wb3MgPSBwb3M7CiAgICAgICAgcmV0dXJuIHRyZWU7CiAgICB9CgogICAgcHVibGljIEpDVHlwZUludGVyc2VjdGlvbiBUeXBlSW50ZXJzZWN0aW9uKExpc3Q8SkNFeHByZXNzaW9uPiBjb21wb25lbnRzKSB7CiAgICAgICAgSkNUeXBlSW50ZXJzZWN0aW9uIHRyZWUgPSBuZXcgSkNUeXBlSW50ZXJzZWN0aW9uKGNvbXBvbmVudHMpOwogICAgICAgIHRyZWUucG9zID0gcG9zOwogICAgICAgIHJldHVybiB0cmVlOwogICAgfQoKICAgIHB1YmxpYyBKQ1R5cGVQYXJhbWV0ZXIgVHlwZVBhcmFtZXRlcihOYW1lIG5hbWUsIExpc3Q8SkNFeHByZXNzaW9uPiBib3VuZHMpIHsKICAgICAgICByZXR1cm4gVHlwZVBhcmFtZXRlcihuYW1lLCBib3VuZHMsIExpc3QubmlsKCkpOwogICAgfQoKICAgIHB1YmxpYyBKQ1R5cGVQYXJhbWV0ZXIgVHlwZVBhcmFtZXRlcihOYW1lIG5hbWUsIExpc3Q8SkNFeHByZXNzaW9uPiBib3VuZHMsIExpc3Q8SkNBbm5vdGF0aW9uPiBhbm5vcykgewogICAgICAgIEpDVHlwZVBhcmFtZXRlciB0cmVlID0gbmV3IEpDVHlwZVBhcmFtZXRlcihuYW1lLCBib3VuZHMsIGFubm9zKTsKICAgICAgICB0cmVlLnBvcyA9IHBvczsKICAgICAgICByZXR1cm4gdHJlZTsKICAgIH0KCiAgICBwdWJsaWMgSkNXaWxkY2FyZCBXaWxkY2FyZChUeXBlQm91bmRLaW5kIGtpbmQsIEpDVHJlZSB0eXBlKSB7CiAgICAgICAgSkNXaWxkY2FyZCB0cmVlID0gbmV3IEpDV2lsZGNhcmQoa2luZCwgdHlwZSk7CiAgICAgICAgdHJlZS5wb3MgPSBwb3M7CiAgICAgICAgcmV0dXJuIHRyZWU7CiAgICB9CgogICAgcHVibGljIFR5cGVCb3VuZEtpbmQgVHlwZUJvdW5kS2luZChCb3VuZEtpbmQga2luZCkgewogICAgICAgIFR5cGVCb3VuZEtpbmQgdHJlZSA9IG5ldyBUeXBlQm91bmRLaW5kKGtpbmQpOwogICAgICAgIHRyZWUucG9zID0gcG9zOwogICAgICAgIHJldHVybiB0cmVlOwogICAgfQoKICAgIHB1YmxpYyBKQ0Fubm90YXRpb24gQW5ub3RhdGlvbihKQ1RyZWUgYW5ub3RhdGlvblR5cGUsIExpc3Q8SkNFeHByZXNzaW9uPiBhcmdzKSB7CiAgICAgICAgSkNBbm5vdGF0aW9uIHRyZWUgPSBuZXcgSkNBbm5vdGF0aW9uKFRhZy5BTk5PVEFUSU9OLCBhbm5vdGF0aW9uVHlwZSwgYXJncyk7CiAgICAgICAgdHJlZS5wb3MgPSBwb3M7CiAgICAgICAgcmV0dXJuIHRyZWU7CiAgICB9CgogICAgcHVibGljIEpDQW5ub3RhdGlvbiBUeXBlQW5ub3RhdGlvbihKQ1RyZWUgYW5ub3RhdGlvblR5cGUsIExpc3Q8SkNFeHByZXNzaW9uPiBhcmdzKSB7CiAgICAgICAgSkNBbm5vdGF0aW9uIHRyZWUgPSBuZXcgSkNBbm5vdGF0aW9uKFRhZy5UWVBFX0FOTk9UQVRJT04sIGFubm90YXRpb25UeXBlLCBhcmdzKTsKICAgICAgICB0cmVlLnBvcyA9IHBvczsKICAgICAgICByZXR1cm4gdHJlZTsKICAgIH0KCiAgICBwdWJsaWMgSkNNb2RpZmllcnMgTW9kaWZpZXJzKGxvbmcgZmxhZ3MsIExpc3Q8SkNBbm5vdGF0aW9uPiBhbm5vdGF0aW9ucykgewogICAgICAgIEpDTW9kaWZpZXJzIHRyZWUgPSBuZXcgSkNNb2RpZmllcnMoZmxhZ3MsIGFubm90YXRpb25zKTsKICAgICAgICBib29sZWFuIG5vRmxhZ3MgPSAoZmxhZ3MgJiAoRmxhZ3MuTW9kaWZpZXJGbGFncyB8IEZsYWdzLkFOTk9UQVRJT04pKSA9PSAwOwogICAgICAgIHRyZWUucG9zID0gKG5vRmxhZ3MgJiYgYW5ub3RhdGlvbnMuaXNFbXB0eSgpKSA/IFBvc2l0aW9uLk5PUE9TIDogcG9zOwogICAgICAgIHJldHVybiB0cmVlOwogICAgfQoKICAgIHB1YmxpYyBKQ01vZGlmaWVycyBNb2RpZmllcnMobG9uZyBmbGFncykgewogICAgICAgIHJldHVybiBNb2RpZmllcnMoZmxhZ3MsIExpc3QubmlsKCkpOwogICAgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIEpDTW9kdWxlRGVjbCBNb2R1bGVEZWYoSkNNb2RpZmllcnMgbW9kcywgTW9kdWxlS2luZCBraW5kLAogICAgICAgICAgICBKQ0V4cHJlc3Npb24gcXVhbGlkLCBMaXN0PEpDRGlyZWN0aXZlPiBkaXJlY3RpdmVzKSB7CiAgICAgICAgSkNNb2R1bGVEZWNsIHRyZWUgPSBuZXcgSkNNb2R1bGVEZWNsKG1vZHMsIGtpbmQsIHF1YWxpZCwgZGlyZWN0aXZlcyk7CiAgICAgICAgdHJlZS5wb3MgPSBwb3M7CiAgICAgICAgcmV0dXJuIHRyZWU7CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgSkNFeHBvcnRzIEV4cG9ydHMoSkNFeHByZXNzaW9uIHF1YWxJZCwgTGlzdDxKQ0V4cHJlc3Npb24+IG1vZHVsZU5hbWVzKSB7CiAgICAgICAgSkNFeHBvcnRzIHRyZWUgPSBuZXcgSkNFeHBvcnRzKHF1YWxJZCwgbW9kdWxlTmFtZXMpOwogICAgICAgIHRyZWUucG9zID0gcG9zOwogICAgICAgIHJldHVybiB0cmVlOwogICAgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIEpDT3BlbnMgT3BlbnMoSkNFeHByZXNzaW9uIHF1YWxJZCwgTGlzdDxKQ0V4cHJlc3Npb24+IG1vZHVsZU5hbWVzKSB7CiAgICAgICAgSkNPcGVucyB0cmVlID0gbmV3IEpDT3BlbnMocXVhbElkLCBtb2R1bGVOYW1lcyk7CiAgICAgICAgdHJlZS5wb3MgPSBwb3M7CiAgICAgICAgcmV0dXJuIHRyZWU7CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgSkNQcm92aWRlcyBQcm92aWRlcyhKQ0V4cHJlc3Npb24gc2VydmljZU5hbWUsIExpc3Q8SkNFeHByZXNzaW9uPiBpbXBsTmFtZXMpIHsKICAgICAgICBKQ1Byb3ZpZGVzIHRyZWUgPSBuZXcgSkNQcm92aWRlcyhzZXJ2aWNlTmFtZSwgaW1wbE5hbWVzKTsKICAgICAgICB0cmVlLnBvcyA9IHBvczsKICAgICAgICByZXR1cm4gdHJlZTsKICAgIH0KCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBKQ1JlcXVpcmVzIFJlcXVpcmVzKGJvb2xlYW4gaXNUcmFuc2l0aXZlLCBib29sZWFuIGlzU3RhdGljUGhhc2UsIEpDRXhwcmVzc2lvbiBxdWFsSWQpIHsKICAgICAgICBKQ1JlcXVpcmVzIHRyZWUgPSBuZXcgSkNSZXF1aXJlcyhpc1RyYW5zaXRpdmUsIGlzU3RhdGljUGhhc2UsIHF1YWxJZCk7CiAgICAgICAgdHJlZS5wb3MgPSBwb3M7CiAgICAgICAgcmV0dXJuIHRyZWU7CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgSkNVc2VzIFVzZXMoSkNFeHByZXNzaW9uIHF1YWxJZCkgewogICAgICAgIEpDVXNlcyB0cmVlID0gbmV3IEpDVXNlcyhxdWFsSWQpOwogICAgICAgIHRyZWUucG9zID0gcG9zOwogICAgICAgIHJldHVybiB0cmVlOwogICAgfQoKICAgIHB1YmxpYyBKQ0Fubm90YXRlZFR5cGUgQW5ub3RhdGVkVHlwZShMaXN0PEpDQW5ub3RhdGlvbj4gYW5ub3RhdGlvbnMsIEpDRXhwcmVzc2lvbiB1bmRlcmx5aW5nVHlwZSkgewogICAgICAgIEpDQW5ub3RhdGVkVHlwZSB0cmVlID0gbmV3IEpDQW5ub3RhdGVkVHlwZShhbm5vdGF0aW9ucywgdW5kZXJseWluZ1R5cGUpOwogICAgICAgIHRyZWUucG9zID0gcG9zOwogICAgICAgIHJldHVybiB0cmVlOwogICAgfQoKICAgIHB1YmxpYyBKQ0Vycm9uZW91cyBFcnJvbmVvdXMoKSB7CiAgICAgICAgcmV0dXJuIEVycm9uZW91cyhMaXN0Lm5pbCgpKTsKICAgIH0KCiAgICBwdWJsaWMgSkNFcnJvbmVvdXMgRXJyb25lb3VzKExpc3Q8PyBleHRlbmRzIEpDVHJlZT4gZXJycykgewogICAgICAgIEpDRXJyb25lb3VzIHRyZWUgPSBuZXcgSkNFcnJvbmVvdXMoZXJycyk7CiAgICAgICAgdHJlZS5wb3MgPSBwb3M7CiAgICAgICAgcmV0dXJuIHRyZWU7CiAgICB9CgogICAgcHVibGljIExldEV4cHIgTGV0RXhwcihMaXN0PEpDVmFyaWFibGVEZWNsPiBkZWZzLCBKQ0V4cHJlc3Npb24gZXhwcikgewogICAgICAgIExldEV4cHIgdHJlZSA9IG5ldyBMZXRFeHByKGRlZnMsIGV4cHIpOwogICAgICAgIHRyZWUucG9zID0gcG9zOwogICAgICAgIHJldHVybiB0cmVlOwogICAgfQoKLyogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERlcml2ZWQgYnVpbGRpbmcgYmxvY2tzLgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiAgICBwdWJsaWMgSkNDbGFzc0RlY2wgQW5vbnltb3VzQ2xhc3NEZWYoSkNNb2RpZmllcnMgbW9kcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0PEpDVHJlZT4gZGVmcykKICAgIHsKICAgICAgICByZXR1cm4gQ2xhc3NEZWYobW9kcywKICAgICAgICAgICAgICAgICAgICAgICAgbmFtZXMuZW1wdHksCiAgICAgICAgICAgICAgICAgICAgICAgIExpc3QubmlsKCksCiAgICAgICAgICAgICAgICAgICAgICAgIG51bGwsCiAgICAgICAgICAgICAgICAgICAgICAgIExpc3QubmlsKCksCiAgICAgICAgICAgICAgICAgICAgICAgIGRlZnMpOwogICAgfQoKICAgIHB1YmxpYyBMZXRFeHByIExldEV4cHIoSkNWYXJpYWJsZURlY2wgZGVmLCBKQ0V4cHJlc3Npb24gZXhwcikgewogICAgICAgIExldEV4cHIgdHJlZSA9IG5ldyBMZXRFeHByKExpc3Qub2YoZGVmKSwgZXhwcik7CiAgICAgICAgdHJlZS5wb3MgPSBwb3M7CiAgICAgICAgcmV0dXJuIHRyZWU7CiAgICB9CgogICAgLyoqIENyZWF0ZSBhbiBpZGVudGlmaWVyIGZyb20gYSBzeW1ib2wuCiAgICAgKi8KICAgIHB1YmxpYyBKQ0lkZW50IElkZW50KFN5bWJvbCBzeW0pIHsKICAgICAgICByZXR1cm4gKEpDSWRlbnQpbmV3IEpDSWRlbnQoKHN5bS5uYW1lICE9IG5hbWVzLmVtcHR5KQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gc3ltLm5hbWUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IHN5bS5mbGF0TmFtZSgpLCBzeW0pCiAgICAgICAgICAgIC5zZXRQb3MocG9zKQogICAgICAgICAgICAuc2V0VHlwZShzeW0udHlwZSk7CiAgICB9CgogICAgLyoqIENyZWF0ZSBhIHNlbGVjdGlvbiBub2RlIGZyb20gYSBxdWFsaWZpZXIgdHJlZSBhbmQgYSBzeW1ib2wuCiAgICAgKiAgQHBhcmFtIGJhc2UgICBUaGUgcXVhbGlmaWVyIHRyZWUuCiAgICAgKi8KICAgIHB1YmxpYyBKQ0V4cHJlc3Npb24gU2VsZWN0KEpDRXhwcmVzc2lvbiBiYXNlLCBTeW1ib2wgc3ltKSB7CiAgICAgICAgcmV0dXJuIG5ldyBKQ0ZpZWxkQWNjZXNzKGJhc2UsIHN5bS5uYW1lLCBzeW0pLnNldFBvcyhwb3MpLnNldFR5cGUoc3ltLnR5cGUpOwogICAgfQoKICAgIC8qKiBDcmVhdGUgYSBxdWFsaWZpZWQgaWRlbnRpZmllciBmcm9tIGEgc3ltYm9sLCBhZGRpbmcgZW5vdWdoIHF1YWxpZmljYXRpb25zCiAgICAgKiAgdG8gbWFrZSB0aGUgcmVmZXJlbmNlIHVuaXF1ZS4KICAgICAqLwogICAgcHVibGljIEpDRXhwcmVzc2lvbiBRdWFsSWRlbnQoU3ltYm9sIHN5bSkgewogICAgICAgIHJldHVybiBpc1VucXVhbGlmaWFibGUoc3ltKQogICAgICAgICAgICA/IElkZW50KHN5bSkKICAgICAgICAgICAgOiBTZWxlY3QoUXVhbElkZW50KHN5bS5vd25lciksIHN5bSk7CiAgICB9CgogICAgLyoqIENyZWF0ZSBhbiBpZGVudGlmaWVyIHRoYXQgcmVmZXJzIHRvIHRoZSB2YXJpYWJsZSBkZWNsYXJlZCBpbiBnaXZlbiB2YXJpYWJsZQogICAgICogIGRlY2xhcmF0aW9uLgogICAgICovCiAgICBwdWJsaWMgSkNFeHByZXNzaW9uIElkZW50KEpDVmFyaWFibGVEZWNsIHBhcmFtKSB7CiAgICAgICAgcmV0dXJuIElkZW50KHBhcmFtLnN5bSk7CiAgICB9CgogICAgLyoqIENyZWF0ZSBhIGxpc3Qgb2YgaWRlbnRpZmllcnMgcmVmZXJyaW5nIHRvIHRoZSB2YXJpYWJsZXMgZGVjbGFyZWQKICAgICAqICBpbiBnaXZlbiBsaXN0IG9mIHZhcmlhYmxlIGRlY2xhcmF0aW9ucy4KICAgICAqLwogICAgcHVibGljIExpc3Q8SkNFeHByZXNzaW9uPiBJZGVudHMoTGlzdDxKQ1ZhcmlhYmxlRGVjbD4gcGFyYW1zKSB7CiAgICAgICAgTGlzdEJ1ZmZlcjxKQ0V4cHJlc3Npb24+IGlkcyA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICBmb3IgKExpc3Q8SkNWYXJpYWJsZURlY2w+IGwgPSBwYXJhbXM7IGwubm9uRW1wdHkoKTsgbCA9IGwudGFpbCkKICAgICAgICAgICAgaWRzLmFwcGVuZChJZGVudChsLmhlYWQpKTsKICAgICAgICByZXR1cm4gaWRzLnRvTGlzdCgpOwogICAgfQoKICAgIC8qKiBDcmVhdGUgYSB0cmVlIHJlcHJlc2VudGluZyBgdGhpcycsIGdpdmVuIGl0cyB0eXBlLgogICAgICovCiAgICBwdWJsaWMgSkNFeHByZXNzaW9uIFRoaXMoVHlwZSB0KSB7CiAgICAgICAgcmV0dXJuIElkZW50KG5ldyBWYXJTeW1ib2woRklOQUwsIG5hbWVzLl90aGlzLCB0LCB0LnRzeW0pKTsKICAgIH0KCiAgICAvKiogQ3JlYXRlIGEgdHJlZSByZXByZXNlbnRpbmcgcXVhbGlmaWVkIGB0aGlzJyBnaXZlbiBpdHMgdHlwZQogICAgICovCiAgICBwdWJsaWMgSkNFeHByZXNzaW9uIFF1YWxUaGlzKFR5cGUgdCkgewogICAgICAgIHJldHVybiBTZWxlY3QoVHlwZSh0KSwgbmV3IFZhclN5bWJvbChGSU5BTCwgbmFtZXMuX3RoaXMsIHQsIHQudHN5bSkpOwogICAgfQoKICAgIC8qKiBDcmVhdGUgYSB0cmVlIHJlcHJlc2VudGluZyBhIGNsYXNzIGxpdGVyYWwuCiAgICAgKi8KICAgIHB1YmxpYyBKQ0V4cHJlc3Npb24gQ2xhc3NMaXRlcmFsKENsYXNzU3ltYm9sIGNsYXp6KSB7CiAgICAgICAgcmV0dXJuIENsYXNzTGl0ZXJhbChjbGF6ei50eXBlKTsKICAgIH0KCiAgICAvKiogQ3JlYXRlIGEgdHJlZSByZXByZXNlbnRpbmcgYSBjbGFzcyBsaXRlcmFsLgogICAgICovCiAgICBwdWJsaWMgSkNFeHByZXNzaW9uIENsYXNzTGl0ZXJhbChUeXBlIHQpIHsKICAgICAgICBWYXJTeW1ib2wgbGl0ID0gbmV3IFZhclN5bWJvbChTVEFUSUMgfCBQVUJMSUMgfCBGSU5BTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lcy5fY2xhc3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0LnRzeW0pOwogICAgICAgIHJldHVybiBTZWxlY3QoVHlwZSh0KSwgbGl0KTsKICAgIH0KCiAgICAvKiogQ3JlYXRlIGEgdHJlZSByZXByZXNlbnRpbmcgYHN1cGVyJywgZ2l2ZW4gaXRzIHR5cGUgYW5kIG93bmVyLgogICAgICovCiAgICBwdWJsaWMgSkNJZGVudCBTdXBlcihUeXBlIHQsIFR5cGVTeW1ib2wgb3duZXIpIHsKICAgICAgICByZXR1cm4gSWRlbnQobmV3IFZhclN5bWJvbChGSU5BTCwgbmFtZXMuX3N1cGVyLCB0LCBvd25lcikpOwogICAgfQoKICAgIC8qKgogICAgICogQ3JlYXRlIGEgbWV0aG9kIGludm9jYXRpb24gZnJvbSBhIG1ldGhvZCB0cmVlIGFuZCBhIGxpc3Qgb2YKICAgICAqIGFyZ3VtZW50IHRyZWVzLgogICAgICovCiAgICBwdWJsaWMgSkNNZXRob2RJbnZvY2F0aW9uIEFwcChKQ0V4cHJlc3Npb24gbWV0aCwgTGlzdDxKQ0V4cHJlc3Npb24+IGFyZ3MpIHsKICAgICAgICByZXR1cm4gQXBwbHkobnVsbCwgbWV0aCwgYXJncykuc2V0VHlwZShtZXRoLnR5cGUuZ2V0UmV0dXJuVHlwZSgpKTsKICAgIH0KCiAgICAvKioKICAgICAqIENyZWF0ZSBhIG5vLWFyZyBtZXRob2QgaW52b2NhdGlvbiBmcm9tIGEgbWV0aG9kIHRyZWUKICAgICAqLwogICAgcHVibGljIEpDTWV0aG9kSW52b2NhdGlvbiBBcHAoSkNFeHByZXNzaW9uIG1ldGgpIHsKICAgICAgICByZXR1cm4gQXBwbHkobnVsbCwgbWV0aCwgTGlzdC5uaWwoKSkuc2V0VHlwZShtZXRoLnR5cGUuZ2V0UmV0dXJuVHlwZSgpKTsKICAgIH0KCiAgICAvKiogQ3JlYXRlIGEgbWV0aG9kIGludm9jYXRpb24gZnJvbSBhIG1ldGhvZCB0cmVlIGFuZCBhIGxpc3Qgb2YgYXJndW1lbnQgdHJlZXMuCiAgICAgKi8KICAgIHB1YmxpYyBKQ0V4cHJlc3Npb24gQ3JlYXRlKFN5bWJvbCBjdG9yLCBMaXN0PEpDRXhwcmVzc2lvbj4gYXJncykgewogICAgICAgIFR5cGUgdCA9IGN0b3Iub3duZXIuZXJhc3VyZSh0eXBlcyk7CiAgICAgICAgSkNOZXdDbGFzcyBuZXdjbGFzcyA9IE5ld0NsYXNzKG51bGwsIG51bGwsIFR5cGUodCksIGFyZ3MsIG51bGwpOwogICAgICAgIG5ld2NsYXNzLmNvbnN0cnVjdG9yID0gY3RvcjsKICAgICAgICBuZXdjbGFzcy5zZXRUeXBlKHQpOwogICAgICAgIHJldHVybiBuZXdjbGFzczsKICAgIH0KCiAgICAvKiogQ3JlYXRlIGEgdHJlZSByZXByZXNlbnRpbmcgZ2l2ZW4gdHlwZS4KICAgICAqLwogICAgcHVibGljIEpDRXhwcmVzc2lvbiBUeXBlKFR5cGUgdCkgewogICAgICAgIGlmICh0ID09IG51bGwpIHJldHVybiBudWxsOwogICAgICAgIEpDRXhwcmVzc2lvbiB0cDsKICAgICAgICBzd2l0Y2ggKHQuZ2V0VGFnKCkpIHsKICAgICAgICBjYXNlIEJZVEU6IGNhc2UgQ0hBUjogY2FzZSBTSE9SVDogY2FzZSBJTlQ6IGNhc2UgTE9ORzogY2FzZSBGTE9BVDoKICAgICAgICBjYXNlIERPVUJMRTogY2FzZSBCT09MRUFOOiBjYXNlIFZPSUQ6CiAgICAgICAgICAgIHRwID0gVHlwZUlkZW50KHQuZ2V0VGFnKCkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFRZUEVWQVI6CiAgICAgICAgICAgIHRwID0gSWRlbnQodC50c3ltKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBXSUxEQ0FSRDogewogICAgICAgICAgICBXaWxkY2FyZFR5cGUgYSA9ICgoV2lsZGNhcmRUeXBlKSB0KTsKICAgICAgICAgICAgdHAgPSBXaWxkY2FyZChUeXBlQm91bmRLaW5kKGEua2luZCksIGEua2luZCA9PSBCb3VuZEtpbmQuVU5CT1VORCA/IG51bGwgOiBUeXBlKGEudHlwZSkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgY2FzZSBDTEFTUzoKICAgICAgICAgICAgc3dpdGNoICh0LmdldEtpbmQoKSkgewogICAgICAgICAgICBjYXNlIFVOSU9OOiB7CiAgICAgICAgICAgICAgICBVbmlvbkNsYXNzVHlwZSB0dSA9IChVbmlvbkNsYXNzVHlwZSl0OwogICAgICAgICAgICAgICAgTGlzdEJ1ZmZlcjxKQ0V4cHJlc3Npb24+IGxhID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgICAgICAgICAgZm9yIChUeXBlIHRhIDogdHUuZ2V0QWx0ZXJuYXRpdmVUeXBlcygpKSB7CiAgICAgICAgICAgICAgICAgICAgbGEuYWRkKFR5cGUodGEpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHRwID0gVHlwZVVuaW9uKGxhLnRvTGlzdCgpKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGNhc2UgSU5URVJTRUNUSU9OOiB7CiAgICAgICAgICAgICAgICBJbnRlcnNlY3Rpb25DbGFzc1R5cGUgaXQgPSAoSW50ZXJzZWN0aW9uQ2xhc3NUeXBlKXQ7CiAgICAgICAgICAgICAgICBMaXN0QnVmZmVyPEpDRXhwcmVzc2lvbj4gbGEgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgICAgICBmb3IgKFR5cGUgdGEgOiBpdC5nZXRFeHBsaWNpdENvbXBvbmVudHMoKSkgewogICAgICAgICAgICAgICAgICAgIGxhLmFkZChUeXBlKHRhKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB0cCA9IFR5cGVJbnRlcnNlY3Rpb24obGEudG9MaXN0KCkpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgVHlwZSBvdXRlciA9IHQuZ2V0RW5jbG9zaW5nVHlwZSgpOwogICAgICAgICAgICAgICAgSkNFeHByZXNzaW9uIGNsYXp6ID0gb3V0ZXIuaGFzVGFnKENMQVNTKSAmJiB0LnRzeW0ub3duZXIua2luZCA9PSBUWVAKICAgICAgICAgICAgICAgICAgICAgICAgPyBTZWxlY3QoVHlwZShvdXRlciksIHQudHN5bSkKICAgICAgICAgICAgICAgICAgICAgICAgOiBRdWFsSWRlbnQodC50c3ltKTsKICAgICAgICAgICAgICAgIHRwID0gdC5nZXRUeXBlQXJndW1lbnRzKCkuaXNFbXB0eSgpCiAgICAgICAgICAgICAgICAgICAgICAgID8gY2xhenoKICAgICAgICAgICAgICAgICAgICAgICAgOiBUeXBlQXBwbHkoY2xhenosIFR5cGVzKHQuZ2V0VHlwZUFyZ3VtZW50cygpKSk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgQVJSQVk6CiAgICAgICAgICAgIHRwID0gVHlwZUFycmF5KFR5cGUodHlwZXMuZWxlbXR5cGUodCkpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBFUlJPUjoKICAgICAgICAgICAgdHAgPSBUeXBlSWRlbnQoRVJST1IpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoInVuZXhwZWN0ZWQgdHlwZTogIiArIHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdHAuc2V0VHlwZSh0KTsKICAgIH0KCiAgICAvKiogQ3JlYXRlIGEgbGlzdCBvZiB0cmVlcyByZXByZXNlbnRpbmcgZ2l2ZW4gbGlzdCBvZiB0eXBlcy4KICAgICAqLwogICAgcHVibGljIExpc3Q8SkNFeHByZXNzaW9uPiBUeXBlcyhMaXN0PFR5cGU+IHRzKSB7CiAgICAgICAgTGlzdEJ1ZmZlcjxKQ0V4cHJlc3Npb24+IGxiID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgIGZvciAoTGlzdDxUeXBlPiBsID0gdHM7IGwubm9uRW1wdHkoKTsgbCA9IGwudGFpbCkKICAgICAgICAgICAgbGIuYXBwZW5kKFR5cGUobC5oZWFkKSk7CiAgICAgICAgcmV0dXJuIGxiLnRvTGlzdCgpOwogICAgfQoKICAgIC8qKiBDcmVhdGUgYSB2YXJpYWJsZSBkZWZpbml0aW9uIGZyb20gYSB2YXJpYWJsZSBzeW1ib2wgYW5kIGFuIGluaXRpYWxpemVyCiAgICAgKiAgZXhwcmVzc2lvbi4KICAgICAqLwogICAgcHVibGljIEpDVmFyaWFibGVEZWNsIFZhckRlZihWYXJTeW1ib2wgdiwgSkNFeHByZXNzaW9uIGluaXQpIHsKICAgICAgICByZXR1cm4gKEpDVmFyaWFibGVEZWNsKQogICAgICAgICAgICBuZXcgSkNWYXJpYWJsZURlY2woCiAgICAgICAgICAgICAgICBNb2RpZmllcnModi5mbGFncygpLCBBbm5vdGF0aW9ucyh2LmdldFJhd0F0dHJpYnV0ZXMoKSkpLAogICAgICAgICAgICAgICAgdi5uYW1lLAogICAgICAgICAgICAgICAgVHlwZSh2LnR5cGUpLAogICAgICAgICAgICAgICAgaW5pdCwKICAgICAgICAgICAgICAgIHYpLnNldFBvcyhwb3MpLnNldFR5cGUodi50eXBlKTsKICAgIH0KCiAgICAvKiogQ3JlYXRlIGFubm90YXRpb24gdHJlZXMgZnJvbSBhbm5vdGF0aW9ucy4KICAgICAqLwogICAgcHVibGljIExpc3Q8SkNBbm5vdGF0aW9uPiBBbm5vdGF0aW9ucyhMaXN0PEF0dHJpYnV0ZS5Db21wb3VuZD4gYXR0cmlidXRlcykgewogICAgICAgIGlmIChhdHRyaWJ1dGVzID09IG51bGwpIHJldHVybiBMaXN0Lm5pbCgpOwogICAgICAgIExpc3RCdWZmZXI8SkNBbm5vdGF0aW9uPiByZXN1bHQgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgZm9yIChMaXN0PEF0dHJpYnV0ZS5Db21wb3VuZD4gaSA9IGF0dHJpYnV0ZXM7IGkubm9uRW1wdHkoKTsgaT1pLnRhaWwpIHsKICAgICAgICAgICAgQXR0cmlidXRlIGEgPSBpLmhlYWQ7CiAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoQW5ub3RhdGlvbihhKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQudG9MaXN0KCk7CiAgICB9CgogICAgcHVibGljIEpDTGl0ZXJhbCBMaXRlcmFsKE9iamVjdCB2YWx1ZSkgewogICAgICAgIEpDTGl0ZXJhbCByZXN1bHQgPSBudWxsOwogICAgICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgICByZXN1bHQgPSBMaXRlcmFsKENMQVNTLCB2YWx1ZSkuCiAgICAgICAgICAgICAgICBzZXRUeXBlKHN5bXMuc3RyaW5nVHlwZS5jb25zdFR5cGUodmFsdWUpKTsKICAgICAgICB9IGVsc2UgaWYgKHZhbHVlIGluc3RhbmNlb2YgSW50ZWdlcikgewogICAgICAgICAgICByZXN1bHQgPSBMaXRlcmFsKElOVCwgdmFsdWUpLgogICAgICAgICAgICAgICAgc2V0VHlwZShzeW1zLmludFR5cGUuY29uc3RUeXBlKHZhbHVlKSk7CiAgICAgICAgfSBlbHNlIGlmICh2YWx1ZSBpbnN0YW5jZW9mIExvbmcpIHsKICAgICAgICAgICAgcmVzdWx0ID0gTGl0ZXJhbChMT05HLCB2YWx1ZSkuCiAgICAgICAgICAgICAgICBzZXRUeXBlKHN5bXMubG9uZ1R5cGUuY29uc3RUeXBlKHZhbHVlKSk7CiAgICAgICAgfSBlbHNlIGlmICh2YWx1ZSBpbnN0YW5jZW9mIEJ5dGUpIHsKICAgICAgICAgICAgcmVzdWx0ID0gTGl0ZXJhbChCWVRFLCB2YWx1ZSkuCiAgICAgICAgICAgICAgICBzZXRUeXBlKHN5bXMuYnl0ZVR5cGUuY29uc3RUeXBlKHZhbHVlKSk7CiAgICAgICAgfSBlbHNlIGlmICh2YWx1ZSBpbnN0YW5jZW9mIENoYXJhY3RlcikgewogICAgICAgICAgICBpbnQgdiA9IChpbnQpICgoKENoYXJhY3RlcikgdmFsdWUpLnRvU3RyaW5nKCkuY2hhckF0KDApKTsKICAgICAgICAgICAgcmVzdWx0ID0gTGl0ZXJhbChDSEFSLCB2KS4KICAgICAgICAgICAgICAgIHNldFR5cGUoc3ltcy5jaGFyVHlwZS5jb25zdFR5cGUodikpOwogICAgICAgIH0gZWxzZSBpZiAodmFsdWUgaW5zdGFuY2VvZiBEb3VibGUpIHsKICAgICAgICAgICAgcmVzdWx0ID0gTGl0ZXJhbChET1VCTEUsIHZhbHVlKS4KICAgICAgICAgICAgICAgIHNldFR5cGUoc3ltcy5kb3VibGVUeXBlLmNvbnN0VHlwZSh2YWx1ZSkpOwogICAgICAgIH0gZWxzZSBpZiAodmFsdWUgaW5zdGFuY2VvZiBGbG9hdCkgewogICAgICAgICAgICByZXN1bHQgPSBMaXRlcmFsKEZMT0FULCB2YWx1ZSkuCiAgICAgICAgICAgICAgICBzZXRUeXBlKHN5bXMuZmxvYXRUeXBlLmNvbnN0VHlwZSh2YWx1ZSkpOwogICAgICAgIH0gZWxzZSBpZiAodmFsdWUgaW5zdGFuY2VvZiBTaG9ydCkgewogICAgICAgICAgICByZXN1bHQgPSBMaXRlcmFsKFNIT1JULCB2YWx1ZSkuCiAgICAgICAgICAgICAgICBzZXRUeXBlKHN5bXMuc2hvcnRUeXBlLmNvbnN0VHlwZSh2YWx1ZSkpOwogICAgICAgIH0gZWxzZSBpZiAodmFsdWUgaW5zdGFuY2VvZiBCb29sZWFuKSB7CiAgICAgICAgICAgIGludCB2ID0gKChCb29sZWFuKSB2YWx1ZSkgPyAxIDogMDsKICAgICAgICAgICAgcmVzdWx0ID0gTGl0ZXJhbChCT09MRUFOLCB2KS4KICAgICAgICAgICAgICAgIHNldFR5cGUoc3ltcy5ib29sZWFuVHlwZS5jb25zdFR5cGUodikpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcih2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9CgogICAgY2xhc3MgQW5ub3RhdGlvbkJ1aWxkZXIgaW1wbGVtZW50cyBBdHRyaWJ1dGUuVmlzaXRvciB7CiAgICAgICAgSkNFeHByZXNzaW9uIHJlc3VsdCA9IG51bGw7CiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRDb25zdGFudChBdHRyaWJ1dGUuQ29uc3RhbnQgdikgewogICAgICAgICAgICByZXN1bHQgPSBMaXRlcmFsKHYudHlwZS5nZXRUYWcoKSwgdi52YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0Q2xhc3MoQXR0cmlidXRlLkNsYXNzIGNsYXp6KSB7CiAgICAgICAgICAgIHJlc3VsdCA9IENsYXNzTGl0ZXJhbChjbGF6ei5jbGFzc1R5cGUpLnNldFR5cGUoc3ltcy5jbGFzc1R5cGUpOwogICAgICAgIH0KICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdEVudW0oQXR0cmlidXRlLkVudW0gZSkgewogICAgICAgICAgICByZXN1bHQgPSBRdWFsSWRlbnQoZS52YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0RXJyb3IoQXR0cmlidXRlLkVycm9yIGUpIHsKICAgICAgICAgICAgcmVzdWx0ID0gRXJyb25lb3VzKCk7CiAgICAgICAgfQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0Q29tcG91bmQoQXR0cmlidXRlLkNvbXBvdW5kIGNvbXBvdW5kKSB7CiAgICAgICAgICAgIGlmIChjb21wb3VuZCBpbnN0YW5jZW9mIEF0dHJpYnV0ZS5UeXBlQ29tcG91bmQpIHsKICAgICAgICAgICAgICAgIHJlc3VsdCA9IHZpc2l0VHlwZUNvbXBvdW5kSW50ZXJuYWwoKEF0dHJpYnV0ZS5UeXBlQ29tcG91bmQpIGNvbXBvdW5kKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHJlc3VsdCA9IHZpc2l0Q29tcG91bmRJbnRlcm5hbChjb21wb3VuZCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcHVibGljIEpDQW5ub3RhdGlvbiB2aXNpdENvbXBvdW5kSW50ZXJuYWwoQXR0cmlidXRlLkNvbXBvdW5kIGNvbXBvdW5kKSB7CiAgICAgICAgICAgIExpc3RCdWZmZXI8SkNFeHByZXNzaW9uPiBhcmdzID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgICAgICBmb3IgKExpc3Q8UGFpcjxTeW1ib2wuTWV0aG9kU3ltYm9sLEF0dHJpYnV0ZT4+IHZhbHVlcyA9IGNvbXBvdW5kLnZhbHVlczsgdmFsdWVzLm5vbkVtcHR5KCk7IHZhbHVlcz12YWx1ZXMudGFpbCkgewogICAgICAgICAgICAgICAgUGFpcjxNZXRob2RTeW1ib2wsQXR0cmlidXRlPiBwYWlyID0gdmFsdWVzLmhlYWQ7CiAgICAgICAgICAgICAgICBKQ0V4cHJlc3Npb24gdmFsdWVUcmVlID0gdHJhbnNsYXRlKHBhaXIuc25kKTsKICAgICAgICAgICAgICAgIGFyZ3MuYXBwZW5kKEFzc2lnbihJZGVudChwYWlyLmZzdCksIHZhbHVlVHJlZSkuc2V0VHlwZSh2YWx1ZVRyZWUudHlwZSkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBBbm5vdGF0aW9uKFR5cGUoY29tcG91bmQudHlwZSksIGFyZ3MudG9MaXN0KCkpOwogICAgICAgIH0KICAgICAgICBwdWJsaWMgSkNBbm5vdGF0aW9uIHZpc2l0VHlwZUNvbXBvdW5kSW50ZXJuYWwoQXR0cmlidXRlLlR5cGVDb21wb3VuZCBjb21wb3VuZCkgewogICAgICAgICAgICBMaXN0QnVmZmVyPEpDRXhwcmVzc2lvbj4gYXJncyA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICAgICAgZm9yIChMaXN0PFBhaXI8U3ltYm9sLk1ldGhvZFN5bWJvbCxBdHRyaWJ1dGU+PiB2YWx1ZXMgPSBjb21wb3VuZC52YWx1ZXM7IHZhbHVlcy5ub25FbXB0eSgpOyB2YWx1ZXM9dmFsdWVzLnRhaWwpIHsKICAgICAgICAgICAgICAgIFBhaXI8TWV0aG9kU3ltYm9sLEF0dHJpYnV0ZT4gcGFpciA9IHZhbHVlcy5oZWFkOwogICAgICAgICAgICAgICAgSkNFeHByZXNzaW9uIHZhbHVlVHJlZSA9IHRyYW5zbGF0ZShwYWlyLnNuZCk7CiAgICAgICAgICAgICAgICBhcmdzLmFwcGVuZChBc3NpZ24oSWRlbnQocGFpci5mc3QpLCB2YWx1ZVRyZWUpLnNldFR5cGUodmFsdWVUcmVlLnR5cGUpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gVHlwZUFubm90YXRpb24oVHlwZShjb21wb3VuZC50eXBlKSwgYXJncy50b0xpc3QoKSk7CiAgICAgICAgfQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0QXJyYXkoQXR0cmlidXRlLkFycmF5IGFycmF5KSB7CiAgICAgICAgICAgIExpc3RCdWZmZXI8SkNFeHByZXNzaW9uPiBlbGVtcyA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhcnJheS52YWx1ZXMubGVuZ3RoOyBpKyspCiAgICAgICAgICAgICAgICBlbGVtcy5hcHBlbmQodHJhbnNsYXRlKGFycmF5LnZhbHVlc1tpXSkpOwogICAgICAgICAgICByZXN1bHQgPSBOZXdBcnJheShudWxsLCBMaXN0Lm5pbCgpLCBlbGVtcy50b0xpc3QoKSkuc2V0VHlwZShhcnJheS50eXBlKTsKICAgICAgICB9CiAgICAgICAgSkNFeHByZXNzaW9uIHRyYW5zbGF0ZShBdHRyaWJ1dGUgYSkgewogICAgICAgICAgICBhLmFjY2VwdCh0aGlzKTsKICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CiAgICAgICAgSkNBbm5vdGF0aW9uIHRyYW5zbGF0ZShBdHRyaWJ1dGUuQ29tcG91bmQgYSkgewogICAgICAgICAgICByZXR1cm4gdmlzaXRDb21wb3VuZEludGVybmFsKGEpOwogICAgICAgIH0KICAgICAgICBKQ0Fubm90YXRpb24gdHJhbnNsYXRlKEF0dHJpYnV0ZS5UeXBlQ29tcG91bmQgYSkgewogICAgICAgICAgICByZXR1cm4gdmlzaXRUeXBlQ29tcG91bmRJbnRlcm5hbChhKTsKICAgICAgICB9CiAgICB9CgogICAgQW5ub3RhdGlvbkJ1aWxkZXIgYW5ub3RhdGlvbkJ1aWxkZXIgPSBuZXcgQW5ub3RhdGlvbkJ1aWxkZXIoKTsKCiAgICAvKiogQ3JlYXRlIGFuIGFubm90YXRpb24gdHJlZSBmcm9tIGFuIGF0dHJpYnV0ZS4KICAgICAqLwogICAgcHVibGljIEpDQW5ub3RhdGlvbiBBbm5vdGF0aW9uKEF0dHJpYnV0ZSBhKSB7CiAgICAgICAgcmV0dXJuIGFubm90YXRpb25CdWlsZGVyLnRyYW5zbGF0ZSgoQXR0cmlidXRlLkNvbXBvdW5kKWEpOwogICAgfQoKICAgIHB1YmxpYyBKQ0Fubm90YXRpb24gVHlwZUFubm90YXRpb24oQXR0cmlidXRlIGEpIHsKICAgICAgICByZXR1cm4gYW5ub3RhdGlvbkJ1aWxkZXIudHJhbnNsYXRlKChBdHRyaWJ1dGUuVHlwZUNvbXBvdW5kKSBhKTsKICAgIH0KCiAgICAvKiogQ3JlYXRlIGEgbWV0aG9kIGRlZmluaXRpb24gZnJvbSBhIG1ldGhvZCBzeW1ib2wgYW5kIGEgbWV0aG9kIGJvZHkuCiAgICAgKi8KICAgIHB1YmxpYyBKQ01ldGhvZERlY2wgTWV0aG9kRGVmKE1ldGhvZFN5bWJvbCBtLCBKQ0Jsb2NrIGJvZHkpIHsKICAgICAgICByZXR1cm4gTWV0aG9kRGVmKG0sIG0udHlwZSwgYm9keSk7CiAgICB9CgogICAgLyoqIENyZWF0ZSBhIG1ldGhvZCBkZWZpbml0aW9uIGZyb20gYSBtZXRob2Qgc3ltYm9sLCBtZXRob2QgdHlwZQogICAgICogIGFuZCBhIG1ldGhvZCBib2R5LgogICAgICovCiAgICBwdWJsaWMgSkNNZXRob2REZWNsIE1ldGhvZERlZihNZXRob2RTeW1ib2wgbSwgVHlwZSBtdHlwZSwgSkNCbG9jayBib2R5KSB7CiAgICAgICAgcmV0dXJuIChKQ01ldGhvZERlY2wpCiAgICAgICAgICAgIG5ldyBKQ01ldGhvZERlY2woCiAgICAgICAgICAgICAgICBNb2RpZmllcnMobS5mbGFncygpLCBBbm5vdGF0aW9ucyhtLmdldFJhd0F0dHJpYnV0ZXMoKSkpLAogICAgICAgICAgICAgICAgbS5uYW1lLAogICAgICAgICAgICAgICAgVHlwZShtdHlwZS5nZXRSZXR1cm5UeXBlKCkpLAogICAgICAgICAgICAgICAgVHlwZVBhcmFtcyhtdHlwZS5nZXRUeXBlQXJndW1lbnRzKCkpLAogICAgICAgICAgICAgICAgbnVsbCwgLy8gcmVjZWl2ZXIgdHlwZQogICAgICAgICAgICAgICAgUGFyYW1zKG10eXBlLmdldFBhcmFtZXRlclR5cGVzKCksIG0pLAogICAgICAgICAgICAgICAgVHlwZXMobXR5cGUuZ2V0VGhyb3duVHlwZXMoKSksCiAgICAgICAgICAgICAgICBib2R5LAogICAgICAgICAgICAgICAgbnVsbCwKICAgICAgICAgICAgICAgIG0pLnNldFBvcyhwb3MpLnNldFR5cGUobXR5cGUpOwogICAgfQoKICAgIC8qKiBDcmVhdGUgYSB0eXBlIHBhcmFtZXRlciB0cmVlIGZyb20gaXRzIG5hbWUgYW5kIHR5cGUuCiAgICAgKi8KICAgIHB1YmxpYyBKQ1R5cGVQYXJhbWV0ZXIgVHlwZVBhcmFtKE5hbWUgbmFtZSwgVHlwZVZhciB0dmFyKSB7CiAgICAgICAgcmV0dXJuIChKQ1R5cGVQYXJhbWV0ZXIpCiAgICAgICAgICAgIFR5cGVQYXJhbWV0ZXIobmFtZSwgVHlwZXModHlwZXMuZ2V0Qm91bmRzKHR2YXIpKSkuc2V0UG9zKHBvcykuc2V0VHlwZSh0dmFyKTsKICAgIH0KCiAgICAvKiogQ3JlYXRlIGEgbGlzdCBvZiB0eXBlIHBhcmFtZXRlciB0cmVlcyBmcm9tIGEgbGlzdCBvZiB0eXBlIHZhcmlhYmxlcy4KICAgICAqLwogICAgcHVibGljIExpc3Q8SkNUeXBlUGFyYW1ldGVyPiBUeXBlUGFyYW1zKExpc3Q8VHlwZT4gdHlwYXJhbXMpIHsKICAgICAgICBMaXN0QnVmZmVyPEpDVHlwZVBhcmFtZXRlcj4gdHBhcmFtcyA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICBmb3IgKExpc3Q8VHlwZT4gbCA9IHR5cGFyYW1zOyBsLm5vbkVtcHR5KCk7IGwgPSBsLnRhaWwpCiAgICAgICAgICAgIHRwYXJhbXMuYXBwZW5kKFR5cGVQYXJhbShsLmhlYWQudHN5bS5uYW1lLCAoVHlwZVZhcilsLmhlYWQpKTsKICAgICAgICByZXR1cm4gdHBhcmFtcy50b0xpc3QoKTsKICAgIH0KCiAgICAvKiogQ3JlYXRlIGEgdmFsdWUgcGFyYW1ldGVyIHRyZWUgZnJvbSBpdHMgbmFtZSwgdHlwZSwgYW5kIG93bmVyLgogICAgICovCiAgICBwdWJsaWMgSkNWYXJpYWJsZURlY2wgUGFyYW0oTmFtZSBuYW1lLCBUeXBlIGFyZ3R5cGUsIFN5bWJvbCBvd25lcikgewogICAgICAgIHJldHVybiBWYXJEZWYobmV3IFZhclN5bWJvbChQQVJBTUVURVIsIG5hbWUsIGFyZ3R5cGUsIG93bmVyKSwgbnVsbCk7CiAgICB9CgogICAgLyoqIENyZWF0ZSBhIGEgbGlzdCBvZiB2YWx1ZSBwYXJhbWV0ZXIgdHJlZXMgeDAsIC4uLiwgeG4gZnJvbSBhIGxpc3Qgb2YKICAgICAqICB0aGVpciB0eXBlcyBhbmQgYW4gdGhlaXIgb3duZXIuCiAgICAgKi8KICAgIHB1YmxpYyBMaXN0PEpDVmFyaWFibGVEZWNsPiBQYXJhbXMoTGlzdDxUeXBlPiBhcmd0eXBlcywgU3ltYm9sIG93bmVyKSB7CiAgICAgICAgTGlzdEJ1ZmZlcjxKQ1ZhcmlhYmxlRGVjbD4gcGFyYW1zID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgIE1ldGhvZFN5bWJvbCBtdGggPSAob3duZXIua2luZCA9PSBNVEgpID8gKChNZXRob2RTeW1ib2wpb3duZXIpIDogbnVsbDsKICAgICAgICBpZiAobXRoICE9IG51bGwgJiYgbXRoLnBhcmFtcyAhPSBudWxsICYmIGFyZ3R5cGVzLmxlbmd0aCgpID09IG10aC5wYXJhbXMubGVuZ3RoKCkpIHsKICAgICAgICAgICAgZm9yIChWYXJTeW1ib2wgcGFyYW0gOiAoKE1ldGhvZFN5bWJvbClvd25lcikucGFyYW1zKQogICAgICAgICAgICAgICAgcGFyYW1zLmFwcGVuZChWYXJEZWYocGFyYW0sIG51bGwpKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBpbnQgaSA9IDA7CiAgICAgICAgICAgIGZvciAoTGlzdDxUeXBlPiBsID0gYXJndHlwZXM7IGwubm9uRW1wdHkoKTsgbCA9IGwudGFpbCkKICAgICAgICAgICAgICAgIHBhcmFtcy5hcHBlbmQoUGFyYW0ocGFyYW1OYW1lKGkrKyksIGwuaGVhZCwgb3duZXIpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHBhcmFtcy50b0xpc3QoKTsKICAgIH0KCiAgICAvKiogV3JhcCBhIG1ldGhvZCBpbnZvY2F0aW9uIGluIGFuIGV4cHJlc3Npb24gc3RhdGVtZW50IG9yIHJldHVybiBzdGF0ZW1lbnQsCiAgICAgKiAgZGVwZW5kaW5nIG9uIHdoZXRoZXIgdGhlIG1ldGhvZCBpbnZvY2F0aW9uIGV4cHJlc3Npb24ncyB0eXBlIGlzIHZvaWQuCiAgICAgKi8KICAgIHB1YmxpYyBKQ1N0YXRlbWVudCBDYWxsKEpDRXhwcmVzc2lvbiBhcHBseSkgewogICAgICAgIHJldHVybiBhcHBseS50eXBlLmhhc1RhZyhWT0lEKSA/IEV4ZWMoYXBwbHkpIDogUmV0dXJuKGFwcGx5KTsKICAgIH0KCiAgICAvKiogQ29uc3RydWN0IGFuIGFzc2lnbm1lbnQgZnJvbSBhIHZhcmlhYmxlIHN5bWJvbCBhbmQgYSByaWdodCBoYW5kIHNpZGUuCiAgICAgKi8KICAgIHB1YmxpYyBKQ1N0YXRlbWVudCBBc3NpZ25tZW50KFN5bWJvbCB2LCBKQ0V4cHJlc3Npb24gcmhzKSB7CiAgICAgICAgcmV0dXJuIEV4ZWMoQXNzaWduKElkZW50KHYpLCByaHMpLnNldFR5cGUodi50eXBlKSk7CiAgICB9CgogICAgLyoqIENvbnN0cnVjdCBhbiBpbmRleCBleHByZXNzaW9uIGZyb20gYSB2YXJpYWJsZSBhbmQgYW4gZXhwcmVzc2lvbi4KICAgICAqLwogICAgcHVibGljIEpDQXJyYXlBY2Nlc3MgSW5kZXhlZChTeW1ib2wgdiwgSkNFeHByZXNzaW9uIGluZGV4KSB7CiAgICAgICAgSkNBcnJheUFjY2VzcyB0cmVlID0gbmV3IEpDQXJyYXlBY2Nlc3MoUXVhbElkZW50KHYpLCBpbmRleCk7CiAgICAgICAgdHJlZS50eXBlID0gKChBcnJheVR5cGUpdi50eXBlKS5lbGVtdHlwZTsKICAgICAgICByZXR1cm4gdHJlZTsKICAgIH0KCiAgICAvKiogTWFrZSBhbiBhdHRyaWJ1dGVkIHR5cGUgY2FzdCBleHByZXNzaW9uLgogICAgICovCiAgICBwdWJsaWMgSkNUeXBlQ2FzdCBUeXBlQ2FzdChUeXBlIHR5cGUsIEpDRXhwcmVzc2lvbiBleHByKSB7CiAgICAgICAgcmV0dXJuIChKQ1R5cGVDYXN0KVR5cGVDYXN0KFR5cGUodHlwZSksIGV4cHIpLnNldFR5cGUodHlwZSk7CiAgICB9CgovKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSGVscGVyIG1ldGhvZHMuCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKICAgIC8qKiBDYW4gZ2l2ZW4gc3ltYm9sIGJlIHJlZmVycmVkIHRvIGluIHVucXVhbGlmaWVkIGZvcm0/CiAgICAgKi8KICAgIGJvb2xlYW4gaXNVbnF1YWxpZmlhYmxlKFN5bWJvbCBzeW0pIHsKICAgICAgICBpZiAoc3ltLm5hbWUgPT0gbmFtZXMuZW1wdHkgfHwKICAgICAgICAgICAgc3ltLm93bmVyID09IG51bGwgfHwKICAgICAgICAgICAgc3ltLm93bmVyID09IHN5bXMucm9vdFBhY2thZ2UgfHwKICAgICAgICAgICAgc3ltLm93bmVyLmtpbmQgPT0gTVRIIHx8IHN5bS5vd25lci5raW5kID09IFZBUikgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9IGVsc2UgaWYgKHN5bS5raW5kID09IFRZUCAmJiB0b3BsZXZlbCAhPSBudWxsKSB7CiAgICAgICAgICAgIEl0ZXJhdG9yPFN5bWJvbD4gaXQgPSB0b3BsZXZlbC5uYW1lZEltcG9ydFNjb3BlLmdldFN5bWJvbHNCeU5hbWUoc3ltLm5hbWUpLml0ZXJhdG9yKCk7CiAgICAgICAgICAgIGlmIChpdC5oYXNOZXh0KCkpIHsKICAgICAgICAgICAgICAgIFN5bWJvbCBzID0gaXQubmV4dCgpOwogICAgICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgICAgICAgICAgIHMgPT0gc3ltICYmCiAgICAgICAgICAgICAgICAgICFpdC5oYXNOZXh0KCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaXQgPSB0b3BsZXZlbC5wYWNrZ2UubWVtYmVycygpLmdldFN5bWJvbHNCeU5hbWUoc3ltLm5hbWUpLml0ZXJhdG9yKCk7CiAgICAgICAgICAgIGlmIChpdC5oYXNOZXh0KCkpIHsKICAgICAgICAgICAgICAgIFN5bWJvbCBzID0gaXQubmV4dCgpOwogICAgICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgICAgICAgICAgIHMgPT0gc3ltICYmCiAgICAgICAgICAgICAgICAgICFpdC5oYXNOZXh0KCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaXQgPSB0b3BsZXZlbC5zdGFySW1wb3J0U2NvcGUuZ2V0U3ltYm9sc0J5TmFtZShzeW0ubmFtZSkuaXRlcmF0b3IoKTsKICAgICAgICAgICAgaWYgKGl0Lmhhc05leHQoKSkgewogICAgICAgICAgICAgICAgU3ltYm9sIHMgPSBpdC5uZXh0KCk7CiAgICAgICAgICAgICAgICByZXR1cm4KICAgICAgICAgICAgICAgICAgcyA9PSBzeW0gJiYKICAgICAgICAgICAgICAgICAgIWl0Lmhhc05leHQoKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgLyoqIFRoZSBuYW1lIG9mIHN5bnRoZXRpYyBwYXJhbWV0ZXIgbnVtYmVyIGBpJy4KICAgICAqLwogICAgcHVibGljIE5hbWUgcGFyYW1OYW1lKGludCBpKSAgIHsgcmV0dXJuIG5hbWVzLmZyb21TdHJpbmcoIngiICsgaSk7IH0KCiAgICAvKiogVGhlIG5hbWUgb2Ygc3ludGhldGljIHR5cGUgcGFyYW1ldGVyIG51bWJlciBgaScuCiAgICAgKi8KICAgIHB1YmxpYyBOYW1lIHR5cGFyYW1OYW1lKGludCBpKSB7IHJldHVybiBuYW1lcy5mcm9tU3RyaW5nKCJBIiArIGkpOyB9Cn0KUEsDBAoAAAgAAAY7qUphVYraWboAAFm6AAAkAAAAY29tL3N1bi90b29scy9qYXZhYy90cmVlL1ByZXR0eS5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAxOTk5LCAyMDE2LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuamF2YWMudHJlZTsKCmltcG9ydCBqYXZhLmlvLio7CgppbXBvcnQgY29tLnN1bi5zb3VyY2UudHJlZS5NZW1iZXJSZWZlcmVuY2VUcmVlLlJlZmVyZW5jZU1vZGU7CmltcG9ydCBjb20uc3VuLnNvdXJjZS50cmVlLk1vZHVsZVRyZWUuTW9kdWxlS2luZDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS4qOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkpDVHJlZS4qOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLio7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuTGlzdDsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuRmxhZ3MuKjsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuRmxhZ3MuQU5OT1RBVElPTjsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuSkNUcmVlLlRhZy4qOwoKLyoqIFByaW50cyBvdXQgYSB0cmVlIGFzIGFuIGluZGVudGVkIEphdmEgc291cmNlIHByb2dyYW0uCiAqCiAqICA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiAgSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93biByaXNrLgogKiAgVGhpcyBjb2RlIGFuZCBpdHMgaW50ZXJuYWwgaW50ZXJmYWNlcyBhcmUgc3ViamVjdCB0byBjaGFuZ2Ugb3IKICogIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj4KICovCnB1YmxpYyBjbGFzcyBQcmV0dHkgZXh0ZW5kcyBKQ1RyZWUuVmlzaXRvciB7CgogICAgcHVibGljIFByZXR0eShXcml0ZXIgb3V0LCBib29sZWFuIHNvdXJjZU91dHB1dCkgewogICAgICAgIHRoaXMub3V0ID0gb3V0OwogICAgICAgIHRoaXMuc291cmNlT3V0cHV0ID0gc291cmNlT3V0cHV0OwogICAgfQoKICAgIC8qKiBTZXQgd2hlbiB3ZSBhcmUgcHJvZHVjaW5nIHNvdXJjZSBvdXRwdXQuICBJZiB3ZSdyZSBub3QKICAgICAqICBwcm9kdWNpbmcgc291cmNlIG91dHB1dCwgd2UgY2FuIHNvbWV0aW1lcyBnaXZlIG1vcmUgZGV0YWlsIGluCiAgICAgKiAgdGhlIG91dHB1dCBldmVuIHRob3VnaCB0aGF0IGRldGFpbCB3b3VsZCBub3QgYmUgdmFsaWQgamF2YQogICAgICogIHNvdXJjZS4KICAgICAqLwogICAgcHJpdmF0ZSBmaW5hbCBib29sZWFuIHNvdXJjZU91dHB1dDsKCiAgICAvKiogVGhlIG91dHB1dCBzdHJlYW0gb24gd2hpY2ggdHJlZXMgYXJlIHByaW50ZWQuCiAgICAgKi8KICAgIFdyaXRlciBvdXQ7CgogICAgLyoqIEluZGVudGF0aW9uIHdpZHRoIChjYW4gYmUgcmVhc3NpZ25lZCBmcm9tIG91dHNpZGUpLgogICAgICovCiAgICBwdWJsaWMgaW50IHdpZHRoID0gNDsKCiAgICAvKiogVGhlIGN1cnJlbnQgbGVmdCBtYXJnaW4uCiAgICAgKi8KICAgIGludCBsbWFyZ2luID0gMDsKCiAgICAvKiogVGhlIGVuY2xvc2luZyBjbGFzcyBuYW1lLgogICAgICovCiAgICBOYW1lIGVuY2xDbGFzc05hbWU7CgogICAgLyoqIEEgdGFibGUgbWFwcGluZyB0cmVlcyB0byB0aGVpciBkb2N1bWVudGF0aW9uIGNvbW1lbnRzCiAgICAgKiAgKGNhbiBiZSBudWxsKQogICAgICovCiAgICBEb2NDb21tZW50VGFibGUgZG9jQ29tbWVudHMgPSBudWxsOwoKICAgIC8qKgogICAgICogQSBzdHJpbmcgc2VxdWVuY2UgdG8gYmUgdXNlZCB3aGVuIFByZXR0eSBvdXRwdXQgc2hvdWxkIGJlIGNvbnN0cmFpbmVkCiAgICAgKiB0byBmaXQgaW50byBhIGdpdmVuIHNpemUKICAgICAqLwogICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgU3RyaW5nIHRyaW1TZXF1ZW5jZSA9ICJbLi4uXSI7CgogICAgLyoqCiAgICAgKiBNYXggbnVtYmVyIG9mIGNoYXJzIHRvIGJlIGdlbmVyYXRlZCB3aGVuIG91dHB1dCBzaG91bGQgZml0IGludG8gYSBzaW5nbGUgbGluZQogICAgICovCiAgICBwcml2YXRlIGZpbmFsIHN0YXRpYyBpbnQgUFJFRkVSUkVEX0xFTkdUSCA9IDIwOwoKICAgIC8qKiBBbGlnbiBjb2RlIHRvIGJlIGluZGVudGVkIHRvIGxlZnQgbWFyZ2luLgogICAgICovCiAgICB2b2lkIGFsaWduKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxtYXJnaW47IGkrKykgb3V0LndyaXRlKCIgIik7CiAgICB9CgogICAgLyoqIEluY3JlYXNlIGxlZnQgbWFyZ2luIGJ5IGluZGVudGF0aW9uIHdpZHRoLgogICAgICovCiAgICB2b2lkIGluZGVudCgpIHsKICAgICAgICBsbWFyZ2luID0gbG1hcmdpbiArIHdpZHRoOwogICAgfQoKICAgIC8qKiBEZWNyZWFzZSBsZWZ0IG1hcmdpbiBieSBpbmRlbnRhdGlvbiB3aWR0aC4KICAgICAqLwogICAgdm9pZCB1bmRlbnQoKSB7CiAgICAgICAgbG1hcmdpbiA9IGxtYXJnaW4gLSB3aWR0aDsKICAgIH0KCiAgICAvKiogRW50ZXIgYSBuZXcgcHJlY2VkZW5jZSBsZXZlbC4gRW1pdCBhIGAoJyBpZiBuZXcgcHJlY2VkZW5jZSBsZXZlbAogICAgICogIGlzIGxlc3MgdGhhbiBwcmVjZWRlbmNlIGxldmVsIHNvIGZhci4KICAgICAqICBAcGFyYW0gY29udGV4dFByZWMgICAgVGhlIHByZWNlZGVuY2UgbGV2ZWwgaW4gZm9yY2Ugc28gZmFyLgogICAgICogIEBwYXJhbSBvd25QcmVjICAgICAgICBUaGUgbmV3IHByZWNlZGVuY2UgbGV2ZWwuCiAgICAgKi8KICAgIHZvaWQgb3BlbihpbnQgY29udGV4dFByZWMsIGludCBvd25QcmVjKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgIGlmIChvd25QcmVjIDwgY29udGV4dFByZWMpIG91dC53cml0ZSgiKCIpOwogICAgfQoKICAgIC8qKiBMZWF2ZSBwcmVjZWRlbmNlIGxldmVsLiBFbWl0IGEgYCgnIGlmIGlubmVyIHByZWNlZGVuY2UgbGV2ZWwKICAgICAqICBpcyBsZXNzIHRoYW4gcHJlY2VkZW5jZSBsZXZlbCB3ZSByZXZlcnQgdG8uCiAgICAgKiAgQHBhcmFtIGNvbnRleHRQcmVjICAgIFRoZSBwcmVjZWRlbmNlIGxldmVsIHdlIHJldmVydCB0by4KICAgICAqICBAcGFyYW0gb3duUHJlYyAgICAgICAgVGhlIGlubmVyIHByZWNlZGVuY2UgbGV2ZWwuCiAgICAgKi8KICAgIHZvaWQgY2xvc2UoaW50IGNvbnRleHRQcmVjLCBpbnQgb3duUHJlYykgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICBpZiAob3duUHJlYyA8IGNvbnRleHRQcmVjKSBvdXQud3JpdGUoIikiKTsKICAgIH0KCiAgICAvKiogUHJpbnQgc3RyaW5nLCByZXBsYWNpbmcgYWxsIG5vbi1hc2NpaSBjaGFyYWN0ZXIgd2l0aCB1bmljb2RlIGVzY2FwZXMuCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHByaW50KE9iamVjdCBzKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgIG91dC53cml0ZShDb252ZXJ0LmVzY2FwZVVuaWNvZGUocy50b1N0cmluZygpKSk7CiAgICB9CgogICAgLyoqIFByaW50IG5ldyBsaW5lLgogICAgICovCiAgICBwdWJsaWMgdm9pZCBwcmludGxuKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICBvdXQud3JpdGUobGluZVNlcCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBTdHJpbmcgdG9TaW1wbGVTdHJpbmcoSkNUcmVlIHRyZWUpIHsKICAgICAgICByZXR1cm4gdG9TaW1wbGVTdHJpbmcodHJlZSwgUFJFRkVSUkVEX0xFTkdUSCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBTdHJpbmcgdG9TaW1wbGVTdHJpbmcoSkNUcmVlIHRyZWUsIGludCBtYXhMZW5ndGgpIHsKICAgICAgICBTdHJpbmdXcml0ZXIgcyA9IG5ldyBTdHJpbmdXcml0ZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgICBuZXcgUHJldHR5KHMsIGZhbHNlKS5wcmludEV4cHIodHJlZSk7CiAgICAgICAgfQogICAgICAgIGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIC8vIHNob3VsZCBuZXZlciBoYXBwZW4sIGJlY2F1c2UgU3RyaW5nV3JpdGVyIGlzIGRlZmluZWQKICAgICAgICAgICAgLy8gbmV2ZXIgdG8gdGhyb3cgYW55IElPRXhjZXB0aW9ucwogICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoZSk7CiAgICAgICAgfQogICAgICAgIC8vd2UgbmVlZCB0byAoaSkgcmVwbGFjZSBhbGwgbGluZSB0ZXJtaW5hdG9ycyB3aXRoIGEgc3BhY2UgYW5kIChpaSkgcmVtb3ZlCiAgICAgICAgLy9vY2N1cnJlbmNlcyBvZiAnbWlzc2luZycgaW4gdGhlIFByZXR0eSBvdXRwdXQgKGdlbmVyYXRlZCB3aGVuIHR5cGVzIGFyZSBtaXNzaW5nKQogICAgICAgIFN0cmluZyByZXMgPSBzLnRvU3RyaW5nKCkudHJpbSgpLnJlcGxhY2VBbGwoIlxccysiLCAiICIpLnJlcGxhY2VBbGwoIi9cXCptaXNzaW5nXFwqLyIsICIiKTsKICAgICAgICBpZiAocmVzLmxlbmd0aCgpIDwgbWF4TGVuZ3RoKSB7CiAgICAgICAgICAgIHJldHVybiByZXM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgaW50IGhlYWQgPSAobWF4TGVuZ3RoIC0gdHJpbVNlcXVlbmNlLmxlbmd0aCgpKSAqIDIgLyAzOwogICAgICAgICAgICBpbnQgdGFpbCA9IG1heExlbmd0aCAtIHRyaW1TZXF1ZW5jZS5sZW5ndGgoKSAtIGhlYWQ7CiAgICAgICAgICAgIHJldHVybiByZXMuc3Vic3RyaW5nKDAsIGhlYWQpICsgdHJpbVNlcXVlbmNlICsgcmVzLnN1YnN0cmluZyhyZXMubGVuZ3RoKCkgLSB0YWlsKTsKICAgICAgICB9CiAgICB9CgogICAgU3RyaW5nIGxpbmVTZXAgPSBTeXN0ZW0uZ2V0UHJvcGVydHkoImxpbmUuc2VwYXJhdG9yIik7CgogICAgLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAgICAgKiBUcmF2ZXJzYWwgbWV0aG9kcwogICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgogICAgLyoqIEV4Y2VwdGlvbiB0byBwcm9wb2dhdGUgSU9FeGNlcHRpb24gdGhyb3VnaCB2aXNpdFhYWCBtZXRob2RzICovCiAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBVbmNoZWNrZWRJT0V4Y2VwdGlvbiBleHRlbmRzIEVycm9yIHsKICAgICAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTQwMzI2OTI2NzkxNTg0MjQ3NTFMOwogICAgICAgIFVuY2hlY2tlZElPRXhjZXB0aW9uKElPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgc3VwZXIoZS5nZXRNZXNzYWdlKCksIGUpOwogICAgICAgIH0KICAgIH0KCiAgICAvKiogVmlzaXRvciBhcmd1bWVudDogdGhlIGN1cnJlbnQgcHJlY2VkZW5jZSBsZXZlbC4KICAgICAqLwogICAgaW50IHByZWM7CgogICAgLyoqIFZpc2l0b3IgbWV0aG9kOiBwcmludCBleHByZXNzaW9uIHRyZWUuCiAgICAgKiAgQHBhcmFtIHByZWMgIFRoZSBjdXJyZW50IHByZWNlZGVuY2UgbGV2ZWwuCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHByaW50RXhwcihKQ1RyZWUgdHJlZSwgaW50IHByZWMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgaW50IHByZXZQcmVjID0gdGhpcy5wcmVjOwogICAgICAgIHRyeSB7CiAgICAgICAgICAgIHRoaXMucHJlYyA9IHByZWM7CiAgICAgICAgICAgIGlmICh0cmVlID09IG51bGwpIHByaW50KCIvKm1pc3NpbmcqLyIpOwogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIHRyZWUuYWNjZXB0KHRoaXMpOwogICAgICAgICAgICB9CiAgICAgICAgfSBjYXRjaCAoVW5jaGVja2VkSU9FeGNlcHRpb24gZXgpIHsKICAgICAgICAgICAgSU9FeGNlcHRpb24gZSA9IG5ldyBJT0V4Y2VwdGlvbihleC5nZXRNZXNzYWdlKCkpOwogICAgICAgICAgICBlLmluaXRDYXVzZShleCk7CiAgICAgICAgICAgIHRocm93IGU7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgdGhpcy5wcmVjID0gcHJldlByZWM7CiAgICAgICAgfQogICAgfQoKICAgIC8qKiBEZXJpdmVkIHZpc2l0b3IgbWV0aG9kOiBwcmludCBleHByZXNzaW9uIHRyZWUgYXQgbWluaW11bSBwcmVjZWRlbmNlIGxldmVsCiAgICAgKiAgZm9yIGV4cHJlc3Npb24uCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHByaW50RXhwcihKQ1RyZWUgdHJlZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICBwcmludEV4cHIodHJlZSwgVHJlZUluZm8ubm9QcmVjKTsKICAgIH0KCiAgICAvKiogRGVyaXZlZCB2aXNpdG9yIG1ldGhvZDogcHJpbnQgc3RhdGVtZW50IHRyZWUuCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHByaW50U3RhdChKQ1RyZWUgdHJlZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICBwcmludEV4cHIodHJlZSwgVHJlZUluZm8ubm90RXhwcmVzc2lvbik7CiAgICB9CgogICAgLyoqIERlcml2ZWQgdmlzaXRvciBtZXRob2Q6IHByaW50IGxpc3Qgb2YgZXhwcmVzc2lvbiB0cmVlcywgc2VwYXJhdGVkIGJ5IGdpdmVuIHN0cmluZy4KICAgICAqICBAcGFyYW0gc2VwIHRoZSBzZXBhcmF0b3Igc3RyaW5nCiAgICAgKi8KICAgIHB1YmxpYyA8VCBleHRlbmRzIEpDVHJlZT4gdm9pZCBwcmludEV4cHJzKExpc3Q8VD4gdHJlZXMsIFN0cmluZyBzZXApIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKHRyZWVzLm5vbkVtcHR5KCkpIHsKICAgICAgICAgICAgcHJpbnRFeHByKHRyZWVzLmhlYWQpOwogICAgICAgICAgICBmb3IgKExpc3Q8VD4gbCA9IHRyZWVzLnRhaWw7IGwubm9uRW1wdHkoKTsgbCA9IGwudGFpbCkgewogICAgICAgICAgICAgICAgcHJpbnQoc2VwKTsKICAgICAgICAgICAgICAgIHByaW50RXhwcihsLmhlYWQpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKiBEZXJpdmVkIHZpc2l0b3IgbWV0aG9kOiBwcmludCBsaXN0IG9mIGV4cHJlc3Npb24gdHJlZXMsIHNlcGFyYXRlZCBieSBjb21tYXMuCiAgICAgKi8KICAgIHB1YmxpYyA8VCBleHRlbmRzIEpDVHJlZT4gdm9pZCBwcmludEV4cHJzKExpc3Q8VD4gdHJlZXMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgcHJpbnRFeHBycyh0cmVlcywgIiwgIik7CiAgICB9CgogICAgLyoqIERlcml2ZWQgdmlzaXRvciBtZXRob2Q6IHByaW50IGxpc3Qgb2Ygc3RhdGVtZW50cywgZWFjaCBvbiBhIHNlcGFyYXRlIGxpbmUuCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHByaW50U3RhdHMoTGlzdDw/IGV4dGVuZHMgSkNUcmVlPiB0cmVlcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICBmb3IgKExpc3Q8PyBleHRlbmRzIEpDVHJlZT4gbCA9IHRyZWVzOyBsLm5vbkVtcHR5KCk7IGwgPSBsLnRhaWwpIHsKICAgICAgICAgICAgYWxpZ24oKTsKICAgICAgICAgICAgcHJpbnRTdGF0KGwuaGVhZCk7CiAgICAgICAgICAgIHByaW50bG4oKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqIFByaW50IGEgc2V0IG9mIG1vZGlmaWVycy4KICAgICAqLwogICAgcHVibGljIHZvaWQgcHJpbnRGbGFncyhsb25nIGZsYWdzKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgIGlmICgoZmxhZ3MgJiBTWU5USEVUSUMpICE9IDApIHByaW50KCIvKnN5bnRoZXRpYyovICIpOwogICAgICAgIHByaW50KFRyZWVJbmZvLmZsYWdOYW1lcyhmbGFncykpOwogICAgICAgIGlmICgoZmxhZ3MgJiBFeHRlbmRlZFN0YW5kYXJkRmxhZ3MpICE9IDApIHByaW50KCIgIik7CiAgICAgICAgaWYgKChmbGFncyAmIEFOTk9UQVRJT04pICE9IDApIHByaW50KCJAIik7CiAgICB9CgogICAgcHVibGljIHZvaWQgcHJpbnRBbm5vdGF0aW9ucyhMaXN0PEpDQW5ub3RhdGlvbj4gdHJlZXMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgZm9yIChMaXN0PEpDQW5ub3RhdGlvbj4gbCA9IHRyZWVzOyBsLm5vbkVtcHR5KCk7IGwgPSBsLnRhaWwpIHsKICAgICAgICAgICAgcHJpbnRTdGF0KGwuaGVhZCk7CiAgICAgICAgICAgIHByaW50bG4oKTsKICAgICAgICAgICAgYWxpZ24oKTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHZvaWQgcHJpbnRUeXBlQW5ub3RhdGlvbnMoTGlzdDxKQ0Fubm90YXRpb24+IHRyZWVzKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgIGZvciAoTGlzdDxKQ0Fubm90YXRpb24+IGwgPSB0cmVlczsgbC5ub25FbXB0eSgpOyBsID0gbC50YWlsKSB7CiAgICAgICAgICAgIHByaW50RXhwcihsLmhlYWQpOwogICAgICAgICAgICBwcmludCgiICIpOwogICAgICAgIH0KICAgIH0KCiAgICAvKiogUHJpbnQgZG9jdW1lbnRhdGlvbiBjb21tZW50LCBpZiBpdCBleGlzdHMKICAgICAqICBAcGFyYW0gdHJlZSAgICBUaGUgdHJlZSBmb3Igd2hpY2ggYSBkb2N1bWVudGF0aW9uIGNvbW1lbnQgc2hvdWxkIGJlIHByaW50ZWQuCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHByaW50RG9jQ29tbWVudChKQ1RyZWUgdHJlZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZG9jQ29tbWVudHMgIT0gbnVsbCkgewogICAgICAgICAgICBTdHJpbmcgZGMgPSBkb2NDb21tZW50cy5nZXRDb21tZW50VGV4dCh0cmVlKTsKICAgICAgICAgICAgaWYgKGRjICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIHByaW50KCIvKioiKTsgcHJpbnRsbigpOwogICAgICAgICAgICAgICAgaW50IHBvcyA9IDA7CiAgICAgICAgICAgICAgICBpbnQgZW5kcG9zID0gbGluZUVuZFBvcyhkYywgcG9zKTsKICAgICAgICAgICAgICAgIHdoaWxlIChwb3MgPCBkYy5sZW5ndGgoKSkgewogICAgICAgICAgICAgICAgICAgIGFsaWduKCk7CiAgICAgICAgICAgICAgICAgICAgcHJpbnQoIiAqIik7CiAgICAgICAgICAgICAgICAgICAgaWYgKHBvcyA8IGRjLmxlbmd0aCgpICYmIGRjLmNoYXJBdChwb3MpID4gJyAnKSBwcmludCgiICIpOwogICAgICAgICAgICAgICAgICAgIHByaW50KGRjLnN1YnN0cmluZyhwb3MsIGVuZHBvcykpOyBwcmludGxuKCk7CiAgICAgICAgICAgICAgICAgICAgcG9zID0gZW5kcG9zICsgMTsKICAgICAgICAgICAgICAgICAgICBlbmRwb3MgPSBsaW5lRW5kUG9zKGRjLCBwb3MpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYWxpZ24oKTsgcHJpbnQoIiAqLyIpOyBwcmludGxuKCk7CiAgICAgICAgICAgICAgICBhbGlnbigpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQovL3doZXJlCiAgICBzdGF0aWMgaW50IGxpbmVFbmRQb3MoU3RyaW5nIHMsIGludCBzdGFydCkgewogICAgICAgIGludCBwb3MgPSBzLmluZGV4T2YoJ1xuJywgc3RhcnQpOwogICAgICAgIGlmIChwb3MgPCAwKSBwb3MgPSBzLmxlbmd0aCgpOwogICAgICAgIHJldHVybiBwb3M7CiAgICB9CgogICAgLyoqIElmIHR5cGUgcGFyYW1ldGVyIGxpc3QgaXMgbm9uLWVtcHR5LCBwcmludCBpdCBlbmNsb3NlZCBpbgogICAgICogIHtAbGl0ZXJhbCAiPC4uLj4ifSBicmFja2V0cy4KICAgICAqLwogICAgcHVibGljIHZvaWQgcHJpbnRUeXBlUGFyYW1ldGVycyhMaXN0PEpDVHlwZVBhcmFtZXRlcj4gdHJlZXMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKHRyZWVzLm5vbkVtcHR5KCkpIHsKICAgICAgICAgICAgcHJpbnQoIjwiKTsKICAgICAgICAgICAgcHJpbnRFeHBycyh0cmVlcyk7CiAgICAgICAgICAgIHByaW50KCI+Iik7CiAgICAgICAgfQogICAgfQoKICAgIC8qKiBQcmludCBhIGJsb2NrLgogICAgICovCiAgICBwdWJsaWMgdm9pZCBwcmludEJsb2NrKExpc3Q8PyBleHRlbmRzIEpDVHJlZT4gc3RhdHMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgcHJpbnQoInsiKTsKICAgICAgICBwcmludGxuKCk7CiAgICAgICAgaW5kZW50KCk7CiAgICAgICAgcHJpbnRTdGF0cyhzdGF0cyk7CiAgICAgICAgdW5kZW50KCk7CiAgICAgICAgYWxpZ24oKTsKICAgICAgICBwcmludCgifSIpOwogICAgfQoKICAgIC8qKiBQcmludCBhIGJsb2NrLgogICAgICovCiAgICBwdWJsaWMgdm9pZCBwcmludEVudW1Cb2R5KExpc3Q8SkNUcmVlPiBzdGF0cykgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICBwcmludCgieyIpOwogICAgICAgIHByaW50bG4oKTsKICAgICAgICBpbmRlbnQoKTsKICAgICAgICBib29sZWFuIGZpcnN0ID0gdHJ1ZTsKICAgICAgICBmb3IgKExpc3Q8SkNUcmVlPiBsID0gc3RhdHM7IGwubm9uRW1wdHkoKTsgbCA9IGwudGFpbCkgewogICAgICAgICAgICBpZiAoaXNFbnVtZXJhdG9yKGwuaGVhZCkpIHsKICAgICAgICAgICAgICAgIGlmICghZmlyc3QpIHsKICAgICAgICAgICAgICAgICAgICBwcmludCgiLCIpOwogICAgICAgICAgICAgICAgICAgIHByaW50bG4oKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGFsaWduKCk7CiAgICAgICAgICAgICAgICBwcmludFN0YXQobC5oZWFkKTsKICAgICAgICAgICAgICAgIGZpcnN0ID0gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcHJpbnQoIjsiKTsKICAgICAgICBwcmludGxuKCk7CiAgICAgICAgZm9yIChMaXN0PEpDVHJlZT4gbCA9IHN0YXRzOyBsLm5vbkVtcHR5KCk7IGwgPSBsLnRhaWwpIHsKICAgICAgICAgICAgaWYgKCFpc0VudW1lcmF0b3IobC5oZWFkKSkgewogICAgICAgICAgICAgICAgYWxpZ24oKTsKICAgICAgICAgICAgICAgIHByaW50U3RhdChsLmhlYWQpOwogICAgICAgICAgICAgICAgcHJpbnRsbigpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHVuZGVudCgpOwogICAgICAgIGFsaWduKCk7CiAgICAgICAgcHJpbnQoIn0iKTsKICAgIH0KCiAgICAvKiogSXMgdGhlIGdpdmVuIHRyZWUgYW4gZW51bWVyYXRvciBkZWZpbml0aW9uPyAqLwogICAgYm9vbGVhbiBpc0VudW1lcmF0b3IoSkNUcmVlIHQpIHsKICAgICAgICByZXR1cm4gdC5oYXNUYWcoVkFSREVGKSAmJiAoKChKQ1ZhcmlhYmxlRGVjbCkgdCkubW9kcy5mbGFncyAmIEVOVU0pICE9IDA7CiAgICB9CgogICAgLyoqIFByaW50IHVuaXQgY29uc2lzdGluZyBvZiBwYWNrYWdlIGNsYXVzZSBhbmQgaW1wb3J0IHN0YXRlbWVudHMgaW4gdG9wbGV2ZWwsCiAgICAgKiAgZm9sbG93ZWQgYnkgY2xhc3MgZGVmaW5pdGlvbi4gaWYgY2xhc3MgZGVmaW5pdGlvbiA9PSBudWxsLAogICAgICogIHByaW50IGFsbCBkZWZpbml0aW9ucyBpbiB0b3BsZXZlbC4KICAgICAqICBAcGFyYW0gdHJlZSAgICAgVGhlIHRvcGxldmVsIHRyZWUKICAgICAqICBAcGFyYW0gY2RlZiAgICAgVGhlIGNsYXNzIGRlZmluaXRpb24sIHdoaWNoIGlzIGFzc3VtZWQgdG8gYmUgcGFydCBvZiB0aGUKICAgICAqICAgICAgICAgICAgICAgICAgdG9wbGV2ZWwgdHJlZS4KICAgICAqLwogICAgcHVibGljIHZvaWQgcHJpbnRVbml0KEpDQ29tcGlsYXRpb25Vbml0IHRyZWUsIEpDQ2xhc3NEZWNsIGNkZWYpIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgZG9jQ29tbWVudHMgPSB0cmVlLmRvY0NvbW1lbnRzOwogICAgICAgIHByaW50RG9jQ29tbWVudCh0cmVlKTsKCiAgICAgICAgYm9vbGVhbiBmaXJzdEltcG9ydCA9IHRydWU7CiAgICAgICAgZm9yIChMaXN0PEpDVHJlZT4gbCA9IHRyZWUuZGVmczsKICAgICAgICAgICAgIGwubm9uRW1wdHkoKSAmJgogICAgICAgICAgICAgICAgIChjZGVmID09IG51bGwgfHwKICAgICAgICAgICAgICAgICAgbC5oZWFkLmhhc1RhZyhJTVBPUlQpIHx8IGwuaGVhZC5oYXNUYWcoUEFDS0FHRURFRikpOwogICAgICAgICAgICAgbCA9IGwudGFpbCkgewogICAgICAgICAgICBpZiAobC5oZWFkLmhhc1RhZyhJTVBPUlQpKSB7CiAgICAgICAgICAgICAgICBKQ0ltcG9ydCBpbXAgPSAoSkNJbXBvcnQpbC5oZWFkOwogICAgICAgICAgICAgICAgTmFtZSBuYW1lID0gVHJlZUluZm8ubmFtZShpbXAucXVhbGlkKTsKICAgICAgICAgICAgICAgIGlmIChuYW1lID09IG5hbWUudGFibGUubmFtZXMuYXN0ZXJpc2sgfHwKICAgICAgICAgICAgICAgICAgICAgICAgY2RlZiA9PSBudWxsIHx8CiAgICAgICAgICAgICAgICAgICAgICAgIGlzVXNlZChUcmVlSW5mby5zeW1ib2woaW1wLnF1YWxpZCksIGNkZWYpKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGZpcnN0SW1wb3J0KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGZpcnN0SW1wb3J0ID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgICAgIHByaW50bG4oKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgcHJpbnRTdGF0KGltcCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBwcmludFN0YXQobC5oZWFkKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoY2RlZiAhPSBudWxsKSB7CiAgICAgICAgICAgIHByaW50U3RhdChjZGVmKTsKICAgICAgICAgICAgcHJpbnRsbigpOwogICAgICAgIH0KICAgIH0KICAgIC8vIHdoZXJlCiAgICBib29sZWFuIGlzVXNlZChmaW5hbCBTeW1ib2wgdCwgSkNUcmVlIGNkZWYpIHsKICAgICAgICBjbGFzcyBVc2VkVmlzaXRvciBleHRlbmRzIFRyZWVTY2FubmVyIHsKICAgICAgICAgICAgcHVibGljIHZvaWQgc2NhbihKQ1RyZWUgdHJlZSkgewogICAgICAgICAgICAgICAgaWYgKHRyZWUhPW51bGwgJiYgIXJlc3VsdCkgdHJlZS5hY2NlcHQodGhpcyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYm9vbGVhbiByZXN1bHQgPSBmYWxzZTsKICAgICAgICAgICAgcHVibGljIHZvaWQgdmlzaXRJZGVudChKQ0lkZW50IHRyZWUpIHsKICAgICAgICAgICAgICAgIGlmICh0cmVlLnN5bSA9PSB0KSByZXN1bHQgPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIFVzZWRWaXNpdG9yIHYgPSBuZXcgVXNlZFZpc2l0b3IoKTsKICAgICAgICB2LnNjYW4oY2RlZik7CiAgICAgICAgcmV0dXJuIHYucmVzdWx0OwogICAgfQoKICAgIC8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogICAgICogVmlzaXRvciBtZXRob2RzCiAgICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiAgICBwdWJsaWMgdm9pZCB2aXNpdFRvcExldmVsKEpDQ29tcGlsYXRpb25Vbml0IHRyZWUpIHsKICAgICAgICB0cnkgewogICAgICAgICAgICBwcmludFVuaXQodHJlZSwgbnVsbCk7CiAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgVW5jaGVja2VkSU9FeGNlcHRpb24oZSk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0UGFja2FnZURlZihKQ1BhY2thZ2VEZWNsIHRyZWUpIHsKICAgICAgICB0cnkgewogICAgICAgICAgICBwcmludERvY0NvbW1lbnQodHJlZSk7CiAgICAgICAgICAgIHByaW50QW5ub3RhdGlvbnModHJlZS5hbm5vdGF0aW9ucyk7CiAgICAgICAgICAgIGlmICh0cmVlLnBpZCAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICBwcmludCgicGFja2FnZSAiKTsKICAgICAgICAgICAgICAgIHByaW50RXhwcih0cmVlLnBpZCk7CiAgICAgICAgICAgICAgICBwcmludCgiOyIpOwogICAgICAgICAgICAgICAgcHJpbnRsbigpOwogICAgICAgICAgICB9CiAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgVW5jaGVja2VkSU9FeGNlcHRpb24oZSk7CiAgICAgICAgfQogICAgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIHZvaWQgdmlzaXRNb2R1bGVEZWYoSkNNb2R1bGVEZWNsIHRyZWUpIHsKICAgICAgICB0cnkgewogICAgICAgICAgICBwcmludEFubm90YXRpb25zKHRyZWUubW9kcy5hbm5vdGF0aW9ucyk7CiAgICAgICAgICAgIGlmICh0cmVlLmdldE1vZHVsZVR5cGUoKSA9PSBNb2R1bGVLaW5kLk9QRU4pIHsKICAgICAgICAgICAgICAgIHByaW50KCJvcGVuICIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHByaW50KCJtb2R1bGUgIik7CiAgICAgICAgICAgIHByaW50RXhwcih0cmVlLnF1YWxJZCk7CiAgICAgICAgICAgIGlmICh0cmVlLmRpcmVjdGl2ZXMgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgcHJpbnQoIjsiKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHByaW50QmxvY2sodHJlZS5kaXJlY3RpdmVzKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBwcmludGxuKCk7CiAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgVW5jaGVja2VkSU9FeGNlcHRpb24oZSk7CiAgICAgICAgfQogICAgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIHZvaWQgdmlzaXRFeHBvcnRzKEpDRXhwb3J0cyB0cmVlKSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgcHJpbnQoImV4cG9ydHMgIik7CiAgICAgICAgICAgIHByaW50RXhwcih0cmVlLnF1YWxpZCk7CiAgICAgICAgICAgIGlmICh0cmVlLm1vZHVsZU5hbWVzICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIHByaW50KCIgdG8gIik7CiAgICAgICAgICAgICAgICBwcmludEV4cHJzKHRyZWUubW9kdWxlTmFtZXMpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHByaW50KCI7Iik7CiAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgVW5jaGVja2VkSU9FeGNlcHRpb24oZSk7CiAgICAgICAgfQogICAgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIHZvaWQgdmlzaXRPcGVucyhKQ09wZW5zIHRyZWUpIHsKICAgICAgICB0cnkgewogICAgICAgICAgICBwcmludCgib3BlbnMgIik7CiAgICAgICAgICAgIHByaW50RXhwcih0cmVlLnF1YWxpZCk7CiAgICAgICAgICAgIGlmICh0cmVlLm1vZHVsZU5hbWVzICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIHByaW50KCIgdG8gIik7CiAgICAgICAgICAgICAgICBwcmludEV4cHJzKHRyZWUubW9kdWxlTmFtZXMpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHByaW50KCI7Iik7CiAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgVW5jaGVja2VkSU9FeGNlcHRpb24oZSk7CiAgICAgICAgfQogICAgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIHZvaWQgdmlzaXRQcm92aWRlcyhKQ1Byb3ZpZGVzIHRyZWUpIHsKICAgICAgICB0cnkgewogICAgICAgICAgICBwcmludCgicHJvdmlkZXMgIik7CiAgICAgICAgICAgIHByaW50RXhwcih0cmVlLnNlcnZpY2VOYW1lKTsKICAgICAgICAgICAgcHJpbnQoIiB3aXRoICIpOwogICAgICAgICAgICBwcmludEV4cHJzKHRyZWUuaW1wbE5hbWVzKTsKICAgICAgICAgICAgcHJpbnQoIjsiKTsKICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBVbmNoZWNrZWRJT0V4Y2VwdGlvbihlKTsKICAgICAgICB9CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB2aXNpdFJlcXVpcmVzKEpDUmVxdWlyZXMgdHJlZSkgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIHByaW50KCJyZXF1aXJlcyAiKTsKICAgICAgICAgICAgaWYgKHRyZWUuaXNTdGF0aWNQaGFzZSkKICAgICAgICAgICAgICAgIHByaW50KCJzdGF0aWMgIik7CiAgICAgICAgICAgIGlmICh0cmVlLmlzVHJhbnNpdGl2ZSkKICAgICAgICAgICAgICAgIHByaW50KCJ0cmFuc2l0aXZlICIpOwogICAgICAgICAgICBwcmludEV4cHIodHJlZS5tb2R1bGVOYW1lKTsKICAgICAgICAgICAgcHJpbnQoIjsiKTsKICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBVbmNoZWNrZWRJT0V4Y2VwdGlvbihlKTsKICAgICAgICB9CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB2aXNpdFVzZXMoSkNVc2VzIHRyZWUpIHsKICAgICAgICB0cnkgewogICAgICAgICAgICBwcmludCgidXNlcyAiKTsKICAgICAgICAgICAgcHJpbnRFeHByKHRyZWUucXVhbGlkKTsKICAgICAgICAgICAgcHJpbnQoIjsiKTsKICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBVbmNoZWNrZWRJT0V4Y2VwdGlvbihlKTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRJbXBvcnQoSkNJbXBvcnQgdHJlZSkgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIHByaW50KCJpbXBvcnQgIik7CiAgICAgICAgICAgIGlmICh0cmVlLnN0YXRpY0ltcG9ydCkgcHJpbnQoInN0YXRpYyAiKTsKICAgICAgICAgICAgcHJpbnRFeHByKHRyZWUucXVhbGlkKTsKICAgICAgICAgICAgcHJpbnQoIjsiKTsKICAgICAgICAgICAgcHJpbnRsbigpOwogICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFVuY2hlY2tlZElPRXhjZXB0aW9uKGUpOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdENsYXNzRGVmKEpDQ2xhc3NEZWNsIHRyZWUpIHsKICAgICAgICB0cnkgewogICAgICAgICAgICBwcmludGxuKCk7IGFsaWduKCk7CiAgICAgICAgICAgIHByaW50RG9jQ29tbWVudCh0cmVlKTsKICAgICAgICAgICAgcHJpbnRBbm5vdGF0aW9ucyh0cmVlLm1vZHMuYW5ub3RhdGlvbnMpOwogICAgICAgICAgICBwcmludEZsYWdzKHRyZWUubW9kcy5mbGFncyAmIH5JTlRFUkZBQ0UpOwogICAgICAgICAgICBOYW1lIGVuY2xDbGFzc05hbWVQcmV2ID0gZW5jbENsYXNzTmFtZTsKICAgICAgICAgICAgZW5jbENsYXNzTmFtZSA9IHRyZWUubmFtZTsKICAgICAgICAgICAgaWYgKCh0cmVlLm1vZHMuZmxhZ3MgJiBJTlRFUkZBQ0UpICE9IDApIHsKICAgICAgICAgICAgICAgIHByaW50KCJpbnRlcmZhY2UgIiArIHRyZWUubmFtZSk7CiAgICAgICAgICAgICAgICBwcmludFR5cGVQYXJhbWV0ZXJzKHRyZWUudHlwYXJhbXMpOwogICAgICAgICAgICAgICAgaWYgKHRyZWUuaW1wbGVtZW50aW5nLm5vbkVtcHR5KCkpIHsKICAgICAgICAgICAgICAgICAgICBwcmludCgiIGV4dGVuZHMgIik7CiAgICAgICAgICAgICAgICAgICAgcHJpbnRFeHBycyh0cmVlLmltcGxlbWVudGluZyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBpZiAoKHRyZWUubW9kcy5mbGFncyAmIEVOVU0pICE9IDApCiAgICAgICAgICAgICAgICAgICAgcHJpbnQoImVudW0gIiArIHRyZWUubmFtZSk7CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgcHJpbnQoImNsYXNzICIgKyB0cmVlLm5hbWUpOwogICAgICAgICAgICAgICAgcHJpbnRUeXBlUGFyYW1ldGVycyh0cmVlLnR5cGFyYW1zKTsKICAgICAgICAgICAgICAgIGlmICh0cmVlLmV4dGVuZGluZyAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgcHJpbnQoIiBleHRlbmRzICIpOwogICAgICAgICAgICAgICAgICAgIHByaW50RXhwcih0cmVlLmV4dGVuZGluZyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAodHJlZS5pbXBsZW1lbnRpbmcubm9uRW1wdHkoKSkgewogICAgICAgICAgICAgICAgICAgIHByaW50KCIgaW1wbGVtZW50cyAiKTsKICAgICAgICAgICAgICAgICAgICBwcmludEV4cHJzKHRyZWUuaW1wbGVtZW50aW5nKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBwcmludCgiICIpOwogICAgICAgICAgICBpZiAoKHRyZWUubW9kcy5mbGFncyAmIEVOVU0pICE9IDApIHsKICAgICAgICAgICAgICAgIHByaW50RW51bUJvZHkodHJlZS5kZWZzKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHByaW50QmxvY2sodHJlZS5kZWZzKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbmNsQ2xhc3NOYW1lID0gZW5jbENsYXNzTmFtZVByZXY7CiAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgVW5jaGVja2VkSU9FeGNlcHRpb24oZSk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0TWV0aG9kRGVmKEpDTWV0aG9kRGVjbCB0cmVlKSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgLy8gd2hlbiBwcm9kdWNpbmcgc291cmNlIG91dHB1dCwgb21pdCBhbm9ueW1vdXMgY29uc3RydWN0b3JzCiAgICAgICAgICAgIGlmICh0cmVlLm5hbWUgPT0gdHJlZS5uYW1lLnRhYmxlLm5hbWVzLmluaXQgJiYKICAgICAgICAgICAgICAgICAgICBlbmNsQ2xhc3NOYW1lID09IG51bGwgJiYKICAgICAgICAgICAgICAgICAgICBzb3VyY2VPdXRwdXQpIHJldHVybjsKICAgICAgICAgICAgcHJpbnRsbigpOyBhbGlnbigpOwogICAgICAgICAgICBwcmludERvY0NvbW1lbnQodHJlZSk7CiAgICAgICAgICAgIHByaW50RXhwcih0cmVlLm1vZHMpOwogICAgICAgICAgICBwcmludFR5cGVQYXJhbWV0ZXJzKHRyZWUudHlwYXJhbXMpOwogICAgICAgICAgICBpZiAodHJlZS5uYW1lID09IHRyZWUubmFtZS50YWJsZS5uYW1lcy5pbml0KSB7CiAgICAgICAgICAgICAgICBwcmludChlbmNsQ2xhc3NOYW1lICE9IG51bGwgPyBlbmNsQ2xhc3NOYW1lIDogdHJlZS5uYW1lKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHByaW50RXhwcih0cmVlLnJlc3R5cGUpOwogICAgICAgICAgICAgICAgcHJpbnQoIiAiICsgdHJlZS5uYW1lKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBwcmludCgiKCIpOwogICAgICAgICAgICBpZiAodHJlZS5yZWN2cGFyYW0hPW51bGwpIHsKICAgICAgICAgICAgICAgIHByaW50RXhwcih0cmVlLnJlY3ZwYXJhbSk7CiAgICAgICAgICAgICAgICBpZiAodHJlZS5wYXJhbXMuc2l6ZSgpID4gMCkgewogICAgICAgICAgICAgICAgICAgIHByaW50KCIsICIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHByaW50RXhwcnModHJlZS5wYXJhbXMpOwogICAgICAgICAgICBwcmludCgiKSIpOwogICAgICAgICAgICBpZiAodHJlZS50aHJvd24ubm9uRW1wdHkoKSkgewogICAgICAgICAgICAgICAgcHJpbnQoIiB0aHJvd3MgIik7CiAgICAgICAgICAgICAgICBwcmludEV4cHJzKHRyZWUudGhyb3duKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAodHJlZS5kZWZhdWx0VmFsdWUgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgcHJpbnQoIiBkZWZhdWx0ICIpOwogICAgICAgICAgICAgICAgcHJpbnRFeHByKHRyZWUuZGVmYXVsdFZhbHVlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAodHJlZS5ib2R5ICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIHByaW50KCIgIik7CiAgICAgICAgICAgICAgICBwcmludFN0YXQodHJlZS5ib2R5KTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHByaW50KCI7Iik7CiAgICAgICAgICAgIH0KICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBVbmNoZWNrZWRJT0V4Y2VwdGlvbihlKTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRWYXJEZWYoSkNWYXJpYWJsZURlY2wgdHJlZSkgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGlmIChkb2NDb21tZW50cyAhPSBudWxsICYmIGRvY0NvbW1lbnRzLmhhc0NvbW1lbnQodHJlZSkpIHsKICAgICAgICAgICAgICAgIHByaW50bG4oKTsgYWxpZ24oKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBwcmludERvY0NvbW1lbnQodHJlZSk7CiAgICAgICAgICAgIGlmICgodHJlZS5tb2RzLmZsYWdzICYgRU5VTSkgIT0gMCkgewogICAgICAgICAgICAgICAgcHJpbnQoIi8qcHVibGljIHN0YXRpYyBmaW5hbCovICIpOwogICAgICAgICAgICAgICAgcHJpbnQodHJlZS5uYW1lKTsKICAgICAgICAgICAgICAgIGlmICh0cmVlLmluaXQgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIGlmIChzb3VyY2VPdXRwdXQgJiYgdHJlZS5pbml0Lmhhc1RhZyhORVdDTEFTUykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnQoIiAvKmVudW0qLyAiKTsKICAgICAgICAgICAgICAgICAgICAgICAgSkNOZXdDbGFzcyBpbml0ID0gKEpDTmV3Q2xhc3MpIHRyZWUuaW5pdDsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGluaXQuYXJncyAhPSBudWxsICYmIGluaXQuYXJncy5ub25FbXB0eSgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmludCgiKCIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnQoaW5pdC5hcmdzKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByaW50KCIpIik7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGluaXQuZGVmICE9IG51bGwgJiYgaW5pdC5kZWYuZGVmcyAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmludCgiICIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnRCbG9jayhpbml0LmRlZi5kZWZzKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHByaW50KCIgLyogPSAiKTsKICAgICAgICAgICAgICAgICAgICBwcmludEV4cHIodHJlZS5pbml0KTsKICAgICAgICAgICAgICAgICAgICBwcmludCgiICovIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBwcmludEV4cHIodHJlZS5tb2RzKTsKICAgICAgICAgICAgICAgIGlmICgodHJlZS5tb2RzLmZsYWdzICYgVkFSQVJHUykgIT0gMCkgewogICAgICAgICAgICAgICAgICAgIEpDVHJlZSB2YXJ0eXBlID0gdHJlZS52YXJ0eXBlOwogICAgICAgICAgICAgICAgICAgIExpc3Q8SkNBbm5vdGF0aW9uPiB0YXMgPSBudWxsOwogICAgICAgICAgICAgICAgICAgIGlmICh2YXJ0eXBlIGluc3RhbmNlb2YgSkNBbm5vdGF0ZWRUeXBlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRhcyA9ICgoSkNBbm5vdGF0ZWRUeXBlKXZhcnR5cGUpLmFubm90YXRpb25zOwogICAgICAgICAgICAgICAgICAgICAgICB2YXJ0eXBlID0gKChKQ0Fubm90YXRlZFR5cGUpdmFydHlwZSkudW5kZXJseWluZ1R5cGU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHByaW50RXhwcigoKEpDQXJyYXlUeXBlVHJlZSkgdmFydHlwZSkuZWxlbXR5cGUpOwogICAgICAgICAgICAgICAgICAgIGlmICh0YXMgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICBwcmludCgnICcpOwogICAgICAgICAgICAgICAgICAgICAgICBwcmludFR5cGVBbm5vdGF0aW9ucyh0YXMpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBwcmludCgiLi4uICIgKyB0cmVlLm5hbWUpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBwcmludEV4cHIodHJlZS52YXJ0eXBlKTsKICAgICAgICAgICAgICAgICAgICBwcmludCgiICIgKyB0cmVlLm5hbWUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKHRyZWUuaW5pdCAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgcHJpbnQoIiA9ICIpOwogICAgICAgICAgICAgICAgICAgIHByaW50RXhwcih0cmVlLmluaXQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKHByZWMgPT0gVHJlZUluZm8ubm90RXhwcmVzc2lvbikgcHJpbnQoIjsiKTsKICAgICAgICAgICAgfQogICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFVuY2hlY2tlZElPRXhjZXB0aW9uKGUpOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdFNraXAoSkNTa2lwIHRyZWUpIHsKICAgICAgICB0cnkgewogICAgICAgICAgICBwcmludCgiOyIpOwogICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFVuY2hlY2tlZElPRXhjZXB0aW9uKGUpOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdEJsb2NrKEpDQmxvY2sgdHJlZSkgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIHByaW50RmxhZ3ModHJlZS5mbGFncyk7CiAgICAgICAgICAgIHByaW50QmxvY2sodHJlZS5zdGF0cyk7CiAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgVW5jaGVja2VkSU9FeGNlcHRpb24oZSk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0RG9Mb29wKEpDRG9XaGlsZUxvb3AgdHJlZSkgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIHByaW50KCJkbyAiKTsKICAgICAgICAgICAgcHJpbnRTdGF0KHRyZWUuYm9keSk7CiAgICAgICAgICAgIGFsaWduKCk7CiAgICAgICAgICAgIHByaW50KCIgd2hpbGUgIik7CiAgICAgICAgICAgIGlmICh0cmVlLmNvbmQuaGFzVGFnKFBBUkVOUykpIHsKICAgICAgICAgICAgICAgIHByaW50RXhwcih0cmVlLmNvbmQpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcHJpbnQoIigiKTsKICAgICAgICAgICAgICAgIHByaW50RXhwcih0cmVlLmNvbmQpOwogICAgICAgICAgICAgICAgcHJpbnQoIikiKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBwcmludCgiOyIpOwogICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFVuY2hlY2tlZElPRXhjZXB0aW9uKGUpOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdFdoaWxlTG9vcChKQ1doaWxlTG9vcCB0cmVlKSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgcHJpbnQoIndoaWxlICIpOwogICAgICAgICAgICBpZiAodHJlZS5jb25kLmhhc1RhZyhQQVJFTlMpKSB7CiAgICAgICAgICAgICAgICBwcmludEV4cHIodHJlZS5jb25kKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHByaW50KCIoIik7CiAgICAgICAgICAgICAgICBwcmludEV4cHIodHJlZS5jb25kKTsKICAgICAgICAgICAgICAgIHByaW50KCIpIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcHJpbnQoIiAiKTsKICAgICAgICAgICAgcHJpbnRTdGF0KHRyZWUuYm9keSk7CiAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgVW5jaGVja2VkSU9FeGNlcHRpb24oZSk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0Rm9yTG9vcChKQ0Zvckxvb3AgdHJlZSkgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIHByaW50KCJmb3IgKCIpOwogICAgICAgICAgICBpZiAodHJlZS5pbml0Lm5vbkVtcHR5KCkpIHsKICAgICAgICAgICAgICAgIGlmICh0cmVlLmluaXQuaGVhZC5oYXNUYWcoVkFSREVGKSkgewogICAgICAgICAgICAgICAgICAgIHByaW50RXhwcih0cmVlLmluaXQuaGVhZCk7CiAgICAgICAgICAgICAgICAgICAgZm9yIChMaXN0PEpDU3RhdGVtZW50PiBsID0gdHJlZS5pbml0LnRhaWw7IGwubm9uRW1wdHkoKTsgbCA9IGwudGFpbCkgewogICAgICAgICAgICAgICAgICAgICAgICBKQ1ZhcmlhYmxlRGVjbCB2ZGVmID0gKEpDVmFyaWFibGVEZWNsKWwuaGVhZDsKICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnQoIiwgIiArIHZkZWYubmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2ZGVmLmluaXQgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnQoIiA9ICIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnRFeHByKHZkZWYuaW5pdCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHByaW50RXhwcnModHJlZS5pbml0KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBwcmludCgiOyAiKTsKICAgICAgICAgICAgaWYgKHRyZWUuY29uZCAhPSBudWxsKSBwcmludEV4cHIodHJlZS5jb25kKTsKICAgICAgICAgICAgcHJpbnQoIjsgIik7CiAgICAgICAgICAgIHByaW50RXhwcnModHJlZS5zdGVwKTsKICAgICAgICAgICAgcHJpbnQoIikgIik7CiAgICAgICAgICAgIHByaW50U3RhdCh0cmVlLmJvZHkpOwogICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFVuY2hlY2tlZElPRXhjZXB0aW9uKGUpOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdEZvcmVhY2hMb29wKEpDRW5oYW5jZWRGb3JMb29wIHRyZWUpIHsKICAgICAgICB0cnkgewogICAgICAgICAgICBwcmludCgiZm9yICgiKTsKICAgICAgICAgICAgcHJpbnRFeHByKHRyZWUudmFyKTsKICAgICAgICAgICAgcHJpbnQoIiA6ICIpOwogICAgICAgICAgICBwcmludEV4cHIodHJlZS5leHByKTsKICAgICAgICAgICAgcHJpbnQoIikgIik7CiAgICAgICAgICAgIHByaW50U3RhdCh0cmVlLmJvZHkpOwogICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFVuY2hlY2tlZElPRXhjZXB0aW9uKGUpOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdExhYmVsbGVkKEpDTGFiZWxlZFN0YXRlbWVudCB0cmVlKSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgcHJpbnQodHJlZS5sYWJlbCArICI6ICIpOwogICAgICAgICAgICBwcmludFN0YXQodHJlZS5ib2R5KTsKICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBVbmNoZWNrZWRJT0V4Y2VwdGlvbihlKTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRTd2l0Y2goSkNTd2l0Y2ggdHJlZSkgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIHByaW50KCJzd2l0Y2ggIik7CiAgICAgICAgICAgIGlmICh0cmVlLnNlbGVjdG9yLmhhc1RhZyhQQVJFTlMpKSB7CiAgICAgICAgICAgICAgICBwcmludEV4cHIodHJlZS5zZWxlY3Rvcik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBwcmludCgiKCIpOwogICAgICAgICAgICAgICAgcHJpbnRFeHByKHRyZWUuc2VsZWN0b3IpOwogICAgICAgICAgICAgICAgcHJpbnQoIikiKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBwcmludCgiIHsiKTsKICAgICAgICAgICAgcHJpbnRsbigpOwogICAgICAgICAgICBwcmludFN0YXRzKHRyZWUuY2FzZXMpOwogICAgICAgICAgICBhbGlnbigpOwogICAgICAgICAgICBwcmludCgifSIpOwogICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFVuY2hlY2tlZElPRXhjZXB0aW9uKGUpOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdENhc2UoSkNDYXNlIHRyZWUpIHsKICAgICAgICB0cnkgewogICAgICAgICAgICBpZiAodHJlZS5wYXQgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgcHJpbnQoImRlZmF1bHQiKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHByaW50KCJjYXNlICIpOwogICAgICAgICAgICAgICAgcHJpbnRFeHByKHRyZWUucGF0KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBwcmludCgiOiAiKTsKICAgICAgICAgICAgcHJpbnRsbigpOwogICAgICAgICAgICBpbmRlbnQoKTsKICAgICAgICAgICAgcHJpbnRTdGF0cyh0cmVlLnN0YXRzKTsKICAgICAgICAgICAgdW5kZW50KCk7CiAgICAgICAgICAgIGFsaWduKCk7CiAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgVW5jaGVja2VkSU9FeGNlcHRpb24oZSk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0U3luY2hyb25pemVkKEpDU3luY2hyb25pemVkIHRyZWUpIHsKICAgICAgICB0cnkgewogICAgICAgICAgICBwcmludCgic3luY2hyb25pemVkICIpOwogICAgICAgICAgICBpZiAodHJlZS5sb2NrLmhhc1RhZyhQQVJFTlMpKSB7CiAgICAgICAgICAgICAgICBwcmludEV4cHIodHJlZS5sb2NrKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHByaW50KCIoIik7CiAgICAgICAgICAgICAgICBwcmludEV4cHIodHJlZS5sb2NrKTsKICAgICAgICAgICAgICAgIHByaW50KCIpIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcHJpbnQoIiAiKTsKICAgICAgICAgICAgcHJpbnRTdGF0KHRyZWUuYm9keSk7CiAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgVW5jaGVja2VkSU9FeGNlcHRpb24oZSk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0VHJ5KEpDVHJ5IHRyZWUpIHsKICAgICAgICB0cnkgewogICAgICAgICAgICBwcmludCgidHJ5ICIpOwogICAgICAgICAgICBpZiAodHJlZS5yZXNvdXJjZXMubm9uRW1wdHkoKSkgewogICAgICAgICAgICAgICAgcHJpbnQoIigiKTsKICAgICAgICAgICAgICAgIGJvb2xlYW4gZmlyc3QgPSB0cnVlOwogICAgICAgICAgICAgICAgZm9yIChKQ1RyZWUgdmFyIDogdHJlZS5yZXNvdXJjZXMpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoIWZpcnN0KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHByaW50bG4oKTsKICAgICAgICAgICAgICAgICAgICAgICAgaW5kZW50KCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHByaW50U3RhdCh2YXIpOwogICAgICAgICAgICAgICAgICAgIGZpcnN0ID0gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBwcmludCgiKSAiKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBwcmludFN0YXQodHJlZS5ib2R5KTsKICAgICAgICAgICAgZm9yIChMaXN0PEpDQ2F0Y2g+IGwgPSB0cmVlLmNhdGNoZXJzOyBsLm5vbkVtcHR5KCk7IGwgPSBsLnRhaWwpIHsKICAgICAgICAgICAgICAgIHByaW50U3RhdChsLmhlYWQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICh0cmVlLmZpbmFsaXplciAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICBwcmludCgiIGZpbmFsbHkgIik7CiAgICAgICAgICAgICAgICBwcmludFN0YXQodHJlZS5maW5hbGl6ZXIpOwogICAgICAgICAgICB9CiAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgVW5jaGVja2VkSU9FeGNlcHRpb24oZSk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0Q2F0Y2goSkNDYXRjaCB0cmVlKSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgcHJpbnQoIiBjYXRjaCAoIik7CiAgICAgICAgICAgIHByaW50RXhwcih0cmVlLnBhcmFtKTsKICAgICAgICAgICAgcHJpbnQoIikgIik7CiAgICAgICAgICAgIHByaW50U3RhdCh0cmVlLmJvZHkpOwogICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFVuY2hlY2tlZElPRXhjZXB0aW9uKGUpOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdENvbmRpdGlvbmFsKEpDQ29uZGl0aW9uYWwgdHJlZSkgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIG9wZW4ocHJlYywgVHJlZUluZm8uY29uZFByZWMpOwogICAgICAgICAgICBwcmludEV4cHIodHJlZS5jb25kLCBUcmVlSW5mby5jb25kUHJlYyArIDEpOwogICAgICAgICAgICBwcmludCgiID8gIik7CiAgICAgICAgICAgIHByaW50RXhwcih0cmVlLnRydWVwYXJ0KTsKICAgICAgICAgICAgcHJpbnQoIiA6ICIpOwogICAgICAgICAgICBwcmludEV4cHIodHJlZS5mYWxzZXBhcnQsIFRyZWVJbmZvLmNvbmRQcmVjKTsKICAgICAgICAgICAgY2xvc2UocHJlYywgVHJlZUluZm8uY29uZFByZWMpOwogICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFVuY2hlY2tlZElPRXhjZXB0aW9uKGUpOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdElmKEpDSWYgdHJlZSkgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIHByaW50KCJpZiAiKTsKICAgICAgICAgICAgaWYgKHRyZWUuY29uZC5oYXNUYWcoUEFSRU5TKSkgewogICAgICAgICAgICAgICAgcHJpbnRFeHByKHRyZWUuY29uZCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBwcmludCgiKCIpOwogICAgICAgICAgICAgICAgcHJpbnRFeHByKHRyZWUuY29uZCk7CiAgICAgICAgICAgICAgICBwcmludCgiKSIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHByaW50KCIgIik7CiAgICAgICAgICAgIHByaW50U3RhdCh0cmVlLnRoZW5wYXJ0KTsKICAgICAgICAgICAgaWYgKHRyZWUuZWxzZXBhcnQgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgcHJpbnQoIiBlbHNlICIpOwogICAgICAgICAgICAgICAgcHJpbnRTdGF0KHRyZWUuZWxzZXBhcnQpOwogICAgICAgICAgICB9CiAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgVW5jaGVja2VkSU9FeGNlcHRpb24oZSk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0RXhlYyhKQ0V4cHJlc3Npb25TdGF0ZW1lbnQgdHJlZSkgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIHByaW50RXhwcih0cmVlLmV4cHIpOwogICAgICAgICAgICBpZiAocHJlYyA9PSBUcmVlSW5mby5ub3RFeHByZXNzaW9uKSBwcmludCgiOyIpOwogICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFVuY2hlY2tlZElPRXhjZXB0aW9uKGUpOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdEJyZWFrKEpDQnJlYWsgdHJlZSkgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIHByaW50KCJicmVhayIpOwogICAgICAgICAgICBpZiAodHJlZS5sYWJlbCAhPSBudWxsKSBwcmludCgiICIgKyB0cmVlLmxhYmVsKTsKICAgICAgICAgICAgcHJpbnQoIjsiKTsKICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBVbmNoZWNrZWRJT0V4Y2VwdGlvbihlKTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRDb250aW51ZShKQ0NvbnRpbnVlIHRyZWUpIHsKICAgICAgICB0cnkgewogICAgICAgICAgICBwcmludCgiY29udGludWUiKTsKICAgICAgICAgICAgaWYgKHRyZWUubGFiZWwgIT0gbnVsbCkgcHJpbnQoIiAiICsgdHJlZS5sYWJlbCk7CiAgICAgICAgICAgIHByaW50KCI7Iik7CiAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgVW5jaGVja2VkSU9FeGNlcHRpb24oZSk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0UmV0dXJuKEpDUmV0dXJuIHRyZWUpIHsKICAgICAgICB0cnkgewogICAgICAgICAgICBwcmludCgicmV0dXJuIik7CiAgICAgICAgICAgIGlmICh0cmVlLmV4cHIgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgcHJpbnQoIiAiKTsKICAgICAgICAgICAgICAgIHByaW50RXhwcih0cmVlLmV4cHIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHByaW50KCI7Iik7CiAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgVW5jaGVja2VkSU9FeGNlcHRpb24oZSk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0VGhyb3coSkNUaHJvdyB0cmVlKSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgcHJpbnQoInRocm93ICIpOwogICAgICAgICAgICBwcmludEV4cHIodHJlZS5leHByKTsKICAgICAgICAgICAgcHJpbnQoIjsiKTsKICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBVbmNoZWNrZWRJT0V4Y2VwdGlvbihlKTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRBc3NlcnQoSkNBc3NlcnQgdHJlZSkgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIHByaW50KCJhc3NlcnQgIik7CiAgICAgICAgICAgIHByaW50RXhwcih0cmVlLmNvbmQpOwogICAgICAgICAgICBpZiAodHJlZS5kZXRhaWwgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgcHJpbnQoIiA6ICIpOwogICAgICAgICAgICAgICAgcHJpbnRFeHByKHRyZWUuZGV0YWlsKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBwcmludCgiOyIpOwogICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFVuY2hlY2tlZElPRXhjZXB0aW9uKGUpOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdEFwcGx5KEpDTWV0aG9kSW52b2NhdGlvbiB0cmVlKSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgaWYgKCF0cmVlLnR5cGVhcmdzLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgICAgaWYgKHRyZWUubWV0aC5oYXNUYWcoU0VMRUNUKSkgewogICAgICAgICAgICAgICAgICAgIEpDRmllbGRBY2Nlc3MgbGVmdCA9IChKQ0ZpZWxkQWNjZXNzKXRyZWUubWV0aDsKICAgICAgICAgICAgICAgICAgICBwcmludEV4cHIobGVmdC5zZWxlY3RlZCk7CiAgICAgICAgICAgICAgICAgICAgcHJpbnQoIi48Iik7CiAgICAgICAgICAgICAgICAgICAgcHJpbnRFeHBycyh0cmVlLnR5cGVhcmdzKTsKICAgICAgICAgICAgICAgICAgICBwcmludCgiPiIgKyBsZWZ0Lm5hbWUpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBwcmludCgiPCIpOwogICAgICAgICAgICAgICAgICAgIHByaW50RXhwcnModHJlZS50eXBlYXJncyk7CiAgICAgICAgICAgICAgICAgICAgcHJpbnQoIj4iKTsKICAgICAgICAgICAgICAgICAgICBwcmludEV4cHIodHJlZS5tZXRoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHByaW50RXhwcih0cmVlLm1ldGgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHByaW50KCIoIik7CiAgICAgICAgICAgIHByaW50RXhwcnModHJlZS5hcmdzKTsKICAgICAgICAgICAgcHJpbnQoIikiKTsKICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBVbmNoZWNrZWRJT0V4Y2VwdGlvbihlKTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXROZXdDbGFzcyhKQ05ld0NsYXNzIHRyZWUpIHsKICAgICAgICB0cnkgewogICAgICAgICAgICBpZiAodHJlZS5lbmNsICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIHByaW50RXhwcih0cmVlLmVuY2wpOwogICAgICAgICAgICAgICAgcHJpbnQoIi4iKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBwcmludCgibmV3ICIpOwogICAgICAgICAgICBpZiAoIXRyZWUudHlwZWFyZ3MuaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgICBwcmludCgiPCIpOwogICAgICAgICAgICAgICAgcHJpbnRFeHBycyh0cmVlLnR5cGVhcmdzKTsKICAgICAgICAgICAgICAgIHByaW50KCI+Iik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHRyZWUuZGVmICE9IG51bGwgJiYgdHJlZS5kZWYubW9kcy5hbm5vdGF0aW9ucy5ub25FbXB0eSgpKSB7CiAgICAgICAgICAgICAgICBwcmludFR5cGVBbm5vdGF0aW9ucyh0cmVlLmRlZi5tb2RzLmFubm90YXRpb25zKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBwcmludEV4cHIodHJlZS5jbGF6eik7CiAgICAgICAgICAgIHByaW50KCIoIik7CiAgICAgICAgICAgIHByaW50RXhwcnModHJlZS5hcmdzKTsKICAgICAgICAgICAgcHJpbnQoIikiKTsKICAgICAgICAgICAgaWYgKHRyZWUuZGVmICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIE5hbWUgZW5jbENsYXNzTmFtZVByZXYgPSBlbmNsQ2xhc3NOYW1lOwogICAgICAgICAgICAgICAgZW5jbENsYXNzTmFtZSA9CiAgICAgICAgICAgICAgICAgICAgICAgIHRyZWUuZGVmLm5hbWUgIT0gbnVsbCA/IHRyZWUuZGVmLm5hbWUgOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJlZS50eXBlICE9IG51bGwgJiYgdHJlZS50eXBlLnRzeW0ubmFtZSAhPSB0cmVlLnR5cGUudHN5bS5uYW1lLnRhYmxlLm5hbWVzLmVtcHR5CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyB0cmVlLnR5cGUudHN5bS5uYW1lIDogbnVsbDsKICAgICAgICAgICAgICAgIGlmICgodHJlZS5kZWYubW9kcy5mbGFncyAmIEZsYWdzLkVOVU0pICE9IDApIHByaW50KCIvKmVudW0qLyIpOwogICAgICAgICAgICAgICAgcHJpbnRCbG9jayh0cmVlLmRlZi5kZWZzKTsKICAgICAgICAgICAgICAgIGVuY2xDbGFzc05hbWUgPSBlbmNsQ2xhc3NOYW1lUHJldjsKICAgICAgICAgICAgfQogICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFVuY2hlY2tlZElPRXhjZXB0aW9uKGUpOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdE5ld0FycmF5KEpDTmV3QXJyYXkgdHJlZSkgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGlmICh0cmVlLmVsZW10eXBlICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIHByaW50KCJuZXcgIik7CiAgICAgICAgICAgICAgICBKQ1RyZWUgZWxlbSA9IHRyZWUuZWxlbXR5cGU7CiAgICAgICAgICAgICAgICBwcmludEJhc2VFbGVtZW50VHlwZShlbGVtKTsKCiAgICAgICAgICAgICAgICBpZiAoIXRyZWUuYW5ub3RhdGlvbnMuaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgICAgICAgcHJpbnQoJyAnKTsKICAgICAgICAgICAgICAgICAgICBwcmludFR5cGVBbm5vdGF0aW9ucyh0cmVlLmFubm90YXRpb25zKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICh0cmVlLmVsZW1zICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICBwcmludCgiW10iKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpbnQgaSA9IDA7CiAgICAgICAgICAgICAgICBMaXN0PExpc3Q8SkNBbm5vdGF0aW9uPj4gZGEgPSB0cmVlLmRpbUFubm90YXRpb25zOwogICAgICAgICAgICAgICAgZm9yIChMaXN0PEpDRXhwcmVzc2lvbj4gbCA9IHRyZWUuZGltczsgbC5ub25FbXB0eSgpOyBsID0gbC50YWlsKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGRhLnNpemUoKSA+IGkgJiYgIWRhLmdldChpKS5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnQoJyAnKTsKICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnRUeXBlQW5ub3RhdGlvbnMoZGEuZ2V0KGkpKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgcHJpbnQoIlsiKTsKICAgICAgICAgICAgICAgICAgICBpKys7CiAgICAgICAgICAgICAgICAgICAgcHJpbnRFeHByKGwuaGVhZCk7CiAgICAgICAgICAgICAgICAgICAgcHJpbnQoIl0iKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHByaW50QnJhY2tldHMoZWxlbSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHRyZWUuZWxlbXMgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgcHJpbnQoInsiKTsKICAgICAgICAgICAgICAgIHByaW50RXhwcnModHJlZS5lbGVtcyk7CiAgICAgICAgICAgICAgICBwcmludCgifSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgVW5jaGVja2VkSU9FeGNlcHRpb24oZSk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0TGFtYmRhKEpDTGFtYmRhIHRyZWUpIHsKICAgICAgICB0cnkgewogICAgICAgICAgICBwcmludCgiKCIpOwogICAgICAgICAgICBpZiAodHJlZS5wYXJhbUtpbmQgPT0gSkNMYW1iZGEuUGFyYW1ldGVyS2luZC5FWFBMSUNJVCkgewogICAgICAgICAgICAgICAgcHJpbnRFeHBycyh0cmVlLnBhcmFtcyk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBTdHJpbmcgc2VwID0gIiI7CiAgICAgICAgICAgICAgICBmb3IgKEpDVmFyaWFibGVEZWNsIHBhcmFtIDogdHJlZS5wYXJhbXMpIHsKICAgICAgICAgICAgICAgICAgICBwcmludChzZXApOwogICAgICAgICAgICAgICAgICAgIHByaW50KHBhcmFtLm5hbWUpOwogICAgICAgICAgICAgICAgICAgIHNlcCA9ICIsIjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBwcmludCgiKS0+Iik7CiAgICAgICAgICAgIHByaW50RXhwcih0cmVlLmJvZHkpOwogICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFVuY2hlY2tlZElPRXhjZXB0aW9uKGUpOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdFBhcmVucyhKQ1BhcmVucyB0cmVlKSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgcHJpbnQoIigiKTsKICAgICAgICAgICAgcHJpbnRFeHByKHRyZWUuZXhwcik7CiAgICAgICAgICAgIHByaW50KCIpIik7CiAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgVW5jaGVja2VkSU9FeGNlcHRpb24oZSk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0QXNzaWduKEpDQXNzaWduIHRyZWUpIHsKICAgICAgICB0cnkgewogICAgICAgICAgICBvcGVuKHByZWMsIFRyZWVJbmZvLmFzc2lnblByZWMpOwogICAgICAgICAgICBwcmludEV4cHIodHJlZS5saHMsIFRyZWVJbmZvLmFzc2lnblByZWMgKyAxKTsKICAgICAgICAgICAgcHJpbnQoIiA9ICIpOwogICAgICAgICAgICBwcmludEV4cHIodHJlZS5yaHMsIFRyZWVJbmZvLmFzc2lnblByZWMpOwogICAgICAgICAgICBjbG9zZShwcmVjLCBUcmVlSW5mby5hc3NpZ25QcmVjKTsKICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBVbmNoZWNrZWRJT0V4Y2VwdGlvbihlKTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIFN0cmluZyBvcGVyYXRvck5hbWUoSkNUcmVlLlRhZyB0YWcpIHsKICAgICAgICBzd2l0Y2godGFnKSB7CiAgICAgICAgICAgIGNhc2UgUE9TOiAgICAgcmV0dXJuICIrIjsKICAgICAgICAgICAgY2FzZSBORUc6ICAgICByZXR1cm4gIi0iOwogICAgICAgICAgICBjYXNlIE5PVDogICAgIHJldHVybiAiISI7CiAgICAgICAgICAgIGNhc2UgQ09NUEw6ICAgcmV0dXJuICJ+IjsKICAgICAgICAgICAgY2FzZSBQUkVJTkM6ICByZXR1cm4gIisrIjsKICAgICAgICAgICAgY2FzZSBQUkVERUM6ICByZXR1cm4gIi0tIjsKICAgICAgICAgICAgY2FzZSBQT1NUSU5DOiByZXR1cm4gIisrIjsKICAgICAgICAgICAgY2FzZSBQT1NUREVDOiByZXR1cm4gIi0tIjsKICAgICAgICAgICAgY2FzZSBOVUxMQ0hLOiByZXR1cm4gIjwqbnVsbGNoayo+IjsKICAgICAgICAgICAgY2FzZSBPUjogICAgICByZXR1cm4gInx8IjsKICAgICAgICAgICAgY2FzZSBBTkQ6ICAgICByZXR1cm4gIiYmIjsKICAgICAgICAgICAgY2FzZSBFUTogICAgICByZXR1cm4gIj09IjsKICAgICAgICAgICAgY2FzZSBORTogICAgICByZXR1cm4gIiE9IjsKICAgICAgICAgICAgY2FzZSBMVDogICAgICByZXR1cm4gIjwiOwogICAgICAgICAgICBjYXNlIEdUOiAgICAgIHJldHVybiAiPiI7CiAgICAgICAgICAgIGNhc2UgTEU6ICAgICAgcmV0dXJuICI8PSI7CiAgICAgICAgICAgIGNhc2UgR0U6ICAgICAgcmV0dXJuICI+PSI7CiAgICAgICAgICAgIGNhc2UgQklUT1I6ICAgcmV0dXJuICJ8IjsKICAgICAgICAgICAgY2FzZSBCSVRYT1I6ICByZXR1cm4gIl4iOwogICAgICAgICAgICBjYXNlIEJJVEFORDogIHJldHVybiAiJiI7CiAgICAgICAgICAgIGNhc2UgU0w6ICAgICAgcmV0dXJuICI8PCI7CiAgICAgICAgICAgIGNhc2UgU1I6ICAgICAgcmV0dXJuICI+PiI7CiAgICAgICAgICAgIGNhc2UgVVNSOiAgICAgcmV0dXJuICI+Pj4iOwogICAgICAgICAgICBjYXNlIFBMVVM6ICAgIHJldHVybiAiKyI7CiAgICAgICAgICAgIGNhc2UgTUlOVVM6ICAgcmV0dXJuICItIjsKICAgICAgICAgICAgY2FzZSBNVUw6ICAgICByZXR1cm4gIioiOwogICAgICAgICAgICBjYXNlIERJVjogICAgIHJldHVybiAiLyI7CiAgICAgICAgICAgIGNhc2UgTU9EOiAgICAgcmV0dXJuICIlIjsKICAgICAgICAgICAgZGVmYXVsdDogdGhyb3cgbmV3IEVycm9yKCk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0QXNzaWdub3AoSkNBc3NpZ25PcCB0cmVlKSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgb3BlbihwcmVjLCBUcmVlSW5mby5hc3NpZ25vcFByZWMpOwogICAgICAgICAgICBwcmludEV4cHIodHJlZS5saHMsIFRyZWVJbmZvLmFzc2lnbm9wUHJlYyArIDEpOwogICAgICAgICAgICBwcmludCgiICIgKyBvcGVyYXRvck5hbWUodHJlZS5nZXRUYWcoKS5ub0Fzc2lnbk9wKCkpICsgIj0gIik7CiAgICAgICAgICAgIHByaW50RXhwcih0cmVlLnJocywgVHJlZUluZm8uYXNzaWdub3BQcmVjKTsKICAgICAgICAgICAgY2xvc2UocHJlYywgVHJlZUluZm8uYXNzaWdub3BQcmVjKTsKICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBVbmNoZWNrZWRJT0V4Y2VwdGlvbihlKTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRVbmFyeShKQ1VuYXJ5IHRyZWUpIHsKICAgICAgICB0cnkgewogICAgICAgICAgICBpbnQgb3ducHJlYyA9IFRyZWVJbmZvLm9wUHJlYyh0cmVlLmdldFRhZygpKTsKICAgICAgICAgICAgU3RyaW5nIG9wbmFtZSA9IG9wZXJhdG9yTmFtZSh0cmVlLmdldFRhZygpKTsKICAgICAgICAgICAgb3BlbihwcmVjLCBvd25wcmVjKTsKICAgICAgICAgICAgaWYgKCF0cmVlLmdldFRhZygpLmlzUG9zdFVuYXJ5T3AoKSkgewogICAgICAgICAgICAgICAgcHJpbnQob3BuYW1lKTsKICAgICAgICAgICAgICAgIHByaW50RXhwcih0cmVlLmFyZywgb3ducHJlYyk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBwcmludEV4cHIodHJlZS5hcmcsIG93bnByZWMpOwogICAgICAgICAgICAgICAgcHJpbnQob3BuYW1lKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBjbG9zZShwcmVjLCBvd25wcmVjKTsKICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBVbmNoZWNrZWRJT0V4Y2VwdGlvbihlKTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRCaW5hcnkoSkNCaW5hcnkgdHJlZSkgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGludCBvd25wcmVjID0gVHJlZUluZm8ub3BQcmVjKHRyZWUuZ2V0VGFnKCkpOwogICAgICAgICAgICBTdHJpbmcgb3BuYW1lID0gb3BlcmF0b3JOYW1lKHRyZWUuZ2V0VGFnKCkpOwogICAgICAgICAgICBvcGVuKHByZWMsIG93bnByZWMpOwogICAgICAgICAgICBwcmludEV4cHIodHJlZS5saHMsIG93bnByZWMpOwogICAgICAgICAgICBwcmludCgiICIgKyBvcG5hbWUgKyAiICIpOwogICAgICAgICAgICBwcmludEV4cHIodHJlZS5yaHMsIG93bnByZWMgKyAxKTsKICAgICAgICAgICAgY2xvc2UocHJlYywgb3ducHJlYyk7CiAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgVW5jaGVja2VkSU9FeGNlcHRpb24oZSk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0VHlwZUNhc3QoSkNUeXBlQ2FzdCB0cmVlKSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgb3BlbihwcmVjLCBUcmVlSW5mby5wcmVmaXhQcmVjKTsKICAgICAgICAgICAgcHJpbnQoIigiKTsKICAgICAgICAgICAgcHJpbnRFeHByKHRyZWUuY2xhenopOwogICAgICAgICAgICBwcmludCgiKSIpOwogICAgICAgICAgICBwcmludEV4cHIodHJlZS5leHByLCBUcmVlSW5mby5wcmVmaXhQcmVjKTsKICAgICAgICAgICAgY2xvc2UocHJlYywgVHJlZUluZm8ucHJlZml4UHJlYyk7CiAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgVW5jaGVja2VkSU9FeGNlcHRpb24oZSk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0VHlwZVRlc3QoSkNJbnN0YW5jZU9mIHRyZWUpIHsKICAgICAgICB0cnkgewogICAgICAgICAgICBvcGVuKHByZWMsIFRyZWVJbmZvLm9yZFByZWMpOwogICAgICAgICAgICBwcmludEV4cHIodHJlZS5leHByLCBUcmVlSW5mby5vcmRQcmVjKTsKICAgICAgICAgICAgcHJpbnQoIiBpbnN0YW5jZW9mICIpOwogICAgICAgICAgICBwcmludEV4cHIodHJlZS5jbGF6eiwgVHJlZUluZm8ub3JkUHJlYyArIDEpOwogICAgICAgICAgICBjbG9zZShwcmVjLCBUcmVlSW5mby5vcmRQcmVjKTsKICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBVbmNoZWNrZWRJT0V4Y2VwdGlvbihlKTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRJbmRleGVkKEpDQXJyYXlBY2Nlc3MgdHJlZSkgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIHByaW50RXhwcih0cmVlLmluZGV4ZWQsIFRyZWVJbmZvLnBvc3RmaXhQcmVjKTsKICAgICAgICAgICAgcHJpbnQoIlsiKTsKICAgICAgICAgICAgcHJpbnRFeHByKHRyZWUuaW5kZXgpOwogICAgICAgICAgICBwcmludCgiXSIpOwogICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFVuY2hlY2tlZElPRXhjZXB0aW9uKGUpOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdFNlbGVjdChKQ0ZpZWxkQWNjZXNzIHRyZWUpIHsKICAgICAgICB0cnkgewogICAgICAgICAgICBwcmludEV4cHIodHJlZS5zZWxlY3RlZCwgVHJlZUluZm8ucG9zdGZpeFByZWMpOwogICAgICAgICAgICBwcmludCgiLiIgKyB0cmVlLm5hbWUpOwogICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFVuY2hlY2tlZElPRXhjZXB0aW9uKGUpOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdFJlZmVyZW5jZShKQ01lbWJlclJlZmVyZW5jZSB0cmVlKSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgcHJpbnRFeHByKHRyZWUuZXhwcik7CiAgICAgICAgICAgIHByaW50KCI6OiIpOwogICAgICAgICAgICBpZiAodHJlZS50eXBlYXJncyAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICBwcmludCgiPCIpOwogICAgICAgICAgICAgICAgcHJpbnRFeHBycyh0cmVlLnR5cGVhcmdzKTsKICAgICAgICAgICAgICAgIHByaW50KCI+Iik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcHJpbnQodHJlZS5nZXRNb2RlKCkgPT0gUmVmZXJlbmNlTW9kZS5JTlZPS0UgPyB0cmVlLm5hbWUgOiAibmV3Iik7CiAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgVW5jaGVja2VkSU9FeGNlcHRpb24oZSk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0SWRlbnQoSkNJZGVudCB0cmVlKSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgcHJpbnQodHJlZS5uYW1lKTsKICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBVbmNoZWNrZWRJT0V4Y2VwdGlvbihlKTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRMaXRlcmFsKEpDTGl0ZXJhbCB0cmVlKSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgc3dpdGNoICh0cmVlLnR5cGV0YWcpIHsKICAgICAgICAgICAgICAgIGNhc2UgSU5UOgogICAgICAgICAgICAgICAgICAgIHByaW50KHRyZWUudmFsdWUudG9TdHJpbmcoKSk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIExPTkc6CiAgICAgICAgICAgICAgICAgICAgcHJpbnQodHJlZS52YWx1ZSArICJMIik7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIEZMT0FUOgogICAgICAgICAgICAgICAgICAgIHByaW50KHRyZWUudmFsdWUgKyAiRiIpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBET1VCTEU6CiAgICAgICAgICAgICAgICAgICAgcHJpbnQodHJlZS52YWx1ZS50b1N0cmluZygpKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgQ0hBUjoKICAgICAgICAgICAgICAgICAgICBwcmludCgiXCciICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbnZlcnQucXVvdGUoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcudmFsdWVPZigoY2hhcikoKE51bWJlcil0cmVlLnZhbHVlKS5pbnRWYWx1ZSgpKSkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgIlwnIik7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIEJPT0xFQU46CiAgICAgICAgICAgICAgICAgICAgcHJpbnQoKChOdW1iZXIpdHJlZS52YWx1ZSkuaW50VmFsdWUoKSA9PSAxID8gInRydWUiIDogImZhbHNlIik7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIEJPVDoKICAgICAgICAgICAgICAgICAgICBwcmludCgibnVsbCIpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICBwcmludCgiXCIiICsgQ29udmVydC5xdW90ZSh0cmVlLnZhbHVlLnRvU3RyaW5nKCkpICsgIlwiIik7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBVbmNoZWNrZWRJT0V4Y2VwdGlvbihlKTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRUeXBlSWRlbnQoSkNQcmltaXRpdmVUeXBlVHJlZSB0cmVlKSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgc3dpdGNoKHRyZWUudHlwZXRhZykgewogICAgICAgICAgICAgICAgY2FzZSBCWVRFOgogICAgICAgICAgICAgICAgICAgIHByaW50KCJieXRlIik7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIENIQVI6CiAgICAgICAgICAgICAgICAgICAgcHJpbnQoImNoYXIiKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgU0hPUlQ6CiAgICAgICAgICAgICAgICAgICAgcHJpbnQoInNob3J0Iik7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIElOVDoKICAgICAgICAgICAgICAgICAgICBwcmludCgiaW50Iik7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIExPTkc6CiAgICAgICAgICAgICAgICAgICAgcHJpbnQoImxvbmciKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgRkxPQVQ6CiAgICAgICAgICAgICAgICAgICAgcHJpbnQoImZsb2F0Iik7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIERPVUJMRToKICAgICAgICAgICAgICAgICAgICBwcmludCgiZG91YmxlIik7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIEJPT0xFQU46CiAgICAgICAgICAgICAgICAgICAgcHJpbnQoImJvb2xlYW4iKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgVk9JRDoKICAgICAgICAgICAgICAgICAgICBwcmludCgidm9pZCIpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICBwcmludCgiZXJyb3IiKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFVuY2hlY2tlZElPRXhjZXB0aW9uKGUpOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdFR5cGVBcnJheShKQ0FycmF5VHlwZVRyZWUgdHJlZSkgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIHByaW50QmFzZUVsZW1lbnRUeXBlKHRyZWUpOwogICAgICAgICAgICBwcmludEJyYWNrZXRzKHRyZWUpOwogICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFVuY2hlY2tlZElPRXhjZXB0aW9uKGUpOwogICAgICAgIH0KICAgIH0KCiAgICAvLyBQcmludHMgdGhlIGlubmVyIGVsZW1lbnQgdHlwZSBvZiBhIG5lc3RlZCBhcnJheQogICAgcHJpdmF0ZSB2b2lkIHByaW50QmFzZUVsZW1lbnRUeXBlKEpDVHJlZSB0cmVlKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgIHByaW50RXhwcihUcmVlSW5mby5pbm5lcm1vc3RUeXBlKHRyZWUpKTsKICAgIH0KCiAgICAvLyBwcmludHMgdGhlIGJyYWNrZXRzIG9mIGEgbmVzdGVkIGFycmF5IGluIHJldmVyc2Ugb3JkZXIKICAgIC8vIHRyZWUgaXMgZWl0aGVyIEpDQXJyYXlUeXBlVHJlZSBvciBKQ0Fubm90YXRlZFR5cGVUcmVlCiAgICBwcml2YXRlIHZvaWQgcHJpbnRCcmFja2V0cyhKQ1RyZWUgdHJlZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICBKQ1RyZWUgZWxlbSA9IHRyZWU7CiAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgICAgaWYgKGVsZW0uaGFzVGFnKEFOTk9UQVRFRF9UWVBFKSkgewogICAgICAgICAgICAgICAgSkNBbm5vdGF0ZWRUeXBlIGF0eXBlID0gKEpDQW5ub3RhdGVkVHlwZSkgZWxlbTsKICAgICAgICAgICAgICAgIGVsZW0gPSBhdHlwZS51bmRlcmx5aW5nVHlwZTsKICAgICAgICAgICAgICAgIGlmIChlbGVtLmhhc1RhZyhUWVBFQVJSQVkpKSB7CiAgICAgICAgICAgICAgICAgICAgcHJpbnQoJyAnKTsKICAgICAgICAgICAgICAgICAgICBwcmludFR5cGVBbm5vdGF0aW9ucyhhdHlwZS5hbm5vdGF0aW9ucyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGVsZW0uaGFzVGFnKFRZUEVBUlJBWSkpIHsKICAgICAgICAgICAgICAgIHByaW50KCJbXSIpOwogICAgICAgICAgICAgICAgZWxlbSA9ICgoSkNBcnJheVR5cGVUcmVlKWVsZW0pLmVsZW10eXBlOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRUeXBlQXBwbHkoSkNUeXBlQXBwbHkgdHJlZSkgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIHByaW50RXhwcih0cmVlLmNsYXp6KTsKICAgICAgICAgICAgcHJpbnQoIjwiKTsKICAgICAgICAgICAgcHJpbnRFeHBycyh0cmVlLmFyZ3VtZW50cyk7CiAgICAgICAgICAgIHByaW50KCI+Iik7CiAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgVW5jaGVja2VkSU9FeGNlcHRpb24oZSk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0VHlwZVVuaW9uKEpDVHlwZVVuaW9uIHRyZWUpIHsKICAgICAgICB0cnkgewogICAgICAgICAgICBwcmludEV4cHJzKHRyZWUuYWx0ZXJuYXRpdmVzLCAiIHwgIik7CiAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgVW5jaGVja2VkSU9FeGNlcHRpb24oZSk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0VHlwZUludGVyc2VjdGlvbihKQ1R5cGVJbnRlcnNlY3Rpb24gdHJlZSkgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIHByaW50RXhwcnModHJlZS5ib3VuZHMsICIgJiAiKTsKICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBVbmNoZWNrZWRJT0V4Y2VwdGlvbihlKTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRUeXBlUGFyYW1ldGVyKEpDVHlwZVBhcmFtZXRlciB0cmVlKSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgaWYgKHRyZWUuYW5ub3RhdGlvbnMubm9uRW1wdHkoKSkgewogICAgICAgICAgICAgICAgdGhpcy5wcmludFR5cGVBbm5vdGF0aW9ucyh0cmVlLmFubm90YXRpb25zKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBwcmludCh0cmVlLm5hbWUpOwogICAgICAgICAgICBpZiAodHJlZS5ib3VuZHMubm9uRW1wdHkoKSkgewogICAgICAgICAgICAgICAgcHJpbnQoIiBleHRlbmRzICIpOwogICAgICAgICAgICAgICAgcHJpbnRFeHBycyh0cmVlLmJvdW5kcywgIiAmICIpOwogICAgICAgICAgICB9CiAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgVW5jaGVja2VkSU9FeGNlcHRpb24oZSk7CiAgICAgICAgfQogICAgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIHZvaWQgdmlzaXRXaWxkY2FyZChKQ1dpbGRjYXJkIHRyZWUpIHsKICAgICAgICB0cnkgewogICAgICAgICAgICBwcmludCh0cmVlLmtpbmQpOwogICAgICAgICAgICBpZiAodHJlZS5raW5kLmtpbmQgIT0gQm91bmRLaW5kLlVOQk9VTkQpCiAgICAgICAgICAgICAgICBwcmludEV4cHIodHJlZS5pbm5lcik7CiAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgVW5jaGVja2VkSU9FeGNlcHRpb24oZSk7CiAgICAgICAgfQogICAgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIHZvaWQgdmlzaXRUeXBlQm91bmRLaW5kKFR5cGVCb3VuZEtpbmQgdHJlZSkgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIHByaW50KFN0cmluZy52YWx1ZU9mKHRyZWUua2luZCkpOwogICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFVuY2hlY2tlZElPRXhjZXB0aW9uKGUpOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdEVycm9uZW91cyhKQ0Vycm9uZW91cyB0cmVlKSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgcHJpbnQoIihFUlJPUikiKTsKICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBVbmNoZWNrZWRJT0V4Y2VwdGlvbihlKTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRMZXRFeHByKExldEV4cHIgdHJlZSkgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIHByaW50KCIobGV0ICIgKyB0cmVlLmRlZnMgKyAiIGluICIgKyB0cmVlLmV4cHIgKyAiKSIpOwogICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFVuY2hlY2tlZElPRXhjZXB0aW9uKGUpOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdE1vZGlmaWVycyhKQ01vZGlmaWVycyBtb2RzKSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgcHJpbnRBbm5vdGF0aW9ucyhtb2RzLmFubm90YXRpb25zKTsKICAgICAgICAgICAgcHJpbnRGbGFncyhtb2RzLmZsYWdzKTsKICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBVbmNoZWNrZWRJT0V4Y2VwdGlvbihlKTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRBbm5vdGF0aW9uKEpDQW5ub3RhdGlvbiB0cmVlKSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgcHJpbnQoIkAiKTsKICAgICAgICAgICAgcHJpbnRFeHByKHRyZWUuYW5ub3RhdGlvblR5cGUpOwogICAgICAgICAgICBwcmludCgiKCIpOwogICAgICAgICAgICBwcmludEV4cHJzKHRyZWUuYXJncyk7CiAgICAgICAgICAgIHByaW50KCIpIik7CiAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgVW5jaGVja2VkSU9FeGNlcHRpb24oZSk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0QW5ub3RhdGVkVHlwZShKQ0Fubm90YXRlZFR5cGUgdHJlZSkgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGlmICh0cmVlLnVuZGVybHlpbmdUeXBlLmhhc1RhZyhTRUxFQ1QpKSB7CiAgICAgICAgICAgICAgICBKQ0ZpZWxkQWNjZXNzIGFjY2VzcyA9IChKQ0ZpZWxkQWNjZXNzKSB0cmVlLnVuZGVybHlpbmdUeXBlOwogICAgICAgICAgICAgICAgcHJpbnRFeHByKGFjY2Vzcy5zZWxlY3RlZCwgVHJlZUluZm8ucG9zdGZpeFByZWMpOwogICAgICAgICAgICAgICAgcHJpbnQoIi4iKTsKICAgICAgICAgICAgICAgIHByaW50VHlwZUFubm90YXRpb25zKHRyZWUuYW5ub3RhdGlvbnMpOwogICAgICAgICAgICAgICAgcHJpbnQoYWNjZXNzLm5hbWUpOwogICAgICAgICAgICB9IGVsc2UgaWYgKHRyZWUudW5kZXJseWluZ1R5cGUuaGFzVGFnKFRZUEVBUlJBWSkpIHsKICAgICAgICAgICAgICAgIHByaW50QmFzZUVsZW1lbnRUeXBlKHRyZWUpOwogICAgICAgICAgICAgICAgcHJpbnRCcmFja2V0cyh0cmVlKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHByaW50VHlwZUFubm90YXRpb25zKHRyZWUuYW5ub3RhdGlvbnMpOwogICAgICAgICAgICAgICAgcHJpbnRFeHByKHRyZWUudW5kZXJseWluZ1R5cGUpOwogICAgICAgICAgICB9CiAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgVW5jaGVja2VkSU9FeGNlcHRpb24oZSk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0VHJlZShKQ1RyZWUgdHJlZSkgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIHByaW50KCIoVU5LTk9XTjogIiArIHRyZWUuZ2V0VGFnKCkgKyAiKSIpOwogICAgICAgICAgICBwcmludGxuKCk7CiAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgVW5jaGVja2VkSU9FeGNlcHRpb24oZSk7CiAgICAgICAgfQogICAgfQoKfQpQSwMECgAACAAABjupSttHn/gEdgAABHYAACQAAABjb20vc3VuL3Rvb2xzL2phdmFjL3RyZWUvRENUcmVlLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTEsIDIwMTYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhYy50cmVlOwoKaW1wb3J0IGphdmF4LnRvb2xzLkRpYWdub3N0aWM7CgppbXBvcnQgY29tLnN1bi5zb3VyY2UuZG9jdHJlZS4qOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5wYXJzZXIuVG9rZW5zLkNvbW1lbnQ7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuQXNzZXJ0OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkRlZmluZWRCeTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5EZWZpbmVkQnkuQXBpOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkRpYWdub3N0aWNTb3VyY2U7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuSkNEaWFnbm9zdGljOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkpDRGlhZ25vc3RpYy5TaW1wbGVEaWFnbm9zdGljUG9zaXRpb247CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuUG9zaXRpb247CgppbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKaW1wb3J0IGphdmEuaW8uU3RyaW5nV3JpdGVyOwppbXBvcnQgamF2YS51dGlsLkxpc3Q7CgppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5lbGVtZW50Lk5hbWU7CmltcG9ydCBqYXZheC50b29scy5KYXZhRmlsZU9iamVjdDsKCi8qKgogKiA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yCiAqIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj4KICovCnB1YmxpYyBhYnN0cmFjdCBjbGFzcyBEQ1RyZWUgaW1wbGVtZW50cyBEb2NUcmVlIHsKCiAgICAvKioKICAgICAqIFRoZSBwb3NpdGlvbiBpbiB0aGUgY29tbWVudCBzdHJpbmcuCiAgICAgKiBVc2Uge0BsaW5rICNnZXRTb3VyY2VQb3NpdGlvbiBnZXRTb3VyY2VQb3NpdGlvbn0gdG8gY29udmVydAogICAgICogaXQgdG8gYSBwb3NpdGlvbiBpbiB0aGUgc291cmNlIGZpbGUuCiAgICAgKgogICAgICogVE9ETzogd2h5IG5vdCBzaW1wbHkgdHJhbnNsYXRlIGFsbCB0aGVzZSB2YWx1ZXMgaW50bwogICAgICogc291cmNlIGZpbGUgcG9zaXRpb25zPyBJcyBpdCB1c2VmdWwgdG8gaGF2ZSBzdHJpbmctb2Zmc2V0CiAgICAgKiBwb3NpdGlvbnMgYXMgd2VsbD8KICAgICAqLwogICAgcHVibGljIGludCBwb3M7CgogICAgcHVibGljIGxvbmcgZ2V0U291cmNlUG9zaXRpb24oRENEb2NDb21tZW50IGRjKSB7CiAgICAgICAgcmV0dXJuIGRjLmNvbW1lbnQuZ2V0U291cmNlUG9zKHBvcyk7CiAgICB9CgogICAgcHVibGljIEpDRGlhZ25vc3RpYy5EaWFnbm9zdGljUG9zaXRpb24gcG9zKERDRG9jQ29tbWVudCBkYykgewogICAgICAgIHJldHVybiBuZXcgU2ltcGxlRGlhZ25vc3RpY1Bvc2l0aW9uKGRjLmNvbW1lbnQuZ2V0U291cmNlUG9zKHBvcykpOwogICAgfQoKICAgIC8qKiBDb252ZXJ0IGEgdHJlZSB0byBhIHByZXR0eS1wcmludGVkIHN0cmluZy4gKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKICAgICAgICBTdHJpbmdXcml0ZXIgcyA9IG5ldyBTdHJpbmdXcml0ZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgICBuZXcgRG9jUHJldHR5KHMpLnByaW50KHRoaXMpOwogICAgICAgIH0KICAgICAgICBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICAvLyBzaG91bGQgbmV2ZXIgaGFwcGVuLCBiZWNhdXNlIFN0cmluZ1dyaXRlciBpcyBkZWZpbmVkCiAgICAgICAgICAgIC8vIG5ldmVyIHRvIHRocm93IGFueSBJT0V4Y2VwdGlvbnMKICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKGUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcy50b1N0cmluZygpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgYWJzdHJhY3QgY2xhc3MgRENFbmRQb3NUcmVlPFQgZXh0ZW5kcyBEQ0VuZFBvc1RyZWU8VD4+IGV4dGVuZHMgRENUcmVlIHsKCiAgICAgICAgcHJpdmF0ZSBpbnQgZW5kUG9zID0gUG9zaXRpb24uTk9QT1M7CgogICAgICAgIHB1YmxpYyBpbnQgZ2V0RW5kUG9zKERDRG9jQ29tbWVudCBkYykgewogICAgICAgICAgICByZXR1cm4gZGMuY29tbWVudC5nZXRTb3VyY2VQb3MoZW5kUG9zKTsKICAgICAgICB9CgogICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQogICAgICAgIHB1YmxpYyBUIHNldEVuZFBvcyhpbnQgZW5kUG9zKSB7CiAgICAgICAgICAgIHRoaXMuZW5kUG9zID0gZW5kUG9zOwogICAgICAgICAgICByZXR1cm4gKFQpIHRoaXM7CiAgICAgICAgfQoKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIERDRG9jQ29tbWVudCBleHRlbmRzIERDVHJlZSBpbXBsZW1lbnRzIERvY0NvbW1lbnRUcmVlIHsKICAgICAgICBwdWJsaWMgZmluYWwgQ29tbWVudCBjb21tZW50OyAvLyByZXF1aXJlZCBmb3IgdGhlIGltcGxpY2l0IHNvdXJjZSBwb3MgdGFibGUKCiAgICAgICAgcHVibGljIGZpbmFsIExpc3Q8RENUcmVlPiBmdWxsQm9keTsKICAgICAgICBwdWJsaWMgZmluYWwgTGlzdDxEQ1RyZWU+IGZpcnN0U2VudGVuY2U7CiAgICAgICAgcHVibGljIGZpbmFsIExpc3Q8RENUcmVlPiBib2R5OwogICAgICAgIHB1YmxpYyBmaW5hbCBMaXN0PERDVHJlZT4gdGFnczsKCiAgICAgICAgcHVibGljIERDRG9jQ29tbWVudChDb21tZW50IGNvbW1lbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0PERDVHJlZT4gZnVsbEJvZHksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0PERDVHJlZT4gZmlyc3RTZW50ZW5jZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIExpc3Q8RENUcmVlPiBib2R5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgTGlzdDxEQ1RyZWU+IHRhZ3MpIHsKICAgICAgICAgICAgdGhpcy5jb21tZW50ID0gY29tbWVudDsKICAgICAgICAgICAgdGhpcy5maXJzdFNlbnRlbmNlID0gZmlyc3RTZW50ZW5jZTsKICAgICAgICAgICAgdGhpcy5mdWxsQm9keSA9IGZ1bGxCb2R5OwogICAgICAgICAgICB0aGlzLmJvZHkgPSBib2R5OwogICAgICAgICAgICB0aGlzLnRhZ3MgPSB0YWdzOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIEtpbmQgZ2V0S2luZCgpIHsKICAgICAgICAgICAgcmV0dXJuIEtpbmQuRE9DX0NPTU1FTlQ7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgPFIsIEQ+IFIgYWNjZXB0KERvY1RyZWVWaXNpdG9yPFIsIEQ+IHYsIEQgZCkgewogICAgICAgICAgICByZXR1cm4gdi52aXNpdERvY0NvbW1lbnQodGhpcywgZCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgTGlzdDw/IGV4dGVuZHMgRG9jVHJlZT4gZ2V0Rmlyc3RTZW50ZW5jZSgpIHsKICAgICAgICAgICAgcmV0dXJuIGZpcnN0U2VudGVuY2U7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgTGlzdDw/IGV4dGVuZHMgRG9jVHJlZT4gZ2V0RnVsbEJvZHkoKSB7CiAgICAgICAgICAgIHJldHVybiBmdWxsQm9keTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBMaXN0PD8gZXh0ZW5kcyBEb2NUcmVlPiBnZXRCb2R5KCkgewogICAgICAgICAgICByZXR1cm4gYm9keTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBMaXN0PD8gZXh0ZW5kcyBEb2NUcmVlPiBnZXRCbG9ja1RhZ3MoKSB7CiAgICAgICAgICAgIHJldHVybiB0YWdzOwogICAgICAgIH0KCiAgICB9CgogICAgcHVibGljIHN0YXRpYyBhYnN0cmFjdCBjbGFzcyBEQ0Jsb2NrVGFnIGV4dGVuZHMgRENUcmVlIGltcGxlbWVudHMgQmxvY2tUYWdUcmVlIHsKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgU3RyaW5nIGdldFRhZ05hbWUoKSB7CiAgICAgICAgICAgIHJldHVybiBnZXRLaW5kKCkudGFnTmFtZTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBhYnN0cmFjdCBjbGFzcyBEQ0lubGluZVRhZyBleHRlbmRzIERDRW5kUG9zVHJlZTxEQ0lubGluZVRhZz4gaW1wbGVtZW50cyBJbmxpbmVUYWdUcmVlIHsKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgU3RyaW5nIGdldFRhZ05hbWUoKSB7CiAgICAgICAgICAgIHJldHVybiBnZXRLaW5kKCkudGFnTmFtZTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjbGFzcyBEQ0F0dHJpYnV0ZSBleHRlbmRzIERDVHJlZSBpbXBsZW1lbnRzIEF0dHJpYnV0ZVRyZWUgewogICAgICAgIHB1YmxpYyBmaW5hbCBOYW1lIG5hbWU7CiAgICAgICAgcHVibGljIGZpbmFsIFZhbHVlS2luZCB2a2luZDsKICAgICAgICBwdWJsaWMgZmluYWwgTGlzdDxEQ1RyZWU+IHZhbHVlOwoKICAgICAgICBEQ0F0dHJpYnV0ZShOYW1lIG5hbWUsIFZhbHVlS2luZCB2a2luZCwgTGlzdDxEQ1RyZWU+IHZhbHVlKSB7CiAgICAgICAgICAgIEFzc2VydC5jaGVjaygodmtpbmQgPT0gVmFsdWVLaW5kLkVNUFRZKSA/ICh2YWx1ZSA9PSBudWxsKSA6ICh2YWx1ZSAhPSBudWxsKSk7CiAgICAgICAgICAgIHRoaXMubmFtZSA9IG5hbWU7CiAgICAgICAgICAgIHRoaXMudmtpbmQgPSB2a2luZDsKICAgICAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIEtpbmQgZ2V0S2luZCgpIHsKICAgICAgICAgICAgcmV0dXJuIEtpbmQuQVRUUklCVVRFOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIDxSLCBEPiBSIGFjY2VwdChEb2NUcmVlVmlzaXRvcjxSLCBEPiB2LCBEIGQpIHsKICAgICAgICAgICAgcmV0dXJuIHYudmlzaXRBdHRyaWJ1dGUodGhpcywgZCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgTmFtZSBnZXROYW1lKCkgewogICAgICAgICAgICByZXR1cm4gbmFtZTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBWYWx1ZUtpbmQgZ2V0VmFsdWVLaW5kKCkgewogICAgICAgICAgICByZXR1cm4gdmtpbmQ7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgTGlzdDxEQ1RyZWU+IGdldFZhbHVlKCkgewogICAgICAgICAgICByZXR1cm4gdmFsdWU7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgRENBdXRob3IgZXh0ZW5kcyBEQ0Jsb2NrVGFnIGltcGxlbWVudHMgQXV0aG9yVHJlZSB7CiAgICAgICAgcHVibGljIGZpbmFsIExpc3Q8RENUcmVlPiBuYW1lOwoKICAgICAgICBEQ0F1dGhvcihMaXN0PERDVHJlZT4gbmFtZSkgewogICAgICAgICAgICB0aGlzLm5hbWUgPSBuYW1lOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIEtpbmQgZ2V0S2luZCgpIHsKICAgICAgICAgICAgcmV0dXJuIEtpbmQuQVVUSE9SOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIDxSLCBEPiBSIGFjY2VwdChEb2NUcmVlVmlzaXRvcjxSLCBEPiB2LCBEIGQpIHsKICAgICAgICAgICAgcmV0dXJuIHYudmlzaXRBdXRob3IodGhpcywgZCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgTGlzdDw/IGV4dGVuZHMgRG9jVHJlZT4gZ2V0TmFtZSgpIHsKICAgICAgICAgICAgcmV0dXJuIG5hbWU7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgRENDb21tZW50IGV4dGVuZHMgRENUcmVlIGltcGxlbWVudHMgQ29tbWVudFRyZWUgewogICAgICAgIHB1YmxpYyBmaW5hbCBTdHJpbmcgYm9keTsKCiAgICAgICAgRENDb21tZW50KFN0cmluZyBib2R5KSB7CiAgICAgICAgICAgIHRoaXMuYm9keSA9IGJvZHk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgS2luZCBnZXRLaW5kKCkgewogICAgICAgICAgICByZXR1cm4gS2luZC5DT01NRU5UOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIDxSLCBEPiBSIGFjY2VwdChEb2NUcmVlVmlzaXRvcjxSLCBEPiB2LCBEIGQpIHsKICAgICAgICAgICAgcmV0dXJuIHYudmlzaXRDb21tZW50KHRoaXMsIGQpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIFN0cmluZyBnZXRCb2R5KCkgewogICAgICAgICAgICByZXR1cm4gYm9keTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjbGFzcyBEQ0RlcHJlY2F0ZWQgZXh0ZW5kcyBEQ0Jsb2NrVGFnIGltcGxlbWVudHMgRGVwcmVjYXRlZFRyZWUgewogICAgICAgIHB1YmxpYyBmaW5hbCBMaXN0PERDVHJlZT4gYm9keTsKCiAgICAgICAgRENEZXByZWNhdGVkKExpc3Q8RENUcmVlPiBib2R5KSB7CiAgICAgICAgICAgIHRoaXMuYm9keSA9IGJvZHk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgS2luZCBnZXRLaW5kKCkgewogICAgICAgICAgICByZXR1cm4gS2luZC5ERVBSRUNBVEVEOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIDxSLCBEPiBSIGFjY2VwdChEb2NUcmVlVmlzaXRvcjxSLCBEPiB2LCBEIGQpIHsKICAgICAgICAgICAgcmV0dXJuIHYudmlzaXREZXByZWNhdGVkKHRoaXMsIGQpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIExpc3Q8PyBleHRlbmRzIERvY1RyZWU+IGdldEJvZHkoKSB7CiAgICAgICAgICAgIHJldHVybiBib2R5OwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIERDRG9jUm9vdCBleHRlbmRzIERDSW5saW5lVGFnIGltcGxlbWVudHMgRG9jUm9vdFRyZWUgewoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgS2luZCBnZXRLaW5kKCkgewogICAgICAgICAgICByZXR1cm4gS2luZC5ET0NfUk9PVDsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyA8UiwgRD4gUiBhY2NlcHQoRG9jVHJlZVZpc2l0b3I8UiwgRD4gdiwgRCBkKSB7CiAgICAgICAgICAgIHJldHVybiB2LnZpc2l0RG9jUm9vdCh0aGlzLCBkKTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjbGFzcyBEQ0VuZEVsZW1lbnQgZXh0ZW5kcyBEQ1RyZWUgaW1wbGVtZW50cyBFbmRFbGVtZW50VHJlZSB7CiAgICAgICAgcHVibGljIGZpbmFsIE5hbWUgbmFtZTsKCiAgICAgICAgRENFbmRFbGVtZW50KE5hbWUgbmFtZSkgewogICAgICAgICAgICB0aGlzLm5hbWUgPSBuYW1lOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIEtpbmQgZ2V0S2luZCgpIHsKICAgICAgICAgICAgcmV0dXJuIEtpbmQuRU5EX0VMRU1FTlQ7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgPFIsIEQ+IFIgYWNjZXB0KERvY1RyZWVWaXNpdG9yPFIsIEQ+IHYsIEQgZCkgewogICAgICAgICAgICByZXR1cm4gdi52aXNpdEVuZEVsZW1lbnQodGhpcywgZCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgTmFtZSBnZXROYW1lKCkgewogICAgICAgICAgICByZXR1cm4gbmFtZTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjbGFzcyBEQ0VudGl0eSBleHRlbmRzIERDVHJlZSBpbXBsZW1lbnRzIEVudGl0eVRyZWUgewogICAgICAgIHB1YmxpYyBmaW5hbCBOYW1lIG5hbWU7CgogICAgICAgIERDRW50aXR5KE5hbWUgbmFtZSkgewogICAgICAgICAgICB0aGlzLm5hbWUgPSBuYW1lOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIEtpbmQgZ2V0S2luZCgpIHsKICAgICAgICAgICAgcmV0dXJuIEtpbmQuRU5USVRZOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIDxSLCBEPiBSIGFjY2VwdChEb2NUcmVlVmlzaXRvcjxSLCBEPiB2LCBEIGQpIHsKICAgICAgICAgICAgcmV0dXJuIHYudmlzaXRFbnRpdHkodGhpcywgZCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgTmFtZSBnZXROYW1lKCkgewogICAgICAgICAgICByZXR1cm4gbmFtZTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjbGFzcyBEQ0Vycm9uZW91cyBleHRlbmRzIERDVHJlZSBpbXBsZW1lbnRzIEVycm9uZW91c1RyZWUsIEpDRGlhZ25vc3RpYy5EaWFnbm9zdGljUG9zaXRpb24gewogICAgICAgIHB1YmxpYyBmaW5hbCBTdHJpbmcgYm9keTsKICAgICAgICBwdWJsaWMgZmluYWwgSkNEaWFnbm9zdGljIGRpYWc7CgogICAgICAgIERDRXJyb25lb3VzKFN0cmluZyBib2R5LCBKQ0RpYWdub3N0aWMuRmFjdG9yeSBkaWFncywgRGlhZ25vc3RpY1NvdXJjZSBkaWFnU291cmNlLCBTdHJpbmcgY29kZSwgT2JqZWN0Li4uIGFyZ3MpIHsKICAgICAgICAgICAgdGhpcy5ib2R5ID0gYm9keTsKICAgICAgICAgICAgdGhpcy5kaWFnID0gZGlhZ3MuZXJyb3IobnVsbCwgZGlhZ1NvdXJjZSwgdGhpcywgY29kZSwgYXJncyk7CiAgICAgICAgfQoKICAgICAgICBEQ0Vycm9uZW91cyhTdHJpbmcgYm9keSwgSkNEaWFnbm9zdGljIGRpYWcpIHsKICAgICAgICAgICAgdGhpcy5ib2R5ID0gYm9keTsKICAgICAgICAgICAgdGhpcy5kaWFnID0gZGlhZzsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBLaW5kIGdldEtpbmQoKSB7CiAgICAgICAgICAgIHJldHVybiBLaW5kLkVSUk9ORU9VUzsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyA8UiwgRD4gUiBhY2NlcHQoRG9jVHJlZVZpc2l0b3I8UiwgRD4gdiwgRCBkKSB7CiAgICAgICAgICAgIHJldHVybiB2LnZpc2l0RXJyb25lb3VzKHRoaXMsIGQpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIFN0cmluZyBnZXRCb2R5KCkgewogICAgICAgICAgICByZXR1cm4gYm9keTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBEaWFnbm9zdGljPEphdmFGaWxlT2JqZWN0PiBnZXREaWFnbm9zdGljKCkgewogICAgICAgICAgICByZXR1cm4gZGlhZzsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBKQ1RyZWUgZ2V0VHJlZSgpIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgaW50IGdldFN0YXJ0UG9zaXRpb24oKSB7CiAgICAgICAgICAgIHJldHVybiBwb3M7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgaW50IGdldFByZWZlcnJlZFBvc2l0aW9uKCkgewogICAgICAgICAgICByZXR1cm4gcG9zICsgYm9keS5sZW5ndGgoKSAtIDE7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgaW50IGdldEVuZFBvc2l0aW9uKEVuZFBvc1RhYmxlIGVuZFBvc1RhYmxlKSB7CiAgICAgICAgICAgIHJldHVybiBwb3MgKyBib2R5Lmxlbmd0aCgpOwogICAgICAgIH0KCiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjbGFzcyBEQ0hpZGRlbiBleHRlbmRzIERDQmxvY2tUYWcgaW1wbGVtZW50cyBIaWRkZW5UcmVlIHsKICAgICAgICBwdWJsaWMgZmluYWwgTGlzdDxEQ1RyZWU+IGJvZHk7CgogICAgICAgIERDSGlkZGVuKExpc3Q8RENUcmVlPiBib2R5KSB7CiAgICAgICAgICAgIHRoaXMuYm9keSA9IGJvZHk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgS2luZCBnZXRLaW5kKCkgewogICAgICAgICAgICByZXR1cm4gS2luZC5ISURERU47CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgPFIsIEQ+IFIgYWNjZXB0KERvY1RyZWVWaXNpdG9yPFIsIEQ+IHYsIEQgZCkgewogICAgICAgICAgICByZXR1cm4gdi52aXNpdEhpZGRlbih0aGlzLCBkKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBMaXN0PD8gZXh0ZW5kcyBEb2NUcmVlPiBnZXRCb2R5KCkgewogICAgICAgICAgICByZXR1cm4gYm9keTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjbGFzcyBEQ0lkZW50aWZpZXIgZXh0ZW5kcyBEQ1RyZWUgaW1wbGVtZW50cyBJZGVudGlmaWVyVHJlZSB7CiAgICAgICAgcHVibGljIGZpbmFsIE5hbWUgbmFtZTsKCiAgICAgICAgRENJZGVudGlmaWVyKE5hbWUgbmFtZSkgewogICAgICAgICAgICB0aGlzLm5hbWUgPSBuYW1lOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIEtpbmQgZ2V0S2luZCgpIHsKICAgICAgICAgICAgcmV0dXJuIEtpbmQuSURFTlRJRklFUjsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyA8UiwgRD4gUiBhY2NlcHQoRG9jVHJlZVZpc2l0b3I8UiwgRD4gdiwgRCBkKSB7CiAgICAgICAgICAgIHJldHVybiB2LnZpc2l0SWRlbnRpZmllcih0aGlzLCBkKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBOYW1lIGdldE5hbWUoKSB7CiAgICAgICAgICAgIHJldHVybiBuYW1lOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIERDSW5kZXggZXh0ZW5kcyBEQ0lubGluZVRhZyBpbXBsZW1lbnRzIEluZGV4VHJlZSB7CiAgICAgICAgcHVibGljIGZpbmFsIERDVHJlZSB0ZXJtOwogICAgICAgIHB1YmxpYyBmaW5hbCBMaXN0PERDVHJlZT4gZGVzY3JpcHRpb247CgogICAgICAgIERDSW5kZXgoRENUcmVlIHRlcm0sIExpc3Q8RENUcmVlPiBkZXNjcmlwdGlvbikgewogICAgICAgICAgICB0aGlzLnRlcm0gPSB0ZXJtOwogICAgICAgICAgICB0aGlzLmRlc2NyaXB0aW9uID0gZGVzY3JpcHRpb247CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgS2luZCBnZXRLaW5kKCkgewogICAgICAgICAgICByZXR1cm4gS2luZC5JTkRFWDsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyA8UiwgRD4gUiBhY2NlcHQoRG9jVHJlZVZpc2l0b3I8UiwgRD4gdiwgRCBkKSB7CiAgICAgICAgICAgIHJldHVybiB2LnZpc2l0SW5kZXgodGhpcywgZCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgRG9jVHJlZSBnZXRTZWFyY2hUZXJtKCkgewogICAgICAgICAgICByZXR1cm4gdGVybTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgRG9jVHJlZT4gZ2V0RGVzY3JpcHRpb24oKSB7CiAgICAgICAgICAgIHJldHVybiBkZXNjcmlwdGlvbjsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjbGFzcyBEQ0luaGVyaXREb2MgZXh0ZW5kcyBEQ0lubGluZVRhZyBpbXBsZW1lbnRzIEluaGVyaXREb2NUcmVlIHsKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgS2luZCBnZXRLaW5kKCkgewogICAgICAgICAgICByZXR1cm4gS2luZC5JTkhFUklUX0RPQzsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyA8UiwgRD4gUiBhY2NlcHQoRG9jVHJlZVZpc2l0b3I8UiwgRD4gdiwgRCBkKSB7CiAgICAgICAgICAgIHJldHVybiB2LnZpc2l0SW5oZXJpdERvYyh0aGlzLCBkKTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjbGFzcyBEQ0xpbmsgZXh0ZW5kcyBEQ0lubGluZVRhZyBpbXBsZW1lbnRzIExpbmtUcmVlIHsKICAgICAgICBwdWJsaWMgZmluYWwgS2luZCBraW5kOwogICAgICAgIHB1YmxpYyBmaW5hbCBEQ1JlZmVyZW5jZSByZWY7CiAgICAgICAgcHVibGljIGZpbmFsIExpc3Q8RENUcmVlPiBsYWJlbDsKCiAgICAgICAgRENMaW5rKEtpbmQga2luZCwgRENSZWZlcmVuY2UgcmVmLCBMaXN0PERDVHJlZT4gbGFiZWwpIHsKICAgICAgICAgICAgQXNzZXJ0LmNoZWNrKGtpbmQgPT0gS2luZC5MSU5LIHx8IGtpbmQgPT0gS2luZC5MSU5LX1BMQUlOKTsKICAgICAgICAgICAgdGhpcy5raW5kID0ga2luZDsKICAgICAgICAgICAgdGhpcy5yZWYgPSByZWY7CiAgICAgICAgICAgIHRoaXMubGFiZWwgPSBsYWJlbDsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBLaW5kIGdldEtpbmQoKSB7CiAgICAgICAgICAgIHJldHVybiBraW5kOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIDxSLCBEPiBSIGFjY2VwdChEb2NUcmVlVmlzaXRvcjxSLCBEPiB2LCBEIGQpIHsKICAgICAgICAgICAgcmV0dXJuIHYudmlzaXRMaW5rKHRoaXMsIGQpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIFJlZmVyZW5jZVRyZWUgZ2V0UmVmZXJlbmNlKCkgewogICAgICAgICAgICByZXR1cm4gcmVmOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIExpc3Q8PyBleHRlbmRzIERvY1RyZWU+IGdldExhYmVsKCkgewogICAgICAgICAgICByZXR1cm4gbGFiZWw7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgRENMaXRlcmFsIGV4dGVuZHMgRENJbmxpbmVUYWcgaW1wbGVtZW50cyBMaXRlcmFsVHJlZSB7CiAgICAgICAgcHVibGljIGZpbmFsIEtpbmQga2luZDsKICAgICAgICBwdWJsaWMgZmluYWwgRENUZXh0IGJvZHk7CgogICAgICAgIERDTGl0ZXJhbChLaW5kIGtpbmQsIERDVGV4dCBib2R5KSB7CiAgICAgICAgICAgIEFzc2VydC5jaGVjayhraW5kID09IEtpbmQuQ09ERSB8fCBraW5kID09IEtpbmQuTElURVJBTCk7CiAgICAgICAgICAgIHRoaXMua2luZCA9IGtpbmQ7CiAgICAgICAgICAgIHRoaXMuYm9keSA9IGJvZHk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgS2luZCBnZXRLaW5kKCkgewogICAgICAgICAgICByZXR1cm4ga2luZDsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyA8UiwgRD4gUiBhY2NlcHQoRG9jVHJlZVZpc2l0b3I8UiwgRD4gdiwgRCBkKSB7CiAgICAgICAgICAgIHJldHVybiB2LnZpc2l0TGl0ZXJhbCh0aGlzLCBkKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBEQ1RleHQgZ2V0Qm9keSgpIHsKICAgICAgICAgICAgcmV0dXJuIGJvZHk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgRENQYXJhbSBleHRlbmRzIERDQmxvY2tUYWcgaW1wbGVtZW50cyBQYXJhbVRyZWUgewogICAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzVHlwZVBhcmFtZXRlcjsKICAgICAgICBwdWJsaWMgZmluYWwgRENJZGVudGlmaWVyIG5hbWU7CiAgICAgICAgcHVibGljIGZpbmFsIExpc3Q8RENUcmVlPiBkZXNjcmlwdGlvbjsKCiAgICAgICAgRENQYXJhbShib29sZWFuIGlzVHlwZVBhcmFtZXRlciwgRENJZGVudGlmaWVyIG5hbWUsIExpc3Q8RENUcmVlPiBkZXNjcmlwdGlvbikgewogICAgICAgICAgICB0aGlzLmlzVHlwZVBhcmFtZXRlciA9IGlzVHlwZVBhcmFtZXRlcjsKICAgICAgICAgICAgdGhpcy5uYW1lID0gbmFtZTsKICAgICAgICAgICAgdGhpcy5kZXNjcmlwdGlvbiA9IGRlc2NyaXB0aW9uOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIEtpbmQgZ2V0S2luZCgpIHsKICAgICAgICAgICAgcmV0dXJuIEtpbmQuUEFSQU07CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgPFIsIEQ+IFIgYWNjZXB0KERvY1RyZWVWaXNpdG9yPFIsIEQ+IHYsIEQgZCkgewogICAgICAgICAgICByZXR1cm4gdi52aXNpdFBhcmFtKHRoaXMsIGQpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIGJvb2xlYW4gaXNUeXBlUGFyYW1ldGVyKCkgewogICAgICAgICAgICByZXR1cm4gaXNUeXBlUGFyYW1ldGVyOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIElkZW50aWZpZXJUcmVlIGdldE5hbWUoKSB7CiAgICAgICAgICAgIHJldHVybiBuYW1lOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIExpc3Q8PyBleHRlbmRzIERvY1RyZWU+IGdldERlc2NyaXB0aW9uKCkgewogICAgICAgICAgICByZXR1cm4gZGVzY3JpcHRpb247CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgRENQcm92aWRlcyBleHRlbmRzIERDQmxvY2tUYWcgaW1wbGVtZW50cyBQcm92aWRlc1RyZWUgewogICAgICAgIHB1YmxpYyBmaW5hbCBEQ1JlZmVyZW5jZSBzZXJ2aWNlVHlwZTsKICAgICAgICBwdWJsaWMgZmluYWwgTGlzdDxEQ1RyZWU+IGRlc2NyaXB0aW9uOwoKICAgICAgICBEQ1Byb3ZpZGVzKERDUmVmZXJlbmNlIHNlcnZpY2VUeXBlLCBMaXN0PERDVHJlZT4gZGVzY3JpcHRpb24pIHsKICAgICAgICAgICAgdGhpcy5zZXJ2aWNlVHlwZSA9IHNlcnZpY2VUeXBlOwogICAgICAgICAgICB0aGlzLmRlc2NyaXB0aW9uID0gZGVzY3JpcHRpb247CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgS2luZCBnZXRLaW5kKCkgewogICAgICAgICAgICByZXR1cm4gS2luZC5QUk9WSURFUzsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyA8UiwgRD4gUiBhY2NlcHQoRG9jVHJlZVZpc2l0b3I8UiwgRD4gdiwgRCBkKSB7CiAgICAgICAgICAgIHJldHVybiB2LnZpc2l0UHJvdmlkZXModGhpcywgZCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgUmVmZXJlbmNlVHJlZSBnZXRTZXJ2aWNlVHlwZSgpIHsKICAgICAgICAgICAgcmV0dXJuIHNlcnZpY2VUeXBlOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIExpc3Q8PyBleHRlbmRzIERvY1RyZWU+IGdldERlc2NyaXB0aW9uKCkgewogICAgICAgICAgICByZXR1cm4gZGVzY3JpcHRpb247CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgRENSZWZlcmVuY2UgZXh0ZW5kcyBEQ0VuZFBvc1RyZWU8RENSZWZlcmVuY2U+IGltcGxlbWVudHMgUmVmZXJlbmNlVHJlZSB7CiAgICAgICAgcHVibGljIGZpbmFsIFN0cmluZyBzaWduYXR1cmU7CgogICAgICAgIC8vIFRoZSBmb2xsb3dpbmcgYXJlIG5vdCBkaXJlY3RseSBleHBvc2VkIHRocm91Z2ggUmVmZXJlbmNlVHJlZQogICAgICAgIC8vIHVzZSBEb2NUcmVlcy5nZXRFbGVtZW50KERvY1RyZWVQYXRoKQogICAgICAgIHB1YmxpYyBmaW5hbCBKQ1RyZWUgcXVhbGlmaWVyRXhwcmVzc2lvbjsKICAgICAgICBwdWJsaWMgZmluYWwgTmFtZSBtZW1iZXJOYW1lOwogICAgICAgIHB1YmxpYyBmaW5hbCBMaXN0PEpDVHJlZT4gcGFyYW1UeXBlczsKCgogICAgICAgIERDUmVmZXJlbmNlKFN0cmluZyBzaWduYXR1cmUsIEpDVHJlZSBxdWFsRXhwciwgTmFtZSBtZW1iZXIsIExpc3Q8SkNUcmVlPiBwYXJhbVR5cGVzKSB7CiAgICAgICAgICAgIHRoaXMuc2lnbmF0dXJlID0gc2lnbmF0dXJlOwogICAgICAgICAgICBxdWFsaWZpZXJFeHByZXNzaW9uID0gcXVhbEV4cHI7CiAgICAgICAgICAgIG1lbWJlck5hbWUgPSBtZW1iZXI7CiAgICAgICAgICAgIHRoaXMucGFyYW1UeXBlcyA9IHBhcmFtVHlwZXM7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgS2luZCBnZXRLaW5kKCkgewogICAgICAgICAgICByZXR1cm4gS2luZC5SRUZFUkVOQ0U7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgPFIsIEQ+IFIgYWNjZXB0KERvY1RyZWVWaXNpdG9yPFIsIEQ+IHYsIEQgZCkgewogICAgICAgICAgICByZXR1cm4gdi52aXNpdFJlZmVyZW5jZSh0aGlzLCBkKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0U2lnbmF0dXJlKCkgewogICAgICAgICAgICByZXR1cm4gc2lnbmF0dXJlOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIERDUmV0dXJuIGV4dGVuZHMgRENCbG9ja1RhZyBpbXBsZW1lbnRzIFJldHVyblRyZWUgewogICAgICAgIHB1YmxpYyBmaW5hbCBMaXN0PERDVHJlZT4gZGVzY3JpcHRpb247CgogICAgICAgIERDUmV0dXJuKExpc3Q8RENUcmVlPiBkZXNjcmlwdGlvbikgewogICAgICAgICAgICB0aGlzLmRlc2NyaXB0aW9uID0gZGVzY3JpcHRpb247CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgS2luZCBnZXRLaW5kKCkgewogICAgICAgICAgICByZXR1cm4gS2luZC5SRVRVUk47CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgPFIsIEQ+IFIgYWNjZXB0KERvY1RyZWVWaXNpdG9yPFIsIEQ+IHYsIEQgZCkgewogICAgICAgICAgICByZXR1cm4gdi52aXNpdFJldHVybih0aGlzLCBkKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBMaXN0PD8gZXh0ZW5kcyBEb2NUcmVlPiBnZXREZXNjcmlwdGlvbigpIHsKICAgICAgICAgICAgcmV0dXJuIGRlc2NyaXB0aW9uOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIERDU2VlIGV4dGVuZHMgRENCbG9ja1RhZyBpbXBsZW1lbnRzIFNlZVRyZWUgewogICAgICAgIHB1YmxpYyBmaW5hbCBMaXN0PERDVHJlZT4gcmVmZXJlbmNlOwoKICAgICAgICBEQ1NlZShMaXN0PERDVHJlZT4gcmVmZXJlbmNlKSB7CiAgICAgICAgICAgIHRoaXMucmVmZXJlbmNlID0gcmVmZXJlbmNlOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIEtpbmQgZ2V0S2luZCgpIHsKICAgICAgICAgICAgcmV0dXJuIEtpbmQuU0VFOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIDxSLCBEPiBSIGFjY2VwdChEb2NUcmVlVmlzaXRvcjxSLCBEPiB2LCBEIGQpIHsKICAgICAgICAgICAgcmV0dXJuIHYudmlzaXRTZWUodGhpcywgZCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgTGlzdDw/IGV4dGVuZHMgRG9jVHJlZT4gZ2V0UmVmZXJlbmNlKCkgewogICAgICAgICAgICByZXR1cm4gcmVmZXJlbmNlOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIERDU2VyaWFsIGV4dGVuZHMgRENCbG9ja1RhZyBpbXBsZW1lbnRzIFNlcmlhbFRyZWUgewogICAgICAgIHB1YmxpYyBmaW5hbCBMaXN0PERDVHJlZT4gZGVzY3JpcHRpb247CgogICAgICAgIERDU2VyaWFsKExpc3Q8RENUcmVlPiBkZXNjcmlwdGlvbikgewogICAgICAgICAgICB0aGlzLmRlc2NyaXB0aW9uID0gZGVzY3JpcHRpb247CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgS2luZCBnZXRLaW5kKCkgewogICAgICAgICAgICByZXR1cm4gS2luZC5TRVJJQUw7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgPFIsIEQ+IFIgYWNjZXB0KERvY1RyZWVWaXNpdG9yPFIsIEQ+IHYsIEQgZCkgewogICAgICAgICAgICByZXR1cm4gdi52aXNpdFNlcmlhbCh0aGlzLCBkKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBMaXN0PD8gZXh0ZW5kcyBEb2NUcmVlPiBnZXREZXNjcmlwdGlvbigpIHsKICAgICAgICAgICAgcmV0dXJuIGRlc2NyaXB0aW9uOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIERDU2VyaWFsRGF0YSBleHRlbmRzIERDQmxvY2tUYWcgaW1wbGVtZW50cyBTZXJpYWxEYXRhVHJlZSB7CiAgICAgICAgcHVibGljIGZpbmFsIExpc3Q8RENUcmVlPiBkZXNjcmlwdGlvbjsKCiAgICAgICAgRENTZXJpYWxEYXRhKExpc3Q8RENUcmVlPiBkZXNjcmlwdGlvbikgewogICAgICAgICAgICB0aGlzLmRlc2NyaXB0aW9uID0gZGVzY3JpcHRpb247CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgS2luZCBnZXRLaW5kKCkgewogICAgICAgICAgICByZXR1cm4gS2luZC5TRVJJQUxfREFUQTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyA8UiwgRD4gUiBhY2NlcHQoRG9jVHJlZVZpc2l0b3I8UiwgRD4gdiwgRCBkKSB7CiAgICAgICAgICAgIHJldHVybiB2LnZpc2l0U2VyaWFsRGF0YSh0aGlzLCBkKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBMaXN0PD8gZXh0ZW5kcyBEb2NUcmVlPiBnZXREZXNjcmlwdGlvbigpIHsKICAgICAgICAgICAgcmV0dXJuIGRlc2NyaXB0aW9uOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIERDU2VyaWFsRmllbGQgZXh0ZW5kcyBEQ0Jsb2NrVGFnIGltcGxlbWVudHMgU2VyaWFsRmllbGRUcmVlIHsKICAgICAgICBwdWJsaWMgZmluYWwgRENJZGVudGlmaWVyIG5hbWU7CiAgICAgICAgcHVibGljIGZpbmFsIERDUmVmZXJlbmNlIHR5cGU7CiAgICAgICAgcHVibGljIGZpbmFsIExpc3Q8RENUcmVlPiBkZXNjcmlwdGlvbjsKCiAgICAgICAgRENTZXJpYWxGaWVsZChEQ0lkZW50aWZpZXIgbmFtZSwgRENSZWZlcmVuY2UgdHlwZSwgTGlzdDxEQ1RyZWU+IGRlc2NyaXB0aW9uKSB7CiAgICAgICAgICAgIHRoaXMuZGVzY3JpcHRpb24gPSBkZXNjcmlwdGlvbjsKICAgICAgICAgICAgdGhpcy5uYW1lID0gbmFtZTsKICAgICAgICAgICAgdGhpcy50eXBlID0gdHlwZTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBLaW5kIGdldEtpbmQoKSB7CiAgICAgICAgICAgIHJldHVybiBLaW5kLlNFUklBTF9GSUVMRDsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyA8UiwgRD4gUiBhY2NlcHQoRG9jVHJlZVZpc2l0b3I8UiwgRD4gdiwgRCBkKSB7CiAgICAgICAgICAgIHJldHVybiB2LnZpc2l0U2VyaWFsRmllbGQodGhpcywgZCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgTGlzdDw/IGV4dGVuZHMgRG9jVHJlZT4gZ2V0RGVzY3JpcHRpb24oKSB7CiAgICAgICAgICAgIHJldHVybiBkZXNjcmlwdGlvbjsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBJZGVudGlmaWVyVHJlZSBnZXROYW1lKCkgewogICAgICAgICAgICByZXR1cm4gbmFtZTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBSZWZlcmVuY2VUcmVlIGdldFR5cGUoKSB7CiAgICAgICAgICAgIHJldHVybiB0eXBlOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIERDU2luY2UgZXh0ZW5kcyBEQ0Jsb2NrVGFnIGltcGxlbWVudHMgU2luY2VUcmVlIHsKICAgICAgICBwdWJsaWMgZmluYWwgTGlzdDxEQ1RyZWU+IGJvZHk7CgogICAgICAgIERDU2luY2UoTGlzdDxEQ1RyZWU+IGJvZHkpIHsKICAgICAgICAgICAgdGhpcy5ib2R5ID0gYm9keTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBLaW5kIGdldEtpbmQoKSB7CiAgICAgICAgICAgIHJldHVybiBLaW5kLlNJTkNFOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIDxSLCBEPiBSIGFjY2VwdChEb2NUcmVlVmlzaXRvcjxSLCBEPiB2LCBEIGQpIHsKICAgICAgICAgICAgcmV0dXJuIHYudmlzaXRTaW5jZSh0aGlzLCBkKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBMaXN0PD8gZXh0ZW5kcyBEb2NUcmVlPiBnZXRCb2R5KCkgewogICAgICAgICAgICByZXR1cm4gYm9keTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjbGFzcyBEQ1N0YXJ0RWxlbWVudCBleHRlbmRzIERDRW5kUG9zVHJlZTxEQ1N0YXJ0RWxlbWVudD4gaW1wbGVtZW50cyBTdGFydEVsZW1lbnRUcmVlIHsKICAgICAgICBwdWJsaWMgZmluYWwgTmFtZSBuYW1lOwogICAgICAgIHB1YmxpYyBmaW5hbCBMaXN0PERDVHJlZT4gYXR0cnM7CiAgICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gc2VsZkNsb3Npbmc7CgogICAgICAgIERDU3RhcnRFbGVtZW50KE5hbWUgbmFtZSwgTGlzdDxEQ1RyZWU+IGF0dHJzLCBib29sZWFuIHNlbGZDbG9zaW5nKSB7CiAgICAgICAgICAgIHRoaXMubmFtZSA9IG5hbWU7CiAgICAgICAgICAgIHRoaXMuYXR0cnMgPSBhdHRyczsKICAgICAgICAgICAgdGhpcy5zZWxmQ2xvc2luZyA9IHNlbGZDbG9zaW5nOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIEtpbmQgZ2V0S2luZCgpIHsKICAgICAgICAgICAgcmV0dXJuIEtpbmQuU1RBUlRfRUxFTUVOVDsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyA8UiwgRD4gUiBhY2NlcHQoRG9jVHJlZVZpc2l0b3I8UiwgRD4gdiwgRCBkKSB7CiAgICAgICAgICAgIHJldHVybiB2LnZpc2l0U3RhcnRFbGVtZW50KHRoaXMsIGQpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIE5hbWUgZ2V0TmFtZSgpIHsKICAgICAgICAgICAgcmV0dXJuIG5hbWU7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgTGlzdDw/IGV4dGVuZHMgRG9jVHJlZT4gZ2V0QXR0cmlidXRlcygpIHsKICAgICAgICAgICAgcmV0dXJuIGF0dHJzOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIGJvb2xlYW4gaXNTZWxmQ2xvc2luZygpIHsKICAgICAgICAgICAgcmV0dXJuIHNlbGZDbG9zaW5nOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIERDVGV4dCBleHRlbmRzIERDVHJlZSBpbXBsZW1lbnRzIFRleHRUcmVlIHsKICAgICAgICBwdWJsaWMgZmluYWwgU3RyaW5nIHRleHQ7CgogICAgICAgIERDVGV4dChTdHJpbmcgdGV4dCkgewogICAgICAgICAgICB0aGlzLnRleHQgPSB0ZXh0OwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIEtpbmQgZ2V0S2luZCgpIHsKICAgICAgICAgICAgcmV0dXJuIEtpbmQuVEVYVDsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyA8UiwgRD4gUiBhY2NlcHQoRG9jVHJlZVZpc2l0b3I8UiwgRD4gdiwgRCBkKSB7CiAgICAgICAgICAgIHJldHVybiB2LnZpc2l0VGV4dCh0aGlzLCBkKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0Qm9keSgpIHsKICAgICAgICAgICAgcmV0dXJuIHRleHQ7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgRENUaHJvd3MgZXh0ZW5kcyBEQ0Jsb2NrVGFnIGltcGxlbWVudHMgVGhyb3dzVHJlZSB7CiAgICAgICAgcHVibGljIGZpbmFsIEtpbmQga2luZDsKICAgICAgICBwdWJsaWMgZmluYWwgRENSZWZlcmVuY2UgbmFtZTsKICAgICAgICBwdWJsaWMgZmluYWwgTGlzdDxEQ1RyZWU+IGRlc2NyaXB0aW9uOwoKICAgICAgICBEQ1Rocm93cyhLaW5kIGtpbmQsIERDUmVmZXJlbmNlIG5hbWUsIExpc3Q8RENUcmVlPiBkZXNjcmlwdGlvbikgewogICAgICAgICAgICBBc3NlcnQuY2hlY2soa2luZCA9PSBLaW5kLkVYQ0VQVElPTiB8fCBraW5kID09IEtpbmQuVEhST1dTKTsKICAgICAgICAgICAgdGhpcy5raW5kID0ga2luZDsKICAgICAgICAgICAgdGhpcy5uYW1lID0gbmFtZTsKICAgICAgICAgICAgdGhpcy5kZXNjcmlwdGlvbiA9IGRlc2NyaXB0aW9uOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIEtpbmQgZ2V0S2luZCgpIHsKICAgICAgICAgICAgcmV0dXJuIGtpbmQ7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgPFIsIEQ+IFIgYWNjZXB0KERvY1RyZWVWaXNpdG9yPFIsIEQ+IHYsIEQgZCkgewogICAgICAgICAgICByZXR1cm4gdi52aXNpdFRocm93cyh0aGlzLCBkKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBSZWZlcmVuY2VUcmVlIGdldEV4Y2VwdGlvbk5hbWUoKSB7CiAgICAgICAgICAgIHJldHVybiBuYW1lOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIExpc3Q8PyBleHRlbmRzIERvY1RyZWU+IGdldERlc2NyaXB0aW9uKCkgewogICAgICAgICAgICByZXR1cm4gZGVzY3JpcHRpb247CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgRENVbmtub3duQmxvY2tUYWcgZXh0ZW5kcyBEQ0Jsb2NrVGFnIGltcGxlbWVudHMgVW5rbm93bkJsb2NrVGFnVHJlZSB7CiAgICAgICAgcHVibGljIGZpbmFsIE5hbWUgbmFtZTsKICAgICAgICBwdWJsaWMgZmluYWwgTGlzdDxEQ1RyZWU+IGNvbnRlbnQ7CgogICAgICAgIERDVW5rbm93bkJsb2NrVGFnKE5hbWUgbmFtZSwgTGlzdDxEQ1RyZWU+IGNvbnRlbnQpIHsKICAgICAgICAgICAgdGhpcy5uYW1lID0gbmFtZTsKICAgICAgICAgICAgdGhpcy5jb250ZW50ID0gY29udGVudDsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBLaW5kIGdldEtpbmQoKSB7CiAgICAgICAgICAgIHJldHVybiBLaW5kLlVOS05PV05fQkxPQ0tfVEFHOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIDxSLCBEPiBSIGFjY2VwdChEb2NUcmVlVmlzaXRvcjxSLCBEPiB2LCBEIGQpIHsKICAgICAgICAgICAgcmV0dXJuIHYudmlzaXRVbmtub3duQmxvY2tUYWcodGhpcywgZCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgU3RyaW5nIGdldFRhZ05hbWUoKSB7CiAgICAgICAgICAgIHJldHVybiBuYW1lLnRvU3RyaW5nKCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgTGlzdDw/IGV4dGVuZHMgRG9jVHJlZT4gZ2V0Q29udGVudCgpIHsKICAgICAgICAgICAgcmV0dXJuIGNvbnRlbnQ7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgRENVbmtub3duSW5saW5lVGFnIGV4dGVuZHMgRENJbmxpbmVUYWcgaW1wbGVtZW50cyBVbmtub3duSW5saW5lVGFnVHJlZSB7CiAgICAgICAgcHVibGljIGZpbmFsIE5hbWUgbmFtZTsKICAgICAgICBwdWJsaWMgZmluYWwgTGlzdDxEQ1RyZWU+IGNvbnRlbnQ7CgogICAgICAgIERDVW5rbm93bklubGluZVRhZyhOYW1lIG5hbWUsIExpc3Q8RENUcmVlPiBjb250ZW50KSB7CiAgICAgICAgICAgIHRoaXMubmFtZSA9IG5hbWU7CiAgICAgICAgICAgIHRoaXMuY29udGVudCA9IGNvbnRlbnQ7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgS2luZCBnZXRLaW5kKCkgewogICAgICAgICAgICByZXR1cm4gS2luZC5VTktOT1dOX0lOTElORV9UQUc7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgPFIsIEQ+IFIgYWNjZXB0KERvY1RyZWVWaXNpdG9yPFIsIEQ+IHYsIEQgZCkgewogICAgICAgICAgICByZXR1cm4gdi52aXNpdFVua25vd25JbmxpbmVUYWcodGhpcywgZCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgU3RyaW5nIGdldFRhZ05hbWUoKSB7CiAgICAgICAgICAgIHJldHVybiBuYW1lLnRvU3RyaW5nKCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgTGlzdDw/IGV4dGVuZHMgRG9jVHJlZT4gZ2V0Q29udGVudCgpIHsKICAgICAgICAgICAgcmV0dXJuIGNvbnRlbnQ7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgRENVc2VzIGV4dGVuZHMgRENCbG9ja1RhZyBpbXBsZW1lbnRzIFVzZXNUcmVlIHsKICAgICAgICBwdWJsaWMgZmluYWwgRENSZWZlcmVuY2Ugc2VydmljZVR5cGU7CiAgICAgICAgcHVibGljIGZpbmFsIExpc3Q8RENUcmVlPiBkZXNjcmlwdGlvbjsKCiAgICAgICAgRENVc2VzKERDUmVmZXJlbmNlIHNlcnZpY2VUeXBlLCBMaXN0PERDVHJlZT4gZGVzY3JpcHRpb24pIHsKICAgICAgICAgICAgdGhpcy5zZXJ2aWNlVHlwZSA9IHNlcnZpY2VUeXBlOwogICAgICAgICAgICB0aGlzLmRlc2NyaXB0aW9uID0gZGVzY3JpcHRpb247CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgS2luZCBnZXRLaW5kKCkgewogICAgICAgICAgICByZXR1cm4gS2luZC5VU0VTOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIDxSLCBEPiBSIGFjY2VwdChEb2NUcmVlVmlzaXRvcjxSLCBEPiB2LCBEIGQpIHsKICAgICAgICAgICAgcmV0dXJuIHYudmlzaXRVc2VzKHRoaXMsIGQpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIFJlZmVyZW5jZVRyZWUgZ2V0U2VydmljZVR5cGUoKSB7CiAgICAgICAgICAgIHJldHVybiBzZXJ2aWNlVHlwZTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBMaXN0PD8gZXh0ZW5kcyBEb2NUcmVlPiBnZXREZXNjcmlwdGlvbigpIHsKICAgICAgICAgICAgcmV0dXJuIGRlc2NyaXB0aW9uOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIERDVmFsdWUgZXh0ZW5kcyBEQ0lubGluZVRhZyBpbXBsZW1lbnRzIFZhbHVlVHJlZSB7CiAgICAgICAgcHVibGljIGZpbmFsIERDUmVmZXJlbmNlIHJlZjsKCiAgICAgICAgRENWYWx1ZShEQ1JlZmVyZW5jZSByZWYpIHsKICAgICAgICAgICAgdGhpcy5yZWYgPSByZWY7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgS2luZCBnZXRLaW5kKCkgewogICAgICAgICAgICByZXR1cm4gS2luZC5WQUxVRTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyA8UiwgRD4gUiBhY2NlcHQoRG9jVHJlZVZpc2l0b3I8UiwgRD4gdiwgRCBkKSB7CiAgICAgICAgICAgIHJldHVybiB2LnZpc2l0VmFsdWUodGhpcywgZCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgUmVmZXJlbmNlVHJlZSBnZXRSZWZlcmVuY2UoKSB7CiAgICAgICAgICAgIHJldHVybiByZWY7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgRENWZXJzaW9uIGV4dGVuZHMgRENCbG9ja1RhZyBpbXBsZW1lbnRzIFZlcnNpb25UcmVlIHsKICAgICAgICBwdWJsaWMgZmluYWwgTGlzdDxEQ1RyZWU+IGJvZHk7CgogICAgICAgIERDVmVyc2lvbihMaXN0PERDVHJlZT4gYm9keSkgewogICAgICAgICAgICB0aGlzLmJvZHkgPSBib2R5OwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIEtpbmQgZ2V0S2luZCgpIHsKICAgICAgICAgICAgcmV0dXJuIEtpbmQuVkVSU0lPTjsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyA8UiwgRD4gUiBhY2NlcHQoRG9jVHJlZVZpc2l0b3I8UiwgRD4gdiwgRCBkKSB7CiAgICAgICAgICAgIHJldHVybiB2LnZpc2l0VmVyc2lvbih0aGlzLCBkKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBMaXN0PD8gZXh0ZW5kcyBEb2NUcmVlPiBnZXRCb2R5KCkgewogICAgICAgICAgICByZXR1cm4gYm9keTsKICAgICAgICB9CiAgICB9Cgp9ClBLAwQKAAAIAADSfU1KLP9kM/g1AAD4NQAALAAAAGNvbS9zdW4vdG9vbHMvamF2YWMvdHJlZS9UcmVlVHJhbnNsYXRvci5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAxOTk5LCAyMDE0LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuamF2YWMudHJlZTsKCmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuKjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5KQ1RyZWUuKjsKCi8qKiBBIHN1YmNsYXNzIG9mIFRyZWUuVmlzaXRvciwgdGhpcyBjbGFzcyBkZWZpbmVzCiAqICBhIGdlbmVyYWwgdHJlZSB0cmFuc2xhdG9yIHBhdHRlcm4uIFRyYW5zbGF0aW9uIHByb2NlZWRzIHJlY3Vyc2l2ZWx5IGluCiAqICBsZWZ0LXRvLXJpZ2h0IG9yZGVyIGRvd24gYSB0cmVlLCBjb25zdHJ1Y3RpbmcgdHJhbnNsYXRlZCBub2RlcyBieQogKiAgb3ZlcndyaXRpbmcgZXhpc3Rpbmcgb25lcy4gVGhlcmUgaXMgb25lIHZpc2l0b3IgbWV0aG9kIGluIHRoaXMgY2xhc3MKICogIGZvciBldmVyeSBwb3NzaWJsZSBraW5kIG9mIHRyZWUgbm9kZS4gIFRvIG9idGFpbiBhIHNwZWNpZmljCiAqICB0cmFuc2xhdG9yLCBpdCBzdWZmaWNlcyB0byBvdmVycmlkZSB0aG9zZSB2aXNpdG9yIG1ldGhvZHMgd2hpY2gKICogIGRvIHNvbWUgaW50ZXJlc3Rpbmcgd29yay4gVGhlIHRyYW5zbGF0b3IgY2xhc3MgaXRzZWxmIHRha2VzIGNhcmUgb2YgYWxsCiAqICBuYXZpZ2F0aW9uYWwgYXNwZWN0cy4KICoKICogIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqICBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqICBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogKiAgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPgogKi8KcHVibGljIGNsYXNzIFRyZWVUcmFuc2xhdG9yIGV4dGVuZHMgSkNUcmVlLlZpc2l0b3IgewoKICAgIC8qKiBWaXNpdG9yIHJlc3VsdCBmaWVsZDogYSB0cmVlCiAgICAgKi8KICAgIHByb3RlY3RlZCBKQ1RyZWUgcmVzdWx0OwoKICAgIC8qKiBWaXNpdG9yIG1ldGhvZDogVHJhbnNsYXRlIGEgc2luZ2xlIG5vZGUuCiAgICAgKi8KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQogICAgcHVibGljIDxUIGV4dGVuZHMgSkNUcmVlPiBUIHRyYW5zbGF0ZShUIHRyZWUpIHsKICAgICAgICBpZiAodHJlZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHRyZWUuYWNjZXB0KHRoaXMpOwogICAgICAgICAgICBKQ1RyZWUgdG1wUmVzdWx0ID0gdGhpcy5yZXN1bHQ7CiAgICAgICAgICAgIHRoaXMucmVzdWx0ID0gbnVsbDsKICAgICAgICAgICAgcmV0dXJuIChUKXRtcFJlc3VsdDsgLy8gWFhYIGNhc3QKICAgICAgICB9CiAgICB9CgogICAgLyoqIFZpc2l0b3IgbWV0aG9kOiB0cmFuc2xhdGUgYSBsaXN0IG9mIG5vZGVzLgogICAgICovCiAgICBwdWJsaWMgPFQgZXh0ZW5kcyBKQ1RyZWU+IExpc3Q8VD4gdHJhbnNsYXRlKExpc3Q8VD4gdHJlZXMpIHsKICAgICAgICBpZiAodHJlZXMgPT0gbnVsbCkgcmV0dXJuIG51bGw7CiAgICAgICAgZm9yIChMaXN0PFQ+IGwgPSB0cmVlczsgbC5ub25FbXB0eSgpOyBsID0gbC50YWlsKQogICAgICAgICAgICBsLmhlYWQgPSB0cmFuc2xhdGUobC5oZWFkKTsKICAgICAgICByZXR1cm4gdHJlZXM7CiAgICB9CgogICAgLyoqICBWaXNpdG9yIG1ldGhvZDogdHJhbnNsYXRlIGEgbGlzdCBvZiB2YXJpYWJsZSBkZWZpbml0aW9ucy4KICAgICAqLwogICAgcHVibGljIExpc3Q8SkNWYXJpYWJsZURlY2w+IHRyYW5zbGF0ZVZhckRlZnMoTGlzdDxKQ1ZhcmlhYmxlRGVjbD4gdHJlZXMpIHsKICAgICAgICBmb3IgKExpc3Q8SkNWYXJpYWJsZURlY2w+IGwgPSB0cmVlczsgbC5ub25FbXB0eSgpOyBsID0gbC50YWlsKQogICAgICAgICAgICBsLmhlYWQgPSB0cmFuc2xhdGUobC5oZWFkKTsKICAgICAgICByZXR1cm4gdHJlZXM7CiAgICB9CgogICAgLyoqICBWaXNpdG9yIG1ldGhvZDogdHJhbnNsYXRlIGEgbGlzdCBvZiB0eXBlIHBhcmFtZXRlcnMuCiAgICAgKi8KICAgIHB1YmxpYyBMaXN0PEpDVHlwZVBhcmFtZXRlcj4gdHJhbnNsYXRlVHlwZVBhcmFtcyhMaXN0PEpDVHlwZVBhcmFtZXRlcj4gdHJlZXMpIHsKICAgICAgICBmb3IgKExpc3Q8SkNUeXBlUGFyYW1ldGVyPiBsID0gdHJlZXM7IGwubm9uRW1wdHkoKTsgbCA9IGwudGFpbCkKICAgICAgICAgICAgbC5oZWFkID0gdHJhbnNsYXRlKGwuaGVhZCk7CiAgICAgICAgcmV0dXJuIHRyZWVzOwogICAgfQoKICAgIC8qKiAgVmlzaXRvciBtZXRob2Q6IHRyYW5zbGF0ZSBhIGxpc3Qgb2YgY2FzZSBwYXJ0cyBvZiBzd2l0Y2ggc3RhdGVtZW50cy4KICAgICAqLwogICAgcHVibGljIExpc3Q8SkNDYXNlPiB0cmFuc2xhdGVDYXNlcyhMaXN0PEpDQ2FzZT4gdHJlZXMpIHsKICAgICAgICBmb3IgKExpc3Q8SkNDYXNlPiBsID0gdHJlZXM7IGwubm9uRW1wdHkoKTsgbCA9IGwudGFpbCkKICAgICAgICAgICAgbC5oZWFkID0gdHJhbnNsYXRlKGwuaGVhZCk7CiAgICAgICAgcmV0dXJuIHRyZWVzOwogICAgfQoKICAgIC8qKiAgVmlzaXRvciBtZXRob2Q6IHRyYW5zbGF0ZSBhIGxpc3Qgb2YgY2F0Y2ggY2xhdXNlcyBpbiB0cnkgc3RhdGVtZW50cy4KICAgICAqLwogICAgcHVibGljIExpc3Q8SkNDYXRjaD4gdHJhbnNsYXRlQ2F0Y2hlcnMoTGlzdDxKQ0NhdGNoPiB0cmVlcykgewogICAgICAgIGZvciAoTGlzdDxKQ0NhdGNoPiBsID0gdHJlZXM7IGwubm9uRW1wdHkoKTsgbCA9IGwudGFpbCkKICAgICAgICAgICAgbC5oZWFkID0gdHJhbnNsYXRlKGwuaGVhZCk7CiAgICAgICAgcmV0dXJuIHRyZWVzOwogICAgfQoKICAgIC8qKiAgVmlzaXRvciBtZXRob2Q6IHRyYW5zbGF0ZSBhIGxpc3Qgb2YgY2F0Y2ggY2xhdXNlcyBpbiB0cnkgc3RhdGVtZW50cy4KICAgICAqLwogICAgcHVibGljIExpc3Q8SkNBbm5vdGF0aW9uPiB0cmFuc2xhdGVBbm5vdGF0aW9ucyhMaXN0PEpDQW5ub3RhdGlvbj4gdHJlZXMpIHsKICAgICAgICBmb3IgKExpc3Q8SkNBbm5vdGF0aW9uPiBsID0gdHJlZXM7IGwubm9uRW1wdHkoKTsgbCA9IGwudGFpbCkKICAgICAgICAgICAgbC5oZWFkID0gdHJhbnNsYXRlKGwuaGVhZCk7CiAgICAgICAgcmV0dXJuIHRyZWVzOwogICAgfQoKLyogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFZpc2l0b3IgbWV0aG9kcwogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiAgICBwdWJsaWMgdm9pZCB2aXNpdFRvcExldmVsKEpDQ29tcGlsYXRpb25Vbml0IHRyZWUpIHsKICAgICAgICB0cmVlLmRlZnMgPSB0cmFuc2xhdGUodHJlZS5kZWZzKTsKICAgICAgICByZXN1bHQgPSB0cmVlOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0UGFja2FnZURlZihKQ1BhY2thZ2VEZWNsIHRyZWUpIHsKICAgICAgICB0cmVlLmFubm90YXRpb25zID0gdHJhbnNsYXRlKHRyZWUuYW5ub3RhdGlvbnMpOwogICAgICAgIHRyZWUucGlkID0gdHJhbnNsYXRlKHRyZWUucGlkKTsKICAgICAgICByZXN1bHQgPSB0cmVlOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0SW1wb3J0KEpDSW1wb3J0IHRyZWUpIHsKICAgICAgICB0cmVlLnF1YWxpZCA9IHRyYW5zbGF0ZSh0cmVlLnF1YWxpZCk7CiAgICAgICAgcmVzdWx0ID0gdHJlZTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdENsYXNzRGVmKEpDQ2xhc3NEZWNsIHRyZWUpIHsKICAgICAgICB0cmVlLm1vZHMgPSB0cmFuc2xhdGUodHJlZS5tb2RzKTsKICAgICAgICB0cmVlLnR5cGFyYW1zID0gdHJhbnNsYXRlVHlwZVBhcmFtcyh0cmVlLnR5cGFyYW1zKTsKICAgICAgICB0cmVlLmV4dGVuZGluZyA9IHRyYW5zbGF0ZSh0cmVlLmV4dGVuZGluZyk7CiAgICAgICAgdHJlZS5pbXBsZW1lbnRpbmcgPSB0cmFuc2xhdGUodHJlZS5pbXBsZW1lbnRpbmcpOwogICAgICAgIHRyZWUuZGVmcyA9IHRyYW5zbGF0ZSh0cmVlLmRlZnMpOwogICAgICAgIHJlc3VsdCA9IHRyZWU7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRNZXRob2REZWYoSkNNZXRob2REZWNsIHRyZWUpIHsKICAgICAgICB0cmVlLm1vZHMgPSB0cmFuc2xhdGUodHJlZS5tb2RzKTsKICAgICAgICB0cmVlLnJlc3R5cGUgPSB0cmFuc2xhdGUodHJlZS5yZXN0eXBlKTsKICAgICAgICB0cmVlLnR5cGFyYW1zID0gdHJhbnNsYXRlVHlwZVBhcmFtcyh0cmVlLnR5cGFyYW1zKTsKICAgICAgICB0cmVlLnJlY3ZwYXJhbSA9IHRyYW5zbGF0ZSh0cmVlLnJlY3ZwYXJhbSk7CiAgICAgICAgdHJlZS5wYXJhbXMgPSB0cmFuc2xhdGVWYXJEZWZzKHRyZWUucGFyYW1zKTsKICAgICAgICB0cmVlLnRocm93biA9IHRyYW5zbGF0ZSh0cmVlLnRocm93bik7CiAgICAgICAgdHJlZS5ib2R5ID0gdHJhbnNsYXRlKHRyZWUuYm9keSk7CiAgICAgICAgcmVzdWx0ID0gdHJlZTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdFZhckRlZihKQ1ZhcmlhYmxlRGVjbCB0cmVlKSB7CiAgICAgICAgdHJlZS5tb2RzID0gdHJhbnNsYXRlKHRyZWUubW9kcyk7CiAgICAgICAgdHJlZS5uYW1lZXhwciA9IHRyYW5zbGF0ZSh0cmVlLm5hbWVleHByKTsKICAgICAgICB0cmVlLnZhcnR5cGUgPSB0cmFuc2xhdGUodHJlZS52YXJ0eXBlKTsKICAgICAgICB0cmVlLmluaXQgPSB0cmFuc2xhdGUodHJlZS5pbml0KTsKICAgICAgICByZXN1bHQgPSB0cmVlOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0U2tpcChKQ1NraXAgdHJlZSkgewogICAgICAgIHJlc3VsdCA9IHRyZWU7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRCbG9jayhKQ0Jsb2NrIHRyZWUpIHsKICAgICAgICB0cmVlLnN0YXRzID0gdHJhbnNsYXRlKHRyZWUuc3RhdHMpOwogICAgICAgIHJlc3VsdCA9IHRyZWU7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXREb0xvb3AoSkNEb1doaWxlTG9vcCB0cmVlKSB7CiAgICAgICAgdHJlZS5ib2R5ID0gdHJhbnNsYXRlKHRyZWUuYm9keSk7CiAgICAgICAgdHJlZS5jb25kID0gdHJhbnNsYXRlKHRyZWUuY29uZCk7CiAgICAgICAgcmVzdWx0ID0gdHJlZTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdFdoaWxlTG9vcChKQ1doaWxlTG9vcCB0cmVlKSB7CiAgICAgICAgdHJlZS5jb25kID0gdHJhbnNsYXRlKHRyZWUuY29uZCk7CiAgICAgICAgdHJlZS5ib2R5ID0gdHJhbnNsYXRlKHRyZWUuYm9keSk7CiAgICAgICAgcmVzdWx0ID0gdHJlZTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdEZvckxvb3AoSkNGb3JMb29wIHRyZWUpIHsKICAgICAgICB0cmVlLmluaXQgPSB0cmFuc2xhdGUodHJlZS5pbml0KTsKICAgICAgICB0cmVlLmNvbmQgPSB0cmFuc2xhdGUodHJlZS5jb25kKTsKICAgICAgICB0cmVlLnN0ZXAgPSB0cmFuc2xhdGUodHJlZS5zdGVwKTsKICAgICAgICB0cmVlLmJvZHkgPSB0cmFuc2xhdGUodHJlZS5ib2R5KTsKICAgICAgICByZXN1bHQgPSB0cmVlOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0Rm9yZWFjaExvb3AoSkNFbmhhbmNlZEZvckxvb3AgdHJlZSkgewogICAgICAgIHRyZWUudmFyID0gdHJhbnNsYXRlKHRyZWUudmFyKTsKICAgICAgICB0cmVlLmV4cHIgPSB0cmFuc2xhdGUodHJlZS5leHByKTsKICAgICAgICB0cmVlLmJvZHkgPSB0cmFuc2xhdGUodHJlZS5ib2R5KTsKICAgICAgICByZXN1bHQgPSB0cmVlOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0TGFiZWxsZWQoSkNMYWJlbGVkU3RhdGVtZW50IHRyZWUpIHsKICAgICAgICB0cmVlLmJvZHkgPSB0cmFuc2xhdGUodHJlZS5ib2R5KTsKICAgICAgICByZXN1bHQgPSB0cmVlOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0U3dpdGNoKEpDU3dpdGNoIHRyZWUpIHsKICAgICAgICB0cmVlLnNlbGVjdG9yID0gdHJhbnNsYXRlKHRyZWUuc2VsZWN0b3IpOwogICAgICAgIHRyZWUuY2FzZXMgPSB0cmFuc2xhdGVDYXNlcyh0cmVlLmNhc2VzKTsKICAgICAgICByZXN1bHQgPSB0cmVlOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0Q2FzZShKQ0Nhc2UgdHJlZSkgewogICAgICAgIHRyZWUucGF0ID0gdHJhbnNsYXRlKHRyZWUucGF0KTsKICAgICAgICB0cmVlLnN0YXRzID0gdHJhbnNsYXRlKHRyZWUuc3RhdHMpOwogICAgICAgIHJlc3VsdCA9IHRyZWU7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRTeW5jaHJvbml6ZWQoSkNTeW5jaHJvbml6ZWQgdHJlZSkgewogICAgICAgIHRyZWUubG9jayA9IHRyYW5zbGF0ZSh0cmVlLmxvY2spOwogICAgICAgIHRyZWUuYm9keSA9IHRyYW5zbGF0ZSh0cmVlLmJvZHkpOwogICAgICAgIHJlc3VsdCA9IHRyZWU7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRUcnkoSkNUcnkgdHJlZSkgewogICAgICAgIHRyZWUucmVzb3VyY2VzID0gdHJhbnNsYXRlKHRyZWUucmVzb3VyY2VzKTsKICAgICAgICB0cmVlLmJvZHkgPSB0cmFuc2xhdGUodHJlZS5ib2R5KTsKICAgICAgICB0cmVlLmNhdGNoZXJzID0gdHJhbnNsYXRlQ2F0Y2hlcnModHJlZS5jYXRjaGVycyk7CiAgICAgICAgdHJlZS5maW5hbGl6ZXIgPSB0cmFuc2xhdGUodHJlZS5maW5hbGl6ZXIpOwogICAgICAgIHJlc3VsdCA9IHRyZWU7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRDYXRjaChKQ0NhdGNoIHRyZWUpIHsKICAgICAgICB0cmVlLnBhcmFtID0gdHJhbnNsYXRlKHRyZWUucGFyYW0pOwogICAgICAgIHRyZWUuYm9keSA9IHRyYW5zbGF0ZSh0cmVlLmJvZHkpOwogICAgICAgIHJlc3VsdCA9IHRyZWU7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRDb25kaXRpb25hbChKQ0NvbmRpdGlvbmFsIHRyZWUpIHsKICAgICAgICB0cmVlLmNvbmQgPSB0cmFuc2xhdGUodHJlZS5jb25kKTsKICAgICAgICB0cmVlLnRydWVwYXJ0ID0gdHJhbnNsYXRlKHRyZWUudHJ1ZXBhcnQpOwogICAgICAgIHRyZWUuZmFsc2VwYXJ0ID0gdHJhbnNsYXRlKHRyZWUuZmFsc2VwYXJ0KTsKICAgICAgICByZXN1bHQgPSB0cmVlOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0SWYoSkNJZiB0cmVlKSB7CiAgICAgICAgdHJlZS5jb25kID0gdHJhbnNsYXRlKHRyZWUuY29uZCk7CiAgICAgICAgdHJlZS50aGVucGFydCA9IHRyYW5zbGF0ZSh0cmVlLnRoZW5wYXJ0KTsKICAgICAgICB0cmVlLmVsc2VwYXJ0ID0gdHJhbnNsYXRlKHRyZWUuZWxzZXBhcnQpOwogICAgICAgIHJlc3VsdCA9IHRyZWU7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRFeGVjKEpDRXhwcmVzc2lvblN0YXRlbWVudCB0cmVlKSB7CiAgICAgICAgdHJlZS5leHByID0gdHJhbnNsYXRlKHRyZWUuZXhwcik7CiAgICAgICAgcmVzdWx0ID0gdHJlZTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdEJyZWFrKEpDQnJlYWsgdHJlZSkgewogICAgICAgIHJlc3VsdCA9IHRyZWU7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRDb250aW51ZShKQ0NvbnRpbnVlIHRyZWUpIHsKICAgICAgICByZXN1bHQgPSB0cmVlOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0UmV0dXJuKEpDUmV0dXJuIHRyZWUpIHsKICAgICAgICB0cmVlLmV4cHIgPSB0cmFuc2xhdGUodHJlZS5leHByKTsKICAgICAgICByZXN1bHQgPSB0cmVlOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0VGhyb3coSkNUaHJvdyB0cmVlKSB7CiAgICAgICAgdHJlZS5leHByID0gdHJhbnNsYXRlKHRyZWUuZXhwcik7CiAgICAgICAgcmVzdWx0ID0gdHJlZTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdEFzc2VydChKQ0Fzc2VydCB0cmVlKSB7CiAgICAgICAgdHJlZS5jb25kID0gdHJhbnNsYXRlKHRyZWUuY29uZCk7CiAgICAgICAgdHJlZS5kZXRhaWwgPSB0cmFuc2xhdGUodHJlZS5kZXRhaWwpOwogICAgICAgIHJlc3VsdCA9IHRyZWU7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRBcHBseShKQ01ldGhvZEludm9jYXRpb24gdHJlZSkgewogICAgICAgIHRyZWUubWV0aCA9IHRyYW5zbGF0ZSh0cmVlLm1ldGgpOwogICAgICAgIHRyZWUuYXJncyA9IHRyYW5zbGF0ZSh0cmVlLmFyZ3MpOwogICAgICAgIHJlc3VsdCA9IHRyZWU7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXROZXdDbGFzcyhKQ05ld0NsYXNzIHRyZWUpIHsKICAgICAgICB0cmVlLmVuY2wgPSB0cmFuc2xhdGUodHJlZS5lbmNsKTsKICAgICAgICB0cmVlLmNsYXp6ID0gdHJhbnNsYXRlKHRyZWUuY2xhenopOwogICAgICAgIHRyZWUuYXJncyA9IHRyYW5zbGF0ZSh0cmVlLmFyZ3MpOwogICAgICAgIHRyZWUuZGVmID0gdHJhbnNsYXRlKHRyZWUuZGVmKTsKICAgICAgICByZXN1bHQgPSB0cmVlOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0TGFtYmRhKEpDTGFtYmRhIHRyZWUpIHsKICAgICAgICB0cmVlLnBhcmFtcyA9IHRyYW5zbGF0ZSh0cmVlLnBhcmFtcyk7CiAgICAgICAgdHJlZS5ib2R5ID0gdHJhbnNsYXRlKHRyZWUuYm9keSk7CiAgICAgICAgcmVzdWx0ID0gdHJlZTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdE5ld0FycmF5KEpDTmV3QXJyYXkgdHJlZSkgewogICAgICAgIHRyZWUuYW5ub3RhdGlvbnMgPSB0cmFuc2xhdGUodHJlZS5hbm5vdGF0aW9ucyk7CiAgICAgICAgTGlzdDxMaXN0PEpDQW5ub3RhdGlvbj4+IGRpbUFubm9zID0gTGlzdC5uaWwoKTsKICAgICAgICBmb3IgKExpc3Q8SkNBbm5vdGF0aW9uPiBvcmlnRGltQW5ub3MgOiB0cmVlLmRpbUFubm90YXRpb25zKQogICAgICAgICAgICBkaW1Bbm5vcyA9IGRpbUFubm9zLmFwcGVuZCh0cmFuc2xhdGUob3JpZ0RpbUFubm9zKSk7CiAgICAgICAgdHJlZS5kaW1Bbm5vdGF0aW9ucyA9IGRpbUFubm9zOwogICAgICAgIHRyZWUuZWxlbXR5cGUgPSB0cmFuc2xhdGUodHJlZS5lbGVtdHlwZSk7CiAgICAgICAgdHJlZS5kaW1zID0gdHJhbnNsYXRlKHRyZWUuZGltcyk7CiAgICAgICAgdHJlZS5lbGVtcyA9IHRyYW5zbGF0ZSh0cmVlLmVsZW1zKTsKICAgICAgICByZXN1bHQgPSB0cmVlOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0UGFyZW5zKEpDUGFyZW5zIHRyZWUpIHsKICAgICAgICB0cmVlLmV4cHIgPSB0cmFuc2xhdGUodHJlZS5leHByKTsKICAgICAgICByZXN1bHQgPSB0cmVlOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0QXNzaWduKEpDQXNzaWduIHRyZWUpIHsKICAgICAgICB0cmVlLmxocyA9IHRyYW5zbGF0ZSh0cmVlLmxocyk7CiAgICAgICAgdHJlZS5yaHMgPSB0cmFuc2xhdGUodHJlZS5yaHMpOwogICAgICAgIHJlc3VsdCA9IHRyZWU7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRBc3NpZ25vcChKQ0Fzc2lnbk9wIHRyZWUpIHsKICAgICAgICB0cmVlLmxocyA9IHRyYW5zbGF0ZSh0cmVlLmxocyk7CiAgICAgICAgdHJlZS5yaHMgPSB0cmFuc2xhdGUodHJlZS5yaHMpOwogICAgICAgIHJlc3VsdCA9IHRyZWU7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRVbmFyeShKQ1VuYXJ5IHRyZWUpIHsKICAgICAgICB0cmVlLmFyZyA9IHRyYW5zbGF0ZSh0cmVlLmFyZyk7CiAgICAgICAgcmVzdWx0ID0gdHJlZTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdEJpbmFyeShKQ0JpbmFyeSB0cmVlKSB7CiAgICAgICAgdHJlZS5saHMgPSB0cmFuc2xhdGUodHJlZS5saHMpOwogICAgICAgIHRyZWUucmhzID0gdHJhbnNsYXRlKHRyZWUucmhzKTsKICAgICAgICByZXN1bHQgPSB0cmVlOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0VHlwZUNhc3QoSkNUeXBlQ2FzdCB0cmVlKSB7CiAgICAgICAgdHJlZS5jbGF6eiA9IHRyYW5zbGF0ZSh0cmVlLmNsYXp6KTsKICAgICAgICB0cmVlLmV4cHIgPSB0cmFuc2xhdGUodHJlZS5leHByKTsKICAgICAgICByZXN1bHQgPSB0cmVlOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0VHlwZVRlc3QoSkNJbnN0YW5jZU9mIHRyZWUpIHsKICAgICAgICB0cmVlLmV4cHIgPSB0cmFuc2xhdGUodHJlZS5leHByKTsKICAgICAgICB0cmVlLmNsYXp6ID0gdHJhbnNsYXRlKHRyZWUuY2xhenopOwogICAgICAgIHJlc3VsdCA9IHRyZWU7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRJbmRleGVkKEpDQXJyYXlBY2Nlc3MgdHJlZSkgewogICAgICAgIHRyZWUuaW5kZXhlZCA9IHRyYW5zbGF0ZSh0cmVlLmluZGV4ZWQpOwogICAgICAgIHRyZWUuaW5kZXggPSB0cmFuc2xhdGUodHJlZS5pbmRleCk7CiAgICAgICAgcmVzdWx0ID0gdHJlZTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdFNlbGVjdChKQ0ZpZWxkQWNjZXNzIHRyZWUpIHsKICAgICAgICB0cmVlLnNlbGVjdGVkID0gdHJhbnNsYXRlKHRyZWUuc2VsZWN0ZWQpOwogICAgICAgIHJlc3VsdCA9IHRyZWU7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRSZWZlcmVuY2UoSkNNZW1iZXJSZWZlcmVuY2UgdHJlZSkgewogICAgICAgIHRyZWUuZXhwciA9IHRyYW5zbGF0ZSh0cmVlLmV4cHIpOwogICAgICAgIHJlc3VsdCA9IHRyZWU7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRJZGVudChKQ0lkZW50IHRyZWUpIHsKICAgICAgICByZXN1bHQgPSB0cmVlOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0TGl0ZXJhbChKQ0xpdGVyYWwgdHJlZSkgewogICAgICAgIHJlc3VsdCA9IHRyZWU7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRUeXBlSWRlbnQoSkNQcmltaXRpdmVUeXBlVHJlZSB0cmVlKSB7CiAgICAgICAgcmVzdWx0ID0gdHJlZTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdFR5cGVBcnJheShKQ0FycmF5VHlwZVRyZWUgdHJlZSkgewogICAgICAgIHRyZWUuZWxlbXR5cGUgPSB0cmFuc2xhdGUodHJlZS5lbGVtdHlwZSk7CiAgICAgICAgcmVzdWx0ID0gdHJlZTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdFR5cGVBcHBseShKQ1R5cGVBcHBseSB0cmVlKSB7CiAgICAgICAgdHJlZS5jbGF6eiA9IHRyYW5zbGF0ZSh0cmVlLmNsYXp6KTsKICAgICAgICB0cmVlLmFyZ3VtZW50cyA9IHRyYW5zbGF0ZSh0cmVlLmFyZ3VtZW50cyk7CiAgICAgICAgcmVzdWx0ID0gdHJlZTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdFR5cGVVbmlvbihKQ1R5cGVVbmlvbiB0cmVlKSB7CiAgICAgICAgdHJlZS5hbHRlcm5hdGl2ZXMgPSB0cmFuc2xhdGUodHJlZS5hbHRlcm5hdGl2ZXMpOwogICAgICAgIHJlc3VsdCA9IHRyZWU7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRUeXBlSW50ZXJzZWN0aW9uKEpDVHlwZUludGVyc2VjdGlvbiB0cmVlKSB7CiAgICAgICAgdHJlZS5ib3VuZHMgPSB0cmFuc2xhdGUodHJlZS5ib3VuZHMpOwogICAgICAgIHJlc3VsdCA9IHRyZWU7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRUeXBlUGFyYW1ldGVyKEpDVHlwZVBhcmFtZXRlciB0cmVlKSB7CiAgICAgICAgdHJlZS5hbm5vdGF0aW9ucyA9IHRyYW5zbGF0ZSh0cmVlLmFubm90YXRpb25zKTsKICAgICAgICB0cmVlLmJvdW5kcyA9IHRyYW5zbGF0ZSh0cmVlLmJvdW5kcyk7CiAgICAgICAgcmVzdWx0ID0gdHJlZTsKICAgIH0KCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHZpc2l0V2lsZGNhcmQoSkNXaWxkY2FyZCB0cmVlKSB7CiAgICAgICAgdHJlZS5raW5kID0gdHJhbnNsYXRlKHRyZWUua2luZCk7CiAgICAgICAgdHJlZS5pbm5lciA9IHRyYW5zbGF0ZSh0cmVlLmlubmVyKTsKICAgICAgICByZXN1bHQgPSB0cmVlOwogICAgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIHZvaWQgdmlzaXRUeXBlQm91bmRLaW5kKFR5cGVCb3VuZEtpbmQgdHJlZSkgewogICAgICAgIHJlc3VsdCA9IHRyZWU7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRFcnJvbmVvdXMoSkNFcnJvbmVvdXMgdHJlZSkgewogICAgICAgIHJlc3VsdCA9IHRyZWU7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRMZXRFeHByKExldEV4cHIgdHJlZSkgewogICAgICAgIHRyZWUuZGVmcyA9IHRyYW5zbGF0ZVZhckRlZnModHJlZS5kZWZzKTsKICAgICAgICB0cmVlLmV4cHIgPSB0cmFuc2xhdGUodHJlZS5leHByKTsKICAgICAgICByZXN1bHQgPSB0cmVlOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0TW9kaWZpZXJzKEpDTW9kaWZpZXJzIHRyZWUpIHsKICAgICAgICB0cmVlLmFubm90YXRpb25zID0gdHJhbnNsYXRlQW5ub3RhdGlvbnModHJlZS5hbm5vdGF0aW9ucyk7CiAgICAgICAgcmVzdWx0ID0gdHJlZTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdEFubm90YXRpb24oSkNBbm5vdGF0aW9uIHRyZWUpIHsKICAgICAgICB0cmVlLmFubm90YXRpb25UeXBlID0gdHJhbnNsYXRlKHRyZWUuYW5ub3RhdGlvblR5cGUpOwogICAgICAgIHRyZWUuYXJncyA9IHRyYW5zbGF0ZSh0cmVlLmFyZ3MpOwogICAgICAgIHJlc3VsdCA9IHRyZWU7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRBbm5vdGF0ZWRUeXBlKEpDQW5ub3RhdGVkVHlwZSB0cmVlKSB7CiAgICAgICAgdHJlZS5hbm5vdGF0aW9ucyA9IHRyYW5zbGF0ZSh0cmVlLmFubm90YXRpb25zKTsKICAgICAgICB0cmVlLnVuZGVybHlpbmdUeXBlID0gdHJhbnNsYXRlKHRyZWUudW5kZXJseWluZ1R5cGUpOwogICAgICAgIHJlc3VsdCA9IHRyZWU7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRUcmVlKEpDVHJlZSB0cmVlKSB7CiAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKHRyZWUpOwogICAgfQp9ClBLAwQKAAAIAAAGO6lKvk14yuQJAADkCQAALQAAAGNvbS9zdW4vdG9vbHMvamF2YWMvdHJlZS9Eb2NDb21tZW50VGFibGUuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAxMiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWU7CgppbXBvcnQgY29tLnN1bi5zb3VyY2UuZG9jdHJlZS5FcnJvbmVvdXNUcmVlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5wYXJzZXIuVG9rZW5zLkNvbW1lbnQ7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuRENUcmVlLkRDRG9jQ29tbWVudDsKCi8qKgogKiBBIHRhYmxlIGdpdmluZyB0aGUgZG9jIGNvbW1lbnQsIGlmIGFueSwgZm9yIGFueSB0cmVlIG5vZGUuCiAqCiAqICA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiAgSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93bgogKiAgcmlzay4gIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlCiAqICBvciBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+CiAqLwpwdWJsaWMgaW50ZXJmYWNlIERvY0NvbW1lbnRUYWJsZSB7CiAgICAvKioKICAgICAqIENoZWNrIGlmIGEgdHJlZSBub2RlIGhhcyBhIGNvcnJlc3BvbmRpbmcgZG9jIGNvbW1lbnQuCiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGhhc0NvbW1lbnQoSkNUcmVlIHRyZWUpOwoKICAgIC8qKgogICAgICogR2V0IHRoZSBDb21tZW50IHRva2VuIGNvbnRhaW5pbmcgdGhlIGRvYyBjb21tZW50LCBpZiBhbnksIGZvciBhIHRyZWUgbm9kZS4KICAgICAqLwogICAgcHVibGljIENvbW1lbnQgZ2V0Q29tbWVudChKQ1RyZWUgdHJlZSk7CgogICAgLyoqCiAgICAgKiBHZXQgdGhlIHBsYWluIHRleHQgb2YgdGhlIGRvYyBjb21tZW50LCBpZiBhbnksIGZvciBhIHRyZWUgbm9kZS4KICAgICAqLwogICAgcHVibGljIFN0cmluZyBnZXRDb21tZW50VGV4dChKQ1RyZWUgdHJlZSk7CgogICAgLyoqCiAgICAgKiBHZXQgdGhlIHBhcnNlZCBmb3JtIG9mIHRoZSBkb2MgY29tbWVudCBhcyBhIERvY1RyZWUuIElmIGFueSBlcnJvcnMKICAgICAqIGFyZSBkZXRlY3RlZCBkdXJpbmcgcGFyc2luZywgdGhleSB3aWxsIGJlIHJlcG9ydGVkIHZpYQogICAgICoge0BsaW5rIEVycm9uZW91c1RyZWUgRXJyb25lb3VzVHJlZX0gbm9kZXMgd2l0aGluIHRoZSByZXN1bHRpbmcgdHJlZS4KICAgICAqLwogICAgcHVibGljIERDRG9jQ29tbWVudCBnZXRDb21tZW50VHJlZShKQ1RyZWUgdHJlZSk7CgogICAgLyoqCiAgICAgKiBTZXQgdGhlIENvbW1lbnQgdG8gYmUgYXNzb2NpYXRlZCB3aXRoIGEgdHJlZSBub2RlLgogICAgICovCiAgICBwdWJsaWMgdm9pZCBwdXRDb21tZW50KEpDVHJlZSB0cmVlLCBDb21tZW50IGMpOwp9ClBLAwQKAAAIAADSfU1Kjltn7DIKAAAyCgAAKQAAAGNvbS9zdW4vdG9vbHMvamF2YWMvdHJlZS9FbmRQb3NUYWJsZS5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDExLCAyMDEzLCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuamF2YWMudHJlZTsKCi8qKgogKiBTcGVjaWZpZXMgdGhlIG1ldGhvZHMgdG8gYWNjZXNzIGEgbWFwcGluZ3Mgb2Ygc3ludGF4IHRyZWVzIHRvIGVuZCBwb3NpdGlvbnMuCiAqIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24KICogcmlzay4gIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlCiAqIG9yIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj48L3A+CiAqLwpwdWJsaWMgaW50ZXJmYWNlIEVuZFBvc1RhYmxlIHsKCiAgICAvKioKICAgICAqIFRoaXMgbWV0aG9kIHdpbGwgcmV0dXJuIHRoZSBlbmQgcG9zaXRpb24gb2YgYSBnaXZlbiB0cmVlLCBvdGhlcndpc2UgYQogICAgICogUG9zaXRpb25zLk5PUE9TIHdpbGwgYmUgcmV0dXJuZWQuCiAgICAgKiBAcGFyYW0gdHJlZSBKQ1RyZWUKICAgICAqIEByZXR1cm4gcG9zaXRpb24gb2YgdGhlIHNvdXJjZSB0cmVlIG9yIFBvc2l0aW9ucy5OT1BPUyBmb3Igbm9uLWV4aXN0ZW50IG1hcHBpbmcKICAgICAqLwogICAgcHVibGljIGludCBnZXRFbmRQb3MoSkNUcmVlIHRyZWUpOwoKICAgIC8qKgogICAgICogU3RvcmUgZW5kaW5nIHBvc2l0aW9uIGZvciBhIHRyZWUsIHRoZSB2YWx1ZSBvZiB3aGljaCBpcyB0aGUgZ3JlYXRlciBvZgogICAgICogbGFzdCBlcnJvciBwb3NpdGlvbiBhbmQgdGhlIGdpdmVuIGVuZGluZyBwb3NpdGlvbi4KICAgICAqIEBwYXJhbSB0cmVlIFRoZSB0cmVlLgogICAgICogQHBhcmFtIGVuZHBvcyBUaGUgZW5kaW5nIHBvc2l0aW9uIHRvIGFzc29jaWF0ZSB3aXRoIHRoZSB0cmVlLgogICAgICovCiAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBzdG9yZUVuZChKQ1RyZWUgdHJlZSwgaW50IGVuZHBvcyk7CgogICAgLyoqCiAgICAgKiBHaXZlIGFuIG9sZCB0cmVlIGFuZCBhIG5ldyB0cmVlLCB0aGUgb2xkIHRyZWUgd2lsbCBiZSByZXBsYWNlZCB3aXRoCiAgICAgKiB0aGUgbmV3IHRyZWUsIHRoZSBwb3NpdGlvbiBvZiB0aGUgbmV3IHRyZWUgd2lsbCBiZSB0aGF0IG9mIHRoZSBvbGQKICAgICAqIHRyZWUuCiAgICAgKiBAcGFyYW0gb2xkdHJlZSBhIEpDVHJlZSB0byBiZSByZXBsYWNlZAogICAgICogQHBhcmFtIG5ld3RyZWUgYSBKQ1RyZWUgdG8gYmUgcmVwbGFjZWQgd2l0aAogICAgICogQHJldHVybiBwb3NpdGlvbiBvZiB0aGUgb2xkIHRyZWUgb3IgUG9zaXRpb25zLk5PUE9TIGZvciBub24tZXhpc3RlbnQgbWFwcGluZwogICAgICovCiAgICBwdWJsaWMgaW50IHJlcGxhY2VUcmVlKEpDVHJlZSBvbGR0cmVlLCBKQ1RyZWUgbmV3dHJlZSk7Cn0KUEsDBAoAAAgAAAY7qUqyfQrp4CQAAOAkAAApAAAAY29tL3N1bi90b29scy9qYXZhYy90cmVlL1RyZWVTY2FubmVyLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDEsIDIwMTYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhYy50cmVlOwoKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC4qOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkpDVHJlZS4qOwoKLyoqIEEgc3ViY2xhc3Mgb2YgVHJlZS5WaXNpdG9yLCB0aGlzIGNsYXNzIGRlZmluZXMKICogIGEgZ2VuZXJhbCB0cmVlIHNjYW5uZXIgcGF0dGVybi4gVHJhbnNsYXRpb24gcHJvY2VlZHMgcmVjdXJzaXZlbHkgaW4KICogIGxlZnQtdG8tcmlnaHQgb3JkZXIgZG93biBhIHRyZWUuIFRoZXJlIGlzIG9uZSB2aXNpdG9yIG1ldGhvZCBpbiB0aGlzIGNsYXNzCiAqICBmb3IgZXZlcnkgcG9zc2libGUga2luZCBvZiB0cmVlIG5vZGUuICBUbyBvYnRhaW4gYSBzcGVjaWZpYwogKiAgc2Nhbm5lciwgaXQgc3VmZmljZXMgdG8gb3ZlcnJpZGUgdGhvc2UgdmlzaXRvciBtZXRob2RzIHdoaWNoCiAqICBkbyBzb21lIGludGVyZXN0aW5nIHdvcmsuIFRoZSBzY2FubmVyIGNsYXNzIGl0c2VsZiB0YWtlcyBjYXJlIG9mIGFsbAogKiAgbmF2aWdhdGlvbmFsIGFzcGVjdHMuCiAqCiAqICA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiAgSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93biByaXNrLgogKiAgVGhpcyBjb2RlIGFuZCBpdHMgaW50ZXJuYWwgaW50ZXJmYWNlcyBhcmUgc3ViamVjdCB0byBjaGFuZ2Ugb3IKICogIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj4KICovCnB1YmxpYyBjbGFzcyBUcmVlU2Nhbm5lciBleHRlbmRzIFZpc2l0b3IgewoKICAgIC8qKiBWaXNpdG9yIG1ldGhvZDogU2NhbiBhIHNpbmdsZSBub2RlLgogICAgICovCiAgICBwdWJsaWMgdm9pZCBzY2FuKEpDVHJlZSB0cmVlKSB7CiAgICAgICAgaWYodHJlZSE9bnVsbCkgdHJlZS5hY2NlcHQodGhpcyk7CiAgICB9CgogICAgLyoqIFZpc2l0b3IgbWV0aG9kOiBzY2FuIGEgbGlzdCBvZiBub2Rlcy4KICAgICAqLwogICAgcHVibGljIHZvaWQgc2NhbihMaXN0PD8gZXh0ZW5kcyBKQ1RyZWU+IHRyZWVzKSB7CiAgICAgICAgaWYgKHRyZWVzICE9IG51bGwpCiAgICAgICAgZm9yIChMaXN0PD8gZXh0ZW5kcyBKQ1RyZWU+IGwgPSB0cmVlczsgbC5ub25FbXB0eSgpOyBsID0gbC50YWlsKQogICAgICAgICAgICBzY2FuKGwuaGVhZCk7CiAgICB9CgoKLyogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFZpc2l0b3IgbWV0aG9kcwogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiAgICBwdWJsaWMgdm9pZCB2aXNpdFRvcExldmVsKEpDQ29tcGlsYXRpb25Vbml0IHRyZWUpIHsKICAgICAgICBzY2FuKHRyZWUuZGVmcyk7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRQYWNrYWdlRGVmKEpDUGFja2FnZURlY2wgdHJlZSkgewogICAgICAgIHNjYW4odHJlZS5hbm5vdGF0aW9ucyk7CiAgICAgICAgc2Nhbih0cmVlLnBpZCk7CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB2aXNpdE1vZHVsZURlZihKQ01vZHVsZURlY2wgdHJlZSkgewogICAgICAgIHNjYW4odHJlZS5tb2RzKTsKICAgICAgICBzY2FuKHRyZWUucXVhbElkKTsKICAgICAgICBzY2FuKHRyZWUuZGlyZWN0aXZlcyk7CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB2aXNpdEV4cG9ydHMoSkNFeHBvcnRzIHRyZWUpIHsKICAgICAgICBzY2FuKHRyZWUucXVhbGlkKTsKICAgICAgICBzY2FuKHRyZWUubW9kdWxlTmFtZXMpOwogICAgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIHZvaWQgdmlzaXRPcGVucyhKQ09wZW5zIHRyZWUpIHsKICAgICAgICBzY2FuKHRyZWUucXVhbGlkKTsKICAgICAgICBzY2FuKHRyZWUubW9kdWxlTmFtZXMpOwogICAgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIHZvaWQgdmlzaXRQcm92aWRlcyhKQ1Byb3ZpZGVzIHRyZWUpIHsKICAgICAgICBzY2FuKHRyZWUuc2VydmljZU5hbWUpOwogICAgICAgIHNjYW4odHJlZS5pbXBsTmFtZXMpOwogICAgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIHZvaWQgdmlzaXRSZXF1aXJlcyhKQ1JlcXVpcmVzIHRyZWUpIHsKICAgICAgICBzY2FuKHRyZWUubW9kdWxlTmFtZSk7CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB2aXNpdFVzZXMoSkNVc2VzIHRyZWUpIHsKICAgICAgICBzY2FuKHRyZWUucXVhbGlkKTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdEltcG9ydChKQ0ltcG9ydCB0cmVlKSB7CiAgICAgICAgc2Nhbih0cmVlLnF1YWxpZCk7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRDbGFzc0RlZihKQ0NsYXNzRGVjbCB0cmVlKSB7CiAgICAgICAgc2Nhbih0cmVlLm1vZHMpOwogICAgICAgIHNjYW4odHJlZS50eXBhcmFtcyk7CiAgICAgICAgc2Nhbih0cmVlLmV4dGVuZGluZyk7CiAgICAgICAgc2Nhbih0cmVlLmltcGxlbWVudGluZyk7CiAgICAgICAgc2Nhbih0cmVlLmRlZnMpOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0TWV0aG9kRGVmKEpDTWV0aG9kRGVjbCB0cmVlKSB7CiAgICAgICAgc2Nhbih0cmVlLm1vZHMpOwogICAgICAgIHNjYW4odHJlZS5yZXN0eXBlKTsKICAgICAgICBzY2FuKHRyZWUudHlwYXJhbXMpOwogICAgICAgIHNjYW4odHJlZS5yZWN2cGFyYW0pOwogICAgICAgIHNjYW4odHJlZS5wYXJhbXMpOwogICAgICAgIHNjYW4odHJlZS50aHJvd24pOwogICAgICAgIHNjYW4odHJlZS5kZWZhdWx0VmFsdWUpOwogICAgICAgIHNjYW4odHJlZS5ib2R5KTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdFZhckRlZihKQ1ZhcmlhYmxlRGVjbCB0cmVlKSB7CiAgICAgICAgc2Nhbih0cmVlLm1vZHMpOwogICAgICAgIHNjYW4odHJlZS52YXJ0eXBlKTsKICAgICAgICBzY2FuKHRyZWUubmFtZWV4cHIpOwogICAgICAgIHNjYW4odHJlZS5pbml0KTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdFNraXAoSkNTa2lwIHRyZWUpIHsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdEJsb2NrKEpDQmxvY2sgdHJlZSkgewogICAgICAgIHNjYW4odHJlZS5zdGF0cyk7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXREb0xvb3AoSkNEb1doaWxlTG9vcCB0cmVlKSB7CiAgICAgICAgc2Nhbih0cmVlLmJvZHkpOwogICAgICAgIHNjYW4odHJlZS5jb25kKTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdFdoaWxlTG9vcChKQ1doaWxlTG9vcCB0cmVlKSB7CiAgICAgICAgc2Nhbih0cmVlLmNvbmQpOwogICAgICAgIHNjYW4odHJlZS5ib2R5KTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdEZvckxvb3AoSkNGb3JMb29wIHRyZWUpIHsKICAgICAgICBzY2FuKHRyZWUuaW5pdCk7CiAgICAgICAgc2Nhbih0cmVlLmNvbmQpOwogICAgICAgIHNjYW4odHJlZS5zdGVwKTsKICAgICAgICBzY2FuKHRyZWUuYm9keSk7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRGb3JlYWNoTG9vcChKQ0VuaGFuY2VkRm9yTG9vcCB0cmVlKSB7CiAgICAgICAgc2Nhbih0cmVlLnZhcik7CiAgICAgICAgc2Nhbih0cmVlLmV4cHIpOwogICAgICAgIHNjYW4odHJlZS5ib2R5KTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdExhYmVsbGVkKEpDTGFiZWxlZFN0YXRlbWVudCB0cmVlKSB7CiAgICAgICAgc2Nhbih0cmVlLmJvZHkpOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0U3dpdGNoKEpDU3dpdGNoIHRyZWUpIHsKICAgICAgICBzY2FuKHRyZWUuc2VsZWN0b3IpOwogICAgICAgIHNjYW4odHJlZS5jYXNlcyk7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRDYXNlKEpDQ2FzZSB0cmVlKSB7CiAgICAgICAgc2Nhbih0cmVlLnBhdCk7CiAgICAgICAgc2Nhbih0cmVlLnN0YXRzKTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdFN5bmNocm9uaXplZChKQ1N5bmNocm9uaXplZCB0cmVlKSB7CiAgICAgICAgc2Nhbih0cmVlLmxvY2spOwogICAgICAgIHNjYW4odHJlZS5ib2R5KTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdFRyeShKQ1RyeSB0cmVlKSB7CiAgICAgICAgc2Nhbih0cmVlLnJlc291cmNlcyk7CiAgICAgICAgc2Nhbih0cmVlLmJvZHkpOwogICAgICAgIHNjYW4odHJlZS5jYXRjaGVycyk7CiAgICAgICAgc2Nhbih0cmVlLmZpbmFsaXplcik7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRDYXRjaChKQ0NhdGNoIHRyZWUpIHsKICAgICAgICBzY2FuKHRyZWUucGFyYW0pOwogICAgICAgIHNjYW4odHJlZS5ib2R5KTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdENvbmRpdGlvbmFsKEpDQ29uZGl0aW9uYWwgdHJlZSkgewogICAgICAgIHNjYW4odHJlZS5jb25kKTsKICAgICAgICBzY2FuKHRyZWUudHJ1ZXBhcnQpOwogICAgICAgIHNjYW4odHJlZS5mYWxzZXBhcnQpOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0SWYoSkNJZiB0cmVlKSB7CiAgICAgICAgc2Nhbih0cmVlLmNvbmQpOwogICAgICAgIHNjYW4odHJlZS50aGVucGFydCk7CiAgICAgICAgc2Nhbih0cmVlLmVsc2VwYXJ0KTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdEV4ZWMoSkNFeHByZXNzaW9uU3RhdGVtZW50IHRyZWUpIHsKICAgICAgICBzY2FuKHRyZWUuZXhwcik7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRCcmVhayhKQ0JyZWFrIHRyZWUpIHsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdENvbnRpbnVlKEpDQ29udGludWUgdHJlZSkgewogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0UmV0dXJuKEpDUmV0dXJuIHRyZWUpIHsKICAgICAgICBzY2FuKHRyZWUuZXhwcik7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRUaHJvdyhKQ1Rocm93IHRyZWUpIHsKICAgICAgICBzY2FuKHRyZWUuZXhwcik7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRBc3NlcnQoSkNBc3NlcnQgdHJlZSkgewogICAgICAgIHNjYW4odHJlZS5jb25kKTsKICAgICAgICBzY2FuKHRyZWUuZGV0YWlsKTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdEFwcGx5KEpDTWV0aG9kSW52b2NhdGlvbiB0cmVlKSB7CiAgICAgICAgc2Nhbih0cmVlLnR5cGVhcmdzKTsKICAgICAgICBzY2FuKHRyZWUubWV0aCk7CiAgICAgICAgc2Nhbih0cmVlLmFyZ3MpOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0TmV3Q2xhc3MoSkNOZXdDbGFzcyB0cmVlKSB7CiAgICAgICAgc2Nhbih0cmVlLmVuY2wpOwogICAgICAgIHNjYW4odHJlZS50eXBlYXJncyk7CiAgICAgICAgc2Nhbih0cmVlLmNsYXp6KTsKICAgICAgICBzY2FuKHRyZWUuYXJncyk7CiAgICAgICAgc2Nhbih0cmVlLmRlZik7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXROZXdBcnJheShKQ05ld0FycmF5IHRyZWUpIHsKICAgICAgICBzY2FuKHRyZWUuYW5ub3RhdGlvbnMpOwogICAgICAgIHNjYW4odHJlZS5lbGVtdHlwZSk7CiAgICAgICAgc2Nhbih0cmVlLmRpbXMpOwogICAgICAgIGZvciAoTGlzdDxKQ0Fubm90YXRpb24+IGFubm9zIDogdHJlZS5kaW1Bbm5vdGF0aW9ucykKICAgICAgICAgICAgc2Nhbihhbm5vcyk7CiAgICAgICAgc2Nhbih0cmVlLmVsZW1zKTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdExhbWJkYShKQ0xhbWJkYSB0cmVlKSB7CiAgICAgICAgc2Nhbih0cmVlLmJvZHkpOwogICAgICAgIHNjYW4odHJlZS5wYXJhbXMpOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0UGFyZW5zKEpDUGFyZW5zIHRyZWUpIHsKICAgICAgICBzY2FuKHRyZWUuZXhwcik7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRBc3NpZ24oSkNBc3NpZ24gdHJlZSkgewogICAgICAgIHNjYW4odHJlZS5saHMpOwogICAgICAgIHNjYW4odHJlZS5yaHMpOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0QXNzaWdub3AoSkNBc3NpZ25PcCB0cmVlKSB7CiAgICAgICAgc2Nhbih0cmVlLmxocyk7CiAgICAgICAgc2Nhbih0cmVlLnJocyk7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRVbmFyeShKQ1VuYXJ5IHRyZWUpIHsKICAgICAgICBzY2FuKHRyZWUuYXJnKTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdEJpbmFyeShKQ0JpbmFyeSB0cmVlKSB7CiAgICAgICAgc2Nhbih0cmVlLmxocyk7CiAgICAgICAgc2Nhbih0cmVlLnJocyk7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRUeXBlQ2FzdChKQ1R5cGVDYXN0IHRyZWUpIHsKICAgICAgICBzY2FuKHRyZWUuY2xhenopOwogICAgICAgIHNjYW4odHJlZS5leHByKTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdFR5cGVUZXN0KEpDSW5zdGFuY2VPZiB0cmVlKSB7CiAgICAgICAgc2Nhbih0cmVlLmV4cHIpOwogICAgICAgIHNjYW4odHJlZS5jbGF6eik7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRJbmRleGVkKEpDQXJyYXlBY2Nlc3MgdHJlZSkgewogICAgICAgIHNjYW4odHJlZS5pbmRleGVkKTsKICAgICAgICBzY2FuKHRyZWUuaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0U2VsZWN0KEpDRmllbGRBY2Nlc3MgdHJlZSkgewogICAgICAgIHNjYW4odHJlZS5zZWxlY3RlZCk7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRSZWZlcmVuY2UoSkNNZW1iZXJSZWZlcmVuY2UgdHJlZSkgewogICAgICAgIHNjYW4odHJlZS5leHByKTsKICAgICAgICBzY2FuKHRyZWUudHlwZWFyZ3MpOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0SWRlbnQoSkNJZGVudCB0cmVlKSB7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRMaXRlcmFsKEpDTGl0ZXJhbCB0cmVlKSB7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRUeXBlSWRlbnQoSkNQcmltaXRpdmVUeXBlVHJlZSB0cmVlKSB7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRUeXBlQXJyYXkoSkNBcnJheVR5cGVUcmVlIHRyZWUpIHsKICAgICAgICBzY2FuKHRyZWUuZWxlbXR5cGUpOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0VHlwZUFwcGx5KEpDVHlwZUFwcGx5IHRyZWUpIHsKICAgICAgICBzY2FuKHRyZWUuY2xhenopOwogICAgICAgIHNjYW4odHJlZS5hcmd1bWVudHMpOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0VHlwZVVuaW9uKEpDVHlwZVVuaW9uIHRyZWUpIHsKICAgICAgICBzY2FuKHRyZWUuYWx0ZXJuYXRpdmVzKTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdFR5cGVJbnRlcnNlY3Rpb24oSkNUeXBlSW50ZXJzZWN0aW9uIHRyZWUpIHsKICAgICAgICBzY2FuKHRyZWUuYm91bmRzKTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdFR5cGVQYXJhbWV0ZXIoSkNUeXBlUGFyYW1ldGVyIHRyZWUpIHsKICAgICAgICBzY2FuKHRyZWUuYW5ub3RhdGlvbnMpOwogICAgICAgIHNjYW4odHJlZS5ib3VuZHMpOwogICAgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIHZvaWQgdmlzaXRXaWxkY2FyZChKQ1dpbGRjYXJkIHRyZWUpIHsKICAgICAgICBzY2FuKHRyZWUua2luZCk7CiAgICAgICAgaWYgKHRyZWUuaW5uZXIgIT0gbnVsbCkKICAgICAgICAgICAgc2Nhbih0cmVlLmlubmVyKTsKICAgIH0KCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHZpc2l0VHlwZUJvdW5kS2luZChUeXBlQm91bmRLaW5kIHRoYXQpIHsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdE1vZGlmaWVycyhKQ01vZGlmaWVycyB0cmVlKSB7CiAgICAgICAgc2Nhbih0cmVlLmFubm90YXRpb25zKTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdEFubm90YXRpb24oSkNBbm5vdGF0aW9uIHRyZWUpIHsKICAgICAgICBzY2FuKHRyZWUuYW5ub3RhdGlvblR5cGUpOwogICAgICAgIHNjYW4odHJlZS5hcmdzKTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdEFubm90YXRlZFR5cGUoSkNBbm5vdGF0ZWRUeXBlIHRyZWUpIHsKICAgICAgICBzY2FuKHRyZWUuYW5ub3RhdGlvbnMpOwogICAgICAgIHNjYW4odHJlZS51bmRlcmx5aW5nVHlwZSk7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRFcnJvbmVvdXMoSkNFcnJvbmVvdXMgdHJlZSkgewogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0TGV0RXhwcihMZXRFeHByIHRyZWUpIHsKICAgICAgICBzY2FuKHRyZWUuZGVmcyk7CiAgICAgICAgc2Nhbih0cmVlLmV4cHIpOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0VHJlZShKQ1RyZWUgdHJlZSkgewogICAgICAgIEFzc2VydC5lcnJvcigpOwogICAgfQp9ClBLAwQKAAAIAAAGO6lKAAAAAAAAAAAAAAAAHwAAAGNvbS9zdW4vdG9vbHMvamF2YWMvcHJvY2Vzc2luZy9QSwMECgAACAAA0n1NSqLwax3RBgAA0QYAAD0AAABjb20vc3VuL3Rvb2xzL2phdmFjL3Byb2Nlc3NpbmcvQW5ub3RhdGlvblByb2Nlc3NpbmdFcnJvci5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDA1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuamF2YWMucHJvY2Vzc2luZzsKCgovKioKICogRXJyb3IgdGhyb3duIGZvciBwcm9ibGVtcyBlbmNvdW50ZXJlZCBkdXJpbmcgYW5ub3RhdGlvbiBwcm9jZXNzaW5nLgogKgogKiA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yCiAqIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj4KICovCnB1YmxpYyBjbGFzcyBBbm5vdGF0aW9uUHJvY2Vzc2luZ0Vycm9yIGV4dGVuZHMgRXJyb3IgewogICAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDMwNTMzNzcwNzAxOTIzMDc5MEw7CiAgICBBbm5vdGF0aW9uUHJvY2Vzc2luZ0Vycm9yKFRocm93YWJsZSBjYXVzZSkgewogICAgICAgIHN1cGVyKGNhdXNlKTsKICAgIH0KfQpQSwMECgAACAAABjupSsR+H2i7JwAAuycAADkAAABjb20vc3VuL3Rvb2xzL2phdmFjL3Byb2Nlc3NpbmcvSmF2YWNSb3VuZEVudmlyb25tZW50LmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMTYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhYy5wcm9jZXNzaW5nOwoKaW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLkFubm90YXRpb247CmltcG9ydCBqYXZheC5hbm5vdGF0aW9uLnByb2Nlc3NpbmcuKjsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC4qOwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC51dGlsLio7CmltcG9ydCBqYXZhLnV0aWwuKjsKCmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuRGVmaW5lZEJ5OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkRlZmluZWRCeS5BcGk7CgovKioKICogT2JqZWN0IHByb3ZpZGluZyBzdGF0ZSBhYm91dCBhIHByaW9yIHJvdW5kIG9mIGFubm90YXRpb24gcHJvY2Vzc2luZy4KICoKICogPHA+VGhlIG1ldGhvZHMgaW4gdGhpcyBjbGFzcyBkbyBub3QgdGFrZSB0eXBlIGFubm90YXRpb25zIGludG8gYWNjb3VudCwKICogYXMgdGFyZ2V0IHR5cGVzLCBub3QgamF2YSBlbGVtZW50cy4KICoKICogPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93biByaXNrLgogKiBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogKiBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+CiAqLwpwdWJsaWMgY2xhc3MgSmF2YWNSb3VuZEVudmlyb25tZW50IGltcGxlbWVudHMgUm91bmRFbnZpcm9ubWVudCB7CiAgICAvLyBEZWZhdWx0IGVxdWFscyBhbmQgaGFzaENvZGUgbWV0aG9kcyBhcmUgb2theS4KCiAgICBwcml2YXRlIGZpbmFsIGJvb2xlYW4gcHJvY2Vzc2luZ092ZXI7CiAgICBwcml2YXRlIGZpbmFsIGJvb2xlYW4gZXJyb3JSYWlzZWQ7CiAgICBwcml2YXRlIGZpbmFsIFByb2Nlc3NpbmdFbnZpcm9ubWVudCBwcm9jZXNzaW5nRW52OwogICAgcHJpdmF0ZSBmaW5hbCBFbGVtZW50cyBlbHRVdGlsczsKCiAgICAvLyBDYWxsZXIgbXVzdCBwYXNzIGluIGFuIGltbXV0YWJsZSBzZXQKICAgIHByaXZhdGUgZmluYWwgU2V0PD8gZXh0ZW5kcyBFbGVtZW50PiByb290RWxlbWVudHM7CgogICAgSmF2YWNSb3VuZEVudmlyb25tZW50KGJvb2xlYW4gcHJvY2Vzc2luZ092ZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBlcnJvclJhaXNlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICBTZXQ8PyBleHRlbmRzIEVsZW1lbnQ+IHJvb3RFbGVtZW50cywKICAgICAgICAgICAgICAgICAgICAgICAgICBQcm9jZXNzaW5nRW52aXJvbm1lbnQgcHJvY2Vzc2luZ0VudikgewogICAgICAgIHRoaXMucHJvY2Vzc2luZ092ZXIgPSBwcm9jZXNzaW5nT3ZlcjsKICAgICAgICB0aGlzLmVycm9yUmFpc2VkID0gZXJyb3JSYWlzZWQ7CiAgICAgICAgdGhpcy5yb290RWxlbWVudHMgPSByb290RWxlbWVudHM7CiAgICAgICAgdGhpcy5wcm9jZXNzaW5nRW52ID0gcHJvY2Vzc2luZ0VudjsKICAgICAgICB0aGlzLmVsdFV0aWxzID0gcHJvY2Vzc2luZ0Vudi5nZXRFbGVtZW50VXRpbHMoKTsKICAgIH0KCiAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewogICAgICAgIHJldHVybiBTdHJpbmcuZm9ybWF0KCJbZXJyb3JSYWlzZWQ9JWIsIHJvb3RFbGVtZW50cz0lcywgcHJvY2Vzc2luZ092ZXI9JWJdIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvclJhaXNlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICByb290RWxlbWVudHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvY2Vzc2luZ092ZXIpOwogICAgfQoKICAgIEBEZWZpbmVkQnkoQXBpLkFOTk9UQVRJT05fUFJPQ0VTU0lORykKICAgIHB1YmxpYyBib29sZWFuIHByb2Nlc3NpbmdPdmVyKCkgewogICAgICAgIHJldHVybiBwcm9jZXNzaW5nT3ZlcjsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMge0Bjb2RlIHRydWV9IGlmIGFuIGVycm9yIHdhcyByYWlzZWQgaW4gdGhlIHByaW9yIHJvdW5kCiAgICAgKiBvZiBwcm9jZXNzaW5nOyByZXR1cm5zIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgogICAgICoKICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIGFuIGVycm9yIHdhcyByYWlzZWQgaW4gdGhlIHByaW9yIHJvdW5kCiAgICAgKiBvZiBwcm9jZXNzaW5nOyByZXR1cm5zIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgogICAgICovCiAgICBARGVmaW5lZEJ5KEFwaS5BTk5PVEFUSU9OX1BST0NFU1NJTkcpCiAgICBwdWJsaWMgYm9vbGVhbiBlcnJvclJhaXNlZCgpIHsKICAgICAgICByZXR1cm4gZXJyb3JSYWlzZWQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSB0eXBlIGVsZW1lbnRzIHNwZWNpZmllZCBieSB0aGUgcHJpb3Igcm91bmQuCiAgICAgKgogICAgICogQHJldHVybiB0aGUgdHlwZXMgZWxlbWVudHMgc3BlY2lmaWVkIGJ5IHRoZSBwcmlvciByb3VuZCwgb3IgYW4KICAgICAqIGVtcHR5IHNldCBpZiB0aGVyZSB3ZXJlIG5vbmUKICAgICAqLwogICAgQERlZmluZWRCeShBcGkuQU5OT1RBVElPTl9QUk9DRVNTSU5HKQogICAgcHVibGljIFNldDw/IGV4dGVuZHMgRWxlbWVudD4gZ2V0Um9vdEVsZW1lbnRzKCkgewogICAgICAgIHJldHVybiByb290RWxlbWVudHM7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBlbGVtZW50cyBhbm5vdGF0ZWQgd2l0aCB0aGUgZ2l2ZW4gYW5ub3RhdGlvbiB0eXBlLgogICAgICogT25seSB0eXBlIGVsZW1lbnRzIDxpPmluY2x1ZGVkPC9pPiBpbiB0aGlzIHJvdW5kIG9mIGFubm90YXRpb24KICAgICAqIHByb2Nlc3NpbmcsIG9yIGRlY2xhcmF0aW9ucyBvZiBtZW1iZXJzLCBwYXJhbWV0ZXJzLCBvciB0eXBlCiAgICAgKiBwYXJhbWV0ZXJzIGRlY2xhcmVkIHdpdGhpbiB0aG9zZSwgYXJlIHJldHVybmVkLiAgSW5jbHVkZWQgdHlwZQogICAgICogZWxlbWVudHMgYXJlIHtAbGlua3BsYWluICNnZXRSb290RWxlbWVudHMgc3BlY2lmaWVkCiAgICAgKiB0eXBlc30gYW5kIGFueSB0eXBlcyBuZXN0ZWQgd2l0aGluIHRoZW0uCiAgICAgKgogICAgICogQHBhcmFtIGEgIGFubm90YXRpb24gdHlwZSBiZWluZyByZXF1ZXN0ZWQKICAgICAqIEByZXR1cm4gdGhlIGVsZW1lbnRzIGFubm90YXRlZCB3aXRoIHRoZSBnaXZlbiBhbm5vdGF0aW9uIHR5cGUsCiAgICAgKiBvciBhbiBlbXB0eSBzZXQgaWYgdGhlcmUgYXJlIG5vbmUKICAgICAqLwogICAgQERlZmluZWRCeShBcGkuQU5OT1RBVElPTl9QUk9DRVNTSU5HKQogICAgcHVibGljIFNldDw/IGV4dGVuZHMgRWxlbWVudD4gZ2V0RWxlbWVudHNBbm5vdGF0ZWRXaXRoKFR5cGVFbGVtZW50IGEpIHsKICAgICAgICB0aHJvd0lmTm90QW5ub3RhdGlvbihhKTsKCiAgICAgICAgU2V0PEVsZW1lbnQ+IHJlc3VsdCA9IENvbGxlY3Rpb25zLmVtcHR5U2V0KCk7CiAgICAgICAgRWxlbWVudFNjYW5uZXI5PFNldDxFbGVtZW50PiwgVHlwZUVsZW1lbnQ+IHNjYW5uZXIgPQogICAgICAgICAgICBuZXcgQW5ub3RhdGlvblNldFNjYW5uZXIocmVzdWx0KTsKCiAgICAgICAgZm9yIChFbGVtZW50IGVsZW1lbnQgOiByb290RWxlbWVudHMpCiAgICAgICAgICAgIHJlc3VsdCA9IHNjYW5uZXIuc2NhbihlbGVtZW50LCBhKTsKCiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KCiAgICBARGVmaW5lZEJ5KEFwaS5BTk5PVEFUSU9OX1BST0NFU1NJTkcpCiAgICBwdWJsaWMgU2V0PD8gZXh0ZW5kcyBFbGVtZW50PiBnZXRFbGVtZW50c0Fubm90YXRlZFdpdGhBbnkoVHlwZUVsZW1lbnQuLi4gYW5ub3RhdGlvbnMpIHsKICAgICAgICAvLyBEb24ndCBib3RoZXIgdG8gc3BlY2lhbC1jYXNlIGFubm90YXRpb25zLmxlbmd0aCA9PSAxIGFzCiAgICAgICAgLy8gcmV0dXJuIGdldEVsZW1lbnRzQW5ub3RhdGVkV2l0aChhbm5vdGF0aW9uc1swXSk7CgogICAgICAgIFNldDxUeXBlRWxlbWVudD4gYW5ub3RhdGlvblNldCA9IG5ldyBMaW5rZWRIYXNoU2V0PD4oYW5ub3RhdGlvbnMubGVuZ3RoKTsKICAgICAgICBmb3IgKFR5cGVFbGVtZW50IGFubm90YXRpb24gOiBhbm5vdGF0aW9ucykgewogICAgICAgICAgICB0aHJvd0lmTm90QW5ub3RhdGlvbihhbm5vdGF0aW9uKTsKICAgICAgICAgICAgYW5ub3RhdGlvblNldC5hZGQoYW5ub3RhdGlvbik7CiAgICAgICAgfQoKICAgICAgICBTZXQ8RWxlbWVudD4gcmVzdWx0ID0gQ29sbGVjdGlvbnMuZW1wdHlTZXQoKTsKICAgICAgICBFbGVtZW50U2Nhbm5lcjk8U2V0PEVsZW1lbnQ+LCBTZXQ8VHlwZUVsZW1lbnQ+PiBzY2FubmVyID0KICAgICAgICAgICAgbmV3IEFubm90YXRpb25TZXRNdWx0aVNjYW5uZXIocmVzdWx0KTsKCiAgICAgICAgZm9yIChFbGVtZW50IGVsZW1lbnQgOiByb290RWxlbWVudHMpCiAgICAgICAgICAgIHJlc3VsdCA9IHNjYW5uZXIuc2NhbihlbGVtZW50LCBhbm5vdGF0aW9uU2V0KTsKCiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KCiAgICAvLyBDb3VsZCBiZSB3cml0dGVuIGFzIGEgbG9jYWwgY2xhc3MgaW5zaWRlIGdldEVsZW1lbnRzQW5ub3RhdGVkV2l0aAogICAgcHJpdmF0ZSBjbGFzcyBBbm5vdGF0aW9uU2V0U2Nhbm5lciBleHRlbmRzCiAgICAgICAgRWxlbWVudFNjYW5uaW5nSW5jbHVkaW5nVHlwZVBhcmFtZXRlcnM8U2V0PEVsZW1lbnQ+LCBUeXBlRWxlbWVudD4gewogICAgICAgIC8vIEluc2VydGlvbi1vcmRlciBwcmVzZXJ2aW5nIHNldAogICAgICAgIHByaXZhdGUgU2V0PEVsZW1lbnQ+IGFubm90YXRlZEVsZW1lbnRzID0gbmV3IExpbmtlZEhhc2hTZXQ8PigpOwoKICAgICAgICBBbm5vdGF0aW9uU2V0U2Nhbm5lcihTZXQ8RWxlbWVudD4gZGVmYXVsdFNldCkgewogICAgICAgICAgICBzdXBlcihkZWZhdWx0U2V0KTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgICAgICBwdWJsaWMgU2V0PEVsZW1lbnQ+IHNjYW4oRWxlbWVudCBlLCBUeXBlRWxlbWVudCBhbm5vdGF0aW9uKSB7CiAgICAgICAgICAgIGZvciAoQW5ub3RhdGlvbk1pcnJvciBhbm5vdE1pcnJvciA6ICBlbHRVdGlscy5nZXRBbGxBbm5vdGF0aW9uTWlycm9ycyhlKSkgewogICAgICAgICAgICAgICAgaWYgKGFubm90YXRpb24uZXF1YWxzKG1pcnJvckFzRWxlbWVudChhbm5vdE1pcnJvcikpKSB7CiAgICAgICAgICAgICAgICAgICAgYW5ub3RhdGVkRWxlbWVudHMuYWRkKGUpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGUuYWNjZXB0KHRoaXMsIGFubm90YXRpb24pOwogICAgICAgICAgICByZXR1cm4gYW5ub3RhdGVkRWxlbWVudHM7CiAgICAgICAgfQogICAgfQoKICAgIC8vIENvdWxkIGJlIHdyaXR0ZW4gYXMgYSBsb2NhbCBjbGFzcyBpbnNpZGUgZ2V0RWxlbWVudHNBbm5vdGF0ZWRXaXRoQW55CiAgICBwcml2YXRlIGNsYXNzIEFubm90YXRpb25TZXRNdWx0aVNjYW5uZXIgZXh0ZW5kcwogICAgICAgIEVsZW1lbnRTY2FubmluZ0luY2x1ZGluZ1R5cGVQYXJhbWV0ZXJzPFNldDxFbGVtZW50PiwgU2V0PFR5cGVFbGVtZW50Pj4gewogICAgICAgIC8vIEluc2VydGlvbi1vcmRlciBwcmVzZXJ2aW5nIHNldAogICAgICAgIHByaXZhdGUgU2V0PEVsZW1lbnQ+IGFubm90YXRlZEVsZW1lbnRzID0gbmV3IExpbmtlZEhhc2hTZXQ8PigpOwoKICAgICAgICBBbm5vdGF0aW9uU2V0TXVsdGlTY2FubmVyKFNldDxFbGVtZW50PiBkZWZhdWx0U2V0KSB7CiAgICAgICAgICAgIHN1cGVyKGRlZmF1bHRTZXQpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyBTZXQ8RWxlbWVudD4gc2NhbihFbGVtZW50IGUsIFNldDxUeXBlRWxlbWVudD4gYW5ub3RhdGlvbnMpIHsKICAgICAgICAgICAgZm9yIChBbm5vdGF0aW9uTWlycm9yIGFubm90TWlycm9yIDogZWx0VXRpbHMuZ2V0QWxsQW5ub3RhdGlvbk1pcnJvcnMoZSkpIHsKICAgICAgICAgICAgICAgIGlmIChhbm5vdGF0aW9ucy5jb250YWlucyhtaXJyb3JBc0VsZW1lbnQoYW5ub3RNaXJyb3IpKSkgewogICAgICAgICAgICAgICAgICAgIGFubm90YXRlZEVsZW1lbnRzLmFkZChlKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBlLmFjY2VwdCh0aGlzLCBhbm5vdGF0aW9ucyk7CiAgICAgICAgICAgIHJldHVybiBhbm5vdGF0ZWRFbGVtZW50czsKICAgICAgICB9CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgYWJzdHJhY3QgY2xhc3MgRWxlbWVudFNjYW5uaW5nSW5jbHVkaW5nVHlwZVBhcmFtZXRlcnM8UiwgUD4KICAgICAgICBleHRlbmRzIEVsZW1lbnRTY2FubmVyOTxSLCBQPiB7CgogICAgICAgIHByb3RlY3RlZCBFbGVtZW50U2Nhbm5pbmdJbmNsdWRpbmdUeXBlUGFyYW1ldGVycyhSIGRlZmF1bHRWYWx1ZSkgewogICAgICAgICAgICBzdXBlcihkZWZhdWx0VmFsdWUpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyBSIHZpc2l0VHlwZShUeXBlRWxlbWVudCBlLCBQIHApIHsKICAgICAgICAgICAgLy8gVHlwZSBwYXJhbWV0ZXJzIGFyZSBub3QgY29uc2lkZXJlZCB0byBiZSBlbmNsb3NlZCBieSBhIHR5cGUKICAgICAgICAgICAgc2NhbihlLmdldFR5cGVQYXJhbWV0ZXJzKCksIHApOwogICAgICAgICAgICByZXR1cm4gc3VwZXIudmlzaXRUeXBlKGUsIHApOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyBSIHZpc2l0RXhlY3V0YWJsZShFeGVjdXRhYmxlRWxlbWVudCBlLCBQIHApIHsKICAgICAgICAgICAgLy8gVHlwZSBwYXJhbWV0ZXJzIGFyZSBub3QgY29uc2lkZXJlZCB0byBiZSBlbmNsb3NlZCBieSBhbiBleGVjdXRhYmxlCiAgICAgICAgICAgIHNjYW4oZS5nZXRUeXBlUGFyYW1ldGVycygpLCBwKTsKICAgICAgICAgICAgcmV0dXJuIHN1cGVyLnZpc2l0RXhlY3V0YWJsZShlLCBwKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIEBEZWZpbmVkQnkoQXBpLkFOTk9UQVRJT05fUFJPQ0VTU0lORykKICAgIHB1YmxpYyBTZXQ8PyBleHRlbmRzIEVsZW1lbnQ+IGdldEVsZW1lbnRzQW5ub3RhdGVkV2l0aChDbGFzczw/IGV4dGVuZHMgQW5ub3RhdGlvbj4gYSkgewogICAgICAgIHRocm93SWZOb3RBbm5vdGF0aW9uKGEpOwogICAgICAgIFN0cmluZyBuYW1lID0gYS5nZXRDYW5vbmljYWxOYW1lKCk7CiAgICAgICAgaWYgKG5hbWUgPT0gbnVsbCkKICAgICAgICAgICAgcmV0dXJuIENvbGxlY3Rpb25zLmVtcHR5U2V0KCk7CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIFR5cGVFbGVtZW50IGFubm90YXRpb25UeXBlID0gZWx0VXRpbHMuZ2V0VHlwZUVsZW1lbnQobmFtZSk7CiAgICAgICAgICAgIGlmIChhbm5vdGF0aW9uVHlwZSA9PSBudWxsKQogICAgICAgICAgICAgICAgcmV0dXJuIENvbGxlY3Rpb25zLmVtcHR5U2V0KCk7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHJldHVybiBnZXRFbGVtZW50c0Fubm90YXRlZFdpdGgoYW5ub3RhdGlvblR5cGUpOwogICAgICAgIH0KICAgIH0KCiAgICBARGVmaW5lZEJ5KEFwaS5BTk5PVEFUSU9OX1BST0NFU1NJTkcpCiAgICBwdWJsaWMgU2V0PD8gZXh0ZW5kcyBFbGVtZW50PiBnZXRFbGVtZW50c0Fubm90YXRlZFdpdGhBbnkoU2V0PENsYXNzPD8gZXh0ZW5kcyBBbm5vdGF0aW9uPj4gYW5ub3RhdGlvbnMpIHsKICAgICAgICBMaXN0PFR5cGVFbGVtZW50PiBhbm5vdGF0aW9uc0FzRWxlbWVudHMgPSBuZXcgQXJyYXlMaXN0PD4oYW5ub3RhdGlvbnMuc2l6ZSgpKTsKCiAgICAgICAgZm9yIChDbGFzczw/IGV4dGVuZHMgQW5ub3RhdGlvbj4gYW5ub3RhdGlvbiA6IGFubm90YXRpb25zKSB7CiAgICAgICAgICAgIHRocm93SWZOb3RBbm5vdGF0aW9uKGFubm90YXRpb24pOwogICAgICAgICAgICBTdHJpbmcgbmFtZSA9IGFubm90YXRpb24uZ2V0Q2Fub25pY2FsTmFtZSgpOwogICAgICAgICAgICBpZiAobmFtZSA9PSBudWxsKQogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIGFubm90YXRpb25zQXNFbGVtZW50cy5hZGQoZWx0VXRpbHMuZ2V0VHlwZUVsZW1lbnQobmFtZSkpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGdldEVsZW1lbnRzQW5ub3RhdGVkV2l0aEFueShhbm5vdGF0aW9uc0FzRWxlbWVudHMudG9BcnJheShuZXcgVHlwZUVsZW1lbnRbMF0pKTsKICAgIH0KCiAgICBwcml2YXRlIEVsZW1lbnQgbWlycm9yQXNFbGVtZW50KEFubm90YXRpb25NaXJyb3IgYW5ub3RhdGlvbk1pcnJvcikgewogICAgICAgIHJldHVybiBhbm5vdGF0aW9uTWlycm9yLmdldEFubm90YXRpb25UeXBlKCkuYXNFbGVtZW50KCk7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIE5PVF9BTl9BTk5PVEFUSU9OX1RZUEUgPQogICAgICAgICJUaGUgYXJndW1lbnQgZG9lcyBub3QgcmVwcmVzZW50IGFuIGFubm90YXRpb24gdHlwZTogIjsKCiAgICBwcml2YXRlIHZvaWQgdGhyb3dJZk5vdEFubm90YXRpb24oQ2xhc3M8PyBleHRlbmRzIEFubm90YXRpb24+IGEpIHsKICAgICAgICBpZiAoIWEuaXNBbm5vdGF0aW9uKCkpCiAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTk9UX0FOX0FOTk9UQVRJT05fVFlQRSArIGEpOwogICAgfQoKICAgIHByaXZhdGUgdm9pZCB0aHJvd0lmTm90QW5ub3RhdGlvbihUeXBlRWxlbWVudCBhKSB7CiAgICAgICAgaWYgKGEuZ2V0S2luZCgpICE9IEVsZW1lbnRLaW5kLkFOTk9UQVRJT05fVFlQRSkKICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihOT1RfQU5fQU5OT1RBVElPTl9UWVBFICsgYSk7CiAgICB9Cn0KUEsDBAoAAAgAAAY7qUr9LZrp3RgAAN0YAAAxAAAAY29tL3N1bi90b29scy9qYXZhYy9wcm9jZXNzaW5nL0phdmFjTWVzc2FnZXIuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAxNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLmphdmFjLnByb2Nlc3Npbmc7CgppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5tb2RlbC5KYXZhY0VsZW1lbnRzOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLio7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuRGVmaW5lZEJ5LkFwaTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5KQ0RpYWdub3N0aWMuRGlhZ25vc3RpY0ZsYWc7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuSkNUcmVlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkpDVHJlZS4qOwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5lbGVtZW50Lio7CmltcG9ydCBqYXZheC50b29scy5KYXZhRmlsZU9iamVjdDsKaW1wb3J0IGphdmF4LnRvb2xzLkRpYWdub3N0aWM7CmltcG9ydCBqYXZheC5hbm5vdGF0aW9uLnByb2Nlc3NpbmcuKjsKCi8qKgogKiBBbiBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgTWVzc2FnZXIgYnVpbHQgb24gdG9wIG9mIGxvZy4KICoKICogPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93biByaXNrLgogKiBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogKiBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+CiAqLwpwdWJsaWMgY2xhc3MgSmF2YWNNZXNzYWdlciBpbXBsZW1lbnRzIE1lc3NhZ2VyIHsKICAgIExvZyBsb2c7CiAgICBKYXZhY1Byb2Nlc3NpbmdFbnZpcm9ubWVudCBwcm9jZXNzaW5nRW52OwogICAgaW50IGVycm9yQ291bnQgPSAwOwogICAgaW50IHdhcm5pbmdDb3VudCA9IDA7CgogICAgSmF2YWNNZXNzYWdlcihDb250ZXh0IGNvbnRleHQsIEphdmFjUHJvY2Vzc2luZ0Vudmlyb25tZW50IHByb2Nlc3NpbmdFbnYpIHsKICAgICAgICBsb2cgPSBMb2cuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgdGhpcy5wcm9jZXNzaW5nRW52ID0gcHJvY2Vzc2luZ0VudjsKICAgIH0KCiAgICAvLyBwcm9jZXNzaW5nRW52LmdldEVsZW1lbnRVdGlscygpCgogICAgQERlZmluZWRCeShBcGkuQU5OT1RBVElPTl9QUk9DRVNTSU5HKQogICAgcHVibGljIHZvaWQgcHJpbnRNZXNzYWdlKERpYWdub3N0aWMuS2luZCBraW5kLCBDaGFyU2VxdWVuY2UgbXNnKSB7CiAgICAgICAgcHJpbnRNZXNzYWdlKGtpbmQsIG1zZywgbnVsbCwgbnVsbCwgbnVsbCk7CiAgICB9CgogICAgQERlZmluZWRCeShBcGkuQU5OT1RBVElPTl9QUk9DRVNTSU5HKQogICAgcHVibGljIHZvaWQgcHJpbnRNZXNzYWdlKERpYWdub3N0aWMuS2luZCBraW5kLCBDaGFyU2VxdWVuY2UgbXNnLAogICAgICAgICAgICAgICAgICAgICAgRWxlbWVudCBlKSB7CiAgICAgICAgcHJpbnRNZXNzYWdlKGtpbmQsIG1zZywgZSwgbnVsbCwgbnVsbCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBQcmludHMgYSBtZXNzYWdlIG9mIHRoZSBzcGVjaWZpZWQga2luZCBhdCB0aGUgbG9jYXRpb24gb2YgdGhlCiAgICAgKiBhbm5vdGF0aW9uIG1pcnJvciBvZiB0aGUgYW5ub3RhdGVkIGVsZW1lbnQuCiAgICAgKgogICAgICogQHBhcmFtIGtpbmQgdGhlIGtpbmQgb2YgbWVzc2FnZQogICAgICogQHBhcmFtIG1zZyAgdGhlIG1lc3NhZ2UsIG9yIGFuIGVtcHR5IHN0cmluZyBpZiBub25lCiAgICAgKiBAcGFyYW0gZSAgICB0aGUgYW5ub3RhdGVkIGVsZW1lbnQKICAgICAqIEBwYXJhbSBhICAgIHRoZSBhbm5vdGF0aW9uIHRvIHVzZSBhcyBhIHBvc2l0aW9uIGhpbnQKICAgICAqLwogICAgQERlZmluZWRCeShBcGkuQU5OT1RBVElPTl9QUk9DRVNTSU5HKQogICAgcHVibGljIHZvaWQgcHJpbnRNZXNzYWdlKERpYWdub3N0aWMuS2luZCBraW5kLCBDaGFyU2VxdWVuY2UgbXNnLAogICAgICAgICAgICAgICAgICAgICAgRWxlbWVudCBlLCBBbm5vdGF0aW9uTWlycm9yIGEpIHsKICAgICAgICBwcmludE1lc3NhZ2Uoa2luZCwgbXNnLCBlLCBhLCBudWxsKTsKICAgIH0KCiAgICAvKioKICAgICAqIFByaW50cyBhIG1lc3NhZ2Ugb2YgdGhlIHNwZWNpZmllZCBraW5kIGF0IHRoZSBsb2NhdGlvbiBvZiB0aGUKICAgICAqIGFubm90YXRpb24gdmFsdWUgaW5zaWRlIHRoZSBhbm5vdGF0aW9uIG1pcnJvciBvZiB0aGUgYW5ub3RhdGVkCiAgICAgKiBlbGVtZW50LgogICAgICoKICAgICAqIEBwYXJhbSBraW5kIHRoZSBraW5kIG9mIG1lc3NhZ2UKICAgICAqIEBwYXJhbSBtc2cgIHRoZSBtZXNzYWdlLCBvciBhbiBlbXB0eSBzdHJpbmcgaWYgbm9uZQogICAgICogQHBhcmFtIGUgICAgdGhlIGFubm90YXRlZCBlbGVtZW50CiAgICAgKiBAcGFyYW0gYSAgICB0aGUgYW5ub3RhdGlvbiBjb250YWluaW5nIHRoZSBhbm5vdGFpdG9uIHZhbHVlCiAgICAgKiBAcGFyYW0gdiAgICB0aGUgYW5ub3RhdGlvbiB2YWx1ZSB0byB1c2UgYXMgYSBwb3NpdGlvbiBoaW50CiAgICAgKi8KICAgIEBEZWZpbmVkQnkoQXBpLkFOTk9UQVRJT05fUFJPQ0VTU0lORykKICAgIHB1YmxpYyB2b2lkIHByaW50TWVzc2FnZShEaWFnbm9zdGljLktpbmQga2luZCwgQ2hhclNlcXVlbmNlIG1zZywKICAgICAgICAgICAgICAgICAgICAgIEVsZW1lbnQgZSwgQW5ub3RhdGlvbk1pcnJvciBhLCBBbm5vdGF0aW9uVmFsdWUgdikgewogICAgICAgIEphdmFGaWxlT2JqZWN0IG9sZFNvdXJjZSA9IG51bGw7CiAgICAgICAgSmF2YUZpbGVPYmplY3QgbmV3U291cmNlID0gbnVsbDsKICAgICAgICBKQ0RpYWdub3N0aWMuRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcyA9IG51bGw7CiAgICAgICAgSmF2YWNFbGVtZW50cyBlbGVtVXRpbHMgPSBwcm9jZXNzaW5nRW52LmdldEVsZW1lbnRVdGlscygpOwogICAgICAgIFBhaXI8SkNUcmVlLCBKQ0NvbXBpbGF0aW9uVW5pdD4gdHJlZVRvcCA9IGVsZW1VdGlscy5nZXRUcmVlQW5kVG9wTGV2ZWwoZSwgYSwgdik7CiAgICAgICAgaWYgKHRyZWVUb3AgIT0gbnVsbCkgewogICAgICAgICAgICBuZXdTb3VyY2UgPSB0cmVlVG9wLnNuZC5zb3VyY2VmaWxlOwogICAgICAgICAgICBpZiAobmV3U291cmNlICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIC8vIHNhdmUgdGhlIG9sZCB2ZXJzaW9uIGFuZCByZWluc3RhdGUgaXQgbGF0ZXIKICAgICAgICAgICAgICAgIG9sZFNvdXJjZSA9IGxvZy51c2VTb3VyY2UobmV3U291cmNlKTsKICAgICAgICAgICAgICAgIHBvcyA9IHRyZWVUb3AuZnN0LnBvcygpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICAgIHN3aXRjaCAoa2luZCkgewogICAgICAgICAgICBjYXNlIEVSUk9SOgogICAgICAgICAgICAgICAgZXJyb3JDb3VudCsrOwogICAgICAgICAgICAgICAgbG9nLmVycm9yKERpYWdub3N0aWNGbGFnLk1VTFRJUExFLCBwb3MsICJwcm9jLm1lc3NhZ2VyIiwgbXNnLnRvU3RyaW5nKCkpOwogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIFdBUk5JTkc6CiAgICAgICAgICAgICAgICB3YXJuaW5nQ291bnQrKzsKICAgICAgICAgICAgICAgIGxvZy53YXJuaW5nKHBvcywgInByb2MubWVzc2FnZXIiLCBtc2cudG9TdHJpbmcoKSk7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgTUFOREFUT1JZX1dBUk5JTkc6CiAgICAgICAgICAgICAgICB3YXJuaW5nQ291bnQrKzsKICAgICAgICAgICAgICAgIGxvZy5tYW5kYXRvcnlXYXJuaW5nKHBvcywgInByb2MubWVzc2FnZXIiLCBtc2cudG9TdHJpbmcoKSk7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICBsb2cubm90ZShwb3MsICJwcm9jLm1lc3NhZ2VyIiwgbXNnLnRvU3RyaW5nKCkpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAvLyByZWluc3RhdGUgdGhlIHNhdmVkIHZlcnNpb24sIG9ubHkgaWYgaXQgd2FzIHNhdmVkIGVhcmxpZXIKICAgICAgICAgICAgaWYgKG5ld1NvdXJjZSAhPSBudWxsKQogICAgICAgICAgICAgICAgbG9nLnVzZVNvdXJjZShvbGRTb3VyY2UpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFByaW50cyBhbiBlcnJvciBtZXNzYWdlLgogICAgICogRXF1aXZhbGVudCB0byB7QGNvZGUgcHJpbnRFcnJvcihudWxsLCBtc2cpfS4KICAgICAqIEBwYXJhbSBtc2cgIHRoZSBtZXNzYWdlLCBvciBhbiBlbXB0eSBzdHJpbmcgaWYgbm9uZQogICAgICovCiAgICBwdWJsaWMgdm9pZCBwcmludEVycm9yKFN0cmluZyBtc2cpIHsKICAgICAgICBwcmludE1lc3NhZ2UoRGlhZ25vc3RpYy5LaW5kLkVSUk9SLCBtc2cpOwogICAgfQoKICAgIC8qKgogICAgICogUHJpbnRzIGEgd2FybmluZyBtZXNzYWdlLgogICAgICogRXF1aXZhbGVudCB0byB7QGNvZGUgcHJpbnRXYXJuaW5nKG51bGwsIG1zZyl9LgogICAgICogQHBhcmFtIG1zZyAgdGhlIG1lc3NhZ2UsIG9yIGFuIGVtcHR5IHN0cmluZyBpZiBub25lCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHByaW50V2FybmluZyhTdHJpbmcgbXNnKSB7CiAgICAgICAgcHJpbnRNZXNzYWdlKERpYWdub3N0aWMuS2luZC5XQVJOSU5HLCBtc2cpOwogICAgfQoKICAgIC8qKgogICAgICogUHJpbnRzIGEgbm90aWNlLgogICAgICogQHBhcmFtIG1zZyAgdGhlIG1lc3NhZ2UsIG9yIGFuIGVtcHR5IHN0cmluZyBpZiBub25lCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHByaW50Tm90aWNlKFN0cmluZyBtc2cpIHsKICAgICAgICBwcmludE1lc3NhZ2UoRGlhZ25vc3RpYy5LaW5kLk5PVEUsIG1zZyk7CiAgICB9CgogICAgcHVibGljIGJvb2xlYW4gZXJyb3JSYWlzZWQoKSB7CiAgICAgICAgcmV0dXJuIGVycm9yQ291bnQgPiAwOwogICAgfQoKICAgIHB1YmxpYyBpbnQgZXJyb3JDb3VudCgpIHsKICAgICAgICByZXR1cm4gZXJyb3JDb3VudDsKICAgIH0KCiAgICBwdWJsaWMgaW50IHdhcm5pbmdDb3VudCgpIHsKICAgICAgICByZXR1cm4gd2FybmluZ0NvdW50OwogICAgfQoKICAgIHB1YmxpYyB2b2lkIG5ld1JvdW5kKCkgewogICAgICAgIGVycm9yQ291bnQgPSAwOwogICAgfQoKICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CiAgICAgICAgcmV0dXJuICJqYXZhYyBNZXNzYWdlciI7CiAgICB9Cn0KUEsDBAoAAAgAAAY7qUpgfZ0silsAAIpbAAA1AAAAY29tL3N1bi90b29scy9qYXZhYy9wcm9jZXNzaW5nL1ByaW50aW5nUHJvY2Vzc29yLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMTcsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhYy5wcm9jZXNzaW5nOwoKaW1wb3J0IGphdmF4LmFubm90YXRpb24ucHJvY2Vzc2luZy4qOwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC4qOwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5lbGVtZW50Lio7CmltcG9ydCBzdGF0aWMgamF2YXgubGFuZy5tb2RlbC5lbGVtZW50LkVsZW1lbnRLaW5kLio7CmltcG9ydCBzdGF0aWMgamF2YXgubGFuZy5tb2RlbC5lbGVtZW50Lk5lc3RpbmdLaW5kLio7CmltcG9ydCBzdGF0aWMgamF2YXgubGFuZy5tb2RlbC5lbGVtZW50Lk1vZHVsZUVsZW1lbnQuRGlyZWN0aXZlS2luZC4qOwppbXBvcnQgc3RhdGljIGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC5Nb2R1bGVFbGVtZW50Lio7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLnR5cGUuKjsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwudXRpbC4qOwoKaW1wb3J0IGphdmEuaW8uUHJpbnRXcml0ZXI7CmltcG9ydCBqYXZhLmlvLldyaXRlcjsKaW1wb3J0IGphdmEudXRpbC4qOwppbXBvcnQgamF2YS51dGlsLnN0cmVhbS5Db2xsZWN0b3JzOwoKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5EZWZpbmVkQnk7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuRGVmaW5lZEJ5LkFwaTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5TdHJpbmdVdGlsczsKCi8qKgogKiBBIHByb2Nlc3NvciB3aGljaCBwcmludHMgb3V0IGVsZW1lbnRzLiAgVXNlZCB0byBpbXBsZW1lbnQgdGhlCiAqIC1YcHJpbnQgb3B0aW9uOyB0aGUgaW5jbHVkZWQgdmlzaXRvciBjbGFzcyBpcyB1c2VkIHRvIGltcGxlbWVudAogKiBFbGVtZW50cy5wcmludEVsZW1lbnRzLgogKgogKiA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yCiAqIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj4KICovCkBTdXBwb3J0ZWRBbm5vdGF0aW9uVHlwZXMoIioiKQpAU3VwcG9ydGVkU291cmNlVmVyc2lvbihTb3VyY2VWZXJzaW9uLlJFTEVBU0VfOSkKcHVibGljIGNsYXNzIFByaW50aW5nUHJvY2Vzc29yIGV4dGVuZHMgQWJzdHJhY3RQcm9jZXNzb3IgewogICAgUHJpbnRXcml0ZXIgd3JpdGVyOwoKICAgIHB1YmxpYyBQcmludGluZ1Byb2Nlc3NvcigpIHsKICAgICAgICBzdXBlcigpOwogICAgICAgIHdyaXRlciA9IG5ldyBQcmludFdyaXRlcihTeXN0ZW0ub3V0KTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCBzZXRXcml0ZXIoV3JpdGVyIHcpIHsKICAgICAgICB3cml0ZXIgPSBuZXcgUHJpbnRXcml0ZXIodyk7CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkFOTk9UQVRJT05fUFJPQ0VTU0lORykKICAgIHB1YmxpYyBib29sZWFuIHByb2Nlc3MoU2V0PD8gZXh0ZW5kcyBUeXBlRWxlbWVudD4gdGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICBSb3VuZEVudmlyb25tZW50IHJlbnYpIHsKCiAgICAgICAgZm9yKEVsZW1lbnQgZWxlbWVudCA6IHJlbnYuZ2V0Um9vdEVsZW1lbnRzKCkpIHsKICAgICAgICAgICAgcHJpbnQoZWxlbWVudCk7CiAgICAgICAgfQoKICAgICAgICAvLyBKdXN0IHByaW50IHRoZSBlbGVtZW50cywgbm90aGluZyBtb3JlIHRvIGRvLgogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIHZvaWQgcHJpbnQoRWxlbWVudCBlbGVtZW50KSB7CiAgICAgICAgbmV3IFByaW50aW5nRWxlbWVudFZpc2l0b3Iod3JpdGVyLCBwcm9jZXNzaW5nRW52LmdldEVsZW1lbnRVdGlscygpKS4KICAgICAgICAgICAgdmlzaXQoZWxlbWVudCkuZmx1c2goKTsKICAgIH0KCiAgICAvKioKICAgICAqIFVzZWQgZm9yIHRoZSAtWHByaW50IG9wdGlvbiBhbmQgY2FsbGVkIGJ5IEVsZW1lbnRzLnByaW50RWxlbWVudHMKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBjbGFzcyBQcmludGluZ0VsZW1lbnRWaXNpdG9yCiAgICAgICAgZXh0ZW5kcyBTaW1wbGVFbGVtZW50VmlzaXRvcjk8UHJpbnRpbmdFbGVtZW50VmlzaXRvciwgQm9vbGVhbj4gewogICAgICAgIGludCBpbmRlbnRhdGlvbjsgLy8gSW5kZW50YXRpb24gbGV2ZWw7CiAgICAgICAgZmluYWwgUHJpbnRXcml0ZXIgd3JpdGVyOwogICAgICAgIGZpbmFsIEVsZW1lbnRzIGVsZW1lbnRVdGlsczsKCiAgICAgICAgcHVibGljIFByaW50aW5nRWxlbWVudFZpc2l0b3IoV3JpdGVyIHcsIEVsZW1lbnRzIGVsZW1lbnRVdGlscykgewogICAgICAgICAgICBzdXBlcigpOwogICAgICAgICAgICB0aGlzLndyaXRlciA9IG5ldyBQcmludFdyaXRlcih3KTsKICAgICAgICAgICAgdGhpcy5lbGVtZW50VXRpbHMgPSBlbGVtZW50VXRpbHM7CiAgICAgICAgICAgIGluZGVudGF0aW9uID0gMDsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgICAgICBwcm90ZWN0ZWQgUHJpbnRpbmdFbGVtZW50VmlzaXRvciBkZWZhdWx0QWN0aW9uKEVsZW1lbnQgZSwgQm9vbGVhbiBuZXdMaW5lKSB7CiAgICAgICAgICAgIGlmIChuZXdMaW5lICE9IG51bGwgJiYgbmV3TGluZSkKICAgICAgICAgICAgICAgIHdyaXRlci5wcmludGxuKCk7CiAgICAgICAgICAgIHByaW50RG9jQ29tbWVudChlKTsKICAgICAgICAgICAgcHJpbnRNb2RpZmllcnMoZSk7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyBQcmludGluZ0VsZW1lbnRWaXNpdG9yIHZpc2l0RXhlY3V0YWJsZShFeGVjdXRhYmxlRWxlbWVudCBlLCBCb29sZWFuIHApIHsKICAgICAgICAgICAgRWxlbWVudEtpbmQga2luZCA9IGUuZ2V0S2luZCgpOwoKICAgICAgICAgICAgaWYgKGtpbmQgIT0gU1RBVElDX0lOSVQgJiYKICAgICAgICAgICAgICAgIGtpbmQgIT0gSU5TVEFOQ0VfSU5JVCkgewogICAgICAgICAgICAgICAgRWxlbWVudCBlbmNsb3NpbmcgPSBlLmdldEVuY2xvc2luZ0VsZW1lbnQoKTsKCiAgICAgICAgICAgICAgICAvLyBEb24ndCBwcmludCBvdXQgdGhlIGNvbnN0cnVjdG9yIG9mIGFuIGFub255bW91cyBjbGFzcwogICAgICAgICAgICAgICAgaWYgKGtpbmQgPT0gQ09OU1RSVUNUT1IgJiYKICAgICAgICAgICAgICAgICAgICBlbmNsb3NpbmcgIT0gbnVsbCAmJgogICAgICAgICAgICAgICAgICAgIE5lc3RpbmdLaW5kLkFOT05ZTU9VUyA9PQogICAgICAgICAgICAgICAgICAgIC8vIFVzZSBhbiBhbm9ueW1vdXMgY2xhc3MgdG8gZGV0ZXJtaW5lIGFub255bWl0eSEKICAgICAgICAgICAgICAgICAgICAobmV3IFNpbXBsZUVsZW1lbnRWaXNpdG9yNzxOZXN0aW5nS2luZCwgVm9pZD4oKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgICAgICAgICAgICAgICAgICAgICAgcHVibGljIE5lc3RpbmdLaW5kIHZpc2l0VHlwZShUeXBlRWxlbWVudCBlLCBWb2lkIHApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBlLmdldE5lc3RpbmdLaW5kKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9KS52aXNpdChlbmNsb3NpbmcpKQogICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzOwoKICAgICAgICAgICAgICAgIGRlZmF1bHRBY3Rpb24oZSwgdHJ1ZSk7CiAgICAgICAgICAgICAgICBwcmludEZvcm1hbFR5cGVQYXJhbWV0ZXJzKGUsIHRydWUpOwoKICAgICAgICAgICAgICAgIHN3aXRjaChraW5kKSB7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBDT05TVFJVQ1RPUjoKICAgICAgICAgICAgICAgICAgICAvLyBQcmludCBvdXQgc2ltcGxlIG5hbWUgb2YgdGhlIGNsYXNzCiAgICAgICAgICAgICAgICAgICAgd3JpdGVyLnByaW50KGUuZ2V0RW5jbG9zaW5nRWxlbWVudCgpLmdldFNpbXBsZU5hbWUoKSk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgICAgIGNhc2UgTUVUSE9EOgogICAgICAgICAgICAgICAgICAgIHdyaXRlci5wcmludChlLmdldFJldHVyblR5cGUoKS50b1N0cmluZygpKTsKICAgICAgICAgICAgICAgICAgICB3cml0ZXIucHJpbnQoIiAiKTsKICAgICAgICAgICAgICAgICAgICB3cml0ZXIucHJpbnQoZS5nZXRTaW1wbGVOYW1lKCkudG9TdHJpbmcoKSk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgd3JpdGVyLnByaW50KCIoIik7CiAgICAgICAgICAgICAgICBwcmludFBhcmFtZXRlcnMoZSk7CiAgICAgICAgICAgICAgICB3cml0ZXIucHJpbnQoIikiKTsKICAgICAgICAgICAgICAgIEFubm90YXRpb25WYWx1ZSBkZWZhdWx0VmFsdWUgPSBlLmdldERlZmF1bHRWYWx1ZSgpOwogICAgICAgICAgICAgICAgaWYgKGRlZmF1bHRWYWx1ZSAhPSBudWxsKQogICAgICAgICAgICAgICAgICAgIHdyaXRlci5wcmludCgiIGRlZmF1bHQgIiArIGRlZmF1bHRWYWx1ZSk7CgogICAgICAgICAgICAgICAgcHJpbnRUaHJvd3MoZSk7CiAgICAgICAgICAgICAgICB3cml0ZXIucHJpbnRsbigiOyIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgICAgICBwdWJsaWMgUHJpbnRpbmdFbGVtZW50VmlzaXRvciB2aXNpdFR5cGUoVHlwZUVsZW1lbnQgZSwgQm9vbGVhbiBwKSB7CiAgICAgICAgICAgIEVsZW1lbnRLaW5kIGtpbmQgPSBlLmdldEtpbmQoKTsKICAgICAgICAgICAgTmVzdGluZ0tpbmQgbmVzdGluZ0tpbmQgPSBlLmdldE5lc3RpbmdLaW5kKCk7CgogICAgICAgICAgICBpZiAoTmVzdGluZ0tpbmQuQU5PTllNT1VTID09IG5lc3RpbmdLaW5kKSB7CiAgICAgICAgICAgICAgICAvLyBQcmludCBvdXQgYW4gYW5vbnltb3VzIGNsYXNzIGluIHRoZSBzdHlsZSBvZiBhCiAgICAgICAgICAgICAgICAvLyBjbGFzcyBpbnN0YW5jZSBjcmVhdGlvbiBleHByZXNzaW9uIHJhdGhlciB0aGFuIGEKICAgICAgICAgICAgICAgIC8vIGNsYXNzIGRlY2xhcmF0aW9uLgogICAgICAgICAgICAgICAgd3JpdGVyLnByaW50KCJuZXcgIik7CgogICAgICAgICAgICAgICAgLy8gSWYgdGhlIGFub255bW91cyBjbGFzcyBpbXBsZW1lbnRzIGFuIGludGVyZmFjZQogICAgICAgICAgICAgICAgLy8gcHJpbnQgdGhhdCBuYW1lLCBvdGhlcndpc2UgcHJpbnQgdGhlIHN1cGVyY2xhc3MuCiAgICAgICAgICAgICAgICBMaXN0PD8gZXh0ZW5kcyBUeXBlTWlycm9yPiBpbnRlcmZhY2VzID0gZS5nZXRJbnRlcmZhY2VzKCk7CiAgICAgICAgICAgICAgICBpZiAoIWludGVyZmFjZXMuaXNFbXB0eSgpKQogICAgICAgICAgICAgICAgICAgIHdyaXRlci5wcmludChpbnRlcmZhY2VzLmdldCgwKSk7CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgd3JpdGVyLnByaW50KGUuZ2V0U3VwZXJjbGFzcygpKTsKCiAgICAgICAgICAgICAgICB3cml0ZXIucHJpbnQoIigiKTsKICAgICAgICAgICAgICAgIC8vIEFub255bW91cyBjbGFzc2VzIHRoYXQgaW1wbGVtZW50IGFuIGludGVyZmFjZSBjYW4ndAogICAgICAgICAgICAgICAgLy8gaGF2ZSBhbnkgY29uc3RydWN0b3IgYXJndW1lbnRzLgogICAgICAgICAgICAgICAgaWYgKGludGVyZmFjZXMuaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gUHJpbnQgb3V0IHRoZSBwYXJhbWV0ZXIgbGlzdCBmcm9tIHRoZSBzb2xlCiAgICAgICAgICAgICAgICAgICAgLy8gY29uc3RydWN0b3IuICBGb3Igbm93LCBkb24ndCB0cnkgdG8gZWxpZGUgYW55CiAgICAgICAgICAgICAgICAgICAgLy8gc3ludGhldGljIHBhcmFtZXRlcnMgYnkgZGV0ZXJtaW5pbmcgaWYgdGhlCiAgICAgICAgICAgICAgICAgICAgLy8gYW5vbnltb3VzIGNsYXNzIGlzIGluIGEgc3RhdGljIGNvbnRleHQsIGV0Yy4KICAgICAgICAgICAgICAgICAgICBMaXN0PD8gZXh0ZW5kcyBFeGVjdXRhYmxlRWxlbWVudD4gY29uc3RydWN0b3JzID0KICAgICAgICAgICAgICAgICAgICAgICAgRWxlbWVudEZpbHRlci5jb25zdHJ1Y3RvcnNJbihlLmdldEVuY2xvc2VkRWxlbWVudHMoKSk7CgogICAgICAgICAgICAgICAgICAgIGlmICghY29uc3RydWN0b3JzLmlzRW1wdHkoKSkKICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnRQYXJhbWV0ZXJzKGNvbnN0cnVjdG9ycy5nZXQoMCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgd3JpdGVyLnByaW50KCIpIik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBpZiAobmVzdGluZ0tpbmQgPT0gVE9QX0xFVkVMKSB7CiAgICAgICAgICAgICAgICAgICAgUGFja2FnZUVsZW1lbnQgcGtnID0gZWxlbWVudFV0aWxzLmdldFBhY2thZ2VPZihlKTsKICAgICAgICAgICAgICAgICAgICBpZiAoIXBrZy5pc1VubmFtZWQoKSkKICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGVyLnByaW50KCJwYWNrYWdlICIgKyBwa2cuZ2V0UXVhbGlmaWVkTmFtZSgpICsgIjtcbiIpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGRlZmF1bHRBY3Rpb24oZSwgdHJ1ZSk7CgogICAgICAgICAgICAgICAgc3dpdGNoKGtpbmQpIHsKICAgICAgICAgICAgICAgIGNhc2UgQU5OT1RBVElPTl9UWVBFOgogICAgICAgICAgICAgICAgICAgIHdyaXRlci5wcmludCgiQGludGVyZmFjZSIpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICB3cml0ZXIucHJpbnQoU3RyaW5nVXRpbHMudG9Mb3dlckNhc2Uoa2luZC50b1N0cmluZygpKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB3cml0ZXIucHJpbnQoIiAiKTsKICAgICAgICAgICAgICAgIHdyaXRlci5wcmludChlLmdldFNpbXBsZU5hbWUoKSk7CgogICAgICAgICAgICAgICAgcHJpbnRGb3JtYWxUeXBlUGFyYW1ldGVycyhlLCBmYWxzZSk7CgogICAgICAgICAgICAgICAgLy8gUHJpbnQgc3VwZXJjbGFzcyBpbmZvcm1hdGlvbiBpZiBpbmZvcm1hdGl2ZQogICAgICAgICAgICAgICAgaWYgKGtpbmQgPT0gQ0xBU1MpIHsKICAgICAgICAgICAgICAgICAgICBUeXBlTWlycm9yIHN1cGVydHlwZSA9IGUuZ2V0U3VwZXJjbGFzcygpOwogICAgICAgICAgICAgICAgICAgIGlmIChzdXBlcnR5cGUuZ2V0S2luZCgpICE9IFR5cGVLaW5kLk5PTkUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgVHlwZUVsZW1lbnQgZTIgPSAoVHlwZUVsZW1lbnQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKERlY2xhcmVkVHlwZSkgc3VwZXJ0eXBlKS5hc0VsZW1lbnQoKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGUyLmdldFN1cGVyY2xhc3MoKS5nZXRLaW5kKCkgIT0gVHlwZUtpbmQuTk9ORSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlci5wcmludCgiIGV4dGVuZHMgIiArIHN1cGVydHlwZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHByaW50SW50ZXJmYWNlcyhlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICB3cml0ZXIucHJpbnRsbigiIHsiKTsKICAgICAgICAgICAgaW5kZW50YXRpb24rKzsKCiAgICAgICAgICAgIGlmIChraW5kID09IEVOVU0pIHsKICAgICAgICAgICAgICAgIExpc3Q8RWxlbWVudD4gZW5jbG9zZWRFbGVtZW50cyA9IG5ldyBBcnJheUxpc3Q8PihlLmdldEVuY2xvc2VkRWxlbWVudHMoKSk7CiAgICAgICAgICAgICAgICAvLyBIYW5kbGUgYW55IGVudW0gY29uc3RhbnRzIHNwZWNpYWxseSBiZWZvcmUgb3RoZXIgZW50aXRpZXMuCiAgICAgICAgICAgICAgICBMaXN0PEVsZW1lbnQ+IGVudW1Db25zdGFudHMgPSBuZXcgQXJyYXlMaXN0PD4oKTsKICAgICAgICAgICAgICAgIGZvcihFbGVtZW50IGVsZW1lbnQgOiBlbmNsb3NlZEVsZW1lbnRzKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGVsZW1lbnQuZ2V0S2luZCgpID09IEVOVU1fQ09OU1RBTlQpCiAgICAgICAgICAgICAgICAgICAgICAgIGVudW1Db25zdGFudHMuYWRkKGVsZW1lbnQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCFlbnVtQ29uc3RhbnRzLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgICAgICAgIGludCBpOwogICAgICAgICAgICAgICAgICAgIGZvcihpID0gMDsgaSA8IGVudW1Db25zdGFudHMuc2l6ZSgpLTE7IGkrKykgewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnZpc2l0KGVudW1Db25zdGFudHMuZ2V0KGkpLCB0cnVlKTsKICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGVyLnByaW50KCIsIik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHRoaXMudmlzaXQoZW51bUNvbnN0YW50cy5nZXQoaSksIHRydWUpOwogICAgICAgICAgICAgICAgICAgIHdyaXRlci5wcmludGxuKCI7XG4iKTsKCiAgICAgICAgICAgICAgICAgICAgZW5jbG9zZWRFbGVtZW50cy5yZW1vdmVBbGwoZW51bUNvbnN0YW50cyk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgZm9yKEVsZW1lbnQgZWxlbWVudCA6IGVuY2xvc2VkRWxlbWVudHMpCiAgICAgICAgICAgICAgICAgICAgdGhpcy52aXNpdChlbGVtZW50KTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGZvcihFbGVtZW50IGVsZW1lbnQgOiBlLmdldEVuY2xvc2VkRWxlbWVudHMoKSkKICAgICAgICAgICAgICAgICAgICB0aGlzLnZpc2l0KGVsZW1lbnQpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpbmRlbnRhdGlvbi0tOwogICAgICAgICAgICBpbmRlbnQoKTsKICAgICAgICAgICAgd3JpdGVyLnByaW50bG4oIn0iKTsKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICAgICAgcHVibGljIFByaW50aW5nRWxlbWVudFZpc2l0b3IgdmlzaXRWYXJpYWJsZShWYXJpYWJsZUVsZW1lbnQgZSwgQm9vbGVhbiBuZXdMaW5lKSB7CiAgICAgICAgICAgIEVsZW1lbnRLaW5kIGtpbmQgPSBlLmdldEtpbmQoKTsKICAgICAgICAgICAgZGVmYXVsdEFjdGlvbihlLCBuZXdMaW5lKTsKCiAgICAgICAgICAgIGlmIChraW5kID09IEVOVU1fQ09OU1RBTlQpCiAgICAgICAgICAgICAgICB3cml0ZXIucHJpbnQoZS5nZXRTaW1wbGVOYW1lKCkpOwogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIHdyaXRlci5wcmludChlLmFzVHlwZSgpLnRvU3RyaW5nKCkgKyAiICIgKyBlLmdldFNpbXBsZU5hbWUoKSApOwogICAgICAgICAgICAgICAgT2JqZWN0IGNvbnN0YW50VmFsdWUgID0gZS5nZXRDb25zdGFudFZhbHVlKCk7CiAgICAgICAgICAgICAgICBpZiAoY29uc3RhbnRWYWx1ZSAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgd3JpdGVyLnByaW50KCIgPSAiKTsKICAgICAgICAgICAgICAgICAgICB3cml0ZXIucHJpbnQoZWxlbWVudFV0aWxzLmdldENvbnN0YW50RXhwcmVzc2lvbihjb25zdGFudFZhbHVlKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB3cml0ZXIucHJpbnRsbigiOyIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyBQcmludGluZ0VsZW1lbnRWaXNpdG9yIHZpc2l0VHlwZVBhcmFtZXRlcihUeXBlUGFyYW1ldGVyRWxlbWVudCBlLCBCb29sZWFuIHApIHsKICAgICAgICAgICAgd3JpdGVyLnByaW50KGUuZ2V0U2ltcGxlTmFtZSgpKTsKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICAvLyBTaG91bGQgd2UgZG8gbW9yZSBoZXJlPwogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgICAgICBwdWJsaWMgUHJpbnRpbmdFbGVtZW50VmlzaXRvciB2aXNpdFBhY2thZ2UoUGFja2FnZUVsZW1lbnQgZSwgQm9vbGVhbiBwKSB7CiAgICAgICAgICAgIGRlZmF1bHRBY3Rpb24oZSwgZmFsc2UpOwogICAgICAgICAgICBpZiAoIWUuaXNVbm5hbWVkKCkpCiAgICAgICAgICAgICAgICB3cml0ZXIucHJpbnRsbigicGFja2FnZSAiICsgZS5nZXRRdWFsaWZpZWROYW1lKCkgKyAiOyIpOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB3cml0ZXIucHJpbnRsbigiLy8gVW5uYW1lZCBwYWNrYWdlIik7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyBQcmludGluZ0VsZW1lbnRWaXNpdG9yIHZpc2l0TW9kdWxlKE1vZHVsZUVsZW1lbnQgZSwgQm9vbGVhbiBwKSB7CiAgICAgICAgICAgIGRlZmF1bHRBY3Rpb24oZSwgZmFsc2UpOwoKICAgICAgICAgICAgaWYgKCFlLmlzVW5uYW1lZCgpKSB7CiAgICAgICAgICAgICAgICBpZiAoZS5pc09wZW4oKSkgewogICAgICAgICAgICAgICAgICAgIHdyaXRlci5wcmludCgib3BlbiAiKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHdyaXRlci5wcmludGxuKCJtb2R1bGUgIiArIGUuZ2V0UXVhbGlmaWVkTmFtZSgpICsgIiB7Iik7CiAgICAgICAgICAgICAgICBpbmRlbnRhdGlvbisrOwogICAgICAgICAgICAgICAgZm9yIChNb2R1bGVFbGVtZW50LkRpcmVjdGl2ZSBkaXJlY3RpdmUgOiBlLmdldERpcmVjdGl2ZXMoKSkgewogICAgICAgICAgICAgICAgICAgIHByaW50RGlyZWN0aXZlKGRpcmVjdGl2ZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbmRlbnRhdGlvbi0tOwogICAgICAgICAgICAgICAgd3JpdGVyLnByaW50bG4oIn0iKTsKICAgICAgICAgICAgfSBlbHNlCiAgICAgICAgICAgICAgICB3cml0ZXIucHJpbnRsbigiLy8gVW5uYW1lZCBtb2R1bGUiKTsgLy8gU2hvdWxkIHdlIGRvIG1vcmUgaGVyZT8KICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIHZvaWQgcHJpbnREaXJlY3RpdmUoTW9kdWxlRWxlbWVudC5EaXJlY3RpdmUgZGlyZWN0aXZlKSB7CiAgICAgICAgICAgIGluZGVudCgpOwogICAgICAgICAgICBzd2l0Y2ggKGRpcmVjdGl2ZS5nZXRLaW5kKCkpIHsKICAgICAgICAgICAgY2FzZSBFWFBPUlRTOiAvLyAiZXhwb3J0cyBwYWNrYWdlLW5hbWUgW3RvIG1vZHVsZS1uYW1lLWxpc3RdIgogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIEV4cG9ydHNEaXJlY3RpdmUgZXhwb3J0c0RpcmVjdGl2ZSA9IChFeHBvcnRzRGlyZWN0aXZlKSBkaXJlY3RpdmU7CiAgICAgICAgICAgICAgICAgICAgd3JpdGVyLnByaW50KCJleHBvcnRzICIpOwogICAgICAgICAgICAgICAgICAgIHdyaXRlci5wcmludChleHBvcnRzRGlyZWN0aXZlLmdldFBhY2thZ2UoKS5nZXRRdWFsaWZpZWROYW1lKCkpOwogICAgICAgICAgICAgICAgICAgIHByaW50TW9kdWxlTGlzdChleHBvcnRzRGlyZWN0aXZlLmdldFRhcmdldE1vZHVsZXMoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgT1BFTlM6IC8vIG9wZW5zIHBhY2thZ2UtbmFtZSBbdG8gbW9kdWxlLW5hbWUtbGlzdF0KICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBPcGVuc0RpcmVjdGl2ZSBvcGVuc0RpcmVjdGl2ZSA9IChPcGVuc0RpcmVjdGl2ZSkgZGlyZWN0aXZlOwogICAgICAgICAgICAgICAgICAgIHdyaXRlci5wcmludCgib3BlbnMgIik7CiAgICAgICAgICAgICAgICAgICAgd3JpdGVyLnByaW50KG9wZW5zRGlyZWN0aXZlLmdldFBhY2thZ2UoKS5nZXRRdWFsaWZpZWROYW1lKCkpOwogICAgICAgICAgICAgICAgICAgIHByaW50TW9kdWxlTGlzdChvcGVuc0RpcmVjdGl2ZS5nZXRUYXJnZXRNb2R1bGVzKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIFBST1ZJREVTOiAvLyBwcm92aWRlcyBzZXJ2aWNlLW5hbWUgd2l0aCBpbXBsZW1lbnRhdGlvbi1uYW1lCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgUHJvdmlkZXNEaXJlY3RpdmUgcHJvdmlkZXNEaXJlY3RpdmUgPSAoUHJvdmlkZXNEaXJlY3RpdmUpIGRpcmVjdGl2ZTsKICAgICAgICAgICAgICAgICAgICB3cml0ZXIucHJpbnQoInByb3ZpZGVzICIpOwogICAgICAgICAgICAgICAgICAgIHdyaXRlci5wcmludChwcm92aWRlc0RpcmVjdGl2ZS5nZXRTZXJ2aWNlKCkuZ2V0UXVhbGlmaWVkTmFtZSgpKTsKICAgICAgICAgICAgICAgICAgICB3cml0ZXIucHJpbnQoIiB3aXRoICIpOwogICAgICAgICAgICAgICAgICAgIHByaW50TmFtZWFibGVMaXN0KHByb3ZpZGVzRGlyZWN0aXZlLmdldEltcGxlbWVudGF0aW9ucygpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBSRVFVSVJFUzogLy8gcmVxdWlyZXMgKHN0YXRpY3x0cmFuc2l0aXZlKSogbW9kdWxlLW5hbWUKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBSZXF1aXJlc0RpcmVjdGl2ZSByZXF1aXJlc0RpcmVjdGl2ZSA9IChSZXF1aXJlc0RpcmVjdGl2ZSkgZGlyZWN0aXZlOwogICAgICAgICAgICAgICAgICAgIHdyaXRlci5wcmludCgicmVxdWlyZXMgIik7CiAgICAgICAgICAgICAgICAgICAgaWYgKHJlcXVpcmVzRGlyZWN0aXZlLmlzU3RhdGljKCkpCiAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlci5wcmludCgic3RhdGljICIpOwogICAgICAgICAgICAgICAgICAgIGlmIChyZXF1aXJlc0RpcmVjdGl2ZS5pc1RyYW5zaXRpdmUoKSkKICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGVyLnByaW50KCJ0cmFuc2l0aXZlICIpOwogICAgICAgICAgICAgICAgICAgIHdyaXRlci5wcmludChyZXF1aXJlc0RpcmVjdGl2ZS5nZXREZXBlbmRlbmN5KCkuZ2V0UXVhbGlmaWVkTmFtZSgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBVU0VTOiAvLyB1c2VzIHNlcnZpY2UtbmFtZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIFVzZXNEaXJlY3RpdmUgdXNlc0RpcmVjdGl2ZSA9IChVc2VzRGlyZWN0aXZlKSBkaXJlY3RpdmU7CiAgICAgICAgICAgICAgICAgICAgd3JpdGVyLnByaW50KCJ1c2VzICIpOwogICAgICAgICAgICAgICAgICAgIHdyaXRlci5wcmludCh1c2VzRGlyZWN0aXZlLmdldFNlcnZpY2UoKS5nZXRRdWFsaWZpZWROYW1lKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJ1bmtub3duIGRpcmVjdGl2ZSAiICsgZGlyZWN0aXZlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICB3cml0ZXIucHJpbnRsbigiOyIpOwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSB2b2lkIHByaW50TW9kdWxlTGlzdChMaXN0PD8gZXh0ZW5kcyBNb2R1bGVFbGVtZW50PiBtb2R1bGVzKSB7CiAgICAgICAgICAgIGlmIChtb2R1bGVzICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIHdyaXRlci5wcmludCgiIHRvICIpOwogICAgICAgICAgICAgICAgcHJpbnROYW1lYWJsZUxpc3QobW9kdWxlcyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHByaXZhdGUgdm9pZCBwcmludE5hbWVhYmxlTGlzdChMaXN0PD8gZXh0ZW5kcyBRdWFsaWZpZWROYW1lYWJsZT4gbmFtZWFibGVzKSB7CiAgICAgICAgICAgICAgICB3cml0ZXIucHJpbnQobmFtZWFibGVzLnN0cmVhbSgpLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hcChRdWFsaWZpZWROYW1lYWJsZTo6Z2V0UXVhbGlmaWVkTmFtZSkuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sbGVjdChDb2xsZWN0b3JzLmpvaW5pbmcoIiwgIikpKTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyB2b2lkIGZsdXNoKCkgewogICAgICAgICAgICB3cml0ZXIuZmx1c2goKTsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgdm9pZCBwcmludERvY0NvbW1lbnQoRWxlbWVudCBlKSB7CiAgICAgICAgICAgIFN0cmluZyBkb2NDb21tZW50ID0gZWxlbWVudFV0aWxzLmdldERvY0NvbW1lbnQoZSk7CgogICAgICAgICAgICBpZiAoZG9jQ29tbWVudCAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAvLyBCcmVhayBjb21tZW50IGludG8gbGluZXMKICAgICAgICAgICAgICAgIGphdmEudXRpbC5TdHJpbmdUb2tlbml6ZXIgc3QgPSBuZXcgU3RyaW5nVG9rZW5pemVyKGRvY0NvbW1lbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJcblxyIik7CiAgICAgICAgICAgICAgICBpbmRlbnQoKTsKICAgICAgICAgICAgICAgIHdyaXRlci5wcmludGxuKCIvKioiKTsKCiAgICAgICAgICAgICAgICB3aGlsZShzdC5oYXNNb3JlVG9rZW5zKCkpIHsKICAgICAgICAgICAgICAgICAgICBpbmRlbnQoKTsKICAgICAgICAgICAgICAgICAgICB3cml0ZXIucHJpbnQoIiAqIik7CiAgICAgICAgICAgICAgICAgICAgd3JpdGVyLnByaW50bG4oc3QubmV4dFRva2VuKCkpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGluZGVudCgpOwogICAgICAgICAgICAgICAgd3JpdGVyLnByaW50bG4oIiAqLyIpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIHZvaWQgcHJpbnRNb2RpZmllcnMoRWxlbWVudCBlKSB7CiAgICAgICAgICAgIEVsZW1lbnRLaW5kIGtpbmQgPSBlLmdldEtpbmQoKTsKICAgICAgICAgICAgaWYgKGtpbmQgPT0gUEFSQU1FVEVSKSB7CiAgICAgICAgICAgICAgICBwcmludEFubm90YXRpb25zSW5saW5lKGUpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcHJpbnRBbm5vdGF0aW9ucyhlKTsKICAgICAgICAgICAgICAgIGluZGVudCgpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoa2luZCA9PSBFTlVNX0NPTlNUQU5UKQogICAgICAgICAgICAgICAgcmV0dXJuOwoKICAgICAgICAgICAgU2V0PE1vZGlmaWVyPiBtb2RpZmllcnMgPSBuZXcgTGlua2VkSGFzaFNldDw+KCk7CiAgICAgICAgICAgIG1vZGlmaWVycy5hZGRBbGwoZS5nZXRNb2RpZmllcnMoKSk7CgogICAgICAgICAgICBzd2l0Y2ggKGtpbmQpIHsKICAgICAgICAgICAgY2FzZSBBTk5PVEFUSU9OX1RZUEU6CiAgICAgICAgICAgIGNhc2UgSU5URVJGQUNFOgogICAgICAgICAgICAgICAgbW9kaWZpZXJzLnJlbW92ZShNb2RpZmllci5BQlNUUkFDVCk7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgRU5VTToKICAgICAgICAgICAgICAgIG1vZGlmaWVycy5yZW1vdmUoTW9kaWZpZXIuRklOQUwpOwogICAgICAgICAgICAgICAgbW9kaWZpZXJzLnJlbW92ZShNb2RpZmllci5BQlNUUkFDVCk7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgTUVUSE9EOgogICAgICAgICAgICBjYXNlIEZJRUxEOgogICAgICAgICAgICAgICAgRWxlbWVudCBlbmNsb3NpbmdFbGVtZW50ID0gZS5nZXRFbmNsb3NpbmdFbGVtZW50KCk7CiAgICAgICAgICAgICAgICBpZiAoZW5jbG9zaW5nRWxlbWVudCAhPSBudWxsICYmCiAgICAgICAgICAgICAgICAgICAgZW5jbG9zaW5nRWxlbWVudC5nZXRLaW5kKCkuaXNJbnRlcmZhY2UoKSkgewogICAgICAgICAgICAgICAgICAgIG1vZGlmaWVycy5yZW1vdmUoTW9kaWZpZXIuUFVCTElDKTsKICAgICAgICAgICAgICAgICAgICBtb2RpZmllcnMucmVtb3ZlKE1vZGlmaWVyLkFCU1RSQUNUKTsgLy8gb25seSBmb3IgbWV0aG9kcwogICAgICAgICAgICAgICAgICAgIG1vZGlmaWVycy5yZW1vdmUoTW9kaWZpZXIuU1RBVElDKTsgICAvLyBvbmx5IGZvciBmaWVsZHMKICAgICAgICAgICAgICAgICAgICBtb2RpZmllcnMucmVtb3ZlKE1vZGlmaWVyLkZJTkFMKTsgICAgLy8gb25seSBmb3IgZmllbGRzCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGZvcihNb2RpZmllciBtOiBtb2RpZmllcnMpIHsKICAgICAgICAgICAgICAgIHdyaXRlci5wcmludChtLnRvU3RyaW5nKCkgKyAiICIpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIHZvaWQgcHJpbnRGb3JtYWxUeXBlUGFyYW1ldGVycyhQYXJhbWV0ZXJpemFibGUgZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIHBhZCkgewogICAgICAgICAgICBMaXN0PD8gZXh0ZW5kcyBUeXBlUGFyYW1ldGVyRWxlbWVudD4gdHlwZVBhcmFtcyA9IGUuZ2V0VHlwZVBhcmFtZXRlcnMoKTsKICAgICAgICAgICAgaWYgKHR5cGVQYXJhbXMuc2l6ZSgpID4gMCkgewogICAgICAgICAgICAgICAgd3JpdGVyLnByaW50KCI8Iik7CgogICAgICAgICAgICAgICAgYm9vbGVhbiBmaXJzdCA9IHRydWU7CiAgICAgICAgICAgICAgICBmb3IoVHlwZVBhcmFtZXRlckVsZW1lbnQgdHBlOiB0eXBlUGFyYW1zKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCFmaXJzdCkKICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGVyLnByaW50KCIsICIpOwogICAgICAgICAgICAgICAgICAgIHByaW50QW5ub3RhdGlvbnNJbmxpbmUodHBlKTsKICAgICAgICAgICAgICAgICAgICB3cml0ZXIucHJpbnQodHBlLnRvU3RyaW5nKCkpOwogICAgICAgICAgICAgICAgICAgIGZpcnN0ID0gZmFsc2U7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgd3JpdGVyLnByaW50KCI+Iik7CiAgICAgICAgICAgICAgICBpZiAocGFkKQogICAgICAgICAgICAgICAgICAgIHdyaXRlci5wcmludCgiICIpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIHZvaWQgcHJpbnRBbm5vdGF0aW9uc0lubGluZShFbGVtZW50IGUpIHsKICAgICAgICAgICAgTGlzdDw/IGV4dGVuZHMgQW5ub3RhdGlvbk1pcnJvcj4gYW5ub3RzID0gZS5nZXRBbm5vdGF0aW9uTWlycm9ycygpOwogICAgICAgICAgICBmb3IoQW5ub3RhdGlvbk1pcnJvciBhbm5vdGF0aW9uTWlycm9yIDogYW5ub3RzKSB7CiAgICAgICAgICAgICAgICB3cml0ZXIucHJpbnQoYW5ub3RhdGlvbk1pcnJvcik7CiAgICAgICAgICAgICAgICB3cml0ZXIucHJpbnQoIiAiKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSB2b2lkIHByaW50QW5ub3RhdGlvbnMoRWxlbWVudCBlKSB7CiAgICAgICAgICAgIExpc3Q8PyBleHRlbmRzIEFubm90YXRpb25NaXJyb3I+IGFubm90cyA9IGUuZ2V0QW5ub3RhdGlvbk1pcnJvcnMoKTsKICAgICAgICAgICAgZm9yKEFubm90YXRpb25NaXJyb3IgYW5ub3RhdGlvbk1pcnJvciA6IGFubm90cykgewogICAgICAgICAgICAgICAgaW5kZW50KCk7CiAgICAgICAgICAgICAgICB3cml0ZXIucHJpbnRsbihhbm5vdGF0aW9uTWlycm9yKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gVE9ETzogUmVmYWN0b3IKICAgICAgICBwcml2YXRlIHZvaWQgcHJpbnRQYXJhbWV0ZXJzKEV4ZWN1dGFibGVFbGVtZW50IGUpIHsKICAgICAgICAgICAgTGlzdDw/IGV4dGVuZHMgVmFyaWFibGVFbGVtZW50PiBwYXJhbWV0ZXJzID0gZS5nZXRQYXJhbWV0ZXJzKCk7CiAgICAgICAgICAgIGludCBzaXplID0gcGFyYW1ldGVycy5zaXplKCk7CgogICAgICAgICAgICBzd2l0Y2ggKHNpemUpIHsKICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIDE6CiAgICAgICAgICAgICAgICBmb3IoVmFyaWFibGVFbGVtZW50IHBhcmFtZXRlcjogcGFyYW1ldGVycykgewogICAgICAgICAgICAgICAgICAgIHByaW50TW9kaWZpZXJzKHBhcmFtZXRlcik7CgogICAgICAgICAgICAgICAgICAgIGlmIChlLmlzVmFyQXJncygpICkgewogICAgICAgICAgICAgICAgICAgICAgICBUeXBlTWlycm9yIHRtID0gcGFyYW1ldGVyLmFzVHlwZSgpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAodG0uZ2V0S2luZCgpICE9IFR5cGVLaW5kLkFSUkFZKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCJWYXItYXJncyBwYXJhbWV0ZXIgaXMgbm90IGFuIGFycmF5IHR5cGU6ICIgKyB0bSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlci5wcmludCgoQXJyYXlUeXBlLmNsYXNzLmNhc3QodG0pKS5nZXRDb21wb25lbnRUeXBlKCkgKTsKICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGVyLnByaW50KCIuLi4iKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGVyLnByaW50KHBhcmFtZXRlci5hc1R5cGUoKSk7CiAgICAgICAgICAgICAgICAgICAgd3JpdGVyLnByaW50KCIgIiArIHBhcmFtZXRlci5nZXRTaW1wbGVOYW1lKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGludCBpID0gMTsKICAgICAgICAgICAgICAgICAgICBmb3IoVmFyaWFibGVFbGVtZW50IHBhcmFtZXRlcjogcGFyYW1ldGVycykgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoaSA9PSAyKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5kZW50YXRpb24rKzsKCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpID4gMSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZGVudCgpOwoKICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnRNb2RpZmllcnMocGFyYW1ldGVyKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpID09IHNpemUgJiYgZS5pc1ZhckFyZ3MoKSApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFR5cGVNaXJyb3IgdG0gPSBwYXJhbWV0ZXIuYXNUeXBlKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodG0uZ2V0S2luZCgpICE9IFR5cGVLaW5kLkFSUkFZKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigiVmFyLWFyZ3MgcGFyYW1ldGVyIGlzIG5vdCBhbiBhcnJheSB0eXBlOiAiICsgdG0pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3cml0ZXIucHJpbnQoKEFycmF5VHlwZS5jbGFzcy5jYXN0KHRtKSkuZ2V0Q29tcG9uZW50VHlwZSgpICk7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGVyLnByaW50KCIuLi4iKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3cml0ZXIucHJpbnQocGFyYW1ldGVyLmFzVHlwZSgpKTsKICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGVyLnByaW50KCIgIiArIHBhcmFtZXRlci5nZXRTaW1wbGVOYW1lKCkpOwoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGkgPCBzaXplKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGVyLnByaW50bG4oIiwiKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIGkrKzsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGlmIChwYXJhbWV0ZXJzLnNpemUoKSA+PSAyKQogICAgICAgICAgICAgICAgICAgICAgICBpbmRlbnRhdGlvbi0tOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHByaXZhdGUgdm9pZCBwcmludEludGVyZmFjZXMoVHlwZUVsZW1lbnQgZSkgewogICAgICAgICAgICBFbGVtZW50S2luZCBraW5kID0gZS5nZXRLaW5kKCk7CgogICAgICAgICAgICBpZihraW5kICE9IEFOTk9UQVRJT05fVFlQRSkgewogICAgICAgICAgICAgICAgTGlzdDw/IGV4dGVuZHMgVHlwZU1pcnJvcj4gaW50ZXJmYWNlcyA9IGUuZ2V0SW50ZXJmYWNlcygpOwogICAgICAgICAgICAgICAgaWYgKGludGVyZmFjZXMuc2l6ZSgpID4gMCkgewogICAgICAgICAgICAgICAgICAgIHdyaXRlci5wcmludCgoa2luZC5pc0NsYXNzKCkgPyAiIGltcGxlbWVudHMiIDogIiBleHRlbmRzIikpOwoKICAgICAgICAgICAgICAgICAgICBib29sZWFuIGZpcnN0ID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBmb3IoVHlwZU1pcnJvciBpbnRlcmY6IGludGVyZmFjZXMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFmaXJzdCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlci5wcmludCgiLCIpOwogICAgICAgICAgICAgICAgICAgICAgICB3cml0ZXIucHJpbnQoIiAiKTsKICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGVyLnByaW50KGludGVyZi50b1N0cmluZygpKTsKICAgICAgICAgICAgICAgICAgICAgICAgZmlyc3QgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHByaXZhdGUgdm9pZCBwcmludFRocm93cyhFeGVjdXRhYmxlRWxlbWVudCBlKSB7CiAgICAgICAgICAgIExpc3Q8PyBleHRlbmRzIFR5cGVNaXJyb3I+IHRocm93blR5cGVzID0gZS5nZXRUaHJvd25UeXBlcygpOwogICAgICAgICAgICBmaW5hbCBpbnQgc2l6ZSA9IHRocm93blR5cGVzLnNpemUoKTsKICAgICAgICAgICAgaWYgKHNpemUgIT0gMCkgewogICAgICAgICAgICAgICAgd3JpdGVyLnByaW50KCIgdGhyb3dzIik7CgogICAgICAgICAgICAgICAgaW50IGkgPSAxOwogICAgICAgICAgICAgICAgZm9yKFR5cGVNaXJyb3IgdGhyb3duVHlwZTogdGhyb3duVHlwZXMpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoaSA9PSAxKQogICAgICAgICAgICAgICAgICAgICAgICB3cml0ZXIucHJpbnQoIiAiKTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKGkgPT0gMikKICAgICAgICAgICAgICAgICAgICAgICAgaW5kZW50YXRpb24rKzsKCiAgICAgICAgICAgICAgICAgICAgaWYgKGkgPj0gMikKICAgICAgICAgICAgICAgICAgICAgICAgaW5kZW50KCk7CgogICAgICAgICAgICAgICAgICAgIHdyaXRlci5wcmludCh0aHJvd25UeXBlKTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKGkgIT0gc2l6ZSkKICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGVyLnByaW50bG4oIiwgIik7CgogICAgICAgICAgICAgICAgICAgIGkrKzsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoc2l6ZSA+PSAyKQogICAgICAgICAgICAgICAgICAgIGluZGVudGF0aW9uLS07CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBbXSBzcGFjZXMgPSB7CiAgICAgICAgICAgICIiLAogICAgICAgICAgICAiICAiLAogICAgICAgICAgICAiICAgICIsCiAgICAgICAgICAgICIgICAgICAiLAogICAgICAgICAgICAiICAgICAgICAiLAogICAgICAgICAgICAiICAgICAgICAgICIsCiAgICAgICAgICAgICIgICAgICAgICAgICAiLAogICAgICAgICAgICAiICAgICAgICAgICAgICAiLAogICAgICAgICAgICAiICAgICAgICAgICAgICAgICIsCiAgICAgICAgICAgICIgICAgICAgICAgICAgICAgICAiLAogICAgICAgICAgICAiICAgICAgICAgICAgICAgICAgICAiCiAgICAgICAgfTsKCiAgICAgICAgcHJpdmF0ZSB2b2lkIGluZGVudCgpIHsKICAgICAgICAgICAgaW50IGluZGVudGF0aW9uID0gdGhpcy5pbmRlbnRhdGlvbjsKICAgICAgICAgICAgaWYgKGluZGVudGF0aW9uIDwgMCkKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgZmluYWwgaW50IG1heEluZGV4ID0gc3BhY2VzLmxlbmd0aCAtIDE7CgogICAgICAgICAgICB3aGlsZSAoaW5kZW50YXRpb24gPiBtYXhJbmRleCkgewogICAgICAgICAgICAgICAgd3JpdGVyLnByaW50KHNwYWNlc1ttYXhJbmRleF0pOwogICAgICAgICAgICAgICAgaW5kZW50YXRpb24gLT0gbWF4SW5kZXg7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgd3JpdGVyLnByaW50KHNwYWNlc1tpbmRlbnRhdGlvbl0pOwogICAgICAgIH0KCiAgICB9Cn0KUEsDBAoAAAgAAAY7qUqlLvD9mHEAAJhxAAAuAAAAY29tL3N1bi90b29scy9qYXZhYy9wcm9jZXNzaW5nL0phdmFjRmlsZXIuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAxNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLmphdmFjLnByb2Nlc3Npbmc7CgppbXBvcnQgamF2YS5pby5DbG9zZWFibGU7CmltcG9ydCBqYXZhLmlvLkZpbGVOb3RGb3VuZEV4Y2VwdGlvbjsKaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CmltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKaW1wb3J0IGphdmEuaW8uRmlsdGVyT3V0cHV0U3RyZWFtOwppbXBvcnQgamF2YS5pby5SZWFkZXI7CmltcG9ydCBqYXZhLmlvLldyaXRlcjsKaW1wb3J0IGphdmEuaW8uRmlsdGVyV3JpdGVyOwppbXBvcnQgamF2YS5pby5QcmludFdyaXRlcjsKaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CmltcG9ydCBqYXZhLnV0aWwuKjsKCmltcG9ydCBzdGF0aWMgamF2YS51dGlsLkNvbGxlY3Rpb25zLio7CgppbXBvcnQgamF2YXguYW5ub3RhdGlvbi5wcm9jZXNzaW5nLio7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLlNvdXJjZVZlcnNpb247CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuTmVzdGluZ0tpbmQ7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuTW9kaWZpZXI7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuRWxlbWVudDsKaW1wb3J0IGphdmF4LnRvb2xzLio7CmltcG9ydCBqYXZheC50b29scy5KYXZhRmlsZU1hbmFnZXIuTG9jYXRpb247CgppbXBvcnQgc3RhdGljIGphdmF4LnRvb2xzLlN0YW5kYXJkTG9jYXRpb24uU09VUkNFX09VVFBVVDsKaW1wb3J0IHN0YXRpYyBqYXZheC50b29scy5TdGFuZGFyZExvY2F0aW9uLkNMQVNTX09VVFBVVDsKCmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuTGludDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5TeW1ib2wuQ2xhc3NTeW1ib2w7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuU3ltYm9sLk1vZHVsZVN5bWJvbDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5TeW10YWI7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvbXAuTW9kdWxlczsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMubW9kZWwuSmF2YWNFbGVtZW50czsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC4qOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkRlZmluZWRCeS5BcGk7CgppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5MaW50LkxpbnRDYXRlZ29yeS5QUk9DRVNTSU5HOwoKLyoqCiAqIFRoZSBGaWxlckltcGxlbWVudGF0aW9uIGNsYXNzIG11c3QgbWFpbnRhaW4gYSBudW1iZXIgb2YKICogY29uc3RyYWludHMuICBGaXJzdCwgbXVsdGlwbGUgYXR0ZW1wdHMgdG8gb3BlbiB0aGUgc2FtZSBwYXRoIHdpdGhpbgogKiB0aGUgc2FtZSBpbnZvY2F0aW9uIG9mIHRoZSB0b29sIHJlc3VsdHMgaW4gYW4gSU9FeGNlcHRpb24gYmVpbmcKICogdGhyb3duLiAgRm9yIGV4YW1wbGUsIHRyeWluZyB0byBvcGVuIHRoZSBzYW1lIHNvdXJjZSBmaWxlIHR3aWNlOgogKgogKiA8cHJlPgogKiBjcmVhdGVTb3VyY2VGaWxlKCJmb28uQmFyIikKICogLi4uCiAqIGNyZWF0ZVNvdXJjZUZpbGUoImZvby5CYXIiKQogKiA8L3ByZT4KICoKICogaXMgZGlzYWxsb3dlZCBhcyBpcyBvcGVuaW5nIGEgdGV4dCBmaWxlIHRoYXQgaGFwcGVucyB0byBoYXZlCiAqIHRoZSBzYW1lIG5hbWUgYXMgYSBzb3VyY2UgZmlsZToKICoKICogPHByZT4KICogY3JlYXRlU291cmNlRmlsZSgiZm9vLkJhciIpCiAqIC4uLgogKiBjcmVhdGVUZXh0RmlsZShTT1VSQ0VfVFJFRSwgImZvbyIsIG5ldyBGaWxlKCJCYXIiKSwgbnVsbCkKICogPC9wcmU+CiAqCiAqIDxwPkFkZGl0aW9uYWxseSwgY3JlYXRpbmcgYSBzb3VyY2UgZmlsZSB0aGF0IGNvcnJlc3BvbmRzIHRvIGFuCiAqIGFscmVhZHkgY3JlYXRlZCBjbGFzcyBmaWxlIChvciB2aWNlIHZlcnNhKSBhbHNvIHJlc3VsdHMgaW4gYW4KICogSU9FeGNlcHRpb24gc2luY2UgZWFjaCB0eXBlIGNhbiBvbmx5IGJlIGNyZWF0ZWQgb25jZS4gIEhvd2V2ZXIsIGlmCiAqIHRoZSBGaWxlciBpcyB1c2VkIHRvIGNyZWF0ZSBhIHRleHQgZmlsZSBuYW1lZCAqLmphdmEgdGhhdCBoYXBwZW5zCiAqIHRvIGNvcnJlc3BvbmQgdG8gYW4gZXhpc3RpbmcgY2xhc3MgZmlsZSwgYSB3YXJuaW5nIGlzICpub3QqCiAqIGdlbmVyYXRlZC4gIFNpbWlsYXJseSwgYSB3YXJuaW5nIGlzIG5vdCBnZW5lcmF0ZWQgZm9yIGEgYmluYXJ5IGZpbGUKICogbmFtZWQgKi5jbGFzcyBhbmQgYW4gZXhpc3Rpbmcgc291cmNlIGZpbGUuCiAqCiAqIDxwPlRoZSByZWFzb24gZm9yIHRoaXMgZGlmZmVyZW5jZSBpcyB0aGF0IHNvdXJjZSBmaWxlcyBhbmQgY2xhc3MKICogZmlsZXMgYXJlIHJlZ2lzdGVyZWQgd2l0aCB0aGUgdG9vbCBhbmQgY2FuIGdldCBwYXNzZWQgb24gYXMKICogZGVjbGFyYXRpb25zIHRvIHRoZSBuZXh0IHJvdW5kIG9mIHByb2Nlc3NpbmcuICBGaWxlcyB0aGF0IGFyZSBqdXN0CiAqIG5hbWVkICouamF2YSBhbmQgKi5jbGFzcyBhcmUgbm90IHByb2Nlc3NlZCBpbiB0aGF0IG1hbm5lcjsgYWx0aG91Z2gKICogaGF2aW5nIGV4dHJhIHNvdXJjZSBmaWxlcyBhbmQgY2xhc3MgZmlsZXMgb24gdGhlIHNvdXJjZSBwYXRoIGFuZAogKiBjbGFzcyBwYXRoIGNhbiBhbHRlciB0aGUgYmVoYXZpb3Igb2YgdGhlIHRvb2wgYW5kIGFueSBmaW5hbAogKiBjb21waWxlLgogKgogKiA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yCiAqIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj4KICovCnB1YmxpYyBjbGFzcyBKYXZhY0ZpbGVyIGltcGxlbWVudHMgRmlsZXIsIENsb3NlYWJsZSB7CiAgICAvLyBUT0RPOiBJbXBsZW1lbnQgZGlmZmVyZW50IHRyYW5zYWN0aW9uIG1vZGVsIGZvciB1cGRhdGluZyB0aGUKICAgIC8vIEZpbGVyJ3MgcmVjb3JkIGtlZXBpbmcgb24gZmlsZSBjbG9zZS4KCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgQUxSRUFEWV9PUEVORUQgPQogICAgICAgICJPdXRwdXQgc3RyZWFtIG9yIHdyaXRlciBoYXMgYWxyZWFkeSBiZWVuIG9wZW5lZC4iOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIE5PVF9GT1JfUkVBRElORyA9CiAgICAgICAgIkZpbGVPYmplY3Qgd2FzIG5vdCBvcGVuZWQgZm9yIHJlYWRpbmcuIjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBOT1RfRk9SX1dSSVRJTkcgPQogICAgICAgICJGaWxlT2JqZWN0IHdhcyBub3Qgb3BlbmVkIGZvciB3cml0aW5nLiI7CgogICAgLyoqCiAgICAgKiBXcmFwIGEgSmF2YUZpbGVPYmplY3QgdG8gbWFuYWdlIHdyaXRpbmcgYnkgdGhlIEZpbGVyLgogICAgICovCiAgICBwcml2YXRlIGNsYXNzIEZpbGVyT3V0cHV0RmlsZU9iamVjdCBleHRlbmRzIEZvcndhcmRpbmdGaWxlT2JqZWN0PEZpbGVPYmplY3Q+IHsKICAgICAgICBwcml2YXRlIGJvb2xlYW4gb3BlbmVkID0gZmFsc2U7CiAgICAgICAgcHJpdmF0ZSBNb2R1bGVTeW1ib2wgbW9kOwogICAgICAgIHByaXZhdGUgU3RyaW5nIG5hbWU7CgogICAgICAgIEZpbGVyT3V0cHV0RmlsZU9iamVjdChNb2R1bGVTeW1ib2wgbW9kLCBTdHJpbmcgbmFtZSwgRmlsZU9iamVjdCBmaWxlT2JqZWN0KSB7CiAgICAgICAgICAgIHN1cGVyKGZpbGVPYmplY3QpOwogICAgICAgICAgICB0aGlzLm1vZCA9IG1vZDsKICAgICAgICAgICAgdGhpcy5uYW1lID0gbmFtZTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgICAgICBwdWJsaWMgc3luY2hyb25pemVkIE91dHB1dFN0cmVhbSBvcGVuT3V0cHV0U3RyZWFtKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICAgICAgaWYgKG9wZW5lZCkKICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbihBTFJFQURZX09QRU5FRCk7CiAgICAgICAgICAgIG9wZW5lZCA9IHRydWU7CiAgICAgICAgICAgIHJldHVybiBuZXcgRmlsZXJPdXRwdXRTdHJlYW0obW9kLCBuYW1lLCBmaWxlT2JqZWN0KTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgICAgICBwdWJsaWMgc3luY2hyb25pemVkIFdyaXRlciBvcGVuV3JpdGVyKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICAgICAgaWYgKG9wZW5lZCkKICAgICAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbihBTFJFQURZX09QRU5FRCk7CiAgICAgICAgICAgIG9wZW5lZCA9IHRydWU7CiAgICAgICAgICAgIHJldHVybiBuZXcgRmlsZXJXcml0ZXIobW9kLCBuYW1lLCBmaWxlT2JqZWN0KTsKICAgICAgICB9CgogICAgICAgIC8vIFRocmVlIGFudGktbGl0ZXJhY3kgbWV0aG9kcwogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgICAgICBwdWJsaWMgSW5wdXRTdHJlYW0gb3BlbklucHV0U3RyZWFtKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbihOT1RfRk9SX1JFQURJTkcpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSKQogICAgICAgIHB1YmxpYyBSZWFkZXIgb3BlblJlYWRlcihib29sZWFuIGlnbm9yZUVuY29kaW5nRXJyb3JzKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKE5PVF9GT1JfUkVBRElORyk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICAgICAgcHVibGljIENoYXJTZXF1ZW5jZSBnZXRDaGFyQ29udGVudChib29sZWFuIGlnbm9yZUVuY29kaW5nRXJyb3JzKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKE5PVF9GT1JfUkVBRElORyk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICAgICAgcHVibGljIGJvb2xlYW4gZGVsZXRlKCkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgY2xhc3MgRmlsZXJPdXRwdXRKYXZhRmlsZU9iamVjdCBleHRlbmRzIEZpbGVyT3V0cHV0RmlsZU9iamVjdCBpbXBsZW1lbnRzIEphdmFGaWxlT2JqZWN0IHsKICAgICAgICBwcml2YXRlIGZpbmFsIEphdmFGaWxlT2JqZWN0IGphdmFGaWxlT2JqZWN0OwogICAgICAgIEZpbGVyT3V0cHV0SmF2YUZpbGVPYmplY3QoTW9kdWxlU3ltYm9sIG1vZCwgU3RyaW5nIG5hbWUsIEphdmFGaWxlT2JqZWN0IGphdmFGaWxlT2JqZWN0KSB7CiAgICAgICAgICAgIHN1cGVyKG1vZCwgbmFtZSwgamF2YUZpbGVPYmplY3QpOwogICAgICAgICAgICB0aGlzLmphdmFGaWxlT2JqZWN0ID0gamF2YUZpbGVPYmplY3Q7CiAgICAgICAgfQoKICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgICAgICBwdWJsaWMgSmF2YUZpbGVPYmplY3QuS2luZCBnZXRLaW5kKCkgewogICAgICAgICAgICByZXR1cm4gamF2YUZpbGVPYmplY3QuZ2V0S2luZCgpOwogICAgICAgIH0KCiAgICAgICAgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICAgICAgcHVibGljIGJvb2xlYW4gaXNOYW1lQ29tcGF0aWJsZShTdHJpbmcgc2ltcGxlTmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEphdmFGaWxlT2JqZWN0LktpbmQga2luZCkgewogICAgICAgICAgICByZXR1cm4gamF2YUZpbGVPYmplY3QuaXNOYW1lQ29tcGF0aWJsZShzaW1wbGVOYW1lLCBraW5kKTsKICAgICAgICB9CgogICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSKQogICAgICAgIHB1YmxpYyBOZXN0aW5nS2luZCBnZXROZXN0aW5nS2luZCgpIHsKICAgICAgICAgICAgcmV0dXJuIGphdmFGaWxlT2JqZWN0LmdldE5lc3RpbmdLaW5kKCk7CiAgICAgICAgfQoKICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgICAgICBwdWJsaWMgTW9kaWZpZXIgZ2V0QWNjZXNzTGV2ZWwoKSB7CiAgICAgICAgICAgIHJldHVybiBqYXZhRmlsZU9iamVjdC5nZXRBY2Nlc3NMZXZlbCgpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFdyYXAgYSBKYXZhRmlsZU9iamVjdCB0byBtYW5hZ2UgcmVhZGluZyBieSB0aGUgRmlsZXIuCiAgICAgKi8KICAgIHByaXZhdGUgY2xhc3MgRmlsZXJJbnB1dEZpbGVPYmplY3QgZXh0ZW5kcyBGb3J3YXJkaW5nRmlsZU9iamVjdDxGaWxlT2JqZWN0PiB7CiAgICAgICAgRmlsZXJJbnB1dEZpbGVPYmplY3QoRmlsZU9iamVjdCBmaWxlT2JqZWN0KSB7CiAgICAgICAgICAgIHN1cGVyKGZpbGVPYmplY3QpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSKQogICAgICAgIHB1YmxpYyBPdXRwdXRTdHJlYW0gb3Blbk91dHB1dFN0cmVhbSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oTk9UX0ZPUl9XUklUSU5HKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgICAgICBwdWJsaWMgV3JpdGVyIG9wZW5Xcml0ZXIoKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKE5PVF9GT1JfV1JJVElORyk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICAgICAgcHVibGljIGJvb2xlYW4gZGVsZXRlKCkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgY2xhc3MgRmlsZXJJbnB1dEphdmFGaWxlT2JqZWN0IGV4dGVuZHMgRmlsZXJJbnB1dEZpbGVPYmplY3QgaW1wbGVtZW50cyBKYXZhRmlsZU9iamVjdCB7CiAgICAgICAgcHJpdmF0ZSBmaW5hbCBKYXZhRmlsZU9iamVjdCBqYXZhRmlsZU9iamVjdDsKICAgICAgICBGaWxlcklucHV0SmF2YUZpbGVPYmplY3QoSmF2YUZpbGVPYmplY3QgamF2YUZpbGVPYmplY3QpIHsKICAgICAgICAgICAgc3VwZXIoamF2YUZpbGVPYmplY3QpOwogICAgICAgICAgICB0aGlzLmphdmFGaWxlT2JqZWN0ID0gamF2YUZpbGVPYmplY3Q7CiAgICAgICAgfQoKICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgICAgICBwdWJsaWMgSmF2YUZpbGVPYmplY3QuS2luZCBnZXRLaW5kKCkgewogICAgICAgICAgICByZXR1cm4gamF2YUZpbGVPYmplY3QuZ2V0S2luZCgpOwogICAgICAgIH0KCiAgICAgICAgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICAgICAgcHVibGljIGJvb2xlYW4gaXNOYW1lQ29tcGF0aWJsZShTdHJpbmcgc2ltcGxlTmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEphdmFGaWxlT2JqZWN0LktpbmQga2luZCkgewogICAgICAgICAgICByZXR1cm4gamF2YUZpbGVPYmplY3QuaXNOYW1lQ29tcGF0aWJsZShzaW1wbGVOYW1lLCBraW5kKTsKICAgICAgICB9CgogICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSKQogICAgICAgIHB1YmxpYyBOZXN0aW5nS2luZCBnZXROZXN0aW5nS2luZCgpIHsKICAgICAgICAgICAgcmV0dXJuIGphdmFGaWxlT2JqZWN0LmdldE5lc3RpbmdLaW5kKCk7CiAgICAgICAgfQoKICAgICAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgICAgICBwdWJsaWMgTW9kaWZpZXIgZ2V0QWNjZXNzTGV2ZWwoKSB7CiAgICAgICAgICAgIHJldHVybiBqYXZhRmlsZU9iamVjdC5nZXRBY2Nlc3NMZXZlbCgpOwogICAgICAgIH0KICAgIH0KCgogICAgLyoqCiAgICAgKiBXcmFwIGEge0Bjb2RlIE91dHB1dFN0cmVhbX0gcmV0dXJuZWQgZnJvbSB0aGUge0Bjb2RlCiAgICAgKiBKYXZhRmlsZU1hbmFnZXJ9IHRvIHByb3Blcmx5IHJlZ2lzdGVyIHNvdXJjZSBvciBjbGFzcyBmaWxlcwogICAgICogd2hlbiB0aGV5IGFyZSBjbG9zZWQuCiAgICAgKi8KICAgIHByaXZhdGUgY2xhc3MgRmlsZXJPdXRwdXRTdHJlYW0gZXh0ZW5kcyBGaWx0ZXJPdXRwdXRTdHJlYW0gewogICAgICAgIE1vZHVsZVN5bWJvbCBtb2Q7CiAgICAgICAgU3RyaW5nIHR5cGVOYW1lOwogICAgICAgIEZpbGVPYmplY3QgZmlsZU9iamVjdDsKICAgICAgICBib29sZWFuIGNsb3NlZCA9IGZhbHNlOwoKICAgICAgICAvKioKICAgICAgICAgKiBAcGFyYW0gdHlwZU5hbWUgbmFtZSBvZiBjbGFzcyBvciB7QGNvZGUgbnVsbH0gaWYganVzdCBhCiAgICAgICAgICogYmluYXJ5IGZpbGUKICAgICAgICAgKi8KICAgICAgICBGaWxlck91dHB1dFN0cmVhbShNb2R1bGVTeW1ib2wgbW9kLCBTdHJpbmcgdHlwZU5hbWUsIEZpbGVPYmplY3QgZmlsZU9iamVjdCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICAgICAgc3VwZXIoZmlsZU9iamVjdC5vcGVuT3V0cHV0U3RyZWFtKCkpOwogICAgICAgICAgICB0aGlzLm1vZCA9IG1vZDsKICAgICAgICAgICAgdGhpcy50eXBlTmFtZSA9IHR5cGVOYW1lOwogICAgICAgICAgICB0aGlzLmZpbGVPYmplY3QgPSBmaWxlT2JqZWN0OwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICAgICAgaWYgKCFjbG9zZWQpIHsKICAgICAgICAgICAgICAgIGNsb3NlZCA9IHRydWU7CiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogSWYgYW4gSU9FeGNlcHRpb24gb2NjdXJzIHdoZW4gY2xvc2luZyB0aGUgdW5kZXJseWluZwogICAgICAgICAgICAgICAgICogc3RyZWFtLCBzdGlsbCB0cnkgdG8gcHJvY2VzcyB0aGUgZmlsZS4KICAgICAgICAgICAgICAgICAqLwoKICAgICAgICAgICAgICAgIGNsb3NlRmlsZU9iamVjdChtb2QsIHR5cGVOYW1lLCBmaWxlT2JqZWN0KTsKICAgICAgICAgICAgICAgIG91dC5jbG9zZSgpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogV3JhcCBhIHtAY29kZSBXcml0ZXJ9IHJldHVybmVkIGZyb20gdGhlIHtAY29kZSBKYXZhRmlsZU1hbmFnZXJ9CiAgICAgKiB0byBwcm9wZXJseSByZWdpc3RlciBzb3VyY2Ugb3IgY2xhc3MgZmlsZXMgd2hlbiB0aGV5IGFyZQogICAgICogY2xvc2VkLgogICAgICovCiAgICBwcml2YXRlIGNsYXNzIEZpbGVyV3JpdGVyIGV4dGVuZHMgRmlsdGVyV3JpdGVyIHsKICAgICAgICBNb2R1bGVTeW1ib2wgbW9kOwogICAgICAgIFN0cmluZyB0eXBlTmFtZTsKICAgICAgICBGaWxlT2JqZWN0IGZpbGVPYmplY3Q7CiAgICAgICAgYm9vbGVhbiBjbG9zZWQgPSBmYWxzZTsKCiAgICAgICAgLyoqCiAgICAgICAgICogQHBhcmFtIGZpbGVPYmplY3QgdGhlIGZpbGVPYmplY3QgdG8gYmUgd3JpdHRlbiB0bwogICAgICAgICAqIEBwYXJhbSB0eXBlTmFtZSBuYW1lIG9mIHNvdXJjZSBmaWxlIG9yIHtAY29kZSBudWxsfSBpZiBqdXN0IGEKICAgICAgICAgKiB0ZXh0IGZpbGUKICAgICAgICAgKi8KICAgICAgICBGaWxlcldyaXRlcihNb2R1bGVTeW1ib2wgbW9kLCBTdHJpbmcgdHlwZU5hbWUsIEZpbGVPYmplY3QgZmlsZU9iamVjdCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICAgICAgc3VwZXIoZmlsZU9iamVjdC5vcGVuV3JpdGVyKCkpOwogICAgICAgICAgICB0aGlzLm1vZCA9IG1vZDsKICAgICAgICAgICAgdGhpcy50eXBlTmFtZSA9IHR5cGVOYW1lOwogICAgICAgICAgICB0aGlzLmZpbGVPYmplY3QgPSBmaWxlT2JqZWN0OwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICAgICAgaWYgKCFjbG9zZWQpIHsKICAgICAgICAgICAgICAgIGNsb3NlZCA9IHRydWU7CiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogSWYgYW4gSU9FeGNlcHRpb24gb2NjdXJzIHdoZW4gY2xvc2luZyB0aGUgdW5kZXJseWluZwogICAgICAgICAgICAgICAgICogV3JpdGVyLCBzdGlsbCB0cnkgdG8gcHJvY2VzcyB0aGUgZmlsZS4KICAgICAgICAgICAgICAgICAqLwoKICAgICAgICAgICAgICAgIGNsb3NlRmlsZU9iamVjdChtb2QsIHR5cGVOYW1lLCBmaWxlT2JqZWN0KTsKICAgICAgICAgICAgICAgIG91dC5jbG9zZSgpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIEphdmFGaWxlTWFuYWdlciBmaWxlTWFuYWdlcjsKICAgIEphdmFjRWxlbWVudHMgZWxlbWVudFV0aWxzOwogICAgTG9nIGxvZzsKICAgIE1vZHVsZXMgbW9kdWxlczsKICAgIE5hbWVzIG5hbWVzOwogICAgU3ltdGFiIHN5bXM7CiAgICBDb250ZXh0IGNvbnRleHQ7CiAgICBib29sZWFuIGxhc3RSb3VuZDsKCiAgICBwcml2YXRlIGZpbmFsIGJvb2xlYW4gbGludDsKCiAgICAvKioKICAgICAqIEluaXRpYWwgaW5wdXRzIHBhc3NlZCB0byB0aGUgdG9vbC4gIFRoaXMgc2V0IG11c3QgYmUKICAgICAqIHN5bmNocm9uaXplZC4KICAgICAqLwogICAgcHJpdmF0ZSBmaW5hbCBTZXQ8RmlsZU9iamVjdD4gaW5pdGlhbElucHV0czsKCiAgICAvKioKICAgICAqIExvZ2ljYWwgbmFtZXMgb2YgYWxsIGNyZWF0ZWQgZmlsZXMuICBUaGlzIHNldCBtdXN0IGJlCiAgICAgKiBzeW5jaHJvbml6ZWQuCiAgICAgKi8KICAgIHByaXZhdGUgZmluYWwgU2V0PEZpbGVPYmplY3Q+IGZpbGVPYmplY3RIaXN0b3J5OwoKICAgIC8qKgogICAgICogTmFtZXMgb2YgdHlwZXMgdGhhdCBoYXZlIGhhZCBmaWxlcyBjcmVhdGVkIGJ1dCBub3QgY2xvc2VkLgogICAgICovCiAgICBwcml2YXRlIGZpbmFsIFNldDxTdHJpbmc+IG9wZW5UeXBlTmFtZXM7CgogICAgLyoqCiAgICAgKiBOYW1lcyBvZiBzb3VyY2UgZmlsZXMgY2xvc2VkIGluIHRoaXMgcm91bmQuICBUaGlzIHNldCBtdXN0IGJlCiAgICAgKiBzeW5jaHJvbml6ZWQuICBJdHMgaXRlcmF0b3JzIHNob3VsZCBwcmVzZXJ2ZSBpbnNlcnRpb24gb3JkZXIuCiAgICAgKi8KICAgIHByaXZhdGUgU2V0PFN0cmluZz4gZ2VuZXJhdGVkU291cmNlTmFtZXM7CgogICAgLyoqCiAgICAgKiBOYW1lcyBhbmQgY2xhc3MgZmlsZXMgb2YgdGhlIGNsYXNzIGZpbGVzIGNsb3NlZCBpbiB0aGlzIHJvdW5kLgogICAgICogVGhpcyBzZXQgbXVzdCBiZSBzeW5jaHJvbml6ZWQuICBJdHMgaXRlcmF0b3JzIHNob3VsZCBwcmVzZXJ2ZQogICAgICogaW5zZXJ0aW9uIG9yZGVyLgogICAgICovCiAgICBwcml2YXRlIGZpbmFsIE1hcDxNb2R1bGVTeW1ib2wsIE1hcDxTdHJpbmcsIEphdmFGaWxlT2JqZWN0Pj4gZ2VuZXJhdGVkQ2xhc3NlczsKCiAgICAvKioKICAgICAqIEphdmFGaWxlT2JqZWN0cyBmb3Igc291cmNlIGZpbGVzIGNsb3NlZCBpbiB0aGlzIHJvdW5kLiAgVGhpcwogICAgICogc2V0IG11c3QgYmUgc3luY2hyb25pemVkLiAgSXRzIGl0ZXJhdG9ycyBzaG91bGQgcHJlc2VydmUKICAgICAqIGluc2VydGlvbiBvcmRlci4KICAgICAqLwogICAgcHJpdmF0ZSBTZXQ8SmF2YUZpbGVPYmplY3Q+IGdlbmVyYXRlZFNvdXJjZUZpbGVPYmplY3RzOwoKICAgIC8qKgogICAgICogTmFtZXMgb2YgYWxsIGNyZWF0ZWQgc291cmNlIGZpbGVzLiAgSXRzIGl0ZXJhdG9ycyBzaG91bGQKICAgICAqIHByZXNlcnZlIGluc2VydGlvbiBvcmRlci4KICAgICAqLwogICAgcHJpdmF0ZSBmaW5hbCBTZXQ8UGFpcjxNb2R1bGVTeW1ib2wsIFN0cmluZz4+IGFnZ3JlZ2F0ZUdlbmVyYXRlZFNvdXJjZU5hbWVzOwoKICAgIC8qKgogICAgICogTmFtZXMgb2YgYWxsIGNyZWF0ZWQgY2xhc3MgZmlsZXMuICBJdHMgaXRlcmF0b3JzIHNob3VsZAogICAgICogcHJlc2VydmUgaW5zZXJ0aW9uIG9yZGVyLgogICAgICovCiAgICBwcml2YXRlIGZpbmFsIFNldDxQYWlyPE1vZHVsZVN5bWJvbCwgU3RyaW5nPj4gYWdncmVnYXRlR2VuZXJhdGVkQ2xhc3NOYW1lczsKCiAgICBwcml2YXRlIGZpbmFsIFNldDxTdHJpbmc+IGluaXRpYWxDbGFzc05hbWVzOwoKICAgIEphdmFjRmlsZXIoQ29udGV4dCBjb250ZXh0KSB7CiAgICAgICAgdGhpcy5jb250ZXh0ID0gY29udGV4dDsKICAgICAgICBmaWxlTWFuYWdlciA9IGNvbnRleHQuZ2V0KEphdmFGaWxlTWFuYWdlci5jbGFzcyk7CiAgICAgICAgZWxlbWVudFV0aWxzID0gSmF2YWNFbGVtZW50cy5pbnN0YW5jZShjb250ZXh0KTsKCiAgICAgICAgbG9nID0gTG9nLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIG1vZHVsZXMgPSBNb2R1bGVzLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIG5hbWVzID0gTmFtZXMuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgc3ltcyA9IFN5bXRhYi5pbnN0YW5jZShjb250ZXh0KTsKCiAgICAgICAgaW5pdGlhbElucHV0cyA9IHN5bmNocm9uaXplZFNldChuZXcgTGlua2VkSGFzaFNldDw+KCkpOwogICAgICAgIGZpbGVPYmplY3RIaXN0b3J5ID0gc3luY2hyb25pemVkU2V0KG5ldyBMaW5rZWRIYXNoU2V0PD4oKSk7CiAgICAgICAgZ2VuZXJhdGVkU291cmNlTmFtZXMgPSBzeW5jaHJvbml6ZWRTZXQobmV3IExpbmtlZEhhc2hTZXQ8PigpKTsKICAgICAgICBnZW5lcmF0ZWRTb3VyY2VGaWxlT2JqZWN0cyA9IHN5bmNocm9uaXplZFNldChuZXcgTGlua2VkSGFzaFNldDw+KCkpOwoKICAgICAgICBnZW5lcmF0ZWRDbGFzc2VzID0gc3luY2hyb25pemVkTWFwKG5ldyBMaW5rZWRIYXNoTWFwPD4oKSk7CgogICAgICAgIG9wZW5UeXBlTmFtZXMgID0gc3luY2hyb25pemVkU2V0KG5ldyBMaW5rZWRIYXNoU2V0PD4oKSk7CgogICAgICAgIGFnZ3JlZ2F0ZUdlbmVyYXRlZFNvdXJjZU5hbWVzID0gbmV3IExpbmtlZEhhc2hTZXQ8PigpOwogICAgICAgIGFnZ3JlZ2F0ZUdlbmVyYXRlZENsYXNzTmFtZXMgID0gbmV3IExpbmtlZEhhc2hTZXQ8PigpOwogICAgICAgIGluaXRpYWxDbGFzc05hbWVzICA9IG5ldyBMaW5rZWRIYXNoU2V0PD4oKTsKCiAgICAgICAgbGludCA9IChMaW50Lmluc3RhbmNlKGNvbnRleHQpKS5pc0VuYWJsZWQoUFJPQ0VTU0lORyk7CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkFOTk9UQVRJT05fUFJPQ0VTU0lORykKICAgIHB1YmxpYyBKYXZhRmlsZU9iamVjdCBjcmVhdGVTb3VyY2VGaWxlKENoYXJTZXF1ZW5jZSBuYW1lQW5kTW9kdWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRWxlbWVudC4uLiBvcmlnaW5hdGluZ0VsZW1lbnRzKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgIFBhaXI8TW9kdWxlU3ltYm9sLCBTdHJpbmc+IG1vZHVsZUFuZENsYXNzID0gY2hlY2tPckluZmVyTW9kdWxlKG5hbWVBbmRNb2R1bGUpOwogICAgICAgIHJldHVybiBjcmVhdGVTb3VyY2VPckNsYXNzRmlsZShtb2R1bGVBbmRDbGFzcy5mc3QsIHRydWUsIG1vZHVsZUFuZENsYXNzLnNuZCk7CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkFOTk9UQVRJT05fUFJPQ0VTU0lORykKICAgIHB1YmxpYyBKYXZhRmlsZU9iamVjdCBjcmVhdGVDbGFzc0ZpbGUoQ2hhclNlcXVlbmNlIG5hbWVBbmRNb2R1bGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVsZW1lbnQuLi4gb3JpZ2luYXRpbmdFbGVtZW50cykgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICBQYWlyPE1vZHVsZVN5bWJvbCwgU3RyaW5nPiBtb2R1bGVBbmRDbGFzcyA9IGNoZWNrT3JJbmZlck1vZHVsZShuYW1lQW5kTW9kdWxlKTsKICAgICAgICByZXR1cm4gY3JlYXRlU291cmNlT3JDbGFzc0ZpbGUobW9kdWxlQW5kQ2xhc3MuZnN0LCBmYWxzZSwgbW9kdWxlQW5kQ2xhc3Muc25kKTsKICAgIH0KCiAgICBwcml2YXRlIFBhaXI8TW9kdWxlU3ltYm9sLCBTdHJpbmc+IGNoZWNrT3JJbmZlck1vZHVsZShDaGFyU2VxdWVuY2UgbW9kdWxlQW5kUGtnKSB0aHJvd3MgRmlsZXJFeGNlcHRpb24gewogICAgICAgIFN0cmluZyBtb2R1bGVBbmRQa2dTdHJpbmcgPSBtb2R1bGVBbmRQa2cudG9TdHJpbmcoKTsKICAgICAgICBpbnQgc2xhc2ggPSBtb2R1bGVBbmRQa2dTdHJpbmcuaW5kZXhPZignLycpOwoKICAgICAgICBpZiAoc2xhc2ggIT0gKC0xKSkgewogICAgICAgICAgICAvL21vZHVsZSBuYW1lIHNwZWNpZmllZDoKICAgICAgICAgICAgU3RyaW5nIG1vZHVsZSA9IG1vZHVsZUFuZFBrZ1N0cmluZy5zdWJzdHJpbmcoMCwgc2xhc2gpOwoKICAgICAgICAgICAgTW9kdWxlU3ltYm9sIGV4cGxpY2l0TW9kdWxlID0gc3ltcy5nZXRNb2R1bGUobmFtZXMuZnJvbVN0cmluZyhtb2R1bGUpKTsKCiAgICAgICAgICAgIGlmIChleHBsaWNpdE1vZHVsZSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRmlsZXJFeGNlcHRpb24oIk1vZHVsZTogIiArIG1vZHVsZSArICIgZG9lcyBub3QgZXhpc3QuIik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICghbW9kdWxlcy5pc1Jvb3RNb2R1bGUoZXhwbGljaXRNb2R1bGUpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRmlsZXJFeGNlcHRpb24oIkNhbm5vdCB3cml0ZSB0byB0aGUgZ2l2ZW4gbW9kdWxlISIpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gUGFpci5vZihleHBsaWNpdE1vZHVsZSwgbW9kdWxlQW5kUGtnU3RyaW5nLnN1YnN0cmluZyhzbGFzaCArIDEpKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBpZiAobW9kdWxlcy5tdWx0aU1vZHVsZU1vZGUpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBGaWxlckV4Y2VwdGlvbigiTm8gbW9kdWxlIHRvIHdyaXRlIHRvIHNwZWNpZmllZCEiKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIFBhaXIub2YobW9kdWxlcy5nZXREZWZhdWx0TW9kdWxlKCksIG1vZHVsZUFuZFBrZ1N0cmluZyk7CiAgICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgSmF2YUZpbGVPYmplY3QgY3JlYXRlU291cmNlT3JDbGFzc0ZpbGUoTW9kdWxlU3ltYm9sIG1vZCwgYm9vbGVhbiBpc1NvdXJjZUZpbGUsIFN0cmluZyBuYW1lKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgIEFzc2VydC5jaGVja05vbk51bGwobW9kKTsKCiAgICAgICAgaWYgKGxpbnQpIHsKICAgICAgICAgICAgaW50IHBlcmlvZEluZGV4ID0gbmFtZS5sYXN0SW5kZXhPZigiLiIpOwogICAgICAgICAgICBpZiAocGVyaW9kSW5kZXggIT0gLTEpIHsKICAgICAgICAgICAgICAgIFN0cmluZyBiYXNlID0gbmFtZS5zdWJzdHJpbmcocGVyaW9kSW5kZXgpOwogICAgICAgICAgICAgICAgU3RyaW5nIGV4dG4gPSAoaXNTb3VyY2VGaWxlID8gIi5qYXZhIiA6ICIuY2xhc3MiKTsKICAgICAgICAgICAgICAgIGlmIChiYXNlLmVxdWFscyhleHRuKSkKICAgICAgICAgICAgICAgICAgICBsb2cud2FybmluZygicHJvYy5zdXNwaWNpb3VzLmNsYXNzLm5hbWUiLCBuYW1lLCBleHRuKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBjaGVja05hbWVBbmRFeGlzdGVuY2UobW9kLCBuYW1lLCBpc1NvdXJjZUZpbGUpOwogICAgICAgIExvY2F0aW9uIGxvYyA9IChpc1NvdXJjZUZpbGUgPyBTT1VSQ0VfT1VUUFVUIDogQ0xBU1NfT1VUUFVUKTsKCiAgICAgICAgaWYgKG1vZHVsZXMubXVsdGlNb2R1bGVNb2RlKSB7CiAgICAgICAgICAgIGxvYyA9IHRoaXMuZmlsZU1hbmFnZXIuZ2V0TG9jYXRpb25Gb3JNb2R1bGUobG9jLCBtb2QubmFtZS50b1N0cmluZygpKTsKICAgICAgICB9CiAgICAgICAgSmF2YUZpbGVPYmplY3QuS2luZCBraW5kID0gKGlzU291cmNlRmlsZSA/CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEphdmFGaWxlT2JqZWN0LktpbmQuU09VUkNFIDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSmF2YUZpbGVPYmplY3QuS2luZC5DTEFTUyk7CgogICAgICAgIEphdmFGaWxlT2JqZWN0IGZpbGVPYmplY3QgPQogICAgICAgICAgICBmaWxlTWFuYWdlci5nZXRKYXZhRmlsZUZvck91dHB1dChsb2MsIG5hbWUsIGtpbmQsIG51bGwpOwogICAgICAgIGNoZWNrRmlsZVJlb3BlbmluZyhmaWxlT2JqZWN0LCB0cnVlKTsKCiAgICAgICAgaWYgKGxhc3RSb3VuZCkKICAgICAgICAgICAgbG9nLndhcm5pbmcoInByb2MuZmlsZS5jcmVhdGUubGFzdC5yb3VuZCIsIG5hbWUpOwoKICAgICAgICBpZiAoaXNTb3VyY2VGaWxlKQogICAgICAgICAgICBhZ2dyZWdhdGVHZW5lcmF0ZWRTb3VyY2VOYW1lcy5hZGQoUGFpci5vZihtb2QsIG5hbWUpKTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIGFnZ3JlZ2F0ZUdlbmVyYXRlZENsYXNzTmFtZXMuYWRkKFBhaXIub2YobW9kLCBuYW1lKSk7CiAgICAgICAgb3BlblR5cGVOYW1lcy5hZGQobmFtZSk7CgogICAgICAgIHJldHVybiBuZXcgRmlsZXJPdXRwdXRKYXZhRmlsZU9iamVjdChtb2QsIG5hbWUsIGZpbGVPYmplY3QpOwogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5BTk5PVEFUSU9OX1BST0NFU1NJTkcpCiAgICBwdWJsaWMgRmlsZU9iamVjdCBjcmVhdGVSZXNvdXJjZShKYXZhRmlsZU1hbmFnZXIuTG9jYXRpb24gbG9jYXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDaGFyU2VxdWVuY2UgbW9kdWxlQW5kUGtnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2hhclNlcXVlbmNlIHJlbGF0aXZlTmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVsZW1lbnQuLi4gb3JpZ2luYXRpbmdFbGVtZW50cykgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICBQYWlyPE1vZHVsZVN5bWJvbCwgU3RyaW5nPiBtb2R1bGVBbmRQYWNrYWdlID0gY2hlY2tPckluZmVyTW9kdWxlKG1vZHVsZUFuZFBrZyk7CiAgICAgICAgTW9kdWxlU3ltYm9sIG1zeW0gPSBtb2R1bGVBbmRQYWNrYWdlLmZzdDsKICAgICAgICBTdHJpbmcgcGtnID0gbW9kdWxlQW5kUGFja2FnZS5zbmQ7CgogICAgICAgIGxvY2F0aW9uQ2hlY2sobG9jYXRpb24pOwoKICAgICAgICBpZiAobW9kdWxlcy5tdWx0aU1vZHVsZU1vZGUpIHsKICAgICAgICAgICAgQXNzZXJ0LmNoZWNrTm9uTnVsbChtc3ltKTsKICAgICAgICAgICAgbG9jYXRpb24gPSB0aGlzLmZpbGVNYW5hZ2VyLmdldExvY2F0aW9uRm9yTW9kdWxlKGxvY2F0aW9uLCBtc3ltLm5hbWUudG9TdHJpbmcoKSk7CiAgICAgICAgfQoKICAgICAgICBTdHJpbmcgc3RyUGtnID0gcGtnLnRvU3RyaW5nKCk7CiAgICAgICAgaWYgKHN0clBrZy5sZW5ndGgoKSA+IDApCiAgICAgICAgICAgIGNoZWNrTmFtZShzdHJQa2cpOwoKICAgICAgICBGaWxlT2JqZWN0IGZpbGVPYmplY3QgPQogICAgICAgICAgICBmaWxlTWFuYWdlci5nZXRGaWxlRm9yT3V0cHV0KGxvY2F0aW9uLCBzdHJQa2csCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVsYXRpdmVOYW1lLnRvU3RyaW5nKCksIG51bGwpOwogICAgICAgIGNoZWNrRmlsZVJlb3BlbmluZyhmaWxlT2JqZWN0LCB0cnVlKTsKCiAgICAgICAgaWYgKGZpbGVPYmplY3QgaW5zdGFuY2VvZiBKYXZhRmlsZU9iamVjdCkKICAgICAgICAgICAgcmV0dXJuIG5ldyBGaWxlck91dHB1dEphdmFGaWxlT2JqZWN0KG1zeW0sIG51bGwsIChKYXZhRmlsZU9iamVjdClmaWxlT2JqZWN0KTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIHJldHVybiBuZXcgRmlsZXJPdXRwdXRGaWxlT2JqZWN0KG1zeW0sIG51bGwsIGZpbGVPYmplY3QpOwogICAgfQoKICAgIHByaXZhdGUgdm9pZCBsb2NhdGlvbkNoZWNrKEphdmFGaWxlTWFuYWdlci5Mb2NhdGlvbiBsb2NhdGlvbikgewogICAgICAgIGlmIChsb2NhdGlvbiBpbnN0YW5jZW9mIFN0YW5kYXJkTG9jYXRpb24pIHsKICAgICAgICAgICAgU3RhbmRhcmRMb2NhdGlvbiBzdGRMb2MgPSAoU3RhbmRhcmRMb2NhdGlvbikgbG9jYXRpb247CiAgICAgICAgICAgIGlmICghc3RkTG9jLmlzT3V0cHV0TG9jYXRpb24oKSkKICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIlJlc291cmNlIGNyZWF0aW9uIG5vdCBzdXBwb3J0ZWQgaW4gbG9jYXRpb24gIiArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZExvYyk7CiAgICAgICAgfQogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5BTk5PVEFUSU9OX1BST0NFU1NJTkcpCiAgICBwdWJsaWMgRmlsZU9iamVjdCBnZXRSZXNvdXJjZShKYXZhRmlsZU1hbmFnZXIuTG9jYXRpb24gbG9jYXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDaGFyU2VxdWVuY2UgbW9kdWxlQW5kUGtnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2hhclNlcXVlbmNlIHJlbGF0aXZlTmFtZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICBQYWlyPE1vZHVsZVN5bWJvbCwgU3RyaW5nPiBtb2R1bGVBbmRQYWNrYWdlID0gY2hlY2tPckluZmVyTW9kdWxlKG1vZHVsZUFuZFBrZyk7CiAgICAgICAgTW9kdWxlU3ltYm9sIG1zeW0gPSBtb2R1bGVBbmRQYWNrYWdlLmZzdDsKICAgICAgICBTdHJpbmcgcGtnID0gbW9kdWxlQW5kUGFja2FnZS5zbmQ7CgogICAgICAgIGlmIChtb2R1bGVzLm11bHRpTW9kdWxlTW9kZSkgewogICAgICAgICAgICBBc3NlcnQuY2hlY2tOb25OdWxsKG1zeW0pOwogICAgICAgICAgICBsb2NhdGlvbiA9IHRoaXMuZmlsZU1hbmFnZXIuZ2V0TG9jYXRpb25Gb3JNb2R1bGUobG9jYXRpb24sIG1zeW0ubmFtZS50b1N0cmluZygpKTsKICAgICAgICB9CgogICAgICAgIGlmIChwa2cubGVuZ3RoKCkgPiAwKQogICAgICAgICAgICBjaGVja05hbWUocGtnKTsKCiAgICAgICAgLy8gVE9ETzogT25seSBzdXBwb3J0IHJlYWRpbmcgcmVzb3VyY2VzIGluIHNlbGVjdGVkIG91dHB1dAogICAgICAgIC8vIGxvY2F0aW9ucz8gIE9ubHkgYWxsb3cgcmVhZGluZyBvZiBub24tc291cmNlLCBub24tY2xhc3MKICAgICAgICAvLyBmaWxlcyBmcm9tIHRoZSBzdXBwb3J0ZWQgaW5wdXQgbG9jYXRpb25zPwoKICAgICAgICAvLyBJbiB0aGUgZm9sbG93aW5nLCBnZXRGaWxlRm9ySW5wdXQgaXMgdGhlICJvYnZpb3VzIiBtZXRob2QKICAgICAgICAvLyB0byB1c2UsIGJ1dCBpdCBkb2VzIG5vdCBoYXZlIHRoZSAib2J2aW91cyIgc2VtYW50aWNzIGZvcgogICAgICAgIC8vIFNPVVJDRV9PVVRQVVQgYW5kIENMQVNTX09VVFBVVC4gQ29udmVyc2VseSwgZ2V0RmlsZUZvck91dHB1dAogICAgICAgIC8vIGRvZXMgbm90IGhhdmUgdGhlIGNvcnJlY3Qgc2VtYW50aWNzIGZvciBhbnkgInBhdGgiIGxvY2F0aW9uCiAgICAgICAgLy8gd2l0aCBtb3JlIHRoYW4gb25lIGNvbXBvbmVudC4gU28sIGZvciBub3csIHdlIHVzZSBhIGh5YnJpZAogICAgICAgIC8vIGludm9jYXRpb24uCiAgICAgICAgRmlsZU9iamVjdCBmaWxlT2JqZWN0OwogICAgICAgIGlmIChsb2NhdGlvbi5pc091dHB1dExvY2F0aW9uKCkpIHsKICAgICAgICAgICAgZmlsZU9iamVjdCA9IGZpbGVNYW5hZ2VyLmdldEZpbGVGb3JPdXRwdXQobG9jYXRpb24sCiAgICAgICAgICAgICAgICAgICAgcGtnLAogICAgICAgICAgICAgICAgICAgIHJlbGF0aXZlTmFtZS50b1N0cmluZygpLAogICAgICAgICAgICAgICAgICAgIG51bGwpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGZpbGVPYmplY3QgPSBmaWxlTWFuYWdlci5nZXRGaWxlRm9ySW5wdXQobG9jYXRpb24sCiAgICAgICAgICAgICAgICAgICAgcGtnLAogICAgICAgICAgICAgICAgICAgIHJlbGF0aXZlTmFtZS50b1N0cmluZygpKTsKICAgICAgICB9CiAgICAgICAgaWYgKGZpbGVPYmplY3QgPT0gbnVsbCkgewogICAgICAgICAgICBTdHJpbmcgbmFtZSA9IChwa2cubGVuZ3RoKCkgPT0gMCkKICAgICAgICAgICAgICAgICAgICA/IHJlbGF0aXZlTmFtZS50b1N0cmluZygpIDogKHBrZyArICIvIiArIHJlbGF0aXZlTmFtZSk7CiAgICAgICAgICAgIHRocm93IG5ldyBGaWxlTm90Rm91bmRFeGNlcHRpb24obmFtZSk7CiAgICAgICAgfQoKICAgICAgICAvLyBJZiB0aGUgcGF0aCB3YXMgYWxyZWFkeSBvcGVuZWQgZm9yIHdyaXRpbmcsIHRocm93IGFuIGV4Y2VwdGlvbi4KICAgICAgICBjaGVja0ZpbGVSZW9wZW5pbmcoZmlsZU9iamVjdCwgZmFsc2UpOwogICAgICAgIHJldHVybiBuZXcgRmlsZXJJbnB1dEZpbGVPYmplY3QoZmlsZU9iamVjdCk7CiAgICB9CgogICAgcHJpdmF0ZSB2b2lkIGNoZWNrTmFtZShTdHJpbmcgbmFtZSkgdGhyb3dzIEZpbGVyRXhjZXB0aW9uIHsKICAgICAgICBjaGVja05hbWUobmFtZSwgZmFsc2UpOwogICAgfQoKICAgIHByaXZhdGUgdm9pZCBjaGVja05hbWUoU3RyaW5nIG5hbWUsIGJvb2xlYW4gYWxsb3dVbm5hbWVkUGFja2FnZUluZm8pIHRocm93cyBGaWxlckV4Y2VwdGlvbiB7CiAgICAgICAgaWYgKCFTb3VyY2VWZXJzaW9uLmlzTmFtZShuYW1lKSAmJiAhaXNQYWNrYWdlSW5mbyhuYW1lLCBhbGxvd1VubmFtZWRQYWNrYWdlSW5mbykpIHsKICAgICAgICAgICAgaWYgKGxpbnQpCiAgICAgICAgICAgICAgICBsb2cud2FybmluZygicHJvYy5pbGxlZ2FsLmZpbGUubmFtZSIsIG5hbWUpOwogICAgICAgICAgICB0aHJvdyBuZXcgRmlsZXJFeGNlcHRpb24oIklsbGVnYWwgbmFtZSAiICsgbmFtZSk7CiAgICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgYm9vbGVhbiBpc1BhY2thZ2VJbmZvKFN0cmluZyBuYW1lLCBib29sZWFuIGFsbG93VW5uYW1lZFBhY2thZ2VJbmZvKSB7CiAgICAgICAgLy8gSXMgdGhlIG5hbWUgb2YgdGhlIGZvcm0gInBhY2thZ2UtaW5mbyIgb3IKICAgICAgICAvLyAiZm9vLmJhci5wYWNrYWdlLWluZm8iPwogICAgICAgIGZpbmFsIFN0cmluZyBQS0dfSU5GTyA9ICJwYWNrYWdlLWluZm8iOwogICAgICAgIGludCBwZXJpb2RJbmRleCA9IG5hbWUubGFzdEluZGV4T2YoIi4iKTsKICAgICAgICBpZiAocGVyaW9kSW5kZXggPT0gLTEpIHsKICAgICAgICAgICAgcmV0dXJuIGFsbG93VW5uYW1lZFBhY2thZ2VJbmZvID8gbmFtZS5lcXVhbHMoUEtHX0lORk8pIDogZmFsc2U7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLy8gImZvby5iYXIucGFja2FnZS1pbmZvLiIgaWxsZWdhbAogICAgICAgICAgICBTdHJpbmcgcHJlZml4ID0gbmFtZS5zdWJzdHJpbmcoMCwgcGVyaW9kSW5kZXgpOwogICAgICAgICAgICBTdHJpbmcgc2ltcGxlID0gbmFtZS5zdWJzdHJpbmcocGVyaW9kSW5kZXgrMSk7CiAgICAgICAgICAgIHJldHVybiBTb3VyY2VWZXJzaW9uLmlzTmFtZShwcmVmaXgpICYmIHNpbXBsZS5lcXVhbHMoUEtHX0lORk8pOwogICAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIHZvaWQgY2hlY2tOYW1lQW5kRXhpc3RlbmNlKE1vZHVsZVN5bWJvbCBtb2QsIFN0cmluZyB0eXBlbmFtZSwgYm9vbGVhbiBhbGxvd1VubmFtZWRQYWNrYWdlSW5mbykgdGhyb3dzIEZpbGVyRXhjZXB0aW9uIHsKICAgICAgICAvLyBUT0RPOiBDaGVjayBpZiB0eXBlIGFscmVhZHkgZXhpc3RzIG9uIHNvdXJjZSBvciBjbGFzcyBwYXRoPwogICAgICAgIC8vIElmIHNvLCB1c2Ugd2FybmluZyBtZXNzYWdlIGtleSBwcm9jLnR5cGUuYWxyZWFkeS5leGlzdHMKICAgICAgICBjaGVja05hbWUodHlwZW5hbWUsIGFsbG93VW5uYW1lZFBhY2thZ2VJbmZvKTsKICAgICAgICBDbGFzc1N5bWJvbCBleGlzdGluZzsKICAgICAgICBib29sZWFuIGFscmVhZHlTZWVuID0gYWdncmVnYXRlR2VuZXJhdGVkU291cmNlTmFtZXMuY29udGFpbnMoUGFpci5vZihtb2QsIHR5cGVuYW1lKSkgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWdncmVnYXRlR2VuZXJhdGVkQ2xhc3NOYW1lcy5jb250YWlucyhQYWlyLm9mKG1vZCwgdHlwZW5hbWUpKSB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbml0aWFsQ2xhc3NOYW1lcy5jb250YWlucyh0eXBlbmFtZSkgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKChleGlzdGluZyA9IGVsZW1lbnRVdGlscy5nZXRUeXBlRWxlbWVudCh0eXBlbmFtZSkpICE9IG51bGwgJiYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluaXRpYWxJbnB1dHMuY29udGFpbnMoZXhpc3Rpbmcuc291cmNlZmlsZSkpOwogICAgICAgIGlmIChhbHJlYWR5U2VlbikgewogICAgICAgICAgICBpZiAobGludCkKICAgICAgICAgICAgICAgIGxvZy53YXJuaW5nKCJwcm9jLnR5cGUucmVjcmVhdGUiLCB0eXBlbmFtZSk7CiAgICAgICAgICAgIHRocm93IG5ldyBGaWxlckV4Y2VwdGlvbigiQXR0ZW1wdCB0byByZWNyZWF0ZSBhIGZpbGUgZm9yIHR5cGUgIiArIHR5cGVuYW1lKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFtb2QuaXNVbm5hbWVkKCkgJiYgIXR5cGVuYW1lLmNvbnRhaW5zKCIuIikpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEZpbGVyRXhjZXB0aW9uKCJBdHRlbXB0IHRvIGNyZWF0ZSBhIHR5cGUgaW4gdW5uYW1lZCBwYWNrYWdlIG9mIGEgbmFtZWQgbW9kdWxlOiAiICsgdHlwZW5hbWUpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrIHRvIHNlZSBpZiB0aGUgZmlsZSBoYXMgYWxyZWFkeSBiZWVuIG9wZW5lZDsgaWYgc28sIHRocm93CiAgICAgKiBhbiBleGNlcHRpb24sIG90aGVyd2lzZSBhZGQgaXQgdG8gdGhlIHNldCBvZiBmaWxlcy4KICAgICAqLwogICAgcHJpdmF0ZSB2b2lkIGNoZWNrRmlsZVJlb3BlbmluZyhGaWxlT2JqZWN0IGZpbGVPYmplY3QsIGJvb2xlYW4gZm9yV3JpdGluZykgdGhyb3dzIEZpbGVyRXhjZXB0aW9uIHsKICAgICAgICBpZiAoaXNJbkZpbGVPYmplY3RIaXN0b3J5KGZpbGVPYmplY3QsIGZvcldyaXRpbmcpKSB7CiAgICAgICAgICAgIGlmIChsaW50KQogICAgICAgICAgICAgICAgbG9nLndhcm5pbmcoInByb2MuZmlsZS5yZW9wZW5pbmciLCBmaWxlT2JqZWN0LmdldE5hbWUoKSk7CiAgICAgICAgICAgIHRocm93IG5ldyBGaWxlckV4Y2VwdGlvbigiQXR0ZW1wdCB0byByZW9wZW4gYSBmaWxlIGZvciBwYXRoICIgKyBmaWxlT2JqZWN0LmdldE5hbWUoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChmb3JXcml0aW5nKQogICAgICAgICAgICBmaWxlT2JqZWN0SGlzdG9yeS5hZGQoZmlsZU9iamVjdCk7CiAgICB9CgogICAgcHJpdmF0ZSBib29sZWFuIGlzSW5GaWxlT2JqZWN0SGlzdG9yeShGaWxlT2JqZWN0IGZpbGVPYmplY3QsIGJvb2xlYW4gZm9yV3JpdGluZykgewogICAgICAgIGlmIChmb3JXcml0aW5nKSB7CiAgICAgICAgICAgIGZvcihGaWxlT2JqZWN0IHZldGVyYW4gOiBpbml0aWFsSW5wdXRzKSB7CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIGlmIChmaWxlTWFuYWdlci5pc1NhbWVGaWxlKHZldGVyYW4sIGZpbGVPYmplY3QpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgICAgICAgLy9pZ25vcmUuLi4KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBmb3IgKFN0cmluZyBjbGFzc05hbWUgOiBpbml0aWFsQ2xhc3NOYW1lcykgewogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICBDbGFzc1N5bWJvbCBleGlzdGluZyA9IGVsZW1lbnRVdGlscy5nZXRUeXBlRWxlbWVudChjbGFzc05hbWUpOwogICAgICAgICAgICAgICAgICAgIGlmICggICBleGlzdGluZyAhPSBudWxsCiAgICAgICAgICAgICAgICAgICAgICAgICYmICggICAoZXhpc3Rpbmcuc291cmNlZmlsZSAhPSBudWxsICYmIGZpbGVNYW5hZ2VyLmlzU2FtZUZpbGUoZXhpc3Rpbmcuc291cmNlZmlsZSwgZmlsZU9iamVjdCkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB8fCAoZXhpc3RpbmcuY2xhc3NmaWxlICE9IG51bGwgJiYgZmlsZU1hbmFnZXIuaXNTYW1lRmlsZShleGlzdGluZy5jbGFzc2ZpbGUsIGZpbGVPYmplY3QpKSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgICAgICAgICAvL2lnbm9yZS4uLgogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBmb3IoRmlsZU9iamVjdCB2ZXRlcmFuIDogZmlsZU9iamVjdEhpc3RvcnkpIHsKICAgICAgICAgICAgaWYgKGZpbGVNYW5hZ2VyLmlzU2FtZUZpbGUodmV0ZXJhbiwgZmlsZU9iamVjdCkpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgcHVibGljIGJvb2xlYW4gbmV3RmlsZXMoKSB7CiAgICAgICAgcmV0dXJuICghZ2VuZXJhdGVkU291cmNlTmFtZXMuaXNFbXB0eSgpKQogICAgICAgICAgICB8fCAoIWdlbmVyYXRlZENsYXNzZXMuaXNFbXB0eSgpKTsKICAgIH0KCiAgICBwdWJsaWMgU2V0PFN0cmluZz4gZ2V0R2VuZXJhdGVkU291cmNlTmFtZXMoKSB7CiAgICAgICAgcmV0dXJuIGdlbmVyYXRlZFNvdXJjZU5hbWVzOwogICAgfQoKICAgIHB1YmxpYyBTZXQ8SmF2YUZpbGVPYmplY3Q+IGdldEdlbmVyYXRlZFNvdXJjZUZpbGVPYmplY3RzKCkgewogICAgICAgIHJldHVybiBnZW5lcmF0ZWRTb3VyY2VGaWxlT2JqZWN0czsKICAgIH0KCiAgICBwdWJsaWMgTWFwPE1vZHVsZVN5bWJvbCwgTWFwPFN0cmluZywgSmF2YUZpbGVPYmplY3Q+PiBnZXRHZW5lcmF0ZWRDbGFzc2VzKCkgewogICAgICAgIHJldHVybiBnZW5lcmF0ZWRDbGFzc2VzOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHdhcm5JZlVuY2xvc2VkRmlsZXMoKSB7CiAgICAgICAgaWYgKCFvcGVuVHlwZU5hbWVzLmlzRW1wdHkoKSkKICAgICAgICAgICAgbG9nLndhcm5pbmcoInByb2MudW5jbG9zZWQudHlwZS5maWxlcyIsIG9wZW5UeXBlTmFtZXMudG9TdHJpbmcoKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBVcGRhdGUgaW50ZXJuYWwgc3RhdGUgZm9yIGEgbmV3IHJvdW5kLgogICAgICovCiAgICBwdWJsaWMgdm9pZCBuZXdSb3VuZCgpIHsKICAgICAgICBjbGVhclJvdW5kU3RhdGUoKTsKICAgIH0KCiAgICB2b2lkIHNldExhc3RSb3VuZChib29sZWFuIGxhc3RSb3VuZCkgewogICAgICAgIHRoaXMubGFzdFJvdW5kID0gbGFzdFJvdW5kOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHNldEluaXRpYWxTdGF0ZShDb2xsZWN0aW9uPD8gZXh0ZW5kcyBKYXZhRmlsZU9iamVjdD4gaW5pdGlhbElucHV0cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb2xsZWN0aW9uPFN0cmluZz4gaW5pdGlhbENsYXNzTmFtZXMpIHsKICAgICAgICB0aGlzLmluaXRpYWxJbnB1dHMuYWRkQWxsKGluaXRpYWxJbnB1dHMpOwogICAgICAgIHRoaXMuaW5pdGlhbENsYXNzTmFtZXMuYWRkQWxsKGluaXRpYWxDbGFzc05hbWVzKTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHsKICAgICAgICBjbGVhclJvdW5kU3RhdGUoKTsKICAgICAgICAvLyBDcm9zcy1yb3VuZCBzdGF0ZQogICAgICAgIGluaXRpYWxDbGFzc05hbWVzLmNsZWFyKCk7CiAgICAgICAgaW5pdGlhbElucHV0cy5jbGVhcigpOwogICAgICAgIGZpbGVPYmplY3RIaXN0b3J5LmNsZWFyKCk7CiAgICAgICAgb3BlblR5cGVOYW1lcy5jbGVhcigpOwogICAgICAgIGFnZ3JlZ2F0ZUdlbmVyYXRlZFNvdXJjZU5hbWVzLmNsZWFyKCk7CiAgICAgICAgYWdncmVnYXRlR2VuZXJhdGVkQ2xhc3NOYW1lcy5jbGVhcigpOwogICAgfQoKICAgIHByaXZhdGUgdm9pZCBjbGVhclJvdW5kU3RhdGUoKSB7CiAgICAgICAgZ2VuZXJhdGVkU291cmNlTmFtZXMuY2xlYXIoKTsKICAgICAgICBnZW5lcmF0ZWRTb3VyY2VGaWxlT2JqZWN0cy5jbGVhcigpOwogICAgICAgIGdlbmVyYXRlZENsYXNzZXMuY2xlYXIoKTsKICAgIH0KCiAgICAvKioKICAgICAqIERlYnVnZ2luZyBmdW5jdGlvbiB0byBkaXNwbGF5IGludGVybmFsIHN0YXRlLgogICAgICovCiAgICBwdWJsaWMgdm9pZCBkaXNwbGF5U3RhdGUoKSB7CiAgICAgICAgUHJpbnRXcml0ZXIgeG91dCA9IGNvbnRleHQuZ2V0KExvZy5sb2dLZXkpLmdldFdyaXRlcihMb2cuV3JpdGVyS2luZC5TVERFUlIpOwogICAgICAgIHhvdXQucHJpbnRsbigiRmlsZSBPYmplY3QgSGlzdG9yeSA6ICIgKyAgZmlsZU9iamVjdEhpc3RvcnkpOwogICAgICAgIHhvdXQucHJpbnRsbigiT3BlbiBUeXBlIE5hbWVzICAgICA6ICIgKyAgb3BlblR5cGVOYW1lcyk7CiAgICAgICAgeG91dC5wcmludGxuKCJHZW4uIFNyYyBOYW1lcyAgICAgIDogIiArICBnZW5lcmF0ZWRTb3VyY2VOYW1lcyk7CiAgICAgICAgeG91dC5wcmludGxuKCJHZW4uIENscyBOYW1lcyAgICAgIDogIiArICBnZW5lcmF0ZWRDbGFzc2VzLmtleVNldCgpKTsKICAgICAgICB4b3V0LnByaW50bG4oIkFnZy4gR2VuLiBTcmMgTmFtZXMgOiAiICsgIGFnZ3JlZ2F0ZUdlbmVyYXRlZFNvdXJjZU5hbWVzKTsKICAgICAgICB4b3V0LnByaW50bG4oIkFnZy4gR2VuLiBDbHMgTmFtZXMgOiAiICsgIGFnZ3JlZ2F0ZUdlbmVyYXRlZENsYXNzTmFtZXMpOwogICAgfQoKICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CiAgICAgICAgcmV0dXJuICJqYXZhYyBGaWxlciI7CiAgICB9CgogICAgLyoqCiAgICAgKiBVcG9uIGNsb3NlLCByZWdpc3RlciBmaWxlcyBvcGVuZWQgYnkgY3JlYXRle1NvdXJjZSwgQ2xhc3N9RmlsZQogICAgICogZm9yIGFubm90YXRpb24gcHJvY2Vzc2luZy4KICAgICAqLwogICAgcHJpdmF0ZSB2b2lkIGNsb3NlRmlsZU9iamVjdChNb2R1bGVTeW1ib2wgbW9kLCBTdHJpbmcgdHlwZU5hbWUsIEZpbGVPYmplY3QgZmlsZU9iamVjdCkgewogICAgICAgIC8qCiAgICAgICAgICogSWYgdHlwZU5hbWUgaXMgbm9uLW51bGwsIHRoZSBmaWxlIG9iamVjdCB3YXMgb3BlbmVkIGFzIGEKICAgICAgICAgKiBzb3VyY2Ugb3IgY2xhc3MgZmlsZSBieSB0aGUgdXNlci4gIElmIGEgZmlsZSB3YXMgb3BlbmVkIGFzCiAgICAgICAgICogYSByZXNvdXJjZSwgdHlwZU5hbWUgd2lsbCBiZSBudWxsIGFuZCB0aGUgZmlsZSBpcyAqbm90KgogICAgICAgICAqIHN1YmplY3QgdG8gYW5ub3RhdGlvbiBwcm9jZXNzaW5nLgogICAgICAgICAqLwogICAgICAgIGlmICgodHlwZU5hbWUgIT0gbnVsbCkpIHsKICAgICAgICAgICAgaWYgKCEoZmlsZU9iamVjdCBpbnN0YW5jZW9mIEphdmFGaWxlT2JqZWN0KSkKICAgICAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigiSmF2YUZpbGVPamVjdCBub3QgZm91bmQgZm9yICIgKyBmaWxlT2JqZWN0KTsKICAgICAgICAgICAgSmF2YUZpbGVPYmplY3QgamF2YUZpbGVPYmplY3QgPSAoSmF2YUZpbGVPYmplY3QpZmlsZU9iamVjdDsKICAgICAgICAgICAgc3dpdGNoKGphdmFGaWxlT2JqZWN0LmdldEtpbmQoKSkgewogICAgICAgICAgICBjYXNlIFNPVVJDRToKICAgICAgICAgICAgICAgIGdlbmVyYXRlZFNvdXJjZU5hbWVzLmFkZCh0eXBlTmFtZSk7CiAgICAgICAgICAgICAgICBnZW5lcmF0ZWRTb3VyY2VGaWxlT2JqZWN0cy5hZGQoamF2YUZpbGVPYmplY3QpOwogICAgICAgICAgICAgICAgb3BlblR5cGVOYW1lcy5yZW1vdmUodHlwZU5hbWUpOwogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIENMQVNTOgogICAgICAgICAgICAgICAgZ2VuZXJhdGVkQ2xhc3Nlcy5jb21wdXRlSWZBYnNlbnQobW9kLCBtIC0+IENvbGxlY3Rpb25zLnN5bmNocm9uaXplZE1hcChuZXcgTGlua2VkSGFzaE1hcDw+KCkpKS5wdXQodHlwZU5hbWUsIGphdmFGaWxlT2JqZWN0KTsKICAgICAgICAgICAgICAgIG9wZW5UeXBlTmFtZXMucmVtb3ZlKHR5cGVOYW1lKTsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKfQpQSwMECgAACAAA0n1NSq8A0Ir9FQAA/RUAADAAAABjb20vc3VuL3Rvb2xzL2phdmFjL3Byb2Nlc3NpbmcvU2VydmljZVByb3h5LmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDYsIDIwMTIsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhYy5wcm9jZXNzaW5nOwoKaW1wb3J0IGphdmEuaW8uQnVmZmVyZWRSZWFkZXI7CmltcG9ydCBqYXZhLmlvLkZpbGVOb3RGb3VuZEV4Y2VwdGlvbjsKaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CmltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOwppbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbVJlYWRlcjsKaW1wb3J0IGphdmEubmV0Lk1hbGZvcm1lZFVSTEV4Y2VwdGlvbjsKaW1wb3J0IGphdmEubmV0LlVSTDsKCi8qKgogKiBVdGlsaXR5IGNsYXNzIHRvIGRldGVybWluZSBpZiBhIHNlcnZpY2UgY2FuIGJlIGZvdW5kIG9uIHRoZQogKiBwYXRoIHRoYXQgbWlnaHQgYmUgdXNlZCB0byBjcmVhdGUgYSBjbGFzcyBsb2FkZXIuCiAqCiAqIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24gcmlzay4KICogVGhpcyBjb2RlIGFuZCBpdHMgaW50ZXJuYWwgaW50ZXJmYWNlcyBhcmUgc3ViamVjdCB0byBjaGFuZ2Ugb3IKICogZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPgogKgogKi8KLy8gYmFzZWQgb24gc3VuLm1pc2MuU2VydmljZQpjbGFzcyBTZXJ2aWNlUHJveHkgewogICAgc3RhdGljIGNsYXNzIFNlcnZpY2VDb25maWd1cmF0aW9uRXJyb3IgZXh0ZW5kcyBFcnJvciB7CiAgICAgICAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDc3MzIwOTEwMzY3NzEwOTgzMDNMOwoKICAgICAgICBTZXJ2aWNlQ29uZmlndXJhdGlvbkVycm9yKFN0cmluZyBtc2cpIHsKICAgICAgICAgICAgc3VwZXIobXNnKTsKICAgICAgICB9CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIHByZWZpeCA9ICJNRVRBLUlORi9zZXJ2aWNlcy8iOwoKICAgIHByaXZhdGUgc3RhdGljIHZvaWQgZmFpbChDbGFzczw/PiBzZXJ2aWNlLCBTdHJpbmcgbXNnKQogICAgICAgICAgICB0aHJvd3MgU2VydmljZUNvbmZpZ3VyYXRpb25FcnJvciB7CiAgICAgICAgdGhyb3cgbmV3IFNlcnZpY2VDb25maWd1cmF0aW9uRXJyb3Ioc2VydmljZS5nZXROYW1lKCkgKyAiOiAiICsgbXNnKTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGZhaWwoQ2xhc3M8Pz4gc2VydmljZSwgVVJMIHUsIGludCBsaW5lLCBTdHJpbmcgbXNnKQogICAgICAgICAgICB0aHJvd3MgU2VydmljZUNvbmZpZ3VyYXRpb25FcnJvciB7CiAgICAgICAgZmFpbChzZXJ2aWNlLCB1ICsgIjoiICsgbGluZSArICI6ICIgKyBtc2cpOwogICAgfQoKICAgIC8qKgogICAgICogUGFyc2UgdGhlIGNvbnRlbnQgb2YgdGhlIGdpdmVuIFVSTCBhcyBhIHByb3ZpZGVyLWNvbmZpZ3VyYXRpb24gZmlsZS4KICAgICAqCiAgICAgKiBAcGFyYW0gIHNlcnZpY2UKICAgICAqICAgICAgICAgVGhlIHNlcnZpY2UgY2xhc3MgZm9yIHdoaWNoIHByb3ZpZGVycyBhcmUgYmVpbmcgc291Z2h0OwogICAgICogICAgICAgICB1c2VkIHRvIGNvbnN0cnVjdCBlcnJvciBkZXRhaWwgc3RyaW5ncwogICAgICoKICAgICAqIEBwYXJhbSAgdQogICAgICogICAgICAgICBUaGUgVVJMIG5hbWluZyB0aGUgY29uZmlndXJhdGlvbiBmaWxlIHRvIGJlIHBhcnNlZAogICAgICoKICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgbmFtZSBvZiBhIHNlcnZpY2UgaXMgZm91bmQKICAgICAqCiAgICAgKiBAdGhyb3dzIFNlcnZpY2VDb25maWd1cmF0aW9uRXJyb3IKICAgICAqICAgICAgICAgSWYgYW4gSS9PIGVycm9yIG9jY3VycyB3aGlsZSByZWFkaW5nIGZyb20gdGhlIGdpdmVuIFVSTCwgb3IKICAgICAqICAgICAgICAgaWYgYSBjb25maWd1cmF0aW9uLWZpbGUgZm9ybWF0IGVycm9yIGlzIGRldGVjdGVkCiAgICAgKi8KICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gcGFyc2UoQ2xhc3M8Pz4gc2VydmljZSwgVVJMIHUpIHRocm93cyBTZXJ2aWNlQ29uZmlndXJhdGlvbkVycm9yIHsKICAgICAgICBJbnB1dFN0cmVhbSBpbiA9IG51bGw7CiAgICAgICAgQnVmZmVyZWRSZWFkZXIgciA9IG51bGw7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgaW4gPSB1Lm9wZW5TdHJlYW0oKTsKICAgICAgICAgICAgciA9IG5ldyBCdWZmZXJlZFJlYWRlcihuZXcgSW5wdXRTdHJlYW1SZWFkZXIoaW4sICJ1dGYtOCIpKTsKICAgICAgICAgICAgaW50IGxjID0gMTsKICAgICAgICAgICAgU3RyaW5nIGxuOwogICAgICAgICAgICB3aGlsZSAoKGxuID0gci5yZWFkTGluZSgpKSAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICBpbnQgY2kgPSBsbi5pbmRleE9mKCcjJyk7CiAgICAgICAgICAgICAgICBpZiAoY2kgPj0gMCkgbG4gPSBsbi5zdWJzdHJpbmcoMCwgY2kpOwogICAgICAgICAgICAgICAgbG4gPSBsbi50cmltKCk7CiAgICAgICAgICAgICAgICBpbnQgbiA9IGxuLmxlbmd0aCgpOwogICAgICAgICAgICAgICAgaWYgKG4gIT0gMCkgewogICAgICAgICAgICAgICAgICAgIGlmICgobG4uaW5kZXhPZignICcpID49IDApIHx8IChsbi5pbmRleE9mKCdcdCcpID49IDApKQogICAgICAgICAgICAgICAgICAgICAgICBmYWlsKHNlcnZpY2UsIHUsIGxjLCAiSWxsZWdhbCBjb25maWd1cmF0aW9uLWZpbGUgc3ludGF4Iik7CiAgICAgICAgICAgICAgICAgICAgaW50IGNwID0gbG4uY29kZVBvaW50QXQoMCk7CiAgICAgICAgICAgICAgICAgICAgaWYgKCFDaGFyYWN0ZXIuaXNKYXZhSWRlbnRpZmllclN0YXJ0KGNwKSkKICAgICAgICAgICAgICAgICAgICAgICAgZmFpbChzZXJ2aWNlLCB1LCBsYywgIklsbGVnYWwgcHJvdmlkZXItY2xhc3MgbmFtZTogIiArIGxuKTsKICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gQ2hhcmFjdGVyLmNoYXJDb3VudChjcCk7IGkgPCBuOyBpICs9IENoYXJhY3Rlci5jaGFyQ291bnQoY3ApKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNwID0gbG4uY29kZVBvaW50QXQoaSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghQ2hhcmFjdGVyLmlzSmF2YUlkZW50aWZpZXJQYXJ0KGNwKSAmJiAoY3AgIT0gJy4nKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhaWwoc2VydmljZSwgdSwgbGMsICJJbGxlZ2FsIHByb3ZpZGVyLWNsYXNzIG5hbWU6ICIgKyBsbik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSBjYXRjaCAoRmlsZU5vdEZvdW5kRXhjZXB0aW9uIHgpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIHgpIHsKICAgICAgICAgICAgZmFpbChzZXJ2aWNlLCAiOiAiICsgeCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIGlmIChyICE9IG51bGwpIHIuY2xvc2UoKTsKICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24geSkgewogICAgICAgICAgICAgICAgZmFpbChzZXJ2aWNlLCAiOiAiICsgeSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIGlmIChpbiAhPSBudWxsKSBpbi5jbG9zZSgpOwogICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiB5KSB7CiAgICAgICAgICAgICAgICBmYWlsKHNlcnZpY2UsICI6ICIgKyB5KTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm4gdHJ1ZSBpZiBhIGRlc2NyaXB0aW9uIGZvciBhdCBsZWFzdCBvbmUgc2VydmljZSBpcyBmb3VuZCBpbiB0aGUKICAgICAqIHNlcnZpY2UgY29uZmlndXJhdGlvbiBmaWxlcyBpbiB0aGUgZ2l2ZW4gVVJMcy4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBib29sZWFuIGhhc1NlcnZpY2UoQ2xhc3M8Pz4gc2VydmljZSwgVVJMW10gdXJscykKICAgICAgICAgICAgdGhyb3dzIFNlcnZpY2VDb25maWd1cmF0aW9uRXJyb3IgewogICAgICAgIGZvciAoVVJMIHVybDogdXJscykgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgU3RyaW5nIGZ1bGxOYW1lID0gcHJlZml4ICsgc2VydmljZS5nZXROYW1lKCk7CiAgICAgICAgICAgICAgICBVUkwgdSA9IG5ldyBVUkwodXJsLCBmdWxsTmFtZSk7CiAgICAgICAgICAgICAgICBib29sZWFuIGZvdW5kID0gcGFyc2Uoc2VydmljZSwgdSk7CiAgICAgICAgICAgICAgICBpZiAoZm91bmQpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0gY2F0Y2ggKE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgICAvLyBzaG91bGQgbm90IGhhcHBlbjsgaWdub3JlIGl0IGlmIGl0IGRvZXMKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9Cn0KUEsDBAoAAAgAAAY7qUotfJe7ugUBALoFAQA+AAAAY29tL3N1bi90b29scy9qYXZhYy9wcm9jZXNzaW5nL0phdmFjUHJvY2Vzc2luZ0Vudmlyb25tZW50LmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMTcsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhYy5wcm9jZXNzaW5nOwoKaW1wb3J0IGphdmEuaW8uQ2xvc2VhYmxlOwppbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKaW1wb3J0IGphdmEuaW8uUHJpbnRXcml0ZXI7CmltcG9ydCBqYXZhLmlvLlN0cmluZ1dyaXRlcjsKaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0Lk1ldGhvZDsKaW1wb3J0IGphdmEubmV0Lk1hbGZvcm1lZFVSTEV4Y2VwdGlvbjsKaW1wb3J0IGphdmEubmV0LlVSTDsKaW1wb3J0IGphdmEubmlvLmZpbGUuUGF0aDsKaW1wb3J0IGphdmEudXRpbC4qOwppbXBvcnQgamF2YS51dGlsLk1hcC5FbnRyeTsKaW1wb3J0IGphdmEudXRpbC5yZWdleC4qOwppbXBvcnQgamF2YS51dGlsLnN0cmVhbS5Db2xsZWN0b3JzOwoKaW1wb3J0IGphdmF4LmFubm90YXRpb24ucHJvY2Vzc2luZy4qOwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5Tb3VyY2VWZXJzaW9uOwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5lbGVtZW50Lio7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLnV0aWwuKjsKaW1wb3J0IGphdmF4LnRvb2xzLkphdmFGaWxlTWFuYWdlcjsKaW1wb3J0IGphdmF4LnRvb2xzLkphdmFGaWxlT2JqZWN0OwppbXBvcnQgamF2YXgudG9vbHMuSmF2YUZpbGVPYmplY3QuS2luZDsKaW1wb3J0IGphdmF4LnRvb2xzLlN0YW5kYXJkSmF2YUZpbGVNYW5hZ2VyOwoKaW1wb3J0IHN0YXRpYyBqYXZheC50b29scy5TdGFuZGFyZExvY2F0aW9uLio7CgppbXBvcnQgY29tLnN1bi5zb3VyY2UudXRpbC5UYXNrRXZlbnQ7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmFwaS5NdWx0aVRhc2tMaXN0ZW5lcjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS4qOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlNjb3BlLldyaXRlYWJsZVNjb3BlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlN5bWJvbC4qOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlR5cGUuQ2xhc3NUeXBlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlR5cGVzOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb21wLkF0dHJDb250ZXh0OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb21wLkNoZWNrOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb21wLkVudGVyOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb21wLkVudjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29tcC5Nb2R1bGVzOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5maWxlLkphdmFjRmlsZU1hbmFnZXI7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLm1haW4uSmF2YUNvbXBpbGVyOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5tYWluLk9wdGlvbjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMubW9kZWwuSmF2YWNFbGVtZW50czsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMubW9kZWwuSmF2YWNUeXBlczsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMucGxhdGZvcm0uUGxhdGZvcm1EZXNjcmlwdGlvbjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMucGxhdGZvcm0uUGxhdGZvcm1EZXNjcmlwdGlvbi5QbHVnaW5JbmZvOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5yZXNvdXJjZXMuQ29tcGlsZXJQcm9wZXJ0aWVzLkVycm9yczsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS4qOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkpDVHJlZS4qOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkFib3J0OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkFzc2VydDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5DbGllbnRDb2RlRXhjZXB0aW9uOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkNvbnRleHQ7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuQ29udmVydDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5EZWZpbmVkQnk7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuRGVmaW5lZEJ5LkFwaTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5JdGVyYXRvcnM7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuSkNEaWFnbm9zdGljOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkpESzlXcmFwcGVycy5Nb2R1bGU7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuSmF2YWNNZXNzYWdlczsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5MaXN0OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkxvZzsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5NYXRjaGluZ1V0aWxzOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLk1vZHVsZUhlbHBlcjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5OYW1lOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLk5hbWVzOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLk9wdGlvbnM7CgppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5MaW50LkxpbnRDYXRlZ29yeS5QUk9DRVNTSU5HOwppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5LaW5kcy5LaW5kLio7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvbXAuQW5ub3RhdGU7CmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5jb21wLkNvbXBpbGVTdGF0ZXMuQ29tcGlsZVN0YXRlOwppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5KQ0RpYWdub3N0aWMuRGlhZ25vc3RpY0ZsYWcuKjsKCi8qKgogKiBPYmplY3RzIG9mIHRoaXMgY2xhc3MgaG9sZCBhbmQgbWFuYWdlIHRoZSBzdGF0ZSBuZWVkZWQgdG8gc3VwcG9ydAogKiBhbm5vdGF0aW9uIHByb2Nlc3NpbmcuCiAqCiAqIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24gcmlzay4KICogVGhpcyBjb2RlIGFuZCBpdHMgaW50ZXJuYWwgaW50ZXJmYWNlcyBhcmUgc3ViamVjdCB0byBjaGFuZ2Ugb3IKICogZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPgogKi8KcHVibGljIGNsYXNzIEphdmFjUHJvY2Vzc2luZ0Vudmlyb25tZW50IGltcGxlbWVudHMgUHJvY2Vzc2luZ0Vudmlyb25tZW50LCBDbG9zZWFibGUgewogICAgcHJpdmF0ZSBmaW5hbCBPcHRpb25zIG9wdGlvbnM7CgogICAgcHJpdmF0ZSBmaW5hbCBib29sZWFuIHByaW50UHJvY2Vzc29ySW5mbzsKICAgIHByaXZhdGUgZmluYWwgYm9vbGVhbiBwcmludFJvdW5kczsKICAgIHByaXZhdGUgZmluYWwgYm9vbGVhbiB2ZXJib3NlOwogICAgcHJpdmF0ZSBmaW5hbCBib29sZWFuIGxpbnQ7CiAgICBwcml2YXRlIGZpbmFsIGJvb2xlYW4gZmF0YWxFcnJvcnM7CiAgICBwcml2YXRlIGZpbmFsIGJvb2xlYW4gd2Vycm9yOwogICAgcHJpdmF0ZSBmaW5hbCBib29sZWFuIHNob3dSZXNvbHZlRXJyb3JzOwogICAgcHJpdmF0ZSBmaW5hbCBib29sZWFuIGFsbG93TW9kdWxlczsKCiAgICBwcml2YXRlIGZpbmFsIEphdmFjRmlsZXIgZmlsZXI7CiAgICBwcml2YXRlIGZpbmFsIEphdmFjTWVzc2FnZXIgbWVzc2FnZXI7CiAgICBwcml2YXRlIGZpbmFsIEphdmFjRWxlbWVudHMgZWxlbWVudFV0aWxzOwogICAgcHJpdmF0ZSBmaW5hbCBKYXZhY1R5cGVzIHR5cGVVdGlsczsKICAgIHByaXZhdGUgZmluYWwgSmF2YUNvbXBpbGVyIGNvbXBpbGVyOwogICAgcHJpdmF0ZSBmaW5hbCBNb2R1bGVzIG1vZHVsZXM7CiAgICBwcml2YXRlIGZpbmFsIFR5cGVzIHR5cGVzOwogICAgcHJpdmF0ZSBmaW5hbCBBbm5vdGF0ZSBhbm5vdGF0ZTsKCiAgICAvKioKICAgICAqIEhvbGRzIHJlbGV2YW50IHN0YXRlIGhpc3Rvcnkgb2Ygd2hpY2ggcHJvY2Vzc29ycyBoYXZlIGJlZW4KICAgICAqIHVzZWQuCiAgICAgKi8KICAgIHByaXZhdGUgRGlzY292ZXJlZFByb2Nlc3NvcnMgZGlzY292ZXJlZFByb2NzOwoKICAgIC8qKgogICAgICogTWFwIG9mIHByb2Nlc3Nvci1zcGVjaWZpYyBvcHRpb25zLgogICAgICovCiAgICBwcml2YXRlIGZpbmFsIE1hcDxTdHJpbmcsIFN0cmluZz4gcHJvY2Vzc29yT3B0aW9uczsKCiAgICAvKioKICAgICAqLwogICAgcHJpdmF0ZSBmaW5hbCBTZXQ8U3RyaW5nPiB1bm1hdGNoZWRQcm9jZXNzb3JPcHRpb25zOwoKICAgIC8qKgogICAgICogQW5ub3RhdGlvbnMgaW1wbGljaXRseSBwcm9jZXNzZWQgYW5kIGNsYWltZWQgYnkgamF2YWMuCiAgICAgKi8KICAgIHByaXZhdGUgZmluYWwgU2V0PFN0cmluZz4gcGxhdGZvcm1Bbm5vdGF0aW9uczsKCiAgICAvKioKICAgICAqIFNldCBvZiBwYWNrYWdlcyBnaXZlbiBvbiBjb21tYW5kIGxpbmUuCiAgICAgKi8KICAgIHByaXZhdGUgU2V0PFBhY2thZ2VTeW1ib2w+IHNwZWNpZmllZFBhY2thZ2VzID0gQ29sbGVjdGlvbnMuZW1wdHlTZXQoKTsKCiAgICAvKiogVGhlIGxvZyB0byBiZSB1c2VkIGZvciBlcnJvciByZXBvcnRpbmcuCiAgICAgKi8KICAgIGZpbmFsIExvZyBsb2c7CgogICAgLyoqIERpYWdub3N0aWMgZmFjdG9yeS4KICAgICAqLwogICAgSkNEaWFnbm9zdGljLkZhY3RvcnkgZGlhZ3M7CgogICAgLyoqCiAgICAgKiBTb3VyY2UgbGV2ZWwgb2YgdGhlIGNvbXBpbGUuCiAgICAgKi8KICAgIFNvdXJjZSBzb3VyY2U7CgogICAgcHJpdmF0ZSBDbGFzc0xvYWRlciBwcm9jZXNzb3JDbGFzc0xvYWRlcjsKICAgIHByaXZhdGUgU2VydmljZUxvYWRlcjxQcm9jZXNzb3I+IHNlcnZpY2VMb2FkZXI7CiAgICBwcml2YXRlIFNlY3VyaXR5RXhjZXB0aW9uIHByb2Nlc3NvckxvYWRlckV4Y2VwdGlvbjsKCiAgICBwcml2YXRlIGZpbmFsIEphdmFGaWxlTWFuYWdlciBmaWxlTWFuYWdlcjsKCiAgICAvKioKICAgICAqIEphdmFjTWVzc2FnZXMgb2JqZWN0IHVzZWQgZm9yIGxvY2FsaXphdGlvbgogICAgICovCiAgICBwcml2YXRlIEphdmFjTWVzc2FnZXMgbWVzc2FnZXM7CgogICAgcHJpdmF0ZSBNdWx0aVRhc2tMaXN0ZW5lciB0YXNrTGlzdGVuZXI7CiAgICBwcml2YXRlIGZpbmFsIFN5bXRhYiBzeW10YWI7CiAgICBwcml2YXRlIGZpbmFsIE5hbWVzIG5hbWVzOwogICAgcHJpdmF0ZSBmaW5hbCBFbnRlciBlbnRlcjsKICAgIHByaXZhdGUgZmluYWwgQ29tcGxldGVyIGluaXRpYWxDb21wbGV0ZXI7CiAgICBwcml2YXRlIGZpbmFsIENoZWNrIGNoazsKCiAgICBwcml2YXRlIGZpbmFsIENvbnRleHQgY29udGV4dDsKCiAgICAvKiogR2V0IHRoZSBKYXZhY1Byb2Nlc3NpbmdFbnZpcm9ubWVudCBpbnN0YW5jZSBmb3IgdGhpcyBjb250ZXh0LiAqLwogICAgcHVibGljIHN0YXRpYyBKYXZhY1Byb2Nlc3NpbmdFbnZpcm9ubWVudCBpbnN0YW5jZShDb250ZXh0IGNvbnRleHQpIHsKICAgICAgICBKYXZhY1Byb2Nlc3NpbmdFbnZpcm9ubWVudCBpbnN0YW5jZSA9IGNvbnRleHQuZ2V0KEphdmFjUHJvY2Vzc2luZ0Vudmlyb25tZW50LmNsYXNzKTsKICAgICAgICBpZiAoaW5zdGFuY2UgPT0gbnVsbCkKICAgICAgICAgICAgaW5zdGFuY2UgPSBuZXcgSmF2YWNQcm9jZXNzaW5nRW52aXJvbm1lbnQoY29udGV4dCk7CiAgICAgICAgcmV0dXJuIGluc3RhbmNlOwogICAgfQoKICAgIHByb3RlY3RlZCBKYXZhY1Byb2Nlc3NpbmdFbnZpcm9ubWVudChDb250ZXh0IGNvbnRleHQpIHsKICAgICAgICB0aGlzLmNvbnRleHQgPSBjb250ZXh0OwogICAgICAgIGNvbnRleHQucHV0KEphdmFjUHJvY2Vzc2luZ0Vudmlyb25tZW50LmNsYXNzLCB0aGlzKTsKICAgICAgICBsb2cgPSBMb2cuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgc291cmNlID0gU291cmNlLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIGRpYWdzID0gSkNEaWFnbm9zdGljLkZhY3RvcnkuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgb3B0aW9ucyA9IE9wdGlvbnMuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgcHJpbnRQcm9jZXNzb3JJbmZvID0gb3B0aW9ucy5pc1NldChPcHRpb24uWFBSSU5UUFJPQ0VTU09SSU5GTyk7CiAgICAgICAgcHJpbnRSb3VuZHMgPSBvcHRpb25zLmlzU2V0KE9wdGlvbi5YUFJJTlRST1VORFMpOwogICAgICAgIHZlcmJvc2UgPSBvcHRpb25zLmlzU2V0KE9wdGlvbi5WRVJCT1NFKTsKICAgICAgICBsaW50ID0gTGludC5pbnN0YW5jZShjb250ZXh0KS5pc0VuYWJsZWQoUFJPQ0VTU0lORyk7CiAgICAgICAgY29tcGlsZXIgPSBKYXZhQ29tcGlsZXIuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgaWYgKG9wdGlvbnMuaXNTZXQoT3B0aW9uLlBST0MsICJvbmx5IikgfHwgb3B0aW9ucy5pc1NldChPcHRpb24uWFBSSU5UKSkgewogICAgICAgICAgICBjb21waWxlci5zaG91bGRTdG9wUG9saWN5SWZOb0Vycm9yID0gQ29tcGlsZVN0YXRlLlBST0NFU1M7CiAgICAgICAgfQogICAgICAgIGZhdGFsRXJyb3JzID0gb3B0aW9ucy5pc1NldCgiZmF0YWxFbnRlckVycm9yIik7CiAgICAgICAgc2hvd1Jlc29sdmVFcnJvcnMgPSBvcHRpb25zLmlzU2V0KCJzaG93UmVzb2x2ZUVycm9ycyIpOwogICAgICAgIHdlcnJvciA9IG9wdGlvbnMuaXNTZXQoT3B0aW9uLldFUlJPUik7CiAgICAgICAgZmlsZU1hbmFnZXIgPSBjb250ZXh0LmdldChKYXZhRmlsZU1hbmFnZXIuY2xhc3MpOwogICAgICAgIHBsYXRmb3JtQW5ub3RhdGlvbnMgPSBpbml0UGxhdGZvcm1Bbm5vdGF0aW9ucygpOwoKICAgICAgICAvLyBJbml0aWFsaXplIHNlcnZpY2VzIGJlZm9yZSBhbnkgcHJvY2Vzc29ycyBhcmUgaW5pdGlhbGl6ZWQKICAgICAgICAvLyBpbiBjYXNlIHByb2Nlc3NvcnMgdXNlIHRoZW0uCiAgICAgICAgZmlsZXIgPSBuZXcgSmF2YWNGaWxlcihjb250ZXh0KTsKICAgICAgICBtZXNzYWdlciA9IG5ldyBKYXZhY01lc3NhZ2VyKGNvbnRleHQsIHRoaXMpOwogICAgICAgIGVsZW1lbnRVdGlscyA9IEphdmFjRWxlbWVudHMuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgdHlwZVV0aWxzID0gSmF2YWNUeXBlcy5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBtb2R1bGVzID0gTW9kdWxlcy5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICB0eXBlcyA9IFR5cGVzLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIGFubm90YXRlID0gQW5ub3RhdGUuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgcHJvY2Vzc29yT3B0aW9ucyA9IGluaXRQcm9jZXNzb3JPcHRpb25zKCk7CiAgICAgICAgdW5tYXRjaGVkUHJvY2Vzc29yT3B0aW9ucyA9IGluaXRVbm1hdGNoZWRQcm9jZXNzb3JPcHRpb25zKCk7CiAgICAgICAgbWVzc2FnZXMgPSBKYXZhY01lc3NhZ2VzLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIHRhc2tMaXN0ZW5lciA9IE11bHRpVGFza0xpc3RlbmVyLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIHN5bXRhYiA9IFN5bXRhYi5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBuYW1lcyA9IE5hbWVzLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIGVudGVyID0gRW50ZXIuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgaW5pdGlhbENvbXBsZXRlciA9IENsYXNzRmluZGVyLmluc3RhbmNlKGNvbnRleHQpLmdldENvbXBsZXRlcigpOwogICAgICAgIGNoayA9IENoZWNrLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIGluaXRQcm9jZXNzb3JMb2FkZXIoKTsKCiAgICAgICAgYWxsb3dNb2R1bGVzID0gc291cmNlLmFsbG93TW9kdWxlcygpOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHNldFByb2Nlc3NvcnMoSXRlcmFibGU8PyBleHRlbmRzIFByb2Nlc3Nvcj4gcHJvY2Vzc29ycykgewogICAgICAgIEFzc2VydC5jaGVja051bGwoZGlzY292ZXJlZFByb2NzKTsKICAgICAgICBpbml0UHJvY2Vzc29ySXRlcmF0b3IocHJvY2Vzc29ycyk7CiAgICB9CgogICAgcHJpdmF0ZSBTZXQ8U3RyaW5nPiBpbml0UGxhdGZvcm1Bbm5vdGF0aW9ucygpIHsKICAgICAgICBTZXQ8U3RyaW5nPiBwbGF0Zm9ybUFubm90YXRpb25zID0gbmV3IEhhc2hTZXQ8PigpOwogICAgICAgIHBsYXRmb3JtQW5ub3RhdGlvbnMuYWRkKCJqYXZhLmxhbmcuRGVwcmVjYXRlZCIpOwogICAgICAgIHBsYXRmb3JtQW5ub3RhdGlvbnMuYWRkKCJqYXZhLmxhbmcuT3ZlcnJpZGUiKTsKICAgICAgICBwbGF0Zm9ybUFubm90YXRpb25zLmFkZCgiamF2YS5sYW5nLlN1cHByZXNzV2FybmluZ3MiKTsKICAgICAgICBwbGF0Zm9ybUFubm90YXRpb25zLmFkZCgiamF2YS5sYW5nLmFubm90YXRpb24uRG9jdW1lbnRlZCIpOwogICAgICAgIHBsYXRmb3JtQW5ub3RhdGlvbnMuYWRkKCJqYXZhLmxhbmcuYW5ub3RhdGlvbi5Jbmhlcml0ZWQiKTsKICAgICAgICBwbGF0Zm9ybUFubm90YXRpb25zLmFkZCgiamF2YS5sYW5nLmFubm90YXRpb24uUmV0ZW50aW9uIik7CiAgICAgICAgcGxhdGZvcm1Bbm5vdGF0aW9ucy5hZGQoImphdmEubGFuZy5hbm5vdGF0aW9uLlRhcmdldCIpOwogICAgICAgIHJldHVybiBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVTZXQocGxhdGZvcm1Bbm5vdGF0aW9ucyk7CiAgICB9CgogICAgcHJpdmF0ZSB2b2lkIGluaXRQcm9jZXNzb3JMb2FkZXIoKSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgaWYgKGZpbGVNYW5hZ2VyLmhhc0xvY2F0aW9uKEFOTk9UQVRJT05fUFJPQ0VTU09SX01PRFVMRV9QQVRIKSkgewogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICBzZXJ2aWNlTG9hZGVyID0gZmlsZU1hbmFnZXIuZ2V0U2VydmljZUxvYWRlcihBTk5PVEFUSU9OX1BST0NFU1NPUl9NT0RVTEVfUEFUSCwgUHJvY2Vzc29yLmNsYXNzKTsKICAgICAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQWJvcnQoZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvLyBJZiBwcm9jZXNzb3JwYXRoIGlzIG5vdCBleHBsaWNpdGx5IHNldCwgdXNlIHRoZSBjbGFzc3BhdGguCiAgICAgICAgICAgICAgICBwcm9jZXNzb3JDbGFzc0xvYWRlciA9IGZpbGVNYW5hZ2VyLmhhc0xvY2F0aW9uKEFOTk9UQVRJT05fUFJPQ0VTU09SX1BBVEgpCiAgICAgICAgICAgICAgICAgICAgPyBmaWxlTWFuYWdlci5nZXRDbGFzc0xvYWRlcihBTk5PVEFUSU9OX1BST0NFU1NPUl9QQVRIKQogICAgICAgICAgICAgICAgICAgIDogZmlsZU1hbmFnZXIuZ2V0Q2xhc3NMb2FkZXIoQ0xBU1NfUEFUSCk7CgogICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMuaXNTZXQoImFjY2Vzc0ludGVybmFsQVBJIikpCiAgICAgICAgICAgICAgICAgICAgTW9kdWxlSGVscGVyLmFkZEV4cG9ydHMoTW9kdWxlLmdldE1vZHVsZShnZXRDbGFzcygpKSwgTW9kdWxlLmdldFVubmFtZWRNb2R1bGUocHJvY2Vzc29yQ2xhc3NMb2FkZXIpKTsKCiAgICAgICAgICAgICAgICBpZiAocHJvY2Vzc29yQ2xhc3NMb2FkZXIgIT0gbnVsbCAmJiBwcm9jZXNzb3JDbGFzc0xvYWRlciBpbnN0YW5jZW9mIENsb3NlYWJsZSkgewogICAgICAgICAgICAgICAgICAgIGNvbXBpbGVyLmNsb3NlYWJsZXMgPSBjb21waWxlci5jbG9zZWFibGVzLnByZXBlbmQoKENsb3NlYWJsZSkgcHJvY2Vzc29yQ2xhc3NMb2FkZXIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSBjYXRjaCAoU2VjdXJpdHlFeGNlcHRpb24gZSkgewogICAgICAgICAgICBwcm9jZXNzb3JMb2FkZXJFeGNlcHRpb24gPSBlOwogICAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIHZvaWQgaW5pdFByb2Nlc3Nvckl0ZXJhdG9yKEl0ZXJhYmxlPD8gZXh0ZW5kcyBQcm9jZXNzb3I+IHByb2Nlc3NvcnMpIHsKICAgICAgICBJdGVyYXRvcjw/IGV4dGVuZHMgUHJvY2Vzc29yPiBwcm9jZXNzb3JJdGVyYXRvcjsKCiAgICAgICAgaWYgKG9wdGlvbnMuaXNTZXQoT3B0aW9uLlhQUklOVCkpIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIHByb2Nlc3Nvckl0ZXJhdG9yID0gTGlzdC5vZihuZXcgUHJpbnRpbmdQcm9jZXNzb3IoKSkuaXRlcmF0b3IoKTsKICAgICAgICAgICAgfSBjYXRjaCAoVGhyb3dhYmxlIHQpIHsKICAgICAgICAgICAgICAgIEFzc2VydGlvbkVycm9yIGFzc2VydEVycm9yID0KICAgICAgICAgICAgICAgICAgICBuZXcgQXNzZXJ0aW9uRXJyb3IoIlByb2JsZW0gaW5zdGFudGlhdGluZyBQcmludGluZ1Byb2Nlc3Nvci4iKTsKICAgICAgICAgICAgICAgIGFzc2VydEVycm9yLmluaXRDYXVzZSh0KTsKICAgICAgICAgICAgICAgIHRocm93IGFzc2VydEVycm9yOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmIChwcm9jZXNzb3JzICE9IG51bGwpIHsKICAgICAgICAgICAgcHJvY2Vzc29ySXRlcmF0b3IgPSBwcm9jZXNzb3JzLml0ZXJhdG9yKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgaWYgKHByb2Nlc3NvckxvYWRlckV4Y2VwdGlvbiA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogSWYgdGhlICItcHJvY2Vzc29yIiBvcHRpb24gaXMgdXNlZCwgc2VhcmNoIHRoZSBhcHByb3ByaWF0ZQogICAgICAgICAgICAgICAgICogcGF0aCBmb3IgdGhlIG5hbWVkIGNsYXNzLiAgT3RoZXJ3aXNlLCB1c2UgYSBzZXJ2aWNlCiAgICAgICAgICAgICAgICAgKiBwcm92aWRlciBtZWNoYW5pc20gdG8gY3JlYXRlIHRoZSBwcm9jZXNzb3IgaXRlcmF0b3IuCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIFN0cmluZyBwcm9jZXNzb3JOYW1lcyA9IG9wdGlvbnMuZ2V0KE9wdGlvbi5QUk9DRVNTT1IpOwogICAgICAgICAgICAgICAgaWYgKGZpbGVNYW5hZ2VyLmhhc0xvY2F0aW9uKEFOTk9UQVRJT05fUFJPQ0VTU09SX01PRFVMRV9QQVRIKSkgewogICAgICAgICAgICAgICAgICAgIHByb2Nlc3Nvckl0ZXJhdG9yID0gKHByb2Nlc3Nvck5hbWVzID09IG51bGwpID8KICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBTZXJ2aWNlSXRlcmF0b3Ioc2VydmljZUxvYWRlciwgbG9nKSA6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgTmFtZVNlcnZpY2VJdGVyYXRvcihzZXJ2aWNlTG9hZGVyLCBsb2csIHByb2Nlc3Nvck5hbWVzKTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocHJvY2Vzc29yTmFtZXMgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIHByb2Nlc3Nvckl0ZXJhdG9yID0gbmV3IE5hbWVQcm9jZXNzSXRlcmF0b3IocHJvY2Vzc29yTmFtZXMsIHByb2Nlc3NvckNsYXNzTG9hZGVyLCBsb2cpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBwcm9jZXNzb3JJdGVyYXRvciA9IG5ldyBTZXJ2aWNlSXRlcmF0b3IocHJvY2Vzc29yQ2xhc3NMb2FkZXIsIGxvZyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogQSBzZWN1cml0eSBleGNlcHRpb24gd2lsbCBvY2N1ciBpZiB3ZSBjYW4ndCBjcmVhdGUgYSBjbGFzc2xvYWRlci4KICAgICAgICAgICAgICAgICAqIElnbm9yZSB0aGUgZXhjZXB0aW9uIGlmLCB3aXRoIGhpbmRzaWdodCwgd2UgZGlkbid0IG5lZWQgaXQgYW55d2F5CiAgICAgICAgICAgICAgICAgKiAoaS5lLiBubyBwcm9jZXNzb3Igd2FzIHNwZWNpZmllZCBlaXRoZXIgZXhwbGljaXRseSwgb3IgaW1wbGljaXRseSwKICAgICAgICAgICAgICAgICAqIGluIHNlcnZpY2UgY29uZmlndXJhdGlvbiBmaWxlLikgT3RoZXJ3aXNlLCB3ZSBjYW5ub3QgY29udGludWUuCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIHByb2Nlc3Nvckl0ZXJhdG9yID0gaGFuZGxlU2VydmljZUxvYWRlclVuYXZhaWxhYmlsaXR5KCJwcm9jLmNhbnQuY3JlYXRlLmxvYWRlciIsCiAgICAgICAgICAgICAgICAgICAgICAgIHByb2Nlc3NvckxvYWRlckV4Y2VwdGlvbik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgUGxhdGZvcm1EZXNjcmlwdGlvbiBwbGF0Zm9ybVByb3ZpZGVyID0gY29udGV4dC5nZXQoUGxhdGZvcm1EZXNjcmlwdGlvbi5jbGFzcyk7CiAgICAgICAgamF2YS51dGlsLkxpc3Q8UHJvY2Vzc29yPiBwbGF0Zm9ybVByb2Nlc3NvcnMgPSBDb2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICBpZiAocGxhdGZvcm1Qcm92aWRlciAhPSBudWxsKSB7CiAgICAgICAgICAgIHBsYXRmb3JtUHJvY2Vzc29ycyA9IHBsYXRmb3JtUHJvdmlkZXIuZ2V0QW5ub3RhdGlvblByb2Nlc3NvcnMoKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnN0cmVhbSgpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAubWFwKFBsdWdpbkluZm86OmdldFBsdWdpbikKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jb2xsZWN0KENvbGxlY3RvcnMudG9MaXN0KCkpOwogICAgICAgIH0KICAgICAgICBMaXN0PEl0ZXJhdG9yPD8gZXh0ZW5kcyBQcm9jZXNzb3I+PiBpdGVyYXRvcnMgPSBMaXN0Lm9mKHByb2Nlc3Nvckl0ZXJhdG9yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGxhdGZvcm1Qcm9jZXNzb3JzLml0ZXJhdG9yKCkpOwogICAgICAgIEl0ZXJhdG9yPD8gZXh0ZW5kcyBQcm9jZXNzb3I+IGNvbXBvdW5kSXRlcmF0b3IgPQogICAgICAgICAgICAgICAgSXRlcmF0b3JzLmNyZWF0ZUNvbXBvdW5kSXRlcmF0b3IoaXRlcmF0b3JzLCBpIC0+IGkpOwogICAgICAgIGRpc2NvdmVyZWRQcm9jcyA9IG5ldyBEaXNjb3ZlcmVkUHJvY2Vzc29ycyhjb21wb3VuZEl0ZXJhdG9yKTsKICAgIH0KCiAgICBwdWJsaWMgPFM+IFNlcnZpY2VMb2FkZXI8Uz4gZ2V0U2VydmljZUxvYWRlcihDbGFzczxTPiBzZXJ2aWNlKSB7CiAgICAgICAgaWYgKGZpbGVNYW5hZ2VyLmhhc0xvY2F0aW9uKEFOTk9UQVRJT05fUFJPQ0VTU09SX01PRFVMRV9QQVRIKSkgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZpbGVNYW5hZ2VyLmdldFNlcnZpY2VMb2FkZXIoQU5OT1RBVElPTl9QUk9DRVNTT1JfTU9EVUxFX1BBVEgsIHNlcnZpY2UpOwogICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQWJvcnQoZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gU2VydmljZUxvYWRlci5sb2FkKHNlcnZpY2UsIGdldFByb2Nlc3NvckNsYXNzTG9hZGVyKCkpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgYW4gZW1wdHkgcHJvY2Vzc29yIGl0ZXJhdG9yIGlmIG5vIHByb2Nlc3NvcnMgYXJlIG9uIHRoZQogICAgICogcmVsZXZhbnQgcGF0aCwgb3RoZXJ3aXNlIGlmIHByb2Nlc3NvcnMgYXJlIHByZXNlbnQsIGxvZ3MgYW4KICAgICAqIGVycm9yLiAgQ2FsbGVkIHdoZW4gYSBzZXJ2aWNlIGxvYWRlciBpcyB1bmF2YWlsYWJsZSBmb3Igc29tZQogICAgICogcmVhc29uLCBlaXRoZXIgYmVjYXVzZSBhIHNlcnZpY2UgbG9hZGVyIGNsYXNzIGNhbm5vdCBiZSBmb3VuZAogICAgICogb3IgYmVjYXVzZSBhIHNlY3VyaXR5IHBvbGljeSBwcmV2ZW50cyBjbGFzcyBsb2FkZXJzIGZyb20gYmVpbmcKICAgICAqIGNyZWF0ZWQuCiAgICAgKgogICAgICogQHBhcmFtIGtleSBUaGUgcmVzb3VyY2Uga2V5IHRvIHVzZSB0byBsb2cgYW4gZXJyb3IgbWVzc2FnZQogICAgICogQHBhcmFtIGUgICBJZiBub24tbnVsbCwgcGFzcyB0aGlzIGV4Y2VwdGlvbiB0byBBYm9ydAogICAgICovCiAgICBwcml2YXRlIEl0ZXJhdG9yPFByb2Nlc3Nvcj4gaGFuZGxlU2VydmljZUxvYWRlclVuYXZhaWxhYmlsaXR5KFN0cmluZyBrZXksIEV4Y2VwdGlvbiBlKSB7CiAgICAgICAgaWYgKGZpbGVNYW5hZ2VyIGluc3RhbmNlb2YgSmF2YWNGaWxlTWFuYWdlcikgewogICAgICAgICAgICBTdGFuZGFyZEphdmFGaWxlTWFuYWdlciBzdGFuZGFyZEZpbGVNYW5hZ2VyID0gKEphdmFjRmlsZU1hbmFnZXIpIGZpbGVNYW5hZ2VyOwogICAgICAgICAgICBJdGVyYWJsZTw/IGV4dGVuZHMgUGF0aD4gd29ya2luZ1BhdGggPSBmaWxlTWFuYWdlci5oYXNMb2NhdGlvbihBTk5PVEFUSU9OX1BST0NFU1NPUl9QQVRIKQogICAgICAgICAgICAgICAgPyBzdGFuZGFyZEZpbGVNYW5hZ2VyLmdldExvY2F0aW9uQXNQYXRocyhBTk5PVEFUSU9OX1BST0NFU1NPUl9QQVRIKQogICAgICAgICAgICAgICAgOiBzdGFuZGFyZEZpbGVNYW5hZ2VyLmdldExvY2F0aW9uQXNQYXRocyhDTEFTU19QQVRIKTsKCiAgICAgICAgICAgIGlmIChuZWVkQ2xhc3NMb2FkZXIob3B0aW9ucy5nZXQoT3B0aW9uLlBST0NFU1NPUiksIHdvcmtpbmdQYXRoKSApCiAgICAgICAgICAgICAgICBoYW5kbGVFeGNlcHRpb24oa2V5LCBlKTsKCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgaGFuZGxlRXhjZXB0aW9uKGtleSwgZSk7CiAgICAgICAgfQoKICAgICAgICBqYXZhLnV0aWwuTGlzdDxQcm9jZXNzb3I+IHBsID0gQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgcmV0dXJuIHBsLml0ZXJhdG9yKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBIYW5kbGUgYSBzZWN1cml0eSBleGNlcHRpb24gdGhyb3duIGR1cmluZyBpbml0aWFsaXppbmcgdGhlCiAgICAgKiBQcm9jZXNzb3IgaXRlcmF0b3IuCiAgICAgKi8KICAgIHByaXZhdGUgdm9pZCBoYW5kbGVFeGNlcHRpb24oU3RyaW5nIGtleSwgRXhjZXB0aW9uIGUpIHsKICAgICAgICBpZiAoZSAhPSBudWxsKSB7CiAgICAgICAgICAgIGxvZy5lcnJvcihrZXksIGUuZ2V0TG9jYWxpemVkTWVzc2FnZSgpKTsKICAgICAgICAgICAgdGhyb3cgbmV3IEFib3J0KGUpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGxvZy5lcnJvcihrZXkpOwogICAgICAgICAgICB0aHJvdyBuZXcgQWJvcnQoKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBVc2UgYSBzZXJ2aWNlIGxvYWRlciBhcHByb3ByaWF0ZSBmb3IgdGhlIHBsYXRmb3JtIHRvIHByb3ZpZGUgYW4KICAgICAqIGl0ZXJhdG9yIG92ZXIgYW5ub3RhdGlvbnMgcHJvY2Vzc29yczsgZmFpbHMgaWYgYSBsb2FkZXIgaXMKICAgICAqIG5lZWRlZCBidXQgdW5hdmFpbGFibGUuCiAgICAgKi8KICAgIHByaXZhdGUgY2xhc3MgU2VydmljZUl0ZXJhdG9yIGltcGxlbWVudHMgSXRlcmF0b3I8UHJvY2Vzc29yPiB7CiAgICAgICAgSXRlcmF0b3I8UHJvY2Vzc29yPiBpdGVyYXRvcjsKICAgICAgICBMb2cgbG9nOwogICAgICAgIFNlcnZpY2VMb2FkZXI8UHJvY2Vzc29yPiBsb2FkZXI7CgogICAgICAgIFNlcnZpY2VJdGVyYXRvcihDbGFzc0xvYWRlciBjbGFzc0xvYWRlciwgTG9nIGxvZykgewogICAgICAgICAgICB0aGlzLmxvZyA9IGxvZzsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgbG9hZGVyID0gU2VydmljZUxvYWRlci5sb2FkKFByb2Nlc3Nvci5jbGFzcywgY2xhc3NMb2FkZXIpOwogICAgICAgICAgICAgICAgICAgIHRoaXMuaXRlcmF0b3IgPSBsb2FkZXIuaXRlcmF0b3IoKTsKICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gRmFpbCBzb2Z0bHkgaWYgYSBsb2FkZXIgaXMgbm90IGFjdHVhbGx5IG5lZWRlZC4KICAgICAgICAgICAgICAgICAgICB0aGlzLml0ZXJhdG9yID0gaGFuZGxlU2VydmljZUxvYWRlclVuYXZhaWxhYmlsaXR5KCJwcm9jLm5vLnNlcnZpY2UiLCBudWxsKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBjYXRjaCAoVGhyb3dhYmxlIHQpIHsKICAgICAgICAgICAgICAgIGxvZy5lcnJvcigicHJvYy5zZXJ2aWNlLnByb2JsZW0iKTsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBBYm9ydCh0KTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgU2VydmljZUl0ZXJhdG9yKFNlcnZpY2VMb2FkZXI8UHJvY2Vzc29yPiBsb2FkZXIsIExvZyBsb2cpIHsKICAgICAgICAgICAgdGhpcy5sb2cgPSBsb2c7CiAgICAgICAgICAgIHRoaXMubG9hZGVyID0gbG9hZGVyOwogICAgICAgICAgICB0aGlzLml0ZXJhdG9yID0gbG9hZGVyLml0ZXJhdG9yKCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNOZXh0KCkgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgcmV0dXJuIGludGVybmFsSGFzTmV4dCgpOwogICAgICAgICAgICB9IGNhdGNoKFNlcnZpY2VDb25maWd1cmF0aW9uRXJyb3Igc2NlKSB7CiAgICAgICAgICAgICAgICBsb2cuZXJyb3IoInByb2MuYmFkLmNvbmZpZy5maWxlIiwgc2NlLmdldExvY2FsaXplZE1lc3NhZ2UoKSk7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQWJvcnQoc2NlKTsKICAgICAgICAgICAgfSBjYXRjaCAoVGhyb3dhYmxlIHQpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBBYm9ydCh0KTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgYm9vbGVhbiBpbnRlcm5hbEhhc05leHQoKSB7CiAgICAgICAgICAgIHJldHVybiBpdGVyYXRvci5oYXNOZXh0KCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgUHJvY2Vzc29yIG5leHQoKSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxOZXh0KCk7CiAgICAgICAgICAgIH0gY2F0Y2ggKFNlcnZpY2VDb25maWd1cmF0aW9uRXJyb3Igc2NlKSB7CiAgICAgICAgICAgICAgICBsb2cuZXJyb3IoInByb2MuYmFkLmNvbmZpZy5maWxlIiwgc2NlLmdldExvY2FsaXplZE1lc3NhZ2UoKSk7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQWJvcnQoc2NlKTsKICAgICAgICAgICAgfSBjYXRjaCAoVGhyb3dhYmxlIHQpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBBYm9ydCh0KTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgUHJvY2Vzc29yIGludGVybmFsTmV4dCgpIHsKICAgICAgICAgICAgcmV0dXJuIGl0ZXJhdG9yLm5leHQoKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHJlbW92ZSgpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHsKICAgICAgICAgICAgaWYgKGxvYWRlciAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIGxvYWRlci5yZWxvYWQoKTsKICAgICAgICAgICAgICAgIH0gY2F0Y2goRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgICAgICAgICAvLyBJZ25vcmUgcHJvYmxlbXMgZHVyaW5nIGEgY2FsbCB0byByZWxvYWQuCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgcHJpdmF0ZSBjbGFzcyBOYW1lU2VydmljZUl0ZXJhdG9yIGV4dGVuZHMgU2VydmljZUl0ZXJhdG9yIHsKICAgICAgICBwcml2YXRlIE1hcDxTdHJpbmcsIFByb2Nlc3Nvcj4gbmFtZWRQcm9jZXNzb3JzTWFwID0gbmV3IEhhc2hNYXA8PigpOzsKICAgICAgICBwcml2YXRlIEl0ZXJhdG9yPFN0cmluZz4gcHJvY2Vzc29yTmFtZXMgPSBudWxsOwogICAgICAgIHByaXZhdGUgUHJvY2Vzc29yIG5leHRQcm9jID0gbnVsbDsKCiAgICAgICAgcHVibGljIE5hbWVTZXJ2aWNlSXRlcmF0b3IoU2VydmljZUxvYWRlcjxQcm9jZXNzb3I+IGxvYWRlciwgTG9nIGxvZywgU3RyaW5nIHRoZU5hbWVzKSB7CiAgICAgICAgICAgIHN1cGVyKGxvYWRlciwgbG9nKTsKICAgICAgICAgICAgdGhpcy5wcm9jZXNzb3JOYW1lcyA9IEFycmF5cy5hc0xpc3QodGhlTmFtZXMuc3BsaXQoIiwiKSkuaXRlcmF0b3IoKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIGJvb2xlYW4gaW50ZXJuYWxIYXNOZXh0KCkgewogICAgICAgICAgICBpZiAobmV4dFByb2MgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCFwcm9jZXNzb3JOYW1lcy5oYXNOZXh0KCkpIHsKICAgICAgICAgICAgICAgIG5hbWVkUHJvY2Vzc29yc01hcCA9IG51bGw7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgU3RyaW5nIHByb2Nlc3Nvck5hbWUgPSBwcm9jZXNzb3JOYW1lcy5uZXh0KCk7CiAgICAgICAgICAgIFByb2Nlc3NvciB0aGVQcm9jZXNzb3IgPSBuYW1lZFByb2Nlc3NvcnNNYXAuZ2V0KHByb2Nlc3Nvck5hbWUpOwogICAgICAgICAgICBpZiAodGhlUHJvY2Vzc29yICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIG5hbWVkUHJvY2Vzc29yc01hcC5yZW1vdmUocHJvY2Vzc29yTmFtZSk7CiAgICAgICAgICAgICAgICBuZXh0UHJvYyA9IHRoZVByb2Nlc3NvcjsKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgd2hpbGUgKGl0ZXJhdG9yLmhhc05leHQoKSkgewogICAgICAgICAgICAgICAgICAgIHRoZVByb2Nlc3NvciA9IGl0ZXJhdG9yLm5leHQoKTsKICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbmFtZSA9IHRoZVByb2Nlc3Nvci5nZXRDbGFzcygpLmdldE5hbWUoKTsKICAgICAgICAgICAgICAgICAgICBpZiAobmFtZS5lcXVhbHMocHJvY2Vzc29yTmFtZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgbmV4dFByb2MgPSB0aGVQcm9jZXNzb3I7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVkUHJvY2Vzc29yc01hcC5wdXQobmFtZSwgdGhlUHJvY2Vzc29yKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBsb2cuZXJyb3IoRXJyb3JzLlByb2NQcm9jZXNzb3JOb3RGb3VuZChwcm9jZXNzb3JOYW1lKSk7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIFByb2Nlc3NvciBpbnRlcm5hbE5leHQoKSB7CiAgICAgICAgICAgIGlmIChoYXNOZXh0KCkpIHsKICAgICAgICAgICAgICAgIFByb2Nlc3NvciBwID0gbmV4dFByb2M7CiAgICAgICAgICAgICAgICBuZXh0UHJvYyA9IG51bGw7CiAgICAgICAgICAgICAgICByZXR1cm4gcDsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgTmFtZVByb2Nlc3NJdGVyYXRvciBpbXBsZW1lbnRzIEl0ZXJhdG9yPFByb2Nlc3Nvcj4gewogICAgICAgIFByb2Nlc3NvciBuZXh0UHJvYyA9IG51bGw7CiAgICAgICAgSXRlcmF0b3I8U3RyaW5nPiBuYW1lczsKICAgICAgICBDbGFzc0xvYWRlciBwcm9jZXNzb3JDTDsKICAgICAgICBMb2cgbG9nOwoKICAgICAgICBOYW1lUHJvY2Vzc0l0ZXJhdG9yKFN0cmluZyBuYW1lcywgQ2xhc3NMb2FkZXIgcHJvY2Vzc29yQ0wsIExvZyBsb2cpIHsKICAgICAgICAgICAgdGhpcy5uYW1lcyA9IEFycmF5cy5hc0xpc3QobmFtZXMuc3BsaXQoIiwiKSkuaXRlcmF0b3IoKTsKICAgICAgICAgICAgdGhpcy5wcm9jZXNzb3JDTCA9IHByb2Nlc3NvckNMOwogICAgICAgICAgICB0aGlzLmxvZyA9IGxvZzsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBib29sZWFuIGhhc05leHQoKSB7CiAgICAgICAgICAgIGlmIChuZXh0UHJvYyAhPSBudWxsKQogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgaWYgKCFuYW1lcy5oYXNOZXh0KCkpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIFByb2Nlc3NvciBwcm9jZXNzb3IgPSBnZXROZXh0UHJvY2Vzc29yKG5hbWVzLm5leHQoKSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKHByb2Nlc3NvciA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBuZXh0UHJvYyA9IHByb2Nlc3NvcjsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIFByb2Nlc3NvciBnZXROZXh0UHJvY2Vzc29yKFN0cmluZyBwcm9jZXNzb3JOYW1lKSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIENsYXNzPD8+IHByb2Nlc3NvckNsYXNzID0gcHJvY2Vzc29yQ0wubG9hZENsYXNzKHByb2Nlc3Nvck5hbWUpOwogICAgICAgICAgICAgICAgICAgIGVuc3VyZVJlYWRhYmxlKHByb2Nlc3NvckNsYXNzKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gKFByb2Nlc3NvcikgcHJvY2Vzc29yQ2xhc3MuZ2V0Q29uc3RydWN0b3IoKS5uZXdJbnN0YW5jZSgpOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiBjbmZlKSB7CiAgICAgICAgICAgICAgICAgICAgbG9nLmVycm9yKCJwcm9jLnByb2Nlc3Nvci5ub3QuZm91bmQiLCBwcm9jZXNzb3JOYW1lKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgIH0gY2F0Y2ggKENsYXNzQ2FzdEV4Y2VwdGlvbiBjY2UpIHsKICAgICAgICAgICAgICAgICAgICBsb2cuZXJyb3IoInByb2MucHJvY2Vzc29yLndyb25nLnR5cGUiLCBwcm9jZXNzb3JOYW1lKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlICkgewogICAgICAgICAgICAgICAgICAgIGxvZy5lcnJvcigicHJvYy5wcm9jZXNzb3IuY2FudC5pbnN0YW50aWF0ZSIsIHByb2Nlc3Nvck5hbWUpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGNhdGNoIChDbGllbnRDb2RlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgICAgIHRocm93IGU7CiAgICAgICAgICAgIH0gY2F0Y2ggKFRocm93YWJsZSB0KSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQW5ub3RhdGlvblByb2Nlc3NpbmdFcnJvcih0KTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHVibGljIFByb2Nlc3NvciBuZXh0KCkgewogICAgICAgICAgICBpZiAoaGFzTmV4dCgpKSB7CiAgICAgICAgICAgICAgICBQcm9jZXNzb3IgcCA9IG5leHRQcm9jOwogICAgICAgICAgICAgICAgbmV4dFByb2MgPSBudWxsOwogICAgICAgICAgICAgICAgcmV0dXJuIHA7CiAgICAgICAgICAgIH0gZWxzZQogICAgICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaEVsZW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyB2b2lkIHJlbW92ZSAoKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogRW5zdXJlcyB0aGF0IHRoZSBtb2R1bGUgb2YgdGhlIGdpdmVuIGNsYXNzIGlzIHJlYWRhYmxlIHRvIHRoaXMKICAgICAgICAgKiBtb2R1bGUuCiAgICAgICAgICovCiAgICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlYWRhYmxlKENsYXNzPD8+IHRhcmdldENsYXNzKSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBNZXRob2QgZ2V0TW9kdWxlTWV0aG9kID0gQ2xhc3MuY2xhc3MuZ2V0TWV0aG9kKCJnZXRNb2R1bGUiKTsKICAgICAgICAgICAgICAgIE9iamVjdCB0aGlzTW9kdWxlID0gZ2V0TW9kdWxlTWV0aG9kLmludm9rZSh0aGlzLmdldENsYXNzKCkpOwogICAgICAgICAgICAgICAgT2JqZWN0IHRhcmdldE1vZHVsZSA9IGdldE1vZHVsZU1ldGhvZC5pbnZva2UodGFyZ2V0Q2xhc3MpOwoKICAgICAgICAgICAgICAgIENsYXNzPD8+IG1vZHVsZUNsYXNzID0gZ2V0TW9kdWxlTWV0aG9kLmdldFJldHVyblR5cGUoKTsKICAgICAgICAgICAgICAgIE1ldGhvZCBhZGRSZWFkc01ldGhvZCA9IG1vZHVsZUNsYXNzLmdldE1ldGhvZCgiYWRkUmVhZHMiLCBtb2R1bGVDbGFzcyk7CiAgICAgICAgICAgICAgICBhZGRSZWFkc01ldGhvZC5pbnZva2UodGhpc01vZHVsZSwgdGFyZ2V0TW9kdWxlKTsKICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoTWV0aG9kRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgICAgIC8vIGlnbm9yZQogICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgcHVibGljIGJvb2xlYW4gYXRMZWFzdE9uZVByb2Nlc3NvcigpIHsKICAgICAgICByZXR1cm4gZGlzY292ZXJlZFByb2NzLml0ZXJhdG9yKCkuaGFzTmV4dCgpOwogICAgfQoKICAgIHByaXZhdGUgTWFwPFN0cmluZywgU3RyaW5nPiBpbml0UHJvY2Vzc29yT3B0aW9ucygpIHsKICAgICAgICBTZXQ8U3RyaW5nPiBrZXlTZXQgPSBvcHRpb25zLmtleVNldCgpOwogICAgICAgIE1hcDxTdHJpbmcsIFN0cmluZz4gdGVtcE9wdGlvbnMgPSBuZXcgTGlua2VkSGFzaE1hcDw+KCk7CgogICAgICAgIGZvcihTdHJpbmcga2V5IDoga2V5U2V0KSB7CiAgICAgICAgICAgIGlmIChrZXkuc3RhcnRzV2l0aCgiLUEiKSAmJiBrZXkubGVuZ3RoKCkgPiAyKSB7CiAgICAgICAgICAgICAgICBpbnQgc2VwSW5kZXggPSBrZXkuaW5kZXhPZignPScpOwogICAgICAgICAgICAgICAgU3RyaW5nIGNhbmRpZGF0ZUtleSA9IG51bGw7CiAgICAgICAgICAgICAgICBTdHJpbmcgY2FuZGlkYXRlVmFsdWUgPSBudWxsOwoKICAgICAgICAgICAgICAgIGlmIChzZXBJbmRleCA9PSAtMSkKICAgICAgICAgICAgICAgICAgICBjYW5kaWRhdGVLZXkgPSBrZXkuc3Vic3RyaW5nKDIpOwogICAgICAgICAgICAgICAgZWxzZSBpZiAoc2VwSW5kZXggPj0gMykgewogICAgICAgICAgICAgICAgICAgIGNhbmRpZGF0ZUtleSA9IGtleS5zdWJzdHJpbmcoMiwgc2VwSW5kZXgpOwogICAgICAgICAgICAgICAgICAgIGNhbmRpZGF0ZVZhbHVlID0gKHNlcEluZGV4IDwga2V5Lmxlbmd0aCgpLTEpPwogICAgICAgICAgICAgICAgICAgICAgICBrZXkuc3Vic3RyaW5nKHNlcEluZGV4KzEpIDogbnVsbDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHRlbXBPcHRpb25zLnB1dChjYW5kaWRhdGVLZXksIGNhbmRpZGF0ZVZhbHVlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgUGxhdGZvcm1EZXNjcmlwdGlvbiBwbGF0Zm9ybVByb3ZpZGVyID0gY29udGV4dC5nZXQoUGxhdGZvcm1EZXNjcmlwdGlvbi5jbGFzcyk7CgogICAgICAgIGlmIChwbGF0Zm9ybVByb3ZpZGVyICE9IG51bGwpIHsKICAgICAgICAgICAgZm9yIChQbHVnaW5JbmZvPFByb2Nlc3Nvcj4gYXAgOiBwbGF0Zm9ybVByb3ZpZGVyLmdldEFubm90YXRpb25Qcm9jZXNzb3JzKCkpIHsKICAgICAgICAgICAgICAgIHRlbXBPcHRpb25zLnB1dEFsbChhcC5nZXRPcHRpb25zKCkpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTWFwKHRlbXBPcHRpb25zKTsKICAgIH0KCiAgICBwcml2YXRlIFNldDxTdHJpbmc+IGluaXRVbm1hdGNoZWRQcm9jZXNzb3JPcHRpb25zKCkgewogICAgICAgIFNldDxTdHJpbmc+IHVubWF0Y2hlZFByb2Nlc3Nvck9wdGlvbnMgPSBuZXcgSGFzaFNldDw+KCk7CiAgICAgICAgdW5tYXRjaGVkUHJvY2Vzc29yT3B0aW9ucy5hZGRBbGwocHJvY2Vzc29yT3B0aW9ucy5rZXlTZXQoKSk7CiAgICAgICAgcmV0dXJuIHVubWF0Y2hlZFByb2Nlc3Nvck9wdGlvbnM7CiAgICB9CgogICAgLyoqCiAgICAgKiBTdGF0ZSBhYm91dCBob3cgYSBwcm9jZXNzb3IgaGFzIGJlZW4gdXNlZCBieSB0aGUgdG9vbC4gIElmIGEKICAgICAqIHByb2Nlc3NvciBoYXMgYmVlbiB1c2VkIG9uIGEgcHJpb3Igcm91bmQsIGl0cyBwcm9jZXNzIG1ldGhvZCBpcwogICAgICogY2FsbGVkIG9uIGFsbCBzdWJzZXF1ZW50IHJvdW5kcywgcGVyaGFwcyB3aXRoIGFuIGVtcHR5IHNldCBvZgogICAgICogYW5ub3RhdGlvbnMgdG8gcHJvY2Vzcy4gIFRoZSB7QGNvZGUgYW5ub3RhdGlvblN1cHBvcnRlZH0gbWV0aG9kCiAgICAgKiBjYWNoZXMgdGhlIHN1cHBvcnRlZCBhbm5vdGF0aW9uIGluZm9ybWF0aW9uIGZyb20gdGhlIGZpcnN0IChhbmQKICAgICAqIG9ubHkpIGdldFN1cHBvcnRlZEFubm90YXRpb25UeXBlcyBjYWxsIHRvIHRoZSBwcm9jZXNzb3IuCiAgICAgKi8KICAgIHN0YXRpYyBjbGFzcyBQcm9jZXNzb3JTdGF0ZSB7CiAgICAgICAgcHVibGljIFByb2Nlc3NvciBwcm9jZXNzb3I7CiAgICAgICAgcHVibGljIGJvb2xlYW4gICBjb250cmlidXRlZDsKICAgICAgICBwcml2YXRlIEFycmF5TGlzdDxQYXR0ZXJuPiBzdXBwb3J0ZWRBbm5vdGF0aW9uUGF0dGVybnM7CiAgICAgICAgcHJpdmF0ZSBBcnJheUxpc3Q8U3RyaW5nPiAgc3VwcG9ydGVkT3B0aW9uTmFtZXM7CgogICAgICAgIFByb2Nlc3NvclN0YXRlKFByb2Nlc3NvciBwLCBMb2cgbG9nLCBTb3VyY2Ugc291cmNlLCBib29sZWFuIGFsbG93TW9kdWxlcywgUHJvY2Vzc2luZ0Vudmlyb25tZW50IGVudikgewogICAgICAgICAgICBwcm9jZXNzb3IgPSBwOwogICAgICAgICAgICBjb250cmlidXRlZCA9IGZhbHNlOwoKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIHByb2Nlc3Nvci5pbml0KGVudik7CgogICAgICAgICAgICAgICAgY2hlY2tTb3VyY2VWZXJzaW9uQ29tcGF0aWJpbGl0eShzb3VyY2UsIGxvZyk7CgogICAgICAgICAgICAgICAgc3VwcG9ydGVkQW5ub3RhdGlvblBhdHRlcm5zID0gbmV3IEFycmF5TGlzdDw+KCk7CiAgICAgICAgICAgICAgICBmb3IgKFN0cmluZyBpbXBvcnRTdHJpbmcgOiBwcm9jZXNzb3IuZ2V0U3VwcG9ydGVkQW5ub3RhdGlvblR5cGVzKCkpIHsKICAgICAgICAgICAgICAgICAgICBzdXBwb3J0ZWRBbm5vdGF0aW9uUGF0dGVybnMuYWRkKGltcG9ydFN0cmluZ1RvUGF0dGVybihhbGxvd01vZHVsZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW1wb3J0U3RyaW5nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb2Nlc3NvciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2cpKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBzdXBwb3J0ZWRPcHRpb25OYW1lcyA9IG5ldyBBcnJheUxpc3Q8PigpOwogICAgICAgICAgICAgICAgZm9yIChTdHJpbmcgb3B0aW9uTmFtZSA6IHByb2Nlc3Nvci5nZXRTdXBwb3J0ZWRPcHRpb25zKCkgKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGNoZWNrT3B0aW9uTmFtZShvcHRpb25OYW1lLCBsb2cpKQogICAgICAgICAgICAgICAgICAgICAgICBzdXBwb3J0ZWRPcHRpb25OYW1lcy5hZGQob3B0aW9uTmFtZSk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICB9IGNhdGNoIChDbGllbnRDb2RlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgICAgIHRocm93IGU7CiAgICAgICAgICAgIH0gY2F0Y2ggKFRocm93YWJsZSB0KSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQW5ub3RhdGlvblByb2Nlc3NpbmdFcnJvcih0KTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogQ2hlY2tzIHdoZXRoZXIgb3Igbm90IGEgcHJvY2Vzc29yJ3Mgc291cmNlIHZlcnNpb24gaXMKICAgICAgICAgKiBjb21wYXRpYmxlIHdpdGggdGhlIGNvbXBpbGF0aW9uIHNvdXJjZSB2ZXJzaW9uLiAgVGhlCiAgICAgICAgICogcHJvY2Vzc29yJ3Mgc291cmNlIHZlcnNpb24gbmVlZHMgdG8gYmUgZ3JlYXRlciB0aGFuIG9yCiAgICAgICAgICogZXF1YWwgdG8gdGhlIHNvdXJjZSB2ZXJzaW9uIG9mIHRoZSBjb21waWxlLgogICAgICAgICAqLwogICAgICAgIHByaXZhdGUgdm9pZCBjaGVja1NvdXJjZVZlcnNpb25Db21wYXRpYmlsaXR5KFNvdXJjZSBzb3VyY2UsIExvZyBsb2cpIHsKICAgICAgICAgICAgU291cmNlVmVyc2lvbiBwcm9jU291cmNlVmVyc2lvbiA9IHByb2Nlc3Nvci5nZXRTdXBwb3J0ZWRTb3VyY2VWZXJzaW9uKCk7CgogICAgICAgICAgICBpZiAocHJvY1NvdXJjZVZlcnNpb24uY29tcGFyZVRvKFNvdXJjZS50b1NvdXJjZVZlcnNpb24oc291cmNlKSkgPCAwICkgIHsKICAgICAgICAgICAgICAgIGxvZy53YXJuaW5nKCJwcm9jLnByb2Nlc3Nvci5pbmNvbXBhdGlibGUuc291cmNlLnZlcnNpb24iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvY1NvdXJjZVZlcnNpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm9jZXNzb3IuZ2V0Q2xhc3MoKS5nZXROYW1lKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzb3VyY2UubmFtZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHByaXZhdGUgYm9vbGVhbiBjaGVja09wdGlvbk5hbWUoU3RyaW5nIG9wdGlvbk5hbWUsIExvZyBsb2cpIHsKICAgICAgICAgICAgYm9vbGVhbiB2YWxpZCA9IGlzVmFsaWRPcHRpb25OYW1lKG9wdGlvbk5hbWUpOwogICAgICAgICAgICBpZiAoIXZhbGlkKQogICAgICAgICAgICAgICAgbG9nLmVycm9yKCJwcm9jLnByb2Nlc3Nvci5iYWQub3B0aW9uLm5hbWUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9uTmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb2Nlc3Nvci5nZXRDbGFzcygpLmdldE5hbWUoKSk7CiAgICAgICAgICAgIHJldHVybiB2YWxpZDsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBib29sZWFuIGFubm90YXRpb25TdXBwb3J0ZWQoU3RyaW5nIGFubm90YXRpb25OYW1lKSB7CiAgICAgICAgICAgIGZvcihQYXR0ZXJuIHA6IHN1cHBvcnRlZEFubm90YXRpb25QYXR0ZXJucykgewogICAgICAgICAgICAgICAgaWYgKHAubWF0Y2hlcihhbm5vdGF0aW9uTmFtZSkubWF0Y2hlcygpKQogICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIFJlbW92ZSBvcHRpb25zIHRoYXQgYXJlIG1hdGNoZWQgYnkgdGhpcyBwcm9jZXNzb3IuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIHZvaWQgcmVtb3ZlU3VwcG9ydGVkT3B0aW9ucyhTZXQ8U3RyaW5nPiB1bm1hdGNoZWRQcm9jZXNzb3JPcHRpb25zKSB7CiAgICAgICAgICAgIHVubWF0Y2hlZFByb2Nlc3Nvck9wdGlvbnMucmVtb3ZlQWxsKHN1cHBvcnRlZE9wdGlvbk5hbWVzKTsKICAgICAgICB9CiAgICB9CgogICAgLy8gVE9ETzogVGhlc2UgdHdvIGNsYXNzZXMgY2FuIHByb2JhYmx5IGJlIHJld3JpdHRlbiBiZXR0ZXIuLi4KICAgIC8qKgogICAgICogVGhpcyBjbGFzcyBob2xkcyBpbmZvcm1hdGlvbiBhYm91dCB0aGUgcHJvY2Vzc29ycyB0aGF0IGhhdmUKICAgICAqIGJlZW4gZGlzY292ZXJlZCBzbyBmYXIgYXMgd2VsbCBhcyB0aGUgbWVhbnMgdG8gZGlzY292ZXIgbW9yZSwgaWYKICAgICAqIG5lY2Vzc2FyeS4gIEEgc2luZ2xlIGl0ZXJhdG9yIHNob3VsZCBiZSB1c2VkIHBlciByb3VuZCBvZgogICAgICogYW5ub3RhdGlvbiBwcm9jZXNzaW5nLiAgVGhlIGl0ZXJhdG9yIGZpcnN0IHZpc2l0cyBhbHJlYWR5CiAgICAgKiBkaXNjb3ZlcmVkIHByb2Nlc3NvcnMgdGhlbiBmYWlscyBvdmVyIHRvIHRoZSBzZXJ2aWNlIHByb3ZpZGVyCiAgICAgKiBtZWNoYW5pc20gaWYgYWRkaXRpb25hbCBxdWVyaWVzIGFyZSBtYWRlLgogICAgICovCiAgICBjbGFzcyBEaXNjb3ZlcmVkUHJvY2Vzc29ycyBpbXBsZW1lbnRzIEl0ZXJhYmxlPFByb2Nlc3NvclN0YXRlPiB7CgogICAgICAgIGNsYXNzIFByb2Nlc3NvclN0YXRlSXRlcmF0b3IgaW1wbGVtZW50cyBJdGVyYXRvcjxQcm9jZXNzb3JTdGF0ZT4gewogICAgICAgICAgICBEaXNjb3ZlcmVkUHJvY2Vzc29ycyBwc2k7CiAgICAgICAgICAgIEl0ZXJhdG9yPFByb2Nlc3NvclN0YXRlPiBpbm5lckl0ZXI7CiAgICAgICAgICAgIGJvb2xlYW4gb25Qcm9jSW50ZXJhdG9yOwoKICAgICAgICAgICAgUHJvY2Vzc29yU3RhdGVJdGVyYXRvcihEaXNjb3ZlcmVkUHJvY2Vzc29ycyBwc2kpIHsKICAgICAgICAgICAgICAgIHRoaXMucHNpID0gcHNpOwogICAgICAgICAgICAgICAgdGhpcy5pbm5lckl0ZXIgPSBwc2kucHJvY1N0YXRlTGlzdC5pdGVyYXRvcigpOwogICAgICAgICAgICAgICAgdGhpcy5vblByb2NJbnRlcmF0b3IgPSBmYWxzZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHVibGljIFByb2Nlc3NvclN0YXRlIG5leHQoKSB7CiAgICAgICAgICAgICAgICBpZiAoIW9uUHJvY0ludGVyYXRvcikgewogICAgICAgICAgICAgICAgICAgIGlmIChpbm5lckl0ZXIuaGFzTmV4dCgpKQogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaW5uZXJJdGVyLm5leHQoKTsKICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIG9uUHJvY0ludGVyYXRvciA9IHRydWU7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKHBzaS5wcm9jZXNzb3JJdGVyYXRvci5oYXNOZXh0KCkpIHsKICAgICAgICAgICAgICAgICAgICBQcm9jZXNzb3JTdGF0ZSBwcyA9IG5ldyBQcm9jZXNzb3JTdGF0ZShwc2kucHJvY2Vzc29ySXRlcmF0b3IubmV4dCgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZywgc291cmNlLCBhbGxvd01vZHVsZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSmF2YWNQcm9jZXNzaW5nRW52aXJvbm1lbnQudGhpcyk7CiAgICAgICAgICAgICAgICAgICAgcHNpLnByb2NTdGF0ZUxpc3QuYWRkKHBzKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gcHM7CiAgICAgICAgICAgICAgICB9IGVsc2UKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbigpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNOZXh0KCkgewogICAgICAgICAgICAgICAgaWYgKG9uUHJvY0ludGVyYXRvcikKICAgICAgICAgICAgICAgICAgICByZXR1cm4gIHBzaS5wcm9jZXNzb3JJdGVyYXRvci5oYXNOZXh0KCk7CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGlubmVySXRlci5oYXNOZXh0KCkgfHwgcHNpLnByb2Nlc3Nvckl0ZXJhdG9yLmhhc05leHQoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHVibGljIHZvaWQgcmVtb3ZlICgpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogUnVuIGFsbCByZW1haW5pbmcgcHJvY2Vzc29ycyBvbiB0aGUgcHJvY1N0YXRlTGlzdCB0aGF0CiAgICAgICAgICAgICAqIGhhdmUgbm90IGFscmVhZHkgcnVuIHRoaXMgcm91bmQgd2l0aCBhbiBlbXB0eSBzZXQgb2YKICAgICAgICAgICAgICogYW5ub3RhdGlvbnMuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBwdWJsaWMgdm9pZCBydW5Db250cmlidXRpbmdQcm9jcyhSb3VuZEVudmlyb25tZW50IHJlKSB7CiAgICAgICAgICAgICAgICBpZiAoIW9uUHJvY0ludGVyYXRvcikgewogICAgICAgICAgICAgICAgICAgIFNldDxUeXBlRWxlbWVudD4gZW1wdHlUeXBlRWxlbWVudHMgPSBDb2xsZWN0aW9ucy5lbXB0eVNldCgpOwogICAgICAgICAgICAgICAgICAgIHdoaWxlKGlubmVySXRlci5oYXNOZXh0KCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgUHJvY2Vzc29yU3RhdGUgcHMgPSBpbm5lckl0ZXIubmV4dCgpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAocHMuY29udHJpYnV0ZWQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWxsUHJvY2Vzc29yKHBzLnByb2Nlc3NvciwgZW1wdHlUeXBlRWxlbWVudHMsIHJlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEl0ZXJhdG9yPD8gZXh0ZW5kcyBQcm9jZXNzb3I+IHByb2Nlc3Nvckl0ZXJhdG9yOwogICAgICAgIEFycmF5TGlzdDxQcm9jZXNzb3JTdGF0ZT4gIHByb2NTdGF0ZUxpc3Q7CgogICAgICAgIHB1YmxpYyBQcm9jZXNzb3JTdGF0ZUl0ZXJhdG9yIGl0ZXJhdG9yKCkgewogICAgICAgICAgICByZXR1cm4gbmV3IFByb2Nlc3NvclN0YXRlSXRlcmF0b3IodGhpcyk7CiAgICAgICAgfQoKICAgICAgICBEaXNjb3ZlcmVkUHJvY2Vzc29ycyhJdGVyYXRvcjw/IGV4dGVuZHMgUHJvY2Vzc29yPiBwcm9jZXNzb3JJdGVyYXRvcikgewogICAgICAgICAgICB0aGlzLnByb2Nlc3Nvckl0ZXJhdG9yID0gcHJvY2Vzc29ySXRlcmF0b3I7CiAgICAgICAgICAgIHRoaXMucHJvY1N0YXRlTGlzdCA9IG5ldyBBcnJheUxpc3Q8PigpOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogRnJlZSBqYXIgZmlsZXMsIGV0Yy4gaWYgdXNpbmcgYSBzZXJ2aWNlIGxvYWRlci4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHsKICAgICAgICAgICAgaWYgKHByb2Nlc3Nvckl0ZXJhdG9yICE9IG51bGwgJiYKICAgICAgICAgICAgICAgIHByb2Nlc3Nvckl0ZXJhdG9yIGluc3RhbmNlb2YgU2VydmljZUl0ZXJhdG9yKSB7CiAgICAgICAgICAgICAgICAoKFNlcnZpY2VJdGVyYXRvcikgcHJvY2Vzc29ySXRlcmF0b3IpLmNsb3NlKCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgcHJpdmF0ZSB2b2lkIGRpc2NvdmVyQW5kUnVuUHJvY3MoU2V0PFR5cGVFbGVtZW50PiBhbm5vdGF0aW9uc1ByZXNlbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0PENsYXNzU3ltYm9sPiB0b3BMZXZlbENsYXNzZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0PFBhY2thZ2VTeW1ib2w+IHBhY2thZ2VJbmZvRmlsZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0PE1vZHVsZVN5bWJvbD4gbW9kdWxlSW5mb0ZpbGVzKSB7CiAgICAgICAgTWFwPFN0cmluZywgVHlwZUVsZW1lbnQ+IHVubWF0Y2hlZEFubm90YXRpb25zID0gbmV3IEhhc2hNYXA8Pihhbm5vdGF0aW9uc1ByZXNlbnQuc2l6ZSgpKTsKCiAgICAgICAgZm9yKFR5cGVFbGVtZW50IGEgIDogYW5ub3RhdGlvbnNQcmVzZW50KSB7CiAgICAgICAgICAgIE1vZHVsZUVsZW1lbnQgbW9kID0gZWxlbWVudFV0aWxzLmdldE1vZHVsZU9mKGEpOwogICAgICAgICAgICBTdHJpbmcgbW9kdWxlU3BlYyA9IGFsbG93TW9kdWxlcyAmJiBtb2QgIT0gbnVsbCA/IG1vZC5nZXRTaW1wbGVOYW1lKCkgKyAiLyIgOiAiIjsKICAgICAgICAgICAgdW5tYXRjaGVkQW5ub3RhdGlvbnMucHV0KG1vZHVsZVNwZWMgKyBhLmdldFF1YWxpZmllZE5hbWUoKS50b1N0cmluZygpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYSk7CiAgICAgICAgfQoKICAgICAgICAvLyBHaXZlICIqIiBwcm9jZXNzb3JzIGEgY2hhbmNlIHRvIG1hdGNoCiAgICAgICAgaWYgKHVubWF0Y2hlZEFubm90YXRpb25zLnNpemUoKSA9PSAwKQogICAgICAgICAgICB1bm1hdGNoZWRBbm5vdGF0aW9ucy5wdXQoIiIsIG51bGwpOwoKICAgICAgICBEaXNjb3ZlcmVkUHJvY2Vzc29ycy5Qcm9jZXNzb3JTdGF0ZUl0ZXJhdG9yIHBzaSA9IGRpc2NvdmVyZWRQcm9jcy5pdGVyYXRvcigpOwogICAgICAgIC8vIFRPRE86IENyZWF0ZSBwcm9wZXIgYXJndW1lbnQgdmFsdWVzOyBuZWVkIHBhc3Qgcm91bmQKICAgICAgICAvLyBpbmZvcm1hdGlvbiB0byBmaWxsIGluIHRoaXMgY29uc3RydWN0b3IuICBOb3RlIHRoYXQgdGhlIDEKICAgICAgICAvLyBzdCByb3VuZCBvZiBwcm9jZXNzaW5nIGNvdWxkIGJlIHRoZSBsYXN0IHJvdW5kIGlmIHRoZXJlCiAgICAgICAgLy8gd2VyZSBwYXJzZSBlcnJvcnMgb24gdGhlIGluaXRpYWwgc291cmNlIGZpbGVzOyBob3dldmVyLCB3ZQogICAgICAgIC8vIGFyZSBub3QgZG9pbmcgcHJvY2Vzc2luZyBpbiB0aGF0IGNhc2UuCgogICAgICAgIFNldDxFbGVtZW50PiByb290RWxlbWVudHMgPSBuZXcgTGlua2VkSGFzaFNldDw+KCk7CiAgICAgICAgcm9vdEVsZW1lbnRzLmFkZEFsbCh0b3BMZXZlbENsYXNzZXMpOwogICAgICAgIHJvb3RFbGVtZW50cy5hZGRBbGwocGFja2FnZUluZm9GaWxlcyk7CiAgICAgICAgcm9vdEVsZW1lbnRzLmFkZEFsbChtb2R1bGVJbmZvRmlsZXMpOwogICAgICAgIHJvb3RFbGVtZW50cyA9IENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZVNldChyb290RWxlbWVudHMpOwoKICAgICAgICBSb3VuZEVudmlyb25tZW50IHJlbnYgPSBuZXcgSmF2YWNSb3VuZEVudmlyb25tZW50KGZhbHNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFsc2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByb290RWxlbWVudHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBKYXZhY1Byb2Nlc3NpbmdFbnZpcm9ubWVudC50aGlzKTsKCiAgICAgICAgd2hpbGUodW5tYXRjaGVkQW5ub3RhdGlvbnMuc2l6ZSgpID4gMCAmJiBwc2kuaGFzTmV4dCgpICkgewogICAgICAgICAgICBQcm9jZXNzb3JTdGF0ZSBwcyA9IHBzaS5uZXh0KCk7CiAgICAgICAgICAgIFNldDxTdHJpbmc+ICBtYXRjaGVkTmFtZXMgPSBuZXcgSGFzaFNldDw+KCk7CiAgICAgICAgICAgIFNldDxUeXBlRWxlbWVudD4gdHlwZUVsZW1lbnRzID0gbmV3IExpbmtlZEhhc2hTZXQ8PigpOwoKICAgICAgICAgICAgZm9yIChNYXAuRW50cnk8U3RyaW5nLCBUeXBlRWxlbWVudD4gZW50cnk6IHVubWF0Y2hlZEFubm90YXRpb25zLmVudHJ5U2V0KCkpIHsKICAgICAgICAgICAgICAgIFN0cmluZyB1bm1hdGNoZWRBbm5vdGF0aW9uTmFtZSA9IGVudHJ5LmdldEtleSgpOwogICAgICAgICAgICAgICAgaWYgKHBzLmFubm90YXRpb25TdXBwb3J0ZWQodW5tYXRjaGVkQW5ub3RhdGlvbk5hbWUpICkgewogICAgICAgICAgICAgICAgICAgIG1hdGNoZWROYW1lcy5hZGQodW5tYXRjaGVkQW5ub3RhdGlvbk5hbWUpOwogICAgICAgICAgICAgICAgICAgIFR5cGVFbGVtZW50IHRlID0gZW50cnkuZ2V0VmFsdWUoKTsKICAgICAgICAgICAgICAgICAgICBpZiAodGUgIT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICAgICAgdHlwZUVsZW1lbnRzLmFkZCh0ZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChtYXRjaGVkTmFtZXMuc2l6ZSgpID4gMCB8fCBwcy5jb250cmlidXRlZCkgewogICAgICAgICAgICAgICAgYm9vbGVhbiBwcm9jZXNzaW5nUmVzdWx0ID0gY2FsbFByb2Nlc3Nvcihwcy5wcm9jZXNzb3IsIHR5cGVFbGVtZW50cywgcmVudik7CiAgICAgICAgICAgICAgICBwcy5jb250cmlidXRlZCA9IHRydWU7CiAgICAgICAgICAgICAgICBwcy5yZW1vdmVTdXBwb3J0ZWRPcHRpb25zKHVubWF0Y2hlZFByb2Nlc3Nvck9wdGlvbnMpOwoKICAgICAgICAgICAgICAgIGlmIChwcmludFByb2Nlc3NvckluZm8gfHwgdmVyYm9zZSkgewogICAgICAgICAgICAgICAgICAgIGxvZy5wcmludExpbmVzKCJ4LnByaW50LnByb2Nlc3Nvci5pbmZvIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBzLnByb2Nlc3Nvci5nZXRDbGFzcygpLmdldE5hbWUoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdGNoZWROYW1lcy50b1N0cmluZygpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvY2Vzc2luZ1Jlc3VsdCk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKHByb2Nlc3NpbmdSZXN1bHQpIHsKICAgICAgICAgICAgICAgICAgICB1bm1hdGNoZWRBbm5vdGF0aW9ucy5rZXlTZXQoKS5yZW1vdmVBbGwobWF0Y2hlZE5hbWVzKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgdW5tYXRjaGVkQW5ub3RhdGlvbnMucmVtb3ZlKCIiKTsKCiAgICAgICAgaWYgKGxpbnQgJiYgdW5tYXRjaGVkQW5ub3RhdGlvbnMuc2l6ZSgpID4gMCkgewogICAgICAgICAgICAvLyBSZW1vdmUgYW5ub3RhdGlvbnMgcHJvY2Vzc2VkIGJ5IGphdmFjCiAgICAgICAgICAgIHVubWF0Y2hlZEFubm90YXRpb25zLmtleVNldCgpLnJlbW92ZUFsbChwbGF0Zm9ybUFubm90YXRpb25zKTsKICAgICAgICAgICAgaWYgKHVubWF0Y2hlZEFubm90YXRpb25zLnNpemUoKSA+IDApIHsKICAgICAgICAgICAgICAgIGxvZy53YXJuaW5nKCJwcm9jLmFubm90YXRpb25zLndpdGhvdXQucHJvY2Vzc29ycyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bm1hdGNoZWRBbm5vdGF0aW9ucy5rZXlTZXQoKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIFJ1biBjb250cmlidXRpbmcgcHJvY2Vzc29ycyB0aGF0IGhhdmVuJ3QgcnVuIHlldAogICAgICAgIHBzaS5ydW5Db250cmlidXRpbmdQcm9jcyhyZW52KTsKICAgIH0KCiAgICAvKioKICAgICAqIENvbXB1dGVzIHRoZSBzZXQgb2YgYW5ub3RhdGlvbnMgb24gdGhlIHN5bWJvbCBpbiBxdWVzdGlvbi4KICAgICAqIExlYXZlIGNsYXNzIHB1YmxpYyBmb3IgZXh0ZXJuYWwgdGVzdGluZyBwdXJwb3Nlcy4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBjbGFzcyBDb21wdXRlQW5ub3RhdGlvblNldCBleHRlbmRzCiAgICAgICAgRWxlbWVudFNjYW5uZXI5PFNldDxUeXBlRWxlbWVudD4sIFNldDxUeXBlRWxlbWVudD4+IHsKICAgICAgICBmaW5hbCBFbGVtZW50cyBlbGVtZW50czsKCiAgICAgICAgcHVibGljIENvbXB1dGVBbm5vdGF0aW9uU2V0KEVsZW1lbnRzIGVsZW1lbnRzKSB7CiAgICAgICAgICAgIHN1cGVyKCk7CiAgICAgICAgICAgIHRoaXMuZWxlbWVudHMgPSBlbGVtZW50czsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgICAgICBwdWJsaWMgU2V0PFR5cGVFbGVtZW50PiB2aXNpdFBhY2thZ2UoUGFja2FnZUVsZW1lbnQgZSwgU2V0PFR5cGVFbGVtZW50PiBwKSB7CiAgICAgICAgICAgIC8vIERvbid0IHNjYW4gZW5jbG9zZWQgZWxlbWVudHMgb2YgYSBwYWNrYWdlCiAgICAgICAgICAgIHJldHVybiBwOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyBTZXQ8VHlwZUVsZW1lbnQ+IHZpc2l0VHlwZShUeXBlRWxlbWVudCBlLCBTZXQ8VHlwZUVsZW1lbnQ+IHApIHsKICAgICAgICAgICAgLy8gVHlwZSBwYXJhbWV0ZXJzIGFyZSBub3QgY29uc2lkZXJlZCB0byBiZSBlbmNsb3NlZCBieSBhIHR5cGUKICAgICAgICAgICAgc2NhbihlLmdldFR5cGVQYXJhbWV0ZXJzKCksIHApOwogICAgICAgICAgICByZXR1cm4gc3VwZXIudmlzaXRUeXBlKGUsIHApOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyBTZXQ8VHlwZUVsZW1lbnQ+IHZpc2l0RXhlY3V0YWJsZShFeGVjdXRhYmxlRWxlbWVudCBlLCBTZXQ8VHlwZUVsZW1lbnQ+IHApIHsKICAgICAgICAgICAgLy8gVHlwZSBwYXJhbWV0ZXJzIGFyZSBub3QgY29uc2lkZXJlZCB0byBiZSBlbmNsb3NlZCBieSBhbiBleGVjdXRhYmxlCiAgICAgICAgICAgIHNjYW4oZS5nZXRUeXBlUGFyYW1ldGVycygpLCBwKTsKICAgICAgICAgICAgcmV0dXJuIHN1cGVyLnZpc2l0RXhlY3V0YWJsZShlLCBwKTsKICAgICAgICB9CgogICAgICAgIHZvaWQgYWRkQW5ub3RhdGlvbnMoRWxlbWVudCBlLCBTZXQ8VHlwZUVsZW1lbnQ+IHApIHsKICAgICAgICAgICAgZm9yIChBbm5vdGF0aW9uTWlycm9yIGFubm90YXRpb25NaXJyb3IgOgogICAgICAgICAgICAgICAgICAgICBlbGVtZW50cy5nZXRBbGxBbm5vdGF0aW9uTWlycm9ycyhlKSApIHsKICAgICAgICAgICAgICAgIEVsZW1lbnQgZTIgPSBhbm5vdGF0aW9uTWlycm9yLmdldEFubm90YXRpb25UeXBlKCkuYXNFbGVtZW50KCk7CiAgICAgICAgICAgICAgICBwLmFkZCgoVHlwZUVsZW1lbnQpIGUyKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyBTZXQ8VHlwZUVsZW1lbnQ+IHNjYW4oRWxlbWVudCBlLCBTZXQ8VHlwZUVsZW1lbnQ+IHApIHsKICAgICAgICAgICAgYWRkQW5ub3RhdGlvbnMoZSwgcCk7CiAgICAgICAgICAgIHJldHVybiBzdXBlci5zY2FuKGUsIHApOwogICAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIGJvb2xlYW4gY2FsbFByb2Nlc3NvcihQcm9jZXNzb3IgcHJvYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTZXQ8PyBleHRlbmRzIFR5cGVFbGVtZW50PiB0ZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUm91bmRFbnZpcm9ubWVudCByZW52KSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgcmV0dXJuIHByb2MucHJvY2Vzcyh0ZXMsIHJlbnYpOwogICAgICAgIH0gY2F0Y2ggKENsYXNzRmluZGVyLkJhZENsYXNzRmlsZSBleCkgewogICAgICAgICAgICBsb2cuZXJyb3IoInByb2MuY2FudC5hY2Nlc3MuMSIsIGV4LnN5bSwgZXguZ2V0RGV0YWlsVmFsdWUoKSk7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9IGNhdGNoIChDb21wbGV0aW9uRmFpbHVyZSBleCkgewogICAgICAgICAgICBTdHJpbmdXcml0ZXIgb3V0ID0gbmV3IFN0cmluZ1dyaXRlcigpOwogICAgICAgICAgICBleC5wcmludFN0YWNrVHJhY2UobmV3IFByaW50V3JpdGVyKG91dCkpOwogICAgICAgICAgICBsb2cuZXJyb3IoInByb2MuY2FudC5hY2Nlc3MiLCBleC5zeW0sIGV4LmdldERldGFpbFZhbHVlKCksIG91dC50b1N0cmluZygpKTsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0gY2F0Y2ggKENsaWVudENvZGVFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBlOwogICAgICAgIH0gY2F0Y2ggKFRocm93YWJsZSB0KSB7CiAgICAgICAgICAgIHRocm93IG5ldyBBbm5vdGF0aW9uUHJvY2Vzc2luZ0Vycm9yKHQpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEhlbHBlciBvYmplY3QgZm9yIGEgc2luZ2xlIHJvdW5kIG9mIGFubm90YXRpb24gcHJvY2Vzc2luZy4KICAgICAqLwogICAgY2xhc3MgUm91bmQgewogICAgICAgIC8qKiBUaGUgcm91bmQgbnVtYmVyLiAqLwogICAgICAgIGZpbmFsIGludCBudW1iZXI7CiAgICAgICAgLyoqIFRoZSBkaWFnbm9zdGljIGhhbmRsZXIgZm9yIHRoZSByb3VuZC4gKi8KICAgICAgICBmaW5hbCBMb2cuRGVmZXJyZWREaWFnbm9zdGljSGFuZGxlciBkZWZlcnJlZERpYWdub3N0aWNIYW5kbGVyOwoKICAgICAgICAvKiogVGhlIEFTVHMgdG8gYmUgY29tcGlsZWQuICovCiAgICAgICAgTGlzdDxKQ0NvbXBpbGF0aW9uVW5pdD4gcm9vdHM7CiAgICAgICAgLyoqIFRoZSB0cmVlcyB0aGF0IG5lZWQgdG8gYmUgY2xlYW5lZCAtIGluY2x1ZGVzIHJvb3RzIGFuZCBpbXBsaWNpdGx5IHBhcnNlZCB0cmVlcy4gKi8KICAgICAgICBTZXQ8SkNDb21waWxhdGlvblVuaXQ+IHRyZWVzVG9DbGVhbjsKICAgICAgICAvKiogVGhlIGNsYXNzZXMgdG8gYmUgY29tcGlsZXIgdGhhdCBoYXZlIHdlcmUgZ2VuZXJhdGVkLiAqLwogICAgICAgIE1hcDxNb2R1bGVTeW1ib2wsIE1hcDxTdHJpbmcsIEphdmFGaWxlT2JqZWN0Pj4gZ2VuQ2xhc3NGaWxlczsKCiAgICAgICAgLyoqIFRoZSBzZXQgb2YgYW5ub3RhdGlvbnMgdG8gYmUgcHJvY2Vzc2VkIHRoaXMgcm91bmQuICovCiAgICAgICAgU2V0PFR5cGVFbGVtZW50PiBhbm5vdGF0aW9uc1ByZXNlbnQ7CiAgICAgICAgLyoqIFRoZSBzZXQgb2YgdG9wIGxldmVsIGNsYXNzZXMgdG8gYmUgcHJvY2Vzc2VkIHRoaXMgcm91bmQuICovCiAgICAgICAgTGlzdDxDbGFzc1N5bWJvbD4gdG9wTGV2ZWxDbGFzc2VzOwogICAgICAgIC8qKiBUaGUgc2V0IG9mIHBhY2thZ2UtaW5mbyBmaWxlcyB0byBiZSBwcm9jZXNzZWQgdGhpcyByb3VuZC4gKi8KICAgICAgICBMaXN0PFBhY2thZ2VTeW1ib2w+IHBhY2thZ2VJbmZvRmlsZXM7CiAgICAgICAgLyoqIFRoZSBzZXQgb2YgbW9kdWxlLWluZm8gZmlsZXMgdG8gYmUgcHJvY2Vzc2VkIHRoaXMgcm91bmQuICovCiAgICAgICAgTGlzdDxNb2R1bGVTeW1ib2w+IG1vZHVsZUluZm9GaWxlczsKCiAgICAgICAgLyoqIENyZWF0ZSBhIHJvdW5kIChjb21tb24gY29kZSkuICovCiAgICAgICAgcHJpdmF0ZSBSb3VuZChpbnQgbnVtYmVyLCBTZXQ8SkNDb21waWxhdGlvblVuaXQ+IHRyZWVzVG9DbGVhbiwKICAgICAgICAgICAgICAgIExvZy5EZWZlcnJlZERpYWdub3N0aWNIYW5kbGVyIGRlZmVycmVkRGlhZ25vc3RpY0hhbmRsZXIpIHsKICAgICAgICAgICAgdGhpcy5udW1iZXIgPSBudW1iZXI7CgogICAgICAgICAgICBpZiAobnVtYmVyID09IDEpIHsKICAgICAgICAgICAgICAgIEFzc2VydC5jaGVja05vbk51bGwoZGVmZXJyZWREaWFnbm9zdGljSGFuZGxlcik7CiAgICAgICAgICAgICAgICB0aGlzLmRlZmVycmVkRGlhZ25vc3RpY0hhbmRsZXIgPSBkZWZlcnJlZERpYWdub3N0aWNIYW5kbGVyOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdGhpcy5kZWZlcnJlZERpYWdub3N0aWNIYW5kbGVyID0gbmV3IExvZy5EZWZlcnJlZERpYWdub3N0aWNIYW5kbGVyKGxvZyk7CiAgICAgICAgICAgICAgICBjb21waWxlci5zZXREZWZlcnJlZERpYWdub3N0aWNIYW5kbGVyKHRoaXMuZGVmZXJyZWREaWFnbm9zdGljSGFuZGxlcik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIHRoZSBmb2xsb3dpbmcgd2lsbCBiZSBwb3B1bGF0ZWQgYXMgbmVlZGVkCiAgICAgICAgICAgIHRvcExldmVsQ2xhc3NlcyAgPSBMaXN0Lm5pbCgpOwogICAgICAgICAgICBwYWNrYWdlSW5mb0ZpbGVzID0gTGlzdC5uaWwoKTsKICAgICAgICAgICAgbW9kdWxlSW5mb0ZpbGVzID0gTGlzdC5uaWwoKTsKICAgICAgICAgICAgdGhpcy50cmVlc1RvQ2xlYW4gPSB0cmVlc1RvQ2xlYW47CiAgICAgICAgfQoKICAgICAgICAvKiogQ3JlYXRlIHRoZSBmaXJzdCByb3VuZC4gKi8KICAgICAgICBSb3VuZChMaXN0PEpDQ29tcGlsYXRpb25Vbml0PiByb290cywKICAgICAgICAgICAgICBMaXN0PENsYXNzU3ltYm9sPiBjbGFzc1N5bWJvbHMsCiAgICAgICAgICAgICAgU2V0PEpDQ29tcGlsYXRpb25Vbml0PiB0cmVlc1RvQ2xlYW4sCiAgICAgICAgICAgICAgTG9nLkRlZmVycmVkRGlhZ25vc3RpY0hhbmRsZXIgZGVmZXJyZWREaWFnbm9zdGljSGFuZGxlcikgewogICAgICAgICAgICB0aGlzKDEsIHRyZWVzVG9DbGVhbiwgZGVmZXJyZWREaWFnbm9zdGljSGFuZGxlcik7CiAgICAgICAgICAgIHRoaXMucm9vdHMgPSByb290czsKICAgICAgICAgICAgZ2VuQ2xhc3NGaWxlcyA9IG5ldyBIYXNoTWFwPD4oKTsKCiAgICAgICAgICAgIC8vIFRoZSByZXZlcnNlKCkgaW4gdGhlIGZvbGxvd2luZyBsaW5lIGlzIHRvIG1haW50YWluIGJlaGF2aW91cmFsCiAgICAgICAgICAgIC8vIGNvbXBhdGliaWxpdHkgd2l0aCB0aGUgcHJldmlvdXMgcmV2aXNpb24gb2YgdGhlIGNvZGUuIFN0cmljdGx5IHNwZWFraW5nLAogICAgICAgICAgICAvLyBpdCBzaG91bGQgbm90IGJlIG5lY2Vzc2FyeSwgYnV0IGEgamF2YWggZ29sZGVuIGZpbGUgdGVzdCBmYWlscyB3aXRob3V0IGl0LgogICAgICAgICAgICB0b3BMZXZlbENsYXNzZXMgPQogICAgICAgICAgICAgICAgZ2V0VG9wTGV2ZWxDbGFzc2VzKHJvb3RzKS5wcmVwZW5kTGlzdChjbGFzc1N5bWJvbHMucmV2ZXJzZSgpKTsKCiAgICAgICAgICAgIHBhY2thZ2VJbmZvRmlsZXMgPSBnZXRQYWNrYWdlSW5mb0ZpbGVzKHJvb3RzKTsKCiAgICAgICAgICAgIG1vZHVsZUluZm9GaWxlcyA9IGdldE1vZHVsZUluZm9GaWxlcyhyb290cyk7CgogICAgICAgICAgICBmaW5kQW5ub3RhdGlvbnNQcmVzZW50KCk7CiAgICAgICAgfQoKICAgICAgICAvKiogQ3JlYXRlIGEgbmV3IHJvdW5kLiAqLwogICAgICAgIHByaXZhdGUgUm91bmQoUm91bmQgcHJldiwKICAgICAgICAgICAgICAgIFNldDxKYXZhRmlsZU9iamVjdD4gbmV3U291cmNlRmlsZXMsIE1hcDxNb2R1bGVTeW1ib2wsIE1hcDxTdHJpbmcsSmF2YUZpbGVPYmplY3Q+PiBuZXdDbGFzc0ZpbGVzKSB7CiAgICAgICAgICAgIHRoaXMocHJldi5udW1iZXIrMSwgcHJldi50cmVlc1RvQ2xlYW4sIG51bGwpOwogICAgICAgICAgICBwcmV2Lm5ld1JvdW5kKCk7CiAgICAgICAgICAgIHRoaXMuZ2VuQ2xhc3NGaWxlcyA9IHByZXYuZ2VuQ2xhc3NGaWxlczsKCiAgICAgICAgICAgIExpc3Q8SkNDb21waWxhdGlvblVuaXQ+IHBhcnNlZEZpbGVzID0gY29tcGlsZXIucGFyc2VGaWxlcyhuZXdTb3VyY2VGaWxlcyk7CiAgICAgICAgICAgIHJvb3RzID0gcHJldi5yb290cy5hcHBlbmRMaXN0KHBhcnNlZEZpbGVzKTsKCiAgICAgICAgICAgIC8vIENoZWNrIGZvciBlcnJvcnMgYWZ0ZXIgcGFyc2luZwogICAgICAgICAgICBpZiAodW5yZWNvdmVyYWJsZUVycm9yKCkpCiAgICAgICAgICAgICAgICByZXR1cm47CgogICAgICAgICAgICByb290cyA9IGNvbXBpbGVyLmluaXRNb2R1bGVzKHJvb3RzKTsKCiAgICAgICAgICAgIGVudGVyQ2xhc3NGaWxlcyhnZW5DbGFzc0ZpbGVzKTsKICAgICAgICAgICAgTGlzdDxDbGFzc1N5bWJvbD4gbmV3Q2xhc3NlcyA9IGVudGVyQ2xhc3NGaWxlcyhuZXdDbGFzc0ZpbGVzKTsKICAgICAgICAgICAgZm9yIChFbnRyeTxNb2R1bGVTeW1ib2wsIE1hcDxTdHJpbmcsIEphdmFGaWxlT2JqZWN0Pj4gbW9kdWxlQW5kQ2xhc3NGaWxlcyA6IG5ld0NsYXNzRmlsZXMuZW50cnlTZXQoKSkgewogICAgICAgICAgICAgICAgZ2VuQ2xhc3NGaWxlcy5jb21wdXRlSWZBYnNlbnQobW9kdWxlQW5kQ2xhc3NGaWxlcy5nZXRLZXkoKSwgbSAtPiBuZXcgTGlua2VkSGFzaE1hcDw+KCkpLnB1dEFsbChtb2R1bGVBbmRDbGFzc0ZpbGVzLmdldFZhbHVlKCkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVudGVyVHJlZXMocm9vdHMpOwoKICAgICAgICAgICAgaWYgKHVucmVjb3ZlcmFibGVFcnJvcigpKQogICAgICAgICAgICAgICAgcmV0dXJuOwoKICAgICAgICAgICAgdG9wTGV2ZWxDbGFzc2VzID0gam9pbigKICAgICAgICAgICAgICAgICAgICBnZXRUb3BMZXZlbENsYXNzZXMocGFyc2VkRmlsZXMpLAogICAgICAgICAgICAgICAgICAgIGdldFRvcExldmVsQ2xhc3Nlc0Zyb21DbGFzc2VzKG5ld0NsYXNzZXMpKTsKCiAgICAgICAgICAgIHBhY2thZ2VJbmZvRmlsZXMgPSBqb2luKAogICAgICAgICAgICAgICAgICAgIGdldFBhY2thZ2VJbmZvRmlsZXMocGFyc2VkRmlsZXMpLAogICAgICAgICAgICAgICAgICAgIGdldFBhY2thZ2VJbmZvRmlsZXNGcm9tQ2xhc3NlcyhuZXdDbGFzc2VzKSk7CgogICAgICAgICAgICBtb2R1bGVJbmZvRmlsZXMgPSBMaXN0Lm5pbCgpOyAvL21vZHVsZS1pbmZvIGNhbm5vdCBiZSBnZW5lcmF0ZWQKCiAgICAgICAgICAgIGZpbmRBbm5vdGF0aW9uc1ByZXNlbnQoKTsKICAgICAgICB9CgogICAgICAgIC8qKiBDcmVhdGUgdGhlIG5leHQgcm91bmQgdG8gYmUgdXNlZC4gKi8KICAgICAgICBSb3VuZCBuZXh0KFNldDxKYXZhRmlsZU9iamVjdD4gbmV3U291cmNlRmlsZXMsIE1hcDxNb2R1bGVTeW1ib2wsIE1hcDxTdHJpbmcsIEphdmFGaWxlT2JqZWN0Pj4gbmV3Q2xhc3NGaWxlcykgewogICAgICAgICAgICByZXR1cm4gbmV3IFJvdW5kKHRoaXMsIG5ld1NvdXJjZUZpbGVzLCBuZXdDbGFzc0ZpbGVzKTsKICAgICAgICB9CgogICAgICAgIC8qKiBQcmVwYXJlIHRoZSBjb21waWxlciBmb3IgdGhlIGZpbmFsIGNvbXBpbGF0aW9uLiAqLwogICAgICAgIHZvaWQgZmluYWxDb21waWxlcigpIHsKICAgICAgICAgICAgbmV3Um91bmQoKTsKICAgICAgICB9CgogICAgICAgIC8qKiBSZXR1cm4gdGhlIG51bWJlciBvZiBlcnJvcnMgZm91bmQgc28gZmFyIGluIHRoaXMgcm91bmQuCiAgICAgICAgICogVGhpcyBtYXkgaW5jbHVkZSB1bmNvdmVyYWJsZSBlcnJvcnMsIHN1Y2ggYXMgcGFyc2UgZXJyb3JzLAogICAgICAgICAqIGFuZCB0cmFuc2llbnQgZXJyb3JzLCBzdWNoIGFzIG1pc3Npbmcgc3ltYm9scy4gKi8KICAgICAgICBpbnQgZXJyb3JDb3VudCgpIHsKICAgICAgICAgICAgcmV0dXJuIGNvbXBpbGVyLmVycm9yQ291bnQoKTsKICAgICAgICB9CgogICAgICAgIC8qKiBSZXR1cm4gdGhlIG51bWJlciBvZiB3YXJuaW5ncyBmb3VuZCBzbyBmYXIgaW4gdGhpcyByb3VuZC4gKi8KICAgICAgICBpbnQgd2FybmluZ0NvdW50KCkgewogICAgICAgICAgICByZXR1cm4gY29tcGlsZXIud2FybmluZ0NvdW50KCk7CiAgICAgICAgfQoKICAgICAgICAvKiogUmV0dXJuIHdoZXRoZXIgb3Igbm90IGFuIHVucmVjb3ZlcmFibGUgZXJyb3IgaGFzIG9jY3VycmVkLiAqLwogICAgICAgIGJvb2xlYW4gdW5yZWNvdmVyYWJsZUVycm9yKCkgewogICAgICAgICAgICBpZiAobWVzc2FnZXIuZXJyb3JSYWlzZWQoKSkKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwoKICAgICAgICAgICAgZm9yIChKQ0RpYWdub3N0aWMgZDogZGVmZXJyZWREaWFnbm9zdGljSGFuZGxlci5nZXREaWFnbm9zdGljcygpKSB7CiAgICAgICAgICAgICAgICBzd2l0Y2ggKGQuZ2V0S2luZCgpKSB7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBXQVJOSU5HOgogICAgICAgICAgICAgICAgICAgICAgICBpZiAod2Vycm9yKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgICAgICBjYXNlIEVSUk9SOgogICAgICAgICAgICAgICAgICAgICAgICBpZiAoZmF0YWxFcnJvcnMgfHwgIWQuaXNGbGFnU2V0KFJFQ09WRVJBQkxFKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgLyoqIEZpbmQgdGhlIHNldCBvZiBhbm5vdGF0aW9ucyBwcmVzZW50IGluIHRoZSBzZXQgb2YgdG9wIGxldmVsCiAgICAgICAgICogIGNsYXNzZXMgYW5kIHBhY2thZ2UgaW5mbyBmaWxlcyB0byBiZSBwcm9jZXNzZWQgdGhpcyByb3VuZC4gKi8KICAgICAgICB2b2lkIGZpbmRBbm5vdGF0aW9uc1ByZXNlbnQoKSB7CiAgICAgICAgICAgIENvbXB1dGVBbm5vdGF0aW9uU2V0IGFubm90YXRpb25Db21wdXRlciA9IG5ldyBDb21wdXRlQW5ub3RhdGlvblNldChlbGVtZW50VXRpbHMpOwogICAgICAgICAgICAvLyBVc2UgYW5ub3RhdGlvbiBwcm9jZXNzaW5nIHRvIGNvbXB1dGUgdGhlIHNldCBvZiBhbm5vdGF0aW9ucyBwcmVzZW50CiAgICAgICAgICAgIGFubm90YXRpb25zUHJlc2VudCA9IG5ldyBMaW5rZWRIYXNoU2V0PD4oKTsKICAgICAgICAgICAgZm9yIChDbGFzc1N5bWJvbCBjbGFzc1N5bSA6IHRvcExldmVsQ2xhc3NlcykKICAgICAgICAgICAgICAgIGFubm90YXRpb25Db21wdXRlci5zY2FuKGNsYXNzU3ltLCBhbm5vdGF0aW9uc1ByZXNlbnQpOwogICAgICAgICAgICBmb3IgKFBhY2thZ2VTeW1ib2wgcGtnU3ltIDogcGFja2FnZUluZm9GaWxlcykKICAgICAgICAgICAgICAgIGFubm90YXRpb25Db21wdXRlci5zY2FuKHBrZ1N5bSwgYW5ub3RhdGlvbnNQcmVzZW50KTsKICAgICAgICAgICAgZm9yIChNb2R1bGVTeW1ib2wgbWRsU3ltIDogbW9kdWxlSW5mb0ZpbGVzKQogICAgICAgICAgICAgICAgYW5ub3RhdGlvbkNvbXB1dGVyLnNjYW4obWRsU3ltLCBhbm5vdGF0aW9uc1ByZXNlbnQpOwogICAgICAgIH0KCiAgICAgICAgLyoqIEVudGVyIGEgc2V0IG9mIGdlbmVyYXRlZCBjbGFzcyBmaWxlcy4gKi8KICAgICAgICBwcml2YXRlIExpc3Q8Q2xhc3NTeW1ib2w+IGVudGVyQ2xhc3NGaWxlcyhNYXA8TW9kdWxlU3ltYm9sLCBNYXA8U3RyaW5nLCBKYXZhRmlsZU9iamVjdD4+IG1vZHVsZXNBbmRDbGFzc0ZpbGVzKSB7CiAgICAgICAgICAgIExpc3Q8Q2xhc3NTeW1ib2w+IGxpc3QgPSBMaXN0Lm5pbCgpOwoKICAgICAgICAgICAgZm9yIChFbnRyeTxNb2R1bGVTeW1ib2wsIE1hcDxTdHJpbmcsIEphdmFGaWxlT2JqZWN0Pj4gbW9kdWxlQW5kQ2xhc3NGaWxlcyA6IG1vZHVsZXNBbmRDbGFzc0ZpbGVzLmVudHJ5U2V0KCkpIHsKICAgICAgICAgICAgICAgIGZvciAoTWFwLkVudHJ5PFN0cmluZyxKYXZhRmlsZU9iamVjdD4gZW50cnkgOiBtb2R1bGVBbmRDbGFzc0ZpbGVzLmdldFZhbHVlKCkuZW50cnlTZXQoKSkgewogICAgICAgICAgICAgICAgICAgIE5hbWUgbmFtZSA9IG5hbWVzLmZyb21TdHJpbmcoZW50cnkuZ2V0S2V5KCkpOwogICAgICAgICAgICAgICAgICAgIEphdmFGaWxlT2JqZWN0IGZpbGUgPSBlbnRyeS5nZXRWYWx1ZSgpOwogICAgICAgICAgICAgICAgICAgIGlmIChmaWxlLmdldEtpbmQoKSAhPSBKYXZhRmlsZU9iamVjdC5LaW5kLkNMQVNTKQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoZmlsZSk7CiAgICAgICAgICAgICAgICAgICAgQ2xhc3NTeW1ib2wgY3M7CiAgICAgICAgICAgICAgICAgICAgaWYgKGlzUGtnSW5mbyhmaWxlLCBKYXZhRmlsZU9iamVjdC5LaW5kLkNMQVNTKSkgewogICAgICAgICAgICAgICAgICAgICAgICBOYW1lIHBhY2thZ2VOYW1lID0gQ29udmVydC5wYWNrYWdlUGFydChuYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgUGFja2FnZVN5bWJvbCBwID0gc3ltdGFiLmVudGVyUGFja2FnZShtb2R1bGVBbmRDbGFzc0ZpbGVzLmdldEtleSgpLCBwYWNrYWdlTmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwLnBhY2thZ2VfaW5mbyA9PSBudWxsKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgcC5wYWNrYWdlX2luZm8gPSBzeW10YWIuZW50ZXJDbGFzcyhtb2R1bGVBbmRDbGFzc0ZpbGVzLmdldEtleSgpLCBDb252ZXJ0LnNob3J0TmFtZShuYW1lKSwgcCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGNzID0gcC5wYWNrYWdlX2luZm87CiAgICAgICAgICAgICAgICAgICAgICAgIGNzLnJlc2V0KCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjcy5jbGFzc2ZpbGUgPT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNzLmNsYXNzZmlsZSA9IGZpbGU7CiAgICAgICAgICAgICAgICAgICAgICAgIGNzLmNvbXBsZXRlciA9IGluaXRpYWxDb21wbGV0ZXI7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgY3MgPSBzeW10YWIuZW50ZXJDbGFzcyhtb2R1bGVBbmRDbGFzc0ZpbGVzLmdldEtleSgpLCBuYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgY3MucmVzZXQoKTsKICAgICAgICAgICAgICAgICAgICAgICAgY3MuY2xhc3NmaWxlID0gZmlsZTsKICAgICAgICAgICAgICAgICAgICAgICAgY3MuY29tcGxldGVyID0gaW5pdGlhbENvbXBsZXRlcjsKICAgICAgICAgICAgICAgICAgICAgICAgY3Mub3duZXIubWVtYmVycygpLmVudGVyKGNzKTsgLy9YWFggLSBPdmVyd3JpdGVCZXR3ZWVuQ29tcGlsYXRpb25zOyBzeW1zLmdldENsYXNzIGlzIG5vdCBzdWZmaWNpZW50IGFueW1vcmUKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgbGlzdCA9IGxpc3QucHJlcGVuZChjcyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGxpc3QucmV2ZXJzZSgpOwogICAgICAgIH0KCiAgICAgICAgLyoqIEVudGVyIGEgc2V0IG9mIHN5bnRheCB0cmVlcy4gKi8KICAgICAgICBwcml2YXRlIHZvaWQgZW50ZXJUcmVlcyhMaXN0PEpDQ29tcGlsYXRpb25Vbml0PiByb290cykgewogICAgICAgICAgICBjb21waWxlci5lbnRlclRyZWVzKHJvb3RzKTsKICAgICAgICB9CgogICAgICAgIC8qKiBSdW4gYSBwcm9jZXNzaW5nIHJvdW5kLiAqLwogICAgICAgIHZvaWQgcnVuKGJvb2xlYW4gbGFzdFJvdW5kLCBib29sZWFuIGVycm9yU3RhdHVzKSB7CiAgICAgICAgICAgIHByaW50Um91bmRJbmZvKGxhc3RSb3VuZCk7CgogICAgICAgICAgICBpZiAoIXRhc2tMaXN0ZW5lci5pc0VtcHR5KCkpCiAgICAgICAgICAgICAgICB0YXNrTGlzdGVuZXIuc3RhcnRlZChuZXcgVGFza0V2ZW50KFRhc2tFdmVudC5LaW5kLkFOTk9UQVRJT05fUFJPQ0VTU0lOR19ST1VORCkpOwoKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIGlmIChsYXN0Um91bmQpIHsKICAgICAgICAgICAgICAgICAgICBmaWxlci5zZXRMYXN0Um91bmQodHJ1ZSk7CiAgICAgICAgICAgICAgICAgICAgU2V0PEVsZW1lbnQ+IGVtcHR5Um9vdEVsZW1lbnRzID0gQ29sbGVjdGlvbnMuZW1wdHlTZXQoKTsgLy8gaW1tdXRhYmxlCiAgICAgICAgICAgICAgICAgICAgUm91bmRFbnZpcm9ubWVudCByZW52ID0gbmV3IEphdmFjUm91bmRFbnZpcm9ubWVudCh0cnVlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JTdGF0dXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbXB0eVJvb3RFbGVtZW50cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEphdmFjUHJvY2Vzc2luZ0Vudmlyb25tZW50LnRoaXMpOwogICAgICAgICAgICAgICAgICAgIGRpc2NvdmVyZWRQcm9jcy5pdGVyYXRvcigpLnJ1bkNvbnRyaWJ1dGluZ1Byb2NzKHJlbnYpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBkaXNjb3ZlckFuZFJ1blByb2NzKGFubm90YXRpb25zUHJlc2VudCwgdG9wTGV2ZWxDbGFzc2VzLCBwYWNrYWdlSW5mb0ZpbGVzLCBtb2R1bGVJbmZvRmlsZXMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGNhdGNoIChUaHJvd2FibGUgdCkgewogICAgICAgICAgICAgICAgLy8gd2UncmUgc3BlY2lmaWNhbGx5IGV4cGVjdGluZyBBYm9ydCBoZXJlLCBidXQgaWYgYW55IFRocm93YWJsZQogICAgICAgICAgICAgICAgLy8gY29tZXMgYnksIHdlIHNob3VsZCBmbHVzaCBhbGwgZGVmZXJyZWQgZGlhZ25vc3RpY3MsIHJhdGhlciB0aGFuCiAgICAgICAgICAgICAgICAvLyBkcm9wIHRoZW0gb24gdGhlIGdyb3VuZC4KICAgICAgICAgICAgICAgIGRlZmVycmVkRGlhZ25vc3RpY0hhbmRsZXIucmVwb3J0RGVmZXJyZWREaWFnbm9zdGljcygpOwogICAgICAgICAgICAgICAgbG9nLnBvcERpYWdub3N0aWNIYW5kbGVyKGRlZmVycmVkRGlhZ25vc3RpY0hhbmRsZXIpOwogICAgICAgICAgICAgICAgY29tcGlsZXIuc2V0RGVmZXJyZWREaWFnbm9zdGljSGFuZGxlcihudWxsKTsKICAgICAgICAgICAgICAgIHRocm93IHQ7CiAgICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgICAgICBpZiAoIXRhc2tMaXN0ZW5lci5pc0VtcHR5KCkpCiAgICAgICAgICAgICAgICAgICAgdGFza0xpc3RlbmVyLmZpbmlzaGVkKG5ldyBUYXNrRXZlbnQoVGFza0V2ZW50LktpbmQuQU5OT1RBVElPTl9QUk9DRVNTSU5HX1JPVU5EKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHZvaWQgc2hvd0RpYWdub3N0aWNzKGJvb2xlYW4gc2hvd0FsbCkgewogICAgICAgICAgICBTZXQ8SkNEaWFnbm9zdGljLktpbmQ+IGtpbmRzID0gRW51bVNldC5hbGxPZihKQ0RpYWdub3N0aWMuS2luZC5jbGFzcyk7CiAgICAgICAgICAgIGlmICghc2hvd0FsbCkgewogICAgICAgICAgICAgICAgLy8gc3VwcHJlc3MgZXJyb3JzLCB3aGljaCBhcmUgYWxsIHByZXN1bWVkIHRvIGJlIHRyYW5zaWVudCByZXNvbHZlIGVycm9ycwogICAgICAgICAgICAgICAga2luZHMucmVtb3ZlKEpDRGlhZ25vc3RpYy5LaW5kLkVSUk9SKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBkZWZlcnJlZERpYWdub3N0aWNIYW5kbGVyLnJlcG9ydERlZmVycmVkRGlhZ25vc3RpY3Moa2luZHMpOwogICAgICAgICAgICBsb2cucG9wRGlhZ25vc3RpY0hhbmRsZXIoZGVmZXJyZWREaWFnbm9zdGljSGFuZGxlcik7CiAgICAgICAgICAgIGNvbXBpbGVyLnNldERlZmVycmVkRGlhZ25vc3RpY0hhbmRsZXIobnVsbCk7CiAgICAgICAgfQoKICAgICAgICAvKiogUHJpbnQgaW5mbyBhYm91dCB0aGlzIHJvdW5kLiAqLwogICAgICAgIHByaXZhdGUgdm9pZCBwcmludFJvdW5kSW5mbyhib29sZWFuIGxhc3RSb3VuZCkgewogICAgICAgICAgICBpZiAocHJpbnRSb3VuZHMgfHwgdmVyYm9zZSkgewogICAgICAgICAgICAgICAgTGlzdDxDbGFzc1N5bWJvbD4gdGxjID0gbGFzdFJvdW5kID8gTGlzdC5uaWwoKSA6IHRvcExldmVsQ2xhc3NlczsKICAgICAgICAgICAgICAgIFNldDxUeXBlRWxlbWVudD4gYXAgPSBsYXN0Um91bmQgPyBDb2xsZWN0aW9ucy5lbXB0eVNldCgpIDogYW5ub3RhdGlvbnNQcmVzZW50OwogICAgICAgICAgICAgICAgbG9nLnByaW50TGluZXMoIngucHJpbnQucm91bmRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgbnVtYmVyLAogICAgICAgICAgICAgICAgICAgICAgICAieyIgKyB0bGMudG9TdHJpbmcoIiwgIikgKyAifSIsCiAgICAgICAgICAgICAgICAgICAgICAgIGFwLAogICAgICAgICAgICAgICAgICAgICAgICBsYXN0Um91bmQpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvKiogUHJlcGFyZSBmb3IgbmV3IHJvdW5kIG9mIGFubm90YXRpb24gcHJvY2Vzc2luZy4gQ2xlYW5zIHRyZWVzLCByZXNldHMgc3ltYm9scywgYW5kCiAgICAgICAgICogYXNrcyBzZWxlY3RlZCBzZXJ2aWNlcyB0byBwcmVwYXJlIHRvIGEgbmV3IHJvdW5kIG9mIGFubm90YXRpb24gcHJvY2Vzc2luZy4KICAgICAgICAgKi8KICAgICAgICBwcml2YXRlIHZvaWQgbmV3Um91bmQoKSB7CiAgICAgICAgICAgIC8vZW5zdXJlIHRyZWVzVG9DbGVhbiBjb250YWlucyBhbGwgdHJlZXMsIGluY2x1ZGluZyBpbXBsaWNpdGx5IHBhcnNlZCBvbmVzCiAgICAgICAgICAgIGZvciAoRW52PEF0dHJDb250ZXh0PiBlbnYgOiBlbnRlci5nZXRFbnZzKCkpIHsKICAgICAgICAgICAgICAgIHRyZWVzVG9DbGVhbi5hZGQoZW52LnRvcGxldmVsKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBmb3IgKEpDQ29tcGlsYXRpb25Vbml0IG5vZGUgOiB0cmVlc1RvQ2xlYW4pIHsKICAgICAgICAgICAgICAgIHRyZWVDbGVhbmVyLnNjYW4obm9kZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY2hrLm5ld1JvdW5kKCk7CiAgICAgICAgICAgIGVudGVyLm5ld1JvdW5kKCk7CiAgICAgICAgICAgIGZpbGVyLm5ld1JvdW5kKCk7CiAgICAgICAgICAgIG1lc3NhZ2VyLm5ld1JvdW5kKCk7CiAgICAgICAgICAgIGNvbXBpbGVyLm5ld1JvdW5kKCk7CiAgICAgICAgICAgIG1vZHVsZXMubmV3Um91bmQoKTsKICAgICAgICAgICAgdHlwZXMubmV3Um91bmQoKTsKICAgICAgICAgICAgYW5ub3RhdGUubmV3Um91bmQoKTsKCiAgICAgICAgICAgIGJvb2xlYW4gZm91bmRFcnJvciA9IGZhbHNlOwoKICAgICAgICAgICAgZm9yIChDbGFzc1N5bWJvbCBjcyA6IHN5bXRhYi5nZXRBbGxDbGFzc2VzKCkpIHsKICAgICAgICAgICAgICAgIGlmIChjcy5raW5kID09IEVSUikgewogICAgICAgICAgICAgICAgICAgIGZvdW5kRXJyb3IgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoZm91bmRFcnJvcikgewogICAgICAgICAgICAgICAgZm9yIChDbGFzc1N5bWJvbCBjcyA6IHN5bXRhYi5nZXRBbGxDbGFzc2VzKCkpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoY3MuY2xhc3NmaWxlICE9IG51bGwgfHwgY3Mua2luZCA9PSBFUlIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY3MucmVzZXQoKTsKICAgICAgICAgICAgICAgICAgICAgICAgY3MudHlwZSA9IG5ldyBDbGFzc1R5cGUoY3MudHlwZS5nZXRFbmNsb3NpbmdUeXBlKCksIG51bGwsIGNzKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNzLmlzQ29tcGxldGVkKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNzLmNvbXBsZXRlciA9IGluaXRpYWxDb21wbGV0ZXI7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgoKICAgIC8vIFRPRE86IGludGVybmFsIGNhdGNoIGNsYXVzZXM/OyBjYXRjaCBhbmQgcmV0aHJvdyBhbiBhbm5vdGF0aW9uCiAgICAvLyBwcm9jZXNzaW5nIGVycm9yCiAgICBwdWJsaWMgYm9vbGVhbiBkb1Byb2Nlc3NpbmcoTGlzdDxKQ0NvbXBpbGF0aW9uVW5pdD4gcm9vdHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTGlzdDxDbGFzc1N5bWJvbD4gY2xhc3NTeW1ib2xzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEl0ZXJhYmxlPD8gZXh0ZW5kcyBQYWNrYWdlU3ltYm9sPiBwY2tTeW1ib2xzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExvZy5EZWZlcnJlZERpYWdub3N0aWNIYW5kbGVyIGRlZmVycmVkRGlhZ25vc3RpY0hhbmRsZXIpIHsKICAgICAgICBmaW5hbCBTZXQ8SkNDb21waWxhdGlvblVuaXQ+IHRyZWVzVG9DbGVhbiA9CiAgICAgICAgICAgICAgICBDb2xsZWN0aW9ucy5uZXdTZXRGcm9tTWFwKG5ldyBJZGVudGl0eUhhc2hNYXA8SkNDb21waWxhdGlvblVuaXQsIEJvb2xlYW4+KCkpOwoKICAgICAgICAvL2ZpbGwgYWxyZWFkeSBhdHRyaWJ1dGVkIGltcGxpY2l0IHRyZWVzOgogICAgICAgIGZvciAoRW52PEF0dHJDb250ZXh0PiBlbnYgOiBlbnRlci5nZXRFbnZzKCkpIHsKICAgICAgICAgICAgdHJlZXNUb0NsZWFuLmFkZChlbnYudG9wbGV2ZWwpOwogICAgICAgIH0KCiAgICAgICAgU2V0PFBhY2thZ2VTeW1ib2w+IHNwZWNpZmllZFBhY2thZ2VzID0gbmV3IExpbmtlZEhhc2hTZXQ8PigpOwogICAgICAgIGZvciAoUGFja2FnZVN5bWJvbCBwc3ltIDogcGNrU3ltYm9scykKICAgICAgICAgICAgc3BlY2lmaWVkUGFja2FnZXMuYWRkKHBzeW0pOwogICAgICAgIHRoaXMuc3BlY2lmaWVkUGFja2FnZXMgPSBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVTZXQoc3BlY2lmaWVkUGFja2FnZXMpOwoKICAgICAgICBSb3VuZCByb3VuZCA9IG5ldyBSb3VuZChyb290cywgY2xhc3NTeW1ib2xzLCB0cmVlc1RvQ2xlYW4sIGRlZmVycmVkRGlhZ25vc3RpY0hhbmRsZXIpOwoKICAgICAgICBib29sZWFuIGVycm9yU3RhdHVzOwogICAgICAgIGJvb2xlYW4gbW9yZVRvRG87CiAgICAgICAgZG8gewogICAgICAgICAgICAvLyBSdW4gcHJvY2Vzc29ycyBmb3Igcm91bmQgbgogICAgICAgICAgICByb3VuZC5ydW4oZmFsc2UsIGZhbHNlKTsKCiAgICAgICAgICAgIC8vIFByb2Nlc3NvcnMgZm9yIHJvdW5kIG4gaGF2ZSBydW4gdG8gY29tcGxldGlvbi4KICAgICAgICAgICAgLy8gQ2hlY2sgZm9yIGVycm9ycyBhbmQgd2hldGhlciB0aGVyZSBpcyBtb3JlIHdvcmsgdG8gZG8uCiAgICAgICAgICAgIGVycm9yU3RhdHVzID0gcm91bmQudW5yZWNvdmVyYWJsZUVycm9yKCk7CiAgICAgICAgICAgIG1vcmVUb0RvID0gbW9yZVRvRG8oKTsKCiAgICAgICAgICAgIHJvdW5kLnNob3dEaWFnbm9zdGljcyhlcnJvclN0YXR1cyB8fCBzaG93UmVzb2x2ZUVycm9ycyk7CgogICAgICAgICAgICAvLyBTZXQgdXAgbmV4dCByb3VuZC4KICAgICAgICAgICAgLy8gQ29weSBtdXRhYmxlIGNvbGxlY3Rpb25zIHJldHVybmVkIGZyb20gZmlsZXIuCiAgICAgICAgICAgIHJvdW5kID0gcm91bmQubmV4dCgKICAgICAgICAgICAgICAgICAgICBuZXcgTGlua2VkSGFzaFNldDw+KGZpbGVyLmdldEdlbmVyYXRlZFNvdXJjZUZpbGVPYmplY3RzKCkpLAogICAgICAgICAgICAgICAgICAgIG5ldyBMaW5rZWRIYXNoTWFwPD4oZmlsZXIuZ2V0R2VuZXJhdGVkQ2xhc3NlcygpKSk7CgogICAgICAgICAgICAgLy8gQ2hlY2sgZm9yIGVycm9ycyBkdXJpbmcgc2V0dXAuCiAgICAgICAgICAgIGlmIChyb3VuZC51bnJlY292ZXJhYmxlRXJyb3IoKSkKICAgICAgICAgICAgICAgIGVycm9yU3RhdHVzID0gdHJ1ZTsKCiAgICAgICAgfSB3aGlsZSAobW9yZVRvRG8gJiYgIWVycm9yU3RhdHVzKTsKCiAgICAgICAgLy8gcnVuIGxhc3Qgcm91bmQKICAgICAgICByb3VuZC5ydW4odHJ1ZSwgZXJyb3JTdGF0dXMpOwogICAgICAgIHJvdW5kLnNob3dEaWFnbm9zdGljcyh0cnVlKTsKCiAgICAgICAgZmlsZXIud2FybklmVW5jbG9zZWRGaWxlcygpOwogICAgICAgIHdhcm5JZlVubWF0Y2hlZE9wdGlvbnMoKTsKCiAgICAgICAgLyoKICAgICAgICAgKiBJZiBhbiBhbm5vdGF0aW9uIHByb2Nlc3NvciByYWlzZXMgYW4gZXJyb3IgaW4gYSByb3VuZCwKICAgICAgICAgKiB0aGF0IHJvdW5kIHJ1bnMgdG8gY29tcGxldGlvbiBhbmQgb25lIGxhc3Qgcm91bmQgb2NjdXJzLgogICAgICAgICAqIFRoZSBsYXN0IHJvdW5kIG1heSBhbHNvIG9jY3VyIGJlY2F1c2Ugbm8gbW9yZSBzb3VyY2Ugb3IKICAgICAgICAgKiBjbGFzcyBmaWxlcyBoYXZlIGJlZW4gZ2VuZXJhdGVkLiAgVGhlcmVmb3JlLCBpZiBhbiBlcnJvcgogICAgICAgICAqIHdhcyByYWlzZWQgb24gZWl0aGVyIG9mIHRoZSBsYXN0ICp0d28qIHJvdW5kcywgdGhlIGNvbXBpbGUKICAgICAgICAgKiBzaG91bGQgZXhpdCB3aXRoIGEgbm9uemVybyBleGl0IGNvZGUuICBUaGUgY3VycmVudCB2YWx1ZSBvZgogICAgICAgICAqIGVycm9yU3RhdHVzIGhvbGRzIHdoZXRoZXIgb3Igbm90IGFuIGVycm9yIHdhcyByYWlzZWQgb24gdGhlCiAgICAgICAgICogc2Vjb25kIHRvIGxhc3Qgcm91bmQ7IGVycm9yUmFpc2VkKCkgZ2l2ZXMgdGhlIGVycm9yIHN0YXR1cwogICAgICAgICAqIG9mIHRoZSBsYXN0IHJvdW5kLgogICAgICAgICAqLwogICAgICAgIGlmIChtZXNzYWdlci5lcnJvclJhaXNlZCgpCiAgICAgICAgICAgICAgICB8fCB3ZXJyb3IgJiYgcm91bmQud2FybmluZ0NvdW50KCkgPiAwICYmIHJvdW5kLmVycm9yQ291bnQoKSA+IDApCiAgICAgICAgICAgIGVycm9yU3RhdHVzID0gdHJ1ZTsKCiAgICAgICAgU2V0PEphdmFGaWxlT2JqZWN0PiBuZXdTb3VyY2VGaWxlcyA9CiAgICAgICAgICAgICAgICBuZXcgTGlua2VkSGFzaFNldDw+KGZpbGVyLmdldEdlbmVyYXRlZFNvdXJjZUZpbGVPYmplY3RzKCkpOwogICAgICAgIHJvb3RzID0gcm91bmQucm9vdHM7CgogICAgICAgIGVycm9yU3RhdHVzID0gZXJyb3JTdGF0dXMgfHwgKGNvbXBpbGVyLmVycm9yQ291bnQoKSA+IDApOwoKICAgICAgICByb3VuZC5maW5hbENvbXBpbGVyKCk7CgogICAgICAgIGlmIChuZXdTb3VyY2VGaWxlcy5zaXplKCkgPiAwKQogICAgICAgICAgICByb290cyA9IHJvb3RzLmFwcGVuZExpc3QoY29tcGlsZXIucGFyc2VGaWxlcyhuZXdTb3VyY2VGaWxlcykpOwoKICAgICAgICBlcnJvclN0YXR1cyA9IGVycm9yU3RhdHVzIHx8IChjb21waWxlci5lcnJvckNvdW50KCkgPiAwKTsKCiAgICAgICAgLy8gRnJlZSByZXNvdXJjZXMKICAgICAgICB0aGlzLmNsb3NlKCk7CgogICAgICAgIGlmIChlcnJvclN0YXR1cyAmJiBjb21waWxlci5lcnJvckNvdW50KCkgPT0gMCkgewogICAgICAgICAgICBjb21waWxlci5sb2cubmVycm9ycysrOwogICAgICAgIH0KCiAgICAgICAgY29tcGlsZXIuZW50ZXJUcmVlc0lmTmVlZGVkKHJvb3RzKTsKCiAgICAgICAgaWYgKCF0YXNrTGlzdGVuZXIuaXNFbXB0eSgpKQogICAgICAgICAgICB0YXNrTGlzdGVuZXIuZmluaXNoZWQobmV3IFRhc2tFdmVudChUYXNrRXZlbnQuS2luZC5BTk5PVEFUSU9OX1BST0NFU1NJTkcpKTsKCiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgcHJpdmF0ZSB2b2lkIHdhcm5JZlVubWF0Y2hlZE9wdGlvbnMoKSB7CiAgICAgICAgaWYgKCF1bm1hdGNoZWRQcm9jZXNzb3JPcHRpb25zLmlzRW1wdHkoKSkgewogICAgICAgICAgICBsb2cud2FybmluZygicHJvYy51bm1hdGNoZWQucHJvY2Vzc29yLm9wdGlvbnMiLCB1bm1hdGNoZWRQcm9jZXNzb3JPcHRpb25zLnRvU3RyaW5nKCkpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEZyZWUgcmVzb3VyY2VzIHJlbGF0ZWQgdG8gYW5ub3RhdGlvbiBwcm9jZXNzaW5nLgogICAgICovCiAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHsKICAgICAgICBmaWxlci5jbG9zZSgpOwogICAgICAgIGlmIChkaXNjb3ZlcmVkUHJvY3MgIT0gbnVsbCkgLy8gTWFrZSBjYWxsaW5nIGNsb3NlIGlkZW1wb3RlbnQKICAgICAgICAgICAgZGlzY292ZXJlZFByb2NzLmNsb3NlKCk7CiAgICAgICAgZGlzY292ZXJlZFByb2NzID0gbnVsbDsKICAgIH0KCiAgICBwcml2YXRlIExpc3Q8Q2xhc3NTeW1ib2w+IGdldFRvcExldmVsQ2xhc3NlcyhMaXN0PD8gZXh0ZW5kcyBKQ0NvbXBpbGF0aW9uVW5pdD4gdW5pdHMpIHsKICAgICAgICBMaXN0PENsYXNzU3ltYm9sPiBjbGFzc2VzID0gTGlzdC5uaWwoKTsKICAgICAgICBmb3IgKEpDQ29tcGlsYXRpb25Vbml0IHVuaXQgOiB1bml0cykgewogICAgICAgICAgICBmb3IgKEpDVHJlZSBub2RlIDogdW5pdC5kZWZzKSB7CiAgICAgICAgICAgICAgICBpZiAobm9kZS5oYXNUYWcoSkNUcmVlLlRhZy5DTEFTU0RFRikpIHsKICAgICAgICAgICAgICAgICAgICBDbGFzc1N5bWJvbCBzeW0gPSAoKEpDQ2xhc3NEZWNsKSBub2RlKS5zeW07CiAgICAgICAgICAgICAgICAgICAgQXNzZXJ0LmNoZWNrTm9uTnVsbChzeW0pOwogICAgICAgICAgICAgICAgICAgIGNsYXNzZXMgPSBjbGFzc2VzLnByZXBlbmQoc3ltKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gY2xhc3Nlcy5yZXZlcnNlKCk7CiAgICB9CgogICAgcHJpdmF0ZSBMaXN0PENsYXNzU3ltYm9sPiBnZXRUb3BMZXZlbENsYXNzZXNGcm9tQ2xhc3NlcyhMaXN0PD8gZXh0ZW5kcyBDbGFzc1N5bWJvbD4gc3ltcykgewogICAgICAgIExpc3Q8Q2xhc3NTeW1ib2w+IGNsYXNzZXMgPSBMaXN0Lm5pbCgpOwogICAgICAgIGZvciAoQ2xhc3NTeW1ib2wgc3ltIDogc3ltcykgewogICAgICAgICAgICBpZiAoIWlzUGtnSW5mbyhzeW0pKSB7CiAgICAgICAgICAgICAgICBjbGFzc2VzID0gY2xhc3Nlcy5wcmVwZW5kKHN5bSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIGNsYXNzZXMucmV2ZXJzZSgpOwogICAgfQoKICAgIHByaXZhdGUgTGlzdDxQYWNrYWdlU3ltYm9sPiBnZXRQYWNrYWdlSW5mb0ZpbGVzKExpc3Q8PyBleHRlbmRzIEpDQ29tcGlsYXRpb25Vbml0PiB1bml0cykgewogICAgICAgIExpc3Q8UGFja2FnZVN5bWJvbD4gcGFja2FnZXMgPSBMaXN0Lm5pbCgpOwogICAgICAgIGZvciAoSkNDb21waWxhdGlvblVuaXQgdW5pdCA6IHVuaXRzKSB7CiAgICAgICAgICAgIGlmIChpc1BrZ0luZm8odW5pdC5zb3VyY2VmaWxlLCBKYXZhRmlsZU9iamVjdC5LaW5kLlNPVVJDRSkpIHsKICAgICAgICAgICAgICAgIHBhY2thZ2VzID0gcGFja2FnZXMucHJlcGVuZCh1bml0LnBhY2tnZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHBhY2thZ2VzLnJldmVyc2UoKTsKICAgIH0KCiAgICBwcml2YXRlIExpc3Q8UGFja2FnZVN5bWJvbD4gZ2V0UGFja2FnZUluZm9GaWxlc0Zyb21DbGFzc2VzKExpc3Q8PyBleHRlbmRzIENsYXNzU3ltYm9sPiBzeW1zKSB7CiAgICAgICAgTGlzdDxQYWNrYWdlU3ltYm9sPiBwYWNrYWdlcyA9IExpc3QubmlsKCk7CiAgICAgICAgZm9yIChDbGFzc1N5bWJvbCBzeW0gOiBzeW1zKSB7CiAgICAgICAgICAgIGlmIChpc1BrZ0luZm8oc3ltKSkgewogICAgICAgICAgICAgICAgcGFja2FnZXMgPSBwYWNrYWdlcy5wcmVwZW5kKChQYWNrYWdlU3ltYm9sKSBzeW0ub3duZXIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBwYWNrYWdlcy5yZXZlcnNlKCk7CiAgICB9CgogICAgcHJpdmF0ZSBMaXN0PE1vZHVsZVN5bWJvbD4gZ2V0TW9kdWxlSW5mb0ZpbGVzKExpc3Q8PyBleHRlbmRzIEpDQ29tcGlsYXRpb25Vbml0PiB1bml0cykgewogICAgICAgIExpc3Q8TW9kdWxlU3ltYm9sPiBtb2R1bGVzID0gTGlzdC5uaWwoKTsKICAgICAgICBmb3IgKEpDQ29tcGlsYXRpb25Vbml0IHVuaXQgOiB1bml0cykgewogICAgICAgICAgICBpZiAoaXNNb2R1bGVJbmZvKHVuaXQuc291cmNlZmlsZSwgSmF2YUZpbGVPYmplY3QuS2luZC5TT1VSQ0UpICYmCiAgICAgICAgICAgICAgICB1bml0LmRlZnMubm9uRW1wdHkoKSAmJgogICAgICAgICAgICAgICAgdW5pdC5kZWZzLmhlYWQuaGFzVGFnKFRhZy5NT0RVTEVERUYpKSB7CiAgICAgICAgICAgICAgICBtb2R1bGVzID0gbW9kdWxlcy5wcmVwZW5kKHVuaXQubW9kbGUpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBtb2R1bGVzLnJldmVyc2UoKTsKICAgIH0KCiAgICAvLyBhdm9pZCB1bmNoZWNrZWQgd2FybmluZyBmcm9tIHVzZSBvZiB2YXJhcmdzCiAgICBwcml2YXRlIHN0YXRpYyA8VD4gTGlzdDxUPiBqb2luKExpc3Q8VD4gbGlzdDEsIExpc3Q8VD4gbGlzdDIpIHsKICAgICAgICByZXR1cm4gbGlzdDEuYXBwZW5kTGlzdChsaXN0Mik7CiAgICB9CgogICAgcHJpdmF0ZSBib29sZWFuIGlzUGtnSW5mbyhKYXZhRmlsZU9iamVjdCBmbywgSmF2YUZpbGVPYmplY3QuS2luZCBraW5kKSB7CiAgICAgICAgcmV0dXJuIGZvLmlzTmFtZUNvbXBhdGlibGUoInBhY2thZ2UtaW5mbyIsIGtpbmQpOwogICAgfQoKICAgIHByaXZhdGUgYm9vbGVhbiBpc1BrZ0luZm8oQ2xhc3NTeW1ib2wgc3ltKSB7CiAgICAgICAgcmV0dXJuIGlzUGtnSW5mbyhzeW0uY2xhc3NmaWxlLCBKYXZhRmlsZU9iamVjdC5LaW5kLkNMQVNTKSAmJiAoc3ltLnBhY2tnZSgpLnBhY2thZ2VfaW5mbyA9PSBzeW0pOwogICAgfQoKICAgIHByaXZhdGUgYm9vbGVhbiBpc01vZHVsZUluZm8oSmF2YUZpbGVPYmplY3QgZm8sIEphdmFGaWxlT2JqZWN0LktpbmQga2luZCkgewogICAgICAgIHJldHVybiBmby5pc05hbWVDb21wYXRpYmxlKCJtb2R1bGUtaW5mbyIsIGtpbmQpOwogICAgfQoKICAgIC8qCiAgICAgKiBDYWxsZWQgcmV0cm9hY3RpdmVseSB0byBkZXRlcm1pbmUgaWYgYSBjbGFzcyBsb2FkZXIgd2FzIHJlcXVpcmVkLAogICAgICogYWZ0ZXIgd2UgaGF2ZSBmYWlsZWQgdG8gY3JlYXRlIG9uZS4KICAgICAqLwogICAgcHJpdmF0ZSBib29sZWFuIG5lZWRDbGFzc0xvYWRlcihTdHJpbmcgcHJvY05hbWVzLCBJdGVyYWJsZTw/IGV4dGVuZHMgUGF0aD4gd29ya2luZ3BhdGgpIHsKICAgICAgICBpZiAocHJvY05hbWVzICE9IG51bGwpCiAgICAgICAgICAgIHJldHVybiB0cnVlOwoKICAgICAgICBVUkxbXSB1cmxzID0gbmV3IFVSTFsxXTsKICAgICAgICBmb3IoUGF0aCBwYXRoRWxlbWVudCA6IHdvcmtpbmdwYXRoKSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICB1cmxzWzBdID0gcGF0aEVsZW1lbnQudG9VcmkoKS50b1VSTCgpOwogICAgICAgICAgICAgICAgaWYgKFNlcnZpY2VQcm94eS5oYXNTZXJ2aWNlKFByb2Nlc3Nvci5jbGFzcywgdXJscykpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0gY2F0Y2ggKE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiBleCkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKGV4KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBjYXRjaCAoU2VydmljZVByb3h5LlNlcnZpY2VDb25maWd1cmF0aW9uRXJyb3IgZSkgewogICAgICAgICAgICAgICAgbG9nLmVycm9yKCJwcm9jLmJhZC5jb25maWcuZmlsZSIsIGUuZ2V0TG9jYWxpemVkTWVzc2FnZSgpKTsKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgY2xhc3MgSW1wbGljaXRDb21wbGV0ZXIgaW1wbGVtZW50cyBDb21wbGV0ZXIgewoKICAgICAgICBwcml2YXRlIGZpbmFsIEpDQ29tcGlsYXRpb25Vbml0IHRvcExldmVsOwoKICAgICAgICBwdWJsaWMgSW1wbGljaXRDb21wbGV0ZXIoSkNDb21waWxhdGlvblVuaXQgdG9wTGV2ZWwpIHsKICAgICAgICAgICAgdGhpcy50b3BMZXZlbCA9IHRvcExldmVsOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyB2b2lkIGNvbXBsZXRlKFN5bWJvbCBzeW0pIHRocm93cyBDb21wbGV0aW9uRmFpbHVyZSB7CiAgICAgICAgICAgIGNvbXBpbGVyLnJlYWRTb3VyY2VGaWxlKHRvcExldmVsLCAoQ2xhc3NTeW1ib2wpIHN5bSk7CiAgICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgZmluYWwgVHJlZVNjYW5uZXIgdHJlZUNsZWFuZXIgPSBuZXcgVHJlZVNjYW5uZXIoKSB7CiAgICAgICAgICAgIHB1YmxpYyB2b2lkIHNjYW4oSkNUcmVlIG5vZGUpIHsKICAgICAgICAgICAgICAgIHN1cGVyLnNjYW4obm9kZSk7CiAgICAgICAgICAgICAgICBpZiAobm9kZSAhPSBudWxsKQogICAgICAgICAgICAgICAgICAgIG5vZGUudHlwZSA9IG51bGw7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgSkNDb21waWxhdGlvblVuaXQgdG9wTGV2ZWw7CiAgICAgICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0VG9wTGV2ZWwoSkNDb21waWxhdGlvblVuaXQgbm9kZSkgewogICAgICAgICAgICAgICAgaWYgKG5vZGUucGFja2dlICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICBpZiAobm9kZS5wYWNrZ2UucGFja2FnZV9pbmZvICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgbm9kZS5wYWNrZ2UucGFja2FnZV9pbmZvLnJlc2V0KCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIG5vZGUucGFja2dlLnJlc2V0KCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBib29sZWFuIGlzTW9kdWxlSW5mbyA9IG5vZGUuc291cmNlZmlsZS5pc05hbWVDb21wYXRpYmxlKCJtb2R1bGUtaW5mbyIsIEtpbmQuU09VUkNFKTsKICAgICAgICAgICAgICAgIGlmIChpc01vZHVsZUluZm8pIHsKICAgICAgICAgICAgICAgICAgICBub2RlLm1vZGxlLnJlc2V0KCk7CiAgICAgICAgICAgICAgICAgICAgbm9kZS5tb2RsZS5jb21wbGV0ZXIgPSBzeW0gLT4gbW9kdWxlcy5lbnRlcihMaXN0Lm9mKG5vZGUpLCBub2RlLm1vZGxlLm1vZHVsZV9pbmZvKTsKICAgICAgICAgICAgICAgICAgICBub2RlLm1vZGxlLm1vZHVsZV9pbmZvLnJlc2V0KCk7CiAgICAgICAgICAgICAgICAgICAgbm9kZS5tb2RsZS5tb2R1bGVfaW5mby5tZW1iZXJzX2ZpZWxkID0gV3JpdGVhYmxlU2NvcGUuY3JlYXRlKG5vZGUubW9kbGUubW9kdWxlX2luZm8pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgbm9kZS5wYWNrZ2UgPSBudWxsOwogICAgICAgICAgICAgICAgdG9wTGV2ZWwgPSBub2RlOwogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICBzdXBlci52aXNpdFRvcExldmVsKG5vZGUpOwogICAgICAgICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgICAgICAgICB0b3BMZXZlbCA9IG51bGw7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcHVibGljIHZvaWQgdmlzaXRDbGFzc0RlZihKQ0NsYXNzRGVjbCBub2RlKSB7CiAgICAgICAgICAgICAgICBzdXBlci52aXNpdENsYXNzRGVmKG5vZGUpOwogICAgICAgICAgICAgICAgLy8gcmVtb3ZlIGdlbmVyYXRlZCBjb25zdHJ1Y3RvciB0aGF0IG1heSBoYXZlIGJlZW4gYWRkZWQgZHVyaW5nIGF0dHJpYnV0aW9uOgogICAgICAgICAgICAgICAgTGlzdDxKQ1RyZWU+IGJlZm9yZUNvbnN0cnVjdG9yID0gTGlzdC5uaWwoKTsKICAgICAgICAgICAgICAgIExpc3Q8SkNUcmVlPiBkZWZzID0gbm9kZS5kZWZzOwogICAgICAgICAgICAgICAgd2hpbGUgKGRlZnMubm9uRW1wdHkoKSAmJiAhZGVmcy5oZWFkLmhhc1RhZyhUYWcuTUVUSE9EREVGKSkgewogICAgICAgICAgICAgICAgICAgIGJlZm9yZUNvbnN0cnVjdG9yID0gYmVmb3JlQ29uc3RydWN0b3IucHJlcGVuZChkZWZzLmhlYWQpOwogICAgICAgICAgICAgICAgICAgIGRlZnMgPSBkZWZzLnRhaWw7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoZGVmcy5ub25FbXB0eSgpICYmCiAgICAgICAgICAgICAgICAgICAgKCgoSkNNZXRob2REZWNsKSBkZWZzLmhlYWQpLm1vZHMuZmxhZ3MgJiBGbGFncy5HRU5FUkFURURDT05TVFIpICE9IDApIHsKICAgICAgICAgICAgICAgICAgICBkZWZzID0gZGVmcy50YWlsOwogICAgICAgICAgICAgICAgICAgIHdoaWxlIChiZWZvcmVDb25zdHJ1Y3Rvci5ub25FbXB0eSgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGRlZnMgPSBkZWZzLnByZXBlbmQoYmVmb3JlQ29uc3RydWN0b3IuaGVhZCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJlZm9yZUNvbnN0cnVjdG9yID0gYmVmb3JlQ29uc3RydWN0b3IudGFpbDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgbm9kZS5kZWZzID0gZGVmczsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChub2RlLnN5bSAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgbm9kZS5zeW0uY29tcGxldGVyID0gbmV3IEltcGxpY2l0Q29tcGxldGVyKHRvcExldmVsKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIG5vZGUuc3ltID0gbnVsbDsKICAgICAgICAgICAgfQogICAgICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdE1ldGhvZERlZihKQ01ldGhvZERlY2wgbm9kZSkgewogICAgICAgICAgICAgICAgLy8gcmVtb3ZlIHN1cGVyIGNvbnN0cnVjdG9yIGNhbGwgdGhhdCBtYXkgaGF2ZSBiZWVuIGFkZGVkIGR1cmluZyBhdHRyaWJ1dGlvbjoKICAgICAgICAgICAgICAgIGlmIChUcmVlSW5mby5pc0NvbnN0cnVjdG9yKG5vZGUpICYmIG5vZGUuc3ltICE9IG51bGwgJiYgbm9kZS5zeW0ub3duZXIuaXNFbnVtKCkgJiYKICAgICAgICAgICAgICAgICAgICBub2RlLmJvZHkuc3RhdHMubm9uRW1wdHkoKSAmJiBUcmVlSW5mby5pc1N1cGVyQ2FsbChub2RlLmJvZHkuc3RhdHMuaGVhZCkgJiYKICAgICAgICAgICAgICAgICAgICBub2RlLmJvZHkuc3RhdHMuaGVhZC5wb3MgPT0gbm9kZS5ib2R5LnBvcykgewogICAgICAgICAgICAgICAgICAgIG5vZGUuYm9keS5zdGF0cyA9IG5vZGUuYm9keS5zdGF0cy50YWlsOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgbm9kZS5zeW0gPSBudWxsOwogICAgICAgICAgICAgICAgc3VwZXIudmlzaXRNZXRob2REZWYobm9kZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcHVibGljIHZvaWQgdmlzaXRWYXJEZWYoSkNWYXJpYWJsZURlY2wgbm9kZSkgewogICAgICAgICAgICAgICAgbm9kZS5zeW0gPSBudWxsOwogICAgICAgICAgICAgICAgc3VwZXIudmlzaXRWYXJEZWYobm9kZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcHVibGljIHZvaWQgdmlzaXROZXdDbGFzcyhKQ05ld0NsYXNzIG5vZGUpIHsKICAgICAgICAgICAgICAgIG5vZGUuY29uc3RydWN0b3IgPSBudWxsOwogICAgICAgICAgICAgICAgc3VwZXIudmlzaXROZXdDbGFzcyhub2RlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdEFzc2lnbm9wKEpDQXNzaWduT3Agbm9kZSkgewogICAgICAgICAgICAgICAgbm9kZS5vcGVyYXRvciA9IG51bGw7CiAgICAgICAgICAgICAgICBzdXBlci52aXNpdEFzc2lnbm9wKG5vZGUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0VW5hcnkoSkNVbmFyeSBub2RlKSB7CiAgICAgICAgICAgICAgICBub2RlLm9wZXJhdG9yID0gbnVsbDsKICAgICAgICAgICAgICAgIHN1cGVyLnZpc2l0VW5hcnkobm9kZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcHVibGljIHZvaWQgdmlzaXRCaW5hcnkoSkNCaW5hcnkgbm9kZSkgewogICAgICAgICAgICAgICAgbm9kZS5vcGVyYXRvciA9IG51bGw7CiAgICAgICAgICAgICAgICBzdXBlci52aXNpdEJpbmFyeShub2RlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdFNlbGVjdChKQ0ZpZWxkQWNjZXNzIG5vZGUpIHsKICAgICAgICAgICAgICAgIG5vZGUuc3ltID0gbnVsbDsKICAgICAgICAgICAgICAgIHN1cGVyLnZpc2l0U2VsZWN0KG5vZGUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0SWRlbnQoSkNJZGVudCBub2RlKSB7CiAgICAgICAgICAgICAgICBub2RlLnN5bSA9IG51bGw7CiAgICAgICAgICAgICAgICBzdXBlci52aXNpdElkZW50KG5vZGUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0QW5ub3RhdGlvbihKQ0Fubm90YXRpb24gbm9kZSkgewogICAgICAgICAgICAgICAgbm9kZS5hdHRyaWJ1dGUgPSBudWxsOwogICAgICAgICAgICAgICAgc3VwZXIudmlzaXRBbm5vdGF0aW9uKG5vZGUpOwogICAgICAgICAgICB9CiAgICAgICAgfTsKCgogICAgcHJpdmF0ZSBib29sZWFuIG1vcmVUb0RvKCkgewogICAgICAgIHJldHVybiBmaWxlci5uZXdGaWxlcygpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICoKICAgICAqIENvbW1hbmQgbGluZSBvcHRpb25zIHN1aXRhYmxlIGZvciBwcmVzZW50aW5nIHRvIGFubm90YXRpb24KICAgICAqIHByb2Nlc3NvcnMuCiAgICAgKiB7QGxpdGVyYWwgIi1BZm9vPWJhciJ9IHNob3VsZCBiZSB7QGxpdGVyYWwgIi1BZm9vIiA9PiAiYmFyIn0uCiAgICAgKi8KICAgIEBEZWZpbmVkQnkoQXBpLkFOTk9UQVRJT05fUFJPQ0VTU0lORykKICAgIHB1YmxpYyBNYXA8U3RyaW5nLFN0cmluZz4gZ2V0T3B0aW9ucygpIHsKICAgICAgICByZXR1cm4gcHJvY2Vzc29yT3B0aW9uczsKICAgIH0KCiAgICBARGVmaW5lZEJ5KEFwaS5BTk5PVEFUSU9OX1BST0NFU1NJTkcpCiAgICBwdWJsaWMgTWVzc2FnZXIgZ2V0TWVzc2FnZXIoKSB7CiAgICAgICAgcmV0dXJuIG1lc3NhZ2VyOwogICAgfQoKICAgIEBEZWZpbmVkQnkoQXBpLkFOTk9UQVRJT05fUFJPQ0VTU0lORykKICAgIHB1YmxpYyBKYXZhY0ZpbGVyIGdldEZpbGVyKCkgewogICAgICAgIHJldHVybiBmaWxlcjsKICAgIH0KCiAgICBARGVmaW5lZEJ5KEFwaS5BTk5PVEFUSU9OX1BST0NFU1NJTkcpCiAgICBwdWJsaWMgSmF2YWNFbGVtZW50cyBnZXRFbGVtZW50VXRpbHMoKSB7CiAgICAgICAgcmV0dXJuIGVsZW1lbnRVdGlsczsKICAgIH0KCiAgICBARGVmaW5lZEJ5KEFwaS5BTk5PVEFUSU9OX1BST0NFU1NJTkcpCiAgICBwdWJsaWMgSmF2YWNUeXBlcyBnZXRUeXBlVXRpbHMoKSB7CiAgICAgICAgcmV0dXJuIHR5cGVVdGlsczsKICAgIH0KCiAgICBARGVmaW5lZEJ5KEFwaS5BTk5PVEFUSU9OX1BST0NFU1NJTkcpCiAgICBwdWJsaWMgU291cmNlVmVyc2lvbiBnZXRTb3VyY2VWZXJzaW9uKCkgewogICAgICAgIHJldHVybiBTb3VyY2UudG9Tb3VyY2VWZXJzaW9uKHNvdXJjZSk7CiAgICB9CgogICAgQERlZmluZWRCeShBcGkuQU5OT1RBVElPTl9QUk9DRVNTSU5HKQogICAgcHVibGljIExvY2FsZSBnZXRMb2NhbGUoKSB7CiAgICAgICAgcmV0dXJuIG1lc3NhZ2VzLmdldEN1cnJlbnRMb2NhbGUoKTsKICAgIH0KCiAgICBwdWJsaWMgU2V0PFN5bWJvbC5QYWNrYWdlU3ltYm9sPiBnZXRTcGVjaWZpZWRQYWNrYWdlcygpIHsKICAgICAgICByZXR1cm4gc3BlY2lmaWVkUGFja2FnZXM7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBQYXR0ZXJuIG5vTWF0Y2hlcyAgPSBQYXR0ZXJuLmNvbXBpbGUoIihcXFB7YWxsfSkrIik7CgogICAgLyoqCiAgICAgKiBDb252ZXJ0IGltcG9ydC1zdHlsZSBzdHJpbmcgZm9yIHN1cHBvcnRlZCBhbm5vdGF0aW9ucyBpbnRvIGEKICAgICAqIHJlZ2V4IG1hdGNoaW5nIHRoYXQgc3RyaW5nLiAgSWYgdGhlIHN0cmluZyBpcyBub3QgYSB2YWxpZAogICAgICogaW1wb3J0LXN0eWxlIHN0cmluZywgcmV0dXJuIGEgcmVnZXggdGhhdCB3b24ndCBtYXRjaCBhbnl0aGluZy4KICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgUGF0dGVybiBpbXBvcnRTdHJpbmdUb1BhdHRlcm4oYm9vbGVhbiBhbGxvd01vZHVsZXMsIFN0cmluZyBzLCBQcm9jZXNzb3IgcCwgTG9nIGxvZykgewogICAgICAgIFN0cmluZyBtb2R1bGU7CiAgICAgICAgU3RyaW5nIHBrZzsKICAgICAgICBpbnQgc2xhc2ggPSBzLmluZGV4T2YoJy8nKTsKICAgICAgICBpZiAoc2xhc2ggPT0gKC0xKSkgewogICAgICAgICAgICBpZiAocy5lcXVhbHMoIioiKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIE1hdGNoaW5nVXRpbHMudmFsaWRJbXBvcnRTdHJpbmdUb1BhdHRlcm4ocyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgbW9kdWxlID0gYWxsb3dNb2R1bGVzID8gIi4qLyIgOiAiIjsKICAgICAgICAgICAgcGtnID0gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBtb2R1bGUgPSBQYXR0ZXJuLnF1b3RlKHMuc3Vic3RyaW5nKDAsIHNsYXNoICsgMSkpOwogICAgICAgICAgICBwa2cgPSBzLnN1YnN0cmluZyhzbGFzaCArIDEpOwogICAgICAgIH0KICAgICAgICBpZiAoTWF0Y2hpbmdVdGlscy5pc1ZhbGlkSW1wb3J0U3RyaW5nKHBrZykpIHsKICAgICAgICAgICAgcmV0dXJuIFBhdHRlcm4uY29tcGlsZShtb2R1bGUgKyBNYXRjaGluZ1V0aWxzLnZhbGlkSW1wb3J0U3RyaW5nVG9QYXR0ZXJuU3RyaW5nKHBrZykpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGxvZy53YXJuaW5nKCJwcm9jLm1hbGZvcm1lZC5zdXBwb3J0ZWQuc3RyaW5nIiwgcywgcC5nZXRDbGFzcygpLmdldE5hbWUoKSk7CiAgICAgICAgICAgIHJldHVybiBub01hdGNoZXM7IC8vIHdvbid0IG1hdGNoIGFueSB2YWxpZCBpZGVudGlmaWVyCiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogRm9yIGludGVybmFsIHVzZSBvbmx5LiAgVGhpcyBtZXRob2QgbWF5IGJlIHJlbW92ZWQgd2l0aG91dCB3YXJuaW5nLgogICAgICovCiAgICBwdWJsaWMgQ29udGV4dCBnZXRDb250ZXh0KCkgewogICAgICAgIHJldHVybiBjb250ZXh0OwogICAgfQoKICAgIC8qKgogICAgICogRm9yIGludGVybmFsIHVzZSBvbmx5LiAgVGhpcyBtZXRob2QgbWF5IGJlIHJlbW92ZWQgd2l0aG91dCB3YXJuaW5nLgogICAgICovCiAgICBwdWJsaWMgQ2xhc3NMb2FkZXIgZ2V0UHJvY2Vzc29yQ2xhc3NMb2FkZXIoKSB7CiAgICAgICAgcmV0dXJuIHByb2Nlc3NvckNsYXNzTG9hZGVyOwogICAgfQoKICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CiAgICAgICAgcmV0dXJuICJqYXZhYyBQcm9jZXNzaW5nRW52aXJvbm1lbnQiOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc1ZhbGlkT3B0aW9uTmFtZShTdHJpbmcgb3B0aW9uTmFtZSkgewogICAgICAgIGZvcihTdHJpbmcgcyA6IG9wdGlvbk5hbWUuc3BsaXQoIlxcLiIsIC0xKSkgewogICAgICAgICAgICBpZiAoIVNvdXJjZVZlcnNpb24uaXNJZGVudGlmaWVyKHMpKQogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KfQpQSwMECgAACAAABjupSgAAAAAAAAAAAAAAABkAAABjb20vc3VuL3Rvb2xzL2phdmFjL3V0aWwvUEsDBAoAAAgAAAY7qUomzMbT4yoAAOMqAAAiAAAAY29tL3N1bi90b29scy9qYXZhYy91dGlsL0JpdHMuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMTk5OSwgMjAxNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWw7CgppbXBvcnQgamF2YS51dGlsLkFycmF5czsKCi8qKiBBIGNsYXNzIGZvciBleHRlbnNpYmxlLCBtdXRhYmxlIGJpdCBzZXRzLgogKgogKiAgPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24gcmlzay4KICogIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yCiAqICBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+CiAqLwpwdWJsaWMgY2xhc3MgQml0cyB7CgogICAgLy8gICAgICAgX19fX19fX19fX19fICAgICAgcmVzZXQgICAgX19fX19fX19fCiAgICAvLyAgICAgIC8gIFVOS05PV04gICBcICAgPC0tLS0tLS0tIC8gVU5JTklUICBcCiAgICAvLyAgICAgIFxfX19fX19fX19fX18vICAgICAgIHwgICAgIFxfX19fX19fX18vCiAgICAvLyAgICAgICAgICAgIHwgICAgICAgICAgICAgIHwgICAgICAgICAgfAogICAgLy8gICAgICAgICAgICB8YXNzaWduICAgICAgICB8ICAgICAgICAgIHwgYW55CiAgICAvLyAgICAgICAgICAgIHwgICAgICAgIF9fX19fX19fX19fICAgICAgfAogICAgLy8gICAgICAgICAgICAtLS0tLS0+IC8gIE5PUk1BTCAgIFwgPC0tLS0KICAgIC8vICAgICAgICAgICAgICAgICAgICBcX19fX19fX19fX18vICAgICB8CiAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgfAogICAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgIHwKICAgIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0tLS0tLS0tLS0tCiAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbnkKICAgIHByb3RlY3RlZCBlbnVtIEJpdHNTdGF0ZSB7CiAgICAgICAgLyogIEEgQml0cyBpbnN0YW5jZSBpcyBpbiBVTktOT1dOIHN0YXRlIGlmIGl0IGhhcyBiZWVuIGV4cGxpY2l0bHkgcmVzZXQuCiAgICAgICAgICogIEl0IGlzIHBvc3NpYmxlIHRvIGdldCB0byB0aGlzIHN0YXRlIGZyb20gYW55IG90aGVyIGJ5IGNhbGxpbmcgdGhlCiAgICAgICAgICogIHJlc2V0IG1ldGhvZC4gQW4gaW5zdGFuY2UgaW4gdGhlIFVOS05PV04gc3RhdGUgY2FuIHBhc3MgdG8gdGhlCiAgICAgICAgICogIE5PUk1BTCBzdGF0ZSBhZnRlciBiZWluZyBhc3NpZ25lZCBhbm90aGVyIEJpdHMgaW5zdGFuY2UuCiAgICAgICAgICoKICAgICAgICAgKiAgQml0cyBpbnN0YW5jZXMgYXJlIGZpbmFsIGZpZWxkcyBpbiBGbG93IHNvIHRoZSBVTktOT1dOIHN0YXRlIG1vZGVscwogICAgICAgICAqICB0aGUgbnVsbCBhc3NpZ25tZW50LgogICAgICAgICAqLwogICAgICAgIFVOS05PV04sCiAgICAgICAgLyogIEEgQml0cyBpbnN0YW5jZSBpcyBpbiBVTklOSVQgd2hlbiBpdCBpcyBjcmVhdGVkIHdpdGggdGhlIGRlZmF1bHQKICAgICAgICAgKiAgY29uc3RydWN0b3IgYnV0IGl0IGlzbid0IGV4cGxpY2l0bHkgcmVzZXQuIFRoZSBtYWluIG9iamVjdGl2ZSBvZiB0aGlzCiAgICAgICAgICogIGludGVybmFsIHN0YXRlIGlzIHRvIHNhdmUgc29tZSBtZW1vcnkuCiAgICAgICAgICovCiAgICAgICAgVU5JTklULAogICAgICAgIC8qICBUaGUgbm9ybWFsIHN0YXRlIGlzIHJlYWNoZWQgYWZ0ZXIgY3JlYXRpbmcgYSBCaXRzIGluc3RhbmNlIGZyb20gYW4KICAgICAgICAgKiAgZXhpc3Rpbmcgb25lIG9yIGFmdGVyIGFwcGx5aW5nIGFueSBvcGVyYXRpb24gdG8gYW4gaW5zdGFuY2Ugb24gVU5JTklUCiAgICAgICAgICogIG9yIE5PUk1BTCBzdGF0ZS4gRnJvbSB0aGlzIHN0YXRlIGEgYml0cyBpbnN0YW5jZSBjYW4gcGFzcyB0byB0aGUKICAgICAgICAgKiAgVU5LTk9XTiBzdGF0ZSBieSBjYWxsaW5nIHRoZSByZXNldCBtZXRob2QuCiAgICAgICAgICovCiAgICAgICAgTk9STUFMOwoKICAgICAgICBzdGF0aWMgQml0c1N0YXRlIGdldFN0YXRlKGludFtdIHNvbWVCaXRzLCBib29sZWFuIHJlc2V0KSB7CiAgICAgICAgICAgIGlmIChyZXNldCkgewogICAgICAgICAgICAgICAgcmV0dXJuIFVOS05PV047CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBpZiAoc29tZUJpdHMgIT0gdW5hc3NpZ25lZEJpdHMpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gTk9STUFMOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gVU5JTklUOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgIH0KCiAgICBwcml2YXRlIGZpbmFsIHN0YXRpYyBpbnQgd29yZGxlbiA9IDMyOwogICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgaW50IHdvcmRzaGlmdCA9IDU7CiAgICBwcml2YXRlIGZpbmFsIHN0YXRpYyBpbnQgd29yZG1hc2sgPSB3b3JkbGVuIC0gMTsKCiAgICBwdWJsaWMgaW50W10gYml0cyA9IG51bGw7CiAgICAvLyBUaGlzIGZpZWxkIHdpbGwgc3RvcmUgbGFzdCB2ZXJzaW9uIG9mIGJpdHMgYWZ0ZXIgZXZlcnkgY2hhbmdlLgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50W10gdW5hc3NpZ25lZEJpdHMgPSBuZXcgaW50WzBdOwoKICAgIHByb3RlY3RlZCBCaXRzU3RhdGUgY3VycmVudFN0YXRlOwoKICAgIC8qKiBDb25zdHJ1Y3QgYW4gaW5pdGlhbGx5IGVtcHR5IHNldC4KICAgICAqLwogICAgcHVibGljIEJpdHMoKSB7CiAgICAgICAgdGhpcyhmYWxzZSk7CiAgICB9CgogICAgcHVibGljIEJpdHMoQml0cyBzb21lQml0cykgewogICAgICAgIHRoaXMoc29tZUJpdHMuZHVwKCkuYml0cywgQml0c1N0YXRlLmdldFN0YXRlKHNvbWVCaXRzLmJpdHMsIGZhbHNlKSk7CiAgICB9CgogICAgcHVibGljIEJpdHMoYm9vbGVhbiByZXNldCkgewogICAgICAgIHRoaXModW5hc3NpZ25lZEJpdHMsIEJpdHNTdGF0ZS5nZXRTdGF0ZSh1bmFzc2lnbmVkQml0cywgcmVzZXQpKTsKICAgIH0KCiAgICAvKiogQ29uc3RydWN0IGEgc2V0IGNvbnNpc3RpbmcgaW5pdGlhbGx5IG9mIGdpdmVuIGJpdCB2ZWN0b3IuCiAgICAgKi8KICAgIHByb3RlY3RlZCBCaXRzKGludFtdIGJpdHMsIEJpdHNTdGF0ZSBpbml0U3RhdGUpIHsKICAgICAgICB0aGlzLmJpdHMgPSBiaXRzOwogICAgICAgIHRoaXMuY3VycmVudFN0YXRlID0gaW5pdFN0YXRlOwogICAgICAgIHN3aXRjaCAoaW5pdFN0YXRlKSB7CiAgICAgICAgICAgIGNhc2UgVU5LTk9XTjoKICAgICAgICAgICAgICAgIHRoaXMuYml0cyA9IG51bGw7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBOT1JNQUw6CiAgICAgICAgICAgICAgICBBc3NlcnQuY2hlY2soYml0cyAhPSB1bmFzc2lnbmVkQml0cyk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICB9CgogICAgcHJvdGVjdGVkIHZvaWQgc2l6ZVRvKGludCBsZW4pIHsKICAgICAgICBpZiAoYml0cy5sZW5ndGggPCBsZW4pIHsKICAgICAgICAgICAgYml0cyA9IEFycmF5cy5jb3B5T2YoYml0cywgbGVuKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqIFRoaXMgc2V0ID0ge30uCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIGNsZWFyKCkgewogICAgICAgIEFzc2VydC5jaGVjayhjdXJyZW50U3RhdGUgIT0gQml0c1N0YXRlLlVOS05PV04pOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYml0cy5sZW5ndGg7IGkrKykgewogICAgICAgICAgICBiaXRzW2ldID0gMDsKICAgICAgICB9CiAgICAgICAgY3VycmVudFN0YXRlID0gQml0c1N0YXRlLk5PUk1BTDsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCByZXNldCgpIHsKICAgICAgICBpbnRlcm5hbFJlc2V0KCk7CiAgICB9CgogICAgcHJvdGVjdGVkIHZvaWQgaW50ZXJuYWxSZXNldCgpIHsKICAgICAgICBiaXRzID0gbnVsbDsKICAgICAgICBjdXJyZW50U3RhdGUgPSBCaXRzU3RhdGUuVU5LTk9XTjsKICAgIH0KCiAgICBwdWJsaWMgYm9vbGVhbiBpc1Jlc2V0KCkgewogICAgICAgIHJldHVybiBjdXJyZW50U3RhdGUgPT0gQml0c1N0YXRlLlVOS05PV047CiAgICB9CgogICAgcHVibGljIEJpdHMgYXNzaWduKEJpdHMgc29tZUJpdHMpIHsKICAgICAgICBiaXRzID0gc29tZUJpdHMuZHVwKCkuYml0czsKICAgICAgICBjdXJyZW50U3RhdGUgPSBCaXRzU3RhdGUuTk9STUFMOwogICAgICAgIHJldHVybiB0aGlzOwogICAgfQoKICAgIC8qKiBSZXR1cm4gYSBjb3B5IG9mIHRoaXMgc2V0LgogICAgICovCiAgICBwdWJsaWMgQml0cyBkdXAoKSB7CiAgICAgICAgQXNzZXJ0LmNoZWNrKGN1cnJlbnRTdGF0ZSAhPSBCaXRzU3RhdGUuVU5LTk9XTik7CiAgICAgICAgQml0cyB0bXAgPSBuZXcgQml0cygpOwogICAgICAgIHRtcC5iaXRzID0gZHVwQml0cygpOwogICAgICAgIGN1cnJlbnRTdGF0ZSA9IEJpdHNTdGF0ZS5OT1JNQUw7CiAgICAgICAgcmV0dXJuIHRtcDsKICAgIH0KCiAgICBwcm90ZWN0ZWQgaW50W10gZHVwQml0cygpIHsKICAgICAgICBpbnQgW10gcmVzdWx0OwogICAgICAgIGlmIChjdXJyZW50U3RhdGUgIT0gQml0c1N0YXRlLk5PUk1BTCkgewogICAgICAgICAgICByZXN1bHQgPSBiaXRzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJlc3VsdCA9IG5ldyBpbnRbYml0cy5sZW5ndGhdOwogICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGJpdHMsIDAsIHJlc3VsdCwgMCwgYml0cy5sZW5ndGgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgfQoKICAgIC8qKiBJbmNsdWRlIHggaW4gdGhpcyBzZXQuCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIGluY2woaW50IHgpIHsKICAgICAgICBBc3NlcnQuY2hlY2soY3VycmVudFN0YXRlICE9IEJpdHNTdGF0ZS5VTktOT1dOKTsKICAgICAgICBBc3NlcnQuY2hlY2soeCA+PSAwKTsKICAgICAgICBzaXplVG8oKHggPj4+IHdvcmRzaGlmdCkgKyAxKTsKICAgICAgICBiaXRzW3ggPj4+IHdvcmRzaGlmdF0gPSBiaXRzW3ggPj4+IHdvcmRzaGlmdF0gfAogICAgICAgICAgICAoMSA8PCAoeCAmIHdvcmRtYXNrKSk7CiAgICAgICAgY3VycmVudFN0YXRlID0gQml0c1N0YXRlLk5PUk1BTDsKICAgIH0KCgogICAgLyoqIEluY2x1ZGUgW3N0YXJ0Li5saW1pdCkgaW4gdGhpcyBzZXQuCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIGluY2xSYW5nZShpbnQgc3RhcnQsIGludCBsaW1pdCkgewogICAgICAgIEFzc2VydC5jaGVjayhjdXJyZW50U3RhdGUgIT0gQml0c1N0YXRlLlVOS05PV04pOwogICAgICAgIHNpemVUbygobGltaXQgPj4+IHdvcmRzaGlmdCkgKyAxKTsKICAgICAgICBmb3IgKGludCB4ID0gc3RhcnQ7IHggPCBsaW1pdDsgeCsrKSB7CiAgICAgICAgICAgIGJpdHNbeCA+Pj4gd29yZHNoaWZ0XSA9IGJpdHNbeCA+Pj4gd29yZHNoaWZ0XSB8CiAgICAgICAgICAgICAgICAoMSA8PCAoeCAmIHdvcmRtYXNrKSk7CiAgICAgICAgfQogICAgICAgIGN1cnJlbnRTdGF0ZSA9IEJpdHNTdGF0ZS5OT1JNQUw7CiAgICB9CgogICAgLyoqIEV4Y2x1ZGUgW3N0YXJ0Li4uZW5kXSBmcm9tIHRoaXMgc2V0LgogICAgICovCiAgICBwdWJsaWMgdm9pZCBleGNsdWRlRnJvbShpbnQgc3RhcnQpIHsKICAgICAgICBBc3NlcnQuY2hlY2soY3VycmVudFN0YXRlICE9IEJpdHNTdGF0ZS5VTktOT1dOKTsKICAgICAgICBCaXRzIHRlbXAgPSBuZXcgQml0cygpOwogICAgICAgIHRlbXAuc2l6ZVRvKGJpdHMubGVuZ3RoKTsKICAgICAgICB0ZW1wLmluY2xSYW5nZSgwLCBzdGFydCk7CiAgICAgICAgaW50ZXJuYWxBbmRTZXQodGVtcCk7CiAgICAgICAgY3VycmVudFN0YXRlID0gQml0c1N0YXRlLk5PUk1BTDsKICAgIH0KCiAgICAvKiogRXhjbHVkZSB4IGZyb20gdGhpcyBzZXQuCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIGV4Y2woaW50IHgpIHsKICAgICAgICBBc3NlcnQuY2hlY2soY3VycmVudFN0YXRlICE9IEJpdHNTdGF0ZS5VTktOT1dOKTsKICAgICAgICBBc3NlcnQuY2hlY2soeCA+PSAwKTsKICAgICAgICBzaXplVG8oKHggPj4+IHdvcmRzaGlmdCkgKyAxKTsKICAgICAgICBiaXRzW3ggPj4+IHdvcmRzaGlmdF0gPSBiaXRzW3ggPj4+IHdvcmRzaGlmdF0gJgogICAgICAgICAgICB+KDEgPDwgKHggJiB3b3JkbWFzaykpOwogICAgICAgIGN1cnJlbnRTdGF0ZSA9IEJpdHNTdGF0ZS5OT1JNQUw7CiAgICB9CgogICAgLyoqIElzIHggYW4gZWxlbWVudCBvZiB0aGlzIHNldD8KICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gaXNNZW1iZXIoaW50IHgpIHsKICAgICAgICBBc3NlcnQuY2hlY2soY3VycmVudFN0YXRlICE9IEJpdHNTdGF0ZS5VTktOT1dOKTsKICAgICAgICByZXR1cm4KICAgICAgICAgICAgMCA8PSB4ICYmIHggPCAoYml0cy5sZW5ndGggPDwgd29yZHNoaWZ0KSAmJgogICAgICAgICAgICAoYml0c1t4ID4+PiB3b3Jkc2hpZnRdICYgKDEgPDwgKHggJiB3b3JkbWFzaykpKSAhPSAwOwogICAgfQoKICAgIC8qKiB7QGxpdGVyYWwgdGhpcyBzZXQgPSB0aGlzIHNldCAmIHhzfS4KICAgICAqLwogICAgcHVibGljIEJpdHMgYW5kU2V0KEJpdHMgeHMpIHsKICAgICAgICBBc3NlcnQuY2hlY2soY3VycmVudFN0YXRlICE9IEJpdHNTdGF0ZS5VTktOT1dOKTsKICAgICAgICBpbnRlcm5hbEFuZFNldCh4cyk7CiAgICAgICAgY3VycmVudFN0YXRlID0gQml0c1N0YXRlLk5PUk1BTDsKICAgICAgICByZXR1cm4gdGhpczsKICAgIH0KCiAgICBwcm90ZWN0ZWQgdm9pZCBpbnRlcm5hbEFuZFNldChCaXRzIHhzKSB7CiAgICAgICAgQXNzZXJ0LmNoZWNrKGN1cnJlbnRTdGF0ZSAhPSBCaXRzU3RhdGUuVU5LTk9XTik7CiAgICAgICAgc2l6ZVRvKHhzLmJpdHMubGVuZ3RoKTsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHhzLmJpdHMubGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgYml0c1tpXSA9IGJpdHNbaV0gJiB4cy5iaXRzW2ldOwogICAgICAgIH0KICAgIH0KCiAgICAvKiogdGhpcyBzZXQgPSB0aGlzIHNldCB8IHhzLgogICAgICovCiAgICBwdWJsaWMgQml0cyBvclNldChCaXRzIHhzKSB7CiAgICAgICAgQXNzZXJ0LmNoZWNrKGN1cnJlbnRTdGF0ZSAhPSBCaXRzU3RhdGUuVU5LTk9XTik7CiAgICAgICAgc2l6ZVRvKHhzLmJpdHMubGVuZ3RoKTsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHhzLmJpdHMubGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgYml0c1tpXSA9IGJpdHNbaV0gfCB4cy5iaXRzW2ldOwogICAgICAgIH0KICAgICAgICBjdXJyZW50U3RhdGUgPSBCaXRzU3RhdGUuTk9STUFMOwogICAgICAgIHJldHVybiB0aGlzOwogICAgfQoKICAgIC8qKiB0aGlzIHNldCA9IHRoaXMgc2V0IFwgeHMuCiAgICAgKi8KICAgIHB1YmxpYyBCaXRzIGRpZmZTZXQoQml0cyB4cykgewogICAgICAgIEFzc2VydC5jaGVjayhjdXJyZW50U3RhdGUgIT0gQml0c1N0YXRlLlVOS05PV04pOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYml0cy5sZW5ndGg7IGkrKykgewogICAgICAgICAgICBpZiAoaSA8IHhzLmJpdHMubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICBiaXRzW2ldID0gYml0c1tpXSAmIH54cy5iaXRzW2ldOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGN1cnJlbnRTdGF0ZSA9IEJpdHNTdGF0ZS5OT1JNQUw7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CgogICAgLyoqIHRoaXMgc2V0ID0gdGhpcyBzZXQgXiB4cy4KICAgICAqLwogICAgcHVibGljIEJpdHMgeG9yU2V0KEJpdHMgeHMpIHsKICAgICAgICBBc3NlcnQuY2hlY2soY3VycmVudFN0YXRlICE9IEJpdHNTdGF0ZS5VTktOT1dOKTsKICAgICAgICBzaXplVG8oeHMuYml0cy5sZW5ndGgpOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgeHMuYml0cy5sZW5ndGg7IGkrKykgewogICAgICAgICAgICBiaXRzW2ldID0gYml0c1tpXSBeIHhzLmJpdHNbaV07CiAgICAgICAgfQogICAgICAgIGN1cnJlbnRTdGF0ZSA9IEJpdHNTdGF0ZS5OT1JNQUw7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CgogICAgLyoqIENvdW50IHRyYWlsaW5nIHplcm8gYml0cyBpbiBhbiBpbnQuIEFsZ29yaXRobSBmcm9tICJIYWNrZXIncwogICAgICogIERlbGlnaHQiIGJ5IEhlbnJ5IFMuIFdhcnJlbiBKci4gKGZpZ3VyZSA1LTEzKQogICAgICovCiAgICBwcml2YXRlIHN0YXRpYyBpbnQgdHJhaWxpbmdaZXJvQml0cyhpbnQgeCkgewogICAgICAgIEFzc2VydC5jaGVjayh3b3JkbGVuID09IDMyKTsKICAgICAgICBpZiAoeCA9PSAwKSB7CiAgICAgICAgICAgIHJldHVybiAzMjsKICAgICAgICB9CiAgICAgICAgaW50IG4gPSAxOwogICAgICAgIGlmICgoeCAmIDB4ZmZmZikgPT0gMCkgeyBuICs9IDE2OyB4ID4+Pj0gMTY7IH0KICAgICAgICBpZiAoKHggJiAweDAwZmYpID09IDApIHsgbiArPSAgODsgeCA+Pj49ICA4OyB9CiAgICAgICAgaWYgKCh4ICYgMHgwMDBmKSA9PSAwKSB7IG4gKz0gIDQ7IHggPj4+PSAgNDsgfQogICAgICAgIGlmICgoeCAmIDB4MDAwMykgPT0gMCkgeyBuICs9ICAyOyB4ID4+Pj0gIDI7IH0KICAgICAgICByZXR1cm4gbiAtICh4JjEpOwogICAgfQoKICAgIC8qKiBSZXR1cm4gdGhlIGluZGV4IG9mIHRoZSBsZWFzdCBiaXQgcG9zaXRpb24gJmdlOyB4IHRoYXQgaXMgc2V0LgogICAgICogIElmIG5vbmUgYXJlIHNldCwgcmV0dXJucyAtMS4gIFRoaXMgcHJvdmlkZXMgYSBuaWNlIHdheSB0byBpdGVyYXRlCiAgICAgKiAgb3ZlciB0aGUgbWVtYmVycyBvZiBhIGJpdCBzZXQ6CiAgICAgKiAgPHByZT57QGNvZGUKICAgICAqICBmb3IgKGludCBpID0gYml0cy5uZXh0Qml0KDApOyBpPj0wOyBpID0gYml0cy5uZXh0Qml0KGkrMSkpIC4uLgogICAgICogIH08L3ByZT4KICAgICAqLwogICAgcHVibGljIGludCBuZXh0Qml0KGludCB4KSB7CiAgICAgICAgQXNzZXJ0LmNoZWNrKGN1cnJlbnRTdGF0ZSAhPSBCaXRzU3RhdGUuVU5LTk9XTik7CiAgICAgICAgaW50IHdpbmRleCA9IHggPj4+IHdvcmRzaGlmdDsKICAgICAgICBpZiAod2luZGV4ID49IGJpdHMubGVuZ3RoKSB7CiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICB9CiAgICAgICAgaW50IHdvcmQgPSBiaXRzW3dpbmRleF0gJiB+KCgxIDw8ICh4ICYgd29yZG1hc2spKS0xKTsKICAgICAgICB3aGlsZSAodHJ1ZSkgewogICAgICAgICAgICBpZiAod29yZCAhPSAwKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gKHdpbmRleCA8PCB3b3Jkc2hpZnQpICsgdHJhaWxpbmdaZXJvQml0cyh3b3JkKTsKICAgICAgICAgICAgfQogICAgICAgICAgICB3aW5kZXgrKzsKICAgICAgICAgICAgaWYgKHdpbmRleCA+PSBiaXRzLmxlbmd0aCkgewogICAgICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHdvcmQgPSBiaXRzW3dpbmRleF07CiAgICAgICAgfQogICAgfQoKICAgIC8qKiBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIHNldC4KICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewogICAgICAgIGlmIChiaXRzICE9IG51bGwgJiYgYml0cy5sZW5ndGggPiAwKSB7CiAgICAgICAgICAgIGNoYXJbXSBkaWdpdHMgPSBuZXcgY2hhcltiaXRzLmxlbmd0aCAqIHdvcmRsZW5dOwogICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGJpdHMubGVuZ3RoICogd29yZGxlbjsgaSsrKSB7CiAgICAgICAgICAgICAgICBkaWdpdHNbaV0gPSBpc01lbWJlcihpKSA/ICcxJyA6ICcwJzsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gbmV3IFN0cmluZyhkaWdpdHMpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiAiW10iOwogICAgICAgIH0KICAgIH0KCn0KUEsDBAoAAAgAAAY7qUq0sJFxpToAAKU6AAAqAAAAY29tL3N1bi90b29scy9qYXZhYy91dGlsL0RlcGVuZGVuY2llcy5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDE0LCAyMDE2LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuamF2YWMudXRpbDsKCmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuU3ltYm9sOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlN5bWJvbC5DbGFzc1N5bWJvbDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5TeW1ib2wuQ29tcGxldGVyOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlN5bWJvbC5Db21wbGV0aW9uRmFpbHVyZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMubWFpbi5KYXZhQ29tcGlsZXI7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuR3JhcGhVdGlscy5EZXBlbmRlbmN5S2luZDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5HcmFwaFV0aWxzLkRvdFZpc2l0b3I7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuR3JhcGhVdGlscy5Ob2RlVmlzaXRvcjsKCmltcG9ydCBqYXZhLmlvLkNsb3NlYWJsZTsKaW1wb3J0IGphdmEuaW8uRmlsZVdyaXRlcjsKaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CmltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OwppbXBvcnQgamF2YS51dGlsLkFycmF5czsKaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uOwppbXBvcnQgamF2YS51dGlsLkVudW1NYXA7CmltcG9ydCBqYXZhLnV0aWwuRW51bVNldDsKaW1wb3J0IGphdmEudXRpbC5MaW5rZWRIYXNoTWFwOwppbXBvcnQgamF2YS51dGlsLkxpc3Q7CmltcG9ydCBqYXZhLnV0aWwuTWFwOwppbXBvcnQgamF2YS51dGlsLlByb3BlcnRpZXM7CmltcG9ydCBqYXZhLnV0aWwuU3RhY2s7CgppbXBvcnQgamF2YXgudG9vbHMuSmF2YUZpbGVPYmplY3Q7CgovKioKICogIFRoaXMgY2xhc3MgaXMgdXNlZCB0byB0cmFjayBkZXBlbmRlbmNpZXMgaW4gdGhlIGphdmFjIHN5bWJvbCBjb21wbGV0aW9uIHByb2Nlc3MuCiAqCiAqICA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiAgSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93biByaXNrLgogKiAgVGhpcyBjb2RlIGFuZCBpdHMgaW50ZXJuYWwgaW50ZXJmYWNlcyBhcmUgc3ViamVjdCB0byBjaGFuZ2Ugb3IKICogIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj4KICovCnB1YmxpYyBhYnN0cmFjdCBjbGFzcyBEZXBlbmRlbmNpZXMgewoKICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgQ29udGV4dC5LZXk8RGVwZW5kZW5jaWVzPiBkZXBlbmRlbmNpZXNLZXkgPSBuZXcgQ29udGV4dC5LZXk8PigpOwoKICAgIHB1YmxpYyBzdGF0aWMgRGVwZW5kZW5jaWVzIGluc3RhbmNlKENvbnRleHQgY29udGV4dCkgewogICAgICAgIERlcGVuZGVuY2llcyBpbnN0YW5jZSA9IGNvbnRleHQuZ2V0KGRlcGVuZGVuY2llc0tleSk7CiAgICAgICAgaWYgKGluc3RhbmNlID09IG51bGwpIHsKICAgICAgICAgICAgLy91c2UgYSBkby1ub3RoaW5nIGltcGxlbWVudGF0aW9uIGluIGNhc2Ugbm8gb3RoZXIgaW1wbGVtZW50YXRpb24gaGFzIGJlZW4gc2V0IGJ5IHByZVJlZ2lzdGVyCiAgICAgICAgICAgIGluc3RhbmNlID0gbmV3IER1bW15RGVwZW5kZW5jaWVzKGNvbnRleHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gaW5zdGFuY2U7CiAgICB9CgogICAgcHJvdGVjdGVkIERlcGVuZGVuY2llcyhDb250ZXh0IGNvbnRleHQpIHsKICAgICAgICBjb250ZXh0LnB1dChkZXBlbmRlbmNpZXNLZXksIHRoaXMpOwogICAgfQoKICAgIC8qKgogICAgICogUHVzaCBhIG5ldyBjb21wbGV0aW9uIG5vZGUgb24gdGhlIHN0YWNrLgogICAgICovCiAgICBhYnN0cmFjdCBwdWJsaWMgdm9pZCBwdXNoKENsYXNzU3ltYm9sIHMsIENvbXBsZXRpb25DYXVzZSBwaGFzZSk7CgogICAgLyoqCiAgICAgKiBSZW1vdmUgY3VycmVudCBkZXBlbmRlbmN5IG5vZGUgZnJvbSB0aGUgc3RhY2suCiAgICAgKi8KICAgIGFic3RyYWN0IHB1YmxpYyB2b2lkIHBvcCgpOwoKICAgIHB1YmxpYyBlbnVtIENvbXBsZXRpb25DYXVzZSBpbXBsZW1lbnRzIEdyYXBoVXRpbHMuRGVwZW5kZW5jeUtpbmQgewogICAgICAgIENMQVNTX1JFQURFUiwKICAgICAgICBIRUFERVJfUEhBU0UsCiAgICAgICAgSElFUkFSQ0hZX1BIQVNFLAogICAgICAgIElNUE9SVFNfUEhBU0UsCiAgICAgICAgTUVNQkVSX0VOVEVSLAogICAgICAgIE1FTUJFUlNfUEhBU0UsCiAgICAgICAgT1RIRVI7CiAgICB9CgogICAgLyoqCiAgICAgKiBUaGlzIGNsYXNzIGNyZWF0ZXMgYSBncmFwaCBvZiBhbGwgZGVwZW5kZW5jaWVzIGFzIHN5bWJvbHMgYXJlIGNvbXBsZXRlZDsKICAgICAqIHdoZW4gY29tcGlsYXRpb24gZmluaXNoZXMsIHRoZSByZXN1bHRpbmcgZGVwZW5kZW5jeSBncmFwaCBpcyB0aGVuIGR1bXBlZAogICAgICogb250byBhIGRvdCBmaWxlLiBTZXZlcmFsIG9wdGlvbnMgYXJlIHByb3ZpZGVkIHRvIGN1c3RvbWl6ZSB0aGUgb3V0cHV0IG9mIHRoZSBncmFwaC4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBjbGFzcyBHcmFwaERlcGVuZGVuY2llcyBleHRlbmRzIERlcGVuZGVuY2llcyBpbXBsZW1lbnRzIENsb3NlYWJsZSwgQ29tcGxldGVyIHsKCiAgICAgICAgLyoqCiAgICAgICAgICogc2V0IG9mIGVuYWJsZWQgZGVwZW5kZW5jaWVzIG1vZGVzCiAgICAgICAgICovCiAgICAgICAgcHJpdmF0ZSBFbnVtU2V0PERlcGVuZGVuY2llc01vZGU+IGRlcGVuZGVuY2llc01vZGVzOwoKICAgICAgICAvKioKICAgICAgICAgKiBmaWxlIGluIHdoaWNoIHRoZSBkZXBlbmRlbmN5IGdyYXBoIHNob3VsZCBiZSB3cml0dGVuCiAgICAgICAgICovCiAgICAgICAgcHJpdmF0ZSBTdHJpbmcgZGVwZW5kZW5jaWVzRmlsZTsKCiAgICAgICAgLyoqCiAgICAgICAgICogUmVnaXN0ZXIgYSBDb250ZXh0LkZhY3RvcnkgdG8gY3JlYXRlIGEgRGVwZW5kZW5jaWVzLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBwcmVSZWdpc3RlcihDb250ZXh0IGNvbnRleHQpIHsKICAgICAgICAgICAgY29udGV4dC5wdXQoZGVwZW5kZW5jaWVzS2V5LCAoQ29udGV4dC5GYWN0b3J5PERlcGVuZGVuY2llcz4pIEdyYXBoRGVwZW5kZW5jaWVzOjpuZXcpOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogQnVpbGQgYSBEZXBlbmRlbmNpZXMgaW5zdGFuY2UuCiAgICAgICAgICovCiAgICAgICAgR3JhcGhEZXBlbmRlbmNpZXMoQ29udGV4dCBjb250ZXh0KSB7CiAgICAgICAgICAgIHN1cGVyKGNvbnRleHQpOwogICAgICAgICAgICAvL2ZldGNoIGZpbGVuYW1lCiAgICAgICAgICAgIE9wdGlvbnMgb3B0aW9ucyA9IE9wdGlvbnMuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgICAgIFN0cmluZ1tdIG1vZGVzID0gb3B0aW9ucy5nZXQoImRlYnVnLmNvbXBsZXRpb25EZXBzIikuc3BsaXQoIiwiKTsKICAgICAgICAgICAgZm9yIChTdHJpbmcgbW9kZSA6IG1vZGVzKSB7CiAgICAgICAgICAgICAgICBpZiAobW9kZS5zdGFydHNXaXRoKCJmaWxlPSIpKSB7CiAgICAgICAgICAgICAgICAgICAgZGVwZW5kZW5jaWVzRmlsZSA9IG1vZGUuc3Vic3RyaW5nKDUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vcGFyc2UgbW9kZXMKICAgICAgICAgICAgZGVwZW5kZW5jaWVzTW9kZXMgPSBEZXBlbmRlbmNpZXNNb2RlLmdldERlcGVuZGVuY2llc01vZGVzKG1vZGVzKTsKICAgICAgICAgICAgLy9hZGQgdG8gY2xvc2VhYmxlcwogICAgICAgICAgICBKYXZhQ29tcGlsZXIgY29tcGlsZXIgPSBKYXZhQ29tcGlsZXIuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgICAgIGNvbXBpbGVyLmNsb3NlYWJsZXMgPSBjb21waWxlci5jbG9zZWFibGVzLnByZXBlbmQodGhpcyk7CiAgICAgICAgfQoKICAgICAgICBlbnVtIERlcGVuZGVuY2llc01vZGUgewogICAgICAgICAgICBTT1VSQ0UoInNvdXJjZSIpLAogICAgICAgICAgICBDTEFTUygiY2xhc3MiKSwKICAgICAgICAgICAgUkVEVU5EQU5UKCJyZWR1bmRhbnQiKTsKCiAgICAgICAgICAgIGZpbmFsIFN0cmluZyBvcHQ7CgogICAgICAgICAgICBEZXBlbmRlbmNpZXNNb2RlKFN0cmluZyBvcHQpIHsKICAgICAgICAgICAgICAgIHRoaXMub3B0ID0gb3B0OwogICAgICAgICAgICB9CgogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogVGhpcyBtZXRob2QgaXMgdXNlZCB0byBwYXJzZSB0aGUge0Bjb2RlIGNvbXBsZXRpb25EZXBzfSBvcHRpb24uCiAgICAgICAgICAgICAqIFBvc3NpYmxlIG1vZGVzIGFyZSBzZXBhcmF0ZWQgYnkgY29sb247IGEgbW9kZSBjYW4gYmUgZXhjbHVkZWQgYnkKICAgICAgICAgICAgICogcHJlcGVuZGluZyAnLScgdG8gaXRzIG5hbWUuIEZpbmFsbHksIHRoZSBzcGVjaWFsIG1vZGUgJ2FsbCcgY2FuIGJlIHVzZWQgdG8KICAgICAgICAgICAgICogYWRkIGFsbCBtb2RlcyB0byB0aGUgcmVzdWx0aW5nIGVudW0uCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBzdGF0aWMgRW51bVNldDxEZXBlbmRlbmNpZXNNb2RlPiBnZXREZXBlbmRlbmNpZXNNb2RlcyhTdHJpbmdbXSBtb2RlcykgewogICAgICAgICAgICAgICAgRW51bVNldDxEZXBlbmRlbmNpZXNNb2RlPiByZXMgPSBFbnVtU2V0Lm5vbmVPZihEZXBlbmRlbmNpZXNNb2RlLmNsYXNzKTsKICAgICAgICAgICAgICAgIENvbGxlY3Rpb248U3RyaW5nPiBhcmdzID0gQXJyYXlzLmFzTGlzdChtb2Rlcyk7CiAgICAgICAgICAgICAgICBpZiAoYXJncy5jb250YWlucygiYWxsIikpIHsKICAgICAgICAgICAgICAgICAgICByZXMgPSBFbnVtU2V0LmFsbE9mKERlcGVuZGVuY2llc01vZGUuY2xhc3MpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZm9yIChEZXBlbmRlbmNpZXNNb2RlIG1vZGUgOiB2YWx1ZXMoKSkgewogICAgICAgICAgICAgICAgICAgIGlmIChhcmdzLmNvbnRhaW5zKG1vZGUub3B0KSkgewogICAgICAgICAgICAgICAgICAgICAgICByZXMuYWRkKG1vZGUpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoYXJncy5jb250YWlucygiLSIgKyBtb2RlLm9wdCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmVzLnJlbW92ZShtb2RlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gcmVzOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBDbGFzcyByZXByZXNlbnRpbmcgYSBub2RlIGluIHRoZSBkZXBlbmRlbmN5IGdyYXBoLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBzdGF0aWMgYWJzdHJhY3QgY2xhc3MgTm9kZSBleHRlbmRzIEdyYXBoVXRpbHMuQWJzdHJhY3ROb2RlPENsYXNzU3ltYm9sLCBOb2RlPgogICAgICAgICAgICAgICAgaW1wbGVtZW50cyBHcmFwaFV0aWxzLkRvdHRhYmxlTm9kZTxDbGFzc1N5bWJvbCwgTm9kZT4gewogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogZGVwZW5kYW50IG5vZGVzIGdyb3VwZWQgYnkga2luZAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgRW51bU1hcDxDb21wbGV0aW9uQ2F1c2UsIExpc3Q8Tm9kZT4+IGRlcHNCeUtpbmQ7CgogICAgICAgICAgICBOb2RlKENsYXNzU3ltYm9sIHZhbHVlKSB7CiAgICAgICAgICAgICAgICBzdXBlcih2YWx1ZSk7CiAgICAgICAgICAgICAgICB0aGlzLmRlcHNCeUtpbmQgPSBuZXcgRW51bU1hcDw+KENvbXBsZXRpb25DYXVzZS5jbGFzcyk7CiAgICAgICAgICAgICAgICBmb3IgKENvbXBsZXRpb25DYXVzZSBkZXBLaW5kIDogQ29tcGxldGlvbkNhdXNlLnZhbHVlcygpKSB7CiAgICAgICAgICAgICAgICAgICAgZGVwc0J5S2luZC5wdXQoZGVwS2luZCwgbmV3IEFycmF5TGlzdDxOb2RlPigpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgdm9pZCBhZGREZXBlbmRlbmN5KERlcGVuZGVuY3lLaW5kIGRlcEtpbmQsIE5vZGUgZGVwKSB7CiAgICAgICAgICAgICAgICBMaXN0PE5vZGU+IGRlcHMgPSBkZXBzQnlLaW5kLmdldChkZXBLaW5kKTsKICAgICAgICAgICAgICAgIGlmICghZGVwcy5jb250YWlucyhkZXApKSB7CiAgICAgICAgICAgICAgICAgICAgZGVwcy5hZGQoZGVwKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gb2JqIGluc3RhbmNlb2YgTm9kZSAmJiBkYXRhLmVxdWFscygoKE5vZGUpIG9iaikuZGF0YSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIGRhdGEuaGFzaENvZGUoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHB1YmxpYyBHcmFwaFV0aWxzLkRlcGVuZGVuY3lLaW5kW10gZ2V0U3VwcG9ydGVkRGVwZW5kZW5jeUtpbmRzKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIENvbXBsZXRpb25DYXVzZS52YWx1ZXMoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHB1YmxpYyBqYXZhLnV0aWwuQ29sbGVjdGlvbjw/IGV4dGVuZHMgTm9kZT4gZ2V0RGVwZW5kZW5jaWVzQnlLaW5kKERlcGVuZGVuY3lLaW5kIGRrKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZGVwc0J5S2luZC5nZXQoZGspOwogICAgICAgICAgICB9CgogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHVibGljIFByb3BlcnRpZXMgbm9kZUF0dHJpYnV0ZXMoKSB7CiAgICAgICAgICAgICAgICBQcm9wZXJ0aWVzIHAgPSBuZXcgUHJvcGVydGllcygpOwogICAgICAgICAgICAgICAgcC5wdXQoImxhYmVsIiwgRG90VmlzaXRvci53cmFwKHRvU3RyaW5nKCkpKTsKICAgICAgICAgICAgICAgIHJldHVybiBwOwogICAgICAgICAgICB9CgogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHVibGljIFByb3BlcnRpZXMgZGVwZW5kZW5jeUF0dHJpYnV0ZXMoTm9kZSB0bywgR3JhcGhVdGlscy5EZXBlbmRlbmN5S2luZCBkaykgewogICAgICAgICAgICAgICAgUHJvcGVydGllcyBwID0gbmV3IFByb3BlcnRpZXMoKTsKICAgICAgICAgICAgICAgIHAucHV0KCJsYWJlbCIsIGRrKTsKICAgICAgICAgICAgICAgIHJldHVybiBwOwogICAgICAgICAgICB9CgogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKICAgICAgICAgICAgICAgIHJldHVybiBkYXRhLmdldFF1YWxpZmllZE5hbWUoKS50b1N0cmluZygpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBUaGlzIGlzIGEgZGVwZW5kZW5jeSBub2RlIHVzZWQgdG8gbW9kZWwgc3ltYm9sIGNvbXBsZXRpb24gcmVxdWVzdHMuCiAgICAgICAgICogQ29tcGxldGlvbiByZXF1ZXN0cyBjYW4gY29tZSBmcm9tIGVpdGhlciBzb3VyY2Ugb3IgY2xhc3MuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIHN0YXRpYyBjbGFzcyBDb21wbGV0aW9uTm9kZSBleHRlbmRzIE5vZGUgewoKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIENvbXBsZXRpb24ga2luZCAoc291cmNlIHZzLiBjbGFzc2ZpbGUpCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBlbnVtIEtpbmQgewogICAgICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAgICAgKiBTb3VyY2UgY29tcGxldGlvbiByZXF1ZXN0CiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIFNPVVJDRSgic29saWQiKSwKICAgICAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgICAgICogQ2xhc3NmaWxlIGNvbXBsZXRpb24gcmVxdWVzdAogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBDTEFTUygiZG90dGVkIik7CgogICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIGRvdFN0eWxlOwoKICAgICAgICAgICAgICAgIEtpbmQoU3RyaW5nIGRvdFN0eWxlKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5kb3RTdHlsZSA9IGRvdFN0eWxlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBmaW5hbCBLaW5kIGNrOwoKICAgICAgICAgICAgQ29tcGxldGlvbk5vZGUoQ2xhc3NTeW1ib2wgc3ltKSB7CiAgICAgICAgICAgICAgICBzdXBlcihzeW0pOwogICAgICAgICAgICAgICAgLy9pbmZlciBjb21wbGV0aW9uIGtpbmQgYnkgbG9va2luZyBhdCB0aGUgc3ltYm9sIGZpZWxkcwogICAgICAgICAgICAgICAgYm9vbGVhbiBmcm9tQ2xhc3MgPSAoc3ltLmNsYXNzZmlsZSA9PSBudWxsICYmIHN5bS5zb3VyY2VmaWxlID09IG51bGwpIHx8CiAgICAgICAgICAgICAgICAgICAgICAgIChzeW0uY2xhc3NmaWxlICE9IG51bGwgJiYgc3ltLmNsYXNzZmlsZS5nZXRLaW5kKCkgPT0gSmF2YUZpbGVPYmplY3QuS2luZC5DTEFTUyk7CiAgICAgICAgICAgICAgICBjayA9IGZyb21DbGFzcyA/CiAgICAgICAgICAgICAgICAgICAgICAgIENvbXBsZXRpb25Ob2RlLktpbmQuQ0xBU1MgOgogICAgICAgICAgICAgICAgICAgICAgICBDb21wbGV0aW9uTm9kZS5LaW5kLlNPVVJDRTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHB1YmxpYyBQcm9wZXJ0aWVzIG5vZGVBdHRyaWJ1dGVzKCkgewogICAgICAgICAgICAgICAgUHJvcGVydGllcyBwID0gc3VwZXIubm9kZUF0dHJpYnV0ZXMoKTsKICAgICAgICAgICAgICAgIHAucHV0KCJzdHlsZSIsIGNrLmRvdFN0eWxlKTsKICAgICAgICAgICAgICAgIHAucHV0KCJzaGFwZSIsICJlbGxpcHNlIik7CiAgICAgICAgICAgICAgICByZXR1cm4gcDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHVibGljIENsYXNzU3ltYm9sIGdldENsYXNzU3ltYm9sKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIGRhdGE7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIHN0YWNrIG9mIGRlcGVuZGVuY3kgbm9kZXMgY3VycmVudGx5IGJlaW5nIHByb2Nlc3NlZAogICAgICAgICAqLwogICAgICAgIFN0YWNrPE5vZGU+IG5vZGVTdGFjayA9IG5ldyBTdGFjazw+KCk7CgogICAgICAgIC8qKgogICAgICAgICAqIG1hcCBjb250YWluaW5nIGFsbCBkZXBlbmRlbmN5IG5vZGVzIHNlZW4gc28gZmFyCiAgICAgICAgICovCiAgICAgICAgTWFwPENsYXNzU3ltYm9sLCBOb2RlPiBkZXBlbmRlbmN5Tm9kZU1hcCA9IG5ldyBMaW5rZWRIYXNoTWFwPD4oKTsKCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgcHVzaChDbGFzc1N5bWJvbCBzLCBDb21wbGV0aW9uQ2F1c2UgcGhhc2UpIHsKICAgICAgICAgICAgTm9kZSBuID0gbmV3IENvbXBsZXRpb25Ob2RlKHMpOwogICAgICAgICAgICBpZiAobiA9PSBwdXNoKG4sIHBoYXNlKSkgewogICAgICAgICAgICAgICAgcy5jb21wbGV0ZXIgPSB0aGlzOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBQdXNoIGEgbmV3IGRlcGVuZGVuY3kgb24gdGhlIHN0YWNrLgogICAgICAgICAqLwogICAgICAgIHByb3RlY3RlZCBOb2RlIHB1c2goTm9kZSBuZXdOb2RlLCBDb21wbGV0aW9uQ2F1c2UgY2MpIHsKICAgICAgICAgICAgTm9kZSBjYWNoZWROb2RlID0gZGVwZW5kZW5jeU5vZGVNYXAuZ2V0KG5ld05vZGUuZGF0YSk7CiAgICAgICAgICAgIGlmIChjYWNoZWROb2RlID09IG51bGwpIHsKICAgICAgICAgICAgICAgIGRlcGVuZGVuY3lOb2RlTWFwLnB1dChuZXdOb2RlLmRhdGEsIG5ld05vZGUpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgbmV3Tm9kZSA9IGNhY2hlZE5vZGU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCFub2RlU3RhY2suaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgICBOb2RlIGN1cnJlbnROb2RlID0gbm9kZVN0YWNrLnBlZWsoKTsKICAgICAgICAgICAgICAgIGN1cnJlbnROb2RlLmFkZERlcGVuZGVuY3koY2MsIG5ld05vZGUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIG5vZGVTdGFjay5wdXNoKG5ld05vZGUpOwogICAgICAgICAgICByZXR1cm4gbmV3Tm9kZTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHBvcCgpIHsKICAgICAgICAgICAgbm9kZVN0YWNrLnBvcCgpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgICAgICBpZiAoIWRlcGVuZGVuY2llc01vZGVzLmNvbnRhaW5zKERlcGVuZGVuY2llc01vZGUuUkVEVU5EQU5UKSkgewogICAgICAgICAgICAgICAgLy9wcnVuZSBzcHVyaW91cyBlZGdlcwogICAgICAgICAgICAgICAgbmV3IFBydW5lVmlzaXRvcigpLnZpc2l0KGRlcGVuZGVuY3lOb2RlTWFwLnZhbHVlcygpLCBudWxsKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoIWRlcGVuZGVuY2llc01vZGVzLmNvbnRhaW5zKERlcGVuZGVuY2llc01vZGUuQ0xBU1MpKSB7CiAgICAgICAgICAgICAgICAvL2ZpbHRlciBjbGFzcyBjb21wbGV0aW9ucwogICAgICAgICAgICAgICAgbmV3IEZpbHRlclZpc2l0b3IoQ29tcGxldGlvbk5vZGUuS2luZC5TT1VSQ0UpLnZpc2l0KGRlcGVuZGVuY3lOb2RlTWFwLnZhbHVlcygpLCBudWxsKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoIWRlcGVuZGVuY2llc01vZGVzLmNvbnRhaW5zKERlcGVuZGVuY2llc01vZGUuU09VUkNFKSkgewogICAgICAgICAgICAgICAgLy9maWx0ZXIgc291cmNlIGNvbXBsZXRpb25zCiAgICAgICAgICAgICAgICBuZXcgRmlsdGVyVmlzaXRvcihDb21wbGV0aW9uTm9kZS5LaW5kLkNMQVNTKS52aXNpdChkZXBlbmRlbmN5Tm9kZU1hcC52YWx1ZXMoKSwgbnVsbCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGRlcGVuZGVuY2llc0ZpbGUgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgLy93cml0ZSB0byBmaWxlCiAgICAgICAgICAgICAgICB0cnkgKEZpbGVXcml0ZXIgZncgPSBuZXcgRmlsZVdyaXRlcihkZXBlbmRlbmNpZXNGaWxlKSkgewogICAgICAgICAgICAgICAgICAgIGZ3LmFwcGVuZChHcmFwaFV0aWxzLnRvRG90KGRlcGVuZGVuY3lOb2RlTWFwLnZhbHVlcygpLCAiQ29tcGxldGlvbkRlcHMiLCAiIikpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCBjb21wbGV0ZShTeW1ib2wgc3ltKSB0aHJvd3MgQ29tcGxldGlvbkZhaWx1cmUgewogICAgICAgICAgICBwdXNoKChDbGFzc1N5bWJvbClzeW0sIENvbXBsZXRpb25DYXVzZS5PVEhFUik7CiAgICAgICAgICAgIHBvcCgpOwogICAgICAgICAgICBzeW0uY29tcGxldGVyID0gdGhpczsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBib29sZWFuIGlzVGVybWluYWwoKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIENvbGxlY3Rpb248Tm9kZT4gZ2V0Tm9kZXMoKSB7CiAgICAgICAgICAgIHJldHVybiBkZXBlbmRlbmN5Tm9kZU1hcC52YWx1ZXMoKTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIFRoaXMgdmlzaXRvciBpcyB1c2VkIHRvIHBydW5lIHRoZSBncmFwaCBmcm9tIHNwdXJpb3VzIGVkZ2VzIHVzaW5nIHNvbWUgaGV1cmlzdGljcy4KICAgICAgICAgKi8KICAgICAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBQcnVuZVZpc2l0b3IgZXh0ZW5kcyBOb2RlVmlzaXRvcjxDbGFzc1N5bWJvbCwgTm9kZSwgVm9pZD4gewogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHVibGljIHZvaWQgdmlzaXROb2RlKE5vZGUgbm9kZSwgVm9pZCBhcmcpIHsKICAgICAgICAgICAgICAgIC8vZG8gbm90aGluZwogICAgICAgICAgICB9CgogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHVibGljIHZvaWQgdmlzaXREZXBlbmRlbmN5KEdyYXBoVXRpbHMuRGVwZW5kZW5jeUtpbmQgZGssIE5vZGUgZnJvbSwgTm9kZSB0bywgVm9pZCBhcmcpIHsKICAgICAgICAgICAgICAgIC8vaGV1cmlzdGljIC0gc2tpcHMgZGVwZW5kZW5jaWVzIHRoYXQgYXJlIGxpa2VseSB0byBiZSBmYWtlCiAgICAgICAgICAgICAgICBpZiAoZnJvbS5lcXVhbHModG8pKSB7CiAgICAgICAgICAgICAgICAgICAgdG8uZGVwc0J5S2luZC5nZXQoZGspLnJlbW92ZShmcm9tKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogVGhpcyB2aXNpdG9yIGlzIHVzZWQgdG8gcmV0YWluIG9ubHkgY29tcGxldGlvbiBub2RlcyB3aXRoIGdpdmVuIGtpbmQuCiAgICAgICAgICovCiAgICAgICAgcHJpdmF0ZSBjbGFzcyBGaWx0ZXJWaXNpdG9yIGV4dGVuZHMgTm9kZVZpc2l0b3I8Q2xhc3NTeW1ib2wsIE5vZGUsIFZvaWQ+IHsKCiAgICAgICAgICAgIENvbXBsZXRpb25Ob2RlLktpbmQgY2s7CgogICAgICAgICAgICBwcml2YXRlIEZpbHRlclZpc2l0b3IoQ29tcGxldGlvbk5vZGUuS2luZCBjaykgewogICAgICAgICAgICAgICAgdGhpcy5jayA9IGNrOwogICAgICAgICAgICB9CgogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHVibGljIHZvaWQgdmlzaXROb2RlKE5vZGUgbm9kZSwgVm9pZCBhcmcpIHsKICAgICAgICAgICAgICAgIGlmIChub2RlIGluc3RhbmNlb2YgQ29tcGxldGlvbk5vZGUpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoKChDb21wbGV0aW9uTm9kZSkgbm9kZSkuY2sgIT0gY2spIHsKICAgICAgICAgICAgICAgICAgICAgICAgZGVwZW5kZW5jeU5vZGVNYXAucmVtb3ZlKG5vZGUuZGF0YSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHVibGljIHZvaWQgdmlzaXREZXBlbmRlbmN5KEdyYXBoVXRpbHMuRGVwZW5kZW5jeUtpbmQgZGssIE5vZGUgZnJvbSwgTm9kZSB0bywgVm9pZCBhcmcpIHsKICAgICAgICAgICAgICAgIGlmICh0byBpbnN0YW5jZW9mIENvbXBsZXRpb25Ob2RlKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCgoQ29tcGxldGlvbk5vZGUpIHRvKS5jayAhPSBjaykgewogICAgICAgICAgICAgICAgICAgICAgICBmcm9tLmRlcHNCeUtpbmQuZ2V0KGRrKS5yZW1vdmUodG8pOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIER1bW15IGNsYXNzIHRvIGJlIHVzZWQgd2hlbiBkZXBlbmRlbmNpZXMgb3B0aW9ucyBhcmUgbm90IHNldC4gVGhpcyBrZWVwcwogICAgICogcGVyZm9ybWFuY2UgY29zdCBvZiBjYWxsaW5nIHB1c2gvcG9wIG1ldGhvZHMgZHVyaW5nIGNvbXBsZXRpb24gbWFyZ2luYWxseSBsb3cuCiAgICAgKi8KICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIER1bW15RGVwZW5kZW5jaWVzIGV4dGVuZHMgRGVwZW5kZW5jaWVzIHsKCiAgICAgICAgcHJpdmF0ZSBEdW1teURlcGVuZGVuY2llcyhDb250ZXh0IGNvbnRleHQpIHsKICAgICAgICAgICAgc3VwZXIoY29udGV4dCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCBwdXNoKENsYXNzU3ltYm9sIHMsIENvbXBsZXRpb25DYXVzZSBwaGFzZSkgewogICAgICAgICAgICAvL2RvIG5vdGhpbmcKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHBvcCgpIHsKICAgICAgICAgICAgLy9kbyBub3RoaW5nCiAgICAgICAgfQogICAgfQp9ClBLAwQKAAAIAAAGO6lKNRJRGrtpAAC7aQAANQAAAGNvbS9zdW4vdG9vbHMvamF2YWMvdXRpbC9SaWNoRGlhZ25vc3RpY0Zvcm1hdHRlci5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDA5LCAyMDE2LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuamF2YWMudXRpbDsKCmltcG9ydCBqYXZhLm5pby5maWxlLlBhdGg7CmltcG9ydCBqYXZhLnV0aWwuRW51bU1hcDsKaW1wb3J0IGphdmEudXRpbC5FbnVtU2V0OwppbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CmltcG9ydCBqYXZhLnV0aWwuTGlua2VkSGFzaE1hcDsKaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CmltcG9ydCBqYXZhLnV0aWwuTWFwOwoKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5QcmludGVyOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlN5bWJvbDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5TeW1ib2wuKjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5TeW10YWI7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuVHlwZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5UeXBlLio7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuVHlwZXM7CgppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5GbGFncy4qOwppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5UeXBlVGFnLio7CmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLktpbmRzLio7CmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLktpbmRzLktpbmQuKjsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuTGF5b3V0Q2hhcmFjdGVycy4qOwppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5SaWNoRGlhZ25vc3RpY0Zvcm1hdHRlci5SaWNoQ29uZmlndXJhdGlvbi4qOwoKLyoqCiAqIEEgcmljaCBkaWFnbm9zdGljIGZvcm1hdHRlciBpcyBhIGZvcm1hdHRlciB0aGF0IHByb3ZpZGVzIGJldHRlciBpbnRlZ3JhdGlvbgogKiB3aXRoIGphdmFjJ3MgdHlwZSBzeXN0ZW0uIEEgZGlhZ29zdGljIGlzIGZpcnN0IHByZXByb2Nlc3NlZCBpbiBvcmRlciB0byBrZWVwCiAqIHRyYWNrIG9mIGVhY2ggdHlwZXMvc3ltYm9scyBpbiBpdDsgYWZ0ZXIgdGhlc2UgaW5mb3JtYXRpb25zIGFyZSBjb2xsZWN0ZWQsCiAqIHRoZSBkaWFnbm9zdGljIGlzIHJlbmRlcmVkIHVzaW5nIGEgc3RhbmRhcmQgZm9ybWF0dGVyLCB3aG9zZSB0eXBlL3N5bWJvbCBwcmludGVyCiAqIGhhcyBiZWVuIHJlcGxhY2VkIGJ5IGEgbW9yZSByZWZpbmVkIHZlcnNpb24gcHJvdmlkZWQgYnkgdGhpcyByaWNoIGZvcm1hdHRlci4KICogVGhlIHJpY2ggZm9ybWF0dGVyIGN1cnJlbnRseSBlbmFibGVzIHRocmVlIGRpZmZlcmVudCBmZWF0dXJlczogKGkpIHNpbXBsZSBjbGFzcwogKiBuYW1lcyAtIHRoYXQgaXMgY2xhc3MgbmFtZXMgYXJlIGRpc3BsYXllZCB1c2VkIGEgbm9uIHF1YWxpZmllZCBuYW1lICh0aHVzCiAqIG9taXR0aW5nIHBhY2thZ2UgaW5mbykgd2hlbmV2ZXIgcG9zc2libGUgLSAoaWkpIHdoZXJlIGNsYXVzZSBsaXN0IC0gYSBsaXN0IG9mCiAqIGFkZGl0aW9uYWwgc3ViZGlhZ25vc3RpY3MgdGhhdCBwcm92aWRlIHNwZWNpZmljIGluZm8gYWJvdXQgdHlwZS12YXJpYWJsZXMsCiAqIGNhcHR1cmVkIHR5cGVzLCBpbnRlcnNlY3Rpb24gdHlwZXMgdGhhdCBvY2N1ciBpbiB0aGUgZGlhZ25vc3RpYyB0aGF0IGlzIHRvIGJlCiAqIGZvcm1hdHRlZCBhbmQgKGlpaSkgdHlwZS12YXJpYWJsZSBkaXNhbWJpZ3VhdGlvbiAtIHdoZW4gdGhlIGRpYWdub3N0aWMgcmVmZXJzCiAqIHRvIHR3byBkaWZmZXJlbnQgdHlwZS12YXJpYWJsZXMgd2l0aCB0aGUgc2FtZSBuYW1lLCB0aGVpciByZXByZXNlbnRhdGlvbiBpcwogKiBkaXNhbWJpZ3VhdGVkIGJ5IGFwcGVuZGluZyBhbiBpbmRleCB0byB0aGUgdHlwZSB2YXJpYWJsZSBuYW1lLgogKgogKiA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yCiAqIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj4KICovCnB1YmxpYyBjbGFzcyBSaWNoRGlhZ25vc3RpY0Zvcm1hdHRlciBleHRlbmRzCiAgICAgICAgRm9yd2FyZGluZ0RpYWdub3N0aWNGb3JtYXR0ZXI8SkNEaWFnbm9zdGljLCBBYnN0cmFjdERpYWdub3N0aWNGb3JtYXR0ZXI+IHsKCiAgICBmaW5hbCBTeW10YWIgc3ltczsKICAgIGZpbmFsIFR5cGVzIHR5cGVzOwogICAgZmluYWwgSkNEaWFnbm9zdGljLkZhY3RvcnkgZGlhZ3M7CiAgICBmaW5hbCBKYXZhY01lc3NhZ2VzIG1lc3NhZ2VzOwoKICAgIC8qIG5hbWUgc2ltcGxpZmllciB1c2VkIGJ5IHRoaXMgZm9ybWF0dGVyICovCiAgICBwcm90ZWN0ZWQgQ2xhc3NOYW1lU2ltcGxpZmllciBuYW1lU2ltcGxpZmllcjsKCiAgICAvKiB0eXBlL3N5bWJvbCBwcmludGVyIHVzZWQgYnkgdGhpcyBmb3JtYXR0ZXIgKi8KICAgIHByaXZhdGUgUmljaFByaW50ZXIgcHJpbnRlcjsKCiAgICAvKiBtYXAgZm9yIGtlZXBpbmcgdHJhY2sgb2YgYSB3aGVyZSBjbGF1c2UgYXNzb2NpYXRlZCB0byBhIGdpdmVuIHR5cGUgKi8KICAgIE1hcDxXaGVyZUNsYXVzZUtpbmQsIE1hcDxUeXBlLCBKQ0RpYWdub3N0aWM+PiB3aGVyZUNsYXVzZXM7CgogICAgLyoqIEdldCB0aGUgRGlhZ25vc3RpY0Zvcm1hdHRlciBpbnN0YW5jZSBmb3IgdGhpcyBjb250ZXh0LiAqLwogICAgcHVibGljIHN0YXRpYyBSaWNoRGlhZ25vc3RpY0Zvcm1hdHRlciBpbnN0YW5jZShDb250ZXh0IGNvbnRleHQpIHsKICAgICAgICBSaWNoRGlhZ25vc3RpY0Zvcm1hdHRlciBpbnN0YW5jZSA9IGNvbnRleHQuZ2V0KFJpY2hEaWFnbm9zdGljRm9ybWF0dGVyLmNsYXNzKTsKICAgICAgICBpZiAoaW5zdGFuY2UgPT0gbnVsbCkKICAgICAgICAgICAgaW5zdGFuY2UgPSBuZXcgUmljaERpYWdub3N0aWNGb3JtYXR0ZXIoY29udGV4dCk7CiAgICAgICAgcmV0dXJuIGluc3RhbmNlOwogICAgfQoKICAgIHByb3RlY3RlZCBSaWNoRGlhZ25vc3RpY0Zvcm1hdHRlcihDb250ZXh0IGNvbnRleHQpIHsKICAgICAgICBzdXBlcigoQWJzdHJhY3REaWFnbm9zdGljRm9ybWF0dGVyKUxvZy5pbnN0YW5jZShjb250ZXh0KS5nZXREaWFnbm9zdGljRm9ybWF0dGVyKCkpOwogICAgICAgIHNldFJpY2hQcmludGVyKG5ldyBSaWNoUHJpbnRlcigpKTsKICAgICAgICB0aGlzLnN5bXMgPSBTeW10YWIuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgdGhpcy5kaWFncyA9IEpDRGlhZ25vc3RpYy5GYWN0b3J5Lmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIHRoaXMudHlwZXMgPSBUeXBlcy5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICB0aGlzLm1lc3NhZ2VzID0gSmF2YWNNZXNzYWdlcy5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICB3aGVyZUNsYXVzZXMgPSBuZXcgRW51bU1hcDw+KFdoZXJlQ2xhdXNlS2luZC5jbGFzcyk7CiAgICAgICAgY29uZmlndXJhdGlvbiA9IG5ldyBSaWNoQ29uZmlndXJhdGlvbihPcHRpb25zLmluc3RhbmNlKGNvbnRleHQpLCBmb3JtYXR0ZXIpOwogICAgICAgIGZvciAoV2hlcmVDbGF1c2VLaW5kIGtpbmQgOiBXaGVyZUNsYXVzZUtpbmQudmFsdWVzKCkpCiAgICAgICAgICAgIHdoZXJlQ2xhdXNlcy5wdXQoa2luZCwgbmV3IExpbmtlZEhhc2hNYXA8VHlwZSwgSkNEaWFnbm9zdGljPigpKTsKICAgIH0KCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBTdHJpbmcgZm9ybWF0KEpDRGlhZ25vc3RpYyBkaWFnLCBMb2NhbGUgbCkgewogICAgICAgIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigpOwogICAgICAgIG5hbWVTaW1wbGlmaWVyID0gbmV3IENsYXNzTmFtZVNpbXBsaWZpZXIoKTsKICAgICAgICBmb3IgKFdoZXJlQ2xhdXNlS2luZCBraW5kIDogV2hlcmVDbGF1c2VLaW5kLnZhbHVlcygpKQogICAgICAgICAgICB3aGVyZUNsYXVzZXMuZ2V0KGtpbmQpLmNsZWFyKCk7CiAgICAgICAgcHJlcHJvY2Vzc0RpYWdub3N0aWMoZGlhZyk7CiAgICAgICAgc2IuYXBwZW5kKGZvcm1hdHRlci5mb3JtYXQoZGlhZywgbCkpOwogICAgICAgIGlmIChnZXRDb25maWd1cmF0aW9uKCkuaXNFbmFibGVkKFJpY2hGb3JtYXR0ZXJGZWF0dXJlLldIRVJFX0NMQVVTRVMpKSB7CiAgICAgICAgICAgIExpc3Q8SkNEaWFnbm9zdGljPiBjbGF1c2VzID0gZ2V0V2hlcmVDbGF1c2VzKCk7CiAgICAgICAgICAgIFN0cmluZyBpbmRlbnQgPSBmb3JtYXR0ZXIuaXNSYXcoKSA/ICIiIDoKICAgICAgICAgICAgICAgIGZvcm1hdHRlci5pbmRlbnRTdHJpbmcoRGV0YWlsc0luYyk7CiAgICAgICAgICAgIGZvciAoSkNEaWFnbm9zdGljIGQgOiBjbGF1c2VzKSB7CiAgICAgICAgICAgICAgICBTdHJpbmcgd2hlcmVDbGF1c2UgPSBmb3JtYXR0ZXIuZm9ybWF0KGQsIGwpOwogICAgICAgICAgICAgICAgaWYgKHdoZXJlQ2xhdXNlLmxlbmd0aCgpID4gMCkgewogICAgICAgICAgICAgICAgICAgIHNiLmFwcGVuZCgnXG4nICsgaW5kZW50ICsgd2hlcmVDbGF1c2UpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBzYi50b1N0cmluZygpOwogICAgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIFN0cmluZyBmb3JtYXRNZXNzYWdlKEpDRGlhZ25vc3RpYyBkaWFnLCBMb2NhbGUgbCkgewogICAgICAgIG5hbWVTaW1wbGlmaWVyID0gbmV3IENsYXNzTmFtZVNpbXBsaWZpZXIoKTsKICAgICAgICBwcmVwcm9jZXNzRGlhZ25vc3RpYyhkaWFnKTsKICAgICAgICByZXR1cm4gc3VwZXIuZm9ybWF0TWVzc2FnZShkaWFnLCBsKTsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgdGhlIHR5cGUvc3ltYm9sIHByaW50ZXIgdXNlZCBieSB0aGlzIGZvcm1hdHRlci4KICAgICAqIEBwYXJhbSBwcmludGVyIHRoZSByaWNoIHByaW50ZXIgdG8gYmUgc2V0CiAgICAgKi8KICAgIHByb3RlY3RlZCB2b2lkIHNldFJpY2hQcmludGVyKFJpY2hQcmludGVyIHByaW50ZXIpIHsKICAgICAgICB0aGlzLnByaW50ZXIgPSBwcmludGVyOwogICAgICAgIGZvcm1hdHRlci5zZXRQcmludGVyKHByaW50ZXIpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgdHlwZS9zeW1ib2wgcHJpbnRlciB1c2VkIGJ5IHRoaXMgZm9ybWF0dGVyLgogICAgICogQHJldHVybiB0eXBlL3N5bWJvbCByaWNoIHByaW50ZXIKICAgICAqLwogICAgcHJvdGVjdGVkIFJpY2hQcmludGVyIGdldFJpY2hQcmludGVyKCkgewogICAgICAgIHJldHVybiBwcmludGVyOwogICAgfQoKICAgIC8qKgogICAgICogUHJlcHJvY2VzcyBhIGdpdmVuIGRpYWdub3N0aWMgYnkgbG9va2luZyBib3RoIGludG8gaXRzIGFyZ3VtZW50cyBhbmQgaW50bwogICAgICogaXRzIHN1YmRpYWdub3N0aWNzIChpZiBhbnkpLiBUaGlzIHByZXByb2Nlc3NpbmcgaXMgcmVzcG9uc2libGUgZm9yCiAgICAgKiBnZW5lcmF0aW5nIGluZm8gY29ycmVzcG9uZGluZyB0byBmZWF0dXJlcyBsaWtlIHdoZXJlIGNsYXVzZXMsIG5hbWUKICAgICAqIHNpbXBsaWZpY2F0aW9uLCBldGMuCiAgICAgKgogICAgICogQHBhcmFtIGRpYWcgdGhlIGRpYWdub3N0aWMgdG8gYmUgcHJlcHJvY2Vzc2VkCiAgICAgKi8KICAgIHByb3RlY3RlZCB2b2lkIHByZXByb2Nlc3NEaWFnbm9zdGljKEpDRGlhZ25vc3RpYyBkaWFnKSB7CiAgICAgICAgZm9yIChPYmplY3QgbyA6IGRpYWcuZ2V0QXJncygpKSB7CiAgICAgICAgICAgIGlmIChvICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIHByZXByb2Nlc3NBcmd1bWVudChvKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoZGlhZy5pc011bHRpbGluZSgpKSB7CiAgICAgICAgICAgIGZvciAoSkNEaWFnbm9zdGljIGQgOiBkaWFnLmdldFN1YmRpYWdub3N0aWNzKCkpCiAgICAgICAgICAgICAgICBwcmVwcm9jZXNzRGlhZ25vc3RpYyhkKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBQcmVwcm9jZXNzIGEgZGlhZ25vc3RpYyBhcmd1bWVudC4gQSB0eXBlL3N5bWJvbCBhcmd1bWVudCBpcwogICAgICogcHJlcHJvY2Vzc2VkIGJ5IHNwZWNpYWxpemVkIHR5cGUvc3ltYm9sIHByZXByb2Nlc3NvcnMuCiAgICAgKgogICAgICogQHBhcmFtIGFyZyB0aGUgYXJndW1lbnQgdG8gYmUgdHJhbnNsYXRlZAogICAgICovCiAgICBwcm90ZWN0ZWQgdm9pZCBwcmVwcm9jZXNzQXJndW1lbnQoT2JqZWN0IGFyZykgewogICAgICAgIGlmIChhcmcgaW5zdGFuY2VvZiBUeXBlKSB7CiAgICAgICAgICAgIHByZXByb2Nlc3NUeXBlKChUeXBlKWFyZyk7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKGFyZyBpbnN0YW5jZW9mIFN5bWJvbCkgewogICAgICAgICAgICBwcmVwcm9jZXNzU3ltYm9sKChTeW1ib2wpYXJnKTsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAoYXJnIGluc3RhbmNlb2YgSkNEaWFnbm9zdGljKSB7CiAgICAgICAgICAgIHByZXByb2Nlc3NEaWFnbm9zdGljKChKQ0RpYWdub3N0aWMpYXJnKTsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAoYXJnIGluc3RhbmNlb2YgSXRlcmFibGU8Pz4gJiYgIShhcmcgaW5zdGFuY2VvZiBQYXRoKSkgewogICAgICAgICAgICBmb3IgKE9iamVjdCBvIDogKEl0ZXJhYmxlPD8+KWFyZykgewogICAgICAgICAgICAgICAgcHJlcHJvY2Vzc0FyZ3VtZW50KG8pOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQnVpbGQgYSBsaXN0IG9mIG11bHRpbGluZSBkaWFnbm9zdGljcyBjb250YWluaW5nIGRldGFpbGVkIGluZm8gYWJvdXQKICAgICAqIHR5cGUtdmFyaWFibGVzLCBjYXB0dXJlZCB0eXBlcywgYW5kIGludGVyc2VjdGlvbiB0eXBlcwogICAgICoKICAgICAqIEByZXR1cm4gd2hlcmUgY2xhdXNlIGxpc3QKICAgICAqLwogICAgcHJvdGVjdGVkIExpc3Q8SkNEaWFnbm9zdGljPiBnZXRXaGVyZUNsYXVzZXMoKSB7CiAgICAgICAgTGlzdDxKQ0RpYWdub3N0aWM+IGNsYXVzZXMgPSBMaXN0Lm5pbCgpOwogICAgICAgIGZvciAoV2hlcmVDbGF1c2VLaW5kIGtpbmQgOiBXaGVyZUNsYXVzZUtpbmQudmFsdWVzKCkpIHsKICAgICAgICAgICAgTGlzdDxKQ0RpYWdub3N0aWM+IGxpbmVzID0gTGlzdC5uaWwoKTsKICAgICAgICAgICAgZm9yIChNYXAuRW50cnk8VHlwZSwgSkNEaWFnbm9zdGljPiBlbnRyeSA6IHdoZXJlQ2xhdXNlcy5nZXQoa2luZCkuZW50cnlTZXQoKSkgewogICAgICAgICAgICAgICAgbGluZXMgPSBsaW5lcy5wcmVwZW5kKGVudHJ5LmdldFZhbHVlKCkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICghbGluZXMuaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgICBTdHJpbmcga2V5ID0ga2luZC5rZXkoKTsKICAgICAgICAgICAgICAgIGlmIChsaW5lcy5zaXplKCkgPiAxKQogICAgICAgICAgICAgICAgICAgIGtleSArPSAiLjEiOwogICAgICAgICAgICAgICAgSkNEaWFnbm9zdGljIGQgPSBkaWFncy5mcmFnbWVudChrZXksIHdoZXJlQ2xhdXNlcy5nZXQoa2luZCkua2V5U2V0KCkpOwogICAgICAgICAgICAgICAgZCA9IG5ldyBKQ0RpYWdub3N0aWMuTXVsdGlsaW5lRGlhZ25vc3RpYyhkLCBsaW5lcy5yZXZlcnNlKCkpOwogICAgICAgICAgICAgICAgY2xhdXNlcyA9IGNsYXVzZXMucHJlcGVuZChkKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gY2xhdXNlcy5yZXZlcnNlKCk7CiAgICB9CgogICAgcHJpdmF0ZSBpbnQgaW5kZXhPZihUeXBlIHR5cGUsIFdoZXJlQ2xhdXNlS2luZCBraW5kKSB7CiAgICAgICAgaW50IGluZGV4ID0gMTsKICAgICAgICBmb3IgKFR5cGUgdCA6IHdoZXJlQ2xhdXNlcy5nZXQoa2luZCkua2V5U2V0KCkpIHsKICAgICAgICAgICAgaWYgKHQudHN5bSA9PSB0eXBlLnRzeW0pIHsKICAgICAgICAgICAgICAgIHJldHVybiBpbmRleDsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoa2luZCAhPSBXaGVyZUNsYXVzZUtpbmQuVFlQRVZBUiB8fAogICAgICAgICAgICAgICAgICAgIHQudG9TdHJpbmcoKS5lcXVhbHModHlwZS50b1N0cmluZygpKSkgewogICAgICAgICAgICAgICAgaW5kZXgrKzsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gLTE7CiAgICB9CgogICAgcHJpdmF0ZSBib29sZWFuIHVuaXF1ZShUeXBlVmFyIHR5cGV2YXIpIHsKICAgICAgICB0eXBldmFyID0gKFR5cGVWYXIpIHR5cGV2YXIuc3RyaXBNZXRhZGF0YSgpOwoKICAgICAgICBpbnQgZm91bmQgPSAwOwogICAgICAgIGZvciAoVHlwZSB0IDogd2hlcmVDbGF1c2VzLmdldChXaGVyZUNsYXVzZUtpbmQuVFlQRVZBUikua2V5U2V0KCkpIHsKICAgICAgICAgICAgaWYgKHQuc3RyaXBNZXRhZGF0YSgpLnRvU3RyaW5nKCkuZXF1YWxzKHR5cGV2YXIudG9TdHJpbmcoKSkpIHsKICAgICAgICAgICAgICAgIGZvdW5kKys7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKGZvdW5kIDwgMSkKICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCJNaXNzaW5nIHR5cGUgdmFyaWFibGUgaW4gd2hlcmUgY2xhdXNlOiAiICsgdHlwZXZhcik7CiAgICAgICAgcmV0dXJuIGZvdW5kID09IDE7CiAgICB9CiAgICAvL3doZXJlCiAgICAvKioKICAgICAqIFRoaXMgZW51bSBkZWZpbmVzIGFsbCBwb3Nzc2libGUga2luZHMgb2Ygd2hlcmUgY2xhdXNlcyB0aGF0IGNhbiBiZQogICAgICogYXR0YWNoZWQgYnkgYSByaWNoIGRpYWdub3N0aWMgZm9ybWF0dGVyIHRvIGEgZ2l2ZW4gZGlhZ25vc3RpYwogICAgICovCiAgICBlbnVtIFdoZXJlQ2xhdXNlS2luZCB7CgogICAgICAgIC8qKiB3aGVyZSBjbGF1c2UgcmVnYXJkaW5nIGEgdHlwZSB2YXJpYWJsZSAqLwogICAgICAgIFRZUEVWQVIoIndoZXJlLmRlc2NyaXB0aW9uLnR5cGV2YXIiKSwKICAgICAgICAvKiogd2hlcmUgY2xhdXNlIHJlZ2FyZGluZyBhIGNhcHR1cmVkIHR5cGUgKi8KICAgICAgICBDQVBUVVJFRCgid2hlcmUuZGVzY3JpcHRpb24uY2FwdHVyZWQiKSwKICAgICAgICAvKiogd2hlcmUgY2xhdXNlIHJlZ2FyZGluZyBhbiBpbnRlcnNlY3Rpb24gdHlwZSAqLwogICAgICAgIElOVEVSU0VDVElPTigid2hlcmUuZGVzY3JpcHRpb24uaW50ZXJzZWN0aW9uIik7CgogICAgICAgIC8qKiByZXNvdXJjZSBrZXkgZm9yIHRoaXMgd2hlcmUgY2xhdXNlIGtpbmQgKi8KICAgICAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBrZXk7CgogICAgICAgIFdoZXJlQ2xhdXNlS2luZChTdHJpbmcga2V5KSB7CiAgICAgICAgICAgIHRoaXMua2V5ID0ga2V5OwogICAgICAgIH0KCiAgICAgICAgU3RyaW5nIGtleSgpIHsKICAgICAgICAgICAgcmV0dXJuIGtleTsKICAgICAgICB9CiAgICB9CgogICAgLy8gPGVkaXRvci1mb2xkIGRlZmF1bHRzdGF0ZT0iY29sbGFwc2VkIiBkZXNjPSJuYW1lIHNpbXBsaWZpZXIiPgogICAgLyoqCiAgICAgKiBBIG5hbWUgc2ltcGxpZmllciBrZWVwcyB0cmFjayBvZiBjbGFzcyBuYW1lcyB1c2FnZXMgaW4gb3JkZXIgdG8gZGV0ZXJtaW5lCiAgICAgKiB3aGV0aGVyIGEgY2xhc3MgbmFtZSBjYW4gYmUgY29tcGFjdGVkIG9yIG5vdC4gU2hvcnQgbmFtZXMgYXJlIG5vdCB1c2VkCiAgICAgKiBpZiBhIGNvbmZsaWN0IGlzIGRldGVjdGVkLCBlLmcuIHdoZW4gdHdvIGNsYXNzZXMgd2l0aCB0aGUgc2FtZSBzaW1wbGUKICAgICAqIG5hbWUgYmVsb25nIHRvIGRpZmZlcmVudCBwYWNrYWdlcyAtIGluIHRoaXMgY2FzZSB0aGUgZm9ybWF0dGVyIHJldmVydHMKICAgICAqIHRvIGZ1bGxuYW1lcyBhcyBjb21wYWN0IG5hbWVzIG1pZ2h0IGxlYWQgdG8gYSBjb25mdXNpbmcgZGlhZ25vc3RpYy4KICAgICAqLwogICAgcHJvdGVjdGVkIGNsYXNzIENsYXNzTmFtZVNpbXBsaWZpZXIgewoKICAgICAgICAvKiB0YWJsZSBmb3Iga2VlcGluZyB0cmFjayBvZiBhbGwgc2hvcnQgbmFtZSB1c2FnZXMgKi8KICAgICAgICBNYXA8TmFtZSwgTGlzdDxTeW1ib2w+PiBuYW1lQ2xhc2hlcyA9IG5ldyBIYXNoTWFwPD4oKTsKCiAgICAgICAgLyoqCiAgICAgICAgICogQWRkIGEgbmFtZSB1c2FnZSB0byB0aGUgc2ltcGxpZmllcidzIGludGVybmFsIGNhY2hlCiAgICAgICAgICovCiAgICAgICAgcHJvdGVjdGVkIHZvaWQgYWRkVXNhZ2UoU3ltYm9sIHN5bSkgewogICAgICAgICAgICBOYW1lIG4gPSBzeW0uZ2V0U2ltcGxlTmFtZSgpOwogICAgICAgICAgICBMaXN0PFN5bWJvbD4gY29uZmxpY3RzID0gbmFtZUNsYXNoZXMuZ2V0KG4pOwogICAgICAgICAgICBpZiAoY29uZmxpY3RzID09IG51bGwpIHsKICAgICAgICAgICAgICAgIGNvbmZsaWN0cyA9IExpc3QubmlsKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCFjb25mbGljdHMuY29udGFpbnMoc3ltKSkKICAgICAgICAgICAgICAgIG5hbWVDbGFzaGVzLnB1dChuLCBjb25mbGljdHMuYXBwZW5kKHN5bSkpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIFN0cmluZyBzaW1wbGlmeShTeW1ib2wgcykgewogICAgICAgICAgICBTdHJpbmcgbmFtZSA9IHMuZ2V0UXVhbGlmaWVkTmFtZSgpLnRvU3RyaW5nKCk7CiAgICAgICAgICAgIGlmICghcy50eXBlLmlzQ29tcG91bmQoKSAmJiAhcy50eXBlLmlzUHJpbWl0aXZlKCkpIHsKICAgICAgICAgICAgICAgIExpc3Q8U3ltYm9sPiBjb25mbGljdHMgPSBuYW1lQ2xhc2hlcy5nZXQocy5nZXRTaW1wbGVOYW1lKCkpOwogICAgICAgICAgICAgICAgaWYgKGNvbmZsaWN0cyA9PSBudWxsIHx8CiAgICAgICAgICAgICAgICAgICAgKGNvbmZsaWN0cy5zaXplKCkgPT0gMSAmJgogICAgICAgICAgICAgICAgICAgIGNvbmZsaWN0cy5jb250YWlucyhzKSkpIHsKICAgICAgICAgICAgICAgICAgICBMaXN0PE5hbWU+IGwgPSBMaXN0Lm5pbCgpOwogICAgICAgICAgICAgICAgICAgIFN5bWJvbCBzMiA9IHM7CiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHMyLnR5cGUuaGFzVGFnKENMQVNTKSAmJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgczIudHlwZS5nZXRFbmNsb3NpbmdUeXBlKCkuaGFzVGFnKENMQVNTKSAmJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgczIub3duZXIua2luZCA9PSBUWVApIHsKICAgICAgICAgICAgICAgICAgICAgICAgbCA9IGwucHJlcGVuZChzMi5nZXRTaW1wbGVOYW1lKCkpOwogICAgICAgICAgICAgICAgICAgICAgICBzMiA9IHMyLm93bmVyOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBsID0gbC5wcmVwZW5kKHMyLmdldFNpbXBsZU5hbWUoKSk7CiAgICAgICAgICAgICAgICAgICAgU3RyaW5nQnVpbGRlciBidWYgPSBuZXcgU3RyaW5nQnVpbGRlcigpOwogICAgICAgICAgICAgICAgICAgIFN0cmluZyBzZXAgPSAiIjsKICAgICAgICAgICAgICAgICAgICBmb3IgKE5hbWUgbjIgOiBsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQoc2VwKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnVmLmFwcGVuZChuMik7CiAgICAgICAgICAgICAgICAgICAgICAgIHNlcCA9ICIuIjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgbmFtZSA9IGJ1Zi50b1N0cmluZygpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBuYW1lOwogICAgICAgIH0KICAgIH0KICAgIC8vIDwvZWRpdG9yLWZvbGQ+CgogICAgLy8gPGVkaXRvci1mb2xkIGRlZmF1bHRzdGF0ZT0iY29sbGFwc2VkIiBkZXNjPSJyaWNoIHByaW50ZXIiPgogICAgLyoqCiAgICAgKiBFbmhhbmNlZCB0eXBlL3N5bWJvbCBwcmludGVyIHRoYXQgcHJvdmlkZXMgc3VwcG9ydCBmb3IgZmVhdHVyZXMgbGlrZSBzaW1wbGUgbmFtZXMKICAgICAqIGFuZCB0eXBlIHZhcmlhYmxlIGRpc2FtYmlndWF0aW9uLiBUaGlzIGVucmljaGVkIHByaW50ZXIgZXhwbG9pdHMgdGhlIGluZm8KICAgICAqIGRpc2NvdmVyZWQgZHVyaW5nIHR5cGUvc3ltYm9sIHByZXByb2Nlc3NpbmcuIFRoaXMgcHJpbnRlciBpcyBzZXQgb24gdGhlIGRlbGVnYXRlCiAgICAgKiBmb3JtYXR0ZXIgc28gdGhhdCByaWNoIHR5cGUvc3ltYm9sIGluZm8gY2FuIGJlIHByb3Blcmx5IHJlbmRlcmVkLgogICAgICovCiAgICBwcm90ZWN0ZWQgY2xhc3MgUmljaFByaW50ZXIgZXh0ZW5kcyBQcmludGVyIHsKCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFN0cmluZyBsb2NhbGl6ZShMb2NhbGUgbG9jYWxlLCBTdHJpbmcga2V5LCBPYmplY3QuLi4gYXJncykgewogICAgICAgICAgICByZXR1cm4gZm9ybWF0dGVyLmxvY2FsaXplKGxvY2FsZSwga2V5LCBhcmdzKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBTdHJpbmcgY2FwdHVyZWRWYXJJZChDYXB0dXJlZFR5cGUgdCwgTG9jYWxlIGxvY2FsZSkgewogICAgICAgICAgICByZXR1cm4gaW5kZXhPZih0LCBXaGVyZUNsYXVzZUtpbmQuQ0FQVFVSRUQpICsgIiI7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgU3RyaW5nIHZpc2l0VHlwZShUeXBlIHQsIExvY2FsZSBsb2NhbGUpIHsKICAgICAgICAgICAgU3RyaW5nIHMgPSBzdXBlci52aXNpdFR5cGUodCwgbG9jYWxlKTsKICAgICAgICAgICAgaWYgKHQgPT0gc3ltcy5ib3RUeXBlKQogICAgICAgICAgICAgICAgcyA9IGxvY2FsaXplKGxvY2FsZSwgImNvbXBpbGVyLm1pc2MudHlwZS5udWxsIik7CiAgICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFN0cmluZyB2aXNpdENhcHR1cmVkVHlwZShDYXB0dXJlZFR5cGUgdCwgTG9jYWxlIGxvY2FsZSkgewogICAgICAgICAgICBpZiAoZ2V0Q29uZmlndXJhdGlvbigpLmlzRW5hYmxlZChSaWNoRm9ybWF0dGVyRmVhdHVyZS5XSEVSRV9DTEFVU0VTKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGxvY2FsaXplKGxvY2FsZSwKICAgICAgICAgICAgICAgICAgICAiY29tcGlsZXIubWlzYy5jYXB0dXJlZC50eXBlIiwKICAgICAgICAgICAgICAgICAgICBpbmRleE9mKHQsIFdoZXJlQ2xhdXNlS2luZC5DQVBUVVJFRCkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHJldHVybiBzdXBlci52aXNpdENhcHR1cmVkVHlwZSh0LCBsb2NhbGUpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFN0cmluZyB2aXNpdENsYXNzVHlwZShDbGFzc1R5cGUgdCwgTG9jYWxlIGxvY2FsZSkgewogICAgICAgICAgICBpZiAodC5pc0NvbXBvdW5kKCkgJiYKICAgICAgICAgICAgICAgICAgICBnZXRDb25maWd1cmF0aW9uKCkuaXNFbmFibGVkKFJpY2hGb3JtYXR0ZXJGZWF0dXJlLldIRVJFX0NMQVVTRVMpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gbG9jYWxpemUobG9jYWxlLAogICAgICAgICAgICAgICAgICAgICAgICAiY29tcGlsZXIubWlzYy5pbnRlcnNlY3Rpb24udHlwZSIsCiAgICAgICAgICAgICAgICAgICAgICAgIGluZGV4T2YodCwgV2hlcmVDbGF1c2VLaW5kLklOVEVSU0VDVElPTikpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHJldHVybiBzdXBlci52aXNpdENsYXNzVHlwZSh0LCBsb2NhbGUpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHJvdGVjdGVkIFN0cmluZyBjbGFzc05hbWUoQ2xhc3NUeXBlIHQsIGJvb2xlYW4gbG9uZ2Zvcm0sIExvY2FsZSBsb2NhbGUpIHsKICAgICAgICAgICAgU3ltYm9sIHN5bSA9IHQudHN5bTsKICAgICAgICAgICAgaWYgKHN5bS5uYW1lLmxlbmd0aCgpID09IDAgfHwKICAgICAgICAgICAgICAgICAgICAhZ2V0Q29uZmlndXJhdGlvbigpLmlzRW5hYmxlZChSaWNoRm9ybWF0dGVyRmVhdHVyZS5TSU1QTEVfTkFNRVMpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gc3VwZXIuY2xhc3NOYW1lKHQsIGxvbmdmb3JtLCBsb2NhbGUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKGxvbmdmb3JtKQogICAgICAgICAgICAgICAgcmV0dXJuIG5hbWVTaW1wbGlmaWVyLnNpbXBsaWZ5KHN5bSkudG9TdHJpbmcoKTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgcmV0dXJuIHN5bS5uYW1lLnRvU3RyaW5nKCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgU3RyaW5nIHZpc2l0VHlwZVZhcihUeXBlVmFyIHQsIExvY2FsZSBsb2NhbGUpIHsKICAgICAgICAgICAgaWYgKHVuaXF1ZSh0KSB8fAogICAgICAgICAgICAgICAgICAgICFnZXRDb25maWd1cmF0aW9uKCkuaXNFbmFibGVkKFJpY2hGb3JtYXR0ZXJGZWF0dXJlLlVOSVFVRV9UWVBFVkFSX05BTUVTKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIHQudG9TdHJpbmcoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIHJldHVybiBsb2NhbGl6ZShsb2NhbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICJjb21waWxlci5taXNjLnR5cGUudmFyIiwKICAgICAgICAgICAgICAgICAgICAgICAgdC50b1N0cmluZygpLCBpbmRleE9mKHQsIFdoZXJlQ2xhdXNlS2luZC5UWVBFVkFSKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBTdHJpbmcgdmlzaXRDbGFzc1N5bWJvbChDbGFzc1N5bWJvbCBzLCBMb2NhbGUgbG9jYWxlKSB7CiAgICAgICAgICAgIGlmIChzLnR5cGUuaXNDb21wb3VuZCgpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdmlzaXQocy50eXBlLCBsb2NhbGUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIFN0cmluZyBuYW1lID0gbmFtZVNpbXBsaWZpZXIuc2ltcGxpZnkocyk7CiAgICAgICAgICAgIGlmIChuYW1lLmxlbmd0aCgpID09IDAgfHwKICAgICAgICAgICAgICAgICAgICAhZ2V0Q29uZmlndXJhdGlvbigpLmlzRW5hYmxlZChSaWNoRm9ybWF0dGVyRmVhdHVyZS5TSU1QTEVfTkFNRVMpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gc3VwZXIudmlzaXRDbGFzc1N5bWJvbChzLCBsb2NhbGUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgcmV0dXJuIG5hbWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBTdHJpbmcgdmlzaXRNZXRob2RTeW1ib2woTWV0aG9kU3ltYm9sIHMsIExvY2FsZSBsb2NhbGUpIHsKICAgICAgICAgICAgU3RyaW5nIG93bmVyTmFtZSA9IHZpc2l0KHMub3duZXIsIGxvY2FsZSk7CiAgICAgICAgICAgIGlmIChzLmlzU3RhdGljT3JJbnN0YW5jZUluaXQoKSkgewogICAgICAgICAgICAgICByZXR1cm4gb3duZXJOYW1lOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgU3RyaW5nIG1zID0gKHMubmFtZSA9PSBzLm5hbWUudGFibGUubmFtZXMuaW5pdCkKICAgICAgICAgICAgICAgICAgICA/IG93bmVyTmFtZQogICAgICAgICAgICAgICAgICAgIDogcy5uYW1lLnRvU3RyaW5nKCk7CiAgICAgICAgICAgICAgICBpZiAocy50eXBlICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICBpZiAocy50eXBlLmhhc1RhZyhGT1JBTEwpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIG1zID0gIjwiICsgdmlzaXRUeXBlcyhzLnR5cGUuZ2V0VHlwZUFyZ3VtZW50cygpLCBsb2NhbGUpICsgIj4iICsgbXM7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIG1zICs9ICIoIiArIHByaW50TWV0aG9kQXJncygKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHMudHlwZS5nZXRQYXJhbWV0ZXJUeXBlcygpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKHMuZmxhZ3MoKSAmIFZBUkFSR1MpICE9IDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2NhbGUpICsgIikiOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIG1zOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgLy8gPC9lZGl0b3ItZm9sZD4KCiAgICAvLyA8ZWRpdG9yLWZvbGQgZGVmYXVsdHN0YXRlPSJjb2xsYXBzZWQiIGRlc2M9InR5cGUgc2Nhbm5lciI+CiAgICAvKioKICAgICAqIFByZXByb2Nlc3MgYSBnaXZlbiB0eXBlIGxvb2tpbmcgZm9yIChpKSBhZGRpdGlvbmFsIGluZm8gKHdoZXJlIGNsYXVzZXMpIHRvIGJlCiAgICAgKiBhZGRlZCB0byB0aGUgbWFpbiBkaWFnbm9zdGljIChpaSkgbmFtZXMgdG8gYmUgY29tcGFjdGVkLgogICAgICovCiAgICBwcm90ZWN0ZWQgdm9pZCBwcmVwcm9jZXNzVHlwZShUeXBlIHQpIHsKICAgICAgICB0eXBlUHJlcHJvY2Vzc29yLnZpc2l0KHQpOwogICAgfQogICAgLy93aGVyZQogICAgcHJvdGVjdGVkIFR5cGVzLlVuYXJ5VmlzaXRvcjxWb2lkPiB0eXBlUHJlcHJvY2Vzc29yID0KICAgICAgICAgICAgbmV3IFR5cGVzLlVuYXJ5VmlzaXRvcjxWb2lkPigpIHsKCiAgICAgICAgcHVibGljIFZvaWQgdmlzaXQoTGlzdDxUeXBlPiB0cykgewogICAgICAgICAgICBmb3IgKFR5cGUgdCA6IHRzKQogICAgICAgICAgICAgICAgdmlzaXQodCk7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFZvaWQgdmlzaXRGb3JBbGwoRm9yQWxsIHQsIFZvaWQgaWdub3JlZCkgewogICAgICAgICAgICB2aXNpdCh0LnR2YXJzKTsKICAgICAgICAgICAgdmlzaXQodC5xdHlwZSk7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFZvaWQgdmlzaXRNZXRob2RUeXBlKE1ldGhvZFR5cGUgdCwgVm9pZCBpZ25vcmVkKSB7CiAgICAgICAgICAgIHZpc2l0KHQuYXJndHlwZXMpOwogICAgICAgICAgICB2aXNpdCh0LnJlc3R5cGUpOwogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBWb2lkIHZpc2l0RXJyb3JUeXBlKEVycm9yVHlwZSB0LCBWb2lkIGlnbm9yZWQpIHsKICAgICAgICAgICAgVHlwZSBvdCA9IHQuZ2V0T3JpZ2luYWxUeXBlKCk7CiAgICAgICAgICAgIGlmIChvdCAhPSBudWxsKQogICAgICAgICAgICAgICAgdmlzaXQob3QpOwogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBWb2lkIHZpc2l0QXJyYXlUeXBlKEFycmF5VHlwZSB0LCBWb2lkIGlnbm9yZWQpIHsKICAgICAgICAgICAgdmlzaXQodC5lbGVtdHlwZSk7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFZvaWQgdmlzaXRXaWxkY2FyZFR5cGUoV2lsZGNhcmRUeXBlIHQsIFZvaWQgaWdub3JlZCkgewogICAgICAgICAgICB2aXNpdCh0LnR5cGUpOwogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBWb2lkIHZpc2l0VHlwZShUeXBlIHQsIFZvaWQgaWdub3JlZCkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBWb2lkIHZpc2l0Q2FwdHVyZWRUeXBlKENhcHR1cmVkVHlwZSB0LCBWb2lkIGlnbm9yZWQpIHsKICAgICAgICAgICAgaWYgKGluZGV4T2YodCwgV2hlcmVDbGF1c2VLaW5kLkNBUFRVUkVEKSA9PSAtMSkgewogICAgICAgICAgICAgICAgU3RyaW5nIHN1ZmZpeCA9IHQubG93ZXIgPT0gc3ltcy5ib3RUeXBlID8gIi4xIiA6ICIiOwogICAgICAgICAgICAgICAgSkNEaWFnbm9zdGljIGQgPSBkaWFncy5mcmFnbWVudCgid2hlcmUuY2FwdHVyZWQiKyBzdWZmaXgsIHQsIHQuYm91bmQsIHQubG93ZXIsIHQud2lsZGNhcmQpOwogICAgICAgICAgICAgICAgd2hlcmVDbGF1c2VzLmdldChXaGVyZUNsYXVzZUtpbmQuQ0FQVFVSRUQpLnB1dCh0LCBkKTsKICAgICAgICAgICAgICAgIHZpc2l0KHQud2lsZGNhcmQpOwogICAgICAgICAgICAgICAgdmlzaXQodC5sb3dlcik7CiAgICAgICAgICAgICAgICB2aXNpdCh0LmJvdW5kKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBWb2lkIHZpc2l0Q2xhc3NUeXBlKENsYXNzVHlwZSB0LCBWb2lkIGlnbm9yZWQpIHsKICAgICAgICAgICAgaWYgKHQuaXNDb21wb3VuZCgpKSB7CiAgICAgICAgICAgICAgICBpZiAoaW5kZXhPZih0LCBXaGVyZUNsYXVzZUtpbmQuSU5URVJTRUNUSU9OKSA9PSAtMSkgewogICAgICAgICAgICAgICAgICAgIFR5cGUgc3VwZXJ0eXBlID0gdHlwZXMuc3VwZXJ0eXBlKHQpOwogICAgICAgICAgICAgICAgICAgIExpc3Q8VHlwZT4gaW50ZXJmYWNlcyA9IHR5cGVzLmludGVyZmFjZXModCk7CiAgICAgICAgICAgICAgICAgICAgSkNEaWFnbm9zdGljIGQgPSBkaWFncy5mcmFnbWVudCgid2hlcmUuaW50ZXJzZWN0aW9uIiwgdCwgaW50ZXJmYWNlcy5wcmVwZW5kKHN1cGVydHlwZSkpOwogICAgICAgICAgICAgICAgICAgIHdoZXJlQ2xhdXNlcy5nZXQoV2hlcmVDbGF1c2VLaW5kLklOVEVSU0VDVElPTikucHV0KHQsIGQpOwogICAgICAgICAgICAgICAgICAgIHZpc2l0KHN1cGVydHlwZSk7CiAgICAgICAgICAgICAgICAgICAgdmlzaXQoaW50ZXJmYWNlcyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSBpZiAodC50c3ltLm5hbWUuaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgICAvL2Fub24gY2xhc3MKICAgICAgICAgICAgICAgIENsYXNzVHlwZSBub3JtID0gKENsYXNzVHlwZSkgdC50c3ltLnR5cGU7CiAgICAgICAgICAgICAgICBpZiAobm9ybSAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKG5vcm0uaW50ZXJmYWNlc19maWVsZCAhPSBudWxsICYmIG5vcm0uaW50ZXJmYWNlc19maWVsZC5ub25FbXB0eSgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZpc2l0KG5vcm0uaW50ZXJmYWNlc19maWVsZC5oZWFkKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICB2aXNpdChub3JtLnN1cGVydHlwZV9maWVsZCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIG5hbWVTaW1wbGlmaWVyLmFkZFVzYWdlKHQudHN5bSk7CiAgICAgICAgICAgIHZpc2l0KHQuZ2V0VHlwZUFyZ3VtZW50cygpKTsKICAgICAgICAgICAgaWYgKHQuZ2V0RW5jbG9zaW5nVHlwZSgpICE9IFR5cGUubm9UeXBlKQogICAgICAgICAgICAgICAgdmlzaXQodC5nZXRFbmNsb3NpbmdUeXBlKCkpOwogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBWb2lkIHZpc2l0VHlwZVZhcihUeXBlVmFyIHQsIFZvaWQgaWdub3JlZCkgewogICAgICAgICAgICB0ID0gKFR5cGVWYXIpdC5zdHJpcE1ldGFkYXRhSWZOZWVkZWQoKTsKICAgICAgICAgICAgaWYgKGluZGV4T2YodCwgV2hlcmVDbGF1c2VLaW5kLlRZUEVWQVIpID09IC0xKSB7CiAgICAgICAgICAgICAgICAvL2FjY2VzcyB0aGUgYm91bmQgdHlwZSBhbmQgc2tpcCBlcnJvciB0eXBlcwogICAgICAgICAgICAgICAgVHlwZSBib3VuZCA9IHQuYm91bmQ7CiAgICAgICAgICAgICAgICB3aGlsZSAoKGJvdW5kIGluc3RhbmNlb2YgRXJyb3JUeXBlKSkKICAgICAgICAgICAgICAgICAgICBib3VuZCA9ICgoRXJyb3JUeXBlKWJvdW5kKS5nZXRPcmlnaW5hbFR5cGUoKTsKICAgICAgICAgICAgICAgIC8vcmV0cmlldmUgdGhlIGJvdW5kIGxpc3QgLSBpZiB0aGUgdHlwZSB2YXJpYWJsZQogICAgICAgICAgICAgICAgLy9oYXMgbm90IGJlZW4gYXR0cmlidXRlZCB0aGUgYm91bmQgaXMgbm90IHNldAogICAgICAgICAgICAgICAgTGlzdDxUeXBlPiBib3VuZHMgPSAoYm91bmQgIT0gbnVsbCkgJiYKICAgICAgICAgICAgICAgICAgICAgICAgKGJvdW5kLmhhc1RhZyhDTEFTUykgfHwgYm91bmQuaGFzVGFnKFRZUEVWQVIpKSA/CiAgICAgICAgICAgICAgICAgICAgdHlwZXMuZ2V0Qm91bmRzKHQpIDoKICAgICAgICAgICAgICAgICAgICBMaXN0Lm5pbCgpOwoKICAgICAgICAgICAgICAgIG5hbWVTaW1wbGlmaWVyLmFkZFVzYWdlKHQudHN5bSk7CgogICAgICAgICAgICAgICAgYm9vbGVhbiBib3VuZEVycm9uZW91cyA9IGJvdW5kcy5oZWFkID09IG51bGwgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib3VuZHMuaGVhZC5oYXNUYWcoTk9ORSkgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib3VuZHMuaGVhZC5oYXNUYWcoRVJST1IpOwoKICAgICAgICAgICAgICAgIGlmICgodC50c3ltLmZsYWdzKCkgJiBTWU5USEVUSUMpID09IDApIHsKICAgICAgICAgICAgICAgICAgICAvL3RoaXMgaXMgYSB0cnVlIHR5cGV2YXIKICAgICAgICAgICAgICAgICAgICBKQ0RpYWdub3N0aWMgZCA9IGRpYWdzLmZyYWdtZW50KCJ3aGVyZS50eXBldmFyIiArCiAgICAgICAgICAgICAgICAgICAgICAgIChib3VuZEVycm9uZW91cyA/ICIuMSIgOiAiIiksIHQsIGJvdW5kcywKICAgICAgICAgICAgICAgICAgICAgICAga2luZE5hbWUodC50c3ltLmxvY2F0aW9uKCkpLCB0LnRzeW0ubG9jYXRpb24oKSk7CiAgICAgICAgICAgICAgICAgICAgd2hlcmVDbGF1c2VzLmdldChXaGVyZUNsYXVzZUtpbmQuVFlQRVZBUikucHV0KHQsIGQpOwogICAgICAgICAgICAgICAgICAgIHN5bWJvbFByZXByb2Nlc3Nvci52aXNpdCh0LnRzeW0ubG9jYXRpb24oKSwgbnVsbCk7CiAgICAgICAgICAgICAgICAgICAgdmlzaXQoYm91bmRzKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgQXNzZXJ0LmNoZWNrKCFib3VuZEVycm9uZW91cyk7CiAgICAgICAgICAgICAgICAgICAgLy90aGlzIGlzIGEgZnJlc2ggKHN5bnRoZXRpYykgdHZhcgogICAgICAgICAgICAgICAgICAgIEpDRGlhZ25vc3RpYyBkID0gZGlhZ3MuZnJhZ21lbnQoIndoZXJlLmZyZXNoLnR5cGV2YXIiLCB0LCBib3VuZHMpOwogICAgICAgICAgICAgICAgICAgIHdoZXJlQ2xhdXNlcy5nZXQoV2hlcmVDbGF1c2VLaW5kLlRZUEVWQVIpLnB1dCh0LCBkKTsKICAgICAgICAgICAgICAgICAgICB2aXNpdChib3VuZHMpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICB9OwogICAgLy8gPC9lZGl0b3ItZm9sZD4KCiAgICAvLyA8ZWRpdG9yLWZvbGQgZGVmYXVsdHN0YXRlPSJjb2xsYXBzZWQiIGRlc2M9InN5bWJvbCBzY2FubmVyIj4KICAgIC8qKgogICAgICogUHJlcHJvY2VzcyBhIGdpdmVuIHN5bWJvbCBsb29raW5nIGZvciAoaSkgYWRkaXRpb25hbCBpbmZvICh3aGVyZSBjbGF1c2VzKSB0byBiZQogICAgICogYWRkZWQgdG8gdGhlIG1haW4gZGlhZ25vc3RpYyAoaWkpIG5hbWVzIHRvIGJlIGNvbXBhY3RlZAogICAgICovCiAgICBwcm90ZWN0ZWQgdm9pZCBwcmVwcm9jZXNzU3ltYm9sKFN5bWJvbCBzKSB7CiAgICAgICAgc3ltYm9sUHJlcHJvY2Vzc29yLnZpc2l0KHMsIG51bGwpOwogICAgfQogICAgLy93aGVyZQogICAgcHJvdGVjdGVkIFR5cGVzLkRlZmF1bHRTeW1ib2xWaXNpdG9yPFZvaWQsIFZvaWQ+IHN5bWJvbFByZXByb2Nlc3NvciA9CiAgICAgICAgICAgIG5ldyBUeXBlcy5EZWZhdWx0U3ltYm9sVmlzaXRvcjxWb2lkLCBWb2lkPigpIHsKCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFZvaWQgdmlzaXRDbGFzc1N5bWJvbChDbGFzc1N5bWJvbCBzLCBWb2lkIGlnbm9yZWQpIHsKICAgICAgICAgICAgaWYgKHMudHlwZS5pc0NvbXBvdW5kKCkpIHsKICAgICAgICAgICAgICAgIHR5cGVQcmVwcm9jZXNzb3IudmlzaXQocy50eXBlKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIG5hbWVTaW1wbGlmaWVyLmFkZFVzYWdlKHMpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFZvaWQgdmlzaXRTeW1ib2woU3ltYm9sIHMsIFZvaWQgaWdub3JlZCkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBWb2lkIHZpc2l0TWV0aG9kU3ltYm9sKE1ldGhvZFN5bWJvbCBzLCBWb2lkIGlnbm9yZWQpIHsKICAgICAgICAgICAgdmlzaXQocy5vd25lciwgbnVsbCk7CiAgICAgICAgICAgIGlmIChzLnR5cGUgIT0gbnVsbCkKICAgICAgICAgICAgICAgIHR5cGVQcmVwcm9jZXNzb3IudmlzaXQocy50eXBlKTsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgfTsKICAgIC8vIDwvZWRpdG9yLWZvbGQ+CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgUmljaENvbmZpZ3VyYXRpb24gZ2V0Q29uZmlndXJhdGlvbigpIHsKICAgICAgICAvL3RoZSBmb2xsb3dpbmcgY2FzdCBpcyBhbHdheXMgc2FmZSAtIHNlZSBpbml0CiAgICAgICAgcmV0dXJuIChSaWNoQ29uZmlndXJhdGlvbiljb25maWd1cmF0aW9uOwogICAgfQoKICAgIC8qKgogICAgICogQ29uZmlndXJhdGlvbiBvYmplY3QgcHJvdmlkZWQgYnkgdGhlIHJpY2ggZm9ybWF0dGVyLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIFJpY2hDb25maWd1cmF0aW9uIGV4dGVuZHMgRm9yd2FyZGluZ0RpYWdub3N0aWNGb3JtYXR0ZXIuRm9yd2FyZGluZ0NvbmZpZ3VyYXRpb24gewoKICAgICAgICAvKiogc2V0IG9mIGVuYWJsZWQgcmljaCBmb3JtYXR0ZXIncyBmZWF0dXJlcyAqLwogICAgICAgIHByb3RlY3RlZCBqYXZhLnV0aWwuRW51bVNldDxSaWNoRm9ybWF0dGVyRmVhdHVyZT4gZmVhdHVyZXM7CgogICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJmYWxsdGhyb3VnaCIpCiAgICAgICAgcHVibGljIFJpY2hDb25maWd1cmF0aW9uKE9wdGlvbnMgb3B0aW9ucywgQWJzdHJhY3REaWFnbm9zdGljRm9ybWF0dGVyIGZvcm1hdHRlcikgewogICAgICAgICAgICBzdXBlcihmb3JtYXR0ZXIuZ2V0Q29uZmlndXJhdGlvbigpKTsKICAgICAgICAgICAgZmVhdHVyZXMgPSBmb3JtYXR0ZXIuaXNSYXcoKSA/IEVudW1TZXQubm9uZU9mKFJpY2hGb3JtYXR0ZXJGZWF0dXJlLmNsYXNzKSA6CiAgICAgICAgICAgICAgICBFbnVtU2V0Lm9mKFJpY2hGb3JtYXR0ZXJGZWF0dXJlLlNJTVBMRV9OQU1FUywKICAgICAgICAgICAgICAgICAgICBSaWNoRm9ybWF0dGVyRmVhdHVyZS5XSEVSRV9DTEFVU0VTLAogICAgICAgICAgICAgICAgICAgIFJpY2hGb3JtYXR0ZXJGZWF0dXJlLlVOSVFVRV9UWVBFVkFSX05BTUVTKTsKICAgICAgICAgICAgU3RyaW5nIGRpYWdPcHRzID0gb3B0aW9ucy5nZXQoImRpYWdzLmZvcm1hdHRlck9wdGlvbnMiKTsKICAgICAgICAgICAgaWYgKGRpYWdPcHRzICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIGZvciAoU3RyaW5nIGFyZ3M6IGRpYWdPcHRzLnNwbGl0KCIsIikpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoYXJncy5lcXVhbHMoIi13aGVyZSIpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGZlYXR1cmVzLnJlbW92ZShSaWNoRm9ybWF0dGVyRmVhdHVyZS5XSEVSRV9DTEFVU0VTKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoYXJncy5lcXVhbHMoIndoZXJlIikpIHsKICAgICAgICAgICAgICAgICAgICAgICAgZmVhdHVyZXMuYWRkKFJpY2hGb3JtYXR0ZXJGZWF0dXJlLldIRVJFX0NMQVVTRVMpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoYXJncy5lcXVhbHMoIi1zaW1wbGVOYW1lcyIpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGZlYXR1cmVzLnJlbW92ZShSaWNoRm9ybWF0dGVyRmVhdHVyZS5TSU1QTEVfTkFNRVMpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChhcmdzLmVxdWFscygic2ltcGxlTmFtZXMiKSkgewogICAgICAgICAgICAgICAgICAgICAgICBmZWF0dXJlcy5hZGQoUmljaEZvcm1hdHRlckZlYXR1cmUuU0lNUExFX05BTUVTKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKGFyZ3MuZXF1YWxzKCItZGlzYW1iaWd1YXRlVHZhcnMiKSkgewogICAgICAgICAgICAgICAgICAgICAgICBmZWF0dXJlcy5yZW1vdmUoUmljaEZvcm1hdHRlckZlYXR1cmUuVU5JUVVFX1RZUEVWQVJfTkFNRVMpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChhcmdzLmVxdWFscygiZGlzYW1iaWd1YXRlVHZhcnMiKSkgewogICAgICAgICAgICAgICAgICAgICAgICBmZWF0dXJlcy5hZGQoUmljaEZvcm1hdHRlckZlYXR1cmUuVU5JUVVFX1RZUEVWQVJfTkFNRVMpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogUmV0dXJucyBhIGxpc3Qgb2YgYWxsIHRoZSBmZWF0dXJlcyBzdXBwb3J0ZWQgYnkgdGhlIHJpY2ggZm9ybWF0dGVyLgogICAgICAgICAqIEByZXR1cm4gbGlzdCBvZiBzdXBwb3J0ZWQgZmVhdHVyZXMKICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgUmljaEZvcm1hdHRlckZlYXR1cmVbXSBnZXRBdmFpbGFibGVGZWF0dXJlcygpIHsKICAgICAgICAgICAgcmV0dXJuIFJpY2hGb3JtYXR0ZXJGZWF0dXJlLnZhbHVlcygpOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogRW5hYmxlIGEgc3BlY2lmaWMgZmVhdHVyZSBvbiB0aGlzIHJpY2ggZm9ybWF0dGVyLgogICAgICAgICAqIEBwYXJhbSBmZWF0dXJlIGZlYXR1cmUgdG8gYmUgZW5hYmxlZAogICAgICAgICAqLwogICAgICAgIHB1YmxpYyB2b2lkIGVuYWJsZShSaWNoRm9ybWF0dGVyRmVhdHVyZSBmZWF0dXJlKSB7CiAgICAgICAgICAgIGZlYXR1cmVzLmFkZChmZWF0dXJlKTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIERpc2FibGUgYSBzcGVjaWZpYyBmZWF0dXJlIG9uIHRoaXMgcmljaCBmb3JtYXR0ZXIuCiAgICAgICAgICogQHBhcmFtIGZlYXR1cmUgZmVhdHVyZSB0byBiZSBkaXNhYmxlZAogICAgICAgICAqLwogICAgICAgIHB1YmxpYyB2b2lkIGRpc2FibGUoUmljaEZvcm1hdHRlckZlYXR1cmUgZmVhdHVyZSkgewogICAgICAgICAgICBmZWF0dXJlcy5yZW1vdmUoZmVhdHVyZSk7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBJcyBhIGdpdmVuIGZlYXR1cmUgZW5hYmxlZCBvbiB0aGlzIGZvcm1hdHRlcj8KICAgICAgICAgKiBAcGFyYW0gZmVhdHVyZSBmZWF0dXJlIHRvIGJlIHRlc3RlZAogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBib29sZWFuIGlzRW5hYmxlZChSaWNoRm9ybWF0dGVyRmVhdHVyZSBmZWF0dXJlKSB7CiAgICAgICAgICAgIHJldHVybiBmZWF0dXJlcy5jb250YWlucyhmZWF0dXJlKTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIFRoZSBhZHZhbmNlZCBmb3JtYXR0aW5nIGZlYXR1cmVzIHByb3ZpZGVkIGJ5IHRoZSByaWNoIGZvcm1hdHRlcgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBlbnVtIFJpY2hGb3JtYXR0ZXJGZWF0dXJlIHsKICAgICAgICAgICAgLyoqIGEgbGlzdCBvZiBhZGRpdGlvbmFsIGluZm8gcmVnYXJkaW5nIGEgZ2l2ZW4gdHlwZS9zeW1ib2wgKi8KICAgICAgICAgICAgV0hFUkVfQ0xBVVNFUywKICAgICAgICAgICAgLyoqIGZ1bGwgY2xhc3MgbmFtZXMgc2ltcGxpZmljYXRpb24gKHdoZXJlIHBvc3NpYmxlKSAqLwogICAgICAgICAgICBTSU1QTEVfTkFNRVMsCiAgICAgICAgICAgIC8qKiB0eXBlLXZhcmlhYmxlIG5hbWVzIGRpc2FtYmlndWF0aW9uICovCiAgICAgICAgICAgIFVOSVFVRV9UWVBFVkFSX05BTUVTCiAgICAgICAgfQogICAgfQp9ClBLAwQKAAAIAAAGO6lKZRo2ZvYaAAD2GgAAKAAAAGNvbS9zdW4vdG9vbHMvamF2YWMvdXRpbC9MaXN0QnVmZmVyLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDE5OTksIDIwMTMsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhYy51dGlsOwoKaW1wb3J0IGphdmEudXRpbC5BYnN0cmFjdFF1ZXVlOwppbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb247CmltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CmltcG9ydCBqYXZhLnV0aWwuTm9TdWNoRWxlbWVudEV4Y2VwdGlvbjsKCi8qKiBBIGNsYXNzIGZvciBjb25zdHJ1Y3RpbmcgbGlzdHMgYnkgYXBwZW5kaW5nIGVsZW1lbnRzLiBNb2RlbGxlZCBhZnRlcgogKiAgamF2YS5sYW5nLlN0cmluZ0J1ZmZlci4KICoKICogIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqICBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqICBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogKiAgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPgogKi8KcHVibGljIGNsYXNzIExpc3RCdWZmZXI8QT4gZXh0ZW5kcyBBYnN0cmFjdFF1ZXVlPEE+IHsKCiAgICBwdWJsaWMgc3RhdGljIDxUPiBMaXN0QnVmZmVyPFQ+IG9mKFQgeCkgewogICAgICAgIExpc3RCdWZmZXI8VD4gbGIgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgbGIuYWRkKHgpOwogICAgICAgIHJldHVybiBsYjsKICAgIH0KCiAgICAvKiogVGhlIGxpc3Qgb2YgZWxlbWVudHMgb2YgdGhpcyBidWZmZXIuCiAgICAgKi8KICAgIHByaXZhdGUgTGlzdDxBPiBlbGVtczsKCiAgICAvKiogQSBwb2ludGVyIHBvaW50aW5nIHRvIHRoZSBsYXN0IGVsZW1lbnQgb2YgJ2VsZW1zJyBjb250YWluaW5nIGRhdGEsCiAgICAgKiAgb3IgbnVsbCBpZiB0aGUgbGlzdCBpcyBlbXB0eS4KICAgICAqLwogICAgcHJpdmF0ZSBMaXN0PEE+IGxhc3Q7CgogICAgLyoqIFRoZSBudW1iZXIgb2YgZWxlbWVudCBpbiB0aGlzIGJ1ZmZlci4KICAgICAqLwogICAgcHJpdmF0ZSBpbnQgY291bnQ7CgogICAgLyoqIEhhcyBhIGxpc3QgYmVlbiBjcmVhdGVkIGZyb20gdGhpcyBidWZmZXIgeWV0PwogICAgICovCiAgICBwcml2YXRlIGJvb2xlYW4gc2hhcmVkOwoKICAgIC8qKiBDcmVhdGUgYSBuZXcgaW5pdGlhbGx5IGVtcHR5IGxpc3QgYnVmZmVyLgogICAgICovCiAgICBwdWJsaWMgTGlzdEJ1ZmZlcigpIHsKICAgICAgICBjbGVhcigpOwogICAgfQoKICAgIHB1YmxpYyBmaW5hbCB2b2lkIGNsZWFyKCkgewogICAgICAgIHRoaXMuZWxlbXMgPSBMaXN0Lm5pbCgpOwogICAgICAgIHRoaXMubGFzdCA9IG51bGw7CiAgICAgICAgY291bnQgPSAwOwogICAgICAgIHNoYXJlZCA9IGZhbHNlOwogICAgfQoKICAgIC8qKiBSZXR1cm4gdGhlIG51bWJlciBvZiBlbGVtZW50cyBpbiB0aGlzIGJ1ZmZlci4KICAgICAqLwogICAgcHVibGljIGludCBsZW5ndGgoKSB7CiAgICAgICAgcmV0dXJuIGNvdW50OwogICAgfQogICAgcHVibGljIGludCBzaXplKCkgewogICAgICAgIHJldHVybiBjb3VudDsKICAgIH0KCiAgICAvKiogSXMgYnVmZmVyIGVtcHR5PwogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBpc0VtcHR5KCkgewogICAgICAgIHJldHVybiBjb3VudCA9PSAwOwogICAgfQoKICAgIC8qKiBJcyBidWZmZXIgbm90IGVtcHR5PwogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBub25FbXB0eSgpIHsKICAgICAgICByZXR1cm4gY291bnQgIT0gMDsKICAgIH0KCiAgICAvKiogQ29weSBsaXN0IGFuZCBzZXRzIGxhc3QuCiAgICAgKi8KICAgIHByaXZhdGUgdm9pZCBjb3B5KCkgewogICAgICAgIGlmIChlbGVtcy5ub25FbXB0eSgpKSB7CiAgICAgICAgICAgIExpc3Q8QT4gb3JpZyA9IGVsZW1zOwoKICAgICAgICAgICAgZWxlbXMgPSBsYXN0ID0gTGlzdC5vZihvcmlnLmhlYWQpOwoKICAgICAgICAgICAgd2hpbGUgKChvcmlnID0gb3JpZy50YWlsKS5ub25FbXB0eSgpKSB7CiAgICAgICAgICAgICAgICBsYXN0LnRhaWwgPSBMaXN0Lm9mKG9yaWcuaGVhZCk7CiAgICAgICAgICAgICAgICBsYXN0ID0gbGFzdC50YWlsOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKiBQcmVwZW5kIGFuIGVsZW1lbnQgdG8gYnVmZmVyLgogICAgICovCiAgICBwdWJsaWMgTGlzdEJ1ZmZlcjxBPiBwcmVwZW5kKEEgeCkgewogICAgICAgIGVsZW1zID0gZWxlbXMucHJlcGVuZCh4KTsKICAgICAgICBpZiAobGFzdCA9PSBudWxsKSBsYXN0ID0gZWxlbXM7CiAgICAgICAgY291bnQrKzsKICAgICAgICByZXR1cm4gdGhpczsKICAgIH0KCiAgICAvKiogQXBwZW5kIGFuIGVsZW1lbnQgdG8gYnVmZmVyLgogICAgICovCiAgICBwdWJsaWMgTGlzdEJ1ZmZlcjxBPiBhcHBlbmQoQSB4KSB7CiAgICAgICAgQXNzZXJ0LmNoZWNrTm9uTnVsbCh4KTsKICAgICAgICBpZiAoc2hhcmVkKSBjb3B5KCk7CiAgICAgICAgTGlzdDxBPiBuZXdMYXN0ID0gTGlzdC5vZih4KTsKICAgICAgICBpZiAobGFzdCAhPSBudWxsKSB7CiAgICAgICAgICAgIGxhc3QudGFpbCA9IG5ld0xhc3Q7CiAgICAgICAgICAgIGxhc3QgPSBuZXdMYXN0OwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVsZW1zID0gbGFzdCA9IG5ld0xhc3Q7CiAgICAgICAgfQogICAgICAgIGNvdW50Kys7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CgogICAgLyoqIEFwcGVuZCBhbGwgZWxlbWVudHMgaW4gYSBsaXN0IHRvIGJ1ZmZlci4KICAgICAqLwogICAgcHVibGljIExpc3RCdWZmZXI8QT4gYXBwZW5kTGlzdChMaXN0PEE+IHhzKSB7CiAgICAgICAgd2hpbGUgKHhzLm5vbkVtcHR5KCkpIHsKICAgICAgICAgICAgYXBwZW5kKHhzLmhlYWQpOwogICAgICAgICAgICB4cyA9IHhzLnRhaWw7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgfQoKICAgIC8qKiBBcHBlbmQgYWxsIGVsZW1lbnRzIGluIGEgbGlzdCB0byBidWZmZXIuCiAgICAgKi8KICAgIHB1YmxpYyBMaXN0QnVmZmVyPEE+IGFwcGVuZExpc3QoTGlzdEJ1ZmZlcjxBPiB4cykgewogICAgICAgIHJldHVybiBhcHBlbmRMaXN0KHhzLnRvTGlzdCgpKTsKICAgIH0KCiAgICAvKiogQXBwZW5kIGFsbCBlbGVtZW50cyBpbiBhbiBhcnJheSB0byBidWZmZXIuCiAgICAgKi8KICAgIHB1YmxpYyBMaXN0QnVmZmVyPEE+IGFwcGVuZEFycmF5KEFbXSB4cykgewogICAgICAgIGZvciAoQSB4IDogeHMpIHsKICAgICAgICAgICAgYXBwZW5kKHgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgIH0KCiAgICAvKiogQ29udmVydCBidWZmZXIgdG8gYSBsaXN0IG9mIGFsbCBpdHMgZWxlbWVudHMuCiAgICAgKi8KICAgIHB1YmxpYyBMaXN0PEE+IHRvTGlzdCgpIHsKICAgICAgICBzaGFyZWQgPSB0cnVlOwogICAgICAgIHJldHVybiBlbGVtczsKICAgIH0KCiAgICAvKiogRG9lcyB0aGUgbGlzdCBjb250YWluIHRoZSBzcGVjaWZpZWQgZWxlbWVudD8KICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnMoT2JqZWN0IHgpIHsKICAgICAgICByZXR1cm4gZWxlbXMuY29udGFpbnMoeCk7CiAgICB9CgogICAgLyoqIENvbnZlcnQgYnVmZmVyIHRvIGFuIGFycmF5CiAgICAgKi8KICAgIHB1YmxpYyA8VD4gVFtdIHRvQXJyYXkoVFtdIHZlYykgewogICAgICAgIHJldHVybiBlbGVtcy50b0FycmF5KHZlYyk7CiAgICB9CiAgICBwdWJsaWMgT2JqZWN0W10gdG9BcnJheSgpIHsKICAgICAgICByZXR1cm4gdG9BcnJheShuZXcgT2JqZWN0W3NpemUoKV0pOwogICAgfQoKICAgIC8qKiBUaGUgZmlyc3QgZWxlbWVudCBpbiB0aGlzIGJ1ZmZlci4KICAgICAqLwogICAgcHVibGljIEEgZmlyc3QoKSB7CiAgICAgICAgcmV0dXJuIGVsZW1zLmhlYWQ7CiAgICB9CgogICAgLyoqIFJldHVybiBmaXJzdCBlbGVtZW50IGluIHRoaXMgYnVmZmVyIGFuZCByZW1vdmUKICAgICAqLwogICAgcHVibGljIEEgbmV4dCgpIHsKICAgICAgICBBIHggPSBlbGVtcy5oZWFkOwogICAgICAgIGlmICghZWxlbXMuaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGVsZW1zID0gZWxlbXMudGFpbDsKICAgICAgICAgICAgaWYgKGVsZW1zLmlzRW1wdHkoKSkgbGFzdCA9IG51bGw7CiAgICAgICAgICAgIGNvdW50LS07CiAgICAgICAgfQogICAgICAgIHJldHVybiB4OwogICAgfQoKICAgIC8qKiBBbiBlbnVtZXJhdGlvbiBvZiBhbGwgZWxlbWVudHMgaW4gdGhpcyBidWZmZXIuCiAgICAgKi8KICAgIHB1YmxpYyBJdGVyYXRvcjxBPiBpdGVyYXRvcigpIHsKICAgICAgICByZXR1cm4gbmV3IEl0ZXJhdG9yPEE+KCkgewogICAgICAgICAgICBMaXN0PEE+IGVsZW1zID0gTGlzdEJ1ZmZlci50aGlzLmVsZW1zOwogICAgICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNOZXh0KCkgewogICAgICAgICAgICAgICAgcmV0dXJuICFlbGVtcy5pc0VtcHR5KCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcHVibGljIEEgbmV4dCgpIHsKICAgICAgICAgICAgICAgIGlmIChlbGVtcy5pc0VtcHR5KCkpCiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaEVsZW1lbnRFeGNlcHRpb24oKTsKICAgICAgICAgICAgICAgIEEgZWxlbSA9IGVsZW1zLmhlYWQ7CiAgICAgICAgICAgICAgICBlbGVtcyA9IGVsZW1zLnRhaWw7CiAgICAgICAgICAgICAgICByZXR1cm4gZWxlbTsKICAgICAgICAgICAgfQogICAgICAgICAgICBwdWJsaWMgdm9pZCByZW1vdmUoKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKICAgICAgICAgICAgfQogICAgICAgIH07CiAgICB9CgogICAgcHVibGljIGJvb2xlYW4gYWRkKEEgYSkgewogICAgICAgIGFwcGVuZChhKTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBwdWJsaWMgYm9vbGVhbiByZW1vdmUoT2JqZWN0IG8pIHsKICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKICAgIH0KCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0FsbChDb2xsZWN0aW9uPD8+IGMpIHsKICAgICAgICBmb3IgKE9iamVjdCB4OiBjKSB7CiAgICAgICAgICAgIGlmICghY29udGFpbnMoeCkpCiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIHB1YmxpYyBib29sZWFuIGFkZEFsbChDb2xsZWN0aW9uPD8gZXh0ZW5kcyBBPiBjKSB7CiAgICAgICAgZm9yIChBIGE6IGMpCiAgICAgICAgICAgIGFwcGVuZChhKTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBwdWJsaWMgYm9vbGVhbiByZW1vdmVBbGwoQ29sbGVjdGlvbjw/PiBjKSB7CiAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CiAgICB9CgogICAgcHVibGljIGJvb2xlYW4gcmV0YWluQWxsKENvbGxlY3Rpb248Pz4gYykgewogICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOwogICAgfQoKICAgIHB1YmxpYyBib29sZWFuIG9mZmVyKEEgYSkgewogICAgICAgIGFwcGVuZChhKTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBwdWJsaWMgQSBwb2xsKCkgewogICAgICAgIHJldHVybiBuZXh0KCk7CiAgICB9CgogICAgcHVibGljIEEgcGVlaygpIHsKICAgICAgICByZXR1cm4gZmlyc3QoKTsKICAgIH0KCiAgICBwdWJsaWMgQSBsYXN0KCkgewogICAgICAgIHJldHVybiBsYXN0ICE9IG51bGwgPyBsYXN0LmhlYWQgOiBudWxsOwogICAgfQp9ClBLAwQKAAAIAADSfU1KTlear8QbAADEGwAALgAAAGNvbS9zdW4vdG9vbHMvamF2YWMvdXRpbC9EaWFnbm9zdGljU291cmNlLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDE5OTksIDIwMTIsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhYy51dGlsOwoKaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CmltcG9ydCBqYXZhLmxhbmcucmVmLlNvZnRSZWZlcmVuY2U7CmltcG9ydCBqYXZhLm5pby5DaGFyQnVmZmVyOwppbXBvcnQgamF2YXgudG9vbHMuSmF2YUZpbGVPYmplY3Q7CgppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5maWxlLkphdmFjRmlsZU1hbmFnZXI7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuRW5kUG9zVGFibGU7CgppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5MYXlvdXRDaGFyYWN0ZXJzLio7CgovKioKICogQSBzaW1wbGUgYWJzdHJhY3Rpb24gb2YgYSBzb3VyY2UgZmlsZSwgYXMgbmVlZGVkIGZvciB1c2UgaW4gYSBkaWFnbm9zdGljIG1lc3NhZ2UuCiAqIFByb3ZpZGVzIGFjY2VzcyB0byB0aGUgbGluZSBhbmQgcG9zaXRpb24gaW4gYSBsaW5lIGZvciBhbnkgZ2l2ZW4gY2hhcmFjdGVyIG9mZnNldC4KICoKICogIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqICBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqICBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogKiAgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPgogKi8KcHVibGljIGNsYXNzIERpYWdub3N0aWNTb3VyY2UgewoKICAgIC8qIGNvbnN0YW50IERpYWdub3N0aWNTb3VyY2UgdG8gYmUgdXNlZCB3aGVuIHNvdXJjZWZpbGUgaXMgbWlzc2luZyAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBEaWFnbm9zdGljU291cmNlIE5PX1NPVVJDRSA9IG5ldyBEaWFnbm9zdGljU291cmNlKCkgewogICAgICAgIEBPdmVycmlkZQogICAgICAgIHByb3RlY3RlZCBib29sZWFuIGZpbmRMaW5lKGludCBwb3MpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgIH07CgogICAgcHVibGljIERpYWdub3N0aWNTb3VyY2UoSmF2YUZpbGVPYmplY3QgZm8sIEFic3RyYWN0TG9nIGxvZykgewogICAgICAgIHRoaXMuZmlsZU9iamVjdCA9IGZvOwogICAgICAgIHRoaXMubG9nID0gbG9nOwogICAgfQoKICAgIHByaXZhdGUgRGlhZ25vc3RpY1NvdXJjZSgpIHt9CgogICAgLyoqIFJldHVybiB0aGUgdW5kZXJseWluZyBmaWxlIG9iamVjdCBoYW5kbGVkIGJ5IHRoaXMKICAgICAqICBEaWFnbm9zdGljU291cmNlIG9iamVjdC4KICAgICAqLwogICAgcHVibGljIEphdmFGaWxlT2JqZWN0IGdldEZpbGUoKSB7CiAgICAgICAgcmV0dXJuIGZpbGVPYmplY3Q7CiAgICB9CgogICAgLyoqIFJldHVybiB0aGUgb25lLWJhc2VkIGxpbmUgbnVtYmVyIGFzc29jaWF0ZWQgd2l0aCBhIGdpdmVuIHBvcwogICAgICogZm9yIHRoZSBjdXJyZW50IHNvdXJjZSBmaWxlLiAgWmVybyBpcyByZXR1cm5lZCBpZiBubyBsaW5lIGV4aXN0cwogICAgICogZm9yIHRoZSBnaXZlbiBwb3NpdGlvbi4KICAgICAqLwogICAgcHVibGljIGludCBnZXRMaW5lTnVtYmVyKGludCBwb3MpIHsKICAgICAgICB0cnkgewogICAgICAgICAgICBpZiAoZmluZExpbmUocG9zKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGxpbmU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgYnVmID0gbnVsbDsKICAgICAgICB9CiAgICB9CgogICAgLyoqIFJldHVybiB0aGUgb25lLWJhc2VkIGNvbHVtbiBudW1iZXIgYXNzb2NpYXRlZCB3aXRoIGEgZ2l2ZW4gcG9zCiAgICAgKiBmb3IgdGhlIGN1cnJlbnQgc291cmNlIGZpbGUuICBaZXJvIGlzIHJldHVybmVkIGlmIG5vIGNvbHVtbiBleGlzdHMKICAgICAqIGZvciB0aGUgZ2l2ZW4gcG9zaXRpb24uCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0Q29sdW1uTnVtYmVyKGludCBwb3MsIGJvb2xlYW4gZXhwYW5kVGFicykgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGlmIChmaW5kTGluZShwb3MpKSB7CiAgICAgICAgICAgICAgICBpbnQgY29sdW1uID0gMDsKICAgICAgICAgICAgICAgIGZvciAoaW50IGJwID0gbGluZVN0YXJ0OyBicCA8IHBvczsgYnArKykgewogICAgICAgICAgICAgICAgICAgIGlmIChicCA+PSBidWZMZW4pIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmIChidWZbYnBdID09ICdcdCcgJiYgZXhwYW5kVGFicykgewogICAgICAgICAgICAgICAgICAgICAgICBjb2x1bW4gPSAoY29sdW1uIC8gVGFiSW5jICogVGFiSW5jKSArIFRhYkluYzsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBjb2x1bW4rKzsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gY29sdW1uICsgMTsgLy8gcG9zaXRpb25zIGFyZSBvbmUtYmFzZWQKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICBidWYgPSBudWxsOwogICAgICAgIH0KICAgIH0KCiAgICAvKiogUmV0dXJuIHRoZSBjb250ZW50IG9mIHRoZSBsaW5lIGNvbnRhaW5pbmcgYSBnaXZlbiBwb3MuCiAgICAgKi8KICAgIHB1YmxpYyBTdHJpbmcgZ2V0TGluZShpbnQgcG9zKSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgaWYgKCFmaW5kTGluZShwb3MpKQogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CgogICAgICAgICAgICBpbnQgbGluZUVuZCA9IGxpbmVTdGFydDsKICAgICAgICAgICAgd2hpbGUgKGxpbmVFbmQgPCBidWZMZW4gJiYgYnVmW2xpbmVFbmRdICE9IENSICYmIGJ1ZltsaW5lRW5kXSAhPSBMRikKICAgICAgICAgICAgICAgIGxpbmVFbmQrKzsKICAgICAgICAgICAgaWYgKGxpbmVFbmQgLSBsaW5lU3RhcnQgPT0gMCkKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICByZXR1cm4gbmV3IFN0cmluZyhidWYsIGxpbmVTdGFydCwgbGluZUVuZCAtIGxpbmVTdGFydCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgYnVmID0gbnVsbDsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIEVuZFBvc1RhYmxlIGdldEVuZFBvc1RhYmxlKCkgewogICAgICAgIHJldHVybiBlbmRQb3NUYWJsZTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCBzZXRFbmRQb3NUYWJsZShFbmRQb3NUYWJsZSB0KSB7CiAgICAgICAgaWYgKGVuZFBvc1RhYmxlICE9IG51bGwgJiYgZW5kUG9zVGFibGUgIT0gdCkKICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiZW5kUG9zVGFibGUgYWxyZWFkeSBzZXQiKTsKICAgICAgICBlbmRQb3NUYWJsZSA9IHQ7CiAgICB9CgogICAgLyoqIEZpbmQgdGhlIGxpbmUgaW4gdGhlIGJ1ZmZlciB0aGF0IGNvbnRhaW5zIHRoZSBjdXJyZW50IHBvc2l0aW9uCiAgICAgKiBAcGFyYW0gcG9zICAgICAgQ2hhcmFjdGVyIG9mZnNldCBpbnRvIHRoZSBidWZmZXIKICAgICAqLwogICAgcHJvdGVjdGVkIGJvb2xlYW4gZmluZExpbmUoaW50IHBvcykgewogICAgICAgIGlmIChwb3MgPT0gUG9zaXRpb24uTk9QT1MpCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKCiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgLy8gdHJ5IGFuZCByZWNvdmVyIGJ1ZmZlciBmcm9tIHNvZnQgcmVmZXJlbmNlIGNhY2hlCiAgICAgICAgICAgIGlmIChidWYgPT0gbnVsbCAmJiByZWZCdWYgIT0gbnVsbCkKICAgICAgICAgICAgICAgIGJ1ZiA9IHJlZkJ1Zi5nZXQoKTsKCiAgICAgICAgICAgIGlmIChidWYgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgYnVmID0gaW5pdEJ1ZihmaWxlT2JqZWN0KTsKICAgICAgICAgICAgICAgIGxpbmVTdGFydCA9IDA7CiAgICAgICAgICAgICAgICBsaW5lID0gMTsKICAgICAgICAgICAgfSBlbHNlIGlmIChsaW5lU3RhcnQgPiBwb3MpIHsgLy8gbWVzc2FnZXMgZG9uJ3QgY29tZSBpbiBvcmRlcgogICAgICAgICAgICAgICAgbGluZVN0YXJ0ID0gMDsKICAgICAgICAgICAgICAgIGxpbmUgPSAxOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpbnQgYnAgPSBsaW5lU3RhcnQ7CiAgICAgICAgICAgIHdoaWxlIChicCA8IGJ1ZkxlbiAmJiBicCA8IHBvcykgewogICAgICAgICAgICAgICAgc3dpdGNoIChidWZbYnArK10pIHsKICAgICAgICAgICAgICAgIGNhc2UgQ1I6CiAgICAgICAgICAgICAgICAgICAgaWYgKGJwIDwgYnVmTGVuICYmIGJ1ZlticF0gPT0gTEYpIGJwKys7CiAgICAgICAgICAgICAgICAgICAgbGluZSsrOwogICAgICAgICAgICAgICAgICAgIGxpbmVTdGFydCA9IGJwOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBMRjoKICAgICAgICAgICAgICAgICAgICBsaW5lKys7CiAgICAgICAgICAgICAgICAgICAgbGluZVN0YXJ0ID0gYnA7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGJwIDw9IGJ1ZkxlbjsKICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIGxvZy5kaXJlY3RFcnJvcigic291cmNlLnVuYXZhaWxhYmxlIik7CiAgICAgICAgICAgIGJ1ZiA9IG5ldyBjaGFyWzBdOwogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgfQoKICAgIHByb3RlY3RlZCBjaGFyW10gaW5pdEJ1ZihKYXZhRmlsZU9iamVjdCBmaWxlT2JqZWN0KSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgIGNoYXJbXSBidWY7CiAgICAgICAgQ2hhclNlcXVlbmNlIGNzID0gZmlsZU9iamVjdC5nZXRDaGFyQ29udGVudCh0cnVlKTsKICAgICAgICBpZiAoY3MgaW5zdGFuY2VvZiBDaGFyQnVmZmVyKSB7CiAgICAgICAgICAgIENoYXJCdWZmZXIgY2IgPSAoQ2hhckJ1ZmZlcikgY3M7CiAgICAgICAgICAgIGJ1ZiA9IEphdmFjRmlsZU1hbmFnZXIudG9BcnJheShjYik7CiAgICAgICAgICAgIGJ1ZkxlbiA9IGNiLmxpbWl0KCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgYnVmID0gY3MudG9TdHJpbmcoKS50b0NoYXJBcnJheSgpOwogICAgICAgICAgICBidWZMZW4gPSBidWYubGVuZ3RoOwogICAgICAgIH0KICAgICAgICByZWZCdWYgPSBuZXcgU29mdFJlZmVyZW5jZTw+KGJ1Zik7CiAgICAgICAgcmV0dXJuIGJ1ZjsKICAgIH0KCiAgICAvKiogVGhlIHVuZGVybHlpbmcgZmlsZSBvYmplY3QuICovCiAgICBwcm90ZWN0ZWQgSmF2YUZpbGVPYmplY3QgZmlsZU9iamVjdDsKCiAgICBwcm90ZWN0ZWQgRW5kUG9zVGFibGUgZW5kUG9zVGFibGU7CgogICAgLyoqIEEgc29mdCByZWZlcmVuY2UgdG8gdGhlIGNvbnRlbnQgb2YgdGhlIGZpbGUgb2JqZWN0LiAqLwogICAgcHJvdGVjdGVkIFNvZnRSZWZlcmVuY2U8Y2hhcltdPiByZWZCdWY7CgogICAgLyoqIEEgdGVtcG9yYXJ5IGhhcmQgcmVmZXJlbmNlIHRvIHRoZSBjb250ZW50IG9mIHRoZSBmaWxlIG9iamVjdC4gKi8KICAgIHByb3RlY3RlZCBjaGFyW10gYnVmOwoKICAgIC8qKiBUaGUgbGVuZ3RoIG9mIHRoZSBjb250ZW50LiAqLwogICAgcHJvdGVjdGVkIGludCBidWZMZW47CgogICAgLyoqIFRoZSBzdGFydCBvZiBhIGxpbmUgZm91bmQgYnkgZmluZExpbmUuICovCiAgICBwcm90ZWN0ZWQgaW50IGxpbmVTdGFydDsKCiAgICAvKiogVGhlIGxpbmUgbnVtYmVyIG9mIGEgbGluZSBmb3VuZCBieSBmaW5kTGluZS4gKi8KICAgIHByb3RlY3RlZCBpbnQgbGluZTsKCiAgICAvKiogQSBsb2cgZm9yIHJlcG9ydGluZyBlcnJvcnMsIHN1Y2ggYXMgZXJyb3JzIGFjY2Vzc2luZyB0aGUgY29udGVudC4gKi8KICAgIHByb3RlY3RlZCBBYnN0cmFjdExvZyBsb2c7Cn0KUEsDBAoAAAgAAAY7qUpnUCPloxIAAKMSAAA7AAAAY29tL3N1bi90b29scy9qYXZhYy91dGlsL0ZvcndhcmRpbmdEaWFnbm9zdGljRm9ybWF0dGVyLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDksIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhYy51dGlsOwoKaW1wb3J0IGphdmEudXRpbC5TZXQ7CmltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOwppbXBvcnQgamF2YXgudG9vbHMuRGlhZ25vc3RpYzsKCmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmFwaS5EaWFnbm9zdGljRm9ybWF0dGVyOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5hcGkuRGlhZ25vc3RpY0Zvcm1hdHRlci5Db25maWd1cmF0aW9uOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5hcGkuRGlhZ25vc3RpY0Zvcm1hdHRlci5Db25maWd1cmF0aW9uLkRpYWdub3N0aWNQYXJ0OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5hcGkuRGlhZ25vc3RpY0Zvcm1hdHRlci5Db25maWd1cmF0aW9uLk11bHRpbGluZUxpbWl0OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5hcGkuRGlhZ25vc3RpY0Zvcm1hdHRlci5Qb3NpdGlvbktpbmQ7CgovKioKICogQSBkZWxlZ2F0ZWQgZGlhZ25vc3RpYyBmb3JtYXR0ZXIgZGVsZWdhdGVzIGFsbCBmb3JtYXR0aW5nCiAqIGFjdGlvbnMgdG8gYW4gdW5kZXJseWluZyBmb3JtYXR0ZXIgKGFrYSB0aGUgZGVsZWdhdGVkIGZvcm1hdHRlcikuCiAqCiAqIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24gcmlzay4KICogVGhpcyBjb2RlIGFuZCBpdHMgaW50ZXJuYWwgaW50ZXJmYWNlcyBhcmUgc3ViamVjdCB0byBjaGFuZ2Ugb3IKICogZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPgogKi8KcHVibGljIGNsYXNzIEZvcndhcmRpbmdEaWFnbm9zdGljRm9ybWF0dGVyPEQgZXh0ZW5kcyBEaWFnbm9zdGljPD8+LCBGIGV4dGVuZHMgRGlhZ25vc3RpY0Zvcm1hdHRlcjxEPj4KICAgICAgICBpbXBsZW1lbnRzIERpYWdub3N0aWNGb3JtYXR0ZXI8RD4gewoKICAgIC8qKgogICAgICogVGhlIGRlbGVnYXRlZCBmb3JtYXR0ZXIKICAgICAqLwogICAgcHJvdGVjdGVkIEYgZm9ybWF0dGVyOwoKICAgIC8qCiAgICAgKiBjb25maWd1cmF0aW9uIG9iamVjdCB1c2VkIGJ5IHRoaXMgZm9ybWF0dGVyCiAgICAgKi8KICAgIHByb3RlY3RlZCBGb3J3YXJkaW5nQ29uZmlndXJhdGlvbiBjb25maWd1cmF0aW9uOwoKICAgIHB1YmxpYyBGb3J3YXJkaW5nRGlhZ25vc3RpY0Zvcm1hdHRlcihGIGZvcm1hdHRlcikgewogICAgICAgIHRoaXMuZm9ybWF0dGVyID0gZm9ybWF0dGVyOwogICAgICAgIHRoaXMuY29uZmlndXJhdGlvbiA9IG5ldyBGb3J3YXJkaW5nQ29uZmlndXJhdGlvbihmb3JtYXR0ZXIuZ2V0Q29uZmlndXJhdGlvbigpKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHVuZGVybHlpbmcgZGVsZWdhdGVkIGZvcm1hdHRlcgogICAgICogQHJldHVybiBkZWxlZ2F0ZSBmb3JtYXR0ZXIKICAgICAqLwogICAgcHVibGljIEYgZ2V0RGVsZWdhdGVkRm9ybWF0dGVyKCkgewogICAgICAgIHJldHVybiBmb3JtYXR0ZXI7CiAgICB9CgogICAgcHVibGljIENvbmZpZ3VyYXRpb24gZ2V0Q29uZmlndXJhdGlvbigpIHsKICAgICAgICByZXR1cm4gY29uZmlndXJhdGlvbjsKICAgIH0KCiAgICBwdWJsaWMgYm9vbGVhbiBkaXNwbGF5U291cmNlKEQgZGlhZykgewogICAgICAgIHJldHVybiBmb3JtYXR0ZXIuZGlzcGxheVNvdXJjZShkaWFnKTsKICAgIH0KCiAgICBwdWJsaWMgU3RyaW5nIGZvcm1hdChEIGRpYWcsIExvY2FsZSBsKSB7CiAgICAgICAgcmV0dXJuIGZvcm1hdHRlci5mb3JtYXQoZGlhZywgbCk7CiAgICB9CgogICAgcHVibGljIFN0cmluZyBmb3JtYXRLaW5kKEQgZGlhZywgTG9jYWxlIGwpIHsKICAgICAgICByZXR1cm4gZm9ybWF0dGVyLmZvcm1hdEtpbmQoZGlhZywgbCk7CiAgICB9CgogICAgcHVibGljIFN0cmluZyBmb3JtYXRNZXNzYWdlKEQgZGlhZywgTG9jYWxlIGwpIHsKICAgICAgICByZXR1cm4gZm9ybWF0dGVyLmZvcm1hdE1lc3NhZ2UoZGlhZywgbCk7CiAgICB9CgogICAgcHVibGljIFN0cmluZyBmb3JtYXRQb3NpdGlvbihEIGRpYWcsIFBvc2l0aW9uS2luZCBwaywgTG9jYWxlIGwpIHsKICAgICAgICByZXR1cm4gZm9ybWF0dGVyLmZvcm1hdFBvc2l0aW9uKGRpYWcsIHBrLCBsKTsKICAgIH0KCiAgICBwdWJsaWMgU3RyaW5nIGZvcm1hdFNvdXJjZShEIGRpYWcsIGJvb2xlYW4gZnVsbG5hbWUsIExvY2FsZSBsKSB7CiAgICAgICAgcmV0dXJuIGZvcm1hdHRlci5mb3JtYXRTb3VyY2UoZGlhZywgZnVsbG5hbWUsIGwpOwogICAgfQoKICAgIC8qKgogICAgICogQSBkZWxlZ2F0ZWQgZm9ybWF0dGVyIGNvbmZpZ3VyYXRpb24gZGVsZWdhdGVzIGFsbCBjb25maWd1cmF0aW9ucyBzZXR0aW5ncwogICAgICogdG8gYW4gdW5kZXJseWluZyBjb25maWd1cmF0aW9uIG9iamVjdCAoYWthIHRoZSBkZWxlZ2F0ZWQgY29uZmlndXJhdGlvbikuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgRm9yd2FyZGluZ0NvbmZpZ3VyYXRpb24gaW1wbGVtZW50cyBEaWFnbm9zdGljRm9ybWF0dGVyLkNvbmZpZ3VyYXRpb24gewoKICAgICAgICAvKiogVGhlIGNvbmZpZ3VyYXRpb25yIG9iamVjdCB0byB3aGljaCB0aGUgZm9yd2FyZGluZyBjb25maWd1cmF0aW9uIGRlbGVnYXRlcyBzb21lIHNldHRpbmdzICovCiAgICAgICAgcHJvdGVjdGVkIENvbmZpZ3VyYXRpb24gY29uZmlndXJhdGlvbjsKCiAgICAgICAgcHVibGljIEZvcndhcmRpbmdDb25maWd1cmF0aW9uKENvbmZpZ3VyYXRpb24gY29uZmlndXJhdGlvbikgewogICAgICAgICAgICB0aGlzLmNvbmZpZ3VyYXRpb24gPSBjb25maWd1cmF0aW9uOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogUmV0dXJucyB0aGUgdW5kZXJseWluZyBkZWxlZ2F0ZWQgY29uZmlndXJhdGlvbi4KICAgICAgICAgKiBAcmV0dXJuIGRlbGVnYXRlZCBjb25maWd1cmF0aW9uCiAgICAgICAgICovCiAgICAgICAgcHVibGljIENvbmZpZ3VyYXRpb24gZ2V0RGVsZWdhdGVkQ29uZmlndXJhdGlvbigpIHsKICAgICAgICAgICAgcmV0dXJuIGNvbmZpZ3VyYXRpb247CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgaW50IGdldE11bHRpbGluZUxpbWl0KE11bHRpbGluZUxpbWl0IGxpbWl0KSB7CiAgICAgICAgICAgIHJldHVybiBjb25maWd1cmF0aW9uLmdldE11bHRpbGluZUxpbWl0KGxpbWl0KTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBTZXQ8RGlhZ25vc3RpY1BhcnQ+IGdldFZpc2libGUoKSB7CiAgICAgICAgICAgIHJldHVybiBjb25maWd1cmF0aW9uLmdldFZpc2libGUoKTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyB2b2lkIHNldE11bHRpbGluZUxpbWl0KE11bHRpbGluZUxpbWl0IGxpbWl0LCBpbnQgdmFsdWUpIHsKICAgICAgICAgICAgY29uZmlndXJhdGlvbi5zZXRNdWx0aWxpbmVMaW1pdChsaW1pdCwgdmFsdWUpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHZvaWQgc2V0VmlzaWJsZShTZXQ8RGlhZ25vc3RpY1BhcnQ+IGRpYWdQYXJ0cykgewogICAgICAgICAgICBjb25maWd1cmF0aW9uLnNldFZpc2libGUoZGlhZ1BhcnRzKTsKICAgICAgICB9CiAgICB9Cn0KUEsDBAoAAAgAAAY7qUq0zbvaIUEAACFBAAApAAAAY29tL3N1bi90b29scy9qYXZhYy91dGlsL0Fic3RyYWN0TG9nLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDE5OTksIDIwMTIsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhYy51dGlsOwoKaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOwppbXBvcnQgamF2YS51dGlsLk1hcDsKaW1wb3J0IGphdmF4LnRvb2xzLkphdmFGaWxlT2JqZWN0OwoKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5MaW50LkxpbnRDYXRlZ29yeTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5KQ0RpYWdub3N0aWMuRGlhZ25vc3RpY0ZsYWc7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuSkNEaWFnbm9zdGljLkVycm9yOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkpDRGlhZ25vc3RpYy5Ob3RlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkpDRGlhZ25vc3RpYy5XYXJuaW5nOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkpDRGlhZ25vc3RpYy5EaWFnbm9zdGljUG9zaXRpb247CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuSkNEaWFnbm9zdGljLlNpbXBsZURpYWdub3N0aWNQb3NpdGlvbjsKCgovKioKICogIEEgYmFzZSBjbGFzcyBmb3IgZXJyb3IgbG9ncy4gUmVwb3J0cyBlcnJvcnMgYW5kIHdhcm5pbmdzLCBhbmQKICogIGtlZXBzIHRyYWNrIG9mIGVycm9yIG51bWJlcnMgYW5kIHBvc2l0aW9ucy4KICoKICogIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqICBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqICBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogKiAgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPgogKi8KcHVibGljIGFic3RyYWN0IGNsYXNzIEFic3RyYWN0TG9nIHsKICAgIC8qKiBGYWN0b3J5IGZvciBkaWFnbm9zdGljcwogICAgICovCiAgICBwcm90ZWN0ZWQgSkNEaWFnbm9zdGljLkZhY3RvcnkgZGlhZ3M7CgogICAgLyoqIFRoZSBmaWxlIHRoYXQncyBjdXJyZW50bHkgYmVpbmcgdHJhbnNsYXRlZC4KICAgICAqLwogICAgcHJvdGVjdGVkIERpYWdub3N0aWNTb3VyY2Ugc291cmNlOwoKICAgIC8qKiBBIGNhY2hlIG9mIGxpZ2h0d2VpZ2h0IERpYWdub3N0aWNTb3VyY2Ugb2JqZWN0cy4KICAgICAqLwogICAgcHJvdGVjdGVkIE1hcDxKYXZhRmlsZU9iamVjdCwgRGlhZ25vc3RpY1NvdXJjZT4gc291cmNlTWFwOwoKICAgIEFic3RyYWN0TG9nKEpDRGlhZ25vc3RpYy5GYWN0b3J5IGRpYWdzKSB7CiAgICAgICAgdGhpcy5kaWFncyA9IGRpYWdzOwogICAgICAgIHNvdXJjZU1hcCA9IG5ldyBIYXNoTWFwPD4oKTsKICAgIH0KCiAgICAvKiogUmUtYXNzaWduIHNvdXJjZSwgcmV0dXJuaW5nIHByZXZpb3VzIHNldHRpbmcuCiAgICAgKi8KICAgIHB1YmxpYyBKYXZhRmlsZU9iamVjdCB1c2VTb3VyY2UoSmF2YUZpbGVPYmplY3QgZmlsZSkgewogICAgICAgIEphdmFGaWxlT2JqZWN0IHByZXYgPSAoc291cmNlID09IG51bGwgPyBudWxsIDogc291cmNlLmdldEZpbGUoKSk7CiAgICAgICAgc291cmNlID0gZ2V0U291cmNlKGZpbGUpOwogICAgICAgIHJldHVybiBwcmV2OwogICAgfQoKICAgIHByb3RlY3RlZCBEaWFnbm9zdGljU291cmNlIGdldFNvdXJjZShKYXZhRmlsZU9iamVjdCBmaWxlKSB7CiAgICAgICAgaWYgKGZpbGUgPT0gbnVsbCkKICAgICAgICAgICAgcmV0dXJuIERpYWdub3N0aWNTb3VyY2UuTk9fU09VUkNFOwogICAgICAgIERpYWdub3N0aWNTb3VyY2UgcyA9IHNvdXJjZU1hcC5nZXQoZmlsZSk7CiAgICAgICAgaWYgKHMgPT0gbnVsbCkgewogICAgICAgICAgICBzID0gbmV3IERpYWdub3N0aWNTb3VyY2UoZmlsZSwgdGhpcyk7CiAgICAgICAgICAgIHNvdXJjZU1hcC5wdXQoZmlsZSwgcyk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgfQoKICAgIC8qKiBSZXR1cm4gdGhlIHVuZGVybHlpbmcgZGlhZ25vc3RpYyBzb3VyY2UKICAgICAqLwogICAgcHVibGljIERpYWdub3N0aWNTb3VyY2UgY3VycmVudFNvdXJjZSgpIHsKICAgICAgICByZXR1cm4gc291cmNlOwogICAgfQoKICAgIC8qKiBSZXBvcnQgYW4gZXJyb3IsIHVubGVzcyBhbm90aGVyIGVycm9yIHdhcyBhbHJlYWR5IHJlcG9ydGVkIGF0IHNhbWUKICAgICAqICBzb3VyY2UgcG9zaXRpb24uCiAgICAgKiAgQHBhcmFtIGtleSAgICBUaGUga2V5IGZvciB0aGUgbG9jYWxpemVkIGVycm9yIG1lc3NhZ2UuCiAgICAgKiAgQHBhcmFtIGFyZ3MgICBGaWVsZHMgb2YgdGhlIGVycm9yIG1lc3NhZ2UuCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIGVycm9yKFN0cmluZyBrZXksIE9iamVjdCAuLi4gYXJncykgewogICAgICAgIGVycm9yKGRpYWdzLmVycm9yS2V5KGtleSwgYXJncykpOwogICAgfQoKICAgIC8qKiBSZXBvcnQgYW4gZXJyb3IsIHVubGVzcyBhbm90aGVyIGVycm9yIHdhcyBhbHJlYWR5IHJlcG9ydGVkIGF0IHNhbWUKICAgICAqICBzb3VyY2UgcG9zaXRpb24uCiAgICAgKiAgQHBhcmFtIGVycm9yS2V5ICAgIFRoZSBrZXkgZm9yIHRoZSBsb2NhbGl6ZWQgZXJyb3IgbWVzc2FnZS4KICAgICAqLwogICAgcHVibGljIHZvaWQgZXJyb3IoRXJyb3IgZXJyb3JLZXkpIHsKICAgICAgICByZXBvcnQoZGlhZ3MuZXJyb3IobnVsbCwgc291cmNlLCBudWxsLCBlcnJvcktleSkpOwogICAgfQoKICAgIC8qKiBSZXBvcnQgYW4gZXJyb3IsIHVubGVzcyBhbm90aGVyIGVycm9yIHdhcyBhbHJlYWR5IHJlcG9ydGVkIGF0IHNhbWUKICAgICAqICBzb3VyY2UgcG9zaXRpb24uCiAgICAgKiAgQHBhcmFtIHBvcyAgICBUaGUgc291cmNlIHBvc2l0aW9uIGF0IHdoaWNoIHRvIHJlcG9ydCB0aGUgZXJyb3IuCiAgICAgKiAgQHBhcmFtIGtleSAgICBUaGUga2V5IGZvciB0aGUgbG9jYWxpemVkIGVycm9yIG1lc3NhZ2UuCiAgICAgKiAgQHBhcmFtIGFyZ3MgICBGaWVsZHMgb2YgdGhlIGVycm9yIG1lc3NhZ2UuCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIGVycm9yKERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIFN0cmluZyBrZXksIE9iamVjdC4uLiBhcmdzKSB7CiAgICAgICAgZXJyb3IocG9zLCBkaWFncy5lcnJvcktleShrZXksIGFyZ3MpKTsKICAgIH0KCiAgICAvKiogUmVwb3J0IGFuIGVycm9yLCB1bmxlc3MgYW5vdGhlciBlcnJvciB3YXMgYWxyZWFkeSByZXBvcnRlZCBhdCBzYW1lCiAgICAgKiAgc291cmNlIHBvc2l0aW9uLgogICAgICogIEBwYXJhbSBwb3MgICAgVGhlIHNvdXJjZSBwb3NpdGlvbiBhdCB3aGljaCB0byByZXBvcnQgdGhlIGVycm9yLgogICAgICogIEBwYXJhbSBlcnJvcktleSAgICBUaGUga2V5IGZvciB0aGUgbG9jYWxpemVkIGVycm9yIG1lc3NhZ2UuCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIGVycm9yKERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIEVycm9yIGVycm9yS2V5KSB7CiAgICAgICAgcmVwb3J0KGRpYWdzLmVycm9yKG51bGwsIHNvdXJjZSwgcG9zLCBlcnJvcktleSkpOwogICAgfQoKICAgIC8qKiBSZXBvcnQgYW4gZXJyb3IsIHVubGVzcyBhbm90aGVyIGVycm9yIHdhcyBhbHJlYWR5IHJlcG9ydGVkIGF0IHNhbWUKICAgICAqICBzb3VyY2UgcG9zaXRpb24uCiAgICAgKiAgQHBhcmFtIGZsYWcgICBBIGZsYWcgdG8gc2V0IG9uIHRoZSBkaWFnbm9zdGljCiAgICAgKiAgQHBhcmFtIHBvcyAgICBUaGUgc291cmNlIHBvc2l0aW9uIGF0IHdoaWNoIHRvIHJlcG9ydCB0aGUgZXJyb3IuCiAgICAgKiAgQHBhcmFtIGtleSAgICBUaGUga2V5IGZvciB0aGUgbG9jYWxpemVkIGVycm9yIG1lc3NhZ2UuCiAgICAgKiAgQHBhcmFtIGFyZ3MgICBGaWVsZHMgb2YgdGhlIGVycm9yIG1lc3NhZ2UuCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIGVycm9yKERpYWdub3N0aWNGbGFnIGZsYWcsIERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIFN0cmluZyBrZXksIE9iamVjdCAuLi4gYXJncykgewogICAgICAgIGVycm9yKGZsYWcsIHBvcywgZGlhZ3MuZXJyb3JLZXkoa2V5LCBhcmdzKSk7CiAgICB9CgogICAgLyoqIFJlcG9ydCBhbiBlcnJvciwgdW5sZXNzIGFub3RoZXIgZXJyb3Igd2FzIGFscmVhZHkgcmVwb3J0ZWQgYXQgc2FtZQogICAgICogIHNvdXJjZSBwb3NpdGlvbi4KICAgICAqICBAcGFyYW0gZmxhZyAgIEEgZmxhZyB0byBzZXQgb24gdGhlIGRpYWdub3N0aWMKICAgICAqICBAcGFyYW0gcG9zICAgIFRoZSBzb3VyY2UgcG9zaXRpb24gYXQgd2hpY2ggdG8gcmVwb3J0IHRoZSBlcnJvci4KICAgICAqICBAcGFyYW0gZXJyb3JLZXkgICAgVGhlIGtleSBmb3IgdGhlIGxvY2FsaXplZCBlcnJvciBtZXNzYWdlLgogICAgICovCiAgICBwdWJsaWMgdm9pZCBlcnJvcihEaWFnbm9zdGljRmxhZyBmbGFnLCBEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBFcnJvciBlcnJvcktleSkgewogICAgICAgIHJlcG9ydChkaWFncy5lcnJvcihmbGFnLCBzb3VyY2UsIHBvcywgZXJyb3JLZXkpKTsKICAgIH0KCiAgICAvKiogUmVwb3J0IGFuIGVycm9yLCB1bmxlc3MgYW5vdGhlciBlcnJvciB3YXMgYWxyZWFkeSByZXBvcnRlZCBhdCBzYW1lCiAgICAgKiAgc291cmNlIHBvc2l0aW9uLgogICAgICogIEBwYXJhbSBwb3MgICAgVGhlIHNvdXJjZSBwb3NpdGlvbiBhdCB3aGljaCB0byByZXBvcnQgdGhlIGVycm9yLgogICAgICogIEBwYXJhbSBrZXkgICAgVGhlIGtleSBmb3IgdGhlIGxvY2FsaXplZCBlcnJvciBtZXNzYWdlLgogICAgICogIEBwYXJhbSBhcmdzICAgRmllbGRzIG9mIHRoZSBlcnJvciBtZXNzYWdlLgogICAgICovCiAgICBwdWJsaWMgdm9pZCBlcnJvcihpbnQgcG9zLCBTdHJpbmcga2V5LCBPYmplY3QgLi4uIGFyZ3MpIHsKICAgICAgICBlcnJvcihwb3MsIGRpYWdzLmVycm9yS2V5KGtleSwgYXJncykpOwogICAgfQoKICAgIC8qKiBSZXBvcnQgYW4gZXJyb3IsIHVubGVzcyBhbm90aGVyIGVycm9yIHdhcyBhbHJlYWR5IHJlcG9ydGVkIGF0IHNhbWUKICAgICAqICBzb3VyY2UgcG9zaXRpb24uCiAgICAgKiAgQHBhcmFtIHBvcyAgICBUaGUgc291cmNlIHBvc2l0aW9uIGF0IHdoaWNoIHRvIHJlcG9ydCB0aGUgZXJyb3IuCiAgICAgKiAgQHBhcmFtIGVycm9yS2V5ICAgIFRoZSBrZXkgZm9yIHRoZSBsb2NhbGl6ZWQgZXJyb3IgbWVzc2FnZS4KICAgICAqLwogICAgcHVibGljIHZvaWQgZXJyb3IoaW50IHBvcywgRXJyb3IgZXJyb3JLZXkpIHsKICAgICAgICByZXBvcnQoZGlhZ3MuZXJyb3IobnVsbCwgc291cmNlLCB3cmFwKHBvcyksIGVycm9yS2V5KSk7CiAgICB9CgogICAgLyoqIFJlcG9ydCBhbiBlcnJvciwgdW5sZXNzIGFub3RoZXIgZXJyb3Igd2FzIGFscmVhZHkgcmVwb3J0ZWQgYXQgc2FtZQogICAgICogIHNvdXJjZSBwb3NpdGlvbi4KICAgICAqICBAcGFyYW0gZmxhZyAgIEEgZmxhZyB0byBzZXQgb24gdGhlIGRpYWdub3N0aWMKICAgICAqICBAcGFyYW0gcG9zICAgIFRoZSBzb3VyY2UgcG9zaXRpb24gYXQgd2hpY2ggdG8gcmVwb3J0IHRoZSBlcnJvci4KICAgICAqICBAcGFyYW0ga2V5ICAgIFRoZSBrZXkgZm9yIHRoZSBsb2NhbGl6ZWQgZXJyb3IgbWVzc2FnZS4KICAgICAqICBAcGFyYW0gYXJncyAgIEZpZWxkcyBvZiB0aGUgZXJyb3IgbWVzc2FnZS4KICAgICAqLwogICAgcHVibGljIHZvaWQgZXJyb3IoRGlhZ25vc3RpY0ZsYWcgZmxhZywgaW50IHBvcywgU3RyaW5nIGtleSwgT2JqZWN0IC4uLiBhcmdzKSB7CiAgICAgICAgZXJyb3IoZmxhZywgcG9zLCBkaWFncy5lcnJvcktleShrZXksIGFyZ3MpKTsKICAgIH0KCiAgICAvKiogUmVwb3J0IGFuIGVycm9yLCB1bmxlc3MgYW5vdGhlciBlcnJvciB3YXMgYWxyZWFkeSByZXBvcnRlZCBhdCBzYW1lCiAgICAgKiAgc291cmNlIHBvc2l0aW9uLgogICAgICogIEBwYXJhbSBmbGFnICAgQSBmbGFnIHRvIHNldCBvbiB0aGUgZGlhZ25vc3RpYwogICAgICogIEBwYXJhbSBwb3MgICAgVGhlIHNvdXJjZSBwb3NpdGlvbiBhdCB3aGljaCB0byByZXBvcnQgdGhlIGVycm9yLgogICAgICogIEBwYXJhbSBlcnJvcktleSAgICBUaGUga2V5IGZvciB0aGUgbG9jYWxpemVkIGVycm9yIG1lc3NhZ2UuCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIGVycm9yKERpYWdub3N0aWNGbGFnIGZsYWcsIGludCBwb3MsIEVycm9yIGVycm9yS2V5KSB7CiAgICAgICAgcmVwb3J0KGRpYWdzLmVycm9yKGZsYWcsIHNvdXJjZSwgd3JhcChwb3MpLCBlcnJvcktleSkpOwogICAgfQoKICAgIC8qKiBSZXBvcnQgYSB3YXJuaW5nLCB1bmxlc3Mgc3VwcHJlc3NlZCBieSB0aGUgIC1ub3dhcm4gb3B0aW9uIG9yIHRoZQogICAgICogIG1heGltdW0gbnVtYmVyIG9mIHdhcm5pbmdzIGhhcyBiZWVuIHJlYWNoZWQuCiAgICAgKiAgQHBhcmFtIGtleSAgICBUaGUga2V5IGZvciB0aGUgbG9jYWxpemVkIHdhcm5pbmcgbWVzc2FnZS4KICAgICAqICBAcGFyYW0gYXJncyAgIEZpZWxkcyBvZiB0aGUgd2FybmluZyBtZXNzYWdlLgogICAgICovCiAgICBwdWJsaWMgdm9pZCB3YXJuaW5nKFN0cmluZyBrZXksIE9iamVjdCAuLi4gYXJncykgewogICAgICAgIHdhcm5pbmcoZGlhZ3Mud2FybmluZ0tleShrZXksIGFyZ3MpKTsKICAgIH0KCiAgICAvKiogUmVwb3J0IGEgd2FybmluZywgdW5sZXNzIHN1cHByZXNzZWQgYnkgdGhlICAtbm93YXJuIG9wdGlvbiBvciB0aGUKICAgICAqICBtYXhpbXVtIG51bWJlciBvZiB3YXJuaW5ncyBoYXMgYmVlbiByZWFjaGVkLgogICAgICogIEBwYXJhbSB3YXJuaW5nS2V5ICAgIFRoZSBrZXkgZm9yIHRoZSBsb2NhbGl6ZWQgd2FybmluZyBtZXNzYWdlLgogICAgICovCiAgICBwdWJsaWMgdm9pZCB3YXJuaW5nKFdhcm5pbmcgd2FybmluZ0tleSkgewogICAgICAgIHJlcG9ydChkaWFncy53YXJuaW5nKG51bGwsIHNvdXJjZSwgbnVsbCwgd2FybmluZ0tleSkpOwogICAgfQoKICAgIC8qKiBSZXBvcnQgYSBsaW50IHdhcm5pbmcsIHVubGVzcyBzdXBwcmVzc2VkIGJ5IHRoZSAgLW5vd2FybiBvcHRpb24gb3IgdGhlCiAgICAgKiAgbWF4aW11bSBudW1iZXIgb2Ygd2FybmluZ3MgaGFzIGJlZW4gcmVhY2hlZC4KICAgICAqICBAcGFyYW0gbGMgICAgIFRoZSBsaW50IGNhdGVnb3J5IGZvciB0aGUgZGlhZ25vc3RpYwogICAgICogIEBwYXJhbSBrZXkgICAgVGhlIGtleSBmb3IgdGhlIGxvY2FsaXplZCB3YXJuaW5nIG1lc3NhZ2UuCiAgICAgKiAgQHBhcmFtIGFyZ3MgICBGaWVsZHMgb2YgdGhlIHdhcm5pbmcgbWVzc2FnZS4KICAgICAqLwogICAgcHVibGljIHZvaWQgd2FybmluZyhMaW50Q2F0ZWdvcnkgbGMsIFN0cmluZyBrZXksIE9iamVjdCAuLi4gYXJncykgewogICAgICAgIHdhcm5pbmcobGMsIGRpYWdzLndhcm5pbmdLZXkoa2V5LCBhcmdzKSk7CiAgICB9CgogICAgLyoqIFJlcG9ydCBhIGxpbnQgd2FybmluZywgdW5sZXNzIHN1cHByZXNzZWQgYnkgdGhlICAtbm93YXJuIG9wdGlvbiBvciB0aGUKICAgICAqICBtYXhpbXVtIG51bWJlciBvZiB3YXJuaW5ncyBoYXMgYmVlbiByZWFjaGVkLgogICAgICogIEBwYXJhbSBsYyAgICAgVGhlIGxpbnQgY2F0ZWdvcnkgZm9yIHRoZSBkaWFnbm9zdGljCiAgICAgKiAgQHBhcmFtIHdhcm5pbmdLZXkgICAgVGhlIGtleSBmb3IgdGhlIGxvY2FsaXplZCB3YXJuaW5nIG1lc3NhZ2UuCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHdhcm5pbmcoTGludENhdGVnb3J5IGxjLCBXYXJuaW5nIHdhcm5pbmdLZXkpIHsKICAgICAgICByZXBvcnQoZGlhZ3Mud2FybmluZyhsYywgbnVsbCwgbnVsbCwgd2FybmluZ0tleSkpOwogICAgfQoKICAgIC8qKiBSZXBvcnQgYSB3YXJuaW5nLCB1bmxlc3Mgc3VwcHJlc3NlZCBieSB0aGUgIC1ub3dhcm4gb3B0aW9uIG9yIHRoZQogICAgICogIG1heGltdW0gbnVtYmVyIG9mIHdhcm5pbmdzIGhhcyBiZWVuIHJlYWNoZWQuCiAgICAgKiAgQHBhcmFtIHBvcyAgICBUaGUgc291cmNlIHBvc2l0aW9uIGF0IHdoaWNoIHRvIHJlcG9ydCB0aGUgd2FybmluZy4KICAgICAqICBAcGFyYW0ga2V5ICAgIFRoZSBrZXkgZm9yIHRoZSBsb2NhbGl6ZWQgd2FybmluZyBtZXNzYWdlLgogICAgICogIEBwYXJhbSBhcmdzICAgRmllbGRzIG9mIHRoZSB3YXJuaW5nIG1lc3NhZ2UuCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHdhcm5pbmcoRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcywgU3RyaW5nIGtleSwgT2JqZWN0IC4uLiBhcmdzKSB7CiAgICAgICAgd2FybmluZyhwb3MsIGRpYWdzLndhcm5pbmdLZXkoa2V5LCBhcmdzKSk7CiAgICB9CgogICAgLyoqIFJlcG9ydCBhIHdhcm5pbmcsIHVubGVzcyBzdXBwcmVzc2VkIGJ5IHRoZSAgLW5vd2FybiBvcHRpb24gb3IgdGhlCiAgICAgKiAgbWF4aW11bSBudW1iZXIgb2Ygd2FybmluZ3MgaGFzIGJlZW4gcmVhY2hlZC4KICAgICAqICBAcGFyYW0gcG9zICAgIFRoZSBzb3VyY2UgcG9zaXRpb24gYXQgd2hpY2ggdG8gcmVwb3J0IHRoZSB3YXJuaW5nLgogICAgICogIEBwYXJhbSB3YXJuaW5nS2V5ICAgIFRoZSBrZXkgZm9yIHRoZSBsb2NhbGl6ZWQgd2FybmluZyBtZXNzYWdlLgogICAgICovCiAgICBwdWJsaWMgdm9pZCB3YXJuaW5nKERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIFdhcm5pbmcgd2FybmluZ0tleSkgewogICAgICAgIHJlcG9ydChkaWFncy53YXJuaW5nKG51bGwsIHNvdXJjZSwgcG9zLCB3YXJuaW5nS2V5KSk7CiAgICB9CgogICAgLyoqIFJlcG9ydCBhIGxpbnQgd2FybmluZywgdW5sZXNzIHN1cHByZXNzZWQgYnkgdGhlICAtbm93YXJuIG9wdGlvbiBvciB0aGUKICAgICAqICBtYXhpbXVtIG51bWJlciBvZiB3YXJuaW5ncyBoYXMgYmVlbiByZWFjaGVkLgogICAgICogIEBwYXJhbSBsYyAgICAgVGhlIGxpbnQgY2F0ZWdvcnkgZm9yIHRoZSBkaWFnbm9zdGljCiAgICAgKiAgQHBhcmFtIHBvcyAgICBUaGUgc291cmNlIHBvc2l0aW9uIGF0IHdoaWNoIHRvIHJlcG9ydCB0aGUgd2FybmluZy4KICAgICAqICBAcGFyYW0ga2V5ICAgIFRoZSBrZXkgZm9yIHRoZSBsb2NhbGl6ZWQgd2FybmluZyBtZXNzYWdlLgogICAgICogIEBwYXJhbSBhcmdzICAgRmllbGRzIG9mIHRoZSB3YXJuaW5nIG1lc3NhZ2UuCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHdhcm5pbmcoTGludENhdGVnb3J5IGxjLCBEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBTdHJpbmcga2V5LCBPYmplY3QgLi4uIGFyZ3MpIHsKICAgICAgICB3YXJuaW5nKGxjLCBwb3MsIGRpYWdzLndhcm5pbmdLZXkoa2V5LCBhcmdzKSk7CiAgICB9CgogICAgLyoqIFJlcG9ydCBhIGxpbnQgd2FybmluZywgdW5sZXNzIHN1cHByZXNzZWQgYnkgdGhlICAtbm93YXJuIG9wdGlvbiBvciB0aGUKICAgICAqICBtYXhpbXVtIG51bWJlciBvZiB3YXJuaW5ncyBoYXMgYmVlbiByZWFjaGVkLgogICAgICogIEBwYXJhbSBsYyAgICAgVGhlIGxpbnQgY2F0ZWdvcnkgZm9yIHRoZSBkaWFnbm9zdGljCiAgICAgKiAgQHBhcmFtIHBvcyAgICBUaGUgc291cmNlIHBvc2l0aW9uIGF0IHdoaWNoIHRvIHJlcG9ydCB0aGUgd2FybmluZy4KICAgICAqICBAcGFyYW0gd2FybmluZ0tleSAgICBUaGUga2V5IGZvciB0aGUgbG9jYWxpemVkIHdhcm5pbmcgbWVzc2FnZS4KICAgICAqLwogICAgcHVibGljIHZvaWQgd2FybmluZyhMaW50Q2F0ZWdvcnkgbGMsIERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIFdhcm5pbmcgd2FybmluZ0tleSkgewogICAgICAgIHJlcG9ydChkaWFncy53YXJuaW5nKGxjLCBzb3VyY2UsIHBvcywgd2FybmluZ0tleSkpOwogICAgfQoKICAgIC8qKiBSZXBvcnQgYSB3YXJuaW5nLCB1bmxlc3Mgc3VwcHJlc3NlZCBieSB0aGUgIC1ub3dhcm4gb3B0aW9uIG9yIHRoZQogICAgICogIG1heGltdW0gbnVtYmVyIG9mIHdhcm5pbmdzIGhhcyBiZWVuIHJlYWNoZWQuCiAgICAgKiAgQHBhcmFtIHBvcyAgICBUaGUgc291cmNlIHBvc2l0aW9uIGF0IHdoaWNoIHRvIHJlcG9ydCB0aGUgd2FybmluZy4KICAgICAqICBAcGFyYW0ga2V5ICAgIFRoZSBrZXkgZm9yIHRoZSBsb2NhbGl6ZWQgd2FybmluZyBtZXNzYWdlLgogICAgICogIEBwYXJhbSBhcmdzICAgRmllbGRzIG9mIHRoZSB3YXJuaW5nIG1lc3NhZ2UuCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHdhcm5pbmcoaW50IHBvcywgU3RyaW5nIGtleSwgT2JqZWN0IC4uLiBhcmdzKSB7CiAgICAgICAgd2FybmluZyhwb3MsIGRpYWdzLndhcm5pbmdLZXkoa2V5LCBhcmdzKSk7CiAgICB9CgogICAgLyoqIFJlcG9ydCBhIHdhcm5pbmcsIHVubGVzcyBzdXBwcmVzc2VkIGJ5IHRoZSAgLW5vd2FybiBvcHRpb24gb3IgdGhlCiAgICAgKiAgbWF4aW11bSBudW1iZXIgb2Ygd2FybmluZ3MgaGFzIGJlZW4gcmVhY2hlZC4KICAgICAqICBAcGFyYW0gcG9zICAgIFRoZSBzb3VyY2UgcG9zaXRpb24gYXQgd2hpY2ggdG8gcmVwb3J0IHRoZSB3YXJuaW5nLgogICAgICogIEBwYXJhbSB3YXJuaW5nS2V5ICAgIFRoZSBrZXkgZm9yIHRoZSBsb2NhbGl6ZWQgd2FybmluZyBtZXNzYWdlLgogICAgICovCiAgICBwdWJsaWMgdm9pZCB3YXJuaW5nKGludCBwb3MsIFdhcm5pbmcgd2FybmluZ0tleSkgewogICAgICAgIHJlcG9ydChkaWFncy53YXJuaW5nKG51bGwsIHNvdXJjZSwgd3JhcChwb3MpLCB3YXJuaW5nS2V5KSk7CiAgICB9CgogICAgLyoqIFJlcG9ydCBhIHdhcm5pbmcuCiAgICAgKiAgQHBhcmFtIHBvcyAgICBUaGUgc291cmNlIHBvc2l0aW9uIGF0IHdoaWNoIHRvIHJlcG9ydCB0aGUgd2FybmluZy4KICAgICAqICBAcGFyYW0ga2V5ICAgIFRoZSBrZXkgZm9yIHRoZSBsb2NhbGl6ZWQgd2FybmluZyBtZXNzYWdlLgogICAgICogIEBwYXJhbSBhcmdzICAgRmllbGRzIG9mIHRoZSB3YXJuaW5nIG1lc3NhZ2UuCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIG1hbmRhdG9yeVdhcm5pbmcoRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcywgU3RyaW5nIGtleSwgT2JqZWN0IC4uLiBhcmdzKSB7CiAgICAgICAgbWFuZGF0b3J5V2FybmluZyhwb3MsIGRpYWdzLndhcm5pbmdLZXkoa2V5LCBhcmdzKSk7CiAgICB9CgogICAgLyoqIFJlcG9ydCBhIHdhcm5pbmcuCiAgICAgKiAgQHBhcmFtIHBvcyAgICBUaGUgc291cmNlIHBvc2l0aW9uIGF0IHdoaWNoIHRvIHJlcG9ydCB0aGUgd2FybmluZy4KICAgICAqICBAcGFyYW0gd2FybmluZ0tleSAgICBUaGUga2V5IGZvciB0aGUgbG9jYWxpemVkIHdhcm5pbmcgbWVzc2FnZS4KICAgICAqLwogICAgcHVibGljIHZvaWQgbWFuZGF0b3J5V2FybmluZyhEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBXYXJuaW5nIHdhcm5pbmdLZXkpIHsKICAgICAgICByZXBvcnQoZGlhZ3MubWFuZGF0b3J5V2FybmluZyhudWxsLCBzb3VyY2UsIHBvcywgd2FybmluZ0tleSkpOwogICAgfQoKICAgIC8qKiBSZXBvcnQgYSB3YXJuaW5nLgogICAgICogIEBwYXJhbSBsYyAgICAgVGhlIGxpbnQgY2F0ZWdvcnkgZm9yIHRoZSBkaWFnbm9zdGljCiAgICAgKiAgQHBhcmFtIHBvcyAgICBUaGUgc291cmNlIHBvc2l0aW9uIGF0IHdoaWNoIHRvIHJlcG9ydCB0aGUgd2FybmluZy4KICAgICAqICBAcGFyYW0ga2V5ICAgIFRoZSBrZXkgZm9yIHRoZSBsb2NhbGl6ZWQgd2FybmluZyBtZXNzYWdlLgogICAgICogIEBwYXJhbSBhcmdzICAgRmllbGRzIG9mIHRoZSB3YXJuaW5nIG1lc3NhZ2UuCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIG1hbmRhdG9yeVdhcm5pbmcoTGludENhdGVnb3J5IGxjLCBEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBTdHJpbmcga2V5LCBPYmplY3QgLi4uIGFyZ3MpIHsKICAgICAgICBtYW5kYXRvcnlXYXJuaW5nKGxjLCBwb3MsIGRpYWdzLndhcm5pbmdLZXkoa2V5LCBhcmdzKSk7CiAgICB9CgogICAgLyoqIFJlcG9ydCBhIHdhcm5pbmcuCiAgICAgKiAgQHBhcmFtIGxjICAgICBUaGUgbGludCBjYXRlZ29yeSBmb3IgdGhlIGRpYWdub3N0aWMKICAgICAqICBAcGFyYW0gcG9zICAgIFRoZSBzb3VyY2UgcG9zaXRpb24gYXQgd2hpY2ggdG8gcmVwb3J0IHRoZSB3YXJuaW5nLgogICAgICogIEBwYXJhbSB3YXJuaW5nS2V5ICAgIFRoZSBrZXkgZm9yIHRoZSBsb2NhbGl6ZWQgd2FybmluZyBtZXNzYWdlLgogICAgICovCiAgICBwdWJsaWMgdm9pZCBtYW5kYXRvcnlXYXJuaW5nKExpbnRDYXRlZ29yeSBsYywgRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcywgV2FybmluZyB3YXJuaW5nS2V5KSB7CiAgICAgICAgcmVwb3J0KGRpYWdzLm1hbmRhdG9yeVdhcm5pbmcobGMsIHNvdXJjZSwgcG9zLCB3YXJuaW5nS2V5KSk7CiAgICB9CgogICAgLyoqIFByb3ZpZGUgYSBub24tZmF0YWwgbm90aWZpY2F0aW9uLCB1bmxlc3Mgc3VwcHJlc3NlZCBieSB0aGUgLW5vd2FybiBvcHRpb24uCiAgICAgKiAgQHBhcmFtIGtleSAgICBUaGUga2V5IGZvciB0aGUgbG9jYWxpemVkIG5vdGlmaWNhdGlvbiBtZXNzYWdlLgogICAgICogIEBwYXJhbSBhcmdzICAgRmllbGRzIG9mIHRoZSBub3RpbnQgYW4gZXJyb3Igb3Igd2FybmluZyBtZXNzYWdlOgogICAgICovCiAgICBwdWJsaWMgdm9pZCBub3RlKFN0cmluZyBrZXksIE9iamVjdCAuLi4gYXJncykgewogICAgICAgIG5vdGUoZGlhZ3Mubm90ZUtleShrZXksIGFyZ3MpKTsKICAgIH0KCiAgICAvKiogUHJvdmlkZSBhIG5vbi1mYXRhbCBub3RpZmljYXRpb24sIHVubGVzcyBzdXBwcmVzc2VkIGJ5IHRoZSAtbm93YXJuIG9wdGlvbi4KICAgICAqICBAcGFyYW0gbm90ZUtleSAgICBUaGUga2V5IGZvciB0aGUgbG9jYWxpemVkIG5vdGlmaWNhdGlvbiBtZXNzYWdlLgogICAgICovCiAgICBwdWJsaWMgdm9pZCBub3RlKE5vdGUgbm90ZUtleSkgewogICAgICAgIHJlcG9ydChkaWFncy5ub3RlKHNvdXJjZSwgbnVsbCwgbm90ZUtleSkpOwogICAgfQoKICAgIC8qKiBQcm92aWRlIGEgbm9uLWZhdGFsIG5vdGlmaWNhdGlvbiwgdW5sZXNzIHN1cHByZXNzZWQgYnkgdGhlIC1ub3dhcm4gb3B0aW9uLgogICAgICogIEBwYXJhbSBrZXkgICAgVGhlIGtleSBmb3IgdGhlIGxvY2FsaXplZCBub3RpZmljYXRpb24gbWVzc2FnZS4KICAgICAqICBAcGFyYW0gYXJncyAgIEZpZWxkcyBvZiB0aGUgbm90aWZpY2F0aW9uIG1lc3NhZ2UuCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIG5vdGUoRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcywgU3RyaW5nIGtleSwgT2JqZWN0IC4uLiBhcmdzKSB7CiAgICAgICAgbm90ZShwb3MsIGRpYWdzLm5vdGVLZXkoa2V5LCBhcmdzKSk7CiAgICB9CgogICAgLyoqIFByb3ZpZGUgYSBub24tZmF0YWwgbm90aWZpY2F0aW9uLCB1bmxlc3Mgc3VwcHJlc3NlZCBieSB0aGUgLW5vd2FybiBvcHRpb24uCiAgICAgKiAgQHBhcmFtIG5vdGVLZXkgICAgVGhlIGtleSBmb3IgdGhlIGxvY2FsaXplZCBub3RpZmljYXRpb24gbWVzc2FnZS4KICAgICAqLwogICAgcHVibGljIHZvaWQgbm90ZShEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBOb3RlIG5vdGVLZXkpIHsKICAgICAgICByZXBvcnQoZGlhZ3Mubm90ZShzb3VyY2UsIHBvcywgbm90ZUtleSkpOwogICAgfQoKICAgIC8qKiBQcm92aWRlIGEgbm9uLWZhdGFsIG5vdGlmaWNhdGlvbiwgdW5sZXNzIHN1cHByZXNzZWQgYnkgdGhlIC1ub3dhcm4gb3B0aW9uLgogICAgICogIEBwYXJhbSBrZXkgICAgVGhlIGtleSBmb3IgdGhlIGxvY2FsaXplZCBub3RpZmljYXRpb24gbWVzc2FnZS4KICAgICAqICBAcGFyYW0gYXJncyAgIEZpZWxkcyBvZiB0aGUgbm90aWZpY2F0aW9uIG1lc3NhZ2UuCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIG5vdGUoaW50IHBvcywgU3RyaW5nIGtleSwgT2JqZWN0IC4uLiBhcmdzKSB7CiAgICAgICAgbm90ZShwb3MsIGRpYWdzLm5vdGVLZXkoa2V5LCBhcmdzKSk7CiAgICB9CgogICAgLyoqIFByb3ZpZGUgYSBub24tZmF0YWwgbm90aWZpY2F0aW9uLCB1bmxlc3Mgc3VwcHJlc3NlZCBieSB0aGUgLW5vd2FybiBvcHRpb24uCiAgICAgKiAgQHBhcmFtIG5vdGVLZXkgICAgVGhlIGtleSBmb3IgdGhlIGxvY2FsaXplZCBub3RpZmljYXRpb24gbWVzc2FnZS4KICAgICAqLwogICAgcHVibGljIHZvaWQgbm90ZShpbnQgcG9zLCBOb3RlIG5vdGVLZXkpIHsKICAgICAgICByZXBvcnQoZGlhZ3Mubm90ZShzb3VyY2UsIHdyYXAocG9zKSwgbm90ZUtleSkpOwogICAgfQoKICAgIC8qKiBQcm92aWRlIGEgbm9uLWZhdGFsIG5vdGlmaWNhdGlvbiwgdW5sZXNzIHN1cHByZXNzZWQgYnkgdGhlIC1ub3dhcm4gb3B0aW9uLgogICAgICogIEBwYXJhbSBrZXkgICAgVGhlIGtleSBmb3IgdGhlIGxvY2FsaXplZCBub3RpZmljYXRpb24gbWVzc2FnZS4KICAgICAqICBAcGFyYW0gYXJncyAgIEZpZWxkcyBvZiB0aGUgbm90aWZpY2F0aW9uIG1lc3NhZ2UuCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIG5vdGUoSmF2YUZpbGVPYmplY3QgZmlsZSwgU3RyaW5nIGtleSwgT2JqZWN0IC4uLiBhcmdzKSB7CiAgICAgICAgbm90ZShmaWxlLCBkaWFncy5ub3RlS2V5KGtleSwgYXJncykpOwogICAgfQoKICAgIC8qKiBQcm92aWRlIGEgbm9uLWZhdGFsIG5vdGlmaWNhdGlvbiwgdW5sZXNzIHN1cHByZXNzZWQgYnkgdGhlIC1ub3dhcm4gb3B0aW9uLgogICAgICogIEBwYXJhbSBub3RlS2V5ICAgIFRoZSBrZXkgZm9yIHRoZSBsb2NhbGl6ZWQgbm90aWZpY2F0aW9uIG1lc3NhZ2UuCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIG5vdGUoSmF2YUZpbGVPYmplY3QgZmlsZSwgTm90ZSBub3RlS2V5KSB7CiAgICAgICAgcmVwb3J0KGRpYWdzLm5vdGUoZ2V0U291cmNlKGZpbGUpLCBudWxsLCBub3RlS2V5KSk7CiAgICB9CgogICAgLyoqIFByb3ZpZGUgYSBub24tZmF0YWwgbm90aWZpY2F0aW9uLCB1bmxlc3Mgc3VwcHJlc3NlZCBieSB0aGUgLW5vd2FybiBvcHRpb24uCiAgICAgKiAgQHBhcmFtIGtleSAgICBUaGUga2V5IGZvciB0aGUgbG9jYWxpemVkIG5vdGlmaWNhdGlvbiBtZXNzYWdlLgogICAgICogIEBwYXJhbSBhcmdzICAgRmllbGRzIG9mIHRoZSBub3RpZmljYXRpb24gbWVzc2FnZS4KICAgICAqLwogICAgcHVibGljIHZvaWQgbWFuZGF0b3J5Tm90ZShmaW5hbCBKYXZhRmlsZU9iamVjdCBmaWxlLCBTdHJpbmcga2V5LCBPYmplY3QgLi4uIGFyZ3MpIHsKICAgICAgICBtYW5kYXRvcnlOb3RlKGZpbGUsIGRpYWdzLm5vdGVLZXkoa2V5LCBhcmdzKSk7CiAgICB9CgogICAgLyoqIFByb3ZpZGUgYSBub24tZmF0YWwgbm90aWZpY2F0aW9uLCB1bmxlc3Mgc3VwcHJlc3NlZCBieSB0aGUgLW5vd2FybiBvcHRpb24uCiAgICAgKiAgQHBhcmFtIG5vdGVLZXkgICAgVGhlIGtleSBmb3IgdGhlIGxvY2FsaXplZCBub3RpZmljYXRpb24gbWVzc2FnZS4KICAgICAqLwogICAgcHVibGljIHZvaWQgbWFuZGF0b3J5Tm90ZShmaW5hbCBKYXZhRmlsZU9iamVjdCBmaWxlLCBOb3RlIG5vdGVLZXkpIHsKICAgICAgICByZXBvcnQoZGlhZ3MubWFuZGF0b3J5Tm90ZShnZXRTb3VyY2UoZmlsZSksIG5vdGVLZXkpKTsKICAgIH0KCiAgICBwcm90ZWN0ZWQgYWJzdHJhY3Qgdm9pZCByZXBvcnQoSkNEaWFnbm9zdGljIGRpYWdub3N0aWMpOwoKICAgIHByb3RlY3RlZCBhYnN0cmFjdCB2b2lkIGRpcmVjdEVycm9yKFN0cmluZyBrZXksIE9iamVjdC4uLiBhcmdzKTsKCiAgICBwcml2YXRlIERpYWdub3N0aWNQb3NpdGlvbiB3cmFwKGludCBwb3MpIHsKICAgICAgICByZXR1cm4gKHBvcyA9PSBQb3NpdGlvbi5OT1BPUyA/IG51bGwgOiBuZXcgU2ltcGxlRGlhZ25vc3RpY1Bvc2l0aW9uKHBvcykpOwogICAgfQp9ClBLAwQKAAAIAAAGO6lKjt6eFT8IAAA/CAAAKgAAAGNvbS9zdW4vdG9vbHMvamF2YWMvdXRpbC9Nb2R1bGVIZWxwZXIuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAxNSwgMjAxNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWw7CgppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkpESzlXcmFwcGVycy5Nb2R1bGU7CgpwdWJsaWMgY2xhc3MgTW9kdWxlSGVscGVyIHsKCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmdbXSBqYXZhY0ludGVybmFsUGFja2FnZXMgPSBuZXcgU3RyaW5nW10gewogICAgICAgICAgICAiY29tLnN1bi50b29scy5qYXZhYy5hcGkiLAogICAgICAgICAgICAiY29tLnN1bi50b29scy5qYXZhYy5jb2RlIiwKICAgICAgICAgICAgImNvbS5zdW4udG9vbHMuamF2YWMuY29tcCIsCiAgICAgICAgICAgICJjb20uc3VuLnRvb2xzLmphdmFjLmZpbGUiLAogICAgICAgICAgICAiY29tLnN1bi50b29scy5qYXZhYy5qdm0iLAogICAgICAgICAgICAiY29tLnN1bi50b29scy5qYXZhYy5tYWluIiwKICAgICAgICAgICAgImNvbS5zdW4udG9vbHMuamF2YWMubW9kZWwiLAogICAgICAgICAgICAiY29tLnN1bi50b29scy5qYXZhYy5wYXJzZXIiLAogICAgICAgICAgICAiY29tLnN1bi50b29scy5qYXZhYy5wbGF0Zm9ybSIsCiAgICAgICAgICAgICJjb20uc3VuLnRvb2xzLmphdmFjLnByb2Nlc3NpbmciLAogICAgICAgICAgICAiY29tLnN1bi50b29scy5qYXZhYy50cmVlIiwKICAgICAgICAgICAgImNvbS5zdW4udG9vbHMuamF2YWMudXRpbCIsCgogICAgICAgICAgICAiY29tLnN1bi50b29scy5kb2NsaW50IiwKICAgIH07CgogICAgcHVibGljIHN0YXRpYyB2b2lkIGFkZEV4cG9ydHMoTW9kdWxlIGZyb20sIE1vZHVsZSB0bykgewogICAgICAgIGZvciAoU3RyaW5nIHBhY2s6IGphdmFjSW50ZXJuYWxQYWNrYWdlcykgewogICAgICAgICAgICBmcm9tLmFkZEV4cG9ydHMocGFjaywgdG8pOwogICAgICAgIH0KICAgIH0KfQoKUEsDBAoAAAgAAAY7qUrEIPZfok4AAKJOAAA5AAAAY29tL3N1bi90b29scy9qYXZhYy91dGlsL0Fic3RyYWN0RGlhZ25vc3RpY0Zvcm1hdHRlci5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDA4LCAyMDE2LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuamF2YWMudXRpbDsKCmltcG9ydCBqYXZhLm5pby5maWxlLlBhdGg7CmltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOwppbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb247CmltcG9ydCBqYXZhLnV0aWwuRW51bVNldDsKaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOwppbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKaW1wb3J0IGphdmEudXRpbC5NYXA7CmltcG9ydCBqYXZhLnV0aWwuU2V0OwoKaW1wb3J0IGphdmF4LnRvb2xzLkphdmFGaWxlT2JqZWN0OwoKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuYXBpLkRpYWdub3N0aWNGb3JtYXR0ZXI7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmFwaS5EaWFnbm9zdGljRm9ybWF0dGVyLkNvbmZpZ3VyYXRpb24uRGlhZ25vc3RpY1BhcnQ7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmFwaS5EaWFnbm9zdGljRm9ybWF0dGVyLkNvbmZpZ3VyYXRpb24uTXVsdGlsaW5lTGltaXQ7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmFwaS5EaWFnbm9zdGljRm9ybWF0dGVyLlBvc2l0aW9uS2luZDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuYXBpLkZvcm1hdHRhYmxlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLkxpbnQuTGludENhdGVnb3J5OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlByaW50ZXI7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuU3ltYm9sOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlR5cGU7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuVHlwZS5DYXB0dXJlZFR5cGU7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmZpbGUuUGF0aEZpbGVPYmplY3Q7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmp2bS5Qcm9maWxlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5tYWluLk9wdGlvbjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5KQ1RyZWUuKjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5QcmV0dHk7CgppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5KQ0RpYWdub3N0aWMuRGlhZ25vc3RpY1R5cGUuKjsKCi8qKgogKiBUaGlzIGFic3RyYWN0IGNsYXNzIHByb3ZpZGVzIGEgYmFzaWMgaW1wbGVtZW50YXRpb24gb2YgdGhlIGZ1bmN0aW9uYWxpdGllcyB0aGF0IHNob3VsZCBiZSBwcm92aWRlZAogKiBieSBhbnkgZm9ybWF0dGVyIHVzZWQgYnkgamF2YWMuIEFtb25nIHRoZSBtYWluIGZlYXR1cmVzIHByb3ZpZGVkIGJ5IEFic3RyYWN0RGlhZ25vc3RpY0Zvcm1hdHRlciBhcmU6CiAqCiAqIDx1bD4KICogIDxsaT4gUHJvdmlkZXMgYSBzdGFuZGFyZCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgdmlzaXRvci1saWtlIG1ldGhvZHMgZGVmaW5lZCBpbiB0aGUgaW50ZXJmYWNlIERpYWduaXN0aWNGb3JtYXR0ZXIuCiAqICBUaG9zZSBpbXBsZW1lbnRhdGlvbnMgYXJlIHNwZWNpZmljYWxseSB0YXJnZXRpbmcgSkNEaWFnbm9zdGljIG9iamVjdHMuCiAqICA8bGk+IFByb3ZpZGVzIGJhc2ljIHN1cHBvcnQgZm9yIGkxOG4gYW5kIGEgbWV0aG9kIGZvciBleGVjdXRpbmcgYWxsIGxvY2FsZS1kZXBlbmRlbnQgY29udmVyc2lvbnMKICogIDxsaT4gUHJvdmlkZXMgdGhlIGZvcm1hdHRpbmcgbG9naWMgZm9yIHJlbmRlcmluZyB0aGUgYXJndW1lbnRzIG9mIGEgSkNEaWFnbm9zdGljIG9iamVjdC4KICogPC91bD4KICoKICogPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93biByaXNrLgogKiBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogKiBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+CiAqLwpwdWJsaWMgYWJzdHJhY3QgY2xhc3MgQWJzdHJhY3REaWFnbm9zdGljRm9ybWF0dGVyIGltcGxlbWVudHMgRGlhZ25vc3RpY0Zvcm1hdHRlcjxKQ0RpYWdub3N0aWM+IHsKCiAgICAvKioKICAgICAqIEphdmFjTWVzc2FnZXMgb2JqZWN0IHVzZWQgYnkgdGhpcyBmb3JtYXR0ZXIgZm9yIGkxOG4uCiAgICAgKi8KICAgIHByb3RlY3RlZCBKYXZhY01lc3NhZ2VzIG1lc3NhZ2VzOwoKICAgIC8qKgogICAgICogQ29uZmlndXJhdGlvbiBvYmplY3QgdXNlZCBieSB0aGlzIGZvcm1hdHRlcgogICAgICovCiAgICBwcml2YXRlIFNpbXBsZUNvbmZpZ3VyYXRpb24gY29uZmlnOwoKICAgIC8qKgogICAgICogQ3VycmVudCBkZXB0aCBsZXZlbCBvZiB0aGUgZGlzZ25vc3RpYyBiZWluZyBmb3JtYXR0ZWQKICAgICAqICghPSAwIGZvciBzdWJkaWFnbm9zdGljcykKICAgICAqLwogICAgcHJvdGVjdGVkIGludCBkZXB0aCA9IDA7CgogICAgLyoqCiAgICAgKiBBbGwgY2FwdHVyZWQgdHlwZXMgdGhhdCBoYXZlIGJlZW4gZW5jb3VudGVyZWQgZHVyaW5nIGRpYWdub3N0aWMgZm9ybWF0dGluZy4KICAgICAqIFRoaXMgaW5mbyBpcyB1c2VkIGJ5IHRoZSBGb3JtYXR0ZXJQcmludGVyIGluIG9yZGVyIHRvIHByaW50IGZyaWVuZGx5IHVuaXF1ZQogICAgICogaWRzIGZvciBjYXB0dXJlZCB0eXBlcwogICAgICovCiAgICBwcml2YXRlIExpc3Q8VHlwZT4gYWxsQ2FwdHVyZWQgPSBMaXN0Lm5pbCgpOwoKICAgIC8qKgogICAgICogSW5pdGlhbGl6ZSBhbiBBYnN0cmFjdERpYWdub3N0aWNGb3JtYXR0ZXIgYnkgc2V0dGluZyBpdHMgSmF2YWNNZXNzYWdlcyBvYmplY3QuCiAgICAgKiBAcGFyYW0gbWVzc2FnZXMKICAgICAqLwogICAgcHJvdGVjdGVkIEFic3RyYWN0RGlhZ25vc3RpY0Zvcm1hdHRlcihKYXZhY01lc3NhZ2VzIG1lc3NhZ2VzLCBTaW1wbGVDb25maWd1cmF0aW9uIGNvbmZpZykgewogICAgICAgIHRoaXMubWVzc2FnZXMgPSBtZXNzYWdlczsKICAgICAgICB0aGlzLmNvbmZpZyA9IGNvbmZpZzsKICAgIH0KCiAgICBwdWJsaWMgU3RyaW5nIGZvcm1hdEtpbmQoSkNEaWFnbm9zdGljIGQsIExvY2FsZSBsKSB7CiAgICAgICAgc3dpdGNoIChkLmdldFR5cGUoKSkgewogICAgICAgICAgICBjYXNlIEZSQUdNRU5UOiByZXR1cm4gIiI7CiAgICAgICAgICAgIGNhc2UgTk9URTogICAgIHJldHVybiBsb2NhbGl6ZShsLCAiY29tcGlsZXIubm90ZS5ub3RlIik7CiAgICAgICAgICAgIGNhc2UgV0FSTklORzogIHJldHVybiBsb2NhbGl6ZShsLCAiY29tcGlsZXIud2Fybi53YXJuaW5nIik7CiAgICAgICAgICAgIGNhc2UgRVJST1I6ICAgIHJldHVybiBsb2NhbGl6ZShsLCAiY29tcGlsZXIuZXJyLmVycm9yIik7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoIlVua25vd24gZGlhZ25vc3RpYyB0eXBlOiAiICsgZC5nZXRUeXBlKCkpOwogICAgICAgIH0KICAgIH0KCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBTdHJpbmcgZm9ybWF0KEpDRGlhZ25vc3RpYyBkLCBMb2NhbGUgbG9jYWxlKSB7CiAgICAgICAgYWxsQ2FwdHVyZWQgPSBMaXN0Lm5pbCgpOwogICAgICAgIHJldHVybiBmb3JtYXREaWFnbm9zdGljKGQsIGxvY2FsZSk7CiAgICB9CgogICAgcHJvdGVjdGVkIGFic3RyYWN0IFN0cmluZyBmb3JtYXREaWFnbm9zdGljKEpDRGlhZ25vc3RpYyBkLCBMb2NhbGUgbG9jYWxlKTsKCiAgICBwdWJsaWMgU3RyaW5nIGZvcm1hdFBvc2l0aW9uKEpDRGlhZ25vc3RpYyBkLCBQb3NpdGlvbktpbmQgcGssTG9jYWxlIGwpIHsKICAgICAgICBBc3NlcnQuY2hlY2soZC5nZXRQb3NpdGlvbigpICE9IFBvc2l0aW9uLk5PUE9TKTsKICAgICAgICByZXR1cm4gU3RyaW5nLnZhbHVlT2YoZ2V0UG9zaXRpb24oZCwgcGspKTsKICAgIH0KICAgIC8vd2hlcmUKICAgIHByaXZhdGUgbG9uZyBnZXRQb3NpdGlvbihKQ0RpYWdub3N0aWMgZCwgUG9zaXRpb25LaW5kIHBrKSB7CiAgICAgICAgc3dpdGNoIChwaykgewogICAgICAgICAgICBjYXNlIFNUQVJUOiByZXR1cm4gZC5nZXRJbnRTdGFydFBvc2l0aW9uKCk7CiAgICAgICAgICAgIGNhc2UgRU5EOiByZXR1cm4gZC5nZXRJbnRFbmRQb3NpdGlvbigpOwogICAgICAgICAgICBjYXNlIExJTkU6IHJldHVybiBkLmdldExpbmVOdW1iZXIoKTsKICAgICAgICAgICAgY2FzZSBDT0xVTU46IHJldHVybiBkLmdldENvbHVtbk51bWJlcigpOwogICAgICAgICAgICBjYXNlIE9GRlNFVDogcmV0dXJuIGQuZ2V0SW50UG9zaXRpb24oKTsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigiVW5rbm93biBkaWFnbm9zdGljIHBvc2l0aW9uOiAiICsgcGspOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgU3RyaW5nIGZvcm1hdFNvdXJjZShKQ0RpYWdub3N0aWMgZCwgYm9vbGVhbiBmdWxsbmFtZSwgTG9jYWxlIGwpIHsKICAgICAgICBKYXZhRmlsZU9iamVjdCBmbyA9IGQuZ2V0U291cmNlKCk7CiAgICAgICAgaWYgKGZvID09IG51bGwpCiAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsgLy8gZCBzaG91bGQgaGF2ZSBzb3VyY2Ugc2V0CiAgICAgICAgaWYgKGZ1bGxuYW1lKQogICAgICAgICAgICByZXR1cm4gZm8uZ2V0TmFtZSgpOwogICAgICAgIGVsc2UgaWYgKGZvIGluc3RhbmNlb2YgUGF0aEZpbGVPYmplY3QpCiAgICAgICAgICAgIHJldHVybiAoKFBhdGhGaWxlT2JqZWN0KSBmbykuZ2V0U2hvcnROYW1lKCk7CiAgICAgICAgZWxzZQogICAgICAgICAgICByZXR1cm4gUGF0aEZpbGVPYmplY3QuZ2V0U2ltcGxlTmFtZShmbyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBGb3JtYXQgdGhlIGFyZ3VtZW50cyBvZiBhIGdpdmVuIGRpYWdub3N0aWMuCiAgICAgKgogICAgICogQHBhcmFtIGQgZGlhZ25vc3RpYyB3aG9zZSBhcmd1bWVudHMgYXJlIHRvIGJlIGZvcm1hdHRlZAogICAgICogQHBhcmFtIGwgbG9jYWxlIG9iamVjdCB0byBiZSB1c2VkIGZvciBpMThuCiAgICAgKiBAcmV0dXJuIGEgQ29sbGVjdGlvbiB3aG9zZSBlbGVtZW50cyBhcmUgdGhlIGZvcm1hdHRlZCBhcmd1bWVudHMgb2YgdGhlIGRpYWdub3N0aWMKICAgICAqLwogICAgcHJvdGVjdGVkIENvbGxlY3Rpb248U3RyaW5nPiBmb3JtYXRBcmd1bWVudHMoSkNEaWFnbm9zdGljIGQsIExvY2FsZSBsKSB7CiAgICAgICAgTGlzdEJ1ZmZlcjxTdHJpbmc+IGJ1ZiA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICBmb3IgKE9iamVjdCBvIDogZC5nZXRBcmdzKCkpIHsKICAgICAgICAgICBidWYuYXBwZW5kKGZvcm1hdEFyZ3VtZW50KGQsIG8sIGwpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1Zi50b0xpc3QoKTsKICAgIH0KCiAgICAvKioKICAgICAqIEZvcm1hdCBhIHNpbmdsZSBhcmd1bWVudCBvZiBhIGdpdmVuIGRpYWdub3N0aWMuCiAgICAgKgogICAgICogQHBhcmFtIGQgZGlhZ25vc3RpYyB3aG9zZSBhcmd1bWVudCBpcyB0byBiZSBmb3JtYXR0ZWQKICAgICAqIEBwYXJhbSBhcmcgYXJndW1lbnQgdG8gYmUgZm9ybWF0dGVkCiAgICAgKiBAcGFyYW0gbCBsb2NhbGUgb2JqZWN0IHRvIGJlIHVzZWQgZm9yIGkxOG4KICAgICAqIEByZXR1cm4gc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBkaWFnbm9zdGljIGFyZ3VtZW50CiAgICAgKi8KICAgIHByb3RlY3RlZCBTdHJpbmcgZm9ybWF0QXJndW1lbnQoSkNEaWFnbm9zdGljIGQsIE9iamVjdCBhcmcsIExvY2FsZSBsKSB7CiAgICAgICAgaWYgKGFyZyBpbnN0YW5jZW9mIEpDRGlhZ25vc3RpYykgewogICAgICAgICAgICBTdHJpbmcgcyA9IG51bGw7CiAgICAgICAgICAgIGRlcHRoKys7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBzID0gZm9ybWF0TWVzc2FnZSgoSkNEaWFnbm9zdGljKWFyZywgbCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZmluYWxseSB7CiAgICAgICAgICAgICAgICBkZXB0aC0tOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0KICAgICAgICBlbHNlIGlmIChhcmcgaW5zdGFuY2VvZiBKQ0V4cHJlc3Npb24pIHsKICAgICAgICAgICAgcmV0dXJuIGV4cHIyU3RyaW5nKChKQ0V4cHJlc3Npb24pYXJnKTsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAoYXJnIGluc3RhbmNlb2YgSXRlcmFibGU8Pz4gJiYgIShhcmcgaW5zdGFuY2VvZiBQYXRoKSkgewogICAgICAgICAgICByZXR1cm4gZm9ybWF0SXRlcmFibGUoZCwgKEl0ZXJhYmxlPD8+KWFyZywgbCk7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKGFyZyBpbnN0YW5jZW9mIFR5cGUpIHsKICAgICAgICAgICAgcmV0dXJuIHByaW50ZXIudmlzaXQoKFR5cGUpYXJnLCBsKTsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAoYXJnIGluc3RhbmNlb2YgU3ltYm9sKSB7CiAgICAgICAgICAgIHJldHVybiBwcmludGVyLnZpc2l0KChTeW1ib2wpYXJnLCBsKTsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAoYXJnIGluc3RhbmNlb2YgSmF2YUZpbGVPYmplY3QpIHsKICAgICAgICAgICAgcmV0dXJuICgoSmF2YUZpbGVPYmplY3QpYXJnKS5nZXROYW1lKCk7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKGFyZyBpbnN0YW5jZW9mIFByb2ZpbGUpIHsKICAgICAgICAgICAgcmV0dXJuICgoUHJvZmlsZSlhcmcpLm5hbWU7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKGFyZyBpbnN0YW5jZW9mIE9wdGlvbikgewogICAgICAgICAgICByZXR1cm4gKChPcHRpb24pYXJnKS5wcmltYXJ5TmFtZTsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAoYXJnIGluc3RhbmNlb2YgRm9ybWF0dGFibGUpIHsKICAgICAgICAgICAgcmV0dXJuICgoRm9ybWF0dGFibGUpYXJnKS50b1N0cmluZyhsLCBtZXNzYWdlcyk7CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICByZXR1cm4gU3RyaW5nLnZhbHVlT2YoYXJnKTsKICAgICAgICB9CiAgICB9CiAgICAvL3doZXJlCiAgICAgICAgICAgIHByaXZhdGUgU3RyaW5nIGV4cHIyU3RyaW5nKEpDRXhwcmVzc2lvbiB0cmVlKSB7CiAgICAgICAgICAgICAgICBzd2l0Y2godHJlZS5nZXRUYWcoKSkgewogICAgICAgICAgICAgICAgICAgIGNhc2UgUEFSRU5TOgogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZXhwcjJTdHJpbmcoKChKQ1BhcmVucyl0cmVlKS5leHByKTsKICAgICAgICAgICAgICAgICAgICBjYXNlIExBTUJEQToKICAgICAgICAgICAgICAgICAgICBjYXNlIFJFRkVSRU5DRToKICAgICAgICAgICAgICAgICAgICBjYXNlIENPTkRFWFBSOgogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJldHR5LnRvU2ltcGxlU3RyaW5nKHRyZWUpOwogICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgICAgIEFzc2VydC5lcnJvcigidW5leHBlY3RlZCB0cmVlIGtpbmQgIiArIHRyZWUuZ2V0S2luZCgpKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAvKioKICAgICAqIEZvcm1hdCBhbiBpdGVyYWJsZSBhcmd1bWVudCBvZiBhIGdpdmVuIGRpYWdub3N0aWMuCiAgICAgKgogICAgICogQHBhcmFtIGQgZGlhZ25vc3RpYyB3aG9zZSBhcmd1bWVudCBpcyB0byBiZSBmb3JtYXR0ZWQKICAgICAqIEBwYXJhbSBpdCBpdGVyYWJsZSBhcmd1bWVudCB0byBiZSBmb3JtYXR0ZWQKICAgICAqIEBwYXJhbSBsIGxvY2FsZSBvYmplY3QgdG8gYmUgdXNlZCBmb3IgaTE4bgogICAgICogQHJldHVybiBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIGRpYWdub3N0aWMgaXRlcmFibGUgYXJndW1lbnQKICAgICAqLwogICAgcHJvdGVjdGVkIFN0cmluZyBmb3JtYXRJdGVyYWJsZShKQ0RpYWdub3N0aWMgZCwgSXRlcmFibGU8Pz4gaXQsIExvY2FsZSBsKSB7CiAgICAgICAgU3RyaW5nQnVpbGRlciBzYnVmID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKICAgICAgICBTdHJpbmcgc2VwID0gIiI7CiAgICAgICAgZm9yIChPYmplY3QgbyA6IGl0KSB7CiAgICAgICAgICAgIHNidWYuYXBwZW5kKHNlcCk7CiAgICAgICAgICAgIHNidWYuYXBwZW5kKGZvcm1hdEFyZ3VtZW50KGQsIG8sIGwpKTsKICAgICAgICAgICAgc2VwID0gIiwiOwogICAgICAgIH0KICAgICAgICByZXR1cm4gc2J1Zi50b1N0cmluZygpOwogICAgfQoKICAgIC8qKgogICAgICogRm9ybWF0IGFsbCB0aGUgc3ViZGlhZ25vc3RpY3MgYXR0YWNoZWQgdG8gYSBnaXZlbiBkaWFnbm9zdGljLgogICAgICoKICAgICAqIEBwYXJhbSBkIGRpYWdub3N0aWMgd2hvc2Ugc3ViZGlhZ25vc3RpY3MgYXJlIHRvIGJlIGZvcm1hdHRlZAogICAgICogQHBhcmFtIGwgbG9jYWxlIG9iamVjdCB0byBiZSB1c2VkIGZvciBpMThuCiAgICAgKiBAcmV0dXJuIGxpc3Qgb2YgYWxsIHN0cmluZyByZXByZXNlbnRhdGlvbnMgb2YgdGhlIHN1YmRpYWdub3N0aWNzCiAgICAgKi8KICAgIHByb3RlY3RlZCBMaXN0PFN0cmluZz4gZm9ybWF0U3ViZGlhZ25vc3RpY3MoSkNEaWFnbm9zdGljIGQsIExvY2FsZSBsKSB7CiAgICAgICAgTGlzdDxTdHJpbmc+IHN1YmRpYWdub3N0aWNzID0gTGlzdC5uaWwoKTsKICAgICAgICBpbnQgbWF4RGVwdGggPSBjb25maWcuZ2V0TXVsdGlsaW5lTGltaXQoTXVsdGlsaW5lTGltaXQuREVQVEgpOwogICAgICAgIGlmIChtYXhEZXB0aCA9PSAtMSB8fCBkZXB0aCA8IG1heERlcHRoKSB7CiAgICAgICAgICAgIGRlcHRoKys7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBpbnQgbWF4Q291bnQgPSBjb25maWcuZ2V0TXVsdGlsaW5lTGltaXQoTXVsdGlsaW5lTGltaXQuTEVOR1RIKTsKICAgICAgICAgICAgICAgIGludCBjb3VudCA9IDA7CiAgICAgICAgICAgICAgICBmb3IgKEpDRGlhZ25vc3RpYyBkMiA6IGQuZ2V0U3ViZGlhZ25vc3RpY3MoKSkgewogICAgICAgICAgICAgICAgICAgIGlmIChtYXhDb3VudCA9PSAtMSB8fCBjb3VudCA8IG1heENvdW50KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHN1YmRpYWdub3N0aWNzID0gc3ViZGlhZ25vc3RpY3MuYXBwZW5kKGZvcm1hdFN1YmRpYWdub3N0aWMoZCwgZDIsIGwpKTsKICAgICAgICAgICAgICAgICAgICAgICAgY291bnQrKzsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBmaW5hbGx5IHsKICAgICAgICAgICAgICAgIGRlcHRoLS07CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHN1YmRpYWdub3N0aWNzOwogICAgfQoKICAgIC8qKgogICAgICogRm9ybWF0IGEgc3ViZGlhZ25vc3RpY3MgYXR0YWNoZWQgdG8gYSBnaXZlbiBkaWFnbm9zdGljLgogICAgICoKICAgICAqIEBwYXJhbSBwYXJlbnQgbXVsdGlsaW5lIGRpYWdub3N0aWMgd2hvc2Ugc3ViZGlhZ25vc3RpY3MgaXMgdG8gYmUgZm9ybWF0dGVkCiAgICAgKiBAcGFyYW0gc3ViIHN1YmRpYWdub3N0aWMgdG8gYmUgZm9ybWF0dGVkCiAgICAgKiBAcGFyYW0gbCBsb2NhbGUgb2JqZWN0IHRvIGJlIHVzZWQgZm9yIGkxOG4KICAgICAqIEByZXR1cm4gc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBzdWJkaWFnbm9zdGljcwogICAgICovCiAgICBwcm90ZWN0ZWQgU3RyaW5nIGZvcm1hdFN1YmRpYWdub3N0aWMoSkNEaWFnbm9zdGljIHBhcmVudCwgSkNEaWFnbm9zdGljIHN1YiwgTG9jYWxlIGwpIHsKICAgICAgICByZXR1cm4gZm9ybWF0TWVzc2FnZShzdWIsIGwpOwogICAgfQoKICAgIC8qKiBGb3JtYXQgdGhlIGZhdWx0eSBzb3VyY2UgY29kZSBsaW5lIGFuZCBwb2ludCB0byB0aGUgZXJyb3IuCiAgICAgKiAgQHBhcmFtIGQgVGhlIGRpYWdub3N0aWMgZm9yIHdoaWNoIHRoZSBlcnJvciBsaW5lIHNob3VsZCBiZSBwcmludGVkCiAgICAgKi8KICAgIHByb3RlY3RlZCBTdHJpbmcgZm9ybWF0U291cmNlTGluZShKQ0RpYWdub3N0aWMgZCwgaW50IG5TcGFjZXMpIHsKICAgICAgICBTdHJpbmdCdWlsZGVyIGJ1ZiA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CiAgICAgICAgRGlhZ25vc3RpY1NvdXJjZSBzb3VyY2UgPSBkLmdldERpYWdub3N0aWNTb3VyY2UoKTsKICAgICAgICBpbnQgcG9zID0gZC5nZXRJbnRQb3NpdGlvbigpOwogICAgICAgIGlmIChkLmdldEludFBvc2l0aW9uKCkgPT0gUG9zaXRpb24uTk9QT1MpCiAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigpOwogICAgICAgIFN0cmluZyBsaW5lID0gKHNvdXJjZSA9PSBudWxsID8gbnVsbCA6IHNvdXJjZS5nZXRMaW5lKHBvcykpOwogICAgICAgIGlmIChsaW5lID09IG51bGwpCiAgICAgICAgICAgIHJldHVybiAiIjsKICAgICAgICBidWYuYXBwZW5kKGluZGVudChsaW5lLCBuU3BhY2VzKSk7CiAgICAgICAgaW50IGNvbCA9IHNvdXJjZS5nZXRDb2x1bW5OdW1iZXIocG9zLCBmYWxzZSk7CiAgICAgICAgaWYgKGNvbmZpZy5pc0NhcmV0RW5hYmxlZCgpKSB7CiAgICAgICAgICAgIGJ1Zi5hcHBlbmQoIlxuIik7CiAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY29sIC0gMTsgaSsrKSAgewogICAgICAgICAgICAgICAgYnVmLmFwcGVuZCgobGluZS5jaGFyQXQoaSkgPT0gJ1x0JykgPyAiXHQiIDogIiAiKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBidWYuYXBwZW5kKGluZGVudCgiXiIsIG5TcGFjZXMpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1Zi50b1N0cmluZygpOwogICAgfQoKICAgIHByb3RlY3RlZCBTdHJpbmcgZm9ybWF0TGludENhdGVnb3J5KEpDRGlhZ25vc3RpYyBkLCBMb2NhbGUgbCkgewogICAgICAgIExpbnRDYXRlZ29yeSBsYyA9IGQuZ2V0TGludENhdGVnb3J5KCk7CiAgICAgICAgaWYgKGxjID09IG51bGwpCiAgICAgICAgICAgIHJldHVybiAiIjsKICAgICAgICByZXR1cm4gbG9jYWxpemUobCwgImNvbXBpbGVyLndhcm4ubGludE9wdGlvbiIsIGxjLm9wdGlvbik7CiAgICB9CgogICAgLyoqCiAgICAgKiBDb252ZXJ0cyBhIFN0cmluZyBpbnRvIGEgbG9jYWxlLWRlcGVuZGVudCByZXByZXNlbnRhdGlvbiBhY2NvcmRpbmdseSB0byBhIGdpdmVuIGxvY2FsZS4KICAgICAqCiAgICAgKiBAcGFyYW0gbCBsb2NhbGUgb2JqZWN0IHRvIGJlIHVzZWQgZm9yIGkxOG4KICAgICAqIEBwYXJhbSBrZXkgbG9jYWxlLWluZGVwZW5kZW50IGtleSB1c2VkIGZvciBsb29raW5nIHVwIGluIGEgcmVzb3VyY2UgZmlsZQogICAgICogQHBhcmFtIGFyZ3MgbG9jYWxpemF0aW9uIGFyZ3VtZW50cwogICAgICogQHJldHVybiBhIGxvY2FsZS1kZXBlbmRlbnQgc3RyaW5nCiAgICAgKi8KICAgIHByb3RlY3RlZCBTdHJpbmcgbG9jYWxpemUoTG9jYWxlIGwsIFN0cmluZyBrZXksIE9iamVjdC4uLiBhcmdzKSB7CiAgICAgICAgcmV0dXJuIG1lc3NhZ2VzLmdldExvY2FsaXplZFN0cmluZyhsLCBrZXksIGFyZ3MpOwogICAgfQoKICAgIHB1YmxpYyBib29sZWFuIGRpc3BsYXlTb3VyY2UoSkNEaWFnbm9zdGljIGQpIHsKICAgICAgICByZXR1cm4gY29uZmlnLmdldFZpc2libGUoKS5jb250YWlucyhEaWFnbm9zdGljUGFydC5TT1VSQ0UpICYmCiAgICAgICAgICAgICAgICBkLmdldFR5cGUoKSAhPSBGUkFHTUVOVCAmJgogICAgICAgICAgICAgICAgZC5nZXRJbnRQb3NpdGlvbigpICE9IFBvc2l0aW9uLk5PUE9TOwogICAgfQoKICAgIHB1YmxpYyBib29sZWFuIGlzUmF3KCkgewogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICAvKioKICAgICAqIENyZWF0ZXMgYSBzdHJpbmcgd2l0aCBhIGdpdmVuIGFtb3VudCBvZiBlbXB0eSBzcGFjZXMuIFVzZWZ1bCBmb3IKICAgICAqIGluZGVudGluZyB0aGUgdGV4dCBvZiBhIGRpYWdub3N0aWMgbWVzc2FnZS4KICAgICAqCiAgICAgKiBAcGFyYW0gblNwYWNlcyB0aGUgYW1vdW50IG9mIHNwYWNlcyB0byBiZSBhZGRlZCB0byB0aGUgcmVzdWx0IHN0cmluZwogICAgICogQHJldHVybiB0aGUgaW5kZW50YXRpb24gc3RyaW5nCiAgICAgKi8KICAgIHByb3RlY3RlZCBTdHJpbmcgaW5kZW50U3RyaW5nKGludCBuU3BhY2VzKSB7CiAgICAgICAgU3RyaW5nIHNwYWNlcyA9ICIgICAgICAgICAgICAgICAgICAgICAgICAiOwogICAgICAgIGlmIChuU3BhY2VzIDw9IHNwYWNlcy5sZW5ndGgoKSkKICAgICAgICAgICAgcmV0dXJuIHNwYWNlcy5zdWJzdHJpbmcoMCwgblNwYWNlcyk7CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIFN0cmluZ0J1aWxkZXIgYnVmID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKICAgICAgICAgICAgZm9yIChpbnQgaSA9IDAgOyBpIDwgblNwYWNlcyA7IGkrKykKICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQoIiAiKTsKICAgICAgICAgICAgcmV0dXJuIGJ1Zi50b1N0cmluZygpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEluZGVudCBhIHN0cmluZyBieSBwcmVwZW5kaW5nIGEgZ2l2ZW4gYW1vdW50IG9mIGVtcHR5IHNwYWNlcyB0byBlYWNoIGxpbmUKICAgICAqIG9mIHRoZSBzdHJpbmcuCiAgICAgKgogICAgICogQHBhcmFtIHMgdGhlIHN0cmluZyB0byBiZSBpbmRlbnRlZAogICAgICogQHBhcmFtIG5TcGFjZXMgdGhlIGFtb3VudCBvZiBzcGFjZXMgdGhhdCBzaG91bGQgYmUgcHJlcGVuZGVkIHRvIGVhY2ggbGluZQogICAgICogb2YgdGhlIHN0cmluZwogICAgICogQHJldHVybiBhbiBpbmRlbnRlZCBzdHJpbmcKICAgICAqLwogICAgcHJvdGVjdGVkIFN0cmluZyBpbmRlbnQoU3RyaW5nIHMsIGludCBuU3BhY2VzKSB7CiAgICAgICAgU3RyaW5nIGluZGVudCA9IGluZGVudFN0cmluZyhuU3BhY2VzKTsKICAgICAgICBTdHJpbmdCdWlsZGVyIGJ1ZiA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CiAgICAgICAgU3RyaW5nIG5sID0gIiI7CiAgICAgICAgZm9yIChTdHJpbmcgbGluZSA6IHMuc3BsaXQoIlxuIikpIHsKICAgICAgICAgICAgYnVmLmFwcGVuZChubCk7CiAgICAgICAgICAgIGJ1Zi5hcHBlbmQoaW5kZW50ICsgbGluZSk7CiAgICAgICAgICAgIG5sID0gIlxuIjsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1Zi50b1N0cmluZygpOwogICAgfQoKICAgIHB1YmxpYyBTaW1wbGVDb25maWd1cmF0aW9uIGdldENvbmZpZ3VyYXRpb24oKSB7CiAgICAgICAgcmV0dXJuIGNvbmZpZzsKICAgIH0KCiAgICBzdGF0aWMgcHVibGljIGNsYXNzIFNpbXBsZUNvbmZpZ3VyYXRpb24gaW1wbGVtZW50cyBDb25maWd1cmF0aW9uIHsKCiAgICAgICAgcHJvdGVjdGVkIE1hcDxNdWx0aWxpbmVMaW1pdCwgSW50ZWdlcj4gbXVsdGlsaW5lTGltaXRzOwogICAgICAgIHByb3RlY3RlZCBFbnVtU2V0PERpYWdub3N0aWNQYXJ0PiB2aXNpYmxlUGFydHM7CiAgICAgICAgcHJvdGVjdGVkIGJvb2xlYW4gY2FyZXRFbmFibGVkOwoKICAgICAgICBwdWJsaWMgU2ltcGxlQ29uZmlndXJhdGlvbihTZXQ8RGlhZ25vc3RpY1BhcnQ+IHBhcnRzKSB7CiAgICAgICAgICAgIG11bHRpbGluZUxpbWl0cyA9IG5ldyBIYXNoTWFwPD4oKTsKICAgICAgICAgICAgc2V0VmlzaWJsZShwYXJ0cyk7CiAgICAgICAgICAgIHNldE11bHRpbGluZUxpbWl0KE11bHRpbGluZUxpbWl0LkRFUFRILCAtMSk7CiAgICAgICAgICAgIHNldE11bHRpbGluZUxpbWl0KE11bHRpbGluZUxpbWl0LkxFTkdUSCwgLTEpOwogICAgICAgICAgICBzZXRDYXJldEVuYWJsZWQodHJ1ZSk7CiAgICAgICAgfQoKICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygiZmFsbHRocm91Z2giKQogICAgICAgIHB1YmxpYyBTaW1wbGVDb25maWd1cmF0aW9uKE9wdGlvbnMgb3B0aW9ucywgU2V0PERpYWdub3N0aWNQYXJ0PiBwYXJ0cykgewogICAgICAgICAgICB0aGlzKHBhcnRzKTsKICAgICAgICAgICAgU3RyaW5nIHNob3dTb3VyY2UgPSBudWxsOwogICAgICAgICAgICBpZiAoKHNob3dTb3VyY2UgPSBvcHRpb25zLmdldCgiZGlhZ3Muc2hvd1NvdXJjZSIpKSAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICBpZiAoc2hvd1NvdXJjZS5lcXVhbHMoInRydWUiKSkKICAgICAgICAgICAgICAgICAgICBzZXRWaXNpYmxlUGFydChEaWFnbm9zdGljUGFydC5TT1VSQ0UsIHRydWUpOwogICAgICAgICAgICAgICAgZWxzZSBpZiAoc2hvd1NvdXJjZS5lcXVhbHMoImZhbHNlIikpCiAgICAgICAgICAgICAgICAgICAgc2V0VmlzaWJsZVBhcnQoRGlhZ25vc3RpY1BhcnQuU09VUkNFLCBmYWxzZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgU3RyaW5nIGRpYWdPcHRzID0gb3B0aW9ucy5nZXQoImRpYWdzLmZvcm1hdHRlck9wdGlvbnMiKTsKICAgICAgICAgICAgaWYgKGRpYWdPcHRzICE9IG51bGwpIHsvL292ZXJyaWRlIC1YRHNob3dTb3VyY2UKICAgICAgICAgICAgICAgIENvbGxlY3Rpb248U3RyaW5nPiBhcmdzID0gQXJyYXlzLmFzTGlzdChkaWFnT3B0cy5zcGxpdCgiLCIpKTsKICAgICAgICAgICAgICAgIGlmIChhcmdzLmNvbnRhaW5zKCJzaG9ydCIpKSB7CiAgICAgICAgICAgICAgICAgICAgc2V0VmlzaWJsZVBhcnQoRGlhZ25vc3RpY1BhcnQuREVUQUlMUywgZmFsc2UpOwogICAgICAgICAgICAgICAgICAgIHNldFZpc2libGVQYXJ0KERpYWdub3N0aWNQYXJ0LlNVQkRJQUdOT1NUSUNTLCBmYWxzZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoYXJncy5jb250YWlucygic291cmNlIikpCiAgICAgICAgICAgICAgICAgICAgc2V0VmlzaWJsZVBhcnQoRGlhZ25vc3RpY1BhcnQuU09VUkNFLCB0cnVlKTsKICAgICAgICAgICAgICAgIGlmIChhcmdzLmNvbnRhaW5zKCItc291cmNlIikpCiAgICAgICAgICAgICAgICAgICAgc2V0VmlzaWJsZVBhcnQoRGlhZ25vc3RpY1BhcnQuU09VUkNFLCBmYWxzZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgU3RyaW5nIG11bHRpUG9saWN5ID0gbnVsbDsKICAgICAgICAgICAgaWYgKChtdWx0aVBvbGljeSA9IG9wdGlvbnMuZ2V0KCJkaWFncy5tdWx0aWxpbmVQb2xpY3kiKSkgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgaWYgKG11bHRpUG9saWN5LmVxdWFscygiZGlzYWJsZWQiKSkKICAgICAgICAgICAgICAgICAgICBzZXRWaXNpYmxlUGFydChEaWFnbm9zdGljUGFydC5TVUJESUFHTk9TVElDUywgZmFsc2UpOwogICAgICAgICAgICAgICAgZWxzZSBpZiAobXVsdGlQb2xpY3kuc3RhcnRzV2l0aCgibGltaXQ6IikpIHsKICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbGltaXRTdHJpbmcgPSBtdWx0aVBvbGljeS5zdWJzdHJpbmcoImxpbWl0OiIubGVuZ3RoKCkpOwogICAgICAgICAgICAgICAgICAgIFN0cmluZ1tdIGxpbWl0cyA9IGxpbWl0U3RyaW5nLnNwbGl0KCI6Iik7CiAgICAgICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChsaW1pdHMubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDI6IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWxpbWl0c1sxXS5lcXVhbHMoIioiKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0TXVsdGlsaW5lTGltaXQoTXVsdGlsaW5lTGltaXQuREVQVEgsIEludGVnZXIucGFyc2VJbnQobGltaXRzWzFdKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDE6IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWxpbWl0c1swXS5lcXVhbHMoIioiKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0TXVsdGlsaW5lTGltaXQoTXVsdGlsaW5lTGltaXQuTEVOR1RILCBJbnRlZ2VyLnBhcnNlSW50KGxpbWl0c1swXSkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGNhdGNoKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBleCkgewogICAgICAgICAgICAgICAgICAgICAgICBzZXRNdWx0aWxpbmVMaW1pdChNdWx0aWxpbmVMaW1pdC5ERVBUSCwgLTEpOwogICAgICAgICAgICAgICAgICAgICAgICBzZXRNdWx0aWxpbmVMaW1pdChNdWx0aWxpbmVMaW1pdC5MRU5HVEgsIC0xKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgU3RyaW5nIHNob3dDYXJldCA9IG51bGw7CiAgICAgICAgICAgIGlmICgoKHNob3dDYXJldCA9IG9wdGlvbnMuZ2V0KCJkaWFncy5zaG93Q2FyZXQiKSkgIT0gbnVsbCkgJiYKICAgICAgICAgICAgICAgIHNob3dDYXJldC5lcXVhbHMoImZhbHNlIikpCiAgICAgICAgICAgICAgICAgICAgc2V0Q2FyZXRFbmFibGVkKGZhbHNlKTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgc2V0Q2FyZXRFbmFibGVkKHRydWUpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIGludCBnZXRNdWx0aWxpbmVMaW1pdChNdWx0aWxpbmVMaW1pdCBsaW1pdCkgewogICAgICAgICAgICByZXR1cm4gbXVsdGlsaW5lTGltaXRzLmdldChsaW1pdCk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgRW51bVNldDxEaWFnbm9zdGljUGFydD4gZ2V0VmlzaWJsZSgpIHsKICAgICAgICAgICAgcmV0dXJuIEVudW1TZXQuY29weU9mKHZpc2libGVQYXJ0cyk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgdm9pZCBzZXRNdWx0aWxpbmVMaW1pdChNdWx0aWxpbmVMaW1pdCBsaW1pdCwgaW50IHZhbHVlKSB7CiAgICAgICAgICAgIG11bHRpbGluZUxpbWl0cy5wdXQobGltaXQsIHZhbHVlIDwgLTEgPyAtMSA6IHZhbHVlKTsKICAgICAgICB9CgoKICAgICAgICBwdWJsaWMgdm9pZCBzZXRWaXNpYmxlKFNldDxEaWFnbm9zdGljUGFydD4gZGlhZ1BhcnRzKSB7CiAgICAgICAgICAgIHZpc2libGVQYXJ0cyA9IEVudW1TZXQuY29weU9mKGRpYWdQYXJ0cyk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgdm9pZCBzZXRWaXNpYmxlUGFydChEaWFnbm9zdGljUGFydCBkaWFnUGFydHMsIGJvb2xlYW4gZW5hYmxlZCkgewogICAgICAgICAgICBpZiAoZW5hYmxlZCkKICAgICAgICAgICAgICAgIHZpc2libGVQYXJ0cy5hZGQoZGlhZ1BhcnRzKTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgdmlzaWJsZVBhcnRzLnJlbW92ZShkaWFnUGFydHMpOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogU2hvd3MgYSAnXicgc2lnbiB1bmRlciB0aGUgc291cmNlIGxpbmUgZGlzcGxheWVkIGJ5IHRoZSBmb3JtYXR0ZXIKICAgICAgICAgKiAoaWYgYXBwbGljYWJsZSkuCiAgICAgICAgICoKICAgICAgICAgKiBAcGFyYW0gY2FyZXRFbmFibGVkIGlmIHRydWUgZW5hYmxlcyBjYXJldAogICAgICAgICAqLwogICAgICAgIHB1YmxpYyB2b2lkIHNldENhcmV0RW5hYmxlZChib29sZWFuIGNhcmV0RW5hYmxlZCkgewogICAgICAgICAgICB0aGlzLmNhcmV0RW5hYmxlZCA9IGNhcmV0RW5hYmxlZDsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIFRlbGxzIHdoZXRoZXIgdGhlIGNhcmV0IGRpc3BsYXkgaXMgYWN0aXZlIG9yIG5vdC4KICAgICAgICAgKgogICAgICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgY2FyZXQgaXMgZW5hYmxlZAogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBib29sZWFuIGlzQ2FyZXRFbmFibGVkKCkgewogICAgICAgICAgICByZXR1cm4gY2FyZXRFbmFibGVkOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgUHJpbnRlciBnZXRQcmludGVyKCkgewogICAgICAgIHJldHVybiBwcmludGVyOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHNldFByaW50ZXIoUHJpbnRlciBwcmludGVyKSB7CiAgICAgICAgdGhpcy5wcmludGVyID0gcHJpbnRlcjsKICAgIH0KCiAgICAvKioKICAgICAqIEFuIGVuaGFuY2VkIHByaW50ZXIgZm9yIGZvcm1hdHRpbmcgdHlwZXMvc3ltYm9scyB1c2VkIGJ5CiAgICAgKiBBYnN0cmFjdERpYWdub3N0aWNGb3JtYXR0ZXIuIFByb3ZpZGVzIGFsdGVybmF0ZSBudW1iZXJpbmcgb2YgY2FwdHVyZWQKICAgICAqIHR5cGVzICh0aGV5IGFyZSBudW1iZXJlZCBzdGFydGluZyBmcm9tIDEgb24gZWFjaCBuZXcgZGlhZ25vc3RpYywgaW5zdGVhZAogICAgICogb2YgcmVseWluZyBvbiB0aGUgdW5kZXJseWluZyBoYXNoY29kZSgpIG1ldGhvZCB3aGljaCBnZW5lcmF0ZXMgdW5zdGFibGUKICAgICAqIG91dHB1dCkuIEFsc28gZGV0ZWN0cyBjeWNsZXMgaW4gd2lsZGNhcmQgbWVzc2FnZXMgKGUuZy4gaWYgdGhlIHdpbGRjYXJkCiAgICAgKiB0eXBlIHJlZmVycmVkIGJ5IGEgZ2l2ZW4gY2FwdHVyZWQgdHlwZSBDIGNvbnRhaW5zIEMgaXRzZWxmKSB3aGljaCBtaWdodAogICAgICogbGVhZCB0byBpbmZpbml0ZSBsb29wcy4KICAgICAqLwogICAgcHJvdGVjdGVkIFByaW50ZXIgcHJpbnRlciA9IG5ldyBQcmludGVyKCkgewoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwcm90ZWN0ZWQgU3RyaW5nIGxvY2FsaXplKExvY2FsZSBsb2NhbGUsIFN0cmluZyBrZXksIE9iamVjdC4uLiBhcmdzKSB7CiAgICAgICAgICAgIHJldHVybiBBYnN0cmFjdERpYWdub3N0aWNGb3JtYXR0ZXIudGhpcy5sb2NhbGl6ZShsb2NhbGUsIGtleSwgYXJncyk7CiAgICAgICAgfQogICAgICAgIEBPdmVycmlkZQogICAgICAgIHByb3RlY3RlZCBTdHJpbmcgY2FwdHVyZWRWYXJJZChDYXB0dXJlZFR5cGUgdCwgTG9jYWxlIGxvY2FsZSkgewogICAgICAgICAgICByZXR1cm4gIiIgKyAoYWxsQ2FwdHVyZWQuaW5kZXhPZih0KSArIDEpOwogICAgICAgIH0KICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgU3RyaW5nIHZpc2l0Q2FwdHVyZWRUeXBlKENhcHR1cmVkVHlwZSB0LCBMb2NhbGUgbG9jYWxlKSB7CiAgICAgICAgICAgIGlmICghYWxsQ2FwdHVyZWQuY29udGFpbnModCkpIHsKICAgICAgICAgICAgICAgIGFsbENhcHR1cmVkID0gYWxsQ2FwdHVyZWQuYXBwZW5kKHQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBzdXBlci52aXNpdENhcHR1cmVkVHlwZSh0LCBsb2NhbGUpOwogICAgICAgIH0KICAgIH07Cn0KUEsDBAoAAAgAANJ9TUqUhrxeUAYAAFAGAAAkAAAAY29tL3N1bi90b29scy9qYXZhYy91dGlsL0ZpbHRlci5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDEwLCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuamF2YWMudXRpbDsKCi8qKgogKiBTaW1wbGUgZmlsdGVyIGFjdGluZyBhcyBhIGJvb2xlYW4gcHJlZGljYXRlLiBNZXRob2QgYWNjZXB0cyByZXR1cm4gdHJ1ZSBpZgogKiB0aGUgc3VwcGxpZWQgZWxlbWVudCBtYXRjaGVzIGFnYWluc3QgdGhlIGZpbHRlci4KICovCnB1YmxpYyBpbnRlcmZhY2UgRmlsdGVyPFQ+IHsKICAgIC8qKgogICAgICogRG9lcyB0aGlzIGVsZW1lbnQgbWF0Y2ggYWdhaW5zdCB0aGUgZmlsdGVyPwogICAgICogQHBhcmFtIHQgZWxlbWVudCB0byBiZSBjaGVja2VkCiAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGVsZW1lbnQgc2F0aXNmeSBjb25zdHJhaW50cyBpbXBvc2VkIGJ5IGZpbHRlcgogICAgICovCiAgICBib29sZWFuIGFjY2VwdHMoVCB0KTsKfQpQSwMECgAACAAABjupSrfPiBTidQAA4nUAACoAAABjb20vc3VuL3Rvb2xzL2phdmFjL3V0aWwvSkNEaWFnbm9zdGljLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDMsIDIwMTUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhYy51dGlsOwoKaW1wb3J0IGphdmEudXRpbC5FbnVtU2V0OwppbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKaW1wb3J0IGphdmEudXRpbC5TZXQ7CmltcG9ydCBqYXZhLnV0aWwuc3RyZWFtLlN0cmVhbTsKCmltcG9ydCBqYXZheC50b29scy5EaWFnbm9zdGljOwppbXBvcnQgamF2YXgudG9vbHMuSmF2YUZpbGVPYmplY3Q7CgppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5hcGkuRGlhZ25vc3RpY0Zvcm1hdHRlcjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5MaW50LkxpbnRDYXRlZ29yeTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5FbmRQb3NUYWJsZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5KQ1RyZWU7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuRGVmaW5lZEJ5LkFwaTsKCmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkpDRGlhZ25vc3RpYy5EaWFnbm9zdGljVHlwZS4qOwoKLyoqIEFuIGFic3RyYWN0aW9uIG9mIGEgZGlhZ25vc3RpYyBtZXNzYWdlIGdlbmVyYXRlZCBieSB0aGUgY29tcGlsZXIuCiAqCiAqICA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiAgSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93biByaXNrLgogKiAgVGhpcyBjb2RlIGFuZCBpdHMgaW50ZXJuYWwgaW50ZXJmYWNlcyBhcmUgc3ViamVjdCB0byBjaGFuZ2Ugb3IKICogIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj4KICovCnB1YmxpYyBjbGFzcyBKQ0RpYWdub3N0aWMgaW1wbGVtZW50cyBEaWFnbm9zdGljPEphdmFGaWxlT2JqZWN0PiB7CiAgICAvKiogQSBmYWN0b3J5IGZvciBjcmVhdGluZyBkaWFnbm9zdGljIG9iamVjdHMuICovCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIEZhY3RvcnkgewogICAgICAgIC8qKiBUaGUgY29udGV4dCBrZXkgZm9yIHRoZSBkaWFnbm9zdGljIGZhY3RvcnkuICovCiAgICAgICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBDb250ZXh0LktleTxKQ0RpYWdub3N0aWMuRmFjdG9yeT4gZGlhZ25vc3RpY0ZhY3RvcnlLZXkgPSBuZXcgQ29udGV4dC5LZXk8PigpOwoKICAgICAgICAvKiogR2V0IHRoZSBGYWN0b3J5IGluc3RhbmNlIGZvciB0aGlzIGNvbnRleHQuICovCiAgICAgICAgcHVibGljIHN0YXRpYyBGYWN0b3J5IGluc3RhbmNlKENvbnRleHQgY29udGV4dCkgewogICAgICAgICAgICBGYWN0b3J5IGluc3RhbmNlID0gY29udGV4dC5nZXQoZGlhZ25vc3RpY0ZhY3RvcnlLZXkpOwogICAgICAgICAgICBpZiAoaW5zdGFuY2UgPT0gbnVsbCkKICAgICAgICAgICAgICAgIGluc3RhbmNlID0gbmV3IEZhY3RvcnkoY29udGV4dCk7CiAgICAgICAgICAgIHJldHVybiBpbnN0YW5jZTsKICAgICAgICB9CgogICAgICAgIERpYWdub3N0aWNGb3JtYXR0ZXI8SkNEaWFnbm9zdGljPiBmb3JtYXR0ZXI7CiAgICAgICAgZmluYWwgU3RyaW5nIHByZWZpeDsKICAgICAgICBmaW5hbCBTZXQ8RGlhZ25vc3RpY0ZsYWc+IGRlZmF1bHRFcnJvckZsYWdzOwoKICAgICAgICAvKiogQ3JlYXRlIGEgbmV3IGRpYWdub3N0aWMgZmFjdG9yeS4gKi8KICAgICAgICBwcm90ZWN0ZWQgRmFjdG9yeShDb250ZXh0IGNvbnRleHQpIHsKICAgICAgICAgICAgdGhpcyhKYXZhY01lc3NhZ2VzLmluc3RhbmNlKGNvbnRleHQpLCAiY29tcGlsZXIiKTsKICAgICAgICAgICAgY29udGV4dC5wdXQoZGlhZ25vc3RpY0ZhY3RvcnlLZXksIHRoaXMpOwoKICAgICAgICAgICAgZmluYWwgT3B0aW9ucyBvcHRpb25zID0gT3B0aW9ucy5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICAgICAgaW5pdE9wdGlvbnMob3B0aW9ucyk7CiAgICAgICAgICAgIG9wdGlvbnMuYWRkTGlzdGVuZXIoKCkgLT4gaW5pdE9wdGlvbnMob3B0aW9ucykpOwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSB2b2lkIGluaXRPcHRpb25zKE9wdGlvbnMgb3B0aW9ucykgewogICAgICAgICAgICBpZiAob3B0aW9ucy5pc1NldCgib25seVN5bnRheEVycm9yc1VucmVjb3ZlcmFibGUiKSkKICAgICAgICAgICAgICAgIGRlZmF1bHRFcnJvckZsYWdzLmFkZChEaWFnbm9zdGljRmxhZy5SRUNPVkVSQUJMRSk7CiAgICAgICAgfQoKICAgICAgICAvKiogQ3JlYXRlIGEgbmV3IGRpYWdub3N0aWMgZmFjdG9yeS4gKi8KICAgICAgICBwdWJsaWMgRmFjdG9yeShKYXZhY01lc3NhZ2VzIG1lc3NhZ2VzLCBTdHJpbmcgcHJlZml4KSB7CiAgICAgICAgICAgIHRoaXMucHJlZml4ID0gcHJlZml4OwogICAgICAgICAgICB0aGlzLmZvcm1hdHRlciA9IG5ldyBCYXNpY0RpYWdub3N0aWNGb3JtYXR0ZXIobWVzc2FnZXMpOwogICAgICAgICAgICBkZWZhdWx0RXJyb3JGbGFncyA9IEVudW1TZXQub2YoRGlhZ25vc3RpY0ZsYWcuTUFOREFUT1JZKTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIENyZWF0ZSBhbiBlcnJvciBkaWFnbm9zdGljCiAgICAgICAgICogIEBwYXJhbSBzb3VyY2UgVGhlIHNvdXJjZSBvZiB0aGUgY29tcGlsYXRpb24gdW5pdCwgaWYgYW55LCBpbiB3aGljaCB0byByZXBvcnQgdGhlIGVycm9yLgogICAgICAgICAqICBAcGFyYW0gcG9zICAgIFRoZSBzb3VyY2UgcG9zaXRpb24gYXQgd2hpY2ggdG8gcmVwb3J0IHRoZSBlcnJvci4KICAgICAgICAgKiAgQHBhcmFtIGtleSAgICBUaGUga2V5IGZvciB0aGUgbG9jYWxpemVkIGVycm9yIG1lc3NhZ2UuCiAgICAgICAgICogIEBwYXJhbSBhcmdzICAgRmllbGRzIG9mIHRoZSBlcnJvciBtZXNzYWdlLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBKQ0RpYWdub3N0aWMgZXJyb3IoCiAgICAgICAgICAgICAgICBEaWFnbm9zdGljRmxhZyBmbGFnLCBEaWFnbm9zdGljU291cmNlIHNvdXJjZSwgRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcywgU3RyaW5nIGtleSwgT2JqZWN0Li4uIGFyZ3MpIHsKICAgICAgICAgICAgcmV0dXJuIGVycm9yKGZsYWcsIHNvdXJjZSwgcG9zLCBlcnJvcktleShrZXksIGFyZ3MpKTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIENyZWF0ZSBhbiBlcnJvciBkaWFnbm9zdGljCiAgICAgICAgICogIEBwYXJhbSBzb3VyY2UgVGhlIHNvdXJjZSBvZiB0aGUgY29tcGlsYXRpb24gdW5pdCwgaWYgYW55LCBpbiB3aGljaCB0byByZXBvcnQgdGhlIGVycm9yLgogICAgICAgICAqICBAcGFyYW0gcG9zICAgIFRoZSBzb3VyY2UgcG9zaXRpb24gYXQgd2hpY2ggdG8gcmVwb3J0IHRoZSBlcnJvci4KICAgICAgICAgKiAgQHBhcmFtIGVycm9yS2V5ICAgIFRoZSBrZXkgZm9yIHRoZSBsb2NhbGl6ZWQgZXJyb3IgbWVzc2FnZS4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgSkNEaWFnbm9zdGljIGVycm9yKAogICAgICAgICAgICAgICAgRGlhZ25vc3RpY0ZsYWcgZmxhZywgRGlhZ25vc3RpY1NvdXJjZSBzb3VyY2UsIERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIEVycm9yIGVycm9yS2V5KSB7CiAgICAgICAgICAgIEpDRGlhZ25vc3RpYyBkaWFnID0gY3JlYXRlKG51bGwsIEVudW1TZXQuY29weU9mKGRlZmF1bHRFcnJvckZsYWdzKSwgc291cmNlLCBwb3MsIGVycm9yS2V5KTsKICAgICAgICAgICAgaWYgKGZsYWcgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgZGlhZy5zZXRGbGFnKGZsYWcpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBkaWFnOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogQ3JlYXRlIGEgd2FybmluZyBkaWFnbm9zdGljIHRoYXQgd2lsbCBub3QgYmUgaGlkZGVuIGJ5IHRoZSAtbm93YXJuIG9yIC1YbGludDpub25lIG9wdGlvbnMuCiAgICAgICAgICogIEBwYXJhbSBsYyAgICAgVGhlIGxpbnQgY2F0ZWdvcnkgZm9yIHRoZSBkaWFnbm9zdGljCiAgICAgICAgICogIEBwYXJhbSBzb3VyY2UgVGhlIHNvdXJjZSBvZiB0aGUgY29tcGlsYXRpb24gdW5pdCwgaWYgYW55LCBpbiB3aGljaCB0byByZXBvcnQgdGhlIHdhcm5pbmcuCiAgICAgICAgICogIEBwYXJhbSBwb3MgICAgVGhlIHNvdXJjZSBwb3NpdGlvbiBhdCB3aGljaCB0byByZXBvcnQgdGhlIHdhcm5pbmcuCiAgICAgICAgICogIEBwYXJhbSBrZXkgICAgVGhlIGtleSBmb3IgdGhlIGxvY2FsaXplZCB3YXJuaW5nIG1lc3NhZ2UuCiAgICAgICAgICogIEBwYXJhbSBhcmdzICAgRmllbGRzIG9mIHRoZSB3YXJuaW5nIG1lc3NhZ2UuCiAgICAgICAgICogIEBzZWUgTWFuZGF0b3J5V2FybmluZ0hhbmRsZXIKICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgSkNEaWFnbm9zdGljIG1hbmRhdG9yeVdhcm5pbmcoCiAgICAgICAgICAgICAgICBMaW50Q2F0ZWdvcnkgbGMsCiAgICAgICAgICAgICAgICBEaWFnbm9zdGljU291cmNlIHNvdXJjZSwgRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcywgU3RyaW5nIGtleSwgT2JqZWN0Li4uIGFyZ3MpIHsKICAgICAgICAgICAgcmV0dXJuIG1hbmRhdG9yeVdhcm5pbmcobGMsIHNvdXJjZSwgcG9zLCB3YXJuaW5nS2V5KGtleSwgYXJncykpOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogQ3JlYXRlIGEgd2FybmluZyBkaWFnbm9zdGljIHRoYXQgd2lsbCBub3QgYmUgaGlkZGVuIGJ5IHRoZSAtbm93YXJuIG9yIC1YbGludDpub25lIG9wdGlvbnMuCiAgICAgICAgICogIEBwYXJhbSBsYyAgICAgVGhlIGxpbnQgY2F0ZWdvcnkgZm9yIHRoZSBkaWFnbm9zdGljCiAgICAgICAgICogIEBwYXJhbSBzb3VyY2UgVGhlIHNvdXJjZSBvZiB0aGUgY29tcGlsYXRpb24gdW5pdCwgaWYgYW55LCBpbiB3aGljaCB0byByZXBvcnQgdGhlIHdhcm5pbmcuCiAgICAgICAgICogIEBwYXJhbSBwb3MgICAgVGhlIHNvdXJjZSBwb3NpdGlvbiBhdCB3aGljaCB0byByZXBvcnQgdGhlIHdhcm5pbmcuCiAgICAgICAgICogIEBwYXJhbSB3YXJuaW5nS2V5ICAgIFRoZSBrZXkgZm9yIHRoZSBsb2NhbGl6ZWQgd2FybmluZyBtZXNzYWdlLgogICAgICAgICAqICBAc2VlIE1hbmRhdG9yeVdhcm5pbmdIYW5kbGVyCiAgICAgICAgICovCiAgICAgICAgcHVibGljIEpDRGlhZ25vc3RpYyBtYW5kYXRvcnlXYXJuaW5nKAogICAgICAgICAgICAgICAgTGludENhdGVnb3J5IGxjLAogICAgICAgICAgICAgICAgRGlhZ25vc3RpY1NvdXJjZSBzb3VyY2UsIERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIFdhcm5pbmcgd2FybmluZ0tleSkgewogICAgICAgICAgICByZXR1cm4gY3JlYXRlKGxjLCBFbnVtU2V0Lm9mKERpYWdub3N0aWNGbGFnLk1BTkRBVE9SWSksIHNvdXJjZSwgcG9zLCB3YXJuaW5nS2V5KTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIENyZWF0ZSBhIHdhcm5pbmcgZGlhZ25vc3RpYy4KICAgICAgICAgKiAgQHBhcmFtIGxjICAgICBUaGUgbGludCBjYXRlZ29yeSBmb3IgdGhlIGRpYWdub3N0aWMKICAgICAgICAgKiAgQHBhcmFtIHNvdXJjZSBUaGUgc291cmNlIG9mIHRoZSBjb21waWxhdGlvbiB1bml0LCBpZiBhbnksIGluIHdoaWNoIHRvIHJlcG9ydCB0aGUgd2FybmluZy4KICAgICAgICAgKiAgQHBhcmFtIHBvcyAgICBUaGUgc291cmNlIHBvc2l0aW9uIGF0IHdoaWNoIHRvIHJlcG9ydCB0aGUgd2FybmluZy4KICAgICAgICAgKiAgQHBhcmFtIGtleSAgICBUaGUga2V5IGZvciB0aGUgbG9jYWxpemVkIGVycm9yIG1lc3NhZ2UuCiAgICAgICAgICogIEBwYXJhbSBhcmdzICAgRmllbGRzIG9mIHRoZSB3YXJuaW5nIG1lc3NhZ2UuCiAgICAgICAgICogIEBzZWUgTWFuZGF0b3J5V2FybmluZ0hhbmRsZXIKICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgSkNEaWFnbm9zdGljIHdhcm5pbmcoCiAgICAgICAgICAgICAgICBMaW50Q2F0ZWdvcnkgbGMsIERpYWdub3N0aWNTb3VyY2Ugc291cmNlLCBEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBTdHJpbmcga2V5LCBPYmplY3QuLi4gYXJncykgewogICAgICAgICAgICByZXR1cm4gd2FybmluZyhsYywgc291cmNlLCBwb3MsIHdhcm5pbmdLZXkoa2V5LCBhcmdzKSk7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBDcmVhdGUgYSB3YXJuaW5nIGRpYWdub3N0aWMuCiAgICAgICAgICogIEBwYXJhbSBsYyAgICAgVGhlIGxpbnQgY2F0ZWdvcnkgZm9yIHRoZSBkaWFnbm9zdGljCiAgICAgICAgICogIEBwYXJhbSBzb3VyY2UgVGhlIHNvdXJjZSBvZiB0aGUgY29tcGlsYXRpb24gdW5pdCwgaWYgYW55LCBpbiB3aGljaCB0byByZXBvcnQgdGhlIHdhcm5pbmcuCiAgICAgICAgICogIEBwYXJhbSBwb3MgICAgVGhlIHNvdXJjZSBwb3NpdGlvbiBhdCB3aGljaCB0byByZXBvcnQgdGhlIHdhcm5pbmcuCiAgICAgICAgICogIEBwYXJhbSB3YXJuaW5nS2V5ICAgIFRoZSBrZXkgZm9yIHRoZSBsb2NhbGl6ZWQgd2FybmluZyBtZXNzYWdlLgogICAgICAgICAqICBAc2VlIE1hbmRhdG9yeVdhcm5pbmdIYW5kbGVyCiAgICAgICAgICovCiAgICAgICAgcHVibGljIEpDRGlhZ25vc3RpYyB3YXJuaW5nKAogICAgICAgICAgICAgICAgTGludENhdGVnb3J5IGxjLCBEaWFnbm9zdGljU291cmNlIHNvdXJjZSwgRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcywgV2FybmluZyB3YXJuaW5nS2V5KSB7CiAgICAgICAgICAgIHJldHVybiBjcmVhdGUobGMsIEVudW1TZXQubm9uZU9mKERpYWdub3N0aWNGbGFnLmNsYXNzKSwgc291cmNlLCBwb3MsIHdhcm5pbmdLZXkpOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogQ3JlYXRlIGEgbm90ZSBkaWFnbm9zdGljIHRoYXQgd2lsbCBub3QgYmUgaGlkZGVuIGJ5IHRoZSAtbm93YXJuIG9yIC1YbGludDpub25lIG9wdGlvbnMuCiAgICAgICAgICogIEBwYXJhbSBzb3VyY2UgVGhlIHNvdXJjZSBvZiB0aGUgY29tcGlsYXRpb24gdW5pdCwgaWYgYW55LCBpbiB3aGljaCB0byByZXBvcnQgdGhlIHdhcm5pbmcuCiAgICAgICAgICogIEBwYXJhbSBrZXkgICAgVGhlIGtleSBmb3IgdGhlIGxvY2FsaXplZCB3YXJuaW5nIG1lc3NhZ2UuCiAgICAgICAgICogIEBwYXJhbSBhcmdzICAgRmllbGRzIG9mIHRoZSB3YXJuaW5nIG1lc3NhZ2UuCiAgICAgICAgICogIEBzZWUgTWFuZGF0b3J5V2FybmluZ0hhbmRsZXIKICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgSkNEaWFnbm9zdGljIG1hbmRhdG9yeU5vdGUoRGlhZ25vc3RpY1NvdXJjZSBzb3VyY2UsIFN0cmluZyBrZXksIE9iamVjdC4uLiBhcmdzKSB7CiAgICAgICAgICAgIHJldHVybiBtYW5kYXRvcnlOb3RlKHNvdXJjZSwgbm90ZUtleShrZXksIGFyZ3MpKTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIENyZWF0ZSBhIG5vdGUgZGlhZ25vc3RpYyB0aGF0IHdpbGwgbm90IGJlIGhpZGRlbiBieSB0aGUgLW5vd2FybiBvciAtWGxpbnQ6bm9uZSBvcHRpb25zLgogICAgICAgICAqICBAcGFyYW0gbm90ZUtleSAgICBUaGUga2V5IGZvciB0aGUgbG9jYWxpemVkIG5vdGUgbWVzc2FnZS4KICAgICAgICAgKiAgQHNlZSBNYW5kYXRvcnlXYXJuaW5nSGFuZGxlcgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBKQ0RpYWdub3N0aWMgbWFuZGF0b3J5Tm90ZShEaWFnbm9zdGljU291cmNlIHNvdXJjZSwgTm90ZSBub3RlS2V5KSB7CiAgICAgICAgICAgIHJldHVybiBjcmVhdGUobnVsbCwgRW51bVNldC5vZihEaWFnbm9zdGljRmxhZy5NQU5EQVRPUlkpLCBzb3VyY2UsIG51bGwsIG5vdGVLZXkpOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogQ3JlYXRlIGEgbm90ZSBkaWFnbm9zdGljLgogICAgICAgICAqICBAcGFyYW0ga2V5ICAgIFRoZSBrZXkgZm9yIHRoZSBsb2NhbGl6ZWQgZXJyb3IgbWVzc2FnZS4KICAgICAgICAgKiAgQHBhcmFtIGFyZ3MgICBGaWVsZHMgb2YgdGhlIG1lc3NhZ2UuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIEpDRGlhZ25vc3RpYyBub3RlKAogICAgICAgICAgICAgICAgRGlhZ25vc3RpY1NvdXJjZSBzb3VyY2UsIERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIFN0cmluZyBrZXksIE9iamVjdC4uLiBhcmdzKSB7CiAgICAgICAgICAgIHJldHVybiBub3RlKHNvdXJjZSwgcG9zLCBub3RlS2V5KGtleSwgYXJncykpOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogQ3JlYXRlIGEgbm90ZSBkaWFnbm9zdGljLgogICAgICAgICAqICBAcGFyYW0gc291cmNlIFRoZSBzb3VyY2Ugb2YgdGhlIGNvbXBpbGF0aW9uIHVuaXQsIGlmIGFueSwgaW4gd2hpY2ggdG8gcmVwb3J0IHRoZSBub3RlLgogICAgICAgICAqICBAcGFyYW0gcG9zICAgIFRoZSBzb3VyY2UgcG9zaXRpb24gYXQgd2hpY2ggdG8gcmVwb3J0IHRoZSBub3RlLgogICAgICAgICAqICBAcGFyYW0gbm90ZUtleSAgICBUaGUga2V5IGZvciB0aGUgbG9jYWxpemVkIG5vdGUgbWVzc2FnZS4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgSkNEaWFnbm9zdGljIG5vdGUoCiAgICAgICAgICAgICAgICBEaWFnbm9zdGljU291cmNlIHNvdXJjZSwgRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcywgTm90ZSBub3RlS2V5KSB7CiAgICAgICAgICAgIHJldHVybiBjcmVhdGUobnVsbCwgRW51bVNldC5ub25lT2YoRGlhZ25vc3RpY0ZsYWcuY2xhc3MpLCBzb3VyY2UsIHBvcywgbm90ZUtleSk7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBDcmVhdGUgYSBmcmFnbWVudCBkaWFnbm9zdGljLCBmb3IgdXNlIGFzIGFuIGFyZ3VtZW50IGluIG90aGVyIGRpYWdub3N0aWNzCiAgICAgICAgICogIEBwYXJhbSBrZXkgICAgVGhlIGtleSBmb3IgdGhlIGxvY2FsaXplZCBtZXNzYWdlLgogICAgICAgICAqICBAcGFyYW0gYXJncyAgIEZpZWxkcyBvZiB0aGUgbWVzc2FnZS4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgSkNEaWFnbm9zdGljIGZyYWdtZW50KFN0cmluZyBrZXksIE9iamVjdC4uLiBhcmdzKSB7CiAgICAgICAgICAgIHJldHVybiBmcmFnbWVudChmcmFnbWVudEtleShrZXksIGFyZ3MpKTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIENyZWF0ZSBhIGZyYWdtZW50IGRpYWdub3N0aWMsIGZvciB1c2UgYXMgYW4gYXJndW1lbnQgaW4gb3RoZXIgZGlhZ25vc3RpY3MKICAgICAgICAgKiAgQHBhcmFtIGZyYWdtZW50S2V5ICAgIFRoZSBrZXkgZm9yIHRoZSBsb2NhbGl6ZWQgc3ViZGlhZ25vc3RpYyBtZXNzYWdlLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBKQ0RpYWdub3N0aWMgZnJhZ21lbnQoRnJhZ21lbnQgZnJhZ21lbnRLZXkpIHsKICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZShudWxsLCBFbnVtU2V0Lm5vbmVPZihEaWFnbm9zdGljRmxhZy5jbGFzcyksIG51bGwsIG51bGwsIGZyYWdtZW50S2V5KTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIENyZWF0ZSBhIG5ldyBkaWFnbm9zdGljIG9mIHRoZSBnaXZlbiBraW5kLCB3aGljaCBpcyBub3QgbWFuZGF0b3J5IGFuZCB3aGljaCBoYXMKICAgICAgICAgKiBubyBsaW50IGNhdGVnb3J5LgogICAgICAgICAqICBAcGFyYW0ga2luZCAgICAgICAgVGhlIGRpYWdub3N0aWMga2luZAogICAgICAgICAqICBAcGFyYW0gc291cmNlICAgICAgVGhlIHNvdXJjZSBvZiB0aGUgY29tcGlsYXRpb24gdW5pdCwgaWYgYW55LCBpbiB3aGljaCB0byByZXBvcnQgdGhlIG1lc3NhZ2UuCiAgICAgICAgICogIEBwYXJhbSBwb3MgICAgICAgICBUaGUgc291cmNlIHBvc2l0aW9uIGF0IHdoaWNoIHRvIHJlcG9ydCB0aGUgbWVzc2FnZS4KICAgICAgICAgKiAgQHBhcmFtIGtleSAgICAgICAgIFRoZSBrZXkgZm9yIHRoZSBsb2NhbGl6ZWQgbWVzc2FnZS4KICAgICAgICAgKiAgQHBhcmFtIGFyZ3MgICAgICAgIEZpZWxkcyBvZiB0aGUgbWVzc2FnZS4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgSkNEaWFnbm9zdGljIGNyZWF0ZSgKICAgICAgICAgICAgICAgIERpYWdub3N0aWNUeXBlIGtpbmQsIERpYWdub3N0aWNTb3VyY2Ugc291cmNlLCBEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBTdHJpbmcga2V5LCBPYmplY3QuLi4gYXJncykgewogICAgICAgICAgICByZXR1cm4gY3JlYXRlKG51bGwsIEVudW1TZXQubm9uZU9mKERpYWdub3N0aWNGbGFnLmNsYXNzKSwgc291cmNlLCBwb3MsIERpYWdub3N0aWNJbmZvLm9mKGtpbmQsIHByZWZpeCwga2V5LCBhcmdzKSk7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBDcmVhdGUgYSBuZXcgZGlhZ25vc3RpYyBvZiB0aGUgZ2l2ZW4ga2luZCwgd2hpY2ggaXMgbm90IG1hbmRhdG9yeSBhbmQgd2hpY2ggaGFzCiAgICAgICAgICogbm8gbGludCBjYXRlZ29yeS4KICAgICAgICAgKiAgQHBhcmFtIHNvdXJjZSAgICAgIFRoZSBzb3VyY2Ugb2YgdGhlIGNvbXBpbGF0aW9uIHVuaXQsIGlmIGFueSwgaW4gd2hpY2ggdG8gcmVwb3J0IHRoZSBtZXNzYWdlLgogICAgICAgICAqICBAcGFyYW0gcG9zICAgICAgICAgVGhlIHNvdXJjZSBwb3NpdGlvbiBhdCB3aGljaCB0byByZXBvcnQgdGhlIG1lc3NhZ2UuCiAgICAgICAgICogIEBwYXJhbSBkaWFnbm9zdGljSW5mbyAgICAgICAgIFRoZSBrZXkgZm9yIHRoZSBsb2NhbGl6ZWQgbWVzc2FnZS4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgSkNEaWFnbm9zdGljIGNyZWF0ZSgKICAgICAgICAgICAgICAgIERpYWdub3N0aWNTb3VyY2Ugc291cmNlLCBEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBEaWFnbm9zdGljSW5mbyBkaWFnbm9zdGljSW5mbykgewogICAgICAgICAgICByZXR1cm4gY3JlYXRlKG51bGwsIEVudW1TZXQubm9uZU9mKERpYWdub3N0aWNGbGFnLmNsYXNzKSwgc291cmNlLCBwb3MsIGRpYWdub3N0aWNJbmZvKTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIENyZWF0ZSBhIG5ldyBkaWFnbm9zdGljIG9mIHRoZSBnaXZlbiBraW5kLgogICAgICAgICAqICBAcGFyYW0ga2luZCAgICAgICAgVGhlIGRpYWdub3N0aWMga2luZAogICAgICAgICAqICBAcGFyYW0gbGMgICAgICAgICAgVGhlIGxpbnQgY2F0ZWdvcnksIGlmIGFwcGxpY2FibGUsIG9yIG51bGwKICAgICAgICAgKiAgQHBhcmFtIGZsYWdzICAgICAgIFRoZSBzZXQgb2YgZmxhZ3MgZm9yIHRoZSBkaWFnbm9zdGljCiAgICAgICAgICogIEBwYXJhbSBzb3VyY2UgICAgICBUaGUgc291cmNlIG9mIHRoZSBjb21waWxhdGlvbiB1bml0LCBpZiBhbnksIGluIHdoaWNoIHRvIHJlcG9ydCB0aGUgbWVzc2FnZS4KICAgICAgICAgKiAgQHBhcmFtIHBvcyAgICAgICAgIFRoZSBzb3VyY2UgcG9zaXRpb24gYXQgd2hpY2ggdG8gcmVwb3J0IHRoZSBtZXNzYWdlLgogICAgICAgICAqICBAcGFyYW0ga2V5ICAgICAgICAgVGhlIGtleSBmb3IgdGhlIGxvY2FsaXplZCBtZXNzYWdlLgogICAgICAgICAqICBAcGFyYW0gYXJncyAgICAgICAgRmllbGRzIG9mIHRoZSBtZXNzYWdlLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBKQ0RpYWdub3N0aWMgY3JlYXRlKERpYWdub3N0aWNUeXBlIGtpbmQsCiAgICAgICAgICAgICAgICBMaW50Q2F0ZWdvcnkgbGMsIFNldDxEaWFnbm9zdGljRmxhZz4gZmxhZ3MsIERpYWdub3N0aWNTb3VyY2Ugc291cmNlLCBEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBTdHJpbmcga2V5LCBPYmplY3QuLi4gYXJncykgewogICAgICAgICAgICByZXR1cm4gY3JlYXRlKGxjLCBmbGFncywgc291cmNlLCBwb3MsIERpYWdub3N0aWNJbmZvLm9mKGtpbmQsIHByZWZpeCwga2V5LCBhcmdzKSk7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBDcmVhdGUgYSBuZXcgZGlhZ25vc3RpYyB3aXRoIGdpdmVuIGtleS4KICAgICAgICAgKiAgQHBhcmFtIGxjICAgICAgICAgIFRoZSBsaW50IGNhdGVnb3J5LCBpZiBhcHBsaWNhYmxlLCBvciBudWxsCiAgICAgICAgICogIEBwYXJhbSBmbGFncyAgICAgICBUaGUgc2V0IG9mIGZsYWdzIGZvciB0aGUgZGlhZ25vc3RpYwogICAgICAgICAqICBAcGFyYW0gc291cmNlICAgICAgVGhlIHNvdXJjZSBvZiB0aGUgY29tcGlsYXRpb24gdW5pdCwgaWYgYW55LCBpbiB3aGljaCB0byByZXBvcnQgdGhlIG1lc3NhZ2UuCiAgICAgICAgICogIEBwYXJhbSBwb3MgICAgICAgICBUaGUgc291cmNlIHBvc2l0aW9uIGF0IHdoaWNoIHRvIHJlcG9ydCB0aGUgbWVzc2FnZS4KICAgICAgICAgKiAgQHBhcmFtIGRpYWdub3N0aWNJbmZvICAgIFRoZSBrZXkgZm9yIHRoZSBsb2NhbGl6ZWQgbWVzc2FnZS4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgSkNEaWFnbm9zdGljIGNyZWF0ZSgKICAgICAgICAgICAgICAgIExpbnRDYXRlZ29yeSBsYywgU2V0PERpYWdub3N0aWNGbGFnPiBmbGFncywgRGlhZ25vc3RpY1NvdXJjZSBzb3VyY2UsIERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIERpYWdub3N0aWNJbmZvIGRpYWdub3N0aWNJbmZvKSB7CiAgICAgICAgICAgIHJldHVybiBuZXcgSkNEaWFnbm9zdGljKGZvcm1hdHRlciwgbm9ybWFsaXplKGRpYWdub3N0aWNJbmZvKSwgbGMsIGZsYWdzLCBzb3VyY2UsIHBvcyk7CiAgICAgICAgfQogICAgICAgIC8vd2hlcmUKICAgICAgICAgICAgRGlhZ25vc3RpY0luZm8gbm9ybWFsaXplKERpYWdub3N0aWNJbmZvIGRpYWdub3N0aWNJbmZvKSB7CiAgICAgICAgICAgICAgICAvL3JlcGxhY2UgYWxsIG5lc3RlZCBGcmFnbWVudEtleSB3aXRoIGZ1bGwtYmxvd24gSkNEaWFnbm9zdGljIG9iamVjdHMKICAgICAgICAgICAgICAgIHJldHVybiBEaWFnbm9zdGljSW5mby5vZihkaWFnbm9zdGljSW5mby50eXBlLCBkaWFnbm9zdGljSW5mby5wcmVmaXgsIGRpYWdub3N0aWNJbmZvLmNvZGUsCiAgICAgICAgICAgICAgICAgICAgICAgIFN0cmVhbS5vZihkaWFnbm9zdGljSW5mby5hcmdzKS5tYXAobyAtPiB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKG8gaW5zdGFuY2VvZiBGcmFnbWVudCkgPwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcmFnbWVudCgoRnJhZ21lbnQpbykgOiBvOwogICAgICAgICAgICAgICAgICAgICAgICB9KS50b0FycmF5KCkpOwogICAgICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIENyZWF0ZSBhIG5ldyBlcnJvciBrZXkuCiAgICAgICAgICovCiAgICAgICAgRXJyb3IgZXJyb3JLZXkoU3RyaW5nIGNvZGUsIE9iamVjdC4uLiBhcmdzKSB7CiAgICAgICAgICAgIHJldHVybiAoRXJyb3IpRGlhZ25vc3RpY0luZm8ub2YoRVJST1IsIHByZWZpeCwgY29kZSwgYXJncyk7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBDcmVhdGUgYSBuZXcgd2FybmluZyBrZXkuCiAgICAgICAgICovCiAgICAgICAgV2FybmluZyB3YXJuaW5nS2V5KFN0cmluZyBjb2RlLCBPYmplY3QuLi4gYXJncykgewogICAgICAgICAgICByZXR1cm4gKFdhcm5pbmcpRGlhZ25vc3RpY0luZm8ub2YoV0FSTklORywgcHJlZml4LCBjb2RlLCBhcmdzKTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIENyZWF0ZSBhIG5ldyBub3RlIGtleS4KICAgICAgICAgKi8KICAgICAgICBOb3RlIG5vdGVLZXkoU3RyaW5nIGNvZGUsIE9iamVjdC4uLiBhcmdzKSB7CiAgICAgICAgICAgIHJldHVybiAoTm90ZSlEaWFnbm9zdGljSW5mby5vZihOT1RFLCBwcmVmaXgsIGNvZGUsIGFyZ3MpOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogQ3JlYXRlIGEgbmV3IGZyYWdtZW50IGtleS4KICAgICAgICAgKi8KICAgICAgICBGcmFnbWVudCBmcmFnbWVudEtleShTdHJpbmcgY29kZSwgT2JqZWN0Li4uIGFyZ3MpIHsKICAgICAgICAgICAgcmV0dXJuIChGcmFnbWVudClEaWFnbm9zdGljSW5mby5vZihGUkFHTUVOVCwgcHJlZml4LCBjb2RlLCBhcmdzKTsKICAgICAgICB9CiAgICB9CgoKCiAgICAvKioKICAgICAqIENyZWF0ZSBhIGZyYWdtZW50IGRpYWdub3N0aWMsIGZvciB1c2UgYXMgYW4gYXJndW1lbnQgaW4gb3RoZXIgZGlhZ25vc3RpY3MKICAgICAqICBAcGFyYW0ga2V5ICAgIFRoZSBrZXkgZm9yIHRoZSBsb2NhbGl6ZWQgZXJyb3IgbWVzc2FnZS4KICAgICAqICBAcGFyYW0gYXJncyAgIEZpZWxkcyBvZiB0aGUgZXJyb3IgbWVzc2FnZS4KICAgICAqCiAgICAgKi8KICAgIEBEZXByZWNhdGVkCiAgICBwdWJsaWMgc3RhdGljIEpDRGlhZ25vc3RpYyBmcmFnbWVudChTdHJpbmcga2V5LCBPYmplY3QuLi4gYXJncykgewogICAgICAgIHJldHVybiBuZXcgSkNEaWFnbm9zdGljKGdldEZyYWdtZW50Rm9ybWF0dGVyKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERpYWdub3N0aWNJbmZvLm9mKEZSQUdNRU5ULAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJjb21waWxlciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2V5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyZ3MpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFbnVtU2V0Lm5vbmVPZihEaWFnbm9zdGljRmxhZy5jbGFzcyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwpOwogICAgfQogICAgLy93aGVyZQogICAgQERlcHJlY2F0ZWQKICAgIHB1YmxpYyBzdGF0aWMgRGlhZ25vc3RpY0Zvcm1hdHRlcjxKQ0RpYWdub3N0aWM+IGdldEZyYWdtZW50Rm9ybWF0dGVyKCkgewogICAgICAgIGlmIChmcmFnbWVudEZvcm1hdHRlciA9PSBudWxsKSB7CiAgICAgICAgICAgIGZyYWdtZW50Rm9ybWF0dGVyID0gbmV3IEJhc2ljRGlhZ25vc3RpY0Zvcm1hdHRlcihKYXZhY01lc3NhZ2VzLmdldERlZmF1bHRNZXNzYWdlcygpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZyYWdtZW50Rm9ybWF0dGVyOwogICAgfQoKICAgIC8qKgogICAgICogQSBEaWFnbm9zdGljVHlwZSBkZWZpbmVzIHRoZSB0eXBlIG9mIHRoZSBkaWFnbm9zdGljLgogICAgICoqLwogICAgcHVibGljIGVudW0gRGlhZ25vc3RpY1R5cGUgewogICAgICAgIC8qKiBBIGZyYWdtZW50IG9mIGFuIGVuY2xvc2luZyBkaWFnbm9zdGljLiAqLwogICAgICAgIEZSQUdNRU5UKCJtaXNjIiksCiAgICAgICAgLyoqIEEgbm90ZTogc2ltaWxhciB0bywgYnV0IGxlc3Mgc2VyaW91cyB0aGFuLCBhIHdhcm5pbmcuICovCiAgICAgICAgTk9URSgibm90ZSIpLAogICAgICAgIC8qKiBBIHdhcm5pbmcuICovCiAgICAgICAgV0FSTklORygid2FybiIpLAogICAgICAgIC8qKiBBbiBlcnJvci4gKi8KICAgICAgICBFUlJPUigiZXJyIik7CgogICAgICAgIGZpbmFsIFN0cmluZyBrZXk7CgogICAgICAgIC8qKiBDcmVhdGUgYSBEaWFnbm9zdGljVHlwZS4KICAgICAgICAgKiBAcGFyYW0ga2V5IEEgc3RyaW5nIHVzZWQgdG8gY3JlYXRlIHRoZSByZXNvdXJjZSBrZXkgZm9yIHRoZSBkaWFnbm9zdGljLgogICAgICAgICAqLwogICAgICAgIERpYWdub3N0aWNUeXBlKFN0cmluZyBrZXkpIHsKICAgICAgICAgICAgdGhpcy5rZXkgPSBrZXk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQSBEaWFnbm9zdGljUG9zaXRpb24gcHJvdmlkZXMgaW5mb3JtYXRpb24gYWJvdXQgdGhlIHBvc2l0aW9ucyBpbiBhIGZpbGUKICAgICAqIHRoYXQgZ2F2ZSByaXNlIHRvIGEgZGlhZ25vc3RpYy4gSXQgYWx3YXlzIGRlZmluZXMgYSAicHJlZmVycmVkIiBwb3NpdGlvbgogICAgICogdGhhdCBtb3N0IGFjY3VyYXRlbHkgZGVmaW5lcyB0aGUgbG9jYXRpb24gb2YgdGhlIGRpYWdub3N0aWMsIGl0IG1heSBhbHNvCiAgICAgKiBwcm92aWRlIGEgcmVsYXRlZCB0cmVlIG5vZGUgdGhhdCBzcGFucyB0aGF0IGxvY2F0aW9uLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGludGVyZmFjZSBEaWFnbm9zdGljUG9zaXRpb24gewogICAgICAgIC8qKiBHZXRzIHRoZSB0cmVlIG5vZGUsIGlmIGFueSwgdG8gd2hpY2ggdGhlIGRpYWdub3N0aWMgYXBwbGllcy4gKi8KICAgICAgICBKQ1RyZWUgZ2V0VHJlZSgpOwogICAgICAgIC8qKiBJZiB0aGVyZSBpcyBhIHRyZWUgbm9kZSwgZ2V0IHRoZSBzdGFydCBwb3NpdGlvbiBvZiB0aGUgdHJlZSBub2RlLgogICAgICAgICAqICBPdGhlcndpc2UsIGp1c3QgcmV0dXJucyB0aGUgc2FtZSBhcyBnZXRQcmVmZXJyZWRQb3NpdGlvbigpLiAqLwogICAgICAgIGludCBnZXRTdGFydFBvc2l0aW9uKCk7CiAgICAgICAgLyoqIEdldCB0aGUgcG9zaXRpb24gd2l0aGluIHRoZSBmaWxlIHRoYXQgbW9zdCBhY2N1cmF0ZWx5IGRlZmluZXMgdGhlCiAgICAgICAgICogIGxvY2F0aW9uIGZvciB0aGUgZGlhZ25vc3RpYy4gKi8KICAgICAgICBpbnQgZ2V0UHJlZmVycmVkUG9zaXRpb24oKTsKICAgICAgICAvKiogSWYgdGhlcmUgaXMgYSB0cmVlIG5vZGUsIGFuZCBpZiBlbmRQb3NpdGlvbnMgYXJlIGF2YWlsYWJsZSwgZ2V0CiAgICAgICAgICogIHRoZSBlbmQgcG9zaXRpb24gb2YgdGhlIHRyZWUgbm9kZS4gT3RoZXJ3aXNlLCBqdXN0IHJldHVybnMgdGhlCiAgICAgICAgICogIHNhbWUgYXMgZ2V0UHJlZmVycmVkUG9zaXRpb24oKS4gKi8KICAgICAgICBpbnQgZ2V0RW5kUG9zaXRpb24oRW5kUG9zVGFibGUgZW5kUG9zVGFibGUpOwogICAgfQoKICAgIC8qKgogICAgICogQSBEaWFnbm9zdGljUG9zaXRpb24gdGhhdCBzaW1wbHkgaWRlbnRpZmllcyBhIHBvc2l0aW9uLCBidXQgbm8gcmVsYXRlZAogICAgICogdHJlZSBub2RlLCBhcyB0aGUgbG9jYXRpb24gZm9yIGEgZGlhZ25vc3RpYy4gVXNlZCBmb3Igc2Nhbm5lciBhbmQgcGFyc2VyCiAgICAgKiBkaWFnbm9zdGljcy4gKi8KICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgU2ltcGxlRGlhZ25vc3RpY1Bvc2l0aW9uIGltcGxlbWVudHMgRGlhZ25vc3RpY1Bvc2l0aW9uIHsKICAgICAgICBwdWJsaWMgU2ltcGxlRGlhZ25vc3RpY1Bvc2l0aW9uKGludCBwb3MpIHsKICAgICAgICAgICAgdGhpcy5wb3MgPSBwb3M7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgSkNUcmVlIGdldFRyZWUoKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIGludCBnZXRTdGFydFBvc2l0aW9uKCkgewogICAgICAgICAgICByZXR1cm4gcG9zOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIGludCBnZXRQcmVmZXJyZWRQb3NpdGlvbigpIHsKICAgICAgICAgICAgcmV0dXJuIHBvczsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBpbnQgZ2V0RW5kUG9zaXRpb24oRW5kUG9zVGFibGUgZW5kUG9zVGFibGUpIHsKICAgICAgICAgICAgcmV0dXJuIHBvczsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgZmluYWwgaW50IHBvczsKICAgIH0KCiAgICBwdWJsaWMgZW51bSBEaWFnbm9zdGljRmxhZyB7CiAgICAgICAgTUFOREFUT1JZLAogICAgICAgIFJFU09MVkVfRVJST1IsCiAgICAgICAgU1lOVEFYLAogICAgICAgIFJFQ09WRVJBQkxFLAogICAgICAgIE5PTl9ERUZFUlJBQkxFLAogICAgICAgIENPTVBSRVNTRUQsCiAgICAgICAgLyoqIFByaW50IG11bHRpcGxlIGVycm9ycyBmb3Igc2FtZSBzb3VyY2UgbG9jYXRpb25zLgogICAgICAgICAqLwogICAgICAgIE1VTFRJUExFLAogICAgICAgIC8qKiBGbGFnIGZvciBub3Qtc3VwcG9ydGVkLWluLXNvdXJjZS1YIGVycm9ycy4KICAgICAgICAgKi8KICAgICAgICBTT1VSQ0VfTEVWRUw7CiAgICB9CgogICAgcHJpdmF0ZSBmaW5hbCBEaWFnbm9zdGljU291cmNlIHNvdXJjZTsKICAgIHByaXZhdGUgZmluYWwgRGlhZ25vc3RpY1Bvc2l0aW9uIHBvc2l0aW9uOwogICAgcHJpdmF0ZSBmaW5hbCBEaWFnbm9zdGljSW5mbyBkaWFnbm9zdGljSW5mbzsKICAgIHByaXZhdGUgZmluYWwgU2V0PERpYWdub3N0aWNGbGFnPiBmbGFnczsKICAgIHByaXZhdGUgZmluYWwgTGludENhdGVnb3J5IGxpbnRDYXRlZ29yeTsKCiAgICAvKiogc291cmNlIGxpbmUgcG9zaXRpb24gKHNldCBsYXppbHkpICovCiAgICBwcml2YXRlIFNvdXJjZVBvc2l0aW9uIHNvdXJjZVBvc2l0aW9uOwoKICAgIC8qKgogICAgICogVGhpcyBjbGFzcyBpcyB1c2VkIHRvIGRlZmVyIHRoZSBsaW5lL2NvbHVtbiBwb3NpdGlvbiBmZXRjaCBsb2dpYyBhZnRlciBkaWFnbm9zdGljIGNvbnN0cnVjdGlvbi4KICAgICAqLwogICAgY2xhc3MgU291cmNlUG9zaXRpb24gewoKICAgICAgICBwcml2YXRlIGZpbmFsIGludCBsaW5lOwogICAgICAgIHByaXZhdGUgZmluYWwgaW50IGNvbHVtbjsKCiAgICAgICAgU291cmNlUG9zaXRpb24oKSB7CiAgICAgICAgICAgIGludCBuID0gKHBvc2l0aW9uID09IG51bGwgPyBQb3NpdGlvbi5OT1BPUyA6IHBvc2l0aW9uLmdldFByZWZlcnJlZFBvc2l0aW9uKCkpOwogICAgICAgICAgICBpZiAobiA9PSBQb3NpdGlvbi5OT1BPUyB8fCBzb3VyY2UgPT0gbnVsbCkKICAgICAgICAgICAgICAgIGxpbmUgPSBjb2x1bW4gPSAtMTsKICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICBsaW5lID0gc291cmNlLmdldExpbmVOdW1iZXIobik7CiAgICAgICAgICAgICAgICBjb2x1bW4gPSBzb3VyY2UuZ2V0Q29sdW1uTnVtYmVyKG4sIHRydWUpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgaW50IGdldExpbmVOdW1iZXIoKSB7CiAgICAgICAgICAgIHJldHVybiBsaW5lOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIGludCBnZXRDb2x1bW5OdW1iZXIoKSB7CiAgICAgICAgICAgIHJldHVybiBjb2x1bW47CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQSBkaWFnbm9zdGljIGtleSBvYmplY3QgZW5jYXBzdWxhdGVzIGJhc2ljIHByb3BlcnRpZXMgb2YgYSBkaWFnbm9zdGljLCBzdWNoIGFzIHRoZSByZXNvdXJjZSBrZXksCiAgICAgKiB0aGUgYXJndW1lbnRzIGFuZCB0aGUga2luZCBhc3NvY2lhdGVkIHdpdGggdGhlIGRpYWdub3N0aWMgb2JqZWN0LiBEaWFnbm9zdGljIGtleXMgY2FuIGJlIGVpdGhlcgogICAgICogY3JlYXRlZCBwcm9ncmFtbWF0aWNhbGx5IChieSB1c2luZyB0aGUgc3VwcGxpZWQgZmFjdG9yeSBtZXRob2QpIG9yIG9idGFpbmVkIHRocm91Z2ggYnVpbGQtdGltZQogICAgICogZ2VuZXJhdGVkIGZhY3RvcnkgbWV0aG9kcy4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBhYnN0cmFjdCBjbGFzcyBEaWFnbm9zdGljSW5mbyB7CgogICAgICAgIC8qKiBUaGUgZGlhZ25vc3RpYyBraW5kIChpLmUuIGVycm9yKS4gKi8KICAgICAgICBEaWFnbm9zdGljVHlwZSB0eXBlOwoKICAgICAgICAvKiogVGhlIGRpYWdub3N0aWMgcHJlZml4IChpLmUuICdqYXZhYycpOyB1c2VkIHRvIGNvbXB1dGUgZnVsbCByZXNvdXJjZSBrZXkuICovCiAgICAgICAgU3RyaW5nIHByZWZpeDsKCiAgICAgICAgLyoqIFRoZSBkaWFnbm9zdGljIGNvZGUgKGkuZS4gJ2Nhbm5vdC5yZXNvbHZlLnN5bScpOyB0b2dldGhlciB3aXRoIHtAY29kZSBwcmVmaXh9IGl0IGZvcm1zCiAgICAgICAgICogdGhlIGZ1bGwgcmVzb3VyY2Uga2V5LiAqLwogICAgICAgIFN0cmluZyBjb2RlOwoKICAgICAgICAvKiogVGhlIGRpYWdub3N0aWMgYXJndW1lbnRzLiAqLwogICAgICAgIE9iamVjdFtdIGFyZ3M7CgogICAgICAgIHByaXZhdGUgRGlhZ25vc3RpY0luZm8oRGlhZ25vc3RpY1R5cGUgdHlwZSwgU3RyaW5nIHByZWZpeCwgU3RyaW5nIGNvZGUsIE9iamVjdC4uLiBhcmdzKSB7CiAgICAgICAgICAgIHRoaXMudHlwZSA9IHR5cGU7CiAgICAgICAgICAgIHRoaXMucHJlZml4ID0gcHJlZml4OwogICAgICAgICAgICB0aGlzLmNvZGUgPSBjb2RlOwogICAgICAgICAgICB0aGlzLmFyZ3MgPSBhcmdzOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogQ29tcHV0ZSB0aGUgcmVzb3VyY2Uga2V5LgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBTdHJpbmcga2V5KCkgewogICAgICAgICAgICByZXR1cm4gcHJlZml4ICsgIi4iICsgdHlwZS5rZXkgKyAiLiIgKyBjb2RlOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogU3RhdGljIGZhY3RvcnkgbWV0aG9kOyBidWlsZCBhIGN1c3RvbSBkaWFnbm9zdGljIGtleSB1c2luZyBnaXZlbiBraW5kLCBwcmVmaXgsIGNvZGUgYW5kIGFyZ3MuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIHN0YXRpYyBEaWFnbm9zdGljSW5mbyBvZihEaWFnbm9zdGljVHlwZSB0eXBlLCBTdHJpbmcgcHJlZml4LCBTdHJpbmcgY29kZSwgT2JqZWN0Li4uIGFyZ3MpIHsKICAgICAgICAgICAgc3dpdGNoICh0eXBlKSB7CiAgICAgICAgICAgICAgICBjYXNlIEVSUk9SOgogICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgRXJyb3IocHJlZml4LCBjb2RlLCBhcmdzKTsKICAgICAgICAgICAgICAgIGNhc2UgV0FSTklORzoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFdhcm5pbmcocHJlZml4LCBjb2RlLCBhcmdzKTsKICAgICAgICAgICAgICAgIGNhc2UgTk9URToKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IE5vdGUocHJlZml4LCBjb2RlLCBhcmdzKTsKICAgICAgICAgICAgICAgIGNhc2UgRlJBR01FTlQ6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBGcmFnbWVudChwcmVmaXgsIGNvZGUsIGFyZ3MpOwogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICBBc3NlcnQuZXJyb3IoIldyb25nIGRpYWdub3N0aWMgdHlwZTogIiArIHR5cGUpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgIH0KCiAgICAvKioKICAgICAqIENsYXNzIHJlcHJlc2VudGluZyBlcnJvciBkaWFnbm9zdGljIGtleXMuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgRXJyb3IgZXh0ZW5kcyBEaWFnbm9zdGljSW5mbyB7CiAgICAgICAgcHVibGljIEVycm9yKFN0cmluZyBwcmVmaXgsIFN0cmluZyBrZXksIE9iamVjdC4uLiBhcmdzKSB7CiAgICAgICAgICAgIHN1cGVyKERpYWdub3N0aWNUeXBlLkVSUk9SLCBwcmVmaXgsIGtleSwgYXJncyk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQ2xhc3MgcmVwcmVzZW50aW5nIHdhcm5pbmcgZGlhZ25vc3RpYyBrZXlzLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFdhcm5pbmcgZXh0ZW5kcyBEaWFnbm9zdGljSW5mbyB7CiAgICAgICAgcHVibGljIFdhcm5pbmcoU3RyaW5nIHByZWZpeCwgU3RyaW5nIGtleSwgT2JqZWN0Li4uIGFyZ3MpIHsKICAgICAgICAgICAgc3VwZXIoRGlhZ25vc3RpY1R5cGUuV0FSTklORywgcHJlZml4LCBrZXksIGFyZ3MpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIENsYXNzIHJlcHJlc2VudGluZyBub3RlIGRpYWdub3N0aWMga2V5cy4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBOb3RlIGV4dGVuZHMgRGlhZ25vc3RpY0luZm8gewogICAgICAgIHB1YmxpYyBOb3RlKFN0cmluZyBwcmVmaXgsIFN0cmluZyBrZXksIE9iamVjdC4uLiBhcmdzKSB7CiAgICAgICAgICAgIHN1cGVyKERpYWdub3N0aWNUeXBlLk5PVEUsIHByZWZpeCwga2V5LCBhcmdzKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBDbGFzcyByZXByZXNlbnRpbmcgZnJhZ21lbnQgZGlhZ25vc3RpYyBrZXlzLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEZyYWdtZW50IGV4dGVuZHMgRGlhZ25vc3RpY0luZm8gewogICAgICAgIHB1YmxpYyBGcmFnbWVudChTdHJpbmcgcHJlZml4LCBTdHJpbmcga2V5LCBPYmplY3QuLi4gYXJncykgewogICAgICAgICAgICBzdXBlcihEaWFnbm9zdGljVHlwZS5GUkFHTUVOVCwgcHJlZml4LCBrZXksIGFyZ3MpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIENyZWF0ZSBhIGRpYWdub3N0aWMgb2JqZWN0LgogICAgICogQHBhcmFtIGZvcm1hdHRlciB0aGUgZm9ybWF0dGVyIHRvIHVzZSBmb3IgdGhlIGRpYWdub3N0aWMKICAgICAqIEBwYXJhbSBkaWFnbm9zdGljSW5mbyB0aGUgZGlhZ25vc3RpYyBrZXkKICAgICAqIEBwYXJhbSBsYyAgICAgdGhlIGxpbnQgY2F0ZWdvcnkgZm9yIHRoZSBkaWFnbm9zdGljCiAgICAgKiBAcGFyYW0gc291cmNlIHRoZSBuYW1lIG9mIHRoZSBzb3VyY2UgZmlsZSwgb3IgbnVsbCBpZiBub25lLgogICAgICogQHBhcmFtIHBvcyB0aGUgY2hhcmFjdGVyIG9mZnNldCB3aXRoaW4gdGhlIHNvdXJjZSBmaWxlLCBpZiBnaXZlbi4KICAgICAqLwogICAgcHJvdGVjdGVkIEpDRGlhZ25vc3RpYyhEaWFnbm9zdGljRm9ybWF0dGVyPEpDRGlhZ25vc3RpYz4gZm9ybWF0dGVyLAogICAgICAgICAgICAgICAgICAgICAgIERpYWdub3N0aWNJbmZvIGRpYWdub3N0aWNJbmZvLAogICAgICAgICAgICAgICAgICAgICAgIExpbnRDYXRlZ29yeSBsYywKICAgICAgICAgICAgICAgICAgICAgICBTZXQ8RGlhZ25vc3RpY0ZsYWc+IGZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgIERpYWdub3N0aWNTb3VyY2Ugc291cmNlLAogICAgICAgICAgICAgICAgICAgICAgIERpYWdub3N0aWNQb3NpdGlvbiBwb3MpIHsKICAgICAgICBpZiAoc291cmNlID09IG51bGwgJiYgcG9zICE9IG51bGwgJiYgcG9zLmdldFByZWZlcnJlZFBvc2l0aW9uKCkgIT0gUG9zaXRpb24uTk9QT1MpCiAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKCiAgICAgICAgdGhpcy5kZWZhdWx0Rm9ybWF0dGVyID0gZm9ybWF0dGVyOwogICAgICAgIHRoaXMuZGlhZ25vc3RpY0luZm8gPSBkaWFnbm9zdGljSW5mbzsKICAgICAgICB0aGlzLmxpbnRDYXRlZ29yeSA9IGxjOwogICAgICAgIHRoaXMuZmxhZ3MgPSBmbGFnczsKICAgICAgICB0aGlzLnNvdXJjZSA9IHNvdXJjZTsKICAgICAgICB0aGlzLnBvc2l0aW9uID0gcG9zOwogICAgfQoKICAgIC8qKgogICAgICogR2V0IHRoZSB0eXBlIG9mIHRoaXMgZGlhZ25vc3RpYy4KICAgICAqIEByZXR1cm4gdGhlIHR5cGUgb2YgdGhpcyBkaWFnbm9zdGljCiAgICAgKi8KICAgIHB1YmxpYyBEaWFnbm9zdGljVHlwZSBnZXRUeXBlKCkgewogICAgICAgIHJldHVybiBkaWFnbm9zdGljSW5mby50eXBlOwogICAgfQoKICAgIC8qKgogICAgICogR2V0IHRoZSBzdWJkaWFnbm9zdGljIGxpc3QKICAgICAqIEByZXR1cm4gc3ViZGlhZ25vc3RpYyBsaXN0CiAgICAgKi8KICAgIHB1YmxpYyBMaXN0PEpDRGlhZ25vc3RpYz4gZ2V0U3ViZGlhZ25vc3RpY3MoKSB7CiAgICAgICAgcmV0dXJuIExpc3QubmlsKCk7CiAgICB9CgogICAgcHVibGljIGJvb2xlYW4gaXNNdWx0aWxpbmUoKSB7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICogQ2hlY2sgd2hldGhlciBvciBub3QgdGhpcyBkaWFnbm9zdGljIGlzIHJlcXVpcmVkIHRvIGJlIHNob3duLgogICAgICogQHJldHVybiB0cnVlIGlmIHRoaXMgZGlhZ25vc3RpYyBpcyByZXF1aXJlZCB0byBiZSBzaG93bi4KICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gaXNNYW5kYXRvcnkoKSB7CiAgICAgICAgcmV0dXJuIGZsYWdzLmNvbnRhaW5zKERpYWdub3N0aWNGbGFnLk1BTkRBVE9SWSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDaGVjayB3aGV0aGVyIHRoaXMgZGlhZ25vc3RpYyBoYXMgYW4gYXNzb2NpYXRlZCBsaW50IGNhdGVnb3J5LgogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMaW50Q2F0ZWdvcnkoKSB7CiAgICAgICAgcmV0dXJuIChsaW50Q2F0ZWdvcnkgIT0gbnVsbCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXQgdGhlIGFzc29jaWF0ZWQgbGludCBjYXRlZ29yeSwgb3IgbnVsbCBpZiBub25lLgogICAgICovCiAgICBwdWJsaWMgTGludENhdGVnb3J5IGdldExpbnRDYXRlZ29yeSgpIHsKICAgICAgICByZXR1cm4gbGludENhdGVnb3J5OwogICAgfQoKICAgIC8qKgogICAgICogR2V0IHRoZSBuYW1lIG9mIHRoZSBzb3VyY2UgZmlsZSByZWZlcnJlZCB0byBieSB0aGlzIGRpYWdub3N0aWMuCiAgICAgKiBAcmV0dXJuIHRoZSBuYW1lIG9mIHRoZSBzb3VyY2UgcmVmZXJyZWQgdG8gd2l0aCB0aGlzIGRpYWdub3N0aWMsIG9yIG51bGwgaWYgbm9uZQogICAgICovCiAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgIHB1YmxpYyBKYXZhRmlsZU9iamVjdCBnZXRTb3VyY2UoKSB7CiAgICAgICAgaWYgKHNvdXJjZSA9PSBudWxsKQogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICBlbHNlCiAgICAgICAgICAgIHJldHVybiBzb3VyY2UuZ2V0RmlsZSgpOwogICAgfQoKICAgIC8qKgogICAgICogR2V0IHRoZSBzb3VyY2UgcmVmZXJyZWQgdG8gYnkgdGhpcyBkaWFnbm9zdGljLgogICAgICogQHJldHVybiB0aGUgc291cmNlIHJlZmVycmVkIHRvIHdpdGggdGhpcyBkaWFnbm9zdGljLCBvciBudWxsIGlmIG5vbmUKICAgICAqLwogICAgcHVibGljIERpYWdub3N0aWNTb3VyY2UgZ2V0RGlhZ25vc3RpY1NvdXJjZSgpIHsKICAgICAgICByZXR1cm4gc291cmNlOwogICAgfQoKICAgIHByb3RlY3RlZCBpbnQgZ2V0SW50U3RhcnRQb3NpdGlvbigpIHsKICAgICAgICByZXR1cm4gKHBvc2l0aW9uID09IG51bGwgPyBQb3NpdGlvbi5OT1BPUyA6IHBvc2l0aW9uLmdldFN0YXJ0UG9zaXRpb24oKSk7CiAgICB9CgogICAgcHJvdGVjdGVkIGludCBnZXRJbnRQb3NpdGlvbigpIHsKICAgICAgICByZXR1cm4gKHBvc2l0aW9uID09IG51bGwgPyBQb3NpdGlvbi5OT1BPUyA6IHBvc2l0aW9uLmdldFByZWZlcnJlZFBvc2l0aW9uKCkpOwogICAgfQoKICAgIHByb3RlY3RlZCBpbnQgZ2V0SW50RW5kUG9zaXRpb24oKSB7CiAgICAgICAgcmV0dXJuIChwb3NpdGlvbiA9PSBudWxsID8gUG9zaXRpb24uTk9QT1MgOiBwb3NpdGlvbi5nZXRFbmRQb3NpdGlvbihzb3VyY2UuZ2V0RW5kUG9zVGFibGUoKSkpOwogICAgfQoKICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSKQogICAgcHVibGljIGxvbmcgZ2V0U3RhcnRQb3NpdGlvbigpIHsKICAgICAgICByZXR1cm4gZ2V0SW50U3RhcnRQb3NpdGlvbigpOwogICAgfQoKICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSKQogICAgcHVibGljIGxvbmcgZ2V0UG9zaXRpb24oKSB7CiAgICAgICAgcmV0dXJuIGdldEludFBvc2l0aW9uKCk7CiAgICB9CgogICAgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICBwdWJsaWMgbG9uZyBnZXRFbmRQb3NpdGlvbigpIHsKICAgICAgICByZXR1cm4gZ2V0SW50RW5kUG9zaXRpb24oKTsKICAgIH0KCiAgICBwdWJsaWMgRGlhZ25vc3RpY1Bvc2l0aW9uIGdldERpYWdub3N0aWNQb3NpdGlvbigpIHsKICAgICAgICByZXR1cm4gcG9zaXRpb247CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXQgdGhlIGxpbmUgbnVtYmVyIHdpdGhpbiB0aGUgc291cmNlIHJlZmVycmVkIHRvIGJ5IHRoaXMgZGlhZ25vc3RpYy4KICAgICAqIEByZXR1cm4gIHRoZSBsaW5lIG51bWJlciB3aXRoaW4gdGhlIHNvdXJjZSByZWZlcnJlZCB0byBieSB0aGlzIGRpYWdub3N0aWMKICAgICAqLwogICAgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICBwdWJsaWMgbG9uZyBnZXRMaW5lTnVtYmVyKCkgewogICAgICAgIGlmIChzb3VyY2VQb3NpdGlvbiA9PSBudWxsKSB7CiAgICAgICAgICAgIHNvdXJjZVBvc2l0aW9uID0gbmV3IFNvdXJjZVBvc2l0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzb3VyY2VQb3NpdGlvbi5nZXRMaW5lTnVtYmVyKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXQgdGhlIGNvbHVtbiBudW1iZXIgd2l0aGluIHRoZSBsaW5lIG9mIHNvdXJjZSByZWZlcnJlZCB0byBieSB0aGlzIGRpYWdub3N0aWMuCiAgICAgKiBAcmV0dXJuICB0aGUgY29sdW1uIG51bWJlciB3aXRoaW4gdGhlIGxpbmUgb2Ygc291cmNlIHJlZmVycmVkIHRvIGJ5IHRoaXMgZGlhZ25vc3RpYwogICAgICovCiAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgIHB1YmxpYyBsb25nIGdldENvbHVtbk51bWJlcigpIHsKICAgICAgICBpZiAoc291cmNlUG9zaXRpb24gPT0gbnVsbCkgewogICAgICAgICAgICBzb3VyY2VQb3NpdGlvbiA9IG5ldyBTb3VyY2VQb3NpdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gc291cmNlUG9zaXRpb24uZ2V0Q29sdW1uTnVtYmVyKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXQgdGhlIGFyZ3VtZW50cyB0byBiZSBpbmNsdWRlZCBpbiB0aGUgdGV4dCBvZiB0aGUgZGlhZ25vc3RpYy4KICAgICAqIEByZXR1cm4gIHRoZSBhcmd1bWVudHMgdG8gYmUgaW5jbHVkZWQgaW4gdGhlIHRleHQgb2YgdGhlIGRpYWdub3N0aWMKICAgICAqLwogICAgcHVibGljIE9iamVjdFtdIGdldEFyZ3MoKSB7CiAgICAgICAgcmV0dXJuIGRpYWdub3N0aWNJbmZvLmFyZ3M7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXQgdGhlIHByZWZpeCBzdHJpbmcgYXNzb2NpYXRlZCB3aXRoIHRoaXMgdHlwZSBvZiBkaWFnbm9zdGljLgogICAgICogQHJldHVybiB0aGUgcHJlZml4IHN0cmluZyBhc3NvY2lhdGVkIHdpdGggdGhpcyB0eXBlIG9mIGRpYWdub3N0aWMKICAgICAqLwogICAgcHVibGljIFN0cmluZyBnZXRQcmVmaXgoKSB7CiAgICAgICAgcmV0dXJuIGdldFByZWZpeChkaWFnbm9zdGljSW5mby50eXBlKTsKICAgIH0KCiAgICAvKioKICAgICAqIEdldCB0aGUgcHJlZml4IHN0cmluZyBhc3NvY2lhdGVkIHdpdGggYSBwYXJ0aWN1bGFyIHR5cGUgb2YgZGlhZ25vc3RpYy4KICAgICAqIEByZXR1cm4gdGhlIHByZWZpeCBzdHJpbmcgYXNzb2NpYXRlZCB3aXRoIGEgcGFydGljdWxhciB0eXBlIG9mIGRpYWdub3N0aWMKICAgICAqLwogICAgcHVibGljIFN0cmluZyBnZXRQcmVmaXgoRGlhZ25vc3RpY1R5cGUgZHQpIHsKICAgICAgICByZXR1cm4gZGVmYXVsdEZvcm1hdHRlci5mb3JtYXRLaW5kKHRoaXMsIExvY2FsZS5nZXREZWZhdWx0KCkpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJuIHRoZSBzdGFuZGFyZCBwcmVzZW50YXRpb24gb2YgdGhpcyBkaWFnbm9zdGljLgogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CiAgICAgICAgcmV0dXJuIGRlZmF1bHRGb3JtYXR0ZXIuZm9ybWF0KHRoaXMsIExvY2FsZS5nZXREZWZhdWx0KCkpOwogICAgfQoKICAgIHByaXZhdGUgRGlhZ25vc3RpY0Zvcm1hdHRlcjxKQ0RpYWdub3N0aWM+IGRlZmF1bHRGb3JtYXR0ZXI7CiAgICBARGVwcmVjYXRlZAogICAgcHJpdmF0ZSBzdGF0aWMgRGlhZ25vc3RpY0Zvcm1hdHRlcjxKQ0RpYWdub3N0aWM+IGZyYWdtZW50Rm9ybWF0dGVyOwoKICAgIC8vIE1ldGhvZHMgZm9yIGphdmF4LnRvb2xzLkRpYWdub3N0aWMKCiAgICBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgIHB1YmxpYyBEaWFnbm9zdGljLktpbmQgZ2V0S2luZCgpIHsKICAgICAgICBzd2l0Y2ggKGRpYWdub3N0aWNJbmZvLnR5cGUpIHsKICAgICAgICBjYXNlIE5PVEU6CiAgICAgICAgICAgIHJldHVybiBEaWFnbm9zdGljLktpbmQuTk9URTsKICAgICAgICBjYXNlIFdBUk5JTkc6CiAgICAgICAgICAgIHJldHVybiBmbGFncy5jb250YWlucyhEaWFnbm9zdGljRmxhZy5NQU5EQVRPUlkpCiAgICAgICAgICAgICAgICAgICAgPyBEaWFnbm9zdGljLktpbmQuTUFOREFUT1JZX1dBUk5JTkcKICAgICAgICAgICAgICAgICAgICA6IERpYWdub3N0aWMuS2luZC5XQVJOSU5HOwogICAgICAgIGNhc2UgRVJST1I6CiAgICAgICAgICAgIHJldHVybiBEaWFnbm9zdGljLktpbmQuRVJST1I7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgcmV0dXJuIERpYWdub3N0aWMuS2luZC5PVEhFUjsKICAgICAgICB9CiAgICB9CgogICAgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICBwdWJsaWMgU3RyaW5nIGdldENvZGUoKSB7CiAgICAgICAgcmV0dXJuIGRpYWdub3N0aWNJbmZvLmtleSgpOwogICAgfQoKICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSKQogICAgcHVibGljIFN0cmluZyBnZXRNZXNzYWdlKExvY2FsZSBsb2NhbGUpIHsKICAgICAgICByZXR1cm4gZGVmYXVsdEZvcm1hdHRlci5mb3JtYXRNZXNzYWdlKHRoaXMsIGxvY2FsZSk7CiAgICB9CgogICAgcHVibGljIHZvaWQgc2V0RmxhZyhEaWFnbm9zdGljRmxhZyBmbGFnKSB7CiAgICAgICAgZmxhZ3MuYWRkKGZsYWcpOwoKICAgICAgICBpZiAoZGlhZ25vc3RpY0luZm8udHlwZSA9PSBEaWFnbm9zdGljVHlwZS5FUlJPUikgewogICAgICAgICAgICBzd2l0Y2ggKGZsYWcpIHsKICAgICAgICAgICAgICAgIGNhc2UgU1lOVEFYOgogICAgICAgICAgICAgICAgICAgIGZsYWdzLnJlbW92ZShEaWFnbm9zdGljRmxhZy5SRUNPVkVSQUJMRSk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIFJFU09MVkVfRVJST1I6CiAgICAgICAgICAgICAgICAgICAgZmxhZ3MuYWRkKERpYWdub3N0aWNGbGFnLlJFQ09WRVJBQkxFKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgYm9vbGVhbiBpc0ZsYWdTZXQoRGlhZ25vc3RpY0ZsYWcgZmxhZykgewogICAgICAgIHJldHVybiBmbGFncy5jb250YWlucyhmbGFnKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIE11bHRpbGluZURpYWdub3N0aWMgZXh0ZW5kcyBKQ0RpYWdub3N0aWMgewoKICAgICAgICBwcml2YXRlIGZpbmFsIExpc3Q8SkNEaWFnbm9zdGljPiBzdWJkaWFnbm9zdGljczsKCiAgICAgICAgcHVibGljIE11bHRpbGluZURpYWdub3N0aWMoSkNEaWFnbm9zdGljIG90aGVyLCBMaXN0PEpDRGlhZ25vc3RpYz4gc3ViZGlhZ25vc3RpY3MpIHsKICAgICAgICAgICAgc3VwZXIob3RoZXIuZGVmYXVsdEZvcm1hdHRlciwKICAgICAgICAgICAgICAgICAgb3RoZXIuZGlhZ25vc3RpY0luZm8sCiAgICAgICAgICAgICAgICAgIG90aGVyLmdldExpbnRDYXRlZ29yeSgpLAogICAgICAgICAgICAgICAgICBvdGhlci5mbGFncywKICAgICAgICAgICAgICAgICAgb3RoZXIuZ2V0RGlhZ25vc3RpY1NvdXJjZSgpLAogICAgICAgICAgICAgICAgICBvdGhlci5wb3NpdGlvbik7CiAgICAgICAgICAgIHRoaXMuc3ViZGlhZ25vc3RpY3MgPSBzdWJkaWFnbm9zdGljczsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBMaXN0PEpDRGlhZ25vc3RpYz4gZ2V0U3ViZGlhZ25vc3RpY3MoKSB7CiAgICAgICAgICAgIHJldHVybiBzdWJkaWFnbm9zdGljczsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBib29sZWFuIGlzTXVsdGlsaW5lKCkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICB9Cn0KUEsDBAoAAAgAANJ9TUoPf/HdjCgAAIwoAAAmAAAAY29tL3N1bi90b29scy9qYXZhYy91dGlsL1Bvc2l0aW9uLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDE5OTksIDIwMTIsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhYy51dGlsOwoKaW1wb3J0IGphdmEudXRpbC5CaXRTZXQ7CgppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkRlZmluZWRCeS5BcGk7CgppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5MYXlvdXRDaGFyYWN0ZXJzLio7CgovKiogQSBjbGFzcyB0aGF0IGRlZmluZXMgc291cmNlIGNvZGUgcG9zaXRpb25zIGFzIHNpbXBsZSBjaGFyYWN0ZXIKICogIG9mZnNldHMgZnJvbSB0aGUgYmVnaW5uaW5nIG9mIHRoZSBmaWxlLiBUaGUgZmlyc3QgY2hhcmFjdGVyCiAqICBpcyBhdCBwb3NpdGlvbiAwLgogKgogKiAgU3VwcG9ydCBpcyBhbHNvIHByb3ZpZGVkIGZvciAobGluZSxjb2x1bW4pIGNvb3JkaW5hdGVzLCBidXQgdGFiCiAqICBleHBhbnNpb24gaXMgb3B0aW9uYWwgYW5kIG5vIFVuaWNvZGUgZXhjYXBlIHRyYW5zbGF0aW9uIGlzIGNvbnNpZGVyZWQuCiAqICBUaGUgZmlyc3QgY2hhcmFjdGVyIGlzIGF0IGxvY2F0aW9uICgxLDEpLgogKgogKiAgPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24gcmlzay4KICogIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yCiAqICBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+CiAqLwpwdWJsaWMgY2xhc3MgUG9zaXRpb24gewogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTk9QT1MgICAgICAgID0gLTE7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklSU1RQT1MgICAgID0gMDsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJUlNUTElORSAgICA9IDE7CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSVJTVENPTFVNTiAgPSAxOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExJTkVTSElGVCAgICA9IDEwOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFYQ09MVU1OICAgID0gKDE8PExJTkVTSElGVCkgLSAxOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFYTElORSAgICAgID0gKDE8PChJbnRlZ2VyLlNJWkUtTElORVNISUZUKSkgLSAxOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1BWFBPUyAgICAgICA9IEludGVnZXIuTUFYX1ZBTFVFOwoKICAgIC8qKgogICAgICogVGhpcyBpcyBjbGFzcyBpcyBub3Qgc3VwcG9zZWQgdG8gYmUgaW5zdGFudGlhdGVkLgogICAgICovCiAgICBwcml2YXRlIFBvc2l0aW9uKCkge30KCiAgICAvKiogQSB0d28td2F5IG1hcCBiZXR3ZWVuIGxpbmUvY29sdW1uIG51bWJlcnMgYW5kIHBvc2l0aW9ucywKICAgICAqICBkZXJpdmVkIGZyb20gYSBzY2FuIGRvbmUgYXQgY3JlYXRpb24gdGltZS4gIFRhYiBleHBhbnNpb24gaXMKICAgICAqICBvcHRpb25hbGx5IHN1cHBvcnRlZCB2aWEgYSBjaGFyYWN0ZXIgbWFwLiAgVGV4dCBjb250ZW50CiAgICAgKiAgaXMgbm90IHJldGFpbmVkLgogICAgICo8cD4KICAgICAqICBOb3RlczogIFRoZSBmaXJzdCBjaGFyYWN0ZXIgcG9zaXRpb24gRklSU1RQT1MgaXMgYXQKICAgICAqICAoRklSU1RMSU5FLEZJUlNUQ09MVU1OKS4gIE5vIGFjY291bnQgaXMgdGFrZW4gb2YgVW5pY29kZSBlc2NhcGVzLgogICAgICoKICAgICAqIEBwYXJhbSAgIHNyYyAgICAgICAgIFNvdXJjZSBjaGFyYWN0ZXJzCiAgICAgKiBAcGFyYW0gICBtYXggICAgICAgICBOdW1iZXIgb2YgY2hhcmFjdGVycyB0byByZWFkCiAgICAgKiBAcGFyYW0gICBleHBhbmRUYWJzICBJZiB0cnVlLCBleHBhbmQgdGFicyB3aGVuIGNhbGN1bGF0aW5nIGNvbHVtbnMKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBMaW5lTWFwIG1ha2VMaW5lTWFwKGNoYXJbXSBzcmMsIGludCBtYXgsIGJvb2xlYW4gZXhwYW5kVGFicykgewogICAgICAgIExpbmVNYXBJbXBsIGxpbmVNYXAgPSBleHBhbmRUYWJzID8KICAgICAgICAgICAgbmV3IExpbmVUYWJNYXBJbXBsKG1heCkgOiBuZXcgTGluZU1hcEltcGwoKTsKICAgICAgICBsaW5lTWFwLmJ1aWxkKHNyYywgbWF4KTsKICAgICAgICByZXR1cm4gbGluZU1hcDsKICAgIH0KCiAgICAvKiogRW5jb2RlIGxpbmUgYW5kIGNvbHVtbiBudW1iZXJzIGluIGFuIGludGVnZXIgYXM6CiAgICAgKiAge0Bjb2RlIGxpbmUtbnVtYmVyIDw8IExJTkVTSElGVCArIGNvbHVtbi1udW1iZXIgfS4KICAgICAqICB7QGxpbmsgUG9zaXRpb24jTk9QT1N9IHJlcHJlc2VudHMgYW4gdW5kZWZpbmVkIHBvc2l0aW9uLgogICAgICoKICAgICAqIEBwYXJhbSAgbGluZSAgbnVtYmVyIG9mIGxpbmUgKGZpcnN0IGlzIDEpCiAgICAgKiBAcGFyYW0gIGNvbCAgIG51bWJlciBvZiBjaGFyYWN0ZXIgb24gbGluZSAoZmlyc3QgaXMgMSkKICAgICAqIEByZXR1cm4gICAgICAgYW4gZW5jb2RlZCBwb3NpdGlvbiBvciB7QGxpbmsgUG9zaXRpb24jTk9QT1N9CiAgICAgKiAgICAgICAgICAgICAgIGlmIHRoZSBsaW5lIG9yIGNvbHVtbiBudW1iZXIgaXMgdG9vIGJpZyB0bwogICAgICogICAgICAgICAgICAgICByZXByZXNlbnQgaW4gdGhlIGVuY29kZWQgZm9ybWF0CiAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiBsaW5lIG9yIGNvbCBpcyBsZXNzIHRoYW4gMQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGludCBlbmNvZGVQb3NpdGlvbihpbnQgbGluZSwgaW50IGNvbCkgewogICAgICAgIGlmIChsaW5lIDwgMSkKICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigibGluZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAwIik7CiAgICAgICAgaWYgKGNvbCA8IDEpCiAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oImNvbHVtbiBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAwIik7CgogICAgICAgIGlmIChsaW5lID4gTUFYTElORSB8fCBjb2wgPiBNQVhDT0xVTU4pIHsKICAgICAgICAgICAgcmV0dXJuIE5PUE9TOwogICAgICAgIH0KICAgICAgICByZXR1cm4gKGxpbmUgPDwgTElORVNISUZUKSArIGNvbDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGludGVyZmFjZSBMaW5lTWFwIGV4dGVuZHMgY29tLnN1bi5zb3VyY2UudHJlZS5MaW5lTWFwIHsKICAgICAgICAvKiogRmluZCB0aGUgc3RhcnQgcG9zaXRpb24gb2YgYSBsaW5lLgogICAgICAgICAqCiAgICAgICAgICogQHBhcmFtIGxpbmUgbnVtYmVyIG9mIGxpbmUgKGZpcnN0IGlzIDEpCiAgICAgICAgICogQHJldHVybiAgICAgcG9zaXRpb24gb2YgZmlyc3QgY2hhcmFjdGVyIGluIGxpbmUKICAgICAgICAgKiBAdGhyb3dzICBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KICAgICAgICAgKiAgICAgICAgICAgaWYge0Bjb2RlIGxpbmVOdW1iZXIgPCAxfQogICAgICAgICAqICAgICAgICAgICBpZiB7QGNvZGUgbGluZU51bWJlciA+IG5vLiBvZiBsaW5lc30KICAgICAgICAgKi8KICAgICAgICBpbnQgZ2V0U3RhcnRQb3NpdGlvbihpbnQgbGluZSk7CgogICAgICAgIC8qKiBGaW5kIHRoZSBwb3NpdGlvbiBjb3JyZXNwb25kaW5nIHRvIGEgKGxpbmUsY29sdW1uKS4KICAgICAgICAgKgogICAgICAgICAqIEBwYXJhbSAgIGxpbmUgICAgbnVtYmVyIG9mIGxpbmUgKGZpcnN0IGlzIDEpCiAgICAgICAgICogQHBhcmFtICAgY29sdW1uICBudW1iZXIgb2YgY2hhcmFjdGVyIG9uIGxpbmUgKGZpcnN0IGlzIDEpCiAgICAgICAgICoKICAgICAgICAgKiBAcmV0dXJuICBwb3NpdGlvbiBvZiBjaGFyYWN0ZXIKICAgICAgICAgKiBAdGhyb3dzICBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24KICAgICAgICAgKiAgICAgICAgICAgaWYge0Bjb2RlIGxpbmUgPCAxfQogICAgICAgICAqICAgICAgICAgICBpZiB7QGNvZGUgbGluZSA+IG5vLiBvZiBsaW5lc30KICAgICAgICAgKi8KICAgICAgICBpbnQgZ2V0UG9zaXRpb24oaW50IGxpbmUsIGludCBjb2x1bW4pOwoKICAgICAgICAvKiogRmluZCB0aGUgbGluZSBjb250YWluaW5nIGEgcG9zaXRpb247IGEgbGluZSB0ZXJtaW5hdGlvbgogICAgICAgICAqIGNoYXJhY3RlciBpcyBvbiB0aGUgbGluZSBpdCB0ZXJtaW5hdGVzLgogICAgICAgICAqCiAgICAgICAgICogQHBhcmFtICAgcG9zICBjaGFyYWN0ZXIgb2Zmc2V0IG9mIHRoZSBwb3NpdGlvbgogICAgICAgICAqIEByZXR1cm4gdGhlIGxpbmUgbnVtYmVyIG9uIHdoaWNoIHBvcyBvY2N1cnMgKGZpcnN0IGxpbmUgaXMgMSkKICAgICAgICAgKi8KICAgICAgICBpbnQgZ2V0TGluZU51bWJlcihpbnQgcG9zKTsKCiAgICAgICAgLyoqIEZpbmQgdGhlIGNvbHVtbiBmb3IgYSBjaGFyYWN0ZXIgcG9zaXRpb24uCiAgICAgICAgICogIE5vdGU6ICB0aGlzIG1ldGhvZCBkb2VzIG5vdCBoYW5kbGUgdGFiIGV4cGFuc2lvbi4KICAgICAgICAgKiAgSWYgdGFiIGV4cGFuc2lvbiBpcyBuZWVkZWQsIHVzZSBhIExpbmVUYWJNYXAgaW5zdGVhZC4KICAgICAgICAgKgogICAgICAgICAqIEBwYXJhbSAgcG9zICAgY2hhcmFjdGVyIG9mZnNldCBvZiB0aGUgcG9zaXRpb24KICAgICAgICAgKiBAcmV0dXJuICAgICAgIHRoZSBjb2x1bW4gbnVtYmVyIGF0IHdoaWNoIHBvcyBvY2N1cnMKICAgICAgICAgKi8KICAgICAgICBpbnQgZ2V0Q29sdW1uTnVtYmVyKGludCBwb3MpOwogICAgfQoKICAgIHN0YXRpYyBjbGFzcyBMaW5lTWFwSW1wbCBpbXBsZW1lbnRzIExpbmVNYXAgewogICAgICAgIHByb3RlY3RlZCBpbnRbXSBzdGFydFBvc2l0aW9uOyAvLyBzdGFydCBwb3NpdGlvbiBvZiBlYWNoIGxpbmUKCiAgICAgICAgcHJvdGVjdGVkIExpbmVNYXBJbXBsKCkge30KCiAgICAgICAgcHJvdGVjdGVkIHZvaWQgYnVpbGQoY2hhcltdIHNyYywgaW50IG1heCkgewogICAgICAgICAgICBpbnQgYyA9IDA7CiAgICAgICAgICAgIGludCBpID0gMDsKICAgICAgICAgICAgaW50W10gbGluZWJ1ZiA9IG5ldyBpbnRbbWF4XTsKICAgICAgICAgICAgd2hpbGUgKGkgPCBtYXgpIHsKICAgICAgICAgICAgICAgIGxpbmVidWZbYysrXSA9IGk7CiAgICAgICAgICAgICAgICBkbyB7CiAgICAgICAgICAgICAgICAgICAgY2hhciBjaCA9IHNyY1tpXTsKICAgICAgICAgICAgICAgICAgICBpZiAoY2ggPT0gJ1xyJyB8fCBjaCA9PSAnXG4nKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjaCA9PSAnXHInICYmIChpKzEpIDwgbWF4ICYmIHNyY1tpKzFdID09ICdcbicpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpICs9IDI7CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgICsraTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGNoID09ICdcdCcpCiAgICAgICAgICAgICAgICAgICAgICAgIHNldFRhYlBvc2l0aW9uKGkpOwogICAgICAgICAgICAgICAgfSB3aGlsZSAoKytpIDwgbWF4KTsKICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLnN0YXJ0UG9zaXRpb24gPSBuZXcgaW50W2NdOwogICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGxpbmVidWYsIDAsIHN0YXJ0UG9zaXRpb24sIDAsIGMpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIGludCBnZXRTdGFydFBvc2l0aW9uKGludCBsaW5lKSB7CiAgICAgICAgICAgIHJldHVybiBzdGFydFBvc2l0aW9uW2xpbmUgLSBGSVJTVExJTkVdOwogICAgICAgIH0KCiAgICAgICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgbG9uZyBnZXRTdGFydFBvc2l0aW9uKGxvbmcgbGluZSkgewogICAgICAgICAgICByZXR1cm4gZ2V0U3RhcnRQb3NpdGlvbihsb25nVG9JbnQobGluZSkpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIGludCBnZXRQb3NpdGlvbihpbnQgbGluZSwgaW50IGNvbHVtbikgewogICAgICAgICAgICByZXR1cm4gc3RhcnRQb3NpdGlvbltsaW5lIC0gRklSU1RMSU5FXSArIGNvbHVtbiAtIEZJUlNUQ09MVU1OOwogICAgICAgIH0KCiAgICAgICAgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgbG9uZyBnZXRQb3NpdGlvbihsb25nIGxpbmUsIGxvbmcgY29sdW1uKSB7CiAgICAgICAgICAgIHJldHVybiBnZXRQb3NpdGlvbihsb25nVG9JbnQobGluZSksIGxvbmdUb0ludChjb2x1bW4pKTsKICAgICAgICB9CgogICAgICAgIC8vIENhY2hlIG9mIGxhc3QgbGluZSBudW1iZXIgbG9va3VwCiAgICAgICAgcHJpdmF0ZSBpbnQgbGFzdFBvc2l0aW9uID0gUG9zaXRpb24uRklSU1RQT1M7CiAgICAgICAgcHJpdmF0ZSBpbnQgbGFzdExpbmUgPSBQb3NpdGlvbi5GSVJTVExJTkU7CgogICAgICAgIHB1YmxpYyBpbnQgZ2V0TGluZU51bWJlcihpbnQgcG9zKSB7CiAgICAgICAgICAgIGlmIChwb3MgPT0gbGFzdFBvc2l0aW9uKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gbGFzdExpbmU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgbGFzdFBvc2l0aW9uID0gcG9zOwoKICAgICAgICAgICAgaW50IGxvdyA9IDA7CiAgICAgICAgICAgIGludCBoaWdoID0gc3RhcnRQb3NpdGlvbi5sZW5ndGgtMTsKICAgICAgICAgICAgd2hpbGUgKGxvdyA8PSBoaWdoKSB7CiAgICAgICAgICAgICAgICBpbnQgbWlkID0gKGxvdyArIGhpZ2gpID4+IDE7CiAgICAgICAgICAgICAgICBpbnQgbWlkVmFsID0gc3RhcnRQb3NpdGlvblttaWRdOwoKICAgICAgICAgICAgICAgIGlmIChtaWRWYWwgPCBwb3MpCiAgICAgICAgICAgICAgICAgICAgbG93ID0gbWlkICsgMTsKICAgICAgICAgICAgICAgIGVsc2UgaWYgKG1pZFZhbCA+IHBvcykKICAgICAgICAgICAgICAgICAgICBoaWdoID0gbWlkIC0gMTsKICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgIGxhc3RMaW5lID0gbWlkICsgMTsgLy8gcG9zIGlzIGF0IGJlZ2lubmluZyBvZiB0aGlzIGxpbmUKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbGFzdExpbmU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgbGFzdExpbmUgPSBsb3c7CiAgICAgICAgICAgIHJldHVybiBsYXN0TGluZTsgIC8vIHBvcyBpcyBvbiB0aGlzIGxpbmUKICAgICAgICB9CgogICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIGxvbmcgZ2V0TGluZU51bWJlcihsb25nIHBvcykgewogICAgICAgICAgICByZXR1cm4gZ2V0TGluZU51bWJlcihsb25nVG9JbnQocG9zKSk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgaW50IGdldENvbHVtbk51bWJlcihpbnQgcG9zKSB7CiAgICAgICAgICAgIHJldHVybiBwb3MgLSBzdGFydFBvc2l0aW9uW2dldExpbmVOdW1iZXIocG9zKSAtIEZJUlNUTElORV0gKyBGSVJTVENPTFVNTjsKICAgICAgICB9CgogICAgICAgIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIGxvbmcgZ2V0Q29sdW1uTnVtYmVyKGxvbmcgcG9zKSB7CiAgICAgICAgICAgIHJldHVybiBnZXRDb2x1bW5OdW1iZXIobG9uZ1RvSW50KHBvcykpOwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgaW50IGxvbmdUb0ludChsb25nIGxvbmdWYWx1ZSkgewogICAgICAgICAgICBpbnQgaW50VmFsdWUgPSAoaW50KWxvbmdWYWx1ZTsKICAgICAgICAgICAgaWYgKGludFZhbHVlICE9IGxvbmdWYWx1ZSkKICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKCk7CiAgICAgICAgICAgIHJldHVybiBpbnRWYWx1ZTsKICAgICAgICB9CgogICAgICAgIHByb3RlY3RlZCB2b2lkIHNldFRhYlBvc2l0aW9uKGludCBvZmZzZXQpIHt9CiAgICB9CgogICAgLyoqCiAgICAgKiBBIExpbmVNYXAgdGhhdCBoYW5kbGVzIHRhYiBleHBhbnNpb24gY29ycmVjdGx5LiAgVGhlIGNvc3QgaXMKICAgICAqIGFuIGFkZGl0aW9uYWwgYml0IHBlciBjaGFyYWN0ZXIgaW4gdGhlIHNvdXJjZSBhcnJheS4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBjbGFzcyBMaW5lVGFiTWFwSW1wbCBleHRlbmRzIExpbmVNYXBJbXBsIHsKICAgICAgICBwcml2YXRlIEJpdFNldCB0YWJNYXA7ICAgICAgIC8vIGJpdHMgc2V0IGZvciB0YWIgcG9zaXRpb25zLgoKICAgICAgICBwdWJsaWMgTGluZVRhYk1hcEltcGwoaW50IG1heCkgewogICAgICAgICAgICBzdXBlcigpOwogICAgICAgICAgICB0YWJNYXAgPSBuZXcgQml0U2V0KG1heCk7CiAgICAgICAgfQoKICAgICAgICBwcm90ZWN0ZWQgdm9pZCBzZXRUYWJQb3NpdGlvbihpbnQgb2Zmc2V0KSB7CiAgICAgICAgICAgIHRhYk1hcC5zZXQob2Zmc2V0KTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBpbnQgZ2V0Q29sdW1uTnVtYmVyKGludCBwb3MpIHsKICAgICAgICAgICAgaW50IGxpbmVTdGFydCA9IHN0YXJ0UG9zaXRpb25bZ2V0TGluZU51bWJlcihwb3MpIC0gRklSU1RMSU5FXTsKICAgICAgICAgICAgaW50IGNvbHVtbiA9IDA7CiAgICAgICAgICAgIGZvciAoaW50IGJwID0gbGluZVN0YXJ0OyBicCA8IHBvczsgYnArKykgewogICAgICAgICAgICAgICAgaWYgKHRhYk1hcC5nZXQoYnApKQogICAgICAgICAgICAgICAgICAgIGNvbHVtbiA9IChjb2x1bW4gLyBUYWJJbmMgKiBUYWJJbmMpICsgVGFiSW5jOwogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIGNvbHVtbisrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBjb2x1bW4gKyBGSVJTVENPTFVNTjsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBpbnQgZ2V0UG9zaXRpb24oaW50IGxpbmUsIGludCBjb2x1bW4pIHsKICAgICAgICAgICAgaW50IHBvcyA9IHN0YXJ0UG9zaXRpb25bbGluZSAtIEZJUlNUTElORV07CiAgICAgICAgICAgIGNvbHVtbiAtPSBGSVJTVENPTFVNTjsKICAgICAgICAgICAgaW50IGNvbCA9IDA7CiAgICAgICAgICAgIHdoaWxlIChjb2wgPCBjb2x1bW4pIHsKICAgICAgICAgICAgICAgIHBvcysrOwogICAgICAgICAgICAgICAgaWYgKHRhYk1hcC5nZXQocG9zKSkKICAgICAgICAgICAgICAgICAgICBjb2wgPSAoY29sIC8gVGFiSW5jICogVGFiSW5jKSArIFRhYkluYzsKICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICBjb2wrKzsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gcG9zOwogICAgICAgIH0KICAgIH0KfQpQSwMECgAACAAABjupSugihoy0HAAAtBwAACUAAABjb20vc3VuL3Rvb2xzL2phdmFjL3V0aWwvQ29udGV4dC5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDAxLCAyMDE0LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuamF2YWMudXRpbDsKCmltcG9ydCBqYXZhLnV0aWwuKjsKCi8qKgogKiBTdXBwb3J0IGZvciBhbiBhYnN0cmFjdCBjb250ZXh0LCBtb2RlbGxlZCBsb29zZWx5IGFmdGVyIFRocmVhZExvY2FsCiAqIGJ1dCB1c2luZyBhIHVzZXItcHJvdmlkZWQgY29udGV4dCBpbnN0ZWFkIG9mIHRoZSBjdXJyZW50IHRocmVhZC4KICoKICogPHA+V2l0aGluIHRoZSBjb21waWxlciwgYSBzaW5nbGUgQ29udGV4dCBpcyB1c2VkIGZvciBlYWNoCiAqIGludm9jYXRpb24gb2YgdGhlIGNvbXBpbGVyLiAgVGhlIGNvbnRleHQgaXMgdGhlbiB1c2VkIHRvIGVuc3VyZSBhCiAqIHNpbmdsZSBjb3B5IG9mIGVhY2ggY29tcGlsZXIgcGhhc2UgZXhpc3RzIHBlciBjb21waWxlciBpbnZvY2F0aW9uLgogKgogKiA8cD5UaGUgY29udGV4dCBjYW4gYmUgdXNlZCB0byBhc3Npc3QgaW4gZXh0ZW5kaW5nIHRoZSBjb21waWxlciBieQogKiBleHRlbmRpbmcgaXRzIGNvbXBvbmVudHMuICBUbyBkbyB0aGF0LCB0aGUgZXh0ZW5kZWQgY29tcG9uZW50IG11c3QKICogYmUgcmVnaXN0ZXJlZCBiZWZvcmUgdGhlIGJhc2UgY29tcG9uZW50LiAgV2UgYnJlYWsgaW5pdGlhbGl6YXRpb24KICogY3ljbGVzIGJ5ICgxKSByZWdpc3RlcmluZyBhIGZhY3RvcnkgZm9yIHRoZSBjb21wb25lbnQgcmF0aGVyIHRoYW4KICogdGhlIGNvbXBvbmVudCBpdHNlbGYsIGFuZCAoMikgYSBjb252ZW50aW9uIGZvciBhIHBhdHRlcm4gb2YgdXNhZ2UKICogaW4gd2hpY2ggZWFjaCBiYXNlIGNvbXBvbmVudCByZWdpc3RlcnMgaXRzZWxmIGJ5IGNhbGxpbmcgYW4KICogaW5zdGFuY2UgbWV0aG9kIHRoYXQgaXMgb3ZlcnJpZGRlbiBpbiBleHRlbmRlZCBjb21wb25lbnRzLiAgQSBiYXNlCiAqIHBoYXNlIHN1cHBvcnRpbmcgZXh0ZW5zaW9uIHdvdWxkIGxvb2sgc29tZXRoaW5nIGxpa2UgdGhpczoKICoKICogPHByZT57QGNvZGUKICogcHVibGljIGNsYXNzIFBoYXNlIHsKICogICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgQ29udGV4dC5LZXk8UGhhc2U+IHBoYXNlS2V5ID0KICogICAgICAgICBuZXcgQ29udGV4dC5LZXk8UGhhc2U+KCk7CiAqCiAqICAgICBwdWJsaWMgc3RhdGljIFBoYXNlIGluc3RhbmNlKENvbnRleHQgY29udGV4dCkgewogKiAgICAgICAgIFBoYXNlIGluc3RhbmNlID0gY29udGV4dC5nZXQocGhhc2VLZXkpOwogKiAgICAgICAgIGlmIChpbnN0YW5jZSA9PSBudWxsKQogKiAgICAgICAgICAgICAvLyB0aGUgcGhhc2UgaGFzIG5vdCBiZWVuIG92ZXJyaWRkZW4KICogICAgICAgICAgICAgaW5zdGFuY2UgPSBuZXcgUGhhc2UoY29udGV4dCk7CiAqICAgICAgICAgcmV0dXJuIGluc3RhbmNlOwogKiAgICAgfQogKgogKiAgICAgcHJvdGVjdGVkIFBoYXNlKENvbnRleHQgY29udGV4dCkgewogKiAgICAgICAgIGNvbnRleHQucHV0KHBoYXNlS2V5LCB0aGlzKTsKICogICAgICAgICAvLyBvdGhlciBpbnRpdGlhbGl6YXRpb24gZm9sbG93cy4uLgogKiAgICAgfQogKiB9CiAqIH08L3ByZT4KICoKICogPHA+SW4gdGhlIGNvbXBpbGVyLCB3ZSBzaW1wbHkgdXNlIFBoYXNlLmluc3RhbmNlKGNvbnRleHQpIHRvIGdldAogKiB0aGUgcmVmZXJlbmNlIHRvIHRoZSBwaGFzZS4gIEJ1dCBpbiBleHRlbnNpb25zIG9mIHRoZSBjb21waWxlciwgd2UKICogbXVzdCByZWdpc3RlciBleHRlbnNpb25zIG9mIHRoZSBwaGFzZXMgdG8gcmVwbGFjZSB0aGUgYmFzZSBwaGFzZSwKICogYW5kIHRoaXMgbXVzdCBiZSBkb25lIGJlZm9yZSBhbnkgcmVmZXJlbmNlIHRvIHRoZSBwaGFzZSBpcyBhY2Nlc3NlZAogKiB1c2luZyBQaGFzZS5pbnN0YW5jZSgpLiAgQW4gZXh0ZW5kZWQgcGhhc2UgbWlnaHQgYmUgZGVjbGFyZWQgdGh1czoKICoKICogPHByZT57QGNvZGUKICogcHVibGljIGNsYXNzIE5ld1BoYXNlIGV4dGVuZHMgUGhhc2UgewogKiAgICAgcHJvdGVjdGVkIE5ld1BoYXNlKENvbnRleHQgY29udGV4dCkgewogKiAgICAgICAgIHN1cGVyKGNvbnRleHQpOwogKiAgICAgfQogKiAgICAgcHVibGljIHN0YXRpYyB2b2lkIHByZVJlZ2lzdGVyKGZpbmFsIENvbnRleHQgY29udGV4dCkgewogKiAgICAgICAgIGNvbnRleHQucHV0KHBoYXNlS2V5LCBuZXcgQ29udGV4dC5GYWN0b3J5PFBoYXNlPigpIHsKICogICAgICAgICAgICAgcHVibGljIFBoYXNlIG1ha2UoKSB7CiAqICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IE5ld1BoYXNlKGNvbnRleHQpOwogKiAgICAgICAgICAgICB9CiAqICAgICAgICAgfSk7CiAqICAgICB9CiAqIH0KICogfTwvcHJlPgogKgogKiA8cD5BbmQgaXMgcmVnaXN0ZXJlZCBlYXJseSBpbiB0aGUgZXh0ZW5kZWQgY29tcGlsZXIgbGlrZSB0aGlzCiAqCiAqIDxwcmU+CiAqICAgICBOZXdQaGFzZS5wcmVSZWdpc3Rlcihjb250ZXh0KTsKICogPC9wcmU+CiAqCiAqICA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiAgSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93biByaXNrLgogKiAgVGhpcyBjb2RlIGFuZCBpdHMgaW50ZXJuYWwgaW50ZXJmYWNlcyBhcmUgc3ViamVjdCB0byBjaGFuZ2Ugb3IKICogIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj4KICovCnB1YmxpYyBjbGFzcyBDb250ZXh0IHsKICAgIC8qKiBUaGUgY2xpZW50IGNyZWF0ZXMgYW4gaW5zdGFuY2Ugb2YgdGhpcyBjbGFzcyBmb3IgZWFjaCBrZXkuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgS2V5PFQ+IHsKICAgICAgICAvLyBub3RlOiB3ZSBpbmhlcml0IGlkZW50aXR5IGVxdWFsaXR5IGZyb20gT2JqZWN0LgogICAgfQoKICAgIC8qKgogICAgICogVGhlIGNsaWVudCBjYW4gcmVnaXN0ZXIgYSBmYWN0b3J5IGZvciBsYXp5IGNyZWF0aW9uIG9mIHRoZQogICAgICogaW5zdGFuY2UuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgaW50ZXJmYWNlIEZhY3Rvcnk8VD4gewogICAgICAgIFQgbWFrZShDb250ZXh0IGMpOwogICAgfQoKICAgIC8qKgogICAgICogVGhlIHVuZGVybHlpbmcgbWFwIHN0b3JpbmcgdGhlIGRhdGEuCiAgICAgKiBXZSBtYWludGFpbiB0aGUgaW52YXJpYW50IHRoYXQgdGhpcyB0YWJsZSBjb250YWlucyBvbmx5CiAgICAgKiBtYXBwaW5ncyBvZiB0aGUgZm9ybQogICAgICoge0BsaXRlcmFsIEtleTxUPiAtPiBUIH0KICAgICAqIG9yCiAgICAgKiB7QGxpdGVyYWwgS2V5PFQ+IC0+IEZhY3Rvcnk8VD4gfQogICAgICovCiAgICBwcm90ZWN0ZWQgZmluYWwgTWFwPEtleTw/PixPYmplY3Q+IGh0ID0gbmV3IEhhc2hNYXA8PigpOwoKICAgIC8qKiBTZXQgdGhlIGZhY3RvcnkgZm9yIHRoZSBrZXkgaW4gdGhpcyBjb250ZXh0LiAqLwogICAgcHVibGljIDxUPiB2b2lkIHB1dChLZXk8VD4ga2V5LCBGYWN0b3J5PFQ+IGZhYykgewogICAgICAgIGNoZWNrU3RhdGUoaHQpOwogICAgICAgIE9iamVjdCBvbGQgPSBodC5wdXQoa2V5LCBmYWMpOwogICAgICAgIGlmIChvbGQgIT0gbnVsbCkKICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCJkdXBsaWNhdGUgY29udGV4dCB2YWx1ZSIpOwogICAgICAgIGNoZWNrU3RhdGUoZnQpOwogICAgICAgIGZ0LnB1dChrZXksIGZhYyk7IC8vIGNhbm5vdCBiZSBkdXBsaWNhdGUgaWYgdW5pcXVlIGluIGh0CiAgICB9CgogICAgLyoqIFNldCB0aGUgdmFsdWUgZm9yIHRoZSBrZXkgaW4gdGhpcyBjb250ZXh0LiAqLwogICAgcHVibGljIDxUPiB2b2lkIHB1dChLZXk8VD4ga2V5LCBUIGRhdGEpIHsKICAgICAgICBpZiAoZGF0YSBpbnN0YW5jZW9mIEZhY3Rvcnk8Pz4pCiAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigiVCBleHRlbmRzIENvbnRleHQuRmFjdG9yeSIpOwogICAgICAgIGNoZWNrU3RhdGUoaHQpOwogICAgICAgIE9iamVjdCBvbGQgPSBodC5wdXQoa2V5LCBkYXRhKTsKICAgICAgICBpZiAob2xkICE9IG51bGwgJiYgIShvbGQgaW5zdGFuY2VvZiBGYWN0b3J5PD8+KSAmJiBvbGQgIT0gZGF0YSAmJiBkYXRhICE9IG51bGwpCiAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigiZHVwbGljYXRlIGNvbnRleHQgdmFsdWUiKTsKICAgIH0KCiAgICAvKiogR2V0IHRoZSB2YWx1ZSBmb3IgdGhlIGtleSBpbiB0aGlzIGNvbnRleHQuICovCiAgICBwdWJsaWMgPFQ+IFQgZ2V0KEtleTxUPiBrZXkpIHsKICAgICAgICBjaGVja1N0YXRlKGh0KTsKICAgICAgICBPYmplY3QgbyA9IGh0LmdldChrZXkpOwogICAgICAgIGlmIChvIGluc3RhbmNlb2YgRmFjdG9yeTw/PikgewogICAgICAgICAgICBGYWN0b3J5PD8+IGZhYyA9IChGYWN0b3J5PD8+KW87CiAgICAgICAgICAgIG8gPSBmYWMubWFrZSh0aGlzKTsKICAgICAgICAgICAgaWYgKG8gaW5zdGFuY2VvZiBGYWN0b3J5PD8+KQogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCJUIGV4dGVuZHMgQ29udGV4dC5GYWN0b3J5Iik7CiAgICAgICAgICAgIEFzc2VydC5jaGVjayhodC5nZXQoa2V5KSA9PSBvKTsKICAgICAgICB9CgogICAgICAgIC8qIFRoZSBmb2xsb3dpbmcgY2FzdCBjYW4ndCBmYWlsIHVubGVzcyB0aGVyZSB3YXMKICAgICAgICAgKiBjaGVhdGluZyBlbHNld2hlcmUsIGJlY2F1c2Ugb2YgdGhlIGludmFyaWFudCBvbiBodC4KICAgICAgICAgKiBTaW5jZSB3ZSBmb3VuZCBhIGtleSBvZiB0eXBlIEtleTxUPiwgdGhlIHZhbHVlIG11c3QKICAgICAgICAgKiBiZSBvZiB0eXBlIFQuCiAgICAgICAgICovCiAgICAgICAgcmV0dXJuIENvbnRleHQudW5jaGVja2VkQ2FzdChvKTsKICAgIH0KCiAgICBwdWJsaWMgQ29udGV4dCgpIHt9CgogICAgLyoqCiAgICAgKiBUaGUgdGFibGUgb2YgcHJlcmVnaXN0ZXJlZCBmYWN0b3JpZXMuCiAgICAgKi8KICAgIHByaXZhdGUgZmluYWwgTWFwPEtleTw/PixGYWN0b3J5PD8+PiBmdCA9IG5ldyBIYXNoTWFwPD4oKTsKCiAgICAvKgogICAgICogVGhlIGtleSB0YWJsZSwgcHJvdmlkaW5nIGEgdW5pcXVlIEtleTxUPiBmb3IgZWFjaCBDbGFzczxUPi4KICAgICAqLwogICAgcHJpdmF0ZSBmaW5hbCBNYXA8Q2xhc3M8Pz4sIEtleTw/Pj4ga3QgPSBuZXcgSGFzaE1hcDw+KCk7CgogICAgcHJvdGVjdGVkIDxUPiBLZXk8VD4ga2V5KENsYXNzPFQ+IGNsc3MpIHsKICAgICAgICBjaGVja1N0YXRlKGt0KTsKICAgICAgICBLZXk8VD4gayA9IHVuY2hlY2tlZENhc3Qoa3QuZ2V0KGNsc3MpKTsKICAgICAgICBpZiAoayA9PSBudWxsKSB7CiAgICAgICAgICAgIGsgPSBuZXcgS2V5PD4oKTsKICAgICAgICAgICAga3QucHV0KGNsc3MsIGspOwogICAgICAgIH0KICAgICAgICByZXR1cm4gazsKICAgIH0KCiAgICBwdWJsaWMgPFQ+IFQgZ2V0KENsYXNzPFQ+IGNsYXp6KSB7CiAgICAgICAgcmV0dXJuIGdldChrZXkoY2xhenopKTsKICAgIH0KCiAgICBwdWJsaWMgPFQ+IHZvaWQgcHV0KENsYXNzPFQ+IGNsYXp6LCBUIGRhdGEpIHsKICAgICAgICBwdXQoa2V5KGNsYXp6KSwgZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgPFQ+IHZvaWQgcHV0KENsYXNzPFQ+IGNsYXp6LCBGYWN0b3J5PFQ+IGZhYykgewogICAgICAgIHB1dChrZXkoY2xhenopLCBmYWMpOwogICAgfQoKICAgIC8qKgogICAgICogVE9ETzogVGhpcyBtZXRob2Qgc2hvdWxkIGJlIHJlbW92ZWQgYW5kIENvbnRleHQgc2hvdWxkIGJlIG1hZGUgdHlwZSBzYWZlLgogICAgICogVGhpcyBjYW4gYmUgYWNjb21wbGlzaGVkIGJ5IHVzaW5nIGNsYXNzIGxpdGVyYWxzIGFzIHR5cGUgdG9rZW5zLgogICAgICovCiAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKICAgIHByaXZhdGUgc3RhdGljIDxUPiBUIHVuY2hlY2tlZENhc3QoT2JqZWN0IG8pIHsKICAgICAgICByZXR1cm4gKFQpbzsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCBkdW1wKCkgewogICAgICAgIGZvciAoT2JqZWN0IHZhbHVlIDogaHQudmFsdWVzKCkpCiAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbih2YWx1ZSA9PSBudWxsID8gbnVsbCA6IHZhbHVlLmdldENsYXNzKCkpOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIHZvaWQgY2hlY2tTdGF0ZShNYXA8Pyw/PiB0KSB7CiAgICAgICAgaWYgKHQgPT0gbnVsbCkKICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigpOwogICAgfQp9ClBLAwQKAAAIAAAGO6lKbq5xPN8RAADfEQAAJAAAAGNvbS9zdW4vdG9vbHMvamF2YWMvdXRpbC9Bc3NlcnQuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAxMSwgMjAxNCwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWw7CgppbXBvcnQgamF2YS51dGlsLmZ1bmN0aW9uLlN1cHBsaWVyOwoKLyoqCiAqIFNpbXBsZSBmYWNpbGl0eSBmb3IgdW5jb25kaXRpb25hbCBhc3NlcnRpb25zLgogKiBUaGUgbWV0aG9kcyBpbiB0aGlzIGNsYXNzIGFyZSBkZXNjcmliZWQgaW4gdGVybXMgb2YgZXF1aXZhbGVudCBhc3NlcnQKICogc3RhdGVtZW50cywgYXNzdW1pbmcgdGhhdCBhc3NlcnRpb25zIGhhdmUgYmVlbiBlbmFibGVkLgogKgogKiAgPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24gcmlzay4KICogIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yCiAqICBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+CiAqLwpwdWJsaWMgY2xhc3MgQXNzZXJ0IHsKICAgIC8qKiBFcXVpdmFsZW50IHRvCiAgICAgKiAgIGFzc2VydCBjb25kOwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIHZvaWQgY2hlY2soYm9vbGVhbiBjb25kKSB7CiAgICAgICAgaWYgKCFjb25kKQogICAgICAgICAgICBlcnJvcigpOwogICAgfQoKICAgIC8qKiBFcXVpdmFsZW50IHRvCiAgICAgKiAgIGFzc2VydCAobyA9PSBudWxsKTsKICAgICAqLwogICAgcHVibGljIHN0YXRpYyB2b2lkIGNoZWNrTnVsbChPYmplY3QgbykgewogICAgICAgIGlmIChvICE9IG51bGwpCiAgICAgICAgICAgIGVycm9yKCk7CiAgICB9CgogICAgLyoqIEVxdWl2YWxlbnQgdG8KICAgICAqICAgYXNzZXJ0ICh0ICE9IG51bGwpOyByZXR1cm4gdDsKICAgICAqLwogICAgcHVibGljIHN0YXRpYyA8VD4gVCBjaGVja05vbk51bGwoVCB0KSB7CiAgICAgICAgaWYgKHQgPT0gbnVsbCkKICAgICAgICAgICAgZXJyb3IoKTsKICAgICAgICByZXR1cm4gdDsKICAgIH0KCiAgICAvKiogRXF1aXZhbGVudCB0bwogICAgICogICBhc3NlcnQgY29uZCA6IHZhbHVlOwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIHZvaWQgY2hlY2soYm9vbGVhbiBjb25kLCBpbnQgdmFsdWUpIHsKICAgICAgICBpZiAoIWNvbmQpCiAgICAgICAgICAgIGVycm9yKFN0cmluZy52YWx1ZU9mKHZhbHVlKSk7CiAgICB9CgogICAgLyoqIEVxdWl2YWxlbnQgdG8KICAgICAqICAgYXNzZXJ0IGNvbmQgOiB2YWx1ZTsKICAgICAqLwogICAgcHVibGljIHN0YXRpYyB2b2lkIGNoZWNrKGJvb2xlYW4gY29uZCwgbG9uZyB2YWx1ZSkgewogICAgICAgIGlmICghY29uZCkKICAgICAgICAgICAgZXJyb3IoU3RyaW5nLnZhbHVlT2YodmFsdWUpKTsKICAgIH0KCiAgICAvKiogRXF1aXZhbGVudCB0bwogICAgICogICBhc3NlcnQgY29uZCA6IHZhbHVlOwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIHZvaWQgY2hlY2soYm9vbGVhbiBjb25kLCBPYmplY3QgdmFsdWUpIHsKICAgICAgICBpZiAoIWNvbmQpCiAgICAgICAgICAgIGVycm9yKFN0cmluZy52YWx1ZU9mKHZhbHVlKSk7CiAgICB9CgogICAgLyoqIEVxdWl2YWxlbnQgdG8KICAgICAqICAgYXNzZXJ0IGNvbmQgOiBtc2c7CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBjaGVjayhib29sZWFuIGNvbmQsIFN0cmluZyBtc2cpIHsKICAgICAgICBpZiAoIWNvbmQpCiAgICAgICAgICAgIGVycm9yKG1zZyk7CiAgICB9CgogICAgLyoqIEVxdWl2YWxlbnQgdG8KICAgICAqICAgYXNzZXJ0IGNvbmQgOiBtc2cuZ2V0KCk7CiAgICAgKiAgTm90ZTogbWVzc2FnZSBzdHJpbmcgaXMgY29tcHV0ZWQgbGF6aWx5LgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIHZvaWQgY2hlY2soYm9vbGVhbiBjb25kLCBTdXBwbGllcjxTdHJpbmc+IG1zZykgewogICAgICAgIGlmICghY29uZCkKICAgICAgICAgICAgZXJyb3IobXNnLmdldCgpKTsKICAgIH0KCiAgICAvKiogRXF1aXZhbGVudCB0bwogICAgICogICBhc3NlcnQgKG8gPT0gbnVsbCkgOiB2YWx1ZTsKICAgICAqLwogICAgcHVibGljIHN0YXRpYyB2b2lkIGNoZWNrTnVsbChPYmplY3QgbywgT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgaWYgKG8gIT0gbnVsbCkKICAgICAgICAgICAgZXJyb3IoU3RyaW5nLnZhbHVlT2YodmFsdWUpKTsKICAgIH0KCiAgICAvKiogRXF1aXZhbGVudCB0bwogICAgICogICBhc3NlcnQgKG8gPT0gbnVsbCkgOiBtc2c7CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBjaGVja051bGwoT2JqZWN0IG8sIFN0cmluZyBtc2cpIHsKICAgICAgICBpZiAobyAhPSBudWxsKQogICAgICAgICAgICBlcnJvcihtc2cpOwogICAgfQoKICAgIC8qKiBFcXVpdmFsZW50IHRvCiAgICAgKiAgIGFzc2VydCAobyA9PSBudWxsKSA6IG1zZy5nZXQoKTsKICAgICAqICBOb3RlOiBtZXNzYWdlIHN0cmluZyBpcyBjb21wdXRlZCBsYXppbHkuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBjaGVja051bGwoT2JqZWN0IG8sIFN1cHBsaWVyPFN0cmluZz4gbXNnKSB7CiAgICAgICAgaWYgKG8gIT0gbnVsbCkKICAgICAgICAgICAgZXJyb3IobXNnLmdldCgpKTsKICAgIH0KCiAgICAvKiogRXF1aXZhbGVudCB0bwogICAgICogICBhc3NlcnQgKG8gIT0gbnVsbCkgOiBtc2c7CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgPFQ+IFQgY2hlY2tOb25OdWxsKFQgdCwgU3RyaW5nIG1zZykgewogICAgICAgIGlmICh0ID09IG51bGwpCiAgICAgICAgICAgIGVycm9yKG1zZyk7CiAgICAgICAgcmV0dXJuIHQ7CiAgICB9CgogICAgLyoqIEVxdWl2YWxlbnQgdG8KICAgICAqICAgYXNzZXJ0IChvICE9IG51bGwpIDogbXNnLmdldCgpOwogICAgICogIE5vdGU6IG1lc3NhZ2Ugc3RyaW5nIGlzIGNvbXB1dGVkIGxhemlseS4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyA8VD4gVCBjaGVja05vbk51bGwoVCB0LCBTdXBwbGllcjxTdHJpbmc+IG1zZykgewogICAgICAgIGlmICh0ID09IG51bGwpCiAgICAgICAgICAgIGVycm9yKG1zZy5nZXQoKSk7CiAgICAgICAgcmV0dXJuIHQ7CiAgICB9CgogICAgLyoqIEVxdWl2YWxlbnQgdG8KICAgICAqICAgYXNzZXJ0IGZhbHNlOwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIHZvaWQgZXJyb3IoKSB7CiAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCk7CiAgICB9CgogICAgLyoqIEVxdWl2YWxlbnQgdG8KICAgICAqICAgYXNzZXJ0IGZhbHNlIDogbXNnOwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIHZvaWQgZXJyb3IoU3RyaW5nIG1zZykgewogICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihtc2cpOwogICAgfQoKICAgIC8qKiBQcmV2ZW50IGluc3RhbnRpYXRpb24uICovCiAgICBwcml2YXRlIEFzc2VydCgpIHsgfQp9ClBLAwQKAAAIAADSfU1Kc1YL5oQLAACECwAAKQAAAGNvbS9zdW4vdG9vbHMvamF2YWMvdXRpbC9TdHJpbmdVdGlscy5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDEzLCAyMDE0LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuamF2YWMudXRpbDsKCmltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOwppbXBvcnQgamF2YS51dGlsLnJlZ2V4Lk1hdGNoZXI7CmltcG9ydCBqYXZhLnV0aWwucmVnZXguUGF0dGVybjsKCi8qKiBBIGNvbGxlY3Rpb24gb2YgdXRpbGl0aWVzIGZvciBTdHJpbmcgbWFuaXB1bGF0aW9uLgogKgogKiAgPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24gcmlzay4KICogIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yCiAqICBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+CiAqLwpwdWJsaWMgY2xhc3MgU3RyaW5nVXRpbHMgewoKICAgIC8qKkNvbnZlcnRzIHRoZSBnaXZlbiBTdHJpbmcgdG8gbG93ZXIgY2FzZSB1c2luZyB0aGUge0BsaW5rIExvY2FsZSNVUyBVUyBMb2NhbGV9LiBUaGUgcmVzdWx0CiAgICAgKiBpcyBpbmRlcGVuZGVudCBvZiB0aGUgZGVmYXVsdCBMb2NhbGUgaW4gdGhlIGN1cnJlbnQgSlZNIGluc3RhbmNlLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIFN0cmluZyB0b0xvd2VyQ2FzZShTdHJpbmcgc291cmNlKSB7CiAgICAgICAgcmV0dXJuIHNvdXJjZS50b0xvd2VyQ2FzZShMb2NhbGUuVVMpOwogICAgfQoKICAgIC8qKkNvbnZlcnRzIHRoZSBnaXZlbiBTdHJpbmcgdG8gdXBwZXIgY2FzZSB1c2luZyB0aGUge0BsaW5rIExvY2FsZSNVUyBVUyBMb2NhbGV9LiBUaGUgcmVzdWx0CiAgICAgKiBpcyBpbmRlcGVuZGVudCBvZiB0aGUgZGVmYXVsdCBMb2NhbGUgaW4gdGhlIGN1cnJlbnQgSlZNIGluc3RhbmNlLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIFN0cmluZyB0b1VwcGVyQ2FzZShTdHJpbmcgc291cmNlKSB7CiAgICAgICAgcmV0dXJuIHNvdXJjZS50b1VwcGVyQ2FzZShMb2NhbGUuVVMpOwogICAgfQoKICAgIC8qKkNhc2UgaW5zZW5zaXRpdmUgdmVyc2lvbiBvZiB7QGxpbmsgU3RyaW5nI2luZGV4T2YoamF2YS5sYW5nLlN0cmluZyl9LiBFcXVpdmFsZW50IHRvCiAgICAgKiB7QGNvZGUgdGV4dC5pbmRleE9mKHN0cil9LCBleGNlcHQgdGhlIG1hdGNoaW5nIGlzIGNhc2UgaW5zZW5zaXRpdmUuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgaW50IGluZGV4T2ZJZ25vcmVDYXNlKFN0cmluZyB0ZXh0LCBTdHJpbmcgc3RyKSB7CiAgICAgICAgcmV0dXJuIGluZGV4T2ZJZ25vcmVDYXNlKHRleHQsIHN0ciwgMCk7CiAgICB9CgogICAgLyoqQ2FzZSBpbnNlbnNpdGl2ZSB2ZXJzaW9uIG9mIHtAbGluayBTdHJpbmcjaW5kZXhPZihqYXZhLmxhbmcuU3RyaW5nLCBpbnQpfS4gRXF1aXZhbGVudCB0bwogICAgICoge0Bjb2RlIHRleHQuaW5kZXhPZihzdHIsIHN0YXJ0SW5kZXgpfSwgZXhjZXB0IHRoZSBtYXRjaGluZyBpcyBjYXNlIGluc2Vuc2l0aXZlLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGludCBpbmRleE9mSWdub3JlQ2FzZShTdHJpbmcgdGV4dCwgU3RyaW5nIHN0ciwgaW50IHN0YXJ0SW5kZXgpIHsKICAgICAgICBNYXRjaGVyIG0gPSBQYXR0ZXJuLmNvbXBpbGUoUGF0dGVybi5xdW90ZShzdHIpLCBQYXR0ZXJuLkNBU0VfSU5TRU5TSVRJVkUpLm1hdGNoZXIodGV4dCk7CiAgICAgICAgcmV0dXJuIG0uZmluZChzdGFydEluZGV4KSA/IG0uc3RhcnQoKSA6IC0xOwogICAgfQoKfQpQSwMECgAACAAABjupSnwDYpveDAAA3gwAACcAAABjb20vc3VuL3Rvb2xzL2phdmFjL3V0aWwvSXRlcmF0b3JzLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTUsIDIwMTYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhYy51dGlsOwoKaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKaW1wb3J0IGphdmEudXRpbC5Ob1N1Y2hFbGVtZW50RXhjZXB0aW9uOwppbXBvcnQgamF2YS51dGlsLmZ1bmN0aW9uLkZ1bmN0aW9uOwoKLyoqIFV0aWxpdGllcyBmb3IgSXRlcmF0b3JzLgogKgogKiAgPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24gcmlzay4KICogIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yCiAqICBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+CiAqLwpwdWJsaWMgY2xhc3MgSXRlcmF0b3JzIHsKCiAgICBwdWJsaWMgc3RhdGljIDxJLCBPPiBJdGVyYXRvcjxPPiBjcmVhdGVDb21wb3VuZEl0ZXJhdG9yKEl0ZXJhYmxlPEk+IGlucHV0cywgRnVuY3Rpb248SSwgSXRlcmF0b3I8Tz4+IGNvbnZlcnRvcikgewogICAgICAgIHJldHVybiBuZXcgQ29tcG91bmRJdGVyYXRvcjw+KGlucHV0cywgY29udmVydG9yKTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBDb21wb3VuZEl0ZXJhdG9yPEksIE8+IGltcGxlbWVudHMgSXRlcmF0b3I8Tz4gewoKICAgICAgICBwcml2YXRlIGZpbmFsIEl0ZXJhdG9yPEk+IGlucHV0czsKICAgICAgICBwcml2YXRlIGZpbmFsIEZ1bmN0aW9uPEksIEl0ZXJhdG9yPE8+PiBjb252ZXJ0b3I7CiAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCiAgICAgICAgcHJpdmF0ZSBJdGVyYXRvcjxPPiBjdXJyZW50SXRlcmF0b3IgPSBFTVBUWTsKCiAgICAgICAgcHVibGljIENvbXBvdW5kSXRlcmF0b3IoSXRlcmFibGU8ST4gaW5wdXRzLCBGdW5jdGlvbjxJLCBJdGVyYXRvcjxPPj4gY29udmVydG9yKSB7CiAgICAgICAgICAgIHRoaXMuaW5wdXRzID0gaW5wdXRzLml0ZXJhdG9yKCk7CiAgICAgICAgICAgIHRoaXMuY29udmVydG9yID0gY29udmVydG9yOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzTmV4dCgpIHsKICAgICAgICAgICAgaWYgKGN1cnJlbnRJdGVyYXRvciAhPSBudWxsICYmICFjdXJyZW50SXRlcmF0b3IuaGFzTmV4dCgpKSB7CiAgICAgICAgICAgICAgICB1cGRhdGUoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gY3VycmVudEl0ZXJhdG9yICE9IG51bGw7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgTyBuZXh0KCkgewogICAgICAgICAgICBpZiAoY3VycmVudEl0ZXJhdG9yID09IEVNUFRZICYmICFoYXNOZXh0KCkpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGN1cnJlbnRJdGVyYXRvci5uZXh0KCk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgdm9pZCByZW1vdmUoKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSB2b2lkIHVwZGF0ZSgpIHsKICAgICAgICAgICAgd2hpbGUgKGlucHV0cy5oYXNOZXh0KCkpIHsKICAgICAgICAgICAgICAgIGN1cnJlbnRJdGVyYXRvciA9IGNvbnZlcnRvci5hcHBseShpbnB1dHMubmV4dCgpKTsKICAgICAgICAgICAgICAgIGlmIChjdXJyZW50SXRlcmF0b3IuaGFzTmV4dCgpKSByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY3VycmVudEl0ZXJhdG9yID0gbnVsbDsKICAgICAgICB9CiAgICB9CgogICAgQFN1cHByZXNzV2FybmluZ3MoInJhd3R5cGVzIikKICAgIHByaXZhdGUgZmluYWwgc3RhdGljIEl0ZXJhdG9yIEVNUFRZID0gbmV3IEl0ZXJhdG9yKCkgewogICAgICAgIHB1YmxpYyBib29sZWFuIGhhc05leHQoKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBPYmplY3QgbmV4dCgpIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgfTsKfQpQSwMECgAACAAA0n1NSumfN2XzBgAA8wYAADEAAABjb20vc3VuL3Rvb2xzL2phdmFjL3V0aWwvQ2xpZW50Q29kZUV4Y2VwdGlvbi5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDA1LCAyMDA2LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuamF2YWMudXRpbDsKCi8qKgogKiBBbiBleGNlcHRpb24gdXNlZCBmb3IgcHJvcG9nYXRpbmcgZXhjZXB0aW9ucyBmb3VuZCBpbiBjbGllbnQgY29kZQogKiBpbnZva2VkIGZyb20gamF2YWMuCiAqCiAqICA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiAgSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93biByaXNrLgogKiAgVGhpcyBjb2RlIGFuZCBpdHMgaW50ZXJuYWwgaW50ZXJmYWNlcyBhcmUgc3ViamVjdCB0byBjaGFuZ2Ugb3IKICogIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj4KICovCnB1YmxpYyBjbGFzcyBDbGllbnRDb2RlRXhjZXB0aW9uIGV4dGVuZHMgUnVudGltZUV4Y2VwdGlvbiB7CgogICAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IC01Njc0NDk0NDA5MzkyNDE1MTYzTDsKCiAgICBwdWJsaWMgQ2xpZW50Q29kZUV4Y2VwdGlvbihUaHJvd2FibGUgY2F1c2UpIHsKICAgICAgICBzdXBlcihjYXVzZSk7CiAgICB9Cn0KUEsDBAoAAAgAAAY7qUoI5s6IoEAAAKBAAAAiAAAAY29tL3N1bi90b29scy9qYXZhYy91dGlsL0xpc3QuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMTk5OSwgMjAxMywgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWw7CgppbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuQXJyYXk7CmltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OwppbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb247CmltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbnM7CmltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CmltcG9ydCBqYXZhLnV0aWwuQWJzdHJhY3RDb2xsZWN0aW9uOwppbXBvcnQgamF2YS51dGlsLkxpc3RJdGVyYXRvcjsKaW1wb3J0IGphdmEudXRpbC5Ob1N1Y2hFbGVtZW50RXhjZXB0aW9uOwppbXBvcnQgamF2YS51dGlsLmZ1bmN0aW9uLkZ1bmN0aW9uOwppbXBvcnQgamF2YS51dGlsLnN0cmVhbS5Db2xsZWN0b3I7CgovKiogQSBjbGFzcyBmb3IgZ2VuZXJpYyBsaW5rZWQgbGlzdHMuIExpbmtzIGFyZSBzdXBwb3NlZCB0byBiZQogKiAgaW1tdXRhYmxlLCB0aGUgb25seSBleGNlcHRpb24gYmVpbmcgdGhlIGluY3JlbWVudGFsIGNvbnN0cnVjdGlvbiBvZgogKiAgbGlzdHMgdmlhIExpc3RCdWZmZXJzLiAgTGlzdCBpcyB0aGUgbWFpbiBjb250YWluZXIgY2xhc3MgaW4KICogIEdKQy4gTW9zdCBkYXRhIHN0cnVjdHVyZXMgYW5kIGFsZ29yaXRobXMgaW4gR0pDIHVzZSBsaXN0cyByYXRoZXIKICogIHRoYW4gYXJyYXlzLgogKgogKiAgPHA+TGlzdHMgYXJlIGFsd2F5cyB0cmFpbGVkIGJ5IGEgc2VudGluZWwgZWxlbWVudCwgd2hvc2UgaGVhZCBhbmQgdGFpbAogKiAgYXJlIGJvdGggbnVsbC4KICoKICogIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqICBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqICBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogKiAgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPgogKi8KcHVibGljIGNsYXNzIExpc3Q8QT4gZXh0ZW5kcyBBYnN0cmFjdENvbGxlY3Rpb248QT4gaW1wbGVtZW50cyBqYXZhLnV0aWwuTGlzdDxBPiB7CgogICAgLyoqIFRoZSBmaXJzdCBlbGVtZW50IG9mIHRoZSBsaXN0LCBzdXBwb3NlZCB0byBiZSBpbW11dGFibGUuCiAgICAgKi8KICAgIHB1YmxpYyBBIGhlYWQ7CgogICAgLyoqIFRoZSByZW1haW5kZXIgb2YgdGhlIGxpc3QgZXhjZXB0IGZvciBpdHMgZmlyc3QgZWxlbWVudCwgc3VwcG9zZWQKICAgICAqICB0byBiZSBpbW11dGFibGUuCiAgICAgKi8KICAgIC8vQERlcHJlY2F0ZWQKICAgIHB1YmxpYyBMaXN0PEE+IHRhaWw7CgogICAgLyoqIENvbnN0cnVjdCBhIGxpc3QgZ2l2ZW4gaXRzIGhlYWQgYW5kIHRhaWwuCiAgICAgKi8KICAgIExpc3QoQSBoZWFkLCBMaXN0PEE+IHRhaWwpIHsKICAgICAgICB0aGlzLnRhaWwgPSB0YWlsOwogICAgICAgIHRoaXMuaGVhZCA9IGhlYWQ7CiAgICB9CgogICAgLyoqIENvbnN0cnVjdCBhbiBlbXB0eSBsaXN0LgogICAgICovCiAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKICAgIHB1YmxpYyBzdGF0aWMgPEE+IExpc3Q8QT4gbmlsKCkgewogICAgICAgIHJldHVybiAoTGlzdDxBPilFTVBUWV9MSVNUOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIExpc3Q8Pz4gRU1QVFlfTElTVCA9IG5ldyBMaXN0PE9iamVjdD4obnVsbCxudWxsKSB7CiAgICAgICAgcHVibGljIExpc3Q8T2JqZWN0PiBzZXRUYWlsKExpc3Q8T2JqZWN0PiB0YWlsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc0VtcHR5KCkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICB9OwoKICAgIC8qKiBSZXR1cm5zIHRoZSBsaXN0IG9idGFpbmVkIGZyb20gJ2wnIGFmdGVyIHJlbW92aW5nIGFsbCBlbGVtZW50cyAnZWxlbScKICAgICAqLwogICAgcHVibGljIHN0YXRpYyA8QT4gTGlzdDxBPiBmaWx0ZXIoTGlzdDxBPiBsLCBBIGVsZW0pIHsKICAgICAgICBBc3NlcnQuY2hlY2tOb25OdWxsKGVsZW0pOwogICAgICAgIExpc3Q8QT4gcmVzID0gTGlzdC5uaWwoKTsKICAgICAgICBmb3IgKEEgYSA6IGwpIHsKICAgICAgICAgICAgaWYgKGEgIT0gbnVsbCAmJiAhYS5lcXVhbHMoZWxlbSkpIHsKICAgICAgICAgICAgICAgIHJlcyA9IHJlcy5wcmVwZW5kKGEpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXMucmV2ZXJzZSgpOwogICAgfQoKICAgIHB1YmxpYyBMaXN0PEE+IGludGVyc2VjdChMaXN0PEE+IHRoYXQpIHsKICAgICAgICBMaXN0QnVmZmVyPEE+IGJ1ZiA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICBmb3IgKEEgZWwgOiB0aGlzKSB7CiAgICAgICAgICAgIGlmICh0aGF0LmNvbnRhaW5zKGVsKSkgewogICAgICAgICAgICAgICAgYnVmLmFwcGVuZChlbCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1Zi50b0xpc3QoKTsKICAgIH0KCiAgICBwdWJsaWMgTGlzdDxBPiBkaWZmKExpc3Q8QT4gdGhhdCkgewogICAgICAgIExpc3RCdWZmZXI8QT4gYnVmID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgIGZvciAoQSBlbCA6IHRoaXMpIHsKICAgICAgICAgICAgaWYgKCF0aGF0LmNvbnRhaW5zKGVsKSkgewogICAgICAgICAgICAgICAgYnVmLmFwcGVuZChlbCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1Zi50b0xpc3QoKTsKICAgIH0KCiAgICAvKioKICAgICAqIENyZWF0ZSBhIG5ldyBsaXN0IGZyb20gdGhlIGZpcnN0IHtAY29kZSBufSBlbGVtZW50cyBvZiB0aGlzIGxpc3QKICAgICAqLwogICAgcHVibGljIExpc3Q8QT4gdGFrZShpbnQgbikgewogICAgICAgIExpc3RCdWZmZXI8QT4gYnVmID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgIGludCBjb3VudCA9IDA7CiAgICAgICAgZm9yIChBIGVsIDogdGhpcykgewogICAgICAgICAgICBpZiAoY291bnQrKyA9PSBuKSBicmVhazsKICAgICAgICAgICAgYnVmLmFwcGVuZChlbCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWYudG9MaXN0KCk7CiAgICB9CgogICAgLyoqIENvbnN0cnVjdCBhIGxpc3QgY29uc2lzdGluZyBvZiBnaXZlbiBlbGVtZW50LgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIDxBPiBMaXN0PEE+IG9mKEEgeDEpIHsKICAgICAgICByZXR1cm4gbmV3IExpc3Q8Pih4MSwgTGlzdC5uaWwoKSk7CiAgICB9CgogICAgLyoqIENvbnN0cnVjdCBhIGxpc3QgY29uc2lzdGluZyBvZiBnaXZlbiBlbGVtZW50cy4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyA8QT4gTGlzdDxBPiBvZihBIHgxLCBBIHgyKSB7CiAgICAgICAgcmV0dXJuIG5ldyBMaXN0PD4oeDEsIG9mKHgyKSk7CiAgICB9CgogICAgLyoqIENvbnN0cnVjdCBhIGxpc3QgY29uc2lzdGluZyBvZiBnaXZlbiBlbGVtZW50cy4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyA8QT4gTGlzdDxBPiBvZihBIHgxLCBBIHgyLCBBIHgzKSB7CiAgICAgICAgcmV0dXJuIG5ldyBMaXN0PD4oeDEsIG9mKHgyLCB4MykpOwogICAgfQoKICAgIC8qKiBDb25zdHJ1Y3QgYSBsaXN0IGNvbnNpc3Rpbmcgb2YgZ2l2ZW4gZWxlbWVudHMuCiAgICAgKi8KICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidmFyYXJncyIsICJ1bmNoZWNrZWQifSkKICAgIHB1YmxpYyBzdGF0aWMgPEE+IExpc3Q8QT4gb2YoQSB4MSwgQSB4MiwgQSB4MywgQS4uLiByZXN0KSB7CiAgICAgICAgcmV0dXJuIG5ldyBMaXN0PD4oeDEsIG5ldyBMaXN0PD4oeDIsIG5ldyBMaXN0PD4oeDMsIGZyb20ocmVzdCkpKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDb25zdHJ1Y3QgYSBsaXN0IGNvbnNpc3RpbmcgYWxsIGVsZW1lbnRzIG9mIGdpdmVuIGFycmF5LgogICAgICogQHBhcmFtIGFycmF5IGFuIGFycmF5OyBpZiB7QGNvZGUgbnVsbH0gcmV0dXJuIGFuIGVtcHR5IGxpc3QKICAgICAqLwogICAgcHVibGljIHN0YXRpYyA8QT4gTGlzdDxBPiBmcm9tKEFbXSBhcnJheSkgewogICAgICAgIExpc3Q8QT4geHMgPSBuaWwoKTsKICAgICAgICBpZiAoYXJyYXkgIT0gbnVsbCkKICAgICAgICAgICAgZm9yIChpbnQgaSA9IGFycmF5Lmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKQogICAgICAgICAgICAgICAgeHMgPSBuZXcgTGlzdDw+KGFycmF5W2ldLCB4cyk7CiAgICAgICAgcmV0dXJuIHhzOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgPEE+IExpc3Q8QT4gZnJvbShJdGVyYWJsZTw/IGV4dGVuZHMgQT4gY29sbCkgewogICAgICAgIExpc3RCdWZmZXI8QT4geHMgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgZm9yIChBIGEgOiBjb2xsKSB7CiAgICAgICAgICAgIHhzLmFwcGVuZChhKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHhzLnRvTGlzdCgpOwogICAgfQoKICAgIC8qKiBDb25zdHJ1Y3QgYSBsaXN0IGNvbnNpc3Rpbmcgb2YgYSBnaXZlbiBudW1iZXIgb2YgaWRlbnRpY2FsIGVsZW1lbnRzLgogICAgICogIEBwYXJhbSBsZW4gICAgVGhlIG51bWJlciBvZiBlbGVtZW50cyBpbiB0aGUgbGlzdC4KICAgICAqICBAcGFyYW0gaW5pdCAgIFRoZSB2YWx1ZSBvZiBlYWNoIGVsZW1lbnQuCiAgICAgKi8KICAgIEBEZXByZWNhdGVkCiAgICBwdWJsaWMgc3RhdGljIDxBPiBMaXN0PEE+IGZpbGwoaW50IGxlbiwgQSBpbml0KSB7CiAgICAgICAgTGlzdDxBPiBsID0gbmlsKCk7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW47IGkrKykgbCA9IG5ldyBMaXN0PD4oaW5pdCwgbCk7CiAgICAgICAgcmV0dXJuIGw7CiAgICB9CgogICAgLyoqIERvZXMgbGlzdCBoYXZlIG5vIGVsZW1lbnRzPwogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGlzRW1wdHkoKSB7CiAgICAgICAgcmV0dXJuIHRhaWwgPT0gbnVsbDsKICAgIH0KCiAgICAvKiogRG9lcyBsaXN0IGhhdmUgZWxlbWVudHM/CiAgICAgKi8KICAgIC8vQERlcHJlY2F0ZWQKICAgIHB1YmxpYyBib29sZWFuIG5vbkVtcHR5KCkgewogICAgICAgIHJldHVybiB0YWlsICE9IG51bGw7CiAgICB9CgogICAgLyoqIFJldHVybiB0aGUgbnVtYmVyIG9mIGVsZW1lbnRzIGluIHRoaXMgbGlzdC4KICAgICAqLwogICAgLy9ARGVwcmVjYXRlZAogICAgcHVibGljIGludCBsZW5ndGgoKSB7CiAgICAgICAgTGlzdDxBPiBsID0gdGhpczsKICAgICAgICBpbnQgbGVuID0gMDsKICAgICAgICB3aGlsZSAobC50YWlsICE9IG51bGwpIHsKICAgICAgICAgICAgbCA9IGwudGFpbDsKICAgICAgICAgICAgbGVuKys7CiAgICAgICAgfQogICAgICAgIHJldHVybiBsZW47CiAgICB9CiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgc2l6ZSgpIHsKICAgICAgICByZXR1cm4gbGVuZ3RoKCk7CiAgICB9CgogICAgcHVibGljIExpc3Q8QT4gc2V0VGFpbChMaXN0PEE+IHRhaWwpIHsKICAgICAgICB0aGlzLnRhaWwgPSB0YWlsOwogICAgICAgIHJldHVybiB0YWlsOwogICAgfQoKICAgIC8qKiBQcmVwZW5kIGdpdmVuIGVsZW1lbnQgdG8gZnJvbnQgb2YgbGlzdCwgZm9ybWluZyBhbmQgcmV0dXJuaW5nCiAgICAgKiAgYSBuZXcgbGlzdC4KICAgICAqLwogICAgcHVibGljIExpc3Q8QT4gcHJlcGVuZChBIHgpIHsKICAgICAgICByZXR1cm4gbmV3IExpc3Q8Pih4LCB0aGlzKTsKICAgIH0KCiAgICAvKiogUHJlcGVuZCBnaXZlbiBsaXN0IG9mIGVsZW1lbnRzIHRvIGZyb250IG9mIGxpc3QsIGZvcm1pbmcgYW5kIHJldHVybmluZwogICAgICogIGEgbmV3IGxpc3QuCiAgICAgKi8KICAgIHB1YmxpYyBMaXN0PEE+IHByZXBlbmRMaXN0KExpc3Q8QT4geHMpIHsKICAgICAgICBpZiAodGhpcy5pc0VtcHR5KCkpIHJldHVybiB4czsKICAgICAgICBpZiAoeHMuaXNFbXB0eSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpZiAoeHMudGFpbC5pc0VtcHR5KCkpIHJldHVybiBwcmVwZW5kKHhzLmhlYWQpOwogICAgICAgIC8vIHJldHVybiB0aGlzLnByZXBlbmRMaXN0KHhzLnRhaWwpLnByZXBlbmQoeHMuaGVhZCk7CiAgICAgICAgTGlzdDxBPiByZXN1bHQgPSB0aGlzOwogICAgICAgIExpc3Q8QT4gcmV2ID0geHMucmV2ZXJzZSgpOwogICAgICAgIEFzc2VydC5jaGVjayhyZXYgIT0geHMpOwogICAgICAgIC8vIHNpbmNlIHhzLnJldmVyc2UoKSByZXR1cm5lZCBhIG5ldyBsaXN0LCB3ZSBjYW4gcmV1c2UgdGhlCiAgICAgICAgLy8gaW5kaXZpZHVhbCBMaXN0IG9iamVjdHMsIGluc3RlYWQgb2YgYWxsb2NhdGluZyBuZXcgb25lcy4KICAgICAgICB3aGlsZSAocmV2Lm5vbkVtcHR5KCkpIHsKICAgICAgICAgICAgTGlzdDxBPiBoID0gcmV2OwogICAgICAgICAgICByZXYgPSByZXYudGFpbDsKICAgICAgICAgICAgaC5zZXRUYWlsKHJlc3VsdCk7CiAgICAgICAgICAgIHJlc3VsdCA9IGg7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9CgogICAgLyoqIFJldmVyc2UgbGlzdC4KICAgICAqIElmIHRoZSBsaXN0IGlzIGVtcHR5IG9yIGEgc2luZ2xldG9uLCB0aGVuIHRoZSBzYW1lIGxpc3QgaXMgcmV0dXJuZWQuCiAgICAgKiBPdGhlcndpc2UgYSBuZXcgbGlzdCBpcyBmb3JtZWQuCiAgICAgKi8KICAgIHB1YmxpYyBMaXN0PEE+IHJldmVyc2UoKSB7CiAgICAgICAgLy8gaWYgaXQgaXMgZW1wdHkgb3IgYSBzaW5nbGV0b24sIHJldHVybiBpdHNlbGYKICAgICAgICBpZiAoaXNFbXB0eSgpIHx8IHRhaWwuaXNFbXB0eSgpKQogICAgICAgICAgICByZXR1cm4gdGhpczsKCiAgICAgICAgTGlzdDxBPiByZXYgPSBuaWwoKTsKICAgICAgICBmb3IgKExpc3Q8QT4gbCA9IHRoaXM7IGwubm9uRW1wdHkoKTsgbCA9IGwudGFpbCkKICAgICAgICAgICAgcmV2ID0gbmV3IExpc3Q8PihsLmhlYWQsIHJldik7CiAgICAgICAgcmV0dXJuIHJldjsKICAgIH0KCiAgICAvKiogQXBwZW5kIGdpdmVuIGVsZW1lbnQgYXQgbGVuZ3RoLCBmb3JtaW5nIGFuZCByZXR1cm5pbmcKICAgICAqICBhIG5ldyBsaXN0LgogICAgICovCiAgICBwdWJsaWMgTGlzdDxBPiBhcHBlbmQoQSB4KSB7CiAgICAgICAgcmV0dXJuIG9mKHgpLnByZXBlbmRMaXN0KHRoaXMpOwogICAgfQoKICAgIC8qKiBBcHBlbmQgZ2l2ZW4gbGlzdCBhdCBsZW5ndGgsIGZvcm1pbmcgYW5kIHJldHVybmluZwogICAgICogIGEgbmV3IGxpc3QuCiAgICAgKi8KICAgIHB1YmxpYyBMaXN0PEE+IGFwcGVuZExpc3QoTGlzdDxBPiB4KSB7CiAgICAgICAgcmV0dXJuIHgucHJlcGVuZExpc3QodGhpcyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBBcHBlbmQgZ2l2ZW4gbGlzdCBidWZmZXIgYXQgbGVuZ3RoLCBmb3JtaW5nIGFuZCByZXR1cm5pbmcgYSBuZXcKICAgICAqIGxpc3QuCiAgICAgKi8KICAgIHB1YmxpYyBMaXN0PEE+IGFwcGVuZExpc3QoTGlzdEJ1ZmZlcjxBPiB4KSB7CiAgICAgICAgcmV0dXJuIGFwcGVuZExpc3QoeC50b0xpc3QoKSk7CiAgICB9CgogICAgLyoqIENvcHkgc3VjY2Vzc2l2ZSBlbGVtZW50cyBvZiB0aGlzIGxpc3QgaW50byBnaXZlbiB2ZWN0b3IgdW50aWwKICAgICAqICBsaXN0IGlzIGV4aGF1c3RlZCBvciBlbmQgb2YgdmVjdG9yIGlzIHJlYWNoZWQuCiAgICAgKi8KICAgIEBPdmVycmlkZSBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKICAgIHB1YmxpYyA8VD4gVFtdIHRvQXJyYXkoVFtdIHZlYykgewogICAgICAgIGludCBpID0gMDsKICAgICAgICBMaXN0PEE+IGwgPSB0aGlzOwogICAgICAgIE9iamVjdFtdIGRlc3QgPSB2ZWM7CiAgICAgICAgd2hpbGUgKGwubm9uRW1wdHkoKSAmJiBpIDwgdmVjLmxlbmd0aCkgewogICAgICAgICAgICBkZXN0W2ldID0gbC5oZWFkOwogICAgICAgICAgICBsID0gbC50YWlsOwogICAgICAgICAgICBpKys7CiAgICAgICAgfQogICAgICAgIGlmIChsLmlzRW1wdHkoKSkgewogICAgICAgICAgICBpZiAoaSA8IHZlYy5sZW5ndGgpCiAgICAgICAgICAgICAgICB2ZWNbaV0gPSBudWxsOwogICAgICAgICAgICByZXR1cm4gdmVjOwogICAgICAgIH0KCiAgICAgICAgdmVjID0gKFRbXSlBcnJheS5uZXdJbnN0YW5jZSh2ZWMuZ2V0Q2xhc3MoKS5nZXRDb21wb25lbnRUeXBlKCksIHNpemUoKSk7CiAgICAgICAgcmV0dXJuIHRvQXJyYXkodmVjKTsKICAgIH0KCiAgICBwdWJsaWMgT2JqZWN0W10gdG9BcnJheSgpIHsKICAgICAgICByZXR1cm4gdG9BcnJheShuZXcgT2JqZWN0W3NpemUoKV0pOwogICAgfQoKICAgIC8qKiBGb3JtIGEgc3RyaW5nIGxpc3RpbmcgYWxsIGVsZW1lbnRzIHdpdGggZ2l2ZW4gc2VwYXJhdG9yIGNoYXJhY3Rlci4KICAgICAqLwogICAgcHVibGljIFN0cmluZyB0b1N0cmluZyhTdHJpbmcgc2VwKSB7CiAgICAgICAgaWYgKGlzRW1wdHkoKSkgewogICAgICAgICAgICByZXR1cm4gIiI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgU3RyaW5nQnVpbGRlciBidWYgPSBuZXcgU3RyaW5nQnVpbGRlcigpOwogICAgICAgICAgICBidWYuYXBwZW5kKGhlYWQpOwogICAgICAgICAgICBmb3IgKExpc3Q8QT4gbCA9IHRhaWw7IGwubm9uRW1wdHkoKTsgbCA9IGwudGFpbCkgewogICAgICAgICAgICAgICAgYnVmLmFwcGVuZChzZXApOwogICAgICAgICAgICAgICAgYnVmLmFwcGVuZChsLmhlYWQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBidWYudG9TdHJpbmcoKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqIEZvcm0gYSBzdHJpbmcgbGlzdGluZyBhbGwgZWxlbWVudHMgd2l0aCBjb21tYSBhcyB0aGUgc2VwYXJhdG9yIGNoYXJhY3Rlci4KICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewogICAgICAgIHJldHVybiB0b1N0cmluZygiLCIpOwogICAgfQoKICAgIC8qKiBDb21wdXRlIGEgaGFzaCBjb2RlLCBvdmVycmlkZXMgT2JqZWN0CiAgICAgKiAgQHNlZSBqYXZhLnV0aWwuTGlzdCNoYXNoQ29kZQogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgICAgTGlzdDxBPiBsID0gdGhpczsKICAgICAgICBpbnQgaCA9IDE7CiAgICAgICAgd2hpbGUgKGwudGFpbCAhPSBudWxsKSB7CiAgICAgICAgICAgIGggPSBoICogMzEgKyAobC5oZWFkID09IG51bGwgPyAwIDogbC5oZWFkLmhhc2hDb2RlKCkpOwogICAgICAgICAgICBsID0gbC50YWlsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gaDsKICAgIH0KCiAgICAvKiogSXMgdGhpcyBsaXN0IHRoZSBzYW1lIGFzIG90aGVyIGxpc3Q/CiAgICAgKiAgQHNlZSBqYXZhLnV0aWwuTGlzdCNlcXVhbHMKICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgTGlzdDw/PikKICAgICAgICAgICAgcmV0dXJuIGVxdWFscyh0aGlzLCAoTGlzdDw/PilvdGhlcik7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgamF2YS51dGlsLkxpc3Q8Pz4pIHsKICAgICAgICAgICAgTGlzdDxBPiB0ID0gdGhpczsKICAgICAgICAgICAgSXRlcmF0b3I8Pz4gb0l0ZXIgPSAoKGphdmEudXRpbC5MaXN0PD8+KSBvdGhlcikuaXRlcmF0b3IoKTsKICAgICAgICAgICAgd2hpbGUgKHQudGFpbCAhPSBudWxsICYmIG9JdGVyLmhhc05leHQoKSkgewogICAgICAgICAgICAgICAgT2JqZWN0IG8gPSBvSXRlci5uZXh0KCk7CiAgICAgICAgICAgICAgICBpZiAoICEodC5oZWFkID09IG51bGwgPyBvID09IG51bGwgOiB0LmhlYWQuZXF1YWxzKG8pKSkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB0ID0gdC50YWlsOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiAodC5pc0VtcHR5KCkgJiYgIW9JdGVyLmhhc05leHQoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICAvKiogQXJlIHRoZSB0d28gbGlzdHMgdGhlIHNhbWU/CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBlcXVhbHMoTGlzdDw/PiB4cywgTGlzdDw/PiB5cykgewogICAgICAgIHdoaWxlICh4cy50YWlsICE9IG51bGwgJiYgeXMudGFpbCAhPSBudWxsKSB7CiAgICAgICAgICAgIGlmICh4cy5oZWFkID09IG51bGwpIHsKICAgICAgICAgICAgICAgIGlmICh5cy5oZWFkICE9IG51bGwpIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGlmICgheHMuaGVhZC5lcXVhbHMoeXMuaGVhZCkpIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgICAgICB4cyA9IHhzLnRhaWw7CiAgICAgICAgICAgIHlzID0geXMudGFpbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHhzLnRhaWwgPT0gbnVsbCAmJiB5cy50YWlsID09IG51bGw7CiAgICB9CgogICAgLyoqIERvZXMgdGhlIGxpc3QgY29udGFpbiB0aGUgc3BlY2lmaWVkIGVsZW1lbnQ/CiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnMoT2JqZWN0IHgpIHsKICAgICAgICBMaXN0PEE+IGwgPSB0aGlzOwogICAgICAgIHdoaWxlIChsLnRhaWwgIT0gbnVsbCkgewogICAgICAgICAgICBpZiAoeCA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICBpZiAobC5oZWFkID09IG51bGwpIHJldHVybiB0cnVlOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgaWYgKGwuaGVhZC5lcXVhbHMoeCkpIHJldHVybiB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGwgPSBsLnRhaWw7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICAvKiogVGhlIGxhc3QgZWxlbWVudCBpbiB0aGUgbGlzdCwgaWYgYW55LCBvciBudWxsLgogICAgICovCiAgICBwdWJsaWMgQSBsYXN0KCkgewogICAgICAgIEEgbGFzdCA9IG51bGw7CiAgICAgICAgTGlzdDxBPiB0ID0gdGhpczsKICAgICAgICB3aGlsZSAodC50YWlsICE9IG51bGwpIHsKICAgICAgICAgICAgbGFzdCA9IHQuaGVhZDsKICAgICAgICAgICAgdCA9IHQudGFpbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGxhc3Q7CiAgICB9CgogICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCiAgICBwdWJsaWMgPFo+IExpc3Q8Wj4gbWFwKEZ1bmN0aW9uPEEsIFo+IG1hcHBlcikgewogICAgICAgIGJvb2xlYW4gY2hhbmdlZCA9IGZhbHNlOwogICAgICAgIExpc3RCdWZmZXI8Wj4gYnVmID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgIGZvciAoQSBhIDogdGhpcykgewogICAgICAgICAgICBaIHogPSBtYXBwZXIuYXBwbHkoYSk7CiAgICAgICAgICAgIGJ1Zi5hcHBlbmQoeik7CiAgICAgICAgICAgIGNoYW5nZWQgfD0gKHogIT0gYSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBjaGFuZ2VkID8gYnVmLnRvTGlzdCgpIDogKExpc3Q8Wj4pdGhpczsKICAgIH0KCiAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKICAgIHB1YmxpYyBzdGF0aWMgPFQ+IExpc3Q8VD4gY29udmVydChDbGFzczxUPiBrbGFzcywgTGlzdDw/PiBsaXN0KSB7CiAgICAgICAgaWYgKGxpc3QgPT0gbnVsbCkKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgZm9yIChPYmplY3QgbyA6IGxpc3QpCiAgICAgICAgICAgIGtsYXNzLmNhc3Qobyk7CiAgICAgICAgcmV0dXJuIChMaXN0PFQ+KWxpc3Q7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgSXRlcmF0b3I8Pz4gRU1QVFlJVEVSQVRPUiA9IG5ldyBJdGVyYXRvcjxPYmplY3Q+KCkgewogICAgICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNOZXh0KCkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHB1YmxpYyBPYmplY3QgbmV4dCgpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBqYXZhLnV0aWwuTm9TdWNoRWxlbWVudEV4Y2VwdGlvbigpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHB1YmxpYyB2b2lkIHJlbW92ZSgpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOwogICAgICAgICAgICB9CiAgICAgICAgfTsKCiAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKICAgIHByaXZhdGUgc3RhdGljIDxBPiBJdGVyYXRvcjxBPiBlbXB0eUl0ZXJhdG9yKCkgewogICAgICAgIHJldHVybiAoSXRlcmF0b3I8QT4pRU1QVFlJVEVSQVRPUjsKICAgIH0KCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBJdGVyYXRvcjxBPiBpdGVyYXRvcigpIHsKICAgICAgICBpZiAodGFpbCA9PSBudWxsKQogICAgICAgICAgICByZXR1cm4gZW1wdHlJdGVyYXRvcigpOwogICAgICAgIHJldHVybiBuZXcgSXRlcmF0b3I8QT4oKSB7CiAgICAgICAgICAgIExpc3Q8QT4gZWxlbXMgPSBMaXN0LnRoaXM7CiAgICAgICAgICAgIHB1YmxpYyBib29sZWFuIGhhc05leHQoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZWxlbXMudGFpbCAhPSBudWxsOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHB1YmxpYyBBIG5leHQoKSB7CiAgICAgICAgICAgICAgICBpZiAoZWxlbXMudGFpbCA9PSBudWxsKQogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgICAgICAgICBBIHJlc3VsdCA9IGVsZW1zLmhlYWQ7CiAgICAgICAgICAgICAgICBlbGVtcyA9IGVsZW1zLnRhaWw7CiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgICAgICB9CiAgICAgICAgICAgIHB1YmxpYyB2b2lkIHJlbW92ZSgpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOwogICAgICAgICAgICB9CiAgICAgICAgfTsKICAgIH0KCiAgICBwdWJsaWMgQSBnZXQoaW50IGluZGV4KSB7CiAgICAgICAgaWYgKGluZGV4IDwgMCkKICAgICAgICAgICAgdGhyb3cgbmV3IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oU3RyaW5nLnZhbHVlT2YoaW5kZXgpKTsKCiAgICAgICAgTGlzdDxBPiBsID0gdGhpczsKICAgICAgICBmb3IgKGludCBpID0gaW5kZXg7IGktLSA+IDAgJiYgIWwuaXNFbXB0eSgpOyBsID0gbC50YWlsKQogICAgICAgICAgICA7CgogICAgICAgIGlmIChsLmlzRW1wdHkoKSkKICAgICAgICAgICAgdGhyb3cgbmV3IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oIkluZGV4OiAiICsgaW5kZXggKyAiLCAiICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNpemU6ICIgKyBzaXplKCkpOwogICAgICAgIHJldHVybiBsLmhlYWQ7CiAgICB9CgogICAgcHVibGljIGJvb2xlYW4gYWRkQWxsKGludCBpbmRleCwgQ29sbGVjdGlvbjw/IGV4dGVuZHMgQT4gYykgewogICAgICAgIGlmIChjLmlzRW1wdHkoKSkKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOwogICAgfQoKICAgIHB1YmxpYyBBIHNldChpbnQgaW5kZXgsIEEgZWxlbWVudCkgewogICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIGFkZChpbnQgaW5kZXgsIEEgZWxlbWVudCkgewogICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOwogICAgfQoKICAgIHB1YmxpYyBBIHJlbW92ZShpbnQgaW5kZXgpIHsKICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKICAgIH0KCiAgICBwdWJsaWMgaW50IGluZGV4T2YoT2JqZWN0IG8pIHsKICAgICAgICBpbnQgaSA9IDA7CiAgICAgICAgZm9yIChMaXN0PEE+IGwgPSB0aGlzOyBsLnRhaWwgIT0gbnVsbDsgbCA9IGwudGFpbCwgaSsrKSB7CiAgICAgICAgICAgIGlmIChsLmhlYWQgPT0gbnVsbCA/IG8gPT0gbnVsbCA6IGwuaGVhZC5lcXVhbHMobykpCiAgICAgICAgICAgICAgICByZXR1cm4gaTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIC0xOwogICAgfQoKICAgIHB1YmxpYyBpbnQgbGFzdEluZGV4T2YoT2JqZWN0IG8pIHsKICAgICAgICBpbnQgbGFzdCA9IC0xOwogICAgICAgIGludCBpID0gMDsKICAgICAgICBmb3IgKExpc3Q8QT4gbCA9IHRoaXM7IGwudGFpbCAhPSBudWxsOyBsID0gbC50YWlsLCBpKyspIHsKICAgICAgICAgICAgaWYgKGwuaGVhZCA9PSBudWxsID8gbyA9PSBudWxsIDogbC5oZWFkLmVxdWFscyhvKSkKICAgICAgICAgICAgICAgIGxhc3QgPSBpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbGFzdDsKICAgIH0KCiAgICBwdWJsaWMgTGlzdEl0ZXJhdG9yPEE+IGxpc3RJdGVyYXRvcigpIHsKICAgICAgICByZXR1cm4gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChuZXcgQXJyYXlMaXN0PEE+KHRoaXMpKS5saXN0SXRlcmF0b3IoKTsKICAgIH0KCiAgICBwdWJsaWMgTGlzdEl0ZXJhdG9yPEE+IGxpc3RJdGVyYXRvcihpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChuZXcgQXJyYXlMaXN0PEE+KHRoaXMpKS5saXN0SXRlcmF0b3IoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxBPiBzdWJMaXN0KGludCBmcm9tSW5kZXgsIGludCB0b0luZGV4KSB7CiAgICAgICAgaWYgIChmcm9tSW5kZXggPCAwIHx8IHRvSW5kZXggPiBzaXplKCkgfHwgZnJvbUluZGV4ID4gdG9JbmRleCkKICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwoKICAgICAgICBBcnJheUxpc3Q8QT4gYSA9IG5ldyBBcnJheUxpc3Q8Pih0b0luZGV4IC0gZnJvbUluZGV4KTsKICAgICAgICBpbnQgaSA9IDA7CiAgICAgICAgZm9yIChMaXN0PEE+IGwgPSB0aGlzOyBsLnRhaWwgIT0gbnVsbDsgbCA9IGwudGFpbCwgaSsrKSB7CiAgICAgICAgICAgIGlmIChpID09IHRvSW5kZXgpCiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgaWYgKGkgPj0gZnJvbUluZGV4KQogICAgICAgICAgICAgICAgYS5hZGQobC5oZWFkKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KGEpOwogICAgfQoKICAgIC8qKgogICAgICogQ29sbGVjdCBlbGVtZW50cyBpbnRvIGEgbmV3IGxpc3QgKHVzaW5nIGEgQGNvZGV7TGlzdEJ1ZmZlcn0pCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgPFo+IENvbGxlY3RvcjxaLCBMaXN0QnVmZmVyPFo+LCBMaXN0PFo+PiBjb2xsZWN0b3IoKSB7CiAgICAgICAgcmV0dXJuIENvbGxlY3Rvci5vZihMaXN0QnVmZmVyOjpuZXcsCiAgICAgICAgICAgICAgICBMaXN0QnVmZmVyOjphZGQsCiAgICAgICAgICAgICAgICAoYnVmMSwgYnVmMiktPiB7IGJ1ZjEuYWRkQWxsKGJ1ZjIpOyByZXR1cm4gYnVmMTsgfSwKICAgICAgICAgICAgICAgIExpc3RCdWZmZXI6OnRvTGlzdCk7CiAgICB9Cn0KUEsDBAoAAAgAAAY7qUrq09Ui2Q0AANkNAAArAAAAY29tL3N1bi90b29scy9qYXZhYy91dGlsL01hdGNoaW5nVXRpbHMuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAxNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWw7CgppbXBvcnQgamF2YS51dGlsLnJlZ2V4LlBhdHRlcm47CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLlNvdXJjZVZlcnNpb247CgovKipVdGlsaXRpZXMgdG8gY29udmVydCBhbiBpbXBvcnQtbGlrZSBzdHJpbmcgdG8gYSByZWdleHAuCiAqCiAqICA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiAgSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93biByaXNrLgogKiAgVGhpcyBjb2RlIGFuZCBpdHMgaW50ZXJuYWwgaW50ZXJmYWNlcyBhcmUgc3ViamVjdCB0byBjaGFuZ2Ugb3IKICogIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj4KICovCnB1YmxpYyBjbGFzcyBNYXRjaGluZ1V0aWxzIHsKCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgYWxsTWF0Y2hlc1N0cmluZyA9ICIuKiI7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBQYXR0ZXJuIGFsbE1hdGNoZXMgPSBQYXR0ZXJuLmNvbXBpbGUoYWxsTWF0Y2hlc1N0cmluZyk7CgogICAgLyoqCiAgICAgKiBSZXR1cm4gdHJ1ZSBpZiB0aGUgYXJndW1lbnQgc3RyaW5nIGlzIGEgdmFsaWQgaW1wb3J0LXN0eWxlCiAgICAgKiBzdHJpbmcgc3BlY2lmeWluZyBjbGFpbWVkIGFubm90YXRpb25zOyByZXR1cm4gZmFsc2Ugb3RoZXJ3aXNlLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNWYWxpZEltcG9ydFN0cmluZyhTdHJpbmcgcykgewogICAgICAgIGlmIChzLmVxdWFscygiKiIpKQogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKCiAgICAgICAgYm9vbGVhbiB2YWxpZCA9IHRydWU7CiAgICAgICAgU3RyaW5nIHQgPSBzOwogICAgICAgIGludCBpbmRleCA9IHQuaW5kZXhPZignKicpOwoKICAgICAgICBpZiAoaW5kZXggIT0gLTEpIHsKICAgICAgICAgICAgLy8gJyonIG11c3QgYmUgbGFzdCBjaGFyYWN0ZXIuLi4KICAgICAgICAgICAgaWYgKGluZGV4ID09IHQubGVuZ3RoKCkgLTEpIHsKICAgICAgICAgICAgICAgIC8vIC4uLiBhbnkgYW5kIHByZWNlZGluZyBjaGFyYWN0ZXIgbXVzdCBiZSAnLicKICAgICAgICAgICAgICAgIGlmICggaW5kZXgtMSA+PSAwICkgewogICAgICAgICAgICAgICAgICAgIHZhbGlkID0gdC5jaGFyQXQoaW5kZXgtMSkgPT0gJy4nOwogICAgICAgICAgICAgICAgICAgIC8vIFN0cmlwIG9mZiAiLiokIiBmb3IgaWRlbnRpZmllciBjaGVja3MKICAgICAgICAgICAgICAgICAgICB0ID0gdC5zdWJzdHJpbmcoMCwgdC5sZW5ndGgoKS0yKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlCiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICAvLyBWZXJpZnkgc3RyaW5nIGlzIG9mZiB0aGUgZm9ybSAoamF2YUlkIFwuKSsgb3IgamF2YUlkCiAgICAgICAgaWYgKHZhbGlkKSB7CiAgICAgICAgICAgIFN0cmluZ1tdIGphdmFJZHMgPSB0LnNwbGl0KCJcXC4iLCB0Lmxlbmd0aCgpKzIpOwogICAgICAgICAgICBmb3IoU3RyaW5nIGphdmFJZDogamF2YUlkcykKICAgICAgICAgICAgICAgIHZhbGlkICY9IFNvdXJjZVZlcnNpb24uaXNJZGVudGlmaWVyKGphdmFJZCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB2YWxpZDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIFN0cmluZyB2YWxpZEltcG9ydFN0cmluZ1RvUGF0dGVyblN0cmluZyhTdHJpbmcgcykgewogICAgICAgIGlmIChzLmVxdWFscygiKiIpKSB7CiAgICAgICAgICAgIHJldHVybiBhbGxNYXRjaGVzU3RyaW5nOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIFN0cmluZyBzX3ByaW1lID0gcy5yZXBsYWNlKCIuIiwgIlxcLiIpOwoKICAgICAgICAgICAgaWYgKHNfcHJpbWUuZW5kc1dpdGgoIioiKSkgewogICAgICAgICAgICAgICAgc19wcmltZSA9ICBzX3ByaW1lLnN1YnN0cmluZygwLCBzX3ByaW1lLmxlbmd0aCgpIC0gMSkgKyAiLisiOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gc19wcmltZTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBQYXR0ZXJuIHZhbGlkSW1wb3J0U3RyaW5nVG9QYXR0ZXJuKFN0cmluZyBzKSB7CiAgICAgICAgU3RyaW5nIHBhdHRlcm4gPSB2YWxpZEltcG9ydFN0cmluZ1RvUGF0dGVyblN0cmluZyhzKTsKCiAgICAgICAgaWYgKHBhdHRlcm4gPT0gYWxsTWF0Y2hlc1N0cmluZykgewogICAgICAgICAgICByZXR1cm4gYWxsTWF0Y2hlczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gUGF0dGVybi5jb21waWxlKHBhdHRlcm4pOwogICAgICAgIH0KICAgIH0KCn0KUEsDBAoAAAgAANJ9TUpsgtJYJwsAACcLAAAkAAAAY29tL3N1bi90b29scy9qYXZhYy91dGlsL1dhcm5lci5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDAzLCAyMDEwLCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuamF2YWMudXRpbDsKCmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuTGludC5MaW50Q2F0ZWdvcnk7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuSkNEaWFnbm9zdGljLkRpYWdub3N0aWNQb3NpdGlvbjsKaW1wb3J0IGphdmEudXRpbC5FbnVtU2V0OwoKLyoqCiAqIEFuIGludGVyZmFjZSB0byBzdXBwb3J0IG9wdGlvbmFsIHdhcm5pbmdzLCBuZWVkZWQgZm9yIHN1cHBvcnQgb2YKICogdW5jaGVja2VkIGNvbnZlcnNpb25zIGFuZCB1bmNoZWNrZWQgY2FzdHMuCiAqCiAqIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24gcmlzay4KICogVGhpcyBjb2RlIGFuZCBpdHMgaW50ZXJuYWwgaW50ZXJmYWNlcyBhcmUgc3ViamVjdCB0byBjaGFuZ2Ugb3IKICogZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPgogKi8KcHVibGljIGNsYXNzIFdhcm5lciB7CgogICAgcHJpdmF0ZSBEaWFnbm9zdGljUG9zaXRpb24gcG9zID0gbnVsbDsKICAgIHByb3RlY3RlZCBib29sZWFuIHdhcm5lZCA9IGZhbHNlOwogICAgcHJpdmF0ZSBFbnVtU2V0PExpbnRDYXRlZ29yeT4gbm9uU2lsZW50TGludFNldCA9IEVudW1TZXQubm9uZU9mKExpbnRDYXRlZ29yeS5jbGFzcyk7CiAgICBwcml2YXRlIEVudW1TZXQ8TGludENhdGVnb3J5PiBzaWxlbnRMaW50U2V0ID0gRW51bVNldC5ub25lT2YoTGludENhdGVnb3J5LmNsYXNzKTsKCiAgICBwdWJsaWMgRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcygpIHsKICAgICAgICByZXR1cm4gcG9zOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHdhcm4oTGludENhdGVnb3J5IGxpbnQpIHsKICAgICAgICBub25TaWxlbnRMaW50U2V0LmFkZChsaW50KTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCBzaWxlbnRXYXJuKExpbnRDYXRlZ29yeSBsaW50KSB7CiAgICAgICAgc2lsZW50TGludFNldC5hZGQobGludCk7CiAgICB9CgogICAgcHVibGljIFdhcm5lcihEaWFnbm9zdGljUG9zaXRpb24gcG9zKSB7CiAgICAgICAgdGhpcy5wb3MgPSBwb3M7CiAgICB9CgogICAgcHVibGljIGJvb2xlYW4gaGFzU2lsZW50TGludChMaW50Q2F0ZWdvcnkgbGludCkgewogICAgICAgIHJldHVybiBzaWxlbnRMaW50U2V0LmNvbnRhaW5zKGxpbnQpOwogICAgfQoKICAgIHB1YmxpYyBib29sZWFuIGhhc05vblNpbGVudExpbnQoTGludENhdGVnb3J5IGxpbnQpIHsKICAgICAgICByZXR1cm4gbm9uU2lsZW50TGludFNldC5jb250YWlucyhsaW50KTsKICAgIH0KCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMaW50KExpbnRDYXRlZ29yeSBsaW50KSB7CiAgICAgICAgcmV0dXJuIGhhc1NpbGVudExpbnQobGludCkgfHwKICAgICAgICAgICAgICAgIGhhc05vblNpbGVudExpbnQobGludCk7CiAgICB9CgogICAgcHVibGljIHZvaWQgY2xlYXIoKSB7CiAgICAgICAgbm9uU2lsZW50TGludFNldC5jbGVhcigpOwogICAgICAgIHNpbGVudExpbnRTZXQuY2xlYXIoKTsKICAgICAgICB0aGlzLndhcm5lZCA9IGZhbHNlOwogICAgfQoKICAgIHB1YmxpYyBXYXJuZXIoKSB7CiAgICAgICAgdGhpcyhudWxsKTsKICAgIH0KfQpQSwMECgAACAAABjupSq4nU1VTIwAAUyMAACgAAABjb20vc3VuL3Rvb2xzL2phdmFjL3V0aWwvR3JhcGhVdGlscy5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAxOTk5LCAyMDEzLCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuamF2YWMudXRpbDsKCmltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OwppbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb247CmltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKCi8qKiA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiAgSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93biByaXNrLgogKiAgVGhpcyBjb2RlIGFuZCBpdHMgaW50ZXJuYWwgaW50ZXJmYWNlcyBhcmUgc3ViamVjdCB0byBjaGFuZ2Ugb3IKICogIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj4KICovCnB1YmxpYyBjbGFzcyBHcmFwaFV0aWxzIHsKCiAgICAvKioKICAgICAqIEJhc2ljIGludGVyZmFjZSBmb3IgZGVmaW5pbmcgdmFyaW91cyBkZXBlbmRlbmN5IGtpbmRzLgogICAgICovCiAgICBwdWJsaWMgaW50ZXJmYWNlIERlcGVuZGVuY3lLaW5kIHsgfQoKICAgIC8qKgogICAgICogQ29tbW9uIHN1cGVyaW50ZXJmYWNlcyB0byBhbGwgZ3JhcGggbm9kZXMuCiAgICAgKi8KICAgIHB1YmxpYyBpbnRlcmZhY2UgTm9kZTxELCBOIGV4dGVuZHMgTm9kZTxELCBOPj4gewogICAgICAgIC8qKgogICAgICAgICAqIHZpc2l0b3IgbWV0aG9kLgogICAgICAgICAqLwogICAgICAgIDxBPiB2b2lkIGFjY2VwdChOb2RlVmlzaXRvcjxELCBOLCBBPiB2aXNpdG9yLCBBIGFyZyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBWaXNpdG9yIGZvciBncmFwaCBub2Rlcy4KICAgICAqLwogICAgc3RhdGljIGFic3RyYWN0IGNsYXNzIE5vZGVWaXNpdG9yPEQsIE4gZXh0ZW5kcyBOb2RlPEQsIE4+LCBBPiB7CiAgICAgICAgLyoqCiAgICAgICAgICogVmlzaXRvciBhY3Rpb24gZm9yIG5vZGVzLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHZpc2l0Tm9kZShOIG5vZGUsIEEgYXJnKTsKICAgICAgICAvKioKICAgICAgICAgKiBWaXNpdG9yIGFjdGlvbiBmb3IgYSBkZXBlbmRlbmN5IGJldHdlZW4gJ2Zyb20nIGFuZCAndG8nIHdpdGggZ2l2ZW4ga2luZC4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCB2aXNpdERlcGVuZGVuY3koRGVwZW5kZW5jeUtpbmQgZGssIE4gZnJvbSwgTiB0bywgQSBhcmcpOwoKICAgICAgICAvKioKICAgICAgICAgKiBWaXNpdG9yIGVudHJ5IHBvaW50LgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0KENvbGxlY3Rpb248PyBleHRlbmRzIE4+IG5vZGVzLCBBIGFyZykgewogICAgICAgICAgICBmb3IgKE4gbiA6IG5ldyBBcnJheUxpc3Q8Pihub2RlcykpIHsKICAgICAgICAgICAgICAgIG4uYWNjZXB0KHRoaXMsIGFyZyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBPcHRpb25hbCBpbnRlcmZhY2UgZm9yIG5vZGVzIHN1cHBvcnRpbmcgZG90LWJhc2VkIHJlcHJlc2VudGF0aW9uLgogICAgICovCiAgICBwdWJsaWMgaW50ZXJmYWNlIERvdHRhYmxlTm9kZTxELCBOIGV4dGVuZHMgRG90dGFibGVOb2RlPEQsIE4+PiBleHRlbmRzIE5vZGU8RCwgTj4gewogICAgICAgIC8qKgogICAgICAgICAqIFJldHJpZXZlcyB0aGUgc2V0IG9mIGRvdCBhdHRyaWJ1dGVzIGFzc29jaWF0ZWQgd2l0aCB0aGUgbm9kZS4KICAgICAgICAgKi8KICAgICAgICBQcm9wZXJ0aWVzIG5vZGVBdHRyaWJ1dGVzKCk7CiAgICAgICAgLyoqCiAgICAgICAgICogUmV0cmlldmVzIHRoZSBzZXQgb2YgZG90IGF0dHJpYnV0ZXMgYXNzb2NpYXRlZCB3aXRoIGEgZ2l2ZW4gZGVwZW5kZW5jeS4KICAgICAgICAgKi8KICAgICAgICBQcm9wZXJ0aWVzIGRlcGVuZGVuY3lBdHRyaWJ1dGVzKE4gdG8sIERlcGVuZGVuY3lLaW5kIGRrKTsKICAgIH0KCiAgICAvKioKICAgICAqIFRoaXMgY2xhc3MgaXMgYSBiYXNpYyBhYnN0cmFjdCBjbGFzcyBmb3IgcmVwcmVzZW50aW5nIGEgbm9kZS4KICAgICAqIEEgbm9kZSBpcyBhc3NvY2lhdGVkIHdpdGggYSBnaXZlbiBkYXRhLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGFic3RyYWN0IGNsYXNzIEFic3RyYWN0Tm9kZTxELCBOIGV4dGVuZHMgQWJzdHJhY3ROb2RlPEQsIE4+PiBpbXBsZW1lbnRzIE5vZGU8RCwgTj4gewogICAgICAgIHB1YmxpYyBmaW5hbCBEIGRhdGE7CgogICAgICAgIHB1YmxpYyBBYnN0cmFjdE5vZGUoRCBkYXRhKSB7CiAgICAgICAgICAgIHRoaXMuZGF0YSA9IGRhdGE7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBHZXQgYW4gYXJyYXkgb2YgdGhlIGRlcGVuZGVuY3kga2luZHMgc3VwcG9ydGVkIGJ5IHRoaXMgbm9kZS4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgYWJzdHJhY3QgRGVwZW5kZW5jeUtpbmRbXSBnZXRTdXBwb3J0ZWREZXBlbmRlbmN5S2luZHMoKTsKCiAgICAgICAgLyoqCiAgICAgICAgICogR2V0IGFsbCBkZXBlbmRlbmNpZXMgb2YgYSBnaXZlbiBraW5kCiAgICAgICAgICovCiAgICAgICAgcHVibGljIGFic3RyYWN0IENvbGxlY3Rpb248PyBleHRlbmRzIE4+IGdldERlcGVuZGVuY2llc0J5S2luZChEZXBlbmRlbmN5S2luZCBkayk7CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CiAgICAgICAgICAgIHJldHVybiBkYXRhLnRvU3RyaW5nKCk7CiAgICAgICAgfQoKICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKICAgICAgICBwdWJsaWMgPEE+IHZvaWQgYWNjZXB0KE5vZGVWaXNpdG9yPEQsIE4sIEE+IHZpc2l0b3IsIEEgYXJnKSB7CiAgICAgICAgICAgIHZpc2l0b3IudmlzaXROb2RlKChOKXRoaXMsIGFyZyk7CiAgICAgICAgICAgIGZvciAoRGVwZW5kZW5jeUtpbmQgZGsgOiBnZXRTdXBwb3J0ZWREZXBlbmRlbmN5S2luZHMoKSkgewogICAgICAgICAgICAgICAgZm9yIChOIGRlcCA6IG5ldyBBcnJheUxpc3Q8PihnZXREZXBlbmRlbmNpZXNCeUtpbmQoZGspKSkgewogICAgICAgICAgICAgICAgICAgIHZpc2l0b3IudmlzaXREZXBlbmRlbmN5KGRrLCAoTil0aGlzLCBkZXAsIGFyZyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBUaGlzIGNsYXNzIHNwZWNpYWxpemVkIE5vZGUsIGJ5IGFkZGluZyBlbGVtZW50cyB0aGF0IGFyZSByZXF1aXJlZCBpbiBvcmRlcgogICAgICogdG8gcGVyZm9ybSBUYXJqYW4gY29tcHV0YXRpb24gb2Ygc3Ryb25nbHkgY29ubmVjdGVkIGNvbXBvbmVudHMuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgYWJzdHJhY3QgY2xhc3MgVGFyamFuTm9kZTxELCBOIGV4dGVuZHMgVGFyamFuTm9kZTxELCBOPj4gZXh0ZW5kcyBBYnN0cmFjdE5vZGU8RCwgTj4KICAgICAgICAgICAgaW1wbGVtZW50cyBDb21wYXJhYmxlPE4+IHsKICAgICAgICBpbnQgaW5kZXggPSAtMTsKICAgICAgICBpbnQgbG93bGluazsKICAgICAgICBib29sZWFuIGFjdGl2ZTsKCiAgICAgICAgcHVibGljIFRhcmphbk5vZGUoRCBkYXRhKSB7CiAgICAgICAgICAgIHN1cGVyKGRhdGEpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIGFic3RyYWN0IEl0ZXJhYmxlPD8gZXh0ZW5kcyBOPiBnZXRBbGxEZXBlbmRlbmNpZXMoKTsKCiAgICAgICAgcHVibGljIGludCBjb21wYXJlVG8oTiBvKSB7CiAgICAgICAgICAgIHJldHVybiAoaW5kZXggPCBvLmluZGV4KSA/IC0xIDogKGluZGV4ID09IG8uaW5kZXgpID8gMCA6IDE7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogVGFyamFuJ3MgYWxnb3JpdGhtIHRvIGRldGVybWluZSBzdHJvbmdseSBjb25uZWN0ZWQgY29tcG9uZW50cyBvZiBhCiAgICAgKiBkaXJlY3RlZCBncmFwaCBpbiBsaW5lYXIgdGltZS4gV29ya3Mgb24gVGFyamFuTm9kZS4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyA8RCwgTiBleHRlbmRzIFRhcmphbk5vZGU8RCwgTj4+IExpc3Q8PyBleHRlbmRzIExpc3Q8PyBleHRlbmRzIE4+PiB0YXJqYW4oSXRlcmFibGU8PyBleHRlbmRzIE4+IG5vZGVzKSB7CiAgICAgICAgVGFyamFuPEQsIE4+IHRhcmphbiA9IG5ldyBUYXJqYW48PigpOwogICAgICAgIHJldHVybiB0YXJqYW4uZmluZFNDQyhub2Rlcyk7CiAgICB9CiAgICAvL3doZXJlCiAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBUYXJqYW48RCwgTiBleHRlbmRzIFRhcmphbk5vZGU8RCwgTj4+IHsKCiAgICAgICAgLyoqIFVuaXF1ZSBub2RlIGlkZW50aWZpZXIuICovCiAgICAgICAgaW50IGluZGV4ID0gMDsKCiAgICAgICAgLyoqIExpc3Qgb2YgU0NDcyBmb3VuZCBmc28gZmFyLiAqLwogICAgICAgIExpc3RCdWZmZXI8TGlzdDxOPj4gc2NjcyA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKCiAgICAgICAgLyoqIFN0YWNrIG9mIGFsbCByZWFjaGVhYmxlIG5vZGVzIGZyb20gZ2l2ZW4gcm9vdC4gKi8KICAgICAgICBMaXN0QnVmZmVyPE4+IHN0YWNrID0gbmV3IExpc3RCdWZmZXI8PigpOwoKICAgICAgICBwcml2YXRlIExpc3Q8PyBleHRlbmRzIExpc3Q8PyBleHRlbmRzIE4+PiBmaW5kU0NDKEl0ZXJhYmxlPD8gZXh0ZW5kcyBOPiBub2RlcykgewogICAgICAgICAgICBmb3IgKE4gbm9kZSA6IG5vZGVzKSB7CiAgICAgICAgICAgICAgICBpZiAobm9kZS5pbmRleCA9PSAtMSkgewogICAgICAgICAgICAgICAgICAgIGZpbmRTQ0Mobm9kZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHNjY3MudG9MaXN0KCk7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIHZvaWQgZmluZFNDQyhOIHYpIHsKICAgICAgICAgICAgdmlzaXROb2RlKHYpOwogICAgICAgICAgICBmb3IgKE4gbjogdi5nZXRBbGxEZXBlbmRlbmNpZXMoKSkgewogICAgICAgICAgICAgICAgaWYgKG4uaW5kZXggPT0gLTEpIHsKICAgICAgICAgICAgICAgICAgICAvL2l0J3MgdGhlIGZpcnN0IHRpbWUgd2Ugc2VlIHRoaXMgbm9kZQogICAgICAgICAgICAgICAgICAgIGZpbmRTQ0Mobik7CiAgICAgICAgICAgICAgICAgICAgdi5sb3dsaW5rID0gTWF0aC5taW4odi5sb3dsaW5rLCBuLmxvd2xpbmspOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChzdGFjay5jb250YWlucyhuKSkgewogICAgICAgICAgICAgICAgICAgIC8vdGhpcyBub2RlIGlzIGFscmVhZHkgcmVhY2hhYmxlIGZyb20gY3VycmVudCByb290CiAgICAgICAgICAgICAgICAgICAgdi5sb3dsaW5rID0gTWF0aC5taW4odi5sb3dsaW5rLCBuLmluZGV4KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAodi5sb3dsaW5rID09IHYuaW5kZXgpIHsKICAgICAgICAgICAgICAgIC8vdiBpcyB0aGUgcm9vdCBvZiBhIFNDQwogICAgICAgICAgICAgICAgYWRkU0NDKHYpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIHZvaWQgdmlzaXROb2RlKE4gbikgewogICAgICAgICAgICBuLmluZGV4ID0gaW5kZXg7CiAgICAgICAgICAgIG4ubG93bGluayA9IGluZGV4OwogICAgICAgICAgICBpbmRleCsrOwogICAgICAgICAgICBzdGFjay5wcmVwZW5kKG4pOwogICAgICAgICAgICBuLmFjdGl2ZSA9IHRydWU7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIHZvaWQgYWRkU0NDKE4gdikgewogICAgICAgICAgICBOIG47CiAgICAgICAgICAgIExpc3RCdWZmZXI8Tj4gY3ljbGUgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgIGRvIHsKICAgICAgICAgICAgICAgIG4gPSBzdGFjay5yZW1vdmUoKTsKICAgICAgICAgICAgICAgIG4uYWN0aXZlID0gZmFsc2U7CiAgICAgICAgICAgICAgICBjeWNsZS5hZGQobik7CiAgICAgICAgICAgIH0gd2hpbGUgKG4gIT0gdik7CiAgICAgICAgICAgIHNjY3MuYWRkKGN5Y2xlLnRvTGlzdCgpKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBEZWJ1Z2dpbmc6IGRvdCByZXByZXNlbnRhdGlvbiBvZiBhIHNldCBvZiBjb25uZWN0ZWQgbm9kZXMuIFRoZSByZXN1bHRpbmcKICAgICAqIGRvdCByZXByZXNlbnRhdGlvbiB3aWxsIHVzZSB7QGNvZGUgTm9kZS50b1N0cmluZ30gdG8gZGlzcGxheSBub2RlIGxhYmVscwogICAgICogYW5kIHtAY29kZSBOb2RlLnByaW50RGVwZW5kZW5jeX0gdG8gZGlzcGxheSBlZGdlIGxhYmVscy4gVGhlIHJlc3VsdGluZwogICAgICogcmVwcmVzZW50YXRpb24gaXMgYWxzbyBjdXN0b21pemFibGUgd2l0aCBhIGdyYXBoIG5hbWUgYW5kIGEgaGVhZGVyLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIDxELCBOIGV4dGVuZHMgRG90dGFibGVOb2RlPEQsIE4+PiBTdHJpbmcgdG9Eb3QoQ29sbGVjdGlvbjw/IGV4dGVuZHMgTj4gbm9kZXMsIFN0cmluZyBuYW1lLCBTdHJpbmcgaGVhZGVyKSB7CiAgICAgICAgU3RyaW5nQnVpbGRlciBidWYgPSBuZXcgU3RyaW5nQnVpbGRlcigpOwogICAgICAgIGJ1Zi5hcHBlbmQoU3RyaW5nLmZvcm1hdCgiZGlncmFwaCAlcyB7XG4iLCBuYW1lKSk7CiAgICAgICAgYnVmLmFwcGVuZChTdHJpbmcuZm9ybWF0KCJsYWJlbCA9ICVzO1xuIiwgRG90VmlzaXRvci53cmFwKGhlYWRlcikpKTsKICAgICAgICBEb3RWaXNpdG9yPEQsIE4+IGRvdFZpc2l0b3IgPSBuZXcgRG90VmlzaXRvcjw+KCk7CiAgICAgICAgZG90VmlzaXRvci52aXNpdChub2RlcywgYnVmKTsKICAgICAgICBidWYuYXBwZW5kKCJ9XG4iKTsKICAgICAgICByZXR1cm4gYnVmLnRvU3RyaW5nKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBUaGlzIHZpc2l0b3IgaXMgdXNlZCB0byBkdW1wIHRoZSBjb250ZW50cyBvZiBhIHNldCBvZiBub2RlcyBvZiB0eXBlIHtAbGluayBEb3R0YWJsZU5vZGV9CiAgICAgKiBvbnRvIGEgc3RyaW5nIGJ1aWxkZXIuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgRG90VmlzaXRvcjxELCBOIGV4dGVuZHMgRG90dGFibGVOb2RlPEQsIE4+PiBleHRlbmRzIE5vZGVWaXNpdG9yPEQsIE4sIFN0cmluZ0J1aWxkZXI+IHsKCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXREZXBlbmRlbmN5KERlcGVuZGVuY3lLaW5kIGRrLCBOIGZyb20sIE4gdG8sIFN0cmluZ0J1aWxkZXIgYnVmKSB7CiAgICAgICAgICAgIGJ1Zi5hcHBlbmQoU3RyaW5nLmZvcm1hdCgiJXMgLT4gJXMiLCBmcm9tLmhhc2hDb2RlKCksIHRvLmhhc2hDb2RlKCkpKTsKICAgICAgICAgICAgYnVmLmFwcGVuZChmb3JtYXRQcm9wZXJ0aWVzKGZyb20uZGVwZW5kZW5jeUF0dHJpYnV0ZXModG8sIGRrKSkpOwogICAgICAgICAgICBidWYuYXBwZW5kKCdcbicpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXROb2RlKE4gbm9kZSwgU3RyaW5nQnVpbGRlciBidWYpIHsKICAgICAgICAgICAgYnVmLmFwcGVuZChTdHJpbmcuZm9ybWF0KCIlcyAiLCBub2RlLmhhc2hDb2RlKCkpKTsKICAgICAgICAgICAgYnVmLmFwcGVuZChmb3JtYXRQcm9wZXJ0aWVzKG5vZGUubm9kZUF0dHJpYnV0ZXMoKSkpOwogICAgICAgICAgICBidWYuYXBwZW5kKCdcbicpOwogICAgICAgIH0KCiAgICAgICAgcHJvdGVjdGVkIFN0cmluZyBmb3JtYXRQcm9wZXJ0aWVzKFByb3BlcnRpZXMgcCkgewogICAgICAgICAgICByZXR1cm4gcC50b1N0cmluZygpLnJlcGxhY2VBbGwoIiwiLCAiICIpCiAgICAgICAgICAgICAgICAucmVwbGFjZUFsbCgiXFx7IiwgIlsiKQogICAgICAgICAgICAgICAgLnJlcGxhY2VBbGwoIlxcfSIsICJdIik7CiAgICAgICAgfQoKICAgICAgICBwcm90ZWN0ZWQgc3RhdGljIFN0cmluZyB3cmFwKFN0cmluZyBzKSB7CiAgICAgICAgICAgIFN0cmluZyByZXMgPSAiXCIiICsgcyArICJcIiI7CiAgICAgICAgICAgIHJldHVybiByZXMucmVwbGFjZUFsbCgiXG4iLCAiIik7CiAgICAgICAgfQogICAgfQp9ClBLAwQKAAAIAADSfU1KLZBrSTwJAAA8CQAALgAAAGNvbS9zdW4vdG9vbHMvamF2YWMvdXRpbC9MYXlvdXRDaGFyYWN0ZXJzLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDE5OTksIDIwMTAsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhYy51dGlsOwoKLyoqIEFuIGludGVyZmFjZSBjb250YWluaW5nIGxheW91dCBjaGFyYWN0ZXIgY29uc3RhbnRzIHVzZWQgaW4gSmF2YQogKiAgcHJvZ3JhbXMuCiAqCiAqICA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiAgSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93biByaXNrLgogKiAgVGhpcyBjb2RlIGFuZCBpdHMgaW50ZXJuYWwgaW50ZXJmYWNlcyBhcmUgc3ViamVjdCB0byBjaGFuZ2Ugb3IKICogIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj4KICovCnB1YmxpYyBpbnRlcmZhY2UgTGF5b3V0Q2hhcmFjdGVycyB7CgogICAgLyoqIFRhYnVsYXRvciBjb2x1bW4gaW5jcmVtZW50LgogICAgICovCiAgICBmaW5hbCBzdGF0aWMgaW50IFRhYkluYyA9IDg7CgogICAgLyoqIFN0YW5kYXJkIGluZGVudGF0aW9uIGZvciBzdWJkaWFnbm9zdGljcwogICAgICovCiAgICBmaW5hbCBzdGF0aWMgaW50IERpYWdJbmMgPSA0OwoKICAgIC8qKiBTdGFuZGFyZCBpbmRlbnRhdGlvbiBmb3IgYWRkaXRpb25hbCBkaWFnbm9zdGljIGxpbmVzCiAgICAgKi8KICAgIGZpbmFsIHN0YXRpYyBpbnQgRGV0YWlsc0luYyA9IDI7CgogICAgLyoqIFRhYnVsYXRvciBjaGFyYWN0ZXIuCiAgICAgKi8KICAgIGZpbmFsIHN0YXRpYyBieXRlIFRBQiAgID0gMHg5OwoKICAgIC8qKiBMaW5lIGZlZWQgY2hhcmFjdGVyLgogICAgICovCiAgICBmaW5hbCBzdGF0aWMgYnl0ZSBMRiAgICA9IDB4QTsKCiAgICAvKiogRm9ybSBmZWVkIGNoYXJhY3Rlci4KICAgICAqLwogICAgZmluYWwgc3RhdGljIGJ5dGUgRkYgICAgPSAweEM7CgogICAgLyoqIENhcnJpYWdlIHJldHVybiBjaGFyYWN0ZXIuCiAgICAgKi8KICAgIGZpbmFsIHN0YXRpYyBieXRlIENSICAgID0gMHhEOwoKICAgIC8qKiBFbmQgb2YgaW5wdXQgY2hhcmFjdGVyLiAgVXNlZCBhcyBhIHNlbnRpbmVsIHRvIGRlbm90ZSB0aGUKICAgICAqICBjaGFyYWN0ZXIgb25lIGJleW9uZCB0aGUgbGFzdCBkZWZpbmVkIGNoYXJhY3RlciBpbiBhCiAgICAgKiAgc291cmNlIGZpbGUuCiAgICAgKi8KICAgIGZpbmFsIHN0YXRpYyBieXRlIEVPSSAgID0gMHgxQTsKfQpQSwMECgAACAAA0n1NSvUbcwYkCgAAJAoAACgAAABjb20vc3VuL3Rvb2xzL2phdmFjL3V0aWwvRmF0YWxFcnJvci5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAxOTk5LCAyMDEwLCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuamF2YWMudXRpbDsKCi8qKiBUaHJvd2luZyBhbiBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzIGNhdXNlcyBpbW1lZGlhdGUgdGVybWluYXRpb24KICogIG9mIHRoZSBtYWluIGNvbXBpbGVyIG1ldGhvZC4gIEl0IGlzIHVzZWQgd2hlbiBzb21lIG5vbi1yZWNvdmVyYWJsZQogKiAgZXJyb3IgaGFzIGJlZW4gZGV0ZWN0ZWQgaW4gdGhlIGNvbXBpbGVyIGVudmlyb25tZW50IGF0IHJ1bnRpbWUuCiAqCiAqICA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiAgSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93biByaXNrLgogKiAgVGhpcyBjb2RlIGFuZCBpdHMgaW50ZXJuYWwgaW50ZXJmYWNlcyBhcmUgc3ViamVjdCB0byBjaGFuZ2Ugb3IKICogIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj4KICovCnB1YmxpYyBjbGFzcyBGYXRhbEVycm9yIGV4dGVuZHMgRXJyb3IgewogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMDsKCiAgICAvKiogQ29uc3RydWN0IGEgPGNvZGU+RmF0YWxFcnJvcjwvY29kZT4gd2l0aCB0aGUgc3BlY2lmaWVkIGRldGFpbCBtZXNzYWdlLgogICAgICogIEBwYXJhbSBkIEEgZGlhZ25vc3RpYyBjb250YWluaW5nIHRoZSByZWFzb24gZm9yIGZhaWx1cmUuCiAgICAgKi8KICAgIHB1YmxpYyBGYXRhbEVycm9yKEpDRGlhZ25vc3RpYyBkKSB7CiAgICAgICAgc3VwZXIoZC50b1N0cmluZygpKTsKICAgIH0KCiAgICAvKiogQ29uc3RydWN0IGEgPGNvZGU+RmF0YWxFcnJvcjwvY29kZT4gd2l0aCB0aGUgc3BlY2lmaWVkIGRldGFpbCBtZXNzYWdlCiAgICAgKiBhbmQgY2F1c2UuCiAgICAgKiAgQHBhcmFtIGQgQSBkaWFnbm9zdGljIGNvbnRhaW5pbmcgdGhlIHJlYXNvbiBmb3IgZmFpbHVyZS4KICAgICAqICBAcGFyYW0gdCBBbiBleGNlcHRpb24gY2F1c2luZyB0aGUgZXJyb3IKICAgICAqLwogICAgcHVibGljIEZhdGFsRXJyb3IoSkNEaWFnbm9zdGljIGQsIFRocm93YWJsZSB0KSB7CiAgICAgICAgc3VwZXIoZC50b1N0cmluZygpLCB0KTsKICAgIH0KCiAgICAvKiogQ29uc3RydWN0IGEgPGNvZGU+RmF0YWxFcnJvcjwvY29kZT4gd2l0aCB0aGUgc3BlY2lmaWVkIGRldGFpbCBtZXNzYWdlLgogICAgICogIEBwYXJhbSBzIEFuIEVuZ2xpc2goISkgc3RyaW5nIGRlc2NyaWJpbmcgdGhlIGZhaWx1cmUsIHR5cGljYWxseSBiZWNhdXNlCiAgICAgKiAgICAgICAgICAgdGhlIGRpYWdub3N0aWMgcmVzb3VyY2VzIGFyZSBtaXNzaW5nLgogICAgICovCiAgICBwdWJsaWMgRmF0YWxFcnJvcihTdHJpbmcgcykgewogICAgICAgIHN1cGVyKHMpOwogICAgfQp9ClBLAwQKAAAIAADSfU1KeHidjhwNAAAcDQAAKAAAAGNvbS9zdW4vdG9vbHMvamF2YWMvdXRpbC9BcnJheVV0aWxzLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDE5OTksIDIwMTMsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhYy51dGlsOwoKaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LkFycmF5OwoKLyoqIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqICBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqICBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogKiAgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPgogKi8KcHVibGljIGNsYXNzIEFycmF5VXRpbHMgewoKICAgIHByaXZhdGUgc3RhdGljIGludCBjYWxjdWxhdGVOZXdMZW5ndGgoaW50IGN1cnJlbnRMZW5ndGgsIGludCBtYXhJbmRleCkgewogICAgICAgIHdoaWxlIChjdXJyZW50TGVuZ3RoIDwgbWF4SW5kZXggKyAxKQogICAgICAgICAgICBjdXJyZW50TGVuZ3RoID0gY3VycmVudExlbmd0aCAqIDI7CiAgICAgICAgcmV0dXJuIGN1cnJlbnRMZW5ndGg7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyA8VD4gVFtdIGVuc3VyZUNhcGFjaXR5KFRbXSBhcnJheSwgaW50IG1heEluZGV4KSB7CiAgICAgICAgaWYgKG1heEluZGV4IDwgYXJyYXkubGVuZ3RoKSB7CiAgICAgICAgICAgIHJldHVybiBhcnJheTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBpbnQgbmV3TGVuZ3RoID0gY2FsY3VsYXRlTmV3TGVuZ3RoKGFycmF5Lmxlbmd0aCwgbWF4SW5kZXgpOwogICAgICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKICAgICAgICAgICAgVFtdIHJlc3VsdCA9IChUW10pIEFycmF5Lm5ld0luc3RhbmNlKGFycmF5LmdldENsYXNzKCkuZ2V0Q29tcG9uZW50VHlwZSgpLCBuZXdMZW5ndGgpOwogICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGFycmF5LCAwLCByZXN1bHQsIDAsIGFycmF5Lmxlbmd0aCk7CiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgYnl0ZVtdIGVuc3VyZUNhcGFjaXR5KGJ5dGVbXSBhcnJheSwgaW50IG1heEluZGV4KSB7CiAgICAgICAgaWYgKG1heEluZGV4IDwgYXJyYXkubGVuZ3RoKSB7CiAgICAgICAgICAgIHJldHVybiBhcnJheTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBpbnQgbmV3TGVuZ3RoID0gY2FsY3VsYXRlTmV3TGVuZ3RoKGFycmF5Lmxlbmd0aCwgbWF4SW5kZXgpOwogICAgICAgICAgICBieXRlW10gcmVzdWx0ID0gbmV3IGJ5dGVbbmV3TGVuZ3RoXTsKICAgICAgICAgICAgU3lzdGVtLmFycmF5Y29weShhcnJheSwgMCwgcmVzdWx0LCAwLCBhcnJheS5sZW5ndGgpOwogICAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNoYXJbXSBlbnN1cmVDYXBhY2l0eShjaGFyW10gYXJyYXksIGludCBtYXhJbmRleCkgewogICAgICAgIGlmIChtYXhJbmRleCA8IGFycmF5Lmxlbmd0aCkgewogICAgICAgICAgICByZXR1cm4gYXJyYXk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgaW50IG5ld0xlbmd0aCA9IGNhbGN1bGF0ZU5ld0xlbmd0aChhcnJheS5sZW5ndGgsIG1heEluZGV4KTsKICAgICAgICAgICAgY2hhcltdIHJlc3VsdCA9IG5ldyBjaGFyW25ld0xlbmd0aF07CiAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYXJyYXksIDAsIHJlc3VsdCwgMCwgYXJyYXkubGVuZ3RoKTsKICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBpbnRbXSBlbnN1cmVDYXBhY2l0eShpbnRbXSBhcnJheSwgaW50IG1heEluZGV4KSB7CiAgICAgICAgaWYgKG1heEluZGV4IDwgYXJyYXkubGVuZ3RoKSB7CiAgICAgICAgICAgIHJldHVybiBhcnJheTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBpbnQgbmV3TGVuZ3RoID0gY2FsY3VsYXRlTmV3TGVuZ3RoKGFycmF5Lmxlbmd0aCwgbWF4SW5kZXgpOwogICAgICAgICAgICBpbnRbXSByZXN1bHQgPSBuZXcgaW50W25ld0xlbmd0aF07CiAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYXJyYXksIDAsIHJlc3VsdCwgMCwgYXJyYXkubGVuZ3RoKTsKICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CiAgICB9Cgp9ClBLAwQKAAAIAAAGO6lKgVkL9h4eAAAeHgAAIgAAAGNvbS9zdW4vdG9vbHMvamF2YWMvdXRpbC9OYW1lLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDE5OTksIDIwMTUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhYy51dGlsOwoKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5EZWZpbmVkQnkuQXBpOwoKLyoqIEFuIGFic3RyYWN0aW9uIGZvciBpbnRlcm5hbCBjb21waWxlciBzdHJpbmdzLiBUaGV5IGFyZSBzdG9yZWQgaW4KICogIFV0ZjggZm9ybWF0LiBOYW1lcyBhcmUgc3RvcmVkIGluIGEgTmFtZS5UYWJsZSwgYW5kIGFyZSB1bmlxdWUgd2l0aGluCiAqICB0aGF0IHRhYmxlLgogKgogKiAgPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24gcmlzay4KICogIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yCiAqICBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+CiAqLwpwdWJsaWMgYWJzdHJhY3QgY2xhc3MgTmFtZSBpbXBsZW1lbnRzIGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC5OYW1lIHsKCiAgICBwdWJsaWMgZmluYWwgVGFibGUgdGFibGU7CgogICAgcHJvdGVjdGVkIE5hbWUoVGFibGUgdGFibGUpIHsKICAgICAgICB0aGlzLnRhYmxlID0gdGFibGU7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgcHVibGljIGJvb2xlYW4gY29udGVudEVxdWFscyhDaGFyU2VxdWVuY2UgY3MpIHsKICAgICAgICByZXR1cm4gdG9TdHJpbmcoKS5lcXVhbHMoY3MudG9TdHJpbmcoKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBpbnQgbGVuZ3RoKCkgewogICAgICAgIHJldHVybiB0b1N0cmluZygpLmxlbmd0aCgpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgY2hhciBjaGFyQXQoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHRvU3RyaW5nKCkuY2hhckF0KGluZGV4KTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIENoYXJTZXF1ZW5jZSBzdWJTZXF1ZW5jZShpbnQgc3RhcnQsIGludCBlbmQpIHsKICAgICAgICByZXR1cm4gdG9TdHJpbmcoKS5zdWJTZXF1ZW5jZShzdGFydCwgZW5kKTsKICAgIH0KCiAgICAvKiogUmV0dXJuIHRoZSBjb25jYXRlbmF0aW9uIG9mIHRoaXMgbmFtZSBhbmQgbmFtZSBgbicuCiAgICAgKi8KICAgIHB1YmxpYyBOYW1lIGFwcGVuZChOYW1lIG4pIHsKICAgICAgICBpbnQgbGVuID0gZ2V0Qnl0ZUxlbmd0aCgpOwogICAgICAgIGJ5dGVbXSBicyA9IG5ldyBieXRlW2xlbiArIG4uZ2V0Qnl0ZUxlbmd0aCgpXTsKICAgICAgICBnZXRCeXRlcyhicywgMCk7CiAgICAgICAgbi5nZXRCeXRlcyhicywgbGVuKTsKICAgICAgICByZXR1cm4gdGFibGUuZnJvbVV0ZihicywgMCwgYnMubGVuZ3RoKTsKICAgIH0KCiAgICAvKiogUmV0dXJuIHRoZSBjb25jYXRlbmF0aW9uIG9mIHRoaXMgbmFtZSwgdGhlIGdpdmVuIEFTQ0lJCiAgICAgKiAgY2hhcmFjdGVyLCBhbmQgbmFtZSBgbicuCiAgICAgKi8KICAgIHB1YmxpYyBOYW1lIGFwcGVuZChjaGFyIGMsIE5hbWUgbikgewogICAgICAgIGludCBsZW4gPSBnZXRCeXRlTGVuZ3RoKCk7CiAgICAgICAgYnl0ZVtdIGJzID0gbmV3IGJ5dGVbbGVuICsgMSArIG4uZ2V0Qnl0ZUxlbmd0aCgpXTsKICAgICAgICBnZXRCeXRlcyhicywgMCk7CiAgICAgICAgYnNbbGVuXSA9IChieXRlKSBjOwogICAgICAgIG4uZ2V0Qnl0ZXMoYnMsIGxlbisxKTsKICAgICAgICByZXR1cm4gdGFibGUuZnJvbVV0ZihicywgMCwgYnMubGVuZ3RoKTsKICAgIH0KCiAgICAvKiogQW4gYXJiaXRyYXJ5IGJ1dCBjb25zaXN0ZW50IGNvbXBsZXRlIG9yZGVyIGFtb25nIGFsbCBOYW1lcy4KICAgICAqLwogICAgcHVibGljIGludCBjb21wYXJlVG8oTmFtZSBvdGhlcikgewogICAgICAgIHJldHVybiBvdGhlci5nZXRJbmRleCgpIC0gdGhpcy5nZXRJbmRleCgpOwogICAgfQoKICAgIC8qKiBSZXR1cm4gdHJ1ZSBpZiB0aGlzIGlzIHRoZSBlbXB0eSBuYW1lLgogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBpc0VtcHR5KCkgewogICAgICAgIHJldHVybiBnZXRCeXRlTGVuZ3RoKCkgPT0gMDsKICAgIH0KCiAgICAvKiogUmV0dXJucyBsYXN0IG9jY3VycmVuY2Ugb2YgYnl0ZSBiIGluIHRoaXMgbmFtZSwgLTEgaWYgbm90IGZvdW5kLgogICAgICovCiAgICBwdWJsaWMgaW50IGxhc3RJbmRleE9mKGJ5dGUgYikgewogICAgICAgIGJ5dGVbXSBieXRlcyA9IGdldEJ5dGVBcnJheSgpOwogICAgICAgIGludCBvZmZzZXQgPSBnZXRCeXRlT2Zmc2V0KCk7CiAgICAgICAgaW50IGkgPSBnZXRCeXRlTGVuZ3RoKCkgLSAxOwogICAgICAgIHdoaWxlIChpID49IDAgJiYgYnl0ZXNbb2Zmc2V0ICsgaV0gIT0gYikgaS0tOwogICAgICAgIHJldHVybiBpOwogICAgfQoKICAgIC8qKiBEb2VzIHRoaXMgbmFtZSBzdGFydCB3aXRoIHByZWZpeD8KICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gc3RhcnRzV2l0aChOYW1lIHByZWZpeCkgewogICAgICAgIGJ5dGVbXSB0aGlzQnl0ZXMgPSB0aGlzLmdldEJ5dGVBcnJheSgpOwogICAgICAgIGludCB0aGlzT2Zmc2V0ICAgPSB0aGlzLmdldEJ5dGVPZmZzZXQoKTsKICAgICAgICBpbnQgdGhpc0xlbmd0aCAgID0gdGhpcy5nZXRCeXRlTGVuZ3RoKCk7CiAgICAgICAgYnl0ZVtdIHByZWZpeEJ5dGVzID0gcHJlZml4LmdldEJ5dGVBcnJheSgpOwogICAgICAgIGludCBwcmVmaXhPZmZzZXQgICA9IHByZWZpeC5nZXRCeXRlT2Zmc2V0KCk7CiAgICAgICAgaW50IHByZWZpeExlbmd0aCAgID0gcHJlZml4LmdldEJ5dGVMZW5ndGgoKTsKCiAgICAgICAgaWYgKHRoaXNMZW5ndGggPCBwcmVmaXhMZW5ndGgpCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKCiAgICAgICAgaW50IGkgPSAwOwogICAgICAgIHdoaWxlIChpIDwgcHJlZml4TGVuZ3RoICYmCiAgICAgICAgICAgICAgIHRoaXNCeXRlc1t0aGlzT2Zmc2V0ICsgaV0gPT0gcHJlZml4Qnl0ZXNbcHJlZml4T2Zmc2V0ICsgaV0pCiAgICAgICAgICAgIGkrKzsKICAgICAgICByZXR1cm4gaSA9PSBwcmVmaXhMZW5ndGg7CiAgICB9CgogICAgLyoqIFJldHVybnMgdGhlIHN1Yi1uYW1lIHN0YXJ0aW5nIGF0IHBvc2l0aW9uIHN0YXJ0LCB1cCB0byBhbmQKICAgICAqICBleGNsdWRpbmcgcG9zaXRpb24gZW5kLgogICAgICovCiAgICBwdWJsaWMgTmFtZSBzdWJOYW1lKGludCBzdGFydCwgaW50IGVuZCkgewogICAgICAgIGlmIChlbmQgPCBzdGFydCkgZW5kID0gc3RhcnQ7CiAgICAgICAgcmV0dXJuIHRhYmxlLmZyb21VdGYoZ2V0Qnl0ZUFycmF5KCksIGdldEJ5dGVPZmZzZXQoKSArIHN0YXJ0LCBlbmQgLSBzdGFydCk7CiAgICB9CgogICAgLyoqIFJldHVybiB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgbmFtZS4KICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewogICAgICAgIHJldHVybiBDb252ZXJ0LnV0ZjJzdHJpbmcoZ2V0Qnl0ZUFycmF5KCksIGdldEJ5dGVPZmZzZXQoKSwgZ2V0Qnl0ZUxlbmd0aCgpKTsKICAgIH0KCiAgICAvKiogUmV0dXJuIHRoZSBVdGY4IHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgbmFtZS4KICAgICAqLwogICAgcHVibGljIGJ5dGVbXSB0b1V0ZigpIHsKICAgICAgICBieXRlW10gYnMgPSBuZXcgYnl0ZVtnZXRCeXRlTGVuZ3RoKCldOwogICAgICAgIGdldEJ5dGVzKGJzLCAwKTsKICAgICAgICByZXR1cm4gYnM7CiAgICB9CgogICAgLyogR2V0IGEgInJlYXNvbmFibHkgc21hbGwiIHZhbHVlIHRoYXQgdW5pcXVlbHkgaWRlbnRpZmllcyB0aGlzIG5hbWUKICAgICAqIHdpdGhpbiBpdHMgbmFtZSB0YWJsZS4KICAgICAqLwogICAgcHVibGljIGFic3RyYWN0IGludCBnZXRJbmRleCgpOwoKICAgIC8qKiBHZXQgdGhlIGxlbmd0aCAoaW4gYnl0ZXMpIG9mIHRoaXMgbmFtZS4KICAgICAqLwogICAgcHVibGljIGFic3RyYWN0IGludCBnZXRCeXRlTGVuZ3RoKCk7CgogICAgLyoqIFJldHVybnMgaSd0aCBieXRlIG9mIHRoaXMgbmFtZS4KICAgICAqLwogICAgcHVibGljIGFic3RyYWN0IGJ5dGUgZ2V0Qnl0ZUF0KGludCBpKTsKCiAgICAvKiogQ29weSBhbGwgYnl0ZXMgb2YgdGhpcyBuYW1lIHRvIGJ1ZmZlciBjcywgc3RhcnRpbmcgYXQgc3RhcnQuCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIGdldEJ5dGVzKGJ5dGUgY3NbXSwgaW50IHN0YXJ0KSB7CiAgICAgICAgU3lzdGVtLmFycmF5Y29weShnZXRCeXRlQXJyYXkoKSwgZ2V0Qnl0ZU9mZnNldCgpLCBjcywgc3RhcnQsIGdldEJ5dGVMZW5ndGgoKSk7CiAgICB9CgogICAgLyoqIEdldCB0aGUgdW5kZXJseWluZyBieXRlIGFycmF5IGZvciB0aGlzIG5hbWUuIFRoZSBjb250ZW50cyBvZiB0aGUKICAgICAqIGFycmF5IG11c3Qgbm90IGJlIG1vZGlmaWVkLgogICAgICovCiAgICBwdWJsaWMgYWJzdHJhY3QgYnl0ZVtdIGdldEJ5dGVBcnJheSgpOwoKICAgIC8qKiBHZXQgdGhlIHN0YXJ0IG9mZnNldCBvZiB0aGlzIG5hbWUgd2l0aGluIGl0cyBieXRlIGFycmF5LgogICAgICovCiAgICBwdWJsaWMgYWJzdHJhY3QgaW50IGdldEJ5dGVPZmZzZXQoKTsKCiAgICAvKiogQW4gYWJzdHJhY3Rpb24gZm9yIHRoZSBoYXNoIHRhYmxlIHVzZWQgdG8gY3JlYXRlIHVuaXF1ZSBOYW1lIGluc3RhbmNlcy4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBhYnN0cmFjdCBjbGFzcyBUYWJsZSB7CiAgICAgICAgLyoqIFN0YW5kYXJkIG5hbWUgdGFibGUuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIGZpbmFsIE5hbWVzIG5hbWVzOwoKICAgICAgICBUYWJsZShOYW1lcyBuYW1lcykgewogICAgICAgICAgICB0aGlzLm5hbWVzID0gbmFtZXM7CiAgICAgICAgfQoKICAgICAgICAvKiogR2V0IHRoZSBuYW1lIGZyb20gdGhlIGNoYXJhY3RlcnMgaW4gY3Nbc3RhcnQuLnN0YXJ0K2xlbi0xXS4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgYWJzdHJhY3QgTmFtZSBmcm9tQ2hhcnMoY2hhcltdIGNzLCBpbnQgc3RhcnQsIGludCBsZW4pOwoKICAgICAgICAvKiogR2V0IHRoZSBuYW1lIGZvciB0aGUgY2hhcmFjdGVycyBpbiBzdHJpbmcgcy4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgTmFtZSBmcm9tU3RyaW5nKFN0cmluZyBzKSB7CiAgICAgICAgICAgIGNoYXJbXSBjcyA9IHMudG9DaGFyQXJyYXkoKTsKICAgICAgICAgICAgcmV0dXJuIGZyb21DaGFycyhjcywgMCwgY3MubGVuZ3RoKTsKICAgICAgICB9CgogICAgICAgIC8qKiBHZXQgdGhlIG5hbWUgZm9yIHRoZSBieXRlcyBpbiBhcnJheSBjcy4KICAgICAgICAgKiAgQXNzdW1lIHRoYXQgYnl0ZXMgYXJlIGluIHV0ZjggZm9ybWF0LgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBOYW1lIGZyb21VdGYoYnl0ZVtdIGNzKSB7CiAgICAgICAgICAgIHJldHVybiBmcm9tVXRmKGNzLCAwLCBjcy5sZW5ndGgpOwogICAgICAgIH0KCiAgICAgICAgLyoqIGdldCB0aGUgbmFtZSBmb3IgdGhlIGJ5dGVzIGluIGNzW3N0YXJ0Li5zdGFydCtsZW4tMV0uCiAgICAgICAgICogIEFzc3VtZSB0aGF0IGJ5dGVzIGFyZSBpbiB1dGY4IGZvcm1hdC4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgYWJzdHJhY3QgTmFtZSBmcm9tVXRmKGJ5dGVbXSBjcywgaW50IHN0YXJ0LCBpbnQgbGVuKTsKCiAgICAgICAgLyoqIFJlbGVhc2UgYW55IHJlc291cmNlcyB1c2VkIGJ5IHRoaXMgdGFibGUuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIGFic3RyYWN0IHZvaWQgZGlzcG9zZSgpOwoKICAgICAgICAvKiogVGhlIGhhc2hjb2RlIG9mIGEgbmFtZS4KICAgICAgICAgKi8KICAgICAgICBwcm90ZWN0ZWQgc3RhdGljIGludCBoYXNoVmFsdWUoYnl0ZSBieXRlc1tdLCBpbnQgb2Zmc2V0LCBpbnQgbGVuZ3RoKSB7CiAgICAgICAgICAgIGludCBoID0gMDsKICAgICAgICAgICAgaW50IG9mZiA9IG9mZnNldDsKCiAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgICAgIGggPSAoaCA8PCA1KSAtIGggKyBieXRlc1tvZmYrK107CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGg7CiAgICAgICAgfQoKICAgICAgICAvKiogQ29tcGFyZSB0d28gc3ViYXJyYXlzCiAgICAgICAgICovCiAgICAgICAgcHJvdGVjdGVkIHN0YXRpYyBib29sZWFuIGVxdWFscyhieXRlW10gYnl0ZXMxLCBpbnQgb2Zmc2V0MSwKICAgICAgICAgICAgICAgIGJ5dGVbXSBieXRlczIsIGludCBvZmZzZXQyLCBpbnQgbGVuZ3RoKSB7CiAgICAgICAgICAgIGludCBpID0gMDsKICAgICAgICAgICAgd2hpbGUgKGkgPCBsZW5ndGggJiYgYnl0ZXMxW29mZnNldDEgKyBpXSA9PSBieXRlczJbb2Zmc2V0MiArIGldKSB7CiAgICAgICAgICAgICAgICBpKys7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGkgPT0gbGVuZ3RoOwogICAgICAgIH0KICAgIH0KfQpQSwMECgAACAAABjupSoUFQOvTPwAA0z8AADYAAABjb20vc3VuL3Rvb2xzL2phdmFjL3V0aWwvQmFzaWNEaWFnbm9zdGljRm9ybWF0dGVyLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMTYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhYy51dGlsOwoKaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uOwppbXBvcnQgamF2YS51dGlsLkVudW1NYXA7CmltcG9ydCBqYXZhLnV0aWwuRW51bVNldDsKaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOwppbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKaW1wb3J0IGphdmEudXRpbC5NYXA7CmltcG9ydCBqYXZhLnV0aWwucmVnZXguTWF0Y2hlcjsKaW1wb3J0IGphdmF4LnRvb2xzLkphdmFGaWxlT2JqZWN0OwoKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5BYnN0cmFjdERpYWdub3N0aWNGb3JtYXR0ZXIuU2ltcGxlQ29uZmlndXJhdGlvbjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5CYXNpY0RpYWdub3N0aWNGb3JtYXR0ZXIuQmFzaWNDb25maWd1cmF0aW9uOwoKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmFwaS5EaWFnbm9zdGljRm9ybWF0dGVyLlBvc2l0aW9uS2luZC4qOwppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5CYXNpY0RpYWdub3N0aWNGb3JtYXR0ZXIuQmFzaWNDb25maWd1cmF0aW9uLio7CmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkxheW91dENoYXJhY3RlcnMuKjsKCi8qKgogKiBBIGJhc2ljIGZvcm1hdHRlciBmb3IgZGlhZ25vc3RpYyBtZXNzYWdlcy4KICogVGhlIGJhc2ljIGZvcm1hdHRlciB3aWxsIGZvcm1hdCBhIGRpYWdub3N0aWMgYWNjb3JkaW5nIHRvIG9uZSBvZiB0aHJlZSBmb3JtYXQgcGF0dGVybnMsIGRlcGVuZGluZyBvbiB3aGV0aGVyCiAqIG9yIG5vdCB0aGUgc291cmNlIG5hbWUgYW5kIHBvc2l0aW9uIGFyZSBzZXQuIFRoZSBmb3JtYXR0ZXIgc3VwcG9ydHMgYSBwcmludGYtbGlrZSBzdHJpbmcgZm9yIHBhdHRlcm5zCiAqIHdpdGggdGhlIGZvbGxvd2luZyBzcGVjaWFsIGNoYXJhY3RlcnM6CiAqIDx1bD4KICogPGxpPiViOiB0aGUgYmFzZSBvZiB0aGUgc291cmNlIG5hbWUKICogPGxpPiVmOiB0aGUgc291cmNlIG5hbWUgKGZ1bGwgYWJzb2x1dGUgcGF0aCkKICogPGxpPiVsOiB0aGUgbGluZSBudW1iZXIgb2YgdGhlIGRpYWdub3N0aWMsIGRlcml2ZWQgZnJvbSB0aGUgY2hhcmFjdGVyIG9mZnNldAogKiA8bGk+JWM6IHRoZSBjb2x1bW4gbnVtYmVyIG9mIHRoZSBkaWFnbm9zdGljLCBkZXJpdmVkIGZyb20gdGhlIGNoYXJhY3RlciBvZmZzZXQKICogPGxpPiVvOiB0aGUgY2hhcmFjdGVyIG9mZnNldCBvZiB0aGUgZGlhZ25vc3RpYyBpZiBzZXQKICogPGxpPiVwOiB0aGUgcHJlZml4IGZvciB0aGUgZGlhZ25vc3RpYywgZGVyaXZlZCBmcm9tIHRoZSBkaWFnbm9zdGljIHR5cGUKICogPGxpPiV0OiB0aGUgcHJlZml4IGFzIGl0IG5vcm1hbGx5IGFwcGVhcnMgaW4gc3RhbmRhcmQgZGlhZ25vc3RpY3MuIEluIHRoaXMgY2FzZSwgbm8gcHJlZml4IGlzCiAqICAgICAgICBzaG93biBpZiB0aGUgdHlwZSBpcyBFUlJPUiBhbmQgaWYgYSBzb3VyY2UgbmFtZSBpcyBzZXQKICogPGxpPiVtOiB0aGUgdGV4dCBvciB0aGUgZGlhZ25vc3RpYywgaW5jbHVkaW5nIGFueSBhcHByb3ByaWF0ZSBhcmd1bWVudHMKICogPGxpPiVfOiBzcGFjZSBkZWxpbWl0ZXIsIHVzZWZ1bCBmb3IgZm9ybWF0dGluZyBwdXJwb3NlcwogKiA8L3VsPgogKgogKiA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yCiAqIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj4KICovCnB1YmxpYyBjbGFzcyBCYXNpY0RpYWdub3N0aWNGb3JtYXR0ZXIgZXh0ZW5kcyBBYnN0cmFjdERpYWdub3N0aWNGb3JtYXR0ZXIgewoKICAgIC8qKgogICAgICogQ3JlYXRlIGEgYmFzaWMgZm9ybWF0dGVyIGJhc2VkIG9uIHRoZSBzdXBwbGllZCBvcHRpb25zLgogICAgICoKICAgICAqIEBwYXJhbSBvcHRpb25zIGxpc3Qgb2YgY29tbWFuZC1saW5lIG9wdGlvbnMKICAgICAqIEBwYXJhbSBtc2dzIEphdmFjTWVzc2FnZXMgb2JqZWN0IHVzZWQgZm9yIGkxOG4KICAgICAqLwogICAgcHVibGljIEJhc2ljRGlhZ25vc3RpY0Zvcm1hdHRlcihPcHRpb25zIG9wdGlvbnMsIEphdmFjTWVzc2FnZXMgbXNncykgewogICAgICAgIHN1cGVyKG1zZ3MsIG5ldyBCYXNpY0NvbmZpZ3VyYXRpb24ob3B0aW9ucykpOwogICAgfQoKICAgIC8qKgogICAgICogQ3JlYXRlIGEgc3RhbmRhcmQgYmFzaWMgZm9ybWF0dGVyCiAgICAgKgogICAgICogQHBhcmFtIG1zZ3MgSmF2YWNNZXNzYWdlcyBvYmplY3QgdXNlZCBmb3IgaTE4bgogICAgICovCiAgICBwdWJsaWMgQmFzaWNEaWFnbm9zdGljRm9ybWF0dGVyKEphdmFjTWVzc2FnZXMgbXNncykgewogICAgICAgIHN1cGVyKG1zZ3MsIG5ldyBCYXNpY0NvbmZpZ3VyYXRpb24oKSk7CiAgICB9CgogICAgcHVibGljIFN0cmluZyBmb3JtYXREaWFnbm9zdGljKEpDRGlhZ25vc3RpYyBkLCBMb2NhbGUgbCkgewogICAgICAgIGlmIChsID09IG51bGwpCiAgICAgICAgICAgIGwgPSBtZXNzYWdlcy5nZXRDdXJyZW50TG9jYWxlKCk7CiAgICAgICAgU3RyaW5nIGZvcm1hdCA9IHNlbGVjdEZvcm1hdChkKTsKICAgICAgICBTdHJpbmdCdWlsZGVyIGJ1ZiA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmb3JtYXQubGVuZ3RoKCk7IGkrKykgewogICAgICAgICAgICBjaGFyIGMgPSBmb3JtYXQuY2hhckF0KGkpOwogICAgICAgICAgICBib29sZWFuIG1ldGEgPSBmYWxzZTsKICAgICAgICAgICAgaWYgKGMgPT0gJyUnICYmIGkgPCBmb3JtYXQubGVuZ3RoKCkgLSAxKSB7CiAgICAgICAgICAgICAgICBtZXRhID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGMgPSBmb3JtYXQuY2hhckF0KCsraSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnVmLmFwcGVuZChtZXRhID8gZm9ybWF0TWV0YShjLCBkLCBsKSA6IFN0cmluZy52YWx1ZU9mKGMpKTsKICAgICAgICB9CiAgICAgICAgaWYgKGRlcHRoID09IDApCiAgICAgICAgICAgIHJldHVybiBhZGRTb3VyY2VMaW5lSWZOZWVkZWQoZCwgYnVmLnRvU3RyaW5nKCkpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgcmV0dXJuIGJ1Zi50b1N0cmluZygpOwogICAgfQoKICAgIHB1YmxpYyBTdHJpbmcgZm9ybWF0TWVzc2FnZShKQ0RpYWdub3N0aWMgZCwgTG9jYWxlIGwpIHsKICAgICAgICBpbnQgY3VycmVudEluZGVudGF0aW9uID0gMDsKICAgICAgICBTdHJpbmdCdWlsZGVyIGJ1ZiA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CiAgICAgICAgQ29sbGVjdGlvbjxTdHJpbmc+IGFyZ3MgPSBmb3JtYXRBcmd1bWVudHMoZCwgbCk7CiAgICAgICAgU3RyaW5nIG1zZyA9IGxvY2FsaXplKGwsIGQuZ2V0Q29kZSgpLCBhcmdzLnRvQXJyYXkoKSk7CiAgICAgICAgU3RyaW5nW10gbGluZXMgPSBtc2cuc3BsaXQoIlxuIik7CiAgICAgICAgaWYgKGxpbmVzLmxlbmd0aCA9PSAwKSAvLyB3aWxsIGhhcHBlbiB3aGVuIG1zZyBvbmx5IGNvbnRhaW5zIG9uZSBvciBtb3JlIHNlcGFyYXRvcnM6ICJcbiIsICJcblxuIiwgZXRjLgogICAgICAgICAgICBsaW5lcyA9IG5ldyBTdHJpbmdbXSB7ICIiIH07CiAgICAgICAgaWYgKGdldENvbmZpZ3VyYXRpb24oKS5nZXRWaXNpYmxlKCkuY29udGFpbnMoRGlhZ25vc3RpY1BhcnQuU1VNTUFSWSkpIHsKICAgICAgICAgICAgY3VycmVudEluZGVudGF0aW9uICs9IGdldENvbmZpZ3VyYXRpb24oKS5nZXRJbmRlbnRhdGlvbihEaWFnbm9zdGljUGFydC5TVU1NQVJZKTsKICAgICAgICAgICAgYnVmLmFwcGVuZChpbmRlbnQobGluZXNbMF0sIGN1cnJlbnRJbmRlbnRhdGlvbikpOyAvL3N1bW1hcnkKICAgICAgICB9CiAgICAgICAgaWYgKGxpbmVzLmxlbmd0aCA+IDEgJiYgZ2V0Q29uZmlndXJhdGlvbigpLmdldFZpc2libGUoKS5jb250YWlucyhEaWFnbm9zdGljUGFydC5ERVRBSUxTKSkgewogICAgICAgICAgICBjdXJyZW50SW5kZW50YXRpb24gKz0gZ2V0Q29uZmlndXJhdGlvbigpLmdldEluZGVudGF0aW9uKERpYWdub3N0aWNQYXJ0LkRFVEFJTFMpOwogICAgICAgICAgICBmb3IgKGludCBpID0gMTtpIDwgbGluZXMubGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQoIlxuIiArIGluZGVudChsaW5lc1tpXSwgY3VycmVudEluZGVudGF0aW9uKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKGQuaXNNdWx0aWxpbmUoKSAmJiBnZXRDb25maWd1cmF0aW9uKCkuZ2V0VmlzaWJsZSgpLmNvbnRhaW5zKERpYWdub3N0aWNQYXJ0LlNVQkRJQUdOT1NUSUNTKSkgewogICAgICAgICAgICBjdXJyZW50SW5kZW50YXRpb24gKz0gZ2V0Q29uZmlndXJhdGlvbigpLmdldEluZGVudGF0aW9uKERpYWdub3N0aWNQYXJ0LlNVQkRJQUdOT1NUSUNTKTsKICAgICAgICAgICAgICAgIGZvciAoU3RyaW5nIHN1YiA6IGZvcm1hdFN1YmRpYWdub3N0aWNzKGQsIGwpKSB7CiAgICAgICAgICAgICAgICAgICAgYnVmLmFwcGVuZCgiXG4iICsgaW5kZW50KHN1YiwgY3VycmVudEluZGVudGF0aW9uKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1Zi50b1N0cmluZygpOwogICAgfQoKICAgIHByb3RlY3RlZCBTdHJpbmcgYWRkU291cmNlTGluZUlmTmVlZGVkKEpDRGlhZ25vc3RpYyBkLCBTdHJpbmcgbXNnKSB7CiAgICAgICAgaWYgKCFkaXNwbGF5U291cmNlKGQpKQogICAgICAgICAgICByZXR1cm4gbXNnOwogICAgICAgIGVsc2UgewogICAgICAgICAgICBCYXNpY0NvbmZpZ3VyYXRpb24gY29uZiA9IGdldENvbmZpZ3VyYXRpb24oKTsKICAgICAgICAgICAgaW50IGluZGVudFNvdXJjZSA9IGNvbmYuZ2V0SW5kZW50YXRpb24oRGlhZ25vc3RpY1BhcnQuU09VUkNFKTsKICAgICAgICAgICAgU3RyaW5nIHNvdXJjZUxpbmUgPSAiXG4iICsgZm9ybWF0U291cmNlTGluZShkLCBpbmRlbnRTb3VyY2UpOwogICAgICAgICAgICBib29sZWFuIHNpbmdsZUxpbmUgPSAhbXNnLmNvbnRhaW5zKCJcbiIpOwogICAgICAgICAgICBpZiAoc2luZ2xlTGluZSB8fCBnZXRDb25maWd1cmF0aW9uKCkuZ2V0U291cmNlUG9zaXRpb24oKSA9PSBTb3VyY2VQb3NpdGlvbi5CT1RUT00pCiAgICAgICAgICAgICAgICByZXR1cm4gbXNnICsgc291cmNlTGluZTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgcmV0dXJuIG1zZy5yZXBsYWNlRmlyc3QoIlxuIiwgTWF0Y2hlci5xdW90ZVJlcGxhY2VtZW50KHNvdXJjZUxpbmUpICsgIlxuIik7CiAgICAgICAgfQogICAgfQoKICAgIHByb3RlY3RlZCBTdHJpbmcgZm9ybWF0TWV0YShjaGFyIGMsIEpDRGlhZ25vc3RpYyBkLCBMb2NhbGUgbCkgewogICAgICAgIHN3aXRjaCAoYykgewogICAgICAgICAgICBjYXNlICdiJzoKICAgICAgICAgICAgICAgIHJldHVybiBmb3JtYXRTb3VyY2UoZCwgZmFsc2UsIGwpOwogICAgICAgICAgICBjYXNlICdlJzoKICAgICAgICAgICAgICAgIHJldHVybiBmb3JtYXRQb3NpdGlvbihkLCBFTkQsIGwpOwogICAgICAgICAgICBjYXNlICdmJzoKICAgICAgICAgICAgICAgIHJldHVybiBmb3JtYXRTb3VyY2UoZCwgdHJ1ZSwgbCk7CiAgICAgICAgICAgIGNhc2UgJ2wnOgogICAgICAgICAgICAgICAgcmV0dXJuIGZvcm1hdFBvc2l0aW9uKGQsIExJTkUsIGwpOwogICAgICAgICAgICBjYXNlICdjJzoKICAgICAgICAgICAgICAgIHJldHVybiBmb3JtYXRQb3NpdGlvbihkLCBDT0xVTU4sIGwpOwogICAgICAgICAgICBjYXNlICdvJzoKICAgICAgICAgICAgICAgIHJldHVybiBmb3JtYXRQb3NpdGlvbihkLCBPRkZTRVQsIGwpOwogICAgICAgICAgICBjYXNlICdwJzoKICAgICAgICAgICAgICAgIHJldHVybiBmb3JtYXRLaW5kKGQsIGwpOwogICAgICAgICAgICBjYXNlICdzJzoKICAgICAgICAgICAgICAgIHJldHVybiBmb3JtYXRQb3NpdGlvbihkLCBTVEFSVCwgbCk7CiAgICAgICAgICAgIGNhc2UgJ3QnOiB7CiAgICAgICAgICAgICAgICBib29sZWFuIHVzZVByZWZpeDsKICAgICAgICAgICAgICAgIHN3aXRjaCAoZC5nZXRUeXBlKCkpIHsKICAgICAgICAgICAgICAgIGNhc2UgRlJBR01FTlQ6CiAgICAgICAgICAgICAgICAgICAgdXNlUHJlZml4ID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIEVSUk9SOgogICAgICAgICAgICAgICAgICAgIHVzZVByZWZpeCA9IChkLmdldEludFBvc2l0aW9uKCkgPT0gUG9zaXRpb24uTk9QT1MpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICB1c2VQcmVmaXggPSB0cnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKHVzZVByZWZpeCkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZm9ybWF0S2luZChkLCBsKTsKICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICByZXR1cm4gIiI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY2FzZSAnbSc6CiAgICAgICAgICAgICAgICByZXR1cm4gZm9ybWF0TWVzc2FnZShkLCBsKTsKICAgICAgICAgICAgY2FzZSAnTCc6CiAgICAgICAgICAgICAgICByZXR1cm4gZm9ybWF0TGludENhdGVnb3J5KGQsIGwpOwogICAgICAgICAgICBjYXNlICdfJzoKICAgICAgICAgICAgICAgIHJldHVybiAiICI7CiAgICAgICAgICAgIGNhc2UgJyUnOgogICAgICAgICAgICAgICAgcmV0dXJuICIlIjsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIHJldHVybiBTdHJpbmcudmFsdWVPZihjKTsKICAgICAgICB9CiAgICB9CgogICAgcHJpdmF0ZSBTdHJpbmcgc2VsZWN0Rm9ybWF0KEpDRGlhZ25vc3RpYyBkKSB7CiAgICAgICAgRGlhZ25vc3RpY1NvdXJjZSBzb3VyY2UgPSBkLmdldERpYWdub3N0aWNTb3VyY2UoKTsKICAgICAgICBTdHJpbmcgZm9ybWF0ID0gZ2V0Q29uZmlndXJhdGlvbigpLmdldEZvcm1hdChCYXNpY0Zvcm1hdEtpbmQuREVGQVVMVF9OT19QT1NfRk9STUFUKTsKICAgICAgICBpZiAoc291cmNlICE9IG51bGwgJiYgc291cmNlICE9IERpYWdub3N0aWNTb3VyY2UuTk9fU09VUkNFKSB7CiAgICAgICAgICAgIGlmIChkLmdldEludFBvc2l0aW9uKCkgIT0gUG9zaXRpb24uTk9QT1MpIHsKICAgICAgICAgICAgICAgIGZvcm1hdCA9IGdldENvbmZpZ3VyYXRpb24oKS5nZXRGb3JtYXQoQmFzaWNGb3JtYXRLaW5kLkRFRkFVTFRfUE9TX0ZPUk1BVCk7CiAgICAgICAgICAgIH0gZWxzZSBpZiAoc291cmNlLmdldEZpbGUoKSAhPSBudWxsICYmCiAgICAgICAgICAgICAgICAgICAgICAgc291cmNlLmdldEZpbGUoKS5nZXRLaW5kKCkgPT0gSmF2YUZpbGVPYmplY3QuS2luZC5DTEFTUykgewogICAgICAgICAgICAgICAgZm9ybWF0ID0gZ2V0Q29uZmlndXJhdGlvbigpLmdldEZvcm1hdChCYXNpY0Zvcm1hdEtpbmQuREVGQVVMVF9DTEFTU19GT1JNQVQpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBmb3JtYXQ7CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgQmFzaWNDb25maWd1cmF0aW9uIGdldENvbmZpZ3VyYXRpb24oKSB7CiAgICAgICAgLy90aGUgZm9sbG93aW5nIGNhc3QgaXMgYWx3YXlzIHNhZmUgLSBzZWUgaW5pdAogICAgICAgIHJldHVybiAoQmFzaWNDb25maWd1cmF0aW9uKXN1cGVyLmdldENvbmZpZ3VyYXRpb24oKTsKICAgIH0KCiAgICBzdGF0aWMgcHVibGljIGNsYXNzIEJhc2ljQ29uZmlndXJhdGlvbiBleHRlbmRzIFNpbXBsZUNvbmZpZ3VyYXRpb24gewoKICAgICAgICBwcm90ZWN0ZWQgTWFwPERpYWdub3N0aWNQYXJ0LCBJbnRlZ2VyPiBpbmRlbnRhdGlvbkxldmVsczsKICAgICAgICBwcm90ZWN0ZWQgTWFwPEJhc2ljRm9ybWF0S2luZCwgU3RyaW5nPiBhdmFpbGFibGVGb3JtYXRzOwogICAgICAgIHByb3RlY3RlZCBTb3VyY2VQb3NpdGlvbiBzb3VyY2VQb3NpdGlvbjsKCiAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoImZhbGx0aHJvdWdoIikKICAgICAgICBwdWJsaWMgQmFzaWNDb25maWd1cmF0aW9uKE9wdGlvbnMgb3B0aW9ucykgewogICAgICAgICAgICBzdXBlcihvcHRpb25zLCBFbnVtU2V0Lm9mKERpYWdub3N0aWNQYXJ0LlNVTU1BUlksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBEaWFnbm9zdGljUGFydC5ERVRBSUxTLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgRGlhZ25vc3RpY1BhcnQuU1VCRElBR05PU1RJQ1MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBEaWFnbm9zdGljUGFydC5TT1VSQ0UpKTsKICAgICAgICAgICAgaW5pdEZvcm1hdCgpOwogICAgICAgICAgICBpbml0SW5kZW50YXRpb24oKTsKICAgICAgICAgICAgaWYgKG9wdGlvbnMuaXNTZXQoImRpYWdzLmxlZ2FjeSIpKQogICAgICAgICAgICAgICAgaW5pdE9sZEZvcm1hdCgpOwogICAgICAgICAgICBTdHJpbmcgZm10ID0gb3B0aW9ucy5nZXQoImRpYWdzLmxheW91dCIpOwogICAgICAgICAgICBpZiAoZm10ICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIGlmIChmbXQuZXF1YWxzKCJPTEQiKSkKICAgICAgICAgICAgICAgICAgICBpbml0T2xkRm9ybWF0KCk7CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgaW5pdEZvcm1hdHMoZm10KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBTdHJpbmcgc3JjUG9zID0gbnVsbDsKICAgICAgICAgICAgaWYgKCgoKHNyY1BvcyA9IG9wdGlvbnMuZ2V0KCJkaWFncy5zb3VyY2VQb3NpdGlvbiIpKSAhPSBudWxsKSkgJiYKICAgICAgICAgICAgICAgICAgICBzcmNQb3MuZXF1YWxzKCJib3R0b20iKSkKICAgICAgICAgICAgICAgICAgICBzZXRTb3VyY2VQb3NpdGlvbihTb3VyY2VQb3NpdGlvbi5CT1RUT00pOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBzZXRTb3VyY2VQb3NpdGlvbihTb3VyY2VQb3NpdGlvbi5BRlRFUl9TVU1NQVJZKTsKICAgICAgICAgICAgU3RyaW5nIGluZGVudCA9IG9wdGlvbnMuZ2V0KCJkaWFncy5pbmRlbnQiKTsKICAgICAgICAgICAgaWYgKGluZGVudCAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICBTdHJpbmdbXSBsZXZlbHMgPSBpbmRlbnQuc3BsaXQoIlxcfCIpOwogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKGxldmVscy5sZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSA1OgogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0SW5kZW50YXRpb24oRGlhZ25vc3RpY1BhcnQuSkxTLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbnRlZ2VyLnBhcnNlSW50KGxldmVsc1s0XSkpOwogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDQ6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRJbmRlbnRhdGlvbihEaWFnbm9zdGljUGFydC5TVUJESUFHTk9TVElDUywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW50ZWdlci5wYXJzZUludChsZXZlbHNbM10pKTsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAzOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0SW5kZW50YXRpb24oRGlhZ25vc3RpY1BhcnQuU09VUkNFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbnRlZ2VyLnBhcnNlSW50KGxldmVsc1syXSkpOwogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDI6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRJbmRlbnRhdGlvbihEaWFnbm9zdGljUGFydC5ERVRBSUxTLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbnRlZ2VyLnBhcnNlSW50KGxldmVsc1sxXSkpOwogICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0SW5kZW50YXRpb24oRGlhZ25vc3RpY1BhcnQuU1VNTUFSWSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW50ZWdlci5wYXJzZUludChsZXZlbHNbMF0pKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGV4KSB7CiAgICAgICAgICAgICAgICAgICAgaW5pdEluZGVudGF0aW9uKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHB1YmxpYyBCYXNpY0NvbmZpZ3VyYXRpb24oKSB7CiAgICAgICAgICAgIHN1cGVyKEVudW1TZXQub2YoRGlhZ25vc3RpY1BhcnQuU1VNTUFSWSwKICAgICAgICAgICAgICAgICAgRGlhZ25vc3RpY1BhcnQuREVUQUlMUywKICAgICAgICAgICAgICAgICAgRGlhZ25vc3RpY1BhcnQuU1VCRElBR05PU1RJQ1MsCiAgICAgICAgICAgICAgICAgIERpYWdub3N0aWNQYXJ0LlNPVVJDRSkpOwogICAgICAgICAgICBpbml0Rm9ybWF0KCk7CiAgICAgICAgICAgIGluaXRJbmRlbnRhdGlvbigpOwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSB2b2lkIGluaXRGb3JtYXQoKSB7CiAgICAgICAgICAgIGluaXRGb3JtYXRzKCIlZjolbDolXyVwJUwlbSIsICIlcCVMJW0iLCAiJWY6JV8lcCVMJW0iKTsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgdm9pZCBpbml0T2xkRm9ybWF0KCkgewogICAgICAgICAgICBpbml0Rm9ybWF0cygiJWY6JWw6JV8ldCVMJW0iLCAiJXAlTCVtIiwgIiVmOiVfJXQlTCVtIik7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIHZvaWQgaW5pdEZvcm1hdHMoU3RyaW5nIHBvcywgU3RyaW5nIG5vcG9zLCBTdHJpbmcgY2xhenopIHsKICAgICAgICAgICAgYXZhaWxhYmxlRm9ybWF0cyA9IG5ldyBFbnVtTWFwPD4oQmFzaWNGb3JtYXRLaW5kLmNsYXNzKTsKICAgICAgICAgICAgc2V0Rm9ybWF0KEJhc2ljRm9ybWF0S2luZC5ERUZBVUxUX1BPU19GT1JNQVQsICAgIHBvcyk7CiAgICAgICAgICAgIHNldEZvcm1hdChCYXNpY0Zvcm1hdEtpbmQuREVGQVVMVF9OT19QT1NfRk9STUFULCBub3Bvcyk7CiAgICAgICAgICAgIHNldEZvcm1hdChCYXNpY0Zvcm1hdEtpbmQuREVGQVVMVF9DTEFTU19GT1JNQVQsICBjbGF6eik7CiAgICAgICAgfQoKICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygiZmFsbHRocm91Z2giKQogICAgICAgIHByaXZhdGUgdm9pZCBpbml0Rm9ybWF0cyhTdHJpbmcgZm10KSB7CiAgICAgICAgICAgIFN0cmluZ1tdIGZvcm1hdHMgPSBmbXQuc3BsaXQoIlxcfCIpOwogICAgICAgICAgICBzd2l0Y2ggKGZvcm1hdHMubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICBjYXNlIDM6CiAgICAgICAgICAgICAgICAgICAgc2V0Rm9ybWF0KEJhc2ljRm9ybWF0S2luZC5ERUZBVUxUX0NMQVNTX0ZPUk1BVCwgZm9ybWF0c1syXSk7CiAgICAgICAgICAgICAgICBjYXNlIDI6CiAgICAgICAgICAgICAgICAgICAgc2V0Rm9ybWF0KEJhc2ljRm9ybWF0S2luZC5ERUZBVUxUX05PX1BPU19GT1JNQVQsIGZvcm1hdHNbMV0pOwogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICBzZXRGb3JtYXQoQmFzaWNGb3JtYXRLaW5kLkRFRkFVTFRfUE9TX0ZPUk1BVCwgZm9ybWF0c1swXSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHByaXZhdGUgdm9pZCBpbml0SW5kZW50YXRpb24oKSB7CiAgICAgICAgICAgIGluZGVudGF0aW9uTGV2ZWxzID0gbmV3IEhhc2hNYXA8PigpOwogICAgICAgICAgICBzZXRJbmRlbnRhdGlvbihEaWFnbm9zdGljUGFydC5TVU1NQVJZLCAwKTsKICAgICAgICAgICAgc2V0SW5kZW50YXRpb24oRGlhZ25vc3RpY1BhcnQuREVUQUlMUywgRGV0YWlsc0luYyk7CiAgICAgICAgICAgIHNldEluZGVudGF0aW9uKERpYWdub3N0aWNQYXJ0LlNVQkRJQUdOT1NUSUNTLCBEaWFnSW5jKTsKICAgICAgICAgICAgc2V0SW5kZW50YXRpb24oRGlhZ25vc3RpY1BhcnQuU09VUkNFLCAwKTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIEdldCB0aGUgYW1vdW50IG9mIHNwYWNlcyBmb3IgYSBnaXZlbiBpbmRlbnRhdGlvbiBraW5kCiAgICAgICAgICogQHBhcmFtIGRpYWdQYXJ0IHRoZSBkaWFnbm9zdGljIHBhcnQgZm9yIHdoaWNoIHRoZSBpbmRlbnRhdGlvbiBpcwogICAgICAgICAqIHRvIGJlIHJldHJpZXZlZAogICAgICAgICAqIEByZXR1cm4gdGhlIGFtb3VudCBvZiBzcGFjZXMgdXNlZCBmb3IgdGhlIHNwZWNpZmllZCBpbmRlbnRhdGlvbiBraW5kCiAgICAgICAgICovCiAgICAgICAgcHVibGljIGludCBnZXRJbmRlbnRhdGlvbihEaWFnbm9zdGljUGFydCBkaWFnUGFydCkgewogICAgICAgICAgICByZXR1cm4gaW5kZW50YXRpb25MZXZlbHMuZ2V0KGRpYWdQYXJ0KTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIFNldCB0aGUgaW5kZW50YXRpb24gbGV2ZWwgZm9yIHZhcmlvdXMgZWxlbWVudCBvZiBhIGdpdmVuIGRpYWdub3N0aWMgLQogICAgICAgICAqIHRoaXMgbWlnaHQgbGVhZCB0byBtb3JlIHJlYWRhYmxlIGRpYWdub3N0aWNzCiAgICAgICAgICoKICAgICAgICAgKiBAcGFyYW0gZGlhZ1BhcnQKICAgICAgICAgKiBAcGFyYW0gblNwYWNlcyBhbW91bnQgb2Ygc3BhY2VzIGZvciB0aGUgc3BlY2lmaWVkIGRpYWdub3N0aWMgcGFydAogICAgICAgICAqLwogICAgICAgIHB1YmxpYyB2b2lkIHNldEluZGVudGF0aW9uKERpYWdub3N0aWNQYXJ0IGRpYWdQYXJ0LCBpbnQgblNwYWNlcykgewogICAgICAgICAgICBpbmRlbnRhdGlvbkxldmVscy5wdXQoZGlhZ1BhcnQsIG5TcGFjZXMpOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogU2V0IHRoZSBzb3VyY2UgbGluZSBwb3NpdGlvbmluZyB1c2VkIGJ5IHRoaXMgZm9ybWF0dGVyCiAgICAgICAgICoKICAgICAgICAgKiBAcGFyYW0gc291cmNlUG9zIGEgcG9zaXRpb25pbmcgdmFsdWUgZm9yIHNvdXJjZSBsaW5lCiAgICAgICAgICovCiAgICAgICAgcHVibGljIHZvaWQgc2V0U291cmNlUG9zaXRpb24oU291cmNlUG9zaXRpb24gc291cmNlUG9zKSB7CiAgICAgICAgICAgIHNvdXJjZVBvc2l0aW9uID0gc291cmNlUG9zOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogR2V0IHRoZSBzb3VyY2UgbGluZSBwb3NpdGlvbmluZyB1c2VkIGJ5IHRoaXMgZm9ybWF0dGVyCiAgICAgICAgICoKICAgICAgICAgKiBAcmV0dXJuIHRoZSBwb3NpdGlvbmluZyB2YWx1ZSB1c2VkIGJ5IHRoaXMgZm9ybWF0dGVyCiAgICAgICAgICovCiAgICAgICAgcHVibGljIFNvdXJjZVBvc2l0aW9uIGdldFNvdXJjZVBvc2l0aW9uKCkgewogICAgICAgICAgICByZXR1cm4gc291cmNlUG9zaXRpb247CiAgICAgICAgfQogICAgICAgIC8vd2hlcmUKICAgICAgICAvKioKICAgICAgICAgKiBBIHNvdXJjZSBwb3NpdGlvbmluZyB2YWx1ZSBjb250cm9scyB0aGUgcG9zaXRpb24gKHdpdGhpbiBhIGdpdmVuCiAgICAgICAgICogZGlhZ25vc3RpYyBtZXNzYWdlKSBpbiB3aGljaCB0aGUgc291cmNlIGxpbmUgdGhlIGRpYWdub3N0aWMgcmVmZXJzIHRvCiAgICAgICAgICogc2hvdWxkIGJlIGRpc3BsYXllZCAoaWYgYXBwbGljYWJsZSkKICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgZW51bSBTb3VyY2VQb3NpdGlvbiB7CiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBTb3VyY2UgbGluZSBpcyBkaXNwbGF5ZWQgYWZ0ZXIgdGhlIGRpYWdub3N0aWMgbWVzc2FnZQogICAgICAgICAgICAgKi8KICAgICAgICAgICAgQk9UVE9NLAogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogU291cmNlIGxpbmUgaXMgZGlzcGxheWVkIGFmdGVyIHRoZSBmaXJzdCBsaW5lIG9mIHRoZSBkaWFnbm9zdGljCiAgICAgICAgICAgICAqIG1lc3NhZ2UKICAgICAgICAgICAgICovCiAgICAgICAgICAgIEFGVEVSX1NVTU1BUlkKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIFNldCBhIG1ldGFjaGFyIHN0cmluZyBmb3IgYSBzcGVjaWZpYyBmb3JtYXQKICAgICAgICAgKgogICAgICAgICAqIEBwYXJhbSBraW5kIHRoZSBmb3JtYXQga2luZCB0byBiZSBzZXQKICAgICAgICAgKiBAcGFyYW0gcyB0aGUgbWV0YWNoYXIgc3RyaW5nIHNwZWNpZnlpbmcgdGhlIGZvcm1hdAogICAgICAgICAqLwogICAgICAgIHB1YmxpYyB2b2lkIHNldEZvcm1hdChCYXNpY0Zvcm1hdEtpbmQga2luZCwgU3RyaW5nIHMpIHsKICAgICAgICAgICAgYXZhaWxhYmxlRm9ybWF0cy5wdXQoa2luZCwgcyk7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBHZXQgYSBtZXRhY2hhciBzdHJpbmcgZm9yIGEgc3BlY2lmaWMgZm9ybWF0CiAgICAgICAgICoKICAgICAgICAgKiBAcGFyYW0ga2luZCB0aGUgZm9ybWF0IGtpbmQgZm9yIHdoaWNoIHRvIGdldCB0aGUgbWV0YWNoYXIgc3RyaW5nCiAgICAgICAgICovCiAgICAgICAgcHVibGljIFN0cmluZyBnZXRGb3JtYXQoQmFzaWNGb3JtYXRLaW5kIGtpbmQpIHsKICAgICAgICAgICAgcmV0dXJuIGF2YWlsYWJsZUZvcm1hdHMuZ2V0KGtpbmQpOwogICAgICAgIH0KICAgICAgICAvL3doZXJlCiAgICAgICAgLyoqCiAgICAgICAgICogVGhpcyBlbnVtIGNvbnRhaW5zIGFsbCB0aGUga2luZHMgb2YgZm9ybWF0dGluZyBwYXR0ZXJucyBzdXBwb3J0ZWQKICAgICAgICAgKiBieSBhIGJhc2ljIGRpYWdub3N0aWMgZm9ybWF0dGVyLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBlbnVtIEJhc2ljRm9ybWF0S2luZCB7CiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAqIEEgZm9ybWF0IHN0cmluZyB0byBiZSB1c2VkIGZvciBkaWFnbm9zdGljcyB3aXRoIGEgZ2l2ZW4gcG9zaXRpb24uCiAgICAgICAgICAgICovCiAgICAgICAgICAgIERFRkFVTFRfUE9TX0ZPUk1BVCwKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICogQSBmb3JtYXQgc3RyaW5nIHRvIGJlIHVzZWQgZm9yIGRpYWdub3N0aWNzIHdpdGhvdXQgYSBnaXZlbiBwb3NpdGlvbi4KICAgICAgICAgICAgKi8KICAgICAgICAgICAgREVGQVVMVF9OT19QT1NfRk9STUFULAogICAgICAgICAgICAvKioKICAgICAgICAgICAgKiBBIGZvcm1hdCBzdHJpbmcgdG8gYmUgdXNlZCBmb3IgZGlhZ25vc3RpY3MgcmVnYXJkaW5nIGNsYXNzZmlsZXMKICAgICAgICAgICAgKi8KICAgICAgICAgICAgREVGQVVMVF9DTEFTU19GT1JNQVQKICAgICAgICB9CiAgICB9Cn0KUEsDBAoAAAgAAAY7qUp/w8FqlxYAAJcWAAA0AAAAY29tL3N1bi90b29scy9qYXZhYy91dGlsL1Jhd0RpYWdub3N0aWNGb3JtYXR0ZXIuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwOCwgMjAxNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWw7CgppbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb247CmltcG9ydCBqYXZhLnV0aWwuRW51bVNldDsKaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CmltcG9ydCBqYXZheC50b29scy5KYXZhRmlsZU9iamVjdDsKCmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmFwaS5EaWFnbm9zdGljRm9ybWF0dGVyLkNvbmZpZ3VyYXRpb24uKjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuYXBpLkZvcm1hdHRhYmxlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5maWxlLlBhdGhGaWxlT2JqZWN0OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkpDVHJlZS4qOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkFic3RyYWN0RGlhZ25vc3RpY0Zvcm1hdHRlci5TaW1wbGVDb25maWd1cmF0aW9uOwoKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmFwaS5EaWFnbm9zdGljRm9ybWF0dGVyLlBvc2l0aW9uS2luZC4qOwoKLyoqCiAqIEEgcmF3IGZvcm1hdHRlciBmb3IgZGlhZ25vc3RpYyBtZXNzYWdlcy4KICogVGhlIHJhdyBmb3JtYXR0ZXIgd2lsbCBmb3JtYXQgYSBkaWFnbm9zdGljIGFjY29yZGluZyB0byBvbmUgb2YgdHdvIGZvcm1hdCBwYXR0ZXJucywgZGVwZW5kaW5nIG9uIHdoZXRoZXIKICogb3Igbm90IHRoZSBzb3VyY2UgbmFtZSBhbmQgcG9zaXRpb24gYXJlIHNldC4gVGhpcyBmb3JtYXR0ZXIgcHJvdmlkZXMgYSBzdGFuZGFyZGl6ZWQsIGxvY2FsaXplLWluZGVwZW5kZW50CiAqIGltcGxlbWVudGF0aW9uIG9mIGEgZGlhZ25vc3RpYyBmb3JtYXR0ZXI7IGFzIHN1Y2gsIHRoaXMgZm9ybWF0dGVyIGlzIGJlc3Qgc3VpdGVkIGZvciB0ZXN0aW5nIHB1cnBvc2VzLgogKgogKiA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yCiAqIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj4KICovCnB1YmxpYyBmaW5hbCBjbGFzcyBSYXdEaWFnbm9zdGljRm9ybWF0dGVyIGV4dGVuZHMgQWJzdHJhY3REaWFnbm9zdGljRm9ybWF0dGVyIHsKCiAgICAvKioKICAgICAqIENyZWF0ZSBhIGZvcm1hdHRlciBiYXNlZCBvbiB0aGUgc3VwcGxpZWQgb3B0aW9ucy4KICAgICAqIEBwYXJhbSBvcHRpb25zCiAgICAgKi8KICAgIHB1YmxpYyBSYXdEaWFnbm9zdGljRm9ybWF0dGVyKE9wdGlvbnMgb3B0aW9ucykgewogICAgICAgIHN1cGVyKG51bGwsIG5ldyBTaW1wbGVDb25maWd1cmF0aW9uKG9wdGlvbnMsCiAgICAgICAgICAgICAgICBFbnVtU2V0Lm9mKERpYWdub3N0aWNQYXJ0LlNVTU1BUlksCiAgICAgICAgICAgICAgICAgICAgICAgIERpYWdub3N0aWNQYXJ0LkRFVEFJTFMsCiAgICAgICAgICAgICAgICAgICAgICAgIERpYWdub3N0aWNQYXJ0LlNVQkRJQUdOT1NUSUNTKSkpOwogICAgfQoKICAgIC8vcHJvdmlkZSBjb21tb24gZGVmYXVsdCBmb3JtYXRzCiAgICBwdWJsaWMgU3RyaW5nIGZvcm1hdERpYWdub3N0aWMoSkNEaWFnbm9zdGljIGQsIExvY2FsZSBsKSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgU3RyaW5nQnVpbGRlciBidWYgPSBuZXcgU3RyaW5nQnVpbGRlcigpOwogICAgICAgICAgICBpZiAoZC5nZXRQb3NpdGlvbigpICE9IFBvc2l0aW9uLk5PUE9TKSB7CiAgICAgICAgICAgICAgICBidWYuYXBwZW5kKGZvcm1hdFNvdXJjZShkLCBmYWxzZSwgbnVsbCkpOwogICAgICAgICAgICAgICAgYnVmLmFwcGVuZCgnOicpOwogICAgICAgICAgICAgICAgYnVmLmFwcGVuZChmb3JtYXRQb3NpdGlvbihkLCBMSU5FLCBudWxsKSk7CiAgICAgICAgICAgICAgICBidWYuYXBwZW5kKCc6Jyk7CiAgICAgICAgICAgICAgICBidWYuYXBwZW5kKGZvcm1hdFBvc2l0aW9uKGQsIENPTFVNTiwgbnVsbCkpOwogICAgICAgICAgICAgICAgYnVmLmFwcGVuZCgnOicpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKGQuZ2V0U291cmNlKCkgIT0gbnVsbCAmJiBkLmdldFNvdXJjZSgpLmdldEtpbmQoKSA9PSBKYXZhRmlsZU9iamVjdC5LaW5kLkNMQVNTKSB7CiAgICAgICAgICAgICAgICBidWYuYXBwZW5kKGZvcm1hdFNvdXJjZShkLCBmYWxzZSwgbnVsbCkpOwogICAgICAgICAgICAgICAgYnVmLmFwcGVuZCgiOi06LToiKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBidWYuYXBwZW5kKCctJyk7CiAgICAgICAgICAgIGJ1Zi5hcHBlbmQoJyAnKTsKICAgICAgICAgICAgYnVmLmFwcGVuZChmb3JtYXRNZXNzYWdlKGQsIG51bGwpKTsKICAgICAgICAgICAgaWYgKGRpc3BsYXlTb3VyY2UoZCkpIHsKICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQoIlxuIik7CiAgICAgICAgICAgICAgICBidWYuYXBwZW5kKGZvcm1hdFNvdXJjZUxpbmUoZCwgMCkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBidWYudG9TdHJpbmcoKTsKICAgICAgICB9CiAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIC8vZS5wcmludFN0YWNrVHJhY2UoKTsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBTdHJpbmcgZm9ybWF0TWVzc2FnZShKQ0RpYWdub3N0aWMgZCwgTG9jYWxlIGwpIHsKICAgICAgICBTdHJpbmdCdWlsZGVyIGJ1ZiA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CiAgICAgICAgQ29sbGVjdGlvbjxTdHJpbmc+IGFyZ3MgPSBmb3JtYXRBcmd1bWVudHMoZCwgbCk7CiAgICAgICAgYnVmLmFwcGVuZChsb2NhbGl6ZShudWxsLCBkLmdldENvZGUoKSwgYXJncy50b0FycmF5KCkpKTsKICAgICAgICBpZiAoZC5pc011bHRpbGluZSgpICYmIGdldENvbmZpZ3VyYXRpb24oKS5nZXRWaXNpYmxlKCkuY29udGFpbnMoRGlhZ25vc3RpY1BhcnQuU1VCRElBR05PU1RJQ1MpKSB7CiAgICAgICAgICAgIExpc3Q8U3RyaW5nPiBzdWJEaWFncyA9IGZvcm1hdFN1YmRpYWdub3N0aWNzKGQsIG51bGwpOwogICAgICAgICAgICBpZiAoc3ViRGlhZ3Mubm9uRW1wdHkoKSkgewogICAgICAgICAgICAgICAgU3RyaW5nIHNlcCA9ICIiOwogICAgICAgICAgICAgICAgYnVmLmFwcGVuZCgiLHsiKTsKICAgICAgICAgICAgICAgIGZvciAoU3RyaW5nIHN1YiA6IGZvcm1hdFN1YmRpYWdub3N0aWNzKGQsIG51bGwpKSB7CiAgICAgICAgICAgICAgICAgICAgYnVmLmFwcGVuZChzZXApOwogICAgICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQoIigiKTsKICAgICAgICAgICAgICAgICAgICBidWYuYXBwZW5kKHN1Yik7CiAgICAgICAgICAgICAgICAgICAgYnVmLmFwcGVuZCgiKSIpOwogICAgICAgICAgICAgICAgICAgIHNlcCA9ICIsIjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQoJ30nKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVmLnRvU3RyaW5nKCk7CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgU3RyaW5nIGZvcm1hdEFyZ3VtZW50KEpDRGlhZ25vc3RpYyBkaWFnLCBPYmplY3QgYXJnLCBMb2NhbGUgbCkgewogICAgICAgIFN0cmluZyBzOwogICAgICAgIGlmIChhcmcgaW5zdGFuY2VvZiBGb3JtYXR0YWJsZSkgewogICAgICAgICAgICBzID0gYXJnLnRvU3RyaW5nKCk7CiAgICAgICAgfSBlbHNlIGlmIChhcmcgaW5zdGFuY2VvZiBKQ0V4cHJlc3Npb24pIHsKICAgICAgICAgICAgSkNFeHByZXNzaW9uIHRyZWUgPSAoSkNFeHByZXNzaW9uKWFyZzsKICAgICAgICAgICAgcyA9ICJAIiArIHRyZWUuZ2V0U3RhcnRQb3NpdGlvbigpOwogICAgICAgIH0gZWxzZSBpZiAoYXJnIGluc3RhbmNlb2YgUGF0aEZpbGVPYmplY3QpIHsKICAgICAgICAgICAgcyA9ICgoUGF0aEZpbGVPYmplY3QpIGFyZykuZ2V0U2hvcnROYW1lKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcyA9IHN1cGVyLmZvcm1hdEFyZ3VtZW50KGRpYWcsIGFyZywgbnVsbCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiAoYXJnIGluc3RhbmNlb2YgSkNEaWFnbm9zdGljKSA/ICIoIiArIHMgKyAiKSIgOiBzOwogICAgfQoKICAgIEBPdmVycmlkZQogICAgcHJvdGVjdGVkIFN0cmluZyBsb2NhbGl6ZShMb2NhbGUgbCwgU3RyaW5nIGtleSwgT2JqZWN0Li4uIGFyZ3MpIHsKICAgICAgICBTdHJpbmdCdWlsZGVyIGJ1ZiA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CiAgICAgICAgYnVmLmFwcGVuZChrZXkpOwogICAgICAgIFN0cmluZyBzZXAgPSAiOiAiOwogICAgICAgIGZvciAoT2JqZWN0IG8gOiBhcmdzKSB7CiAgICAgICAgICAgIGJ1Zi5hcHBlbmQoc2VwKTsKICAgICAgICAgICAgYnVmLmFwcGVuZChvKTsKICAgICAgICAgICAgc2VwID0gIiwgIjsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1Zi50b1N0cmluZygpOwogICAgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaXNSYXcoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9Cn0KUEsDBAoAAAgAAAY7qUp6h3MHsW8AALFvAAAhAAAAY29tL3N1bi90b29scy9qYXZhYy91dGlsL0xvZy5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAxOTk5LCAyMDE2LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuamF2YWMudXRpbDsKCmltcG9ydCBqYXZhLmlvLio7CmltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOwppbXBvcnQgamF2YS51dGlsLkVudW1NYXA7CmltcG9ydCBqYXZhLnV0aWwuRW51bVNldDsKaW1wb3J0IGphdmEudXRpbC5IYXNoU2V0OwppbXBvcnQgamF2YS51dGlsLk1hcDsKaW1wb3J0IGphdmEudXRpbC5RdWV1ZTsKaW1wb3J0IGphdmEudXRpbC5TZXQ7CgppbXBvcnQgamF2YXgudG9vbHMuRGlhZ25vc3RpY0xpc3RlbmVyOwppbXBvcnQgamF2YXgudG9vbHMuSmF2YUZpbGVPYmplY3Q7CgppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5hcGkuRGlhZ25vc3RpY0Zvcm1hdHRlcjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMubWFpbi5NYWluOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5tYWluLk9wdGlvbjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5FbmRQb3NUYWJsZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5KQ0RpYWdub3N0aWMuRGlhZ25vc3RpY0ZsYWc7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuSkNEaWFnbm9zdGljLkRpYWdub3N0aWNQb3NpdGlvbjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5KQ0RpYWdub3N0aWMuRGlhZ25vc3RpY1R5cGU7CgppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMubWFpbi5PcHRpb24uKjsKCi8qKiBBIGNsYXNzIGZvciBlcnJvciBsb2dzLiBSZXBvcnRzIGVycm9ycyBhbmQgd2FybmluZ3MsIGFuZAogKiAga2VlcHMgdHJhY2sgb2YgZXJyb3IgbnVtYmVycyBhbmQgcG9zaXRpb25zLgogKgogKiAgPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24gcmlzay4KICogIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yCiAqICBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+CiAqLwpwdWJsaWMgY2xhc3MgTG9nIGV4dGVuZHMgQWJzdHJhY3RMb2cgewogICAgLyoqIFRoZSBjb250ZXh0IGtleSBmb3IgdGhlIGxvZy4gKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQ29udGV4dC5LZXk8TG9nPiBsb2dLZXkgPSBuZXcgQ29udGV4dC5LZXk8PigpOwoKICAgIC8qKiBUaGUgY29udGV4dCBrZXkgZm9yIHRoZSBzdGFuZGFyZCBvdXRwdXQgUHJpbnRXcml0ZXIuICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIENvbnRleHQuS2V5PFByaW50V3JpdGVyPiBvdXRLZXkgPSBuZXcgQ29udGV4dC5LZXk8PigpOwoKICAgIC8qKiBUaGUgY29udGV4dCBrZXkgZm9yIHRoZSBkaWFnbm9zdGljIFByaW50V3JpdGVyLiAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBDb250ZXh0LktleTxQcmludFdyaXRlcj4gZXJyS2V5ID0gbmV3IENvbnRleHQuS2V5PD4oKTsKCiAgICAvKiBUT0RPOiBTaG91bGQgdW5pZnkgdGhpcyB3aXRoIHByZWZpeCBoYW5kbGluZyBpbiBKQ0RpYWdub3N0aWMuRmFjdG9yeS4gKi8KICAgIHB1YmxpYyBlbnVtIFByZWZpeEtpbmQgewogICAgICAgIEpBVkFDKCJqYXZhYy4iKSwKICAgICAgICBDT01QSUxFUl9NSVNDKCJjb21waWxlci5taXNjLiIpOwogICAgICAgIFByZWZpeEtpbmQoU3RyaW5nIHYpIHsKICAgICAgICAgICAgdmFsdWUgPSB2OwogICAgICAgIH0KICAgICAgICBwdWJsaWMgU3RyaW5nIGtleShTdHJpbmcgaykgewogICAgICAgICAgICByZXR1cm4gdmFsdWUgKyBrOwogICAgICAgIH0KICAgICAgICBmaW5hbCBTdHJpbmcgdmFsdWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBEaWFnbm9zdGljSGFuZGxlcidzIHByb3ZpZGUgdGhlIGluaXRpYWwgaGFuZGxpbmcgZm9yIGRpYWdub3N0aWNzLgogICAgICogV2hlbiBhIGRpYWdub3N0aWMgaGFuZGxlciBpcyBjcmVhdGVkIGFuZCBoYXMgYmVlbiBpbml0aWFsaXplZCwgaXQKICAgICAqIHNob3VsZCBpbnN0YWxsIGl0c2VsZiBhcyB0aGUgY3VycmVudCBkaWFnbm9zdGljIGhhbmRsZXIuIFdoZW4gYQogICAgICogY2xpZW50IGhhcyBmaW5pc2hlZCB1c2luZyBhIGhhbmRsZXIsIHRoZSBjbGllbnQgc2hvdWxkIGNhbGwKICAgICAqIHtAY29kZSBsb2cucmVtb3ZlRGlhZ25vc3RpY0hhbmRsZXIoKTt9CiAgICAgKgogICAgICogTm90ZSB0aGF0IGphdmF4LnRvb2xzLkRpYWdub3N0aWNMaXN0ZW5lciAoaWYgc2V0KSBpcyBjYWxsZWQgbGF0ZXIgaW4gdGhlCiAgICAgKiBkaWFnbm9zdGljIHBpcGVsaW5lLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGFic3RyYWN0IGNsYXNzIERpYWdub3N0aWNIYW5kbGVyIHsKICAgICAgICAvKioKICAgICAgICAgKiBUaGUgcHJldmlvdXNseSBpbnN0YWxsZWQgZGlhZ25vc3RpYyBoYW5kbGVyLgogICAgICAgICAqLwogICAgICAgIHByb3RlY3RlZCBEaWFnbm9zdGljSGFuZGxlciBwcmV2OwoKICAgICAgICAvKioKICAgICAgICAgKiBJbnN0YWxsIHRoaXMgZGlhZ25vc3RpYyBoYW5kbGVyIGFzIHRoZSBjdXJyZW50IG9uZSwKICAgICAgICAgKiByZWNvcmRpbmcgdGhlIHByZXZpb3VzIG9uZS4KICAgICAgICAgKi8KICAgICAgICBwcm90ZWN0ZWQgdm9pZCBpbnN0YWxsKExvZyBsb2cpIHsKICAgICAgICAgICAgcHJldiA9IGxvZy5kaWFnbm9zdGljSGFuZGxlcjsKICAgICAgICAgICAgbG9nLmRpYWdub3N0aWNIYW5kbGVyID0gdGhpczsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIEhhbmRsZSBhIGRpYWdub3N0aWMuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIGFic3RyYWN0IHZvaWQgcmVwb3J0KEpDRGlhZ25vc3RpYyBkaWFnKTsKICAgIH0KCiAgICAvKioKICAgICAqIEEgRGlhZ25vc3RpY0hhbmRsZXIgdGhhdCBkaXNjYXJkcyBhbGwgZGlhZ25vc3RpY3MuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgRGlzY2FyZERpYWdub3N0aWNIYW5kbGVyIGV4dGVuZHMgRGlhZ25vc3RpY0hhbmRsZXIgewogICAgICAgIHB1YmxpYyBEaXNjYXJkRGlhZ25vc3RpY0hhbmRsZXIoTG9nIGxvZykgewogICAgICAgICAgICBpbnN0YWxsKGxvZyk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCByZXBvcnQoSkNEaWFnbm9zdGljIGRpYWcpIHsgfQogICAgfQoKICAgIC8qKgogICAgICogQSBEaWFnbm9zdGljSGFuZGxlciB0aGF0IGNhbiBkZWZlciBzb21lIG9yIGFsbCBkaWFnbm9zdGljcywKICAgICAqIGJ5IGJ1ZmZlcmluZyB0aGVtIGZvciBsYXRlciBleGFtaW5hdGlvbiBhbmQvb3IgcmVwb3J0aW5nLgogICAgICogSWYgYSBkaWFnbm9zdGljIGlzIG5vdCBkZWZlcnJlZCwgb3IgaXMgc3Vic2VxdWVudGx5IHJlcG9ydGVkCiAgICAgKiB3aXRoIHJlcG9ydEFsbERpYWdub3N0aWNzKCksIGl0IHdpbGwgYmUgcmVwb3J0ZWQgdG8gdGhlIHByZXZpb3VzbHkKICAgICAqIGFjdGl2ZSBkaWFnbm9zdGljIGhhbmRsZXIuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgRGVmZXJyZWREaWFnbm9zdGljSGFuZGxlciBleHRlbmRzIERpYWdub3N0aWNIYW5kbGVyIHsKICAgICAgICBwcml2YXRlIFF1ZXVlPEpDRGlhZ25vc3RpYz4gZGVmZXJyZWQgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgcHJpdmF0ZSBmaW5hbCBGaWx0ZXI8SkNEaWFnbm9zdGljPiBmaWx0ZXI7CgogICAgICAgIHB1YmxpYyBEZWZlcnJlZERpYWdub3N0aWNIYW5kbGVyKExvZyBsb2cpIHsKICAgICAgICAgICAgdGhpcyhsb2csIG51bGwpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIERlZmVycmVkRGlhZ25vc3RpY0hhbmRsZXIoTG9nIGxvZywgRmlsdGVyPEpDRGlhZ25vc3RpYz4gZmlsdGVyKSB7CiAgICAgICAgICAgIHRoaXMuZmlsdGVyID0gZmlsdGVyOwogICAgICAgICAgICBpbnN0YWxsKGxvZyk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCByZXBvcnQoSkNEaWFnbm9zdGljIGRpYWcpIHsKICAgICAgICAgICAgaWYgKCFkaWFnLmlzRmxhZ1NldChKQ0RpYWdub3N0aWMuRGlhZ25vc3RpY0ZsYWcuTk9OX0RFRkVSUkFCTEUpICYmCiAgICAgICAgICAgICAgICAoZmlsdGVyID09IG51bGwgfHwgZmlsdGVyLmFjY2VwdHMoZGlhZykpKSB7CiAgICAgICAgICAgICAgICBkZWZlcnJlZC5hZGQoZGlhZyk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBwcmV2LnJlcG9ydChkaWFnKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHVibGljIFF1ZXVlPEpDRGlhZ25vc3RpYz4gZ2V0RGlhZ25vc3RpY3MoKSB7CiAgICAgICAgICAgIHJldHVybiBkZWZlcnJlZDsKICAgICAgICB9CgogICAgICAgIC8qKiBSZXBvcnQgYWxsIGRlZmVycmVkIGRpYWdub3N0aWNzLiAqLwogICAgICAgIHB1YmxpYyB2b2lkIHJlcG9ydERlZmVycmVkRGlhZ25vc3RpY3MoKSB7CiAgICAgICAgICAgIHJlcG9ydERlZmVycmVkRGlhZ25vc3RpY3MoRW51bVNldC5hbGxPZihKQ0RpYWdub3N0aWMuS2luZC5jbGFzcykpOwogICAgICAgIH0KCiAgICAgICAgLyoqIFJlcG9ydCBzZWxlY3RlZCBkZWZlcnJlZCBkaWFnbm9zdGljcy4gKi8KICAgICAgICBwdWJsaWMgdm9pZCByZXBvcnREZWZlcnJlZERpYWdub3N0aWNzKFNldDxKQ0RpYWdub3N0aWMuS2luZD4ga2luZHMpIHsKICAgICAgICAgICAgSkNEaWFnbm9zdGljIGQ7CiAgICAgICAgICAgIHdoaWxlICgoZCA9IGRlZmVycmVkLnBvbGwoKSkgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgaWYgKGtpbmRzLmNvbnRhaW5zKGQuZ2V0S2luZCgpKSkKICAgICAgICAgICAgICAgICAgICBwcmV2LnJlcG9ydChkKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBkZWZlcnJlZCA9IG51bGw7IC8vIHByZXZlbnQgYWNjaWRlbnRhbCBvbmdvaW5nIHVzZQogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgZW51bSBXcml0ZXJLaW5kIHsgTk9USUNFLCBXQVJOSU5HLCBFUlJPUiwgU1RET1VULCBTVERFUlIgfQoKICAgIHByaXZhdGUgZmluYWwgTWFwPFdyaXRlcktpbmQsIFByaW50V3JpdGVyPiB3cml0ZXJzOwoKICAgIC8qKiBUaGUgbWF4aW11bSBudW1iZXIgb2YgZXJyb3JzL3dhcm5pbmdzIHRoYXQgYXJlIHJlcG9ydGVkLgogICAgICovCiAgICBwcm90ZWN0ZWQgaW50IE1heEVycm9yczsKICAgIHByb3RlY3RlZCBpbnQgTWF4V2FybmluZ3M7CgogICAgLyoqIFN3aXRjaDogcHJvbXB0IHVzZXIgb24gZWFjaCBlcnJvci4KICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gcHJvbXB0T25FcnJvcjsKCiAgICAvKiogU3dpdGNoOiBlbWl0IHdhcm5pbmcgbWVzc2FnZXMuCiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGVtaXRXYXJuaW5nczsKCiAgICAvKiogU3dpdGNoOiBzdXBwcmVzcyBub3RlIG1lc3NhZ2VzLgogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBzdXBwcmVzc05vdGVzOwoKICAgIC8qKiBQcmludCBzdGFjayB0cmFjZSBvbiBlcnJvcnM/CiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGR1bXBPbkVycm9yOwoKICAgIC8qKgogICAgICogRGlhZ25vc3RpYyBsaXN0ZW5lciwgaWYgcHJvdmlkZWQgdGhyb3VnaCBwcm9ncmFtbWF0aWMKICAgICAqIGludGVyZmFjZSB0byBqYXZhYyAoSlNSIDE5OSkuCiAgICAgKi8KICAgIHByb3RlY3RlZCBEaWFnbm9zdGljTGlzdGVuZXI8PyBzdXBlciBKYXZhRmlsZU9iamVjdD4gZGlhZ0xpc3RlbmVyOwoKICAgIC8qKgogICAgICogRm9ybWF0dGVyIGZvciBkaWFnbm9zdGljcy4KICAgICAqLwogICAgcHJpdmF0ZSBEaWFnbm9zdGljRm9ybWF0dGVyPEpDRGlhZ25vc3RpYz4gZGlhZ0Zvcm1hdHRlcjsKCiAgICAvKioKICAgICAqIEtleXMgZm9yIGV4cGVjdGVkIGRpYWdub3N0aWNzLgogICAgICovCiAgICBwdWJsaWMgU2V0PFN0cmluZz4gZXhwZWN0RGlhZ0tleXM7CgogICAgLyoqCiAgICAgKiBTZXQgdG8gdHJ1ZSBpZiBhIGNvbXByZXNzZWQgZGlhZ25vc3RpYyBpcyByZXBvcnRlZAogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBjb21wcmVzc2VkT3V0cHV0OwoKICAgIC8qKgogICAgICogSmF2YWNNZXNzYWdlcyBvYmplY3QgdXNlZCBmb3IgbG9jYWxpemF0aW9uLgogICAgICovCiAgICBwcml2YXRlIEphdmFjTWVzc2FnZXMgbWVzc2FnZXM7CgogICAgLyoqCiAgICAgKiBIYW5kbGVyIGZvciBpbml0aWFsIGRpc3BhdGNoIG9mIGRpYWdub3N0aWNzLgogICAgICovCiAgICBwcml2YXRlIERpYWdub3N0aWNIYW5kbGVyIGRpYWdub3N0aWNIYW5kbGVyOwoKICAgIC8qKiBHZXQgdGhlIExvZyBpbnN0YW5jZSBmb3IgdGhpcyBjb250ZXh0LiAqLwogICAgcHVibGljIHN0YXRpYyBMb2cgaW5zdGFuY2UoQ29udGV4dCBjb250ZXh0KSB7CiAgICAgICAgTG9nIGluc3RhbmNlID0gY29udGV4dC5nZXQobG9nS2V5KTsKICAgICAgICBpZiAoaW5zdGFuY2UgPT0gbnVsbCkKICAgICAgICAgICAgaW5zdGFuY2UgPSBuZXcgTG9nKGNvbnRleHQpOwogICAgICAgIHJldHVybiBpbnN0YW5jZTsKICAgIH0KCiAgICAvKioKICAgICAqIFJlZ2lzdGVyIGEgQ29udGV4dC5GYWN0b3J5IHRvIGNyZWF0ZSBhIExvZy4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyB2b2lkIHByZVJlZ2lzdGVyKENvbnRleHQgY29udGV4dCwgUHJpbnRXcml0ZXIgdykgewogICAgICAgIGNvbnRleHQucHV0KExvZy5jbGFzcywgKENvbnRleHQuRmFjdG9yeTxMb2c+KSAoYyAtPiBuZXcgTG9nKGMsIHcpKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDb25zdHJ1Y3QgYSBsb2cgd2l0aCBkZWZhdWx0IHNldHRpbmdzLgogICAgICogSWYgbm8gc3RyZWFtcyBhcmUgc2V0IGluIHRoZSBjb250ZXh0LCB0aGUgbG9nIHdpbGwgYmUgaW5pdGlhbGl6ZWQgdG8gdXNlCiAgICAgKiBTeXN0ZW0ub3V0IGZvciBub3JtYWwgb3V0cHV0LCBhbmQgU3lzdGVtLmVyciBmb3IgYWxsIGRpYWdub3N0aWMgb3V0cHV0LgogICAgICogSWYgb25lIHN0cmVhbSBpcyBzZXQgaW4gdGhlIGNvbnRleHQsIHdpdGggZWl0aGVyIExvZy5vdXRLZXkgb3IgTG9nLmVycktleSwKICAgICAqIGl0IHdpbGwgYmUgdXNlZCBmb3IgYWxsIG91dHB1dC4KICAgICAqIE90aGVyd2lzZSwgdGhlIGxvZyB3aWxsIGJlIGluaXRpYWxpemVkIHRvIHVzZSBib3RoIHN0cmVhbXMgZm91bmQgaW4gdGhlIGNvbnRleHQuCiAgICAgKi8KICAgIHByb3RlY3RlZCBMb2coQ29udGV4dCBjb250ZXh0KSB7CiAgICAgICAgdGhpcyhjb250ZXh0LCBpbml0V3JpdGVycyhjb250ZXh0KSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBJbml0aWFsaXplIGEgbWFwIG9mIHdyaXRlcnMgYmFzZWQgb24gdmFsdWVzIGZvdW5kIGluIHRoZSBjb250ZXh0CiAgICAgKiBAcGFyYW0gY29udGV4dCB0aGUgY29udGV4dCBpbiB3aGljaCB0byBmaW5kIHdyaXRlcnMgdG8gdXNlCiAgICAgKiBAcmV0dXJuIGEgbWFwIG9mIHdyaXRlcnMKICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgTWFwPFdyaXRlcktpbmQsIFByaW50V3JpdGVyPiBpbml0V3JpdGVycyhDb250ZXh0IGNvbnRleHQpIHsKICAgICAgICBQcmludFdyaXRlciBvdXQgPSBjb250ZXh0LmdldChvdXRLZXkpOwogICAgICAgIFByaW50V3JpdGVyIGVyciA9IGNvbnRleHQuZ2V0KGVycktleSk7CiAgICAgICAgaWYgKG91dCA9PSBudWxsICYmIGVyciA9PSBudWxsKSB7CiAgICAgICAgICAgIG91dCA9IG5ldyBQcmludFdyaXRlcihTeXN0ZW0ub3V0LCB0cnVlKTsKICAgICAgICAgICAgZXJyID0gbmV3IFByaW50V3JpdGVyKFN5c3RlbS5lcnIsIHRydWUpOwogICAgICAgICAgICByZXR1cm4gaW5pdFdyaXRlcnMob3V0LCBlcnIpOwogICAgICAgIH0gZWxzZSBpZiAob3V0ID09IG51bGwgfHwgZXJyID09IG51bGwpIHsKICAgICAgICAgICAgUHJpbnRXcml0ZXIgcHcgPSAob3V0ICE9IG51bGwpID8gb3V0IDogZXJyOwogICAgICAgICAgICByZXR1cm4gaW5pdFdyaXRlcnMocHcsIHB3KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gaW5pdFdyaXRlcnMob3V0LCBlcnIpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIENvbnN0cnVjdCBhIGxvZyB3aXRoIGFsbCBvdXRwdXQgc2VudCB0byBhIHNpbmdsZSBvdXRwdXQgc3RyZWFtLgogICAgICovCiAgICBwcm90ZWN0ZWQgTG9nKENvbnRleHQgY29udGV4dCwgUHJpbnRXcml0ZXIgd3JpdGVyKSB7CiAgICAgICAgdGhpcyhjb250ZXh0LCBpbml0V3JpdGVycyh3cml0ZXIsIHdyaXRlcikpOwogICAgfQoKICAgIC8qKgogICAgICogQ29uc3RydWN0IGEgbG9nLgogICAgICogVGhlIGxvZyB3aWxsIGJlIGluaXRpYWxpemVkIHRvIHVzZSBzdGRPdXQgZm9yIG5vcm1hbCBvdXRwdXQsIGFuZCBzdGRFcnIKICAgICAqIGZvciBhbGwgZGlhZ25vc3RpYyBvdXRwdXQuCiAgICAgKi8KICAgIHByb3RlY3RlZCBMb2coQ29udGV4dCBjb250ZXh0LCBQcmludFdyaXRlciBvdXQsIFByaW50V3JpdGVyIGVycikgewogICAgICAgIHRoaXMoY29udGV4dCwgaW5pdFdyaXRlcnMob3V0LCBlcnIpKTsKICAgIH0KCiAgICAvKioKICAgICAqIEluaXRpYWxpemUgYSB3cml0ZXIgbWFwIGZvciBhIHN0cmVhbSBmb3Igbm9ybWFsIG91dHB1dCwgYW5kIGEgc3RyZWFtIGZvciBkaWFnbm9zdGljcy4KICAgICAqIEBwYXJhbSBvdXQgYSBzdHJlYW0gdG8gYmUgdXNlZCBmb3Igbm9ybWFsIG91dHB1dAogICAgICogQHBhcmFtIGVyciBhIHN0cmVhbSB0byBiZSB1c2VkIGZvciBkaWFnbm9zdGljIG1lc3NhZ2VzLCBzdWNoIGFzIGVycm9ycywgd2FybmluZ3MsIGV0YwogICAgICogQHJldHVybiBhIG1hcCBvZiB3cml0ZXJzCiAgICAgKi8KICAgIHByaXZhdGUgc3RhdGljIE1hcDxXcml0ZXJLaW5kLCBQcmludFdyaXRlcj4gaW5pdFdyaXRlcnMoUHJpbnRXcml0ZXIgb3V0LCBQcmludFdyaXRlciBlcnIpIHsKICAgICAgICBNYXA8V3JpdGVyS2luZCwgUHJpbnRXcml0ZXI+IHdyaXRlcnMgPSBuZXcgRW51bU1hcDw+KFdyaXRlcktpbmQuY2xhc3MpOwogICAgICAgIHdyaXRlcnMucHV0KFdyaXRlcktpbmQuRVJST1IsIGVycik7CiAgICAgICAgd3JpdGVycy5wdXQoV3JpdGVyS2luZC5XQVJOSU5HLCBlcnIpOwogICAgICAgIHdyaXRlcnMucHV0KFdyaXRlcktpbmQuTk9USUNFLCBlcnIpOwoKICAgICAgICB3cml0ZXJzLnB1dChXcml0ZXJLaW5kLlNURE9VVCwgb3V0KTsKICAgICAgICB3cml0ZXJzLnB1dChXcml0ZXJLaW5kLlNUREVSUiwgZXJyKTsKCiAgICAgICAgcmV0dXJuIHdyaXRlcnM7CiAgICB9CgogICAgLyoqCiAgICAgKiBDb25zdHJ1Y3QgYSBsb2cgd2l0aCBnaXZlbiBJL08gcmVkaXJlY3Rpb25zLgogICAgICogQGRlcHJlY2F0ZWQKICAgICAqIFRoaXMgY29uc3RydWN0b3IgaXMgcHJvdmlkZWQgdG8gc3VwcG9ydCB0aGUgc3VwcG9ydGVkIGJ1dCBub3ctZGVwcmVjYXRlZCBqYXZhZG9jIGVudHJ5IHBvaW50CiAgICAgKiAgICAgIGNvbS5zdW4udG9vbHMuamF2YWRvYy5NYWluLmV4ZWN1dGUoU3RyaW5nIHByb2dyYW1OYW1lLAogICAgICogICAgICAgICAgUHJpbnRXcml0ZXIgZXJyV3JpdGVyLCBQcmludFdyaXRlciB3YXJuV3JpdGVyLCBQcmludFdyaXRlciBub3RpY2VXcml0ZXIsCiAgICAgKiAgICAgICAgICBTdHJpbmcgZGVmYXVsdERvY2xldENsYXNzTmFtZSwgU3RyaW5nLi4uIGFyZ3MpCiAgICAgKi8KICAgIEBEZXByZWNhdGVkCiAgICBwcm90ZWN0ZWQgTG9nKENvbnRleHQgY29udGV4dCwgUHJpbnRXcml0ZXIgZXJyV3JpdGVyLCBQcmludFdyaXRlciB3YXJuV3JpdGVyLCBQcmludFdyaXRlciBub3RpY2VXcml0ZXIpIHsKICAgICAgICB0aGlzKGNvbnRleHQsIGluaXRXcml0ZXJzKGVycldyaXRlciwgd2FybldyaXRlciwgbm90aWNlV3JpdGVyKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBJbml0aWFsaXplIGEgd3JpdGVyIG1hcCB3aXRoIGRpZmZlcmVudCBzdHJlYW1zIGZvciBkaWZmZXJlbnQgdHlwZXMgb2YgZGlhZ25vc3RpY3MuCiAgICAgKiBAcGFyYW0gZXJyV3JpdGVyIGEgc3RyZWFtIGZvciB3cml0aW5nIGVycm9yIG1lc3NhZ2VzCiAgICAgKiBAcGFyYW0gd2FybldyaXRlciBhIHN0cmVhbSBmb3Igd3JpdGluZyB3YXJuaW5nIG1lc3NhZ2VzCiAgICAgKiBAcGFyYW0gbm90aWNlV3JpdGVyIGEgc3RyZWFtIGZvciB3cml0aW5nIG5vdGljZSBtZXNzYWdlcwogICAgICogQHJldHVybiBhIG1hcCBvZiB3cml0ZXJzCiAgICAgKiBAZGVwcmVjYXRlZCBUaGlzIG1ldGhvZCBleGlzdHMgdG8gc3VwcG9ydCBhIHN1cHBvcnRlZCBidXQgbm93IGRlcHJlY2F0ZWQgamF2YWRvYyBlbnRyeSBwb2ludC4KICAgICAqLwogICAgQERlcHJlY2F0ZWQKICAgIHByaXZhdGUgc3RhdGljIE1hcDxXcml0ZXJLaW5kLCBQcmludFdyaXRlcj4gIGluaXRXcml0ZXJzKFByaW50V3JpdGVyIGVycldyaXRlciwgUHJpbnRXcml0ZXIgd2FybldyaXRlciwgUHJpbnRXcml0ZXIgbm90aWNlV3JpdGVyKSB7CiAgICAgICAgTWFwPFdyaXRlcktpbmQsIFByaW50V3JpdGVyPiB3cml0ZXJzID0gbmV3IEVudW1NYXA8PihXcml0ZXJLaW5kLmNsYXNzKTsKICAgICAgICB3cml0ZXJzLnB1dChXcml0ZXJLaW5kLkVSUk9SLCBlcnJXcml0ZXIpOwogICAgICAgIHdyaXRlcnMucHV0KFdyaXRlcktpbmQuV0FSTklORywgd2FybldyaXRlcik7CiAgICAgICAgd3JpdGVycy5wdXQoV3JpdGVyS2luZC5OT1RJQ0UsIG5vdGljZVdyaXRlcik7CgogICAgICAgIHdyaXRlcnMucHV0KFdyaXRlcktpbmQuU1RET1VULCBub3RpY2VXcml0ZXIpOwogICAgICAgIHdyaXRlcnMucHV0KFdyaXRlcktpbmQuU1RERVJSLCBlcnJXcml0ZXIpOwoKICAgICAgICByZXR1cm4gd3JpdGVyczsKICAgIH0KCiAgICAvKioKICAgICAqIENyZWF0ZXMgYSBsb2cuCiAgICAgKiBAcGFyYW0gY29udGV4dCB0aGUgY29udGV4dCBpbiB3aGljaCB0aGUgbG9nIHNob3VsZCBiZSByZWdpc3RlcmVkCiAgICAgKiBAcGFyYW0gd3JpdGVycyBhIG1hcCBvZiB3cml0ZXJzIHRoYXQgY2FuIGJlIGFjY2Vzc2VkIGJ5IHRoZSBraW5kIG9mIHdyaXRlciByZXF1aXJlZAogICAgICovCiAgICBwcml2YXRlIExvZyhDb250ZXh0IGNvbnRleHQsIE1hcDxXcml0ZXJLaW5kLCBQcmludFdyaXRlcj4gd3JpdGVycykgewogICAgICAgIHN1cGVyKEpDRGlhZ25vc3RpYy5GYWN0b3J5Lmluc3RhbmNlKGNvbnRleHQpKTsKICAgICAgICBjb250ZXh0LnB1dChsb2dLZXksIHRoaXMpOwogICAgICAgIHRoaXMud3JpdGVycyA9IHdyaXRlcnM7CgogICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKSAvLyBGSVhNRQogICAgICAgIERpYWdub3N0aWNMaXN0ZW5lcjw/IHN1cGVyIEphdmFGaWxlT2JqZWN0PiBkbCA9CiAgICAgICAgICAgIGNvbnRleHQuZ2V0KERpYWdub3N0aWNMaXN0ZW5lci5jbGFzcyk7CiAgICAgICAgdGhpcy5kaWFnTGlzdGVuZXIgPSBkbDsKCiAgICAgICAgZGlhZ25vc3RpY0hhbmRsZXIgPSBuZXcgRGVmYXVsdERpYWdub3N0aWNIYW5kbGVyKCk7CgogICAgICAgIG1lc3NhZ2VzID0gSmF2YWNNZXNzYWdlcy5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBtZXNzYWdlcy5hZGQoTWFpbi5qYXZhY0J1bmRsZU5hbWUpOwoKICAgICAgICBmaW5hbCBPcHRpb25zIG9wdGlvbnMgPSBPcHRpb25zLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIGluaXRPcHRpb25zKG9wdGlvbnMpOwogICAgICAgIG9wdGlvbnMuYWRkTGlzdGVuZXIoKCkgLT4gaW5pdE9wdGlvbnMob3B0aW9ucykpOwogICAgfQogICAgLy8gd2hlcmUKICAgICAgICBwcml2YXRlIHZvaWQgaW5pdE9wdGlvbnMoT3B0aW9ucyBvcHRpb25zKSB7CiAgICAgICAgICAgIHRoaXMuZHVtcE9uRXJyb3IgPSBvcHRpb25zLmlzU2V0KERPRSk7CiAgICAgICAgICAgIHRoaXMucHJvbXB0T25FcnJvciA9IG9wdGlvbnMuaXNTZXQoUFJPTVBUKTsKICAgICAgICAgICAgdGhpcy5lbWl0V2FybmluZ3MgPSBvcHRpb25zLmlzVW5zZXQoWExJTlRfQ1VTVE9NLCAibm9uZSIpOwogICAgICAgICAgICB0aGlzLnN1cHByZXNzTm90ZXMgPSBvcHRpb25zLmlzU2V0KCJzdXBwcmVzc05vdGVzIik7CiAgICAgICAgICAgIHRoaXMuTWF4RXJyb3JzID0gZ2V0SW50T3B0aW9uKG9wdGlvbnMsIFhNQVhFUlJTLCBnZXREZWZhdWx0TWF4RXJyb3JzKCkpOwogICAgICAgICAgICB0aGlzLk1heFdhcm5pbmdzID0gZ2V0SW50T3B0aW9uKG9wdGlvbnMsIFhNQVhXQVJOUywgZ2V0RGVmYXVsdE1heFdhcm5pbmdzKCkpOwoKICAgICAgICAgICAgYm9vbGVhbiByYXdEaWFnbm9zdGljcyA9IG9wdGlvbnMuaXNTZXQoInJhd0RpYWdub3N0aWNzIik7CiAgICAgICAgICAgIHRoaXMuZGlhZ0Zvcm1hdHRlciA9IHJhd0RpYWdub3N0aWNzID8gbmV3IFJhd0RpYWdub3N0aWNGb3JtYXR0ZXIob3B0aW9ucykgOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBCYXNpY0RpYWdub3N0aWNGb3JtYXR0ZXIob3B0aW9ucywgbWVzc2FnZXMpOwoKICAgICAgICAgICAgU3RyaW5nIGVrID0gb3B0aW9ucy5nZXQoImV4cGVjdEtleXMiKTsKICAgICAgICAgICAgaWYgKGVrICE9IG51bGwpCiAgICAgICAgICAgICAgICBleHBlY3REaWFnS2V5cyA9IG5ldyBIYXNoU2V0PD4oQXJyYXlzLmFzTGlzdChlay5zcGxpdCgiLCAqIikpKTsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgaW50IGdldEludE9wdGlvbihPcHRpb25zIG9wdGlvbnMsIE9wdGlvbiBvcHRpb24sIGludCBkZWZhdWx0VmFsdWUpIHsKICAgICAgICAgICAgU3RyaW5nIHMgPSBvcHRpb25zLmdldChvcHRpb24pOwogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgaWYgKHMgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIGludCBuID0gSW50ZWdlci5wYXJzZUludChzKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gKG4gPD0gMCA/IEludGVnZXIuTUFYX1ZBTFVFIDogbik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgICAvLyBzaWxlbnRseSBpZ25vcmUgaWxsLWZvcm1lZCBudW1iZXJzCiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGRlZmF1bHRWYWx1ZTsKICAgICAgICB9CgogICAgICAgIC8qKiBEZWZhdWx0IHZhbHVlIGZvciAtWG1heGVycnMuCiAgICAgICAgICovCiAgICAgICAgcHJvdGVjdGVkIGludCBnZXREZWZhdWx0TWF4RXJyb3JzKCkgewogICAgICAgICAgICByZXR1cm4gMTAwOwogICAgICAgIH0KCiAgICAgICAgLyoqIERlZmF1bHQgdmFsdWUgZm9yIC1YbWF4d2FybnMuCiAgICAgICAgICovCiAgICAgICAgcHJvdGVjdGVkIGludCBnZXREZWZhdWx0TWF4V2FybmluZ3MoKSB7CiAgICAgICAgICAgIHJldHVybiAxMDA7CiAgICAgICAgfQoKICAgIC8qKiBUaGUgbnVtYmVyIG9mIGVycm9ycyBlbmNvdW50ZXJlZCBzbyBmYXIuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgbmVycm9ycyA9IDA7CgogICAgLyoqIFRoZSBudW1iZXIgb2Ygd2FybmluZ3MgZW5jb3VudGVyZWQgc28gZmFyLgogICAgICovCiAgICBwdWJsaWMgaW50IG53YXJuaW5ncyA9IDA7CgogICAgLyoqIEEgc2V0IG9mIGFsbCBlcnJvcnMgZ2VuZXJhdGVkIHNvIGZhci4gVGhpcyBpcyB1c2VkIHRvIGF2b2lkIHByaW50aW5nIGFuCiAgICAgKiAgZXJyb3IgbWVzc2FnZSBtb3JlIHRoYW4gb25jZS4gRm9yIGVhY2ggZXJyb3IsIGEgcGFpciBjb25zaXN0aW5nIG9mIHRoZQogICAgICogIHNvdXJjZSBmaWxlIG5hbWUgYW5kIHNvdXJjZSBjb2RlIHBvc2l0aW9uIG9mIHRoZSBlcnJvciBpcyBhZGRlZCB0byB0aGUgc2V0LgogICAgICovCiAgICBwcm90ZWN0ZWQgU2V0PFBhaXI8SmF2YUZpbGVPYmplY3QsIEludGVnZXI+PiByZWNvcmRlZCA9IG5ldyBIYXNoU2V0PD4oKTsKCiAgICAvKiogQSBzZXQgb2YgIm5vdC1zdXBwb3J0ZWQtaW4tc291cmNlLVgiIGVycm9ycyBwcm9kdWNlZCBzbyBmYXIuIFRoaXMgaXMgdXNlZCB0byBvbmx5IGdlbmVyYXRlCiAgICAgKiAgb25lIHN1Y2ggZXJyb3IgcGVyIGZpbGUuCiAgICAgKi8KICAgIHByb3RlY3RlZCBTZXQ8UGFpcjxKYXZhRmlsZU9iamVjdCwgU3RyaW5nPj4gIHJlY29yZGVkU291cmNlTGV2ZWxFcnJvcnMgPSBuZXcgSGFzaFNldDw+KCk7CgogICAgcHVibGljIGJvb2xlYW4gaGFzRGlhZ25vc3RpY0xpc3RlbmVyKCkgewogICAgICAgIHJldHVybiBkaWFnTGlzdGVuZXIgIT0gbnVsbDsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCBzZXRFbmRQb3NUYWJsZShKYXZhRmlsZU9iamVjdCBuYW1lLCBFbmRQb3NUYWJsZSBlbmRQb3NUYWJsZSkgewogICAgICAgIEFzc2VydC5jaGVja05vbk51bGwobmFtZSk7CiAgICAgICAgZ2V0U291cmNlKG5hbWUpLnNldEVuZFBvc1RhYmxlKGVuZFBvc1RhYmxlKTsKICAgIH0KCiAgICAvKiogUmV0dXJuIGN1cnJlbnQgc291cmNlZmlsZS4KICAgICAqLwogICAgcHVibGljIEphdmFGaWxlT2JqZWN0IGN1cnJlbnRTb3VyY2VGaWxlKCkgewogICAgICAgIHJldHVybiBzb3VyY2UgPT0gbnVsbCA/IG51bGwgOiBzb3VyY2UuZ2V0RmlsZSgpOwogICAgfQoKICAgIC8qKiBHZXQgdGhlIGN1cnJlbnQgZGlhZ25vc3RpYyBmb3JtYXR0ZXIuCiAgICAgKi8KICAgIHB1YmxpYyBEaWFnbm9zdGljRm9ybWF0dGVyPEpDRGlhZ25vc3RpYz4gZ2V0RGlhZ25vc3RpY0Zvcm1hdHRlcigpIHsKICAgICAgICByZXR1cm4gZGlhZ0Zvcm1hdHRlcjsKICAgIH0KCiAgICAvKiogU2V0IHRoZSBjdXJyZW50IGRpYWdub3N0aWMgZm9ybWF0dGVyLgogICAgICovCiAgICBwdWJsaWMgdm9pZCBzZXREaWFnbm9zdGljRm9ybWF0dGVyKERpYWdub3N0aWNGb3JtYXR0ZXI8SkNEaWFnbm9zdGljPiBkaWFnRm9ybWF0dGVyKSB7CiAgICAgICAgdGhpcy5kaWFnRm9ybWF0dGVyID0gZGlhZ0Zvcm1hdHRlcjsKICAgIH0KCiAgICBwdWJsaWMgUHJpbnRXcml0ZXIgZ2V0V3JpdGVyKFdyaXRlcktpbmQga2luZCkgewogICAgICAgIHJldHVybiB3cml0ZXJzLmdldChraW5kKTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCBzZXRXcml0ZXIoV3JpdGVyS2luZCBraW5kLCBQcmludFdyaXRlciBwdykgewogICAgICAgIEFzc2VydC5jaGVja05vbk51bGwocHcpOwogICAgICAgIHdyaXRlcnMucHV0KGtpbmQsIHB3KTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCBzZXRXcml0ZXJzKFByaW50V3JpdGVyIHB3KSB7CiAgICAgICAgQXNzZXJ0LmNoZWNrTm9uTnVsbChwdyk7CiAgICAgICAgZm9yIChXcml0ZXJLaW5kIGs6IFdyaXRlcktpbmQudmFsdWVzKCkpCiAgICAgICAgICAgIHdyaXRlcnMucHV0KGssIHB3KTsKICAgIH0KCiAgICAvKioKICAgICAqIFJlcGxhY2UgdGhlIHNwZWNpZmllZCBkaWFnbm9zdGljIGhhbmRsZXIgd2l0aCB0aGUKICAgICAqIGhhbmRsZXIgdGhhdCB3YXMgY3VycmVudCBhdCB0aGUgdGltZSB0aGlzIGhhbmRsZXIgd2FzIGNyZWF0ZWQuCiAgICAgKiBUaGUgZ2l2ZW4gaGFuZGxlciBtdXN0IGJlIHRoZSBjdXJyZW50bHkgaW5zdGFsbGVkIGhhbmRsZXI7CiAgICAgKiBpdCBtdXN0IGJlIHNwZWNpZmllZCBleHBsaWNpdGx5IGZvciBjbGFyaXR5IGFuZCBjb25zaXN0ZW5jeSBjaGVja2luZy4KICAgICAqLwogICAgcHVibGljIHZvaWQgcG9wRGlhZ25vc3RpY0hhbmRsZXIoRGlhZ25vc3RpY0hhbmRsZXIgaCkgewogICAgICAgIEFzc2VydC5jaGVjayhkaWFnbm9zdGljSGFuZGxlciA9PSBoKTsKICAgICAgICBkaWFnbm9zdGljSGFuZGxlciA9IGgucHJldjsKICAgIH0KCiAgICAvKiogRmx1c2ggdGhlIGxvZ3MKICAgICAqLwogICAgcHVibGljIHZvaWQgZmx1c2goKSB7CiAgICAgICAgZm9yIChQcmludFdyaXRlciBwdzogd3JpdGVycy52YWx1ZXMoKSkgewogICAgICAgICAgICBwdy5mbHVzaCgpOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgdm9pZCBmbHVzaChXcml0ZXJLaW5kIGtpbmQpIHsKICAgICAgICBnZXRXcml0ZXIoa2luZCkuZmx1c2goKTsKICAgIH0KCiAgICAvKiogUmV0dXJucyB0cnVlIGlmIGFuIGVycm9yIG5lZWRzIHRvIGJlIHJlcG9ydGVkIGZvciBhIGdpdmVuCiAgICAgKiBzb3VyY2UgbmFtZSBhbmQgcG9zLgogICAgICovCiAgICBwcm90ZWN0ZWQgYm9vbGVhbiBzaG91bGRSZXBvcnQoSmF2YUZpbGVPYmplY3QgZmlsZSwgaW50IHBvcykgewogICAgICAgIGlmIChmaWxlID09IG51bGwpCiAgICAgICAgICAgIHJldHVybiB0cnVlOwoKICAgICAgICBQYWlyPEphdmFGaWxlT2JqZWN0LEludGVnZXI+IGNvb3JkcyA9IG5ldyBQYWlyPD4oZmlsZSwgcG9zKTsKICAgICAgICBib29sZWFuIHNob3VsZFJlcG9ydCA9ICFyZWNvcmRlZC5jb250YWlucyhjb29yZHMpOwogICAgICAgIGlmIChzaG91bGRSZXBvcnQpCiAgICAgICAgICAgIHJlY29yZGVkLmFkZChjb29yZHMpOwogICAgICAgIHJldHVybiBzaG91bGRSZXBvcnQ7CiAgICB9CgogICAgLyoqIFJldHVybnMgdHJ1ZSBpZiBhIGRpYWdub3N0aWNzIG5lZWRzIHRvIGJlIHJlcG9ydGVkLgogICAgICovCiAgICBwcml2YXRlIGJvb2xlYW4gc2hvdWxkUmVwb3J0KEpDRGlhZ25vc3RpYyBkKSB7CiAgICAgICAgSmF2YUZpbGVPYmplY3QgZmlsZSA9IGQuZ2V0U291cmNlKCk7CgogICAgICAgIGlmIChmaWxlID09IG51bGwpCiAgICAgICAgICAgIHJldHVybiB0cnVlOwoKICAgICAgICBpZiAoIXNob3VsZFJlcG9ydChmaWxlLCBkLmdldEludFBvc2l0aW9uKCkpKQogICAgICAgICAgICByZXR1cm4gZmFsc2U7CgogICAgICAgIGlmICghZC5pc0ZsYWdTZXQoRGlhZ25vc3RpY0ZsYWcuU09VUkNFX0xFVkVMKSkKICAgICAgICAgICAgcmV0dXJuIHRydWU7CgogICAgICAgIFBhaXI8SmF2YUZpbGVPYmplY3QsIFN0cmluZz4gY29vcmRzID0gbmV3IFBhaXI8PihmaWxlLCBkLmdldENvZGUoKSk7CiAgICAgICAgYm9vbGVhbiBzaG91bGRSZXBvcnQgPSAhcmVjb3JkZWRTb3VyY2VMZXZlbEVycm9ycy5jb250YWlucyhjb29yZHMpOwogICAgICAgIGlmIChzaG91bGRSZXBvcnQpCiAgICAgICAgICAgIHJlY29yZGVkU291cmNlTGV2ZWxFcnJvcnMuYWRkKGNvb3Jkcyk7CiAgICAgICAgcmV0dXJuIHNob3VsZFJlcG9ydDsKICAgIH0KCiAgICAvKiogUHJvbXB0IHVzZXIgYWZ0ZXIgYW4gZXJyb3IuCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHByb21wdCgpIHsKICAgICAgICBpZiAocHJvbXB0T25FcnJvcikgewogICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4obG9jYWxpemUoInJlc3VtZS5hYm9ydCIpKTsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIHdoaWxlICh0cnVlKSB7CiAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChTeXN0ZW0uaW4ucmVhZCgpKSB7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAnYSc6IGNhc2UgJ0EnOgogICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0uZXhpdCgtMSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICBjYXNlICdyJzogY2FzZSAnUic6CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICBjYXNlICd4JzogY2FzZSAnWCc6CiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigidXNlciBhYm9ydCIpOwogICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7fQogICAgICAgIH0KICAgIH0KCiAgICAvKiogUHJpbnQgdGhlIGZhdWx0eSBzb3VyY2UgY29kZSBsaW5lIGFuZCBwb2ludCB0byB0aGUgZXJyb3IuCiAgICAgKiAgQHBhcmFtIHBvcyAgIEJ1ZmZlciBpbmRleCBvZiB0aGUgZXJyb3IgcG9zaXRpb24sIG11c3QgYmUgb24gY3VycmVudCBsaW5lCiAgICAgKi8KICAgIHByaXZhdGUgdm9pZCBwcmludEVyckxpbmUoaW50IHBvcywgUHJpbnRXcml0ZXIgd3JpdGVyKSB7CiAgICAgICAgU3RyaW5nIGxpbmUgPSAoc291cmNlID09IG51bGwgPyBudWxsIDogc291cmNlLmdldExpbmUocG9zKSk7CiAgICAgICAgaWYgKGxpbmUgPT0gbnVsbCkKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIGludCBjb2wgPSBzb3VyY2UuZ2V0Q29sdW1uTnVtYmVyKHBvcywgZmFsc2UpOwoKICAgICAgICBwcmludFJhd0xpbmVzKHdyaXRlciwgbGluZSk7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjb2wgLSAxOyBpKyspIHsKICAgICAgICAgICAgd3JpdGVyLnByaW50KChsaW5lLmNoYXJBdChpKSA9PSAnXHQnKSA/ICJcdCIgOiAiICIpOwogICAgICAgIH0KICAgICAgICB3cml0ZXIucHJpbnRsbigiXiIpOwogICAgICAgIHdyaXRlci5mbHVzaCgpOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHByaW50TmV3bGluZSgpIHsKICAgICAgICBQcmludFdyaXRlciBub3RpY2VXcml0ZXIgPSB3cml0ZXJzLmdldChXcml0ZXJLaW5kLk5PVElDRSk7CiAgICAgICAgbm90aWNlV3JpdGVyLnByaW50bG4oKTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCBwcmludE5ld2xpbmUoV3JpdGVyS2luZCB3aykgewogICAgICAgIGdldFdyaXRlcih3aykucHJpbnRsbigpOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHByaW50TGluZXMoU3RyaW5nIGtleSwgT2JqZWN0Li4uIGFyZ3MpIHsKICAgICAgICBQcmludFdyaXRlciBub3RpY2VXcml0ZXIgPSB3cml0ZXJzLmdldChXcml0ZXJLaW5kLk5PVElDRSk7CiAgICAgICAgcHJpbnRSYXdMaW5lcyhub3RpY2VXcml0ZXIsIGxvY2FsaXplKGtleSwgYXJncykpOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHByaW50TGluZXMoUHJlZml4S2luZCBwaywgU3RyaW5nIGtleSwgT2JqZWN0Li4uIGFyZ3MpIHsKICAgICAgICBQcmludFdyaXRlciBub3RpY2VXcml0ZXIgPSB3cml0ZXJzLmdldChXcml0ZXJLaW5kLk5PVElDRSk7CiAgICAgICAgcHJpbnRSYXdMaW5lcyhub3RpY2VXcml0ZXIsIGxvY2FsaXplKHBrLCBrZXksIGFyZ3MpKTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCBwcmludExpbmVzKFdyaXRlcktpbmQgd2ssIFN0cmluZyBrZXksIE9iamVjdC4uLiBhcmdzKSB7CiAgICAgICAgcHJpbnRSYXdMaW5lcyhnZXRXcml0ZXIod2spLCBsb2NhbGl6ZShrZXksIGFyZ3MpKTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCBwcmludExpbmVzKFdyaXRlcktpbmQgd2ssIFByZWZpeEtpbmQgcGssIFN0cmluZyBrZXksIE9iamVjdC4uLiBhcmdzKSB7CiAgICAgICAgcHJpbnRSYXdMaW5lcyhnZXRXcml0ZXIod2spLCBsb2NhbGl6ZShwaywga2V5LCBhcmdzKSk7CiAgICB9CgogICAgLyoqIFByaW50IHRoZSB0ZXh0IG9mIGEgbWVzc2FnZSwgdHJhbnNsYXRpbmcgbmV3bGluZXMgYXBwcm9wcmlhdGVseQogICAgICogIGZvciB0aGUgcGxhdGZvcm0uCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHByaW50UmF3TGluZXMoU3RyaW5nIG1zZykgewogICAgICAgIFByaW50V3JpdGVyIG5vdGljZVdyaXRlciA9IHdyaXRlcnMuZ2V0KFdyaXRlcktpbmQuTk9USUNFKTsKICAgICAgICBwcmludFJhd0xpbmVzKG5vdGljZVdyaXRlciwgbXNnKTsKICAgIH0KCiAgICAvKiogUHJpbnQgdGhlIHRleHQgb2YgYSBtZXNzYWdlLCB0cmFuc2xhdGluZyBuZXdsaW5lcyBhcHByb3ByaWF0ZWx5CiAgICAgKiAgZm9yIHRoZSBwbGF0Zm9ybS4KICAgICAqLwogICAgcHVibGljIHZvaWQgcHJpbnRSYXdMaW5lcyhXcml0ZXJLaW5kIGtpbmQsIFN0cmluZyBtc2cpIHsKICAgICAgICBwcmludFJhd0xpbmVzKGdldFdyaXRlcihraW5kKSwgbXNnKTsKICAgIH0KCiAgICAvKiogUHJpbnQgdGhlIHRleHQgb2YgYSBtZXNzYWdlLCB0cmFuc2xhdGluZyBuZXdsaW5lcyBhcHByb3ByaWF0ZWx5CiAgICAgKiAgZm9yIHRoZSBwbGF0Zm9ybS4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyB2b2lkIHByaW50UmF3TGluZXMoUHJpbnRXcml0ZXIgd3JpdGVyLCBTdHJpbmcgbXNnKSB7CiAgICAgICAgaW50IG5sOwogICAgICAgIHdoaWxlICgobmwgPSBtc2cuaW5kZXhPZignXG4nKSkgIT0gLTEpIHsKICAgICAgICAgICAgd3JpdGVyLnByaW50bG4obXNnLnN1YnN0cmluZygwLCBubCkpOwogICAgICAgICAgICBtc2cgPSBtc2cuc3Vic3RyaW5nKG5sKzEpOwogICAgICAgIH0KICAgICAgICBpZiAobXNnLmxlbmd0aCgpICE9IDApIHdyaXRlci5wcmludGxuKG1zZyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBQcmludCB0aGUgbG9jYWxpemVkIHRleHQgb2YgYSAidmVyYm9zZSIgbWVzc2FnZSB0byB0aGUKICAgICAqIG5vdGljZVdyaXRlciBzdHJlYW0uCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHByaW50VmVyYm9zZShTdHJpbmcga2V5LCBPYmplY3QuLi4gYXJncykgewogICAgICAgIFByaW50V3JpdGVyIG5vdGljZVdyaXRlciA9IHdyaXRlcnMuZ2V0KFdyaXRlcktpbmQuTk9USUNFKTsKICAgICAgICBwcmludFJhd0xpbmVzKG5vdGljZVdyaXRlciwgbG9jYWxpemUoInZlcmJvc2UuIiArIGtleSwgYXJncykpOwogICAgfQoKICAgIEBPdmVycmlkZQogICAgcHJvdGVjdGVkIHZvaWQgZGlyZWN0RXJyb3IoU3RyaW5nIGtleSwgT2JqZWN0Li4uIGFyZ3MpIHsKICAgICAgICBQcmludFdyaXRlciBlcnJXcml0ZXIgPSB3cml0ZXJzLmdldChXcml0ZXJLaW5kLkVSUk9SKTsKICAgICAgICBwcmludFJhd0xpbmVzKGVycldyaXRlciwgbG9jYWxpemUoa2V5LCBhcmdzKSk7CiAgICAgICAgZXJyV3JpdGVyLmZsdXNoKCk7CiAgICB9CgogICAgLyoqIFJlcG9ydCBhIHdhcm5pbmcgdGhhdCBjYW5ub3QgYmUgc3VwcHJlc3NlZC4KICAgICAqICBAcGFyYW0gcG9zICAgIFRoZSBzb3VyY2UgcG9zaXRpb24gYXQgd2hpY2ggdG8gcmVwb3J0IHRoZSB3YXJuaW5nLgogICAgICogIEBwYXJhbSBrZXkgICAgVGhlIGtleSBmb3IgdGhlIGxvY2FsaXplZCB3YXJuaW5nIG1lc3NhZ2UuCiAgICAgKiAgQHBhcmFtIGFyZ3MgICBGaWVsZHMgb2YgdGhlIHdhcm5pbmcgbWVzc2FnZS4KICAgICAqLwogICAgcHVibGljIHZvaWQgc3RyaWN0V2FybmluZyhEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBTdHJpbmcga2V5LCBPYmplY3QgLi4uIGFyZ3MpIHsKICAgICAgICB3cml0ZURpYWdub3N0aWMoZGlhZ3Mud2FybmluZyhudWxsLCBzb3VyY2UsIHBvcywga2V5LCBhcmdzKSk7CiAgICAgICAgbndhcm5pbmdzKys7CiAgICB9CgogICAgLyoqCiAgICAgKiBQcmltYXJ5IG1ldGhvZCB0byByZXBvcnQgYSBkaWFnbm9zdGljLgogICAgICogQHBhcmFtIGRpYWdub3N0aWMKICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCByZXBvcnQoSkNEaWFnbm9zdGljIGRpYWdub3N0aWMpIHsKICAgICAgICBkaWFnbm9zdGljSGFuZGxlci5yZXBvcnQoZGlhZ25vc3RpYyk7CiAgICAgfQoKICAgIC8qKgogICAgICogQ29tbW9uIGRpYWdub3N0aWMgaGFuZGxpbmcuCiAgICAgKiBUaGUgZGlhZ25vc3RpYyBpcyBjb3VudGVkLCBhbmQgZGVwZW5kaW5nIG9uIHRoZSBvcHRpb25zIGFuZCBob3cgbWFueSBkaWFnbm9zdGljcyBoYXZlIGJlZW4KICAgICAqIHJlcG9ydGVkIHNvIGZhciwgdGhlIGRpYWdub3N0aWMgbWF5IGJlIGhhbmRlZCBvZmYgdG8gd3JpdGVEaWFnbm9zdGljLgogICAgICovCiAgICBwcml2YXRlIGNsYXNzIERlZmF1bHREaWFnbm9zdGljSGFuZGxlciBleHRlbmRzIERpYWdub3N0aWNIYW5kbGVyIHsKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCByZXBvcnQoSkNEaWFnbm9zdGljIGRpYWdub3N0aWMpIHsKICAgICAgICAgICAgaWYgKGV4cGVjdERpYWdLZXlzICE9IG51bGwpCiAgICAgICAgICAgICAgICBleHBlY3REaWFnS2V5cy5yZW1vdmUoZGlhZ25vc3RpYy5nZXRDb2RlKCkpOwoKICAgICAgICAgICAgc3dpdGNoIChkaWFnbm9zdGljLmdldFR5cGUoKSkgewogICAgICAgICAgICBjYXNlIEZSQUdNRU5UOgogICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwoKICAgICAgICAgICAgY2FzZSBOT1RFOgogICAgICAgICAgICAgICAgLy8gUHJpbnQgb3V0IG5vdGVzIG9ubHkgd2hlbiB3ZSBhcmUgcGVybWl0dGVkIHRvIHJlcG9ydCB3YXJuaW5ncwogICAgICAgICAgICAgICAgLy8gTm90ZXMgYXJlIG9ubHkgZ2VuZXJhdGVkIGF0IHRoZSBlbmQgb2YgYSBjb21waWxhdGlvbiwgc28gc2hvdWxkIGJlIHNtYWxsCiAgICAgICAgICAgICAgICAvLyBpbiBudW1iZXIuCiAgICAgICAgICAgICAgICBpZiAoKGVtaXRXYXJuaW5ncyB8fCBkaWFnbm9zdGljLmlzTWFuZGF0b3J5KCkpICYmICFzdXBwcmVzc05vdGVzKSB7CiAgICAgICAgICAgICAgICAgICAgd3JpdGVEaWFnbm9zdGljKGRpYWdub3N0aWMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIFdBUk5JTkc6CiAgICAgICAgICAgICAgICBpZiAoZW1pdFdhcm5pbmdzIHx8IGRpYWdub3N0aWMuaXNNYW5kYXRvcnkoKSkgewogICAgICAgICAgICAgICAgICAgIGlmIChud2FybmluZ3MgPCBNYXhXYXJuaW5ncykgewogICAgICAgICAgICAgICAgICAgICAgICB3cml0ZURpYWdub3N0aWMoZGlhZ25vc3RpYyk7CiAgICAgICAgICAgICAgICAgICAgICAgIG53YXJuaW5ncysrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBFUlJPUjoKICAgICAgICAgICAgICAgIGlmIChuZXJyb3JzIDwgTWF4RXJyb3JzICYmCiAgICAgICAgICAgICAgICAgICAgKGRpYWdub3N0aWMuaXNGbGFnU2V0KERpYWdub3N0aWNGbGFnLk1VTFRJUExFKSB8fAogICAgICAgICAgICAgICAgICAgICBzaG91bGRSZXBvcnQoZGlhZ25vc3RpYykpKSB7CiAgICAgICAgICAgICAgICAgICAgd3JpdGVEaWFnbm9zdGljKGRpYWdub3N0aWMpOwogICAgICAgICAgICAgICAgICAgIG5lcnJvcnMrKzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChkaWFnbm9zdGljLmlzRmxhZ1NldChKQ0RpYWdub3N0aWMuRGlhZ25vc3RpY0ZsYWcuQ09NUFJFU1NFRCkpIHsKICAgICAgICAgICAgICAgIGNvbXByZXNzZWRPdXRwdXQgPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogV3JpdGUgb3V0IGEgZGlhZ25vc3RpYy4KICAgICAqLwogICAgcHJvdGVjdGVkIHZvaWQgd3JpdGVEaWFnbm9zdGljKEpDRGlhZ25vc3RpYyBkaWFnKSB7CiAgICAgICAgaWYgKGRpYWdMaXN0ZW5lciAhPSBudWxsKSB7CiAgICAgICAgICAgIGRpYWdMaXN0ZW5lci5yZXBvcnQoZGlhZyk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIFByaW50V3JpdGVyIHdyaXRlciA9IGdldFdyaXRlckZvckRpYWdub3N0aWNUeXBlKGRpYWcuZ2V0VHlwZSgpKTsKCiAgICAgICAgcHJpbnRSYXdMaW5lcyh3cml0ZXIsIGRpYWdGb3JtYXR0ZXIuZm9ybWF0KGRpYWcsIG1lc3NhZ2VzLmdldEN1cnJlbnRMb2NhbGUoKSkpOwoKICAgICAgICBpZiAocHJvbXB0T25FcnJvcikgewogICAgICAgICAgICBzd2l0Y2ggKGRpYWcuZ2V0VHlwZSgpKSB7CiAgICAgICAgICAgIGNhc2UgRVJST1I6CiAgICAgICAgICAgIGNhc2UgV0FSTklORzoKICAgICAgICAgICAgICAgIHByb21wdCgpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoZHVtcE9uRXJyb3IpCiAgICAgICAgICAgIG5ldyBSdW50aW1lRXhjZXB0aW9uKCkucHJpbnRTdGFja1RyYWNlKHdyaXRlcik7CgogICAgICAgIHdyaXRlci5mbHVzaCgpOwogICAgfQoKICAgIEBEZXByZWNhdGVkCiAgICBwcm90ZWN0ZWQgUHJpbnRXcml0ZXIgZ2V0V3JpdGVyRm9yRGlhZ25vc3RpY1R5cGUoRGlhZ25vc3RpY1R5cGUgZHQpIHsKICAgICAgICBzd2l0Y2ggKGR0KSB7CiAgICAgICAgY2FzZSBGUkFHTUVOVDoKICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwoKICAgICAgICBjYXNlIE5PVEU6CiAgICAgICAgICAgIHJldHVybiB3cml0ZXJzLmdldChXcml0ZXJLaW5kLk5PVElDRSk7CgogICAgICAgIGNhc2UgV0FSTklORzoKICAgICAgICAgICAgcmV0dXJuIHdyaXRlcnMuZ2V0KFdyaXRlcktpbmQuV0FSTklORyk7CgogICAgICAgIGNhc2UgRVJST1I6CiAgICAgICAgICAgIHJldHVybiB3cml0ZXJzLmdldChXcml0ZXJLaW5kLkVSUk9SKTsKCiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKiBGaW5kIGEgbG9jYWxpemVkIHN0cmluZyBpbiB0aGUgcmVzb3VyY2UgYnVuZGxlLgogICAgICogIEJlY2F1c2UgdGhpcyBtZXRob2QgaXMgc3RhdGljLCBpdCBpZ25vcmVzIHRoZSBsb2NhbGUuCiAgICAgKiAgVXNlIGxvY2FsaXplKGtleSwgYXJncykgd2hlbiBwb3NzaWJsZS4KICAgICAqICBAcGFyYW0ga2V5ICAgIFRoZSBrZXkgZm9yIHRoZSBsb2NhbGl6ZWQgc3RyaW5nLgogICAgICogIEBwYXJhbSBhcmdzICAgRmllbGRzIHRvIHN1YnN0aXR1dGUgaW50byB0aGUgc3RyaW5nLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBnZXRMb2NhbGl6ZWRTdHJpbmcoU3RyaW5nIGtleSwgT2JqZWN0IC4uLiBhcmdzKSB7CiAgICAgICAgcmV0dXJuIEphdmFjTWVzc2FnZXMuZ2V0RGVmYXVsdExvY2FsaXplZFN0cmluZyhQcmVmaXhLaW5kLkNPTVBJTEVSX01JU0Mua2V5KGtleSksIGFyZ3MpOwogICAgfQoKICAgIC8qKiBGaW5kIGEgbG9jYWxpemVkIHN0cmluZyBpbiB0aGUgcmVzb3VyY2UgYnVuZGxlLgogICAgICogIEBwYXJhbSBrZXkgICAgVGhlIGtleSBmb3IgdGhlIGxvY2FsaXplZCBzdHJpbmcuCiAgICAgKiAgQHBhcmFtIGFyZ3MgICBGaWVsZHMgdG8gc3Vic3RpdHV0ZSBpbnRvIHRoZSBzdHJpbmcuCiAgICAgKi8KICAgIHB1YmxpYyBTdHJpbmcgbG9jYWxpemUoU3RyaW5nIGtleSwgT2JqZWN0Li4uIGFyZ3MpIHsKICAgICAgICByZXR1cm4gbG9jYWxpemUoUHJlZml4S2luZC5DT01QSUxFUl9NSVNDLCBrZXksIGFyZ3MpOwogICAgfQoKICAgIHB1YmxpYyBTdHJpbmcgbG9jYWxpemUoSkNEaWFnbm9zdGljLkRpYWdub3N0aWNJbmZvIGRpYWdJbmZvKSB7CiAgICAgICAgaWYgKHVzZVJhd01lc3NhZ2VzKSB7CiAgICAgICAgICAgIHJldHVybiBkaWFnSW5mby5rZXkoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gbWVzc2FnZXMuZ2V0TG9jYWxpemVkU3RyaW5nKGRpYWdJbmZvLmtleSgpLCBkaWFnSW5mby5hcmdzKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqIEZpbmQgYSBsb2NhbGl6ZWQgc3RyaW5nIGluIHRoZSByZXNvdXJjZSBidW5kbGUuCiAgICAgKiAgQHBhcmFtIGtleSAgICBUaGUga2V5IGZvciB0aGUgbG9jYWxpemVkIHN0cmluZy4KICAgICAqICBAcGFyYW0gYXJncyAgIEZpZWxkcyB0byBzdWJzdGl0dXRlIGludG8gdGhlIHN0cmluZy4KICAgICAqLwogICAgcHVibGljIFN0cmluZyBsb2NhbGl6ZShQcmVmaXhLaW5kIHBrLCBTdHJpbmcga2V5LCBPYmplY3QuLi4gYXJncykgewogICAgICAgIGlmICh1c2VSYXdNZXNzYWdlcykKICAgICAgICAgICAgcmV0dXJuIHBrLmtleShrZXkpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgcmV0dXJuIG1lc3NhZ2VzLmdldExvY2FsaXplZFN0cmluZyhway5rZXkoa2V5KSwgYXJncyk7CiAgICB9CiAgICAvLyB3aGVyZQogICAgICAgIC8vIGJhY2tkb29yIGhvb2sgZm9yIHRlc3RpbmcsIHNob3VsZCB0cmFuc2l0aW9uIHRvIHVzZSAtWERyYXdEaWFnbm9zdGljcwogICAgICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gdXNlUmF3TWVzc2FnZXMgPSBmYWxzZTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogcmF3IGVycm9yIG1lc3NhZ2VzIHdpdGhvdXQgaW50ZXJuYXRpb25hbGl6YXRpb247IHVzZWQgZm9yIGV4cGVyaW1lbnRhdGlvbgogKiBhbmQgcXVpY2sgcHJvdG90eXBpbmcKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiAgICAvKiogcHJpbnQgYW4gZXJyb3Igb3Igd2FybmluZyBtZXNzYWdlOgogICAgICovCiAgICBwcml2YXRlIHZvaWQgcHJpbnRSYXdEaWFnKFByaW50V3JpdGVyIHB3LCBTdHJpbmcgcHJlZml4LCBpbnQgcG9zLCBTdHJpbmcgbXNnKSB7CiAgICAgICAgaWYgKHNvdXJjZSA9PSBudWxsIHx8IHBvcyA9PSBQb3NpdGlvbi5OT1BPUykgewogICAgICAgICAgICBwcmludFJhd0xpbmVzKHB3LCBwcmVmaXggKyBtc2cpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGludCBsaW5lID0gc291cmNlLmdldExpbmVOdW1iZXIocG9zKTsKICAgICAgICAgICAgSmF2YUZpbGVPYmplY3QgZmlsZSA9IHNvdXJjZS5nZXRGaWxlKCk7CiAgICAgICAgICAgIGlmIChmaWxlICE9IG51bGwpCiAgICAgICAgICAgICAgICBwcmludFJhd0xpbmVzKHB3LAogICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlLmdldE5hbWUoKSArICI6IiArCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpbmUgKyAiOiAiICsgbXNnKTsKICAgICAgICAgICAgcHJpbnRFcnJMaW5lKHBvcywgcHcpOwogICAgICAgIH0KICAgICAgICBwdy5mbHVzaCgpOwogICAgfQoKICAgIC8qKiByZXBvcnQgYW4gZXJyb3I6CiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHJhd0Vycm9yKGludCBwb3MsIFN0cmluZyBtc2cpIHsKICAgICAgICBQcmludFdyaXRlciBlcnJXcml0ZXIgPSB3cml0ZXJzLmdldChXcml0ZXJLaW5kLkVSUk9SKTsKICAgICAgICBpZiAobmVycm9ycyA8IE1heEVycm9ycyAmJiBzaG91bGRSZXBvcnQoY3VycmVudFNvdXJjZUZpbGUoKSwgcG9zKSkgewogICAgICAgICAgICBwcmludFJhd0RpYWcoZXJyV3JpdGVyLCAiZXJyb3I6ICIsIHBvcywgbXNnKTsKICAgICAgICAgICAgcHJvbXB0KCk7CiAgICAgICAgICAgIG5lcnJvcnMrKzsKICAgICAgICB9CiAgICAgICAgZXJyV3JpdGVyLmZsdXNoKCk7CiAgICB9CgogICAgLyoqIHJlcG9ydCBhIHdhcm5pbmc6CiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHJhd1dhcm5pbmcoaW50IHBvcywgU3RyaW5nIG1zZykgewogICAgICAgIFByaW50V3JpdGVyIHdhcm5Xcml0ZXIgPSB3cml0ZXJzLmdldChXcml0ZXJLaW5kLkVSUk9SKTsKICAgICAgICBpZiAobndhcm5pbmdzIDwgTWF4V2FybmluZ3MgJiYgZW1pdFdhcm5pbmdzKSB7CiAgICAgICAgICAgIHByaW50UmF3RGlhZyh3YXJuV3JpdGVyLCAid2FybmluZzogIiwgcG9zLCBtc2cpOwogICAgICAgIH0KICAgICAgICBwcm9tcHQoKTsKICAgICAgICBud2FybmluZ3MrKzsKICAgICAgICB3YXJuV3JpdGVyLmZsdXNoKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBTdHJpbmcgZm9ybWF0KFN0cmluZyBmbXQsIE9iamVjdC4uLiBhcmdzKSB7CiAgICAgICAgcmV0dXJuIFN0cmluZy5mb3JtYXQoKGphdmEudXRpbC5Mb2NhbGUpbnVsbCwgZm10LCBhcmdzKTsKICAgIH0KCn0KUEsDBAoAAAgAAAY7qUre8DU+lBYAAJQWAAAlAAAAY29tL3N1bi90b29scy9qYXZhYy91dGlsL09wdGlvbnMuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwMSwgMjAxNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWw7CgppbXBvcnQgamF2YS51dGlsLio7CgppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5tYWluLk9wdGlvbjsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLm1haW4uT3B0aW9uLio7CgovKiogQSB0YWJsZSBvZiBhbGwgY29tbWFuZC1saW5lIG9wdGlvbnMuCiAqICBJZiBhbiBvcHRpb24gaGFzIGFuIGFyZ3VtZW50LCB0aGUgb3B0aW9uIG5hbWUgaXMgbWFwcGVkIHRvIHRoZSBhcmd1bWVudC4KICogIElmIGEgc2V0IG9wdGlvbiBoYXMgbm8gYXJndW1lbnQsIGl0IGlzIG1hcHBlZCB0byBpdHNlbGYuCiAqCiAqICA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiAgSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93biByaXNrLgogKiAgVGhpcyBjb2RlIGFuZCBpdHMgaW50ZXJuYWwgaW50ZXJmYWNlcyBhcmUgc3ViamVjdCB0byBjaGFuZ2Ugb3IKICogIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj4KICovCnB1YmxpYyBjbGFzcyBPcHRpb25zIHsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDA7CgogICAgLyoqIFRoZSBjb250ZXh0IGtleSBmb3IgdGhlIG9wdGlvbnMuICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIENvbnRleHQuS2V5PE9wdGlvbnM+IG9wdGlvbnNLZXkgPSBuZXcgQ29udGV4dC5LZXk8PigpOwoKICAgIHByaXZhdGUgTGlua2VkSGFzaE1hcDxTdHJpbmcsU3RyaW5nPiB2YWx1ZXM7CgogICAgLyoqIEdldCB0aGUgT3B0aW9ucyBpbnN0YW5jZSBmb3IgdGhpcyBjb250ZXh0LiAqLwogICAgcHVibGljIHN0YXRpYyBPcHRpb25zIGluc3RhbmNlKENvbnRleHQgY29udGV4dCkgewogICAgICAgIE9wdGlvbnMgaW5zdGFuY2UgPSBjb250ZXh0LmdldChvcHRpb25zS2V5KTsKICAgICAgICBpZiAoaW5zdGFuY2UgPT0gbnVsbCkKICAgICAgICAgICAgaW5zdGFuY2UgPSBuZXcgT3B0aW9ucyhjb250ZXh0KTsKICAgICAgICByZXR1cm4gaW5zdGFuY2U7CiAgICB9CgogICAgcHJvdGVjdGVkIE9wdGlvbnMoQ29udGV4dCBjb250ZXh0KSB7Ci8vIERFQlVHR0lORyAtLSBVc2UgTGlua2VkSGFzaE1hcCBmb3IgcmVwcm9kdWNhYmlsaXR5CiAgICAgICAgdmFsdWVzID0gbmV3IExpbmtlZEhhc2hNYXA8PigpOwogICAgICAgIGNvbnRleHQucHV0KG9wdGlvbnNLZXksIHRoaXMpOwogICAgfQoKICAgIC8qKgogICAgICogR2V0IHRoZSB2YWx1ZSBmb3IgYW4gdW5kb2N1bWVudGVkIG9wdGlvbi4KICAgICAqLwogICAgcHVibGljIFN0cmluZyBnZXQoU3RyaW5nIG5hbWUpIHsKICAgICAgICByZXR1cm4gdmFsdWVzLmdldChuYW1lKTsKICAgIH0KCiAgICAvKioKICAgICAqIEdldCB0aGUgdmFsdWUgZm9yIGFuIG9wdGlvbi4KICAgICAqLwogICAgcHVibGljIFN0cmluZyBnZXQoT3B0aW9uIG9wdGlvbikgewogICAgICAgIHJldHVybiB2YWx1ZXMuZ2V0KG9wdGlvbi5wcmltYXJ5TmFtZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXQgdGhlIGJvb2xlYW4gdmFsdWUgZm9yIGFuIG9wdGlvbiwgcGF0dGVybmVkIGFmdGVyIEJvb2xlYW4uZ2V0Qm9vbGVhbiwKICAgICAqIGVzc2VudGlhbGx5IHdpbGwgcmV0dXJuIHRydWUsIGlmZiB0aGUgdmFsdWUgZXhpc3RzIGFuZCBpcyBzZXQgdG8gInRydWUiLgogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRCb29sZWFuKFN0cmluZyBuYW1lKSB7CiAgICAgICAgcmV0dXJuIGdldEJvb2xlYW4obmFtZSwgZmFsc2UpOwogICAgfQoKICAgIC8qKgogICAgICogR2V0IHRoZSBib29sZWFuIHdpdGggYSBkZWZhdWx0IHZhbHVlIGlmIHRoZSBvcHRpb24gaXMgbm90IHNldC4KICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gZ2V0Qm9vbGVhbihTdHJpbmcgbmFtZSwgYm9vbGVhbiBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBTdHJpbmcgdmFsdWUgPSBnZXQobmFtZSk7CiAgICAgICAgcmV0dXJuICh2YWx1ZSA9PSBudWxsKSA/IGRlZmF1bHRWYWx1ZSA6IEJvb2xlYW4ucGFyc2VCb29sZWFuKHZhbHVlKTsKICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrIGlmIHRoZSB2YWx1ZSBmb3IgYW4gdW5kb2N1bWVudGVkIG9wdGlvbiBoYXMgYmVlbiBzZXQuCiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGlzU2V0KFN0cmluZyBuYW1lKSB7CiAgICAgICAgcmV0dXJuICh2YWx1ZXMuZ2V0KG5hbWUpICE9IG51bGwpOwogICAgfQoKICAgIC8qKgogICAgICogQ2hlY2sgaWYgdGhlIHZhbHVlIGZvciBhbiBvcHRpb24gaGFzIGJlZW4gc2V0LgogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBpc1NldChPcHRpb24gb3B0aW9uKSB7CiAgICAgICAgcmV0dXJuICh2YWx1ZXMuZ2V0KG9wdGlvbi5wcmltYXJ5TmFtZSkgIT0gbnVsbCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDaGVjayBpZiB0aGUgdmFsdWUgZm9yIGEgY2hvaWNlIG9wdGlvbiBoYXMgYmVlbiBzZXQgdG8gYSBzcGVjaWZpYyB2YWx1ZS4KICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gaXNTZXQoT3B0aW9uIG9wdGlvbiwgU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgcmV0dXJuICh2YWx1ZXMuZ2V0KG9wdGlvbi5wcmltYXJ5TmFtZSArIHZhbHVlKSAhPSBudWxsKTsKICAgIH0KCiAgICAvKiogQ2hlY2sgaWYgdGhlIHZhbHVlIGZvciBhIGxpbnQgb3B0aW9uIGhhcyBiZWVuIGV4cGxpY2l0bHkgc2V0LCBlaXRoZXIgd2l0aCAtWGxpbnQ6b3B0CiAgICAgKiAgb3IgaWYgYWxsIGxpbnQgb3B0aW9ucyBoYXZlIGVuYWJsZWQgYW5kIHRoaXMgb25lIG5vdCBkaXNhYmxlZCB3aXRoIC1YbGludDotb3B0LgogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBpc0xpbnRTZXQoU3RyaW5nIHMpIHsKICAgICAgICAvLyByZXR1cm4gdHJ1ZSBpZiBlaXRoZXIgdGhlIHNwZWNpZmljIG9wdGlvbiBpcyBlbmFibGVkLCBvcgogICAgICAgIC8vIHRoZXkgYXJlIGFsbCBlbmFibGVkIHdpdGhvdXQgdGhlIHNwZWNpZmljIG9uZSBiZWluZwogICAgICAgIC8vIGRpc2FibGVkCiAgICAgICAgcmV0dXJuCiAgICAgICAgICAgIGlzU2V0KFhMSU5UX0NVU1RPTSwgcykgfHwKICAgICAgICAgICAgKGlzU2V0KFhMSU5UKSB8fCBpc1NldChYTElOVF9DVVNUT00sICJhbGwiKSkgJiYgaXNVbnNldChYTElOVF9DVVNUT00sICItIiArIHMpOwogICAgfQoKICAgIC8qKgogICAgICogQ2hlY2sgaWYgdGhlIHZhbHVlIGZvciBhbiB1bmRvY3VtZW50ZWQgb3B0aW9uIGhhcyBub3QgYmVlbiBzZXQuCiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGlzVW5zZXQoU3RyaW5nIG5hbWUpIHsKICAgICAgICByZXR1cm4gKHZhbHVlcy5nZXQobmFtZSkgPT0gbnVsbCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDaGVjayBpZiB0aGUgdmFsdWUgZm9yIGFuIG9wdGlvbiBoYXMgbm90IGJlZW4gc2V0LgogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBpc1Vuc2V0KE9wdGlvbiBvcHRpb24pIHsKICAgICAgICByZXR1cm4gKHZhbHVlcy5nZXQob3B0aW9uLnByaW1hcnlOYW1lKSA9PSBudWxsKTsKICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrIGlmIHRoZSB2YWx1ZSBmb3IgYSBjaG9pY2Ugb3B0aW9uIGhhcyBub3QgYmVlbiBzZXQgdG8gYSBzcGVjaWZpYyB2YWx1ZS4KICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gaXNVbnNldChPcHRpb24gb3B0aW9uLCBTdHJpbmcgdmFsdWUpIHsKICAgICAgICByZXR1cm4gKHZhbHVlcy5nZXQob3B0aW9uLnByaW1hcnlOYW1lICsgdmFsdWUpID09IG51bGwpOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHB1dChTdHJpbmcgbmFtZSwgU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgdmFsdWVzLnB1dChuYW1lLCB2YWx1ZSk7CiAgICB9CgogICAgcHVibGljIHZvaWQgcHV0KE9wdGlvbiBvcHRpb24sIFN0cmluZyB2YWx1ZSkgewogICAgICAgIHZhbHVlcy5wdXQob3B0aW9uLnByaW1hcnlOYW1lLCB2YWx1ZSk7CiAgICB9CgogICAgcHVibGljIHZvaWQgcHV0QWxsKE9wdGlvbnMgb3B0aW9ucykgewogICAgICAgIHZhbHVlcy5wdXRBbGwob3B0aW9ucy52YWx1ZXMpOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHJlbW92ZShTdHJpbmcgbmFtZSkgewogICAgICAgIHZhbHVlcy5yZW1vdmUobmFtZSk7CiAgICB9CgogICAgcHVibGljIFNldDxTdHJpbmc+IGtleVNldCgpIHsKICAgICAgICByZXR1cm4gdmFsdWVzLmtleVNldCgpOwogICAgfQoKICAgIHB1YmxpYyBpbnQgc2l6ZSgpIHsKICAgICAgICByZXR1cm4gdmFsdWVzLnNpemUoKTsKICAgIH0KCiAgICAvLyBsaWdodC13ZWlnaHQgbm90aWZpY2F0aW9uIG1lY2hhbmlzbQoKICAgIHByaXZhdGUgTGlzdDxSdW5uYWJsZT4gbGlzdGVuZXJzID0gTGlzdC5uaWwoKTsKCiAgICBwdWJsaWMgdm9pZCBhZGRMaXN0ZW5lcihSdW5uYWJsZSBsaXN0ZW5lcikgewogICAgICAgIGxpc3RlbmVycyA9IGxpc3RlbmVycy5wcmVwZW5kKGxpc3RlbmVyKTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCBub3RpZnlMaXN0ZW5lcnMoKSB7CiAgICAgICAgZm9yIChSdW5uYWJsZSByOiBsaXN0ZW5lcnMpCiAgICAgICAgICAgIHIucnVuKCk7CiAgICB9Cn0KUEsDBAoAAAgAANJ9TUrSF2+2DQkAAA0JAAAiAAAAY29tL3N1bi90b29scy9qYXZhYy91dGlsL1BhaXIuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMTk5OSwgMjAxMywgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWw7CgppbXBvcnQgamF2YS51dGlsLk9iamVjdHM7CgovKiogQSBnZW5lcmljIGNsYXNzIGZvciBwYWlycy4KICoKICogIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqICBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqICBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogKiAgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPgogKi8KcHVibGljIGNsYXNzIFBhaXI8QSwgQj4gewoKICAgIHB1YmxpYyBmaW5hbCBBIGZzdDsKICAgIHB1YmxpYyBmaW5hbCBCIHNuZDsKCiAgICBwdWJsaWMgUGFpcihBIGZzdCwgQiBzbmQpIHsKICAgICAgICB0aGlzLmZzdCA9IGZzdDsKICAgICAgICB0aGlzLnNuZCA9IHNuZDsKICAgIH0KCiAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewogICAgICAgIHJldHVybiAiUGFpclsiICsgZnN0ICsgIiwiICsgc25kICsgIl0iOwogICAgfQoKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb3RoZXIpIHsKICAgICAgICByZXR1cm4KICAgICAgICAgICAgb3RoZXIgaW5zdGFuY2VvZiBQYWlyPD8sPz4gJiYKICAgICAgICAgICAgT2JqZWN0cy5lcXVhbHMoZnN0LCAoKFBhaXI8Pyw/PilvdGhlcikuZnN0KSAmJgogICAgICAgICAgICBPYmplY3RzLmVxdWFscyhzbmQsICgoUGFpcjw/LD8+KW90aGVyKS5zbmQpOwogICAgfQoKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgICAgaWYgKGZzdCA9PSBudWxsKSByZXR1cm4gKHNuZCA9PSBudWxsKSA/IDAgOiBzbmQuaGFzaENvZGUoKSArIDE7CiAgICAgICAgZWxzZSBpZiAoc25kID09IG51bGwpIHJldHVybiBmc3QuaGFzaENvZGUoKSArIDI7CiAgICAgICAgZWxzZSByZXR1cm4gZnN0Lmhhc2hDb2RlKCkgKiAxNyArIHNuZC5oYXNoQ29kZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgPEEsQj4gUGFpcjxBLEI+IG9mKEEgYSwgQiBiKSB7CiAgICAgICAgcmV0dXJuIG5ldyBQYWlyPD4oYSxiKTsKICAgIH0KfQpQSwMECgAACAAA0n1NSjeZy6ZBGQAAQRkAAC0AAABjb20vc3VuL3Rvb2xzL2phdmFjL3V0aWwvU2hhcmVkTmFtZVRhYmxlLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDE5OTksIDIwMTIsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhYy51dGlsOwoKaW1wb3J0IGphdmEubGFuZy5yZWYuU29mdFJlZmVyZW5jZTsKCmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuRGVmaW5lZEJ5LkFwaTsKCi8qKgogKiBJbXBsZW1lbnRhdGlvbiBvZiBOYW1lLlRhYmxlIHRoYXQgc3RvcmVzIGFsbCBuYW1lcyBpbiBhIHNpbmdsZSBzaGFyZWQKICogYnl0ZSBhcnJheSwgZXhwYW5kaW5nIGl0IGFzIG5lZWRlZC4gVGhpcyBhdm9pZHMgdGhlIG92ZXJoZWFkIGluY3VycmVkCiAqIGJ5IHVzaW5nIGFuIGFycmF5IG9mIGJ5dGVzIGZvciBlYWNoIG5hbWUuCiAqCiAqICA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiAgSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93biByaXNrLgogKiAgVGhpcyBjb2RlIGFuZCBpdHMgaW50ZXJuYWwgaW50ZXJmYWNlcyBhcmUgc3ViamVjdCB0byBjaGFuZ2Ugb3IKICogIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj4KICovCnB1YmxpYyBjbGFzcyBTaGFyZWROYW1lVGFibGUgZXh0ZW5kcyBOYW1lLlRhYmxlIHsKICAgIC8vIG1haW50YWluIGEgZnJlZWxpc3Qgb2YgcmVjZW50bHkgdXNlZCBuYW1lIHRhYmxlcyBmb3IgcmV1c2UuCiAgICBwcml2YXRlIHN0YXRpYyBMaXN0PFNvZnRSZWZlcmVuY2U8U2hhcmVkTmFtZVRhYmxlPj4gZnJlZWxpc3QgPSBMaXN0Lm5pbCgpOwoKICAgIHN0YXRpYyBwdWJsaWMgc3luY2hyb25pemVkIFNoYXJlZE5hbWVUYWJsZSBjcmVhdGUoTmFtZXMgbmFtZXMpIHsKICAgICAgICB3aGlsZSAoZnJlZWxpc3Qubm9uRW1wdHkoKSkgewogICAgICAgICAgICBTaGFyZWROYW1lVGFibGUgdCA9IGZyZWVsaXN0LmhlYWQuZ2V0KCk7CiAgICAgICAgICAgIGZyZWVsaXN0ID0gZnJlZWxpc3QudGFpbDsKICAgICAgICAgICAgaWYgKHQgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHQ7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIG5ldyBTaGFyZWROYW1lVGFibGUobmFtZXMpOwogICAgfQoKICAgIHN0YXRpYyBwcml2YXRlIHN5bmNocm9uaXplZCB2b2lkIGRpc3Bvc2UoU2hhcmVkTmFtZVRhYmxlIHQpIHsKICAgICAgICBmcmVlbGlzdCA9IGZyZWVsaXN0LnByZXBlbmQobmV3IFNvZnRSZWZlcmVuY2U8Pih0KSk7CiAgICB9CgogICAgLyoqIFRoZSBoYXNoIHRhYmxlIGZvciBuYW1lcy4KICAgICAqLwogICAgcHJpdmF0ZSBOYW1lSW1wbFtdIGhhc2hlczsKCiAgICAvKiogVGhlIHNoYXJlZCBieXRlIGFycmF5IGhvbGRpbmcgYWxsIGVuY291bnRlcmVkIG5hbWVzLgogICAgICovCiAgICBwdWJsaWMgYnl0ZVtdIGJ5dGVzOwoKICAgIC8qKiBUaGUgbWFzayB0byBiZSB1c2VkIGZvciBoYXNoaW5nCiAgICAgKi8KICAgIHByaXZhdGUgaW50IGhhc2hNYXNrOwoKICAgIC8qKiBUaGUgbnVtYmVyIG9mIGZpbGxlZCBieXRlcyBpbiBgbmFtZXMnLgogICAgICovCiAgICBwcml2YXRlIGludCBuYyA9IDA7CgogICAgLyoqIEFsbG9jYXRvcgogICAgICogIEBwYXJhbSBuYW1lcyBUaGUgbWFpbiBuYW1lIHRhYmxlCiAgICAgKiAgQHBhcmFtIGhhc2hTaXplIHRoZSAoY29uc3RhbnQpIHNpemUgdG8gYmUgdXNlZCBmb3IgdGhlIGhhc2ggdGFibGUKICAgICAqICAgICAgICAgICAgICAgICAgbmVlZHMgdG8gYmUgYSBwb3dlciBvZiB0d28uCiAgICAgKiAgQHBhcmFtIG5hbWVTaXplIHRoZSBpbml0aWFsIHNpemUgb2YgdGhlIG5hbWUgdGFibGUuCiAgICAgKi8KICAgIHB1YmxpYyBTaGFyZWROYW1lVGFibGUoTmFtZXMgbmFtZXMsIGludCBoYXNoU2l6ZSwgaW50IG5hbWVTaXplKSB7CiAgICAgICAgc3VwZXIobmFtZXMpOwogICAgICAgIGhhc2hNYXNrID0gaGFzaFNpemUgLSAxOwogICAgICAgIGhhc2hlcyA9IG5ldyBOYW1lSW1wbFtoYXNoU2l6ZV07CiAgICAgICAgYnl0ZXMgPSBuZXcgYnl0ZVtuYW1lU2l6ZV07CgogICAgfQoKICAgIHB1YmxpYyBTaGFyZWROYW1lVGFibGUoTmFtZXMgbmFtZXMpIHsKICAgICAgICB0aGlzKG5hbWVzLCAweDgwMDAsIDB4MjAwMDApOwogICAgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIE5hbWUgZnJvbUNoYXJzKGNoYXJbXSBjcywgaW50IHN0YXJ0LCBpbnQgbGVuKSB7CiAgICAgICAgaW50IG5jID0gdGhpcy5uYzsKICAgICAgICBieXRlW10gYnl0ZXMgPSB0aGlzLmJ5dGVzID0gQXJyYXlVdGlscy5lbnN1cmVDYXBhY2l0eSh0aGlzLmJ5dGVzLCBuYyArIGxlbiAqIDMpOwogICAgICAgIGludCBuYnl0ZXMgPSBDb252ZXJ0LmNoYXJzMnV0Zihjcywgc3RhcnQsIGJ5dGVzLCBuYywgbGVuKSAtIG5jOwogICAgICAgIGludCBoID0gaGFzaFZhbHVlKGJ5dGVzLCBuYywgbmJ5dGVzKSAmIGhhc2hNYXNrOwogICAgICAgIE5hbWVJbXBsIG4gPSBoYXNoZXNbaF07CiAgICAgICAgd2hpbGUgKG4gIT0gbnVsbCAmJgogICAgICAgICAgICAgICAgKG4uZ2V0Qnl0ZUxlbmd0aCgpICE9IG5ieXRlcyB8fAogICAgICAgICAgICAgICAgIWVxdWFscyhieXRlcywgbi5pbmRleCwgYnl0ZXMsIG5jLCBuYnl0ZXMpKSkgewogICAgICAgICAgICBuID0gbi5uZXh0OwogICAgICAgIH0KICAgICAgICBpZiAobiA9PSBudWxsKSB7CiAgICAgICAgICAgIG4gPSBuZXcgTmFtZUltcGwodGhpcyk7CiAgICAgICAgICAgIG4uaW5kZXggPSBuYzsKICAgICAgICAgICAgbi5sZW5ndGggPSBuYnl0ZXM7CiAgICAgICAgICAgIG4ubmV4dCA9IGhhc2hlc1toXTsKICAgICAgICAgICAgaGFzaGVzW2hdID0gbjsKICAgICAgICAgICAgdGhpcy5uYyA9IG5jICsgbmJ5dGVzOwogICAgICAgICAgICBpZiAobmJ5dGVzID09IDApIHsKICAgICAgICAgICAgICAgIHRoaXMubmMrKzsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gbjsKICAgIH0KCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBOYW1lIGZyb21VdGYoYnl0ZVtdIGNzLCBpbnQgc3RhcnQsIGludCBsZW4pIHsKICAgICAgICBpbnQgaCA9IGhhc2hWYWx1ZShjcywgc3RhcnQsIGxlbikgJiBoYXNoTWFzazsKICAgICAgICBOYW1lSW1wbCBuID0gaGFzaGVzW2hdOwogICAgICAgIGJ5dGVbXSBuYW1lcyA9IHRoaXMuYnl0ZXM7CiAgICAgICAgd2hpbGUgKG4gIT0gbnVsbCAmJgogICAgICAgICAgICAgICAgKG4uZ2V0Qnl0ZUxlbmd0aCgpICE9IGxlbiB8fCAhZXF1YWxzKG5hbWVzLCBuLmluZGV4LCBjcywgc3RhcnQsIGxlbikpKSB7CiAgICAgICAgICAgIG4gPSBuLm5leHQ7CiAgICAgICAgfQogICAgICAgIGlmIChuID09IG51bGwpIHsKICAgICAgICAgICAgaW50IG5jID0gdGhpcy5uYzsKICAgICAgICAgICAgbmFtZXMgPSB0aGlzLmJ5dGVzID0gQXJyYXlVdGlscy5lbnN1cmVDYXBhY2l0eShuYW1lcywgbmMgKyBsZW4pOwogICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGNzLCBzdGFydCwgbmFtZXMsIG5jLCBsZW4pOwogICAgICAgICAgICBuID0gbmV3IE5hbWVJbXBsKHRoaXMpOwogICAgICAgICAgICBuLmluZGV4ID0gbmM7CiAgICAgICAgICAgIG4ubGVuZ3RoID0gbGVuOwogICAgICAgICAgICBuLm5leHQgPSBoYXNoZXNbaF07CiAgICAgICAgICAgIGhhc2hlc1toXSA9IG47CiAgICAgICAgICAgIHRoaXMubmMgPSBuYyArIGxlbjsKICAgICAgICAgICAgaWYgKGxlbiA9PSAwKSB7CiAgICAgICAgICAgICAgICB0aGlzLm5jKys7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIG47CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCBkaXNwb3NlKCkgewogICAgICAgIGRpc3Bvc2UodGhpcyk7CiAgICB9CgogICAgc3RhdGljIGNsYXNzIE5hbWVJbXBsIGV4dGVuZHMgTmFtZSB7CiAgICAgICAgLyoqIFRoZSBuZXh0IG5hbWUgb2NjdXB5aW5nIHRoZSBzYW1lIGhhc2ggYnVja2V0LgogICAgICAgICAqLwogICAgICAgIE5hbWVJbXBsIG5leHQ7CgogICAgICAgIC8qKiBUaGUgaW5kZXggd2hlcmUgdGhlIGJ5dGVzIG9mIHRoaXMgbmFtZSBhcmUgc3RvcmVkIGluIHRoZSBnbG9iYWwgbmFtZQogICAgICAgICAqICBidWZmZXIgYGJ5dGUnLgogICAgICAgICAqLwogICAgICAgIGludCBpbmRleDsKCiAgICAgICAgLyoqIFRoZSBudW1iZXIgb2YgYnl0ZXMgaW4gdGhpcyBuYW1lLgogICAgICAgICAqLwogICAgICAgIGludCBsZW5ndGg7CgogICAgICAgIE5hbWVJbXBsKFNoYXJlZE5hbWVUYWJsZSB0YWJsZSkgewogICAgICAgICAgICBzdXBlcih0YWJsZSk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgaW50IGdldEluZGV4KCkgewogICAgICAgICAgICByZXR1cm4gaW5kZXg7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgaW50IGdldEJ5dGVMZW5ndGgoKSB7CiAgICAgICAgICAgIHJldHVybiBsZW5ndGg7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgYnl0ZSBnZXRCeXRlQXQoaW50IGkpIHsKICAgICAgICAgICAgcmV0dXJuIGdldEJ5dGVBcnJheSgpW2luZGV4ICsgaV07CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgYnl0ZVtdIGdldEJ5dGVBcnJheSgpIHsKICAgICAgICAgICAgcmV0dXJuICgoU2hhcmVkTmFtZVRhYmxlKSB0YWJsZSkuYnl0ZXM7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgaW50IGdldEJ5dGVPZmZzZXQoKSB7CiAgICAgICAgICAgIHJldHVybiBpbmRleDsKICAgICAgICB9CgogICAgICAgIC8qKiBSZXR1cm4gdGhlIGhhc2ggdmFsdWUgb2YgdGhpcyBuYW1lLgogICAgICAgICAqLwogICAgICAgIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgICAgICAgIHJldHVybiBpbmRleDsKICAgICAgICB9CgogICAgICAgIC8qKiBJcyB0aGlzIG5hbWUgZXF1YWwgdG8gb3RoZXI/CiAgICAgICAgICovCiAgICAgICAgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICAgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvdGhlcikgewogICAgICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBOYW1lKQogICAgICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgICAgICAgICAgICAgdGFibGUgPT0gKChOYW1lKW90aGVyKS50YWJsZSAmJiBpbmRleCA9PSAoKE5hbWUpIG90aGVyKS5nZXRJbmRleCgpOwogICAgICAgICAgICBlbHNlIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgfQoKfQpQSwMECgAACAAA0n1NSq4FIZDxBgAA8QYAACMAAABjb20vc3VuL3Rvb2xzL2phdmFjL3V0aWwvQWJvcnQuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMTk5OSwgMjAwNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWw7CgovKiogVGhyb3dpbmcgYW4gaW5zdGFuY2Ugb2YKICogIHRoaXMgY2xhc3MgY2F1c2VzIChzaWxlbnQpIHRlcm1pbmF0aW9uIG9mIHRoZSBtYWluIGNvbXBpbGVyIG1ldGhvZC4KICoKICogIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqICBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqICBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogKiAgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPgogKi8KcHVibGljIGNsYXNzIEFib3J0IGV4dGVuZHMgRXJyb3IgewogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMDsKCiAgICBwdWJsaWMgQWJvcnQoVGhyb3dhYmxlIGNhdXNlKSB7CiAgICAgICAgc3VwZXIoY2F1c2UpOwogICAgfQoKICAgIHB1YmxpYyBBYm9ydCgpIHsKICAgICAgICBzdXBlcigpOwogICAgfQoKfQpQSwMECgAACAAA0n1NSjzaFOH6FAAA+hQAAC8AAABjb20vc3VuL3Rvb2xzL2phdmFjL3V0aWwvVW5zaGFyZWROYW1lVGFibGUuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMTk5OSwgMjAxMywgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWw7CgppbXBvcnQgamF2YS5sYW5nLnJlZi5XZWFrUmVmZXJlbmNlOwoKLyoqCiAqIEltcGxlbWVudGF0aW9uIG9mIE5hbWUuVGFibGUgdGhhdCBzdG9yZXMgbmFtZXMgaW4gaW5kaXZpZHVhbCBhcnJheXMKICogdXNpbmcgd2VhayByZWZlcmVuY2VzLiBJdCBpcyByZWNvbW1lbmRlZCBmb3IgdXNlIHdoZW4gYSBzaW5nbGUgc2hhcmVkCiAqIGJ5dGUgYXJyYXkgaXMgdW5zdWl0YWJsZS4KICoKICogIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqICBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqICBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogKiAgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPgogKi8KcHVibGljIGNsYXNzIFVuc2hhcmVkTmFtZVRhYmxlIGV4dGVuZHMgTmFtZS5UYWJsZSB7CiAgICBzdGF0aWMgcHVibGljIE5hbWUuVGFibGUgY3JlYXRlKE5hbWVzIG5hbWVzKSB7CiAgICAgICAgcmV0dXJuIG5ldyBVbnNoYXJlZE5hbWVUYWJsZShuYW1lcyk7CiAgICB9CgogICAgc3RhdGljIGNsYXNzIEhhc2hFbnRyeSBleHRlbmRzIFdlYWtSZWZlcmVuY2U8TmFtZUltcGw+IHsKICAgICAgICBIYXNoRW50cnkgbmV4dDsKICAgICAgICBIYXNoRW50cnkoTmFtZUltcGwgcmVmZXJlbnQpIHsKICAgICAgICAgICAgc3VwZXIocmVmZXJlbnQpOwogICAgICAgIH0KICAgIH0KCiAgICAvKiogVGhlIGhhc2ggdGFibGUgZm9yIG5hbWVzLgogICAgICovCiAgICBwcml2YXRlIEhhc2hFbnRyeVtdIGhhc2hlcyA9IG51bGw7CgogICAgLyoqIFRoZSBtYXNrIHRvIGJlIHVzZWQgZm9yIGhhc2hpbmcKICAgICAqLwogICAgcHJpdmF0ZSBpbnQgaGFzaE1hc2s7CgogICAgLyoqIEluZGV4IGNvdW50ZXIgZm9yIG5hbWVzIGluIHRoaXMgdGFibGUuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgaW5kZXg7CgogICAgLyoqIEFsbG9jYXRvcgogICAgICogIEBwYXJhbSBuYW1lcyBUaGUgbWFpbiBuYW1lIHRhYmxlCiAgICAgKiAgQHBhcmFtIGhhc2hTaXplIHRoZSAoY29uc3RhbnQpIHNpemUgdG8gYmUgdXNlZCBmb3IgdGhlIGhhc2ggdGFibGUKICAgICAqICAgICAgICAgICAgICAgICAgbmVlZHMgdG8gYmUgYSBwb3dlciBvZiB0d28uCiAgICAgKi8KICAgIHB1YmxpYyBVbnNoYXJlZE5hbWVUYWJsZShOYW1lcyBuYW1lcywgaW50IGhhc2hTaXplKSB7CiAgICAgICAgc3VwZXIobmFtZXMpOwogICAgICAgIGhhc2hNYXNrID0gaGFzaFNpemUgLSAxOwogICAgICAgIGhhc2hlcyA9IG5ldyBIYXNoRW50cnlbaGFzaFNpemVdOwogICAgfQoKICAgIHB1YmxpYyBVbnNoYXJlZE5hbWVUYWJsZShOYW1lcyBuYW1lcykgewogICAgICAgIHRoaXMobmFtZXMsIDB4ODAwMCk7CiAgICB9CgoKICAgIEBPdmVycmlkZQogICAgcHVibGljIE5hbWUgZnJvbUNoYXJzKGNoYXJbXSBjcywgaW50IHN0YXJ0LCBpbnQgbGVuKSB7CiAgICAgICAgYnl0ZVtdIG5hbWUgPSBuZXcgYnl0ZVtsZW4gKiAzXTsKICAgICAgICBpbnQgbmJ5dGVzID0gQ29udmVydC5jaGFyczJ1dGYoY3MsIHN0YXJ0LCBuYW1lLCAwLCBsZW4pOwogICAgICAgIHJldHVybiBmcm9tVXRmKG5hbWUsIDAsIG5ieXRlcyk7CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgTmFtZSBmcm9tVXRmKGJ5dGVbXSBjcywgaW50IHN0YXJ0LCBpbnQgbGVuKSB7CiAgICAgICAgaW50IGggPSBoYXNoVmFsdWUoY3MsIHN0YXJ0LCBsZW4pICYgaGFzaE1hc2s7CgogICAgICAgIEhhc2hFbnRyeSBlbGVtZW50ID0gaGFzaGVzW2hdOwoKICAgICAgICBOYW1lSW1wbCBuID0gbnVsbDsKCiAgICAgICAgSGFzaEVudHJ5IHByZXZpb3VzTm9uTnVsbFRhYmxlRW50cnkgPSBudWxsOwogICAgICAgIEhhc2hFbnRyeSBmaXJzdFRhYmxlRW50cnkgPSBlbGVtZW50OwoKICAgICAgICB3aGlsZSAoZWxlbWVudCAhPSBudWxsKSB7CiAgICAgICAgICAgIGlmIChlbGVtZW50ID09IG51bGwpIHsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CgogICAgICAgICAgICBuID0gZWxlbWVudC5nZXQoKTsKCiAgICAgICAgICAgIGlmIChuID09IG51bGwpIHsKICAgICAgICAgICAgICAgIGlmIChmaXJzdFRhYmxlRW50cnkgPT0gZWxlbWVudCkgewogICAgICAgICAgICAgICAgICAgIGhhc2hlc1toXSA9IGZpcnN0VGFibGVFbnRyeSA9IGVsZW1lbnQubmV4dDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgIEFzc2VydC5jaGVja05vbk51bGwocHJldmlvdXNOb25OdWxsVGFibGVFbnRyeSwgInByZXZpb3VzTm9uTnVsbFRhYmxlRW50cnkgY2Fubm90IGJlIG51bGwgaGVyZS4iKTsKICAgICAgICAgICAgICAgICAgICBwcmV2aW91c05vbk51bGxUYWJsZUVudHJ5Lm5leHQgPSBlbGVtZW50Lm5leHQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICBpZiAobi5nZXRCeXRlTGVuZ3RoKCkgPT0gbGVuICYmIGVxdWFscyhuLmJ5dGVzLCAwLCBjcywgc3RhcnQsIGxlbikpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHByZXZpb3VzTm9uTnVsbFRhYmxlRW50cnkgPSBlbGVtZW50OwogICAgICAgICAgICB9CgogICAgICAgICAgICBlbGVtZW50ID0gZWxlbWVudC5uZXh0OwogICAgICAgIH0KCiAgICAgICAgYnl0ZVtdIGJ5dGVzID0gbmV3IGJ5dGVbbGVuXTsKICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGNzLCBzdGFydCwgYnl0ZXMsIDAsIGxlbik7CiAgICAgICAgbiA9IG5ldyBOYW1lSW1wbCh0aGlzLCBieXRlcywgaW5kZXgrKyk7CgogICAgICAgIEhhc2hFbnRyeSBuZXdFbnRyeSA9IG5ldyBIYXNoRW50cnkobik7CgogICAgICAgIGlmIChwcmV2aW91c05vbk51bGxUYWJsZUVudHJ5ID09IG51bGwpIHsgLy8gV2UgYXJlIG5vdCB0aGUgZmlyc3QgbmFtZSB3aXRoIHRoYXQgaGFzaENvZGUuCiAgICAgICAgICAgIGhhc2hlc1toXSA9IG5ld0VudHJ5OwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgQXNzZXJ0LmNoZWNrTnVsbChwcmV2aW91c05vbk51bGxUYWJsZUVudHJ5Lm5leHQsICJwcmV2aW91c05vbk51bGxUYWJsZUVudHJ5Lm5leHQgbXVzdCBiZSBudWxsLiIpOwogICAgICAgICAgICBwcmV2aW91c05vbk51bGxUYWJsZUVudHJ5Lm5leHQgPSBuZXdFbnRyeTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBuOwogICAgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIHZvaWQgZGlzcG9zZSgpIHsKICAgICAgICBoYXNoZXMgPSBudWxsOwogICAgfQoKICAgIHN0YXRpYyBjbGFzcyBOYW1lSW1wbCBleHRlbmRzIE5hbWUgewogICAgICAgIE5hbWVJbXBsKFVuc2hhcmVkTmFtZVRhYmxlIHRhYmxlLCBieXRlW10gYnl0ZXMsIGludCBpbmRleCkgewogICAgICAgICAgICBzdXBlcih0YWJsZSk7CiAgICAgICAgICAgIHRoaXMuYnl0ZXMgPSBieXRlczsKICAgICAgICAgICAgdGhpcy5pbmRleCA9IGluZGV4OwogICAgICAgIH0KCiAgICAgICAgZmluYWwgYnl0ZVtdIGJ5dGVzOwogICAgICAgIGZpbmFsIGludCBpbmRleDsKCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIGludCBnZXRJbmRleCgpIHsKICAgICAgICAgICAgcmV0dXJuIGluZGV4OwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIGludCBnZXRCeXRlTGVuZ3RoKCkgewogICAgICAgICAgICByZXR1cm4gYnl0ZXMubGVuZ3RoOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIGJ5dGUgZ2V0Qnl0ZUF0KGludCBpKSB7CiAgICAgICAgICAgIHJldHVybiBieXRlc1tpXTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBieXRlW10gZ2V0Qnl0ZUFycmF5KCkgewogICAgICAgICAgICByZXR1cm4gYnl0ZXM7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgaW50IGdldEJ5dGVPZmZzZXQoKSB7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KCiAgICB9Cgp9ClBLAwQKAAAIAADSfU1Ka7ujVGQHAABkBwAAMQAAAGNvbS9zdW4vdG9vbHMvamF2YWMvdXRpbC9Qcm9wYWdhdGVkRXhjZXB0aW9uLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhYy51dGlsOwoKLyoqCiAqIFVzZWQgdG8gcHJvcGFnYXRlIGV4Y2VwdGlvbnMgdGhyb3VnaCB0byB0aGUgdXNlci4KICoKICogPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93bgogKiByaXNrLiAgVGhpcyBjb2RlIGFuZCBpdHMgaW50ZXJuYWwgaW50ZXJmYWNlcyBhcmUgc3ViamVjdCB0byBjaGFuZ2UKICogb3IgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPjwvcD4KICoKICogQGF1dGhvciBQZXRlciB2b24gZGVyIEFoXHUwMGU5CiAqLwpwdWJsaWMgY2xhc3MgUHJvcGFnYXRlZEV4Y2VwdGlvbiBleHRlbmRzIFJ1bnRpbWVFeGNlcHRpb24gewoKICAgIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtNjA2NTMwOTMzOTg4ODc3NTM2N0w7CgogICAgcHVibGljIFByb3BhZ2F0ZWRFeGNlcHRpb24oUnVudGltZUV4Y2VwdGlvbiBjYXVzZSkgewogICAgICAgIHN1cGVyKGNhdXNlKTsKICAgIH0KCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSdW50aW1lRXhjZXB0aW9uIGdldENhdXNlKCkgewogICAgICAgIHJldHVybiAoUnVudGltZUV4Y2VwdGlvbilzdXBlci5nZXRDYXVzZSgpOwogICAgfQp9ClBLAwQKAAAIAADSfU1K4kXGiWAIAABgCAAAJwAAAGNvbS9zdW4vdG9vbHMvamF2YWMvdXRpbC9EZWZpbmVkQnkuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAxNCwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWw7CgppbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uRWxlbWVudFR5cGU7CmltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5SZXRlbnRpb247CmltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5SZXRlbnRpb25Qb2xpY3k7CmltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5UYXJnZXQ7CgovKipNZXRob2RzIHRoYXQgZGlyZWN0bHkgaW1wbGVtZW50IGEgbWV0aG9kIGRlY2xhcmVkIGluIGEgcHVibGljLCBzdXBwb3J0ZWQgQVBJIHNob3VsZCBiZSBtYXJrZWQKICogd2l0aCB0aGlzIGFubm90YXRpb24uCiAqLwpAVGFyZ2V0KEVsZW1lbnRUeXBlLk1FVEhPRCkKQFJldGVudGlvbihSZXRlbnRpb25Qb2xpY3kuU09VUkNFKQpwdWJsaWMgQGludGVyZmFjZSBEZWZpbmVkQnkgewoKICAgIC8qKlRoZSBBUEkgd2hpY2ggZGVmaW5lcyB0aGUgaW1wbGVtZW50ZWQgbWV0aG9kLgogICAgICovCiAgICBBcGkgdmFsdWUoKTsKCiAgICBwdWJsaWMgZW51bSBBcGkgewogICAgICAgIEFOTk9UQVRJT05fUFJPQ0VTU0lORygiamF2YXguYW5ub3RhdGlvbi5wcm9jZXNzaW5nIiksCiAgICAgICAgQ09NUElMRVIoImphdmF4LnRvb2xzIiksCiAgICAgICAgQ09NUElMRVJfVFJFRSgiY29tLnN1bi5zb3VyY2UiKSwKICAgICAgICBMQU5HVUFHRV9NT0RFTCgiamF2YXgubGFuZy5tb2RlbCIpOwoKICAgICAgICAvKipUaGUgcGFja2FnZSB1bmRlciB3aGljaCBhbGwgaW50ZXJmYWNlcy9jbGFzc2VzIG9mIHRoaXMgQVBJIGJlbG9uZy4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgZmluYWwgU3RyaW5nIHBhY2thZ2VSb290OwoKICAgICAgICBwcml2YXRlIEFwaShTdHJpbmcgcGFja2FnZVJvb3QpIHsKICAgICAgICAgICAgdGhpcy5wYWNrYWdlUm9vdCA9IHBhY2thZ2VSb290OwogICAgICAgIH0KCiAgICB9Cn0KUEsDBAoAAAgAANJ9TUrMsYq4MCsAADArAAA1AAAAY29tL3N1bi90b29scy9qYXZhYy91dGlsL01hbmRhdG9yeVdhcm5pbmdIYW5kbGVyLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMTQsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhYy51dGlsOwoKaW1wb3J0IGphdmEudXRpbC5IYXNoU2V0OwppbXBvcnQgamF2YS51dGlsLlNldDsKaW1wb3J0IGphdmF4LnRvb2xzLkphdmFGaWxlT2JqZWN0OwoKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5MaW50LkxpbnRDYXRlZ29yeTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5KQ0RpYWdub3N0aWMuRGlhZ25vc3RpY1Bvc2l0aW9uOwoKCi8qKgogKiBBIGhhbmRsZXIgdG8gcHJvY2VzcyBtYW5kYXRvcnkgd2FybmluZ3MsIHNldHRpbmcgdXAgYSBkZWZlcnJlZCBkaWFnbm9zdGljCiAqIHRvIGJlIHByaW50ZWQgYXQgdGhlIGVuZCBvZiB0aGUgY29tcGlsYXRpb24gaWYgc29tZSB3YXJuaW5ncyBnZXQgc3VwcHJlc3NlZAogKiBiZWNhdXNlIHRvbyBtYW55IHdhcm5pbmdzIGhhdmUgYWxyZWFkeSBiZWVuIGdlbmVyYXRlZC4KICoKICogTm90ZSB0aGF0IHRoZSBTdXBwcmVzc1dhcm5pbmdzIGFubm90YXRpb24gY2FuIGJlIHVzZWQgdG8gc3VwcHJlc3Mgd2FybmluZ3MKICogYWJvdXQgY29uZGl0aW9ucyB0aGF0IHdvdWxkIG90aGVyd2lzZSBtZXJpdCBhIHdhcm5pbmcuIFN1Y2ggcHJvY2Vzc2luZwogKiBpcyBkb25lIHdoZW4gdGhlIGNvbmRpdGlvbiBpcyBkZXRlY3RlZCwgYW5kIGluIHRob3NlIGNhc2VzLCBubyBjYWxsIGlzCiAqIG1hZGUgb24gYW55IEFQSSB0byBnZW5lcmF0ZSBhIHdhcm5pbmcgYXQgYWxsLiBJbiBjb25zZXF1ZW5jZSwgdGhpcyBoYW5kbGVyIG9ubHkKICogUmV0dXJucyB0byBoYW5kbGUgdGhvc2Ugd2FybmluZ3MgdGhhdCBKTFMgc2F5cyBtdXN0IGJlIGdlbmVyYXRlZC4KICoKICogIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqICBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqICBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogKiAgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPgogKi8KcHVibGljIGNsYXNzIE1hbmRhdG9yeVdhcm5pbmdIYW5kbGVyIHsKCiAgICAvKioKICAgICAqIFRoZSBraW5kcyBvZiBkaWZmZXJlbnQgZGVmZXJyZWQgZGlhZ25vc3RpY3MgdGhhdCBtaWdodCBiZSBnZW5lcmF0ZWQKICAgICAqIGlmIGEgbWFuZGF0b3J5IHdhcm5pbmcgaXMgc3VwcHJlc3NlZCBiZWNhdXNlIHRvbyBtYW55IHdhcm5pbmdzIGhhdmUKICAgICAqIGFscmVhZHkgYmVlbiBvdXRwdXQuCiAgICAgKgogICAgICogVGhlIHBhcmFtZXRlciBpcyBhIGZyYWdtZW50IHVzZWQgdG8gYnVpbGQgYW4gSTE4TiBtZXNzYWdlIGtleSBmb3IgTG9nLgogICAgICovCiAgICBwcml2YXRlIGVudW0gRGVmZXJyZWREaWFnbm9zdGljS2luZCB7CiAgICAgICAgLyoqCiAgICAgICAgICogVGhpcyBraW5kIGlzIHVzZWQgd2hlbiBhIHNpbmdsZSBzcGVjaWZpYyBmaWxlIGlzIGZvdW5kIHRvIGhhdmUgd2FybmluZ3MKICAgICAgICAgKiBhbmQgbm8gc2ltaWxhciB3YXJuaW5ncyBoYXZlIGFscmVhZHkgYmVlbiBnaXZlbi4KICAgICAgICAgKiBJdCBnZW5lcmF0ZXMgYSBtZXNzYWdlIGxpa2U6CiAgICAgICAgICogICAgICBGSUxFIGhhcyBJU1NVRVMKICAgICAgICAgKi8KICAgICAgICBJTl9GSUxFKCIuZmlsZW5hbWUiKSwKICAgICAgICAvKioKICAgICAgICAgKiBUaGlzIGtpbmQgaXMgdXNlZCB3aGVuIGEgc2luZ2xlIHNwZWNpZmljIGZpbGUgaXMgZm91bmQgdG8gaGF2ZSB3YXJuaW5ncwogICAgICAgICAqIGFuZCB3aGVuIHNpbWlsYXIgd2FybmluZ3MgaGF2ZSBhbHJlYWR5IGJlZW4gcmVwb3J0ZWQgZm9yIHRoZSBmaWxlLgogICAgICAgICAqIEl0IGdlbmVyYXRlcyBhIG1lc3NhZ2UgbGlrZToKICAgICAgICAgKiAgICAgIEZJTEUgaGFzIGFkZGl0aW9uYWwgSVNTVUVTCiAgICAgICAgICovCiAgICAgICAgQURESVRJT05BTF9JTl9GSUxFKCIuZmlsZW5hbWUuYWRkaXRpb25hbCIpLAogICAgICAgIC8qKgogICAgICAgICAqIFRoaXMga2luZCBpcyB1c2VkIHdoZW4gbXVsdGlwbGUgZmlsZXMgaGF2ZSBiZWVuIGZvdW5kIHRvIGhhdmUgd2FybmluZ3MsCiAgICAgICAgICogYW5kIG5vbmUgb2YgdGhlbSBoYXZlIGhhZCBhbnkgc2ltaWxhciB3YXJuaW5ncy4KICAgICAgICAgKiBJdCBnZW5lcmF0ZXMgYSBtZXNzYWdlIGxpa2U6CiAgICAgICAgICogICAgICBTb21lIGZpbGVzIGhhdmUgSVNTVUVTCiAgICAgICAgICovCiAgICAgICAgSU5fRklMRVMoIi5wbHVyYWwiKSwKICAgICAgICAvKioKICAgICAgICAgKiBUaGlzIGtpbmQgaXMgdXNlZCB3aGVuIG11bHRpcGxlIGZpbGVzIGhhdmUgYmVlbiBmb3VuZCB0byBoYXZlIHdhcm5pbmdzLAogICAgICAgICAqIGFuZCBzb21lIG9mIHRoZW0gaGF2ZSBoYWQgYWxyZWFkeSBoYWQgc3BlY2lmaWMgc2ltaWxhciB3YXJuaW5ncy4KICAgICAgICAgKiBJdCBnZW5lcmF0ZXMgYSBtZXNzYWdlIGxpa2U6CiAgICAgICAgICogICAgICBTb21lIGZpbGVzIGhhdmUgYWRkaXRpb25hbCBJU1NVRVMKICAgICAgICAgKi8KICAgICAgICBBRERJVElPTkFMX0lOX0ZJTEVTKCIucGx1cmFsLmFkZGl0aW9uYWwiKTsKCiAgICAgICAgRGVmZXJyZWREaWFnbm9zdGljS2luZChTdHJpbmcgdikgeyB2YWx1ZSA9IHY7IH0KICAgICAgICBTdHJpbmcgZ2V0S2V5KFN0cmluZyBwcmVmaXgpIHsgcmV0dXJuIHByZWZpeCArIHZhbHVlOyB9CgogICAgICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIHZhbHVlOwogICAgfQoKCiAgICAvKioKICAgICAqIENyZWF0ZSBhIGhhbmRsZXIgZm9yIG1hbmRhdG9yeSB3YXJuaW5ncy4KICAgICAqIEBwYXJhbSBsb2cgICAgIFRoZSBsb2cgb24gd2hpY2ggdG8gZ2VuZXJhdGUgYW55IGRpYWdub3N0aWNzCiAgICAgKiBAcGFyYW0gdmVyYm9zZSBTcGVjaWZ5IHdoZXRoZXIgb3Igbm90IGRldGFpbGVkIG1lc3NhZ2VzIGFib3V0CiAgICAgKiAgICAgICAgICAgICAgICBpbmRpdmlkdWFsIGluc3RhbmNlcyBzaG91bGQgYmUgZ2l2ZW4sIG9yIHdoZXRoZXIgYW4gYWdncmVnYXRlCiAgICAgKiAgICAgICAgICAgICAgICBtZXNzYWdlIHNob3VsZCBiZSBnZW5lcmF0ZWQgYXQgdGhlIGVuZCBvZiB0aGUgY29tcGlsYXRpb24uCiAgICAgKiAgICAgICAgICAgICAgICBUeXBpY2FsbHkgc2V0IHZpYSAgLVhsaW50Om9wdGlvbi4KICAgICAqIEBwYXJhbSBlbmZvcmNlTWFuZGF0b3J5CiAgICAgKiAgICAgICAgICAgICAgICBUcnVlIGlmIG1hbmRhdG9yeSB3YXJuaW5ncyBhbmQgbm90ZXMgYXJlIGJlaW5nIGVuZm9yY2VkLgogICAgICogQHBhcmFtIHByZWZpeCAgQSBjb21tb24gcHJlZml4IGZvciB0aGUgc2V0IG9mIG1lc3NhZ2Uga2V5cyBmb3IKICAgICAqICAgICAgICAgICAgICAgIHRoZSBtZXNzYWdlcyB0aGF0IG1heSBiZSBnZW5lcmF0ZWQuCiAgICAgKiBAcGFyYW0gbGMgICAgICBBbiBhc3NvY2lhdGVkIGxpbnQgY2F0ZWdvcnkgZm9yIHRoZSB3YXJuaW5ncywgb3IgbnVsbCBpZiBub25lLgogICAgICovCiAgICBwdWJsaWMgTWFuZGF0b3J5V2FybmluZ0hhbmRsZXIoTG9nIGxvZywgYm9vbGVhbiB2ZXJib3NlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gZW5mb3JjZU1hbmRhdG9yeSwgU3RyaW5nIHByZWZpeCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaW50Q2F0ZWdvcnkgbGMpIHsKICAgICAgICB0aGlzLmxvZyA9IGxvZzsKICAgICAgICB0aGlzLnZlcmJvc2UgPSB2ZXJib3NlOwogICAgICAgIHRoaXMucHJlZml4ID0gcHJlZml4OwogICAgICAgIHRoaXMuZW5mb3JjZU1hbmRhdG9yeSA9IGVuZm9yY2VNYW5kYXRvcnk7CiAgICAgICAgdGhpcy5saW50Q2F0ZWdvcnkgPSBsYzsKICAgIH0KCiAgICAvKioKICAgICAqIFJlcG9ydCBhIG1hbmRhdG9yeSB3YXJuaW5nLgogICAgICovCiAgICBwdWJsaWMgdm9pZCByZXBvcnQoRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcywgU3RyaW5nIG1zZywgT2JqZWN0Li4uIGFyZ3MpIHsKICAgICAgICBKYXZhRmlsZU9iamVjdCBjdXJyZW50U291cmNlID0gbG9nLmN1cnJlbnRTb3VyY2VGaWxlKCk7CgogICAgICAgIGlmICh2ZXJib3NlKSB7CiAgICAgICAgICAgIGlmIChzb3VyY2VzV2l0aFJlcG9ydGVkV2FybmluZ3MgPT0gbnVsbCkKICAgICAgICAgICAgICAgIHNvdXJjZXNXaXRoUmVwb3J0ZWRXYXJuaW5ncyA9IG5ldyBIYXNoU2V0PD4oKTsKCiAgICAgICAgICAgIGlmIChsb2cubndhcm5pbmdzIDwgbG9nLk1heFdhcm5pbmdzKSB7CiAgICAgICAgICAgICAgICAvLyBnZW5lcmF0ZSBtZXNzYWdlIGFuZCByZW1lbWJlciB0aGUgc291cmNlIGZpbGUKICAgICAgICAgICAgICAgIGxvZ01hbmRhdG9yeVdhcm5pbmcocG9zLCBtc2csIGFyZ3MpOwogICAgICAgICAgICAgICAgc291cmNlc1dpdGhSZXBvcnRlZFdhcm5pbmdzLmFkZChjdXJyZW50U291cmNlKTsKICAgICAgICAgICAgfSBlbHNlIGlmIChkZWZlcnJlZERpYWdub3N0aWNLaW5kID09IG51bGwpIHsKICAgICAgICAgICAgICAgIC8vIHNldCB1cCBkZWZlcnJlZCBtZXNzYWdlCiAgICAgICAgICAgICAgICBpZiAoc291cmNlc1dpdGhSZXBvcnRlZFdhcm5pbmdzLmNvbnRhaW5zKGN1cnJlbnRTb3VyY2UpKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gbW9yZSBlcnJvcnMgaW4gYSBmaWxlIHRoYXQgYWxyZWFkeSBoYXMgcmVwb3J0ZWQgd2FybmluZ3MKICAgICAgICAgICAgICAgICAgICBkZWZlcnJlZERpYWdub3N0aWNLaW5kID0gRGVmZXJyZWREaWFnbm9zdGljS2luZC5BRERJVElPTkFMX0lOX0ZJTEU7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIC8vIHdhcm5pbmdzIGluIGEgbmV3IHNvdXJjZSBmaWxlCiAgICAgICAgICAgICAgICAgICAgZGVmZXJyZWREaWFnbm9zdGljS2luZCA9IERlZmVycmVkRGlhZ25vc3RpY0tpbmQuSU5fRklMRTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGRlZmVycmVkRGlhZ25vc3RpY1NvdXJjZSA9IGN1cnJlbnRTb3VyY2U7CiAgICAgICAgICAgICAgICBkZWZlcnJlZERpYWdub3N0aWNBcmcgPSBjdXJyZW50U291cmNlOwogICAgICAgICAgICB9IGVsc2UgaWYgKChkZWZlcnJlZERpYWdub3N0aWNLaW5kID09IERlZmVycmVkRGlhZ25vc3RpY0tpbmQuSU5fRklMRQogICAgICAgICAgICAgICAgICAgICAgICB8fCBkZWZlcnJlZERpYWdub3N0aWNLaW5kID09IERlZmVycmVkRGlhZ25vc3RpY0tpbmQuQURESVRJT05BTF9JTl9GSUxFKQogICAgICAgICAgICAgICAgICAgICAgICYmICFlcXVhbChkZWZlcnJlZERpYWdub3N0aWNTb3VyY2UsIGN1cnJlbnRTb3VyY2UpKSB7CiAgICAgICAgICAgICAgICAvLyBhZGRpdGlvbmFsIGVycm9ycyBpbiBtb3JlIHRoYW4gb25lIHNvdXJjZSBmaWxlCiAgICAgICAgICAgICAgICBkZWZlcnJlZERpYWdub3N0aWNLaW5kID0gRGVmZXJyZWREaWFnbm9zdGljS2luZC5BRERJVElPTkFMX0lOX0ZJTEVTOwogICAgICAgICAgICAgICAgZGVmZXJyZWREaWFnbm9zdGljQXJnID0gbnVsbDsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGlmIChkZWZlcnJlZERpYWdub3N0aWNLaW5kID09IG51bGwpIHsKICAgICAgICAgICAgICAgIC8vIHdhcm5pbmdzIGluIGEgc2luZ2xlIHNvdXJjZQogICAgICAgICAgICAgICAgZGVmZXJyZWREaWFnbm9zdGljS2luZCA9IERlZmVycmVkRGlhZ25vc3RpY0tpbmQuSU5fRklMRTsKICAgICAgICAgICAgICAgIGRlZmVycmVkRGlhZ25vc3RpY1NvdXJjZSA9IGN1cnJlbnRTb3VyY2U7CiAgICAgICAgICAgICAgICBkZWZlcnJlZERpYWdub3N0aWNBcmcgPSBjdXJyZW50U291cmNlOwogICAgICAgICAgICB9ICBlbHNlIGlmIChkZWZlcnJlZERpYWdub3N0aWNLaW5kID09IERlZmVycmVkRGlhZ25vc3RpY0tpbmQuSU5fRklMRSAmJgogICAgICAgICAgICAgICAgICAgICAgICAhZXF1YWwoZGVmZXJyZWREaWFnbm9zdGljU291cmNlLCBjdXJyZW50U291cmNlKSkgewogICAgICAgICAgICAgICAgLy8gd2FybmluZ3MgaW4gbXVsdGlwbGUgc291cmNlIGZpbGVzCiAgICAgICAgICAgICAgICBkZWZlcnJlZERpYWdub3N0aWNLaW5kID0gRGVmZXJyZWREaWFnbm9zdGljS2luZC5JTl9GSUxFUzsKICAgICAgICAgICAgICAgIGRlZmVycmVkRGlhZ25vc3RpY0FyZyA9IG51bGw7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXBvcnQgYW55IGRpYWdub3N0aWMgdGhhdCBtaWdodCBoYXZlIGJlZW4gZGVmZXJyZWQgYnkgcHJldmlvdXMgY2FsbHMgb2YgcmVwb3J0KCkuCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHJlcG9ydERlZmVycmVkRGlhZ25vc3RpYygpIHsKICAgICAgICBpZiAoZGVmZXJyZWREaWFnbm9zdGljS2luZCAhPSBudWxsKSB7CiAgICAgICAgICAgIGlmIChkZWZlcnJlZERpYWdub3N0aWNBcmcgPT0gbnVsbCkKICAgICAgICAgICAgICAgIGxvZ01hbmRhdG9yeU5vdGUoZGVmZXJyZWREaWFnbm9zdGljU291cmNlLCBkZWZlcnJlZERpYWdub3N0aWNLaW5kLmdldEtleShwcmVmaXgpKTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgbG9nTWFuZGF0b3J5Tm90ZShkZWZlcnJlZERpYWdub3N0aWNTb3VyY2UsIGRlZmVycmVkRGlhZ25vc3RpY0tpbmQuZ2V0S2V5KHByZWZpeCksIGRlZmVycmVkRGlhZ25vc3RpY0FyZyk7CgogICAgICAgICAgICBpZiAoIXZlcmJvc2UpCiAgICAgICAgICAgICAgICBsb2dNYW5kYXRvcnlOb3RlKGRlZmVycmVkRGlhZ25vc3RpY1NvdXJjZSwgcHJlZml4ICsgIi5yZWNvbXBpbGUiKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBDaGVjayB0d28gb2JqZWN0cywgZWFjaCBwb3NzaWJseSBudWxsLCBhcmUgZWl0aGVyIGJvdGggbnVsbCBvciBhcmUgZXF1YWwuCiAgICAgKi8KICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gZXF1YWwoT2JqZWN0IG8xLCBPYmplY3QgbzIpIHsKICAgICAgICByZXR1cm4gKChvMSA9PSBudWxsIHx8IG8yID09IG51bGwpID8gKG8xID09IG8yKSA6IG8xLmVxdWFscyhvMikpOwogICAgfQoKICAgIC8qKgogICAgICogVGhlIGxvZyB0byB3aGljaCB0byByZXBvcnQgd2FybmluZ3MuCiAgICAgKi8KICAgIHByaXZhdGUgTG9nIGxvZzsKCiAgICAvKioKICAgICAqIFdoZXRoZXIgb3Igbm90IHRvIHJlcG9ydCBpbmRpdmlkdWFsIHdhcm5pbmdzLCBvciBzaW1wbHkgdG8gcmVwb3J0IGEKICAgICAqIHNpbmdsZSBhZ2dyZWdhdGUgd2FybmluZyBhdCB0aGUgZW5kIG9mIHRoZSBjb21waWxhdGlvbi4KICAgICAqLwogICAgcHJpdmF0ZSBib29sZWFuIHZlcmJvc2U7CgogICAgLyoqCiAgICAgKiBUaGUgY29tbW9uIHByZWZpeCBmb3IgYWxsIEkxOE4gbWVzc2FnZSBrZXlzIGdlbmVyYXRlZCBieSB0aGlzIGhhbmRsZXIuCiAgICAgKi8KICAgIHByaXZhdGUgU3RyaW5nIHByZWZpeDsKCiAgICAvKioKICAgICAqIEEgc2V0IGNvbnRhaW5pbmcgdGhlIG5hbWVzIG9mIHRoZSBzb3VyY2UgZmlsZXMgZm9yIHdoaWNoIHNwZWNpZmljCiAgICAgKiB3YXJuaW5ncyBoYXZlIGJlZW4gZ2VuZXJhdGVkIC0tIGkuZS4gaW4gdmVyYm9zZSBtb2RlLiAgSWYgYSBzb3VyY2UgbmFtZQogICAgICogYXBwZWFycyBpbiB0aGlzIGxpc3QsIHRoZW4gZGVmZXJyZWQgZGlhZ25vc3RpY3Mgd2lsbCBiZSBwaHJhc2VkIHRvCiAgICAgKiBpbmNsdWRlICJhZGRpdGlvbmFsbHkiLi4uCiAgICAgKi8KICAgIHByaXZhdGUgU2V0PEphdmFGaWxlT2JqZWN0PiBzb3VyY2VzV2l0aFJlcG9ydGVkV2FybmluZ3M7CgogICAgLyoqCiAgICAgKiBBIHZhcmlhYmxlIGluZGljYXRpbmcgdGhlIGxhdGVzdCBiZXN0IGd1ZXNzIGF0IHdoYXQgdGhlIGZpbmFsCiAgICAgKiBkZWZlcnJlZCBkaWFnbm9zdGljIHdpbGwgYmUuIEluaXRpYWxseSBhcyBzcGVjaWZpYyBhbmQgaGVscGZ1bAogICAgICogYXMgcG9zc2libGUsIGFzIG1vcmUgd2FybmluZ3MgYXJlIHJlcG9ydGVkLCB0aGUgc2NvcGUgb2YgdGhlCiAgICAgKiBkaWFnbm9zdGljIHdpbGwgYmUgYnJvYWRlbmVkLgogICAgICovCiAgICBwcml2YXRlIERlZmVycmVkRGlhZ25vc3RpY0tpbmQgZGVmZXJyZWREaWFnbm9zdGljS2luZDsKCiAgICAvKioKICAgICAqIElmIGRlZmVycmVkRGlhZ25vc3RpY0tpbmQgaXMgSU5fRklMRSBvciBBRERJVElPTkFMX0lOX0ZJTEUsIHRoaXMgdmFyaWFibGUKICAgICAqIGdpdmVzIHRoZSB2YWx1ZSBvZiBsb2cuY3VycmVudFNvdXJjZSgpIGZvciB0aGUgZmlsZSBpbiBxdWVzdGlvbi4KICAgICAqLwogICAgcHJpdmF0ZSBKYXZhRmlsZU9iamVjdCBkZWZlcnJlZERpYWdub3N0aWNTb3VyY2U7CgogICAgLyoqCiAgICAgKiBBbiBvcHRpb25hbCBhcmd1bWVudCB0byBiZSB1c2VkIHdoZW4gY29uc3RydWN0aW5nIHRoZQogICAgICogZGVmZXJyZWQgZGlhZ25vc3RpYyBtZXNzYWdlLCBiYXNlZCBvbiBkZWZlcnJlZERpYWdub3N0aWNLaW5kLgogICAgICogVGhpcyB2YXJpYWJsZSBzaG91bGQgbm9ybWFsbHkgYmUgc2V0L3VwZGF0ZWQgd2hlbmV2ZXIKICAgICAqIGRlZmVycmVkRGlhZ25vc3RpY0tpbmQgaXMgdXBkYXRlZC4KICAgICAqLwogICAgcHJpdmF0ZSBPYmplY3QgZGVmZXJyZWREaWFnbm9zdGljQXJnOwoKICAgIC8qKgogICAgICogVHJ1ZSBpZiBtYW5kYXRvcnkgd2FybmluZ3MgYW5kIG5vdGVzIGFyZSBiZWluZyBlbmZvcmNlZC4KICAgICAqLwogICAgcHJpdmF0ZSBmaW5hbCBib29sZWFuIGVuZm9yY2VNYW5kYXRvcnk7CgogICAgLyoqCiAgICAgKiBBIExpbnRDYXRlZ29yeSB0byBiZSBpbmNsdWRlZCBpbiBwb2ludC1vZi11c2UgZGlhZ25vc3RpY3MgdG8gaW5kaWNhdGUKICAgICAqIGhvdyBtZXNzYWdlcyBtaWdodCBiZSBzdXBwcmVzc2VkIChpLmUuIHdpdGggQFN1cHByZXNzV2FybmluZ3MpLgogICAgICovCiAgICBwcml2YXRlIGZpbmFsIExpbnRDYXRlZ29yeSBsaW50Q2F0ZWdvcnk7CgogICAgLyoqCiAgICAgKiBSZXBvcnRzIGEgbWFuZGF0b3J5IHdhcm5pbmcgdG8gdGhlIGxvZy4gIElmIG1hbmRhdG9yeSB3YXJuaW5ncwogICAgICogYXJlIG5vdCBiZWluZyBlbmZvcmNlZCwgdHJlYXQgdGhpcyBhcyBhbiBvcmRpbmFyeSB3YXJuaW5nLgogICAgICovCiAgICBwcml2YXRlIHZvaWQgbG9nTWFuZGF0b3J5V2FybmluZyhEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBTdHJpbmcgbXNnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT2JqZWN0Li4uIGFyZ3MpIHsKICAgICAgICAvLyBOb3RlOiB0aGUgZm9sbG93aW5nIGxvZyBtZXRob2RzIGFyZSBzYWZlIGlmIGxpbnRDYXRlZ29yeSBpcyBudWxsLgogICAgICAgIGlmIChlbmZvcmNlTWFuZGF0b3J5KQogICAgICAgICAgICBsb2cubWFuZGF0b3J5V2FybmluZyhsaW50Q2F0ZWdvcnksIHBvcywgbXNnLCBhcmdzKTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIGxvZy53YXJuaW5nKGxpbnRDYXRlZ29yeSwgcG9zLCBtc2csIGFyZ3MpOwogICAgfQoKICAgIC8qKgogICAgICogUmVwb3J0cyBhIG1hbmRhdG9yeSBub3RlIHRvIHRoZSBsb2cuICBJZiBtYW5kYXRvcnkgbm90ZXMgYXJlCiAgICAgKiBub3QgYmVpbmcgZW5mb3JjZWQsIHRyZWF0IHRoaXMgYXMgYW4gb3JkaW5hcnkgbm90ZS4KICAgICAqLwogICAgcHJpdmF0ZSB2b2lkIGxvZ01hbmRhdG9yeU5vdGUoSmF2YUZpbGVPYmplY3QgZmlsZSwgU3RyaW5nIG1zZywgT2JqZWN0Li4uIGFyZ3MpIHsKICAgICAgICBpZiAoZW5mb3JjZU1hbmRhdG9yeSkKICAgICAgICAgICAgbG9nLm1hbmRhdG9yeU5vdGUoZmlsZSwgbXNnLCBhcmdzKTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIGxvZy5ub3RlKGZpbGUsIG1zZywgYXJncyk7CiAgICB9Cn0KUEsDBAoAAAgAANJ9TUpiht1qXBQAAFwUAAAnAAAAY29tL3N1bi90b29scy9qYXZhYy91dGlsL0NvbnN0YW50cy5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDA1LCAyMDEyLCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuamF2YWMudXRpbDsKCmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuVHlwZTsKCi8qKgogKiBVdGlsaXRpZXMgZm9yIG9wZXJhdGluZyBvbiBjb25zdGFudCB2YWx1ZXMuCiAqCiAqIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24gcmlzay4KICogVGhpcyBjb2RlIGFuZCBpdHMgaW50ZXJuYWwgaW50ZXJmYWNlcyBhcmUgc3ViamVjdCB0byBjaGFuZ2Ugb3IKICogZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPgogKi8KcHVibGljIGNsYXNzIENvbnN0YW50cyB7CgogICAgLyoqCiAgICAgKiBDb252ZXJ0cyBhIGNvbnN0YW50IGluIGludGVybmFsIHJlcHJlc2VudGF0aW9uIChpbiB3aGljaAogICAgICogYm9vbGVhbiwgY2hhciwgYnl0ZSwgc2hvcnQsIGFuZCBpbnQgYXJlIGVhY2ggcmVwcmVzZW50ZWQgYnkgYW4KICAgICAqIEludGVnZXIpIGludG8gc3RhbmRhcmQgcmVwcmVzZW50YXRpb24uICBPdGhlciB2YWx1ZXMgKGluY2x1ZGluZwogICAgICogbnVsbCkgYXJlIHJldHVybmVkIHVuY2hhbmdlZC4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBPYmplY3QgZGVjb2RlKE9iamVjdCB2YWx1ZSwgVHlwZSB0eXBlKSB7CiAgICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgSW50ZWdlcikgewogICAgICAgICAgICBpbnQgaSA9IChJbnRlZ2VyKSB2YWx1ZTsKICAgICAgICAgICAgc3dpdGNoICh0eXBlLmdldFRhZygpKSB7CiAgICAgICAgICAgIGNhc2UgQk9PTEVBTjogIHJldHVybiBpICE9IDA7CiAgICAgICAgICAgIGNhc2UgQ0hBUjogICAgIHJldHVybiAoY2hhcikgaTsKICAgICAgICAgICAgY2FzZSBCWVRFOiAgICAgcmV0dXJuIChieXRlKSBpOwogICAgICAgICAgICBjYXNlIFNIT1JUOiAgICByZXR1cm4gKHNob3J0KSBpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiB2YWx1ZTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgYSBjb25zdGFudCB2YWx1ZSAoZ2l2ZW4gaW4KICAgICAqIGludGVybmFsIHJlcHJlc2VudGF0aW9uKSwgcXVvdGVkIGFuZCBmb3JtYXR0ZWQgYXMgaW4gSmF2YSBzb3VyY2UuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGZvcm1hdChPYmplY3QgdmFsdWUsIFR5cGUgdHlwZSkgewogICAgICAgIHZhbHVlID0gZGVjb2RlKHZhbHVlLCB0eXBlKTsKICAgICAgICBzd2l0Y2ggKHR5cGUuZ2V0VGFnKCkpIHsKICAgICAgICBjYXNlIEJZVEU6ICAgICAgcmV0dXJuIGZvcm1hdEJ5dGUoKEJ5dGUpIHZhbHVlKTsKICAgICAgICBjYXNlIExPTkc6ICAgICAgcmV0dXJuIGZvcm1hdExvbmcoKExvbmcpIHZhbHVlKTsKICAgICAgICBjYXNlIEZMT0FUOiAgICAgcmV0dXJuIGZvcm1hdEZsb2F0KChGbG9hdCkgdmFsdWUpOwogICAgICAgIGNhc2UgRE9VQkxFOiAgICByZXR1cm4gZm9ybWF0RG91YmxlKChEb3VibGUpIHZhbHVlKTsKICAgICAgICBjYXNlIENIQVI6ICAgICAgcmV0dXJuIGZvcm1hdENoYXIoKENoYXJhY3RlcikgdmFsdWUpOwogICAgICAgIH0KICAgICAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBTdHJpbmcpCiAgICAgICAgICAgIHJldHVybiBmb3JtYXRTdHJpbmcoKFN0cmluZykgdmFsdWUpOwogICAgICAgIHJldHVybiB2YWx1ZSArICIiOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBhIGNvbnN0YW50IHZhbHVlIChnaXZlbiBpbgogICAgICogc3RhbmRhcmQgd3JhcHBlZCByZXByZXNlbnRhdGlvbiksIHF1b3RlZCBhbmQgZm9ybWF0dGVkIGFzIGluCiAgICAgKiBKYXZhIHNvdXJjZS4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBTdHJpbmcgZm9ybWF0KE9iamVjdCB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIEJ5dGUpICAgICAgcmV0dXJuIGZvcm1hdEJ5dGUoKEJ5dGUpIHZhbHVlKTsKICAgICAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBTaG9ydCkgICAgIHJldHVybiBmb3JtYXRTaG9ydCgoU2hvcnQpIHZhbHVlKTsKICAgICAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBMb25nKSAgICAgIHJldHVybiBmb3JtYXRMb25nKChMb25nKSB2YWx1ZSk7CiAgICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgRmxvYXQpICAgICByZXR1cm4gZm9ybWF0RmxvYXQoKEZsb2F0KSB2YWx1ZSk7CiAgICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgRG91YmxlKSAgICByZXR1cm4gZm9ybWF0RG91YmxlKChEb3VibGUpIHZhbHVlKTsKICAgICAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBDaGFyYWN0ZXIpIHJldHVybiBmb3JtYXRDaGFyKChDaGFyYWN0ZXIpIHZhbHVlKTsKICAgICAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBTdHJpbmcpICAgIHJldHVybiBmb3JtYXRTdHJpbmcoKFN0cmluZykgdmFsdWUpOwogICAgICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIEludGVnZXIgfHwKICAgICAgICAgICAgdmFsdWUgaW5zdGFuY2VvZiBCb29sZWFuKSAgIHJldHVybiB2YWx1ZS50b1N0cmluZygpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiQXJndW1lbnQgaXMgbm90IGEgcHJpbWl0aXZlIHR5cGUgb3IgYSBzdHJpbmc7IGl0ICIgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgodmFsdWUgPT0gbnVsbCkgPwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiaXMgYSBudWxsIHZhbHVlLiIgOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiaGFzIGNsYXNzICIgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZS5nZXRDbGFzcygpLmdldE5hbWUoKSkgKyAiLiIgKTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgZm9ybWF0Qnl0ZShieXRlIGIpIHsKICAgICAgICByZXR1cm4gU3RyaW5nLmZvcm1hdCgiKGJ5dGUpMHglMDJ4IiwgYik7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIGZvcm1hdFNob3J0KHNob3J0IHMpIHsKICAgICAgICByZXR1cm4gU3RyaW5nLmZvcm1hdCgiKHNob3J0KSVkIiwgcyk7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIGZvcm1hdExvbmcobG9uZyBsbmcpIHsKICAgICAgICByZXR1cm4gbG5nICsgIkwiOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBmb3JtYXRGbG9hdChmbG9hdCBmKSB7CiAgICAgICAgaWYgKEZsb2F0LmlzTmFOKGYpKQogICAgICAgICAgICByZXR1cm4gIjAuMGYvMC4wZiI7CiAgICAgICAgZWxzZSBpZiAoRmxvYXQuaXNJbmZpbml0ZShmKSkKICAgICAgICAgICAgcmV0dXJuIChmIDwgMCkgPyAiLTEuMGYvMC4wZiIgOiAiMS4wZi8wLjBmIjsKICAgICAgICBlbHNlCiAgICAgICAgICAgIHJldHVybiBmICsgImYiOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBmb3JtYXREb3VibGUoZG91YmxlIGQpIHsKICAgICAgICBpZiAoRG91YmxlLmlzTmFOKGQpKQogICAgICAgICAgICByZXR1cm4gIjAuMC8wLjAiOwogICAgICAgIGVsc2UgaWYgKERvdWJsZS5pc0luZmluaXRlKGQpKQogICAgICAgICAgICByZXR1cm4gKGQgPCAwKSA/ICItMS4wLzAuMCIgOiAiMS4wLzAuMCI7CiAgICAgICAgZWxzZQogICAgICAgICAgICByZXR1cm4gZCArICIiOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBmb3JtYXRDaGFyKGNoYXIgYykgewogICAgICAgIHJldHVybiAnXCcnICsgQ29udmVydC5xdW90ZShjKSArICdcJyc7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIGZvcm1hdFN0cmluZyhTdHJpbmcgcykgewogICAgICAgIHJldHVybiAnIicgKyBDb252ZXJ0LnF1b3RlKHMpICsgJyInOwogICAgfQp9ClBLAwQKAAAIAAAGO6lKq6JgEiofAAAqHwAAKwAAAGNvbS9zdW4vdG9vbHMvamF2YWMvdXRpbC9KYXZhY01lc3NhZ2VzLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMTUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhYy51dGlsOwoKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuYXBpLk1lc3NhZ2VzOwppbXBvcnQgamF2YS5sYW5nLnJlZi5Tb2Z0UmVmZXJlbmNlOwppbXBvcnQgamF2YS51dGlsLlJlc291cmNlQnVuZGxlOwppbXBvcnQgamF2YS51dGlsLk1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbjsKaW1wb3J0IGphdmEudGV4dC5NZXNzYWdlRm9ybWF0OwppbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CmltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOwppbXBvcnQgamF2YS51dGlsLk1hcDsKCi8qKgogKiAgU3VwcG9ydCBmb3IgZm9ybWF0dGVkIGxvY2FsaXplZCBtZXNzYWdlcy4KICoKICogIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqICBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqICBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogKiAgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPgogKi8KcHVibGljIGNsYXNzIEphdmFjTWVzc2FnZXMgaW1wbGVtZW50cyBNZXNzYWdlcyB7CiAgICAvKiogVGhlIGNvbnRleHQga2V5IGZvciB0aGUgSmF2YWNNZXNzYWdlcyBvYmplY3QuICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIENvbnRleHQuS2V5PEphdmFjTWVzc2FnZXM+IG1lc3NhZ2VzS2V5ID0gbmV3IENvbnRleHQuS2V5PD4oKTsKCiAgICAvKiogR2V0IHRoZSBKYXZhY01lc3NhZ2VzIGluc3RhbmNlIGZvciB0aGlzIGNvbnRleHQuICovCiAgICBwdWJsaWMgc3RhdGljIEphdmFjTWVzc2FnZXMgaW5zdGFuY2UoQ29udGV4dCBjb250ZXh0KSB7CiAgICAgICAgSmF2YWNNZXNzYWdlcyBpbnN0YW5jZSA9IGNvbnRleHQuZ2V0KG1lc3NhZ2VzS2V5KTsKICAgICAgICBpZiAoaW5zdGFuY2UgPT0gbnVsbCkKICAgICAgICAgICAgaW5zdGFuY2UgPSBuZXcgSmF2YWNNZXNzYWdlcyhjb250ZXh0KTsKICAgICAgICByZXR1cm4gaW5zdGFuY2U7CiAgICB9CgogICAgcHJpdmF0ZSBNYXA8TG9jYWxlLCBTb2Z0UmVmZXJlbmNlPExpc3Q8UmVzb3VyY2VCdW5kbGU+Pj4gYnVuZGxlQ2FjaGU7CgogICAgcHJpdmF0ZSBMaXN0PFJlc291cmNlQnVuZGxlSGVscGVyPiBidW5kbGVIZWxwZXJzOwoKICAgIHByaXZhdGUgTG9jYWxlIGN1cnJlbnRMb2NhbGU7CiAgICBwcml2YXRlIExpc3Q8UmVzb3VyY2VCdW5kbGU+IGN1cnJlbnRCdW5kbGVzOwoKICAgIHB1YmxpYyBMb2NhbGUgZ2V0Q3VycmVudExvY2FsZSgpIHsKICAgICAgICByZXR1cm4gY3VycmVudExvY2FsZTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCBzZXRDdXJyZW50TG9jYWxlKExvY2FsZSBsb2NhbGUpIHsKICAgICAgICBpZiAobG9jYWxlID09IG51bGwpIHsKICAgICAgICAgICAgbG9jYWxlID0gTG9jYWxlLmdldERlZmF1bHQoKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5jdXJyZW50QnVuZGxlcyA9IGdldEJ1bmRsZXMobG9jYWxlKTsKICAgICAgICB0aGlzLmN1cnJlbnRMb2NhbGUgPSBsb2NhbGU7CiAgICB9CgogICAgLyoqIENyZWF0ZXMgYSBKYXZhY01lc3NhZ2VzIG9iamVjdC4KICAgICAqLwogICAgcHVibGljIEphdmFjTWVzc2FnZXMoQ29udGV4dCBjb250ZXh0KSB7CiAgICAgICAgdGhpcyhkZWZhdWx0QnVuZGxlTmFtZSwgY29udGV4dC5nZXQoTG9jYWxlLmNsYXNzKSk7CiAgICAgICAgY29udGV4dC5wdXQobWVzc2FnZXNLZXksIHRoaXMpOwogICAgfQoKICAgIC8qKiBDcmVhdGVzIGEgSmF2YWNNZXNzYWdlcyBvYmplY3QuCiAgICAgKiBAcGFyYW0gYnVuZGxlTmFtZSB0aGUgbmFtZSB0byBpZGVudGlmeSB0aGUgcmVzb3VyY2UgYnVuZGxlIG9mIGxvY2FsaXplZCBtZXNzYWdlcy4KICAgICAqLwogICAgcHVibGljIEphdmFjTWVzc2FnZXMoU3RyaW5nIGJ1bmRsZU5hbWUpIHRocm93cyBNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24gewogICAgICAgIHRoaXMoYnVuZGxlTmFtZSwgbnVsbCk7CiAgICB9CgogICAgLyoqIENyZWF0ZXMgYSBKYXZhY01lc3NhZ2VzIG9iamVjdC4KICAgICAqIEBwYXJhbSBidW5kbGVOYW1lIHRoZSBuYW1lIHRvIGlkZW50aWZ5IHRoZSByZXNvdXJjZSBidW5kbGUgb2YgbG9jYWxpemVkIG1lc3NhZ2VzLgogICAgICovCiAgICBwdWJsaWMgSmF2YWNNZXNzYWdlcyhTdHJpbmcgYnVuZGxlTmFtZSwgTG9jYWxlIGxvY2FsZSkgdGhyb3dzIE1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbiB7CiAgICAgICAgYnVuZGxlSGVscGVycyA9IExpc3QubmlsKCk7CiAgICAgICAgYnVuZGxlQ2FjaGUgPSBuZXcgSGFzaE1hcDw+KCk7CiAgICAgICAgYWRkKGJ1bmRsZU5hbWUpOwogICAgICAgIHNldEN1cnJlbnRMb2NhbGUobG9jYWxlKTsKICAgIH0KCiAgICBwdWJsaWMgSmF2YWNNZXNzYWdlcygpIHRocm93cyBNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24gewogICAgICAgIHRoaXMoZGVmYXVsdEJ1bmRsZU5hbWUpOwogICAgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIHZvaWQgYWRkKFN0cmluZyBidW5kbGVOYW1lKSB0aHJvd3MgTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uIHsKICAgICAgICBhZGQobG9jYWxlIC0+IFJlc291cmNlQnVuZGxlLmdldEJ1bmRsZShidW5kbGVOYW1lLCBsb2NhbGUpKTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCBhZGQoUmVzb3VyY2VCdW5kbGVIZWxwZXIgbWEpIHsKICAgICAgICBidW5kbGVIZWxwZXJzID0gYnVuZGxlSGVscGVycy5wcmVwZW5kKG1hKTsKICAgICAgICBpZiAoIWJ1bmRsZUNhY2hlLmlzRW1wdHkoKSkKICAgICAgICAgICAgYnVuZGxlQ2FjaGUuY2xlYXIoKTsKICAgICAgICBjdXJyZW50QnVuZGxlcyA9IG51bGw7CiAgICB9CgogICAgcHVibGljIExpc3Q8UmVzb3VyY2VCdW5kbGU+IGdldEJ1bmRsZXMoTG9jYWxlIGxvY2FsZSkgewogICAgICAgIGlmIChsb2NhbGUgPT0gY3VycmVudExvY2FsZSAmJiBjdXJyZW50QnVuZGxlcyAhPSBudWxsKQogICAgICAgICAgICByZXR1cm4gY3VycmVudEJ1bmRsZXM7CiAgICAgICAgU29mdFJlZmVyZW5jZTxMaXN0PFJlc291cmNlQnVuZGxlPj4gYnVuZGxlcyA9IGJ1bmRsZUNhY2hlLmdldChsb2NhbGUpOwogICAgICAgIExpc3Q8UmVzb3VyY2VCdW5kbGU+IGJ1bmRsZUxpc3QgPSBidW5kbGVzID09IG51bGwgPyBudWxsIDogYnVuZGxlcy5nZXQoKTsKICAgICAgICBpZiAoYnVuZGxlTGlzdCA9PSBudWxsKSB7CiAgICAgICAgICAgIGJ1bmRsZUxpc3QgPSBMaXN0Lm5pbCgpOwogICAgICAgICAgICBmb3IgKFJlc291cmNlQnVuZGxlSGVscGVyIGhlbHBlciA6IGJ1bmRsZUhlbHBlcnMpIHsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgUmVzb3VyY2VCdW5kbGUgcmIgPSBoZWxwZXIuZ2V0UmVzb3VyY2VCdW5kbGUobG9jYWxlKTsKICAgICAgICAgICAgICAgICAgICBidW5kbGVMaXN0ID0gYnVuZGxlTGlzdC5wcmVwZW5kKHJiKTsKICAgICAgICAgICAgICAgIH0gY2F0Y2ggKE1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoIkNhbm5vdCBmaW5kIHJlcXVlc3RlZCByZXNvdXJjZSBidW5kbGUgZm9yIGxvY2FsZSAiICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvY2FsZSwgZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnVuZGxlQ2FjaGUucHV0KGxvY2FsZSwgbmV3IFNvZnRSZWZlcmVuY2U8PihidW5kbGVMaXN0KSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidW5kbGVMaXN0OwogICAgfQoKICAgIC8qKiBHZXRzIHRoZSBsb2NhbGl6ZWQgc3RyaW5nIGNvcnJlc3BvbmRpbmcgdG8gYSBrZXksIGZvcm1hdHRlZCB3aXRoIGEgc2V0IG9mIGFyZ3MuCiAgICAgKi8KICAgIHB1YmxpYyBTdHJpbmcgZ2V0TG9jYWxpemVkU3RyaW5nKFN0cmluZyBrZXksIE9iamVjdC4uLiBhcmdzKSB7CiAgICAgICAgcmV0dXJuIGdldExvY2FsaXplZFN0cmluZyhjdXJyZW50TG9jYWxlLCBrZXksIGFyZ3MpOwogICAgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIFN0cmluZyBnZXRMb2NhbGl6ZWRTdHJpbmcoTG9jYWxlIGwsIFN0cmluZyBrZXksIE9iamVjdC4uLiBhcmdzKSB7CiAgICAgICAgaWYgKGwgPT0gbnVsbCkKICAgICAgICAgICAgbCA9IGdldEN1cnJlbnRMb2NhbGUoKTsKICAgICAgICByZXR1cm4gZ2V0TG9jYWxpemVkU3RyaW5nKGdldEJ1bmRsZXMobCksIGtleSwgYXJncyk7CiAgICB9CgogICAgLyogU3RhdGljIGFjY2VzczoKICAgICAqIGphdmFjIGhhcyBhIGZpcm1seSBlbnRyZW5jaGVkIG5vdGlvbiBvZiBhIGRlZmF1bHQgbWVzc2FnZSBidW5kbGUKICAgICAqIHdoaWNoIGl0IGNhbiBhY2Nlc3MgZnJvbSBhbnkgc3RhdGljIGNvbnRleHQuIFRoaXMgaXMgdXNlZCB0byBnZXQKICAgICAqIGVhc3kgYWNjZXNzIHRvIHNpbXBsZSBsb2NhbGl6ZWQgc3RyaW5ncy4KICAgICAqLwoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBkZWZhdWx0QnVuZGxlTmFtZSA9ICJjb20uc3VuLnRvb2xzLmphdmFjLnJlc291cmNlcy5jb21waWxlciI7CiAgICBwcml2YXRlIHN0YXRpYyBSZXNvdXJjZUJ1bmRsZSBkZWZhdWx0QnVuZGxlOwogICAgcHJpdmF0ZSBzdGF0aWMgSmF2YWNNZXNzYWdlcyBkZWZhdWx0TWVzc2FnZXM7CgoKICAgIC8qKgogICAgICogUmV0dXJucyBhIGxvY2FsaXplZCBzdHJpbmcgZnJvbSB0aGUgY29tcGlsZXIncyBkZWZhdWx0IGJ1bmRsZS4KICAgICAqLwogICAgLy8gdXNlZCB0byBzdXBwb3J0IGxlZ2FjeSBMb2cuZ2V0TG9jYWxpemVkU3RyaW5nCiAgICBzdGF0aWMgU3RyaW5nIGdldERlZmF1bHRMb2NhbGl6ZWRTdHJpbmcoU3RyaW5nIGtleSwgT2JqZWN0Li4uIGFyZ3MpIHsKICAgICAgICByZXR1cm4gZ2V0TG9jYWxpemVkU3RyaW5nKExpc3Qub2YoZ2V0RGVmYXVsdEJ1bmRsZSgpKSwga2V5LCBhcmdzKTsKICAgIH0KCiAgICAvLyB1c2VkIHRvIHN1cHBvcnQgbGVnYWN5IHN0YXRpYyBEaWFnbm9zdGljLmZyYWdtZW50CiAgICBARGVwcmVjYXRlZAogICAgc3RhdGljIEphdmFjTWVzc2FnZXMgZ2V0RGVmYXVsdE1lc3NhZ2VzKCkgewogICAgICAgIGlmIChkZWZhdWx0TWVzc2FnZXMgPT0gbnVsbCkKICAgICAgICAgICAgZGVmYXVsdE1lc3NhZ2VzID0gbmV3IEphdmFjTWVzc2FnZXMoZGVmYXVsdEJ1bmRsZU5hbWUpOwogICAgICAgIHJldHVybiBkZWZhdWx0TWVzc2FnZXM7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBSZXNvdXJjZUJ1bmRsZSBnZXREZWZhdWx0QnVuZGxlKCkgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGlmIChkZWZhdWx0QnVuZGxlID09IG51bGwpCiAgICAgICAgICAgICAgICBkZWZhdWx0QnVuZGxlID0gUmVzb3VyY2VCdW5kbGUuZ2V0QnVuZGxlKGRlZmF1bHRCdW5kbGVOYW1lKTsKICAgICAgICAgICAgcmV0dXJuIGRlZmF1bHRCdW5kbGU7CiAgICAgICAgfQogICAgICAgIGNhdGNoIChNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoIkZhdGFsOiBSZXNvdXJjZSBmb3IgY29tcGlsZXIgaXMgbWlzc2luZyIsIGUpOwogICAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgZ2V0TG9jYWxpemVkU3RyaW5nKExpc3Q8UmVzb3VyY2VCdW5kbGU+IGJ1bmRsZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBrZXksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9iamVjdC4uLiBhcmdzKSB7CiAgICAgICBTdHJpbmcgbXNnID0gbnVsbDsKICAgICAgIGZvciAoTGlzdDxSZXNvdXJjZUJ1bmRsZT4gbCA9IGJ1bmRsZXM7IGwubm9uRW1wdHkoKSAmJiBtc2cgPT0gbnVsbDsgbCA9IGwudGFpbCkgewogICAgICAgICAgIFJlc291cmNlQnVuZGxlIHJiID0gbC5oZWFkOwogICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgIG1zZyA9IHJiLmdldFN0cmluZyhrZXkpOwogICAgICAgICAgIH0KICAgICAgICAgICBjYXRjaCAoTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgICAgLy8gaWdub3JlLCB0cnkgb3RoZXIgYnVuZGxlcyBpbiBsaXN0CiAgICAgICAgICAgfQogICAgICAgfQogICAgICAgaWYgKG1zZyA9PSBudWxsKSB7CiAgICAgICAgICAgbXNnID0gImNvbXBpbGVyIG1lc3NhZ2UgZmlsZSBicm9rZW46IGtleT0iICsga2V5ICsKICAgICAgICAgICAgICAgIiBhcmd1bWVudHM9ezB9LCB7MX0sIHsyfSwgezN9LCB7NH0sIHs1fSwgezZ9LCB7N30iOwogICAgICAgfQogICAgICAgcmV0dXJuIE1lc3NhZ2VGb3JtYXQuZm9ybWF0KG1zZywgYXJncyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBUaGlzIHByb3ZpZGVzIGEgd2F5IGZvciB0aGUgSmF2YWNNZXNzYWdlciB0byByZXRyaWV2ZSBhCiAgICAgKiBSZXNvdXJjZUJ1bmRsZSBmcm9tIGFub3RoZXIgbW9kdWxlIHN1Y2ggYXMgamRrLmphdmFkb2MuCiAgICAgKi8KICAgIHB1YmxpYyBpbnRlcmZhY2UgUmVzb3VyY2VCdW5kbGVIZWxwZXIgewogICAgICAgIC8qKgogICAgICAgICAqIEdldHMgdGhlIFJlc291cmNlQnVuZGxlLgogICAgICAgICAqIEBwYXJhbSBsb2NhbGUgdGhlIHJlcXVlc3RlZCBidW5kbGUncyBsb2NhbGUKICAgICAgICAgKiBAcmV0dXJuIFJlc291cmNlQnVuZGxlCiAgICAgICAgICovCiAgICAgICAgUmVzb3VyY2VCdW5kbGUgZ2V0UmVzb3VyY2VCdW5kbGUoTG9jYWxlIGxvY2FsZSk7CiAgICB9Cn0KUEsDBAoAAAgAAAY7qUoaVAF0kjcAAJI3AAAjAAAAY29tL3N1bi90b29scy9qYXZhYy91dGlsL05hbWVzLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDE5OTksIDIwMTYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhYy51dGlsOwoKLyoqCiAqIEFjY2VzcyB0byB0aGUgY29tcGlsZXIncyBuYW1lIHRhYmxlLiAgU1RhbmRhcmQgbmFtZXMgYXJlIGRlZmluZWQsCiAqIGFzIHdlbGwgYXMgbWV0aG9kcyB0byBjcmVhdGUgbmV3IG5hbWVzLgogKgogKiAgPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24gcmlzay4KICogIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yCiAqICBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+CiAqLwpwdWJsaWMgY2xhc3MgTmFtZXMgewoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQ29udGV4dC5LZXk8TmFtZXM+IG5hbWVzS2V5ID0gbmV3IENvbnRleHQuS2V5PD4oKTsKCiAgICBwdWJsaWMgc3RhdGljIE5hbWVzIGluc3RhbmNlKENvbnRleHQgY29udGV4dCkgewogICAgICAgIE5hbWVzIGluc3RhbmNlID0gY29udGV4dC5nZXQobmFtZXNLZXkpOwogICAgICAgIGlmIChpbnN0YW5jZSA9PSBudWxsKSB7CiAgICAgICAgICAgIGluc3RhbmNlID0gbmV3IE5hbWVzKGNvbnRleHQpOwogICAgICAgICAgICBjb250ZXh0LnB1dChuYW1lc0tleSwgaW5zdGFuY2UpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gaW5zdGFuY2U7CiAgICB9CgogICAgLy8gb3BlcmF0b3JzIGFuZCBwdW5jdHVhdGlvbgogICAgcHVibGljIGZpbmFsIE5hbWUgYXN0ZXJpc2s7CiAgICBwdWJsaWMgZmluYWwgTmFtZSBjb21tYTsKICAgIHB1YmxpYyBmaW5hbCBOYW1lIGVtcHR5OwogICAgcHVibGljIGZpbmFsIE5hbWUgaHlwaGVuOwogICAgcHVibGljIGZpbmFsIE5hbWUgb25lOwogICAgcHVibGljIGZpbmFsIE5hbWUgcGVyaW9kOwogICAgcHVibGljIGZpbmFsIE5hbWUgc2VtaWNvbG9uOwogICAgcHVibGljIGZpbmFsIE5hbWUgc2xhc2g7CiAgICBwdWJsaWMgZmluYWwgTmFtZSBzbGFzaGVxdWFsczsKCiAgICAvLyBrZXl3b3JkcwogICAgcHVibGljIGZpbmFsIE5hbWUgX2NsYXNzOwogICAgcHVibGljIGZpbmFsIE5hbWUgX2RlZmF1bHQ7CiAgICBwdWJsaWMgZmluYWwgTmFtZSBfc3VwZXI7CiAgICBwdWJsaWMgZmluYWwgTmFtZSBfdGhpczsKICAgIHB1YmxpYyBmaW5hbCBOYW1lIGV4cG9ydHM7CiAgICBwdWJsaWMgZmluYWwgTmFtZSBvcGVuczsKICAgIHB1YmxpYyBmaW5hbCBOYW1lIG1vZHVsZTsKICAgIHB1YmxpYyBmaW5hbCBOYW1lIHByb3ZpZGVzOwogICAgcHVibGljIGZpbmFsIE5hbWUgcmVxdWlyZXM7CiAgICBwdWJsaWMgZmluYWwgTmFtZSB0bzsKICAgIHB1YmxpYyBmaW5hbCBOYW1lIHRyYW5zaXRpdmU7CiAgICBwdWJsaWMgZmluYWwgTmFtZSB1c2VzOwogICAgcHVibGljIGZpbmFsIE5hbWUgb3BlbjsKICAgIHB1YmxpYyBmaW5hbCBOYW1lIHdpdGg7CgogICAgLy8gZmllbGQgYW5kIG1ldGhvZCBuYW1lcwogICAgcHVibGljIGZpbmFsIE5hbWUgX25hbWU7CiAgICBwdWJsaWMgZmluYWwgTmFtZSBhZGRTdXBwcmVzc2VkOwogICAgcHVibGljIGZpbmFsIE5hbWUgYW55OwogICAgcHVibGljIGZpbmFsIE5hbWUgYXBwZW5kOwogICAgcHVibGljIGZpbmFsIE5hbWUgY2xpbml0OwogICAgcHVibGljIGZpbmFsIE5hbWUgY2xvbmU7CiAgICBwdWJsaWMgZmluYWwgTmFtZSBjbG9zZTsKICAgIHB1YmxpYyBmaW5hbCBOYW1lIGNvbXBhcmVUbzsKICAgIHB1YmxpYyBmaW5hbCBOYW1lIGRlc2VyaWFsaXplTGFtYmRhOwogICAgcHVibGljIGZpbmFsIE5hbWUgZGVzaXJlZEFzc2VydGlvblN0YXR1czsKICAgIHB1YmxpYyBmaW5hbCBOYW1lIGVxdWFsczsKICAgIHB1YmxpYyBmaW5hbCBOYW1lIGVycm9yOwogICAgcHVibGljIGZpbmFsIE5hbWUgZmFtaWx5OwogICAgcHVibGljIGZpbmFsIE5hbWUgZmluYWxpemU7CiAgICBwdWJsaWMgZmluYWwgTmFtZSBmb3JOYW1lOwogICAgcHVibGljIGZpbmFsIE5hbWUgZm9yUmVtb3ZhbDsKICAgIHB1YmxpYyBmaW5hbCBOYW1lIGdldENsYXNzOwogICAgcHVibGljIGZpbmFsIE5hbWUgZ2V0Q2xhc3NMb2FkZXI7CiAgICBwdWJsaWMgZmluYWwgTmFtZSBnZXRDb21wb25lbnRUeXBlOwogICAgcHVibGljIGZpbmFsIE5hbWUgZ2V0RGVjbGFyaW5nQ2xhc3M7CiAgICBwdWJsaWMgZmluYWwgTmFtZSBnZXRNZXNzYWdlOwogICAgcHVibGljIGZpbmFsIE5hbWUgaGFzTmV4dDsKICAgIHB1YmxpYyBmaW5hbCBOYW1lIGhhc2hDb2RlOwogICAgcHVibGljIGZpbmFsIE5hbWUgaW5pdDsKICAgIHB1YmxpYyBmaW5hbCBOYW1lIGluaXRDYXVzZTsKICAgIHB1YmxpYyBmaW5hbCBOYW1lIGl0ZXJhdG9yOwogICAgcHVibGljIGZpbmFsIE5hbWUgbGVuZ3RoOwogICAgcHVibGljIGZpbmFsIE5hbWUgbmV4dDsKICAgIHB1YmxpYyBmaW5hbCBOYW1lIG9yZGluYWw7CiAgICBwdWJsaWMgZmluYWwgTmFtZSBwcm92aWRlcjsKICAgIHB1YmxpYyBmaW5hbCBOYW1lIHNlcmlhbFZlcnNpb25VSUQ7CiAgICBwdWJsaWMgZmluYWwgTmFtZSB0b1N0cmluZzsKICAgIHB1YmxpYyBmaW5hbCBOYW1lIHZhbHVlOwogICAgcHVibGljIGZpbmFsIE5hbWUgdmFsdWVPZjsKICAgIHB1YmxpYyBmaW5hbCBOYW1lIHZhbHVlczsKCiAgICAvLyBjbGFzcyBuYW1lcwogICAgcHVibGljIGZpbmFsIE5hbWUgamF2YV9pb19TZXJpYWxpemFibGU7CiAgICBwdWJsaWMgZmluYWwgTmFtZSBqYXZhX2xhbmdfQXV0b0Nsb3NlYWJsZTsKICAgIHB1YmxpYyBmaW5hbCBOYW1lIGphdmFfbGFuZ19DbGFzczsKICAgIHB1YmxpYyBmaW5hbCBOYW1lIGphdmFfbGFuZ19DbG9uZWFibGU7CiAgICBwdWJsaWMgZmluYWwgTmFtZSBqYXZhX2xhbmdfRW51bTsKICAgIHB1YmxpYyBmaW5hbCBOYW1lIGphdmFfbGFuZ19PYmplY3Q7CiAgICBwdWJsaWMgZmluYWwgTmFtZSBqYXZhX2xhbmdfaW52b2tlX01ldGhvZEhhbmRsZTsKCiAgICAvLyBuYW1lcyBvZiBidWlsdGluIGNsYXNzZXMKICAgIHB1YmxpYyBmaW5hbCBOYW1lIEFycmF5OwogICAgcHVibGljIGZpbmFsIE5hbWUgQm91bmQ7CiAgICBwdWJsaWMgZmluYWwgTmFtZSBNZXRob2Q7CgogICAgLy8gcGFja2FnZSBuYW1lcwogICAgcHVibGljIGZpbmFsIE5hbWUgamF2YV9sYW5nOwoKICAgIC8vIG1vZHVsZSBuYW1lcwogICAgcHVibGljIGZpbmFsIE5hbWUgamF2YV9iYXNlOwoKICAgIC8vIGF0dHJpYnV0ZSBuYW1lcwogICAgcHVibGljIGZpbmFsIE5hbWUgQW5ub3RhdGlvbjsKICAgIHB1YmxpYyBmaW5hbCBOYW1lIEFubm90YXRpb25EZWZhdWx0OwogICAgcHVibGljIGZpbmFsIE5hbWUgQm9vdHN0cmFwTWV0aG9kczsKICAgIHB1YmxpYyBmaW5hbCBOYW1lIEJyaWRnZTsKICAgIHB1YmxpYyBmaW5hbCBOYW1lIENoYXJhY3RlclJhbmdlVGFibGU7CiAgICBwdWJsaWMgZmluYWwgTmFtZSBDb2RlOwogICAgcHVibGljIGZpbmFsIE5hbWUgQ29tcGlsYXRpb25JRDsKICAgIHB1YmxpYyBmaW5hbCBOYW1lIENvbnN0YW50VmFsdWU7CiAgICBwdWJsaWMgZmluYWwgTmFtZSBEZXByZWNhdGVkOwogICAgcHVibGljIGZpbmFsIE5hbWUgRW5jbG9zaW5nTWV0aG9kOwogICAgcHVibGljIGZpbmFsIE5hbWUgRW51bTsKICAgIHB1YmxpYyBmaW5hbCBOYW1lIEV4Y2VwdGlvbnM7CiAgICBwdWJsaWMgZmluYWwgTmFtZSBJbm5lckNsYXNzZXM7CiAgICBwdWJsaWMgZmluYWwgTmFtZSBMaW5lTnVtYmVyVGFibGU7CiAgICBwdWJsaWMgZmluYWwgTmFtZSBMb2NhbFZhcmlhYmxlVGFibGU7CiAgICBwdWJsaWMgZmluYWwgTmFtZSBMb2NhbFZhcmlhYmxlVHlwZVRhYmxlOwogICAgcHVibGljIGZpbmFsIE5hbWUgTWV0aG9kUGFyYW1ldGVyczsKICAgIHB1YmxpYyBmaW5hbCBOYW1lIE1vZHVsZTsKICAgIHB1YmxpYyBmaW5hbCBOYW1lIE1vZHVsZVJlc29sdXRpb247CiAgICBwdWJsaWMgZmluYWwgTmFtZSBSdW50aW1lSW52aXNpYmxlQW5ub3RhdGlvbnM7CiAgICBwdWJsaWMgZmluYWwgTmFtZSBSdW50aW1lSW52aXNpYmxlUGFyYW1ldGVyQW5ub3RhdGlvbnM7CiAgICBwdWJsaWMgZmluYWwgTmFtZSBSdW50aW1lSW52aXNpYmxlVHlwZUFubm90YXRpb25zOwogICAgcHVibGljIGZpbmFsIE5hbWUgUnVudGltZVZpc2libGVBbm5vdGF0aW9uczsKICAgIHB1YmxpYyBmaW5hbCBOYW1lIFJ1bnRpbWVWaXNpYmxlUGFyYW1ldGVyQW5ub3RhdGlvbnM7CiAgICBwdWJsaWMgZmluYWwgTmFtZSBSdW50aW1lVmlzaWJsZVR5cGVBbm5vdGF0aW9uczsKICAgIHB1YmxpYyBmaW5hbCBOYW1lIFNpZ25hdHVyZTsKICAgIHB1YmxpYyBmaW5hbCBOYW1lIFNvdXJjZUZpbGU7CiAgICBwdWJsaWMgZmluYWwgTmFtZSBTb3VyY2VJRDsKICAgIHB1YmxpYyBmaW5hbCBOYW1lIFN0YWNrTWFwOwogICAgcHVibGljIGZpbmFsIE5hbWUgU3RhY2tNYXBUYWJsZTsKICAgIHB1YmxpYyBmaW5hbCBOYW1lIFN5bnRoZXRpYzsKICAgIHB1YmxpYyBmaW5hbCBOYW1lIFZhbHVlOwogICAgcHVibGljIGZpbmFsIE5hbWUgVmFyYXJnczsKCiAgICAvLyBtZW1iZXJzIG9mIGphdmEubGFuZy5hbm5vdGF0aW9uLkVsZW1lbnRUeXBlCiAgICBwdWJsaWMgZmluYWwgTmFtZSBBTk5PVEFUSU9OX1RZUEU7CiAgICBwdWJsaWMgZmluYWwgTmFtZSBDT05TVFJVQ1RPUjsKICAgIHB1YmxpYyBmaW5hbCBOYW1lIEZJRUxEOwogICAgcHVibGljIGZpbmFsIE5hbWUgTE9DQUxfVkFSSUFCTEU7CiAgICBwdWJsaWMgZmluYWwgTmFtZSBNRVRIT0Q7CiAgICBwdWJsaWMgZmluYWwgTmFtZSBNT0RVTEU7CiAgICBwdWJsaWMgZmluYWwgTmFtZSBQQUNLQUdFOwogICAgcHVibGljIGZpbmFsIE5hbWUgUEFSQU1FVEVSOwogICAgcHVibGljIGZpbmFsIE5hbWUgVFlQRTsKICAgIHB1YmxpYyBmaW5hbCBOYW1lIFRZUEVfUEFSQU1FVEVSOwogICAgcHVibGljIGZpbmFsIE5hbWUgVFlQRV9VU0U7CgogICAgLy8gbWVtYmVycyBvZiBqYXZhLmxhbmcuYW5ub3RhdGlvbi5SZXRlbnRpb25Qb2xpY3kKICAgIHB1YmxpYyBmaW5hbCBOYW1lIENMQVNTOwogICAgcHVibGljIGZpbmFsIE5hbWUgUlVOVElNRTsKICAgIHB1YmxpYyBmaW5hbCBOYW1lIFNPVVJDRTsKCiAgICAvLyBvdGhlciBpZGVudGlmaWVycwogICAgcHVibGljIGZpbmFsIE5hbWUgVDsKICAgIHB1YmxpYyBmaW5hbCBOYW1lIGRlcHJlY2F0ZWQ7CiAgICBwdWJsaWMgZmluYWwgTmFtZSBleDsKICAgIHB1YmxpYyBmaW5hbCBOYW1lIG1vZHVsZV9pbmZvOwogICAgcHVibGljIGZpbmFsIE5hbWUgcGFja2FnZV9pbmZvOwogICAgcHVibGljIGZpbmFsIE5hbWUgcmVxdWlyZU5vbk51bGw7CgogICAgLy8gbGFtYmRhLXJlbGF0ZWQKICAgIHB1YmxpYyBmaW5hbCBOYW1lIGxhbWJkYTsKICAgIHB1YmxpYyBmaW5hbCBOYW1lIG1ldGFmYWN0b3J5OwogICAgcHVibGljIGZpbmFsIE5hbWUgYWx0TWV0YWZhY3Rvcnk7CiAgICBwdWJsaWMgZmluYWwgTmFtZSBkb2xsYXJUaGlzOwoKICAgIC8vIHN0cmluZyBjb25jYXQKICAgIHB1YmxpYyBmaW5hbCBOYW1lIG1ha2VDb25jYXQ7CiAgICBwdWJsaWMgZmluYWwgTmFtZSBtYWtlQ29uY2F0V2l0aENvbnN0YW50czsKCiAgICBwdWJsaWMgZmluYWwgTmFtZS5UYWJsZSB0YWJsZTsKCiAgICBwdWJsaWMgTmFtZXMoQ29udGV4dCBjb250ZXh0KSB7CiAgICAgICAgT3B0aW9ucyBvcHRpb25zID0gT3B0aW9ucy5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICB0YWJsZSA9IGNyZWF0ZVRhYmxlKG9wdGlvbnMpOwoKICAgICAgICAvLyBvcGVyYXRvcnMgYW5kIHB1bmN0dWF0aW9uCiAgICAgICAgYXN0ZXJpc2sgPSBmcm9tU3RyaW5nKCIqIik7CiAgICAgICAgY29tbWEgPSBmcm9tU3RyaW5nKCIsIik7CiAgICAgICAgZW1wdHkgPSBmcm9tU3RyaW5nKCIiKTsKICAgICAgICBoeXBoZW4gPSBmcm9tU3RyaW5nKCItIik7CiAgICAgICAgb25lID0gZnJvbVN0cmluZygiMSIpOwogICAgICAgIHBlcmlvZCA9IGZyb21TdHJpbmcoIi4iKTsKICAgICAgICBzZW1pY29sb24gPSBmcm9tU3RyaW5nKCI7Iik7CiAgICAgICAgc2xhc2ggPSBmcm9tU3RyaW5nKCIvIik7CiAgICAgICAgc2xhc2hlcXVhbHMgPSBmcm9tU3RyaW5nKCIvPSIpOwoKICAgICAgICAvLyBrZXl3b3JkcwogICAgICAgIF9jbGFzcyA9IGZyb21TdHJpbmcoImNsYXNzIik7CiAgICAgICAgX2RlZmF1bHQgPSBmcm9tU3RyaW5nKCJkZWZhdWx0Iik7CiAgICAgICAgX3N1cGVyID0gZnJvbVN0cmluZygic3VwZXIiKTsKICAgICAgICBfdGhpcyA9IGZyb21TdHJpbmcoInRoaXMiKTsKICAgICAgICBleHBvcnRzID0gZnJvbVN0cmluZygiZXhwb3J0cyIpOwogICAgICAgIG9wZW5zID0gZnJvbVN0cmluZygib3BlbnMiKTsKICAgICAgICBtb2R1bGUgPSBmcm9tU3RyaW5nKCJtb2R1bGUiKTsKICAgICAgICBwcm92aWRlcyA9IGZyb21TdHJpbmcoInByb3ZpZGVzIik7CiAgICAgICAgcmVxdWlyZXMgPSBmcm9tU3RyaW5nKCJyZXF1aXJlcyIpOwogICAgICAgIHRvID0gZnJvbVN0cmluZygidG8iKTsKICAgICAgICB0cmFuc2l0aXZlID0gZnJvbVN0cmluZygidHJhbnNpdGl2ZSIpOwogICAgICAgIHVzZXMgPSBmcm9tU3RyaW5nKCJ1c2VzIik7CiAgICAgICAgb3BlbiA9IGZyb21TdHJpbmcoIm9wZW4iKTsKICAgICAgICB3aXRoID0gZnJvbVN0cmluZygid2l0aCIpOwoKICAgICAgICAvLyBmaWVsZCBhbmQgbWV0aG9kIG5hbWVzCiAgICAgICAgX25hbWUgPSBmcm9tU3RyaW5nKCJuYW1lIik7CiAgICAgICAgYWRkU3VwcHJlc3NlZCA9IGZyb21TdHJpbmcoImFkZFN1cHByZXNzZWQiKTsKICAgICAgICBhbnkgPSBmcm9tU3RyaW5nKCI8YW55PiIpOwogICAgICAgIGFwcGVuZCA9IGZyb21TdHJpbmcoImFwcGVuZCIpOwogICAgICAgIGNsaW5pdCA9IGZyb21TdHJpbmcoIjxjbGluaXQ+Iik7CiAgICAgICAgY2xvbmUgPSBmcm9tU3RyaW5nKCJjbG9uZSIpOwogICAgICAgIGNsb3NlID0gZnJvbVN0cmluZygiY2xvc2UiKTsKICAgICAgICBjb21wYXJlVG8gPSBmcm9tU3RyaW5nKCJjb21wYXJlVG8iKTsKICAgICAgICBkZXNlcmlhbGl6ZUxhbWJkYSA9IGZyb21TdHJpbmcoIiRkZXNlcmlhbGl6ZUxhbWJkYSQiKTsKICAgICAgICBkZXNpcmVkQXNzZXJ0aW9uU3RhdHVzID0gZnJvbVN0cmluZygiZGVzaXJlZEFzc2VydGlvblN0YXR1cyIpOwogICAgICAgIGVxdWFscyA9IGZyb21TdHJpbmcoImVxdWFscyIpOwogICAgICAgIGVycm9yID0gZnJvbVN0cmluZygiPGVycm9yPiIpOwogICAgICAgIGZhbWlseSA9IGZyb21TdHJpbmcoImZhbWlseSIpOwogICAgICAgIGZpbmFsaXplID0gZnJvbVN0cmluZygiZmluYWxpemUiKTsKICAgICAgICBmb3JOYW1lID0gZnJvbVN0cmluZygiZm9yTmFtZSIpOwogICAgICAgIGZvclJlbW92YWwgPSBmcm9tU3RyaW5nKCJmb3JSZW1vdmFsIik7CiAgICAgICAgZ2V0Q2xhc3MgPSBmcm9tU3RyaW5nKCJnZXRDbGFzcyIpOwogICAgICAgIGdldENsYXNzTG9hZGVyID0gZnJvbVN0cmluZygiZ2V0Q2xhc3NMb2FkZXIiKTsKICAgICAgICBnZXRDb21wb25lbnRUeXBlID0gZnJvbVN0cmluZygiZ2V0Q29tcG9uZW50VHlwZSIpOwogICAgICAgIGdldERlY2xhcmluZ0NsYXNzID0gZnJvbVN0cmluZygiZ2V0RGVjbGFyaW5nQ2xhc3MiKTsKICAgICAgICBnZXRNZXNzYWdlID0gZnJvbVN0cmluZygiZ2V0TWVzc2FnZSIpOwogICAgICAgIGhhc05leHQgPSBmcm9tU3RyaW5nKCJoYXNOZXh0Iik7CiAgICAgICAgaGFzaENvZGUgPSBmcm9tU3RyaW5nKCJoYXNoQ29kZSIpOwogICAgICAgIGluaXQgPSBmcm9tU3RyaW5nKCI8aW5pdD4iKTsKICAgICAgICBpbml0Q2F1c2UgPSBmcm9tU3RyaW5nKCJpbml0Q2F1c2UiKTsKICAgICAgICBpdGVyYXRvciA9IGZyb21TdHJpbmcoIml0ZXJhdG9yIik7CiAgICAgICAgbGVuZ3RoID0gZnJvbVN0cmluZygibGVuZ3RoIik7CiAgICAgICAgbmV4dCA9IGZyb21TdHJpbmcoIm5leHQiKTsKICAgICAgICBvcmRpbmFsID0gZnJvbVN0cmluZygib3JkaW5hbCIpOwogICAgICAgIHByb3ZpZGVyID0gZnJvbVN0cmluZygicHJvdmlkZXIiKTsKICAgICAgICBzZXJpYWxWZXJzaW9uVUlEID0gZnJvbVN0cmluZygic2VyaWFsVmVyc2lvblVJRCIpOwogICAgICAgIHRvU3RyaW5nID0gZnJvbVN0cmluZygidG9TdHJpbmciKTsKICAgICAgICB2YWx1ZSA9IGZyb21TdHJpbmcoInZhbHVlIik7CiAgICAgICAgdmFsdWVPZiA9IGZyb21TdHJpbmcoInZhbHVlT2YiKTsKICAgICAgICB2YWx1ZXMgPSBmcm9tU3RyaW5nKCJ2YWx1ZXMiKTsKICAgICAgICBkb2xsYXJUaGlzID0gZnJvbVN0cmluZygiJHRoaXMiKTsKCiAgICAgICAgLy8gY2xhc3MgbmFtZXMKICAgICAgICBqYXZhX2lvX1NlcmlhbGl6YWJsZSA9IGZyb21TdHJpbmcoImphdmEuaW8uU2VyaWFsaXphYmxlIik7CiAgICAgICAgamF2YV9sYW5nX0F1dG9DbG9zZWFibGUgPSBmcm9tU3RyaW5nKCJqYXZhLmxhbmcuQXV0b0Nsb3NlYWJsZSIpOwogICAgICAgIGphdmFfbGFuZ19DbGFzcyA9IGZyb21TdHJpbmcoImphdmEubGFuZy5DbGFzcyIpOwogICAgICAgIGphdmFfbGFuZ19DbG9uZWFibGUgPSBmcm9tU3RyaW5nKCJqYXZhLmxhbmcuQ2xvbmVhYmxlIik7CiAgICAgICAgamF2YV9sYW5nX0VudW0gPSBmcm9tU3RyaW5nKCJqYXZhLmxhbmcuRW51bSIpOwogICAgICAgIGphdmFfbGFuZ19PYmplY3QgPSBmcm9tU3RyaW5nKCJqYXZhLmxhbmcuT2JqZWN0Iik7CiAgICAgICAgamF2YV9sYW5nX2ludm9rZV9NZXRob2RIYW5kbGUgPSBmcm9tU3RyaW5nKCJqYXZhLmxhbmcuaW52b2tlLk1ldGhvZEhhbmRsZSIpOwoKICAgICAgICAvLyBuYW1lcyBvZiBidWlsdGluIGNsYXNzZXMKICAgICAgICBBcnJheSA9IGZyb21TdHJpbmcoIkFycmF5Iik7CiAgICAgICAgQm91bmQgPSBmcm9tU3RyaW5nKCJCb3VuZCIpOwogICAgICAgIE1ldGhvZCA9IGZyb21TdHJpbmcoIk1ldGhvZCIpOwoKICAgICAgICAvLyBwYWNrYWdlIG5hbWVzCiAgICAgICAgamF2YV9sYW5nID0gZnJvbVN0cmluZygiamF2YS5sYW5nIik7CgogICAgICAgIC8vIG1vZHVsZSBuYW1lcwogICAgICAgIGphdmFfYmFzZSA9IGZyb21TdHJpbmcoImphdmEuYmFzZSIpOwoKICAgICAgICAvLyBhdHRyaWJ1dGUgbmFtZXMKICAgICAgICBBbm5vdGF0aW9uID0gZnJvbVN0cmluZygiQW5ub3RhdGlvbiIpOwogICAgICAgIEFubm90YXRpb25EZWZhdWx0ID0gZnJvbVN0cmluZygiQW5ub3RhdGlvbkRlZmF1bHQiKTsKICAgICAgICBCb290c3RyYXBNZXRob2RzID0gZnJvbVN0cmluZygiQm9vdHN0cmFwTWV0aG9kcyIpOwogICAgICAgIEJyaWRnZSA9IGZyb21TdHJpbmcoIkJyaWRnZSIpOwogICAgICAgIENoYXJhY3RlclJhbmdlVGFibGUgPSBmcm9tU3RyaW5nKCJDaGFyYWN0ZXJSYW5nZVRhYmxlIik7CiAgICAgICAgQ29kZSA9IGZyb21TdHJpbmcoIkNvZGUiKTsKICAgICAgICBDb21waWxhdGlvbklEID0gZnJvbVN0cmluZygiQ29tcGlsYXRpb25JRCIpOwogICAgICAgIENvbnN0YW50VmFsdWUgPSBmcm9tU3RyaW5nKCJDb25zdGFudFZhbHVlIik7CiAgICAgICAgRGVwcmVjYXRlZCA9IGZyb21TdHJpbmcoIkRlcHJlY2F0ZWQiKTsKICAgICAgICBFbmNsb3NpbmdNZXRob2QgPSBmcm9tU3RyaW5nKCJFbmNsb3NpbmdNZXRob2QiKTsKICAgICAgICBFbnVtID0gZnJvbVN0cmluZygiRW51bSIpOwogICAgICAgIEV4Y2VwdGlvbnMgPSBmcm9tU3RyaW5nKCJFeGNlcHRpb25zIik7CiAgICAgICAgSW5uZXJDbGFzc2VzID0gZnJvbVN0cmluZygiSW5uZXJDbGFzc2VzIik7CiAgICAgICAgTGluZU51bWJlclRhYmxlID0gZnJvbVN0cmluZygiTGluZU51bWJlclRhYmxlIik7CiAgICAgICAgTG9jYWxWYXJpYWJsZVRhYmxlID0gZnJvbVN0cmluZygiTG9jYWxWYXJpYWJsZVRhYmxlIik7CiAgICAgICAgTG9jYWxWYXJpYWJsZVR5cGVUYWJsZSA9IGZyb21TdHJpbmcoIkxvY2FsVmFyaWFibGVUeXBlVGFibGUiKTsKICAgICAgICBNZXRob2RQYXJhbWV0ZXJzID0gZnJvbVN0cmluZygiTWV0aG9kUGFyYW1ldGVycyIpOwogICAgICAgIE1vZHVsZSA9IGZyb21TdHJpbmcoIk1vZHVsZSIpOwogICAgICAgIE1vZHVsZVJlc29sdXRpb24gPSBmcm9tU3RyaW5nKCJNb2R1bGVSZXNvbHV0aW9uIik7CiAgICAgICAgUnVudGltZUludmlzaWJsZUFubm90YXRpb25zID0gZnJvbVN0cmluZygiUnVudGltZUludmlzaWJsZUFubm90YXRpb25zIik7CiAgICAgICAgUnVudGltZUludmlzaWJsZVBhcmFtZXRlckFubm90YXRpb25zID0gZnJvbVN0cmluZygiUnVudGltZUludmlzaWJsZVBhcmFtZXRlckFubm90YXRpb25zIik7CiAgICAgICAgUnVudGltZUludmlzaWJsZVR5cGVBbm5vdGF0aW9ucyA9IGZyb21TdHJpbmcoIlJ1bnRpbWVJbnZpc2libGVUeXBlQW5ub3RhdGlvbnMiKTsKICAgICAgICBSdW50aW1lVmlzaWJsZUFubm90YXRpb25zID0gZnJvbVN0cmluZygiUnVudGltZVZpc2libGVBbm5vdGF0aW9ucyIpOwogICAgICAgIFJ1bnRpbWVWaXNpYmxlUGFyYW1ldGVyQW5ub3RhdGlvbnMgPSBmcm9tU3RyaW5nKCJSdW50aW1lVmlzaWJsZVBhcmFtZXRlckFubm90YXRpb25zIik7CiAgICAgICAgUnVudGltZVZpc2libGVUeXBlQW5ub3RhdGlvbnMgPSBmcm9tU3RyaW5nKCJSdW50aW1lVmlzaWJsZVR5cGVBbm5vdGF0aW9ucyIpOwogICAgICAgIFNpZ25hdHVyZSA9IGZyb21TdHJpbmcoIlNpZ25hdHVyZSIpOwogICAgICAgIFNvdXJjZUZpbGUgPSBmcm9tU3RyaW5nKCJTb3VyY2VGaWxlIik7CiAgICAgICAgU291cmNlSUQgPSBmcm9tU3RyaW5nKCJTb3VyY2VJRCIpOwogICAgICAgIFN0YWNrTWFwID0gZnJvbVN0cmluZygiU3RhY2tNYXAiKTsKICAgICAgICBTdGFja01hcFRhYmxlID0gZnJvbVN0cmluZygiU3RhY2tNYXBUYWJsZSIpOwogICAgICAgIFN5bnRoZXRpYyA9IGZyb21TdHJpbmcoIlN5bnRoZXRpYyIpOwogICAgICAgIFZhbHVlID0gZnJvbVN0cmluZygiVmFsdWUiKTsKICAgICAgICBWYXJhcmdzID0gZnJvbVN0cmluZygiVmFyYXJncyIpOwoKICAgICAgICAvLyBtZW1iZXJzIG9mIGphdmEubGFuZy5hbm5vdGF0aW9uLkVsZW1lbnRUeXBlCiAgICAgICAgQU5OT1RBVElPTl9UWVBFID0gZnJvbVN0cmluZygiQU5OT1RBVElPTl9UWVBFIik7CiAgICAgICAgQ09OU1RSVUNUT1IgPSBmcm9tU3RyaW5nKCJDT05TVFJVQ1RPUiIpOwogICAgICAgIEZJRUxEID0gZnJvbVN0cmluZygiRklFTEQiKTsKICAgICAgICBMT0NBTF9WQVJJQUJMRSA9IGZyb21TdHJpbmcoIkxPQ0FMX1ZBUklBQkxFIik7CiAgICAgICAgTUVUSE9EID0gZnJvbVN0cmluZygiTUVUSE9EIik7CiAgICAgICAgTU9EVUxFID0gZnJvbVN0cmluZygiTU9EVUxFIik7CiAgICAgICAgUEFDS0FHRSA9IGZyb21TdHJpbmcoIlBBQ0tBR0UiKTsKICAgICAgICBQQVJBTUVURVIgPSBmcm9tU3RyaW5nKCJQQVJBTUVURVIiKTsKICAgICAgICBUWVBFID0gZnJvbVN0cmluZygiVFlQRSIpOwogICAgICAgIFRZUEVfUEFSQU1FVEVSID0gZnJvbVN0cmluZygiVFlQRV9QQVJBTUVURVIiKTsKICAgICAgICBUWVBFX1VTRSA9IGZyb21TdHJpbmcoIlRZUEVfVVNFIik7CgogICAgICAgIC8vIG1lbWJlcnMgb2YgamF2YS5sYW5nLmFubm90YXRpb24uUmV0ZW50aW9uUG9saWN5CiAgICAgICAgQ0xBU1MgPSBmcm9tU3RyaW5nKCJDTEFTUyIpOwogICAgICAgIFJVTlRJTUUgPSBmcm9tU3RyaW5nKCJSVU5USU1FIik7CiAgICAgICAgU09VUkNFID0gZnJvbVN0cmluZygiU09VUkNFIik7CgogICAgICAgIC8vIG90aGVyIGlkZW50aWZpZXJzCiAgICAgICAgVCA9IGZyb21TdHJpbmcoIlQiKTsKICAgICAgICBkZXByZWNhdGVkID0gZnJvbVN0cmluZygiZGVwcmVjYXRlZCIpOwogICAgICAgIGV4ID0gZnJvbVN0cmluZygiZXgiKTsKICAgICAgICBtb2R1bGVfaW5mbyA9IGZyb21TdHJpbmcoIm1vZHVsZS1pbmZvIik7CiAgICAgICAgcGFja2FnZV9pbmZvID0gZnJvbVN0cmluZygicGFja2FnZS1pbmZvIik7CiAgICAgICAgcmVxdWlyZU5vbk51bGwgPSBmcm9tU3RyaW5nKCJyZXF1aXJlTm9uTnVsbCIpOwoKICAgICAgICAvL2xhbWJkYS1yZWxhdGVkCiAgICAgICAgbGFtYmRhID0gZnJvbVN0cmluZygibGFtYmRhJCIpOwogICAgICAgIG1ldGFmYWN0b3J5ID0gZnJvbVN0cmluZygibWV0YWZhY3RvcnkiKTsKICAgICAgICBhbHRNZXRhZmFjdG9yeSA9IGZyb21TdHJpbmcoImFsdE1ldGFmYWN0b3J5Iik7CgogICAgICAgIC8vIHN0cmluZyBjb25jYXQKICAgICAgICBtYWtlQ29uY2F0ID0gZnJvbVN0cmluZygibWFrZUNvbmNhdCIpOwogICAgICAgIG1ha2VDb25jYXRXaXRoQ29uc3RhbnRzID0gZnJvbVN0cmluZygibWFrZUNvbmNhdFdpdGhDb25zdGFudHMiKTsKICAgIH0KCiAgICBwcm90ZWN0ZWQgTmFtZS5UYWJsZSBjcmVhdGVUYWJsZShPcHRpb25zIG9wdGlvbnMpIHsKICAgICAgICBib29sZWFuIHVzZVVuc2hhcmVkVGFibGUgPSBvcHRpb25zLmlzU2V0KCJ1c2VVbnNoYXJlZFRhYmxlIik7CiAgICAgICAgaWYgKHVzZVVuc2hhcmVkVGFibGUpCiAgICAgICAgICAgIHJldHVybiBVbnNoYXJlZE5hbWVUYWJsZS5jcmVhdGUodGhpcyk7CiAgICAgICAgZWxzZQogICAgICAgICAgICByZXR1cm4gU2hhcmVkTmFtZVRhYmxlLmNyZWF0ZSh0aGlzKTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCBkaXNwb3NlKCkgewogICAgICAgIHRhYmxlLmRpc3Bvc2UoKTsKICAgIH0KCiAgICBwdWJsaWMgTmFtZSBmcm9tQ2hhcnMoY2hhcltdIGNzLCBpbnQgc3RhcnQsIGludCBsZW4pIHsKICAgICAgICByZXR1cm4gdGFibGUuZnJvbUNoYXJzKGNzLCBzdGFydCwgbGVuKTsKICAgIH0KCiAgICBwdWJsaWMgTmFtZSBmcm9tU3RyaW5nKFN0cmluZyBzKSB7CiAgICAgICAgcmV0dXJuIHRhYmxlLmZyb21TdHJpbmcocyk7CiAgICB9CgogICAgcHVibGljIE5hbWUgZnJvbVV0ZihieXRlW10gY3MpIHsKICAgICAgICByZXR1cm4gdGFibGUuZnJvbVV0Zihjcyk7CiAgICB9CgogICAgcHVibGljIE5hbWUgZnJvbVV0ZihieXRlW10gY3MsIGludCBzdGFydCwgaW50IGxlbikgewogICAgICAgIHJldHVybiB0YWJsZS5mcm9tVXRmKGNzLCBzdGFydCwgbGVuKTsKICAgIH0KfQpQSwMECgAACAAABjupSsich58HSAAAB0gAACoAAABjb20vc3VuL3Rvb2xzL2phdmFjL3V0aWwvSkRLOVdyYXBwZXJzLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTUsIDIwMTYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhYy51dGlsOwoKaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CmltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5JbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uOwppbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuTWV0aG9kOwppbXBvcnQgamF2YS5uaW8uZmlsZS5QYXRoOwppbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb247CmltcG9ydCBqYXZhLnV0aWwuU2VydmljZUxvYWRlcjsKCi8qKgogKiAgVGhpcyBjbGFzcyBwcm92aWRlcyB3cmFwcGVycyBmb3IgY2xhc3NlcyBhbmQgbWV0aG9kcyB0aGF0IGFyZSBuZXcgaW4gSkRLIDksIGFuZCB3aGljaCBhcmUgbm90CiAqICBhdmFpbGFibGUgb24gb2xkZXIgdmVyc2lvbnMgb2YgdGhlIHBsYXRmb3JtIG9uIHdoaWNoIGphdmFjIG1heSBiZSBjb21waWxlZCBhbmQgcnVuLgogKiAgSW4gZnV0dXJlIHJlbGVhc2VzLCB3aGVuIGphdmFjIGlzIGFsd2F5cyBjb21waWxlZCBvbiBKREsgOSBvciBsYXRlciwgdGhlIHVzZSBvZiB0aGVzZSB3cmFwcGVycwogKiAgY2FuIGJlIHJlcGxhY2VkIGJ5IHVzZSBvZiB0aGUgcmVhbCB1bmRlcmx5aW5nIGNsYXNzZXMuCiAqCiAqICA8cD5XcmFwcGVyIGNsYXNzZXMgcHJvdmlkZSBhIHN1YnNldCBvZiB0aGUgQVBJIG9mIHRoZSB3cmFwcGVkIGNsYXNzZXMsIGFzIG5lZWRlZCBmb3IgdXNlCiAqICBpbiBqYXZhYy4gV3JhcHBlciBvYmplY3RzIGNvbnRhaW4gYW4ge0Bjb2RlIE9iamVjdH0gcmVmZXJlbmNlIHRvIHRoZSB1bmRlcmx5aW5nIHJ1bnRpbWUgb2JqZWN0LAogKiAgYW5kIHtAY29kZSBDbGFzc30gYW5kIHtAY29kZSBNZXRob2R9IG9iamVjdHMgZm9yIG9idGFpbmluZyBvciB1c2luZyBzdWNoIGluc3RhbmNlcyB2aWEKICogIHJ1bnRpbWUgcmVmbGVjdGlvbi4gIFRoZSB7QGNvZGUgQ2xhc3N9IGFuZCB7QGNvZGUgTWV0aG9kfSBvYmplY3RzIGFyZSBzZXQgdXAgb24gYSBwZXItY2xhc3MKICogIGJhc2lzLCBieSBhbiB7QGNvZGUgaW5pdH0gbWV0aG9kLCB3aGljaCBpcyBjYWxsZWQgZnJvbSBzdGF0aWMgbWV0aG9kcyBvbiB0aGUgd3JhcHBlciBjbGFzcywKICogIG9yIGluIHRoZSBjb25zdHJ1Y3Rvciwgd2hlbiBpbnN0YW5jZXMgYXJlIGNyZWF0ZWQuCiAqICA8cD4KICoKICogIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqICBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqICBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogKiAgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPgogKi8KcHVibGljIGNsYXNzIEpESzlXcmFwcGVycyB7CgogICAgLyoqCiAgICAgKiBIZWxwZXIgY2xhc3MgZm9yIG5ldyBtZXRob2QgaW4gamF2YS51dGlsLlNlcnZpY2VMb2FkZXIuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgU2VydmljZUxvYWRlckhlbHBlciB7CiAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCiAgICAgICAgcHVibGljIHN0YXRpYyA8Uz4gU2VydmljZUxvYWRlcjxTPiBsb2FkKExheWVyIGxheWVyLCBDbGFzczxTPiBzZXJ2aWNlKSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBpbml0KCk7CiAgICAgICAgICAgICAgICBPYmplY3QgcmVzdWx0ID0gbG9hZE1ldGhvZC5pbnZva2UobnVsbCwgbGF5ZXIudGhlUmVhbExheWVyLCBzZXJ2aWNlKTsKICAgICAgICAgICAgICAgIHJldHVybiAoU2VydmljZUxvYWRlcjxTPilyZXN1bHQ7CiAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBY2Nlc3NFeGNlcHRpb24gfCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gfCBJbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uCiAgICAgICAgICAgICAgICAgICAgfCBTZWN1cml0eUV4Y2VwdGlvbiBleCkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFib3J0KGV4KTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgTWV0aG9kIGxvYWRNZXRob2QgPSBudWxsOwoKICAgICAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGluaXQoKSB7CiAgICAgICAgICAgIGlmIChsb2FkTWV0aG9kID09IG51bGwpIHsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgQ2xhc3M8Pz4gbGF5ZXJDbGFzcyA9IExheWVyLmxheWVyQ2xhc3M7CiAgICAgICAgICAgICAgICAgICAgbG9hZE1ldGhvZCA9IFNlcnZpY2VMb2FkZXIuY2xhc3MuZ2V0RGVjbGFyZWRNZXRob2QoImxvYWQiLCBsYXllckNsYXNzLCBDbGFzcy5jbGFzcyk7CiAgICAgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hNZXRob2RFeGNlcHRpb24gfCBTZWN1cml0eUV4Y2VwdGlvbiBleCkgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBBYm9ydChleCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBXcmFwcGVyIGNsYXNzIGZvciBqYXZhLmxhbmcubW9kdWxlLk1vZHVsZURlc2NyaXB0b3IgYW5kIE1vZHVsZURlc2NyaXB0b3IuVmVyc2lvbi4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBjbGFzcyBNb2R1bGVEZXNjcmlwdG9yIHsKICAgICAgICBwdWJsaWMgc3RhdGljIGNsYXNzIFZlcnNpb24gewogICAgICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBDTEFTU05BTUUgPSAiamF2YS5sYW5nLm1vZHVsZS5Nb2R1bGVEZXNjcmlwdG9yJFZlcnNpb24iOwogICAgICAgICAgICBwcml2YXRlIGZpbmFsIE9iamVjdCB0aGVSZWFsVmVyc2lvbjsKCiAgICAgICAgICAgIHByaXZhdGUgVmVyc2lvbihPYmplY3QgdmVyc2lvbikgewogICAgICAgICAgICAgICAgdGhpcy50aGVSZWFsVmVyc2lvbiA9IHZlcnNpb247CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHB1YmxpYyBzdGF0aWMgVmVyc2lvbiBwYXJzZShTdHJpbmcgdikgewogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICBpbml0KCk7CiAgICAgICAgICAgICAgICAgICAgT2JqZWN0IHJlc3VsdCA9IHBhcnNlTWV0aG9kLmludm9rZShudWxsLCB2KTsKICAgICAgICAgICAgICAgICAgICBWZXJzaW9uIHZlcnNpb24gPSBuZXcgVmVyc2lvbihyZXN1bHQpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiB2ZXJzaW9uOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbiBleCkgewogICAgICAgICAgICAgICAgICAgIGlmIChleC5nZXRDYXVzZSgpIGluc3RhbmNlb2YgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24pIGV4LmdldENhdXNlKCk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFib3J0KGV4KTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uIHwgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHwgU2VjdXJpdHlFeGNlcHRpb24gZXgpIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQWJvcnQoZXgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGVSZWFsVmVyc2lvbi50b1N0cmluZygpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgQ2xhc3M8Pz4gdmVyc2lvbkNsYXNzID0gbnVsbDsKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgTWV0aG9kIHBhcnNlTWV0aG9kID0gbnVsbDsKCiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIHZvaWQgaW5pdCgpIHsKICAgICAgICAgICAgICAgIGlmICh2ZXJzaW9uQ2xhc3MgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZlcnNpb25DbGFzcyA9IENsYXNzLmZvck5hbWUoQ0xBU1NOQU1FLCBmYWxzZSwgbnVsbCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHBhcnNlTWV0aG9kID0gdmVyc2lvbkNsYXNzLmdldERlY2xhcmVkTWV0aG9kKCJwYXJzZSIsIFN0cmluZy5jbGFzcyk7CiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiB8IE5vU3VjaE1ldGhvZEV4Y2VwdGlvbiB8IFNlY3VyaXR5RXhjZXB0aW9uIGV4KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBBYm9ydChleCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogV3JhcHBlciBjbGFzcyBmb3IgamF2YS5sYW5nLm1vZHVsZS5Nb2R1bGVGaW5kZXIuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgTW9kdWxlRmluZGVyIHsKICAgICAgICBwcml2YXRlIGZpbmFsIE9iamVjdCB0aGVSZWFsTW9kdWxlRmluZGVyOwoKICAgICAgICBwcml2YXRlIE1vZHVsZUZpbmRlcihPYmplY3QgbW9kdWxlRmluZGVyKSB7CiAgICAgICAgICAgIHRoaXMudGhlUmVhbE1vZHVsZUZpbmRlciA9IG1vZHVsZUZpbmRlcjsKICAgICAgICAgICAgaW5pdCgpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHN0YXRpYyBNb2R1bGVGaW5kZXIgb2YoUGF0aC4uLiBkaXJzKSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBpbml0KCk7CiAgICAgICAgICAgICAgICBPYmplY3QgcmVzdWx0ID0gb2ZNZXRob2QuaW52b2tlKG51bGwsIChPYmplY3QpZGlycyk7CiAgICAgICAgICAgICAgICBNb2R1bGVGaW5kZXIgbUZpbmRlciA9IG5ldyBNb2R1bGVGaW5kZXIocmVzdWx0KTsKICAgICAgICAgICAgICAgIHJldHVybiBtRmluZGVyOwogICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uIHwgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHwgSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbgogICAgICAgICAgICAgICAgICAgIHwgU2VjdXJpdHlFeGNlcHRpb24gZXgpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBBYm9ydChleCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgICAgIHByaXZhdGUgc3RhdGljIENsYXNzPD8+IG1vZHVsZUZpbmRlckNsYXNzID0gbnVsbDsKICAgICAgICBwcml2YXRlIHN0YXRpYyBNZXRob2Qgb2ZNZXRob2Q7CgogICAgICAgIHN0YXRpYyBmaW5hbCBDbGFzczw/PiBnZXRNb2R1bGVGaW5kZXJDbGFzcygpIHsKICAgICAgICAgICAgaW5pdCgpOwogICAgICAgICAgICByZXR1cm4gbW9kdWxlRmluZGVyQ2xhc3M7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGluaXQoKSB7CiAgICAgICAgICAgIGlmIChtb2R1bGVGaW5kZXJDbGFzcyA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIG1vZHVsZUZpbmRlckNsYXNzID0gQ2xhc3MuZm9yTmFtZSgiamF2YS5sYW5nLm1vZHVsZS5Nb2R1bGVGaW5kZXIiLCBmYWxzZSwgbnVsbCk7CiAgICAgICAgICAgICAgICAgICAgb2ZNZXRob2QgPSBtb2R1bGVGaW5kZXJDbGFzcy5nZXREZWNsYXJlZE1ldGhvZCgib2YiLCBQYXRoW10uY2xhc3MpOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiB8IE5vU3VjaE1ldGhvZEV4Y2VwdGlvbiB8IFNlY3VyaXR5RXhjZXB0aW9uIGV4KSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFib3J0KGV4KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFdyYXBwZXIgY2xhc3MgZm9yIGphdmEubGFuZy5yZWZsZWN0Lk1vZHVsZS4gVG8gbWF0ZXJpYWxpemUgYSBoYW5kbGUgdXNlIHRoZSBzdGF0aWMgZmFjdG9yeQogICAgICogbWV0aG9kcyBNb2R1bGUjZ2V0TW9kdWxlKENsYXNzPD8+KSBvciBNb2R1bGUjZ2V0VW5uYW1lZE1vZHVsZShDbGFzc0xvYWRlcikuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgTW9kdWxlIHsKCiAgICAgICAgcHJpdmF0ZSBmaW5hbCBPYmplY3QgdGhlUmVhbE1vZHVsZTsKCiAgICAgICAgcHJpdmF0ZSBNb2R1bGUoT2JqZWN0IG1vZHVsZSkgewogICAgICAgICAgICB0aGlzLnRoZVJlYWxNb2R1bGUgPSBtb2R1bGU7CiAgICAgICAgICAgIGluaXQoKTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBzdGF0aWMgTW9kdWxlIGdldE1vZHVsZShDbGFzczw/PiBjbGF6eikgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgaW5pdCgpOwogICAgICAgICAgICAgICAgT2JqZWN0IHJlc3VsdCA9IGdldE1vZHVsZU1ldGhvZC5pbnZva2UoY2xhenosIG5ldyBPYmplY3RbMF0pOwogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBNb2R1bGUocmVzdWx0KTsKICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiB8IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB8IEludm9jYXRpb25UYXJnZXRFeGNlcHRpb24KICAgICAgICAgICAgICAgICAgICB8IFNlY3VyaXR5RXhjZXB0aW9uIGV4KSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQWJvcnQoZXgpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgc3RhdGljIE1vZHVsZSBnZXRVbm5hbWVkTW9kdWxlKENsYXNzTG9hZGVyIGNsYXNzTG9hZGVyKSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBpbml0KCk7CiAgICAgICAgICAgICAgICBPYmplY3QgcmVzdWx0ID0gZ2V0VW5uYW1lZE1vZHVsZU1ldGhvZC5pbnZva2UoY2xhc3NMb2FkZXIsIG5ldyBPYmplY3RbMF0pOwogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBNb2R1bGUocmVzdWx0KTsKICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiB8IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB8IEludm9jYXRpb25UYXJnZXRFeGNlcHRpb24KICAgICAgICAgICAgICAgICAgICB8IFNlY3VyaXR5RXhjZXB0aW9uIGV4KSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQWJvcnQoZXgpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgTW9kdWxlIGFkZEV4cG9ydHMoU3RyaW5nIHBuLCBNb2R1bGUgb3RoZXIpIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIGFkZEV4cG9ydHNNZXRob2QuaW52b2tlKHRoZVJlYWxNb2R1bGUsIG5ldyBPYmplY3RbXSB7IHBuLCBvdGhlci50aGVSZWFsTW9kdWxlfSk7CiAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBY2Nlc3NFeGNlcHRpb24gfCBJbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uIGV4KSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQWJvcnQoZXgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIE1vZHVsZSBhZGRVc2VzKENsYXNzPD8+IHN0KSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBhZGRVc2VzTWV0aG9kLmludm9rZSh0aGVSZWFsTW9kdWxlLCBuZXcgT2JqZWN0W10geyBzdCB9KTsKICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiB8IEludm9jYXRpb25UYXJnZXRFeGNlcHRpb24gZXgpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBBYm9ydChleCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgICAgIC8vIG9uIGphdmEubGFuZy5yZWZsZWN0Lk1vZHVsZQogICAgICAgIHByaXZhdGUgc3RhdGljIE1ldGhvZCBhZGRFeHBvcnRzTWV0aG9kID0gbnVsbDsKICAgICAgICAvLyBvbiBqYXZhLmxhbmcucmVmbGVjdC5Nb2R1bGUKICAgICAgICBwcml2YXRlIHN0YXRpYyBNZXRob2QgYWRkVXNlc01ldGhvZCA9IG51bGw7CiAgICAgICAgLy8gb24gamF2YS5sYW5nLkNsYXNzCiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgTWV0aG9kIGdldE1vZHVsZU1ldGhvZDsKICAgICAgICAvLyBvbiBqYXZhLmxhbmcuQ2xhc3NMb2FkZXIKICAgICAgICBwcml2YXRlIHN0YXRpYyBNZXRob2QgZ2V0VW5uYW1lZE1vZHVsZU1ldGhvZDsKCiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBpbml0KCkgewogICAgICAgICAgICBpZiAoYWRkRXhwb3J0c01ldGhvZCA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIENsYXNzPD8+IG1vZHVsZUNsYXNzID0gQ2xhc3MuZm9yTmFtZSgiamF2YS5sYW5nLnJlZmxlY3QuTW9kdWxlIiwgZmFsc2UsIG51bGwpOwogICAgICAgICAgICAgICAgICAgIGFkZFVzZXNNZXRob2QgPSBtb2R1bGVDbGFzcy5nZXREZWNsYXJlZE1ldGhvZCgiYWRkVXNlcyIsIG5ldyBDbGFzczw/PltdIHsgQ2xhc3MuY2xhc3MgfSk7CiAgICAgICAgICAgICAgICAgICAgYWRkRXhwb3J0c01ldGhvZCA9IG1vZHVsZUNsYXNzLmdldERlY2xhcmVkTWV0aG9kKCJhZGRFeHBvcnRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgQ2xhc3M8Pz5bXSB7IFN0cmluZy5jbGFzcywgbW9kdWxlQ2xhc3MgfSk7CiAgICAgICAgICAgICAgICAgICAgZ2V0TW9kdWxlTWV0aG9kID0gQ2xhc3MuY2xhc3MuZ2V0RGVjbGFyZWRNZXRob2QoImdldE1vZHVsZSIsIG5ldyBDbGFzczw/PlswXSk7CiAgICAgICAgICAgICAgICAgICAgZ2V0VW5uYW1lZE1vZHVsZU1ldGhvZCA9IENsYXNzTG9hZGVyLmNsYXNzLmdldERlY2xhcmVkTWV0aG9kKCJnZXRVbm5hbWVkTW9kdWxlIiwgbmV3IENsYXNzPD8+WzBdKTsKICAgICAgICAgICAgICAgIH0gY2F0Y2ggKENsYXNzTm90Rm91bmRFeGNlcHRpb24gfCBOb1N1Y2hNZXRob2RFeGNlcHRpb24gfCBTZWN1cml0eUV4Y2VwdGlvbiBleCkgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBBYm9ydChleCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBXcmFwcGVyIGNsYXNzIGZvciBqYXZhLmxhbmcubW9kdWxlLkNvbmZpZ3VyYXRpb24uCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQ29uZmlndXJhdGlvbiB7CiAgICAgICAgcHJpdmF0ZSBmaW5hbCBPYmplY3QgdGhlUmVhbENvbmZpZ3VyYXRpb247CgogICAgICAgIHByaXZhdGUgQ29uZmlndXJhdGlvbihPYmplY3QgY29uZmlndXJhdGlvbikgewogICAgICAgICAgICB0aGlzLnRoZVJlYWxDb25maWd1cmF0aW9uID0gY29uZmlndXJhdGlvbjsKICAgICAgICAgICAgaW5pdCgpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIENvbmZpZ3VyYXRpb24gcmVzb2x2ZUFuZEJpbmQoCiAgICAgICAgICAgICAgICBNb2R1bGVGaW5kZXIgYmVmb3JlRmluZGVyLAogICAgICAgICAgICAgICAgTW9kdWxlRmluZGVyIGFmdGVyRmluZGVyLAogICAgICAgICAgICAgICAgQ29sbGVjdGlvbjxTdHJpbmc+IHJvb3RzKSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBPYmplY3QgcmVzdWx0ID0gcmVzb2x2ZUFuZEJpbmRNZXRob2QuaW52b2tlKHRoZVJlYWxDb25maWd1cmF0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiZWZvcmVGaW5kZXIudGhlUmVhbE1vZHVsZUZpbmRlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWZ0ZXJGaW5kZXIudGhlUmVhbE1vZHVsZUZpbmRlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcm9vdHMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgQ29uZmlndXJhdGlvbiBjb25maWd1cmF0aW9uID0gbmV3IENvbmZpZ3VyYXRpb24ocmVzdWx0KTsKICAgICAgICAgICAgICAgIHJldHVybiBjb25maWd1cmF0aW9uOwogICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uIHwgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHwgSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbgogICAgICAgICAgICAgICAgICAgIHwgU2VjdXJpdHlFeGNlcHRpb24gZXgpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBBYm9ydChleCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgICAgIHByaXZhdGUgc3RhdGljIENsYXNzPD8+IGNvbmZpZ3VyYXRpb25DbGFzcyA9IG51bGw7CiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgTWV0aG9kIHJlc29sdmVBbmRCaW5kTWV0aG9kOwoKICAgICAgICBzdGF0aWMgZmluYWwgQ2xhc3M8Pz4gZ2V0Q29uZmlndXJhdGlvbkNsYXNzKCkgewogICAgICAgICAgICBpbml0KCk7CiAgICAgICAgICAgIHJldHVybiBjb25maWd1cmF0aW9uQ2xhc3M7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGluaXQoKSB7CiAgICAgICAgICAgIGlmIChjb25maWd1cmF0aW9uQ2xhc3MgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICBjb25maWd1cmF0aW9uQ2xhc3MgPSBDbGFzcy5mb3JOYW1lKCJqYXZhLmxhbmcubW9kdWxlLkNvbmZpZ3VyYXRpb24iLCBmYWxzZSwgbnVsbCk7CiAgICAgICAgICAgICAgICAgICAgQ2xhc3M8Pz4gbW9kdWxlRmluZGVySW50ZXJmYWNlID0gTW9kdWxlRmluZGVyLmdldE1vZHVsZUZpbmRlckNsYXNzKCk7CiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZUFuZEJpbmRNZXRob2QgPSBjb25maWd1cmF0aW9uQ2xhc3MuZ2V0RGVjbGFyZWRNZXRob2QoInJlc29sdmVBbmRCaW5kIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb2R1bGVGaW5kZXJJbnRlcmZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9kdWxlRmluZGVySW50ZXJmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbGxlY3Rpb24uY2xhc3MKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiB8IE5vU3VjaE1ldGhvZEV4Y2VwdGlvbiB8IFNlY3VyaXR5RXhjZXB0aW9uIGV4KSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFib3J0KGV4KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFdyYXBwZXIgY2xhc3MgZm9yIGphdmEubGFuZy5tb2R1bGUuTGF5ZXIuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgTGF5ZXIgewogICAgICAgIHByaXZhdGUgZmluYWwgT2JqZWN0IHRoZVJlYWxMYXllcjsKCiAgICAgICAgcHJpdmF0ZSBMYXllcihPYmplY3QgbGF5ZXIpIHsKICAgICAgICAgICAgdGhpcy50aGVSZWFsTGF5ZXIgPSBsYXllcjsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBzdGF0aWMgTGF5ZXIgYm9vdCgpIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIGluaXQoKTsKICAgICAgICAgICAgICAgIE9iamVjdCByZXN1bHQgPSBib290TWV0aG9kLmludm9rZShudWxsKTsKICAgICAgICAgICAgICAgIExheWVyIGxheWVyID0gbmV3IExheWVyKHJlc3VsdCk7CiAgICAgICAgICAgICAgICByZXR1cm4gbGF5ZXI7CiAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBY2Nlc3NFeGNlcHRpb24gfCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gfCBJbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uCiAgICAgICAgICAgICAgICAgICAgfCBTZWN1cml0eUV4Y2VwdGlvbiBleCkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFib3J0KGV4KTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHVibGljIENvbmZpZ3VyYXRpb24gY29uZmlndXJhdGlvbigpIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIE9iamVjdCByZXN1bHQgPSBjb25maWd1cmF0aW9uTWV0aG9kLmludm9rZSh0aGVSZWFsTGF5ZXIpOwogICAgICAgICAgICAgICAgQ29uZmlndXJhdGlvbiBjb25maWd1cmF0aW9uID0gbmV3IENvbmZpZ3VyYXRpb24ocmVzdWx0KTsKICAgICAgICAgICAgICAgIHJldHVybiBjb25maWd1cmF0aW9uOwogICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uIHwgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHwgSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbgogICAgICAgICAgICAgICAgICAgIHwgU2VjdXJpdHlFeGNlcHRpb24gZXgpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBBYm9ydChleCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHB1YmxpYyBMYXllciBkZWZpbmVNb2R1bGVzV2l0aE9uZUxvYWRlcihDb25maWd1cmF0aW9uIGNvbmZpZ3VyYXRpb24sIENsYXNzTG9hZGVyIHBhcmVudENsYXNzTG9hZGVyKSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBPYmplY3QgcmVzdWx0ID0gZGVmaW5lTW9kdWxlc1dpdGhPbmVMb2FkZXJNZXRob2QuaW52b2tlKAogICAgICAgICAgICAgICAgICAgICAgICB0aGVSZWFsTGF5ZXIsIGNvbmZpZ3VyYXRpb24udGhlUmVhbENvbmZpZ3VyYXRpb24sIHBhcmVudENsYXNzTG9hZGVyKTsKICAgICAgICAgICAgICAgIExheWVyIGxheWVyID0gbmV3IExheWVyKHJlc3VsdCk7CiAgICAgICAgICAgICAgICByZXR1cm4gbGF5ZXI7CiAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBY2Nlc3NFeGNlcHRpb24gfCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gfCBJbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uCiAgICAgICAgICAgICAgICAgICAgfCBTZWN1cml0eUV4Y2VwdGlvbiBleCkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFib3J0KGV4KTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgQ2xhc3M8Pz4gbGF5ZXJDbGFzcyA9IG51bGw7CiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgTWV0aG9kIGJvb3RNZXRob2Q7CiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgTWV0aG9kIGRlZmluZU1vZHVsZXNXaXRoT25lTG9hZGVyTWV0aG9kOwogICAgICAgIHByaXZhdGUgc3RhdGljIE1ldGhvZCBjb25maWd1cmF0aW9uTWV0aG9kOwoKICAgICAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGluaXQoKSB7CiAgICAgICAgICAgIGlmIChsYXllckNsYXNzID09IG51bGwpIHsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgbGF5ZXJDbGFzcyA9IENsYXNzLmZvck5hbWUoImphdmEubGFuZy5yZWZsZWN0LkxheWVyIiwgZmFsc2UsIG51bGwpOwogICAgICAgICAgICAgICAgICAgIGJvb3RNZXRob2QgPSBsYXllckNsYXNzLmdldERlY2xhcmVkTWV0aG9kKCJib290Iik7CiAgICAgICAgICAgICAgICAgICAgZGVmaW5lTW9kdWxlc1dpdGhPbmVMb2FkZXJNZXRob2QgPSBsYXllckNsYXNzLmdldERlY2xhcmVkTWV0aG9kKCJkZWZpbmVNb2R1bGVzV2l0aE9uZUxvYWRlciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29uZmlndXJhdGlvbi5nZXRDb25maWd1cmF0aW9uQ2xhc3MoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDbGFzc0xvYWRlci5jbGFzcyk7CiAgICAgICAgICAgICAgICAgICAgY29uZmlndXJhdGlvbk1ldGhvZCA9IGxheWVyQ2xhc3MuZ2V0RGVjbGFyZWRNZXRob2QoImNvbmZpZ3VyYXRpb24iKTsKICAgICAgICAgICAgICAgIH0gY2F0Y2ggKENsYXNzTm90Rm91bmRFeGNlcHRpb24gfCBOb1N1Y2hNZXRob2RFeGNlcHRpb24gfCBTZWN1cml0eUV4Y2VwdGlvbiBleCkgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBBYm9ydChleCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgoKICAgIC8qKgogICAgICogSGVscGVyIGNsYXNzIGZvciBuZXcgbWV0aG9kIGluIGpkay5pbnRlcm5hbC5taXNjLlZNLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFZNSGVscGVyIHsKICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBDTEFTU05BTUUgPSAiamRrLmludGVybmFsLm1pc2MuVk0iOwoKICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKICAgICAgICBwdWJsaWMgc3RhdGljIFN0cmluZ1tdIGdldFJ1bnRpbWVBcmd1bWVudHMoKSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBpbml0KCk7CiAgICAgICAgICAgICAgICBPYmplY3QgcmVzdWx0ID0gZ2V0UnVudGltZUFyZ3VtZW50c01ldGhvZC5pbnZva2UobnVsbCk7CiAgICAgICAgICAgICAgICByZXR1cm4gKFN0cmluZ1tdKXJlc3VsdDsKICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiB8IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB8IEludm9jYXRpb25UYXJnZXRFeGNlcHRpb24KICAgICAgICAgICAgICAgICAgICB8IFNlY3VyaXR5RXhjZXB0aW9uIGV4KSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQWJvcnQoZXgpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgICAgICBwcml2YXRlIHN0YXRpYyBDbGFzczw/PiB2bUNsYXNzID0gbnVsbDsKICAgICAgICBwcml2YXRlIHN0YXRpYyBNZXRob2QgZ2V0UnVudGltZUFyZ3VtZW50c01ldGhvZCA9IG51bGw7CgogICAgICAgIHByaXZhdGUgc3RhdGljIHZvaWQgaW5pdCgpIHsKICAgICAgICAgICAgaWYgKHZtQ2xhc3MgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICB2bUNsYXNzID0gQ2xhc3MuZm9yTmFtZShDTEFTU05BTUUsIGZhbHNlLCBudWxsKTsKICAgICAgICAgICAgICAgICAgICBnZXRSdW50aW1lQXJndW1lbnRzTWV0aG9kID0gdm1DbGFzcy5nZXREZWNsYXJlZE1ldGhvZCgiZ2V0UnVudGltZUFyZ3VtZW50cyIpOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiB8IE5vU3VjaE1ldGhvZEV4Y2VwdGlvbiB8IFNlY3VyaXR5RXhjZXB0aW9uIGV4KSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFib3J0KGV4KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEhlbHBlciBjbGFzcyBmb3IgbmV3IG1ldGhvZCBpbiBqZGsuaW50ZXJuYWwuam1vZC5KbW9kRmlsZQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEptb2RGaWxlIHsKICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBKTU9EX0ZJTEVfQ0xBU1NOQU1FID0gImpkay5pbnRlcm5hbC5qbW9kLkptb2RGaWxlIjsKCiAgICAgICAgcHVibGljIHN0YXRpYyB2b2lkIGNoZWNrTWFnaWMoUGF0aCBmaWxlKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgaW5pdCgpOwogICAgICAgICAgICAgICAgY2hlY2tNYWdpY01ldGhvZC5pbnZva2UobnVsbCwgZmlsZSk7CiAgICAgICAgICAgIH0gY2F0Y2ggKEludm9jYXRpb25UYXJnZXRFeGNlcHRpb24gZXgpIHsKICAgICAgICAgICAgICAgIGlmIChleC5nZXRDYXVzZSgpIGluc3RhbmNlb2YgSU9FeGNlcHRpb24pIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBJT0V4Y2VwdGlvbi5jbGFzcy5jYXN0KGV4LmdldENhdXNlKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFib3J0KGV4KTsKICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiB8IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB8IFNlY3VyaXR5RXhjZXB0aW9uIGV4KSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQWJvcnQoZXgpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgICAgICBwcml2YXRlIHN0YXRpYyBDbGFzczw/PiBqbW9kRmlsZUNsYXNzID0gbnVsbDsKICAgICAgICBwcml2YXRlIHN0YXRpYyBNZXRob2QgY2hlY2tNYWdpY01ldGhvZCA9IG51bGw7CgogICAgICAgIHByaXZhdGUgc3RhdGljIHZvaWQgaW5pdCgpIHsKICAgICAgICAgICAgaWYgKGptb2RGaWxlQ2xhc3MgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICBqbW9kRmlsZUNsYXNzID0gQ2xhc3MuZm9yTmFtZShKTU9EX0ZJTEVfQ0xBU1NOQU1FLCBmYWxzZSwgbnVsbCk7CiAgICAgICAgICAgICAgICAgICAgY2hlY2tNYWdpY01ldGhvZCA9IGptb2RGaWxlQ2xhc3MuZ2V0RGVjbGFyZWRNZXRob2QoImNoZWNrTWFnaWMiLCBQYXRoLmNsYXNzKTsKICAgICAgICAgICAgICAgIH0gY2F0Y2ggKENsYXNzTm90Rm91bmRFeGNlcHRpb24gfCBOb1N1Y2hNZXRob2RFeGNlcHRpb24gfCBTZWN1cml0eUV4Y2VwdGlvbiBleCkgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBBYm9ydChleCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9Cn0KUEsDBAoAAAgAANJ9TUr0BjoEOxQAADsUAAAoAAAAY29tL3N1bi90b29scy9qYXZhYy91dGlsL0J5dGVCdWZmZXIuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMTk5OSwgMjAxMiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWw7CgppbXBvcnQgamF2YS5pby4qOwoKLyoqIEEgYnl0ZSBidWZmZXIgaXMgYSBmbGV4aWJsZSBhcnJheSB3aGljaCBncm93cyB3aGVuIGVsZW1lbnRzIGFyZQogKiAgYXBwZW5kZWQuIFRoZXJlIGFyZSBhbHNvIG1ldGhvZHMgdG8gYXBwZW5kIG5hbWVzIHRvIGJ5dGUgYnVmZmVycwogKiAgYW5kIHRvIGNvbnZlcnQgYnl0ZSBidWZmZXJzIHRvIG5hbWVzLgogKgogKiAgPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24gcmlzay4KICogIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yCiAqICBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+CiAqLwpwdWJsaWMgY2xhc3MgQnl0ZUJ1ZmZlciB7CgogICAgLyoqIEFuIGFycmF5IGhvbGRpbmcgdGhlIGJ5dGVzIGluIHRoaXMgYnVmZmVyOyBjYW4gYmUgZ3Jvd24uCiAgICAgKi8KICAgIHB1YmxpYyBieXRlW10gZWxlbXM7CgogICAgLyoqIFRoZSBjdXJyZW50IG51bWJlciBvZiBkZWZpbmVkIGJ5dGVzIGluIHRoaXMgYnVmZmVyLgogICAgICovCiAgICBwdWJsaWMgaW50IGxlbmd0aDsKCiAgICAvKiogQ3JlYXRlIGEgbmV3IGJ5dGUgYnVmZmVyLgogICAgICovCiAgICBwdWJsaWMgQnl0ZUJ1ZmZlcigpIHsKICAgICAgICB0aGlzKDY0KTsKICAgIH0KCiAgICAvKiogQ3JlYXRlIGEgbmV3IGJ5dGUgYnVmZmVyIHdpdGggYW4gaW5pdGlhbCBlbGVtZW50cyBhcnJheQogICAgICogIG9mIGdpdmVuIHNpemUuCiAgICAgKi8KICAgIHB1YmxpYyBCeXRlQnVmZmVyKGludCBpbml0aWFsU2l6ZSkgewogICAgICAgIGVsZW1zID0gbmV3IGJ5dGVbaW5pdGlhbFNpemVdOwogICAgICAgIGxlbmd0aCA9IDA7CiAgICB9CgogICAgLyoqIEFwcGVuZCBieXRlIHRvIHRoaXMgYnVmZmVyLgogICAgICovCiAgICBwdWJsaWMgdm9pZCBhcHBlbmRCeXRlKGludCBiKSB7CiAgICAgICAgZWxlbXMgPSBBcnJheVV0aWxzLmVuc3VyZUNhcGFjaXR5KGVsZW1zLCBsZW5ndGgpOwogICAgICAgIGVsZW1zW2xlbmd0aCsrXSA9IChieXRlKWI7CiAgICB9CgogICAgLyoqIEFwcGVuZCBgbGVuJyBieXRlcyBmcm9tIGJ5dGUgYXJyYXksCiAgICAgKiAgc3RhcnRpbmcgYXQgZ2l2ZW4gYHN0YXJ0JyBvZmZzZXQuCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIGFwcGVuZEJ5dGVzKGJ5dGVbXSBicywgaW50IHN0YXJ0LCBpbnQgbGVuKSB7CiAgICAgICAgZWxlbXMgPSBBcnJheVV0aWxzLmVuc3VyZUNhcGFjaXR5KGVsZW1zLCBsZW5ndGggKyBsZW4pOwogICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYnMsIHN0YXJ0LCBlbGVtcywgbGVuZ3RoLCBsZW4pOwogICAgICAgIGxlbmd0aCArPSBsZW47CiAgICB9CgogICAgLyoqIEFwcGVuZCBhbGwgYnl0ZXMgZnJvbSBnaXZlbiBieXRlIGFycmF5LgogICAgICovCiAgICBwdWJsaWMgdm9pZCBhcHBlbmRCeXRlcyhieXRlW10gYnMpIHsKICAgICAgICBhcHBlbmRCeXRlcyhicywgMCwgYnMubGVuZ3RoKTsKICAgIH0KCiAgICAvKiogQXBwZW5kIGEgY2hhcmFjdGVyIGFzIGEgdHdvIGJ5dGUgbnVtYmVyLgogICAgICovCiAgICBwdWJsaWMgdm9pZCBhcHBlbmRDaGFyKGludCB4KSB7CiAgICAgICAgZWxlbXMgPSBBcnJheVV0aWxzLmVuc3VyZUNhcGFjaXR5KGVsZW1zLCBsZW5ndGggKyAxKTsKICAgICAgICBlbGVtc1tsZW5ndGggIF0gPSAoYnl0ZSkoKHggPj4gIDgpICYgMHhGRik7CiAgICAgICAgZWxlbXNbbGVuZ3RoKzFdID0gKGJ5dGUpKCh4ICAgICAgKSAmIDB4RkYpOwogICAgICAgIGxlbmd0aCA9IGxlbmd0aCArIDI7CiAgICB9CgogICAgLyoqIEFwcGVuZCBhbiBpbnRlZ2VyIGFzIGEgZm91ciBieXRlIG51bWJlci4KICAgICAqLwogICAgcHVibGljIHZvaWQgYXBwZW5kSW50KGludCB4KSB7CiAgICAgICAgZWxlbXMgPSBBcnJheVV0aWxzLmVuc3VyZUNhcGFjaXR5KGVsZW1zLCBsZW5ndGggKyAzKTsKICAgICAgICBlbGVtc1tsZW5ndGggIF0gPSAoYnl0ZSkoKHggPj4gMjQpICYgMHhGRik7CiAgICAgICAgZWxlbXNbbGVuZ3RoKzFdID0gKGJ5dGUpKCh4ID4+IDE2KSAmIDB4RkYpOwogICAgICAgIGVsZW1zW2xlbmd0aCsyXSA9IChieXRlKSgoeCA+PiAgOCkgJiAweEZGKTsKICAgICAgICBlbGVtc1tsZW5ndGgrM10gPSAoYnl0ZSkoKHggICAgICApICYgMHhGRik7CiAgICAgICAgbGVuZ3RoID0gbGVuZ3RoICsgNDsKICAgIH0KCiAgICAvKiogQXBwZW5kIGEgbG9uZyBhcyBhbiBlaWdodCBieXRlIG51bWJlci4KICAgICAqLwogICAgcHVibGljIHZvaWQgYXBwZW5kTG9uZyhsb25nIHgpIHsKICAgICAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYnVmZmVyID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSg4KTsKICAgICAgICBEYXRhT3V0cHV0U3RyZWFtIGJ1Zm91dCA9IG5ldyBEYXRhT3V0cHV0U3RyZWFtKGJ1ZmZlcik7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgYnVmb3V0LndyaXRlTG9uZyh4KTsKICAgICAgICAgICAgYXBwZW5kQnl0ZXMoYnVmZmVyLnRvQnl0ZUFycmF5KCksIDAsIDgpOwogICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCJ3cml0ZSIpOwogICAgICAgIH0KICAgIH0KCiAgICAvKiogQXBwZW5kIGEgZmxvYXQgYXMgYSBmb3VyIGJ5dGUgbnVtYmVyLgogICAgICovCiAgICBwdWJsaWMgdm9pZCBhcHBlbmRGbG9hdChmbG9hdCB4KSB7CiAgICAgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJ1ZmZlciA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oNCk7CiAgICAgICAgRGF0YU91dHB1dFN0cmVhbSBidWZvdXQgPSBuZXcgRGF0YU91dHB1dFN0cmVhbShidWZmZXIpOwogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGJ1Zm91dC53cml0ZUZsb2F0KHgpOwogICAgICAgICAgICBhcHBlbmRCeXRlcyhidWZmZXIudG9CeXRlQXJyYXkoKSwgMCwgNCk7CiAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoIndyaXRlIik7CiAgICAgICAgfQogICAgfQoKICAgIC8qKiBBcHBlbmQgYSBkb3VibGUgYXMgYSBlaWdodCBieXRlIG51bWJlci4KICAgICAqLwogICAgcHVibGljIHZvaWQgYXBwZW5kRG91YmxlKGRvdWJsZSB4KSB7CiAgICAgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJ1ZmZlciA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oOCk7CiAgICAgICAgRGF0YU91dHB1dFN0cmVhbSBidWZvdXQgPSBuZXcgRGF0YU91dHB1dFN0cmVhbShidWZmZXIpOwogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGJ1Zm91dC53cml0ZURvdWJsZSh4KTsKICAgICAgICAgICAgYXBwZW5kQnl0ZXMoYnVmZmVyLnRvQnl0ZUFycmF5KCksIDAsIDgpOwogICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCJ3cml0ZSIpOwogICAgICAgIH0KICAgIH0KCiAgICAvKiogQXBwZW5kIGEgbmFtZS4KICAgICAqLwogICAgcHVibGljIHZvaWQgYXBwZW5kTmFtZShOYW1lIG5hbWUpIHsKICAgICAgICBhcHBlbmRCeXRlcyhuYW1lLmdldEJ5dGVBcnJheSgpLCBuYW1lLmdldEJ5dGVPZmZzZXQoKSwgbmFtZS5nZXRCeXRlTGVuZ3RoKCkpOwogICAgfQoKICAgIC8qKiBSZXNldCB0byB6ZXJvIGxlbmd0aC4KICAgICAqLwogICAgcHVibGljIHZvaWQgcmVzZXQoKSB7CiAgICAgICAgbGVuZ3RoID0gMDsKICAgIH0KCiAgICAvKiogQ29udmVydCBjb250ZW50cyB0byBuYW1lLgogICAgICovCiAgICBwdWJsaWMgTmFtZSB0b05hbWUoTmFtZXMgbmFtZXMpIHsKICAgICAgICByZXR1cm4gbmFtZXMuZnJvbVV0ZihlbGVtcywgMCwgbGVuZ3RoKTsKICAgIH0KfQpQSwMECgAACAAABjupSjHHFyiMGgAAjBoAACoAAABjb20vc3VuL3Rvb2xzL2phdmFjL3V0aWwvSW50SGFzaFRhYmxlLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTQsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhYy51dGlsOwoKLyoqCiAqIEEgaGFzaCB0YWJsZSB0aGF0IG1hcHMgT2JqZWN0IHRvIGludC4KICoKICogVGhpcyBpcyBhIGN1c3RvbSBoYXNoIHRhYmxlIG9wdGltaXNlZCBmb3IgdGhlIE9iamVjdCB7QGxpdGVyYWwgLT59IGludAogKiBtYXBzLiBUaGlzIGlzIGRvbmUgdG8gYXZvaWQgdW5uZWNlc3Nhcnkgb2JqZWN0IGFsbG9jYXRpb24gaW4gdGhlIGltYWdlIHNldC4KICoKICogQGF1dGhvciBDaGFybGVzIFR1cm5lcgogKiBAYXV0aG9yIFBlciBCb3RobmVyCiAqLwpwdWJsaWMgY2xhc3MgSW50SGFzaFRhYmxlIHsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBERUZBVUxUX0lOSVRJQUxfU0laRSA9IDY0OwogICAgcHJvdGVjdGVkIE9iamVjdFtdIG9ianM7IC8vIHRoZSBkb21haW4gc2V0CiAgICBwcm90ZWN0ZWQgaW50W10gaW50czsgLy8gdGhlIGltYWdlIHNldAogICAgcHJvdGVjdGVkIGludCBtYXNrOyAvLyB1c2VkIHRvIGNsaXAgaW50J3MgaW50byB0aGUgZG9tYWluCiAgICBwcm90ZWN0ZWQgaW50IG51bV9iaW5kaW5nczsgLy8gdGhlIG51bWJlciBvZiBtYXBwaW5ncyAoaW5jbHVkaW5nIERFTEVURUQpCiAgICBwcml2YXRlIGZpbmFsIHN0YXRpYyBPYmplY3QgREVMRVRFRCA9IG5ldyBPYmplY3QoKTsKCiAgICAvKioKICAgICAqIENvbnN0cnVjdCBhbiBPYmplY3Qge0BsaXRlcmFsIC0+fSBpbnQgaGFzaCB0YWJsZS4KICAgICAqCiAgICAgKiBUaGUgZGVmYXVsdCBzaXplIG9mIHRoZSBoYXNoIHRhYmxlIGlzIDY0IG1hcHBpbmdzLgogICAgICovCiAgICBwdWJsaWMgSW50SGFzaFRhYmxlKCkgewogICAgICAgIG9ianMgPSBuZXcgT2JqZWN0W0RFRkFVTFRfSU5JVElBTF9TSVpFXTsKICAgICAgICBpbnRzID0gbmV3IGludFtERUZBVUxUX0lOSVRJQUxfU0laRV07CiAgICAgICAgbWFzayA9IERFRkFVTFRfSU5JVElBTF9TSVpFIC0gMTsKICAgIH0KCiAgICAvKioKICAgICAqIENvbnN0cnVjdCBhbiBPYmplY3Qge0BsaXRlcmFsIC0+fSBpbnQgaGFzaCB0YWJsZSB3aXRoIGEgc3BlY2lmaWVkIGFtb3VudCBvZiBtYXBwaW5ncy4KICAgICAqIEBwYXJhbSBjYXBhY2l0eSBUaGUgbnVtYmVyIG9mIGRlZmF1bHQgbWFwcGluZ3MgaW4gdGhpcyBoYXNoIHRhYmxlLgogICAgICovCiAgICBwdWJsaWMgSW50SGFzaFRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGludCBsb2cyU2l6ZSA9IDQ7CiAgICAgICAgd2hpbGUgKGNhcGFjaXR5ID4gKDEgPDwgbG9nMlNpemUpKSB7CiAgICAgICAgICAgIGxvZzJTaXplKys7CiAgICAgICAgfQogICAgICAgIGNhcGFjaXR5ID0gMSA8PCBsb2cyU2l6ZTsKICAgICAgICBvYmpzID0gbmV3IE9iamVjdFtjYXBhY2l0eV07CiAgICAgICAgaW50cyA9IG5ldyBpbnRbY2FwYWNpdHldOwogICAgICAgIG1hc2sgPSBjYXBhY2l0eSAtIDE7CiAgICB9CgogICAgLyoqCiAgICAgKiBDb21wdXRlIHRoZSBoYXNoIGNvZGUgb2YgYSBnaXZlbiBvYmplY3QuCiAgICAgKgogICAgICogQHBhcmFtIGtleSBUaGUgb2JqZWN0IHdob3NlIGhhc2ggY29kZSBpcyB0byBiZSBjb21wdXRlZC4KICAgICAqIEByZXR1cm4gemVybyBpZiB0aGUgb2JqZWN0IGlzIG51bGwsIG90aGVyd2lzZSB0aGUgaWRlbnRpdHlIYXNoQ29kZQogICAgICovCiAgICBwdWJsaWMgaW50IGhhc2goT2JqZWN0IGtleSkgewogICAgICAgIHJldHVybiBTeXN0ZW0uaWRlbnRpdHlIYXNoQ29kZShrZXkpOwogICAgfQoKICAgIC8qKgogICAgICogRmluZCBlaXRoZXIgdGhlIGluZGV4IG9mIGEga2V5J3MgdmFsdWUsIG9yIHRoZSBpbmRleCBvZiBhbiBhdmFpbGFibGUgc3BhY2UuCiAgICAgKgogICAgICogQHBhcmFtIGtleSBUaGUga2V5IHRvIHdob3NlIHZhbHVlIHlvdSB3YW50IHRvIGZpbmQuCiAgICAgKiBAcGFyYW0gaGFzaCBUaGUgaGFzaCBjb2RlIG9mIHRoaXMga2V5LgogICAgICogQHJldHVybiBFaXRoZXIgdGhlIGluZGV4IG9mIHRoZSBrZXkncyB2YWx1ZSwgb3IgYW4gaW5kZXggcG9pbnRpbmcgdG8KICAgICAqIHVub2NjdXBpZWQgc3BhY2UuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgbG9va3VwKE9iamVjdCBrZXksIGludCBoYXNoKSB7CiAgICAgICAgT2JqZWN0IG5vZGU7CiAgICAgICAgaW50IGhhc2gxID0gaGFzaCBeIChoYXNoID4+PiAxNSk7CiAgICAgICAgaW50IGhhc2gyID0gKGhhc2ggXiAoaGFzaCA8PCA2KSkgfCAxOyAvL2Vuc3VyZSBjb3ByaW1lbmVzcwogICAgICAgIGludCBkZWxldGVkID0gLTE7CiAgICAgICAgZm9yIChpbnQgaSA9IGhhc2gxICYgbWFzazs7IGkgPSAoaSArIGhhc2gyKSAmIG1hc2spIHsKICAgICAgICAgICAgbm9kZSA9IG9ianNbaV07CiAgICAgICAgICAgIGlmIChub2RlID09IGtleSkKICAgICAgICAgICAgICAgIHJldHVybiBpOwogICAgICAgICAgICBpZiAobm9kZSA9PSBudWxsKQogICAgICAgICAgICAgICAgcmV0dXJuIGRlbGV0ZWQgPj0gMCA/IGRlbGV0ZWQgOiBpOwogICAgICAgICAgICBpZiAobm9kZSA9PSBERUxFVEVEICYmIGRlbGV0ZWQgPCAwKQogICAgICAgICAgICAgICAgZGVsZXRlZCA9IGk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogTG9va3VwIGEgZ2l2ZW4ga2V5J3MgdmFsdWUgaW4gdGhlIGhhc2ggdGFibGUuCiAgICAgKgogICAgICogQHBhcmFtIGtleSBUaGUga2V5IHdob3NlIHZhbHVlIHlvdSB3YW50IHRvIGZpbmQuCiAgICAgKiBAcmV0dXJuIEVpdGhlciB0aGUgaW5kZXggb2YgdGhlIGtleSdzIHZhbHVlLCBvciBhbiBpbmRleCBwb2ludGluZyB0bwogICAgICogdW5vY2N1cGllZCBzcGFjZS4KICAgICAqLwogICAgcHVibGljIGludCBsb29rdXAoT2JqZWN0IGtleSkgewogICAgICAgIHJldHVybiBsb29rdXAoa2V5LCBoYXNoKGtleSkpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJuIHRoZSB2YWx1ZSBzdG9yZWQgYXQgdGhlIHNwZWNpZmllZCBpbmRleCBpbiB0aGUgdGFibGUuCiAgICAgKgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBpbnNwZWN0LCBhcyByZXR1cm5lZCBmcm9tIHtAbGluayAjbG9va3VwfQogICAgICogQHJldHVybiBBIG5vbi1uZWdhdGl2ZSBpbnRlZ2VyIGlmIHRoZSBpbmRleCBjb250YWlucyBhIG5vbi1udWxsCiAgICAgKiAgICAgICAgIHZhbHVlLCBvciAtMSBpZiBpdCBkb2VzLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldEZyb21JbmRleChpbnQgaW5kZXgpIHsKICAgICAgICBPYmplY3Qgbm9kZSA9IG9ianNbaW5kZXhdOwogICAgICAgIHJldHVybiBub2RlID09IG51bGwgfHwgbm9kZSA9PSBERUxFVEVEID8gLTEgOiBpbnRzW2luZGV4XTsKICAgIH0KCiAgICAvKioKICAgICAqIEFzc29jaWF0ZXMgdGhlIHNwZWNpZmllZCBrZXkgd2l0aCB0aGUgc3BlY2lmaWVkIHZhbHVlIGluIHRoaXMgbWFwLgogICAgICoKICAgICAqIEBwYXJhbSBrZXkga2V5IHdpdGggd2hpY2ggdGhlIHNwZWNpZmllZCB2YWx1ZSBpcyB0byBiZSBhc3NvY2lhdGVkLgogICAgICogQHBhcmFtIHZhbHVlIHZhbHVlIHRvIGJlIGFzc29jaWF0ZWQgd2l0aCB0aGUgc3BlY2lmaWVkIGtleS4KICAgICAqIEBwYXJhbSBpbmRleCB0aGUgaW5kZXggYXQgd2hpY2ggdG8gcGxhY2UgdGhpcyBiaW5kaW5nLCBhcyByZXR1cm5lZAogICAgICogICAgICAgICAgICAgIGZyb20ge0BsaW5rICNsb29rdXB9LgogICAgICogQHJldHVybiBwcmV2aW91cyB2YWx1ZSBhc3NvY2lhdGVkIHdpdGggc3BlY2lmaWVkIGtleSwgb3IgLTEgaWYgdGhlcmUgd2FzCiAgICAgKiBubyBtYXBwaW5nIGZvciBrZXkuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgcHV0QXRJbmRleChPYmplY3Qga2V5LCBpbnQgdmFsdWUsIGludCBpbmRleCkgewogICAgICAgIE9iamVjdCBvbGQgPSBvYmpzW2luZGV4XTsKICAgICAgICBpZiAob2xkID09IG51bGwgfHwgb2xkID09IERFTEVURUQpIHsKICAgICAgICAgICAgb2Jqc1tpbmRleF0gPSBrZXk7CiAgICAgICAgICAgIGludHNbaW5kZXhdID0gdmFsdWU7CiAgICAgICAgICAgIGlmIChvbGQgIT0gREVMRVRFRCkKICAgICAgICAgICAgICAgIG51bV9iaW5kaW5ncysrOwogICAgICAgICAgICBpZiAoMyAqIG51bV9iaW5kaW5ncyA+PSAyICogb2Jqcy5sZW5ndGgpCiAgICAgICAgICAgICAgICByZWhhc2goKTsKICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgIH0gZWxzZSB7IC8vIHVwZGF0ZSBleGlzdGluZyBtYXBwaW5nCiAgICAgICAgICAgIGludCBvbGRWYWx1ZSA9IGludHNbaW5kZXhdOwogICAgICAgICAgICBpbnRzW2luZGV4XSA9IHZhbHVlOwogICAgICAgICAgICByZXR1cm4gb2xkVmFsdWU7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBpbnQgcmVtb3ZlKE9iamVjdCBrZXkpIHsKICAgICAgICBpbnQgaW5kZXggPSBsb29rdXAoa2V5KTsKICAgICAgICBPYmplY3Qgb2xkID0gb2Jqc1tpbmRleF07CiAgICAgICAgaWYgKG9sZCA9PSBudWxsIHx8IG9sZCA9PSBERUxFVEVEKQogICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgb2Jqc1tpbmRleF0gPSBERUxFVEVEOwogICAgICAgIHJldHVybiBpbnRzW2luZGV4XTsKICAgIH0KCiAgICAvKioKICAgICAqIEV4cGFuZCB0aGUgaGFzaCB0YWJsZSB3aGVuIGl0IGV4Y2VlZHMgdGhlIGxvYWQgZmFjdG9yLgogICAgICoKICAgICAqIFJlaGFzaCB0aGUgZXhpc3Rpbmcgb2JqZWN0cy4KICAgICAqLwogICAgcHJvdGVjdGVkIHZvaWQgcmVoYXNoKCkgewogICAgICAgIE9iamVjdFtdIG9sZE9ianNUYWJsZSA9IG9ianM7CiAgICAgICAgaW50W10gb2xkSW50c1RhYmxlID0gaW50czsKICAgICAgICBpbnQgb2xkQ2FwYWNpdHkgPSBvbGRPYmpzVGFibGUubGVuZ3RoOwogICAgICAgIGludCBuZXdDYXBhY2l0eSA9IG9sZENhcGFjaXR5IDw8IDE7CiAgICAgICAgT2JqZWN0W10gbmV3T2JqVGFibGUgPSBuZXcgT2JqZWN0W25ld0NhcGFjaXR5XTsKICAgICAgICBpbnRbXSBuZXdJbnRUYWJsZSA9IG5ldyBpbnRbbmV3Q2FwYWNpdHldOwogICAgICAgIGludCBuZXdNYXNrID0gbmV3Q2FwYWNpdHkgLSAxOwogICAgICAgIG9ianMgPSBuZXdPYmpUYWJsZTsKICAgICAgICBpbnRzID0gbmV3SW50VGFibGU7CiAgICAgICAgbWFzayA9IG5ld01hc2s7CiAgICAgICAgbnVtX2JpbmRpbmdzID0gMDsgLy8gdGhpcyBpcyByZWNvbXB1dGVkIGJlbG93CiAgICAgICAgT2JqZWN0IGtleTsKICAgICAgICBmb3IgKGludCBpID0gb2xkSW50c1RhYmxlLmxlbmd0aDsgLS1pID49IDA7KSB7CiAgICAgICAgICAgIGtleSA9IG9sZE9ianNUYWJsZVtpXTsKICAgICAgICAgICAgaWYgKGtleSAhPSBudWxsICYmIGtleSAhPSBERUxFVEVEKQogICAgICAgICAgICAgICAgcHV0QXRJbmRleChrZXksIG9sZEludHNUYWJsZVtpXSwgbG9va3VwKGtleSwgaGFzaChrZXkpKSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogUmVtb3ZlcyBhbGwgbWFwcGluZ3MgZnJvbSB0aGlzIG1hcC4KICAgICAqLwogICAgcHVibGljIHZvaWQgY2xlYXIoKSB7CiAgICAgICAgZm9yIChpbnQgaSA9IG9ianMubGVuZ3RoOyAtLWkgPj0gMDspIHsKICAgICAgICAgICAgb2Jqc1tpXSA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG51bV9iaW5kaW5ncyA9IDA7CiAgICB9Cn0KUEsDBAoAAAgAAAY7qUrrK4zkEjIAABIyAAAlAAAAY29tL3N1bi90b29scy9qYXZhYy91dGlsL0NvbnZlcnQuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMTk5OSwgMjAxNywgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWw7CgovKiogVXRpbGl0eSBjbGFzcyBmb3Igc3RhdGljIGNvbnZlcnNpb24gbWV0aG9kcyBiZXR3ZWVuIG51bWJlcnMKICogIGFuZCBzdHJpbmdzIGluIHZhcmlvdXMgZm9ybWF0cy4KICoKICogIDxwPk5vdGUgcmVnYXJkaW5nIFVURi04LgogKiAgVGhlIEpWTVMgZGVmaW5lcyBpdHMgb3duIHZlcnNpb24gb2YgdGhlIFVURi04IGZvcm1hdCBzbyB0aGF0IGl0CiAqICBjb250YWlucyBubyB6ZXJvIGJ5dGVzIChtb2RpZmllZCBVVEYtOCkuIFRoaXMgaXMgbm90IGFjdHVhbGx5IHRoZSBzYW1lCiAqICBhcyBDaGFyc2V0LmZvck5hbWUoIlVURi04IikuCiAqCiAqICA8cD4KICogIFNlZSBhbHNvOgogKiAgPHVsPgogKiAgPGxpPjxhIGhyZWY9Imh0dHA6Ly9kb2NzLm9yYWNsZS5jb20vamF2YXNlL3NwZWNzL2p2bXMvc2U3L2h0bWwvanZtcy00Lmh0bWwjanZtcy00LjQuNyI+CiAqICAgIEpWTVMgNC40LjcgPC9hPjwvbGk+CiAqICA8bGk+PGEgaHJlZj0iaHR0cDovL2RvY3Mub3JhY2xlLmNvbS9qYXZhc2UvNy9kb2NzL2FwaS9qYXZhL2lvL0RhdGFJbnB1dC5odG1sI21vZGlmaWVkLXV0Zi04Ij4KICAgICAgamF2YS5pby5EYXRhSW5wdXQ6IE1vZGlmaWVkIFVURi04IDwvYT48L2xpPgogICAgPGxpPjxhIGhyZWY9Imh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1VURi04I01vZGlmaWVkX1VURi04Ij4KICAgICAgTW9kaWZpZWQgVVRGLTggKHdpa2lwZWRpYSkgPC9hPjwvbGk+CiAqICA8L3VsPgogKgogKiAgVGhlIG1ldGhvZHMgaGVyZSBzdXBwb3J0IG1vZGlmaWVkIFVURi04LgogKgogKiAgPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24gcmlzay4KICogIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yCiAqICBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+CiAqLwpwdWJsaWMgY2xhc3MgQ29udmVydCB7CgogICAgLyoqIENvbnZlcnQgc3RyaW5nIHRvIGludGVnZXIuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgaW50IHN0cmluZzJpbnQoU3RyaW5nIHMsIGludCByYWRpeCkKICAgICAgICB0aHJvd3MgTnVtYmVyRm9ybWF0RXhjZXB0aW9uIHsKICAgICAgICBpZiAocmFkaXggPT0gMTApIHsKICAgICAgICAgICAgcmV0dXJuIEludGVnZXIucGFyc2VJbnQocywgcmFkaXgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGNoYXJbXSBjcyA9IHMudG9DaGFyQXJyYXkoKTsKICAgICAgICAgICAgaW50IGxpbWl0ID0gSW50ZWdlci5NQVhfVkFMVUUgLyAocmFkaXgvMik7CiAgICAgICAgICAgIGludCBuID0gMDsKICAgICAgICAgICAgZm9yIChjaGFyIGMgOiBjcykgewogICAgICAgICAgICAgICAgaW50IGQgPSBDaGFyYWN0ZXIuZGlnaXQoYywgcmFkaXgpOwogICAgICAgICAgICAgICAgaWYgKG4gPCAwIHx8CiAgICAgICAgICAgICAgICAgICAgbiA+IGxpbWl0IHx8CiAgICAgICAgICAgICAgICAgICAgbiAqIHJhZGl4ID4gSW50ZWdlci5NQVhfVkFMVUUgLSBkKQogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBOdW1iZXJGb3JtYXRFeGNlcHRpb24oKTsKICAgICAgICAgICAgICAgIG4gPSBuICogcmFkaXggKyBkOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBuOwogICAgICAgIH0KICAgIH0KCiAgICAvKiogQ29udmVydCBzdHJpbmcgdG8gbG9uZyBpbnRlZ2VyLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGxvbmcgc3RyaW5nMmxvbmcoU3RyaW5nIHMsIGludCByYWRpeCkKICAgICAgICB0aHJvd3MgTnVtYmVyRm9ybWF0RXhjZXB0aW9uIHsKICAgICAgICBpZiAocmFkaXggPT0gMTApIHsKICAgICAgICAgICAgcmV0dXJuIExvbmcucGFyc2VMb25nKHMsIHJhZGl4KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBjaGFyW10gY3MgPSBzLnRvQ2hhckFycmF5KCk7CiAgICAgICAgICAgIGxvbmcgbGltaXQgPSBMb25nLk1BWF9WQUxVRSAvIChyYWRpeC8yKTsKICAgICAgICAgICAgbG9uZyBuID0gMDsKICAgICAgICAgICAgZm9yIChjaGFyIGMgOiBjcykgewogICAgICAgICAgICAgICAgaW50IGQgPSBDaGFyYWN0ZXIuZGlnaXQoYywgcmFkaXgpOwogICAgICAgICAgICAgICAgaWYgKG4gPCAwIHx8CiAgICAgICAgICAgICAgICAgICAgbiA+IGxpbWl0IHx8CiAgICAgICAgICAgICAgICAgICAgbiAqIHJhZGl4ID4gTG9uZy5NQVhfVkFMVUUgLSBkKQogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBOdW1iZXJGb3JtYXRFeGNlcHRpb24oKTsKICAgICAgICAgICAgICAgIG4gPSBuICogcmFkaXggKyBkOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBuOwogICAgICAgIH0KICAgIH0KCi8qIENvbnZlcnNpb24gcm91dGluZXMgYmV0d2VlbiBuYW1lcywgc3RyaW5ncywgYW5kIGJ5dGUgYXJyYXlzIGluIFV0ZjggZm9ybWF0CiAqLwoKICAgIC8qKiBDb252ZXJ0IGBsZW4nIGJ5dGVzIGZyb20gdXRmOCB0byBjaGFyYWN0ZXJzLgogICAgICogIFBhcmFtZXRlcnMgYXJlIGFzIGluIFN5c3RlbS5hcnJheWNvcHkKICAgICAqICBSZXR1cm4gZmlyc3QgaW5kZXggaW4gYGRzdCcgcGFzdCB0aGUgbGFzdCBjb3BpZWQgY2hhci4KICAgICAqICBAcGFyYW0gc3JjICAgICAgICBUaGUgYXJyYXkgaG9sZGluZyB0aGUgYnl0ZXMgdG8gY29udmVydC4KICAgICAqICBAcGFyYW0gc2luZGV4ICAgICBUaGUgc3RhcnQgaW5kZXggZnJvbSB3aGljaCBieXRlcyBhcmUgY29udmVydGVkLgogICAgICogIEBwYXJhbSBkc3QgICAgICAgIFRoZSBhcnJheSBob2xkaW5nIHRoZSBjb252ZXJ0ZWQgY2hhcmFjdGVycy4uCiAgICAgKiAgQHBhcmFtIGRpbmRleCAgICAgVGhlIHN0YXJ0IGluZGV4IGZyb20gd2hpY2ggY29udmVydGVkIGNoYXJhY3RlcnMKICAgICAqICAgICAgICAgICAgICAgICAgICBhcmUgd3JpdHRlbi4KICAgICAqICBAcGFyYW0gbGVuICAgICAgICBUaGUgbWF4aW11bSBudW1iZXIgb2YgYnl0ZXMgdG8gY29udmVydC4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBpbnQgdXRmMmNoYXJzKGJ5dGVbXSBzcmMsIGludCBzaW5kZXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhcltdIGRzdCwgaW50IGRpbmRleCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbGVuKSB7CiAgICAgICAgaW50IGkgPSBzaW5kZXg7CiAgICAgICAgaW50IGogPSBkaW5kZXg7CiAgICAgICAgaW50IGxpbWl0ID0gc2luZGV4ICsgbGVuOwogICAgICAgIHdoaWxlIChpIDwgbGltaXQpIHsKICAgICAgICAgICAgaW50IGIgPSBzcmNbaSsrXSAmIDB4RkY7CiAgICAgICAgICAgIGlmIChiID49IDB4RTApIHsKICAgICAgICAgICAgICAgIGIgPSAoYiAmIDB4MEYpIDw8IDEyOwogICAgICAgICAgICAgICAgYiA9IGIgfCAoc3JjW2krK10gJiAweDNGKSA8PCA2OwogICAgICAgICAgICAgICAgYiA9IGIgfCAoc3JjW2krK10gJiAweDNGKTsKICAgICAgICAgICAgfSBlbHNlIGlmIChiID49IDB4QzApIHsKICAgICAgICAgICAgICAgIGIgPSAoYiAmIDB4MUYpIDw8IDY7CiAgICAgICAgICAgICAgICBiID0gYiB8IChzcmNbaSsrXSAmIDB4M0YpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGRzdFtqKytdID0gKGNoYXIpYjsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGo7CiAgICB9CgogICAgLyoqIFJldHVybiBieXRlcyBpbiBVdGY4IHJlcHJlc2VudGF0aW9uIGFzIGFuIGFycmF5IG9mIGNoYXJhY3RlcnMuCiAgICAgKiAgQHBhcmFtIHNyYyAgICAgICAgVGhlIGFycmF5IGhvbGRpbmcgdGhlIGJ5dGVzLgogICAgICogIEBwYXJhbSBzaW5kZXggICAgIFRoZSBzdGFydCBpbmRleCBmcm9tIHdoaWNoIGJ5dGVzIGFyZSBjb252ZXJ0ZWQuCiAgICAgKiAgQHBhcmFtIGxlbiAgICAgICAgVGhlIG1heGltdW0gbnVtYmVyIG9mIGJ5dGVzIHRvIGNvbnZlcnQuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgY2hhcltdIHV0ZjJjaGFycyhieXRlW10gc3JjLCBpbnQgc2luZGV4LCBpbnQgbGVuKSB7CiAgICAgICAgY2hhcltdIGRzdCA9IG5ldyBjaGFyW2xlbl07CiAgICAgICAgaW50IGxlbjEgPSB1dGYyY2hhcnMoc3JjLCBzaW5kZXgsIGRzdCwgMCwgbGVuKTsKICAgICAgICBjaGFyW10gcmVzdWx0ID0gbmV3IGNoYXJbbGVuMV07CiAgICAgICAgU3lzdGVtLmFycmF5Y29weShkc3QsIDAsIHJlc3VsdCwgMCwgbGVuMSk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KCiAgICAvKiogUmV0dXJuIGFsbCBieXRlcyBvZiBhIGdpdmVuIGFycmF5IGluIFV0ZjggcmVwcmVzZW50YXRpb24KICAgICAqICBhcyBhbiBhcnJheSBvZiBjaGFyYWN0ZXJzLgogICAgICogIEBwYXJhbSBzcmMgICAgICAgIFRoZSBhcnJheSBob2xkaW5nIHRoZSBieXRlcy4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBjaGFyW10gdXRmMmNoYXJzKGJ5dGVbXSBzcmMpIHsKICAgICAgICByZXR1cm4gdXRmMmNoYXJzKHNyYywgMCwgc3JjLmxlbmd0aCk7CiAgICB9CgogICAgLyoqIFJldHVybiBieXRlcyBpbiBVdGY4IHJlcHJlc2VudGF0aW9uIGFzIGEgc3RyaW5nLgogICAgICogIEBwYXJhbSBzcmMgICAgICAgIFRoZSBhcnJheSBob2xkaW5nIHRoZSBieXRlcy4KICAgICAqICBAcGFyYW0gc2luZGV4ICAgICBUaGUgc3RhcnQgaW5kZXggZnJvbSB3aGljaCBieXRlcyBhcmUgY29udmVydGVkLgogICAgICogIEBwYXJhbSBsZW4gICAgICAgIFRoZSBtYXhpbXVtIG51bWJlciBvZiBieXRlcyB0byBjb252ZXJ0LgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIFN0cmluZyB1dGYyc3RyaW5nKGJ5dGVbXSBzcmMsIGludCBzaW5kZXgsIGludCBsZW4pIHsKICAgICAgICBjaGFyIGRzdFtdID0gbmV3IGNoYXJbbGVuXTsKICAgICAgICBpbnQgbGVuMSA9IHV0ZjJjaGFycyhzcmMsIHNpbmRleCwgZHN0LCAwLCBsZW4pOwogICAgICAgIHJldHVybiBuZXcgU3RyaW5nKGRzdCwgMCwgbGVuMSk7CiAgICB9CgogICAgLyoqIFJldHVybiBhbGwgYnl0ZXMgb2YgYSBnaXZlbiBhcnJheSBpbiBVdGY4IHJlcHJlc2VudGF0aW9uCiAgICAgKiAgYXMgYSBzdHJpbmcuCiAgICAgKiAgQHBhcmFtIHNyYyAgICAgICAgVGhlIGFycmF5IGhvbGRpbmcgdGhlIGJ5dGVzLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIFN0cmluZyB1dGYyc3RyaW5nKGJ5dGVbXSBzcmMpIHsKICAgICAgICByZXR1cm4gdXRmMnN0cmluZyhzcmMsIDAsIHNyYy5sZW5ndGgpOwogICAgfQoKICAgIC8qKiBDb3B5IGNoYXJhY3RlcnMgaW4gc291cmNlIGFycmF5IHRvIGJ5dGVzIGluIHRhcmdldCBhcnJheSwKICAgICAqICBjb252ZXJ0aW5nIHRoZW0gdG8gVXRmOCByZXByZXNlbnRhdGlvbi4KICAgICAqICBUaGUgdGFyZ2V0IGFycmF5IG11c3QgYmUgbGFyZ2UgZW5vdWdoIHRvIGhvbGQgdGhlIHJlc3VsdC4KICAgICAqICByZXR1cm5zIGZpcnN0IGluZGV4IGluIGBkc3QnIHBhc3QgdGhlIGxhc3QgY29waWVkIGJ5dGUuCiAgICAgKiAgQHBhcmFtIHNyYyAgICAgICAgVGhlIGFycmF5IGhvbGRpbmcgdGhlIGNoYXJhY3RlcnMgdG8gY29udmVydC4KICAgICAqICBAcGFyYW0gc2luZGV4ICAgICBUaGUgc3RhcnQgaW5kZXggZnJvbSB3aGljaCBjaGFyYWN0ZXJzIGFyZSBjb252ZXJ0ZWQuCiAgICAgKiAgQHBhcmFtIGRzdCAgICAgICAgVGhlIGFycmF5IGhvbGRpbmcgdGhlIGNvbnZlcnRlZCBjaGFyYWN0ZXJzLi4KICAgICAqICBAcGFyYW0gZGluZGV4ICAgICBUaGUgc3RhcnQgaW5kZXggZnJvbSB3aGljaCBjb252ZXJ0ZWQgYnl0ZXMKICAgICAqICAgICAgICAgICAgICAgICAgICBhcmUgd3JpdHRlbi4KICAgICAqICBAcGFyYW0gbGVuICAgICAgICBUaGUgbWF4aW11bSBudW1iZXIgb2YgY2hhcmFjdGVycyB0byBjb252ZXJ0LgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGludCBjaGFyczJ1dGYoY2hhcltdIHNyYywgaW50IHNpbmRleCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBieXRlW10gZHN0LCBpbnQgZGluZGV4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBsZW4pIHsKICAgICAgICBpbnQgaiA9IGRpbmRleDsKICAgICAgICBpbnQgbGltaXQgPSBzaW5kZXggKyBsZW47CiAgICAgICAgZm9yIChpbnQgaSA9IHNpbmRleDsgaSA8IGxpbWl0OyBpKyspIHsKICAgICAgICAgICAgY2hhciBjaCA9IHNyY1tpXTsKICAgICAgICAgICAgaWYgKDEgPD0gY2ggJiYgY2ggPD0gMHg3RikgewogICAgICAgICAgICAgICAgZHN0W2orK10gPSAoYnl0ZSljaDsKICAgICAgICAgICAgfSBlbHNlIGlmIChjaCA8PSAweDdGRikgewogICAgICAgICAgICAgICAgZHN0W2orK10gPSAoYnl0ZSkoMHhDMCB8IChjaCA+PiA2KSk7CiAgICAgICAgICAgICAgICBkc3RbaisrXSA9IChieXRlKSgweDgwIHwgKGNoICYgMHgzRikpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgZHN0W2orK10gPSAoYnl0ZSkoMHhFMCB8IChjaCA+PiAxMikpOwogICAgICAgICAgICAgICAgZHN0W2orK10gPSAoYnl0ZSkoMHg4MCB8ICgoY2ggPj4gNikgJiAweDNGKSk7CiAgICAgICAgICAgICAgICBkc3RbaisrXSA9IChieXRlKSgweDgwIHwgKGNoICYgMHgzRikpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBqOwogICAgfQoKICAgIC8qKiBSZXR1cm4gY2hhcmFjdGVycyBhcyBhbiBhcnJheSBvZiBieXRlcyBpbiBVdGY4IHJlcHJlc2VudGF0aW9uLgogICAgICogIEBwYXJhbSBzcmMgICAgICAgIFRoZSBhcnJheSBob2xkaW5nIHRoZSBjaGFyYWN0ZXJzLgogICAgICogIEBwYXJhbSBzaW5kZXggICAgIFRoZSBzdGFydCBpbmRleCBmcm9tIHdoaWNoIGNoYXJhY3RlcnMgYXJlIGNvbnZlcnRlZC4KICAgICAqICBAcGFyYW0gbGVuICAgICAgICBUaGUgbWF4aW11bSBudW1iZXIgb2YgY2hhcmFjdGVycyB0byBjb252ZXJ0LgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGJ5dGVbXSBjaGFyczJ1dGYoY2hhcltdIHNyYywgaW50IHNpbmRleCwgaW50IGxlbikgewogICAgICAgIGJ5dGVbXSBkc3QgPSBuZXcgYnl0ZVtsZW4gKiAzXTsKICAgICAgICBpbnQgbGVuMSA9IGNoYXJzMnV0ZihzcmMsIHNpbmRleCwgZHN0LCAwLCBsZW4pOwogICAgICAgIGJ5dGVbXSByZXN1bHQgPSBuZXcgYnl0ZVtsZW4xXTsKICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KGRzdCwgMCwgcmVzdWx0LCAwLCBsZW4xKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgfQoKICAgIC8qKiBSZXR1cm4gYWxsIGNoYXJhY3RlcnMgaW4gZ2l2ZW4gYXJyYXkgYXMgYW4gYXJyYXkgb2YgYnl0ZXMKICAgICAqICBpbiBVdGY4IHJlcHJlc2VudGF0aW9uLgogICAgICogIEBwYXJhbSBzcmMgICAgICAgIFRoZSBhcnJheSBob2xkaW5nIHRoZSBjaGFyYWN0ZXJzLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGJ5dGVbXSBjaGFyczJ1dGYoY2hhcltdIHNyYykgewogICAgICAgIHJldHVybiBjaGFyczJ1dGYoc3JjLCAwLCBzcmMubGVuZ3RoKTsKICAgIH0KCiAgICAvKiogUmV0dXJuIHN0cmluZyBhcyBhbiBhcnJheSBvZiBieXRlcyBpbiBpbiBVdGY4IHJlcHJlc2VudGF0aW9uLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGJ5dGVbXSBzdHJpbmcydXRmKFN0cmluZyBzKSB7CiAgICAgICAgcmV0dXJuIGNoYXJzMnV0ZihzLnRvQ2hhckFycmF5KCkpOwogICAgfQoKICAgIC8qKgogICAgICogRXNjYXBlcyBlYWNoIGNoYXJhY3RlciBpbiBhIHN0cmluZyB0aGF0IGhhcyBhbiBlc2NhcGUgc2VxdWVuY2Ugb3IKICAgICAqIGlzIG5vbi1wcmludGFibGUgQVNDSUkuICBMZWF2ZXMgbm9uLUFTQ0lJIGNoYXJhY3RlcnMgYWxvbmUuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHF1b3RlKFN0cmluZyBzKSB7CiAgICAgICAgU3RyaW5nQnVpbGRlciBidWYgPSBuZXcgU3RyaW5nQnVpbGRlcigpOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcy5sZW5ndGgoKTsgaSsrKSB7CiAgICAgICAgICAgIGJ1Zi5hcHBlbmQocXVvdGUocy5jaGFyQXQoaSkpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1Zi50b1N0cmluZygpOwogICAgfQoKICAgIC8qKgogICAgICogRXNjYXBlcyBhIGNoYXJhY3RlciBpZiBpdCBoYXMgYW4gZXNjYXBlIHNlcXVlbmNlIG9yIGlzCiAgICAgKiBub24tcHJpbnRhYmxlIEFTQ0lJLiAgTGVhdmVzIG5vbi1BU0NJSSBjaGFyYWN0ZXJzIGFsb25lLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBxdW90ZShjaGFyIGNoKSB7CiAgICAgICAgc3dpdGNoIChjaCkgewogICAgICAgIGNhc2UgJ1xiJzogIHJldHVybiAiXFxiIjsKICAgICAgICBjYXNlICdcZic6ICByZXR1cm4gIlxcZiI7CiAgICAgICAgY2FzZSAnXG4nOiAgcmV0dXJuICJcXG4iOwogICAgICAgIGNhc2UgJ1xyJzogIHJldHVybiAiXFxyIjsKICAgICAgICBjYXNlICdcdCc6ICByZXR1cm4gIlxcdCI7CiAgICAgICAgY2FzZSAnXCcnOiAgcmV0dXJuICJcXCciOwogICAgICAgIGNhc2UgJ1wiJzogIHJldHVybiAiXFxcIiI7CiAgICAgICAgY2FzZSAnXFwnOiAgcmV0dXJuICJcXFxcIjsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICByZXR1cm4gKGlzUHJpbnRhYmxlQXNjaWkoY2gpKQogICAgICAgICAgICAgICAgPyBTdHJpbmcudmFsdWVPZihjaCkKICAgICAgICAgICAgICAgIDogU3RyaW5nLmZvcm1hdCgiXFx1JTA0eCIsIChpbnQpIGNoKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBJcyBhIGNoYXJhY3RlciBwcmludGFibGUgQVNDSUk/CiAgICAgKi8KICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gaXNQcmludGFibGVBc2NpaShjaGFyIGNoKSB7CiAgICAgICAgcmV0dXJuIGNoID49ICcgJyAmJiBjaCA8PSAnfic7CiAgICB9CgogICAgLyoqIEVzY2FwZSBhbGwgdW5pY29kZSBjaGFyYWN0ZXJzIGluIHN0cmluZy4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBTdHJpbmcgZXNjYXBlVW5pY29kZShTdHJpbmcgcykgewogICAgICAgIGludCBsZW4gPSBzLmxlbmd0aCgpOwogICAgICAgIGludCBpID0gMDsKICAgICAgICB3aGlsZSAoaSA8IGxlbikgewogICAgICAgICAgICBjaGFyIGNoID0gcy5jaGFyQXQoaSk7CiAgICAgICAgICAgIGlmIChjaCA+IDI1NSkgewogICAgICAgICAgICAgICAgU3RyaW5nQnVpbGRlciBidWYgPSBuZXcgU3RyaW5nQnVpbGRlcigpOwogICAgICAgICAgICAgICAgYnVmLmFwcGVuZChzLnN1YnN0cmluZygwLCBpKSk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaSA8IGxlbikgewogICAgICAgICAgICAgICAgICAgIGNoID0gcy5jaGFyQXQoaSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKGNoID4gMjU1KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQoIlxcdSIpOwogICAgICAgICAgICAgICAgICAgICAgICBidWYuYXBwZW5kKENoYXJhY3Rlci5mb3JEaWdpdCgoY2ggPj4gMTIpICUgMTYsIDE2KSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQoQ2hhcmFjdGVyLmZvckRpZ2l0KChjaCA+PiAgOCkgJSAxNiwgMTYpKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnVmLmFwcGVuZChDaGFyYWN0ZXIuZm9yRGlnaXQoKGNoID4+ICA0KSAlIDE2LCAxNikpOwogICAgICAgICAgICAgICAgICAgICAgICBidWYuYXBwZW5kKENoYXJhY3Rlci5mb3JEaWdpdCgoY2ggICAgICApICUgMTYsIDE2KSk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgYnVmLmFwcGVuZChjaCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGkrKzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHMgPSBidWYudG9TdHJpbmcoKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGkrKzsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgIH0KCi8qIENvbnZlcnNpb24gcm91dGluZXMgZm9yIHF1YWxpZmllZCBuYW1lIHNwbGl0dGluZwogKi8KICAgIC8qKiBSZXR1cm4gdGhlIGxhc3QgcGFydCBvZiBhIGNsYXNzIG5hbWUuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgTmFtZSBzaG9ydE5hbWUoTmFtZSBjbGFzc25hbWUpIHsKICAgICAgICByZXR1cm4gY2xhc3NuYW1lLnN1Yk5hbWUoCiAgICAgICAgICAgIGNsYXNzbmFtZS5sYXN0SW5kZXhPZigoYnl0ZSknLicpICsgMSwgY2xhc3NuYW1lLmdldEJ5dGVMZW5ndGgoKSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBTdHJpbmcgc2hvcnROYW1lKFN0cmluZyBjbGFzc25hbWUpIHsKICAgICAgICByZXR1cm4gY2xhc3NuYW1lLnN1YnN0cmluZyhjbGFzc25hbWUubGFzdEluZGV4T2YoJy4nKSArIDEpOwogICAgfQoKICAgIC8qKiBSZXR1cm4gdGhlIHBhY2thZ2UgbmFtZSBvZiBhIGNsYXNzIG5hbWUsIGV4Y2x1ZGluZyB0aGUgdHJhaWxpbmcgJy4nLAogICAgICogICIiIGlmIG5vdCBleGlzdGVudC4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBOYW1lIHBhY2thZ2VQYXJ0KE5hbWUgY2xhc3NuYW1lKSB7CiAgICAgICAgcmV0dXJuIGNsYXNzbmFtZS5zdWJOYW1lKDAsIGNsYXNzbmFtZS5sYXN0SW5kZXhPZigoYnl0ZSknLicpKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBwYWNrYWdlUGFydChTdHJpbmcgY2xhc3NuYW1lKSB7CiAgICAgICAgaW50IGxhc3REb3QgPSBjbGFzc25hbWUubGFzdEluZGV4T2YoJy4nKTsKICAgICAgICByZXR1cm4gKGxhc3REb3QgPCAwID8gIiIgOiBjbGFzc25hbWUuc3Vic3RyaW5nKDAsIGxhc3REb3QpKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIExpc3Q8TmFtZT4gZW5jbG9zaW5nQ2FuZGlkYXRlcyhOYW1lIG5hbWUpIHsKICAgICAgICBMaXN0PE5hbWU+IG5hbWVzID0gTGlzdC5uaWwoKTsKICAgICAgICBpbnQgaW5kZXg7CiAgICAgICAgd2hpbGUgKChpbmRleCA9IG5hbWUubGFzdEluZGV4T2YoKGJ5dGUpJyQnKSkgPiAwKSB7CiAgICAgICAgICAgIG5hbWUgPSBuYW1lLnN1Yk5hbWUoMCwgaW5kZXgpOwogICAgICAgICAgICBuYW1lcyA9IG5hbWVzLnByZXBlbmQobmFtZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBuYW1lczsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIExpc3Q8TmFtZT4gY2xhc3NDYW5kaWRhdGVzKE5hbWUgbmFtZSkgewogICAgICAgIExpc3Q8TmFtZT4gbmFtZXMgPSBMaXN0Lm5pbCgpOwogICAgICAgIFN0cmluZyBuYW1lU3RyID0gbmFtZS50b1N0cmluZygpOwogICAgICAgIGludCBpbmRleCA9IC0xOwogICAgICAgIHdoaWxlICgoaW5kZXggPSBuYW1lU3RyLmluZGV4T2YoJy4nLCBpbmRleCArIDEpKSA+IDApIHsKICAgICAgICAgICAgU3RyaW5nIHBhY2sgPSBuYW1lU3RyLnN1YnN0cmluZygwLCBpbmRleCArIDEpOwogICAgICAgICAgICBTdHJpbmcgY2x6ID0gbmFtZVN0ci5zdWJzdHJpbmcoaW5kZXggKyAxKS5yZXBsYWNlKCcuJywgJyQnKTsKICAgICAgICAgICAgbmFtZXMgPSBuYW1lcy5wcmVwZW5kKG5hbWUudGFibGUubmFtZXMuZnJvbVN0cmluZyhwYWNrICsgY2x6KSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBuYW1lcy5yZXZlcnNlKCk7CiAgICB9Cn0KUEsDBAoAAAgAAAY7qUoAAAAAAAAAAAAAAAAaAAAAY29tL3N1bi90b29scy9qYXZhYy9tb2RlbC9QSwMECgAACAAABjupSqto1fp9MgAAfTIAACkAAABjb20vc3VuL3Rvb2xzL2phdmFjL21vZGVsL0phdmFjVHlwZXMuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAxNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLmphdmFjLm1vZGVsOwoKaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uOwppbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOwppbXBvcnQgamF2YS51dGlsLkVudW1TZXQ7CmltcG9ydCBqYXZhLnV0aWwuTGlua2VkSGFzaFNldDsKaW1wb3J0IGphdmEudXRpbC5MaXN0OwppbXBvcnQgamF2YS51dGlsLlNldDsKaW1wb3J0IGphdmEudXRpbC5zdHJlYW0uQ29sbGVjdG9yczsKCmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuKjsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwudHlwZS4qOwoKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS4qOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlN5bWJvbC4qOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLio7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuRGVmaW5lZEJ5LkFwaTsKCmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLktpbmRzLktpbmQuKjsKCi8qKgogKiBVdGlsaXR5IG1ldGhvZHMgZm9yIG9wZXJhdGluZyBvbiB0eXBlcy4KICoKICogPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93bgogKiByaXNrLiAgVGhpcyBjb2RlIGFuZCBpdHMgaW50ZXJuYWwgaW50ZXJmYWNlcyBhcmUgc3ViamVjdCB0byBjaGFuZ2UKICogb3IgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPjwvcD4KICovCnB1YmxpYyBjbGFzcyBKYXZhY1R5cGVzIGltcGxlbWVudHMgamF2YXgubGFuZy5tb2RlbC51dGlsLlR5cGVzIHsKCiAgICBwcml2YXRlIGZpbmFsIFN5bXRhYiBzeW1zOwogICAgcHJpdmF0ZSBmaW5hbCBUeXBlcyB0eXBlczsKCiAgICBwdWJsaWMgc3RhdGljIEphdmFjVHlwZXMgaW5zdGFuY2UoQ29udGV4dCBjb250ZXh0KSB7CiAgICAgICAgSmF2YWNUeXBlcyBpbnN0YW5jZSA9IGNvbnRleHQuZ2V0KEphdmFjVHlwZXMuY2xhc3MpOwogICAgICAgIGlmIChpbnN0YW5jZSA9PSBudWxsKQogICAgICAgICAgICBpbnN0YW5jZSA9IG5ldyBKYXZhY1R5cGVzKGNvbnRleHQpOwogICAgICAgIHJldHVybiBpbnN0YW5jZTsKICAgIH0KCiAgICBwcm90ZWN0ZWQgSmF2YWNUeXBlcyhDb250ZXh0IGNvbnRleHQpIHsKICAgICAgICBjb250ZXh0LnB1dChKYXZhY1R5cGVzLmNsYXNzLCB0aGlzKTsKICAgICAgICBzeW1zID0gU3ltdGFiLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIHR5cGVzID0gVHlwZXMuaW5zdGFuY2UoY29udGV4dCk7CiAgICB9CgogICAgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICBwdWJsaWMgRWxlbWVudCBhc0VsZW1lbnQoVHlwZU1pcnJvciB0KSB7CiAgICAgICAgc3dpdGNoICh0LmdldEtpbmQoKSkgewogICAgICAgICAgICBjYXNlIERFQ0xBUkVEOgogICAgICAgICAgICBjYXNlIElOVEVSU0VDVElPTjoKICAgICAgICAgICAgY2FzZSBFUlJPUjoKICAgICAgICAgICAgY2FzZSBUWVBFVkFSOgogICAgICAgICAgICAgICAgVHlwZSB0eXBlID0gY2FzdChUeXBlLmNsYXNzLCB0KTsKICAgICAgICAgICAgICAgIHJldHVybiB0eXBlLmFzRWxlbWVudCgpOwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgfQoKICAgIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgcHVibGljIGJvb2xlYW4gaXNTYW1lVHlwZShUeXBlTWlycm9yIHQxLCBUeXBlTWlycm9yIHQyKSB7CiAgICAgICAgaWYgKHQxLmdldEtpbmQoKSA9PSBUeXBlS2luZC5XSUxEQ0FSRCB8fCB0Mi5nZXRLaW5kKCkgPT0gVHlwZUtpbmQuV0lMRENBUkQpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdHlwZXMuaXNTYW1lVHlwZSgoVHlwZSkgdDEsIChUeXBlKSB0Mik7CiAgICB9CgogICAgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICBwdWJsaWMgYm9vbGVhbiBpc1N1YnR5cGUoVHlwZU1pcnJvciB0MSwgVHlwZU1pcnJvciB0MikgewogICAgICAgIHZhbGlkYXRlVHlwZU5vdEluKHQxLCBFWEVDX09SX1BLR19PUl9NT0QpOwogICAgICAgIHZhbGlkYXRlVHlwZU5vdEluKHQyLCBFWEVDX09SX1BLR19PUl9NT0QpOwogICAgICAgIHJldHVybiB0eXBlcy5pc1N1YnR5cGUoKFR5cGUpIHQxLCAoVHlwZSkgdDIpOwogICAgfQoKICAgIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgcHVibGljIGJvb2xlYW4gaXNBc3NpZ25hYmxlKFR5cGVNaXJyb3IgdDEsIFR5cGVNaXJyb3IgdDIpIHsKICAgICAgICB2YWxpZGF0ZVR5cGVOb3RJbih0MSwgRVhFQ19PUl9QS0dfT1JfTU9EKTsKICAgICAgICB2YWxpZGF0ZVR5cGVOb3RJbih0MiwgRVhFQ19PUl9QS0dfT1JfTU9EKTsKICAgICAgICByZXR1cm4gdHlwZXMuaXNBc3NpZ25hYmxlKChUeXBlKSB0MSwgKFR5cGUpIHQyKTsKICAgIH0KCiAgICBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKFR5cGVNaXJyb3IgdDEsIFR5cGVNaXJyb3IgdDIpIHsKICAgICAgICB2YWxpZGF0ZVR5cGVOb3RJbih0MSwgRVhFQ19PUl9QS0dfT1JfTU9EKTsKICAgICAgICB2YWxpZGF0ZVR5cGVOb3RJbih0MiwgRVhFQ19PUl9QS0dfT1JfTU9EKTsKICAgICAgICByZXR1cm4gdHlwZXMuY29udGFpbnNUeXBlKChUeXBlKSB0MSwgKFR5cGUpIHQyKTsKICAgIH0KCiAgICBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgIHB1YmxpYyBib29sZWFuIGlzU3Vic2lnbmF0dXJlKEV4ZWN1dGFibGVUeXBlIG0xLCBFeGVjdXRhYmxlVHlwZSBtMikgewogICAgICAgIHJldHVybiB0eXBlcy5pc1N1YlNpZ25hdHVyZSgoVHlwZSkgbTEsIChUeXBlKSBtMik7CiAgICB9CgogICAgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICBwdWJsaWMgTGlzdDxUeXBlPiBkaXJlY3RTdXBlcnR5cGVzKFR5cGVNaXJyb3IgdCkgewogICAgICAgIHZhbGlkYXRlVHlwZU5vdEluKHQsIEVYRUNfT1JfUEtHX09SX01PRCk7CiAgICAgICAgVHlwZSB0eSA9IChUeXBlKXQ7CiAgICAgICAgcmV0dXJuIHR5cGVzLmRpcmVjdFN1cGVydHlwZXModHkpLnN0cmVhbSgpCiAgICAgICAgICAgICAgICAubWFwKFR5cGU6OnN0cmlwTWV0YWRhdGFJZk5lZWRlZCkKICAgICAgICAgICAgICAgIC5jb2xsZWN0KENvbGxlY3RvcnMudG9MaXN0KCkpOwogICAgfQoKICAgIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgcHVibGljIFR5cGVNaXJyb3IgZXJhc3VyZShUeXBlTWlycm9yIHQpIHsKICAgICAgICBUeXBlS2luZCBraW5kID0gdC5nZXRLaW5kKCk7CiAgICAgICAgaWYgKGtpbmQgPT0gVHlwZUtpbmQuUEFDS0FHRSB8fCBraW5kID09IFR5cGVLaW5kLk1PRFVMRSkKICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbih0LnRvU3RyaW5nKCkpOwogICAgICAgIHJldHVybiB0eXBlcy5lcmFzdXJlKChUeXBlKXQpLnN0cmlwTWV0YWRhdGFJZk5lZWRlZCgpOwogICAgfQoKICAgIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgcHVibGljIFR5cGVFbGVtZW50IGJveGVkQ2xhc3MoUHJpbWl0aXZlVHlwZSBwKSB7CiAgICAgICAgcmV0dXJuIHR5cGVzLmJveGVkQ2xhc3MoKFR5cGUpIHApOwogICAgfQoKICAgIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgcHVibGljIFByaW1pdGl2ZVR5cGUgdW5ib3hlZFR5cGUoVHlwZU1pcnJvciB0KSB7CiAgICAgICAgaWYgKHQuZ2V0S2luZCgpICE9IFR5cGVLaW5kLkRFQ0xBUkVEKQogICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKHQudG9TdHJpbmcoKSk7CiAgICAgICAgVHlwZSB1bmJveGVkID0gdHlwZXMudW5ib3hlZFR5cGUoKFR5cGUpIHQpOwogICAgICAgIGlmICghIHVuYm94ZWQuaXNQcmltaXRpdmUoKSkgICAgLy8gb25seSB0cnVlIHByaW1pdGl2ZXMsIG5vdCB2b2lkCiAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24odC50b1N0cmluZygpKTsKICAgICAgICByZXR1cm4gKFByaW1pdGl2ZVR5cGUpdW5ib3hlZDsKICAgIH0KCiAgICBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgIHB1YmxpYyBUeXBlTWlycm9yIGNhcHR1cmUoVHlwZU1pcnJvciB0KSB7CiAgICAgICAgdmFsaWRhdGVUeXBlTm90SW4odCwgRVhFQ19PUl9QS0dfT1JfTU9EKTsKICAgICAgICByZXR1cm4gdHlwZXMuY2FwdHVyZSgoVHlwZSl0KS5zdHJpcE1ldGFkYXRhSWZOZWVkZWQoKTsKICAgIH0KCiAgICBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgIHB1YmxpYyBQcmltaXRpdmVUeXBlIGdldFByaW1pdGl2ZVR5cGUoVHlwZUtpbmQga2luZCkgewogICAgICAgIHN3aXRjaCAoa2luZCkgewogICAgICAgIGNhc2UgQk9PTEVBTjogICByZXR1cm4gc3ltcy5ib29sZWFuVHlwZTsKICAgICAgICBjYXNlIEJZVEU6ICAgICAgcmV0dXJuIHN5bXMuYnl0ZVR5cGU7CiAgICAgICAgY2FzZSBTSE9SVDogICAgIHJldHVybiBzeW1zLnNob3J0VHlwZTsKICAgICAgICBjYXNlIElOVDogICAgICAgcmV0dXJuIHN5bXMuaW50VHlwZTsKICAgICAgICBjYXNlIExPTkc6ICAgICAgcmV0dXJuIHN5bXMubG9uZ1R5cGU7CiAgICAgICAgY2FzZSBDSEFSOiAgICAgIHJldHVybiBzeW1zLmNoYXJUeXBlOwogICAgICAgIGNhc2UgRkxPQVQ6ICAgICByZXR1cm4gc3ltcy5mbG9hdFR5cGU7CiAgICAgICAgY2FzZSBET1VCTEU6ICAgIHJldHVybiBzeW1zLmRvdWJsZVR5cGU7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiTm90IGEgcHJpbWl0aXZlIHR5cGU6ICIgKyBraW5kKTsKICAgICAgICB9CiAgICB9CgogICAgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICBwdWJsaWMgTnVsbFR5cGUgZ2V0TnVsbFR5cGUoKSB7CiAgICAgICAgcmV0dXJuIChOdWxsVHlwZSkgc3ltcy5ib3RUeXBlOwogICAgfQoKICAgIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgcHVibGljIE5vVHlwZSBnZXROb1R5cGUoVHlwZUtpbmQga2luZCkgewogICAgICAgIHN3aXRjaCAoa2luZCkgewogICAgICAgIGNhc2UgVk9JRDogICAgICByZXR1cm4gc3ltcy52b2lkVHlwZTsKICAgICAgICBjYXNlIE5PTkU6ICAgICAgcmV0dXJuIFR5cGUubm9UeXBlOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oa2luZC50b1N0cmluZygpKTsKICAgICAgICB9CiAgICB9CgogICAgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICBwdWJsaWMgQXJyYXlUeXBlIGdldEFycmF5VHlwZShUeXBlTWlycm9yIGNvbXBvbmVudFR5cGUpIHsKICAgICAgICBzd2l0Y2ggKGNvbXBvbmVudFR5cGUuZ2V0S2luZCgpKSB7CiAgICAgICAgY2FzZSBWT0lEOgogICAgICAgIGNhc2UgRVhFQ1VUQUJMRToKICAgICAgICBjYXNlIFdJTERDQVJEOiAgLy8gaGVoIQogICAgICAgIGNhc2UgUEFDS0FHRToKICAgICAgICBjYXNlIE1PRFVMRToKICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihjb21wb25lbnRUeXBlLnRvU3RyaW5nKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbmV3IFR5cGUuQXJyYXlUeXBlKChUeXBlKSBjb21wb25lbnRUeXBlLCBzeW1zLmFycmF5Q2xhc3MpOwogICAgfQoKICAgIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgcHVibGljIFdpbGRjYXJkVHlwZSBnZXRXaWxkY2FyZFR5cGUoVHlwZU1pcnJvciBleHRlbmRzQm91bmQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUeXBlTWlycm9yIHN1cGVyQm91bmQpIHsKICAgICAgICBCb3VuZEtpbmQgYmtpbmQ7CiAgICAgICAgVHlwZSBib3VuZDsKICAgICAgICBpZiAoZXh0ZW5kc0JvdW5kID09IG51bGwgJiYgc3VwZXJCb3VuZCA9PSBudWxsKSB7CiAgICAgICAgICAgIGJraW5kID0gQm91bmRLaW5kLlVOQk9VTkQ7CiAgICAgICAgICAgIGJvdW5kID0gc3ltcy5vYmplY3RUeXBlOwogICAgICAgIH0gZWxzZSBpZiAoc3VwZXJCb3VuZCA9PSBudWxsKSB7CiAgICAgICAgICAgIGJraW5kID0gQm91bmRLaW5kLkVYVEVORFM7CiAgICAgICAgICAgIGJvdW5kID0gKFR5cGUpIGV4dGVuZHNCb3VuZDsKICAgICAgICB9IGVsc2UgaWYgKGV4dGVuZHNCb3VuZCA9PSBudWxsKSB7CiAgICAgICAgICAgIGJraW5kID0gQm91bmRLaW5kLlNVUEVSOwogICAgICAgICAgICBib3VuZCA9IChUeXBlKSBzdXBlckJvdW5kOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAgICAgIkV4dGVuZHMgYW5kIHN1cGVyIGJvdW5kcyBjYW5ub3QgYm90aCBiZSBwcm92aWRlZCIpOwogICAgICAgIH0KICAgICAgICBzd2l0Y2ggKGJvdW5kLmdldEtpbmQoKSkgewogICAgICAgIGNhc2UgQVJSQVk6CiAgICAgICAgY2FzZSBERUNMQVJFRDoKICAgICAgICBjYXNlIEVSUk9SOgogICAgICAgIGNhc2UgVFlQRVZBUjoKICAgICAgICAgICAgcmV0dXJuIG5ldyBUeXBlLldpbGRjYXJkVHlwZShib3VuZCwgYmtpbmQsIHN5bXMuYm91bmRDbGFzcyk7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihib3VuZC50b1N0cmluZygpKTsKICAgICAgICB9CiAgICB9CgogICAgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICBwdWJsaWMgRGVjbGFyZWRUeXBlIGdldERlY2xhcmVkVHlwZShUeXBlRWxlbWVudCB0eXBlRWxlbSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFR5cGVNaXJyb3IuLi4gdHlwZUFyZ3MpIHsKICAgICAgICBDbGFzc1N5bWJvbCBzeW0gPSAoQ2xhc3NTeW1ib2wpIHR5cGVFbGVtOwoKICAgICAgICBpZiAodHlwZUFyZ3MubGVuZ3RoID09IDApCiAgICAgICAgICAgIHJldHVybiAoRGVjbGFyZWRUeXBlKSBzeW0uZXJhc3VyZSh0eXBlcyk7CiAgICAgICAgaWYgKHN5bS50eXBlLmdldEVuY2xvc2luZ1R5cGUoKS5pc1BhcmFtZXRlcml6ZWQoKSkKICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihzeW0udG9TdHJpbmcoKSk7CgogICAgICAgIHJldHVybiBnZXREZWNsYXJlZFR5cGUwKHN5bS50eXBlLmdldEVuY2xvc2luZ1R5cGUoKSwgc3ltLCB0eXBlQXJncyk7CiAgICB9CgogICAgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICBwdWJsaWMgRGVjbGFyZWRUeXBlIGdldERlY2xhcmVkVHlwZShEZWNsYXJlZFR5cGUgZW5jbG9zaW5nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVHlwZUVsZW1lbnQgdHlwZUVsZW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUeXBlTWlycm9yLi4uIHR5cGVBcmdzKSB7CiAgICAgICAgaWYgKGVuY2xvc2luZyA9PSBudWxsKQogICAgICAgICAgICByZXR1cm4gZ2V0RGVjbGFyZWRUeXBlKHR5cGVFbGVtLCB0eXBlQXJncyk7CgogICAgICAgIENsYXNzU3ltYm9sIHN5bSA9IChDbGFzc1N5bWJvbCkgdHlwZUVsZW07CiAgICAgICAgVHlwZSBvdXRlciA9IChUeXBlKSBlbmNsb3Npbmc7CgogICAgICAgIGlmIChvdXRlci50c3ltICE9IHN5bS5vd25lci5lbmNsQ2xhc3MoKSkKICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihlbmNsb3NpbmcudG9TdHJpbmcoKSk7CiAgICAgICAgaWYgKCFvdXRlci5pc1BhcmFtZXRlcml6ZWQoKSkKICAgICAgICAgICAgcmV0dXJuIGdldERlY2xhcmVkVHlwZSh0eXBlRWxlbSwgdHlwZUFyZ3MpOwoKICAgICAgICByZXR1cm4gZ2V0RGVjbGFyZWRUeXBlMChvdXRlciwgc3ltLCB0eXBlQXJncyk7CiAgICB9CiAgICAvLyB3aGVyZQogICAgICAgIHByaXZhdGUgRGVjbGFyZWRUeXBlIGdldERlY2xhcmVkVHlwZTAoVHlwZSBvdXRlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENsYXNzU3ltYm9sIHN5bSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFR5cGVNaXJyb3IuLi4gdHlwZUFyZ3MpIHsKICAgICAgICAgICAgaWYgKHR5cGVBcmdzLmxlbmd0aCAhPSBzeW0udHlwZS5nZXRUeXBlQXJndW1lbnRzKCkubGVuZ3RoKCkpCiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAogICAgICAgICAgICAgICAgIkluY29ycmVjdCBudW1iZXIgb2YgdHlwZSBhcmd1bWVudHMiKTsKCiAgICAgICAgICAgIExpc3RCdWZmZXI8VHlwZT4gdGFyZ3MgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgIGZvciAoVHlwZU1pcnJvciB0IDogdHlwZUFyZ3MpIHsKICAgICAgICAgICAgICAgIGlmICghKHQgaW5zdGFuY2VvZiBSZWZlcmVuY2VUeXBlIHx8IHQgaW5zdGFuY2VvZiBXaWxkY2FyZFR5cGUpKQogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24odC50b1N0cmluZygpKTsKICAgICAgICAgICAgICAgIHRhcmdzLmFwcGVuZCgoVHlwZSkgdCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gVE9ETzogV291bGQgbGlrZSBhIHdheSB0byBjaGVjayB0aGF0IHR5cGUgYXJncyBtYXRjaCBmb3JtYWxzLgoKICAgICAgICAgICAgcmV0dXJuIChEZWNsYXJlZFR5cGUpIG5ldyBUeXBlLkNsYXNzVHlwZShvdXRlciwgdGFyZ3MudG9MaXN0KCksIHN5bSk7CiAgICAgICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgdHlwZSBvZiBhbiBlbGVtZW50IHdoZW4gdGhhdCBlbGVtZW50IGlzIHZpZXdlZCBhcwogICAgICogYSBtZW1iZXIgb2YsIG9yIG90aGVyd2lzZSBkaXJlY3RseSBjb250YWluZWQgYnksIGEgZ2l2ZW4gdHlwZS4KICAgICAqIEZvciBleGFtcGxlLAogICAgICogd2hlbiB2aWV3ZWQgYXMgYSBtZW1iZXIgb2YgdGhlIHBhcmFtZXRlcml6ZWQgdHlwZSB7QGNvZGUgU2V0PFN0cmluZz59LAogICAgICogdGhlIHtAY29kZSBTZXQuYWRkfSBtZXRob2QgaXMgYW4ge0Bjb2RlIEV4ZWN1dGFibGVUeXBlfQogICAgICogd2hvc2UgcGFyYW1ldGVyIGlzIG9mIHR5cGUge0Bjb2RlIFN0cmluZ30uCiAgICAgKgogICAgICogQHBhcmFtIGNvbnRhaW5pbmcgIHRoZSBjb250YWluaW5nIHR5cGUKICAgICAqIEBwYXJhbSBlbGVtZW50ICAgICB0aGUgZWxlbWVudAogICAgICogQHJldHVybiB0aGUgdHlwZSBvZiB0aGUgZWxlbWVudCBhcyB2aWV3ZWQgZnJvbSB0aGUgY29udGFpbmluZyB0eXBlCiAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgZWxlbWVudCBpcyBub3QgYSB2YWxpZCBvbmUKICAgICAqICAgICAgICAgIGZvciB0aGUgZ2l2ZW4gdHlwZQogICAgICovCiAgICBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgIHB1YmxpYyBUeXBlTWlycm9yIGFzTWVtYmVyT2YoRGVjbGFyZWRUeXBlIGNvbnRhaW5pbmcsIEVsZW1lbnQgZWxlbWVudCkgewogICAgICAgIFR5cGUgc2l0ZSA9IChUeXBlKWNvbnRhaW5pbmc7CiAgICAgICAgU3ltYm9sIHN5bSA9IChTeW1ib2wpZWxlbWVudDsKICAgICAgICBpZiAodHlwZXMuYXNTdXBlcihzaXRlLCBzeW0uZ2V0RW5jbG9zaW5nRWxlbWVudCgpKSA9PSBudWxsKQogICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKHN5bSArICJAIiArIHNpdGUpOwogICAgICAgIHJldHVybiB0eXBlcy5tZW1iZXJUeXBlKHNpdGUsIHN5bSk7CiAgICB9CgoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFNldDxUeXBlS2luZD4gRVhFQ19PUl9QS0dfT1JfTU9EID0KICAgICAgICBFbnVtU2V0Lm9mKFR5cGVLaW5kLkVYRUNVVEFCTEUsIFR5cGVLaW5kLlBBQ0tBR0UsIFR5cGVLaW5kLk1PRFVMRSk7CgogICAgLyoqCiAgICAgKiBUaHJvd3MgYW4gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIGEgdHlwZSdzIGtpbmQgaXMgb25lIG9mIGEgc2V0LgogICAgICovCiAgICBwcml2YXRlIHZvaWQgdmFsaWRhdGVUeXBlTm90SW4oVHlwZU1pcnJvciB0LCBTZXQ8VHlwZUtpbmQ+IGludmFsaWRLaW5kcykgewogICAgICAgIGlmIChpbnZhbGlkS2luZHMuY29udGFpbnModC5nZXRLaW5kKCkpKQogICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKHQudG9TdHJpbmcoKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGFuIG9iamVjdCBjYXN0IHRvIHRoZSBzcGVjaWZpZWQgdHlwZS4KICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIG9iamVjdCBpcyB7QGNvZGUgbnVsbH0KICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHRoZSBvYmplY3QgaXMgb2YgdGhlIHdyb25nIHR5cGUKICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgPFQ+IFQgY2FzdChDbGFzczxUPiBjbGF6eiwgT2JqZWN0IG8pIHsKICAgICAgICBpZiAoISBjbGF6ei5pc0luc3RhbmNlKG8pKQogICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKG8udG9TdHJpbmcoKSk7CiAgICAgICAgcmV0dXJuIGNsYXp6LmNhc3Qobyk7CiAgICB9CgogICAgcHVibGljIFNldDxNZXRob2RTeW1ib2w+IGdldE92ZXJyaWRkZW5NZXRob2RzKEVsZW1lbnQgZWxlbSkgewogICAgICAgIGlmIChlbGVtLmdldEtpbmQoKSAhPSBFbGVtZW50S2luZC5NRVRIT0QKICAgICAgICAgICAgICAgIHx8IGVsZW0uZ2V0TW9kaWZpZXJzKCkuY29udGFpbnMoTW9kaWZpZXIuU1RBVElDKQogICAgICAgICAgICAgICAgfHwgZWxlbS5nZXRNb2RpZmllcnMoKS5jb250YWlucyhNb2RpZmllci5QUklWQVRFKSkKICAgICAgICAgICAgcmV0dXJuIENvbGxlY3Rpb25zLmVtcHR5U2V0KCk7CgogICAgICAgIGlmICghKGVsZW0gaW5zdGFuY2VvZiBNZXRob2RTeW1ib2wpKQogICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CgogICAgICAgIE1ldGhvZFN5bWJvbCBtID0gKE1ldGhvZFN5bWJvbCkgZWxlbTsKICAgICAgICBDbGFzc1N5bWJvbCBvcmlnaW4gPSAoQ2xhc3NTeW1ib2wpIG0ub3duZXI7CgogICAgICAgIFNldDxNZXRob2RTeW1ib2w+IHJlc3VsdHMgPSBuZXcgTGlua2VkSGFzaFNldDw+KCk7CiAgICAgICAgZm9yIChUeXBlIHQgOiB0eXBlcy5jbG9zdXJlKG9yaWdpbi50eXBlKSkgewogICAgICAgICAgICBpZiAodCAhPSBvcmlnaW4udHlwZSkgewogICAgICAgICAgICAgICAgQ2xhc3NTeW1ib2wgYyA9IChDbGFzc1N5bWJvbCkgdC50c3ltOwogICAgICAgICAgICAgICAgZm9yIChTeW1ib2wgc3ltIDogYy5tZW1iZXJzKCkuZ2V0U3ltYm9sc0J5TmFtZShtLm5hbWUpKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHN5bS5raW5kID09IE1USCAmJiBtLm92ZXJyaWRlcyhzeW0sIG9yaWdpbiwgdHlwZXMsIHRydWUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdHMuYWRkKChNZXRob2RTeW1ib2wpIHN5bSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gcmVzdWx0czsKICAgIH0KfQpQSwMECgAACAAABjupSvk7PVbQdAAA0HQAACwAAABjb20vc3VuL3Rvb2xzL2phdmFjL21vZGVsL0phdmFjRWxlbWVudHMuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAxNywgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLmphdmFjLm1vZGVsOwoKaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKaW1wb3J0IGphdmEudXRpbC5IYXNoU2V0OwppbXBvcnQgamF2YS51dGlsLkxpbmtlZEhhc2hTZXQ7CmltcG9ydCBqYXZhLnV0aWwuTWFwOwppbXBvcnQgamF2YS51dGlsLlNldDsKaW1wb3J0IGphdmEudXRpbC5zdHJlYW0uQ29sbGVjdG9yczsKCmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLkFubm90YXRlZENvbnN0cnVjdDsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuU291cmNlVmVyc2lvbjsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC4qOwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC50eXBlLkRlY2xhcmVkVHlwZTsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwudXRpbC5FbGVtZW50czsKaW1wb3J0IGphdmF4LnRvb2xzLkphdmFGaWxlT2JqZWN0OwppbXBvcnQgc3RhdGljIGphdmF4LmxhbmcubW9kZWwudXRpbC5FbGVtZW50RmlsdGVyLm1ldGhvZHNJbjsKCmltcG9ydCBjb20uc3VuLnNvdXJjZS51dGlsLkphdmFjVGFzazsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuYXBpLkphdmFjVGFza0ltcGw7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuKjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5BdHRyaWJ1dGUuQ29tcG91bmQ7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuRGlyZWN0aXZlLkV4cG9ydHNEaXJlY3RpdmU7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuRGlyZWN0aXZlLkV4cG9ydHNGbGFnOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLkRpcmVjdGl2ZS5PcGVuc0RpcmVjdGl2ZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5EaXJlY3RpdmUuT3BlbnNGbGFnOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLkRpcmVjdGl2ZS5SZXF1aXJlc0RpcmVjdGl2ZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5EaXJlY3RpdmUuUmVxdWlyZXNGbGFnOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlNjb3BlLldyaXRlYWJsZVNjb3BlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlN5bWJvbC4qOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb21wLkF0dHJDb250ZXh0OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb21wLkVudGVyOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb21wLkVudjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMubWFpbi5KYXZhQ29tcGlsZXI7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnByb2Nlc3NpbmcuUHJpbnRpbmdQcm9jZXNzb3I7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuSkNUcmVlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkpDVHJlZS4qOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLlRyZWVJbmZvOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLlRyZWVTY2FubmVyOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLio7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuRGVmaW5lZEJ5LkFwaTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5OYW1lOwppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5LaW5kcy5LaW5kLio7CmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlNjb3BlLkxvb2t1cEtpbmQuTk9OX1JFQ1VSU0lWRTsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuVHlwZVRhZy5DTEFTUzsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29tcC5Nb2R1bGVzOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb21wLlJlc29sdmU7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvbXAuUmVzb2x2ZS5SZWNvdmVyeUxvYWRDbGFzczsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMucmVzb3VyY2VzLkNvbXBpbGVyUHJvcGVydGllcy5Ob3RlczsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuSkNUcmVlLlRhZy4qOwoKLyoqCiAqIFV0aWxpdHkgbWV0aG9kcyBmb3Igb3BlcmF0aW5nIG9uIHByb2dyYW0gZWxlbWVudHMuCiAqCiAqIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24KICogcmlzay4gIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlCiAqIG9yIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj48L3A+CiAqLwpwdWJsaWMgY2xhc3MgSmF2YWNFbGVtZW50cyBpbXBsZW1lbnRzIEVsZW1lbnRzIHsKCiAgICBwcml2YXRlIGZpbmFsIEphdmFDb21waWxlciBqYXZhQ29tcGlsZXI7CiAgICBwcml2YXRlIGZpbmFsIFN5bXRhYiBzeW1zOwogICAgcHJpdmF0ZSBmaW5hbCBNb2R1bGVzIG1vZHVsZXM7CiAgICBwcml2YXRlIGZpbmFsIE5hbWVzIG5hbWVzOwogICAgcHJpdmF0ZSBmaW5hbCBUeXBlcyB0eXBlczsKICAgIHByaXZhdGUgZmluYWwgRW50ZXIgZW50ZXI7CiAgICBwcml2YXRlIGZpbmFsIFJlc29sdmUgcmVzb2x2ZTsKICAgIHByaXZhdGUgZmluYWwgSmF2YWNUYXNrSW1wbCBqYXZhY1Rhc2tJbXBsOwogICAgcHJpdmF0ZSBmaW5hbCBMb2cgbG9nOwogICAgcHJpdmF0ZSBmaW5hbCBib29sZWFuIGFsbG93TW9kdWxlczsKCiAgICBwdWJsaWMgc3RhdGljIEphdmFjRWxlbWVudHMgaW5zdGFuY2UoQ29udGV4dCBjb250ZXh0KSB7CiAgICAgICAgSmF2YWNFbGVtZW50cyBpbnN0YW5jZSA9IGNvbnRleHQuZ2V0KEphdmFjRWxlbWVudHMuY2xhc3MpOwogICAgICAgIGlmIChpbnN0YW5jZSA9PSBudWxsKQogICAgICAgICAgICBpbnN0YW5jZSA9IG5ldyBKYXZhY0VsZW1lbnRzKGNvbnRleHQpOwogICAgICAgIHJldHVybiBpbnN0YW5jZTsKICAgIH0KCiAgICBwcm90ZWN0ZWQgSmF2YWNFbGVtZW50cyhDb250ZXh0IGNvbnRleHQpIHsKICAgICAgICBjb250ZXh0LnB1dChKYXZhY0VsZW1lbnRzLmNsYXNzLCB0aGlzKTsKICAgICAgICBqYXZhQ29tcGlsZXIgPSBKYXZhQ29tcGlsZXIuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgc3ltcyA9IFN5bXRhYi5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBtb2R1bGVzID0gTW9kdWxlcy5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBuYW1lcyA9IE5hbWVzLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIHR5cGVzID0gVHlwZXMuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgZW50ZXIgPSBFbnRlci5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICByZXNvbHZlID0gUmVzb2x2ZS5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBKYXZhY1Rhc2sgdCA9IGNvbnRleHQuZ2V0KEphdmFjVGFzay5jbGFzcyk7CiAgICAgICAgamF2YWNUYXNrSW1wbCA9IHQgaW5zdGFuY2VvZiBKYXZhY1Rhc2tJbXBsID8gKEphdmFjVGFza0ltcGwpIHQgOiBudWxsOwogICAgICAgIGxvZyA9IExvZy5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBTb3VyY2Ugc291cmNlID0gU291cmNlLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIGFsbG93TW9kdWxlcyA9IHNvdXJjZS5hbGxvd01vZHVsZXMoKTsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICBwdWJsaWMgU2V0PD8gZXh0ZW5kcyBNb2R1bGVFbGVtZW50PiBnZXRBbGxNb2R1bGVFbGVtZW50cygpIHsKICAgICAgICBpZiAoYWxsb3dNb2R1bGVzKQogICAgICAgICAgICByZXR1cm4gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlU2V0KG1vZHVsZXMuYWxsTW9kdWxlcygpKTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIHJldHVybiBDb2xsZWN0aW9ucy5lbXB0eVNldCgpOwogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgIHB1YmxpYyBNb2R1bGVTeW1ib2wgZ2V0TW9kdWxlRWxlbWVudChDaGFyU2VxdWVuY2UgbmFtZSkgewogICAgICAgIGVuc3VyZUVudGVyZWQoImdldE1vZHVsZUVsZW1lbnQiKTsKICAgICAgICBpZiAobW9kdWxlcy5nZXREZWZhdWx0TW9kdWxlKCkgPT0gc3ltcy5ub01vZHVsZSkKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgU3RyaW5nIHN0ck5hbWUgPSBuYW1lLnRvU3RyaW5nKCk7CiAgICAgICAgaWYgKHN0ck5hbWUuZXF1YWxzKCIiKSkKICAgICAgICAgICAgcmV0dXJuIHN5bXMudW5uYW1lZE1vZHVsZTsKICAgICAgICByZXR1cm4gbW9kdWxlcy5nZXRPYnNlcnZhYmxlTW9kdWxlKG5hbWVzLmZyb21TdHJpbmcoc3RyTmFtZSkpOwogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgIHB1YmxpYyBQYWNrYWdlU3ltYm9sIGdldFBhY2thZ2VFbGVtZW50KENoYXJTZXF1ZW5jZSBuYW1lKSB7CiAgICAgICAgcmV0dXJuIGRvR2V0UGFja2FnZUVsZW1lbnQobnVsbCwgbmFtZSk7CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgcHVibGljIFBhY2thZ2VTeW1ib2wgZ2V0UGFja2FnZUVsZW1lbnQoTW9kdWxlRWxlbWVudCBtb2R1bGUsIENoYXJTZXF1ZW5jZSBuYW1lKSB7CiAgICAgICAgbW9kdWxlLmdldENsYXNzKCk7CiAgICAgICAgcmV0dXJuIGRvR2V0UGFja2FnZUVsZW1lbnQobW9kdWxlLCBuYW1lKTsKICAgIH0KCiAgICBwcml2YXRlIFBhY2thZ2VTeW1ib2wgZG9HZXRQYWNrYWdlRWxlbWVudChNb2R1bGVFbGVtZW50IG1vZHVsZSwgQ2hhclNlcXVlbmNlIG5hbWUpIHsKICAgICAgICBlbnN1cmVFbnRlcmVkKCJnZXRQYWNrYWdlRWxlbWVudCIpOwogICAgICAgIHJldHVybiBkb0dldEVsZW1lbnQobW9kdWxlLCAiZ2V0UGFja2FnZUVsZW1lbnQiLCBuYW1lLCBQYWNrYWdlU3ltYm9sLmNsYXNzKTsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICBwdWJsaWMgQ2xhc3NTeW1ib2wgZ2V0VHlwZUVsZW1lbnQoQ2hhclNlcXVlbmNlIG5hbWUpIHsKICAgICAgICByZXR1cm4gZG9HZXRUeXBlRWxlbWVudChudWxsLCBuYW1lKTsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICBwdWJsaWMgQ2xhc3NTeW1ib2wgZ2V0VHlwZUVsZW1lbnQoTW9kdWxlRWxlbWVudCBtb2R1bGUsIENoYXJTZXF1ZW5jZSBuYW1lKSB7CiAgICAgICAgbW9kdWxlLmdldENsYXNzKCk7CgogICAgICAgIHJldHVybiBkb0dldFR5cGVFbGVtZW50KG1vZHVsZSwgbmFtZSk7CiAgICB9CgogICAgcHJpdmF0ZSBDbGFzc1N5bWJvbCBkb0dldFR5cGVFbGVtZW50KE1vZHVsZUVsZW1lbnQgbW9kdWxlLCBDaGFyU2VxdWVuY2UgbmFtZSkgewogICAgICAgIGVuc3VyZUVudGVyZWQoImdldFR5cGVFbGVtZW50Iik7CiAgICAgICAgcmV0dXJuIGRvR2V0RWxlbWVudChtb2R1bGUsICJnZXRUeXBlRWxlbWVudCIsIG5hbWUsIENsYXNzU3ltYm9sLmNsYXNzKTsKICAgIH0KCiAgICBwcml2YXRlIDxTIGV4dGVuZHMgU3ltYm9sPiBTIGRvR2V0RWxlbWVudChNb2R1bGVFbGVtZW50IG1vZHVsZSwgU3RyaW5nIG1ldGhvZE5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDaGFyU2VxdWVuY2UgbmFtZSwgQ2xhc3M8Uz4gY2xhenopIHsKICAgICAgICBTdHJpbmcgc3RyTmFtZSA9IG5hbWUudG9TdHJpbmcoKTsKICAgICAgICBpZiAoIVNvdXJjZVZlcnNpb24uaXNOYW1lKHN0ck5hbWUpICYmICghc3RyTmFtZS5pc0VtcHR5KCkgfHwgY2xhenogPT0gQ2xhc3NTeW1ib2wuY2xhc3MpKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgICBpZiAobW9kdWxlID09IG51bGwpIHsKICAgICAgICAgICAgcmV0dXJuIHVuYm91bmROYW1lVG9TeW1ib2wobWV0aG9kTmFtZSwgc3RyTmFtZSwgY2xhenopOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiBuYW1lVG9TeW1ib2woKE1vZHVsZVN5bWJvbCkgbW9kdWxlLCBzdHJOYW1lLCBjbGF6eik7CiAgICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgZmluYWwgU2V0PFN0cmluZz4gYWxyZWFkeVdhcm5lZER1cGxpY2F0ZXMgPSBuZXcgSGFzaFNldDw+KCk7CgogICAgcHJpdmF0ZSA8UyBleHRlbmRzIFN5bWJvbD4gUyB1bmJvdW5kTmFtZVRvU3ltYm9sKFN0cmluZyBtZXRob2ROYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBuYW1lU3RyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENsYXNzPFM+IGNsYXp6KSB7CiAgICAgICAgaWYgKG1vZHVsZXMuZ2V0RGVmYXVsdE1vZHVsZSgpID09IHN5bXMubm9Nb2R1bGUpIHsgLy9ub3QgYSBtb2R1bGFyIG1vZGU6CiAgICAgICAgICAgIHJldHVybiBuYW1lVG9TeW1ib2woc3ltcy5ub01vZHVsZSwgbmFtZVN0ciwgY2xhenopOwogICAgICAgIH0KCiAgICAgICAgU2V0PFM+IGZvdW5kID0gbmV3IExpbmtlZEhhc2hTZXQ8PigpOwoKICAgICAgICBmb3IgKE1vZHVsZVN5bWJvbCBtc3ltIDogbW9kdWxlcy5hbGxNb2R1bGVzKCkpIHsKICAgICAgICAgICAgUyBzeW0gPSBuYW1lVG9TeW1ib2wobXN5bSwgbmFtZVN0ciwgY2xhenopOwoKICAgICAgICAgICAgaWYgKHN5bSAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICBpZiAoIWFsbG93TW9kdWxlcyB8fCBjbGF6eiA9PSBDbGFzc1N5bWJvbC5jbGFzcyB8fCAhc3ltLm1lbWJlcnMoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICAgICAgICAvL2RvIG5vdCBhZGQgcGFja2FnZXMgd2l0aG91dCBtZW1iZXJzOgogICAgICAgICAgICAgICAgICAgIGZvdW5kLmFkZChzeW0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoZm91bmQuc2l6ZSgpID09IDEpIHsKICAgICAgICAgICAgcmV0dXJuIGZvdW5kLml0ZXJhdG9yKCkubmV4dCgpOwogICAgICAgIH0gZWxzZSBpZiAoZm91bmQuc2l6ZSgpID4gMSkgewogICAgICAgICAgICAvL21vcmUgdGhhbiBvbmUgZWxlbWVudCBmb3VuZCwgcHJvZHVjZSBhIG5vdGU6CiAgICAgICAgICAgIGlmIChhbHJlYWR5V2FybmVkRHVwbGljYXRlcy5hZGQobWV0aG9kTmFtZSArICI6IiArIG5hbWVTdHIpKSB7CiAgICAgICAgICAgICAgICBTdHJpbmcgbW9kdWxlTmFtZXMgPSBmb3VuZC5zdHJlYW0oKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAubWFwKHMgLT4gcy5wYWNrZ2UoKS5tb2RsZSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLm1hcChtIC0+IG0udG9TdHJpbmcoKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmNvbGxlY3QoQ29sbGVjdG9ycy5qb2luaW5nKCIsICIpKTsKICAgICAgICAgICAgICAgIGxvZy5ub3RlKE5vdGVzLk11bHRpcGxlRWxlbWVudHMobWV0aG9kTmFtZSwgbmFtZVN0ciwgbW9kdWxlTmFtZXMpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvL25vdCBmb3VuZCwgb3IgbW9yZSB0aGFuIG9uZSBlbGVtZW50IGZvdW5kOgogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgc3ltYm9sIGdpdmVuIHRoZSB0eXBlJ3Mgb3IgcGFja2FnZSdzIGNhbm9uaWNhbCBuYW1lLAogICAgICogb3IgbnVsbCBpZiB0aGUgbmFtZSBpc24ndCBmb3VuZC4KICAgICAqLwogICAgcHJpdmF0ZSA8UyBleHRlbmRzIFN5bWJvbD4gUyBuYW1lVG9TeW1ib2woTW9kdWxlU3ltYm9sIG1vZHVsZSwgU3RyaW5nIG5hbWVTdHIsIENsYXNzPFM+IGNsYXp6KSB7CiAgICAgICAgTmFtZSBuYW1lID0gbmFtZXMuZnJvbVN0cmluZyhuYW1lU3RyKTsKICAgICAgICAvLyBGaXJzdCBjaGVjayBjYWNoZS4KICAgICAgICBTeW1ib2wgc3ltID0gKGNsYXp6ID09IENsYXNzU3ltYm9sLmNsYXNzKQogICAgICAgICAgICAgICAgICAgID8gc3ltcy5nZXRDbGFzcyhtb2R1bGUsIG5hbWUpCiAgICAgICAgICAgICAgICAgICAgOiBzeW1zLmxvb2t1cFBhY2thZ2UobW9kdWxlLCBuYW1lKTsKCiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgaWYgKHN5bSA9PSBudWxsKQogICAgICAgICAgICAgICAgc3ltID0gamF2YUNvbXBpbGVyLnJlc29sdmVJZGVudChtb2R1bGUsIG5hbWVTdHIpOwoKICAgICAgICAgICAgc3ltLmNvbXBsZXRlKCk7CgogICAgICAgICAgICByZXR1cm4gKHN5bS5raW5kICE9IEVSUiAmJgogICAgICAgICAgICAgICAgICAgIHN5bS5leGlzdHMoKSAmJgogICAgICAgICAgICAgICAgICAgIGNsYXp6LmlzSW5zdGFuY2Uoc3ltKSAmJgogICAgICAgICAgICAgICAgICAgIG5hbWUuZXF1YWxzKHN5bS5nZXRRdWFsaWZpZWROYW1lKCkpKQogICAgICAgICAgICAgICAgPyBjbGF6ei5jYXN0KHN5bSkKICAgICAgICAgICAgICAgIDogbnVsbDsKICAgICAgICB9IGNhdGNoIChDb21wbGV0aW9uRmFpbHVyZSBlKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHRyZWUgZm9yIGFuIGFubm90YXRpb24gZ2l2ZW4gdGhlIGFubm90YXRlZCBlbGVtZW50CiAgICAgKiBhbmQgdGhlIGVsZW1lbnQncyBvd24gdHJlZS4gIFJldHVybnMgbnVsbCBpZiB0aGUgdHJlZSBjYW5ub3QgYmUgZm91bmQuCiAgICAgKi8KICAgIHByaXZhdGUgSkNUcmVlIG1hdGNoQW5ub1RvVHJlZShBbm5vdGF0aW9uTWlycm9yIGZpbmRtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFbGVtZW50IGUsIEpDVHJlZSB0cmVlKSB7CiAgICAgICAgU3ltYm9sIHN5bSA9IGNhc3QoU3ltYm9sLmNsYXNzLCBlKTsKICAgICAgICBjbGFzcyBWaXMgZXh0ZW5kcyBKQ1RyZWUuVmlzaXRvciB7CiAgICAgICAgICAgIExpc3Q8SkNBbm5vdGF0aW9uPiByZXN1bHQgPSBudWxsOwogICAgICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdFBhY2thZ2VEZWYoSkNQYWNrYWdlRGVjbCB0cmVlKSB7CiAgICAgICAgICAgICAgICByZXN1bHQgPSB0cmVlLmFubm90YXRpb25zOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0Q2xhc3NEZWYoSkNDbGFzc0RlY2wgdHJlZSkgewogICAgICAgICAgICAgICAgcmVzdWx0ID0gdHJlZS5tb2RzLmFubm90YXRpb25zOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0TWV0aG9kRGVmKEpDTWV0aG9kRGVjbCB0cmVlKSB7CiAgICAgICAgICAgICAgICByZXN1bHQgPSB0cmVlLm1vZHMuYW5ub3RhdGlvbnM7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcHVibGljIHZvaWQgdmlzaXRWYXJEZWYoSkNWYXJpYWJsZURlY2wgdHJlZSkgewogICAgICAgICAgICAgICAgcmVzdWx0ID0gdHJlZS5tb2RzLmFubm90YXRpb25zOwogICAgICAgICAgICB9CiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdFR5cGVQYXJhbWV0ZXIoSkNUeXBlUGFyYW1ldGVyIHRyZWUpIHsKICAgICAgICAgICAgICAgIHJlc3VsdCA9IHRyZWUuYW5ub3RhdGlvbnM7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgVmlzIHZpcyA9IG5ldyBWaXMoKTsKICAgICAgICB0cmVlLmFjY2VwdCh2aXMpOwogICAgICAgIGlmICh2aXMucmVzdWx0ID09IG51bGwpCiAgICAgICAgICAgIHJldHVybiBudWxsOwoKICAgICAgICBMaXN0PEF0dHJpYnV0ZS5Db21wb3VuZD4gYW5ub3MgPSBzeW0uZ2V0QW5ub3RhdGlvbk1pcnJvcnMoKTsKICAgICAgICByZXR1cm4gbWF0Y2hBbm5vVG9UcmVlKGNhc3QoQXR0cmlidXRlLkNvbXBvdW5kLmNsYXNzLCBmaW5kbWUpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5ub3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aXMucmVzdWx0KTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHRyZWUgZm9yIGFuIGFubm90YXRpb24gZ2l2ZW4gYSBsaXN0IG9mIGFubm90YXRpb25zCiAgICAgKiBpbiB3aGljaCB0byBzZWFyY2ggKHJlY3Vyc2l2ZWx5KSBhbmQgdGhlaXIgY29ycmVzcG9uZGluZyB0cmVlcy4KICAgICAqIFJldHVybnMgbnVsbCBpZiB0aGUgdHJlZSBjYW5ub3QgYmUgZm91bmQuCiAgICAgKi8KICAgIHByaXZhdGUgSkNUcmVlIG1hdGNoQW5ub1RvVHJlZShBdHRyaWJ1dGUuQ29tcG91bmQgZmluZG1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExpc3Q8QXR0cmlidXRlLkNvbXBvdW5kPiBhbm5vcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0PEpDQW5ub3RhdGlvbj4gdHJlZXMpIHsKICAgICAgICBmb3IgKEF0dHJpYnV0ZS5Db21wb3VuZCBhbm5vIDogYW5ub3MpIHsKICAgICAgICAgICAgZm9yIChKQ0Fubm90YXRpb24gdHJlZSA6IHRyZWVzKSB7CiAgICAgICAgICAgICAgICBpZiAodHJlZS50eXBlLnRzeW0gIT0gYW5uby50eXBlLnRzeW0pCiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICBKQ1RyZWUgbWF0Y2ggPSBtYXRjaEF0dHJpYnV0ZVRvVHJlZShmaW5kbWUsIGFubm8sIHRyZWUpOwogICAgICAgICAgICAgICAgaWYgKG1hdGNoICE9IG51bGwpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG1hdGNoOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgdHJlZSBmb3IgYW4gYXR0cmlidXRlIGdpdmVuIGFuIGVuY2xvc2luZyBhdHRyaWJ1dGUgdG8KICAgICAqIHNlYXJjaCAocmVjdXJzaXZlbHkpIGFuZCB0aGUgZW5jbG9zaW5nIGF0dHJpYnV0ZSdzIGNvcnJlc3BvbmRpbmcgdHJlZS4KICAgICAqIFJldHVybnMgbnVsbCBpZiB0aGUgdHJlZSBjYW5ub3QgYmUgZm91bmQuCiAgICAgKi8KICAgIHByaXZhdGUgSkNUcmVlIG1hdGNoQXR0cmlidXRlVG9UcmVlKGZpbmFsIEF0dHJpYnV0ZSBmaW5kbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBBdHRyaWJ1dGUgYXR0ciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIEpDVHJlZSB0cmVlKSB7CiAgICAgICAgaWYgKGF0dHIgPT0gZmluZG1lKQogICAgICAgICAgICByZXR1cm4gdHJlZTsKCiAgICAgICAgY2xhc3MgVmlzIGltcGxlbWVudHMgQXR0cmlidXRlLlZpc2l0b3IgewogICAgICAgICAgICBKQ1RyZWUgcmVzdWx0ID0gbnVsbDsKICAgICAgICAgICAgcHVibGljIHZvaWQgdmlzaXRDb25zdGFudChBdHRyaWJ1dGUuQ29uc3RhbnQgdmFsdWUpIHsKICAgICAgICAgICAgfQogICAgICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdENsYXNzKEF0dHJpYnV0ZS5DbGFzcyBjbGF6eikgewogICAgICAgICAgICB9CiAgICAgICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0Q29tcG91bmQoQXR0cmlidXRlLkNvbXBvdW5kIGFubm8pIHsKICAgICAgICAgICAgICAgIGZvciAoUGFpcjxNZXRob2RTeW1ib2wsIEF0dHJpYnV0ZT4gcGFpciA6IGFubm8udmFsdWVzKSB7CiAgICAgICAgICAgICAgICAgICAgSkNFeHByZXNzaW9uIGV4cHIgPSBzY2FuRm9yQXNzaWduKHBhaXIuZnN0LCB0cmVlKTsKICAgICAgICAgICAgICAgICAgICBpZiAoZXhwciAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIEpDVHJlZSBtYXRjaCA9IG1hdGNoQXR0cmlidXRlVG9UcmVlKGZpbmRtZSwgcGFpci5zbmQsIGV4cHIpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAobWF0Y2ggIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gbWF0Y2g7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcHVibGljIHZvaWQgdmlzaXRBcnJheShBdHRyaWJ1dGUuQXJyYXkgYXJyYXkpIHsKICAgICAgICAgICAgICAgIGlmICh0cmVlLmhhc1RhZyhORVdBUlJBWSkpIHsKICAgICAgICAgICAgICAgICAgICBMaXN0PEpDRXhwcmVzc2lvbj4gZWxlbXMgPSAoKEpDTmV3QXJyYXkpdHJlZSkuZWxlbXM7CiAgICAgICAgICAgICAgICAgICAgZm9yIChBdHRyaWJ1dGUgdmFsdWUgOiBhcnJheS52YWx1ZXMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgSkNUcmVlIG1hdGNoID0gbWF0Y2hBdHRyaWJ1dGVUb1RyZWUoZmluZG1lLCB2YWx1ZSwgZWxlbXMuaGVhZCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChtYXRjaCAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBtYXRjaDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbGVtcyA9IGVsZW1zLnRhaWw7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChhcnJheS52YWx1ZXMubGVuZ3RoID09IDEpIHsKICAgICAgICAgICAgICAgICAgICAvLyB0aGUgdHJlZSBtYXkgbm90IGJlIGEgTkVXQVJSQVkgZm9yIHNpbmdsZS1lbGVtZW50IGFycmF5IGluaXRpYWxpemVycwogICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IG1hdGNoQXR0cmlidXRlVG9UcmVlKGZpbmRtZSwgYXJyYXkudmFsdWVzWzBdLCB0cmVlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdEVudW0oQXR0cmlidXRlLkVudW0gZSkgewogICAgICAgICAgICB9CiAgICAgICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0RXJyb3IoQXR0cmlidXRlLkVycm9yIGUpIHsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBWaXMgdmlzID0gbmV3IFZpcygpOwogICAgICAgIGF0dHIuYWNjZXB0KHZpcyk7CiAgICAgICAgcmV0dXJuIHZpcy5yZXN1bHQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBTY2FucyBmb3IgYSBKQ0Fzc2lnbiBub2RlIHdpdGggYSBMSFMgbWF0Y2hpbmcgYSBnaXZlbgogICAgICogc3ltYm9sLCBhbmQgcmV0dXJucyBpdHMgUkhTLiAgRG9lcyBub3Qgc2NhbiBuZXN0ZWQgSkNBbm5vdGF0aW9ucy4KICAgICAqLwogICAgcHJpdmF0ZSBKQ0V4cHJlc3Npb24gc2NhbkZvckFzc2lnbihmaW5hbCBNZXRob2RTeW1ib2wgc3ltLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBKQ1RyZWUgdHJlZSkgewogICAgICAgIGNsYXNzIFRTIGV4dGVuZHMgVHJlZVNjYW5uZXIgewogICAgICAgICAgICBKQ0V4cHJlc3Npb24gcmVzdWx0ID0gbnVsbDsKICAgICAgICAgICAgcHVibGljIHZvaWQgc2NhbihKQ1RyZWUgdCkgewogICAgICAgICAgICAgICAgaWYgKHQgIT0gbnVsbCAmJiByZXN1bHQgPT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICB0LmFjY2VwdCh0aGlzKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdEFubm90YXRpb24oSkNBbm5vdGF0aW9uIHQpIHsKICAgICAgICAgICAgICAgIGlmICh0ID09IHRyZWUpCiAgICAgICAgICAgICAgICAgICAgc2Nhbih0LmFyZ3MpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0QXNzaWduKEpDQXNzaWduIHQpIHsKICAgICAgICAgICAgICAgIGlmICh0Lmxocy5oYXNUYWcoSURFTlQpKSB7CiAgICAgICAgICAgICAgICAgICAgSkNJZGVudCBpZGVudCA9IChKQ0lkZW50KSB0LmxoczsKICAgICAgICAgICAgICAgICAgICBpZiAoaWRlbnQuc3ltID09IHN5bSkKICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gdC5yaHM7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgVFMgc2Nhbm5lciA9IG5ldyBUUygpOwogICAgICAgIHRyZWUuYWNjZXB0KHNjYW5uZXIpOwogICAgICAgIHJldHVybiBzY2FubmVyLnJlc3VsdDsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHRyZWUgbm9kZSBjb3JyZXNwb25kaW5nIHRvIHRoaXMgZWxlbWVudCwgb3IgbnVsbAogICAgICogaWYgbm9uZSBjYW4gYmUgZm91bmQuCiAgICAgKi8KICAgIHB1YmxpYyBKQ1RyZWUgZ2V0VHJlZShFbGVtZW50IGUpIHsKICAgICAgICBQYWlyPEpDVHJlZSwgPz4gdHJlZVRvcCA9IGdldFRyZWVBbmRUb3BMZXZlbChlKTsKICAgICAgICByZXR1cm4gKHRyZWVUb3AgIT0gbnVsbCkgPyB0cmVlVG9wLmZzdCA6IG51bGw7CiAgICB9CgogICAgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICBwdWJsaWMgU3RyaW5nIGdldERvY0NvbW1lbnQoRWxlbWVudCBlKSB7CiAgICAgICAgLy8gT3VyIGRvYyBjb21tZW50IGlzIGNvbnRhaW5lZCBpbiBhIG1hcCBpbiBvdXIgdG9wbGV2ZWwsCiAgICAgICAgLy8gaW5kZXhlZCBieSBvdXIgdHJlZS4gIEZpbmQgb3VyIGVudGVyIGVudmlyb25tZW50LCB3aGljaCBnaXZlcwogICAgICAgIC8vIHVzIG91ciB0b3BsZXZlbC4gIEl0IGFsc28gZ2l2ZXMgdXMgYSB0cmVlIHRoYXQgY29udGFpbnMgb3VyCiAgICAgICAgLy8gdHJlZTogIHdhbGsgaXQgdG8gZmluZCBvdXIgdHJlZS4gIFRoaXMgaXMgcGFpbmZ1bC4KICAgICAgICBQYWlyPEpDVHJlZSwgSkNDb21waWxhdGlvblVuaXQ+IHRyZWVUb3AgPSBnZXRUcmVlQW5kVG9wTGV2ZWwoZSk7CiAgICAgICAgaWYgKHRyZWVUb3AgPT0gbnVsbCkKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgSkNUcmVlIHRyZWUgPSB0cmVlVG9wLmZzdDsKICAgICAgICBKQ0NvbXBpbGF0aW9uVW5pdCB0b3BsZXZlbCA9IHRyZWVUb3Auc25kOwogICAgICAgIGlmICh0b3BsZXZlbC5kb2NDb21tZW50cyA9PSBudWxsKQogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICByZXR1cm4gdG9wbGV2ZWwuZG9jQ29tbWVudHMuZ2V0Q29tbWVudFRleHQodHJlZSk7CiAgICB9CgogICAgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICBwdWJsaWMgUGFja2FnZUVsZW1lbnQgZ2V0UGFja2FnZU9mKEVsZW1lbnQgZSkgewogICAgICAgIHJldHVybiBjYXN0KFN5bWJvbC5jbGFzcywgZSkucGFja2dlKCk7CiAgICB9CgogICAgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICBwdWJsaWMgTW9kdWxlRWxlbWVudCBnZXRNb2R1bGVPZihFbGVtZW50IGUpIHsKICAgICAgICBTeW1ib2wgc3ltID0gY2FzdChTeW1ib2wuY2xhc3MsIGUpOwogICAgICAgIGlmIChtb2R1bGVzLmdldERlZmF1bHRNb2R1bGUoKSA9PSBzeW1zLm5vTW9kdWxlKQogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICByZXR1cm4gKHN5bS5raW5kID09IE1ETCkgPyAoKE1vZHVsZUVsZW1lbnQpIGUpIDogc3ltLnBhY2tnZSgpLm1vZGxlOwogICAgfQoKICAgIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgcHVibGljIGJvb2xlYW4gaXNEZXByZWNhdGVkKEVsZW1lbnQgZSkgewogICAgICAgIFN5bWJvbCBzeW0gPSBjYXN0KFN5bWJvbC5jbGFzcywgZSk7CiAgICAgICAgc3ltLmNvbXBsZXRlKCk7CiAgICAgICAgcmV0dXJuIHN5bS5pc0RlcHJlY2F0ZWQoKTsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICBwdWJsaWMgT3JpZ2luIGdldE9yaWdpbihFbGVtZW50IGUpIHsKICAgICAgICBTeW1ib2wgc3ltID0gY2FzdChTeW1ib2wuY2xhc3MsIGUpOwogICAgICAgIGlmICgoc3ltLmZsYWdzKCkgJiBGbGFncy5HRU5FUkFURURDT05TVFIpICE9IDApCiAgICAgICAgICAgIHJldHVybiBPcmlnaW4uTUFOREFURUQ7CiAgICAgICAgLy9UeXBlRWxlbWVudC5nZXRFbmNsb3NlZEVsZW1lbnRzIGRvZXMgbm90IHJldHVybiBzeW50aGV0aWMgZWxlbWVudHMsCiAgICAgICAgLy9hbmQgbW9zdCBzeW50aGV0aWMgZWxlbWVudHMgYXJlIG5vdCByZWFkIGZyb20gdGhlIGNsYXNzZmlsZSBhbnl3YXk6CiAgICAgICAgcmV0dXJuIE9yaWdpbi5FWFBMSUNJVDsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICBwdWJsaWMgT3JpZ2luIGdldE9yaWdpbihBbm5vdGF0ZWRDb25zdHJ1Y3QgYywgQW5ub3RhdGlvbk1pcnJvciBhKSB7CiAgICAgICAgQ29tcG91bmQgYWMgPSBjYXN0KENvbXBvdW5kLmNsYXNzLCBhKTsKICAgICAgICBpZiAoYWMuaXNTeW50aGVzaXplZCgpKQogICAgICAgICAgICByZXR1cm4gT3JpZ2luLk1BTkRBVEVEOwogICAgICAgIHJldHVybiBPcmlnaW4uRVhQTElDSVQ7CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgcHVibGljIE9yaWdpbiBnZXRPcmlnaW4oTW9kdWxlRWxlbWVudCBtLCBNb2R1bGVFbGVtZW50LkRpcmVjdGl2ZSBkaXJlY3RpdmUpIHsKICAgICAgICBzd2l0Y2ggKGRpcmVjdGl2ZS5nZXRLaW5kKCkpIHsKICAgICAgICAgICAgY2FzZSBSRVFVSVJFUzoKICAgICAgICAgICAgICAgIFJlcXVpcmVzRGlyZWN0aXZlIHJkID0gY2FzdChSZXF1aXJlc0RpcmVjdGl2ZS5jbGFzcywgZGlyZWN0aXZlKTsKICAgICAgICAgICAgICAgIGlmIChyZC5mbGFncy5jb250YWlucyhSZXF1aXJlc0ZsYWcuTUFOREFURUQpKQogICAgICAgICAgICAgICAgICAgIHJldHVybiBPcmlnaW4uTUFOREFURUQ7CiAgICAgICAgICAgICAgICBpZiAocmQuZmxhZ3MuY29udGFpbnMoUmVxdWlyZXNGbGFnLlNZTlRIRVRJQykpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE9yaWdpbi5TWU5USEVUSUM7CiAgICAgICAgICAgICAgICByZXR1cm4gT3JpZ2luLkVYUExJQ0lUOwogICAgICAgICAgICBjYXNlIEVYUE9SVFM6CiAgICAgICAgICAgICAgICBFeHBvcnRzRGlyZWN0aXZlIGVkID0gY2FzdChFeHBvcnRzRGlyZWN0aXZlLmNsYXNzLCBkaXJlY3RpdmUpOwogICAgICAgICAgICAgICAgaWYgKGVkLmZsYWdzLmNvbnRhaW5zKEV4cG9ydHNGbGFnLk1BTkRBVEVEKSkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gT3JpZ2luLk1BTkRBVEVEOwogICAgICAgICAgICAgICAgaWYgKGVkLmZsYWdzLmNvbnRhaW5zKEV4cG9ydHNGbGFnLlNZTlRIRVRJQykpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE9yaWdpbi5TWU5USEVUSUM7CiAgICAgICAgICAgICAgICByZXR1cm4gT3JpZ2luLkVYUExJQ0lUOwogICAgICAgICAgICBjYXNlIE9QRU5TOgogICAgICAgICAgICAgICAgT3BlbnNEaXJlY3RpdmUgb2QgPSBjYXN0KE9wZW5zRGlyZWN0aXZlLmNsYXNzLCBkaXJlY3RpdmUpOwogICAgICAgICAgICAgICAgaWYgKG9kLmZsYWdzLmNvbnRhaW5zKE9wZW5zRmxhZy5NQU5EQVRFRCkpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE9yaWdpbi5NQU5EQVRFRDsKICAgICAgICAgICAgICAgIGlmIChvZC5mbGFncy5jb250YWlucyhPcGVuc0ZsYWcuU1lOVEhFVElDKSkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gT3JpZ2luLlNZTlRIRVRJQzsKICAgICAgICAgICAgICAgIHJldHVybiBPcmlnaW4uRVhQTElDSVQ7CiAgICAgICAgfQogICAgICAgIHJldHVybiBPcmlnaW4uRVhQTElDSVQ7CiAgICB9CgogICAgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICBwdWJsaWMgTmFtZSBnZXRCaW5hcnlOYW1lKFR5cGVFbGVtZW50IHR5cGUpIHsKICAgICAgICByZXR1cm4gY2FzdChUeXBlU3ltYm9sLmNsYXNzLCB0eXBlKS5mbGF0TmFtZSgpOwogICAgfQoKICAgIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgcHVibGljIE1hcDxNZXRob2RTeW1ib2wsIEF0dHJpYnV0ZT4gZ2V0RWxlbWVudFZhbHVlc1dpdGhEZWZhdWx0cygKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBbm5vdGF0aW9uTWlycm9yIGEpIHsKICAgICAgICBBdHRyaWJ1dGUuQ29tcG91bmQgYW5ubyA9IGNhc3QoQXR0cmlidXRlLkNvbXBvdW5kLmNsYXNzLCBhKTsKICAgICAgICBEZWNsYXJlZFR5cGUgYW5ub3R5cGUgPSBhLmdldEFubm90YXRpb25UeXBlKCk7CiAgICAgICAgTWFwPE1ldGhvZFN5bWJvbCwgQXR0cmlidXRlPiB2YWxtYXAgPSBhbm5vLmdldEVsZW1lbnRWYWx1ZXMoKTsKCiAgICAgICAgZm9yIChFeGVjdXRhYmxlRWxlbWVudCBleCA6CiAgICAgICAgICAgICAgICAgbWV0aG9kc0luKGFubm90eXBlLmFzRWxlbWVudCgpLmdldEVuY2xvc2VkRWxlbWVudHMoKSkpIHsKICAgICAgICAgICAgTWV0aG9kU3ltYm9sIG1ldGggPSAoTWV0aG9kU3ltYm9sKSBleDsKICAgICAgICAgICAgQXR0cmlidXRlIGRlZmF1bHRWYWx1ZSA9IG1ldGguZ2V0RGVmYXVsdFZhbHVlKCk7CiAgICAgICAgICAgIGlmIChkZWZhdWx0VmFsdWUgIT0gbnVsbCAmJiAhdmFsbWFwLmNvbnRhaW5zS2V5KG1ldGgpKSB7CiAgICAgICAgICAgICAgICB2YWxtYXAucHV0KG1ldGgsIGRlZmF1bHRWYWx1ZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHZhbG1hcDsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICBwdWJsaWMgRmlsdGVyZWRNZW1iZXJMaXN0IGdldEFsbE1lbWJlcnMoVHlwZUVsZW1lbnQgZWxlbWVudCkgewogICAgICAgIFN5bWJvbCBzeW0gPSBjYXN0KFN5bWJvbC5jbGFzcywgZWxlbWVudCk7CiAgICAgICAgV3JpdGVhYmxlU2NvcGUgc2NvcGUgPSBzeW0ubWVtYmVycygpLmR1cFVuc2hhcmVkKCk7CiAgICAgICAgTGlzdDxUeXBlPiBjbG9zdXJlID0gdHlwZXMuY2xvc3VyZShzeW0uYXNUeXBlKCkpOwogICAgICAgIGZvciAoVHlwZSB0IDogY2xvc3VyZSkKICAgICAgICAgICAgYWRkTWVtYmVycyhzY29wZSwgdCk7CiAgICAgICAgcmV0dXJuIG5ldyBGaWx0ZXJlZE1lbWJlckxpc3Qoc2NvcGUpOwogICAgfQogICAgLy8gd2hlcmUKICAgICAgICBwcml2YXRlIHZvaWQgYWRkTWVtYmVycyhXcml0ZWFibGVTY29wZSBzY29wZSwgVHlwZSB0eXBlKSB7CiAgICAgICAgICAgIG1lbWJlcnM6CiAgICAgICAgICAgIGZvciAoU3ltYm9sIGUgOiB0eXBlLmFzRWxlbWVudCgpLm1lbWJlcnMoKS5nZXRTeW1ib2xzKE5PTl9SRUNVUlNJVkUpKSB7CiAgICAgICAgICAgICAgICBmb3IgKFN5bWJvbCBvdmVycmlkZXIgOiBzY29wZS5nZXRTeW1ib2xzQnlOYW1lKGUuZ2V0U2ltcGxlTmFtZSgpKSkgewogICAgICAgICAgICAgICAgICAgIGlmIChvdmVycmlkZXIua2luZCA9PSBlLmtpbmQgJiYgKG92ZXJyaWRlci5mbGFncygpICYgRmxhZ3MuU1lOVEhFVElDKSA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvdmVycmlkZXIuZ2V0S2luZCgpID09IEVsZW1lbnRLaW5kLk1FVEhPRCAmJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG92ZXJyaWRlcygoRXhlY3V0YWJsZUVsZW1lbnQpb3ZlcnJpZGVyLCAoRXhlY3V0YWJsZUVsZW1lbnQpZSwgKFR5cGVFbGVtZW50KXR5cGUuYXNFbGVtZW50KCkpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZSBtZW1iZXJzOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYm9vbGVhbiBkZXJpdmVkID0gZS5nZXRFbmNsb3NpbmdFbGVtZW50KCkgIT0gc2NvcGUub3duZXI7CiAgICAgICAgICAgICAgICBFbGVtZW50S2luZCBraW5kID0gZS5nZXRLaW5kKCk7CiAgICAgICAgICAgICAgICBib29sZWFuIGluaXRpYWxpemVyID0ga2luZCA9PSBFbGVtZW50S2luZC5DT05TVFJVQ1RPUgogICAgICAgICAgICAgICAgICAgIHx8IGtpbmQgPT0gRWxlbWVudEtpbmQuSU5TVEFOQ0VfSU5JVAogICAgICAgICAgICAgICAgICAgIHx8IGtpbmQgPT0gRWxlbWVudEtpbmQuU1RBVElDX0lOSVQ7CiAgICAgICAgICAgICAgICBpZiAoIWRlcml2ZWQgfHwgKCFpbml0aWFsaXplciAmJiBlLmlzSW5oZXJpdGVkSW4oc2NvcGUub3duZXIsIHR5cGVzKSkpCiAgICAgICAgICAgICAgICAgICAgc2NvcGUuZW50ZXIoZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGFsbCBhbm5vdGF0aW9ucyBvZiBhbiBlbGVtZW50LCB3aGV0aGVyCiAgICAgKiBpbmhlcml0ZWQgb3IgZGlyZWN0bHkgcHJlc2VudC4KICAgICAqCiAgICAgKiBAcGFyYW0gZSAgdGhlIGVsZW1lbnQgYmVpbmcgZXhhbWluZWQKICAgICAqIEByZXR1cm4gYWxsIGFubm90YXRpb25zIG9mIHRoZSBlbGVtZW50CiAgICAgKi8KICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgIHB1YmxpYyBMaXN0PEF0dHJpYnV0ZS5Db21wb3VuZD4gZ2V0QWxsQW5ub3RhdGlvbk1pcnJvcnMoRWxlbWVudCBlKSB7CiAgICAgICAgU3ltYm9sIHN5bSA9IGNhc3QoU3ltYm9sLmNsYXNzLCBlKTsKICAgICAgICBMaXN0PEF0dHJpYnV0ZS5Db21wb3VuZD4gYW5ub3MgPSBzeW0uZ2V0QW5ub3RhdGlvbk1pcnJvcnMoKTsKICAgICAgICB3aGlsZSAoc3ltLmdldEtpbmQoKSA9PSBFbGVtZW50S2luZC5DTEFTUykgewogICAgICAgICAgICBUeXBlIHN1cCA9ICgoQ2xhc3NTeW1ib2wpIHN5bSkuZ2V0U3VwZXJjbGFzcygpOwogICAgICAgICAgICBpZiAoIXN1cC5oYXNUYWcoQ0xBU1MpIHx8IHN1cC5pc0Vycm9uZW91cygpIHx8CiAgICAgICAgICAgICAgICAgICAgc3VwLnRzeW0gPT0gc3ltcy5vYmplY3RUeXBlLnRzeW0pIHsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHN5bSA9IHN1cC50c3ltOwogICAgICAgICAgICBMaXN0PEF0dHJpYnV0ZS5Db21wb3VuZD4gb2xkQW5ub3MgPSBhbm5vczsKICAgICAgICAgICAgTGlzdDxBdHRyaWJ1dGUuQ29tcG91bmQ+IG5ld0Fubm9zID0gc3ltLmdldEFubm90YXRpb25NaXJyb3JzKCk7CiAgICAgICAgICAgIGZvciAoQXR0cmlidXRlLkNvbXBvdW5kIGFubm8gOiBuZXdBbm5vcykgewogICAgICAgICAgICAgICAgaWYgKGlzSW5oZXJpdGVkKGFubm8udHlwZSkgJiYKICAgICAgICAgICAgICAgICAgICAgICAgIWNvbnRhaW5zQW5ub09mVHlwZShvbGRBbm5vcywgYW5uby50eXBlKSkgewogICAgICAgICAgICAgICAgICAgIGFubm9zID0gYW5ub3MucHJlcGVuZChhbm5vKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gYW5ub3M7CiAgICB9CgogICAgLyoqCiAgICAgKiBUZXN0cyB3aGV0aGVyIGFuIGFubm90YXRpb24gdHlwZSBpcyBASW5oZXJpdGVkLgogICAgICovCiAgICBwcml2YXRlIGJvb2xlYW4gaXNJbmhlcml0ZWQoVHlwZSBhbm5vdHlwZSkgewogICAgICAgIHJldHVybiBhbm5vdHlwZS50c3ltLmF0dHJpYnV0ZShzeW1zLmluaGVyaXRlZFR5cGUudHN5bSkgIT0gbnVsbDsKICAgIH0KCiAgICAvKioKICAgICAqIFRlc3RzIHdoZXRoZXIgYSBsaXN0IG9mIGFubm90YXRpb25zIGNvbnRhaW5zIGFuIGFubm90YXRpb24KICAgICAqIG9mIGEgZ2l2ZW4gdHlwZS4KICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBjb250YWluc0Fubm9PZlR5cGUoTGlzdDxBdHRyaWJ1dGUuQ29tcG91bmQ+IGFubm9zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVHlwZSB0eXBlKSB7CiAgICAgICAgZm9yIChBdHRyaWJ1dGUuQ29tcG91bmQgYW5ubyA6IGFubm9zKSB7CiAgICAgICAgICAgIGlmIChhbm5vLnR5cGUudHN5bSA9PSB0eXBlLnRzeW0pCiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgcHVibGljIGJvb2xlYW4gaGlkZXMoRWxlbWVudCBoaWRlckVsLCBFbGVtZW50IGhpZGVlRWwpIHsKICAgICAgICBTeW1ib2wgaGlkZXIgPSBjYXN0KFN5bWJvbC5jbGFzcywgaGlkZXJFbCk7CiAgICAgICAgU3ltYm9sIGhpZGVlID0gY2FzdChTeW1ib2wuY2xhc3MsIGhpZGVlRWwpOwoKICAgICAgICAvLyBGaWVsZHMgb25seSBoaWRlIGZpZWxkczsgbWV0aG9kcyBvbmx5IG1ldGhvZHM7IHR5cGVzIG9ubHkgdHlwZXMuCiAgICAgICAgLy8gTmFtZXMgbXVzdCBtYXRjaC4gIE5vdGhpbmcgaGlkZXMgaXRzZWxmIChqdXN0IHRyeSBpdCkuCiAgICAgICAgaWYgKGhpZGVyID09IGhpZGVlIHx8CiAgICAgICAgICAgICAgICBoaWRlci5raW5kICE9IGhpZGVlLmtpbmQgfHwKICAgICAgICAgICAgICAgIGhpZGVyLm5hbWUgIT0gaGlkZWUubmFtZSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICAvLyBPbmx5IHN0YXRpYyBtZXRob2RzIGNhbiBoaWRlIG90aGVyIG1ldGhvZHMuCiAgICAgICAgLy8gTWV0aG9kcyBvbmx5IGhpZGUgbWV0aG9kcyB3aXRoIG1hdGNoaW5nIHNpZ25hdHVyZXMuCiAgICAgICAgaWYgKGhpZGVyLmtpbmQgPT0gTVRIKSB7CiAgICAgICAgICAgIGlmICghaGlkZXIuaXNTdGF0aWMoKSB8fAogICAgICAgICAgICAgICAgICAgICAgICAhdHlwZXMuaXNTdWJTaWduYXR1cmUoaGlkZXIudHlwZSwgaGlkZWUudHlwZSkpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gSGlkZXIgbXVzdCBiZSBpbiBhIHN1YmNsYXNzIG9mIGhpZGVlJ3MgY2xhc3MuCiAgICAgICAgLy8gTm90ZSB0aGF0IGlmIE0xIGhpZGVzIE0yLCBhbmQgTTIgaGlkZXMgTTMsIGFuZCBNMyBpcyBhY2Nlc3NpYmxlCiAgICAgICAgLy8gaW4gTTEncyBjbGFzcywgdGhlbiBNMSBhbmQgTTIgYm90aCBoaWRlIE0zLgogICAgICAgIENsYXNzU3ltYm9sIGhpZGVyQ2xhc3MgPSBoaWRlci5vd25lci5lbmNsQ2xhc3MoKTsKICAgICAgICBDbGFzc1N5bWJvbCBoaWRlZUNsYXNzID0gaGlkZWUub3duZXIuZW5jbENsYXNzKCk7CiAgICAgICAgaWYgKGhpZGVyQ2xhc3MgPT0gbnVsbCB8fCBoaWRlZUNsYXNzID09IG51bGwgfHwKICAgICAgICAgICAgICAgICFoaWRlckNsYXNzLmlzU3ViQ2xhc3MoaGlkZWVDbGFzcywgdHlwZXMpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIC8vIEhpZGVlIG11c3QgYmUgYWNjZXNzaWJsZSBpbiBoaWRlcidzIGNsYXNzLgogICAgICAgIC8vIFRoZSBtZXRob2QgaXNJbmhlcml0ZWRJbiBpcyBwb29ybHkgbmFtZWQ6ICBpdCBjaGVja3Mgb25seSBhY2Nlc3MuCiAgICAgICAgcmV0dXJuIGhpZGVlLmlzSW5oZXJpdGVkSW4oaGlkZXJDbGFzcywgdHlwZXMpOwogICAgfQoKICAgIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgcHVibGljIGJvb2xlYW4gb3ZlcnJpZGVzKEV4ZWN1dGFibGVFbGVtZW50IHJpZGVyRWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRXhlY3V0YWJsZUVsZW1lbnQgcmlkZWVFbCwgVHlwZUVsZW1lbnQgdHlwZUVsKSB7CiAgICAgICAgTWV0aG9kU3ltYm9sIHJpZGVyID0gY2FzdChNZXRob2RTeW1ib2wuY2xhc3MsIHJpZGVyRWwpOwogICAgICAgIE1ldGhvZFN5bWJvbCByaWRlZSA9IGNhc3QoTWV0aG9kU3ltYm9sLmNsYXNzLCByaWRlZUVsKTsKICAgICAgICBDbGFzc1N5bWJvbCBvcmlnaW4gPSBjYXN0KENsYXNzU3ltYm9sLmNsYXNzLCB0eXBlRWwpOwoKICAgICAgICByZXR1cm4gcmlkZXIubmFtZSA9PSByaWRlZS5uYW1lICYmCgogICAgICAgICAgICAgICAvLyBub3QgcmVmbGV4aXZlIGFzIHBlciBKTFMKICAgICAgICAgICAgICAgcmlkZXIgIT0gcmlkZWUgJiYKCiAgICAgICAgICAgICAgIC8vIHdlIGRvbid0IGNhcmUgaWYgcmlkZWUgaXMgc3RhdGljLCB0aG91Z2ggdGhhdCB3b3VsZG4ndAogICAgICAgICAgICAgICAvLyBjb21waWxlCiAgICAgICAgICAgICAgICFyaWRlci5pc1N0YXRpYygpICYmCgogICAgICAgICAgICAgICAvLyBTeW1ib2wub3ZlcnJpZGVzIGFzc3VtZXMgdGhlIGZvbGxvd2luZwogICAgICAgICAgICAgICByaWRlZS5pc01lbWJlck9mKG9yaWdpbiwgdHlwZXMpICYmCgogICAgICAgICAgICAgICAvLyBjaGVjayBhY2Nlc3MgYW5kIHNpZ25hdHVyZXM7IGRvbid0IGNoZWNrIHJldHVybiB0eXBlcwogICAgICAgICAgICAgICByaWRlci5vdmVycmlkZXMocmlkZWUsIG9yaWdpbiwgdHlwZXMsIGZhbHNlKTsKICAgIH0KCiAgICBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgIHB1YmxpYyBTdHJpbmcgZ2V0Q29uc3RhbnRFeHByZXNzaW9uKE9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBDb25zdGFudHMuZm9ybWF0KHZhbHVlKTsKICAgIH0KCiAgICAvKioKICAgICAqIFByaW50IGEgcmVwcmVzZW50YXRpb24gb2YgdGhlIGVsZW1lbnRzIHRvIHRoZSBnaXZlbiB3cml0ZXIgaW4KICAgICAqIHRoZSBzcGVjaWZpZWQgb3JkZXIuICBUaGUgbWFpbiBwdXJwb3NlIG9mIHRoaXMgbWV0aG9kIGlzIGZvcgogICAgICogZGlhZ25vc3RpY3MuICBUaGUgZXhhY3QgZm9ybWF0IG9mIHRoZSBvdXRwdXQgaXMgPGVtPm5vdDwvZW0+CiAgICAgKiBzcGVjaWZpZWQgYW5kIGlzIHN1YmplY3QgdG8gY2hhbmdlLgogICAgICoKICAgICAqIEBwYXJhbSB3IHRoZSB3cml0ZXIgdG8gcHJpbnQgdGhlIG91dHB1dCB0bwogICAgICogQHBhcmFtIGVsZW1lbnRzIHRoZSBlbGVtZW50cyB0byBwcmludAogICAgICovCiAgICBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgIHB1YmxpYyB2b2lkIHByaW50RWxlbWVudHMoamF2YS5pby5Xcml0ZXIgdywgRWxlbWVudC4uLiBlbGVtZW50cykgewogICAgICAgIGZvciAoRWxlbWVudCBlbGVtZW50IDogZWxlbWVudHMpCiAgICAgICAgICAgIChuZXcgUHJpbnRpbmdQcm9jZXNzb3IuUHJpbnRpbmdFbGVtZW50VmlzaXRvcih3LCB0aGlzKSkudmlzaXQoZWxlbWVudCkuZmx1c2goKTsKICAgIH0KCiAgICBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgIHB1YmxpYyBOYW1lIGdldE5hbWUoQ2hhclNlcXVlbmNlIGNzKSB7CiAgICAgICAgcmV0dXJuIG5hbWVzLmZyb21TdHJpbmcoY3MudG9TdHJpbmcoKSk7CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgcHVibGljIGJvb2xlYW4gaXNGdW5jdGlvbmFsSW50ZXJmYWNlKFR5cGVFbGVtZW50IGVsZW1lbnQpIHsKICAgICAgICBpZiAoZWxlbWVudC5nZXRLaW5kKCkgIT0gRWxlbWVudEtpbmQuSU5URVJGQUNFKQogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIFR5cGVTeW1ib2wgdHN5bSA9IGNhc3QoVHlwZVN5bWJvbC5jbGFzcywgZWxlbWVudCk7CiAgICAgICAgICAgIHJldHVybiB0eXBlcy5pc0Z1bmN0aW9uYWxJbnRlcmZhY2UodHN5bSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgdHJlZSBub2RlIGFuZCBjb21waWxhdGlvbiB1bml0IGNvcnJlc3BvbmRpbmcgdG8gdGhpcwogICAgICogZWxlbWVudCwgb3IgbnVsbCBpZiB0aGV5IGNhbid0IGJlIGZvdW5kLgogICAgICovCiAgICBwcml2YXRlIFBhaXI8SkNUcmVlLCBKQ0NvbXBpbGF0aW9uVW5pdD4gZ2V0VHJlZUFuZFRvcExldmVsKEVsZW1lbnQgZSkgewogICAgICAgIFN5bWJvbCBzeW0gPSBjYXN0KFN5bWJvbC5jbGFzcywgZSk7CiAgICAgICAgRW52PEF0dHJDb250ZXh0PiBlbnRlckVudiA9IGdldEVudGVyRW52KHN5bSk7CiAgICAgICAgaWYgKGVudGVyRW52ID09IG51bGwpCiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIEpDVHJlZSB0cmVlID0gVHJlZUluZm8uZGVjbGFyYXRpb25Gb3Ioc3ltLCBlbnRlckVudi50cmVlKTsKICAgICAgICBpZiAodHJlZSA9PSBudWxsIHx8IGVudGVyRW52LnRvcGxldmVsID09IG51bGwpCiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIHJldHVybiBuZXcgUGFpcjw+KHRyZWUsIGVudGVyRW52LnRvcGxldmVsKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGJlc3QgYXBwcm94aW1hdGlvbiBmb3IgdGhlIHRyZWUgbm9kZSBhbmQgY29tcGlsYXRpb24gdW5pdAogICAgICogY29ycmVzcG9uZGluZyB0byB0aGUgZ2l2ZW4gZWxlbWVudCwgYW5ub3RhdGlvbiBhbmQgdmFsdWUuCiAgICAgKiBJZiB0aGUgZWxlbWVudCBpcyBudWxsLCBudWxsIGlzIHJldHVybmVkLgogICAgICogSWYgdGhlIGFubm90YXRpb24gaXMgbnVsbCBvciBjYW5ub3QgYmUgZm91bmQsIHRoZSB0cmVlIG5vZGUgYW5kCiAgICAgKiBjb21waWxhdGlvbiB1bml0IGZvciB0aGUgZWxlbWVudCBpcyByZXR1cm5lZC4KICAgICAqIElmIHRoZSBhbm5vdGF0aW9uIHZhbHVlIGlzIG51bGwgb3IgY2Fubm90IGJlIGZvdW5kLCB0aGUgdHJlZSBub2RlIGFuZAogICAgICogY29tcGlsYXRpb24gdW5pdCBmb3IgdGhlIGFubm90YXRpb24gaXMgcmV0dXJuZWQuCiAgICAgKi8KICAgIHB1YmxpYyBQYWlyPEpDVHJlZSwgSkNDb21waWxhdGlvblVuaXQ+IGdldFRyZWVBbmRUb3BMZXZlbCgKICAgICAgICAgICAgICAgICAgICAgIEVsZW1lbnQgZSwgQW5ub3RhdGlvbk1pcnJvciBhLCBBbm5vdGF0aW9uVmFsdWUgdikgewogICAgICAgIGlmIChlID09IG51bGwpCiAgICAgICAgICAgIHJldHVybiBudWxsOwoKICAgICAgICBQYWlyPEpDVHJlZSwgSkNDb21waWxhdGlvblVuaXQ+IGVsZW1UcmVlVG9wID0gZ2V0VHJlZUFuZFRvcExldmVsKGUpOwogICAgICAgIGlmIChlbGVtVHJlZVRvcCA9PSBudWxsKQogICAgICAgICAgICByZXR1cm4gbnVsbDsKCiAgICAgICAgaWYgKGEgPT0gbnVsbCkKICAgICAgICAgICAgcmV0dXJuIGVsZW1UcmVlVG9wOwoKICAgICAgICBKQ1RyZWUgYW5ub1RyZWUgPSBtYXRjaEFubm9Ub1RyZWUoYSwgZSwgZWxlbVRyZWVUb3AuZnN0KTsKICAgICAgICBpZiAoYW5ub1RyZWUgPT0gbnVsbCkKICAgICAgICAgICAgcmV0dXJuIGVsZW1UcmVlVG9wOwoKICAgICAgICBpZiAodiA9PSBudWxsKQogICAgICAgICAgICByZXR1cm4gbmV3IFBhaXI8Pihhbm5vVHJlZSwgZWxlbVRyZWVUb3Auc25kKTsKCiAgICAgICAgSkNUcmVlIHZhbHVlVHJlZSA9IG1hdGNoQXR0cmlidXRlVG9UcmVlKAogICAgICAgICAgICAgICAgY2FzdChBdHRyaWJ1dGUuY2xhc3MsIHYpLCBjYXN0KEF0dHJpYnV0ZS5jbGFzcywgYSksIGFubm9UcmVlKTsKICAgICAgICBpZiAodmFsdWVUcmVlID09IG51bGwpCiAgICAgICAgICAgIHJldHVybiBuZXcgUGFpcjw+KGFubm9UcmVlLCBlbGVtVHJlZVRvcC5zbmQpOwoKICAgICAgICByZXR1cm4gbmV3IFBhaXI8Pih2YWx1ZVRyZWUsIGVsZW1UcmVlVG9wLnNuZCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgc3ltYm9sJ3MgZW50ZXIgZW52aXJvbm1lbnQsIG9yIG51bGwgaWYgaXQgaGFzIG5vbmUuCiAgICAgKi8KICAgIHByaXZhdGUgRW52PEF0dHJDb250ZXh0PiBnZXRFbnRlckVudihTeW1ib2wgc3ltKSB7CiAgICAgICAgLy8gR2V0IGVuY2xvc2luZyBjbGFzcyBvZiBzeW0sIG9yIHN5bSBpdHNlbGYgaWYgaXQgaXMgYSBjbGFzcwogICAgICAgIC8vIHBhY2thZ2UsIG9yIG1vZHVsZS4KICAgICAgICBUeXBlU3ltYm9sIHRzID0gbnVsbDsKICAgICAgICBzd2l0Y2ggKHN5bS5raW5kKSB7CiAgICAgICAgICAgIGNhc2UgUENLOgogICAgICAgICAgICAgICAgdHMgPSAoUGFja2FnZVN5bWJvbClzeW07CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBNREw6CiAgICAgICAgICAgICAgICB0cyA9IChNb2R1bGVTeW1ib2wpc3ltOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICB0cyA9IHN5bS5lbmNsQ2xhc3MoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuICh0cyAhPSBudWxsKQogICAgICAgICAgICAgICAgPyBlbnRlci5nZXRFbnYodHMpCiAgICAgICAgICAgICAgICA6IG51bGw7CiAgICB9CgogICAgcHJpdmF0ZSB2b2lkIGVuc3VyZUVudGVyZWQoU3RyaW5nIG1ldGhvZE5hbWUpIHsKICAgICAgICBpZiAoamF2YWNUYXNrSW1wbCAhPSBudWxsKSB7CiAgICAgICAgICAgIGphdmFjVGFza0ltcGwuZW5zdXJlRW50ZXJlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIWphdmFDb21waWxlci5pc0VudGVyRG9uZSgpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oIkNhbm5vdCB1c2UgRWxlbWVudHMuIiArIG1ldGhvZE5hbWUgKyAiIGJlZm9yZSB0aGUgVGFza0V2ZW50LktpbmQuRU5URVIgZmluaXNoZWQgZXZlbnQuIik7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyBhbiBvYmplY3QgY2FzdCB0byB0aGUgc3BlY2lmaWVkIHR5cGUuCiAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBvYmplY3QgaXMge0Bjb2RlIG51bGx9CiAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgb2JqZWN0IGlzIG9mIHRoZSB3cm9uZyB0eXBlCiAgICAgKi8KICAgIHByaXZhdGUgc3RhdGljIDxUPiBUIGNhc3QoQ2xhc3M8VD4gY2xhenosIE9iamVjdCBvKSB7CiAgICAgICAgaWYgKCEgY2xhenouaXNJbnN0YW5jZShvKSkKICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihvLnRvU3RyaW5nKCkpOwogICAgICAgIHJldHVybiBjbGF6ei5jYXN0KG8pOwogICAgfQp9ClBLAwQKAAAIAAAGO6lKu8BdqjAzAAAwMwAAMwAAAGNvbS9zdW4vdG9vbHMvamF2YWMvbW9kZWwvQW5ub3RhdGlvblByb3h5TWFrZXIuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAxNCwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLmphdmFjLm1vZGVsOwoKaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CmltcG9ydCBqYXZhLmlvLk9iamVjdElucHV0U3RyZWFtOwppbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uKjsKaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LkFycmF5OwppbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuTWV0aG9kOwppbXBvcnQgamF2YS51dGlsLkxpbmtlZEhhc2hNYXA7CmltcG9ydCBqYXZhLnV0aWwuTWFwOwppbXBvcnQgc3VuLnJlZmxlY3QuYW5ub3RhdGlvbi4qOwoKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwudHlwZS5NaXJyb3JlZFR5cGVFeGNlcHRpb247CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLnR5cGUuTWlycm9yZWRUeXBlc0V4Y2VwdGlvbjsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwudHlwZS5UeXBlTWlycm9yOwoKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS4qOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlN5bWJvbC4qOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlR5cGUuQXJyYXlUeXBlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLio7CgppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5TY29wZS5Mb29rdXBLaW5kLk5PTl9SRUNVUlNJVkU7CmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLktpbmRzLktpbmQuKjsKCi8qKgogKiBBIGdlbmVyYXRvciBvZiBkeW5hbWljIHByb3h5IGltcGxlbWVudGF0aW9ucyBvZgogKiBqYXZhLmxhbmcuYW5ub3RhdGlvbi5Bbm5vdGF0aW9uLgogKgogKiA8cD4gVGhlICJkeW5hbWljIHByb3h5IHJldHVybiBmb3JtIiBvZiBhbiBhbm5vdGF0aW9uIGVsZW1lbnQgdmFsdWUgaXMKICogdGhlIGZvcm0gdXNlZCBieSBzdW4ucmVmbGVjdC5hbm5vdGF0aW9uLkFubm90YXRpb25JbnZvY2F0aW9uSGFuZGxlci4KICoKICogPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93biByaXNrLgogKiBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogKiBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+CiAqLwoKcHVibGljIGNsYXNzIEFubm90YXRpb25Qcm94eU1ha2VyIHsKCiAgICBwcml2YXRlIGZpbmFsIEF0dHJpYnV0ZS5Db21wb3VuZCBhbm5vOwogICAgcHJpdmF0ZSBmaW5hbCBDbGFzczw/IGV4dGVuZHMgQW5ub3RhdGlvbj4gYW5ub1R5cGU7CgoKICAgIHByaXZhdGUgQW5ub3RhdGlvblByb3h5TWFrZXIoQXR0cmlidXRlLkNvbXBvdW5kIGFubm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENsYXNzPD8gZXh0ZW5kcyBBbm5vdGF0aW9uPiBhbm5vVHlwZSkgewogICAgICAgIHRoaXMuYW5ubyA9IGFubm87CiAgICAgICAgdGhpcy5hbm5vVHlwZSA9IGFubm9UeXBlOwogICAgfQoKCiAgICAvKioKICAgICAqIFJldHVybnMgYSBkeW5hbWljIHByb3h5IGZvciBhbiBhbm5vdGF0aW9uIG1pcnJvci4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyA8QSBleHRlbmRzIEFubm90YXRpb24+IEEgZ2VuZXJhdGVBbm5vdGF0aW9uKAogICAgICAgICAgICBBdHRyaWJ1dGUuQ29tcG91bmQgYW5ubywgQ2xhc3M8QT4gYW5ub1R5cGUpIHsKICAgICAgICBBbm5vdGF0aW9uUHJveHlNYWtlciBhcG0gPSBuZXcgQW5ub3RhdGlvblByb3h5TWFrZXIoYW5ubywgYW5ub1R5cGUpOwogICAgICAgIHJldHVybiBhbm5vVHlwZS5jYXN0KGFwbS5nZW5lcmF0ZUFubm90YXRpb24oKSk7CiAgICB9CgoKICAgIC8qKgogICAgICogUmV0dXJucyBhIGR5bmFtaWMgcHJveHkgZm9yIGFuIGFubm90YXRpb24gbWlycm9yLgogICAgICovCiAgICBwcml2YXRlIEFubm90YXRpb24gZ2VuZXJhdGVBbm5vdGF0aW9uKCkgewogICAgICAgIHJldHVybiBBbm5vdGF0aW9uUGFyc2VyLmFubm90YXRpb25Gb3JNYXAoYW5ub1R5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRBbGxSZWZsZWN0ZWRWYWx1ZXMoKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgbWFwIGZyb20gZWxlbWVudCBuYW1lcyB0byB0aGVpciB2YWx1ZXMgaW4gImR5bmFtaWMKICAgICAqIHByb3h5IHJldHVybiBmb3JtIi4gIEluY2x1ZGVzIGFsbCBlbGVtZW50cywgd2hldGhlciBleHBsaWNpdCBvcgogICAgICogZGVmYXVsdGVkLgogICAgICovCiAgICBwcml2YXRlIE1hcDxTdHJpbmcsIE9iamVjdD4gZ2V0QWxsUmVmbGVjdGVkVmFsdWVzKCkgewogICAgICAgIE1hcDxTdHJpbmcsIE9iamVjdD4gcmVzID0gbmV3IExpbmtlZEhhc2hNYXA8PigpOwoKICAgICAgICBmb3IgKE1hcC5FbnRyeTxNZXRob2RTeW1ib2wsIEF0dHJpYnV0ZT4gZW50cnkgOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldEFsbFZhbHVlcygpLmVudHJ5U2V0KCkpIHsKICAgICAgICAgICAgTWV0aG9kU3ltYm9sIG1ldGggPSBlbnRyeS5nZXRLZXkoKTsKICAgICAgICAgICAgT2JqZWN0IHZhbHVlID0gZ2VuZXJhdGVWYWx1ZShtZXRoLCBlbnRyeS5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgaWYgKHZhbHVlICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIHJlcy5wdXQobWV0aC5uYW1lLnRvU3RyaW5nKCksIHZhbHVlKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIC8vIElnbm9yZSB0aGlzIGVsZW1lbnQuICBNYXkgKHByb3Blcmx5KSBsZWFkIHRvCiAgICAgICAgICAgICAgICAvLyBJbmNvbXBsZXRlQW5ub3RhdGlvbkV4Y2VwdGlvbiBzb21ld2hlcmUgZG93biB0aGUgbGluZS4KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyBhIG1hcCBmcm9tIGVsZW1lbnQgc3ltYm9scyB0byB0aGVpciB2YWx1ZXMuCiAgICAgKiBJbmNsdWRlcyBhbGwgZWxlbWVudHMsIHdoZXRoZXIgZXhwbGljaXQgb3IgZGVmYXVsdGVkLgogICAgICovCiAgICBwcml2YXRlIE1hcDxNZXRob2RTeW1ib2wsIEF0dHJpYnV0ZT4gZ2V0QWxsVmFsdWVzKCkgewogICAgICAgIE1hcDxNZXRob2RTeW1ib2wsIEF0dHJpYnV0ZT4gcmVzID0gbmV3IExpbmtlZEhhc2hNYXA8PigpOwoKICAgICAgICAvLyBGaXJzdCBmaW5kIHRoZSBkZWZhdWx0IHZhbHVlcy4KICAgICAgICBDbGFzc1N5bWJvbCBzeW0gPSAoQ2xhc3NTeW1ib2wpIGFubm8udHlwZS50c3ltOwogICAgICAgIGZvciAoU3ltYm9sIHMgOiBzeW0ubWVtYmVycygpLmdldFN5bWJvbHMoTk9OX1JFQ1VSU0lWRSkpIHsKICAgICAgICAgICAgaWYgKHMua2luZCA9PSBNVEgpIHsKICAgICAgICAgICAgICAgIE1ldGhvZFN5bWJvbCBtID0gKE1ldGhvZFN5bWJvbCkgczsKICAgICAgICAgICAgICAgIEF0dHJpYnV0ZSBkZWYgPSBtLmdldERlZmF1bHRWYWx1ZSgpOwogICAgICAgICAgICAgICAgaWYgKGRlZiAhPSBudWxsKQogICAgICAgICAgICAgICAgICAgIHJlcy5wdXQobSwgZGVmKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvLyBOZXh0IGZpbmQgdGhlIGV4cGxpY2l0IHZhbHVlcywgcG9zc2libHkgb3ZlcnJpZGluZyBkZWZhdWx0cy4KICAgICAgICBmb3IgKFBhaXI8TWV0aG9kU3ltYm9sLCBBdHRyaWJ1dGU+IHAgOiBhbm5vLnZhbHVlcykKICAgICAgICAgICAgcmVzLnB1dChwLmZzdCwgcC5zbmQpOwogICAgICAgIHJldHVybiByZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBDb252ZXJ0cyBhbiBlbGVtZW50IHZhbHVlIHRvIGl0cyAiZHluYW1pYyBwcm94eSByZXR1cm4gZm9ybSIuCiAgICAgKiBSZXR1cm5zIGFuIGV4Y2VwdGlvbiBwcm94eSBvbiBzb21lIGVycm9ycywgYnV0IG1heSByZXR1cm4gbnVsbCBpZgogICAgICogYSB1c2VmdWwgZXhjZXB0aW9uIGNhbm5vdCBvciBzaG91bGQgbm90IGJlIGdlbmVyYXRlZCBhdCB0aGlzIHBvaW50LgogICAgICovCiAgICBwcml2YXRlIE9iamVjdCBnZW5lcmF0ZVZhbHVlKE1ldGhvZFN5bWJvbCBtZXRoLCBBdHRyaWJ1dGUgYXR0cikgewogICAgICAgIFZhbHVlVmlzaXRvciB2diA9IG5ldyBWYWx1ZVZpc2l0b3IobWV0aCk7CiAgICAgICAgcmV0dXJuIHZ2LmdldFZhbHVlKGF0dHIpOwogICAgfQoKCiAgICBwcml2YXRlIGNsYXNzIFZhbHVlVmlzaXRvciBpbXBsZW1lbnRzIEF0dHJpYnV0ZS5WaXNpdG9yIHsKCiAgICAgICAgcHJpdmF0ZSBNZXRob2RTeW1ib2wgbWV0aDsgICAgICAvLyBhbm5vdGF0aW9uIGVsZW1lbnQgYmVpbmcgdmlzaXRlZAogICAgICAgIHByaXZhdGUgQ2xhc3M8Pz4gcmV0dXJuQ2xhc3M7ICAgLy8gcmV0dXJuIHR5cGUgb2YgYW5ub3RhdGlvbiBlbGVtZW50CiAgICAgICAgcHJpdmF0ZSBPYmplY3QgdmFsdWU7ICAgICAgICAgICAvLyB2YWx1ZSBpbiAiZHluYW1pYyBwcm94eSByZXR1cm4gZm9ybSIKCiAgICAgICAgVmFsdWVWaXNpdG9yKE1ldGhvZFN5bWJvbCBtZXRoKSB7CiAgICAgICAgICAgIHRoaXMubWV0aCA9IG1ldGg7CiAgICAgICAgfQoKICAgICAgICBPYmplY3QgZ2V0VmFsdWUoQXR0cmlidXRlIGF0dHIpIHsKICAgICAgICAgICAgTWV0aG9kIG1ldGhvZDsgICAgICAgICAgICAgIC8vIHJ1bnRpbWUgbWV0aG9kIG9mIGFubm90YXRpb24gZWxlbWVudAogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgbWV0aG9kID0gYW5ub1R5cGUuZ2V0TWV0aG9kKG1ldGgubmFtZS50b1N0cmluZygpKTsKICAgICAgICAgICAgfSBjYXRjaCAoTm9TdWNoTWV0aG9kRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybkNsYXNzID0gbWV0aG9kLmdldFJldHVyblR5cGUoKTsKICAgICAgICAgICAgYXR0ci5hY2NlcHQodGhpcyk7CiAgICAgICAgICAgIGlmICghKHZhbHVlIGluc3RhbmNlb2YgRXhjZXB0aW9uUHJveHkpICYmCiAgICAgICAgICAgICAgICAhQW5ub3RhdGlvblR5cGUuaW52b2NhdGlvbkhhbmRsZXJSZXR1cm5UeXBlKHJldHVybkNsYXNzKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5pc0luc3RhbmNlKHZhbHVlKSkgewogICAgICAgICAgICAgICAgdHlwZU1pc21hdGNoKG1ldGhvZCwgYXR0cik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHZhbHVlOwogICAgICAgIH0KCgogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0Q29uc3RhbnQoQXR0cmlidXRlLkNvbnN0YW50IGMpIHsKICAgICAgICAgICAgdmFsdWUgPSBjLmdldFZhbHVlKCk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdENsYXNzKEF0dHJpYnV0ZS5DbGFzcyBjKSB7CiAgICAgICAgICAgIHZhbHVlID0gbmV3IE1pcnJvcmVkVHlwZUV4Y2VwdGlvblByb3h5KGMuY2xhc3NUeXBlKTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0QXJyYXkoQXR0cmlidXRlLkFycmF5IGEpIHsKICAgICAgICAgICAgTmFtZSBlbGVtTmFtZSA9ICgoQXJyYXlUeXBlKSBhLnR5cGUpLmVsZW10eXBlLnRzeW0uZ2V0UXVhbGlmaWVkTmFtZSgpOwoKICAgICAgICAgICAgaWYgKGVsZW1OYW1lLmVxdWFscyhlbGVtTmFtZS50YWJsZS5uYW1lcy5qYXZhX2xhbmdfQ2xhc3MpKSB7ICAgLy8gQ2xhc3NbXQogICAgICAgICAgICAgICAgLy8gQ29uc3RydWN0IGEgcHJveHkgZm9yIGEgTWlycm9yZWRUeXBlc0V4Y2VwdGlvbgogICAgICAgICAgICAgICAgTGlzdEJ1ZmZlcjxUeXBlTWlycm9yPiBlbGVtcyA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICAgICAgICAgIGZvciAoQXR0cmlidXRlIHZhbHVlIDogYS52YWx1ZXMpIHsKICAgICAgICAgICAgICAgICAgICBUeXBlIGVsZW0gPSAoKEF0dHJpYnV0ZS5DbGFzcykgdmFsdWUpLmNsYXNzVHlwZTsKICAgICAgICAgICAgICAgICAgICBlbGVtcy5hcHBlbmQoZWxlbSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB2YWx1ZSA9IG5ldyBNaXJyb3JlZFR5cGVzRXhjZXB0aW9uUHJveHkoZWxlbXMudG9MaXN0KCkpOwoKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGludCBsZW4gPSBhLnZhbHVlcy5sZW5ndGg7CiAgICAgICAgICAgICAgICBDbGFzczw/PiByZXR1cm5DbGFzc1NhdmVkID0gcmV0dXJuQ2xhc3M7CiAgICAgICAgICAgICAgICByZXR1cm5DbGFzcyA9IHJldHVybkNsYXNzLmdldENvbXBvbmVudFR5cGUoKTsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgT2JqZWN0IHJlcyA9IEFycmF5Lm5ld0luc3RhbmNlKHJldHVybkNsYXNzLCBsZW4pOwogICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICAgICAgYS52YWx1ZXNbaV0uYWNjZXB0KHRoaXMpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCB8fCB2YWx1ZSBpbnN0YW5jZW9mIEV4Y2VwdGlvblByb3h5KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFycmF5LnNldChyZXMsIGksIHZhbHVlKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlID0gbnVsbDsgICAgICAgLy8gaW5kaWNhdGVzIGEgdHlwZSBtaXNtYXRjaAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHZhbHVlID0gcmVzOwogICAgICAgICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgICAgICAgICByZXR1cm5DbGFzcyA9IHJldHVybkNsYXNzU2F2ZWQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW5jaGVja2VkIiwgInJhd3R5cGVzIn0pCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRFbnVtKEF0dHJpYnV0ZS5FbnVtIGUpIHsKICAgICAgICAgICAgaWYgKHJldHVybkNsYXNzLmlzRW51bSgpKSB7CiAgICAgICAgICAgICAgICBTdHJpbmcgY29uc3ROYW1lID0gZS52YWx1ZS50b1N0cmluZygpOwogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IEVudW0udmFsdWVPZigoQ2xhc3MpcmV0dXJuQ2xhc3MsIGNvbnN0TmFtZSk7CiAgICAgICAgICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZXgpIHsKICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IG5ldyBFbnVtQ29uc3RhbnROb3RQcmVzZW50RXhjZXB0aW9uUHJveHkoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoQ2xhc3M8RW51bTw/Pj4pIHJldHVybkNsYXNzLCBjb25zdE5hbWUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdmFsdWUgPSBudWxsOyAgIC8vIGluZGljYXRlcyBhIHR5cGUgbWlzbWF0Y2gKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRDb21wb3VuZChBdHRyaWJ1dGUuQ29tcG91bmQgYykgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgQ2xhc3M8PyBleHRlbmRzIEFubm90YXRpb24+IG5lc3RlZCA9CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuQ2xhc3MuYXNTdWJjbGFzcyhBbm5vdGF0aW9uLmNsYXNzKTsKICAgICAgICAgICAgICAgIHZhbHVlID0gZ2VuZXJhdGVBbm5vdGF0aW9uKGMsIG5lc3RlZCk7CiAgICAgICAgICAgIH0gY2F0Y2ggKENsYXNzQ2FzdEV4Y2VwdGlvbiBleCkgewogICAgICAgICAgICAgICAgdmFsdWUgPSBudWxsOyAgIC8vIGluZGljYXRlcyBhIHR5cGUgbWlzbWF0Y2gKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRFcnJvcihBdHRyaWJ1dGUuRXJyb3IgZSkgewogICAgICAgICAgICBpZiAoZSBpbnN0YW5jZW9mIEF0dHJpYnV0ZS5VbnJlc29sdmVkQ2xhc3MpCiAgICAgICAgICAgICAgICB2YWx1ZSA9IG5ldyBNaXJyb3JlZFR5cGVFeGNlcHRpb25Qcm94eSgoKEF0dHJpYnV0ZS5VbnJlc29sdmVkQ2xhc3MpZSkuY2xhc3NUeXBlKTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgdmFsdWUgPSBudWxsOyAgICAgICAvLyBpbmRpY2F0ZXMgYSB0eXBlIG1pc21hdGNoCiAgICAgICAgfQoKCiAgICAgICAgLyoqCiAgICAgICAgICogU2V0cyAidmFsdWUiIHRvIGFuIEV4Y2VwdGlvblByb3h5IGluZGljYXRpbmcgYSB0eXBlIG1pc21hdGNoLgogICAgICAgICAqLwogICAgICAgIHByaXZhdGUgdm9pZCB0eXBlTWlzbWF0Y2goTWV0aG9kIG1ldGhvZCwgZmluYWwgQXR0cmlidXRlIGF0dHIpIHsKICAgICAgICAgICAgY2xhc3MgQW5ub3RhdGlvblR5cGVNaXNtYXRjaEV4Y2VwdGlvblByb3h5IGV4dGVuZHMgRXhjZXB0aW9uUHJveHkgewogICAgICAgICAgICAgICAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDI2OTsKICAgICAgICAgICAgICAgIHRyYW5zaWVudCBmaW5hbCBNZXRob2QgbWV0aG9kOwogICAgICAgICAgICAgICAgQW5ub3RhdGlvblR5cGVNaXNtYXRjaEV4Y2VwdGlvblByb3h5KE1ldGhvZCBtZXRob2QpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLm1ldGhvZCA9IG1ldGhvZDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICI8ZXJyb3I+IjsgICAvLyBlZzogIEBBbm5vKHZhbHVlPTxlcnJvcj4pCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBwcm90ZWN0ZWQgUnVudGltZUV4Y2VwdGlvbiBnZW5lcmF0ZUV4Y2VwdGlvbigpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEFubm90YXRpb25UeXBlTWlzbWF0Y2hFeGNlcHRpb24obWV0aG9kLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHIudHlwZS50b1N0cmluZygpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICB2YWx1ZSA9IG5ldyBBbm5vdGF0aW9uVHlwZU1pc21hdGNoRXhjZXB0aW9uUHJveHkobWV0aG9kKTsKICAgICAgICB9CiAgICB9CgoKICAgIC8qKgogICAgICogRXhjZXB0aW9uUHJveHkgZm9yIE1pcnJvcmVkVHlwZUV4Y2VwdGlvbi4KICAgICAqIFRoZSB0b1N0cmluZywgaGFzaENvZGUsIGFuZCBlcXVhbHMgbWV0aG9kcyBmb3J3YXJkIHRvIHRoZSB1bmRlcmx5aW5nCiAgICAgKiB0eXBlLgogICAgICovCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBNaXJyb3JlZFR5cGVFeGNlcHRpb25Qcm94eSBleHRlbmRzIEV4Y2VwdGlvblByb3h5IHsKICAgICAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMjY5OwoKICAgICAgICBwcml2YXRlIHRyYW5zaWVudCBUeXBlTWlycm9yIHR5cGU7CiAgICAgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgdHlwZVN0cmluZzsKCiAgICAgICAgTWlycm9yZWRUeXBlRXhjZXB0aW9uUHJveHkoVHlwZU1pcnJvciB0KSB7CiAgICAgICAgICAgIHR5cGUgPSB0OwogICAgICAgICAgICB0eXBlU3RyaW5nID0gdC50b1N0cmluZygpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKICAgICAgICAgICAgcmV0dXJuIHR5cGVTdHJpbmc7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICAgICAgICByZXR1cm4gKHR5cGUgIT0gbnVsbCA/IHR5cGUgOiB0eXBlU3RyaW5nKS5oYXNoQ29kZSgpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmopIHsKICAgICAgICAgICAgcmV0dXJuIHR5cGUgIT0gbnVsbCAmJgogICAgICAgICAgICAgICAgICAgb2JqIGluc3RhbmNlb2YgTWlycm9yZWRUeXBlRXhjZXB0aW9uUHJveHkgJiYKICAgICAgICAgICAgICAgICAgIHR5cGUuZXF1YWxzKCgoTWlycm9yZWRUeXBlRXhjZXB0aW9uUHJveHkpIG9iaikudHlwZSk7CiAgICAgICAgfQoKICAgICAgICBwcm90ZWN0ZWQgUnVudGltZUV4Y2VwdGlvbiBnZW5lcmF0ZUV4Y2VwdGlvbigpIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyBNaXJyb3JlZFR5cGVFeGNlcHRpb24odHlwZSk7CiAgICAgICAgfQoKICAgICAgICAvLyBFeHBsaWNpdGx5IHNldCBhbGwgdHJhbnNpZW50IGZpZWxkcy4KICAgICAgICBwcml2YXRlIHZvaWQgcmVhZE9iamVjdChPYmplY3RJbnB1dFN0cmVhbSBzKQogICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIENsYXNzTm90Rm91bmRFeGNlcHRpb24gewogICAgICAgICAgICBzLmRlZmF1bHRSZWFkT2JqZWN0KCk7CiAgICAgICAgICAgIHR5cGUgPSBudWxsOwogICAgICAgIH0KICAgIH0KCgogICAgLyoqCiAgICAgKiBFeGNlcHRpb25Qcm94eSBmb3IgTWlycm9yZWRUeXBlc0V4Y2VwdGlvbi4KICAgICAqIFRoZSB0b1N0cmluZywgaGFzaENvZGUsIGFuZCBlcXVhbHMgbWV0aG9kcyBmb3dhcmQgdG8gdGhlIHVuZGVybHlpbmcKICAgICAqIHR5cGVzLgogICAgICovCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBNaXJyb3JlZFR5cGVzRXhjZXB0aW9uUHJveHkgZXh0ZW5kcyBFeGNlcHRpb25Qcm94eSB7CiAgICAgICAgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDI2OTsKCiAgICAgICAgcHJpdmF0ZSB0cmFuc2llbnQgTGlzdDxUeXBlTWlycm9yPiB0eXBlczsKICAgICAgICBwcml2YXRlIGZpbmFsIFN0cmluZyB0eXBlU3RyaW5nczsKCiAgICAgICAgTWlycm9yZWRUeXBlc0V4Y2VwdGlvblByb3h5KExpc3Q8VHlwZU1pcnJvcj4gdHMpIHsKICAgICAgICAgICAgdHlwZXMgPSB0czsKICAgICAgICAgICAgdHlwZVN0cmluZ3MgPSB0cy50b1N0cmluZygpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKICAgICAgICAgICAgcmV0dXJuIHR5cGVTdHJpbmdzOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgICAgICAgcmV0dXJuICh0eXBlcyAhPSBudWxsID8gdHlwZXMgOiB0eXBlU3RyaW5ncykuaGFzaENvZGUoKTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqKSB7CiAgICAgICAgICAgIHJldHVybiB0eXBlcyAhPSBudWxsICYmCiAgICAgICAgICAgICAgICAgICBvYmogaW5zdGFuY2VvZiBNaXJyb3JlZFR5cGVzRXhjZXB0aW9uUHJveHkgJiYKICAgICAgICAgICAgICAgICAgIHR5cGVzLmVxdWFscygKICAgICAgICAgICAgICAgICAgICAgICgoTWlycm9yZWRUeXBlc0V4Y2VwdGlvblByb3h5KSBvYmopLnR5cGVzKTsKICAgICAgICB9CgogICAgICAgIHByb3RlY3RlZCBSdW50aW1lRXhjZXB0aW9uIGdlbmVyYXRlRXhjZXB0aW9uKCkgewogICAgICAgICAgICByZXR1cm4gbmV3IE1pcnJvcmVkVHlwZXNFeGNlcHRpb24odHlwZXMpOwogICAgICAgIH0KCiAgICAgICAgLy8gRXhwbGljaXRseSBzZXQgYWxsIHRyYW5zaWVudCBmaWVsZHMuCiAgICAgICAgcHJpdmF0ZSB2b2lkIHJlYWRPYmplY3QoT2JqZWN0SW5wdXRTdHJlYW0gcykKICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBDbGFzc05vdEZvdW5kRXhjZXB0aW9uIHsKICAgICAgICAgICAgcy5kZWZhdWx0UmVhZE9iamVjdCgpOwogICAgICAgICAgICB0eXBlcyA9IG51bGw7CiAgICAgICAgfQogICAgfQp9ClBLAwQKAAAIAAAGO6lKyWdmz9ILAADSCwAAMQAAAGNvbS9zdW4vdG9vbHMvamF2YWMvbW9kZWwvRmlsdGVyZWRNZW1iZXJMaXN0LmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMTQsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhYy5tb2RlbDsKCmltcG9ydCBqYXZhLnV0aWwuQWJzdHJhY3RMaXN0OwppbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlNjb3BlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlN5bWJvbDsKCmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuRmlsdGVyOwppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5GbGFncy4qOwppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5TY29wZS5Mb29rdXBLaW5kLk5PTl9SRUNVUlNJVkU7CgovKioKICogVXRpbGl0eSB0byBjb25zdHJ1Y3QgYSB2aWV3IG9mIGEgc3ltYm9sJ3MgbWVtYmVycywKICogZmlsdGVyaW5nIG91dCB1bndhbnRlZCBlbGVtZW50cyBzdWNoIGFzIHN5bnRoZXRpYyBvbmVzLgogKiBUaGlzIHZpZXcgaXMgbW9zdCBlZmZpY2llbnRseSBhY2Nlc3NlZCB0aHJvdWdoIGl0cyBpdGVyYXRvcigpIG1ldGhvZC4KICoKICogPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93biByaXNrLgogKiBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogKiBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+CiAqLwpwdWJsaWMgY2xhc3MgRmlsdGVyZWRNZW1iZXJMaXN0IGV4dGVuZHMgQWJzdHJhY3RMaXN0PFN5bWJvbD4gewoKICAgIHByaXZhdGUgZmluYWwgU2NvcGUgc2NvcGU7CgogICAgcHVibGljIEZpbHRlcmVkTWVtYmVyTGlzdChTY29wZSBzY29wZSkgewogICAgICAgIHRoaXMuc2NvcGUgPSBzY29wZTsKICAgIH0KCiAgICBwdWJsaWMgaW50IHNpemUoKSB7CiAgICAgICAgaW50IGNudCA9IDA7CiAgICAgICAgZm9yIChTeW1ib2wgc3ltIDogc2NvcGUuZ2V0U3ltYm9scyhOT05fUkVDVVJTSVZFKSkgewogICAgICAgICAgICBpZiAoIXVud2FudGVkKHN5bSkpCiAgICAgICAgICAgICAgICBjbnQrKzsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGNudDsKICAgIH0KCiAgICBwdWJsaWMgU3ltYm9sIGdldChpbnQgaW5kZXgpIHsKICAgICAgICBmb3IgKFN5bWJvbCBzeW0gOiBzY29wZS5nZXRTeW1ib2xzKE5PTl9SRUNVUlNJVkUpKSB7CiAgICAgICAgICAgIGlmICghdW53YW50ZWQoc3ltKSAmJiAoaW5kZXgtLSA9PSAwKSkKICAgICAgICAgICAgICAgIHJldHVybiBzeW07CiAgICAgICAgfQogICAgICAgIHRocm93IG5ldyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKCk7CiAgICB9CgogICAgLy8gQSBtb3JlIGVmZmljaWVudCBpbXBsZW1lbnRhdGlvbiB0aGFuIEFic3RyYWN0TGlzdCdzLgogICAgcHVibGljIEl0ZXJhdG9yPFN5bWJvbD4gaXRlcmF0b3IoKSB7CiAgICAgICAgcmV0dXJuIHNjb3BlLmdldFN5bWJvbHModCAtPiAhdW53YW50ZWQodCksIE5PTl9SRUNVUlNJVkUpLml0ZXJhdG9yKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBUZXN0cyB3aGV0aGVyIHRoaXMgaXMgYSBzeW1ib2wgdGhhdCBzaG91bGQgbmV2ZXIgYmUgc2VlbiBieQogICAgICogY2xpZW50cywgc3VjaCBhcyBhIHN5bnRoZXRpYyBjbGFzcy4gIFJldHVybnMgdHJ1ZSBmb3IgbnVsbC4KICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiB1bndhbnRlZChTeW1ib2wgcykgewogICAgICAgIHJldHVybiBzID09IG51bGwgIHx8ICAocy5mbGFncygpICYgU1lOVEhFVElDKSAhPSAwOwogICAgfQp9ClBLAwQKAAAIAACuPKlKAAAAAAAAAAAAAAAAGQAAAGNvbS9zdW4vdG9vbHMvamF2YWMvY29kZS9QSwMECgAACAAABjupSr0xtSM+IgAAPiIAACwAAABjb20vc3VuL3Rvb2xzL2phdmFjL2NvZGUvU3ltYm9sTWV0YWRhdGEuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAxMiwgMjAxMywgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGU7CgoKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5BdHRyaWJ1dGUuVHlwZUNvbXBvdW5kOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLktpbmRzLktpbmQ7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuQXNzZXJ0OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkxpc3Q7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuTGlzdEJ1ZmZlcjsKCi8qKgogKiBDb250YWluZXIgZm9yIGFsbCBhbm5vdGF0aW9ucyAoYXR0cmlidXRlcyBpbiBqYXZhYykgb24gYSBTeW1ib2wuCiAqCiAqIFRoaXMgY2xhc3MgaXMgZXhwbGljaXRseSBtdXRhYmxlLiBJdHMgY29udGVudHMgd2lsbCBjaGFuZ2Ugd2hlbiBhdHRyaWJ1dGVzCiAqIGFyZSBhbm5vdGF0ZWQgb250byB0aGUgU3ltYm9sLiBIb3dldmVyIHRoaXMgY2xhc3MgZGVwZW5kcyBvbiB0aGUgZmFjdHMgdGhhdAogKiBMaXN0IChpbiBqYXZhYykgaXMgaW1tdXRhYmxlLgogKgogKiBBbiBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzIGNhbiBiZSBpbiBvbmUgb2YgdGhyZWUgc3RhdGVzOgogKgogKiBOT1RfU1RBUlRFRCBpbmRpY2F0ZXMgdGhhdCB0aGUgU3ltYm9sIHRoaXMgaW5zdGFuY2UgYmVsb25ncyB0byBoYXMgbm90IGJlZW4KICogYW5ub3RhdGVkICh5ZXQpLiBTcGVjaWZpY2FsbHkgaWYgdGhlIGRlY2xhcmF0aW9uIGlzIG5vdCBhbm5vdGF0ZWQgdGhpcwogKiBpbnN0YW5jZSB3aWxsIG5ldmVyIG1vdmUgcGFzdCBOT1RfU1RBUlRFRC4gWW91IGNhbiBuZXZlciBnbyBiYWNrIHRvCiAqIE5PVF9TVEFSVEVELgogKgogKiBJTl9QUk9HUkVTUyBhbm5vdGF0aW9ucyBoYXZlIGJlZW4gZm91bmQgb24gdGhlIGRlY2xhcmF0aW9uLiBXaWxsIGJlIHByb2Nlc3NlZAogKiBsYXRlci4gWW91IGNhbiByZXNldCB0byBJTl9QUk9HUkVTUy4gV2hpbGUgSU5fUFJPR1JFU1MgeW91IGNhbiBzZXQgdGhlIGxpc3QKICogb2YgYXR0cmlidXRlcyAoYW5kIHRoaXMgbW92ZXMgb3V0IG9mIHRoZSBJTl9QUk9HUkVTUyBzdGF0ZSkuCiAqCiAqICJ1bm5hbWVkIiB0aGlzIFN5bWJvbE1ldGFkYXRhIGNvbnRhaW5zIHNvbWUgYXR0cmlidXRlcywgcG9zc2libHkgdGhlIGZpbmFsIHNldC4KICogV2hpbGUgaW4gdGhpcyBzdGF0ZSB5b3UgY2FuIG9ubHkgcHJlcGVuZCBvciBhcHBlbmQgdG8gdGhlIGF0dHJpYnV0ZXMgbm90IHNldAogKiBpdCBkaXJlY3RseS4gWW91IGNhbiBhbHNvIG1vdmUgYmFjayB0byB0aGUgSU5fUFJPR1JFU1Mgc3RhdGUgdXNpbmcgcmVzZXQoKS4KICoKICogPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4gSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzCiAqIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93biByaXNrLiBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzCiAqIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvciBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+CiAqLwpwdWJsaWMgY2xhc3MgU3ltYm9sTWV0YWRhdGEgewoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIExpc3Q8QXR0cmlidXRlLkNvbXBvdW5kPiBERUNMX05PVF9TVEFSVEVEID0gTGlzdC5vZihudWxsKTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIExpc3Q8QXR0cmlidXRlLkNvbXBvdW5kPiBERUNMX0lOX1BST0dSRVNTID0gTGlzdC5vZihudWxsKTsKCiAgICAvKgogICAgICogVGhpcyBmaWVsZCBzaG91bGQgbmV2ZXIgYmUgbnVsbAogICAgICovCiAgICBwcml2YXRlIExpc3Q8QXR0cmlidXRlLkNvbXBvdW5kPiBhdHRyaWJ1dGVzID0gREVDTF9OT1RfU1RBUlRFRDsKCiAgICAvKgogICAgICogVHlwZSBhdHRyaWJ1dGVzIGZvciB0aGlzIHN5bWJvbC4KICAgICAqIFRoaXMgZmllbGQgc2hvdWxkIG5ldmVyIGJlIG51bGwuCiAgICAgKi8KICAgIHByaXZhdGUgTGlzdDxBdHRyaWJ1dGUuVHlwZUNvbXBvdW5kPiB0eXBlX2F0dHJpYnV0ZXMgPSBMaXN0Lm5pbCgpOwoKICAgIC8qCiAgICAgKiBUeXBlIGF0dHJpYnV0ZXMgb2YgaW5pdGlhbGl6ZXJzIGluIHRoaXMgY2xhc3MuCiAgICAgKiBVbnVzZWQgaWYgdGhlIGN1cnJlbnQgc3ltYm9sIGlzIG5vdCBhIENsYXNzU3ltYm9sLgogICAgICovCiAgICBwcml2YXRlIExpc3Q8QXR0cmlidXRlLlR5cGVDb21wb3VuZD4gaW5pdF90eXBlX2F0dHJpYnV0ZXMgPSBMaXN0Lm5pbCgpOwoKICAgIC8qCiAgICAgKiBUeXBlIGF0dHJpYnV0ZXMgb2YgY2xhc3MgaW5pdGlhbGl6ZXJzIGluIHRoaXMgY2xhc3MuCiAgICAgKiBVbnVzZWQgaWYgdGhlIGN1cnJlbnQgc3ltYm9sIGlzIG5vdCBhIENsYXNzU3ltYm9sLgogICAgICovCiAgICBwcml2YXRlIExpc3Q8QXR0cmlidXRlLlR5cGVDb21wb3VuZD4gY2xpbml0X3R5cGVfYXR0cmlidXRlcyA9IExpc3QubmlsKCk7CgogICAgLyoKICAgICAqIFRoZSBTeW1ib2wgdGhpcyBTeW1ib2xNZXRhZGF0YSBpbnN0YW5jZSBiZWxvbmdzIHRvCiAgICAgKi8KICAgIHByaXZhdGUgZmluYWwgU3ltYm9sIHN5bTsKCiAgICBwdWJsaWMgU3ltYm9sTWV0YWRhdGEoU3ltYm9sIHN5bSkgewogICAgICAgIHRoaXMuc3ltID0gc3ltOwogICAgfQoKICAgIHB1YmxpYyBMaXN0PEF0dHJpYnV0ZS5Db21wb3VuZD4gZ2V0RGVjbGFyYXRpb25BdHRyaWJ1dGVzKCkgewogICAgICAgIHJldHVybiBmaWx0ZXJEZWNsU2VudGluZWxzKGF0dHJpYnV0ZXMpOwogICAgfQoKICAgIHB1YmxpYyBMaXN0PEF0dHJpYnV0ZS5UeXBlQ29tcG91bmQ+IGdldFR5cGVBdHRyaWJ1dGVzKCkgewogICAgICAgIHJldHVybiB0eXBlX2F0dHJpYnV0ZXM7CiAgICB9CgogICAgcHVibGljIExpc3Q8QXR0cmlidXRlLlR5cGVDb21wb3VuZD4gZ2V0SW5pdFR5cGVBdHRyaWJ1dGVzKCkgewogICAgICAgIHJldHVybiBpbml0X3R5cGVfYXR0cmlidXRlczsKICAgIH0KCiAgICBwdWJsaWMgTGlzdDxBdHRyaWJ1dGUuVHlwZUNvbXBvdW5kPiBnZXRDbGFzc0luaXRUeXBlQXR0cmlidXRlcygpIHsKICAgICAgICByZXR1cm4gY2xpbml0X3R5cGVfYXR0cmlidXRlczsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCBzZXREZWNsYXJhdGlvbkF0dHJpYnV0ZXMoTGlzdDxBdHRyaWJ1dGUuQ29tcG91bmQ+IGEpIHsKICAgICAgICBBc3NlcnQuY2hlY2socGVuZGluZ0NvbXBsZXRpb24oKSB8fCAhaXNTdGFydGVkKCkpOwogICAgICAgIGlmIChhID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGF0dHJpYnV0ZXMgPSBhOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHNldFR5cGVBdHRyaWJ1dGVzKExpc3Q8QXR0cmlidXRlLlR5cGVDb21wb3VuZD4gYSkgewogICAgICAgIGlmIChhID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHR5cGVfYXR0cmlidXRlcyA9IGE7CiAgICB9CgogICAgcHVibGljIHZvaWQgc2V0SW5pdFR5cGVBdHRyaWJ1dGVzKExpc3Q8QXR0cmlidXRlLlR5cGVDb21wb3VuZD4gYSkgewogICAgICAgIGlmIChhID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGluaXRfdHlwZV9hdHRyaWJ1dGVzID0gYTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCBzZXRDbGFzc0luaXRUeXBlQXR0cmlidXRlcyhMaXN0PEF0dHJpYnV0ZS5UeXBlQ29tcG91bmQ+IGEpIHsKICAgICAgICBpZiAoYSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBjbGluaXRfdHlwZV9hdHRyaWJ1dGVzID0gYTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCBzZXRBdHRyaWJ1dGVzKFN5bWJvbE1ldGFkYXRhIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHNldERlY2xhcmF0aW9uQXR0cmlidXRlcyhvdGhlci5nZXREZWNsYXJhdGlvbkF0dHJpYnV0ZXMoKSk7CiAgICAgICAgaWYgKChzeW0uZmxhZ3MoKSAmIEZsYWdzLkJSSURHRSkgIT0gMCkgewogICAgICAgICAgICBBc3NlcnQuY2hlY2sob3RoZXIuc3ltLmtpbmQgPT0gS2luZC5NVEgpOwogICAgICAgICAgICBMaXN0QnVmZmVyPFR5cGVDb21wb3VuZD4gdHlwZUF0dHJpYnV0ZXMgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgIGZvciAoVHlwZUNvbXBvdW5kIHRjIDogb3RoZXIuZ2V0VHlwZUF0dHJpYnV0ZXMoKSkgewogICAgICAgICAgICAgICAgLy8gQ2Fycnkgb3ZlciBvbmx5IGNvbnRyYWN0dWFsIHR5cGUgYW5ub3RhdGlvbnM6IGkuZSBub3RoaW5nIGludGVyaW9yIHRvIG1ldGhvZCBib2R5LgogICAgICAgICAgICAgICAgaWYgKCF0Yy5wb3NpdGlvbi50eXBlLmlzTG9jYWwoKSkKICAgICAgICAgICAgICAgICAgICB0eXBlQXR0cmlidXRlcy5hcHBlbmQodGMpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHNldFR5cGVBdHRyaWJ1dGVzKHR5cGVBdHRyaWJ1dGVzLnRvTGlzdCgpKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzZXRUeXBlQXR0cmlidXRlcyhvdGhlci5nZXRUeXBlQXR0cmlidXRlcygpKTsKICAgICAgICB9CiAgICAgICAgaWYgKHN5bS5raW5kID09IEtpbmQuVFlQKSB7CiAgICAgICAgICAgIHNldEluaXRUeXBlQXR0cmlidXRlcyhvdGhlci5nZXRJbml0VHlwZUF0dHJpYnV0ZXMoKSk7CiAgICAgICAgICAgIHNldENsYXNzSW5pdFR5cGVBdHRyaWJ1dGVzKG90aGVyLmdldENsYXNzSW5pdFR5cGVBdHRyaWJ1dGVzKCkpOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgU3ltYm9sTWV0YWRhdGEgcmVzZXQoKSB7CiAgICAgICAgYXR0cmlidXRlcyA9IERFQ0xfSU5fUFJPR1JFU1M7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CgogICAgcHVibGljIGJvb2xlYW4gaXNFbXB0eSgpIHsKICAgICAgICByZXR1cm4gIWlzU3RhcnRlZCgpCiAgICAgICAgICAgICAgICB8fCBwZW5kaW5nQ29tcGxldGlvbigpCiAgICAgICAgICAgICAgICB8fCBhdHRyaWJ1dGVzLmlzRW1wdHkoKTsKICAgIH0KCiAgICBwdWJsaWMgYm9vbGVhbiBpc1R5cGVzRW1wdHkoKSB7CiAgICAgICAgcmV0dXJuIHR5cGVfYXR0cmlidXRlcy5pc0VtcHR5KCk7CiAgICB9CgogICAgcHVibGljIGJvb2xlYW4gcGVuZGluZ0NvbXBsZXRpb24oKSB7CiAgICAgICAgcmV0dXJuIGF0dHJpYnV0ZXMgPT0gREVDTF9JTl9QUk9HUkVTUzsKICAgIH0KCiAgICBwdWJsaWMgU3ltYm9sTWV0YWRhdGEgYXBwZW5kKExpc3Q8QXR0cmlidXRlLkNvbXBvdW5kPiBsKSB7CiAgICAgICAgYXR0cmlidXRlcyA9IGZpbHRlckRlY2xTZW50aW5lbHMoYXR0cmlidXRlcyk7CgogICAgICAgIGlmIChsLmlzRW1wdHkoKSkgewogICAgICAgICAgICAvLyBuby1vcAogICAgICAgIH0gZWxzZSBpZiAoYXR0cmlidXRlcy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgYXR0cmlidXRlcyA9IGw7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgYXR0cmlidXRlcyA9IGF0dHJpYnV0ZXMuYXBwZW5kTGlzdChsKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CgogICAgcHVibGljIFN5bWJvbE1ldGFkYXRhIGFwcGVuZFVuaXF1ZVR5cGVzKExpc3Q8QXR0cmlidXRlLlR5cGVDb21wb3VuZD4gbCkgewogICAgICAgIGlmIChsLmlzRW1wdHkoKSkgewogICAgICAgICAgICAvLyBuby1vcAogICAgICAgIH0gZWxzZSBpZiAodHlwZV9hdHRyaWJ1dGVzLmlzRW1wdHkoKSkgewogICAgICAgICAgICB0eXBlX2F0dHJpYnV0ZXMgPSBsOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8vIFRPRE86IGluIGNhc2Ugd2UgZXhwZWN0IGEgbGFyZ2UgbnVtYmVyIG9mIGFubm90YXRpb25zLCB0aGlzCiAgICAgICAgICAgIC8vIG1pZ2h0IGJlIGluZWZmaWNpZW50LgogICAgICAgICAgICBmb3IgKEF0dHJpYnV0ZS5UeXBlQ29tcG91bmQgdGMgOiBsKSB7CiAgICAgICAgICAgICAgICBpZiAoIXR5cGVfYXR0cmlidXRlcy5jb250YWlucyh0YykpCiAgICAgICAgICAgICAgICAgICAgdHlwZV9hdHRyaWJ1dGVzID0gdHlwZV9hdHRyaWJ1dGVzLmFwcGVuZCh0Yyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CgogICAgcHVibGljIFN5bWJvbE1ldGFkYXRhIGFwcGVuZEluaXRUeXBlQXR0cmlidXRlcyhMaXN0PEF0dHJpYnV0ZS5UeXBlQ29tcG91bmQ+IGwpIHsKICAgICAgICBpZiAobC5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgLy8gbm8tb3AKICAgICAgICB9IGVsc2UgaWYgKGluaXRfdHlwZV9hdHRyaWJ1dGVzLmlzRW1wdHkoKSkgewogICAgICAgICAgICBpbml0X3R5cGVfYXR0cmlidXRlcyA9IGw7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgaW5pdF90eXBlX2F0dHJpYnV0ZXMgPSBpbml0X3R5cGVfYXR0cmlidXRlcy5hcHBlbmRMaXN0KGwpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgIH0KCiAgICBwdWJsaWMgU3ltYm9sTWV0YWRhdGEgYXBwZW5kQ2xhc3NJbml0VHlwZUF0dHJpYnV0ZXMoTGlzdDxBdHRyaWJ1dGUuVHlwZUNvbXBvdW5kPiBsKSB7CiAgICAgICAgaWYgKGwuaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIC8vIG5vLW9wCiAgICAgICAgfSBlbHNlIGlmIChjbGluaXRfdHlwZV9hdHRyaWJ1dGVzLmlzRW1wdHkoKSkgewogICAgICAgICAgICBjbGluaXRfdHlwZV9hdHRyaWJ1dGVzID0gbDsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBjbGluaXRfdHlwZV9hdHRyaWJ1dGVzID0gY2xpbml0X3R5cGVfYXR0cmlidXRlcy5hcHBlbmRMaXN0KGwpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgIH0KCiAgICBwdWJsaWMgU3ltYm9sTWV0YWRhdGEgcHJlcGVuZChMaXN0PEF0dHJpYnV0ZS5Db21wb3VuZD4gbCkgewogICAgICAgIGF0dHJpYnV0ZXMgPSBmaWx0ZXJEZWNsU2VudGluZWxzKGF0dHJpYnV0ZXMpOwoKICAgICAgICBpZiAobC5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgLy8gbm8tb3AKICAgICAgICB9IGVsc2UgaWYgKGF0dHJpYnV0ZXMuaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGF0dHJpYnV0ZXMgPSBsOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGF0dHJpYnV0ZXMgPSBhdHRyaWJ1dGVzLnByZXBlbmRMaXN0KGwpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgIH0KCiAgICBwcml2YXRlIExpc3Q8QXR0cmlidXRlLkNvbXBvdW5kPiBmaWx0ZXJEZWNsU2VudGluZWxzKExpc3Q8QXR0cmlidXRlLkNvbXBvdW5kPiBhKSB7CiAgICAgICAgcmV0dXJuIChhID09IERFQ0xfSU5fUFJPR1JFU1MgfHwgYSA9PSBERUNMX05PVF9TVEFSVEVEKQogICAgICAgICAgICAgICAgPyBMaXN0Lm5pbCgpCiAgICAgICAgICAgICAgICA6IGE7CiAgICB9CgogICAgcHJpdmF0ZSBib29sZWFuIGlzU3RhcnRlZCgpIHsKICAgICAgICByZXR1cm4gYXR0cmlidXRlcyAhPSBERUNMX05PVF9TVEFSVEVEOwogICAgfQp9ClBLAwQKAAAIAAAGO6lKj4Vc1SECAQAhAgEALQAAAGNvbS9zdW4vdG9vbHMvamF2YWMvY29kZS9UeXBlQW5ub3RhdGlvbnMuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwOSwgMjAxNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGU7CgppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5lbGVtZW50LkVsZW1lbnQ7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuRWxlbWVudEtpbmQ7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLnR5cGUuVHlwZUtpbmQ7CmltcG9ydCBqYXZheC50b29scy5KYXZhRmlsZU9iamVjdDsKCmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuQXR0cmlidXRlLkFycmF5OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLkF0dHJpYnV0ZS5UeXBlQ29tcG91bmQ7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuU3ltYm9sLkNsYXNzU3ltYm9sOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlN5bWJvbC5UeXBlU3ltYm9sOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlR5cGUuQXJyYXlUeXBlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlR5cGUuQ2FwdHVyZWRUeXBlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlR5cGUuQ2xhc3NUeXBlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlR5cGUuRXJyb3JUeXBlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlR5cGUuRm9yQWxsOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlR5cGUuTWV0aG9kVHlwZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5UeXBlLlBhY2thZ2VUeXBlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlR5cGUuVHlwZVZhcjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5UeXBlLlVuZGV0VmFyOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlR5cGUuVmlzaXRvcjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5UeXBlLldpbGRjYXJkVHlwZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5UeXBlQW5ub3RhdGlvblBvc2l0aW9uLlR5cGVQYXRoRW50cnk7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuVHlwZUFubm90YXRpb25Qb3NpdGlvbi5UeXBlUGF0aEVudHJ5S2luZDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5TeW1ib2wuVmFyU3ltYm9sOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlN5bWJvbC5NZXRob2RTeW1ib2w7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuVHlwZS5Nb2R1bGVUeXBlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlR5cGVNZXRhZGF0YS5FbnRyeS5LaW5kOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb21wLkFubm90YXRlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb21wLkF0dHI7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvbXAuQXR0ckNvbnRleHQ7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvbXAuRW52OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkpDVHJlZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5UcmVlSW5mbzsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5KQ1RyZWUuSkNCbG9jazsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5KQ1RyZWUuSkNDbGFzc0RlY2w7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuSkNUcmVlLkpDRXhwcmVzc2lvbjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5KQ1RyZWUuSkNMYW1iZGE7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuSkNUcmVlLkpDTWV0aG9kRGVjbDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5KQ1RyZWUuSkNNZXRob2RJbnZvY2F0aW9uOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkpDVHJlZS5KQ05ld0NsYXNzOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkpDVHJlZS5KQ1R5cGVBcHBseTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5KQ1RyZWUuSkNWYXJpYWJsZURlY2w7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuVHJlZVNjYW5uZXI7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuSkNUcmVlLio7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuQXNzZXJ0OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkNvbnRleHQ7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuTGlzdDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5MaXN0QnVmZmVyOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkxvZzsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5OYW1lczsKCmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLktpbmRzLktpbmQuKjsKCi8qKgogKiBDb250YWlucyBvcGVyYXRpb25zIHNwZWNpZmljIHRvIHByb2Nlc3NpbmcgdHlwZSBhbm5vdGF0aW9ucy4KICogVGhpcyBjbGFzcyBoYXMgdHdvIGZ1bmN0aW9uczoKICogc2VwYXJhdGUgZGVjbGFyYXRpb24gZnJvbSB0eXBlIGFubm90YXRpb25zIGFuZCBpbnNlcnQgdGhlIHR5cGUKICogYW5ub3RhdGlvbnMgdG8gdGhlaXIgdHlwZXM7CiAqIGFuZCBkZXRlcm1pbmUgdGhlIFR5cGVBbm5vdGF0aW9uUG9zaXRpb25zIGZvciBhbGwgdHlwZSBhbm5vdGF0aW9ucy4KICovCnB1YmxpYyBjbGFzcyBUeXBlQW5ub3RhdGlvbnMgewogICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBDb250ZXh0LktleTxUeXBlQW5ub3RhdGlvbnM+IHR5cGVBbm5vc0tleSA9IG5ldyBDb250ZXh0LktleTw+KCk7CgogICAgcHVibGljIHN0YXRpYyBUeXBlQW5ub3RhdGlvbnMgaW5zdGFuY2UoQ29udGV4dCBjb250ZXh0KSB7CiAgICAgICAgVHlwZUFubm90YXRpb25zIGluc3RhbmNlID0gY29udGV4dC5nZXQodHlwZUFubm9zS2V5KTsKICAgICAgICBpZiAoaW5zdGFuY2UgPT0gbnVsbCkKICAgICAgICAgICAgaW5zdGFuY2UgPSBuZXcgVHlwZUFubm90YXRpb25zKGNvbnRleHQpOwogICAgICAgIHJldHVybiBpbnN0YW5jZTsKICAgIH0KCiAgICBmaW5hbCBMb2cgbG9nOwogICAgZmluYWwgTmFtZXMgbmFtZXM7CiAgICBmaW5hbCBTeW10YWIgc3ltczsKICAgIGZpbmFsIEFubm90YXRlIGFubm90YXRlOwogICAgZmluYWwgQXR0ciBhdHRyOwoKICAgIHByb3RlY3RlZCBUeXBlQW5ub3RhdGlvbnMoQ29udGV4dCBjb250ZXh0KSB7CiAgICAgICAgY29udGV4dC5wdXQodHlwZUFubm9zS2V5LCB0aGlzKTsKICAgICAgICBuYW1lcyA9IE5hbWVzLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIGxvZyA9IExvZy5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBzeW1zID0gU3ltdGFiLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIGFubm90YXRlID0gQW5ub3RhdGUuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgYXR0ciA9IEF0dHIuaW5zdGFuY2UoY29udGV4dCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXBhcmF0ZSB0eXBlIGFubm90YXRpb25zIGZyb20gZGVjbGFyYXRpb24gYW5ub3RhdGlvbnMgYW5kCiAgICAgKiBkZXRlcm1pbmUgdGhlIGNvcnJlY3QgcG9zaXRpb25zIGZvciB0eXBlIGFubm90YXRpb25zLgogICAgICogVGhpcyB2ZXJzaW9uIG9ubHkgdmlzaXRzIHR5cGVzIGluIHNpZ25hdHVyZXMgYW5kIHNob3VsZCBiZQogICAgICogY2FsbGVkIGZyb20gTWVtYmVyRW50ZXIuCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIG9yZ2FuaXplVHlwZUFubm90YXRpb25zU2lnbmF0dXJlcyhmaW5hbCBFbnY8QXR0ckNvbnRleHQ+IGVudiwgZmluYWwgSkNDbGFzc0RlY2wgdHJlZSkgewogICAgICAgIGFubm90YXRlLmFmdGVyVHlwZXMoKCkgLT4gewogICAgICAgICAgICBKYXZhRmlsZU9iamVjdCBvbGRTb3VyY2UgPSBsb2cudXNlU291cmNlKGVudi50b3BsZXZlbC5zb3VyY2VmaWxlKTsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIG5ldyBUeXBlQW5ub3RhdGlvblBvc2l0aW9ucyh0cnVlKS5zY2FuKHRyZWUpOwogICAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAgICAgbG9nLnVzZVNvdXJjZShvbGRTb3VyY2UpOwogICAgICAgICAgICB9CiAgICAgICAgfSk7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmFsaWRhdGVUeXBlQW5ub3RhdGlvbnNTaWduYXR1cmVzKGZpbmFsIEVudjxBdHRyQ29udGV4dD4gZW52LCBmaW5hbCBKQ0NsYXNzRGVjbCB0cmVlKSB7CiAgICAgICAgYW5ub3RhdGUudmFsaWRhdGUoKCkgLT4geyAvL3ZhbGlkYXRlIGFubm90YXRpb25zCiAgICAgICAgICAgIEphdmFGaWxlT2JqZWN0IG9sZFNvdXJjZSA9IGxvZy51c2VTb3VyY2UoZW52LnRvcGxldmVsLnNvdXJjZWZpbGUpOwogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgYXR0ci52YWxpZGF0ZVR5cGVBbm5vdGF0aW9ucyh0cmVlLCB0cnVlKTsKICAgICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgICAgIGxvZy51c2VTb3VyY2Uob2xkU291cmNlKTsKICAgICAgICAgICAgfQogICAgICAgIH0pOwogICAgfQoKICAgIC8qKgogICAgICogVGhpcyB2ZXJzaW9uIG9ubHkgdmlzaXRzIHR5cGVzIGluIGJvZGllcywgdGhhdCBpcywgZmllbGQgaW5pdGlhbGl6ZXJzLAogICAgICogdG9wLWxldmVsIGJsb2NrcywgYW5kIG1ldGhvZCBib2RpZXMsIGFuZCBzaG91bGQgYmUgY2FsbGVkIGZyb20gQXR0ci4KICAgICAqLwogICAgcHVibGljIHZvaWQgb3JnYW5pemVUeXBlQW5ub3RhdGlvbnNCb2RpZXMoSkNDbGFzc0RlY2wgdHJlZSkgewogICAgICAgIG5ldyBUeXBlQW5ub3RhdGlvblBvc2l0aW9ucyhmYWxzZSkuc2Nhbih0cmVlKTsKICAgIH0KCiAgICBwdWJsaWMgZW51bSBBbm5vdGF0aW9uVHlwZSB7IERFQ0xBUkFUSU9OLCBUWVBFLCBOT05FLCBCT1RIIH0KCiAgICBwdWJsaWMgTGlzdDxBdHRyaWJ1dGU+IGFubm90YXRpb25UYXJnZXRzKFR5cGVTeW1ib2wgdHN5bSkgewogICAgICAgIEF0dHJpYnV0ZS5Db21wb3VuZCBhdFRhcmdldCA9IHRzeW0uZ2V0QW5ub3RhdGlvblR5cGVNZXRhZGF0YSgpLmdldFRhcmdldCgpOwogICAgICAgIGlmIChhdFRhcmdldCA9PSBudWxsKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgQXR0cmlidXRlIGF0VmFsdWUgPSBhdFRhcmdldC5tZW1iZXIobmFtZXMudmFsdWUpOwogICAgICAgIGlmICghKGF0VmFsdWUgaW5zdGFuY2VvZiBBdHRyaWJ1dGUuQXJyYXkpKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgTGlzdDxBdHRyaWJ1dGU+IHRhcmdldHMgPSAoKEFycmF5KWF0VmFsdWUpLmdldFZhbHVlKCk7CiAgICAgICAgaWYgKHRhcmdldHMuc3RyZWFtKCkuYW55TWF0Y2goYSAtPiAhKGEgaW5zdGFuY2VvZiBBdHRyaWJ1dGUuRW51bSkpKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHRhcmdldHM7CiAgICB9CgogICAgLyoqCiAgICAgKiBEZXRlcm1pbmUgd2hldGhlciBhbiBhbm5vdGF0aW9uIGlzIGEgZGVjbGFyYXRpb24gYW5ub3RhdGlvbiwKICAgICAqIGEgdHlwZSBhbm5vdGF0aW9uLCBvciBib3RoLgogICAgICovCiAgICBwdWJsaWMgQW5ub3RhdGlvblR5cGUgYW5ub3RhdGlvblRhcmdldFR5cGUoQXR0cmlidXRlLkNvbXBvdW5kIGEsIFN5bWJvbCBzKSB7CiAgICAgICAgTGlzdDxBdHRyaWJ1dGU+IHRhcmdldHMgPSBhbm5vdGF0aW9uVGFyZ2V0cyhhLnR5cGUudHN5bSk7CiAgICAgICAgcmV0dXJuICh0YXJnZXRzID09IG51bGwpID8KICAgICAgICAgICAgICAgIEFubm90YXRpb25UeXBlLkRFQ0xBUkFUSU9OIDoKICAgICAgICAgICAgICAgIHRhcmdldHMuc3RyZWFtKCkKICAgICAgICAgICAgICAgICAgICAgICAgLm1hcChhdHRyIC0+IHRhcmdldFRvQW5ub3RhdGlvblR5cGUoYXR0ciwgcykpCiAgICAgICAgICAgICAgICAgICAgICAgIC5yZWR1Y2UoQW5ub3RhdGlvblR5cGUuTk9ORSwgdGhpczo6Y29tYmluZUFubm90YXRpb25UeXBlKTsKICAgIH0KCiAgICBwcml2YXRlIEFubm90YXRpb25UeXBlIGNvbWJpbmVBbm5vdGF0aW9uVHlwZShBbm5vdGF0aW9uVHlwZSBhdDEsIEFubm90YXRpb25UeXBlIGF0MikgewogICAgICAgIGlmIChhdDEgPT0gQW5ub3RhdGlvblR5cGUuTk9ORSkgewogICAgICAgICAgICByZXR1cm4gYXQyOwogICAgICAgIH0gZWxzZSBpZiAoYXQyID09IEFubm90YXRpb25UeXBlLk5PTkUpIHsKICAgICAgICAgICAgcmV0dXJuIGF0MTsKICAgICAgICB9IGVsc2UgaWYgKGF0MSAhPSBhdDIpIHsKICAgICAgICAgICAgcmV0dXJuIEFubm90YXRpb25UeXBlLkJPVEg7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIGF0MTsKICAgICAgICB9CiAgICB9CgogICAgcHJpdmF0ZSBBbm5vdGF0aW9uVHlwZSB0YXJnZXRUb0Fubm90YXRpb25UeXBlKEF0dHJpYnV0ZSBhLCBTeW1ib2wgcykgewogICAgICAgIEF0dHJpYnV0ZS5FbnVtIGUgPSAoQXR0cmlidXRlLkVudW0pYTsKICAgICAgICBpZiAoZS52YWx1ZS5uYW1lID09IG5hbWVzLlRZUEUpIHsKICAgICAgICAgICAgaWYgKHMua2luZCA9PSBUWVApCiAgICAgICAgICAgICAgICByZXR1cm4gQW5ub3RhdGlvblR5cGUuREVDTEFSQVRJT047CiAgICAgICAgfSBlbHNlIGlmIChlLnZhbHVlLm5hbWUgPT0gbmFtZXMuRklFTEQpIHsKICAgICAgICAgICAgaWYgKHMua2luZCA9PSBWQVIgJiYKICAgICAgICAgICAgICAgICAgICBzLm93bmVyLmtpbmQgIT0gTVRIKQogICAgICAgICAgICAgICAgcmV0dXJuIEFubm90YXRpb25UeXBlLkRFQ0xBUkFUSU9OOwogICAgICAgIH0gZWxzZSBpZiAoZS52YWx1ZS5uYW1lID09IG5hbWVzLk1FVEhPRCkgewogICAgICAgICAgICBpZiAocy5raW5kID09IE1USCAmJgogICAgICAgICAgICAgICAgICAgICFzLmlzQ29uc3RydWN0b3IoKSkKICAgICAgICAgICAgICAgIHJldHVybiBBbm5vdGF0aW9uVHlwZS5ERUNMQVJBVElPTjsKICAgICAgICB9IGVsc2UgaWYgKGUudmFsdWUubmFtZSA9PSBuYW1lcy5QQVJBTUVURVIpIHsKICAgICAgICAgICAgaWYgKHMua2luZCA9PSBWQVIgJiYKICAgICAgICAgICAgICAgICAgICBzLm93bmVyLmtpbmQgPT0gTVRIICYmCiAgICAgICAgICAgICAgICAgICAgKHMuZmxhZ3MoKSAmIEZsYWdzLlBBUkFNRVRFUikgIT0gMCkKICAgICAgICAgICAgICAgIHJldHVybiBBbm5vdGF0aW9uVHlwZS5ERUNMQVJBVElPTjsKICAgICAgICB9IGVsc2UgaWYgKGUudmFsdWUubmFtZSA9PSBuYW1lcy5DT05TVFJVQ1RPUikgewogICAgICAgICAgICBpZiAocy5raW5kID09IE1USCAmJgogICAgICAgICAgICAgICAgICAgIHMuaXNDb25zdHJ1Y3RvcigpKQogICAgICAgICAgICAgICAgcmV0dXJuIEFubm90YXRpb25UeXBlLkRFQ0xBUkFUSU9OOwogICAgICAgIH0gZWxzZSBpZiAoZS52YWx1ZS5uYW1lID09IG5hbWVzLkxPQ0FMX1ZBUklBQkxFKSB7CiAgICAgICAgICAgIGlmIChzLmtpbmQgPT0gVkFSICYmCiAgICAgICAgICAgICAgICAgICAgcy5vd25lci5raW5kID09IE1USCAmJgogICAgICAgICAgICAgICAgICAgIChzLmZsYWdzKCkgJiBGbGFncy5QQVJBTUVURVIpID09IDApCiAgICAgICAgICAgICAgICByZXR1cm4gQW5ub3RhdGlvblR5cGUuREVDTEFSQVRJT047CiAgICAgICAgfSBlbHNlIGlmIChlLnZhbHVlLm5hbWUgPT0gbmFtZXMuQU5OT1RBVElPTl9UWVBFKSB7CiAgICAgICAgICAgIGlmIChzLmtpbmQgPT0gVFlQICYmCiAgICAgICAgICAgICAgICAgICAgKHMuZmxhZ3MoKSAmIEZsYWdzLkFOTk9UQVRJT04pICE9IDApCiAgICAgICAgICAgICAgICByZXR1cm4gQW5ub3RhdGlvblR5cGUuREVDTEFSQVRJT047CiAgICAgICAgfSBlbHNlIGlmIChlLnZhbHVlLm5hbWUgPT0gbmFtZXMuUEFDS0FHRSkgewogICAgICAgICAgICBpZiAocy5raW5kID09IFBDSykKICAgICAgICAgICAgICAgIHJldHVybiBBbm5vdGF0aW9uVHlwZS5ERUNMQVJBVElPTjsKICAgICAgICB9IGVsc2UgaWYgKGUudmFsdWUubmFtZSA9PSBuYW1lcy5UWVBFX1VTRSkgewogICAgICAgICAgICBpZiAocy5raW5kID09IFRZUCB8fAogICAgICAgICAgICAgICAgICAgIHMua2luZCA9PSBWQVIgfHwKICAgICAgICAgICAgICAgICAgICAocy5raW5kID09IE1USCAmJiAhcy5pc0NvbnN0cnVjdG9yKCkgJiYKICAgICAgICAgICAgICAgICAgICAhcy50eXBlLmdldFJldHVyblR5cGUoKS5oYXNUYWcoVHlwZVRhZy5WT0lEKSkgfHwKICAgICAgICAgICAgICAgICAgICAocy5raW5kID09IE1USCAmJiBzLmlzQ29uc3RydWN0b3IoKSkpCiAgICAgICAgICAgICAgICByZXR1cm4gQW5ub3RhdGlvblR5cGUuVFlQRTsKICAgICAgICB9IGVsc2UgaWYgKGUudmFsdWUubmFtZSA9PSBuYW1lcy5UWVBFX1BBUkFNRVRFUikgewogICAgICAgICAgICAvKiBJcnJlbGV2YW50IGluIHRoaXMgY2FzZSAqLwogICAgICAgICAgICAvLyBUWVBFX1BBUkFNRVRFUiBkb2Vzbid0IGFpZCBpbiBkaXN0aW5ndWlzaGluZyBiZXR3ZWVuCiAgICAgICAgICAgIC8vIFR5cGUgYW5ub3RhdGlvbnMgYW5kIGRlY2xhcmF0aW9uIGFubm90YXRpb25zIG9uIGFuCiAgICAgICAgICAgIC8vIEVsZW1lbnQKICAgICAgICB9IGVsc2UgaWYgKGUudmFsdWUubmFtZSA9PSBuYW1lcy5NT0RVTEUpIHsKICAgICAgICAgICAgaWYgKHMua2luZCA9PSBNREwpCiAgICAgICAgICAgICAgICByZXR1cm4gQW5ub3RhdGlvblR5cGUuREVDTEFSQVRJT047CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgQXNzZXJ0LmVycm9yKCJhbm5vdGF0aW9uVGFyZ2V0VHlwZSgpOiB1bnJlY29nbml6ZWQgQXR0cmlidXRlIG5hbWUgIiArIGUudmFsdWUubmFtZSArCiAgICAgICAgICAgICAgICAgICAgIiAoIiArIGUudmFsdWUubmFtZS5nZXRDbGFzcygpICsgIikiKTsKICAgICAgICAgICAgcmV0dXJuIEFubm90YXRpb25UeXBlLkRFQ0xBUkFUSU9OOwogICAgICAgIH0KICAgICAgICByZXR1cm4gQW5ub3RhdGlvblR5cGUuTk9ORTsKICAgIH0KCiAgICBwcml2YXRlIGNsYXNzIFR5cGVBbm5vdGF0aW9uUG9zaXRpb25zIGV4dGVuZHMgVHJlZVNjYW5uZXIgewoKICAgICAgICBwcml2YXRlIGZpbmFsIGJvb2xlYW4gc2lnT25seTsKCiAgICAgICAgVHlwZUFubm90YXRpb25Qb3NpdGlvbnMoYm9vbGVhbiBzaWdPbmx5KSB7CiAgICAgICAgICAgIHRoaXMuc2lnT25seSA9IHNpZ09ubHk7CiAgICAgICAgfQoKICAgICAgICAvKgogICAgICAgICAqIFdoZW4gdHJhdmVyc2luZyB0aGUgQVNUIHdlIGtlZXAgdGhlICJmcmFtZXMiIG9mIHZpc2l0ZWQKICAgICAgICAgKiB0cmVlcyBpbiBvcmRlciB0byBkZXRlcm1pbmUgdGhlIHBvc2l0aW9uIG9mIGFubm90YXRpb25zLgogICAgICAgICAqLwogICAgICAgIHByaXZhdGUgTGlzdDxKQ1RyZWU+IGZyYW1lcyA9IExpc3QubmlsKCk7CgogICAgICAgIHByb3RlY3RlZCB2b2lkIHB1c2goSkNUcmVlIHQpIHsKICAgICAgICAgICAgZnJhbWVzID0gZnJhbWVzLnByZXBlbmQodCk7CiAgICAgICAgfQogICAgICAgIHByb3RlY3RlZCBKQ1RyZWUgcG9wKCkgewogICAgICAgICAgICBKQ1RyZWUgdCA9IGZyYW1lcy5oZWFkOwogICAgICAgICAgICBmcmFtZXMgPSBmcmFtZXMudGFpbDsKICAgICAgICAgICAgcmV0dXJuIHQ7CiAgICAgICAgICAgIH0KICAgICAgICAvLyBjb3VsZCB0aGlzIGJlIGZyYW1lcy5lbGVtcy50YWlsLmhlYWQ/CiAgICAgICAgcHJpdmF0ZSBKQ1RyZWUgcGVlazIoKSB7CiAgICAgICAgICAgIHJldHVybiBmcmFtZXMudGFpbC5oZWFkOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgc2NhbihKQ1RyZWUgdHJlZSkgewogICAgICAgICAgICBwdXNoKHRyZWUpOwogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgc3VwZXIuc2Nhbih0cmVlKTsKICAgICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgICAgIHBvcCgpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBTZXBhcmF0ZXMgdHlwZSBhbm5vdGF0aW9ucyBmcm9tIGRlY2xhcmF0aW9uIGFubm90YXRpb25zLgogICAgICAgICAqIFRoaXMgc3RlcCBpcyBuZWVkZWQgYmVjYXVzZSBpbiBjZXJ0YWluIGxvY2F0aW9ucyAod2hlcmUgZGVjbGFyYXRpb24KICAgICAgICAgKiBhbmQgdHlwZSBhbm5vdGF0aW9ucyBjYW4gYmUgbWl4ZWQsIGUuZy4gdGhlIHR5cGUgb2YgYSBmaWVsZCkKICAgICAgICAgKiB3ZSBuZXZlciBidWlsZCBhbiBKQ0Fubm90YXRlZFR5cGUuIFRoaXMgc3RlcCBmaW5kcyB0aGVzZQogICAgICAgICAqIGFubm90YXRpb25zIGFuZCBtYXJrcyB0aGVtIGFzIGlmIHRoZXkgd2VyZSBwYXJ0IG9mIHRoZSB0eXBlLgogICAgICAgICAqLwogICAgICAgIHByaXZhdGUgdm9pZCBzZXBhcmF0ZUFubm90YXRpb25zS2luZHMoSkNUcmVlIHR5cGV0cmVlLCBUeXBlIHR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTeW1ib2wgc3ltLCBUeXBlQW5ub3RhdGlvblBvc2l0aW9uIHBvcykKICAgICAgICB7CiAgICAgICAgICAgIExpc3Q8QXR0cmlidXRlLkNvbXBvdW5kPiBhbGxBbm5vdGF0aW9ucyA9IHN5bS5nZXRSYXdBdHRyaWJ1dGVzKCk7CiAgICAgICAgICAgIExpc3RCdWZmZXI8QXR0cmlidXRlLkNvbXBvdW5kPiBkZWNsQW5ub3MgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgIExpc3RCdWZmZXI8QXR0cmlidXRlLlR5cGVDb21wb3VuZD4gdHlwZUFubm9zID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgICAgICBMaXN0QnVmZmVyPEF0dHJpYnV0ZS5UeXBlQ29tcG91bmQ+IG9ubHlUeXBlQW5ub3MgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CgogICAgICAgICAgICBmb3IgKEF0dHJpYnV0ZS5Db21wb3VuZCBhIDogYWxsQW5ub3RhdGlvbnMpIHsKICAgICAgICAgICAgICAgIHN3aXRjaCAoYW5ub3RhdGlvblRhcmdldFR5cGUoYSwgc3ltKSkgewogICAgICAgICAgICAgICAgICAgIGNhc2UgREVDTEFSQVRJT046CiAgICAgICAgICAgICAgICAgICAgICAgIGRlY2xBbm5vcy5hcHBlbmQoYSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgQk9USDogewogICAgICAgICAgICAgICAgICAgICAgICBkZWNsQW5ub3MuYXBwZW5kKGEpOwogICAgICAgICAgICAgICAgICAgICAgICBBdHRyaWJ1dGUuVHlwZUNvbXBvdW5kIHRhID0gdG9UeXBlQ29tcG91bmQoYSwgcG9zKTsKICAgICAgICAgICAgICAgICAgICAgICAgdHlwZUFubm9zLmFwcGVuZCh0YSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBjYXNlIFRZUEU6IHsKICAgICAgICAgICAgICAgICAgICAgICAgQXR0cmlidXRlLlR5cGVDb21wb3VuZCB0YSA9IHRvVHlwZUNvbXBvdW5kKGEsIHBvcyk7CiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVBbm5vcy5hcHBlbmQodGEpOwogICAgICAgICAgICAgICAgICAgICAgICAvLyBBbHNvIGtlZXAgdHJhY2sgd2hpY2ggYW5ub3RhdGlvbnMgYXJlIG9ubHkgdHlwZSBhbm5vdGF0aW9ucwogICAgICAgICAgICAgICAgICAgICAgICBvbmx5VHlwZUFubm9zLmFwcGVuZCh0YSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gSWYgd2UgaGF2ZSBubyB0eXBlIGFubm90YXRpb25zIHdlIGFyZSBkb25lIGZvciB0aGlzIFN5bWJvbAogICAgICAgICAgICBpZiAodHlwZUFubm9zLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBSZXNldCBkZWNsIGFubm90YXRpb25zIHRvIHRoZSBzZXQge2FsbCAtIHR5cGUgb25seX0KICAgICAgICAgICAgc3ltLnJlc2V0QW5ub3RhdGlvbnMoKTsKICAgICAgICAgICAgc3ltLnNldERlY2xhcmF0aW9uQXR0cmlidXRlcyhkZWNsQW5ub3MudG9MaXN0KCkpOwoKICAgICAgICAgICAgTGlzdDxBdHRyaWJ1dGUuVHlwZUNvbXBvdW5kPiB0eXBlQW5ub3RhdGlvbnMgPSB0eXBlQW5ub3MudG9MaXN0KCk7CgogICAgICAgICAgICBpZiAodHlwZSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAvLyBXaGVuIHR5cGUgaXMgbnVsbCwgcHV0IHRoZSB0eXBlIGFubm90YXRpb25zIHRvIHRoZSBzeW1ib2wuCiAgICAgICAgICAgICAgICAvLyBUaGlzIGlzIHVzZWQgZm9yIGNvbnN0cnVjdG9yIHJldHVybiBhbm5vdGF0aW9ucywgZm9yIHdoaWNoCiAgICAgICAgICAgICAgICAvLyB3ZSB1c2UgdGhlIHR5cGUgb2YgdGhlIGVuY2xvc2luZyBjbGFzcy4KICAgICAgICAgICAgICAgIHR5cGUgPSBzeW0uZ2V0RW5jbG9zaW5nRWxlbWVudCgpLmFzVHlwZSgpOwoKICAgICAgICAgICAgICAgIC8vIERlY2xhcmF0aW9uIGFubm90YXRpb25zIGFyZSBhbHdheXMgYWxsb3dlZCBvbiBjb25zdHJ1Y3RvciByZXR1cm5zLgogICAgICAgICAgICAgICAgLy8gVGhlcmVmb3JlLCB1c2UgdHlwZUFubm90YXRpb25zIGluc3RlYWQgb2Ygb25seVR5cGVBbm5vcy4KICAgICAgICAgICAgICAgIHR5cGVXaXRoQW5ub3RhdGlvbnModHlwZXRyZWUsIHR5cGUsIHR5cGVBbm5vdGF0aW9ucywgdHlwZUFubm90YXRpb25zLCBwb3MpOwogICAgICAgICAgICAgICAgLy8gTm90ZSB0aGF0IHdlIGRvbid0IHVzZSB0aGUgcmVzdWx0LCB0aGUgY2FsbCB0bwogICAgICAgICAgICAgICAgLy8gdHlwZVdpdGhBbm5vdGF0aW9ucyBzaWRlLWVmZmVjdHMgdGhlIHR5cGUgYW5ub3RhdGlvbiBwb3NpdGlvbnMuCiAgICAgICAgICAgICAgICAvLyBUaGlzIGlzIGltcG9ydGFudCBmb3IgY29uc3RydWN0b3JzIG9mIG5lc3RlZCBjbGFzc2VzLgogICAgICAgICAgICAgICAgc3ltLmFwcGVuZFVuaXF1ZVR5cGVBdHRyaWJ1dGVzKHR5cGVBbm5vdGF0aW9ucyk7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIHR5cGUgaXMgbm9uLW51bGwsIGFkZCB0eXBlIGFubm90YXRpb25zIGZyb20gZGVjbGFyYXRpb24gY29udGV4dCB0byB0aGUgdHlwZQogICAgICAgICAgICB0eXBlID0gdHlwZVdpdGhBbm5vdGF0aW9ucyh0eXBldHJlZSwgdHlwZSwgdHlwZUFubm90YXRpb25zLCBvbmx5VHlwZUFubm9zLnRvTGlzdCgpLCBwb3MpOwoKICAgICAgICAgICAgaWYgKHN5bS5nZXRLaW5kKCkgPT0gRWxlbWVudEtpbmQuTUVUSE9EKSB7CiAgICAgICAgICAgICAgICBzeW0udHlwZS5hc01ldGhvZFR5cGUoKS5yZXN0eXBlID0gdHlwZTsKICAgICAgICAgICAgfSBlbHNlIGlmIChzeW0uZ2V0S2luZCgpID09IEVsZW1lbnRLaW5kLlBBUkFNRVRFUiAmJiBjdXJyZW50TGFtYmRhID09IG51bGwpIHsKICAgICAgICAgICAgICAgIHN5bS50eXBlID0gdHlwZTsKICAgICAgICAgICAgICAgIGlmIChzeW0uZ2V0UXVhbGlmaWVkTmFtZSgpLmVxdWFscyhuYW1lcy5fdGhpcykpIHsKICAgICAgICAgICAgICAgICAgICBzeW0ub3duZXIudHlwZS5hc01ldGhvZFR5cGUoKS5yZWN2dHlwZSA9IHR5cGU7CiAgICAgICAgICAgICAgICAgICAgLy8gbm90ZSB0aGF0IHRoZSB0eXBlQW5ub3RhdGlvbnMgd2lsbCBhbHNvIGJlIGFkZGVkIHRvIHRoZSBvd25lciBiZWxvdy4KICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgTWV0aG9kVHlwZSBtZXRoVHlwZSA9IHN5bS5vd25lci50eXBlLmFzTWV0aG9kVHlwZSgpOwogICAgICAgICAgICAgICAgICAgIExpc3Q8VmFyU3ltYm9sPiBwYXJhbXMgPSAoKE1ldGhvZFN5bWJvbClzeW0ub3duZXIpLnBhcmFtczsKICAgICAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IG9sZEFyZ3MgPSBtZXRoVHlwZS5hcmd0eXBlczsKICAgICAgICAgICAgICAgICAgICBMaXN0QnVmZmVyPFR5cGU+IG5ld0FyZ3MgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHBhcmFtcy5ub25FbXB0eSgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwYXJhbXMuaGVhZCA9PSBzeW0pIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld0FyZ3MuYWRkKHR5cGUpOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3QXJncy5hZGQob2xkQXJncy5oZWFkKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBvbGRBcmdzID0gb2xkQXJncy50YWlsOwogICAgICAgICAgICAgICAgICAgICAgICBwYXJhbXMgPSBwYXJhbXMudGFpbDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgbWV0aFR5cGUuYXJndHlwZXMgPSBuZXdBcmdzLnRvTGlzdCgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgc3ltLnR5cGUgPSB0eXBlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBzeW0uYXBwZW5kVW5pcXVlVHlwZUF0dHJpYnV0ZXModHlwZUFubm90YXRpb25zKTsKCiAgICAgICAgICAgIGlmIChzeW0uZ2V0S2luZCgpID09IEVsZW1lbnRLaW5kLlBBUkFNRVRFUiB8fAogICAgICAgICAgICAgICAgc3ltLmdldEtpbmQoKSA9PSBFbGVtZW50S2luZC5MT0NBTF9WQVJJQUJMRSB8fAogICAgICAgICAgICAgICAgc3ltLmdldEtpbmQoKSA9PSBFbGVtZW50S2luZC5SRVNPVVJDRV9WQVJJQUJMRSB8fAogICAgICAgICAgICAgICAgc3ltLmdldEtpbmQoKSA9PSBFbGVtZW50S2luZC5FWENFUFRJT05fUEFSQU1FVEVSKSB7CiAgICAgICAgICAgICAgICAvLyBNYWtlIHN1cmUgYWxsIHR5cGUgYW5ub3RhdGlvbnMgZnJvbSB0aGUgc3ltYm9sIGFyZSBhbHNvCiAgICAgICAgICAgICAgICAvLyBvbiB0aGUgb3duZXIuIElmIHRoZSBvd25lciBpcyBhbiBpbml0aWFsaXplciBibG9jaywgcHJvcGFnYXRlCiAgICAgICAgICAgICAgICAvLyB0byB0aGUgdHlwZS4KICAgICAgICAgICAgICAgIGZpbmFsIGxvbmcgb3duZXJGbGFncyA9IHN5bS5vd25lci5mbGFncygpOwogICAgICAgICAgICAgICAgaWYgKChvd25lckZsYWdzICYgRmxhZ3MuQkxPQ0spICE9IDApIHsKICAgICAgICAgICAgICAgICAgICAvLyBTdG9yZSBpbml0IGFuZCBjbGluaXQgdHlwZSBhbm5vdGF0aW9ucyB3aXRoIHRoZSBDbGFzc1N5bWJvbAogICAgICAgICAgICAgICAgICAgIC8vIHRvIGFsbG93IG91dHB1dCBpbiBHZW4ubm9ybWFsaXplRGVmcy4KICAgICAgICAgICAgICAgICAgICBDbGFzc1N5bWJvbCBjcyA9IChDbGFzc1N5bWJvbCkgc3ltLm93bmVyLm93bmVyOwogICAgICAgICAgICAgICAgICAgIGlmICgob3duZXJGbGFncyAmIEZsYWdzLlNUQVRJQykgIT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICBjcy5hcHBlbmRDbGFzc0luaXRUeXBlQXR0cmlidXRlcyh0eXBlQW5ub3RhdGlvbnMpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNzLmFwcGVuZEluaXRUeXBlQXR0cmlidXRlcyh0eXBlQW5ub3RhdGlvbnMpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgc3ltLm93bmVyLmFwcGVuZFVuaXF1ZVR5cGVBdHRyaWJ1dGVzKHN5bS5nZXRSYXdUeXBlQXR0cmlidXRlcygpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gVGhpcyBtZXRob2QgaGFzIGEgc2ltaWxhciBwdXJwb3NlIGFzCiAgICAgICAgLy8ge0BsaW5rIGNvbS5zdW4udG9vbHMuamF2YWMucGFyc2VyLkphdmFjUGFyc2VyLmluc2VydEFubm90YXRpb25zVG9Nb3N0SW5uZXIoSkNFeHByZXNzaW9uLCBMaXN0PEpDVHlwZUFubm90YXRpb24+LCBib29sZWFuKX0KICAgICAgICAvLyBXZSBmb3VuZCBhIHR5cGUgYW5ub3RhdGlvbiBpbiBhIGRlY2xhcmF0aW9uIGFubm90YXRpb24gcG9zaXRpb24sCiAgICAgICAgLy8gZm9yIGV4YW1wbGUsIG9uIHRoZSByZXR1cm4gdHlwZS4KICAgICAgICAvLyBTdWNoIGFuIGFubm90YXRpb24gaXMgX25vdF8gcGFydCBvZiBhbiBKQ0Fubm90YXRlZFR5cGUgdHJlZSBhbmQgd2UgdGhlcmVmb3JlCiAgICAgICAgLy8gbmVlZCB0byBzZXQgaXRzIHBvc2l0aW9uIGV4cGxpY2l0bHkuCiAgICAgICAgLy8gVGhlIG1ldGhvZCByZXR1cm5zIGEgY29weSBvZiB0eXBlIHRoYXQgY29udGFpbnMgdGhlc2UgYW5ub3RhdGlvbnMuCiAgICAgICAgLy8KICAgICAgICAvLyBBcyBhIHNpZGUgZWZmZWN0IHRoZSBtZXRob2Qgc2V0cyB0aGUgdHlwZSBhbm5vdGF0aW9uIHBvc2l0aW9uIG9mICJhbm5vdGF0aW9ucyIuCiAgICAgICAgLy8gTm90ZSB0aGF0IGl0IGlzIGFzc3VtZWQgdGhhdCBhbGwgYW5ub3RhdGlvbnMgc2hhcmUgdGhlIHNhbWUgcG9zaXRpb24uCiAgICAgICAgcHJpdmF0ZSBUeXBlIHR5cGVXaXRoQW5ub3RhdGlvbnMoZmluYWwgSkNUcmVlIHR5cGV0cmVlLCBmaW5hbCBUeXBlIHR5cGUsCiAgICAgICAgICAgICAgICBmaW5hbCBMaXN0PEF0dHJpYnV0ZS5UeXBlQ29tcG91bmQ+IGFubm90YXRpb25zLAogICAgICAgICAgICAgICAgZmluYWwgTGlzdDxBdHRyaWJ1dGUuVHlwZUNvbXBvdW5kPiBvbmx5VHlwZUFubm90YXRpb25zLAogICAgICAgICAgICAgICAgZmluYWwgVHlwZUFubm90YXRpb25Qb3NpdGlvbiBwb3MpCiAgICAgICAgewogICAgICAgICAgICBpZiAoYW5ub3RhdGlvbnMuaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHlwZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKHR5cGUuaGFzVGFnKFR5cGVUYWcuQVJSQVkpKQogICAgICAgICAgICAgICAgcmV0dXJuIHJld3JpdGVBcnJheVR5cGUoKEFycmF5VHlwZSl0eXBlLCBhbm5vdGF0aW9ucywgcG9zKTsKCiAgICAgICAgICAgIGlmICh0eXBlLmhhc1RhZyhUeXBlVGFnLlRZUEVWQVIpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHlwZS5hbm5vdGF0ZWRUeXBlKG9ubHlUeXBlQW5ub3RhdGlvbnMpOwogICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGUuZ2V0S2luZCgpID09IFR5cGVLaW5kLlVOSU9OKSB7CiAgICAgICAgICAgICAgICAvLyBUaGVyZSBpcyBhIFR5cGVLaW5kLCBidXQgbm8gVHlwZVRhZy4KICAgICAgICAgICAgICAgIEpDVHlwZVVuaW9uIHR1dHJlZSA9IChKQ1R5cGVVbmlvbil0eXBldHJlZTsKICAgICAgICAgICAgICAgIEpDRXhwcmVzc2lvbiBmc3QgPSB0dXRyZWUuYWx0ZXJuYXRpdmVzLmdldCgwKTsKICAgICAgICAgICAgICAgIFR5cGUgcmVzID0gdHlwZVdpdGhBbm5vdGF0aW9ucyhmc3QsIGZzdC50eXBlLCBhbm5vdGF0aW9ucywgb25seVR5cGVBbm5vdGF0aW9ucywgcG9zKTsKICAgICAgICAgICAgICAgIGZzdC50eXBlID0gcmVzOwogICAgICAgICAgICAgICAgLy8gVE9ETzogZG8gd2Ugd2FudCB0byBzZXQgcmVzIGFzIGZpcnN0IGVsZW1lbnQgaW4gdWN0LmFsdGVybmF0aXZlcz8KICAgICAgICAgICAgICAgIC8vIFVuaW9uQ2xhc3NUeXBlIHVjdCA9IChjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuVHlwZS5VbmlvbkNsYXNzVHlwZSl0eXBlOwogICAgICAgICAgICAgICAgLy8gUmV0dXJuIHRoZSB1bi1hbm5vdGF0ZWQgdW5pb24tdHlwZS4KICAgICAgICAgICAgICAgIHJldHVybiB0eXBlOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgVHlwZSBlbmNsVHkgPSB0eXBlOwogICAgICAgICAgICAgICAgRWxlbWVudCBlbmNsRWwgPSB0eXBlLmFzRWxlbWVudCgpOwogICAgICAgICAgICAgICAgSkNUcmVlIGVuY2xUciA9IHR5cGV0cmVlOwoKICAgICAgICAgICAgICAgIHdoaWxlIChlbmNsRWwgIT0gbnVsbCAmJgogICAgICAgICAgICAgICAgICAgICAgICBlbmNsRWwuZ2V0S2luZCgpICE9IEVsZW1lbnRLaW5kLlBBQ0tBR0UgJiYKICAgICAgICAgICAgICAgICAgICAgICAgZW5jbFR5ICE9IG51bGwgJiYKICAgICAgICAgICAgICAgICAgICAgICAgZW5jbFR5LmdldEtpbmQoKSAhPSBUeXBlS2luZC5OT05FICYmCiAgICAgICAgICAgICAgICAgICAgICAgIGVuY2xUeS5nZXRLaW5kKCkgIT0gVHlwZUtpbmQuRVJST1IgJiYKICAgICAgICAgICAgICAgICAgICAgICAgKGVuY2xUci5nZXRLaW5kKCkgPT0gSkNUcmVlLktpbmQuTUVNQkVSX1NFTEVDVCB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVuY2xUci5nZXRLaW5kKCkgPT0gSkNUcmVlLktpbmQuUEFSQU1FVEVSSVpFRF9UWVBFIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5jbFRyLmdldEtpbmQoKSA9PSBKQ1RyZWUuS2luZC5BTk5PVEFURURfVFlQRSkpIHsKICAgICAgICAgICAgICAgICAgICAvLyBJdGVyYXRlIGFsc28gb3ZlciB0aGUgdHlwZSB0cmVlLCBub3QganVzdCB0aGUgdHlwZTogdGhlIHR5cGUgaXMgYWxyZWFkeQogICAgICAgICAgICAgICAgICAgIC8vIGNvbXBsZXRlbHkgcmVzb2x2ZWQgYW5kIHdlIGNhbm5vdCBkaXN0aW5ndWlzaCB3aGVyZSB0aGUgYW5ub3RhdGlvbgogICAgICAgICAgICAgICAgICAgIC8vIGJlbG9uZ3MgZm9yIGEgbmVzdGVkIHR5cGUuCiAgICAgICAgICAgICAgICAgICAgaWYgKGVuY2xUci5nZXRLaW5kKCkgPT0gSkNUcmVlLktpbmQuTUVNQkVSX1NFTEVDVCkgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBvbmx5IGNoYW5nZSBlbmNsIGluIHRoaXMgY2FzZS4KICAgICAgICAgICAgICAgICAgICAgICAgZW5jbFR5ID0gZW5jbFR5LmdldEVuY2xvc2luZ1R5cGUoKTsKICAgICAgICAgICAgICAgICAgICAgICAgZW5jbEVsID0gZW5jbEVsLmdldEVuY2xvc2luZ0VsZW1lbnQoKTsKICAgICAgICAgICAgICAgICAgICAgICAgZW5jbFRyID0gKChKQ0ZpZWxkQWNjZXNzKWVuY2xUcikuZ2V0RXhwcmVzc2lvbigpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZW5jbFRyLmdldEtpbmQoKSA9PSBKQ1RyZWUuS2luZC5QQVJBTUVURVJJWkVEX1RZUEUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgZW5jbFRyID0gKChKQ1R5cGVBcHBseSllbmNsVHIpLmdldFR5cGUoKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBvbmx5IG90aGVyIG9wdGlvbiBiZWNhdXNlIG9mIHdoaWxlIGNvbmRpdGlvbgogICAgICAgICAgICAgICAgICAgICAgICBlbmNsVHIgPSAoKEpDQW5ub3RhdGVkVHlwZSllbmNsVHIpLmdldFVuZGVybHlpbmdUeXBlKCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8qKiBXZSBhcmUgdHJ5aW5nIHRvIGFubm90YXRlIHNvbWUgZW5jbG9zaW5nIHR5cGUsCiAgICAgICAgICAgICAgICAgKiBidXQgbm90aGluZyBtb3JlIGV4aXN0cy4KICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgaWYgKGVuY2xUeSAhPSBudWxsICYmCiAgICAgICAgICAgICAgICAgICAgICAgIGVuY2xUeS5oYXNUYWcoVHlwZVRhZy5OT05FKSkgewogICAgICAgICAgICAgICAgICAgIHN3aXRjaCAob25seVR5cGVBbm5vdGF0aW9ucy5zaXplKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gRG9uJ3QgaXNzdWUgYW4gZXJyb3IgaWYgYWxsIHR5cGUgYW5ub3RhdGlvbnMgYXJlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBhbHNvIGRlY2xhcmF0aW9uIGFubm90YXRpb25zLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSWYgdGhlIGFubm90YXRpb25zIGFyZSBhbHNvIGRlY2xhcmF0aW9uIGFubm90YXRpb25zLCB0aGV5IGFyZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaWxsZWdhbCBhcyB0eXBlIGFubm90YXRpb25zIGJ1dCBtaWdodCBiZSBsZWdhbCBhcyBkZWNsYXJhdGlvbiBhbm5vdGF0aW9ucy4KICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoZSBub3JtYWwgZGVjbGFyYXRpb24gYW5ub3RhdGlvbiBjaGVja3MgbWFrZSBzdXJlIHRoYXQgdGhlIHVzZSBpcyB2YWxpZC4KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDE6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2cuZXJyb3IodHlwZXRyZWUucG9zKCksICJjYW50LnR5cGUuYW5ub3RhdGUuc2NvcGluZy4xIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb25seVR5cGVBbm5vdGF0aW9ucyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZy5lcnJvcih0eXBldHJlZS5wb3MoKSwgImNhbnQudHlwZS5hbm5vdGF0ZS5zY29waW5nIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb25seVR5cGVBbm5vdGF0aW9ucyk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHJldHVybiB0eXBlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIEF0IHRoaXMgcG9pbnQgd2UgaGF2ZSB2aXNpdGVkIHRoZSBwYXJ0IG9mIHRoZSBuZXN0ZWQKICAgICAgICAgICAgICAgIC8vIHR5cGUgdGhhdCBpcyB3cml0dGVuIGluIHRoZSBzb3VyY2UgY29kZS4KICAgICAgICAgICAgICAgIC8vIE5vdyBjb3VudCBmcm9tIGhlcmUgdG8gdGhlIGFjdHVhbCB0b3AtbGV2ZWwgY2xhc3MgdG8gZGV0ZXJtaW5lCiAgICAgICAgICAgICAgICAvLyB0aGUgY29ycmVjdCBuZXN0aW5nLgoKICAgICAgICAgICAgICAgIC8vIFRoZSBnZW5lcmljTG9jYXRpb24gZm9yIHRoZSBhbm5vdGF0aW9uLgogICAgICAgICAgICAgICAgTGlzdEJ1ZmZlcjxUeXBlUGF0aEVudHJ5PiBkZXB0aCA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKCiAgICAgICAgICAgICAgICBUeXBlIHRvcFR5ID0gZW5jbFR5OwogICAgICAgICAgICAgICAgd2hpbGUgKGVuY2xFbCAhPSBudWxsICYmCiAgICAgICAgICAgICAgICAgICAgICAgIGVuY2xFbC5nZXRLaW5kKCkgIT0gRWxlbWVudEtpbmQuUEFDS0FHRSAmJgogICAgICAgICAgICAgICAgICAgICAgICB0b3BUeSAhPSBudWxsICYmCiAgICAgICAgICAgICAgICAgICAgICAgIHRvcFR5LmdldEtpbmQoKSAhPSBUeXBlS2luZC5OT05FICYmCiAgICAgICAgICAgICAgICAgICAgICAgIHRvcFR5LmdldEtpbmQoKSAhPSBUeXBlS2luZC5FUlJPUikgewogICAgICAgICAgICAgICAgICAgIHRvcFR5ID0gdG9wVHkuZ2V0RW5jbG9zaW5nVHlwZSgpOwogICAgICAgICAgICAgICAgICAgIGVuY2xFbCA9IGVuY2xFbC5nZXRFbmNsb3NpbmdFbGVtZW50KCk7CgogICAgICAgICAgICAgICAgICAgIGlmICh0b3BUeSAhPSBudWxsICYmIHRvcFR5LmdldEtpbmQoKSAhPSBUeXBlS2luZC5OT05FKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIE9ubHkgY291bnQgZW5jbG9zaW5nIHR5cGVzLgogICAgICAgICAgICAgICAgICAgICAgICBkZXB0aCA9IGRlcHRoLmFwcGVuZChUeXBlUGF0aEVudHJ5LklOTkVSX1RZUEUpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoZGVwdGgubm9uRW1wdHkoKSkgewogICAgICAgICAgICAgICAgICAgIC8vIE9ubHkgbmVlZCB0byBjaGFuZ2UgdGhlIGFubm90YXRpb24gcG9zaXRpb25zCiAgICAgICAgICAgICAgICAgICAgLy8gaWYgdGhleSBhcmUgb24gYW4gZW5jbG9zZWQgdHlwZS4KICAgICAgICAgICAgICAgICAgICAvLyBBbGwgYW5ub3RhdGlvbnMgc2hhcmUgdGhlIHNhbWUgcG9zaXRpb247IG1vZGlmeSB0aGUgZmlyc3Qgb25lLgogICAgICAgICAgICAgICAgICAgIEF0dHJpYnV0ZS5UeXBlQ29tcG91bmQgYSA9IGFubm90YXRpb25zLmdldCgwKTsKICAgICAgICAgICAgICAgICAgICBUeXBlQW5ub3RhdGlvblBvc2l0aW9uIHAgPSBhLnBvc2l0aW9uOwogICAgICAgICAgICAgICAgICAgIHAubG9jYXRpb24gPSBwLmxvY2F0aW9uLmFwcGVuZExpc3QoZGVwdGgudG9MaXN0KCkpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIFR5cGUgcmV0ID0gdHlwZVdpdGhBbm5vdGF0aW9ucyh0eXBlLCBlbmNsVHksIGFubm90YXRpb25zKTsKICAgICAgICAgICAgICAgIHR5cGV0cmVlLnR5cGUgPSByZXQ7CiAgICAgICAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBDcmVhdGUgYSBjb3B5IG9mIHRoZSB7QGNvZGUgVHlwZSB0eXBlfSB3aXRoIHRoZSBoZWxwIG9mIHRoZSBUcmVlIGZvciBhIHR5cGUKICAgICAgICAgKiB7QGNvZGUgSkNUcmVlIHR5cGV0cmVlfSBpbnNlcnRpbmcgYWxsIHR5cGUgYW5ub3RhdGlvbnMgaW4ge0Bjb2RlIGFubm90YXRpb25zfSB0byB0aGUKICAgICAgICAgKiBpbm5lcm1vc3QgYXJyYXkgY29tcG9uZW50IHR5cGUuCiAgICAgICAgICoKICAgICAgICAgKiBTSURFIEVGRkVDVDogVXBkYXRlIHBvc2l0aW9uIGZvciB0aGUgYW5ub3RhdGlvbnMgdG8gYmUge0Bjb2RlIHBvc30uCiAgICAgICAgICovCiAgICAgICAgcHJpdmF0ZSBUeXBlIHJld3JpdGVBcnJheVR5cGUoQXJyYXlUeXBlIHR5cGUsIExpc3Q8VHlwZUNvbXBvdW5kPiBhbm5vdGF0aW9ucywgVHlwZUFubm90YXRpb25Qb3NpdGlvbiBwb3MpIHsKICAgICAgICAgICAgQXJyYXlUeXBlIHRvbW9kaWZ5ID0gbmV3IEFycmF5VHlwZSh0eXBlKTsKICAgICAgICAgICAgQXJyYXlUeXBlIHJlcyA9IHRvbW9kaWZ5OwoKICAgICAgICAgICAgTGlzdDxUeXBlUGF0aEVudHJ5PiBsb2MgPSBMaXN0Lm5pbCgpOwoKICAgICAgICAgICAgLy8gcGVlbCBvbmUgYW5kIHVwZGF0ZSBsb2MKICAgICAgICAgICAgVHlwZSB0bXBUeXBlID0gdHlwZS5lbGVtdHlwZTsKICAgICAgICAgICAgbG9jID0gbG9jLnByZXBlbmQoVHlwZVBhdGhFbnRyeS5BUlJBWSk7CgogICAgICAgICAgICB3aGlsZSAodG1wVHlwZS5oYXNUYWcoVHlwZVRhZy5BUlJBWSkpIHsKICAgICAgICAgICAgICAgIEFycmF5VHlwZSBhcnIgPSAoQXJyYXlUeXBlKXRtcFR5cGU7CgogICAgICAgICAgICAgICAgLy8gVXBkYXRlIGxhc3QgdHlwZSB3aXRoIG5ldyBlbGVtZW50IHR5cGUKICAgICAgICAgICAgICAgIEFycmF5VHlwZSB0bXAgPSBuZXcgQXJyYXlUeXBlKGFycik7CiAgICAgICAgICAgICAgICB0b21vZGlmeS5lbGVtdHlwZSA9IHRtcDsKICAgICAgICAgICAgICAgIHRvbW9kaWZ5ID0gdG1wOwoKICAgICAgICAgICAgICAgIHRtcFR5cGUgPSBhcnIuZWxlbXR5cGU7CiAgICAgICAgICAgICAgICBsb2MgPSBsb2MucHJlcGVuZChUeXBlUGF0aEVudHJ5LkFSUkFZKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gRml4IGlubmVybW9zdCBlbGVtZW50IHR5cGUKICAgICAgICAgICAgVHlwZSBlbGVtVHlwZTsKICAgICAgICAgICAgaWYgKHRtcFR5cGUuZ2V0TWV0YWRhdGEoKSAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICBMaXN0PFR5cGVDb21wb3VuZD4gdGNzOwogICAgICAgICAgICAgICAgaWYgKHRtcFR5cGUuZ2V0QW5ub3RhdGlvbk1pcnJvcnMoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICAgICAgICB0Y3MgPSBhbm5vdGF0aW9uczsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgLy8gU3BlY2lhbCBjYXNlLCBsZXRzIHByZXBlbmQKICAgICAgICAgICAgICAgICAgICB0Y3MgPSAgYW5ub3RhdGlvbnMuYXBwZW5kTGlzdCh0bXBUeXBlLmdldEFubm90YXRpb25NaXJyb3JzKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxlbVR5cGUgPSB0bXBUeXBlLmNsb25lV2l0aE1ldGFkYXRhKHRtcFR5cGUKICAgICAgICAgICAgICAgICAgICAgICAgLmdldE1ldGFkYXRhKCkKICAgICAgICAgICAgICAgICAgICAgICAgLndpdGhvdXQoS2luZC5BTk5PVEFUSU9OUykKICAgICAgICAgICAgICAgICAgICAgICAgLmNvbWJpbmUobmV3IFR5cGVNZXRhZGF0YS5Bbm5vdGF0aW9ucyh0Y3MpKSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBlbGVtVHlwZSA9IHRtcFR5cGUuY2xvbmVXaXRoTWV0YWRhdGEobmV3IFR5cGVNZXRhZGF0YShuZXcgVHlwZU1ldGFkYXRhLkFubm90YXRpb25zKGFubm90YXRpb25zKSkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHRvbW9kaWZ5LmVsZW10eXBlID0gZWxlbVR5cGU7CgogICAgICAgICAgICAvLyBVcGRhdGUgcG9zaXRpb25zCiAgICAgICAgICAgIGZvciAoVHlwZUNvbXBvdW5kIHRjIDogYW5ub3RhdGlvbnMpIHsKICAgICAgICAgICAgICAgIGlmICh0Yy5wb3NpdGlvbiA9PSBudWxsKQogICAgICAgICAgICAgICAgICAgIHRjLnBvc2l0aW9uID0gcG9zOwogICAgICAgICAgICAgICAgdGMucG9zaXRpb24ubG9jYXRpb24gPSBsb2M7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiByZXM7CiAgICAgICAgfQoKICAgICAgICAvKiogUmV0dXJuIGEgY29weSBvZiB0aGUgZmlyc3QgdHlwZSB0aGF0IG9ubHkgZGlmZmVycyBieQogICAgICAgICAqIGluc2VydGluZyB0aGUgYW5ub3RhdGlvbnMgdG8gdGhlIGxlZnQtbW9zdC9pbm5lci1tb3N0IHR5cGUKICAgICAgICAgKiBvciB0aGUgdHlwZSBnaXZlbiBieSBzdG9wQXQuCiAgICAgICAgICoKICAgICAgICAgKiBXZSBuZWVkIHRoZSBzdG9wQXQgcGFyYW1ldGVyIHRvIGtub3cgd2hlcmUgb24gYSB0eXBlIHRvCiAgICAgICAgICogcHV0IHRoZSBhbm5vdGF0aW9ucy4KICAgICAgICAgKiBJZiB3ZSBoYXZlIG5lc3RlZCBjbGFzc2VzIE91dGVyID4gTWlkZGxlID4gSW5uZXIsIGFuZCB3ZQogICAgICAgICAqIGhhdmUgdGhlIHNvdXJjZSB0eXBlICJAQSBNaWRkbGUuSW5uZXIiLCB3ZSB3aWxsIGludm9rZQogICAgICAgICAqIHRoaXMgbWV0aG9kIHdpdGggdHlwZSA9IE91dGVyLk1pZGRsZS5Jbm5lciwKICAgICAgICAgKiBzdG9wQXQgPSBNaWRkbGUuSW5uZXIsIGFuZCBhbm5vdGF0aW9ucyA9IEBBLgogICAgICAgICAqCiAgICAgICAgICogQHBhcmFtIHR5cGUgVGhlIHR5cGUgdG8gY29weS4KICAgICAgICAgKiBAcGFyYW0gc3RvcEF0IFRoZSB0eXBlIHRvIHN0b3AgYXQuCiAgICAgICAgICogQHBhcmFtIGFubm90YXRpb25zIFRoZSBhbm5vdGF0aW9ucyB0byBpbnNlcnQuCiAgICAgICAgICogQHJldHVybiBBIGNvcHkgb2YgdHlwZSB0aGF0IGNvbnRhaW5zIHRoZSBhbm5vdGF0aW9ucy4KICAgICAgICAgKi8KICAgICAgICBwcml2YXRlIFR5cGUgdHlwZVdpdGhBbm5vdGF0aW9ucyhmaW5hbCBUeXBlIHR5cGUsCiAgICAgICAgICAgICAgICBmaW5hbCBUeXBlIHN0b3BBdCwKICAgICAgICAgICAgICAgIGZpbmFsIExpc3Q8QXR0cmlidXRlLlR5cGVDb21wb3VuZD4gYW5ub3RhdGlvbnMpIHsKICAgICAgICAgICAgVmlzaXRvcjxUeXBlLCBMaXN0PFR5cGVDb21wb3VuZD4+IHZpc2l0b3IgPQogICAgICAgICAgICAgICAgICAgIG5ldyBUeXBlLlZpc2l0b3I8VHlwZSwgTGlzdDxBdHRyaWJ1dGUuVHlwZUNvbXBvdW5kPj4oKSB7CiAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgICAgIHB1YmxpYyBUeXBlIHZpc2l0Q2xhc3NUeXBlKENsYXNzVHlwZSB0LCBMaXN0PFR5cGVDb21wb3VuZD4gcykgewogICAgICAgICAgICAgICAgICAgIC8vIGFzc2VydCB0aGF0IHQuY29uc3RWYWx1ZSgpID09IG51bGw/CiAgICAgICAgICAgICAgICAgICAgaWYgKHQgPT0gc3RvcEF0IHx8CiAgICAgICAgICAgICAgICAgICAgICAgIHQuZ2V0RW5jbG9zaW5nVHlwZSgpID09IFR5cGUubm9UeXBlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0LmFubm90YXRlZFR5cGUocyk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgQ2xhc3NUeXBlIHJldCA9IG5ldyBDbGFzc1R5cGUodC5nZXRFbmNsb3NpbmdUeXBlKCkuYWNjZXB0KHRoaXMsIHMpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0LnR5cGFyYW1zX2ZpZWxkLCB0LnRzeW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHQuZ2V0TWV0YWRhdGEoKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldC5hbGxfaW50ZXJmYWNlc19maWVsZCA9IHQuYWxsX2ludGVyZmFjZXNfZmllbGQ7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldC5hbGxwYXJhbXNfZmllbGQgPSB0LmFsbHBhcmFtc19maWVsZDsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0LmludGVyZmFjZXNfZmllbGQgPSB0LmludGVyZmFjZXNfZmllbGQ7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldC5yYW5rX2ZpZWxkID0gdC5yYW5rX2ZpZWxkOwogICAgICAgICAgICAgICAgICAgICAgICByZXQuc3VwZXJ0eXBlX2ZpZWxkID0gdC5zdXBlcnR5cGVfZmllbGQ7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICAgICAgcHVibGljIFR5cGUgdmlzaXRXaWxkY2FyZFR5cGUoV2lsZGNhcmRUeXBlIHQsIExpc3Q8VHlwZUNvbXBvdW5kPiBzKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHQuYW5ub3RhdGVkVHlwZShzKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgICAgIHB1YmxpYyBUeXBlIHZpc2l0QXJyYXlUeXBlKEFycmF5VHlwZSB0LCBMaXN0PFR5cGVDb21wb3VuZD4gcykgewogICAgICAgICAgICAgICAgICAgIEFycmF5VHlwZSByZXQgPSBuZXcgQXJyYXlUeXBlKHQuZWxlbXR5cGUuYWNjZXB0KHRoaXMsIHMpLCB0LnRzeW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdC5nZXRNZXRhZGF0YSgpKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICAgICAgcHVibGljIFR5cGUgdmlzaXRNZXRob2RUeXBlKE1ldGhvZFR5cGUgdCwgTGlzdDxUeXBlQ29tcG91bmQ+IHMpIHsKICAgICAgICAgICAgICAgICAgICAvLyBJbXBvc3NpYmxlPwogICAgICAgICAgICAgICAgICAgIHJldHVybiB0OwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICAgICAgcHVibGljIFR5cGUgdmlzaXRQYWNrYWdlVHlwZShQYWNrYWdlVHlwZSB0LCBMaXN0PFR5cGVDb21wb3VuZD4gcykgewogICAgICAgICAgICAgICAgICAgIC8vIEltcG9zc2libGU/CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHQ7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgICAgICBwdWJsaWMgVHlwZSB2aXNpdFR5cGVWYXIoVHlwZVZhciB0LCBMaXN0PFR5cGVDb21wb3VuZD4gcykgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB0LmFubm90YXRlZFR5cGUocyk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgICAgICBwdWJsaWMgVHlwZSB2aXNpdE1vZHVsZVR5cGUoTW9kdWxlVHlwZSB0LCBMaXN0PFR5cGVDb21wb3VuZD4gcykgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB0LmFubm90YXRlZFR5cGUocyk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgICAgICBwdWJsaWMgVHlwZSB2aXNpdENhcHR1cmVkVHlwZShDYXB0dXJlZFR5cGUgdCwgTGlzdDxUeXBlQ29tcG91bmQ+IHMpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdC5hbm5vdGF0ZWRUeXBlKHMpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICAgICAgcHVibGljIFR5cGUgdmlzaXRGb3JBbGwoRm9yQWxsIHQsIExpc3Q8VHlwZUNvbXBvdW5kPiBzKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gSW1wb3NzaWJsZT8KICAgICAgICAgICAgICAgICAgICByZXR1cm4gdDsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgICAgIHB1YmxpYyBUeXBlIHZpc2l0VW5kZXRWYXIoVW5kZXRWYXIgdCwgTGlzdDxUeXBlQ29tcG91bmQ+IHMpIHsKICAgICAgICAgICAgICAgICAgICAvLyBJbXBvc3NpYmxlPwogICAgICAgICAgICAgICAgICAgIHJldHVybiB0OwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICAgICAgcHVibGljIFR5cGUgdmlzaXRFcnJvclR5cGUoRXJyb3JUeXBlIHQsIExpc3Q8VHlwZUNvbXBvdW5kPiBzKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHQuYW5ub3RhdGVkVHlwZShzKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgICAgIHB1YmxpYyBUeXBlIHZpc2l0VHlwZShUeXBlIHQsIExpc3Q8VHlwZUNvbXBvdW5kPiBzKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHQuYW5ub3RhdGVkVHlwZShzKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKCiAgICAgICAgICAgIHJldHVybiB0eXBlLmFjY2VwdCh2aXNpdG9yLCBhbm5vdGF0aW9ucyk7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIEF0dHJpYnV0ZS5UeXBlQ29tcG91bmQgdG9UeXBlQ29tcG91bmQoQXR0cmlidXRlLkNvbXBvdW5kIGEsIFR5cGVBbm5vdGF0aW9uUG9zaXRpb24gcCkgewogICAgICAgICAgICAvLyBJdCBpcyBzYWZlIHRvIGFsaWFzIHRoZSBwb3NpdGlvbi4KICAgICAgICAgICAgcmV0dXJuIG5ldyBBdHRyaWJ1dGUuVHlwZUNvbXBvdW5kKGEsIHApOwogICAgICAgIH0KCgogICAgICAgIC8qIFRoaXMgaXMgdGhlIGJlZ2lubmluZyBvZiB0aGUgc2Vjb25kIHBhcnQgb2Ygb3JnYW5pemluZwogICAgICAgICAqIHR5cGUgYW5ub3RhdGlvbnM6IGRldGVybWluZSB0aGUgdHlwZSBhbm5vdGF0aW9uIHBvc2l0aW9ucy4KICAgICAgICAgKi8KICAgICAgICBwcml2YXRlIFR5cGVBbm5vdGF0aW9uUG9zaXRpb24KICAgICAgICAgICAgcmVzb2x2ZUZyYW1lKEpDVHJlZSB0cmVlLAogICAgICAgICAgICAgICAgICAgICAgICAgSkNUcmVlIGZyYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgTGlzdDxKQ1RyZWU+IHBhdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICBKQ0xhbWJkYSBjdXJyZW50TGFtYmRhLAogICAgICAgICAgICAgICAgICAgICAgICAgaW50IG91dGVyX3R5cGVfaW5kZXgsCiAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0QnVmZmVyPFR5cGVQYXRoRW50cnk+IGxvY2F0aW9uKQogICAgICAgIHsKCiAgICAgICAgICAgIC8vIE5vdGUgdGhhdCBwLm9mZnNldCBpcyBzZXQgaW4KICAgICAgICAgICAgLy8gY29tLnN1bi50b29scy5qYXZhYy5qdm0uR2VuLnNldFR5cGVBbm5vdGF0aW9uUG9zaXRpb25zKGludCkKCiAgICAgICAgICAgIHN3aXRjaCAoZnJhbWUuZ2V0S2luZCgpKSB7CiAgICAgICAgICAgICAgICBjYXNlIFRZUEVfQ0FTVDoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gVHlwZUFubm90YXRpb25Qb3NpdGlvbi50eXBlQ2FzdChsb2NhdGlvbi50b0xpc3QoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50TGFtYmRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG91dGVyX3R5cGVfaW5kZXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJhbWUucG9zKTsKCiAgICAgICAgICAgICAgICBjYXNlIElOU1RBTkNFX09GOgogICAgICAgICAgICAgICAgICAgIHJldHVybiBUeXBlQW5ub3RhdGlvblBvc2l0aW9uLmluc3RhbmNlT2YobG9jYXRpb24udG9MaXN0KCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50TGFtYmRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJhbWUucG9zKTsKCiAgICAgICAgICAgICAgICBjYXNlIE5FV19DTEFTUzoKICAgICAgICAgICAgICAgICAgICBmaW5hbCBKQ05ld0NsYXNzIGZyYW1lTmV3Q2xhc3MgPSAoSkNOZXdDbGFzcykgZnJhbWU7CiAgICAgICAgICAgICAgICAgICAgaWYgKGZyYW1lTmV3Q2xhc3MuZGVmICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gU3BlY2lhbCBoYW5kbGluZyBmb3IgYW5vbnltb3VzIGNsYXNzIGluc3RhbnRpYXRpb25zCiAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIEpDQ2xhc3NEZWNsIGZyYW1lQ2xhc3NEZWNsID0gZnJhbWVOZXdDbGFzcy5kZWY7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmcmFtZUNsYXNzRGVjbC5pbXBsZW1lbnRpbmcuY29udGFpbnModHJlZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGludCB0eXBlX2luZGV4ID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcmFtZUNsYXNzRGVjbC5pbXBsZW1lbnRpbmcuaW5kZXhPZih0cmVlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBUeXBlQW5ub3RhdGlvblBvc2l0aW9uCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmNsYXNzRXh0ZW5kcyhsb2NhdGlvbi50b0xpc3QoKSwgY3VycmVudExhbWJkYSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVfaW5kZXgsIGZyYW1lLnBvcyk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2ZvciBlbmNsLm5ldyBAVEEgQ2xhenooKSwgdHJlZSBtYXkgYmUgZGlmZmVyZW50IGZyb20gZnJhbWVDbGFzc0RlY2wuZXh0ZW5kaW5nCiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gVHlwZUFubm90YXRpb25Qb3NpdGlvbgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jbGFzc0V4dGVuZHMobG9jYXRpb24udG9MaXN0KCksIGN1cnJlbnRMYW1iZGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcmFtZS5wb3MpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChmcmFtZU5ld0NsYXNzLnR5cGVhcmdzLmNvbnRhaW5zKHRyZWUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGludCB0eXBlX2luZGV4ID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZyYW1lTmV3Q2xhc3MudHlwZWFyZ3MuaW5kZXhPZih0cmVlKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFR5cGVBbm5vdGF0aW9uUG9zaXRpb24KICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jb25zdHJ1Y3Rvckludm9jYXRpb25UeXBlQXJnKGxvY2F0aW9uLnRvTGlzdCgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudExhbWJkYSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVfaW5kZXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcmFtZS5wb3MpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBUeXBlQW5ub3RhdGlvblBvc2l0aW9uCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAubmV3T2JqKGxvY2F0aW9uLnRvTGlzdCgpLCBjdXJyZW50TGFtYmRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcmFtZS5wb3MpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBjYXNlIE5FV19BUlJBWToKICAgICAgICAgICAgICAgICAgICByZXR1cm4gVHlwZUFubm90YXRpb25Qb3NpdGlvbgogICAgICAgICAgICAgICAgICAgICAgICAubmV3T2JqKGxvY2F0aW9uLnRvTGlzdCgpLCBjdXJyZW50TGFtYmRhLCBmcmFtZS5wb3MpOwoKICAgICAgICAgICAgICAgIGNhc2UgQU5OT1RBVElPTl9UWVBFOgogICAgICAgICAgICAgICAgY2FzZSBDTEFTUzoKICAgICAgICAgICAgICAgIGNhc2UgRU5VTToKICAgICAgICAgICAgICAgIGNhc2UgSU5URVJGQUNFOgogICAgICAgICAgICAgICAgICAgIGlmICgoKEpDQ2xhc3NEZWNsKWZyYW1lKS5leHRlbmRpbmcgPT0gdHJlZSkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gVHlwZUFubm90YXRpb25Qb3NpdGlvbgogICAgICAgICAgICAgICAgICAgICAgICAgICAgLmNsYXNzRXh0ZW5kcyhsb2NhdGlvbi50b0xpc3QoKSwgY3VycmVudExhbWJkYSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJhbWUucG9zKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCgoSkNDbGFzc0RlY2wpZnJhbWUpLmltcGxlbWVudGluZy5jb250YWlucyh0cmVlKSkgewogICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgdHlwZV9pbmRleCA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKEpDQ2xhc3NEZWNsKWZyYW1lKS5pbXBsZW1lbnRpbmcuaW5kZXhPZih0cmVlKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFR5cGVBbm5vdGF0aW9uUG9zaXRpb24KICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jbGFzc0V4dGVuZHMobG9jYXRpb24udG9MaXN0KCksIGN1cnJlbnRMYW1iZGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVfaW5kZXgsIGZyYW1lLnBvcyk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICgoKEpDQ2xhc3NEZWNsKWZyYW1lKS50eXBhcmFtcy5jb250YWlucyh0cmVlKSkgewogICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgcGFyYW1ldGVyX2luZGV4ID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoSkNDbGFzc0RlY2wpZnJhbWUpLnR5cGFyYW1zLmluZGV4T2YodHJlZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBUeXBlQW5ub3RhdGlvblBvc2l0aW9uCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAudHlwZVBhcmFtZXRlcihsb2NhdGlvbi50b0xpc3QoKSwgY3VycmVudExhbWJkYSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtZXRlcl9pbmRleCwgZnJhbWUucG9zKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoIkNvdWxkIG5vdCBkZXRlcm1pbmUgcG9zaXRpb24gb2YgdHJlZSAiICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyZWUgKyAiIHdpdGhpbiBmcmFtZSAiICsgZnJhbWUpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBjYXNlIE1FVEhPRDogewogICAgICAgICAgICAgICAgICAgIGZpbmFsIEpDTWV0aG9kRGVjbCBmcmFtZU1ldGhvZCA9IChKQ01ldGhvZERlY2wpIGZyYW1lOwogICAgICAgICAgICAgICAgICAgIGlmIChmcmFtZU1ldGhvZC50aHJvd24uY29udGFpbnModHJlZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IHR5cGVfaW5kZXggPSBmcmFtZU1ldGhvZC50aHJvd24uaW5kZXhPZih0cmVlKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFR5cGVBbm5vdGF0aW9uUG9zaXRpb24KICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5tZXRob2RUaHJvd3MobG9jYXRpb24udG9MaXN0KCksIGN1cnJlbnRMYW1iZGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVfaW5kZXgsIGZyYW1lLnBvcyk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChmcmFtZU1ldGhvZC5yZXN0eXBlID09IHRyZWUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFR5cGVBbm5vdGF0aW9uUG9zaXRpb24KICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5tZXRob2RSZXR1cm4obG9jYXRpb24udG9MaXN0KCksIGN1cnJlbnRMYW1iZGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZyYW1lLnBvcyk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChmcmFtZU1ldGhvZC50eXBhcmFtcy5jb250YWlucyh0cmVlKSkgewogICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgcGFyYW1ldGVyX2luZGV4ID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZyYW1lTWV0aG9kLnR5cGFyYW1zLmluZGV4T2YodHJlZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBUeXBlQW5ub3RhdGlvblBvc2l0aW9uCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAubWV0aG9kVHlwZVBhcmFtZXRlcihsb2NhdGlvbi50b0xpc3QoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRMYW1iZGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJhbWV0ZXJfaW5kZXgsIGZyYW1lLnBvcyk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCJDb3VsZCBub3QgZGV0ZXJtaW5lIHBvc2l0aW9uIG9mIHRyZWUgIiArIHRyZWUgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiB3aXRoaW4gZnJhbWUgIiArIGZyYW1lKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgY2FzZSBQQVJBTUVURVJJWkVEX1RZUEU6IHsKICAgICAgICAgICAgICAgICAgICBMaXN0PEpDVHJlZT4gbmV3UGF0aCA9IHBhdGgudGFpbDsKCiAgICAgICAgICAgICAgICAgICAgaWYgKCgoSkNUeXBlQXBwbHkpZnJhbWUpLmNsYXp6ID09IHRyZWUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gZ2VuZXJpYzogUkFXOyBub29wCiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICgoKEpDVHlwZUFwcGx5KWZyYW1lKS5hcmd1bWVudHMuY29udGFpbnModHJlZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgSkNUeXBlQXBwbHkgdGFmcmFtZSA9IChKQ1R5cGVBcHBseSkgZnJhbWU7CiAgICAgICAgICAgICAgICAgICAgICAgIGludCBhcmcgPSB0YWZyYW1lLmFyZ3VtZW50cy5pbmRleE9mKHRyZWUpOwogICAgICAgICAgICAgICAgICAgICAgICBsb2NhdGlvbiA9IGxvY2F0aW9uLnByZXBlbmQoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgVHlwZVBhdGhFbnRyeShUeXBlUGF0aEVudHJ5S2luZC5UWVBFX0FSR1VNRU5ULAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJnKSk7CgogICAgICAgICAgICAgICAgICAgICAgICBUeXBlIHR5cGVUb1VzZTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5ld1BhdGgudGFpbCAhPSBudWxsICYmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdQYXRoLnRhaWwuaGVhZC5oYXNUYWcoVGFnLk5FV0NMQVNTKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSWYgd2UgYXJlIHdpdGhpbiBhbiBhbm9ueW1vdXMgY2xhc3MKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGluc3RhbnRpYXRpb24sIHVzZSBpdHMgdHlwZSwgYmVjYXVzZSBpdAogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gY29udGFpbnMgYSBjb3JyZWN0bHkgbmVzdGVkIHR5cGUuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlVG9Vc2UgPSBuZXdQYXRoLnRhaWwuaGVhZC50eXBlOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZVRvVXNlID0gdGFmcmFtZS50eXBlOwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICBsb2NhdGlvbiA9IGxvY2F0ZU5lc3RlZFR5cGVzKHR5cGVUb1VzZSwgbG9jYXRpb24pOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigiQ291bGQgbm90IGRldGVybWluZSB0eXBlIGFyZ3VtZW50IHBvc2l0aW9uIG9mIHRyZWUgIiArIHRyZWUgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiB3aXRoaW4gZnJhbWUgIiArIGZyYW1lKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlRnJhbWUobmV3UGF0aC5oZWFkLCBuZXdQYXRoLnRhaWwuaGVhZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld1BhdGgsIGN1cnJlbnRMYW1iZGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdXRlcl90eXBlX2luZGV4LCBsb2NhdGlvbik7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgY2FzZSBNRU1CRVJfUkVGRVJFTkNFOiB7CiAgICAgICAgICAgICAgICAgICAgSkNNZW1iZXJSZWZlcmVuY2UgbXJmcmFtZSA9IChKQ01lbWJlclJlZmVyZW5jZSkgZnJhbWU7CgogICAgICAgICAgICAgICAgICAgIGlmIChtcmZyYW1lLmV4cHIgPT0gdHJlZSkgewogICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKG1yZnJhbWUubW9kZSkgewogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIElOVk9LRToKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBUeXBlQW5ub3RhdGlvblBvc2l0aW9uCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLm1ldGhvZFJlZihsb2NhdGlvbi50b0xpc3QoKSwgY3VycmVudExhbWJkYSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZyYW1lLnBvcyk7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgTkVXOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFR5cGVBbm5vdGF0aW9uUG9zaXRpb24KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY29uc3RydWN0b3JSZWYobG9jYXRpb24udG9MaXN0KCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRMYW1iZGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZyYW1lLnBvcyk7CiAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoIlVua25vd24gbWV0aG9kIHJlZmVyZW5jZSBtb2RlICIgKyBtcmZyYW1lLm1vZGUgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgZm9yIHRyZWUgIiArIHRyZWUgKyAiIHdpdGhpbiBmcmFtZSAiICsgZnJhbWUpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChtcmZyYW1lLnR5cGVhcmdzICE9IG51bGwgJiYKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1yZnJhbWUudHlwZWFyZ3MuY29udGFpbnModHJlZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IHR5cGVfaW5kZXggPSBtcmZyYW1lLnR5cGVhcmdzLmluZGV4T2YodHJlZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHN3aXRjaCAobXJmcmFtZS5tb2RlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgSU5WT0tFOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFR5cGVBbm5vdGF0aW9uUG9zaXRpb24KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAubWV0aG9kUmVmVHlwZUFyZyhsb2NhdGlvbi50b0xpc3QoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50TGFtYmRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVfaW5kZXgsIGZyYW1lLnBvcyk7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgTkVXOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFR5cGVBbm5vdGF0aW9uUG9zaXRpb24KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY29uc3RydWN0b3JSZWZUeXBlQXJnKGxvY2F0aW9uLnRvTGlzdCgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudExhbWJkYSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVfaW5kZXgsIGZyYW1lLnBvcyk7CiAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoIlVua25vd24gbWV0aG9kIHJlZmVyZW5jZSBtb2RlICIgKyBtcmZyYW1lLm1vZGUgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiIGZvciB0cmVlICIgKyB0cmVlICsgIiB3aXRoaW4gZnJhbWUgIiArIGZyYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigiQ291bGQgbm90IGRldGVybWluZSB0eXBlIGFyZ3VtZW50IHBvc2l0aW9uIG9mIHRyZWUgIiArIHRyZWUgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgd2l0aGluIGZyYW1lICIgKyBmcmFtZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGNhc2UgQVJSQVlfVFlQRTogewogICAgICAgICAgICAgICAgICAgIGxvY2F0aW9uID0gbG9jYXRpb24ucHJlcGVuZChUeXBlUGF0aEVudHJ5LkFSUkFZKTsKICAgICAgICAgICAgICAgICAgICBMaXN0PEpDVHJlZT4gbmV3UGF0aCA9IHBhdGgudGFpbDsKICAgICAgICAgICAgICAgICAgICB3aGlsZSAodHJ1ZSkgewogICAgICAgICAgICAgICAgICAgICAgICBKQ1RyZWUgbnBIZWFkID0gbmV3UGF0aC50YWlsLmhlYWQ7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChucEhlYWQuaGFzVGFnKEpDVHJlZS5UYWcuVFlQRUFSUkFZKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3UGF0aCA9IG5ld1BhdGgudGFpbDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvY2F0aW9uID0gbG9jYXRpb24ucHJlcGVuZChUeXBlUGF0aEVudHJ5LkFSUkFZKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChucEhlYWQuaGFzVGFnKEpDVHJlZS5UYWcuQU5OT1RBVEVEX1RZUEUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdQYXRoID0gbmV3UGF0aC50YWlsOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmVGcmFtZShuZXdQYXRoLmhlYWQsIG5ld1BhdGgudGFpbC5oZWFkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3UGF0aCwgY3VycmVudExhbWJkYSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG91dGVyX3R5cGVfaW5kZXgsIGxvY2F0aW9uKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBjYXNlIFRZUEVfUEFSQU1FVEVSOgogICAgICAgICAgICAgICAgICAgIGlmIChwYXRoLnRhaWwudGFpbC5oZWFkLmhhc1RhZyhKQ1RyZWUuVGFnLkNMQVNTREVGKSkgewogICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBKQ0NsYXNzRGVjbCBjbGF6eiA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoSkNDbGFzc0RlY2wpcGF0aC50YWlsLnRhaWwuaGVhZDsKICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IHBhcmFtZXRlcl9pbmRleCA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGF6ei50eXBhcmFtcy5pbmRleE9mKHBhdGgudGFpbC5oZWFkKTsKICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IGJvdW5kX2luZGV4ID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoSkNUeXBlUGFyYW1ldGVyKWZyYW1lKS5ib3VuZHMuZ2V0KDApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAudHlwZS5pc0ludGVyZmFjZSgpID8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoSkNUeXBlUGFyYW1ldGVyKWZyYW1lKS5ib3VuZHMuaW5kZXhPZih0cmVlKSArIDE6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKEpDVHlwZVBhcmFtZXRlcilmcmFtZSkuYm91bmRzLmluZGV4T2YodHJlZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBUeXBlQW5ub3RhdGlvblBvc2l0aW9uCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAudHlwZVBhcmFtZXRlckJvdW5kKGxvY2F0aW9uLnRvTGlzdCgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50TGFtYmRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJhbWV0ZXJfaW5kZXgsIGJvdW5kX2luZGV4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcmFtZS5wb3MpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocGF0aC50YWlsLnRhaWwuaGVhZC5oYXNUYWcoSkNUcmVlLlRhZy5NRVRIT0RERUYpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIEpDTWV0aG9kRGVjbCBtZXRob2QgPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgKEpDTWV0aG9kRGVjbClwYXRoLnRhaWwudGFpbC5oZWFkOwogICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgcGFyYW1ldGVyX2luZGV4ID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZC50eXBhcmFtcy5pbmRleE9mKHBhdGgudGFpbC5oZWFkKTsKICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IGJvdW5kX2luZGV4ID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoSkNUeXBlUGFyYW1ldGVyKWZyYW1lKS5ib3VuZHMuZ2V0KDApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAudHlwZS5pc0ludGVyZmFjZSgpID8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoSkNUeXBlUGFyYW1ldGVyKWZyYW1lKS5ib3VuZHMuaW5kZXhPZih0cmVlKSArIDE6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKEpDVHlwZVBhcmFtZXRlcilmcmFtZSkuYm91bmRzLmluZGV4T2YodHJlZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBUeXBlQW5ub3RhdGlvblBvc2l0aW9uCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAubWV0aG9kVHlwZVBhcmFtZXRlckJvdW5kKGxvY2F0aW9uLnRvTGlzdCgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50TGFtYmRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJhbWV0ZXJfaW5kZXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvdW5kX2luZGV4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcmFtZS5wb3MpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigiQ291bGQgbm90IGRldGVybWluZSBwb3NpdGlvbiBvZiB0cmVlICIgKyB0cmVlICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgd2l0aGluIGZyYW1lICIgKyBmcmFtZSk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGNhc2UgVkFSSUFCTEU6CiAgICAgICAgICAgICAgICAgICAgVmFyU3ltYm9sIHYgPSAoKEpDVmFyaWFibGVEZWNsKWZyYW1lKS5zeW07CiAgICAgICAgICAgICAgICAgICAgaWYgKHYuZ2V0S2luZCgpICE9IEVsZW1lbnRLaW5kLkZJRUxEKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHYub3duZXIuYXBwZW5kVW5pcXVlVHlwZUF0dHJpYnV0ZXModi5nZXRSYXdUeXBlQXR0cmlidXRlcygpKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgc3dpdGNoICh2LmdldEtpbmQoKSkgewogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIExPQ0FMX1ZBUklBQkxFOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFR5cGVBbm5vdGF0aW9uUG9zaXRpb24KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAubG9jYWxWYXJpYWJsZShsb2NhdGlvbi50b0xpc3QoKSwgY3VycmVudExhbWJkYSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcmFtZS5wb3MpOwogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIEZJRUxEOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFR5cGVBbm5vdGF0aW9uUG9zaXRpb24uZmllbGQobG9jYXRpb24udG9MaXN0KCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50TGFtYmRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJhbWUucG9zKTsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBQQVJBTUVURVI6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodi5nZXRRdWFsaWZpZWROYW1lKCkuZXF1YWxzKG5hbWVzLl90aGlzKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBUeXBlQW5ub3RhdGlvblBvc2l0aW9uCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5tZXRob2RSZWNlaXZlcihsb2NhdGlvbi50b0xpc3QoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRMYW1iZGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcmFtZS5wb3MpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgcGFyYW1ldGVyX2luZGV4ID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kUGFyYW1JbmRleChwYXRoLCBmcmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFR5cGVBbm5vdGF0aW9uUG9zaXRpb24KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLm1ldGhvZFBhcmFtZXRlcihsb2NhdGlvbi50b0xpc3QoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50TGFtYmRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtZXRlcl9pbmRleCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcmFtZS5wb3MpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIEVYQ0VQVElPTl9QQVJBTUVURVI6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gVHlwZUFubm90YXRpb25Qb3NpdGlvbgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5leGNlcHRpb25QYXJhbWV0ZXIobG9jYXRpb24udG9MaXN0KCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50TGFtYmRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJhbWUucG9zKTsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBSRVNPVVJDRV9WQVJJQUJMRToKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBUeXBlQW5ub3RhdGlvblBvc2l0aW9uCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnJlc291cmNlVmFyaWFibGUobG9jYXRpb24udG9MaXN0KCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudExhbWJkYSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcmFtZS5wb3MpOwogICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCJGb3VuZCB1bmV4cGVjdGVkIHR5cGUgYW5ub3RhdGlvbiBmb3IgdmFyaWFibGU6ICIgKyB2ICsgIiB3aXRoIGtpbmQ6ICIgKyB2LmdldEtpbmQoKSk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGNhc2UgQU5OT1RBVEVEX1RZUEU6IHsKICAgICAgICAgICAgICAgICAgICBpZiAoZnJhbWUgPT0gdHJlZSkgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBUaGlzIGlzIG9ubHkgdHJ1ZSBmb3IgdGhlIGZpcnN0IGFubm90YXRlZCB0eXBlIHdlIHNlZS4KICAgICAgICAgICAgICAgICAgICAgICAgLy8gRm9yIGFueSBvdGhlciBhbm5vdGF0ZWQgdHlwZXMgYWxvbmcgdGhlIHBhdGgsIHdlIGRvCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIG5vdCBjYXJlIGFib3V0IGlubmVyIHR5cGVzLgogICAgICAgICAgICAgICAgICAgICAgICBKQ0Fubm90YXRlZFR5cGUgYXR5cGV0cmVlID0gKEpDQW5ub3RhdGVkVHlwZSkgZnJhbWU7CiAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIFR5cGUgdXR5cGUgPSBhdHlwZXRyZWUudW5kZXJseWluZ1R5cGUudHlwZTsKICAgICAgICAgICAgICAgICAgICAgICAgQXNzZXJ0LmNoZWNrTm9uTnVsbCh1dHlwZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIFN5bWJvbCB0c3ltID0gdXR5cGUudHN5bTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRzeW0uZ2V0S2luZCgpLmVxdWFscyhFbGVtZW50S2luZC5UWVBFX1BBUkFNRVRFUikgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1dHlwZS5nZXRLaW5kKCkuZXF1YWxzKFR5cGVLaW5kLldJTERDQVJEKSB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHV0eXBlLmdldEtpbmQoKS5lcXVhbHMoVHlwZUtpbmQuQVJSQVkpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBUeXBlIHBhcmFtZXRlcnMsIHdpbGRjYXJkcywgYW5kIGFycmF5cyBoYXZlIHRoZSBkZWNsYXJpbmcKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNsYXNzL21ldGhvZCBhcyBlbmNsb3NpbmcgZWxlbWVudHMuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBUaGVyZSBpcyBhY3R1YWxseSBub3RoaW5nIHRvIGRvIGZvciB0aGVtLgogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9jYXRpb24gPSBsb2NhdGVOZXN0ZWRUeXBlcyh1dHlwZSwgbG9jYXRpb24pOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIExpc3Q8SkNUcmVlPiBuZXdQYXRoID0gcGF0aC50YWlsOwogICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlRnJhbWUobmV3UGF0aC5oZWFkLCBuZXdQYXRoLnRhaWwuaGVhZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld1BhdGgsIGN1cnJlbnRMYW1iZGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdXRlcl90eXBlX2luZGV4LCBsb2NhdGlvbik7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgY2FzZSBVTklPTl9UWVBFOiB7CiAgICAgICAgICAgICAgICAgICAgTGlzdDxKQ1RyZWU+IG5ld1BhdGggPSBwYXRoLnRhaWw7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmVGcmFtZShuZXdQYXRoLmhlYWQsIG5ld1BhdGgudGFpbC5oZWFkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3UGF0aCwgY3VycmVudExhbWJkYSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG91dGVyX3R5cGVfaW5kZXgsIGxvY2F0aW9uKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBjYXNlIElOVEVSU0VDVElPTl9UWVBFOiB7CiAgICAgICAgICAgICAgICAgICAgSkNUeXBlSW50ZXJzZWN0aW9uIGlzZWN0ID0gKEpDVHlwZUludGVyc2VjdGlvbilmcmFtZTsKICAgICAgICAgICAgICAgICAgICBmaW5hbCBMaXN0PEpDVHJlZT4gbmV3UGF0aCA9IHBhdGgudGFpbDsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZUZyYW1lKG5ld1BhdGguaGVhZCwgbmV3UGF0aC50YWlsLmhlYWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdQYXRoLCBjdXJyZW50TGFtYmRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNlY3QuYm91bmRzLmluZGV4T2YodHJlZSksIGxvY2F0aW9uKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBjYXNlIE1FVEhPRF9JTlZPQ0FUSU9OOiB7CiAgICAgICAgICAgICAgICAgICAgSkNNZXRob2RJbnZvY2F0aW9uIGludm9jYXRpb24gPSAoSkNNZXRob2RJbnZvY2F0aW9uKWZyYW1lOwogICAgICAgICAgICAgICAgICAgIGlmICghaW52b2NhdGlvbi50eXBlYXJncy5jb250YWlucyh0cmVlKSkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gVHlwZUFubm90YXRpb25Qb3NpdGlvbi51bmtub3duOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBNZXRob2RTeW1ib2wgZXhzeW0gPSAoTWV0aG9kU3ltYm9sKSBUcmVlSW5mby5zeW1ib2woaW52b2NhdGlvbi5nZXRNZXRob2RTZWxlY3QoKSk7CiAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IHR5cGVfaW5kZXggPSBpbnZvY2F0aW9uLnR5cGVhcmdzLmluZGV4T2YodHJlZSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKGV4c3ltID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCJjb3VsZCBub3QgZGV0ZXJtaW5lIHN5bWJvbCBmb3IgeyIgKyBpbnZvY2F0aW9uICsgIn0iKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGV4c3ltLmlzQ29uc3RydWN0b3IoKSkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gVHlwZUFubm90YXRpb25Qb3NpdGlvbgogICAgICAgICAgICAgICAgICAgICAgICAgICAgLmNvbnN0cnVjdG9ySW52b2NhdGlvblR5cGVBcmcobG9jYXRpb24udG9MaXN0KCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50TGFtYmRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZV9pbmRleCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludm9jYXRpb24ucG9zKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gVHlwZUFubm90YXRpb25Qb3NpdGlvbgogICAgICAgICAgICAgICAgICAgICAgICAgICAgLm1ldGhvZEludm9jYXRpb25UeXBlQXJnKGxvY2F0aW9uLnRvTGlzdCgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRMYW1iZGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZV9pbmRleCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnZvY2F0aW9uLnBvcyk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGNhc2UgRVhURU5EU19XSUxEQ0FSRDoKICAgICAgICAgICAgICAgIGNhc2UgU1VQRVJfV0lMRENBUkQ6IHsKICAgICAgICAgICAgICAgICAgICAvLyBBbm5vdGF0aW9ucyBpbiB3aWxkY2FyZCBib3VuZHMKICAgICAgICAgICAgICAgICAgICBmaW5hbCBMaXN0PEpDVHJlZT4gbmV3UGF0aCA9IHBhdGgudGFpbDsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZUZyYW1lKG5ld1BhdGguaGVhZCwgbmV3UGF0aC50YWlsLmhlYWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdQYXRoLCBjdXJyZW50TGFtYmRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3V0ZXJfdHlwZV9pbmRleCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvY2F0aW9uLnByZXBlbmQoVHlwZVBhdGhFbnRyeS5XSUxEQ0FSRCkpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGNhc2UgTUVNQkVSX1NFTEVDVDogewogICAgICAgICAgICAgICAgICAgIGZpbmFsIExpc3Q8SkNUcmVlPiBuZXdQYXRoID0gcGF0aC50YWlsOwogICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlRnJhbWUobmV3UGF0aC5oZWFkLCBuZXdQYXRoLnRhaWwuaGVhZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld1BhdGgsIGN1cnJlbnRMYW1iZGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdXRlcl90eXBlX2luZGV4LCBsb2NhdGlvbik7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoIlVucmVzb2x2ZWQgZnJhbWU6ICIgKyBmcmFtZSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgb2Yga2luZDogIiArIGZyYW1lLmdldEtpbmQoKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJcbiAgICBMb29raW5nIGZvciB0cmVlOiAiICsgdHJlZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHByaXZhdGUgTGlzdEJ1ZmZlcjxUeXBlUGF0aEVudHJ5PgogICAgICAgICAgICBsb2NhdGVOZXN0ZWRUeXBlcyhUeXBlIHR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExpc3RCdWZmZXI8VHlwZVBhdGhFbnRyeT4gZGVwdGgpIHsKICAgICAgICAgICAgVHlwZSBlbmNsID0gdHlwZS5nZXRFbmNsb3NpbmdUeXBlKCk7CiAgICAgICAgICAgIHdoaWxlIChlbmNsICE9IG51bGwgJiYKICAgICAgICAgICAgICAgICAgICBlbmNsLmdldEtpbmQoKSAhPSBUeXBlS2luZC5OT05FICYmCiAgICAgICAgICAgICAgICAgICAgZW5jbC5nZXRLaW5kKCkgIT0gVHlwZUtpbmQuRVJST1IpIHsKICAgICAgICAgICAgICAgIGRlcHRoID0gZGVwdGgucHJlcGVuZChUeXBlUGF0aEVudHJ5LklOTkVSX1RZUEUpOwogICAgICAgICAgICAgICAgZW5jbCA9IGVuY2wuZ2V0RW5jbG9zaW5nVHlwZSgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBkZXB0aDsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgaW50IG1ldGhvZFBhcmFtSW5kZXgoTGlzdDxKQ1RyZWU+IHBhdGgsIEpDVHJlZSBwYXJhbSkgewogICAgICAgICAgICBMaXN0PEpDVHJlZT4gY3VyciA9IHBhdGg7CiAgICAgICAgICAgIHdoaWxlIChjdXJyLmhlYWQuZ2V0VGFnKCkgIT0gVGFnLk1FVEhPRERFRiAmJgogICAgICAgICAgICAgICAgICAgIGN1cnIuaGVhZC5nZXRUYWcoKSAhPSBUYWcuTEFNQkRBKSB7CiAgICAgICAgICAgICAgICBjdXJyID0gY3Vyci50YWlsOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChjdXJyLmhlYWQuZ2V0VGFnKCkgPT0gVGFnLk1FVEhPRERFRikgewogICAgICAgICAgICAgICAgSkNNZXRob2REZWNsIG1ldGhvZCA9IChKQ01ldGhvZERlY2wpY3Vyci5oZWFkOwogICAgICAgICAgICAgICAgcmV0dXJuIG1ldGhvZC5wYXJhbXMuaW5kZXhPZihwYXJhbSk7CiAgICAgICAgICAgIH0gZWxzZSBpZiAoY3Vyci5oZWFkLmdldFRhZygpID09IFRhZy5MQU1CREEpIHsKICAgICAgICAgICAgICAgIEpDTGFtYmRhIGxhbWJkYSA9IChKQ0xhbWJkYSljdXJyLmhlYWQ7CiAgICAgICAgICAgICAgICByZXR1cm4gbGFtYmRhLnBhcmFtcy5pbmRleE9mKHBhcmFtKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIEFzc2VydC5lcnJvcigibWV0aG9kUGFyYW1JbmRleCBleHBlY3RlZCB0byBmaW5kIG1ldGhvZCBvciBsYW1iZGEgZm9yIHBhcmFtOiAiICsgcGFyYW0pOwogICAgICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBFYWNoIGNsYXNzIChpbmNsdWRpbmcgZW5jbG9zZWQgaW5uZXIgY2xhc3NlcykgaXMgdmlzaXRlZCBzZXBhcmF0ZWx5LgogICAgICAgIC8vIFRoaXMgZmxhZyBpcyB1c2VkIHRvIHByZXZlbnQgZnJvbSB2aXNpdGluZyBpbm5lciBjbGFzc2VzLgogICAgICAgIHByaXZhdGUgYm9vbGVhbiBpc0luQ2xhc3MgPSBmYWxzZTsKCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRDbGFzc0RlZihKQ0NsYXNzRGVjbCB0cmVlKSB7CiAgICAgICAgICAgIGlmIChpc0luQ2xhc3MpCiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIGlzSW5DbGFzcyA9IHRydWU7CgogICAgICAgICAgICBpZiAoc2lnT25seSkgewogICAgICAgICAgICAgICAgc2Nhbih0cmVlLm1vZHMpOwogICAgICAgICAgICAgICAgc2Nhbih0cmVlLnR5cGFyYW1zKTsKICAgICAgICAgICAgICAgIHNjYW4odHJlZS5leHRlbmRpbmcpOwogICAgICAgICAgICAgICAgc2Nhbih0cmVlLmltcGxlbWVudGluZyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc2Nhbih0cmVlLmRlZnMpOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogUmVzb2x2ZSBkZWNsYXJhdGlvbiB2cy4gdHlwZSBhbm5vdGF0aW9ucyBpbiBtZXRob2RzIGFuZAogICAgICAgICAqIHRoZW4gZGV0ZXJtaW5lIHRoZSBwb3NpdGlvbnMuCiAgICAgICAgICovCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRNZXRob2REZWYoZmluYWwgSkNNZXRob2REZWNsIHRyZWUpIHsKICAgICAgICAgICAgaWYgKHRyZWUuc3ltID09IG51bGwpIHsKICAgICAgICAgICAgICAgIEFzc2VydC5lcnJvcigiVmlzaXRpbmcgdHJlZSBub2RlIGJlZm9yZSBtZW1iZXJFbnRlciIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChzaWdPbmx5KSB7CiAgICAgICAgICAgICAgICBpZiAoIXRyZWUubW9kcy5hbm5vdGF0aW9ucy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICAgICAgICBpZiAodHJlZS5zeW0uaXNDb25zdHJ1Y3RvcigpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIFR5cGVBbm5vdGF0aW9uUG9zaXRpb24gcG9zID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIFR5cGVBbm5vdGF0aW9uUG9zaXRpb24ubWV0aG9kUmV0dXJuKHRyZWUucG9zKTsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gVXNlIG51bGwgdG8gbWFyayB0aGF0IHRoZSBhbm5vdGF0aW9ucyBnbwogICAgICAgICAgICAgICAgICAgICAgICAvLyB3aXRoIHRoZSBzeW1ib2wuCiAgICAgICAgICAgICAgICAgICAgICAgIHNlcGFyYXRlQW5ub3RhdGlvbnNLaW5kcyh0cmVlLCBudWxsLCB0cmVlLnN5bSwgcG9zKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBUeXBlQW5ub3RhdGlvblBvc2l0aW9uIHBvcyA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBUeXBlQW5ub3RhdGlvblBvc2l0aW9uLm1ldGhvZFJldHVybih0cmVlLnJlc3R5cGUucG9zKTsKICAgICAgICAgICAgICAgICAgICAgICAgc2VwYXJhdGVBbm5vdGF0aW9uc0tpbmRzKHRyZWUucmVzdHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyZWUuc3ltLnR5cGUuZ2V0UmV0dXJuVHlwZSgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJlZS5zeW0sIHBvcyk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKHRyZWUucmVjdnBhcmFtICE9IG51bGwgJiYgdHJlZS5yZWN2cGFyYW0uc3ltICE9IG51bGwgJiYKICAgICAgICAgICAgICAgICAgICAgICAgIXRyZWUucmVjdnBhcmFtLm1vZHMuYW5ub3RhdGlvbnMuaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gTm90aGluZyB0byBkbyBmb3Igc2VwYXJhdGVBbm5vdGF0aW9uc0tpbmRzIGlmCiAgICAgICAgICAgICAgICAgICAgLy8gdGhlcmUgYXJlIG5vIGFubm90YXRpb25zIG9mIGVpdGhlciBraW5kLgogICAgICAgICAgICAgICAgICAgIC8vIFRPRE86IG1ha2Ugc3VyZSB0aGVyZSBhcmUgbm8gZGVjbGFyYXRpb24gYW5ub3RhdGlvbnMuCiAgICAgICAgICAgICAgICAgICAgZmluYWwgVHlwZUFubm90YXRpb25Qb3NpdGlvbiBwb3MgPSBUeXBlQW5ub3RhdGlvblBvc2l0aW9uLm1ldGhvZFJlY2VpdmVyKHRyZWUucmVjdnBhcmFtLnZhcnR5cGUucG9zKTsKICAgICAgICAgICAgICAgICAgICBwdXNoKHRyZWUucmVjdnBhcmFtKTsKICAgICAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgICAgICBzZXBhcmF0ZUFubm90YXRpb25zS2luZHModHJlZS5yZWN2cGFyYW0udmFydHlwZSwgdHJlZS5yZWN2cGFyYW0uc3ltLnR5cGUsIHRyZWUucmVjdnBhcmFtLnN5bSwgcG9zKTsKICAgICAgICAgICAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAgICAgICAgICAgICBwb3AoKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnQgaSA9IDA7CiAgICAgICAgICAgICAgICBmb3IgKEpDVmFyaWFibGVEZWNsIHBhcmFtIDogdHJlZS5wYXJhbXMpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoIXBhcmFtLm1vZHMuYW5ub3RhdGlvbnMuaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIE5vdGhpbmcgdG8gZG8gZm9yIHNlcGFyYXRlQW5ub3RhdGlvbnNLaW5kcyBpZgogICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGVyZSBhcmUgbm8gYW5ub3RhdGlvbnMgb2YgZWl0aGVyIGtpbmQuCiAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIFR5cGVBbm5vdGF0aW9uUG9zaXRpb24gcG9zID0gVHlwZUFubm90YXRpb25Qb3NpdGlvbi5tZXRob2RQYXJhbWV0ZXIoaSwgcGFyYW0udmFydHlwZS5wb3MpOwogICAgICAgICAgICAgICAgICAgICAgICBwdXNoKHBhcmFtKTsKICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlcGFyYXRlQW5ub3RhdGlvbnNLaW5kcyhwYXJhbS52YXJ0eXBlLCBwYXJhbS5zeW0udHlwZSwgcGFyYW0uc3ltLCBwb3MpOwogICAgICAgICAgICAgICAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9wKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgKytpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoc2lnT25seSkgewogICAgICAgICAgICAgICAgc2Nhbih0cmVlLm1vZHMpOwogICAgICAgICAgICAgICAgc2Nhbih0cmVlLnJlc3R5cGUpOwogICAgICAgICAgICAgICAgc2Nhbih0cmVlLnR5cGFyYW1zKTsKICAgICAgICAgICAgICAgIHNjYW4odHJlZS5yZWN2cGFyYW0pOwogICAgICAgICAgICAgICAgc2Nhbih0cmVlLnBhcmFtcyk7CiAgICAgICAgICAgICAgICBzY2FuKHRyZWUudGhyb3duKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHNjYW4odHJlZS5kZWZhdWx0VmFsdWUpOwogICAgICAgICAgICAgICAgc2Nhbih0cmVlLmJvZHkpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvKiBTdG9yZSBhIHJlZmVyZW5jZSB0byB0aGUgY3VycmVudCBsYW1iZGEgZXhwcmVzc2lvbiwgdG8KICAgICAgICAgKiBiZSB1c2VkIGJ5IGFsbCB0eXBlIGFubm90YXRpb25zIHdpdGhpbiB0aGlzIGV4cHJlc3Npb24uCiAgICAgICAgICovCiAgICAgICAgcHJpdmF0ZSBKQ0xhbWJkYSBjdXJyZW50TGFtYmRhID0gbnVsbDsKCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRMYW1iZGEoSkNMYW1iZGEgdHJlZSkgewogICAgICAgICAgICBKQ0xhbWJkYSBwcmV2TGFtYmRhID0gY3VycmVudExhbWJkYTsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIGN1cnJlbnRMYW1iZGEgPSB0cmVlOwoKICAgICAgICAgICAgICAgIGludCBpID0gMDsKICAgICAgICAgICAgICAgIGZvciAoSkNWYXJpYWJsZURlY2wgcGFyYW0gOiB0cmVlLnBhcmFtcykgewogICAgICAgICAgICAgICAgICAgIGlmICghcGFyYW0ubW9kcy5hbm5vdGF0aW9ucy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gTm90aGluZyB0byBkbyBmb3Igc2VwYXJhdGVBbm5vdGF0aW9uc0tpbmRzIGlmCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRoZXJlIGFyZSBubyBhbm5vdGF0aW9ucyBvZiBlaXRoZXIga2luZC4KICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgVHlwZUFubm90YXRpb25Qb3NpdGlvbiBwb3MgPSAgVHlwZUFubm90YXRpb25Qb3NpdGlvbgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5tZXRob2RQYXJhbWV0ZXIodHJlZSwgaSwgcGFyYW0udmFydHlwZS5wb3MpOwogICAgICAgICAgICAgICAgICAgICAgICBwdXNoKHBhcmFtKTsKICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlcGFyYXRlQW5ub3RhdGlvbnNLaW5kcyhwYXJhbS52YXJ0eXBlLCBwYXJhbS5zeW0udHlwZSwgcGFyYW0uc3ltLCBwb3MpOwogICAgICAgICAgICAgICAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9wKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgKytpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHNjYW4odHJlZS5ib2R5KTsKICAgICAgICAgICAgICAgIHNjYW4odHJlZS5wYXJhbXMpOwogICAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAgICAgY3VycmVudExhbWJkYSA9IHByZXZMYW1iZGE7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIFJlc29sdmUgZGVjbGFyYXRpb24gdnMuIHR5cGUgYW5ub3RhdGlvbnMgaW4gdmFyaWFibGUgZGVjbGFyYXRpb25zIGFuZAogICAgICAgICAqIHRoZW4gZGV0ZXJtaW5lIHRoZSBwb3NpdGlvbnMuCiAgICAgICAgICovCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRWYXJEZWYoZmluYWwgSkNWYXJpYWJsZURlY2wgdHJlZSkgewogICAgICAgICAgICBpZiAodHJlZS5tb2RzLmFubm90YXRpb25zLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgICAgLy8gTm90aGluZyB0byBkbyBmb3Igc2VwYXJhdGVBbm5vdGF0aW9uc0tpbmRzIGlmCiAgICAgICAgICAgICAgICAvLyB0aGVyZSBhcmUgbm8gYW5ub3RhdGlvbnMgb2YgZWl0aGVyIGtpbmQuCiAgICAgICAgICAgIH0gZWxzZSBpZiAodHJlZS5zeW0gPT0gbnVsbCkgewogICAgICAgICAgICAgICAgQXNzZXJ0LmVycm9yKCJWaXNpdGluZyB0cmVlIG5vZGUgYmVmb3JlIG1lbWJlckVudGVyIik7CiAgICAgICAgICAgIH0gZWxzZSBpZiAodHJlZS5zeW0uZ2V0S2luZCgpID09IEVsZW1lbnRLaW5kLlBBUkFNRVRFUikgewogICAgICAgICAgICAgICAgLy8gUGFyYW1ldGVycyBhcmUgaGFuZGxlZCBpbiB2aXNpdE1ldGhvZERlZiBvciB2aXNpdExhbWJkYS4KICAgICAgICAgICAgfSBlbHNlIGlmICh0cmVlLnN5bS5nZXRLaW5kKCkgPT0gRWxlbWVudEtpbmQuRklFTEQpIHsKICAgICAgICAgICAgICAgIGlmIChzaWdPbmx5KSB7CiAgICAgICAgICAgICAgICAgICAgVHlwZUFubm90YXRpb25Qb3NpdGlvbiBwb3MgPQogICAgICAgICAgICAgICAgICAgICAgICBUeXBlQW5ub3RhdGlvblBvc2l0aW9uLmZpZWxkKHRyZWUucG9zKTsKICAgICAgICAgICAgICAgICAgICBzZXBhcmF0ZUFubm90YXRpb25zS2luZHModHJlZS52YXJ0eXBlLCB0cmVlLnN5bS50eXBlLCB0cmVlLnN5bSwgcG9zKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIGlmICh0cmVlLnN5bS5nZXRLaW5kKCkgPT0gRWxlbWVudEtpbmQuTE9DQUxfVkFSSUFCTEUpIHsKICAgICAgICAgICAgICAgIGZpbmFsIFR5cGVBbm5vdGF0aW9uUG9zaXRpb24gcG9zID0KICAgICAgICAgICAgICAgICAgICBUeXBlQW5ub3RhdGlvblBvc2l0aW9uLmxvY2FsVmFyaWFibGUoY3VycmVudExhbWJkYSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJlZS5wb3MpOwogICAgICAgICAgICAgICAgc2VwYXJhdGVBbm5vdGF0aW9uc0tpbmRzKHRyZWUudmFydHlwZSwgdHJlZS5zeW0udHlwZSwgdHJlZS5zeW0sIHBvcyk7CiAgICAgICAgICAgIH0gZWxzZSBpZiAodHJlZS5zeW0uZ2V0S2luZCgpID09IEVsZW1lbnRLaW5kLkVYQ0VQVElPTl9QQVJBTUVURVIpIHsKICAgICAgICAgICAgICAgIGZpbmFsIFR5cGVBbm5vdGF0aW9uUG9zaXRpb24gcG9zID0KICAgICAgICAgICAgICAgICAgICBUeXBlQW5ub3RhdGlvblBvc2l0aW9uLmV4Y2VwdGlvblBhcmFtZXRlcihjdXJyZW50TGFtYmRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyZWUucG9zKTsKICAgICAgICAgICAgICAgIHNlcGFyYXRlQW5ub3RhdGlvbnNLaW5kcyh0cmVlLnZhcnR5cGUsIHRyZWUuc3ltLnR5cGUsIHRyZWUuc3ltLCBwb3MpOwogICAgICAgICAgICB9IGVsc2UgaWYgKHRyZWUuc3ltLmdldEtpbmQoKSA9PSBFbGVtZW50S2luZC5SRVNPVVJDRV9WQVJJQUJMRSkgewogICAgICAgICAgICAgICAgZmluYWwgVHlwZUFubm90YXRpb25Qb3NpdGlvbiBwb3MgPQogICAgICAgICAgICAgICAgICAgIFR5cGVBbm5vdGF0aW9uUG9zaXRpb24ucmVzb3VyY2VWYXJpYWJsZShjdXJyZW50TGFtYmRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmVlLnBvcyk7CiAgICAgICAgICAgICAgICBzZXBhcmF0ZUFubm90YXRpb25zS2luZHModHJlZS52YXJ0eXBlLCB0cmVlLnN5bS50eXBlLCB0cmVlLnN5bSwgcG9zKTsKICAgICAgICAgICAgfSBlbHNlIGlmICh0cmVlLnN5bS5nZXRLaW5kKCkgPT0gRWxlbWVudEtpbmQuRU5VTV9DT05TVEFOVCkgewogICAgICAgICAgICAgICAgLy8gTm8gdHlwZSBhbm5vdGF0aW9ucyBjYW4gb2NjdXIgaGVyZS4KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIC8vIFRoZXJlIGlzIG5vdGhpbmcgZWxzZSBpbiBhIHZhcmlhYmxlIGRlY2xhcmF0aW9uIHRoYXQgbmVlZHMgc2VwYXJhdGlvbi4KICAgICAgICAgICAgICAgIEFzc2VydC5lcnJvcigiVW5oYW5kbGVkIHZhcmlhYmxlIGtpbmQiKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgc2Nhbih0cmVlLm1vZHMpOwogICAgICAgICAgICBzY2FuKHRyZWUudmFydHlwZSk7CiAgICAgICAgICAgIGlmICghc2lnT25seSkgewogICAgICAgICAgICAgICAgc2Nhbih0cmVlLmluaXQpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdEJsb2NrKEpDQmxvY2sgdHJlZSkgewogICAgICAgICAgICAvLyBEbyBub3QgZGVzY2VuZCBpbnRvIHRvcC1sZXZlbCBibG9ja3Mgd2hlbiBvbmx5IGludGVyZXN0ZWQKICAgICAgICAgICAgLy8gaW4gdGhlIHNpZ25hdHVyZS4KICAgICAgICAgICAgaWYgKCFzaWdPbmx5KSB7CiAgICAgICAgICAgICAgICBzY2FuKHRyZWUuc3RhdHMpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdEFubm90YXRlZFR5cGUoSkNBbm5vdGF0ZWRUeXBlIHRyZWUpIHsKICAgICAgICAgICAgcHVzaCh0cmVlKTsKICAgICAgICAgICAgZmluZFBvc2l0aW9uKHRyZWUsIHRyZWUsIHRyZWUuYW5ub3RhdGlvbnMpOwogICAgICAgICAgICBwb3AoKTsKICAgICAgICAgICAgc3VwZXIudmlzaXRBbm5vdGF0ZWRUeXBlKHRyZWUpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRUeXBlUGFyYW1ldGVyKEpDVHlwZVBhcmFtZXRlciB0cmVlKSB7CiAgICAgICAgICAgIGZpbmRQb3NpdGlvbih0cmVlLCBwZWVrMigpLCB0cmVlLmFubm90YXRpb25zKTsKICAgICAgICAgICAgc3VwZXIudmlzaXRUeXBlUGFyYW1ldGVyKHRyZWUpOwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSB2b2lkIGNvcHlOZXdDbGFzc0Fubm90YXRpb25zVG9Pd25lcihKQ05ld0NsYXNzIHRyZWUpIHsKICAgICAgICAgICAgU3ltYm9sIHN5bSA9IHRyZWUuZGVmLnN5bTsKICAgICAgICAgICAgZmluYWwgVHlwZUFubm90YXRpb25Qb3NpdGlvbiBwb3MgPQogICAgICAgICAgICAgICAgVHlwZUFubm90YXRpb25Qb3NpdGlvbi5uZXdPYmoodHJlZS5wb3MpOwogICAgICAgICAgICBMaXN0QnVmZmVyPEF0dHJpYnV0ZS5UeXBlQ29tcG91bmQ+IG5ld2F0dHJzID0gbmV3IExpc3RCdWZmZXI8PigpOwoKICAgICAgICAgICAgZm9yIChBdHRyaWJ1dGUuVHlwZUNvbXBvdW5kIG9sZCA6IHN5bS5nZXRSYXdUeXBlQXR0cmlidXRlcygpKSB7CiAgICAgICAgICAgICAgICBuZXdhdHRycy5hcHBlbmQobmV3IEF0dHJpYnV0ZS5UeXBlQ29tcG91bmQob2xkLnR5cGUsIG9sZC52YWx1ZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9zKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHN5bS5vd25lci5hcHBlbmRVbmlxdWVUeXBlQXR0cmlidXRlcyhuZXdhdHRycy50b0xpc3QoKSk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdE5ld0NsYXNzKEpDTmV3Q2xhc3MgdHJlZSkgewogICAgICAgICAgICBpZiAodHJlZS5kZWYgIT0gbnVsbCAmJgogICAgICAgICAgICAgICAgICAgICF0cmVlLmRlZi5tb2RzLmFubm90YXRpb25zLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgICAgSkNDbGFzc0RlY2wgY2xhc3NkZWNsID0gdHJlZS5kZWY7CiAgICAgICAgICAgICAgICBUeXBlQW5ub3RhdGlvblBvc2l0aW9uIHBvczsKCiAgICAgICAgICAgICAgICBpZiAoY2xhc3NkZWNsLmV4dGVuZGluZyA9PSB0cmVlLmNsYXp6KSB7CiAgICAgICAgICAgICAgICAgICAgcG9zID0gVHlwZUFubm90YXRpb25Qb3NpdGlvbi5jbGFzc0V4dGVuZHModHJlZS5wb3MpOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjbGFzc2RlY2wuaW1wbGVtZW50aW5nLmNvbnRhaW5zKHRyZWUuY2xhenopKSB7CiAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IGluZGV4ID0gY2xhc3NkZWNsLmltcGxlbWVudGluZy5pbmRleE9mKHRyZWUuY2xhenopOwogICAgICAgICAgICAgICAgICAgIHBvcyA9IFR5cGVBbm5vdGF0aW9uUG9zaXRpb24uY2xhc3NFeHRlbmRzKGluZGV4LCB0cmVlLnBvcyk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIC8vIEluIGNvbnRyYXN0IHRvIENMQVNTIGVsc2V3aGVyZSwgdHlwYXJhbXMgY2Fubm90IG9jY3VyIGhlcmUuCiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCJDb3VsZCBub3QgZGV0ZXJtaW5lIHBvc2l0aW9uIG9mIHRyZWUgIiArIHRyZWUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgVHlwZSBiZWZvcmUgPSBjbGFzc2RlY2wuc3ltLnR5cGU7CiAgICAgICAgICAgICAgICBzZXBhcmF0ZUFubm90YXRpb25zS2luZHMoY2xhc3NkZWNsLCB0cmVlLmNsYXp6LnR5cGUsIGNsYXNzZGVjbC5zeW0sIHBvcyk7CiAgICAgICAgICAgICAgICBjb3B5TmV3Q2xhc3NBbm5vdGF0aW9uc1RvT3duZXIodHJlZSk7CiAgICAgICAgICAgICAgICAvLyBjbGFzc2RlY2wuc3ltLnR5cGUgbm93IGNvbnRhaW5zIGFuIGFubm90YXRlZCB0eXBlLCB3aGljaAogICAgICAgICAgICAgICAgLy8gaXMgbm90IHdoYXQgd2Ugd2FudCB0aGVyZS4KICAgICAgICAgICAgICAgIC8vIFRPRE86IHNob3VsZCB3ZSBwdXQgdGhpcyB0eXBlIHNvbWV3aGVyZSBpbiB0aGUgc3VwZXJjbGFzcy9pbnRlcmZhY2U/CiAgICAgICAgICAgICAgICBjbGFzc2RlY2wuc3ltLnR5cGUgPSBiZWZvcmU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHNjYW4odHJlZS5lbmNsKTsKICAgICAgICAgICAgc2Nhbih0cmVlLnR5cGVhcmdzKTsKICAgICAgICAgICAgaWYgKHRyZWUuZGVmID09IG51bGwpIHsKICAgICAgICAgICAgICAgIHNjYW4odHJlZS5jbGF6eik7CiAgICAgICAgICAgIH0gLy8gZWxzZSBzdXBlciB0eXBlIHdpbGwgYWxyZWFkeSBoYXZlIGJlZW4gc2Nhbm5lZCBpbiB0aGUgY29udGV4dCBvZiB0aGUgYW5vbnltb3VzIGNsYXNzLgogICAgICAgICAgICBzY2FuKHRyZWUuYXJncyk7CgogICAgICAgICAgICAvLyBUaGUgY2xhc3MgYm9keSB3aWxsIGFscmVhZHkgYmUgc2Nhbm5lZC4KICAgICAgICAgICAgLy8gc2Nhbih0cmVlLmRlZik7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdE5ld0FycmF5KEpDTmV3QXJyYXkgdHJlZSkgewogICAgICAgICAgICBmaW5kUG9zaXRpb24odHJlZSwgdHJlZSwgdHJlZS5hbm5vdGF0aW9ucyk7CiAgICAgICAgICAgIGludCBkaW1Bbm5vc0NvdW50ID0gdHJlZS5kaW1Bbm5vdGF0aW9ucy5zaXplKCk7CiAgICAgICAgICAgIExpc3RCdWZmZXI8VHlwZVBhdGhFbnRyeT4gZGVwdGggPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CgogICAgICAgICAgICAvLyBoYW5kbGUgYW5ub3RhdGlvbnMgYXNzb2NpYXRlZCB3aXRoIGRpbWVuc2lvbnMKICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBkaW1Bbm5vc0NvdW50OyArK2kpIHsKICAgICAgICAgICAgICAgIExpc3RCdWZmZXI8VHlwZVBhdGhFbnRyeT4gbG9jYXRpb24gPQogICAgICAgICAgICAgICAgICAgIG5ldyBMaXN0QnVmZmVyPFR5cGVQYXRoRW50cnk+KCk7CiAgICAgICAgICAgICAgICBpZiAoaSAhPSAwKSB7CiAgICAgICAgICAgICAgICAgICAgZGVwdGggPSBkZXB0aC5hcHBlbmQoVHlwZVBhdGhFbnRyeS5BUlJBWSk7CiAgICAgICAgICAgICAgICAgICAgbG9jYXRpb24gPSBsb2NhdGlvbi5hcHBlbmRMaXN0KGRlcHRoLnRvTGlzdCgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGZpbmFsIFR5cGVBbm5vdGF0aW9uUG9zaXRpb24gcCA9CiAgICAgICAgICAgICAgICAgICAgVHlwZUFubm90YXRpb25Qb3NpdGlvbi5uZXdPYmoobG9jYXRpb24udG9MaXN0KCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudExhbWJkYSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmVlLnBvcyk7CgogICAgICAgICAgICAgICAgc2V0VHlwZUFubm90YXRpb25Qb3ModHJlZS5kaW1Bbm5vdGF0aW9ucy5nZXQoaSksIHApOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBoYW5kbGUgImZyZWUiIGFubm90YXRpb25zCiAgICAgICAgICAgIC8vIGludCBpID0gZGltQW5ub3NDb3VudCA9PSAwID8gMCA6IGRpbUFubm9zQ291bnQgLSAxOwogICAgICAgICAgICAvLyBUT0RPOiBpcyBkZXB0aC5zaXplID09IGkgaGVyZT8KICAgICAgICAgICAgSkNFeHByZXNzaW9uIGVsZW1UeXBlID0gdHJlZS5lbGVtdHlwZTsKICAgICAgICAgICAgZGVwdGggPSBkZXB0aC5hcHBlbmQoVHlwZVBhdGhFbnRyeS5BUlJBWSk7CiAgICAgICAgICAgIHdoaWxlIChlbGVtVHlwZSAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICBpZiAoZWxlbVR5cGUuaGFzVGFnKEpDVHJlZS5UYWcuQU5OT1RBVEVEX1RZUEUpKSB7CiAgICAgICAgICAgICAgICAgICAgSkNBbm5vdGF0ZWRUeXBlIGF0ID0gKEpDQW5ub3RhdGVkVHlwZSllbGVtVHlwZTsKICAgICAgICAgICAgICAgICAgICBmaW5hbCBMaXN0QnVmZmVyPFR5cGVQYXRoRW50cnk+IGxvY2F0aW9uYnVmID0KICAgICAgICAgICAgICAgICAgICAgICAgbG9jYXRlTmVzdGVkVHlwZXMoZWxlbVR5cGUudHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IExpc3RCdWZmZXI8VHlwZVBhdGhFbnRyeT4oKSk7CiAgICAgICAgICAgICAgICAgICAgZmluYWwgTGlzdDxUeXBlUGF0aEVudHJ5PiBsb2NhdGlvbiA9CiAgICAgICAgICAgICAgICAgICAgICAgIGxvY2F0aW9uYnVmLnRvTGlzdCgpLnByZXBlbmRMaXN0KGRlcHRoLnRvTGlzdCgpKTsKICAgICAgICAgICAgICAgICAgICBmaW5hbCBUeXBlQW5ub3RhdGlvblBvc2l0aW9uIHAgPQogICAgICAgICAgICAgICAgICAgICAgICBUeXBlQW5ub3RhdGlvblBvc2l0aW9uLm5ld09iaihsb2NhdGlvbiwgY3VycmVudExhbWJkYSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJlZS5wb3MpOwogICAgICAgICAgICAgICAgICAgIHNldFR5cGVBbm5vdGF0aW9uUG9zKGF0LmFubm90YXRpb25zLCBwKTsKICAgICAgICAgICAgICAgICAgICBlbGVtVHlwZSA9IGF0LnVuZGVybHlpbmdUeXBlOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChlbGVtVHlwZS5oYXNUYWcoSkNUcmVlLlRhZy5UWVBFQVJSQVkpKSB7CiAgICAgICAgICAgICAgICAgICAgZGVwdGggPSBkZXB0aC5hcHBlbmQoVHlwZVBhdGhFbnRyeS5BUlJBWSk7CiAgICAgICAgICAgICAgICAgICAgZWxlbVR5cGUgPSAoKEpDQXJyYXlUeXBlVHJlZSllbGVtVHlwZSkuZWxlbXR5cGU7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGVsZW1UeXBlLmhhc1RhZyhKQ1RyZWUuVGFnLlNFTEVDVCkpIHsKICAgICAgICAgICAgICAgICAgICBlbGVtVHlwZSA9ICgoSkNGaWVsZEFjY2VzcyllbGVtVHlwZSkuc2VsZWN0ZWQ7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHNjYW4odHJlZS5lbGVtcyk7CiAgICAgICAgfQoKCiAgICAgICAgcHJpdmF0ZSB2b2lkIGZpbmRUeXBlQ29tcG91bmRQb3NpdGlvbihKQ1RyZWUgdHJlZSwgSkNUcmVlIGZyYW1lLCBMaXN0PEF0dHJpYnV0ZS5UeXBlQ29tcG91bmQ+IGFubm90YXRpb25zKSB7CiAgICAgICAgICAgIGlmICghYW5ub3RhdGlvbnMuaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgICBmaW5hbCBUeXBlQW5ub3RhdGlvblBvc2l0aW9uIHAgPQogICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlRnJhbWUodHJlZSwgZnJhbWUsIGZyYW1lcywgY3VycmVudExhbWJkYSwgMCwgbmV3IExpc3RCdWZmZXI8PigpKTsKICAgICAgICAgICAgICAgIGZvciAoVHlwZUNvbXBvdW5kIHRjIDogYW5ub3RhdGlvbnMpCiAgICAgICAgICAgICAgICAgICAgdGMucG9zaXRpb24gPSBwOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIHZvaWQgZmluZFBvc2l0aW9uKEpDVHJlZSB0cmVlLCBKQ1RyZWUgZnJhbWUsIExpc3Q8SkNBbm5vdGF0aW9uPiBhbm5vdGF0aW9ucykgewogICAgICAgICAgICBpZiAoIWFubm90YXRpb25zLmlzRW1wdHkoKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZmluYWwgVHlwZUFubm90YXRpb25Qb3NpdGlvbiBwID0KICAgICAgICAgICAgICAgICAgICByZXNvbHZlRnJhbWUodHJlZSwgZnJhbWUsIGZyYW1lcywgY3VycmVudExhbWJkYSwgMCwgbmV3IExpc3RCdWZmZXI8PigpKTsKCiAgICAgICAgICAgICAgICBzZXRUeXBlQW5ub3RhdGlvblBvcyhhbm5vdGF0aW9ucywgcCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHByaXZhdGUgdm9pZCBzZXRUeXBlQW5ub3RhdGlvblBvcyhMaXN0PEpDQW5ub3RhdGlvbj4gYW5ub3RhdGlvbnMsIFR5cGVBbm5vdGF0aW9uUG9zaXRpb24gcG9zaXRpb24pCiAgICAgICAgewogICAgICAgICAgICAvLyBhdHRyaWJ1dGUgbWlnaHQgYmUgbnVsbCBkdXJpbmcgRGVmZXJyZWRBdHRyOwogICAgICAgICAgICAvLyB3ZSB3aWxsIGJlIGJhY2sgbGF0ZXIuCiAgICAgICAgICAgIGZvciAoSkNBbm5vdGF0aW9uIGFubm8gOiBhbm5vdGF0aW9ucykgewogICAgICAgICAgICAgICAgaWYgKGFubm8uYXR0cmlidXRlICE9IG51bGwpCiAgICAgICAgICAgICAgICAgICAgKChBdHRyaWJ1dGUuVHlwZUNvbXBvdW5kKSBhbm5vLmF0dHJpYnV0ZSkucG9zaXRpb24gPSBwb3NpdGlvbjsKICAgICAgICAgICAgfQogICAgICAgIH0KCgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CiAgICAgICAgICAgIHJldHVybiBzdXBlci50b1N0cmluZygpICsgIjogc2lnT25seTogIiArIHNpZ09ubHk7CiAgICAgICAgfQogICAgfQp9ClBLAwQKAAAIAAAGO6lKselRtrAwAACwMAAAIgAAAGNvbS9zdW4vdG9vbHMvamF2YWMvY29kZS9MaW50LmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMTcsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhYy5jb2RlOwoKaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CmltcG9ydCBqYXZhLnV0aWwuRW51bVNldDsKaW1wb3J0IGphdmEudXRpbC5NYXA7CmltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5Db25jdXJyZW50SGFzaE1hcDsKCmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuU3ltYm9sLio7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLm1haW4uT3B0aW9uOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkNvbnRleHQ7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuTGlzdDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5PcHRpb25zOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLlBhaXI7CgovKioKICogQSBjbGFzcyBmb3IgaGFuZGxpbmcgLVhsaW50IHN1Ym9wdGlvbnMgYW5kIEBTdXBwcmVzc3NXYXJuaW5ncy4KICoKICogIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqICBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqICBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogKiAgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPgogKi8KcHVibGljIGNsYXNzIExpbnQKewogICAgLyoqIFRoZSBjb250ZXh0IGtleSBmb3IgdGhlIHJvb3QgTGludCBvYmplY3QuICovCiAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIENvbnRleHQuS2V5PExpbnQ+IGxpbnRLZXkgPSBuZXcgQ29udGV4dC5LZXk8PigpOwoKICAgIC8qKiBHZXQgdGhlIHJvb3QgTGludCBpbnN0YW5jZS4gKi8KICAgIHB1YmxpYyBzdGF0aWMgTGludCBpbnN0YW5jZShDb250ZXh0IGNvbnRleHQpIHsKICAgICAgICBMaW50IGluc3RhbmNlID0gY29udGV4dC5nZXQobGludEtleSk7CiAgICAgICAgaWYgKGluc3RhbmNlID09IG51bGwpCiAgICAgICAgICAgIGluc3RhbmNlID0gbmV3IExpbnQoY29udGV4dCk7CiAgICAgICAgcmV0dXJuIGluc3RhbmNlOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgcmVzdWx0IG9mIGNvbWJpbmluZyB0aGUgdmFsdWVzIGluIHRoaXMgb2JqZWN0IHdpdGgKICAgICAqIHRoZSBnaXZlbiBhbm5vdGF0aW9uLgogICAgICovCiAgICBwdWJsaWMgTGludCBhdWdtZW50KEF0dHJpYnV0ZS5Db21wb3VuZCBhdHRyKSB7CiAgICAgICAgcmV0dXJuIGF1Z21lbnRvci5hdWdtZW50KHRoaXMsIGF0dHIpOwogICAgfQoKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHJlc3VsdCBvZiBjb21iaW5pbmcgdGhlIHZhbHVlcyBpbiB0aGlzIG9iamVjdCB3aXRoCiAgICAgKiB0aGUgbWV0YWRhdGEgb24gdGhlIGdpdmVuIHN5bWJvbC4KICAgICAqLwogICAgcHVibGljIExpbnQgYXVnbWVudChTeW1ib2wgc3ltKSB7CiAgICAgICAgTGludCBsID0gYXVnbWVudG9yLmF1Z21lbnQodGhpcywgc3ltLmdldERlY2xhcmF0aW9uQXR0cmlidXRlcygpKTsKICAgICAgICBpZiAoc3ltLmlzRGVwcmVjYXRlZCgpKSB7CiAgICAgICAgICAgIGlmIChsID09IHRoaXMpCiAgICAgICAgICAgICAgICBsID0gbmV3IExpbnQodGhpcyk7CiAgICAgICAgICAgIGwudmFsdWVzLnJlbW92ZShMaW50Q2F0ZWdvcnkuREVQUkVDQVRJT04pOwogICAgICAgICAgICBsLnN1cHByZXNzZWRWYWx1ZXMuYWRkKExpbnRDYXRlZ29yeS5ERVBSRUNBVElPTik7CiAgICAgICAgfQogICAgICAgIHJldHVybiBsOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyBhIG5ldyBMaW50IHRoYXQgaGFzIHRoZSBnaXZlbiBMaW50Q2F0ZWdvcnlzIHN1cHByZXNzZWQuCiAgICAgKiBAcGFyYW0gbGMgb25lIG9yIG1vcmUgY2F0ZWdvcmllcyB0byBiZSBzdXBwcmVzc2VkCiAgICAgKi8KICAgIHB1YmxpYyBMaW50IHN1cHByZXNzKExpbnRDYXRlZ29yeS4uLiBsYykgewogICAgICAgIExpbnQgbCA9IG5ldyBMaW50KHRoaXMpOwogICAgICAgIGwudmFsdWVzLnJlbW92ZUFsbChBcnJheXMuYXNMaXN0KGxjKSk7CiAgICAgICAgbC5zdXBwcmVzc2VkVmFsdWVzLmFkZEFsbChBcnJheXMuYXNMaXN0KGxjKSk7CiAgICAgICAgcmV0dXJuIGw7CiAgICB9CgogICAgcHJpdmF0ZSBmaW5hbCBBdWdtZW50VmlzaXRvciBhdWdtZW50b3I7CgogICAgcHJpdmF0ZSBmaW5hbCBFbnVtU2V0PExpbnRDYXRlZ29yeT4gdmFsdWVzOwogICAgcHJpdmF0ZSBmaW5hbCBFbnVtU2V0PExpbnRDYXRlZ29yeT4gc3VwcHJlc3NlZFZhbHVlczsKCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBNYXA8U3RyaW5nLCBMaW50Q2F0ZWdvcnk+IG1hcCA9IG5ldyBDb25jdXJyZW50SGFzaE1hcDw+KDIwKTsKCiAgICBwcm90ZWN0ZWQgTGludChDb250ZXh0IGNvbnRleHQpIHsKICAgICAgICAvLyBpbml0aWFsaXplIHZhbHVlcyBhY2NvcmRpbmcgdG8gdGhlIGxpbnQgb3B0aW9ucwogICAgICAgIE9wdGlvbnMgb3B0aW9ucyA9IE9wdGlvbnMuaW5zdGFuY2UoY29udGV4dCk7CgogICAgICAgIGlmIChvcHRpb25zLmlzU2V0KE9wdGlvbi5YTElOVCkgfHwgb3B0aW9ucy5pc1NldChPcHRpb24uWExJTlRfQ1VTVE9NLCAiYWxsIikpIHsKICAgICAgICAgICAgLy8gSWYgLVhsaW50IG9yIC1YbGludDphbGwgaXMgZ2l2ZW4sIGVuYWJsZSBhbGwgY2F0ZWdvcmllcyBieSBkZWZhdWx0CiAgICAgICAgICAgIHZhbHVlcyA9IEVudW1TZXQuYWxsT2YoTGludENhdGVnb3J5LmNsYXNzKTsKICAgICAgICB9IGVsc2UgaWYgKG9wdGlvbnMuaXNTZXQoT3B0aW9uLlhMSU5UX0NVU1RPTSwgIm5vbmUiKSkgewogICAgICAgICAgICAvLyBpZiAtWGxpbnQ6bm9uZSBpcyBnaXZlbiwgZGlzYWJsZSBhbGwgY2F0ZWdvcmllcyBieSBkZWZhdWx0CiAgICAgICAgICAgIHZhbHVlcyA9IEVudW1TZXQubm9uZU9mKExpbnRDYXRlZ29yeS5jbGFzcyk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLy8gb3RoZXJ3aXNlLCBlbmFibGUgb24tYnktZGVmYXVsdCBjYXRlZ29yaWVzCiAgICAgICAgICAgIHZhbHVlcyA9IEVudW1TZXQubm9uZU9mKExpbnRDYXRlZ29yeS5jbGFzcyk7CgogICAgICAgICAgICBTb3VyY2Ugc291cmNlID0gU291cmNlLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgICAgICBpZiAoc291cmNlLmNvbXBhcmVUbyhTb3VyY2UuSkRLMV85KSA+PSAwKSB7CiAgICAgICAgICAgICAgICB2YWx1ZXMuYWRkKExpbnRDYXRlZ29yeS5ERVBfQU5OKTsKICAgICAgICAgICAgfQogICAgICAgICAgICB2YWx1ZXMuYWRkKExpbnRDYXRlZ29yeS5PUEVOUyk7CiAgICAgICAgICAgIHZhbHVlcy5hZGQoTGludENhdGVnb3J5Lk1PRFVMRSk7CiAgICAgICAgICAgIHZhbHVlcy5hZGQoTGludENhdGVnb3J5LlJFTU9WQUwpOwogICAgICAgIH0KCiAgICAgICAgLy8gTG9vayBmb3Igc3BlY2lmaWMgb3ZlcnJpZGVzCiAgICAgICAgZm9yIChMaW50Q2F0ZWdvcnkgbGMgOiBMaW50Q2F0ZWdvcnkudmFsdWVzKCkpIHsKICAgICAgICAgICAgaWYgKG9wdGlvbnMuaXNTZXQoT3B0aW9uLlhMSU5UX0NVU1RPTSwgbGMub3B0aW9uKSkgewogICAgICAgICAgICAgICAgdmFsdWVzLmFkZChsYyk7CiAgICAgICAgICAgIH0gZWxzZSBpZiAob3B0aW9ucy5pc1NldChPcHRpb24uWExJTlRfQ1VTVE9NLCAiLSIgKyBsYy5vcHRpb24pKSB7CiAgICAgICAgICAgICAgICB2YWx1ZXMucmVtb3ZlKGxjKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgc3VwcHJlc3NlZFZhbHVlcyA9IEVudW1TZXQubm9uZU9mKExpbnRDYXRlZ29yeS5jbGFzcyk7CgogICAgICAgIGNvbnRleHQucHV0KGxpbnRLZXksIHRoaXMpOwogICAgICAgIGF1Z21lbnRvciA9IG5ldyBBdWdtZW50VmlzaXRvcihjb250ZXh0KTsKICAgIH0KCiAgICBwcm90ZWN0ZWQgTGludChMaW50IG90aGVyKSB7CiAgICAgICAgdGhpcy5hdWdtZW50b3IgPSBvdGhlci5hdWdtZW50b3I7CiAgICAgICAgdGhpcy52YWx1ZXMgPSBvdGhlci52YWx1ZXMuY2xvbmUoKTsKICAgICAgICB0aGlzLnN1cHByZXNzZWRWYWx1ZXMgPSBvdGhlci5zdXBwcmVzc2VkVmFsdWVzLmNsb25lKCk7CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewogICAgICAgIHJldHVybiAiTGludDpbdmFsdWVzIiArIHZhbHVlcyArICIgc3VwcHJlc3NlZFZhbHVlcyIgKyBzdXBwcmVzc2VkVmFsdWVzICsgIl0iOwogICAgfQoKICAgIC8qKgogICAgICogQ2F0ZWdvcmllcyBvZiB3YXJuaW5ncyB0aGF0IGNhbiBiZSBnZW5lcmF0ZWQgYnkgdGhlIGNvbXBpbGVyLgogICAgICovCiAgICBwdWJsaWMgZW51bSBMaW50Q2F0ZWdvcnkgewogICAgICAgIC8qKgogICAgICAgICAqIFdhcm4gd2hlbiBjb2RlIHJlZmVycyB0byBhIGF1eGlsaWFyeSBjbGFzcyB0aGF0IGlzIGhpZGRlbiBpbiBhIHNvdXJjZSBmaWxlIChpZSBzb3VyY2UgZmlsZSBuYW1lIGlzCiAgICAgICAgICogZGlmZmVyZW50IGZyb20gdGhlIGNsYXNzIG5hbWUsIGFuZCB0aGUgdHlwZSBpcyBub3QgcHJvcGVybHkgbmVzdGVkKSBhbmQgdGhlIHJlZmVycmluZyBjb2RlCiAgICAgICAgICogaXMgbm90IGxvY2F0ZWQgaW4gdGhlIHNhbWUgc291cmNlIGZpbGUuCiAgICAgICAgICovCiAgICAgICAgQVVYSUxJQVJZQ0xBU1MoImF1eGlsaWFyeWNsYXNzIiksCgogICAgICAgIC8qKgogICAgICAgICAqIFdhcm4gYWJvdXQgdXNlIG9mIHVubmVjZXNzYXJ5IGNhc3RzLgogICAgICAgICAqLwogICAgICAgIENBU1QoImNhc3QiKSwKCiAgICAgICAgLyoqCiAgICAgICAgICogV2FybiBhYm91dCBpc3N1ZXMgcmVsYXRlZCB0byBjbGFzc2ZpbGUgY29udGVudHMKICAgICAgICAgKi8KICAgICAgICBDTEFTU0ZJTEUoImNsYXNzZmlsZSIpLAoKICAgICAgICAvKioKICAgICAgICAgKiBXYXJuIGFib3V0IHVzZSBvZiBkZXByZWNhdGVkIGl0ZW1zLgogICAgICAgICAqLwogICAgICAgIERFUFJFQ0FUSU9OKCJkZXByZWNhdGlvbiIpLAoKICAgICAgICAvKioKICAgICAgICAgKiBXYXJuIGFib3V0IGl0ZW1zIHdoaWNoIGFyZSBkb2N1bWVudGVkIHdpdGggYW4ge0Bjb2RlIEBkZXByZWNhdGVkfSBKYXZhRG9jCiAgICAgICAgICogY29tbWVudCwgYnV0IHdoaWNoIGRvIG5vdCBoYXZlIHtAY29kZSBARGVwcmVjYXRlZH0gYW5ub3RhdGlvbi4KICAgICAgICAgKi8KICAgICAgICBERVBfQU5OKCJkZXAtYW5uIiksCgogICAgICAgIC8qKgogICAgICAgICAqIFdhcm4gYWJvdXQgZGl2aXNpb24gYnkgY29uc3RhbnQgaW50ZWdlciAwLgogICAgICAgICAqLwogICAgICAgIERJVlpFUk8oImRpdnplcm8iKSwKCiAgICAgICAgLyoqCiAgICAgICAgICogV2FybiBhYm91dCBlbXB0eSBzdGF0ZW1lbnQgYWZ0ZXIgaWYuCiAgICAgICAgICovCiAgICAgICAgRU1QVFkoImVtcHR5IiksCgogICAgICAgIC8qKgogICAgICAgICAqIFdhcm4gYWJvdXQgaXNzdWVzIHJlZ2FyZGluZyBtb2R1bGUgZXhwb3J0cy4KICAgICAgICAgKi8KICAgICAgICBFWFBPUlRTKCJleHBvcnRzIiksCgogICAgICAgIC8qKgogICAgICAgICAqIFdhcm4gYWJvdXQgZmFsbGluZyB0aHJvdWdoIGZyb20gb25lIGNhc2Ugb2YgYSBzd2l0Y2ggc3RhdGVtZW50IHRvIHRoZSBuZXh0LgogICAgICAgICAqLwogICAgICAgIEZBTExUSFJPVUdIKCJmYWxsdGhyb3VnaCIpLAoKICAgICAgICAvKioKICAgICAgICAgKiBXYXJuIGFib3V0IGZpbmFsbHkgY2xhdXNlcyB0aGF0IGRvIG5vdCB0ZXJtaW5hdGUgbm9ybWFsbHkuCiAgICAgICAgICovCiAgICAgICAgRklOQUxMWSgiZmluYWxseSIpLAoKICAgICAgICAvKioKICAgICAgICAgKiBXYXJuIGFib3V0IG1vZHVsZSBzeXN0ZW0gcmVsYXRlZCBpc3N1ZXMuCiAgICAgICAgICovCiAgICAgICAgTU9EVUxFKCJtb2R1bGUiKSwKCiAgICAgICAgLyoqCiAgICAgICAgICogV2FybiBhYm91dCBpc3N1ZXMgcmVnYXJkaW5nIG1vZHVsZSBvcGVucy4KICAgICAgICAgKi8KICAgICAgICBPUEVOUygib3BlbnMiKSwKCiAgICAgICAgLyoqCiAgICAgICAgICogV2FybiBhYm91dCBpc3N1ZXMgcmVsYXRpbmcgdG8gdXNlIG9mIGNvbW1hbmQgbGluZSBvcHRpb25zCiAgICAgICAgICovCiAgICAgICAgT1BUSU9OUygib3B0aW9ucyIpLAoKICAgICAgICAvKioKICAgICAgICAgKiBXYXJuIGFib3V0IGlzc3VlcyByZWdhcmRpbmcgbWV0aG9kIG92ZXJsb2Fkcy4KICAgICAgICAgKi8KICAgICAgICBPVkVSTE9BRFMoIm92ZXJsb2FkcyIpLAoKICAgICAgICAvKioKICAgICAgICAgKiBXYXJuIGFib3V0IGlzc3VlcyByZWdhcmRpbmcgbWV0aG9kIG92ZXJyaWRlcy4KICAgICAgICAgKi8KICAgICAgICBPVkVSUklERVMoIm92ZXJyaWRlcyIpLAoKICAgICAgICAvKioKICAgICAgICAgKiBXYXJuIGFib3V0IGludmFsaWQgcGF0aCBlbGVtZW50cyBvbiB0aGUgY29tbWFuZCBsaW5lLgogICAgICAgICAqIFN1Y2ggd2FybmluZ3MgY2Fubm90IGJlIHN1cHByZXNzZWQgd2l0aCB0aGUgU3VwcHJlc3NXYXJuaW5ncwogICAgICAgICAqIGFubm90YXRpb24uCiAgICAgICAgICovCiAgICAgICAgUEFUSCgicGF0aCIpLAoKICAgICAgICAvKioKICAgICAgICAgKiBXYXJuIGFib3V0IGlzc3VlcyByZWdhcmRpbmcgYW5ub3RhdGlvbiBwcm9jZXNzaW5nLgogICAgICAgICAqLwogICAgICAgIFBST0NFU1NJTkcoInByb2Nlc3NpbmciKSwKCiAgICAgICAgLyoqCiAgICAgICAgICogV2FybiBhYm91dCB1bmNoZWNrZWQgb3BlcmF0aW9ucyBvbiByYXcgdHlwZXMuCiAgICAgICAgICovCiAgICAgICAgUkFXKCJyYXd0eXBlcyIpLAoKICAgICAgICAvKioKICAgICAgICAgKiBXYXJuIGFib3V0IHVzZSBvZiBkZXByZWNhdGVkLWZvci1yZW1vdmFsIGl0ZW1zLgogICAgICAgICAqLwogICAgICAgIFJFTU9WQUwoInJlbW92YWwiKSwKCiAgICAgICAgLyoqCiAgICAgICAgICogV2FybiBhYm91dCBTZXJpYWxpemFibGUgY2xhc3NlcyB0aGF0IGRvIG5vdCBwcm92aWRlIGEgc2VyaWFsIHZlcnNpb24gSUQuCiAgICAgICAgICovCiAgICAgICAgU0VSSUFMKCJzZXJpYWwiKSwKCiAgICAgICAgLyoqCiAgICAgICAgICogV2FybiBhYm91dCBpc3N1ZXMgcmVsYXRpbmcgdG8gdXNlIG9mIHN0YXRpY3MKICAgICAgICAgKi8KICAgICAgICBTVEFUSUMoInN0YXRpYyIpLAoKICAgICAgICAvKioKICAgICAgICAgKiBXYXJuIGFib3V0IGlzc3VlcyByZWxhdGluZyB0byB1c2Ugb2YgdHJ5IGJsb2NrcyAoaS5lLiB0cnktd2l0aC1yZXNvdXJjZXMpCiAgICAgICAgICovCiAgICAgICAgVFJZKCJ0cnkiKSwKCiAgICAgICAgLyoqCiAgICAgICAgICogV2FybiBhYm91dCB1bmNoZWNrZWQgb3BlcmF0aW9ucyBvbiByYXcgdHlwZXMuCiAgICAgICAgICovCiAgICAgICAgVU5DSEVDS0VEKCJ1bmNoZWNrZWQiKSwKCiAgICAgICAgLyoqCiAgICAgICAgICogV2FybiBhYm91dCBwb3RlbnRpYWxseSB1bnNhZmUgdmFyYXJnIG1ldGhvZHMKICAgICAgICAgKi8KICAgICAgICBWQVJBUkdTKCJ2YXJhcmdzIik7CgogICAgICAgIExpbnRDYXRlZ29yeShTdHJpbmcgb3B0aW9uKSB7CiAgICAgICAgICAgIHRoaXMob3B0aW9uLCBmYWxzZSk7CiAgICAgICAgfQoKICAgICAgICBMaW50Q2F0ZWdvcnkoU3RyaW5nIG9wdGlvbiwgYm9vbGVhbiBoaWRkZW4pIHsKICAgICAgICAgICAgdGhpcy5vcHRpb24gPSBvcHRpb247CiAgICAgICAgICAgIHRoaXMuaGlkZGVuID0gaGlkZGVuOwogICAgICAgICAgICBtYXAucHV0KG9wdGlvbiwgdGhpcyk7CiAgICAgICAgfQoKICAgICAgICBzdGF0aWMgTGludENhdGVnb3J5IGdldChTdHJpbmcgb3B0aW9uKSB7CiAgICAgICAgICAgIHJldHVybiBtYXAuZ2V0KG9wdGlvbik7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgZmluYWwgU3RyaW5nIG9wdGlvbjsKICAgICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBoaWRkZW47CiAgICB9CgogICAgLyoqCiAgICAgKiBDaGVja3MgaWYgYSB3YXJuaW5nIGNhdGVnb3J5IGlzIGVuYWJsZWQuIEEgd2FybmluZyBjYXRlZ29yeSBtYXkgYmUgZW5hYmxlZAogICAgICogb24gdGhlIGNvbW1hbmQgbGluZSwgb3IgYnkgZGVmYXVsdCwgYW5kIGNhbiBiZSB0ZW1wb3JhcmlseSBkaXNhYmxlZCB3aXRoCiAgICAgKiB0aGUgU3VwcHJlc3NXYXJuaW5ncyBhbm5vdGF0aW9uLgogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBpc0VuYWJsZWQoTGludENhdGVnb3J5IGxjKSB7CiAgICAgICAgcmV0dXJuIHZhbHVlcy5jb250YWlucyhsYyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDaGVja3MgaXMgYSB3YXJuaW5nIGNhdGVnb3J5IGhhcyBiZWVuIHNwZWNpZmljYWxseSBzdXBwcmVzc2VkLCBieSBtZWFucwogICAgICogb2YgdGhlIFN1cHByZXNzV2FybmluZ3MgYW5ub3RhdGlvbiwgb3IsIGluIHRoZSBjYXNlIG9mIHRoZSBkZXByZWNhdGVkCiAgICAgKiBjYXRlZ29yeSwgd2hldGhlciBpdCBoYXMgYmVlbiBpbXBsaWNpdGx5IHN1cHByZXNzZWQgYnkgdmlydHVlIG9mIHRoZQogICAgICogY3VycmVudCBlbnRpdHkgYmVpbmcgaXRzZWxmIGRlcHJlY2F0ZWQuCiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGlzU3VwcHJlc3NlZChMaW50Q2F0ZWdvcnkgbGMpIHsKICAgICAgICByZXR1cm4gc3VwcHJlc3NlZFZhbHVlcy5jb250YWlucyhsYyk7CiAgICB9CgogICAgcHJvdGVjdGVkIHN0YXRpYyBjbGFzcyBBdWdtZW50VmlzaXRvciBpbXBsZW1lbnRzIEF0dHJpYnV0ZS5WaXNpdG9yIHsKICAgICAgICBwcml2YXRlIGZpbmFsIENvbnRleHQgY29udGV4dDsKICAgICAgICBwcml2YXRlIFN5bXRhYiBzeW1zOwogICAgICAgIHByaXZhdGUgTGludCBwYXJlbnQ7CiAgICAgICAgcHJpdmF0ZSBMaW50IGxpbnQ7CgogICAgICAgIEF1Z21lbnRWaXNpdG9yKENvbnRleHQgY29udGV4dCkgewogICAgICAgICAgICAvLyB0byBicmVhayBhbiB1Z2x5IHNlcXVlbmNlIG9mIGluaXRpYWxpemF0aW9uIGRlcGVuZGVuY2llcywKICAgICAgICAgICAgLy8gd2UgZGVmZXIgdGhlIGluaXRpYWxpemF0aW9uIG9mIHN5bXMgdW50aWwgaXQgaXMgbmVlZGVkCiAgICAgICAgICAgIHRoaXMuY29udGV4dCA9IGNvbnRleHQ7CiAgICAgICAgfQoKICAgICAgICBMaW50IGF1Z21lbnQoTGludCBwYXJlbnQsIEF0dHJpYnV0ZS5Db21wb3VuZCBhdHRyKSB7CiAgICAgICAgICAgIGluaXRTeW1zKCk7CiAgICAgICAgICAgIHRoaXMucGFyZW50ID0gcGFyZW50OwogICAgICAgICAgICBsaW50ID0gbnVsbDsKICAgICAgICAgICAgYXR0ci5hY2NlcHQodGhpcyk7CiAgICAgICAgICAgIHJldHVybiAobGludCA9PSBudWxsID8gcGFyZW50IDogbGludCk7CiAgICAgICAgfQoKICAgICAgICBMaW50IGF1Z21lbnQoTGludCBwYXJlbnQsIExpc3Q8QXR0cmlidXRlLkNvbXBvdW5kPiBhdHRycykgewogICAgICAgICAgICBpbml0U3ltcygpOwogICAgICAgICAgICB0aGlzLnBhcmVudCA9IHBhcmVudDsKICAgICAgICAgICAgbGludCA9IG51bGw7CiAgICAgICAgICAgIGZvciAoQXR0cmlidXRlLkNvbXBvdW5kIGE6IGF0dHJzKSB7CiAgICAgICAgICAgICAgICBhLmFjY2VwdCh0aGlzKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gKGxpbnQgPT0gbnVsbCA/IHBhcmVudCA6IGxpbnQpOwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSB2b2lkIGluaXRTeW1zKCkgewogICAgICAgICAgICBpZiAoc3ltcyA9PSBudWxsKQogICAgICAgICAgICAgICAgc3ltcyA9IFN5bXRhYi5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgdm9pZCBzdXBwcmVzcyhMaW50Q2F0ZWdvcnkgbGMpIHsKICAgICAgICAgICAgaWYgKGxpbnQgPT0gbnVsbCkKICAgICAgICAgICAgICAgIGxpbnQgPSBuZXcgTGludChwYXJlbnQpOwogICAgICAgICAgICBsaW50LnN1cHByZXNzZWRWYWx1ZXMuYWRkKGxjKTsKICAgICAgICAgICAgbGludC52YWx1ZXMucmVtb3ZlKGxjKTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0Q29uc3RhbnQoQXR0cmlidXRlLkNvbnN0YW50IHZhbHVlKSB7CiAgICAgICAgICAgIGlmICh2YWx1ZS50eXBlLnRzeW0gPT0gc3ltcy5zdHJpbmdUeXBlLnRzeW0pIHsKICAgICAgICAgICAgICAgIExpbnRDYXRlZ29yeSBsYyA9IExpbnRDYXRlZ29yeS5nZXQoKFN0cmluZykgKHZhbHVlLnZhbHVlKSk7CiAgICAgICAgICAgICAgICBpZiAobGMgIT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICBzdXBwcmVzcyhsYyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0Q2xhc3MoQXR0cmlidXRlLkNsYXNzIGNsYXp6KSB7CiAgICAgICAgfQoKICAgICAgICAvLyBJZiB3ZSBmaW5kIGEgQFN1cHByZXNzV2FybmluZ3MgYW5ub3RhdGlvbiwgdGhlbiB3ZSBjb250aW51ZQogICAgICAgIC8vIHdhbGtpbmcgdGhlIHRyZWUsIGluIG9yZGVyIHRvIHN1cHByZXNzIHRoZSBpbmRpdmlkdWFsIHdhcm5pbmdzCiAgICAgICAgLy8gc3BlY2lmaWVkIGluIHRoZSBAU3VwcHJlc3NXYXJuaW5ncyBhbm5vdGF0aW9uLgogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0Q29tcG91bmQoQXR0cmlidXRlLkNvbXBvdW5kIGNvbXBvdW5kKSB7CiAgICAgICAgICAgIGlmIChjb21wb3VuZC50eXBlLnRzeW0gPT0gc3ltcy5zdXBwcmVzc1dhcm5pbmdzVHlwZS50c3ltKSB7CiAgICAgICAgICAgICAgICBmb3IgKExpc3Q8UGFpcjxNZXRob2RTeW1ib2wsQXR0cmlidXRlPj4gdiA9IGNvbXBvdW5kLnZhbHVlczsKICAgICAgICAgICAgICAgICAgICAgdi5ub25FbXB0eSgpOyB2ID0gdi50YWlsKSB7CiAgICAgICAgICAgICAgICAgICAgUGFpcjxNZXRob2RTeW1ib2wsQXR0cmlidXRlPiB2YWx1ZSA9IHYuaGVhZDsKICAgICAgICAgICAgICAgICAgICBpZiAodmFsdWUuZnN0Lm5hbWUudG9TdHJpbmcoKS5lcXVhbHMoInZhbHVlIikpCiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlLnNuZC5hY2NlcHQodGhpcyk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdEFycmF5KEF0dHJpYnV0ZS5BcnJheSBhcnJheSkgewogICAgICAgICAgICBmb3IgKEF0dHJpYnV0ZSB2YWx1ZSA6IGFycmF5LnZhbHVlcykKICAgICAgICAgICAgICAgIHZhbHVlLmFjY2VwdCh0aGlzKTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0RW51bShBdHRyaWJ1dGUuRW51bSBlKSB7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdEVycm9yKEF0dHJpYnV0ZS5FcnJvciBlKSB7CiAgICAgICAgfQogICAgfQp9ClBLAwQKAAAIAAAGO6lKm4mB97s6AAC7OgAAJwAAAGNvbS9zdW4vdG9vbHMvamF2YWMvY29kZS9BdHRyaWJ1dGUuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwMywgMjAxMywgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGU7CgppbXBvcnQgamF2YS51dGlsLkxpbmtlZEhhc2hNYXA7CmltcG9ydCBqYXZhLnV0aWwuTWFwOwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5lbGVtZW50LkFubm90YXRpb25NaXJyb3I7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuQW5ub3RhdGlvblZhbHVlOwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5lbGVtZW50LkFubm90YXRpb25WYWx1ZVZpc2l0b3I7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLnR5cGUuRGVjbGFyZWRUeXBlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlN5bWJvbC4qOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLio7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuRGVmaW5lZEJ5LkFwaTsKCi8qKiBBbiBhbm5vdGF0aW9uIHZhbHVlLgogKgogKiAgPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24gcmlzay4KICogIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yCiAqICBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+CiAqLwpwdWJsaWMgYWJzdHJhY3QgY2xhc3MgQXR0cmlidXRlIGltcGxlbWVudHMgQW5ub3RhdGlvblZhbHVlIHsKCiAgICAvKiogVGhlIHR5cGUgb2YgdGhlIGFubm90YXRpb24gZWxlbWVudC4gKi8KICAgIHB1YmxpYyBUeXBlIHR5cGU7CgogICAgcHVibGljIEF0dHJpYnV0ZShUeXBlIHR5cGUpIHsKICAgICAgICB0aGlzLnR5cGUgPSB0eXBlOwogICAgfQoKICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIGFjY2VwdChWaXNpdG9yIHYpOwoKICAgIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgcHVibGljIE9iamVjdCBnZXRWYWx1ZSgpIHsKICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKICAgIH0KCiAgICBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgIHB1YmxpYyA8UiwgUD4gUiBhY2NlcHQoQW5ub3RhdGlvblZhbHVlVmlzaXRvcjxSLCBQPiB2LCBQIHApIHsKICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKICAgIH0KCiAgICBwdWJsaWMgYm9vbGVhbiBpc1N5bnRoZXNpemVkKCkgewogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICBwdWJsaWMgVHlwZUFubm90YXRpb25Qb3NpdGlvbiBnZXRQb3NpdGlvbigpIHsgcmV0dXJuIG51bGw7IH0KCiAgICAvKiogVGhlIHZhbHVlIGZvciBhbiBhbm5vdGF0aW9uIGVsZW1lbnQgb2YgcHJpbWl0aXZlIHR5cGUgb3IgU3RyaW5nLiAqLwogICAgcHVibGljIHN0YXRpYyBjbGFzcyBDb25zdGFudCBleHRlbmRzIEF0dHJpYnV0ZSB7CiAgICAgICAgcHVibGljIGZpbmFsIE9iamVjdCB2YWx1ZTsKICAgICAgICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7IHYudmlzaXRDb25zdGFudCh0aGlzKTsgfQogICAgICAgIHB1YmxpYyBDb25zdGFudChUeXBlIHR5cGUsIE9iamVjdCB2YWx1ZSkgewogICAgICAgICAgICBzdXBlcih0eXBlKTsKICAgICAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlOwogICAgICAgIH0KICAgICAgICBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgICAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewogICAgICAgICAgICByZXR1cm4gQ29uc3RhbnRzLmZvcm1hdCh2YWx1ZSwgdHlwZSk7CiAgICAgICAgfQogICAgICAgIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyBPYmplY3QgZ2V0VmFsdWUoKSB7CiAgICAgICAgICAgIHJldHVybiBDb25zdGFudHMuZGVjb2RlKHZhbHVlLCB0eXBlKTsKICAgICAgICB9CiAgICAgICAgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICAgICAgcHVibGljIDxSLCBQPiBSIGFjY2VwdChBbm5vdGF0aW9uVmFsdWVWaXNpdG9yPFIsIFA+IHYsIFAgcCkgewogICAgICAgICAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBTdHJpbmcpCiAgICAgICAgICAgICAgICByZXR1cm4gdi52aXNpdFN0cmluZygoU3RyaW5nKSB2YWx1ZSwgcCk7CiAgICAgICAgICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIEludGVnZXIpIHsKICAgICAgICAgICAgICAgIGludCBpID0gKEludGVnZXIpIHZhbHVlOwogICAgICAgICAgICAgICAgc3dpdGNoICh0eXBlLmdldFRhZygpKSB7CiAgICAgICAgICAgICAgICBjYXNlIEJPT0xFQU46ICAgcmV0dXJuIHYudmlzaXRCb29sZWFuKGkgIT0gMCwgcCk7CiAgICAgICAgICAgICAgICBjYXNlIENIQVI6ICAgICAgcmV0dXJuIHYudmlzaXRDaGFyKChjaGFyKSBpLCBwKTsKICAgICAgICAgICAgICAgIGNhc2UgQllURTogICAgICByZXR1cm4gdi52aXNpdEJ5dGUoKGJ5dGUpIGksIHApOwogICAgICAgICAgICAgICAgY2FzZSBTSE9SVDogICAgIHJldHVybiB2LnZpc2l0U2hvcnQoKHNob3J0KSBpLCBwKTsKICAgICAgICAgICAgICAgIGNhc2UgSU5UOiAgICAgICByZXR1cm4gdi52aXNpdEludChpLCBwKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBzd2l0Y2ggKHR5cGUuZ2V0VGFnKCkpIHsKICAgICAgICAgICAgY2FzZSBMT05HOiAgICAgICAgICByZXR1cm4gdi52aXNpdExvbmcoKExvbmcpIHZhbHVlLCBwKTsKICAgICAgICAgICAgY2FzZSBGTE9BVDogICAgICAgICByZXR1cm4gdi52aXNpdEZsb2F0KChGbG9hdCkgdmFsdWUsIHApOwogICAgICAgICAgICBjYXNlIERPVUJMRTogICAgICAgIHJldHVybiB2LnZpc2l0RG91YmxlKChEb3VibGUpIHZhbHVlLCBwKTsKICAgICAgICAgICAgfQogICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoIkJhZCBhbm5vdGF0aW9uIGVsZW1lbnQgdmFsdWU6ICIgKyB2YWx1ZSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKiBUaGUgdmFsdWUgZm9yIGFuIGFubm90YXRpb24gZWxlbWVudCBvZiB0eXBlIGphdmEubGFuZy5DbGFzcywKICAgICAqICByZXByZXNlbnRlZCBhcyBhIENsYXNzU3ltYm9sLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIENsYXNzIGV4dGVuZHMgQXR0cmlidXRlIHsKICAgICAgICBwdWJsaWMgZmluYWwgVHlwZSBjbGFzc1R5cGU7CiAgICAgICAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgeyB2LnZpc2l0Q2xhc3ModGhpcyk7IH0KICAgICAgICBwdWJsaWMgQ2xhc3MoVHlwZXMgdHlwZXMsIFR5cGUgdHlwZSkgewogICAgICAgICAgICBzdXBlcihtYWtlQ2xhc3NUeXBlKHR5cGVzLCB0eXBlKSk7CiAgICAgICAgICAgIHRoaXMuY2xhc3NUeXBlID0gdHlwZTsKICAgICAgICB9CiAgICAgICAgc3RhdGljIFR5cGUgbWFrZUNsYXNzVHlwZShUeXBlcyB0eXBlcywgVHlwZSB0eXBlKSB7CiAgICAgICAgICAgIFR5cGUgYXJnID0gdHlwZS5pc1ByaW1pdGl2ZSgpCiAgICAgICAgICAgICAgICA/IHR5cGVzLmJveGVkQ2xhc3ModHlwZSkudHlwZQogICAgICAgICAgICAgICAgOiB0eXBlcy5lcmFzdXJlKHR5cGUpOwogICAgICAgICAgICByZXR1cm4gbmV3IFR5cGUuQ2xhc3NUeXBlKHR5cGVzLnN5bXMuY2xhc3NUeXBlLmdldEVuY2xvc2luZ1R5cGUoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0Lm9mKGFyZyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZXMuc3ltcy5jbGFzc1R5cGUudHN5bSk7CiAgICAgICAgfQogICAgICAgIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CiAgICAgICAgICAgIHJldHVybiBjbGFzc1R5cGUgKyAiLmNsYXNzIjsKICAgICAgICB9CiAgICAgICAgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICAgICAgcHVibGljIFR5cGUgZ2V0VmFsdWUoKSB7CiAgICAgICAgICAgIHJldHVybiBjbGFzc1R5cGU7CiAgICAgICAgfQogICAgICAgIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyA8UiwgUD4gUiBhY2NlcHQoQW5ub3RhdGlvblZhbHVlVmlzaXRvcjxSLCBQPiB2LCBQIHApIHsKICAgICAgICAgICAgcmV0dXJuIHYudmlzaXRUeXBlKGNsYXNzVHlwZSwgcCk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKiBBIGNvbXBvdW5kIGFubm90YXRpb24gZWxlbWVudCB2YWx1ZSwgdGhlIHR5cGUgb2Ygd2hpY2ggaXMgYW4KICAgICAqICBhdHRyaWJ1dGUgaW50ZXJmYWNlLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIENvbXBvdW5kIGV4dGVuZHMgQXR0cmlidXRlIGltcGxlbWVudHMgQW5ub3RhdGlvbk1pcnJvciB7CiAgICAgICAgLyoqIFRoZSBhdHRyaWJ1dGVzIHZhbHVlcywgYXMgcGFpcnMuICBFYWNoIHBhaXIgY29udGFpbnMgYQogICAgICAgICAqICByZWZlcmVuY2UgdG8gdGhlIGFjY2Vzc2luZyBtZXRob2QgaW4gdGhlIGF0dHJpYnV0ZSBpbnRlcmZhY2UKICAgICAgICAgKiAgYW5kIHRoZSB2YWx1ZSB0byBiZSByZXR1cm5lZCB3aGVuIHRoYXQgbWV0aG9kIGlzIGNhbGxlZCB0bwogICAgICAgICAqICBhY2Nlc3MgdGhpcyBhdHRyaWJ1dGUuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIGZpbmFsIExpc3Q8UGFpcjxNZXRob2RTeW1ib2wsQXR0cmlidXRlPj4gdmFsdWVzOwogICAgICAgIHB1YmxpYyBUeXBlQW5ub3RhdGlvblBvc2l0aW9uIHBvc2l0aW9uOwoKICAgICAgICBwcml2YXRlIGJvb2xlYW4gc3ludGhlc2l6ZWQgPSBmYWxzZTsKCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gaXNTeW50aGVzaXplZCgpIHsKICAgICAgICAgICAgcmV0dXJuIHN5bnRoZXNpemVkOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHZvaWQgc2V0U3ludGhlc2l6ZWQoYm9vbGVhbiBzeW50aGVzaXplZCkgewogICAgICAgICAgICB0aGlzLnN5bnRoZXNpemVkID0gc3ludGhlc2l6ZWQ7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgQ29tcG91bmQoVHlwZSB0eXBlLAogICAgICAgICAgICAgICAgICAgICAgICBMaXN0PFBhaXI8TWV0aG9kU3ltYm9sLEF0dHJpYnV0ZT4+IHZhbHVlcywKICAgICAgICAgICAgICAgICAgICAgICAgVHlwZUFubm90YXRpb25Qb3NpdGlvbiBwb3NpdGlvbikgewogICAgICAgICAgICBzdXBlcih0eXBlKTsKICAgICAgICAgICAgdGhpcy52YWx1ZXMgPSB2YWx1ZXM7CiAgICAgICAgICAgIHRoaXMucG9zaXRpb24gPSBwb3NpdGlvbjsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBDb21wb3VuZChUeXBlIHR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgIExpc3Q8UGFpcjxNZXRob2RTeW1ib2wsQXR0cmlidXRlPj4gdmFsdWVzKSB7CiAgICAgICAgICAgIHRoaXModHlwZSwgdmFsdWVzLCBudWxsKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBUeXBlQW5ub3RhdGlvblBvc2l0aW9uIGdldFBvc2l0aW9uKCkgewogICAgICAgICAgICBpZiAoaGFzVW5rbm93blBvc2l0aW9uKCkpIHsKICAgICAgICAgICAgICAgIGlmICh2YWx1ZXMuc2l6ZSgpICE9IDApIHsKICAgICAgICAgICAgICAgICAgICBOYW1lIHZhbHVlTmFtZSA9IHZhbHVlcy5oZWFkLmZzdC5uYW1lLnRhYmxlLm5hbWVzLnZhbHVlOwogICAgICAgICAgICAgICAgICAgIFBhaXI8TWV0aG9kU3ltYm9sLCBBdHRyaWJ1dGU+IHJlcyA9IGdldEVsZW1QYWlyKHZhbHVlTmFtZSk7CiAgICAgICAgICAgICAgICAgICAgcG9zaXRpb24gPSByZXMgPT0gbnVsbCA/IG51bGwgOiByZXMuc25kLmdldFBvc2l0aW9uKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHBvc2l0aW9uOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIGJvb2xlYW4gaXNDb250YWluZXJUeXBlQ29tcG91bmQoKSB7CiAgICAgICAgICAgIGlmIChpc1N5bnRoZXNpemVkKCkgJiYgdmFsdWVzLnNpemUoKSA9PSAxKQogICAgICAgICAgICAgICAgcmV0dXJuIGdldEZpcnN0RW1iZWRkZWRUQygpICE9IG51bGw7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgQ29tcG91bmQgZ2V0Rmlyc3RFbWJlZGRlZFRDKCkgewogICAgICAgICAgICBpZiAodmFsdWVzLnNpemUoKSA9PSAxKSB7CiAgICAgICAgICAgICAgICBQYWlyPE1ldGhvZFN5bWJvbCwgQXR0cmlidXRlPiB2YWwgPSB2YWx1ZXMuZ2V0KDApOwogICAgICAgICAgICAgICAgaWYgKHZhbC5mc3QuZ2V0U2ltcGxlTmFtZSgpLmNvbnRlbnRFcXVhbHMoInZhbHVlIikKICAgICAgICAgICAgICAgICAgICAgICAgJiYgdmFsLnNuZCBpbnN0YW5jZW9mIEFycmF5KSB7CiAgICAgICAgICAgICAgICAgICAgQXJyYXkgYXJyID0gKEFycmF5KSB2YWwuc25kOwogICAgICAgICAgICAgICAgICAgIGlmIChhcnIudmFsdWVzLmxlbmd0aCAhPSAwCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiBhcnIudmFsdWVzWzBdIGluc3RhbmNlb2YgQXR0cmlidXRlLlR5cGVDb21wb3VuZCkKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChBdHRyaWJ1dGUuVHlwZUNvbXBvdW5kKSBhcnIudmFsdWVzWzBdOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIGJvb2xlYW4gdHJ5Rml4UG9zaXRpb24oKSB7CiAgICAgICAgICAgIGlmICghaXNDb250YWluZXJUeXBlQ29tcG91bmQoKSkKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKCiAgICAgICAgICAgIENvbXBvdW5kIGZyb20gPSBnZXRGaXJzdEVtYmVkZGVkVEMoKTsKICAgICAgICAgICAgaWYgKGZyb20gIT0gbnVsbCAmJiBmcm9tLnBvc2l0aW9uICE9IG51bGwgJiYKICAgICAgICAgICAgICAgICAgICBmcm9tLnBvc2l0aW9uLnR5cGUgIT0gVGFyZ2V0VHlwZS5VTktOT1dOKSB7CiAgICAgICAgICAgICAgICBwb3NpdGlvbiA9IGZyb20ucG9zaXRpb247CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNVbmtub3duUG9zaXRpb24oKSB7CiAgICAgICAgICAgIHJldHVybiBwb3NpdGlvbi50eXBlID09IFRhcmdldFR5cGUuVU5LTk9XTjsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsgdi52aXNpdENvbXBvdW5kKHRoaXMpOyB9CgogICAgICAgIC8qKgogICAgICAgICAqIFJldHVybnMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBhbm5vdGF0aW9uLgogICAgICAgICAqIFN0cmluZyBpcyBvZiBvbmUgb2YgdGhlIGZvcm1zOgogICAgICAgICAqIDxwcmU+CiAgICAgICAgICogICAgIHtAY29kZSBAY29tLmV4YW1wbGUuZm9vKG5hbWUxPXZhbDEsIG5hbWUyPXZhbDIpfQogICAgICAgICAqICAgICB7QGNvZGUgQGNvbS5leGFtcGxlLmZvbyh2YWwpfQogICAgICAgICAqICAgICB7QGNvZGUgQGNvbS5leGFtcGxlLmZvb30KICAgICAgICAgKiA8L3ByZT4KICAgICAgICAgKiBPbWl0IHBhcmVucyBmb3IgbWFya2VyIGFubm90YXRpb25zLCBhbmQgb21pdCAidmFsdWU9IiB3aGVuIGFsbG93ZWQuCiAgICAgICAgICovCiAgICAgICAgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKICAgICAgICAgICAgU3RyaW5nQnVpbGRlciBidWYgPSBuZXcgU3RyaW5nQnVpbGRlcigpOwogICAgICAgICAgICBidWYuYXBwZW5kKCJAIik7CiAgICAgICAgICAgIGJ1Zi5hcHBlbmQodHlwZSk7CiAgICAgICAgICAgIGludCBsZW4gPSB2YWx1ZXMubGVuZ3RoKCk7CiAgICAgICAgICAgIGlmIChsZW4gPiAwKSB7CiAgICAgICAgICAgICAgICBidWYuYXBwZW5kKCcoJyk7CiAgICAgICAgICAgICAgICBib29sZWFuIGZpcnN0ID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGZvciAoUGFpcjxNZXRob2RTeW1ib2wsIEF0dHJpYnV0ZT4gdmFsdWUgOiB2YWx1ZXMpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoIWZpcnN0KSBidWYuYXBwZW5kKCIsICIpOwogICAgICAgICAgICAgICAgICAgIGZpcnN0ID0gZmFsc2U7CgogICAgICAgICAgICAgICAgICAgIE5hbWUgbmFtZSA9IHZhbHVlLmZzdC5uYW1lOwogICAgICAgICAgICAgICAgICAgIGlmIChsZW4gPiAxIHx8IG5hbWUgIT0gbmFtZS50YWJsZS5uYW1lcy52YWx1ZSkgewogICAgICAgICAgICAgICAgICAgICAgICBidWYuYXBwZW5kKG5hbWUpOwogICAgICAgICAgICAgICAgICAgICAgICBidWYuYXBwZW5kKCc9Jyk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQodmFsdWUuc25kKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQoJyknKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gYnVmLnRvU3RyaW5nKCk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgQXR0cmlidXRlIG1lbWJlcihOYW1lIG1lbWJlcikgewogICAgICAgICAgICBQYWlyPE1ldGhvZFN5bWJvbCxBdHRyaWJ1dGU+IHJlcyA9IGdldEVsZW1QYWlyKG1lbWJlcik7CiAgICAgICAgICAgIHJldHVybiByZXMgPT0gbnVsbCA/IG51bGwgOiByZXMuc25kOwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBQYWlyPE1ldGhvZFN5bWJvbCwgQXR0cmlidXRlPiBnZXRFbGVtUGFpcihOYW1lIG1lbWJlcikgewogICAgICAgICAgICBmb3IgKFBhaXI8TWV0aG9kU3ltYm9sLEF0dHJpYnV0ZT4gcGFpciA6IHZhbHVlcykKICAgICAgICAgICAgICAgIGlmIChwYWlyLmZzdC5uYW1lID09IG1lbWJlcikgcmV0dXJuIHBhaXI7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICAgICAgcHVibGljIEF0dHJpYnV0ZS5Db21wb3VuZCBnZXRWYWx1ZSgpIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgICAgICBwdWJsaWMgPFIsIFA+IFIgYWNjZXB0KEFubm90YXRpb25WYWx1ZVZpc2l0b3I8UiwgUD4gdiwgUCBwKSB7CiAgICAgICAgICAgIHJldHVybiB2LnZpc2l0QW5ub3RhdGlvbih0aGlzLCBwKTsKICAgICAgICB9CgogICAgICAgIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyBEZWNsYXJlZFR5cGUgZ2V0QW5ub3RhdGlvblR5cGUoKSB7CiAgICAgICAgICAgIHJldHVybiAoRGVjbGFyZWRUeXBlKSB0eXBlOwogICAgICAgIH0KCiAgICAgICAgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICAgICAgcHVibGljIE1hcDxNZXRob2RTeW1ib2wsIEF0dHJpYnV0ZT4gZ2V0RWxlbWVudFZhbHVlcygpIHsKICAgICAgICAgICAgTWFwPE1ldGhvZFN5bWJvbCwgQXR0cmlidXRlPiB2YWxtYXAgPSBuZXcgTGlua2VkSGFzaE1hcDw+KCk7CiAgICAgICAgICAgIGZvciAoUGFpcjxNZXRob2RTeW1ib2wsIEF0dHJpYnV0ZT4gdmFsdWUgOiB2YWx1ZXMpCiAgICAgICAgICAgICAgICB2YWxtYXAucHV0KHZhbHVlLmZzdCwgdmFsdWUuc25kKTsKICAgICAgICAgICAgcmV0dXJuIHZhbG1hcDsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjbGFzcyBUeXBlQ29tcG91bmQgZXh0ZW5kcyBDb21wb3VuZCB7CiAgICAgICAgcHVibGljIFR5cGVDb21wb3VuZChDb21wb3VuZCBjb21wb3VuZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUeXBlQW5ub3RhdGlvblBvc2l0aW9uIHBvc2l0aW9uKSB7CiAgICAgICAgICAgIHN1cGVyKGNvbXBvdW5kLnR5cGUsIGNvbXBvdW5kLnZhbHVlcywgcG9zaXRpb24pOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIFR5cGVDb21wb3VuZChUeXBlIHR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTGlzdDxQYWlyPE1ldGhvZFN5bWJvbCxBdHRyaWJ1dGU+PiB2YWx1ZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVHlwZUFubm90YXRpb25Qb3NpdGlvbiBwb3NpdGlvbikgewogICAgICAgICAgICBzdXBlcih0eXBlLCB2YWx1ZXMsIHBvc2l0aW9uKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqIFRoZSB2YWx1ZSBmb3IgYW4gYW5ub3RhdGlvbiBlbGVtZW50IG9mIGFuIGFycmF5IHR5cGUuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgQXJyYXkgZXh0ZW5kcyBBdHRyaWJ1dGUgewogICAgICAgIHB1YmxpYyBmaW5hbCBBdHRyaWJ1dGVbXSB2YWx1ZXM7CiAgICAgICAgcHVibGljIEFycmF5KFR5cGUgdHlwZSwgQXR0cmlidXRlW10gdmFsdWVzKSB7CiAgICAgICAgICAgIHN1cGVyKHR5cGUpOwogICAgICAgICAgICB0aGlzLnZhbHVlcyA9IHZhbHVlczsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBBcnJheShUeXBlIHR5cGUsIExpc3Q8QXR0cmlidXRlPiB2YWx1ZXMpIHsKICAgICAgICAgICAgc3VwZXIodHlwZSk7CiAgICAgICAgICAgIHRoaXMudmFsdWVzID0gdmFsdWVzLnRvQXJyYXkobmV3IEF0dHJpYnV0ZVt2YWx1ZXMuc2l6ZSgpXSk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7IHYudmlzaXRBcnJheSh0aGlzKTsgfQogICAgICAgIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CiAgICAgICAgICAgIFN0cmluZ0J1aWxkZXIgYnVmID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKICAgICAgICAgICAgYnVmLmFwcGVuZCgneycpOwogICAgICAgICAgICBib29sZWFuIGZpcnN0ID0gdHJ1ZTsKICAgICAgICAgICAgZm9yIChBdHRyaWJ1dGUgdmFsdWUgOiB2YWx1ZXMpIHsKICAgICAgICAgICAgICAgIGlmICghZmlyc3QpCiAgICAgICAgICAgICAgICAgICAgYnVmLmFwcGVuZCgiLCAiKTsKICAgICAgICAgICAgICAgIGZpcnN0ID0gZmFsc2U7CiAgICAgICAgICAgICAgICBidWYuYXBwZW5kKHZhbHVlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBidWYuYXBwZW5kKCd9Jyk7CiAgICAgICAgICAgIHJldHVybiBidWYudG9TdHJpbmcoKTsKICAgICAgICB9CiAgICAgICAgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICAgICAgcHVibGljIExpc3Q8QXR0cmlidXRlPiBnZXRWYWx1ZSgpIHsKICAgICAgICAgICAgcmV0dXJuIExpc3QuZnJvbSh2YWx1ZXMpOwogICAgICAgIH0KICAgICAgICBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgICAgICBwdWJsaWMgPFIsIFA+IFIgYWNjZXB0KEFubm90YXRpb25WYWx1ZVZpc2l0b3I8UiwgUD4gdiwgUCBwKSB7CiAgICAgICAgICAgIHJldHVybiB2LnZpc2l0QXJyYXkoZ2V0VmFsdWUoKSwgcCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgVHlwZUFubm90YXRpb25Qb3NpdGlvbiBnZXRQb3NpdGlvbigpIHsKICAgICAgICAgICAgaWYgKHZhbHVlcy5sZW5ndGggIT0gMCkKICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZXNbMF0uZ2V0UG9zaXRpb24oKTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgfQoKICAgIC8qKiBUaGUgdmFsdWUgZm9yIGFuIGFubm90YXRpb24gZWxlbWVudCBvZiBhbiBlbnVtIHR5cGUuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgRW51bSBleHRlbmRzIEF0dHJpYnV0ZSB7CiAgICAgICAgcHVibGljIFZhclN5bWJvbCB2YWx1ZTsKICAgICAgICBwdWJsaWMgRW51bShUeXBlIHR5cGUsIFZhclN5bWJvbCB2YWx1ZSkgewogICAgICAgICAgICBzdXBlcih0eXBlKTsKICAgICAgICAgICAgdGhpcy52YWx1ZSA9IEFzc2VydC5jaGVja05vbk51bGwodmFsdWUpOwogICAgICAgIH0KICAgICAgICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7IHYudmlzaXRFbnVtKHRoaXMpOyB9CiAgICAgICAgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKICAgICAgICAgICAgcmV0dXJuIHZhbHVlLmVuY2xDbGFzcygpICsgIi4iICsgdmFsdWU7ICAgICAvLyBxdWFsaWZpZWQgbmFtZQogICAgICAgIH0KICAgICAgICBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgICAgICBwdWJsaWMgVmFyU3ltYm9sIGdldFZhbHVlKCkgewogICAgICAgICAgICByZXR1cm4gdmFsdWU7CiAgICAgICAgfQogICAgICAgIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyA8UiwgUD4gUiBhY2NlcHQoQW5ub3RhdGlvblZhbHVlVmlzaXRvcjxSLCBQPiB2LCBQIHApIHsKICAgICAgICAgICAgcmV0dXJuIHYudmlzaXRFbnVtQ29uc3RhbnQodmFsdWUsIHApOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIEVycm9yIGV4dGVuZHMgQXR0cmlidXRlIHsKICAgICAgICBwdWJsaWMgRXJyb3IoVHlwZSB0eXBlKSB7CiAgICAgICAgICAgIHN1cGVyKHR5cGUpOwogICAgICAgIH0KICAgICAgICBwdWJsaWMgdm9pZCBhY2NlcHQoVmlzaXRvciB2KSB7IHYudmlzaXRFcnJvcih0aGlzKTsgfQogICAgICAgIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CiAgICAgICAgICAgIHJldHVybiAiPGVycm9yPiI7CiAgICAgICAgfQogICAgICAgIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0VmFsdWUoKSB7CiAgICAgICAgICAgIHJldHVybiB0b1N0cmluZygpOwogICAgICAgIH0KICAgICAgICBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgICAgICBwdWJsaWMgPFIsIFA+IFIgYWNjZXB0KEFubm90YXRpb25WYWx1ZVZpc2l0b3I8UiwgUD4gdiwgUCBwKSB7CiAgICAgICAgICAgIHJldHVybiB2LnZpc2l0U3RyaW5nKHRvU3RyaW5nKCksIHApOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIFVucmVzb2x2ZWRDbGFzcyBleHRlbmRzIEVycm9yIHsKICAgICAgICBwdWJsaWMgVHlwZSBjbGFzc1R5cGU7CiAgICAgICAgcHVibGljIFVucmVzb2x2ZWRDbGFzcyhUeXBlIHR5cGUsIFR5cGUgY2xhc3NUeXBlKSB7CiAgICAgICAgICAgIHN1cGVyKHR5cGUpOwogICAgICAgICAgICB0aGlzLmNsYXNzVHlwZSA9IGNsYXNzVHlwZTsKICAgICAgICB9CiAgICB9CgogICAgLyoqIEEgdmlzaXRvciB0eXBlIGZvciBkeW5hbWljIGRpc3BhdGNoIG9uIHRoZSBraW5kIG9mIGF0dHJpYnV0ZSB2YWx1ZS4gKi8KICAgIHB1YmxpYyBzdGF0aWMgaW50ZXJmYWNlIFZpc2l0b3IgewogICAgICAgIHZvaWQgdmlzaXRDb25zdGFudChBdHRyaWJ1dGUuQ29uc3RhbnQgdmFsdWUpOwogICAgICAgIHZvaWQgdmlzaXRDbGFzcyhBdHRyaWJ1dGUuQ2xhc3MgY2xhenopOwogICAgICAgIHZvaWQgdmlzaXRDb21wb3VuZChBdHRyaWJ1dGUuQ29tcG91bmQgY29tcG91bmQpOwogICAgICAgIHZvaWQgdmlzaXRBcnJheShBdHRyaWJ1dGUuQXJyYXkgYXJyYXkpOwogICAgICAgIHZvaWQgdmlzaXRFbnVtKEF0dHJpYnV0ZS5FbnVtIGUpOwogICAgICAgIHZvaWQgdmlzaXRFcnJvcihBdHRyaWJ1dGUuRXJyb3IgZSk7CiAgICB9CgogICAgLyoqIEEgbWlycm9yIG9mIGphdmEubGFuZy5hbm5vdGF0aW9uLlJldGVudGlvblBvbGljeS4gKi8KICAgIHB1YmxpYyBzdGF0aWMgZW51bSBSZXRlbnRpb25Qb2xpY3kgewogICAgICAgIFNPVVJDRSwKICAgICAgICBDTEFTUywKICAgICAgICBSVU5USU1FCiAgICB9Cn0KUEsDBAoAAAgAAAY7qUpXwXfTpD0AAKQ9AAAjAAAAY29tL3N1bi90b29scy9qYXZhYy9jb2RlL0ZsYWdzLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDE5OTksIDIwMTYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhYy5jb2RlOwoKaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKaW1wb3J0IGphdmEudXRpbC5FbnVtU2V0OwppbXBvcnQgamF2YS51dGlsLk1hcDsKaW1wb3J0IGphdmEudXRpbC5TZXQ7CmltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5Db25jdXJyZW50SGFzaE1hcDsKCmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuTW9kaWZpZXI7CgppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkFzc2VydDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5TdHJpbmdVdGlsczsKCi8qKiBBY2Nlc3MgZmxhZ3MgYW5kIG90aGVyIG1vZGlmaWVycyBmb3IgSmF2YSBjbGFzc2VzIGFuZCBtZW1iZXJzLgogKgogKiAgPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24gcmlzay4KICogIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yCiAqICBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+CiAqLwpwdWJsaWMgY2xhc3MgRmxhZ3MgewoKICAgIHByaXZhdGUgRmxhZ3MoKSB7fSAvLyB1bmluc3RhbnRpYWJsZQoKICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHRvU3RyaW5nKGxvbmcgZmxhZ3MpIHsKICAgICAgICBTdHJpbmdCdWlsZGVyIGJ1ZiA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CiAgICAgICAgU3RyaW5nIHNlcCA9ICIiOwogICAgICAgIGZvciAoRmxhZyBmbGFnIDogYXNGbGFnU2V0KGZsYWdzKSkgewogICAgICAgICAgICBidWYuYXBwZW5kKHNlcCk7CiAgICAgICAgICAgIGJ1Zi5hcHBlbmQoZmxhZyk7CiAgICAgICAgICAgIHNlcCA9ICIgIjsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1Zi50b1N0cmluZygpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgRW51bVNldDxGbGFnPiBhc0ZsYWdTZXQobG9uZyBmbGFncykgewogICAgICAgIEVudW1TZXQ8RmxhZz4gZmxhZ1NldCA9IEVudW1TZXQubm9uZU9mKEZsYWcuY2xhc3MpOwogICAgICAgIGZvciAoRmxhZyBmbGFnIDogRmxhZy52YWx1ZXMoKSkgewogICAgICAgICAgICBpZiAoKGZsYWdzICYgZmxhZy52YWx1ZSkgIT0gMCkgewogICAgICAgICAgICAgICAgZmxhZ1NldC5hZGQoZmxhZyk7CiAgICAgICAgICAgICAgICBmbGFncyAmPSB+ZmxhZy52YWx1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBBc3NlcnQuY2hlY2soZmxhZ3MgPT0gMCk7CiAgICAgICAgcmV0dXJuIGZsYWdTZXQ7CiAgICB9CgogICAgLyogU3RhbmRhcmQgSmF2YSBmbGFncy4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUFVCTElDICAgICAgID0gMTsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBSSVZBVEUgICAgICA9IDE8PDE7CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQUk9URUNURUQgICAgPSAxPDwyOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU1RBVElDICAgICAgID0gMTw8MzsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJTkFMICAgICAgICA9IDE8PDQ7CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTWU5DSFJPTklaRUQgPSAxPDw1OwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVk9MQVRJTEUgICAgID0gMTw8NjsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRSQU5TSUVOVCAgICA9IDE8PDc7CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBOQVRJVkUgICAgICAgPSAxPDw4OwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSU5URVJGQUNFICAgID0gMTw8OTsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEFCU1RSQUNUICAgICA9IDE8PDEwOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU1RSSUNURlAgICAgID0gMTw8MTE7CgogICAgLyogRmxhZyB0aGF0IG1hcmtzIGEgc3ltYm9sIHN5bnRoZXRpYywgYWRkZWQgaW4gY2xhc3NmaWxlIHY0OS4wLiAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU1lOVEhFVElDICAgID0gMTw8MTI7CgogICAgLyoqIEZsYWcgdGhhdCBtYXJrcyBhdHRyaWJ1dGUgaW50ZXJmYWNlcywgYWRkZWQgaW4gY2xhc3NmaWxlIHY0OS4wLiAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQU5OT1RBVElPTiAgID0gMTw8MTM7CgogICAgLyoqIEFuIGVudW1lcmF0aW9uIHR5cGUgb3IgYW4gZW51bWVyYXRpb24gY29uc3RhbnQsIGFkZGVkIGluCiAgICAgKiAgY2xhc3NmaWxlIHY0OS4wLiAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRU5VTSAgICAgICAgID0gMTw8MTQ7CgogICAgLyoqIEFkZGVkIGluIFNFOCwgcmVwcmVzZW50cyBjb25zdHJ1Y3RzIGltcGxpY2l0bHkgZGVjbGFyZWQgaW4gc291cmNlLiAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFOREFURUQgICAgID0gMTw8MTU7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU3RhbmRhcmRGbGFncyA9IDB4MGZmZjsKCiAgICAvLyBCZWNhdXNlIHRoZSBmb2xsb3dpbmcgYWNjZXNzIGZsYWdzIGFyZSBvdmVybG9hZGVkIHdpdGggb3RoZXIKICAgIC8vIGJpdCBwb3NpdGlvbnMsIHdlIHRyYW5zbGF0ZSB0aGVtIHdoZW4gcmVhZGluZyBhbmQgd3JpdGluZyBjbGFzcwogICAgLy8gZmlsZXMgaW50byB1bmlxdWUgYml0cyBwb3NpdGlvbnM6IEFDQ19TWU5USEVUSUMgPC0+IFNZTlRIRVRJQywKICAgIC8vIGZvciBleGFtcGxlLgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQUNDX1NVUEVSICAgID0gMHgwMDIwOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQUNDX0JSSURHRSAgID0gMHgwMDQwOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQUNDX1ZBUkFSR1MgID0gMHgwMDgwOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQUNDX01PRFVMRSAgID0gMHg4MDAwOwoKICAgIC8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogICAgICogSW50ZXJuYWwgY29tcGlsZXIgZmxhZ3MgKG5vIGJpdHMgaW4gdGhlIGxvd2VyIDE2KS4KICAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiAgICAvKiogRmxhZyBpcyBzZXQgaWYgc3ltYm9sIGlzIGRlcHJlY2F0ZWQuICBTZWUgYWxzbyBERVBSRUNBVEVEX1JFTU9WQUwuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERFUFJFQ0FURUQgICA9IDE8PDE3OwoKICAgIC8qKiBGbGFnIGlzIHNldCBmb3IgYSB2YXJpYWJsZSBzeW1ib2wgaWYgdGhlIHZhcmlhYmxlJ3MgZGVmaW5pdGlvbgogICAgICogIGhhcyBhbiBpbml0aWFsaXplciBwYXJ0LgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBIQVNJTklUICAgICAgICAgID0gMTw8MTg7CgogICAgLyoqIEZsYWcgaXMgc2V0IGZvciBjb21waWxlci1nZW5lcmF0ZWQgYW5vbnltb3VzIG1ldGhvZCBzeW1ib2xzCiAgICAgKiAgdGhhdCBgb3duJyBhbiBpbml0aWFsaXplciBibG9jay4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQkxPQ0sgICAgICAgICAgICA9IDE8PDIwOwoKICAgIC8qKiBGbGFnIGJpdCAyMSBpcyBhdmFpbGFibGUuICh1c2VkIGVhcmxpZXIgdG8gdGFnIGNvbXBpbGVyLWdlbmVyYXRlZCBhYnN0cmFjdCBtZXRob2RzIHRoYXQgaW1wbGVtZW50CiAgICAgKiAgYW4gaW50ZXJmYWNlIG1ldGhvZCAoTWlyYW5kYSBtZXRob2RzKSkuCiAgICAgKi8KCiAgICAvKiogRmxhZyBpcyBzZXQgZm9yIG5lc3RlZCBjbGFzc2VzIHRoYXQgZG8gbm90IGFjY2VzcyBpbnN0YW5jZSBtZW1iZXJzCiAgICAgKiAgb3IgYHRoaXMnIG9mIGFuIG91dGVyIGNsYXNzIGFuZCB0aGVyZWZvcmUgZG9uJ3QgbmVlZCB0byBiZSBwYXNzZWQKICAgICAqICBhIHRoaXMkbiByZWZlcmVuY2UuICBUaGlzIHZhbHVlIGlzIGN1cnJlbnRseSBzZXQgb25seSBmb3IgYW5vbnltb3VzCiAgICAgKiAgY2xhc3NlcyBpbiBzdXBlcmNsYXNzIGNvbnN0cnVjdG9yIGNhbGxzLgogICAgICogIHRvZG86IHVzZSB0aGlzIHZhbHVlIGZvciBvcHRpbWl6aW5nIGF3YXkgdGhpcyRuIHBhcmFtZXRlcnMgaW4KICAgICAqICBvdGhlciBjYXNlcy4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTk9PVVRFUlRISVMgID0gMTw8MjI7CgogICAgLyoqIEZsYWcgaXMgc2V0IGZvciBwYWNrYWdlIHN5bWJvbHMgaWYgYSBwYWNrYWdlIGhhcyBhIG1lbWJlciBvcgogICAgICogIGRpcmVjdG9yeSBhbmQgdGhlcmVmb3JlIGV4aXN0cy4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVhJU1RTICAgICAgICAgICA9IDE8PDIzOwoKICAgIC8qKiBGbGFnIGlzIHNldCBmb3IgY29tcGlsZXItZ2VuZXJhdGVkIGNvbXBvdW5kIGNsYXNzZXMKICAgICAqICByZXByZXNlbnRpbmcgbXVsdGlwbGUgdmFyaWFibGUgYm91bmRzCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENPTVBPVU5EICAgICA9IDE8PDI0OwoKICAgIC8qKiBGbGFnIGlzIHNldCBmb3IgY2xhc3Mgc3ltYm9scyBpZiBhIGNsYXNzIGZpbGUgd2FzIGZvdW5kIGZvciB0aGlzIGNsYXNzLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBDTEFTU19TRUVOICAgPSAxPDwyNTsKCiAgICAvKiogRmxhZyBpcyBzZXQgZm9yIGNsYXNzIHN5bWJvbHMgaWYgYSBzb3VyY2UgZmlsZSB3YXMgZm91bmQgZm9yIHRoaXMKICAgICAqICBjbGFzcy4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU09VUkNFX1NFRU4gID0gMTw8MjY7CgogICAgLyogU3RhdGUgZmxhZ3MgKGFyZSByZXNldCBkdXJpbmcgY29tcGlsYXRpb24pLgogICAgICovCgogICAgLyoqIEZsYWcgZm9yIGNsYXNzIHN5bWJvbHMgaXMgc2V0IGFuZCBsYXRlciByZS1zZXQgYXMgYSBsb2NrIGluCiAgICAgKiAgRW50ZXIgdG8gZGV0ZWN0IGN5Y2xlcyBpbiB0aGUgc3VwZXJjbGFzcy9zdXBlcmludGVyZmFjZQogICAgICogIHJlbGF0aW9ucy4gIFNpbWlsYXJseSBmb3IgY29uc3RydWN0b3IgY2FsbCBjeWNsZSBkZXRlY3Rpb24gaW4KICAgICAqICBBdHRyLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT0NLRUQgICAgICAgICAgID0gMTw8Mjc7CgogICAgLyoqIEZsYWcgZm9yIGNsYXNzIHN5bWJvbHMgaXMgc2V0IGFuZCBsYXRlciByZS1zZXQgdG8gaW5kaWNhdGUgdGhhdCBhIGNsYXNzCiAgICAgKiAgaGFzIGJlZW4gZW50ZXJlZCBidXQgaGFzIG5vdCB5ZXQgYmVlbiBhdHRyaWJ1dGVkLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBVTkFUVFJJQlVURUQgPSAxPDwyODsKCiAgICAvKiogRmxhZyBmb3Igc3ludGhlc2l6ZWQgZGVmYXVsdCBjb25zdHJ1Y3RvcnMgb2YgYW5vbnltb3VzIGNsYXNzZXMuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEFOT05DT05TVFIgICA9IDE8PDI5OwoKICAgIC8qKiBGbGFnIGZvciBjbGFzcyBzeW1ib2xzIHRvIGluZGljYXRlIGl0IGhhcyBiZWVuIGNoZWNrZWQgYW5kIGZvdW5kCiAgICAgKiAgYWN5Y2xpYy4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQUNZQ0xJQyAgICAgICAgICA9IDE8PDMwOwoKICAgIC8qKiBGbGFnIHRoYXQgbWFya3MgYnJpZGdlIG1ldGhvZHMuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgbG9uZyBCUklER0UgICAgICAgICAgPSAxTDw8MzE7CgogICAgLyoqIEZsYWcgdGhhdCBtYXJrcyBmb3JtYWwgcGFyYW1ldGVycy4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBsb25nIFBBUkFNRVRFUiAgID0gMUw8PDMzOwoKICAgIC8qKiBGbGFnIHRoYXQgbWFya3MgdmFyYXJncyBtZXRob2RzLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGxvbmcgVkFSQVJHUyAgID0gMUw8PDM0OwoKICAgIC8qKiBGbGFnIGZvciBhbm5vdGF0aW9uIHR5cGUgc3ltYm9scyB0byBpbmRpY2F0ZSBpdCBoYXMgYmVlbgogICAgICogIGNoZWNrZWQgYW5kIGZvdW5kIGFjeWNsaWMuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgbG9uZyBBQ1lDTElDX0FOTiAgICAgID0gMUw8PDM1OwoKICAgIC8qKiBGbGFnIHRoYXQgbWFya3MgYSBnZW5lcmF0ZWQgZGVmYXVsdCBjb25zdHJ1Y3Rvci4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBsb25nIEdFTkVSQVRFRENPTlNUUiAgID0gMUw8PDM2OwoKICAgIC8qKiBGbGFnIHRoYXQgbWFya3MgYSBoeXBvdGhldGljYWwgbWV0aG9kIHRoYXQgbmVlZCBub3QgcmVhbGx5IGJlCiAgICAgKiAgZ2VuZXJhdGVkIGluIHRoZSBiaW5hcnksIGJ1dCBpcyBwcmVzZW50IGluIHRoZSBzeW1ib2wgdGFibGUgdG8KICAgICAqICBzaW1wbGlmeSBjaGVja2luZyBmb3IgZXJhc3VyZSBjbGFzaGVzIC0gYWxzbyB1c2VkIGZvciAyOTIgcG9seSBzaWcgbWV0aG9kcy4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBsb25nIEhZUE9USEVUSUNBTCAgID0gMUw8PDM3OwoKICAgIC8qKgogICAgICogRmxhZyB0aGF0IG1hcmtzIGFuIGludGVybmFsIHByb3ByaWV0YXJ5IGNsYXNzLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGxvbmcgUFJPUFJJRVRBUlkgPSAxTDw8Mzg7CgogICAgLyoqCiAgICAgKiBGbGFnIHRoYXQgbWFya3MgYSBtdWx0aS1jYXRjaCBwYXJhbWV0ZXIuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgbG9uZyBVTklPTiA9IDFMPDwzOTsKCiAgICAvLyBGbGFnIGJpdCAoMUwgPDwgNDApIGlzIGF2YWlsYWJsZS4KCiAgICAvKioKICAgICAqIEZsYWcgdGhhdCBtYXJrcyBhbiAnZWZmZWN0aXZlbHkgZmluYWwnIGxvY2FsIHZhcmlhYmxlLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGxvbmcgRUZGRUNUSVZFTFlfRklOQUwgPSAxTDw8NDE7CgogICAgLyoqCiAgICAgKiBGbGFnIHRoYXQgbWFya3Mgbm9uLW92ZXJyaWRlIGVxdWl2YWxlbnQgbWV0aG9kcyB3aXRoIHRoZSBzYW1lIHNpZ25hdHVyZS4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBsb25nIENMQVNIID0gMUw8PDQyOwoKICAgIC8qKgogICAgICogRmxhZyB0aGF0IG1hcmtzIGVpdGhlciBhIGRlZmF1bHQgbWV0aG9kIG9yIGFuIGludGVyZmFjZSBjb250YWluaW5nIGRlZmF1bHQgbWV0aG9kcy4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBsb25nIERFRkFVTFQgPSAxTDw8NDM7CgogICAgLyoqCiAgICAgKiBGbGFnIHRoYXQgbWFya3MgY2xhc3MgYXMgYXV4aWxpYXJ5LCBpZSBhIG5vbi1wdWJsaWMgY2xhc3MgZm9sbG93aW5nCiAgICAgKiB0aGUgcHVibGljIGNsYXNzIGluIGEgc291cmNlIGZpbGUsIHRoYXQgY291bGQgYmxvY2sgaW1wbGljaXQgY29tcGlsYXRpb24uCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgbG9uZyBBVVhJTElBUlkgPSAxTDw8NDQ7CgogICAgLyoqCiAgICAgKiBGbGFnIHRoYXQgbWFya3MgdGhhdCBhIHN5bWJvbCBpcyBub3QgYXZhaWxhYmxlIGluIHRoZSBjdXJyZW50IHByb2ZpbGUKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBsb25nIE5PVF9JTl9QUk9GSUxFID0gMUw8PDQ1OwoKICAgIC8qKgogICAgICogRmxhZyB0aGF0IGluZGljYXRlcyB0aGF0IGFuIG92ZXJyaWRlIGVycm9yIGhhcyBiZWVuIGRldGVjdGVkIGJ5IENoZWNrLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGxvbmcgQkFEX09WRVJSSURFID0gMUw8PDQ1OwoKICAgIC8qKgogICAgICogRmxhZyB0aGF0IGluZGljYXRlcyBhIHNpZ25hdHVyZSBwb2x5bW9ycGhpYyBtZXRob2QgKDI5MikuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgbG9uZyBTSUdOQVRVUkVfUE9MWU1PUlBISUMgPSAxTDw8NDY7CgogICAgLyoqCiAgICAgKiBGbGFnIHRoYXQgaW5kaWNhdGVzIHRoYXQgYW4gaW5mZXJlbmNlIHZhcmlhYmxlIGlzIHVzZWQgaW4gYSAndGhyb3dzJyBjbGF1c2UuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgbG9uZyBUSFJPV1MgPSAxTDw8NDc7CgogICAgLyoqCiAgICAgKiBGbGFnIHRoYXQgbWFya3MgcG90ZW50aWFsbHkgYW1iaWd1b3VzIG92ZXJsb2FkcwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGxvbmcgUE9URU5USUFMTFlfQU1CSUdVT1VTID0gMUw8PDQ4OwoKICAgIC8qKgogICAgICogRmxhZyB0aGF0IG1hcmtzIGEgc3ludGhldGljIG1ldGhvZCBib2R5IGZvciBhIGxhbWJkYSBleHByZXNzaW9uCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgbG9uZyBMQU1CREFfTUVUSE9EID0gMUw8PDQ5OwoKICAgIC8qKgogICAgICogRmxhZyB0byBjb250cm9sIHJlY3Vyc2lvbiBpbiBUcmFuc1R5cGVzCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgbG9uZyBUWVBFX1RSQU5TTEFURUQgPSAxTDw8NTA7CgogICAgLyoqCiAgICAgKiBGbGFnIHRvIGluZGljYXRlIGNsYXNzIHN5bWJvbCBpcyBmb3IgbW9kdWxlLWluZm8KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBsb25nIE1PRFVMRSA9IDFMPDw1MTsKCiAgICAvKioKICAgICAqIEZsYWcgdG8gaW5kaWNhdGUgdGhlIGdpdmVuIE1vZHVsZVN5bWJvbCBpcyBhbiBhdXRvbWF0aWMgbW9kdWxlLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGxvbmcgQVVUT01BVElDX01PRFVMRSA9IDFMPDw1MjsKCiAgICAvKioKICAgICAqIEZsYWcgdG8gaW5kaWNhdGUgdGhlIGdpdmVuIE1vZHVsZVN5bWJvbCBpcyBhIHN5c3RlbSBtb2R1bGUuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgbG9uZyBTWVNURU1fTU9EVUxFID0gMUw8PDUzOwoKICAgIC8qKgogICAgICogRmxhZyB0byBpbmRpY2F0ZSB0aGUgZ2l2ZW4gc3ltYm9sIGhhcyBhIEBEZXByZWNhdGVkIGFubm90YXRpb24uCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgbG9uZyBERVBSRUNBVEVEX0FOTk9UQVRJT04gPSAxTDw8NTQ7CgogICAgLyoqCiAgICAgKiBGbGFnIHRvIGluZGljYXRlIHRoZSBnaXZlbiBzeW1ib2wgaGFzIGJlZW4gZGVwcmVjYXRlZCBhbmQgbWFya2VkIGZvciByZW1vdmFsLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGxvbmcgREVQUkVDQVRFRF9SRU1PVkFMID0gMUw8PDU1OwoKICAgIC8qKgogICAgICogRmxhZyB0byBpbmRpY2F0ZSB0aGUgZ2l2ZW4gUGFja2FnZVN5bWJvbCBjb250YWlucyBhbnkgbm9uLS5qYXZhIGFuZCBub24tLmNsYXNzIHJlc291cmNlcy4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBsb25nIEhBU19SRVNPVVJDRSA9IDFMPDw1NjsKCiAgICAvKiogTW9kaWZpZXIgbWFza3MuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50CiAgICAgICAgQWNjZXNzRmxhZ3MgICAgICAgICAgID0gUFVCTElDIHwgUFJPVEVDVEVEIHwgUFJJVkFURSwKICAgICAgICBMb2NhbENsYXNzRmxhZ3MgICAgICAgPSBGSU5BTCB8IEFCU1RSQUNUIHwgU1RSSUNURlAgfCBFTlVNIHwgU1lOVEhFVElDLAogICAgICAgIE1lbWJlckNsYXNzRmxhZ3MgICAgICA9IExvY2FsQ2xhc3NGbGFncyB8IElOVEVSRkFDRSB8IEFjY2Vzc0ZsYWdzLAogICAgICAgIENsYXNzRmxhZ3MgICAgICAgICAgICA9IExvY2FsQ2xhc3NGbGFncyB8IElOVEVSRkFDRSB8IFBVQkxJQyB8IEFOTk9UQVRJT04sCiAgICAgICAgSW50ZXJmYWNlVmFyRmxhZ3MgICAgID0gRklOQUwgfCBTVEFUSUMgfCBQVUJMSUMsCiAgICAgICAgVmFyRmxhZ3MgICAgICAgICAgICAgID0gQWNjZXNzRmxhZ3MgfCBGSU5BTCB8IFNUQVRJQyB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVk9MQVRJTEUgfCBUUkFOU0lFTlQgfCBFTlVNLAogICAgICAgIENvbnN0cnVjdG9yRmxhZ3MgICAgICA9IEFjY2Vzc0ZsYWdzLAogICAgICAgIEludGVyZmFjZU1ldGhvZEZsYWdzICA9IEFCU1RSQUNUIHwgUFVCTElDLAogICAgICAgIE1ldGhvZEZsYWdzICAgICAgICAgICA9IEFjY2Vzc0ZsYWdzIHwgQUJTVFJBQ1QgfCBTVEFUSUMgfCBOQVRJVkUgfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNZTkNIUk9OSVpFRCB8IEZJTkFMIHwgU1RSSUNURlA7CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGxvbmcKICAgICAgICBFeHRlbmRlZFN0YW5kYXJkRmxhZ3MgICAgICAgPSAobG9uZylTdGFuZGFyZEZsYWdzIHwgREVGQVVMVCwKICAgICAgICBNb2RpZmllckZsYWdzICAgICAgICAgICAgICAgPSAoKGxvbmcpU3RhbmRhcmRGbGFncyAmIH5JTlRFUkZBQ0UpIHwgREVGQVVMVCwKICAgICAgICBJbnRlcmZhY2VNZXRob2RNYXNrICAgICAgICAgPSBBQlNUUkFDVCB8IFBSSVZBVEUgfCBTVEFUSUMgfCBQVUJMSUMgfCBTVFJJQ1RGUCB8IERFRkFVTFQsCiAgICAgICAgQW5ub3RhdGlvblR5cGVFbGVtZW50TWFzayAgID0gQUJTVFJBQ1QgfCBQVUJMSUMsCiAgICAgICAgTG9jYWxWYXJGbGFncyAgICAgICAgICAgICAgID0gRklOQUwgfCBQQVJBTUVURVIsCiAgICAgICAgUmVjZWl2ZXJQYXJhbUZsYWdzICAgICAgICAgID0gUEFSQU1FVEVSOwoKCiAgICBwdWJsaWMgc3RhdGljIFNldDxNb2RpZmllcj4gYXNNb2RpZmllclNldChsb25nIGZsYWdzKSB7CiAgICAgICAgU2V0PE1vZGlmaWVyPiBtb2RpZmllcnMgPSBtb2RpZmllclNldHMuZ2V0KGZsYWdzKTsKICAgICAgICBpZiAobW9kaWZpZXJzID09IG51bGwpIHsKICAgICAgICAgICAgbW9kaWZpZXJzID0gamF2YS51dGlsLkVudW1TZXQubm9uZU9mKE1vZGlmaWVyLmNsYXNzKTsKICAgICAgICAgICAgaWYgKDAgIT0gKGZsYWdzICYgUFVCTElDKSkgICAgbW9kaWZpZXJzLmFkZChNb2RpZmllci5QVUJMSUMpOwogICAgICAgICAgICBpZiAoMCAhPSAoZmxhZ3MgJiBQUk9URUNURUQpKSBtb2RpZmllcnMuYWRkKE1vZGlmaWVyLlBST1RFQ1RFRCk7CiAgICAgICAgICAgIGlmICgwICE9IChmbGFncyAmIFBSSVZBVEUpKSAgIG1vZGlmaWVycy5hZGQoTW9kaWZpZXIuUFJJVkFURSk7CiAgICAgICAgICAgIGlmICgwICE9IChmbGFncyAmIEFCU1RSQUNUKSkgIG1vZGlmaWVycy5hZGQoTW9kaWZpZXIuQUJTVFJBQ1QpOwogICAgICAgICAgICBpZiAoMCAhPSAoZmxhZ3MgJiBTVEFUSUMpKSAgICBtb2RpZmllcnMuYWRkKE1vZGlmaWVyLlNUQVRJQyk7CiAgICAgICAgICAgIGlmICgwICE9IChmbGFncyAmIEZJTkFMKSkgICAgIG1vZGlmaWVycy5hZGQoTW9kaWZpZXIuRklOQUwpOwogICAgICAgICAgICBpZiAoMCAhPSAoZmxhZ3MgJiBUUkFOU0lFTlQpKSBtb2RpZmllcnMuYWRkKE1vZGlmaWVyLlRSQU5TSUVOVCk7CiAgICAgICAgICAgIGlmICgwICE9IChmbGFncyAmIFZPTEFUSUxFKSkgIG1vZGlmaWVycy5hZGQoTW9kaWZpZXIuVk9MQVRJTEUpOwogICAgICAgICAgICBpZiAoMCAhPSAoZmxhZ3MgJiBTWU5DSFJPTklaRUQpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb2RpZmllcnMuYWRkKE1vZGlmaWVyLlNZTkNIUk9OSVpFRCk7CiAgICAgICAgICAgIGlmICgwICE9IChmbGFncyAmIE5BVElWRSkpICAgIG1vZGlmaWVycy5hZGQoTW9kaWZpZXIuTkFUSVZFKTsKICAgICAgICAgICAgaWYgKDAgIT0gKGZsYWdzICYgU1RSSUNURlApKSAgbW9kaWZpZXJzLmFkZChNb2RpZmllci5TVFJJQ1RGUCk7CiAgICAgICAgICAgIGlmICgwICE9IChmbGFncyAmIERFRkFVTFQpKSAgIG1vZGlmaWVycy5hZGQoTW9kaWZpZXIuREVGQVVMVCk7CiAgICAgICAgICAgIG1vZGlmaWVycyA9IENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZVNldChtb2RpZmllcnMpOwogICAgICAgICAgICBtb2RpZmllclNldHMucHV0KGZsYWdzLCBtb2RpZmllcnMpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbW9kaWZpZXJzOwogICAgfQoKICAgIC8vIENhY2hlIG9mIG1vZGlmaWVyIHNldHMuCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBNYXA8TG9uZywgU2V0PE1vZGlmaWVyPj4gbW9kaWZpZXJTZXRzID0gbmV3IENvbmN1cnJlbnRIYXNoTWFwPD4oNjQpOwoKICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc1N0YXRpYyhTeW1ib2wgc3ltYm9sKSB7CiAgICAgICAgcmV0dXJuIChzeW1ib2wuZmxhZ3MoKSAmIFNUQVRJQykgIT0gMDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNFbnVtKFN5bWJvbCBzeW1ib2wpIHsKICAgICAgICByZXR1cm4gKHN5bWJvbC5mbGFncygpICYgRU5VTSkgIT0gMDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNDb25zdGFudChTeW1ib2wuVmFyU3ltYm9sIHN5bWJvbCkgewogICAgICAgIHJldHVybiBzeW1ib2wuZ2V0Q29uc3RWYWx1ZSgpICE9IG51bGw7CiAgICB9CgoKICAgIHB1YmxpYyBlbnVtIEZsYWcgewogICAgICAgIFBVQkxJQyhGbGFncy5QVUJMSUMpLAogICAgICAgIFBSSVZBVEUoRmxhZ3MuUFJJVkFURSksCiAgICAgICAgUFJPVEVDVEVEKEZsYWdzLlBST1RFQ1RFRCksCiAgICAgICAgU1RBVElDKEZsYWdzLlNUQVRJQyksCiAgICAgICAgRklOQUwoRmxhZ3MuRklOQUwpLAogICAgICAgIFNZTkNIUk9OSVpFRChGbGFncy5TWU5DSFJPTklaRUQpLAogICAgICAgIFZPTEFUSUxFKEZsYWdzLlZPTEFUSUxFKSwKICAgICAgICBUUkFOU0lFTlQoRmxhZ3MuVFJBTlNJRU5UKSwKICAgICAgICBOQVRJVkUoRmxhZ3MuTkFUSVZFKSwKICAgICAgICBJTlRFUkZBQ0UoRmxhZ3MuSU5URVJGQUNFKSwKICAgICAgICBBQlNUUkFDVChGbGFncy5BQlNUUkFDVCksCiAgICAgICAgREVGQVVMVChGbGFncy5ERUZBVUxUKSwKICAgICAgICBTVFJJQ1RGUChGbGFncy5TVFJJQ1RGUCksCiAgICAgICAgQlJJREdFKEZsYWdzLkJSSURHRSksCiAgICAgICAgU1lOVEhFVElDKEZsYWdzLlNZTlRIRVRJQyksCiAgICAgICAgQU5OT1RBVElPTihGbGFncy5BTk5PVEFUSU9OKSwKICAgICAgICBERVBSRUNBVEVEKEZsYWdzLkRFUFJFQ0FURUQpLAogICAgICAgIEhBU0lOSVQoRmxhZ3MuSEFTSU5JVCksCiAgICAgICAgQkxPQ0soRmxhZ3MuQkxPQ0spLAogICAgICAgIEVOVU0oRmxhZ3MuRU5VTSksCiAgICAgICAgTUFOREFURUQoRmxhZ3MuTUFOREFURUQpLAogICAgICAgIE5PT1VURVJUSElTKEZsYWdzLk5PT1VURVJUSElTKSwKICAgICAgICBFWElTVFMoRmxhZ3MuRVhJU1RTKSwKICAgICAgICBDT01QT1VORChGbGFncy5DT01QT1VORCksCiAgICAgICAgQ0xBU1NfU0VFTihGbGFncy5DTEFTU19TRUVOKSwKICAgICAgICBTT1VSQ0VfU0VFTihGbGFncy5TT1VSQ0VfU0VFTiksCiAgICAgICAgTE9DS0VEKEZsYWdzLkxPQ0tFRCksCiAgICAgICAgVU5BVFRSSUJVVEVEKEZsYWdzLlVOQVRUUklCVVRFRCksCiAgICAgICAgQU5PTkNPTlNUUihGbGFncy5BTk9OQ09OU1RSKSwKICAgICAgICBBQ1lDTElDKEZsYWdzLkFDWUNMSUMpLAogICAgICAgIFBBUkFNRVRFUihGbGFncy5QQVJBTUVURVIpLAogICAgICAgIFZBUkFSR1MoRmxhZ3MuVkFSQVJHUyksCiAgICAgICAgQUNZQ0xJQ19BTk4oRmxhZ3MuQUNZQ0xJQ19BTk4pLAogICAgICAgIEdFTkVSQVRFRENPTlNUUihGbGFncy5HRU5FUkFURURDT05TVFIpLAogICAgICAgIEhZUE9USEVUSUNBTChGbGFncy5IWVBPVEhFVElDQUwpLAogICAgICAgIFBST1BSSUVUQVJZKEZsYWdzLlBST1BSSUVUQVJZKSwKICAgICAgICBVTklPTihGbGFncy5VTklPTiksCiAgICAgICAgRUZGRUNUSVZFTFlfRklOQUwoRmxhZ3MuRUZGRUNUSVZFTFlfRklOQUwpLAogICAgICAgIENMQVNIKEZsYWdzLkNMQVNIKSwKICAgICAgICBBVVhJTElBUlkoRmxhZ3MuQVVYSUxJQVJZKSwKICAgICAgICBOT1RfSU5fUFJPRklMRShGbGFncy5OT1RfSU5fUFJPRklMRSksCiAgICAgICAgQkFEX09WRVJSSURFKEZsYWdzLkJBRF9PVkVSUklERSksCiAgICAgICAgU0lHTkFUVVJFX1BPTFlNT1JQSElDKEZsYWdzLlNJR05BVFVSRV9QT0xZTU9SUEhJQyksCiAgICAgICAgVEhST1dTKEZsYWdzLlRIUk9XUyksCiAgICAgICAgTEFNQkRBX01FVEhPRChGbGFncy5MQU1CREFfTUVUSE9EKSwKICAgICAgICBUWVBFX1RSQU5TTEFURUQoRmxhZ3MuVFlQRV9UUkFOU0xBVEVEKSwKICAgICAgICBNT0RVTEUoRmxhZ3MuTU9EVUxFKSwKICAgICAgICBBVVRPTUFUSUNfTU9EVUxFKEZsYWdzLkFVVE9NQVRJQ19NT0RVTEUpLAogICAgICAgIFNZU1RFTV9NT0RVTEUoRmxhZ3MuU1lTVEVNX01PRFVMRSksCiAgICAgICAgREVQUkVDQVRFRF9BTk5PVEFUSU9OKEZsYWdzLkRFUFJFQ0FURURfQU5OT1RBVElPTiksCiAgICAgICAgREVQUkVDQVRFRF9SRU1PVkFMKEZsYWdzLkRFUFJFQ0FURURfUkVNT1ZBTCksCiAgICAgICAgSEFTX1JFU09VUkNFKEZsYWdzLkhBU19SRVNPVVJDRSk7CgogICAgICAgIEZsYWcobG9uZyBmbGFnKSB7CiAgICAgICAgICAgIHRoaXMudmFsdWUgPSBmbGFnOwogICAgICAgICAgICB0aGlzLmxvd2VyY2FzZU5hbWUgPSBTdHJpbmdVdGlscy50b0xvd2VyQ2FzZShuYW1lKCkpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKICAgICAgICAgICAgcmV0dXJuIGxvd2VyY2FzZU5hbWU7CiAgICAgICAgfQoKICAgICAgICBmaW5hbCBsb25nIHZhbHVlOwogICAgICAgIGZpbmFsIFN0cmluZyBsb3dlcmNhc2VOYW1lOwogICAgfQoKfQpQSwMECgAACAAABjupSsvp3/pbLAAAWywAACcAAABjb20vc3VuL3Rvb2xzL2phdmFjL2NvZGUvRGlyZWN0aXZlLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDksIDIwMTcsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhYy5jb2RlOwoKaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKaW1wb3J0IGphdmEudXRpbC5FbnVtU2V0OwppbXBvcnQgamF2YS51dGlsLlNldDsKCmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuTW9kdWxlRWxlbWVudDsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC5Nb2R1bGVFbGVtZW50LkRpcmVjdGl2ZVZpc2l0b3I7CgppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlN5bWJvbC5DbGFzc1N5bWJvbDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5TeW1ib2wuTW9kdWxlU3ltYm9sOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlN5bWJvbC5QYWNrYWdlU3ltYm9sOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkRlZmluZWRCeTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5EZWZpbmVkQnkuQXBpOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkxpc3Q7CgoKLyoqCiAqICBSb290IGNsYXNzIGZvciB0aGUgZGlyZWN0aXZlcyB0aGF0IG1heSBhcHBlYXIgaW4gbW9kdWxlIGNvbXBpbGF0aW9uIHVuaXRzLgogKgogKiAgPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24gcmlzay4KICogIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yCiAqICBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+CiAqLwpwdWJsaWMgYWJzdHJhY3QgY2xhc3MgRGlyZWN0aXZlIGltcGxlbWVudHMgTW9kdWxlRWxlbWVudC5EaXJlY3RpdmUgewoKICAgIC8qKiBGbGFncyBmb3IgUmVxdWlyZXNEaXJlY3RpdmUuICovCiAgICBwdWJsaWMgZW51bSBSZXF1aXJlc0ZsYWcgewogICAgICAgIFRSQU5TSVRJVkUoMHgwMDIwKSwKICAgICAgICBTVEFUSUNfUEhBU0UoMHgwMDQwKSwKICAgICAgICBTWU5USEVUSUMoMHgxMDAwKSwKICAgICAgICBNQU5EQVRFRCgweDgwMDApLAogICAgICAgIEVYVFJBKDB4MTAwMDApOwoKICAgICAgICAvLyBvdmVya2lsbD8gbW92ZSB0byBDbGFzc1dyaXRlcj8KICAgICAgICBwdWJsaWMgc3RhdGljIGludCB2YWx1ZShTZXQ8UmVxdWlyZXNGbGFnPiBzKSB7CiAgICAgICAgICAgIGludCB2ID0gMDsKICAgICAgICAgICAgZm9yIChSZXF1aXJlc0ZsYWcgZjogcykKICAgICAgICAgICAgICAgIHYgfD0gZi52YWx1ZTsKICAgICAgICAgICAgcmV0dXJuIHY7CiAgICAgICAgfQoKICAgICAgICBSZXF1aXJlc0ZsYWcoaW50IHZhbHVlKSB7CiAgICAgICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBmaW5hbCBpbnQgdmFsdWU7CiAgICB9CgogICAgLyoqIEZsYWdzIGZvciBFeHBvcnRzRGlyZWN0aXZlLiAqLwogICAgcHVibGljIGVudW0gRXhwb3J0c0ZsYWcgewogICAgICAgIFNZTlRIRVRJQygweDEwMDApLAogICAgICAgIE1BTkRBVEVEKDB4ODAwMCk7CgogICAgICAgIC8vIG92ZXJraWxsPyBtb3ZlIHRvIENsYXNzV3JpdGVyPwogICAgICAgIHB1YmxpYyBzdGF0aWMgaW50IHZhbHVlKFNldDxFeHBvcnRzRmxhZz4gcykgewogICAgICAgICAgICBpbnQgdiA9IDA7CiAgICAgICAgICAgIGZvciAoRXhwb3J0c0ZsYWcgZjogcykKICAgICAgICAgICAgICAgIHYgfD0gZi52YWx1ZTsKICAgICAgICAgICAgcmV0dXJuIHY7CiAgICAgICAgfQoKICAgICAgICBFeHBvcnRzRmxhZyhpbnQgdmFsdWUpIHsKICAgICAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIGZpbmFsIGludCB2YWx1ZTsKICAgIH0KCiAgICAvKioKICAgICAqICdleHBvcnRzJyBQYWNrYWdlICc7JwogICAgICogJ2V4cG9ydHMnIFBhY2thZ2UgJ3RvJyBNb2R1bGVMaXN0ICc7JwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIEV4cG9ydHNEaXJlY3RpdmUgZXh0ZW5kcyBEaXJlY3RpdmUKICAgICAgICAgICAgaW1wbGVtZW50cyBNb2R1bGVFbGVtZW50LkV4cG9ydHNEaXJlY3RpdmUgewogICAgICAgIHB1YmxpYyBmaW5hbCBQYWNrYWdlU3ltYm9sIHBhY2tnZTsKICAgICAgICBwdWJsaWMgZmluYWwgTGlzdDxNb2R1bGVTeW1ib2w+IG1vZHVsZXM7CiAgICAgICAgcHVibGljIGZpbmFsIFNldDxFeHBvcnRzRmxhZz4gZmxhZ3M7CgogICAgICAgIHB1YmxpYyBFeHBvcnRzRGlyZWN0aXZlKFBhY2thZ2VTeW1ib2wgcGFja2dlLCBMaXN0PE1vZHVsZVN5bWJvbD4gbW9kdWxlcykgewogICAgICAgICAgICB0aGlzKHBhY2tnZSwgbW9kdWxlcywgRW51bVNldC5ub25lT2YoRXhwb3J0c0ZsYWcuY2xhc3MpKTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBFeHBvcnRzRGlyZWN0aXZlKFBhY2thZ2VTeW1ib2wgcGFja2dlLCBMaXN0PE1vZHVsZVN5bWJvbD4gbW9kdWxlcywgU2V0PEV4cG9ydHNGbGFnPiBmbGFncykgewogICAgICAgICAgICB0aGlzLnBhY2tnZSA9IHBhY2tnZTsKICAgICAgICAgICAgdGhpcy5tb2R1bGVzID0gbW9kdWxlczsKICAgICAgICAgICAgdGhpcy5mbGFncyA9IGZsYWdzOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyBNb2R1bGVFbGVtZW50LkRpcmVjdGl2ZUtpbmQgZ2V0S2luZCgpIHsKICAgICAgICAgICAgcmV0dXJuIE1vZHVsZUVsZW1lbnQuRGlyZWN0aXZlS2luZC5FWFBPUlRTOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyBQYWNrYWdlU3ltYm9sIGdldFBhY2thZ2UoKSB7CiAgICAgICAgICAgIHJldHVybiBwYWNrZ2U7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PE1vZHVsZVN5bWJvbD4gZ2V0VGFyZ2V0TW9kdWxlcygpIHsKICAgICAgICAgICAgcmV0dXJuIG1vZHVsZXMgPT0gbnVsbAogICAgICAgICAgICAgICAgICAgID8gbnVsbAogICAgICAgICAgICAgICAgICAgIDogQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChtb2R1bGVzKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CiAgICAgICAgICAgIGlmIChtb2R1bGVzID09IG51bGwpCiAgICAgICAgICAgICAgICByZXR1cm4gIkV4cG9ydHNbIiArIHBhY2tnZSArICJdIjsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgcmV0dXJuICJFeHBvcnRzWyIgKyBwYWNrZ2UgKyAiOiIgKyBtb2R1bGVzICsgIl0iOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyA8UiwgUD4gUiBhY2NlcHQoRGlyZWN0aXZlVmlzaXRvcjxSLCBQPiB2LCBQIHApIHsKICAgICAgICAgICAgcmV0dXJuIHYudmlzaXRFeHBvcnRzKHRoaXMsIHApOwogICAgICAgIH0KICAgIH0KCiAgICAvKiogRmxhZ3MgZm9yIE9wZW5zRGlyZWN0aXZlLiAqLwogICAgcHVibGljIGVudW0gT3BlbnNGbGFnIHsKICAgICAgICBTWU5USEVUSUMoMHgxMDAwKSwKICAgICAgICBNQU5EQVRFRCgweDgwMDApOwoKICAgICAgICAvLyBvdmVya2lsbD8gbW92ZSB0byBDbGFzc1dyaXRlcj8KICAgICAgICBwdWJsaWMgc3RhdGljIGludCB2YWx1ZShTZXQ8T3BlbnNGbGFnPiBzKSB7CiAgICAgICAgICAgIGludCB2ID0gMDsKICAgICAgICAgICAgZm9yIChPcGVuc0ZsYWcgZjogcykKICAgICAgICAgICAgICAgIHYgfD0gZi52YWx1ZTsKICAgICAgICAgICAgcmV0dXJuIHY7CiAgICAgICAgfQoKICAgICAgICBPcGVuc0ZsYWcoaW50IHZhbHVlKSB7CiAgICAgICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBmaW5hbCBpbnQgdmFsdWU7CiAgICB9CgogICAgLyoqCiAgICAgKiAnb3BlbnMnIFBhY2thZ2UgJzsnCiAgICAgKiAnb3BlbnMnIFBhY2thZ2UgJ3RvJyBNb2R1bGVMaXN0ICc7JwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIE9wZW5zRGlyZWN0aXZlIGV4dGVuZHMgRGlyZWN0aXZlCiAgICAgICAgICAgIGltcGxlbWVudHMgTW9kdWxlRWxlbWVudC5PcGVuc0RpcmVjdGl2ZSB7CiAgICAgICAgcHVibGljIGZpbmFsIFBhY2thZ2VTeW1ib2wgcGFja2dlOwogICAgICAgIHB1YmxpYyBmaW5hbCBMaXN0PE1vZHVsZVN5bWJvbD4gbW9kdWxlczsKICAgICAgICBwdWJsaWMgZmluYWwgU2V0PE9wZW5zRmxhZz4gZmxhZ3M7CgogICAgICAgIHB1YmxpYyBPcGVuc0RpcmVjdGl2ZShQYWNrYWdlU3ltYm9sIHBhY2tnZSwgTGlzdDxNb2R1bGVTeW1ib2w+IG1vZHVsZXMpIHsKICAgICAgICAgICAgdGhpcyhwYWNrZ2UsIG1vZHVsZXMsIEVudW1TZXQubm9uZU9mKE9wZW5zRmxhZy5jbGFzcykpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIE9wZW5zRGlyZWN0aXZlKFBhY2thZ2VTeW1ib2wgcGFja2dlLCBMaXN0PE1vZHVsZVN5bWJvbD4gbW9kdWxlcywgU2V0PE9wZW5zRmxhZz4gZmxhZ3MpIHsKICAgICAgICAgICAgdGhpcy5wYWNrZ2UgPSBwYWNrZ2U7CiAgICAgICAgICAgIHRoaXMubW9kdWxlcyA9IG1vZHVsZXM7CiAgICAgICAgICAgIHRoaXMuZmxhZ3MgPSBmbGFnczsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgICAgICBwdWJsaWMgTW9kdWxlRWxlbWVudC5EaXJlY3RpdmVLaW5kIGdldEtpbmQoKSB7CiAgICAgICAgICAgIHJldHVybiBNb2R1bGVFbGVtZW50LkRpcmVjdGl2ZUtpbmQuT1BFTlM7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICAgICAgcHVibGljIFBhY2thZ2VTeW1ib2wgZ2V0UGFja2FnZSgpIHsKICAgICAgICAgICAgcmV0dXJuIHBhY2tnZTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8TW9kdWxlU3ltYm9sPiBnZXRUYXJnZXRNb2R1bGVzKCkgewogICAgICAgICAgICByZXR1cm4gbW9kdWxlcyA9PSBudWxsCiAgICAgICAgICAgICAgICAgICAgPyBudWxsCiAgICAgICAgICAgICAgICAgICAgOiBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KG1vZHVsZXMpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKICAgICAgICAgICAgaWYgKG1vZHVsZXMgPT0gbnVsbCkKICAgICAgICAgICAgICAgIHJldHVybiAiT3BlbnNbIiArIHBhY2tnZSArICJdIjsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgcmV0dXJuICJPcGVuc1siICsgcGFja2dlICsgIjoiICsgbW9kdWxlcyArICJdIjsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgICAgICBwdWJsaWMgPFIsIFA+IFIgYWNjZXB0KERpcmVjdGl2ZVZpc2l0b3I8UiwgUD4gdiwgUCBwKSB7CiAgICAgICAgICAgIHJldHVybiB2LnZpc2l0T3BlbnModGhpcywgcCk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogJ3Byb3ZpZGVzJyBTZXJ2aWNlTmFtZSAnd2l0aCcgUXVhbGlmaWVkSWRlbnRpZmVyICc7JwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIFByb3ZpZGVzRGlyZWN0aXZlIGV4dGVuZHMgRGlyZWN0aXZlCiAgICAgICAgICAgIGltcGxlbWVudHMgTW9kdWxlRWxlbWVudC5Qcm92aWRlc0RpcmVjdGl2ZSB7CiAgICAgICAgcHVibGljIGZpbmFsIENsYXNzU3ltYm9sIHNlcnZpY2U7CiAgICAgICAgcHVibGljIGZpbmFsIExpc3Q8Q2xhc3NTeW1ib2w+IGltcGxzOwoKICAgICAgICBwdWJsaWMgUHJvdmlkZXNEaXJlY3RpdmUoQ2xhc3NTeW1ib2wgc2VydmljZSwgTGlzdDxDbGFzc1N5bWJvbD4gaW1wbHMpIHsKICAgICAgICAgICAgdGhpcy5zZXJ2aWNlID0gc2VydmljZTsKICAgICAgICAgICAgdGhpcy5pbXBscyA9IGltcGxzOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyBNb2R1bGVFbGVtZW50LkRpcmVjdGl2ZUtpbmQgZ2V0S2luZCgpIHsKICAgICAgICAgICAgcmV0dXJuIE1vZHVsZUVsZW1lbnQuRGlyZWN0aXZlS2luZC5QUk9WSURFUzsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgICAgICBwdWJsaWMgQ2xhc3NTeW1ib2wgZ2V0U2VydmljZSgpIHsKICAgICAgICAgICAgcmV0dXJuIHNlcnZpY2U7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICAgICAgcHVibGljIExpc3Q8Q2xhc3NTeW1ib2w+IGdldEltcGxlbWVudGF0aW9ucygpIHsKICAgICAgICAgICAgcmV0dXJuIGltcGxzOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKICAgICAgICAgICAgcmV0dXJuICJQcm92aWRlc1siICsgc2VydmljZSArICIsIiArIGltcGxzICsgIl0iOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyA8UiwgUD4gUiBhY2NlcHQoRGlyZWN0aXZlVmlzaXRvcjxSLCBQPiB2LCBQIHApIHsKICAgICAgICAgICAgcmV0dXJuIHYudmlzaXRQcm92aWRlcyh0aGlzLCBwKTsKICAgICAgICB9CgogICAgICAgIC8vIFRPRE86IGRlbGV0ZT8KICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iaikgewogICAgICAgICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBQcm92aWRlc0RpcmVjdGl2ZSkpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBQcm92aWRlc0RpcmVjdGl2ZSBvdGhlciA9IChQcm92aWRlc0RpcmVjdGl2ZSlvYmo7CiAgICAgICAgICAgIHJldHVybiBzZXJ2aWNlID09IG90aGVyLnNlcnZpY2UgJiYgaW1wbHMuZXF1YWxzKG90aGVyLmltcGxzKTsKICAgICAgICB9CgogICAgICAgIC8vIFRPRE86IGRlbGV0ZT8KICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICAgICAgICByZXR1cm4gc2VydmljZS5oYXNoQ29kZSgpICogMzEgKyBpbXBscy5oYXNoQ29kZSgpICogMzc7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogJ3JlcXVpcmVzJyAoJ3N0YXRpYycgfCAndHJhbnNpdGl2ZScpKiBNb2R1bGVOYW1lICc7JwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIFJlcXVpcmVzRGlyZWN0aXZlIGV4dGVuZHMgRGlyZWN0aXZlCiAgICAgICAgICAgIGltcGxlbWVudHMgTW9kdWxlRWxlbWVudC5SZXF1aXJlc0RpcmVjdGl2ZSB7CiAgICAgICAgcHVibGljIGZpbmFsIE1vZHVsZVN5bWJvbCBtb2R1bGU7CiAgICAgICAgcHVibGljIGZpbmFsIFNldDxSZXF1aXJlc0ZsYWc+IGZsYWdzOwoKICAgICAgICBwdWJsaWMgUmVxdWlyZXNEaXJlY3RpdmUoTW9kdWxlU3ltYm9sIG1vZHVsZSkgewogICAgICAgICAgICB0aGlzKG1vZHVsZSwgRW51bVNldC5ub25lT2YoUmVxdWlyZXNGbGFnLmNsYXNzKSk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgUmVxdWlyZXNEaXJlY3RpdmUoTW9kdWxlU3ltYm9sIG1vZHVsZSwgU2V0PFJlcXVpcmVzRmxhZz4gZmxhZ3MpIHsKICAgICAgICAgICAgdGhpcy5tb2R1bGUgPSBtb2R1bGU7CiAgICAgICAgICAgIHRoaXMuZmxhZ3MgPSBmbGFnczsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgICAgICBwdWJsaWMgTW9kdWxlRWxlbWVudC5EaXJlY3RpdmVLaW5kIGdldEtpbmQoKSB7CiAgICAgICAgICAgIHJldHVybiBNb2R1bGVFbGVtZW50LkRpcmVjdGl2ZUtpbmQuUkVRVUlSRVM7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICAgICAgcHVibGljIGJvb2xlYW4gaXNTdGF0aWMoKSB7CiAgICAgICAgICAgIHJldHVybiBmbGFncy5jb250YWlucyhSZXF1aXJlc0ZsYWcuU1RBVElDX1BIQVNFKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc1RyYW5zaXRpdmUoKSB7CiAgICAgICAgICAgIHJldHVybiBmbGFncy5jb250YWlucyhSZXF1aXJlc0ZsYWcuVFJBTlNJVElWRSk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICAgICAgcHVibGljIE1vZHVsZVN5bWJvbCBnZXREZXBlbmRlbmN5KCkgewogICAgICAgICAgICByZXR1cm4gbW9kdWxlOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKICAgICAgICAgICAgcmV0dXJuICJSZXF1aXJlc1siICsgZmxhZ3MgKyAiLCIgKyBtb2R1bGUgKyAiXSI7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICAgICAgcHVibGljIDxSLCBQPiBSIGFjY2VwdChEaXJlY3RpdmVWaXNpdG9yPFIsIFA+IHYsIFAgcCkgewogICAgICAgICAgICByZXR1cm4gdi52aXNpdFJlcXVpcmVzKHRoaXMsIHApOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqICd1c2VzJyBTZXJ2aWNlTmFtZSAnOycKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBjbGFzcyBVc2VzRGlyZWN0aXZlIGV4dGVuZHMgRGlyZWN0aXZlCiAgICAgICAgICAgIGltcGxlbWVudHMgTW9kdWxlRWxlbWVudC5Vc2VzRGlyZWN0aXZlIHsKICAgICAgICBwdWJsaWMgZmluYWwgQ2xhc3NTeW1ib2wgc2VydmljZTsKCiAgICAgICAgcHVibGljIFVzZXNEaXJlY3RpdmUoQ2xhc3NTeW1ib2wgc2VydmljZSkgewogICAgICAgICAgICB0aGlzLnNlcnZpY2UgPSBzZXJ2aWNlOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyBNb2R1bGVFbGVtZW50LkRpcmVjdGl2ZUtpbmQgZ2V0S2luZCgpIHsKICAgICAgICAgICAgcmV0dXJuIE1vZHVsZUVsZW1lbnQuRGlyZWN0aXZlS2luZC5VU0VTOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyBDbGFzc1N5bWJvbCBnZXRTZXJ2aWNlKCkgewogICAgICAgICAgICByZXR1cm4gc2VydmljZTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CiAgICAgICAgICAgIHJldHVybiAiVXNlc1siICsgc2VydmljZSArICJdIjsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgICAgICBwdWJsaWMgPFIsIFA+IFIgYWNjZXB0KERpcmVjdGl2ZVZpc2l0b3I8UiwgUD4gdiwgUCBwKSB7CiAgICAgICAgICAgIHJldHVybiB2LnZpc2l0VXNlcyh0aGlzLCBwKTsKICAgICAgICB9CgogICAgICAgIC8vIFRPRE86IGRlbGV0ZT8KICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iaikgewogICAgICAgICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBVc2VzRGlyZWN0aXZlKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIFVzZXNEaXJlY3RpdmUgb3RoZXIgPSAoVXNlc0RpcmVjdGl2ZSlvYmo7CiAgICAgICAgICAgIHJldHVybiBzZXJ2aWNlID09IG90aGVyLnNlcnZpY2U7CiAgICAgICAgfQoKICAgICAgICAvLyBUT0RPOiBkZWxldGU/CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgICAgICAgcmV0dXJuIHNlcnZpY2UuaGFzaENvZGUoKSAqIDMxOwogICAgICAgIH0KICAgIH0KfQpQSwMECgAACAAABjupSs8sn1jrmwAA65sAACMAAABjb20vc3VuL3Rvb2xzL2phdmFjL2NvZGUvU2NvcGUuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMTk5OSwgMjAxNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGU7CgppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLktpbmRzLktpbmQ7CmltcG9ydCBqYXZhLmxhbmcucmVmLldlYWtSZWZlcmVuY2U7CmltcG9ydCBqYXZhLnV0aWwuKjsKaW1wb3J0IGphdmEudXRpbC5mdW5jdGlvbi5CaUNvbnN1bWVyOwppbXBvcnQgamF2YS51dGlsLnN0cmVhbS5TdHJlYW07CmltcG9ydCBqYXZhLnV0aWwuc3RyZWFtLlN0cmVhbVN1cHBvcnQ7CgppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlN5bWJvbC5Db21wbGV0aW9uRmFpbHVyZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5TeW1ib2wuVHlwZVN5bWJvbDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5KQ1RyZWUuSkNJbXBvcnQ7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuKjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5MaXN0OwoKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuU2NvcGUuTG9va3VwS2luZC5OT05fUkVDVVJTSVZFOwppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5TY29wZS5Mb29rdXBLaW5kLlJFQ1VSU0lWRTsKCi8qKiBBIHNjb3BlIHJlcHJlc2VudHMgYW4gYXJlYSBvZiB2aXNpYmlsaXR5IGluIGEgSmF2YSBwcm9ncmFtLiBUaGUKICogIFNjb3BlIGNsYXNzIGlzIGEgY29udGFpbmVyIGZvciBzeW1ib2xzIHdoaWNoIHByb3ZpZGVzCiAqICBlZmZpY2llbnQgYWNjZXNzIHRvIHN5bWJvbHMgZ2l2ZW4gdGhlaXIgbmFtZXMuIFNjb3BlcyBhcmUgaW1wbGVtZW50ZWQKICogIGFzIGhhc2ggdGFibGVzIHdpdGggIm9wZW4gYWRkcmVzc2luZyIgYW5kICJkb3VibGUgaGFzaGluZyIuCiAqICBTY29wZXMgY2FuIGJlIG5lc3RlZC4gTmVzdGVkIHNjb3BlcyBjYW4gc2hhcmUgdGhlaXIgaGFzaCB0YWJsZXMuCiAqCiAqICA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiAgSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93biByaXNrLgogKiAgVGhpcyBjb2RlIGFuZCBpdHMgaW50ZXJuYWwgaW50ZXJmYWNlcyBhcmUgc3ViamVjdCB0byBjaGFuZ2Ugb3IKICogIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj4KICovCnB1YmxpYyBhYnN0cmFjdCBjbGFzcyBTY29wZSB7CgogICAgLyoqIFRoZSBzY29wZSdzIG93bmVyLgogICAgICovCiAgICBwdWJsaWMgZmluYWwgU3ltYm9sIG93bmVyOwoKICAgIHByb3RlY3RlZCBTY29wZShTeW1ib2wgb3duZXIpIHsKICAgICAgICB0aGlzLm93bmVyID0gb3duZXI7CiAgICB9CgogICAgLyoqUmV0dXJucyBhbGwgU3ltYm9scyBpbiB0aGlzIFNjb3BlLiBTeW1ib2xzIGZyb20gb3V0d2FyZCBTY29wZXMgYXJlIGluY2x1ZGVkLgogICAgICovCiAgICBwdWJsaWMgZmluYWwgSXRlcmFibGU8U3ltYm9sPiBnZXRTeW1ib2xzKCkgewogICAgICAgIHJldHVybiBnZXRTeW1ib2xzKG5vRmlsdGVyKTsKICAgIH0KCiAgICAvKipSZXR1cm5zIFN5bWJvbHMgdGhhdCBtYXRjaCB0aGUgZ2l2ZW4gZmlsdGVyLiBTeW1ib2xzIGZyb20gb3V0d2FyZCBTY29wZXMgYXJlIGluY2x1ZGVkLgogICAgICovCiAgICBwdWJsaWMgZmluYWwgSXRlcmFibGU8U3ltYm9sPiBnZXRTeW1ib2xzKEZpbHRlcjxTeW1ib2w+IHNmKSB7CiAgICAgICAgcmV0dXJuIGdldFN5bWJvbHMoc2YsIFJFQ1VSU0lWRSk7CiAgICB9CgogICAgLyoqUmV0dXJucyBhbGwgU3ltYm9scyBpbiB0aGlzIFNjb3BlLiBTeW1ib2xzIGZyb20gb3V0d2FyZCBTY29wZXMgYXJlIGluY2x1ZGVkCiAgICAgKiBpZmYgbG9va3VwS2luZCA9PSBSRUNVUlNJVkUuCiAgICAgKi8KICAgIHB1YmxpYyBmaW5hbCBJdGVyYWJsZTxTeW1ib2w+IGdldFN5bWJvbHMoTG9va3VwS2luZCBsb29rdXBLaW5kKSB7CiAgICAgICAgcmV0dXJuIGdldFN5bWJvbHMobm9GaWx0ZXIsIGxvb2t1cEtpbmQpOwogICAgfQoKICAgIC8qKlJldHVybnMgU3ltYm9scyB0aGF0IG1hdGNoIHRoZSBnaXZlbiBmaWx0ZXIuIFN5bWJvbHMgZnJvbSBvdXR3YXJkIFNjb3BlcyBhcmUgaW5jbHVkZWQKICAgICAqIGlmZiBsb29rdXBLaW5kID09IFJFQ1VSU0lWRS4KICAgICAqLwogICAgcHVibGljIGFic3RyYWN0IEl0ZXJhYmxlPFN5bWJvbD4gZ2V0U3ltYm9scyhGaWx0ZXI8U3ltYm9sPiBzZiwgTG9va3VwS2luZCBsb29rdXBLaW5kKTsKCiAgICAvKipSZXR1cm5zIFN5bWJvbHMgd2l0aCB0aGUgZ2l2ZW4gbmFtZS4gU3ltYm9scyBmcm9tIG91dHdhcmQgU2NvcGVzIGFyZSBpbmNsdWRlZC4KICAgICAqLwogICAgcHVibGljIGZpbmFsIEl0ZXJhYmxlPFN5bWJvbD4gZ2V0U3ltYm9sc0J5TmFtZShOYW1lIG5hbWUpIHsKICAgICAgICByZXR1cm4gZ2V0U3ltYm9sc0J5TmFtZShuYW1lLCBSRUNVUlNJVkUpOwogICAgfQoKICAgIC8qKlJldHVybnMgU3ltYm9scyB3aXRoIHRoZSBnaXZlbiBuYW1lIHRoYXQgbWF0Y2ggdGhlIGdpdmVuIGZpbHRlci4KICAgICAqIFN5bWJvbHMgZnJvbSBvdXR3YXJkIFNjb3BlcyBhcmUgaW5jbHVkZWQuCiAgICAgKi8KICAgIHB1YmxpYyBmaW5hbCBJdGVyYWJsZTxTeW1ib2w+IGdldFN5bWJvbHNCeU5hbWUoZmluYWwgTmFtZSBuYW1lLCBmaW5hbCBGaWx0ZXI8U3ltYm9sPiBzZikgewogICAgICAgIHJldHVybiBnZXRTeW1ib2xzQnlOYW1lKG5hbWUsIHNmLCBSRUNVUlNJVkUpOwogICAgfQoKICAgIC8qKlJldHVybnMgU3ltYm9scyB3aXRoIHRoZSBnaXZlbiBuYW1lLiBTeW1ib2xzIGZyb20gb3V0d2FyZCBTY29wZXMgYXJlIGluY2x1ZGVkCiAgICAgKiBpZmYgbG9va3VwS2luZCA9PSBSRUNVUlNJVkUuCiAgICAgKi8KICAgIHB1YmxpYyBmaW5hbCBJdGVyYWJsZTxTeW1ib2w+IGdldFN5bWJvbHNCeU5hbWUoTmFtZSBuYW1lLCBMb29rdXBLaW5kIGxvb2t1cEtpbmQpIHsKICAgICAgICByZXR1cm4gZ2V0U3ltYm9sc0J5TmFtZShuYW1lLCBub0ZpbHRlciwgbG9va3VwS2luZCk7CiAgICB9CgogICAgLyoqUmV0dXJucyBTeW1ib2xzIHdpdGggdGhlIGdpdmVuIG5hbWUgdGhhdCBtYXRjaCB0aGUgZ2l2ZW4gZmlsdGVyLgogICAgICogU3ltYm9scyBmcm9tIG91dHdhcmQgU2NvcGVzIGFyZSBpbmNsdWRlZCBpZmYgbG9va3VwS2luZCA9PSBSRUNVUlNJVkUuCiAgICAgKi8KICAgIHB1YmxpYyBhYnN0cmFjdCBJdGVyYWJsZTxTeW1ib2w+IGdldFN5bWJvbHNCeU5hbWUoZmluYWwgTmFtZSBuYW1lLCBmaW5hbCBGaWx0ZXI8U3ltYm9sPiBzZiwKICAgICAgICAgICAgZmluYWwgTG9va3VwS2luZCBsb29rdXBLaW5kKTsKCiAgICAvKiogUmV0dXJuIHRoZSBmaXJzdCBTeW1ib2wgZnJvbSB0aGlzIG9yIG91dHdhcmQgc2NvcGVzIHdpdGggdGhlIGdpdmVuIG5hbWUuCiAgICAgKiBSZXR1cm5zIG51bGwgaWYgbm9uZS4KICAgICAqLwogICAgcHVibGljIGZpbmFsIFN5bWJvbCBmaW5kRmlyc3QoTmFtZSBuYW1lKSB7CiAgICAgICAgcmV0dXJuIGZpbmRGaXJzdChuYW1lLCBub0ZpbHRlcik7CiAgICB9CgogICAgLyoqIFJldHVybiB0aGUgZmlyc3QgU3ltYm9sIGZyb20gdGhpcyBvciBvdXR3YXJkIHNjb3BlcyB3aXRoIHRoZSBnaXZlbiBuYW1lIHRoYXQgbWF0Y2hlcyB0aGUKICAgICAqICBnaXZlbiBmaWx0ZXIuIFJldHVybnMgbnVsbCBpZiBub25lLgogICAgICovCiAgICBwdWJsaWMgU3ltYm9sIGZpbmRGaXJzdChOYW1lIG5hbWUsIEZpbHRlcjxTeW1ib2w+IHNmKSB7CiAgICAgICAgSXRlcmF0b3I8U3ltYm9sPiBpdCA9IGdldFN5bWJvbHNCeU5hbWUobmFtZSwgc2YpLml0ZXJhdG9yKCk7CiAgICAgICAgcmV0dXJuIGl0Lmhhc05leHQoKSA/IGl0Lm5leHQoKSA6IG51bGw7CiAgICB9CgogICAgLyoqIFJldHVybnMgdHJ1ZSBpZmYgdGhlcmUgYXJlIGlzIGF0IGxlYXN0IG9uZSBTeW1ib2wgaW4gdGhpcyBzY29wZSBtYXRjaGluZyB0aGUgZ2l2ZW4gZmlsdGVyLgogICAgICogIERvZXMgbm90IGluc3BlY3Qgb3V0d2FyZCBzY29wZXMuCiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGFueU1hdGNoKEZpbHRlcjxTeW1ib2w+IGZpbHRlcikgewogICAgICAgIHJldHVybiBnZXRTeW1ib2xzKGZpbHRlciwgTk9OX1JFQ1VSU0lWRSkuaXRlcmF0b3IoKS5oYXNOZXh0KCk7CiAgICB9CgogICAgLyoqIFJldHVybnMgdHJ1ZSBpZmYgdGhlIGdpdmVuIFN5bWJvbCBpcyBpbiB0aGlzIHNjb3BlIG9yIGFueSBvdXR3YXJkIHNjb3BlLgogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBpbmNsdWRlcyhmaW5hbCBTeW1ib2wgc3ltKSB7CiAgICAgICAgcmV0dXJuIGluY2x1ZGVzKHN5bSwgUkVDVVJTSVZFKTsKICAgIH0KCiAgICAvKiogUmV0dXJucyB0cnVlIGlmZiB0aGUgZ2l2ZW4gU3ltYm9sIGlzIGluIHRoaXMgc2NvcGUsIG9wdGlvbmFsbHkgY2hlY2tpbmcgb3V0d2FyZCBzY29wZXMuCiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGluY2x1ZGVzKGZpbmFsIFN5bWJvbCBzeW0sIExvb2t1cEtpbmQgbG9va3VwS2luZCkgewogICAgICAgIHJldHVybiBnZXRTeW1ib2xzQnlOYW1lKHN5bS5uYW1lLCB0IC0+IHQgPT0gc3ltLCBsb29rdXBLaW5kKS5pdGVyYXRvcigpLmhhc05leHQoKTsKICAgIH0KCiAgICAvKiogUmV0dXJucyB0cnVlIGlmZiB0aGlzIHNjb3BlIGRvZXMgbm90IGNvbnRhaW4gYW55IFN5bWJvbC4gRG9lcyBub3QgaW5zcGVjdCBvdXR3YXJkIHNjb3Blcy4KICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gaXNFbXB0eSgpIHsKICAgICAgICByZXR1cm4gIWdldFN5bWJvbHMoTk9OX1JFQ1VSU0lWRSkuaXRlcmF0b3IoKS5oYXNOZXh0KCk7CiAgICB9CgogICAgLyoqIFJldHVybnMgdGhlIFNjb3BlIGZyb20gd2hpY2ggdGhlIGdpdmlucyBTeW1ib2wgb3JpZ2luYXRlcyBpbiB0aGlzIHNjb3BlLgogICAgICovCiAgICBwdWJsaWMgYWJzdHJhY3QgU2NvcGUgZ2V0T3JpZ2luKFN5bWJvbCBieU5hbWUpOwoKICAgIC8qKiBSZXR1cm5zIHRydWUgaWZmIHRoZSBnaXZlbiBTeW1ib2wgaXMgcGFydCBvZiB0aGlzIHNjb3BlIGR1ZSB0byBhIHN0YXRpYyBpbXBvcnQuCiAgICAgKi8KICAgIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIGlzU3RhdGljYWxseUltcG9ydGVkKFN5bWJvbCBieU5hbWUpOwoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEZpbHRlcjxTeW1ib2w+IG5vRmlsdGVyID0gbnVsbDsKCiAgICAvKiogQSBsaXN0IG9mIHNjb3BlcyB0byBiZSBub3RpZmllZCBpZiBpdGVtcyBhcmUgdG8gYmUgcmVtb3ZlZCBmcm9tIHRoaXMgc2NvcGUuCiAgICAgKi8KICAgIFNjb3BlTGlzdGVuZXJMaXN0IGxpc3RlbmVycyA9IG5ldyBTY29wZUxpc3RlbmVyTGlzdCgpOwoKICAgIHB1YmxpYyBpbnRlcmZhY2UgU2NvcGVMaXN0ZW5lciB7CiAgICAgICAgdm9pZCBzeW1ib2xBZGRlZChTeW1ib2wgc3ltLCBTY29wZSBzKTsKICAgICAgICB2b2lkIHN5bWJvbFJlbW92ZWQoU3ltYm9sIHN5bSwgU2NvcGUgcyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBBIGxpc3Qgb2Ygc2NvcGUgbGlzdGVuZXJzOyBsaXN0ZW5lcnMgYXJlIHN0b3JlZCBpbiB3ZWFrIHJlZmVyZW5jZXMsIHRvIGF2b2lkIG1lbW9yeSBsZWFrcy4KICAgICAqIFdoZW4gdGhlIGxpc3RlbmVyIGxpc3QgaXMgc2Nhbm5lZCAodXBvbiBub3RpZmljYXRpb24pLCBlbGVtZW50cyBjb3JyZXNwb25kaW5nIHRvIEdDLWVkCiAgICAgKiBsaXN0ZW5lcnMgYXJlIHJlbW92ZWQgc28gdGhhdCB0aGUgbGlzdGVuZXIgbGlzdCBzaXplIGlzIGtlcHQgaW4gY2hlY2suCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgU2NvcGVMaXN0ZW5lckxpc3QgewoKICAgICAgICBMaXN0PFdlYWtSZWZlcmVuY2U8U2NvcGVMaXN0ZW5lcj4+IGxpc3RlbmVycyA9IExpc3QubmlsKCk7CgogICAgICAgIHZvaWQgYWRkKFNjb3BlTGlzdGVuZXIgc2wpIHsKICAgICAgICAgICAgbGlzdGVuZXJzID0gbGlzdGVuZXJzLnByZXBlbmQobmV3IFdlYWtSZWZlcmVuY2U8PihzbCkpOwogICAgICAgIH0KCiAgICAgICAgdm9pZCBzeW1ib2xBZGRlZChTeW1ib2wgc3ltLCBTY29wZSBzY29wZSkgewogICAgICAgICAgICB3YWxrUmVmZXJlbmNlcyhzeW0sIHNjb3BlLCBmYWxzZSk7CiAgICAgICAgfQoKICAgICAgICB2b2lkIHN5bWJvbFJlbW92ZWQoU3ltYm9sIHN5bSwgU2NvcGUgc2NvcGUpIHsKICAgICAgICAgICAgd2Fsa1JlZmVyZW5jZXMoc3ltLCBzY29wZSwgdHJ1ZSk7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIHZvaWQgd2Fsa1JlZmVyZW5jZXMoU3ltYm9sIHN5bSwgU2NvcGUgc2NvcGUsIGJvb2xlYW4gaXNSZW1vdmUpIHsKICAgICAgICAgICAgTGlzdEJ1ZmZlcjxXZWFrUmVmZXJlbmNlPFNjb3BlTGlzdGVuZXI+PiBuZXdMaXN0ZW5lcnMgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgIGZvciAoV2Vha1JlZmVyZW5jZTxTY29wZUxpc3RlbmVyPiB3c2wgOiBsaXN0ZW5lcnMpIHsKICAgICAgICAgICAgICAgIFNjb3BlTGlzdGVuZXIgc2wgPSB3c2wuZ2V0KCk7CiAgICAgICAgICAgICAgICBpZiAoc2wgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIGlmIChpc1JlbW92ZSkgewogICAgICAgICAgICAgICAgICAgICAgICBzbC5zeW1ib2xSZW1vdmVkKHN5bSwgc2NvcGUpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHNsLnN5bWJvbEFkZGVkKHN5bSwgc2NvcGUpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBuZXdMaXN0ZW5lcnMuYWRkKHdzbCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgbGlzdGVuZXJzID0gbmV3TGlzdGVuZXJzLnRvTGlzdCgpOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgZW51bSBMb29rdXBLaW5kIHsKICAgICAgICBSRUNVUlNJVkUsCiAgICAgICAgTk9OX1JFQ1VSU0lWRTsKICAgIH0KCiAgICAvKipBIHNjb3BlIGludG8gd2hpY2ggU3ltYm9scyBjYW4gYmUgYWRkZWQuKi8KICAgIHB1YmxpYyBhYnN0cmFjdCBzdGF0aWMgY2xhc3MgV3JpdGVhYmxlU2NvcGUgZXh0ZW5kcyBTY29wZSB7CgogICAgICAgIHB1YmxpYyBXcml0ZWFibGVTY29wZShTeW1ib2wgb3duZXIpIHsKICAgICAgICAgICAgc3VwZXIob3duZXIpOwogICAgICAgIH0KCiAgICAgICAgLyoqIEVudGVyIHRoZSBnaXZlbiBTeW1ib2wgaW50byB0aGlzIHNjb3BlLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIGVudGVyKFN5bWJvbCBjKTsKICAgICAgICAvKiogRW50ZXIgc3ltYm9sIHN5bSBpbiB0aGlzIHNjb3BlIGlmIG5vdCBhbHJlYWR5IHRoZXJlLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIGVudGVySWZBYnNlbnQoU3ltYm9sIGMpOwoKICAgICAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCByZW1vdmUoU3ltYm9sIGMpOwoKICAgICAgICAvKiogQ29uc3RydWN0IGEgZnJlc2ggc2NvcGUgd2l0aGluIHRoaXMgc2NvcGUsIHdpdGggc2FtZSBvd25lci4gVGhlIG5ldyBzY29wZSBtYXkKICAgICAgICAgKiAgc2hhcmVzIGludGVybmFsIHN0cnVjdHVyZXMgd2l0aCB0aGUgdGhpcyBzY29wZS4gVXNlZCBpbiBjb25uZWN0aW9uIHdpdGgKICAgICAgICAgKiAgbWV0aG9kIGxlYXZlIGlmIHNjb3BlIGFjY2VzcyBpcyBzdGFjay1saWtlIGluIG9yZGVyIHRvIGF2b2lkIGFsbG9jYXRpb24KICAgICAgICAgKiAgb2YgZnJlc2ggdGFibGVzLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBmaW5hbCBXcml0ZWFibGVTY29wZSBkdXAoKSB7CiAgICAgICAgICAgIHJldHVybiBkdXAodGhpcy5vd25lcik7CiAgICAgICAgfQoKICAgICAgICAvKiogQ29uc3RydWN0IGEgZnJlc2ggc2NvcGUgd2l0aGluIHRoaXMgc2NvcGUsIHdpdGggbmV3IG93bmVyLiBUaGUgbmV3IHNjb3BlIG1heQogICAgICAgICAqICBzaGFyZXMgaW50ZXJuYWwgc3RydWN0dXJlcyB3aXRoIHRoZSB0aGlzIHNjb3BlLiBVc2VkIGluIGNvbm5lY3Rpb24gd2l0aAogICAgICAgICAqICBtZXRob2QgbGVhdmUgaWYgc2NvcGUgYWNjZXNzIGlzIHN0YWNrLWxpa2UgaW4gb3JkZXIgdG8gYXZvaWQgYWxsb2NhdGlvbgogICAgICAgICAqICBvZiBmcmVzaCB0YWJsZXMuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIGFic3RyYWN0IFdyaXRlYWJsZVNjb3BlIGR1cChTeW1ib2wgbmV3T3duZXIpOwoKICAgICAgICAvKiogTXVzdCBiZSBjYWxsZWQgb24gZHVwLWVkIHNjb3BlcyB0byBiZSBhYmxlIHRvIHdvcmsgd2l0aCB0aGUgb3V0d2FyZCBzY29wZSBhZ2Fpbi4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgYWJzdHJhY3QgV3JpdGVhYmxlU2NvcGUgbGVhdmUoKTsKCiAgICAgICAgLyoqIENvbnN0cnVjdCBhIGZyZXNoIHNjb3BlIHdpdGhpbiB0aGlzIHNjb3BlLCB3aXRoIHNhbWUgb3duZXIuIFRoZSBuZXcgc2NvcGUKICAgICAgICAgKiAgd2lsbCBub3Qgc2hhcmUgaW50ZXJuYWwgc3RydWN0dXJlcyB3aXRoIHRoaXMgc2NvcGUuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIGZpbmFsIFdyaXRlYWJsZVNjb3BlIGR1cFVuc2hhcmVkKCkgewogICAgICAgICAgICByZXR1cm4gZHVwVW5zaGFyZWQob3duZXIpOwogICAgICAgIH0KCiAgICAgICAgLyoqIENvbnN0cnVjdCBhIGZyZXNoIHNjb3BlIHdpdGhpbiB0aGlzIHNjb3BlLCB3aXRoIG5ldyBvd25lci4gVGhlIG5ldyBzY29wZQogICAgICAgICAqICB3aWxsIG5vdCBzaGFyZSBpbnRlcm5hbCBzdHJ1Y3R1cmVzIHdpdGggdGhpcyBzY29wZS4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgYWJzdHJhY3QgV3JpdGVhYmxlU2NvcGUgZHVwVW5zaGFyZWQoU3ltYm9sIG5ld093bmVyKTsKCiAgICAgICAgLyoqIENyZWF0ZSBhIG5ldyBXcml0ZWFibGVTY29wZS4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgc3RhdGljIFdyaXRlYWJsZVNjb3BlIGNyZWF0ZShTeW1ib2wgb3duZXIpIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyBTY29wZUltcGwob3duZXIpOwogICAgICAgIH0KCiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgU2NvcGVJbXBsIGV4dGVuZHMgV3JpdGVhYmxlU2NvcGUgewogICAgICAgIC8qKiBUaGUgbnVtYmVyIG9mIHNjb3BlcyB0aGF0IHNoYXJlIHRoaXMgc2NvcGUncyBoYXNoIHRhYmxlLgogICAgICAgICAqLwogICAgICAgIHByaXZhdGUgaW50IHNoYXJlZDsKCiAgICAgICAgLyoqIE5leHQgZW5jbG9zaW5nIHNjb3BlICh3aXRoIHdob20gdGhpcyBzY29wZSBtYXkgc2hhcmUgYSBoYXNodGFibGUpCiAgICAgICAgICovCiAgICAgICAgcHVibGljIFNjb3BlSW1wbCBuZXh0OwoKICAgICAgICAvKiogQSBoYXNoIHRhYmxlIGZvciB0aGUgc2NvcGUncyBlbnRyaWVzLgogICAgICAgICAqLwogICAgICAgIEVudHJ5W10gdGFibGU7CgogICAgICAgIC8qKiBNYXNrIGZvciBoYXNoIGNvZGVzLCBhbHdheXMgZXF1YWwgdG8gKHRhYmxlLmxlbmd0aCAtIDEpLgogICAgICAgICAqLwogICAgICAgIGludCBoYXNoTWFzazsKCiAgICAgICAgLyoqIEEgbGluZWFyIGxpc3QgdGhhdCBhbHNvIGNvbnRhaW5zIGFsbCBlbnRyaWVzIGluCiAgICAgICAgICogIHJldmVyc2Ugb3JkZXIgb2YgYXBwZWFyYW5jZSAoaS5lIGxhdGVyIGVudHJpZXMgYXJlIHB1c2hlZCBvbiB0b3ApLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBFbnRyeSBlbGVtczsKCiAgICAgICAgLyoqIFRoZSBudW1iZXIgb2YgZWxlbWVudHMgaW4gdGhpcyBzY29wZS4KICAgICAgICAgKiBUaGlzIGluY2x1ZGVzIGRlbGV0ZWQgZWxlbWVudHMsIHdob3NlIHZhbHVlIGlzIHRoZSBzZW50aW5lbC4KICAgICAgICAgKi8KICAgICAgICBpbnQgbmVsZW1zID0gMDsKCiAgICAgICAgaW50IHJlbW92ZUNvdW50ID0gMDsKCiAgICAgICAgLyoqIFVzZSBhcyBhICJub3QtZm91bmQiIHJlc3VsdCBmb3IgbG9va3VwLgogICAgICAgICAqIEFsc28gdXNlZCB0byBtYXJrIGRlbGV0ZWQgZW50cmllcyBpbiB0aGUgdGFibGUuCiAgICAgICAgICovCiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgRW50cnkgc2VudGluZWwgPSBuZXcgRW50cnkobnVsbCwgbnVsbCwgbnVsbCwgbnVsbCk7CgogICAgICAgIC8qKiBUaGUgaGFzaCB0YWJsZSdzIGluaXRpYWwgc2l6ZS4KICAgICAgICAgKi8KICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgSU5JVElBTF9TSVpFID0gMHgxMDsKCiAgICAgICAgLyoqIENvbnN0cnVjdCBhIG5ldyBzY29wZSwgd2l0aGluIHNjb3BlIG5leHQsIHdpdGggZ2l2ZW4gb3duZXIsIHVzaW5nCiAgICAgICAgICogIGdpdmVuIHRhYmxlLiBUaGUgdGFibGUncyBsZW5ndGggbXVzdCBiZSBhbiBleHBvbmVudCBvZiAyLgogICAgICAgICAqLwogICAgICAgIHByaXZhdGUgU2NvcGVJbXBsKFNjb3BlSW1wbCBuZXh0LCBTeW1ib2wgb3duZXIsIEVudHJ5W10gdGFibGUpIHsKICAgICAgICAgICAgc3VwZXIob3duZXIpOwogICAgICAgICAgICB0aGlzLm5leHQgPSBuZXh0OwogICAgICAgICAgICBBc3NlcnQuY2hlY2sob3duZXIgIT0gbnVsbCk7CiAgICAgICAgICAgIHRoaXMudGFibGUgPSB0YWJsZTsKICAgICAgICAgICAgdGhpcy5oYXNoTWFzayA9IHRhYmxlLmxlbmd0aCAtIDE7CiAgICAgICAgfQoKICAgICAgICAvKiogQ29udmVuaWVuY2UgY29uc3RydWN0b3IgdXNlZCBmb3IgZHVwIGFuZCBkdXBVbnNoYXJlZC4gKi8KICAgICAgICBwcml2YXRlIFNjb3BlSW1wbChTY29wZUltcGwgbmV4dCwgU3ltYm9sIG93bmVyLCBFbnRyeVtdIHRhYmxlLCBpbnQgbmVsZW1zKSB7CiAgICAgICAgICAgIHRoaXMobmV4dCwgb3duZXIsIHRhYmxlKTsKICAgICAgICAgICAgdGhpcy5uZWxlbXMgPSBuZWxlbXM7CiAgICAgICAgfQoKICAgICAgICAvKiogQ29uc3RydWN0IGEgbmV3IHNjb3BlLCB3aXRoaW4gc2NvcGUgbmV4dCwgd2l0aCBnaXZlbiBvd25lciwKICAgICAgICAgKiAgdXNpbmcgYSBmcmVzaCB0YWJsZSBvZiBsZW5ndGggSU5JVElBTF9TSVpFLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBTY29wZUltcGwoU3ltYm9sIG93bmVyKSB7CiAgICAgICAgICAgIHRoaXMobnVsbCwgb3duZXIsIG5ldyBFbnRyeVtJTklUSUFMX1NJWkVdKTsKICAgICAgICB9CgogICAgICAgIC8qKiBDb25zdHJ1Y3QgYSBmcmVzaCBzY29wZSB3aXRoaW4gdGhpcyBzY29wZSwgd2l0aCBuZXcgb3duZXIsCiAgICAgICAgICogIHdoaWNoIHNoYXJlcyBpdHMgdGFibGUgd2l0aCB0aGUgb3V0ZXIgc2NvcGUuIFVzZWQgaW4gY29ubmVjdGlvbiB3aXRoCiAgICAgICAgICogIG1ldGhvZCBsZWF2ZSBpZiBzY29wZSBhY2Nlc3MgaXMgc3RhY2stbGlrZSBpbiBvcmRlciB0byBhdm9pZCBhbGxvY2F0aW9uCiAgICAgICAgICogIG9mIGZyZXNoIHRhYmxlcy4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgV3JpdGVhYmxlU2NvcGUgZHVwKFN5bWJvbCBuZXdPd25lcikgewogICAgICAgICAgICBTY29wZUltcGwgcmVzdWx0ID0gbmV3IFNjb3BlSW1wbCh0aGlzLCBuZXdPd25lciwgdGhpcy50YWJsZSwgdGhpcy5uZWxlbXMpOwogICAgICAgICAgICBzaGFyZWQrKzsKICAgICAgICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCI9PT09PiBkdXBpbmcgc2NvcGUgIiArIHRoaXMuaGFzaENvZGUoKSArICIgb3duZWQgYnkgIiArIG5ld093bmVyICsgIiB0byAiICsgcmVzdWx0Lmhhc2hDb2RlKCkpOwogICAgICAgICAgICAvLyBuZXcgRXJyb3IoKS5wcmludFN0YWNrVHJhY2UoU3lzdGVtLm91dCk7CiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfQoKICAgICAgICAvKiogQ29uc3RydWN0IGEgZnJlc2ggc2NvcGUgd2l0aGluIHRoaXMgc2NvcGUsIHdpdGggbmV3IG93bmVyLAogICAgICAgICAqICB3aXRoIGEgbmV3IGhhc2ggdGFibGUsIHdob3NlIGNvbnRlbnRzIGluaXRpYWxseSBhcmUgdGhvc2Ugb2YKICAgICAgICAgKiAgdGhlIHRhYmxlIG9mIGl0cyBvdXRlciBzY29wZS4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgV3JpdGVhYmxlU2NvcGUgZHVwVW5zaGFyZWQoU3ltYm9sIG5ld093bmVyKSB7CiAgICAgICAgICAgIGlmIChzaGFyZWQgPiAwKSB7CiAgICAgICAgICAgICAgICAvL1RoZSBuZXN0ZWQgU2NvcGVzIG1pZ2h0IGhhdmUgYWxyZWFkeSBhZGRlZCBzb21ldGhpbmcgdG8gdGhlIHRhYmxlLCBzbyBhbGwgaXRlbXMKICAgICAgICAgICAgICAgIC8vdGhhdCBkb24ndCBvcmlnaW5hdGUgaW4gdGhpcyBTY29wZSBvciBhbnkgb2YgaXRzIG91dGVyIFNjb3BlcyBuZWVkIHRvIGJlIGNsZWFyZWQ6CiAgICAgICAgICAgICAgICBTZXQ8U2NvcGU+IGFjY2VwdFNjb3BlcyA9IENvbGxlY3Rpb25zLm5ld1NldEZyb21NYXAobmV3IElkZW50aXR5SGFzaE1hcDw+KCkpOwogICAgICAgICAgICAgICAgU2NvcGVJbXBsIGMgPSB0aGlzOwogICAgICAgICAgICAgICAgd2hpbGUgKGMgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIGFjY2VwdFNjb3Blcy5hZGQoYyk7CiAgICAgICAgICAgICAgICAgICAgYyA9IGMubmV4dDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGludCBuID0gMDsKICAgICAgICAgICAgICAgIEVudHJ5W10gb2xkVGFibGUgPSB0aGlzLnRhYmxlOwogICAgICAgICAgICAgICAgRW50cnlbXSBuZXdUYWJsZSA9IG5ldyBFbnRyeVt0aGlzLnRhYmxlLmxlbmd0aF07CiAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG9sZFRhYmxlLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgRW50cnkgZSA9IG9sZFRhYmxlW2ldOwogICAgICAgICAgICAgICAgICAgIHdoaWxlIChlICE9IG51bGwgJiYgZSAhPSBzZW50aW5lbCAmJiAhYWNjZXB0U2NvcGVzLmNvbnRhaW5zKGUuc2NvcGUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGUgPSBlLnNoYWRvd2VkOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoZSAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIG4rKzsKICAgICAgICAgICAgICAgICAgICAgICAgbmV3VGFibGVbaV0gPSBlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBuZXcgU2NvcGVJbXBsKHRoaXMsIG5ld093bmVyLCBuZXdUYWJsZSwgbik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFNjb3BlSW1wbCh0aGlzLCBuZXdPd25lciwgdGhpcy50YWJsZS5jbG9uZSgpLCB0aGlzLm5lbGVtcyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8qKiBSZW1vdmUgYWxsIGVudHJpZXMgb2YgdGhpcyBzY29wZSBmcm9tIGl0cyB0YWJsZSwgaWYgc2hhcmVkCiAgICAgICAgICogIHdpdGggbmV4dC4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgV3JpdGVhYmxlU2NvcGUgbGVhdmUoKSB7CiAgICAgICAgICAgIEFzc2VydC5jaGVjayhzaGFyZWQgPT0gMCk7CiAgICAgICAgICAgIGlmICh0YWJsZSAhPSBuZXh0LnRhYmxlKSByZXR1cm4gbmV4dDsKICAgICAgICAgICAgd2hpbGUgKGVsZW1zICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIGludCBoYXNoID0gZ2V0SW5kZXgoZWxlbXMuc3ltLm5hbWUpOwogICAgICAgICAgICAgICAgRW50cnkgZSA9IHRhYmxlW2hhc2hdOwogICAgICAgICAgICAgICAgQXNzZXJ0LmNoZWNrKGUgPT0gZWxlbXMsIGVsZW1zLnN5bSk7CiAgICAgICAgICAgICAgICB0YWJsZVtoYXNoXSA9IGVsZW1zLnNoYWRvd2VkOwogICAgICAgICAgICAgICAgZWxlbXMgPSBlbGVtcy5zaWJsaW5nOwogICAgICAgICAgICB9CiAgICAgICAgICAgIEFzc2VydC5jaGVjayhuZXh0LnNoYXJlZCA+IDApOwogICAgICAgICAgICBuZXh0LnNoYXJlZC0tOwogICAgICAgICAgICBuZXh0Lm5lbGVtcyA9IG5lbGVtczsKICAgICAgICAgICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCI9PT09PiBsZWF2aW5nIHNjb3BlICIgKyB0aGlzLmhhc2hDb2RlKCkgKyAiIG93bmVkIGJ5ICIgKyB0aGlzLm93bmVyICsgIiB0byAiICsgbmV4dC5oYXNoQ29kZSgpKTsKICAgICAgICAgICAgLy8gbmV3IEVycm9yKCkucHJpbnRTdGFja1RyYWNlKFN5c3RlbS5vdXQpOwogICAgICAgICAgICByZXR1cm4gbmV4dDsKICAgICAgICB9CgogICAgICAgIC8qKiBEb3VibGUgc2l6ZSBvZiBoYXNoIHRhYmxlLgogICAgICAgICAqLwogICAgICAgIHByaXZhdGUgdm9pZCBkYmxlKCkgewogICAgICAgICAgICBBc3NlcnQuY2hlY2soc2hhcmVkID09IDApOwogICAgICAgICAgICBFbnRyeVtdIG9sZHRhYmxlID0gdGFibGU7CiAgICAgICAgICAgIEVudHJ5W10gbmV3dGFibGUgPSBuZXcgRW50cnlbb2xkdGFibGUubGVuZ3RoICogMl07CiAgICAgICAgICAgIGZvciAoU2NvcGVJbXBsIHMgPSB0aGlzOyBzICE9IG51bGw7IHMgPSBzLm5leHQpIHsKICAgICAgICAgICAgICAgIGlmIChzLnRhYmxlID09IG9sZHRhYmxlKSB7CiAgICAgICAgICAgICAgICAgICAgQXNzZXJ0LmNoZWNrKHMgPT0gdGhpcyB8fCBzLnNoYXJlZCAhPSAwKTsKICAgICAgICAgICAgICAgICAgICBzLnRhYmxlID0gbmV3dGFibGU7CiAgICAgICAgICAgICAgICAgICAgcy5oYXNoTWFzayA9IG5ld3RhYmxlLmxlbmd0aCAtIDE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaW50IG4gPSAwOwogICAgICAgICAgICBmb3IgKGludCBpID0gb2xkdGFibGUubGVuZ3RoOyAtLWkgPj0gMDsgKSB7CiAgICAgICAgICAgICAgICBFbnRyeSBlID0gb2xkdGFibGVbaV07CiAgICAgICAgICAgICAgICBpZiAoZSAhPSBudWxsICYmIGUgIT0gc2VudGluZWwpIHsKICAgICAgICAgICAgICAgICAgICB0YWJsZVtnZXRJbmRleChlLnN5bS5uYW1lKV0gPSBlOwogICAgICAgICAgICAgICAgICAgIG4rKzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICAvLyBXZSBkb24ndCBuZWVkIHRvIHVwZGF0ZSBuZWxlbXMgZm9yIHNoYXJlZCBpbmhlcml0ZWQgc2NvcGVzLAogICAgICAgICAgICAvLyBzaW5jZSB0aGF0IGdldHMgaGFuZGxlZCBieSBsZWF2ZSgpLgogICAgICAgICAgICBuZWxlbXMgPSBuOwogICAgICAgIH0KCiAgICAgICAgLyoqIEVudGVyIHN5bWJvbCBzeW0gaW4gdGhpcyBzY29wZS4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgdm9pZCBlbnRlcihTeW1ib2wgc3ltKSB7CiAgICAgICAgICAgIEFzc2VydC5jaGVjayhzaGFyZWQgPT0gMCk7CiAgICAgICAgICAgIGlmIChuZWxlbXMgKiAzID49IGhhc2hNYXNrICogMikKICAgICAgICAgICAgICAgIGRibGUoKTsKICAgICAgICAgICAgaW50IGhhc2ggPSBnZXRJbmRleChzeW0ubmFtZSk7CiAgICAgICAgICAgIEVudHJ5IG9sZCA9IHRhYmxlW2hhc2hdOwogICAgICAgICAgICBpZiAob2xkID09IG51bGwpIHsKICAgICAgICAgICAgICAgIG9sZCA9IHNlbnRpbmVsOwogICAgICAgICAgICAgICAgbmVsZW1zKys7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgRW50cnkgZSA9IG5ldyBFbnRyeShzeW0sIG9sZCwgZWxlbXMsIHRoaXMpOwogICAgICAgICAgICB0YWJsZVtoYXNoXSA9IGU7CiAgICAgICAgICAgIGVsZW1zID0gZTsKCiAgICAgICAgICAgIC8vbm90aWZ5IGxpc3RlbmVycwogICAgICAgICAgICBsaXN0ZW5lcnMuc3ltYm9sQWRkZWQoc3ltLCB0aGlzKTsKICAgICAgICB9CgogICAgICAgIC8qKiBSZW1vdmUgc3ltYm9sIGZyb20gdGhpcyBzY29wZS4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgdm9pZCByZW1vdmUoU3ltYm9sIHN5bSkgewogICAgICAgICAgICBBc3NlcnQuY2hlY2soc2hhcmVkID09IDApOwogICAgICAgICAgICBFbnRyeSBlID0gbG9va3VwKHN5bS5uYW1lLCBjYW5kaWRhdGUgLT4gY2FuZGlkYXRlID09IHN5bSk7CiAgICAgICAgICAgIGlmIChlLnNjb3BlID09IG51bGwpIHJldHVybjsKCiAgICAgICAgICAgIC8vIHJlbW92ZSBlIGZyb20gdGFibGUgYW5kIHNoYWRvd2VkIGxpc3Q7CiAgICAgICAgICAgIGludCBpID0gZ2V0SW5kZXgoc3ltLm5hbWUpOwogICAgICAgICAgICBFbnRyeSB0ZSA9IHRhYmxlW2ldOwogICAgICAgICAgICBpZiAodGUgPT0gZSkKICAgICAgICAgICAgICAgIHRhYmxlW2ldID0gZS5zaGFkb3dlZDsKICAgICAgICAgICAgZWxzZSB3aGlsZSAodHJ1ZSkgewogICAgICAgICAgICAgICAgaWYgKHRlLnNoYWRvd2VkID09IGUpIHsKICAgICAgICAgICAgICAgICAgICB0ZS5zaGFkb3dlZCA9IGUuc2hhZG93ZWQ7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB0ZSA9IHRlLnNoYWRvd2VkOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyByZW1vdmUgZSBmcm9tIGVsZW1zIGFuZCBzaWJsaW5nIGxpc3QKICAgICAgICAgICAgdGUgPSBlbGVtczsKICAgICAgICAgICAgaWYgKHRlID09IGUpCiAgICAgICAgICAgICAgICBlbGVtcyA9IGUuc2libGluZzsKICAgICAgICAgICAgZWxzZSB3aGlsZSAodHJ1ZSkgewogICAgICAgICAgICAgICAgaWYgKHRlLnNpYmxpbmcgPT0gZSkgewogICAgICAgICAgICAgICAgICAgIHRlLnNpYmxpbmcgPSBlLnNpYmxpbmc7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB0ZSA9IHRlLnNpYmxpbmc7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJlbW92ZUNvdW50Kys7CgogICAgICAgICAgICAvL25vdGlmeSBsaXN0ZW5lcnMKICAgICAgICAgICAgbGlzdGVuZXJzLnN5bWJvbFJlbW92ZWQoc3ltLCB0aGlzKTsKICAgICAgICB9CgogICAgICAgIC8qKiBFbnRlciBzeW1ib2wgc3ltIGluIHRoaXMgc2NvcGUgaWYgbm90IGFscmVhZHkgdGhlcmUuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIHZvaWQgZW50ZXJJZkFic2VudChTeW1ib2wgc3ltKSB7CiAgICAgICAgICAgIEFzc2VydC5jaGVjayhzaGFyZWQgPT0gMCk7CiAgICAgICAgICAgIEVudHJ5IGUgPSBsb29rdXAoc3ltLm5hbWUpOwogICAgICAgICAgICB3aGlsZSAoZS5zY29wZSA9PSB0aGlzICYmIGUuc3ltLmtpbmQgIT0gc3ltLmtpbmQpIGUgPSBlLm5leHQoKTsKICAgICAgICAgICAgaWYgKGUuc2NvcGUgIT0gdGhpcykgZW50ZXIoc3ltKTsKICAgICAgICB9CgogICAgICAgIC8qKiBHaXZlbiBhIGNsYXNzLCBpcyB0aGVyZSBhbHJlYWR5IGEgY2xhc3Mgd2l0aCBzYW1lIGZ1bGx5CiAgICAgICAgICogIHF1YWxpZmllZCBuYW1lIGluIHRoaXMgKGltcG9ydCkgc2NvcGU/CiAgICAgICAgICovCiAgICAgICAgcHVibGljIGJvb2xlYW4gaW5jbHVkZXMoU3ltYm9sIGMpIHsKICAgICAgICAgICAgZm9yIChTY29wZS5FbnRyeSBlID0gbG9va3VwKGMubmFtZSk7CiAgICAgICAgICAgICAgICAgZS5zY29wZSA9PSB0aGlzOwogICAgICAgICAgICAgICAgIGUgPSBlLm5leHQoKSkgewogICAgICAgICAgICAgICAgaWYgKGUuc3ltID09IGMpIHJldHVybiB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIC8qKiBSZXR1cm4gdGhlIGVudHJ5IGFzc29jaWF0ZWQgd2l0aCBnaXZlbiBuYW1lLCBzdGFydGluZyBpbgogICAgICAgICAqICB0aGlzIHNjb3BlIGFuZCBwcm9jZWVkaW5nIG91dHdhcmRzLiBJZiBubyBlbnRyeSB3YXMgZm91bmQsCiAgICAgICAgICogIHJldHVybiB0aGUgc2VudGluZWwsIHdoaWNoIGlzIGNoYXJhY3Rlcml6ZWQgYnkgaGF2aW5nIGEgbnVsbCBpbgogICAgICAgICAqICBib3RoIGl0cyBzY29wZSBhbmQgc3ltIGZpZWxkcywgd2hlcmVhcyBib3RoIGZpZWxkcyBhcmUgbm9uLW51bGwKICAgICAgICAgKiAgZm9yIHJlZ3VsYXIgZW50cmllcy4KICAgICAgICAgKi8KICAgICAgICBwcm90ZWN0ZWQgRW50cnkgbG9va3VwKE5hbWUgbmFtZSkgewogICAgICAgICAgICByZXR1cm4gbG9va3VwKG5hbWUsIG5vRmlsdGVyKTsKICAgICAgICB9CgogICAgICAgIHByb3RlY3RlZCBFbnRyeSBsb29rdXAoTmFtZSBuYW1lLCBGaWx0ZXI8U3ltYm9sPiBzZikgewogICAgICAgICAgICBFbnRyeSBlID0gdGFibGVbZ2V0SW5kZXgobmFtZSldOwogICAgICAgICAgICBpZiAoZSA9PSBudWxsIHx8IGUgPT0gc2VudGluZWwpCiAgICAgICAgICAgICAgICByZXR1cm4gc2VudGluZWw7CiAgICAgICAgICAgIHdoaWxlIChlLnNjb3BlICE9IG51bGwgJiYgKGUuc3ltLm5hbWUgIT0gbmFtZSB8fCAoc2YgIT0gbnVsbCAmJiAhc2YuYWNjZXB0cyhlLnN5bSkpKSkKICAgICAgICAgICAgICAgIGUgPSBlLnNoYWRvd2VkOwogICAgICAgICAgICByZXR1cm4gZTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBTeW1ib2wgZmluZEZpcnN0KE5hbWUgbmFtZSwgRmlsdGVyPFN5bWJvbD4gc2YpIHsKICAgICAgICAgICAgcmV0dXJuIGxvb2t1cChuYW1lLCBzZikuc3ltOwogICAgICAgIH0KCiAgICAgICAgLyp2b2lkIGR1bXAgKGphdmEuaW8uUHJpbnRTdHJlYW0gb3V0KSB7CiAgICAgICAgICAgIG91dC5wcmludGxuKHRoaXMpOwogICAgICAgICAgICBmb3IgKGludCBsPTA7IGwgPCB0YWJsZS5sZW5ndGg7IGwrKykgewogICAgICAgICAgICAgICAgRW50cnkgbGUgPSB0YWJsZVtsXTsKICAgICAgICAgICAgICAgIG91dC5wcmludCgiIyIrbCsiOiAiKTsKICAgICAgICAgICAgICAgIGlmIChsZT09c2VudGluZWwpIG91dC5wcmludGxuKCJzZW50aW5lbCIpOwogICAgICAgICAgICAgICAgZWxzZSBpZihsZSA9PSBudWxsKSBvdXQucHJpbnRsbigibnVsbCIpOwogICAgICAgICAgICAgICAgZWxzZSBvdXQucHJpbnRsbigiIitsZSsiIHM6IitsZS5zeW0pOwogICAgICAgICAgICB9CiAgICAgICAgfSovCgogICAgICAgIC8qKiBMb29rIGZvciBzbG90IGluIHRoZSB0YWJsZS4KICAgICAgICAgKiAgV2UgdXNlIG9wZW4gYWRkcmVzc2luZyB3aXRoIGRvdWJsZSBoYXNoaW5nLgogICAgICAgICAqLwogICAgICAgIGludCBnZXRJbmRleCAoTmFtZSBuYW1lKSB7CiAgICAgICAgICAgIGludCBoID0gbmFtZS5oYXNoQ29kZSgpOwogICAgICAgICAgICBpbnQgaSA9IGggJiBoYXNoTWFzazsKICAgICAgICAgICAgLy8gVGhlIGV4cHJlc3Npb24gYmVsb3cgaXMgYWx3YXlzIG9kZCwgc28gaXQgaXMgZ3VhcmFudGVlZAogICAgICAgICAgICAvLyB0byBiZSBtdXR1YWxseSBwcmltZSB3aXRoIHRhYmxlLmxlbmd0aCwgYSBwb3dlciBvZiAyLgogICAgICAgICAgICBpbnQgeCA9IGhhc2hNYXNrIC0gKChoICsgKGggPj4gMTYpKSA8PCAxKTsKICAgICAgICAgICAgaW50IGQgPSAtMTsgLy8gSW5kZXggb2YgYSBkZWxldGVkIGl0ZW0uCiAgICAgICAgICAgIGZvciAoOzspIHsKICAgICAgICAgICAgICAgIEVudHJ5IGUgPSB0YWJsZVtpXTsKICAgICAgICAgICAgICAgIGlmIChlID09IG51bGwpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGQgPj0gMCA/IGQgOiBpOwogICAgICAgICAgICAgICAgaWYgKGUgPT0gc2VudGluZWwpIHsKICAgICAgICAgICAgICAgICAgICAvLyBXZSBoYXZlIHRvIGtlZXAgc2VhcmNoaW5nIGV2ZW4gaWYgd2Ugc2VlIGEgZGVsZXRlZCBpdGVtLgogICAgICAgICAgICAgICAgICAgIC8vIEhvd2V2ZXIsIHJlbWVtYmVyIHRoZSBpbmRleCBpbiBjYXNlIHdlIGZhaWwgdG8gZmluZCB0aGUgbmFtZS4KICAgICAgICAgICAgICAgICAgICBpZiAoZCA8IDApCiAgICAgICAgICAgICAgICAgICAgICAgIGQgPSBpOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChlLnN5bS5uYW1lID09IG5hbWUpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGk7CiAgICAgICAgICAgICAgICBpID0gKGkgKyB4KSAmIGhhc2hNYXNrOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgYm9vbGVhbiBhbnlNYXRjaChGaWx0ZXI8U3ltYm9sPiBzZikgewogICAgICAgICAgICByZXR1cm4gZ2V0U3ltYm9scyhzZiwgTk9OX1JFQ1VSU0lWRSkuaXRlcmF0b3IoKS5oYXNOZXh0KCk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgSXRlcmFibGU8U3ltYm9sPiBnZXRTeW1ib2xzKGZpbmFsIEZpbHRlcjxTeW1ib2w+IHNmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgTG9va3VwS2luZCBsb29rdXBLaW5kKSB7CiAgICAgICAgICAgIHJldHVybiAoKSAtPiBuZXcgSXRlcmF0b3I8U3ltYm9sPigpIHsKICAgICAgICAgICAgICAgIHByaXZhdGUgU2NvcGVJbXBsIGN1cnJTY29wZSA9IFNjb3BlSW1wbC50aGlzOwogICAgICAgICAgICAgICAgcHJpdmF0ZSBFbnRyeSBjdXJyRW50cnkgPSBlbGVtczsKICAgICAgICAgICAgICAgIHByaXZhdGUgaW50IHNlZW5SZW1vdmVDb3VudCA9IGN1cnJTY29wZS5yZW1vdmVDb3VudDsKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB1cGRhdGUoKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNOZXh0KCkgewogICAgICAgICAgICAgICAgICAgIGlmIChzZWVuUmVtb3ZlQ291bnQgIT0gY3VyclNjb3BlLnJlbW92ZUNvdW50ICYmCiAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJFbnRyeSAhPSBudWxsICYmCiAgICAgICAgICAgICAgICAgICAgICAgICFjdXJyRW50cnkuc2NvcGUuaW5jbHVkZXMoY3VyckVudHJ5LnN5bSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgZG9OZXh0KCk7IC8vc2tpcCBlbnRyeSB0aGF0IGlzIG5vIGxvbmdlciBpbiB0aGUgU2NvcGUKICAgICAgICAgICAgICAgICAgICAgICAgc2VlblJlbW92ZUNvdW50ID0gY3VyclNjb3BlLnJlbW92ZUNvdW50OwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICByZXR1cm4gY3VyckVudHJ5ICE9IG51bGw7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcHVibGljIFN5bWJvbCBuZXh0KCkgewogICAgICAgICAgICAgICAgICAgIGlmICghaGFzTmV4dCgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZG9OZXh0KCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBwcml2YXRlIFN5bWJvbCBkb05leHQoKSB7CiAgICAgICAgICAgICAgICAgICAgU3ltYm9sIHN5bSA9IChjdXJyRW50cnkgPT0gbnVsbCA/IG51bGwgOiBjdXJyRW50cnkuc3ltKTsKICAgICAgICAgICAgICAgICAgICBpZiAoY3VyckVudHJ5ICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY3VyckVudHJ5ID0gY3VyckVudHJ5LnNpYmxpbmc7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHVwZGF0ZSgpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBzeW07CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcHJpdmF0ZSB2b2lkIHVwZGF0ZSgpIHsKICAgICAgICAgICAgICAgICAgICBza2lwVG9OZXh0TWF0Y2hpbmdFbnRyeSgpOwogICAgICAgICAgICAgICAgICAgIGlmIChsb29rdXBLaW5kID09IFJFQ1VSU0lWRSkgewogICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoY3VyckVudHJ5ID09IG51bGwgJiYgY3VyclNjb3BlLm5leHQgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VyclNjb3BlID0gY3VyclNjb3BlLm5leHQ7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyRW50cnkgPSBjdXJyU2NvcGUuZWxlbXM7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWVuUmVtb3ZlQ291bnQgPSBjdXJyU2NvcGUucmVtb3ZlQ291bnQ7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBza2lwVG9OZXh0TWF0Y2hpbmdFbnRyeSgpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHZvaWQgc2tpcFRvTmV4dE1hdGNoaW5nRW50cnkoKSB7CiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGN1cnJFbnRyeSAhPSBudWxsICYmIHNmICE9IG51bGwgJiYgIXNmLmFjY2VwdHMoY3VyckVudHJ5LnN5bSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY3VyckVudHJ5ID0gY3VyckVudHJ5LnNpYmxpbmc7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwogICAgICAgIH0KCiAgICAgICAgcHVibGljIEl0ZXJhYmxlPFN5bWJvbD4gZ2V0U3ltYm9sc0J5TmFtZShmaW5hbCBOYW1lIG5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBGaWx0ZXI8U3ltYm9sPiBzZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIExvb2t1cEtpbmQgbG9va3VwS2luZCkgewogICAgICAgICAgICByZXR1cm4gKCkgLT4gbmV3IEl0ZXJhdG9yPFN5bWJvbD4oKSB7CiAgICAgICAgICAgICAgIEVudHJ5IGN1cnJlbnRFbnRyeSA9IGxvb2t1cChuYW1lLCBzZik7CiAgICAgICAgICAgICAgIGludCBzZWVuUmVtb3ZlQ291bnQgPSBjdXJyZW50RW50cnkuc2NvcGUgIT0gbnVsbCA/CiAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudEVudHJ5LnNjb3BlLnJlbW92ZUNvdW50IDogLTE7CgogICAgICAgICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNOZXh0KCkgewogICAgICAgICAgICAgICAgICAgaWYgKGN1cnJlbnRFbnRyeS5zY29wZSAhPSBudWxsICYmCiAgICAgICAgICAgICAgICAgICAgICAgc2VlblJlbW92ZUNvdW50ICE9IGN1cnJlbnRFbnRyeS5zY29wZS5yZW1vdmVDb3VudCAmJgogICAgICAgICAgICAgICAgICAgICAgICFjdXJyZW50RW50cnkuc2NvcGUuaW5jbHVkZXMoY3VycmVudEVudHJ5LnN5bSkpIHsKICAgICAgICAgICAgICAgICAgICAgICBkb05leHQoKTsgLy9za2lwIGVudHJ5IHRoYXQgaXMgbm8gbG9uZ2VyIGluIHRoZSBTY29wZQogICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgcmV0dXJuIGN1cnJlbnRFbnRyeS5zY29wZSAhPSBudWxsICYmCiAgICAgICAgICAgICAgICAgICAgICAgICAgIChsb29rdXBLaW5kID09IFJFQ1VSU0lWRSB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudEVudHJ5LnNjb3BlID09IFNjb3BlSW1wbC50aGlzKTsKICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICBwdWJsaWMgU3ltYm9sIG5leHQoKSB7CiAgICAgICAgICAgICAgICAgICBpZiAoIWhhc05leHQoKSkgewogICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICByZXR1cm4gZG9OZXh0KCk7CiAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgcHJpdmF0ZSBTeW1ib2wgZG9OZXh0KCkgewogICAgICAgICAgICAgICAgICAgRW50cnkgcHJldkVudHJ5ID0gY3VycmVudEVudHJ5OwogICAgICAgICAgICAgICAgICAgY3VycmVudEVudHJ5ID0gY3VycmVudEVudHJ5Lm5leHQoc2YpOwogICAgICAgICAgICAgICAgICAgcmV0dXJuIHByZXZFbnRyeS5zeW07CiAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgcHVibGljIHZvaWQgcmVtb3ZlKCkgewogICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CiAgICAgICAgICAgICAgIH0KICAgICAgICAgICB9OwogICAgICAgIH0KCiAgICAgICAgcHVibGljIFNjb3BlIGdldE9yaWdpbihTeW1ib2wgcykgewogICAgICAgICAgICBmb3IgKFNjb3BlLkVudHJ5IGUgPSBsb29rdXAocy5uYW1lKTsgZS5zY29wZSAhPSBudWxsIDsgZSA9IGUubmV4dCgpKSB7CiAgICAgICAgICAgICAgICBpZiAoZS5zeW0gPT0gcykgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gaXNTdGF0aWNhbGx5SW1wb3J0ZWQoU3ltYm9sIHMpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKICAgICAgICAgICAgU3RyaW5nQnVpbGRlciByZXN1bHQgPSBuZXcgU3RyaW5nQnVpbGRlcigpOwogICAgICAgICAgICByZXN1bHQuYXBwZW5kKCJTY29wZVsiKTsKICAgICAgICAgICAgZm9yIChTY29wZUltcGwgcyA9IHRoaXM7IHMgIT0gbnVsbCA7IHMgPSBzLm5leHQpIHsKICAgICAgICAgICAgICAgIGlmIChzICE9IHRoaXMpIHJlc3VsdC5hcHBlbmQoIiB8ICIpOwogICAgICAgICAgICAgICAgZm9yIChFbnRyeSBlID0gcy5lbGVtczsgZSAhPSBudWxsOyBlID0gZS5zaWJsaW5nKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGUgIT0gcy5lbGVtcykgcmVzdWx0LmFwcGVuZCgiLCAiKTsKICAgICAgICAgICAgICAgICAgICByZXN1bHQuYXBwZW5kKGUuc3ltKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXN1bHQuYXBwZW5kKCJdIik7CiAgICAgICAgICAgIHJldHVybiByZXN1bHQudG9TdHJpbmcoKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqIEEgY2xhc3MgZm9yIHNjb3BlIGVudHJpZXMuCiAgICAgKi8KICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIEVudHJ5IHsKCiAgICAgICAgLyoqIFRoZSByZWZlcmVuY2VkIHN5bWJvbC4KICAgICAgICAgKiAgc3ltID09IG51bGwgICBpZmYgICB0aGlzID09IHNlbnRpbmVsCiAgICAgICAgICovCiAgICAgICAgcHVibGljIFN5bWJvbCBzeW07CgogICAgICAgIC8qKiBBbiBlbnRyeSB3aXRoIHRoZSBzYW1lIGhhc2ggY29kZSwgb3Igc2VudGluZWwuCiAgICAgICAgICovCiAgICAgICAgcHJpdmF0ZSBFbnRyeSBzaGFkb3dlZDsKCiAgICAgICAgLyoqIE5leHQgZW50cnkgaW4gc2FtZSBzY29wZS4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgRW50cnkgc2libGluZzsKCiAgICAgICAgLyoqIFRoZSBlbnRyeSdzIHNjb3BlLgogICAgICAgICAqICBzY29wZSA9PSBudWxsICAgaWZmICAgdGhpcyA9PSBzZW50aW5lbAogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBTY29wZUltcGwgc2NvcGU7CgogICAgICAgIHB1YmxpYyBFbnRyeShTeW1ib2wgc3ltLCBFbnRyeSBzaGFkb3dlZCwgRW50cnkgc2libGluZywgU2NvcGVJbXBsIHNjb3BlKSB7CiAgICAgICAgICAgIHRoaXMuc3ltID0gc3ltOwogICAgICAgICAgICB0aGlzLnNoYWRvd2VkID0gc2hhZG93ZWQ7CiAgICAgICAgICAgIHRoaXMuc2libGluZyA9IHNpYmxpbmc7CiAgICAgICAgICAgIHRoaXMuc2NvcGUgPSBzY29wZTsKICAgICAgICB9CgogICAgICAgIC8qKiBSZXR1cm4gbmV4dCBlbnRyeSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgdGhpcyBlbnRyeSwgcHJvY2VlZGluZwogICAgICAgICAqICBvdXR3YXJkcyBpZiBub3QgZm91bmQgaW4gdGhpcyBzY29wZS4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgRW50cnkgbmV4dCgpIHsKICAgICAgICAgICAgcmV0dXJuIHNoYWRvd2VkOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIEVudHJ5IG5leHQoRmlsdGVyPFN5bWJvbD4gc2YpIHsKICAgICAgICAgICAgaWYgKHNoYWRvd2VkLnN5bSA9PSBudWxsIHx8IHNmID09IG51bGwgfHwgc2YuYWNjZXB0cyhzaGFkb3dlZC5zeW0pKSByZXR1cm4gc2hhZG93ZWQ7CiAgICAgICAgICAgIGVsc2UgcmV0dXJuIHNoYWRvd2VkLm5leHQoc2YpOwogICAgICAgIH0KCiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjbGFzcyBJbXBvcnRTY29wZSBleHRlbmRzIENvbXBvdW5kU2NvcGUgewoKICAgICAgICBwdWJsaWMgSW1wb3J0U2NvcGUoU3ltYm9sIG93bmVyKSB7CiAgICAgICAgICAgIHN1cGVyKG93bmVyKTsKICAgICAgICB9CgogICAgICAgIC8qKkZpbmFsaXplIHRoZSBjb250ZW50IG9mIHRoZSBJbXBvcnRTY29wZSB0byBzcGVlZC11cCBmdXR1cmUgbG9va3Vwcy4KICAgICAgICAgKiBObyBmdXJ0aGVyIGNoYW5nZXMgdG8gY2xhc3MgaGllcmFyY2h5IG9yIGNsYXNzIGNvbnRlbnQgd2lsbCBiZSByZWZsZWN0ZWQuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIHZvaWQgZmluYWxpemVTY29wZSgpIHsKICAgICAgICAgICAgZm9yIChMaXN0PFNjb3BlPiBzY29wZXMgPSB0aGlzLnN1YlNjb3Blczsgc2NvcGVzLm5vbkVtcHR5KCk7IHNjb3BlcyA9IHNjb3Blcy50YWlsKSB7CiAgICAgICAgICAgICAgICBTY29wZSBpbXBTY29wZSA9IHNjb3Blcy5oZWFkOwoKICAgICAgICAgICAgICAgIGlmIChpbXBTY29wZSBpbnN0YW5jZW9mIEZpbHRlckltcG9ydFNjb3BlICYmIGltcFNjb3BlLm93bmVyLmtpbmQgPT0gS2luZC5UWVApIHsKICAgICAgICAgICAgICAgICAgICBXcml0ZWFibGVTY29wZSBmaW5hbGl6ZWQgPSBXcml0ZWFibGVTY29wZS5jcmVhdGUoaW1wU2NvcGUub3duZXIpOwoKICAgICAgICAgICAgICAgICAgICBmb3IgKFN5bWJvbCBzeW0gOiBpbXBTY29wZS5nZXRTeW1ib2xzKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxpemVkLmVudGVyKHN5bSk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBmaW5hbGl6ZWQubGlzdGVuZXJzLmFkZChuZXcgU2NvcGVMaXN0ZW5lcigpIHsKICAgICAgICAgICAgICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgICAgICAgICAgICAgIHB1YmxpYyB2b2lkIHN5bWJvbEFkZGVkKFN5bWJvbCBzeW0sIFNjb3BlIHMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFzc2VydC5lcnJvcigiVGhlIHNjb3BlIGlzIHNlYWxlZC4iKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgICAgICAgICAgICAgIHB1YmxpYyB2b2lkIHN5bWJvbFJlbW92ZWQoU3ltYm9sIHN5bSwgU2NvcGUgcykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgQXNzZXJ0LmVycm9yKCJUaGUgc2NvcGUgaXMgc2VhbGVkLiIpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAgICAgICAgIHNjb3Blcy5oZWFkID0gZmluYWxpemVkOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIE5hbWVkSW1wb3J0U2NvcGUgZXh0ZW5kcyBJbXBvcnRTY29wZSB7CgogICAgICAgIHB1YmxpYyBOYW1lZEltcG9ydFNjb3BlKFN5bWJvbCBvd25lciwgU2NvcGUgY3VycmVudEZpbGVTY29wZSkgewogICAgICAgICAgICBzdXBlcihvd25lcik7CiAgICAgICAgICAgIHByZXBlbmRTdWJTY29wZShjdXJyZW50RmlsZVNjb3BlKTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBTY29wZSBpbXBvcnRCeU5hbWUoVHlwZXMgdHlwZXMsIFNjb3BlIG9yaWdpbiwgTmFtZSBuYW1lLCBJbXBvcnRGaWx0ZXIgZmlsdGVyLCBKQ0ltcG9ydCBpbXAsIEJpQ29uc3VtZXI8SkNJbXBvcnQsIENvbXBsZXRpb25GYWlsdXJlPiBjZkhhbmRsZXIpIHsKICAgICAgICAgICAgcmV0dXJuIGFwcGVuZFNjb3BlKG5ldyBGaWx0ZXJJbXBvcnRTY29wZSh0eXBlcywgb3JpZ2luLCBuYW1lLCBmaWx0ZXIsIGltcCwgY2ZIYW5kbGVyKSk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgU2NvcGUgaW1wb3J0VHlwZShTY29wZSBkZWxlZ2F0ZSwgU2NvcGUgb3JpZ2luLCBTeW1ib2wgc3ltKSB7CiAgICAgICAgICAgIHJldHVybiBhcHBlbmRTY29wZShuZXcgU2luZ2xlRW50cnlTY29wZShkZWxlZ2F0ZS5vd25lciwgc3ltLCBvcmlnaW4pKTsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgU2NvcGUgYXBwZW5kU2NvcGUoU2NvcGUgbmV3U2NvcGUpIHsKICAgICAgICAgICAgTGlzdDxTY29wZT4gZXhpc3RpbmdTY29wZXMgPSB0aGlzLnN1YlNjb3Blcy5yZXZlcnNlKCk7CiAgICAgICAgICAgIHN1YlNjb3BlcyA9IExpc3Qub2YoZXhpc3RpbmdTY29wZXMuaGVhZCk7CiAgICAgICAgICAgIHN1YlNjb3BlcyA9IHN1YlNjb3Blcy5wcmVwZW5kKG5ld1Njb3BlKTsKICAgICAgICAgICAgZm9yIChTY29wZSBzIDogZXhpc3RpbmdTY29wZXMudGFpbCkgewogICAgICAgICAgICAgICAgc3ViU2NvcGVzID0gc3ViU2NvcGVzLnByZXBlbmQocyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG5ld1Njb3BlOwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgU2luZ2xlRW50cnlTY29wZSBleHRlbmRzIFNjb3BlIHsKCiAgICAgICAgICAgIHByaXZhdGUgZmluYWwgU3ltYm9sIHN5bTsKICAgICAgICAgICAgcHJpdmF0ZSBmaW5hbCBMaXN0PFN5bWJvbD4gY29udGVudDsKICAgICAgICAgICAgcHJpdmF0ZSBmaW5hbCBTY29wZSBvcmlnaW47CgogICAgICAgICAgICBwdWJsaWMgU2luZ2xlRW50cnlTY29wZShTeW1ib2wgb3duZXIsIFN5bWJvbCBzeW0sIFNjb3BlIG9yaWdpbikgewogICAgICAgICAgICAgICAgc3VwZXIob3duZXIpOwogICAgICAgICAgICAgICAgdGhpcy5zeW0gPSBzeW07CiAgICAgICAgICAgICAgICB0aGlzLmNvbnRlbnQgPSBMaXN0Lm9mKHN5bSk7CiAgICAgICAgICAgICAgICB0aGlzLm9yaWdpbiA9IG9yaWdpbjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHB1YmxpYyBJdGVyYWJsZTxTeW1ib2w+IGdldFN5bWJvbHMoRmlsdGVyPFN5bWJvbD4gc2YsIExvb2t1cEtpbmQgbG9va3VwS2luZCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHNmID09IG51bGwgfHwgc2YuYWNjZXB0cyhzeW0pID8gY29udGVudCA6IENvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHVibGljIEl0ZXJhYmxlPFN5bWJvbD4gZ2V0U3ltYm9sc0J5TmFtZShOYW1lIG5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmlsdGVyPFN5bWJvbD4gc2YsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTG9va3VwS2luZCBsb29rdXBLaW5kKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gc3ltLm5hbWUgPT0gbmFtZSAmJgogICAgICAgICAgICAgICAgICAgICAgIChzZiA9PSBudWxsIHx8IHNmLmFjY2VwdHMoc3ltKSkgPyBjb250ZW50IDogQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgU2NvcGUgZ2V0T3JpZ2luKFN5bWJvbCBieU5hbWUpIHsKICAgICAgICAgICAgICAgIHJldHVybiBzeW0gPT0gYnlOYW1lID8gb3JpZ2luIDogbnVsbDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHB1YmxpYyBib29sZWFuIGlzU3RhdGljYWxseUltcG9ydGVkKFN5bWJvbCBieU5hbWUpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQoKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjbGFzcyBTdGFySW1wb3J0U2NvcGUgZXh0ZW5kcyBJbXBvcnRTY29wZSB7CgogICAgICAgIHB1YmxpYyBTdGFySW1wb3J0U2NvcGUoU3ltYm9sIG93bmVyKSB7CiAgICAgICAgICAgIHN1cGVyKG93bmVyKTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyB2b2lkIGltcG9ydEFsbChUeXBlcyB0eXBlcywgU2NvcGUgb3JpZ2luLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbXBvcnRGaWx0ZXIgZmlsdGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBKQ0ltcG9ydCBpbXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJpQ29uc3VtZXI8SkNJbXBvcnQsIENvbXBsZXRpb25GYWlsdXJlPiBjZkhhbmRsZXIpIHsKICAgICAgICAgICAgZm9yIChTY29wZSBleGlzdGluZyA6IHN1YlNjb3BlcykgewogICAgICAgICAgICAgICAgQXNzZXJ0LmNoZWNrKGV4aXN0aW5nIGluc3RhbmNlb2YgRmlsdGVySW1wb3J0U2NvcGUpOwogICAgICAgICAgICAgICAgRmlsdGVySW1wb3J0U2NvcGUgZmlzID0gKEZpbHRlckltcG9ydFNjb3BlKSBleGlzdGluZzsKICAgICAgICAgICAgICAgIGlmIChmaXMub3JpZ2luID09IG9yaWdpbiAmJiBmaXMuZmlsdGVyID09IGZpbHRlciAmJgogICAgICAgICAgICAgICAgICAgIGZpcy5pbXAuc3RhdGljSW1wb3J0ID09IGltcC5zdGF0aWNJbXBvcnQpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDsgLy9hdm9pZCBlbnRlcmluZyB0aGUgc2FtZSBzY29wZSB0d2ljZQogICAgICAgICAgICB9CiAgICAgICAgICAgIHByZXBlbmRTdWJTY29wZShuZXcgRmlsdGVySW1wb3J0U2NvcGUodHlwZXMsIG9yaWdpbiwgbnVsbCwgZmlsdGVyLCBpbXAsIGNmSGFuZGxlcikpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIGJvb2xlYW4gaXNGaWxsZWQoKSB7CiAgICAgICAgICAgIHJldHVybiBzdWJTY29wZXMubm9uRW1wdHkoKTsKICAgICAgICB9CgogICAgfQoKICAgIHB1YmxpYyBpbnRlcmZhY2UgSW1wb3J0RmlsdGVyIHsKICAgICAgICBwdWJsaWMgYm9vbGVhbiBhY2NlcHRzKFNjb3BlIG9yaWdpbiwgU3ltYm9sIHN5bSk7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgRmlsdGVySW1wb3J0U2NvcGUgZXh0ZW5kcyBTY29wZSB7CgogICAgICAgIHByaXZhdGUgZmluYWwgVHlwZXMgdHlwZXM7CiAgICAgICAgcHJpdmF0ZSBmaW5hbCBTY29wZSBvcmlnaW47CiAgICAgICAgcHJpdmF0ZSBmaW5hbCBOYW1lICBmaWx0ZXJOYW1lOwogICAgICAgIHByaXZhdGUgZmluYWwgSW1wb3J0RmlsdGVyIGZpbHRlcjsKICAgICAgICBwcml2YXRlIGZpbmFsIEpDSW1wb3J0IGltcDsKICAgICAgICBwcml2YXRlIGZpbmFsIEJpQ29uc3VtZXI8SkNJbXBvcnQsIENvbXBsZXRpb25GYWlsdXJlPiBjZkhhbmRsZXI7CgogICAgICAgIHB1YmxpYyBGaWx0ZXJJbXBvcnRTY29wZShUeXBlcyB0eXBlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU2NvcGUgb3JpZ2luLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOYW1lICBmaWx0ZXJOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbXBvcnRGaWx0ZXIgZmlsdGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBKQ0ltcG9ydCBpbXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJpQ29uc3VtZXI8SkNJbXBvcnQsIENvbXBsZXRpb25GYWlsdXJlPiBjZkhhbmRsZXIpIHsKICAgICAgICAgICAgc3VwZXIob3JpZ2luLm93bmVyKTsKICAgICAgICAgICAgdGhpcy50eXBlcyA9IHR5cGVzOwogICAgICAgICAgICB0aGlzLm9yaWdpbiA9IG9yaWdpbjsKICAgICAgICAgICAgdGhpcy5maWx0ZXJOYW1lID0gZmlsdGVyTmFtZTsKICAgICAgICAgICAgdGhpcy5maWx0ZXIgPSBmaWx0ZXI7CiAgICAgICAgICAgIHRoaXMuaW1wID0gaW1wOwogICAgICAgICAgICB0aGlzLmNmSGFuZGxlciA9IGNmSGFuZGxlcjsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBJdGVyYWJsZTxTeW1ib2w+IGdldFN5bWJvbHMoZmluYWwgRmlsdGVyPFN5bWJvbD4gc2YsIGZpbmFsIExvb2t1cEtpbmQgbG9va3VwS2luZCkgewogICAgICAgICAgICBpZiAoZmlsdGVyTmFtZSAhPSBudWxsKQogICAgICAgICAgICAgICAgcmV0dXJuIGdldFN5bWJvbHNCeU5hbWUoZmlsdGVyTmFtZSwgc2YsIGxvb2t1cEtpbmQpOwogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgU3ltYm9sSW1wb3J0ZXIgc2kgPSBuZXcgU3ltYm9sSW1wb3J0ZXIoaW1wLnN0YXRpY0ltcG9ydCkgewogICAgICAgICAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICAgICAgICAgIEl0ZXJhYmxlPFN5bWJvbD4gZG9Mb29rdXAoVHlwZVN5bWJvbCB0c3ltKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0c3ltLm1lbWJlcnMoKS5nZXRTeW1ib2xzKHNmLCBsb29rdXBLaW5kKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgcmV0dXJuIHNpLmltcG9ydEZyb20oKFR5cGVTeW1ib2wpIG9yaWdpbi5vd25lcikgOjogaXRlcmF0b3I7CiAgICAgICAgICAgIH0gY2F0Y2ggKENvbXBsZXRpb25GYWlsdXJlIGNmKSB7CiAgICAgICAgICAgICAgICBjZkhhbmRsZXIuYWNjZXB0KGltcCwgY2YpOwogICAgICAgICAgICAgICAgcmV0dXJuIENvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgSXRlcmFibGU8U3ltYm9sPiBnZXRTeW1ib2xzQnlOYW1lKGZpbmFsIE5hbWUgbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIEZpbHRlcjxTeW1ib2w+IHNmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgTG9va3VwS2luZCBsb29rdXBLaW5kKSB7CiAgICAgICAgICAgIGlmIChmaWx0ZXJOYW1lICE9IG51bGwgJiYgZmlsdGVyTmFtZSAhPSBuYW1lKQogICAgICAgICAgICAgICAgcmV0dXJuIENvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgU3ltYm9sSW1wb3J0ZXIgc2kgPSBuZXcgU3ltYm9sSW1wb3J0ZXIoaW1wLnN0YXRpY0ltcG9ydCkgewogICAgICAgICAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICAgICAgICAgIEl0ZXJhYmxlPFN5bWJvbD4gZG9Mb29rdXAoVHlwZVN5bWJvbCB0c3ltKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0c3ltLm1lbWJlcnMoKS5nZXRTeW1ib2xzQnlOYW1lKG5hbWUsIHNmLCBsb29rdXBLaW5kKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgcmV0dXJuIHNpLmltcG9ydEZyb20oKFR5cGVTeW1ib2wpIG9yaWdpbi5vd25lcikgOjogaXRlcmF0b3I7CiAgICAgICAgICAgIH0gY2F0Y2ggKENvbXBsZXRpb25GYWlsdXJlIGNmKSB7CiAgICAgICAgICAgICAgICBjZkhhbmRsZXIuYWNjZXB0KGltcCwgY2YpOwogICAgICAgICAgICAgICAgcmV0dXJuIENvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgU2NvcGUgZ2V0T3JpZ2luKFN5bWJvbCBieU5hbWUpIHsKICAgICAgICAgICAgcmV0dXJuIG9yaWdpbjsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBib29sZWFuIGlzU3RhdGljYWxseUltcG9ydGVkKFN5bWJvbCBieU5hbWUpIHsKICAgICAgICAgICAgcmV0dXJuIGltcC5zdGF0aWNJbXBvcnQ7CiAgICAgICAgfQoKICAgICAgICBhYnN0cmFjdCBjbGFzcyBTeW1ib2xJbXBvcnRlciB7CiAgICAgICAgICAgIFNldDxTeW1ib2w+IHByb2Nlc3NlZCA9IG5ldyBIYXNoU2V0PD4oKTsKICAgICAgICAgICAgTGlzdDxJdGVyYWJsZTxTeW1ib2w+PiBkZWxlZ2F0ZXMgPSBMaXN0Lm5pbCgpOwogICAgICAgICAgICBmaW5hbCBib29sZWFuIGluc3BlY3RTdXBlclR5cGVzOwogICAgICAgICAgICBwdWJsaWMgU3ltYm9sSW1wb3J0ZXIoYm9vbGVhbiBpbnNwZWN0U3VwZXJUeXBlcykgewogICAgICAgICAgICAgICAgdGhpcy5pbnNwZWN0U3VwZXJUeXBlcyA9IGluc3BlY3RTdXBlclR5cGVzOwogICAgICAgICAgICB9CiAgICAgICAgICAgIFN0cmVhbTxTeW1ib2w+IGltcG9ydEZyb20oVHlwZVN5bWJvbCB0c3ltKSB7CiAgICAgICAgICAgICAgICBpZiAodHN5bSA9PSBudWxsIHx8ICFwcm9jZXNzZWQuYWRkKHRzeW0pKQogICAgICAgICAgICAgICAgICAgIHJldHVybiBTdHJlYW0uZW1wdHkoKTsKCiAgICAgICAgICAgICAgICBTdHJlYW08U3ltYm9sPiByZXN1bHQgPSBTdHJlYW0uZW1wdHkoKTsKCiAgICAgICAgICAgICAgICBpZiAoaW5zcGVjdFN1cGVyVHlwZXMpIHsKICAgICAgICAgICAgICAgICAgICAvLyBhbHNvIGltcG9ydCBpbmhlcml0ZWQgbmFtZXMKICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBpbXBvcnRGcm9tKHR5cGVzLnN1cGVydHlwZSh0c3ltLnR5cGUpLnRzeW0pOwogICAgICAgICAgICAgICAgICAgIGZvciAoVHlwZSB0IDogdHlwZXMuaW50ZXJmYWNlcyh0c3ltLnR5cGUpKQogICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBTdHJlYW0uY29uY2F0KGltcG9ydEZyb20odC50c3ltKSwgcmVzdWx0KTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICByZXR1cm4gU3RyZWFtLmNvbmNhdChTdHJlYW1TdXBwb3J0LnN0cmVhbShkb0xvb2t1cCh0c3ltKS5zcGxpdGVyYXRvcigpLCBmYWxzZSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZmlsdGVyKHMgLT4gZmlsdGVyLmFjY2VwdHMob3JpZ2luLCBzKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGFic3RyYWN0IEl0ZXJhYmxlPFN5bWJvbD4gZG9Mb29rdXAoVHlwZVN5bWJvbCB0c3ltKTsKICAgICAgICB9CgogICAgfQoKICAgIC8qKiBBIGNsYXNzIHNjb3BlIGFkZHMgY2FwYWJpbGl0aWVzIHRvIGtlZXAgdHJhY2sgb2YgY2hhbmdlcyBpbiByZWxhdGVkCiAgICAgKiAgY2xhc3Mgc2NvcGVzIC0gdGhpcyBhbGxvd3MgY2xpZW50IHRvIHJlYWxpemUgd2hldGhlciBhIGNsYXNzIHNjb3BlCiAgICAgKiAgaGFzIGNoYW5nZWQsIGVpdGhlciBkaXJlY3RseSAoYmVjYXVzZSBhIG5ldyBtZW1iZXIgaGFzIGJlZW4gYWRkZWQvcmVtb3ZlZAogICAgICogIHRvIHRoaXMgc2NvcGUpIG9yIGluZGlyZWN0bHkgKGkuZS4gYmVjYXVzZSBhIG5ldyBtZW1iZXIgaGFzIGJlZW4KICAgICAqICBhZGRlZC9yZW1vdmVkIGludG8gYSBzdXBlcnR5cGUgc2NvcGUpCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgQ29tcG91bmRTY29wZSBleHRlbmRzIFNjb3BlIGltcGxlbWVudHMgU2NvcGVMaXN0ZW5lciB7CgogICAgICAgIExpc3Q8U2NvcGU+IHN1YlNjb3BlcyA9IExpc3QubmlsKCk7CiAgICAgICAgcHJpdmF0ZSBpbnQgbWFyayA9IDA7CgogICAgICAgIHB1YmxpYyBDb21wb3VuZFNjb3BlKFN5bWJvbCBvd25lcikgewogICAgICAgICAgICBzdXBlcihvd25lcik7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgdm9pZCBwcmVwZW5kU3ViU2NvcGUoU2NvcGUgdGhhdCkgewogICAgICAgICAgIGlmICh0aGF0ICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIHN1YlNjb3BlcyA9IHN1YlNjb3Blcy5wcmVwZW5kKHRoYXQpOwogICAgICAgICAgICAgICAgdGhhdC5saXN0ZW5lcnMuYWRkKHRoaXMpOwogICAgICAgICAgICAgICAgbWFyaysrOwogICAgICAgICAgICAgICAgbGlzdGVuZXJzLnN5bWJvbEFkZGVkKG51bGwsIHRoaXMpOwogICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHB1YmxpYyB2b2lkIHN5bWJvbEFkZGVkKFN5bWJvbCBzeW0sIFNjb3BlIHMpIHsKICAgICAgICAgICAgbWFyaysrOwogICAgICAgICAgICBsaXN0ZW5lcnMuc3ltYm9sQWRkZWQoc3ltLCBzKTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyB2b2lkIHN5bWJvbFJlbW92ZWQoU3ltYm9sIHN5bSwgU2NvcGUgcykgewogICAgICAgICAgICBtYXJrKys7CiAgICAgICAgICAgIGxpc3RlbmVycy5zeW1ib2xSZW1vdmVkKHN5bSwgcyk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgaW50IGdldE1hcmsoKSB7CiAgICAgICAgICAgIHJldHVybiBtYXJrOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKICAgICAgICAgICAgU3RyaW5nQnVpbGRlciBidWYgPSBuZXcgU3RyaW5nQnVpbGRlcigpOwogICAgICAgICAgICBidWYuYXBwZW5kKCJDb21wb3VuZFNjb3BleyIpOwogICAgICAgICAgICBTdHJpbmcgc2VwID0gIiI7CiAgICAgICAgICAgIGZvciAoU2NvcGUgcyA6IHN1YlNjb3BlcykgewogICAgICAgICAgICAgICAgYnVmLmFwcGVuZChzZXApOwogICAgICAgICAgICAgICAgYnVmLmFwcGVuZChzKTsKICAgICAgICAgICAgICAgIHNlcCA9ICIsIjsKICAgICAgICAgICAgfQogICAgICAgICAgICBidWYuYXBwZW5kKCJ9Iik7CiAgICAgICAgICAgIHJldHVybiBidWYudG9TdHJpbmcoKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBJdGVyYWJsZTxTeW1ib2w+IGdldFN5bWJvbHMoZmluYWwgRmlsdGVyPFN5bWJvbD4gc2YsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBMb29rdXBLaW5kIGxvb2t1cEtpbmQpIHsKICAgICAgICAgICAgcmV0dXJuICgpIC0+IEl0ZXJhdG9ycy5jcmVhdGVDb21wb3VuZEl0ZXJhdG9yKHN1YlNjb3BlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjb3BlIC0+IHNjb3BlLmdldFN5bWJvbHMoc2YsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvb2t1cEtpbmQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5pdGVyYXRvcigpKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBJdGVyYWJsZTxTeW1ib2w+IGdldFN5bWJvbHNCeU5hbWUoZmluYWwgTmFtZSBuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgRmlsdGVyPFN5bWJvbD4gc2YsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBMb29rdXBLaW5kIGxvb2t1cEtpbmQpIHsKICAgICAgICAgICAgcmV0dXJuICgpIC0+IEl0ZXJhdG9ycy5jcmVhdGVDb21wb3VuZEl0ZXJhdG9yKHN1YlNjb3BlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjb3BlIC0+IHNjb3BlLmdldFN5bWJvbHNCeU5hbWUobmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2YsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvb2t1cEtpbmQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5pdGVyYXRvcigpKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBTY29wZSBnZXRPcmlnaW4oU3ltYm9sIHN5bSkgewogICAgICAgICAgICBmb3IgKFNjb3BlIGRlbGVnYXRlIDogc3ViU2NvcGVzKSB7CiAgICAgICAgICAgICAgICBpZiAoZGVsZWdhdGUuaW5jbHVkZXMoc3ltKSkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGVsZWdhdGUuZ2V0T3JpZ2luKHN5bSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gaXNTdGF0aWNhbGx5SW1wb3J0ZWQoU3ltYm9sIHN5bSkgewogICAgICAgICAgICBmb3IgKFNjb3BlIGRlbGVnYXRlIDogc3ViU2NvcGVzKSB7CiAgICAgICAgICAgICAgICBpZiAoZGVsZWdhdGUuaW5jbHVkZXMoc3ltKSkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGVsZWdhdGUuaXNTdGF0aWNhbGx5SW1wb3J0ZWQoc3ltKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICB9CgogICAgLyoqIEFuIGVycm9yIHNjb3BlLCBmb3Igd2hpY2ggdGhlIG93bmVyIHNob3VsZCBiZSBhbiBlcnJvciBzeW1ib2wuICovCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIEVycm9yU2NvcGUgZXh0ZW5kcyBTY29wZUltcGwgewogICAgICAgIEVycm9yU2NvcGUoU2NvcGVJbXBsIG5leHQsIFN5bWJvbCBlcnJTeW1ib2wsIEVudHJ5W10gdGFibGUpIHsKICAgICAgICAgICAgc3VwZXIobmV4dCwgLypvd25lcj0qL2VyclN5bWJvbCwgdGFibGUpOwogICAgICAgIH0KICAgICAgICBwdWJsaWMgRXJyb3JTY29wZShTeW1ib2wgZXJyU3ltYm9sKSB7CiAgICAgICAgICAgIHN1cGVyKGVyclN5bWJvbCk7CiAgICAgICAgfQogICAgICAgIHB1YmxpYyBXcml0ZWFibGVTY29wZSBkdXAoU3ltYm9sIG5ld093bmVyKSB7CiAgICAgICAgICAgIHJldHVybiBuZXcgRXJyb3JTY29wZSh0aGlzLCBuZXdPd25lciwgdGFibGUpOwogICAgICAgIH0KICAgICAgICBwdWJsaWMgV3JpdGVhYmxlU2NvcGUgZHVwVW5zaGFyZWQoU3ltYm9sIG5ld093bmVyKSB7CiAgICAgICAgICAgIHJldHVybiBuZXcgRXJyb3JTY29wZSh0aGlzLCBuZXdPd25lciwgdGFibGUuY2xvbmUoKSk7CiAgICAgICAgfQogICAgICAgIHB1YmxpYyBFbnRyeSBsb29rdXAoTmFtZSBuYW1lKSB7CiAgICAgICAgICAgIEVudHJ5IGUgPSBzdXBlci5sb29rdXAobmFtZSk7CiAgICAgICAgICAgIGlmIChlLnNjb3BlID09IG51bGwpCiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEVudHJ5KG93bmVyLCBudWxsLCBudWxsLCBudWxsKTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgcmV0dXJuIGU7CiAgICAgICAgfQogICAgfQp9ClBLAwQKAAAIAADSfU1KCpPFmNYXAADWFwAAKAAAAGNvbS9zdW4vdG9vbHMvamF2YWMvY29kZS9UYXJnZXRUeXBlLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDgsIDIwMTMsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhYy5jb2RlOwoKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5Bc3NlcnQ7CgovKioKICogRGVzY3JpYmVzIHRoZSB0eXBlIG9mIHByb2dyYW0gZWxlbWVudCBhbiBleHRlbmRlZCBhbm5vdGF0aW9uIChvciBleHRlbmRlZAogKiBjb21wb3VuZCBhdHRyaWJ1dGUpIHRhcmdldHMuCiAqCiAqIEJ5IGNvbXBhcmlzb24sIGEgVHJlZS5LaW5kIGhhcyBlbnVtIHZhbHVlcyBmb3IgYWxsIGVsZW1lbnRzIGluIHRoZSBBU1QsIGFuZAogKiBpdCBkb2VzIG5vdCBwcm92aWRlIGVub3VnaCByZXNvbHV0aW9uIGZvciB0eXBlIGFyZ3VtZW50cyAoaS5lLiwgd2hldGhlciBhbgogKiBhbm5vdGF0aW9uIHRhcmdldHMgYSB0eXBlIGFyZ3VtZW50IGluIGEgbG9jYWwgdmFyaWFibGUsIG1ldGhvZCByZXR1cm4gdHlwZSwKICogb3IgYSB0eXBlY2FzdCkuCiAqCiAqICA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiAgSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93biByaXNrLgogKiAgVGhpcyBjb2RlIGFuZCBpdHMgaW50ZXJuYWwgaW50ZXJmYWNlcyBhcmUgc3ViamVjdCB0byBjaGFuZ2Ugb3IKICogIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj4KICovCi8vIENvZGUgZHVwbGljYXRlZCBpbiBjb20uc3VuLnRvb2xzLmNsYXNzZmlsZS5UeXBlQW5ub3RhdGlvbi5UYXJnZXRUeXBlCnB1YmxpYyBlbnVtIFRhcmdldFR5cGUgewogICAgLyoqIEZvciBhbm5vdGF0aW9ucyBvbiBhIGNsYXNzIHR5cGUgcGFyYW1ldGVyIGRlY2xhcmF0aW9uLiAqLwogICAgQ0xBU1NfVFlQRV9QQVJBTUVURVIoMHgwMCksCgogICAgLyoqIEZvciBhbm5vdGF0aW9ucyBvbiBhIG1ldGhvZCB0eXBlIHBhcmFtZXRlciBkZWNsYXJhdGlvbi4gKi8KICAgIE1FVEhPRF9UWVBFX1BBUkFNRVRFUigweDAxKSwKCiAgICAvKiogRm9yIGFubm90YXRpb25zIG9uIHRoZSB0eXBlIG9mIGFuICJleHRlbmRzIiBvciAiaW1wbGVtZW50cyIgY2xhdXNlLiAqLwogICAgQ0xBU1NfRVhURU5EUygweDEwKSwKCiAgICAvKiogRm9yIGFubm90YXRpb25zIG9uIGEgYm91bmQgb2YgYSB0eXBlIHBhcmFtZXRlciBvZiBhIGNsYXNzLiAqLwogICAgQ0xBU1NfVFlQRV9QQVJBTUVURVJfQk9VTkQoMHgxMSksCgogICAgLyoqIEZvciBhbm5vdGF0aW9ucyBvbiBhIGJvdW5kIG9mIGEgdHlwZSBwYXJhbWV0ZXIgb2YgYSBtZXRob2QuICovCiAgICBNRVRIT0RfVFlQRV9QQVJBTUVURVJfQk9VTkQoMHgxMiksCgogICAgLyoqIEZvciBhbm5vdGF0aW9ucyBvbiBhIGZpZWxkLiAqLwogICAgRklFTEQoMHgxMyksCgogICAgLyoqIEZvciBhbm5vdGF0aW9ucyBvbiBhIG1ldGhvZCByZXR1cm4gdHlwZS4gKi8KICAgIE1FVEhPRF9SRVRVUk4oMHgxNCksCgogICAgLyoqIEZvciBhbm5vdGF0aW9ucyBvbiB0aGUgbWV0aG9kIHJlY2VpdmVyLiAqLwogICAgTUVUSE9EX1JFQ0VJVkVSKDB4MTUpLAoKICAgIC8qKiBGb3IgYW5ub3RhdGlvbnMgb24gYSBtZXRob2QgcGFyYW1ldGVyLiAqLwogICAgTUVUSE9EX0ZPUk1BTF9QQVJBTUVURVIoMHgxNiksCgogICAgLyoqIEZvciBhbm5vdGF0aW9ucyBvbiBhIHRocm93cyBjbGF1c2UgaW4gYSBtZXRob2QgZGVjbGFyYXRpb24uICovCiAgICBUSFJPV1MoMHgxNyksCgogICAgLyoqIEZvciBhbm5vdGF0aW9ucyBvbiBhIGxvY2FsIHZhcmlhYmxlLiAqLwogICAgTE9DQUxfVkFSSUFCTEUoMHg0MCwgdHJ1ZSksCgogICAgLyoqIEZvciBhbm5vdGF0aW9ucyBvbiBhIHJlc291cmNlIHZhcmlhYmxlLiAqLwogICAgUkVTT1VSQ0VfVkFSSUFCTEUoMHg0MSwgdHJ1ZSksCgogICAgLyoqIEZvciBhbm5vdGF0aW9ucyBvbiBhbiBleGNlcHRpb24gcGFyYW1ldGVyLiAqLwogICAgRVhDRVBUSU9OX1BBUkFNRVRFUigweDQyLCB0cnVlKSwKCiAgICAvKiogRm9yIGFubm90YXRpb25zIG9uIGEgdHlwZSB0ZXN0LiAqLwogICAgSU5TVEFOQ0VPRigweDQzLCB0cnVlKSwKCiAgICAvKiogRm9yIGFubm90YXRpb25zIG9uIGFuIG9iamVjdCBjcmVhdGlvbiBleHByZXNzaW9uLiAqLwogICAgTkVXKDB4NDQsIHRydWUpLAoKICAgIC8qKiBGb3IgYW5ub3RhdGlvbnMgb24gYSBjb25zdHJ1Y3RvciByZWZlcmVuY2UgcmVjZWl2ZXIuICovCiAgICBDT05TVFJVQ1RPUl9SRUZFUkVOQ0UoMHg0NSwgdHJ1ZSksCgogICAgLyoqIEZvciBhbm5vdGF0aW9ucyBvbiBhIG1ldGhvZCByZWZlcmVuY2UgcmVjZWl2ZXIuICovCiAgICBNRVRIT0RfUkVGRVJFTkNFKDB4NDYsIHRydWUpLAoKICAgIC8qKiBGb3IgYW5ub3RhdGlvbnMgb24gYSB0eXBlY2FzdC4gKi8KICAgIENBU1QoMHg0NywgdHJ1ZSksCgogICAgLyoqIEZvciBhbm5vdGF0aW9ucyBvbiBhIHR5cGUgYXJndW1lbnQgb2YgYW4gb2JqZWN0IGNyZWF0aW9uIGV4cHJlc3Npb24uICovCiAgICBDT05TVFJVQ1RPUl9JTlZPQ0FUSU9OX1RZUEVfQVJHVU1FTlQoMHg0OCwgdHJ1ZSksCgogICAgLyoqIEZvciBhbm5vdGF0aW9ucyBvbiBhIHR5cGUgYXJndW1lbnQgb2YgYSBtZXRob2QgY2FsbC4gKi8KICAgIE1FVEhPRF9JTlZPQ0FUSU9OX1RZUEVfQVJHVU1FTlQoMHg0OSwgdHJ1ZSksCgogICAgLyoqIEZvciBhbm5vdGF0aW9ucyBvbiBhIHR5cGUgYXJndW1lbnQgb2YgYSBjb25zdHJ1Y3RvciByZWZlcmVuY2UuICovCiAgICBDT05TVFJVQ1RPUl9SRUZFUkVOQ0VfVFlQRV9BUkdVTUVOVCgweDRBLCB0cnVlKSwKCiAgICAvKiogRm9yIGFubm90YXRpb25zIG9uIGEgdHlwZSBhcmd1bWVudCBvZiBhIG1ldGhvZCByZWZlcmVuY2UuICovCiAgICBNRVRIT0RfUkVGRVJFTkNFX1RZUEVfQVJHVU1FTlQoMHg0QiwgdHJ1ZSksCgogICAgLyoqIEZvciBhbm5vdGF0aW9ucyB3aXRoIGFuIHVua25vd24gdGFyZ2V0LiAqLwogICAgVU5LTk9XTigweEZGKTsKCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTUFYSU1VTV9UQVJHRVRfVFlQRV9WQUxVRSA9IDB4NEI7CgogICAgcHJpdmF0ZSBmaW5hbCBpbnQgdGFyZ2V0VHlwZVZhbHVlOwogICAgcHJpdmF0ZSBmaW5hbCBib29sZWFuIGlzTG9jYWw7CgogICAgcHJpdmF0ZSBUYXJnZXRUeXBlKGludCB0YXJnZXRUeXBlVmFsdWUpIHsKICAgICAgICB0aGlzKHRhcmdldFR5cGVWYWx1ZSwgZmFsc2UpOwogICAgfQoKICAgIHByaXZhdGUgVGFyZ2V0VHlwZShpbnQgdGFyZ2V0VHlwZVZhbHVlLCBib29sZWFuIGlzTG9jYWwpIHsKICAgICAgICBpZiAodGFyZ2V0VHlwZVZhbHVlIDwgMAogICAgICAgICAgICAgICAgfHwgdGFyZ2V0VHlwZVZhbHVlID4gMjU1KQogICAgICAgICAgICAgICAgQXNzZXJ0LmVycm9yKCJBdHRyaWJ1dGUgdHlwZSB2YWx1ZSBuZWVkcyB0byBiZSBhbiB1bnNpZ25lZCBieXRlOiAiICsgU3RyaW5nLmZvcm1hdCgiMHglMDJYIiwgdGFyZ2V0VHlwZVZhbHVlKSk7CiAgICAgICAgdGhpcy50YXJnZXRUeXBlVmFsdWUgPSB0YXJnZXRUeXBlVmFsdWU7CiAgICAgICAgdGhpcy5pc0xvY2FsID0gaXNMb2NhbDsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgd2hldGhlciBvciBub3QgdGhpcyBUYXJnZXRUeXBlIHJlcHJlc2VudHMgYW4gYW5ub3RhdGlvbiB3aG9zZQogICAgICogdGFyZ2V0IGlzIGV4Y2x1c2l2ZWx5IGEgdHJlZSBpbiBhIG1ldGhvZCBib2R5CiAgICAgKgogICAgICogTm90ZTogd2lsZGNhcmQgYm91bmQgdGFyZ2V0cyBjb3VsZCB0YXJnZXQgYSBsb2NhbCB0cmVlIGFuZCBhIGNsYXNzCiAgICAgKiBtZW1iZXIgZGVjbGFyYXRpb24gc2lnbmF0dXJlIHRyZWUKICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gaXNMb2NhbCgpIHsKICAgICAgICByZXR1cm4gaXNMb2NhbDsKICAgIH0KCiAgICBwdWJsaWMgaW50IHRhcmdldFR5cGVWYWx1ZSgpIHsKICAgICAgICByZXR1cm4gdGhpcy50YXJnZXRUeXBlVmFsdWU7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVGFyZ2V0VHlwZVtdIHRhcmdldHM7CgogICAgc3RhdGljIHsKICAgICAgICB0YXJnZXRzID0gbmV3IFRhcmdldFR5cGVbTUFYSU1VTV9UQVJHRVRfVFlQRV9WQUxVRSArIDFdOwogICAgICAgIFRhcmdldFR5cGVbXSBhbGx0YXJnZXRzID0gdmFsdWVzKCk7CiAgICAgICAgZm9yIChUYXJnZXRUeXBlIHRhcmdldCA6IGFsbHRhcmdldHMpIHsKICAgICAgICAgICAgaWYgKHRhcmdldC50YXJnZXRUeXBlVmFsdWUgIT0gVU5LTk9XTi50YXJnZXRUeXBlVmFsdWUpCiAgICAgICAgICAgICAgICB0YXJnZXRzW3RhcmdldC50YXJnZXRUeXBlVmFsdWVdID0gdGFyZ2V0OwogICAgICAgIH0KICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8PSBNQVhJTVVNX1RBUkdFVF9UWVBFX1ZBTFVFOyArK2kpIHsKICAgICAgICAgICAgaWYgKHRhcmdldHNbaV0gPT0gbnVsbCkKICAgICAgICAgICAgICAgIHRhcmdldHNbaV0gPSBVTktOT1dOOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNWYWxpZFRhcmdldFR5cGVWYWx1ZShpbnQgdGFnKSB7CiAgICAgICAgaWYgKHRhZyA9PSBVTktOT1dOLnRhcmdldFR5cGVWYWx1ZSkKICAgICAgICAgICAgcmV0dXJuIHRydWU7CgogICAgICAgIHJldHVybiAodGFnID49IDAgJiYgdGFnIDwgdGFyZ2V0cy5sZW5ndGgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgVGFyZ2V0VHlwZSBmcm9tVGFyZ2V0VHlwZVZhbHVlKGludCB0YWcpIHsKICAgICAgICBpZiAodGFnID09IFVOS05PV04udGFyZ2V0VHlwZVZhbHVlKQogICAgICAgICAgICByZXR1cm4gVU5LTk9XTjsKCiAgICAgICAgaWYgKHRhZyA8IDAgfHwgdGFnID49IHRhcmdldHMubGVuZ3RoKQogICAgICAgICAgICBBc3NlcnQuZXJyb3IoIlVua25vd24gVGFyZ2V0VHlwZTogIiArIHRhZyk7CiAgICAgICAgcmV0dXJuIHRhcmdldHNbdGFnXTsKICAgIH0KfQpQSwMECgAACAAABjupShyXiJOaLQAAmi0AACMAAABjb20vc3VuL3Rvb2xzL2phdmFjL2NvZGUvS2luZHMuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMTk5OSwgMjAxNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGU7CgppbXBvcnQgamF2YS51dGlsLkVudW1TZXQ7CmltcG9ydCBqYXZhLnV0aWwuU2V0OwppbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKCmltcG9ydCBjb20uc3VuLnNvdXJjZS50cmVlLk1lbWJlclJlZmVyZW5jZVRyZWU7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmFwaS5Gb3JtYXR0YWJsZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuYXBpLk1lc3NhZ2VzOwoKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuRmxhZ3MuKjsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuVHlwZVRhZy5DTEFTUzsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuVHlwZVRhZy5QQUNLQUdFOwppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5UeXBlVGFnLlRZUEVWQVI7CgovKiogSW50ZXJuYWwgc3ltYm9sIGtpbmRzLCB3aGljaCBkaXN0aW5ndWlzaCBiZXR3ZWVuIGVsZW1lbnRzIG9mCiAqICBkaWZmZXJlbnQgc3ViY2xhc3NlcyBvZiBTeW1ib2wuIFN5bWJvbCBraW5kcyBhcmUgb3JnYW5pemVkIHNvIHRoZXkgY2FuIGJlCiAqICBvcidlZCB0byBzZXRzLgogKgogKiAgPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24gcmlzay4KICogIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yCiAqICBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+CiAqLwpwdWJsaWMgY2xhc3MgS2luZHMgewoKICAgIHByaXZhdGUgS2luZHMoKSB7fSAvLyB1bmluc3RhbnRpYWJsZQoKICAgIC8qKgogICAgICogS2luZCBvZiBzeW1ib2xzLgogICAgICoKICAgICAqIElNUE9SVEFOVDogVGhpcyBpcyBhbiBvcmRlcmVkIHR5cGUuICBUaGUgb3JkZXJpbmcgb2YKICAgICAqIGRlY2xhcmF0aW9ucyBpbiB0aGlzIGVudW0gbWF0dGVycy4gIEJlIGNhcmVmdWwgd2hlbiBjaGFuZ2luZwogICAgICogaXQuCiAgICAgKi8KICAgIHB1YmxpYyBlbnVtIEtpbmQgewogICAgICAgIE5JTChDYXRlZ29yeS5CQVNJQywgS2luZFNlbGVjdG9yLk5JTCksCiAgICAgICAgUENLKENhdGVnb3J5LkJBU0lDLCBLaW5kTmFtZS5QQUNLQUdFLCBLaW5kU2VsZWN0b3IuUENLKSwKICAgICAgICBUWVAoQ2F0ZWdvcnkuQkFTSUMsIEtpbmROYW1lLkNMQVNTLCBLaW5kU2VsZWN0b3IuVFlQKSwKICAgICAgICBWQVIoQ2F0ZWdvcnkuQkFTSUMsIEtpbmROYW1lLlZBUiwgS2luZFNlbGVjdG9yLlZBUiksCiAgICAgICAgTVRIKENhdGVnb3J5LkJBU0lDLCBLaW5kTmFtZS5NRVRIT0QsIEtpbmRTZWxlY3Rvci5NVEgpLAogICAgICAgIFBPTFkoQ2F0ZWdvcnkuQkFTSUMsIEtpbmRTZWxlY3Rvci5QT0xZKSwKICAgICAgICBNREwoQ2F0ZWdvcnkuQkFTSUMsIEtpbmRTZWxlY3Rvci5NREwpLAogICAgICAgIEVSUihDYXRlZ29yeS5FUlJPUiwgS2luZFNlbGVjdG9yLkVSUiksCiAgICAgICAgQU1CSUdVT1VTKENhdGVnb3J5LlJFU09MVVRJT05fVEFSR0VUKSwgICAgICAgICAgICAgICAgICAgICAgICAgLy8gb3ZlcmxvYWRlZCAgICAgICB0YXJnZXQKICAgICAgICBISURERU4oQ2F0ZWdvcnkuUkVTT0xVVElPTl9UQVJHRVQpLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBub3Qgb3ZlcmxvYWRlZCAgIG5vbi10YXJnZXQKICAgICAgICBTVEFUSUNFUlIoQ2F0ZWdvcnkuUkVTT0xVVElPTl9UQVJHRVQpLCAgICAgICAgICAgICAgICAgICAgICAgICAvLyBvdmVybG9hZGVkPyAgICAgIHRhcmdldAogICAgICAgIE1JU1NJTkdfRU5DTChDYXRlZ29yeS5SRVNPTFVUSU9OKSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG5vdCBvdmVybG9hZGVkICAgbm9uLXRhcmdldAogICAgICAgIEFCU0VOVF9WQVIoQ2F0ZWdvcnkuUkVTT0xVVElPTl9UQVJHRVQsIEtpbmROYW1lLlZBUiksICAgICAgICAgIC8vIG5vdCBvdmVybG9hZGVkICAgbm9uLXRhcmdldAogICAgICAgIFdST05HX01USFMoQ2F0ZWdvcnkuUkVTT0xVVElPTl9UQVJHRVQsIEtpbmROYW1lLk1FVEhPRCksICAgICAgIC8vIG92ZXJsb2FkZWQgICAgICAgdGFyZ2V0CiAgICAgICAgV1JPTkdfTVRIKENhdGVnb3J5LlJFU09MVVRJT05fVEFSR0VULCBLaW5kTmFtZS5NRVRIT0QpLCAgICAgICAgLy8gbm90IG92ZXJsb2FkZWQgICB0YXJnZXQKICAgICAgICBBQlNFTlRfTVRIKENhdGVnb3J5LlJFU09MVVRJT05fVEFSR0VULCBLaW5kTmFtZS5NRVRIT0QpLCAgICAgICAvLyBub3Qgb3ZlcmxvYWRlZCAgIG5vbi10YXJnZXQKICAgICAgICBBQlNFTlRfVFlQKENhdGVnb3J5LlJFU09MVVRJT05fVEFSR0VULCBLaW5kTmFtZS5DTEFTUyk7ICAgICAgICAvLyBub3Qgb3ZlcmxvYWRlZCAgIG5vbi10YXJnZXQKCiAgICAgICAgLy8gVGhlcmUgYXJlIGVzc2VudGlhbGx5IHR3byAibGV2ZWxzIiB0byB0aGUgS2luZCBkYXRhdHlwZS4KICAgICAgICAvLyBUaGUgZmlyc3QgaXMgYSB0b3RhbGx5LW9yZGVyZWQgc2V0IG9mIGNhdGVnb3JpZXMgb2YKICAgICAgICAvLyBzb2x1dGlvbnMuICBXaXRoaW4gZWFjaCBjYXRlZ29yeSwgd2UgaGF2ZSBtb3JlCiAgICAgICAgLy8gcG9zc2liaWxpdGllcy4KICAgICAgICBwcml2YXRlIGVudW0gQ2F0ZWdvcnkgewogICAgICAgICAgICBCQVNJQywgRVJST1IsIFJFU09MVVRJT04sIFJFU09MVVRJT05fVEFSR0VUOwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBmaW5hbCBLaW5kTmFtZSBraW5kTmFtZTsKICAgICAgICBwcml2YXRlIGZpbmFsIEtpbmROYW1lIGFic2VudEtpbmQ7CiAgICAgICAgcHJpdmF0ZSBmaW5hbCBLaW5kU2VsZWN0b3Igc2VsZWN0b3I7CiAgICAgICAgcHJpdmF0ZSBmaW5hbCBDYXRlZ29yeSBjYXRlZ29yeTsKCiAgICAgICAgcHJpdmF0ZSBLaW5kKENhdGVnb3J5IGNhdGVnb3J5KSB7CiAgICAgICAgICAgIHRoaXMoY2F0ZWdvcnksIG51bGwsIG51bGwsIG51bGwpOwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBLaW5kKENhdGVnb3J5IGNhdGVnb3J5LAogICAgICAgICAgICAgICAgICAgICBLaW5kU2VsZWN0b3Igc2VsZWN0b3IpIHsKICAgICAgICAgICAgdGhpcyhjYXRlZ29yeSwgbnVsbCwgbnVsbCwgc2VsZWN0b3IpOwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBLaW5kKENhdGVnb3J5IGNhdGVnb3J5LAogICAgICAgICAgICAgICAgICAgICBLaW5kTmFtZSBhYnNlbnRLaW5kKSB7CiAgICAgICAgICAgIHRoaXMoY2F0ZWdvcnksIG51bGwsIGFic2VudEtpbmQsIG51bGwpOwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBLaW5kKENhdGVnb3J5IGNhdGVnb3J5LAogICAgICAgICAgICAgICAgICAgICBLaW5kTmFtZSBraW5kTmFtZSwKICAgICAgICAgICAgICAgICAgICAgS2luZFNlbGVjdG9yIHNlbGVjdG9yKSB7CiAgICAgICAgICAgIHRoaXMoY2F0ZWdvcnksIGtpbmROYW1lLCBudWxsLCBzZWxlY3Rvcik7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIEtpbmQoQ2F0ZWdvcnkgY2F0ZWdvcnksCiAgICAgICAgICAgICAgICAgICAgIEtpbmROYW1lIGtpbmROYW1lLAogICAgICAgICAgICAgICAgICAgICBLaW5kTmFtZSBhYnNlbnRLaW5kLAogICAgICAgICAgICAgICAgICAgICBLaW5kU2VsZWN0b3Igc2VsZWN0b3IpIHsKICAgICAgICAgICAgdGhpcy5jYXRlZ29yeSA9IGNhdGVnb3J5OwogICAgICAgICAgICB0aGlzLmtpbmROYW1lID0ga2luZE5hbWU7CiAgICAgICAgICAgIHRoaXMuYWJzZW50S2luZCA9IGFic2VudEtpbmQ7CiAgICAgICAgICAgIHRoaXMuc2VsZWN0b3IgPSBzZWxlY3RvcjsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBLaW5kU2VsZWN0b3IgdG9TZWxlY3RvcigpIHsKICAgICAgICAgICAgcmV0dXJuIHNlbGVjdG9yOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIGJvb2xlYW4gbWF0Y2hlcyhLaW5kU2VsZWN0b3Iga2luZFNlbGVjdG9ycykgewogICAgICAgICAgICByZXR1cm4gc2VsZWN0b3IuY29udGFpbnMoa2luZFNlbGVjdG9ycyk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc1Jlc29sdXRpb25FcnJvcigpIHsKICAgICAgICAgICAgcmV0dXJuIGNhdGVnb3J5ID09IENhdGVnb3J5LlJFU09MVVRJT04gfHwgY2F0ZWdvcnkgPT0gQ2F0ZWdvcnkuUkVTT0xVVElPTl9UQVJHRVQ7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc1Jlc29sdXRpb25UYXJnZXRFcnJvcigpIHsKICAgICAgICAgICAgcmV0dXJuIGNhdGVnb3J5ID09IENhdGVnb3J5LlJFU09MVVRJT05fVEFSR0VUOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIGJvb2xlYW4gaXNWYWxpZCgpIHsKICAgICAgICAgICAgcmV0dXJuIGNhdGVnb3J5ID09IENhdGVnb3J5LkJBU0lDOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIGJvb2xlYW4gYmV0dGVyVGhhbihLaW5kIG90aGVyKSB7CiAgICAgICAgICAgIHJldHVybiBvcmRpbmFsKCkgPCBvdGhlci5vcmRpbmFsKCk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgS2luZE5hbWUga2luZE5hbWUoKSB7CiAgICAgICAgICAgIGlmIChraW5kTmFtZSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoIlVuZXhwZWN0ZWQga2luZDogIiArIHRoaXMpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcmV0dXJuIGtpbmROYW1lOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgS2luZE5hbWUgYWJzZW50S2luZCgpIHsKICAgICAgICAgICAgaWYgKGFic2VudEtpbmQgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCJVbmV4cGVjdGVkIGtpbmQ6ICIgKyB0aGlzKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHJldHVybiBhYnNlbnRLaW5kOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgS2luZFNlbGVjdG9yIHsKCiAgICAgICAgLy9iYXNpYyBzZWxlY3RvcnMKICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEtpbmRTZWxlY3RvciBOSUwgPSBuZXcgS2luZFNlbGVjdG9yKDApOwogICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgS2luZFNlbGVjdG9yIFBDSyA9IG5ldyBLaW5kU2VsZWN0b3IoMHgwMSk7CiAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBLaW5kU2VsZWN0b3IgVFlQID0gbmV3IEtpbmRTZWxlY3RvcigweDAyKTsKICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEtpbmRTZWxlY3RvciBWQVIgPSBuZXcgS2luZFNlbGVjdG9yKDB4MDQpOwogICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgS2luZFNlbGVjdG9yIFZBTCA9IG5ldyBLaW5kU2VsZWN0b3IoMHgwYyk7CiAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBLaW5kU2VsZWN0b3IgTVRIID0gbmV3IEtpbmRTZWxlY3RvcigweDEwKTsKICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEtpbmRTZWxlY3RvciBQT0xZID0gbmV3IEtpbmRTZWxlY3RvcigweDIwKTsKICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEtpbmRTZWxlY3RvciBNREwgPSBuZXcgS2luZFNlbGVjdG9yKDB4NDApOwogICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgS2luZFNlbGVjdG9yIEVSUiA9IG5ldyBLaW5kU2VsZWN0b3IoMHg3Zik7CiAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBLaW5kU2VsZWN0b3IgQVNHID0gbmV3IEtpbmRTZWxlY3RvcigweDg0KTsKCiAgICAgICAgLy9jb21tb24gZGVyaXZlZCBzZWxlY3RvcnMKICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEtpbmRTZWxlY3RvciBUWVBfUENLID0gb2YoVFlQLCBQQ0spOwogICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgS2luZFNlbGVjdG9yIFZBTF9NVEggPSBvZihWQUwsIE1USCk7CiAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBLaW5kU2VsZWN0b3IgVkFMX1BPTFkgPSBvZihWQUwsIFBPTFkpOwogICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgS2luZFNlbGVjdG9yIFZBTF9UWVAgPSBvZihWQUwsIFRZUCk7CiAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBLaW5kU2VsZWN0b3IgVkFMX1RZUF9QQ0sgPSBvZihWQUwsIFRZUCwgUENLKTsKCiAgICAgICAgcHJpdmF0ZSBmaW5hbCBieXRlIGRhdGE7CgogICAgICAgIHByaXZhdGUgS2luZFNlbGVjdG9yKGludCBkYXRhKSB7CiAgICAgICAgICAgIHRoaXMuZGF0YSA9IChieXRlKSBkYXRhOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHN0YXRpYyBLaW5kU2VsZWN0b3Igb2YoS2luZFNlbGVjdG9yLi4uIGtpbmRTZWxlY3RvcnMpIHsKICAgICAgICAgICAgYnl0ZSBuZXdEYXRhID0gMDsKICAgICAgICAgICAgZm9yIChLaW5kU2VsZWN0b3Iga2luZFNlbCA6IGtpbmRTZWxlY3RvcnMpIHsKICAgICAgICAgICAgICAgIG5ld0RhdGEgfD0ga2luZFNlbC5kYXRhOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBuZXcgS2luZFNlbGVjdG9yKG5ld0RhdGEpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIGJvb2xlYW4gc3Vic2V0KEtpbmRTZWxlY3RvciBvdGhlcikgewogICAgICAgICAgICByZXR1cm4gKGRhdGEgJiB+b3RoZXIuZGF0YSkgPT0gMDsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zKEtpbmRTZWxlY3RvciBvdGhlcikgewogICAgICAgICAgICByZXR1cm4gKGRhdGEgJiBvdGhlci5kYXRhKSAhPSAwOwogICAgICAgIH0KCiAgICAgICAgLyoqIEEgc2V0IG9mIEtpbmROYW1lKHMpIHJlcHJlc2VudGluZyBhIHNldCBvZiBzeW1ib2wncyBraW5kcy4gKi8KICAgICAgICBwdWJsaWMgU2V0PEtpbmROYW1lPiBraW5kTmFtZXMoKSB7CiAgICAgICAgICAgIEVudW1TZXQ8S2luZE5hbWU+IGtpbmRzID0gRW51bVNldC5ub25lT2YoS2luZE5hbWUuY2xhc3MpOwogICAgICAgICAgICBpZiAoKGRhdGEgJiBWQUwuZGF0YSkgIT0gMCkgewogICAgICAgICAgICAgICAgaWYgKChkYXRhICYgVkFMLmRhdGEpID09IFZBUi5kYXRhKSBraW5kcy5hZGQoS2luZE5hbWUuVkFSKTsKICAgICAgICAgICAgICAgIGVsc2Uga2luZHMuYWRkKEtpbmROYW1lLlZBTCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKChkYXRhICYgTVRILmRhdGEpICE9IDApIGtpbmRzLmFkZChLaW5kTmFtZS5NRVRIT0QpOwogICAgICAgICAgICBpZiAoKGRhdGEgJiBUWVAuZGF0YSkgIT0gMCkga2luZHMuYWRkKEtpbmROYW1lLkNMQVNTKTsKICAgICAgICAgICAgaWYgKChkYXRhICYgUENLLmRhdGEpICE9IDApIGtpbmRzLmFkZChLaW5kTmFtZS5QQUNLQUdFKTsKICAgICAgICAgICAgaWYgKChkYXRhICYgTURMLmRhdGEpICE9IDApIGtpbmRzLmFkZChLaW5kTmFtZS5NT0RVTEUpOwogICAgICAgICAgICByZXR1cm4ga2luZHM7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBlbnVtIEtpbmROYW1lIGltcGxlbWVudHMgRm9ybWF0dGFibGUgewogICAgICAgIEFOTk9UQVRJT04oImtpbmRuYW1lLmFubm90YXRpb24iKSwKICAgICAgICBDT05TVFJVQ1RPUigia2luZG5hbWUuY29uc3RydWN0b3IiKSwKICAgICAgICBJTlRFUkZBQ0UoImtpbmRuYW1lLmludGVyZmFjZSIpLAogICAgICAgIEVOVU0oImtpbmRuYW1lLmVudW0iKSwKICAgICAgICBTVEFUSUMoImtpbmRuYW1lLnN0YXRpYyIpLAogICAgICAgIFRZUEVWQVIoImtpbmRuYW1lLnR5cGUudmFyaWFibGUiKSwKICAgICAgICBCT1VORCgia2luZG5hbWUudHlwZS52YXJpYWJsZS5ib3VuZCIpLAogICAgICAgIFZBUigia2luZG5hbWUudmFyaWFibGUiKSwKICAgICAgICBWQUwoImtpbmRuYW1lLnZhbHVlIiksCiAgICAgICAgTUVUSE9EKCJraW5kbmFtZS5tZXRob2QiKSwKICAgICAgICBDTEFTUygia2luZG5hbWUuY2xhc3MiKSwKICAgICAgICBTVEFUSUNfSU5JVCgia2luZG5hbWUuc3RhdGljLmluaXQiKSwKICAgICAgICBJTlNUQU5DRV9JTklUKCJraW5kbmFtZS5pbnN0YW5jZS5pbml0IiksCiAgICAgICAgUEFDS0FHRSgia2luZG5hbWUucGFja2FnZSIpLAogICAgICAgIE1PRFVMRSgia2luZG5hbWUubW9kdWxlIik7CgogICAgICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIG5hbWU7CgogICAgICAgIEtpbmROYW1lKFN0cmluZyBuYW1lKSB7CiAgICAgICAgICAgIHRoaXMubmFtZSA9IG5hbWU7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewogICAgICAgICAgICByZXR1cm4gbmFtZTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0S2luZCgpIHsKICAgICAgICAgICAgcmV0dXJuICJLaW5kbmFtZSI7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKExvY2FsZSBsb2NhbGUsIE1lc3NhZ2VzIG1lc3NhZ2VzKSB7CiAgICAgICAgICAgIFN0cmluZyBzID0gdG9TdHJpbmcoKTsKICAgICAgICAgICAgcmV0dXJuIG1lc3NhZ2VzLmdldExvY2FsaXplZFN0cmluZyhsb2NhbGUsICJjb21waWxlci5taXNjLiIgKyBzKTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBLaW5kTmFtZSBraW5kTmFtZShNZW1iZXJSZWZlcmVuY2VUcmVlLlJlZmVyZW5jZU1vZGUgbW9kZSkgewogICAgICAgIHN3aXRjaCAobW9kZSkgewogICAgICAgICAgICBjYXNlIElOVk9LRTogcmV0dXJuIEtpbmROYW1lLk1FVEhPRDsKICAgICAgICAgICAgY2FzZSBORVc6IHJldHVybiBLaW5kTmFtZS5DT05TVFJVQ1RPUjsKICAgICAgICAgICAgZGVmYXVsdCA6IHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigiVW5leHBlY3RlZCBtb2RlOiAiKyBtb2RlKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqIEEgS2luZE5hbWUgcmVwcmVzZW50aW5nIGEgZ2l2ZW4gc3ltYm9sCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgS2luZE5hbWUga2luZE5hbWUoU3ltYm9sIHN5bSkgewogICAgICAgIHN3aXRjaCAoc3ltLmdldEtpbmQoKSkgewogICAgICAgIGNhc2UgUEFDS0FHRToKICAgICAgICAgICAgcmV0dXJuIEtpbmROYW1lLlBBQ0tBR0U7CgogICAgICAgIGNhc2UgRU5VTToKICAgICAgICAgICAgcmV0dXJuIEtpbmROYW1lLkVOVU07CgogICAgICAgIGNhc2UgQU5OT1RBVElPTl9UWVBFOgogICAgICAgIGNhc2UgQ0xBU1M6CiAgICAgICAgICAgIHJldHVybiBLaW5kTmFtZS5DTEFTUzsKCiAgICAgICAgY2FzZSBJTlRFUkZBQ0U6CiAgICAgICAgICAgIHJldHVybiBLaW5kTmFtZS5JTlRFUkZBQ0U7CgogICAgICAgIGNhc2UgVFlQRV9QQVJBTUVURVI6CiAgICAgICAgICAgIHJldHVybiBLaW5kTmFtZS5UWVBFVkFSOwoKICAgICAgICBjYXNlIEVOVU1fQ09OU1RBTlQ6CiAgICAgICAgY2FzZSBGSUVMRDoKICAgICAgICBjYXNlIFBBUkFNRVRFUjoKICAgICAgICBjYXNlIExPQ0FMX1ZBUklBQkxFOgogICAgICAgIGNhc2UgRVhDRVBUSU9OX1BBUkFNRVRFUjoKICAgICAgICBjYXNlIFJFU09VUkNFX1ZBUklBQkxFOgogICAgICAgICAgICByZXR1cm4gS2luZE5hbWUuVkFSOwoKICAgICAgICBjYXNlIENPTlNUUlVDVE9SOgogICAgICAgICAgICByZXR1cm4gS2luZE5hbWUuQ09OU1RSVUNUT1I7CgogICAgICAgIGNhc2UgTUVUSE9EOgogICAgICAgICAgICByZXR1cm4gS2luZE5hbWUuTUVUSE9EOwogICAgICAgIGNhc2UgU1RBVElDX0lOSVQ6CiAgICAgICAgICAgIHJldHVybiBLaW5kTmFtZS5TVEFUSUNfSU5JVDsKICAgICAgICBjYXNlIElOU1RBTkNFX0lOSVQ6CiAgICAgICAgICAgIHJldHVybiBLaW5kTmFtZS5JTlNUQU5DRV9JTklUOwoKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCJVbmV4cGVjdGVkIGtpbmQ6ICIrc3ltLmdldEtpbmQoKSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKiBBIEtpbmROYW1lIHJlcHJlc2VudGluZyB0aGUga2luZCBvZiBhIGdpdmVuIGNsYXNzL2ludGVyZmFjZSB0eXBlLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIEtpbmROYW1lIHR5cGVLaW5kTmFtZShUeXBlIHQpIHsKICAgICAgICBpZiAodC5oYXNUYWcoVFlQRVZBUikgfHwKICAgICAgICAgICAgdC5oYXNUYWcoQ0xBU1MpICYmICh0LnRzeW0uZmxhZ3MoKSAmIENPTVBPVU5EKSAhPSAwKQogICAgICAgICAgICByZXR1cm4gS2luZE5hbWUuQk9VTkQ7CiAgICAgICAgZWxzZSBpZiAodC5oYXNUYWcoUEFDS0FHRSkpCiAgICAgICAgICAgIHJldHVybiBLaW5kTmFtZS5QQUNLQUdFOwogICAgICAgIGVsc2UgaWYgKCh0LnRzeW0uZmxhZ3NfZmllbGQgJiBBTk5PVEFUSU9OKSAhPSAwKQogICAgICAgICAgICByZXR1cm4gS2luZE5hbWUuQU5OT1RBVElPTjsKICAgICAgICBlbHNlIGlmICgodC50c3ltLmZsYWdzX2ZpZWxkICYgSU5URVJGQUNFKSAhPSAwKQogICAgICAgICAgICByZXR1cm4gS2luZE5hbWUuSU5URVJGQUNFOwogICAgICAgIGVsc2UKICAgICAgICAgICAgcmV0dXJuIEtpbmROYW1lLkNMQVNTOwogICAgfQoKfQpQSwMECgAACAAArjypStT89Vwm3AIAJtwCACMAAABjb20vc3VuL3Rvb2xzL2phdmFjL2NvZGUvVHlwZXMuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwMywgMjAxNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGU7CgppbXBvcnQgamF2YS5sYW5nLnJlZi5Tb2Z0UmVmZXJlbmNlOwppbXBvcnQgamF2YS51dGlsLkhhc2hTZXQ7CmltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CmltcG9ydCBqYXZhLnV0aWwuTWFwOwppbXBvcnQgamF2YS51dGlsLk9wdGlvbmFsOwppbXBvcnQgamF2YS51dGlsLlNldDsKaW1wb3J0IGphdmEudXRpbC5XZWFrSGFzaE1hcDsKaW1wb3J0IGphdmEudXRpbC5mdW5jdGlvbi5CaVByZWRpY2F0ZTsKaW1wb3J0IGphdmEudXRpbC5mdW5jdGlvbi5GdW5jdGlvbjsKaW1wb3J0IGphdmEudXRpbC5zdHJlYW0uQ29sbGVjdG9yOwoKaW1wb3J0IGphdmF4LnRvb2xzLkphdmFGaWxlT2JqZWN0OwoKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5BdHRyaWJ1dGUuUmV0ZW50aW9uUG9saWN5OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLkxpbnQuTGludENhdGVnb3J5OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlR5cGUuVW5kZXRWYXIuSW5mZXJlbmNlQm91bmQ7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuVHlwZU1ldGFkYXRhLkVudHJ5LktpbmQ7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvbXAuQXR0ckNvbnRleHQ7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvbXAuQ2hlY2s7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvbXAuRW50ZXI7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvbXAuRW52OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLio7CgppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5Cb3VuZEtpbmQuKjsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuRmxhZ3MuKjsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuS2luZHMuS2luZC4qOwppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5TY29wZS4qOwppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5TY29wZS5Mb29rdXBLaW5kLk5PTl9SRUNVUlNJVkU7CmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlN5bWJvbC4qOwppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5UeXBlLio7CmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlR5cGVUYWcuKjsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmp2bS5DbGFzc0ZpbGUuZXh0ZXJuYWxpemU7CgovKioKICogVXRpbGl0eSBjbGFzcyBjb250YWluaW5nIHZhcmlvdXMgb3BlcmF0aW9ucyBvbiB0eXBlcy4KICoKICogPHA+VW5sZXNzIG90aGVyIG5hbWVzIGFyZSBtb3JlIGlsbHVzdHJhdGl2ZSwgdGhlIGZvbGxvd2luZyBuYW1pbmcKICogY29udmVudGlvbnMgc2hvdWxkIGJlIG9ic2VydmVkIGluIHRoaXMgZmlsZToKICoKICogPGRsPgogKiA8ZHQ+dDwvZHQ+CiAqIDxkZD5JZiB0aGUgZmlyc3QgYXJndW1lbnQgdG8gYW4gb3BlcmF0aW9uIGlzIGEgdHlwZSwgaXQgc2hvdWxkIGJlIG5hbWVkIHQuPC9kZD4KICogPGR0PnM8L2R0PgogKiA8ZGQ+U2ltaWxhcmx5LCBpZiB0aGUgc2Vjb25kIGFyZ3VtZW50IHRvIGFuIG9wZXJhdGlvbiBpcyBhIHR5cGUsIGl0IHNob3VsZCBiZSBuYW1lZCBzLjwvZGQ+CiAqIDxkdD50czwvZHQ+CiAqIDxkZD5JZiBhbiBvcGVyYXRpb25zIHRha2VzIGEgbGlzdCBvZiB0eXBlcywgdGhlIGZpcnN0IHNob3VsZCBiZSBuYW1lZCB0cy48L2RkPgogKiA8ZHQ+c3M8L2R0PgogKiA8ZGQ+QSBzZWNvbmQgbGlzdCBvZiB0eXBlcyBzaG91bGQgYmUgbmFtZWQgc3MuPC9kZD4KICogPC9kbD4KICoKICogPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93biByaXNrLgogKiBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogKiBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+CiAqLwpwdWJsaWMgY2xhc3MgVHlwZXMgewogICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBDb250ZXh0LktleTxUeXBlcz4gdHlwZXNLZXkgPSBuZXcgQ29udGV4dC5LZXk8PigpOwoKICAgIGZpbmFsIFN5bXRhYiBzeW1zOwogICAgZmluYWwgSmF2YWNNZXNzYWdlcyBtZXNzYWdlczsKICAgIGZpbmFsIE5hbWVzIG5hbWVzOwogICAgZmluYWwgYm9vbGVhbiBhbGxvd09iamVjdFRvUHJpbWl0aXZlQ2FzdDsKICAgIGZpbmFsIGJvb2xlYW4gYWxsb3dEZWZhdWx0TWV0aG9kczsKICAgIGZpbmFsIGJvb2xlYW4gbWFwQ2FwdHVyZXNUb0JvdW5kczsKICAgIGZpbmFsIENoZWNrIGNoazsKICAgIGZpbmFsIEVudGVyIGVudGVyOwogICAgSkNEaWFnbm9zdGljLkZhY3RvcnkgZGlhZ3M7CiAgICBMaXN0PFdhcm5lcj4gd2FyblN0YWNrID0gTGlzdC5uaWwoKTsKICAgIGZpbmFsIE5hbWUgY2FwdHVyZWROYW1lOwogICAgcHJpdmF0ZSBmaW5hbCBGdW5jdGlvbkRlc2NyaXB0b3JMb29rdXBFcnJvciBmdW5jdGlvbkRlc2NyaXB0b3JMb29rdXBFcnJvcjsKCiAgICBwdWJsaWMgZmluYWwgV2FybmVyIG5vV2FybmluZ3M7CgogICAgLy8gPGVkaXRvci1mb2xkIGRlZmF1bHRzdGF0ZT0iY29sbGFwc2VkIiBkZXNjPSJJbnN0YW50aWF0aW5nIj4KICAgIHB1YmxpYyBzdGF0aWMgVHlwZXMgaW5zdGFuY2UoQ29udGV4dCBjb250ZXh0KSB7CiAgICAgICAgVHlwZXMgaW5zdGFuY2UgPSBjb250ZXh0LmdldCh0eXBlc0tleSk7CiAgICAgICAgaWYgKGluc3RhbmNlID09IG51bGwpCiAgICAgICAgICAgIGluc3RhbmNlID0gbmV3IFR5cGVzKGNvbnRleHQpOwogICAgICAgIHJldHVybiBpbnN0YW5jZTsKICAgIH0KCiAgICBwcm90ZWN0ZWQgVHlwZXMoQ29udGV4dCBjb250ZXh0KSB7CiAgICAgICAgY29udGV4dC5wdXQodHlwZXNLZXksIHRoaXMpOwogICAgICAgIHN5bXMgPSBTeW10YWIuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgbmFtZXMgPSBOYW1lcy5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBTb3VyY2Ugc291cmNlID0gU291cmNlLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIGFsbG93T2JqZWN0VG9QcmltaXRpdmVDYXN0ID0gc291cmNlLmFsbG93T2JqZWN0VG9QcmltaXRpdmVDYXN0KCk7CiAgICAgICAgYWxsb3dEZWZhdWx0TWV0aG9kcyA9IHNvdXJjZS5hbGxvd0RlZmF1bHRNZXRob2RzKCk7CiAgICAgICAgbWFwQ2FwdHVyZXNUb0JvdW5kcyA9IHNvdXJjZS5tYXBDYXB0dXJlc1RvQm91bmRzKCk7CiAgICAgICAgY2hrID0gQ2hlY2suaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgZW50ZXIgPSBFbnRlci5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBjYXB0dXJlZE5hbWUgPSBuYW1lcy5mcm9tU3RyaW5nKCI8Y2FwdHVyZWQgd2lsZGNhcmQ+Iik7CiAgICAgICAgbWVzc2FnZXMgPSBKYXZhY01lc3NhZ2VzLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIGRpYWdzID0gSkNEaWFnbm9zdGljLkZhY3RvcnkuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgZnVuY3Rpb25EZXNjcmlwdG9yTG9va3VwRXJyb3IgPSBuZXcgRnVuY3Rpb25EZXNjcmlwdG9yTG9va3VwRXJyb3IoKTsKICAgICAgICBub1dhcm5pbmdzID0gbmV3IFdhcm5lcihudWxsKTsKICAgIH0KICAgIC8vIDwvZWRpdG9yLWZvbGQ+CgogICAgLy8gPGVkaXRvci1mb2xkIGRlZmF1bHRzdGF0ZT0iY29sbGFwc2VkIiBkZXNjPSJib3VuZHMiPgogICAgLyoqCiAgICAgKiBHZXQgYSB3aWxkY2FyZCdzIHVwcGVyIGJvdW5kLCByZXR1cm5pbmcgbm9uLXdpbGRjYXJkcyB1bmNoYW5nZWQuCiAgICAgKiBAcGFyYW0gdCBhIHR5cGUgYXJndW1lbnQsIGVpdGhlciBhIHdpbGRjYXJkIG9yIGEgdHlwZQogICAgICovCiAgICBwdWJsaWMgVHlwZSB3aWxkVXBwZXJCb3VuZChUeXBlIHQpIHsKICAgICAgICBpZiAodC5oYXNUYWcoV0lMRENBUkQpKSB7CiAgICAgICAgICAgIFdpbGRjYXJkVHlwZSB3ID0gKFdpbGRjYXJkVHlwZSkgdDsKICAgICAgICAgICAgaWYgKHcuaXNTdXBlckJvdW5kKCkpCiAgICAgICAgICAgICAgICByZXR1cm4gdy5ib3VuZCA9PSBudWxsID8gc3ltcy5vYmplY3RUeXBlIDogdy5ib3VuZC5ib3VuZDsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgcmV0dXJuIHdpbGRVcHBlckJvdW5kKHcudHlwZSk7CiAgICAgICAgfQogICAgICAgIGVsc2UgcmV0dXJuIHQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXQgYSBjYXB0dXJlIHZhcmlhYmxlJ3MgdXBwZXIgYm91bmQsIHJldHVybmluZyBvdGhlciB0eXBlcyB1bmNoYW5nZWQuCiAgICAgKiBAcGFyYW0gdCBhIHR5cGUKICAgICAqLwogICAgcHVibGljIFR5cGUgY3ZhclVwcGVyQm91bmQoVHlwZSB0KSB7CiAgICAgICAgaWYgKHQuaGFzVGFnKFRZUEVWQVIpKSB7CiAgICAgICAgICAgIFR5cGVWYXIgdiA9IChUeXBlVmFyKSB0OwogICAgICAgICAgICByZXR1cm4gdi5pc0NhcHR1cmVkKCkgPyBjdmFyVXBwZXJCb3VuZCh2LmJvdW5kKSA6IHY7CiAgICAgICAgfQogICAgICAgIGVsc2UgcmV0dXJuIHQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXQgYSB3aWxkY2FyZCdzIGxvd2VyIGJvdW5kLCByZXR1cm5pbmcgbm9uLXdpbGRjYXJkcyB1bmNoYW5nZWQuCiAgICAgKiBAcGFyYW0gdCBhIHR5cGUgYXJndW1lbnQsIGVpdGhlciBhIHdpbGRjYXJkIG9yIGEgdHlwZQogICAgICovCiAgICBwdWJsaWMgVHlwZSB3aWxkTG93ZXJCb3VuZChUeXBlIHQpIHsKICAgICAgICBpZiAodC5oYXNUYWcoV0lMRENBUkQpKSB7CiAgICAgICAgICAgIFdpbGRjYXJkVHlwZSB3ID0gKFdpbGRjYXJkVHlwZSkgdDsKICAgICAgICAgICAgcmV0dXJuIHcuaXNFeHRlbmRzQm91bmQoKSA/IHN5bXMuYm90VHlwZSA6IHdpbGRMb3dlckJvdW5kKHcudHlwZSk7CiAgICAgICAgfQogICAgICAgIGVsc2UgcmV0dXJuIHQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXQgYSBjYXB0dXJlIHZhcmlhYmxlJ3MgbG93ZXIgYm91bmQsIHJldHVybmluZyBvdGhlciB0eXBlcyB1bmNoYW5nZWQuCiAgICAgKiBAcGFyYW0gdCBhIHR5cGUKICAgICAqLwogICAgcHVibGljIFR5cGUgY3Zhckxvd2VyQm91bmQoVHlwZSB0KSB7CiAgICAgICAgaWYgKHQuaGFzVGFnKFRZUEVWQVIpICYmICgoVHlwZVZhcikgdCkuaXNDYXB0dXJlZCgpKSB7CiAgICAgICAgICAgIHJldHVybiBjdmFyTG93ZXJCb3VuZCh0LmdldExvd2VyQm91bmQoKSk7CiAgICAgICAgfQogICAgICAgIGVsc2UgcmV0dXJuIHQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZWN1cnNpdmVseSBza2lwIHR5cGUtdmFyaWFibGVzIHVudGlsIGEgY2xhc3MvYXJyYXkgdHlwZSBpcyBmb3VuZDsgY2FwdHVyZSBjb252ZXJzaW9uIGlzIHRoZW4KICAgICAqIChvcHRpb25hbGx5KSBhcHBsaWVkIHRvIHRoZSByZXN1bHRpbmcgdHlwZS4gVGhpcyBpcyB1c2VmdWwgZm9yIGkuZS4gY29tcHV0aW5nIGEgc2l0ZSB0aGF0IGlzCiAgICAgKiBzdWl0YWJsZSBmb3IgYSBtZXRob2QgbG9va3VwLgogICAgICovCiAgICBwdWJsaWMgVHlwZSBza2lwVHlwZVZhcnMoVHlwZSBzaXRlLCBib29sZWFuIGNhcHR1cmUpIHsKICAgICAgICB3aGlsZSAoc2l0ZS5oYXNUYWcoVFlQRVZBUikpIHsKICAgICAgICAgICAgc2l0ZSA9IHNpdGUuZ2V0VXBwZXJCb3VuZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gY2FwdHVyZSA/IGNhcHR1cmUoc2l0ZSkgOiBzaXRlOwogICAgfQogICAgLy8gPC9lZGl0b3ItZm9sZD4KCiAgICAvLyA8ZWRpdG9yLWZvbGQgZGVmYXVsdHN0YXRlPSJjb2xsYXBzZWQiIGRlc2M9ImlzVW5ib3VuZGVkIj4KICAgIC8qKgogICAgICogQ2hlY2tzIHRoYXQgYWxsIHRoZSBhcmd1bWVudHMgdG8gYSBjbGFzcyBhcmUgdW5ib3VuZGVkCiAgICAgKiB3aWxkY2FyZHMgb3Igc29tZXRoaW5nIGVsc2UgdGhhdCBkb2Vzbid0IG1ha2UgYW55IHJlc3RyaWN0aW9ucwogICAgICogb24gdGhlIGFyZ3VtZW50cy4gSWYgYSBjbGFzcyBpc1VuYm91bmRlZCwgYSByYXcgc3VwZXItIG9yCiAgICAgKiBzdWJjbGFzcyBjYW4gYmUgY2FzdCB0byBpdCB3aXRob3V0IGEgd2FybmluZy4KICAgICAqIEBwYXJhbSB0IGEgdHlwZQogICAgICogQHJldHVybiB0cnVlIGlmZiB0aGUgZ2l2ZW4gdHlwZSBpcyB1bmJvdW5kZWQgb3IgcmF3CiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGlzVW5ib3VuZGVkKFR5cGUgdCkgewogICAgICAgIHJldHVybiBpc1VuYm91bmRlZC52aXNpdCh0KTsKICAgIH0KICAgIC8vIHdoZXJlCiAgICAgICAgcHJpdmF0ZSBmaW5hbCBVbmFyeVZpc2l0b3I8Qm9vbGVhbj4gaXNVbmJvdW5kZWQgPSBuZXcgVW5hcnlWaXNpdG9yPEJvb2xlYW4+KCkgewoKICAgICAgICAgICAgcHVibGljIEJvb2xlYW4gdmlzaXRUeXBlKFR5cGUgdCwgVm9pZCBpZ25vcmVkKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHB1YmxpYyBCb29sZWFuIHZpc2l0Q2xhc3NUeXBlKENsYXNzVHlwZSB0LCBWb2lkIGlnbm9yZWQpIHsKICAgICAgICAgICAgICAgIExpc3Q8VHlwZT4gcGFybXMgPSB0LnRzeW0udHlwZS5hbGxwYXJhbXMoKTsKICAgICAgICAgICAgICAgIExpc3Q8VHlwZT4gYXJncyA9IHQuYWxscGFyYW1zKCk7CiAgICAgICAgICAgICAgICB3aGlsZSAocGFybXMubm9uRW1wdHkoKSkgewogICAgICAgICAgICAgICAgICAgIFdpbGRjYXJkVHlwZSB1bmIgPSBuZXcgV2lsZGNhcmRUeXBlKHN5bXMub2JqZWN0VHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCb3VuZEtpbmQuVU5CT1VORCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeW1zLmJvdW5kQ2xhc3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFR5cGVWYXIpcGFybXMuaGVhZCk7CiAgICAgICAgICAgICAgICAgICAgaWYgKCFjb250YWluc1R5cGUoYXJncy5oZWFkLCB1bmIpKQogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgcGFybXMgPSBwYXJtcy50YWlsOwogICAgICAgICAgICAgICAgICAgIGFyZ3MgPSBhcmdzLnRhaWw7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH07CiAgICAvLyA8L2VkaXRvci1mb2xkPgoKICAgIC8vIDxlZGl0b3ItZm9sZCBkZWZhdWx0c3RhdGU9ImNvbGxhcHNlZCIgZGVzYz0iYXNTdWIiPgogICAgLyoqCiAgICAgKiBSZXR1cm4gdGhlIGxlYXN0IHNwZWNpZmljIHN1YnR5cGUgb2YgdCB0aGF0IHN0YXJ0cyB3aXRoIHN5bWJvbAogICAgICogc3ltLiAgSWYgbm9uZSBleGlzdHMsIHJldHVybiBudWxsLiAgVGhlIGxlYXN0IHNwZWNpZmljIHN1YnR5cGUKICAgICAqIGlzIGRldGVybWluZWQgYXMgZm9sbG93czoKICAgICAqCiAgICAgKiA8cD5JZiB0aGVyZSBpcyBleGFjdGx5IG9uZSBwYXJhbWV0ZXJpemVkIGluc3RhbmNlIG9mIHN5bSB0aGF0IGlzIGEKICAgICAqIHN1YnR5cGUgb2YgdCwgdGhhdCBwYXJhbWV0ZXJpemVkIGluc3RhbmNlIGlzIHJldHVybmVkLjxicj4KICAgICAqIE90aGVyd2lzZSwgaWYgdGhlIHBsYWluIHR5cGUgb3IgcmF3IHR5cGUgYHN5bScgaXMgYSBzdWJ0eXBlIG9mCiAgICAgKiB0eXBlIHQsIHRoZSB0eXBlIGBzeW0nIGl0c2VsZiBpcyByZXR1cm5lZC4gIE90aGVyd2lzZSwgbnVsbCBpcwogICAgICogcmV0dXJuZWQuCiAgICAgKi8KICAgIHB1YmxpYyBUeXBlIGFzU3ViKFR5cGUgdCwgU3ltYm9sIHN5bSkgewogICAgICAgIHJldHVybiBhc1N1Yi52aXNpdCh0LCBzeW0pOwogICAgfQogICAgLy8gd2hlcmUKICAgICAgICBwcml2YXRlIGZpbmFsIFNpbXBsZVZpc2l0b3I8VHlwZSxTeW1ib2w+IGFzU3ViID0gbmV3IFNpbXBsZVZpc2l0b3I8VHlwZSxTeW1ib2w+KCkgewoKICAgICAgICAgICAgcHVibGljIFR5cGUgdmlzaXRUeXBlKFR5cGUgdCwgU3ltYm9sIHN5bSkgewogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgVHlwZSB2aXNpdENsYXNzVHlwZShDbGFzc1R5cGUgdCwgU3ltYm9sIHN5bSkgewogICAgICAgICAgICAgICAgaWYgKHQudHN5bSA9PSBzeW0pCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHQ7CiAgICAgICAgICAgICAgICBUeXBlIGJhc2UgPSBhc1N1cGVyKHN5bS50eXBlLCB0LnRzeW0pOwogICAgICAgICAgICAgICAgaWYgKGJhc2UgPT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgIExpc3RCdWZmZXI8VHlwZT4gZnJvbSA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICAgICAgICAgIExpc3RCdWZmZXI8VHlwZT4gdG8gPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIGFkYXB0KGJhc2UsIHQsIGZyb20sIHRvKTsKICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEFkYXB0RmFpbHVyZSBleCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgVHlwZSByZXMgPSBzdWJzdChzeW0udHlwZSwgZnJvbS50b0xpc3QoKSwgdG8udG9MaXN0KCkpOwogICAgICAgICAgICAgICAgaWYgKCFpc1N1YnR5cGUocmVzLCB0KSkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgIExpc3RCdWZmZXI8VHlwZT4gb3BlblZhcnMgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgICAgICBmb3IgKExpc3Q8VHlwZT4gbCA9IHN5bS50eXBlLmFsbHBhcmFtcygpOwogICAgICAgICAgICAgICAgICAgICBsLm5vbkVtcHR5KCk7IGwgPSBsLnRhaWwpCiAgICAgICAgICAgICAgICAgICAgaWYgKHJlcy5jb250YWlucyhsLmhlYWQpICYmICF0LmNvbnRhaW5zKGwuaGVhZCkpCiAgICAgICAgICAgICAgICAgICAgICAgIG9wZW5WYXJzLmFwcGVuZChsLmhlYWQpOwogICAgICAgICAgICAgICAgaWYgKG9wZW5WYXJzLm5vbkVtcHR5KCkpIHsKICAgICAgICAgICAgICAgICAgICBpZiAodC5pc1JhdygpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoZSBzdWJ0eXBlIG9mIGEgcmF3IHR5cGUgaXMgcmF3CiAgICAgICAgICAgICAgICAgICAgICAgIHJlcyA9IGVyYXN1cmUocmVzKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBVbmJvdW5kIHR5cGUgYXJndW1lbnRzIGRlZmF1bHQgdG8gPwogICAgICAgICAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IG9wZW5zID0gb3BlblZhcnMudG9MaXN0KCk7CiAgICAgICAgICAgICAgICAgICAgICAgIExpc3RCdWZmZXI8VHlwZT4gcXMgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoTGlzdDxUeXBlPiBpdGVyID0gb3BlbnM7IGl0ZXIubm9uRW1wdHkoKTsgaXRlciA9IGl0ZXIudGFpbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcXMuYXBwZW5kKG5ldyBXaWxkY2FyZFR5cGUoc3ltcy5vYmplY3RUeXBlLCBCb3VuZEtpbmQuVU5CT1VORCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5bXMuYm91bmRDbGFzcywgKFR5cGVWYXIpIGl0ZXIuaGVhZCkpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIHJlcyA9IHN1YnN0KHJlcywgb3BlbnMsIHFzLnRvTGlzdCgpKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gcmVzOwogICAgICAgICAgICB9CgogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHVibGljIFR5cGUgdmlzaXRFcnJvclR5cGUoRXJyb3JUeXBlIHQsIFN5bWJvbCBzeW0pIHsKICAgICAgICAgICAgICAgIHJldHVybiB0OwogICAgICAgICAgICB9CiAgICAgICAgfTsKICAgIC8vIDwvZWRpdG9yLWZvbGQ+CgogICAgLy8gPGVkaXRvci1mb2xkIGRlZmF1bHRzdGF0ZT0iY29sbGFwc2VkIiBkZXNjPSJpc0NvbnZlcnRpYmxlIj4KICAgIC8qKgogICAgICogSXMgdCBhIHN1YnR5cGUgb2Ygb3IgY29udmVydGlibGUgdmlhIGJveGluZy91bmJveGluZwogICAgICogY29udmVyc2lvbiB0byBzPwogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBpc0NvbnZlcnRpYmxlKFR5cGUgdCwgVHlwZSBzLCBXYXJuZXIgd2FybikgewogICAgICAgIGlmICh0Lmhhc1RhZyhFUlJPUikpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgICAgIGJvb2xlYW4gdFByaW1pdGl2ZSA9IHQuaXNQcmltaXRpdmUoKTsKICAgICAgICBib29sZWFuIHNQcmltaXRpdmUgPSBzLmlzUHJpbWl0aXZlKCk7CiAgICAgICAgaWYgKHRQcmltaXRpdmUgPT0gc1ByaW1pdGl2ZSkgewogICAgICAgICAgICByZXR1cm4gaXNTdWJ0eXBlVW5jaGVja2VkKHQsIHMsIHdhcm4pOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdFByaW1pdGl2ZQogICAgICAgICAgICA/IGlzU3VidHlwZShib3hlZENsYXNzKHQpLnR5cGUsIHMpCiAgICAgICAgICAgIDogaXNTdWJ0eXBlKHVuYm94ZWRUeXBlKHQpLCBzKTsKICAgIH0KCiAgICAvKioKICAgICAqIElzIHQgYSBzdWJ0eXBlIG9mIG9yIGNvbnZlcnRpYmxlIHZpYSBib3hpbmcvdW5ib3hpbmcKICAgICAqIGNvbnZlcnNpb25zIHRvIHM/CiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGlzQ29udmVydGlibGUoVHlwZSB0LCBUeXBlIHMpIHsKICAgICAgICByZXR1cm4gaXNDb252ZXJ0aWJsZSh0LCBzLCBub1dhcm5pbmdzKTsKICAgIH0KICAgIC8vIDwvZWRpdG9yLWZvbGQ+CgogICAgLy8gPGVkaXRvci1mb2xkIGRlZmF1bHRzdGF0ZT0iY29sbGFwc2VkIiBkZXNjPSJmaW5kU2FtIj4KCiAgICAvKioKICAgICAqIEV4Y2VwdGlvbiB1c2VkIHRvIHJlcG9ydCBhIGZ1bmN0aW9uIGRlc2NyaXB0b3IgbG9va3VwIGZhaWx1cmUuIFRoZSBleGNlcHRpb24KICAgICAqIHdyYXBzIGEgZGlhZ25vc3RpYyB0aGF0IGNhbiBiZSB1c2VkIHRvIGdlbmVyYXRlIG1vcmUgZGV0YWlscyBlcnJvcgogICAgICogbWVzc2FnZXMuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgRnVuY3Rpb25EZXNjcmlwdG9yTG9va3VwRXJyb3IgZXh0ZW5kcyBSdW50aW1lRXhjZXB0aW9uIHsKICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwOwoKICAgICAgICBKQ0RpYWdub3N0aWMgZGlhZ25vc3RpYzsKCiAgICAgICAgRnVuY3Rpb25EZXNjcmlwdG9yTG9va3VwRXJyb3IoKSB7CiAgICAgICAgICAgIHRoaXMuZGlhZ25vc3RpYyA9IG51bGw7CiAgICAgICAgfQoKICAgICAgICBGdW5jdGlvbkRlc2NyaXB0b3JMb29rdXBFcnJvciBzZXRNZXNzYWdlKEpDRGlhZ25vc3RpYyBkaWFnKSB7CiAgICAgICAgICAgIHRoaXMuZGlhZ25vc3RpYyA9IGRpYWc7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIEpDRGlhZ25vc3RpYyBnZXREaWFnbm9zdGljKCkgewogICAgICAgICAgICByZXR1cm4gZGlhZ25vc3RpYzsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBBIGNhY2hlIHRoYXQga2VlcHMgdHJhY2sgb2YgZnVuY3Rpb24gZGVzY3JpcHRvcnMgYXNzb2NpYXRlZCB3aXRoIGdpdmVuCiAgICAgKiBmdW5jdGlvbmFsIGludGVyZmFjZXMuCiAgICAgKi8KICAgIGNsYXNzIERlc2NyaXB0b3JDYWNoZSB7CgogICAgICAgIHByaXZhdGUgV2Vha0hhc2hNYXA8VHlwZVN5bWJvbCwgRW50cnk+IF9tYXAgPSBuZXcgV2Vha0hhc2hNYXA8PigpOwoKICAgICAgICBjbGFzcyBGdW5jdGlvbkRlc2NyaXB0b3IgewogICAgICAgICAgICBTeW1ib2wgZGVzY1N5bTsKCiAgICAgICAgICAgIEZ1bmN0aW9uRGVzY3JpcHRvcihTeW1ib2wgZGVzY1N5bSkgewogICAgICAgICAgICAgICAgdGhpcy5kZXNjU3ltID0gZGVzY1N5bTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHVibGljIFN5bWJvbCBnZXRTeW1ib2woKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZGVzY1N5bTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHVibGljIFR5cGUgZ2V0VHlwZShUeXBlIHNpdGUpIHsKICAgICAgICAgICAgICAgIHNpdGUgPSByZW1vdmVXaWxkY2FyZHMoc2l0ZSk7CiAgICAgICAgICAgICAgICBpZiAoIWNoay5jaGVja1ZhbGlkR2VuZXJpY1R5cGUoc2l0ZSkpIHsKICAgICAgICAgICAgICAgICAgICAvL2lmIHRoZSBpbmZlcnJlZCBmdW5jdGlvbmFsIGludGVyZmFjZSB0eXBlIGlzIG5vdCB3ZWxsLWZvcm1lZCwKICAgICAgICAgICAgICAgICAgICAvL29yIGlmIGl0J3Mgbm90IGEgc3VidHlwZSBvZiB0aGUgb3JpZ2luYWwgdGFyZ2V0LCBpc3N1ZSBhbiBlcnJvcgogICAgICAgICAgICAgICAgICAgIHRocm93IGZhaWx1cmUoZGlhZ3MuZnJhZ21lbnQoIm5vLnN1aXRhYmxlLmZ1bmN0aW9uYWwuaW50Zi5pbnN0Iiwgc2l0ZSkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIG1lbWJlclR5cGUoc2l0ZSwgZGVzY1N5bSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGNsYXNzIEVudHJ5IHsKICAgICAgICAgICAgZmluYWwgRnVuY3Rpb25EZXNjcmlwdG9yIGNhY2hlZERlc2NSZXM7CiAgICAgICAgICAgIGZpbmFsIGludCBwcmV2TWFyazsKCiAgICAgICAgICAgIHB1YmxpYyBFbnRyeShGdW5jdGlvbkRlc2NyaXB0b3IgY2FjaGVkRGVzY1JlcywKICAgICAgICAgICAgICAgICAgICBpbnQgcHJldk1hcmspIHsKICAgICAgICAgICAgICAgIHRoaXMuY2FjaGVkRGVzY1JlcyA9IGNhY2hlZERlc2NSZXM7CiAgICAgICAgICAgICAgICB0aGlzLnByZXZNYXJrID0gcHJldk1hcms7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGJvb2xlYW4gbWF0Y2hlcyhpbnQgbWFyaykgewogICAgICAgICAgICAgICAgcmV0dXJuICB0aGlzLnByZXZNYXJrID09IG1hcms7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEZ1bmN0aW9uRGVzY3JpcHRvciBnZXQoVHlwZVN5bWJvbCBvcmlnaW4pIHRocm93cyBGdW5jdGlvbkRlc2NyaXB0b3JMb29rdXBFcnJvciB7CiAgICAgICAgICAgIEVudHJ5IGUgPSBfbWFwLmdldChvcmlnaW4pOwogICAgICAgICAgICBDb21wb3VuZFNjb3BlIG1lbWJlcnMgPSBtZW1iZXJzQ2xvc3VyZShvcmlnaW4udHlwZSwgZmFsc2UpOwogICAgICAgICAgICBpZiAoZSA9PSBudWxsIHx8CiAgICAgICAgICAgICAgICAgICAgIWUubWF0Y2hlcyhtZW1iZXJzLmdldE1hcmsoKSkpIHsKICAgICAgICAgICAgICAgIEZ1bmN0aW9uRGVzY3JpcHRvciBkZXNjUmVzID0gZmluZERlc2NyaXB0b3JJbnRlcm5hbChvcmlnaW4sIG1lbWJlcnMpOwogICAgICAgICAgICAgICAgX21hcC5wdXQob3JpZ2luLCBuZXcgRW50cnkoZGVzY1JlcywgbWVtYmVycy5nZXRNYXJrKCkpKTsKICAgICAgICAgICAgICAgIHJldHVybiBkZXNjUmVzOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgcmV0dXJuIGUuY2FjaGVkRGVzY1JlczsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogQ29tcHV0ZSB0aGUgZnVuY3Rpb24gZGVzY3JpcHRvciBhc3NvY2lhdGVkIHdpdGggYSBnaXZlbiBmdW5jdGlvbmFsIGludGVyZmFjZQogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBGdW5jdGlvbkRlc2NyaXB0b3IgZmluZERlc2NyaXB0b3JJbnRlcm5hbChUeXBlU3ltYm9sIG9yaWdpbiwKICAgICAgICAgICAgICAgIENvbXBvdW5kU2NvcGUgbWVtYmVyc0NhY2hlKSB0aHJvd3MgRnVuY3Rpb25EZXNjcmlwdG9yTG9va3VwRXJyb3IgewogICAgICAgICAgICBpZiAoIW9yaWdpbi5pc0ludGVyZmFjZSgpIHx8IChvcmlnaW4uZmxhZ3MoKSAmIEFOTk9UQVRJT04pICE9IDApIHsKICAgICAgICAgICAgICAgIC8vdCBtdXN0IGJlIGFuIGludGVyZmFjZQogICAgICAgICAgICAgICAgdGhyb3cgZmFpbHVyZSgibm90LmEuZnVuY3Rpb25hbC5pbnRmIiwgb3JpZ2luKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZmluYWwgTGlzdEJ1ZmZlcjxTeW1ib2w+IGFic3RyYWN0cyA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICAgICAgZm9yIChTeW1ib2wgc3ltIDogbWVtYmVyc0NhY2hlLmdldFN5bWJvbHMobmV3IERlc2NyaXB0b3JGaWx0ZXIob3JpZ2luKSkpIHsKICAgICAgICAgICAgICAgIFR5cGUgbXR5cGUgPSBtZW1iZXJUeXBlKG9yaWdpbi50eXBlLCBzeW0pOwogICAgICAgICAgICAgICAgaWYgKGFic3RyYWN0cy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICAgICAgICBhYnN0cmFjdHMuYXBwZW5kKHN5bSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKChzeW0ubmFtZSA9PSBhYnN0cmFjdHMuZmlyc3QoKS5uYW1lICYmCiAgICAgICAgICAgICAgICAgICAgICAgIG92ZXJyaWRlRXF1aXZhbGVudChtdHlwZSwgbWVtYmVyVHlwZShvcmlnaW4udHlwZSwgYWJzdHJhY3RzLmZpcnN0KCkpKSkpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoIWFic3RyYWN0cy5zdHJlYW0oKS5maWx0ZXIobXN5bSAtPiBtc3ltLm93bmVyLmlzU3ViQ2xhc3Moc3ltLmVuY2xDbGFzcygpLCBUeXBlcy50aGlzKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5tYXAobXN5bSAtPiBtZW1iZXJUeXBlKG9yaWdpbi50eXBlLCBtc3ltKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5hbnlNYXRjaChhYnN0cmFjdE1UeXBlIC0+IGlzU3ViU2lnbmF0dXJlKGFic3RyYWN0TVR5cGUsIG10eXBlKSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgYWJzdHJhY3RzLmFwcGVuZChzeW0pOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgLy90aGUgdGFyZ2V0IG1ldGhvZChzKSBzaG91bGQgYmUgdGhlIG9ubHkgYWJzdHJhY3QgbWVtYmVycyBvZiB0CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgZmFpbHVyZSgibm90LmEuZnVuY3Rpb25hbC5pbnRmLjEiLCAgb3JpZ2luLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlhZ3MuZnJhZ21lbnQoImluY29tcGF0aWJsZS5hYnN0cmFjdHMiLCBLaW5kcy5raW5kTmFtZShvcmlnaW4pLCBvcmlnaW4pKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoYWJzdHJhY3RzLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgICAgLy90IG11c3QgZGVmaW5lIGEgc3VpdGFibGUgbm9uLWdlbmVyaWMgbWV0aG9kCiAgICAgICAgICAgICAgICB0aHJvdyBmYWlsdXJlKCJub3QuYS5mdW5jdGlvbmFsLmludGYuMSIsIG9yaWdpbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpYWdzLmZyYWdtZW50KCJuby5hYnN0cmFjdHMiLCBLaW5kcy5raW5kTmFtZShvcmlnaW4pLCBvcmlnaW4pKTsKICAgICAgICAgICAgfSBlbHNlIGlmIChhYnN0cmFjdHMuc2l6ZSgpID09IDEpIHsKICAgICAgICAgICAgICAgIHJldHVybiBuZXcgRnVuY3Rpb25EZXNjcmlwdG9yKGFic3RyYWN0cy5maXJzdCgpKTsKICAgICAgICAgICAgfSBlbHNlIHsgLy8gc2l6ZSA+IDEKICAgICAgICAgICAgICAgIEZ1bmN0aW9uRGVzY3JpcHRvciBkZXNjUmVzID0gbWVyZ2VEZXNjcmlwdG9ycyhvcmlnaW4sIGFic3RyYWN0cy50b0xpc3QoKSk7CiAgICAgICAgICAgICAgICBpZiAoZGVzY1JlcyA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgLy93ZSBjYW4gZ2V0IGhlcmUgaWYgdGhlIGZ1bmN0aW9uYWwgaW50ZXJmYWNlIGlzIGlsbC1mb3JtZWQKICAgICAgICAgICAgICAgICAgICBMaXN0QnVmZmVyPEpDRGlhZ25vc3RpYz4gZGVzY3JpcHRvcnMgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgICAgICAgICAgZm9yIChTeW1ib2wgZGVzYyA6IGFic3RyYWN0cykgewogICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcga2V5ID0gZGVzYy50eXBlLmdldFRocm93blR5cGVzKCkubm9uRW1wdHkoKSA/CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0b3IudGhyb3dzIiA6ICJkZXNjcmlwdG9yIjsKICAgICAgICAgICAgICAgICAgICAgICAgZGVzY3JpcHRvcnMuYXBwZW5kKGRpYWdzLmZyYWdtZW50KGtleSwgZGVzYy5uYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlc2MudHlwZS5nZXRQYXJhbWV0ZXJUeXBlcygpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlc2MudHlwZS5nZXRSZXR1cm5UeXBlKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVzYy50eXBlLmdldFRocm93blR5cGVzKCkpKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgSkNEaWFnbm9zdGljLk11bHRpbGluZURpYWdub3N0aWMgaW5jb21wYXRpYmxlRGVzY3JpcHRvcnMgPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IEpDRGlhZ25vc3RpYy5NdWx0aWxpbmVEaWFnbm9zdGljKGRpYWdzLmZyYWdtZW50KCJpbmNvbXBhdGlibGUuZGVzY3MuaW4uZnVuY3Rpb25hbC5pbnRmIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEtpbmRzLmtpbmROYW1lKG9yaWdpbiksIG9yaWdpbiksIGRlc2NyaXB0b3JzLnRvTGlzdCgpKTsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBmYWlsdXJlKGluY29tcGF0aWJsZURlc2NyaXB0b3JzKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBkZXNjUmVzOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBDb21wdXRlIGEgc3ludGhldGljIHR5cGUgZm9yIHRoZSB0YXJnZXQgZGVzY3JpcHRvciBnaXZlbiBhIGxpc3QKICAgICAgICAgKiBvZiBvdmVycmlkZS1lcXVpdmFsZW50IG1ldGhvZHMgaW4gdGhlIGZ1bmN0aW9uYWwgaW50ZXJmYWNlIHR5cGUuCiAgICAgICAgICogVGhlIHJlc3VsdGluZyBtZXRob2QgdHlwZSBpcyBhIG1ldGhvZCB0eXBlIHRoYXQgaXMgb3ZlcnJpZGUtZXF1aXZhbGVudAogICAgICAgICAqIGFuZCByZXR1cm4tdHlwZSBzdWJzdGl0dXRhYmxlIHdpdGggZWFjaCBtZXRob2QgaW4gdGhlIG9yaWdpbmFsIGxpc3QuCiAgICAgICAgICovCiAgICAgICAgcHJpdmF0ZSBGdW5jdGlvbkRlc2NyaXB0b3IgbWVyZ2VEZXNjcmlwdG9ycyhUeXBlU3ltYm9sIG9yaWdpbiwgTGlzdDxTeW1ib2w+IG1ldGhvZFN5bXMpIHsKICAgICAgICAgICAgcmV0dXJuIG1lcmdlQWJzdHJhY3RzKG1ldGhvZFN5bXMsIG9yaWdpbi50eXBlLCBmYWxzZSkKICAgICAgICAgICAgICAgICAgICAubWFwKGJlc3RTb0ZhciAtPiBuZXcgRnVuY3Rpb25EZXNjcmlwdG9yKGJlc3RTb0Zhci5iYXNlU3ltYm9sKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgICAgICAgICAgICAgIHB1YmxpYyBUeXBlIGdldFR5cGUoVHlwZSBvcmlnaW4pIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFR5cGUgbXQgPSBtZW1iZXJUeXBlKG9yaWdpbiwgZ2V0U3ltYm9sKCkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZU1ldGhvZFR5cGVXaXRoVGhyb3duKG10LCBiZXN0U29GYXIudHlwZS5nZXRUaHJvd25UeXBlcygpKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0pLm9yRWxzZShudWxsKTsKICAgICAgICB9CgogICAgICAgIEZ1bmN0aW9uRGVzY3JpcHRvckxvb2t1cEVycm9yIGZhaWx1cmUoU3RyaW5nIG1zZywgT2JqZWN0Li4uIGFyZ3MpIHsKICAgICAgICAgICAgcmV0dXJuIGZhaWx1cmUoZGlhZ3MuZnJhZ21lbnQobXNnLCBhcmdzKSk7CiAgICAgICAgfQoKICAgICAgICBGdW5jdGlvbkRlc2NyaXB0b3JMb29rdXBFcnJvciBmYWlsdXJlKEpDRGlhZ25vc3RpYyBkaWFnKSB7CiAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbkRlc2NyaXB0b3JMb29rdXBFcnJvci5zZXRNZXNzYWdlKGRpYWcpOwogICAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIERlc2NyaXB0b3JDYWNoZSBkZXNjQ2FjaGUgPSBuZXcgRGVzY3JpcHRvckNhY2hlKCk7CgogICAgLyoqCiAgICAgKiBGaW5kIHRoZSBtZXRob2QgZGVzY3JpcHRvciBhc3NvY2lhdGVkIHRvIHRoaXMgY2xhc3Mgc3ltYm9sIC0gaWYgdGhlCiAgICAgKiBzeW1ib2wgJ29yaWdpbicgaXMgbm90IGEgZnVuY3Rpb25hbCBpbnRlcmZhY2UsIGFuIGV4Y2VwdGlvbiBpcyB0aHJvd24uCiAgICAgKi8KICAgIHB1YmxpYyBTeW1ib2wgZmluZERlc2NyaXB0b3JTeW1ib2woVHlwZVN5bWJvbCBvcmlnaW4pIHRocm93cyBGdW5jdGlvbkRlc2NyaXB0b3JMb29rdXBFcnJvciB7CiAgICAgICAgcmV0dXJuIGRlc2NDYWNoZS5nZXQob3JpZ2luKS5nZXRTeW1ib2woKTsKICAgIH0KCiAgICAvKioKICAgICAqIEZpbmQgdGhlIHR5cGUgb2YgdGhlIG1ldGhvZCBkZXNjcmlwdG9yIGFzc29jaWF0ZWQgdG8gdGhpcyBjbGFzcyBzeW1ib2wgLQogICAgICogaWYgdGhlIHN5bWJvbCAnb3JpZ2luJyBpcyBub3QgYSBmdW5jdGlvbmFsIGludGVyZmFjZSwgYW4gZXhjZXB0aW9uIGlzIHRocm93bi4KICAgICAqLwogICAgcHVibGljIFR5cGUgZmluZERlc2NyaXB0b3JUeXBlKFR5cGUgb3JpZ2luKSB0aHJvd3MgRnVuY3Rpb25EZXNjcmlwdG9yTG9va3VwRXJyb3IgewogICAgICAgIHJldHVybiBkZXNjQ2FjaGUuZ2V0KG9yaWdpbi50c3ltKS5nZXRUeXBlKG9yaWdpbik7CiAgICB9CgogICAgLyoqCiAgICAgKiBJcyBnaXZlbiB0eXBlIGEgZnVuY3Rpb25hbCBpbnRlcmZhY2U/CiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGlzRnVuY3Rpb25hbEludGVyZmFjZShUeXBlU3ltYm9sIHRzeW0pIHsKICAgICAgICB0cnkgewogICAgICAgICAgICBmaW5kRGVzY3JpcHRvclN5bWJvbCh0c3ltKTsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfSBjYXRjaCAoRnVuY3Rpb25EZXNjcmlwdG9yTG9va3VwRXJyb3IgZXgpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgYm9vbGVhbiBpc0Z1bmN0aW9uYWxJbnRlcmZhY2UoVHlwZSBzaXRlKSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgZmluZERlc2NyaXB0b3JUeXBlKHNpdGUpOwogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9IGNhdGNoIChGdW5jdGlvbkRlc2NyaXB0b3JMb29rdXBFcnJvciBleCkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBUeXBlIHJlbW92ZVdpbGRjYXJkcyhUeXBlIHNpdGUpIHsKICAgICAgICBpZiAoc2l0ZS5nZXRUeXBlQXJndW1lbnRzKCkuc3RyZWFtKCkuYW55TWF0Y2godCAtPiB0Lmhhc1RhZyhXSUxEQ0FSRCkpKSB7CiAgICAgICAgICAgIC8vY29tcHV0ZSBub24td2lsZGNhcmQgcGFyYW1ldGVyaXphdGlvbiAtIEpMUyA5LjkKICAgICAgICAgICAgTGlzdDxUeXBlPiBhY3R1YWxzID0gc2l0ZS5nZXRUeXBlQXJndW1lbnRzKCk7CiAgICAgICAgICAgIExpc3Q8VHlwZT4gZm9ybWFscyA9IHNpdGUudHN5bS50eXBlLmdldFR5cGVBcmd1bWVudHMoKTsKICAgICAgICAgICAgTGlzdEJ1ZmZlcjxUeXBlPiB0YXJncyA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICAgICAgZm9yIChUeXBlIGZvcm1hbCA6IGZvcm1hbHMpIHsKICAgICAgICAgICAgICAgIFR5cGUgYWN0dWFsID0gYWN0dWFscy5oZWFkOwogICAgICAgICAgICAgICAgVHlwZSBib3VuZCA9IGZvcm1hbC5nZXRVcHBlckJvdW5kKCk7CiAgICAgICAgICAgICAgICBpZiAoYWN0dWFscy5oZWFkLmhhc1RhZyhXSUxEQ0FSRCkpIHsKICAgICAgICAgICAgICAgICAgICBXaWxkY2FyZFR5cGUgd3QgPSAoV2lsZGNhcmRUeXBlKWFjdHVhbDsKICAgICAgICAgICAgICAgICAgICAvL2NoZWNrIHRoYXQgYm91bmQgZG9lcyBub3QgY29udGFpbiBvdGhlciBmb3JtYWxzCiAgICAgICAgICAgICAgICAgICAgaWYgKGJvdW5kLmNvbnRhaW5zQW55KGZvcm1hbHMpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdzLmFkZCh3dC50eXBlKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAvL2NvbXB1dGUgbmV3IHR5cGUtYXJndW1lbnQgYmFzZWQgb24gZGVjbGFyZWQgYm91bmQgYW5kIHdpbGRjYXJkIGJvdW5kCiAgICAgICAgICAgICAgICAgICAgICAgIHN3aXRjaCAod3Qua2luZCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBVTkJPVU5EOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdzLmFkZChib3VuZCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIEVYVEVORFM6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ3MuYWRkKGdsYihib3VuZCwgd3QudHlwZSkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBTVVBFUjoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXJncy5hZGQod3QudHlwZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFzc2VydC5lcnJvcigiQ2Fubm90IGdldCBoZXJlISIpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAvL25vdCBhIHdpbGRjYXJkIC0gdGhlIG5ldyB0eXBlIGFyZ3VtZW50IHJlbWFpbnMgdW5jaGFuZ2VkCiAgICAgICAgICAgICAgICAgICAgdGFyZ3MuYWRkKGFjdHVhbCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBhY3R1YWxzID0gYWN0dWFscy50YWlsOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBzdWJzdChzaXRlLnRzeW0udHlwZSwgZm9ybWFscywgdGFyZ3MudG9MaXN0KCkpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiBzaXRlOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIENyZWF0ZSBhIHN5bWJvbCBmb3IgYSBjbGFzcyB0aGF0IGltcGxlbWVudHMgYSBnaXZlbiBmdW5jdGlvbmFsIGludGVyZmFjZQogICAgICogYW5kIG92ZXJyaWRlcyBpdHMgZnVuY3Rpb25hbCBkZXNjcmlwdG9yLiBUaGlzIHJvdXRpbmUgaXMgdXNlZCBmb3IgdHdvCiAgICAgKiBtYWluIHB1cnBvc2VzOiAoaSkgY2hlY2tpbmcgd2VsbC1mb3JtZWRuZXNzIG9mIGEgZnVuY3Rpb25hbCBpbnRlcmZhY2U7CiAgICAgKiAoaWkpIHBlcmZvcm0gZnVuY3Rpb25hbCBpbnRlcmZhY2UgYnJpZGdlIGNhbGN1bGF0aW9uLgogICAgICovCiAgICBwdWJsaWMgQ2xhc3NTeW1ib2wgbWFrZUZ1bmN0aW9uYWxJbnRlcmZhY2VDbGFzcyhFbnY8QXR0ckNvbnRleHQ+IGVudiwgTmFtZSBuYW1lLCBMaXN0PFR5cGU+IHRhcmdldHMsIGxvbmcgY2ZsYWdzKSB7CiAgICAgICAgaWYgKHRhcmdldHMuaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgICBTeW1ib2wgZGVzY1N5bSA9IGZpbmREZXNjcmlwdG9yU3ltYm9sKHRhcmdldHMuaGVhZC50c3ltKTsKICAgICAgICBUeXBlIGRlc2NUeXBlID0gZmluZERlc2NyaXB0b3JUeXBlKHRhcmdldHMuaGVhZCk7CiAgICAgICAgQ2xhc3NTeW1ib2wgY3N5bSA9IG5ldyBDbGFzc1N5bWJvbChjZmxhZ3MsIG5hbWUsIGVudi5lbmNsQ2xhc3Muc3ltLm91dGVybW9zdENsYXNzKCkpOwogICAgICAgIGNzeW0uY29tcGxldGVyID0gQ29tcGxldGVyLk5VTExfQ09NUExFVEVSOwogICAgICAgIGNzeW0ubWVtYmVyc19maWVsZCA9IFdyaXRlYWJsZVNjb3BlLmNyZWF0ZShjc3ltKTsKICAgICAgICBNZXRob2RTeW1ib2wgaW5zdERlc2NTeW0gPSBuZXcgTWV0aG9kU3ltYm9sKGRlc2NTeW0uZmxhZ3MoKSwgZGVzY1N5bS5uYW1lLCBkZXNjVHlwZSwgY3N5bSk7CiAgICAgICAgY3N5bS5tZW1iZXJzX2ZpZWxkLmVudGVyKGluc3REZXNjU3ltKTsKICAgICAgICBUeXBlLkNsYXNzVHlwZSBjdHlwZSA9IG5ldyBUeXBlLkNsYXNzVHlwZShUeXBlLm5vVHlwZSwgTGlzdC5uaWwoKSwgY3N5bSk7CiAgICAgICAgY3R5cGUuc3VwZXJ0eXBlX2ZpZWxkID0gc3ltcy5vYmplY3RUeXBlOwogICAgICAgIGN0eXBlLmludGVyZmFjZXNfZmllbGQgPSB0YXJnZXRzOwogICAgICAgIGNzeW0udHlwZSA9IGN0eXBlOwogICAgICAgIGNzeW0uc291cmNlZmlsZSA9ICgoQ2xhc3NTeW1ib2wpY3N5bS5vd25lcikuc291cmNlZmlsZTsKICAgICAgICByZXR1cm4gY3N5bTsKICAgIH0KCiAgICAvKioKICAgICAqIEZpbmQgdGhlIG1pbmltYWwgc2V0IG9mIG1ldGhvZHMgdGhhdCBhcmUgb3ZlcnJpZGRlbiBieSB0aGUgZnVuY3Rpb25hbAogICAgICogZGVzY3JpcHRvciBpbiAnb3JpZ2luJy4gQWxsIHJldHVybmVkIG1ldGhvZHMgYXJlIGFzc3VtZWQgdG8gaGF2ZSBkaWZmZXJlbnQKICAgICAqIGVyYXNlZCBzaWduYXR1cmVzLgogICAgICovCiAgICBwdWJsaWMgTGlzdDxTeW1ib2w+IGZ1bmN0aW9uYWxJbnRlcmZhY2VCcmlkZ2VzKFR5cGVTeW1ib2wgb3JpZ2luKSB7CiAgICAgICAgQXNzZXJ0LmNoZWNrKGlzRnVuY3Rpb25hbEludGVyZmFjZShvcmlnaW4pKTsKICAgICAgICBTeW1ib2wgZGVzY1N5bSA9IGZpbmREZXNjcmlwdG9yU3ltYm9sKG9yaWdpbik7CiAgICAgICAgQ29tcG91bmRTY29wZSBtZW1iZXJzID0gbWVtYmVyc0Nsb3N1cmUob3JpZ2luLnR5cGUsIGZhbHNlKTsKICAgICAgICBMaXN0QnVmZmVyPFN5bWJvbD4gb3ZlcnJpZGRlbiA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICBvdXRlcjogZm9yIChTeW1ib2wgbTIgOiBtZW1iZXJzLmdldFN5bWJvbHNCeU5hbWUoZGVzY1N5bS5uYW1lLCBicmlkZ2VGaWx0ZXIpKSB7CiAgICAgICAgICAgIGlmIChtMiA9PSBkZXNjU3ltKSBjb250aW51ZTsKICAgICAgICAgICAgZWxzZSBpZiAoZGVzY1N5bS5vdmVycmlkZXMobTIsIG9yaWdpbiwgVHlwZXMudGhpcywgZmFsc2UpKSB7CiAgICAgICAgICAgICAgICBmb3IgKFN5bWJvbCBtMyA6IG92ZXJyaWRkZW4pIHsKICAgICAgICAgICAgICAgICAgICBpZiAoaXNTYW1lVHlwZShtMy5lcmFzdXJlKFR5cGVzLnRoaXMpLCBtMi5lcmFzdXJlKFR5cGVzLnRoaXMpKSB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKG0zLm92ZXJyaWRlcyhtMiwgb3JpZ2luLCBUeXBlcy50aGlzLCBmYWxzZSkgJiYKICAgICAgICAgICAgICAgICAgICAgICAgICAgIChwZW5kaW5nQnJpZGdlcygoQ2xhc3NTeW1ib2wpb3JpZ2luLCBtMy5lbmNsQ2xhc3MoKSkgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoKE1ldGhvZFN5bWJvbCltMikuYmluYXJ5SW1wbGVtZW50YXRpb24oKENsYXNzU3ltYm9sKW0zLm93bmVyLCBUeXBlcy50aGlzKSAhPSBudWxsKSkpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlIG91dGVyOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIG92ZXJyaWRkZW4uYWRkKG0yKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gb3ZlcnJpZGRlbi50b0xpc3QoKTsKICAgIH0KICAgIC8vd2hlcmUKICAgICAgICBwcml2YXRlIEZpbHRlcjxTeW1ib2w+IGJyaWRnZUZpbHRlciA9IG5ldyBGaWx0ZXI8U3ltYm9sPigpIHsKICAgICAgICAgICAgcHVibGljIGJvb2xlYW4gYWNjZXB0cyhTeW1ib2wgdCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHQua2luZCA9PSBNVEggJiYKICAgICAgICAgICAgICAgICAgICAgICAgdC5uYW1lICE9IG5hbWVzLmluaXQgJiYKICAgICAgICAgICAgICAgICAgICAgICAgdC5uYW1lICE9IG5hbWVzLmNsaW5pdCAmJgogICAgICAgICAgICAgICAgICAgICAgICAodC5mbGFncygpICYgU1lOVEhFVElDKSA9PSAwOwogICAgICAgICAgICB9CiAgICAgICAgfTsKICAgICAgICBwcml2YXRlIGJvb2xlYW4gcGVuZGluZ0JyaWRnZXMoQ2xhc3NTeW1ib2wgb3JpZ2luLCBUeXBlU3ltYm9sIHMpIHsKICAgICAgICAgICAgLy9hIHN5bWJvbCB3aWxsIGJlIGNvbXBsZXRlZCBmcm9tIGEgY2xhc3NmaWxlIGlmIChhKSBzeW1ib2wgaGFzCiAgICAgICAgICAgIC8vYW4gYXNzb2NpYXRlZCBmaWxlIG9iamVjdCB3aXRoIENMQVNTIGtpbmQgYW5kIChiKSB0aGUgc3ltYm9sIGhhcwogICAgICAgICAgICAvL25vdCBiZWVuIGVudGVyZWQKICAgICAgICAgICAgaWYgKG9yaWdpbi5jbGFzc2ZpbGUgIT0gbnVsbCAmJgogICAgICAgICAgICAgICAgICAgIG9yaWdpbi5jbGFzc2ZpbGUuZ2V0S2luZCgpID09IEphdmFGaWxlT2JqZWN0LktpbmQuQ0xBU1MgJiYKICAgICAgICAgICAgICAgICAgICBlbnRlci5nZXRFbnYob3JpZ2luKSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKG9yaWdpbiA9PSBzKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBmb3IgKFR5cGUgdCA6IGludGVyZmFjZXMob3JpZ2luLnR5cGUpKSB7CiAgICAgICAgICAgICAgICBpZiAocGVuZGluZ0JyaWRnZXMoKENsYXNzU3ltYm9sKXQudHN5bSwgcykpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgLy8gPC9lZGl0b3ItZm9sZD4KCiAgIC8qKgogICAgKiBTY29wZSBmaWx0ZXIgdXNlZCB0byBza2lwIG1ldGhvZHMgdGhhdCBzaG91bGQgYmUgaWdub3JlZCAoc3VjaCBhcyBtZXRob2RzCiAgICAqIG92ZXJyaWRkZW4gYnkgai5sLk9iamVjdCkgZHVyaW5nIGZ1bmN0aW9uIGludGVyZmFjZSBjb252ZXJzaW9uIGludGVyZmFjZSBjaGVjawogICAgKi8KICAgIGNsYXNzIERlc2NyaXB0b3JGaWx0ZXIgaW1wbGVtZW50cyBGaWx0ZXI8U3ltYm9sPiB7CgogICAgICAgVHlwZVN5bWJvbCBvcmlnaW47CgogICAgICAgRGVzY3JpcHRvckZpbHRlcihUeXBlU3ltYm9sIG9yaWdpbikgewogICAgICAgICAgIHRoaXMub3JpZ2luID0gb3JpZ2luOwogICAgICAgfQoKICAgICAgIEBPdmVycmlkZQogICAgICAgcHVibGljIGJvb2xlYW4gYWNjZXB0cyhTeW1ib2wgc3ltKSB7CiAgICAgICAgICAgcmV0dXJuIHN5bS5raW5kID09IE1USCAmJgogICAgICAgICAgICAgICAgICAgKHN5bS5mbGFncygpICYgKEFCU1RSQUNUIHwgREVGQVVMVCkpID09IEFCU1RSQUNUICYmCiAgICAgICAgICAgICAgICAgICAhb3ZlcnJpZGVzT2JqZWN0TWV0aG9kKG9yaWdpbiwgc3ltKSAmJgogICAgICAgICAgICAgICAgICAgKGludGVyZmFjZUNhbmRpZGF0ZXMob3JpZ2luLnR5cGUsIChNZXRob2RTeW1ib2wpc3ltKS5oZWFkLmZsYWdzKCkgJiBERUZBVUxUKSA9PSAwOwogICAgICAgfQogICAgfQoKICAgIC8vIDxlZGl0b3ItZm9sZCBkZWZhdWx0c3RhdGU9ImNvbGxhcHNlZCIgZGVzYz0iaXNTdWJ0eXBlIj4KICAgIC8qKgogICAgICogSXMgdCBhbiB1bmNoZWNrZWQgc3VidHlwZSBvZiBzPwogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBpc1N1YnR5cGVVbmNoZWNrZWQoVHlwZSB0LCBUeXBlIHMpIHsKICAgICAgICByZXR1cm4gaXNTdWJ0eXBlVW5jaGVja2VkKHQsIHMsIG5vV2FybmluZ3MpOwogICAgfQogICAgLyoqCiAgICAgKiBJcyB0IGFuIHVuY2hlY2tlZCBzdWJ0eXBlIG9mIHM/CiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGlzU3VidHlwZVVuY2hlY2tlZChUeXBlIHQsIFR5cGUgcywgV2FybmVyIHdhcm4pIHsKICAgICAgICBib29sZWFuIHJlc3VsdCA9IGlzU3VidHlwZVVuY2hlY2tlZEludGVybmFsKHQsIHMsIHRydWUsIHdhcm4pOwogICAgICAgIGlmIChyZXN1bHQpIHsKICAgICAgICAgICAgY2hlY2tVbnNhZmVWYXJhcmdzQ29udmVyc2lvbih0LCBzLCB3YXJuKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KICAgIC8vd2hlcmUKICAgICAgICBwcml2YXRlIGJvb2xlYW4gaXNTdWJ0eXBlVW5jaGVja2VkSW50ZXJuYWwoVHlwZSB0LCBUeXBlIHMsIGJvb2xlYW4gY2FwdHVyZSwgV2FybmVyIHdhcm4pIHsKICAgICAgICAgICAgaWYgKHQuaGFzVGFnKEFSUkFZKSAmJiBzLmhhc1RhZyhBUlJBWSkpIHsKICAgICAgICAgICAgICAgIGlmICgoKEFycmF5VHlwZSl0KS5lbGVtdHlwZS5pc1ByaW1pdGl2ZSgpKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGlzU2FtZVR5cGUoZWxlbXR5cGUodCksIGVsZW10eXBlKHMpKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGlzU3VidHlwZVVuY2hlY2tlZEludGVybmFsKGVsZW10eXBlKHQpLCBlbGVtdHlwZShzKSwgZmFsc2UsIHdhcm4pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgaWYgKGlzU3VidHlwZSh0LCBzLCBjYXB0dXJlKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0gZWxzZSBpZiAodC5oYXNUYWcoVFlQRVZBUikpIHsKICAgICAgICAgICAgICAgIHJldHVybiBpc1N1YnR5cGVVbmNoZWNrZWRJbnRlcm5hbCh0LmdldFVwcGVyQm91bmQoKSwgcywgZmFsc2UsIHdhcm4pOwogICAgICAgICAgICB9IGVsc2UgaWYgKCFzLmlzUmF3KCkpIHsKICAgICAgICAgICAgICAgIFR5cGUgdDIgPSBhc1N1cGVyKHQsIHMudHN5bSk7CiAgICAgICAgICAgICAgICBpZiAodDIgIT0gbnVsbCAmJiB0Mi5pc1JhdygpKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGlzUmVpZmlhYmxlKHMpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHdhcm4uc2lsZW50V2FybihMaW50Q2F0ZWdvcnkuVU5DSEVDS0VEKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICB3YXJuLndhcm4oTGludENhdGVnb3J5LlVOQ0hFQ0tFRCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgdm9pZCBjaGVja1Vuc2FmZVZhcmFyZ3NDb252ZXJzaW9uKFR5cGUgdCwgVHlwZSBzLCBXYXJuZXIgd2FybikgewogICAgICAgICAgICBpZiAoIXQuaGFzVGFnKEFSUkFZKSB8fCBpc1JlaWZpYWJsZSh0KSkgewogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CiAgICAgICAgICAgIEFycmF5VHlwZSBmcm9tID0gKEFycmF5VHlwZSl0OwogICAgICAgICAgICBib29sZWFuIHNob3VsZFdhcm4gPSBmYWxzZTsKICAgICAgICAgICAgc3dpdGNoIChzLmdldFRhZygpKSB7CiAgICAgICAgICAgICAgICBjYXNlIEFSUkFZOgogICAgICAgICAgICAgICAgICAgIEFycmF5VHlwZSB0byA9IChBcnJheVR5cGUpczsKICAgICAgICAgICAgICAgICAgICBzaG91bGRXYXJuID0gZnJvbS5pc1ZhcmFyZ3MoKSAmJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgIXRvLmlzVmFyYXJncygpICYmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAhaXNSZWlmaWFibGUoZnJvbSk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIENMQVNTOgogICAgICAgICAgICAgICAgICAgIHNob3VsZFdhcm4gPSBmcm9tLmlzVmFyYXJncygpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChzaG91bGRXYXJuKSB7CiAgICAgICAgICAgICAgICB3YXJuLndhcm4oTGludENhdGVnb3J5LlZBUkFSR1MpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgIC8qKgogICAgICogSXMgdCBhIHN1YnR5cGUgb2Ygcz88YnI+CiAgICAgKiAobm90IGRlZmluZWQgZm9yIE1ldGhvZCBhbmQgRm9yQWxsIHR5cGVzKQogICAgICovCiAgICBmaW5hbCBwdWJsaWMgYm9vbGVhbiBpc1N1YnR5cGUoVHlwZSB0LCBUeXBlIHMpIHsKICAgICAgICByZXR1cm4gaXNTdWJ0eXBlKHQsIHMsIHRydWUpOwogICAgfQogICAgZmluYWwgcHVibGljIGJvb2xlYW4gaXNTdWJ0eXBlTm9DYXB0dXJlKFR5cGUgdCwgVHlwZSBzKSB7CiAgICAgICAgcmV0dXJuIGlzU3VidHlwZSh0LCBzLCBmYWxzZSk7CiAgICB9CiAgICBwdWJsaWMgYm9vbGVhbiBpc1N1YnR5cGUoVHlwZSB0LCBUeXBlIHMsIGJvb2xlYW4gY2FwdHVyZSkgewogICAgICAgIGlmICh0LmVxdWFsc0lnbm9yZU1ldGFkYXRhKHMpKQogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICBpZiAocy5pc1BhcnRpYWwoKSkKICAgICAgICAgICAgcmV0dXJuIGlzU3VwZXJUeXBlKHMsIHQpOwoKICAgICAgICBpZiAocy5pc0NvbXBvdW5kKCkpIHsKICAgICAgICAgICAgZm9yIChUeXBlIHMyIDogaW50ZXJmYWNlcyhzKS5wcmVwZW5kKHN1cGVydHlwZShzKSkpIHsKICAgICAgICAgICAgICAgIGlmICghaXNTdWJ0eXBlKHQsIHMyLCBjYXB0dXJlKSkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICAvLyBHZW5lcmFsbHksIGlmICdzJyBpcyBhIGxvd2VyLWJvdW5kZWQgdHlwZSB2YXJpYWJsZSwgcmVjdXIgb24gbG93ZXIgYm91bmQ7IGJ1dAogICAgICAgIC8vIGZvciBpbmZlcmVuY2UgdmFyaWFibGVzIGFuZCBpbnRlcnNlY3Rpb25zLCB3ZSBuZWVkIHRvIGtlZXAgJ3MnCiAgICAgICAgLy8gKHNlZSBKTFMgNC4xMC4yIGZvciBpbnRlcnNlY3Rpb25zIGFuZCAxOC4yLjMgZm9yIGluZmVyZW5jZSB2YXJzKQogICAgICAgIGlmICghdC5oYXNUYWcoVU5ERVRWQVIpICYmICF0LmlzQ29tcG91bmQoKSkgewogICAgICAgICAgICAvLyBUT0RPOiBKREstODAzOTE5OCwgYm91bmRzIGNoZWNraW5nIHNvbWV0aW1lcyBwYXNzZXMgaW4gYSB3aWxkY2FyZCBhcyBzCiAgICAgICAgICAgIFR5cGUgbG93ZXIgPSBjdmFyTG93ZXJCb3VuZCh3aWxkTG93ZXJCb3VuZChzKSk7CiAgICAgICAgICAgIGlmIChzICE9IGxvd2VyICYmICFsb3dlci5oYXNUYWcoQk9UKSkKICAgICAgICAgICAgICAgIHJldHVybiBpc1N1YnR5cGUoY2FwdHVyZSA/IGNhcHR1cmUodCkgOiB0LCBsb3dlciwgZmFsc2UpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGlzU3VidHlwZS52aXNpdChjYXB0dXJlID8gY2FwdHVyZSh0KSA6IHQsIHMpOwogICAgfQogICAgLy8gd2hlcmUKICAgICAgICBwcml2YXRlIFR5cGVSZWxhdGlvbiBpc1N1YnR5cGUgPSBuZXcgVHlwZVJlbGF0aW9uKCkKICAgICAgICB7CiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgQm9vbGVhbiB2aXNpdFR5cGUoVHlwZSB0LCBUeXBlIHMpIHsKICAgICAgICAgICAgICAgIHN3aXRjaCAodC5nZXRUYWcoKSkgewogICAgICAgICAgICAgICAgIGNhc2UgQllURToKICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICghcy5oYXNUYWcoQ0hBUikgJiYgdC5nZXRUYWcoKS5pc1N1YlJhbmdlT2Yocy5nZXRUYWcoKSkpOwogICAgICAgICAgICAgICAgIGNhc2UgQ0hBUjoKICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICghcy5oYXNUYWcoU0hPUlQpICYmIHQuZ2V0VGFnKCkuaXNTdWJSYW5nZU9mKHMuZ2V0VGFnKCkpKTsKICAgICAgICAgICAgICAgICBjYXNlIFNIT1JUOiBjYXNlIElOVDogY2FzZSBMT05HOgogICAgICAgICAgICAgICAgIGNhc2UgRkxPQVQ6IGNhc2UgRE9VQkxFOgogICAgICAgICAgICAgICAgICAgICByZXR1cm4gdC5nZXRUYWcoKS5pc1N1YlJhbmdlT2Yocy5nZXRUYWcoKSk7CiAgICAgICAgICAgICAgICAgY2FzZSBCT09MRUFOOiBjYXNlIFZPSUQ6CiAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0Lmhhc1RhZyhzLmdldFRhZygpKTsKICAgICAgICAgICAgICAgICBjYXNlIFRZUEVWQVI6CiAgICAgICAgICAgICAgICAgICAgIHJldHVybiBpc1N1YnR5cGVOb0NhcHR1cmUodC5nZXRVcHBlckJvdW5kKCksIHMpOwogICAgICAgICAgICAgICAgIGNhc2UgQk9UOgogICAgICAgICAgICAgICAgICAgICByZXR1cm4KICAgICAgICAgICAgICAgICAgICAgICAgIHMuaGFzVGFnKEJPVCkgfHwgcy5oYXNUYWcoQ0xBU1MpIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICBzLmhhc1RhZyhBUlJBWSkgfHwgcy5oYXNUYWcoVFlQRVZBUik7CiAgICAgICAgICAgICAgICAgY2FzZSBXSUxEQ0FSRDogLy93ZSBzaG91bGRuJ3QgYmUgaGVyZSAtIGF2b2lkcyBjcmFzaCAoc2VlIDcwMzQ0OTUpCiAgICAgICAgICAgICAgICAgY2FzZSBOT05FOgogICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCJpc1N1YnR5cGUgIiArIHQuZ2V0VGFnKCkpOwogICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHJpdmF0ZSBTZXQ8VHlwZVBhaXI+IGNhY2hlID0gbmV3IEhhc2hTZXQ8PigpOwoKICAgICAgICAgICAgcHJpdmF0ZSBib29sZWFuIGNvbnRhaW5zVHlwZVJlY3Vyc2l2ZShUeXBlIHQsIFR5cGUgcykgewogICAgICAgICAgICAgICAgVHlwZVBhaXIgcGFpciA9IG5ldyBUeXBlUGFpcih0LCBzKTsKICAgICAgICAgICAgICAgIGlmIChjYWNoZS5hZGQocGFpcikpIHsKICAgICAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29udGFpbnNUeXBlKHQuZ2V0VHlwZUFyZ3VtZW50cygpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHMuZ2V0VHlwZUFyZ3VtZW50cygpKTsKICAgICAgICAgICAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAgICAgICAgICAgICBjYWNoZS5yZW1vdmUocGFpcik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29udGFpbnNUeXBlKHQuZ2V0VHlwZUFyZ3VtZW50cygpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV3cml0ZVN1cGVycyhzKS5nZXRUeXBlQXJndW1lbnRzKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBwcml2YXRlIFR5cGUgcmV3cml0ZVN1cGVycyhUeXBlIHQpIHsKICAgICAgICAgICAgICAgIGlmICghdC5pc1BhcmFtZXRlcml6ZWQoKSkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdDsKICAgICAgICAgICAgICAgIExpc3RCdWZmZXI8VHlwZT4gZnJvbSA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICAgICAgICAgIExpc3RCdWZmZXI8VHlwZT4gdG8gPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgICAgICBhZGFwdFNlbGYodCwgZnJvbSwgdG8pOwogICAgICAgICAgICAgICAgaWYgKGZyb20uaXNFbXB0eSgpKQogICAgICAgICAgICAgICAgICAgIHJldHVybiB0OwogICAgICAgICAgICAgICAgTGlzdEJ1ZmZlcjxUeXBlPiByZXdyaXRlID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgICAgICAgICAgYm9vbGVhbiBjaGFuZ2VkID0gZmFsc2U7CiAgICAgICAgICAgICAgICBmb3IgKFR5cGUgb3JpZyA6IHRvLnRvTGlzdCgpKSB7CiAgICAgICAgICAgICAgICAgICAgVHlwZSBzID0gcmV3cml0ZVN1cGVycyhvcmlnKTsKICAgICAgICAgICAgICAgICAgICBpZiAocy5pc1N1cGVyQm91bmQoKSAmJiAhcy5pc0V4dGVuZHNCb3VuZCgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHMgPSBuZXcgV2lsZGNhcmRUeXBlKHN5bXMub2JqZWN0VHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQm91bmRLaW5kLlVOQk9VTkQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5bXMuYm91bmRDbGFzcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcy5nZXRNZXRhZGF0YSgpKTsKICAgICAgICAgICAgICAgICAgICAgICAgY2hhbmdlZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChzICE9IG9yaWcpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcyA9IG5ldyBXaWxkY2FyZFR5cGUod2lsZFVwcGVyQm91bmQocyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJvdW5kS2luZC5FWFRFTkRTLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeW1zLmJvdW5kQ2xhc3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHMuZ2V0TWV0YWRhdGEoKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5nZWQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICByZXdyaXRlLmFwcGVuZChzKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChjaGFuZ2VkKQogICAgICAgICAgICAgICAgICAgIHJldHVybiBzdWJzdCh0LnRzeW0udHlwZSwgZnJvbS50b0xpc3QoKSwgcmV3cml0ZS50b0xpc3QoKSk7CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHQ7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgQm9vbGVhbiB2aXNpdENsYXNzVHlwZShDbGFzc1R5cGUgdCwgVHlwZSBzKSB7CiAgICAgICAgICAgICAgICBUeXBlIHN1cCA9IGFzU3VwZXIodCwgcy50c3ltKTsKICAgICAgICAgICAgICAgIGlmIChzdXAgPT0gbnVsbCkgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgLy8gSWYgdCBpcyBhbiBpbnRlcnNlY3Rpb24sIHN1cCBtaWdodCBub3QgYmUgYSBjbGFzcyB0eXBlCiAgICAgICAgICAgICAgICBpZiAoIXN1cC5oYXNUYWcoQ0xBU1MpKSByZXR1cm4gaXNTdWJ0eXBlTm9DYXB0dXJlKHN1cCwgcyk7CiAgICAgICAgICAgICAgICByZXR1cm4gc3VwLnRzeW0gPT0gcy50c3ltCiAgICAgICAgICAgICAgICAgICAgIC8vIENoZWNrIHR5cGUgdmFyaWFibGUgY29udGFpbm1lbnQKICAgICAgICAgICAgICAgICAgICAmJiAoIXMuaXNQYXJhbWV0ZXJpemVkKCkgfHwgY29udGFpbnNUeXBlUmVjdXJzaXZlKHMsIHN1cCkpCiAgICAgICAgICAgICAgICAgICAgJiYgaXNTdWJ0eXBlTm9DYXB0dXJlKHN1cC5nZXRFbmNsb3NpbmdUeXBlKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHMuZ2V0RW5jbG9zaW5nVHlwZSgpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHB1YmxpYyBCb29sZWFuIHZpc2l0QXJyYXlUeXBlKEFycmF5VHlwZSB0LCBUeXBlIHMpIHsKICAgICAgICAgICAgICAgIGlmIChzLmhhc1RhZyhBUlJBWSkpIHsKICAgICAgICAgICAgICAgICAgICBpZiAodC5lbGVtdHlwZS5pc1ByaW1pdGl2ZSgpKQogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaXNTYW1lVHlwZSh0LmVsZW10eXBlLCBlbGVtdHlwZShzKSk7CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaXNTdWJ0eXBlTm9DYXB0dXJlKHQuZWxlbXR5cGUsIGVsZW10eXBlKHMpKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAocy5oYXNUYWcoQ0xBU1MpKSB7CiAgICAgICAgICAgICAgICAgICAgTmFtZSBzbmFtZSA9IHMudHN5bS5nZXRRdWFsaWZpZWROYW1lKCk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHNuYW1lID09IG5hbWVzLmphdmFfbGFuZ19PYmplY3QKICAgICAgICAgICAgICAgICAgICAgICAgfHwgc25hbWUgPT0gbmFtZXMuamF2YV9sYW5nX0Nsb25lYWJsZQogICAgICAgICAgICAgICAgICAgICAgICB8fCBzbmFtZSA9PSBuYW1lcy5qYXZhX2lvX1NlcmlhbGl6YWJsZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgQm9vbGVhbiB2aXNpdFVuZGV0VmFyKFVuZGV0VmFyIHQsIFR5cGUgcykgewogICAgICAgICAgICAgICAgLy90b2RvOiB0ZXN0IGFnYWluc3Qgb3JpZ2luIG5lZWRlZD8gb3IgcmVwbGFjZSB3aXRoIHN1YnN0aXR1dGlvbj8KICAgICAgICAgICAgICAgIGlmICh0ID09IHMgfHwgdC5xdHlwZSA9PSBzIHx8IHMuaGFzVGFnKEVSUk9SKSB8fCBzLmhhc1RhZyhVTktOT1dOKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChzLmhhc1RhZyhCT1QpKSB7CiAgICAgICAgICAgICAgICAgICAgLy9pZiAncycgaXMgJ251bGwnIHRoZXJlJ3Mgbm8gaW5zdGFudGlhdGVkIHR5cGUgVSBmb3Igd2hpY2gKICAgICAgICAgICAgICAgICAgICAvL1UgPDogcyAoYnV0ICdudWxsJyBpdHNlbGYsIHdoaWNoIGlzIG5vdCBhIHZhbGlkIHR5cGUpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHQuYWRkQm91bmQoSW5mZXJlbmNlQm91bmQuVVBQRVIsIHMsIFR5cGVzLnRoaXMpOwogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgQm9vbGVhbiB2aXNpdEVycm9yVHlwZShFcnJvclR5cGUgdCwgVHlwZSBzKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH07CgogICAgLyoqCiAgICAgKiBJcyB0IGEgc3VidHlwZSBvZiBldmVyeSB0eXBlIGluIGdpdmVuIGxpc3QgYHRzJz88YnI+CiAgICAgKiAobm90IGRlZmluZWQgZm9yIE1ldGhvZCBhbmQgRm9yQWxsIHR5cGVzKTxicj4KICAgICAqIEFsbG93cyB1bmNoZWNrZWQgY29udmVyc2lvbnMuCiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGlzU3VidHlwZVVuY2hlY2tlZChUeXBlIHQsIExpc3Q8VHlwZT4gdHMsIFdhcm5lciB3YXJuKSB7CiAgICAgICAgZm9yIChMaXN0PFR5cGU+IGwgPSB0czsgbC5ub25FbXB0eSgpOyBsID0gbC50YWlsKQogICAgICAgICAgICBpZiAoIWlzU3VidHlwZVVuY2hlY2tlZCh0LCBsLmhlYWQsIHdhcm4pKQogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIC8qKgogICAgICogQXJlIGNvcnJlc3BvbmRpbmcgZWxlbWVudHMgb2YgdHMgc3VidHlwZXMgb2Ygc3M/ICBJZiBsaXN0cyBhcmUKICAgICAqIG9mIGRpZmZlcmVudCBsZW5ndGgsIHJldHVybiBmYWxzZS4KICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gaXNTdWJ0eXBlcyhMaXN0PFR5cGU+IHRzLCBMaXN0PFR5cGU+IHNzKSB7CiAgICAgICAgd2hpbGUgKHRzLnRhaWwgIT0gbnVsbCAmJiBzcy50YWlsICE9IG51bGwKICAgICAgICAgICAgICAgLyppbmxpbmVkOiB0cy5ub25FbXB0eSgpICYmIHNzLm5vbkVtcHR5KCkqLyAmJgogICAgICAgICAgICAgICBpc1N1YnR5cGUodHMuaGVhZCwgc3MuaGVhZCkpIHsKICAgICAgICAgICAgdHMgPSB0cy50YWlsOwogICAgICAgICAgICBzcyA9IHNzLnRhaWw7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0cy50YWlsID09IG51bGwgJiYgc3MudGFpbCA9PSBudWxsOwogICAgICAgIC8qaW5saW5lZDogdHMuaXNFbXB0eSgpICYmIHNzLmlzRW1wdHkoKTsqLwogICAgfQoKICAgIC8qKgogICAgICogQXJlIGNvcnJlc3BvbmRpbmcgZWxlbWVudHMgb2YgdHMgc3VidHlwZXMgb2Ygc3MsIGFsbG93aW5nCiAgICAgKiB1bmNoZWNrZWQgY29udmVyc2lvbnM/ICBJZiBsaXN0cyBhcmUgb2YgZGlmZmVyZW50IGxlbmd0aCwKICAgICAqIHJldHVybiBmYWxzZS4KICAgICAqKi8KICAgIHB1YmxpYyBib29sZWFuIGlzU3VidHlwZXNVbmNoZWNrZWQoTGlzdDxUeXBlPiB0cywgTGlzdDxUeXBlPiBzcywgV2FybmVyIHdhcm4pIHsKICAgICAgICB3aGlsZSAodHMudGFpbCAhPSBudWxsICYmIHNzLnRhaWwgIT0gbnVsbAogICAgICAgICAgICAgICAvKmlubGluZWQ6IHRzLm5vbkVtcHR5KCkgJiYgc3Mubm9uRW1wdHkoKSovICYmCiAgICAgICAgICAgICAgIGlzU3VidHlwZVVuY2hlY2tlZCh0cy5oZWFkLCBzcy5oZWFkLCB3YXJuKSkgewogICAgICAgICAgICB0cyA9IHRzLnRhaWw7CiAgICAgICAgICAgIHNzID0gc3MudGFpbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRzLnRhaWwgPT0gbnVsbCAmJiBzcy50YWlsID09IG51bGw7CiAgICAgICAgLyppbmxpbmVkOiB0cy5pc0VtcHR5KCkgJiYgc3MuaXNFbXB0eSgpOyovCiAgICB9CiAgICAvLyA8L2VkaXRvci1mb2xkPgoKICAgIC8vIDxlZGl0b3ItZm9sZCBkZWZhdWx0c3RhdGU9ImNvbGxhcHNlZCIgZGVzYz0iaXNTdXBlclR5cGUiPgogICAgLyoqCiAgICAgKiBJcyB0IGEgc3VwZXJ0eXBlIG9mIHM/CiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGlzU3VwZXJUeXBlKFR5cGUgdCwgVHlwZSBzKSB7CiAgICAgICAgc3dpdGNoICh0LmdldFRhZygpKSB7CiAgICAgICAgY2FzZSBFUlJPUjoKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgY2FzZSBVTkRFVFZBUjogewogICAgICAgICAgICBVbmRldFZhciB1bmRldCA9IChVbmRldFZhcil0OwogICAgICAgICAgICBpZiAodCA9PSBzIHx8CiAgICAgICAgICAgICAgICB1bmRldC5xdHlwZSA9PSBzIHx8CiAgICAgICAgICAgICAgICBzLmhhc1RhZyhFUlJPUikgfHwKICAgICAgICAgICAgICAgIHMuaGFzVGFnKEJPVCkpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHVuZGV0LmFkZEJvdW5kKEluZmVyZW5jZUJvdW5kLkxPV0VSLCBzLCB0aGlzKTsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHJldHVybiBpc1N1YnR5cGUocywgdCk7CiAgICAgICAgfQogICAgfQogICAgLy8gPC9lZGl0b3ItZm9sZD4KCiAgICAvLyA8ZWRpdG9yLWZvbGQgZGVmYXVsdHN0YXRlPSJjb2xsYXBzZWQiIGRlc2M9ImlzU2FtZVR5cGUiPgogICAgLyoqCiAgICAgKiBBcmUgY29ycmVzcG9uZGluZyBlbGVtZW50cyBvZiB0aGUgbGlzdHMgdGhlIHNhbWUgdHlwZT8gIElmCiAgICAgKiBsaXN0cyBhcmUgb2YgZGlmZmVyZW50IGxlbmd0aCwgcmV0dXJuIGZhbHNlLgogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBpc1NhbWVUeXBlcyhMaXN0PFR5cGU+IHRzLCBMaXN0PFR5cGU+IHNzKSB7CiAgICAgICAgcmV0dXJuIGlzU2FtZVR5cGVzKHRzLCBzcywgZmFsc2UpOwogICAgfQogICAgcHVibGljIGJvb2xlYW4gaXNTYW1lVHlwZXMoTGlzdDxUeXBlPiB0cywgTGlzdDxUeXBlPiBzcywgYm9vbGVhbiBzdHJpY3QpIHsKICAgICAgICB3aGlsZSAodHMudGFpbCAhPSBudWxsICYmIHNzLnRhaWwgIT0gbnVsbAogICAgICAgICAgICAgICAvKmlubGluZWQ6IHRzLm5vbkVtcHR5KCkgJiYgc3Mubm9uRW1wdHkoKSovICYmCiAgICAgICAgICAgICAgIGlzU2FtZVR5cGUodHMuaGVhZCwgc3MuaGVhZCwgc3RyaWN0KSkgewogICAgICAgICAgICB0cyA9IHRzLnRhaWw7CiAgICAgICAgICAgIHNzID0gc3MudGFpbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRzLnRhaWwgPT0gbnVsbCAmJiBzcy50YWlsID09IG51bGw7CiAgICAgICAgLyppbmxpbmVkOiB0cy5pc0VtcHR5KCkgJiYgc3MuaXNFbXB0eSgpOyovCiAgICB9CgogICAgLyoqCiAgICAgKiBBIHBvbHltb3JwaGljIHNpZ25hdHVyZSBtZXRob2QgKEpMUyAxNS4xMi4zKSBpcyBhIG1ldGhvZCB0aGF0CiAgICAgKiAgIChpKSBpcyBkZWNsYXJlZCBpbiB0aGUgamF2YS5sYW5nLmludm9rZS5NZXRob2RIYW5kbGUvVmFySGFuZGxlIGNsYXNzZXM7CiAgICAgKiAgKGlpKSB0YWtlcyBhIHNpbmdsZSB2YXJpYWJsZSBhcml0eSBwYXJhbWV0ZXI7CiAgICAgKiAoaWlpKSB3aG9zZSBkZWNsYXJlZCB0eXBlIGlzIE9iamVjdFtdOwogICAgICogIChpdikgaGFzIGFueSByZXR1cm4gdHlwZSwgT2JqZWN0IHNpZ25pZnlpbmcgYSBwb2x5bW9ycGhpYyByZXR1cm4gdHlwZTsgYW5kCiAgICAgKiAgICh2KSBpcyBuYXRpdmUuCiAgICAqLwogICBwdWJsaWMgYm9vbGVhbiBpc1NpZ25hdHVyZVBvbHltb3JwaGljKE1ldGhvZFN5bWJvbCBtc3ltKSB7CiAgICAgICBMaXN0PFR5cGU+IGFyZ3R5cGVzID0gbXN5bS50eXBlLmdldFBhcmFtZXRlclR5cGVzKCk7CiAgICAgICByZXR1cm4gKG1zeW0uZmxhZ3NfZmllbGQgJiBOQVRJVkUpICE9IDAgJiYKICAgICAgICAgICAgICAobXN5bS5vd25lciA9PSBzeW1zLm1ldGhvZEhhbmRsZVR5cGUudHN5bSB8fCBtc3ltLm93bmVyID09IHN5bXMudmFySGFuZGxlVHlwZS50c3ltKSAmJgogICAgICAgICAgICAgICBhcmd0eXBlcy5sZW5ndGgoKSA9PSAxICYmCiAgICAgICAgICAgICAgIGFyZ3R5cGVzLmhlYWQuaGFzVGFnKFR5cGVUYWcuQVJSQVkpICYmCiAgICAgICAgICAgICAgICgoQXJyYXlUeXBlKWFyZ3R5cGVzLmhlYWQpLmVsZW10eXBlLnRzeW0gPT0gc3ltcy5vYmplY3RUeXBlLnRzeW07CiAgIH0KCiAgICAvKioKICAgICAqIElzIHQgdGhlIHNhbWUgdHlwZSBhcyBzPwogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBpc1NhbWVUeXBlKFR5cGUgdCwgVHlwZSBzKSB7CiAgICAgICAgcmV0dXJuIGlzU2FtZVR5cGUodCwgcywgZmFsc2UpOwogICAgfQogICAgcHVibGljIGJvb2xlYW4gaXNTYW1lVHlwZShUeXBlIHQsIFR5cGUgcywgYm9vbGVhbiBzdHJpY3QpIHsKICAgICAgICByZXR1cm4gc3RyaWN0ID8KICAgICAgICAgICAgICAgIGlzU2FtZVR5cGVTdHJpY3QudmlzaXQodCwgcykgOgogICAgICAgICAgICAgICAgaXNTYW1lVHlwZUxvb3NlLnZpc2l0KHQsIHMpOwogICAgfQogICAgLy8gd2hlcmUKICAgICAgICBhYnN0cmFjdCBjbGFzcyBTYW1lVHlwZVZpc2l0b3IgZXh0ZW5kcyBUeXBlUmVsYXRpb24gewoKICAgICAgICAgICAgcHVibGljIEJvb2xlYW4gdmlzaXRUeXBlKFR5cGUgdCwgVHlwZSBzKSB7CiAgICAgICAgICAgICAgICBpZiAodC5lcXVhbHNJZ25vcmVNZXRhZGF0YShzKSkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKCiAgICAgICAgICAgICAgICBpZiAocy5pc1BhcnRpYWwoKSkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdmlzaXQocywgdCk7CgogICAgICAgICAgICAgICAgc3dpdGNoICh0LmdldFRhZygpKSB7CiAgICAgICAgICAgICAgICBjYXNlIEJZVEU6IGNhc2UgQ0hBUjogY2FzZSBTSE9SVDogY2FzZSBJTlQ6IGNhc2UgTE9ORzogY2FzZSBGTE9BVDoKICAgICAgICAgICAgICAgIGNhc2UgRE9VQkxFOiBjYXNlIEJPT0xFQU46IGNhc2UgVk9JRDogY2FzZSBCT1Q6IGNhc2UgTk9ORToKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdC5oYXNUYWcocy5nZXRUYWcoKSk7CiAgICAgICAgICAgICAgICBjYXNlIFRZUEVWQVI6IHsKICAgICAgICAgICAgICAgICAgICBpZiAocy5oYXNUYWcoVFlQRVZBUikpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy90eXBlLXN1YnN0aXR1dGlvbiBkb2VzIG5vdCBwcmVzZXJ2ZSB0eXBlLXZhciB0eXBlcwogICAgICAgICAgICAgICAgICAgICAgICAvL2NoZWNrIHRoYXQgdHlwZSB2YXIgc3ltYm9scyBhbmQgYm91bmRzIGFyZSBpbmRlZWQgdGhlIHNhbWUKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHNhbWVUeXBlVmFycygoVHlwZVZhcil0LCAoVHlwZVZhcilzKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vc3BlY2lhbCBjYXNlIGZvciBzID09ID8gc3VwZXIgWCwgd2hlcmUgdXBwZXIocykgPSB1CiAgICAgICAgICAgICAgICAgICAgICAgIC8vY2hlY2sgdGhhdCB1ID09IHQsIHdoZXJlIHUgaGFzIGJlZW4gc2V0IGJ5IFR5cGUud2l0aFR5cGVWYXIKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHMuaXNTdXBlckJvdW5kKCkgJiYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAhcy5pc0V4dGVuZHNCb3VuZCgpICYmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlzaXQodCwgd2lsZFVwcGVyQm91bmQocykpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCJpc1NhbWVUeXBlICIgKyB0LmdldFRhZygpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgYWJzdHJhY3QgYm9vbGVhbiBzYW1lVHlwZVZhcnMoVHlwZVZhciB0djEsIFR5cGVWYXIgdHYyKTsKCiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgQm9vbGVhbiB2aXNpdFdpbGRjYXJkVHlwZShXaWxkY2FyZFR5cGUgdCwgVHlwZSBzKSB7CiAgICAgICAgICAgICAgICBpZiAoIXMuaGFzVGFnKFdJTERDQVJEKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgV2lsZGNhcmRUeXBlIHQyID0gKFdpbGRjYXJkVHlwZSlzOwogICAgICAgICAgICAgICAgICAgIHJldHVybiAodC5raW5kID09IHQyLmtpbmQgfHwgKHQuaXNFeHRlbmRzQm91bmQoKSAmJiBzLmlzRXh0ZW5kc0JvdW5kKCkpKSAmJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNTYW1lVHlwZSh0LnR5cGUsIHQyLnR5cGUsIHRydWUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHVibGljIEJvb2xlYW4gdmlzaXRDbGFzc1R5cGUoQ2xhc3NUeXBlIHQsIFR5cGUgcykgewogICAgICAgICAgICAgICAgaWYgKHQgPT0gcykKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKCiAgICAgICAgICAgICAgICBpZiAocy5pc1BhcnRpYWwoKSkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdmlzaXQocywgdCk7CgogICAgICAgICAgICAgICAgaWYgKHMuaXNTdXBlckJvdW5kKCkgJiYgIXMuaXNFeHRlbmRzQm91bmQoKSkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdmlzaXQodCwgd2lsZFVwcGVyQm91bmQocykpICYmIHZpc2l0KHQsIHdpbGRMb3dlckJvdW5kKHMpKTsKCiAgICAgICAgICAgICAgICBpZiAodC5pc0NvbXBvdW5kKCkgJiYgcy5pc0NvbXBvdW5kKCkpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoIXZpc2l0KHN1cGVydHlwZSh0KSwgc3VwZXJ0eXBlKHMpKSkKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwoKICAgICAgICAgICAgICAgICAgICBNYXA8U3ltYm9sLFR5cGU+IHRNYXAgPSBuZXcgSGFzaE1hcDw+KCk7CiAgICAgICAgICAgICAgICAgICAgZm9yIChUeXBlIHRpIDogaW50ZXJmYWNlcyh0KSkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAodE1hcC5jb250YWluc0tleSh0aSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigiTWFsZm9ybWVkIGludGVyc2VjdGlvbiIpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIHRNYXAucHV0KHRpLnRzeW0sIHRpKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZm9yIChUeXBlIHNpIDogaW50ZXJmYWNlcyhzKSkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXRNYXAuY29udGFpbnNLZXkoc2kudHN5bSkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgICAgIFR5cGUgdGkgPSB0TWFwLnJlbW92ZShzaS50c3ltKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCF2aXNpdCh0aSwgc2kpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICByZXR1cm4gdE1hcC5pc0VtcHR5KCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gdC50c3ltID09IHMudHN5bQogICAgICAgICAgICAgICAgICAgICYmIHZpc2l0KHQuZ2V0RW5jbG9zaW5nVHlwZSgpLCBzLmdldEVuY2xvc2luZ1R5cGUoKSkKICAgICAgICAgICAgICAgICAgICAmJiBjb250YWluc1R5cGVzKHQuZ2V0VHlwZUFyZ3VtZW50cygpLCBzLmdldFR5cGVBcmd1bWVudHMoKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGFic3RyYWN0IHByb3RlY3RlZCBib29sZWFuIGNvbnRhaW5zVHlwZXMoTGlzdDxUeXBlPiB0czEsIExpc3Q8VHlwZT4gdHMyKTsKCiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgQm9vbGVhbiB2aXNpdEFycmF5VHlwZShBcnJheVR5cGUgdCwgVHlwZSBzKSB7CiAgICAgICAgICAgICAgICBpZiAodCA9PSBzKQogICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwoKICAgICAgICAgICAgICAgIGlmIChzLmlzUGFydGlhbCgpKQogICAgICAgICAgICAgICAgICAgIHJldHVybiB2aXNpdChzLCB0KTsKCiAgICAgICAgICAgICAgICByZXR1cm4gcy5oYXNUYWcoQVJSQVkpCiAgICAgICAgICAgICAgICAgICAgJiYgY29udGFpbnNUeXBlRXF1aXZhbGVudCh0LmVsZW10eXBlLCBlbGVtdHlwZShzKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgQm9vbGVhbiB2aXNpdE1ldGhvZFR5cGUoTWV0aG9kVHlwZSB0LCBUeXBlIHMpIHsKICAgICAgICAgICAgICAgIC8vIGlzU2FtZVR5cGUgZm9yIG1ldGhvZHMgZG9lcyBub3QgdGFrZSB0aHJvd24KICAgICAgICAgICAgICAgIC8vIGV4Y2VwdGlvbnMgaW50byBhY2NvdW50IQogICAgICAgICAgICAgICAgcmV0dXJuIGhhc1NhbWVBcmdzKHQsIHMpICYmIHZpc2l0KHQuZ2V0UmV0dXJuVHlwZSgpLCBzLmdldFJldHVyblR5cGUoKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgQm9vbGVhbiB2aXNpdFBhY2thZ2VUeXBlKFBhY2thZ2VUeXBlIHQsIFR5cGUgcykgewogICAgICAgICAgICAgICAgcmV0dXJuIHQgPT0gczsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHB1YmxpYyBCb29sZWFuIHZpc2l0Rm9yQWxsKEZvckFsbCB0LCBUeXBlIHMpIHsKICAgICAgICAgICAgICAgIGlmICghcy5oYXNUYWcoRk9SQUxMKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBGb3JBbGwgZm9yQWxsID0gKEZvckFsbClzOwogICAgICAgICAgICAgICAgcmV0dXJuIGhhc1NhbWVCb3VuZHModCwgZm9yQWxsKQogICAgICAgICAgICAgICAgICAgICYmIHZpc2l0KHQucXR5cGUsIHN1YnN0KGZvckFsbC5xdHlwZSwgZm9yQWxsLnR2YXJzLCB0LnR2YXJzKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgQm9vbGVhbiB2aXNpdFVuZGV0VmFyKFVuZGV0VmFyIHQsIFR5cGUgcykgewogICAgICAgICAgICAgICAgaWYgKHMuaGFzVGFnKFdJTERDQVJEKSkgewogICAgICAgICAgICAgICAgICAgIC8vIEZJWE1FLCB0aGlzIG1pZ2h0IGJlIGxlZnRvdmVycyBmcm9tIGJlZm9yZSBjYXB0dXJlIGNvbnZlcnNpb24KICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKHQgPT0gcyB8fCB0LnF0eXBlID09IHMgfHwgcy5oYXNUYWcoRVJST1IpIHx8IHMuaGFzVGFnKFVOS05PV04pKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgdC5hZGRCb3VuZChJbmZlcmVuY2VCb3VuZC5FUSwgcywgVHlwZXMudGhpcyk7CgogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgQm9vbGVhbiB2aXNpdEVycm9yVHlwZShFcnJvclR5cGUgdCwgVHlwZSBzKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogU3RhbmRhcmQgdHlwZS1lcXVhbGl0eSByZWxhdGlvbiAtIHR5cGUgdmFyaWFibGVzIGFyZSBjb25zaWRlcmVkCiAgICAgICAgICogZXF1YWxzIGlmIHRoZXkgc2hhcmUgdGhlIHNhbWUgdHlwZSBzeW1ib2wuCiAgICAgICAgICovCiAgICAgICAgVHlwZVJlbGF0aW9uIGlzU2FtZVR5cGVMb29zZSA9IG5ldyBMb29zZVNhbWVUeXBlVmlzaXRvcigpOwoKICAgICAgICBwcml2YXRlIGNsYXNzIExvb3NlU2FtZVR5cGVWaXNpdG9yIGV4dGVuZHMgU2FtZVR5cGVWaXNpdG9yIHsKCiAgICAgICAgICAgIC8qKiBjYWNoZSBvZiB0aGUgdHlwZS12YXJpYWJsZSBwYWlycyBiZWluZyAocmVjdXJzaXZlbHkpIHRlc3RlZC4gKi8KICAgICAgICAgICAgcHJpdmF0ZSBTZXQ8VHlwZVBhaXI+IGNhY2hlID0gbmV3IEhhc2hTZXQ8PigpOwoKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIGJvb2xlYW4gc2FtZVR5cGVWYXJzKFR5cGVWYXIgdHYxLCBUeXBlVmFyIHR2MikgewogICAgICAgICAgICAgICAgcmV0dXJuIHR2MS50c3ltID09IHR2Mi50c3ltICYmIGNoZWNrU2FtZUJvdW5kcyh0djEsIHR2Mik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHByb3RlY3RlZCBib29sZWFuIGNvbnRhaW5zVHlwZXMoTGlzdDxUeXBlPiB0czEsIExpc3Q8VHlwZT4gdHMyKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gY29udGFpbnNUeXBlRXF1aXZhbGVudCh0czEsIHRzMik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBTaW5jZSB0eXBlLXZhcmlhYmxlIGJvdW5kcyBjYW4gYmUgcmVjdXJzaXZlLCB3ZSBuZWVkIHRvIHByb3RlY3QgYWdhaW5zdAogICAgICAgICAgICAgKiBpbmZpbml0ZSBsb29wcyAtIHdoZXJlIHRoZSBzYW1lIGJvdW5kcyBhcmUgY2hlY2tlZCBvdmVyIGFuZCBvdmVyIHJlY3Vyc2l2ZWx5LgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgcHJpdmF0ZSBib29sZWFuIGNoZWNrU2FtZUJvdW5kcyhUeXBlVmFyIHR2MSwgVHlwZVZhciB0djIpIHsKICAgICAgICAgICAgICAgIFR5cGVQYWlyIHAgPSBuZXcgVHlwZVBhaXIodHYxLCB0djIsIHRydWUpOwogICAgICAgICAgICAgICAgaWYgKGNhY2hlLmFkZChwKSkgewogICAgICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB2aXNpdCh0djEuZ2V0VXBwZXJCb3VuZCgpLCB0djIuZ2V0VXBwZXJCb3VuZCgpKTsKICAgICAgICAgICAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAgICAgICAgICAgICBjYWNoZS5yZW1vdmUocCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKiBTdHJpY3QgdHlwZS1lcXVhbGl0eSByZWxhdGlvbiAtIHR5cGUgdmFyaWFibGVzIGFyZSBjb25zaWRlcmVkCiAgICAgICAgICogZXF1YWxzIGlmIHRoZXkgc2hhcmUgdGhlIHNhbWUgb2JqZWN0IGlkZW50aXR5LgogICAgICAgICAqLwogICAgICAgIFR5cGVSZWxhdGlvbiBpc1NhbWVUeXBlU3RyaWN0ID0gbmV3IFNhbWVUeXBlVmlzaXRvcigpIHsKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIGJvb2xlYW4gc2FtZVR5cGVWYXJzKFR5cGVWYXIgdHYxLCBUeXBlVmFyIHR2MikgewogICAgICAgICAgICAgICAgcmV0dXJuIHR2MSA9PSB0djI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHByb3RlY3RlZCBib29sZWFuIGNvbnRhaW5zVHlwZXMoTGlzdDxUeXBlPiB0czEsIExpc3Q8VHlwZT4gdHMyKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gaXNTYW1lVHlwZXModHMxLCB0czIsIHRydWUpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHVibGljIEJvb2xlYW4gdmlzaXRXaWxkY2FyZFR5cGUoV2lsZGNhcmRUeXBlIHQsIFR5cGUgcykgewogICAgICAgICAgICAgICAgaWYgKCFzLmhhc1RhZyhXSUxEQ0FSRCkpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIFdpbGRjYXJkVHlwZSB0MiA9IChXaWxkY2FyZFR5cGUpczsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdC5raW5kID09IHQyLmtpbmQgJiYKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzU2FtZVR5cGUodC50eXBlLCB0Mi50eXBlLCB0cnVlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH07CgogICAgLy8gPC9lZGl0b3ItZm9sZD4KCiAgICAvLyA8ZWRpdG9yLWZvbGQgZGVmYXVsdHN0YXRlPSJjb2xsYXBzZWQiIGRlc2M9IkNvbnRhaW5zIFR5cGUiPgogICAgcHVibGljIGJvb2xlYW4gY29udGFpbmVkQnkoVHlwZSB0LCBUeXBlIHMpIHsKICAgICAgICBzd2l0Y2ggKHQuZ2V0VGFnKCkpIHsKICAgICAgICBjYXNlIFVOREVUVkFSOgogICAgICAgICAgICBpZiAocy5oYXNUYWcoV0lMRENBUkQpKSB7CiAgICAgICAgICAgICAgICBVbmRldFZhciB1bmRldHZhciA9IChVbmRldFZhcil0OwogICAgICAgICAgICAgICAgV2lsZGNhcmRUeXBlIHd0ID0gKFdpbGRjYXJkVHlwZSlzOwogICAgICAgICAgICAgICAgc3dpdGNoKHd0LmtpbmQpIHsKICAgICAgICAgICAgICAgICAgICBjYXNlIFVOQk9VTkQ6CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgRVhURU5EUzogewogICAgICAgICAgICAgICAgICAgICAgICBUeXBlIGJvdW5kID0gd2lsZFVwcGVyQm91bmQocyk7CiAgICAgICAgICAgICAgICAgICAgICAgIHVuZGV0dmFyLmFkZEJvdW5kKEluZmVyZW5jZUJvdW5kLlVQUEVSLCBib3VuZCwgdGhpcyk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBjYXNlIFNVUEVSOiB7CiAgICAgICAgICAgICAgICAgICAgICAgIFR5cGUgYm91bmQgPSB3aWxkTG93ZXJCb3VuZChzKTsKICAgICAgICAgICAgICAgICAgICAgICAgdW5kZXR2YXIuYWRkQm91bmQoSW5mZXJlbmNlQm91bmQuTE9XRVIsIGJvdW5kLCB0aGlzKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICByZXR1cm4gaXNTYW1lVHlwZSh0LCBzKTsKICAgICAgICAgICAgfQogICAgICAgIGNhc2UgRVJST1I6CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHJldHVybiBjb250YWluc1R5cGUocywgdCk7CiAgICAgICAgfQogICAgfQoKICAgIGJvb2xlYW4gY29udGFpbnNUeXBlKExpc3Q8VHlwZT4gdHMsIExpc3Q8VHlwZT4gc3MpIHsKICAgICAgICB3aGlsZSAodHMubm9uRW1wdHkoKSAmJiBzcy5ub25FbXB0eSgpCiAgICAgICAgICAgICAgICYmIGNvbnRhaW5zVHlwZSh0cy5oZWFkLCBzcy5oZWFkKSkgewogICAgICAgICAgICB0cyA9IHRzLnRhaWw7CiAgICAgICAgICAgIHNzID0gc3MudGFpbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRzLmlzRW1wdHkoKSAmJiBzcy5pc0VtcHR5KCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDaGVjayBpZiB0IGNvbnRhaW5zIHMuCiAgICAgKgogICAgICogPHA+VCBjb250YWlucyBTIGlmOgogICAgICoKICAgICAqIDxwPntAY29kZSBMKFQpIDw6IEwoUykgJiYgVShTKSA8OiBVKFQpfQogICAgICoKICAgICAqIDxwPlRoaXMgcmVsYXRpb24gaXMgb25seSB1c2VkIGJ5IENsYXNzVHlwZS5pc1N1YnR5cGUoKSwgdGhhdAogICAgICogaXMsCiAgICAgKgogICAgICogPHA+e0Bjb2RlIEM8Uz4gPDogQzxUPiBpZiBUIGNvbnRhaW5zIFMufQogICAgICoKICAgICAqIDxwPkJlY2F1c2Ugb2YgRi1ib3VuZHMsIHRoaXMgcmVsYXRpb24gY2FuIGxlYWQgdG8gaW5maW5pdGUKICAgICAqIHJlY3Vyc2lvbi4gIFRodXMgd2UgbXVzdCBzb21laG93IGJyZWFrIHRoYXQgcmVjdXJzaW9uLiAgTm90aWNlCiAgICAgKiB0aGF0IGNvbnRhaW5zVHlwZSgpIGlzIG9ubHkgY2FsbGVkIGZyb20gQ2xhc3NUeXBlLmlzU3VidHlwZSgpLgogICAgICogU2luY2UgdGhlIGFyZ3VtZW50cyBoYXZlIGFscmVhZHkgYmVlbiBjaGVja2VkIGFnYWluc3QgdGhlaXIKICAgICAqIGJvdW5kcywgd2Uga25vdzoKICAgICAqCiAgICAgKiA8cD57QGNvZGUgVShTKSA8OiBVKFQpIGlmIFQgaXMgInN1cGVyIiBib3VuZCAoVShUKSAqaXMqIHRoZSBib3VuZCl9CiAgICAgKgogICAgICogPHA+e0Bjb2RlIEwoVCkgPDogTChTKSBpZiBUIGlzICJleHRlbmRzIiBib3VuZCAoTChUKSBpcyBib3R0b20pfQogICAgICoKICAgICAqIEBwYXJhbSB0IGEgdHlwZQogICAgICogQHBhcmFtIHMgYSB0eXBlCiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zVHlwZShUeXBlIHQsIFR5cGUgcykgewogICAgICAgIHJldHVybiBjb250YWluc1R5cGUudmlzaXQodCwgcyk7CiAgICB9CiAgICAvLyB3aGVyZQogICAgICAgIHByaXZhdGUgVHlwZVJlbGF0aW9uIGNvbnRhaW5zVHlwZSA9IG5ldyBUeXBlUmVsYXRpb24oKSB7CgogICAgICAgICAgICBwdWJsaWMgQm9vbGVhbiB2aXNpdFR5cGUoVHlwZSB0LCBUeXBlIHMpIHsKICAgICAgICAgICAgICAgIGlmIChzLmlzUGFydGlhbCgpKQogICAgICAgICAgICAgICAgICAgIHJldHVybiBjb250YWluZWRCeShzLCB0KTsKICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICByZXR1cm4gaXNTYW1lVHlwZSh0LCBzKTsKICAgICAgICAgICAgfQoKLy8gICAgICAgICAgICB2b2lkIGRlYnVnQ29udGFpbnNUeXBlKFdpbGRjYXJkVHlwZSB0LCBUeXBlIHMpIHsKLy8gICAgICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKCk7Ci8vICAgICAgICAgICAgICAgIFN5c3RlbS5lcnIuZm9ybWF0KCIgZG9lcyAlcyBjb250YWluICVzPyVuIiwgdCwgcyk7Ci8vICAgICAgICAgICAgICAgIFN5c3RlbS5lcnIuZm9ybWF0KCIgJXMgVSglcykgPDogVSglcykgJXMgPSAlcyVuIiwKLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lsZFVwcGVyQm91bmQocyksIHMsIHQsIHdpbGRVcHBlckJvdW5kKHQpLAovLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0LmlzU3VwZXJCb3VuZCgpCi8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8IGlzU3VidHlwZU5vQ2FwdHVyZSh3aWxkVXBwZXJCb3VuZChzKSwgd2lsZFVwcGVyQm91bmQodCkpKTsKLy8gICAgICAgICAgICAgICAgU3lzdGVtLmVyci5mb3JtYXQoIiAlcyBMKCVzKSA8OiBMKCVzKSAlcyA9ICVzJW4iLAovLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aWxkTG93ZXJCb3VuZCh0KSwgdCwgcywgd2lsZExvd2VyQm91bmQocyksCi8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHQuaXNFeHRlbmRzQm91bmQoKQovLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8fCBpc1N1YnR5cGVOb0NhcHR1cmUod2lsZExvd2VyQm91bmQodCksIHdpbGRMb3dlckJvdW5kKHMpKSk7Ci8vICAgICAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigpOwovLyAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgQm9vbGVhbiB2aXNpdFdpbGRjYXJkVHlwZShXaWxkY2FyZFR5cGUgdCwgVHlwZSBzKSB7CiAgICAgICAgICAgICAgICBpZiAocy5pc1BhcnRpYWwoKSkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29udGFpbmVkQnkocywgdCk7CiAgICAgICAgICAgICAgICBlbHNlIHsKLy8gICAgICAgICAgICAgICAgICAgIGRlYnVnQ29udGFpbnNUeXBlKHQsIHMpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBpc1NhbWVXaWxkY2FyZCh0LCBzKQogICAgICAgICAgICAgICAgICAgICAgICB8fCBpc0NhcHR1cmVPZihzLCB0KQogICAgICAgICAgICAgICAgICAgICAgICB8fCAoKHQuaXNFeHRlbmRzQm91bmQoKSB8fCBpc1N1YnR5cGVOb0NhcHR1cmUod2lsZExvd2VyQm91bmQodCksIHdpbGRMb3dlckJvdW5kKHMpKSkgJiYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICh0LmlzU3VwZXJCb3VuZCgpIHx8IGlzU3VidHlwZU5vQ2FwdHVyZSh3aWxkVXBwZXJCb3VuZChzKSwgd2lsZFVwcGVyQm91bmQodCkpKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgQm9vbGVhbiB2aXNpdFVuZGV0VmFyKFVuZGV0VmFyIHQsIFR5cGUgcykgewogICAgICAgICAgICAgICAgaWYgKCFzLmhhc1RhZyhXSUxEQ0FSRCkpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gaXNTYW1lVHlwZSh0LCBzKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHVibGljIEJvb2xlYW4gdmlzaXRFcnJvclR5cGUoRXJyb3JUeXBlIHQsIFR5cGUgcykgewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9OwoKICAgIHB1YmxpYyBib29sZWFuIGlzQ2FwdHVyZU9mKFR5cGUgcywgV2lsZGNhcmRUeXBlIHQpIHsKICAgICAgICBpZiAoIXMuaGFzVGFnKFRZUEVWQVIpIHx8ICEoKFR5cGVWYXIpcykuaXNDYXB0dXJlZCgpKQogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgcmV0dXJuIGlzU2FtZVdpbGRjYXJkKHQsICgoQ2FwdHVyZWRUeXBlKXMpLndpbGRjYXJkKTsKICAgIH0KCiAgICBwdWJsaWMgYm9vbGVhbiBpc1NhbWVXaWxkY2FyZChXaWxkY2FyZFR5cGUgdCwgVHlwZSBzKSB7CiAgICAgICAgaWYgKCFzLmhhc1RhZyhXSUxEQ0FSRCkpCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICBXaWxkY2FyZFR5cGUgdyA9IChXaWxkY2FyZFR5cGUpczsKICAgICAgICByZXR1cm4gdy5raW5kID09IHQua2luZCAmJiB3LnR5cGUgPT0gdC50eXBlOwogICAgfQoKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zVHlwZUVxdWl2YWxlbnQoTGlzdDxUeXBlPiB0cywgTGlzdDxUeXBlPiBzcykgewogICAgICAgIHdoaWxlICh0cy5ub25FbXB0eSgpICYmIHNzLm5vbkVtcHR5KCkKICAgICAgICAgICAgICAgJiYgY29udGFpbnNUeXBlRXF1aXZhbGVudCh0cy5oZWFkLCBzcy5oZWFkKSkgewogICAgICAgICAgICB0cyA9IHRzLnRhaWw7CiAgICAgICAgICAgIHNzID0gc3MudGFpbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRzLmlzRW1wdHkoKSAmJiBzcy5pc0VtcHR5KCk7CiAgICB9CiAgICAvLyA8L2VkaXRvci1mb2xkPgoKICAgIC8vIDxlZGl0b3ItZm9sZCBkZWZhdWx0c3RhdGU9ImNvbGxhcHNlZCIgZGVzYz0iaXNDYXN0YWJsZSI+CiAgICBwdWJsaWMgYm9vbGVhbiBpc0Nhc3RhYmxlKFR5cGUgdCwgVHlwZSBzKSB7CiAgICAgICAgcmV0dXJuIGlzQ2FzdGFibGUodCwgcywgbm9XYXJuaW5ncyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBJcyB0IGlzIGNhc3RhYmxlIHRvIHM/PGJyPgogICAgICogcyBpcyBhc3N1bWVkIHRvIGJlIGFuIGVyYXNlZCB0eXBlLjxicj4KICAgICAqIChub3QgZGVmaW5lZCBmb3IgTWV0aG9kIGFuZCBGb3JBbGwgdHlwZXMpLgogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBpc0Nhc3RhYmxlKFR5cGUgdCwgVHlwZSBzLCBXYXJuZXIgd2FybikgewogICAgICAgIGlmICh0ID09IHMpCiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIGlmICh0LmlzUHJpbWl0aXZlKCkgIT0gcy5pc1ByaW1pdGl2ZSgpKSB7CiAgICAgICAgICAgIHQgPSBza2lwVHlwZVZhcnModCwgZmFsc2UpOwogICAgICAgICAgICByZXR1cm4gKGlzQ29udmVydGlibGUodCwgcywgd2FybikKICAgICAgICAgICAgICAgICAgICB8fCAoYWxsb3dPYmplY3RUb1ByaW1pdGl2ZUNhc3QgJiYKICAgICAgICAgICAgICAgICAgICAgICAgcy5pc1ByaW1pdGl2ZSgpICYmCiAgICAgICAgICAgICAgICAgICAgICAgIGlzU3VidHlwZShib3hlZENsYXNzKHMpLnR5cGUsIHQpKSk7CiAgICAgICAgfQogICAgICAgIGlmICh3YXJuICE9IHdhcm5TdGFjay5oZWFkKSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICB3YXJuU3RhY2sgPSB3YXJuU3RhY2sucHJlcGVuZCh3YXJuKTsKICAgICAgICAgICAgICAgIGNoZWNrVW5zYWZlVmFyYXJnc0NvbnZlcnNpb24odCwgcywgd2Fybik7CiAgICAgICAgICAgICAgICByZXR1cm4gaXNDYXN0YWJsZS52aXNpdCh0LHMpOwogICAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAgICAgd2FyblN0YWNrID0gd2FyblN0YWNrLnRhaWw7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gaXNDYXN0YWJsZS52aXNpdCh0LHMpOwogICAgICAgIH0KICAgIH0KICAgIC8vIHdoZXJlCiAgICAgICAgcHJpdmF0ZSBUeXBlUmVsYXRpb24gaXNDYXN0YWJsZSA9IG5ldyBUeXBlUmVsYXRpb24oKSB7CgogICAgICAgICAgICBwdWJsaWMgQm9vbGVhbiB2aXNpdFR5cGUoVHlwZSB0LCBUeXBlIHMpIHsKICAgICAgICAgICAgICAgIGlmIChzLmhhc1RhZyhFUlJPUikpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CgogICAgICAgICAgICAgICAgc3dpdGNoICh0LmdldFRhZygpKSB7CiAgICAgICAgICAgICAgICBjYXNlIEJZVEU6IGNhc2UgQ0hBUjogY2FzZSBTSE9SVDogY2FzZSBJTlQ6IGNhc2UgTE9ORzogY2FzZSBGTE9BVDoKICAgICAgICAgICAgICAgIGNhc2UgRE9VQkxFOgogICAgICAgICAgICAgICAgICAgIHJldHVybiBzLmlzTnVtZXJpYygpOwogICAgICAgICAgICAgICAgY2FzZSBCT09MRUFOOgogICAgICAgICAgICAgICAgICAgIHJldHVybiBzLmhhc1RhZyhCT09MRUFOKTsKICAgICAgICAgICAgICAgIGNhc2UgVk9JRDoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICBjYXNlIEJPVDoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gaXNTdWJ0eXBlKHQsIHMpOwogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHB1YmxpYyBCb29sZWFuIHZpc2l0V2lsZGNhcmRUeXBlKFdpbGRjYXJkVHlwZSB0LCBUeXBlIHMpIHsKICAgICAgICAgICAgICAgIHJldHVybiBpc0Nhc3RhYmxlKHdpbGRVcHBlckJvdW5kKHQpLCBzLCB3YXJuU3RhY2suaGVhZCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgQm9vbGVhbiB2aXNpdENsYXNzVHlwZShDbGFzc1R5cGUgdCwgVHlwZSBzKSB7CiAgICAgICAgICAgICAgICBpZiAocy5oYXNUYWcoRVJST1IpIHx8IHMuaGFzVGFnKEJPVCkpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CgogICAgICAgICAgICAgICAgaWYgKHMuaGFzVGFnKFRZUEVWQVIpKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGlzQ2FzdGFibGUodCwgcy5nZXRVcHBlckJvdW5kKCksIG5vV2FybmluZ3MpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHdhcm5TdGFjay5oZWFkLndhcm4oTGludENhdGVnb3J5LlVOQ0hFQ0tFRCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKHQuaXNDb21wb3VuZCgpIHx8IHMuaXNDb21wb3VuZCgpKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICF0LmlzQ29tcG91bmQoKSA/CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aXNpdENvbXBvdW5kVHlwZSgoQ2xhc3NUeXBlKXMsIHQsIHRydWUpIDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpc2l0Q29tcG91bmRUeXBlKHQsIHMsIGZhbHNlKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAocy5oYXNUYWcoQ0xBU1MpIHx8IHMuaGFzVGFnKEFSUkFZKSkgewogICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gdXBjYXN0OwogICAgICAgICAgICAgICAgICAgIGlmICgodXBjYXN0ID0gaXNTdWJ0eXBlKGVyYXN1cmUodCksIGVyYXN1cmUocykpKQogICAgICAgICAgICAgICAgICAgICAgICB8fCBpc1N1YnR5cGUoZXJhc3VyZShzKSwgZXJhc3VyZSh0KSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCF1cGNhc3QgJiYgcy5oYXNUYWcoQVJSQVkpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWlzUmVpZmlhYmxlKHMpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdhcm5TdGFjay5oZWFkLndhcm4oTGludENhdGVnb3J5LlVOQ0hFQ0tFRCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChzLmlzUmF3KCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHQuaXNSYXcoKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFpc1VuYm91bmRlZChzKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3YXJuU3RhY2suaGVhZC53YXJuKExpbnRDYXRlZ29yeS5VTkNIRUNLRUQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgLy8gQXNzdW1lIHxhfCA8OiB8YnwKICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgVHlwZSBhID0gdXBjYXN0ID8gdCA6IHM7CiAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIFR5cGUgYiA9IHVwY2FzdCA/IHMgOiB0OwogICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBib29sZWFuIEhJR0ggPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBib29sZWFuIExPVyA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBib29sZWFuIERPTlRfUkVXUklURV9UWVBFVkFSUyA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgICAgICBUeXBlIGFIaWdoID0gcmV3cml0ZVF1YW50aWZpZXJzKGEsIEhJR0gsIERPTlRfUkVXUklURV9UWVBFVkFSUyk7CiAgICAgICAgICAgICAgICAgICAgICAgIFR5cGUgYUxvdyAgPSByZXdyaXRlUXVhbnRpZmllcnMoYSwgTE9XLCAgRE9OVF9SRVdSSVRFX1RZUEVWQVJTKTsKICAgICAgICAgICAgICAgICAgICAgICAgVHlwZSBiSGlnaCA9IHJld3JpdGVRdWFudGlmaWVycyhiLCBISUdILCBET05UX1JFV1JJVEVfVFlQRVZBUlMpOwogICAgICAgICAgICAgICAgICAgICAgICBUeXBlIGJMb3cgID0gcmV3cml0ZVF1YW50aWZpZXJzKGIsIExPVywgIERPTlRfUkVXUklURV9UWVBFVkFSUyk7CiAgICAgICAgICAgICAgICAgICAgICAgIFR5cGUgbG93U3ViID0gYXNTdWIoYkxvdywgYUxvdy50c3ltKTsKICAgICAgICAgICAgICAgICAgICAgICAgVHlwZSBoaWdoU3ViID0gKGxvd1N1YiA9PSBudWxsKSA/IG51bGwgOiBhc1N1YihiSGlnaCwgYUhpZ2gudHN5bSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChoaWdoU3ViID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGJvb2xlYW4gUkVXUklURV9UWVBFVkFSUyA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhSGlnaCA9IHJld3JpdGVRdWFudGlmaWVycyhhLCBISUdILCBSRVdSSVRFX1RZUEVWQVJTKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFMb3cgID0gcmV3cml0ZVF1YW50aWZpZXJzKGEsIExPVywgIFJFV1JJVEVfVFlQRVZBUlMpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYkhpZ2ggPSByZXdyaXRlUXVhbnRpZmllcnMoYiwgSElHSCwgUkVXUklURV9UWVBFVkFSUyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBiTG93ICA9IHJld3JpdGVRdWFudGlmaWVycyhiLCBMT1csICBSRVdSSVRFX1RZUEVWQVJTKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvd1N1YiA9IGFzU3ViKGJMb3csIGFMb3cudHN5bSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBoaWdoU3ViID0gKGxvd1N1YiA9PSBudWxsKSA/IG51bGwgOiBhc1N1YihiSGlnaCwgYUhpZ2gudHN5bSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGhpZ2hTdWIgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEoYS50c3ltID09IGhpZ2hTdWIudHN5bSAmJiBhLnRzeW0gPT0gbG93U3ViLnRzeW0pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXNzZXJ0LmVycm9yKGEudHN5bSArICIgIT0gIiArIGhpZ2hTdWIudHN5bSArICIgIT0gIiArIGxvd1N1Yi50c3ltKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghZGlzam9pbnRUeXBlcyhhSGlnaC5hbGxwYXJhbXMoKSwgaGlnaFN1Yi5hbGxwYXJhbXMoKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiAhZGlzam9pbnRUeXBlcyhhSGlnaC5hbGxwYXJhbXMoKSwgbG93U3ViLmFsbHBhcmFtcygpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICYmICFkaXNqb2ludFR5cGVzKGFMb3cuYWxscGFyYW1zKCksIGhpZ2hTdWIuYWxscGFyYW1zKCkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgIWRpc2pvaW50VHlwZXMoYUxvdy5hbGxwYXJhbXMoKSwgbG93U3ViLmFsbHBhcmFtcygpKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh1cGNhc3QgPyBnaXZlV2FybmluZyhhLCBiKSA6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdpdmVXYXJuaW5nKGIsIGEpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3YXJuU3RhY2suaGVhZC53YXJuKExpbnRDYXRlZ29yeS5VTkNIRUNLRUQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc1JlaWZpYWJsZShzKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBpc1N1YnR5cGVVbmNoZWNrZWQoYSwgYik7CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBpc1N1YnR5cGVVbmNoZWNrZWQoYSwgYiwgd2FyblN0YWNrLmhlYWQpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gU2lkZWNhc3QKICAgICAgICAgICAgICAgICAgICBpZiAocy5oYXNUYWcoQ0xBU1MpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgocy50c3ltLmZsYWdzKCkgJiBJTlRFUkZBQ0UpICE9IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAoKHQudHN5bS5mbGFncygpICYgRklOQUwpID09IDApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBzaWRlQ2FzdCh0LCBzLCB3YXJuU3RhY2suaGVhZCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IHNpZGVDYXN0RmluYWwodCwgcywgd2FyblN0YWNrLmhlYWQpOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCh0LnRzeW0uZmxhZ3MoKSAmIElOVEVSRkFDRSkgIT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICgocy50c3ltLmZsYWdzKCkgJiBGSU5BTCkgPT0gMCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IHNpZGVDYXN0KHQsIHMsIHdhcm5TdGFjay5oZWFkKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogc2lkZUNhc3RGaW5hbCh0LCBzLCB3YXJuU3RhY2suaGVhZCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB1bnJlbGF0ZWQgY2xhc3MgdHlwZXMKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgYm9vbGVhbiB2aXNpdENvbXBvdW5kVHlwZShDbGFzc1R5cGUgY3QsIFR5cGUgcywgYm9vbGVhbiByZXZlcnNlKSB7CiAgICAgICAgICAgICAgICBXYXJuZXIgd2FybiA9IG5vV2FybmluZ3M7CiAgICAgICAgICAgICAgICBmb3IgKFR5cGUgYyA6IGRpcmVjdFN1cGVydHlwZXMoY3QpKSB7CiAgICAgICAgICAgICAgICAgICAgd2Fybi5jbGVhcigpOwogICAgICAgICAgICAgICAgICAgIGlmIChyZXZlcnNlID8gIWlzQ2FzdGFibGUocywgYywgd2FybikgOiAhaXNDYXN0YWJsZShjLCBzLCB3YXJuKSkKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKHdhcm4uaGFzTGludChMaW50Q2F0ZWdvcnkuVU5DSEVDS0VEKSkKICAgICAgICAgICAgICAgICAgICB3YXJuU3RhY2suaGVhZC53YXJuKExpbnRDYXRlZ29yeS5VTkNIRUNLRUQpOwogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgQm9vbGVhbiB2aXNpdEFycmF5VHlwZShBcnJheVR5cGUgdCwgVHlwZSBzKSB7CiAgICAgICAgICAgICAgICBzd2l0Y2ggKHMuZ2V0VGFnKCkpIHsKICAgICAgICAgICAgICAgIGNhc2UgRVJST1I6CiAgICAgICAgICAgICAgICBjYXNlIEJPVDoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgIGNhc2UgVFlQRVZBUjoKICAgICAgICAgICAgICAgICAgICBpZiAoaXNDYXN0YWJsZShzLCB0LCBub1dhcm5pbmdzKSkgewogICAgICAgICAgICAgICAgICAgICAgICB3YXJuU3RhY2suaGVhZC53YXJuKExpbnRDYXRlZ29yeS5VTkNIRUNLRUQpOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgY2FzZSBDTEFTUzoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gaXNTdWJ0eXBlKHQsIHMpOwogICAgICAgICAgICAgICAgY2FzZSBBUlJBWToKICAgICAgICAgICAgICAgICAgICBpZiAoZWxlbXR5cGUodCkuaXNQcmltaXRpdmUoKSB8fCBlbGVtdHlwZShzKS5pc1ByaW1pdGl2ZSgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBlbGVtdHlwZSh0KS5oYXNUYWcoZWxlbXR5cGUocykuZ2V0VGFnKCkpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB2aXNpdChlbGVtdHlwZSh0KSwgZWxlbXR5cGUocykpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHVibGljIEJvb2xlYW4gdmlzaXRUeXBlVmFyKFR5cGVWYXIgdCwgVHlwZSBzKSB7CiAgICAgICAgICAgICAgICBzd2l0Y2ggKHMuZ2V0VGFnKCkpIHsKICAgICAgICAgICAgICAgIGNhc2UgRVJST1I6CiAgICAgICAgICAgICAgICBjYXNlIEJPVDoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgIGNhc2UgVFlQRVZBUjoKICAgICAgICAgICAgICAgICAgICBpZiAoaXNTdWJ0eXBlKHQsIHMpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNDYXN0YWJsZSh0LmJvdW5kLCBzLCBub1dhcm5pbmdzKSkgewogICAgICAgICAgICAgICAgICAgICAgICB3YXJuU3RhY2suaGVhZC53YXJuKExpbnRDYXRlZ29yeS5VTkNIRUNLRUQpOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gaXNDYXN0YWJsZSh0LmJvdW5kLCBzLCB3YXJuU3RhY2suaGVhZCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgQm9vbGVhbiB2aXNpdEVycm9yVHlwZShFcnJvclR5cGUgdCwgVHlwZSBzKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH07CiAgICAvLyA8L2VkaXRvci1mb2xkPgoKICAgIC8vIDxlZGl0b3ItZm9sZCBkZWZhdWx0c3RhdGU9ImNvbGxhcHNlZCIgZGVzYz0iZGlzam9pbnRUeXBlcyI+CiAgICBwdWJsaWMgYm9vbGVhbiBkaXNqb2ludFR5cGVzKExpc3Q8VHlwZT4gdHMsIExpc3Q8VHlwZT4gc3MpIHsKICAgICAgICB3aGlsZSAodHMudGFpbCAhPSBudWxsICYmIHNzLnRhaWwgIT0gbnVsbCkgewogICAgICAgICAgICBpZiAoZGlzam9pbnRUeXBlKHRzLmhlYWQsIHNzLmhlYWQpKSByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgdHMgPSB0cy50YWlsOwogICAgICAgICAgICBzcyA9IHNzLnRhaWw7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICAvKioKICAgICAqIFR3byB0eXBlcyBvciB3aWxkY2FyZHMgYXJlIGNvbnNpZGVyZWQgZGlzam9pbnQgaWYgaXQgY2FuIGJlCiAgICAgKiBwcm92ZW4gdGhhdCBubyB0eXBlIGNhbiBiZSBjb250YWluZWQgaW4gYm90aC4gSXQgaXMKICAgICAqIGNvbnNlcnZhdGl2ZSBpbiB0aGF0IGl0IGlzIGFsbG93ZWQgdG8gc2F5IHRoYXQgdHdvIHR5cGVzIGFyZQogICAgICogbm90IGRpc2pvaW50LCBldmVuIHRob3VnaCB0aGV5IGFjdHVhbGx5IGFyZS4KICAgICAqCiAgICAgKiBUaGUgdHlwZSB7QGNvZGUgQzxYPn0gaXMgY2FzdGFibGUgdG8ge0Bjb2RlIEM8WT59IGV4YWN0bHkgaWYKICAgICAqIHtAY29kZSBYfSBhbmQge0Bjb2RlIFl9IGFyZSBub3QgZGlzam9pbnQuCiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGRpc2pvaW50VHlwZShUeXBlIHQsIFR5cGUgcykgewogICAgICAgIHJldHVybiBkaXNqb2ludFR5cGUudmlzaXQodCwgcyk7CiAgICB9CiAgICAvLyB3aGVyZQogICAgICAgIHByaXZhdGUgVHlwZVJlbGF0aW9uIGRpc2pvaW50VHlwZSA9IG5ldyBUeXBlUmVsYXRpb24oKSB7CgogICAgICAgICAgICBwcml2YXRlIFNldDxUeXBlUGFpcj4gY2FjaGUgPSBuZXcgSGFzaFNldDw+KCk7CgogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHVibGljIEJvb2xlYW4gdmlzaXRUeXBlKFR5cGUgdCwgVHlwZSBzKSB7CiAgICAgICAgICAgICAgICBpZiAocy5oYXNUYWcoV0lMRENBUkQpKQogICAgICAgICAgICAgICAgICAgIHJldHVybiB2aXNpdChzLCB0KTsKICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbm90U29mdFN1YnR5cGVSZWN1cnNpdmUodCwgcykgfHwgbm90U29mdFN1YnR5cGVSZWN1cnNpdmUocywgdCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHByaXZhdGUgYm9vbGVhbiBpc0Nhc3RhYmxlUmVjdXJzaXZlKFR5cGUgdCwgVHlwZSBzKSB7CiAgICAgICAgICAgICAgICBUeXBlUGFpciBwYWlyID0gbmV3IFR5cGVQYWlyKHQsIHMpOwogICAgICAgICAgICAgICAgaWYgKGNhY2hlLmFkZChwYWlyKSkgewogICAgICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBUeXBlcy50aGlzLmlzQ2FzdGFibGUodCwgcyk7CiAgICAgICAgICAgICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgICAgICAgICAgICAgY2FjaGUucmVtb3ZlKHBhaXIpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHByaXZhdGUgYm9vbGVhbiBub3RTb2Z0U3VidHlwZVJlY3Vyc2l2ZShUeXBlIHQsIFR5cGUgcykgewogICAgICAgICAgICAgICAgVHlwZVBhaXIgcGFpciA9IG5ldyBUeXBlUGFpcih0LCBzKTsKICAgICAgICAgICAgICAgIGlmIChjYWNoZS5hZGQocGFpcikpIHsKICAgICAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gVHlwZXMudGhpcy5ub3RTb2Z0U3VidHlwZSh0LCBzKTsKICAgICAgICAgICAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAgICAgICAgICAgICBjYWNoZS5yZW1vdmUocGFpcik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgQm9vbGVhbiB2aXNpdFdpbGRjYXJkVHlwZShXaWxkY2FyZFR5cGUgdCwgVHlwZSBzKSB7CiAgICAgICAgICAgICAgICBpZiAodC5pc1VuYm91bmQoKSkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CgogICAgICAgICAgICAgICAgaWYgKCFzLmhhc1RhZyhXSUxEQ0FSRCkpIHsKICAgICAgICAgICAgICAgICAgICBpZiAodC5pc0V4dGVuZHNCb3VuZCgpKQogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbm90U29mdFN1YnR5cGVSZWN1cnNpdmUocywgdC50eXBlKTsKICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBub3RTb2Z0U3VidHlwZVJlY3Vyc2l2ZSh0LnR5cGUsIHMpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmIChzLmlzVW5ib3VuZCgpKQogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKCiAgICAgICAgICAgICAgICBpZiAodC5pc0V4dGVuZHNCb3VuZCgpKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHMuaXNFeHRlbmRzQm91bmQoKSkKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICFpc0Nhc3RhYmxlUmVjdXJzaXZlKHQudHlwZSwgd2lsZFVwcGVyQm91bmQocykpOwogICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHMuaXNTdXBlckJvdW5kKCkpCiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBub3RTb2Z0U3VidHlwZVJlY3Vyc2l2ZSh3aWxkTG93ZXJCb3VuZChzKSwgdC50eXBlKTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodC5pc1N1cGVyQm91bmQoKSkgewogICAgICAgICAgICAgICAgICAgIGlmIChzLmlzRXh0ZW5kc0JvdW5kKCkpCiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBub3RTb2Z0U3VidHlwZVJlY3Vyc2l2ZSh0LnR5cGUsIHdpbGRVcHBlckJvdW5kKHMpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgIH07CiAgICAvLyA8L2VkaXRvci1mb2xkPgoKICAgIC8vIDxlZGl0b3ItZm9sZCBkZWZhdWx0c3RhdGU9ImNvbGxhcHNlZCIgZGVzYz0iY3Zhckxvd2VyQm91bmRzIj4KICAgIHB1YmxpYyBMaXN0PFR5cGU+IGN2YXJMb3dlckJvdW5kcyhMaXN0PFR5cGU+IHRzKSB7CiAgICAgICAgcmV0dXJuIHRzLm1hcChjdmFyTG93ZXJCb3VuZE1hcHBpbmcpOwogICAgfQogICAgICAgIHByaXZhdGUgZmluYWwgVHlwZU1hcHBpbmc8Vm9pZD4gY3Zhckxvd2VyQm91bmRNYXBwaW5nID0gbmV3IFR5cGVNYXBwaW5nPFZvaWQ+KCkgewogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHVibGljIFR5cGUgdmlzaXRDYXB0dXJlZFR5cGUoQ2FwdHVyZWRUeXBlIHQsIFZvaWQgX3VudXNlZCkgewogICAgICAgICAgICAgICAgcmV0dXJuIGN2YXJMb3dlckJvdW5kKHQpOwogICAgICAgICAgICB9CiAgICAgICAgfTsKICAgIC8vIDwvZWRpdG9yLWZvbGQ+CgogICAgLy8gPGVkaXRvci1mb2xkIGRlZmF1bHRzdGF0ZT0iY29sbGFwc2VkIiBkZXNjPSJub3RTb2Z0U3VidHlwZSI+CiAgICAvKioKICAgICAqIFRoaXMgcmVsYXRpb24gYW5zd2VycyB0aGUgcXVlc3Rpb246IGlzIGltcG9zc2libGUgdGhhdAogICAgICogc29tZXRoaW5nIG9mIHR5cGUgYHQnIGNhbiBiZSBhIHN1YnR5cGUgb2YgYHMnPyBUaGlzIGlzCiAgICAgKiBkaWZmZXJlbnQgZnJvbSB0aGUgcXVlc3Rpb24gImlzIGB0JyBub3QgYSBzdWJ0eXBlIG9mIGBzJz8iCiAgICAgKiB3aGVuIHR5cGUgdmFyaWFibGVzIGFyZSBpbnZvbHZlZDogSW50ZWdlciBpcyBub3QgYSBzdWJ0eXBlIG9mIFQKICAgICAqIHdoZXJlIHtAY29kZSA8VCBleHRlbmRzIE51bWJlcj59IGJ1dCBpdCBpcyBub3QgdHJ1ZSB0aGF0IEludGVnZXIgY2Fubm90CiAgICAgKiBwb3NzaWJseSBiZSBhIHN1YnR5cGUgb2YgVC4KICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gbm90U29mdFN1YnR5cGUoVHlwZSB0LCBUeXBlIHMpIHsKICAgICAgICBpZiAodCA9PSBzKSByZXR1cm4gZmFsc2U7CiAgICAgICAgaWYgKHQuaGFzVGFnKFRZUEVWQVIpKSB7CiAgICAgICAgICAgIFR5cGVWYXIgdHYgPSAoVHlwZVZhcikgdDsKICAgICAgICAgICAgcmV0dXJuICFpc0Nhc3RhYmxlKHR2LmJvdW5kLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVsYXhCb3VuZChzKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vV2FybmluZ3MpOwogICAgICAgIH0KICAgICAgICBpZiAoIXMuaGFzVGFnKFdJTERDQVJEKSkKICAgICAgICAgICAgcyA9IGN2YXJVcHBlckJvdW5kKHMpOwoKICAgICAgICByZXR1cm4gIWlzU3VidHlwZSh0LCByZWxheEJvdW5kKHMpKTsKICAgIH0KCiAgICBwcml2YXRlIFR5cGUgcmVsYXhCb3VuZChUeXBlIHQpIHsKICAgICAgICByZXR1cm4gKHQuaGFzVGFnKFRZUEVWQVIpKSA/CiAgICAgICAgICAgICAgICByZXdyaXRlUXVhbnRpZmllcnMoc2tpcFR5cGVWYXJzKHQsIGZhbHNlKSwgdHJ1ZSwgdHJ1ZSkgOgogICAgICAgICAgICAgICAgdDsKICAgIH0KICAgIC8vIDwvZWRpdG9yLWZvbGQ+CgogICAgLy8gPGVkaXRvci1mb2xkIGRlZmF1bHRzdGF0ZT0iY29sbGFwc2VkIiBkZXNjPSJpc1JlaWZpYWJsZSI+CiAgICBwdWJsaWMgYm9vbGVhbiBpc1JlaWZpYWJsZShUeXBlIHQpIHsKICAgICAgICByZXR1cm4gaXNSZWlmaWFibGUudmlzaXQodCk7CiAgICB9CiAgICAvLyB3aGVyZQogICAgICAgIHByaXZhdGUgVW5hcnlWaXNpdG9yPEJvb2xlYW4+IGlzUmVpZmlhYmxlID0gbmV3IFVuYXJ5VmlzaXRvcjxCb29sZWFuPigpIHsKCiAgICAgICAgICAgIHB1YmxpYyBCb29sZWFuIHZpc2l0VHlwZShUeXBlIHQsIFZvaWQgaWdub3JlZCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgQm9vbGVhbiB2aXNpdENsYXNzVHlwZShDbGFzc1R5cGUgdCwgVm9pZCBpZ25vcmVkKSB7CiAgICAgICAgICAgICAgICBpZiAodC5pc0NvbXBvdW5kKCkpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCF0LmlzUGFyYW1ldGVyaXplZCgpKQogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKCiAgICAgICAgICAgICAgICAgICAgZm9yIChUeXBlIHBhcmFtIDogdC5hbGxwYXJhbXMoKSkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXBhcmFtLmlzVW5ib3VuZCgpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHB1YmxpYyBCb29sZWFuIHZpc2l0QXJyYXlUeXBlKEFycmF5VHlwZSB0LCBWb2lkIGlnbm9yZWQpIHsKICAgICAgICAgICAgICAgIHJldHVybiB2aXNpdCh0LmVsZW10eXBlKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHB1YmxpYyBCb29sZWFuIHZpc2l0VHlwZVZhcihUeXBlVmFyIHQsIFZvaWQgaWdub3JlZCkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfTsKICAgIC8vIDwvZWRpdG9yLWZvbGQ+CgogICAgLy8gPGVkaXRvci1mb2xkIGRlZmF1bHRzdGF0ZT0iY29sbGFwc2VkIiBkZXNjPSJBcnJheSBVdGlscyI+CiAgICBwdWJsaWMgYm9vbGVhbiBpc0FycmF5KFR5cGUgdCkgewogICAgICAgIHdoaWxlICh0Lmhhc1RhZyhXSUxEQ0FSRCkpCiAgICAgICAgICAgIHQgPSB3aWxkVXBwZXJCb3VuZCh0KTsKICAgICAgICByZXR1cm4gdC5oYXNUYWcoQVJSQVkpOwogICAgfQoKICAgIC8qKgogICAgICogVGhlIGVsZW1lbnQgdHlwZSBvZiBhbiBhcnJheS4KICAgICAqLwogICAgcHVibGljIFR5cGUgZWxlbXR5cGUoVHlwZSB0KSB7CiAgICAgICAgc3dpdGNoICh0LmdldFRhZygpKSB7CiAgICAgICAgY2FzZSBXSUxEQ0FSRDoKICAgICAgICAgICAgcmV0dXJuIGVsZW10eXBlKHdpbGRVcHBlckJvdW5kKHQpKTsKICAgICAgICBjYXNlIEFSUkFZOgogICAgICAgICAgICByZXR1cm4gKChBcnJheVR5cGUpdCkuZWxlbXR5cGU7CiAgICAgICAgY2FzZSBGT1JBTEw6CiAgICAgICAgICAgIHJldHVybiBlbGVtdHlwZSgoKEZvckFsbCl0KS5xdHlwZSk7CiAgICAgICAgY2FzZSBFUlJPUjoKICAgICAgICAgICAgcmV0dXJuIHQ7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBUeXBlIGVsZW10eXBlT3JUeXBlKFR5cGUgdCkgewogICAgICAgIFR5cGUgZWxlbXR5cGUgPSBlbGVtdHlwZSh0KTsKICAgICAgICByZXR1cm4gZWxlbXR5cGUgIT0gbnVsbCA/CiAgICAgICAgICAgIGVsZW10eXBlIDoKICAgICAgICAgICAgdDsKICAgIH0KCiAgICAvKioKICAgICAqIE1hcHBpbmcgdG8gdGFrZSBlbGVtZW50IHR5cGUgb2YgYW4gYXJyYXl0eXBlCiAgICAgKi8KICAgIHByaXZhdGUgVHlwZU1hcHBpbmc8Vm9pZD4gZWxlbVR5cGVGdW4gPSBuZXcgVHlwZU1hcHBpbmc8Vm9pZD4oKSB7CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFR5cGUgdmlzaXRBcnJheVR5cGUoQXJyYXlUeXBlIHQsIFZvaWQgX3VudXNlZCkgewogICAgICAgICAgICByZXR1cm4gdC5lbGVtdHlwZTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBUeXBlIHZpc2l0VHlwZVZhcihUeXBlVmFyIHQsIFZvaWQgX3VudXNlZCkgewogICAgICAgICAgICByZXR1cm4gdmlzaXQoc2tpcFR5cGVWYXJzKHQsIGZhbHNlKSk7CiAgICAgICAgfQogICAgfTsKCiAgICAvKioKICAgICAqIFRoZSBudW1iZXIgb2YgZGltZW5zaW9ucyBvZiBhbiBhcnJheSB0eXBlLgogICAgICovCiAgICBwdWJsaWMgaW50IGRpbWVuc2lvbnMoVHlwZSB0KSB7CiAgICAgICAgaW50IHJlc3VsdCA9IDA7CiAgICAgICAgd2hpbGUgKHQuaGFzVGFnKEFSUkFZKSkgewogICAgICAgICAgICByZXN1bHQrKzsKICAgICAgICAgICAgdCA9IGVsZW10eXBlKHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyBhbiBBcnJheVR5cGUgd2l0aCB0aGUgY29tcG9uZW50IHR5cGUgdAogICAgICoKICAgICAqIEBwYXJhbSB0IFRoZSBjb21wb25lbnQgdHlwZSBvZiB0aGUgQXJyYXlUeXBlCiAgICAgKiBAcmV0dXJuIHRoZSBBcnJheVR5cGUgZm9yIHRoZSBnaXZlbiBjb21wb25lbnQKICAgICAqLwogICAgcHVibGljIEFycmF5VHlwZSBtYWtlQXJyYXlUeXBlKFR5cGUgdCkgewogICAgICAgIGlmICh0Lmhhc1RhZyhWT0lEKSB8fCB0Lmhhc1RhZyhQQUNLQUdFKSkgewogICAgICAgICAgICBBc3NlcnQuZXJyb3IoIlR5cGUgdCBtdXN0IG5vdCBiZSBhIFZPSUQgb3IgUEFDS0FHRSB0eXBlLCAiICsgdC50b1N0cmluZygpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG5ldyBBcnJheVR5cGUodCwgc3ltcy5hcnJheUNsYXNzKTsKICAgIH0KICAgIC8vIDwvZWRpdG9yLWZvbGQ+CgogICAgLy8gPGVkaXRvci1mb2xkIGRlZmF1bHRzdGF0ZT0iY29sbGFwc2VkIiBkZXNjPSJhc1N1cGVyIj4KICAgIC8qKgogICAgICogUmV0dXJuIHRoZSAobW9zdCBzcGVjaWZpYykgYmFzZSB0eXBlIG9mIHQgdGhhdCBzdGFydHMgd2l0aCB0aGUKICAgICAqIGdpdmVuIHN5bWJvbC4gIElmIG5vbmUgZXhpc3RzLCByZXR1cm4gbnVsbC4KICAgICAqCiAgICAgKiBDYXZlYXQgRW1wdG9yOiBTaW5jZSBqYXZhYyByZXByZXNlbnRzIHRoZSBjbGFzcyBvZiBhbGwgYXJyYXlzIHdpdGggYSBzaW5nbGV0b24KICAgICAqIHN5bWJvbCBTeW10YWIuYXJyYXlDbGFzcywgd2hpY2ggYnkgYmVpbmcgYSBzaW5nbGV0b24gY2Fubm90IGhvbGQgYW55IGRpc2NyaW1pbmFudCwKICAgICAqIHRoaXMgbWV0aG9kIGNvdWxkIHlpZWxkIHN1cnByaXNpbmcgYW5zd2VycyB3aGVuIGludm9rZWQgb24gYXJyYXlzLiBGb3IgZXhhbXBsZSB3aGVuCiAgICAgKiBpbnZva2VkIHdpdGggdCBiZWluZyBieXRlIFtdIGFuZCBzeW0gYmVpbmcgdC5zeW0gaXRzZWxmLCBhc1N1cGVyIHdvdWxkIGFuc3dlciBudWxsLgogICAgICoKICAgICAqIEBwYXJhbSB0IGEgdHlwZQogICAgICogQHBhcmFtIHN5bSBhIHN5bWJvbAogICAgICovCiAgICBwdWJsaWMgVHlwZSBhc1N1cGVyKFR5cGUgdCwgU3ltYm9sIHN5bSkgewogICAgICAgIC8qIFNvbWUgZXhhbXBsZXM6CiAgICAgICAgICoKICAgICAgICAgKiAoRW51bTxFPiwgQ29tcGFyYWJsZSkgPT4gQ29tcGFyYWJsZTxFPgogICAgICAgICAqIChjLnMucy5kLkF0dHJpYnV0ZVRyZWUuVmFsdWVLaW5kLCBFbnVtKSA9PiBFbnVtPGMucy5zLmQuQXR0cmlidXRlVHJlZS5WYWx1ZUtpbmQ+CiAgICAgICAgICogKGMucy5zLnQuRXhwcmVzc2lvblRyZWUsIGMucy5zLnQuVHJlZSkgPT4gYy5zLnMudC5UcmVlCiAgICAgICAgICogKGoudS5MaXN0PGNhcHR1cmUjMTYwIG9mID8gZXh0ZW5kcyBjLnMucy5kLkRvY1RyZWU+LCBJdGVyYWJsZSkgPT4KICAgICAgICAgKiAgICAgSXRlcmFibGU8Y2FwdHVyZSMxNjAgb2YgPyBleHRlbmRzIGMucy5zLmQuRG9jVHJlZT4KICAgICAgICAgKi8KICAgICAgICBpZiAoc3ltLnR5cGUgPT0gc3ltcy5vYmplY3RUeXBlKSB7IC8vb3B0aW1pemF0aW9uCiAgICAgICAgICAgIHJldHVybiBzeW1zLm9iamVjdFR5cGU7CiAgICAgICAgfQogICAgICAgIHJldHVybiBhc1N1cGVyLnZpc2l0KHQsIHN5bSk7CiAgICB9CiAgICAvLyB3aGVyZQogICAgICAgIHByaXZhdGUgU2ltcGxlVmlzaXRvcjxUeXBlLFN5bWJvbD4gYXNTdXBlciA9IG5ldyBTaW1wbGVWaXNpdG9yPFR5cGUsU3ltYm9sPigpIHsKCiAgICAgICAgICAgIHB1YmxpYyBUeXBlIHZpc2l0VHlwZShUeXBlIHQsIFN5bWJvbCBzeW0pIHsKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICB9CgogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHVibGljIFR5cGUgdmlzaXRDbGFzc1R5cGUoQ2xhc3NUeXBlIHQsIFN5bWJvbCBzeW0pIHsKICAgICAgICAgICAgICAgIGlmICh0LnRzeW0gPT0gc3ltKQogICAgICAgICAgICAgICAgICAgIHJldHVybiB0OwoKICAgICAgICAgICAgICAgIFR5cGUgc3QgPSBzdXBlcnR5cGUodCk7CiAgICAgICAgICAgICAgICBpZiAoc3QuaGFzVGFnKENMQVNTKSB8fCBzdC5oYXNUYWcoVFlQRVZBUikpIHsKICAgICAgICAgICAgICAgICAgICBUeXBlIHggPSBhc1N1cGVyKHN0LCBzeW0pOwogICAgICAgICAgICAgICAgICAgIGlmICh4ICE9IG51bGwpCiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB4OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKChzeW0uZmxhZ3MoKSAmIElOVEVSRkFDRSkgIT0gMCkgewogICAgICAgICAgICAgICAgICAgIGZvciAoTGlzdDxUeXBlPiBsID0gaW50ZXJmYWNlcyh0KTsgbC5ub25FbXB0eSgpOyBsID0gbC50YWlsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghbC5oZWFkLmhhc1RhZyhFUlJPUikpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFR5cGUgeCA9IGFzU3VwZXIobC5oZWFkLCBzeW0pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHggIT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4geDsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICB9CgogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHVibGljIFR5cGUgdmlzaXRBcnJheVR5cGUoQXJyYXlUeXBlIHQsIFN5bWJvbCBzeW0pIHsKICAgICAgICAgICAgICAgIHJldHVybiBpc1N1YnR5cGUodCwgc3ltLnR5cGUpID8gc3ltLnR5cGUgOiBudWxsOwogICAgICAgICAgICB9CgogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHVibGljIFR5cGUgdmlzaXRUeXBlVmFyKFR5cGVWYXIgdCwgU3ltYm9sIHN5bSkgewogICAgICAgICAgICAgICAgaWYgKHQudHN5bSA9PSBzeW0pCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHQ7CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGFzU3VwZXIodC5ib3VuZCwgc3ltKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHB1YmxpYyBUeXBlIHZpc2l0RXJyb3JUeXBlKEVycm9yVHlwZSB0LCBTeW1ib2wgc3ltKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdDsKICAgICAgICAgICAgfQogICAgICAgIH07CgogICAgLyoqCiAgICAgKiBSZXR1cm4gdGhlIGJhc2UgdHlwZSBvZiB0IG9yIGFueSBvZiBpdHMgb3V0ZXIgdHlwZXMgdGhhdCBzdGFydHMKICAgICAqIHdpdGggdGhlIGdpdmVuIHN5bWJvbC4gIElmIG5vbmUgZXhpc3RzLCByZXR1cm4gbnVsbC4KICAgICAqCiAgICAgKiBAcGFyYW0gdCBhIHR5cGUKICAgICAqIEBwYXJhbSBzeW0gYSBzeW1ib2wKICAgICAqLwogICAgcHVibGljIFR5cGUgYXNPdXRlclN1cGVyKFR5cGUgdCwgU3ltYm9sIHN5bSkgewogICAgICAgIHN3aXRjaCAodC5nZXRUYWcoKSkgewogICAgICAgIGNhc2UgQ0xBU1M6CiAgICAgICAgICAgIGRvIHsKICAgICAgICAgICAgICAgIFR5cGUgcyA9IGFzU3VwZXIodCwgc3ltKTsKICAgICAgICAgICAgICAgIGlmIChzICE9IG51bGwpIHJldHVybiBzOwogICAgICAgICAgICAgICAgdCA9IHQuZ2V0RW5jbG9zaW5nVHlwZSgpOwogICAgICAgICAgICB9IHdoaWxlICh0Lmhhc1RhZyhDTEFTUykpOwogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICBjYXNlIEFSUkFZOgogICAgICAgICAgICByZXR1cm4gaXNTdWJ0eXBlKHQsIHN5bS50eXBlKSA/IHN5bS50eXBlIDogbnVsbDsKICAgICAgICBjYXNlIFRZUEVWQVI6CiAgICAgICAgICAgIHJldHVybiBhc1N1cGVyKHQsIHN5bSk7CiAgICAgICAgY2FzZSBFUlJPUjoKICAgICAgICAgICAgcmV0dXJuIHQ7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJuIHRoZSBiYXNlIHR5cGUgb2YgdCBvciBhbnkgb2YgaXRzIGVuY2xvc2luZyB0eXBlcyB0aGF0CiAgICAgKiBzdGFydHMgd2l0aCB0aGUgZ2l2ZW4gc3ltYm9sLiAgSWYgbm9uZSBleGlzdHMsIHJldHVybiBudWxsLgogICAgICoKICAgICAqIEBwYXJhbSB0IGEgdHlwZQogICAgICogQHBhcmFtIHN5bSBhIHN5bWJvbAogICAgICovCiAgICBwdWJsaWMgVHlwZSBhc0VuY2xvc2luZ1N1cGVyKFR5cGUgdCwgU3ltYm9sIHN5bSkgewogICAgICAgIHN3aXRjaCAodC5nZXRUYWcoKSkgewogICAgICAgIGNhc2UgQ0xBU1M6CiAgICAgICAgICAgIGRvIHsKICAgICAgICAgICAgICAgIFR5cGUgcyA9IGFzU3VwZXIodCwgc3ltKTsKICAgICAgICAgICAgICAgIGlmIChzICE9IG51bGwpIHJldHVybiBzOwogICAgICAgICAgICAgICAgVHlwZSBvdXRlciA9IHQuZ2V0RW5jbG9zaW5nVHlwZSgpOwogICAgICAgICAgICAgICAgdCA9IChvdXRlci5oYXNUYWcoQ0xBU1MpKSA/IG91dGVyIDoKICAgICAgICAgICAgICAgICAgICAodC50c3ltLm93bmVyLmVuY2xDbGFzcygpICE9IG51bGwpID8gdC50c3ltLm93bmVyLmVuY2xDbGFzcygpLnR5cGUgOgogICAgICAgICAgICAgICAgICAgIFR5cGUubm9UeXBlOwogICAgICAgICAgICB9IHdoaWxlICh0Lmhhc1RhZyhDTEFTUykpOwogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICBjYXNlIEFSUkFZOgogICAgICAgICAgICByZXR1cm4gaXNTdWJ0eXBlKHQsIHN5bS50eXBlKSA/IHN5bS50eXBlIDogbnVsbDsKICAgICAgICBjYXNlIFRZUEVWQVI6CiAgICAgICAgICAgIHJldHVybiBhc1N1cGVyKHQsIHN5bSk7CiAgICAgICAgY2FzZSBFUlJPUjoKICAgICAgICAgICAgcmV0dXJuIHQ7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgfQogICAgLy8gPC9lZGl0b3ItZm9sZD4KCiAgICAvLyA8ZWRpdG9yLWZvbGQgZGVmYXVsdHN0YXRlPSJjb2xsYXBzZWQiIGRlc2M9Im1lbWJlclR5cGUiPgogICAgLyoqCiAgICAgKiBUaGUgdHlwZSBvZiBnaXZlbiBzeW1ib2wsIHNlZW4gYXMgYSBtZW1iZXIgb2YgdC4KICAgICAqCiAgICAgKiBAcGFyYW0gdCBhIHR5cGUKICAgICAqIEBwYXJhbSBzeW0gYSBzeW1ib2wKICAgICAqLwogICAgcHVibGljIFR5cGUgbWVtYmVyVHlwZShUeXBlIHQsIFN5bWJvbCBzeW0pIHsKICAgICAgICByZXR1cm4gKHN5bS5mbGFncygpICYgU1RBVElDKSAhPSAwCiAgICAgICAgICAgID8gc3ltLnR5cGUKICAgICAgICAgICAgOiBtZW1iZXJUeXBlLnZpc2l0KHQsIHN5bSk7CiAgICAgICAgfQogICAgLy8gd2hlcmUKICAgICAgICBwcml2YXRlIFNpbXBsZVZpc2l0b3I8VHlwZSxTeW1ib2w+IG1lbWJlclR5cGUgPSBuZXcgU2ltcGxlVmlzaXRvcjxUeXBlLFN5bWJvbD4oKSB7CgogICAgICAgICAgICBwdWJsaWMgVHlwZSB2aXNpdFR5cGUoVHlwZSB0LCBTeW1ib2wgc3ltKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gc3ltLnR5cGU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgVHlwZSB2aXNpdFdpbGRjYXJkVHlwZShXaWxkY2FyZFR5cGUgdCwgU3ltYm9sIHN5bSkgewogICAgICAgICAgICAgICAgcmV0dXJuIG1lbWJlclR5cGUod2lsZFVwcGVyQm91bmQodCksIHN5bSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgVHlwZSB2aXNpdENsYXNzVHlwZShDbGFzc1R5cGUgdCwgU3ltYm9sIHN5bSkgewogICAgICAgICAgICAgICAgU3ltYm9sIG93bmVyID0gc3ltLm93bmVyOwogICAgICAgICAgICAgICAgbG9uZyBmbGFncyA9IHN5bS5mbGFncygpOwogICAgICAgICAgICAgICAgaWYgKCgoZmxhZ3MgJiBTVEFUSUMpID09IDApICYmIG93bmVyLnR5cGUuaXNQYXJhbWV0ZXJpemVkKCkpIHsKICAgICAgICAgICAgICAgICAgICBUeXBlIGJhc2UgPSBhc091dGVyU3VwZXIodCwgb3duZXIpOwogICAgICAgICAgICAgICAgICAgIC8vaWYgdCBpcyBhbiBpbnRlcnNlY3Rpb24gdHlwZSBUID0gQ1QgJiBJMSAmIEkyIC4uLiAmIEluCiAgICAgICAgICAgICAgICAgICAgLy9pdHMgc3VwZXJ0eXBlcyBDVCwgSTEsIC4uLiBJbiBtaWdodCBjb250YWluIHdpbGRjYXJkcwogICAgICAgICAgICAgICAgICAgIC8vc28gd2UgbmVlZCB0byBnbyB0aHJvdWdoIGNhcHR1cmUgY29udmVyc2lvbgogICAgICAgICAgICAgICAgICAgIGJhc2UgPSB0LmlzQ29tcG91bmQoKSA/IGNhcHR1cmUoYmFzZSkgOiBiYXNlOwogICAgICAgICAgICAgICAgICAgIGlmIChiYXNlICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgTGlzdDxUeXBlPiBvd25lclBhcmFtcyA9IG93bmVyLnR5cGUuYWxscGFyYW1zKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIExpc3Q8VHlwZT4gYmFzZVBhcmFtcyA9IGJhc2UuYWxscGFyYW1zKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvd25lclBhcmFtcy5ub25FbXB0eSgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYmFzZVBhcmFtcy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGVuIGJhc2UgaXMgYSByYXcgdHlwZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBlcmFzdXJlKHN5bS50eXBlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHN1YnN0KHN5bS50eXBlLCBvd25lclBhcmFtcywgYmFzZVBhcmFtcyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gc3ltLnR5cGU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgVHlwZSB2aXNpdFR5cGVWYXIoVHlwZVZhciB0LCBTeW1ib2wgc3ltKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gbWVtYmVyVHlwZSh0LmJvdW5kLCBzeW0pOwogICAgICAgICAgICB9CgogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHVibGljIFR5cGUgdmlzaXRFcnJvclR5cGUoRXJyb3JUeXBlIHQsIFN5bWJvbCBzeW0pIHsKICAgICAgICAgICAgICAgIHJldHVybiB0OwogICAgICAgICAgICB9CiAgICAgICAgfTsKICAgIC8vIDwvZWRpdG9yLWZvbGQ+CgogICAgLy8gPGVkaXRvci1mb2xkIGRlZmF1bHRzdGF0ZT0iY29sbGFwc2VkIiBkZXNjPSJpc0Fzc2lnbmFibGUiPgogICAgcHVibGljIGJvb2xlYW4gaXNBc3NpZ25hYmxlKFR5cGUgdCwgVHlwZSBzKSB7CiAgICAgICAgcmV0dXJuIGlzQXNzaWduYWJsZSh0LCBzLCBub1dhcm5pbmdzKTsKICAgIH0KCiAgICAvKioKICAgICAqIElzIHQgYXNzaWduYWJsZSB0byBzPzxicj4KICAgICAqIEVxdWl2YWxlbnQgdG8gc3VidHlwZSBleGNlcHQgZm9yIGNvbnN0YW50IHZhbHVlcyBhbmQgcmF3CiAgICAgKiB0eXBlcy48YnI+CiAgICAgKiAobm90IGRlZmluZWQgZm9yIE1ldGhvZCBhbmQgRm9yQWxsIHR5cGVzKQogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBpc0Fzc2lnbmFibGUoVHlwZSB0LCBUeXBlIHMsIFdhcm5lciB3YXJuKSB7CiAgICAgICAgaWYgKHQuaGFzVGFnKEVSUk9SKSkKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgaWYgKHQuZ2V0VGFnKCkuaXNTdWJSYW5nZU9mKElOVCkgJiYgdC5jb25zdFZhbHVlKCkgIT0gbnVsbCkgewogICAgICAgICAgICBpbnQgdmFsdWUgPSAoKE51bWJlcil0LmNvbnN0VmFsdWUoKSkuaW50VmFsdWUoKTsKICAgICAgICAgICAgc3dpdGNoIChzLmdldFRhZygpKSB7CiAgICAgICAgICAgIGNhc2UgQllURToKICAgICAgICAgICAgY2FzZSBDSEFSOgogICAgICAgICAgICBjYXNlIFNIT1JUOgogICAgICAgICAgICBjYXNlIElOVDoKICAgICAgICAgICAgICAgIGlmIChzLmdldFRhZygpLmNoZWNrUmFuZ2UodmFsdWUpKQogICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgQ0xBU1M6CiAgICAgICAgICAgICAgICBzd2l0Y2ggKHVuYm94ZWRUeXBlKHMpLmdldFRhZygpKSB7CiAgICAgICAgICAgICAgICBjYXNlIEJZVEU6CiAgICAgICAgICAgICAgICBjYXNlIENIQVI6CiAgICAgICAgICAgICAgICBjYXNlIFNIT1JUOgogICAgICAgICAgICAgICAgICAgIHJldHVybiBpc0Fzc2lnbmFibGUodCwgdW5ib3hlZFR5cGUocyksIHdhcm4pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIGlzQ29udmVydGlibGUodCwgcywgd2Fybik7CiAgICB9CiAgICAvLyA8L2VkaXRvci1mb2xkPgoKICAgIC8vIDxlZGl0b3ItZm9sZCBkZWZhdWx0c3RhdGU9ImNvbGxhcHNlZCIgZGVzYz0iZXJhc3VyZSI+CiAgICAvKioKICAgICAqIFRoZSBlcmFzdXJlIG9mIHQge0Bjb2RlIHx0fH0gLS0gdGhlIHR5cGUgdGhhdCByZXN1bHRzIHdoZW4gYWxsCiAgICAgKiB0eXBlIHBhcmFtZXRlcnMgaW4gdCBhcmUgZGVsZXRlZC4KICAgICAqLwogICAgcHVibGljIFR5cGUgZXJhc3VyZShUeXBlIHQpIHsKICAgICAgICByZXR1cm4gZXJhc2VOb3ROZWVkZWQodCkgPyB0IDogZXJhc3VyZSh0LCBmYWxzZSk7CiAgICB9CiAgICAvL3doZXJlCiAgICBwcml2YXRlIGJvb2xlYW4gZXJhc2VOb3ROZWVkZWQoVHlwZSB0KSB7CiAgICAgICAgLy8gV2UgZG9uJ3Qgd2FudCB0byBlcmFzZSBwcmltaXRpdmUgdHlwZXMgYW5kIFN0cmluZyB0eXBlIGFzIHRoYXQKICAgICAgICAvLyBvcGVyYXRpb24gaXMgaWRlbXBvdGVudC4gQWxzbywgZXJhc2luZyB0aGVzZSBjb3VsZCByZXN1bHQgaW4gbG9zcwogICAgICAgIC8vIG9mIGluZm9ybWF0aW9uIHN1Y2ggYXMgY29uc3RhbnQgdmFsdWVzIGF0dGFjaGVkIHRvIHN1Y2ggdHlwZXMuCiAgICAgICAgcmV0dXJuICh0LmlzUHJpbWl0aXZlKCkpIHx8IChzeW1zLnN0cmluZ1R5cGUudHN5bSA9PSB0LnRzeW0pOwogICAgfQoKICAgIHByaXZhdGUgVHlwZSBlcmFzdXJlKFR5cGUgdCwgYm9vbGVhbiByZWN1cnNlKSB7CiAgICAgICAgaWYgKHQuaXNQcmltaXRpdmUoKSkgewogICAgICAgICAgICByZXR1cm4gdDsgLyogZmFzdCBzcGVjaWFsIGNhc2UgKi8KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBUeXBlIG91dCA9IGVyYXN1cmUudmlzaXQodCwgcmVjdXJzZSk7CiAgICAgICAgICAgIHJldHVybiBvdXQ7CiAgICAgICAgfQogICAgICAgIH0KICAgIC8vIHdoZXJlCiAgICAgICAgcHJpdmF0ZSBUeXBlTWFwcGluZzxCb29sZWFuPiBlcmFzdXJlID0gbmV3IFN0cnVjdHVyYWxUeXBlTWFwcGluZzxCb29sZWFuPigpIHsKICAgICAgICAgICAgcHJpdmF0ZSBUeXBlIGNvbWJpbmVNZXRhZGF0YShmaW5hbCBUeXBlIHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgVHlwZSB0KSB7CiAgICAgICAgICAgICAgICBpZiAodC5nZXRNZXRhZGF0YSgpICE9IFR5cGVNZXRhZGF0YS5FTVBUWSkgewogICAgICAgICAgICAgICAgICAgIHN3aXRjaCAocy5nZXRLaW5kKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBPVEhFUjoKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBVTklPTjoKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBJTlRFUlNFQ1RJT046CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgUEFDS0FHRToKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBFWEVDVVRBQkxFOgogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIE5PTkU6CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgVk9JRDoKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBFUlJPUjoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzOwogICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OiByZXR1cm4gcy5jbG9uZVdpdGhNZXRhZGF0YShzLmdldE1ldGFkYXRhKCkud2l0aG91dChLaW5kLkFOTk9UQVRJT05TKSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gczsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHVibGljIFR5cGUgdmlzaXRUeXBlKFR5cGUgdCwgQm9vbGVhbiByZWN1cnNlKSB7CiAgICAgICAgICAgICAgICBpZiAodC5pc1ByaW1pdGl2ZSgpKQogICAgICAgICAgICAgICAgICAgIHJldHVybiB0OyAvKmZhc3Qgc3BlY2lhbCBjYXNlKi8KICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgIC8vb3RoZXIgY2FzZXMgYWxyZWFkeSBoYW5kbGVkCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNvbWJpbmVNZXRhZGF0YSh0LCB0KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHB1YmxpYyBUeXBlIHZpc2l0V2lsZGNhcmRUeXBlKFdpbGRjYXJkVHlwZSB0LCBCb29sZWFuIHJlY3Vyc2UpIHsKICAgICAgICAgICAgICAgIFR5cGUgZXJhc2VkID0gZXJhc3VyZSh3aWxkVXBwZXJCb3VuZCh0KSwgcmVjdXJzZSk7CiAgICAgICAgICAgICAgICByZXR1cm4gY29tYmluZU1ldGFkYXRhKGVyYXNlZCwgdCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgVHlwZSB2aXNpdENsYXNzVHlwZShDbGFzc1R5cGUgdCwgQm9vbGVhbiByZWN1cnNlKSB7CiAgICAgICAgICAgICAgICBUeXBlIGVyYXNlZCA9IHQudHN5bS5lcmFzdXJlKFR5cGVzLnRoaXMpOwogICAgICAgICAgICAgICAgaWYgKHJlY3Vyc2UpIHsKICAgICAgICAgICAgICAgICAgICBlcmFzZWQgPSBuZXcgRXJhc2VkQ2xhc3NUeXBlKGVyYXNlZC5nZXRFbmNsb3NpbmdUeXBlKCksZXJhc2VkLnRzeW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0LmdldE1ldGFkYXRhKCkud2l0aG91dChLaW5kLkFOTk9UQVRJT05TKSk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGVyYXNlZDsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNvbWJpbmVNZXRhZGF0YShlcmFzZWQsIHQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHVibGljIFR5cGUgdmlzaXRUeXBlVmFyKFR5cGVWYXIgdCwgQm9vbGVhbiByZWN1cnNlKSB7CiAgICAgICAgICAgICAgICBUeXBlIGVyYXNlZCA9IGVyYXN1cmUodC5ib3VuZCwgcmVjdXJzZSk7CiAgICAgICAgICAgICAgICByZXR1cm4gY29tYmluZU1ldGFkYXRhKGVyYXNlZCwgdCk7CiAgICAgICAgICAgIH0KICAgICAgICB9OwoKICAgIHB1YmxpYyBMaXN0PFR5cGU+IGVyYXN1cmUoTGlzdDxUeXBlPiB0cykgewogICAgICAgIHJldHVybiBlcmFzdXJlLnZpc2l0KHRzLCBmYWxzZSk7CiAgICB9CgogICAgcHVibGljIFR5cGUgZXJhc3VyZVJlY3Vyc2l2ZShUeXBlIHQpIHsKICAgICAgICByZXR1cm4gZXJhc3VyZSh0LCB0cnVlKTsKICAgIH0KCiAgICBwdWJsaWMgTGlzdDxUeXBlPiBlcmFzdXJlUmVjdXJzaXZlKExpc3Q8VHlwZT4gdHMpIHsKICAgICAgICByZXR1cm4gZXJhc3VyZS52aXNpdCh0cywgdHJ1ZSk7CiAgICB9CiAgICAvLyA8L2VkaXRvci1mb2xkPgoKICAgIC8vIDxlZGl0b3ItZm9sZCBkZWZhdWx0c3RhdGU9ImNvbGxhcHNlZCIgZGVzYz0ibWFrZUludGVyc2VjdGlvblR5cGUiPgogICAgLyoqCiAgICAgKiBNYWtlIGFuIGludGVyc2VjdGlvbiB0eXBlIGZyb20gbm9uLWVtcHR5IGxpc3Qgb2YgdHlwZXMuICBUaGUgbGlzdCBzaG91bGQgYmUgb3JkZXJlZCBhY2NvcmRpbmcgdG8KICAgICAqIHtAbGluayBUeXBlU3ltYm9sI3ByZWNlZGVzKFR5cGVTeW1ib2wsIFR5cGVzKX0uIE5vdGUgdGhhdCB0aGlzIG1pZ2h0IGNhdXNlIGEgc3ltYm9sIGNvbXBsZXRpb24uCiAgICAgKiBIZW5jZSwgdGhpcyB2ZXJzaW9uIG9mIG1ha2VJbnRlcnNlY3Rpb25UeXBlIG1heSBub3QgYmUgY2FsbGVkIGR1cmluZyBhIGNsYXNzZmlsZSByZWFkLgogICAgICoKICAgICAqIEBwYXJhbSBib3VuZHMgICAgdGhlIHR5cGVzIGZyb20gd2hpY2ggdGhlIGludGVyc2VjdGlvbiB0eXBlIGlzIGZvcm1lZAogICAgICovCiAgICBwdWJsaWMgSW50ZXJzZWN0aW9uQ2xhc3NUeXBlIG1ha2VJbnRlcnNlY3Rpb25UeXBlKExpc3Q8VHlwZT4gYm91bmRzKSB7CiAgICAgICAgcmV0dXJuIG1ha2VJbnRlcnNlY3Rpb25UeXBlKGJvdW5kcywgYm91bmRzLmhlYWQudHN5bS5pc0ludGVyZmFjZSgpKTsKICAgIH0KCiAgICAvKioKICAgICAqIE1ha2UgYW4gaW50ZXJzZWN0aW9uIHR5cGUgZnJvbSBub24tZW1wdHkgbGlzdCBvZiB0eXBlcy4gIFRoZSBsaXN0IHNob3VsZCBiZSBvcmRlcmVkIGFjY29yZGluZyB0bwogICAgICoge0BsaW5rIFR5cGVTeW1ib2wjcHJlY2VkZXMoVHlwZVN5bWJvbCwgVHlwZXMpfS4gVGhpcyBkb2VzIG5vdCBjYXVzZSBzeW1ib2wgY29tcGxldGlvbiBhcwogICAgICogYW4gZXh0cmEgcGFyYW1ldGVyIGluZGljYXRlcyBhcyB0byB3aGV0aGVyIGFsbCBib3VuZHMgYXJlIGludGVyZmFjZXMgLSBpbiB3aGljaCBjYXNlIHRoZQogICAgICogc3VwZXJ0eXBlIGlzIGltcGxpY2l0bHkgYXNzdW1lZCB0byBiZSAnT2JqZWN0Jy4KICAgICAqCiAgICAgKiBAcGFyYW0gYm91bmRzICAgICAgICB0aGUgdHlwZXMgZnJvbSB3aGljaCB0aGUgaW50ZXJzZWN0aW9uIHR5cGUgaXMgZm9ybWVkCiAgICAgKiBAcGFyYW0gYWxsSW50ZXJmYWNlcyBhcmUgYWxsIGJvdW5kcyBpbnRlcmZhY2UgdHlwZXM/CiAgICAgKi8KICAgIHB1YmxpYyBJbnRlcnNlY3Rpb25DbGFzc1R5cGUgbWFrZUludGVyc2VjdGlvblR5cGUoTGlzdDxUeXBlPiBib3VuZHMsIGJvb2xlYW4gYWxsSW50ZXJmYWNlcykgewogICAgICAgIEFzc2VydC5jaGVjayhib3VuZHMubm9uRW1wdHkoKSk7CiAgICAgICAgVHlwZSBmaXJzdEV4cGxpY2l0Qm91bmQgPSBib3VuZHMuaGVhZDsKICAgICAgICBpZiAoYWxsSW50ZXJmYWNlcykgewogICAgICAgICAgICBib3VuZHMgPSBib3VuZHMucHJlcGVuZChzeW1zLm9iamVjdFR5cGUpOwogICAgICAgIH0KICAgICAgICBDbGFzc1N5bWJvbCBiYyA9CiAgICAgICAgICAgIG5ldyBDbGFzc1N5bWJvbChBQlNUUkFDVHxQVUJMSUN8U1lOVEhFVElDfENPTVBPVU5EfEFDWUNMSUMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBUeXBlLm1vcmVJbmZvCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBuYW1lcy5mcm9tU3RyaW5nKGJvdW5kcy50b1N0cmluZygpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogbmFtZXMuZW1wdHksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ltcy5ub1N5bWJvbCk7CiAgICAgICAgSW50ZXJzZWN0aW9uQ2xhc3NUeXBlIGludGVyc2VjdGlvblR5cGUgPSBuZXcgSW50ZXJzZWN0aW9uQ2xhc3NUeXBlKGJvdW5kcywgYmMsIGFsbEludGVyZmFjZXMpOwogICAgICAgIGJjLnR5cGUgPSBpbnRlcnNlY3Rpb25UeXBlOwogICAgICAgIGJjLmVyYXN1cmVfZmllbGQgPSAoYm91bmRzLmhlYWQuaGFzVGFnKFRZUEVWQVIpKSA/CiAgICAgICAgICAgICAgICBzeW1zLm9iamVjdFR5cGUgOiAvLyBlcnJvciBjb25kaXRpb24sIHJlY292ZXIKICAgICAgICAgICAgICAgIGVyYXN1cmUoZmlyc3RFeHBsaWNpdEJvdW5kKTsKICAgICAgICBiYy5tZW1iZXJzX2ZpZWxkID0gV3JpdGVhYmxlU2NvcGUuY3JlYXRlKGJjKTsKICAgICAgICByZXR1cm4gaW50ZXJzZWN0aW9uVHlwZTsKICAgIH0KICAgIC8vIDwvZWRpdG9yLWZvbGQ+CgogICAgLy8gPGVkaXRvci1mb2xkIGRlZmF1bHRzdGF0ZT0iY29sbGFwc2VkIiBkZXNjPSJzdXBlcnR5cGUiPgogICAgcHVibGljIFR5cGUgc3VwZXJ0eXBlKFR5cGUgdCkgewogICAgICAgIHJldHVybiBzdXBlcnR5cGUudmlzaXQodCk7CiAgICB9CiAgICAvLyB3aGVyZQogICAgICAgIHByaXZhdGUgVW5hcnlWaXNpdG9yPFR5cGU+IHN1cGVydHlwZSA9IG5ldyBVbmFyeVZpc2l0b3I8VHlwZT4oKSB7CgogICAgICAgICAgICBwdWJsaWMgVHlwZSB2aXNpdFR5cGUoVHlwZSB0LCBWb2lkIGlnbm9yZWQpIHsKICAgICAgICAgICAgICAgIC8vIEEgbm90ZSBvbiB3aWxkY2FyZHM6IHRoZXJlIGlzIG5vIGdvb2Qgd2F5IHRvCiAgICAgICAgICAgICAgICAvLyBkZXRlcm1pbmUgYSBzdXBlcnR5cGUgZm9yIGEgc3VwZXIgYm91bmRlZCB3aWxkY2FyZC4KICAgICAgICAgICAgICAgIHJldHVybiBUeXBlLm5vVHlwZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHB1YmxpYyBUeXBlIHZpc2l0Q2xhc3NUeXBlKENsYXNzVHlwZSB0LCBWb2lkIGlnbm9yZWQpIHsKICAgICAgICAgICAgICAgIGlmICh0LnN1cGVydHlwZV9maWVsZCA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgVHlwZSBzdXBlcnR5cGUgPSAoKENsYXNzU3ltYm9sKXQudHN5bSkuZ2V0U3VwZXJjbGFzcygpOwogICAgICAgICAgICAgICAgICAgIC8vIEFuIGludGVyZmFjZSBoYXMgbm8gc3VwZXJjbGFzczsgaXRzIHN1cGVydHlwZSBpcyBPYmplY3QuCiAgICAgICAgICAgICAgICAgICAgaWYgKHQuaXNJbnRlcmZhY2UoKSkKICAgICAgICAgICAgICAgICAgICAgICAgc3VwZXJ0eXBlID0gKChDbGFzc1R5cGUpdC50c3ltLnR5cGUpLnN1cGVydHlwZV9maWVsZDsKICAgICAgICAgICAgICAgICAgICBpZiAodC5zdXBlcnR5cGVfZmllbGQgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IGFjdHVhbHMgPSBjbGFzc0JvdW5kKHQpLmFsbHBhcmFtcygpOwogICAgICAgICAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IGZvcm1hbHMgPSB0LnRzeW0udHlwZS5hbGxwYXJhbXMoKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHQuaGFzRXJhc2VkU3VwZXJ0eXBlcygpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0LnN1cGVydHlwZV9maWVsZCA9IGVyYXN1cmVSZWN1cnNpdmUoc3VwZXJ0eXBlKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChmb3JtYWxzLm5vbkVtcHR5KCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHQuc3VwZXJ0eXBlX2ZpZWxkID0gc3Vic3Qoc3VwZXJ0eXBlLCBmb3JtYWxzLCBhY3R1YWxzKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHQuc3VwZXJ0eXBlX2ZpZWxkID0gc3VwZXJ0eXBlOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIHQuc3VwZXJ0eXBlX2ZpZWxkOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogVGhlIHN1cGVydHlwZSBpcyBhbHdheXMgYSBjbGFzcyB0eXBlLiBJZiB0aGUgdHlwZQogICAgICAgICAgICAgKiB2YXJpYWJsZSdzIGJvdW5kcyBzdGFydCB3aXRoIGEgY2xhc3MgdHlwZSwgdGhpcyBpcyBhbHNvCiAgICAgICAgICAgICAqIHRoZSBzdXBlcnR5cGUuICBPdGhlcndpc2UsIHRoZSBzdXBlcnR5cGUgaXMKICAgICAgICAgICAgICogamF2YS5sYW5nLk9iamVjdC4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgVHlwZSB2aXNpdFR5cGVWYXIoVHlwZVZhciB0LCBWb2lkIGlnbm9yZWQpIHsKICAgICAgICAgICAgICAgIGlmICh0LmJvdW5kLmhhc1RhZyhUWVBFVkFSKSB8fAogICAgICAgICAgICAgICAgICAgICghdC5ib3VuZC5pc0NvbXBvdW5kKCkgJiYgIXQuYm91bmQuaXNJbnRlcmZhY2UoKSkpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdC5ib3VuZDsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHN1cGVydHlwZSh0LmJvdW5kKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHB1YmxpYyBUeXBlIHZpc2l0QXJyYXlUeXBlKEFycmF5VHlwZSB0LCBWb2lkIGlnbm9yZWQpIHsKICAgICAgICAgICAgICAgIGlmICh0LmVsZW10eXBlLmlzUHJpbWl0aXZlKCkgfHwgaXNTYW1lVHlwZSh0LmVsZW10eXBlLCBzeW1zLm9iamVjdFR5cGUpKQogICAgICAgICAgICAgICAgICAgIHJldHVybiBhcnJheVN1cGVyVHlwZSgpOwogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgQXJyYXlUeXBlKHN1cGVydHlwZSh0LmVsZW10eXBlKSwgdC50c3ltKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHB1YmxpYyBUeXBlIHZpc2l0RXJyb3JUeXBlKEVycm9yVHlwZSB0LCBWb2lkIGlnbm9yZWQpIHsKICAgICAgICAgICAgICAgIHJldHVybiBUeXBlLm5vVHlwZTsKICAgICAgICAgICAgfQogICAgICAgIH07CiAgICAvLyA8L2VkaXRvci1mb2xkPgoKICAgIC8vIDxlZGl0b3ItZm9sZCBkZWZhdWx0c3RhdGU9ImNvbGxhcHNlZCIgZGVzYz0iaW50ZXJmYWNlcyI+CiAgICAvKioKICAgICAqIFJldHVybiB0aGUgaW50ZXJmYWNlcyBpbXBsZW1lbnRlZCBieSB0aGlzIGNsYXNzLgogICAgICovCiAgICBwdWJsaWMgTGlzdDxUeXBlPiBpbnRlcmZhY2VzKFR5cGUgdCkgewogICAgICAgIHJldHVybiBpbnRlcmZhY2VzLnZpc2l0KHQpOwogICAgfQogICAgLy8gd2hlcmUKICAgICAgICBwcml2YXRlIFVuYXJ5VmlzaXRvcjxMaXN0PFR5cGU+PiBpbnRlcmZhY2VzID0gbmV3IFVuYXJ5VmlzaXRvcjxMaXN0PFR5cGU+PigpIHsKCiAgICAgICAgICAgIHB1YmxpYyBMaXN0PFR5cGU+IHZpc2l0VHlwZShUeXBlIHQsIFZvaWQgaWdub3JlZCkgewogICAgICAgICAgICAgICAgcmV0dXJuIExpc3QubmlsKCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgTGlzdDxUeXBlPiB2aXNpdENsYXNzVHlwZShDbGFzc1R5cGUgdCwgVm9pZCBpZ25vcmVkKSB7CiAgICAgICAgICAgICAgICBpZiAodC5pbnRlcmZhY2VzX2ZpZWxkID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IGludGVyZmFjZXMgPSAoKENsYXNzU3ltYm9sKXQudHN5bSkuZ2V0SW50ZXJmYWNlcygpOwogICAgICAgICAgICAgICAgICAgIGlmICh0LmludGVyZmFjZXNfZmllbGQgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBJZiB0LmludGVyZmFjZXNfZmllbGQgaXMgbnVsbCwgdGhlbiB0IG11c3QKICAgICAgICAgICAgICAgICAgICAgICAgLy8gYmUgYSBwYXJhbWV0ZXJpemVkIHR5cGUgKG5vdCB0byBiZSBjb25mdXNlZAogICAgICAgICAgICAgICAgICAgICAgICAvLyB3aXRoIGEgZ2VuZXJpYyB0eXBlIGRlY2xhcmF0aW9uKS4KICAgICAgICAgICAgICAgICAgICAgICAgLy8gVGVybWlub2xvZ3k6CiAgICAgICAgICAgICAgICAgICAgICAgIC8vICAgIFBhcmFtZXRlcml6ZWQgdHlwZTogTGlzdDxTdHJpbmc+CiAgICAgICAgICAgICAgICAgICAgICAgIC8vICAgIEdlbmVyaWMgdHlwZSBkZWNsYXJhdGlvbjogY2xhc3MgTGlzdDxFPiB7IC4uLiB9CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNvIHQgY29ycmVzcG9uZHMgdG8gTGlzdDxTdHJpbmc+IGFuZAogICAgICAgICAgICAgICAgICAgICAgICAvLyB0LnRzeW0udHlwZSBjb3JyZXNwb25kcyB0byBMaXN0PEU+LgogICAgICAgICAgICAgICAgICAgICAgICAvLyBUaGUgcmVhc29uIHQgbXVzdCBiZSBwYXJhbWV0ZXJpemVkIHR5cGUgaXMKICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhhdCBjb21wbGV0aW9uIHdpbGwgaGFwcGVuIGFzIGEgc2lkZQogICAgICAgICAgICAgICAgICAgICAgICAvLyBlZmZlY3Qgb2YgY2FsbGluZwogICAgICAgICAgICAgICAgICAgICAgICAvLyBDbGFzc1N5bWJvbC5nZXRJbnRlcmZhY2VzLiAgU2luY2UKICAgICAgICAgICAgICAgICAgICAgICAgLy8gdC5pbnRlcmZhY2VzX2ZpZWxkIGlzIG51bGwgYWZ0ZXIKICAgICAgICAgICAgICAgICAgICAgICAgLy8gY29tcGxldGlvbiwgd2UgY2FuIGFzc3VtZSB0aGF0IHQgaXMgbm90IHRoZQogICAgICAgICAgICAgICAgICAgICAgICAvLyB0eXBlIG9mIGEgY2xhc3MvaW50ZXJmYWNlIGRlY2xhcmF0aW9uLgogICAgICAgICAgICAgICAgICAgICAgICBBc3NlcnQuY2hlY2sodCAhPSB0LnRzeW0udHlwZSwgdCk7CiAgICAgICAgICAgICAgICAgICAgICAgIExpc3Q8VHlwZT4gYWN0dWFscyA9IHQuYWxscGFyYW1zKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIExpc3Q8VHlwZT4gZm9ybWFscyA9IHQudHN5bS50eXBlLmFsbHBhcmFtcygpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAodC5oYXNFcmFzZWRTdXBlcnR5cGVzKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHQuaW50ZXJmYWNlc19maWVsZCA9IGVyYXN1cmVSZWN1cnNpdmUoaW50ZXJmYWNlcyk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZm9ybWFscy5ub25FbXB0eSgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0LmludGVyZmFjZXNfZmllbGQgPSBzdWJzdChpbnRlcmZhY2VzLCBmb3JtYWxzLCBhY3R1YWxzKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHQuaW50ZXJmYWNlc19maWVsZCA9IGludGVyZmFjZXM7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gdC5pbnRlcmZhY2VzX2ZpZWxkOwogICAgICAgICAgICB9CgogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHVibGljIExpc3Q8VHlwZT4gdmlzaXRUeXBlVmFyKFR5cGVWYXIgdCwgVm9pZCBpZ25vcmVkKSB7CiAgICAgICAgICAgICAgICBpZiAodC5ib3VuZC5pc0NvbXBvdW5kKCkpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGludGVyZmFjZXModC5ib3VuZCk7CgogICAgICAgICAgICAgICAgaWYgKHQuYm91bmQuaXNJbnRlcmZhY2UoKSkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gTGlzdC5vZih0LmJvdW5kKTsKCiAgICAgICAgICAgICAgICByZXR1cm4gTGlzdC5uaWwoKTsKICAgICAgICAgICAgfQogICAgICAgIH07CgogICAgcHVibGljIExpc3Q8VHlwZT4gZGlyZWN0U3VwZXJ0eXBlcyhUeXBlIHQpIHsKICAgICAgICByZXR1cm4gZGlyZWN0U3VwZXJ0eXBlcy52aXNpdCh0KTsKICAgIH0KICAgIC8vIHdoZXJlCiAgICAgICAgcHJpdmF0ZSBmaW5hbCBVbmFyeVZpc2l0b3I8TGlzdDxUeXBlPj4gZGlyZWN0U3VwZXJ0eXBlcyA9IG5ldyBVbmFyeVZpc2l0b3I8TGlzdDxUeXBlPj4oKSB7CgogICAgICAgICAgICBwdWJsaWMgTGlzdDxUeXBlPiB2aXNpdFR5cGUoZmluYWwgVHlwZSB0eXBlLCBmaW5hbCBWb2lkIGlnbm9yZWQpIHsKICAgICAgICAgICAgICAgIGlmICghdHlwZS5pc0ludGVyc2VjdGlvbigpKSB7CiAgICAgICAgICAgICAgICAgICAgZmluYWwgVHlwZSBzdXAgPSBzdXBlcnR5cGUodHlwZSk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChzdXAgPT0gVHlwZS5ub1R5cGUgfHwgc3VwID09IHR5cGUgfHwgc3VwID09IG51bGwpCiAgICAgICAgICAgICAgICAgICAgICAgID8gaW50ZXJmYWNlcyh0eXBlKQogICAgICAgICAgICAgICAgICAgICAgICA6IGludGVyZmFjZXModHlwZSkucHJlcGVuZChzdXApOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gKChJbnRlcnNlY3Rpb25DbGFzc1R5cGUpdHlwZSkuZ2V0RXhwbGljaXRDb21wb25lbnRzKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9OwoKICAgIHB1YmxpYyBib29sZWFuIGlzRGlyZWN0U3VwZXJJbnRlcmZhY2UoVHlwZVN5bWJvbCBpc3ltLCBUeXBlU3ltYm9sIG9yaWdpbikgewogICAgICAgIGZvciAoVHlwZSBpMiA6IGludGVyZmFjZXMob3JpZ2luLnR5cGUpKSB7CiAgICAgICAgICAgIGlmIChpc3ltID09IGkyLnRzeW0pIHJldHVybiB0cnVlOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CiAgICAvLyA8L2VkaXRvci1mb2xkPgoKICAgIC8vIDxlZGl0b3ItZm9sZCBkZWZhdWx0c3RhdGU9ImNvbGxhcHNlZCIgZGVzYz0iaXNEZXJpdmVkUmF3Ij4KICAgIE1hcDxUeXBlLEJvb2xlYW4+IGlzRGVyaXZlZFJhd0NhY2hlID0gbmV3IEhhc2hNYXA8PigpOwoKICAgIHB1YmxpYyBib29sZWFuIGlzRGVyaXZlZFJhdyhUeXBlIHQpIHsKICAgICAgICBCb29sZWFuIHJlc3VsdCA9IGlzRGVyaXZlZFJhd0NhY2hlLmdldCh0KTsKICAgICAgICBpZiAocmVzdWx0ID09IG51bGwpIHsKICAgICAgICAgICAgcmVzdWx0ID0gaXNEZXJpdmVkUmF3SW50ZXJuYWwodCk7CiAgICAgICAgICAgIGlzRGVyaXZlZFJhd0NhY2hlLnB1dCh0LCByZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgfQoKICAgIHB1YmxpYyBib29sZWFuIGlzRGVyaXZlZFJhd0ludGVybmFsKFR5cGUgdCkgewogICAgICAgIGlmICh0LmlzRXJyb25lb3VzKCkpCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICByZXR1cm4KICAgICAgICAgICAgdC5pc1JhdygpIHx8CiAgICAgICAgICAgIHN1cGVydHlwZSh0KSAhPSBUeXBlLm5vVHlwZSAmJiBpc0Rlcml2ZWRSYXcoc3VwZXJ0eXBlKHQpKSB8fAogICAgICAgICAgICBpc0Rlcml2ZWRSYXcoaW50ZXJmYWNlcyh0KSk7CiAgICB9CgogICAgcHVibGljIGJvb2xlYW4gaXNEZXJpdmVkUmF3KExpc3Q8VHlwZT4gdHMpIHsKICAgICAgICBMaXN0PFR5cGU+IGwgPSB0czsKICAgICAgICB3aGlsZSAobC5ub25FbXB0eSgpICYmICFpc0Rlcml2ZWRSYXcobC5oZWFkKSkgbCA9IGwudGFpbDsKICAgICAgICByZXR1cm4gbC5ub25FbXB0eSgpOwogICAgfQogICAgLy8gPC9lZGl0b3ItZm9sZD4KCiAgICAvLyA8ZWRpdG9yLWZvbGQgZGVmYXVsdHN0YXRlPSJjb2xsYXBzZWQiIGRlc2M9InNldEJvdW5kcyI+CiAgICAvKioKICAgICAqIFNhbWUgYXMge0BsaW5rIFR5cGVzI3NldEJvdW5kcyhUeXBlVmFyLCBMaXN0LCBib29sZWFuKX0sIGV4Y2VwdCB0aGF0IHRoaXJkIHBhcmFtZXRlciBpcyBjb21wdXRlZCBkaXJlY3RseSwKICAgICAqIGFzIGZvbGxvd3M6IGlmIGFsbCBhbGwgYm91bmRzIGFyZSBpbnRlcmZhY2UgdHlwZXMsIHRoZSBjb21wdXRlZCBzdXBlcnR5cGUgaXMgT2JqZWN0LG90aGVyd2lzZQogICAgICogdGhlIHN1cGVydHlwZSBpcyBzaW1wbHkgbGVmdCBudWxsIChpbiB0aGlzIGNhc2UsIHRoZSBzdXBlcnR5cGUgaXMgYXNzdW1lZCB0byBiZSB0aGUgaGVhZCBvZgogICAgICogdGhlIGJvdW5kIGxpc3QgcGFzc2VkIGFzIHNlY29uZCBhcmd1bWVudCkuIE5vdGUgdGhhdCB0aGlzIGNoZWNrIG1pZ2h0IGNhdXNlIGEgc3ltYm9sIGNvbXBsZXRpb24uCiAgICAgKiBIZW5jZSwgdGhpcyB2ZXJzaW9uIG9mIHNldEJvdW5kcyBtYXkgbm90IGJlIGNhbGxlZCBkdXJpbmcgYSBjbGFzc2ZpbGUgcmVhZC4KICAgICAqCiAgICAgKiBAcGFyYW0gdCAgICAgICAgIGEgdHlwZSB2YXJpYWJsZQogICAgICogQHBhcmFtIGJvdW5kcyAgICB0aGUgYm91bmRzLCBtdXN0IGJlIG5vbmVtcHR5CiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHNldEJvdW5kcyhUeXBlVmFyIHQsIExpc3Q8VHlwZT4gYm91bmRzKSB7CiAgICAgICAgc2V0Qm91bmRzKHQsIGJvdW5kcywgYm91bmRzLmhlYWQudHN5bS5pc0ludGVyZmFjZSgpKTsKICAgIH0KCiAgICAvKioKICAgICAqIFNldCB0aGUgYm91bmRzIGZpZWxkIG9mIHRoZSBnaXZlbiB0eXBlIHZhcmlhYmxlIHRvIHJlZmxlY3QgYSAocG9zc2libHkgbXVsdGlwbGUpIGxpc3Qgb2YgYm91bmRzLgogICAgICogVGhpcyBkb2VzIG5vdCBjYXVzZSBzeW1ib2wgY29tcGxldGlvbiBhcyBhbiBleHRyYSBwYXJhbWV0ZXIgaW5kaWNhdGVzIGFzIHRvIHdoZXRoZXIgYWxsIGJvdW5kcwogICAgICogYXJlIGludGVyZmFjZXMgLSBpbiB3aGljaCBjYXNlIHRoZSBzdXBlcnR5cGUgaXMgaW1wbGljaXRseSBhc3N1bWVkIHRvIGJlICdPYmplY3QnLgogICAgICoKICAgICAqIEBwYXJhbSB0ICAgICAgICAgICAgIGEgdHlwZSB2YXJpYWJsZQogICAgICogQHBhcmFtIGJvdW5kcyAgICAgICAgdGhlIGJvdW5kcywgbXVzdCBiZSBub25lbXB0eQogICAgICogQHBhcmFtIGFsbEludGVyZmFjZXMgYXJlIGFsbCBib3VuZHMgaW50ZXJmYWNlIHR5cGVzPwogICAgICovCiAgICBwdWJsaWMgdm9pZCBzZXRCb3VuZHMoVHlwZVZhciB0LCBMaXN0PFR5cGU+IGJvdW5kcywgYm9vbGVhbiBhbGxJbnRlcmZhY2VzKSB7CiAgICAgICAgdC5ib3VuZCA9IGJvdW5kcy50YWlsLmlzRW1wdHkoKSA/CiAgICAgICAgICAgICAgICBib3VuZHMuaGVhZCA6CiAgICAgICAgICAgICAgICBtYWtlSW50ZXJzZWN0aW9uVHlwZShib3VuZHMsIGFsbEludGVyZmFjZXMpOwogICAgICAgIHQucmFua19maWVsZCA9IC0xOwogICAgfQogICAgLy8gPC9lZGl0b3ItZm9sZD4KCiAgICAvLyA8ZWRpdG9yLWZvbGQgZGVmYXVsdHN0YXRlPSJjb2xsYXBzZWQiIGRlc2M9ImdldEJvdW5kcyI+CiAgICAvKioKICAgICAqIFJldHVybiBsaXN0IG9mIGJvdW5kcyBvZiB0aGUgZ2l2ZW4gdHlwZSB2YXJpYWJsZS4KICAgICAqLwogICAgcHVibGljIExpc3Q8VHlwZT4gZ2V0Qm91bmRzKFR5cGVWYXIgdCkgewogICAgICAgIGlmICh0LmJvdW5kLmhhc1RhZyhOT05FKSkKICAgICAgICAgICAgcmV0dXJuIExpc3QubmlsKCk7CiAgICAgICAgZWxzZSBpZiAodC5ib3VuZC5pc0Vycm9uZW91cygpIHx8ICF0LmJvdW5kLmlzQ29tcG91bmQoKSkKICAgICAgICAgICAgcmV0dXJuIExpc3Qub2YodC5ib3VuZCk7CiAgICAgICAgZWxzZSBpZiAoKGVyYXN1cmUodCkudHN5bS5mbGFncygpICYgSU5URVJGQUNFKSA9PSAwKQogICAgICAgICAgICByZXR1cm4gaW50ZXJmYWNlcyh0KS5wcmVwZW5kKHN1cGVydHlwZSh0KSk7CiAgICAgICAgZWxzZQogICAgICAgICAgICAvLyBObyBzdXBlcmNsYXNzIHdhcyBnaXZlbiBpbiBib3VuZHMuCiAgICAgICAgICAgIC8vIEluIHRoaXMgY2FzZSwgc3VwZXJ0eXBlIGlzIE9iamVjdCwgZXJhc3VyZSBpcyBmaXJzdCBpbnRlcmZhY2UuCiAgICAgICAgICAgIHJldHVybiBpbnRlcmZhY2VzKHQpOwogICAgfQogICAgLy8gPC9lZGl0b3ItZm9sZD4KCiAgICAvLyA8ZWRpdG9yLWZvbGQgZGVmYXVsdHN0YXRlPSJjb2xsYXBzZWQiIGRlc2M9ImNsYXNzQm91bmQiPgogICAgLyoqCiAgICAgKiBJZiB0aGUgZ2l2ZW4gdHlwZSBpcyBhIChwb3NzaWJseSBzZWxlY3RlZCkgdHlwZSB2YXJpYWJsZSwKICAgICAqIHJldHVybiB0aGUgYm91bmRpbmcgY2xhc3Mgb2YgdGhpcyB0eXBlLCBvdGhlcndpc2UgcmV0dXJuIHRoZQogICAgICogdHlwZSBpdHNlbGYuCiAgICAgKi8KICAgIHB1YmxpYyBUeXBlIGNsYXNzQm91bmQoVHlwZSB0KSB7CiAgICAgICAgcmV0dXJuIGNsYXNzQm91bmQudmlzaXQodCk7CiAgICB9CiAgICAvLyB3aGVyZQogICAgICAgIHByaXZhdGUgVW5hcnlWaXNpdG9yPFR5cGU+IGNsYXNzQm91bmQgPSBuZXcgVW5hcnlWaXNpdG9yPFR5cGU+KCkgewoKICAgICAgICAgICAgcHVibGljIFR5cGUgdmlzaXRUeXBlKFR5cGUgdCwgVm9pZCBpZ25vcmVkKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHB1YmxpYyBUeXBlIHZpc2l0Q2xhc3NUeXBlKENsYXNzVHlwZSB0LCBWb2lkIGlnbm9yZWQpIHsKICAgICAgICAgICAgICAgIFR5cGUgb3V0ZXIxID0gY2xhc3NCb3VuZCh0LmdldEVuY2xvc2luZ1R5cGUoKSk7CiAgICAgICAgICAgICAgICBpZiAob3V0ZXIxICE9IHQuZ2V0RW5jbG9zaW5nVHlwZSgpKQogICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgQ2xhc3NUeXBlKG91dGVyMSwgdC5nZXRUeXBlQXJndW1lbnRzKCksIHQudHN5bSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0LmdldE1ldGFkYXRhKCkpOwogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHJldHVybiB0OwogICAgICAgICAgICB9CgogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHVibGljIFR5cGUgdmlzaXRUeXBlVmFyKFR5cGVWYXIgdCwgVm9pZCBpZ25vcmVkKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gY2xhc3NCb3VuZChzdXBlcnR5cGUodCkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHVibGljIFR5cGUgdmlzaXRFcnJvclR5cGUoRXJyb3JUeXBlIHQsIFZvaWQgaWdub3JlZCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHQ7CiAgICAgICAgICAgIH0KICAgICAgICB9OwogICAgLy8gPC9lZGl0b3ItZm9sZD4KCiAgICAvLyA8ZWRpdG9yLWZvbGQgZGVmYXVsdHN0YXRlPSJjb2xsYXBzZWQiIGRlc2M9InN1YiBzaWduYXR1cmUgLyBvdmVycmlkZSBlcXVpdmFsZW5jZSI+CiAgICAvKioKICAgICAqIFJldHVybnMgdHJ1ZSBpZmYgdGhlIGZpcnN0IHNpZ25hdHVyZSBpcyBhIDxlbT5zdWIKICAgICAqIHNpZ25hdHVyZTwvZW0+IG9mIHRoZSBvdGhlci4gIFRoaXMgaXMgPGI+bm90PC9iPiBhbiBlcXVpdmFsZW5jZQogICAgICogcmVsYXRpb24uCiAgICAgKgogICAgICogQGpscyBzZWN0aW9uIDguNC4yLgogICAgICogQHNlZSAjb3ZlcnJpZGVFcXVpdmFsZW50KFR5cGUgdCwgVHlwZSBzKQogICAgICogQHBhcmFtIHQgZmlyc3Qgc2lnbmF0dXJlIChwb3NzaWJseSByYXcpLgogICAgICogQHBhcmFtIHMgc2Vjb25kIHNpZ25hdHVyZSAoY291bGQgYmUgc3ViamVjdGVkIHRvIGVyYXN1cmUpLgogICAgICogQHJldHVybiB0cnVlIGlmIHQgaXMgYSBzdWIgc2lnbmF0dXJlIG9mIHMuCiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGlzU3ViU2lnbmF0dXJlKFR5cGUgdCwgVHlwZSBzKSB7CiAgICAgICAgcmV0dXJuIGlzU3ViU2lnbmF0dXJlKHQsIHMsIHRydWUpOwogICAgfQoKICAgIHB1YmxpYyBib29sZWFuIGlzU3ViU2lnbmF0dXJlKFR5cGUgdCwgVHlwZSBzLCBib29sZWFuIHN0cmljdCkgewogICAgICAgIHJldHVybiBoYXNTYW1lQXJncyh0LCBzLCBzdHJpY3QpIHx8IGhhc1NhbWVBcmdzKHQsIGVyYXN1cmUocyksIHN0cmljdCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRydWUgaWZmIHRoZXNlIHNpZ25hdHVyZXMgYXJlIHJlbGF0ZWQgYnkgPGVtPm92ZXJyaWRlCiAgICAgKiBlcXVpdmFsZW5jZTwvZW0+LiAgVGhpcyBpcyB0aGUgbmF0dXJhbCBleHRlbnNpb24gb2YKICAgICAqIGlzU3ViU2lnbmF0dXJlIHRvIGFuIGVxdWl2YWxlbmNlIHJlbGF0aW9uLgogICAgICoKICAgICAqIEBqbHMgc2VjdGlvbiA4LjQuMi4KICAgICAqIEBzZWUgI2lzU3ViU2lnbmF0dXJlKFR5cGUgdCwgVHlwZSBzKQogICAgICogQHBhcmFtIHQgYSBzaWduYXR1cmUgKHBvc3NpYmxlIHJhdywgY291bGQgYmUgc3ViamVjdGVkIHRvCiAgICAgKiBlcmFzdXJlKS4KICAgICAqIEBwYXJhbSBzIGEgc2lnbmF0dXJlIChwb3NzaWJsZSByYXcsIGNvdWxkIGJlIHN1YmplY3RlZCB0bwogICAgICogZXJhc3VyZSkuCiAgICAgKiBAcmV0dXJuIHRydWUgaWYgZWl0aGVyIGFyZ3VtZW50IGlzIGEgc3ViIHNpZ25hdHVyZSBvZiB0aGUgb3RoZXIuCiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIG92ZXJyaWRlRXF1aXZhbGVudChUeXBlIHQsIFR5cGUgcykgewogICAgICAgIHJldHVybiBoYXNTYW1lQXJncyh0LCBzKSB8fAogICAgICAgICAgICBoYXNTYW1lQXJncyh0LCBlcmFzdXJlKHMpKSB8fCBoYXNTYW1lQXJncyhlcmFzdXJlKHQpLCBzKTsKICAgIH0KCiAgICBwdWJsaWMgYm9vbGVhbiBvdmVycmlkZXNPYmplY3RNZXRob2QoVHlwZVN5bWJvbCBvcmlnaW4sIFN5bWJvbCBtc3ltKSB7CiAgICAgICAgZm9yIChTeW1ib2wgc3ltIDogc3ltcy5vYmplY3RUeXBlLnRzeW0ubWVtYmVycygpLmdldFN5bWJvbHNCeU5hbWUobXN5bS5uYW1lKSkgewogICAgICAgICAgICBpZiAobXN5bS5vdmVycmlkZXMoc3ltLCBvcmlnaW4sIFR5cGVzLnRoaXMsIHRydWUpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBUaGlzIGVudW0gZGVmaW5lcyB0aGUgc3RyYXRlZ3kgZm9yIGltcGxlbWVudGluZyBtb3N0IHNwZWNpZmljIHJldHVybiB0eXBlIGNoZWNrCiAgICAgKiBkdXJpbmcgdGhlIG1vc3Qgc3BlY2lmaWMgYW5kIGZ1bmN0aW9uYWwgaW50ZXJmYWNlIGNoZWNrcy4KICAgICAqLwogICAgcHVibGljIGVudW0gTW9zdFNwZWNpZmljUmV0dXJuQ2hlY2sgewogICAgICAgIC8qKgogICAgICAgICAqIFJldHVybiByMSBpcyBtb3JlIHNwZWNpZmljIHRoYW4gcjIgaWYge0Bjb2RlIHIxIDw6IHIyfS4gRXh0cmEgY2FyZSByZXF1aXJlZCBmb3IgKGkpIGhhbmRsaW5nCiAgICAgICAgICogbWV0aG9kIHR5cGUgdmFyaWFibGVzIChpZiBlaXRoZXIgbWV0aG9kIGlzIGdlbmVyaWMpIGFuZCAoaWkpIHN1YnR5cGluZyBzaG91bGQgYmUgcmVwbGFjZWQKICAgICAgICAgKiBieSB0eXBlLWVxdWl2YWxlbmNlIGZvciBwcmltaXRpdmVzLiBUaGlzIGlzIGVzc2VudGlhbGx5IGFuIGlubGluZWQgdmVyc2lvbiBvZgogICAgICAgICAqIHtAbGluayBUeXBlcyNyZXN1bHRTdWJ0eXBlKFR5cGUsIFR5cGUsIFdhcm5lcil9LCB3aGVyZSB0aGUgYXNzaWduYWJpbGl0eSBjaGVjayBoYXMgYmVlbgogICAgICAgICAqIHJlcGxhY2VkIHdpdGggYSBzdHJpY3Qgc3VidHlwaW5nIGNoZWNrLgogICAgICAgICAqLwogICAgICAgIEJBU0lDKCkgewogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHVibGljIGJvb2xlYW4gdGVzdChUeXBlIG10MSwgVHlwZSBtdDIsIFR5cGVzIHR5cGVzKSB7CiAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IHR2YXJzID0gbXQxLmdldFR5cGVBcmd1bWVudHMoKTsKICAgICAgICAgICAgICAgIExpc3Q8VHlwZT4gc3ZhcnMgPSBtdDIuZ2V0VHlwZUFyZ3VtZW50cygpOwogICAgICAgICAgICAgICAgVHlwZSB0ID0gbXQxLmdldFJldHVyblR5cGUoKTsKICAgICAgICAgICAgICAgIFR5cGUgcyA9IHR5cGVzLnN1YnN0KG10Mi5nZXRSZXR1cm5UeXBlKCksIHN2YXJzLCB0dmFycyk7CiAgICAgICAgICAgICAgICByZXR1cm4gdHlwZXMuaXNTYW1lVHlwZSh0LCBzKSB8fAogICAgICAgICAgICAgICAgICAgICF0LmlzUHJpbWl0aXZlKCkgJiYKICAgICAgICAgICAgICAgICAgICAhcy5pc1ByaW1pdGl2ZSgpICYmCiAgICAgICAgICAgICAgICAgICAgdHlwZXMuaXNTdWJ0eXBlKHQsIHMpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAvKioKICAgICAgICAgKiBSZXR1cm4gcjEgaXMgbW9yZSBzcGVjaWZpYyB0aGFuIHIyIGlmIHIxIGlzIHJldHVybi10eXBlLXN1YnN0aXR1dGFibGUgZm9yIHIyLgogICAgICAgICAqLwogICAgICAgIFJUUygpIHsKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHB1YmxpYyBib29sZWFuIHRlc3QoVHlwZSBtdDEsIFR5cGUgbXQyLCBUeXBlcyB0eXBlcykgewogICAgICAgICAgICAgICAgcmV0dXJuIHR5cGVzLnJldHVyblR5cGVTdWJzdGl0dXRhYmxlKG10MSwgbXQyKTsKICAgICAgICAgICAgfQogICAgICAgIH07CgogICAgICAgIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIHRlc3QoVHlwZSBtdDEsIFR5cGUgbXQyLCBUeXBlcyB0eXBlcyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBNZXJnZSBtdWx0aXBsZSBhYnN0cmFjdCBtZXRob2RzLiBUaGUgcHJlZmVycmVkIG1ldGhvZCBpcyBhIG1ldGhvZCB0aGF0IGlzIGEgc3Vic2lnbmF0dXJlCiAgICAgKiBvZiBhbGwgdGhlIG90aGVyIHNpZ25hdHVyZXMgYW5kIHdob3NlIHJldHVybiB0eXBlIGlzIG1vcmUgc3BlY2lmaWMge0BzZWUgTW9zdFNwZWNpZmljUmV0dXJuQ2hlY2t9LgogICAgICogVGhlIHJlc3VsdGluZyBwcmVmZXJyZWQgbWV0aG9kIGhhcyBhIHRocm93biBjbGF1c2UgdGhhdCBpcyB0aGUgaW50ZXJzZWN0aW9uIG9mIHRoZSBtZXJnZWQKICAgICAqIG1ldGhvZHMnIGNsYXVzZXMuCiAgICAgKi8KICAgIHB1YmxpYyBPcHRpb25hbDxTeW1ib2w+IG1lcmdlQWJzdHJhY3RzKExpc3Q8U3ltYm9sPiBhbWJpZ3VvdXNJbk9yZGVyLCBUeXBlIHNpdGUsIGJvb2xlYW4gc2lnQ2hlY2spIHsKICAgICAgICAvL2ZpcnN0IGNoZWNrIGZvciBwcmVjb25kaXRpb25zCiAgICAgICAgYm9vbGVhbiBzaG91bGRFcmFzZSA9IGZhbHNlOwogICAgICAgIExpc3Q8VHlwZT4gZXJhc2VkUGFyYW1zID0gYW1iaWd1b3VzSW5PcmRlci5oZWFkLmVyYXN1cmUodGhpcykuZ2V0UGFyYW1ldGVyVHlwZXMoKTsKICAgICAgICBmb3IgKFN5bWJvbCBzIDogYW1iaWd1b3VzSW5PcmRlcikgewogICAgICAgICAgICBpZiAoKHMuZmxhZ3MoKSAmIEFCU1RSQUNUKSA9PSAwIHx8CiAgICAgICAgICAgICAgICAgICAgKHNpZ0NoZWNrICYmICFpc1NhbWVUeXBlcyhlcmFzZWRQYXJhbXMsIHMuZXJhc3VyZSh0aGlzKS5nZXRQYXJhbWV0ZXJUeXBlcygpKSkpIHsKICAgICAgICAgICAgICAgIHJldHVybiBPcHRpb25hbC5lbXB0eSgpOwogICAgICAgICAgICB9IGVsc2UgaWYgKHMudHlwZS5oYXNUYWcoRk9SQUxMKSkgewogICAgICAgICAgICAgICAgc2hvdWxkRXJhc2UgPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8vdGhlbiBtZXJnZSBhYnN0cmFjdHMKICAgICAgICBmb3IgKE1vc3RTcGVjaWZpY1JldHVybkNoZWNrIG1vc3RTcGVjaWZpY1JldHVybkNoZWNrIDogTW9zdFNwZWNpZmljUmV0dXJuQ2hlY2sudmFsdWVzKCkpIHsKICAgICAgICAgICAgb3V0ZXI6IGZvciAoU3ltYm9sIHMgOiBhbWJpZ3VvdXNJbk9yZGVyKSB7CiAgICAgICAgICAgICAgICBUeXBlIG10ID0gbWVtYmVyVHlwZShzaXRlLCBzKTsKICAgICAgICAgICAgICAgIExpc3Q8VHlwZT4gYWxsVGhyb3duID0gbXQuZ2V0VGhyb3duVHlwZXMoKTsKICAgICAgICAgICAgICAgIGZvciAoU3ltYm9sIHMyIDogYW1iaWd1b3VzSW5PcmRlcikgewogICAgICAgICAgICAgICAgICAgIGlmIChzICE9IHMyKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIFR5cGUgbXQyID0gbWVtYmVyVHlwZShzaXRlLCBzMik7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghaXNTdWJTaWduYXR1cmUobXQsIG10MikgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAhbW9zdFNwZWNpZmljUmV0dXJuQ2hlY2sudGVzdChtdCwgbXQyLCB0aGlzKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9hbWJpZ3VpdHkgY2Fubm90IGJlIHJlc29sdmVkCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZSBvdXRlcjsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIExpc3Q8VHlwZT4gdGhyb3duVHlwZXMyID0gbXQyLmdldFRocm93blR5cGVzKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIW10Lmhhc1RhZyhGT1JBTEwpICYmIHNob3VsZEVyYXNlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3duVHlwZXMyID0gZXJhc3VyZSh0aHJvd25UeXBlczIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChtdC5oYXNUYWcoRk9SQUxMKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vc3Vic2lnbmF0dXJlIGltcGxpZXMgdGhhdCBpZiBtb3N0IHNwZWNpZmljIGlzIGdlbmVyaWMsIHRoZW4gYWxsIG90aGVyCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9tZXRob2RzIGFyZSB0b28KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBc3NlcnQuY2hlY2sobXQyLmhhc1RhZyhGT1JBTEwpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpZiBib3RoIGFyZSBnZW5lcmljIG1ldGhvZHMsIGFkanVzdCB0aHJvd24gdHlwZXMgYWhlYWQgb2YgaW50ZXJzZWN0aW9uIGNvbXB1dGF0aW9uCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3duVHlwZXMyID0gc3Vic3QodGhyb3duVHlwZXMyLCBtdDIuZ2V0VHlwZUFyZ3VtZW50cygpLCBtdC5nZXRUeXBlQXJndW1lbnRzKCkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgYWxsVGhyb3duID0gY2hrLmludGVyc2VjdChhbGxUaHJvd24sIHRocm93blR5cGVzMik7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gKGFsbFRocm93biA9PSBtdC5nZXRUaHJvd25UeXBlcygpKSA/CiAgICAgICAgICAgICAgICAgICAgICAgIE9wdGlvbmFsLm9mKHMpIDoKICAgICAgICAgICAgICAgICAgICAgICAgT3B0aW9uYWwub2YobmV3IE1ldGhvZFN5bWJvbCgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzLmZsYWdzKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcy5uYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNyZWF0ZU1ldGhvZFR5cGVXaXRoVGhyb3duKHMudHlwZSwgYWxsVGhyb3duKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzLm93bmVyKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHB1YmxpYyBTeW1ib2wgYmFzZVN5bWJvbCgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gczsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIE9wdGlvbmFsLmVtcHR5KCk7CiAgICB9CgogICAgLy8gPGVkaXRvci1mb2xkIGRlZmF1bHRzdGF0ZT0iY29sbGFwc2VkIiBkZXNjPSJEZXRlcm1pbmluZyBtZXRob2QgaW1wbGVtZW50YXRpb24gaW4gZ2l2ZW4gc2l0ZSI+CiAgICBjbGFzcyBJbXBsZW1lbnRhdGlvbkNhY2hlIHsKCiAgICAgICAgcHJpdmF0ZSBXZWFrSGFzaE1hcDxNZXRob2RTeW1ib2wsIFNvZnRSZWZlcmVuY2U8TWFwPFR5cGVTeW1ib2wsIEVudHJ5Pj4+IF9tYXAgPSBuZXcgV2Vha0hhc2hNYXA8PigpOwoKICAgICAgICBjbGFzcyBFbnRyeSB7CiAgICAgICAgICAgIGZpbmFsIE1ldGhvZFN5bWJvbCBjYWNoZWRJbXBsOwogICAgICAgICAgICBmaW5hbCBGaWx0ZXI8U3ltYm9sPiBpbXBsRmlsdGVyOwogICAgICAgICAgICBmaW5hbCBib29sZWFuIGNoZWNrUmVzdWx0OwogICAgICAgICAgICBmaW5hbCBpbnQgcHJldk1hcms7CgogICAgICAgICAgICBwdWJsaWMgRW50cnkoTWV0aG9kU3ltYm9sIGNhY2hlZEltcGwsCiAgICAgICAgICAgICAgICAgICAgRmlsdGVyPFN5bWJvbD4gc2NvcGVGaWx0ZXIsCiAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBjaGVja1Jlc3VsdCwKICAgICAgICAgICAgICAgICAgICBpbnQgcHJldk1hcmspIHsKICAgICAgICAgICAgICAgIHRoaXMuY2FjaGVkSW1wbCA9IGNhY2hlZEltcGw7CiAgICAgICAgICAgICAgICB0aGlzLmltcGxGaWx0ZXIgPSBzY29wZUZpbHRlcjsKICAgICAgICAgICAgICAgIHRoaXMuY2hlY2tSZXN1bHQgPSBjaGVja1Jlc3VsdDsKICAgICAgICAgICAgICAgIHRoaXMucHJldk1hcmsgPSBwcmV2TWFyazsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgYm9vbGVhbiBtYXRjaGVzKEZpbHRlcjxTeW1ib2w+IHNjb3BlRmlsdGVyLCBib29sZWFuIGNoZWNrUmVzdWx0LCBpbnQgbWFyaykgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuaW1wbEZpbHRlciA9PSBzY29wZUZpbHRlciAmJgogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNoZWNrUmVzdWx0ID09IGNoZWNrUmVzdWx0ICYmCiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucHJldk1hcmsgPT0gbWFyazsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgTWV0aG9kU3ltYm9sIGdldChNZXRob2RTeW1ib2wgbXMsIFR5cGVTeW1ib2wgb3JpZ2luLCBib29sZWFuIGNoZWNrUmVzdWx0LCBGaWx0ZXI8U3ltYm9sPiBpbXBsRmlsdGVyKSB7CiAgICAgICAgICAgIFNvZnRSZWZlcmVuY2U8TWFwPFR5cGVTeW1ib2wsIEVudHJ5Pj4gcmVmX2NhY2hlID0gX21hcC5nZXQobXMpOwogICAgICAgICAgICBNYXA8VHlwZVN5bWJvbCwgRW50cnk+IGNhY2hlID0gcmVmX2NhY2hlICE9IG51bGwgPyByZWZfY2FjaGUuZ2V0KCkgOiBudWxsOwogICAgICAgICAgICBpZiAoY2FjaGUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgY2FjaGUgPSBuZXcgSGFzaE1hcDw+KCk7CiAgICAgICAgICAgICAgICBfbWFwLnB1dChtcywgbmV3IFNvZnRSZWZlcmVuY2U8PihjYWNoZSkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIEVudHJ5IGUgPSBjYWNoZS5nZXQob3JpZ2luKTsKICAgICAgICAgICAgQ29tcG91bmRTY29wZSBtZW1iZXJzID0gbWVtYmVyc0Nsb3N1cmUob3JpZ2luLnR5cGUsIHRydWUpOwogICAgICAgICAgICBpZiAoZSA9PSBudWxsIHx8CiAgICAgICAgICAgICAgICAgICAgIWUubWF0Y2hlcyhpbXBsRmlsdGVyLCBjaGVja1Jlc3VsdCwgbWVtYmVycy5nZXRNYXJrKCkpKSB7CiAgICAgICAgICAgICAgICBNZXRob2RTeW1ib2wgaW1wbCA9IGltcGxlbWVudGF0aW9uSW50ZXJuYWwobXMsIG9yaWdpbiwgY2hlY2tSZXN1bHQsIGltcGxGaWx0ZXIpOwogICAgICAgICAgICAgICAgY2FjaGUucHV0KG9yaWdpbiwgbmV3IEVudHJ5KGltcGwsIGltcGxGaWx0ZXIsIGNoZWNrUmVzdWx0LCBtZW1iZXJzLmdldE1hcmsoKSkpOwogICAgICAgICAgICAgICAgcmV0dXJuIGltcGw7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZS5jYWNoZWRJbXBsOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIE1ldGhvZFN5bWJvbCBpbXBsZW1lbnRhdGlvbkludGVybmFsKE1ldGhvZFN5bWJvbCBtcywgVHlwZVN5bWJvbCBvcmlnaW4sIGJvb2xlYW4gY2hlY2tSZXN1bHQsIEZpbHRlcjxTeW1ib2w+IGltcGxGaWx0ZXIpIHsKICAgICAgICAgICAgZm9yIChUeXBlIHQgPSBvcmlnaW4udHlwZTsgdC5oYXNUYWcoQ0xBU1MpIHx8IHQuaGFzVGFnKFRZUEVWQVIpOyB0ID0gc3VwZXJ0eXBlKHQpKSB7CiAgICAgICAgICAgICAgICB0ID0gc2tpcFR5cGVWYXJzKHQsIGZhbHNlKTsKICAgICAgICAgICAgICAgIFR5cGVTeW1ib2wgYyA9IHQudHN5bTsKICAgICAgICAgICAgICAgIFN5bWJvbCBiZXN0U29GYXIgPSBudWxsOwogICAgICAgICAgICAgICAgZm9yIChTeW1ib2wgc3ltIDogYy5tZW1iZXJzKCkuZ2V0U3ltYm9sc0J5TmFtZShtcy5uYW1lLCBpbXBsRmlsdGVyKSkgewogICAgICAgICAgICAgICAgICAgIGlmIChzeW0gIT0gbnVsbCAmJiBzeW0ub3ZlcnJpZGVzKG1zLCBvcmlnaW4sIFR5cGVzLnRoaXMsIGNoZWNrUmVzdWx0KSkgewogICAgICAgICAgICAgICAgICAgICAgICBiZXN0U29GYXIgPSBzeW07CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgoc3ltLmZsYWdzKCkgJiBBQlNUUkFDVCkgPT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9pZiBjb25jcmV0ZSBpbXBsIGlzIGZvdW5kLCBleGl0IGltbWVkaWF0ZWx5CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChiZXN0U29GYXIgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIC8vcmV0dXJuIGVpdGhlciB0aGUgKG9ubHkpIGNvbmNyZXRlIGltcGxlbWVudGF0aW9uIG9yIHRoZSBmaXJzdCBhYnN0cmFjdCBvbmUKICAgICAgICAgICAgICAgICAgICByZXR1cm4gKE1ldGhvZFN5bWJvbCliZXN0U29GYXI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgSW1wbGVtZW50YXRpb25DYWNoZSBpbXBsQ2FjaGUgPSBuZXcgSW1wbGVtZW50YXRpb25DYWNoZSgpOwoKICAgIHB1YmxpYyBNZXRob2RTeW1ib2wgaW1wbGVtZW50YXRpb24oTWV0aG9kU3ltYm9sIG1zLCBUeXBlU3ltYm9sIG9yaWdpbiwgYm9vbGVhbiBjaGVja1Jlc3VsdCwgRmlsdGVyPFN5bWJvbD4gaW1wbEZpbHRlcikgewogICAgICAgIHJldHVybiBpbXBsQ2FjaGUuZ2V0KG1zLCBvcmlnaW4sIGNoZWNrUmVzdWx0LCBpbXBsRmlsdGVyKTsKICAgIH0KICAgIC8vIDwvZWRpdG9yLWZvbGQ+CgogICAgLy8gPGVkaXRvci1mb2xkIGRlZmF1bHRzdGF0ZT0iY29sbGFwc2VkIiBkZXNjPSJjb21wdXRlIHRyYW5zaXRpdmUgY2xvc3VyZSBvZiBhbGwgbWVtYmVycyBpbiBnaXZlbiBzaXRlIj4KICAgIGNsYXNzIE1lbWJlcnNDbG9zdXJlQ2FjaGUgZXh0ZW5kcyBTaW1wbGVWaXNpdG9yPFNjb3BlLkNvbXBvdW5kU2NvcGUsIFZvaWQ+IHsKCiAgICAgICAgcHJpdmF0ZSBNYXA8VHlwZVN5bWJvbCwgQ29tcG91bmRTY29wZT4gX21hcCA9IG5ldyBIYXNoTWFwPD4oKTsKCiAgICAgICAgU2V0PFR5cGVTeW1ib2w+IHNlZW5UeXBlcyA9IG5ldyBIYXNoU2V0PD4oKTsKCiAgICAgICAgY2xhc3MgTWVtYmVyc1Njb3BlIGV4dGVuZHMgQ29tcG91bmRTY29wZSB7CgogICAgICAgICAgICBDb21wb3VuZFNjb3BlIHNjb3BlOwoKICAgICAgICAgICAgcHVibGljIE1lbWJlcnNTY29wZShDb21wb3VuZFNjb3BlIHNjb3BlKSB7CiAgICAgICAgICAgICAgICBzdXBlcihzY29wZS5vd25lcik7CiAgICAgICAgICAgICAgICB0aGlzLnNjb3BlID0gc2NvcGU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEZpbHRlcjxTeW1ib2w+IGNvbWJpbmUoRmlsdGVyPFN5bWJvbD4gc2YpIHsKICAgICAgICAgICAgICAgIHJldHVybiBzIC0+ICFzLm93bmVyLmlzSW50ZXJmYWNlKCkgJiYgKHNmID09IG51bGwgfHwgc2YuYWNjZXB0cyhzKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgSXRlcmFibGU8U3ltYm9sPiBnZXRTeW1ib2xzKEZpbHRlcjxTeW1ib2w+IHNmLCBMb29rdXBLaW5kIGxvb2t1cEtpbmQpIHsKICAgICAgICAgICAgICAgIHJldHVybiBzY29wZS5nZXRTeW1ib2xzKGNvbWJpbmUoc2YpLCBsb29rdXBLaW5kKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHB1YmxpYyBJdGVyYWJsZTxTeW1ib2w+IGdldFN5bWJvbHNCeU5hbWUoTmFtZSBuYW1lLCBGaWx0ZXI8U3ltYm9sPiBzZiwgTG9va3VwS2luZCBsb29rdXBLaW5kKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gc2NvcGUuZ2V0U3ltYm9sc0J5TmFtZShuYW1lLCBjb21iaW5lKHNmKSwgbG9va3VwS2luZCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgaW50IGdldE1hcmsoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gc2NvcGUuZ2V0TWFyaygpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBDb21wb3VuZFNjb3BlIG5pbFNjb3BlOwoKICAgICAgICAvKiogbWVtYmVycyBjbG9zdXJlIHZpc2l0b3IgbWV0aG9kcyAqKi8KCiAgICAgICAgcHVibGljIENvbXBvdW5kU2NvcGUgdmlzaXRUeXBlKFR5cGUgdCwgVm9pZCBfdW51c2VkKSB7CiAgICAgICAgICAgIGlmIChuaWxTY29wZSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICBuaWxTY29wZSA9IG5ldyBDb21wb3VuZFNjb3BlKHN5bXMubm9TeW1ib2wpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBuaWxTY29wZTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBDb21wb3VuZFNjb3BlIHZpc2l0Q2xhc3NUeXBlKENsYXNzVHlwZSB0LCBWb2lkIF91bnVzZWQpIHsKICAgICAgICAgICAgaWYgKCFzZWVuVHlwZXMuYWRkKHQudHN5bSkpIHsKICAgICAgICAgICAgICAgIC8vdGhpcyBpcyBwb3NzaWJsZSB3aGVuIGFuIGludGVyZmFjZSBpcyBpbXBsZW1lbnRlZCBpbiBtdWx0aXBsZQogICAgICAgICAgICAgICAgLy9zdXBlcmNsYXNzZXMsIG9yIHdoZW4gYSBjbGFzcyBoaWVyYXJjaHkgaXMgY2lyY3VsYXIgLSBpbiBzdWNoCiAgICAgICAgICAgICAgICAvL2Nhc2VzIHdlIGRvbid0IG5lZWQgdG8gcmVjdXJzZSAoZW1wdHkgc2NvcGUgaXMgcmV0dXJuZWQpCiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IENvbXBvdW5kU2NvcGUodC50c3ltKTsKICAgICAgICAgICAgfQogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgc2VlblR5cGVzLmFkZCh0LnRzeW0pOwogICAgICAgICAgICAgICAgQ2xhc3NTeW1ib2wgY3N5bSA9IChDbGFzc1N5bWJvbCl0LnRzeW07CiAgICAgICAgICAgICAgICBDb21wb3VuZFNjb3BlIG1lbWJlcnNDbG9zdXJlID0gX21hcC5nZXQoY3N5bSk7CiAgICAgICAgICAgICAgICBpZiAobWVtYmVyc0Nsb3N1cmUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIG1lbWJlcnNDbG9zdXJlID0gbmV3IENvbXBvdW5kU2NvcGUoY3N5bSk7CiAgICAgICAgICAgICAgICAgICAgZm9yIChUeXBlIGkgOiBpbnRlcmZhY2VzKHQpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIG1lbWJlcnNDbG9zdXJlLnByZXBlbmRTdWJTY29wZSh2aXNpdChpLCBudWxsKSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIG1lbWJlcnNDbG9zdXJlLnByZXBlbmRTdWJTY29wZSh2aXNpdChzdXBlcnR5cGUodCksIG51bGwpKTsKICAgICAgICAgICAgICAgICAgICBtZW1iZXJzQ2xvc3VyZS5wcmVwZW5kU3ViU2NvcGUoY3N5bS5tZW1iZXJzKCkpOwogICAgICAgICAgICAgICAgICAgIF9tYXAucHV0KGNzeW0sIG1lbWJlcnNDbG9zdXJlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBtZW1iZXJzQ2xvc3VyZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBmaW5hbGx5IHsKICAgICAgICAgICAgICAgIHNlZW5UeXBlcy5yZW1vdmUodC50c3ltKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIENvbXBvdW5kU2NvcGUgdmlzaXRUeXBlVmFyKFR5cGVWYXIgdCwgVm9pZCBfdW51c2VkKSB7CiAgICAgICAgICAgIHJldHVybiB2aXNpdCh0LmdldFVwcGVyQm91bmQoKSwgbnVsbCk7CiAgICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgTWVtYmVyc0Nsb3N1cmVDYWNoZSBtZW1iZXJzQ2FjaGUgPSBuZXcgTWVtYmVyc0Nsb3N1cmVDYWNoZSgpOwoKICAgIHB1YmxpYyBDb21wb3VuZFNjb3BlIG1lbWJlcnNDbG9zdXJlKFR5cGUgc2l0ZSwgYm9vbGVhbiBza2lwSW50ZXJmYWNlKSB7CiAgICAgICAgQ29tcG91bmRTY29wZSBjcyA9IG1lbWJlcnNDYWNoZS52aXNpdChzaXRlLCBudWxsKTsKICAgICAgICBBc3NlcnQuY2hlY2tOb25OdWxsKGNzLCAoKSAtPiAidHlwZSAiICsgc2l0ZSk7CiAgICAgICAgcmV0dXJuIHNraXBJbnRlcmZhY2UgPyBtZW1iZXJzQ2FjaGUubmV3IE1lbWJlcnNTY29wZShjcykgOiBjczsKICAgIH0KICAgIC8vIDwvZWRpdG9yLWZvbGQ+CgoKICAgIC8qKiBSZXR1cm4gZmlyc3QgYWJzdHJhY3QgbWVtYmVyIG9mIGNsYXNzIGBzeW0nLgogICAgICovCiAgICBwdWJsaWMgTWV0aG9kU3ltYm9sIGZpcnN0VW5pbXBsZW1lbnRlZEFic3RyYWN0KENsYXNzU3ltYm9sIHN5bSkgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIHJldHVybiBmaXJzdFVuaW1wbGVtZW50ZWRBYnN0cmFjdEltcGwoc3ltLCBzeW0pOwogICAgICAgIH0gY2F0Y2ggKENvbXBsZXRpb25GYWlsdXJlIGV4KSB7CiAgICAgICAgICAgIGNoay5jb21wbGV0aW9uRXJyb3IoZW50ZXIuZ2V0RW52KHN5bSkudHJlZS5wb3MoKSwgZXgpOwogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICB9CiAgICAgICAgLy93aGVyZToKICAgICAgICBwcml2YXRlIE1ldGhvZFN5bWJvbCBmaXJzdFVuaW1wbGVtZW50ZWRBYnN0cmFjdEltcGwoQ2xhc3NTeW1ib2wgaW1wbCwgQ2xhc3NTeW1ib2wgYykgewogICAgICAgICAgICBNZXRob2RTeW1ib2wgdW5kZWYgPSBudWxsOwogICAgICAgICAgICAvLyBEbyBub3QgYm90aGVyIHRvIHNlYXJjaCBpbiBjbGFzc2VzIHRoYXQgYXJlIG5vdCBhYnN0cmFjdCwKICAgICAgICAgICAgLy8gc2luY2UgdGhleSBjYW5ub3QgaGF2ZSBhYnN0cmFjdCBtZW1iZXJzLgogICAgICAgICAgICBpZiAoYyA9PSBpbXBsIHx8IChjLmZsYWdzKCkgJiAoQUJTVFJBQ1QgfCBJTlRFUkZBQ0UpKSAhPSAwKSB7CiAgICAgICAgICAgICAgICBTY29wZSBzID0gYy5tZW1iZXJzKCk7CiAgICAgICAgICAgICAgICBmb3IgKFN5bWJvbCBzeW0gOiBzLmdldFN5bWJvbHMoTk9OX1JFQ1VSU0lWRSkpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoc3ltLmtpbmQgPT0gTVRIICYmCiAgICAgICAgICAgICAgICAgICAgICAgIChzeW0uZmxhZ3MoKSAmIChBQlNUUkFDVHxERUZBVUxUfFBSSVZBVEUpKSA9PSBBQlNUUkFDVCkgewogICAgICAgICAgICAgICAgICAgICAgICBNZXRob2RTeW1ib2wgYWJzbWV0aCA9IChNZXRob2RTeW1ib2wpc3ltOwogICAgICAgICAgICAgICAgICAgICAgICBNZXRob2RTeW1ib2wgaW1wbG1ldGggPSBhYnNtZXRoLmltcGxlbWVudGF0aW9uKGltcGwsIHRoaXMsIHRydWUpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW1wbG1ldGggPT0gbnVsbCB8fCBpbXBsbWV0aCA9PSBhYnNtZXRoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2xvb2sgZm9yIGRlZmF1bHQgaW1wbGVtZW50YXRpb25zCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYWxsb3dEZWZhdWx0TWV0aG9kcykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1ldGhvZFN5bWJvbCBwcm92ID0gaW50ZXJmYWNlQ2FuZGlkYXRlcyhpbXBsLnR5cGUsIGFic21ldGgpLmhlYWQ7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHByb3YgIT0gbnVsbCAmJiBwcm92Lm92ZXJyaWRlcyhhYnNtZXRoLCBpbXBsLCB0aGlzLCB0cnVlKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbXBsbWV0aCA9IHByb3Y7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpbXBsbWV0aCA9PSBudWxsIHx8IGltcGxtZXRoID09IGFic21ldGgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuZGVmID0gYWJzbWV0aDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKHVuZGVmID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICBUeXBlIHN0ID0gc3VwZXJ0eXBlKGMudHlwZSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKHN0Lmhhc1RhZyhDTEFTUykpCiAgICAgICAgICAgICAgICAgICAgICAgIHVuZGVmID0gZmlyc3RVbmltcGxlbWVudGVkQWJzdHJhY3RJbXBsKGltcGwsIChDbGFzc1N5bWJvbClzdC50c3ltKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGZvciAoTGlzdDxUeXBlPiBsID0gaW50ZXJmYWNlcyhjLnR5cGUpOwogICAgICAgICAgICAgICAgICAgICB1bmRlZiA9PSBudWxsICYmIGwubm9uRW1wdHkoKTsKICAgICAgICAgICAgICAgICAgICAgbCA9IGwudGFpbCkgewogICAgICAgICAgICAgICAgICAgIHVuZGVmID0gZmlyc3RVbmltcGxlbWVudGVkQWJzdHJhY3RJbXBsKGltcGwsIChDbGFzc1N5bWJvbClsLmhlYWQudHN5bSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHVuZGVmOwogICAgICAgIH0KCiAgICBwdWJsaWMgY2xhc3MgQ2FuZGlkYXRlc0NhY2hlIHsKICAgICAgICBwdWJsaWMgTWFwPEVudHJ5LCBMaXN0PE1ldGhvZFN5bWJvbD4+IGNhY2hlID0gbmV3IFdlYWtIYXNoTWFwPD4oKTsKCiAgICAgICAgY2xhc3MgRW50cnkgewogICAgICAgICAgICBUeXBlIHNpdGU7CiAgICAgICAgICAgIE1ldGhvZFN5bWJvbCBtc3ltOwoKICAgICAgICAgICAgRW50cnkoVHlwZSBzaXRlLCBNZXRob2RTeW1ib2wgbXN5bSkgewogICAgICAgICAgICAgICAgdGhpcy5zaXRlID0gc2l0ZTsKICAgICAgICAgICAgICAgIHRoaXMubXN5bSA9IG1zeW07CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iaikgewogICAgICAgICAgICAgICAgaWYgKG9iaiBpbnN0YW5jZW9mIEVudHJ5KSB7CiAgICAgICAgICAgICAgICAgICAgRW50cnkgZSA9IChFbnRyeSlvYmo7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGUubXN5bSA9PSBtc3ltICYmIGlzU2FtZVR5cGUoc2l0ZSwgZS5zaXRlKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgICAgICAgICAgIHJldHVybiBUeXBlcy50aGlzLmhhc2hDb2RlKHNpdGUpICYgfm1zeW0uaGFzaENvZGUoKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHVibGljIExpc3Q8TWV0aG9kU3ltYm9sPiBnZXQoRW50cnkgZSkgewogICAgICAgICAgICByZXR1cm4gY2FjaGUuZ2V0KGUpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHZvaWQgcHV0KEVudHJ5IGUsIExpc3Q8TWV0aG9kU3ltYm9sPiBtc3ltYm9scykgewogICAgICAgICAgICBjYWNoZS5wdXQoZSwgbXN5bWJvbHMpOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgQ2FuZGlkYXRlc0NhY2hlIGNhbmRpZGF0ZXNDYWNoZSA9IG5ldyBDYW5kaWRhdGVzQ2FjaGUoKTsKCiAgICAvL3doZXJlCiAgICBwdWJsaWMgTGlzdDxNZXRob2RTeW1ib2w+IGludGVyZmFjZUNhbmRpZGF0ZXMoVHlwZSBzaXRlLCBNZXRob2RTeW1ib2wgbXMpIHsKICAgICAgICBDYW5kaWRhdGVzQ2FjaGUuRW50cnkgZSA9IGNhbmRpZGF0ZXNDYWNoZS5uZXcgRW50cnkoc2l0ZSwgbXMpOwogICAgICAgIExpc3Q8TWV0aG9kU3ltYm9sPiBjYW5kaWRhdGVzID0gY2FuZGlkYXRlc0NhY2hlLmdldChlKTsKICAgICAgICBpZiAoY2FuZGlkYXRlcyA9PSBudWxsKSB7CiAgICAgICAgICAgIEZpbHRlcjxTeW1ib2w+IGZpbHRlciA9IG5ldyBNZXRob2RGaWx0ZXIobXMsIHNpdGUpOwogICAgICAgICAgICBMaXN0PE1ldGhvZFN5bWJvbD4gY2FuZGlkYXRlczIgPSBMaXN0Lm5pbCgpOwogICAgICAgICAgICBmb3IgKFN5bWJvbCBzIDogbWVtYmVyc0Nsb3N1cmUoc2l0ZSwgZmFsc2UpLmdldFN5bWJvbHMoZmlsdGVyKSkgewogICAgICAgICAgICAgICAgaWYgKCFzaXRlLnRzeW0uaXNJbnRlcmZhY2UoKSAmJiAhcy5vd25lci5pc0ludGVyZmFjZSgpKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIExpc3Qub2YoKE1ldGhvZFN5bWJvbClzKTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoIWNhbmRpZGF0ZXMyLmNvbnRhaW5zKHMpKSB7CiAgICAgICAgICAgICAgICAgICAgY2FuZGlkYXRlczIgPSBjYW5kaWRhdGVzMi5wcmVwZW5kKChNZXRob2RTeW1ib2wpcyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY2FuZGlkYXRlcyA9IHBydW5lKGNhbmRpZGF0ZXMyKTsKICAgICAgICAgICAgY2FuZGlkYXRlc0NhY2hlLnB1dChlLCBjYW5kaWRhdGVzKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGNhbmRpZGF0ZXM7CiAgICB9CgogICAgcHVibGljIExpc3Q8TWV0aG9kU3ltYm9sPiBwcnVuZShMaXN0PE1ldGhvZFN5bWJvbD4gbWV0aG9kcykgewogICAgICAgIExpc3RCdWZmZXI8TWV0aG9kU3ltYm9sPiBtZXRob2RzTWluID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgIGZvciAoTWV0aG9kU3ltYm9sIG0xIDogbWV0aG9kcykgewogICAgICAgICAgICBib29sZWFuIGlzTWluX20xID0gdHJ1ZTsKICAgICAgICAgICAgZm9yIChNZXRob2RTeW1ib2wgbTIgOiBtZXRob2RzKSB7CiAgICAgICAgICAgICAgICBpZiAobTEgPT0gbTIpIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgaWYgKG0yLm93bmVyICE9IG0xLm93bmVyICYmCiAgICAgICAgICAgICAgICAgICAgICAgIGFzU3VwZXIobTIub3duZXIudHlwZSwgbTEub3duZXIpICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICBpc01pbl9tMSA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChpc01pbl9tMSkKICAgICAgICAgICAgICAgIG1ldGhvZHNNaW4uYXBwZW5kKG0xKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1ldGhvZHNNaW4udG9MaXN0KCk7CiAgICB9CiAgICAvLyB3aGVyZQogICAgICAgICAgICBwcml2YXRlIGNsYXNzIE1ldGhvZEZpbHRlciBpbXBsZW1lbnRzIEZpbHRlcjxTeW1ib2w+IHsKCiAgICAgICAgICAgICAgICBTeW1ib2wgbXN5bTsKICAgICAgICAgICAgICAgIFR5cGUgc2l0ZTsKCiAgICAgICAgICAgICAgICBNZXRob2RGaWx0ZXIoU3ltYm9sIG1zeW0sIFR5cGUgc2l0ZSkgewogICAgICAgICAgICAgICAgICAgIHRoaXMubXN5bSA9IG1zeW07CiAgICAgICAgICAgICAgICAgICAgdGhpcy5zaXRlID0gc2l0ZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBwdWJsaWMgYm9vbGVhbiBhY2NlcHRzKFN5bWJvbCBzKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHMua2luZCA9PSBNVEggJiYKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHMubmFtZSA9PSBtc3ltLm5hbWUgJiYKICAgICAgICAgICAgICAgICAgICAgICAgICAgIChzLmZsYWdzKCkgJiBTWU5USEVUSUMpID09IDAgJiYKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHMuaXNJbmhlcml0ZWRJbihzaXRlLnRzeW0sIFR5cGVzLnRoaXMpICYmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdmVycmlkZUVxdWl2YWxlbnQobWVtYmVyVHlwZShzaXRlLCBzKSwgbWVtYmVyVHlwZShzaXRlLCBtc3ltKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgIC8vIDwvZWRpdG9yLWZvbGQ+CgogICAgLyoqCiAgICAgKiBEb2VzIHQgaGF2ZSB0aGUgc2FtZSBhcmd1bWVudHMgYXMgcz8gIEl0IGlzIGFzc3VtZWQgdGhhdCBib3RoCiAgICAgKiB0eXBlcyBhcmUgKHBvc3NpYmx5IHBvbHltb3JwaGljKSBtZXRob2QgdHlwZXMuICBNb25vbW9ycGhpYwogICAgICogbWV0aG9kIHR5cGVzICJoYXZlIHRoZSBzYW1lIGFyZ3VtZW50cyIsIGlmIHRoZWlyIGFyZ3VtZW50IGxpc3RzCiAgICAgKiBhcmUgZXF1YWwuICBQb2x5bW9ycGhpYyBtZXRob2QgdHlwZXMgImhhdmUgdGhlIHNhbWUgYXJndW1lbnRzIiwKICAgICAqIGlmIHRoZXkgaGF2ZSB0aGUgc2FtZSBhcmd1bWVudHMgYWZ0ZXIgcmVuYW1pbmcgYWxsIHR5cGUKICAgICAqIHZhcmlhYmxlcyBvZiBvbmUgdG8gY29ycmVzcG9uZGluZyB0eXBlIHZhcmlhYmxlcyBpbiB0aGUgb3RoZXIsCiAgICAgKiB3aGVyZSBjb3JyZXNwb25kZW5jZSBpcyBieSBwb3NpdGlvbiBpbiB0aGUgdHlwZSBwYXJhbWV0ZXIgbGlzdC4KICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gaGFzU2FtZUFyZ3MoVHlwZSB0LCBUeXBlIHMpIHsKICAgICAgICByZXR1cm4gaGFzU2FtZUFyZ3ModCwgcywgdHJ1ZSk7CiAgICB9CgogICAgcHVibGljIGJvb2xlYW4gaGFzU2FtZUFyZ3MoVHlwZSB0LCBUeXBlIHMsIGJvb2xlYW4gc3RyaWN0KSB7CiAgICAgICAgcmV0dXJuIGhhc1NhbWVBcmdzKHQsIHMsIHN0cmljdCA/IGhhc1NhbWVBcmdzX3N0cmljdCA6IGhhc1NhbWVBcmdzX25vbnN0cmljdCk7CiAgICB9CgogICAgcHJpdmF0ZSBib29sZWFuIGhhc1NhbWVBcmdzKFR5cGUgdCwgVHlwZSBzLCBUeXBlUmVsYXRpb24gaGFzU2FtZUFyZ3MpIHsKICAgICAgICByZXR1cm4gaGFzU2FtZUFyZ3MudmlzaXQodCwgcyk7CiAgICB9CiAgICAvLyB3aGVyZQogICAgICAgIHByaXZhdGUgY2xhc3MgSGFzU2FtZUFyZ3MgZXh0ZW5kcyBUeXBlUmVsYXRpb24gewoKICAgICAgICAgICAgYm9vbGVhbiBzdHJpY3Q7CgogICAgICAgICAgICBwdWJsaWMgSGFzU2FtZUFyZ3MoYm9vbGVhbiBzdHJpY3QpIHsKICAgICAgICAgICAgICAgIHRoaXMuc3RyaWN0ID0gc3RyaWN0OwogICAgICAgICAgICB9CgogICAgICAgICAgICBwdWJsaWMgQm9vbGVhbiB2aXNpdFR5cGUoVHlwZSB0LCBUeXBlIHMpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHVibGljIEJvb2xlYW4gdmlzaXRNZXRob2RUeXBlKE1ldGhvZFR5cGUgdCwgVHlwZSBzKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gcy5oYXNUYWcoTUVUSE9EKQogICAgICAgICAgICAgICAgICAgICYmIGNvbnRhaW5zVHlwZUVxdWl2YWxlbnQodC5hcmd0eXBlcywgcy5nZXRQYXJhbWV0ZXJUeXBlcygpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHB1YmxpYyBCb29sZWFuIHZpc2l0Rm9yQWxsKEZvckFsbCB0LCBUeXBlIHMpIHsKICAgICAgICAgICAgICAgIGlmICghcy5oYXNUYWcoRk9SQUxMKSkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3RyaWN0ID8gZmFsc2UgOiB2aXNpdE1ldGhvZFR5cGUodC5hc01ldGhvZFR5cGUoKSwgcyk7CgogICAgICAgICAgICAgICAgRm9yQWxsIGZvckFsbCA9IChGb3JBbGwpczsKICAgICAgICAgICAgICAgIHJldHVybiBoYXNTYW1lQm91bmRzKHQsIGZvckFsbCkKICAgICAgICAgICAgICAgICAgICAmJiB2aXNpdCh0LnF0eXBlLCBzdWJzdChmb3JBbGwucXR5cGUsIGZvckFsbC50dmFycywgdC50dmFycykpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHVibGljIEJvb2xlYW4gdmlzaXRFcnJvclR5cGUoRXJyb3JUeXBlIHQsIFR5cGUgcykgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgIFR5cGVSZWxhdGlvbiBoYXNTYW1lQXJnc19zdHJpY3QgPSBuZXcgSGFzU2FtZUFyZ3ModHJ1ZSk7CiAgICAgICAgVHlwZVJlbGF0aW9uIGhhc1NhbWVBcmdzX25vbnN0cmljdCA9IG5ldyBIYXNTYW1lQXJncyhmYWxzZSk7CgogICAgLy8gPC9lZGl0b3ItZm9sZD4KCiAgICAvLyA8ZWRpdG9yLWZvbGQgZGVmYXVsdHN0YXRlPSJjb2xsYXBzZWQiIGRlc2M9InN1YnN0Ij4KICAgIHB1YmxpYyBMaXN0PFR5cGU+IHN1YnN0KExpc3Q8VHlwZT4gdHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IGZyb20sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IHRvKSB7CiAgICAgICAgcmV0dXJuIHRzLm1hcChuZXcgU3Vic3QoZnJvbSwgdG8pKTsKICAgIH0KCiAgICAvKioKICAgICAqIFN1YnN0aXR1dGUgYWxsIG9jY3VycmVuY2VzIG9mIGEgdHlwZSBpbiBgZnJvbScgd2l0aCB0aGUKICAgICAqIGNvcnJlc3BvbmRpbmcgdHlwZSBpbiBgdG8nIGluICd0Jy4gTWF0Y2ggbGlzdHMgYGZyb20nIGFuZCBgdG8nCiAgICAgKiBmcm9tIHRoZSByaWdodDogSWYgbGlzdHMgaGF2ZSBkaWZmZXJlbnQgbGVuZ3RoLCBkaXNjYXJkIGxlYWRpbmcKICAgICAqIGVsZW1lbnRzIG9mIHRoZSBsb25nZXIgbGlzdC4KICAgICAqLwogICAgcHVibGljIFR5cGUgc3Vic3QoVHlwZSB0LCBMaXN0PFR5cGU+IGZyb20sIExpc3Q8VHlwZT4gdG8pIHsKICAgICAgICByZXR1cm4gdC5tYXAobmV3IFN1YnN0KGZyb20sIHRvKSk7CiAgICB9CgogICAgcHJpdmF0ZSBjbGFzcyBTdWJzdCBleHRlbmRzIFN0cnVjdHVyYWxUeXBlTWFwcGluZzxWb2lkPiB7CiAgICAgICAgTGlzdDxUeXBlPiBmcm9tOwogICAgICAgIExpc3Q8VHlwZT4gdG87CgogICAgICAgIHB1YmxpYyBTdWJzdChMaXN0PFR5cGU+IGZyb20sIExpc3Q8VHlwZT4gdG8pIHsKICAgICAgICAgICAgaW50IGZyb21MZW5ndGggPSBmcm9tLmxlbmd0aCgpOwogICAgICAgICAgICBpbnQgdG9MZW5ndGggPSB0by5sZW5ndGgoKTsKICAgICAgICAgICAgd2hpbGUgKGZyb21MZW5ndGggPiB0b0xlbmd0aCkgewogICAgICAgICAgICAgICAgZnJvbUxlbmd0aC0tOwogICAgICAgICAgICAgICAgZnJvbSA9IGZyb20udGFpbDsKICAgICAgICAgICAgfQogICAgICAgICAgICB3aGlsZSAoZnJvbUxlbmd0aCA8IHRvTGVuZ3RoKSB7CiAgICAgICAgICAgICAgICB0b0xlbmd0aC0tOwogICAgICAgICAgICAgICAgdG8gPSB0by50YWlsOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHRoaXMuZnJvbSA9IGZyb207CiAgICAgICAgICAgIHRoaXMudG8gPSB0bzsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBUeXBlIHZpc2l0VHlwZVZhcihUeXBlVmFyIHQsIFZvaWQgaWdub3JlZCkgewogICAgICAgICAgICBmb3IgKExpc3Q8VHlwZT4gZnJvbSA9IHRoaXMuZnJvbSwgdG8gPSB0aGlzLnRvOwogICAgICAgICAgICAgICAgIGZyb20ubm9uRW1wdHkoKTsKICAgICAgICAgICAgICAgICBmcm9tID0gZnJvbS50YWlsLCB0byA9IHRvLnRhaWwpIHsKICAgICAgICAgICAgICAgIGlmICh0LmVxdWFsc0lnbm9yZU1ldGFkYXRhKGZyb20uaGVhZCkpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdG8uaGVhZC53aXRoVHlwZVZhcih0KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gdDsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBUeXBlIHZpc2l0Q2xhc3NUeXBlKENsYXNzVHlwZSB0LCBWb2lkIGlnbm9yZWQpIHsKICAgICAgICAgICAgaWYgKCF0LmlzQ29tcG91bmQoKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIHN1cGVyLnZpc2l0Q2xhc3NUeXBlKHQsIGlnbm9yZWQpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgVHlwZSBzdCA9IHZpc2l0KHN1cGVydHlwZSh0KSk7CiAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IGlzID0gdmlzaXQoaW50ZXJmYWNlcyh0KSwgaWdub3JlZCk7CiAgICAgICAgICAgICAgICBpZiAoc3QgPT0gc3VwZXJ0eXBlKHQpICYmIGlzID09IGludGVyZmFjZXModCkpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHQ7CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG1ha2VJbnRlcnNlY3Rpb25UeXBlKGlzLnByZXBlbmQoc3QpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFR5cGUgdmlzaXRXaWxkY2FyZFR5cGUoV2lsZGNhcmRUeXBlIHQsIFZvaWQgaWdub3JlZCkgewogICAgICAgICAgICBXaWxkY2FyZFR5cGUgdDIgPSAoV2lsZGNhcmRUeXBlKXN1cGVyLnZpc2l0V2lsZGNhcmRUeXBlKHQsIGlnbm9yZWQpOwogICAgICAgICAgICBpZiAodDIgIT0gdCAmJiB0LmlzRXh0ZW5kc0JvdW5kKCkgJiYgdDIudHlwZS5pc0V4dGVuZHNCb3VuZCgpKSB7CiAgICAgICAgICAgICAgICB0Mi50eXBlID0gd2lsZFVwcGVyQm91bmQodDIudHlwZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHQyOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFR5cGUgdmlzaXRGb3JBbGwoRm9yQWxsIHQsIFZvaWQgaWdub3JlZCkgewogICAgICAgICAgICBpZiAoVHlwZS5jb250YWluc0FueSh0bywgdC50dmFycykpIHsKICAgICAgICAgICAgICAgIC8vcGVyZm9ybSBhbHBoYS1yZW5hbWluZyBvZiBmcmVlLXZhcmlhYmxlcyBpbiAndCcKICAgICAgICAgICAgICAgIC8vaWYgJ3RvJyB0eXBlcyBjb250YWluIHZhcmlhYmxlcyB0aGF0IGFyZSBmcmVlIGluICd0JwogICAgICAgICAgICAgICAgTGlzdDxUeXBlPiBmcmVldmFycyA9IG5ld0luc3RhbmNlcyh0LnR2YXJzKTsKICAgICAgICAgICAgICAgIHQgPSBuZXcgRm9yQWxsKGZyZWV2YXJzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVHlwZXMudGhpcy5zdWJzdCh0LnF0eXBlLCB0LnR2YXJzLCBmcmVldmFycykpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIExpc3Q8VHlwZT4gdHZhcnMxID0gc3Vic3RCb3VuZHModC50dmFycywgZnJvbSwgdG8pOwogICAgICAgICAgICBUeXBlIHF0eXBlMSA9IHZpc2l0KHQucXR5cGUpOwogICAgICAgICAgICBpZiAodHZhcnMxID09IHQudHZhcnMgJiYgcXR5cGUxID09IHQucXR5cGUpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0OwogICAgICAgICAgICB9IGVsc2UgaWYgKHR2YXJzMSA9PSB0LnR2YXJzKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEZvckFsbCh0dmFyczEsIHF0eXBlMSkgewogICAgICAgICAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICAgICAgICAgIHB1YmxpYyBib29sZWFuIG5lZWRzU3RyaXBwaW5nKCkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBGb3JBbGwodHZhcnMxLCBUeXBlcy50aGlzLnN1YnN0KHF0eXBlMSwgdC50dmFycywgdHZhcnMxKSkgewogICAgICAgICAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICAgICAgICAgIHB1YmxpYyBib29sZWFuIG5lZWRzU3RyaXBwaW5nKCkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBMaXN0PFR5cGU+IHN1YnN0Qm91bmRzKExpc3Q8VHlwZT4gdHZhcnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IGZyb20sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IHRvKSB7CiAgICAgICAgaWYgKHR2YXJzLmlzRW1wdHkoKSkKICAgICAgICAgICAgcmV0dXJuIHR2YXJzOwogICAgICAgIExpc3RCdWZmZXI8VHlwZT4gbmV3Qm91bmRzQnVmID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgIGJvb2xlYW4gY2hhbmdlZCA9IGZhbHNlOwogICAgICAgIC8vIGNhbGN1bGF0ZSBuZXcgYm91bmRzCiAgICAgICAgZm9yIChUeXBlIHQgOiB0dmFycykgewogICAgICAgICAgICBUeXBlVmFyIHR2ID0gKFR5cGVWYXIpIHQ7CiAgICAgICAgICAgIFR5cGUgYm91bmQgPSBzdWJzdCh0di5ib3VuZCwgZnJvbSwgdG8pOwogICAgICAgICAgICBpZiAoYm91bmQgIT0gdHYuYm91bmQpCiAgICAgICAgICAgICAgICBjaGFuZ2VkID0gdHJ1ZTsKICAgICAgICAgICAgbmV3Qm91bmRzQnVmLmFwcGVuZChib3VuZCk7CiAgICAgICAgfQogICAgICAgIGlmICghY2hhbmdlZCkKICAgICAgICAgICAgcmV0dXJuIHR2YXJzOwogICAgICAgIExpc3RCdWZmZXI8VHlwZT4gbmV3VHZhcnMgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgLy8gY3JlYXRlIG5ldyB0eXBlIHZhcmlhYmxlcyB3aXRob3V0IGJvdW5kcwogICAgICAgIGZvciAoVHlwZSB0IDogdHZhcnMpIHsKICAgICAgICAgICAgbmV3VHZhcnMuYXBwZW5kKG5ldyBUeXBlVmFyKHQudHN5bSwgbnVsbCwgc3ltcy5ib3RUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdC5nZXRNZXRhZGF0YSgpKSk7CiAgICAgICAgfQogICAgICAgIC8vIHRoZSBuZXcgYm91bmRzIHNob3VsZCB1c2UgdGhlIG5ldyB0eXBlIHZhcmlhYmxlcyBpbiBwbGFjZQogICAgICAgIC8vIG9mIHRoZSBvbGQKICAgICAgICBMaXN0PFR5cGU+IG5ld0JvdW5kcyA9IG5ld0JvdW5kc0J1Zi50b0xpc3QoKTsKICAgICAgICBmcm9tID0gdHZhcnM7CiAgICAgICAgdG8gPSBuZXdUdmFycy50b0xpc3QoKTsKICAgICAgICBmb3IgKDsgIW5ld0JvdW5kcy5pc0VtcHR5KCk7IG5ld0JvdW5kcyA9IG5ld0JvdW5kcy50YWlsKSB7CiAgICAgICAgICAgIG5ld0JvdW5kcy5oZWFkID0gc3Vic3QobmV3Qm91bmRzLmhlYWQsIGZyb20sIHRvKTsKICAgICAgICB9CiAgICAgICAgbmV3Qm91bmRzID0gbmV3Qm91bmRzQnVmLnRvTGlzdCgpOwogICAgICAgIC8vIHNldCB0aGUgYm91bmRzIG9mIG5ldyB0eXBlIHZhcmlhYmxlcyB0byB0aGUgbmV3IGJvdW5kcwogICAgICAgIGZvciAoVHlwZSB0IDogbmV3VHZhcnMudG9MaXN0KCkpIHsKICAgICAgICAgICAgVHlwZVZhciB0diA9IChUeXBlVmFyKSB0OwogICAgICAgICAgICB0di5ib3VuZCA9IG5ld0JvdW5kcy5oZWFkOwogICAgICAgICAgICBuZXdCb3VuZHMgPSBuZXdCb3VuZHMudGFpbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG5ld1R2YXJzLnRvTGlzdCgpOwogICAgfQoKICAgIHB1YmxpYyBUeXBlVmFyIHN1YnN0Qm91bmQoVHlwZVZhciB0LCBMaXN0PFR5cGU+IGZyb20sIExpc3Q8VHlwZT4gdG8pIHsKICAgICAgICBUeXBlIGJvdW5kMSA9IHN1YnN0KHQuYm91bmQsIGZyb20sIHRvKTsKICAgICAgICBpZiAoYm91bmQxID09IHQuYm91bmQpCiAgICAgICAgICAgIHJldHVybiB0OwogICAgICAgIGVsc2UgewogICAgICAgICAgICAvLyBjcmVhdGUgbmV3IHR5cGUgdmFyaWFibGUgd2l0aG91dCBib3VuZHMKICAgICAgICAgICAgVHlwZVZhciB0diA9IG5ldyBUeXBlVmFyKHQudHN5bSwgbnVsbCwgc3ltcy5ib3RUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdC5nZXRNZXRhZGF0YSgpKTsKICAgICAgICAgICAgLy8gdGhlIG5ldyBib3VuZCBzaG91bGQgdXNlIHRoZSBuZXcgdHlwZSB2YXJpYWJsZSBpbiBwbGFjZQogICAgICAgICAgICAvLyBvZiB0aGUgb2xkCiAgICAgICAgICAgIHR2LmJvdW5kID0gc3Vic3QoYm91bmQxLCBMaXN0Lm9mKHQpLCBMaXN0Lm9mKHR2KSk7CiAgICAgICAgICAgIHJldHVybiB0djsKICAgICAgICB9CiAgICB9CiAgICAvLyA8L2VkaXRvci1mb2xkPgoKICAgIC8vIDxlZGl0b3ItZm9sZCBkZWZhdWx0c3RhdGU9ImNvbGxhcHNlZCIgZGVzYz0iaGFzU2FtZUJvdW5kcyI+CiAgICAvKioKICAgICAqIERvZXMgdCBoYXZlIHRoZSBzYW1lIGJvdW5kcyBmb3IgcXVhbnRpZmllZCB2YXJpYWJsZXMgYXMgcz8KICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gaGFzU2FtZUJvdW5kcyhGb3JBbGwgdCwgRm9yQWxsIHMpIHsKICAgICAgICBMaXN0PFR5cGU+IGwxID0gdC50dmFyczsKICAgICAgICBMaXN0PFR5cGU+IGwyID0gcy50dmFyczsKICAgICAgICB3aGlsZSAobDEubm9uRW1wdHkoKSAmJiBsMi5ub25FbXB0eSgpICYmCiAgICAgICAgICAgICAgIGlzU2FtZVR5cGUobDEuaGVhZC5nZXRVcHBlckJvdW5kKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgc3Vic3QobDIuaGVhZC5nZXRVcHBlckJvdW5kKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcy50dmFycywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0LnR2YXJzKSkpIHsKICAgICAgICAgICAgbDEgPSBsMS50YWlsOwogICAgICAgICAgICBsMiA9IGwyLnRhaWw7CiAgICAgICAgfQogICAgICAgIHJldHVybiBsMS5pc0VtcHR5KCkgJiYgbDIuaXNFbXB0eSgpOwogICAgfQogICAgLy8gPC9lZGl0b3ItZm9sZD4KCiAgICAvLyA8ZWRpdG9yLWZvbGQgZGVmYXVsdHN0YXRlPSJjb2xsYXBzZWQiIGRlc2M9Im5ld0luc3RhbmNlcyI+CiAgICAvKiogQ3JlYXRlIG5ldyB2ZWN0b3Igb2YgdHlwZSB2YXJpYWJsZXMgZnJvbSBsaXN0IG9mIHZhcmlhYmxlcwogICAgICogIGNoYW5naW5nIGFsbCByZWN1cnNpdmUgYm91bmRzIGZyb20gb2xkIHRvIG5ldyBsaXN0LgogICAgICovCiAgICBwdWJsaWMgTGlzdDxUeXBlPiBuZXdJbnN0YW5jZXMoTGlzdDxUeXBlPiB0dmFycykgewogICAgICAgIExpc3Q8VHlwZT4gdHZhcnMxID0gdHZhcnMubWFwKG5ld0luc3RhbmNlRnVuKTsKICAgICAgICBmb3IgKExpc3Q8VHlwZT4gbCA9IHR2YXJzMTsgbC5ub25FbXB0eSgpOyBsID0gbC50YWlsKSB7CiAgICAgICAgICAgIFR5cGVWYXIgdHYgPSAoVHlwZVZhcikgbC5oZWFkOwogICAgICAgICAgICB0di5ib3VuZCA9IHN1YnN0KHR2LmJvdW5kLCB0dmFycywgdHZhcnMxKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHR2YXJzMTsKICAgIH0KICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBUeXBlTWFwcGluZzxWb2lkPiBuZXdJbnN0YW5jZUZ1biA9IG5ldyBUeXBlTWFwcGluZzxWb2lkPigpIHsKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHB1YmxpYyBUeXBlVmFyIHZpc2l0VHlwZVZhcihUeXBlVmFyIHQsIFZvaWQgX3VudXNlZCkgewogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBUeXBlVmFyKHQudHN5bSwgdC5nZXRVcHBlckJvdW5kKCksIHQuZ2V0TG93ZXJCb3VuZCgpLCB0LmdldE1ldGFkYXRhKCkpOwogICAgICAgICAgICB9CiAgICAgICAgfTsKICAgIC8vIDwvZWRpdG9yLWZvbGQ+CgogICAgcHVibGljIFR5cGUgY3JlYXRlTWV0aG9kVHlwZVdpdGhQYXJhbWV0ZXJzKFR5cGUgb3JpZ2luYWwsIExpc3Q8VHlwZT4gbmV3UGFyYW1zKSB7CiAgICAgICAgcmV0dXJuIG9yaWdpbmFsLmFjY2VwdChtZXRob2RXaXRoUGFyYW1ldGVycywgbmV3UGFyYW1zKTsKICAgIH0KICAgIC8vIHdoZXJlCiAgICAgICAgcHJpdmF0ZSBmaW5hbCBNYXBWaXNpdG9yPExpc3Q8VHlwZT4+IG1ldGhvZFdpdGhQYXJhbWV0ZXJzID0gbmV3IE1hcFZpc2l0b3I8TGlzdDxUeXBlPj4oKSB7CiAgICAgICAgICAgIHB1YmxpYyBUeXBlIHZpc2l0VHlwZShUeXBlIHQsIExpc3Q8VHlwZT4gbmV3UGFyYW1zKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJOb3QgYSBtZXRob2QgdHlwZTogIiArIHQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHB1YmxpYyBUeXBlIHZpc2l0TWV0aG9kVHlwZShNZXRob2RUeXBlIHQsIExpc3Q8VHlwZT4gbmV3UGFyYW1zKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IE1ldGhvZFR5cGUobmV3UGFyYW1zLCB0LnJlc3R5cGUsIHQudGhyb3duLCB0LnRzeW0pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHB1YmxpYyBUeXBlIHZpc2l0Rm9yQWxsKEZvckFsbCB0LCBMaXN0PFR5cGU+IG5ld1BhcmFtcykgewogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBGb3JBbGwodC50dmFycywgdC5xdHlwZS5hY2NlcHQodGhpcywgbmV3UGFyYW1zKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9OwoKICAgIHB1YmxpYyBUeXBlIGNyZWF0ZU1ldGhvZFR5cGVXaXRoVGhyb3duKFR5cGUgb3JpZ2luYWwsIExpc3Q8VHlwZT4gbmV3VGhyb3duKSB7CiAgICAgICAgcmV0dXJuIG9yaWdpbmFsLmFjY2VwdChtZXRob2RXaXRoVGhyb3duLCBuZXdUaHJvd24pOwogICAgfQogICAgLy8gd2hlcmUKICAgICAgICBwcml2YXRlIGZpbmFsIE1hcFZpc2l0b3I8TGlzdDxUeXBlPj4gbWV0aG9kV2l0aFRocm93biA9IG5ldyBNYXBWaXNpdG9yPExpc3Q8VHlwZT4+KCkgewogICAgICAgICAgICBwdWJsaWMgVHlwZSB2aXNpdFR5cGUoVHlwZSB0LCBMaXN0PFR5cGU+IG5ld1Rocm93bikgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiTm90IGEgbWV0aG9kIHR5cGU6ICIgKyB0KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBwdWJsaWMgVHlwZSB2aXNpdE1ldGhvZFR5cGUoTWV0aG9kVHlwZSB0LCBMaXN0PFR5cGU+IG5ld1Rocm93bikgewogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBNZXRob2RUeXBlKHQuYXJndHlwZXMsIHQucmVzdHlwZSwgbmV3VGhyb3duLCB0LnRzeW0pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHB1YmxpYyBUeXBlIHZpc2l0Rm9yQWxsKEZvckFsbCB0LCBMaXN0PFR5cGU+IG5ld1Rocm93bikgewogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBGb3JBbGwodC50dmFycywgdC5xdHlwZS5hY2NlcHQodGhpcywgbmV3VGhyb3duKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9OwoKICAgIHB1YmxpYyBUeXBlIGNyZWF0ZU1ldGhvZFR5cGVXaXRoUmV0dXJuKFR5cGUgb3JpZ2luYWwsIFR5cGUgbmV3UmV0dXJuKSB7CiAgICAgICAgcmV0dXJuIG9yaWdpbmFsLmFjY2VwdChtZXRob2RXaXRoUmV0dXJuLCBuZXdSZXR1cm4pOwogICAgfQogICAgLy8gd2hlcmUKICAgICAgICBwcml2YXRlIGZpbmFsIE1hcFZpc2l0b3I8VHlwZT4gbWV0aG9kV2l0aFJldHVybiA9IG5ldyBNYXBWaXNpdG9yPFR5cGU+KCkgewogICAgICAgICAgICBwdWJsaWMgVHlwZSB2aXNpdFR5cGUoVHlwZSB0LCBUeXBlIG5ld1JldHVybikgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiTm90IGEgbWV0aG9kIHR5cGU6ICIgKyB0KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBwdWJsaWMgVHlwZSB2aXNpdE1ldGhvZFR5cGUoTWV0aG9kVHlwZSB0LCBUeXBlIG5ld1JldHVybikgewogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBNZXRob2RUeXBlKHQuYXJndHlwZXMsIG5ld1JldHVybiwgdC50aHJvd24sIHQudHN5bSkgewogICAgICAgICAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICAgICAgICAgIHB1YmxpYyBUeXBlIGJhc2VUeXBlKCkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICB9CiAgICAgICAgICAgIHB1YmxpYyBUeXBlIHZpc2l0Rm9yQWxsKEZvckFsbCB0LCBUeXBlIG5ld1JldHVybikgewogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBGb3JBbGwodC50dmFycywgdC5xdHlwZS5hY2NlcHQodGhpcywgbmV3UmV0dXJuKSkgewogICAgICAgICAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICAgICAgICAgIHB1YmxpYyBUeXBlIGJhc2VUeXBlKCkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICB9CiAgICAgICAgfTsKCiAgICAvLyA8ZWRpdG9yLWZvbGQgZGVmYXVsdHN0YXRlPSJjb2xsYXBzZWQiIGRlc2M9ImNyZWF0ZUVycm9yVHlwZSI+CiAgICBwdWJsaWMgVHlwZSBjcmVhdGVFcnJvclR5cGUoVHlwZSBvcmlnaW5hbFR5cGUpIHsKICAgICAgICByZXR1cm4gbmV3IEVycm9yVHlwZShvcmlnaW5hbFR5cGUsIHN5bXMuZXJyU3ltYm9sKTsKICAgIH0KCiAgICBwdWJsaWMgVHlwZSBjcmVhdGVFcnJvclR5cGUoQ2xhc3NTeW1ib2wgYywgVHlwZSBvcmlnaW5hbFR5cGUpIHsKICAgICAgICByZXR1cm4gbmV3IEVycm9yVHlwZShjLCBvcmlnaW5hbFR5cGUpOwogICAgfQoKICAgIHB1YmxpYyBUeXBlIGNyZWF0ZUVycm9yVHlwZShOYW1lIG5hbWUsIFR5cGVTeW1ib2wgY29udGFpbmVyLCBUeXBlIG9yaWdpbmFsVHlwZSkgewogICAgICAgIHJldHVybiBuZXcgRXJyb3JUeXBlKG5hbWUsIGNvbnRhaW5lciwgb3JpZ2luYWxUeXBlKTsKICAgIH0KICAgIC8vIDwvZWRpdG9yLWZvbGQ+CgogICAgLy8gPGVkaXRvci1mb2xkIGRlZmF1bHRzdGF0ZT0iY29sbGFwc2VkIiBkZXNjPSJyYW5rIj4KICAgIC8qKgogICAgICogVGhlIHJhbmsgb2YgYSBjbGFzcyBpcyB0aGUgbGVuZ3RoIG9mIHRoZSBsb25nZXN0IHBhdGggYmV0d2VlbgogICAgICogdGhlIGNsYXNzIGFuZCBqYXZhLmxhbmcuT2JqZWN0IGluIHRoZSBjbGFzcyBpbmhlcml0YW5jZQogICAgICogZ3JhcGguIFVuZGVmaW5lZCBmb3IgYWxsIGJ1dCByZWZlcmVuY2UgdHlwZXMuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgcmFuayhUeXBlIHQpIHsKICAgICAgICBzd2l0Y2godC5nZXRUYWcoKSkgewogICAgICAgIGNhc2UgQ0xBU1M6IHsKICAgICAgICAgICAgQ2xhc3NUeXBlIGNscyA9IChDbGFzc1R5cGUpdDsKICAgICAgICAgICAgaWYgKGNscy5yYW5rX2ZpZWxkIDwgMCkgewogICAgICAgICAgICAgICAgTmFtZSBmdWxsbmFtZSA9IGNscy50c3ltLmdldFF1YWxpZmllZE5hbWUoKTsKICAgICAgICAgICAgICAgIGlmIChmdWxsbmFtZSA9PSBuYW1lcy5qYXZhX2xhbmdfT2JqZWN0KQogICAgICAgICAgICAgICAgICAgIGNscy5yYW5rX2ZpZWxkID0gMDsKICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgIGludCByID0gcmFuayhzdXBlcnR5cGUoY2xzKSk7CiAgICAgICAgICAgICAgICAgICAgZm9yIChMaXN0PFR5cGU+IGwgPSBpbnRlcmZhY2VzKGNscyk7CiAgICAgICAgICAgICAgICAgICAgICAgICBsLm5vbkVtcHR5KCk7CiAgICAgICAgICAgICAgICAgICAgICAgICBsID0gbC50YWlsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyYW5rKGwuaGVhZCkgPiByKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgciA9IHJhbmsobC5oZWFkKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgY2xzLnJhbmtfZmllbGQgPSByICsgMTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gY2xzLnJhbmtfZmllbGQ7CiAgICAgICAgfQogICAgICAgIGNhc2UgVFlQRVZBUjogewogICAgICAgICAgICBUeXBlVmFyIHR2YXIgPSAoVHlwZVZhcil0OwogICAgICAgICAgICBpZiAodHZhci5yYW5rX2ZpZWxkIDwgMCkgewogICAgICAgICAgICAgICAgaW50IHIgPSByYW5rKHN1cGVydHlwZSh0dmFyKSk7CiAgICAgICAgICAgICAgICBmb3IgKExpc3Q8VHlwZT4gbCA9IGludGVyZmFjZXModHZhcik7CiAgICAgICAgICAgICAgICAgICAgIGwubm9uRW1wdHkoKTsKICAgICAgICAgICAgICAgICAgICAgbCA9IGwudGFpbCkgewogICAgICAgICAgICAgICAgICAgIGlmIChyYW5rKGwuaGVhZCkgPiByKSByID0gcmFuayhsLmhlYWQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdHZhci5yYW5rX2ZpZWxkID0gciArIDE7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHR2YXIucmFua19maWVsZDsKICAgICAgICB9CiAgICAgICAgY2FzZSBFUlJPUjoKICAgICAgICBjYXNlIE5PTkU6CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigpOwogICAgICAgIH0KICAgIH0KICAgIC8vIDwvZWRpdG9yLWZvbGQ+CgogICAgLyoqCiAgICAgKiBIZWxwZXIgbWV0aG9kIGZvciBnZW5lcmF0aW5nIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIGEgZ2l2ZW4gdHlwZQogICAgICogYWNjb3JkaW5nbHkgdG8gYSBnaXZlbiBsb2NhbGUKICAgICAqLwogICAgcHVibGljIFN0cmluZyB0b1N0cmluZyhUeXBlIHQsIExvY2FsZSBsb2NhbGUpIHsKICAgICAgICByZXR1cm4gUHJpbnRlci5jcmVhdGVTdGFuZGFyZFByaW50ZXIobWVzc2FnZXMpLnZpc2l0KHQsIGxvY2FsZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBIZWxwZXIgbWV0aG9kIGZvciBnZW5lcmF0aW5nIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIGEgZ2l2ZW4gdHlwZQogICAgICogYWNjb3JkaW5nbHkgdG8gYSBnaXZlbiBsb2NhbGUKICAgICAqLwogICAgcHVibGljIFN0cmluZyB0b1N0cmluZyhTeW1ib2wgdCwgTG9jYWxlIGxvY2FsZSkgewogICAgICAgIHJldHVybiBQcmludGVyLmNyZWF0ZVN0YW5kYXJkUHJpbnRlcihtZXNzYWdlcykudmlzaXQodCwgbG9jYWxlKTsKICAgIH0KCiAgICAvLyA8ZWRpdG9yLWZvbGQgZGVmYXVsdHN0YXRlPSJjb2xsYXBzZWQiIGRlc2M9InRvU3RyaW5nIj4KICAgIC8qKgogICAgICogVGhpcyB0b1N0cmluZyBpcyBzbGlnaHRseSBtb3JlIGRlc2NyaXB0aXZlIHRoYW4gdGhlIG9uZSBvbiBUeXBlLgogICAgICoKICAgICAqIEBkZXByZWNhdGVkIFR5cGVzLnRvU3RyaW5nKFR5cGUgdCwgTG9jYWxlIGwpIHByb3ZpZGVzIGJldHRlciBzdXBwb3J0CiAgICAgKiBmb3IgbG9jYWxpemF0aW9uCiAgICAgKi8KICAgIEBEZXByZWNhdGVkCiAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKFR5cGUgdCkgewogICAgICAgIGlmICh0Lmhhc1RhZyhGT1JBTEwpKSB7CiAgICAgICAgICAgIEZvckFsbCBmb3JBbGwgPSAoRm9yQWxsKXQ7CiAgICAgICAgICAgIHJldHVybiB0eXBhcmFtc1N0cmluZyhmb3JBbGwudHZhcnMpICsgZm9yQWxsLnF0eXBlOwogICAgICAgIH0KICAgICAgICByZXR1cm4gIiIgKyB0OwogICAgfQogICAgLy8gd2hlcmUKICAgICAgICBwcml2YXRlIFN0cmluZyB0eXBhcmFtc1N0cmluZyhMaXN0PFR5cGU+IHR2YXJzKSB7CiAgICAgICAgICAgIFN0cmluZ0J1aWxkZXIgcyA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CiAgICAgICAgICAgIHMuYXBwZW5kKCc8Jyk7CiAgICAgICAgICAgIGJvb2xlYW4gZmlyc3QgPSB0cnVlOwogICAgICAgICAgICBmb3IgKFR5cGUgdCA6IHR2YXJzKSB7CiAgICAgICAgICAgICAgICBpZiAoIWZpcnN0KSBzLmFwcGVuZCgiLCAiKTsKICAgICAgICAgICAgICAgIGZpcnN0ID0gZmFsc2U7CiAgICAgICAgICAgICAgICBhcHBlbmRUeXBhcmFtU3RyaW5nKCgoVHlwZVZhcil0KSwgcyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcy5hcHBlbmQoJz4nKTsKICAgICAgICAgICAgcmV0dXJuIHMudG9TdHJpbmcoKTsKICAgICAgICB9CiAgICAgICAgcHJpdmF0ZSB2b2lkIGFwcGVuZFR5cGFyYW1TdHJpbmcoVHlwZVZhciB0LCBTdHJpbmdCdWlsZGVyIGJ1ZikgewogICAgICAgICAgICBidWYuYXBwZW5kKHQpOwogICAgICAgICAgICBpZiAodC5ib3VuZCA9PSBudWxsIHx8CiAgICAgICAgICAgICAgICB0LmJvdW5kLnRzeW0uZ2V0UXVhbGlmaWVkTmFtZSgpID09IG5hbWVzLmphdmFfbGFuZ19PYmplY3QpCiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIGJ1Zi5hcHBlbmQoIiBleHRlbmRzICIpOyAvLyBKYXZhIHN5bnRheDsgbm8gbmVlZCBmb3IgaTE4bgogICAgICAgICAgICBUeXBlIGJvdW5kID0gdC5ib3VuZDsKICAgICAgICAgICAgaWYgKCFib3VuZC5pc0NvbXBvdW5kKCkpIHsKICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQoYm91bmQpOwogICAgICAgICAgICB9IGVsc2UgaWYgKChlcmFzdXJlKHQpLnRzeW0uZmxhZ3MoKSAmIElOVEVSRkFDRSkgPT0gMCkgewogICAgICAgICAgICAgICAgYnVmLmFwcGVuZChzdXBlcnR5cGUodCkpOwogICAgICAgICAgICAgICAgZm9yIChUeXBlIGludGYgOiBpbnRlcmZhY2VzKHQpKSB7CiAgICAgICAgICAgICAgICAgICAgYnVmLmFwcGVuZCgnJicpOwogICAgICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQoaW50Zik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvLyBObyBzdXBlcmNsYXNzIHdhcyBnaXZlbiBpbiBib3VuZHMuCiAgICAgICAgICAgICAgICAvLyBJbiB0aGlzIGNhc2UsIHN1cGVydHlwZSBpcyBPYmplY3QsIGVyYXN1cmUgaXMgZmlyc3QgaW50ZXJmYWNlLgogICAgICAgICAgICAgICAgYm9vbGVhbiBmaXJzdCA9IHRydWU7CiAgICAgICAgICAgICAgICBmb3IgKFR5cGUgaW50ZiA6IGludGVyZmFjZXModCkpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoIWZpcnN0KSBidWYuYXBwZW5kKCcmJyk7CiAgICAgICAgICAgICAgICAgICAgZmlyc3QgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICBidWYuYXBwZW5kKGludGYpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgLy8gPC9lZGl0b3ItZm9sZD4KCiAgICAvLyA8ZWRpdG9yLWZvbGQgZGVmYXVsdHN0YXRlPSJjb2xsYXBzZWQiIGRlc2M9IkRldGVybWluaW5nIGxlYXN0IHVwcGVyIGJvdW5kcyBvZiB0eXBlcyI+CiAgICAvKioKICAgICAqIEEgY2FjaGUgZm9yIGNsb3N1cmVzLgogICAgICoKICAgICAqIDxwPkEgY2xvc3VyZSBpcyBhIGxpc3Qgb2YgYWxsIHRoZSBzdXBlcnR5cGVzIGFuZCBpbnRlcmZhY2VzIG9mCiAgICAgKiBhIGNsYXNzIG9yIGludGVyZmFjZSB0eXBlLCBvcmRlcmVkIGJ5IENsYXNzU3ltYm9sLnByZWNlZGVzCiAgICAgKiAodGhhdCBpcywgc3ViY2xhc3NlcyBjb21lIGZpcnN0LCBhcmJpdHJhcnkgYnV0IGZpeGVkCiAgICAgKiBvdGhlcndpc2UpLgogICAgICovCiAgICBwcml2YXRlIE1hcDxUeXBlLExpc3Q8VHlwZT4+IGNsb3N1cmVDYWNoZSA9IG5ldyBIYXNoTWFwPD4oKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGNsb3N1cmUgb2YgYSBjbGFzcyBvciBpbnRlcmZhY2UgdHlwZS4KICAgICAqLwogICAgcHVibGljIExpc3Q8VHlwZT4gY2xvc3VyZShUeXBlIHQpIHsKICAgICAgICBMaXN0PFR5cGU+IGNsID0gY2xvc3VyZUNhY2hlLmdldCh0KTsKICAgICAgICBpZiAoY2wgPT0gbnVsbCkgewogICAgICAgICAgICBUeXBlIHN0ID0gc3VwZXJ0eXBlKHQpOwogICAgICAgICAgICBpZiAoIXQuaXNDb21wb3VuZCgpKSB7CiAgICAgICAgICAgICAgICBpZiAoc3QuaGFzVGFnKENMQVNTKSkgewogICAgICAgICAgICAgICAgICAgIGNsID0gaW5zZXJ0KGNsb3N1cmUoc3QpLCB0KTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoc3QuaGFzVGFnKFRZUEVWQVIpKSB7CiAgICAgICAgICAgICAgICAgICAgY2wgPSBjbG9zdXJlKHN0KS5wcmVwZW5kKHQpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBjbCA9IExpc3Qub2YodCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBjbCA9IGNsb3N1cmUoc3VwZXJ0eXBlKHQpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBmb3IgKExpc3Q8VHlwZT4gbCA9IGludGVyZmFjZXModCk7IGwubm9uRW1wdHkoKTsgbCA9IGwudGFpbCkKICAgICAgICAgICAgICAgIGNsID0gdW5pb24oY2wsIGNsb3N1cmUobC5oZWFkKSk7CiAgICAgICAgICAgIGNsb3N1cmVDYWNoZS5wdXQodCwgY2wpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gY2w7CiAgICB9CgogICAgLyoqCiAgICAgKiBDb2xsZWN0IHR5cGVzIGludG8gYSBuZXcgY2xvc3VyZSAodXNpbmcgYSBAY29kZXtDbG9zdXJlSG9sZGVyfSkKICAgICAqLwogICAgcHVibGljIENvbGxlY3RvcjxUeXBlLCBDbG9zdXJlSG9sZGVyLCBMaXN0PFR5cGU+PiBjbG9zdXJlQ29sbGVjdG9yKGJvb2xlYW4gbWluQ2xvc3VyZSwgQmlQcmVkaWNhdGU8VHlwZSwgVHlwZT4gc2hvdWxkU2tpcCkgewogICAgICAgIHJldHVybiBDb2xsZWN0b3Iub2YoKCkgLT4gbmV3IENsb3N1cmVIb2xkZXIobWluQ2xvc3VyZSwgc2hvdWxkU2tpcCksCiAgICAgICAgICAgICAgICBDbG9zdXJlSG9sZGVyOjphZGQsCiAgICAgICAgICAgICAgICBDbG9zdXJlSG9sZGVyOjptZXJnZSwKICAgICAgICAgICAgICAgIENsb3N1cmVIb2xkZXI6OmNsb3N1cmUpOwogICAgfQogICAgLy93aGVyZQogICAgICAgIGNsYXNzIENsb3N1cmVIb2xkZXIgewogICAgICAgICAgICBMaXN0PFR5cGU+IGNsb3N1cmU7CiAgICAgICAgICAgIGZpbmFsIGJvb2xlYW4gbWluQ2xvc3VyZTsKICAgICAgICAgICAgZmluYWwgQmlQcmVkaWNhdGU8VHlwZSwgVHlwZT4gc2hvdWxkU2tpcDsKCiAgICAgICAgICAgIENsb3N1cmVIb2xkZXIoYm9vbGVhbiBtaW5DbG9zdXJlLCBCaVByZWRpY2F0ZTxUeXBlLCBUeXBlPiBzaG91bGRTa2lwKSB7CiAgICAgICAgICAgICAgICB0aGlzLmNsb3N1cmUgPSBMaXN0Lm5pbCgpOwogICAgICAgICAgICAgICAgdGhpcy5taW5DbG9zdXJlID0gbWluQ2xvc3VyZTsKICAgICAgICAgICAgICAgIHRoaXMuc2hvdWxkU2tpcCA9IHNob3VsZFNraXA7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHZvaWQgYWRkKFR5cGUgdHlwZSkgewogICAgICAgICAgICAgICAgY2xvc3VyZSA9IGluc2VydChjbG9zdXJlLCB0eXBlLCBzaG91bGRTa2lwKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgQ2xvc3VyZUhvbGRlciBtZXJnZShDbG9zdXJlSG9sZGVyIG90aGVyKSB7CiAgICAgICAgICAgICAgICBjbG9zdXJlID0gdW5pb24oY2xvc3VyZSwgb3RoZXIuY2xvc3VyZSwgc2hvdWxkU2tpcCk7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgTGlzdDxUeXBlPiBjbG9zdXJlKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIG1pbkNsb3N1cmUgPyBjbG9zdXJlTWluKGNsb3N1cmUpIDogY2xvc3VyZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICBCaVByZWRpY2F0ZTxUeXBlLCBUeXBlPiBiYXNpY0Nsb3N1cmVTa2lwID0gKHQxLCB0MikgLT4gdDEudHN5bSA9PSB0Mi50c3ltOwoKICAgIC8qKgogICAgICogSW5zZXJ0IGEgdHlwZSBpbiBhIGNsb3N1cmUKICAgICAqLwogICAgcHVibGljIExpc3Q8VHlwZT4gaW5zZXJ0KExpc3Q8VHlwZT4gY2wsIFR5cGUgdCwgQmlQcmVkaWNhdGU8VHlwZSwgVHlwZT4gc2hvdWxkU2tpcCkgewogICAgICAgIGlmIChjbC5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmV0dXJuIGNsLnByZXBlbmQodCk7CiAgICAgICAgfSBlbHNlIGlmIChzaG91bGRTa2lwLnRlc3QodCwgY2wuaGVhZCkpIHsKICAgICAgICAgICAgcmV0dXJuIGNsOwogICAgICAgIH0gZWxzZSBpZiAodC50c3ltLnByZWNlZGVzKGNsLmhlYWQudHN5bSwgdGhpcykpIHsKICAgICAgICAgICAgcmV0dXJuIGNsLnByZXBlbmQodCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLy8gdCBjb21lcyBhZnRlciBoZWFkLCBvciB0aGUgdHdvIGFyZSB1bnJlbGF0ZWQKICAgICAgICAgICAgcmV0dXJuIGluc2VydChjbC50YWlsLCB0LCBzaG91bGRTa2lwKS5wcmVwZW5kKGNsLmhlYWQpOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgTGlzdDxUeXBlPiBpbnNlcnQoTGlzdDxUeXBlPiBjbCwgVHlwZSB0KSB7CiAgICAgICAgcmV0dXJuIGluc2VydChjbCwgdCwgYmFzaWNDbG9zdXJlU2tpcCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBGb3JtIHRoZSB1bmlvbiBvZiB0d28gY2xvc3VyZXMKICAgICAqLwogICAgcHVibGljIExpc3Q8VHlwZT4gdW5pb24oTGlzdDxUeXBlPiBjbDEsIExpc3Q8VHlwZT4gY2wyLCBCaVByZWRpY2F0ZTxUeXBlLCBUeXBlPiBzaG91bGRTa2lwKSB7CiAgICAgICAgaWYgKGNsMS5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmV0dXJuIGNsMjsKICAgICAgICB9IGVsc2UgaWYgKGNsMi5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmV0dXJuIGNsMTsKICAgICAgICB9IGVsc2UgaWYgKHNob3VsZFNraXAudGVzdChjbDEuaGVhZCwgY2wyLmhlYWQpKSB7CiAgICAgICAgICAgIHJldHVybiB1bmlvbihjbDEudGFpbCwgY2wyLnRhaWwsIHNob3VsZFNraXApLnByZXBlbmQoY2wxLmhlYWQpOwogICAgICAgIH0gZWxzZSBpZiAoY2wxLmhlYWQudHN5bS5wcmVjZWRlcyhjbDIuaGVhZC50c3ltLCB0aGlzKSkgewogICAgICAgICAgICByZXR1cm4gdW5pb24oY2wxLnRhaWwsIGNsMiwgc2hvdWxkU2tpcCkucHJlcGVuZChjbDEuaGVhZCk7CiAgICAgICAgfSBlbHNlIGlmIChjbDIuaGVhZC50c3ltLnByZWNlZGVzKGNsMS5oZWFkLnRzeW0sIHRoaXMpKSB7CiAgICAgICAgICAgIHJldHVybiB1bmlvbihjbDEsIGNsMi50YWlsLCBzaG91bGRTa2lwKS5wcmVwZW5kKGNsMi5oZWFkKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvLyB1bnJlbGF0ZWQgdHlwZXMKICAgICAgICAgICAgcmV0dXJuIHVuaW9uKGNsMS50YWlsLCBjbDIsIHNob3VsZFNraXApLnByZXBlbmQoY2wxLmhlYWQpOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgTGlzdDxUeXBlPiB1bmlvbihMaXN0PFR5cGU+IGNsMSwgTGlzdDxUeXBlPiBjbDIpIHsKICAgICAgICByZXR1cm4gdW5pb24oY2wxLCBjbDIsIGJhc2ljQ2xvc3VyZVNraXApOwogICAgfQoKICAgIC8qKgogICAgICogSW50ZXJzZWN0IHR3byBjbG9zdXJlcwogICAgICovCiAgICBwdWJsaWMgTGlzdDxUeXBlPiBpbnRlcnNlY3QoTGlzdDxUeXBlPiBjbDEsIExpc3Q8VHlwZT4gY2wyKSB7CiAgICAgICAgaWYgKGNsMSA9PSBjbDIpCiAgICAgICAgICAgIHJldHVybiBjbDE7CiAgICAgICAgaWYgKGNsMS5pc0VtcHR5KCkgfHwgY2wyLmlzRW1wdHkoKSkKICAgICAgICAgICAgcmV0dXJuIExpc3QubmlsKCk7CiAgICAgICAgaWYgKGNsMS5oZWFkLnRzeW0ucHJlY2VkZXMoY2wyLmhlYWQudHN5bSwgdGhpcykpCiAgICAgICAgICAgIHJldHVybiBpbnRlcnNlY3QoY2wxLnRhaWwsIGNsMik7CiAgICAgICAgaWYgKGNsMi5oZWFkLnRzeW0ucHJlY2VkZXMoY2wxLmhlYWQudHN5bSwgdGhpcykpCiAgICAgICAgICAgIHJldHVybiBpbnRlcnNlY3QoY2wxLCBjbDIudGFpbCk7CiAgICAgICAgaWYgKGlzU2FtZVR5cGUoY2wxLmhlYWQsIGNsMi5oZWFkKSkKICAgICAgICAgICAgcmV0dXJuIGludGVyc2VjdChjbDEudGFpbCwgY2wyLnRhaWwpLnByZXBlbmQoY2wxLmhlYWQpOwogICAgICAgIGlmIChjbDEuaGVhZC50c3ltID09IGNsMi5oZWFkLnRzeW0gJiYKICAgICAgICAgICAgY2wxLmhlYWQuaGFzVGFnKENMQVNTKSAmJiBjbDIuaGVhZC5oYXNUYWcoQ0xBU1MpKSB7CiAgICAgICAgICAgIGlmIChjbDEuaGVhZC5pc1BhcmFtZXRlcml6ZWQoKSAmJiBjbDIuaGVhZC5pc1BhcmFtZXRlcml6ZWQoKSkgewogICAgICAgICAgICAgICAgVHlwZSBtZXJnZSA9IG1lcmdlKGNsMS5oZWFkLGNsMi5oZWFkKTsKICAgICAgICAgICAgICAgIHJldHVybiBpbnRlcnNlY3QoY2wxLnRhaWwsIGNsMi50YWlsKS5wcmVwZW5kKG1lcmdlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoY2wxLmhlYWQuaXNSYXcoKSB8fCBjbDIuaGVhZC5pc1JhdygpKQogICAgICAgICAgICAgICAgcmV0dXJuIGludGVyc2VjdChjbDEudGFpbCwgY2wyLnRhaWwpLnByZXBlbmQoZXJhc3VyZShjbDEuaGVhZCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gaW50ZXJzZWN0KGNsMS50YWlsLCBjbDIudGFpbCk7CiAgICB9CiAgICAvLyB3aGVyZQogICAgICAgIGNsYXNzIFR5cGVQYWlyIHsKICAgICAgICAgICAgZmluYWwgVHlwZSB0MTsKICAgICAgICAgICAgZmluYWwgVHlwZSB0MjsKICAgICAgICAgICAgYm9vbGVhbiBzdHJpY3Q7CgogICAgICAgICAgICBUeXBlUGFpcihUeXBlIHQxLCBUeXBlIHQyKSB7CiAgICAgICAgICAgICAgICB0aGlzKHQxLCB0MiwgZmFsc2UpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBUeXBlUGFpcihUeXBlIHQxLCBUeXBlIHQyLCBib29sZWFuIHN0cmljdCkgewogICAgICAgICAgICAgICAgdGhpcy50MSA9IHQxOwogICAgICAgICAgICAgICAgdGhpcy50MiA9IHQyOwogICAgICAgICAgICAgICAgdGhpcy5zdHJpY3QgPSBzdHJpY3Q7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gMTI3ICogVHlwZXMudGhpcy5oYXNoQ29kZSh0MSkgKyBUeXBlcy50aGlzLmhhc2hDb2RlKHQyKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmopIHsKICAgICAgICAgICAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIFR5cGVQYWlyKSkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICBUeXBlUGFpciB0eXBlUGFpciA9IChUeXBlUGFpcilvYmo7CiAgICAgICAgICAgICAgICByZXR1cm4gaXNTYW1lVHlwZSh0MSwgdHlwZVBhaXIudDEsIHN0cmljdCkKICAgICAgICAgICAgICAgICAgICAmJiBpc1NhbWVUeXBlKHQyLCB0eXBlUGFpci50Miwgc3RyaWN0KTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBTZXQ8VHlwZVBhaXI+IG1lcmdlQ2FjaGUgPSBuZXcgSGFzaFNldDw+KCk7CiAgICAgICAgcHJpdmF0ZSBUeXBlIG1lcmdlKFR5cGUgYzEsIFR5cGUgYzIpIHsKICAgICAgICAgICAgQ2xhc3NUeXBlIGNsYXNzMSA9IChDbGFzc1R5cGUpIGMxOwogICAgICAgICAgICBMaXN0PFR5cGU+IGFjdDEgPSBjbGFzczEuZ2V0VHlwZUFyZ3VtZW50cygpOwogICAgICAgICAgICBDbGFzc1R5cGUgY2xhc3MyID0gKENsYXNzVHlwZSkgYzI7CiAgICAgICAgICAgIExpc3Q8VHlwZT4gYWN0MiA9IGNsYXNzMi5nZXRUeXBlQXJndW1lbnRzKCk7CiAgICAgICAgICAgIExpc3RCdWZmZXI8VHlwZT4gbWVyZ2VkID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgICAgICBMaXN0PFR5cGU+IHR5cGFyYW1zID0gY2xhc3MxLnRzeW0udHlwZS5nZXRUeXBlQXJndW1lbnRzKCk7CgogICAgICAgICAgICB3aGlsZSAoYWN0MS5ub25FbXB0eSgpICYmIGFjdDIubm9uRW1wdHkoKSAmJiB0eXBhcmFtcy5ub25FbXB0eSgpKSB7CiAgICAgICAgICAgICAgICBpZiAoY29udGFpbnNUeXBlKGFjdDEuaGVhZCwgYWN0Mi5oZWFkKSkgewogICAgICAgICAgICAgICAgICAgIG1lcmdlZC5hcHBlbmQoYWN0MS5oZWFkKTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoY29udGFpbnNUeXBlKGFjdDIuaGVhZCwgYWN0MS5oZWFkKSkgewogICAgICAgICAgICAgICAgICAgIG1lcmdlZC5hcHBlbmQoYWN0Mi5oZWFkKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgVHlwZVBhaXIgcGFpciA9IG5ldyBUeXBlUGFpcihjMSwgYzIpOwogICAgICAgICAgICAgICAgICAgIFR5cGUgbTsKICAgICAgICAgICAgICAgICAgICBpZiAobWVyZ2VDYWNoZS5hZGQocGFpcikpIHsKICAgICAgICAgICAgICAgICAgICAgICAgbSA9IG5ldyBXaWxkY2FyZFR5cGUobHViKHdpbGRVcHBlckJvdW5kKGFjdDEuaGVhZCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aWxkVXBwZXJCb3VuZChhY3QyLmhlYWQpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQm91bmRLaW5kLkVYVEVORFMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5bXMuYm91bmRDbGFzcyk7CiAgICAgICAgICAgICAgICAgICAgICAgIG1lcmdlQ2FjaGUucmVtb3ZlKHBhaXIpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIG0gPSBuZXcgV2lsZGNhcmRUeXBlKHN5bXMub2JqZWN0VHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQm91bmRLaW5kLlVOQk9VTkQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5bXMuYm91bmRDbGFzcyk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIG1lcmdlZC5hcHBlbmQobS53aXRoVHlwZVZhcih0eXBhcmFtcy5oZWFkKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBhY3QxID0gYWN0MS50YWlsOwogICAgICAgICAgICAgICAgYWN0MiA9IGFjdDIudGFpbDsKICAgICAgICAgICAgICAgIHR5cGFyYW1zID0gdHlwYXJhbXMudGFpbDsKICAgICAgICAgICAgfQogICAgICAgICAgICBBc3NlcnQuY2hlY2soYWN0MS5pc0VtcHR5KCkgJiYgYWN0Mi5pc0VtcHR5KCkgJiYgdHlwYXJhbXMuaXNFbXB0eSgpKTsKICAgICAgICAgICAgLy8gVGhlcmUgaXMgbm8gc3BlYyBkZXRhaWxpbmcgaG93IHR5cGUgYW5ub3RhdGlvbnMgYXJlIHRvCiAgICAgICAgICAgIC8vIGJlIGluaGVyaXRlZC4gIFNvIHNldCBpdCB0byBub0Fubm90YXRpb25zIGZvciBub3cKICAgICAgICAgICAgcmV0dXJuIG5ldyBDbGFzc1R5cGUoY2xhc3MxLmdldEVuY2xvc2luZ1R5cGUoKSwgbWVyZ2VkLnRvTGlzdCgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzczEudHN5bSk7CiAgICAgICAgfQoKICAgIC8qKgogICAgICogUmV0dXJuIHRoZSBtaW5pbXVtIHR5cGUgb2YgYSBjbG9zdXJlLCBhIGNvbXBvdW5kIHR5cGUgaWYgbm8KICAgICAqIHVuaXF1ZSBtaW5pbXVtIGV4aXN0cy4KICAgICAqLwogICAgcHJpdmF0ZSBUeXBlIGNvbXBvdW5kTWluKExpc3Q8VHlwZT4gY2wpIHsKICAgICAgICBpZiAoY2wuaXNFbXB0eSgpKSByZXR1cm4gc3ltcy5vYmplY3RUeXBlOwogICAgICAgIExpc3Q8VHlwZT4gY29tcG91bmQgPSBjbG9zdXJlTWluKGNsKTsKICAgICAgICBpZiAoY29tcG91bmQuaXNFbXB0eSgpKQogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICBlbHNlIGlmIChjb21wb3VuZC50YWlsLmlzRW1wdHkoKSkKICAgICAgICAgICAgcmV0dXJuIGNvbXBvdW5kLmhlYWQ7CiAgICAgICAgZWxzZQogICAgICAgICAgICByZXR1cm4gbWFrZUludGVyc2VjdGlvblR5cGUoY29tcG91bmQpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJuIHRoZSBtaW5pbXVtIHR5cGVzIG9mIGEgY2xvc3VyZSwgc3VpdGFibGUgZm9yIGNvbXB1dGluZwogICAgICogY29tcG91bmRNaW4gb3IgZ2xiLgogICAgICovCiAgICBwcml2YXRlIExpc3Q8VHlwZT4gY2xvc3VyZU1pbihMaXN0PFR5cGU+IGNsKSB7CiAgICAgICAgTGlzdEJ1ZmZlcjxUeXBlPiBjbGFzc2VzID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgIExpc3RCdWZmZXI8VHlwZT4gaW50ZXJmYWNlcyA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICBTZXQ8VHlwZT4gdG9Ta2lwID0gbmV3IEhhc2hTZXQ8PigpOwogICAgICAgIHdoaWxlICghY2wuaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIFR5cGUgY3VycmVudCA9IGNsLmhlYWQ7CiAgICAgICAgICAgIGJvb2xlYW4ga2VlcCA9ICF0b1NraXAuY29udGFpbnMoY3VycmVudCk7CiAgICAgICAgICAgIGlmIChrZWVwICYmIGN1cnJlbnQuaGFzVGFnKFRZUEVWQVIpKSB7CiAgICAgICAgICAgICAgICAvLyBza2lwIGxvd2VyLWJvdW5kZWQgdmFyaWFibGVzIHdpdGggYSBzdWJ0eXBlIGluIGNsLnRhaWwKICAgICAgICAgICAgICAgIGZvciAoVHlwZSB0IDogY2wudGFpbCkgewogICAgICAgICAgICAgICAgICAgIGlmIChpc1N1YnR5cGVOb0NhcHR1cmUodCwgY3VycmVudCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAga2VlcCA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGtlZXApIHsKICAgICAgICAgICAgICAgIGlmIChjdXJyZW50LmlzSW50ZXJmYWNlKCkpCiAgICAgICAgICAgICAgICAgICAgaW50ZXJmYWNlcy5hcHBlbmQoY3VycmVudCk7CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgY2xhc3Nlcy5hcHBlbmQoY3VycmVudCk7CiAgICAgICAgICAgICAgICBmb3IgKFR5cGUgdCA6IGNsLnRhaWwpIHsKICAgICAgICAgICAgICAgICAgICAvLyBza2lwIHN1cGVydHlwZXMgb2YgJ2N1cnJlbnQnIGluIGNsLnRhaWwKICAgICAgICAgICAgICAgICAgICBpZiAoaXNTdWJ0eXBlTm9DYXB0dXJlKGN1cnJlbnQsIHQpKQogICAgICAgICAgICAgICAgICAgICAgICB0b1NraXAuYWRkKHQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGNsID0gY2wudGFpbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGNsYXNzZXMuYXBwZW5kTGlzdChpbnRlcmZhY2VzKS50b0xpc3QoKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybiB0aGUgbGVhc3QgdXBwZXIgYm91bmQgb2YgbGlzdCBvZiB0eXBlcy4gIGlmIHRoZSBsdWIgZG9lcwogICAgICogbm90IGV4aXN0IHJldHVybiBudWxsLgogICAgICovCiAgICBwdWJsaWMgVHlwZSBsdWIoTGlzdDxUeXBlPiB0cykgewogICAgICAgIHJldHVybiBsdWIodHMudG9BcnJheShuZXcgVHlwZVt0cy5sZW5ndGgoKV0pKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybiB0aGUgbGVhc3QgdXBwZXIgYm91bmQgKGx1Yikgb2Ygc2V0IG9mIHR5cGVzLiAgSWYgdGhlIGx1YgogICAgICogZG9lcyBub3QgZXhpc3QgcmV0dXJuIHRoZSB0eXBlIG9mIG51bGwgKGJvdHRvbSkuCiAgICAgKi8KICAgIHB1YmxpYyBUeXBlIGx1YihUeXBlLi4uIHRzKSB7CiAgICAgICAgZmluYWwgaW50IFVOS05PV05fQk9VTkQgPSAwOwogICAgICAgIGZpbmFsIGludCBBUlJBWV9CT1VORCA9IDE7CiAgICAgICAgZmluYWwgaW50IENMQVNTX0JPVU5EID0gMjsKCiAgICAgICAgaW50W10ga2luZHMgPSBuZXcgaW50W3RzLmxlbmd0aF07CgogICAgICAgIGludCBib3VuZGtpbmQgPSBVTktOT1dOX0JPVU5EOwogICAgICAgIGZvciAoaW50IGkgPSAwIDsgaSA8IHRzLmxlbmd0aCA7IGkrKykgewogICAgICAgICAgICBUeXBlIHQgPSB0c1tpXTsKICAgICAgICAgICAgc3dpdGNoICh0LmdldFRhZygpKSB7CiAgICAgICAgICAgIGNhc2UgQ0xBU1M6CiAgICAgICAgICAgICAgICBib3VuZGtpbmQgfD0ga2luZHNbaV0gPSBDTEFTU19CT1VORDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIEFSUkFZOgogICAgICAgICAgICAgICAgYm91bmRraW5kIHw9IGtpbmRzW2ldID0gQVJSQVlfQk9VTkQ7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAgVFlQRVZBUjoKICAgICAgICAgICAgICAgIGRvIHsKICAgICAgICAgICAgICAgICAgICB0ID0gdC5nZXRVcHBlckJvdW5kKCk7CiAgICAgICAgICAgICAgICB9IHdoaWxlICh0Lmhhc1RhZyhUWVBFVkFSKSk7CiAgICAgICAgICAgICAgICBpZiAodC5oYXNUYWcoQVJSQVkpKSB7CiAgICAgICAgICAgICAgICAgICAgYm91bmRraW5kIHw9IGtpbmRzW2ldID0gQVJSQVlfQk9VTkQ7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGJvdW5ka2luZCB8PSBraW5kc1tpXSA9IENMQVNTX0JPVU5EOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICBraW5kc1tpXSA9IFVOS05PV05fQk9VTkQ7CiAgICAgICAgICAgICAgICBpZiAodC5pc1ByaW1pdGl2ZSgpKQogICAgICAgICAgICAgICAgICAgIHJldHVybiBzeW1zLmVyclR5cGU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgc3dpdGNoIChib3VuZGtpbmQpIHsKICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgIHJldHVybiBzeW1zLmJvdFR5cGU7CgogICAgICAgIGNhc2UgQVJSQVlfQk9VTkQ6CiAgICAgICAgICAgIC8vIGNhbGN1bGF0ZSBsdWIoQVtdLCBCW10pCiAgICAgICAgICAgIFR5cGVbXSBlbGVtZW50cyA9IG5ldyBUeXBlW3RzLmxlbmd0aF07CiAgICAgICAgICAgIGZvciAoaW50IGkgPSAwIDsgaSA8IHRzLmxlbmd0aCA7IGkrKykgewogICAgICAgICAgICAgICAgVHlwZSBlbGVtID0gZWxlbWVudHNbaV0gPSBlbGVtVHlwZUZ1bi5hcHBseSh0c1tpXSk7CiAgICAgICAgICAgICAgICBpZiAoZWxlbS5pc1ByaW1pdGl2ZSgpKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gaWYgYSBwcmltaXRpdmUgdHlwZSBpcyBmb3VuZCwgdGhlbiByZXR1cm4KICAgICAgICAgICAgICAgICAgICAvLyBhcnJheVN1cGVyVHlwZSB1bmxlc3MgYWxsIHRoZSB0eXBlcyBhcmUgdGhlCiAgICAgICAgICAgICAgICAgICAgLy8gc2FtZQogICAgICAgICAgICAgICAgICAgIFR5cGUgZmlyc3QgPSB0c1swXTsKICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBqID0gMSA7IGogPCB0cy5sZW5ndGggOyBqKyspIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFpc1NhbWVUeXBlKGZpcnN0LCB0c1tqXSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBsdWIoaW50W10sIEJbXSkgaXMgQ2xvbmVhYmxlICYgU2VyaWFsaXphYmxlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYXJyYXlTdXBlclR5cGUoKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAvLyBhbGwgdGhlIGFycmF5IHR5cGVzIGFyZSB0aGUgc2FtZSwgcmV0dXJuIG9uZQogICAgICAgICAgICAgICAgICAgIC8vIGx1YihpbnRbXSwgaW50W10pIGlzIGludFtdCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZpcnN0OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIGx1YihBW10sIEJbXSkgaXMgbHViKEEsIEIpW10KICAgICAgICAgICAgcmV0dXJuIG5ldyBBcnJheVR5cGUobHViKGVsZW1lbnRzKSwgc3ltcy5hcnJheUNsYXNzKTsKCiAgICAgICAgY2FzZSBDTEFTU19CT1VORDoKICAgICAgICAgICAgLy8gY2FsY3VsYXRlIGx1YihBLCBCKQogICAgICAgICAgICBpbnQgc3RhcnRJZHggPSAwOwogICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHRzLmxlbmd0aCA7IGkrKykgewogICAgICAgICAgICAgICAgVHlwZSB0ID0gdHNbaV07CiAgICAgICAgICAgICAgICBpZiAodC5oYXNUYWcoQ0xBU1MpIHx8IHQuaGFzVGFnKFRZUEVWQVIpKSB7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHN0YXJ0SWR4Kys7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgQXNzZXJ0LmNoZWNrKHN0YXJ0SWR4IDwgdHMubGVuZ3RoKTsKICAgICAgICAgICAgLy9zdGVwIDEgLSBjb21wdXRlIGVyYXNlZCBjYW5kaWRhdGUgc2V0IChFQykKICAgICAgICAgICAgTGlzdDxUeXBlPiBjbCA9IGVyYXNlZFN1cGVydHlwZXModHNbc3RhcnRJZHhdKTsKICAgICAgICAgICAgZm9yIChpbnQgaSA9IHN0YXJ0SWR4ICsgMSA7IGkgPCB0cy5sZW5ndGggOyBpKyspIHsKICAgICAgICAgICAgICAgIFR5cGUgdCA9IHRzW2ldOwogICAgICAgICAgICAgICAgaWYgKHQuaGFzVGFnKENMQVNTKSB8fCB0Lmhhc1RhZyhUWVBFVkFSKSkKICAgICAgICAgICAgICAgICAgICBjbCA9IGludGVyc2VjdChjbCwgZXJhc2VkU3VwZXJ0eXBlcyh0KSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy9zdGVwIDIgLSBjb21wdXRlIG1pbmltYWwgZXJhc2VkIGNhbmRpZGF0ZSBzZXQgKE1FQykKICAgICAgICAgICAgTGlzdDxUeXBlPiBtZWMgPSBjbG9zdXJlTWluKGNsKTsKICAgICAgICAgICAgLy9zdGVwIDMgLSBmb3IgZWFjaCBlbGVtZW50IEcgaW4gTUVDLCBjb21wdXRlIGxjaShJbnYoRykpCiAgICAgICAgICAgIExpc3Q8VHlwZT4gY2FuZGlkYXRlcyA9IExpc3QubmlsKCk7CiAgICAgICAgICAgIGZvciAoVHlwZSBlcmFzZWRTdXBlcnR5cGUgOiBtZWMpIHsKICAgICAgICAgICAgICAgIExpc3Q8VHlwZT4gbGNpID0gTGlzdC5vZihhc1N1cGVyKHRzW3N0YXJ0SWR4XSwgZXJhc2VkU3VwZXJ0eXBlLnRzeW0pKTsKICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSBzdGFydElkeCArIDEgOyBpIDwgdHMubGVuZ3RoIDsgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgVHlwZSBzdXBlclR5cGUgPSBhc1N1cGVyKHRzW2ldLCBlcmFzZWRTdXBlcnR5cGUudHN5bSk7CiAgICAgICAgICAgICAgICAgICAgbGNpID0gaW50ZXJzZWN0KGxjaSwgc3VwZXJUeXBlICE9IG51bGwgPyBMaXN0Lm9mKHN1cGVyVHlwZSkgOiBMaXN0Lm5pbCgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGNhbmRpZGF0ZXMgPSBjYW5kaWRhdGVzLmFwcGVuZExpc3QobGNpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvL3N0ZXAgNCAtIGxldCBNRUMgYmUgeyBHMSwgRzIgLi4uIEduIH0sIHRoZW4gd2UgaGF2ZSB0aGF0CiAgICAgICAgICAgIC8vbHViID0gbGNpKEludihHMSkpICYgbGNpKEludihHMikpICYgLi4uICYgbGNpKEludihHbikpCiAgICAgICAgICAgIHJldHVybiBjb21wb3VuZE1pbihjYW5kaWRhdGVzKTsKCiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgLy8gY2FsY3VsYXRlIGx1YihBLCBCW10pCiAgICAgICAgICAgIExpc3Q8VHlwZT4gY2xhc3NlcyA9IExpc3Qub2YoYXJyYXlTdXBlclR5cGUoKSk7CiAgICAgICAgICAgIGZvciAoaW50IGkgPSAwIDsgaSA8IHRzLmxlbmd0aCA7IGkrKykgewogICAgICAgICAgICAgICAgaWYgKGtpbmRzW2ldICE9IEFSUkFZX0JPVU5EKSAvLyBGaWx0ZXIgb3V0IGFueSBhcnJheXMKICAgICAgICAgICAgICAgICAgICBjbGFzc2VzID0gY2xhc3Nlcy5wcmVwZW5kKHRzW2ldKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvLyBsdWIoQSwgQltdKSBpcyBsdWIoQSwgYXJyYXlTdXBlclR5cGUpCiAgICAgICAgICAgIHJldHVybiBsdWIoY2xhc3Nlcyk7CiAgICAgICAgfQogICAgfQogICAgLy8gd2hlcmUKICAgICAgICBMaXN0PFR5cGU+IGVyYXNlZFN1cGVydHlwZXMoVHlwZSB0KSB7CiAgICAgICAgICAgIExpc3RCdWZmZXI8VHlwZT4gYnVmID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgICAgICBmb3IgKFR5cGUgc3VwIDogY2xvc3VyZSh0KSkgewogICAgICAgICAgICAgICAgaWYgKHN1cC5oYXNUYWcoVFlQRVZBUikpIHsKICAgICAgICAgICAgICAgICAgICBidWYuYXBwZW5kKHN1cCk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQoZXJhc3VyZShzdXApKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gYnVmLnRvTGlzdCgpOwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBUeXBlIGFycmF5U3VwZXJUeXBlID0gbnVsbDsKICAgICAgICBwcml2YXRlIFR5cGUgYXJyYXlTdXBlclR5cGUoKSB7CiAgICAgICAgICAgIC8vIGluaXRpYWxpemVkIGxhemlseSB0byBhdm9pZCBwcm9ibGVtcyBkdXJpbmcgY29tcGlsZXIgc3RhcnR1cAogICAgICAgICAgICBpZiAoYXJyYXlTdXBlclR5cGUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgc3luY2hyb25pemVkICh0aGlzKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGFycmF5U3VwZXJUeXBlID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gSkxTIDEwLjg6IGFsbCBhcnJheXMgaW1wbGVtZW50IENsb25lYWJsZSBhbmQgU2VyaWFsaXphYmxlLgogICAgICAgICAgICAgICAgICAgICAgICBhcnJheVN1cGVyVHlwZSA9IG1ha2VJbnRlcnNlY3Rpb25UeXBlKExpc3Qub2Yoc3ltcy5zZXJpYWxpemFibGVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5bXMuY2xvbmVhYmxlVHlwZSksIHRydWUpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gYXJyYXlTdXBlclR5cGU7CiAgICAgICAgfQogICAgLy8gPC9lZGl0b3ItZm9sZD4KCiAgICAvLyA8ZWRpdG9yLWZvbGQgZGVmYXVsdHN0YXRlPSJjb2xsYXBzZWQiIGRlc2M9IkdyZWF0ZXN0IGxvd2VyIGJvdW5kIj4KICAgIHB1YmxpYyBUeXBlIGdsYihMaXN0PFR5cGU+IHRzKSB7CiAgICAgICAgVHlwZSB0MSA9IHRzLmhlYWQ7CiAgICAgICAgZm9yIChUeXBlIHQyIDogdHMudGFpbCkgewogICAgICAgICAgICBpZiAodDEuaXNFcnJvbmVvdXMoKSkKICAgICAgICAgICAgICAgIHJldHVybiB0MTsKICAgICAgICAgICAgdDEgPSBnbGIodDEsIHQyKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHQxOwogICAgfQogICAgLy93aGVyZQogICAgcHVibGljIFR5cGUgZ2xiKFR5cGUgdCwgVHlwZSBzKSB7CiAgICAgICAgaWYgKHMgPT0gbnVsbCkKICAgICAgICAgICAgcmV0dXJuIHQ7CiAgICAgICAgZWxzZSBpZiAodC5pc1ByaW1pdGl2ZSgpIHx8IHMuaXNQcmltaXRpdmUoKSkKICAgICAgICAgICAgcmV0dXJuIHN5bXMuZXJyVHlwZTsKICAgICAgICBlbHNlIGlmIChpc1N1YnR5cGVOb0NhcHR1cmUodCwgcykpCiAgICAgICAgICAgIHJldHVybiB0OwogICAgICAgIGVsc2UgaWYgKGlzU3VidHlwZU5vQ2FwdHVyZShzLCB0KSkKICAgICAgICAgICAgcmV0dXJuIHM7CgogICAgICAgIExpc3Q8VHlwZT4gY2xvc3VyZSA9IHVuaW9uKGNsb3N1cmUodCksIGNsb3N1cmUocykpOwogICAgICAgIHJldHVybiBnbGJGbGF0dGVuZWQoY2xvc3VyZSwgdCk7CiAgICB9CiAgICAvL3doZXJlCiAgICAvKioKICAgICAqIFBlcmZvcm0gZ2xiIGZvciBhIGxpc3Qgb2Ygbm9uLXByaW1pdGl2ZSwgbm9uLWVycm9yLCBub24tY29tcG91bmQgdHlwZXM7CiAgICAgKiByZWR1bmRhbnQgZWxlbWVudHMgYXJlIHJlbW92ZWQuICBCb3VuZHMgc2hvdWxkIGJlIG9yZGVyZWQgYWNjb3JkaW5nIHRvCiAgICAgKiB7QGxpbmsgU3ltYm9sI3ByZWNlZGVzKFR5cGVTeW1ib2wsVHlwZXMpfS4KICAgICAqCiAgICAgKiBAcGFyYW0gZmxhdEJvdW5kcyBMaXN0IG9mIHR5cGUgdG8gZ2xiCiAgICAgKiBAcGFyYW0gZXJyVCBPcmlnaW5hbCB0eXBlIHRvIHVzZSBpZiB0aGUgcmVzdWx0IGlzIGFuIGVycm9yIHR5cGUKICAgICAqLwogICAgcHJpdmF0ZSBUeXBlIGdsYkZsYXR0ZW5lZChMaXN0PFR5cGU+IGZsYXRCb3VuZHMsIFR5cGUgZXJyVCkgewogICAgICAgIExpc3Q8VHlwZT4gYm91bmRzID0gY2xvc3VyZU1pbihmbGF0Qm91bmRzKTsKCiAgICAgICAgaWYgKGJvdW5kcy5pc0VtcHR5KCkpIHsgICAgICAgICAgICAgLy8gbGVuZ3RoID09IDAKICAgICAgICAgICAgcmV0dXJuIHN5bXMub2JqZWN0VHlwZTsKICAgICAgICB9IGVsc2UgaWYgKGJvdW5kcy50YWlsLmlzRW1wdHkoKSkgeyAvLyBsZW5ndGggPT0gMQogICAgICAgICAgICByZXR1cm4gYm91bmRzLmhlYWQ7CiAgICAgICAgfSBlbHNlIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbGVuZ3RoID4gMQogICAgICAgICAgICBpbnQgY2xhc3NDb3VudCA9IDA7CiAgICAgICAgICAgIExpc3Q8VHlwZT4gY3ZhcnMgPSBMaXN0Lm5pbCgpOwogICAgICAgICAgICBMaXN0PFR5cGU+IGxvd2VycyA9IExpc3QubmlsKCk7CiAgICAgICAgICAgIGZvciAoVHlwZSBib3VuZCA6IGJvdW5kcykgewogICAgICAgICAgICAgICAgaWYgKCFib3VuZC5pc0ludGVyZmFjZSgpKSB7CiAgICAgICAgICAgICAgICAgICAgY2xhc3NDb3VudCsrOwogICAgICAgICAgICAgICAgICAgIFR5cGUgbG93ZXIgPSBjdmFyTG93ZXJCb3VuZChib3VuZCk7CiAgICAgICAgICAgICAgICAgICAgaWYgKGJvdW5kICE9IGxvd2VyICYmICFsb3dlci5oYXNUYWcoQk9UKSkgewogICAgICAgICAgICAgICAgICAgICAgICBjdmFycyA9IGN2YXJzLmFwcGVuZChib3VuZCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGxvd2VycyA9IGxvd2Vycy5hcHBlbmQobG93ZXIpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoY2xhc3NDb3VudCA+IDEpIHsKICAgICAgICAgICAgICAgIGlmIChsb3dlcnMuaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZUVycm9yVHlwZShlcnJUKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgLy8gdHJ5IGFnYWluIHdpdGggbG93ZXIgYm91bmRzIGluY2x1ZGVkIGluc3RlYWQgb2YgY2FwdHVyZSB2YXJpYWJsZXMKICAgICAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IG5ld0JvdW5kcyA9IGJvdW5kcy5kaWZmKGN2YXJzKS5hcHBlbmRMaXN0KGxvd2Vycyk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGdsYihuZXdCb3VuZHMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYWtlSW50ZXJzZWN0aW9uVHlwZShib3VuZHMpOwogICAgfQogICAgLy8gPC9lZGl0b3ItZm9sZD4KCiAgICAvLyA8ZWRpdG9yLWZvbGQgZGVmYXVsdHN0YXRlPSJjb2xsYXBzZWQiIGRlc2M9Imhhc2hDb2RlIj4KICAgIC8qKgogICAgICogQ29tcHV0ZSBhIGhhc2ggY29kZSBvbiBhIHR5cGUuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoVHlwZSB0KSB7CiAgICAgICAgcmV0dXJuIGhhc2hDb2RlKHQsIGZhbHNlKTsKICAgIH0KCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKFR5cGUgdCwgYm9vbGVhbiBzdHJpY3QpIHsKICAgICAgICByZXR1cm4gc3RyaWN0ID8KICAgICAgICAgICAgICAgIGhhc2hDb2RlU3RyaWN0VmlzaXRvci52aXNpdCh0KSA6CiAgICAgICAgICAgICAgICBoYXNoQ29kZVZpc2l0b3IudmlzaXQodCk7CiAgICB9CiAgICAvLyB3aGVyZQogICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEhhc2hDb2RlVmlzaXRvciBoYXNoQ29kZVZpc2l0b3IgPSBuZXcgSGFzaENvZGVWaXNpdG9yKCk7CiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgSGFzaENvZGVWaXNpdG9yIGhhc2hDb2RlU3RyaWN0VmlzaXRvciA9IG5ldyBIYXNoQ29kZVZpc2l0b3IoKSB7CiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgSW50ZWdlciB2aXNpdFR5cGVWYXIoVHlwZVZhciB0LCBWb2lkIGlnbm9yZWQpIHsKICAgICAgICAgICAgICAgIHJldHVybiBTeXN0ZW0uaWRlbnRpdHlIYXNoQ29kZSh0KTsKICAgICAgICAgICAgfQogICAgICAgIH07CgogICAgICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIEhhc2hDb2RlVmlzaXRvciBleHRlbmRzIFVuYXJ5VmlzaXRvcjxJbnRlZ2VyPiB7CiAgICAgICAgICAgIHB1YmxpYyBJbnRlZ2VyIHZpc2l0VHlwZShUeXBlIHQsIFZvaWQgaWdub3JlZCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHQuZ2V0VGFnKCkub3JkaW5hbCgpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHVibGljIEludGVnZXIgdmlzaXRDbGFzc1R5cGUoQ2xhc3NUeXBlIHQsIFZvaWQgaWdub3JlZCkgewogICAgICAgICAgICAgICAgaW50IHJlc3VsdCA9IHZpc2l0KHQuZ2V0RW5jbG9zaW5nVHlwZSgpKTsKICAgICAgICAgICAgICAgIHJlc3VsdCAqPSAxMjc7CiAgICAgICAgICAgICAgICByZXN1bHQgKz0gdC50c3ltLmZsYXROYW1lKCkuaGFzaENvZGUoKTsKICAgICAgICAgICAgICAgIGZvciAoVHlwZSBzIDogdC5nZXRUeXBlQXJndW1lbnRzKCkpIHsKICAgICAgICAgICAgICAgICAgICByZXN1bHQgKj0gMTI3OwogICAgICAgICAgICAgICAgICAgIHJlc3VsdCArPSB2aXNpdChzKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgSW50ZWdlciB2aXNpdE1ldGhvZFR5cGUoTWV0aG9kVHlwZSB0LCBWb2lkIGlnbm9yZWQpIHsKICAgICAgICAgICAgICAgIGludCBoID0gTUVUSE9ELm9yZGluYWwoKTsKICAgICAgICAgICAgICAgIGZvciAoTGlzdDxUeXBlPiB0aGlzYXJncyA9IHQuYXJndHlwZXM7CiAgICAgICAgICAgICAgICAgICAgIHRoaXNhcmdzLnRhaWwgIT0gbnVsbDsKICAgICAgICAgICAgICAgICAgICAgdGhpc2FyZ3MgPSB0aGlzYXJncy50YWlsKQogICAgICAgICAgICAgICAgICAgIGggPSAoaCA8PCA1KSArIHZpc2l0KHRoaXNhcmdzLmhlYWQpOwogICAgICAgICAgICAgICAgcmV0dXJuIChoIDw8IDUpICsgdmlzaXQodC5yZXN0eXBlKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHB1YmxpYyBJbnRlZ2VyIHZpc2l0V2lsZGNhcmRUeXBlKFdpbGRjYXJkVHlwZSB0LCBWb2lkIGlnbm9yZWQpIHsKICAgICAgICAgICAgICAgIGludCByZXN1bHQgPSB0LmtpbmQuaGFzaENvZGUoKTsKICAgICAgICAgICAgICAgIGlmICh0LnR5cGUgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIHJlc3VsdCAqPSAxMjc7CiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ICs9IHZpc2l0KHQudHlwZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgICAgICB9CgogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHVibGljIEludGVnZXIgdmlzaXRBcnJheVR5cGUoQXJyYXlUeXBlIHQsIFZvaWQgaWdub3JlZCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHZpc2l0KHQuZWxlbXR5cGUpICsgMTI7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgSW50ZWdlciB2aXNpdFR5cGVWYXIoVHlwZVZhciB0LCBWb2lkIGlnbm9yZWQpIHsKICAgICAgICAgICAgICAgIHJldHVybiBTeXN0ZW0uaWRlbnRpdHlIYXNoQ29kZSh0KTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHB1YmxpYyBJbnRlZ2VyIHZpc2l0VW5kZXRWYXIoVW5kZXRWYXIgdCwgVm9pZCBpZ25vcmVkKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gU3lzdGVtLmlkZW50aXR5SGFzaENvZGUodCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgSW50ZWdlciB2aXNpdEVycm9yVHlwZShFcnJvclR5cGUgdCwgVm9pZCBpZ25vcmVkKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIC8vIDwvZWRpdG9yLWZvbGQ+CgogICAgLy8gPGVkaXRvci1mb2xkIGRlZmF1bHRzdGF0ZT0iY29sbGFwc2VkIiBkZXNjPSJSZXR1cm4tVHlwZS1TdWJzdGl0dXRhYmxlIj4KICAgIC8qKgogICAgICogRG9lcyB0IGhhdmUgYSByZXN1bHQgdGhhdCBpcyBhIHN1YnR5cGUgb2YgdGhlIHJlc3VsdCB0eXBlIG9mIHMsCiAgICAgKiBzdWl0YWJsZSBmb3IgY292YXJpYW50IHJldHVybnM/ICBJdCBpcyBhc3N1bWVkIHRoYXQgYm90aCB0eXBlcwogICAgICogYXJlIChwb3NzaWJseSBwb2x5bW9ycGhpYykgbWV0aG9kIHR5cGVzLiAgTW9ub21vcnBoaWMgbWV0aG9kCiAgICAgKiB0eXBlcyBhcmUgaGFuZGxlZCBpbiB0aGUgb2J2aW91cyB3YXkuICBQb2x5bW9ycGhpYyBtZXRob2QgdHlwZXMKICAgICAqIHJlcXVpcmUgcmVuYW1pbmcgYWxsIHR5cGUgdmFyaWFibGVzIG9mIG9uZSB0byBjb3JyZXNwb25kaW5nCiAgICAgKiB0eXBlIHZhcmlhYmxlcyBpbiB0aGUgb3RoZXIsIHdoZXJlIGNvcnJlc3BvbmRlbmNlIGlzIGJ5CiAgICAgKiBwb3NpdGlvbiBpbiB0aGUgdHlwZSBwYXJhbWV0ZXIgbGlzdC4gKi8KICAgIHB1YmxpYyBib29sZWFuIHJlc3VsdFN1YnR5cGUoVHlwZSB0LCBUeXBlIHMsIFdhcm5lciB3YXJuZXIpIHsKICAgICAgICBMaXN0PFR5cGU+IHR2YXJzID0gdC5nZXRUeXBlQXJndW1lbnRzKCk7CiAgICAgICAgTGlzdDxUeXBlPiBzdmFycyA9IHMuZ2V0VHlwZUFyZ3VtZW50cygpOwogICAgICAgIFR5cGUgdHJlcyA9IHQuZ2V0UmV0dXJuVHlwZSgpOwogICAgICAgIFR5cGUgc3JlcyA9IHN1YnN0KHMuZ2V0UmV0dXJuVHlwZSgpLCBzdmFycywgdHZhcnMpOwogICAgICAgIHJldHVybiBjb3ZhcmlhbnRSZXR1cm5UeXBlKHRyZXMsIHNyZXMsIHdhcm5lcik7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm4tVHlwZS1TdWJzdGl0dXRhYmxlLgogICAgICogQGpscyBzZWN0aW9uIDguNC41CiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIHJldHVyblR5cGVTdWJzdGl0dXRhYmxlKFR5cGUgcjEsIFR5cGUgcjIpIHsKICAgICAgICBpZiAoaGFzU2FtZUFyZ3MocjEsIHIyKSkKICAgICAgICAgICAgcmV0dXJuIHJlc3VsdFN1YnR5cGUocjEsIHIyLCBub1dhcm5pbmdzKTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIHJldHVybiBjb3ZhcmlhbnRSZXR1cm5UeXBlKHIxLmdldFJldHVyblR5cGUoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJhc3VyZShyMi5nZXRSZXR1cm5UeXBlKCkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub1dhcm5pbmdzKTsKICAgIH0KCiAgICBwdWJsaWMgYm9vbGVhbiByZXR1cm5UeXBlU3Vic3RpdHV0YWJsZShUeXBlIHIxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVHlwZSByMiwgVHlwZSByMnJlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdhcm5lciB3YXJuZXIpIHsKICAgICAgICBpZiAoaXNTYW1lVHlwZShyMS5nZXRSZXR1cm5UeXBlKCksIHIycmVzKSkKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgaWYgKHIxLmdldFJldHVyblR5cGUoKS5pc1ByaW1pdGl2ZSgpIHx8IHIycmVzLmlzUHJpbWl0aXZlKCkpCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKCiAgICAgICAgaWYgKGhhc1NhbWVBcmdzKHIxLCByMikpCiAgICAgICAgICAgIHJldHVybiBjb3ZhcmlhbnRSZXR1cm5UeXBlKHIxLmdldFJldHVyblR5cGUoKSwgcjJyZXMsIHdhcm5lcik7CiAgICAgICAgaWYgKGlzU3VidHlwZVVuY2hlY2tlZChyMS5nZXRSZXR1cm5UeXBlKCksIHIycmVzLCB3YXJuZXIpKQogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICBpZiAoIWlzU3VidHlwZShyMS5nZXRSZXR1cm5UeXBlKCksIGVyYXN1cmUocjJyZXMpKSkKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIHdhcm5lci53YXJuKExpbnRDYXRlZ29yeS5VTkNIRUNLRUQpOwogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIC8qKgogICAgICogSXMgdCBhbiBhcHByb3ByaWF0ZSByZXR1cm4gdHlwZSBpbiBhbiBvdmVycmlkZXIgZm9yIGEKICAgICAqIG1ldGhvZCB0aGF0IHJldHVybnMgcz8KICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gY292YXJpYW50UmV0dXJuVHlwZShUeXBlIHQsIFR5cGUgcywgV2FybmVyIHdhcm5lcikgewogICAgICAgIHJldHVybgogICAgICAgICAgICBpc1NhbWVUeXBlKHQsIHMpIHx8CiAgICAgICAgICAgICF0LmlzUHJpbWl0aXZlKCkgJiYKICAgICAgICAgICAgIXMuaXNQcmltaXRpdmUoKSAmJgogICAgICAgICAgICBpc0Fzc2lnbmFibGUodCwgcywgd2FybmVyKTsKICAgIH0KICAgIC8vIDwvZWRpdG9yLWZvbGQ+CgogICAgLy8gPGVkaXRvci1mb2xkIGRlZmF1bHRzdGF0ZT0iY29sbGFwc2VkIiBkZXNjPSJCb3gvdW5ib3ggc3VwcG9ydCI+CiAgICAvKioKICAgICAqIFJldHVybiB0aGUgY2xhc3MgdGhhdCBib3hlcyB0aGUgZ2l2ZW4gcHJpbWl0aXZlLgogICAgICovCiAgICBwdWJsaWMgQ2xhc3NTeW1ib2wgYm94ZWRDbGFzcyhUeXBlIHQpIHsKICAgICAgICByZXR1cm4gc3ltcy5lbnRlckNsYXNzKHN5bXMuamF2YV9iYXNlLCBzeW1zLmJveGVkTmFtZVt0LmdldFRhZygpLm9yZGluYWwoKV0pOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJuIHRoZSBib3hlZCB0eXBlIGlmICd0JyBpcyBwcmltaXRpdmUsIG90aGVyd2lzZSByZXR1cm4gJ3QnIGl0c2VsZi4KICAgICAqLwogICAgcHVibGljIFR5cGUgYm94ZWRUeXBlT3JUeXBlKFR5cGUgdCkgewogICAgICAgIHJldHVybiB0LmlzUHJpbWl0aXZlKCkgPwogICAgICAgICAgICBib3hlZENsYXNzKHQpLnR5cGUgOgogICAgICAgICAgICB0OwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJuIHRoZSBwcmltaXRpdmUgdHlwZSBjb3JyZXNwb25kaW5nIHRvIGEgYm94ZWQgdHlwZS4KICAgICAqLwogICAgcHVibGljIFR5cGUgdW5ib3hlZFR5cGUoVHlwZSB0KSB7CiAgICAgICAgZm9yIChpbnQgaT0wOyBpPHN5bXMuYm94ZWROYW1lLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgIE5hbWUgYm94ID0gc3ltcy5ib3hlZE5hbWVbaV07CiAgICAgICAgICAgIGlmIChib3ggIT0gbnVsbCAmJgogICAgICAgICAgICAgICAgYXNTdXBlcih0LCBzeW1zLmVudGVyQ2xhc3Moc3ltcy5qYXZhX2Jhc2UsIGJveCkpICE9IG51bGwpCiAgICAgICAgICAgICAgICByZXR1cm4gc3ltcy50eXBlT2ZUYWdbaV07CiAgICAgICAgfQogICAgICAgIHJldHVybiBUeXBlLm5vVHlwZTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybiB0aGUgdW5ib3hlZCB0eXBlIGlmICd0JyBpcyBhIGJveGVkIGNsYXNzLCBvdGhlcndpc2UgcmV0dXJuICd0JyBpdHNlbGYuCiAgICAgKi8KICAgIHB1YmxpYyBUeXBlIHVuYm94ZWRUeXBlT3JUeXBlKFR5cGUgdCkgewogICAgICAgIFR5cGUgdW5ib3hlZFR5cGUgPSB1bmJveGVkVHlwZSh0KTsKICAgICAgICByZXR1cm4gdW5ib3hlZFR5cGUuaGFzVGFnKE5PTkUpID8gdCA6IHVuYm94ZWRUeXBlOwogICAgfQogICAgLy8gPC9lZGl0b3ItZm9sZD4KCiAgICAvLyA8ZWRpdG9yLWZvbGQgZGVmYXVsdHN0YXRlPSJjb2xsYXBzZWQiIGRlc2M9IkNhcHR1cmUgY29udmVyc2lvbiI+CiAgICAvKgogICAgICogSkxTIDUuMS4xMCBDYXB0dXJlIENvbnZlcnNpb246CiAgICAgKgogICAgICogTGV0IEcgbmFtZSBhIGdlbmVyaWMgdHlwZSBkZWNsYXJhdGlvbiB3aXRoIG4gZm9ybWFsIHR5cGUKICAgICAqIHBhcmFtZXRlcnMgQTEgLi4uIEFuIHdpdGggY29ycmVzcG9uZGluZyBib3VuZHMgVTEgLi4uIFVuLiBUaGVyZQogICAgICogZXhpc3RzIGEgY2FwdHVyZSBjb252ZXJzaW9uIGZyb20gRzxUMSAuLi4gVG4+IHRvIEc8UzEgLi4uIFNuPiwKICAgICAqIHdoZXJlLCBmb3IgMSA8PSBpIDw9IG46CiAgICAgKgogICAgICogKyBJZiBUaSBpcyBhIHdpbGRjYXJkIHR5cGUgYXJndW1lbnQgKDQuNS4xKSBvZiB0aGUgZm9ybSA/IHRoZW4KICAgICAqICAgU2kgaXMgYSBmcmVzaCB0eXBlIHZhcmlhYmxlIHdob3NlIHVwcGVyIGJvdW5kIGlzCiAgICAgKiAgIFVpW0ExIDo9IFMxLCAuLi4sIEFuIDo9IFNuXSBhbmQgd2hvc2UgbG93ZXIgYm91bmQgaXMgdGhlIG51bGwKICAgICAqICAgdHlwZS4KICAgICAqCiAgICAgKiArIElmIFRpIGlzIGEgd2lsZGNhcmQgdHlwZSBhcmd1bWVudCBvZiB0aGUgZm9ybSA/IGV4dGVuZHMgQmksCiAgICAgKiAgIHRoZW4gU2kgaXMgYSBmcmVzaCB0eXBlIHZhcmlhYmxlIHdob3NlIHVwcGVyIGJvdW5kIGlzCiAgICAgKiAgIGdsYihCaSwgVWlbQTEgOj0gUzEsIC4uLiwgQW4gOj0gU25dKSBhbmQgd2hvc2UgbG93ZXIgYm91bmQgaXMKICAgICAqICAgdGhlIG51bGwgdHlwZSwgd2hlcmUgZ2xiKFYxLC4uLiAsVm0pIGlzIFYxICYgLi4uICYgVm0uIEl0IGlzCiAgICAgKiAgIGEgY29tcGlsZS10aW1lIGVycm9yIGlmIGZvciBhbnkgdHdvIGNsYXNzZXMgKG5vdCBpbnRlcmZhY2VzKQogICAgICogICBWaSBhbmQgVmosVmkgaXMgbm90IGEgc3ViY2xhc3Mgb2YgVmogb3IgdmljZSB2ZXJzYS4KICAgICAqCiAgICAgKiArIElmIFRpIGlzIGEgd2lsZGNhcmQgdHlwZSBhcmd1bWVudCBvZiB0aGUgZm9ybSA/IHN1cGVyIEJpLAogICAgICogICB0aGVuIFNpIGlzIGEgZnJlc2ggdHlwZSB2YXJpYWJsZSB3aG9zZSB1cHBlciBib3VuZCBpcwogICAgICogICBVaVtBMSA6PSBTMSwgLi4uLCBBbiA6PSBTbl0gYW5kIHdob3NlIGxvd2VyIGJvdW5kIGlzIEJpLgogICAgICoKICAgICAqICsgT3RoZXJ3aXNlLCBTaSA9IFRpLgogICAgICoKICAgICAqIENhcHR1cmUgY29udmVyc2lvbiBvbiBhbnkgdHlwZSBvdGhlciB0aGFuIGEgcGFyYW1ldGVyaXplZCB0eXBlCiAgICAgKiAoNC41KSBhY3RzIGFzIGFuIGlkZW50aXR5IGNvbnZlcnNpb24gKDUuMS4xKS4gQ2FwdHVyZQogICAgICogY29udmVyc2lvbnMgbmV2ZXIgcmVxdWlyZSBhIHNwZWNpYWwgYWN0aW9uIGF0IHJ1biB0aW1lIGFuZAogICAgICogdGhlcmVmb3JlIG5ldmVyIHRocm93IGFuIGV4Y2VwdGlvbiBhdCBydW4gdGltZS4KICAgICAqCiAgICAgKiBDYXB0dXJlIGNvbnZlcnNpb24gaXMgbm90IGFwcGxpZWQgcmVjdXJzaXZlbHkuCiAgICAgKi8KICAgIC8qKgogICAgICogQ2FwdHVyZSBjb252ZXJzaW9uIGFzIHNwZWNpZmllZCBieSB0aGUgSkxTLgogICAgICovCgogICAgcHVibGljIExpc3Q8VHlwZT4gY2FwdHVyZShMaXN0PFR5cGU+IHRzKSB7CiAgICAgICAgTGlzdDxUeXBlPiBidWYgPSBMaXN0Lm5pbCgpOwogICAgICAgIGZvciAoVHlwZSB0IDogdHMpIHsKICAgICAgICAgICAgYnVmID0gYnVmLnByZXBlbmQoY2FwdHVyZSh0KSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWYucmV2ZXJzZSgpOwogICAgfQoKICAgIHB1YmxpYyBUeXBlIGNhcHR1cmUoVHlwZSB0KSB7CiAgICAgICAgaWYgKCF0Lmhhc1RhZyhDTEFTUykpIHsKICAgICAgICAgICAgcmV0dXJuIHQ7CiAgICAgICAgfQogICAgICAgIGlmICh0LmdldEVuY2xvc2luZ1R5cGUoKSAhPSBUeXBlLm5vVHlwZSkgewogICAgICAgICAgICBUeXBlIGNhcHR1cmVkRW5jbCA9IGNhcHR1cmUodC5nZXRFbmNsb3NpbmdUeXBlKCkpOwogICAgICAgICAgICBpZiAoY2FwdHVyZWRFbmNsICE9IHQuZ2V0RW5jbG9zaW5nVHlwZSgpKSB7CiAgICAgICAgICAgICAgICBUeXBlIHR5cGUxID0gbWVtYmVyVHlwZShjYXB0dXJlZEVuY2wsIHQudHN5bSk7CiAgICAgICAgICAgICAgICB0ID0gc3Vic3QodHlwZTEsIHQudHN5bS50eXBlLmdldFR5cGVBcmd1bWVudHMoKSwgdC5nZXRUeXBlQXJndW1lbnRzKCkpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIENsYXNzVHlwZSBjbHMgPSAoQ2xhc3NUeXBlKXQ7CiAgICAgICAgaWYgKGNscy5pc1JhdygpIHx8ICFjbHMuaXNQYXJhbWV0ZXJpemVkKCkpCiAgICAgICAgICAgIHJldHVybiBjbHM7CgogICAgICAgIENsYXNzVHlwZSBHID0gKENsYXNzVHlwZSljbHMuYXNFbGVtZW50KCkuYXNUeXBlKCk7CiAgICAgICAgTGlzdDxUeXBlPiBBID0gRy5nZXRUeXBlQXJndW1lbnRzKCk7CiAgICAgICAgTGlzdDxUeXBlPiBUID0gY2xzLmdldFR5cGVBcmd1bWVudHMoKTsKICAgICAgICBMaXN0PFR5cGU+IFMgPSBmcmVzaFR5cGVWYXJpYWJsZXMoVCk7CgogICAgICAgIExpc3Q8VHlwZT4gY3VycmVudEEgPSBBOwogICAgICAgIExpc3Q8VHlwZT4gY3VycmVudFQgPSBUOwogICAgICAgIExpc3Q8VHlwZT4gY3VycmVudFMgPSBTOwogICAgICAgIGJvb2xlYW4gY2FwdHVyZWQgPSBmYWxzZTsKICAgICAgICB3aGlsZSAoIWN1cnJlbnRBLmlzRW1wdHkoKSAmJgogICAgICAgICAgICAgICAhY3VycmVudFQuaXNFbXB0eSgpICYmCiAgICAgICAgICAgICAgICFjdXJyZW50Uy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgaWYgKGN1cnJlbnRTLmhlYWQgIT0gY3VycmVudFQuaGVhZCkgewogICAgICAgICAgICAgICAgY2FwdHVyZWQgPSB0cnVlOwogICAgICAgICAgICAgICAgV2lsZGNhcmRUeXBlIFRpID0gKFdpbGRjYXJkVHlwZSljdXJyZW50VC5oZWFkOwogICAgICAgICAgICAgICAgVHlwZSBVaSA9IGN1cnJlbnRBLmhlYWQuZ2V0VXBwZXJCb3VuZCgpOwogICAgICAgICAgICAgICAgQ2FwdHVyZWRUeXBlIFNpID0gKENhcHR1cmVkVHlwZSljdXJyZW50Uy5oZWFkOwogICAgICAgICAgICAgICAgaWYgKFVpID09IG51bGwpCiAgICAgICAgICAgICAgICAgICAgVWkgPSBzeW1zLm9iamVjdFR5cGU7CiAgICAgICAgICAgICAgICBzd2l0Y2ggKFRpLmtpbmQpIHsKICAgICAgICAgICAgICAgIGNhc2UgVU5CT1VORDoKICAgICAgICAgICAgICAgICAgICBTaS5ib3VuZCA9IHN1YnN0KFVpLCBBLCBTKTsKICAgICAgICAgICAgICAgICAgICBTaS5sb3dlciA9IHN5bXMuYm90VHlwZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgRVhURU5EUzoKICAgICAgICAgICAgICAgICAgICBTaS5ib3VuZCA9IGdsYihUaS5nZXRFeHRlbmRzQm91bmQoKSwgc3Vic3QoVWksIEEsIFMpKTsKICAgICAgICAgICAgICAgICAgICBTaS5sb3dlciA9IHN5bXMuYm90VHlwZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgU1VQRVI6CiAgICAgICAgICAgICAgICAgICAgU2kuYm91bmQgPSBzdWJzdChVaSwgQSwgUyk7CiAgICAgICAgICAgICAgICAgICAgU2kubG93ZXIgPSBUaS5nZXRTdXBlckJvdW5kKCk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBUeXBlIHRtcEJvdW5kID0gU2kuYm91bmQuaGFzVGFnKFVOREVUVkFSKSA/ICgoVW5kZXRWYXIpU2kuYm91bmQpLnF0eXBlIDogU2kuYm91bmQ7CiAgICAgICAgICAgICAgICBUeXBlIHRtcExvd2VyID0gU2kubG93ZXIuaGFzVGFnKFVOREVUVkFSKSA/ICgoVW5kZXRWYXIpU2kubG93ZXIpLnF0eXBlIDogU2kubG93ZXI7CiAgICAgICAgICAgICAgICBpZiAoIVNpLmJvdW5kLmhhc1RhZyhFUlJPUikgJiYKICAgICAgICAgICAgICAgICAgICAhU2kubG93ZXIuaGFzVGFnKEVSUk9SKSAmJgogICAgICAgICAgICAgICAgICAgIGlzU2FtZVR5cGUodG1wQm91bmQsIHRtcExvd2VyLCBmYWxzZSkpIHsKICAgICAgICAgICAgICAgICAgICBjdXJyZW50Uy5oZWFkID0gU2kuYm91bmQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY3VycmVudEEgPSBjdXJyZW50QS50YWlsOwogICAgICAgICAgICBjdXJyZW50VCA9IGN1cnJlbnRULnRhaWw7CiAgICAgICAgICAgIGN1cnJlbnRTID0gY3VycmVudFMudGFpbDsKICAgICAgICB9CiAgICAgICAgaWYgKCFjdXJyZW50QS5pc0VtcHR5KCkgfHwgIWN1cnJlbnRULmlzRW1wdHkoKSB8fCAhY3VycmVudFMuaXNFbXB0eSgpKQogICAgICAgICAgICByZXR1cm4gZXJhc3VyZSh0KTsgLy8gc29tZSAicmFyZSIgdHlwZSBpbnZvbHZlZAoKICAgICAgICBpZiAoY2FwdHVyZWQpCiAgICAgICAgICAgIHJldHVybiBuZXcgQ2xhc3NUeXBlKGNscy5nZXRFbmNsb3NpbmdUeXBlKCksIFMsIGNscy50c3ltLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbHMuZ2V0TWV0YWRhdGEoKSk7CiAgICAgICAgZWxzZQogICAgICAgICAgICByZXR1cm4gdDsKICAgIH0KICAgIC8vIHdoZXJlCiAgICAgICAgcHVibGljIExpc3Q8VHlwZT4gZnJlc2hUeXBlVmFyaWFibGVzKExpc3Q8VHlwZT4gdHlwZXMpIHsKICAgICAgICAgICAgTGlzdEJ1ZmZlcjxUeXBlPiByZXN1bHQgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgIGZvciAoVHlwZSB0IDogdHlwZXMpIHsKICAgICAgICAgICAgICAgIGlmICh0Lmhhc1RhZyhXSUxEQ0FSRCkpIHsKICAgICAgICAgICAgICAgICAgICBUeXBlIGJvdW5kID0gKChXaWxkY2FyZFR5cGUpdCkuZ2V0RXh0ZW5kc0JvdW5kKCk7CiAgICAgICAgICAgICAgICAgICAgaWYgKGJvdW5kID09IG51bGwpCiAgICAgICAgICAgICAgICAgICAgICAgIGJvdW5kID0gc3ltcy5vYmplY3RUeXBlOwogICAgICAgICAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQobmV3IENhcHR1cmVkVHlwZShjYXB0dXJlZE5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5bXMubm9TeW1ib2wsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvdW5kLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeW1zLmJvdFR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChXaWxkY2FyZFR5cGUpdCkpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICByZXN1bHQuYXBwZW5kKHQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiByZXN1bHQudG9MaXN0KCk7CiAgICAgICAgfQogICAgLy8gPC9lZGl0b3ItZm9sZD4KCiAgICAvLyA8ZWRpdG9yLWZvbGQgZGVmYXVsdHN0YXRlPSJjb2xsYXBzZWQiIGRlc2M9IkludGVybmFsIHV0aWxpdHkgbWV0aG9kcyI+CiAgICBwcml2YXRlIGJvb2xlYW4gc2lkZUNhc3QoVHlwZSBmcm9tLCBUeXBlIHRvLCBXYXJuZXIgd2FybikgewogICAgICAgIC8vIFdlIGFyZSBjYXN0aW5nIGZyb20gdHlwZSAkZnJvbSQgdG8gdHlwZSAkdG8kLCB3aGljaCBhcmUKICAgICAgICAvLyBub24tZmluYWwgdW5yZWxhdGVkIHR5cGVzLiAgVGhpcyBtZXRob2QKICAgICAgICAvLyB0cmllcyB0byByZWplY3QgYSBjYXN0IGJ5IHRyYW5zZmVycmluZyB0eXBlIHBhcmFtZXRlcnMKICAgICAgICAvLyBmcm9tICR0byQgdG8gJGZyb20kIGJ5IGNvbW1vbiBzdXBlcmludGVyZmFjZXMuCiAgICAgICAgYm9vbGVhbiByZXZlcnNlID0gZmFsc2U7CiAgICAgICAgVHlwZSB0YXJnZXQgPSB0bzsKICAgICAgICBpZiAoKHRvLnRzeW0uZmxhZ3MoKSAmIElOVEVSRkFDRSkgPT0gMCkgewogICAgICAgICAgICBBc3NlcnQuY2hlY2soKGZyb20udHN5bS5mbGFncygpICYgSU5URVJGQUNFKSAhPSAwKTsKICAgICAgICAgICAgcmV2ZXJzZSA9IHRydWU7CiAgICAgICAgICAgIHRvID0gZnJvbTsKICAgICAgICAgICAgZnJvbSA9IHRhcmdldDsKICAgICAgICB9CiAgICAgICAgTGlzdDxUeXBlPiBjb21tb25TdXBlcnMgPSBzdXBlckNsb3N1cmUodG8sIGVyYXN1cmUoZnJvbSkpOwogICAgICAgIGJvb2xlYW4gZ2l2ZVdhcm5pbmcgPSBjb21tb25TdXBlcnMuaXNFbXB0eSgpOwogICAgICAgIC8vIFRoZSBhcmd1bWVudHMgdG8gdGhlIHN1cGVycyBjb3VsZCBiZSB1bmlmaWVkIGhlcmUgdG8KICAgICAgICAvLyBnZXQgYSBtb3JlIGFjY3VyYXRlIGFuYWx5c2lzCiAgICAgICAgd2hpbGUgKGNvbW1vblN1cGVycy5ub25FbXB0eSgpKSB7CiAgICAgICAgICAgIFR5cGUgdDEgPSBhc1N1cGVyKGZyb20sIGNvbW1vblN1cGVycy5oZWFkLnRzeW0pOwogICAgICAgICAgICBUeXBlIHQyID0gY29tbW9uU3VwZXJzLmhlYWQ7IC8vIHNhbWUgYXMgYXNTdXBlcih0bywgY29tbW9uU3VwZXJzLmhlYWQudHN5bSk7CiAgICAgICAgICAgIGlmIChkaXNqb2ludFR5cGVzKHQxLmdldFR5cGVBcmd1bWVudHMoKSwgdDIuZ2V0VHlwZUFyZ3VtZW50cygpKSkKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgZ2l2ZVdhcm5pbmcgPSBnaXZlV2FybmluZyB8fCAocmV2ZXJzZSA/IGdpdmVXYXJuaW5nKHQyLCB0MSkgOiBnaXZlV2FybmluZyh0MSwgdDIpKTsKICAgICAgICAgICAgY29tbW9uU3VwZXJzID0gY29tbW9uU3VwZXJzLnRhaWw7CiAgICAgICAgfQogICAgICAgIGlmIChnaXZlV2FybmluZyAmJiAhaXNSZWlmaWFibGUocmV2ZXJzZSA/IGZyb20gOiB0bykpCiAgICAgICAgICAgIHdhcm4ud2FybihMaW50Q2F0ZWdvcnkuVU5DSEVDS0VEKTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBwcml2YXRlIGJvb2xlYW4gc2lkZUNhc3RGaW5hbChUeXBlIGZyb20sIFR5cGUgdG8sIFdhcm5lciB3YXJuKSB7CiAgICAgICAgLy8gV2UgYXJlIGNhc3RpbmcgZnJvbSB0eXBlICRmcm9tJCB0byB0eXBlICR0byQsIHdoaWNoIGFyZQogICAgICAgIC8vIHVucmVsYXRlZCB0eXBlcyBvbmUgb2Ygd2hpY2ggaXMgZmluYWwgYW5kIHRoZSBvdGhlciBvZgogICAgICAgIC8vIHdoaWNoIGlzIGFuIGludGVyZmFjZS4gIFRoaXMgbWV0aG9kCiAgICAgICAgLy8gdHJpZXMgdG8gcmVqZWN0IGEgY2FzdCBieSB0cmFuc2ZlcnJpbmcgdHlwZSBwYXJhbWV0ZXJzCiAgICAgICAgLy8gZnJvbSB0aGUgZmluYWwgY2xhc3MgdG8gdGhlIGludGVyZmFjZS4KICAgICAgICBib29sZWFuIHJldmVyc2UgPSBmYWxzZTsKICAgICAgICBUeXBlIHRhcmdldCA9IHRvOwogICAgICAgIGlmICgodG8udHN5bS5mbGFncygpICYgSU5URVJGQUNFKSA9PSAwKSB7CiAgICAgICAgICAgIEFzc2VydC5jaGVjaygoZnJvbS50c3ltLmZsYWdzKCkgJiBJTlRFUkZBQ0UpICE9IDApOwogICAgICAgICAgICByZXZlcnNlID0gdHJ1ZTsKICAgICAgICAgICAgdG8gPSBmcm9tOwogICAgICAgICAgICBmcm9tID0gdGFyZ2V0OwogICAgICAgIH0KICAgICAgICBBc3NlcnQuY2hlY2soKGZyb20udHN5bS5mbGFncygpICYgRklOQUwpICE9IDApOwogICAgICAgIFR5cGUgdDEgPSBhc1N1cGVyKGZyb20sIHRvLnRzeW0pOwogICAgICAgIGlmICh0MSA9PSBudWxsKSByZXR1cm4gZmFsc2U7CiAgICAgICAgVHlwZSB0MiA9IHRvOwogICAgICAgIGlmIChkaXNqb2ludFR5cGVzKHQxLmdldFR5cGVBcmd1bWVudHMoKSwgdDIuZ2V0VHlwZUFyZ3VtZW50cygpKSkKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIGlmICghaXNSZWlmaWFibGUodGFyZ2V0KSAmJgogICAgICAgICAgICAocmV2ZXJzZSA/IGdpdmVXYXJuaW5nKHQyLCB0MSkgOiBnaXZlV2FybmluZyh0MSwgdDIpKSkKICAgICAgICAgICAgd2Fybi53YXJuKExpbnRDYXRlZ29yeS5VTkNIRUNLRUQpOwogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIHByaXZhdGUgYm9vbGVhbiBnaXZlV2FybmluZyhUeXBlIGZyb20sIFR5cGUgdG8pIHsKICAgICAgICBMaXN0PFR5cGU+IGJvdW5kcyA9IHRvLmlzQ29tcG91bmQoKSA/CiAgICAgICAgICAgICAgICBkaXJlY3RTdXBlcnR5cGVzKHRvKSA6IExpc3Qub2YodG8pOwogICAgICAgIGZvciAoVHlwZSBiIDogYm91bmRzKSB7CiAgICAgICAgICAgIFR5cGUgc3ViRnJvbSA9IGFzU3ViKGZyb20sIGIudHN5bSk7CiAgICAgICAgICAgIGlmIChiLmlzUGFyYW1ldGVyaXplZCgpICYmCiAgICAgICAgICAgICAgICAgICAgKCEoaXNVbmJvdW5kZWQoYikgfHwKICAgICAgICAgICAgICAgICAgICBpc1N1YnR5cGUoZnJvbSwgYikgfHwKICAgICAgICAgICAgICAgICAgICAoKHN1YkZyb20gIT0gbnVsbCkgJiYgY29udGFpbnNUeXBlKGIuYWxscGFyYW1zKCksIHN1YkZyb20uYWxscGFyYW1zKCkpKSkpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgcHJpdmF0ZSBMaXN0PFR5cGU+IHN1cGVyQ2xvc3VyZShUeXBlIHQsIFR5cGUgcykgewogICAgICAgIExpc3Q8VHlwZT4gY2wgPSBMaXN0Lm5pbCgpOwogICAgICAgIGZvciAoTGlzdDxUeXBlPiBsID0gaW50ZXJmYWNlcyh0KTsgbC5ub25FbXB0eSgpOyBsID0gbC50YWlsKSB7CiAgICAgICAgICAgIGlmIChpc1N1YnR5cGUocywgZXJhc3VyZShsLmhlYWQpKSkgewogICAgICAgICAgICAgICAgY2wgPSBpbnNlcnQoY2wsIGwuaGVhZCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBjbCA9IHVuaW9uKGNsLCBzdXBlckNsb3N1cmUobC5oZWFkLCBzKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIGNsOwogICAgfQoKICAgIHByaXZhdGUgYm9vbGVhbiBjb250YWluc1R5cGVFcXVpdmFsZW50KFR5cGUgdCwgVHlwZSBzKSB7CiAgICAgICAgcmV0dXJuIGlzU2FtZVR5cGUodCwgcykgfHwgLy8gc2hvcnRjdXQKICAgICAgICAgICAgY29udGFpbnNUeXBlKHQsIHMpICYmIGNvbnRhaW5zVHlwZShzLCB0KTsKICAgIH0KCiAgICAvLyA8ZWRpdG9yLWZvbGQgZGVmYXVsdHN0YXRlPSJjb2xsYXBzZWQiIGRlc2M9ImFkYXB0Ij4KICAgIC8qKgogICAgICogQWRhcHQgYSB0eXBlIGJ5IGNvbXB1dGluZyBhIHN1YnN0aXR1dGlvbiB3aGljaCBtYXBzIGEgc291cmNlCiAgICAgKiB0eXBlIHRvIGEgdGFyZ2V0IHR5cGUuCiAgICAgKgogICAgICogQHBhcmFtIHNvdXJjZSAgICB0aGUgc291cmNlIHR5cGUKICAgICAqIEBwYXJhbSB0YXJnZXQgICAgdGhlIHRhcmdldCB0eXBlCiAgICAgKiBAcGFyYW0gZnJvbSAgICAgIHRoZSB0eXBlIHZhcmlhYmxlcyBvZiB0aGUgY29tcHV0ZWQgc3Vic3RpdHV0aW9uCiAgICAgKiBAcGFyYW0gdG8gICAgICAgIHRoZSB0eXBlcyBvZiB0aGUgY29tcHV0ZWQgc3Vic3RpdHV0aW9uLgogICAgICovCiAgICBwdWJsaWMgdm9pZCBhZGFwdChUeXBlIHNvdXJjZSwKICAgICAgICAgICAgICAgICAgICAgICBUeXBlIHRhcmdldCwKICAgICAgICAgICAgICAgICAgICAgICBMaXN0QnVmZmVyPFR5cGU+IGZyb20sCiAgICAgICAgICAgICAgICAgICAgICAgTGlzdEJ1ZmZlcjxUeXBlPiB0bykgdGhyb3dzIEFkYXB0RmFpbHVyZSB7CiAgICAgICAgbmV3IEFkYXB0ZXIoZnJvbSwgdG8pLmFkYXB0KHNvdXJjZSwgdGFyZ2V0KTsKICAgIH0KCiAgICBjbGFzcyBBZGFwdGVyIGV4dGVuZHMgU2ltcGxlVmlzaXRvcjxWb2lkLCBUeXBlPiB7CgogICAgICAgIExpc3RCdWZmZXI8VHlwZT4gZnJvbTsKICAgICAgICBMaXN0QnVmZmVyPFR5cGU+IHRvOwogICAgICAgIE1hcDxTeW1ib2wsVHlwZT4gbWFwcGluZzsKCiAgICAgICAgQWRhcHRlcihMaXN0QnVmZmVyPFR5cGU+IGZyb20sIExpc3RCdWZmZXI8VHlwZT4gdG8pIHsKICAgICAgICAgICAgdGhpcy5mcm9tID0gZnJvbTsKICAgICAgICAgICAgdGhpcy50byA9IHRvOwogICAgICAgICAgICBtYXBwaW5nID0gbmV3IEhhc2hNYXA8PigpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHZvaWQgYWRhcHQoVHlwZSBzb3VyY2UsIFR5cGUgdGFyZ2V0KSB0aHJvd3MgQWRhcHRGYWlsdXJlIHsKICAgICAgICAgICAgdmlzaXQoc291cmNlLCB0YXJnZXQpOwogICAgICAgICAgICBMaXN0PFR5cGU+IGZyb21MaXN0ID0gZnJvbS50b0xpc3QoKTsKICAgICAgICAgICAgTGlzdDxUeXBlPiB0b0xpc3QgPSB0by50b0xpc3QoKTsKICAgICAgICAgICAgd2hpbGUgKCFmcm9tTGlzdC5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICAgIFR5cGUgdmFsID0gbWFwcGluZy5nZXQoZnJvbUxpc3QuaGVhZC50c3ltKTsKICAgICAgICAgICAgICAgIGlmICh0b0xpc3QuaGVhZCAhPSB2YWwpCiAgICAgICAgICAgICAgICAgICAgdG9MaXN0LmhlYWQgPSB2YWw7CiAgICAgICAgICAgICAgICBmcm9tTGlzdCA9IGZyb21MaXN0LnRhaWw7CiAgICAgICAgICAgICAgICB0b0xpc3QgPSB0b0xpc3QudGFpbDsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFZvaWQgdmlzaXRDbGFzc1R5cGUoQ2xhc3NUeXBlIHNvdXJjZSwgVHlwZSB0YXJnZXQpIHRocm93cyBBZGFwdEZhaWx1cmUgewogICAgICAgICAgICBpZiAodGFyZ2V0Lmhhc1RhZyhDTEFTUykpCiAgICAgICAgICAgICAgICBhZGFwdFJlY3Vyc2l2ZShzb3VyY2UuYWxscGFyYW1zKCksIHRhcmdldC5hbGxwYXJhbXMoKSk7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFZvaWQgdmlzaXRBcnJheVR5cGUoQXJyYXlUeXBlIHNvdXJjZSwgVHlwZSB0YXJnZXQpIHRocm93cyBBZGFwdEZhaWx1cmUgewogICAgICAgICAgICBpZiAodGFyZ2V0Lmhhc1RhZyhBUlJBWSkpCiAgICAgICAgICAgICAgICBhZGFwdFJlY3Vyc2l2ZShlbGVtdHlwZShzb3VyY2UpLCBlbGVtdHlwZSh0YXJnZXQpKTsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgVm9pZCB2aXNpdFdpbGRjYXJkVHlwZShXaWxkY2FyZFR5cGUgc291cmNlLCBUeXBlIHRhcmdldCkgdGhyb3dzIEFkYXB0RmFpbHVyZSB7CiAgICAgICAgICAgIGlmIChzb3VyY2UuaXNFeHRlbmRzQm91bmQoKSkKICAgICAgICAgICAgICAgIGFkYXB0UmVjdXJzaXZlKHdpbGRVcHBlckJvdW5kKHNvdXJjZSksIHdpbGRVcHBlckJvdW5kKHRhcmdldCkpOwogICAgICAgICAgICBlbHNlIGlmIChzb3VyY2UuaXNTdXBlckJvdW5kKCkpCiAgICAgICAgICAgICAgICBhZGFwdFJlY3Vyc2l2ZSh3aWxkTG93ZXJCb3VuZChzb3VyY2UpLCB3aWxkTG93ZXJCb3VuZCh0YXJnZXQpKTsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgVm9pZCB2aXNpdFR5cGVWYXIoVHlwZVZhciBzb3VyY2UsIFR5cGUgdGFyZ2V0KSB0aHJvd3MgQWRhcHRGYWlsdXJlIHsKICAgICAgICAgICAgLy8gQ2hlY2sgdG8gc2VlIGlmIHRoZXJlIGlzCiAgICAgICAgICAgIC8vIGFscmVhZHkgYSBtYXBwaW5nIGZvciAkc291cmNlJCwgaW4gd2hpY2ggY2FzZQogICAgICAgICAgICAvLyB0aGUgb2xkIG1hcHBpbmcgd2lsbCBiZSBtZXJnZWQgd2l0aCB0aGUgbmV3CiAgICAgICAgICAgIFR5cGUgdmFsID0gbWFwcGluZy5nZXQoc291cmNlLnRzeW0pOwogICAgICAgICAgICBpZiAodmFsICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIGlmICh2YWwuaXNTdXBlckJvdW5kKCkgJiYgdGFyZ2V0LmlzU3VwZXJCb3VuZCgpKSB7CiAgICAgICAgICAgICAgICAgICAgdmFsID0gaXNTdWJ0eXBlKHdpbGRMb3dlckJvdW5kKHZhbCksIHdpbGRMb3dlckJvdW5kKHRhcmdldCkpCiAgICAgICAgICAgICAgICAgICAgICAgID8gdGFyZ2V0IDogdmFsOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmICh2YWwuaXNFeHRlbmRzQm91bmQoKSAmJiB0YXJnZXQuaXNFeHRlbmRzQm91bmQoKSkgewogICAgICAgICAgICAgICAgICAgIHZhbCA9IGlzU3VidHlwZSh3aWxkVXBwZXJCb3VuZCh2YWwpLCB3aWxkVXBwZXJCb3VuZCh0YXJnZXQpKQogICAgICAgICAgICAgICAgICAgICAgICA/IHZhbCA6IHRhcmdldDsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoIWlzU2FtZVR5cGUodmFsLCB0YXJnZXQpKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFkYXB0RmFpbHVyZSgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdmFsID0gdGFyZ2V0OwogICAgICAgICAgICAgICAgZnJvbS5hcHBlbmQoc291cmNlKTsKICAgICAgICAgICAgICAgIHRvLmFwcGVuZCh0YXJnZXQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIG1hcHBpbmcucHV0KHNvdXJjZS50c3ltLCB2YWwpOwogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBWb2lkIHZpc2l0VHlwZShUeXBlIHNvdXJjZSwgVHlwZSB0YXJnZXQpIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIFNldDxUeXBlUGFpcj4gY2FjaGUgPSBuZXcgSGFzaFNldDw+KCk7CgogICAgICAgIHByaXZhdGUgdm9pZCBhZGFwdFJlY3Vyc2l2ZShUeXBlIHNvdXJjZSwgVHlwZSB0YXJnZXQpIHsKICAgICAgICAgICAgVHlwZVBhaXIgcGFpciA9IG5ldyBUeXBlUGFpcihzb3VyY2UsIHRhcmdldCk7CiAgICAgICAgICAgIGlmIChjYWNoZS5hZGQocGFpcikpIHsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgdmlzaXQoc291cmNlLCB0YXJnZXQpOwogICAgICAgICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgICAgICAgICBjYWNoZS5yZW1vdmUocGFpcik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHByaXZhdGUgdm9pZCBhZGFwdFJlY3Vyc2l2ZShMaXN0PFR5cGU+IHNvdXJjZSwgTGlzdDxUeXBlPiB0YXJnZXQpIHsKICAgICAgICAgICAgaWYgKHNvdXJjZS5sZW5ndGgoKSA9PSB0YXJnZXQubGVuZ3RoKCkpIHsKICAgICAgICAgICAgICAgIHdoaWxlIChzb3VyY2Uubm9uRW1wdHkoKSkgewogICAgICAgICAgICAgICAgICAgIGFkYXB0UmVjdXJzaXZlKHNvdXJjZS5oZWFkLCB0YXJnZXQuaGVhZCk7CiAgICAgICAgICAgICAgICAgICAgc291cmNlID0gc291cmNlLnRhaWw7CiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0ID0gdGFyZ2V0LnRhaWw7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjbGFzcyBBZGFwdEZhaWx1cmUgZXh0ZW5kcyBSdW50aW1lRXhjZXB0aW9uIHsKICAgICAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gLTc0OTAyMzE1NDgyNzI3MDE1NjZMOwogICAgfQoKICAgIHByaXZhdGUgdm9pZCBhZGFwdFNlbGYoVHlwZSB0LAogICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0QnVmZmVyPFR5cGU+IGZyb20sCiAgICAgICAgICAgICAgICAgICAgICAgICAgIExpc3RCdWZmZXI8VHlwZT4gdG8pIHsKICAgICAgICB0cnkgewogICAgICAgICAgICAvL2lmICh0LnRzeW0udHlwZSAhPSB0KQogICAgICAgICAgICAgICAgYWRhcHQodC50c3ltLnR5cGUsIHQsIGZyb20sIHRvKTsKICAgICAgICB9IGNhdGNoIChBZGFwdEZhaWx1cmUgZXgpIHsKICAgICAgICAgICAgLy8gQWRhcHQgc2hvdWxkIG5ldmVyIGZhaWwgY2FsY3VsYXRpbmcgYSBtYXBwaW5nIGZyb20KICAgICAgICAgICAgLy8gdC50c3ltLnR5cGUgdG8gdCBhcyB0aGVyZSBjYW4gYmUgbm8gbWVyZ2UgcHJvYmxlbS4KICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKGV4KTsKICAgICAgICB9CiAgICB9CiAgICAvLyA8L2VkaXRvci1mb2xkPgoKICAgIC8qKgogICAgICogUmV3cml0ZSBhbGwgdHlwZSB2YXJpYWJsZXMgKHVuaXZlcnNhbCBxdWFudGlmaWVycykgaW4gdGhlIGdpdmVuCiAgICAgKiB0eXBlIHRvIHdpbGRjYXJkcyAoZXhpc3RlbnRpYWwgcXVhbnRpZmllcnMpLiAgVGhpcyBpcyB1c2VkIHRvCiAgICAgKiBkZXRlcm1pbmUgaWYgYSBjYXN0IGlzIGFsbG93ZWQuICBGb3IgZXhhbXBsZSwgaWYgaGlnaCBpcyB0cnVlCiAgICAgKiBhbmQge0Bjb2RlIFQgPDogTnVtYmVyfSwgdGhlbiB7QGNvZGUgTGlzdDxUPn0gaXMgcmV3cml0dGVuIHRvCiAgICAgKiB7QGNvZGUgTGlzdDw/ICBleHRlbmRzIE51bWJlcj59LiAgU2luY2Uge0Bjb2RlIExpc3Q8SW50ZWdlcj4gPDoKICAgICAqIExpc3Q8PyBleHRlbmRzIE51bWJlcj59IGEge0Bjb2RlIExpc3Q8VD59IGNhbiBiZSBjYXN0IHRvIHtAY29kZQogICAgICogTGlzdDxJbnRlZ2VyPn0gd2l0aCBhIHdhcm5pbmcuCiAgICAgKiBAcGFyYW0gdCBhIHR5cGUKICAgICAqIEBwYXJhbSBoaWdoIGlmIHRydWUgcmV0dXJuIGFuIHVwcGVyIGJvdW5kOyBvdGhlcndpc2UgYSBsb3dlcgogICAgICogYm91bmQKICAgICAqIEBwYXJhbSByZXdyaXRlVHlwZVZhcnMgb25seSByZXdyaXRlIGNhcHR1cmVkIHdpbGRjYXJkcyBpZiBmYWxzZTsKICAgICAqIG90aGVyd2lzZSByZXdyaXRlIGFsbCB0eXBlIHZhcmlhYmxlcwogICAgICogQHJldHVybiB0aGUgdHlwZSByZXdyaXR0ZW4gd2l0aCB3aWxkY2FyZHMgKGV4aXN0ZW50aWFsCiAgICAgKiBxdWFudGlmaWVycykgb25seQogICAgICovCiAgICBwcml2YXRlIFR5cGUgcmV3cml0ZVF1YW50aWZpZXJzKFR5cGUgdCwgYm9vbGVhbiBoaWdoLCBib29sZWFuIHJld3JpdGVUeXBlVmFycykgewogICAgICAgIHJldHVybiBuZXcgUmV3cml0ZXIoaGlnaCwgcmV3cml0ZVR5cGVWYXJzKS52aXNpdCh0KTsKICAgIH0KCiAgICBjbGFzcyBSZXdyaXRlciBleHRlbmRzIFVuYXJ5VmlzaXRvcjxUeXBlPiB7CgogICAgICAgIGJvb2xlYW4gaGlnaDsKICAgICAgICBib29sZWFuIHJld3JpdGVUeXBlVmFyczsKCiAgICAgICAgUmV3cml0ZXIoYm9vbGVhbiBoaWdoLCBib29sZWFuIHJld3JpdGVUeXBlVmFycykgewogICAgICAgICAgICB0aGlzLmhpZ2ggPSBoaWdoOwogICAgICAgICAgICB0aGlzLnJld3JpdGVUeXBlVmFycyA9IHJld3JpdGVUeXBlVmFyczsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBUeXBlIHZpc2l0Q2xhc3NUeXBlKENsYXNzVHlwZSB0LCBWb2lkIHMpIHsKICAgICAgICAgICAgTGlzdEJ1ZmZlcjxUeXBlPiByZXdyaXR0ZW4gPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgIGJvb2xlYW4gY2hhbmdlZCA9IGZhbHNlOwogICAgICAgICAgICBmb3IgKFR5cGUgYXJnIDogdC5hbGxwYXJhbXMoKSkgewogICAgICAgICAgICAgICAgVHlwZSBib3VuZCA9IHZpc2l0KGFyZyk7CiAgICAgICAgICAgICAgICBpZiAoYXJnICE9IGJvdW5kKSB7CiAgICAgICAgICAgICAgICAgICAgY2hhbmdlZCA9IHRydWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXdyaXR0ZW4uYXBwZW5kKGJvdW5kKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoY2hhbmdlZCkKICAgICAgICAgICAgICAgIHJldHVybiBzdWJzdCh0LnRzeW0udHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgdC50c3ltLnR5cGUuYWxscGFyYW1zKCksCiAgICAgICAgICAgICAgICAgICAgICAgIHJld3JpdHRlbi50b0xpc3QoKSk7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHJldHVybiB0OwogICAgICAgIH0KCiAgICAgICAgcHVibGljIFR5cGUgdmlzaXRUeXBlKFR5cGUgdCwgVm9pZCBzKSB7CiAgICAgICAgICAgIHJldHVybiB0OwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFR5cGUgdmlzaXRDYXB0dXJlZFR5cGUoQ2FwdHVyZWRUeXBlIHQsIFZvaWQgcykgewogICAgICAgICAgICBUeXBlIHdfYm91bmQgPSB0LndpbGRjYXJkLnR5cGU7CiAgICAgICAgICAgIFR5cGUgYm91bmQgPSB3X2JvdW5kLmNvbnRhaW5zKHQpID8KICAgICAgICAgICAgICAgICAgICAgICAgZXJhc3VyZSh3X2JvdW5kKSA6CiAgICAgICAgICAgICAgICAgICAgICAgIHZpc2l0KHdfYm91bmQpOwogICAgICAgICAgICByZXR1cm4gcmV3cml0ZUFzV2lsZGNhcmRUeXBlKHZpc2l0KGJvdW5kKSwgdC53aWxkY2FyZC5ib3VuZCwgdC53aWxkY2FyZC5raW5kKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBUeXBlIHZpc2l0VHlwZVZhcihUeXBlVmFyIHQsIFZvaWQgcykgewogICAgICAgICAgICBpZiAocmV3cml0ZVR5cGVWYXJzKSB7CiAgICAgICAgICAgICAgICBUeXBlIGJvdW5kID0gdC5ib3VuZC5jb250YWlucyh0KSA/CiAgICAgICAgICAgICAgICAgICAgICAgIGVyYXN1cmUodC5ib3VuZCkgOgogICAgICAgICAgICAgICAgICAgICAgICB2aXNpdCh0LmJvdW5kKTsKICAgICAgICAgICAgICAgIHJldHVybiByZXdyaXRlQXNXaWxkY2FyZFR5cGUoYm91bmQsIHQsIEVYVEVORFMpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcmV0dXJuIHQ7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBUeXBlIHZpc2l0V2lsZGNhcmRUeXBlKFdpbGRjYXJkVHlwZSB0LCBWb2lkIHMpIHsKICAgICAgICAgICAgVHlwZSBib3VuZDIgPSB2aXNpdCh0LnR5cGUpOwogICAgICAgICAgICByZXR1cm4gdC50eXBlID09IGJvdW5kMiA/IHQgOiByZXdyaXRlQXNXaWxkY2FyZFR5cGUoYm91bmQyLCB0LmJvdW5kLCB0LmtpbmQpOwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBUeXBlIHJld3JpdGVBc1dpbGRjYXJkVHlwZShUeXBlIGJvdW5kLCBUeXBlVmFyIGZvcm1hbCwgQm91bmRLaW5kIGJrKSB7CiAgICAgICAgICAgIHN3aXRjaCAoYmspIHsKICAgICAgICAgICAgICAgY2FzZSBFWFRFTkRTOiByZXR1cm4gaGlnaCA/CiAgICAgICAgICAgICAgICAgICAgICAgbWFrZUV4dGVuZHNXaWxkY2FyZChCKGJvdW5kKSwgZm9ybWFsKSA6CiAgICAgICAgICAgICAgICAgICAgICAgbWFrZUV4dGVuZHNXaWxkY2FyZChzeW1zLm9iamVjdFR5cGUsIGZvcm1hbCk7CiAgICAgICAgICAgICAgIGNhc2UgU1VQRVI6IHJldHVybiBoaWdoID8KICAgICAgICAgICAgICAgICAgICAgICBtYWtlU3VwZXJXaWxkY2FyZChzeW1zLmJvdFR5cGUsIGZvcm1hbCkgOgogICAgICAgICAgICAgICAgICAgICAgIG1ha2VTdXBlcldpbGRjYXJkKEIoYm91bmQpLCBmb3JtYWwpOwogICAgICAgICAgICAgICBjYXNlIFVOQk9VTkQ6IHJldHVybiBtYWtlRXh0ZW5kc1dpbGRjYXJkKHN5bXMub2JqZWN0VHlwZSwgZm9ybWFsKTsKICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgIEFzc2VydC5lcnJvcigiSW52YWxpZCBib3VuZCBraW5kICIgKyBiayk7CiAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgVHlwZSBCKFR5cGUgdCkgewogICAgICAgICAgICB3aGlsZSAodC5oYXNUYWcoV0lMRENBUkQpKSB7CiAgICAgICAgICAgICAgICBXaWxkY2FyZFR5cGUgdyA9IChXaWxkY2FyZFR5cGUpdDsKICAgICAgICAgICAgICAgIHQgPSBoaWdoID8KICAgICAgICAgICAgICAgICAgICB3LmdldEV4dGVuZHNCb3VuZCgpIDoKICAgICAgICAgICAgICAgICAgICB3LmdldFN1cGVyQm91bmQoKTsKICAgICAgICAgICAgICAgIGlmICh0ID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICB0ID0gaGlnaCA/IHN5bXMub2JqZWN0VHlwZSA6IHN5bXMuYm90VHlwZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gdDsKICAgICAgICB9CiAgICB9CgoKICAgIC8qKgogICAgICogQ3JlYXRlIGEgd2lsZGNhcmQgd2l0aCB0aGUgZ2l2ZW4gdXBwZXIgKGV4dGVuZHMpIGJvdW5kOyBjcmVhdGUKICAgICAqIGFuIHVuYm91bmRlZCB3aWxkY2FyZCBpZiBib3VuZCBpcyBPYmplY3QuCiAgICAgKgogICAgICogQHBhcmFtIGJvdW5kIHRoZSB1cHBlciBib3VuZAogICAgICogQHBhcmFtIGZvcm1hbCB0aGUgZm9ybWFsIHR5cGUgcGFyYW1ldGVyIHRoYXQgd2lsbCBiZQogICAgICogc3Vic3RpdHV0ZWQgYnkgdGhlIHdpbGRjYXJkCiAgICAgKi8KICAgIHByaXZhdGUgV2lsZGNhcmRUeXBlIG1ha2VFeHRlbmRzV2lsZGNhcmQoVHlwZSBib3VuZCwgVHlwZVZhciBmb3JtYWwpIHsKICAgICAgICBpZiAoYm91bmQgPT0gc3ltcy5vYmplY3RUeXBlKSB7CiAgICAgICAgICAgIHJldHVybiBuZXcgV2lsZGNhcmRUeXBlKHN5bXMub2JqZWN0VHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQm91bmRLaW5kLlVOQk9VTkQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5bXMuYm91bmRDbGFzcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9ybWFsKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gbmV3IFdpbGRjYXJkVHlwZShib3VuZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQm91bmRLaW5kLkVYVEVORFMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5bXMuYm91bmRDbGFzcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9ybWFsKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBDcmVhdGUgYSB3aWxkY2FyZCB3aXRoIHRoZSBnaXZlbiBsb3dlciAoc3VwZXIpIGJvdW5kOyBjcmVhdGUgYW4KICAgICAqIHVuYm91bmRlZCB3aWxkY2FyZCBpZiBib3VuZCBpcyBib3R0b20gKHR5cGUgb2Yge0Bjb2RlIG51bGx9KS4KICAgICAqCiAgICAgKiBAcGFyYW0gYm91bmQgdGhlIGxvd2VyIGJvdW5kCiAgICAgKiBAcGFyYW0gZm9ybWFsIHRoZSBmb3JtYWwgdHlwZSBwYXJhbWV0ZXIgdGhhdCB3aWxsIGJlCiAgICAgKiBzdWJzdGl0dXRlZCBieSB0aGUgd2lsZGNhcmQKICAgICAqLwogICAgcHJpdmF0ZSBXaWxkY2FyZFR5cGUgbWFrZVN1cGVyV2lsZGNhcmQoVHlwZSBib3VuZCwgVHlwZVZhciBmb3JtYWwpIHsKICAgICAgICBpZiAoYm91bmQuaGFzVGFnKEJPVCkpIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyBXaWxkY2FyZFR5cGUoc3ltcy5vYmplY3RUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCb3VuZEtpbmQuVU5CT1VORCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ltcy5ib3VuZENsYXNzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JtYWwpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiBuZXcgV2lsZGNhcmRUeXBlKGJvdW5kLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCb3VuZEtpbmQuU1VQRVIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5bXMuYm91bmRDbGFzcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9ybWFsKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBBIHdyYXBwZXIgZm9yIGEgdHlwZSB0aGF0IGFsbG93cyB1c2UgaW4gc2V0cy4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBjbGFzcyBVbmlxdWVUeXBlIHsKICAgICAgICBwdWJsaWMgZmluYWwgVHlwZSB0eXBlOwogICAgICAgIGZpbmFsIFR5cGVzIHR5cGVzOwoKICAgICAgICBwdWJsaWMgVW5pcXVlVHlwZShUeXBlIHR5cGUsIFR5cGVzIHR5cGVzKSB7CiAgICAgICAgICAgIHRoaXMudHlwZSA9IHR5cGU7CiAgICAgICAgICAgIHRoaXMudHlwZXMgPSB0eXBlczsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgICAgICAgIHJldHVybiB0eXBlcy5oYXNoQ29kZSh0eXBlKTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqKSB7CiAgICAgICAgICAgIHJldHVybiAob2JqIGluc3RhbmNlb2YgVW5pcXVlVHlwZSkgJiYKICAgICAgICAgICAgICAgIHR5cGVzLmlzU2FtZVR5cGUodHlwZSwgKChVbmlxdWVUeXBlKW9iaikudHlwZSk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewogICAgICAgICAgICByZXR1cm4gdHlwZS50b1N0cmluZygpOwogICAgICAgIH0KCiAgICB9CiAgICAvLyA8L2VkaXRvci1mb2xkPgoKICAgIC8vIDxlZGl0b3ItZm9sZCBkZWZhdWx0c3RhdGU9ImNvbGxhcHNlZCIgZGVzYz0iVmlzaXRvcnMiPgogICAgLyoqCiAgICAgKiBBIGRlZmF1bHQgdmlzaXRvciBmb3IgdHlwZXMuICBBbGwgdmlzaXRvciBtZXRob2RzIGV4Y2VwdAogICAgICogdmlzaXRUeXBlIGFyZSBpbXBsZW1lbnRlZCBieSBkZWxlZ2F0aW5nIHRvIHZpc2l0VHlwZS4gIENvbmNyZXRlCiAgICAgKiBzdWJjbGFzc2VzIG11c3QgcHJvdmlkZSBhbiBpbXBsZW1lbnRhdGlvbiBvZiB2aXNpdFR5cGUgYW5kIGNhbgogICAgICogb3ZlcnJpZGUgb3RoZXIgbWV0aG9kcyBhcyBuZWVkZWQuCiAgICAgKgogICAgICogQHBhcmFtIDxSPiB0aGUgcmV0dXJuIHR5cGUgb2YgdGhlIG9wZXJhdGlvbiBpbXBsZW1lbnRlZCBieSB0aGlzCiAgICAgKiB2aXNpdG9yOyB1c2UgVm9pZCBpZiBubyByZXR1cm4gdHlwZSBpcyBuZWVkZWQuCiAgICAgKiBAcGFyYW0gPFM+IHRoZSB0eXBlIG9mIHRoZSBzZWNvbmQgYXJndW1lbnQgKHRoZSBmaXJzdCBiZWluZyB0aGUKICAgICAqIHR5cGUgaXRzZWxmKSBvZiB0aGUgb3BlcmF0aW9uIGltcGxlbWVudGVkIGJ5IHRoaXMgdmlzaXRvcjsgdXNlCiAgICAgKiBWb2lkIGlmIGEgc2Vjb25kIGFyZ3VtZW50IGlzIG5vdCBuZWVkZWQuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgYWJzdHJhY3QgY2xhc3MgRGVmYXVsdFR5cGVWaXNpdG9yPFIsUz4gaW1wbGVtZW50cyBUeXBlLlZpc2l0b3I8UixTPiB7CiAgICAgICAgZmluYWwgcHVibGljIFIgdmlzaXQoVHlwZSB0LCBTIHMpICAgICAgICAgICAgICAgeyByZXR1cm4gdC5hY2NlcHQodGhpcywgcyk7IH0KICAgICAgICBwdWJsaWMgUiB2aXNpdENsYXNzVHlwZShDbGFzc1R5cGUgdCwgUyBzKSAgICAgICB7IHJldHVybiB2aXNpdFR5cGUodCwgcyk7IH0KICAgICAgICBwdWJsaWMgUiB2aXNpdFdpbGRjYXJkVHlwZShXaWxkY2FyZFR5cGUgdCwgUyBzKSB7IHJldHVybiB2aXNpdFR5cGUodCwgcyk7IH0KICAgICAgICBwdWJsaWMgUiB2aXNpdEFycmF5VHlwZShBcnJheVR5cGUgdCwgUyBzKSAgICAgICB7IHJldHVybiB2aXNpdFR5cGUodCwgcyk7IH0KICAgICAgICBwdWJsaWMgUiB2aXNpdE1ldGhvZFR5cGUoTWV0aG9kVHlwZSB0LCBTIHMpICAgICB7IHJldHVybiB2aXNpdFR5cGUodCwgcyk7IH0KICAgICAgICBwdWJsaWMgUiB2aXNpdFBhY2thZ2VUeXBlKFBhY2thZ2VUeXBlIHQsIFMgcykgICB7IHJldHVybiB2aXNpdFR5cGUodCwgcyk7IH0KICAgICAgICBwdWJsaWMgUiB2aXNpdE1vZHVsZVR5cGUoTW9kdWxlVHlwZSB0LCBTIHMpICAgICB7IHJldHVybiB2aXNpdFR5cGUodCwgcyk7IH0KICAgICAgICBwdWJsaWMgUiB2aXNpdFR5cGVWYXIoVHlwZVZhciB0LCBTIHMpICAgICAgICAgICB7IHJldHVybiB2aXNpdFR5cGUodCwgcyk7IH0KICAgICAgICBwdWJsaWMgUiB2aXNpdENhcHR1cmVkVHlwZShDYXB0dXJlZFR5cGUgdCwgUyBzKSB7IHJldHVybiB2aXNpdFR5cGUodCwgcyk7IH0KICAgICAgICBwdWJsaWMgUiB2aXNpdEZvckFsbChGb3JBbGwgdCwgUyBzKSAgICAgICAgICAgICB7IHJldHVybiB2aXNpdFR5cGUodCwgcyk7IH0KICAgICAgICBwdWJsaWMgUiB2aXNpdFVuZGV0VmFyKFVuZGV0VmFyIHQsIFMgcykgICAgICAgICB7IHJldHVybiB2aXNpdFR5cGUodCwgcyk7IH0KICAgICAgICBwdWJsaWMgUiB2aXNpdEVycm9yVHlwZShFcnJvclR5cGUgdCwgUyBzKSAgICAgICB7IHJldHVybiB2aXNpdFR5cGUodCwgcyk7IH0KICAgIH0KCiAgICAvKioKICAgICAqIEEgZGVmYXVsdCB2aXNpdG9yIGZvciBzeW1ib2xzLiAgQWxsIHZpc2l0b3IgbWV0aG9kcyBleGNlcHQKICAgICAqIHZpc2l0U3ltYm9sIGFyZSBpbXBsZW1lbnRlZCBieSBkZWxlZ2F0aW5nIHRvIHZpc2l0U3ltYm9sLiAgQ29uY3JldGUKICAgICAqIHN1YmNsYXNzZXMgbXVzdCBwcm92aWRlIGFuIGltcGxlbWVudGF0aW9uIG9mIHZpc2l0U3ltYm9sIGFuZCBjYW4KICAgICAqIG92ZXJyaWRlIG90aGVyIG1ldGhvZHMgYXMgbmVlZGVkLgogICAgICoKICAgICAqIEBwYXJhbSA8Uj4gdGhlIHJldHVybiB0eXBlIG9mIHRoZSBvcGVyYXRpb24gaW1wbGVtZW50ZWQgYnkgdGhpcwogICAgICogdmlzaXRvcjsgdXNlIFZvaWQgaWYgbm8gcmV0dXJuIHR5cGUgaXMgbmVlZGVkLgogICAgICogQHBhcmFtIDxTPiB0aGUgdHlwZSBvZiB0aGUgc2Vjb25kIGFyZ3VtZW50ICh0aGUgZmlyc3QgYmVpbmcgdGhlCiAgICAgKiBzeW1ib2wgaXRzZWxmKSBvZiB0aGUgb3BlcmF0aW9uIGltcGxlbWVudGVkIGJ5IHRoaXMgdmlzaXRvcjsgdXNlCiAgICAgKiBWb2lkIGlmIGEgc2Vjb25kIGFyZ3VtZW50IGlzIG5vdCBuZWVkZWQuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgYWJzdHJhY3QgY2xhc3MgRGVmYXVsdFN5bWJvbFZpc2l0b3I8UixTPiBpbXBsZW1lbnRzIFN5bWJvbC5WaXNpdG9yPFIsUz4gewogICAgICAgIGZpbmFsIHB1YmxpYyBSIHZpc2l0KFN5bWJvbCBzLCBTIGFyZykgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gcy5hY2NlcHQodGhpcywgYXJnKTsgfQogICAgICAgIHB1YmxpYyBSIHZpc2l0Q2xhc3NTeW1ib2woQ2xhc3NTeW1ib2wgcywgUyBhcmcpICAgICAgICAgeyByZXR1cm4gdmlzaXRTeW1ib2wocywgYXJnKTsgfQogICAgICAgIHB1YmxpYyBSIHZpc2l0TWV0aG9kU3ltYm9sKE1ldGhvZFN5bWJvbCBzLCBTIGFyZykgICAgICAgeyByZXR1cm4gdmlzaXRTeW1ib2wocywgYXJnKTsgfQogICAgICAgIHB1YmxpYyBSIHZpc2l0T3BlcmF0b3JTeW1ib2woT3BlcmF0b3JTeW1ib2wgcywgUyBhcmcpICAgeyByZXR1cm4gdmlzaXRTeW1ib2wocywgYXJnKTsgfQogICAgICAgIHB1YmxpYyBSIHZpc2l0UGFja2FnZVN5bWJvbChQYWNrYWdlU3ltYm9sIHMsIFMgYXJnKSAgICAgeyByZXR1cm4gdmlzaXRTeW1ib2wocywgYXJnKTsgfQogICAgICAgIHB1YmxpYyBSIHZpc2l0VHlwZVN5bWJvbChUeXBlU3ltYm9sIHMsIFMgYXJnKSAgICAgICAgICAgeyByZXR1cm4gdmlzaXRTeW1ib2wocywgYXJnKTsgfQogICAgICAgIHB1YmxpYyBSIHZpc2l0VmFyU3ltYm9sKFZhclN5bWJvbCBzLCBTIGFyZykgICAgICAgICAgICAgeyByZXR1cm4gdmlzaXRTeW1ib2wocywgYXJnKTsgfQogICAgfQoKICAgIC8qKgogICAgICogQSA8ZW0+c2ltcGxlPC9lbT4gdmlzaXRvciBmb3IgdHlwZXMuICBUaGlzIHZpc2l0b3IgaXMgc2ltcGxlIGFzCiAgICAgKiBjYXB0dXJlZCB3aWxkY2FyZHMsIGZvci1hbGwgdHlwZXMgKGdlbmVyaWMgbWV0aG9kcyksIGFuZAogICAgICogdW5kZXRlcm1pbmVkIHR5cGUgdmFyaWFibGVzIChwYXJ0IG9mIGluZmVyZW5jZSkgYXJlIGhpZGRlbi4KICAgICAqIENhcHR1cmVkIHdpbGRjYXJkcyBhcmUgaGlkZGVuIGJ5IHRyZWF0aW5nIHRoZW0gYXMgdHlwZQogICAgICogdmFyaWFibGVzIGFuZCB0aGUgcmVzdCBhcmUgaGlkZGVuIGJ5IHZpc2l0aW5nIHRoZWlyIHF0eXBlcy4KICAgICAqCiAgICAgKiBAcGFyYW0gPFI+IHRoZSByZXR1cm4gdHlwZSBvZiB0aGUgb3BlcmF0aW9uIGltcGxlbWVudGVkIGJ5IHRoaXMKICAgICAqIHZpc2l0b3I7IHVzZSBWb2lkIGlmIG5vIHJldHVybiB0eXBlIGlzIG5lZWRlZC4KICAgICAqIEBwYXJhbSA8Uz4gdGhlIHR5cGUgb2YgdGhlIHNlY29uZCBhcmd1bWVudCAodGhlIGZpcnN0IGJlaW5nIHRoZQogICAgICogdHlwZSBpdHNlbGYpIG9mIHRoZSBvcGVyYXRpb24gaW1wbGVtZW50ZWQgYnkgdGhpcyB2aXNpdG9yOyB1c2UKICAgICAqIFZvaWQgaWYgYSBzZWNvbmQgYXJndW1lbnQgaXMgbm90IG5lZWRlZC4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBhYnN0cmFjdCBjbGFzcyBTaW1wbGVWaXNpdG9yPFIsUz4gZXh0ZW5kcyBEZWZhdWx0VHlwZVZpc2l0b3I8UixTPiB7CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFIgdmlzaXRDYXB0dXJlZFR5cGUoQ2FwdHVyZWRUeXBlIHQsIFMgcykgewogICAgICAgICAgICByZXR1cm4gdmlzaXRUeXBlVmFyKHQsIHMpOwogICAgICAgIH0KICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgUiB2aXNpdEZvckFsbChGb3JBbGwgdCwgUyBzKSB7CiAgICAgICAgICAgIHJldHVybiB2aXNpdCh0LnF0eXBlLCBzKTsKICAgICAgICB9CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFIgdmlzaXRVbmRldFZhcihVbmRldFZhciB0LCBTIHMpIHsKICAgICAgICAgICAgcmV0dXJuIHZpc2l0KHQucXR5cGUsIHMpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEEgcGxhaW4gcmVsYXRpb24gb24gdHlwZXMuICBUaGF0IGlzIGEgMi1hcnkgZnVuY3Rpb24gb24gdGhlCiAgICAgKiBmb3JtIFR5cGUmbmJzcDsmdGltZXM7Jm5ic3A7VHlwZSZuYnNwOyZyYXJyOyZuYnNwO0Jvb2xlYW4uCiAgICAgKiA8IS0tIEluIHBsYWluIHRleHQ6IFR5cGUgeCBUeXBlIC0+IEJvb2xlYW4gLS0+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgYWJzdHJhY3QgY2xhc3MgVHlwZVJlbGF0aW9uIGV4dGVuZHMgU2ltcGxlVmlzaXRvcjxCb29sZWFuLFR5cGU+IHt9CgogICAgLyoqCiAgICAgKiBBIGNvbnZlbmllbmNlIHZpc2l0b3IgZm9yIGltcGxlbWVudGluZyBvcGVyYXRpb25zIHRoYXQgb25seQogICAgICogcmVxdWlyZSBvbmUgYXJndW1lbnQgKHRoZSB0eXBlIGl0c2VsZiksIHRoYXQgaXMsIHVuYXJ5CiAgICAgKiBvcGVyYXRpb25zLgogICAgICoKICAgICAqIEBwYXJhbSA8Uj4gdGhlIHJldHVybiB0eXBlIG9mIHRoZSBvcGVyYXRpb24gaW1wbGVtZW50ZWQgYnkgdGhpcwogICAgICogdmlzaXRvcjsgdXNlIFZvaWQgaWYgbm8gcmV0dXJuIHR5cGUgaXMgbmVlZGVkLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGFic3RyYWN0IGNsYXNzIFVuYXJ5VmlzaXRvcjxSPiBleHRlbmRzIFNpbXBsZVZpc2l0b3I8UixWb2lkPiB7CiAgICAgICAgZmluYWwgcHVibGljIFIgdmlzaXQoVHlwZSB0KSB7IHJldHVybiB0LmFjY2VwdCh0aGlzLCBudWxsKTsgfQogICAgfQoKICAgIC8qKgogICAgICogQSB2aXNpdG9yIGZvciBpbXBsZW1lbnRpbmcgYSBtYXBwaW5nIGZyb20gdHlwZXMgdG8gdHlwZXMuICBUaGUKICAgICAqIGRlZmF1bHQgYmVoYXZpb3Igb2YgdGhpcyBjbGFzcyBpcyB0byBpbXBsZW1lbnQgdGhlIGlkZW50aXR5CiAgICAgKiBtYXBwaW5nIChtYXBwaW5nIGEgdHlwZSB0byBpdHNlbGYpLiAgVGhpcyBjYW4gYmUgb3ZlcnJpZGRlbiBpbgogICAgICogc3ViY2xhc3Nlcy4KICAgICAqCiAgICAgKiBAcGFyYW0gPFM+IHRoZSB0eXBlIG9mIHRoZSBzZWNvbmQgYXJndW1lbnQgKHRoZSBmaXJzdCBiZWluZyB0aGUKICAgICAqIHR5cGUgaXRzZWxmKSBvZiB0aGlzIG1hcHBpbmc7IHVzZSBWb2lkIGlmIGEgc2Vjb25kIGFyZ3VtZW50IGlzCiAgICAgKiBub3QgbmVlZGVkLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIE1hcFZpc2l0b3I8Uz4gZXh0ZW5kcyBEZWZhdWx0VHlwZVZpc2l0b3I8VHlwZSxTPiB7CiAgICAgICAgZmluYWwgcHVibGljIFR5cGUgdmlzaXQoVHlwZSB0KSB7IHJldHVybiB0LmFjY2VwdCh0aGlzLCBudWxsKTsgfQogICAgICAgIHB1YmxpYyBUeXBlIHZpc2l0VHlwZShUeXBlIHQsIFMgcykgeyByZXR1cm4gdDsgfQogICAgfQoKICAgIC8qKgogICAgICogQW4gYWJzdHJhY3QgY2xhc3MgZm9yIG1hcHBpbmdzIGZyb20gdHlwZXMgdG8gdHlwZXMgKHNlZSB7QGxpbmsgVHlwZSNtYXAoVHlwZU1hcHBpbmcpfS4KICAgICAqIFRoaXMgY2xhc3MgaW1wbGVtZW50cyB0aGUgZnVuY3Rpb25hbCBpbnRlcmZhY2Uge0Bjb2RlIEZ1bmN0aW9ufSwgdGhhdCBhbGxvd3MgaXQgdG8gYmUgdXNlZAogICAgICogZmx1ZW50bHkgaW4gc3RyZWFtLWxpa2UgcHJvY2Vzc2luZy4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBjbGFzcyBUeXBlTWFwcGluZzxTPiBleHRlbmRzIE1hcFZpc2l0b3I8Uz4gaW1wbGVtZW50cyBGdW5jdGlvbjxUeXBlLCBUeXBlPiB7CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFR5cGUgYXBwbHkoVHlwZSB0eXBlKSB7IHJldHVybiB2aXNpdCh0eXBlKTsgfQoKICAgICAgICBMaXN0PFR5cGU+IHZpc2l0KExpc3Q8VHlwZT4gdHMsIFMgcykgewogICAgICAgICAgICByZXR1cm4gdHMubWFwKHQgLT4gdmlzaXQodCwgcykpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFR5cGUgdmlzaXRDYXB0dXJlZFR5cGUoQ2FwdHVyZWRUeXBlIHQsIFMgcykgewogICAgICAgICAgICByZXR1cm4gdmlzaXRUeXBlVmFyKHQsIHMpOwogICAgICAgIH0KICAgIH0KICAgIC8vIDwvZWRpdG9yLWZvbGQ+CgoKICAgIC8vIDxlZGl0b3ItZm9sZCBkZWZhdWx0c3RhdGU9ImNvbGxhcHNlZCIgZGVzYz0iQW5ub3RhdGlvbiBzdXBwb3J0Ij4KCiAgICBwdWJsaWMgUmV0ZW50aW9uUG9saWN5IGdldFJldGVudGlvbihBdHRyaWJ1dGUuQ29tcG91bmQgYSkgewogICAgICAgIHJldHVybiBnZXRSZXRlbnRpb24oYS50eXBlLnRzeW0pOwogICAgfQoKICAgIHB1YmxpYyBSZXRlbnRpb25Qb2xpY3kgZ2V0UmV0ZW50aW9uKFR5cGVTeW1ib2wgc3ltKSB7CiAgICAgICAgUmV0ZW50aW9uUG9saWN5IHZpcyA9IFJldGVudGlvblBvbGljeS5DTEFTUzsgLy8gdGhlIGRlZmF1bHQKICAgICAgICBBdHRyaWJ1dGUuQ29tcG91bmQgYyA9IHN5bS5hdHRyaWJ1dGUoc3ltcy5yZXRlbnRpb25UeXBlLnRzeW0pOwogICAgICAgIGlmIChjICE9IG51bGwpIHsKICAgICAgICAgICAgQXR0cmlidXRlIHZhbHVlID0gYy5tZW1iZXIobmFtZXMudmFsdWUpOwogICAgICAgICAgICBpZiAodmFsdWUgIT0gbnVsbCAmJiB2YWx1ZSBpbnN0YW5jZW9mIEF0dHJpYnV0ZS5FbnVtKSB7CiAgICAgICAgICAgICAgICBOYW1lIGxldmVsTmFtZSA9ICgoQXR0cmlidXRlLkVudW0pdmFsdWUpLnZhbHVlLm5hbWU7CiAgICAgICAgICAgICAgICBpZiAobGV2ZWxOYW1lID09IG5hbWVzLlNPVVJDRSkgdmlzID0gUmV0ZW50aW9uUG9saWN5LlNPVVJDRTsKICAgICAgICAgICAgICAgIGVsc2UgaWYgKGxldmVsTmFtZSA9PSBuYW1lcy5DTEFTUykgdmlzID0gUmV0ZW50aW9uUG9saWN5LkNMQVNTOwogICAgICAgICAgICAgICAgZWxzZSBpZiAobGV2ZWxOYW1lID09IG5hbWVzLlJVTlRJTUUpIHZpcyA9IFJldGVudGlvblBvbGljeS5SVU5USU1FOwogICAgICAgICAgICAgICAgZWxzZSA7Ly8gLyogZmFpbCBzb2Z0ICovIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihsZXZlbE5hbWUpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiB2aXM7CiAgICB9CiAgICAvLyA8L2VkaXRvci1mb2xkPgoKICAgIC8vIDxlZGl0b3ItZm9sZCBkZWZhdWx0c3RhdGU9ImNvbGxhcHNlZCIgZGVzYz0iU2lnbmF0dXJlIEdlbmVyYXRpb24iPgoKICAgIHB1YmxpYyBzdGF0aWMgYWJzdHJhY3QgY2xhc3MgU2lnbmF0dXJlR2VuZXJhdG9yIHsKCiAgICAgICAgcHJpdmF0ZSBmaW5hbCBUeXBlcyB0eXBlczsKCiAgICAgICAgcHJvdGVjdGVkIGFic3RyYWN0IHZvaWQgYXBwZW5kKGNoYXIgY2gpOwogICAgICAgIHByb3RlY3RlZCBhYnN0cmFjdCB2b2lkIGFwcGVuZChieXRlW10gYmEpOwogICAgICAgIHByb3RlY3RlZCBhYnN0cmFjdCB2b2lkIGFwcGVuZChOYW1lIG5hbWUpOwogICAgICAgIHByb3RlY3RlZCB2b2lkIGNsYXNzUmVmZXJlbmNlKENsYXNzU3ltYm9sIGMpIHsgLyogYnkgZGVmYXVsdDogbm8tb3AgKi8gfQoKICAgICAgICBwcm90ZWN0ZWQgU2lnbmF0dXJlR2VuZXJhdG9yKFR5cGVzIHR5cGVzKSB7CiAgICAgICAgICAgIHRoaXMudHlwZXMgPSB0eXBlczsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIEFzc2VtYmxlIHNpZ25hdHVyZSBvZiBnaXZlbiB0eXBlIGluIHN0cmluZyBidWZmZXIuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIHZvaWQgYXNzZW1ibGVTaWcoVHlwZSB0eXBlKSB7CiAgICAgICAgICAgIHN3aXRjaCAodHlwZS5nZXRUYWcoKSkgewogICAgICAgICAgICAgICAgY2FzZSBCWVRFOgogICAgICAgICAgICAgICAgICAgIGFwcGVuZCgnQicpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBTSE9SVDoKICAgICAgICAgICAgICAgICAgICBhcHBlbmQoJ1MnKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgQ0hBUjoKICAgICAgICAgICAgICAgICAgICBhcHBlbmQoJ0MnKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgSU5UOgogICAgICAgICAgICAgICAgICAgIGFwcGVuZCgnSScpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBMT05HOgogICAgICAgICAgICAgICAgICAgIGFwcGVuZCgnSicpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBGTE9BVDoKICAgICAgICAgICAgICAgICAgICBhcHBlbmQoJ0YnKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgRE9VQkxFOgogICAgICAgICAgICAgICAgICAgIGFwcGVuZCgnRCcpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBCT09MRUFOOgogICAgICAgICAgICAgICAgICAgIGFwcGVuZCgnWicpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBWT0lEOgogICAgICAgICAgICAgICAgICAgIGFwcGVuZCgnVicpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBDTEFTUzoKICAgICAgICAgICAgICAgICAgICBhcHBlbmQoJ0wnKTsKICAgICAgICAgICAgICAgICAgICBhc3NlbWJsZUNsYXNzU2lnKHR5cGUpOwogICAgICAgICAgICAgICAgICAgIGFwcGVuZCgnOycpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBBUlJBWToKICAgICAgICAgICAgICAgICAgICBBcnJheVR5cGUgYXQgPSAoQXJyYXlUeXBlKSB0eXBlOwogICAgICAgICAgICAgICAgICAgIGFwcGVuZCgnWycpOwogICAgICAgICAgICAgICAgICAgIGFzc2VtYmxlU2lnKGF0LmVsZW10eXBlKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgTUVUSE9EOgogICAgICAgICAgICAgICAgICAgIE1ldGhvZFR5cGUgbXQgPSAoTWV0aG9kVHlwZSkgdHlwZTsKICAgICAgICAgICAgICAgICAgICBhcHBlbmQoJygnKTsKICAgICAgICAgICAgICAgICAgICBhc3NlbWJsZVNpZyhtdC5hcmd0eXBlcyk7CiAgICAgICAgICAgICAgICAgICAgYXBwZW5kKCcpJyk7CiAgICAgICAgICAgICAgICAgICAgYXNzZW1ibGVTaWcobXQucmVzdHlwZSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKGhhc1R5cGVWYXIobXQudGhyb3duKSkgewogICAgICAgICAgICAgICAgICAgICAgICBmb3IgKExpc3Q8VHlwZT4gbCA9IG10LnRocm93bjsgbC5ub25FbXB0eSgpOyBsID0gbC50YWlsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcHBlbmQoJ14nKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFzc2VtYmxlU2lnKGwuaGVhZCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIFdJTERDQVJEOiB7CiAgICAgICAgICAgICAgICAgICAgVHlwZS5XaWxkY2FyZFR5cGUgdGEgPSAoVHlwZS5XaWxkY2FyZFR5cGUpIHR5cGU7CiAgICAgICAgICAgICAgICAgICAgc3dpdGNoICh0YS5raW5kKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgU1VQRVI6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcHBlbmQoJy0nKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFzc2VtYmxlU2lnKHRhLnR5cGUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgRVhURU5EUzoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFwcGVuZCgnKycpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYXNzZW1ibGVTaWcodGEudHlwZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBVTkJPVU5EOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgYXBwZW5kKCcqJyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcih0YS5raW5kKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBjYXNlIFRZUEVWQVI6CiAgICAgICAgICAgICAgICAgICAgYXBwZW5kKCdUJyk7CiAgICAgICAgICAgICAgICAgICAgYXBwZW5kKHR5cGUudHN5bS5uYW1lKTsKICAgICAgICAgICAgICAgICAgICBhcHBlbmQoJzsnKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgRk9SQUxMOgogICAgICAgICAgICAgICAgICAgIFR5cGUuRm9yQWxsIGZ0ID0gKFR5cGUuRm9yQWxsKSB0eXBlOwogICAgICAgICAgICAgICAgICAgIGFzc2VtYmxlUGFyYW1zU2lnKGZ0LnR2YXJzKTsKICAgICAgICAgICAgICAgICAgICBhc3NlbWJsZVNpZyhmdC5xdHlwZSk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigidHlwZVNpZyAiICsgdHlwZS5nZXRUYWcoKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHB1YmxpYyBib29sZWFuIGhhc1R5cGVWYXIoTGlzdDxUeXBlPiBsKSB7CiAgICAgICAgICAgIHdoaWxlIChsLm5vbkVtcHR5KCkpIHsKICAgICAgICAgICAgICAgIGlmIChsLmhlYWQuaGFzVGFnKFR5cGVUYWcuVFlQRVZBUikpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGwgPSBsLnRhaWw7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHZvaWQgYXNzZW1ibGVDbGFzc1NpZyhUeXBlIHR5cGUpIHsKICAgICAgICAgICAgQ2xhc3NUeXBlIGN0ID0gKENsYXNzVHlwZSkgdHlwZTsKICAgICAgICAgICAgQ2xhc3NTeW1ib2wgYyA9IChDbGFzc1N5bWJvbCkgY3QudHN5bTsKICAgICAgICAgICAgY2xhc3NSZWZlcmVuY2UoYyk7CiAgICAgICAgICAgIFR5cGUgb3V0ZXIgPSBjdC5nZXRFbmNsb3NpbmdUeXBlKCk7CiAgICAgICAgICAgIGlmIChvdXRlci5hbGxwYXJhbXMoKS5ub25FbXB0eSgpKSB7CiAgICAgICAgICAgICAgICBib29sZWFuIHJhd091dGVyID0KICAgICAgICAgICAgICAgICAgICAgICAgYy5vd25lci5raW5kID09IE1USCB8fCAvLyBlaXRoZXIgYSBsb2NhbCBjbGFzcwogICAgICAgICAgICAgICAgICAgICAgICBjLm5hbWUgPT0gdHlwZXMubmFtZXMuZW1wdHk7IC8vIG9yIGFub255bW91cwogICAgICAgICAgICAgICAgYXNzZW1ibGVDbGFzc1NpZyhyYXdPdXRlcgogICAgICAgICAgICAgICAgICAgICAgICA/IHR5cGVzLmVyYXN1cmUob3V0ZXIpCiAgICAgICAgICAgICAgICAgICAgICAgIDogb3V0ZXIpOwogICAgICAgICAgICAgICAgYXBwZW5kKHJhd091dGVyID8gJyQnIDogJy4nKTsKICAgICAgICAgICAgICAgIEFzc2VydC5jaGVjayhjLmZsYXRuYW1lLnN0YXJ0c1dpdGgoYy5vd25lci5lbmNsQ2xhc3MoKS5mbGF0bmFtZSkpOwogICAgICAgICAgICAgICAgYXBwZW5kKHJhd091dGVyCiAgICAgICAgICAgICAgICAgICAgICAgID8gYy5mbGF0bmFtZS5zdWJOYW1lKGMub3duZXIuZW5jbENsYXNzKCkuZmxhdG5hbWUuZ2V0Qnl0ZUxlbmd0aCgpICsgMSwgYy5mbGF0bmFtZS5nZXRCeXRlTGVuZ3RoKCkpCiAgICAgICAgICAgICAgICAgICAgICAgIDogYy5uYW1lKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGFwcGVuZChleHRlcm5hbGl6ZShjLmZsYXRuYW1lKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGN0LmdldFR5cGVBcmd1bWVudHMoKS5ub25FbXB0eSgpKSB7CiAgICAgICAgICAgICAgICBhcHBlbmQoJzwnKTsKICAgICAgICAgICAgICAgIGFzc2VtYmxlU2lnKGN0LmdldFR5cGVBcmd1bWVudHMoKSk7CiAgICAgICAgICAgICAgICBhcHBlbmQoJz4nKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHVibGljIHZvaWQgYXNzZW1ibGVQYXJhbXNTaWcoTGlzdDxUeXBlPiB0eXBhcmFtcykgewogICAgICAgICAgICBhcHBlbmQoJzwnKTsKICAgICAgICAgICAgZm9yIChMaXN0PFR5cGU+IHRzID0gdHlwYXJhbXM7IHRzLm5vbkVtcHR5KCk7IHRzID0gdHMudGFpbCkgewogICAgICAgICAgICAgICAgVHlwZS5UeXBlVmFyIHR2YXIgPSAoVHlwZS5UeXBlVmFyKSB0cy5oZWFkOwogICAgICAgICAgICAgICAgYXBwZW5kKHR2YXIudHN5bS5uYW1lKTsKICAgICAgICAgICAgICAgIExpc3Q8VHlwZT4gYm91bmRzID0gdHlwZXMuZ2V0Qm91bmRzKHR2YXIpOwogICAgICAgICAgICAgICAgaWYgKChib3VuZHMuaGVhZC50c3ltLmZsYWdzKCkgJiBJTlRFUkZBQ0UpICE9IDApIHsKICAgICAgICAgICAgICAgICAgICBhcHBlbmQoJzonKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGZvciAoTGlzdDxUeXBlPiBsID0gYm91bmRzOyBsLm5vbkVtcHR5KCk7IGwgPSBsLnRhaWwpIHsKICAgICAgICAgICAgICAgICAgICBhcHBlbmQoJzonKTsKICAgICAgICAgICAgICAgICAgICBhc3NlbWJsZVNpZyhsLmhlYWQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGFwcGVuZCgnPicpOwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSB2b2lkIGFzc2VtYmxlU2lnKExpc3Q8VHlwZT4gdHlwZXMpIHsKICAgICAgICAgICAgZm9yIChMaXN0PFR5cGU+IHRzID0gdHlwZXM7IHRzLm5vbkVtcHR5KCk7IHRzID0gdHMudGFpbCkgewogICAgICAgICAgICAgICAgYXNzZW1ibGVTaWcodHMuaGVhZCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICAvLyA8L2VkaXRvci1mb2xkPgoKICAgIHB1YmxpYyB2b2lkIG5ld1JvdW5kKCkgewogICAgICAgIGRlc2NDYWNoZS5fbWFwLmNsZWFyKCk7CiAgICAgICAgaXNEZXJpdmVkUmF3Q2FjaGUuY2xlYXIoKTsKICAgICAgICBpbXBsQ2FjaGUuX21hcC5jbGVhcigpOwogICAgICAgIG1lbWJlcnNDYWNoZS5fbWFwLmNsZWFyKCk7CiAgICAgICAgY2xvc3VyZUNhY2hlLmNsZWFyKCk7CiAgICB9Cn0KUEsDBAoAAAgAAK48qUo0R4i4CTcBAAk3AQAiAAAAY29tL3N1bi90b29scy9qYXZhYy9jb2RlL1R5cGUuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMTk5OSwgMjAxNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGU7CgppbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uQW5ub3RhdGlvbjsKaW1wb3J0IGphdmEudXRpbC5BcnJheURlcXVlOwppbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOwppbXBvcnQgamF2YS51dGlsLkVudW1NYXA7CmltcG9ydCBqYXZhLnV0aWwuTWFwOwoKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwudHlwZS4qOwoKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5TeW1ib2wuKjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5UeXBlTWV0YWRhdGEuRW50cnk7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuVHlwZXMuVHlwZU1hcHBpbmc7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvbXAuSW5mZXIuSW5jb3Jwb3JhdGlvbkFjdGlvbjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC4qOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkRlZmluZWRCeS5BcGk7CgppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5Cb3VuZEtpbmQuKjsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuRmxhZ3MuKjsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuS2luZHMuS2luZC4qOwppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5UeXBlVGFnLio7CgovKiogVGhpcyBjbGFzcyByZXByZXNlbnRzIEphdmEgdHlwZXMuIFRoZSBjbGFzcyBpdHNlbGYgZGVmaW5lcyB0aGUgYmVoYXZpb3Igb2YKICogIHRoZSBmb2xsb3dpbmcgdHlwZXM6CiAqICA8cHJlPgogKiAgYmFzZSB0eXBlcyAodGFnczogQllURSwgQ0hBUiwgU0hPUlQsIElOVCwgTE9ORywgRkxPQVQsIERPVUJMRSwgQk9PTEVBTiksCiAqICB0eXBlIGB2b2lkJyAodGFnOiBWT0lEKSwKICogIHRoZSBib3R0b20gdHlwZSAodGFnOiBCT1QpLAogKiAgdGhlIG1pc3NpbmcgdHlwZSAodGFnOiBOT05FKS4KICogIDwvcHJlPgogKiAgPHA+VGhlIGJlaGF2aW9yIG9mIHRoZSBmb2xsb3dpbmcgdHlwZXMgaXMgZGVmaW5lZCBpbiBzdWJjbGFzc2VzLCB3aGljaCBhcmUKICogIGFsbCBzdGF0aWMgaW5uZXIgY2xhc3NlcyBvZiB0aGlzIGNsYXNzOgogKiAgPHByZT4KICogIGNsYXNzIHR5cGVzICh0YWc6IENMQVNTLCBjbGFzczogQ2xhc3NUeXBlKSwKICogIGFycmF5IHR5cGVzICh0YWc6IEFSUkFZLCBjbGFzczogQXJyYXlUeXBlKSwKICogIG1ldGhvZCB0eXBlcyAodGFnOiBNRVRIT0QsIGNsYXNzOiBNZXRob2RUeXBlKSwKICogIHBhY2thZ2UgdHlwZXMgKHRhZzogUEFDS0FHRSwgY2xhc3M6IFBhY2thZ2VUeXBlKSwKICogIHR5cGUgdmFyaWFibGVzICh0YWc6IFRZUEVWQVIsIGNsYXNzOiBUeXBlVmFyKSwKICogIHR5cGUgYXJndW1lbnRzICh0YWc6IFdJTERDQVJELCBjbGFzczogV2lsZGNhcmRUeXBlKSwKICogIGdlbmVyaWMgbWV0aG9kIHR5cGVzICh0YWc6IEZPUkFMTCwgY2xhc3M6IEZvckFsbCksCiAqICB0aGUgZXJyb3IgdHlwZSAodGFnOiBFUlJPUiwgY2xhc3M6IEVycm9yVHlwZSkuCiAqICA8L3ByZT4KICoKICogIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqICBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqICBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogKiAgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPgogKgogKiAgQHNlZSBUeXBlVGFnCiAqLwpwdWJsaWMgYWJzdHJhY3QgY2xhc3MgVHlwZSBleHRlbmRzIEFubm9Db25zdHJ1Y3QgaW1wbGVtZW50cyBUeXBlTWlycm9yIHsKCiAgICAvKioKICAgICAqIFR5cGUgbWV0YWRhdGEsICBTaG91bGQgYmUge0Bjb2RlIG51bGx9IGZvciB0aGUgZGVmYXVsdCB2YWx1ZS4KICAgICAqCiAgICAgKiBOb3RlOiBpdCBpcyBhbiBpbnZhcmlhbnQgdGhhdCBmb3IgYW55IHtAY29kZSBUeXBlTWV0YWRhdGF9CiAgICAgKiBjbGFzcywgYSBnaXZlbiB7QGNvZGUgVHlwZX0gbWF5IGhhdmUgYXQgbW9zdCBvbmUgbWV0YWRhdGEgYXJyYXkKICAgICAqIGVudHJ5IG9mIHRoYXQgY2xhc3MuCiAgICAgKi8KICAgIHByb3RlY3RlZCBmaW5hbCBUeXBlTWV0YWRhdGEgbWV0YWRhdGE7CgogICAgcHVibGljIFR5cGVNZXRhZGF0YSBnZXRNZXRhZGF0YSgpIHsKICAgICAgICByZXR1cm4gbWV0YWRhdGE7CiAgICB9CgogICAgcHVibGljIEVudHJ5IGdldE1ldGFkYXRhT2ZLaW5kKGZpbmFsIEVudHJ5LktpbmQga2luZCkgewogICAgICAgIHJldHVybiBtZXRhZGF0YSAhPSBudWxsID8gbWV0YWRhdGEuZ2V0KGtpbmQpIDogbnVsbDsKICAgIH0KCiAgICAvKiogQ29uc3RhbnQgdHlwZTogbm8gdHlwZSBhdCBhbGwuICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEpDTm9UeXBlIG5vVHlwZSA9IG5ldyBKQ05vVHlwZSgpIHsKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKICAgICAgICAgICAgcmV0dXJuICJub25lIjsKICAgICAgICB9CiAgICB9OwoKICAgIC8qKiBDb25zdGFudCB0eXBlOiBzcGVjaWFsIHR5cGUgdG8gYmUgdXNlZCBkdXJpbmcgcmVjb3Zlcnkgb2YgZGVmZXJyZWQgZXhwcmVzc2lvbnMuICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEpDTm9UeXBlIHJlY292ZXJ5VHlwZSA9IG5ldyBKQ05vVHlwZSgpewogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgICAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewogICAgICAgICAgICByZXR1cm4gInJlY292ZXJ5IjsKICAgICAgICB9CiAgICB9OwoKICAgIC8qKiBDb25zdGFudCB0eXBlOiBzcGVjaWFsIHR5cGUgdG8gYmUgdXNlZCBmb3IgbWFya2luZyBzdHVjayB0cmVlcy4gKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgSkNOb1R5cGUgc3R1Y2tUeXBlID0gbmV3IEpDTm9UeXBlKCkgewogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgICAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewogICAgICAgICAgICByZXR1cm4gInN0dWNrIjsKICAgICAgICB9CiAgICB9OwoKICAgIC8qKiBJZiB0aGlzIHN3aXRjaCBpcyB0dXJuZWQgb24sIHRoZSBuYW1lcyBvZiB0eXBlIHZhcmlhYmxlcwogICAgICogIGFuZCBhbm9ueW1vdXMgY2xhc3NlcyBhcmUgcHJpbnRlZCB3aXRoIGhhc2hjb2RlcyBhcHBlbmRlZC4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBib29sZWFuIG1vcmVJbmZvID0gZmFsc2U7CgogICAgLyoqIFRoZSBkZWZpbmluZyBjbGFzcyAvIGludGVyZmFjZSAvIHBhY2thZ2UgLyB0eXBlIHZhcmlhYmxlLgogICAgICovCiAgICBwdWJsaWMgVHlwZVN5bWJvbCB0c3ltOwoKICAgIC8qKgogICAgICogQ2hlY2tzIGlmIHRoZSBjdXJyZW50IHR5cGUgdGFnIGlzIGVxdWFsIHRvIHRoZSBnaXZlbiB0YWcuCiAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGFnIGlzIGVxdWFsIHRvIHRoZSBjdXJyZW50IHR5cGUgdGFnLgogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNUYWcoVHlwZVRhZyB0YWcpIHsKICAgICAgICByZXR1cm4gdGFnID09IGdldFRhZygpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgY3VycmVudCB0eXBlIHRhZy4KICAgICAqIEByZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSBjdXJyZW50IHR5cGUgdGFnLgogICAgICovCiAgICBwdWJsaWMgYWJzdHJhY3QgVHlwZVRhZyBnZXRUYWcoKTsKCiAgICBwdWJsaWMgYm9vbGVhbiBpc051bWVyaWMoKSB7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIHB1YmxpYyBib29sZWFuIGlzSW50ZWdyYWwoKSB7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIHB1YmxpYyBib29sZWFuIGlzUHJpbWl0aXZlKCkgewogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICBwdWJsaWMgYm9vbGVhbiBpc1ByaW1pdGl2ZU9yVm9pZCgpIHsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgcHVibGljIGJvb2xlYW4gaXNSZWZlcmVuY2UoKSB7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIHB1YmxpYyBib29sZWFuIGlzTnVsbE9yUmVmZXJlbmNlKCkgewogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICBwdWJsaWMgYm9vbGVhbiBpc1BhcnRpYWwoKSB7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICogVGhlIGNvbnN0YW50IHZhbHVlIG9mIHRoaXMgdHlwZSwgbnVsbCBpZiB0aGlzIHR5cGUgZG9lcyBub3QKICAgICAqIGhhdmUgYSBjb25zdGFudCB2YWx1ZSBhdHRyaWJ1dGUuIE9ubHkgcHJpbWl0aXZlIHR5cGVzIGFuZAogICAgICogc3RyaW5ncyAoQ2xhc3NUeXBlKSBjYW4gaGF2ZSBhIGNvbnN0YW50IHZhbHVlIGF0dHJpYnV0ZS4KICAgICAqIEByZXR1cm4gdGhlIGNvbnN0YW50IHZhbHVlIGF0dHJpYnV0ZSBvZiB0aGlzIHR5cGUKICAgICAqLwogICAgcHVibGljIE9iamVjdCBjb25zdFZhbHVlKCkgewogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIC8qKiBJcyB0aGlzIGEgY29uc3RhbnQgdHlwZSB3aG9zZSB2YWx1ZSBpcyBmYWxzZT8KICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gaXNGYWxzZSgpIHsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgLyoqIElzIHRoaXMgYSBjb25zdGFudCB0eXBlIHdob3NlIHZhbHVlIGlzIHRydWU/CiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGlzVHJ1ZSgpIHsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXQgdGhlIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgdHlwZSB1c2VkIGZvciBtb2RlbGxpbmcgcHVycG9zZXMuCiAgICAgKiBCeSBkZWZhdWx0LCB0aGlzIGlzIGl0c2VsZi4gRm9yIEVycm9yVHlwZSwgYSBkaWZmZXJlbnQgdmFsdWUKICAgICAqIG1heSBiZSBwcm92aWRlZC4KICAgICAqLwogICAgcHVibGljIFR5cGUgZ2V0TW9kZWxUeXBlKCkgewogICAgICAgIHJldHVybiB0aGlzOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgTGlzdDxUeXBlPiBnZXRNb2RlbFR5cGVzKExpc3Q8VHlwZT4gdHMpIHsKICAgICAgICBMaXN0QnVmZmVyPFR5cGU+IGxiID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgIGZvciAoVHlwZSB0OiB0cykKICAgICAgICAgICAgbGIuYXBwZW5kKHQuZ2V0TW9kZWxUeXBlKCkpOwogICAgICAgIHJldHVybiBsYi50b0xpc3QoKTsKICAgIH0KCiAgICAvKipGb3IgRXJyb3JUeXBlLCByZXR1cm5zIHRoZSBvcmlnaW5hbCB0eXBlLCBvdGhlcndpc2UgcmV0dXJucyB0aGUgdHlwZSBpdHNlbGYuCiAgICAgKi8KICAgIHB1YmxpYyBUeXBlIGdldE9yaWdpbmFsVHlwZSgpIHsKICAgICAgICByZXR1cm4gdGhpczsKICAgIH0KCiAgICBwdWJsaWMgPFIsUz4gUiBhY2NlcHQoVHlwZS5WaXNpdG9yPFIsUz4gdiwgUyBzKSB7IHJldHVybiB2LnZpc2l0VHlwZSh0aGlzLCBzKTsgfQoKICAgIC8qKiBEZWZpbmUgYSB0eXBlIGdpdmVuIGl0cyB0YWcsIHR5cGUgc3ltYm9sLCBhbmQgdHlwZSBhbm5vdGF0aW9ucwogICAgICovCgogICAgcHVibGljIFR5cGUoVHlwZVN5bWJvbCB0c3ltLCBUeXBlTWV0YWRhdGEgbWV0YWRhdGEpIHsKICAgICAgICBBc3NlcnQuY2hlY2tOb25OdWxsKG1ldGFkYXRhKTsKICAgICAgICB0aGlzLnRzeW0gPSB0c3ltOwogICAgICAgIHRoaXMubWV0YWRhdGEgPSBtZXRhZGF0YTsKICAgIH0KCiAgICAvKioKICAgICAqIEEgc3ViY2xhc3Mgb2Yge0BsaW5rIFR5cGVzLlR5cGVNYXBwaW5nfSB3aGljaCBhcHBsaWVzIGEgbWFwcGluZyByZWN1cnNpdmVseSB0byB0aGUgc3VidGVybXMKICAgICAqIG9mIGEgZ2l2ZW4gdHlwZSBleHByZXNzaW9uLiBUaGlzIG1hcHBpbmcgcmV0dXJucyB0aGUgb3JpZ2luYWwgdHlwZSBpcyBubyBjaGFuZ2VzIG9jY3VycmVkCiAgICAgKiB3aGVuIHJlY3Vyc2l2ZWx5IG1hcHBpbmcgdGhlIG9yaWdpbmFsIHR5cGUncyBzdWJ0ZXJtcy4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBhYnN0cmFjdCBjbGFzcyBTdHJ1Y3R1cmFsVHlwZU1hcHBpbmc8Uz4gZXh0ZW5kcyBUeXBlcy5UeXBlTWFwcGluZzxTPiB7CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBUeXBlIHZpc2l0Q2xhc3NUeXBlKENsYXNzVHlwZSB0LCBTIHMpIHsKICAgICAgICAgICAgVHlwZSBvdXRlciA9IHQuZ2V0RW5jbG9zaW5nVHlwZSgpOwogICAgICAgICAgICBUeXBlIG91dGVyMSA9IHZpc2l0KG91dGVyLCBzKTsKICAgICAgICAgICAgTGlzdDxUeXBlPiB0eXBhcmFtcyA9IHQuZ2V0VHlwZUFyZ3VtZW50cygpOwogICAgICAgICAgICBMaXN0PFR5cGU+IHR5cGFyYW1zMSA9IHZpc2l0KHR5cGFyYW1zLCBzKTsKICAgICAgICAgICAgaWYgKG91dGVyMSA9PSBvdXRlciAmJiB0eXBhcmFtczEgPT0gdHlwYXJhbXMpIHJldHVybiB0OwogICAgICAgICAgICBlbHNlIHJldHVybiBuZXcgQ2xhc3NUeXBlKG91dGVyMSwgdHlwYXJhbXMxLCB0LnRzeW0sIHQubWV0YWRhdGEpIHsKICAgICAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICAgICAgcHJvdGVjdGVkIGJvb2xlYW4gbmVlZHNTdHJpcHBpbmcoKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgVHlwZSB2aXNpdFdpbGRjYXJkVHlwZShXaWxkY2FyZFR5cGUgd3QsIFMgcykgewogICAgICAgICAgICBUeXBlIHQgPSB3dC50eXBlOwogICAgICAgICAgICBpZiAodCAhPSBudWxsKQogICAgICAgICAgICAgICAgdCA9IHZpc2l0KHQsIHMpOwogICAgICAgICAgICBpZiAodCA9PSB3dC50eXBlKQogICAgICAgICAgICAgICAgcmV0dXJuIHd0OwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFdpbGRjYXJkVHlwZSh0LCB3dC5raW5kLCB3dC50c3ltLCB3dC5ib3VuZCwgd3QubWV0YWRhdGEpIHsKICAgICAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgICAgICAgICBwcm90ZWN0ZWQgYm9vbGVhbiBuZWVkc1N0cmlwcGluZygpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBUeXBlIHZpc2l0QXJyYXlUeXBlKEFycmF5VHlwZSB0LCBTIHMpIHsKICAgICAgICAgICAgVHlwZSBlbGVtdHlwZSA9IHQuZWxlbXR5cGU7CiAgICAgICAgICAgIFR5cGUgZWxlbXR5cGUxID0gdmlzaXQoZWxlbXR5cGUsIHMpOwogICAgICAgICAgICBpZiAoZWxlbXR5cGUxID09IGVsZW10eXBlKSByZXR1cm4gdDsKICAgICAgICAgICAgZWxzZSByZXR1cm4gbmV3IEFycmF5VHlwZShlbGVtdHlwZTEsIHQudHN5bSwgdC5tZXRhZGF0YSkgewogICAgICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgICAgICBwcm90ZWN0ZWQgYm9vbGVhbiBuZWVkc1N0cmlwcGluZygpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBUeXBlIHZpc2l0TWV0aG9kVHlwZShNZXRob2RUeXBlIHQsIFMgcykgewogICAgICAgICAgICBMaXN0PFR5cGU+IGFyZ3R5cGVzID0gdC5hcmd0eXBlczsKICAgICAgICAgICAgVHlwZSByZXN0eXBlID0gdC5yZXN0eXBlOwogICAgICAgICAgICBMaXN0PFR5cGU+IHRocm93biA9IHQudGhyb3duOwogICAgICAgICAgICBMaXN0PFR5cGU+IGFyZ3R5cGVzMSA9IHZpc2l0KGFyZ3R5cGVzLCBzKTsKICAgICAgICAgICAgVHlwZSByZXN0eXBlMSA9IHZpc2l0KHJlc3R5cGUsIHMpOwogICAgICAgICAgICBMaXN0PFR5cGU+IHRocm93bjEgPSB2aXNpdCh0aHJvd24sIHMpOwogICAgICAgICAgICBpZiAoYXJndHlwZXMxID09IGFyZ3R5cGVzICYmCiAgICAgICAgICAgICAgICByZXN0eXBlMSA9PSByZXN0eXBlICYmCiAgICAgICAgICAgICAgICB0aHJvd24xID09IHRocm93bikgcmV0dXJuIHQ7CiAgICAgICAgICAgIGVsc2UgcmV0dXJuIG5ldyBNZXRob2RUeXBlKGFyZ3R5cGVzMSwgcmVzdHlwZTEsIHRocm93bjEsIHQudHN5bSkgewogICAgICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgICAgICBwcm90ZWN0ZWQgYm9vbGVhbiBuZWVkc1N0cmlwcGluZygpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBUeXBlIHZpc2l0Rm9yQWxsKEZvckFsbCB0LCBTIHMpIHsKICAgICAgICAgICAgcmV0dXJuIHZpc2l0KHQucXR5cGUsIHMpOwogICAgICAgIH0KICAgIH0KCiAgICAvKiogbWFwIGEgdHlwZSBmdW5jdGlvbiBvdmVyIGFsbCBpbW1lZGlhdGUgZGVzY2VuZGFudHMgb2YgdGhpcyB0eXBlCiAgICAgKi8KICAgIHB1YmxpYyA8Wj4gVHlwZSBtYXAoVHlwZU1hcHBpbmc8Wj4gbWFwcGluZywgWiBhcmcpIHsKICAgICAgICByZXR1cm4gbWFwcGluZy52aXNpdCh0aGlzLCBhcmcpOwogICAgfQoKICAgIC8qKiBtYXAgYSB0eXBlIGZ1bmN0aW9uIG92ZXIgYWxsIGltbWVkaWF0ZSBkZXNjZW5kYW50cyBvZiB0aGlzIHR5cGUgKG5vIGFyZyB2ZXJzaW9uKQogICAgICovCiAgICBwdWJsaWMgPFo+IFR5cGUgbWFwKFR5cGVNYXBwaW5nPFo+IG1hcHBpbmcpIHsKICAgICAgICByZXR1cm4gbWFwcGluZy52aXNpdCh0aGlzLCBudWxsKTsKICAgIH0KCiAgICAvKiogRGVmaW5lIGEgY29uc3RhbnQgdHlwZSwgb2YgdGhlIHNhbWUga2luZCBhcyB0aGlzIHR5cGUKICAgICAqICBhbmQgd2l0aCBnaXZlbiBjb25zdGFudCB2YWx1ZQogICAgICovCiAgICBwdWJsaWMgVHlwZSBjb25zdFR5cGUoT2JqZWN0IGNvbnN0VmFsdWUpIHsKICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoKTsKICAgIH0KCiAgICAvKioKICAgICAqIElmIHRoaXMgaXMgYSBjb25zdGFudCB0eXBlLCByZXR1cm4gaXRzIHVuZGVybHlpbmcgdHlwZS4KICAgICAqIE90aGVyd2lzZSwgcmV0dXJuIHRoZSB0eXBlIGl0c2VsZi4KICAgICAqLwogICAgcHVibGljIFR5cGUgYmFzZVR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBvcmlnaW5hbCB2ZXJzaW9uIG9mIHRoaXMgdHlwZSwgYmVmb3JlIG1ldGFkYXRhIHdlcmUgYWRkZWQuIFRoaXMgcm91dGluZSBpcyBtZWFudAogICAgICogZm9yIGludGVybmFsIHVzZSBvbmx5IChpLmUuIHtAbGluayBUeXBlI2VxdWFsc0lnbm9yZU1ldGFkYXRhKFR5cGUpfSwge0BsaW5rIFR5cGUjc3RyaXBNZXRhZGF0YX0pOwogICAgICogaXQgc2hvdWxkIG5vdCBiZSB1c2VkIG91dHNpZGUgdGhpcyBjbGFzcy4KICAgICAqLwogICAgcHJvdGVjdGVkIFR5cGUgdHlwZU5vTWV0YWRhdGEoKSB7CiAgICAgICAgcmV0dXJuIG1ldGFkYXRhID09IFR5cGVNZXRhZGF0YS5FTVBUWSA/IHRoaXMgOiBiYXNlVHlwZSgpOwogICAgfQoKICAgIC8qKgogICAgICogQ3JlYXRlIGEgbmV3IGNvcHkgb2YgdGhpcyB0eXBlIGJ1dCB3aXRoIHRoZSBzcGVjaWZpZWQgVHlwZU1ldGFkYXRhLgogICAgICovCiAgICBwdWJsaWMgYWJzdHJhY3QgVHlwZSBjbG9uZVdpdGhNZXRhZGF0YShUeXBlTWV0YWRhdGEgbWV0YWRhdGEpOwoKICAgIC8qKgogICAgICogRG9lcyB0aGlzIHR5cGUgcmVxdWlyZSBhbm5vdGF0aW9uIHN0cmlwcGluZyBmb3IgQVBJIGNsaWVudHM/CiAgICAgKi8KICAgIHByb3RlY3RlZCBib29sZWFuIG5lZWRzU3RyaXBwaW5nKCkgewogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICAvKioKICAgICAqIFN0cmlwIGFsbCBtZXRhZGF0YSBhc3NvY2lhdGVkIHdpdGggdGhpcyB0eXBlIC0gdGhpcyBjb3VsZCByZXR1cm4gYSBuZXcgY2xvbmUgb2YgdGhlIHR5cGUuCiAgICAgKiBUaGlzIHJvdXRpbmUgaXMgb25seSB1c2VkIHRvIHByZXNlbnQgdGhlIGNvcnJlY3QgYW5ub3RhdGVkIHR5cGVzIGJhY2sgdG8gdGhlIHVzZXJzIHdoZW4gdHlwZXMKICAgICAqIGFyZSBhY2Nlc3NlZCB0aHJvdWdoIGNvbXBpbGVyIEFQSXM7IGl0IHNob3VsZCBub3QgYmUgdXNlZCBhbnl3aGVyZSBpbiB0aGUgY29tcGlsZXIgaW50ZXJuYWxzCiAgICAgKiBhcyBkb2luZyBzbyBtaWdodCByZXN1bHQgaW4gcGVyZm9ybWFuY2UgcGVuYWx0aWVzLgogICAgICovCiAgICBwdWJsaWMgVHlwZSBzdHJpcE1ldGFkYXRhSWZOZWVkZWQoKSB7CiAgICAgICAgcmV0dXJuIG5lZWRzU3RyaXBwaW5nKCkgPwogICAgICAgICAgICAgICAgYWNjZXB0KHN0cmlwTWV0YWRhdGEsIG51bGwpIDoKICAgICAgICAgICAgICAgIHRoaXM7CiAgICB9CgogICAgcHVibGljIFR5cGUgc3RyaXBNZXRhZGF0YSgpIHsKICAgICAgICByZXR1cm4gYWNjZXB0KHN0cmlwTWV0YWRhdGEsIG51bGwpOwogICAgfQogICAgLy93aGVyZQogICAgICAgIHByaXZhdGUgZmluYWwgc3RhdGljIFR5cGVNYXBwaW5nPFZvaWQ+IHN0cmlwTWV0YWRhdGEgPSBuZXcgU3RydWN0dXJhbFR5cGVNYXBwaW5nPFZvaWQ+KCkgewogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHVibGljIFR5cGUgdmlzaXRDbGFzc1R5cGUoQ2xhc3NUeXBlIHQsIFZvaWQgYVZvaWQpIHsKICAgICAgICAgICAgICAgIHJldHVybiBzdXBlci52aXNpdENsYXNzVHlwZSgoQ2xhc3NUeXBlKXQudHlwZU5vTWV0YWRhdGEoKSwgYVZvaWQpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHVibGljIFR5cGUgdmlzaXRBcnJheVR5cGUoQXJyYXlUeXBlIHQsIFZvaWQgYVZvaWQpIHsKICAgICAgICAgICAgICAgIHJldHVybiBzdXBlci52aXNpdEFycmF5VHlwZSgoQXJyYXlUeXBlKXQudHlwZU5vTWV0YWRhdGEoKSwgYVZvaWQpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHVibGljIFR5cGUgdmlzaXRUeXBlVmFyKFR5cGVWYXIgdCwgVm9pZCBhVm9pZCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHN1cGVyLnZpc2l0VHlwZVZhcigoVHlwZVZhcil0LnR5cGVOb01ldGFkYXRhKCksIGFWb2lkKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHB1YmxpYyBUeXBlIHZpc2l0V2lsZGNhcmRUeXBlKFdpbGRjYXJkVHlwZSB3dCwgVm9pZCBhVm9pZCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHN1cGVyLnZpc2l0V2lsZGNhcmRUeXBlKChXaWxkY2FyZFR5cGUpd3QudHlwZU5vTWV0YWRhdGEoKSwgYVZvaWQpOwogICAgICAgICAgICB9CiAgICAgICAgfTsKCiAgICBwdWJsaWMgVHlwZSBhbm5vdGF0ZWRUeXBlKGZpbmFsIExpc3Q8QXR0cmlidXRlLlR5cGVDb21wb3VuZD4gYW5ub3MpIHsKICAgICAgICBmaW5hbCBFbnRyeSBhbm5vTWV0YWRhdGEgPSBuZXcgVHlwZU1ldGFkYXRhLkFubm90YXRpb25zKGFubm9zKTsKICAgICAgICByZXR1cm4gY2xvbmVXaXRoTWV0YWRhdGEobWV0YWRhdGEuY29tYmluZShhbm5vTWV0YWRhdGEpKTsKICAgIH0KCiAgICBwdWJsaWMgYm9vbGVhbiBpc0Fubm90YXRlZCgpIHsKICAgICAgICBmaW5hbCBUeXBlTWV0YWRhdGEuQW5ub3RhdGlvbnMgbWV0YWRhdGEgPQogICAgICAgICAgICAoVHlwZU1ldGFkYXRhLkFubm90YXRpb25zKWdldE1ldGFkYXRhT2ZLaW5kKEVudHJ5LktpbmQuQU5OT1RBVElPTlMpOwoKICAgICAgICByZXR1cm4gbnVsbCAhPSBtZXRhZGF0YSAmJiAhbWV0YWRhdGEuZ2V0QW5ub3RhdGlvbnMoKS5pc0VtcHR5KCk7CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgcHVibGljIExpc3Q8QXR0cmlidXRlLlR5cGVDb21wb3VuZD4gZ2V0QW5ub3RhdGlvbk1pcnJvcnMoKSB7CiAgICAgICAgZmluYWwgVHlwZU1ldGFkYXRhLkFubm90YXRpb25zIG1ldGFkYXRhID0KICAgICAgICAgICAgKFR5cGVNZXRhZGF0YS5Bbm5vdGF0aW9ucylnZXRNZXRhZGF0YU9mS2luZChFbnRyeS5LaW5kLkFOTk9UQVRJT05TKTsKCiAgICAgICAgcmV0dXJuIG1ldGFkYXRhID09IG51bGwgPyBMaXN0Lm5pbCgpIDogbWV0YWRhdGEuZ2V0QW5ub3RhdGlvbnMoKTsKICAgIH0KCgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgcHVibGljIDxBIGV4dGVuZHMgQW5ub3RhdGlvbj4gQSBnZXRBbm5vdGF0aW9uKENsYXNzPEE+IGFubm90YXRpb25UeXBlKSB7CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgIHB1YmxpYyA8QSBleHRlbmRzIEFubm90YXRpb24+IEFbXSBnZXRBbm5vdGF0aW9uc0J5VHlwZShDbGFzczxBPiBhbm5vdGF0aW9uVHlwZSkgewogICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQogICAgICAgIEFbXSB0bXAgPSAoQVtdKSBqYXZhLmxhbmcucmVmbGVjdC5BcnJheS5uZXdJbnN0YW5jZShhbm5vdGF0aW9uVHlwZSwgMCk7CiAgICAgICAgcmV0dXJuIHRtcDsKICAgIH0KCiAgICAvKiogUmV0dXJuIHRoZSBiYXNlIHR5cGVzIG9mIGEgbGlzdCBvZiB0eXBlcy4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBMaXN0PFR5cGU+IGJhc2VUeXBlcyhMaXN0PFR5cGU+IHRzKSB7CiAgICAgICAgaWYgKHRzLm5vbkVtcHR5KCkpIHsKICAgICAgICAgICAgVHlwZSB0ID0gdHMuaGVhZC5iYXNlVHlwZSgpOwogICAgICAgICAgICBMaXN0PFR5cGU+IGJhc2VUeXBlcyA9IGJhc2VUeXBlcyh0cy50YWlsKTsKICAgICAgICAgICAgaWYgKHQgIT0gdHMuaGVhZCB8fCBiYXNlVHlwZXMgIT0gdHMudGFpbCkKICAgICAgICAgICAgICAgIHJldHVybiBiYXNlVHlwZXMucHJlcGVuZCh0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRzOwogICAgfQoKICAgIHByb3RlY3RlZCB2b2lkIGFwcGVuZEFubm90YXRpb25zU3RyaW5nKFN0cmluZ0J1aWxkZXIgc2IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBwcmVmaXgpIHsKICAgICAgICBpZiAoaXNBbm5vdGF0ZWQoKSkgewogICAgICAgICAgICBpZiAocHJlZml4KSB7CiAgICAgICAgICAgICAgICBzYi5hcHBlbmQoIiAiKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBzYi5hcHBlbmQoZ2V0QW5ub3RhdGlvbk1pcnJvcnMoKSk7CiAgICAgICAgICAgIHNiLmFwcGVuZCgiICIpOwogICAgICAgIH0KICAgIH0KCiAgICBwcm90ZWN0ZWQgdm9pZCBhcHBlbmRBbm5vdGF0aW9uc1N0cmluZyhTdHJpbmdCdWlsZGVyIHNiKSB7CiAgICAgICAgYXBwZW5kQW5ub3RhdGlvbnNTdHJpbmcoc2IsIGZhbHNlKTsKICAgIH0KCiAgICAvKiogVGhlIEphdmEgc291cmNlIHdoaWNoIHRoaXMgdHlwZSByZXByZXNlbnRzLgogICAgICovCiAgICBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CiAgICAgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CiAgICAgICAgYXBwZW5kQW5ub3RhdGlvbnNTdHJpbmcoc2IpOwogICAgICAgIGlmICh0c3ltID09IG51bGwgfHwgdHN5bS5uYW1lID09IG51bGwpIHsKICAgICAgICAgICAgc2IuYXBwZW5kKCI8bm9uZT4iKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzYi5hcHBlbmQodHN5bS5uYW1lKTsKICAgICAgICB9CiAgICAgICAgaWYgKG1vcmVJbmZvICYmIGhhc1RhZyhUWVBFVkFSKSkgewogICAgICAgICAgICBzYi5hcHBlbmQoaGFzaENvZGUoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzYi50b1N0cmluZygpOwogICAgfQoKICAgIC8qKgogICAgICogVGhlIEphdmEgc291cmNlIHdoaWNoIHRoaXMgdHlwZSBsaXN0IHJlcHJlc2VudHMuICBBIExpc3QgaXMKICAgICAqIHJlcHJlc2VudGVkIGFzIGEgY29tbWEtc3BlYXJhdGVkIGxpc3Rpbmcgb2YgdGhlIGVsZW1lbnRzIGluCiAgICAgKiB0aGF0IGxpc3QuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHRvU3RyaW5nKExpc3Q8VHlwZT4gdHMpIHsKICAgICAgICBpZiAodHMuaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJldHVybiAiIjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBTdHJpbmdCdWlsZGVyIGJ1ZiA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CiAgICAgICAgICAgIGJ1Zi5hcHBlbmQodHMuaGVhZC50b1N0cmluZygpKTsKICAgICAgICAgICAgZm9yIChMaXN0PFR5cGU+IGwgPSB0cy50YWlsOyBsLm5vbkVtcHR5KCk7IGwgPSBsLnRhaWwpCiAgICAgICAgICAgICAgICBidWYuYXBwZW5kKCIsIikuYXBwZW5kKGwuaGVhZC50b1N0cmluZygpKTsKICAgICAgICAgICAgcmV0dXJuIGJ1Zi50b1N0cmluZygpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFRoZSBjb25zdGFudCB2YWx1ZSBvZiB0aGlzIHR5cGUsIGNvbnZlcnRlZCB0byBTdHJpbmcKICAgICAqLwogICAgcHVibGljIFN0cmluZyBzdHJpbmdWYWx1ZSgpIHsKICAgICAgICBPYmplY3QgY3YgPSBBc3NlcnQuY2hlY2tOb25OdWxsKGNvbnN0VmFsdWUoKSk7CiAgICAgICAgcmV0dXJuIGN2LnRvU3RyaW5nKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBPdmVycmlkZSB0aGlzIG1ldGhvZCB3aXRoIGNhcmUuIEZvciBtb3N0IFR5cGUgaW5zdGFuY2VzIHRoaXMgc2hvdWxkIGJlaGF2ZSBhcyA9PS4KICAgICAqLwogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCB0KSB7CiAgICAgICAgcmV0dXJuIHRoaXMgPT0gdDsKICAgIH0KCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHNJZ25vcmVNZXRhZGF0YShUeXBlIHQpIHsKICAgICAgICByZXR1cm4gdHlwZU5vTWV0YWRhdGEoKS5lcXVhbHModC50eXBlTm9NZXRhZGF0YSgpKTsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICAgIHJldHVybiBzdXBlci5oYXNoQ29kZSgpOwogICAgfQoKICAgIHB1YmxpYyBTdHJpbmcgYXJndHlwZXMoYm9vbGVhbiB2YXJhcmdzKSB7CiAgICAgICAgTGlzdDxUeXBlPiBhcmdzID0gZ2V0UGFyYW1ldGVyVHlwZXMoKTsKICAgICAgICBpZiAoIXZhcmFyZ3MpIHJldHVybiBhcmdzLnRvU3RyaW5nKCk7CiAgICAgICAgU3RyaW5nQnVpbGRlciBidWYgPSBuZXcgU3RyaW5nQnVpbGRlcigpOwogICAgICAgIHdoaWxlIChhcmdzLnRhaWwubm9uRW1wdHkoKSkgewogICAgICAgICAgICBidWYuYXBwZW5kKGFyZ3MuaGVhZCk7CiAgICAgICAgICAgIGFyZ3MgPSBhcmdzLnRhaWw7CiAgICAgICAgICAgIGJ1Zi5hcHBlbmQoJywnKTsKICAgICAgICB9CiAgICAgICAgaWYgKGFyZ3MuaGVhZC5oYXNUYWcoQVJSQVkpKSB7CiAgICAgICAgICAgIGJ1Zi5hcHBlbmQoKChBcnJheVR5cGUpYXJncy5oZWFkKS5lbGVtdHlwZSk7CiAgICAgICAgICAgIGlmIChhcmdzLmhlYWQuZ2V0QW5ub3RhdGlvbk1pcnJvcnMoKS5ub25FbXB0eSgpKSB7CiAgICAgICAgICAgICAgICBidWYuYXBwZW5kKGFyZ3MuaGVhZC5nZXRBbm5vdGF0aW9uTWlycm9ycygpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBidWYuYXBwZW5kKCIuLi4iKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBidWYuYXBwZW5kKGFyZ3MuaGVhZCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWYudG9TdHJpbmcoKTsKICAgIH0KCiAgICAvKiogQWNjZXNzIG1ldGhvZHMuCiAgICAgKi8KICAgIHB1YmxpYyBMaXN0PFR5cGU+ICAgICAgICBnZXRUeXBlQXJndW1lbnRzKCkgIHsgcmV0dXJuIExpc3QubmlsKCk7IH0KICAgIHB1YmxpYyBUeXBlICAgICAgICAgICAgICBnZXRFbmNsb3NpbmdUeXBlKCkgIHsgcmV0dXJuIG51bGw7IH0KICAgIHB1YmxpYyBMaXN0PFR5cGU+ICAgICAgICBnZXRQYXJhbWV0ZXJUeXBlcygpIHsgcmV0dXJuIExpc3QubmlsKCk7IH0KICAgIHB1YmxpYyBUeXBlICAgICAgICAgICAgICBnZXRSZXR1cm5UeXBlKCkgICAgIHsgcmV0dXJuIG51bGw7IH0KICAgIHB1YmxpYyBUeXBlICAgICAgICAgICAgICBnZXRSZWNlaXZlclR5cGUoKSAgIHsgcmV0dXJuIG51bGw7IH0KICAgIHB1YmxpYyBMaXN0PFR5cGU+ICAgICAgICBnZXRUaHJvd25UeXBlcygpICAgIHsgcmV0dXJuIExpc3QubmlsKCk7IH0KICAgIHB1YmxpYyBUeXBlICAgICAgICAgICAgICBnZXRVcHBlckJvdW5kKCkgICAgIHsgcmV0dXJuIG51bGw7IH0KICAgIHB1YmxpYyBUeXBlICAgICAgICAgICAgICBnZXRMb3dlckJvdW5kKCkgICAgIHsgcmV0dXJuIG51bGw7IH0KCiAgICAvKiogTmF2aWdhdGlvbiBtZXRob2RzLCB0aGVzZSB3aWxsIHdvcmsgZm9yIGNsYXNzZXMsIHR5cGUgdmFyaWFibGVzLAogICAgICogIGZvcmFsbHMsIGJ1dCB3aWxsIHJldHVybiBudWxsIGZvciBhcnJheXMgYW5kIG1ldGhvZHMuCiAgICAgKi8KCiAgIC8qKiBSZXR1cm4gYWxsIHBhcmFtZXRlcnMgb2YgdGhpcyB0eXBlIGFuZCBhbGwgaXRzIG91dGVyIHR5cGVzIGluIG9yZGVyCiAgICAqICBvdXRlciAoZmlyc3QpIHRvIGlubmVyIChsYXN0KS4KICAgICovCiAgICBwdWJsaWMgTGlzdDxUeXBlPiBhbGxwYXJhbXMoKSB7IHJldHVybiBMaXN0Lm5pbCgpOyB9CgogICAgLyoqIERvZXMgdGhpcyB0eXBlIGNvbnRhaW4gImVycm9yIiBlbGVtZW50cz8KICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gaXNFcnJvbmVvdXMoKSB7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc0Vycm9uZW91cyhMaXN0PFR5cGU+IHRzKSB7CiAgICAgICAgZm9yIChMaXN0PFR5cGU+IGwgPSB0czsgbC5ub25FbXB0eSgpOyBsID0gbC50YWlsKQogICAgICAgICAgICBpZiAobC5oZWFkLmlzRXJyb25lb3VzKCkpIHJldHVybiB0cnVlOwogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICAvKiogSXMgdGhpcyB0eXBlIHBhcmFtZXRlcml6ZWQ/CiAgICAgKiAgQSBjbGFzcyB0eXBlIGlzIHBhcmFtZXRlcml6ZWQgaWYgaXQgaGFzIHNvbWUgcGFyYW1ldGVycy4KICAgICAqICBBbiBhcnJheSB0eXBlIGlzIHBhcmFtZXRlcml6ZWQgaWYgaXRzIGVsZW1lbnQgdHlwZSBpcyBwYXJhbWV0ZXJpemVkLgogICAgICogIEFsbCBvdGhlciB0eXBlcyBhcmUgbm90IHBhcmFtZXRlcml6ZWQuCiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGlzUGFyYW1ldGVyaXplZCgpIHsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgLyoqIElzIHRoaXMgdHlwZSBhIHJhdyB0eXBlPwogICAgICogIEEgY2xhc3MgdHlwZSBpcyBhIHJhdyB0eXBlIGlmIGl0IG1pc3NlcyBzb21lIG9mIGl0cyBwYXJhbWV0ZXJzLgogICAgICogIEFuIGFycmF5IHR5cGUgaXMgYSByYXcgdHlwZSBpZiBpdHMgZWxlbWVudCB0eXBlIGlzIHJhdy4KICAgICAqICBBbGwgb3RoZXIgdHlwZXMgYXJlIG5vdCByYXcuCiAgICAgKiAgVHlwZSB2YWxpZGF0aW9uIHdpbGwgZW5zdXJlIHRoYXQgdGhlIG9ubHkgcmF3IHR5cGVzCiAgICAgKiAgaW4gYSBwcm9ncmFtIGFyZSB0eXBlcyB0aGF0IG1pc3MgYWxsIHRoZWlyIHR5cGUgdmFyaWFibGVzLgogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBpc1JhdygpIHsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBBIGNvbXBvdW5kIHR5cGUgaXMgYSBzcGVjaWFsIGNsYXNzIHR5cGUgd2hvc2Ugc3VwZXJ0eXBlcyBhcmUgdXNlZCB0byBzdG9yZSBhIGxpc3QKICAgICAqIG9mIGNvbXBvbmVudCB0eXBlcy4gVGhlcmUgYXJlIHR3byBraW5kcyBvZiBjb21wb3VuZCB0eXBlczogKGkpIGludGVyc2VjdGlvbiB0eXBlcwogICAgICoge0BzZWUgSW50ZXJzZWN0aW9uQ2xhc3NUeXBlfSBhbmQgKGlpKSB1bmlvbiB0eXBlcyB7QHNlZSBVbmlvbkNsYXNzVHlwZX0uCiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGlzQ29tcG91bmQoKSB7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIHB1YmxpYyBib29sZWFuIGlzSW50ZXJzZWN0aW9uKCkgewogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICBwdWJsaWMgYm9vbGVhbiBpc1VuaW9uKCkgewogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICBwdWJsaWMgYm9vbGVhbiBpc0ludGVyZmFjZSgpIHsKICAgICAgICByZXR1cm4gKHRzeW0uZmxhZ3MoKSAmIElOVEVSRkFDRSkgIT0gMDsKICAgIH0KCiAgICBwdWJsaWMgYm9vbGVhbiBpc0ZpbmFsKCkgewogICAgICAgIHJldHVybiAodHN5bS5mbGFncygpICYgRklOQUwpICE9IDA7CiAgICB9CgogICAgLyoqCiAgICAgKiBEb2VzIHRoaXMgdHlwZSBjb250YWluIG9jY3VycmVuY2VzIG9mIHR5cGUgdD8KICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnMoVHlwZSB0KSB7CiAgICAgICAgcmV0dXJuIHQuZXF1YWxzSWdub3JlTWV0YWRhdGEodGhpcyk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBib29sZWFuIGNvbnRhaW5zKExpc3Q8VHlwZT4gdHMsIFR5cGUgdCkgewogICAgICAgIGZvciAoTGlzdDxUeXBlPiBsID0gdHM7CiAgICAgICAgICAgICBsLnRhaWwgIT0gbnVsbCAvKmlubGluZWQ6IGwubm9uRW1wdHkoKSovOwogICAgICAgICAgICAgbCA9IGwudGFpbCkKICAgICAgICAgICAgaWYgKGwuaGVhZC5jb250YWlucyh0KSkgcmV0dXJuIHRydWU7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIC8qKiBEb2VzIHRoaXMgdHlwZSBjb250YWluIGFuIG9jY3VycmVuY2Ugb2Ygc29tZSB0eXBlIGluICd0cyc/CiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zQW55KExpc3Q8VHlwZT4gdHMpIHsKICAgICAgICBmb3IgKFR5cGUgdCA6IHRzKQogICAgICAgICAgICBpZiAodGhpcy5jb250YWlucyh0KSkgcmV0dXJuIHRydWU7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBjb250YWluc0FueShMaXN0PFR5cGU+IHRzMSwgTGlzdDxUeXBlPiB0czIpIHsKICAgICAgICBmb3IgKFR5cGUgdCA6IHRzMSkKICAgICAgICAgICAgaWYgKHQuY29udGFpbnNBbnkodHMyKSkgcmV0dXJuIHRydWU7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgTGlzdDxUeXBlPiBmaWx0ZXIoTGlzdDxUeXBlPiB0cywgRmlsdGVyPFR5cGU+IHRmKSB7CiAgICAgICAgTGlzdEJ1ZmZlcjxUeXBlPiBidWYgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgZm9yIChUeXBlIHQgOiB0cykgewogICAgICAgICAgICBpZiAodGYuYWNjZXB0cyh0KSkgewogICAgICAgICAgICAgICAgYnVmLmFwcGVuZCh0KTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVmLnRvTGlzdCgpOwogICAgfQoKICAgIHB1YmxpYyBib29sZWFuIGlzU3VwZXJCb3VuZCgpIHsgcmV0dXJuIGZhbHNlOyB9CiAgICBwdWJsaWMgYm9vbGVhbiBpc0V4dGVuZHNCb3VuZCgpIHsgcmV0dXJuIGZhbHNlOyB9CiAgICBwdWJsaWMgYm9vbGVhbiBpc1VuYm91bmQoKSB7IHJldHVybiBmYWxzZTsgfQogICAgcHVibGljIFR5cGUgd2l0aFR5cGVWYXIoVHlwZSB0KSB7IHJldHVybiB0aGlzOyB9CgogICAgLyoqIFRoZSB1bmRlcmx5aW5nIG1ldGhvZCB0eXBlIG9mIHRoaXMgdHlwZS4KICAgICAqLwogICAgcHVibGljIE1ldGhvZFR5cGUgYXNNZXRob2RUeXBlKCkgeyB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoKTsgfQoKICAgIC8qKiBDb21wbGV0ZSBsb2FkaW5nIGFsbCBjbGFzc2VzIGluIHRoaXMgdHlwZS4KICAgICAqLwogICAgcHVibGljIHZvaWQgY29tcGxldGUoKSB7fQoKICAgIHB1YmxpYyBUeXBlU3ltYm9sIGFzRWxlbWVudCgpIHsKICAgICAgICByZXR1cm4gdHN5bTsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICBwdWJsaWMgVHlwZUtpbmQgZ2V0S2luZCgpIHsKICAgICAgICByZXR1cm4gVHlwZUtpbmQuT1RIRVI7CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgcHVibGljIDxSLCBQPiBSIGFjY2VwdChUeXBlVmlzaXRvcjxSLCBQPiB2LCBQIHApIHsKICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIEpDUHJpbWl0aXZlVHlwZSBleHRlbmRzIFR5cGUKICAgICAgICAgICAgaW1wbGVtZW50cyBqYXZheC5sYW5nLm1vZGVsLnR5cGUuUHJpbWl0aXZlVHlwZSB7CgogICAgICAgIFR5cGVUYWcgdGFnOwoKICAgICAgICBwdWJsaWMgSkNQcmltaXRpdmVUeXBlKFR5cGVUYWcgdGFnLCBUeXBlU3ltYm9sIHRzeW0pIHsKICAgICAgICAgICAgdGhpcyh0YWcsIHRzeW0sIFR5cGVNZXRhZGF0YS5FTVBUWSk7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIEpDUHJpbWl0aXZlVHlwZShUeXBlVGFnIHRhZywgVHlwZVN5bWJvbCB0c3ltLCBUeXBlTWV0YWRhdGEgbWV0YWRhdGEpIHsKICAgICAgICAgICAgc3VwZXIodHN5bSwgbWV0YWRhdGEpOwogICAgICAgICAgICB0aGlzLnRhZyA9IHRhZzsKICAgICAgICAgICAgQXNzZXJ0LmNoZWNrKHRhZy5pc1ByaW1pdGl2ZSk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgSkNQcmltaXRpdmVUeXBlIGNsb25lV2l0aE1ldGFkYXRhKFR5cGVNZXRhZGF0YSBtZCkgewogICAgICAgICAgICByZXR1cm4gbmV3IEpDUHJpbWl0aXZlVHlwZSh0YWcsIHRzeW0sIG1kKSB7CiAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgICAgIHB1YmxpYyBUeXBlIGJhc2VUeXBlKCkgeyByZXR1cm4gSkNQcmltaXRpdmVUeXBlLnRoaXMuYmFzZVR5cGUoKTsgfQogICAgICAgICAgICB9OwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gaXNOdW1lcmljKCkgewogICAgICAgICAgICByZXR1cm4gdGFnICE9IEJPT0xFQU47CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc0ludGVncmFsKCkgewogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgICAgY2FzZSBDSEFSOgogICAgICAgICAgICAgICAgY2FzZSBCWVRFOgogICAgICAgICAgICAgICAgY2FzZSBTSE9SVDoKICAgICAgICAgICAgICAgIGNhc2UgSU5UOgogICAgICAgICAgICAgICAgY2FzZSBMT05HOgogICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBib29sZWFuIGlzUHJpbWl0aXZlKCkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBUeXBlVGFnIGdldFRhZygpIHsKICAgICAgICAgICAgcmV0dXJuIHRhZzsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBib29sZWFuIGlzUHJpbWl0aXZlT3JWb2lkKCkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIC8qKiBEZWZpbmUgYSBjb25zdGFudCB0eXBlLCBvZiB0aGUgc2FtZSBraW5kIGFzIHRoaXMgdHlwZQogICAgICAgICAqICBhbmQgd2l0aCBnaXZlbiBjb25zdGFudCB2YWx1ZQogICAgICAgICAqLwogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBUeXBlIGNvbnN0VHlwZShPYmplY3QgY29uc3RWYWx1ZSkgewogICAgICAgICAgICBmaW5hbCBPYmplY3QgdmFsdWUgPSBjb25zdFZhbHVlOwogICAgICAgICAgICByZXR1cm4gbmV3IEpDUHJpbWl0aXZlVHlwZSh0YWcsIHRzeW0sIG1ldGFkYXRhKSB7CiAgICAgICAgICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgICAgICAgICAgcHVibGljIE9iamVjdCBjb25zdFZhbHVlKCkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICAgICAgICAgIHB1YmxpYyBUeXBlIGJhc2VUeXBlKCkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHN5bS50eXBlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH07CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBUaGUgY29uc3RhbnQgdmFsdWUgb2YgdGhpcyB0eXBlLCBjb252ZXJ0ZWQgdG8gU3RyaW5nCiAgICAgICAgICovCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFN0cmluZyBzdHJpbmdWYWx1ZSgpIHsKICAgICAgICAgICAgT2JqZWN0IGN2ID0gQXNzZXJ0LmNoZWNrTm9uTnVsbChjb25zdFZhbHVlKCkpOwogICAgICAgICAgICBpZiAodGFnID09IEJPT0xFQU4pIHsKICAgICAgICAgICAgICAgIHJldHVybiAoKEludGVnZXIpIGN2KS5pbnRWYWx1ZSgpID09IDAgPyAiZmFsc2UiIDogInRydWUiOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKHRhZyA9PSBDSEFSKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gU3RyaW5nLnZhbHVlT2YoKGNoYXIpICgoSW50ZWdlcikgY3YpLmludFZhbHVlKCkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgcmV0dXJuIGN2LnRvU3RyaW5nKCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8qKiBJcyB0aGlzIGEgY29uc3RhbnQgdHlwZSB3aG9zZSB2YWx1ZSBpcyBmYWxzZT8KICAgICAgICAgKi8KICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc0ZhbHNlKCkgewogICAgICAgICAgICByZXR1cm4KICAgICAgICAgICAgICAgIHRhZyA9PSBCT09MRUFOICYmCiAgICAgICAgICAgICAgICBjb25zdFZhbHVlKCkgIT0gbnVsbCAmJgogICAgICAgICAgICAgICAgKChJbnRlZ2VyKWNvbnN0VmFsdWUoKSkuaW50VmFsdWUoKSA9PSAwOwogICAgICAgIH0KCiAgICAgICAgLyoqIElzIHRoaXMgYSBjb25zdGFudCB0eXBlIHdob3NlIHZhbHVlIGlzIHRydWU/CiAgICAgICAgICovCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gaXNUcnVlKCkgewogICAgICAgICAgICByZXR1cm4KICAgICAgICAgICAgICAgIHRhZyA9PSBCT09MRUFOICYmCiAgICAgICAgICAgICAgICBjb25zdFZhbHVlKCkgIT0gbnVsbCAmJgogICAgICAgICAgICAgICAgKChJbnRlZ2VyKWNvbnN0VmFsdWUoKSkuaW50VmFsdWUoKSAhPSAwOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyA8UiwgUD4gUiBhY2NlcHQoVHlwZVZpc2l0b3I8UiwgUD4gdiwgUCBwKSB7CiAgICAgICAgICAgIHJldHVybiB2LnZpc2l0UHJpbWl0aXZlKHRoaXMsIHApOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyBUeXBlS2luZCBnZXRLaW5kKCkgewogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgICAgY2FzZSBCWVRFOiAgICAgIHJldHVybiBUeXBlS2luZC5CWVRFOwogICAgICAgICAgICAgICAgY2FzZSBDSEFSOiAgICAgIHJldHVybiBUeXBlS2luZC5DSEFSOwogICAgICAgICAgICAgICAgY2FzZSBTSE9SVDogICAgIHJldHVybiBUeXBlS2luZC5TSE9SVDsKICAgICAgICAgICAgICAgIGNhc2UgSU5UOiAgICAgICByZXR1cm4gVHlwZUtpbmQuSU5UOwogICAgICAgICAgICAgICAgY2FzZSBMT05HOiAgICAgIHJldHVybiBUeXBlS2luZC5MT05HOwogICAgICAgICAgICAgICAgY2FzZSBGTE9BVDogICAgIHJldHVybiBUeXBlS2luZC5GTE9BVDsKICAgICAgICAgICAgICAgIGNhc2UgRE9VQkxFOiAgICByZXR1cm4gVHlwZUtpbmQuRE9VQkxFOwogICAgICAgICAgICAgICAgY2FzZSBCT09MRUFOOiAgIHJldHVybiBUeXBlS2luZC5CT09MRUFOOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigpOwogICAgICAgIH0KCiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjbGFzcyBXaWxkY2FyZFR5cGUgZXh0ZW5kcyBUeXBlCiAgICAgICAgICAgIGltcGxlbWVudHMgamF2YXgubGFuZy5tb2RlbC50eXBlLldpbGRjYXJkVHlwZSB7CgogICAgICAgIHB1YmxpYyBUeXBlIHR5cGU7CiAgICAgICAgcHVibGljIEJvdW5kS2luZCBraW5kOwogICAgICAgIHB1YmxpYyBUeXBlVmFyIGJvdW5kOwoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgPFIsUz4gUiBhY2NlcHQoVHlwZS5WaXNpdG9yPFIsUz4gdiwgUyBzKSB7CiAgICAgICAgICAgIHJldHVybiB2LnZpc2l0V2lsZGNhcmRUeXBlKHRoaXMsIHMpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIFdpbGRjYXJkVHlwZShUeXBlIHR5cGUsIEJvdW5kS2luZCBraW5kLCBUeXBlU3ltYm9sIHRzeW0pIHsKICAgICAgICAgICAgdGhpcyh0eXBlLCBraW5kLCB0c3ltLCBudWxsLCBUeXBlTWV0YWRhdGEuRU1QVFkpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIFdpbGRjYXJkVHlwZShUeXBlIHR5cGUsIEJvdW5kS2luZCBraW5kLCBUeXBlU3ltYm9sIHRzeW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBUeXBlTWV0YWRhdGEgbWV0YWRhdGEpIHsKICAgICAgICAgICAgdGhpcyh0eXBlLCBraW5kLCB0c3ltLCBudWxsLCBtZXRhZGF0YSk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgV2lsZGNhcmRUeXBlKFR5cGUgdHlwZSwgQm91bmRLaW5kIGtpbmQsIFR5cGVTeW1ib2wgdHN5bSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFR5cGVWYXIgYm91bmQpIHsKICAgICAgICAgICAgdGhpcyh0eXBlLCBraW5kLCB0c3ltLCBib3VuZCwgVHlwZU1ldGFkYXRhLkVNUFRZKTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBXaWxkY2FyZFR5cGUoVHlwZSB0eXBlLCBCb3VuZEtpbmQga2luZCwgVHlwZVN5bWJvbCB0c3ltLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgVHlwZVZhciBib3VuZCwgVHlwZU1ldGFkYXRhIG1ldGFkYXRhKSB7CiAgICAgICAgICAgIHN1cGVyKHRzeW0sIG1ldGFkYXRhKTsKICAgICAgICAgICAgdGhpcy50eXBlID0gQXNzZXJ0LmNoZWNrTm9uTnVsbCh0eXBlKTsKICAgICAgICAgICAgdGhpcy5raW5kID0ga2luZDsKICAgICAgICAgICAgdGhpcy5ib3VuZCA9IGJvdW5kOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFdpbGRjYXJkVHlwZSBjbG9uZVdpdGhNZXRhZGF0YShUeXBlTWV0YWRhdGEgbWQpIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyBXaWxkY2FyZFR5cGUodHlwZSwga2luZCwgdHN5bSwgYm91bmQsIG1kKSB7CiAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgICAgIHB1YmxpYyBUeXBlIGJhc2VUeXBlKCkgeyByZXR1cm4gV2lsZGNhcmRUeXBlLnRoaXMuYmFzZVR5cGUoKTsgfQogICAgICAgICAgICB9OwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFR5cGVUYWcgZ2V0VGFnKCkgewogICAgICAgICAgICByZXR1cm4gV0lMRENBUkQ7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWlucyhUeXBlIHQpIHsKICAgICAgICAgICAgcmV0dXJuIGtpbmQgIT0gVU5CT1VORCAmJiB0eXBlLmNvbnRhaW5zKHQpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIGJvb2xlYW4gaXNTdXBlckJvdW5kKCkgewogICAgICAgICAgICByZXR1cm4ga2luZCA9PSBTVVBFUiB8fAogICAgICAgICAgICAgICAga2luZCA9PSBVTkJPVU5EOwogICAgICAgIH0KICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc0V4dGVuZHNCb3VuZCgpIHsKICAgICAgICAgICAgcmV0dXJuIGtpbmQgPT0gRVhURU5EUyB8fAogICAgICAgICAgICAgICAga2luZCA9PSBVTkJPVU5EOwogICAgICAgIH0KICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc1VuYm91bmQoKSB7CiAgICAgICAgICAgIHJldHVybiBraW5kID09IFVOQk9VTkQ7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc1JlZmVyZW5jZSgpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc051bGxPclJlZmVyZW5jZSgpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgVHlwZSB3aXRoVHlwZVZhcihUeXBlIHQpIHsKICAgICAgICAgICAgLy8tU3lzdGVtLmVyci5wcmludGxuKHRoaXMrIi53aXRoVHlwZVZhcigiK3QrIik7Iik7Ly9ERUJVRwogICAgICAgICAgICBpZiAoYm91bmQgPT0gdCkKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgICBib3VuZCA9IChUeXBlVmFyKXQ7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgYm9vbGVhbiBpc1ByaW50aW5nQm91bmQgPSBmYWxzZTsKICAgICAgICBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgICAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewogICAgICAgICAgICBTdHJpbmdCdWlsZGVyIHMgPSBuZXcgU3RyaW5nQnVpbGRlcigpOwogICAgICAgICAgICBhcHBlbmRBbm5vdGF0aW9uc1N0cmluZyhzKTsKICAgICAgICAgICAgcy5hcHBlbmQoa2luZC50b1N0cmluZygpKTsKICAgICAgICAgICAgaWYgKGtpbmQgIT0gVU5CT1VORCkKICAgICAgICAgICAgICAgIHMuYXBwZW5kKHR5cGUpOwogICAgICAgICAgICBpZiAobW9yZUluZm8gJiYgYm91bmQgIT0gbnVsbCAmJiAhaXNQcmludGluZ0JvdW5kKQogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICBpc1ByaW50aW5nQm91bmQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIHMuYXBwZW5kKCJ7OiIpLmFwcGVuZChib3VuZC5ib3VuZCkuYXBwZW5kKCI6fSIpOwogICAgICAgICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgICAgICAgICBpc1ByaW50aW5nQm91bmQgPSBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHMudG9TdHJpbmcoKTsKICAgICAgICB9CgogICAgICAgIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyBUeXBlIGdldEV4dGVuZHNCb3VuZCgpIHsKICAgICAgICAgICAgaWYgKGtpbmQgPT0gRVhURU5EUykKICAgICAgICAgICAgICAgIHJldHVybiB0eXBlOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyBUeXBlIGdldFN1cGVyQm91bmQoKSB7CiAgICAgICAgICAgIGlmIChraW5kID09IFNVUEVSKQogICAgICAgICAgICAgICAgcmV0dXJuIHR5cGU7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICAgICAgcHVibGljIFR5cGVLaW5kIGdldEtpbmQoKSB7CiAgICAgICAgICAgIHJldHVybiBUeXBlS2luZC5XSUxEQ0FSRDsKICAgICAgICB9CgogICAgICAgIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyA8UiwgUD4gUiBhY2NlcHQoVHlwZVZpc2l0b3I8UiwgUD4gdiwgUCBwKSB7CiAgICAgICAgICAgIHJldHVybiB2LnZpc2l0V2lsZGNhcmQodGhpcywgcCk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgQ2xhc3NUeXBlIGV4dGVuZHMgVHlwZSBpbXBsZW1lbnRzIERlY2xhcmVkVHlwZSB7CgogICAgICAgIC8qKiBUaGUgZW5jbG9zaW5nIHR5cGUgb2YgdGhpcyB0eXBlLiBJZiB0aGlzIGlzIHRoZSB0eXBlIG9mIGFuIGlubmVyCiAgICAgICAgICogIGNsYXNzLCBvdXRlcl9maWVsZCByZWZlcnMgdG8gdGhlIHR5cGUgb2YgaXRzIGVuY2xvc2luZwogICAgICAgICAqICBpbnN0YW5jZSBjbGFzcywgaW4gYWxsIG90aGVyIGNhc2VzIGl0IHJlZmVycyB0byBub1R5cGUuCiAgICAgICAgICovCiAgICAgICAgcHJpdmF0ZSBUeXBlIG91dGVyX2ZpZWxkOwoKICAgICAgICAvKiogVGhlIHR5cGUgcGFyYW1ldGVycyBvZiB0aGlzIHR5cGUgKHRvIGJlIHNldCBvbmNlIGNsYXNzIGlzIGxvYWRlZCkuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIExpc3Q8VHlwZT4gdHlwYXJhbXNfZmllbGQ7CgogICAgICAgIC8qKiBBIGNhY2hlIHZhcmlhYmxlIGZvciB0aGUgdHlwZSBwYXJhbWV0ZXJzIG9mIHRoaXMgdHlwZSwKICAgICAgICAgKiAgYXBwZW5kZWQgdG8gYWxsIHBhcmFtZXRlcnMgb2YgaXRzIGVuY2xvc2luZyBjbGFzcy4KICAgICAgICAgKiAgQHNlZSAjYWxscGFyYW1zCiAgICAgICAgICovCiAgICAgICAgcHVibGljIExpc3Q8VHlwZT4gYWxscGFyYW1zX2ZpZWxkOwoKICAgICAgICAvKiogVGhlIHN1cGVydHlwZSBvZiB0aGlzIGNsYXNzICh0byBiZSBzZXQgb25jZSBjbGFzcyBpcyBsb2FkZWQpLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBUeXBlIHN1cGVydHlwZV9maWVsZDsKCiAgICAgICAgLyoqIFRoZSBpbnRlcmZhY2VzIG9mIHRoaXMgY2xhc3MgKHRvIGJlIHNldCBvbmNlIGNsYXNzIGlzIGxvYWRlZCkuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIExpc3Q8VHlwZT4gaW50ZXJmYWNlc19maWVsZDsKCiAgICAgICAgLyoqIEFsbCB0aGUgaW50ZXJmYWNlcyBvZiB0aGlzIGNsYXNzLCBpbmNsdWRpbmcgbWlzc2luZyBvbmVzLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBMaXN0PFR5cGU+IGFsbF9pbnRlcmZhY2VzX2ZpZWxkOwoKICAgICAgICBwdWJsaWMgQ2xhc3NUeXBlKFR5cGUgb3V0ZXIsIExpc3Q8VHlwZT4gdHlwYXJhbXMsIFR5cGVTeW1ib2wgdHN5bSkgewogICAgICAgICAgICB0aGlzKG91dGVyLCB0eXBhcmFtcywgdHN5bSwgVHlwZU1ldGFkYXRhLkVNUFRZKTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBDbGFzc1R5cGUoVHlwZSBvdXRlciwgTGlzdDxUeXBlPiB0eXBhcmFtcywgVHlwZVN5bWJvbCB0c3ltLAogICAgICAgICAgICAgICAgICAgICAgICAgVHlwZU1ldGFkYXRhIG1ldGFkYXRhKSB7CiAgICAgICAgICAgIHN1cGVyKHRzeW0sIG1ldGFkYXRhKTsKICAgICAgICAgICAgdGhpcy5vdXRlcl9maWVsZCA9IG91dGVyOwogICAgICAgICAgICB0aGlzLnR5cGFyYW1zX2ZpZWxkID0gdHlwYXJhbXM7CiAgICAgICAgICAgIHRoaXMuYWxscGFyYW1zX2ZpZWxkID0gbnVsbDsKICAgICAgICAgICAgdGhpcy5zdXBlcnR5cGVfZmllbGQgPSBudWxsOwogICAgICAgICAgICB0aGlzLmludGVyZmFjZXNfZmllbGQgPSBudWxsOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIENsYXNzVHlwZSBjbG9uZVdpdGhNZXRhZGF0YShUeXBlTWV0YWRhdGEgbWQpIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyBDbGFzc1R5cGUob3V0ZXJfZmllbGQsIHR5cGFyYW1zX2ZpZWxkLCB0c3ltLCBtZCkgewogICAgICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgICAgICBwdWJsaWMgVHlwZSBiYXNlVHlwZSgpIHsgcmV0dXJuIENsYXNzVHlwZS50aGlzLmJhc2VUeXBlKCk7IH0KICAgICAgICAgICAgfTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBUeXBlVGFnIGdldFRhZygpIHsKICAgICAgICAgICAgcmV0dXJuIENMQVNTOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIDxSLFM+IFIgYWNjZXB0KFR5cGUuVmlzaXRvcjxSLFM+IHYsIFMgcykgewogICAgICAgICAgICByZXR1cm4gdi52aXNpdENsYXNzVHlwZSh0aGlzLCBzKTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBUeXBlIGNvbnN0VHlwZShPYmplY3QgY29uc3RWYWx1ZSkgewogICAgICAgICAgICBmaW5hbCBPYmplY3QgdmFsdWUgPSBjb25zdFZhbHVlOwogICAgICAgICAgICByZXR1cm4gbmV3IENsYXNzVHlwZShnZXRFbmNsb3NpbmdUeXBlKCksIHR5cGFyYW1zX2ZpZWxkLCB0c3ltLCBtZXRhZGF0YSkgewogICAgICAgICAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICAgICAgICAgIHB1YmxpYyBPYmplY3QgY29uc3RWYWx1ZSgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgICAgICAgICBwdWJsaWMgVHlwZSBiYXNlVHlwZSgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRzeW0udHlwZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9OwogICAgICAgIH0KCiAgICAgICAgLyoqIFRoZSBKYXZhIHNvdXJjZSB3aGljaCB0aGlzIHR5cGUgcmVwcmVzZW50cy4KICAgICAgICAgKi8KICAgICAgICBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgICAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewogICAgICAgICAgICBTdHJpbmdCdWlsZGVyIGJ1ZiA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CiAgICAgICAgICAgIGlmIChnZXRFbmNsb3NpbmdUeXBlKCkuaGFzVGFnKENMQVNTKSAmJiB0c3ltLm93bmVyLmtpbmQgPT0gVFlQKSB7CiAgICAgICAgICAgICAgICBidWYuYXBwZW5kKGdldEVuY2xvc2luZ1R5cGUoKS50b1N0cmluZygpKTsKICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQoIi4iKTsKICAgICAgICAgICAgICAgIGFwcGVuZEFubm90YXRpb25zU3RyaW5nKGJ1Zik7CiAgICAgICAgICAgICAgICBidWYuYXBwZW5kKGNsYXNzTmFtZSh0c3ltLCBmYWxzZSkpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgYXBwZW5kQW5ub3RhdGlvbnNTdHJpbmcoYnVmKTsKICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQoY2xhc3NOYW1lKHRzeW0sIHRydWUpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKGdldFR5cGVBcmd1bWVudHMoKS5ub25FbXB0eSgpKSB7CiAgICAgICAgICAgICAgICBidWYuYXBwZW5kKCc8Jyk7CiAgICAgICAgICAgICAgICBidWYuYXBwZW5kKGdldFR5cGVBcmd1bWVudHMoKS50b1N0cmluZygpKTsKICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQoIj4iKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gYnVmLnRvU3RyaW5nKCk7CiAgICAgICAgfQovL3doZXJlCiAgICAgICAgICAgIHByaXZhdGUgU3RyaW5nIGNsYXNzTmFtZShTeW1ib2wgc3ltLCBib29sZWFuIGxvbmdmb3JtKSB7CiAgICAgICAgICAgICAgICBpZiAoc3ltLm5hbWUuaXNFbXB0eSgpICYmIChzeW0uZmxhZ3MoKSAmIENPTVBPVU5EKSAhPSAwKSB7CiAgICAgICAgICAgICAgICAgICAgU3RyaW5nQnVpbGRlciBzID0gbmV3IFN0cmluZ0J1aWxkZXIoc3VwZXJ0eXBlX2ZpZWxkLnRvU3RyaW5nKCkpOwogICAgICAgICAgICAgICAgICAgIGZvciAoTGlzdDxUeXBlPiBpcz1pbnRlcmZhY2VzX2ZpZWxkOyBpcy5ub25FbXB0eSgpOyBpcyA9IGlzLnRhaWwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcy5hcHBlbmQoIiYiKTsKICAgICAgICAgICAgICAgICAgICAgICAgcy5hcHBlbmQoaXMuaGVhZC50b1N0cmluZygpKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHMudG9TdHJpbmcoKTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoc3ltLm5hbWUuaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHM7CiAgICAgICAgICAgICAgICAgICAgQ2xhc3NUeXBlIG5vcm0gPSAoQ2xhc3NUeXBlKSB0c3ltLnR5cGU7CiAgICAgICAgICAgICAgICAgICAgaWYgKG5vcm0gPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICBzID0gTG9nLmdldExvY2FsaXplZFN0cmluZygiYW5vbnltb3VzLmNsYXNzIiwgKE9iamVjdCludWxsKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKG5vcm0uaW50ZXJmYWNlc19maWVsZCAhPSBudWxsICYmIG5vcm0uaW50ZXJmYWNlc19maWVsZC5ub25FbXB0eSgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHMgPSBMb2cuZ2V0TG9jYWxpemVkU3RyaW5nKCJhbm9ueW1vdXMuY2xhc3MiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub3JtLmludGVyZmFjZXNfZmllbGQuaGVhZCk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgcyA9IExvZy5nZXRMb2NhbGl6ZWRTdHJpbmcoImFub255bW91cy5jbGFzcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vcm0uc3VwZXJ0eXBlX2ZpZWxkKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKG1vcmVJbmZvKQogICAgICAgICAgICAgICAgICAgICAgICBzICs9IFN0cmluZy52YWx1ZU9mKHN5bS5oYXNoQ29kZSgpKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gczsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAobG9uZ2Zvcm0pIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3ltLmdldFF1YWxpZmllZE5hbWUoKS50b1N0cmluZygpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3ltLm5hbWUudG9TdHJpbmcoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgICAgICBwdWJsaWMgTGlzdDxUeXBlPiBnZXRUeXBlQXJndW1lbnRzKCkgewogICAgICAgICAgICBpZiAodHlwYXJhbXNfZmllbGQgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgY29tcGxldGUoKTsKICAgICAgICAgICAgICAgIGlmICh0eXBhcmFtc19maWVsZCA9PSBudWxsKQogICAgICAgICAgICAgICAgICAgIHR5cGFyYW1zX2ZpZWxkID0gTGlzdC5uaWwoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gdHlwYXJhbXNfZmllbGQ7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNFcmFzZWRTdXBlcnR5cGVzKCkgewogICAgICAgICAgICByZXR1cm4gaXNSYXcoKTsKICAgICAgICB9CgogICAgICAgIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyBUeXBlIGdldEVuY2xvc2luZ1R5cGUoKSB7CiAgICAgICAgICAgIHJldHVybiBvdXRlcl9maWVsZDsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyB2b2lkIHNldEVuY2xvc2luZ1R5cGUoVHlwZSBvdXRlcikgewogICAgICAgICAgICBvdXRlcl9maWVsZCA9IG91dGVyOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIExpc3Q8VHlwZT4gYWxscGFyYW1zKCkgewogICAgICAgICAgICBpZiAoYWxscGFyYW1zX2ZpZWxkID09IG51bGwpIHsKICAgICAgICAgICAgICAgIGFsbHBhcmFtc19maWVsZCA9IGdldFR5cGVBcmd1bWVudHMoKS5wcmVwZW5kTGlzdChnZXRFbmNsb3NpbmdUeXBlKCkuYWxscGFyYW1zKCkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBhbGxwYXJhbXNfZmllbGQ7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc0Vycm9uZW91cygpIHsKICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgICAgICAgICBnZXRFbmNsb3NpbmdUeXBlKCkuaXNFcnJvbmVvdXMoKSB8fAogICAgICAgICAgICAgICAgaXNFcnJvbmVvdXMoZ2V0VHlwZUFyZ3VtZW50cygpKSB8fAogICAgICAgICAgICAgICAgdGhpcyAhPSB0c3ltLnR5cGUgJiYgdHN5bS50eXBlLmlzRXJyb25lb3VzKCk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc1BhcmFtZXRlcml6ZWQoKSB7CiAgICAgICAgICAgIHJldHVybiBhbGxwYXJhbXMoKS50YWlsICE9IG51bGw7CiAgICAgICAgICAgIC8vIG9wdGltaXphdGlvbiwgd2FzOiBhbGxwYXJhbXMoKS5ub25FbXB0eSgpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gaXNSZWZlcmVuY2UoKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gaXNOdWxsT3JSZWZlcmVuY2UoKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgLyoqIEEgY2FjaGUgZm9yIHRoZSByYW5rLiAqLwogICAgICAgIGludCByYW5rX2ZpZWxkID0gLTE7CgogICAgICAgIC8qKiBBIGNsYXNzIHR5cGUgaXMgcmF3IGlmIGl0IG1pc3NlcyBzb21lCiAgICAgICAgICogIG9mIGl0cyB0eXBlIHBhcmFtZXRlciBzZWN0aW9ucy4KICAgICAgICAgKiAgQWZ0ZXIgdmFsaWRhdGlvbiwgdGhpcyBpcyBlcXVpdmFsZW50IHRvOgogICAgICAgICAqICB7QGNvZGUgYWxscGFyYW1zLmlzRW1wdHkoKSAmJiB0c3ltLnR5cGUuYWxscGFyYW1zLm5vbkVtcHR5KCk7IH0KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc1JhdygpIHsKICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgICAgICAgICB0aGlzICE9IHRzeW0udHlwZSAmJiAvLyBuZWNlc3NhcnksIGJ1dCBub3Qgc3VmZmljaWVudCBjb25kaXRpb24KICAgICAgICAgICAgICAgIHRzeW0udHlwZS5hbGxwYXJhbXMoKS5ub25FbXB0eSgpICYmCiAgICAgICAgICAgICAgICBhbGxwYXJhbXMoKS5pc0VtcHR5KCk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWlucyhUeXBlIGVsZW0pIHsKICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgICAgICAgICBlbGVtLmVxdWFsc0lnbm9yZU1ldGFkYXRhKHRoaXMpCiAgICAgICAgICAgICAgICB8fCAoaXNQYXJhbWV0ZXJpemVkKCkKICAgICAgICAgICAgICAgICAgICAmJiAoZ2V0RW5jbG9zaW5nVHlwZSgpLmNvbnRhaW5zKGVsZW0pIHx8IGNvbnRhaW5zKGdldFR5cGVBcmd1bWVudHMoKSwgZWxlbSkpKQogICAgICAgICAgICAgICAgfHwgKGlzQ29tcG91bmQoKQogICAgICAgICAgICAgICAgICAgICYmIChzdXBlcnR5cGVfZmllbGQuY29udGFpbnMoZWxlbSkgfHwgY29udGFpbnMoaW50ZXJmYWNlc19maWVsZCwgZWxlbSkpKTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyB2b2lkIGNvbXBsZXRlKCkgewogICAgICAgICAgICB0c3ltLmNvbXBsZXRlKCk7CiAgICAgICAgfQoKICAgICAgICBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgICAgICBwdWJsaWMgVHlwZUtpbmQgZ2V0S2luZCgpIHsKICAgICAgICAgICAgcmV0dXJuIFR5cGVLaW5kLkRFQ0xBUkVEOwogICAgICAgIH0KCiAgICAgICAgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICAgICAgcHVibGljIDxSLCBQPiBSIGFjY2VwdChUeXBlVmlzaXRvcjxSLCBQPiB2LCBQIHApIHsKICAgICAgICAgICAgcmV0dXJuIHYudmlzaXREZWNsYXJlZCh0aGlzLCBwKTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjbGFzcyBFcmFzZWRDbGFzc1R5cGUgZXh0ZW5kcyBDbGFzc1R5cGUgewogICAgICAgIHB1YmxpYyBFcmFzZWRDbGFzc1R5cGUoVHlwZSBvdXRlciwgVHlwZVN5bWJvbCB0c3ltLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVHlwZU1ldGFkYXRhIG1ldGFkYXRhKSB7CiAgICAgICAgICAgIHN1cGVyKG91dGVyLCBMaXN0Lm5pbCgpLCB0c3ltLCBtZXRhZGF0YSk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNFcmFzZWRTdXBlcnR5cGVzKCkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICB9CgogICAgLy8gYSBjbG9uZSBvZiBhIENsYXNzVHlwZSB0aGF0IGtub3dzIGFib3V0IHRoZSBhbHRlcm5hdGl2ZXMgb2YgYSB1bmlvbiB0eXBlLgogICAgcHVibGljIHN0YXRpYyBjbGFzcyBVbmlvbkNsYXNzVHlwZSBleHRlbmRzIENsYXNzVHlwZSBpbXBsZW1lbnRzIFVuaW9uVHlwZSB7CiAgICAgICAgZmluYWwgTGlzdDw/IGV4dGVuZHMgVHlwZT4gYWx0ZXJuYXRpdmVzX2ZpZWxkOwoKICAgICAgICBwdWJsaWMgVW5pb25DbGFzc1R5cGUoQ2xhc3NUeXBlIGN0LCBMaXN0PD8gZXh0ZW5kcyBUeXBlPiBhbHRlcm5hdGl2ZXMpIHsKICAgICAgICAgICAgLy8gUHJlc2VudGx5IG5vIHdheSB0byByZWZlciB0byB0aGlzIHR5cGUgZGlyZWN0bHksIHNvIHdlCiAgICAgICAgICAgIC8vIGNhbm5vdCBwdXQgYW5ub3RhdGlvbnMgZGlyZWN0bHkgb24gaXQuCiAgICAgICAgICAgIHN1cGVyKGN0Lm91dGVyX2ZpZWxkLCBjdC50eXBhcmFtc19maWVsZCwgY3QudHN5bSk7CiAgICAgICAgICAgIGFsbHBhcmFtc19maWVsZCA9IGN0LmFsbHBhcmFtc19maWVsZDsKICAgICAgICAgICAgc3VwZXJ0eXBlX2ZpZWxkID0gY3Quc3VwZXJ0eXBlX2ZpZWxkOwogICAgICAgICAgICBpbnRlcmZhY2VzX2ZpZWxkID0gY3QuaW50ZXJmYWNlc19maWVsZDsKICAgICAgICAgICAgYWxsX2ludGVyZmFjZXNfZmllbGQgPSBjdC5pbnRlcmZhY2VzX2ZpZWxkOwogICAgICAgICAgICBhbHRlcm5hdGl2ZXNfZmllbGQgPSBhbHRlcm5hdGl2ZXM7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgVW5pb25DbGFzc1R5cGUgY2xvbmVXaXRoTWV0YWRhdGEoVHlwZU1ldGFkYXRhIG1kKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigiQ2Fubm90IGFkZCBtZXRhZGF0YSB0byBhIHVuaW9uIHR5cGUiKTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBUeXBlIGdldEx1YigpIHsKICAgICAgICAgICAgcmV0dXJuIHRzeW0udHlwZTsKICAgICAgICB9CgogICAgICAgIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgVHlwZU1pcnJvcj4gZ2V0QWx0ZXJuYXRpdmVzKCkgewogICAgICAgICAgICByZXR1cm4gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChhbHRlcm5hdGl2ZXNfZmllbGQpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gaXNVbmlvbigpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc0NvbXBvdW5kKCkgewogICAgICAgICAgICByZXR1cm4gZ2V0THViKCkuaXNDb21wb3VuZCgpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyBUeXBlS2luZCBnZXRLaW5kKCkgewogICAgICAgICAgICByZXR1cm4gVHlwZUtpbmQuVU5JT047CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICAgICAgcHVibGljIDxSLCBQPiBSIGFjY2VwdChUeXBlVmlzaXRvcjxSLCBQPiB2LCBQIHApIHsKICAgICAgICAgICAgcmV0dXJuIHYudmlzaXRVbmlvbih0aGlzLCBwKTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBJdGVyYWJsZTw/IGV4dGVuZHMgVHlwZT4gZ2V0QWx0ZXJuYXRpdmVUeXBlcygpIHsKICAgICAgICAgICAgcmV0dXJuIGFsdGVybmF0aXZlc19maWVsZDsKICAgICAgICB9CiAgICB9CgogICAgLy8gYSBjbG9uZSBvZiBhIENsYXNzVHlwZSB0aGF0IGtub3dzIGFib3V0IHRoZSBib3VuZHMgb2YgYW4gaW50ZXJzZWN0aW9uIHR5cGUuCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIEludGVyc2VjdGlvbkNsYXNzVHlwZSBleHRlbmRzIENsYXNzVHlwZSBpbXBsZW1lbnRzIEludGVyc2VjdGlvblR5cGUgewoKICAgICAgICBwdWJsaWMgYm9vbGVhbiBhbGxJbnRlcmZhY2VzOwoKICAgICAgICBwdWJsaWMgSW50ZXJzZWN0aW9uQ2xhc3NUeXBlKExpc3Q8VHlwZT4gYm91bmRzLCBDbGFzc1N5bWJvbCBjc3ltLCBib29sZWFuIGFsbEludGVyZmFjZXMpIHsKICAgICAgICAgICAgLy8gUHJlc2VudGx5IG5vIHdheSB0byByZWZlciB0byB0aGlzIHR5cGUgZGlyZWN0bHksIHNvIHdlCiAgICAgICAgICAgIC8vIGNhbm5vdCBwdXQgYW5ub3RhdGlvbnMgZGlyZWN0bHkgb24gaXQuCiAgICAgICAgICAgIHN1cGVyKFR5cGUubm9UeXBlLCBMaXN0Lm5pbCgpLCBjc3ltKTsKICAgICAgICAgICAgdGhpcy5hbGxJbnRlcmZhY2VzID0gYWxsSW50ZXJmYWNlczsKICAgICAgICAgICAgQXNzZXJ0LmNoZWNrKChjc3ltLmZsYWdzKCkgJiBDT01QT1VORCkgIT0gMCk7CiAgICAgICAgICAgIHN1cGVydHlwZV9maWVsZCA9IGJvdW5kcy5oZWFkOwogICAgICAgICAgICBpbnRlcmZhY2VzX2ZpZWxkID0gYm91bmRzLnRhaWw7CiAgICAgICAgICAgIEFzc2VydC5jaGVjayghc3VwZXJ0eXBlX2ZpZWxkLnRzeW0uaXNDb21wbGV0ZWQoKSB8fAogICAgICAgICAgICAgICAgICAgICFzdXBlcnR5cGVfZmllbGQuaXNJbnRlcmZhY2UoKSwgc3VwZXJ0eXBlX2ZpZWxkKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBJbnRlcnNlY3Rpb25DbGFzc1R5cGUgY2xvbmVXaXRoTWV0YWRhdGEoVHlwZU1ldGFkYXRhIG1kKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigiQ2Fubm90IGFkZCBtZXRhZGF0YSB0byBhbiBpbnRlcnNlY3Rpb24gdHlwZSIpOwogICAgICAgIH0KCiAgICAgICAgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBUeXBlTWlycm9yPiBnZXRCb3VuZHMoKSB7CiAgICAgICAgICAgIHJldHVybiBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KGdldEV4cGxpY2l0Q29tcG9uZW50cygpKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBib29sZWFuIGlzQ29tcG91bmQoKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIExpc3Q8VHlwZT4gZ2V0Q29tcG9uZW50cygpIHsKICAgICAgICAgICAgcmV0dXJuIGludGVyZmFjZXNfZmllbGQucHJlcGVuZChzdXBlcnR5cGVfZmllbGQpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gaXNJbnRlcnNlY3Rpb24oKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIExpc3Q8VHlwZT4gZ2V0RXhwbGljaXRDb21wb25lbnRzKCkgewogICAgICAgICAgICByZXR1cm4gYWxsSW50ZXJmYWNlcyA/CiAgICAgICAgICAgICAgICAgICAgaW50ZXJmYWNlc19maWVsZCA6CiAgICAgICAgICAgICAgICAgICAgZ2V0Q29tcG9uZW50cygpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyBUeXBlS2luZCBnZXRLaW5kKCkgewogICAgICAgICAgICByZXR1cm4gVHlwZUtpbmQuSU5URVJTRUNUSU9OOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyA8UiwgUD4gUiBhY2NlcHQoVHlwZVZpc2l0b3I8UiwgUD4gdiwgUCBwKSB7CiAgICAgICAgICAgIHJldHVybiB2LnZpc2l0SW50ZXJzZWN0aW9uKHRoaXMsIHApOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIEFycmF5VHlwZSBleHRlbmRzIFR5cGUKICAgICAgICAgICAgaW1wbGVtZW50cyBqYXZheC5sYW5nLm1vZGVsLnR5cGUuQXJyYXlUeXBlIHsKCiAgICAgICAgcHVibGljIFR5cGUgZWxlbXR5cGU7CgogICAgICAgIHB1YmxpYyBBcnJheVR5cGUoVHlwZSBlbGVtdHlwZSwgVHlwZVN5bWJvbCBhcnJheUNsYXNzKSB7CiAgICAgICAgICAgIHRoaXMoZWxlbXR5cGUsIGFycmF5Q2xhc3MsIFR5cGVNZXRhZGF0YS5FTVBUWSk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgQXJyYXlUeXBlKFR5cGUgZWxlbXR5cGUsIFR5cGVTeW1ib2wgYXJyYXlDbGFzcywKICAgICAgICAgICAgICAgICAgICAgICAgIFR5cGVNZXRhZGF0YSBtZXRhZGF0YSkgewogICAgICAgICAgICBzdXBlcihhcnJheUNsYXNzLCBtZXRhZGF0YSk7CiAgICAgICAgICAgIHRoaXMuZWxlbXR5cGUgPSBlbGVtdHlwZTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBBcnJheVR5cGUoQXJyYXlUeXBlIHRoYXQpIHsKICAgICAgICAgICAgLy9ub3RlOiB0eXBlIG1ldGFkYXRhIGlzIGRlbGliZXJhdGVseSBzaGFyZWQgaGVyZSwgYXMgd2Ugd2FudCBzaWRlLWVmZmVjdHMgZnJvbSBhbm5vdGF0aW9uCiAgICAgICAgICAgIC8vcHJvY2Vzc2luZyB0byBmbG93IGZyb20gb3JpZ2luYWwgYXJyYXkgdG8gdGhlIGNsb25lZCBhcnJheS4KICAgICAgICAgICAgdGhpcyh0aGF0LmVsZW10eXBlLCB0aGF0LnRzeW0sIHRoYXQuZ2V0TWV0YWRhdGEoKSk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQXJyYXlUeXBlIGNsb25lV2l0aE1ldGFkYXRhKFR5cGVNZXRhZGF0YSBtZCkgewogICAgICAgICAgICByZXR1cm4gbmV3IEFycmF5VHlwZShlbGVtdHlwZSwgdHN5bSwgbWQpIHsKICAgICAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICAgICAgcHVibGljIFR5cGUgYmFzZVR5cGUoKSB7IHJldHVybiBBcnJheVR5cGUudGhpcy5iYXNlVHlwZSgpOyB9CiAgICAgICAgICAgIH07CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgVHlwZVRhZyBnZXRUYWcoKSB7CiAgICAgICAgICAgIHJldHVybiBBUlJBWTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyA8UixTPiBSIGFjY2VwdChUeXBlLlZpc2l0b3I8UixTPiB2LCBTIHMpIHsKICAgICAgICAgICAgcmV0dXJuIHYudmlzaXRBcnJheVR5cGUodGhpcywgcyk7CiAgICAgICAgfQoKICAgICAgICBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgICAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewogICAgICAgICAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKCiAgICAgICAgICAgIC8vIEZpcnN0IGFwcGVuZCByb290IGNvbXBvbmVudCB0eXBlCiAgICAgICAgICAgIFR5cGUgdCA9IGVsZW10eXBlOwogICAgICAgICAgICB3aGlsZSAodC5nZXRLaW5kKCkgPT0gVHlwZUtpbmQuQVJSQVkpCiAgICAgICAgICAgICAgICB0ID0gKChBcnJheVR5cGUpIHQpLmdldENvbXBvbmVudFR5cGUoKTsKICAgICAgICAgICAgc2IuYXBwZW5kKHQpOwoKICAgICAgICAgICAgLy8gdGhlbiBhcHBlbmQgQEFubm9bXSBAQW5ub1tdIC4uLiBAQW5ub1tdCiAgICAgICAgICAgIHQgPSB0aGlzOwogICAgICAgICAgICBkbyB7CiAgICAgICAgICAgICAgICB0LmFwcGVuZEFubm90YXRpb25zU3RyaW5nKHNiLCB0cnVlKTsKICAgICAgICAgICAgICAgIHNiLmFwcGVuZCgiW10iKTsKICAgICAgICAgICAgICAgIHQgPSAoKEFycmF5VHlwZSkgdCkuZ2V0Q29tcG9uZW50VHlwZSgpOwogICAgICAgICAgICB9IHdoaWxlICh0LmdldEtpbmQoKSA9PSBUeXBlS2luZC5BUlJBWSk7CgogICAgICAgICAgICByZXR1cm4gc2IudG9TdHJpbmcoKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgICAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iaikgewogICAgICAgICAgICBpZiAob2JqIGluc3RhbmNlb2YgQXJyYXlUeXBlKSB7CiAgICAgICAgICAgICAgICBBcnJheVR5cGUgdGhhdCA9IChBcnJheVR5cGUpb2JqOwogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMgPT0gdGhhdCB8fAogICAgICAgICAgICAgICAgICAgICAgICBlbGVtdHlwZS5lcXVhbHModGhhdC5lbGVtdHlwZSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgICAgICAgIHJldHVybiAoQVJSQVkub3JkaW5hbCgpIDw8IDUpICsgZWxlbXR5cGUuaGFzaENvZGUoKTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBib29sZWFuIGlzVmFyYXJncygpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIExpc3Q8VHlwZT4gYWxscGFyYW1zKCkgeyByZXR1cm4gZWxlbXR5cGUuYWxscGFyYW1zKCk7IH0KCiAgICAgICAgcHVibGljIGJvb2xlYW4gaXNFcnJvbmVvdXMoKSB7CiAgICAgICAgICAgIHJldHVybiBlbGVtdHlwZS5pc0Vycm9uZW91cygpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIGJvb2xlYW4gaXNQYXJhbWV0ZXJpemVkKCkgewogICAgICAgICAgICByZXR1cm4gZWxlbXR5cGUuaXNQYXJhbWV0ZXJpemVkKCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc1JlZmVyZW5jZSgpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc051bGxPclJlZmVyZW5jZSgpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc1JhdygpIHsKICAgICAgICAgICAgcmV0dXJuIGVsZW10eXBlLmlzUmF3KCk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgQXJyYXlUeXBlIG1ha2VWYXJhcmdzKCkgewogICAgICAgICAgICByZXR1cm4gbmV3IEFycmF5VHlwZShlbGVtdHlwZSwgdHN5bSwgbWV0YWRhdGEpIHsKICAgICAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICAgICAgcHVibGljIGJvb2xlYW4gaXNWYXJhcmdzKCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwogICAgICAgIH0KCiAgICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnMoVHlwZSBlbGVtKSB7CiAgICAgICAgICAgIHJldHVybiBlbGVtLmVxdWFsc0lnbm9yZU1ldGFkYXRhKHRoaXMpIHx8IGVsZW10eXBlLmNvbnRhaW5zKGVsZW0pOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHZvaWQgY29tcGxldGUoKSB7CiAgICAgICAgICAgIGVsZW10eXBlLmNvbXBsZXRlKCk7CiAgICAgICAgfQoKICAgICAgICBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgICAgICBwdWJsaWMgVHlwZSBnZXRDb21wb25lbnRUeXBlKCkgewogICAgICAgICAgICByZXR1cm4gZWxlbXR5cGU7CiAgICAgICAgfQoKICAgICAgICBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgICAgICBwdWJsaWMgVHlwZUtpbmQgZ2V0S2luZCgpIHsKICAgICAgICAgICAgcmV0dXJuIFR5cGVLaW5kLkFSUkFZOwogICAgICAgIH0KCiAgICAgICAgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICAgICAgcHVibGljIDxSLCBQPiBSIGFjY2VwdChUeXBlVmlzaXRvcjxSLCBQPiB2LCBQIHApIHsKICAgICAgICAgICAgcmV0dXJuIHYudmlzaXRBcnJheSh0aGlzLCBwKTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjbGFzcyBNZXRob2RUeXBlIGV4dGVuZHMgVHlwZSBpbXBsZW1lbnRzIEV4ZWN1dGFibGVUeXBlIHsKCiAgICAgICAgcHVibGljIExpc3Q8VHlwZT4gYXJndHlwZXM7CiAgICAgICAgcHVibGljIFR5cGUgcmVzdHlwZTsKICAgICAgICBwdWJsaWMgTGlzdDxUeXBlPiB0aHJvd247CgogICAgICAgIC8qKiBUaGUgdHlwZSBhbm5vdGF0aW9ucyBvbiB0aGUgbWV0aG9kIHJlY2VpdmVyLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBUeXBlIHJlY3Z0eXBlOwoKICAgICAgICBwdWJsaWMgTWV0aG9kVHlwZShMaXN0PFR5cGU+IGFyZ3R5cGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgIFR5cGUgcmVzdHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IHRocm93biwKICAgICAgICAgICAgICAgICAgICAgICAgICBUeXBlU3ltYm9sIG1ldGhvZENsYXNzKSB7CiAgICAgICAgICAgIC8vIFByZXNlbnRseSBubyB3YXkgdG8gcmVmZXIgdG8gYSBtZXRob2QgdHlwZSBkaXJlY3RseSwgc28KICAgICAgICAgICAgLy8gd2UgY2Fubm90IHB1dCB0eXBlIGFubm90YXRpb25zIG9uIGl0LgogICAgICAgICAgICBzdXBlcihtZXRob2RDbGFzcywgVHlwZU1ldGFkYXRhLkVNUFRZKTsKICAgICAgICAgICAgdGhpcy5hcmd0eXBlcyA9IGFyZ3R5cGVzOwogICAgICAgICAgICB0aGlzLnJlc3R5cGUgPSByZXN0eXBlOwogICAgICAgICAgICB0aGlzLnRocm93biA9IHRocm93bjsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBNZXRob2RUeXBlIGNsb25lV2l0aE1ldGFkYXRhKFR5cGVNZXRhZGF0YSBtZCkgewogICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoIkNhbm5vdCBhZGQgbWV0YWRhdGEgdG8gYSBtZXRob2QgdHlwZSIpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFR5cGVUYWcgZ2V0VGFnKCkgewogICAgICAgICAgICByZXR1cm4gTUVUSE9EOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIDxSLFM+IFIgYWNjZXB0KFR5cGUuVmlzaXRvcjxSLFM+IHYsIFMgcykgewogICAgICAgICAgICByZXR1cm4gdi52aXNpdE1ldGhvZFR5cGUodGhpcywgcyk7CiAgICAgICAgfQoKICAgICAgICAvKiogVGhlIEphdmEgc291cmNlIHdoaWNoIHRoaXMgdHlwZSByZXByZXNlbnRzLgogICAgICAgICAqCiAgICAgICAgICogIFhYWCAwNi8wOS85OSBpcmlzIFRoaXMgaXNuJ3QgY29ycmVjdCBKYXZhIHN5bnRheCwgYnV0IGl0IHByb2JhYmx5CiAgICAgICAgICogIHNob3VsZCBiZS4KICAgICAgICAgKi8KICAgICAgICBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgICAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewogICAgICAgICAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKICAgICAgICAgICAgYXBwZW5kQW5ub3RhdGlvbnNTdHJpbmcoc2IpOwogICAgICAgICAgICBzYi5hcHBlbmQoJygnKTsKICAgICAgICAgICAgc2IuYXBwZW5kKGFyZ3R5cGVzKTsKICAgICAgICAgICAgc2IuYXBwZW5kKCcpJyk7CiAgICAgICAgICAgIHNiLmFwcGVuZChyZXN0eXBlKTsKICAgICAgICAgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7CiAgICAgICAgfQoKICAgICAgICBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgICAgICBwdWJsaWMgTGlzdDxUeXBlPiAgICAgICAgZ2V0UGFyYW1ldGVyVHlwZXMoKSB7IHJldHVybiBhcmd0eXBlczsgfQogICAgICAgIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyBUeXBlICAgICAgICAgICAgICBnZXRSZXR1cm5UeXBlKCkgICAgIHsgcmV0dXJuIHJlc3R5cGU7IH0KICAgICAgICBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgICAgICBwdWJsaWMgVHlwZSAgICAgICAgICAgICAgZ2V0UmVjZWl2ZXJUeXBlKCkgICB7IHJldHVybiByZWN2dHlwZTsgfQogICAgICAgIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyBMaXN0PFR5cGU+ICAgICAgICBnZXRUaHJvd25UeXBlcygpICAgIHsgcmV0dXJuIHRocm93bjsgfQoKICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc0Vycm9uZW91cygpIHsKICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgICAgICAgICBpc0Vycm9uZW91cyhhcmd0eXBlcykgfHwKICAgICAgICAgICAgICAgIHJlc3R5cGUgIT0gbnVsbCAmJiByZXN0eXBlLmlzRXJyb25lb3VzKCk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWlucyhUeXBlIGVsZW0pIHsKICAgICAgICAgICAgcmV0dXJuIGVsZW0uZXF1YWxzSWdub3JlTWV0YWRhdGEodGhpcykgfHwgY29udGFpbnMoYXJndHlwZXMsIGVsZW0pIHx8IHJlc3R5cGUuY29udGFpbnMoZWxlbSkgfHwgY29udGFpbnModGhyb3duLCBlbGVtKTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBNZXRob2RUeXBlIGFzTWV0aG9kVHlwZSgpIHsgcmV0dXJuIHRoaXM7IH0KCiAgICAgICAgcHVibGljIHZvaWQgY29tcGxldGUoKSB7CiAgICAgICAgICAgIGZvciAoTGlzdDxUeXBlPiBsID0gYXJndHlwZXM7IGwubm9uRW1wdHkoKTsgbCA9IGwudGFpbCkKICAgICAgICAgICAgICAgIGwuaGVhZC5jb21wbGV0ZSgpOwogICAgICAgICAgICByZXN0eXBlLmNvbXBsZXRlKCk7CiAgICAgICAgICAgIHJlY3Z0eXBlLmNvbXBsZXRlKCk7CiAgICAgICAgICAgIGZvciAoTGlzdDxUeXBlPiBsID0gdGhyb3duOyBsLm5vbkVtcHR5KCk7IGwgPSBsLnRhaWwpCiAgICAgICAgICAgICAgICBsLmhlYWQuY29tcGxldGUoKTsKICAgICAgICB9CgogICAgICAgIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyBMaXN0PFR5cGVWYXI+IGdldFR5cGVWYXJpYWJsZXMoKSB7CiAgICAgICAgICAgIHJldHVybiBMaXN0Lm5pbCgpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIFR5cGVTeW1ib2wgYXNFbGVtZW50KCkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyBUeXBlS2luZCBnZXRLaW5kKCkgewogICAgICAgICAgICByZXR1cm4gVHlwZUtpbmQuRVhFQ1VUQUJMRTsKICAgICAgICB9CgogICAgICAgIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyA8UiwgUD4gUiBhY2NlcHQoVHlwZVZpc2l0b3I8UiwgUD4gdiwgUCBwKSB7CiAgICAgICAgICAgIHJldHVybiB2LnZpc2l0RXhlY3V0YWJsZSh0aGlzLCBwKTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjbGFzcyBQYWNrYWdlVHlwZSBleHRlbmRzIFR5cGUgaW1wbGVtZW50cyBOb1R5cGUgewoKICAgICAgICBQYWNrYWdlVHlwZShQYWNrYWdlU3ltYm9sIHRzeW0pIHsKICAgICAgICAgICAgLy8gUGFja2FnZSB0eXBlcyBjYW5ub3QgYmUgYW5ub3RhdGVkCiAgICAgICAgICAgIHN1cGVyKHRzeW0sIFR5cGVNZXRhZGF0YS5FTVBUWSk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgUGFja2FnZVR5cGUgY2xvbmVXaXRoTWV0YWRhdGEoVHlwZU1ldGFkYXRhIG1kKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigiQ2Fubm90IGFkZCBtZXRhZGF0YSB0byBhIHBhY2thZ2UgdHlwZSIpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFR5cGVUYWcgZ2V0VGFnKCkgewogICAgICAgICAgICByZXR1cm4gUEFDS0FHRTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyA8UixTPiBSIGFjY2VwdChUeXBlLlZpc2l0b3I8UixTPiB2LCBTIHMpIHsKICAgICAgICAgICAgcmV0dXJuIHYudmlzaXRQYWNrYWdlVHlwZSh0aGlzLCBzKTsKICAgICAgICB9CgogICAgICAgIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CiAgICAgICAgICAgIHJldHVybiB0c3ltLmdldFF1YWxpZmllZE5hbWUoKS50b1N0cmluZygpOwogICAgICAgIH0KCiAgICAgICAgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICAgICAgcHVibGljIFR5cGVLaW5kIGdldEtpbmQoKSB7CiAgICAgICAgICAgIHJldHVybiBUeXBlS2luZC5QQUNLQUdFOwogICAgICAgIH0KCiAgICAgICAgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICAgICAgcHVibGljIDxSLCBQPiBSIGFjY2VwdChUeXBlVmlzaXRvcjxSLCBQPiB2LCBQIHApIHsKICAgICAgICAgICAgcmV0dXJuIHYudmlzaXROb1R5cGUodGhpcywgcCk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgTW9kdWxlVHlwZSBleHRlbmRzIFR5cGUgaW1wbGVtZW50cyBOb1R5cGUgewoKICAgICAgICBNb2R1bGVUeXBlKE1vZHVsZVN5bWJvbCB0c3ltKSB7CiAgICAgICAgICAgIC8vIE1vZHVsZSB0eXBlcyBjYW5ub3QgYmUgYW5ub3RhdGVkCiAgICAgICAgICAgIHN1cGVyKHRzeW0sIFR5cGVNZXRhZGF0YS5FTVBUWSk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgTW9kdWxlVHlwZSBjbG9uZVdpdGhNZXRhZGF0YShUeXBlTWV0YWRhdGEgbWQpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCJDYW5ub3QgYWRkIG1ldGFkYXRhIHRvIGEgbW9kdWxlIHR5cGUiKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBNb2R1bGVUeXBlIGFubm90YXRlZFR5cGUoTGlzdDxBdHRyaWJ1dGUuVHlwZUNvbXBvdW5kPiBhbm5vcykgewogICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoIkNhbm5vdCBhbm5vdGF0ZSBhIG1vZHVsZSB0eXBlIik7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgVHlwZVRhZyBnZXRUYWcoKSB7CiAgICAgICAgICAgIHJldHVybiBUeXBlVGFnLk1PRFVMRTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyA8UixTPiBSIGFjY2VwdChUeXBlLlZpc2l0b3I8UixTPiB2LCBTIHMpIHsKICAgICAgICAgICAgcmV0dXJuIHYudmlzaXRNb2R1bGVUeXBlKHRoaXMsIHMpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CiAgICAgICAgICAgIHJldHVybiB0c3ltLmdldFF1YWxpZmllZE5hbWUoKS50b1N0cmluZygpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyBUeXBlS2luZCBnZXRLaW5kKCkgewogICAgICAgICAgICByZXR1cm4gVHlwZUtpbmQuTU9EVUxFOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyA8UiwgUD4gUiBhY2NlcHQoVHlwZVZpc2l0b3I8UiwgUD4gdiwgUCBwKSB7CiAgICAgICAgICAgIHJldHVybiB2LnZpc2l0Tm9UeXBlKHRoaXMsIHApOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIFR5cGVWYXIgZXh0ZW5kcyBUeXBlIGltcGxlbWVudHMgVHlwZVZhcmlhYmxlIHsKCiAgICAgICAgLyoqIFRoZSB1cHBlciBib3VuZCBvZiB0aGlzIHR5cGUgdmFyaWFibGU7IHNldCBmcm9tIG91dHNpZGUuCiAgICAgICAgICogIE11c3QgYmUgbm9uZW1wdHkgb25jZSBpdCBpcyBzZXQuCiAgICAgICAgICogIEZvciBhIGJvdW5kLCBgYm91bmQnIGlzIHRoZSBib3VuZCB0eXBlIGl0c2VsZi4KICAgICAgICAgKiAgTXVsdGlwbGUgYm91bmRzIGFyZSBleHByZXNzZWQgYXMgYSBzaW5nbGUgY2xhc3MgdHlwZSB3aGljaCBoYXMgdGhlCiAgICAgICAgICogIGluZGl2aWR1YWwgYm91bmRzIGFzIHN1cGVyY2xhc3MsIHJlc3BlY3RpdmVseSBpbnRlcmZhY2VzLgogICAgICAgICAqICBUaGUgY2xhc3MgdHlwZSB0aGVuIGhhcyBhcyBgdHN5bScgYSBjb21waWxlciBnZW5lcmF0ZWQgY2xhc3MgYGMnLAogICAgICAgICAqICB3aGljaCBoYXMgYSBmbGFnIENPTVBPVU5EIGFuZCB3aG9zZSBvd25lciBpcyB0aGUgdHlwZSB2YXJpYWJsZQogICAgICAgICAqICBpdHNlbGYuIEZ1cnRoZXJtb3JlLCB0aGUgZXJhc3VyZV9maWVsZCBvZiB0aGUgY2xhc3MKICAgICAgICAgKiAgcG9pbnRzIHRvIHRoZSBmaXJzdCBjbGFzcyBvciBpbnRlcmZhY2UgYm91bmQuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIFR5cGUgYm91bmQgPSBudWxsOwoKICAgICAgICAvKiogVGhlIGxvd2VyIGJvdW5kIG9mIHRoaXMgdHlwZSB2YXJpYWJsZS4KICAgICAgICAgKiAgVHlwZVZhcnMgZG9uJ3Qgbm9ybWFsbHkgaGF2ZSBhIGxvd2VyIGJvdW5kLCBzbyBpdCBpcyBub3JtYWxseSBzZXQKICAgICAgICAgKiAgdG8gc3ltcy5ib3RUeXBlLgogICAgICAgICAqICBTdWJ0eXBlcywgc3VjaCBhcyBDYXB0dXJlZFR5cGUsIG1heSBwcm92aWRlIGEgZGlmZmVyZW50IHZhbHVlLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBUeXBlIGxvd2VyOwoKICAgICAgICBwdWJsaWMgVHlwZVZhcihOYW1lIG5hbWUsIFN5bWJvbCBvd25lciwgVHlwZSBsb3dlcikgewogICAgICAgICAgICBzdXBlcihudWxsLCBUeXBlTWV0YWRhdGEuRU1QVFkpOwogICAgICAgICAgICB0c3ltID0gbmV3IFR5cGVWYXJpYWJsZVN5bWJvbCgwLCBuYW1lLCB0aGlzLCBvd25lcik7CiAgICAgICAgICAgIHRoaXMuYm91bmQgPSBudWxsOwogICAgICAgICAgICB0aGlzLmxvd2VyID0gbG93ZXI7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgVHlwZVZhcihUeXBlU3ltYm9sIHRzeW0sIFR5cGUgYm91bmQsIFR5cGUgbG93ZXIpIHsKICAgICAgICAgICAgdGhpcyh0c3ltLCBib3VuZCwgbG93ZXIsIFR5cGVNZXRhZGF0YS5FTVBUWSk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgVHlwZVZhcihUeXBlU3ltYm9sIHRzeW0sIFR5cGUgYm91bmQsIFR5cGUgbG93ZXIsCiAgICAgICAgICAgICAgICAgICAgICAgVHlwZU1ldGFkYXRhIG1ldGFkYXRhKSB7CiAgICAgICAgICAgIHN1cGVyKHRzeW0sIG1ldGFkYXRhKTsKICAgICAgICAgICAgdGhpcy5ib3VuZCA9IGJvdW5kOwogICAgICAgICAgICB0aGlzLmxvd2VyID0gbG93ZXI7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgVHlwZVZhciBjbG9uZVdpdGhNZXRhZGF0YShUeXBlTWV0YWRhdGEgbWQpIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyBUeXBlVmFyKHRzeW0sIGJvdW5kLCBsb3dlciwgbWQpIHsKICAgICAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICAgICAgcHVibGljIFR5cGUgYmFzZVR5cGUoKSB7IHJldHVybiBUeXBlVmFyLnRoaXMuYmFzZVR5cGUoKTsgfQogICAgICAgICAgICB9OwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFR5cGVUYWcgZ2V0VGFnKCkgewogICAgICAgICAgICByZXR1cm4gVFlQRVZBUjsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyA8UixTPiBSIGFjY2VwdChUeXBlLlZpc2l0b3I8UixTPiB2LCBTIHMpIHsKICAgICAgICAgICAgcmV0dXJuIHYudmlzaXRUeXBlVmFyKHRoaXMsIHMpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyBUeXBlIGdldFVwcGVyQm91bmQoKSB7CiAgICAgICAgICAgIGlmICgoYm91bmQgPT0gbnVsbCB8fCBib3VuZC5oYXNUYWcoTk9ORSkpICYmIHRoaXMgIT0gdHN5bS50eXBlKSB7CiAgICAgICAgICAgICAgICBib3VuZCA9IHRzeW0udHlwZS5nZXRVcHBlckJvdW5kKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGJvdW5kOwogICAgICAgIH0KCiAgICAgICAgaW50IHJhbmtfZmllbGQgPSAtMTsKCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyBUeXBlIGdldExvd2VyQm91bmQoKSB7CiAgICAgICAgICAgIHJldHVybiBsb3dlcjsKICAgICAgICB9CgogICAgICAgIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyBUeXBlS2luZCBnZXRLaW5kKCkgewogICAgICAgICAgICByZXR1cm4gVHlwZUtpbmQuVFlQRVZBUjsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBib29sZWFuIGlzQ2FwdHVyZWQoKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBib29sZWFuIGlzUmVmZXJlbmNlKCkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBib29sZWFuIGlzTnVsbE9yUmVmZXJlbmNlKCkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgICAgICBwdWJsaWMgPFIsIFA+IFIgYWNjZXB0KFR5cGVWaXNpdG9yPFIsIFA+IHYsIFAgcCkgewogICAgICAgICAgICByZXR1cm4gdi52aXNpdFR5cGVWYXJpYWJsZSh0aGlzLCBwKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqIEEgY2FwdHVyZWQgdHlwZSB2YXJpYWJsZSBjb21lcyBmcm9tIHdpbGRjYXJkcyB3aGljaCBjYW4gaGF2ZQogICAgICogIGJvdGggdXBwZXIgYW5kIGxvd2VyIGJvdW5kLiAgQ2FwdHVyZWRUeXBlIGV4dGVuZHMgVHlwZVZhciB3aXRoCiAgICAgKiAgYSBsb3dlciBib3VuZC4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBjbGFzcyBDYXB0dXJlZFR5cGUgZXh0ZW5kcyBUeXBlVmFyIHsKCiAgICAgICAgcHVibGljIFdpbGRjYXJkVHlwZSB3aWxkY2FyZDsKCiAgICAgICAgcHVibGljIENhcHR1cmVkVHlwZShOYW1lIG5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBTeW1ib2wgb3duZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBUeXBlIHVwcGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgVHlwZSBsb3dlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdpbGRjYXJkVHlwZSB3aWxkY2FyZCkgewogICAgICAgICAgICBzdXBlcihuYW1lLCBvd25lciwgbG93ZXIpOwogICAgICAgICAgICB0aGlzLmxvd2VyID0gQXNzZXJ0LmNoZWNrTm9uTnVsbChsb3dlcik7CiAgICAgICAgICAgIHRoaXMuYm91bmQgPSB1cHBlcjsKICAgICAgICAgICAgdGhpcy53aWxkY2FyZCA9IHdpbGRjYXJkOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIENhcHR1cmVkVHlwZShUeXBlU3ltYm9sIHRzeW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBUeXBlIGJvdW5kLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgVHlwZSB1cHBlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFR5cGUgbG93ZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBXaWxkY2FyZFR5cGUgd2lsZGNhcmQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBUeXBlTWV0YWRhdGEgbWV0YWRhdGEpIHsKICAgICAgICAgICAgc3VwZXIodHN5bSwgYm91bmQsIGxvd2VyLCBtZXRhZGF0YSk7CiAgICAgICAgICAgIHRoaXMud2lsZGNhcmQgPSB3aWxkY2FyZDsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBDYXB0dXJlZFR5cGUgY2xvbmVXaXRoTWV0YWRhdGEoVHlwZU1ldGFkYXRhIG1kKSB7CiAgICAgICAgICAgIHJldHVybiBuZXcgQ2FwdHVyZWRUeXBlKHRzeW0sIGJvdW5kLCBib3VuZCwgbG93ZXIsIHdpbGRjYXJkLCBtZCkgewogICAgICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgICAgICBwdWJsaWMgVHlwZSBiYXNlVHlwZSgpIHsgcmV0dXJuIENhcHR1cmVkVHlwZS50aGlzLmJhc2VUeXBlKCk7IH0KICAgICAgICAgICAgfTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyA8UixTPiBSIGFjY2VwdChUeXBlLlZpc2l0b3I8UixTPiB2LCBTIHMpIHsKICAgICAgICAgICAgcmV0dXJuIHYudmlzaXRDYXB0dXJlZFR5cGUodGhpcywgcyk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc0NhcHR1cmVkKCkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgICAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewogICAgICAgICAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKICAgICAgICAgICAgYXBwZW5kQW5ub3RhdGlvbnNTdHJpbmcoc2IpOwogICAgICAgICAgICBzYi5hcHBlbmQoImNhcHR1cmUjIik7CiAgICAgICAgICAgIHNiLmFwcGVuZCgoaGFzaENvZGUoKSAmIDB4RkZGRkZGRkZMKSAlIFByaW50ZXIuUFJJTUUpOwogICAgICAgICAgICBzYi5hcHBlbmQoIiBvZiAiKTsKICAgICAgICAgICAgc2IuYXBwZW5kKHdpbGRjYXJkKTsKICAgICAgICAgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgYWJzdHJhY3QgY2xhc3MgRGVsZWdhdGVkVHlwZSBleHRlbmRzIFR5cGUgewogICAgICAgIHB1YmxpYyBUeXBlIHF0eXBlOwogICAgICAgIHB1YmxpYyBUeXBlVGFnIHRhZzsKCiAgICAgICAgcHVibGljIERlbGVnYXRlZFR5cGUoVHlwZVRhZyB0YWcsIFR5cGUgcXR5cGUpIHsKICAgICAgICAgICAgdGhpcyh0YWcsIHF0eXBlLCBUeXBlTWV0YWRhdGEuRU1QVFkpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIERlbGVnYXRlZFR5cGUoVHlwZVRhZyB0YWcsIFR5cGUgcXR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVHlwZU1ldGFkYXRhIG1ldGFkYXRhKSB7CiAgICAgICAgICAgIHN1cGVyKHF0eXBlLnRzeW0sIG1ldGFkYXRhKTsKICAgICAgICAgICAgdGhpcy50YWcgPSB0YWc7CiAgICAgICAgICAgIHRoaXMucXR5cGUgPSBxdHlwZTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBUeXBlVGFnIGdldFRhZygpIHsgcmV0dXJuIHRhZzsgfQogICAgICAgIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7IHJldHVybiBxdHlwZS50b1N0cmluZygpOyB9CiAgICAgICAgcHVibGljIExpc3Q8VHlwZT4gZ2V0VHlwZUFyZ3VtZW50cygpIHsgcmV0dXJuIHF0eXBlLmdldFR5cGVBcmd1bWVudHMoKTsgfQogICAgICAgIHB1YmxpYyBUeXBlIGdldEVuY2xvc2luZ1R5cGUoKSB7IHJldHVybiBxdHlwZS5nZXRFbmNsb3NpbmdUeXBlKCk7IH0KICAgICAgICBwdWJsaWMgTGlzdDxUeXBlPiBnZXRQYXJhbWV0ZXJUeXBlcygpIHsgcmV0dXJuIHF0eXBlLmdldFBhcmFtZXRlclR5cGVzKCk7IH0KICAgICAgICBwdWJsaWMgVHlwZSBnZXRSZXR1cm5UeXBlKCkgeyByZXR1cm4gcXR5cGUuZ2V0UmV0dXJuVHlwZSgpOyB9CiAgICAgICAgcHVibGljIFR5cGUgZ2V0UmVjZWl2ZXJUeXBlKCkgeyByZXR1cm4gcXR5cGUuZ2V0UmVjZWl2ZXJUeXBlKCk7IH0KICAgICAgICBwdWJsaWMgTGlzdDxUeXBlPiBnZXRUaHJvd25UeXBlcygpIHsgcmV0dXJuIHF0eXBlLmdldFRocm93blR5cGVzKCk7IH0KICAgICAgICBwdWJsaWMgTGlzdDxUeXBlPiBhbGxwYXJhbXMoKSB7IHJldHVybiBxdHlwZS5hbGxwYXJhbXMoKTsgfQogICAgICAgIHB1YmxpYyBUeXBlIGdldFVwcGVyQm91bmQoKSB7IHJldHVybiBxdHlwZS5nZXRVcHBlckJvdW5kKCk7IH0KICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc0Vycm9uZW91cygpIHsgcmV0dXJuIHF0eXBlLmlzRXJyb25lb3VzKCk7IH0KICAgIH0KCiAgICAvKioKICAgICAqIFRoZSB0eXBlIG9mIGEgZ2VuZXJpYyBtZXRob2QgdHlwZS4gSXQgY29uc2lzdHMgb2YgYSBtZXRob2QgdHlwZSBhbmQKICAgICAqIGEgbGlzdCBvZiBtZXRob2QgdHlwZS1wYXJhbWV0ZXJzIHRoYXQgYXJlIHVzZWQgd2l0aGluIHRoZSBtZXRob2QKICAgICAqIHR5cGUuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgRm9yQWxsIGV4dGVuZHMgRGVsZWdhdGVkVHlwZSBpbXBsZW1lbnRzIEV4ZWN1dGFibGVUeXBlIHsKICAgICAgICBwdWJsaWMgTGlzdDxUeXBlPiB0dmFyczsKCiAgICAgICAgcHVibGljIEZvckFsbChMaXN0PFR5cGU+IHR2YXJzLCBUeXBlIHF0eXBlKSB7CiAgICAgICAgICAgIHN1cGVyKEZPUkFMTCwgKE1ldGhvZFR5cGUpcXR5cGUpOwogICAgICAgICAgICB0aGlzLnR2YXJzID0gdHZhcnM7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgRm9yQWxsIGNsb25lV2l0aE1ldGFkYXRhKFR5cGVNZXRhZGF0YSBtZCkgewogICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoIkNhbm5vdCBhZGQgbWV0YWRhdGEgdG8gYSBmb3JhbGwgdHlwZSIpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIDxSLFM+IFIgYWNjZXB0KFR5cGUuVmlzaXRvcjxSLFM+IHYsIFMgcykgewogICAgICAgICAgICByZXR1cm4gdi52aXNpdEZvckFsbCh0aGlzLCBzKTsKICAgICAgICB9CgogICAgICAgIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CiAgICAgICAgICAgIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigpOwogICAgICAgICAgICBhcHBlbmRBbm5vdGF0aW9uc1N0cmluZyhzYik7CiAgICAgICAgICAgIHNiLmFwcGVuZCgnPCcpOwogICAgICAgICAgICBzYi5hcHBlbmQodHZhcnMpOwogICAgICAgICAgICBzYi5hcHBlbmQoJz4nKTsKICAgICAgICAgICAgc2IuYXBwZW5kKHF0eXBlKTsKICAgICAgICAgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgTGlzdDxUeXBlPiBnZXRUeXBlQXJndW1lbnRzKCkgICB7IHJldHVybiB0dmFyczsgfQoKICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc0Vycm9uZW91cygpICB7CiAgICAgICAgICAgIHJldHVybiBxdHlwZS5pc0Vycm9uZW91cygpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnMoVHlwZSBlbGVtKSB7CiAgICAgICAgICAgIHJldHVybiBxdHlwZS5jb250YWlucyhlbGVtKTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBNZXRob2RUeXBlIGFzTWV0aG9kVHlwZSgpIHsKICAgICAgICAgICAgcmV0dXJuIChNZXRob2RUeXBlKXF0eXBlOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHZvaWQgY29tcGxldGUoKSB7CiAgICAgICAgICAgIGZvciAoTGlzdDxUeXBlPiBsID0gdHZhcnM7IGwubm9uRW1wdHkoKTsgbCA9IGwudGFpbCkgewogICAgICAgICAgICAgICAgKChUeXBlVmFyKWwuaGVhZCkuYm91bmQuY29tcGxldGUoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBxdHlwZS5jb21wbGV0ZSgpOwogICAgICAgIH0KCiAgICAgICAgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICAgICAgcHVibGljIExpc3Q8VHlwZVZhcj4gZ2V0VHlwZVZhcmlhYmxlcygpIHsKICAgICAgICAgICAgcmV0dXJuIExpc3QuY29udmVydChUeXBlVmFyLmNsYXNzLCBnZXRUeXBlQXJndW1lbnRzKCkpOwogICAgICAgIH0KCiAgICAgICAgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICAgICAgcHVibGljIFR5cGVLaW5kIGdldEtpbmQoKSB7CiAgICAgICAgICAgIHJldHVybiBUeXBlS2luZC5FWEVDVVRBQkxFOwogICAgICAgIH0KCiAgICAgICAgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICAgICAgcHVibGljIDxSLCBQPiBSIGFjY2VwdChUeXBlVmlzaXRvcjxSLCBQPiB2LCBQIHApIHsKICAgICAgICAgICAgcmV0dXJuIHYudmlzaXRFeGVjdXRhYmxlKHRoaXMsIHApOwogICAgICAgIH0KICAgIH0KCiAgICAvKiogQSBjbGFzcyBmb3IgaW5mZXJlbmNlIHZhcmlhYmxlcywgZm9yIHVzZSBkdXJpbmcgbWV0aG9kL2RpYW1vbmQgdHlwZQogICAgICogIGluZmVyZW5jZS4gQW4gaW5mZXJlbmNlIHZhcmlhYmxlIGhhcyB1cHBlci9sb3dlciBib3VuZHMgYW5kIGEgc2V0CiAgICAgKiAgb2YgZXF1YWxpdHkgY29uc3RyYWludHMuIFN1Y2ggYm91bmRzIGFyZSBzZXQgZHVyaW5nIHN1YnR5cGluZywgdHlwZS1jb250YWlubWVudCwKICAgICAqICB0eXBlLWVxdWFsaXR5IGNoZWNrcywgd2hlbiB0aGUgdHlwZXMgYmVpbmcgdGVzdGVkIGNvbnRhaW4gaW5mZXJlbmNlIHZhcmlhYmxlcy4KICAgICAqICBBIGNoYW5nZSBsaXN0ZW5lciBjYW4gYmUgYXR0YWNoZWQgdG8gYW4gaW5mZXJlbmNlIHZhcmlhYmxlLCB0byByZWNlaXZlIG5vdGlmaWNhdGlvbnMKICAgICAqICB3aGVuZXZlciB0aGUgYm91bmRzIG9mIGFuIGluZmVyZW5jZSB2YXJpYWJsZSBjaGFuZ2UuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgVW5kZXRWYXIgZXh0ZW5kcyBEZWxlZ2F0ZWRUeXBlIHsKCiAgICAgICAgZW51bSBLaW5kIHsKICAgICAgICAgICAgTk9STUFMLAogICAgICAgICAgICBDQVBUVVJFRCwKICAgICAgICAgICAgVEhST1dTOwogICAgICAgIH0KCiAgICAgICAgLyoqIEluZmVyZW5jZSB2YXJpYWJsZSBjaGFuZ2UgbGlzdGVuZXIuIFRoZSBsaXN0ZW5lciBtZXRob2QgaXMgY2FsbGVkCiAgICAgICAgICogIHdoZW5ldmVyIGEgY2hhbmdlIHRvIHRoZSBpbmZlcmVuY2UgdmFyaWFibGUncyBib3VuZHMgb2NjdXJzCiAgICAgICAgICovCiAgICAgICAgcHVibGljIGludGVyZmFjZSBVbmRldFZhckxpc3RlbmVyIHsKICAgICAgICAgICAgLyoqIGNhbGxlZCB3aGVuIHNvbWUgaW5mZXJlbmNlIHZhcmlhYmxlIGJvdW5kcyAob2YgZ2l2ZW4ga2luZHMgaWJzKSBjaGFuZ2UgKi8KICAgICAgICAgICAgdm9pZCB2YXJCb3VuZENoYW5nZWQoVW5kZXRWYXIgdXYsIEluZmVyZW5jZUJvdW5kIGliLCBUeXBlIGJvdW5kLCBib29sZWFuIHVwZGF0ZSk7CiAgICAgICAgICAgIC8qKiBjYWxsZWQgd2hlbiB0aGUgaW5mZXJyZWQgdHlwZSBpcyBzZXQgb24gc29tZSBpbmZlcmVuY2UgdmFyaWFibGUgKi8KICAgICAgICAgICAgZGVmYXVsdCB2b2lkIHZhckluc3RhbnRpYXRlZChVbmRldFZhciB1dikgeyBBc3NlcnQuZXJyb3IoKTsgfQogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogSW5mZXJlbmNlIHZhcmlhYmxlIGJvdW5kIGtpbmRzCiAgICAgICAgICovCiAgICAgICAgcHVibGljIGVudW0gSW5mZXJlbmNlQm91bmQgewogICAgICAgICAgICAvKiogbG93ZXIgYm91bmRzICovCiAgICAgICAgICAgIExPV0VSIHsKICAgICAgICAgICAgICAgIHB1YmxpYyBJbmZlcmVuY2VCb3VuZCBjb21wbGVtZW50KCkgeyByZXR1cm4gVVBQRVI7IH0KICAgICAgICAgICAgfSwKICAgICAgICAgICAgLyoqIGVxdWFsaXR5IGNvbnN0cmFpbnRzICovCiAgICAgICAgICAgIEVRIHsKICAgICAgICAgICAgICAgIHB1YmxpYyBJbmZlcmVuY2VCb3VuZCBjb21wbGVtZW50KCkgeyByZXR1cm4gRVE7IH0KICAgICAgICAgICAgfSwKICAgICAgICAgICAgLyoqIHVwcGVyIGJvdW5kcyAqLwogICAgICAgICAgICBVUFBFUiB7CiAgICAgICAgICAgICAgICBwdWJsaWMgSW5mZXJlbmNlQm91bmQgY29tcGxlbWVudCgpIHsgcmV0dXJuIExPV0VSOyB9CiAgICAgICAgICAgIH07CgogICAgICAgICAgICBwdWJsaWMgYWJzdHJhY3QgSW5mZXJlbmNlQm91bmQgY29tcGxlbWVudCgpOwoKICAgICAgICAgICAgcHVibGljIGJvb2xlYW4gbGVzc1RoYW4oSW5mZXJlbmNlQm91bmQgdGhhdCkgewogICAgICAgICAgICAgICAgaWYgKHRoYXQgPT0gdGhpcykgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgc3dpdGNoICh0aGF0KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgVVBQRVI6IHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIExPV0VSOiByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgRVE6IHJldHVybiAodGhpcyAhPSBVUFBFUik7CiAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBBc3NlcnQuZXJyb3IoIkNhbm5vdCBnZXQgaGVyZSEiKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8qKiBsaXN0IG9mIGluY29ycG9yYXRpb24gYWN0aW9ucyAodXNlZCBieSB0aGUgaW5jb3Jwb3JhdGlvbiBlbmdpbmUpLiAqLwogICAgICAgIHB1YmxpYyBBcnJheURlcXVlPEluY29ycG9yYXRpb25BY3Rpb24+IGluY29ycG9yYXRpb25BY3Rpb25zID0gbmV3IEFycmF5RGVxdWU8PigpOwoKICAgICAgICAvKiogaW5mZXJlbmNlIHZhcmlhYmxlIGJvdW5kcyAqLwogICAgICAgIHByb3RlY3RlZCBNYXA8SW5mZXJlbmNlQm91bmQsIExpc3Q8VHlwZT4+IGJvdW5kczsKCiAgICAgICAgLyoqIGluZmVyZW5jZSB2YXJpYWJsZSdzIGluZmVycmVkIHR5cGUgKHNldCBmcm9tIEluZmVyLmphdmEpICovCiAgICAgICAgcHJpdmF0ZSBUeXBlIGluc3QgPSBudWxsOwoKICAgICAgICAvKiogbnVtYmVyIG9mIGRlY2xhcmVkICh1cHBlcikgYm91bmRzICovCiAgICAgICAgcHVibGljIGludCBkZWNsYXJlZENvdW50OwoKICAgICAgICAvKiogaW5mZXJlbmNlIHZhcmlhYmxlJ3MgY2hhbmdlIGxpc3RlbmVyICovCiAgICAgICAgcHVibGljIFVuZGV0VmFyTGlzdGVuZXIgbGlzdGVuZXIgPSBudWxsOwoKICAgICAgICBLaW5kIGtpbmQ7CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyA8UixTPiBSIGFjY2VwdChUeXBlLlZpc2l0b3I8UixTPiB2LCBTIHMpIHsKICAgICAgICAgICAgcmV0dXJuIHYudmlzaXRVbmRldFZhcih0aGlzLCBzKTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBVbmRldFZhcihUeXBlVmFyIG9yaWdpbiwgVW5kZXRWYXJMaXN0ZW5lciBsaXN0ZW5lciwgVHlwZXMgdHlwZXMpIHsKICAgICAgICAgICAgLy8gVGhpcyBpcyBhIHN5bnRoZXNpemVkIGludGVybmFsIHR5cGUsIHNvIHdlIGNhbm5vdCBhbm5vdGF0ZSBpdC4KICAgICAgICAgICAgc3VwZXIoVU5ERVRWQVIsIG9yaWdpbik7CiAgICAgICAgICAgIHRoaXMua2luZCA9IG9yaWdpbi5pc0NhcHR1cmVkKCkgPwogICAgICAgICAgICAgICAgICAgIEtpbmQuQ0FQVFVSRUQgOgogICAgICAgICAgICAgICAgICAgIEtpbmQuTk9STUFMOwogICAgICAgICAgICB0aGlzLmxpc3RlbmVyID0gbGlzdGVuZXI7CiAgICAgICAgICAgIGJvdW5kcyA9IG5ldyBFbnVtTWFwPD4oSW5mZXJlbmNlQm91bmQuY2xhc3MpOwogICAgICAgICAgICBMaXN0PFR5cGU+IGRlY2xhcmVkQm91bmRzID0gdHlwZXMuZ2V0Qm91bmRzKG9yaWdpbik7CiAgICAgICAgICAgIGRlY2xhcmVkQ291bnQgPSBkZWNsYXJlZEJvdW5kcy5sZW5ndGgoKTsKICAgICAgICAgICAgYm91bmRzLnB1dChJbmZlcmVuY2VCb3VuZC5VUFBFUiwgTGlzdC5uaWwoKSk7CiAgICAgICAgICAgIGJvdW5kcy5wdXQoSW5mZXJlbmNlQm91bmQuTE9XRVIsIExpc3QubmlsKCkpOwogICAgICAgICAgICBib3VuZHMucHV0KEluZmVyZW5jZUJvdW5kLkVRLCBMaXN0Lm5pbCgpKTsKICAgICAgICAgICAgZm9yIChUeXBlIHQgOiBkZWNsYXJlZEJvdW5kcy5yZXZlcnNlKCkpIHsKICAgICAgICAgICAgICAgIC8vYWRkIGJvdW5kIHdvcmtzIGluIHJldmVyc2Ugb3JkZXIKICAgICAgICAgICAgICAgIGFkZEJvdW5kKEluZmVyZW5jZUJvdW5kLlVQUEVSLCB0LCB0eXBlcywgdHJ1ZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKG9yaWdpbi5pc0NhcHR1cmVkKCkgJiYgIW9yaWdpbi5sb3dlci5oYXNUYWcoQk9UKSkgewogICAgICAgICAgICAgICAgLy9hZGQgbG93ZXIgYm91bmQgaWYgbmVlZGVkCiAgICAgICAgICAgICAgICBhZGRCb3VuZChJbmZlcmVuY2VCb3VuZC5MT1dFUiwgb3JpZ2luLmxvd2VyLCB0eXBlcywgdHJ1ZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CiAgICAgICAgICAgIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigpOwogICAgICAgICAgICBhcHBlbmRBbm5vdGF0aW9uc1N0cmluZyhzYik7CiAgICAgICAgICAgIGlmIChpbnN0ID09IG51bGwpIHsKICAgICAgICAgICAgICAgIHNiLmFwcGVuZChxdHlwZSk7CiAgICAgICAgICAgICAgICBzYi5hcHBlbmQoJz8nKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHNiLmFwcGVuZChpbnN0KTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gc2IudG9TdHJpbmcoKTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBTdHJpbmcgZGVidWdTdHJpbmcoKSB7CiAgICAgICAgICAgIFN0cmluZyByZXN1bHQgPSAiaW5mZXJlbmNlIHZhciA9ICIgKyBxdHlwZSArICJcbiI7CiAgICAgICAgICAgIGlmIChpbnN0ICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIHJlc3VsdCArPSAiaW5zdCA9ICIgKyBpbnN0ICsgJ1xuJzsKICAgICAgICAgICAgfQogICAgICAgICAgICBmb3IgKEluZmVyZW5jZUJvdW5kIGJvdW5kOiBJbmZlcmVuY2VCb3VuZC52YWx1ZXMoKSkgewogICAgICAgICAgICAgICAgTGlzdDxUeXBlPiBhYm91bmRMaXN0ID0gYm91bmRzLmdldChib3VuZCk7CiAgICAgICAgICAgICAgICBpZiAoYWJvdW5kTGlzdC5zaXplKCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ICs9IGJvdW5kICsgIiA9ICIgKyBhYm91bmRMaXN0ICsgJ1xuJzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHZvaWQgc2V0VGhyb3coKSB7CiAgICAgICAgICAgIGlmICh0aGlzLmtpbmQgPT0gS2luZC5DQVBUVVJFRCkgewogICAgICAgICAgICAgICAgLy9pbnZhbGlkIHN0YXRlIHRyYW5zaXRpb24KICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oKTsKICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLmtpbmQgPSBLaW5kLlRIUk9XUzsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIFJldHVybnMgYSBuZXcgY29weSBvZiB0aGlzIHVuZGV0IHZhci4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgVW5kZXRWYXIgZHVwKFR5cGVzIHR5cGVzKSB7CiAgICAgICAgICAgIFVuZGV0VmFyIHV2MiA9IG5ldyBVbmRldFZhcigoVHlwZVZhcilxdHlwZSwgbGlzdGVuZXIsIHR5cGVzKTsKICAgICAgICAgICAgZHVwVG8odXYyLCB0eXBlcyk7CiAgICAgICAgICAgIHJldHVybiB1djI7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBEdW1wcyB0aGUgY29udGVudHMgb2YgdGhpcyB1bmRldCB2YXIgb24gYW5vdGhlciB1bmRldCB2YXIuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIHZvaWQgZHVwVG8oVW5kZXRWYXIgdXYyLCBUeXBlcyB0eXBlcykgewogICAgICAgICAgICB1djIubGlzdGVuZXIgPSBudWxsOwogICAgICAgICAgICB1djIuYm91bmRzLmNsZWFyKCk7CiAgICAgICAgICAgIGZvciAoSW5mZXJlbmNlQm91bmQgaWIgOiBJbmZlcmVuY2VCb3VuZC52YWx1ZXMoKSkgewogICAgICAgICAgICAgICAgdXYyLmJvdW5kcy5wdXQoaWIsIExpc3QubmlsKCkpOwogICAgICAgICAgICAgICAgZm9yIChUeXBlIHQgOiBnZXRCb3VuZHMoaWIpKSB7CiAgICAgICAgICAgICAgICAgICAgdXYyLmFkZEJvdW5kKGliLCB0LCB0eXBlcywgdHJ1ZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdXYyLmluc3QgPSBpbnN0OwogICAgICAgICAgICB1djIubGlzdGVuZXIgPSBsaXN0ZW5lcjsKICAgICAgICAgICAgdXYyLmluY29ycG9yYXRpb25BY3Rpb25zID0gbmV3IEFycmF5RGVxdWU8PigpOwogICAgICAgICAgICBmb3IgKEluY29ycG9yYXRpb25BY3Rpb24gYWN0aW9uIDogaW5jb3Jwb3JhdGlvbkFjdGlvbnMpIHsKICAgICAgICAgICAgICAgIHV2Mi5pbmNvcnBvcmF0aW9uQWN0aW9ucy5hZGQoYWN0aW9uLmR1cCh1djIpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFVuZGV0VmFyIGNsb25lV2l0aE1ldGFkYXRhKFR5cGVNZXRhZGF0YSBtZCkgewogICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoIkNhbm5vdCBhZGQgbWV0YWRhdGEgdG8gYW4gVW5kZXRWYXIgdHlwZSIpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gaXNQYXJ0aWFsKCkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBUeXBlIGJhc2VUeXBlKCkgewogICAgICAgICAgICByZXR1cm4gKGluc3QgPT0gbnVsbCkgPyB0aGlzIDogaW5zdC5iYXNlVHlwZSgpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIFR5cGUgZ2V0SW5zdCgpIHsKICAgICAgICAgICAgcmV0dXJuIGluc3Q7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgdm9pZCBzZXRJbnN0KFR5cGUgaW5zdCkgewogICAgICAgICAgICB0aGlzLmluc3QgPSBpbnN0OwogICAgICAgICAgICBpZiAobGlzdGVuZXIgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgbGlzdGVuZXIudmFySW5zdGFudGlhdGVkKHRoaXMpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvKiogZ2V0IGFsbCBib3VuZHMgb2YgYSBnaXZlbiBraW5kICovCiAgICAgICAgcHVibGljIExpc3Q8VHlwZT4gZ2V0Qm91bmRzKEluZmVyZW5jZUJvdW5kLi4uIGlicykgewogICAgICAgICAgICBMaXN0QnVmZmVyPFR5cGU+IGJ1ZiA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICAgICAgZm9yIChJbmZlcmVuY2VCb3VuZCBpYiA6IGlicykgewogICAgICAgICAgICAgICAgYnVmLmFwcGVuZExpc3QoYm91bmRzLmdldChpYikpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBidWYudG9MaXN0KCk7CiAgICAgICAgfQoKICAgICAgICAvKiogZ2V0IHRoZSBsaXN0IG9mIGRlY2xhcmVkICh1cHBlcikgYm91bmRzICovCiAgICAgICAgcHVibGljIExpc3Q8VHlwZT4gZ2V0RGVjbGFyZWRCb3VuZHMoKSB7CiAgICAgICAgICAgIExpc3RCdWZmZXI8VHlwZT4gYnVmID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgICAgICBpbnQgY291bnQgPSAwOwogICAgICAgICAgICBmb3IgKFR5cGUgYiA6IGdldEJvdW5kcyhJbmZlcmVuY2VCb3VuZC5VUFBFUikpIHsKICAgICAgICAgICAgICAgIGlmIChjb3VudCsrID09IGRlY2xhcmVkQ291bnQpIGJyZWFrOwogICAgICAgICAgICAgICAgYnVmLmFwcGVuZChiKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gYnVmLnRvTGlzdCgpOwogICAgICAgIH0KCiAgICAgICAgLyoqIGludGVybmFsIG1ldGhvZCB1c2VkIHRvIG92ZXJyaWRlIGFuIHVuZGV0dmFyIGJvdW5kcyAqLwogICAgICAgIHB1YmxpYyB2b2lkIHNldEJvdW5kcyhJbmZlcmVuY2VCb3VuZCBpYiwgTGlzdDxUeXBlPiBuZXdCb3VuZHMpIHsKICAgICAgICAgICAgYm91bmRzLnB1dChpYiwgbmV3Qm91bmRzKTsKICAgICAgICB9CgogICAgICAgIC8qKiBhZGQgYSBib3VuZCBvZiBhIGdpdmVuIGtpbmQgLSB0aGlzIG1pZ2h0IHRyaWdnZXIgbGlzdGVuZXIgbm90aWZpY2F0aW9uICovCiAgICAgICAgcHVibGljIGZpbmFsIHZvaWQgYWRkQm91bmQoSW5mZXJlbmNlQm91bmQgaWIsIFR5cGUgYm91bmQsIFR5cGVzIHR5cGVzKSB7CiAgICAgICAgICAgIC8vIFBlciBKREstODA3NTc5MzogaW4gcHJlLTggc291cmNlcywgZm9sbG93IGxlZ2FjeSBqYXZhYyBiZWhhdmlvcgogICAgICAgICAgICAvLyB3aGVuIGNhcHR1cmUgdmFyaWFibGVzIGFyZSBpbmZlcnJlZCBhcyBib3VuZHM6IGZvciBsb3dlciBib3VuZHMsCiAgICAgICAgICAgIC8vIG1hcCB0byB0aGUgY2FwdHVyZSB2YXJpYWJsZSdzIHVwcGVyIGJvdW5kOyBmb3IgdXBwZXIgYm91bmRzLAogICAgICAgICAgICAvLyBpZiB0aGUgY2FwdHVyZSB2YXJpYWJsZSBoYXMgYSBsb3dlciBib3VuZCwgbWFwIHRvIHRoYXQgdHlwZQogICAgICAgICAgICBpZiAodHlwZXMubWFwQ2FwdHVyZXNUb0JvdW5kcykgewogICAgICAgICAgICAgICAgc3dpdGNoIChpYikgewogICAgICAgICAgICAgICAgICAgIGNhc2UgTE9XRVI6CiAgICAgICAgICAgICAgICAgICAgICAgIGJvdW5kID0gdHlwZXMuY3ZhclVwcGVyQm91bmQoYm91bmQpOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICBjYXNlIFVQUEVSOgogICAgICAgICAgICAgICAgICAgICAgICBUeXBlIGFsdEJvdW5kID0gdHlwZXMuY3Zhckxvd2VyQm91bmQoYm91bmQpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWFsdEJvdW5kLmhhc1RhZyhUeXBlVGFnLkJPVCkpIGJvdW5kID0gYWx0Qm91bmQ7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGFkZEJvdW5kKGliLCBib3VuZCwgdHlwZXMsIGZhbHNlKTsKICAgICAgICB9CgogICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJmYWxsdGhyb3VnaCIpCiAgICAgICAgcHJpdmF0ZSB2b2lkIGFkZEJvdW5kKEluZmVyZW5jZUJvdW5kIGliLCBUeXBlIGJvdW5kLCBUeXBlcyB0eXBlcywgYm9vbGVhbiB1cGRhdGUpIHsKICAgICAgICAgICAgaWYgKGtpbmQgPT0gS2luZC5DQVBUVVJFRCAmJiAhdXBkYXRlKSB7CiAgICAgICAgICAgICAgICAvL0NhcHR1cmVkIGluZmVyZW5jZSB2YXJpYWJsZXMgYm91bmRzIG11c3Qgbm90IGJlIHVwZGF0ZWQgZHVyaW5nIGluY29ycG9yYXRpb24sCiAgICAgICAgICAgICAgICAvL2V4Y2VwdCB3aGVuIHNvbWUgaW5mZXJlbmNlIHZhcmlhYmxlIChiZXRhKSBoYXMgYmVlbiBpbnN0YW50aWF0ZWQgaW4gdGhlCiAgICAgICAgICAgICAgICAvL3JpZ2h0LWhhbmQtc2lkZSBvZiBhICdDPGFscGhhPiA9IGNhcHR1cmUoQzw/IGV4dGVuZHMvc3VwZXIgYmV0YT4pIGNvbnN0cmFpbnQuCiAgICAgICAgICAgICAgICBpZiAoYm91bmQuaGFzVGFnKFVOREVUVkFSKSAmJiAhKChVbmRldFZhcilib3VuZCkuaXNDYXB0dXJlZCgpKSB7CiAgICAgICAgICAgICAgICAgICAgLy9JZiB0aGUgbmV3IGluY29taW5nIGJvdW5kIGlzIGl0c2VsZiBhIChyZWd1bGFyKSBpbmZlcmVuY2UgdmFyaWFibGUsCiAgICAgICAgICAgICAgICAgICAgLy90aGVuIHdlIGFyZSBhbGxvd2VkIHRvIHByb3BhZ2F0ZSB0aGlzIGluZmVyZW5jZSB2YXJpYWJsZSBib3VuZHMgdG8gaXQuCiAgICAgICAgICAgICAgICAgICAgKChVbmRldFZhcilib3VuZCkuYWRkQm91bmQoaWIuY29tcGxlbWVudCgpLCB0aGlzLCB0eXBlcywgZmFsc2UpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgVHlwZSBib3VuZDIgPSBib3VuZC5tYXAodG9UeXBlVmFyTWFwKS5iYXNlVHlwZSgpOwogICAgICAgICAgICAgICAgTGlzdDxUeXBlPiBwcmV2Qm91bmRzID0gYm91bmRzLmdldChpYik7CiAgICAgICAgICAgICAgICBpZiAoYm91bmQgPT0gcXR5cGUpIHJldHVybjsKICAgICAgICAgICAgICAgIGZvciAoVHlwZSBiIDogcHJldkJvdW5kcykgewogICAgICAgICAgICAgICAgICAgIC8vY2hlY2sgZm9yIHJlZHVuZGFuY3kgLSB1c2Ugc3RyaWN0IHZlcnNpb24gb2YgaXNTYW1lVHlwZSBvbiB0dmFycwogICAgICAgICAgICAgICAgICAgIC8vKGFzIHRoZSBzdGFuZGFyZCB2ZXJzaW9uIHdpbGwgbGVhZCB0byBmYWxzZSBwb3NpdGl2ZXMgdy5yLnQuIGNsb25lcyBpdmFycykKICAgICAgICAgICAgICAgICAgICBpZiAodHlwZXMuaXNTYW1lVHlwZShiLCBib3VuZDIsIHRydWUpKSByZXR1cm47CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBib3VuZHMucHV0KGliLCBwcmV2Qm91bmRzLnByZXBlbmQoYm91bmQyKSk7CiAgICAgICAgICAgICAgICBub3RpZnlCb3VuZENoYW5nZShpYiwgYm91bmQyLCBmYWxzZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLy93aGVyZQogICAgICAgICAgICBUeXBlTWFwcGluZzxWb2lkPiB0b1R5cGVWYXJNYXAgPSBuZXcgU3RydWN0dXJhbFR5cGVNYXBwaW5nPFZvaWQ+KCkgewogICAgICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgICAgICBwdWJsaWMgVHlwZSB2aXNpdFVuZGV0VmFyKFVuZGV0VmFyIHV2LCBWb2lkIF91bnVzZWQpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdXYuaW5zdCAhPSBudWxsID8gdXYuaW5zdCA6IHV2LnF0eXBlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwoKICAgICAgICAvKiogcmVwbGFjZSB0eXBlcyBpbiBhbGwgYm91bmRzIC0gdGhpcyBtaWdodCB0cmlnZ2VyIGxpc3RlbmVyIG5vdGlmaWNhdGlvbiAqLwogICAgICAgIHB1YmxpYyB2b2lkIHN1YnN0Qm91bmRzKExpc3Q8VHlwZT4gZnJvbSwgTGlzdDxUeXBlPiB0bywgVHlwZXMgdHlwZXMpIHsKICAgICAgICAgICAgZmluYWwgTGlzdEJ1ZmZlcjxQYWlyPEluZmVyZW5jZUJvdW5kLCBUeXBlPj4gIGJvdW5kc0NoYW5nZWQgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgIFVuZGV0VmFyTGlzdGVuZXIgcHJldkxpc3RlbmVyID0gbGlzdGVuZXI7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAvL3NldHVwIG5ldyBsaXN0ZW5lciBmb3Iga2VlcGluZyB0cmFjayBvZiBjaGFuZ2VkIGJvdW5kcwogICAgICAgICAgICAgICAgbGlzdGVuZXIgPSAodXYsIGliLCB0LCBfaWdub3JlZCkgLT4gewogICAgICAgICAgICAgICAgICAgIEFzc2VydC5jaGVjayh1diA9PSBVbmRldFZhci50aGlzKTsKICAgICAgICAgICAgICAgICAgICBib3VuZHNDaGFuZ2VkLmFkZChuZXcgUGFpcjw+KGliLCB0KSk7CiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgZm9yIChNYXAuRW50cnk8SW5mZXJlbmNlQm91bmQsIExpc3Q8VHlwZT4+IF9lbnRyeSA6IGJvdW5kcy5lbnRyeVNldCgpKSB7CiAgICAgICAgICAgICAgICAgICAgSW5mZXJlbmNlQm91bmQgaWIgPSBfZW50cnkuZ2V0S2V5KCk7CiAgICAgICAgICAgICAgICAgICAgTGlzdDxUeXBlPiBwcmV2Qm91bmRzID0gX2VudHJ5LmdldFZhbHVlKCk7CiAgICAgICAgICAgICAgICAgICAgTGlzdEJ1ZmZlcjxUeXBlPiBuZXdCb3VuZHMgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgICAgICAgICAgTGlzdEJ1ZmZlcjxUeXBlPiBkZXBzID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgICAgICAgICAgICAgIC8vc3RlcCAxIC0gcmUtYWRkIGJvdW5kcyB0aGF0IGFyZSBub3QgZGVwZW5kZW50IG9uIGl2YXJzCiAgICAgICAgICAgICAgICAgICAgZm9yIChUeXBlIHQgOiBwcmV2Qm91bmRzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghdC5jb250YWluc0FueShmcm9tKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3Qm91bmRzLmFwcGVuZCh0KTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlcHMuYXBwZW5kKHQpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIC8vc3RlcCAyIC0gcmVwbGFjZSBib3VuZHMKICAgICAgICAgICAgICAgICAgICBib3VuZHMucHV0KGliLCBuZXdCb3VuZHMudG9MaXN0KCkpOwogICAgICAgICAgICAgICAgICAgIC8vc3RlcCAzIC0gZm9yIGVhY2ggZGVwZW5kZW5jeSwgYWRkIG5ldyByZXBsYWNlZCBib3VuZAogICAgICAgICAgICAgICAgICAgIGZvciAoVHlwZSBkZXAgOiBkZXBzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGFkZEJvdW5kKGliLCB0eXBlcy5zdWJzdChkZXAsIGZyb20sIHRvKSwgdHlwZXMsIHRydWUpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgICAgIGxpc3RlbmVyID0gcHJldkxpc3RlbmVyOwogICAgICAgICAgICAgICAgZm9yIChQYWlyPEluZmVyZW5jZUJvdW5kLCBUeXBlPiBib3VuZFVwZGF0ZSA6IGJvdW5kc0NoYW5nZWQpIHsKICAgICAgICAgICAgICAgICAgICBub3RpZnlCb3VuZENoYW5nZShib3VuZFVwZGF0ZS5mc3QsIGJvdW5kVXBkYXRlLnNuZCwgdHJ1ZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHByaXZhdGUgdm9pZCBub3RpZnlCb3VuZENoYW5nZShJbmZlcmVuY2VCb3VuZCBpYiwgVHlwZSBib3VuZCwgYm9vbGVhbiB1cGRhdGUpIHsKICAgICAgICAgICAgaWYgKGxpc3RlbmVyICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIGxpc3RlbmVyLnZhckJvdW5kQ2hhbmdlZCh0aGlzLCBpYiwgYm91bmQsIHVwZGF0ZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzQ2FwdHVyZWQoKSB7CiAgICAgICAgICAgIHJldHVybiBraW5kID09IEtpbmQuQ0FQVFVSRUQ7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc1Rocm93cygpIHsKICAgICAgICAgICAgcmV0dXJuIGtpbmQgPT0gS2luZC5USFJPV1M7CiAgICAgICAgfQogICAgfQoKICAgIC8qKiBSZXByZXNlbnRzIE5PTkUuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgSkNOb1R5cGUgZXh0ZW5kcyBUeXBlIGltcGxlbWVudHMgTm9UeXBlIHsKICAgICAgICBwdWJsaWMgSkNOb1R5cGUoKSB7CiAgICAgICAgICAgIC8vIE5lZWQgdG8gdXNlIExpc3QubmlsKCksIGJlY2F1c2UgSkNOb1R5cGUgY29uc3RydWN0b3IKICAgICAgICAgICAgLy8gZ2V0cyBjYWxsZWQgaW4gc3RhdGljIGluaXRpYWxpemVycyBpbiBUeXBlLCB3aGVyZQogICAgICAgICAgICAvLyBub0Fubm90YXRpb25zIGlzIGFsc28gZGVmaW5lZC4KICAgICAgICAgICAgc3VwZXIobnVsbCwgVHlwZU1ldGFkYXRhLkVNUFRZKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBKQ05vVHlwZSBjbG9uZVdpdGhNZXRhZGF0YShUeXBlTWV0YWRhdGEgbWQpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCJDYW5ub3QgYWRkIG1ldGFkYXRhIHRvIGEgSkNOb1R5cGUiKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBUeXBlVGFnIGdldFRhZygpIHsKICAgICAgICAgICAgcmV0dXJuIE5PTkU7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICAgICAgcHVibGljIFR5cGVLaW5kIGdldEtpbmQoKSB7CiAgICAgICAgICAgIHJldHVybiBUeXBlS2luZC5OT05FOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyA8UiwgUD4gUiBhY2NlcHQoVHlwZVZpc2l0b3I8UiwgUD4gdiwgUCBwKSB7CiAgICAgICAgICAgIHJldHVybiB2LnZpc2l0Tm9UeXBlKHRoaXMsIHApOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gaXNDb21wb3VuZCgpIHsgcmV0dXJuIGZhbHNlOyB9CiAgICB9CgogICAgLyoqIFJlcHJlc2VudHMgVk9JRC4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBjbGFzcyBKQ1ZvaWRUeXBlIGV4dGVuZHMgVHlwZSBpbXBsZW1lbnRzIE5vVHlwZSB7CgogICAgICAgIHB1YmxpYyBKQ1ZvaWRUeXBlKCkgewogICAgICAgICAgICAvLyBWb2lkIGNhbm5vdCBiZSBhbm5vdGF0ZWQKICAgICAgICAgICAgc3VwZXIobnVsbCwgVHlwZU1ldGFkYXRhLkVNUFRZKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBKQ1ZvaWRUeXBlIGNsb25lV2l0aE1ldGFkYXRhKFR5cGVNZXRhZGF0YSBtZCkgewogICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoIkNhbm5vdCBhZGQgbWV0YWRhdGEgdG8gYSB2b2lkIHR5cGUiKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBUeXBlVGFnIGdldFRhZygpIHsKICAgICAgICAgICAgcmV0dXJuIFZPSUQ7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICAgICAgcHVibGljIFR5cGVLaW5kIGdldEtpbmQoKSB7CiAgICAgICAgICAgIHJldHVybiBUeXBlS2luZC5WT0lEOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gaXNDb21wb3VuZCgpIHsgcmV0dXJuIGZhbHNlOyB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgICAgICBwdWJsaWMgPFIsIFA+IFIgYWNjZXB0KFR5cGVWaXNpdG9yPFIsIFA+IHYsIFAgcCkgewogICAgICAgICAgICByZXR1cm4gdi52aXNpdE5vVHlwZSh0aGlzLCBwKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBib29sZWFuIGlzUHJpbWl0aXZlT3JWb2lkKCkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICB9CgogICAgc3RhdGljIGNsYXNzIEJvdHRvbVR5cGUgZXh0ZW5kcyBUeXBlIGltcGxlbWVudHMgTnVsbFR5cGUgewogICAgICAgIHB1YmxpYyBCb3R0b21UeXBlKCkgewogICAgICAgICAgICAvLyBCb3R0b20gaXMgYSBzeW50aGVzaXplZCBpbnRlcm5hbCB0eXBlLCBzbyBpdCBjYW5ub3QgYmUgYW5ub3RhdGVkCiAgICAgICAgICAgIHN1cGVyKG51bGwsIFR5cGVNZXRhZGF0YS5FTVBUWSk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQm90dG9tVHlwZSBjbG9uZVdpdGhNZXRhZGF0YShUeXBlTWV0YWRhdGEgbWQpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCJDYW5ub3QgYWRkIG1ldGFkYXRhIHRvIGEgYm90dG9tIHR5cGUiKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBUeXBlVGFnIGdldFRhZygpIHsKICAgICAgICAgICAgcmV0dXJuIEJPVDsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgICAgICBwdWJsaWMgVHlwZUtpbmQgZ2V0S2luZCgpIHsKICAgICAgICAgICAgcmV0dXJuIFR5cGVLaW5kLk5VTEw7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc0NvbXBvdW5kKCkgeyByZXR1cm4gZmFsc2U7IH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyA8UiwgUD4gUiBhY2NlcHQoVHlwZVZpc2l0b3I8UiwgUD4gdiwgUCBwKSB7CiAgICAgICAgICAgIHJldHVybiB2LnZpc2l0TnVsbCh0aGlzLCBwKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBUeXBlIGNvbnN0VHlwZShPYmplY3QgdmFsdWUpIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgU3RyaW5nIHN0cmluZ1ZhbHVlKCkgewogICAgICAgICAgICByZXR1cm4gIm51bGwiOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gaXNOdWxsT3JSZWZlcmVuY2UoKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjbGFzcyBFcnJvclR5cGUgZXh0ZW5kcyBDbGFzc1R5cGUKICAgICAgICAgICAgaW1wbGVtZW50cyBqYXZheC5sYW5nLm1vZGVsLnR5cGUuRXJyb3JUeXBlIHsKCiAgICAgICAgcHJpdmF0ZSBUeXBlIG9yaWdpbmFsVHlwZSA9IG51bGw7CgogICAgICAgIHB1YmxpYyBFcnJvclR5cGUoQ2xhc3NTeW1ib2wgYywgVHlwZSBvcmlnaW5hbFR5cGUpIHsKICAgICAgICAgICAgdGhpcyhvcmlnaW5hbFR5cGUsIGMpOwogICAgICAgICAgICBjLnR5cGUgPSB0aGlzOwogICAgICAgICAgICBjLmtpbmQgPSBFUlI7CiAgICAgICAgICAgIGMubWVtYmVyc19maWVsZCA9IG5ldyBTY29wZS5FcnJvclNjb3BlKGMpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIEVycm9yVHlwZShUeXBlIG9yaWdpbmFsVHlwZSwgVHlwZVN5bWJvbCB0c3ltKSB7CiAgICAgICAgICAgIHN1cGVyKG5vVHlwZSwgTGlzdC5uaWwoKSwgbnVsbCk7CiAgICAgICAgICAgIHRoaXMudHN5bSA9IHRzeW07CiAgICAgICAgICAgIHRoaXMub3JpZ2luYWxUeXBlID0gKG9yaWdpbmFsVHlwZSA9PSBudWxsID8gbm9UeXBlIDogb3JpZ2luYWxUeXBlKTsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgRXJyb3JUeXBlKFR5cGUgb3JpZ2luYWxUeXBlLCBUeXBlU3ltYm9sIHRzeW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgVHlwZU1ldGFkYXRhIG1ldGFkYXRhKSB7CiAgICAgICAgICAgIHN1cGVyKG5vVHlwZSwgTGlzdC5uaWwoKSwgbnVsbCwgbWV0YWRhdGEpOwogICAgICAgICAgICB0aGlzLnRzeW0gPSB0c3ltOwogICAgICAgICAgICB0aGlzLm9yaWdpbmFsVHlwZSA9IChvcmlnaW5hbFR5cGUgPT0gbnVsbCA/IG5vVHlwZSA6IG9yaWdpbmFsVHlwZSk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgRXJyb3JUeXBlIGNsb25lV2l0aE1ldGFkYXRhKFR5cGVNZXRhZGF0YSBtZCkgewogICAgICAgICAgICByZXR1cm4gbmV3IEVycm9yVHlwZShvcmlnaW5hbFR5cGUsIHRzeW0sIG1kKSB7CiAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgICAgIHB1YmxpYyBUeXBlIGJhc2VUeXBlKCkgeyByZXR1cm4gRXJyb3JUeXBlLnRoaXMuYmFzZVR5cGUoKTsgfQogICAgICAgICAgICB9OwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFR5cGVUYWcgZ2V0VGFnKCkgewogICAgICAgICAgICByZXR1cm4gRVJST1I7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc1BhcnRpYWwoKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gaXNSZWZlcmVuY2UoKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gaXNOdWxsT3JSZWZlcmVuY2UoKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIEVycm9yVHlwZShOYW1lIG5hbWUsIFR5cGVTeW1ib2wgY29udGFpbmVyLCBUeXBlIG9yaWdpbmFsVHlwZSkgewogICAgICAgICAgICB0aGlzKG5ldyBDbGFzc1N5bWJvbChQVUJMSUN8U1RBVElDfEFDWUNMSUMsIG5hbWUsIG51bGwsIGNvbnRhaW5lciksIG9yaWdpbmFsVHlwZSk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgPFIsUz4gUiBhY2NlcHQoVHlwZS5WaXNpdG9yPFIsUz4gdiwgUyBzKSB7CiAgICAgICAgICAgIHJldHVybiB2LnZpc2l0RXJyb3JUeXBlKHRoaXMsIHMpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIFR5cGUgY29uc3RUeXBlKE9iamVjdCBjb25zdFZhbHVlKSB7IHJldHVybiB0aGlzOyB9CiAgICAgICAgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICAgICAgcHVibGljIFR5cGUgZ2V0RW5jbG9zaW5nVHlwZSgpICAgICAgICAgICB7IHJldHVybiB0aGlzOyB9CiAgICAgICAgcHVibGljIFR5cGUgZ2V0UmV0dXJuVHlwZSgpICAgICAgICAgICAgICB7IHJldHVybiB0aGlzOyB9CiAgICAgICAgcHVibGljIFR5cGUgYXNTdWIoU3ltYm9sIHN5bSkgICAgICAgICAgICB7IHJldHVybiB0aGlzOyB9CgogICAgICAgIHB1YmxpYyBib29sZWFuIGlzR2VuVHlwZShUeXBlIHQpICAgICAgICAgeyByZXR1cm4gdHJ1ZTsgfQogICAgICAgIHB1YmxpYyBib29sZWFuIGlzRXJyb25lb3VzKCkgICAgICAgICAgICAgeyByZXR1cm4gdHJ1ZTsgfQogICAgICAgIHB1YmxpYyBib29sZWFuIGlzQ29tcG91bmQoKSAgICAgICAgICAgICAgeyByZXR1cm4gZmFsc2U7IH0KICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc0ludGVyZmFjZSgpICAgICAgICAgICAgIHsgcmV0dXJuIGZhbHNlOyB9CgogICAgICAgIHB1YmxpYyBMaXN0PFR5cGU+IGFsbHBhcmFtcygpICAgICAgICAgICAgeyByZXR1cm4gTGlzdC5uaWwoKTsgfQogICAgICAgIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyBMaXN0PFR5cGU+IGdldFR5cGVBcmd1bWVudHMoKSAgICAgeyByZXR1cm4gTGlzdC5uaWwoKTsgfQoKICAgICAgICBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgICAgICBwdWJsaWMgVHlwZUtpbmQgZ2V0S2luZCgpIHsKICAgICAgICAgICAgcmV0dXJuIFR5cGVLaW5kLkVSUk9SOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIFR5cGUgZ2V0T3JpZ2luYWxUeXBlKCkgewogICAgICAgICAgICByZXR1cm4gb3JpZ2luYWxUeXBlOwogICAgICAgIH0KCiAgICAgICAgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICAgICAgcHVibGljIDxSLCBQPiBSIGFjY2VwdChUeXBlVmlzaXRvcjxSLCBQPiB2LCBQIHApIHsKICAgICAgICAgICAgcmV0dXJuIHYudmlzaXRFcnJvcih0aGlzLCBwKTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjbGFzcyBVbmtub3duVHlwZSBleHRlbmRzIFR5cGUgewoKICAgICAgICBwdWJsaWMgVW5rbm93blR5cGUoKSB7CiAgICAgICAgICAgIC8vIFVua25vd24gaXMgYSBzeW50aGVzaXplZCBpbnRlcm5hbCB0eXBlLCBzbyBpdCBjYW5ub3QgYmUKICAgICAgICAgICAgLy8gYW5ub3RhdGVkLgogICAgICAgICAgICBzdXBlcihudWxsLCBUeXBlTWV0YWRhdGEuRU1QVFkpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFVua25vd25UeXBlIGNsb25lV2l0aE1ldGFkYXRhKFR5cGVNZXRhZGF0YSBtZCkgewogICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoIkNhbm5vdCBhZGQgbWV0YWRhdGEgdG8gYW4gdW5rbm93biB0eXBlIik7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgVHlwZVRhZyBnZXRUYWcoKSB7CiAgICAgICAgICAgIHJldHVybiBVTktOT1dOOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyA8UiwgUD4gUiBhY2NlcHQoVHlwZVZpc2l0b3I8UiwgUD4gdiwgUCBwKSB7CiAgICAgICAgICAgIHJldHVybiB2LnZpc2l0VW5rbm93bih0aGlzLCBwKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBib29sZWFuIGlzUGFydGlhbCgpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQSB2aXNpdG9yIGZvciB0eXBlcy4gIEEgdmlzaXRvciBpcyB1c2VkIHRvIGltcGxlbWVudCBvcGVyYXRpb25zCiAgICAgKiAob3IgcmVsYXRpb25zKSBvbiB0eXBlcy4gIE1vc3QgY29tbW9uIG9wZXJhdGlvbnMgb24gdHlwZXMgYXJlCiAgICAgKiBiaW5hcnkgcmVsYXRpb25zIGFuZCB0aGlzIGludGVyZmFjZSBpcyBkZXNpZ25lZCBmb3IgYmluYXJ5CiAgICAgKiByZWxhdGlvbnMsIHRoYXQgaXMsIG9wZXJhdGlvbnMgb2YgdGhlIGZvcm0KICAgICAqIFR5cGUmbmJzcDsmdGltZXM7Jm5ic3A7UyZuYnNwOyZyYXJyOyZuYnNwO1IuCiAgICAgKiA8IS0tIEluIHBsYWluIHRleHQ6IFR5cGUgeCBTIC0+IFIgLS0+CiAgICAgKgogICAgICogQHBhcmFtIDxSPiB0aGUgcmV0dXJuIHR5cGUgb2YgdGhlIG9wZXJhdGlvbiBpbXBsZW1lbnRlZCBieSB0aGlzCiAgICAgKiB2aXNpdG9yOyB1c2UgVm9pZCBpZiBubyByZXR1cm4gdHlwZSBpcyBuZWVkZWQuCiAgICAgKiBAcGFyYW0gPFM+IHRoZSB0eXBlIG9mIHRoZSBzZWNvbmQgYXJndW1lbnQgKHRoZSBmaXJzdCBiZWluZyB0aGUKICAgICAqIHR5cGUgaXRzZWxmKSBvZiB0aGUgb3BlcmF0aW9uIGltcGxlbWVudGVkIGJ5IHRoaXMgdmlzaXRvcjsgdXNlCiAgICAgKiBWb2lkIGlmIGEgc2Vjb25kIGFyZ3VtZW50IGlzIG5vdCBuZWVkZWQuCiAgICAgKi8KICAgIHB1YmxpYyBpbnRlcmZhY2UgVmlzaXRvcjxSLFM+IHsKICAgICAgICBSIHZpc2l0Q2xhc3NUeXBlKENsYXNzVHlwZSB0LCBTIHMpOwogICAgICAgIFIgdmlzaXRXaWxkY2FyZFR5cGUoV2lsZGNhcmRUeXBlIHQsIFMgcyk7CiAgICAgICAgUiB2aXNpdEFycmF5VHlwZShBcnJheVR5cGUgdCwgUyBzKTsKICAgICAgICBSIHZpc2l0TWV0aG9kVHlwZShNZXRob2RUeXBlIHQsIFMgcyk7CiAgICAgICAgUiB2aXNpdFBhY2thZ2VUeXBlKFBhY2thZ2VUeXBlIHQsIFMgcyk7CiAgICAgICAgUiB2aXNpdE1vZHVsZVR5cGUoTW9kdWxlVHlwZSB0LCBTIHMpOwogICAgICAgIFIgdmlzaXRUeXBlVmFyKFR5cGVWYXIgdCwgUyBzKTsKICAgICAgICBSIHZpc2l0Q2FwdHVyZWRUeXBlKENhcHR1cmVkVHlwZSB0LCBTIHMpOwogICAgICAgIFIgdmlzaXRGb3JBbGwoRm9yQWxsIHQsIFMgcyk7CiAgICAgICAgUiB2aXNpdFVuZGV0VmFyKFVuZGV0VmFyIHQsIFMgcyk7CiAgICAgICAgUiB2aXNpdEVycm9yVHlwZShFcnJvclR5cGUgdCwgUyBzKTsKICAgICAgICBSIHZpc2l0VHlwZShUeXBlIHQsIFMgcyk7CiAgICB9Cn0KUEsDBAoAAAgAAAY7qUoV9fGJFR4AABUeAAAlAAAAY29tL3N1bi90b29scy9qYXZhYy9jb2RlL1R5cGVUYWcuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMTk5OSwgMjAxNCwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGU7CgppbXBvcnQgY29tLnN1bi5zb3VyY2UudHJlZS5UcmVlLktpbmQ7CgppbXBvcnQgamF2YXgubGFuZy5tb2RlbC50eXBlLlR5cGVLaW5kOwoKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuVHlwZVRhZy5OdW1lcmljQ2xhc3Nlcy4qOwoKLyoqIEFuIGludGVyZmFjZSBmb3IgdHlwZSB0YWcgdmFsdWVzLCB3aGljaCBkaXN0aW5ndWlzaCBiZXR3ZWVuIGRpZmZlcmVudAogKiAgc29ydHMgb2YgdHlwZXMuCiAqCiAqICA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiAgSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93biByaXNrLgogKiAgVGhpcyBjb2RlIGFuZCBpdHMgaW50ZXJuYWwgaW50ZXJmYWNlcyBhcmUgc3ViamVjdCB0byBjaGFuZ2Ugb3IKICogIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj4KICovCnB1YmxpYyBlbnVtIFR5cGVUYWcgewogICAgLyoqIFRoZSB0YWcgb2YgdGhlIGJhc2ljIHR5cGUgYGJ5dGUnLgogICAgICovCiAgICBCWVRFKEJZVEVfQ0xBU1MsIEJZVEVfU1VQRVJDTEFTU0VTLCB0cnVlKSwKCiAgICAvKiogVGhlIHRhZyBvZiB0aGUgYmFzaWMgdHlwZSBgY2hhcicuCiAgICAgKi8KICAgIENIQVIoQ0hBUl9DTEFTUywgQ0hBUl9TVVBFUkNMQVNTRVMsIHRydWUpLAoKICAgIC8qKiBUaGUgdGFnIG9mIHRoZSBiYXNpYyB0eXBlIGBzaG9ydCcuCiAgICAgKi8KICAgIFNIT1JUKFNIT1JUX0NMQVNTLCBTSE9SVF9TVVBFUkNMQVNTRVMsIHRydWUpLAoKICAgIC8qKiBUaGUgdGFnIG9mIHRoZSBiYXNpYyB0eXBlIGBsb25nJy4KICAgICAqLwogICAgTE9ORyhMT05HX0NMQVNTLCBMT05HX1NVUEVSQ0xBU1NFUywgdHJ1ZSksCgogICAgLyoqIFRoZSB0YWcgb2YgdGhlIGJhc2ljIHR5cGUgYGZsb2F0Jy4KICAgICAqLwogICAgRkxPQVQoRkxPQVRfQ0xBU1MsIEZMT0FUX1NVUEVSQ0xBU1NFUywgdHJ1ZSksCiAgICAvKiogVGhlIHRhZyBvZiB0aGUgYmFzaWMgdHlwZSBgaW50Jy4KICAgICAqLwogICAgSU5UKElOVF9DTEFTUywgSU5UX1NVUEVSQ0xBU1NFUywgdHJ1ZSksCiAgICAvKiogVGhlIHRhZyBvZiB0aGUgYmFzaWMgdHlwZSBgZG91YmxlJy4KICAgICAqLwogICAgRE9VQkxFKERPVUJMRV9DTEFTUywgRE9VQkxFX0NMQVNTLCB0cnVlKSwKICAgIC8qKiBUaGUgdGFnIG9mIHRoZSBiYXNpYyB0eXBlIGBib29sZWFuJy4KICAgICAqLwogICAgQk9PTEVBTigwLCAwLCB0cnVlKSwKCiAgICAvKiogVGhlIHRhZyBvZiB0aGUgdHlwZSBgdm9pZCcuCiAgICAgKi8KICAgIFZPSUQsCgogICAgLyoqIFRoZSB0YWcgb2YgYWxsIGNsYXNzIGFuZCBpbnRlcmZhY2UgdHlwZXMuCiAgICAgKi8KICAgIENMQVNTLAoKICAgIC8qKiBUaGUgdGFnIG9mIGFsbCBhcnJheSB0eXBlcy4KICAgICAqLwogICAgQVJSQVksCgogICAgLyoqIFRoZSB0YWcgb2YgYWxsIChtb25vbW9ycGhpYykgbWV0aG9kIHR5cGVzLgogICAgICovCiAgICBNRVRIT0QsCgogICAgLyoqIFRoZSB0YWcgb2YgYWxsIHBhY2thZ2UgInR5cGVzIi4KICAgICAqLwogICAgUEFDS0FHRSwKCiAgICAvKiogVGhlIHRhZyBvZiBhbGwgbW9kdWxlICJ0eXBlcyIuCiAgICAgKi8KICAgIE1PRFVMRSwKCiAgICAvKiogVGhlIHRhZyBvZiBhbGwgKHNvdXJjZS1sZXZlbCkgdHlwZSB2YXJpYWJsZXMuCiAgICAgKi8KICAgIFRZUEVWQVIsCgogICAgLyoqIFRoZSB0YWcgb2YgYWxsIHR5cGUgYXJndW1lbnRzLgogICAgICovCiAgICBXSUxEQ0FSRCwKCiAgICAvKiogVGhlIHRhZyBvZiBhbGwgcG9seW1vcnBoaWMgKG1ldGhvZC0pIHR5cGVzLgogICAgICovCiAgICBGT1JBTEwsCgogICAgLyoqIFRoZSB0YWcgb2YgZGVmZXJyZWQgZXhwcmVzc2lvbiB0eXBlcyBpbiBtZXRob2QgY29udGV4dAogICAgICovCiAgICBERUZFUlJFRCwKCiAgICAvKiogVGhlIHRhZyBvZiB0aGUgYm90dG9tIHR5cGUge0Bjb2RlIDxudWxsPn0uCiAgICAgKi8KICAgIEJPVCwKCiAgICAvKiogVGhlIHRhZyBvZiBhIG1pc3NpbmcgdHlwZS4KICAgICAqLwogICAgTk9ORSwKCiAgICAvKiogVGhlIHRhZyBvZiB0aGUgZXJyb3IgdHlwZS4KICAgICAqLwogICAgRVJST1IsCgogICAgLyoqIFRoZSB0YWcgb2YgYW4gdW5rbm93biB0eXBlCiAgICAgKi8KICAgIFVOS05PV04sCgogICAgLyoqIFRoZSB0YWcgb2YgYWxsIGluc3RhbnRpYXRhYmxlIHR5cGUgdmFyaWFibGVzLgogICAgICovCiAgICBVTkRFVFZBUiwKCiAgICAvKiogUHNldWRvLXR5cGVzLCB0aGVzZSBhcmUgc3BlY2lhbCB0YWdzCiAgICAgKi8KICAgIFVOSU5JVElBTElaRURfVEhJUywKCiAgICBVTklOSVRJQUxJWkVEX09CSkVDVDsKCiAgICBmaW5hbCBpbnQgc3VwZXJDbGFzc2VzOwogICAgZmluYWwgaW50IG51bWVyaWNDbGFzczsKICAgIGZpbmFsIGJvb2xlYW4gaXNQcmltaXRpdmU7CgogICAgcHJpdmF0ZSBUeXBlVGFnKCkgewogICAgICAgIHRoaXMoMCwgMCwgZmFsc2UpOwogICAgfQoKICAgIHByaXZhdGUgVHlwZVRhZyhpbnQgbnVtZXJpY0NsYXNzLCBpbnQgc3VwZXJDbGFzc2VzLCBib29sZWFuIGlzUHJpbWl0aXZlKSB7CiAgICAgICAgdGhpcy5zdXBlckNsYXNzZXMgPSBzdXBlckNsYXNzZXM7CiAgICAgICAgdGhpcy5udW1lcmljQ2xhc3MgPSBudW1lcmljQ2xhc3M7CiAgICAgICAgdGhpcy5pc1ByaW1pdGl2ZSA9IGlzUHJpbWl0aXZlOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgTnVtZXJpY0NsYXNzZXMgewogICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJZVEVfQ0xBU1MgPSAxOwogICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENIQVJfQ0xBU1MgPSAyOwogICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNIT1JUX0NMQVNTID0gNDsKICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJTlRfQ0xBU1MgPSA4OwogICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfQ0xBU1MgPSAxNjsKICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGTE9BVF9DTEFTUyA9IDMyOwogICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERPVUJMRV9DTEFTUyA9IDY0OwoKICAgICAgICBzdGF0aWMgZmluYWwgaW50IEJZVEVfU1VQRVJDTEFTU0VTID0gQllURV9DTEFTUyB8IFNIT1JUX0NMQVNTIHwgSU5UX0NMQVNTIHwKICAgICAgICAgICAgICAgIExPTkdfQ0xBU1MgfCBGTE9BVF9DTEFTUyB8IERPVUJMRV9DTEFTUzsKCiAgICAgICAgc3RhdGljIGZpbmFsIGludCBDSEFSX1NVUEVSQ0xBU1NFUyA9IENIQVJfQ0xBU1MgfCBJTlRfQ0xBU1MgfAogICAgICAgICAgICAgICAgTE9OR19DTEFTUyB8IEZMT0FUX0NMQVNTIHwgRE9VQkxFX0NMQVNTOwoKICAgICAgICBzdGF0aWMgZmluYWwgaW50IFNIT1JUX1NVUEVSQ0xBU1NFUyA9IFNIT1JUX0NMQVNTIHwgSU5UX0NMQVNTIHwKICAgICAgICAgICAgICAgIExPTkdfQ0xBU1MgfCBGTE9BVF9DTEFTUyB8IERPVUJMRV9DTEFTUzsKCiAgICAgICAgc3RhdGljIGZpbmFsIGludCBJTlRfU1VQRVJDTEFTU0VTID0gSU5UX0NMQVNTIHwgTE9OR19DTEFTUyB8IEZMT0FUX0NMQVNTIHwgRE9VQkxFX0NMQVNTOwoKICAgICAgICBzdGF0aWMgZmluYWwgaW50IExPTkdfU1VQRVJDTEFTU0VTID0gTE9OR19DTEFTUyB8IEZMT0FUX0NMQVNTIHwgRE9VQkxFX0NMQVNTOwoKICAgICAgICBzdGF0aWMgZmluYWwgaW50IEZMT0FUX1NVUEVSQ0xBU1NFUyA9IEZMT0FUX0NMQVNTIHwgRE9VQkxFX0NMQVNTOwogICAgfQoKICAgIHB1YmxpYyBib29sZWFuIGlzU3RyaWN0U3ViUmFuZ2VPZihUeXBlVGFnIHRhZykgewogICAgICAgIC8qICBQbGVhc2UgZG9uJ3QgY2hhbmdlIHRoZSBpbXBsZW1lbnRhdGlvbiBvZiB0aGlzIG1ldGhvZCB0byBjYWxsIG1ldGhvZAogICAgICAgICAqICBpc1N1YlJhbmdlT2YuIEJvdGggbWV0aG9kcyBhcmUgY2FsbGVkIGZyb20gaG90c3BvdCBjb2RlLCB0aGUgY3VycmVudAogICAgICAgICAqICBpbXBsZW1lbnRhdGlvbiBpcyBiZXR0ZXIgcGVyZm9ybWFuY2Utd2lzZSB0aGFuIHRoZSBjb21tZW50ZWQgbW9kaWZpY2F0aW9uLgogICAgICAgICAqLwogICAgICAgIHJldHVybiAodGhpcy5zdXBlckNsYXNzZXMgJiB0YWcubnVtZXJpY0NsYXNzKSAhPSAwICYmIHRoaXMgIT0gdGFnOwogICAgfQoKICAgIHB1YmxpYyBib29sZWFuIGlzU3ViUmFuZ2VPZihUeXBlVGFnIHRhZykgewogICAgICAgIHJldHVybiAodGhpcy5zdXBlckNsYXNzZXMgJiB0YWcubnVtZXJpY0NsYXNzKSAhPSAwOwogICAgfQoKICAgIC8qKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgdHlwZSB0YWdzLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGludCBnZXRUeXBlVGFnQ291bnQoKSB7CiAgICAgICAgLy8gbGFzdCB0d28gdGFncyBhcmUgbm90IGluY2x1ZGVkIGluIHRoZSB0b3RhbCBhcyBsb25nIGFzIHRoZXkgYXJlIHBzZXVkby10eXBlcwogICAgICAgIHJldHVybiAoVU5ERVRWQVIub3JkaW5hbCgpICsgMSk7CiAgICB9CgogICAgcHVibGljIEtpbmQgZ2V0S2luZExpdGVyYWwoKSB7CiAgICAgICAgc3dpdGNoICh0aGlzKSB7CiAgICAgICAgY2FzZSBJTlQ6CiAgICAgICAgICAgIHJldHVybiBLaW5kLklOVF9MSVRFUkFMOwogICAgICAgIGNhc2UgTE9ORzoKICAgICAgICAgICAgcmV0dXJuIEtpbmQuTE9OR19MSVRFUkFMOwogICAgICAgIGNhc2UgRkxPQVQ6CiAgICAgICAgICAgIHJldHVybiBLaW5kLkZMT0FUX0xJVEVSQUw7CiAgICAgICAgY2FzZSBET1VCTEU6CiAgICAgICAgICAgIHJldHVybiBLaW5kLkRPVUJMRV9MSVRFUkFMOwogICAgICAgIGNhc2UgQk9PTEVBTjoKICAgICAgICAgICAgcmV0dXJuIEtpbmQuQk9PTEVBTl9MSVRFUkFMOwogICAgICAgIGNhc2UgQ0hBUjoKICAgICAgICAgICAgcmV0dXJuIEtpbmQuQ0hBUl9MSVRFUkFMOwogICAgICAgIGNhc2UgQ0xBU1M6CiAgICAgICAgICAgIHJldHVybiBLaW5kLlNUUklOR19MSVRFUkFMOwogICAgICAgIGNhc2UgQk9UOgogICAgICAgICAgICByZXR1cm4gS2luZC5OVUxMX0xJVEVSQUw7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCJ1bmtub3duIGxpdGVyYWwga2luZCAiICsgdGhpcyk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBUeXBlS2luZCBnZXRQcmltaXRpdmVUeXBlS2luZCgpIHsKICAgICAgICBzd2l0Y2ggKHRoaXMpIHsKICAgICAgICBjYXNlIEJPT0xFQU46CiAgICAgICAgICAgIHJldHVybiBUeXBlS2luZC5CT09MRUFOOwogICAgICAgIGNhc2UgQllURToKICAgICAgICAgICAgcmV0dXJuIFR5cGVLaW5kLkJZVEU7CiAgICAgICAgY2FzZSBTSE9SVDoKICAgICAgICAgICAgcmV0dXJuIFR5cGVLaW5kLlNIT1JUOwogICAgICAgIGNhc2UgSU5UOgogICAgICAgICAgICByZXR1cm4gVHlwZUtpbmQuSU5UOwogICAgICAgIGNhc2UgTE9ORzoKICAgICAgICAgICAgcmV0dXJuIFR5cGVLaW5kLkxPTkc7CiAgICAgICAgY2FzZSBDSEFSOgogICAgICAgICAgICByZXR1cm4gVHlwZUtpbmQuQ0hBUjsKICAgICAgICBjYXNlIEZMT0FUOgogICAgICAgICAgICByZXR1cm4gVHlwZUtpbmQuRkxPQVQ7CiAgICAgICAgY2FzZSBET1VCTEU6CiAgICAgICAgICAgIHJldHVybiBUeXBlS2luZC5ET1VCTEU7CiAgICAgICAgY2FzZSBWT0lEOgogICAgICAgICAgICByZXR1cm4gVHlwZUtpbmQuVk9JRDsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoInVua25vd24gcHJpbWl0aXZlIHR5cGUgIiArIHRoaXMpOwogICAgICAgIH0KICAgIH0KCiAgICAvKiogUmV0dXJucyB0cnVlIGlmIHRoZSBnaXZlbiB2YWx1ZSBpcyB3aXRoaW4gdGhlIGFsbG93ZWQgcmFuZ2UgZm9yIHRoaXMgdHlwZS4gKi8KICAgIHB1YmxpYyBib29sZWFuIGNoZWNrUmFuZ2UoaW50IHZhbHVlKSB7CiAgICAgICAgc3dpdGNoICh0aGlzKSB7CiAgICAgICAgICAgIGNhc2UgQk9PTEVBTjoKICAgICAgICAgICAgICAgIHJldHVybiAwIDw9IHZhbHVlICYmIHZhbHVlIDw9IDE7CiAgICAgICAgICAgIGNhc2UgQllURToKICAgICAgICAgICAgICAgIHJldHVybiBCeXRlLk1JTl9WQUxVRSA8PSB2YWx1ZSAmJiB2YWx1ZSA8PSBCeXRlLk1BWF9WQUxVRTsKICAgICAgICAgICAgY2FzZSBDSEFSOgogICAgICAgICAgICAgICAgcmV0dXJuIENoYXJhY3Rlci5NSU5fVkFMVUUgPD0gdmFsdWUgJiYgdmFsdWUgPD0gQ2hhcmFjdGVyLk1BWF9WQUxVRTsKICAgICAgICAgICAgY2FzZSBTSE9SVDoKICAgICAgICAgICAgICAgIHJldHVybiBTaG9ydC5NSU5fVkFMVUUgPD0gdmFsdWUgJiYgdmFsdWUgPD0gU2hvcnQuTUFYX1ZBTFVFOwogICAgICAgICAgICBjYXNlIElOVDoKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCk7CiAgICAgICAgfQogICAgfQp9ClBLAwQKAAAIAADSfU1KqguCuCkUAAApFAAAMQAAAGNvbS9zdW4vdG9vbHMvamF2YWMvY29kZS9EZWZlcnJlZExpbnRIYW5kbGVyLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTEsIDIwMTMsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhYy5jb2RlOwoKaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOwppbXBvcnQgamF2YS51dGlsLk1hcDsKCmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuRW5kUG9zVGFibGU7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuSkNUcmVlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkFzc2VydDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5Db250ZXh0OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkpDRGlhZ25vc3RpYy5EaWFnbm9zdGljUG9zaXRpb247CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuTGlzdEJ1ZmZlcjsKCi8qKgogKgogKiA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yCiAqIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj4KICovCnB1YmxpYyBjbGFzcyBEZWZlcnJlZExpbnRIYW5kbGVyIHsKICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgQ29udGV4dC5LZXk8RGVmZXJyZWRMaW50SGFuZGxlcj4gZGVmZXJyZWRMaW50SGFuZGxlcktleSA9IG5ldyBDb250ZXh0LktleTw+KCk7CgogICAgcHVibGljIHN0YXRpYyBEZWZlcnJlZExpbnRIYW5kbGVyIGluc3RhbmNlKENvbnRleHQgY29udGV4dCkgewogICAgICAgIERlZmVycmVkTGludEhhbmRsZXIgaW5zdGFuY2UgPSBjb250ZXh0LmdldChkZWZlcnJlZExpbnRIYW5kbGVyS2V5KTsKICAgICAgICBpZiAoaW5zdGFuY2UgPT0gbnVsbCkKICAgICAgICAgICAgaW5zdGFuY2UgPSBuZXcgRGVmZXJyZWRMaW50SGFuZGxlcihjb250ZXh0KTsKICAgICAgICByZXR1cm4gaW5zdGFuY2U7CiAgICB9CgogICAgcHJvdGVjdGVkIERlZmVycmVkTGludEhhbmRsZXIoQ29udGV4dCBjb250ZXh0KSB7CiAgICAgICAgY29udGV4dC5wdXQoZGVmZXJyZWRMaW50SGFuZGxlcktleSwgdGhpcyk7CiAgICAgICAgdGhpcy5jdXJyZW50UG9zID0gSU1NRURJQVRFX1BPU0lUSU9OOwogICAgfQoKICAgIC8qKkFuIGludGVyZmFjZSBmb3IgZGVmZXJyZWQgbGludCByZXBvcnRpbmcgLSBsb2dnZXJzIHBhc3NlZCB0bwogICAgICoge0BsaW5rICNyZXBvcnQoTGludExvZ2dlcikgfSB3aWxsIGJlIGNhbGxlZCB3aGVuCiAgICAgKiB7QGxpbmsgI2ZsdXNoKERpYWdub3N0aWNQb3NpdGlvbikgfSBpcyBpbnZva2VkLgogICAgICovCiAgICBwdWJsaWMgaW50ZXJmYWNlIExpbnRMb2dnZXIgewogICAgICAgIHZvaWQgcmVwb3J0KCk7CiAgICB9CgogICAgcHJpdmF0ZSBEaWFnbm9zdGljUG9zaXRpb24gY3VycmVudFBvczsKICAgIHByaXZhdGUgTWFwPERpYWdub3N0aWNQb3NpdGlvbiwgTGlzdEJ1ZmZlcjxMaW50TG9nZ2VyPj4gbG9nZ2Vyc1F1ZXVlID0gbmV3IEhhc2hNYXA8PigpOwoKICAgIC8qKkFzc29jaWF0ZSB0aGUgZ2l2ZW4gbG9nZ2VyIHdpdGggdGhlIGN1cnJlbnQgcG9zaXRpb24gYXMgc2V0IGJ5IHtAbGluayAjc2V0UG9zKERpYWdub3N0aWNQb3NpdGlvbikgfS4KICAgICAqIFdpbGwgYmUgaW52b2tlZCB3aGVuIHtAbGluayAjZmx1c2goRGlhZ25vc3RpY1Bvc2l0aW9uKSB9IHdpbGwgYmUgaW52b2tlZCB3aXRoIHRoZSBzYW1lIHBvc2l0aW9uLgogICAgICogPGJyPgogICAgICogV2lsbCBpbnZva2UgdGhlIGxvZ2dlciBzeW5jaHJvbm91c2x5IGlmIHtAbGluayAjaW1tZWRpYXRlKCkgfSB3YXMgY2FsbGVkCiAgICAgKiBpbnN0ZWFkIG9mIHtAbGluayAjc2V0UG9zKERpYWdub3N0aWNQb3NpdGlvbikgfS4KICAgICAqLwogICAgcHVibGljIHZvaWQgcmVwb3J0KExpbnRMb2dnZXIgbG9nZ2VyKSB7CiAgICAgICAgaWYgKGN1cnJlbnRQb3MgPT0gSU1NRURJQVRFX1BPU0lUSU9OKSB7CiAgICAgICAgICAgIGxvZ2dlci5yZXBvcnQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBMaXN0QnVmZmVyPExpbnRMb2dnZXI+IGxvZ2dlcnMgPSBsb2dnZXJzUXVldWUuZ2V0KGN1cnJlbnRQb3MpOwogICAgICAgICAgICBpZiAobG9nZ2VycyA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICBsb2dnZXJzUXVldWUucHV0KGN1cnJlbnRQb3MsIGxvZ2dlcnMgPSBuZXcgTGlzdEJ1ZmZlcjw+KCkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGxvZ2dlcnMuYXBwZW5kKGxvZ2dlcik7CiAgICAgICAgfQogICAgfQoKICAgIC8qKkludm9rZSBhbGwge0BsaW5rIExpbnRMb2dnZXJ9cyB0aGF0IHdlcmUgYXNzb2NpYXRlZCB3aXRoIHRoZSBwcm92aWRlZCB7QGNvZGUgcG9zfS4KICAgICAqLwogICAgcHVibGljIHZvaWQgZmx1c2goRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcykgewogICAgICAgIExpc3RCdWZmZXI8TGludExvZ2dlcj4gbG9nZ2VycyA9IGxvZ2dlcnNRdWV1ZS5nZXQocG9zKTsKICAgICAgICBpZiAobG9nZ2VycyAhPSBudWxsKSB7CiAgICAgICAgICAgIGZvciAoTGludExvZ2dlciBsaW50TG9nZ2VyIDogbG9nZ2VycykgewogICAgICAgICAgICAgICAgbGludExvZ2dlci5yZXBvcnQoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBsb2dnZXJzUXVldWUucmVtb3ZlKHBvcyk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKlNldHMgdGhlIGN1cnJlbnQgcG9zaXRpb24gdG8gdGhlIHByb3ZpZGVkIHtAY29kZSBjdXJyZW50UG9zfS4ge0BsaW5rIExpbnRMb2dnZXJ9cwogICAgICogcGFzc2VkIHRvIHN1YnNlcXVlbnQgaW52b2NhdGlvbnMgb2Yge0BsaW5rICNyZXBvcnQoTGludExvZ2dlcikgfSB3aWxsIGJlIGFzc29jaWF0ZWQKICAgICAqIHdpdGggdGhlIGdpdmVuIHBvc2l0aW9uLgogICAgICovCiAgICBwdWJsaWMgRGlhZ25vc3RpY1Bvc2l0aW9uIHNldFBvcyhEaWFnbm9zdGljUG9zaXRpb24gY3VycmVudFBvcykgewogICAgICAgIERpYWdub3N0aWNQb3NpdGlvbiBwcmV2UG9zaXRpb24gPSB0aGlzLmN1cnJlbnRQb3M7CiAgICAgICAgdGhpcy5jdXJyZW50UG9zID0gY3VycmVudFBvczsKICAgICAgICByZXR1cm4gcHJldlBvc2l0aW9uOwogICAgfQoKICAgIC8qKntAbGluayBMaW50TG9nZ2VyfXMgcGFzc2VkIHRvIHN1YnNlcXVlbnQgaW52b2NhdGlvbnMgb2YKICAgICAqIHtAbGluayAjcmVwb3J0KExpbnRMb2dnZXIpIH0gd2lsbCBiZSBpbnZva2VkIGltbWVkaWF0ZWx5LgogICAgICovCiAgICBwdWJsaWMgRGlhZ25vc3RpY1Bvc2l0aW9uIGltbWVkaWF0ZSgpIHsKICAgICAgICByZXR1cm4gc2V0UG9zKElNTUVESUFURV9QT1NJVElPTik7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgRGlhZ25vc3RpY1Bvc2l0aW9uIElNTUVESUFURV9QT1NJVElPTiA9IG5ldyBEaWFnbm9zdGljUG9zaXRpb24oKSB7CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIEpDVHJlZSBnZXRUcmVlKCkgewogICAgICAgICAgICBBc3NlcnQuZXJyb3IoKTsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgaW50IGdldFN0YXJ0UG9zaXRpb24oKSB7CiAgICAgICAgICAgIEFzc2VydC5lcnJvcigpOwogICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgaW50IGdldFByZWZlcnJlZFBvc2l0aW9uKCkgewogICAgICAgICAgICBBc3NlcnQuZXJyb3IoKTsKICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIGludCBnZXRFbmRQb3NpdGlvbihFbmRQb3NUYWJsZSBlbmRQb3NUYWJsZSkgewogICAgICAgICAgICBBc3NlcnQuZXJyb3IoKTsKICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgIH0KICAgIH07Cn0KUEsDBAoAAAgAAAY7qUp8x7ls93YAAPd2AAApAAAAY29tL3N1bi90b29scy9qYXZhYy9jb2RlL0NsYXNzRmluZGVyLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDE5OTksIDIwMTYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhYy5jb2RlOwoKaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CmltcG9ydCBqYXZhLm5pby5maWxlLlBhdGg7CmltcG9ydCBqYXZhLnV0aWwuRW51bVNldDsKaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOwppbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOwppbXBvcnQgamF2YS51dGlsLk1hcDsKaW1wb3J0IGphdmEudXRpbC5Ob1N1Y2hFbGVtZW50RXhjZXB0aW9uOwppbXBvcnQgamF2YS51dGlsLlNldDsKCmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLlNvdXJjZVZlcnNpb247CmltcG9ydCBqYXZheC50b29scy5KYXZhRmlsZU1hbmFnZXI7CmltcG9ydCBqYXZheC50b29scy5KYXZhRmlsZU1hbmFnZXIuTG9jYXRpb247CmltcG9ydCBqYXZheC50b29scy5KYXZhRmlsZU9iamVjdDsKaW1wb3J0IGphdmF4LnRvb2xzLkphdmFGaWxlT2JqZWN0LktpbmQ7CmltcG9ydCBqYXZheC50b29scy5TdGFuZGFyZEphdmFGaWxlTWFuYWdlcjsKaW1wb3J0IGphdmF4LnRvb2xzLlN0YW5kYXJkTG9jYXRpb247CgppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlNjb3BlLldyaXRlYWJsZVNjb3BlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlN5bWJvbC5DbGFzc1N5bWJvbDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5TeW1ib2wuQ29tcGxldGVyOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlN5bWJvbC5Db21wbGV0aW9uRmFpbHVyZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5TeW1ib2wuTW9kdWxlU3ltYm9sOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlN5bWJvbC5QYWNrYWdlU3ltYm9sOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlN5bWJvbC5UeXBlU3ltYm9sOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb21wLkFubm90YXRlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5maWxlLkpSVEluZGV4OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5maWxlLkphdmFjRmlsZU1hbmFnZXI7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmp2bS5DbGFzc1JlYWRlcjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuanZtLlByb2ZpbGU7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLm1haW4uT3B0aW9uOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5wbGF0Zm9ybS5QbGF0Zm9ybURlc2NyaXB0aW9uOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLio7CgppbXBvcnQgc3RhdGljIGphdmF4LnRvb2xzLlN0YW5kYXJkTG9jYXRpb24uKjsKCmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLkZsYWdzLio7CmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLktpbmRzLktpbmQuKjsKCmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuRGVwZW5kZW5jaWVzLkNvbXBsZXRpb25DYXVzZTsKCi8qKgogKiAgVGhpcyBjbGFzcyBwcm92aWRlcyBvcGVyYXRpb25zIHRvIGxvY2F0ZSBjbGFzcyBkZWZpbml0aW9ucwogKiAgZnJvbSB0aGUgc291cmNlIGFuZCBjbGFzcyBmaWxlcyBvbiB0aGUgcGF0aHMgcHJvdmlkZWQgdG8gamF2YWMuCiAqCiAqICA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiAgSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93biByaXNrLgogKiAgVGhpcyBjb2RlIGFuZCBpdHMgaW50ZXJuYWwgaW50ZXJmYWNlcyBhcmUgc3ViamVjdCB0byBjaGFuZ2Ugb3IKICogIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj4KICovCnB1YmxpYyBjbGFzcyBDbGFzc0ZpbmRlciB7CiAgICAvKiogVGhlIGNvbnRleHQga2V5IGZvciB0aGUgY2xhc3MgZmluZGVyLiAqLwogICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBDb250ZXh0LktleTxDbGFzc0ZpbmRlcj4gY2xhc3NGaW5kZXJLZXkgPSBuZXcgQ29udGV4dC5LZXk8PigpOwoKICAgIENsYXNzUmVhZGVyIHJlYWRlcjsKCiAgICBwcml2YXRlIGZpbmFsIEFubm90YXRlIGFubm90YXRlOwoKICAgIC8qKiBTd2l0Y2g6IHZlcmJvc2Ugb3V0cHV0LgogICAgICovCiAgICBib29sZWFuIHZlcmJvc2U7CgogICAgLyoqCiAgICAgKiBTd2l0Y2g6IGNhY2hlIGNvbXBsZXRpb24gZmFpbHVyZXMgdW5sZXNzIC1YRGRldiBpcyB1c2VkCiAgICAgKi8KICAgIHByaXZhdGUgYm9vbGVhbiBjYWNoZUNvbXBsZXRpb25GYWlsdXJlOwoKICAgIC8qKgogICAgICogU3dpdGNoOiBwcmVmZXIgc291cmNlIGZpbGVzIGluc3RlYWQgb2YgbmV3ZXIgd2hlbiBib3RoIHNvdXJjZQogICAgICogYW5kIGNsYXNzIGFyZSBhdmFpbGFibGUKICAgICAqKi8KICAgIHByb3RlY3RlZCBib29sZWFuIHByZWZlclNvdXJjZTsKCiAgICAvKioKICAgICAqIFN3aXRjaDogU2VhcmNoIGNsYXNzcGF0aCBhbmQgc291cmNlcGF0aCBmb3IgY2xhc3NlcyBiZWZvcmUgdGhlCiAgICAgKiBib290Y2xhc3NwYXRoCiAgICAgKi8KICAgIHByb3RlY3RlZCBib29sZWFuIHVzZXJQYXRoc0ZpcnN0OwoKICAgIC8qKgogICAgICogU3dpdGNoOiBzaG91bGQgcmVhZCBPVEhFUiBjbGFzc2ZpbGVzICguc2lnIGZpbGVzKSBmcm9tIFBMQVRGT1JNX0NMQVNTX1BBVEguCiAgICAgKi8KICAgIHByaXZhdGUgYm9vbGVhbiBhbGxvd1NpZ0ZpbGVzOwoKICAgIC8qKiBUaGUgbG9nIHRvIHVzZSBmb3IgdmVyYm9zZSBvdXRwdXQKICAgICAqLwogICAgZmluYWwgTG9nIGxvZzsKCiAgICAvKiogVGhlIHN5bWJvbCB0YWJsZS4gKi8KICAgIFN5bXRhYiBzeW1zOwoKICAgIC8qKiBUaGUgbmFtZSB0YWJsZS4gKi8KICAgIGZpbmFsIE5hbWVzIG5hbWVzOwoKICAgIC8qKiBGb3JjZSBhIGNvbXBsZXRpb24gZmFpbHVyZSBvbiB0aGlzIG5hbWUKICAgICAqLwogICAgZmluYWwgTmFtZSBjb21wbGV0aW9uRmFpbHVyZU5hbWU7CgogICAgLyoqIEFjY2VzcyB0byBmaWxlcwogICAgICovCiAgICBwcml2YXRlIGZpbmFsIEphdmFGaWxlTWFuYWdlciBmaWxlTWFuYWdlcjsKCiAgICAvKiogRGVwZW5kZW5jeSB0cmFja2VyCiAgICAgKi8KICAgIHByaXZhdGUgZmluYWwgRGVwZW5kZW5jaWVzIGRlcGVuZGVuY2llczsKCiAgICAvKiogRmFjdG9yeSBmb3IgZGlhZ25vc3RpY3MKICAgICAqLwogICAgSkNEaWFnbm9zdGljLkZhY3RvcnkgZGlhZ0ZhY3Rvcnk7CgogICAgLyoqIENhbiBiZSByZWFzc2lnbmVkIGZyb20gb3V0c2lkZToKICAgICAqICB0aGUgY29tcGxldGVyIHRvIGJlIHVzZWQgZm9yICIuamF2YSIgZmlsZXMuIElmIHRoaXMgcmVtYWlucyB1bmFzc2lnbmVkCiAgICAgKiAgIi5qYXZhIiBmaWxlcyB3aWxsIG5vdCBiZSBsb2FkZWQuCiAgICAgKi8KICAgIHB1YmxpYyBDb21wbGV0ZXIgc291cmNlQ29tcGxldGVyID0gQ29tcGxldGVyLk5VTExfQ09NUExFVEVSOwoKICAgIC8qKiBUaGUgcGF0aCBuYW1lIG9mIHRoZSBjbGFzcyBmaWxlIGN1cnJlbnRseSBiZWluZyByZWFkLgogICAgICovCiAgICBwcm90ZWN0ZWQgSmF2YUZpbGVPYmplY3QgY3VycmVudENsYXNzRmlsZSA9IG51bGw7CgogICAgLyoqIFRoZSBjbGFzcyBvciBtZXRob2QgY3VycmVudGx5IGJlaW5nIHJlYWQuCiAgICAgKi8KICAgIHByb3RlY3RlZCBTeW1ib2wgY3VycmVudE93bmVyID0gbnVsbDsKCiAgICAvKioKICAgICAqIFRoZSBjdXJyZW50bHkgc2VsZWN0ZWQgcHJvZmlsZS4KICAgICAqLwogICAgcHJpdmF0ZSBmaW5hbCBQcm9maWxlIHByb2ZpbGU7CgogICAgLyoqCiAgICAgKiBVc2UgZGlyZWN0IGFjY2VzcyB0byB0aGUgSlJUSW5kZXggdG8gYWNjZXNzIHRoZSB0ZW1wb3JhcnkKICAgICAqIHJlcGxhY2VtZW50IGZvciB0aGUgaW5mbyB0aGF0IHVzZWQgdG8gYmUgaW4gY3Quc3ltLgogICAgICogSW4gdGltZSwgdGhpcyB3aWxsIGdvIGF3YXkgYW5kIGJlIHJlcGxhY2VkIGJ5IHRoZSBtb2R1bGUgc3lzdGVtLgogICAgICovCiAgICBwcml2YXRlIGZpbmFsIEpSVEluZGV4IGpydEluZGV4OwoKICAgIC8qKgogICAgICogQ29tcGxldGVyIHRoYXQgZGVsZWdhdGVzIHRvIHRoZSBjb21wbGV0ZS1tZXRob2Qgb2YgdGhpcyBjbGFzcy4KICAgICAqLwogICAgcHJpdmF0ZSBmaW5hbCBDb21wbGV0ZXIgdGhpc0NvbXBsZXRlciA9IHRoaXM6OmNvbXBsZXRlOwoKICAgIHB1YmxpYyBDb21wbGV0ZXIgZ2V0Q29tcGxldGVyKCkgewogICAgICAgIHJldHVybiB0aGlzQ29tcGxldGVyOwogICAgfQoKICAgIC8qKiBHZXQgdGhlIENsYXNzRmluZGVyIGluc3RhbmNlIGZvciB0aGlzIGludm9jYXRpb24uICovCiAgICBwdWJsaWMgc3RhdGljIENsYXNzRmluZGVyIGluc3RhbmNlKENvbnRleHQgY29udGV4dCkgewogICAgICAgIENsYXNzRmluZGVyIGluc3RhbmNlID0gY29udGV4dC5nZXQoY2xhc3NGaW5kZXJLZXkpOwogICAgICAgIGlmIChpbnN0YW5jZSA9PSBudWxsKQogICAgICAgICAgICBpbnN0YW5jZSA9IG5ldyBDbGFzc0ZpbmRlcihjb250ZXh0KTsKICAgICAgICByZXR1cm4gaW5zdGFuY2U7CiAgICB9CgogICAgLyoqIENvbnN0cnVjdCBhIG5ldyBjbGFzcyBmaW5kZXIuICovCiAgICBwcm90ZWN0ZWQgQ2xhc3NGaW5kZXIoQ29udGV4dCBjb250ZXh0KSB7CiAgICAgICAgY29udGV4dC5wdXQoY2xhc3NGaW5kZXJLZXksIHRoaXMpOwogICAgICAgIHJlYWRlciA9IENsYXNzUmVhZGVyLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIG5hbWVzID0gTmFtZXMuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgc3ltcyA9IFN5bXRhYi5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBmaWxlTWFuYWdlciA9IGNvbnRleHQuZ2V0KEphdmFGaWxlTWFuYWdlci5jbGFzcyk7CiAgICAgICAgZGVwZW5kZW5jaWVzID0gRGVwZW5kZW5jaWVzLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIGlmIChmaWxlTWFuYWdlciA9PSBudWxsKQogICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoIkZpbGVNYW5hZ2VyIGluaXRpYWxpemF0aW9uIGVycm9yIik7CiAgICAgICAgZGlhZ0ZhY3RvcnkgPSBKQ0RpYWdub3N0aWMuRmFjdG9yeS5pbnN0YW5jZShjb250ZXh0KTsKCiAgICAgICAgbG9nID0gTG9nLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIGFubm90YXRlID0gQW5ub3RhdGUuaW5zdGFuY2UoY29udGV4dCk7CgogICAgICAgIE9wdGlvbnMgb3B0aW9ucyA9IE9wdGlvbnMuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgdmVyYm9zZSA9IG9wdGlvbnMuaXNTZXQoT3B0aW9uLlZFUkJPU0UpOwogICAgICAgIGNhY2hlQ29tcGxldGlvbkZhaWx1cmUgPSBvcHRpb25zLmlzVW5zZXQoImRldiIpOwogICAgICAgIHByZWZlclNvdXJjZSA9ICJzb3VyY2UiLmVxdWFscyhvcHRpb25zLmdldCgiLVhwcmVmZXIiKSk7CiAgICAgICAgdXNlclBhdGhzRmlyc3QgPSBvcHRpb25zLmlzU2V0KE9wdGlvbi5YWFVTRVJQQVRIU0ZJUlNUKTsKICAgICAgICBhbGxvd1NpZ0ZpbGVzID0gY29udGV4dC5nZXQoUGxhdGZvcm1EZXNjcmlwdGlvbi5jbGFzcykgIT0gbnVsbDsKCiAgICAgICAgY29tcGxldGlvbkZhaWx1cmVOYW1lID0KICAgICAgICAgICAgb3B0aW9ucy5pc1NldCgiZmFpbGNvbXBsZXRlIikKICAgICAgICAgICAgPyBuYW1lcy5mcm9tU3RyaW5nKG9wdGlvbnMuZ2V0KCJmYWlsY29tcGxldGUiKSkKICAgICAgICAgICAgOiBudWxsOwoKICAgICAgICAvLyBUZW1wb3JhcnksIHVudGlsIG1vcmUgaW5mbyBpcyBhdmFpbGFibGUgZnJvbSB0aGUgbW9kdWxlIHN5c3RlbS4KICAgICAgICBib29sZWFuIHVzZUN0UHJvcHM7CiAgICAgICAgSmF2YUZpbGVNYW5hZ2VyIGZtID0gY29udGV4dC5nZXQoSmF2YUZpbGVNYW5hZ2VyLmNsYXNzKTsKICAgICAgICBpZiAoZm0gaW5zdGFuY2VvZiBKYXZhY0ZpbGVNYW5hZ2VyKSB7CiAgICAgICAgICAgIEphdmFjRmlsZU1hbmFnZXIgamZtID0gKEphdmFjRmlsZU1hbmFnZXIpIGZtOwogICAgICAgICAgICB1c2VDdFByb3BzID0gamZtLmlzRGVmYXVsdEJvb3RDbGFzc1BhdGgoKSAmJiBqZm0uaXNTeW1ib2xGaWxlRW5hYmxlZCgpOwogICAgICAgIH0gZWxzZSBpZiAoZm0uZ2V0Q2xhc3MoKS5nZXROYW1lKCkuZXF1YWxzKCJjb20uc3VuLnRvb2xzLnNqYXZhYy5jb21wLlNtYXJ0RmlsZU1hbmFnZXIiKSkgewogICAgICAgICAgICB1c2VDdFByb3BzID0gIW9wdGlvbnMuaXNTZXQoImlnbm9yZS5zeW1ib2wuZmlsZSIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHVzZUN0UHJvcHMgPSBmYWxzZTsKICAgICAgICB9CiAgICAgICAganJ0SW5kZXggPSB1c2VDdFByb3BzICYmIEpSVEluZGV4LmlzQXZhaWxhYmxlKCkgPyBKUlRJbmRleC5nZXRTaGFyZWRJbnN0YW5jZSgpIDogbnVsbDsKCiAgICAgICAgcHJvZmlsZSA9IFByb2ZpbGUuaW5zdGFuY2UoY29udGV4dCk7CiAgICB9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBUZW1wb3JhcnkgY3Quc3ltIHJlcGxhY2VtZW50CiAqCiAqIFRoZSBmb2xsb3dpbmcgY29kZSBpcyBhIHRlbXBvcmFyeSBzdWJzdGl0dXRlIGZvciB0aGUgY3Quc3ltIG1lY2hhbmlzbQogKiB1c2VkIGluIEpESyA2IHRocnUgSkRLIDguCiAqIFRoaXMgbWVjaGFuaXNtIHdpbGwgZXZlbnR1YWxseSBiZSBzdXBlcnNlZGVkIGJ5IHRoZSBKaWdzYXcgbW9kdWxlIHN5c3RlbS4KICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKICAgIC8qKgogICAgICogUmV0dXJucyBhbnkgZXh0cmEgZmxhZ3MgZm9yIGEgY2xhc3Mgc3ltYm9sLgogICAgICogVGhpcyBpbmZvcm1hdGlvbiB1c2VkIHRvIGJlIHByb3ZpZGVkIHVzaW5nIHByaXZhdGUgYW5ub3RhdGlvbnMKICAgICAqIGluIHRoZSBjbGFzcyBmaWxlIGluIGN0LnN5bTsgaW4gdGltZSwgdGhpcyBpbmZvcm1hdGlvbiB3aWxsIGJlCiAgICAgKiBhdmFpbGFibGUgZnJvbSB0aGUgbW9kdWxlIHN5c3RlbS4KICAgICAqLwogICAgbG9uZyBnZXRTdXBwbGVtZW50YXJ5RmxhZ3MoQ2xhc3NTeW1ib2wgYykgewogICAgICAgIGlmIChqcnRJbmRleCA9PSBudWxsIHx8ICFqcnRJbmRleC5pc0luSlJUKGMuY2xhc3NmaWxlKSB8fCBjLm5hbWUgPT0gbmFtZXMubW9kdWxlX2luZm8pIHsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQoKICAgICAgICBpZiAoc3VwcGxlbWVudGFyeUZsYWdzID09IG51bGwpIHsKICAgICAgICAgICAgc3VwcGxlbWVudGFyeUZsYWdzID0gbmV3IEhhc2hNYXA8PigpOwogICAgICAgIH0KCiAgICAgICAgTG9uZyBmbGFncyA9IHN1cHBsZW1lbnRhcnlGbGFncy5nZXQoYy5wYWNrZ2UoKSk7CiAgICAgICAgaWYgKGZsYWdzID09IG51bGwpIHsKICAgICAgICAgICAgbG9uZyBuZXdGbGFncyA9IDA7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBKUlRJbmRleC5DdFN5bSBjdFN5bSA9IGpydEluZGV4LmdldEN0U3ltKGMucGFja2dlKCkuZmxhdE5hbWUoKSk7CiAgICAgICAgICAgICAgICBQcm9maWxlIG1pblByb2ZpbGUgPSBQcm9maWxlLkRFRkFVTFQ7CiAgICAgICAgICAgICAgICBpZiAoY3RTeW0ucHJvcHJpZXRhcnkpCiAgICAgICAgICAgICAgICAgICAgbmV3RmxhZ3MgfD0gUFJPUFJJRVRBUlk7CiAgICAgICAgICAgICAgICBpZiAoY3RTeW0ubWluUHJvZmlsZSAhPSBudWxsKQogICAgICAgICAgICAgICAgICAgIG1pblByb2ZpbGUgPSBQcm9maWxlLmxvb2t1cChjdFN5bS5taW5Qcm9maWxlKTsKICAgICAgICAgICAgICAgIGlmIChwcm9maWxlICE9IFByb2ZpbGUuREVGQVVMVCAmJiBtaW5Qcm9maWxlLnZhbHVlID4gcHJvZmlsZS52YWx1ZSkgewogICAgICAgICAgICAgICAgICAgIG5ld0ZsYWdzIHw9IE5PVF9JTl9QUk9GSUxFOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBpZ25vcmUpIHsKICAgICAgICAgICAgfQogICAgICAgICAgICBzdXBwbGVtZW50YXJ5RmxhZ3MucHV0KGMucGFja2dlKCksIGZsYWdzID0gbmV3RmxhZ3MpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmxhZ3M7CiAgICB9CgogICAgcHJpdmF0ZSBNYXA8UGFja2FnZVN5bWJvbCwgTG9uZz4gc3VwcGxlbWVudGFyeUZsYWdzOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBMb2FkaW5nIENsYXNzZXMKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKICAgIC8qKiBDb21wbGV0aW9uIGZvciBjbGFzc2VzIHRvIGJlIGxvYWRlZC4gQmVmb3JlIGEgY2xhc3MgaXMgbG9hZGVkCiAgICAgKiAgd2UgbWFrZSBzdXJlIGl0cyBlbmNsb3NpbmcgY2xhc3MgKGlmIGFueSkgaXMgbG9hZGVkLgogICAgICovCiAgICBwcml2YXRlIHZvaWQgY29tcGxldGUoU3ltYm9sIHN5bSkgdGhyb3dzIENvbXBsZXRpb25GYWlsdXJlIHsKICAgICAgICBpZiAoc3ltLmtpbmQgPT0gVFlQKSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBDbGFzc1N5bWJvbCBjID0gKENsYXNzU3ltYm9sKSBzeW07CiAgICAgICAgICAgICAgICBkZXBlbmRlbmNpZXMucHVzaChjLCBDb21wbGV0aW9uQ2F1c2UuQ0xBU1NfUkVBREVSKTsKICAgICAgICAgICAgICAgIGFubm90YXRlLmJsb2NrQW5ub3RhdGlvbnMoKTsKICAgICAgICAgICAgICAgIGMubWVtYmVyc19maWVsZCA9IG5ldyBTY29wZS5FcnJvclNjb3BlKGMpOyAvLyBtYWtlIHN1cmUgaXQncyBhbHdheXMgZGVmaW5lZAogICAgICAgICAgICAgICAgY29tcGxldGVPd25lcnMoYy5vd25lcik7CiAgICAgICAgICAgICAgICBjb21wbGV0ZUVuY2xvc2luZyhjKTsKICAgICAgICAgICAgICAgIGZpbGxJbihjKTsKICAgICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgICAgIGFubm90YXRlLnVuYmxvY2tBbm5vdGF0aW9uc05vRmx1c2goKTsKICAgICAgICAgICAgICAgIGRlcGVuZGVuY2llcy5wb3AoKTsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSBpZiAoc3ltLmtpbmQgPT0gUENLKSB7CiAgICAgICAgICAgIFBhY2thZ2VTeW1ib2wgcCA9IChQYWNrYWdlU3ltYm9sKXN5bTsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIGZpbGxJbihwKTsKICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBDb21wbGV0aW9uRmFpbHVyZShzeW0sIGV4LmdldExvY2FsaXplZE1lc3NhZ2UoKSkuaW5pdENhdXNlKGV4KTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoIXJlYWRlci5maWxsaW5nKQogICAgICAgICAgICBhbm5vdGF0ZS5mbHVzaCgpOyAvLyBmaW5pc2ggYXR0YWNoaW5nIGFubm90YXRpb25zCiAgICB9CgogICAgLyoqIGNvbXBsZXRlIHVwIHRocm91Z2ggdGhlIGVuY2xvc2luZyBwYWNrYWdlLiAqLwogICAgcHJpdmF0ZSB2b2lkIGNvbXBsZXRlT3duZXJzKFN5bWJvbCBvKSB7CiAgICAgICAgaWYgKG8ua2luZCAhPSBQQ0spIGNvbXBsZXRlT3duZXJzKG8ub3duZXIpOwogICAgICAgIG8uY29tcGxldGUoKTsKICAgIH0KCiAgICAvKioKICAgICAqIFRyaWVzIHRvIGNvbXBsZXRlIGxleGljYWxseSBlbmNsb3NpbmcgY2xhc3NlcyBpZiBjIGxvb2tzIGxpa2UgYQogICAgICogbmVzdGVkIGNsYXNzLiAgVGhpcyBpcyBzaW1pbGFyIHRvIGNvbXBsZXRlT3duZXJzIGJ1dCBoYW5kbGVzCiAgICAgKiB0aGUgc2l0dWF0aW9uIHdoZW4gYSBuZXN0ZWQgY2xhc3MgaXMgYWNjZXNzZWQgZGlyZWN0bHkgYXMgaXQgaXMKICAgICAqIHBvc3NpYmxlIHdpdGggdGhlIFRyZWUgQVBJIG9yIGphdmF4LmxhbmcubW9kZWwuKi4KICAgICAqLwogICAgcHJpdmF0ZSB2b2lkIGNvbXBsZXRlRW5jbG9zaW5nKENsYXNzU3ltYm9sIGMpIHsKICAgICAgICBpZiAoYy5vd25lci5raW5kID09IFBDSykgewogICAgICAgICAgICBTeW1ib2wgb3duZXIgPSBjLm93bmVyOwogICAgICAgICAgICBmb3IgKE5hbWUgbmFtZSA6IENvbnZlcnQuZW5jbG9zaW5nQ2FuZGlkYXRlcyhDb252ZXJ0LnNob3J0TmFtZShjLm5hbWUpKSkgewogICAgICAgICAgICAgICAgU3ltYm9sIGVuY2wgPSBvd25lci5tZW1iZXJzKCkuZmluZEZpcnN0KG5hbWUpOwogICAgICAgICAgICAgICAgaWYgKGVuY2wgPT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICBlbmNsID0gc3ltcy5nZXRDbGFzcyhjLnBhY2tnZSgpLm1vZGxlLCBUeXBlU3ltYm9sLmZvcm1GbGF0TmFtZShuYW1lLCBvd25lcikpOwogICAgICAgICAgICAgICAgaWYgKGVuY2wgIT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICBlbmNsLmNvbXBsZXRlKCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqIEZpbGwgaW4gZGVmaW5pdGlvbiBvZiBjbGFzcyBgYycgZnJvbSBjb3JyZXNwb25kaW5nIGNsYXNzIG9yCiAgICAgKiAgc291cmNlIGZpbGUuCiAgICAgKi8KICAgIHZvaWQgZmlsbEluKENsYXNzU3ltYm9sIGMpIHsKICAgICAgICBpZiAoY29tcGxldGlvbkZhaWx1cmVOYW1lID09IGMuZnVsbG5hbWUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IENvbXBsZXRpb25GYWlsdXJlKGMsICJ1c2VyLXNlbGVjdGVkIGNvbXBsZXRpb24gZmFpbHVyZSBieSBjbGFzcyBuYW1lIik7CiAgICAgICAgfQogICAgICAgIGN1cnJlbnRPd25lciA9IGM7CiAgICAgICAgSmF2YUZpbGVPYmplY3QgY2xhc3NmaWxlID0gYy5jbGFzc2ZpbGU7CiAgICAgICAgaWYgKGNsYXNzZmlsZSAhPSBudWxsKSB7CiAgICAgICAgICAgIEphdmFGaWxlT2JqZWN0IHByZXZpb3VzQ2xhc3NGaWxlID0gY3VycmVudENsYXNzRmlsZTsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIGlmIChyZWFkZXIuZmlsbGluZykgewogICAgICAgICAgICAgICAgICAgIEFzc2VydC5lcnJvcigiRmlsbGluZyAiICsgY2xhc3NmaWxlLnRvVXJpKCkgKyAiIGR1cmluZyAiICsgcHJldmlvdXNDbGFzc0ZpbGUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgY3VycmVudENsYXNzRmlsZSA9IGNsYXNzZmlsZTsKICAgICAgICAgICAgICAgIGlmICh2ZXJib3NlKSB7CiAgICAgICAgICAgICAgICAgICAgbG9nLnByaW50VmVyYm9zZSgibG9hZGluZyIsIGN1cnJlbnRDbGFzc0ZpbGUuZ2V0TmFtZSgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChjbGFzc2ZpbGUuZ2V0S2luZCgpID09IEphdmFGaWxlT2JqZWN0LktpbmQuQ0xBU1MgfHwKICAgICAgICAgICAgICAgICAgICBjbGFzc2ZpbGUuZ2V0S2luZCgpID09IEphdmFGaWxlT2JqZWN0LktpbmQuT1RIRVIpIHsKICAgICAgICAgICAgICAgICAgICByZWFkZXIucmVhZENsYXNzRmlsZShjKTsKICAgICAgICAgICAgICAgICAgICBjLmZsYWdzX2ZpZWxkIHw9IGdldFN1cHBsZW1lbnRhcnlGbGFncyhjKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCFzb3VyY2VDb21wbGV0ZXIuaXNUZXJtaW5hbCgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHNvdXJjZUNvbXBsZXRlci5jb21wbGV0ZShjKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJTb3VyY2UgY29tcGxldGVyIHJlcXVpcmVkIHRvIHJlYWQgIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgY2xhc3NmaWxlLnRvVXJpKCkpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgICAgIGN1cnJlbnRDbGFzc0ZpbGUgPSBwcmV2aW91c0NsYXNzRmlsZTsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHRocm93IGNsYXNzRmlsZU5vdEZvdW5kKGMpOwogICAgICAgIH0KICAgIH0KICAgIC8vIHdoZXJlCiAgICAgICAgcHJpdmF0ZSBDb21wbGV0aW9uRmFpbHVyZSBjbGFzc0ZpbGVOb3RGb3VuZChDbGFzc1N5bWJvbCBjKSB7CiAgICAgICAgICAgIEpDRGlhZ25vc3RpYyBkaWFnID0KICAgICAgICAgICAgICAgIGRpYWdGYWN0b3J5LmZyYWdtZW50KCJjbGFzcy5maWxlLm5vdC5mb3VuZCIsIGMuZmxhdG5hbWUpOwogICAgICAgICAgICByZXR1cm4gbmV3Q29tcGxldGlvbkZhaWx1cmUoYywgZGlhZyk7CiAgICAgICAgfQogICAgICAgIC8qKiBTdGF0aWMgZmFjdG9yeSBmb3IgQ29tcGxldGlvbkZhaWx1cmUgb2JqZWN0cy4KICAgICAgICAgKiAgSW4gcHJhY3RpY2UsIG9ubHkgb25lIGNhbiBiZSB1c2VkIGF0IGEgdGltZSwgc28gd2Ugc2hhcmUgb25lCiAgICAgICAgICogIHRvIHJlZHVjZSB0aGUgZXhwZW5zZSBvZiBhbGxvY2F0aW5nIG5ldyBleGNlcHRpb24gb2JqZWN0cy4KICAgICAgICAgKi8KICAgICAgICBwcml2YXRlIENvbXBsZXRpb25GYWlsdXJlIG5ld0NvbXBsZXRpb25GYWlsdXJlKFR5cGVTeW1ib2wgYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEpDRGlhZ25vc3RpYyBkaWFnKSB7CiAgICAgICAgICAgIGlmICghY2FjaGVDb21wbGV0aW9uRmFpbHVyZSkgewogICAgICAgICAgICAgICAgLy8gbG9nLndhcm5pbmcoInByb2MubWVzc2FnZXIiLAogICAgICAgICAgICAgICAgLy8gICAgICAgICAgICAgTG9nLmdldExvY2FsaXplZFN0cmluZygiY2xhc3MuZmlsZS5ub3QuZm91bmQiLCBjLmZsYXRuYW1lKSk7CiAgICAgICAgICAgICAgICAvLyBjLmRlYnVnLnByaW50U3RhY2tUcmFjZSgpOwogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBDb21wbGV0aW9uRmFpbHVyZShjLCBkaWFnKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIENvbXBsZXRpb25GYWlsdXJlIHJlc3VsdCA9IGNhY2hlZENvbXBsZXRpb25GYWlsdXJlOwogICAgICAgICAgICAgICAgcmVzdWx0LnN5bSA9IGM7CiAgICAgICAgICAgICAgICByZXN1bHQuZGlhZyA9IGRpYWc7CiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHByaXZhdGUgZmluYWwgQ29tcGxldGlvbkZhaWx1cmUgY2FjaGVkQ29tcGxldGlvbkZhaWx1cmUgPQogICAgICAgICAgICBuZXcgQ29tcGxldGlvbkZhaWx1cmUobnVsbCwgKEpDRGlhZ25vc3RpYykgbnVsbCk7CiAgICAgICAgewogICAgICAgICAgICBjYWNoZWRDb21wbGV0aW9uRmFpbHVyZS5zZXRTdGFja1RyYWNlKG5ldyBTdGFja1RyYWNlRWxlbWVudFswXSk7CiAgICAgICAgfQoKCiAgICAvKiogTG9hZCBhIHRvcGxldmVsIGNsYXNzIHdpdGggZ2l2ZW4gZnVsbHkgcXVhbGlmaWVkIG5hbWUKICAgICAqICBUaGUgY2xhc3MgaXMgZW50ZXJlZCBpbnRvIGBjbGFzc2VzJyBvbmx5IGlmIGxvYWQgd2FzIHN1Y2Nlc3NmdWwuCiAgICAgKi8KICAgIHB1YmxpYyBDbGFzc1N5bWJvbCBsb2FkQ2xhc3MoTW9kdWxlU3ltYm9sIG1zeW0sIE5hbWUgZmxhdG5hbWUpIHRocm93cyBDb21wbGV0aW9uRmFpbHVyZSB7CiAgICAgICAgQXNzZXJ0LmNoZWNrTm9uTnVsbChtc3ltKTsKICAgICAgICBOYW1lIHBhY2thZ2VOYW1lID0gQ29udmVydC5wYWNrYWdlUGFydChmbGF0bmFtZSk7CiAgICAgICAgUGFja2FnZVN5bWJvbCBwcyA9IHN5bXMubG9va3VwUGFja2FnZShtc3ltLCBwYWNrYWdlTmFtZSk7CgogICAgICAgIEFzc2VydC5jaGVja05vbk51bGwocHMubW9kbGUsICgpIC0+ICJtc3ltPSIgKyBtc3ltICsgIjsgZmxhdE5hbWU9IiArIGZsYXRuYW1lKTsKCiAgICAgICAgYm9vbGVhbiBhYnNlbnQgPSBzeW1zLmdldENsYXNzKHBzLm1vZGxlLCBmbGF0bmFtZSkgPT0gbnVsbDsKICAgICAgICBDbGFzc1N5bWJvbCBjID0gc3ltcy5lbnRlckNsYXNzKHBzLm1vZGxlLCBmbGF0bmFtZSk7CgogICAgICAgIGlmIChjLm1lbWJlcnNfZmllbGQgPT0gbnVsbCkgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgYy5jb21wbGV0ZSgpOwogICAgICAgICAgICB9IGNhdGNoIChDb21wbGV0aW9uRmFpbHVyZSBleCkgewogICAgICAgICAgICAgICAgaWYgKGFic2VudCkgc3ltcy5yZW1vdmVDbGFzcyhwcy5tb2RsZSwgZmxhdG5hbWUpOwogICAgICAgICAgICAgICAgdGhyb3cgZXg7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIGM7CiAgICB9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIExvYWRpbmcgUGFja2FnZXMKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKICAgIC8qKiBJbmNsdWRlIGNsYXNzIGNvcnJlc3BvbmRpbmcgdG8gZ2l2ZW4gY2xhc3MgZmlsZSBpbiBwYWNrYWdlLAogICAgICogIHVubGVzcyAoMSkgd2UgYWxyZWFkeSBoYXZlIG9uZSB0aGUgc2FtZSBraW5kICguY2xhc3Mgb3IgLmphdmEpLCBvcgogICAgICogICAgICAgICAoMikgd2UgaGF2ZSBvbmUgb2YgdGhlIG90aGVyIGtpbmQsIGFuZCB0aGUgZ2l2ZW4gY2xhc3MgZmlsZQogICAgICogICAgICAgICAgICAgaXMgb2xkZXIuCiAgICAgKi8KICAgIHByb3RlY3RlZCB2b2lkIGluY2x1ZGVDbGFzc0ZpbGUoUGFja2FnZVN5bWJvbCBwLCBKYXZhRmlsZU9iamVjdCBmaWxlKSB7CiAgICAgICAgaWYgKChwLmZsYWdzX2ZpZWxkICYgRVhJU1RTKSA9PSAwKQogICAgICAgICAgICBmb3IgKFN5bWJvbCBxID0gcDsgcSAhPSBudWxsICYmIHEua2luZCA9PSBQQ0s7IHEgPSBxLm93bmVyKQogICAgICAgICAgICAgICAgcS5mbGFnc19maWVsZCB8PSBFWElTVFM7CiAgICAgICAgSmF2YUZpbGVPYmplY3QuS2luZCBraW5kID0gZmlsZS5nZXRLaW5kKCk7CiAgICAgICAgaW50IHNlZW47CiAgICAgICAgaWYgKGtpbmQgPT0gSmF2YUZpbGVPYmplY3QuS2luZC5DTEFTUyB8fCBraW5kID09IEphdmFGaWxlT2JqZWN0LktpbmQuT1RIRVIpCiAgICAgICAgICAgIHNlZW4gPSBDTEFTU19TRUVOOwogICAgICAgIGVsc2UKICAgICAgICAgICAgc2VlbiA9IFNPVVJDRV9TRUVOOwogICAgICAgIFN0cmluZyBiaW5hcnlOYW1lID0gZmlsZU1hbmFnZXIuaW5mZXJCaW5hcnlOYW1lKGN1cnJlbnRMb2MsIGZpbGUpOwogICAgICAgIGludCBsYXN0RG90ID0gYmluYXJ5TmFtZS5sYXN0SW5kZXhPZigiLiIpOwogICAgICAgIE5hbWUgY2xhc3NuYW1lID0gbmFtZXMuZnJvbVN0cmluZyhiaW5hcnlOYW1lLnN1YnN0cmluZyhsYXN0RG90ICsgMSkpOwogICAgICAgIGJvb2xlYW4gaXNQa2dJbmZvID0gY2xhc3NuYW1lID09IG5hbWVzLnBhY2thZ2VfaW5mbzsKICAgICAgICBDbGFzc1N5bWJvbCBjID0gaXNQa2dJbmZvCiAgICAgICAgICAgID8gcC5wYWNrYWdlX2luZm8KICAgICAgICAgICAgOiAoQ2xhc3NTeW1ib2wpIHAubWVtYmVyc19maWVsZC5maW5kRmlyc3QoY2xhc3NuYW1lKTsKICAgICAgICBpZiAoYyA9PSBudWxsKSB7CiAgICAgICAgICAgIGMgPSBzeW1zLmVudGVyQ2xhc3MocC5tb2RsZSwgY2xhc3NuYW1lLCBwKTsKICAgICAgICAgICAgaWYgKGMuY2xhc3NmaWxlID09IG51bGwpIC8vIG9ubHkgdXBkYXRlIHRoZSBmaWxlIGlmJ3MgaXQncyBuZXdseSBjcmVhdGVkCiAgICAgICAgICAgICAgICBjLmNsYXNzZmlsZSA9IGZpbGU7CiAgICAgICAgICAgIGlmIChpc1BrZ0luZm8pIHsKICAgICAgICAgICAgICAgIHAucGFja2FnZV9pbmZvID0gYzsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGlmIChjLm93bmVyID09IHApICAvLyBpdCBtaWdodCBiZSBhbiBpbm5lciBjbGFzcwogICAgICAgICAgICAgICAgICAgIHAubWVtYmVyc19maWVsZC5lbnRlcihjKTsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSBpZiAoIXByZWZlckN1cnJlbnQgJiYgYy5jbGFzc2ZpbGUgIT0gbnVsbCAmJiAoYy5mbGFnc19maWVsZCAmIHNlZW4pID09IDApIHsKICAgICAgICAgICAgLy8gaWYgYy5jbGFzc2ZpbGUgPT0gbnVsbCwgd2UgYXJlIGN1cnJlbnRseSBjb21waWxpbmcgdGhpcyBjbGFzcwogICAgICAgICAgICAvLyBhbmQgbm8gZnVydGhlciBhY3Rpb24gaXMgbmVjZXNzYXJ5LgogICAgICAgICAgICAvLyBpZiAoYy5mbGFnc19maWVsZCAmIHNlZW4pICE9IDAsIHdlIGhhdmUgYWxyZWFkeSBlbmNvdW50ZXJlZAogICAgICAgICAgICAvLyBhIGZpbGUgb2YgdGhlIHNhbWUga2luZDsgYWdhaW4gbm8gZnVydGhlciBhY3Rpb24gaXMgbmVjZXNzYXJ5LgogICAgICAgICAgICBpZiAoKGMuZmxhZ3NfZmllbGQgJiAoQ0xBU1NfU0VFTiB8IFNPVVJDRV9TRUVOKSkgIT0gMCkKICAgICAgICAgICAgICAgIGMuY2xhc3NmaWxlID0gcHJlZmVycmVkRmlsZU9iamVjdChmaWxlLCBjLmNsYXNzZmlsZSk7CiAgICAgICAgfQogICAgICAgIGMuZmxhZ3NfZmllbGQgfD0gc2VlbjsKICAgIH0KCiAgICAvKiogSW1wbGVtZW50IHBvbGljeSB0byBjaG9vc2UgdG8gZGVyaXZlIGluZm9ybWF0aW9uIGZyb20gYSBzb3VyY2UKICAgICAqICBmaWxlIG9yIGEgY2xhc3MgZmlsZSB3aGVuIGJvdGggYXJlIHByZXNlbnQuICBNYXkgYmUgb3ZlcnJpZGRlbgogICAgICogIGJ5IHN1YmNsYXNzZXMuCiAgICAgKi8KICAgIHByb3RlY3RlZCBKYXZhRmlsZU9iamVjdCBwcmVmZXJyZWRGaWxlT2JqZWN0KEphdmFGaWxlT2JqZWN0IGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBKYXZhRmlsZU9iamVjdCBiKSB7CgogICAgICAgIGlmIChwcmVmZXJTb3VyY2UpCiAgICAgICAgICAgIHJldHVybiAoYS5nZXRLaW5kKCkgPT0gSmF2YUZpbGVPYmplY3QuS2luZC5TT1VSQ0UpID8gYSA6IGI7CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIGxvbmcgYWRhdGUgPSBhLmdldExhc3RNb2RpZmllZCgpOwogICAgICAgICAgICBsb25nIGJkYXRlID0gYi5nZXRMYXN0TW9kaWZpZWQoKTsKICAgICAgICAgICAgLy8gNjQ0OTMyNjogcG9saWN5IGZvciBiYWQgbGFzdE1vZGlmaWVkVGltZSBpbiBDbGFzc1JlYWRlcgogICAgICAgICAgICAvL2Fzc2VydCBhZGF0ZSA+PSAwICYmIGJkYXRlID49IDA7CiAgICAgICAgICAgIHJldHVybiAoYWRhdGUgPiBiZGF0ZSkgPyBhIDogYjsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBzcGVjaWZpZXMgdHlwZXMgb2YgZmlsZXMgdG8gYmUgcmVhZCB3aGVuIGZpbGxpbmcgaW4gYSBwYWNrYWdlIHN5bWJvbAogICAgICovCiAgICAvLyBOb3RlOiBvdmVycmlkZGVuIGJ5IEphdmFkb2NDbGFzc0ZpbmRlcgogICAgcHJvdGVjdGVkIEVudW1TZXQ8SmF2YUZpbGVPYmplY3QuS2luZD4gZ2V0UGFja2FnZUZpbGVLaW5kcygpIHsKICAgICAgICByZXR1cm4gRW51bVNldC5vZihKYXZhRmlsZU9iamVjdC5LaW5kLkNMQVNTLCBKYXZhRmlsZU9iamVjdC5LaW5kLlNPVVJDRSk7CiAgICB9CgogICAgLyoqCiAgICAgKiB0aGlzIGlzIHVzZWQgdG8gc3VwcG9ydCBqYXZhZG9jCiAgICAgKi8KICAgIHByb3RlY3RlZCB2b2lkIGV4dHJhRmlsZUFjdGlvbnMoUGFja2FnZVN5bWJvbCBwYWNrLCBKYXZhRmlsZU9iamVjdCBmZSkgewogICAgfQoKICAgIHByb3RlY3RlZCBMb2NhdGlvbiBjdXJyZW50TG9jOyAvLyBGSVhNRQoKICAgIHByaXZhdGUgYm9vbGVhbiB2ZXJib3NlUGF0aCA9IHRydWU7CgogICAgLy8gU2V0IHRvIHRydWUgd2hlbiB0aGUgY3VycmVudGx5IHNlbGVjdGVkIGZpbGUgc2hvdWxkIGJlIGtlcHQKICAgIHByaXZhdGUgYm9vbGVhbiBwcmVmZXJDdXJyZW50OwoKICAgIC8qKiBMb2FkIGRpcmVjdG9yeSBvZiBwYWNrYWdlIGludG8gbWVtYmVycyBzY29wZS4KICAgICAqLwogICAgcHJpdmF0ZSB2b2lkIGZpbGxJbihQYWNrYWdlU3ltYm9sIHApIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKHAubWVtYmVyc19maWVsZCA9PSBudWxsKQogICAgICAgICAgICBwLm1lbWJlcnNfZmllbGQgPSBXcml0ZWFibGVTY29wZS5jcmVhdGUocCk7CgogICAgICAgIE1vZHVsZVN5bWJvbCBtc3ltID0gcC5tb2RsZTsKCiAgICAgICAgQXNzZXJ0LmNoZWNrTm9uTnVsbChtc3ltLCBwOjp0b1N0cmluZyk7CgogICAgICAgIG1zeW0uY29tcGxldGUoKTsKCiAgICAgICAgaWYgKG1zeW0gPT0gc3ltcy5ub01vZHVsZSkgewogICAgICAgICAgICBwcmVmZXJDdXJyZW50ID0gZmFsc2U7CiAgICAgICAgICAgIGlmICh1c2VyUGF0aHNGaXJzdCkgewogICAgICAgICAgICAgICAgc2NhblVzZXJQYXRocyhwLCB0cnVlKTsKICAgICAgICAgICAgICAgIHByZWZlckN1cnJlbnQgPSB0cnVlOwogICAgICAgICAgICAgICAgc2NhblBsYXRmb3JtUGF0aChwKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHNjYW5QbGF0Zm9ybVBhdGgocCk7CiAgICAgICAgICAgICAgICBzY2FuVXNlclBhdGhzKHAsIHRydWUpOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmIChtc3ltLmNsYXNzTG9jYXRpb24gPT0gU3RhbmRhcmRMb2NhdGlvbi5DTEFTU19QQVRIKSB7CiAgICAgICAgICAgIHNjYW5Vc2VyUGF0aHMocCwgbXN5bS5zb3VyY2VMb2NhdGlvbiA9PSBTdGFuZGFyZExvY2F0aW9uLlNPVVJDRV9QQVRIKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzY2FuTW9kdWxlUGF0aHMocCwgbXN5bSk7CiAgICAgICAgfQogICAgfQoKICAgIC8vIFRPRE86IGZvciBub3csIHRoaXMgaXMgYSBtdWNoIHNpbXBsaWZpZWQgZm9ybSBvZiBzY2FuVXNlclBhdGhzCiAgICAvLyBhbmQgKGRlbGliZXJhdGVseSkgZG9lcyBub3QgZGVmYXVsdCBzb3VyY2VwYXRoIHRvIGNsYXNzcGF0aC4KICAgIC8vIEJ1dCwgd2UgbmVlZCB0byB0aGluayBhYm91dCByZXRhaW5pbmcgZXhpc3RpbmcgYmVoYXZpb3IgZm9yCiAgICAvLyAtY2xhc3NwYXRoIGFuZCAtc291cmNlcGF0aCBmb3Igc2luZ2xlIG1vZHVsZSBtb2RlLgogICAgLy8gT25lIHBsYXVzaWJsZSBzb2x1dGlvbiBpcyB0byBkZXRlY3QgaWYgdGhlIG1vZHVsZSdzIHNvdXJjZUxvY2F0aW9uCiAgICAvLyBpcyB0aGUgc2FtZSBhcyB0aGUgbW9kdWxlJ3MgY2xhc3NMb2NhdGlvbi4KICAgIHByaXZhdGUgdm9pZCBzY2FuTW9kdWxlUGF0aHMoUGFja2FnZVN5bWJvbCBwLCBNb2R1bGVTeW1ib2wgbXN5bSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICBTZXQ8SmF2YUZpbGVPYmplY3QuS2luZD4ga2luZHMgPSBnZXRQYWNrYWdlRmlsZUtpbmRzKCk7CgogICAgICAgIFNldDxKYXZhRmlsZU9iamVjdC5LaW5kPiBjbGFzc0tpbmRzID0gRW51bVNldC5jb3B5T2Yoa2luZHMpOwogICAgICAgIGNsYXNzS2luZHMucmVtb3ZlKEphdmFGaWxlT2JqZWN0LktpbmQuU09VUkNFKTsKICAgICAgICBib29sZWFuIHdhbnRDbGFzc0ZpbGVzID0gIWNsYXNzS2luZHMuaXNFbXB0eSgpOwoKICAgICAgICBTZXQ8SmF2YUZpbGVPYmplY3QuS2luZD4gc291cmNlS2luZHMgPSBFbnVtU2V0LmNvcHlPZihraW5kcyk7CiAgICAgICAgc291cmNlS2luZHMucmVtb3ZlKEphdmFGaWxlT2JqZWN0LktpbmQuQ0xBU1MpOwogICAgICAgIGJvb2xlYW4gd2FudFNvdXJjZUZpbGVzID0gIXNvdXJjZUtpbmRzLmlzRW1wdHkoKTsKCiAgICAgICAgU3RyaW5nIHBhY2thZ2VOYW1lID0gcC5mdWxsbmFtZS50b1N0cmluZygpOwoKICAgICAgICBMb2NhdGlvbiBjbGFzc0xvY24gPSBtc3ltLmNsYXNzTG9jYXRpb247CiAgICAgICAgTG9jYXRpb24gc291cmNlTG9jbiA9IG1zeW0uc291cmNlTG9jYXRpb247CiAgICAgICAgTG9jYXRpb24gcGF0Y2hMb2NuID0gbXN5bS5wYXRjaExvY2F0aW9uOwogICAgICAgIExvY2F0aW9uIHBhdGNoT3V0TG9jbiA9IG1zeW0ucGF0Y2hPdXRwdXRMb2NhdGlvbjsKCiAgICAgICAgYm9vbGVhbiBwcmV2UHJlZmVyQ3VycmVudCA9IHByZWZlckN1cnJlbnQ7CgogICAgICAgIHRyeSB7CiAgICAgICAgICAgIHByZWZlckN1cnJlbnQgPSBmYWxzZTsKICAgICAgICAgICAgaWYgKHdhbnRDbGFzc0ZpbGVzICYmIChwYXRjaE91dExvY24gIT0gbnVsbCkpIHsKICAgICAgICAgICAgICAgIGZpbGxJbihwLCBwYXRjaE91dExvY24sCiAgICAgICAgICAgICAgICAgICAgICAgbGlzdChwYXRjaE91dExvY24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2FnZU5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzc0tpbmRzKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCh3YW50Q2xhc3NGaWxlcyB8fCB3YW50U291cmNlRmlsZXMpICYmIChwYXRjaExvY24gIT0gbnVsbCkpIHsKICAgICAgICAgICAgICAgIFNldDxKYXZhRmlsZU9iamVjdC5LaW5kPiBjb21iaW5lZCA9IEVudW1TZXQubm9uZU9mKEphdmFGaWxlT2JqZWN0LktpbmQuY2xhc3MpOwogICAgICAgICAgICAgICAgY29tYmluZWQuYWRkQWxsKGNsYXNzS2luZHMpOwogICAgICAgICAgICAgICAgY29tYmluZWQuYWRkQWxsKHNvdXJjZUtpbmRzKTsKICAgICAgICAgICAgICAgIGZpbGxJbihwLCBwYXRjaExvY24sCiAgICAgICAgICAgICAgICAgICAgICAgbGlzdChwYXRjaExvY24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2FnZU5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21iaW5lZCkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHByZWZlckN1cnJlbnQgPSB0cnVlOwogICAgICAgICAgICBpZiAod2FudENsYXNzRmlsZXMgJiYgKGNsYXNzTG9jbiAhPSBudWxsKSkgewogICAgICAgICAgICAgICAgZmlsbEluKHAsIGNsYXNzTG9jbiwKICAgICAgICAgICAgICAgICAgICAgICBsaXN0KGNsYXNzTG9jbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWNrYWdlTmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzS2luZHMpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAod2FudFNvdXJjZUZpbGVzICYmIChzb3VyY2VMb2NuICE9IG51bGwpKSB7CiAgICAgICAgICAgICAgICBmaWxsSW4ocCwgc291cmNlTG9jbiwKICAgICAgICAgICAgICAgICAgICAgICBsaXN0KHNvdXJjZUxvY24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2FnZU5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzb3VyY2VLaW5kcykpOwogICAgICAgICAgICB9CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgcHJlZmVyQ3VycmVudCA9IHByZXZQcmVmZXJDdXJyZW50OwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFNjYW5zIGNsYXNzIHBhdGggYW5kIHNvdXJjZSBwYXRoIGZvciBmaWxlcyBpbiBnaXZlbiBwYWNrYWdlLgogICAgICovCiAgICBwcml2YXRlIHZvaWQgc2NhblVzZXJQYXRocyhQYWNrYWdlU3ltYm9sIHAsIGJvb2xlYW4gaW5jbHVkZVNvdXJjZVBhdGgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgU2V0PEphdmFGaWxlT2JqZWN0LktpbmQ+IGtpbmRzID0gZ2V0UGFja2FnZUZpbGVLaW5kcygpOwoKICAgICAgICBTZXQ8SmF2YUZpbGVPYmplY3QuS2luZD4gY2xhc3NLaW5kcyA9IEVudW1TZXQuY29weU9mKGtpbmRzKTsKICAgICAgICBjbGFzc0tpbmRzLnJlbW92ZShKYXZhRmlsZU9iamVjdC5LaW5kLlNPVVJDRSk7CiAgICAgICAgYm9vbGVhbiB3YW50Q2xhc3NGaWxlcyA9ICFjbGFzc0tpbmRzLmlzRW1wdHkoKTsKCiAgICAgICAgU2V0PEphdmFGaWxlT2JqZWN0LktpbmQ+IHNvdXJjZUtpbmRzID0gRW51bVNldC5jb3B5T2Yoa2luZHMpOwogICAgICAgIHNvdXJjZUtpbmRzLnJlbW92ZShKYXZhRmlsZU9iamVjdC5LaW5kLkNMQVNTKTsKICAgICAgICBib29sZWFuIHdhbnRTb3VyY2VGaWxlcyA9ICFzb3VyY2VLaW5kcy5pc0VtcHR5KCk7CgogICAgICAgIGJvb2xlYW4gaGF2ZVNvdXJjZVBhdGggPSBpbmNsdWRlU291cmNlUGF0aCAmJiBmaWxlTWFuYWdlci5oYXNMb2NhdGlvbihTT1VSQ0VfUEFUSCk7CgogICAgICAgIGlmICh2ZXJib3NlICYmIHZlcmJvc2VQYXRoKSB7CiAgICAgICAgICAgIGlmIChmaWxlTWFuYWdlciBpbnN0YW5jZW9mIFN0YW5kYXJkSmF2YUZpbGVNYW5hZ2VyKSB7CiAgICAgICAgICAgICAgICBTdGFuZGFyZEphdmFGaWxlTWFuYWdlciBmbSA9IChTdGFuZGFyZEphdmFGaWxlTWFuYWdlcilmaWxlTWFuYWdlcjsKICAgICAgICAgICAgICAgIGlmIChoYXZlU291cmNlUGF0aCAmJiB3YW50U291cmNlRmlsZXMpIHsKICAgICAgICAgICAgICAgICAgICBMaXN0PFBhdGg+IHBhdGggPSBMaXN0Lm5pbCgpOwogICAgICAgICAgICAgICAgICAgIGZvciAoUGF0aCBzb3VyY2VQYXRoIDogZm0uZ2V0TG9jYXRpb25Bc1BhdGhzKFNPVVJDRV9QQVRIKSkgewogICAgICAgICAgICAgICAgICAgICAgICBwYXRoID0gcGF0aC5wcmVwZW5kKHNvdXJjZVBhdGgpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBsb2cucHJpbnRWZXJib3NlKCJzb3VyY2VwYXRoIiwgcGF0aC5yZXZlcnNlKCkudG9TdHJpbmcoKSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHdhbnRTb3VyY2VGaWxlcykgewogICAgICAgICAgICAgICAgICAgIExpc3Q8UGF0aD4gcGF0aCA9IExpc3QubmlsKCk7CiAgICAgICAgICAgICAgICAgICAgZm9yIChQYXRoIGNsYXNzUGF0aCA6IGZtLmdldExvY2F0aW9uQXNQYXRocyhDTEFTU19QQVRIKSkgewogICAgICAgICAgICAgICAgICAgICAgICBwYXRoID0gcGF0aC5wcmVwZW5kKGNsYXNzUGF0aCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGxvZy5wcmludFZlcmJvc2UoInNvdXJjZXBhdGgiLCBwYXRoLnJldmVyc2UoKS50b1N0cmluZygpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICh3YW50Q2xhc3NGaWxlcykgewogICAgICAgICAgICAgICAgICAgIExpc3Q8UGF0aD4gcGF0aCA9IExpc3QubmlsKCk7CiAgICAgICAgICAgICAgICAgICAgZm9yIChQYXRoIHBsYXRmb3JtUGF0aCA6IGZtLmdldExvY2F0aW9uQXNQYXRocyhQTEFURk9STV9DTEFTU19QQVRIKSkgewogICAgICAgICAgICAgICAgICAgICAgICBwYXRoID0gcGF0aC5wcmVwZW5kKHBsYXRmb3JtUGF0aCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGZvciAoUGF0aCBjbGFzc1BhdGggOiBmbS5nZXRMb2NhdGlvbkFzUGF0aHMoQ0xBU1NfUEFUSCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcGF0aCA9IHBhdGgucHJlcGVuZChjbGFzc1BhdGgpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBsb2cucHJpbnRWZXJib3NlKCJjbGFzc3BhdGgiLCAgcGF0aC5yZXZlcnNlKCkudG9TdHJpbmcoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIFN0cmluZyBwYWNrYWdlTmFtZSA9IHAuZnVsbG5hbWUudG9TdHJpbmcoKTsKICAgICAgICBpZiAod2FudFNvdXJjZUZpbGVzICYmICFoYXZlU291cmNlUGF0aCkgewogICAgICAgICAgICBmaWxsSW4ocCwgQ0xBU1NfUEFUSCwKICAgICAgICAgICAgICAgICAgIGxpc3QoQ0xBU1NfUEFUSCwKICAgICAgICAgICAgICAgICAgICAgICAgcCwKICAgICAgICAgICAgICAgICAgICAgICAgcGFja2FnZU5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgIGtpbmRzKSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgaWYgKHdhbnRDbGFzc0ZpbGVzKQogICAgICAgICAgICAgICAgZmlsbEluKHAsIENMQVNTX1BBVEgsCiAgICAgICAgICAgICAgICAgICAgICAgbGlzdChDTEFTU19QQVRILAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhY2thZ2VOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3NLaW5kcykpOwogICAgICAgICAgICBpZiAod2FudFNvdXJjZUZpbGVzKQogICAgICAgICAgICAgICAgZmlsbEluKHAsIFNPVVJDRV9QQVRILAogICAgICAgICAgICAgICAgICAgICAgIGxpc3QoU09VUkNFX1BBVEgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2FnZU5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzb3VyY2VLaW5kcykpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFNjYW5zIHBsYXRmb3JtIGNsYXNzIHBhdGggZm9yIGZpbGVzIGluIGdpdmVuIHBhY2thZ2UuCiAgICAgKi8KICAgIHByaXZhdGUgdm9pZCBzY2FuUGxhdGZvcm1QYXRoKFBhY2thZ2VTeW1ib2wgcCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICBmaWxsSW4ocCwgUExBVEZPUk1fQ0xBU1NfUEFUSCwKICAgICAgICAgICAgICAgbGlzdChQTEFURk9STV9DTEFTU19QQVRILAogICAgICAgICAgICAgICAgICAgIHAsCiAgICAgICAgICAgICAgICAgICAgcC5mdWxsbmFtZS50b1N0cmluZygpLAogICAgICAgICAgICAgICAgICAgIGFsbG93U2lnRmlsZXMgPyBFbnVtU2V0Lm9mKEphdmFGaWxlT2JqZWN0LktpbmQuQ0xBU1MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSmF2YUZpbGVPYmplY3QuS2luZC5PVEhFUikKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogRW51bVNldC5vZihKYXZhRmlsZU9iamVjdC5LaW5kLkNMQVNTKSkpOwogICAgfQogICAgLy8gd2hlcmUKICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygiZmFsbHRocm91Z2giKQogICAgICAgIHByaXZhdGUgdm9pZCBmaWxsSW4oUGFja2FnZVN5bWJvbCBwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgTG9jYXRpb24gbG9jYXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBJdGVyYWJsZTxKYXZhRmlsZU9iamVjdD4gZmlsZXMpCiAgICAgICAgewogICAgICAgICAgICBjdXJyZW50TG9jID0gbG9jYXRpb247CiAgICAgICAgICAgIGZvciAoSmF2YUZpbGVPYmplY3QgZm8gOiBmaWxlcykgewogICAgICAgICAgICAgICAgc3dpdGNoIChmby5nZXRLaW5kKCkpIHsKICAgICAgICAgICAgICAgIGNhc2UgT1RIRVI6CiAgICAgICAgICAgICAgICAgICAgaWYgKCFpc1NpZ0ZpbGUobG9jYXRpb24sIGZvKSkgewogICAgICAgICAgICAgICAgICAgICAgICBleHRyYUZpbGVBY3Rpb25zKHAsIGZvKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIC8vaW50ZW50aW9uYWwgZmFsbC10aHJvdWdoOgogICAgICAgICAgICAgICAgY2FzZSBDTEFTUzoKICAgICAgICAgICAgICAgIGNhc2UgU09VUkNFOiB7CiAgICAgICAgICAgICAgICAgICAgLy8gVE9ETyBwYXNzIGJpbmFyeU5hbWUgdG8gaW5jbHVkZUNsYXNzRmlsZQogICAgICAgICAgICAgICAgICAgIFN0cmluZyBiaW5hcnlOYW1lID0gZmlsZU1hbmFnZXIuaW5mZXJCaW5hcnlOYW1lKGN1cnJlbnRMb2MsIGZvKTsKICAgICAgICAgICAgICAgICAgICBTdHJpbmcgc2ltcGxlTmFtZSA9IGJpbmFyeU5hbWUuc3Vic3RyaW5nKGJpbmFyeU5hbWUubGFzdEluZGV4T2YoIi4iKSArIDEpOwogICAgICAgICAgICAgICAgICAgIGlmIChTb3VyY2VWZXJzaW9uLmlzSWRlbnRpZmllcihzaW1wbGVOYW1lKSB8fAogICAgICAgICAgICAgICAgICAgICAgICBzaW1wbGVOYW1lLmVxdWFscygicGFja2FnZS1pbmZvIikpCiAgICAgICAgICAgICAgICAgICAgICAgIGluY2x1ZGVDbGFzc0ZpbGUocCwgZm8pOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICBleHRyYUZpbGVBY3Rpb25zKHAsIGZvKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgYm9vbGVhbiBpc1NpZ0ZpbGUoTG9jYXRpb24gbG9jYXRpb24sIEphdmFGaWxlT2JqZWN0IGZvKSB7CiAgICAgICAgICAgIHJldHVybiBsb2NhdGlvbiA9PSBQTEFURk9STV9DTEFTU19QQVRIICYmCiAgICAgICAgICAgICAgICAgICBhbGxvd1NpZ0ZpbGVzICYmCiAgICAgICAgICAgICAgICAgICBmby5nZXROYW1lKCkuZW5kc1dpdGgoIi5zaWciKTsKICAgICAgICB9CgogICAgICAgIEl0ZXJhYmxlPEphdmFGaWxlT2JqZWN0PiBsaXN0KExvY2F0aW9uIGxvY2F0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBhY2thZ2VTeW1ib2wgcCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcGFja2FnZU5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU2V0PEtpbmQ+IGtpbmRzKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgICAgICBJdGVyYWJsZTxKYXZhRmlsZU9iamVjdD4gbGlzdGVkID0gZmlsZU1hbmFnZXIubGlzdChsb2NhdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2FnZU5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVudW1TZXQuYWxsT2YoS2luZC5jbGFzcyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbHNlKTsKICAgICAgICAgICAgcmV0dXJuICgpIC0+IG5ldyBJdGVyYXRvcjxKYXZhRmlsZU9iamVjdD4oKSB7CiAgICAgICAgICAgICAgICBwcml2YXRlIGZpbmFsIEl0ZXJhdG9yPEphdmFGaWxlT2JqZWN0PiBvcmlnaW5hbCA9IGxpc3RlZC5pdGVyYXRvcigpOwogICAgICAgICAgICAgICAgcHJpdmF0ZSBKYXZhRmlsZU9iamVjdCBuZXh0OwogICAgICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNOZXh0KCkgewogICAgICAgICAgICAgICAgICAgIGlmIChuZXh0ID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKG9yaWdpbmFsLmhhc05leHQoKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgSmF2YUZpbGVPYmplY3QgZm8gPSBvcmlnaW5hbC5uZXh0KCk7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZvLmdldEtpbmQoKSAhPSBLaW5kLkNMQVNTICYmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm8uZ2V0S2luZCgpICE9IEtpbmQuU09VUkNFICYmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIWlzU2lnRmlsZShjdXJyZW50TG9jLCBmbykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwLmZsYWdzX2ZpZWxkIHw9IEZsYWdzLkhBU19SRVNPVVJDRTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoa2luZHMuY29udGFpbnMoZm8uZ2V0S2luZCgpKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5leHQgPSBmbzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV4dCAhPSBudWxsOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICAgICAgcHVibGljIEphdmFGaWxlT2JqZWN0IG5leHQoKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCFoYXNOZXh0KCkpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgICAgICAgICAgICAgSmF2YUZpbGVPYmplY3QgcmVzdWx0ID0gbmV4dDsKICAgICAgICAgICAgICAgICAgICBuZXh0ID0gbnVsbDsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgfTsKICAgICAgICB9CgogICAgLyoqCiAgICAgKiBVc2VkIGZvciBiYWQgY2xhc3MgZGVmaW5pdGlvbiBmaWxlcywgc3VjaCBhcyBiYWQgLmNsYXNzIGZpbGVzIG9yCiAgICAgKiBmb3IgLmphdmEgZmlsZXMgd2l0aCB1bmV4cGVjdGVkIHBhY2thZ2Ugb3IgY2xhc3MgbmFtZXMuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgQmFkQ2xhc3NGaWxlIGV4dGVuZHMgQ29tcGxldGlvbkZhaWx1cmUgewogICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDA7CgogICAgICAgIHB1YmxpYyBCYWRDbGFzc0ZpbGUoVHlwZVN5bWJvbCBzeW0sIEphdmFGaWxlT2JqZWN0IGZpbGUsIEpDRGlhZ25vc3RpYyBkaWFnLAogICAgICAgICAgICAgICAgSkNEaWFnbm9zdGljLkZhY3RvcnkgZGlhZ0ZhY3RvcnkpIHsKICAgICAgICAgICAgc3VwZXIoc3ltLCBjcmVhdGVCYWRDbGFzc0ZpbGVEaWFnbm9zdGljKGZpbGUsIGRpYWcsIGRpYWdGYWN0b3J5KSk7CiAgICAgICAgfQogICAgICAgIC8vIHdoZXJlCiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgSkNEaWFnbm9zdGljIGNyZWF0ZUJhZENsYXNzRmlsZURpYWdub3N0aWMoCiAgICAgICAgICAgICAgICBKYXZhRmlsZU9iamVjdCBmaWxlLCBKQ0RpYWdub3N0aWMgZGlhZywgSkNEaWFnbm9zdGljLkZhY3RvcnkgZGlhZ0ZhY3RvcnkpIHsKICAgICAgICAgICAgU3RyaW5nIGtleSA9IChmaWxlLmdldEtpbmQoKSA9PSBKYXZhRmlsZU9iamVjdC5LaW5kLlNPVVJDRQogICAgICAgICAgICAgICAgICAgICAgICA/ICJiYWQuc291cmNlLmZpbGUuaGVhZGVyIiA6ICJiYWQuY2xhc3MuZmlsZS5oZWFkZXIiKTsKICAgICAgICAgICAgcmV0dXJuIGRpYWdGYWN0b3J5LmZyYWdtZW50KGtleSwgZmlsZSwgZGlhZyk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgQmFkRW5jbG9zaW5nTWV0aG9kQXR0ciBleHRlbmRzIEJhZENsYXNzRmlsZSB7CiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMDsKCiAgICAgICAgcHVibGljIEJhZEVuY2xvc2luZ01ldGhvZEF0dHIoVHlwZVN5bWJvbCBzeW0sIEphdmFGaWxlT2JqZWN0IGZpbGUsIEpDRGlhZ25vc3RpYyBkaWFnLAogICAgICAgICAgICAgICAgSkNEaWFnbm9zdGljLkZhY3RvcnkgZGlhZ0ZhY3RvcnkpIHsKICAgICAgICAgICAgc3VwZXIoc3ltLCBmaWxlLCBkaWFnLCBkaWFnRmFjdG9yeSk7CiAgICAgICAgfQogICAgfQp9ClBLAwQKAAAIAAAGO6lK64fWrGiEAABohAAAJAAAAGNvbS9zdW4vdG9vbHMvamF2YWMvY29kZS9TeW10YWIuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMTk5OSwgMjAxNywgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGU7CgppbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb247CmltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbnM7CmltcG9ydCBqYXZhLnV0aWwuRW51bVNldDsKaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOwppbXBvcnQgamF2YS51dGlsLkxpbmtlZEhhc2hNYXA7CmltcG9ydCBqYXZhLnV0aWwuTWFwOwoKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC5FbGVtZW50VmlzaXRvcjsKCmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuU2NvcGUuV3JpdGVhYmxlU2NvcGU7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuU3ltYm9sLkNsYXNzU3ltYm9sOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlN5bWJvbC5Db21wbGV0ZXI7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuU3ltYm9sLkNvbXBsZXRpb25GYWlsdXJlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlN5bWJvbC5NZXRob2RTeW1ib2w7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuU3ltYm9sLk1vZHVsZVN5bWJvbDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5TeW1ib2wuUGFja2FnZVN5bWJvbDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5TeW1ib2wuVHlwZVN5bWJvbDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5TeW1ib2wuVmFyU3ltYm9sOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlR5cGUuQm90dG9tVHlwZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5UeXBlLkNsYXNzVHlwZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5UeXBlLkVycm9yVHlwZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5UeXBlLkpDUHJpbWl0aXZlVHlwZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5UeXBlLkpDVm9pZFR5cGU7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuVHlwZS5NZXRob2RUeXBlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlR5cGUuVW5rbm93blR5cGU7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvbXAuTW9kdWxlczsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5Bc3NlcnQ7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuQ29udGV4dDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5Db252ZXJ0OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkRlZmluZWRCeTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5EZWZpbmVkQnkuQXBpOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkl0ZXJhdG9yczsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5KYXZhY01lc3NhZ2VzOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkxpc3Q7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuTmFtZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5OYW1lczsKCmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLkZsYWdzLio7CmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLktpbmRzLktpbmQuKjsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuVHlwZVRhZy4qOwoKLyoqIEEgY2xhc3MgdGhhdCBkZWZpbmVzIGFsbCBwcmVkZWZpbmVkIGNvbnN0YW50cyBhbmQgb3BlcmF0b3JzCiAqICBhcyB3ZWxsIGFzIHNwZWNpYWwgY2xhc3NlcyBzdWNoIGFzIGphdmEubGFuZy5PYmplY3QsIHdoaWNoIG5lZWQKICogIHRvIGJlIGtub3duIHRvIHRoZSBjb21waWxlci4gQWxsIHN5bWJvbHMgYXJlIGhlbGQgaW4gaW5zdGFuY2UKICogIGZpZWxkcy4gVGhpcyBtYWtlcyBpdCBwb3NzaWJsZSB0byB3b3JrIGluIG11bHRpcGxlIGNvbmN1cnJlbnQKICogIHByb2plY3RzLCB3aGljaCBtaWdodCB1c2UgZGlmZmVyZW50IGNsYXNzIGZpbGVzIGZvciBsaWJyYXJ5IGNsYXNzZXMuCiAqCiAqICA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiAgSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93biByaXNrLgogKiAgVGhpcyBjb2RlIGFuZCBpdHMgaW50ZXJuYWwgaW50ZXJmYWNlcyBhcmUgc3ViamVjdCB0byBjaGFuZ2Ugb3IKICogIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj4KICovCnB1YmxpYyBjbGFzcyBTeW10YWIgewogICAgLyoqIFRoZSBjb250ZXh0IGtleSBmb3IgdGhlIHN5bWJvbCB0YWJsZS4gKi8KICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgQ29udGV4dC5LZXk8U3ltdGFiPiBzeW10YWJLZXkgPSBuZXcgQ29udGV4dC5LZXk8PigpOwoKICAgIC8qKiBHZXQgdGhlIHN5bWJvbCB0YWJsZSBpbnN0YW5jZS4gKi8KICAgIHB1YmxpYyBzdGF0aWMgU3ltdGFiIGluc3RhbmNlKENvbnRleHQgY29udGV4dCkgewogICAgICAgIFN5bXRhYiBpbnN0YW5jZSA9IGNvbnRleHQuZ2V0KHN5bXRhYktleSk7CiAgICAgICAgaWYgKGluc3RhbmNlID09IG51bGwpCiAgICAgICAgICAgIGluc3RhbmNlID0gbmV3IFN5bXRhYihjb250ZXh0KTsKICAgICAgICByZXR1cm4gaW5zdGFuY2U7CiAgICB9CgogICAgLyoqIEJ1aWx0aW4gdHlwZXMuCiAgICAgKi8KICAgIHB1YmxpYyBmaW5hbCBKQ1ByaW1pdGl2ZVR5cGUgYnl0ZVR5cGUgPSBuZXcgSkNQcmltaXRpdmVUeXBlKEJZVEUsIG51bGwpOwogICAgcHVibGljIGZpbmFsIEpDUHJpbWl0aXZlVHlwZSBjaGFyVHlwZSA9IG5ldyBKQ1ByaW1pdGl2ZVR5cGUoQ0hBUiwgbnVsbCk7CiAgICBwdWJsaWMgZmluYWwgSkNQcmltaXRpdmVUeXBlIHNob3J0VHlwZSA9IG5ldyBKQ1ByaW1pdGl2ZVR5cGUoU0hPUlQsIG51bGwpOwogICAgcHVibGljIGZpbmFsIEpDUHJpbWl0aXZlVHlwZSBpbnRUeXBlID0gbmV3IEpDUHJpbWl0aXZlVHlwZShJTlQsIG51bGwpOwogICAgcHVibGljIGZpbmFsIEpDUHJpbWl0aXZlVHlwZSBsb25nVHlwZSA9IG5ldyBKQ1ByaW1pdGl2ZVR5cGUoTE9ORywgbnVsbCk7CiAgICBwdWJsaWMgZmluYWwgSkNQcmltaXRpdmVUeXBlIGZsb2F0VHlwZSA9IG5ldyBKQ1ByaW1pdGl2ZVR5cGUoRkxPQVQsIG51bGwpOwogICAgcHVibGljIGZpbmFsIEpDUHJpbWl0aXZlVHlwZSBkb3VibGVUeXBlID0gbmV3IEpDUHJpbWl0aXZlVHlwZShET1VCTEUsIG51bGwpOwogICAgcHVibGljIGZpbmFsIEpDUHJpbWl0aXZlVHlwZSBib29sZWFuVHlwZSA9IG5ldyBKQ1ByaW1pdGl2ZVR5cGUoQk9PTEVBTiwgbnVsbCk7CiAgICBwdWJsaWMgZmluYWwgVHlwZSBib3RUeXBlID0gbmV3IEJvdHRvbVR5cGUoKTsKICAgIHB1YmxpYyBmaW5hbCBKQ1ZvaWRUeXBlIHZvaWRUeXBlID0gbmV3IEpDVm9pZFR5cGUoKTsKCiAgICBwcml2YXRlIGZpbmFsIE5hbWVzIG5hbWVzOwogICAgcHJpdmF0ZSBmaW5hbCBKYXZhY01lc3NhZ2VzIG1lc3NhZ2VzOwogICAgcHJpdmF0ZSBmaW5hbCBDb21wbGV0ZXIgaW5pdGlhbENvbXBsZXRlcjsKICAgIHByaXZhdGUgZmluYWwgQ29tcGxldGVyIG1vZHVsZUNvbXBsZXRlcjsKCiAgICAvKiogQSBzeW1ib2wgZm9yIHRoZSB1bm5hbWVkIG1vZHVsZS4KICAgICAqLwogICAgcHVibGljIGZpbmFsIE1vZHVsZVN5bWJvbCB1bm5hbWVkTW9kdWxlOwoKICAgIC8qKiBUaGUgZXJyb3IgbW9kdWxlLgogICAgICovCiAgICBwdWJsaWMgZmluYWwgTW9kdWxlU3ltYm9sIGVyck1vZHVsZTsKCiAgICAvKiogQSBzeW1ib2wgZm9yIG5vIG1vZHVsZSwgZm9yIHVzZSB3aXRoIC1zb3VyY2UgOCBvciBsZXNzCiAgICAgKi8KICAgIHB1YmxpYyBmaW5hbCBNb2R1bGVTeW1ib2wgbm9Nb2R1bGU7CgogICAgLyoqIEEgc3ltYm9sIGZvciB0aGUgcm9vdCBwYWNrYWdlLgogICAgICovCiAgICBwdWJsaWMgZmluYWwgUGFja2FnZVN5bWJvbCByb290UGFja2FnZTsKCiAgICAvKiogQSBzeW1ib2wgdGhhdCBzdGFuZHMgZm9yIGEgbWlzc2luZyBzeW1ib2wuCiAgICAgKi8KICAgIHB1YmxpYyBmaW5hbCBUeXBlU3ltYm9sIG5vU3ltYm9sOwoKICAgIC8qKiBUaGUgZXJyb3Igc3ltYm9sLgogICAgICovCiAgICBwdWJsaWMgZmluYWwgQ2xhc3NTeW1ib2wgZXJyU3ltYm9sOwoKICAgIC8qKiBUaGUgdW5rbm93biBzeW1ib2wuCiAgICAgKi8KICAgIHB1YmxpYyBmaW5hbCBDbGFzc1N5bWJvbCB1bmtub3duU3ltYm9sOwoKICAgIC8qKiBBIHZhbHVlIGZvciB0aGUgZXJyVHlwZSwgd2l0aCBhIG9yaWdpbmFsVHlwZSBvZiBub1R5cGUgKi8KICAgIHB1YmxpYyBmaW5hbCBUeXBlIGVyclR5cGU7CgogICAgLyoqIEEgdmFsdWUgZm9yIHRoZSB1bmtub3duIHR5cGUuICovCiAgICBwdWJsaWMgZmluYWwgVHlwZSB1bmtub3duVHlwZTsKCiAgICAvKiogVGhlIGJ1aWx0aW4gdHlwZSBvZiBhbGwgYXJyYXlzLiAqLwogICAgcHVibGljIGZpbmFsIENsYXNzU3ltYm9sIGFycmF5Q2xhc3M7CiAgICBwdWJsaWMgZmluYWwgTWV0aG9kU3ltYm9sIGFycmF5Q2xvbmVNZXRob2Q7CgogICAgLyoqIFZHSjogVGhlIChzaW5nbGV0b24pIHR5cGUgb2YgYWxsIGJvdW5kIHR5cGVzLiAqLwogICAgcHVibGljIGZpbmFsIENsYXNzU3ltYm9sIGJvdW5kQ2xhc3M7CgogICAgLyoqIFRoZSBidWlsdGluIHR5cGUgb2YgYWxsIG1ldGhvZHMuICovCiAgICBwdWJsaWMgZmluYWwgQ2xhc3NTeW1ib2wgbWV0aG9kQ2xhc3M7CgogICAgLyoqIEEgc3ltYm9sIGZvciB0aGUgamF2YS5iYXNlIG1vZHVsZS4KICAgICAqLwogICAgcHVibGljIGZpbmFsIE1vZHVsZVN5bWJvbCBqYXZhX2Jhc2U7CgogICAgLyoqIFByZWRlZmluZWQgdHlwZXMuCiAgICAgKi8KICAgIHB1YmxpYyBmaW5hbCBUeXBlIG9iamVjdFR5cGU7CiAgICBwdWJsaWMgZmluYWwgVHlwZSBvYmplY3RzVHlwZTsKICAgIHB1YmxpYyBmaW5hbCBUeXBlIGNsYXNzVHlwZTsKICAgIHB1YmxpYyBmaW5hbCBUeXBlIGNsYXNzTG9hZGVyVHlwZTsKICAgIHB1YmxpYyBmaW5hbCBUeXBlIHN0cmluZ1R5cGU7CiAgICBwdWJsaWMgZmluYWwgVHlwZSBzdHJpbmdCdWZmZXJUeXBlOwogICAgcHVibGljIGZpbmFsIFR5cGUgc3RyaW5nQnVpbGRlclR5cGU7CiAgICBwdWJsaWMgZmluYWwgVHlwZSBjbG9uZWFibGVUeXBlOwogICAgcHVibGljIGZpbmFsIFR5cGUgc2VyaWFsaXphYmxlVHlwZTsKICAgIHB1YmxpYyBmaW5hbCBUeXBlIHNlcmlhbGl6ZWRMYW1iZGFUeXBlOwogICAgcHVibGljIGZpbmFsIFR5cGUgdmFySGFuZGxlVHlwZTsKICAgIHB1YmxpYyBmaW5hbCBUeXBlIG1ldGhvZEhhbmRsZVR5cGU7CiAgICBwdWJsaWMgZmluYWwgVHlwZSBtZXRob2RIYW5kbGVMb29rdXBUeXBlOwogICAgcHVibGljIGZpbmFsIFR5cGUgbWV0aG9kVHlwZVR5cGU7CiAgICBwdWJsaWMgZmluYWwgVHlwZSBuYXRpdmVIZWFkZXJUeXBlOwogICAgcHVibGljIGZpbmFsIFR5cGUgdGhyb3dhYmxlVHlwZTsKICAgIHB1YmxpYyBmaW5hbCBUeXBlIGVycm9yVHlwZTsKICAgIHB1YmxpYyBmaW5hbCBUeXBlIGludGVycnVwdGVkRXhjZXB0aW9uVHlwZTsKICAgIHB1YmxpYyBmaW5hbCBUeXBlIGlsbGVnYWxBcmd1bWVudEV4Y2VwdGlvblR5cGU7CiAgICBwdWJsaWMgZmluYWwgVHlwZSBleGNlcHRpb25UeXBlOwogICAgcHVibGljIGZpbmFsIFR5cGUgcnVudGltZUV4Y2VwdGlvblR5cGU7CiAgICBwdWJsaWMgZmluYWwgVHlwZSBjbGFzc05vdEZvdW5kRXhjZXB0aW9uVHlwZTsKICAgIHB1YmxpYyBmaW5hbCBUeXBlIG5vQ2xhc3NEZWZGb3VuZEVycm9yVHlwZTsKICAgIHB1YmxpYyBmaW5hbCBUeXBlIG5vU3VjaEZpZWxkRXJyb3JUeXBlOwogICAgcHVibGljIGZpbmFsIFR5cGUgYXNzZXJ0aW9uRXJyb3JUeXBlOwogICAgcHVibGljIGZpbmFsIFR5cGUgY2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb25UeXBlOwogICAgcHVibGljIGZpbmFsIFR5cGUgYW5ub3RhdGlvblR5cGU7CiAgICBwdWJsaWMgZmluYWwgVHlwZVN5bWJvbCBlbnVtU3ltOwogICAgcHVibGljIGZpbmFsIFR5cGUgbGlzdFR5cGU7CiAgICBwdWJsaWMgZmluYWwgVHlwZSBjb2xsZWN0aW9uc1R5cGU7CiAgICBwdWJsaWMgZmluYWwgVHlwZSBjb21wYXJhYmxlVHlwZTsKICAgIHB1YmxpYyBmaW5hbCBUeXBlIGNvbXBhcmF0b3JUeXBlOwogICAgcHVibGljIGZpbmFsIFR5cGUgYXJyYXlzVHlwZTsKICAgIHB1YmxpYyBmaW5hbCBUeXBlIGl0ZXJhYmxlVHlwZTsKICAgIHB1YmxpYyBmaW5hbCBUeXBlIGl0ZXJhdG9yVHlwZTsKICAgIHB1YmxpYyBmaW5hbCBUeXBlIGFubm90YXRpb25UYXJnZXRUeXBlOwogICAgcHVibGljIGZpbmFsIFR5cGUgb3ZlcnJpZGVUeXBlOwogICAgcHVibGljIGZpbmFsIFR5cGUgcmV0ZW50aW9uVHlwZTsKICAgIHB1YmxpYyBmaW5hbCBUeXBlIGRlcHJlY2F0ZWRUeXBlOwogICAgcHVibGljIGZpbmFsIFR5cGUgc3VwcHJlc3NXYXJuaW5nc1R5cGU7CiAgICBwdWJsaWMgZmluYWwgVHlwZSBzdXBwbGllclR5cGU7CiAgICBwdWJsaWMgZmluYWwgVHlwZSBpbmhlcml0ZWRUeXBlOwogICAgcHVibGljIGZpbmFsIFR5cGUgcHJvZmlsZVR5cGU7CiAgICBwdWJsaWMgZmluYWwgVHlwZSBwcm9wcmlldGFyeVR5cGU7CiAgICBwdWJsaWMgZmluYWwgVHlwZSBzeXN0ZW1UeXBlOwogICAgcHVibGljIGZpbmFsIFR5cGUgYXV0b0Nsb3NlYWJsZVR5cGU7CiAgICBwdWJsaWMgZmluYWwgVHlwZSB0cnVzdE1lVHlwZTsKICAgIHB1YmxpYyBmaW5hbCBUeXBlIGxhbWJkYU1ldGFmYWN0b3J5OwogICAgcHVibGljIGZpbmFsIFR5cGUgc3RyaW5nQ29uY2F0RmFjdG9yeTsKICAgIHB1YmxpYyBmaW5hbCBUeXBlIHJlcGVhdGFibGVUeXBlOwogICAgcHVibGljIGZpbmFsIFR5cGUgZG9jdW1lbnRlZFR5cGU7CiAgICBwdWJsaWMgZmluYWwgVHlwZSBlbGVtZW50VHlwZVR5cGU7CiAgICBwdWJsaWMgZmluYWwgVHlwZSBmdW5jdGlvbmFsSW50ZXJmYWNlVHlwZTsKCiAgICAvKiogVGhlIHN5bWJvbCByZXByZXNlbnRpbmcgdGhlIGxlbmd0aCBmaWVsZCBvZiBhbiBhcnJheS4KICAgICAqLwogICAgcHVibGljIGZpbmFsIFZhclN5bWJvbCBsZW5ndGhWYXI7CgogICAgLyoqIFRoZSBzeW1ib2wgcmVwcmVzZW50aW5nIHRoZSBmaW5hbCBmaW5hbGl6ZSBtZXRob2Qgb24gZW51bXMgKi8KICAgIHB1YmxpYyBmaW5hbCBNZXRob2RTeW1ib2wgZW51bUZpbmFsRmluYWxpemU7CgogICAgLyoqIFRoZSBzeW1ib2wgcmVwcmVzZW50aW5nIHRoZSBjbG9zZSBtZXRob2Qgb24gVFdSIEF1dG9DbG9zZWFibGUgdHlwZSAqLwogICAgcHVibGljIGZpbmFsIE1ldGhvZFN5bWJvbCBhdXRvQ2xvc2VhYmxlQ2xvc2U7CgogICAgLyoqIFRoZSBwcmVkZWZpbmVkIHR5cGUgdGhhdCBiZWxvbmdzIHRvIGEgdGFnLgogICAgICovCiAgICBwdWJsaWMgZmluYWwgVHlwZVtdIHR5cGVPZlRhZyA9IG5ldyBUeXBlW1R5cGVUYWcuZ2V0VHlwZVRhZ0NvdW50KCldOwoKICAgIC8qKiBUaGUgbmFtZSBvZiB0aGUgY2xhc3MgdGhhdCBiZWxvbmdzIHRvIGEgYmFzaWMgdHlwZSB0YWcuCiAgICAgKi8KICAgIHB1YmxpYyBmaW5hbCBOYW1lW10gYm94ZWROYW1lID0gbmV3IE5hbWVbVHlwZVRhZy5nZXRUeXBlVGFnQ291bnQoKV07CgogICAgLyoqIEEgaGFzaHRhYmxlIGNvbnRhaW5pbmcgdGhlIGVuY291bnRlcmVkIHRvcC1sZXZlbCBhbmQgbWVtYmVyIGNsYXNzZXMsCiAgICAgKiAgaW5kZXhlZCBieSBmbGF0IG5hbWVzLiBUaGUgdGFibGUgZG9lcyBub3QgY29udGFpbiBsb2NhbCBjbGFzc2VzLgogICAgICogIEl0IHNob3VsZCBiZSB1cGRhdGVkIGZyb20gdGhlIG91dHNpZGUgdG8gcmVmbGVjdCBjbGFzc2VzIGRlZmluZWQKICAgICAqICBieSBjb21waWxlZCBzb3VyY2UgZmlsZXMuCiAgICAgKi8KICAgIHByaXZhdGUgZmluYWwgTWFwPE5hbWUsIE1hcDxNb2R1bGVTeW1ib2wsQ2xhc3NTeW1ib2w+PiBjbGFzc2VzID0gbmV3IEhhc2hNYXA8PigpOwoKICAgIC8qKiBBIGhhc2h0YWJsZSBjb250YWluaW5nIHRoZSBlbmNvdW50ZXJlZCBwYWNrYWdlcy4KICAgICAqICB0aGUgdGFibGUgc2hvdWxkIGJlIHVwZGF0ZWQgZnJvbSBvdXRzaWRlIHRvIHJlZmxlY3QgcGFja2FnZXMgZGVmaW5lZAogICAgICogIGJ5IGNvbXBpbGVkIHNvdXJjZSBmaWxlcy4KICAgICAqLwogICAgcHJpdmF0ZSBmaW5hbCBNYXA8TmFtZSwgTWFwPE1vZHVsZVN5bWJvbCxQYWNrYWdlU3ltYm9sPj4gcGFja2FnZXMgPSBuZXcgSGFzaE1hcDw+KCk7CgogICAgLyoqIEEgaGFzaHRhYmxlIGdpdmluZyB0aGUgZW5jb3VudGVyZWQgbW9kdWxlcy4KICAgICAqLwogICAgcHJpdmF0ZSBmaW5hbCBNYXA8TmFtZSwgTW9kdWxlU3ltYm9sPiBtb2R1bGVzID0gbmV3IExpbmtlZEhhc2hNYXA8PigpOwoKICAgIHB1YmxpYyB2b2lkIGluaXRUeXBlKFR5cGUgdHlwZSwgQ2xhc3NTeW1ib2wgYykgewogICAgICAgIHR5cGUudHN5bSA9IGM7CiAgICAgICAgdHlwZU9mVGFnW3R5cGUuZ2V0VGFnKCkub3JkaW5hbCgpXSA9IHR5cGU7CiAgICB9CgogICAgcHVibGljIHZvaWQgaW5pdFR5cGUoVHlwZSB0eXBlLCBTdHJpbmcgbmFtZSkgewogICAgICAgIGluaXRUeXBlKAogICAgICAgICAgICB0eXBlLAogICAgICAgICAgICBuZXcgQ2xhc3NTeW1ib2woCiAgICAgICAgICAgICAgICBQVUJMSUMsIG5hbWVzLmZyb21TdHJpbmcobmFtZSksIHR5cGUsIHJvb3RQYWNrYWdlKSk7CiAgICB9CgogICAgcHVibGljIHZvaWQgaW5pdFR5cGUoVHlwZSB0eXBlLCBTdHJpbmcgbmFtZSwgU3RyaW5nIGJuYW1lKSB7CiAgICAgICAgaW5pdFR5cGUodHlwZSwgbmFtZSk7CiAgICAgICAgYm94ZWROYW1lW3R5cGUuZ2V0VGFnKCkub3JkaW5hbCgpXSA9IG5hbWVzLmZyb21TdHJpbmcoImphdmEubGFuZy4iICsgYm5hbWUpOwogICAgfQoKICAgIC8qKiBUaGUgY2xhc3Mgc3ltYm9sIHRoYXQgb3ducyBhbGwgcHJlZGVmaW5lZCBzeW1ib2xzLgogICAgICovCiAgICBwdWJsaWMgZmluYWwgQ2xhc3NTeW1ib2wgcHJlZGVmQ2xhc3M7CgogICAgLyoqIEVudGVyIGEgY2xhc3MgaW50byBzeW1ib2wgdGFibGUuCiAgICAgKiAgQHBhcmFtIHMgVGhlIG5hbWUgb2YgdGhlIGNsYXNzLgogICAgICovCiAgICBwcml2YXRlIFR5cGUgZW50ZXJDbGFzcyhTdHJpbmcgcykgewogICAgICAgIHJldHVybiBlbnRlckNsYXNzKGphdmFfYmFzZSwgbmFtZXMuZnJvbVN0cmluZyhzKSkudHlwZTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCBzeW50aGVzaXplRW1wdHlJbnRlcmZhY2VJZk1pc3NpbmcoZmluYWwgVHlwZSB0eXBlKSB7CiAgICAgICAgZmluYWwgQ29tcGxldGVyIGNvbXBsZXRlciA9IHR5cGUudHN5bS5jb21wbGV0ZXI7CiAgICAgICAgdHlwZS50c3ltLmNvbXBsZXRlciA9IG5ldyBDb21wbGV0ZXIoKSB7CiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgdm9pZCBjb21wbGV0ZShTeW1ib2wgc3ltKSB0aHJvd3MgQ29tcGxldGlvbkZhaWx1cmUgewogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICBjb21wbGV0ZXIuY29tcGxldGUoc3ltKTsKICAgICAgICAgICAgICAgIH0gY2F0Y2ggKENvbXBsZXRpb25GYWlsdXJlIGUpIHsKICAgICAgICAgICAgICAgICAgICBzeW0uZmxhZ3NfZmllbGQgfD0gKFBVQkxJQyB8IElOVEVSRkFDRSk7CiAgICAgICAgICAgICAgICAgICAgKChDbGFzc1R5cGUpIHN5bS50eXBlKS5zdXBlcnR5cGVfZmllbGQgPSBvYmplY3RUeXBlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHVibGljIGJvb2xlYW4gaXNUZXJtaW5hbCgpIHsKICAgICAgICAgICAgICAgIHJldHVybiBjb21wbGV0ZXIuaXNUZXJtaW5hbCgpOwogICAgICAgICAgICB9CiAgICAgICAgfTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCBzeW50aGVzaXplQm94VHlwZUlmTWlzc2luZyhmaW5hbCBUeXBlIHR5cGUpIHsKICAgICAgICBDbGFzc1N5bWJvbCBzeW0gPSBlbnRlckNsYXNzKGphdmFfYmFzZSwgYm94ZWROYW1lW3R5cGUuZ2V0VGFnKCkub3JkaW5hbCgpXSk7CiAgICAgICAgZmluYWwgQ29tcGxldGVyIGNvbXBsZXRlciA9IHN5bS5jb21wbGV0ZXI7CiAgICAgICAgc3ltLmNvbXBsZXRlciA9IG5ldyBDb21wbGV0ZXIoKSB7CiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgdm9pZCBjb21wbGV0ZShTeW1ib2wgc3ltKSB0aHJvd3MgQ29tcGxldGlvbkZhaWx1cmUgewogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICBjb21wbGV0ZXIuY29tcGxldGUoc3ltKTsKICAgICAgICAgICAgICAgIH0gY2F0Y2ggKENvbXBsZXRpb25GYWlsdXJlIGUpIHsKICAgICAgICAgICAgICAgICAgICBzeW0uZmxhZ3NfZmllbGQgfD0gUFVCTElDOwogICAgICAgICAgICAgICAgICAgICgoQ2xhc3NUeXBlKSBzeW0udHlwZSkuc3VwZXJ0eXBlX2ZpZWxkID0gb2JqZWN0VHlwZTsKICAgICAgICAgICAgICAgICAgICBNZXRob2RTeW1ib2wgYm94TWV0aG9kID0KICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE1ldGhvZFN5bWJvbChQVUJMSUMgfCBTVEFUSUMsIG5hbWVzLnZhbHVlT2YsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE1ldGhvZFR5cGUoTGlzdC5vZih0eXBlKSwgc3ltLnR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTGlzdC5uaWwoKSwgbWV0aG9kQ2xhc3MpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ltKTsKICAgICAgICAgICAgICAgICAgICBzeW0ubWVtYmVycygpLmVudGVyKGJveE1ldGhvZCk7CiAgICAgICAgICAgICAgICAgICAgTWV0aG9kU3ltYm9sIHVuYm94TWV0aG9kID0KICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE1ldGhvZFN5bWJvbChQVUJMSUMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlLnRzeW0ubmFtZS5hcHBlbmQobmFtZXMuVmFsdWUpLCAvLyB4LmludFZhbHVlKCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBNZXRob2RUeXBlKExpc3QubmlsKCksIHR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTGlzdC5uaWwoKSwgbWV0aG9kQ2xhc3MpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ltKTsKICAgICAgICAgICAgICAgICAgICBzeW0ubWVtYmVycygpLmVudGVyKHVuYm94TWV0aG9kKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHB1YmxpYyBib29sZWFuIGlzVGVybWluYWwoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gY29tcGxldGVyLmlzVGVybWluYWwoKTsKICAgICAgICAgICAgfQogICAgICAgIH07CiAgICB9CgogICAgLy8gRW50ZXIgYSBzeW50aGV0aWMgY2xhc3MgdGhhdCBpcyB1c2VkIHRvIG1hcmsgY2xhc3NlcyBpbiBjdC5zeW0uCiAgICAvLyBUaGlzIGNsYXNzIGRvZXMgbm90IGhhdmUgYSBjbGFzcyBmaWxlLgogICAgcHJpdmF0ZSBUeXBlIGVudGVyU3ludGhldGljQW5ub3RhdGlvbihTdHJpbmcgbmFtZSkgewogICAgICAgIC8vIGZvciBub3csIGxlYXZlIHRoZSBtb2R1bGUgbnVsbCwgdG8gcHJldmVudCBwcm9ibGVtcyBmcm9tIHN5bnRoZXNpemluZyB0aGUKICAgICAgICAvLyBleGlzdGVuY2Ugb2YgYSBjbGFzcyBpbiBhbnkgc3BlY2lmaWMgbW9kdWxlLCBpbmNsdWRpbmcgbm9Nb2R1bGUKICAgICAgICBDbGFzc1R5cGUgdHlwZSA9IChDbGFzc1R5cGUpZW50ZXJDbGFzcyhqYXZhX2Jhc2UsIG5hbWVzLmZyb21TdHJpbmcobmFtZSkpLnR5cGU7CiAgICAgICAgQ2xhc3NTeW1ib2wgc3ltID0gKENsYXNzU3ltYm9sKXR5cGUudHN5bTsKICAgICAgICBzeW0uY29tcGxldGVyID0gQ29tcGxldGVyLk5VTExfQ09NUExFVEVSOwogICAgICAgIHN5bS5mbGFnc19maWVsZCA9IFBVQkxJQ3xBQ1lDTElDfEFOTk9UQVRJT058SU5URVJGQUNFOwogICAgICAgIHN5bS5lcmFzdXJlX2ZpZWxkID0gdHlwZTsKICAgICAgICBzeW0ubWVtYmVyc19maWVsZCA9IFdyaXRlYWJsZVNjb3BlLmNyZWF0ZShzeW0pOwogICAgICAgIHR5cGUudHlwYXJhbXNfZmllbGQgPSBMaXN0Lm5pbCgpOwogICAgICAgIHR5cGUuYWxscGFyYW1zX2ZpZWxkID0gTGlzdC5uaWwoKTsKICAgICAgICB0eXBlLnN1cGVydHlwZV9maWVsZCA9IGFubm90YXRpb25UeXBlOwogICAgICAgIHR5cGUuaW50ZXJmYWNlc19maWVsZCA9IExpc3QubmlsKCk7CiAgICAgICAgcmV0dXJuIHR5cGU7CiAgICB9CgogICAgLyoqIENvbnN0cnVjdG9yOyBlbnRlcnMgYWxsIHByZWRlZmluZWQgaWRlbnRpZmllcnMgYW5kIG9wZXJhdG9ycwogICAgICogIGludG8gc3ltYm9sIHRhYmxlLgogICAgICovCiAgICBwcm90ZWN0ZWQgU3ltdGFiKENvbnRleHQgY29udGV4dCkgdGhyb3dzIENvbXBsZXRpb25GYWlsdXJlIHsKICAgICAgICBjb250ZXh0LnB1dChzeW10YWJLZXksIHRoaXMpOwoKICAgICAgICBuYW1lcyA9IE5hbWVzLmluc3RhbmNlKGNvbnRleHQpOwoKICAgICAgICAvLyBDcmVhdGUgdGhlIHVua25vd24gdHlwZQogICAgICAgIHVua25vd25UeXBlID0gbmV3IFVua25vd25UeXBlKCk7CgogICAgICAgIG1lc3NhZ2VzID0gSmF2YWNNZXNzYWdlcy5pbnN0YW5jZShjb250ZXh0KTsKCiAgICAgICAgcm9vdFBhY2thZ2UgPSBuZXcgUGFja2FnZVN5bWJvbChuYW1lcy5lbXB0eSwgbnVsbCk7CgogICAgICAgIC8vIGNyZWF0ZSB0aGUgYmFzaWMgYnVpbHRpbiBzeW1ib2xzCiAgICAgICAgdW5uYW1lZE1vZHVsZSA9IG5ldyBNb2R1bGVTeW1ib2wobmFtZXMuZW1wdHksIG51bGwpIHsKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBkaXJlY3RpdmVzID0gTGlzdC5uaWwoKTsKICAgICAgICAgICAgICAgICAgICBleHBvcnRzID0gTGlzdC5uaWwoKTsKICAgICAgICAgICAgICAgICAgICBwcm92aWRlcyA9IExpc3QubmlsKCk7CiAgICAgICAgICAgICAgICAgICAgdXNlcyA9IExpc3QubmlsKCk7CiAgICAgICAgICAgICAgICAgICAgTW9kdWxlU3ltYm9sIGphdmFfYmFzZSA9IGVudGVyTW9kdWxlKG5hbWVzLmphdmFfYmFzZSk7CiAgICAgICAgICAgICAgICAgICAgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLkRpcmVjdGl2ZS5SZXF1aXJlc0RpcmVjdGl2ZSBkID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuRGlyZWN0aXZlLlJlcXVpcmVzRGlyZWN0aXZlKGphdmFfYmFzZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRW51bVNldC5vZihjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuRGlyZWN0aXZlLlJlcXVpcmVzRmxhZy5NQU5EQVRFRCkpOwogICAgICAgICAgICAgICAgICAgIHJlcXVpcmVzID0gTGlzdC5vZihkKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbWVzc2FnZXMuZ2V0TG9jYWxpemVkU3RyaW5nKCJjb21waWxlci5taXNjLnVubmFtZWQubW9kdWxlIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CiAgICAgICAgYWRkUm9vdFBhY2thZ2VGb3IodW5uYW1lZE1vZHVsZSk7CiAgICAgICAgdW5uYW1lZE1vZHVsZS5lbmNsb3NlZFBhY2thZ2VzID0gdW5uYW1lZE1vZHVsZS5lbmNsb3NlZFBhY2thZ2VzLnByZXBlbmQodW5uYW1lZE1vZHVsZS51bm5hbWVkUGFja2FnZSk7CgogICAgICAgIGVyck1vZHVsZSA9IG5ldyBNb2R1bGVTeW1ib2wobmFtZXMuZW1wdHksIG51bGwpIHsKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBkaXJlY3RpdmVzID0gTGlzdC5uaWwoKTsKICAgICAgICAgICAgICAgICAgICBleHBvcnRzID0gTGlzdC5uaWwoKTsKICAgICAgICAgICAgICAgICAgICBwcm92aWRlcyA9IExpc3QubmlsKCk7CiAgICAgICAgICAgICAgICAgICAgdXNlcyA9IExpc3QubmlsKCk7CiAgICAgICAgICAgICAgICAgICAgTW9kdWxlU3ltYm9sIGphdmFfYmFzZSA9IGVudGVyTW9kdWxlKG5hbWVzLmphdmFfYmFzZSk7CiAgICAgICAgICAgICAgICAgICAgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLkRpcmVjdGl2ZS5SZXF1aXJlc0RpcmVjdGl2ZSBkID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuRGlyZWN0aXZlLlJlcXVpcmVzRGlyZWN0aXZlKGphdmFfYmFzZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRW51bVNldC5vZihjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuRGlyZWN0aXZlLlJlcXVpcmVzRmxhZy5NQU5EQVRFRCkpOwogICAgICAgICAgICAgICAgICAgIHJlcXVpcmVzID0gTGlzdC5vZihkKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKICAgICAgICBhZGRSb290UGFja2FnZUZvcihlcnJNb2R1bGUpOwoKICAgICAgICBub01vZHVsZSA9IG5ldyBNb2R1bGVTeW1ib2wobmFtZXMuZW1wdHksIG51bGwpIHsKICAgICAgICAgICAgQE92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGlzTm9Nb2R1bGUoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH07CiAgICAgICAgYWRkUm9vdFBhY2thZ2VGb3Iobm9Nb2R1bGUpOwoKICAgICAgICBub1N5bWJvbCA9IG5ldyBUeXBlU3ltYm9sKE5JTCwgMCwgbmFtZXMuZW1wdHksIFR5cGUubm9UeXBlLCByb290UGFja2FnZSkgewogICAgICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICAgICAgICAgIHB1YmxpYyA8UiwgUD4gUiBhY2NlcHQoRWxlbWVudFZpc2l0b3I8UiwgUD4gdiwgUCBwKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdi52aXNpdFVua25vd24odGhpcywgcCk7CiAgICAgICAgICAgIH0KICAgICAgICB9OwoKICAgICAgICAvLyBjcmVhdGUgdGhlIGVycm9yIHN5bWJvbHMKICAgICAgICBlcnJTeW1ib2wgPSBuZXcgQ2xhc3NTeW1ib2woUFVCTElDfFNUQVRJQ3xBQ1lDTElDLCBuYW1lcy5hbnksIG51bGwsIHJvb3RQYWNrYWdlKTsKICAgICAgICBlcnJUeXBlID0gbmV3IEVycm9yVHlwZShlcnJTeW1ib2wsIFR5cGUubm9UeXBlKTsKCiAgICAgICAgdW5rbm93blN5bWJvbCA9IG5ldyBDbGFzc1N5bWJvbChQVUJMSUN8U1RBVElDfEFDWUNMSUMsIG5hbWVzLmZyb21TdHJpbmcoIjxhbnk/PiIpLCBudWxsLCByb290UGFja2FnZSk7CiAgICAgICAgdW5rbm93blN5bWJvbC5tZW1iZXJzX2ZpZWxkID0gbmV3IFNjb3BlLkVycm9yU2NvcGUodW5rbm93blN5bWJvbCk7CiAgICAgICAgdW5rbm93blN5bWJvbC50eXBlID0gdW5rbm93blR5cGU7CgogICAgICAgIC8vIGluaXRpYWxpemUgYnVpbHRpbiB0eXBlcwogICAgICAgIGluaXRUeXBlKGJ5dGVUeXBlLCAiYnl0ZSIsICJCeXRlIik7CiAgICAgICAgaW5pdFR5cGUoc2hvcnRUeXBlLCAic2hvcnQiLCAiU2hvcnQiKTsKICAgICAgICBpbml0VHlwZShjaGFyVHlwZSwgImNoYXIiLCAiQ2hhcmFjdGVyIik7CiAgICAgICAgaW5pdFR5cGUoaW50VHlwZSwgImludCIsICJJbnRlZ2VyIik7CiAgICAgICAgaW5pdFR5cGUobG9uZ1R5cGUsICJsb25nIiwgIkxvbmciKTsKICAgICAgICBpbml0VHlwZShmbG9hdFR5cGUsICJmbG9hdCIsICJGbG9hdCIpOwogICAgICAgIGluaXRUeXBlKGRvdWJsZVR5cGUsICJkb3VibGUiLCAiRG91YmxlIik7CiAgICAgICAgaW5pdFR5cGUoYm9vbGVhblR5cGUsICJib29sZWFuIiwgIkJvb2xlYW4iKTsKICAgICAgICBpbml0VHlwZSh2b2lkVHlwZSwgInZvaWQiLCAiVm9pZCIpOwogICAgICAgIGluaXRUeXBlKGJvdFR5cGUsICI8bnVsbHR5cGU+Iik7CiAgICAgICAgaW5pdFR5cGUoZXJyVHlwZSwgZXJyU3ltYm9sKTsKICAgICAgICBpbml0VHlwZSh1bmtub3duVHlwZSwgdW5rbm93blN5bWJvbCk7CgogICAgICAgIC8vIHRoZSBidWlsdGluIGNsYXNzIG9mIGFsbCBhcnJheXMKICAgICAgICBhcnJheUNsYXNzID0gbmV3IENsYXNzU3ltYm9sKFBVQkxJQ3xBQ1lDTElDLCBuYW1lcy5BcnJheSwgbm9TeW1ib2wpOwoKICAgICAgICAvLyBWR0oKICAgICAgICBib3VuZENsYXNzID0gbmV3IENsYXNzU3ltYm9sKFBVQkxJQ3xBQ1lDTElDLCBuYW1lcy5Cb3VuZCwgbm9TeW1ib2wpOwogICAgICAgIGJvdW5kQ2xhc3MubWVtYmVyc19maWVsZCA9IG5ldyBTY29wZS5FcnJvclNjb3BlKGJvdW5kQ2xhc3MpOwoKICAgICAgICAvLyB0aGUgYnVpbHRpbiBjbGFzcyBvZiBhbGwgbWV0aG9kcwogICAgICAgIG1ldGhvZENsYXNzID0gbmV3IENsYXNzU3ltYm9sKFBVQkxJQ3xBQ1lDTElDLCBuYW1lcy5NZXRob2QsIG5vU3ltYm9sKTsKICAgICAgICBtZXRob2RDbGFzcy5tZW1iZXJzX2ZpZWxkID0gbmV3IFNjb3BlLkVycm9yU2NvcGUoYm91bmRDbGFzcyk7CgogICAgICAgIC8vIENyZWF0ZSBjbGFzcyB0byBob2xkIGFsbCBwcmVkZWZpbmVkIGNvbnN0YW50cyBhbmQgb3BlcmF0aW9ucy4KICAgICAgICBwcmVkZWZDbGFzcyA9IG5ldyBDbGFzc1N5bWJvbChQVUJMSUN8QUNZQ0xJQywgbmFtZXMuZW1wdHksIHJvb3RQYWNrYWdlKTsKICAgICAgICBXcml0ZWFibGVTY29wZSBzY29wZSA9IFdyaXRlYWJsZVNjb3BlLmNyZWF0ZShwcmVkZWZDbGFzcyk7CiAgICAgICAgcHJlZGVmQ2xhc3MubWVtYmVyc19maWVsZCA9IHNjb3BlOwoKICAgICAgICAvLyBHZXQgdGhlIGluaXRpYWwgY29tcGxldGVyIGZvciBTeW1ib2xzIGZyb20gdGhlIENsYXNzRmluZGVyCiAgICAgICAgaW5pdGlhbENvbXBsZXRlciA9IENsYXNzRmluZGVyLmluc3RhbmNlKGNvbnRleHQpLmdldENvbXBsZXRlcigpOwogICAgICAgIHJvb3RQYWNrYWdlLm1lbWJlcnNfZmllbGQgPSBXcml0ZWFibGVTY29wZS5jcmVhdGUocm9vdFBhY2thZ2UpOwoKICAgICAgICAvLyBFbnRlciBzeW1ib2xzIGZvciBiYXNpYyB0eXBlcy4KICAgICAgICBzY29wZS5lbnRlcihieXRlVHlwZS50c3ltKTsKICAgICAgICBzY29wZS5lbnRlcihzaG9ydFR5cGUudHN5bSk7CiAgICAgICAgc2NvcGUuZW50ZXIoY2hhclR5cGUudHN5bSk7CiAgICAgICAgc2NvcGUuZW50ZXIoaW50VHlwZS50c3ltKTsKICAgICAgICBzY29wZS5lbnRlcihsb25nVHlwZS50c3ltKTsKICAgICAgICBzY29wZS5lbnRlcihmbG9hdFR5cGUudHN5bSk7CiAgICAgICAgc2NvcGUuZW50ZXIoZG91YmxlVHlwZS50c3ltKTsKICAgICAgICBzY29wZS5lbnRlcihib29sZWFuVHlwZS50c3ltKTsKICAgICAgICBzY29wZS5lbnRlcihlcnJUeXBlLnRzeW0pOwoKICAgICAgICAvLyBFbnRlciBzeW1ib2wgZm9yIHRoZSBlcnJTeW1ib2wKICAgICAgICBzY29wZS5lbnRlcihlcnJTeW1ib2wpOwoKICAgICAgICBTb3VyY2Ugc291cmNlID0gU291cmNlLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIGlmIChzb3VyY2UuYWxsb3dNb2R1bGVzKCkpIHsKICAgICAgICAgICAgamF2YV9iYXNlID0gZW50ZXJNb2R1bGUobmFtZXMuamF2YV9iYXNlKTsKICAgICAgICAgICAgLy9hdm9pZCBjb21wbGV0aW5nIGphdmEuYmFzZSBkdXJpbmcgdGhlIFN5bXRhYiBpbml0aWFsaXphdGlvbgogICAgICAgICAgICBqYXZhX2Jhc2UuY29tcGxldGVyID0gQ29tcGxldGVyLk5VTExfQ09NUExFVEVSOwogICAgICAgICAgICBqYXZhX2Jhc2UudmlzaWJsZVBhY2thZ2VzID0gQ29sbGVjdGlvbnMuZW1wdHlNYXAoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBqYXZhX2Jhc2UgPSBub01vZHVsZTsKICAgICAgICB9CgogICAgICAgIC8vIEdldCB0aGUgaW5pdGlhbCBjb21wbGV0ZXIgZm9yIE1vZHVsZVN5bWJvbHMgZnJvbSBNb2R1bGVzCiAgICAgICAgbW9kdWxlQ29tcGxldGVyID0gTW9kdWxlcy5pbnN0YW5jZShjb250ZXh0KS5nZXRDb21wbGV0ZXIoKTsKCiAgICAgICAgLy8gRW50ZXIgcHJlZGVmaW5lZCBjbGFzc2VzLiBBbGwgYXJlIGFzc3VtZWQgdG8gYmUgaW4gdGhlIGphdmEuYmFzZSBtb2R1bGUuCiAgICAgICAgb2JqZWN0VHlwZSA9IGVudGVyQ2xhc3MoImphdmEubGFuZy5PYmplY3QiKTsKICAgICAgICBvYmplY3RzVHlwZSA9IGVudGVyQ2xhc3MoImphdmEudXRpbC5PYmplY3RzIik7CiAgICAgICAgY2xhc3NUeXBlID0gZW50ZXJDbGFzcygiamF2YS5sYW5nLkNsYXNzIik7CiAgICAgICAgc3RyaW5nVHlwZSA9IGVudGVyQ2xhc3MoImphdmEubGFuZy5TdHJpbmciKTsKICAgICAgICBzdHJpbmdCdWZmZXJUeXBlID0gZW50ZXJDbGFzcygiamF2YS5sYW5nLlN0cmluZ0J1ZmZlciIpOwogICAgICAgIHN0cmluZ0J1aWxkZXJUeXBlID0gZW50ZXJDbGFzcygiamF2YS5sYW5nLlN0cmluZ0J1aWxkZXIiKTsKICAgICAgICBjbG9uZWFibGVUeXBlID0gZW50ZXJDbGFzcygiamF2YS5sYW5nLkNsb25lYWJsZSIpOwogICAgICAgIHRocm93YWJsZVR5cGUgPSBlbnRlckNsYXNzKCJqYXZhLmxhbmcuVGhyb3dhYmxlIik7CiAgICAgICAgc2VyaWFsaXphYmxlVHlwZSA9IGVudGVyQ2xhc3MoImphdmEuaW8uU2VyaWFsaXphYmxlIik7CiAgICAgICAgc2VyaWFsaXplZExhbWJkYVR5cGUgPSBlbnRlckNsYXNzKCJqYXZhLmxhbmcuaW52b2tlLlNlcmlhbGl6ZWRMYW1iZGEiKTsKICAgICAgICB2YXJIYW5kbGVUeXBlID0gZW50ZXJDbGFzcygiamF2YS5sYW5nLmludm9rZS5WYXJIYW5kbGUiKTsKICAgICAgICBtZXRob2RIYW5kbGVUeXBlID0gZW50ZXJDbGFzcygiamF2YS5sYW5nLmludm9rZS5NZXRob2RIYW5kbGUiKTsKICAgICAgICBtZXRob2RIYW5kbGVMb29rdXBUeXBlID0gZW50ZXJDbGFzcygiamF2YS5sYW5nLmludm9rZS5NZXRob2RIYW5kbGVzJExvb2t1cCIpOwogICAgICAgIG1ldGhvZFR5cGVUeXBlID0gZW50ZXJDbGFzcygiamF2YS5sYW5nLmludm9rZS5NZXRob2RUeXBlIik7CiAgICAgICAgZXJyb3JUeXBlID0gZW50ZXJDbGFzcygiamF2YS5sYW5nLkVycm9yIik7CiAgICAgICAgaWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uVHlwZSA9IGVudGVyQ2xhc3MoImphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24iKTsKICAgICAgICBpbnRlcnJ1cHRlZEV4Y2VwdGlvblR5cGUgPSBlbnRlckNsYXNzKCJqYXZhLmxhbmcuSW50ZXJydXB0ZWRFeGNlcHRpb24iKTsKICAgICAgICBleGNlcHRpb25UeXBlID0gZW50ZXJDbGFzcygiamF2YS5sYW5nLkV4Y2VwdGlvbiIpOwogICAgICAgIHJ1bnRpbWVFeGNlcHRpb25UeXBlID0gZW50ZXJDbGFzcygiamF2YS5sYW5nLlJ1bnRpbWVFeGNlcHRpb24iKTsKICAgICAgICBjbGFzc05vdEZvdW5kRXhjZXB0aW9uVHlwZSA9IGVudGVyQ2xhc3MoImphdmEubGFuZy5DbGFzc05vdEZvdW5kRXhjZXB0aW9uIik7CiAgICAgICAgbm9DbGFzc0RlZkZvdW5kRXJyb3JUeXBlID0gZW50ZXJDbGFzcygiamF2YS5sYW5nLk5vQ2xhc3NEZWZGb3VuZEVycm9yIik7CiAgICAgICAgbm9TdWNoRmllbGRFcnJvclR5cGUgPSBlbnRlckNsYXNzKCJqYXZhLmxhbmcuTm9TdWNoRmllbGRFcnJvciIpOwogICAgICAgIGFzc2VydGlvbkVycm9yVHlwZSA9IGVudGVyQ2xhc3MoImphdmEubGFuZy5Bc3NlcnRpb25FcnJvciIpOwogICAgICAgIGNsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uVHlwZSA9IGVudGVyQ2xhc3MoImphdmEubGFuZy5DbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiIpOwogICAgICAgIGFubm90YXRpb25UeXBlID0gZW50ZXJDbGFzcygiamF2YS5sYW5nLmFubm90YXRpb24uQW5ub3RhdGlvbiIpOwogICAgICAgIGNsYXNzTG9hZGVyVHlwZSA9IGVudGVyQ2xhc3MoImphdmEubGFuZy5DbGFzc0xvYWRlciIpOwogICAgICAgIGVudW1TeW0gPSBlbnRlckNsYXNzKGphdmFfYmFzZSwgbmFtZXMuamF2YV9sYW5nX0VudW0pOwogICAgICAgIGVudW1GaW5hbEZpbmFsaXplID0KICAgICAgICAgICAgbmV3IE1ldGhvZFN5bWJvbChQUk9URUNURUR8RklOQUx8SFlQT1RIRVRJQ0FMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVzLmZpbmFsaXplLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBNZXRob2RUeXBlKExpc3QubmlsKCksIHZvaWRUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExpc3QubmlsKCksIG1ldGhvZENsYXNzKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbnVtU3ltKTsKICAgICAgICBsaXN0VHlwZSA9IGVudGVyQ2xhc3MoImphdmEudXRpbC5MaXN0Iik7CiAgICAgICAgY29sbGVjdGlvbnNUeXBlID0gZW50ZXJDbGFzcygiamF2YS51dGlsLkNvbGxlY3Rpb25zIik7CiAgICAgICAgY29tcGFyYWJsZVR5cGUgPSBlbnRlckNsYXNzKCJqYXZhLmxhbmcuQ29tcGFyYWJsZSIpOwogICAgICAgIGNvbXBhcmF0b3JUeXBlID0gZW50ZXJDbGFzcygiamF2YS51dGlsLkNvbXBhcmF0b3IiKTsKICAgICAgICBhcnJheXNUeXBlID0gZW50ZXJDbGFzcygiamF2YS51dGlsLkFycmF5cyIpOwogICAgICAgIGl0ZXJhYmxlVHlwZSA9IGVudGVyQ2xhc3MoImphdmEubGFuZy5JdGVyYWJsZSIpOwogICAgICAgIGl0ZXJhdG9yVHlwZSA9IGVudGVyQ2xhc3MoImphdmEudXRpbC5JdGVyYXRvciIpOwogICAgICAgIGFubm90YXRpb25UYXJnZXRUeXBlID0gZW50ZXJDbGFzcygiamF2YS5sYW5nLmFubm90YXRpb24uVGFyZ2V0Iik7CiAgICAgICAgb3ZlcnJpZGVUeXBlID0gZW50ZXJDbGFzcygiamF2YS5sYW5nLk92ZXJyaWRlIik7CiAgICAgICAgcmV0ZW50aW9uVHlwZSA9IGVudGVyQ2xhc3MoImphdmEubGFuZy5hbm5vdGF0aW9uLlJldGVudGlvbiIpOwogICAgICAgIGRlcHJlY2F0ZWRUeXBlID0gZW50ZXJDbGFzcygiamF2YS5sYW5nLkRlcHJlY2F0ZWQiKTsKICAgICAgICBzdXBwcmVzc1dhcm5pbmdzVHlwZSA9IGVudGVyQ2xhc3MoImphdmEubGFuZy5TdXBwcmVzc1dhcm5pbmdzIik7CiAgICAgICAgc3VwcGxpZXJUeXBlID0gZW50ZXJDbGFzcygiamF2YS51dGlsLmZ1bmN0aW9uLlN1cHBsaWVyIik7CiAgICAgICAgaW5oZXJpdGVkVHlwZSA9IGVudGVyQ2xhc3MoImphdmEubGFuZy5hbm5vdGF0aW9uLkluaGVyaXRlZCIpOwogICAgICAgIHJlcGVhdGFibGVUeXBlID0gZW50ZXJDbGFzcygiamF2YS5sYW5nLmFubm90YXRpb24uUmVwZWF0YWJsZSIpOwogICAgICAgIGRvY3VtZW50ZWRUeXBlID0gZW50ZXJDbGFzcygiamF2YS5sYW5nLmFubm90YXRpb24uRG9jdW1lbnRlZCIpOwogICAgICAgIGVsZW1lbnRUeXBlVHlwZSA9IGVudGVyQ2xhc3MoImphdmEubGFuZy5hbm5vdGF0aW9uLkVsZW1lbnRUeXBlIik7CiAgICAgICAgc3lzdGVtVHlwZSA9IGVudGVyQ2xhc3MoImphdmEubGFuZy5TeXN0ZW0iKTsKICAgICAgICBhdXRvQ2xvc2VhYmxlVHlwZSA9IGVudGVyQ2xhc3MoImphdmEubGFuZy5BdXRvQ2xvc2VhYmxlIik7CiAgICAgICAgYXV0b0Nsb3NlYWJsZUNsb3NlID0gbmV3IE1ldGhvZFN5bWJvbChQVUJMSUMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZXMuY2xvc2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE1ldGhvZFR5cGUoTGlzdC5uaWwoKSwgdm9pZFR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTGlzdC5vZihleGNlcHRpb25UeXBlKSwgbWV0aG9kQ2xhc3MpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF1dG9DbG9zZWFibGVUeXBlLnRzeW0pOwogICAgICAgIHRydXN0TWVUeXBlID0gZW50ZXJDbGFzcygiamF2YS5sYW5nLlNhZmVWYXJhcmdzIik7CiAgICAgICAgbmF0aXZlSGVhZGVyVHlwZSA9IGVudGVyQ2xhc3MoImphdmEubGFuZy5hbm5vdGF0aW9uLk5hdGl2ZSIpOwogICAgICAgIGxhbWJkYU1ldGFmYWN0b3J5ID0gZW50ZXJDbGFzcygiamF2YS5sYW5nLmludm9rZS5MYW1iZGFNZXRhZmFjdG9yeSIpOwogICAgICAgIHN0cmluZ0NvbmNhdEZhY3RvcnkgPSBlbnRlckNsYXNzKCJqYXZhLmxhbmcuaW52b2tlLlN0cmluZ0NvbmNhdEZhY3RvcnkiKTsKICAgICAgICBmdW5jdGlvbmFsSW50ZXJmYWNlVHlwZSA9IGVudGVyQ2xhc3MoImphdmEubGFuZy5GdW5jdGlvbmFsSW50ZXJmYWNlIik7CgogICAgICAgIHN5bnRoZXNpemVFbXB0eUludGVyZmFjZUlmTWlzc2luZyhhdXRvQ2xvc2VhYmxlVHlwZSk7CiAgICAgICAgc3ludGhlc2l6ZUVtcHR5SW50ZXJmYWNlSWZNaXNzaW5nKGNsb25lYWJsZVR5cGUpOwogICAgICAgIHN5bnRoZXNpemVFbXB0eUludGVyZmFjZUlmTWlzc2luZyhzZXJpYWxpemFibGVUeXBlKTsKICAgICAgICBzeW50aGVzaXplRW1wdHlJbnRlcmZhY2VJZk1pc3NpbmcobGFtYmRhTWV0YWZhY3RvcnkpOwogICAgICAgIHN5bnRoZXNpemVFbXB0eUludGVyZmFjZUlmTWlzc2luZyhzZXJpYWxpemVkTGFtYmRhVHlwZSk7CiAgICAgICAgc3ludGhlc2l6ZUVtcHR5SW50ZXJmYWNlSWZNaXNzaW5nKHN0cmluZ0NvbmNhdEZhY3RvcnkpOwogICAgICAgIHN5bnRoZXNpemVCb3hUeXBlSWZNaXNzaW5nKGRvdWJsZVR5cGUpOwogICAgICAgIHN5bnRoZXNpemVCb3hUeXBlSWZNaXNzaW5nKGZsb2F0VHlwZSk7CiAgICAgICAgc3ludGhlc2l6ZUJveFR5cGVJZk1pc3Npbmcodm9pZFR5cGUpOwoKICAgICAgICAvLyBFbnRlciBhIHN5bnRoZXRpYyBjbGFzcyB0aGF0IGlzIHVzZWQgdG8gbWFyayBpbnRlcm5hbAogICAgICAgIC8vIHByb3ByaWV0YXJ5IGNsYXNzZXMgaW4gY3Quc3ltLiAgVGhpcyBjbGFzcyBkb2VzIG5vdCBoYXZlIGEKICAgICAgICAvLyBjbGFzcyBmaWxlLgogICAgICAgIHByb3ByaWV0YXJ5VHlwZSA9IGVudGVyU3ludGhldGljQW5ub3RhdGlvbigic3VuLlByb3ByaWV0YXJ5K0Fubm90YXRpb24iKTsKCiAgICAgICAgLy8gRW50ZXIgYSBzeW50aGV0aWMgY2xhc3MgdGhhdCBpcyB1c2VkIHRvIHByb3ZpZGUgcHJvZmlsZSBpbmZvIGZvcgogICAgICAgIC8vIGNsYXNzZXMgaW4gY3Quc3ltLiAgVGhpcyBjbGFzcyBkb2VzIG5vdCBoYXZlIGEgY2xhc3MgZmlsZS4KICAgICAgICBwcm9maWxlVHlwZSA9IGVudGVyU3ludGhldGljQW5ub3RhdGlvbigiamRrLlByb2ZpbGUrQW5ub3RhdGlvbiIpOwogICAgICAgIE1ldGhvZFN5bWJvbCBtID0gbmV3IE1ldGhvZFN5bWJvbChQVUJMSUMgfCBBQlNUUkFDVCwgbmFtZXMudmFsdWUsIGludFR5cGUsIHByb2ZpbGVUeXBlLnRzeW0pOwogICAgICAgIHByb2ZpbGVUeXBlLnRzeW0ubWVtYmVycygpLmVudGVyKG0pOwoKICAgICAgICAvLyBFbnRlciBhIGNsYXNzIGZvciBhcnJheXMuCiAgICAgICAgLy8gVGhlIGNsYXNzIGltcGxlbWVudHMgamF2YS5sYW5nLkNsb25lYWJsZSBhbmQgamF2YS5pby5TZXJpYWxpemFibGUuCiAgICAgICAgLy8gSXQgaGFzIGEgZmluYWwgbGVuZ3RoIGZpZWxkIGFuZCBhIGNsb25lIG1ldGhvZC4KICAgICAgICBDbGFzc1R5cGUgYXJyYXlDbGFzc1R5cGUgPSAoQ2xhc3NUeXBlKWFycmF5Q2xhc3MudHlwZTsKICAgICAgICBhcnJheUNsYXNzVHlwZS5zdXBlcnR5cGVfZmllbGQgPSBvYmplY3RUeXBlOwogICAgICAgIGFycmF5Q2xhc3NUeXBlLmludGVyZmFjZXNfZmllbGQgPSBMaXN0Lm9mKGNsb25lYWJsZVR5cGUsIHNlcmlhbGl6YWJsZVR5cGUpOwogICAgICAgIGFycmF5Q2xhc3MubWVtYmVyc19maWVsZCA9IFdyaXRlYWJsZVNjb3BlLmNyZWF0ZShhcnJheUNsYXNzKTsKICAgICAgICBsZW5ndGhWYXIgPSBuZXcgVmFyU3ltYm9sKAogICAgICAgICAgICBQVUJMSUMgfCBGSU5BTCwKICAgICAgICAgICAgbmFtZXMubGVuZ3RoLAogICAgICAgICAgICBpbnRUeXBlLAogICAgICAgICAgICBhcnJheUNsYXNzKTsKICAgICAgICBhcnJheUNsYXNzLm1lbWJlcnMoKS5lbnRlcihsZW5ndGhWYXIpOwogICAgICAgIGFycmF5Q2xvbmVNZXRob2QgPSBuZXcgTWV0aG9kU3ltYm9sKAogICAgICAgICAgICBQVUJMSUMsCiAgICAgICAgICAgIG5hbWVzLmNsb25lLAogICAgICAgICAgICBuZXcgTWV0aG9kVHlwZShMaXN0Lm5pbCgpLCBvYmplY3RUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0Lm5pbCgpLCBtZXRob2RDbGFzcyksCiAgICAgICAgICAgIGFycmF5Q2xhc3MpOwogICAgICAgIGFycmF5Q2xhc3MubWVtYmVycygpLmVudGVyKGFycmF5Q2xvbmVNZXRob2QpOwoKICAgICAgICBpZiAoamF2YV9iYXNlICE9IG5vTW9kdWxlKQogICAgICAgICAgICBqYXZhX2Jhc2UuY29tcGxldGVyID0gbW9kdWxlQ29tcGxldGVyOjpjb21wbGV0ZTsgLy9ib290c3RyYXAgaXNzdWVzCgogICAgfQoKICAgIC8qKiBEZWZpbmUgYSBuZXcgY2xhc3MgZ2l2ZW4gaXRzIG5hbWUgYW5kIG93bmVyLgogICAgICovCiAgICBwdWJsaWMgQ2xhc3NTeW1ib2wgZGVmaW5lQ2xhc3MoTmFtZSBuYW1lLCBTeW1ib2wgb3duZXIpIHsKICAgICAgICBDbGFzc1N5bWJvbCBjID0gbmV3IENsYXNzU3ltYm9sKDAsIG5hbWUsIG93bmVyKTsKICAgICAgICBjLmNvbXBsZXRlciA9IGluaXRpYWxDb21wbGV0ZXI7CiAgICAgICAgcmV0dXJuIGM7CiAgICB9CgogICAgLyoqIENyZWF0ZSBhIG5ldyB0b3BsZXZlbCBvciBtZW1iZXIgY2xhc3Mgc3ltYm9sIHdpdGggZ2l2ZW4gbmFtZQogICAgICogIGFuZCBvd25lciBhbmQgZW50ZXIgaW4gYGNsYXNzZXMnIHVubGVzcyBhbHJlYWR5IHRoZXJlLgogICAgICovCiAgICBwdWJsaWMgQ2xhc3NTeW1ib2wgZW50ZXJDbGFzcyhNb2R1bGVTeW1ib2wgbXN5bSwgTmFtZSBuYW1lLCBUeXBlU3ltYm9sIG93bmVyKSB7CiAgICAgICAgQXNzZXJ0LmNoZWNrTm9uTnVsbChtc3ltKTsKICAgICAgICBOYW1lIGZsYXRuYW1lID0gVHlwZVN5bWJvbC5mb3JtRmxhdE5hbWUobmFtZSwgb3duZXIpOwogICAgICAgIENsYXNzU3ltYm9sIGMgPSBnZXRDbGFzcyhtc3ltLCBmbGF0bmFtZSk7CiAgICAgICAgaWYgKGMgPT0gbnVsbCkgewogICAgICAgICAgICBjID0gZGVmaW5lQ2xhc3MobmFtZSwgb3duZXIpOwogICAgICAgICAgICBkb0VudGVyQ2xhc3MobXN5bSwgYyk7CiAgICAgICAgfSBlbHNlIGlmICgoYy5uYW1lICE9IG5hbWUgfHwgYy5vd25lciAhPSBvd25lcikgJiYgb3duZXIua2luZCA9PSBUWVAgJiYgYy5vd25lci5raW5kID09IFBDSykgewogICAgICAgICAgICAvLyByZWFzc2lnbiBmaWVsZHMgb2YgY2xhc3NlcyB0aGF0IG1pZ2h0IGhhdmUgYmVlbiBsb2FkZWQgd2l0aAogICAgICAgICAgICAvLyB0aGVpciBmbGF0IG5hbWVzLgogICAgICAgICAgICBjLm93bmVyLm1lbWJlcnMoKS5yZW1vdmUoYyk7CiAgICAgICAgICAgIGMubmFtZSA9IG5hbWU7CiAgICAgICAgICAgIGMub3duZXIgPSBvd25lcjsKICAgICAgICAgICAgYy5mdWxsbmFtZSA9IENsYXNzU3ltYm9sLmZvcm1GdWxsTmFtZShuYW1lLCBvd25lcik7CiAgICAgICAgfQogICAgICAgIHJldHVybiBjOwogICAgfQoKICAgIHB1YmxpYyBDbGFzc1N5bWJvbCBnZXRDbGFzcyhNb2R1bGVTeW1ib2wgbXN5bSwgTmFtZSBmbGF0TmFtZSkgewogICAgICAgIEFzc2VydC5jaGVja05vbk51bGwobXN5bSwgZmxhdE5hbWU6OnRvU3RyaW5nKTsKICAgICAgICByZXR1cm4gY2xhc3Nlcy5nZXRPckRlZmF1bHQoZmxhdE5hbWUsIENvbGxlY3Rpb25zLmVtcHR5TWFwKCkpLmdldChtc3ltKTsKICAgIH0KCiAgICBwdWJsaWMgUGFja2FnZVN5bWJvbCBsb29rdXBQYWNrYWdlKE1vZHVsZVN5bWJvbCBtc3ltLCBOYW1lIGZsYXROYW1lKSB7CiAgICAgICAgQXNzZXJ0LmNoZWNrTm9uTnVsbChtc3ltKTsKCiAgICAgICAgaWYgKGZsYXROYW1lLmlzRW1wdHkoKSkgewogICAgICAgICAgICAvL3VubmFtZWQgcGFja2FnZXMgb25seSBmcm9tIHRoZSBjdXJyZW50IG1vZHVsZSAtIHZpc2libGVQYWNrYWdlcyBjb250YWlucyAqcm9vdCogcGFja2FnZSwgbm90IHVubmFtZWQgcGFja2FnZSEKICAgICAgICAgICAgcmV0dXJuIG1zeW0udW5uYW1lZFBhY2thZ2U7CiAgICAgICAgfQoKICAgICAgICBpZiAobXN5bSA9PSBub01vZHVsZSkgewogICAgICAgICAgICByZXR1cm4gZW50ZXJQYWNrYWdlKG1zeW0sIGZsYXROYW1lKTsKICAgICAgICB9CgogICAgICAgIG1zeW0uY29tcGxldGUoKTsKCiAgICAgICAgUGFja2FnZVN5bWJvbCBwYWNrOwoKICAgICAgICBwYWNrID0gbXN5bS52aXNpYmxlUGFja2FnZXMuZ2V0KGZsYXROYW1lKTsKCiAgICAgICAgaWYgKHBhY2sgIT0gbnVsbCkKICAgICAgICAgICAgcmV0dXJuIHBhY2s7CgogICAgICAgIHBhY2sgPSBnZXRQYWNrYWdlKG1zeW0sIGZsYXROYW1lKTsKCiAgICAgICAgaWYgKHBhY2sgIT0gbnVsbCAmJiBwYWNrLmV4aXN0cygpKQogICAgICAgICAgICByZXR1cm4gcGFjazsKCiAgICAgICAgYm9vbGVhbiBkZXBlbmRzT25Vbm5hbWVkID0gbXN5bS5yZXF1aXJlcyAhPSBudWxsICYmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXN5bS5yZXF1aXJlcy5zdHJlYW0oKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAubWFwKHJkIC0+IHJkLm1vZHVsZSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmFueU1hdGNoKG1vZCAtPiBtb2QgPT0gdW5uYW1lZE1vZHVsZSk7CgogICAgICAgIGlmIChkZXBlbmRzT25Vbm5hbWVkKSB7CiAgICAgICAgICAgIC8vbXN5bXMgZGVwZW5kcyBvbiB0aGUgdW5uYW1lZCBtb2R1bGUsIGZvciB3aGljaCB3ZSBnZW5lcmFsbHkgZG9uJ3Qga25vdwogICAgICAgICAgICAvL3RoZSBsaXN0IG9mIHBhY2thZ2VzIGl0ICJleHBvcnRzIiBhaGVhZCBvZiB0aW1lLiBTbyB0cnkgdG8gbG9va3VwIHRoZSBwYWNrYWdlIGluIHRoZQogICAgICAgICAgICAvL2N1cnJlbnQgbW9kdWxlLCBhbmQgaW4gdGhlIHVubmFtZWQgbW9kdWxlIGFuZCBzZWUgaWYgaXQgZXhpc3RzIGluIG9uZSBvZiB0aGVtCiAgICAgICAgICAgIFBhY2thZ2VTeW1ib2wgdW5uYW1lZFBhY2sgPSBnZXRQYWNrYWdlKHVubmFtZWRNb2R1bGUsIGZsYXROYW1lKTsKCiAgICAgICAgICAgIGlmICh1bm5hbWVkUGFjayAhPSBudWxsICYmIHVubmFtZWRQYWNrLmV4aXN0cygpKSB7CiAgICAgICAgICAgICAgICBtc3ltLnZpc2libGVQYWNrYWdlcy5wdXQodW5uYW1lZFBhY2suZnVsbG5hbWUsIHVubmFtZWRQYWNrKTsKICAgICAgICAgICAgICAgIHJldHVybiB1bm5hbWVkUGFjazsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcGFjayA9IGVudGVyUGFja2FnZShtc3ltLCBmbGF0TmFtZSk7CiAgICAgICAgICAgIHBhY2suY29tcGxldGUoKTsKICAgICAgICAgICAgaWYgKHBhY2suZXhpc3RzKCkpCiAgICAgICAgICAgICAgICByZXR1cm4gcGFjazsKCiAgICAgICAgICAgIHVubmFtZWRQYWNrID0gZW50ZXJQYWNrYWdlKHVubmFtZWRNb2R1bGUsIGZsYXROYW1lKTsKICAgICAgICAgICAgdW5uYW1lZFBhY2suY29tcGxldGUoKTsKICAgICAgICAgICAgaWYgKHVubmFtZWRQYWNrLmV4aXN0cygpKSB7CiAgICAgICAgICAgICAgICBtc3ltLnZpc2libGVQYWNrYWdlcy5wdXQodW5uYW1lZFBhY2suZnVsbG5hbWUsIHVubmFtZWRQYWNrKTsKICAgICAgICAgICAgICAgIHJldHVybiB1bm5hbWVkUGFjazsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIHBhY2s7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gZW50ZXJQYWNrYWdlKG1zeW0sIGZsYXROYW1lKTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBNYXA8TW9kdWxlU3ltYm9sLCBDbGFzc1N5bWJvbD4gRU1QVFkgPSBuZXcgSGFzaE1hcDw+KCk7CgogICAgcHVibGljIHZvaWQgcmVtb3ZlQ2xhc3MoTW9kdWxlU3ltYm9sIG1zeW0sIE5hbWUgZmxhdE5hbWUpIHsKICAgICAgICBjbGFzc2VzLmdldE9yRGVmYXVsdChmbGF0TmFtZSwgRU1QVFkpLnJlbW92ZShtc3ltKTsKICAgIH0KCiAgICBwdWJsaWMgSXRlcmFibGU8Q2xhc3NTeW1ib2w+IGdldEFsbENsYXNzZXMoKSB7CiAgICAgICAgcmV0dXJuICgpIC0+IEl0ZXJhdG9ycy5jcmVhdGVDb21wb3VuZEl0ZXJhdG9yKGNsYXNzZXMudmFsdWVzKCksIHYgLT4gdi52YWx1ZXMoKS5pdGVyYXRvcigpKTsKICAgIH0KCiAgICBwcml2YXRlIHZvaWQgZG9FbnRlckNsYXNzKE1vZHVsZVN5bWJvbCBtc3ltLCBDbGFzc1N5bWJvbCBjcykgewogICAgICAgIGNsYXNzZXMuY29tcHV0ZUlmQWJzZW50KGNzLmZsYXRuYW1lLCBuIC0+IG5ldyBIYXNoTWFwPD4oKSkucHV0KG1zeW0sIGNzKTsKICAgIH0KCiAgICAvKiogQ3JlYXRlIGEgbmV3IG1lbWJlciBvciB0b3BsZXZlbCBjbGFzcyBzeW1ib2wgd2l0aCBnaXZlbiBmbGF0IG5hbWUKICAgICAqICBhbmQgZW50ZXIgaW4gYGNsYXNzZXMnIHVubGVzcyBhbHJlYWR5IHRoZXJlLgogICAgICovCiAgICBwdWJsaWMgQ2xhc3NTeW1ib2wgZW50ZXJDbGFzcyhNb2R1bGVTeW1ib2wgbXN5bSwgTmFtZSBmbGF0bmFtZSkgewogICAgICAgIEFzc2VydC5jaGVja05vbk51bGwobXN5bSk7CiAgICAgICAgUGFja2FnZVN5bWJvbCBwcyA9IGxvb2t1cFBhY2thZ2UobXN5bSwgQ29udmVydC5wYWNrYWdlUGFydChmbGF0bmFtZSkpOwogICAgICAgIEFzc2VydC5jaGVja05vbk51bGwocHMpOwogICAgICAgIEFzc2VydC5jaGVja05vbk51bGwocHMubW9kbGUpOwogICAgICAgIENsYXNzU3ltYm9sIGMgPSBnZXRDbGFzcyhwcy5tb2RsZSwgZmxhdG5hbWUpOwogICAgICAgIGlmIChjID09IG51bGwpIHsKICAgICAgICAgICAgYyA9IGRlZmluZUNsYXNzKENvbnZlcnQuc2hvcnROYW1lKGZsYXRuYW1lKSwgcHMpOwogICAgICAgICAgICBkb0VudGVyQ2xhc3MocHMubW9kbGUsIGMpOwogICAgICAgICAgICByZXR1cm4gYzsKICAgICAgICB9IGVsc2UKICAgICAgICAgICAgcmV0dXJuIGM7CiAgICB9CgogICAgLyoqIENoZWNrIHRvIHNlZSBpZiBhIHBhY2thZ2UgZXhpc3RzLCBnaXZlbiBpdHMgZnVsbHkgcXVhbGlmaWVkIG5hbWUuCiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIHBhY2thZ2VFeGlzdHMoTW9kdWxlU3ltYm9sIG1zeW0sIE5hbWUgZnVsbG5hbWUpIHsKICAgICAgICBBc3NlcnQuY2hlY2tOb25OdWxsKG1zeW0pOwogICAgICAgIHJldHVybiBsb29rdXBQYWNrYWdlKG1zeW0sIGZ1bGxuYW1lKS5leGlzdHMoKTsKICAgIH0KCiAgICAvKiogTWFrZSBhIHBhY2thZ2UsIGdpdmVuIGl0cyBmdWxseSBxdWFsaWZpZWQgbmFtZS4KICAgICAqLwogICAgcHVibGljIFBhY2thZ2VTeW1ib2wgZW50ZXJQYWNrYWdlKE1vZHVsZVN5bWJvbCBjdXJyTW9kdWxlLCBOYW1lIGZ1bGxuYW1lKSB7CiAgICAgICAgQXNzZXJ0LmNoZWNrTm9uTnVsbChjdXJyTW9kdWxlKTsKICAgICAgICBQYWNrYWdlU3ltYm9sIHAgPSBnZXRQYWNrYWdlKGN1cnJNb2R1bGUsIGZ1bGxuYW1lKTsKICAgICAgICBpZiAocCA9PSBudWxsKSB7CiAgICAgICAgICAgIEFzc2VydC5jaGVjayghZnVsbG5hbWUuaXNFbXB0eSgpLCAoKSAtPiAicm9vdFBhY2thZ2UgbWlzc2luZyE7IGN1cnJNb2R1bGU6ICIgKyBjdXJyTW9kdWxlKTsKICAgICAgICAgICAgcCA9IG5ldyBQYWNrYWdlU3ltYm9sKAogICAgICAgICAgICAgICAgICAgIENvbnZlcnQuc2hvcnROYW1lKGZ1bGxuYW1lKSwKICAgICAgICAgICAgICAgICAgICBlbnRlclBhY2thZ2UoY3Vyck1vZHVsZSwgQ29udmVydC5wYWNrYWdlUGFydChmdWxsbmFtZSkpKTsKICAgICAgICAgICAgcC5jb21wbGV0ZXIgPSBpbml0aWFsQ29tcGxldGVyOwogICAgICAgICAgICBwLm1vZGxlID0gY3Vyck1vZHVsZTsKICAgICAgICAgICAgZG9FbnRlclBhY2thZ2UoY3Vyck1vZHVsZSwgcCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBwOwogICAgfQoKICAgIHByaXZhdGUgdm9pZCBkb0VudGVyUGFja2FnZShNb2R1bGVTeW1ib2wgbXN5bSwgUGFja2FnZVN5bWJvbCBwYWNrKSB7CiAgICAgICAgcGFja2FnZXMuY29tcHV0ZUlmQWJzZW50KHBhY2suZnVsbG5hbWUsIG4gLT4gbmV3IEhhc2hNYXA8PigpKS5wdXQobXN5bSwgcGFjayk7CiAgICAgICAgbXN5bS5lbmNsb3NlZFBhY2thZ2VzID0gbXN5bS5lbmNsb3NlZFBhY2thZ2VzLnByZXBlbmQocGFjayk7CiAgICB9CgogICAgcHJpdmF0ZSB2b2lkIGFkZFJvb3RQYWNrYWdlRm9yKE1vZHVsZVN5bWJvbCBtb2R1bGUpIHsKICAgICAgICBkb0VudGVyUGFja2FnZShtb2R1bGUsIHJvb3RQYWNrYWdlKTsKICAgICAgICBQYWNrYWdlU3ltYm9sIHVubmFtZWRQYWNrYWdlID0gbmV3IFBhY2thZ2VTeW1ib2wobmFtZXMuZW1wdHksIHJvb3RQYWNrYWdlKSB7CiAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG1lc3NhZ2VzLmdldExvY2FsaXplZFN0cmluZygiY29tcGlsZXIubWlzYy51bm5hbWVkLnBhY2thZ2UiKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKICAgICAgICB1bm5hbWVkUGFja2FnZS5tb2RsZSA9IG1vZHVsZTsKICAgICAgICAvL3dlIGNhbm5vdCB1c2UgYSBtZXRob2QgcmVmZXJlbmNlIGJlbG93LCBhcyBpbml0aWFsQ29tcGxldGVyIG1pZ2h0IGJlIG51bGwgbm93CiAgICAgICAgdW5uYW1lZFBhY2thZ2UuY29tcGxldGVyID0gcyAtPiBpbml0aWFsQ29tcGxldGVyLmNvbXBsZXRlKHMpOwogICAgICAgIG1vZHVsZS51bm5hbWVkUGFja2FnZSA9IHVubmFtZWRQYWNrYWdlOwogICAgfQoKICAgIHB1YmxpYyBQYWNrYWdlU3ltYm9sIGdldFBhY2thZ2UoTW9kdWxlU3ltYm9sIG1vZHVsZSwgTmFtZSBmdWxsbmFtZSkgewogICAgICAgIHJldHVybiBwYWNrYWdlcy5nZXRPckRlZmF1bHQoZnVsbG5hbWUsIENvbGxlY3Rpb25zLmVtcHR5TWFwKCkpLmdldChtb2R1bGUpOwogICAgfQoKICAgIHB1YmxpYyBNb2R1bGVTeW1ib2wgZW50ZXJNb2R1bGUoTmFtZSBuYW1lKSB7CiAgICAgICAgTW9kdWxlU3ltYm9sIG1zeW0gPSBtb2R1bGVzLmdldChuYW1lKTsKICAgICAgICBpZiAobXN5bSA9PSBudWxsKSB7CiAgICAgICAgICAgIG1zeW0gPSBNb2R1bGVTeW1ib2wuY3JlYXRlKG5hbWUsIG5hbWVzLm1vZHVsZV9pbmZvKTsKICAgICAgICAgICAgYWRkUm9vdFBhY2thZ2VGb3IobXN5bSk7CiAgICAgICAgICAgIG1zeW0uY29tcGxldGVyID0gcyAtPiBtb2R1bGVDb21wbGV0ZXIuY29tcGxldGUocyk7IC8vYm9vdHN0cmFwIGlzc3VlcwogICAgICAgICAgICBtb2R1bGVzLnB1dChuYW1lLCBtc3ltKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1zeW07CiAgICB9CgogICAgcHVibGljIE1vZHVsZVN5bWJvbCBnZXRNb2R1bGUoTmFtZSBuYW1lKSB7CiAgICAgICAgcmV0dXJuIG1vZHVsZXMuZ2V0KG5hbWUpOwogICAgfQoKICAgIC8vdGVtcG9yYXJ5OgogICAgcHVibGljIE1vZHVsZVN5bWJvbCBpbmZlck1vZHVsZShOYW1lIHBhY2thZ2VOYW1lKSB7CiAgICAgICAgaWYgKHBhY2thZ2VOYW1lLmlzRW1wdHkoKSkKICAgICAgICAgICAgcmV0dXJuIGphdmFfYmFzZSA9PSBub01vZHVsZSA/IG5vTW9kdWxlIDogdW5uYW1lZE1vZHVsZTsvLyEKCiAgICAgICAgTW9kdWxlU3ltYm9sIG1zeW0gPSBudWxsOwogICAgICAgIE1hcDxNb2R1bGVTeW1ib2wsUGFja2FnZVN5bWJvbD4gbWFwID0gcGFja2FnZXMuZ2V0KHBhY2thZ2VOYW1lKTsKICAgICAgICBpZiAobWFwID09IG51bGwpCiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIGZvciAoTWFwLkVudHJ5PE1vZHVsZVN5bWJvbCxQYWNrYWdlU3ltYm9sPiBlOiBtYXAuZW50cnlTZXQoKSkgewogICAgICAgICAgICBpZiAoIWUuZ2V0VmFsdWUoKS5tZW1iZXJzKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgICBpZiAobXN5bSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgbXN5bSA9IGUuZ2V0S2V5KCk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBtc3ltOwogICAgfQoKICAgIHB1YmxpYyBMaXN0PE1vZHVsZVN5bWJvbD4gbGlzdFBhY2thZ2VNb2R1bGVzKE5hbWUgcGFja2FnZU5hbWUpIHsKICAgICAgICBpZiAocGFja2FnZU5hbWUuaXNFbXB0eSgpKQogICAgICAgICAgICByZXR1cm4gTGlzdC5uaWwoKTsKCiAgICAgICAgTGlzdDxNb2R1bGVTeW1ib2w+IHJlc3VsdCA9IExpc3QubmlsKCk7CiAgICAgICAgTWFwPE1vZHVsZVN5bWJvbCxQYWNrYWdlU3ltYm9sPiBtYXAgPSBwYWNrYWdlcy5nZXQocGFja2FnZU5hbWUpOwogICAgICAgIGlmIChtYXAgIT0gbnVsbCkgewogICAgICAgICAgICBmb3IgKE1hcC5FbnRyeTxNb2R1bGVTeW1ib2wsIFBhY2thZ2VTeW1ib2w+IGU6IG1hcC5lbnRyeVNldCgpKSB7CiAgICAgICAgICAgICAgICBpZiAoIWUuZ2V0VmFsdWUoKS5tZW1iZXJzKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0LnByZXBlbmQoZS5nZXRLZXkoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KCiAgICBwdWJsaWMgQ29sbGVjdGlvbjxNb2R1bGVTeW1ib2w+IGdldEFsbE1vZHVsZXMoKSB7CiAgICAgICAgcmV0dXJuIG1vZHVsZXMudmFsdWVzKCk7CiAgICB9CgogICAgcHVibGljIEl0ZXJhYmxlPENsYXNzU3ltYm9sPiBnZXRDbGFzc2VzRm9yTmFtZShOYW1lIGNhbmRpZGF0ZSkgewogICAgICAgIHJldHVybiBjbGFzc2VzLmdldE9yRGVmYXVsdChjYW5kaWRhdGUsIENvbGxlY3Rpb25zLmVtcHR5TWFwKCkpLnZhbHVlcygpOwogICAgfQoKICAgIHB1YmxpYyBJdGVyYWJsZTxQYWNrYWdlU3ltYm9sPiBnZXRQYWNrYWdlc0Zvck5hbWUoTmFtZSBjYW5kaWRhdGUpIHsKICAgICAgICByZXR1cm4gcGFja2FnZXMuZ2V0T3JEZWZhdWx0KGNhbmRpZGF0ZSwgQ29sbGVjdGlvbnMuZW1wdHlNYXAoKSkudmFsdWVzKCk7CiAgICB9Cn0KUEsDBAoAAAgAANJ9TUol0JZrsAYAALAGAAAnAAAAY29tL3N1bi90b29scy9qYXZhYy9jb2RlL0JvdW5kS2luZC5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDAzLCAyMDA1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuamF2YWMuY29kZTsKCi8qKgogKgogKiA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yCiAqIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj4KICovCnB1YmxpYyBlbnVtIEJvdW5kS2luZCB7CiAgICBFWFRFTkRTKCI/IGV4dGVuZHMgIiksCiAgICBTVVBFUigiPyBzdXBlciAiKSwKICAgIFVOQk9VTkQoIj8iKTsKCiAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBuYW1lOwoKICAgIEJvdW5kS2luZChTdHJpbmcgbmFtZSkgewogICAgICAgIHRoaXMubmFtZSA9IG5hbWU7CiAgICB9CgogICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsgcmV0dXJuIG5hbWU7IH0KfQpQSwMECgAACAAABjupSq8KDotCIAAAQiAAACsAAABjb20vc3VuL3Rvb2xzL2phdmFjL2NvZGUvQW5ub0NvbnN0cnVjdC5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDA1LCAyMDE1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuamF2YWMuY29kZTsKCmltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5Bbm5vdGF0aW9uOwppbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uSW5oZXJpdGVkOwppbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uUmVwZWF0YWJsZTsKaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0Lkludm9jYXRpb25UYXJnZXRFeGNlcHRpb247CmltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5NZXRob2Q7CgppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5Bbm5vdGF0ZWRDb25zdHJ1Y3Q7CgppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5tb2RlbC5Bbm5vdGF0aW9uUHJveHlNYWtlcjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5EZWZpbmVkQnk7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuRGVmaW5lZEJ5LkFwaTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5MaXN0OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkxpc3RCdWZmZXI7CgovKioKICogQ29tbW9uIHN1cGVyIHR5cGUgZm9yIGFubm90YXRlZCBjb25zdHJ1Y3RzIHN1Y2ggYXMgVHlwZXMgYW5kIFN5bWJvbHMuCiAqCiAqIFRoaXMgY2xhc3Mgc2hvdWxkICpub3QqIGNvbnRhaW4gYW55IGZpZWxkcyBzaW5jZSBpdCB3b3VsZCBoYXZlIGEgc2lnbmlmaWNhbnQKICogaW1wYWN0IG9uIHRoZSBqYXZhYyBtZW1vcnkgZm9vdHByaW50LgogKgogKiA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duCiAqIHJpc2suICBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZQogKiBvciBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+PC9wPgogKi8KcHVibGljIGFic3RyYWN0IGNsYXNzIEFubm9Db25zdHJ1Y3QgaW1wbGVtZW50cyBBbm5vdGF0ZWRDb25zdHJ1Y3QgewoKCiAgICAvLyBPdmVycmlkZSB0byBlbmZvcmNlIGEgbmFycm93ZXIgcmV0dXJuIHR5cGUuCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICBwdWJsaWMgYWJzdHJhY3QgTGlzdDw/IGV4dGVuZHMgQXR0cmlidXRlLkNvbXBvdW5kPiBnZXRBbm5vdGF0aW9uTWlycm9ycygpOwoKCiAgICAvLyBUaGlzIG1ldGhvZCBpcyBwYXJ0IG9mIHRoZSBqYXZheC5sYW5nLm1vZGVsIEFQSSwgZG8gbm90IHVzZSB0aGlzIGluIGphdmFjIGNvZGUuCiAgICBwcm90ZWN0ZWQgPEEgZXh0ZW5kcyBBbm5vdGF0aW9uPiBBdHRyaWJ1dGUuQ29tcG91bmQgZ2V0QXR0cmlidXRlKENsYXNzPEE+IGFubm9UeXBlKSB7CiAgICAgICAgU3RyaW5nIG5hbWUgPSBhbm5vVHlwZS5nZXROYW1lKCk7CgogICAgICAgIGZvciAoQXR0cmlidXRlLkNvbXBvdW5kIGFubm8gOiBnZXRBbm5vdGF0aW9uTWlycm9ycygpKSB7CiAgICAgICAgICAgIGlmIChuYW1lLmVxdWFscyhhbm5vLnR5cGUudHN5bS5mbGF0TmFtZSgpLnRvU3RyaW5nKCkpKQogICAgICAgICAgICAgICAgcmV0dXJuIGFubm87CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCgogICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCiAgICBwcm90ZWN0ZWQgPEEgZXh0ZW5kcyBBbm5vdGF0aW9uPiBBW10gZ2V0SW5oZXJpdGVkQW5ub3RhdGlvbnMoQ2xhc3M8QT4gYW5ub1R5cGUpIHsKICAgICAgICByZXR1cm4gKEFbXSkgamF2YS5sYW5nLnJlZmxlY3QuQXJyYXkubmV3SW5zdGFuY2UoYW5ub1R5cGUsIDApOyAgLy8gYW5ub1R5cGUgaXMgdGhlIENsYXNzIGZvciBBCiAgICB9CgoKICAgIC8vIFRoaXMgbWV0aG9kIGlzIHBhcnQgb2YgdGhlIGphdmF4LmxhbmcubW9kZWwgQVBJLCBkbyBub3QgdXNlIHRoaXMgaW4gamF2YWMgY29kZS4KICAgIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgcHVibGljIDxBIGV4dGVuZHMgQW5ub3RhdGlvbj4gQVtdIGdldEFubm90YXRpb25zQnlUeXBlKENsYXNzPEE+IGFubm9UeXBlKSB7CgogICAgICAgIGlmICghYW5ub1R5cGUuaXNBbm5vdGF0aW9uKCkpCiAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIk5vdCBhbiBhbm5vdGF0aW9uIHR5cGU6ICIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIGFubm9UeXBlKTsKICAgICAgICAvLyBJZiBhbm5vVHlwZSBkb2VzIG5vdCBkZWNsYXJlIGEgY29udGFpbmVyIHRoaXMgaXMgZXF1aXZhbGVudCB0byB3cmFwcGluZwogICAgICAgIC8vIGdldEFubm90YXRpb24oLi4uKSBpbiBhbiBhcnJheS4KICAgICAgICBDbGFzcyA8PyBleHRlbmRzIEFubm90YXRpb24+IGNvbnRhaW5lclR5cGUgPSBnZXRDb250YWluZXIoYW5ub1R5cGUpOwogICAgICAgIGlmIChjb250YWluZXJUeXBlID09IG51bGwpIHsKICAgICAgICAgICAgQSByZXMgPSBnZXRBbm5vdGF0aW9uKGFubm9UeXBlKTsKICAgICAgICAgICAgaW50IHNpemUgPSByZXMgPT0gbnVsbCA/IDAgOiAxOwoKICAgICAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpIC8vIGFubm9UeXBlIGlzIHRoZSBDbGFzcyBmb3IgQQogICAgICAgICAgICBBW10gYXJyID0gKEFbXSlqYXZhLmxhbmcucmVmbGVjdC5BcnJheS5uZXdJbnN0YW5jZShhbm5vVHlwZSwgc2l6ZSk7CiAgICAgICAgICAgIGlmIChyZXMgIT0gbnVsbCkKICAgICAgICAgICAgICAgIGFyclswXSA9IHJlczsKICAgICAgICAgICAgcmV0dXJuIGFycjsKICAgICAgICB9CgogICAgICAgIC8vIFNvIHdlIGhhdmUgYSBjb250YWluaW5nIHR5cGUKICAgICAgICBTdHJpbmcgYW5ub1R5cGVOYW1lID0gYW5ub1R5cGUuZ2V0TmFtZSgpOwogICAgICAgIFN0cmluZyBjb250YWluZXJUeXBlTmFtZSA9IGNvbnRhaW5lclR5cGUuZ2V0TmFtZSgpOwogICAgICAgIGludCBkaXJlY3RJbmRleCA9IC0xLCBjb250YWluZXJJbmRleCA9IC0xOwogICAgICAgIEF0dHJpYnV0ZS5Db21wb3VuZCBkaXJlY3QgPSBudWxsLCBjb250YWluZXIgPSBudWxsOwogICAgICAgIC8vIEZpbmQgZGlyZWN0bHkgKGV4cGxpY2l0IG9yIGltcGxpY2l0KSBwcmVzZW50IGFubm90YXRpb25zCiAgICAgICAgaW50IGluZGV4ID0gLTE7CiAgICAgICAgZm9yIChBdHRyaWJ1dGUuQ29tcG91bmQgYXR0cmlidXRlIDogZ2V0QW5ub3RhdGlvbk1pcnJvcnMoKSkgewogICAgICAgICAgICBpbmRleCsrOwogICAgICAgICAgICBpZiAoYXR0cmlidXRlLnR5cGUudHN5bS5mbGF0TmFtZSgpLmNvbnRlbnRFcXVhbHMoYW5ub1R5cGVOYW1lKSkgewogICAgICAgICAgICAgICAgZGlyZWN0SW5kZXggPSBpbmRleDsKICAgICAgICAgICAgICAgIGRpcmVjdCA9IGF0dHJpYnV0ZTsKICAgICAgICAgICAgfSBlbHNlIGlmKGNvbnRhaW5lclR5cGVOYW1lICE9IG51bGwgJiYKICAgICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZS50eXBlLnRzeW0uZmxhdE5hbWUoKS5jb250ZW50RXF1YWxzKGNvbnRhaW5lclR5cGVOYW1lKSkgewogICAgICAgICAgICAgICAgY29udGFpbmVySW5kZXggPSBpbmRleDsKICAgICAgICAgICAgICAgIGNvbnRhaW5lciA9IGF0dHJpYnV0ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gRGVhbCB3aXRoIGluaGVyaXRlZCBhbm5vdGF0aW9ucwogICAgICAgIGlmIChkaXJlY3QgPT0gbnVsbCAmJiBjb250YWluZXIgPT0gbnVsbCAmJgogICAgICAgICAgICAgICAgYW5ub1R5cGUuaXNBbm5vdGF0aW9uUHJlc2VudChJbmhlcml0ZWQuY2xhc3MpKQogICAgICAgICAgICByZXR1cm4gZ2V0SW5oZXJpdGVkQW5ub3RhdGlvbnMoYW5ub1R5cGUpOwoKICAgICAgICBBdHRyaWJ1dGUuQ29tcG91bmRbXSBjb250YWluZWQgPSB1bnBhY2tDb250YWluZWQoY29udGFpbmVyKTsKCiAgICAgICAgLy8gSW4gY2FzZSBvZiBhbiBlbXB0eSBsZWdhY3kgY29udGFpbmVyIHdlIG1pZ2h0IG5lZWQgdG8gbG9vayBmb3IKICAgICAgICAvLyBpbmhlcml0ZWQgYW5ub3MgYXMgd2VsbAogICAgICAgIGlmIChkaXJlY3QgPT0gbnVsbCAmJiBjb250YWluZWQubGVuZ3RoID09IDAgJiYKICAgICAgICAgICAgICAgIGFubm9UeXBlLmlzQW5ub3RhdGlvblByZXNlbnQoSW5oZXJpdGVkLmNsYXNzKSkKICAgICAgICAgICAgcmV0dXJuIGdldEluaGVyaXRlZEFubm90YXRpb25zKGFubm9UeXBlKTsKCiAgICAgICAgaW50IHNpemUgPSAoZGlyZWN0ID09IG51bGwgPyAwIDogMSkgKyBjb250YWluZWQubGVuZ3RoOwogICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKSAvLyBhbm5vVHlwZSBpcyB0aGUgQ2xhc3MgZm9yIEEKICAgICAgICBBW10gYXJyID0gKEFbXSlqYXZhLmxhbmcucmVmbGVjdC5BcnJheS5uZXdJbnN0YW5jZShhbm5vVHlwZSwgc2l6ZSk7CgogICAgICAgIC8vIGlmIGRpcmVjdCAmJiBjb250YWluZXIsIHdoaWNoIGlzIGZpcnN0PwogICAgICAgIGludCBpbnNlcnQgPSAtMTsKICAgICAgICBpbnQgbGVuZ3RoID0gYXJyLmxlbmd0aDsKICAgICAgICBpZiAoZGlyZWN0SW5kZXggPj0gMCAmJiBjb250YWluZXJJbmRleCA+PSAwKSB7CiAgICAgICAgICAgIGlmIChkaXJlY3RJbmRleCA8IGNvbnRhaW5lckluZGV4KSB7CiAgICAgICAgICAgICAgICBhcnJbMF0gPSBBbm5vdGF0aW9uUHJveHlNYWtlci5nZW5lcmF0ZUFubm90YXRpb24oZGlyZWN0LCBhbm5vVHlwZSk7CiAgICAgICAgICAgICAgICBpbnNlcnQgPSAxOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgYXJyW2Fyci5sZW5ndGggLSAxXSA9IEFubm90YXRpb25Qcm94eU1ha2VyLmdlbmVyYXRlQW5ub3RhdGlvbihkaXJlY3QsIGFubm9UeXBlKTsKICAgICAgICAgICAgICAgIGluc2VydCA9IDA7CiAgICAgICAgICAgICAgICBsZW5ndGgtLTsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSBpZiAoZGlyZWN0SW5kZXggPj0gMCkgewogICAgICAgICAgICBhcnJbMF0gPSBBbm5vdGF0aW9uUHJveHlNYWtlci5nZW5lcmF0ZUFubm90YXRpb24oZGlyZWN0LCBhbm5vVHlwZSk7CiAgICAgICAgICAgIHJldHVybiBhcnI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLy8gT25seSBjb250YWluZXIKICAgICAgICAgICAgaW5zZXJ0ID0gMDsKICAgICAgICB9CgogICAgICAgIGZvciAoaW50IGkgPSAwOyBpICsgaW5zZXJ0IDwgbGVuZ3RoOyBpKyspCiAgICAgICAgICAgIGFycltpbnNlcnQgKyBpXSA9IEFubm90YXRpb25Qcm94eU1ha2VyLmdlbmVyYXRlQW5ub3RhdGlvbihjb250YWluZWRbaV0sIGFubm9UeXBlKTsKCiAgICAgICAgcmV0dXJuIGFycjsKICAgIH0KCiAgICBwcml2YXRlIEF0dHJpYnV0ZS5Db21wb3VuZFtdIHVucGFja0NvbnRhaW5lZChBdHRyaWJ1dGUuQ29tcG91bmQgY29udGFpbmVyKSB7CiAgICAgICAgLy8gUGFjayB0aGVtIGluIGFuIGFycmF5CiAgICAgICAgQXR0cmlidXRlW10gY29udGFpbmVkMCA9IG51bGw7CiAgICAgICAgaWYgKGNvbnRhaW5lciAhPSBudWxsKQogICAgICAgICAgICBjb250YWluZWQwID0gdW5wYWNrQXR0cmlidXRlcyhjb250YWluZXIpOwogICAgICAgIExpc3RCdWZmZXI8QXR0cmlidXRlLkNvbXBvdW5kPiBjb21wb3VuZHMgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgaWYgKGNvbnRhaW5lZDAgIT0gbnVsbCkgewogICAgICAgICAgICBmb3IgKEF0dHJpYnV0ZSBhIDogY29udGFpbmVkMCkKICAgICAgICAgICAgICAgIGlmIChhIGluc3RhbmNlb2YgQXR0cmlidXRlLkNvbXBvdW5kKQogICAgICAgICAgICAgICAgICAgIGNvbXBvdW5kcyA9IGNvbXBvdW5kcy5hcHBlbmQoKEF0dHJpYnV0ZS5Db21wb3VuZClhKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGNvbXBvdW5kcy50b0FycmF5KG5ldyBBdHRyaWJ1dGUuQ29tcG91bmRbY29tcG91bmRzLnNpemUoKV0pOwogICAgfQoKICAgIC8vIFRoaXMgbWV0aG9kIGlzIHBhcnQgb2YgdGhlIGphdmF4LmxhbmcubW9kZWwgQVBJLCBkbyBub3QgdXNlIHRoaXMgaW4gamF2YWMgY29kZS4KICAgIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgcHVibGljIDxBIGV4dGVuZHMgQW5ub3RhdGlvbj4gQSBnZXRBbm5vdGF0aW9uKENsYXNzPEE+IGFubm9UeXBlKSB7CgogICAgICAgIGlmICghYW5ub1R5cGUuaXNBbm5vdGF0aW9uKCkpCiAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIk5vdCBhbiBhbm5vdGF0aW9uIHR5cGU6ICIgKyBhbm5vVHlwZSk7CgogICAgICAgIEF0dHJpYnV0ZS5Db21wb3VuZCBjID0gZ2V0QXR0cmlidXRlKGFubm9UeXBlKTsKICAgICAgICByZXR1cm4gYyA9PSBudWxsID8gbnVsbCA6IEFubm90YXRpb25Qcm94eU1ha2VyLmdlbmVyYXRlQW5ub3RhdGlvbihjLCBhbm5vVHlwZSk7CiAgICB9CgogICAgLy8gSGVscGVyIHRvIGdldEFubm90YXRpb25zQnlUeXBlCiAgICBwcml2YXRlIHN0YXRpYyBDbGFzczw/IGV4dGVuZHMgQW5ub3RhdGlvbj4gZ2V0Q29udGFpbmVyKENsYXNzPD8gZXh0ZW5kcyBBbm5vdGF0aW9uPiBhbm5vVHlwZSkgewogICAgICAgIFJlcGVhdGFibGUgcmVwZWF0YWJsZSA9IGFubm9UeXBlLmdldEFubm90YXRpb24oUmVwZWF0YWJsZS5jbGFzcyk7CiAgICAgICAgcmV0dXJuIChyZXBlYXRhYmxlID09IG51bGwpID8gbnVsbCA6IHJlcGVhdGFibGUudmFsdWUoKTsKICAgIH0KCiAgICAvLyBIZWxwZXIgdG8gZ2V0QW5ub3RhdGlvbnNCeVR5cGUKICAgIHByaXZhdGUgc3RhdGljIEF0dHJpYnV0ZVtdIHVucGFja0F0dHJpYnV0ZXMoQXR0cmlidXRlLkNvbXBvdW5kIGNvbnRhaW5lcikgewogICAgICAgIC8vIFdlIG5vdyBoYXZlIGFuIGluc3RhbmNlIG9mIHRoZSBjb250YWluZXIsCiAgICAgICAgLy8gdW5wYWNrIGl0IHJldHVybmluZyBhbiBpbnN0YW5jZSBvZiB0aGUKICAgICAgICAvLyBjb250YWluZWQgdHlwZSBvciBudWxsCiAgICAgICAgcmV0dXJuICgoQXR0cmlidXRlLkFycmF5KWNvbnRhaW5lci5tZW1iZXIoY29udGFpbmVyLnR5cGUudHN5bS5uYW1lLnRhYmxlLm5hbWVzLnZhbHVlKSkudmFsdWVzOwogICAgfQoKfQpQSwMECgAACAAABjupSg9S+5O+OQAAvjkAACUAAABjb20vc3VuL3Rvb2xzL2phdmFjL2NvZGUvUHJpbnRlci5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDA5LCAyMDE0LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuamF2YWMuY29kZTsKCmltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOwoKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuYXBpLk1lc3NhZ2VzOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlR5cGUuQXJyYXlUeXBlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlN5bWJvbC4qOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlR5cGUuKjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5MaXN0OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkxpc3RCdWZmZXI7CgppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5Cb3VuZEtpbmQuKjsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuRmxhZ3MuKjsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuS2luZHMuS2luZC4qOwppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5UeXBlVGFnLkNMQVNTOwppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5UeXBlVGFnLkZPUkFMTDsKCi8qKgogKiBBIGNvbWJpbmVkIHR5cGUvc3ltYm9sIHZpc2l0b3IgZm9yIGdlbmVyYXRpbmcgbm9uLXRyaXZpYWwgbG9jYWxpemVkIHN0cmluZwogKiByZXByZXNlbnRhdGlvbiBvZiB0eXBlcyBhbmQgc3ltYm9scy4KICoKICogPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93biByaXNrLgogKiBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogKiBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+CiAqLwpwdWJsaWMgYWJzdHJhY3QgY2xhc3MgUHJpbnRlciBpbXBsZW1lbnRzIFR5cGUuVmlzaXRvcjxTdHJpbmcsIExvY2FsZT4sIFN5bWJvbC5WaXNpdG9yPFN0cmluZywgTG9jYWxlPiB7CgogICAgTGlzdDxUeXBlPiBzZWVuQ2FwdHVyZWQgPSBMaXN0Lm5pbCgpOwogICAgc3RhdGljIGZpbmFsIGludCBQUklNRSA9IDk5NzsgIC8vIGxhcmdlc3QgcHJpbWUgbGVzcyB0aGFuIDEwMDAKCiAgICBwcm90ZWN0ZWQgUHJpbnRlcigpIHsgfQoKICAgIC8qKgogICAgICogVGhpcyBtZXRob2Qgc2hvdWxkIGJlIG92ZXJyaWRlbiBpbiBvcmRlciB0byBwcm92aWRlIHByb3BlciBpMThuIHN1cHBvcnQuCiAgICAgKgogICAgICogQHBhcmFtIGxvY2FsZSB0aGUgbG9jYWxlIGluIHdoaWNoIHRoZSBzdHJpbmcgaXMgdG8gYmUgcmVuZGVyZWQKICAgICAqIEBwYXJhbSBrZXkgdGhlIGtleSBjb3JyZXNwb25kaW5nIHRvIHRoZSBtZXNzYWdlIHRvIGJlIGRpc3BsYXllZAogICAgICogQHBhcmFtIGFyZ3MgYSBsaXN0IG9mIG9wdGlvbmFsIGFyZ3VtZW50cwogICAgICogQHJldHVybiBsb2NhbGl6ZWQgc3RyaW5nIHJlcHJlc2VudGF0aW9uCiAgICAgKi8KICAgIHByb3RlY3RlZCBhYnN0cmFjdCBTdHJpbmcgbG9jYWxpemUoTG9jYWxlIGxvY2FsZSwgU3RyaW5nIGtleSwgT2JqZWN0Li4uIGFyZ3MpOwoKICAgIC8qKgogICAgICogTWFwcyBhIGNhcHR1cmVkIHR5cGUgaW50byBhbiB1bmlxdWUgaWRlbnRpZmllci4KICAgICAqCiAgICAgKiBAcGFyYW0gdCB0aGUgY2FwdHVyZWQgdHlwZSBmb3Igd2hpY2ggYW4gaWQgaXMgdG8gYmUgcmV0cmlldmVkCiAgICAgKiBAcGFyYW0gbG9jYWxlIGxvY2FsZSBzZXR0aW5ncwogICAgICogQHJldHVybiB1bmlxdWUgaWQgcmVwcmVzZW50aW5nIHRoaXMgY2FwdHVyZWQgdHlwZQogICAgICovCiAgICBwcm90ZWN0ZWQgYWJzdHJhY3QgU3RyaW5nIGNhcHR1cmVkVmFySWQoQ2FwdHVyZWRUeXBlIHQsIExvY2FsZSBsb2NhbGUpOwoKICAgIC8qKgogICAgICogQ3JlYXRlIGEgcHJpbnRlciB3aXRoIGRlZmF1bHQgaTE4biBzdXBwb3J0IHByb3ZpZGVkIGJ5IE1lc3NhZ2VzLiBCeSBkZWZhdWx0LAogICAgICogY2FwdHVyZWQgdHlwZXMgaWRzIGFyZSBnZW5lcmF0ZWQgdXNpbmcgaGFzaGNvZGUuCiAgICAgKgogICAgICogQHBhcmFtIG1lc3NhZ2VzIE1lc3NhZ2VzIGNsYXNzIHRvIGJlIHVzZWQgZm9yIGkxOG4KICAgICAqIEByZXR1cm4gcHJpbnRlciB2aXNpdG9yIGluc3RhbmNlCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgUHJpbnRlciBjcmVhdGVTdGFuZGFyZFByaW50ZXIoZmluYWwgTWVzc2FnZXMgbWVzc2FnZXMpIHsKICAgICAgICByZXR1cm4gbmV3IFByaW50ZXIoKSB7CiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwcm90ZWN0ZWQgU3RyaW5nIGxvY2FsaXplKExvY2FsZSBsb2NhbGUsIFN0cmluZyBrZXksIE9iamVjdC4uLiBhcmdzKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gbWVzc2FnZXMuZ2V0TG9jYWxpemVkU3RyaW5nKGxvY2FsZSwga2V5LCBhcmdzKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHByb3RlY3RlZCBTdHJpbmcgY2FwdHVyZWRWYXJJZChDYXB0dXJlZFR5cGUgdCwgTG9jYWxlIGxvY2FsZSkgewogICAgICAgICAgICAgICAgcmV0dXJuICh0Lmhhc2hDb2RlKCkgJiAweEZGRkZGRkZGTCkgJSBQUklNRSArICIiOwogICAgICAgIH19OwogICAgfQoKICAgIC8qKgogICAgICogR2V0IGEgbG9jYWxpemVkIHN0cmluZyByZXByZXNlbnRhdGlvbiBmb3IgYWxsIHRoZSB0eXBlcyBpbiB0aGUgaW5wdXQgbGlzdC4KICAgICAqCiAgICAgKiBAcGFyYW0gdHMgdHlwZXMgdG8gYmUgZGlzcGxheWVkCiAgICAgKiBAcGFyYW0gbG9jYWxlIHRoZSBsb2NhbGUgaW4gd2hpY2ggdGhlIHN0cmluZyBpcyB0byBiZSByZW5kZXJlZAogICAgICogQHJldHVybiBsb2NhbGl6ZWQgc3RyaW5nIHJlcHJlc2VudGF0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBTdHJpbmcgdmlzaXRUeXBlcyhMaXN0PFR5cGU+IHRzLCBMb2NhbGUgbG9jYWxlKSB7CiAgICAgICAgTGlzdEJ1ZmZlcjxTdHJpbmc+IHNidWYgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgZm9yIChUeXBlIHQgOiB0cykgewogICAgICAgICAgICBzYnVmLmFwcGVuZCh2aXNpdCh0LCBsb2NhbGUpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHNidWYudG9MaXN0KCkudG9TdHJpbmcoKTsKICAgIH0KCiAgICAvKioKICAgICAqICogR2V0IGEgbG9jYWxpemVkIHN0cmluZyByZXByZXNlbnRhdGlvbiBmb3IgYWxsIHRoZSBzeW1ib2xzIGluIHRoZSBpbnB1dCBsaXN0LgogICAgICoKICAgICAqIEBwYXJhbSB0cyBzeW1ib2xzIHRvIGJlIGRpc3BsYXllZAogICAgICogQHBhcmFtIGxvY2FsZSB0aGUgbG9jYWxlIGluIHdoaWNoIHRoZSBzdHJpbmcgaXMgdG8gYmUgcmVuZGVyZWQKICAgICAqIEByZXR1cm4gbG9jYWxpemVkIHN0cmluZyByZXByZXNlbnRhdGlvbgogICAgICovCiAgICBwdWJsaWMgU3RyaW5nIHZpc2l0U3ltYm9scyhMaXN0PFN5bWJvbD4gdHMsIExvY2FsZSBsb2NhbGUpIHsKICAgICAgICBMaXN0QnVmZmVyPFN0cmluZz4gc2J1ZiA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICBmb3IgKFN5bWJvbCB0IDogdHMpIHsKICAgICAgICAgICAgc2J1Zi5hcHBlbmQodmlzaXQodCwgbG9jYWxlKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzYnVmLnRvTGlzdCgpLnRvU3RyaW5nKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBHZXQgYSBsb2NhbGl6ZWQgc3RyaW5nIHJlcHJlc2VudGF0aW9uIGZvciBhIGdpdmVuIHR5cGUuCiAgICAgKgogICAgICogQHBhcmFtIHQgdHlwZSB0byBiZSBkaXNwbGF5ZWQKICAgICAqIEBwYXJhbSBsb2NhbGUgdGhlIGxvY2FsZSBpbiB3aGljaCB0aGUgc3RyaW5nIGlzIHRvIGJlIHJlbmRlcmVkCiAgICAgKiBAcmV0dXJuIGxvY2FsaXplZCBzdHJpbmcgcmVwcmVzZW50YXRpb24KICAgICAqLwogICAgcHVibGljIFN0cmluZyB2aXNpdChUeXBlIHQsIExvY2FsZSBsb2NhbGUpIHsKICAgICAgICByZXR1cm4gdC5hY2NlcHQodGhpcywgbG9jYWxlKTsKICAgIH0KCiAgICAvKioKICAgICAqIEdldCBhIGxvY2FsaXplZCBzdHJpbmcgcmVwcmVzZW50YXRpb24gZm9yIGEgZ2l2ZW4gc3ltYm9sLgogICAgICoKICAgICAqIEBwYXJhbSBzIHN5bWJvbCB0byBiZSBkaXNwbGF5ZWQKICAgICAqIEBwYXJhbSBsb2NhbGUgdGhlIGxvY2FsZSBpbiB3aGljaCB0aGUgc3RyaW5nIGlzIHRvIGJlIHJlbmRlcmVkCiAgICAgKiBAcmV0dXJuIGxvY2FsaXplZCBzdHJpbmcgcmVwcmVzZW50YXRpb24KICAgICAqLwogICAgcHVibGljIFN0cmluZyB2aXNpdChTeW1ib2wgcywgTG9jYWxlIGxvY2FsZSkgewogICAgICAgIHJldHVybiBzLmFjY2VwdCh0aGlzLCBsb2NhbGUpOwogICAgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIFN0cmluZyB2aXNpdENhcHR1cmVkVHlwZShDYXB0dXJlZFR5cGUgdCwgTG9jYWxlIGxvY2FsZSkgewogICAgICAgIGlmIChzZWVuQ2FwdHVyZWQuY29udGFpbnModCkpCiAgICAgICAgICAgIHJldHVybiBwcmludEFubm90YXRpb25zKHQpICsKICAgICAgICAgICAgICAgIGxvY2FsaXplKGxvY2FsZSwgImNvbXBpbGVyLm1pc2MudHlwZS5jYXB0dXJlb2YuMSIsCiAgICAgICAgICAgICAgICBjYXB0dXJlZFZhcklkKHQsIGxvY2FsZSkpOwogICAgICAgIGVsc2UgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgc2VlbkNhcHR1cmVkID0gc2VlbkNhcHR1cmVkLnByZXBlbmQodCk7CiAgICAgICAgICAgICAgICByZXR1cm4gcHJpbnRBbm5vdGF0aW9ucyh0KSArCiAgICAgICAgICAgICAgICAgICAgbG9jYWxpemUobG9jYWxlLCAiY29tcGlsZXIubWlzYy50eXBlLmNhcHR1cmVvZiIsCiAgICAgICAgICAgICAgICAgICAgY2FwdHVyZWRWYXJJZCh0LCBsb2NhbGUpLAogICAgICAgICAgICAgICAgICAgIHZpc2l0KHQud2lsZGNhcmQsIGxvY2FsZSkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGZpbmFsbHkgewogICAgICAgICAgICAgICAgc2VlbkNhcHR1cmVkID0gc2VlbkNhcHR1cmVkLnRhaWw7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgU3RyaW5nIHZpc2l0Rm9yQWxsKEZvckFsbCB0LCBMb2NhbGUgbG9jYWxlKSB7CiAgICAgICAgcmV0dXJuIHByaW50QW5ub3RhdGlvbnModCkgKyAiPCIgKyB2aXNpdFR5cGVzKHQudHZhcnMsIGxvY2FsZSkgKwogICAgICAgICAgICAiPiIgKyB2aXNpdCh0LnF0eXBlLCBsb2NhbGUpOwogICAgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIFN0cmluZyB2aXNpdFVuZGV0VmFyKFVuZGV0VmFyIHQsIExvY2FsZSBsb2NhbGUpIHsKICAgICAgICBpZiAodC5nZXRJbnN0KCkgIT0gbnVsbCkgewogICAgICAgICAgICByZXR1cm4gcHJpbnRBbm5vdGF0aW9ucyh0KSArIHZpc2l0KHQuZ2V0SW5zdCgpLCBsb2NhbGUpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiBwcmludEFubm90YXRpb25zKHQpICsgdmlzaXQodC5xdHlwZSwgbG9jYWxlKSArICI/IjsKICAgICAgICB9CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgU3RyaW5nIHZpc2l0QXJyYXlUeXBlKEFycmF5VHlwZSB0LCBMb2NhbGUgbG9jYWxlKSB7CiAgICAgICAgU3RyaW5nQnVpbGRlciByZXMgPSBuZXcgU3RyaW5nQnVpbGRlcigpOwogICAgICAgIHByaW50QmFzZUVsZW1lbnRUeXBlKHQsIHJlcywgbG9jYWxlKTsKICAgICAgICBwcmludEJyYWNrZXRzKHQsIHJlcywgbG9jYWxlKTsKICAgICAgICByZXR1cm4gcmVzLnRvU3RyaW5nKCk7CiAgICB9CgogICAgcHJpdmF0ZSBTdHJpbmcgcHJpbnRBbm5vdGF0aW9ucyhUeXBlIHQpIHsKICAgICAgICByZXR1cm4gcHJpbnRBbm5vdGF0aW9ucyh0LCBmYWxzZSk7CiAgICB9CgogICAgcHJpdmF0ZSBTdHJpbmcgcHJpbnRBbm5vdGF0aW9ucyhUeXBlIHQsIGJvb2xlYW4gcHJlZml4KSB7CiAgICAgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CiAgICAgICAgTGlzdDxBdHRyaWJ1dGUuVHlwZUNvbXBvdW5kPiBhbm5vcyA9IHQuZ2V0QW5ub3RhdGlvbk1pcnJvcnMoKTsKICAgICAgICBpZiAoIWFubm9zLmlzRW1wdHkoKSkgewogICAgICAgICAgICBpZiAocHJlZml4KSBzYi5hcHBlbmQoJyAnKTsKICAgICAgICAgICAgc2IuYXBwZW5kKGFubm9zKTsKICAgICAgICAgICAgc2IuYXBwZW5kKCcgJyk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzYi50b1N0cmluZygpOwogICAgfQoKICAgIHByaXZhdGUgdm9pZCBwcmludEJhc2VFbGVtZW50VHlwZShUeXBlIHQsIFN0cmluZ0J1aWxkZXIgc2IsIExvY2FsZSBsb2NhbGUpIHsKICAgICAgICBUeXBlIGFycmVsID0gdDsKICAgICAgICB3aGlsZSAoYXJyZWwuaGFzVGFnKFR5cGVUYWcuQVJSQVkpKSB7CiAgICAgICAgICAgIGFycmVsID0gKChBcnJheVR5cGUpIGFycmVsKS5lbGVtdHlwZTsKICAgICAgICB9CiAgICAgICAgc2IuYXBwZW5kKHZpc2l0KGFycmVsLCBsb2NhbGUpKTsKICAgIH0KCiAgICBwcml2YXRlIHZvaWQgcHJpbnRCcmFja2V0cyhUeXBlIHQsIFN0cmluZ0J1aWxkZXIgc2IsIExvY2FsZSBsb2NhbGUpIHsKICAgICAgICBUeXBlIGFycmVsID0gdDsKICAgICAgICB3aGlsZSAoYXJyZWwuaGFzVGFnKFR5cGVUYWcuQVJSQVkpKSB7CiAgICAgICAgICAgIHNiLmFwcGVuZChwcmludEFubm90YXRpb25zKGFycmVsLCB0cnVlKSk7CiAgICAgICAgICAgIHNiLmFwcGVuZCgiW10iKTsKICAgICAgICAgICAgYXJyZWwgPSAoKEFycmF5VHlwZSkgYXJyZWwpLmVsZW10eXBlOwogICAgICAgIH0KICAgIH0KCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBTdHJpbmcgdmlzaXRDbGFzc1R5cGUoQ2xhc3NUeXBlIHQsIExvY2FsZSBsb2NhbGUpIHsKICAgICAgICBTdHJpbmdCdWlsZGVyIGJ1ZiA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CiAgICAgICAgaWYgKHQuZ2V0RW5jbG9zaW5nVHlwZSgpLmhhc1RhZyhDTEFTUykgJiYgdC50c3ltLm93bmVyLmtpbmQgPT0gVFlQKSB7CiAgICAgICAgICAgIGJ1Zi5hcHBlbmQodmlzaXQodC5nZXRFbmNsb3NpbmdUeXBlKCksIGxvY2FsZSkpOwogICAgICAgICAgICBidWYuYXBwZW5kKCcuJyk7CiAgICAgICAgICAgIGJ1Zi5hcHBlbmQocHJpbnRBbm5vdGF0aW9ucyh0KSk7CiAgICAgICAgICAgIGJ1Zi5hcHBlbmQoY2xhc3NOYW1lKHQsIGZhbHNlLCBsb2NhbGUpKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBidWYuYXBwZW5kKHByaW50QW5ub3RhdGlvbnModCkpOwogICAgICAgICAgICBidWYuYXBwZW5kKGNsYXNzTmFtZSh0LCB0cnVlLCBsb2NhbGUpKTsKICAgICAgICB9CiAgICAgICAgaWYgKHQuZ2V0VHlwZUFyZ3VtZW50cygpLm5vbkVtcHR5KCkpIHsKICAgICAgICAgICAgYnVmLmFwcGVuZCgnPCcpOwogICAgICAgICAgICBidWYuYXBwZW5kKHZpc2l0VHlwZXModC5nZXRUeXBlQXJndW1lbnRzKCksIGxvY2FsZSkpOwogICAgICAgICAgICBidWYuYXBwZW5kKCc+Jyk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWYudG9TdHJpbmcoKTsKICAgIH0KCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBTdHJpbmcgdmlzaXRNZXRob2RUeXBlKE1ldGhvZFR5cGUgdCwgTG9jYWxlIGxvY2FsZSkgewogICAgICAgIHJldHVybiAiKCIgKyBwcmludE1ldGhvZEFyZ3ModC5hcmd0eXBlcywgZmFsc2UsIGxvY2FsZSkgKyAiKSIgKwogICAgICAgICAgICB2aXNpdCh0LnJlc3R5cGUsIGxvY2FsZSk7CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgU3RyaW5nIHZpc2l0UGFja2FnZVR5cGUoUGFja2FnZVR5cGUgdCwgTG9jYWxlIGxvY2FsZSkgewogICAgICAgIHJldHVybiB0LnRzeW0uZ2V0UXVhbGlmaWVkTmFtZSgpLnRvU3RyaW5nKCk7CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgU3RyaW5nIHZpc2l0V2lsZGNhcmRUeXBlKFdpbGRjYXJkVHlwZSB0LCBMb2NhbGUgbG9jYWxlKSB7CiAgICAgICAgU3RyaW5nQnVpbGRlciBzID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKICAgICAgICBzLmFwcGVuZCh0LmtpbmQpOwogICAgICAgIGlmICh0LmtpbmQgIT0gVU5CT1VORCkgewogICAgICAgICAgICBzLmFwcGVuZChwcmludEFubm90YXRpb25zKHQpKTsKICAgICAgICAgICAgcy5hcHBlbmQodmlzaXQodC50eXBlLCBsb2NhbGUpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHMudG9TdHJpbmcoKTsKICAgIH0KCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBTdHJpbmcgdmlzaXRFcnJvclR5cGUoRXJyb3JUeXBlIHQsIExvY2FsZSBsb2NhbGUpIHsKICAgICAgICByZXR1cm4gdmlzaXRUeXBlKHQsIGxvY2FsZSk7CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgU3RyaW5nIHZpc2l0VHlwZVZhcihUeXBlVmFyIHQsIExvY2FsZSBsb2NhbGUpIHsKICAgICAgICByZXR1cm4gdmlzaXRUeXBlKHQsIGxvY2FsZSk7CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgU3RyaW5nIHZpc2l0TW9kdWxlVHlwZShNb2R1bGVUeXBlIHQsIExvY2FsZSBsb2NhbGUpIHsKICAgICAgICByZXR1cm4gdmlzaXRUeXBlKHQsIGxvY2FsZSk7CiAgICB9CgogICAgcHVibGljIFN0cmluZyB2aXNpdFR5cGUoVHlwZSB0LCBMb2NhbGUgbG9jYWxlKSB7CiAgICAgICAgU3RyaW5nIHMgPSAodC50c3ltID09IG51bGwgfHwgdC50c3ltLm5hbWUgPT0gbnVsbCkKICAgICAgICAgICAgICAgID8gbG9jYWxpemUobG9jYWxlLCAiY29tcGlsZXIubWlzYy50eXBlLm5vbmUiKQogICAgICAgICAgICAgICAgOiB0LnRzeW0ubmFtZS50b1N0cmluZygpOwogICAgICAgIHJldHVybiBzOwogICAgfQoKICAgIC8qKgogICAgICogQ29udmVydHMgYSBjbGFzcyBuYW1lIGludG8gYSAocG9zc2libHkgbG9jYWxpemVkKSBzdHJpbmcuIEFub255bW91cwogICAgICogaW5uZXIgY2xhc3NlcyBnZXQgY29udmVydGVkIGludG8gYSBsb2NhbGl6ZWQgc3RyaW5nLgogICAgICoKICAgICAqIEBwYXJhbSB0IHRoZSB0eXBlIG9mIHRoZSBjbGFzcyB3aG9zZSBuYW1lIGlzIHRvIGJlIHJlbmRlcmVkCiAgICAgKiBAcGFyYW0gbG9uZ2Zvcm0gaWYgc2V0LCB0aGUgY2xhc3MnIGZ1bGxuYW1lIGlzIGRpc3BsYXllZCAtIGlmIHVuc2V0IHRoZQogICAgICogc2hvcnQgbmFtZSBpcyBjaG9zZW4gKHcvbyBwYWNrYWdlKQogICAgICogQHBhcmFtIGxvY2FsZSB0aGUgbG9jYWxlIGluIHdoaWNoIHRoZSBzdHJpbmcgaXMgdG8gYmUgcmVuZGVyZWQKICAgICAqIEByZXR1cm4gbG9jYWxpemVkIHN0cmluZyByZXByZXNlbnRhdGlvbgogICAgICovCiAgICBwcm90ZWN0ZWQgU3RyaW5nIGNsYXNzTmFtZShDbGFzc1R5cGUgdCwgYm9vbGVhbiBsb25nZm9ybSwgTG9jYWxlIGxvY2FsZSkgewogICAgICAgIFN5bWJvbCBzeW0gPSB0LnRzeW07CiAgICAgICAgaWYgKHN5bS5uYW1lLmxlbmd0aCgpID09IDAgJiYgKHN5bS5mbGFncygpICYgQ09NUE9VTkQpICE9IDApIHsKICAgICAgICAgICAgU3RyaW5nQnVpbGRlciBzID0gbmV3IFN0cmluZ0J1aWxkZXIodmlzaXQodC5zdXBlcnR5cGVfZmllbGQsIGxvY2FsZSkpOwogICAgICAgICAgICBmb3IgKExpc3Q8VHlwZT4gaXMgPSB0LmludGVyZmFjZXNfZmllbGQ7IGlzLm5vbkVtcHR5KCk7IGlzID0gaXMudGFpbCkgewogICAgICAgICAgICAgICAgcy5hcHBlbmQoJyYnKTsKICAgICAgICAgICAgICAgIHMuYXBwZW5kKHZpc2l0KGlzLmhlYWQsIGxvY2FsZSkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBzLnRvU3RyaW5nKCk7CiAgICAgICAgfSBlbHNlIGlmIChzeW0ubmFtZS5sZW5ndGgoKSA9PSAwKSB7CiAgICAgICAgICAgIFN0cmluZyBzOwogICAgICAgICAgICBDbGFzc1R5cGUgbm9ybSA9IChDbGFzc1R5cGUpIHQudHN5bS50eXBlOwogICAgICAgICAgICBpZiAobm9ybSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICBzID0gbG9jYWxpemUobG9jYWxlLCAiY29tcGlsZXIubWlzYy5hbm9ueW1vdXMuY2xhc3MiLCAoT2JqZWN0KSBudWxsKTsKICAgICAgICAgICAgfSBlbHNlIGlmIChub3JtLmludGVyZmFjZXNfZmllbGQgIT0gbnVsbCAmJiBub3JtLmludGVyZmFjZXNfZmllbGQubm9uRW1wdHkoKSkgewogICAgICAgICAgICAgICAgcyA9IGxvY2FsaXplKGxvY2FsZSwgImNvbXBpbGVyLm1pc2MuYW5vbnltb3VzLmNsYXNzIiwKICAgICAgICAgICAgICAgICAgICAgICAgdmlzaXQobm9ybS5pbnRlcmZhY2VzX2ZpZWxkLmhlYWQsIGxvY2FsZSkpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcyA9IGxvY2FsaXplKGxvY2FsZSwgImNvbXBpbGVyLm1pc2MuYW5vbnltb3VzLmNsYXNzIiwKICAgICAgICAgICAgICAgICAgICAgICAgdmlzaXQobm9ybS5zdXBlcnR5cGVfZmllbGQsIGxvY2FsZSkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSBpZiAobG9uZ2Zvcm0pIHsKICAgICAgICAgICAgcmV0dXJuIHN5bS5nZXRRdWFsaWZpZWROYW1lKCkudG9TdHJpbmcoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gc3ltLm5hbWUudG9TdHJpbmcoKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBDb252ZXJ0cyBhIHNldCBvZiBtZXRob2QgYXJndW1lbnQgdHlwZXMgaW50byB0aGVpciBjb3JyZXNwb25kaW5nCiAgICAgKiBsb2NhbGl6ZWQgc3RyaW5nIHJlcHJlc2VudGF0aW9uLgogICAgICoKICAgICAqIEBwYXJhbSBhcmdzIGFyZ3VtZW50cyB0byBiZSByZW5kZXJlZAogICAgICogQHBhcmFtIHZhckFyZ3MgaWYgdHJ1ZSwgdGhlIGxhc3QgbWV0aG9kIGFyZ3VtZW50IGlzIHJlZ2FyZGVkIGFzIGEgdmFyYXJnCiAgICAgKiBAcGFyYW0gbG9jYWxlIHRoZSBsb2NhbGUgaW4gd2hpY2ggdGhlIHN0cmluZyBpcyB0byBiZSByZW5kZXJlZAogICAgICogQHJldHVybiBsb2NhbGl6ZWQgc3RyaW5nIHJlcHJlc2VudGF0aW9uCiAgICAgKi8KICAgIHByb3RlY3RlZCBTdHJpbmcgcHJpbnRNZXRob2RBcmdzKExpc3Q8VHlwZT4gYXJncywgYm9vbGVhbiB2YXJBcmdzLCBMb2NhbGUgbG9jYWxlKSB7CiAgICAgICAgaWYgKCF2YXJBcmdzKSB7CiAgICAgICAgICAgIHJldHVybiB2aXNpdFR5cGVzKGFyZ3MsIGxvY2FsZSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgU3RyaW5nQnVpbGRlciBidWYgPSBuZXcgU3RyaW5nQnVpbGRlcigpOwogICAgICAgICAgICB3aGlsZSAoYXJncy50YWlsLm5vbkVtcHR5KCkpIHsKICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQodmlzaXQoYXJncy5oZWFkLCBsb2NhbGUpKTsKICAgICAgICAgICAgICAgIGFyZ3MgPSBhcmdzLnRhaWw7CiAgICAgICAgICAgICAgICBidWYuYXBwZW5kKCcsJyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGFyZ3MuaGVhZC5oYXNUYWcoVHlwZVRhZy5BUlJBWSkpIHsKICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQodmlzaXQoKChBcnJheVR5cGUpIGFyZ3MuaGVhZCkuZWxlbXR5cGUsIGxvY2FsZSkpOwogICAgICAgICAgICAgICAgaWYgKGFyZ3MuaGVhZC5nZXRBbm5vdGF0aW9uTWlycm9ycygpLm5vbkVtcHR5KCkpIHsKICAgICAgICAgICAgICAgICAgICBidWYuYXBwZW5kKCcgJyk7CiAgICAgICAgICAgICAgICAgICAgYnVmLmFwcGVuZChhcmdzLmhlYWQuZ2V0QW5ub3RhdGlvbk1pcnJvcnMoKSk7CiAgICAgICAgICAgICAgICAgICAgYnVmLmFwcGVuZCgnICcpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnVmLmFwcGVuZCgiLi4uIik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBidWYuYXBwZW5kKHZpc2l0KGFyZ3MuaGVhZCwgbG9jYWxlKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGJ1Zi50b1N0cmluZygpOwogICAgICAgIH0KICAgIH0KCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBTdHJpbmcgdmlzaXRDbGFzc1N5bWJvbChDbGFzc1N5bWJvbCBzeW0sIExvY2FsZSBsb2NhbGUpIHsKICAgICAgICByZXR1cm4gc3ltLm5hbWUuaXNFbXB0eSgpCiAgICAgICAgICAgICAgICA/IGxvY2FsaXplKGxvY2FsZSwgImNvbXBpbGVyLm1pc2MuYW5vbnltb3VzLmNsYXNzIiwgc3ltLmZsYXRuYW1lKQogICAgICAgICAgICAgICAgOiBzeW0uZnVsbG5hbWUudG9TdHJpbmcoKTsKICAgIH0KCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBTdHJpbmcgdmlzaXRNZXRob2RTeW1ib2woTWV0aG9kU3ltYm9sIHMsIExvY2FsZSBsb2NhbGUpIHsKICAgICAgICBpZiAocy5pc1N0YXRpY09ySW5zdGFuY2VJbml0KCkpIHsKICAgICAgICAgICAgcmV0dXJuIHMub3duZXIubmFtZS50b1N0cmluZygpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIFN0cmluZyBtcyA9IChzLm5hbWUgPT0gcy5uYW1lLnRhYmxlLm5hbWVzLmluaXQpCiAgICAgICAgICAgICAgICAgICAgPyBzLm93bmVyLm5hbWUudG9TdHJpbmcoKQogICAgICAgICAgICAgICAgICAgIDogcy5uYW1lLnRvU3RyaW5nKCk7CiAgICAgICAgICAgIGlmIChzLnR5cGUgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgaWYgKHMudHlwZS5oYXNUYWcoRk9SQUxMKSkgewogICAgICAgICAgICAgICAgICAgIG1zID0gIjwiICsgdmlzaXRUeXBlcyhzLnR5cGUuZ2V0VHlwZUFyZ3VtZW50cygpLCBsb2NhbGUpICsgIj4iICsgbXM7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBtcyArPSAiKCIgKyBwcmludE1ldGhvZEFyZ3MoCiAgICAgICAgICAgICAgICAgICAgICAgIHMudHlwZS5nZXRQYXJhbWV0ZXJUeXBlcygpLAogICAgICAgICAgICAgICAgICAgICAgICAocy5mbGFncygpICYgVkFSQVJHUykgIT0gMCwKICAgICAgICAgICAgICAgICAgICAgICAgbG9jYWxlKSArICIpIjsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gbXM7CiAgICAgICAgfQogICAgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIFN0cmluZyB2aXNpdE9wZXJhdG9yU3ltYm9sKE9wZXJhdG9yU3ltYm9sIHMsIExvY2FsZSBsb2NhbGUpIHsKICAgICAgICByZXR1cm4gdmlzaXRNZXRob2RTeW1ib2wocywgbG9jYWxlKTsKICAgIH0KCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBTdHJpbmcgdmlzaXRQYWNrYWdlU3ltYm9sKFBhY2thZ2VTeW1ib2wgcywgTG9jYWxlIGxvY2FsZSkgewogICAgICAgIHJldHVybiBzLmlzVW5uYW1lZCgpCiAgICAgICAgICAgICAgICA/IGxvY2FsaXplKGxvY2FsZSwgImNvbXBpbGVyLm1pc2MudW5uYW1lZC5wYWNrYWdlIikKICAgICAgICAgICAgICAgIDogcy5mdWxsbmFtZS50b1N0cmluZygpOwogICAgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIFN0cmluZyB2aXNpdFR5cGVTeW1ib2woVHlwZVN5bWJvbCBzLCBMb2NhbGUgbG9jYWxlKSB7CiAgICAgICAgcmV0dXJuIHZpc2l0U3ltYm9sKHMsIGxvY2FsZSk7CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgU3RyaW5nIHZpc2l0VmFyU3ltYm9sKFZhclN5bWJvbCBzLCBMb2NhbGUgbG9jYWxlKSB7CiAgICAgICAgcmV0dXJuIHZpc2l0U3ltYm9sKHMsIGxvY2FsZSk7CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgU3RyaW5nIHZpc2l0U3ltYm9sKFN5bWJvbCBzLCBMb2NhbGUgbG9jYWxlKSB7CiAgICAgICAgcmV0dXJuIHMubmFtZS50b1N0cmluZygpOwogICAgfQp9ClBLAwQKAAAIAAAGO6lK2omyx0Y0AQBGNAEAJAAAAGNvbS9zdW4vdG9vbHMvamF2YWMvY29kZS9TeW1ib2wuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMTk5OSwgMjAxNywgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGU7CgppbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uQW5ub3RhdGlvbjsKaW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLkluaGVyaXRlZDsKaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKaW1wb3J0IGphdmEudXRpbC5FbnVtU2V0OwppbXBvcnQgamF2YS51dGlsLk1hcDsKaW1wb3J0IGphdmEudXRpbC5TZXQ7CmltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5DYWxsYWJsZTsKCmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuRWxlbWVudDsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC5FbGVtZW50S2luZDsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC5FbGVtZW50VmlzaXRvcjsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC5FeGVjdXRhYmxlRWxlbWVudDsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC5Nb2RpZmllcjsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC5Nb2R1bGVFbGVtZW50OwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5lbGVtZW50Lk5lc3RpbmdLaW5kOwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5lbGVtZW50LlBhY2thZ2VFbGVtZW50OwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5lbGVtZW50LlR5cGVFbGVtZW50OwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5lbGVtZW50LlR5cGVQYXJhbWV0ZXJFbGVtZW50OwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5lbGVtZW50LlZhcmlhYmxlRWxlbWVudDsKaW1wb3J0IGphdmF4LnRvb2xzLkphdmFGaWxlTWFuYWdlcjsKaW1wb3J0IGphdmF4LnRvb2xzLkphdmFGaWxlT2JqZWN0OwoKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5DbGFzc0ZpbmRlci5CYWRFbmNsb3NpbmdNZXRob2RBdHRyOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLkRpcmVjdGl2ZS5SZXF1aXJlc0ZsYWc7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuS2luZHMuS2luZDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29tcC5Bbm5vdGF0ZS5Bbm5vdGF0aW9uVHlwZU1ldGFkYXRhOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlNjb3BlLldyaXRlYWJsZVNjb3BlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlR5cGUuKjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29tcC5BdHRyOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb21wLkF0dHJDb250ZXh0OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb21wLkVudjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuanZtLio7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuSkNUcmVlLkpDRmllbGRBY2Nlc3M7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuSkNUcmVlLkpDVmFyaWFibGVEZWNsOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkpDVHJlZS5UYWc7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuKjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5EZWZpbmVkQnkuQXBpOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLk5hbWU7CgppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5GbGFncy4qOwppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5LaW5kcy4qOwppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5LaW5kcy5LaW5kLio7CmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlNjb3BlLkxvb2t1cEtpbmQuTk9OX1JFQ1VSU0lWRTsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuU3ltYm9sLk9wZXJhdG9yU3ltYm9sLkFjY2Vzc0NvZGUuRklSU1RBU0dPUDsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuVHlwZVRhZy5DTEFTUzsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuVHlwZVRhZy5GT1JBTEw7CmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlR5cGVUYWcuVFlQRVZBUjsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmp2bS5CeXRlQ29kZXMuaWFkZDsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmp2bS5CeXRlQ29kZXMuaXNobGw7CmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5qdm0uQnl0ZUNvZGVzLmx1c2hybDsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmp2bS5CeXRlQ29kZXMubHhvcjsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmp2bS5CeXRlQ29kZXMuc3RyaW5nX2FkZDsKCi8qKiBSb290IGNsYXNzIGZvciBKYXZhIHN5bWJvbHMuIEl0IGNvbnRhaW5zIHN1YmNsYXNzZXMKICogIGZvciBzcGVjaWZpYyBzb3J0cyBvZiBzeW1ib2xzLCBzdWNoIGFzIHZhcmlhYmxlcywgbWV0aG9kcyBhbmQgb3BlcmF0b3JzLAogKiAgdHlwZXMsIHBhY2thZ2VzLiBFYWNoIHN1YmNsYXNzIGlzIHJlcHJlc2VudGVkIGFzIGEgc3RhdGljIGlubmVyIGNsYXNzCiAqICBpbnNpZGUgU3ltYm9sLgogKgogKiAgPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24gcmlzay4KICogIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yCiAqICBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+CiAqLwpwdWJsaWMgYWJzdHJhY3QgY2xhc3MgU3ltYm9sIGV4dGVuZHMgQW5ub0NvbnN0cnVjdCBpbXBsZW1lbnRzIEVsZW1lbnQgewoKICAgIC8qKiBUaGUga2luZCBvZiB0aGlzIHN5bWJvbC4KICAgICAqICBAc2VlIEtpbmRzCiAgICAgKi8KICAgIHB1YmxpYyBLaW5kIGtpbmQ7CgogICAgLyoqIFRoZSBmbGFncyBvZiB0aGlzIHN5bWJvbC4KICAgICAqLwogICAgcHVibGljIGxvbmcgZmxhZ3NfZmllbGQ7CgogICAgLyoqIEFuIGFjY2Vzc29yIG1ldGhvZCBmb3IgdGhlIGZsYWdzIG9mIHRoaXMgc3ltYm9sLgogICAgICogIEZsYWdzIG9mIGNsYXNzIHN5bWJvbHMgc2hvdWxkIGJlIGFjY2Vzc2VkIHRocm91Z2ggdGhlIGFjY2Vzc29yCiAgICAgKiAgbWV0aG9kIHRvIG1ha2Ugc3VyZSB0aGF0IHRoZSBjbGFzcyBzeW1ib2wgaXMgbG9hZGVkLgogICAgICovCiAgICBwdWJsaWMgbG9uZyBmbGFncygpIHsgcmV0dXJuIGZsYWdzX2ZpZWxkOyB9CgogICAgLyoqIFRoZSBuYW1lIG9mIHRoaXMgc3ltYm9sIGluIFV0ZjggcmVwcmVzZW50YXRpb24uCiAgICAgKi8KICAgIHB1YmxpYyBOYW1lIG5hbWU7CgogICAgLyoqIFRoZSB0eXBlIG9mIHRoaXMgc3ltYm9sLgogICAgICovCiAgICBwdWJsaWMgVHlwZSB0eXBlOwoKICAgIC8qKiBUaGUgb3duZXIgb2YgdGhpcyBzeW1ib2wuCiAgICAgKi8KICAgIHB1YmxpYyBTeW1ib2wgb3duZXI7CgogICAgLyoqIFRoZSBjb21wbGV0ZXIgb2YgdGhpcyBzeW1ib2wuCiAgICAgKiBUaGlzIHNob3VsZCBuZXZlciBlcXVhbCBudWxsIChOVUxMX0NPTVBMRVRFUiBzaG91bGQgYmUgdXNlZCBpbnN0ZWFkKS4KICAgICAqLwogICAgcHVibGljIENvbXBsZXRlciBjb21wbGV0ZXI7CgogICAgLyoqIEEgY2FjaGUgZm9yIHRoZSB0eXBlIGVyYXN1cmUgb2YgdGhpcyBzeW1ib2wuCiAgICAgKi8KICAgIHB1YmxpYyBUeXBlIGVyYXN1cmVfZmllbGQ7CgogICAgLy8gPGVkaXRvci1mb2xkIGRlZmF1bHRzdGF0ZT0iY29sbGFwc2VkIiBkZXNjPSJhbm5vdGF0aW9ucyI+CgogICAgLyoqIFRoZSBhdHRyaWJ1dGVzIG9mIHRoaXMgc3ltYm9sIGFyZSBjb250YWluZWQgaW4gdGhpcwogICAgICogU3ltYm9sTWV0YWRhdGEuIFRoZSBTeW1ib2xNZXRhZGF0YSBpbnN0YW5jZSBpcyBOT1QgaW1tdXRhYmxlLgogICAgICovCiAgICBwcm90ZWN0ZWQgU3ltYm9sTWV0YWRhdGEgbWV0YWRhdGE7CgoKICAgIC8qKiBBbiBhY2Nlc3NvciBtZXRob2QgZm9yIHRoZSBhdHRyaWJ1dGVzIG9mIHRoaXMgc3ltYm9sLgogICAgICogIEF0dHJpYnV0ZXMgb2YgY2xhc3Mgc3ltYm9scyBzaG91bGQgYmUgYWNjZXNzZWQgdGhyb3VnaCB0aGUgYWNjZXNzb3IKICAgICAqICBtZXRob2QgdG8gbWFrZSBzdXJlIHRoYXQgdGhlIGNsYXNzIHN5bWJvbCBpcyBsb2FkZWQuCiAgICAgKi8KICAgIHB1YmxpYyBMaXN0PEF0dHJpYnV0ZS5Db21wb3VuZD4gZ2V0UmF3QXR0cmlidXRlcygpIHsKICAgICAgICByZXR1cm4gKG1ldGFkYXRhID09IG51bGwpCiAgICAgICAgICAgICAgICA/IExpc3QubmlsKCkKICAgICAgICAgICAgICAgIDogbWV0YWRhdGEuZ2V0RGVjbGFyYXRpb25BdHRyaWJ1dGVzKCk7CiAgICB9CgogICAgLyoqIEFuIGFjY2Vzc29yIG1ldGhvZCBmb3IgdGhlIHR5cGUgYXR0cmlidXRlcyBvZiB0aGlzIHN5bWJvbC4KICAgICAqICBBdHRyaWJ1dGVzIG9mIGNsYXNzIHN5bWJvbHMgc2hvdWxkIGJlIGFjY2Vzc2VkIHRocm91Z2ggdGhlIGFjY2Vzc29yCiAgICAgKiAgbWV0aG9kIHRvIG1ha2Ugc3VyZSB0aGF0IHRoZSBjbGFzcyBzeW1ib2wgaXMgbG9hZGVkLgogICAgICovCiAgICBwdWJsaWMgTGlzdDxBdHRyaWJ1dGUuVHlwZUNvbXBvdW5kPiBnZXRSYXdUeXBlQXR0cmlidXRlcygpIHsKICAgICAgICByZXR1cm4gKG1ldGFkYXRhID09IG51bGwpCiAgICAgICAgICAgICAgICA/IExpc3QubmlsKCkKICAgICAgICAgICAgICAgIDogbWV0YWRhdGEuZ2V0VHlwZUF0dHJpYnV0ZXMoKTsKICAgIH0KCiAgICAvKiogRmV0Y2ggYSBwYXJ0aWN1bGFyIGFubm90YXRpb24gZnJvbSBhIHN5bWJvbC4gKi8KICAgIHB1YmxpYyBBdHRyaWJ1dGUuQ29tcG91bmQgYXR0cmlidXRlKFN5bWJvbCBhbm5vKSB7CiAgICAgICAgZm9yIChBdHRyaWJ1dGUuQ29tcG91bmQgYSA6IGdldFJhd0F0dHJpYnV0ZXMoKSkgewogICAgICAgICAgICBpZiAoYS50eXBlLnRzeW0gPT0gYW5ubykgcmV0dXJuIGE7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIHB1YmxpYyBib29sZWFuIGFubm90YXRpb25zUGVuZGluZ0NvbXBsZXRpb24oKSB7CiAgICAgICAgcmV0dXJuIG1ldGFkYXRhID09IG51bGwgPyBmYWxzZSA6IG1ldGFkYXRhLnBlbmRpbmdDb21wbGV0aW9uKCk7CiAgICB9CgogICAgcHVibGljIHZvaWQgYXBwZW5kQXR0cmlidXRlcyhMaXN0PEF0dHJpYnV0ZS5Db21wb3VuZD4gbCkgewogICAgICAgIGlmIChsLm5vbkVtcHR5KCkpIHsKICAgICAgICAgICAgaW5pdGVkTWV0YWRhdGEoKS5hcHBlbmQobCk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyB2b2lkIGFwcGVuZENsYXNzSW5pdFR5cGVBdHRyaWJ1dGVzKExpc3Q8QXR0cmlidXRlLlR5cGVDb21wb3VuZD4gbCkgewogICAgICAgIGlmIChsLm5vbkVtcHR5KCkpIHsKICAgICAgICAgICAgaW5pdGVkTWV0YWRhdGEoKS5hcHBlbmRDbGFzc0luaXRUeXBlQXR0cmlidXRlcyhsKTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHZvaWQgYXBwZW5kSW5pdFR5cGVBdHRyaWJ1dGVzKExpc3Q8QXR0cmlidXRlLlR5cGVDb21wb3VuZD4gbCkgewogICAgICAgIGlmIChsLm5vbkVtcHR5KCkpIHsKICAgICAgICAgICAgaW5pdGVkTWV0YWRhdGEoKS5hcHBlbmRJbml0VHlwZUF0dHJpYnV0ZXMobCk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyB2b2lkIGFwcGVuZFVuaXF1ZVR5cGVBdHRyaWJ1dGVzKExpc3Q8QXR0cmlidXRlLlR5cGVDb21wb3VuZD4gbCkgewogICAgICAgIGlmIChsLm5vbkVtcHR5KCkpIHsKICAgICAgICAgICAgaW5pdGVkTWV0YWRhdGEoKS5hcHBlbmRVbmlxdWVUeXBlcyhsKTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIExpc3Q8QXR0cmlidXRlLlR5cGVDb21wb3VuZD4gZ2V0Q2xhc3NJbml0VHlwZUF0dHJpYnV0ZXMoKSB7CiAgICAgICAgcmV0dXJuIChtZXRhZGF0YSA9PSBudWxsKQogICAgICAgICAgICAgICAgPyBMaXN0Lm5pbCgpCiAgICAgICAgICAgICAgICA6IG1ldGFkYXRhLmdldENsYXNzSW5pdFR5cGVBdHRyaWJ1dGVzKCk7CiAgICB9CgogICAgcHVibGljIExpc3Q8QXR0cmlidXRlLlR5cGVDb21wb3VuZD4gZ2V0SW5pdFR5cGVBdHRyaWJ1dGVzKCkgewogICAgICAgIHJldHVybiAobWV0YWRhdGEgPT0gbnVsbCkKICAgICAgICAgICAgICAgID8gTGlzdC5uaWwoKQogICAgICAgICAgICAgICAgOiBtZXRhZGF0YS5nZXRJbml0VHlwZUF0dHJpYnV0ZXMoKTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCBzZXRJbml0VHlwZUF0dHJpYnV0ZXMoTGlzdDxBdHRyaWJ1dGUuVHlwZUNvbXBvdW5kPiBsKSB7CiAgICAgICAgaW5pdGVkTWV0YWRhdGEoKS5zZXRJbml0VHlwZUF0dHJpYnV0ZXMobCk7CiAgICB9CgogICAgcHVibGljIHZvaWQgc2V0Q2xhc3NJbml0VHlwZUF0dHJpYnV0ZXMoTGlzdDxBdHRyaWJ1dGUuVHlwZUNvbXBvdW5kPiBsKSB7CiAgICAgICAgaW5pdGVkTWV0YWRhdGEoKS5zZXRDbGFzc0luaXRUeXBlQXR0cmlidXRlcyhsKTsKICAgIH0KCiAgICBwdWJsaWMgTGlzdDxBdHRyaWJ1dGUuQ29tcG91bmQ+IGdldERlY2xhcmF0aW9uQXR0cmlidXRlcygpIHsKICAgICAgICByZXR1cm4gKG1ldGFkYXRhID09IG51bGwpCiAgICAgICAgICAgICAgICA/IExpc3QubmlsKCkKICAgICAgICAgICAgICAgIDogbWV0YWRhdGEuZ2V0RGVjbGFyYXRpb25BdHRyaWJ1dGVzKCk7CiAgICB9CgogICAgcHVibGljIGJvb2xlYW4gaGFzQW5ub3RhdGlvbnMoKSB7CiAgICAgICAgcmV0dXJuIChtZXRhZGF0YSAhPSBudWxsICYmICFtZXRhZGF0YS5pc0VtcHR5KCkpOwogICAgfQoKICAgIHB1YmxpYyBib29sZWFuIGhhc1R5cGVBbm5vdGF0aW9ucygpIHsKICAgICAgICByZXR1cm4gKG1ldGFkYXRhICE9IG51bGwgJiYgIW1ldGFkYXRhLmlzVHlwZXNFbXB0eSgpKTsKICAgIH0KCiAgICBwdWJsaWMgYm9vbGVhbiBpc0NvbXBsZXRlZCgpIHsKICAgICAgICByZXR1cm4gY29tcGxldGVyLmlzVGVybWluYWwoKTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCBwcmVwZW5kQXR0cmlidXRlcyhMaXN0PEF0dHJpYnV0ZS5Db21wb3VuZD4gbCkgewogICAgICAgIGlmIChsLm5vbkVtcHR5KCkpIHsKICAgICAgICAgICAgaW5pdGVkTWV0YWRhdGEoKS5wcmVwZW5kKGwpOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgdm9pZCByZXNldEFubm90YXRpb25zKCkgewogICAgICAgIGluaXRlZE1ldGFkYXRhKCkucmVzZXQoKTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCBzZXRBdHRyaWJ1dGVzKFN5bWJvbCBvdGhlcikgewogICAgICAgIGlmIChtZXRhZGF0YSAhPSBudWxsIHx8IG90aGVyLm1ldGFkYXRhICE9IG51bGwpIHsKICAgICAgICAgICAgaW5pdGVkTWV0YWRhdGEoKS5zZXRBdHRyaWJ1dGVzKG90aGVyLm1ldGFkYXRhKTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHZvaWQgc2V0RGVjbGFyYXRpb25BdHRyaWJ1dGVzKExpc3Q8QXR0cmlidXRlLkNvbXBvdW5kPiBhKSB7CiAgICAgICAgaWYgKG1ldGFkYXRhICE9IG51bGwgfHwgYS5ub25FbXB0eSgpKSB7CiAgICAgICAgICAgIGluaXRlZE1ldGFkYXRhKCkuc2V0RGVjbGFyYXRpb25BdHRyaWJ1dGVzKGEpOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgdm9pZCBzZXRUeXBlQXR0cmlidXRlcyhMaXN0PEF0dHJpYnV0ZS5UeXBlQ29tcG91bmQ+IGEpIHsKICAgICAgICBpZiAobWV0YWRhdGEgIT0gbnVsbCB8fCBhLm5vbkVtcHR5KCkpIHsKICAgICAgICAgICAgaWYgKG1ldGFkYXRhID09IG51bGwpCiAgICAgICAgICAgICAgICBtZXRhZGF0YSA9IG5ldyBTeW1ib2xNZXRhZGF0YSh0aGlzKTsKICAgICAgICAgICAgbWV0YWRhdGEuc2V0VHlwZUF0dHJpYnV0ZXMoYSk7CiAgICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgU3ltYm9sTWV0YWRhdGEgaW5pdGVkTWV0YWRhdGEoKSB7CiAgICAgICAgaWYgKG1ldGFkYXRhID09IG51bGwpCiAgICAgICAgICAgIG1ldGFkYXRhID0gbmV3IFN5bWJvbE1ldGFkYXRhKHRoaXMpOwogICAgICAgIHJldHVybiBtZXRhZGF0YTsKICAgIH0KCiAgICAvKiogVGhpcyBtZXRob2QgaXMgaW50ZW5kZWQgZm9yIGRlYnVnZ2luZyBvbmx5LiAqLwogICAgcHVibGljIFN5bWJvbE1ldGFkYXRhIGdldE1ldGFkYXRhKCkgewogICAgICAgIHJldHVybiBtZXRhZGF0YTsKICAgIH0KCiAgICAvLyA8L2VkaXRvci1mb2xkPgoKICAgIC8qKiBDb25zdHJ1Y3QgYSBzeW1ib2wgd2l0aCBnaXZlbiBraW5kLCBmbGFncywgbmFtZSwgdHlwZSBhbmQgb3duZXIuCiAgICAgKi8KICAgIHB1YmxpYyBTeW1ib2woS2luZCBraW5kLCBsb25nIGZsYWdzLCBOYW1lIG5hbWUsIFR5cGUgdHlwZSwgU3ltYm9sIG93bmVyKSB7CiAgICAgICAgdGhpcy5raW5kID0ga2luZDsKICAgICAgICB0aGlzLmZsYWdzX2ZpZWxkID0gZmxhZ3M7CiAgICAgICAgdGhpcy50eXBlID0gdHlwZTsKICAgICAgICB0aGlzLm93bmVyID0gb3duZXI7CiAgICAgICAgdGhpcy5jb21wbGV0ZXIgPSBDb21wbGV0ZXIuTlVMTF9DT01QTEVURVI7CiAgICAgICAgdGhpcy5lcmFzdXJlX2ZpZWxkID0gbnVsbDsKICAgICAgICB0aGlzLm5hbWUgPSBuYW1lOwogICAgfQoKICAgIC8qKiBDbG9uZSB0aGlzIHN5bWJvbCB3aXRoIG5ldyBvd25lci4KICAgICAqICBMZWdhbCBvbmx5IGZvciBmaWVsZHMgYW5kIG1ldGhvZHMuCiAgICAgKi8KICAgIHB1YmxpYyBTeW1ib2wgY2xvbmUoU3ltYm9sIG5ld093bmVyKSB7CiAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCk7CiAgICB9CgogICAgcHVibGljIDxSLCBQPiBSIGFjY2VwdChTeW1ib2wuVmlzaXRvcjxSLCBQPiB2LCBQIHApIHsKICAgICAgICByZXR1cm4gdi52aXNpdFN5bWJvbCh0aGlzLCBwKTsKICAgIH0KCiAgICAvKiogVGhlIEphdmEgc291cmNlIHdoaWNoIHRoaXMgc3ltYm9sIHJlcHJlc2VudHMuCiAgICAgKiAgQSBkZXNjcmlwdGlvbiBvZiB0aGlzIHN5bWJvbDsgb3ZlcnJpZGVzIE9iamVjdC4KICAgICAqLwogICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKICAgICAgICByZXR1cm4gbmFtZS50b1N0cmluZygpOwogICAgfQoKICAgIC8qKiBBIEphdmEgc291cmNlIGRlc2NyaXB0aW9uIG9mIHRoZSBsb2NhdGlvbiBvZiB0aGlzIHN5bWJvbDsgdXNlZCBmb3IKICAgICAqICBlcnJvciByZXBvcnRpbmcuCiAgICAgKgogICAgICogQHJldHVybiBudWxsIGlmIHRoZSBzeW1ib2wgaXMgYSBwYWNrYWdlIG9yIGEgdG9wbGV2ZWwgY2xhc3MgZGVmaW5lZCBpbgogICAgICogdGhlIGRlZmF1bHQgcGFja2FnZTsgb3RoZXJ3aXNlLCB0aGUgb3duZXIgc3ltYm9sIGlzIHJldHVybmVkCiAgICAgKi8KICAgIHB1YmxpYyBTeW1ib2wgbG9jYXRpb24oKSB7CiAgICAgICAgaWYgKG93bmVyLm5hbWUgPT0gbnVsbCB8fCAob3duZXIubmFtZS5pc0VtcHR5KCkgJiYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAob3duZXIuZmxhZ3MoKSAmIEJMT0NLKSA9PSAwICYmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3duZXIua2luZCAhPSBQQ0sgJiYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvd25lci5raW5kICE9IFRZUCkpIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiBvd25lcjsKICAgIH0KCiAgICBwdWJsaWMgU3ltYm9sIGxvY2F0aW9uKFR5cGUgc2l0ZSwgVHlwZXMgdHlwZXMpIHsKICAgICAgICBpZiAob3duZXIubmFtZSA9PSBudWxsIHx8IG93bmVyLm5hbWUuaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJldHVybiBsb2NhdGlvbigpOwogICAgICAgIH0KICAgICAgICBpZiAob3duZXIudHlwZS5oYXNUYWcoQ0xBU1MpKSB7CiAgICAgICAgICAgIFR5cGUgb3duZXJ0eXBlID0gdHlwZXMuYXNPdXRlclN1cGVyKHNpdGUsIG93bmVyKTsKICAgICAgICAgICAgaWYgKG93bmVydHlwZSAhPSBudWxsKSByZXR1cm4gb3duZXJ0eXBlLnRzeW07CiAgICAgICAgfQogICAgICAgIHJldHVybiBvd25lcjsKICAgIH0KCiAgICBwdWJsaWMgU3ltYm9sIGJhc2VTeW1ib2woKSB7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CgogICAgLyoqIFRoZSBzeW1ib2wncyBlcmFzZWQgdHlwZS4KICAgICAqLwogICAgcHVibGljIFR5cGUgZXJhc3VyZShUeXBlcyB0eXBlcykgewogICAgICAgIGlmIChlcmFzdXJlX2ZpZWxkID09IG51bGwpCiAgICAgICAgICAgIGVyYXN1cmVfZmllbGQgPSB0eXBlcy5lcmFzdXJlKHR5cGUpOwogICAgICAgIHJldHVybiBlcmFzdXJlX2ZpZWxkOwogICAgfQoKICAgIC8qKiBUaGUgZXh0ZXJuYWwgdHlwZSBvZiBhIHN5bWJvbC4gVGhpcyBpcyB0aGUgc3ltYm9sJ3MgZXJhc2VkIHR5cGUKICAgICAqICBleGNlcHQgZm9yIGNvbnN0cnVjdG9ycyBvZiBpbm5lciBjbGFzc2VzIHdoaWNoIGdldCB0aGUgZW5jbG9zaW5nCiAgICAgKiAgaW5zdGFuY2UgY2xhc3MgYWRkZWQgYXMgZmlyc3QgYXJndW1lbnQuCiAgICAgKi8KICAgIHB1YmxpYyBUeXBlIGV4dGVybmFsVHlwZShUeXBlcyB0eXBlcykgewogICAgICAgIFR5cGUgdCA9IGVyYXN1cmUodHlwZXMpOwogICAgICAgIGlmIChuYW1lID09IG5hbWUudGFibGUubmFtZXMuaW5pdCAmJiBvd25lci5oYXNPdXRlckluc3RhbmNlKCkpIHsKICAgICAgICAgICAgVHlwZSBvdXRlclRoaXNUeXBlID0gdHlwZXMuZXJhc3VyZShvd25lci50eXBlLmdldEVuY2xvc2luZ1R5cGUoKSk7CiAgICAgICAgICAgIHJldHVybiBuZXcgTWV0aG9kVHlwZSh0LmdldFBhcmFtZXRlclR5cGVzKCkucHJlcGVuZChvdXRlclRoaXNUeXBlKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHQuZ2V0UmV0dXJuVHlwZSgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdC5nZXRUaHJvd25UeXBlcygpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdC50c3ltKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gdDsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIGJvb2xlYW4gaXNEZXByZWNhdGVkKCkgewogICAgICAgIHJldHVybiAoZmxhZ3NfZmllbGQgJiBERVBSRUNBVEVEKSAhPSAwOwogICAgfQoKICAgIHB1YmxpYyBib29sZWFuIGhhc0RlcHJlY2F0ZWRBbm5vdGF0aW9uKCkgewogICAgICAgIHJldHVybiAoZmxhZ3NfZmllbGQgJiBERVBSRUNBVEVEX0FOTk9UQVRJT04pICE9IDA7CiAgICB9CgogICAgcHVibGljIGJvb2xlYW4gaXNEZXByZWNhdGVkRm9yUmVtb3ZhbCgpIHsKICAgICAgICByZXR1cm4gKGZsYWdzX2ZpZWxkICYgREVQUkVDQVRFRF9SRU1PVkFMKSAhPSAwOwogICAgfQoKICAgIHB1YmxpYyBib29sZWFuIGlzRGVwcmVjYXRhYmxlVmlhQW5ub3RhdGlvbigpIHsKICAgICAgICBzd2l0Y2ggKGdldEtpbmQoKSkgewogICAgICAgICAgICBjYXNlIExPQ0FMX1ZBUklBQkxFOgogICAgICAgICAgICBjYXNlIFBBQ0tBR0U6CiAgICAgICAgICAgIGNhc2UgUEFSQU1FVEVSOgogICAgICAgICAgICBjYXNlIFJFU09VUkNFX1ZBUklBQkxFOgogICAgICAgICAgICBjYXNlIEVYQ0VQVElPTl9QQVJBTUVURVI6CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIGJvb2xlYW4gaXNTdGF0aWMoKSB7CiAgICAgICAgcmV0dXJuCiAgICAgICAgICAgIChmbGFncygpICYgU1RBVElDKSAhPSAwIHx8CiAgICAgICAgICAgIChvd25lci5mbGFncygpICYgSU5URVJGQUNFKSAhPSAwICYmIGtpbmQgIT0gTVRIICYmCiAgICAgICAgICAgICBuYW1lICE9IG5hbWUudGFibGUubmFtZXMuX3RoaXM7CiAgICB9CgogICAgcHVibGljIGJvb2xlYW4gaXNJbnRlcmZhY2UoKSB7CiAgICAgICAgcmV0dXJuIChmbGFncygpICYgSU5URVJGQUNFKSAhPSAwOwogICAgfQoKICAgIHB1YmxpYyBib29sZWFuIGlzUHJpdmF0ZSgpIHsKICAgICAgICByZXR1cm4gKGZsYWdzX2ZpZWxkICYgRmxhZ3MuQWNjZXNzRmxhZ3MpID09IFBSSVZBVEU7CiAgICB9CgogICAgcHVibGljIGJvb2xlYW4gaXNFbnVtKCkgewogICAgICAgIHJldHVybiAoZmxhZ3MoKSAmIEVOVU0pICE9IDA7CiAgICB9CgogICAgLyoqIElzIHRoaXMgc3ltYm9sIGRlY2xhcmVkIChkaXJlY3RseSBvciBpbmRpcmVjdGx5KSBsb2NhbAogICAgICogIHRvIGEgbWV0aG9kIG9yIHZhcmlhYmxlIGluaXRpYWxpemVyPwogICAgICogIEFsc28gaW5jbHVkZXMgZmllbGRzIG9mIGlubmVyIGNsYXNzZXMgd2hpY2ggYXJlIGluCiAgICAgKiAgdHVybiBsb2NhbCB0byBhIG1ldGhvZCBvciB2YXJpYWJsZSBpbml0aWFsaXplci4KICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gaXNMb2NhbCgpIHsKICAgICAgICByZXR1cm4KICAgICAgICAgICAgKG93bmVyLmtpbmQubWF0Y2hlcyhLaW5kU2VsZWN0b3IuVkFMX01USCkgfHwKICAgICAgICAgICAgIChvd25lci5raW5kID09IFRZUCAmJiBvd25lci5pc0xvY2FsKCkpKTsKICAgIH0KCiAgICAvKiogSGFzIHRoaXMgc3ltYm9sIGFuIGVtcHR5IG5hbWU/IFRoaXMgaW5jbHVkZXMgYW5vbnltb3VzCiAgICAgKiAgaW5uZXIgY2xhc3Nlcy4KICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gaXNBbm9ueW1vdXMoKSB7CiAgICAgICAgcmV0dXJuIG5hbWUuaXNFbXB0eSgpOwogICAgfQoKICAgIC8qKiBJcyB0aGlzIHN5bWJvbCBhIGNvbnN0cnVjdG9yPwogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBpc0NvbnN0cnVjdG9yKCkgewogICAgICAgIHJldHVybiBuYW1lID09IG5hbWUudGFibGUubmFtZXMuaW5pdDsKICAgIH0KCiAgICAvKiogVGhlIGZ1bGx5IHF1YWxpZmllZCBuYW1lIG9mIHRoaXMgc3ltYm9sLgogICAgICogIFRoaXMgaXMgdGhlIHNhbWUgYXMgdGhlIHN5bWJvbCdzIG5hbWUgZXhjZXB0IGZvciBjbGFzcyBzeW1ib2xzLAogICAgICogIHdoaWNoIGFyZSBoYW5kbGVkIHNlcGFyYXRlbHkuCiAgICAgKi8KICAgIHB1YmxpYyBOYW1lIGdldFF1YWxpZmllZE5hbWUoKSB7CiAgICAgICAgcmV0dXJuIG5hbWU7CiAgICB9CgogICAgLyoqIFRoZSBmdWxseSBxdWFsaWZpZWQgbmFtZSBvZiB0aGlzIHN5bWJvbCBhZnRlciBjb252ZXJ0aW5nIHRvIGZsYXQKICAgICAqICByZXByZXNlbnRhdGlvbi4gVGhpcyBpcyB0aGUgc2FtZSBhcyB0aGUgc3ltYm9sJ3MgbmFtZSBleGNlcHQgZm9yCiAgICAgKiAgY2xhc3Mgc3ltYm9scywgd2hpY2ggYXJlIGhhbmRsZWQgc2VwYXJhdGVseS4KICAgICAqLwogICAgcHVibGljIE5hbWUgZmxhdE5hbWUoKSB7CiAgICAgICAgcmV0dXJuIGdldFF1YWxpZmllZE5hbWUoKTsKICAgIH0KCiAgICAvKiogSWYgdGhpcyBpcyBhIGNsYXNzIG9yIHBhY2thZ2UsIGl0cyBtZW1iZXJzLCBvdGhlcndpc2UgbnVsbC4KICAgICAqLwogICAgcHVibGljIFdyaXRlYWJsZVNjb3BlIG1lbWJlcnMoKSB7CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgLyoqIEEgY2xhc3MgaXMgYW4gaW5uZXIgY2xhc3MgaWYgaXQgaXQgaGFzIGFuIGVuY2xvc2luZyBpbnN0YW5jZSBjbGFzcy4KICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gaXNJbm5lcigpIHsKICAgICAgICByZXR1cm4ga2luZCA9PSBUWVAgJiYgdHlwZS5nZXRFbmNsb3NpbmdUeXBlKCkuaGFzVGFnKENMQVNTKTsKICAgIH0KCiAgICAvKiogQW4gaW5uZXIgY2xhc3MgaGFzIGFuIG91dGVyIGluc3RhbmNlIGlmIGl0IGlzIG5vdCBhbiBpbnRlcmZhY2UKICAgICAqICBpdCBoYXMgYW4gZW5jbG9zaW5nIGluc3RhbmNlIGNsYXNzIHdoaWNoIG1pZ2h0IGJlIHJlZmVyZW5jZWQgZnJvbSB0aGUgY2xhc3MuCiAgICAgKiAgTmVzdGVkIGNsYXNzZXMgY2FuIHNlZSBpbnN0YW5jZSBtZW1iZXJzIG9mIHRoZWlyIGVuY2xvc2luZyBjbGFzcy4KICAgICAqICBUaGVpciBjb25zdHJ1Y3RvcnMgY2FycnkgYW4gYWRkaXRpb25hbCB0aGlzJG4gcGFyYW1ldGVyLCBpbnNlcnRlZAogICAgICogIGltcGxpY2l0bHkgYnkgdGhlIGNvbXBpbGVyLgogICAgICoKICAgICAqICBAc2VlICNpc0lubmVyCiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGhhc091dGVySW5zdGFuY2UoKSB7CiAgICAgICAgcmV0dXJuCiAgICAgICAgICAgIHR5cGUuZ2V0RW5jbG9zaW5nVHlwZSgpLmhhc1RhZyhDTEFTUykgJiYgKGZsYWdzKCkgJiAoSU5URVJGQUNFIHwgTk9PVVRFUlRISVMpKSA9PSAwOwogICAgfQoKICAgIC8qKiBUaGUgY2xvc2VzdCBlbmNsb3NpbmcgY2xhc3Mgb2YgdGhpcyBzeW1ib2wncyBkZWNsYXJhdGlvbi4KICAgICAqICBXYXJuaW5nOiB0aGlzIChtaXNuYW1lZCkgbWV0aG9kIHJldHVybnMgdGhlIHJlY2VpdmVyIGl0c2VsZgogICAgICogIHdoZW4gdGhlIHJlY2VpdmVyIGlzIGEgY2xhc3MgKGFzIG9wcG9zZWQgdG8gaXRzIGVuY2xvc2luZwogICAgICogIGNsYXNzIGFzIG9uZSBtYXkgYmUgbWlzbGVkIHRvIGJlbGlldmUuKQogICAgICovCiAgICBwdWJsaWMgQ2xhc3NTeW1ib2wgZW5jbENsYXNzKCkgewogICAgICAgIFN5bWJvbCBjID0gdGhpczsKICAgICAgICB3aGlsZSAoYyAhPSBudWxsICYmCiAgICAgICAgICAgICAgICghYy5raW5kLm1hdGNoZXMoS2luZFNlbGVjdG9yLlRZUCkgfHwgIWMudHlwZS5oYXNUYWcoQ0xBU1MpKSkgewogICAgICAgICAgICBjID0gYy5vd25lcjsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIChDbGFzc1N5bWJvbCljOwogICAgfQoKICAgIC8qKiBUaGUgb3V0ZXJtb3N0IGNsYXNzIHdoaWNoIGluZGlyZWN0bHkgb3ducyB0aGlzIHN5bWJvbC4KICAgICAqLwogICAgcHVibGljIENsYXNzU3ltYm9sIG91dGVybW9zdENsYXNzKCkgewogICAgICAgIFN5bWJvbCBzeW0gPSB0aGlzOwogICAgICAgIFN5bWJvbCBwcmV2ID0gbnVsbDsKICAgICAgICB3aGlsZSAoc3ltLmtpbmQgIT0gUENLKSB7CiAgICAgICAgICAgIHByZXYgPSBzeW07CiAgICAgICAgICAgIHN5bSA9IHN5bS5vd25lcjsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIChDbGFzc1N5bWJvbCkgcHJldjsKICAgIH0KCiAgICAvKiogVGhlIHBhY2thZ2Ugd2hpY2ggaW5kaXJlY3RseSBvd25zIHRoaXMgc3ltYm9sLgogICAgICovCiAgICBwdWJsaWMgUGFja2FnZVN5bWJvbCBwYWNrZ2UoKSB7CiAgICAgICAgU3ltYm9sIHN5bSA9IHRoaXM7CiAgICAgICAgd2hpbGUgKHN5bS5raW5kICE9IFBDSykgewogICAgICAgICAgICBzeW0gPSBzeW0ub3duZXI7CiAgICAgICAgfQogICAgICAgIHJldHVybiAoUGFja2FnZVN5bWJvbCkgc3ltOwogICAgfQoKICAgIC8qKiBJcyB0aGlzIHN5bWJvbCBhIHN1YmNsYXNzIG9mIGBiYXNlJz8gT25seSBkZWZpbmVkIGZvciBDbGFzc1N5bWJvbHMuCiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGlzU3ViQ2xhc3MoU3ltYm9sIGJhc2UsIFR5cGVzIHR5cGVzKSB7CiAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCJpc1N1YkNsYXNzICIgKyB0aGlzKTsKICAgIH0KCiAgICAvKiogRnVsbHkgY2hlY2sgbWVtYmVyc2hpcDogaGllcmFyY2h5LCBwcm90ZWN0aW9uLCBhbmQgaGlkaW5nLgogICAgICogIERvZXMgbm90IGV4Y2x1ZGUgbWV0aG9kcyBub3QgaW5oZXJpdGVkIGR1ZSB0byBvdmVycmlkaW5nLgogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBpc01lbWJlck9mKFR5cGVTeW1ib2wgY2xhenosIFR5cGVzIHR5cGVzKSB7CiAgICAgICAgcmV0dXJuCiAgICAgICAgICAgIG93bmVyID09IGNsYXp6IHx8CiAgICAgICAgICAgIGNsYXp6LmlzU3ViQ2xhc3Mob3duZXIsIHR5cGVzKSAmJgogICAgICAgICAgICBpc0luaGVyaXRlZEluKGNsYXp6LCB0eXBlcykgJiYKICAgICAgICAgICAgIWhpZGRlbkluKChDbGFzc1N5bWJvbCljbGF6eiwgdHlwZXMpOwogICAgfQoKICAgIC8qKiBJcyB0aGlzIHN5bWJvbCB0aGUgc2FtZSBhcyBvciBlbmNsb3NlZCBieSB0aGUgZ2l2ZW4gY2xhc3M/ICovCiAgICBwdWJsaWMgYm9vbGVhbiBpc0VuY2xvc2VkQnkoQ2xhc3NTeW1ib2wgY2xhenopIHsKICAgICAgICBmb3IgKFN5bWJvbCBzeW0gPSB0aGlzOyBzeW0ua2luZCAhPSBQQ0s7IHN5bSA9IHN5bS5vd25lcikKICAgICAgICAgICAgaWYgKHN5bSA9PSBjbGF6eikgcmV0dXJuIHRydWU7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIHByaXZhdGUgYm9vbGVhbiBoaWRkZW5JbihDbGFzc1N5bWJvbCBjbGF6eiwgVHlwZXMgdHlwZXMpIHsKICAgICAgICBTeW1ib2wgc3ltID0gaGlkZGVuSW5JbnRlcm5hbChjbGF6eiwgdHlwZXMpOwogICAgICAgIEFzc2VydC5jaGVjayhzeW0gIT0gbnVsbCwgInRoZSByZXN1bHQgb2YgaGlkZGVuSW5JbnRlcm5hbCgpIGNhbid0IGJlIG51bGwiKTsKICAgICAgICAvKiBJZiB3ZSBmaW5kIHRoZSBjdXJyZW50IHN5bWJvbCB0aGVuIHRoZXJlIGlzIG5vIHN5bWJvbCBoaWRpbmcgaXQKICAgICAgICAgKi8KICAgICAgICByZXR1cm4gc3ltICE9IHRoaXM7CiAgICB9CgogICAgLyoqIFRoaXMgbWV0aG9kIGxvb2tzIGluIHRoZSBzdXBlcnR5cGVzIGdyYXBoIHRoYXQgaGFzIHRoZSBjdXJyZW50IGNsYXNzIGFzIHRoZQogICAgICogaW5pdGlhbCBub2RlLCB0aWxsIGl0IGZpbmRzIHRoZSBjdXJyZW50IHN5bWJvbCBvciBhbm90aGVyIHN5bWJvbCB0aGF0IGhpZGVzIGl0LgogICAgICogSWYgdGhlIGN1cnJlbnQgY2xhc3MgaGFzIG1vcmUgdGhhbiBvbmUgc3VwZXJ0eXBlIChleHRlbmRzIG9uZSBjbGFzcyBhbmQKICAgICAqIGltcGxlbWVudHMgb25lIG9yIG1vcmUgaW50ZXJmYWNlcykgdGhlbiBudWxsIGNhbiBiZSByZXR1cm5lZCwgbWVhbmluZyB0aGF0CiAgICAgKiBhIHdyb25nIHBhdGggaW4gdGhlIHN1cGVydHlwZXMgZ3JhcGggd2FzIHNlbGVjdGVkLiBOdWxsIGNhbiBvbmx5IGJlIHJldHVybmVkCiAgICAgKiBhcyBhIHRlbXBvcmFyeSB2YWx1ZSwgYXMgYSByZXN1bHQgb2YgdGhlIHJlY3Vyc2l2ZSBjYWxsLgogICAgICovCiAgICBwcml2YXRlIFN5bWJvbCBoaWRkZW5JbkludGVybmFsKENsYXNzU3ltYm9sIGN1cnJlbnRDbGFzcywgVHlwZXMgdHlwZXMpIHsKICAgICAgICBpZiAoY3VycmVudENsYXNzID09IG93bmVyKSB7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICBmb3IgKFN5bWJvbCBzeW0gOiBjdXJyZW50Q2xhc3MubWVtYmVycygpLmdldFN5bWJvbHNCeU5hbWUobmFtZSkpIHsKICAgICAgICAgICAgaWYgKHN5bS5raW5kID09IGtpbmQgJiYKICAgICAgICAgICAgICAgICAgICAoa2luZCAhPSBNVEggfHwKICAgICAgICAgICAgICAgICAgICAoc3ltLmZsYWdzKCkgJiBTVEFUSUMpICE9IDAgJiYKICAgICAgICAgICAgICAgICAgICB0eXBlcy5pc1N1YlNpZ25hdHVyZShzeW0udHlwZSwgdHlwZSkpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gc3ltOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIFN5bWJvbCBoaWRkZW5TeW0gPSBudWxsOwogICAgICAgIGZvciAoVHlwZSBzdCA6IHR5cGVzLmludGVyZmFjZXMoY3VycmVudENsYXNzLnR5cGUpCiAgICAgICAgICAgICAgICAucHJlcGVuZCh0eXBlcy5zdXBlcnR5cGUoY3VycmVudENsYXNzLnR5cGUpKSkgewogICAgICAgICAgICBpZiAoc3QgIT0gbnVsbCAmJiAoc3QuaGFzVGFnKENMQVNTKSkpIHsKICAgICAgICAgICAgICAgIFN5bWJvbCBzeW0gPSBoaWRkZW5JbkludGVybmFsKChDbGFzc1N5bWJvbClzdC50c3ltLCB0eXBlcyk7CiAgICAgICAgICAgICAgICBpZiAoc3ltID09IHRoaXMpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoc3ltICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICBoaWRkZW5TeW0gPSBzeW07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIGhpZGRlblN5bTsKICAgIH0KCiAgICAvKiogSXMgdGhpcyBzeW1ib2wgaW5oZXJpdGVkIGludG8gYSBnaXZlbiBjbGFzcz8KICAgICAqICBQUkU6IElmIHN5bWJvbCdzIG93bmVyIGlzIGEgaW50ZXJmYWNlLAogICAgICogICAgICAgaXQgaXMgYWxyZWFkeSBhc3N1bWVkIHRoYXQgdGhlIGludGVyZmFjZSBpcyBhIHN1cGVyaW50ZXJmYWNlCiAgICAgKiAgICAgICBvZiBnaXZlbiBjbGFzcy4KICAgICAqICBAcGFyYW0gY2xhenogIFRoZSBjbGFzcyBmb3Igd2hpY2ggd2Ugd2FudCB0byBlc3RhYmxpc2ggbWVtYmVyc2hpcC4KICAgICAqICAgICAgICAgICAgICAgIFRoaXMgbXVzdCBiZSBhIHN1YmNsYXNzIG9mIHRoZSBtZW1iZXIncyBvd25lci4KICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gaXNJbmhlcml0ZWRJbihTeW1ib2wgY2xhenosIFR5cGVzIHR5cGVzKSB7CiAgICAgICAgc3dpdGNoICgoaW50KShmbGFnc19maWVsZCAmIEZsYWdzLkFjY2Vzc0ZsYWdzKSkgewogICAgICAgIGRlZmF1bHQ6IC8vIGVycm9yIHJlY292ZXJ5CiAgICAgICAgY2FzZSBQVUJMSUM6CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIGNhc2UgUFJJVkFURToKICAgICAgICAgICAgcmV0dXJuIHRoaXMub3duZXIgPT0gY2xheno7CiAgICAgICAgY2FzZSBQUk9URUNURUQ6CiAgICAgICAgICAgIC8vIHdlIG1vZGVsIGludGVyZmFjZXMgYXMgZXh0ZW5kaW5nIE9iamVjdAogICAgICAgICAgICByZXR1cm4gKGNsYXp6LmZsYWdzKCkgJiBJTlRFUkZBQ0UpID09IDA7CiAgICAgICAgY2FzZSAwOgogICAgICAgICAgICBQYWNrYWdlU3ltYm9sIHRoaXNQYWNrYWdlID0gdGhpcy5wYWNrZ2UoKTsKICAgICAgICAgICAgZm9yIChTeW1ib2wgc3VwID0gY2xheno7CiAgICAgICAgICAgICAgICAgc3VwICE9IG51bGwgJiYgc3VwICE9IHRoaXMub3duZXI7CiAgICAgICAgICAgICAgICAgc3VwID0gdHlwZXMuc3VwZXJ0eXBlKHN1cC50eXBlKS50c3ltKSB7CiAgICAgICAgICAgICAgICB3aGlsZSAoc3VwLnR5cGUuaGFzVGFnKFRZUEVWQVIpKQogICAgICAgICAgICAgICAgICAgIHN1cCA9IHN1cC50eXBlLmdldFVwcGVyQm91bmQoKS50c3ltOwogICAgICAgICAgICAgICAgaWYgKHN1cC50eXBlLmlzRXJyb25lb3VzKCkpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7IC8vIGVycm9yIHJlY292ZXJ5CiAgICAgICAgICAgICAgICBpZiAoKHN1cC5mbGFncygpICYgQ09NUE9VTkQpICE9IDApCiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICBpZiAoc3VwLnBhY2tnZSgpICE9IHRoaXNQYWNrYWdlKQogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gKGNsYXp6LmZsYWdzKCkgJiBJTlRFUkZBQ0UpID09IDA7CiAgICAgICAgfQogICAgfQoKICAgIC8qKiBUaGUgKHZhcmlhYmxlIG9yIG1ldGhvZCkgc3ltYm9sIHNlZW4gYXMgYSBtZW1iZXIgb2YgZ2l2ZW4KICAgICAqICBjbGFzcyB0eXBlYHNpdGUnICh0aGlzIG1pZ2h0IGNoYW5nZSB0aGUgc3ltYm9sJ3MgdHlwZSkuCiAgICAgKiAgVGhpcyBpcyB1c2VkIGV4Y2x1c2l2ZWx5IGZvciBwcm9kdWNpbmcgZGlhZ25vc3RpY3MuCiAgICAgKi8KICAgIHB1YmxpYyBTeW1ib2wgYXNNZW1iZXJPZihUeXBlIHNpdGUsIFR5cGVzIHR5cGVzKSB7CiAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCk7CiAgICB9CgogICAgLyoqIERvZXMgdGhpcyBtZXRob2Qgc3ltYm9sIG92ZXJyaWRlIGBvdGhlcicgc3ltYm9sLCB3aGVuIGJvdGggYXJlIHNlZW4gYXMKICAgICAqICBtZW1iZXJzIG9mIGNsYXNzIGBvcmlnaW4nPyAgSXQgaXMgYXNzdW1lZCB0aGF0IF9vdGhlciBpcyBhIG1lbWJlcgogICAgICogIG9mIG9yaWdpbi4KICAgICAqCiAgICAgKiAgSXQgaXMgYXNzdW1lZCB0aGF0IGJvdGggc3ltYm9scyBoYXZlIHRoZSBzYW1lIG5hbWUuICBUaGUgc3RhdGljCiAgICAgKiAgbW9kaWZpZXIgaXMgaWdub3JlZCBmb3IgdGhpcyB0ZXN0LgogICAgICoKICAgICAqICBTZWUgSkxTIDguNC42LjEgKHdpdGhvdXQgdHJhbnNpdGl2aXR5KSBhbmQgOC40LjYuNAogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBvdmVycmlkZXMoU3ltYm9sIF9vdGhlciwgVHlwZVN5bWJvbCBvcmlnaW4sIFR5cGVzIHR5cGVzLCBib29sZWFuIGNoZWNrUmVzdWx0KSB7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIC8qKiBDb21wbGV0ZSB0aGUgZWxhYm9yYXRpb24gb2YgdGhpcyBzeW1ib2wncyBkZWZpbml0aW9uLgogICAgICovCiAgICBwdWJsaWMgdm9pZCBjb21wbGV0ZSgpIHRocm93cyBDb21wbGV0aW9uRmFpbHVyZSB7CiAgICAgICAgaWYgKGNvbXBsZXRlciAhPSBDb21wbGV0ZXIuTlVMTF9DT01QTEVURVIpIHsKICAgICAgICAgICAgQ29tcGxldGVyIGMgPSBjb21wbGV0ZXI7CiAgICAgICAgICAgIGNvbXBsZXRlciA9IENvbXBsZXRlci5OVUxMX0NPTVBMRVRFUjsKICAgICAgICAgICAgYy5jb21wbGV0ZSh0aGlzKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqIFRydWUgaWYgdGhlIHN5bWJvbCByZXByZXNlbnRzIGFuIGVudGl0eSB0aGF0IGV4aXN0cy4KICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gZXhpc3RzKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgcHVibGljIFR5cGUgYXNUeXBlKCkgewogICAgICAgIHJldHVybiB0eXBlOwogICAgfQoKICAgIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgcHVibGljIFN5bWJvbCBnZXRFbmNsb3NpbmdFbGVtZW50KCkgewogICAgICAgIHJldHVybiBvd25lcjsKICAgIH0KCiAgICBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgIHB1YmxpYyBFbGVtZW50S2luZCBnZXRLaW5kKCkgewogICAgICAgIHJldHVybiBFbGVtZW50S2luZC5PVEhFUjsgICAgICAgLy8gbW9zdCB1bmtpbmQKICAgIH0KCiAgICBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgIHB1YmxpYyBTZXQ8TW9kaWZpZXI+IGdldE1vZGlmaWVycygpIHsKICAgICAgICByZXR1cm4gRmxhZ3MuYXNNb2RpZmllclNldChmbGFncygpKTsKICAgIH0KCiAgICBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgIHB1YmxpYyBOYW1lIGdldFNpbXBsZU5hbWUoKSB7CiAgICAgICAgcmV0dXJuIG5hbWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBUaGlzIGlzIHRoZSBpbXBsZW1lbnRhdGlvbiBmb3Ige0Bjb2RlCiAgICAgKiBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuRWxlbWVudC5nZXRBbm5vdGF0aW9uTWlycm9ycygpfS4KICAgICAqLwogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgcHVibGljIExpc3Q8QXR0cmlidXRlLkNvbXBvdW5kPiBnZXRBbm5vdGF0aW9uTWlycm9ycygpIHsKICAgICAgICByZXR1cm4gZ2V0UmF3QXR0cmlidXRlcygpOwogICAgfQoKCiAgICAvLyBUT0RPOiBnZXRFbmNsb3NlZEVsZW1lbnRzIHNob3VsZCByZXR1cm4gYSBqYXZhYyBMaXN0LCBmaXggaW4gRmlsdGVyZWRNZW1iZXJMaXN0CiAgICBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxTeW1ib2w+IGdldEVuY2xvc2VkRWxlbWVudHMoKSB7CiAgICAgICAgcmV0dXJuIExpc3QubmlsKCk7CiAgICB9CgogICAgcHVibGljIExpc3Q8VHlwZVZhcmlhYmxlU3ltYm9sPiBnZXRUeXBlUGFyYW1ldGVycygpIHsKICAgICAgICBMaXN0QnVmZmVyPFR5cGVWYXJpYWJsZVN5bWJvbD4gbCA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICBmb3IgKFR5cGUgdCA6IHR5cGUuZ2V0VHlwZUFyZ3VtZW50cygpKSB7CiAgICAgICAgICAgIEFzc2VydC5jaGVjayh0LnRzeW0uZ2V0S2luZCgpID09IEVsZW1lbnRLaW5kLlRZUEVfUEFSQU1FVEVSKTsKICAgICAgICAgICAgbC5hcHBlbmQoKFR5cGVWYXJpYWJsZVN5bWJvbCl0LnRzeW0pOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbC50b0xpc3QoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIERlbGVnYXRlZFN5bWJvbDxUIGV4dGVuZHMgU3ltYm9sPiBleHRlbmRzIFN5bWJvbCB7CiAgICAgICAgcHJvdGVjdGVkIFQgb3RoZXI7CiAgICAgICAgcHVibGljIERlbGVnYXRlZFN5bWJvbChUIG90aGVyKSB7CiAgICAgICAgICAgIHN1cGVyKG90aGVyLmtpbmQsIG90aGVyLmZsYWdzX2ZpZWxkLCBvdGhlci5uYW1lLCBvdGhlci50eXBlLCBvdGhlci5vd25lcik7CiAgICAgICAgICAgIHRoaXMub3RoZXIgPSBvdGhlcjsKICAgICAgICB9CiAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsgcmV0dXJuIG90aGVyLnRvU3RyaW5nKCk7IH0KICAgICAgICBwdWJsaWMgU3ltYm9sIGxvY2F0aW9uKCkgeyByZXR1cm4gb3RoZXIubG9jYXRpb24oKTsgfQogICAgICAgIHB1YmxpYyBTeW1ib2wgbG9jYXRpb24oVHlwZSBzaXRlLCBUeXBlcyB0eXBlcykgeyByZXR1cm4gb3RoZXIubG9jYXRpb24oc2l0ZSwgdHlwZXMpOyB9CiAgICAgICAgcHVibGljIFN5bWJvbCBiYXNlU3ltYm9sKCkgeyByZXR1cm4gb3RoZXI7IH0KICAgICAgICBwdWJsaWMgVHlwZSBlcmFzdXJlKFR5cGVzIHR5cGVzKSB7IHJldHVybiBvdGhlci5lcmFzdXJlKHR5cGVzKTsgfQogICAgICAgIHB1YmxpYyBUeXBlIGV4dGVybmFsVHlwZShUeXBlcyB0eXBlcykgeyByZXR1cm4gb3RoZXIuZXh0ZXJuYWxUeXBlKHR5cGVzKTsgfQogICAgICAgIHB1YmxpYyBib29sZWFuIGlzTG9jYWwoKSB7IHJldHVybiBvdGhlci5pc0xvY2FsKCk7IH0KICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc0NvbnN0cnVjdG9yKCkgeyByZXR1cm4gb3RoZXIuaXNDb25zdHJ1Y3RvcigpOyB9CiAgICAgICAgcHVibGljIE5hbWUgZ2V0UXVhbGlmaWVkTmFtZSgpIHsgcmV0dXJuIG90aGVyLmdldFF1YWxpZmllZE5hbWUoKTsgfQogICAgICAgIHB1YmxpYyBOYW1lIGZsYXROYW1lKCkgeyByZXR1cm4gb3RoZXIuZmxhdE5hbWUoKTsgfQogICAgICAgIHB1YmxpYyBXcml0ZWFibGVTY29wZSBtZW1iZXJzKCkgeyByZXR1cm4gb3RoZXIubWVtYmVycygpOyB9CiAgICAgICAgcHVibGljIGJvb2xlYW4gaXNJbm5lcigpIHsgcmV0dXJuIG90aGVyLmlzSW5uZXIoKTsgfQogICAgICAgIHB1YmxpYyBib29sZWFuIGhhc091dGVySW5zdGFuY2UoKSB7IHJldHVybiBvdGhlci5oYXNPdXRlckluc3RhbmNlKCk7IH0KICAgICAgICBwdWJsaWMgQ2xhc3NTeW1ib2wgZW5jbENsYXNzKCkgeyByZXR1cm4gb3RoZXIuZW5jbENsYXNzKCk7IH0KICAgICAgICBwdWJsaWMgQ2xhc3NTeW1ib2wgb3V0ZXJtb3N0Q2xhc3MoKSB7IHJldHVybiBvdGhlci5vdXRlcm1vc3RDbGFzcygpOyB9CiAgICAgICAgcHVibGljIFBhY2thZ2VTeW1ib2wgcGFja2dlKCkgeyByZXR1cm4gb3RoZXIucGFja2dlKCk7IH0KICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc1N1YkNsYXNzKFN5bWJvbCBiYXNlLCBUeXBlcyB0eXBlcykgeyByZXR1cm4gb3RoZXIuaXNTdWJDbGFzcyhiYXNlLCB0eXBlcyk7IH0KICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc01lbWJlck9mKFR5cGVTeW1ib2wgY2xhenosIFR5cGVzIHR5cGVzKSB7IHJldHVybiBvdGhlci5pc01lbWJlck9mKGNsYXp6LCB0eXBlcyk7IH0KICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc0VuY2xvc2VkQnkoQ2xhc3NTeW1ib2wgY2xhenopIHsgcmV0dXJuIG90aGVyLmlzRW5jbG9zZWRCeShjbGF6eik7IH0KICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc0luaGVyaXRlZEluKFN5bWJvbCBjbGF6eiwgVHlwZXMgdHlwZXMpIHsgcmV0dXJuIG90aGVyLmlzSW5oZXJpdGVkSW4oY2xhenosIHR5cGVzKTsgfQogICAgICAgIHB1YmxpYyBTeW1ib2wgYXNNZW1iZXJPZihUeXBlIHNpdGUsIFR5cGVzIHR5cGVzKSB7IHJldHVybiBvdGhlci5hc01lbWJlck9mKHNpdGUsIHR5cGVzKTsgfQogICAgICAgIHB1YmxpYyB2b2lkIGNvbXBsZXRlKCkgdGhyb3dzIENvbXBsZXRpb25GYWlsdXJlIHsgb3RoZXIuY29tcGxldGUoKTsgfQoKICAgICAgICBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgICAgICBwdWJsaWMgPFIsIFA+IFIgYWNjZXB0KEVsZW1lbnRWaXNpdG9yPFIsIFA+IHYsIFAgcCkgewogICAgICAgICAgICByZXR1cm4gb3RoZXIuYWNjZXB0KHYsIHApOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIDxSLCBQPiBSIGFjY2VwdChTeW1ib2wuVmlzaXRvcjxSLCBQPiB2LCBQIHApIHsKICAgICAgICAgICAgcmV0dXJuIHYudmlzaXRTeW1ib2wob3RoZXIsIHApOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIFQgZ2V0VW5kZXJseWluZ1N5bWJvbCgpIHsKICAgICAgICAgICAgcmV0dXJuIG90aGVyOwogICAgICAgIH0KICAgIH0KCiAgICAvKiogQSBiYXNlIGNsYXNzIGZvciBTeW1ib2xzIHJlcHJlc2VudGluZyB0eXBlcy4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBhYnN0cmFjdCBjbGFzcyBUeXBlU3ltYm9sIGV4dGVuZHMgU3ltYm9sIHsKICAgICAgICBwdWJsaWMgVHlwZVN5bWJvbChLaW5kIGtpbmQsIGxvbmcgZmxhZ3MsIE5hbWUgbmFtZSwgVHlwZSB0eXBlLCBTeW1ib2wgb3duZXIpIHsKICAgICAgICAgICAgc3VwZXIoa2luZCwgZmxhZ3MsIG5hbWUsIHR5cGUsIG93bmVyKTsKICAgICAgICB9CiAgICAgICAgLyoqIGZvcm0gYSBmdWxseSBxdWFsaWZpZWQgbmFtZSBmcm9tIGEgbmFtZSBhbmQgYW4gb3duZXIKICAgICAgICAgKi8KICAgICAgICBzdGF0aWMgcHVibGljIE5hbWUgZm9ybUZ1bGxOYW1lKE5hbWUgbmFtZSwgU3ltYm9sIG93bmVyKSB7CiAgICAgICAgICAgIGlmIChvd25lciA9PSBudWxsKSByZXR1cm4gbmFtZTsKICAgICAgICAgICAgaWYgKChvd25lci5raW5kICE9IEVSUikgJiYKICAgICAgICAgICAgICAgIChvd25lci5raW5kLm1hdGNoZXMoS2luZFNlbGVjdG9yLlZBTF9NVEgpIHx8CiAgICAgICAgICAgICAgICAgKG93bmVyLmtpbmQgPT0gVFlQICYmIG93bmVyLnR5cGUuaGFzVGFnKFRZUEVWQVIpKQogICAgICAgICAgICAgICAgICkpIHJldHVybiBuYW1lOwogICAgICAgICAgICBOYW1lIHByZWZpeCA9IG93bmVyLmdldFF1YWxpZmllZE5hbWUoKTsKICAgICAgICAgICAgaWYgKHByZWZpeCA9PSBudWxsIHx8IHByZWZpeCA9PSBwcmVmaXgudGFibGUubmFtZXMuZW1wdHkpCiAgICAgICAgICAgICAgICByZXR1cm4gbmFtZTsKICAgICAgICAgICAgZWxzZSByZXR1cm4gcHJlZml4LmFwcGVuZCgnLicsIG5hbWUpOwogICAgICAgIH0KCiAgICAgICAgLyoqIGZvcm0gYSBmdWxseSBxdWFsaWZpZWQgbmFtZSBmcm9tIGEgbmFtZSBhbmQgYW4gb3duZXIsIGFmdGVyCiAgICAgICAgICogIGNvbnZlcnRpbmcgdG8gZmxhdCByZXByZXNlbnRhdGlvbgogICAgICAgICAqLwogICAgICAgIHN0YXRpYyBwdWJsaWMgTmFtZSBmb3JtRmxhdE5hbWUoTmFtZSBuYW1lLCBTeW1ib2wgb3duZXIpIHsKICAgICAgICAgICAgaWYgKG93bmVyID09IG51bGwgfHwgb3duZXIua2luZC5tYXRjaGVzKEtpbmRTZWxlY3Rvci5WQUxfTVRIKSB8fAogICAgICAgICAgICAgICAgKG93bmVyLmtpbmQgPT0gVFlQICYmIG93bmVyLnR5cGUuaGFzVGFnKFRZUEVWQVIpKQogICAgICAgICAgICAgICAgKSByZXR1cm4gbmFtZTsKICAgICAgICAgICAgY2hhciBzZXAgPSBvd25lci5raW5kID09IFRZUCA/ICckJyA6ICcuJzsKICAgICAgICAgICAgTmFtZSBwcmVmaXggPSBvd25lci5mbGF0TmFtZSgpOwogICAgICAgICAgICBpZiAocHJlZml4ID09IG51bGwgfHwgcHJlZml4ID09IHByZWZpeC50YWJsZS5uYW1lcy5lbXB0eSkKICAgICAgICAgICAgICAgIHJldHVybiBuYW1lOwogICAgICAgICAgICBlbHNlIHJldHVybiBwcmVmaXguYXBwZW5kKHNlcCwgbmFtZSk7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBBIHBhcnRpYWwgb3JkZXJpbmcgYmV0d2VlbiB0eXBlIHN5bWJvbHMgdGhhdCByZWZpbmVzIHRoZQogICAgICAgICAqIGNsYXNzIGluaGVyaXRhbmNlIGdyYXBoLgogICAgICAgICAqCiAgICAgICAgICogVHlwZSB2YXJpYWJsZXMgYWx3YXlzIHByZWNlZGUgb3RoZXIga2luZHMgb2Ygc3ltYm9scy4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBwcmVjZWRlcyhUeXBlU3ltYm9sIHRoYXQsIFR5cGVzIHR5cGVzKSB7CiAgICAgICAgICAgIGlmICh0aGlzID09IHRoYXQpCiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIGlmICh0eXBlLmhhc1RhZyh0aGF0LnR5cGUuZ2V0VGFnKCkpKSB7CiAgICAgICAgICAgICAgICBpZiAodHlwZS5oYXNUYWcoQ0xBU1MpKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVzLnJhbmsodGhhdC50eXBlKSA8IHR5cGVzLnJhbmsodGhpcy50eXBlKSB8fAogICAgICAgICAgICAgICAgICAgICAgICB0eXBlcy5yYW5rKHRoYXQudHlwZSkgPT0gdHlwZXMucmFuayh0aGlzLnR5cGUpICYmCiAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQuZ2V0UXVhbGlmaWVkTmFtZSgpLmNvbXBhcmVUbyh0aGlzLmdldFF1YWxpZmllZE5hbWUoKSkgPCAwOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlLmhhc1RhZyhUWVBFVkFSKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB0eXBlcy5pc1N1YnR5cGUodGhpcy50eXBlLCB0aGF0LnR5cGUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiB0eXBlLmhhc1RhZyhUWVBFVkFSKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8U3ltYm9sPiBnZXRFbmNsb3NlZEVsZW1lbnRzKCkgewogICAgICAgICAgICBMaXN0PFN5bWJvbD4gbGlzdCA9IExpc3QubmlsKCk7CiAgICAgICAgICAgIGlmIChraW5kID09IFRZUCAmJiB0eXBlLmhhc1RhZyhUWVBFVkFSKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGxpc3Q7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZm9yIChTeW1ib2wgc3ltIDogbWVtYmVycygpLmdldFN5bWJvbHMoTk9OX1JFQ1VSU0lWRSkpIHsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHN5bSAhPSBudWxsICYmIChzeW0uZmxhZ3MoKSAmIFNZTlRIRVRJQykgPT0gMCAmJiBzeW0ub3duZXIgPT0gdGhpcykgewogICAgICAgICAgICAgICAgICAgICAgICBsaXN0ID0gbGlzdC5wcmVwZW5kKHN5bSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBjYXRjaCAoQmFkRW5jbG9zaW5nTWV0aG9kQXR0ciBiYWRFbmNsb3NpbmdNZXRob2QpIHsKICAgICAgICAgICAgICAgICAgICAvLyBpZ25vcmUgdGhlIGV4Y2VwdGlvbgogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBsaXN0OwogICAgICAgIH0KCiAgICAgICAgcHVibGljIEFubm90YXRpb25UeXBlTWV0YWRhdGEgZ2V0QW5ub3RhdGlvblR5cGVNZXRhZGF0YSgpIHsKICAgICAgICAgICAgQXNzZXJ0LmVycm9yKCJPbmx5IG9uIENsYXNzU3ltYm9sIik7CiAgICAgICAgICAgIHJldHVybiBudWxsOyAvL3VucmVhY2hhYmxlCiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc0Fubm90YXRpb25UeXBlKCkgeyByZXR1cm4gZmFsc2U7IH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIDxSLCBQPiBSIGFjY2VwdChTeW1ib2wuVmlzaXRvcjxSLCBQPiB2LCBQIHApIHsKICAgICAgICAgICAgcmV0dXJuIHYudmlzaXRUeXBlU3ltYm9sKHRoaXMsIHApOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFR5cGUgdmFyaWFibGVzIGFyZSByZXByZXNlbnRlZCBieSBpbnN0YW5jZXMgb2YgdGhpcyBjbGFzcy4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBjbGFzcyBUeXBlVmFyaWFibGVTeW1ib2wKICAgICAgICAgICAgZXh0ZW5kcyBUeXBlU3ltYm9sIGltcGxlbWVudHMgVHlwZVBhcmFtZXRlckVsZW1lbnQgewoKICAgICAgICBwdWJsaWMgVHlwZVZhcmlhYmxlU3ltYm9sKGxvbmcgZmxhZ3MsIE5hbWUgbmFtZSwgVHlwZSB0eXBlLCBTeW1ib2wgb3duZXIpIHsKICAgICAgICAgICAgc3VwZXIoVFlQLCBmbGFncywgbmFtZSwgdHlwZSwgb3duZXIpOwogICAgICAgIH0KCiAgICAgICAgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICAgICAgcHVibGljIEVsZW1lbnRLaW5kIGdldEtpbmQoKSB7CiAgICAgICAgICAgIHJldHVybiBFbGVtZW50S2luZC5UWVBFX1BBUkFNRVRFUjsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgICAgICBwdWJsaWMgU3ltYm9sIGdldEdlbmVyaWNFbGVtZW50KCkgewogICAgICAgICAgICByZXR1cm4gb3duZXI7CiAgICAgICAgfQoKICAgICAgICBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgICAgICBwdWJsaWMgTGlzdDxUeXBlPiBnZXRCb3VuZHMoKSB7CiAgICAgICAgICAgIFR5cGVWYXIgdCA9IChUeXBlVmFyKXR5cGU7CiAgICAgICAgICAgIFR5cGUgYm91bmQgPSB0LmdldFVwcGVyQm91bmQoKTsKICAgICAgICAgICAgaWYgKCFib3VuZC5pc0NvbXBvdW5kKCkpCiAgICAgICAgICAgICAgICByZXR1cm4gTGlzdC5vZihib3VuZCk7CiAgICAgICAgICAgIENsYXNzVHlwZSBjdCA9IChDbGFzc1R5cGUpYm91bmQ7CiAgICAgICAgICAgIGlmICghY3QudHN5bS5lcmFzdXJlX2ZpZWxkLmlzSW50ZXJmYWNlKCkpIHsKICAgICAgICAgICAgICAgIHJldHVybiBjdC5pbnRlcmZhY2VzX2ZpZWxkLnByZXBlbmQoY3Quc3VwZXJ0eXBlX2ZpZWxkKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIC8vIE5vIHN1cGVyY2xhc3Mgd2FzIGdpdmVuIGluIGJvdW5kcy4KICAgICAgICAgICAgICAgIC8vIEluIHRoaXMgY2FzZSwgc3VwZXJ0eXBlIGlzIE9iamVjdCwgZXJhc3VyZSBpcyBmaXJzdCBpbnRlcmZhY2UuCiAgICAgICAgICAgICAgICByZXR1cm4gY3QuaW50ZXJmYWNlc19maWVsZDsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyBMaXN0PEF0dHJpYnV0ZS5Db21wb3VuZD4gZ2V0QW5ub3RhdGlvbk1pcnJvcnMoKSB7CiAgICAgICAgICAgIC8vIERlY2xhcmF0aW9uIGFubm90YXRpb25zIG9uIHR5cGUgdmFyaWFibGVzIGFyZSBzdG9yZWQgaW4gdHlwZSBhdHRyaWJ1dGVzCiAgICAgICAgICAgIC8vIG9uIHRoZSBvd25lciBvZiB0aGUgVHlwZVZhcmlhYmxlU3ltYm9sCiAgICAgICAgICAgIExpc3Q8QXR0cmlidXRlLlR5cGVDb21wb3VuZD4gY2FuZGlkYXRlcyA9IG93bmVyLmdldFJhd1R5cGVBdHRyaWJ1dGVzKCk7CiAgICAgICAgICAgIGludCBpbmRleCA9IG93bmVyLmdldFR5cGVQYXJhbWV0ZXJzKCkuaW5kZXhPZih0aGlzKTsKICAgICAgICAgICAgTGlzdDxBdHRyaWJ1dGUuQ29tcG91bmQ+IHJlcyA9IExpc3QubmlsKCk7CiAgICAgICAgICAgIGZvciAoQXR0cmlidXRlLlR5cGVDb21wb3VuZCBhIDogY2FuZGlkYXRlcykgewogICAgICAgICAgICAgICAgaWYgKGlzQ3VycmVudFN5bWJvbHNBbm5vdGF0aW9uKGEsIGluZGV4KSkKICAgICAgICAgICAgICAgICAgICByZXMgPSByZXMucHJlcGVuZChhKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIHJlcy5yZXZlcnNlKCk7CiAgICAgICAgfQoKICAgICAgICAvLyBIZWxwZXIgdG8gZ2V0QW5ub3RhdGlvbltzXQogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyA8QSBleHRlbmRzIEFubm90YXRpb24+IEF0dHJpYnV0ZS5Db21wb3VuZCBnZXRBdHRyaWJ1dGUoQ2xhc3M8QT4gYW5ub1R5cGUpIHsKICAgICAgICAgICAgU3RyaW5nIG5hbWUgPSBhbm5vVHlwZS5nZXROYW1lKCk7CgogICAgICAgICAgICAvLyBEZWNsYXJhdGlvbiBhbm5vdGF0aW9ucyBvbiB0eXBlIHZhcmlhYmxlcyBhcmUgc3RvcmVkIGluIHR5cGUgYXR0cmlidXRlcwogICAgICAgICAgICAvLyBvbiB0aGUgb3duZXIgb2YgdGhlIFR5cGVWYXJpYWJsZVN5bWJvbAogICAgICAgICAgICBMaXN0PEF0dHJpYnV0ZS5UeXBlQ29tcG91bmQ+IGNhbmRpZGF0ZXMgPSBvd25lci5nZXRSYXdUeXBlQXR0cmlidXRlcygpOwogICAgICAgICAgICBpbnQgaW5kZXggPSBvd25lci5nZXRUeXBlUGFyYW1ldGVycygpLmluZGV4T2YodGhpcyk7CiAgICAgICAgICAgIGZvciAoQXR0cmlidXRlLlR5cGVDb21wb3VuZCBhbm5vIDogY2FuZGlkYXRlcykKICAgICAgICAgICAgICAgIGlmIChpc0N1cnJlbnRTeW1ib2xzQW5ub3RhdGlvbihhbm5vLCBpbmRleCkgJiYKICAgICAgICAgICAgICAgICAgICBuYW1lLmNvbnRlbnRFcXVhbHMoYW5uby50eXBlLnRzeW0uZmxhdE5hbWUoKSkpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGFubm87CgogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICAgICAgICAgIC8vd2hlcmU6CiAgICAgICAgICAgIGJvb2xlYW4gaXNDdXJyZW50U3ltYm9sc0Fubm90YXRpb24oQXR0cmlidXRlLlR5cGVDb21wb3VuZCBhbm5vLCBpbnQgaW5kZXgpIHsKICAgICAgICAgICAgICAgIHJldHVybiAoYW5uby5wb3NpdGlvbi50eXBlID09IFRhcmdldFR5cGUuQ0xBU1NfVFlQRV9QQVJBTUVURVIgfHwKICAgICAgICAgICAgICAgICAgICAgICAgYW5uby5wb3NpdGlvbi50eXBlID09IFRhcmdldFR5cGUuTUVUSE9EX1RZUEVfUEFSQU1FVEVSKSAmJgogICAgICAgICAgICAgICAgICAgICAgICBhbm5vLnBvc2l0aW9uLnBhcmFtZXRlcl9pbmRleCA9PSBpbmRleDsKICAgICAgICAgICAgfQoKCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyA8UiwgUD4gUiBhY2NlcHQoRWxlbWVudFZpc2l0b3I8UiwgUD4gdiwgUCBwKSB7CiAgICAgICAgICAgIHJldHVybiB2LnZpc2l0VHlwZVBhcmFtZXRlcih0aGlzLCBwKTsKICAgICAgICB9CiAgICB9CiAgICAvKiogQSBjbGFzcyBmb3IgbW9kdWxlIHN5bWJvbHMuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgTW9kdWxlU3ltYm9sIGV4dGVuZHMgVHlwZVN5bWJvbAogICAgICAgICAgICBpbXBsZW1lbnRzIE1vZHVsZUVsZW1lbnQgewoKICAgICAgICBwdWJsaWMgTmFtZSB2ZXJzaW9uOwogICAgICAgIHB1YmxpYyBKYXZhRmlsZU1hbmFnZXIuTG9jYXRpb24gc291cmNlTG9jYXRpb247CiAgICAgICAgcHVibGljIEphdmFGaWxlTWFuYWdlci5Mb2NhdGlvbiBjbGFzc0xvY2F0aW9uOwogICAgICAgIHB1YmxpYyBKYXZhRmlsZU1hbmFnZXIuTG9jYXRpb24gcGF0Y2hMb2NhdGlvbjsKICAgICAgICBwdWJsaWMgSmF2YUZpbGVNYW5hZ2VyLkxvY2F0aW9uIHBhdGNoT3V0cHV0TG9jYXRpb247CgogICAgICAgIC8qKiBBbGwgZGlyZWN0aXZlcywgaW4gbmF0dXJhbCBvcmRlci4gKi8KICAgICAgICBwdWJsaWMgTGlzdDxjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuRGlyZWN0aXZlPiBkaXJlY3RpdmVzOwogICAgICAgIHB1YmxpYyBMaXN0PGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5EaXJlY3RpdmUuUmVxdWlyZXNEaXJlY3RpdmU+IHJlcXVpcmVzOwogICAgICAgIHB1YmxpYyBMaXN0PGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5EaXJlY3RpdmUuRXhwb3J0c0RpcmVjdGl2ZT4gZXhwb3J0czsKICAgICAgICBwdWJsaWMgTGlzdDxjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuRGlyZWN0aXZlLk9wZW5zRGlyZWN0aXZlPiBvcGVuczsKICAgICAgICBwdWJsaWMgTGlzdDxjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuRGlyZWN0aXZlLlByb3ZpZGVzRGlyZWN0aXZlPiBwcm92aWRlczsKICAgICAgICBwdWJsaWMgTGlzdDxjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuRGlyZWN0aXZlLlVzZXNEaXJlY3RpdmU+IHVzZXM7CgogICAgICAgIHB1YmxpYyBDbGFzc1N5bWJvbCBtb2R1bGVfaW5mbzsKCiAgICAgICAgcHVibGljIFBhY2thZ2VTeW1ib2wgdW5uYW1lZFBhY2thZ2U7CiAgICAgICAgcHVibGljIE1hcDxOYW1lLCBQYWNrYWdlU3ltYm9sPiB2aXNpYmxlUGFja2FnZXM7CiAgICAgICAgcHVibGljIFNldDxNb2R1bGVTeW1ib2w+IHJlYWRNb2R1bGVzOwogICAgICAgIHB1YmxpYyBMaXN0PFN5bWJvbD4gZW5jbG9zZWRQYWNrYWdlcyA9IExpc3QubmlsKCk7CgogICAgICAgIHB1YmxpYyBDb21wbGV0ZXIgdXNlc1Byb3ZpZGVzQ29tcGxldGVyID0gQ29tcGxldGVyLk5VTExfQ09NUExFVEVSOwogICAgICAgIHB1YmxpYyBmaW5hbCBTZXQ8TW9kdWxlRmxhZ3M+IGZsYWdzID0gRW51bVNldC5ub25lT2YoTW9kdWxlRmxhZ3MuY2xhc3MpOwogICAgICAgIHB1YmxpYyBmaW5hbCBTZXQ8TW9kdWxlUmVzb2x1dGlvbkZsYWdzPiByZXNvbHV0aW9uRmxhZ3MgPSBFbnVtU2V0Lm5vbmVPZihNb2R1bGVSZXNvbHV0aW9uRmxhZ3MuY2xhc3MpOwoKICAgICAgICAvKioKICAgICAgICAgKiBDcmVhdGUgYSBNb2R1bGVTeW1ib2wgd2l0aCBhbiBhc3NvY2lhdGVkIG1vZHVsZS1pbmZvIENsYXNzU3ltYm9sLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBzdGF0aWMgTW9kdWxlU3ltYm9sIGNyZWF0ZShOYW1lIG5hbWUsIE5hbWUgbW9kdWxlX2luZm8pIHsKICAgICAgICAgICAgTW9kdWxlU3ltYm9sIG1zeW0gPSBuZXcgTW9kdWxlU3ltYm9sKG5hbWUsIG51bGwpOwogICAgICAgICAgICBDbGFzc1N5bWJvbCBpbmZvID0gbmV3IENsYXNzU3ltYm9sKEZsYWdzLk1PRFVMRSwgbW9kdWxlX2luZm8sIG1zeW0pOwogICAgICAgICAgICBpbmZvLmZ1bGxuYW1lID0gZm9ybUZ1bGxOYW1lKG1vZHVsZV9pbmZvLCBtc3ltKTsKICAgICAgICAgICAgaW5mby5mbGF0bmFtZSA9IGluZm8uZnVsbG5hbWU7CiAgICAgICAgICAgIGluZm8ubWVtYmVyc19maWVsZCA9IFdyaXRlYWJsZVNjb3BlLmNyZWF0ZShpbmZvKTsKICAgICAgICAgICAgbXN5bS5tb2R1bGVfaW5mbyA9IGluZm87CiAgICAgICAgICAgIHJldHVybiBtc3ltOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIE1vZHVsZVN5bWJvbChOYW1lIG5hbWUsIFN5bWJvbCBvd25lcikgewogICAgICAgICAgICBzdXBlcihNREwsIDAsIG5hbWUsIG51bGwsIG93bmVyKTsKICAgICAgICAgICAgQXNzZXJ0LmNoZWNrTm9uTnVsbChuYW1lKTsKICAgICAgICAgICAgdGhpcy50eXBlID0gbmV3IE1vZHVsZVR5cGUodGhpcyk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICAgICAgcHVibGljIGJvb2xlYW4gaXNPcGVuKCkgewogICAgICAgICAgICByZXR1cm4gZmxhZ3MuY29udGFpbnMoTW9kdWxlRmxhZ3MuT1BFTik7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICAgICAgcHVibGljIGJvb2xlYW4gaXNVbm5hbWVkKCkgewogICAgICAgICAgICByZXR1cm4gbmFtZS5pc0VtcHR5KCkgJiYgb3duZXIgPT0gbnVsbDsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBib29sZWFuIGlzRGVwcmVjYXRlZCgpIHsKICAgICAgICAgICAgcmV0dXJuIGhhc0RlcHJlY2F0ZWRBbm5vdGF0aW9uKCk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc05vTW9kdWxlKCkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICAgICAgcHVibGljIEVsZW1lbnRLaW5kIGdldEtpbmQoKSB7CiAgICAgICAgICAgIHJldHVybiBFbGVtZW50S2luZC5NT0RVTEU7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PERpcmVjdGl2ZT4gZ2V0RGlyZWN0aXZlcygpIHsKICAgICAgICAgICAgY29tcGxldGUoKTsKICAgICAgICAgICAgY29tcGxldGVVc2VzUHJvdmlkZXMoKTsKICAgICAgICAgICAgcmV0dXJuIENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QoZGlyZWN0aXZlcyk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgdm9pZCBjb21wbGV0ZVVzZXNQcm92aWRlcygpIHsKICAgICAgICAgICAgaWYgKHVzZXNQcm92aWRlc0NvbXBsZXRlciAhPSBDb21wbGV0ZXIuTlVMTF9DT01QTEVURVIpIHsKICAgICAgICAgICAgICAgIENvbXBsZXRlciBjID0gdXNlc1Byb3ZpZGVzQ29tcGxldGVyOwogICAgICAgICAgICAgICAgdXNlc1Byb3ZpZGVzQ29tcGxldGVyID0gQ29tcGxldGVyLk5VTExfQ09NUExFVEVSOwogICAgICAgICAgICAgICAgYy5jb21wbGV0ZSh0aGlzKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIENsYXNzU3ltYm9sIG91dGVybW9zdENsYXNzKCkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CiAgICAgICAgICAgIC8vIFRPRE86IHRoZSBmb2xsb3dpbmcgc3RyaW5ncyBzaG91bGQgYmUgbG9jYWxpemVkCiAgICAgICAgICAgIC8vIERvIHRoaXMgd2l0aCBjdXN0b20gYW5vbiBzdWJ0eXBlcyBpbiBTeW10YWIKICAgICAgICAgICAgU3RyaW5nIG4gPSAobmFtZSA9PSBudWxsKSA/ICI8dW5rbm93bj4iCiAgICAgICAgICAgICAgICAgICAgOiAobmFtZS5pc0VtcHR5KCkpID8gIjx1bm5hbWVkPiIKICAgICAgICAgICAgICAgICAgICA6IFN0cmluZy52YWx1ZU9mKG5hbWUpOwogICAgICAgICAgICByZXR1cm4gbjsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgICAgICBwdWJsaWMgPFIsIFA+IFIgYWNjZXB0KEVsZW1lbnRWaXNpdG9yPFIsIFA+IHYsIFAgcCkgewogICAgICAgICAgICByZXR1cm4gdi52aXNpdE1vZHVsZSh0aGlzLCBwKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgICAgICBwdWJsaWMgTGlzdDxTeW1ib2w+IGdldEVuY2xvc2VkRWxlbWVudHMoKSB7CiAgICAgICAgICAgIExpc3Q8U3ltYm9sPiBsaXN0ID0gTGlzdC5uaWwoKTsKICAgICAgICAgICAgZm9yIChTeW1ib2wgc3ltIDogZW5jbG9zZWRQYWNrYWdlcykgewogICAgICAgICAgICAgICAgaWYgKHN5bS5tZW1iZXJzKCkuYW55TWF0Y2gobSAtPiBtLmtpbmQgPT0gVFlQKSkKICAgICAgICAgICAgICAgICAgICBsaXN0ID0gbGlzdC5wcmVwZW5kKHN5bSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGxpc3Q7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgdm9pZCByZXNldCgpIHsKICAgICAgICAgICAgdGhpcy5kaXJlY3RpdmVzID0gbnVsbDsKICAgICAgICAgICAgdGhpcy5yZXF1aXJlcyA9IG51bGw7CiAgICAgICAgICAgIHRoaXMuZXhwb3J0cyA9IG51bGw7CiAgICAgICAgICAgIHRoaXMucHJvdmlkZXMgPSBudWxsOwogICAgICAgICAgICB0aGlzLnVzZXMgPSBudWxsOwogICAgICAgICAgICB0aGlzLnZpc2libGVQYWNrYWdlcyA9IG51bGw7CiAgICAgICAgfQoKICAgIH0KCiAgICBwdWJsaWMgZW51bSBNb2R1bGVGbGFncyB7CiAgICAgICAgT1BFTigweDAwMjApLAogICAgICAgIFNZTlRIRVRJQygweDEwMDApLAogICAgICAgIE1BTkRBVEVEKDB4ODAwMCk7CgogICAgICAgIHB1YmxpYyBzdGF0aWMgaW50IHZhbHVlKFNldDxNb2R1bGVGbGFncz4gcykgewogICAgICAgICAgICBpbnQgdiA9IDA7CiAgICAgICAgICAgIGZvciAoTW9kdWxlRmxhZ3MgZjogcykKICAgICAgICAgICAgICAgIHYgfD0gZi52YWx1ZTsKICAgICAgICAgICAgcmV0dXJuIHY7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIE1vZHVsZUZsYWdzKGludCB2YWx1ZSkgewogICAgICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgZmluYWwgaW50IHZhbHVlOwogICAgfQoKICAgIHB1YmxpYyBlbnVtIE1vZHVsZVJlc29sdXRpb25GbGFncyB7CiAgICAgICAgRE9fTk9UX1JFU09MVkVfQllfREVGQVVMVCgweDAwMDEpLAogICAgICAgIFdBUk5fREVQUkVDQVRFRCgweDAwMDIpLAogICAgICAgIFdBUk5fREVQUkVDQVRFRF9SRU1PVkFMKDB4MDAwNCksCiAgICAgICAgV0FSTl9JTkNVQkFUSU5HKDB4MDAwOCk7CgogICAgICAgIHB1YmxpYyBzdGF0aWMgaW50IHZhbHVlKFNldDxNb2R1bGVSZXNvbHV0aW9uRmxhZ3M+IHMpIHsKICAgICAgICAgICAgaW50IHYgPSAwOwogICAgICAgICAgICBmb3IgKE1vZHVsZVJlc29sdXRpb25GbGFncyBmOiBzKQogICAgICAgICAgICAgICAgdiB8PSBmLnZhbHVlOwogICAgICAgICAgICByZXR1cm4gdjsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgTW9kdWxlUmVzb2x1dGlvbkZsYWdzKGludCB2YWx1ZSkgewogICAgICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgZmluYWwgaW50IHZhbHVlOwogICAgfQoKICAgIC8qKiBBIGNsYXNzIGZvciBwYWNrYWdlIHN5bWJvbHMKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBjbGFzcyBQYWNrYWdlU3ltYm9sIGV4dGVuZHMgVHlwZVN5bWJvbAogICAgICAgIGltcGxlbWVudHMgUGFja2FnZUVsZW1lbnQgewoKICAgICAgICBwdWJsaWMgV3JpdGVhYmxlU2NvcGUgbWVtYmVyc19maWVsZDsKICAgICAgICBwdWJsaWMgTmFtZSBmdWxsbmFtZTsKICAgICAgICBwdWJsaWMgQ2xhc3NTeW1ib2wgcGFja2FnZV9pbmZvOyAvLyBzZWUgYnVnIDY0NDMwNzMKICAgICAgICBwdWJsaWMgTW9kdWxlU3ltYm9sIG1vZGxlOwogICAgICAgIC8vIHRoZSBmaWxlIGNvbnRhaW5pbmcgdGhlIGRvY3VtZW50YXRpb24gY29tbWVudHMgZm9yIHRoZSBwYWNrYWdlCiAgICAgICAgcHVibGljIEphdmFGaWxlT2JqZWN0IHNvdXJjZWZpbGU7CgogICAgICAgIHB1YmxpYyBQYWNrYWdlU3ltYm9sKE5hbWUgbmFtZSwgVHlwZSB0eXBlLCBTeW1ib2wgb3duZXIpIHsKICAgICAgICAgICAgc3VwZXIoUENLLCAwLCBuYW1lLCB0eXBlLCBvd25lcik7CiAgICAgICAgICAgIHRoaXMubWVtYmVyc19maWVsZCA9IG51bGw7CiAgICAgICAgICAgIHRoaXMuZnVsbG5hbWUgPSBmb3JtRnVsbE5hbWUobmFtZSwgb3duZXIpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIFBhY2thZ2VTeW1ib2woTmFtZSBuYW1lLCBTeW1ib2wgb3duZXIpIHsKICAgICAgICAgICAgdGhpcyhuYW1lLCBudWxsLCBvd25lcik7CiAgICAgICAgICAgIHRoaXMudHlwZSA9IG5ldyBQYWNrYWdlVHlwZSh0aGlzKTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CiAgICAgICAgICAgIHJldHVybiBmdWxsbmFtZS50b1N0cmluZygpOwogICAgICAgIH0KCiAgICAgICAgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICAgICAgcHVibGljIE5hbWUgZ2V0UXVhbGlmaWVkTmFtZSgpIHsKICAgICAgICAgICAgcmV0dXJuIGZ1bGxuYW1lOwogICAgICAgIH0KCiAgICAgICAgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICAgICAgcHVibGljIGJvb2xlYW4gaXNVbm5hbWVkKCkgewogICAgICAgICAgICByZXR1cm4gbmFtZS5pc0VtcHR5KCkgJiYgb3duZXIgIT0gbnVsbDsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBXcml0ZWFibGVTY29wZSBtZW1iZXJzKCkgewogICAgICAgICAgICBjb21wbGV0ZSgpOwogICAgICAgICAgICByZXR1cm4gbWVtYmVyc19maWVsZDsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBsb25nIGZsYWdzKCkgewogICAgICAgICAgICBjb21wbGV0ZSgpOwogICAgICAgICAgICByZXR1cm4gZmxhZ3NfZmllbGQ7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgTGlzdDxBdHRyaWJ1dGUuQ29tcG91bmQ+IGdldFJhd0F0dHJpYnV0ZXMoKSB7CiAgICAgICAgICAgIGNvbXBsZXRlKCk7CiAgICAgICAgICAgIGlmIChwYWNrYWdlX2luZm8gIT0gbnVsbCkgewogICAgICAgICAgICAgICAgcGFja2FnZV9pbmZvLmNvbXBsZXRlKCk7CiAgICAgICAgICAgICAgICBtZXJnZUF0dHJpYnV0ZXMoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gc3VwZXIuZ2V0UmF3QXR0cmlidXRlcygpOwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSB2b2lkIG1lcmdlQXR0cmlidXRlcygpIHsKICAgICAgICAgICAgaWYgKG1ldGFkYXRhID09IG51bGwgJiYKICAgICAgICAgICAgICAgIHBhY2thZ2VfaW5mby5tZXRhZGF0YSAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICBtZXRhZGF0YSA9IG5ldyBTeW1ib2xNZXRhZGF0YSh0aGlzKTsKICAgICAgICAgICAgICAgIG1ldGFkYXRhLnNldEF0dHJpYnV0ZXMocGFja2FnZV9pbmZvLm1ldGFkYXRhKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLyoqIEEgcGFja2FnZSAiZXhpc3RzIiBpZiBhIHR5cGUgb3IgcGFja2FnZSB0aGF0IGV4aXN0cyBoYXMKICAgICAgICAgKiAgYmVlbiBzZWVuIHdpdGhpbiBpdC4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgYm9vbGVhbiBleGlzdHMoKSB7CiAgICAgICAgICAgIHJldHVybiAoZmxhZ3NfZmllbGQgJiBFWElTVFMpICE9IDA7CiAgICAgICAgfQoKICAgICAgICBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgICAgICBwdWJsaWMgRWxlbWVudEtpbmQgZ2V0S2luZCgpIHsKICAgICAgICAgICAgcmV0dXJuIEVsZW1lbnRLaW5kLlBBQ0tBR0U7CiAgICAgICAgfQoKICAgICAgICBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgICAgICBwdWJsaWMgU3ltYm9sIGdldEVuY2xvc2luZ0VsZW1lbnQoKSB7CiAgICAgICAgICAgIHJldHVybiBtb2RsZSAhPSBudWxsICYmICFtb2RsZS5pc05vTW9kdWxlKCkgPyBtb2RsZSA6IG51bGw7CiAgICAgICAgfQoKICAgICAgICBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgICAgICBwdWJsaWMgPFIsIFA+IFIgYWNjZXB0KEVsZW1lbnRWaXNpdG9yPFIsIFA+IHYsIFAgcCkgewogICAgICAgICAgICByZXR1cm4gdi52aXNpdFBhY2thZ2UodGhpcywgcCk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgPFIsIFA+IFIgYWNjZXB0KFN5bWJvbC5WaXNpdG9yPFIsIFA+IHYsIFAgcCkgewogICAgICAgICAgICByZXR1cm4gdi52aXNpdFBhY2thZ2VTeW1ib2wodGhpcywgcCk7CiAgICAgICAgfQoKICAgICAgICAvKipSZXNldHMgdGhlIFN5bWJvbCBpbnRvIHRoZSBzdGF0ZSBnb29kIGZvciBuZXh0IHJvdW5kIG9mIGFubm90YXRpb24gcHJvY2Vzc2luZy4qLwogICAgICAgIHB1YmxpYyB2b2lkIHJlc2V0KCkgewogICAgICAgICAgICBtZXRhZGF0YSA9IG51bGw7CiAgICAgICAgfQoKICAgIH0KCiAgICAvKiogQSBjbGFzcyBmb3IgY2xhc3Mgc3ltYm9scwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIENsYXNzU3ltYm9sIGV4dGVuZHMgVHlwZVN5bWJvbCBpbXBsZW1lbnRzIFR5cGVFbGVtZW50IHsKCiAgICAgICAgLyoqIGEgc2NvcGUgZm9yIGFsbCBjbGFzcyBtZW1iZXJzOyB2YXJpYWJsZXMsIG1ldGhvZHMgYW5kIGlubmVyIGNsYXNzZXMKICAgICAgICAgKiAgdHlwZSBwYXJhbWV0ZXJzIGFyZSBub3QgcGFydCBvZiB0aGlzIHNjb3BlCiAgICAgICAgICovCiAgICAgICAgcHVibGljIFdyaXRlYWJsZVNjb3BlIG1lbWJlcnNfZmllbGQ7CgogICAgICAgIC8qKiB0aGUgZnVsbHkgcXVhbGlmaWVkIG5hbWUgb2YgdGhlIGNsYXNzLCBpLmUuIHBjay5vdXRlci5pbm5lci4KICAgICAgICAgKiAgbnVsbCBmb3IgYW5vbnltb3VzIGNsYXNzZXMKICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgTmFtZSBmdWxsbmFtZTsKCiAgICAgICAgLyoqIHRoZSBmdWxseSBxdWFsaWZpZWQgbmFtZSBvZiB0aGUgY2xhc3MgYWZ0ZXIgY29udmVydGluZyB0byBmbGF0CiAgICAgICAgICogIHJlcHJlc2VudGF0aW9uLCBpLmUuIHBjay5vdXRlciRpbm5lciwKICAgICAgICAgKiAgc2V0IGV4dGVybmFsbHkgZm9yIGxvY2FsIGFuZCBhbm9ueW1vdXMgY2xhc3NlcwogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBOYW1lIGZsYXRuYW1lOwoKICAgICAgICAvKiogdGhlIHNvdXJjZWZpbGUgd2hlcmUgdGhlIGNsYXNzIGNhbWUgZnJvbQogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBKYXZhRmlsZU9iamVjdCBzb3VyY2VmaWxlOwoKICAgICAgICAvKiogdGhlIGNsYXNzZmlsZSBmcm9tIHdoZXJlIHRvIGxvYWQgdGhpcyBjbGFzcwogICAgICAgICAqICB0aGlzIHdpbGwgaGF2ZSBleHRlbnNpb24gLmNsYXNzIG9yIC5qYXZhCiAgICAgICAgICovCiAgICAgICAgcHVibGljIEphdmFGaWxlT2JqZWN0IGNsYXNzZmlsZTsKCiAgICAgICAgLyoqIHRoZSBsaXN0IG9mIHRyYW5zbGF0ZWQgbG9jYWwgY2xhc3NlcyAodXNlZCBmb3IgZ2VuZXJhdGluZwogICAgICAgICAqIElubmVyQ2xhc3NlcyBhdHRyaWJ1dGUpCiAgICAgICAgICovCiAgICAgICAgcHVibGljIExpc3Q8Q2xhc3NTeW1ib2w+IHRyYW5zX2xvY2FsOwoKICAgICAgICAvKiogdGhlIGNvbnN0YW50IHBvb2wgb2YgdGhlIGNsYXNzCiAgICAgICAgICovCiAgICAgICAgcHVibGljIFBvb2wgcG9vbDsKCiAgICAgICAgLyoqIHRoZSBhbm5vdGF0aW9uIG1ldGFkYXRhIGF0dGFjaGVkIHRvIHRoaXMgY2xhc3MgKi8KICAgICAgICBwcml2YXRlIEFubm90YXRpb25UeXBlTWV0YWRhdGEgYW5ub3RhdGlvblR5cGVNZXRhZGF0YTsKCiAgICAgICAgcHVibGljIENsYXNzU3ltYm9sKGxvbmcgZmxhZ3MsIE5hbWUgbmFtZSwgVHlwZSB0eXBlLCBTeW1ib2wgb3duZXIpIHsKICAgICAgICAgICAgc3VwZXIoVFlQLCBmbGFncywgbmFtZSwgdHlwZSwgb3duZXIpOwogICAgICAgICAgICB0aGlzLm1lbWJlcnNfZmllbGQgPSBudWxsOwogICAgICAgICAgICB0aGlzLmZ1bGxuYW1lID0gZm9ybUZ1bGxOYW1lKG5hbWUsIG93bmVyKTsKICAgICAgICAgICAgdGhpcy5mbGF0bmFtZSA9IGZvcm1GbGF0TmFtZShuYW1lLCBvd25lcik7CiAgICAgICAgICAgIHRoaXMuc291cmNlZmlsZSA9IG51bGw7CiAgICAgICAgICAgIHRoaXMuY2xhc3NmaWxlID0gbnVsbDsKICAgICAgICAgICAgdGhpcy5wb29sID0gbnVsbDsKICAgICAgICAgICAgdGhpcy5hbm5vdGF0aW9uVHlwZU1ldGFkYXRhID0gQW5ub3RhdGlvblR5cGVNZXRhZGF0YS5ub3RBbkFubm90YXRpb25UeXBlKCk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgQ2xhc3NTeW1ib2wobG9uZyBmbGFncywgTmFtZSBuYW1lLCBTeW1ib2wgb3duZXIpIHsKICAgICAgICAgICAgdGhpcygKICAgICAgICAgICAgICAgIGZsYWdzLAogICAgICAgICAgICAgICAgbmFtZSwKICAgICAgICAgICAgICAgIG5ldyBDbGFzc1R5cGUoVHlwZS5ub1R5cGUsIG51bGwsIG51bGwpLAogICAgICAgICAgICAgICAgb3duZXIpOwogICAgICAgICAgICB0aGlzLnR5cGUudHN5bSA9IHRoaXM7CiAgICAgICAgfQoKICAgICAgICAvKiogVGhlIEphdmEgc291cmNlIHdoaWNoIHRoaXMgc3ltYm9sIHJlcHJlc2VudHMuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKICAgICAgICAgICAgcmV0dXJuIGNsYXNzTmFtZSgpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIGxvbmcgZmxhZ3MoKSB7CiAgICAgICAgICAgIGNvbXBsZXRlKCk7CiAgICAgICAgICAgIHJldHVybiBmbGFnc19maWVsZDsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBXcml0ZWFibGVTY29wZSBtZW1iZXJzKCkgewogICAgICAgICAgICBjb21wbGV0ZSgpOwogICAgICAgICAgICByZXR1cm4gbWVtYmVyc19maWVsZDsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBMaXN0PEF0dHJpYnV0ZS5Db21wb3VuZD4gZ2V0UmF3QXR0cmlidXRlcygpIHsKICAgICAgICAgICAgY29tcGxldGUoKTsKICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmdldFJhd0F0dHJpYnV0ZXMoKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBMaXN0PEF0dHJpYnV0ZS5UeXBlQ29tcG91bmQ+IGdldFJhd1R5cGVBdHRyaWJ1dGVzKCkgewogICAgICAgICAgICBjb21wbGV0ZSgpOwogICAgICAgICAgICByZXR1cm4gc3VwZXIuZ2V0UmF3VHlwZUF0dHJpYnV0ZXMoKTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBUeXBlIGVyYXN1cmUoVHlwZXMgdHlwZXMpIHsKICAgICAgICAgICAgaWYgKGVyYXN1cmVfZmllbGQgPT0gbnVsbCkKICAgICAgICAgICAgICAgIGVyYXN1cmVfZmllbGQgPSBuZXcgQ2xhc3NUeXBlKHR5cGVzLmVyYXN1cmUodHlwZS5nZXRFbmNsb3NpbmdUeXBlKCkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTGlzdC5uaWwoKSwgdGhpcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUuZ2V0TWV0YWRhdGEoKSk7CiAgICAgICAgICAgIHJldHVybiBlcmFzdXJlX2ZpZWxkOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIFN0cmluZyBjbGFzc05hbWUoKSB7CiAgICAgICAgICAgIGlmIChuYW1lLmlzRW1wdHkoKSkKICAgICAgICAgICAgICAgIHJldHVybgogICAgICAgICAgICAgICAgICAgIExvZy5nZXRMb2NhbGl6ZWRTdHJpbmcoImFub255bW91cy5jbGFzcyIsIGZsYXRuYW1lKTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgcmV0dXJuIGZ1bGxuYW1lLnRvU3RyaW5nKCk7CiAgICAgICAgfQoKICAgICAgICBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgICAgICBwdWJsaWMgTmFtZSBnZXRRdWFsaWZpZWROYW1lKCkgewogICAgICAgICAgICByZXR1cm4gZnVsbG5hbWU7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgTmFtZSBmbGF0TmFtZSgpIHsKICAgICAgICAgICAgcmV0dXJuIGZsYXRuYW1lOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIGJvb2xlYW4gaXNTdWJDbGFzcyhTeW1ib2wgYmFzZSwgVHlwZXMgdHlwZXMpIHsKICAgICAgICAgICAgaWYgKHRoaXMgPT0gYmFzZSkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0gZWxzZSBpZiAoKGJhc2UuZmxhZ3MoKSAmIElOVEVSRkFDRSkgIT0gMCkgewogICAgICAgICAgICAgICAgZm9yIChUeXBlIHQgPSB0eXBlOyB0Lmhhc1RhZyhDTEFTUyk7IHQgPSB0eXBlcy5zdXBlcnR5cGUodCkpCiAgICAgICAgICAgICAgICAgICAgZm9yIChMaXN0PFR5cGU+IGlzID0gdHlwZXMuaW50ZXJmYWNlcyh0KTsKICAgICAgICAgICAgICAgICAgICAgICAgIGlzLm5vbkVtcHR5KCk7CiAgICAgICAgICAgICAgICAgICAgICAgICBpcyA9IGlzLnRhaWwpCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpcy5oZWFkLnRzeW0uaXNTdWJDbGFzcyhiYXNlLCB0eXBlcykpIHJldHVybiB0cnVlOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgZm9yIChUeXBlIHQgPSB0eXBlOyB0Lmhhc1RhZyhDTEFTUyk7IHQgPSB0eXBlcy5zdXBlcnR5cGUodCkpCiAgICAgICAgICAgICAgICAgICAgaWYgKHQudHN5bSA9PSBiYXNlKSByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICAvKiogQ29tcGxldGUgdGhlIGVsYWJvcmF0aW9uIG9mIHRoaXMgc3ltYm9sJ3MgZGVmaW5pdGlvbi4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgdm9pZCBjb21wbGV0ZSgpIHRocm93cyBDb21wbGV0aW9uRmFpbHVyZSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBzdXBlci5jb21wbGV0ZSgpOwogICAgICAgICAgICB9IGNhdGNoIChDb21wbGV0aW9uRmFpbHVyZSBleCkgewogICAgICAgICAgICAgICAgLy8gcXVpZXQgZXJyb3IgcmVjb3ZlcnkKICAgICAgICAgICAgICAgIGZsYWdzX2ZpZWxkIHw9IChQVUJMSUN8U1RBVElDKTsKICAgICAgICAgICAgICAgIHRoaXMudHlwZSA9IG5ldyBFcnJvclR5cGUodGhpcywgVHlwZS5ub1R5cGUpOwogICAgICAgICAgICAgICAgdGhyb3cgZXg7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyBMaXN0PFR5cGU+IGdldEludGVyZmFjZXMoKSB7CiAgICAgICAgICAgIGNvbXBsZXRlKCk7CiAgICAgICAgICAgIGlmICh0eXBlIGluc3RhbmNlb2YgQ2xhc3NUeXBlKSB7CiAgICAgICAgICAgICAgICBDbGFzc1R5cGUgdCA9IChDbGFzc1R5cGUpdHlwZTsKICAgICAgICAgICAgICAgIGlmICh0LmludGVyZmFjZXNfZmllbGQgPT0gbnVsbCkgLy8gRklYTUU6IHNob3VsZG4ndCBiZSBudWxsCiAgICAgICAgICAgICAgICAgICAgdC5pbnRlcmZhY2VzX2ZpZWxkID0gTGlzdC5uaWwoKTsKICAgICAgICAgICAgICAgIGlmICh0LmFsbF9pbnRlcmZhY2VzX2ZpZWxkICE9IG51bGwpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFR5cGUuZ2V0TW9kZWxUeXBlcyh0LmFsbF9pbnRlcmZhY2VzX2ZpZWxkKTsKICAgICAgICAgICAgICAgIHJldHVybiB0LmludGVyZmFjZXNfZmllbGQ7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICByZXR1cm4gTGlzdC5uaWwoKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICAgICAgcHVibGljIFR5cGUgZ2V0U3VwZXJjbGFzcygpIHsKICAgICAgICAgICAgY29tcGxldGUoKTsKICAgICAgICAgICAgaWYgKHR5cGUgaW5zdGFuY2VvZiBDbGFzc1R5cGUpIHsKICAgICAgICAgICAgICAgIENsYXNzVHlwZSB0ID0gKENsYXNzVHlwZSl0eXBlOwogICAgICAgICAgICAgICAgaWYgKHQuc3VwZXJ0eXBlX2ZpZWxkID09IG51bGwpIC8vIEZJWE1FOiBzaG91bGRuJ3QgYmUgbnVsbAogICAgICAgICAgICAgICAgICAgIHQuc3VwZXJ0eXBlX2ZpZWxkID0gVHlwZS5ub1R5cGU7CiAgICAgICAgICAgICAgICAvLyBBbiBpbnRlcmZhY2UgaGFzIG5vIHN1cGVyY2xhc3M7IGl0cyBzdXBlcnR5cGUgaXMgT2JqZWN0LgogICAgICAgICAgICAgICAgcmV0dXJuIHQuaXNJbnRlcmZhY2UoKQogICAgICAgICAgICAgICAgICAgID8gVHlwZS5ub1R5cGUKICAgICAgICAgICAgICAgICAgICA6IHQuc3VwZXJ0eXBlX2ZpZWxkLmdldE1vZGVsVHlwZSgpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcmV0dXJuIFR5cGUubm9UeXBlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBSZXR1cm5zIHRoZSBuZXh0IGNsYXNzIHRvIHNlYXJjaCBmb3IgaW5oZXJpdGVkIGFubm90YXRpb25zIG9yIHtAY29kZSBudWxsfQogICAgICAgICAqIGlmIHRoZSBuZXh0IGNsYXNzIGNhbid0IGJlIGZvdW5kLgogICAgICAgICAqLwogICAgICAgIHByaXZhdGUgQ2xhc3NTeW1ib2wgZ2V0U3VwZXJDbGFzc1RvU2VhcmNoRm9yQW5ub3RhdGlvbnMoKSB7CgogICAgICAgICAgICBUeXBlIHN1cCA9IGdldFN1cGVyY2xhc3MoKTsKCiAgICAgICAgICAgIGlmICghc3VwLmhhc1RhZyhDTEFTUykgfHwgc3VwLmlzRXJyb25lb3VzKCkpCiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKCiAgICAgICAgICAgIHJldHVybiAoQ2xhc3NTeW1ib2wpIHN1cC50c3ltOwogICAgICAgIH0KCgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHByb3RlY3RlZCA8QSBleHRlbmRzIEFubm90YXRpb24+IEFbXSBnZXRJbmhlcml0ZWRBbm5vdGF0aW9ucyhDbGFzczxBPiBhbm5vVHlwZSkgewoKICAgICAgICAgICAgQ2xhc3NTeW1ib2wgc3VwID0gZ2V0U3VwZXJDbGFzc1RvU2VhcmNoRm9yQW5ub3RhdGlvbnMoKTsKCiAgICAgICAgICAgIHJldHVybiBzdXAgPT0gbnVsbCA/IHN1cGVyLmdldEluaGVyaXRlZEFubm90YXRpb25zKGFubm9UeXBlKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBzdXAuZ2V0QW5ub3RhdGlvbnNCeVR5cGUoYW5ub1R5cGUpOwogICAgICAgIH0KCgogICAgICAgIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyBFbGVtZW50S2luZCBnZXRLaW5kKCkgewogICAgICAgICAgICBsb25nIGZsYWdzID0gZmxhZ3MoKTsKICAgICAgICAgICAgaWYgKChmbGFncyAmIEFOTk9UQVRJT04pICE9IDApCiAgICAgICAgICAgICAgICByZXR1cm4gRWxlbWVudEtpbmQuQU5OT1RBVElPTl9UWVBFOwogICAgICAgICAgICBlbHNlIGlmICgoZmxhZ3MgJiBJTlRFUkZBQ0UpICE9IDApCiAgICAgICAgICAgICAgICByZXR1cm4gRWxlbWVudEtpbmQuSU5URVJGQUNFOwogICAgICAgICAgICBlbHNlIGlmICgoZmxhZ3MgJiBFTlVNKSAhPSAwKQogICAgICAgICAgICAgICAgcmV0dXJuIEVsZW1lbnRLaW5kLkVOVU07CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHJldHVybiBFbGVtZW50S2luZC5DTEFTUzsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgICAgICBwdWJsaWMgU2V0PE1vZGlmaWVyPiBnZXRNb2RpZmllcnMoKSB7CiAgICAgICAgICAgIGxvbmcgZmxhZ3MgPSBmbGFncygpOwogICAgICAgICAgICByZXR1cm4gRmxhZ3MuYXNNb2RpZmllclNldChmbGFncyAmIH5ERUZBVUxUKTsKICAgICAgICB9CgogICAgICAgIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyBOZXN0aW5nS2luZCBnZXROZXN0aW5nS2luZCgpIHsKICAgICAgICAgICAgY29tcGxldGUoKTsKICAgICAgICAgICAgaWYgKG93bmVyLmtpbmQgPT0gUENLKQogICAgICAgICAgICAgICAgcmV0dXJuIE5lc3RpbmdLaW5kLlRPUF9MRVZFTDsKICAgICAgICAgICAgZWxzZSBpZiAobmFtZS5pc0VtcHR5KCkpCiAgICAgICAgICAgICAgICByZXR1cm4gTmVzdGluZ0tpbmQuQU5PTllNT1VTOwogICAgICAgICAgICBlbHNlIGlmIChvd25lci5raW5kID09IE1USCkKICAgICAgICAgICAgICAgIHJldHVybiBOZXN0aW5nS2luZC5MT0NBTDsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgcmV0dXJuIE5lc3RpbmdLaW5kLk1FTUJFUjsKICAgICAgICB9CgoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwcm90ZWN0ZWQgPEEgZXh0ZW5kcyBBbm5vdGF0aW9uPiBBdHRyaWJ1dGUuQ29tcG91bmQgZ2V0QXR0cmlidXRlKGZpbmFsIENsYXNzPEE+IGFubm9UeXBlKSB7CgogICAgICAgICAgICBBdHRyaWJ1dGUuQ29tcG91bmQgYXR0cmliID0gc3VwZXIuZ2V0QXR0cmlidXRlKGFubm9UeXBlKTsKCiAgICAgICAgICAgIGJvb2xlYW4gaW5oZXJpdGVkID0gYW5ub1R5cGUuaXNBbm5vdGF0aW9uUHJlc2VudChJbmhlcml0ZWQuY2xhc3MpOwogICAgICAgICAgICBpZiAoYXR0cmliICE9IG51bGwgfHwgIWluaGVyaXRlZCkKICAgICAgICAgICAgICAgIHJldHVybiBhdHRyaWI7CgogICAgICAgICAgICAvLyBTZWFyY2ggc3VwZXJ0eXBlcwogICAgICAgICAgICBDbGFzc1N5bWJvbCBzdXBlclR5cGUgPSBnZXRTdXBlckNsYXNzVG9TZWFyY2hGb3JBbm5vdGF0aW9ucygpOwogICAgICAgICAgICByZXR1cm4gc3VwZXJUeXBlID09IG51bGwgPyBudWxsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IHN1cGVyVHlwZS5nZXRBdHRyaWJ1dGUoYW5ub1R5cGUpOwogICAgICAgIH0KCgoKCiAgICAgICAgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICAgICAgcHVibGljIDxSLCBQPiBSIGFjY2VwdChFbGVtZW50VmlzaXRvcjxSLCBQPiB2LCBQIHApIHsKICAgICAgICAgICAgcmV0dXJuIHYudmlzaXRUeXBlKHRoaXMsIHApOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIDxSLCBQPiBSIGFjY2VwdChTeW1ib2wuVmlzaXRvcjxSLCBQPiB2LCBQIHApIHsKICAgICAgICAgICAgcmV0dXJuIHYudmlzaXRDbGFzc1N5bWJvbCh0aGlzLCBwKTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyB2b2lkIG1hcmtBYnN0cmFjdElmTmVlZGVkKFR5cGVzIHR5cGVzKSB7CiAgICAgICAgICAgIGlmICh0eXBlcy5lbnRlci5nZXRFbnYodGhpcykgIT0gbnVsbCAmJgogICAgICAgICAgICAgICAgKGZsYWdzKCkgJiBFTlVNKSAhPSAwICYmIHR5cGVzLnN1cGVydHlwZSh0eXBlKS50c3ltID09IHR5cGVzLnN5bXMuZW51bVN5bSAmJgogICAgICAgICAgICAgICAgKGZsYWdzKCkgJiAoRklOQUwgfCBBQlNUUkFDVCkpID09IDApIHsKICAgICAgICAgICAgICAgIGlmICh0eXBlcy5maXJzdFVuaW1wbGVtZW50ZWRBYnN0cmFjdCh0aGlzKSAhPSBudWxsKQogICAgICAgICAgICAgICAgICAgIC8vIGFkZCB0aGUgQUJTVFJBQ1QgZmxhZyB0byBhbiBlbnVtCiAgICAgICAgICAgICAgICAgICAgZmxhZ3NfZmllbGQgfD0gQUJTVFJBQ1Q7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8qKlJlc2V0cyB0aGUgU3ltYm9sIGludG8gdGhlIHN0YXRlIGdvb2QgZm9yIG5leHQgcm91bmQgb2YgYW5ub3RhdGlvbiBwcm9jZXNzaW5nLiovCiAgICAgICAgcHVibGljIHZvaWQgcmVzZXQoKSB7CiAgICAgICAgICAgIGtpbmQgPSBUWVA7CiAgICAgICAgICAgIGVyYXN1cmVfZmllbGQgPSBudWxsOwogICAgICAgICAgICBtZW1iZXJzX2ZpZWxkID0gbnVsbDsKICAgICAgICAgICAgZmxhZ3NfZmllbGQgPSAwOwogICAgICAgICAgICBpZiAodHlwZSBpbnN0YW5jZW9mIENsYXNzVHlwZSkgewogICAgICAgICAgICAgICAgQ2xhc3NUeXBlIHQgPSAoQ2xhc3NUeXBlKXR5cGU7CiAgICAgICAgICAgICAgICB0LnNldEVuY2xvc2luZ1R5cGUoVHlwZS5ub1R5cGUpOwogICAgICAgICAgICAgICAgdC5yYW5rX2ZpZWxkID0gLTE7CiAgICAgICAgICAgICAgICB0LnR5cGFyYW1zX2ZpZWxkID0gbnVsbDsKICAgICAgICAgICAgICAgIHQuYWxscGFyYW1zX2ZpZWxkID0gbnVsbDsKICAgICAgICAgICAgICAgIHQuc3VwZXJ0eXBlX2ZpZWxkID0gbnVsbDsKICAgICAgICAgICAgICAgIHQuaW50ZXJmYWNlc19maWVsZCA9IG51bGw7CiAgICAgICAgICAgICAgICB0LmFsbF9pbnRlcmZhY2VzX2ZpZWxkID0gbnVsbDsKICAgICAgICAgICAgfQogICAgICAgICAgICBjbGVhckFubm90YXRpb25NZXRhZGF0YSgpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHZvaWQgY2xlYXJBbm5vdGF0aW9uTWV0YWRhdGEoKSB7CiAgICAgICAgICAgIG1ldGFkYXRhID0gbnVsbDsKICAgICAgICAgICAgYW5ub3RhdGlvblR5cGVNZXRhZGF0YSA9IEFubm90YXRpb25UeXBlTWV0YWRhdGEubm90QW5Bbm5vdGF0aW9uVHlwZSgpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIEFubm90YXRpb25UeXBlTWV0YWRhdGEgZ2V0QW5ub3RhdGlvblR5cGVNZXRhZGF0YSgpIHsKICAgICAgICAgICAgcmV0dXJuIGFubm90YXRpb25UeXBlTWV0YWRhdGE7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc0Fubm90YXRpb25UeXBlKCkgewogICAgICAgICAgICByZXR1cm4gKGZsYWdzX2ZpZWxkICYgRmxhZ3MuQU5OT1RBVElPTikgIT0gMDsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyB2b2lkIHNldEFubm90YXRpb25UeXBlTWV0YWRhdGEoQW5ub3RhdGlvblR5cGVNZXRhZGF0YSBhKSB7CiAgICAgICAgICAgIEFzc2VydC5jaGVja05vbk51bGwoYSk7CiAgICAgICAgICAgIEFzc2VydC5jaGVjayghYW5ub3RhdGlvblR5cGVNZXRhZGF0YS5pc01ldGFkYXRhRm9yQW5ub3RhdGlvblR5cGUoKSk7CiAgICAgICAgICAgIHRoaXMuYW5ub3RhdGlvblR5cGVNZXRhZGF0YSA9IGE7CiAgICAgICAgfQogICAgfQoKCiAgICAvKiogQSBjbGFzcyBmb3IgdmFyaWFibGUgc3ltYm9scwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIFZhclN5bWJvbCBleHRlbmRzIFN5bWJvbCBpbXBsZW1lbnRzIFZhcmlhYmxlRWxlbWVudCB7CgogICAgICAgIC8qKiBUaGUgdmFyaWFibGUncyBkZWNsYXJhdGlvbiBwb3NpdGlvbi4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgaW50IHBvcyA9IFBvc2l0aW9uLk5PUE9TOwoKICAgICAgICAvKiogVGhlIHZhcmlhYmxlJ3MgYWRkcmVzcy4gVXNlZCBmb3IgZGlmZmVyZW50IHB1cnBvc2VzIGR1cmluZwogICAgICAgICAqICBmbG93IGFuYWx5c2lzLCB0cmFuc2xhdGlvbiBhbmQgY29kZSBnZW5lcmF0aW9uLgogICAgICAgICAqICBGbG93IGFuYWx5c2lzOgogICAgICAgICAqICAgIElmIHRoaXMgaXMgYSBibGFuayBmaW5hbCBvciBsb2NhbCB2YXJpYWJsZSwgaXRzIHNlcXVlbmNlIG51bWJlci4KICAgICAgICAgKiAgVHJhbnNsYXRpb246CiAgICAgICAgICogICAgSWYgdGhpcyBpcyBhIHByaXZhdGUgZmllbGQsIGl0cyBhY2Nlc3MgbnVtYmVyLgogICAgICAgICAqICBDb2RlIGdlbmVyYXRpb246CiAgICAgICAgICogICAgSWYgdGhpcyBpcyBhIGxvY2FsIHZhcmlhYmxlLCBpdHMgbG9naWNhbCBzbG90IG51bWJlci4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgaW50IGFkciA9IC0xOwoKICAgICAgICAvKiogQ29uc3RydWN0IGEgdmFyaWFibGUgc3ltYm9sLCBnaXZlbiBpdHMgZmxhZ3MsIG5hbWUsIHR5cGUgYW5kIG93bmVyLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBWYXJTeW1ib2wobG9uZyBmbGFncywgTmFtZSBuYW1lLCBUeXBlIHR5cGUsIFN5bWJvbCBvd25lcikgewogICAgICAgICAgICBzdXBlcihWQVIsIGZsYWdzLCBuYW1lLCB0eXBlLCBvd25lcik7CiAgICAgICAgfQoKICAgICAgICAvKiogQ2xvbmUgdGhpcyBzeW1ib2wgd2l0aCBuZXcgb3duZXIuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIFZhclN5bWJvbCBjbG9uZShTeW1ib2wgbmV3T3duZXIpIHsKICAgICAgICAgICAgVmFyU3ltYm9sIHYgPSBuZXcgVmFyU3ltYm9sKGZsYWdzX2ZpZWxkLCBuYW1lLCB0eXBlLCBuZXdPd25lcikgewogICAgICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgICAgICBwdWJsaWMgU3ltYm9sIGJhc2VTeW1ib2woKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFZhclN5bWJvbC50aGlzOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwogICAgICAgICAgICB2LnBvcyA9IHBvczsKICAgICAgICAgICAgdi5hZHIgPSBhZHI7CiAgICAgICAgICAgIHYuZGF0YSA9IGRhdGE7Ci8vICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiY2xvbmUgIiArIHYgKyAiIGluICIgKyBuZXdPd25lcik7Ly9ERUJVRwogICAgICAgICAgICByZXR1cm4gdjsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CiAgICAgICAgICAgIHJldHVybiBuYW1lLnRvU3RyaW5nKCk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgU3ltYm9sIGFzTWVtYmVyT2YoVHlwZSBzaXRlLCBUeXBlcyB0eXBlcykgewogICAgICAgICAgICByZXR1cm4gbmV3IFZhclN5bWJvbChmbGFnc19maWVsZCwgbmFtZSwgdHlwZXMubWVtYmVyVHlwZShzaXRlLCB0aGlzKSwgb3duZXIpOwogICAgICAgIH0KCiAgICAgICAgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICAgICAgcHVibGljIEVsZW1lbnRLaW5kIGdldEtpbmQoKSB7CiAgICAgICAgICAgIGxvbmcgZmxhZ3MgPSBmbGFncygpOwogICAgICAgICAgICBpZiAoKGZsYWdzICYgUEFSQU1FVEVSKSAhPSAwKSB7CiAgICAgICAgICAgICAgICBpZiAoaXNFeGNlcHRpb25QYXJhbWV0ZXIoKSkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gRWxlbWVudEtpbmQuRVhDRVBUSU9OX1BBUkFNRVRFUjsKICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICByZXR1cm4gRWxlbWVudEtpbmQuUEFSQU1FVEVSOwogICAgICAgICAgICB9IGVsc2UgaWYgKChmbGFncyAmIEVOVU0pICE9IDApIHsKICAgICAgICAgICAgICAgIHJldHVybiBFbGVtZW50S2luZC5FTlVNX0NPTlNUQU5UOwogICAgICAgICAgICB9IGVsc2UgaWYgKG93bmVyLmtpbmQgPT0gVFlQIHx8IG93bmVyLmtpbmQgPT0gRVJSKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gRWxlbWVudEtpbmQuRklFTEQ7CiAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNSZXNvdXJjZVZhcmlhYmxlKCkpIHsKICAgICAgICAgICAgICAgIHJldHVybiBFbGVtZW50S2luZC5SRVNPVVJDRV9WQVJJQUJMRTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHJldHVybiBFbGVtZW50S2luZC5MT0NBTF9WQVJJQUJMRTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICAgICAgcHVibGljIDxSLCBQPiBSIGFjY2VwdChFbGVtZW50VmlzaXRvcjxSLCBQPiB2LCBQIHApIHsKICAgICAgICAgICAgcmV0dXJuIHYudmlzaXRWYXJpYWJsZSh0aGlzLCBwKTsKICAgICAgICB9CgogICAgICAgIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyBPYmplY3QgZ2V0Q29uc3RhbnRWYWx1ZSgpIHsgLy8gTWlycm9yIEFQSQogICAgICAgICAgICByZXR1cm4gQ29uc3RhbnRzLmRlY29kZShnZXRDb25zdFZhbHVlKCksIHR5cGUpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHZvaWQgc2V0TGF6eUNvbnN0VmFsdWUoZmluYWwgRW52PEF0dHJDb250ZXh0PiBlbnYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgQXR0ciBhdHRyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIEpDVmFyaWFibGVEZWNsIHZhcmlhYmxlKQogICAgICAgIHsKICAgICAgICAgICAgc2V0RGF0YSgoQ2FsbGFibGU8T2JqZWN0PikoKSAtPiBhdHRyLmF0dHJpYkxhenlDb25zdGFudFZhbHVlKGVudiwgdmFyaWFibGUsIHR5cGUpKTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIFRoZSB2YXJpYWJsZSdzIGNvbnN0YW50IHZhbHVlLCBpZiB0aGlzIGlzIGEgY29uc3RhbnQuCiAgICAgICAgICogQmVmb3JlIHRoZSBjb25zdGFudCB2YWx1ZSBpcyBldmFsdWF0ZWQsIGl0IHBvaW50cyB0byBhbgogICAgICAgICAqIGluaXRpYWxpemVyIGVudmlyb25tZW50LiAgSWYgdGhpcyBpcyBub3QgYSBjb25zdGFudCwgaXQgY2FuCiAgICAgICAgICogYmUgdXNlZCBmb3Igb3RoZXIgc3R1ZmYuCiAgICAgICAgICovCiAgICAgICAgcHJpdmF0ZSBPYmplY3QgZGF0YTsKCiAgICAgICAgcHVibGljIGJvb2xlYW4gaXNFeGNlcHRpb25QYXJhbWV0ZXIoKSB7CiAgICAgICAgICAgIHJldHVybiBkYXRhID09IEVsZW1lbnRLaW5kLkVYQ0VQVElPTl9QQVJBTUVURVI7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc1Jlc291cmNlVmFyaWFibGUoKSB7CiAgICAgICAgICAgIHJldHVybiBkYXRhID09IEVsZW1lbnRLaW5kLlJFU09VUkNFX1ZBUklBQkxFOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIE9iamVjdCBnZXRDb25zdFZhbHVlKCkgewogICAgICAgICAgICAvLyBUT0RPOiBDb25zaWRlciBpZiBnZXRDb25zdFZhbHVlIGFuZCBnZXRDb25zdGFudFZhbHVlIGNhbiBiZSBjb2xsYXBzZWQKICAgICAgICAgICAgaWYgKGRhdGEgPT0gRWxlbWVudEtpbmQuRVhDRVBUSU9OX1BBUkFNRVRFUiB8fAogICAgICAgICAgICAgICAgZGF0YSA9PSBFbGVtZW50S2luZC5SRVNPVVJDRV9WQVJJQUJMRSkgewogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0gZWxzZSBpZiAoZGF0YSBpbnN0YW5jZW9mIENhbGxhYmxlPD8+KSB7CiAgICAgICAgICAgICAgICAvLyBJbiB0aGlzIGNhc2UsIHRoaXMgaXMgYSBmaW5hbCB2YXJpYWJsZSwgd2l0aCBhbiBhcwogICAgICAgICAgICAgICAgLy8geWV0IHVuZXZhbHVhdGVkIGluaXRpYWxpemVyLgogICAgICAgICAgICAgICAgQ2FsbGFibGU8Pz4gZXZhbCA9IChDYWxsYWJsZTw/PilkYXRhOwogICAgICAgICAgICAgICAgZGF0YSA9IG51bGw7IC8vIHRvIG1ha2Ugc3VyZSB3ZSBkb24ndCBldmFsdWF0ZSB0aGlzIHR3aWNlLgogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICBkYXRhID0gZXZhbC5jYWxsKCk7CiAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoZXgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBkYXRhOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHZvaWQgc2V0RGF0YShPYmplY3QgZGF0YSkgewogICAgICAgICAgICBBc3NlcnQuY2hlY2soIShkYXRhIGluc3RhbmNlb2YgRW52PD8+KSwgdGhpcyk7CiAgICAgICAgICAgIHRoaXMuZGF0YSA9IGRhdGE7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgPFIsIFA+IFIgYWNjZXB0KFN5bWJvbC5WaXNpdG9yPFIsIFA+IHYsIFAgcCkgewogICAgICAgICAgICByZXR1cm4gdi52aXNpdFZhclN5bWJvbCh0aGlzLCBwKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqIEEgY2xhc3MgZm9yIG1ldGhvZCBzeW1ib2xzLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIE1ldGhvZFN5bWJvbCBleHRlbmRzIFN5bWJvbCBpbXBsZW1lbnRzIEV4ZWN1dGFibGVFbGVtZW50IHsKCiAgICAgICAgLyoqIFRoZSBjb2RlIG9mIHRoZSBtZXRob2QuICovCiAgICAgICAgcHVibGljIENvZGUgY29kZSA9IG51bGw7CgogICAgICAgIC8qKiBUaGUgZXh0cmEgKHN5bnRoZXRpYy9tYW5kYXRlZCkgcGFyYW1ldGVycyBvZiB0aGUgbWV0aG9kLiAqLwogICAgICAgIHB1YmxpYyBMaXN0PFZhclN5bWJvbD4gZXh0cmFQYXJhbXMgPSBMaXN0Lm5pbCgpOwoKICAgICAgICAvKiogVGhlIGNhcHR1cmVkIGxvY2FsIHZhcmlhYmxlcyBpbiBhbiBhbm9ueW1vdXMgY2xhc3MgKi8KICAgICAgICBwdWJsaWMgTGlzdDxWYXJTeW1ib2w+IGNhcHR1cmVkTG9jYWxzID0gTGlzdC5uaWwoKTsKCiAgICAgICAgLyoqIFRoZSBwYXJhbWV0ZXJzIG9mIHRoZSBtZXRob2QuICovCiAgICAgICAgcHVibGljIExpc3Q8VmFyU3ltYm9sPiBwYXJhbXMgPSBudWxsOwoKICAgICAgICAvKiogVGhlIG5hbWVzIG9mIHRoZSBwYXJhbWV0ZXJzICovCiAgICAgICAgcHVibGljIExpc3Q8TmFtZT4gc2F2ZWRQYXJhbWV0ZXJOYW1lczsKCiAgICAgICAgLyoqIEZvciBhbiBhbm5vdGF0aW9uIHR5cGUgZWxlbWVudCwgaXRzIGRlZmF1bHQgdmFsdWUgaWYgYW55LgogICAgICAgICAqICBUaGUgdmFsdWUgaXMgbnVsbCBpZiBub25lIGFwcGVhcmVkIGluIHRoZSBtZXRob2QKICAgICAgICAgKiAgZGVjbGFyYXRpb24uCiAgICAgICAgICovCiAgICAgICAgcHVibGljIEF0dHJpYnV0ZSBkZWZhdWx0VmFsdWUgPSBudWxsOwoKICAgICAgICAvKiogQ29uc3RydWN0IGEgbWV0aG9kIHN5bWJvbCwgZ2l2ZW4gaXRzIGZsYWdzLCBuYW1lLCB0eXBlIGFuZCBvd25lci4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgTWV0aG9kU3ltYm9sKGxvbmcgZmxhZ3MsIE5hbWUgbmFtZSwgVHlwZSB0eXBlLCBTeW1ib2wgb3duZXIpIHsKICAgICAgICAgICAgc3VwZXIoTVRILCBmbGFncywgbmFtZSwgdHlwZSwgb3duZXIpOwogICAgICAgICAgICBpZiAob3duZXIudHlwZS5oYXNUYWcoVFlQRVZBUikpIEFzc2VydC5lcnJvcihvd25lciArICIuIiArIG5hbWUpOwogICAgICAgIH0KCiAgICAgICAgLyoqIENsb25lIHRoaXMgc3ltYm9sIHdpdGggbmV3IG93bmVyLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBNZXRob2RTeW1ib2wgY2xvbmUoU3ltYm9sIG5ld093bmVyKSB7CiAgICAgICAgICAgIE1ldGhvZFN5bWJvbCBtID0gbmV3IE1ldGhvZFN5bWJvbChmbGFnc19maWVsZCwgbmFtZSwgdHlwZSwgbmV3T3duZXIpIHsKICAgICAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICAgICAgcHVibGljIFN5bWJvbCBiYXNlU3ltYm9sKCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBNZXRob2RTeW1ib2wudGhpczsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKICAgICAgICAgICAgbS5jb2RlID0gY29kZTsKICAgICAgICAgICAgcmV0dXJuIG07CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICAgICAgcHVibGljIFNldDxNb2RpZmllcj4gZ2V0TW9kaWZpZXJzKCkgewogICAgICAgICAgICBsb25nIGZsYWdzID0gZmxhZ3MoKTsKICAgICAgICAgICAgcmV0dXJuIEZsYWdzLmFzTW9kaWZpZXJTZXQoKGZsYWdzICYgREVGQVVMVCkgIT0gMCA/IGZsYWdzICYgfkFCU1RSQUNUIDogZmxhZ3MpOwogICAgICAgIH0KCiAgICAgICAgLyoqIFRoZSBKYXZhIHNvdXJjZSB3aGljaCB0aGlzIHN5bWJvbCByZXByZXNlbnRzLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CiAgICAgICAgICAgIGlmICgoZmxhZ3MoKSAmIEJMT0NLKSAhPSAwKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gb3duZXIubmFtZS50b1N0cmluZygpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgU3RyaW5nIHMgPSAobmFtZSA9PSBuYW1lLnRhYmxlLm5hbWVzLmluaXQpCiAgICAgICAgICAgICAgICAgICAgPyBvd25lci5uYW1lLnRvU3RyaW5nKCkKICAgICAgICAgICAgICAgICAgICA6IG5hbWUudG9TdHJpbmcoKTsKICAgICAgICAgICAgICAgIGlmICh0eXBlICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICBpZiAodHlwZS5oYXNUYWcoRk9SQUxMKSkKICAgICAgICAgICAgICAgICAgICAgICAgcyA9ICI8IiArICgoRm9yQWxsKXR5cGUpLmdldFR5cGVBcmd1bWVudHMoKSArICI+IiArIHM7CiAgICAgICAgICAgICAgICAgICAgcyArPSAiKCIgKyB0eXBlLmFyZ3R5cGVzKChmbGFncygpICYgVkFSQVJHUykgIT0gMCkgKyAiKSI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gczsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHVibGljIGJvb2xlYW4gaXNEeW5hbWljKCkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICAvKiogZmluZCBhIHN5bWJvbCB0aGF0IHRoaXMgKHByb3h5IG1ldGhvZCkgc3ltYm9sIGltcGxlbWVudHMuCiAgICAgICAgICogIEBwYXJhbSAgICBjICAgICAgIFRoZSBjbGFzcyB3aG9zZSBtZW1iZXJzIGFyZSBzZWFyY2hlZCBmb3IKICAgICAgICAgKiAgICAgICAgICAgICAgICAgICAgaW1wbGVtZW50YXRpb25zCiAgICAgICAgICovCiAgICAgICAgcHVibGljIFN5bWJvbCBpbXBsZW1lbnRlZChUeXBlU3ltYm9sIGMsIFR5cGVzIHR5cGVzKSB7CiAgICAgICAgICAgIFN5bWJvbCBpbXBsID0gbnVsbDsKICAgICAgICAgICAgZm9yIChMaXN0PFR5cGU+IGlzID0gdHlwZXMuaW50ZXJmYWNlcyhjLnR5cGUpOwogICAgICAgICAgICAgICAgIGltcGwgPT0gbnVsbCAmJiBpcy5ub25FbXB0eSgpOwogICAgICAgICAgICAgICAgIGlzID0gaXMudGFpbCkgewogICAgICAgICAgICAgICAgVHlwZVN5bWJvbCBpID0gaXMuaGVhZC50c3ltOwogICAgICAgICAgICAgICAgaW1wbCA9IGltcGxlbWVudGVkSW4oaSwgdHlwZXMpOwogICAgICAgICAgICAgICAgaWYgKGltcGwgPT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICBpbXBsID0gaW1wbGVtZW50ZWQoaSwgdHlwZXMpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBpbXBsOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIFN5bWJvbCBpbXBsZW1lbnRlZEluKFR5cGVTeW1ib2wgYywgVHlwZXMgdHlwZXMpIHsKICAgICAgICAgICAgU3ltYm9sIGltcGwgPSBudWxsOwogICAgICAgICAgICBmb3IgKFN5bWJvbCBzeW0gOiBjLm1lbWJlcnMoKS5nZXRTeW1ib2xzQnlOYW1lKG5hbWUpKSB7CiAgICAgICAgICAgICAgICBpZiAodGhpcy5vdmVycmlkZXMoc3ltLCAoVHlwZVN5bWJvbClvd25lciwgdHlwZXMsIHRydWUpICYmCiAgICAgICAgICAgICAgICAgICAgLy8gRklYTUU6IEkgc3VzcGVjdCB0aGUgZm9sbG93aW5nIHJlcXVpcmVzIGEKICAgICAgICAgICAgICAgICAgICAvLyBzdWJzdCgpIGZvciBhIHBhcmFtZXRyaWMgcmV0dXJuIHR5cGUuCiAgICAgICAgICAgICAgICAgICAgdHlwZXMuaXNTYW1lVHlwZSh0eXBlLmdldFJldHVyblR5cGUoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVzLm1lbWJlclR5cGUob3duZXIudHlwZSwgc3ltKS5nZXRSZXR1cm5UeXBlKCkpKSB7CiAgICAgICAgICAgICAgICAgICAgaW1wbCA9IHN5bTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gaW1wbDsKICAgICAgICB9CgogICAgICAgIC8qKiBXaWxsIHRoZSBlcmFzdXJlIG9mIHRoaXMgbWV0aG9kIGJlIGNvbnNpZGVyZWQgYnkgdGhlIFZNIHRvCiAgICAgICAgICogIG92ZXJyaWRlIHRoZSBlcmFzdXJlIG9mIHRoZSBvdGhlciB3aGVuIHNlZW4gZnJvbSBjbGFzcyBgb3JpZ2luJz8KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgYm9vbGVhbiBiaW5hcnlPdmVycmlkZXMoU3ltYm9sIF9vdGhlciwgVHlwZVN5bWJvbCBvcmlnaW4sIFR5cGVzIHR5cGVzKSB7CiAgICAgICAgICAgIGlmIChpc0NvbnN0cnVjdG9yKCkgfHwgX290aGVyLmtpbmQgIT0gTVRIKSByZXR1cm4gZmFsc2U7CgogICAgICAgICAgICBpZiAodGhpcyA9PSBfb3RoZXIpIHJldHVybiB0cnVlOwogICAgICAgICAgICBNZXRob2RTeW1ib2wgb3RoZXIgPSAoTWV0aG9kU3ltYm9sKV9vdGhlcjsKCiAgICAgICAgICAgIC8vIGNoZWNrIGZvciBhIGRpcmVjdCBpbXBsZW1lbnRhdGlvbgogICAgICAgICAgICBpZiAob3RoZXIuaXNPdmVycmlkYWJsZUluKChUeXBlU3ltYm9sKW93bmVyKSAmJgogICAgICAgICAgICAgICAgdHlwZXMuYXNTdXBlcihvd25lci50eXBlLCBvdGhlci5vd25lcikgIT0gbnVsbCAmJgogICAgICAgICAgICAgICAgdHlwZXMuaXNTYW1lVHlwZShlcmFzdXJlKHR5cGVzKSwgb3RoZXIuZXJhc3VyZSh0eXBlcykpKQogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CgogICAgICAgICAgICAvLyBjaGVjayBmb3IgYW4gaW5oZXJpdGVkIGltcGxlbWVudGF0aW9uCiAgICAgICAgICAgIHJldHVybgogICAgICAgICAgICAgICAgKGZsYWdzKCkgJiBBQlNUUkFDVCkgPT0gMCAmJgogICAgICAgICAgICAgICAgb3RoZXIuaXNPdmVycmlkYWJsZUluKG9yaWdpbikgJiYKICAgICAgICAgICAgICAgIHRoaXMuaXNNZW1iZXJPZihvcmlnaW4sIHR5cGVzKSAmJgogICAgICAgICAgICAgICAgdHlwZXMuaXNTYW1lVHlwZShlcmFzdXJlKHR5cGVzKSwgb3RoZXIuZXJhc3VyZSh0eXBlcykpOwogICAgICAgIH0KCiAgICAgICAgLyoqIFRoZSBpbXBsZW1lbnRhdGlvbiBvZiB0aGlzIChhYnN0cmFjdCkgc3ltYm9sIGluIGNsYXNzIG9yaWdpbiwKICAgICAgICAgKiAgZnJvbSB0aGUgVk0ncyBwb2ludCBvZiB2aWV3LCBudWxsIGlmIG1ldGhvZCBkb2VzIG5vdCBoYXZlIGFuCiAgICAgICAgICogIGltcGxlbWVudGF0aW9uIGluIGNsYXNzLgogICAgICAgICAqICBAcGFyYW0gb3JpZ2luICAgVGhlIGNsYXNzIG9mIHdoaWNoIHRoZSBpbXBsZW1lbnRhdGlvbiBpcyBhIG1lbWJlci4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgTWV0aG9kU3ltYm9sIGJpbmFyeUltcGxlbWVudGF0aW9uKENsYXNzU3ltYm9sIG9yaWdpbiwgVHlwZXMgdHlwZXMpIHsKICAgICAgICAgICAgZm9yIChUeXBlU3ltYm9sIGMgPSBvcmlnaW47IGMgIT0gbnVsbDsgYyA9IHR5cGVzLnN1cGVydHlwZShjLnR5cGUpLnRzeW0pIHsKICAgICAgICAgICAgICAgIGZvciAoU3ltYm9sIHN5bSA6IGMubWVtYmVycygpLmdldFN5bWJvbHNCeU5hbWUobmFtZSkpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoc3ltLmtpbmQgPT0gTVRIICYmCiAgICAgICAgICAgICAgICAgICAgICAgICgoTWV0aG9kU3ltYm9sKXN5bSkuYmluYXJ5T3ZlcnJpZGVzKHRoaXMsIG9yaWdpbiwgdHlwZXMpKQogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKE1ldGhvZFN5bWJvbClzeW07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICAvKiogRG9lcyB0aGlzIHN5bWJvbCBvdmVycmlkZSBgb3RoZXInIHN5bWJvbCwgd2hlbiBib3RoIGFyZSBzZWVuIGFzCiAgICAgICAgICogIG1lbWJlcnMgb2YgY2xhc3MgYG9yaWdpbic/ICBJdCBpcyBhc3N1bWVkIHRoYXQgX290aGVyIGlzIGEgbWVtYmVyCiAgICAgICAgICogIG9mIG9yaWdpbi4KICAgICAgICAgKgogICAgICAgICAqICBJdCBpcyBhc3N1bWVkIHRoYXQgYm90aCBzeW1ib2xzIGhhdmUgdGhlIHNhbWUgbmFtZS4gIFRoZSBzdGF0aWMKICAgICAgICAgKiAgbW9kaWZpZXIgaXMgaWdub3JlZCBmb3IgdGhpcyB0ZXN0LgogICAgICAgICAqCiAgICAgICAgICogIEEgcXVpcmsgaW4gdGhlIHdvcmtzIGlzIHRoYXQgaWYgdGhlIHJlY2VpdmVyIGlzIGEgbWV0aG9kIHN5bWJvbCBmb3IKICAgICAgICAgKiAgYW4gaW5oZXJpdGVkIGFic3RyYWN0IG1ldGhvZCB3ZSBhbnN3ZXIgZmFsc2Ugc3VtbWFyaWx5IGFsbCBlbHNlIGJlaW5nCiAgICAgICAgICogIGltbWF0ZXJpYWwuIEFic3RyYWN0ICJvd24iIG1ldGhvZHMgKGkuZSBgdGhpcycgaXMgYSBkaXJlY3QgbWVtYmVyIG9mCiAgICAgICAgICogIG9yaWdpbikgZG9uJ3QgZ2V0IHJlamVjdGVkIGFzIHN1bW1hcmlseSBhbmQgYXJlIHB1dCB0byB0ZXN0IGFnYWluc3QgdGhlCiAgICAgICAgICogIHN1aXRhYmxlIGNyaXRlcmlhLgogICAgICAgICAqCiAgICAgICAgICogIFNlZSBKTFMgOC40LjYuMSAod2l0aG91dCB0cmFuc2l0aXZpdHkpIGFuZCA4LjQuNi40CiAgICAgICAgICovCiAgICAgICAgcHVibGljIGJvb2xlYW4gb3ZlcnJpZGVzKFN5bWJvbCBfb3RoZXIsIFR5cGVTeW1ib2wgb3JpZ2luLCBUeXBlcyB0eXBlcywgYm9vbGVhbiBjaGVja1Jlc3VsdCkgewogICAgICAgICAgICByZXR1cm4gb3ZlcnJpZGVzKF9vdGhlciwgb3JpZ2luLCB0eXBlcywgY2hlY2tSZXN1bHQsIHRydWUpOwogICAgICAgIH0KCiAgICAgICAgLyoqIERvZXMgdGhpcyBzeW1ib2wgb3ZlcnJpZGUgYG90aGVyJyBzeW1ib2wsIHdoZW4gYm90aCBhcmUgc2VlbiBhcwogICAgICAgICAqICBtZW1iZXJzIG9mIGNsYXNzIGBvcmlnaW4nPyAgSXQgaXMgYXNzdW1lZCB0aGF0IF9vdGhlciBpcyBhIG1lbWJlcgogICAgICAgICAqICBvZiBvcmlnaW4uCiAgICAgICAgICoKICAgICAgICAgKiAgQ2F2ZWF0OiBJZiBgdGhpcycgaXMgYW4gYWJzdHJhY3QgaW5oZXJpdGVkIG1lbWJlciBvZiBvcmlnaW4sIGl0IGlzCiAgICAgICAgICogIGRlZW1lZCB0byBvdmVycmlkZSBgb3RoZXInIG9ubHkgd2hlbiBgcmVxdWlyZUNvbmNyZXRlSWZJbmhlcml0ZWQnCiAgICAgICAgICogIGlzIGZhbHNlLgogICAgICAgICAqCiAgICAgICAgICogIEl0IGlzIGFzc3VtZWQgdGhhdCBib3RoIHN5bWJvbHMgaGF2ZSB0aGUgc2FtZSBuYW1lLiAgVGhlIHN0YXRpYwogICAgICAgICAqICBtb2RpZmllciBpcyBpZ25vcmVkIGZvciB0aGlzIHRlc3QuCiAgICAgICAgICoKICAgICAgICAgKiAgU2VlIEpMUyA4LjQuNi4xICh3aXRob3V0IHRyYW5zaXRpdml0eSkgYW5kIDguNC42LjQKICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgYm9vbGVhbiBvdmVycmlkZXMoU3ltYm9sIF9vdGhlciwgVHlwZVN5bWJvbCBvcmlnaW4sIFR5cGVzIHR5cGVzLCBib29sZWFuIGNoZWNrUmVzdWx0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gcmVxdWlyZUNvbmNyZXRlSWZJbmhlcml0ZWQpIHsKICAgICAgICAgICAgaWYgKGlzQ29uc3RydWN0b3IoKSB8fCBfb3RoZXIua2luZCAhPSBNVEgpIHJldHVybiBmYWxzZTsKCiAgICAgICAgICAgIGlmICh0aGlzID09IF9vdGhlcikgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIE1ldGhvZFN5bWJvbCBvdGhlciA9IChNZXRob2RTeW1ib2wpX290aGVyOwoKICAgICAgICAgICAgLy8gY2hlY2sgZm9yIGEgZGlyZWN0IGltcGxlbWVudGF0aW9uCiAgICAgICAgICAgIGlmIChvdGhlci5pc092ZXJyaWRhYmxlSW4oKFR5cGVTeW1ib2wpb3duZXIpICYmCiAgICAgICAgICAgICAgICB0eXBlcy5hc1N1cGVyKG93bmVyLnR5cGUsIG90aGVyLm93bmVyKSAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICBUeXBlIG10ID0gdHlwZXMubWVtYmVyVHlwZShvd25lci50eXBlLCB0aGlzKTsKICAgICAgICAgICAgICAgIFR5cGUgb3QgPSB0eXBlcy5tZW1iZXJUeXBlKG93bmVyLnR5cGUsIG90aGVyKTsKICAgICAgICAgICAgICAgIGlmICh0eXBlcy5pc1N1YlNpZ25hdHVyZShtdCwgb3QpKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCFjaGVja1Jlc3VsdCkKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVzLnJldHVyblR5cGVTdWJzdGl0dXRhYmxlKG10LCBvdCkpCiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBjaGVjayBmb3IgYW4gaW5oZXJpdGVkIGltcGxlbWVudGF0aW9uCiAgICAgICAgICAgIGlmICgoKGZsYWdzKCkgJiBBQlNUUkFDVCkgIT0gMCAmJiByZXF1aXJlQ29uY3JldGVJZkluaGVyaXRlZCkgfHwKICAgICAgICAgICAgICAgICAgICAoKG90aGVyLmZsYWdzKCkgJiBBQlNUUkFDVCkgPT0gMCAmJiAob3RoZXIuZmxhZ3MoKSAmIERFRkFVTFQpID09IDApIHx8CiAgICAgICAgICAgICAgICAgICAgIW90aGVyLmlzT3ZlcnJpZGFibGVJbihvcmlnaW4pIHx8CiAgICAgICAgICAgICAgICAgICAgIXRoaXMuaXNNZW1iZXJPZihvcmlnaW4sIHR5cGVzKSkKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKCiAgICAgICAgICAgIC8vIGFzc2VydCB0eXBlcy5hc1N1cGVyKG9yaWdpbi50eXBlLCBvdGhlci5vd25lcikgIT0gbnVsbDsKICAgICAgICAgICAgVHlwZSBtdCA9IHR5cGVzLm1lbWJlclR5cGUob3JpZ2luLnR5cGUsIHRoaXMpOwogICAgICAgICAgICBUeXBlIG90ID0gdHlwZXMubWVtYmVyVHlwZShvcmlnaW4udHlwZSwgb3RoZXIpOwogICAgICAgICAgICByZXR1cm4KICAgICAgICAgICAgICAgIHR5cGVzLmlzU3ViU2lnbmF0dXJlKG10LCBvdCkgJiYKICAgICAgICAgICAgICAgICghY2hlY2tSZXN1bHQgfHwgdHlwZXMucmVzdWx0U3VidHlwZShtdCwgb3QsIHR5cGVzLm5vV2FybmluZ3MpKTsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgYm9vbGVhbiBpc092ZXJyaWRhYmxlSW4oVHlwZVN5bWJvbCBvcmlnaW4pIHsKICAgICAgICAgICAgLy8gSkxTIDguNC42LjEKICAgICAgICAgICAgc3dpdGNoICgoaW50KShmbGFnc19maWVsZCAmIEZsYWdzLkFjY2Vzc0ZsYWdzKSkgewogICAgICAgICAgICBjYXNlIEZsYWdzLlBSSVZBVEU6CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIGNhc2UgRmxhZ3MuUFVCTElDOgogICAgICAgICAgICAgICAgcmV0dXJuICF0aGlzLm93bmVyLmlzSW50ZXJmYWNlKCkgfHwKICAgICAgICAgICAgICAgICAgICAgICAgKGZsYWdzX2ZpZWxkICYgU1RBVElDKSA9PSAwOwogICAgICAgICAgICBjYXNlIEZsYWdzLlBST1RFQ1RFRDoKICAgICAgICAgICAgICAgIHJldHVybiAob3JpZ2luLmZsYWdzKCkgJiBJTlRFUkZBQ0UpID09IDA7CiAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIC8vIGZvciBwYWNrYWdlIHByaXZhdGU6IGNhbiBvbmx5IG92ZXJyaWRlIGluIHRoZSBzYW1lCiAgICAgICAgICAgICAgICAvLyBwYWNrYWdlCiAgICAgICAgICAgICAgICByZXR1cm4KICAgICAgICAgICAgICAgICAgICB0aGlzLnBhY2tnZSgpID09IG9yaWdpbi5wYWNrZ2UoKSAmJgogICAgICAgICAgICAgICAgICAgIChvcmlnaW4uZmxhZ3MoKSAmIElOVEVSRkFDRSkgPT0gMDsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gaXNJbmhlcml0ZWRJbihTeW1ib2wgY2xhenosIFR5cGVzIHR5cGVzKSB7CiAgICAgICAgICAgIHN3aXRjaCAoKGludCkoZmxhZ3NfZmllbGQgJiBGbGFncy5BY2Nlc3NGbGFncykpIHsKICAgICAgICAgICAgICAgIGNhc2UgUFVCTElDOgogICAgICAgICAgICAgICAgICAgIHJldHVybiAhdGhpcy5vd25lci5pc0ludGVyZmFjZSgpIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGF6eiA9PSBvd25lciB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKGZsYWdzX2ZpZWxkICYgU1RBVElDKSA9PSAwOwogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3VwZXIuaXNJbmhlcml0ZWRJbihjbGF6eiwgdHlwZXMpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc0xhbWJkYU1ldGhvZCgpIHsKICAgICAgICAgICAgcmV0dXJuIChmbGFncygpICYgTEFNQkRBX01FVEhPRCkgPT0gTEFNQkRBX01FVEhPRDsKICAgICAgICB9CgogICAgICAgIC8qKiBUaGUgaW1wbGVtZW50YXRpb24gb2YgdGhpcyAoYWJzdHJhY3QpIHN5bWJvbCBpbiBjbGFzcyBvcmlnaW47CiAgICAgICAgICogIG51bGwgaWYgbm9uZSBleGlzdHMuIFN5bnRoZXRpYyBtZXRob2RzIGFyZSBub3QgY29uc2lkZXJlZAogICAgICAgICAqICBhcyBwb3NzaWJsZSBpbXBsZW1lbnRhdGlvbnMuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIE1ldGhvZFN5bWJvbCBpbXBsZW1lbnRhdGlvbihUeXBlU3ltYm9sIG9yaWdpbiwgVHlwZXMgdHlwZXMsIGJvb2xlYW4gY2hlY2tSZXN1bHQpIHsKICAgICAgICAgICAgcmV0dXJuIGltcGxlbWVudGF0aW9uKG9yaWdpbiwgdHlwZXMsIGNoZWNrUmVzdWx0LCBpbXBsZW1lbnRhdGlvbl9maWx0ZXIpOwogICAgICAgIH0KICAgICAgICAvLyB3aGVyZQogICAgICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIEZpbHRlcjxTeW1ib2w+IGltcGxlbWVudGF0aW9uX2ZpbHRlciA9IHMgLT4KICAgICAgICAgICAgICAgICAgICBzLmtpbmQgPT0gTVRIICYmIChzLmZsYWdzKCkgJiBTWU5USEVUSUMpID09IDA7CgogICAgICAgIHB1YmxpYyBNZXRob2RTeW1ib2wgaW1wbGVtZW50YXRpb24oVHlwZVN5bWJvbCBvcmlnaW4sIFR5cGVzIHR5cGVzLCBib29sZWFuIGNoZWNrUmVzdWx0LCBGaWx0ZXI8U3ltYm9sPiBpbXBsRmlsdGVyKSB7CiAgICAgICAgICAgIE1ldGhvZFN5bWJvbCByZXMgPSB0eXBlcy5pbXBsZW1lbnRhdGlvbih0aGlzLCBvcmlnaW4sIGNoZWNrUmVzdWx0LCBpbXBsRmlsdGVyKTsKICAgICAgICAgICAgaWYgKHJlcyAhPSBudWxsKQogICAgICAgICAgICAgICAgcmV0dXJuIHJlczsKICAgICAgICAgICAgLy8gaWYgb3JpZ2luIGlzIGRlcml2ZWQgZnJvbSBhIHJhdyB0eXBlLCB3ZSBtaWdodCBoYXZlIG1pc3NlZAogICAgICAgICAgICAvLyBhbiBpbXBsZW1lbnRhdGlvbiBiZWNhdXNlIHdlIGRvIG5vdCBrbm93IGVub3VnaCBhYm91dCBpbnN0YW50aWF0aW9ucy4KICAgICAgICAgICAgLy8gaW4gdGhpcyBjYXNlIGNvbnRpbnVlIHdpdGggdGhlIHN1cGVydHlwZSBhcyBvcmlnaW4uCiAgICAgICAgICAgIGlmICh0eXBlcy5pc0Rlcml2ZWRSYXcob3JpZ2luLnR5cGUpICYmICFvcmlnaW4uaXNJbnRlcmZhY2UoKSkKICAgICAgICAgICAgICAgIHJldHVybiBpbXBsZW1lbnRhdGlvbih0eXBlcy5zdXBlcnR5cGUob3JpZ2luLnR5cGUpLnRzeW0sIHR5cGVzLCBjaGVja1Jlc3VsdCk7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIExpc3Q8VmFyU3ltYm9sPiBwYXJhbXMoKSB7CiAgICAgICAgICAgIG93bmVyLmNvbXBsZXRlKCk7CiAgICAgICAgICAgIGlmIChwYXJhbXMgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgLy8gSWYgQ2xhc3NSZWFkZXIuc2F2ZVBhcmFtZXRlck5hbWVzIGhhcyBiZWVuIHNldCB0cnVlLCB0aGVuCiAgICAgICAgICAgICAgICAvLyBzYXZlZFBhcmFtZXRlck5hbWVzIHdpbGwgYmUgc2V0IHRvIGEgbGlzdCBvZiBuYW1lcyB0aGF0CiAgICAgICAgICAgICAgICAvLyBtYXRjaGVzIHRoZSB0eXBlcyBpbiB0eXBlLmdldFBhcmFtZXRlclR5cGVzKCkuICBJZiBhbnkgbmFtZXMKICAgICAgICAgICAgICAgIC8vIHdlcmUgbm90IGZvdW5kIGluIHRoZSBjbGFzcyBmaWxlLCB0aG9zZSBuYW1lcyBpbiB0aGUgbGlzdCB3aWxsCiAgICAgICAgICAgICAgICAvLyBiZSBzZXQgdG8gdGhlIGVtcHR5IG5hbWUuCiAgICAgICAgICAgICAgICAvLyBJZiBDbGFzc1JlYWRlci5zYXZlUGFyYW1ldGVyTmFtZXMgaGFzIGJlZW4gc2V0IGZhbHNlLCB0aGVuCiAgICAgICAgICAgICAgICAvLyBzYXZlZFBhcmFtZXRlck5hbWVzIHdpbGwgYmUgbnVsbC4KICAgICAgICAgICAgICAgIExpc3Q8TmFtZT4gcGFyYW1OYW1lcyA9IHNhdmVkUGFyYW1ldGVyTmFtZXM7CiAgICAgICAgICAgICAgICBzYXZlZFBhcmFtZXRlck5hbWVzID0gbnVsbDsKICAgICAgICAgICAgICAgIC8vIGRpc2NhcmQgdGhlIHByb3ZpZGVkIG5hbWVzIGlmIHRoZSBsaXN0IG9mIG5hbWVzIGlzIHRoZSB3cm9uZyBzaXplLgogICAgICAgICAgICAgICAgaWYgKHBhcmFtTmFtZXMgPT0gbnVsbCB8fCBwYXJhbU5hbWVzLnNpemUoKSAhPSB0eXBlLmdldFBhcmFtZXRlclR5cGVzKCkuc2l6ZSgpKSB7CiAgICAgICAgICAgICAgICAgICAgcGFyYW1OYW1lcyA9IExpc3QubmlsKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBMaXN0QnVmZmVyPFZhclN5bWJvbD4gYnVmID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgICAgICAgICAgTGlzdDxOYW1lPiByZW1haW5pbmcgPSBwYXJhbU5hbWVzOwogICAgICAgICAgICAgICAgLy8gYXNzZXJ0OiByZW1haW5pbmcgYW5kIHBhcmFtTmFtZXMgYXJlIGJvdGggZW1wdHkgb3IgYm90aAogICAgICAgICAgICAgICAgLy8gaGF2ZSBzYW1lIGNhcmRpbmFsaXR5IGFzIHR5cGUuZ2V0UGFyYW1ldGVyVHlwZXMoKQogICAgICAgICAgICAgICAgaW50IGkgPSAwOwogICAgICAgICAgICAgICAgZm9yIChUeXBlIHQgOiB0eXBlLmdldFBhcmFtZXRlclR5cGVzKCkpIHsKICAgICAgICAgICAgICAgICAgICBOYW1lIHBhcmFtTmFtZTsKICAgICAgICAgICAgICAgICAgICBpZiAocmVtYWluaW5nLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBubyBuYW1lcyBmb3IgYW55IHBhcmFtZXRlcnMgYXZhaWxhYmxlCiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtTmFtZSA9IGNyZWF0ZUFyZ05hbWUoaSwgcGFyYW1OYW1lcyk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgcGFyYW1OYW1lID0gcmVtYWluaW5nLmhlYWQ7CiAgICAgICAgICAgICAgICAgICAgICAgIHJlbWFpbmluZyA9IHJlbWFpbmluZy50YWlsOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAocGFyYW1OYW1lLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbm8gbmFtZSBmb3IgdGhpcyBzcGVjaWZpYyBwYXJhbWV0ZXIKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtTmFtZSA9IGNyZWF0ZUFyZ05hbWUoaSwgcGFyYW1OYW1lcyk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnVmLmFwcGVuZChuZXcgVmFyU3ltYm9sKFBBUkFNRVRFUiwgcGFyYW1OYW1lLCB0LCB0aGlzKSk7CiAgICAgICAgICAgICAgICAgICAgaSsrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcGFyYW1zID0gYnVmLnRvTGlzdCgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBwYXJhbXM7CiAgICAgICAgfQoKICAgICAgICAvLyBDcmVhdGUgYSBuYW1lIGZvciB0aGUgYXJndW1lbnQgYXQgcG9zaXRpb24gJ2luZGV4JyB0aGF0IGlzIG5vdCBpbgogICAgICAgIC8vIHRoZSBleGNsdWRlIGxpc3QuIEluIG5vcm1hbCB1c2UsIGVpdGhlciBubyBuYW1lcyB3aWxsIGhhdmUgYmVlbgogICAgICAgIC8vIHByb3ZpZGVkLCBpbiB3aGljaCBjYXNlIHRoZSBleGNsdWRlIGxpc3QgaXMgZW1wdHksIG9yIGFsbCB0aGUgbmFtZXMKICAgICAgICAvLyB3aWxsIGhhdmUgYmVlbiBwcm92aWRlZCwgaW4gd2hpY2ggY2FzZSB0aGlzIG1ldGhvZCB3aWxsIG5vdCBiZSBjYWxsZWQuCiAgICAgICAgcHJpdmF0ZSBOYW1lIGNyZWF0ZUFyZ05hbWUoaW50IGluZGV4LCBMaXN0PE5hbWU+IGV4Y2x1ZGUpIHsKICAgICAgICAgICAgU3RyaW5nIHByZWZpeCA9ICJhcmciOwogICAgICAgICAgICB3aGlsZSAodHJ1ZSkgewogICAgICAgICAgICAgICAgTmFtZSBhcmdOYW1lID0gbmFtZS50YWJsZS5mcm9tU3RyaW5nKHByZWZpeCArIGluZGV4KTsKICAgICAgICAgICAgICAgIGlmICghZXhjbHVkZS5jb250YWlucyhhcmdOYW1lKSkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gYXJnTmFtZTsKICAgICAgICAgICAgICAgIHByZWZpeCArPSAiJCI7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHB1YmxpYyBTeW1ib2wgYXNNZW1iZXJPZihUeXBlIHNpdGUsIFR5cGVzIHR5cGVzKSB7CiAgICAgICAgICAgIHJldHVybiBuZXcgTWV0aG9kU3ltYm9sKGZsYWdzX2ZpZWxkLCBuYW1lLCB0eXBlcy5tZW1iZXJUeXBlKHNpdGUsIHRoaXMpLCBvd25lcik7CiAgICAgICAgfQoKICAgICAgICBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgICAgICBwdWJsaWMgRWxlbWVudEtpbmQgZ2V0S2luZCgpIHsKICAgICAgICAgICAgaWYgKG5hbWUgPT0gbmFtZS50YWJsZS5uYW1lcy5pbml0KQogICAgICAgICAgICAgICAgcmV0dXJuIEVsZW1lbnRLaW5kLkNPTlNUUlVDVE9SOwogICAgICAgICAgICBlbHNlIGlmIChuYW1lID09IG5hbWUudGFibGUubmFtZXMuY2xpbml0KQogICAgICAgICAgICAgICAgcmV0dXJuIEVsZW1lbnRLaW5kLlNUQVRJQ19JTklUOwogICAgICAgICAgICBlbHNlIGlmICgoZmxhZ3MoKSAmIEJMT0NLKSAhPSAwKQogICAgICAgICAgICAgICAgcmV0dXJuIGlzU3RhdGljKCkgPyBFbGVtZW50S2luZC5TVEFUSUNfSU5JVCA6IEVsZW1lbnRLaW5kLklOU1RBTkNFX0lOSVQ7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHJldHVybiBFbGVtZW50S2luZC5NRVRIT0Q7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc1N0YXRpY09ySW5zdGFuY2VJbml0KCkgewogICAgICAgICAgICByZXR1cm4gZ2V0S2luZCgpID09IEVsZW1lbnRLaW5kLlNUQVRJQ19JTklUIHx8CiAgICAgICAgICAgICAgICAgICAgZ2V0S2luZCgpID09IEVsZW1lbnRLaW5kLklOU1RBTkNFX0lOSVQ7CiAgICAgICAgfQoKICAgICAgICBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgICAgICBwdWJsaWMgQXR0cmlidXRlIGdldERlZmF1bHRWYWx1ZSgpIHsKICAgICAgICAgICAgcmV0dXJuIGRlZmF1bHRWYWx1ZTsKICAgICAgICB9CgogICAgICAgIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyBMaXN0PFZhclN5bWJvbD4gZ2V0UGFyYW1ldGVycygpIHsKICAgICAgICAgICAgcmV0dXJuIHBhcmFtcygpOwogICAgICAgIH0KCiAgICAgICAgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICAgICAgcHVibGljIGJvb2xlYW4gaXNWYXJBcmdzKCkgewogICAgICAgICAgICByZXR1cm4gKGZsYWdzKCkgJiBWQVJBUkdTKSAhPSAwOwogICAgICAgIH0KCiAgICAgICAgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICAgICAgcHVibGljIGJvb2xlYW4gaXNEZWZhdWx0KCkgewogICAgICAgICAgICByZXR1cm4gKGZsYWdzKCkgJiBERUZBVUxUKSAhPSAwOwogICAgICAgIH0KCiAgICAgICAgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICAgICAgcHVibGljIDxSLCBQPiBSIGFjY2VwdChFbGVtZW50VmlzaXRvcjxSLCBQPiB2LCBQIHApIHsKICAgICAgICAgICAgcmV0dXJuIHYudmlzaXRFeGVjdXRhYmxlKHRoaXMsIHApOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIDxSLCBQPiBSIGFjY2VwdChTeW1ib2wuVmlzaXRvcjxSLCBQPiB2LCBQIHApIHsKICAgICAgICAgICAgcmV0dXJuIHYudmlzaXRNZXRob2RTeW1ib2wodGhpcywgcCk7CiAgICAgICAgfQoKICAgICAgICBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgICAgICBwdWJsaWMgVHlwZSBnZXRSZWNlaXZlclR5cGUoKSB7CiAgICAgICAgICAgIHJldHVybiBhc1R5cGUoKS5nZXRSZWNlaXZlclR5cGUoKTsKICAgICAgICB9CgogICAgICAgIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyBUeXBlIGdldFJldHVyblR5cGUoKSB7CiAgICAgICAgICAgIHJldHVybiBhc1R5cGUoKS5nZXRSZXR1cm5UeXBlKCk7CiAgICAgICAgfQoKICAgICAgICBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgICAgICBwdWJsaWMgTGlzdDxUeXBlPiBnZXRUaHJvd25UeXBlcygpIHsKICAgICAgICAgICAgcmV0dXJuIGFzVHlwZSgpLmdldFRocm93blR5cGVzKCk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKiBBIGNsYXNzIGZvciBpbnZva2VkeW5hbWljIG1ldGhvZCBjYWxscy4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBjbGFzcyBEeW5hbWljTWV0aG9kU3ltYm9sIGV4dGVuZHMgTWV0aG9kU3ltYm9sIHsKCiAgICAgICAgcHVibGljIE9iamVjdFtdIHN0YXRpY0FyZ3M7CiAgICAgICAgcHVibGljIFN5bWJvbCBic207CiAgICAgICAgcHVibGljIGludCBic21LaW5kOwoKICAgICAgICBwdWJsaWMgRHluYW1pY01ldGhvZFN5bWJvbChOYW1lIG5hbWUsIFN5bWJvbCBvd25lciwgaW50IGJzbUtpbmQsIE1ldGhvZFN5bWJvbCBic20sIFR5cGUgdHlwZSwgT2JqZWN0W10gc3RhdGljQXJncykgewogICAgICAgICAgICBzdXBlcigwLCBuYW1lLCB0eXBlLCBvd25lcik7CiAgICAgICAgICAgIHRoaXMuYnNtID0gYnNtOwogICAgICAgICAgICB0aGlzLmJzbUtpbmQgPSBic21LaW5kOwogICAgICAgICAgICB0aGlzLnN0YXRpY0FyZ3MgPSBzdGF0aWNBcmdzOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gaXNEeW5hbWljKCkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICB9CgogICAgLyoqIEEgY2xhc3MgZm9yIHByZWRlZmluZWQgb3BlcmF0b3JzLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIE9wZXJhdG9yU3ltYm9sIGV4dGVuZHMgTWV0aG9kU3ltYm9sIHsKCiAgICAgICAgcHVibGljIGludCBvcGNvZGU7CiAgICAgICAgcHJpdmF0ZSBpbnQgYWNjZXNzQ29kZSA9IEludGVnZXIuTUlOX1ZBTFVFOwoKICAgICAgICBwdWJsaWMgT3BlcmF0b3JTeW1ib2woTmFtZSBuYW1lLCBUeXBlIHR5cGUsIGludCBvcGNvZGUsIFN5bWJvbCBvd25lcikgewogICAgICAgICAgICBzdXBlcihQVUJMSUMgfCBTVEFUSUMsIG5hbWUsIHR5cGUsIG93bmVyKTsKICAgICAgICAgICAgdGhpcy5vcGNvZGUgPSBvcGNvZGU7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgPFIsIFA+IFIgYWNjZXB0KFN5bWJvbC5WaXNpdG9yPFIsIFA+IHYsIFAgcCkgewogICAgICAgICAgICByZXR1cm4gdi52aXNpdE9wZXJhdG9yU3ltYm9sKHRoaXMsIHApOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIGludCBnZXRBY2Nlc3NDb2RlKFRhZyB0YWcpIHsKICAgICAgICAgICAgaWYgKGFjY2Vzc0NvZGUgIT0gSW50ZWdlci5NSU5fVkFMVUUgJiYgIXRhZy5pc0luY09yRGVjVW5hcnlPcCgpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gYWNjZXNzQ29kZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBhY2Nlc3NDb2RlID0gQWNjZXNzQ29kZS5mcm9tKHRhZywgb3Bjb2RlKTsKICAgICAgICAgICAgcmV0dXJuIGFjY2Vzc0NvZGU7CiAgICAgICAgfQoKICAgICAgICAvKiogQWNjZXNzIGNvZGVzIGZvciBkZXJlZmVyZW5jaW5nLCBhc3NpZ25tZW50LAogICAgICAgICAqICBhbmQgcHJlL3Bvc3QgaW5jcmVtZW50L2RlY3JlbWVudC4KCiAgICAgICAgICogIEFsbCBhY2Nlc3MgY29kZXMgZm9yIGFjY2Vzc2VzIHRvIHRoZSBjdXJyZW50IGNsYXNzIGFyZSBldmVuLgogICAgICAgICAqICBJZiBhIG1lbWJlciBvZiB0aGUgc3VwZXJjbGFzcyBzaG91bGQgYmUgYWNjZXNzZWQgaW5zdGVhZCAoYmVjYXVzZQogICAgICAgICAqICBhY2Nlc3Mgd2FzIHZpYSBhIHF1YWxpZmllZCBzdXBlciksIGFkZCBvbmUgdG8gdGhlIGNvcnJlc3BvbmRpbmcgY29kZQogICAgICAgICAqICBmb3IgdGhlIGN1cnJlbnQgY2xhc3MsIG1ha2luZyB0aGUgbnVtYmVyIG9kZC4KICAgICAgICAgKiAgVGhpcyBudW1iZXJpbmcgc2NoZW1lIGlzIHVzZWQgYnkgdGhlIGJhY2tlbmQgdG8gZGVjaWRlIHdoZXRoZXIKICAgICAgICAgKiAgdG8gaXNzdWUgYW4gaW52b2tldmlydHVhbCBvciBpbnZva2VzcGVjaWFsIGNhbGwuCiAgICAgICAgICoKICAgICAgICAgKiAgQHNlZSBHZW4jdmlzaXRTZWxlY3QoSkNGaWVsZEFjY2VzcyB0cmVlKQogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBlbnVtIEFjY2Vzc0NvZGUgewogICAgICAgICAgICBVTktOT1dOKC0xLCBUYWcuTk9fVEFHKSwKICAgICAgICAgICAgREVSRUYoMCwgVGFnLk5PX1RBRyksCiAgICAgICAgICAgIEFTU0lHTigyLCBUYWcuQVNTSUdOKSwKICAgICAgICAgICAgUFJFSU5DKDQsIFRhZy5QUkVJTkMpLAogICAgICAgICAgICBQUkVERUMoNiwgVGFnLlBSRURFQyksCiAgICAgICAgICAgIFBPU1RJTkMoOCwgVGFnLlBPU1RJTkMpLAogICAgICAgICAgICBQT1NUREVDKDEwLCBUYWcuUE9TVERFQyksCiAgICAgICAgICAgIEZJUlNUQVNHT1AoMTIsIFRhZy5OT19UQUcpOwoKICAgICAgICAgICAgcHVibGljIGZpbmFsIGludCBjb2RlOwogICAgICAgICAgICBwdWJsaWMgZmluYWwgVGFnIHRhZzsKICAgICAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgbnVtYmVyT2ZBY2Nlc3NDb2RlcyA9IChsdXNocmwgLSBpc2hsbCArIGx4b3IgKyAyIC0gaWFkZCkgKiAyICsgRklSU1RBU0dPUC5jb2RlICsgMjsKCiAgICAgICAgICAgIEFjY2Vzc0NvZGUoaW50IGNvZGUsIFRhZyB0YWcpIHsKICAgICAgICAgICAgICAgIHRoaXMuY29kZSA9IGNvZGU7CiAgICAgICAgICAgICAgICB0aGlzLnRhZyA9IHRhZzsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgc3RhdGljIHB1YmxpYyBBY2Nlc3NDb2RlIGdldEZyb21Db2RlKGludCBjb2RlKSB7CiAgICAgICAgICAgICAgICBmb3IgKEFjY2Vzc0NvZGUgYUNvZGVzIDogQWNjZXNzQ29kZS52YWx1ZXMoKSkgewogICAgICAgICAgICAgICAgICAgIGlmIChhQ29kZXMuY29kZSA9PSBjb2RlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBhQ29kZXM7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIFVOS05PV047CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHN0YXRpYyBpbnQgZnJvbShUYWcgdGFnLCBpbnQgb3Bjb2RlKSB7CiAgICAgICAgICAgICAgICAvKiogTWFwIGJ5dGVjb2RlIG9mIGJpbmFyeSBvcGVyYXRpb24gdG8gYWNjZXNzIGNvZGUgb2YgY29ycmVzcG9uZGluZwogICAgICAgICAgICAgICAgKiAgYXNzaWdubWVudCBvcGVyYXRpb24uIFRoaXMgaXMgYWx3YXlzIGFuIGV2ZW4gbnVtYmVyLgogICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBQUkVJTkM6CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBBY2Nlc3NDb2RlLlBSRUlOQy5jb2RlOwogICAgICAgICAgICAgICAgICAgIGNhc2UgUFJFREVDOgogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gQWNjZXNzQ29kZS5QUkVERUMuY29kZTsKICAgICAgICAgICAgICAgICAgICBjYXNlIFBPU1RJTkM6CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBBY2Nlc3NDb2RlLlBPU1RJTkMuY29kZTsKICAgICAgICAgICAgICAgICAgICBjYXNlIFBPU1RERUM6CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBBY2Nlc3NDb2RlLlBPU1RERUMuY29kZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChpYWRkIDw9IG9wY29kZSAmJiBvcGNvZGUgPD0gbHhvcikgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAob3Bjb2RlIC0gaWFkZCkgKiAyICsgRklSU1RBU0dPUC5jb2RlOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChvcGNvZGUgPT0gc3RyaW5nX2FkZCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAobHhvciArIDEgLSBpYWRkKSAqIDIgKyBGSVJTVEFTR09QLmNvZGU7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGlzaGxsIDw9IG9wY29kZSAmJiBvcGNvZGUgPD0gbHVzaHJsKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChvcGNvZGUgLSBpc2hsbCArIGx4b3IgKyAyIC0gaWFkZCkgKiAyICsgRklSU1RBU0dPUC5jb2RlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKiBTeW1ib2wgY29tcGxldGVyIGludGVyZmFjZS4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBpbnRlcmZhY2UgQ29tcGxldGVyIHsKCiAgICAgICAgLyoqIER1bW15IGNvbXBsZXRlciB0byBiZSB1c2VkIHdoZW4gdGhlIHN5bWJvbCBoYXMgYmVlbiBjb21wbGV0ZWQgb3IKICAgICAgICAgKiBkb2VzIG5vdCBuZWVkIGNvbXBsZXRpb24uCiAgICAgICAgICovCiAgICAgICAgcHVibGljIGZpbmFsIHN0YXRpYyBDb21wbGV0ZXIgTlVMTF9DT01QTEVURVIgPSBuZXcgQ29tcGxldGVyKCkgewogICAgICAgICAgICBwdWJsaWMgdm9pZCBjb21wbGV0ZShTeW1ib2wgc3ltKSB7IH0KICAgICAgICAgICAgcHVibGljIGJvb2xlYW4gaXNUZXJtaW5hbCgpIHsgcmV0dXJuIHRydWU7IH0KICAgICAgICB9OwoKICAgICAgICB2b2lkIGNvbXBsZXRlKFN5bWJvbCBzeW0pIHRocm93cyBDb21wbGV0aW9uRmFpbHVyZTsKCiAgICAgICAgLyoqIFJldHVybnMgdHJ1ZSBpZiB0aGlzIGNvbXBsZXRlciBpcyA8ZW0+dGVybWluYWw8L2VtPi4gQSB0ZXJtaW5hbAogICAgICAgICAqIGNvbXBsZXRlciBpcyB1c2VkIGFzIGEgcGxhY2UgaG9sZGVyIHdoZW4gdGhlIHN5bWJvbCBpcyBjb21wbGV0ZWQuCiAgICAgICAgICogQ2FsbGluZyBjb21wbGV0ZSBvbiBhIHRlcm1pbmFsIGNvbXBsZXRlciB3aWxsIG5vdCBhZmZlY3QgdGhlIHN5bWJvbC4KICAgICAgICAgKgogICAgICAgICAqIFRoZSBkdW1teSBOVUxMX0NPTVBMRVRFUiBhbmQgdGhlIEdyYXBoRGVwZW5kZW5jaWVzIGNvbXBsZXRlciBhcmUKICAgICAgICAgKiBleGFtcGxlcyBvZiB0ZXJtaW5hbCBjb21wbGV0ZXJzLgogICAgICAgICAqCiAgICAgICAgICogQHJldHVybiB0cnVlIGlmZiB0aGlzIGNvbXBsZXRlciBpcyB0ZXJtaW5hbAogICAgICAgICAqLwogICAgICAgIGRlZmF1bHQgYm9vbGVhbiBpc1Rlcm1pbmFsKCkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgQ29tcGxldGlvbkZhaWx1cmUgZXh0ZW5kcyBSdW50aW1lRXhjZXB0aW9uIHsKICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwOwogICAgICAgIHB1YmxpYyBTeW1ib2wgc3ltOwoKICAgICAgICAvKiogQSBkaWFnbm9zdGljIG9iamVjdCBkZXNjcmliaW5nIHRoZSBmYWlsdXJlCiAgICAgICAgICovCiAgICAgICAgcHVibGljIEpDRGlhZ25vc3RpYyBkaWFnOwoKICAgICAgICAvKiogQSBsb2NhbGl6ZWQgc3RyaW5nIGRlc2NyaWJpbmcgdGhlIGZhaWx1cmUuCiAgICAgICAgICogQGRlcHJlY2F0ZWQgVXNlIHtAY29kZSBnZXREZXRhaWwoKX0gb3Ige0Bjb2RlIGdldE1lc3NhZ2UoKX0KICAgICAgICAgKi8KICAgICAgICBARGVwcmVjYXRlZAogICAgICAgIHB1YmxpYyBTdHJpbmcgZXJybXNnOwoKICAgICAgICBwdWJsaWMgQ29tcGxldGlvbkZhaWx1cmUoU3ltYm9sIHN5bSwgU3RyaW5nIGVycm1zZykgewogICAgICAgICAgICB0aGlzLnN5bSA9IHN5bTsKICAgICAgICAgICAgdGhpcy5lcnJtc2cgPSBlcnJtc2c7Ci8vICAgICAgICAgIHRoaXMucHJpbnRTdGFja1RyYWNlKCk7Ly9ERUJVRwogICAgICAgIH0KCiAgICAgICAgcHVibGljIENvbXBsZXRpb25GYWlsdXJlKFN5bWJvbCBzeW0sIEpDRGlhZ25vc3RpYyBkaWFnKSB7CiAgICAgICAgICAgIHRoaXMuc3ltID0gc3ltOwogICAgICAgICAgICB0aGlzLmRpYWcgPSBkaWFnOwovLyAgICAgICAgICB0aGlzLnByaW50U3RhY2tUcmFjZSgpOy8vREVCVUcKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBKQ0RpYWdub3N0aWMgZ2V0RGlhZ25vc3RpYygpIHsKICAgICAgICAgICAgcmV0dXJuIGRpYWc7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgU3RyaW5nIGdldE1lc3NhZ2UoKSB7CiAgICAgICAgICAgIGlmIChkaWFnICE9IG51bGwpCiAgICAgICAgICAgICAgICByZXR1cm4gZGlhZy5nZXRNZXNzYWdlKG51bGwpOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICByZXR1cm4gZXJybXNnOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIE9iamVjdCBnZXREZXRhaWxWYWx1ZSgpIHsKICAgICAgICAgICAgcmV0dXJuIChkaWFnICE9IG51bGwgPyBkaWFnIDogZXJybXNnKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBDb21wbGV0aW9uRmFpbHVyZSBpbml0Q2F1c2UoVGhyb3dhYmxlIGNhdXNlKSB7CiAgICAgICAgICAgIHN1cGVyLmluaXRDYXVzZShjYXVzZSk7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICB9CgogICAgLyoqCiAgICAgKiBBIHZpc2l0b3IgZm9yIHN5bWJvbHMuICBBIHZpc2l0b3IgaXMgdXNlZCB0byBpbXBsZW1lbnQgb3BlcmF0aW9ucwogICAgICogKG9yIHJlbGF0aW9ucykgb24gc3ltYm9scy4gIE1vc3QgY29tbW9uIG9wZXJhdGlvbnMgb24gdHlwZXMgYXJlCiAgICAgKiBiaW5hcnkgcmVsYXRpb25zIGFuZCB0aGlzIGludGVyZmFjZSBpcyBkZXNpZ25lZCBmb3IgYmluYXJ5CiAgICAgKiByZWxhdGlvbnMsIHRoYXQgaXMsIG9wZXJhdGlvbnMgb24gdGhlIGZvcm0KICAgICAqIFN5bWJvbCZuYnNwOyZ0aW1lczsmbmJzcDtQJm5ic3A7JnJhcnI7Jm5ic3A7Ui4KICAgICAqIDwhLS0gSW4gcGxhaW4gdGV4dDogVHlwZSB4IFAgLT4gUiAtLT4KICAgICAqCiAgICAgKiBAcGFyYW0gPFI+IHRoZSByZXR1cm4gdHlwZSBvZiB0aGUgb3BlcmF0aW9uIGltcGxlbWVudGVkIGJ5IHRoaXMKICAgICAqIHZpc2l0b3I7IHVzZSBWb2lkIGlmIG5vIHJldHVybiB0eXBlIGlzIG5lZWRlZC4KICAgICAqIEBwYXJhbSA8UD4gdGhlIHR5cGUgb2YgdGhlIHNlY29uZCBhcmd1bWVudCAodGhlIGZpcnN0IGJlaW5nIHRoZQogICAgICogc3ltYm9sIGl0c2VsZikgb2YgdGhlIG9wZXJhdGlvbiBpbXBsZW1lbnRlZCBieSB0aGlzIHZpc2l0b3I7IHVzZQogICAgICogVm9pZCBpZiBhIHNlY29uZCBhcmd1bWVudCBpcyBub3QgbmVlZGVkLgogICAgICovCiAgICBwdWJsaWMgaW50ZXJmYWNlIFZpc2l0b3I8UixQPiB7CiAgICAgICAgUiB2aXNpdENsYXNzU3ltYm9sKENsYXNzU3ltYm9sIHMsIFAgYXJnKTsKICAgICAgICBSIHZpc2l0TWV0aG9kU3ltYm9sKE1ldGhvZFN5bWJvbCBzLCBQIGFyZyk7CiAgICAgICAgUiB2aXNpdFBhY2thZ2VTeW1ib2woUGFja2FnZVN5bWJvbCBzLCBQIGFyZyk7CiAgICAgICAgUiB2aXNpdE9wZXJhdG9yU3ltYm9sKE9wZXJhdG9yU3ltYm9sIHMsIFAgYXJnKTsKICAgICAgICBSIHZpc2l0VmFyU3ltYm9sKFZhclN5bWJvbCBzLCBQIGFyZyk7CiAgICAgICAgUiB2aXNpdFR5cGVTeW1ib2woVHlwZVN5bWJvbCBzLCBQIGFyZyk7CiAgICAgICAgUiB2aXNpdFN5bWJvbChTeW1ib2wgcywgUCBhcmcpOwogICAgfQp9ClBLAwQKAAAIAAAGO6lKfN3ncA1CAAANQgAAKgAAAGNvbS9zdW4vdG9vbHMvamF2YWMvY29kZS9Nb2R1bGVGaW5kZXIuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAxNSwgMjAxNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwpwYWNrYWdlIGNvbS5zdW4udG9vbHMuamF2YWMuY29kZTsKCmltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwppbXBvcnQgamF2YS51dGlsLkFycmF5czsKaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOwppbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOwppbXBvcnQgamF2YS51dGlsLk1hcDsKaW1wb3J0IGphdmEudXRpbC5Ob1N1Y2hFbGVtZW50RXhjZXB0aW9uOwppbXBvcnQgamF2YS51dGlsLlNldDsKaW1wb3J0IGphdmEudXRpbC5mdW5jdGlvbi5GdW5jdGlvbjsKCmltcG9ydCBqYXZheC50b29scy5KYXZhRmlsZU1hbmFnZXI7CmltcG9ydCBqYXZheC50b29scy5KYXZhRmlsZU1hbmFnZXIuTG9jYXRpb247CmltcG9ydCBqYXZheC50b29scy5KYXZhRmlsZU9iamVjdDsKaW1wb3J0IGphdmF4LnRvb2xzLkphdmFGaWxlT2JqZWN0LktpbmQ7CmltcG9ydCBqYXZheC50b29scy5TdGFuZGFyZExvY2F0aW9uOwoKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5TeW1ib2wuQ29tcGxldGVyOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlN5bWJvbC5Db21wbGV0aW9uRmFpbHVyZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5TeW1ib2wuTW9kdWxlU3ltYm9sOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5qdm0uTW9kdWxlTmFtZVJlYWRlcjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuanZtLk1vZHVsZU5hbWVSZWFkZXIuQmFkQ2xhc3NGaWxlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5yZXNvdXJjZXMuQ29tcGlsZXJQcm9wZXJ0aWVzLkVycm9yczsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMucmVzb3VyY2VzLkNvbXBpbGVyUHJvcGVydGllcy5GcmFnbWVudHM7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuQXNzZXJ0OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkNvbnRleHQ7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuSkNEaWFnbm9zdGljOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkpDRGlhZ25vc3RpYy5GcmFnbWVudDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5MaXN0OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkxpc3RCdWZmZXI7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuTG9nOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLk5hbWU7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuTmFtZXM7CgppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5LaW5kcy5LaW5kLio7CgovKioKICogIFRoaXMgY2xhc3MgcHJvdmlkZXMgb3BlcmF0aW9ucyB0byBsb2NhdGUgbW9kdWxlIGRlZmluaXRpb25zCiAqICBmcm9tIHRoZSBzb3VyY2UgYW5kIGNsYXNzIGZpbGVzIG9uIHRoZSBwYXRocyBwcm92aWRlZCB0byBqYXZhYy4KICoKICogIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqICBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqICBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogKiAgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPgogKi8KcHVibGljIGNsYXNzIE1vZHVsZUZpbmRlciB7CiAgICAvKiogVGhlIGNvbnRleHQga2V5IGZvciB0aGUgbW9kdWxlIGZpbmRlci4gKi8KICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgQ29udGV4dC5LZXk8TW9kdWxlRmluZGVyPiBtb2R1bGVGaW5kZXJLZXkgPSBuZXcgQ29udGV4dC5LZXk8PigpOwoKICAgIC8qKiBUaGUgbG9nIHRvIHVzZSBmb3IgdmVyYm9zZSBvdXRwdXQuICovCiAgICBwcml2YXRlIGZpbmFsIExvZyBsb2c7CgogICAgLyoqIFRoZSBzeW1ib2wgdGFibGUuICovCiAgICBwcml2YXRlIGZpbmFsIFN5bXRhYiBzeW1zOwoKICAgIC8qKiBUaGUgbmFtZSB0YWJsZS4gKi8KICAgIHByaXZhdGUgZmluYWwgTmFtZXMgbmFtZXM7CgogICAgcHJpdmF0ZSBmaW5hbCBDbGFzc0ZpbmRlciBjbGFzc0ZpbmRlcjsKCiAgICAvKiogQWNjZXNzIHRvIGZpbGVzCiAgICAgKi8KICAgIHByaXZhdGUgZmluYWwgSmF2YUZpbGVNYW5hZ2VyIGZpbGVNYW5hZ2VyOwoKICAgIHByaXZhdGUgZmluYWwgSkNEaWFnbm9zdGljLkZhY3RvcnkgZGlhZ3M7CgogICAgcHJpdmF0ZSBNb2R1bGVOYW1lUmVhZGVyIG1vZHVsZU5hbWVSZWFkZXI7CgogICAgcHVibGljIE1vZHVsZUluZm9Tb3VyY2VGaWxlQ29tcGxldGVyIHNvdXJjZUZpbGVDb21wbGV0ZXI7CgogICAgLyoqIEdldCB0aGUgTW9kdWxlRmluZGVyIGluc3RhbmNlIGZvciB0aGlzIGludm9jYXRpb24uICovCiAgICBwdWJsaWMgc3RhdGljIE1vZHVsZUZpbmRlciBpbnN0YW5jZShDb250ZXh0IGNvbnRleHQpIHsKICAgICAgICBNb2R1bGVGaW5kZXIgaW5zdGFuY2UgPSBjb250ZXh0LmdldChtb2R1bGVGaW5kZXJLZXkpOwogICAgICAgIGlmIChpbnN0YW5jZSA9PSBudWxsKQogICAgICAgICAgICBpbnN0YW5jZSA9IG5ldyBNb2R1bGVGaW5kZXIoY29udGV4dCk7CiAgICAgICAgcmV0dXJuIGluc3RhbmNlOwogICAgfQoKICAgIC8qKiBDb25zdHJ1Y3QgYSBuZXcgbW9kdWxlIGZpbmRlci4gKi8KICAgIHByb3RlY3RlZCBNb2R1bGVGaW5kZXIoQ29udGV4dCBjb250ZXh0KSB7CiAgICAgICAgY29udGV4dC5wdXQobW9kdWxlRmluZGVyS2V5LCB0aGlzKTsKICAgICAgICBuYW1lcyA9IE5hbWVzLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIHN5bXMgPSBTeW10YWIuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgZmlsZU1hbmFnZXIgPSBjb250ZXh0LmdldChKYXZhRmlsZU1hbmFnZXIuY2xhc3MpOwogICAgICAgIGxvZyA9IExvZy5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBjbGFzc0ZpbmRlciA9IENsYXNzRmluZGVyLmluc3RhbmNlKGNvbnRleHQpOwoKICAgICAgICBkaWFncyA9IEpDRGlhZ25vc3RpYy5GYWN0b3J5Lmluc3RhbmNlKGNvbnRleHQpOwogICAgfQoKICAgIGNsYXNzIE1vZHVsZUxvY2F0aW9uSXRlcmF0b3IgaW1wbGVtZW50cyBJdGVyYXRvcjxTZXQ8TG9jYXRpb24+PiB7CiAgICAgICAgU3RhbmRhcmRMb2NhdGlvbiBvdXRlcjsKICAgICAgICBTZXQ8TG9jYXRpb24+IG5leHQgPSBudWxsOwoKICAgICAgICBJdGVyYXRvcjxTdGFuZGFyZExvY2F0aW9uPiBvdXRlckl0ZXIgPSBBcnJheXMuYXNMaXN0KAogICAgICAgICAgICAgICAgU3RhbmRhcmRMb2NhdGlvbi5NT0RVTEVfU09VUkNFX1BBVEgsCiAgICAgICAgICAgICAgICBTdGFuZGFyZExvY2F0aW9uLlVQR1JBREVfTU9EVUxFX1BBVEgsCiAgICAgICAgICAgICAgICBTdGFuZGFyZExvY2F0aW9uLlNZU1RFTV9NT0RVTEVTLAogICAgICAgICAgICAgICAgU3RhbmRhcmRMb2NhdGlvbi5NT0RVTEVfUEFUSAogICAgICAgICkuaXRlcmF0b3IoKTsKICAgICAgICBJdGVyYXRvcjxTZXQ8TG9jYXRpb24+PiBpbm5lckl0ZXIgPSBudWxsOwoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNOZXh0KCkgewogICAgICAgICAgICB3aGlsZSAobmV4dCA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5uZXJJdGVyID09IG51bGwgfHwgIWlubmVySXRlci5oYXNOZXh0KCkpIHsKICAgICAgICAgICAgICAgICAgICBpZiAob3V0ZXJJdGVyLmhhc05leHQoKSkgewogICAgICAgICAgICAgICAgICAgICAgICBvdXRlciA9IG91dGVySXRlci5uZXh0KCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbm5lckl0ZXIgPSBmaWxlTWFuYWdlci5saXN0TG9jYXRpb25zRm9yTW9kdWxlcyhvdXRlcikuaXRlcmF0b3IoKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKCJlcnJvciBsaXN0aW5nIG1vZHVsZSBsb2NhdGlvbnMgZm9yICIgKyBvdXRlciArICI6ICIgKyBlKTsgIC8vIEZJWE1FCiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9IGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmIChpbm5lckl0ZXIuaGFzTmV4dCgpKQogICAgICAgICAgICAgICAgICAgIG5leHQgPSBpbm5lckl0ZXIubmV4dCgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFNldDxMb2NhdGlvbj4gbmV4dCgpIHsKICAgICAgICAgICAgaGFzTmV4dCgpOwogICAgICAgICAgICBpZiAobmV4dCAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICBTZXQ8TG9jYXRpb24+IHJlc3VsdCA9IG5leHQ7CiAgICAgICAgICAgICAgICBuZXh0ID0gbnVsbDsKICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdGhyb3cgbmV3IE5vU3VjaEVsZW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CgogICAgfQoKICAgIE1vZHVsZUxvY2F0aW9uSXRlcmF0b3IgbW9kdWxlTG9jYXRpb25JdGVyYXRvciA9IG5ldyBNb2R1bGVMb2NhdGlvbkl0ZXJhdG9yKCk7CgogICAgcHVibGljIE1vZHVsZVN5bWJvbCBmaW5kTW9kdWxlKE5hbWUgbmFtZSkgewogICAgICAgIHJldHVybiBmaW5kTW9kdWxlKHN5bXMuZW50ZXJNb2R1bGUobmFtZSkpOwogICAgfQoKICAgIHB1YmxpYyBNb2R1bGVTeW1ib2wgZmluZE1vZHVsZShNb2R1bGVTeW1ib2wgbXN5bSkgewogICAgICAgIGlmIChtc3ltLmtpbmQgIT0gRVJSICYmIG1zeW0uc291cmNlTG9jYXRpb24gPT0gbnVsbCAmJiBtc3ltLmNsYXNzTG9jYXRpb24gPT0gbnVsbCkgewogICAgICAgICAgICAvLyBmaWxsIGluIGxvY2F0aW9uCiAgICAgICAgICAgIExpc3Q8TW9kdWxlU3ltYm9sPiBsaXN0ID0gc2Nhbk1vZHVsZVBhdGgobXN5bSk7CiAgICAgICAgICAgIGlmIChsaXN0LmlzRW1wdHkoKSkgewogICAgICAgICAgICAgICAgbXN5bS5raW5kID0gRVJSOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmIChtc3ltLmtpbmQgIT0gRVJSICYmIG1zeW0ubW9kdWxlX2luZm8uc291cmNlZmlsZSA9PSBudWxsICYmIG1zeW0ubW9kdWxlX2luZm8uY2xhc3NmaWxlID09IG51bGwpIHsKICAgICAgICAgICAgLy8gZmlsbCBpbiBtb2R1bGUtaW5mbwogICAgICAgICAgICBmaW5kTW9kdWxlSW5mbyhtc3ltKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1zeW07CiAgICB9CgogICAgcHVibGljIExpc3Q8TW9kdWxlU3ltYm9sPiBmaW5kQWxsTW9kdWxlcygpIHsKICAgICAgICBMaXN0PE1vZHVsZVN5bWJvbD4gbGlzdCA9IHNjYW5Nb2R1bGVQYXRoKG51bGwpOwogICAgICAgIGZvciAoTW9kdWxlU3ltYm9sIG1zeW06IGxpc3QpIHsKICAgICAgICAgICAgaWYgKG1zeW0ua2luZCAhPSBFUlIgJiYgbXN5bS5tb2R1bGVfaW5mby5zb3VyY2VmaWxlID09IG51bGwgJiYgbXN5bS5tb2R1bGVfaW5mby5jbGFzc2ZpbGUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgLy8gZmlsbCBpbiBtb2R1bGUtaW5mbwogICAgICAgICAgICAgICAgZmluZE1vZHVsZUluZm8obXN5bSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIGxpc3Q7CiAgICB9CgogICAgcHJpdmF0ZSBib29sZWFuIGluRmluZFNpbmdsZU1vZHVsZTsKCiAgICBwdWJsaWMgTW9kdWxlU3ltYm9sIGZpbmRTaW5nbGVNb2R1bGUoKSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgSmF2YUZpbGVPYmplY3Qgc3JjX2ZvID0gZ2V0TW9kdWxlSW5mb0Zyb21Mb2NhdGlvbihTdGFuZGFyZExvY2F0aW9uLlNPVVJDRV9QQVRILCBLaW5kLlNPVVJDRSk7CiAgICAgICAgICAgIEphdmFGaWxlT2JqZWN0IGNsYXNzX2ZvID0gZ2V0TW9kdWxlSW5mb0Zyb21Mb2NhdGlvbihTdGFuZGFyZExvY2F0aW9uLkNMQVNTX09VVFBVVCwgS2luZC5DTEFTUyk7CiAgICAgICAgICAgIEphdmFGaWxlT2JqZWN0IGZvID0gKHNyY19mbyA9PSBudWxsKSA/IGNsYXNzX2ZvCiAgICAgICAgICAgICAgICAgICAgOiAoY2xhc3NfZm8gPT0gbnVsbCkgPyBzcmNfZm8KICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogY2xhc3NGaW5kZXIucHJlZmVycmVkRmlsZU9iamVjdChzcmNfZm8sIGNsYXNzX2ZvKTsKCiAgICAgICAgICAgIE1vZHVsZVN5bWJvbCBtc3ltOwogICAgICAgICAgICBpZiAoZm8gPT0gbnVsbCkgewogICAgICAgICAgICAgICAgbXN5bSA9IHN5bXMudW5uYW1lZE1vZHVsZTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHN3aXRjaCAoZm8uZ2V0S2luZCgpKSB7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBTT1VSQ0U6CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghaW5GaW5kU2luZ2xlTW9kdWxlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluRmluZFNpbmdsZU1vZHVsZSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTm90ZTogdGhlIGZvbGxvd2luZyB3aWxsIHRyaWdnZXIgYSByZS1lbnRyYW50IGNhbGwgdG8gTW9kdWxlcy5lbnRlcgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1zeW0gPSBzb3VyY2VGaWxlQ29tcGxldGVyLmNvbXBsZXRlKGZvKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtc3ltLm1vZHVsZV9pbmZvLmNsYXNzZmlsZSA9IGZvOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbkZpbmRTaW5nbGVNb2R1bGUgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vdGhlIG1vZHVsZS1pbmZvLmphdmEgZG9lcyBub3QgY29udGFpbiBhIG1vZHVsZSBkZWNsYXJhdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vYXZvaWQgaW5maW5pdGUgcmVjdXJzaW9uOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgbXN5bSA9IHN5bXMudW5uYW1lZE1vZHVsZTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICBjYXNlIENMQVNTOgogICAgICAgICAgICAgICAgICAgICAgICBOYW1lIG5hbWU7CiAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lID0gbmFtZXMuZnJvbVN0cmluZyhyZWFkTW9kdWxlTmFtZShmbykpOwogICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChCYWRDbGFzc0ZpbGUgfCBJT0V4Y2VwdGlvbiBleCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9maWxsSW4gd2lsbCByZXBvcnQgcHJvcGVyIGVycm9yczoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUgPSBuYW1lcy5lcnJvcjsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBtc3ltID0gc3ltcy5lbnRlck1vZHVsZShuYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgbXN5bS5tb2R1bGVfaW5mby5jbGFzc2ZpbGUgPSBmbzsKICAgICAgICAgICAgICAgICAgICAgICAgbXN5bS5jb21wbGV0ZXIgPSBDb21wbGV0ZXIuTlVMTF9DT01QTEVURVI7CiAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzRmluZGVyLmZpbGxJbihtc3ltLm1vZHVsZV9pbmZvKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgICAgQXNzZXJ0LmVycm9yKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIG1zeW0gPSBzeW1zLnVubmFtZWRNb2R1bGU7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBtc3ltLmNsYXNzTG9jYXRpb24gPSBTdGFuZGFyZExvY2F0aW9uLkNMQVNTX09VVFBVVDsKICAgICAgICAgICAgcmV0dXJuIG1zeW07CgogICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGUpOyAvLyBGSVhNRQogICAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIFN0cmluZyByZWFkTW9kdWxlTmFtZShKYXZhRmlsZU9iamVjdCBqZm8pIHRocm93cyBJT0V4Y2VwdGlvbiwgTW9kdWxlTmFtZVJlYWRlci5CYWRDbGFzc0ZpbGUgewogICAgICAgIGlmIChtb2R1bGVOYW1lUmVhZGVyID09IG51bGwpCiAgICAgICAgICAgIG1vZHVsZU5hbWVSZWFkZXIgPSBuZXcgTW9kdWxlTmFtZVJlYWRlcigpOwogICAgICAgIHJldHVybiBtb2R1bGVOYW1lUmVhZGVyLnJlYWRNb2R1bGVOYW1lKGpmbyk7CiAgICB9CgogICAgcHJpdmF0ZSBKYXZhRmlsZU9iamVjdCBnZXRNb2R1bGVJbmZvRnJvbUxvY2F0aW9uKExvY2F0aW9uIGxvY2F0aW9uLCBLaW5kIGtpbmQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKCFmaWxlTWFuYWdlci5oYXNMb2NhdGlvbihsb2NhdGlvbikpCiAgICAgICAgICAgIHJldHVybiBudWxsOwoKICAgICAgICByZXR1cm4gZmlsZU1hbmFnZXIuZ2V0SmF2YUZpbGVGb3JJbnB1dChsb2NhdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lcy5tb2R1bGVfaW5mby50b1N0cmluZygpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtpbmQpOwogICAgfQoKICAgIHByaXZhdGUgTGlzdDxNb2R1bGVTeW1ib2w+IHNjYW5Nb2R1bGVQYXRoKE1vZHVsZVN5bWJvbCB0b0ZpbmQpIHsKICAgICAgICBMaXN0QnVmZmVyPE1vZHVsZVN5bWJvbD4gcmVzdWx0cyA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICBNYXA8TmFtZSwgTG9jYXRpb24+IG5hbWVzSW5TZXQgPSBuZXcgSGFzaE1hcDw+KCk7CiAgICAgICAgYm9vbGVhbiBtdWx0aU1vZHVsZU1vZGUgPSBmaWxlTWFuYWdlci5oYXNMb2NhdGlvbihTdGFuZGFyZExvY2F0aW9uLk1PRFVMRV9TT1VSQ0VfUEFUSCk7CiAgICAgICAgd2hpbGUgKG1vZHVsZUxvY2F0aW9uSXRlcmF0b3IuaGFzTmV4dCgpKSB7CiAgICAgICAgICAgIFNldDxMb2NhdGlvbj4gbG9jbnMgPSAobW9kdWxlTG9jYXRpb25JdGVyYXRvci5uZXh0KCkpOwogICAgICAgICAgICBuYW1lc0luU2V0LmNsZWFyKCk7CiAgICAgICAgICAgIGZvciAoTG9jYXRpb24gbDogbG9jbnMpIHsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgTmFtZSBuID0gbmFtZXMuZnJvbVN0cmluZyhmaWxlTWFuYWdlci5pbmZlck1vZHVsZU5hbWUobCkpOwogICAgICAgICAgICAgICAgICAgIGlmIChuYW1lc0luU2V0LnB1dChuLCBsKSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIE1vZHVsZVN5bWJvbCBtc3ltID0gc3ltcy5lbnRlck1vZHVsZShuKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG1zeW0uc291cmNlTG9jYXRpb24gIT0gbnVsbCB8fCBtc3ltLmNsYXNzTG9jYXRpb24gIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbW9kdWxlIGhhcyBhbHJlYWR5IGJlZW4gZm91bmQsIHNvIGlnbm9yZSB0aGlzIGluc3RhbmNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBpZiAoZmlsZU1hbmFnZXIuaGFzTG9jYXRpb24oU3RhbmRhcmRMb2NhdGlvbi5QQVRDSF9NT0RVTEVfUEFUSCkgJiYKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1zeW0ucGF0Y2hMb2NhdGlvbiA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtc3ltLnBhdGNoTG9jYXRpb24gPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlTWFuYWdlci5nZXRMb2NhdGlvbkZvck1vZHVsZShTdGFuZGFyZExvY2F0aW9uLlBBVENIX01PRFVMRV9QQVRILAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtc3ltLm5hbWUudG9TdHJpbmcoKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGVja01vZHVsZUluZm9PbkxvY2F0aW9uKG1zeW0ucGF0Y2hMb2NhdGlvbiwgS2luZC5DTEFTUywgS2luZC5TT1VSQ0UpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG1zeW0ucGF0Y2hMb2NhdGlvbiAhPSBudWxsICYmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXVsdGlNb2R1bGVNb2RlICYmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZU1hbmFnZXIuaGFzTG9jYXRpb24oU3RhbmRhcmRMb2NhdGlvbi5DTEFTU19PVVRQVVQpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXN5bS5wYXRjaE91dHB1dExvY2F0aW9uID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVNYW5hZ2VyLmdldExvY2F0aW9uRm9yTW9kdWxlKFN0YW5kYXJkTG9jYXRpb24uQ0xBU1NfT1VUUFVULAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXN5bS5uYW1lLnRvU3RyaW5nKCkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoZWNrTW9kdWxlSW5mb09uTG9jYXRpb24obXN5bS5wYXRjaE91dHB1dExvY2F0aW9uLCBLaW5kLkNMQVNTKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBpZiAobW9kdWxlTG9jYXRpb25JdGVyYXRvci5vdXRlciA9PSBTdGFuZGFyZExvY2F0aW9uLk1PRFVMRV9TT1VSQ0VfUEFUSCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG1zeW0ucGF0Y2hMb2NhdGlvbiA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXN5bS5zb3VyY2VMb2NhdGlvbiA9IGw7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZpbGVNYW5hZ2VyLmhhc0xvY2F0aW9uKFN0YW5kYXJkTG9jYXRpb24uQ0xBU1NfT1VUUFVUKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtc3ltLmNsYXNzTG9jYXRpb24gPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVNYW5hZ2VyLmdldExvY2F0aW9uRm9yTW9kdWxlKFN0YW5kYXJkTG9jYXRpb24uQ0xBU1NfT1VUUFVULAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1zeW0ubmFtZS50b1N0cmluZygpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtc3ltLmNsYXNzTG9jYXRpb24gPSBsOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChtb2R1bGVMb2NhdGlvbkl0ZXJhdG9yLm91dGVyID09IFN0YW5kYXJkTG9jYXRpb24uU1lTVEVNX01PRFVMRVMgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vZHVsZUxvY2F0aW9uSXRlcmF0b3Iub3V0ZXIgPT0gU3RhbmRhcmRMb2NhdGlvbi5VUEdSQURFX01PRFVMRV9QQVRIKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtc3ltLmZsYWdzX2ZpZWxkIHw9IEZsYWdzLlNZU1RFTV9NT0RVTEU7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRvRmluZCA9PSBudWxsIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAodG9GaW5kID09IG1zeW0gJiYgKG1zeW0uc291cmNlTG9jYXRpb24gIT0gbnVsbCB8fCBtc3ltLmNsYXNzTG9jYXRpb24gIT0gbnVsbCkpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBOb3RlOiBjYW5ub3QgcmV0dXJuIG1zeW0gZGlyZWN0bHksIGJlY2F1c2Ugd2UgbXVzdCBmaW5pc2gKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHByb2Nlc3NpbmcgdGhpcyBzZXQgZmlyc3QKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdHMuYWRkKG1zeW0pOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgbG9nLmVycm9yKEVycm9ycy5EdXBsaWNhdGVNb2R1bGVPblBhdGgoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0RGVzY3JpcHRpb24obW9kdWxlTG9jYXRpb25JdGVyYXRvci5vdXRlciksIG4pKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gc2tpcCBsb2NhdGlvbiBmb3Igbm93PyAgbG9nIGVycm9yPwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICh0b0ZpbmQgIT0gbnVsbCAmJiByZXN1bHRzLm5vbkVtcHR5KCkpCiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0cy50b0xpc3QoKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiByZXN1bHRzLnRvTGlzdCgpOwogICAgfQoKICAgIHByaXZhdGUgdm9pZCBjaGVja01vZHVsZUluZm9PbkxvY2F0aW9uKExvY2F0aW9uIGxvY2F0aW9uLCBLaW5kLi4uIGtpbmRzKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgIGlmIChsb2NhdGlvbiA9PSBudWxsKQogICAgICAgICAgICByZXR1cm4gOwoKICAgICAgICBmb3IgKEtpbmQga2luZCA6IGtpbmRzKSB7CiAgICAgICAgICAgIEphdmFGaWxlT2JqZWN0IGZpbGUgPSBmaWxlTWFuYWdlci5nZXRKYXZhRmlsZUZvcklucHV0KGxvY2F0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lcy5tb2R1bGVfaW5mby50b1N0cmluZygpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBraW5kKTsKICAgICAgICAgICAgaWYgKGZpbGUgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgbG9nLmVycm9yKEVycm9ycy5Mb2NuTW9kdWxlSW5mb05vdEFsbG93ZWRPblBhdGNoUGF0aChmaWxlKSk7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgcHJpdmF0ZSB2b2lkIGZpbmRNb2R1bGVJbmZvKE1vZHVsZVN5bWJvbCBtc3ltKSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgSmF2YUZpbGVPYmplY3Qgc3JjX2ZvID0gKG1zeW0uc291cmNlTG9jYXRpb24gPT0gbnVsbCkgPyBudWxsCiAgICAgICAgICAgICAgICAgICAgOiBmaWxlTWFuYWdlci5nZXRKYXZhRmlsZUZvcklucHV0KG1zeW0uc291cmNlTG9jYXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lcy5tb2R1bGVfaW5mby50b1N0cmluZygpLCBLaW5kLlNPVVJDRSk7CgogICAgICAgICAgICBKYXZhRmlsZU9iamVjdCBjbGFzc19mbyA9IChtc3ltLmNsYXNzTG9jYXRpb24gPT0gbnVsbCkgPyBudWxsCiAgICAgICAgICAgICAgICAgICAgOiBmaWxlTWFuYWdlci5nZXRKYXZhRmlsZUZvcklucHV0KG1zeW0uY2xhc3NMb2NhdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVzLm1vZHVsZV9pbmZvLnRvU3RyaW5nKCksIEtpbmQuQ0xBU1MpOwoKICAgICAgICAgICAgSmF2YUZpbGVPYmplY3QgZm8gPSAoc3JjX2ZvID09IG51bGwpID8gY2xhc3NfZm8gOgogICAgICAgICAgICAgICAgICAgIChjbGFzc19mbyA9PSBudWxsKSA/IHNyY19mbyA6CiAgICAgICAgICAgICAgICAgICAgY2xhc3NGaW5kZXIucHJlZmVycmVkRmlsZU9iamVjdChzcmNfZm8sIGNsYXNzX2ZvKTsKCiAgICAgICAgICAgIGlmIChmbyA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICBTdHJpbmcgbW9kdWxlTmFtZSA9IG1zeW0uc291cmNlTG9jYXRpb24gPT0gbnVsbCAmJiBtc3ltLmNsYXNzTG9jYXRpb24gIT0gbnVsbCA/CiAgICAgICAgICAgICAgICAgICAgZmlsZU1hbmFnZXIuaW5mZXJNb2R1bGVOYW1lKG1zeW0uY2xhc3NMb2NhdGlvbikgOiBudWxsOwogICAgICAgICAgICAgICAgaWYgKG1vZHVsZU5hbWUgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIG1zeW0ubW9kdWxlX2luZm8uY2xhc3NmaWxlID0gbnVsbDsKICAgICAgICAgICAgICAgICAgICBtc3ltLmZsYWdzX2ZpZWxkIHw9IEZsYWdzLkFVVE9NQVRJQ19NT0RVTEU7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIG1zeW0ua2luZCA9IEVSUjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIG1zeW0ubW9kdWxlX2luZm8uY2xhc3NmaWxlID0gZm87CiAgICAgICAgICAgICAgICBtc3ltLm1vZHVsZV9pbmZvLmNvbXBsZXRlciA9IG5ldyBTeW1ib2wuQ29tcGxldGVyKCkgewogICAgICAgICAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICAgICAgICAgIHB1YmxpYyB2b2lkIGNvbXBsZXRlKFN5bWJvbCBzeW0pIHRocm93cyBDb21wbGV0aW9uRmFpbHVyZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzRmluZGVyLmZpbGxJbihtc3ltLm1vZHVsZV9pbmZvKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgICAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICJNb2R1bGVJbmZvQ29tcGxldGVyIjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICB9CiAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICBtc3ltLmtpbmQgPSBFUlI7CiAgICAgICAgfQogICAgfQoKICAgIEZyYWdtZW50IGdldERlc2NyaXB0aW9uKFN0YW5kYXJkTG9jYXRpb24gbCkgewogICAgICAgIHN3aXRjaCAobCkgewogICAgICAgICAgICBjYXNlIE1PRFVMRV9QQVRIOiByZXR1cm4gRnJhZ21lbnRzLkxvY25Nb2R1bGVfcGF0aDsKICAgICAgICAgICAgY2FzZSBNT0RVTEVfU09VUkNFX1BBVEg6IHJldHVybiBGcmFnbWVudHMuTG9jbk1vZHVsZV9zb3VyY2VfcGF0aDsKICAgICAgICAgICAgY2FzZSBTWVNURU1fTU9EVUxFUzogcmV0dXJuIEZyYWdtZW50cy5Mb2NuU3lzdGVtX21vZHVsZXM7CiAgICAgICAgICAgIGNhc2UgVVBHUkFERV9NT0RVTEVfUEFUSDogcmV0dXJuIEZyYWdtZW50cy5Mb2NuVXBncmFkZV9tb2R1bGVfcGF0aDsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigpOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgaW50ZXJmYWNlIE1vZHVsZUluZm9Tb3VyY2VGaWxlQ29tcGxldGVyIHsKICAgICAgICBwdWJsaWMgTW9kdWxlU3ltYm9sIGNvbXBsZXRlKEphdmFGaWxlT2JqZWN0IGZpbGUpOwogICAgfQoKfQpQSwMECgAACAAABjupSo4YTqbvHwAA7x8AACQAAABjb20vc3VuL3Rvb2xzL2phdmFjL2NvZGUvU291cmNlLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDIsIDIwMTUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhYy5jb2RlOwoKaW1wb3J0IGphdmEudXRpbC4qOwoKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuU291cmNlVmVyc2lvbjsKaW1wb3J0IHN0YXRpYyBqYXZheC5sYW5nLm1vZGVsLlNvdXJjZVZlcnNpb24uKjsKCmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmp2bS5UYXJnZXQ7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuKjsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLm1haW4uT3B0aW9uLio7CgovKiogVGhlIHNvdXJjZSBsYW5ndWFnZSB2ZXJzaW9uIGFjY2VwdGVkLgogKgogKiAgPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24gcmlzay4KICogIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yCiAqICBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+CiAqLwpwdWJsaWMgZW51bSBTb3VyY2UgewogICAgLyoqIDEuMCBoYWQgbm8gaW5uZXIgY2xhc3NlcywgYW5kIHNvIGNvdWxkIG5vdCBwYXNzIHRoZSBKQ0suICovCiAgICAvLyBwdWJsaWMgc3RhdGljIGZpbmFsIFNvdXJjZSBKREsxXzAgPSAgICAgICAgICAgICAgbmV3IFNvdXJjZSgiMS4wIik7CgogICAgLyoqIDEuMSBkaWQgbm90IGhhdmUgc3RyaWN0ZnAsIGFuZCBzbyBjb3VsZCBub3QgcGFzcyB0aGUgSkNLLiAqLwogICAgLy8gcHVibGljIHN0YXRpYyBmaW5hbCBTb3VyY2UgSkRLMV8xID0gICAgICAgICAgICAgIG5ldyBTb3VyY2UoIjEuMSIpOwoKICAgIC8qKiAxLjIgaW50cm9kdWNlZCBzdHJpY3RmcC4gKi8KICAgIEpESzFfMigiMS4yIiksCgogICAgLyoqIDEuMyBpcyB0aGUgc2FtZSBsYW5ndWFnZSBhcyAxLjIuICovCiAgICBKREsxXzMoIjEuMyIpLAoKICAgIC8qKiAxLjQgaW50cm9kdWNlZCBhc3NlcnQuICovCiAgICBKREsxXzQoIjEuNCIpLAoKICAgIC8qKiAxLjUgaW50cm9kdWNlZCBnZW5lcmljcywgYXR0cmlidXRlcywgZm9yZWFjaCwgYm94aW5nLCBzdGF0aWMgaW1wb3J0LAogICAgICogIGNvdmFyaWFudCByZXR1cm4sIGVudW1zLCB2YXJhcmdzLCBldCBhbC4gKi8KICAgIEpESzFfNSgiMS41IiksCgogICAgLyoqIDEuNiByZXBvcnRzIGVuY29kaW5nIHByb2JsZW1zIGFzIGVycm9ycyBpbnN0ZWFkIG9mIHdhcm5pbmdzLiAqLwogICAgSkRLMV82KCIxLjYiKSwKCiAgICAvKiogMS43IGludHJvZHVjZWQgdHJ5LXdpdGgtcmVzb3VyY2VzLCBtdWx0aS1jYXRjaCwgc3RyaW5nIHN3aXRjaCwgZXRjLiAqLwogICAgSkRLMV83KCIxLjciKSwKCiAgICAvKiogMS44IGxhbWJkYSBleHByZXNzaW9ucyBhbmQgZGVmYXVsdCBtZXRob2RzLiAqLwogICAgSkRLMV84KCIxLjgiKSwKCiAgICAvKiogMS45IGNvdmVycyB0aGUgdG8gYmUgZGV0ZXJtaW5lZCBsYW5ndWFnZSBmZWF0dXJlcyB0aGF0IHdpbGwgYmUgYWRkZWQgaW4gSkRLIDkuICovCiAgICBKREsxXzkoIjEuOSIpOwoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIENvbnRleHQuS2V5PFNvdXJjZT4gc291cmNlS2V5ID0gbmV3IENvbnRleHQuS2V5PD4oKTsKCiAgICBwdWJsaWMgc3RhdGljIFNvdXJjZSBpbnN0YW5jZShDb250ZXh0IGNvbnRleHQpIHsKICAgICAgICBTb3VyY2UgaW5zdGFuY2UgPSBjb250ZXh0LmdldChzb3VyY2VLZXkpOwogICAgICAgIGlmIChpbnN0YW5jZSA9PSBudWxsKSB7CiAgICAgICAgICAgIE9wdGlvbnMgb3B0aW9ucyA9IE9wdGlvbnMuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgICAgIFN0cmluZyBzb3VyY2VTdHJpbmcgPSBvcHRpb25zLmdldChTT1VSQ0UpOwogICAgICAgICAgICBpZiAoc291cmNlU3RyaW5nICE9IG51bGwpIGluc3RhbmNlID0gbG9va3VwKHNvdXJjZVN0cmluZyk7CiAgICAgICAgICAgIGlmIChpbnN0YW5jZSA9PSBudWxsKSBpbnN0YW5jZSA9IERFRkFVTFQ7CiAgICAgICAgICAgIGNvbnRleHQucHV0KHNvdXJjZUtleSwgaW5zdGFuY2UpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gaW5zdGFuY2U7CiAgICB9CgogICAgcHVibGljIGZpbmFsIFN0cmluZyBuYW1lOwoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIE1hcDxTdHJpbmcsU291cmNlPiB0YWIgPSBuZXcgSGFzaE1hcDw+KCk7CiAgICBzdGF0aWMgewogICAgICAgIGZvciAoU291cmNlIHMgOiB2YWx1ZXMoKSkgewogICAgICAgICAgICB0YWIucHV0KHMubmFtZSwgcyk7CiAgICAgICAgfQogICAgICAgIHRhYi5wdXQoIjUiLCBKREsxXzUpOyAvLyBNYWtlIDUgYW4gYWxpYXMgZm9yIDEuNQogICAgICAgIHRhYi5wdXQoIjYiLCBKREsxXzYpOyAvLyBNYWtlIDYgYW4gYWxpYXMgZm9yIDEuNgogICAgICAgIHRhYi5wdXQoIjciLCBKREsxXzcpOyAvLyBNYWtlIDcgYW4gYWxpYXMgZm9yIDEuNwogICAgICAgIHRhYi5wdXQoIjgiLCBKREsxXzgpOyAvLyBNYWtlIDggYW4gYWxpYXMgZm9yIDEuOAogICAgICAgIHRhYi5wdXQoIjkiLCBKREsxXzkpOyAvLyBNYWtlIDkgYW4gYWxpYXMgZm9yIDEuOQogICAgfQoKICAgIHByaXZhdGUgU291cmNlKFN0cmluZyBuYW1lKSB7CiAgICAgICAgdGhpcy5uYW1lID0gbmFtZTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFNvdXJjZSBNSU4gPSBTb3VyY2UuSkRLMV82OwoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFNvdXJjZSBNQVggPSB2YWx1ZXMoKVt2YWx1ZXMoKS5sZW5ndGggLSAxXTsKCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFNvdXJjZSBERUZBVUxUID0gSkRLMV84OwoKICAgIHB1YmxpYyBzdGF0aWMgU291cmNlIGxvb2t1cChTdHJpbmcgbmFtZSkgewogICAgICAgIHJldHVybiB0YWIuZ2V0KG5hbWUpOwogICAgfQoKICAgIHB1YmxpYyBUYXJnZXQgcmVxdWlyZWRUYXJnZXQoKSB7CiAgICAgICAgaWYgKHRoaXMuY29tcGFyZVRvKEpESzFfOSkgPj0gMCkgcmV0dXJuIFRhcmdldC5KREsxXzk7CiAgICAgICAgaWYgKHRoaXMuY29tcGFyZVRvKEpESzFfOCkgPj0gMCkgcmV0dXJuIFRhcmdldC5KREsxXzg7CiAgICAgICAgaWYgKHRoaXMuY29tcGFyZVRvKEpESzFfNykgPj0gMCkgcmV0dXJuIFRhcmdldC5KREsxXzc7CiAgICAgICAgaWYgKHRoaXMuY29tcGFyZVRvKEpESzFfNikgPj0gMCkgcmV0dXJuIFRhcmdldC5KREsxXzY7CiAgICAgICAgaWYgKHRoaXMuY29tcGFyZVRvKEpESzFfNSkgPj0gMCkgcmV0dXJuIFRhcmdldC5KREsxXzU7CiAgICAgICAgaWYgKHRoaXMuY29tcGFyZVRvKEpESzFfNCkgPj0gMCkgcmV0dXJuIFRhcmdldC5KREsxXzQ7CiAgICAgICAgcmV0dXJuIFRhcmdldC5KREsxXzE7CiAgICB9CgogICAgcHVibGljIGJvb2xlYW4gYWxsb3dEaWFtb25kKCkgewogICAgICAgIHJldHVybiBjb21wYXJlVG8oSkRLMV83KSA+PSAwOwogICAgfQogICAgcHVibGljIGJvb2xlYW4gYWxsb3dNdWx0aWNhdGNoKCkgewogICAgICAgIHJldHVybiBjb21wYXJlVG8oSkRLMV83KSA+PSAwOwogICAgfQogICAgcHVibGljIGJvb2xlYW4gYWxsb3dJbXByb3ZlZFJldGhyb3dBbmFseXNpcygpIHsKICAgICAgICByZXR1cm4gY29tcGFyZVRvKEpESzFfNykgPj0gMDsKICAgIH0KICAgIHB1YmxpYyBib29sZWFuIGFsbG93SW1wcm92ZWRDYXRjaEFuYWx5c2lzKCkgewogICAgICAgIHJldHVybiBjb21wYXJlVG8oSkRLMV83KSA+PSAwOwogICAgfQogICAgcHVibGljIGJvb2xlYW4gYWxsb3dNb2R1bGVzKCkgewogICAgICAgIHJldHVybiBjb21wYXJlVG8oSkRLMV85KSA+PSAwOwogICAgfQogICAgcHVibGljIGJvb2xlYW4gYWxsb3dUcnlXaXRoUmVzb3VyY2VzKCkgewogICAgICAgIHJldHVybiBjb21wYXJlVG8oSkRLMV83KSA+PSAwOwogICAgfQogICAgcHVibGljIGJvb2xlYW4gYWxsb3dFZmZlY3RpdmVseUZpbmFsVmFyaWFibGVzSW5UcnlXaXRoUmVzb3VyY2VzKCkgewogICAgICAgIHJldHVybiBjb21wYXJlVG8oSkRLMV85KSA+PSAwOwogICAgfQogICAgcHVibGljIGJvb2xlYW4gYWxsb3dCaW5hcnlMaXRlcmFscygpIHsKICAgICAgICByZXR1cm4gY29tcGFyZVRvKEpESzFfNykgPj0gMDsKICAgIH0KICAgIHB1YmxpYyBib29sZWFuIGFsbG93VW5kZXJzY29yZXNJbkxpdGVyYWxzKCkgewogICAgICAgIHJldHVybiBjb21wYXJlVG8oSkRLMV83KSA+PSAwOwogICAgfQogICAgcHVibGljIGJvb2xlYW4gYWxsb3dTdHJpbmdzSW5Td2l0Y2goKSB7CiAgICAgICAgcmV0dXJuIGNvbXBhcmVUbyhKREsxXzcpID49IDA7CiAgICB9CiAgICBwdWJsaWMgYm9vbGVhbiBhbGxvd0RlcHJlY2F0aW9uT25JbXBvcnQoKSB7CiAgICAgICAgcmV0dXJuIGNvbXBhcmVUbyhKREsxXzkpIDwgMDsKICAgIH0KICAgIHB1YmxpYyBib29sZWFuIGFsbG93U2ltcGxpZmllZFZhcmFyZ3MoKSB7CiAgICAgICAgcmV0dXJuIGNvbXBhcmVUbyhKREsxXzcpID49IDA7CiAgICB9CiAgICBwdWJsaWMgYm9vbGVhbiBhbGxvd09iamVjdFRvUHJpbWl0aXZlQ2FzdCgpIHsKICAgICAgICByZXR1cm4gY29tcGFyZVRvKEpESzFfNykgPj0gMDsKICAgIH0KICAgIHB1YmxpYyBib29sZWFuIGVuZm9yY2VUaGlzRG90SW5pdCgpIHsKICAgICAgICByZXR1cm4gY29tcGFyZVRvKEpESzFfNykgPj0gMDsKICAgIH0KICAgIHB1YmxpYyBib29sZWFuIGFsbG93UG9seSgpIHsKICAgICAgICByZXR1cm4gY29tcGFyZVRvKEpESzFfOCkgPj0gMDsKICAgIH0KICAgIHB1YmxpYyBib29sZWFuIGFsbG93TGFtYmRhKCkgewogICAgICAgIHJldHVybiBjb21wYXJlVG8oSkRLMV84KSA+PSAwOwogICAgfQogICAgcHVibGljIGJvb2xlYW4gYWxsb3dNZXRob2RSZWZlcmVuY2VzKCkgewogICAgICAgIHJldHVybiBjb21wYXJlVG8oSkRLMV84KSA+PSAwOwogICAgfQogICAgcHVibGljIGJvb2xlYW4gYWxsb3dEZWZhdWx0TWV0aG9kcygpIHsKICAgICAgICByZXR1cm4gY29tcGFyZVRvKEpESzFfOCkgPj0gMDsKICAgIH0KICAgIHB1YmxpYyBib29sZWFuIGFsbG93U3RhdGljSW50ZXJmYWNlTWV0aG9kcygpIHsKICAgICAgICByZXR1cm4gY29tcGFyZVRvKEpESzFfOCkgPj0gMDsKICAgIH0KICAgIHB1YmxpYyBib29sZWFuIGFsbG93U3RyaWN0TWV0aG9kQ2xhc2hDaGVjaygpIHsKICAgICAgICByZXR1cm4gY29tcGFyZVRvKEpESzFfOCkgPj0gMDsKICAgIH0KICAgIHB1YmxpYyBib29sZWFuIGFsbG93RWZmZWN0aXZlbHlGaW5hbEluSW5uZXJDbGFzc2VzKCkgewogICAgICAgIHJldHVybiBjb21wYXJlVG8oSkRLMV84KSA+PSAwOwogICAgfQogICAgcHVibGljIGJvb2xlYW4gYWxsb3dUeXBlQW5ub3RhdGlvbnMoKSB7CiAgICAgICAgcmV0dXJuIGNvbXBhcmVUbyhKREsxXzgpID49IDA7CiAgICB9CiAgICBwdWJsaWMgYm9vbGVhbiBhbGxvd0Fubm90YXRpb25zQWZ0ZXJUeXBlUGFyYW1zKCkgewogICAgICAgIHJldHVybiBjb21wYXJlVG8oSkRLMV84KSA+PSAwOwogICAgfQogICAgcHVibGljIGJvb2xlYW4gYWxsb3dSZXBlYXRlZEFubm90YXRpb25zKCkgewogICAgICAgIHJldHVybiBjb21wYXJlVG8oSkRLMV84KSA+PSAwOwogICAgfQogICAgcHVibGljIGJvb2xlYW4gYWxsb3dJbnRlcnNlY3Rpb25UeXBlc0luQ2FzdCgpIHsKICAgICAgICByZXR1cm4gY29tcGFyZVRvKEpESzFfOCkgPj0gMDsKICAgIH0KICAgIHB1YmxpYyBib29sZWFuIGFsbG93R3JhcGhJbmZlcmVuY2UoKSB7CiAgICAgICAgcmV0dXJuIGNvbXBhcmVUbyhKREsxXzgpID49IDA7CiAgICB9CiAgICBwdWJsaWMgYm9vbGVhbiBhbGxvd0Z1bmN0aW9uYWxJbnRlcmZhY2VNb3N0U3BlY2lmaWMoKSB7CiAgICAgICAgcmV0dXJuIGNvbXBhcmVUbyhKREsxXzgpID49IDA7CiAgICB9CiAgICBwdWJsaWMgYm9vbGVhbiBhbGxvd1Bvc3RBcHBsaWNhYmlsaXR5VmFyYXJnc0FjY2Vzc0NoZWNrKCkgewogICAgICAgIHJldHVybiBjb21wYXJlVG8oSkRLMV84KSA+PSAwOwogICAgfQogICAgcHVibGljIGJvb2xlYW4gbWFwQ2FwdHVyZXNUb0JvdW5kcygpIHsKICAgICAgICByZXR1cm4gY29tcGFyZVRvKEpESzFfOCkgPCAwOwogICAgfQogICAgcHVibGljIGJvb2xlYW4gYWxsb3dQcml2YXRlU2FmZVZhcmFyZ3MoKSB7CiAgICAgICAgcmV0dXJuIGNvbXBhcmVUbyhKREsxXzkpID49IDA7CiAgICB9CiAgICBwdWJsaWMgYm9vbGVhbiBhbGxvd0RpYW1vbmRXaXRoQW5vbnltb3VzQ2xhc3NDcmVhdGlvbigpIHsKICAgICAgICByZXR1cm4gY29tcGFyZVRvKEpESzFfOSkgPj0gMDsKICAgIH0KICAgIHB1YmxpYyBib29sZWFuIGFsbG93VW5kZXJzY29yZUlkZW50aWZpZXIoKSB7CiAgICAgICAgcmV0dXJuIGNvbXBhcmVUbyhKREsxXzgpIDw9IDA7CiAgICB9CiAgICBwdWJsaWMgYm9vbGVhbiBhbGxvd1ByaXZhdGVJbnRlcmZhY2VNZXRob2RzKCkgeyByZXR1cm4gY29tcGFyZVRvKEpESzFfOSkgPj0gMDsgfQogICAgcHVibGljIHN0YXRpYyBTb3VyY2VWZXJzaW9uIHRvU291cmNlVmVyc2lvbihTb3VyY2Ugc291cmNlKSB7CiAgICAgICAgc3dpdGNoKHNvdXJjZSkgewogICAgICAgIGNhc2UgSkRLMV8yOgogICAgICAgICAgICByZXR1cm4gUkVMRUFTRV8yOwogICAgICAgIGNhc2UgSkRLMV8zOgogICAgICAgICAgICByZXR1cm4gUkVMRUFTRV8zOwogICAgICAgIGNhc2UgSkRLMV80OgogICAgICAgICAgICByZXR1cm4gUkVMRUFTRV80OwogICAgICAgIGNhc2UgSkRLMV81OgogICAgICAgICAgICByZXR1cm4gUkVMRUFTRV81OwogICAgICAgIGNhc2UgSkRLMV82OgogICAgICAgICAgICByZXR1cm4gUkVMRUFTRV82OwogICAgICAgIGNhc2UgSkRLMV83OgogICAgICAgICAgICByZXR1cm4gUkVMRUFTRV83OwogICAgICAgIGNhc2UgSkRLMV84OgogICAgICAgICAgICByZXR1cm4gUkVMRUFTRV84OwogICAgICAgIGNhc2UgSkRLMV85OgogICAgICAgICAgICByZXR1cm4gUkVMRUFTRV85OwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KICAgIH0KfQpQSwMECgAACAAABjupSorY2pCUqwAAlKsAADQAAABjb20vc3VuL3Rvb2xzL2phdmFjL2NvZGUvVHlwZUFubm90YXRpb25Qb3NpdGlvbi5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDAzLCAyMDE1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuamF2YWMuY29kZTsKCmltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CgppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkpDVHJlZS5KQ0xhbWJkYTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC4qOwoKLyoqIEEgdHlwZSBhbm5vdGF0aW9uIHBvc2l0aW9uLgoqCiogIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiogIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24gcmlzay4KKiAgVGhpcyBjb2RlIGFuZCBpdHMgaW50ZXJuYWwgaW50ZXJmYWNlcyBhcmUgc3ViamVjdCB0byBjaGFuZ2Ugb3IKKiAgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPgoqLwovLyBDb2RlIGR1cGxpY2F0ZWQgaW4gY29tLnN1bi50b29scy5jbGFzc2ZpbGUuVHlwZUFubm90YXRpb24uUG9zaXRpb24KcHVibGljIGNsYXNzIFR5cGVBbm5vdGF0aW9uUG9zaXRpb24gewoKICAgIHB1YmxpYyBlbnVtIFR5cGVQYXRoRW50cnlLaW5kIHsKICAgICAgICBBUlJBWSgwKSwKICAgICAgICBJTk5FUl9UWVBFKDEpLAogICAgICAgIFdJTERDQVJEKDIpLAogICAgICAgIFRZUEVfQVJHVU1FTlQoMyk7CgogICAgICAgIHB1YmxpYyBmaW5hbCBpbnQgdGFnOwoKICAgICAgICBwcml2YXRlIFR5cGVQYXRoRW50cnlLaW5kKGludCB0YWcpIHsKICAgICAgICAgICAgdGhpcy50YWcgPSB0YWc7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgVHlwZVBhdGhFbnRyeSB7CiAgICAgICAgLyoqIFRoZSBmaXhlZCBudW1iZXIgb2YgYnl0ZXMgcGVyIFR5cGVQYXRoRW50cnkuICovCiAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgYnl0ZXNQZXJFbnRyeSA9IDI7CgogICAgICAgIHB1YmxpYyBmaW5hbCBUeXBlUGF0aEVudHJ5S2luZCB0YWc7CiAgICAgICAgcHVibGljIGZpbmFsIGludCBhcmc7CgogICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVHlwZVBhdGhFbnRyeSBBUlJBWSA9IG5ldyBUeXBlUGF0aEVudHJ5KFR5cGVQYXRoRW50cnlLaW5kLkFSUkFZKTsKICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFR5cGVQYXRoRW50cnkgSU5ORVJfVFlQRSA9IG5ldyBUeXBlUGF0aEVudHJ5KFR5cGVQYXRoRW50cnlLaW5kLklOTkVSX1RZUEUpOwogICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVHlwZVBhdGhFbnRyeSBXSUxEQ0FSRCA9IG5ldyBUeXBlUGF0aEVudHJ5KFR5cGVQYXRoRW50cnlLaW5kLldJTERDQVJEKTsKCiAgICAgICAgcHJpdmF0ZSBUeXBlUGF0aEVudHJ5KFR5cGVQYXRoRW50cnlLaW5kIHRhZykgewogICAgICAgICAgICBBc3NlcnQuY2hlY2sodGFnID09IFR5cGVQYXRoRW50cnlLaW5kLkFSUkFZIHx8CiAgICAgICAgICAgICAgICAgICAgdGFnID09IFR5cGVQYXRoRW50cnlLaW5kLklOTkVSX1RZUEUgfHwKICAgICAgICAgICAgICAgICAgICB0YWcgPT0gVHlwZVBhdGhFbnRyeUtpbmQuV0lMRENBUkQpOwogICAgICAgICAgICB0aGlzLnRhZyA9IHRhZzsKICAgICAgICAgICAgdGhpcy5hcmcgPSAwOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIFR5cGVQYXRoRW50cnkoVHlwZVBhdGhFbnRyeUtpbmQgdGFnLCBpbnQgYXJnKSB7CiAgICAgICAgICAgIEFzc2VydC5jaGVjayh0YWcgPT0gVHlwZVBhdGhFbnRyeUtpbmQuVFlQRV9BUkdVTUVOVCk7CiAgICAgICAgICAgIHRoaXMudGFnID0gdGFnOwogICAgICAgICAgICB0aGlzLmFyZyA9IGFyZzsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBzdGF0aWMgVHlwZVBhdGhFbnRyeSBmcm9tQmluYXJ5KGludCB0YWcsIGludCBhcmcpIHsKICAgICAgICAgICAgQXNzZXJ0LmNoZWNrKGFyZyA9PSAwIHx8IHRhZyA9PSBUeXBlUGF0aEVudHJ5S2luZC5UWVBFX0FSR1VNRU5ULnRhZyk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIHJldHVybiBBUlJBWTsKICAgICAgICAgICAgY2FzZSAxOgogICAgICAgICAgICAgICAgcmV0dXJuIElOTkVSX1RZUEU7CiAgICAgICAgICAgIGNhc2UgMjoKICAgICAgICAgICAgICAgIHJldHVybiBXSUxEQ0FSRDsKICAgICAgICAgICAgY2FzZSAzOgogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBUeXBlUGF0aEVudHJ5KFR5cGVQYXRoRW50cnlLaW5kLlRZUEVfQVJHVU1FTlQsIGFyZyk7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICBBc3NlcnQuZXJyb3IoIkludmFsaWQgVHlwZVBhdGhFbnRyeUtpbmQgdGFnOiAiICsgdGFnKTsKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewogICAgICAgICAgICByZXR1cm4gdGFnLnRvU3RyaW5nKCkgKwogICAgICAgICAgICAgICAgICAgICh0YWcgPT0gVHlwZVBhdGhFbnRyeUtpbmQuVFlQRV9BUkdVTUVOVCA/ICgiKCIgKyBhcmcgKyAiKSIpIDogIiIpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvdGhlcikgewogICAgICAgICAgICBpZiAoISAob3RoZXIgaW5zdGFuY2VvZiBUeXBlUGF0aEVudHJ5KSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIFR5cGVQYXRoRW50cnkgdHBlID0gKFR5cGVQYXRoRW50cnkpIG90aGVyOwogICAgICAgICAgICByZXR1cm4gdGhpcy50YWcgPT0gdHBlLnRhZyAmJiB0aGlzLmFyZyA9PSB0cGUuYXJnOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMudGFnLmhhc2hDb2RlKCkgKiAxNyArIHRoaXMuYXJnOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIExpc3Q8VHlwZVBhdGhFbnRyeT4gZW1wdHlQYXRoID0gTGlzdC5uaWwoKTsKCiAgICBwdWJsaWMgZmluYWwgVGFyZ2V0VHlwZSB0eXBlOwoKICAgIC8vIEZvciBnZW5lcmljL2FycmF5IHR5cGVzLgoKICAgIHB1YmxpYyBMaXN0PFR5cGVQYXRoRW50cnk+IGxvY2F0aW9uOwoKICAgIC8vIFRyZWUgcG9zaXRpb24uCiAgICBwdWJsaWMgZmluYWwgaW50IHBvczsKCiAgICAvLyBGb3IgdHlwZSBjYXN0cywgdHlwZSB0ZXN0cywgbmV3LCBsb2NhbHMgKGFzIHN0YXJ0X3BjKSwKICAgIC8vIGFuZCBtZXRob2QgYW5kIGNvbnN0cnVjdG9yIHJlZmVyZW5jZSB0eXBlIGFyZ3VtZW50cy4KICAgIHB1YmxpYyBib29sZWFuIGlzVmFsaWRPZmZzZXQgPSBmYWxzZTsKICAgIHB1YmxpYyBpbnQgb2Zmc2V0ID0gLTE7CgogICAgLy8gRm9yIGxvY2Fscy4gYXJyYXlzIHNhbWUgbGVuZ3RoCiAgICBwdWJsaWMgaW50W10gbHZhck9mZnNldCA9IG51bGw7CiAgICBwdWJsaWMgaW50W10gbHZhckxlbmd0aCA9IG51bGw7CiAgICBwdWJsaWMgaW50W10gbHZhckluZGV4ID0gbnVsbDsKCiAgICAvLyBGb3IgdHlwZSBwYXJhbWV0ZXIgYm91bmQKICAgIHB1YmxpYyBmaW5hbCBpbnQgYm91bmRfaW5kZXg7CgogICAgLy8gRm9yIHR5cGUgcGFyYW1ldGVyIGFuZCBtZXRob2QgcGFyYW1ldGVyCiAgICBwdWJsaWMgaW50IHBhcmFtZXRlcl9pbmRleDsKCiAgICAvLyBGb3IgY2xhc3MgZXh0ZW5kcywgaW1wbGVtZW50cywgYW5kIHRocm93cyBjbGF1c2VzCiAgICBwdWJsaWMgZmluYWwgaW50IHR5cGVfaW5kZXg7CgogICAgLy8gRm9yIGV4Y2VwdGlvbiBwYXJhbWV0ZXJzLCBpbmRleCBpbnRvIGV4Y2VwdGlvbiB0YWJsZS4gIEluCiAgICAvLyBjb20uc3VuLnRvb2xzLmphdmFjLmp2bS5HZW4uZ2VuQ2F0Y2gsIHdlIGZpcnN0IHVzZSB0aGlzIHRvIGhvbGQKICAgIC8vIHRoZSBjYXRjaCB0eXBlJ3MgY29uc3RhbnQgcG9vbCBlbnRyeSBpbmRleC4gIFRoZW4gaW4KICAgIC8vIGNvbS5zdW4udG9vbHMuamF2YWMuanZtLkNvZGUuZmlsbEV4Y2VwdGlvblBhcmFtZXRlclBvc2l0aW9ucyB3ZQogICAgLy8gdXNlIHRoYXQgdmFsdWUgdG8gZGV0ZXJtaW5lIHRoZSBleGNlcHRpb24gdGFibGUgaW5kZXguCiAgICAvLyBXaGVuIHJlYWQgZnJvbSBjbGFzcyBmaWxlLCB0aGlzIGhvbGRzCiAgICBwcml2YXRlIGludCBleGNlcHRpb25faW5kZXggPSBJbnRlZ2VyLk1JTl9WQUxVRTsKCiAgICAvLyBJZiB0aGlzIHR5cGUgYW5ub3RhdGlvbiBpcyB3aXRoaW4gYSBsYW1iZGEgZXhwcmVzc2lvbiwKICAgIC8vIHN0b3JlIGEgcG9pbnRlciB0byB0aGUgbGFtYmRhIGV4cHJlc3Npb24gdHJlZSBpbiBvcmRlcgogICAgLy8gdG8gYWxsb3cgYSBsYXRlciB0cmFuc2xhdGlvbiB0byB0aGUgcmlnaHQgbWV0aG9kLgogICAgcHVibGljIGZpbmFsIEpDTGFtYmRhIG9uTGFtYmRhOwoKICAgIC8vIE5PVEU6IFRoaXMgY29uc3RydWN0b3Igd2lsbCBldmVudHVhbGx5IGdvIGF3YXksIGFuZCBiZSByZXBsYWNlZAogICAgLy8gYnkgc3RhdGljIGJ1aWxkZXIgbWV0aG9kcy4KCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CiAgICAgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CiAgICAgICAgc2IuYXBwZW5kKCdbJyk7CiAgICAgICAgc2IuYXBwZW5kKHR5cGUpOwoKICAgICAgICBzd2l0Y2ggKHR5cGUpIHsKICAgICAgICAvLyBpbnN0YW5jZW9mCiAgICAgICAgY2FzZSBJTlNUQU5DRU9GOgogICAgICAgIC8vIG5ldyBleHByZXNzaW9uCiAgICAgICAgY2FzZSBORVc6CiAgICAgICAgLy8gY29uc3RydWN0b3IvbWV0aG9kIHJlZmVyZW5jZSByZWNlaXZlcgogICAgICAgIGNhc2UgQ09OU1RSVUNUT1JfUkVGRVJFTkNFOgogICAgICAgIGNhc2UgTUVUSE9EX1JFRkVSRU5DRToKICAgICAgICAgICAgc2IuYXBwZW5kKCIsIG9mZnNldCA9ICIpOwogICAgICAgICAgICBzYi5hcHBlbmQob2Zmc2V0KTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgLy8gbG9jYWwgdmFyaWFibGUKICAgICAgICBjYXNlIExPQ0FMX1ZBUklBQkxFOgogICAgICAgIC8vIHJlc291cmNlIHZhcmlhYmxlCiAgICAgICAgY2FzZSBSRVNPVVJDRV9WQVJJQUJMRToKICAgICAgICAgICAgaWYgKGx2YXJPZmZzZXQgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgc2IuYXBwZW5kKCIsIGx2YXJPZmZzZXQgaXMgbnVsbCEiKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHNiLmFwcGVuZCgiLCB7Iik7CiAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbHZhck9mZnNldC5sZW5ndGg7ICsraSkgewogICAgICAgICAgICAgICAgaWYgKGkgIT0gMCkgc2IuYXBwZW5kKCI7ICIpOwogICAgICAgICAgICAgICAgc2IuYXBwZW5kKCJzdGFydF9wYyA9ICIpOwogICAgICAgICAgICAgICAgc2IuYXBwZW5kKGx2YXJPZmZzZXRbaV0pOwogICAgICAgICAgICAgICAgc2IuYXBwZW5kKCIsIGxlbmd0aCA9ICIpOwogICAgICAgICAgICAgICAgc2IuYXBwZW5kKGx2YXJMZW5ndGhbaV0pOwogICAgICAgICAgICAgICAgc2IuYXBwZW5kKCIsIGluZGV4ID0gIik7CiAgICAgICAgICAgICAgICBzYi5hcHBlbmQobHZhckluZGV4W2ldKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBzYi5hcHBlbmQoIn0iKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgLy8gbWV0aG9kIHJlY2VpdmVyCiAgICAgICAgY2FzZSBNRVRIT0RfUkVDRUlWRVI6CiAgICAgICAgICAgIC8vIERvIG5vdGhpbmcKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgLy8gdHlwZSBwYXJhbWV0ZXIKICAgICAgICBjYXNlIENMQVNTX1RZUEVfUEFSQU1FVEVSOgogICAgICAgIGNhc2UgTUVUSE9EX1RZUEVfUEFSQU1FVEVSOgogICAgICAgICAgICBzYi5hcHBlbmQoIiwgcGFyYW1faW5kZXggPSAiKTsKICAgICAgICAgICAgc2IuYXBwZW5kKHBhcmFtZXRlcl9pbmRleCk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIC8vIHR5cGUgcGFyYW1ldGVyIGJvdW5kCiAgICAgICAgY2FzZSBDTEFTU19UWVBFX1BBUkFNRVRFUl9CT1VORDoKICAgICAgICBjYXNlIE1FVEhPRF9UWVBFX1BBUkFNRVRFUl9CT1VORDoKICAgICAgICAgICAgc2IuYXBwZW5kKCIsIHBhcmFtX2luZGV4ID0gIik7CiAgICAgICAgICAgIHNiLmFwcGVuZChwYXJhbWV0ZXJfaW5kZXgpOwogICAgICAgICAgICBzYi5hcHBlbmQoIiwgYm91bmRfaW5kZXggPSAiKTsKICAgICAgICAgICAgc2IuYXBwZW5kKGJvdW5kX2luZGV4KTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgLy8gY2xhc3MgZXh0ZW5kcyBvciBpbXBsZW1lbnRzIGNsYXVzZQogICAgICAgIGNhc2UgQ0xBU1NfRVhURU5EUzoKICAgICAgICAgICAgc2IuYXBwZW5kKCIsIHR5cGVfaW5kZXggPSAiKTsKICAgICAgICAgICAgc2IuYXBwZW5kKHR5cGVfaW5kZXgpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAvLyB0aHJvd3MKICAgICAgICBjYXNlIFRIUk9XUzoKICAgICAgICAgICAgc2IuYXBwZW5kKCIsIHR5cGVfaW5kZXggPSAiKTsKICAgICAgICAgICAgc2IuYXBwZW5kKHR5cGVfaW5kZXgpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAvLyBleGNlcHRpb24gcGFyYW1ldGVyCiAgICAgICAgY2FzZSBFWENFUFRJT05fUEFSQU1FVEVSOgogICAgICAgICAgICBzYi5hcHBlbmQoIiwgZXhjZXB0aW9uX2luZGV4ID0gIik7CiAgICAgICAgICAgIHNiLmFwcGVuZChleGNlcHRpb25faW5kZXgpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAvLyBtZXRob2QgcGFyYW1ldGVyCiAgICAgICAgY2FzZSBNRVRIT0RfRk9STUFMX1BBUkFNRVRFUjoKICAgICAgICAgICAgc2IuYXBwZW5kKCIsIHBhcmFtX2luZGV4ID0gIik7CiAgICAgICAgICAgIHNiLmFwcGVuZChwYXJhbWV0ZXJfaW5kZXgpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAvLyB0eXBlIGNhc3QKICAgICAgICBjYXNlIENBU1Q6CiAgICAgICAgLy8gbWV0aG9kL2NvbnN0cnVjdG9yL3JlZmVyZW5jZSB0eXBlIGFyZ3VtZW50CiAgICAgICAgY2FzZSBDT05TVFJVQ1RPUl9JTlZPQ0FUSU9OX1RZUEVfQVJHVU1FTlQ6CiAgICAgICAgY2FzZSBNRVRIT0RfSU5WT0NBVElPTl9UWVBFX0FSR1VNRU5UOgogICAgICAgIGNhc2UgQ09OU1RSVUNUT1JfUkVGRVJFTkNFX1RZUEVfQVJHVU1FTlQ6CiAgICAgICAgY2FzZSBNRVRIT0RfUkVGRVJFTkNFX1RZUEVfQVJHVU1FTlQ6CiAgICAgICAgICAgIHNiLmFwcGVuZCgiLCBvZmZzZXQgPSAiKTsKICAgICAgICAgICAgc2IuYXBwZW5kKG9mZnNldCk7CiAgICAgICAgICAgIHNiLmFwcGVuZCgiLCB0eXBlX2luZGV4ID0gIik7CiAgICAgICAgICAgIHNiLmFwcGVuZCh0eXBlX2luZGV4KTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgLy8gV2UgZG9uJ3QgbmVlZCB0byB3b3JyeSBhYm91dCB0aGVzZQogICAgICAgIGNhc2UgTUVUSE9EX1JFVFVSTjoKICAgICAgICBjYXNlIEZJRUxEOgogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFVOS05PV046CiAgICAgICAgICAgIHNiLmFwcGVuZCgiLCBwb3NpdGlvbiBVTktOT1dOISIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBBc3NlcnQuZXJyb3IoIlVua25vd24gdGFyZ2V0IHR5cGU6ICIgKyB0eXBlKTsKICAgICAgICB9CgogICAgICAgIC8vIEFwcGVuZCBsb2NhdGlvbiBkYXRhIGZvciBnZW5lcmljcy9hcnJheXMuCiAgICAgICAgaWYgKCFsb2NhdGlvbi5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgc2IuYXBwZW5kKCIsIGxvY2F0aW9uID0gKCIpOwogICAgICAgICAgICBzYi5hcHBlbmQobG9jYXRpb24pOwogICAgICAgICAgICBzYi5hcHBlbmQoIikiKTsKICAgICAgICB9CgogICAgICAgIHNiLmFwcGVuZCgiLCBwb3MgPSAiKTsKICAgICAgICBzYi5hcHBlbmQocG9zKTsKCiAgICAgICAgaWYgKG9uTGFtYmRhICE9IG51bGwpIHsKICAgICAgICAgICAgc2IuYXBwZW5kKCIsIG9uTGFtYmRhIGhhc2ggPSAiKTsKICAgICAgICAgICAgc2IuYXBwZW5kKG9uTGFtYmRhLmhhc2hDb2RlKCkpOwogICAgICAgIH0KCiAgICAgICAgc2IuYXBwZW5kKCddJyk7CiAgICAgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGUgdGFyZ2V0IHRyZWUgb2YgdGhlIGFubm90YXRpb24gaGFzIGJlZW4gb3B0aW1pemVkCiAgICAgKiBhd2F5IGZyb20gY2xhc3NmaWxlIG9yIG5vdC4KICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgdGFyZ2V0IGhhcyBub3QgYmVlbiBvcHRpbWl6ZWQgYXdheQogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBlbWl0VG9DbGFzc2ZpbGUoKSB7CiAgICAgICAgcmV0dXJuICF0eXBlLmlzTG9jYWwoKSB8fCBpc1ZhbGlkT2Zmc2V0OwogICAgfQoKCiAgICBwdWJsaWMgYm9vbGVhbiBtYXRjaGVzUG9zKGludCBwb3MpIHsKICAgICAgICByZXR1cm4gdGhpcy5wb3MgPT0gcG9zOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHVwZGF0ZVBvc09mZnNldChpbnQgdG8pIHsKICAgICAgICBvZmZzZXQgPSB0bzsKICAgICAgICBsdmFyT2Zmc2V0ID0gbmV3IGludFtde3RvfTsKICAgICAgICBpc1ZhbGlkT2Zmc2V0ID0gdHJ1ZTsKICAgIH0KCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNFeGNlcHRpb25JbmRleCgpIHsKICAgICAgICByZXR1cm4gZXhjZXB0aW9uX2luZGV4ID49IDA7CiAgICB9CgogICAgcHVibGljIGludCBnZXRFeGNlcHRpb25JbmRleCgpIHsKICAgICAgICBBc3NlcnQuY2hlY2soZXhjZXB0aW9uX2luZGV4ID49IDAsICJleGNlcHRpb25faW5kZXggaXMgbm90IHNldCIpOwogICAgICAgIHJldHVybiBleGNlcHRpb25faW5kZXg7CiAgICB9CgogICAgcHVibGljIHZvaWQgc2V0RXhjZXB0aW9uSW5kZXgoZmluYWwgaW50IGV4Y2VwdGlvbl9pbmRleCkgewogICAgICAgIEFzc2VydC5jaGVjayghaGFzRXhjZXB0aW9uSW5kZXgoKSwgImV4Y2VwdGlvbl9pbmRleCBhbHJlYWR5IHNldCIpOwogICAgICAgIEFzc2VydC5jaGVjayhleGNlcHRpb25faW5kZXggPj0gMCwgIkV4cGVjdGVkIGEgdmFsaWQgaW5kZXggaW50byBleGNlcHRpb24gdGFibGUiKTsKICAgICAgICB0aGlzLmV4Y2VwdGlvbl9pbmRleCA9IGV4Y2VwdGlvbl9pbmRleDsKICAgIH0KCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNDYXRjaFR5cGUoKSB7CiAgICAgICAgcmV0dXJuIGV4Y2VwdGlvbl9pbmRleCA8IDAgJiYgZXhjZXB0aW9uX2luZGV4ICE9IEludGVnZXIuTUlOX1ZBTFVFOwogICAgfQoKICAgIHB1YmxpYyBpbnQgZ2V0Q2F0Y2hUeXBlKCkgewogICAgICAgIEFzc2VydC5jaGVjayhoYXNDYXRjaFR5cGUoKSwKICAgICAgICAgICAgICAgICAgICAgImV4Y2VwdGlvbl9pbmRleCBkb2VzIG5vdCBjb250YWluIHZhbGlkIGNhdGNoIGluZm8iKTsKICAgICAgICByZXR1cm4gKCgtdGhpcy5leGNlcHRpb25faW5kZXgpIC0gMSkgJiAweGZmIDsKICAgIH0KCiAgICBwdWJsaWMgaW50IGdldFN0YXJ0UG9zKCkgewogICAgICAgIEFzc2VydC5jaGVjayhoYXNDYXRjaFR5cGUoKSwKICAgICAgICAgICAgICAgICAgICAgImV4Y2VwdGlvbl9pbmRleCBkb2VzIG5vdCBjb250YWluIHZhbGlkIGNhdGNoIGluZm8iKTsKICAgICAgICByZXR1cm4gKCgtdGhpcy5leGNlcHRpb25faW5kZXgpIC0gMSkgPj4gOCA7CiAgICB9CgogICAgcHVibGljIHZvaWQgc2V0Q2F0Y2hJbmZvKGZpbmFsIGludCBjYXRjaFR5cGUsIGZpbmFsIGludCBzdGFydFBvcykgewogICAgICAgIEFzc2VydC5jaGVjayghaGFzRXhjZXB0aW9uSW5kZXgoKSwKICAgICAgICAgICAgICAgICAgICAgImV4Y2VwdGlvbl9pbmRleCBpcyBhbHJlYWR5IHNldCIpOwogICAgICAgIEFzc2VydC5jaGVjayhjYXRjaFR5cGUgPj0gMCwgIkV4cGVjdGVkIGEgdmFsaWQgY2F0Y2ggdHlwZSIpOwogICAgICAgIHRoaXMuZXhjZXB0aW9uX2luZGV4ID0gLSgoY2F0Y2hUeXBlIHwgc3RhcnRQb3MgPDwgOCkgKyAxKTsKICAgIH0KCiAgICAvKioKICAgICAqIERlY29kZSB0aGUgYmluYXJ5IHJlcHJlc2VudGF0aW9uIGZvciBhIHR5cGUgcGF0aCBhbmQgc2V0CiAgICAgKiB0aGUge0Bjb2RlIGxvY2F0aW9ufSBmaWVsZC4KICAgICAqCiAgICAgKiBAcGFyYW0gbGlzdCBUaGUgYnl0ZWNvZGUgcmVwcmVzZW50YXRpb24gb2YgdGhlIHR5cGUgcGF0aC4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBMaXN0PFR5cGVQYXRoRW50cnk+IGdldFR5cGVQYXRoRnJvbUJpbmFyeShqYXZhLnV0aWwuTGlzdDxJbnRlZ2VyPiBsaXN0KSB7CiAgICAgICAgTGlzdEJ1ZmZlcjxUeXBlUGF0aEVudHJ5PiBsb2MgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgSXRlcmF0b3I8SW50ZWdlcj4gaXRlciA9IGxpc3QuaXRlcmF0b3IoKTsKICAgICAgICB3aGlsZSAoaXRlci5oYXNOZXh0KCkpIHsKICAgICAgICAgICAgSW50ZWdlciBmc3QgPSBpdGVyLm5leHQoKTsKICAgICAgICAgICAgQXNzZXJ0LmNoZWNrKGl0ZXIuaGFzTmV4dCgpKTsKICAgICAgICAgICAgSW50ZWdlciBzbmQgPSBpdGVyLm5leHQoKTsKICAgICAgICAgICAgbG9jID0gbG9jLmFwcGVuZChUeXBlUGF0aEVudHJ5LmZyb21CaW5hcnkoZnN0LCBzbmQpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGxvYy50b0xpc3QoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIExpc3Q8SW50ZWdlcj4gZ2V0QmluYXJ5RnJvbVR5cGVQYXRoKGphdmEudXRpbC5MaXN0PFR5cGVQYXRoRW50cnk+IGxvY3MpIHsKICAgICAgICBMaXN0QnVmZmVyPEludGVnZXI+IGxvYyA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICBmb3IgKFR5cGVQYXRoRW50cnkgdHBlIDogbG9jcykgewogICAgICAgICAgICBsb2MgPSBsb2MuYXBwZW5kKHRwZS50YWcudGFnKTsKICAgICAgICAgICAgbG9jID0gbG9jLmFwcGVuZCh0cGUuYXJnKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGxvYy50b0xpc3QoKTsKICAgIH0KCiAgICAvLyBUaGVzZSBtZXRob2RzIGFyZSB0aGUgbmV3IHByZWZlcnJlZCB3YXkgdG8gY3JlYXRlCiAgICAvLyBUeXBlQW5ub3RhdGlvblBvc2l0aW9ucwoKICAgIC8vIE5ldmVyIG1ha2UgdGhpcyBhIHB1YmxpYyBjb25zdHJ1Y3RvciB3aXRob3V0IGNyZWF0aW5nIGEgYnVpbGRlci4KICAgIHByaXZhdGUgVHlwZUFubm90YXRpb25Qb3NpdGlvbihmaW5hbCBUYXJnZXRUeXBlIHR0eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGludCBwb3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IHBhcmFtZXRlcl9pbmRleCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBKQ0xhbWJkYSBvbkxhbWJkYSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgdHlwZV9pbmRleCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgYm91bmRfaW5kZXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgTGlzdDxUeXBlUGF0aEVudHJ5PiBsb2NhdGlvbikgewogICAgICAgIEFzc2VydC5jaGVja05vbk51bGwobG9jYXRpb24pOwogICAgICAgIHRoaXMudHlwZSA9IHR0eXBlOwogICAgICAgIHRoaXMucG9zID0gcG9zOwogICAgICAgIHRoaXMucGFyYW1ldGVyX2luZGV4ID0gcGFyYW1ldGVyX2luZGV4OwogICAgICAgIHRoaXMub25MYW1iZGEgPSBvbkxhbWJkYTsKICAgICAgICB0aGlzLnR5cGVfaW5kZXggPSB0eXBlX2luZGV4OwogICAgICAgIHRoaXMuYm91bmRfaW5kZXggPSBib3VuZF9pbmRleDsKICAgICAgICB0aGlzLmxvY2F0aW9uID0gbG9jYXRpb247CiAgICB9CgogICAgLyoqCiAgICAgKiBDcmVhdGUgYSB7QGNvZGUgVHlwZUFubm90YXRpb25Qb3NpdGlvbn0gZm9yIGEgbWV0aG9kIHJldHVybi4KICAgICAqCiAgICAgKiBAcGFyYW0gbG9jYXRpb24gVGhlIHR5cGUgcGF0aC4KICAgICAqIEBwYXJhbSBvbkxhbWJkYSBUaGUgbGFtYmRhIGZvciB0aGlzIHBhcmFtZXRlci4KICAgICAqIEBwYXJhbSBwb3MgVGhlIHBvc2l0aW9uIGZyb20gdGhlIGFzc29jaWF0ZWQgdHJlZSBub2RlLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIFR5cGVBbm5vdGF0aW9uUG9zaXRpb24KICAgICAgICBtZXRob2RSZXR1cm4oZmluYWwgTGlzdDxUeXBlUGF0aEVudHJ5PiBsb2NhdGlvbiwKICAgICAgICAgICAgICAgICAgICAgZmluYWwgSkNMYW1iZGEgb25MYW1iZGEsCiAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGludCBwb3MpIHsKICAgICAgICByZXR1cm4gbmV3IFR5cGVBbm5vdGF0aW9uUG9zaXRpb24oVGFyZ2V0VHlwZS5NRVRIT0RfUkVUVVJOLCBwb3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEludGVnZXIuTUlOX1ZBTFVFLCBvbkxhbWJkYSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW50ZWdlci5NSU5fVkFMVUUsIEludGVnZXIuTUlOX1ZBTFVFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2NhdGlvbik7CiAgICB9CgogICAgLyoqCiAgICAgKiBDcmVhdGUgYSB7QGNvZGUgVHlwZUFubm90YXRpb25Qb3NpdGlvbn0gZm9yIGEgbWV0aG9kIHJldHVybi4KICAgICAqCiAgICAgKiBAcGFyYW0gbG9jYXRpb24gVGhlIHR5cGUgcGF0aC4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBUeXBlQW5ub3RhdGlvblBvc2l0aW9uCiAgICAgICAgbWV0aG9kUmV0dXJuKGZpbmFsIExpc3Q8VHlwZVBhdGhFbnRyeT4gbG9jYXRpb24pIHsKICAgICAgICByZXR1cm4gbWV0aG9kUmV0dXJuKGxvY2F0aW9uLCBudWxsLCAtMSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDcmVhdGUgYSB7QGNvZGUgVHlwZUFubm90YXRpb25Qb3NpdGlvbn0gZm9yIGEgbWV0aG9kIHJldHVybi4KICAgICAqCiAgICAgKiBAcGFyYW0gcG9zIFRoZSBwb3NpdGlvbiBmcm9tIHRoZSBhc3NvY2lhdGVkIHRyZWUgbm9kZS4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBUeXBlQW5ub3RhdGlvblBvc2l0aW9uIG1ldGhvZFJldHVybihmaW5hbCBpbnQgcG9zKSB7CiAgICAgICAgcmV0dXJuIG1ldGhvZFJldHVybihlbXB0eVBhdGgsIG51bGwsIHBvcyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDcmVhdGUgYSB7QGNvZGUgVHlwZUFubm90YXRpb25Qb3NpdGlvbn0gZm9yIGEgbWV0aG9kIHJlY2VpdmVyIHBhcmFtZXRlci4KICAgICAqCiAgICAgKiBAcGFyYW0gbG9jYXRpb24gVGhlIHR5cGUgcGF0aC4KICAgICAqIEBwYXJhbSBvbkxhbWJkYSBUaGUgbGFtYmRhIGZvciB0aGlzIHBhcmFtZXRlci4KICAgICAqIEBwYXJhbSBwb3MgVGhlIHBvc2l0aW9uIGZyb20gdGhlIGFzc29jaWF0ZWQgdHJlZSBub2RlLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIFR5cGVBbm5vdGF0aW9uUG9zaXRpb24KICAgICAgICBtZXRob2RSZWNlaXZlcihmaW5hbCBMaXN0PFR5cGVQYXRoRW50cnk+IGxvY2F0aW9uLAogICAgICAgICAgICAgICAgICAgICBmaW5hbCBKQ0xhbWJkYSBvbkxhbWJkYSwKICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IHBvcykgewogICAgICAgIHJldHVybiBuZXcgVHlwZUFubm90YXRpb25Qb3NpdGlvbihUYXJnZXRUeXBlLk1FVEhPRF9SRUNFSVZFUiwgcG9zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbnRlZ2VyLk1JTl9WQUxVRSwgb25MYW1iZGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEludGVnZXIuTUlOX1ZBTFVFLCBJbnRlZ2VyLk1JTl9WQUxVRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9jYXRpb24pOwogICAgfQoKICAgIC8qKgogICAgICogQ3JlYXRlIGEge0Bjb2RlIFR5cGVBbm5vdGF0aW9uUG9zaXRpb259IGZvciBhIG1ldGhvZCByZWNlaXZlciBwYXJhbWV0ZXIuCiAgICAgKgogICAgICogQHBhcmFtIGxvY2F0aW9uIFRoZSB0eXBlIHBhdGguCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgVHlwZUFubm90YXRpb25Qb3NpdGlvbgogICAgICAgIG1ldGhvZFJlY2VpdmVyKGZpbmFsIExpc3Q8VHlwZVBhdGhFbnRyeT4gbG9jYXRpb24pIHsKICAgICAgICByZXR1cm4gbWV0aG9kUmVjZWl2ZXIobG9jYXRpb24sIG51bGwsIC0xKTsKICAgIH0KCiAgICAvKioKICAgICAqIENyZWF0ZSBhIHtAY29kZSBUeXBlQW5ub3RhdGlvblBvc2l0aW9ufSBmb3IgYSBtZXRob2QgcmVjZWl2ZXIgcGFyYW1ldGVyLgogICAgICoKICAgICAqIEBwYXJhbSBwb3MgVGhlIHBvc2l0aW9uIGZyb20gdGhlIGFzc29jaWF0ZWQgdHJlZSBub2RlLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIFR5cGVBbm5vdGF0aW9uUG9zaXRpb24gbWV0aG9kUmVjZWl2ZXIoZmluYWwgaW50IHBvcykgewogICAgICAgIHJldHVybiBtZXRob2RSZWNlaXZlcihlbXB0eVBhdGgsIG51bGwsIHBvcyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDcmVhdGUgYSB7QGNvZGUgVHlwZUFubm90YXRpb25Qb3NpdGlvbn0gZm9yIGEgbWV0aG9kIGZvcm1hbCBwYXJhbWV0ZXIuCiAgICAgKgogICAgICogQHBhcmFtIGxvY2F0aW9uIFRoZSB0eXBlIHBhdGguCiAgICAgKiBAcGFyYW0gb25MYW1iZGEgVGhlIGxhbWJkYSBmb3IgdGhpcyBwYXJhbWV0ZXIuCiAgICAgKiBAcGFyYW0gcGFyYW1ldGVyX2luZGV4IFRoZSBpbmRleCBvZiB0aGUgcGFyYW1ldGVyLgogICAgICogQHBhcmFtIHBvcyBUaGUgcG9zaXRpb24gZnJvbSB0aGUgYXNzb2NpYXRlZCB0cmVlIG5vZGUuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgVHlwZUFubm90YXRpb25Qb3NpdGlvbgogICAgICAgIG1ldGhvZFBhcmFtZXRlcihmaW5hbCBMaXN0PFR5cGVQYXRoRW50cnk+IGxvY2F0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBKQ0xhbWJkYSBvbkxhbWJkYSwKICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IHBhcmFtZXRlcl9pbmRleCwKICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IHBvcykgewogICAgICAgIHJldHVybiBuZXcgVHlwZUFubm90YXRpb25Qb3NpdGlvbihUYXJnZXRUeXBlLk1FVEhPRF9GT1JNQUxfUEFSQU1FVEVSLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb3MsIHBhcmFtZXRlcl9pbmRleCwgb25MYW1iZGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEludGVnZXIuTUlOX1ZBTFVFLCBJbnRlZ2VyLk1JTl9WQUxVRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9jYXRpb24pOwogICAgfQoKICAgIC8qKgogICAgICogQ3JlYXRlIGEge0Bjb2RlIFR5cGVBbm5vdGF0aW9uUG9zaXRpb259IGZvciBhIG1ldGhvZCBmb3JtYWwgcGFyYW1ldGVyLgogICAgICoKICAgICAqIEBwYXJhbSBvbkxhbWJkYSBUaGUgbGFtYmRhIGZvciB0aGlzIHBhcmFtZXRlci4KICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJfaW5kZXggVGhlIGluZGV4IG9mIHRoZSBwYXJhbWV0ZXIuCiAgICAgKiBAcGFyYW0gcG9zIFRoZSBwb3NpdGlvbiBmcm9tIHRoZSBhc3NvY2lhdGVkIHRyZWUgbm9kZS4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBUeXBlQW5ub3RhdGlvblBvc2l0aW9uCiAgICAgICAgbWV0aG9kUGFyYW1ldGVyKGZpbmFsIEpDTGFtYmRhIG9uTGFtYmRhLAogICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgcGFyYW1ldGVyX2luZGV4LAogICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgcG9zKSB7CiAgICAgICAgcmV0dXJuIG1ldGhvZFBhcmFtZXRlcihlbXB0eVBhdGgsIG9uTGFtYmRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyYW1ldGVyX2luZGV4LCBwb3MpOwogICAgfQoKICAgIC8qKgogICAgICogQ3JlYXRlIGEge0Bjb2RlIFR5cGVBbm5vdGF0aW9uUG9zaXRpb259IGZvciBhIG1ldGhvZCBmb3JtYWwgcGFyYW1ldGVyLgogICAgICoKICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJfaW5kZXggVGhlIGluZGV4IG9mIHRoZSBwYXJhbWV0ZXIuCiAgICAgKiBAcGFyYW0gcG9zIFRoZSBwb3NpdGlvbiBmcm9tIHRoZSBhc3NvY2lhdGVkIHRyZWUgbm9kZS4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBUeXBlQW5ub3RhdGlvblBvc2l0aW9uCiAgICAgICAgbWV0aG9kUGFyYW1ldGVyKGZpbmFsIGludCBwYXJhbWV0ZXJfaW5kZXgsCiAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGludCBwb3MpIHsKICAgICAgICByZXR1cm4gbWV0aG9kUGFyYW1ldGVyKG51bGwsIHBhcmFtZXRlcl9pbmRleCwgcG9zKTsKICAgIH0KCiAgICAvKioKICAgICAqIENyZWF0ZSBhIHtAY29kZSBUeXBlQW5ub3RhdGlvblBvc2l0aW9ufSBmb3IgYSBtZXRob2QgZm9ybWFsIHBhcmFtZXRlci4KICAgICAqCiAgICAgKiBAcGFyYW0gbG9jYXRpb24gVGhlIHR5cGUgcGF0aC4KICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJfaW5kZXggVGhlIGluZGV4IG9mIHRoZSBwYXJhbWV0ZXIuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgVHlwZUFubm90YXRpb25Qb3NpdGlvbgogICAgICAgIG1ldGhvZFBhcmFtZXRlcihmaW5hbCBMaXN0PFR5cGVQYXRoRW50cnk+IGxvY2F0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgcGFyYW1ldGVyX2luZGV4KSB7CiAgICAgICAgcmV0dXJuIG1ldGhvZFBhcmFtZXRlcihsb2NhdGlvbiwgbnVsbCwgcGFyYW1ldGVyX2luZGV4LCAtMSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDcmVhdGUgYSB7QGNvZGUgVHlwZUFubm90YXRpb25Qb3NpdGlvbn0gZm9yIGEgbWV0aG9kIHJlZmVyZW5jZS4KICAgICAqCiAgICAgKiBAcGFyYW0gbG9jYXRpb24gVGhlIHR5cGUgcGF0aC4KICAgICAqIEBwYXJhbSBvbkxhbWJkYSBUaGUgbGFtYmRhIGZvciB0aGlzIG1ldGhvZCByZWZlcmVuY2UuCiAgICAgKiBAcGFyYW0gcG9zIFRoZSBwb3NpdGlvbiBmcm9tIHRoZSBhc3NvY2lhdGVkIHRyZWUgbm9kZS4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBUeXBlQW5ub3RhdGlvblBvc2l0aW9uCiAgICAgICAgbWV0aG9kUmVmKGZpbmFsIExpc3Q8VHlwZVBhdGhFbnRyeT4gbG9jYXRpb24sCiAgICAgICAgICAgICAgICAgIGZpbmFsIEpDTGFtYmRhIG9uTGFtYmRhLAogICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgcG9zKSB7CiAgICAgICAgcmV0dXJuIG5ldyBUeXBlQW5ub3RhdGlvblBvc2l0aW9uKFRhcmdldFR5cGUuTUVUSE9EX1JFRkVSRU5DRSwgcG9zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbnRlZ2VyLk1JTl9WQUxVRSwgb25MYW1iZGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEludGVnZXIuTUlOX1ZBTFVFLCBJbnRlZ2VyLk1JTl9WQUxVRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9jYXRpb24pOwogICAgfQoKICAgIC8qKgogICAgICogQ3JlYXRlIGEge0Bjb2RlIFR5cGVBbm5vdGF0aW9uUG9zaXRpb259IGZvciBhIG1ldGhvZCByZWZlcmVuY2UuCiAgICAgKgogICAgICogQHBhcmFtIGxvY2F0aW9uIFRoZSB0eXBlIHBhdGguCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgVHlwZUFubm90YXRpb25Qb3NpdGlvbgogICAgICAgIG1ldGhvZFJlZihmaW5hbCBMaXN0PFR5cGVQYXRoRW50cnk+IGxvY2F0aW9uKSB7CiAgICAgICAgcmV0dXJuIG1ldGhvZFJlZihsb2NhdGlvbiwgbnVsbCwgLTEpOwogICAgfQoKICAgIC8qKgogICAgICogQ3JlYXRlIGEge0Bjb2RlIFR5cGVBbm5vdGF0aW9uUG9zaXRpb259IGZvciBhIGNvbnN0cnVjdG9yIHJlZmVyZW5jZS4KICAgICAqCiAgICAgKiBAcGFyYW0gbG9jYXRpb24gVGhlIHR5cGUgcGF0aC4KICAgICAqIEBwYXJhbSBvbkxhbWJkYSBUaGUgbGFtYmRhIGZvciB0aGlzIGNvbnN0cnVjdG9yIHJlZmVyZW5jZS4KICAgICAqIEBwYXJhbSBwb3MgVGhlIHBvc2l0aW9uIGZyb20gdGhlIGFzc29jaWF0ZWQgdHJlZSBub2RlLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIFR5cGVBbm5vdGF0aW9uUG9zaXRpb24KICAgICAgICBjb25zdHJ1Y3RvclJlZihmaW5hbCBMaXN0PFR5cGVQYXRoRW50cnk+IGxvY2F0aW9uLAogICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIEpDTGFtYmRhIG9uTGFtYmRhLAogICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGludCBwb3MpIHsKICAgICAgICByZXR1cm4gbmV3IFR5cGVBbm5vdGF0aW9uUG9zaXRpb24oVGFyZ2V0VHlwZS5DT05TVFJVQ1RPUl9SRUZFUkVOQ0UsIHBvcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW50ZWdlci5NSU5fVkFMVUUsIG9uTGFtYmRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbnRlZ2VyLk1JTl9WQUxVRSwgSW50ZWdlci5NSU5fVkFMVUUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvY2F0aW9uKTsKICAgIH0KCiAgICAvKioKICAgICAqIENyZWF0ZSBhIHtAY29kZSBUeXBlQW5ub3RhdGlvblBvc2l0aW9ufSBmb3IgYSBjb25zdHJ1Y3RvciByZWZlcmVuY2UuCiAgICAgKgogICAgICogQHBhcmFtIGxvY2F0aW9uIFRoZSB0eXBlIHBhdGguCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgVHlwZUFubm90YXRpb25Qb3NpdGlvbgogICAgICAgIGNvbnN0cnVjdG9yUmVmKGZpbmFsIExpc3Q8VHlwZVBhdGhFbnRyeT4gbG9jYXRpb24pIHsKICAgICAgICByZXR1cm4gY29uc3RydWN0b3JSZWYobG9jYXRpb24sIG51bGwsIC0xKTsKICAgIH0KCiAgICAvKioKICAgICAqIENyZWF0ZSBhIHtAY29kZSBUeXBlQW5ub3RhdGlvblBvc2l0aW9ufSBmb3IgYSBmaWVsZC4KICAgICAqCiAgICAgKiBAcGFyYW0gbG9jYXRpb24gVGhlIHR5cGUgcGF0aC4KICAgICAqIEBwYXJhbSBvbkxhbWJkYSBUaGUgbGFtYmRhIGZvciB0aGlzIHZhcmlhYmxlLgogICAgICogQHBhcmFtIHBvcyBUaGUgcG9zaXRpb24gZnJvbSB0aGUgYXNzb2NpYXRlZCB0cmVlIG5vZGUuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgVHlwZUFubm90YXRpb25Qb3NpdGlvbgogICAgICAgIGZpZWxkKGZpbmFsIExpc3Q8VHlwZVBhdGhFbnRyeT4gbG9jYXRpb24sCiAgICAgICAgICAgICAgZmluYWwgSkNMYW1iZGEgb25MYW1iZGEsCiAgICAgICAgICAgICAgZmluYWwgaW50IHBvcykgewogICAgICAgIHJldHVybiBuZXcgVHlwZUFubm90YXRpb25Qb3NpdGlvbihUYXJnZXRUeXBlLkZJRUxELCBwb3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEludGVnZXIuTUlOX1ZBTFVFLCBvbkxhbWJkYSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW50ZWdlci5NSU5fVkFMVUUsIEludGVnZXIuTUlOX1ZBTFVFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2NhdGlvbik7CiAgICB9CgogICAgLyoqCiAgICAgKiBDcmVhdGUgYSB7QGNvZGUgVHlwZUFubm90YXRpb25Qb3NpdGlvbn0gZm9yIGEgZmllbGQuCiAgICAgKgogICAgICogQHBhcmFtIGxvY2F0aW9uIFRoZSB0eXBlIHBhdGguCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgVHlwZUFubm90YXRpb25Qb3NpdGlvbgogICAgICAgIGZpZWxkKGZpbmFsIExpc3Q8VHlwZVBhdGhFbnRyeT4gbG9jYXRpb24pIHsKICAgICAgICByZXR1cm4gZmllbGQobG9jYXRpb24sIG51bGwsIC0xKTsKICAgIH0KCiAgICAvKioKICAgICAqIENyZWF0ZSBhIHtAY29kZSBUeXBlQW5ub3RhdGlvblBvc2l0aW9ufSBmb3IgYSBmaWVsZC4KICAgICAqCiAgICAgKiBAcGFyYW0gcG9zIFRoZSBwb3NpdGlvbiBmcm9tIHRoZSBhc3NvY2lhdGVkIHRyZWUgbm9kZS4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBUeXBlQW5ub3RhdGlvblBvc2l0aW9uIGZpZWxkKGZpbmFsIGludCBwb3MpIHsKICAgICAgICByZXR1cm4gZmllbGQoZW1wdHlQYXRoLCBudWxsLCBwb3MpOwogICAgfQoKICAgIC8qKgogICAgICogQ3JlYXRlIGEge0Bjb2RlIFR5cGVBbm5vdGF0aW9uUG9zaXRpb259IGZvciBhIGxvY2FsIHZhcmlhYmxlLgogICAgICoKICAgICAqIEBwYXJhbSBsb2NhdGlvbiBUaGUgdHlwZSBwYXRoLgogICAgICogQHBhcmFtIG9uTGFtYmRhIFRoZSBsYW1iZGEgZm9yIHRoaXMgdmFyaWFibGUuCiAgICAgKiBAcGFyYW0gcG9zIFRoZSBwb3NpdGlvbiBmcm9tIHRoZSBhc3NvY2lhdGVkIHRyZWUgbm9kZS4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBUeXBlQW5ub3RhdGlvblBvc2l0aW9uCiAgICAgICAgbG9jYWxWYXJpYWJsZShmaW5hbCBMaXN0PFR5cGVQYXRoRW50cnk+IGxvY2F0aW9uLAogICAgICAgICAgICAgICAgICAgICAgZmluYWwgSkNMYW1iZGEgb25MYW1iZGEsCiAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgcG9zKSB7CiAgICAgICAgcmV0dXJuIG5ldyBUeXBlQW5ub3RhdGlvblBvc2l0aW9uKFRhcmdldFR5cGUuTE9DQUxfVkFSSUFCTEUsIHBvcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW50ZWdlci5NSU5fVkFMVUUsIG9uTGFtYmRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbnRlZ2VyLk1JTl9WQUxVRSwgSW50ZWdlci5NSU5fVkFMVUUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvY2F0aW9uKTsKICAgIH0KCiAgICAvKioKICAgICAqIENyZWF0ZSBhIHtAY29kZSBUeXBlQW5ub3RhdGlvblBvc2l0aW9ufSBmb3IgYSBsb2NhbCB2YXJpYWJsZS4KICAgICAqCiAgICAgKiBAcGFyYW0gb25MYW1iZGEgVGhlIGxhbWJkYSBmb3IgdGhpcyB2YXJpYWJsZS4KICAgICAqIEBwYXJhbSBwb3MgVGhlIHBvc2l0aW9uIGZyb20gdGhlIGFzc29jaWF0ZWQgdHJlZSBub2RlLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIFR5cGVBbm5vdGF0aW9uUG9zaXRpb24KICAgICAgICBsb2NhbFZhcmlhYmxlKGZpbmFsIEpDTGFtYmRhIG9uTGFtYmRhLAogICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IHBvcykgewogICAgICAgIHJldHVybiBsb2NhbFZhcmlhYmxlKGVtcHR5UGF0aCwgb25MYW1iZGEsIHBvcyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDcmVhdGUgYSB7QGNvZGUgVHlwZUFubm90YXRpb25Qb3NpdGlvbn0gZm9yIGEgbG9jYWwgdmFyaWFibGUuCiAgICAgKgogICAgICogQHBhcmFtIGxvY2F0aW9uIFRoZSB0eXBlIHBhdGguCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgVHlwZUFubm90YXRpb25Qb3NpdGlvbgogICAgICAgIGxvY2FsVmFyaWFibGUoZmluYWwgTGlzdDxUeXBlUGF0aEVudHJ5PiBsb2NhdGlvbikgewogICAgICAgIHJldHVybiBsb2NhbFZhcmlhYmxlKGxvY2F0aW9uLCBudWxsLCAtMSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDcmVhdGUgYSB7QGNvZGUgVHlwZUFubm90YXRpb25Qb3NpdGlvbn0gZm9yIGFuIGV4Y2VwdGlvbiBwYXJhbWV0ZXIuCiAgICAgKgogICAgICogQHBhcmFtIGxvY2F0aW9uIFRoZSB0eXBlIHBhdGguCiAgICAgKiBAcGFyYW0gb25MYW1iZGEgVGhlIGxhbWJkYSBmb3IgdGhpcyBwYXJhbWV0ZXIuCiAgICAgKiBAcGFyYW0gcG9zIFRoZSBwb3NpdGlvbiBmcm9tIHRoZSBhc3NvY2lhdGVkIHRyZWUgbm9kZS4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBUeXBlQW5ub3RhdGlvblBvc2l0aW9uCiAgICAgICAgZXhjZXB0aW9uUGFyYW1ldGVyKGZpbmFsIExpc3Q8VHlwZVBhdGhFbnRyeT4gbG9jYXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIEpDTGFtYmRhIG9uTGFtYmRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgcG9zKSB7CiAgICAgICAgcmV0dXJuIG5ldyBUeXBlQW5ub3RhdGlvblBvc2l0aW9uKFRhcmdldFR5cGUuRVhDRVBUSU9OX1BBUkFNRVRFUiwgcG9zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbnRlZ2VyLk1JTl9WQUxVRSwgb25MYW1iZGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEludGVnZXIuTUlOX1ZBTFVFLCBJbnRlZ2VyLk1JTl9WQUxVRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9jYXRpb24pOwogICAgfQoKICAgIC8qKgogICAgICogQ3JlYXRlIGEge0Bjb2RlIFR5cGVBbm5vdGF0aW9uUG9zaXRpb259IGZvciBhbiBleGNlcHRpb24gcGFyYW1ldGVyLgogICAgICoKICAgICAqIEBwYXJhbSBvbkxhbWJkYSBUaGUgbGFtYmRhIGZvciB0aGlzIHBhcmFtZXRlci4KICAgICAqIEBwYXJhbSBwb3MgVGhlIHBvc2l0aW9uIGZyb20gdGhlIGFzc29jaWF0ZWQgdHJlZSBub2RlLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIFR5cGVBbm5vdGF0aW9uUG9zaXRpb24KICAgICAgICBleGNlcHRpb25QYXJhbWV0ZXIoZmluYWwgSkNMYW1iZGEgb25MYW1iZGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGludCBwb3MpIHsKICAgICAgICByZXR1cm4gZXhjZXB0aW9uUGFyYW1ldGVyKGVtcHR5UGF0aCwgb25MYW1iZGEsIHBvcyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDcmVhdGUgYSB7QGNvZGUgVHlwZUFubm90YXRpb25Qb3NpdGlvbn0gZm9yIGFuIGV4Y2VwdGlvbiBwYXJhbWV0ZXIuCiAgICAgKgogICAgICogQHBhcmFtIGxvY2F0aW9uIFRoZSB0eXBlIHBhdGguCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgVHlwZUFubm90YXRpb25Qb3NpdGlvbgogICAgICAgIGV4Y2VwdGlvblBhcmFtZXRlcihmaW5hbCBMaXN0PFR5cGVQYXRoRW50cnk+IGxvY2F0aW9uKSB7CiAgICAgICAgcmV0dXJuIGV4Y2VwdGlvblBhcmFtZXRlcihsb2NhdGlvbiwgbnVsbCwgLTEpOwogICAgfQoKCiAgICAvKioKICAgICAqIENyZWF0ZSBhIHtAY29kZSBUeXBlQW5ub3RhdGlvblBvc2l0aW9ufSBmb3IgYSByZXNvdXJjZSB2YXJpYWJsZS4KICAgICAqCiAgICAgKiBAcGFyYW0gbG9jYXRpb24gVGhlIHR5cGUgcGF0aC4KICAgICAqIEBwYXJhbSBvbkxhbWJkYSBUaGUgbGFtYmRhIGZvciB0aGlzIHZhcmlhYmxlLgogICAgICogQHBhcmFtIHBvcyBUaGUgcG9zaXRpb24gZnJvbSB0aGUgYXNzb2NpYXRlZCB0cmVlIG5vZGUuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgVHlwZUFubm90YXRpb25Qb3NpdGlvbgogICAgICAgIHJlc291cmNlVmFyaWFibGUoZmluYWwgTGlzdDxUeXBlUGF0aEVudHJ5PiBsb2NhdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIEpDTGFtYmRhIG9uTGFtYmRhLAogICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IHBvcykgewogICAgICAgIHJldHVybiBuZXcgVHlwZUFubm90YXRpb25Qb3NpdGlvbihUYXJnZXRUeXBlLlJFU09VUkNFX1ZBUklBQkxFLCBwb3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEludGVnZXIuTUlOX1ZBTFVFLCBvbkxhbWJkYSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW50ZWdlci5NSU5fVkFMVUUsIEludGVnZXIuTUlOX1ZBTFVFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2NhdGlvbik7CiAgICB9CgogICAgLyoqCiAgICAgKiBDcmVhdGUgYSB7QGNvZGUgVHlwZUFubm90YXRpb25Qb3NpdGlvbn0gZm9yIGEgcmVzb3VyY2UgdmFyaWFibGUuCiAgICAgKgogICAgICogQHBhcmFtIG9uTGFtYmRhIFRoZSBsYW1iZGEgZm9yIHRoaXMgdmFyaWFibGUuCiAgICAgKiBAcGFyYW0gcG9zIFRoZSBwb3NpdGlvbiBmcm9tIHRoZSBhc3NvY2lhdGVkIHRyZWUgbm9kZS4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBUeXBlQW5ub3RhdGlvblBvc2l0aW9uCiAgICAgICAgcmVzb3VyY2VWYXJpYWJsZShmaW5hbCBKQ0xhbWJkYSBvbkxhbWJkYSwKICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGludCBwb3MpIHsKICAgICAgICByZXR1cm4gcmVzb3VyY2VWYXJpYWJsZShlbXB0eVBhdGgsIG9uTGFtYmRhLCBwb3MpOwogICAgfQoKICAgIC8qKgogICAgICogQ3JlYXRlIGEge0Bjb2RlIFR5cGVBbm5vdGF0aW9uUG9zaXRpb259IGZvciBhIHJlc291cmNlIHZhcmlhYmxlLgogICAgICoKICAgICAqIEBwYXJhbSBsb2NhdGlvbiBUaGUgdHlwZSBwYXRoLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIFR5cGVBbm5vdGF0aW9uUG9zaXRpb24KICAgICAgICByZXNvdXJjZVZhcmlhYmxlKGZpbmFsIExpc3Q8VHlwZVBhdGhFbnRyeT4gbG9jYXRpb24pIHsKICAgICAgICByZXR1cm4gcmVzb3VyY2VWYXJpYWJsZShsb2NhdGlvbiwgbnVsbCwgLTEpOwogICAgfQoKICAgIC8qKgogICAgICogQ3JlYXRlIGEge0Bjb2RlIFR5cGVBbm5vdGF0aW9uUG9zaXRpb259IGZvciBhIG5ldy4KICAgICAqCiAgICAgKiBAcGFyYW0gbG9jYXRpb24gVGhlIHR5cGUgcGF0aC4KICAgICAqIEBwYXJhbSBvbkxhbWJkYSBUaGUgbGFtYmRhIGZvciB0aGlzIHZhcmlhYmxlLgogICAgICogQHBhcmFtIHBvcyBUaGUgcG9zaXRpb24gZnJvbSB0aGUgYXNzb2NpYXRlZCB0cmVlIG5vZGUuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgVHlwZUFubm90YXRpb25Qb3NpdGlvbgogICAgICAgIG5ld09iaihmaW5hbCBMaXN0PFR5cGVQYXRoRW50cnk+IGxvY2F0aW9uLAogICAgICAgICAgICAgICBmaW5hbCBKQ0xhbWJkYSBvbkxhbWJkYSwKICAgICAgICAgICAgICAgZmluYWwgaW50IHBvcykgewogICAgICAgIHJldHVybiBuZXcgVHlwZUFubm90YXRpb25Qb3NpdGlvbihUYXJnZXRUeXBlLk5FVywgcG9zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbnRlZ2VyLk1JTl9WQUxVRSwgb25MYW1iZGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEludGVnZXIuTUlOX1ZBTFVFLCBJbnRlZ2VyLk1JTl9WQUxVRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9jYXRpb24pOwogICAgfQoKICAgIC8qKgogICAgICogQ3JlYXRlIGEge0Bjb2RlIFR5cGVBbm5vdGF0aW9uUG9zaXRpb259IGZvciBhIG5ldy4KICAgICAqCiAgICAgKiBAcGFyYW0gcG9zIFRoZSBwb3NpdGlvbiBmcm9tIHRoZSBhc3NvY2lhdGVkIHRyZWUgbm9kZS4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBUeXBlQW5ub3RhdGlvblBvc2l0aW9uIG5ld09iaihmaW5hbCBpbnQgcG9zKSB7CiAgICAgICAgcmV0dXJuIG5ld09iaihlbXB0eVBhdGgsIG51bGwsIHBvcyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDcmVhdGUgYSB7QGNvZGUgVHlwZUFubm90YXRpb25Qb3NpdGlvbn0gZm9yIGEgbmV3LgogICAgICoKICAgICAqIEBwYXJhbSBsb2NhdGlvbiBUaGUgdHlwZSBwYXRoLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIFR5cGVBbm5vdGF0aW9uUG9zaXRpb24KICAgICAgICBuZXdPYmooZmluYWwgTGlzdDxUeXBlUGF0aEVudHJ5PiBsb2NhdGlvbikgewogICAgICAgIHJldHVybiBuZXdPYmoobG9jYXRpb24sIG51bGwsIC0xKTsKICAgIH0KCiAgICAvKioKICAgICAqIENyZWF0ZSBhIHtAY29kZSBUeXBlQW5ub3RhdGlvblBvc2l0aW9ufSBmb3IgYSBjbGFzcyBleHRlbnNpb24uCiAgICAgKgogICAgICogQHBhcmFtIGxvY2F0aW9uIFRoZSB0eXBlIHBhdGguCiAgICAgKiBAcGFyYW0gb25MYW1iZGEgVGhlIGxhbWJkYSBmb3IgdGhpcyB2YXJpYWJsZS4KICAgICAqIEBwYXJhbSB0eXBlX2luZGV4IFRoZSBpbmRleCBvZiB0aGUgaW50ZXJmYWNlLgogICAgICogQHBhcmFtIHBvcyBUaGUgcG9zaXRpb24gZnJvbSB0aGUgYXNzb2NpYXRlZCB0cmVlIG5vZGUuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgVHlwZUFubm90YXRpb25Qb3NpdGlvbgogICAgICAgIGNsYXNzRXh0ZW5kcyhmaW5hbCBMaXN0PFR5cGVQYXRoRW50cnk+IGxvY2F0aW9uLAogICAgICAgICAgICAgICAgICAgICBmaW5hbCBKQ0xhbWJkYSBvbkxhbWJkYSwKICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IHR5cGVfaW5kZXgsCiAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGludCBwb3MpIHsKICAgICAgICByZXR1cm4gbmV3IFR5cGVBbm5vdGF0aW9uUG9zaXRpb24oVGFyZ2V0VHlwZS5DTEFTU19FWFRFTkRTLCBwb3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEludGVnZXIuTUlOX1ZBTFVFLCBvbkxhbWJkYSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZV9pbmRleCwgSW50ZWdlci5NSU5fVkFMVUUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvY2F0aW9uKTsKICAgIH0KCiAgICAvKioKICAgICAqIENyZWF0ZSBhIHtAY29kZSBUeXBlQW5ub3RhdGlvblBvc2l0aW9ufSBmb3IgYSBjbGFzcyBleHRlbnNpb24uCiAgICAgKgogICAgICogQHBhcmFtIGxvY2F0aW9uIFRoZSB0eXBlIHBhdGguCiAgICAgKiBAcGFyYW0gb25MYW1iZGEgVGhlIGxhbWJkYSBmb3IgdGhpcyB2YXJpYWJsZS4KICAgICAqIEBwYXJhbSBwb3MgVGhlIHBvc2l0aW9uIGZyb20gdGhlIGFzc29jaWF0ZWQgdHJlZSBub2RlLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIFR5cGVBbm5vdGF0aW9uUG9zaXRpb24KICAgICAgICBjbGFzc0V4dGVuZHMoZmluYWwgTGlzdDxUeXBlUGF0aEVudHJ5PiBsb2NhdGlvbiwKICAgICAgICAgICAgICAgICAgICAgZmluYWwgSkNMYW1iZGEgb25MYW1iZGEsCiAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGludCBwb3MpIHsKICAgICAgICByZXR1cm4gY2xhc3NFeHRlbmRzKGxvY2F0aW9uLCBvbkxhbWJkYSwgNjU1MzUsIHBvcyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDcmVhdGUgYSB7QGNvZGUgVHlwZUFubm90YXRpb25Qb3NpdGlvbn0gZm9yIGEgY2xhc3MgZXh0ZW5zaW9uLgogICAgICoKICAgICAqIEBwYXJhbSBsb2NhdGlvbiBUaGUgdHlwZSBwYXRoLgogICAgICogQHBhcmFtIHR5cGVfaW5kZXggVGhlIGluZGV4IG9mIHRoZSBpbnRlcmZhY2UuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgVHlwZUFubm90YXRpb25Qb3NpdGlvbgogICAgICAgIGNsYXNzRXh0ZW5kcyhmaW5hbCBMaXN0PFR5cGVQYXRoRW50cnk+IGxvY2F0aW9uLAogICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgdHlwZV9pbmRleCkgewogICAgICAgIHJldHVybiBjbGFzc0V4dGVuZHMobG9jYXRpb24sIG51bGwsIHR5cGVfaW5kZXgsIC0xKTsKICAgIH0KCiAgICAvKioKICAgICAqIENyZWF0ZSBhIHtAY29kZSBUeXBlQW5ub3RhdGlvblBvc2l0aW9ufSBmb3IgYSBjbGFzcyBleHRlbnNpb24uCiAgICAgKgogICAgICogQHBhcmFtIHR5cGVfaW5kZXggVGhlIGluZGV4IG9mIHRoZSBpbnRlcmZhY2UuCiAgICAgKiBAcGFyYW0gcG9zIFRoZSBwb3NpdGlvbiBmcm9tIHRoZSBhc3NvY2lhdGVkIHRyZWUgbm9kZS4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBUeXBlQW5ub3RhdGlvblBvc2l0aW9uIGNsYXNzRXh0ZW5kcyhmaW5hbCBpbnQgdHlwZV9pbmRleCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IHBvcykgewogICAgICAgIHJldHVybiBjbGFzc0V4dGVuZHMoZW1wdHlQYXRoLCBudWxsLCB0eXBlX2luZGV4LCBwb3MpOwogICAgfQoKICAgIC8qKgogICAgICogQ3JlYXRlIGEge0Bjb2RlIFR5cGVBbm5vdGF0aW9uUG9zaXRpb259IGZvciBhIGNsYXNzIGV4dGVuc2lvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gcG9zIFRoZSBwb3NpdGlvbiBmcm9tIHRoZSBhc3NvY2lhdGVkIHRyZWUgbm9kZS4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBUeXBlQW5ub3RhdGlvblBvc2l0aW9uIGNsYXNzRXh0ZW5kcyhmaW5hbCBpbnQgcG9zKSB7CiAgICAgICAgcmV0dXJuIGNsYXNzRXh0ZW5kcyg2NTUzNSwgcG9zKTsKICAgIH0KCiAgICAvKioKICAgICAqIENyZWF0ZSBhIHtAY29kZSBUeXBlQW5ub3RhdGlvblBvc2l0aW9ufSBmb3IgYW4gaW5zdGFuY2VvZi4KICAgICAqCiAgICAgKiBAcGFyYW0gbG9jYXRpb24gVGhlIHR5cGUgcGF0aC4KICAgICAqIEBwYXJhbSBvbkxhbWJkYSBUaGUgbGFtYmRhIGZvciB0aGlzIHZhcmlhYmxlLgogICAgICogQHBhcmFtIHBvcyBUaGUgcG9zaXRpb24gZnJvbSB0aGUgYXNzb2NpYXRlZCB0cmVlIG5vZGUuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgVHlwZUFubm90YXRpb25Qb3NpdGlvbgogICAgICAgIGluc3RhbmNlT2YoZmluYWwgTGlzdDxUeXBlUGF0aEVudHJ5PiBsb2NhdGlvbiwKICAgICAgICAgICAgICAgICAgIGZpbmFsIEpDTGFtYmRhIG9uTGFtYmRhLAogICAgICAgICAgICAgICAgICAgZmluYWwgaW50IHBvcykgewogICAgICAgIHJldHVybiBuZXcgVHlwZUFubm90YXRpb25Qb3NpdGlvbihUYXJnZXRUeXBlLklOU1RBTkNFT0YsIHBvcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW50ZWdlci5NSU5fVkFMVUUsIG9uTGFtYmRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbnRlZ2VyLk1JTl9WQUxVRSwgSW50ZWdlci5NSU5fVkFMVUUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvY2F0aW9uKTsKICAgIH0KICAgIC8qKgogICAgICogQ3JlYXRlIGEge0Bjb2RlIFR5cGVBbm5vdGF0aW9uUG9zaXRpb259IGZvciBhbiBpbnN0YW5jZW9mLgogICAgICoKICAgICAqIEBwYXJhbSBsb2NhdGlvbiBUaGUgdHlwZSBwYXRoLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIFR5cGVBbm5vdGF0aW9uUG9zaXRpb24KICAgICAgICBpbnN0YW5jZU9mKGZpbmFsIExpc3Q8VHlwZVBhdGhFbnRyeT4gbG9jYXRpb24pIHsKICAgICAgICByZXR1cm4gaW5zdGFuY2VPZihsb2NhdGlvbiwgbnVsbCwgLTEpOwogICAgfQoKICAgIC8qKgogICAgICogQ3JlYXRlIGEge0Bjb2RlIFR5cGVBbm5vdGF0aW9uUG9zaXRpb259IGZvciBhIHR5cGUgY2FzdC4KICAgICAqCiAgICAgKiBAcGFyYW0gbG9jYXRpb24gVGhlIHR5cGUgcGF0aC4KICAgICAqIEBwYXJhbSBvbkxhbWJkYSBUaGUgbGFtYmRhIGZvciB0aGlzIHZhcmlhYmxlLgogICAgICogQHBhcmFtIHR5cGVfaW5kZXggVGhlIGluZGV4IGludG8gYW4gaW50ZXJzZWN0aW9uIHR5cGUuCiAgICAgKiBAcGFyYW0gcG9zIFRoZSBwb3NpdGlvbiBmcm9tIHRoZSBhc3NvY2lhdGVkIHRyZWUgbm9kZS4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBUeXBlQW5ub3RhdGlvblBvc2l0aW9uCiAgICAgICAgdHlwZUNhc3QoZmluYWwgTGlzdDxUeXBlUGF0aEVudHJ5PiBsb2NhdGlvbiwKICAgICAgICAgICAgICAgICBmaW5hbCBKQ0xhbWJkYSBvbkxhbWJkYSwKICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgdHlwZV9pbmRleCwKICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgcG9zKSB7CiAgICAgICAgcmV0dXJuIG5ldyBUeXBlQW5ub3RhdGlvblBvc2l0aW9uKFRhcmdldFR5cGUuQ0FTVCwgcG9zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbnRlZ2VyLk1JTl9WQUxVRSwgb25MYW1iZGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVfaW5kZXgsIEludGVnZXIuTUlOX1ZBTFVFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2NhdGlvbik7CiAgICB9CgogICAgLyoqCiAgICAgKiBDcmVhdGUgYSB7QGNvZGUgVHlwZUFubm90YXRpb25Qb3NpdGlvbn0gZm9yIGEgdHlwZSBjYXN0LgogICAgICoKICAgICAqIEBwYXJhbSBsb2NhdGlvbiBUaGUgdHlwZSBwYXRoLgogICAgICogQHBhcmFtIHR5cGVfaW5kZXggVGhlIGluZGV4IGludG8gYW4gaW50ZXJzZWN0aW9uIHR5cGUuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgVHlwZUFubm90YXRpb25Qb3NpdGlvbgogICAgICAgIHR5cGVDYXN0KGZpbmFsIExpc3Q8VHlwZVBhdGhFbnRyeT4gbG9jYXRpb24sCiAgICAgICAgICAgICAgICAgZmluYWwgaW50IHR5cGVfaW5kZXgpIHsKICAgICAgICByZXR1cm4gdHlwZUNhc3QobG9jYXRpb24sIG51bGwsIHR5cGVfaW5kZXgsIC0xKTsKICAgIH0KCiAgICAvKioKICAgICAqIENyZWF0ZSBhIHtAY29kZSBUeXBlQW5ub3RhdGlvblBvc2l0aW9ufSBmb3IgYSBtZXRob2QKICAgICAqIGludm9jYXRpb24gdHlwZSBhcmd1bWVudC4KICAgICAqCiAgICAgKiBAcGFyYW0gbG9jYXRpb24gVGhlIHR5cGUgcGF0aC4KICAgICAqIEBwYXJhbSBvbkxhbWJkYSBUaGUgbGFtYmRhIGZvciB0aGlzIHZhcmlhYmxlLgogICAgICogQHBhcmFtIHR5cGVfaW5kZXggVGhlIGluZGV4IG9mIHRoZSB0eXBlIGFyZ3VtZW50LgogICAgICogQHBhcmFtIHBvcyBUaGUgcG9zaXRpb24gZnJvbSB0aGUgYXNzb2NpYXRlZCB0cmVlIG5vZGUuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgVHlwZUFubm90YXRpb25Qb3NpdGlvbgogICAgICAgIG1ldGhvZEludm9jYXRpb25UeXBlQXJnKGZpbmFsIExpc3Q8VHlwZVBhdGhFbnRyeT4gbG9jYXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgSkNMYW1iZGEgb25MYW1iZGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IHR5cGVfaW5kZXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IHBvcykgewogICAgICAgIHJldHVybiBuZXcgVHlwZUFubm90YXRpb25Qb3NpdGlvbihUYXJnZXRUeXBlLk1FVEhPRF9JTlZPQ0FUSU9OX1RZUEVfQVJHVU1FTlQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvcywgSW50ZWdlci5NSU5fVkFMVUUsIG9uTGFtYmRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlX2luZGV4LCBJbnRlZ2VyLk1JTl9WQUxVRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9jYXRpb24pOwogICAgfQoKICAgIC8qKgogICAgICogQ3JlYXRlIGEge0Bjb2RlIFR5cGVBbm5vdGF0aW9uUG9zaXRpb259IGZvciBhIG1ldGhvZAogICAgICogaW52b2NhdGlvbiB0eXBlIGFyZ3VtZW50LgogICAgICoKICAgICAqIEBwYXJhbSBsb2NhdGlvbiBUaGUgdHlwZSBwYXRoLgogICAgICogQHBhcmFtIHR5cGVfaW5kZXggVGhlIGluZGV4IG9mIHRoZSB0eXBlIGFyZ3VtZW50LgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIFR5cGVBbm5vdGF0aW9uUG9zaXRpb24KICAgICAgICBtZXRob2RJbnZvY2F0aW9uVHlwZUFyZyhmaW5hbCBMaXN0PFR5cGVQYXRoRW50cnk+IGxvY2F0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGludCB0eXBlX2luZGV4KSB7CiAgICAgICAgcmV0dXJuIG1ldGhvZEludm9jYXRpb25UeXBlQXJnKGxvY2F0aW9uLCBudWxsLCB0eXBlX2luZGV4LCAtMSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDcmVhdGUgYSB7QGNvZGUgVHlwZUFubm90YXRpb25Qb3NpdGlvbn0gZm9yIGEgY29uc3RydWN0b3IKICAgICAqIGludm9jYXRpb24gdHlwZSBhcmd1bWVudC4KICAgICAqCiAgICAgKiBAcGFyYW0gbG9jYXRpb24gVGhlIHR5cGUgcGF0aC4KICAgICAqIEBwYXJhbSBvbkxhbWJkYSBUaGUgbGFtYmRhIGZvciB0aGlzIHZhcmlhYmxlLgogICAgICogQHBhcmFtIHR5cGVfaW5kZXggVGhlIGluZGV4IG9mIHRoZSB0eXBlIGFyZ3VtZW50LgogICAgICogQHBhcmFtIHBvcyBUaGUgcG9zaXRpb24gZnJvbSB0aGUgYXNzb2NpYXRlZCB0cmVlIG5vZGUuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgVHlwZUFubm90YXRpb25Qb3NpdGlvbgogICAgICAgIGNvbnN0cnVjdG9ySW52b2NhdGlvblR5cGVBcmcoZmluYWwgTGlzdDxUeXBlUGF0aEVudHJ5PiBsb2NhdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIEpDTGFtYmRhIG9uTGFtYmRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IHR5cGVfaW5kZXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgcG9zKSB7CiAgICAgICAgcmV0dXJuIG5ldyBUeXBlQW5ub3RhdGlvblBvc2l0aW9uKFRhcmdldFR5cGUuQ09OU1RSVUNUT1JfSU5WT0NBVElPTl9UWVBFX0FSR1VNRU5ULAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb3MsIEludGVnZXIuTUlOX1ZBTFVFLCBvbkxhbWJkYSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZV9pbmRleCwgSW50ZWdlci5NSU5fVkFMVUUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvY2F0aW9uKTsKICAgIH0KCiAgICAvKioKICAgICAqIENyZWF0ZSBhIHtAY29kZSBUeXBlQW5ub3RhdGlvblBvc2l0aW9ufSBmb3IgYSBjb25zdHJ1Y3RvcgogICAgICogaW52b2NhdGlvbiB0eXBlIGFyZ3VtZW50LgogICAgICoKICAgICAqIEBwYXJhbSBsb2NhdGlvbiBUaGUgdHlwZSBwYXRoLgogICAgICogQHBhcmFtIHR5cGVfaW5kZXggVGhlIGluZGV4IG9mIHRoZSB0eXBlIGFyZ3VtZW50LgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIFR5cGVBbm5vdGF0aW9uUG9zaXRpb24KICAgICAgICBjb25zdHJ1Y3Rvckludm9jYXRpb25UeXBlQXJnKGZpbmFsIExpc3Q8VHlwZVBhdGhFbnRyeT4gbG9jYXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgdHlwZV9pbmRleCkgewogICAgICAgIHJldHVybiBjb25zdHJ1Y3Rvckludm9jYXRpb25UeXBlQXJnKGxvY2F0aW9uLCBudWxsLCB0eXBlX2luZGV4LCAtMSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDcmVhdGUgYSB7QGNvZGUgVHlwZUFubm90YXRpb25Qb3NpdGlvbn0gZm9yIGEgdHlwZSBwYXJhbWV0ZXIuCiAgICAgKgogICAgICogQHBhcmFtIGxvY2F0aW9uIFRoZSB0eXBlIHBhdGguCiAgICAgKiBAcGFyYW0gb25MYW1iZGEgVGhlIGxhbWJkYSBmb3IgdGhpcyB2YXJpYWJsZS4KICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJfaW5kZXggVGhlIGluZGV4IG9mIHRoZSB0eXBlIHBhcmFtZXRlci4KICAgICAqIEBwYXJhbSBwb3MgVGhlIHBvc2l0aW9uIGZyb20gdGhlIGFzc29jaWF0ZWQgdHJlZSBub2RlLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIFR5cGVBbm5vdGF0aW9uUG9zaXRpb24KICAgICAgICB0eXBlUGFyYW1ldGVyKGZpbmFsIExpc3Q8VHlwZVBhdGhFbnRyeT4gbG9jYXRpb24sCiAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBKQ0xhbWJkYSBvbkxhbWJkYSwKICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGludCBwYXJhbWV0ZXJfaW5kZXgsCiAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgcG9zKSB7CiAgICAgICAgcmV0dXJuIG5ldyBUeXBlQW5ub3RhdGlvblBvc2l0aW9uKFRhcmdldFR5cGUuQ0xBU1NfVFlQRV9QQVJBTUVURVIsIHBvcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyYW1ldGVyX2luZGV4LCBvbkxhbWJkYSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW50ZWdlci5NSU5fVkFMVUUsIEludGVnZXIuTUlOX1ZBTFVFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2NhdGlvbik7CiAgICB9CgogICAgLyoqCiAgICAgKiBDcmVhdGUgYSB7QGNvZGUgVHlwZUFubm90YXRpb25Qb3NpdGlvbn0gZm9yIGEgdHlwZSBwYXJhbWV0ZXIuCiAgICAgKgogICAgICogQHBhcmFtIGxvY2F0aW9uIFRoZSB0eXBlIHBhdGguCiAgICAgKiBAcGFyYW0gcGFyYW1ldGVyX2luZGV4IFRoZSBpbmRleCBvZiB0aGUgdHlwZSBwYXJhbWV0ZXIuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgVHlwZUFubm90YXRpb25Qb3NpdGlvbgogICAgICAgIHR5cGVQYXJhbWV0ZXIoZmluYWwgTGlzdDxUeXBlUGF0aEVudHJ5PiBsb2NhdGlvbiwKICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGludCBwYXJhbWV0ZXJfaW5kZXgpIHsKICAgICAgICByZXR1cm4gdHlwZVBhcmFtZXRlcihsb2NhdGlvbiwgbnVsbCwgcGFyYW1ldGVyX2luZGV4LCAtMSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDcmVhdGUgYSB7QGNvZGUgVHlwZUFubm90YXRpb25Qb3NpdGlvbn0gZm9yIGEgbWV0aG9kIHR5cGUgcGFyYW1ldGVyLgogICAgICoKICAgICAqIEBwYXJhbSBsb2NhdGlvbiBUaGUgdHlwZSBwYXRoLgogICAgICogQHBhcmFtIG9uTGFtYmRhIFRoZSBsYW1iZGEgZm9yIHRoaXMgdmFyaWFibGUuCiAgICAgKiBAcGFyYW0gcGFyYW1ldGVyX2luZGV4IFRoZSBpbmRleCBvZiB0aGUgdHlwZSBwYXJhbWV0ZXIuCiAgICAgKiBAcGFyYW0gcG9zIFRoZSBwb3NpdGlvbiBmcm9tIHRoZSBhc3NvY2lhdGVkIHRyZWUgbm9kZS4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBUeXBlQW5ub3RhdGlvblBvc2l0aW9uCiAgICAgICAgbWV0aG9kVHlwZVBhcmFtZXRlcihmaW5hbCBMaXN0PFR5cGVQYXRoRW50cnk+IGxvY2F0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgSkNMYW1iZGEgb25MYW1iZGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgcGFyYW1ldGVyX2luZGV4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IHBvcykgewogICAgICAgIHJldHVybiBuZXcgVHlwZUFubm90YXRpb25Qb3NpdGlvbihUYXJnZXRUeXBlLk1FVEhPRF9UWVBFX1BBUkFNRVRFUiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9zLCBwYXJhbWV0ZXJfaW5kZXgsIG9uTGFtYmRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbnRlZ2VyLk1JTl9WQUxVRSwgSW50ZWdlci5NSU5fVkFMVUUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvY2F0aW9uKTsKICAgIH0KCiAgICAvKioKICAgICAqIENyZWF0ZSBhIHtAY29kZSBUeXBlQW5ub3RhdGlvblBvc2l0aW9ufSBmb3IgYSBtZXRob2QgdHlwZSBwYXJhbWV0ZXIuCiAgICAgKgogICAgICogQHBhcmFtIGxvY2F0aW9uIFRoZSB0eXBlIHBhdGguCiAgICAgKiBAcGFyYW0gcGFyYW1ldGVyX2luZGV4IFRoZSBpbmRleCBvZiB0aGUgdHlwZSBwYXJhbWV0ZXIuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgVHlwZUFubm90YXRpb25Qb3NpdGlvbgogICAgICAgIG1ldGhvZFR5cGVQYXJhbWV0ZXIoZmluYWwgTGlzdDxUeXBlUGF0aEVudHJ5PiBsb2NhdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGludCBwYXJhbWV0ZXJfaW5kZXgpIHsKICAgICAgICByZXR1cm4gbWV0aG9kVHlwZVBhcmFtZXRlcihsb2NhdGlvbiwgbnVsbCwgcGFyYW1ldGVyX2luZGV4LCAtMSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDcmVhdGUgYSB7QGNvZGUgVHlwZUFubm90YXRpb25Qb3NpdGlvbn0gZm9yIGEgdGhyb3dzIGNsYXVzZS4KICAgICAqCiAgICAgKiBAcGFyYW0gbG9jYXRpb24gVGhlIHR5cGUgcGF0aC4KICAgICAqIEBwYXJhbSBvbkxhbWJkYSBUaGUgbGFtYmRhIGZvciB0aGlzIHZhcmlhYmxlLgogICAgICogQHBhcmFtIHR5cGVfaW5kZXggVGhlIGluZGV4IG9mIHRoZSBleGNlcHRpb24uCiAgICAgKiBAcGFyYW0gcG9zIFRoZSBwb3NpdGlvbiBmcm9tIHRoZSBhc3NvY2lhdGVkIHRyZWUgbm9kZS4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBUeXBlQW5ub3RhdGlvblBvc2l0aW9uCiAgICAgICAgbWV0aG9kVGhyb3dzKGZpbmFsIExpc3Q8VHlwZVBhdGhFbnRyeT4gbG9jYXRpb24sCiAgICAgICAgICAgICAgICAgICAgIGZpbmFsIEpDTGFtYmRhIG9uTGFtYmRhLAogICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgdHlwZV9pbmRleCwKICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IHBvcykgewogICAgICAgIHJldHVybiBuZXcgVHlwZUFubm90YXRpb25Qb3NpdGlvbihUYXJnZXRUeXBlLlRIUk9XUywgcG9zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbnRlZ2VyLk1JTl9WQUxVRSwgb25MYW1iZGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVfaW5kZXgsIEludGVnZXIuTUlOX1ZBTFVFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2NhdGlvbik7CiAgICB9CgogICAgLyoqCiAgICAgKiBDcmVhdGUgYSB7QGNvZGUgVHlwZUFubm90YXRpb25Qb3NpdGlvbn0gZm9yIGEgdGhyb3dzIGNsYXVzZS4KICAgICAqCiAgICAgKiBAcGFyYW0gbG9jYXRpb24gVGhlIHR5cGUgcGF0aC4KICAgICAqIEBwYXJhbSB0eXBlX2luZGV4IFRoZSBpbmRleCBvZiB0aGUgZXhjZXB0aW9uLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIFR5cGVBbm5vdGF0aW9uUG9zaXRpb24KICAgICAgICBtZXRob2RUaHJvd3MoZmluYWwgTGlzdDxUeXBlUGF0aEVudHJ5PiBsb2NhdGlvbiwKICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IHR5cGVfaW5kZXgpIHsKICAgICAgICByZXR1cm4gbWV0aG9kVGhyb3dzKGxvY2F0aW9uLCBudWxsLCB0eXBlX2luZGV4LCAtMSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDcmVhdGUgYSB7QGNvZGUgVHlwZUFubm90YXRpb25Qb3NpdGlvbn0gZm9yIGEgbWV0aG9kIHJlZmVyZW5jZQogICAgICogdHlwZSBhcmd1bWVudC4KICAgICAqCiAgICAgKiBAcGFyYW0gbG9jYXRpb24gVGhlIHR5cGUgcGF0aC4KICAgICAqIEBwYXJhbSBvbkxhbWJkYSBUaGUgbGFtYmRhIGZvciB0aGlzIHZhcmlhYmxlLgogICAgICogQHBhcmFtIHR5cGVfaW5kZXggVGhlIGluZGV4IG9mIHRoZSB0eXBlIGFyZ3VtZW50LgogICAgICogQHBhcmFtIHBvcyBUaGUgcG9zaXRpb24gZnJvbSB0aGUgYXNzb2NpYXRlZCB0cmVlIG5vZGUuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgVHlwZUFubm90YXRpb25Qb3NpdGlvbgogICAgICAgIG1ldGhvZFJlZlR5cGVBcmcoZmluYWwgTGlzdDxUeXBlUGF0aEVudHJ5PiBsb2NhdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIEpDTGFtYmRhIG9uTGFtYmRhLAogICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IHR5cGVfaW5kZXgsCiAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgcG9zKSB7CiAgICAgICAgcmV0dXJuIG5ldyBUeXBlQW5ub3RhdGlvblBvc2l0aW9uKFRhcmdldFR5cGUuTUVUSE9EX1JFRkVSRU5DRV9UWVBFX0FSR1VNRU5ULAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb3MsIEludGVnZXIuTUlOX1ZBTFVFLCBvbkxhbWJkYSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZV9pbmRleCwgSW50ZWdlci5NSU5fVkFMVUUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvY2F0aW9uKTsKICAgIH0KCiAgICAvKioKICAgICAqIENyZWF0ZSBhIHtAY29kZSBUeXBlQW5ub3RhdGlvblBvc2l0aW9ufSBmb3IgYSBtZXRob2QgcmVmZXJlbmNlCiAgICAgKiB0eXBlIGFyZ3VtZW50LgogICAgICoKICAgICAqIEBwYXJhbSBsb2NhdGlvbiBUaGUgdHlwZSBwYXRoLgogICAgICogQHBhcmFtIHR5cGVfaW5kZXggVGhlIGluZGV4IG9mIHRoZSB0eXBlIGFyZ3VtZW50LgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIFR5cGVBbm5vdGF0aW9uUG9zaXRpb24KICAgICAgICBtZXRob2RSZWZUeXBlQXJnKGZpbmFsIExpc3Q8VHlwZVBhdGhFbnRyeT4gbG9jYXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgdHlwZV9pbmRleCkgewogICAgICAgIHJldHVybiBtZXRob2RSZWZUeXBlQXJnKGxvY2F0aW9uLCBudWxsLCB0eXBlX2luZGV4LCAtMSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDcmVhdGUgYSB7QGNvZGUgVHlwZUFubm90YXRpb25Qb3NpdGlvbn0gZm9yIGEgY29uc3RydWN0b3IgcmVmZXJlbmNlCiAgICAgKiB0eXBlIGFyZ3VtZW50LgogICAgICoKICAgICAqIEBwYXJhbSBsb2NhdGlvbiBUaGUgdHlwZSBwYXRoLgogICAgICogQHBhcmFtIG9uTGFtYmRhIFRoZSBsYW1iZGEgZm9yIHRoaXMgdmFyaWFibGUuCiAgICAgKiBAcGFyYW0gdHlwZV9pbmRleCBUaGUgaW5kZXggb2YgdGhlIHR5cGUgYXJndW1lbnQuCiAgICAgKiBAcGFyYW0gcG9zIFRoZSBwb3NpdGlvbiBmcm9tIHRoZSBhc3NvY2lhdGVkIHRyZWUgbm9kZS4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBUeXBlQW5ub3RhdGlvblBvc2l0aW9uCiAgICAgICAgY29uc3RydWN0b3JSZWZUeXBlQXJnKGZpbmFsIExpc3Q8VHlwZVBhdGhFbnRyeT4gbG9jYXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIEpDTGFtYmRhIG9uTGFtYmRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgdHlwZV9pbmRleCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IHBvcykgewogICAgICAgIHJldHVybiBuZXcgVHlwZUFubm90YXRpb25Qb3NpdGlvbihUYXJnZXRUeXBlLkNPTlNUUlVDVE9SX1JFRkVSRU5DRV9UWVBFX0FSR1VNRU5ULAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb3MsIEludGVnZXIuTUlOX1ZBTFVFLCBvbkxhbWJkYSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZV9pbmRleCwgSW50ZWdlci5NSU5fVkFMVUUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvY2F0aW9uKTsKICAgIH0KCiAgICAvKioKICAgICAqIENyZWF0ZSBhIHtAY29kZSBUeXBlQW5ub3RhdGlvblBvc2l0aW9ufSBmb3IgYSBjb25zdHJ1Y3RvciByZWZlcmVuY2UKICAgICAqIHR5cGUgYXJndW1lbnQuCiAgICAgKgogICAgICogQHBhcmFtIGxvY2F0aW9uIFRoZSB0eXBlIHBhdGguCiAgICAgKiBAcGFyYW0gdHlwZV9pbmRleCBUaGUgaW5kZXggb2YgdGhlIHR5cGUgYXJndW1lbnQuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgVHlwZUFubm90YXRpb25Qb3NpdGlvbgogICAgICAgIGNvbnN0cnVjdG9yUmVmVHlwZUFyZyhmaW5hbCBMaXN0PFR5cGVQYXRoRW50cnk+IGxvY2F0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgdHlwZV9pbmRleCkgewogICAgICAgIHJldHVybiBjb25zdHJ1Y3RvclJlZlR5cGVBcmcobG9jYXRpb24sIG51bGwsIHR5cGVfaW5kZXgsIC0xKTsKICAgIH0KCiAgICAvKioKICAgICAqIENyZWF0ZSBhIHtAY29kZSBUeXBlQW5ub3RhdGlvblBvc2l0aW9ufSBmb3IgYSB0eXBlIHBhcmFtZXRlciBib3VuZC4KICAgICAqCiAgICAgKiBAcGFyYW0gbG9jYXRpb24gVGhlIHR5cGUgcGF0aC4KICAgICAqIEBwYXJhbSBvbkxhbWJkYSBUaGUgbGFtYmRhIGZvciB0aGlzIHZhcmlhYmxlLgogICAgICogQHBhcmFtIHBhcmFtZXRlcl9pbmRleCBUaGUgaW5kZXggb2YgdGhlIHR5cGUgcGFyYW1ldGVyLgogICAgICogQHBhcmFtIGJvdW5kX2luZGV4IFRoZSBpbmRleCBvZiB0aGUgdHlwZSBwYXJhbWV0ZXIgYm91bmQuCiAgICAgKiBAcGFyYW0gcG9zIFRoZSBwb3NpdGlvbiBmcm9tIHRoZSBhc3NvY2lhdGVkIHRyZWUgbm9kZS4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBUeXBlQW5ub3RhdGlvblBvc2l0aW9uCiAgICAgICAgdHlwZVBhcmFtZXRlckJvdW5kKGZpbmFsIExpc3Q8VHlwZVBhdGhFbnRyeT4gbG9jYXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIEpDTGFtYmRhIG9uTGFtYmRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgcGFyYW1ldGVyX2luZGV4LAogICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgYm91bmRfaW5kZXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGludCBwb3MpIHsKICAgICAgICByZXR1cm4gbmV3IFR5cGVBbm5vdGF0aW9uUG9zaXRpb24oVGFyZ2V0VHlwZS5DTEFTU19UWVBFX1BBUkFNRVRFUl9CT1VORCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9zLCBwYXJhbWV0ZXJfaW5kZXgsIG9uTGFtYmRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbnRlZ2VyLk1JTl9WQUxVRSwgYm91bmRfaW5kZXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvY2F0aW9uKTsKICAgIH0KCiAgICAvKioKICAgICAqIENyZWF0ZSBhIHtAY29kZSBUeXBlQW5ub3RhdGlvblBvc2l0aW9ufSBmb3IgYSB0eXBlIHBhcmFtZXRlciBib3VuZC4KICAgICAqCiAgICAgKiBAcGFyYW0gbG9jYXRpb24gVGhlIHR5cGUgcGF0aC4KICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJfaW5kZXggVGhlIGluZGV4IG9mIHRoZSB0eXBlIHBhcmFtZXRlci4KICAgICAqIEBwYXJhbSBib3VuZF9pbmRleCBUaGUgaW5kZXggb2YgdGhlIHR5cGUgcGFyYW1ldGVyIGJvdW5kLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIFR5cGVBbm5vdGF0aW9uUG9zaXRpb24KICAgICAgICB0eXBlUGFyYW1ldGVyQm91bmQoZmluYWwgTGlzdDxUeXBlUGF0aEVudHJ5PiBsb2NhdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IHBhcmFtZXRlcl9pbmRleCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IGJvdW5kX2luZGV4KSB7CiAgICAgICAgcmV0dXJuIHR5cGVQYXJhbWV0ZXJCb3VuZChsb2NhdGlvbiwgbnVsbCwgcGFyYW1ldGVyX2luZGV4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm91bmRfaW5kZXgsIC0xKTsKICAgIH0KCiAgICAvKioKICAgICAqIENyZWF0ZSBhIHtAY29kZSBUeXBlQW5ub3RhdGlvblBvc2l0aW9ufSBmb3IgYSBtZXRob2QgdHlwZQogICAgICogcGFyYW1ldGVyIGJvdW5kLgogICAgICoKICAgICAqIEBwYXJhbSBsb2NhdGlvbiBUaGUgdHlwZSBwYXRoLgogICAgICogQHBhcmFtIG9uTGFtYmRhIFRoZSBsYW1iZGEgZm9yIHRoaXMgdmFyaWFibGUuCiAgICAgKiBAcGFyYW0gcGFyYW1ldGVyX2luZGV4IFRoZSBpbmRleCBvZiB0aGUgdHlwZSBwYXJhbWV0ZXIuCiAgICAgKiBAcGFyYW0gYm91bmRfaW5kZXggVGhlIGluZGV4IG9mIHRoZSB0eXBlIHBhcmFtZXRlciBib3VuZC4KICAgICAqIEBwYXJhbSBwb3MgVGhlIHBvc2l0aW9uIGZyb20gdGhlIGFzc29jaWF0ZWQgdHJlZSBub2RlLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIFR5cGVBbm5vdGF0aW9uUG9zaXRpb24KICAgICAgICBtZXRob2RUeXBlUGFyYW1ldGVyQm91bmQoZmluYWwgTGlzdDxUeXBlUGF0aEVudHJ5PiBsb2NhdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgSkNMYW1iZGEgb25MYW1iZGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGludCBwYXJhbWV0ZXJfaW5kZXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIGludCBib3VuZF9pbmRleCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgaW50IHBvcykgewogICAgICAgIHJldHVybiBuZXcgVHlwZUFubm90YXRpb25Qb3NpdGlvbihUYXJnZXRUeXBlLk1FVEhPRF9UWVBFX1BBUkFNRVRFUl9CT1VORCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9zLCBwYXJhbWV0ZXJfaW5kZXgsIG9uTGFtYmRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbnRlZ2VyLk1JTl9WQUxVRSwgYm91bmRfaW5kZXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvY2F0aW9uKTsKICAgIH0KCiAgICAvKioKICAgICAqIENyZWF0ZSBhIHtAY29kZSBUeXBlQW5ub3RhdGlvblBvc2l0aW9ufSBmb3IgYSBtZXRob2QgdHlwZQogICAgICogcGFyYW1ldGVyIGJvdW5kLgogICAgICoKICAgICAqIEBwYXJhbSBsb2NhdGlvbiBUaGUgdHlwZSBwYXRoLgogICAgICogQHBhcmFtIHBhcmFtZXRlcl9pbmRleCBUaGUgaW5kZXggb2YgdGhlIHR5cGUgcGFyYW1ldGVyLgogICAgICogQHBhcmFtIGJvdW5kX2luZGV4IFRoZSBpbmRleCBvZiB0aGUgdHlwZSBwYXJhbWV0ZXIgYm91bmQuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgVHlwZUFubm90YXRpb25Qb3NpdGlvbgogICAgICAgIG1ldGhvZFR5cGVQYXJhbWV0ZXJCb3VuZChmaW5hbCBMaXN0PFR5cGVQYXRoRW50cnk+IGxvY2F0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgcGFyYW1ldGVyX2luZGV4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgYm91bmRfaW5kZXgpIHsKICAgICAgICByZXR1cm4gbWV0aG9kVHlwZVBhcmFtZXRlckJvdW5kKGxvY2F0aW9uLCBudWxsLCBwYXJhbWV0ZXJfaW5kZXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib3VuZF9pbmRleCwgLTEpOwogICAgfQoKICAgIC8vIENvbnNpZGVyIHRoaXMgZGVwcmVjYXRlZCBvbiBhcnJpdmFsLiAgV2UgZXZlbnR1YWxseSB3YW50IHRvIGdldAogICAgLy8gcmlkIG9mIHRoaXMgdmFsdWUgYWx0b2dldGhlci4gIERvIG5vdCB1c2UgaXQgZm9yIGFueXRoaW5nIG5ldy4KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVHlwZUFubm90YXRpb25Qb3NpdGlvbiB1bmtub3duID0KICAgICAgICBuZXcgVHlwZUFubm90YXRpb25Qb3NpdGlvbihUYXJnZXRUeXBlLlVOS05PV04sIC0xLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEludGVnZXIuTUlOX1ZBTFVFLCBudWxsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEludGVnZXIuTUlOX1ZBTFVFLCBJbnRlZ2VyLk1JTl9WQUxVRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbXB0eVBhdGgpOwp9ClBLAwQKAAAIAAAGO6lKYfFancoZAADKGQAAKgAAAGNvbS9zdW4vdG9vbHMvamF2YWMvY29kZS9UeXBlTWV0YWRhdGEuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAxNCwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGU7CgppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkFzc2VydDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5MaXN0OwppbXBvcnQgamF2YS51dGlsLkVudW1NYXA7CmltcG9ydCBqYXZhLnV0aWwuSGFzaFNldDsKaW1wb3J0IGphdmEudXRpbC5TZXQ7CgovKioKICogVHlwZU1ldGFkYXRhIGlzIGVzc2VudGlhbGx5IGFuIGltbXV0YWJsZSB7QGNvZGUgRW51bU1hcDxFbnRyeS5LaW5kLCA8PyBleHRlbmRzIEVudHJ5Pj59CiAqCiAqIEEgbWV0YWRhdGEgY2xhc3MgcmVwcmVzZW50ZWQgYnkgYSBzdWJ0eXBlIG9mIEVudHJ5IGNhbiBleHByZXNzIGEgcHJvcGVydHkgb24gYSBUeXBlIGluc3RhbmNlLgogKiBUaGVycyBzaG91bGQgYmUgYXQgbW9zdCBvbmUgaW5zdGFuY2Ugb2YgYW4gRW50cnkgcGVyIEVudHJ5LktpbmQgb24gYW55IGdpdmVuIFR5cGUgaW5zdGFuY2UuCiAqCiAqIE1ldGFkYXRhIGNsYXNzZXMgb2YgYSBzcGVjaWZpYyBraW5kIGFyZSByZXNwb25zaWJsZSBmb3IgaG93IHRoZXkgY29tYmluZSB0aGVtc2VsdnMuCiAqCiAqIEBpbXBsTm90ZSB7QGNvZGUgRW50cnk6Y29tYmluZX0gbmVlZCBub3QgYmUgY29tbXV0YXRpdmUuCiAqLwpwdWJsaWMgY2xhc3MgVHlwZU1ldGFkYXRhIHsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVHlwZU1ldGFkYXRhIEVNUFRZID0gbmV3IFR5cGVNZXRhZGF0YSgpOwoKICAgIHByaXZhdGUgZmluYWwgRW51bU1hcDxFbnRyeS5LaW5kLCBFbnRyeT4gY29udGVudHM7CgogICAgLyoqCiAgICAgKiBDcmVhdGUgYSBuZXcgZW1wdHkgVHlwZU1ldGFkYXRhIG1hcC4KICAgICAqLwogICAgcHJpdmF0ZSBUeXBlTWV0YWRhdGEoKSB7CiAgICAgICAgY29udGVudHMgPSBuZXcgRW51bU1hcDw+KEVudHJ5LktpbmQuY2xhc3MpOwogICAgfQoKICAgIC8qKgogICAgICogQ3JlYXRlIGEgbmV3IFR5cGVNZXRhZGF0YSBtYXAgY29udGFpbmluZyB0aGUgRW50cnkge0Bjb2RlIGVsZW19LgogICAgICoKICAgICAqIEBwYXJhbSBlbGVtIHRoZSBzb2xlIGNvbnRlbnRzIG9mIHRoaXMgbWFwCiAgICAgKi8KICAgIHB1YmxpYyBUeXBlTWV0YWRhdGEoRW50cnkgZWxlbSkgewogICAgICAgIHRoaXMoKTsKICAgICAgICBBc3NlcnQuY2hlY2tOb25OdWxsKGVsZW0pOwogICAgICAgIGNvbnRlbnRzLnB1dChlbGVtLmtpbmQoKSwgZWxlbSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDcmVhdGVzIGEgY29weSBvZiBUeXBlTWV0YWRhdGEge0Bjb2RlIG90aGVyfSB3aXRoIGEgc2hhbGxvdyBjb3B5IHRoZSBvdGhlcidzIG1ldGFkYXRhIGNvbnRlbnRzLgogICAgICoKICAgICAqIEBwYXJhbSBvdGhlciB0aGUgVHlwZU1ldGFkYXRhIHRvIGNvcHkgY29udGVudHMgZnJvbS4KICAgICAqLwogICAgcHVibGljIFR5cGVNZXRhZGF0YShUeXBlTWV0YWRhdGEgb3RoZXIpIHsKICAgICAgICBBc3NlcnQuY2hlY2tOb25OdWxsKG90aGVyKTsKICAgICAgICBjb250ZW50cyA9IG90aGVyLmNvbnRlbnRzLmNsb25lKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm4gYSBjb3B5IG9mIHRoaXMgVHlwZU1ldGFkYXRhIHdpdGggdGhlIG1ldGFkYXRhIGVudHJ5IGZvciB7QGNvZGUgZWxlbS5raW5kKCl9IGNvbWJpbmVkCiAgICAgKiB3aXRoIHtAY29kZSBlbGVtfS4KICAgICAqCiAgICAgKiBAcGFyYW0gZWxlbSB0aGUgbmV3IHZhbHVlCiAgICAgKiBAcmV0dXJuIGEgbmV3IFR5cGVNZXRhZGF0YSB1cGRhdGVkIHdpdGgge0Bjb2RlIEVudHJ5IGVsZW19CiAgICAgKi8KICAgIHB1YmxpYyBUeXBlTWV0YWRhdGEgY29tYmluZShFbnRyeSBlbGVtKSB7CiAgICAgICAgQXNzZXJ0LmNoZWNrTm9uTnVsbChlbGVtKTsKCiAgICAgICAgVHlwZU1ldGFkYXRhIG91dCA9IG5ldyBUeXBlTWV0YWRhdGEodGhpcyk7CiAgICAgICAgRW50cnkuS2luZCBrZXkgPSBlbGVtLmtpbmQoKTsKICAgICAgICBpZiAoY29udGVudHMuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgICBvdXQuYWRkKGtleSwgdGhpcy5jb250ZW50cy5nZXQoa2V5KS5jb21iaW5lKGVsZW0pKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBvdXQuYWRkKGtleSwgZWxlbSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBvdXQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm4gYSBjb3B5IG9mIHRoaXMgVHlwZU1ldGFkYXRhIHdpdGggdGhlIG1ldGFkYXRhIGVudHJ5IGZvciBhbGwga2luZHMgZnJvbSB7QGNvZGUgb3RoZXJ9CiAgICAgKiBjb21iaW5lZCB3aXRoIHRoZSBzYW1lIGtpbmQgZnJvbSB0aGlzLgogICAgICoKICAgICAqIEBwYXJhbSBvdGhlciB0aGUgVHlwZU1ldGFkYXRhIHRvIGNvbWJpbmUgd2l0aCB0aGlzCiAgICAgKiBAcmV0dXJuIGEgbmV3IFR5cGVNZXRhZGF0YSB1cGRhdGVkIHdpdGggYWxsIGVudHJpZXMgZnJvbSB7QGNvZGUgb3RoZXJ9CiAgICAgKi8KICAgIHB1YmxpYyBUeXBlTWV0YWRhdGEgY29tYmluZUFsbChUeXBlTWV0YWRhdGEgb3RoZXIpIHsKICAgICAgICBBc3NlcnQuY2hlY2tOb25OdWxsKG90aGVyKTsKCiAgICAgICAgVHlwZU1ldGFkYXRhIG91dCA9IG5ldyBUeXBlTWV0YWRhdGEoKTsKICAgICAgICBTZXQ8RW50cnkuS2luZD4ga2V5cyA9IG5ldyBIYXNoU2V0PD4oY29udGVudHMua2V5U2V0KCkpOwogICAgICAgIGtleXMuYWRkQWxsKG90aGVyLmNvbnRlbnRzLmtleVNldCgpKTsKCiAgICAgICAgZm9yKEVudHJ5LktpbmQga2V5IDoga2V5cykgewogICAgICAgICAgICBpZiAoY29udGVudHMuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgICAgICAgaWYgKG90aGVyLmNvbnRlbnRzLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgICAgICAgICAgICBvdXQuYWRkKGtleSwgY29udGVudHMuZ2V0KGtleSkuY29tYmluZShvdGhlci5jb250ZW50cy5nZXQoa2V5KSkpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBvdXQuYWRkKGtleSwgY29udGVudHMuZ2V0KGtleSkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgaWYgKG90aGVyLmNvbnRlbnRzLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgICAgICAgIG91dC5hZGQoa2V5LCBvdGhlci5jb250ZW50cy5nZXQoa2V5KSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIG91dDsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybiBhIFR5cGVNZXRhZGF0YSB3aXRoIHRoZSBtZXRhZGF0YSBlbnRyeSBmb3Ige0Bjb2RlIGtpbmR9IHJlbW92ZWQuCiAgICAgKgogICAgICogVGhpcyBtYXkgYmUgdGhlIHNhbWUgaW5zdGFuY2Ugb3IgYSBuZXcgVHlwZU1ldGFkYXRhLgogICAgICoKICAgICAqIEBwYXJhbSBraW5kIHRoZSB7QGNvZGUgS2luZH0gdG8gcmVtb3ZlIG1ldGFkYXRhIGZvcgogICAgICogQHJldHVybiBhIG5ldyBUeXBlTWV0YWRhdGEgd2l0aG91dCB7QGNvZGUgS2luZCBraW5kfQogICAgICovCiAgICBwdWJsaWMgVHlwZU1ldGFkYXRhIHdpdGhvdXQoRW50cnkuS2luZCBraW5kKSB7CiAgICAgICAgaWYgKHRoaXMgPT0gRU1QVFkgfHwgY29udGVudHMuZ2V0KGtpbmQpID09IG51bGwpCiAgICAgICAgICAgIHJldHVybiB0aGlzOwoKICAgICAgICBUeXBlTWV0YWRhdGEgb3V0ID0gbmV3IFR5cGVNZXRhZGF0YSh0aGlzKTsKICAgICAgICBvdXQuY29udGVudHMucmVtb3ZlKGtpbmQpOwogICAgICAgIHJldHVybiBvdXQuY29udGVudHMuaXNFbXB0eSgpID8gRU1QVFkgOiBvdXQ7CiAgICB9CgogICAgcHVibGljIEVudHJ5IGdldChFbnRyeS5LaW5kIGtpbmQpIHsKICAgICAgICByZXR1cm4gY29udGVudHMuZ2V0KGtpbmQpOwogICAgfQoKICAgIHByaXZhdGUgdm9pZCBhZGQoRW50cnkuS2luZCBraW5kLCBFbnRyeSBlbGVtKSB7CiAgICAgICAgY29udGVudHMucHV0KGtpbmQsIGVsZW0pOwogICAgfQoKICAgIHB1YmxpYyBpbnRlcmZhY2UgRW50cnkgewoKICAgICAgICBwdWJsaWMgZW51bSBLaW5kIHsKICAgICAgICAgICAgQU5OT1RBVElPTlMKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIEdldCB0aGUga2luZCBvZiBtZXRhZGF0YSB0aGlzIG9iamVjdCByZXByZXNlbnRzCiAgICAgICAgICovCiAgICAgICAgcHVibGljIEtpbmQga2luZCgpOwoKICAgICAgICAvKioKICAgICAgICAgKiBDb21iaW5lIHRoaXMgdHlwZSBtZXRhZGF0YSB3aXRoIGFub3RoZXIgbWV0YWRhdGEgb2YgdGhlCiAgICAgICAgICogc2FtZSBraW5kLgogICAgICAgICAqCiAgICAgICAgICogQHBhcmFtIG90aGVyIFRoZSBtZXRhZGF0YSB3aXRoIHdoaWNoIHRvIGNvbWJpbmUgdGhpcyBvbmUuCiAgICAgICAgICogQHJldHVybiBUaGUgY29tYmluZWQgbWV0YWRhdGEuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIEVudHJ5IGNvbWJpbmUoRW50cnkgb3RoZXIpOwogICAgfQoKICAgIC8qKgogICAgICogQSB0eXBlIG1ldGFkYXRhIG9iamVjdCBob2xkaW5nIHR5cGUgYW5ub3RhdGlvbnMuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgQW5ub3RhdGlvbnMgaW1wbGVtZW50cyBFbnRyeSB7CiAgICAgICAgcHJpdmF0ZSBMaXN0PEF0dHJpYnV0ZS5UeXBlQ29tcG91bmQ+IGFubm9zOwoKICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIExpc3Q8QXR0cmlidXRlLlR5cGVDb21wb3VuZD4gVE9fQkVfU0VUID0gTGlzdC5uaWwoKTsKCiAgICAgICAgcHVibGljIEFubm90YXRpb25zKExpc3Q8QXR0cmlidXRlLlR5cGVDb21wb3VuZD4gYW5ub3MpIHsKICAgICAgICAgICAgdGhpcy5hbm5vcyA9IGFubm9zOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogR2V0IHRoZSB0eXBlIGFubm90YXRpb25zIGNvbnRhaW5lZCBpbiB0aGlzIG1ldGFkYXRhLgogICAgICAgICAqCiAgICAgICAgICogQHJldHVybiBUaGUgYW5ub3RhdGlvbnMuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIExpc3Q8QXR0cmlidXRlLlR5cGVDb21wb3VuZD4gZ2V0QW5ub3RhdGlvbnMoKSB7CiAgICAgICAgICAgIHJldHVybiBhbm5vczsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBBbm5vdGF0aW9ucyBjb21iaW5lKEVudHJ5IG90aGVyKSB7CiAgICAgICAgICAgIEFzc2VydC5jaGVjayhhbm5vcyA9PSBUT19CRV9TRVQpOwogICAgICAgICAgICBhbm5vcyA9ICgoQW5ub3RhdGlvbnMpb3RoZXIpLmFubm9zOwogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBLaW5kIGtpbmQoKSB7IHJldHVybiBLaW5kLkFOTk9UQVRJT05TOyB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7IHJldHVybiAiQU5OT1RBVElPTlMgWyAiICsgYW5ub3MgKyAiIF0iOyB9CiAgICB9Cn0KUEsDBAoAAAgAAAY7qUoAAAAAAAAAAAAAAAAZAAAAY29tL3N1bi90b29scy9qYXZhYy9tYWluL1BLAwQKAAAIAAAGO6lK2XE7rmsHAABrBwAALwAAAGNvbS9zdW4vdG9vbHMvamF2YWMvbWFpbi9KYXZhY1Rvb2xQcm92aWRlci5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDE2LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuamF2YWMubWFpbjsKCmltcG9ydCBqYXZhLmlvLlByaW50V3JpdGVyOwppbXBvcnQgamF2YS51dGlsLnNwaS5Ub29sUHJvdmlkZXI7CgovKioKICogQW4gaW1wbGVtZW50YXRpb24gb2YgdGhlIHtAbGluayBqYXZhLnV0aWwuc3BpLlRvb2xQcm92aWRlciBUb29sUHJvdmlkZXJ9IFNQSSwKICogcHJvdmlkaW5nIGFjY2VzcyB0byBKREsgSmF2YSBjb21waWxlciwgamF2YWMuCiAqCiAqIEBzaW5jZSA5CiAqLwovLyBUaGlzIGlzIGN1cnJlbnRseSBhIHN0YW5kLWFsb25lIHRvcC1sZXZlbCBjbGFzcyBzbyB0aGF0IGl0IGNhbiBlYXNpbHkgYmUgZXhjbHVkZWQKLy8gZnJvbSBpbnRlcmltcyBidWlsZHMgb2YgamF2YWMsIHVzZWQgd2hpbGUgYnVpbGRpbmcgSkRLLgpwdWJsaWMgY2xhc3MgSmF2YWNUb29sUHJvdmlkZXIgaW1wbGVtZW50cyBUb29sUHJvdmlkZXIgewogICAgcHVibGljIFN0cmluZyBuYW1lKCkgewogICAgICAgIHJldHVybiAiamF2YWMiOwogICAgfQoKICAgIHB1YmxpYyBpbnQgcnVuKFByaW50V3JpdGVyIG91dCwgUHJpbnRXcml0ZXIgZXJyLCBTdHJpbmcuLi4gYXJncykgewogICAgICAgIE1haW4gY29tcGlsZXIgPSBuZXcgTWFpbigiamF2YWMiLCBvdXQsIGVycik7CiAgICAgICAgcmV0dXJuIGNvbXBpbGVyLmNvbXBpbGUoYXJncykuZXhpdENvZGU7CiAgICB9Cn0KUEsDBAoAAAgAAAY7qUoIVvqqLcwAAC3MAAAkAAAAY29tL3N1bi90b29scy9qYXZhYy9tYWluL09wdGlvbi5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDA2LCAyMDE3LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuamF2YWMubWFpbjsKCmltcG9ydCBqYXZhLmlvLkZpbGVXcml0ZXI7CmltcG9ydCBqYXZhLmlvLlByaW50V3JpdGVyOwppbXBvcnQgamF2YS5uaW8uZmlsZS5GaWxlczsKaW1wb3J0IGphdmEubmlvLmZpbGUuUGF0aDsKaW1wb3J0IGphdmEubmlvLmZpbGUuUGF0aHM7CmltcG9ydCBqYXZhLnRleHQuQ29sbGF0b3I7CmltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOwppbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOwppbXBvcnQgamF2YS51dGlsLkNvbXBhcmF0b3I7CmltcG9ydCBqYXZhLnV0aWwuRW51bVNldDsKaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKaW1wb3J0IGphdmEudXRpbC5MaW5rZWRIYXNoU2V0OwppbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKaW1wb3J0IGphdmEudXRpbC5TZXJ2aWNlTG9hZGVyOwppbXBvcnQgamF2YS51dGlsLlNldDsKaW1wb3J0IGphdmEudXRpbC5UcmVlU2V0OwppbXBvcnQgamF2YS51dGlsLnJlZ2V4LlBhdHRlcm47CmltcG9ydCBqYXZhLnV0aWwuc3RyZWFtLkNvbGxlY3RvcnM7CmltcG9ydCBqYXZhLnV0aWwuc3RyZWFtLlN0cmVhbVN1cHBvcnQ7CgppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5Tb3VyY2VWZXJzaW9uOwoKaW1wb3J0IGNvbS5zdW4udG9vbHMuZG9jbGludC5Eb2NMaW50OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLkxpbnQ7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuTGludC5MaW50Q2F0ZWdvcnk7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuU291cmNlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlR5cGU7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmp2bS5Qcm9maWxlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5qdm0uVGFyZ2V0OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5wbGF0Zm9ybS5QbGF0Zm9ybVByb3ZpZGVyOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5wcm9jZXNzaW5nLkphdmFjUHJvY2Vzc2luZ0Vudmlyb25tZW50OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkFzc2VydDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5KREs5V3JhcHBlcnM7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuTG9nOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkxvZy5QcmVmaXhLaW5kOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkxvZy5Xcml0ZXJLaW5kOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLk9wdGlvbnM7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuU3RyaW5nVXRpbHM7CgppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMubWFpbi5PcHRpb24uQ2hvaWNlS2luZC4qOwppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMubWFpbi5PcHRpb24uT3B0aW9uR3JvdXAuKjsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLm1haW4uT3B0aW9uLk9wdGlvbktpbmQuKjsKCi8qKgogKiBPcHRpb25zIGZvciBqYXZhYy4KICogVGhlIHNwZWNpZmljIE9wdGlvbiB0byBoYW5kbGUgYSBjb21tYW5kLWxpbmUgb3B0aW9uIGNhbiBiZSBmb3VuZCBieSBjYWxsaW5nCiAqIHtAbGluayAjbG9va3VwfSwgd2hpY2ggc2VhcmNoIHNvbWUgb3IgYWxsIG9mIHRoZSBtZW1iZXJzIG9mIHRoaXMgZW51bSBpbiBvcmRlciwKICogbG9va2luZyBmb3IgdGhlIGZpcnN0IHtAbGluayAjbWF0Y2hlcyBtYXRjaH0uCiAqIFRoZSBhY3Rpb24gZm9yIGFuIE9wdGlvbiBpcyBwZXJmb3JtZWQge0BsaW5rICNoYW5kbGVPcHRpb259LCB3aGljaCBkZXRlcm1pbmVzCiAqIHdoZXRoZXIgYW4gYXJndW1lbnQgaXMgbmVlZGVkIGFuZCB3aGVyZSB0byBmaW5kIGl0OwogKiB7QGNvZGUgaGFuZGxlT3B0aW9ufSB0aGVuIGNhbGxzIHtAbGluayAjcHJvY2VzcyBwcm9jZXNzfSBwcm92aWRpbmcgYSBzdWl0YWJsZQogKiB7QGxpbmsgT3B0aW9uSGVscGVyfSB0byBwcm92aWRlIGFjY2VzcyB0aGUgY29tcGlsZXIgc3RhdGUuCiAqCiAqIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24KICogcmlzay4gIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlCiAqIG9yIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj48L3A+CiAqLwpwdWJsaWMgZW51bSBPcHRpb24gewogICAgRygiLWciLCAib3B0LmciLCBTVEFOREFSRCwgQkFTSUMpLAoKICAgIEdfTk9ORSgiLWc6bm9uZSIsICJvcHQuZy5ub25lIiwgU1RBTkRBUkQsIEJBU0lDKSB7CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgcHJvY2VzcyhPcHRpb25IZWxwZXIgaGVscGVyLCBTdHJpbmcgb3B0aW9uKSB7CiAgICAgICAgICAgIGhlbHBlci5wdXQoIi1nOiIsICJub25lIik7CiAgICAgICAgfQogICAgfSwKCiAgICBHX0NVU1RPTSgiLWc6IiwgICJvcHQuZy5saW5lcy52YXJzLnNvdXJjZSIsCiAgICAgICAgICAgIFNUQU5EQVJELCBCQVNJQywgQU5ZT0YsICJsaW5lcyIsICJ2YXJzIiwgInNvdXJjZSIpLAoKICAgIFhMSU5UKCItWGxpbnQiLCAib3B0LlhsaW50IiwgRVhURU5ERUQsIEJBU0lDKSwKCiAgICBYTElOVF9DVVNUT00oIi1YbGludDoiLCAib3B0LmFyZy5YbGludCIsICJvcHQuWGxpbnQuY3VzdG9tIiwgRVhURU5ERUQsIEJBU0lDLCBBTllPRiwgZ2V0WExpbnRDaG9pY2VzKCkpIHsKICAgICAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBMSU5UX0tFWV9GT1JNQVQgPSBMQVJHRV9JTkRFTlQgKyAiICAlLSIgKwogICAgICAgICAgICAgICAgKERFRkFVTFRfU1lOT1BTSVNfV0lEVEggKyBTTUFMTF9JTkRFTlQubGVuZ3RoKCkgLSBMQVJHRV9JTkRFTlQubGVuZ3RoKCkgLSAyKSArICJzICVzIjsKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwcm90ZWN0ZWQgdm9pZCBoZWxwKExvZyBsb2cpIHsKICAgICAgICAgICAgc3VwZXIuaGVscChsb2cpOwogICAgICAgICAgICBsb2cucHJpbnRSYXdMaW5lcyhXcml0ZXJLaW5kLlNURE9VVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nLmZvcm1hdChMSU5UX0tFWV9GT1JNQVQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImFsbCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9nLmxvY2FsaXplKFByZWZpeEtpbmQuSkFWQUMsICJvcHQuWGxpbnQuYWxsIikpKTsKICAgICAgICAgICAgZm9yIChMaW50Q2F0ZWdvcnkgbGMgOiBMaW50Q2F0ZWdvcnkudmFsdWVzKCkpIHsKICAgICAgICAgICAgICAgIGxvZy5wcmludFJhd0xpbmVzKFdyaXRlcktpbmQuU1RET1VULAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nLmZvcm1hdChMSU5UX0tFWV9GT1JNQVQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxjLm9wdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9nLmxvY2FsaXplKFByZWZpeEtpbmQuSkFWQUMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAib3B0LlhsaW50LmRlc2MuIiArIGxjLm9wdGlvbikpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBsb2cucHJpbnRSYXdMaW5lcyhXcml0ZXJLaW5kLlNURE9VVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nLmZvcm1hdChMSU5UX0tFWV9GT1JNQVQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm5vbmUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZy5sb2NhbGl6ZShQcmVmaXhLaW5kLkpBVkFDLCAib3B0LlhsaW50Lm5vbmUiKSkpOwogICAgICAgIH0KICAgIH0sCgogICAgWERPQ0xJTlQoIi1YZG9jbGludCIsICJvcHQuWGRvY2xpbnQiLCBFWFRFTkRFRCwgQkFTSUMpLAoKICAgIFhET0NMSU5UX0NVU1RPTSgiLVhkb2NsaW50OiIsICJvcHQuWGRvY2xpbnQuc3Vib3B0cyIsICJvcHQuWGRvY2xpbnQuY3VzdG9tIiwgRVhURU5ERUQsIEJBU0lDKSB7CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gbWF0Y2hlcyhTdHJpbmcgb3B0aW9uKSB7CiAgICAgICAgICAgIHJldHVybiBEb2NMaW50LmlzVmFsaWRPcHRpb24oCiAgICAgICAgICAgICAgICAgICAgb3B0aW9uLnJlcGxhY2UoWERPQ0xJTlRfQ1VTVE9NLnByaW1hcnlOYW1lLCBEb2NMaW50LlhNU0dTX0NVU1RPTV9QUkVGSVgpKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHByb2Nlc3MoT3B0aW9uSGVscGVyIGhlbHBlciwgU3RyaW5nIG9wdGlvbikgewogICAgICAgICAgICBTdHJpbmcgcHJldiA9IGhlbHBlci5nZXQoWERPQ0xJTlRfQ1VTVE9NKTsKICAgICAgICAgICAgU3RyaW5nIG5leHQgPSAocHJldiA9PSBudWxsKSA/IG9wdGlvbiA6IChwcmV2ICsgIiAiICsgb3B0aW9uKTsKICAgICAgICAgICAgaGVscGVyLnB1dChYRE9DTElOVF9DVVNUT00ucHJpbWFyeU5hbWUsIG5leHQpOwogICAgICAgIH0KICAgIH0sCgogICAgWERPQ0xJTlRfUEFDS0FHRSgiLVhkb2NsaW50L3BhY2thZ2U6IiwgIm9wdC5YZG9jbGludC5wYWNrYWdlLmFyZ3MiLCAib3B0Llhkb2NsaW50LnBhY2thZ2UuZGVzYyIsIEVYVEVOREVELCBCQVNJQykgewogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBib29sZWFuIG1hdGNoZXMoU3RyaW5nIG9wdGlvbikgewogICAgICAgICAgICByZXR1cm4gRG9jTGludC5pc1ZhbGlkT3B0aW9uKAogICAgICAgICAgICAgICAgICAgIG9wdGlvbi5yZXBsYWNlKFhET0NMSU5UX1BBQ0tBR0UucHJpbWFyeU5hbWUsIERvY0xpbnQuWENIRUNLX1BBQ0tBR0UpKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHByb2Nlc3MoT3B0aW9uSGVscGVyIGhlbHBlciwgU3RyaW5nIG9wdGlvbikgewogICAgICAgICAgICBTdHJpbmcgcHJldiA9IGhlbHBlci5nZXQoWERPQ0xJTlRfUEFDS0FHRSk7CiAgICAgICAgICAgIFN0cmluZyBuZXh0ID0gKHByZXYgPT0gbnVsbCkgPyBvcHRpb24gOiAocHJldiArICIgIiArIG9wdGlvbik7CiAgICAgICAgICAgIGhlbHBlci5wdXQoWERPQ0xJTlRfUEFDS0FHRS5wcmltYXJ5TmFtZSwgbmV4dCk7CiAgICAgICAgfQogICAgfSwKCiAgICBET0NMSU5UX0ZPUk1BVCgiLS1kb2NsaW50LWZvcm1hdCIsICJvcHQuZG9jbGludC5mb3JtYXQiLCBFWFRFTkRFRCwgQkFTSUMsIE9ORU9GLCAiaHRtbDQiLCAiaHRtbDUiKSwKCiAgICAvLyAtbm93YXJuIGlzIHJldGFpbmVkIGZvciBjb21tYW5kLWxpbmUgYmFja3dhcmQgY29tcGF0aWJpbGl0eQogICAgTk9XQVJOKCItbm93YXJuIiwgIm9wdC5ub3dhcm4iLCBTVEFOREFSRCwgQkFTSUMpIHsKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCBwcm9jZXNzKE9wdGlvbkhlbHBlciBoZWxwZXIsIFN0cmluZyBvcHRpb24pIHsKICAgICAgICAgICAgaGVscGVyLnB1dCgiLVhsaW50Om5vbmUiLCBvcHRpb24pOwogICAgICAgIH0KICAgIH0sCgogICAgVkVSQk9TRSgiLXZlcmJvc2UiLCAib3B0LnZlcmJvc2UiLCBTVEFOREFSRCwgQkFTSUMpLAoKICAgIC8vIC1kZXByZWNhdGlvbiBpcyByZXRhaW5lZCBmb3IgY29tbWFuZC1saW5lIGJhY2t3YXJkIGNvbXBhdGliaWxpdHkKICAgIERFUFJFQ0FUSU9OKCItZGVwcmVjYXRpb24iLCAib3B0LmRlcHJlY2F0aW9uIiwgU1RBTkRBUkQsIEJBU0lDKSB7CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgcHJvY2VzcyhPcHRpb25IZWxwZXIgaGVscGVyLCBTdHJpbmcgb3B0aW9uKSB7CiAgICAgICAgICAgIGhlbHBlci5wdXQoIi1YbGludDpkZXByZWNhdGlvbiIsIG9wdGlvbik7CiAgICAgICAgfQogICAgfSwKCiAgICBDTEFTU19QQVRIKCItLWNsYXNzLXBhdGggLWNsYXNzcGF0aCAtY3AiLCAib3B0LmFyZy5wYXRoIiwgIm9wdC5jbGFzc3BhdGgiLCBTVEFOREFSRCwgRklMRU1BTkFHRVIpLAoKICAgIFNPVVJDRV9QQVRIKCItLXNvdXJjZS1wYXRoIC1zb3VyY2VwYXRoIiwgIm9wdC5hcmcucGF0aCIsICJvcHQuc291cmNlcGF0aCIsIFNUQU5EQVJELCBGSUxFTUFOQUdFUiksCgogICAgTU9EVUxFX1NPVVJDRV9QQVRIKCItLW1vZHVsZS1zb3VyY2UtcGF0aCIsICJvcHQuYXJnLm1zcGF0aCIsICJvcHQubW9kdWxlc291cmNlcGF0aCIsIFNUQU5EQVJELCBGSUxFTUFOQUdFUiksCgogICAgTU9EVUxFX1BBVEgoIi0tbW9kdWxlLXBhdGggLXAiLCAib3B0LmFyZy5wYXRoIiwgIm9wdC5tb2R1bGVwYXRoIiwgU1RBTkRBUkQsIEZJTEVNQU5BR0VSKSwKCiAgICBVUEdSQURFX01PRFVMRV9QQVRIKCItLXVwZ3JhZGUtbW9kdWxlLXBhdGgiLCAib3B0LmFyZy5wYXRoIiwgIm9wdC51cGdyYWRlbW9kdWxlcGF0aCIsIFNUQU5EQVJELCBGSUxFTUFOQUdFUiksCgogICAgU1lTVEVNKCItLXN5c3RlbSIsICJvcHQuYXJnLmpkayIsICJvcHQuc3lzdGVtIiwgU1RBTkRBUkQsIEZJTEVNQU5BR0VSKSwKCiAgICBQQVRDSF9NT0RVTEUoIi0tcGF0Y2gtbW9kdWxlIiwgIm9wdC5hcmcucGF0Y2giLCAib3B0LnBhdGNoIiwgRVhURU5ERUQsIEZJTEVNQU5BR0VSKSB7CiAgICAgICAgLy8gVGhlIGRlZmVycmVkIGZpbGVtYW5hZ2VyIGRpYWdub3N0aWNzIG1lY2hhbmlzbSBhc3N1bWVzIGEgc2luZ2xlIHZhbHVlIHBlciBvcHRpb24sCiAgICAgICAgLy8gYnV0IC0tcGF0Y2gtbW9kdWxlIGNhbiBiZSB1c2VkIG11bHRpcGxlIHRpbWVzLCBvbmNlIHBlciBtb2R1bGUuIFRoZXJlZm9yZSB3ZSBjb21wb3NlCiAgICAgICAgLy8gYSB2YWx1ZSBmb3IgdGhlIG9wdGlvbiBjb250YWluaW5nIHRoZSBsYXN0IHZhbHVlIHNwZWNpZmllZCBmb3IgZWFjaCBtb2R1bGUsIGFuZCBzZXBhcmF0ZQogICAgICAgIC8vIHRoZSB0aGUgbW9kdWxlPXBhdGggcGFpcnMgYnkgYW4gaW52YWxpZCBwYXRoIGNoYXJhY3RlciwgTlVMTC4KICAgICAgICAvLyBUaGUgc3RhbmRhcmQgZmlsZSBtYW5hZ2VyIGNvZGUga25vd3MgdG8gc3BsaXQgYXBhcnQgdGhlIE5VTEwtc2VwYXJhdGVkIGNvbXBvbmVudHMuCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgcHJvY2VzcyhPcHRpb25IZWxwZXIgaGVscGVyLCBTdHJpbmcgb3B0aW9uLCBTdHJpbmcgYXJnKSB0aHJvd3MgSW52YWxpZFZhbHVlRXhjZXB0aW9uIHsKICAgICAgICAgICAgaWYgKGFyZy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICAgIHRocm93IGhlbHBlci5uZXdJbnZhbGlkVmFsdWVFeGNlcHRpb24oImVyci5uby52YWx1ZS5mb3Iub3B0aW9uIiwgb3B0aW9uKTsKICAgICAgICAgICAgfSBlbHNlIGlmIChnZXRQYXR0ZXJuKCkubWF0Y2hlcihhcmcpLm1hdGNoZXMoKSkgewogICAgICAgICAgICAgICAgU3RyaW5nIHByZXYgPSBoZWxwZXIuZ2V0KFBBVENIX01PRFVMRSk7CiAgICAgICAgICAgICAgICBpZiAocHJldiA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgc3VwZXIucHJvY2VzcyhoZWxwZXIsIG9wdGlvbiwgYXJnKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGFyZ01vZHVsZVBhY2thZ2UgPSBhcmcuc3Vic3RyaW5nKDAsIGFyZy5pbmRleE9mKCc9JykpOwogICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gaXNSZXBlYXRlZCA9IEFycmF5cy5zdHJlYW0ocHJldi5zcGxpdCgiXDAiKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5tYXAocyAtPiBzLnN1YnN0cmluZygwLCBzLmluZGV4T2YoJz0nKSkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY29sbGVjdChDb2xsZWN0b3JzLnRvU2V0KCkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY29udGFpbnMoYXJnTW9kdWxlUGFja2FnZSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKGlzUmVwZWF0ZWQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgaGVscGVyLm5ld0ludmFsaWRWYWx1ZUV4Y2VwdGlvbigiZXJyLnJlcGVhdGVkLnZhbHVlLmZvci5wYXRjaC5tb2R1bGUiLCBhcmdNb2R1bGVQYWNrYWdlKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBzdXBlci5wcm9jZXNzKGhlbHBlciwgb3B0aW9uLCBwcmV2ICsgJ1wwJyArIGFyZyk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdGhyb3cgaGVscGVyLm5ld0ludmFsaWRWYWx1ZUV4Y2VwdGlvbigiZXJyLmJhZC52YWx1ZS5mb3Iub3B0aW9uIiwgb3B0aW9uLCBhcmcpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgUGF0dGVybiBnZXRQYXR0ZXJuKCkgewogICAgICAgICAgICByZXR1cm4gUGF0dGVybi5jb21waWxlKCIoW14vXSspPSgsKlteLF0uKikiKTsKICAgICAgICB9CiAgICB9LAoKICAgIEJPT1RfQ0xBU1NfUEFUSCgiLS1ib290LWNsYXNzLXBhdGggLWJvb3RjbGFzc3BhdGgiLCAib3B0LmFyZy5wYXRoIiwgIm9wdC5ib290Y2xhc3NwYXRoIiwgU1RBTkRBUkQsIEZJTEVNQU5BR0VSKSB7CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgcHJvY2VzcyhPcHRpb25IZWxwZXIgaGVscGVyLCBTdHJpbmcgb3B0aW9uLCBTdHJpbmcgYXJnKSB0aHJvd3MgSW52YWxpZFZhbHVlRXhjZXB0aW9uIHsKICAgICAgICAgICAgaGVscGVyLnJlbW92ZSgiLVhib290Y2xhc3NwYXRoL3A6Iik7CiAgICAgICAgICAgIGhlbHBlci5yZW1vdmUoIi1YYm9vdGNsYXNzcGF0aC9hOiIpOwogICAgICAgICAgICBzdXBlci5wcm9jZXNzKGhlbHBlciwgb3B0aW9uLCBhcmcpOwogICAgICAgIH0KICAgIH0sCgogICAgWEJPT1RDTEFTU1BBVEhfUFJFUEVORCgiLVhib290Y2xhc3NwYXRoL3A6IiwgIm9wdC5hcmcucGF0aCIsICJvcHQuWGJvb3RjbGFzc3BhdGgucCIsIEVYVEVOREVELCBGSUxFTUFOQUdFUiksCgogICAgWEJPT1RDTEFTU1BBVEhfQVBQRU5EKCItWGJvb3RjbGFzc3BhdGgvYToiLCAib3B0LmFyZy5wYXRoIiwgIm9wdC5YYm9vdGNsYXNzcGF0aC5hIiwgRVhURU5ERUQsIEZJTEVNQU5BR0VSKSwKCiAgICBYQk9PVENMQVNTUEFUSCgiLVhib290Y2xhc3NwYXRoOiIsICJvcHQuYXJnLnBhdGgiLCAib3B0LmJvb3RjbGFzc3BhdGgiLCBFWFRFTkRFRCwgRklMRU1BTkFHRVIpIHsKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCBwcm9jZXNzKE9wdGlvbkhlbHBlciBoZWxwZXIsIFN0cmluZyBvcHRpb24sIFN0cmluZyBhcmcpIHRocm93cyBJbnZhbGlkVmFsdWVFeGNlcHRpb24gewogICAgICAgICAgICBoZWxwZXIucmVtb3ZlKCItWGJvb3RjbGFzc3BhdGgvcDoiKTsKICAgICAgICAgICAgaGVscGVyLnJlbW92ZSgiLVhib290Y2xhc3NwYXRoL2E6Iik7CiAgICAgICAgICAgIHN1cGVyLnByb2Nlc3MoaGVscGVyLCAiLWJvb3RjbGFzc3BhdGgiLCBhcmcpOwogICAgICAgIH0KICAgIH0sCgogICAgRVhURElSUygiLWV4dGRpcnMiLCAib3B0LmFyZy5kaXJzIiwgIm9wdC5leHRkaXJzIiwgU1RBTkRBUkQsIEZJTEVNQU5BR0VSKSwKCiAgICBESkFWQV9FWFRfRElSUygiLURqYXZhLmV4dC5kaXJzPSIsICJvcHQuYXJnLmRpcnMiLCAib3B0LmV4dGRpcnMiLCBFWFRFTkRFRCwgRklMRU1BTkFHRVIpIHsKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCBwcm9jZXNzKE9wdGlvbkhlbHBlciBoZWxwZXIsIFN0cmluZyBvcHRpb24sIFN0cmluZyBhcmcpIHRocm93cyBJbnZhbGlkVmFsdWVFeGNlcHRpb24gewogICAgICAgICAgICBFWFRESVJTLnByb2Nlc3MoaGVscGVyLCAiLWV4dGRpcnMiLCBhcmcpOwogICAgICAgIH0KICAgIH0sCgogICAgRU5ET1JTRURESVJTKCItZW5kb3JzZWRkaXJzIiwgIm9wdC5hcmcuZGlycyIsICJvcHQuZW5kb3JzZWRkaXJzIiwgU1RBTkRBUkQsIEZJTEVNQU5BR0VSKSwKCiAgICBESkFWQV9FTkRPUlNFRF9ESVJTKCItRGphdmEuZW5kb3JzZWQuZGlycz0iLCAib3B0LmFyZy5kaXJzIiwgIm9wdC5lbmRvcnNlZGRpcnMiLCBFWFRFTkRFRCwgRklMRU1BTkFHRVIpIHsKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCBwcm9jZXNzKE9wdGlvbkhlbHBlciBoZWxwZXIsIFN0cmluZyBvcHRpb24sIFN0cmluZyBhcmcpIHRocm93cyBJbnZhbGlkVmFsdWVFeGNlcHRpb24gewogICAgICAgICAgICBFTkRPUlNFRERJUlMucHJvY2VzcyhoZWxwZXIsICItZW5kb3JzZWRkaXJzIiwgYXJnKTsKICAgICAgICB9CiAgICB9LAoKICAgIFBST0MoIi1wcm9jOiIsICJvcHQucHJvYy5ub25lLm9ubHkiLCBTVEFOREFSRCwgQkFTSUMsICBPTkVPRiwgIm5vbmUiLCAib25seSIpLAoKICAgIFBST0NFU1NPUigiLXByb2Nlc3NvciIsICJvcHQuYXJnLmNsYXNzLmxpc3QiLCAib3B0LnByb2Nlc3NvciIsIFNUQU5EQVJELCBCQVNJQyksCgogICAgUFJPQ0VTU09SX1BBVEgoIi0tcHJvY2Vzc29yLXBhdGggLXByb2Nlc3NvcnBhdGgiLCAib3B0LmFyZy5wYXRoIiwgIm9wdC5wcm9jZXNzb3JwYXRoIiwgU1RBTkRBUkQsIEZJTEVNQU5BR0VSKSwKCiAgICBQUk9DRVNTT1JfTU9EVUxFX1BBVEgoIi0tcHJvY2Vzc29yLW1vZHVsZS1wYXRoIiwgIm9wdC5hcmcucGF0aCIsICJvcHQucHJvY2Vzc29ybW9kdWxlcGF0aCIsIFNUQU5EQVJELCBGSUxFTUFOQUdFUiksCgogICAgUEFSQU1FVEVSUygiLXBhcmFtZXRlcnMiLCJvcHQucGFyYW1ldGVycyIsIFNUQU5EQVJELCBCQVNJQyksCgogICAgRCgiLWQiLCAib3B0LmFyZy5kaXJlY3RvcnkiLCAib3B0LmQiLCBTVEFOREFSRCwgRklMRU1BTkFHRVIpLAoKICAgIFMoIi1zIiwgIm9wdC5hcmcuZGlyZWN0b3J5IiwgIm9wdC5zb3VyY2VEZXN0IiwgU1RBTkRBUkQsIEZJTEVNQU5BR0VSKSwKCiAgICBIKCItaCIsICJvcHQuYXJnLmRpcmVjdG9yeSIsICJvcHQuaGVhZGVyRGVzdCIsIFNUQU5EQVJELCBGSUxFTUFOQUdFUiksCgogICAgSU1QTElDSVQoIi1pbXBsaWNpdDoiLCAib3B0LmltcGxpY2l0IiwgU1RBTkRBUkQsIEJBU0lDLCBPTkVPRiwgIm5vbmUiLCAiY2xhc3MiKSwKCiAgICBFTkNPRElORygiLWVuY29kaW5nIiwgIm9wdC5hcmcuZW5jb2RpbmciLCAib3B0LmVuY29kaW5nIiwgU1RBTkRBUkQsIEZJTEVNQU5BR0VSKSwKCiAgICBTT1VSQ0UoIi1zb3VyY2UiLCAib3B0LmFyZy5yZWxlYXNlIiwgIm9wdC5zb3VyY2UiLCBTVEFOREFSRCwgQkFTSUMpIHsKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCBwcm9jZXNzKE9wdGlvbkhlbHBlciBoZWxwZXIsIFN0cmluZyBvcHRpb24sIFN0cmluZyBvcGVyYW5kKSB0aHJvd3MgSW52YWxpZFZhbHVlRXhjZXB0aW9uIHsKICAgICAgICAgICAgU291cmNlIHNvdXJjZSA9IFNvdXJjZS5sb29rdXAob3BlcmFuZCk7CiAgICAgICAgICAgIGlmIChzb3VyY2UgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgdGhyb3cgaGVscGVyLm5ld0ludmFsaWRWYWx1ZUV4Y2VwdGlvbigiZXJyLmludmFsaWQuc291cmNlIiwgb3BlcmFuZCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc3VwZXIucHJvY2VzcyhoZWxwZXIsIG9wdGlvbiwgb3BlcmFuZCk7CiAgICAgICAgfQogICAgfSwKCiAgICBUQVJHRVQoIi10YXJnZXQiLCAib3B0LmFyZy5yZWxlYXNlIiwgIm9wdC50YXJnZXQiLCBTVEFOREFSRCwgQkFTSUMpIHsKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCBwcm9jZXNzKE9wdGlvbkhlbHBlciBoZWxwZXIsIFN0cmluZyBvcHRpb24sIFN0cmluZyBvcGVyYW5kKSB0aHJvd3MgSW52YWxpZFZhbHVlRXhjZXB0aW9uIHsKICAgICAgICAgICAgVGFyZ2V0IHRhcmdldCA9IFRhcmdldC5sb29rdXAob3BlcmFuZCk7CiAgICAgICAgICAgIGlmICh0YXJnZXQgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgdGhyb3cgaGVscGVyLm5ld0ludmFsaWRWYWx1ZUV4Y2VwdGlvbigiZXJyLmludmFsaWQudGFyZ2V0Iiwgb3BlcmFuZCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc3VwZXIucHJvY2VzcyhoZWxwZXIsIG9wdGlvbiwgb3BlcmFuZCk7CiAgICAgICAgfQogICAgfSwKCiAgICBSRUxFQVNFKCItLXJlbGVhc2UiLCAib3B0LmFyZy5yZWxlYXNlIiwgIm9wdC5yZWxlYXNlIiwgU1RBTkRBUkQsIEJBU0lDKSB7CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHJvdGVjdGVkIHZvaWQgaGVscChMb2cgbG9nKSB7CiAgICAgICAgICAgIEl0ZXJhYmxlPFBsYXRmb3JtUHJvdmlkZXI+IHByb3ZpZGVycyA9CiAgICAgICAgICAgICAgICAgICAgU2VydmljZUxvYWRlci5sb2FkKFBsYXRmb3JtUHJvdmlkZXIuY2xhc3MsIEFyZ3VtZW50cy5jbGFzcy5nZXRDbGFzc0xvYWRlcigpKTsKICAgICAgICAgICAgU2V0PFN0cmluZz4gcGxhdGZvcm1zID0gU3RyZWFtU3VwcG9ydC5zdHJlYW0ocHJvdmlkZXJzLnNwbGl0ZXJhdG9yKCksIGZhbHNlKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmZsYXRNYXAocHJvdmlkZXIgLT4gU3RyZWFtU3VwcG9ydC5zdHJlYW0ocHJvdmlkZXIuZ2V0U3VwcG9ydGVkUGxhdGZvcm1OYW1lcygpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5zcGxpdGVyYXRvcigpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFsc2UpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmNvbGxlY3QoQ29sbGVjdG9ycy50b0NvbGxlY3Rpb24oVHJlZVNldCA6OiBuZXcpKTsKCiAgICAgICAgICAgIFN0cmluZ0J1aWxkZXIgdGFyZ2V0cyA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CiAgICAgICAgICAgIFN0cmluZyBkZWxpbSA9ICIiOwogICAgICAgICAgICBmb3IgKFN0cmluZyBwbGF0Zm9ybSA6IHBsYXRmb3JtcykgewogICAgICAgICAgICAgICAgdGFyZ2V0cy5hcHBlbmQoZGVsaW0pOwogICAgICAgICAgICAgICAgdGFyZ2V0cy5hcHBlbmQocGxhdGZvcm0pOwogICAgICAgICAgICAgICAgZGVsaW0gPSAiLCAiOwogICAgICAgICAgICB9CgogICAgICAgICAgICBzdXBlci5oZWxwKGxvZywgbG9nLmxvY2FsaXplKFByZWZpeEtpbmQuSkFWQUMsIGRlc2NyS2V5LCB0YXJnZXRzLnRvU3RyaW5nKCkpKTsKICAgICAgICB9CiAgICB9LAoKICAgIFBST0ZJTEUoIi1wcm9maWxlIiwgIm9wdC5hcmcucHJvZmlsZSIsICJvcHQucHJvZmlsZSIsIFNUQU5EQVJELCBCQVNJQykgewogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHByb2Nlc3MoT3B0aW9uSGVscGVyIGhlbHBlciwgU3RyaW5nIG9wdGlvbiwgU3RyaW5nIG9wZXJhbmQpIHRocm93cyBJbnZhbGlkVmFsdWVFeGNlcHRpb24gewogICAgICAgICAgICBQcm9maWxlIHByb2ZpbGUgPSBQcm9maWxlLmxvb2t1cChvcGVyYW5kKTsKICAgICAgICAgICAgaWYgKHByb2ZpbGUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgdGhyb3cgaGVscGVyLm5ld0ludmFsaWRWYWx1ZUV4Y2VwdGlvbigiZXJyLmludmFsaWQucHJvZmlsZSIsIG9wZXJhbmQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHN1cGVyLnByb2Nlc3MoaGVscGVyLCBvcHRpb24sIG9wZXJhbmQpOwogICAgICAgIH0KICAgIH0sCgogICAgVkVSU0lPTigiLS12ZXJzaW9uIC12ZXJzaW9uIiwgIm9wdC52ZXJzaW9uIiwgU1RBTkRBUkQsIElORk8pIHsKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCBwcm9jZXNzKE9wdGlvbkhlbHBlciBoZWxwZXIsIFN0cmluZyBvcHRpb24pIHRocm93cyBJbnZhbGlkVmFsdWVFeGNlcHRpb24gewogICAgICAgICAgICBMb2cgbG9nID0gaGVscGVyLmdldExvZygpOwogICAgICAgICAgICBTdHJpbmcgb3duTmFtZSA9IGhlbHBlci5nZXRPd25OYW1lKCk7CiAgICAgICAgICAgIGxvZy5wcmludExpbmVzKFdyaXRlcktpbmQuU1RET1VULCBQcmVmaXhLaW5kLkpBVkFDLCAidmVyc2lvbiIsIG93bk5hbWUsICBKYXZhQ29tcGlsZXIudmVyc2lvbigpKTsKICAgICAgICAgICAgc3VwZXIucHJvY2VzcyhoZWxwZXIsIG9wdGlvbik7CiAgICAgICAgfQogICAgfSwKCiAgICBGVUxMVkVSU0lPTigiLS1mdWxsLXZlcnNpb24gLWZ1bGx2ZXJzaW9uIiwgbnVsbCwgSElEREVOLCBJTkZPKSB7CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgcHJvY2VzcyhPcHRpb25IZWxwZXIgaGVscGVyLCBTdHJpbmcgb3B0aW9uKSB0aHJvd3MgSW52YWxpZFZhbHVlRXhjZXB0aW9uIHsKICAgICAgICAgICAgTG9nIGxvZyA9IGhlbHBlci5nZXRMb2coKTsKICAgICAgICAgICAgU3RyaW5nIG93bk5hbWUgPSBoZWxwZXIuZ2V0T3duTmFtZSgpOwogICAgICAgICAgICBsb2cucHJpbnRMaW5lcyhXcml0ZXJLaW5kLlNURE9VVCwgUHJlZml4S2luZC5KQVZBQywgImZ1bGxWZXJzaW9uIiwgb3duTmFtZSwgIEphdmFDb21waWxlci5mdWxsVmVyc2lvbigpKTsKICAgICAgICAgICAgc3VwZXIucHJvY2VzcyhoZWxwZXIsIG9wdGlvbik7CiAgICAgICAgfQogICAgfSwKCiAgICAvLyBOb3RlOiAtaCBpcyBhbHJlYWR5IHRha2VuIGZvciAibmF0aXZlIGhlYWRlciBvdXRwdXQgZGlyZWN0b3J5Ii4KICAgIEhFTFAoIi0taGVscCAtaGVscCIsICJvcHQuaGVscCIsIFNUQU5EQVJELCBJTkZPKSB7CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgcHJvY2VzcyhPcHRpb25IZWxwZXIgaGVscGVyLCBTdHJpbmcgb3B0aW9uKSB0aHJvd3MgSW52YWxpZFZhbHVlRXhjZXB0aW9uIHsKICAgICAgICAgICAgTG9nIGxvZyA9IGhlbHBlci5nZXRMb2coKTsKICAgICAgICAgICAgU3RyaW5nIG93bk5hbWUgPSBoZWxwZXIuZ2V0T3duTmFtZSgpOwogICAgICAgICAgICBsb2cucHJpbnRMaW5lcyhXcml0ZXJLaW5kLlNURE9VVCwgUHJlZml4S2luZC5KQVZBQywgIm1zZy51c2FnZS5oZWFkZXIiLCBvd25OYW1lKTsKICAgICAgICAgICAgc2hvd0hlbHAobG9nLCBPcHRpb25LaW5kLlNUQU5EQVJEKTsKICAgICAgICAgICAgbG9nLnByaW50TmV3bGluZShXcml0ZXJLaW5kLlNURE9VVCk7CiAgICAgICAgICAgIHN1cGVyLnByb2Nlc3MoaGVscGVyLCBvcHRpb24pOwogICAgICAgIH0KICAgIH0sCgogICAgQSgiLUEiLCAib3B0LmFyZy5rZXkuZXF1YWxzLnZhbHVlIiwgIm9wdC5BIiwgU1RBTkRBUkQsIEJBU0lDLCBBcmdLaW5kLkFESkFDRU5UKSB7CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gbWF0Y2hlcyhTdHJpbmcgYXJnKSB7CiAgICAgICAgICAgIHJldHVybiBhcmcuc3RhcnRzV2l0aCgiLUEiKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBib29sZWFuIGhhc0FyZygpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICAvLyBNYXBwaW5nIGZvciBwcm9jZXNzb3Igb3B0aW9ucyBjcmVhdGVkIGluCiAgICAgICAgLy8gSmF2YWNQcm9jZXNzaW5nRW52aXJvbm1lbnQKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCBwcm9jZXNzKE9wdGlvbkhlbHBlciBoZWxwZXIsIFN0cmluZyBvcHRpb24pIHRocm93cyBJbnZhbGlkVmFsdWVFeGNlcHRpb24gewogICAgICAgICAgICBpbnQgYXJnTGVuZ3RoID0gb3B0aW9uLmxlbmd0aCgpOwogICAgICAgICAgICBpZiAoYXJnTGVuZ3RoID09IDIpIHsKICAgICAgICAgICAgICAgIHRocm93IGhlbHBlci5uZXdJbnZhbGlkVmFsdWVFeGNlcHRpb24oImVyci5lbXB0eS5BLmFyZ3VtZW50Iik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaW50IHNlcEluZGV4ID0gb3B0aW9uLmluZGV4T2YoJz0nKTsKICAgICAgICAgICAgU3RyaW5nIGtleSA9IG9wdGlvbi5zdWJzdHJpbmcoMiwgKHNlcEluZGV4ICE9IC0xID8gc2VwSW5kZXggOiBhcmdMZW5ndGgpICk7CiAgICAgICAgICAgIGlmICghSmF2YWNQcm9jZXNzaW5nRW52aXJvbm1lbnQuaXNWYWxpZE9wdGlvbk5hbWUoa2V5KSkgewogICAgICAgICAgICAgICAgdGhyb3cgaGVscGVyLm5ld0ludmFsaWRWYWx1ZUV4Y2VwdGlvbigiZXJyLmludmFsaWQuQS5rZXkiLCBvcHRpb24pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGhlbHBlci5wdXQob3B0aW9uLCBvcHRpb24pOwogICAgICAgIH0KICAgIH0sCgogICAgWCgiLS1oZWxwLWV4dHJhIC1YIiwgIm9wdC5YIiwgU1RBTkRBUkQsIElORk8pIHsKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCBwcm9jZXNzKE9wdGlvbkhlbHBlciBoZWxwZXIsIFN0cmluZyBvcHRpb24pIHRocm93cyBJbnZhbGlkVmFsdWVFeGNlcHRpb24gewogICAgICAgICAgICBMb2cgbG9nID0gaGVscGVyLmdldExvZygpOwogICAgICAgICAgICBzaG93SGVscChsb2csIE9wdGlvbktpbmQuRVhURU5ERUQpOwogICAgICAgICAgICBsb2cucHJpbnROZXdsaW5lKFdyaXRlcktpbmQuU1RET1VUKTsKICAgICAgICAgICAgbG9nLnByaW50TGluZXMoV3JpdGVyS2luZC5TVERPVVQsIFByZWZpeEtpbmQuSkFWQUMsICJtc2cudXNhZ2Uubm9uc3RhbmRhcmQuZm9vdGVyIik7CiAgICAgICAgICAgIHN1cGVyLnByb2Nlc3MoaGVscGVyLCBvcHRpb24pOwogICAgICAgIH0KICAgIH0sCgogICAgLy8gVGhpcyBvcHRpb24gZXhpc3RzIG9ubHkgZm9yIHRoZSBwdXJwb3NlIG9mIGRvY3VtZW50aW5nIGl0c2VsZi4KICAgIC8vIEl0J3MgYWN0dWFsbHkgaW1wbGVtZW50ZWQgYnkgdGhlIGxhdW5jaGVyLgogICAgSigiLUoiLCAib3B0LmFyZy5mbGFnIiwgIm9wdC5KIiwgU1RBTkRBUkQsIElORk8sIEFyZ0tpbmQuQURKQUNFTlQpIHsKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCBwcm9jZXNzKE9wdGlvbkhlbHBlciBoZWxwZXIsIFN0cmluZyBvcHRpb24pIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCJ0aGUgLUogZmxhZyBzaG91bGQgYmUgY2F1Z2h0IGJ5IHRoZSBsYXVuY2hlci4iKTsKICAgICAgICB9CiAgICB9LAoKICAgIE1PUkVJTkZPKCItbW9yZWluZm8iLCBudWxsLCBISURERU4sIEJBU0lDKSB7CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgcHJvY2VzcyhPcHRpb25IZWxwZXIgaGVscGVyLCBTdHJpbmcgb3B0aW9uKSB0aHJvd3MgSW52YWxpZFZhbHVlRXhjZXB0aW9uIHsKICAgICAgICAgICAgVHlwZS5tb3JlSW5mbyA9IHRydWU7CiAgICAgICAgICAgIHN1cGVyLnByb2Nlc3MoaGVscGVyLCBvcHRpb24pOwogICAgICAgIH0KICAgIH0sCgogICAgLy8gdHJlYXQgd2FybmluZ3MgYXMgZXJyb3JzCiAgICBXRVJST1IoIi1XZXJyb3IiLCAib3B0LldlcnJvciIsIFNUQU5EQVJELCBCQVNJQyksCgogICAgLy8gcHJvbXB0IGFmdGVyIGVhY2ggZXJyb3IKICAgIC8vIG5ldyBPcHRpb24oIi1wcm9tcHQiLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAib3B0LnByb21wdCIpLAogICAgUFJPTVBUKCItcHJvbXB0IiwgbnVsbCwgSElEREVOLCBCQVNJQyksCgogICAgLy8gZHVtcCBzdGFjayBvbiBlcnJvcgogICAgRE9FKCItZG9lIiwgbnVsbCwgSElEREVOLCBCQVNJQyksCgogICAgLy8gb3V0cHV0IHNvdXJjZSBhZnRlciB0eXBlIGVyYXN1cmUKICAgIFBSSU5UU09VUkNFKCItcHJpbnRzb3VyY2UiLCBudWxsLCBISURERU4sIEJBU0lDKSwKCiAgICAvLyBkaXNwbGF5IHdhcm5pbmdzIGZvciBnZW5lcmljIHVuY2hlY2tlZCBvcGVyYXRpb25zCiAgICBXQVJOVU5DSEVDS0VEKCItd2FybnVuY2hlY2tlZCIsIG51bGwsIEhJRERFTiwgQkFTSUMpIHsKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCBwcm9jZXNzKE9wdGlvbkhlbHBlciBoZWxwZXIsIFN0cmluZyBvcHRpb24pIHsKICAgICAgICAgICAgaGVscGVyLnB1dCgiLVhsaW50OnVuY2hlY2tlZCIsIG9wdGlvbik7CiAgICAgICAgfQogICAgfSwKCiAgICBYTUFYRVJSUygiLVhtYXhlcnJzIiwgIm9wdC5hcmcubnVtYmVyIiwgIm9wdC5tYXhlcnJzIiwgRVhURU5ERUQsIEJBU0lDKSwKCiAgICBYTUFYV0FSTlMoIi1YbWF4d2FybnMiLCAib3B0LmFyZy5udW1iZXIiLCAib3B0Lm1heHdhcm5zIiwgRVhURU5ERUQsIEJBU0lDKSwKCiAgICBYU1RET1VUKCItWHN0ZG91dCIsICJvcHQuYXJnLmZpbGUiLCAib3B0LlhzdGRvdXQiLCBFWFRFTkRFRCwgSU5GTykgewogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHByb2Nlc3MoT3B0aW9uSGVscGVyIGhlbHBlciwgU3RyaW5nIG9wdGlvbiwgU3RyaW5nIGFyZykgdGhyb3dzIEludmFsaWRWYWx1ZUV4Y2VwdGlvbiB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBMb2cgbG9nID0gaGVscGVyLmdldExvZygpOwogICAgICAgICAgICAgICAgbG9nLnNldFdyaXRlcnMobmV3IFByaW50V3JpdGVyKG5ldyBGaWxlV3JpdGVyKGFyZyksIHRydWUpKTsKICAgICAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBoZWxwZXIubmV3SW52YWxpZFZhbHVlRXhjZXB0aW9uKCJlcnIuZXJyb3Iud3JpdGluZy5maWxlIiwgYXJnLCBlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBzdXBlci5wcm9jZXNzKGhlbHBlciwgb3B0aW9uLCBhcmcpOwogICAgICAgIH0KICAgIH0sCgogICAgWFBSSU5UKCItWHByaW50IiwgIm9wdC5wcmludCIsIEVYVEVOREVELCBCQVNJQyksCgogICAgWFBSSU5UUk9VTkRTKCItWHByaW50Um91bmRzIiwgIm9wdC5wcmludFJvdW5kcyIsIEVYVEVOREVELCBCQVNJQyksCgogICAgWFBSSU5UUFJPQ0VTU09SSU5GTygiLVhwcmludFByb2Nlc3NvckluZm8iLCAib3B0LnByaW50UHJvY2Vzc29ySW5mbyIsIEVYVEVOREVELCBCQVNJQyksCgogICAgWFBSRUZFUigiLVhwcmVmZXI6IiwgIm9wdC5wcmVmZXIiLCBFWFRFTkRFRCwgQkFTSUMsIE9ORU9GLCAic291cmNlIiwgIm5ld2VyIiksCgogICAgWFhVU0VSUEFUSFNGSVJTVCgiLVhYdXNlclBhdGhzRmlyc3QiLCAib3B0LnVzZXJwYXRoc2ZpcnN0IiwgSElEREVOLCBCQVNJQyksCgogICAgLy8gc2VlIGVudW0gUGtnSW5mbwogICAgWFBLR0lORk8oIi1YcGtnaW5mbzoiLCAib3B0LnBrZ2luZm8iLCBFWFRFTkRFRCwgQkFTSUMsIE9ORU9GLCAiYWx3YXlzIiwgImxlZ2FjeSIsICJub25lbXB0eSIpLAoKICAgIC8qIC1PIGlzIGEgbm8tb3AsIGFjY2VwdGVkIGZvciBiYWNrd2FyZCBjb21wYXRpYmlsaXR5LiAqLwogICAgTygiLU8iLCBudWxsLCBISURERU4sIEJBU0lDKSwKCiAgICAvKiAtWGpjb3YgcHJvZHVjZXMgdGFibGVzIHRvIHN1cHBvcnQgdGhlIGNvZGUgY292ZXJhZ2UgdG9vbCBqY292LiAqLwogICAgWEpDT1YoIi1YamNvdiIsIG51bGwsIEhJRERFTiwgQkFTSUMpLAoKICAgIFBMVUdJTigiLVhwbHVnaW46IiwgIm9wdC5hcmcucGx1Z2luIiwgIm9wdC5wbHVnaW4iLCBFWFRFTkRFRCwgQkFTSUMpIHsKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCBwcm9jZXNzKE9wdGlvbkhlbHBlciBoZWxwZXIsIFN0cmluZyBvcHRpb24pIHsKICAgICAgICAgICAgU3RyaW5nIHAgPSBvcHRpb24uc3Vic3RyaW5nKG9wdGlvbi5pbmRleE9mKCc6JykgKyAxKS50cmltKCk7CiAgICAgICAgICAgIFN0cmluZyBwcmV2ID0gaGVscGVyLmdldChQTFVHSU4pOwogICAgICAgICAgICBoZWxwZXIucHV0KFBMVUdJTi5wcmltYXJ5TmFtZSwgKHByZXYgPT0gbnVsbCkgPyBwIDogcHJldiArICdcMCcgKyBwKTsKICAgICAgICB9CiAgICB9LAoKICAgIFhESUFHUygiLVhkaWFnczoiLCAib3B0LmRpYWdzIiwgRVhURU5ERUQsIEJBU0lDLCBPTkVPRiwgImNvbXBhY3QiLCAidmVyYm9zZSIpLAoKICAgIERFQlVHKCItLWRlYnVnOiIsIG51bGwsIEhJRERFTiwgQkFTSUMpIHsKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCBwcm9jZXNzKE9wdGlvbkhlbHBlciBoZWxwZXIsIFN0cmluZyBvcHRpb24pIHRocm93cyBJbnZhbGlkVmFsdWVFeGNlcHRpb24gewogICAgICAgICAgICBIaWRkZW5Hcm91cC5ERUJVRy5wcm9jZXNzKGhlbHBlciwgb3B0aW9uKTsKICAgICAgICB9CiAgICB9LAoKICAgIFNIT1VMRFNUT1AoIi0tc2hvdWxkLXN0b3A6IiwgbnVsbCwgSElEREVOLCBCQVNJQykgewogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHByb2Nlc3MoT3B0aW9uSGVscGVyIGhlbHBlciwgU3RyaW5nIG9wdGlvbikgdGhyb3dzIEludmFsaWRWYWx1ZUV4Y2VwdGlvbiB7CiAgICAgICAgICAgIEhpZGRlbkdyb3VwLlNIT1VMRFNUT1AucHJvY2VzcyhoZWxwZXIsIG9wdGlvbik7CiAgICAgICAgfQogICAgfSwKCiAgICBESUFHUygiLS1kaWFnczoiLCBudWxsLCBISURERU4sIEJBU0lDKSB7CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgcHJvY2VzcyhPcHRpb25IZWxwZXIgaGVscGVyLCBTdHJpbmcgb3B0aW9uKSB0aHJvd3MgSW52YWxpZFZhbHVlRXhjZXB0aW9uIHsKICAgICAgICAgICAgSGlkZGVuR3JvdXAuRElBR1MucHJvY2VzcyhoZWxwZXIsIG9wdGlvbik7CiAgICAgICAgfQogICAgfSwKCiAgICAvKiBUaGlzIGlzIGEgYmFjayBkb29yIHRvIHRoZSBjb21waWxlcidzIG9wdGlvbiB0YWJsZS4KICAgICAqIC1YRHg9eSBzZXRzIHRoZSBvcHRpb24geCB0byB0aGUgdmFsdWUgeS4KICAgICAqIC1YRHggc2V0cyB0aGUgb3B0aW9uIHggdG8gdGhlIHZhbHVlIHguCiAgICAgKi8KICAgIFhEKCItWEQiLCBudWxsLCBISURERU4sIEJBU0lDKSB7CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gbWF0Y2hlcyhTdHJpbmcgcykgewogICAgICAgICAgICByZXR1cm4gcy5zdGFydHNXaXRoKHByaW1hcnlOYW1lKTsKICAgICAgICB9CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgcHJvY2VzcyhPcHRpb25IZWxwZXIgaGVscGVyLCBTdHJpbmcgb3B0aW9uKSB7CiAgICAgICAgICAgIHByb2Nlc3MoaGVscGVyLCBvcHRpb24sIG9wdGlvbi5zdWJzdHJpbmcocHJpbWFyeU5hbWUubGVuZ3RoKCkpKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHByb2Nlc3MoT3B0aW9uSGVscGVyIGhlbHBlciwgU3RyaW5nIG9wdGlvbiwgU3RyaW5nIGFyZykgewogICAgICAgICAgICBpbnQgZXEgPSBhcmcuaW5kZXhPZignPScpOwogICAgICAgICAgICBTdHJpbmcga2V5ID0gKGVxIDwgMCkgPyBhcmcgOiBhcmcuc3Vic3RyaW5nKDAsIGVxKTsKICAgICAgICAgICAgU3RyaW5nIHZhbHVlID0gKGVxIDwgMCkgPyBhcmcgOiBhcmcuc3Vic3RyaW5nKGVxKzEpOwogICAgICAgICAgICBoZWxwZXIucHV0KGtleSwgdmFsdWUpOwogICAgICAgIH0KICAgIH0sCgogICAgQUREX0VYUE9SVFMoIi0tYWRkLWV4cG9ydHMiLCAib3B0LmFyZy5hZGRFeHBvcnRzIiwgIm9wdC5hZGRFeHBvcnRzIiwgRVhURU5ERUQsIEJBU0lDKSB7CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgcHJvY2VzcyhPcHRpb25IZWxwZXIgaGVscGVyLCBTdHJpbmcgb3B0aW9uLCBTdHJpbmcgYXJnKSB0aHJvd3MgSW52YWxpZFZhbHVlRXhjZXB0aW9uIHsKICAgICAgICAgICAgaWYgKGFyZy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICAgIHRocm93IGhlbHBlci5uZXdJbnZhbGlkVmFsdWVFeGNlcHRpb24oImVyci5uby52YWx1ZS5mb3Iub3B0aW9uIiwgb3B0aW9uKTsKICAgICAgICAgICAgfSBlbHNlIGlmIChnZXRQYXR0ZXJuKCkubWF0Y2hlcihhcmcpLm1hdGNoZXMoKSkgewogICAgICAgICAgICAgICAgU3RyaW5nIHByZXYgPSBoZWxwZXIuZ2V0KEFERF9FWFBPUlRTKTsKICAgICAgICAgICAgICAgIGhlbHBlci5wdXQoQUREX0VYUE9SVFMucHJpbWFyeU5hbWUsIChwcmV2ID09IG51bGwpID8gYXJnIDogcHJldiArICdcMCcgKyBhcmcpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdGhyb3cgaGVscGVyLm5ld0ludmFsaWRWYWx1ZUV4Y2VwdGlvbigiZXJyLmJhZC52YWx1ZS5mb3Iub3B0aW9uIiwgb3B0aW9uLCBhcmcpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgUGF0dGVybiBnZXRQYXR0ZXJuKCkgewogICAgICAgICAgICByZXR1cm4gUGF0dGVybi5jb21waWxlKCIoW14vXSspLyhbXj1dKyk9KCwqW14sXS4qKSIpOwogICAgICAgIH0KICAgIH0sCgogICAgQUREX09QRU5TKCItLWFkZC1vcGVucyIsIG51bGwsIG51bGwsIEhJRERFTiwgQkFTSUMpLAoKICAgIEFERF9SRUFEUygiLS1hZGQtcmVhZHMiLCAib3B0LmFyZy5hZGRSZWFkcyIsICJvcHQuYWRkUmVhZHMiLCBFWFRFTkRFRCwgQkFTSUMpIHsKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCBwcm9jZXNzKE9wdGlvbkhlbHBlciBoZWxwZXIsIFN0cmluZyBvcHRpb24sIFN0cmluZyBhcmcpIHRocm93cyBJbnZhbGlkVmFsdWVFeGNlcHRpb24gewogICAgICAgICAgICBpZiAoYXJnLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgICAgdGhyb3cgaGVscGVyLm5ld0ludmFsaWRWYWx1ZUV4Y2VwdGlvbigiZXJyLm5vLnZhbHVlLmZvci5vcHRpb24iLCBvcHRpb24pOwogICAgICAgICAgICB9IGVsc2UgaWYgKGdldFBhdHRlcm4oKS5tYXRjaGVyKGFyZykubWF0Y2hlcygpKSB7CiAgICAgICAgICAgICAgICBTdHJpbmcgcHJldiA9IGhlbHBlci5nZXQoQUREX1JFQURTKTsKICAgICAgICAgICAgICAgIGhlbHBlci5wdXQoQUREX1JFQURTLnByaW1hcnlOYW1lLCAocHJldiA9PSBudWxsKSA/IGFyZyA6IHByZXYgKyAnXDAnICsgYXJnKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHRocm93IGhlbHBlci5uZXdJbnZhbGlkVmFsdWVFeGNlcHRpb24oImVyci5iYWQudmFsdWUuZm9yLm9wdGlvbiIsIG9wdGlvbiwgYXJnKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFBhdHRlcm4gZ2V0UGF0dGVybigpIHsKICAgICAgICAgICAgcmV0dXJuIFBhdHRlcm4uY29tcGlsZSgiKFtePV0rKT0oLCpbXixdLiopIik7CiAgICAgICAgfQogICAgfSwKCiAgICBYTU9EVUxFKCItWG1vZHVsZToiLCAib3B0LmFyZy5tb2R1bGUiLCAib3B0Lm1vZHVsZSIsIEhJRERFTiwgQkFTSUMpIHsKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCBwcm9jZXNzKE9wdGlvbkhlbHBlciBoZWxwZXIsIFN0cmluZyBvcHRpb24sIFN0cmluZyBhcmcpIHRocm93cyBJbnZhbGlkVmFsdWVFeGNlcHRpb24gewogICAgICAgICAgICBTdHJpbmcgcHJldiA9IGhlbHBlci5nZXQoWE1PRFVMRSk7CiAgICAgICAgICAgIGlmIChwcmV2ICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIHRocm93IGhlbHBlci5uZXdJbnZhbGlkVmFsdWVFeGNlcHRpb24oImVyci5vcHRpb24udG9vLm1hbnkiLCBYTU9EVUxFLnByaW1hcnlOYW1lKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBoZWxwZXIucHV0KFhNT0RVTEUucHJpbWFyeU5hbWUsIGFyZyk7CiAgICAgICAgfQogICAgfSwKCiAgICBNT0RVTEUoIi0tbW9kdWxlIC1tIiwgIm9wdC5hcmcubSIsICJvcHQubSIsIFNUQU5EQVJELCBCQVNJQyksCgogICAgQUREX01PRFVMRVMoIi0tYWRkLW1vZHVsZXMiLCAib3B0LmFyZy5hZGRtb2RzIiwgIm9wdC5hZGRtb2RzIiwgU1RBTkRBUkQsIEJBU0lDKSB7CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgcHJvY2VzcyhPcHRpb25IZWxwZXIgaGVscGVyLCBTdHJpbmcgb3B0aW9uLCBTdHJpbmcgYXJnKSB0aHJvd3MgSW52YWxpZFZhbHVlRXhjZXB0aW9uIHsKICAgICAgICAgICAgaWYgKGFyZy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICAgIHRocm93IGhlbHBlci5uZXdJbnZhbGlkVmFsdWVFeGNlcHRpb24oImVyci5uby52YWx1ZS5mb3Iub3B0aW9uIiwgb3B0aW9uKTsKICAgICAgICAgICAgfSBlbHNlIGlmIChnZXRQYXR0ZXJuKCkubWF0Y2hlcihhcmcpLm1hdGNoZXMoKSkgewogICAgICAgICAgICAgICAgU3RyaW5nIHByZXYgPSBoZWxwZXIuZ2V0KEFERF9NT0RVTEVTKTsKICAgICAgICAgICAgICAgIC8vIHNpbmNlIHRoZSBpbmRpdmlkdWFsIHZhbHVlcyBhcmUgc2ltcGxlIG5hbWVzLCB3ZSBjYW4gc2ltcGx5IGpvaW4gdGhlCiAgICAgICAgICAgICAgICAvLyB2YWx1ZXMgb2YgbXVsdGlwbGUgLS1hZGQtbW9kdWxlcyBvcHRpb25zIHdpdGggJywnCiAgICAgICAgICAgICAgICBoZWxwZXIucHV0KEFERF9NT0RVTEVTLnByaW1hcnlOYW1lLCAocHJldiA9PSBudWxsKSA/IGFyZyA6IHByZXYgKyAnLCcgKyBhcmcpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdGhyb3cgaGVscGVyLm5ld0ludmFsaWRWYWx1ZUV4Y2VwdGlvbigiZXJyLmJhZC52YWx1ZS5mb3Iub3B0aW9uIiwgb3B0aW9uLCBhcmcpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgUGF0dGVybiBnZXRQYXR0ZXJuKCkgewogICAgICAgICAgICByZXR1cm4gUGF0dGVybi5jb21waWxlKCIsKlteLF0uKiIpOwogICAgICAgIH0KICAgIH0sCgogICAgTElNSVRfTU9EVUxFUygiLS1saW1pdC1tb2R1bGVzIiwgIm9wdC5hcmcubGltaXRtb2RzIiwgIm9wdC5saW1pdG1vZHMiLCBTVEFOREFSRCwgQkFTSUMpIHsKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCBwcm9jZXNzKE9wdGlvbkhlbHBlciBoZWxwZXIsIFN0cmluZyBvcHRpb24sIFN0cmluZyBhcmcpIHRocm93cyBJbnZhbGlkVmFsdWVFeGNlcHRpb24gewogICAgICAgICAgICBpZiAoYXJnLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgICAgdGhyb3cgaGVscGVyLm5ld0ludmFsaWRWYWx1ZUV4Y2VwdGlvbigiZXJyLm5vLnZhbHVlLmZvci5vcHRpb24iLCBvcHRpb24pOwogICAgICAgICAgICB9IGVsc2UgaWYgKGdldFBhdHRlcm4oKS5tYXRjaGVyKGFyZykubWF0Y2hlcygpKSB7CiAgICAgICAgICAgICAgICBoZWxwZXIucHV0KExJTUlUX01PRFVMRVMucHJpbWFyeU5hbWUsIGFyZyk7IC8vIGxhc3Qgb25lIHdpbnMKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHRocm93IGhlbHBlci5uZXdJbnZhbGlkVmFsdWVFeGNlcHRpb24oImVyci5iYWQudmFsdWUuZm9yLm9wdGlvbiIsIG9wdGlvbiwgYXJnKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFBhdHRlcm4gZ2V0UGF0dGVybigpIHsKICAgICAgICAgICAgcmV0dXJuIFBhdHRlcm4uY29tcGlsZSgiLCpbXixdLioiKTsKICAgICAgICB9CiAgICB9LAoKICAgIE1PRFVMRV9WRVJTSU9OKCItLW1vZHVsZS12ZXJzaW9uIiwgIm9wdC5hcmcubW9kdWxlLnZlcnNpb24iLCAib3B0Lm1vZHVsZS52ZXJzaW9uIiwgU1RBTkRBUkQsIEJBU0lDKSB7CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgcHJvY2VzcyhPcHRpb25IZWxwZXIgaGVscGVyLCBTdHJpbmcgb3B0aW9uLCBTdHJpbmcgYXJnKSB0aHJvd3MgSW52YWxpZFZhbHVlRXhjZXB0aW9uIHsKICAgICAgICAgICAgaWYgKGFyZy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICAgIHRocm93IGhlbHBlci5uZXdJbnZhbGlkVmFsdWVFeGNlcHRpb24oImVyci5uby52YWx1ZS5mb3Iub3B0aW9uIiwgb3B0aW9uKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgQ2xhc3MuZm9yTmFtZShKREs5V3JhcHBlcnMuTW9kdWxlRGVzY3JpcHRvci5WZXJzaW9uLkNMQVNTTkFNRSk7CiAgICAgICAgICAgICAgICAgICAgLy8gdXNlIG9mZmljaWFsIHBhcnNlciBpZiBhdmFpbGFibGUKICAgICAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgICAgICBKREs5V3JhcHBlcnMuTW9kdWxlRGVzY3JpcHRvci5WZXJzaW9uLnBhcnNlKGFyZyk7CiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgaGVscGVyLm5ld0ludmFsaWRWYWx1ZUV4Y2VwdGlvbigiZXJyLmJhZC52YWx1ZS5mb3Iub3B0aW9uIiwgb3B0aW9uLCBhcmcpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gY2F0Y2ggKENsYXNzTm90Rm91bmRFeGNlcHRpb24gZXgpIHsKICAgICAgICAgICAgICAgICAgICAvLyBmYWxsLWJhY2sgdG8gc2ltcGxpc3RpYyBydWxlcyB3aGVuIHJ1bm5pbmcgb24gb2xkZXIgcGxhdGZvcm0KICAgICAgICAgICAgICAgICAgICBpZiAoIShhcmcuY2hhckF0KDApID49ICcwJyAmJiBhcmcuY2hhckF0KDApIDw9ICc5JykgfHwKICAgICAgICAgICAgICAgICAgICAgICAgYXJnLmVuZHNXaXRoKCItIikgfHwKICAgICAgICAgICAgICAgICAgICAgICAgYXJnLmVuZHNXaXRoKCIrIikpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgaGVscGVyLm5ld0ludmFsaWRWYWx1ZUV4Y2VwdGlvbigiZXJyLmJhZC52YWx1ZS5mb3Iub3B0aW9uIiwgb3B0aW9uLCBhcmcpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBzdXBlci5wcm9jZXNzKGhlbHBlciwgb3B0aW9uLCBhcmcpOwogICAgICAgIH0KICAgIH0sCgogICAgLy8gVGhpcyBvcHRpb24gZXhpc3RzIG9ubHkgZm9yIHRoZSBwdXJwb3NlIG9mIGRvY3VtZW50aW5nIGl0c2VsZi4KICAgIC8vIEl0J3MgYWN0dWFsbHkgaW1wbGVtZW50ZWQgYnkgdGhlIENvbW1hbmRMaW5lIGNsYXNzLgogICAgQVQoIkAiLCAib3B0LmFyZy5maWxlIiwgIm9wdC5BVCIsIFNUQU5EQVJELCBJTkZPLCBBcmdLaW5kLkFESkFDRU5UKSB7CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgcHJvY2VzcyhPcHRpb25IZWxwZXIgaGVscGVyLCBTdHJpbmcgb3B0aW9uKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigidGhlIEAgZmxhZyBzaG91bGQgYmUgY2F1Z2h0IGJ5IENvbW1hbmRMaW5lLiIpOwogICAgICAgIH0KICAgIH0sCgogICAgLy8gU3RhbmRhbG9uZSBwb3NpdGlvbmFsIGFyZ3VtZW50OiBzb3VyY2UgZmlsZSBvciB0eXBlIG5hbWUuCiAgICBTT1VSQ0VGSUxFKCJzb3VyY2VmaWxlIiwgbnVsbCwgSElEREVOLCBJTkZPKSB7CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gbWF0Y2hlcyhTdHJpbmcgcykgewogICAgICAgICAgICBpZiAocy5lbmRzV2l0aCgiLmphdmEiKSkgIC8vIEphdmEgc291cmNlIGZpbGUKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICBpbnQgc2VwID0gcy5pbmRleE9mKCcvJyk7CiAgICAgICAgICAgIGlmIChzZXAgIT0gLTEpIHsKICAgICAgICAgICAgICAgIHJldHVybiBTb3VyY2VWZXJzaW9uLmlzTmFtZShzLnN1YnN0cmluZygwLCBzZXApKQogICAgICAgICAgICAgICAgICAgICAgICAmJiBTb3VyY2VWZXJzaW9uLmlzTmFtZShzLnN1YnN0cmluZyhzZXAgKyAxKSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICByZXR1cm4gU291cmNlVmVyc2lvbi5pc05hbWUocyk7ICAgLy8gTGVnYWwgdHlwZSBuYW1lCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgcHJvY2VzcyhPcHRpb25IZWxwZXIgaGVscGVyLCBTdHJpbmcgb3B0aW9uKSB0aHJvd3MgSW52YWxpZFZhbHVlRXhjZXB0aW9uIHsKICAgICAgICAgICAgaWYgKG9wdGlvbi5lbmRzV2l0aCgiLmphdmEiKSApIHsKICAgICAgICAgICAgICAgIFBhdGggcCA9IFBhdGhzLmdldChvcHRpb24pOwogICAgICAgICAgICAgICAgaWYgKCFGaWxlcy5leGlzdHMocCkpIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBoZWxwZXIubmV3SW52YWxpZFZhbHVlRXhjZXB0aW9uKCJlcnIuZmlsZS5ub3QuZm91bmQiLCBwKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICghRmlsZXMuaXNSZWd1bGFyRmlsZShwKSkgewogICAgICAgICAgICAgICAgICAgIHRocm93IGhlbHBlci5uZXdJbnZhbGlkVmFsdWVFeGNlcHRpb24oImVyci5maWxlLm5vdC5maWxlIiwgcCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBoZWxwZXIuYWRkRmlsZShwKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGhlbHBlci5hZGRDbGFzc05hbWUob3B0aW9uKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0sCgogICAgTVVMVElSRUxFQVNFKCItLW11bHRpLXJlbGVhc2UiLCAib3B0LmFyZy5tdWx0aS1yZWxlYXNlIiwgIm9wdC5tdWx0aS1yZWxlYXNlIiwgSElEREVOLCBGSUxFTUFOQUdFUiksCgogICAgSU5IRVJJVF9SVU5USU1FX0VOVklST05NRU5UKCItLWluaGVyaXQtcnVudGltZS1lbnZpcm9ubWVudCIsICJvcHQuaW5oZXJpdF9ydW50aW1lX2Vudmlyb25tZW50IiwKICAgICAgICAgICAgSElEREVOLCBCQVNJQykgewogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHByb2Nlc3MoT3B0aW9uSGVscGVyIGhlbHBlciwgU3RyaW5nIG9wdGlvbikgdGhyb3dzIEludmFsaWRWYWx1ZUV4Y2VwdGlvbiB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBDbGFzcy5mb3JOYW1lKEpESzlXcmFwcGVycy5WTUhlbHBlci5DTEFTU05BTUUpOwogICAgICAgICAgICAgICAgU3RyaW5nW10gcnVudGltZUFyZ3MgPSBKREs5V3JhcHBlcnMuVk1IZWxwZXIuZ2V0UnVudGltZUFyZ3VtZW50cygpOwogICAgICAgICAgICAgICAgZm9yIChTdHJpbmcgYXJnIDogcnVudGltZUFyZ3MpIHsKICAgICAgICAgICAgICAgICAgICAvLyBIYW5kbGUgYW55IHN1cHBvcnRlZCBydW50aW1lIG9wdGlvbnM7IGlnbm9yZSBhbGwgb3RoZXJzLgogICAgICAgICAgICAgICAgICAgIC8vIFRoZSBydW50aW1lIGFyZ3VtZW50cyBhbHdheXMgdXNlIHRoZSBzaW5nbGUgdG9rZW4gZm9ybSwgZS5nLiAiLS1uYW1lPXZhbHVlIi4KICAgICAgICAgICAgICAgICAgICBmb3IgKE9wdGlvbiBvIDogZ2V0U3VwcG9ydGVkUnVudGltZU9wdGlvbnMoKSkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoby5tYXRjaGVzKGFyZykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN3aXRjaCAobykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgQUREX01PRFVMRVM6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBlcSA9IGFyZy5pbmRleE9mKCc9Jyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFzc2VydC5jaGVjayhlcSA+IDAsICgpIC0+ICgiaW52YWxpZCBydW50aW1lIG9wdGlvbjoiICsgYXJnKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIC0tYWRkLW1vZHVsZXM9QUxMLURFRkFVTFQgaXMgbm90IHN1cHBvcnRlZCBhdCBjb21waWxlLXRpbWUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc28gcmVtb3ZlIGl0IGZyb20gbGlzdCwgYW5kIG9ubHkgcHJvY2VzcyB0aGUgcmVzdAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpZiB0aGUgc2V0IGlzIG5vbi1lbXB0eS4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTm90ZSB0aGF0IC0tYWRkLW1vZHVsZXM9QUxMLURFRkFVTFQgaXMgYXV0b21hdGljYWxseSBhZGRlZAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBieSB0aGUgc3RhbmRhcmQgamF2YWMgbGF1bmNoZXIuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBtb2RzID0gQXJyYXlzLnN0cmVhbShhcmcuc3Vic3RyaW5nKGVxICsgMSkuc3BsaXQoIiwiKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZmlsdGVyKHMgLT4gIXMuaXNFbXB0eSgpICYmICFzLmVxdWFscygiQUxMLURFRkFVTFQiKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY29sbGVjdChDb2xsZWN0b3JzLmpvaW5pbmcoIiwiKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghbW9kcy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyB1cGRhdGVkQXJnID0gYXJnLnN1YnN0cmluZygwLCBlcSArIDEpICsgbW9kczsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG8uaGFuZGxlT3B0aW9uKGhlbHBlciwgdXBkYXRlZEFyZywgQ29sbGVjdGlvbnMuZW1wdHlJdGVyYXRvcigpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvLmhhbmRsZU9wdGlvbihoZWxwZXIsIGFyZywgQ29sbGVjdGlvbnMuZW1wdHlJdGVyYXRvcigpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBjYXRjaCAoQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiB8IFNlY3VyaXR5RXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgICAgIHRocm93IGhlbHBlci5uZXdJbnZhbGlkVmFsdWVFeGNlcHRpb24oImVyci5jYW5ub3QuYWNjZXNzLnJ1bnRpbWUuZW52Iik7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHByaXZhdGUgT3B0aW9uW10gZ2V0U3VwcG9ydGVkUnVudGltZU9wdGlvbnMoKSB7CiAgICAgICAgICAgIE9wdGlvbltdIHN1cHBvcnRlZFJ1bnRpbWVPcHRpb25zID0gewogICAgICAgICAgICAgICAgQUREX0VYUE9SVFMsCiAgICAgICAgICAgICAgICBBRERfTU9EVUxFUywKICAgICAgICAgICAgICAgIExJTUlUX01PRFVMRVMsCiAgICAgICAgICAgICAgICBNT0RVTEVfUEFUSCwKICAgICAgICAgICAgICAgIFVQR1JBREVfTU9EVUxFX1BBVEgsCiAgICAgICAgICAgICAgICBQQVRDSF9NT0RVTEUKICAgICAgICAgICAgfTsKICAgICAgICAgICAgcmV0dXJuIHN1cHBvcnRlZFJ1bnRpbWVPcHRpb25zOwogICAgICAgIH0KICAgIH07CgogICAgLyoqCiAgICAgKiBUaGlzIGV4Y2VwdGlvbiBpcyB0aHJvd24gd2hlbiBhbiBpbnZhbGlkIHZhbHVlIGlzIGdpdmVuIGZvciBhbiBvcHRpb24uCiAgICAgKiBUaGUgZGV0YWlsIHN0cmluZyBnaXZlcyBhIGRldGFpbGVkLCBsb2NhbGl6ZWQgbWVzc2FnZSwgc3VpdGFibGUgZm9yIHVzZQogICAgICogaW4gZXJyb3IgbWVzc2FnZXMgcmVwb3J0ZWQgdG8gdGhlIHVzZXIuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgSW52YWxpZFZhbHVlRXhjZXB0aW9uIGV4dGVuZHMgRXhjZXB0aW9uIHsKICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAtMTsKCiAgICAgICAgcHVibGljIEludmFsaWRWYWx1ZUV4Y2VwdGlvbihTdHJpbmcgbXNnKSB7CiAgICAgICAgICAgIHN1cGVyKG1zZyk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgSW52YWxpZFZhbHVlRXhjZXB0aW9uKFN0cmluZyBtc2csIFRocm93YWJsZSBjYXVzZSkgewogICAgICAgICAgICBzdXBlcihtc2csIGNhdXNlKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBUaGUga2luZCBvZiBhcmd1bWVudCwgaWYgYW55LCBhY2NlcHRlZCBieSB0aGlzIG9wdGlvbi4gVGhlIGtpbmQgaXMgYXVnbWVudGVkCiAgICAgKiBieSBjaGFyYWN0ZXJzIGluIHRoZSBuYW1lIG9mIHRoZSBvcHRpb24uCiAgICAgKi8KICAgIHB1YmxpYyBlbnVtIEFyZ0tpbmQgewogICAgICAgIC8qKiBUaGlzIG9wdGlvbiBkb2VzIG5vdCB0YWtlIGFueSBhcmd1bWVudC4gKi8KICAgICAgICBOT05FLAoKLy8gTm90IGN1cnJlbnRseSBzdXBwb3J0ZWQKLy8gICAgICAgIC8qKgovLyAgICAgICAgICogVGhpcyBvcHRpb24gdGFrZXMgYW4gb3B0aW9uYWwgYXJndW1lbnQsIHdoaWNoIG1heSBiZSBwcm92aWRlZCBkaXJlY3RseSBhZnRlciBhbiAnPScKLy8gICAgICAgICAqIHNlcGFyYXRvciwgb3IgaW4gdGhlIGZvbGxvd2luZyBhcmd1bWVudCBwb3NpdGlvbiBpZiB0aGF0IHdvcmQgZG9lcyBub3QgaXRzZWxmIGFwcGVhcgovLyAgICAgICAgICogdG8gYmUgdGhlIG5hbWUgb2YgYW4gb3B0aW9uLgovLyAgICAgICAgICovCi8vICAgICAgICBPUFRJT05BTCwKCiAgICAgICAgLyoqCiAgICAgICAgICogVGhpcyBvcHRpb24gdGFrZXMgYW4gYXJndW1lbnQuCiAgICAgICAgICogSWYgdGhlIG5hbWUgb2Ygb3B0aW9uIGVuZHMgd2l0aCAnOicgb3IgJz0nLCB0aGUgYXJndW1lbnQgbXVzdCBiZSBwcm92aWRlZCBkaXJlY3RseQogICAgICAgICAqIGFmdGVyIHRoYXQgc2VwYXJhdG9yLgogICAgICAgICAqIE90aGVyd2lzZSwgaXQgbWF5IGFwcGVhciBhZnRlciBhbiAnPScgb3IgaW4gdGhlIGZvbGxvd2luZyBhcmd1bWVudCBwb3NpdGlvbi4KICAgICAgICAgKi8KICAgICAgICBSRVFVSVJFRCwKCiAgICAgICAgLyoqCiAgICAgICAgICogVGhpcyBvcHRpb24gdGFrZXMgYW4gYXJndW1lbnQgaW1tZWRpYXRlbHkgYWZ0ZXIgdGhlIG9wdGlvbiBuYW1lLCB3aXRoIG5vIHNlcGFyYXRvcgogICAgICAgICAqIGNoYXJhY3Rlci4KICAgICAgICAgKi8KICAgICAgICBBREpBQ0VOVAogICAgfQoKICAgIC8qKgogICAgICogVGhlIGtpbmQgb2YgYW4gT3B0aW9uLiBUaGlzIGlzIHVzZWQgYnkgdGhlIC1oZWxwIGFuZCAtWCBvcHRpb25zLgogICAgICovCiAgICBwdWJsaWMgZW51bSBPcHRpb25LaW5kIHsKICAgICAgICAvKiogQSBzdGFuZGFyZCBvcHRpb24sIGRvY3VtZW50ZWQgYnkgLWhlbHAuICovCiAgICAgICAgU1RBTkRBUkQsCiAgICAgICAgLyoqIEFuIGV4dGVuZGVkIG9wdGlvbiwgZG9jdW1lbnRlZCBieSAtWC4gKi8KICAgICAgICBFWFRFTkRFRCwKICAgICAgICAvKiogQSBoaWRkZW4gb3B0aW9uLCBub3QgZG9jdW1lbnRlZC4gKi8KICAgICAgICBISURERU4sCiAgICB9CgogICAgLyoqCiAgICAgKiBUaGUgZ3JvdXAgZm9yIGFuIE9wdGlvbi4gVGhpcyBkZXRlcm1pbmVzIHRoZSBzaXR1YXRpb25zIGluIHdoaWNoIHRoZQogICAgICogb3B0aW9uIGlzIGFwcGxpY2FibGUuCiAgICAgKi8KICAgIGVudW0gT3B0aW9uR3JvdXAgewogICAgICAgIC8qKiBBIGJhc2ljIG9wdGlvbiwgYXZhaWxhYmxlIGZvciB1c2Ugb24gdGhlIGNvbW1hbmQgbGluZSBvciB2aWEgdGhlCiAgICAgICAgICogIENvbXBpbGVyIEFQSS4gKi8KICAgICAgICBCQVNJQywKICAgICAgICAvKiogQW4gb3B0aW9uIGZvciBqYXZhYydzIHN0YW5kYXJkIEphdmFGaWxlTWFuYWdlci4gT3RoZXIgZmlsZSBtYW5hZ2VycwogICAgICAgICAqICBtYXkgb3IgbWF5IG5vdCBzdXBwb3J0IHRoZXNlIG9wdGlvbnMuICovCiAgICAgICAgRklMRU1BTkFHRVIsCiAgICAgICAgLyoqIEEgY29tbWFuZC1saW5lIG9wdGlvbiB0aGF0IHJlcXVlc3RzIGluZm9ybWF0aW9uLCBzdWNoIGFzIC1oZWxwLiAqLwogICAgICAgIElORk8sCiAgICAgICAgLyoqIEEgY29tbWFuZC1saW5lICJvcHRpb24iIHJlcHJlc2VudGluZyBhIGZpbGUgb3IgY2xhc3MgbmFtZS4gKi8KICAgICAgICBPUEVSQU5ECiAgICB9CgogICAgLyoqCiAgICAgKiBUaGUga2luZCBvZiBjaG9pY2UgZm9yICJjaG9pY2UiIG9wdGlvbnMuCiAgICAgKi8KICAgIGVudW0gQ2hvaWNlS2luZCB7CiAgICAgICAgLyoqIFRoZSBleHBlY3RlZCB2YWx1ZSBpcyBleGFjdGx5IG9uZSBvZiB0aGUgc2V0IG9mIGNob2ljZXMuICovCiAgICAgICAgT05FT0YsCiAgICAgICAgLyoqIFRoZSBleHBlY3RlZCB2YWx1ZSBpcyBvbmUgb2YgbW9yZSBvZiB0aGUgc2V0IG9mIGNob2ljZXMuICovCiAgICAgICAgQU5ZT0YKICAgIH0KCiAgICBlbnVtIEhpZGRlbkdyb3VwIHsKICAgICAgICBESUFHUygiZGlhZ3MiKSwKICAgICAgICBERUJVRygiZGVidWciKSwKICAgICAgICBTSE9VTERTVE9QKCJzaG91bGQtc3RvcCIpOwoKICAgICAgICBzdGF0aWMgZmluYWwgU2V0PFN0cmluZz4gc2tpcFNldCA9IG5ldyBqYXZhLnV0aWwuSGFzaFNldDw+KAogICAgICAgICAgICAgICAgQXJyYXlzLmFzTGlzdCgiLS1kaWFnczoiLCAiLS1kZWJ1ZzoiLCAiLS1zaG91bGQtc3RvcDoiKSk7CgogICAgICAgIGZpbmFsIFN0cmluZyB0ZXh0OwoKICAgICAgICBIaWRkZW5Hcm91cChTdHJpbmcgdGV4dCkgewogICAgICAgICAgICB0aGlzLnRleHQgPSB0ZXh0OwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHZvaWQgcHJvY2VzcyhPcHRpb25IZWxwZXIgaGVscGVyLCBTdHJpbmcgb3B0aW9uKSB0aHJvd3MgSW52YWxpZFZhbHVlRXhjZXB0aW9uIHsKICAgICAgICAgICAgU3RyaW5nIHAgPSBvcHRpb24uc3Vic3RyaW5nKG9wdGlvbi5pbmRleE9mKCc6JykgKyAxKS50cmltKCk7CiAgICAgICAgICAgIFN0cmluZ1tdIHN1Yk9wdGlvbnMgPSBwLnNwbGl0KCI7Iik7CiAgICAgICAgICAgIGZvciAoU3RyaW5nIHN1Yk9wdGlvbiA6IHN1Yk9wdGlvbnMpIHsKICAgICAgICAgICAgICAgIHN1Yk9wdGlvbiA9IHRleHQgKyAiLiIgKyBzdWJPcHRpb24udHJpbSgpOwogICAgICAgICAgICAgICAgWEQucHJvY2VzcyhoZWxwZXIsIHN1Yk9wdGlvbiwgc3ViT3B0aW9uKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgc3RhdGljIGJvb2xlYW4gc2tpcChTdHJpbmcgbmFtZSkgewogICAgICAgICAgICByZXR1cm4gc2tpcFNldC5jb250YWlucyhuYW1lKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBUaGUgInByaW1hcnkgbmFtZSIgZm9yIHRoaXMgb3B0aW9uLgogICAgICogVGhpcyBpcyB0aGUgbmFtZSB0aGF0IGlzIHVzZWQgdG8gcHV0IHZhbHVlcyBpbiB0aGUge0BsaW5rIE9wdGlvbnN9IHRhYmxlLgogICAgICovCiAgICBwdWJsaWMgZmluYWwgU3RyaW5nIHByaW1hcnlOYW1lOwoKICAgIC8qKgogICAgICogVGhlIHNldCBvZiBuYW1lcyAocHJpbWFyeSBuYW1lIGFuZCBhbGlhc2VzKSBmb3IgdGhpcyBvcHRpb24uCiAgICAgKiBOb3RlIHRoYXQgc29tZSBuYW1lcyBtYXkgZW5kIGluIGEgc2VwYXJhdG9yLCB0byBpbmRpY2F0ZSB0aGF0IGFuIGFyZ3VtZW50IG11c3QgaW1tZWRpYXRlbHkKICAgICAqIGZvbGxvdyB0aGUgc2VwYXJhdG9yIChhbmQgY2Fubm90IGFwcGVhciBpbiB0aGUgZm9sbG93aW5nIGFyZ3VtZW50IHBvc2l0aW9uLgogICAgICovCiAgICBwdWJsaWMgZmluYWwgU3RyaW5nW10gbmFtZXM7CgogICAgLyoqIERvY3VtZW50YXRpb24ga2V5IGZvciBhcmd1bWVudHMuICovCiAgICBwcm90ZWN0ZWQgZmluYWwgU3RyaW5nIGFyZ3NOYW1lS2V5OwoKICAgIC8qKiBEb2N1bWVudGF0aW9uIGtleSBmb3IgZGVzY3JpcHRpb24uCiAgICAgKi8KICAgIHByb3RlY3RlZCBmaW5hbCBTdHJpbmcgZGVzY3JLZXk7CgogICAgLyoqIFRoZSBraW5kIG9mIHRoaXMgb3B0aW9uLiAqLwogICAgcHJpdmF0ZSBmaW5hbCBPcHRpb25LaW5kIGtpbmQ7CgogICAgLyoqIFRoZSBncm91cCBmb3IgdGhpcyBvcHRpb24uICovCiAgICBwcml2YXRlIGZpbmFsIE9wdGlvbkdyb3VwIGdyb3VwOwoKICAgIC8qKiBUaGUga2luZCBvZiBhcmd1bWVudCBmb3IgdGhpcyBvcHRpb24uICovCiAgICBwcml2YXRlIGZpbmFsIEFyZ0tpbmQgYXJnS2luZDsKCiAgICAvKiogVGhlIGtpbmQgb2YgY2hvaWNlcyBmb3IgdGhpcyBvcHRpb24sIGlmIGFueS4gKi8KICAgIHByaXZhdGUgZmluYWwgQ2hvaWNlS2luZCBjaG9pY2VLaW5kOwoKICAgIC8qKiBUaGUgY2hvaWNlcyBmb3IgdGhpcyBvcHRpb24sIGlmIGFueS4gKi8KICAgIHByaXZhdGUgZmluYWwgU2V0PFN0cmluZz4gY2hvaWNlczsKCiAgICAvKioKICAgICAqIExvb2tzIHVwIHRoZSBmaXJzdCBvcHRpb24gbWF0Y2hpbmcgdGhlIGdpdmVuIGFyZ3VtZW50IGluIHRoZSBmdWxsIHNldCBvZiBvcHRpb25zLgogICAgICogQHBhcmFtIGFyZyB0aGUgYXJndW1lbnQgdG8gYmUgbWF0Y2hlcwogICAgICogQHJldHVybiB0aGUgZmlyc3Qgb3B0aW9uIHRoYXQgbWF0Y2hlcywgb3IgbnVsbCBpZiBub25lLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIE9wdGlvbiBsb29rdXAoU3RyaW5nIGFyZykgewogICAgICAgIHJldHVybiBsb29rdXAoYXJnLCBFbnVtU2V0LmFsbE9mKE9wdGlvbi5jbGFzcykpOwogICAgfQoKICAgIC8qKgogICAgICogTG9va3MgdXAgdGhlIGZpcnN0IG9wdGlvbiBtYXRjaGluZyB0aGUgZ2l2ZW4gYXJndW1lbnQgd2l0aGluIGEgc2V0IG9mIG9wdGlvbnMuCiAgICAgKiBAcGFyYW0gYXJnIHRoZSBhcmd1bWVudCB0byBiZSBtYXRjaGVkCiAgICAgKiBAcGFyYW0gb3B0aW9ucyB0aGUgc2V0IG9mIHBvc3NpYmxlIG9wdGlvbnMKICAgICAqIEByZXR1cm4gdGhlIGZpcnN0IG9wdGlvbiB0aGF0IG1hdGNoZXMsIG9yIG51bGwgaWYgbm9uZS4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBPcHRpb24gbG9va3VwKFN0cmluZyBhcmcsIFNldDxPcHRpb24+IG9wdGlvbnMpIHsKICAgICAgICBmb3IgKE9wdGlvbiBvcHRpb246IG9wdGlvbnMpIHsKICAgICAgICAgICAgaWYgKG9wdGlvbi5tYXRjaGVzKGFyZykpCiAgICAgICAgICAgICAgICByZXR1cm4gb3B0aW9uOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICAvKioKICAgICAqIFdyaXRlcyB0aGUgImNvbW1hbmQgbGluZSBoZWxwIiBmb3IgZ2l2ZW4ga2luZCBvZiBvcHRpb24gdG8gdGhlIGxvZy4KICAgICAqIEBwYXJhbSBsb2cgdGhlIGxvZwogICAgICogQHBhcmFtIGtpbmQgIHRoZSBraW5kIG9mIG9wdGlvbnMgdG8gc2VsZWN0CiAgICAgKi8KICAgIHByaXZhdGUgc3RhdGljIHZvaWQgc2hvd0hlbHAoTG9nIGxvZywgT3B0aW9uS2luZCBraW5kKSB7CiAgICAgICAgQ29tcGFyYXRvcjxPcHRpb24+IGNvbXAgPSBuZXcgQ29tcGFyYXRvcjxPcHRpb24+KCkgewogICAgICAgICAgICBmaW5hbCBDb2xsYXRvciBjb2xsYXRvciA9IENvbGxhdG9yLmdldEluc3RhbmNlKExvY2FsZS5VUyk7CiAgICAgICAgICAgIHsgY29sbGF0b3Iuc2V0U3RyZW5ndGgoQ29sbGF0b3IuUFJJTUFSWSk7IH0KCiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgaW50IGNvbXBhcmUoT3B0aW9uIG8xLCBPcHRpb24gbzIpIHsKICAgICAgICAgICAgICAgIHJldHVybiBjb2xsYXRvci5jb21wYXJlKG8xLnByaW1hcnlOYW1lLCBvMi5wcmltYXJ5TmFtZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9OwoKICAgICAgICBnZXRKYXZhQ29tcGlsZXJPcHRpb25zKCkKICAgICAgICAgICAgICAgIC5zdHJlYW0oKQogICAgICAgICAgICAgICAgLmZpbHRlcihvIC0+IG8ua2luZCA9PSBraW5kKQogICAgICAgICAgICAgICAgLnNvcnRlZChjb21wKQogICAgICAgICAgICAgICAgLmZvckVhY2gobyAtPiB7CiAgICAgICAgICAgICAgICAgICAgby5oZWxwKGxvZyk7CiAgICAgICAgICAgICAgICB9KTsKICAgIH0KCiAgICBPcHRpb24oU3RyaW5nIHRleHQsIFN0cmluZyBkZXNjcktleSwKICAgICAgICAgICAgT3B0aW9uS2luZCBraW5kLCBPcHRpb25Hcm91cCBncm91cCkgewogICAgICAgIHRoaXModGV4dCwgbnVsbCwgZGVzY3JLZXksIGtpbmQsIGdyb3VwLCBudWxsLCBudWxsLCBBcmdLaW5kLk5PTkUpOwogICAgfQoKICAgIE9wdGlvbihTdHJpbmcgdGV4dCwgU3RyaW5nIGFyZ3NOYW1lS2V5LCBTdHJpbmcgZGVzY3JLZXksCiAgICAgICAgICAgIE9wdGlvbktpbmQga2luZCwgT3B0aW9uR3JvdXAgZ3JvdXApIHsKICAgICAgICB0aGlzKHRleHQsIGFyZ3NOYW1lS2V5LCBkZXNjcktleSwga2luZCwgZ3JvdXAsIG51bGwsIG51bGwsIEFyZ0tpbmQuUkVRVUlSRUQpOwogICAgfQoKICAgIE9wdGlvbihTdHJpbmcgdGV4dCwgU3RyaW5nIGFyZ3NOYW1lS2V5LCBTdHJpbmcgZGVzY3JLZXksCiAgICAgICAgICAgIE9wdGlvbktpbmQga2luZCwgT3B0aW9uR3JvdXAgZ3JvdXAsIEFyZ0tpbmQgYWspIHsKICAgICAgICB0aGlzKHRleHQsIGFyZ3NOYW1lS2V5LCBkZXNjcktleSwga2luZCwgZ3JvdXAsIG51bGwsIG51bGwsIGFrKTsKICAgIH0KCiAgICBPcHRpb24oU3RyaW5nIHRleHQsIFN0cmluZyBhcmdzTmFtZUtleSwgU3RyaW5nIGRlc2NyS2V5LCBPcHRpb25LaW5kIGtpbmQsIE9wdGlvbkdyb3VwIGdyb3VwLAogICAgICAgICAgICBDaG9pY2VLaW5kIGNob2ljZUtpbmQsIFNldDxTdHJpbmc+IGNob2ljZXMpIHsKICAgICAgICB0aGlzKHRleHQsIGFyZ3NOYW1lS2V5LCBkZXNjcktleSwga2luZCwgZ3JvdXAsIGNob2ljZUtpbmQsIGNob2ljZXMsIEFyZ0tpbmQuUkVRVUlSRUQpOwogICAgfQoKICAgIE9wdGlvbihTdHJpbmcgdGV4dCwgU3RyaW5nIGRlc2NyS2V5LAogICAgICAgICAgICBPcHRpb25LaW5kIGtpbmQsIE9wdGlvbkdyb3VwIGdyb3VwLAogICAgICAgICAgICBDaG9pY2VLaW5kIGNob2ljZUtpbmQsIFN0cmluZy4uLiBjaG9pY2VzKSB7CiAgICAgICAgdGhpcyh0ZXh0LCBudWxsLCBkZXNjcktleSwga2luZCwgZ3JvdXAsIGNob2ljZUtpbmQsCiAgICAgICAgICAgICAgICBuZXcgTGlua2VkSGFzaFNldDw+KEFycmF5cy5hc0xpc3QoY2hvaWNlcykpLCBBcmdLaW5kLlJFUVVJUkVEKTsKICAgIH0KCiAgICBwcml2YXRlIE9wdGlvbihTdHJpbmcgdGV4dCwgU3RyaW5nIGFyZ3NOYW1lS2V5LCBTdHJpbmcgZGVzY3JLZXksCiAgICAgICAgICAgIE9wdGlvbktpbmQga2luZCwgT3B0aW9uR3JvdXAgZ3JvdXAsCiAgICAgICAgICAgIENob2ljZUtpbmQgY2hvaWNlS2luZCwgU2V0PFN0cmluZz4gY2hvaWNlcywKICAgICAgICAgICAgQXJnS2luZCBhcmdLaW5kKSB7CiAgICAgICAgdGhpcy5uYW1lcyA9IHRleHQudHJpbSgpLnNwbGl0KCJcXHMrIik7CiAgICAgICAgQXNzZXJ0LmNoZWNrKG5hbWVzLmxlbmd0aCA+PSAxKTsKICAgICAgICB0aGlzLnByaW1hcnlOYW1lID0gbmFtZXNbMF07CiAgICAgICAgdGhpcy5hcmdzTmFtZUtleSA9IGFyZ3NOYW1lS2V5OwogICAgICAgIHRoaXMuZGVzY3JLZXkgPSBkZXNjcktleTsKICAgICAgICB0aGlzLmtpbmQgPSBraW5kOwogICAgICAgIHRoaXMuZ3JvdXAgPSBncm91cDsKICAgICAgICB0aGlzLmNob2ljZUtpbmQgPSBjaG9pY2VLaW5kOwogICAgICAgIHRoaXMuY2hvaWNlcyA9IGNob2ljZXM7CiAgICAgICAgdGhpcy5hcmdLaW5kID0gYXJnS2luZDsKICAgIH0KCiAgICBwdWJsaWMgU3RyaW5nIGdldFByaW1hcnlOYW1lKCkgewogICAgICAgIHJldHVybiBwcmltYXJ5TmFtZTsKICAgIH0KCiAgICBwdWJsaWMgT3B0aW9uS2luZCBnZXRLaW5kKCkgewogICAgICAgIHJldHVybiBraW5kOwogICAgfQoKICAgIHB1YmxpYyBBcmdLaW5kIGdldEFyZ0tpbmQoKSB7CiAgICAgICAgcmV0dXJuIGFyZ0tpbmQ7CiAgICB9CgogICAgcHVibGljIGJvb2xlYW4gaGFzQXJnKCkgewogICAgICAgIHJldHVybiAoYXJnS2luZCAhPSBBcmdLaW5kLk5PTkUpOwogICAgfQoKICAgIHB1YmxpYyBib29sZWFuIG1hdGNoZXMoU3RyaW5nIG9wdGlvbikgewogICAgICAgIGZvciAoU3RyaW5nIG5hbWU6IG5hbWVzKSB7CiAgICAgICAgICAgIGlmIChtYXRjaGVzKG9wdGlvbiwgbmFtZSkpCiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIHByaXZhdGUgYm9vbGVhbiBtYXRjaGVzKFN0cmluZyBvcHRpb24sIFN0cmluZyBuYW1lKSB7CiAgICAgICAgaWYgKG5hbWUuc3RhcnRzV2l0aCgiLS0iKSAmJiAhSGlkZGVuR3JvdXAuc2tpcChuYW1lKSkgewogICAgICAgICAgICByZXR1cm4gb3B0aW9uLmVxdWFscyhuYW1lKQogICAgICAgICAgICAgICAgICAgIHx8IGhhc0FyZygpICYmIG9wdGlvbi5zdGFydHNXaXRoKG5hbWUgKyAiPSIpOwogICAgICAgIH0KCiAgICAgICAgYm9vbGVhbiBoYXNTdWZmaXggPSAoYXJnS2luZCA9PSBBcmdLaW5kLkFESkFDRU5UKQogICAgICAgICAgICAgICAgfHwgbmFtZS5lbmRzV2l0aCgiOiIpIHx8IG5hbWUuZW5kc1dpdGgoIj0iKTsKCiAgICAgICAgaWYgKCFoYXNTdWZmaXgpCiAgICAgICAgICAgIHJldHVybiBvcHRpb24uZXF1YWxzKG5hbWUpOwoKICAgICAgICBpZiAoIW9wdGlvbi5zdGFydHNXaXRoKG5hbWUpKQogICAgICAgICAgICByZXR1cm4gZmFsc2U7CgogICAgICAgIGlmIChjaG9pY2VzICE9IG51bGwpIHsKICAgICAgICAgICAgU3RyaW5nIGFyZyA9IG9wdGlvbi5zdWJzdHJpbmcobmFtZS5sZW5ndGgoKSk7CiAgICAgICAgICAgIGlmIChjaG9pY2VLaW5kID09IENob2ljZUtpbmQuT05FT0YpCiAgICAgICAgICAgICAgICByZXR1cm4gY2hvaWNlcy5jb250YWlucyhhcmcpOwogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIGZvciAoU3RyaW5nIGE6IGFyZy5zcGxpdCgiLCsiKSkgewogICAgICAgICAgICAgICAgICAgIGlmICghY2hvaWNlcy5jb250YWlucyhhKSkKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICAvKioKICAgICAqIEhhbmRsZXMgYW4gb3B0aW9uLgogICAgICogSWYgYW4gYXJndW1lbnQgZm9yIHRoZSBvcHRpb24gaXMgcmVxdWlyZWQsIGRlcGVuZGluZyBvbiBzcGVjIG9mIHRoZSBvcHRpb24sIGl0IHdpbGwgYmUgZm91bmQKICAgICAqIGFzIHBhcnQgb2YgdGhlIGN1cnJlbnQgYXJnIChmb2xsb3dpbmcgJzonIG9yICc9Jykgb3IgaW4gdGhlIGZvbGxvd2luZyBhcmd1bWVudC4KICAgICAqIFRoaXMgaXMgdGhlIHJlY29tbWVuZGVkIHdheSB0byBoYW5kbGUgYW4gb3B0aW9uIGRpcmVjdGx5LCBpbnN0ZWFkIG9mIGNhbGxpbmcgdGhlIHVuZGVybHlpbmcKICAgICAqIHtAbGluayAjcHJvY2VzcyBwcm9jZXNzfSBtZXRob2RzLgogICAgICogQHBhcmFtIGhlbHBlciBhIGhlbHBlciB0byBwcm92aWRlIGFjY2VzcyB0byB0aGUgZW52aXJvbm1lbnQKICAgICAqIEBwYXJhbSBhcmcgdGhlIGFyZyBzdHJpbmcgdGhhdCBpZGVudGlmaWVkIHRoaXMgb3B0aW9uCiAgICAgKiBAcGFyYW0gcmVzdCB0aGUgcmVtYWluaW5nIHN0cmluZ3MgdG8gYmUgYW5hbHlzZWQKICAgICAqIEB0aHJvd3MgSW52YWxpZFZhbHVlRXhjZXB0aW9uIGlmIHRoZSB2YWx1ZSBvZiB0aGUgb3B0aW9uIHdhcyBpbnZhbGlkCiAgICAgKiBAaW1wbE5vdGUgVGhlIHJldHVybiB2YWx1ZSBpcyB0aGUgb3Bwb3NpdGUgb2YgdGhhdCB1c2VkIGJ5IHtAbGluayAjcHJvY2Vzc30uCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIGhhbmRsZU9wdGlvbihPcHRpb25IZWxwZXIgaGVscGVyLCBTdHJpbmcgYXJnLCBJdGVyYXRvcjxTdHJpbmc+IHJlc3QpIHRocm93cyBJbnZhbGlkVmFsdWVFeGNlcHRpb24gewogICAgICAgIGlmIChoYXNBcmcoKSkgewogICAgICAgICAgICBTdHJpbmcgb3B0aW9uOwogICAgICAgICAgICBTdHJpbmcgb3BlcmFuZDsKICAgICAgICAgICAgaW50IHNlcCA9IGZpbmRTZXBhcmF0b3IoYXJnKTsKICAgICAgICAgICAgaWYgKGdldEFyZ0tpbmQoKSA9PSBPcHRpb24uQXJnS2luZC5BREpBQ0VOVCkgewogICAgICAgICAgICAgICAgb3B0aW9uID0gcHJpbWFyeU5hbWU7IC8vIGFsaWFzZXMgbm90IHN1cHBvcnRlZAogICAgICAgICAgICAgICAgb3BlcmFuZCA9IGFyZy5zdWJzdHJpbmcocHJpbWFyeU5hbWUubGVuZ3RoKCkpOwogICAgICAgICAgICB9IGVsc2UgaWYgKHNlcCA+IDApIHsKICAgICAgICAgICAgICAgIG9wdGlvbiA9IGFyZy5zdWJzdHJpbmcoMCwgc2VwKTsKICAgICAgICAgICAgICAgIG9wZXJhbmQgPSBhcmcuc3Vic3RyaW5nKHNlcCArIDEpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgaWYgKCFyZXN0Lmhhc05leHQoKSkgewogICAgICAgICAgICAgICAgICAgIHRocm93IGhlbHBlci5uZXdJbnZhbGlkVmFsdWVFeGNlcHRpb24oImVyci5yZXEuYXJnIiwgYXJnKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIG9wdGlvbiA9IGFyZzsKICAgICAgICAgICAgICAgIG9wZXJhbmQgPSByZXN0Lm5leHQoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBwcm9jZXNzKGhlbHBlciwgb3B0aW9uLCBvcGVyYW5kKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBwcm9jZXNzKGhlbHBlciwgYXJnKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBQcm9jZXNzZXMgYW4gb3B0aW9uIHRoYXQgZWl0aGVyIGRvZXMgbm90IG5lZWQgYW4gYXJndW1lbnQsCiAgICAgKiBvciB3aGljaCBjb250YWlucyBhbiBhcmd1bWVudCB3aXRoaW4gaXQsIGZvbGxvd2luZyBhIHNlcGFyYXRvci4KICAgICAqIEBwYXJhbSBoZWxwZXIgYSBoZWxwZXIgdG8gcHJvdmlkZSBhY2Nlc3MgdG8gdGhlIGVudmlyb25tZW50CiAgICAgKiBAcGFyYW0gb3B0aW9uIHRoZSBvcHRpb24gdG8gYmUgcHJvY2Vzc2VkCiAgICAgKiBAdGhyb3dzIEludmFsaWRWYWx1ZUV4Y2VwdGlvbiBpZiBhbiBlcnJvciBvY2N1cnJlZAogICAgICovCiAgICBwdWJsaWMgdm9pZCBwcm9jZXNzKE9wdGlvbkhlbHBlciBoZWxwZXIsIFN0cmluZyBvcHRpb24pIHRocm93cyBJbnZhbGlkVmFsdWVFeGNlcHRpb24gewogICAgICAgIGlmIChhcmdLaW5kID09IEFyZ0tpbmQuTk9ORSkgewogICAgICAgICAgICBwcm9jZXNzKGhlbHBlciwgcHJpbWFyeU5hbWUsIG9wdGlvbik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgaW50IHNlcCA9IGZpbmRTZXBhcmF0b3Iob3B0aW9uKTsKICAgICAgICAgICAgcHJvY2VzcyhoZWxwZXIsIHByaW1hcnlOYW1lLCBvcHRpb24uc3Vic3RyaW5nKHNlcCArIDEpKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBQcm9jZXNzZXMgYW4gb3B0aW9uIGJ5IHVwZGF0aW5nIHRoZSBlbnZpcm9ubWVudCB2aWEgYSBoZWxwZXIgb2JqZWN0LgogICAgICogQHBhcmFtIGhlbHBlciBhIGhlbHBlciB0byBwcm92aWRlIGFjY2VzcyB0byB0aGUgZW52aXJvbm1lbnQKICAgICAqIEBwYXJhbSBvcHRpb24gdGhlIG9wdGlvbiB0byBiZSBwcm9jZXNzZWQKICAgICAqIEBwYXJhbSBhcmcgdGhlIHZhbHVlIHRvIGFzc29jaWF0ZSB3aXRoIHRoZSBvcHRpb24sIG9yIGEgZGVmYXVsdCB2YWx1ZQogICAgICogIHRvIGJlIHVzZWQgaWYgdGhlIG9wdGlvbiBkb2VzIG5vdCBvdGhlcndpc2UgdGFrZSBhbiBhcmd1bWVudC4KICAgICAqIEB0aHJvd3MgSW52YWxpZFZhbHVlRXhjZXB0aW9uIGlmIGFuIGVycm9yIG9jY3VycmVkCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHByb2Nlc3MoT3B0aW9uSGVscGVyIGhlbHBlciwgU3RyaW5nIG9wdGlvbiwgU3RyaW5nIGFyZykgdGhyb3dzIEludmFsaWRWYWx1ZUV4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGNob2ljZXMgIT0gbnVsbCkgewogICAgICAgICAgICBpZiAoY2hvaWNlS2luZCA9PSBDaG9pY2VLaW5kLk9ORU9GKSB7CiAgICAgICAgICAgICAgICAvLyBzb21lIGNsaWVudHMgbGlrZSB0byBzZWUganVzdCBvbmUgb2Ygb3B0aW9uK2Nob2ljZSBzZXQKICAgICAgICAgICAgICAgIGZvciAoU3RyaW5nIHMgOiBjaG9pY2VzKQogICAgICAgICAgICAgICAgICAgIGhlbHBlci5yZW1vdmUocHJpbWFyeU5hbWUgKyBzKTsKICAgICAgICAgICAgICAgIFN0cmluZyBvcHQgPSBwcmltYXJ5TmFtZSArIGFyZzsKICAgICAgICAgICAgICAgIGhlbHBlci5wdXQob3B0LCBvcHQpOwogICAgICAgICAgICAgICAgLy8gc29tZSBjbGllbnRzIGxpa2UgdG8gc2VlIG9wdGlvbiAod2l0aG91dCB0cmFpbGluZyAiOiIpCiAgICAgICAgICAgICAgICAvLyBzZXQgdG8gYXJnCiAgICAgICAgICAgICAgICBTdHJpbmcgbm0gPSBwcmltYXJ5TmFtZS5zdWJzdHJpbmcoMCwgcHJpbWFyeU5hbWUubGVuZ3RoKCkgLSAxKTsKICAgICAgICAgICAgICAgIGhlbHBlci5wdXQobm0sIGFyZyk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvLyBzZXQgb3B0aW9uK3dvcmQgZm9yIGVhY2ggd29yZCBpbiBhcmcKICAgICAgICAgICAgICAgIGZvciAoU3RyaW5nIGE6IGFyZy5zcGxpdCgiLCsiKSkgewogICAgICAgICAgICAgICAgICAgIFN0cmluZyBvcHQgPSBwcmltYXJ5TmFtZSArIGE7CiAgICAgICAgICAgICAgICAgICAgaGVscGVyLnB1dChvcHQsIG9wdCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaGVscGVyLnB1dChwcmltYXJ5TmFtZSwgYXJnKTsKICAgICAgICBpZiAoZ3JvdXAgPT0gT3B0aW9uR3JvdXAuRklMRU1BTkFHRVIpCiAgICAgICAgICAgIGhlbHBlci5oYW5kbGVGaWxlTWFuYWdlck9wdGlvbih0aGlzLCBhcmcpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyBhIHBhdHRlcm4gdG8gYW5hbHl6ZSB0aGUgdmFsdWUgZm9yIGFuIG9wdGlvbi4KICAgICAqIEByZXR1cm4gdGhlIHBhdHRlcm4KICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gaWYgYW4gb3B0aW9uIGRvZXMgbm90IHByb3ZpZGUgYSBwYXR0ZXJuLgogICAgICovCiAgICBwdWJsaWMgUGF0dGVybiBnZXRQYXR0ZXJuKCkgewogICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOwogICAgfQoKICAgIC8qKgogICAgICogU2NhbnMgYSB3b3JkIHRvIGZpbmQgdGhlIGZpcnN0IHNlcGFyYXRvciBjaGFyYWN0ZXIsIGVpdGhlciBjb2xvbiBvciBlcXVhbHMuCiAgICAgKiBAcGFyYW0gd29yZCB0aGUgd29yZCB0byBiZSBzY2FubmVkCiAgICAgKiBAcmV0dXJuIHRoZSBwb3NpdGlvbiBvZiB0aGUgZmlyc3QnOicgb3IgJz0nIGNoYXJhY3RlciBpbiB0aGUgd29yZCwKICAgICAqICBvciAtMSBpZiBub25lIGZvdW5kCiAgICAgKi8KICAgIHByaXZhdGUgc3RhdGljIGludCBmaW5kU2VwYXJhdG9yKFN0cmluZyB3b3JkKSB7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB3b3JkLmxlbmd0aCgpOyBpKyspIHsKICAgICAgICAgICAgc3dpdGNoICh3b3JkLmNoYXJBdChpKSkgewogICAgICAgICAgICAgICAgY2FzZSAnOic6IGNhc2UgJz0nOgogICAgICAgICAgICAgICAgICAgIHJldHVybiBpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiAtMTsKICAgIH0KCiAgICAvKiogVGhlIGluZGVudCBmb3IgdGhlIG9wdGlvbiBzeW5vcHNpcy4gKi8KICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBTTUFMTF9JTkRFTlQgPSAiICAiOwogICAgLyoqIFRoZSBhdXRvbWF0aWMgaW5kZW50IGZvciB0aGUgZGVzY3JpcHRpb24uICovCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgTEFSR0VfSU5ERU5UID0gIiAgICAgICAgIjsKICAgIC8qKiBUaGUgc3BhY2UgYWxsb3dlZCBmb3IgdGhlIHN5bm9wc2lzLCBpZiB0aGUgZGVzY3JpcHRpb24gaXMgdG8gYmUgc2hvd24gb24gdGhlIHNhbWUgbGluZS4gKi8KICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBERUZBVUxUX1NZTk9QU0lTX1dJRFRIID0gMjg7CiAgICAvKiogVGhlIG5vbWluYWwgbWF4aW11bSBsaW5lIGxlbmd0aCwgd2hlbiBzZWVpbmcgaWYgdGV4dCB3aWxsIGZpdCBvbiBhIGxpbmUuICovCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgREVGQVVMVF9NQVhfTElORV9MRU5HVEggPSA4MDsKICAgIC8qKiBUaGUgZm9ybWF0IGZvciBhIHNpbmdsZS1saW5lIGhlbHAgZW50cnkuICovCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ09NUEFDVF9GT1JNQVQgPSBTTUFMTF9JTkRFTlQgKyAiJS0iICsgREVGQVVMVF9TWU5PUFNJU19XSURUSCArICJzICVzIjsKCiAgICAvKioKICAgICAqIFdyaXRlcyBoZWxwIHRleHQgZm9yIHRoaXMgb3B0aW9uIHRvIHRoZSBsb2cuCiAgICAgKiBAcGFyYW0gbG9nIHRoZSBsb2cKICAgICAqLwogICAgcHJvdGVjdGVkIHZvaWQgaGVscChMb2cgbG9nKSB7CiAgICAgICAgaGVscChsb2csIGxvZy5sb2NhbGl6ZShQcmVmaXhLaW5kLkpBVkFDLCBkZXNjcktleSkpOwogICAgfQoKICAgIHByb3RlY3RlZCB2b2lkIGhlbHAoTG9nIGxvZywgU3RyaW5nIGRlc2NyKSB7CiAgICAgICAgU3RyaW5nIHN5bm9wc2VzID0gQXJyYXlzLnN0cmVhbShuYW1lcykKICAgICAgICAgICAgICAgIC5tYXAocyAtPiBoZWxwU3lub3BzaXMocywgbG9nKSkKICAgICAgICAgICAgICAgIC5jb2xsZWN0KENvbGxlY3RvcnMuam9pbmluZygiLCAiKSk7CgogICAgICAgIC8vIElmIG9wdGlvbiBzeW5vcHNlcyBhbmQgZGVzY3JpcHRpb24gZml0IG9uIGEgc2luZ2xlIGxpbmUgb2YgcmVhc29uYWJsZSBsZW5ndGgsCiAgICAgICAgLy8gZGlzcGxheSB1c2luZyBDT01QQUNUX0ZPUk1BVAogICAgICAgIGlmIChzeW5vcHNlcy5sZW5ndGgoKSA8IERFRkFVTFRfU1lOT1BTSVNfV0lEVEgKICAgICAgICAgICAgICAgICYmICFkZXNjci5jb250YWlucygiXG4iKQogICAgICAgICAgICAgICAgJiYgKFNNQUxMX0lOREVOVC5sZW5ndGgoKSArIERFRkFVTFRfU1lOT1BTSVNfV0lEVEggKyAxICsgZGVzY3IubGVuZ3RoKCkgPD0gREVGQVVMVF9NQVhfTElORV9MRU5HVEgpKSB7CiAgICAgICAgICAgIGxvZy5wcmludFJhd0xpbmVzKFdyaXRlcktpbmQuU1RET1VULCBTdHJpbmcuZm9ybWF0KENPTVBBQ1RfRk9STUFULCBzeW5vcHNlcywgZGVzY3IpKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgLy8gSWYgb3B0aW9uIHN5bm9wc2VzIGZpdCBvbiBhIHNpbmdsZSBsaW5lIG9mIHJlYXNvbmFibGUgbGVuZ3RoLCBzaG93IHRoYXQ7CiAgICAgICAgLy8gb3RoZXJ3aXNlLCBzaG93IDEgcGVyIGxpbmUKICAgICAgICBpZiAoc3lub3BzZXMubGVuZ3RoKCkgPD0gREVGQVVMVF9NQVhfTElORV9MRU5HVEgpIHsKICAgICAgICAgICAgbG9nLnByaW50UmF3TGluZXMoV3JpdGVyS2luZC5TVERPVVQsIFNNQUxMX0lOREVOVCArIHN5bm9wc2VzKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBmb3IgKFN0cmluZyBuYW1lOiBuYW1lcykgewogICAgICAgICAgICAgICAgbG9nLnByaW50UmF3TGluZXMoV3JpdGVyS2luZC5TVERPVVQsIFNNQUxMX0lOREVOVCArIGhlbHBTeW5vcHNpcyhuYW1lLCBsb2cpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gRmluYWxseSwgc2hvdyB0aGUgZGVzY3JpcHRpb24KICAgICAgICBsb2cucHJpbnRSYXdMaW5lcyhXcml0ZXJLaW5kLlNURE9VVCwgTEFSR0VfSU5ERU5UICsgZGVzY3IucmVwbGFjZSgiXG4iLCAiXG4iICsgTEFSR0VfSU5ERU5UKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDb21wb3NlcyB0aGUgaW5pdGlhbCBzeW5vcHNpcyBvZiBvbmUgb2YgdGhlIGZvcm1zIGZvciB0aGlzIG9wdGlvbi4KICAgICAqIEBwYXJhbSBuYW1lIHRoZSBuYW1lIG9mIHRoaXMgZm9ybSBvZiB0aGUgb3B0aW9uCiAgICAgKiBAcGFyYW0gbG9nIHRoZSBsb2cgdXNlZCB0byBsb2NhbGl6ZSB0aGUgZGVzY3JpcHRpb24gb2YgdGhlIGFyZ3VtZW50cwogICAgICogQHJldHVybiAgdGhlIHN5bm9wc2lzCiAgICAgKi8KICAgIHByaXZhdGUgU3RyaW5nIGhlbHBTeW5vcHNpcyhTdHJpbmcgbmFtZSwgTG9nIGxvZykgewogICAgICAgIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigpOwogICAgICAgIHNiLmFwcGVuZChuYW1lKTsKICAgICAgICBpZiAoYXJnc05hbWVLZXkgPT0gbnVsbCkgewogICAgICAgICAgICBpZiAoY2hvaWNlcyAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICBpZiAoIW5hbWUuZW5kc1dpdGgoIjoiKSkKICAgICAgICAgICAgICAgICAgICBzYi5hcHBlbmQoIiAiKTsKICAgICAgICAgICAgICAgIFN0cmluZyBzZXAgPSAieyI7CiAgICAgICAgICAgICAgICBmb3IgKFN0cmluZyBjaG9pY2UgOiBjaG9pY2VzKSB7CiAgICAgICAgICAgICAgICAgICAgc2IuYXBwZW5kKHNlcCk7CiAgICAgICAgICAgICAgICAgICAgc2IuYXBwZW5kKGNob2ljZSk7CiAgICAgICAgICAgICAgICAgICAgc2VwID0gIiwiOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgc2IuYXBwZW5kKCJ9Iik7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBpZiAoIW5hbWUubWF0Y2hlcygiLipbPTpdJCIpICYmIGFyZ0tpbmQgIT0gQXJnS2luZC5BREpBQ0VOVCkKICAgICAgICAgICAgICAgIHNiLmFwcGVuZCgiICIpOwogICAgICAgICAgICBzYi5hcHBlbmQobG9nLmxvY2FsaXplKFByZWZpeEtpbmQuSkFWQUMsIGFyZ3NOYW1lS2V5KSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gc2IudG9TdHJpbmcoKTsKICAgIH0KCiAgICAvLyBGb3IgLVhwa2dJbmZvOnZhbHVlCiAgICBwdWJsaWMgZW51bSBQa2dJbmZvIHsKICAgICAgICAvKioKICAgICAgICAgKiBBbHdheXMgZ2VuZXJhdGUgcGFja2FnZS1pbmZvLmNsYXNzIGZvciBldmVyeSBwYWNrYWdlLWluZm8uamF2YSBmaWxlLgogICAgICAgICAqIFRoZSBmaWxlIG1heSBiZSBlbXB0eSBpZiB0aGVyZSBhbm5vdGF0aW9ucyB3aXRoIGEgUmV0ZW50aW9uUG9saWN5CiAgICAgICAgICogb2YgQ0xBU1Mgb3IgUlVOVElNRS4gIFRoaXMgb3B0aW9uIG1heSBiZSB1c2VmdWwgaW4gY29uanVuY3Rpb24gd2l0aAogICAgICAgICAqIGJ1aWxkIHN5c3RlbXMgKHN1Y2ggYXMgQW50KSB0aGF0IGV4cGVjdCBqYXZhYyB0byBnZW5lcmF0ZSBhdCBsZWFzdAogICAgICAgICAqIG9uZSAuY2xhc3MgZmlsZSBmb3IgZXZlcnkgLmphdmEgZmlsZS4KICAgICAgICAgKi8KICAgICAgICBBTFdBWVMsCiAgICAgICAgLyoqCiAgICAgICAgICogR2VuZXJhdGUgYSBwYWNrYWdlLWluZm8uY2xhc3MgZmlsZSBpZiBwYWNrYWdlLWluZm8uamF2YSBjb250YWlucwogICAgICAgICAqIGFubm90YXRpb25zLiBUaGUgZmlsZSBtYXkgYmUgZW1wdHkgaWYgYWxsIHRoZSBhbm5vdGF0aW9ucyBoYXZlCiAgICAgICAgICogYSBSZXRlbnRpb25Qb2xpY3kgb2YgU09VUkNFLgogICAgICAgICAqIFRoaXMgdmFsdWUgaXMganVzdCBmb3IgYmFja3dhcmRzIGNvbXBhdGliaWxpdHkgd2l0aCBlYXJsaWVyIGJlaGF2aW9yLgogICAgICAgICAqIEVpdGhlciBvZiB0aGUgb3RoZXIgdHdvIHZhbHVlcyBhcmUgdG8gYmUgcHJlZmVycmVkIHRvIHVzaW5nIHRoaXMgb25lLgogICAgICAgICAqLwogICAgICAgIExFR0FDWSwKICAgICAgICAvKioKICAgICAgICAgKiBHZW5lcmF0ZSBhIHBhY2thZ2UtaW5mby5jbGFzcyBmaWxlIGlmIGFuZCBvbmx5IGlmIHRoZXJlIGFyZSBhbm5vdGF0aW9ucwogICAgICAgICAqIGluIHBhY2thZ2UtaW5mby5qYXZhIHRvIGJlIHdyaXR0ZW4gaW50byBpdC4KICAgICAgICAgKi8KICAgICAgICBOT05FTVBUWTsKCiAgICAgICAgcHVibGljIHN0YXRpYyBQa2dJbmZvIGdldChPcHRpb25zIG9wdGlvbnMpIHsKICAgICAgICAgICAgU3RyaW5nIHYgPSBvcHRpb25zLmdldChYUEtHSU5GTyk7CiAgICAgICAgICAgIHJldHVybiAodiA9PSBudWxsCiAgICAgICAgICAgICAgICAgICAgPyBQa2dJbmZvLkxFR0FDWQogICAgICAgICAgICAgICAgICAgIDogUGtnSW5mby52YWx1ZU9mKFN0cmluZ1V0aWxzLnRvVXBwZXJDYXNlKHYpKSk7CiAgICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIFNldDxTdHJpbmc+IGdldFhMaW50Q2hvaWNlcygpIHsKICAgICAgICBTZXQ8U3RyaW5nPiBjaG9pY2VzID0gbmV3IExpbmtlZEhhc2hTZXQ8PigpOwogICAgICAgIGNob2ljZXMuYWRkKCJhbGwiKTsKICAgICAgICBmb3IgKExpbnQuTGludENhdGVnb3J5IGMgOiBMaW50LkxpbnRDYXRlZ29yeS52YWx1ZXMoKSkgewogICAgICAgICAgICBjaG9pY2VzLmFkZChjLm9wdGlvbik7CiAgICAgICAgICAgIGNob2ljZXMuYWRkKCItIiArIGMub3B0aW9uKTsKICAgICAgICB9CiAgICAgICAgY2hvaWNlcy5hZGQoIm5vbmUiKTsKICAgICAgICByZXR1cm4gY2hvaWNlczsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHNldCBvZiBvcHRpb25zIHN1cHBvcnRlZCBieSB0aGUgY29tbWFuZCBsaW5lIHRvb2wuCiAgICAgKiBAcmV0dXJuIHRoZSBzZXQgb2Ygb3B0aW9ucy4KICAgICAqLwogICAgc3RhdGljIFNldDxPcHRpb24+IGdldEphdmFDb21waWxlck9wdGlvbnMoKSB7CiAgICAgICAgcmV0dXJuIEVudW1TZXQuYWxsT2YoT3B0aW9uLmNsYXNzKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHNldCBvZiBvcHRpb25zIHN1cHBvcnRlZCBieSB0aGUgYnVpbHQtaW4gZmlsZSBtYW5hZ2VyLgogICAgICogQHJldHVybiB0aGUgc2V0IG9mIG9wdGlvbnMuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgU2V0PE9wdGlvbj4gZ2V0SmF2YWNGaWxlTWFuYWdlck9wdGlvbnMoKSB7CiAgICAgICAgcmV0dXJuIGdldE9wdGlvbnMoRklMRU1BTkFHRVIpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgc2V0IG9mIG9wdGlvbnMgc3VwcG9ydGVkIGJ5IHRoaXMgaW1wbGVtZW50YXRpb24gb2YKICAgICAqIHRoZSBKYXZhQ29tcGlsZXIgQVBJLCB2aWEge0BsaW5rIEphdmFDb21waWxlciNnZXRUYXNrfS4KICAgICAqIEByZXR1cm4gdGhlIHNldCBvZiBvcHRpb25zLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIFNldDxPcHRpb24+IGdldEphdmFjVG9vbE9wdGlvbnMoKSB7CiAgICAgICAgcmV0dXJuIGdldE9wdGlvbnMoQkFTSUMpOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIFNldDxPcHRpb24+IGdldE9wdGlvbnMoT3B0aW9uR3JvdXAgZ3JvdXApIHsKICAgICAgICByZXR1cm4gQXJyYXlzLnN0cmVhbShPcHRpb24udmFsdWVzKCkpCiAgICAgICAgICAgICAgICAuZmlsdGVyKG8gLT4gby5ncm91cCA9PSBncm91cCkKICAgICAgICAgICAgICAgIC5jb2xsZWN0KENvbGxlY3RvcnMudG9Db2xsZWN0aW9uKCgpIC0+IEVudW1TZXQubm9uZU9mKE9wdGlvbi5jbGFzcykpKTsKICAgIH0KCn0KUEsDBAoAAAgAAAY7qUrwiT4JewsBAHsLAQAqAAAAY29tL3N1bi90b29scy9qYXZhYy9tYWluL0phdmFDb21waWxlci5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAxOTk5LCAyMDE3LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuamF2YWMubWFpbjsKCmltcG9ydCBqYXZhLmlvLio7CmltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbjsKaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOwppbXBvcnQgamF2YS51dGlsLkhhc2hTZXQ7CmltcG9ydCBqYXZhLnV0aWwuTGlua2VkSGFzaE1hcDsKaW1wb3J0IGphdmEudXRpbC5MaW5rZWRIYXNoU2V0OwppbXBvcnQgamF2YS51dGlsLk1hcDsKaW1wb3J0IGphdmEudXRpbC5NaXNzaW5nUmVzb3VyY2VFeGNlcHRpb247CmltcG9ydCBqYXZhLnV0aWwuUXVldWU7CmltcG9ydCBqYXZhLnV0aWwuUmVzb3VyY2VCdW5kbGU7CmltcG9ydCBqYXZhLnV0aWwuU2V0OwppbXBvcnQgamF2YS51dGlsLmZ1bmN0aW9uLkZ1bmN0aW9uOwoKaW1wb3J0IGphdmF4LmFubm90YXRpb24ucHJvY2Vzc2luZy5Qcm9jZXNzb3I7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLlNvdXJjZVZlcnNpb247CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuRWxlbWVudFZpc2l0b3I7CmltcG9ydCBqYXZheC50b29scy5EaWFnbm9zdGljTGlzdGVuZXI7CmltcG9ydCBqYXZheC50b29scy5KYXZhRmlsZU1hbmFnZXI7CmltcG9ydCBqYXZheC50b29scy5KYXZhRmlsZU9iamVjdDsKaW1wb3J0IGphdmF4LnRvb2xzLkphdmFGaWxlT2JqZWN0LktpbmQ7CmltcG9ydCBqYXZheC50b29scy5TdGFuZGFyZExvY2F0aW9uOwoKaW1wb3J0IGNvbS5zdW4uc291cmNlLnV0aWwuVGFza0V2ZW50OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5hcGkuTXVsdGlUYXNrTGlzdGVuZXI7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuKjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5MaW50LkxpbnRDYXRlZ29yeTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5TeW1ib2wuQ2xhc3NTeW1ib2w7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuU3ltYm9sLkNvbXBsZXRpb25GYWlsdXJlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlN5bWJvbC5QYWNrYWdlU3ltYm9sOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb21wLio7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvbXAuQ29tcGlsZVN0YXRlcy5Db21waWxlU3RhdGU7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmZpbGUuSmF2YWNGaWxlTWFuYWdlcjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuanZtLio7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnBhcnNlci4qOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5wbGF0Zm9ybS5QbGF0Zm9ybURlc2NyaXB0aW9uOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5wcm9jZXNzaW5nLio7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuKjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5KQ1RyZWUuSkNDbGFzc0RlY2w7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuSkNUcmVlLkpDQ29tcGlsYXRpb25Vbml0OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkpDVHJlZS5KQ0V4cHJlc3Npb247CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuSkNUcmVlLkpDTGFtYmRhOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkpDVHJlZS5KQ01lbWJlclJlZmVyZW5jZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5KQ1RyZWUuSkNNZXRob2REZWNsOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkpDVHJlZS5KQ01vZHVsZURlY2w7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuSkNUcmVlLkpDVmFyaWFibGVEZWNsOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkpDVHJlZS5UYWc7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuKjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5EZWZpbmVkQnkuQXBpOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkpDRGlhZ25vc3RpYy5GYWN0b3J5OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkxvZy5Xcml0ZXJLaW5kOwoKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuS2luZHMuS2luZC4qOwoKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5TeW1ib2wuTW9kdWxlU3ltYm9sOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5yZXNvdXJjZXMuQ29tcGlsZXJQcm9wZXJ0aWVzLkVycm9yczsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMucmVzb3VyY2VzLkNvbXBpbGVyUHJvcGVydGllcy5XYXJuaW5nczsKCmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlR5cGVUYWcuQ0xBU1M7CmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5tYWluLk9wdGlvbi4qOwppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5KQ0RpYWdub3N0aWMuRGlhZ25vc3RpY0ZsYWcuKjsKCmltcG9ydCBzdGF0aWMgamF2YXgudG9vbHMuU3RhbmRhcmRMb2NhdGlvbi5DTEFTU19PVVRQVVQ7CgovKiogVGhpcyBjbGFzcyBjb3VsZCBiZSB0aGUgbWFpbiBlbnRyeSBwb2ludCBmb3IgR0pDIHdoZW4gR0pDIGlzIHVzZWQgYXMgYQogKiAgY29tcG9uZW50IGluIGEgbGFyZ2VyIHNvZnR3YXJlIHN5c3RlbS4gSXQgcHJvdmlkZXMgb3BlcmF0aW9ucyB0bwogKiAgY29uc3RydWN0IGEgbmV3IGNvbXBpbGVyLCBhbmQgdG8gcnVuIGEgbmV3IGNvbXBpbGVyIG9uIGEgc2V0IG9mIHNvdXJjZQogKiAgZmlsZXMuCiAqCiAqICA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiAgSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93biByaXNrLgogKiAgVGhpcyBjb2RlIGFuZCBpdHMgaW50ZXJuYWwgaW50ZXJmYWNlcyBhcmUgc3ViamVjdCB0byBjaGFuZ2Ugb3IKICogIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj4KICovCnB1YmxpYyBjbGFzcyBKYXZhQ29tcGlsZXIgewogICAgLyoqIFRoZSBjb250ZXh0IGtleSBmb3IgdGhlIGNvbXBpbGVyLiAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBDb250ZXh0LktleTxKYXZhQ29tcGlsZXI+IGNvbXBpbGVyS2V5ID0gbmV3IENvbnRleHQuS2V5PD4oKTsKCiAgICAvKiogR2V0IHRoZSBKYXZhQ29tcGlsZXIgaW5zdGFuY2UgZm9yIHRoaXMgY29udGV4dC4gKi8KICAgIHB1YmxpYyBzdGF0aWMgSmF2YUNvbXBpbGVyIGluc3RhbmNlKENvbnRleHQgY29udGV4dCkgewogICAgICAgIEphdmFDb21waWxlciBpbnN0YW5jZSA9IGNvbnRleHQuZ2V0KGNvbXBpbGVyS2V5KTsKICAgICAgICBpZiAoaW5zdGFuY2UgPT0gbnVsbCkKICAgICAgICAgICAgaW5zdGFuY2UgPSBuZXcgSmF2YUNvbXBpbGVyKGNvbnRleHQpOwogICAgICAgIHJldHVybiBpbnN0YW5jZTsKICAgIH0KCiAgICAvKiogVGhlIGN1cnJlbnQgdmVyc2lvbiBudW1iZXIgYXMgYSBzdHJpbmcuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHZlcnNpb24oKSB7CiAgICAgICAgcmV0dXJuIHZlcnNpb24oInJlbGVhc2UiKTsgIC8vIG1tLm5uLm9vWy1taWxlc3RvbmVdCiAgICB9CgogICAgLyoqIFRoZSBjdXJyZW50IGZ1bGwgdmVyc2lvbiBudW1iZXIgYXMgYSBzdHJpbmcuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGZ1bGxWZXJzaW9uKCkgewogICAgICAgIHJldHVybiB2ZXJzaW9uKCJmdWxsIik7IC8vIG1tLm1tLm9vWy1taWxlc3RvbmVdLWJ1aWxkCiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIHZlcnNpb25SQk5hbWUgPSAiY29tLnN1bi50b29scy5qYXZhYy5yZXNvdXJjZXMudmVyc2lvbiI7CiAgICBwcml2YXRlIHN0YXRpYyBSZXNvdXJjZUJ1bmRsZSB2ZXJzaW9uUkI7CgogICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIHZlcnNpb24oU3RyaW5nIGtleSkgewogICAgICAgIGlmICh2ZXJzaW9uUkIgPT0gbnVsbCkgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgdmVyc2lvblJCID0gUmVzb3VyY2VCdW5kbGUuZ2V0QnVuZGxlKHZlcnNpb25SQk5hbWUpOwogICAgICAgICAgICB9IGNhdGNoIChNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24gZSkgewogICAgICAgICAgICAgICAgcmV0dXJuIExvZy5nZXRMb2NhbGl6ZWRTdHJpbmcoInZlcnNpb24ubm90LmF2YWlsYWJsZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICAgIHJldHVybiB2ZXJzaW9uUkIuZ2V0U3RyaW5nKGtleSk7CiAgICAgICAgfQogICAgICAgIGNhdGNoIChNaXNzaW5nUmVzb3VyY2VFeGNlcHRpb24gZSkgewogICAgICAgICAgICByZXR1cm4gTG9nLmdldExvY2FsaXplZFN0cmluZygidmVyc2lvbi5ub3QuYXZhaWxhYmxlIik7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQ29udHJvbCBob3cgdGhlIGNvbXBpbGVyJ3MgbGF0dGVyIHBoYXNlcyAoYXR0ciwgZmxvdywgZGVzdWdhciwgZ2VuZXJhdGUpCiAgICAgKiBhcmUgY29ubmVjdGVkLiBFYWNoIGluZGl2aWR1YWwgZmlsZSBpcyBwcm9jZXNzZWQgYnkgZWFjaCBwaGFzZSBpbiB0dXJuLAogICAgICogYnV0IHdpdGggZGlmZmVyZW50IGNvbXBpbGUgcG9saWNpZXMsIHlvdSBjYW4gY29udHJvbCB0aGUgb3JkZXIgaW4gd2hpY2gKICAgICAqIGVhY2ggY2xhc3MgaXMgcHJvY2Vzc2VkIHRocm91Z2ggaXRzIG5leHQgcGhhc2UuCiAgICAgKgogICAgICogPHA+R2VuZXJhbGx5IHNwZWFraW5nLCB0aGUgY29tcGlsZXIgd2lsbCAiZmFpbCBmYXN0IiBpbiB0aGUgZmFjZSBvZgogICAgICogZXJyb3JzLCBhbHRob3VnaCBub3QgYWdncmVzc2l2ZWx5IHNvLiBmbG93LCBkZXN1Z2FyLCBldGMgYmVjb21lIG5vLW9wcwogICAgICogb25jZSBhbnkgZXJyb3JzIGhhdmUgb2NjdXJyZWQuIE5vIGF0dGVtcHQgaXMgY3VycmVudGx5IG1hZGUgdG8gZGV0ZXJtaW5lCiAgICAgKiBpZiBpdCBtaWdodCBiZSBzYWZlIHRvIHByb2Nlc3MgYSBjbGFzcyB0aHJvdWdoIGl0cyBuZXh0IHBoYXNlIGJlY2F1c2UKICAgICAqIGl0IGRvZXMgbm90IGRlcGVuZCBvbiBhbnkgdW5yZWxhdGVkIGVycm9ycyB0aGF0IG1pZ2h0IGhhdmUgb2NjdXJyZWQuCiAgICAgKi8KICAgIHByb3RlY3RlZCBzdGF0aWMgZW51bSBDb21waWxlUG9saWN5IHsKICAgICAgICAvKioKICAgICAgICAgKiBKdXN0IGF0dHJpYnV0ZSB0aGUgcGFyc2UgdHJlZXMuCiAgICAgICAgICovCiAgICAgICAgQVRUUl9PTkxZLAoKICAgICAgICAvKioKICAgICAgICAgKiBKdXN0IGF0dHJpYnV0ZSBhbmQgZG8gZmxvdyBhbmFseXNpcyBvbiB0aGUgcGFyc2UgdHJlZXMuCiAgICAgICAgICogVGhpcyBzaG91bGQgY2F0Y2ggbW9zdCB1c2VyIGVycm9ycy4KICAgICAgICAgKi8KICAgICAgICBDSEVDS19PTkxZLAoKICAgICAgICAvKioKICAgICAgICAgKiBBdHRyaWJ1dGUgZXZlcnl0aGluZywgdGhlbiBkbyBmbG93IGFuYWx5c2lzIGZvciBldmVyeXRoaW5nLAogICAgICAgICAqIHRoZW4gZGVzdWdhciBldmVyeXRoaW5nLCBhbmQgb25seSB0aGVuIGdlbmVyYXRlIG91dHB1dC4KICAgICAgICAgKiBUaGlzIG1lYW5zIG5vIG91dHB1dCB3aWxsIGJlIGdlbmVyYXRlZCBpZiB0aGVyZSBhcmUgYW55CiAgICAgICAgICogZXJyb3JzIGluIGFueSBjbGFzc2VzLgogICAgICAgICAqLwogICAgICAgIFNJTVBMRSwKCiAgICAgICAgLyoqCiAgICAgICAgICogR3JvdXBzIHRoZSBjbGFzc2VzIGZvciBlYWNoIHNvdXJjZSBmaWxlIHRvZ2V0aGVyLCB0aGVuIHByb2Nlc3MKICAgICAgICAgKiBlYWNoIGdyb3VwIGluIGEgbWFubmVyIGVxdWl2YWxlbnQgdG8gdGhlIHtAY29kZSBTSU1QTEV9IHBvbGljeS4KICAgICAgICAgKiBUaGlzIG1lYW5zIG5vIG91dHB1dCB3aWxsIGJlIGdlbmVyYXRlZCBpZiB0aGVyZSBhcmUgYW55CiAgICAgICAgICogZXJyb3JzIGluIGFueSBvZiB0aGUgY2xhc3NlcyBpbiBhIHNvdXJjZSBmaWxlLgogICAgICAgICAqLwogICAgICAgIEJZX0ZJTEUsCgogICAgICAgIC8qKgogICAgICAgICAqIENvbXBsZXRlbHkgcHJvY2VzcyBlYWNoIGVudHJ5IG9uIHRoZSB0b2RvIGxpc3QgaW4gdHVybi4KICAgICAgICAgKiAtLSB0aGlzIGlzIHRoZSBzYW1lIGZvciAxLjUuCiAgICAgICAgICogTWVhbnMgb3V0cHV0IG1pZ2h0IGJlIGdlbmVyYXRlZCBmb3Igc29tZSBjbGFzc2VzIGluIGEgY29tcGlsYXRpb24gdW5pdAogICAgICAgICAqIGFuZCBub3Qgb3RoZXJzLgogICAgICAgICAqLwogICAgICAgIEJZX1RPRE87CgogICAgICAgIHN0YXRpYyBDb21waWxlUG9saWN5IGRlY29kZShTdHJpbmcgb3B0aW9uKSB7CiAgICAgICAgICAgIGlmIChvcHRpb24gPT0gbnVsbCkKICAgICAgICAgICAgICAgIHJldHVybiBERUZBVUxUX0NPTVBJTEVfUE9MSUNZOwogICAgICAgICAgICBlbHNlIGlmIChvcHRpb24uZXF1YWxzKCJhdHRyIikpCiAgICAgICAgICAgICAgICByZXR1cm4gQVRUUl9PTkxZOwogICAgICAgICAgICBlbHNlIGlmIChvcHRpb24uZXF1YWxzKCJjaGVjayIpKQogICAgICAgICAgICAgICAgcmV0dXJuIENIRUNLX09OTFk7CiAgICAgICAgICAgIGVsc2UgaWYgKG9wdGlvbi5lcXVhbHMoInNpbXBsZSIpKQogICAgICAgICAgICAgICAgcmV0dXJuIFNJTVBMRTsKICAgICAgICAgICAgZWxzZSBpZiAob3B0aW9uLmVxdWFscygiYnlmaWxlIikpCiAgICAgICAgICAgICAgICByZXR1cm4gQllfRklMRTsKICAgICAgICAgICAgZWxzZSBpZiAob3B0aW9uLmVxdWFscygiYnl0b2RvIikpCiAgICAgICAgICAgICAgICByZXR1cm4gQllfVE9ETzsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgcmV0dXJuIERFRkFVTFRfQ09NUElMRV9QT0xJQ1k7CiAgICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIENvbXBpbGVQb2xpY3kgREVGQVVMVF9DT01QSUxFX1BPTElDWSA9IENvbXBpbGVQb2xpY3kuQllfVE9ETzsKCiAgICBwcm90ZWN0ZWQgc3RhdGljIGVudW0gSW1wbGljaXRTb3VyY2VQb2xpY3kgewogICAgICAgIC8qKiBEb24ndCBnZW5lcmF0ZSBvciBwcm9jZXNzIGltcGxpY2l0bHkgcmVhZCBzb3VyY2UgZmlsZXMuICovCiAgICAgICAgTk9ORSwKICAgICAgICAvKiogR2VuZXJhdGUgY2xhc3NlcyBmb3IgaW1wbGljaXRseSByZWFkIHNvdXJjZSBmaWxlcy4gKi8KICAgICAgICBDTEFTUywKICAgICAgICAvKiogTGlrZSBDTEFTUywgYnV0IGdlbmVyYXRlIHdhcm5pbmdzIGlmIGFubm90YXRpb24gcHJvY2Vzc2luZyBvY2N1cnMgKi8KICAgICAgICBVTlNFVDsKCiAgICAgICAgc3RhdGljIEltcGxpY2l0U291cmNlUG9saWN5IGRlY29kZShTdHJpbmcgb3B0aW9uKSB7CiAgICAgICAgICAgIGlmIChvcHRpb24gPT0gbnVsbCkKICAgICAgICAgICAgICAgIHJldHVybiBVTlNFVDsKICAgICAgICAgICAgZWxzZSBpZiAob3B0aW9uLmVxdWFscygibm9uZSIpKQogICAgICAgICAgICAgICAgcmV0dXJuIE5PTkU7CiAgICAgICAgICAgIGVsc2UgaWYgKG9wdGlvbi5lcXVhbHMoImNsYXNzIikpCiAgICAgICAgICAgICAgICByZXR1cm4gQ0xBU1M7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHJldHVybiBVTlNFVDsKICAgICAgICB9CiAgICB9CgogICAgLyoqIFRoZSBsb2cgdG8gYmUgdXNlZCBmb3IgZXJyb3IgcmVwb3J0aW5nLgogICAgICovCiAgICBwdWJsaWMgTG9nIGxvZzsKCiAgICAvKiogRmFjdG9yeSBmb3IgY3JlYXRpbmcgZGlhZ25vc3RpYyBvYmplY3RzCiAgICAgKi8KICAgIEpDRGlhZ25vc3RpYy5GYWN0b3J5IGRpYWdGYWN0b3J5OwoKICAgIC8qKiBUaGUgdHJlZSBmYWN0b3J5IG1vZHVsZS4KICAgICAqLwogICAgcHJvdGVjdGVkIFRyZWVNYWtlciBtYWtlOwoKICAgIC8qKiBUaGUgY2xhc3MgZmluZGVyLgogICAgICovCiAgICBwcm90ZWN0ZWQgQ2xhc3NGaW5kZXIgZmluZGVyOwoKICAgIC8qKiBUaGUgY2xhc3MgcmVhZGVyLgogICAgICovCiAgICBwcm90ZWN0ZWQgQ2xhc3NSZWFkZXIgcmVhZGVyOwoKICAgIC8qKiBUaGUgY2xhc3Mgd3JpdGVyLgogICAgICovCiAgICBwcm90ZWN0ZWQgQ2xhc3NXcml0ZXIgd3JpdGVyOwoKICAgIC8qKiBUaGUgbmF0aXZlIGhlYWRlciB3cml0ZXIuCiAgICAgKi8KICAgIHByb3RlY3RlZCBKTklXcml0ZXIgam5pV3JpdGVyOwoKICAgIC8qKiBUaGUgbW9kdWxlIGZvciB0aGUgc3ltYm9sIHRhYmxlIGVudHJ5IHBoYXNlcy4KICAgICAqLwogICAgcHJvdGVjdGVkIEVudGVyIGVudGVyOwoKICAgIC8qKiBUaGUgc3ltYm9sIHRhYmxlLgogICAgICovCiAgICBwcm90ZWN0ZWQgU3ltdGFiIHN5bXM7CgogICAgLyoqIFRoZSBsYW5ndWFnZSB2ZXJzaW9uLgogICAgICovCiAgICBwcm90ZWN0ZWQgU291cmNlIHNvdXJjZTsKCiAgICAvKiogVGhlIG1vZHVsZSBmb3IgY29kZSBnZW5lcmF0aW9uLgogICAgICovCiAgICBwcm90ZWN0ZWQgR2VuIGdlbjsKCiAgICAvKiogVGhlIG5hbWUgdGFibGUuCiAgICAgKi8KICAgIHByb3RlY3RlZCBOYW1lcyBuYW1lczsKCiAgICAvKiogVGhlIGF0dHJpYnV0b3IuCiAgICAgKi8KICAgIHByb3RlY3RlZCBBdHRyIGF0dHI7CgogICAgLyoqIFRoZSBhdHRyaWJ1dG9yLgogICAgICovCiAgICBwcm90ZWN0ZWQgQ2hlY2sgY2hrOwoKICAgIC8qKiBUaGUgZmxvdyBhbmFseXplci4KICAgICAqLwogICAgcHJvdGVjdGVkIEZsb3cgZmxvdzsKCiAgICAvKiogVGhlIG1vZHVsZXMgdmlzaXRvcgogICAgICovCiAgICBwcm90ZWN0ZWQgTW9kdWxlcyBtb2R1bGVzOwoKICAgIC8qKiBUaGUgbW9kdWxlIGZpbmRlcgogICAgICovCiAgICBwcm90ZWN0ZWQgTW9kdWxlRmluZGVyIG1vZHVsZUZpbmRlcjsKCiAgICAvKiogVGhlIGRpYWdub3N0aWNzIGZhY3RvcnkKICAgICAqLwogICAgcHJvdGVjdGVkIEpDRGlhZ25vc3RpYy5GYWN0b3J5IGRpYWdzOwoKICAgIC8qKiBUaGUgdHlwZSBlcmFzZXIuCiAgICAgKi8KICAgIHByb3RlY3RlZCBUcmFuc1R5cGVzIHRyYW5zVHlwZXM7CgogICAgLyoqIFRoZSBzeW50YWN0aWMgc3VnYXIgZGVzd2VldGVuZXIuCiAgICAgKi8KICAgIHByb3RlY3RlZCBMb3dlciBsb3dlcjsKCiAgICAvKiogVGhlIGFubm90YXRpb24gYW5ub3RhdG9yLgogICAgICovCiAgICBwcm90ZWN0ZWQgQW5ub3RhdGUgYW5ub3RhdGU7CgogICAgLyoqIEZvcmNlIGEgY29tcGxldGlvbiBmYWlsdXJlIG9uIHRoaXMgbmFtZQogICAgICovCiAgICBwcm90ZWN0ZWQgZmluYWwgTmFtZSBjb21wbGV0aW9uRmFpbHVyZU5hbWU7CgogICAgLyoqIFR5cGUgdXRpbGl0aWVzLgogICAgICovCiAgICBwcm90ZWN0ZWQgVHlwZXMgdHlwZXM7CgogICAgLyoqIEFjY2VzcyB0byBmaWxlIG9iamVjdHMuCiAgICAgKi8KICAgIHByb3RlY3RlZCBKYXZhRmlsZU1hbmFnZXIgZmlsZU1hbmFnZXI7CgogICAgLyoqIEZhY3RvcnkgZm9yIHBhcnNlcnMuCiAgICAgKi8KICAgIHByb3RlY3RlZCBQYXJzZXJGYWN0b3J5IHBhcnNlckZhY3Rvcnk7CgogICAgLyoqIEJyb2FkY2FzdGluZyBsaXN0ZW5lciBmb3IgcHJvZ3Jlc3MgZXZlbnRzCiAgICAgKi8KICAgIHByb3RlY3RlZCBNdWx0aVRhc2tMaXN0ZW5lciB0YXNrTGlzdGVuZXI7CgogICAgLyoqCiAgICAgKiBTb3VyY2VDb21wbGV0ZXIgdGhhdCBkZWxlZ2F0ZXMgdG8gdGhlIHJlYWRTb3VyY2VGaWxlIG1ldGhvZCBvZiB0aGlzIGNsYXNzLgogICAgICovCiAgICBwcm90ZWN0ZWQgZmluYWwgU3ltYm9sLkNvbXBsZXRlciBzb3VyY2VDb21wbGV0ZXIgPQogICAgICAgICAgICBzeW0gLT4gcmVhZFNvdXJjZUZpbGUoKENsYXNzU3ltYm9sKSBzeW0pOwoKICAgIHByb3RlY3RlZCBmaW5hbCBNb2R1bGVGaW5kZXIuTW9kdWxlSW5mb1NvdXJjZUZpbGVDb21wbGV0ZXIgbW9kdWxlSW5mb1NvdXJjZUZpbGVDb21wbGV0ZXIgPQogICAgICAgICAgICBmbyAtPiAoTW9kdWxlU3ltYm9sKSByZWFkU291cmNlRmlsZShwYXJzZUltcGxpY2l0RmlsZShmbyksIG51bGwsIHRsIC0+IHsKICAgICAgICAgICAgICAgIHJldHVybiB0bC5kZWZzLm5vbkVtcHR5KCkgJiYgdGwuZGVmcy5oZWFkLmhhc1RhZyhUYWcuTU9EVUxFREVGKSA/CiAgICAgICAgICAgICAgICAgICAgICAgICgoSkNNb2R1bGVEZWNsKSB0bC5kZWZzLmhlYWQpLnN5bS5tb2R1bGVfaW5mbyA6CiAgICAgICAgICAgICAgICAgICAgICAgIHN5bXMuZGVmaW5lQ2xhc3MobmFtZXMubW9kdWxlX2luZm8sIHN5bXMuZXJyTW9kdWxlKTsKICAgICAgICAgICAgfSkub3duZXI7CgogICAgLyoqCiAgICAgKiBDb21tYW5kIGxpbmUgb3B0aW9ucy4KICAgICAqLwogICAgcHJvdGVjdGVkIE9wdGlvbnMgb3B0aW9uczsKCiAgICBwcm90ZWN0ZWQgQ29udGV4dCBjb250ZXh0OwoKICAgIC8qKgogICAgICogRmxhZyBzZXQgaWYgYW55IGFubm90YXRpb24gcHJvY2Vzc2luZyBvY2N1cnJlZC4KICAgICAqKi8KICAgIHByb3RlY3RlZCBib29sZWFuIGFubm90YXRpb25Qcm9jZXNzaW5nT2NjdXJyZWQ7CgogICAgLyoqCiAgICAgKiBGbGFnIHNldCBpZiBhbnkgaW1wbGljaXQgc291cmNlIGZpbGVzIHJlYWQuCiAgICAgKiovCiAgICBwcm90ZWN0ZWQgYm9vbGVhbiBpbXBsaWNpdFNvdXJjZUZpbGVzUmVhZDsKCiAgICBwcml2YXRlIGJvb2xlYW4gZW50ZXJEb25lOwoKICAgIHByb3RlY3RlZCBDb21waWxlU3RhdGVzIGNvbXBpbGVTdGF0ZXM7CgogICAgLyoqIENvbnN0cnVjdCBhIG5ldyBjb21waWxlciB1c2luZyBhIHNoYXJlZCBjb250ZXh0LgogICAgICovCiAgICBwdWJsaWMgSmF2YUNvbXBpbGVyKENvbnRleHQgY29udGV4dCkgewogICAgICAgIHRoaXMuY29udGV4dCA9IGNvbnRleHQ7CiAgICAgICAgY29udGV4dC5wdXQoY29tcGlsZXJLZXksIHRoaXMpOwoKICAgICAgICAvLyBpZiBmaWxlTWFuYWdlciBub3QgYWxyZWFkeSBzZXQsIHJlZ2lzdGVyIHRoZSBKYXZhY0ZpbGVNYW5hZ2VyIHRvIGJlIHVzZWQKICAgICAgICBpZiAoY29udGV4dC5nZXQoSmF2YUZpbGVNYW5hZ2VyLmNsYXNzKSA9PSBudWxsKQogICAgICAgICAgICBKYXZhY0ZpbGVNYW5hZ2VyLnByZVJlZ2lzdGVyKGNvbnRleHQpOwoKICAgICAgICBuYW1lcyA9IE5hbWVzLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIGxvZyA9IExvZy5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBkaWFnRmFjdG9yeSA9IEpDRGlhZ25vc3RpYy5GYWN0b3J5Lmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIGZpbmRlciA9IENsYXNzRmluZGVyLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIHJlYWRlciA9IENsYXNzUmVhZGVyLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIG1ha2UgPSBUcmVlTWFrZXIuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgd3JpdGVyID0gQ2xhc3NXcml0ZXIuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgam5pV3JpdGVyID0gSk5JV3JpdGVyLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIGVudGVyID0gRW50ZXIuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgdG9kbyA9IFRvZG8uaW5zdGFuY2UoY29udGV4dCk7CgogICAgICAgIGZpbGVNYW5hZ2VyID0gY29udGV4dC5nZXQoSmF2YUZpbGVNYW5hZ2VyLmNsYXNzKTsKICAgICAgICBwYXJzZXJGYWN0b3J5ID0gUGFyc2VyRmFjdG9yeS5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBjb21waWxlU3RhdGVzID0gQ29tcGlsZVN0YXRlcy5pbnN0YW5jZShjb250ZXh0KTsKCiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgLy8gY2F0Y2ggY29tcGxldGlvbiBwcm9ibGVtcyB3aXRoIHByZWRlZmluZWRzCiAgICAgICAgICAgIHN5bXMgPSBTeW10YWIuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgfSBjYXRjaCAoQ29tcGxldGlvbkZhaWx1cmUgZXgpIHsKICAgICAgICAgICAgLy8gaW5saW5lZCBDaGVjay5jb21wbGV0aW9uRXJyb3IgYXMgaXQgaXMgbm90IGluaXRpYWxpemVkIHlldAogICAgICAgICAgICBsb2cuZXJyb3IoImNhbnQuYWNjZXNzIiwgZXguc3ltLCBleC5nZXREZXRhaWxWYWx1ZSgpKTsKICAgICAgICAgICAgaWYgKGV4IGluc3RhbmNlb2YgQ2xhc3NGaW5kZXIuQmFkQ2xhc3NGaWxlKQogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFib3J0KCk7CiAgICAgICAgfQogICAgICAgIHNvdXJjZSA9IFNvdXJjZS5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBhdHRyID0gQXR0ci5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBjaGsgPSBDaGVjay5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBnZW4gPSBHZW4uaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgZmxvdyA9IEZsb3cuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgdHJhbnNUeXBlcyA9IFRyYW5zVHlwZXMuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgbG93ZXIgPSBMb3dlci5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBhbm5vdGF0ZSA9IEFubm90YXRlLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIHR5cGVzID0gVHlwZXMuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgdGFza0xpc3RlbmVyID0gTXVsdGlUYXNrTGlzdGVuZXIuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgbW9kdWxlcyA9IE1vZHVsZXMuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgbW9kdWxlRmluZGVyID0gTW9kdWxlRmluZGVyLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIGRpYWdzID0gRmFjdG9yeS5pbnN0YW5jZShjb250ZXh0KTsKCiAgICAgICAgZmluZGVyLnNvdXJjZUNvbXBsZXRlciA9IHNvdXJjZUNvbXBsZXRlcjsKICAgICAgICBtb2R1bGVGaW5kZXIuc291cmNlRmlsZUNvbXBsZXRlciA9IG1vZHVsZUluZm9Tb3VyY2VGaWxlQ29tcGxldGVyOwoKICAgICAgICBvcHRpb25zID0gT3B0aW9ucy5pbnN0YW5jZShjb250ZXh0KTsKCiAgICAgICAgdmVyYm9zZSAgICAgICA9IG9wdGlvbnMuaXNTZXQoVkVSQk9TRSk7CiAgICAgICAgc291cmNlT3V0cHV0ICA9IG9wdGlvbnMuaXNTZXQoUFJJTlRTT1VSQ0UpOyAvLyB1c2VkIHRvIGJlIC1zCiAgICAgICAgbGluZURlYnVnSW5mbyA9IG9wdGlvbnMuaXNVbnNldChHX0NVU1RPTSkgfHwKICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5pc1NldChHX0NVU1RPTSwgImxpbmVzIik7CiAgICAgICAgZ2VuRW5kUG9zICAgICA9IG9wdGlvbnMuaXNTZXQoWEpDT1YpIHx8CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHQuZ2V0KERpYWdub3N0aWNMaXN0ZW5lci5jbGFzcykgIT0gbnVsbDsKICAgICAgICBkZXZWZXJib3NlICAgID0gb3B0aW9ucy5pc1NldCgiZGV2Iik7CiAgICAgICAgcHJvY2Vzc1Bja3MgICA9IG9wdGlvbnMuaXNTZXQoInByb2Nlc3MucGFja2FnZXMiKTsKICAgICAgICB3ZXJyb3IgICAgICAgID0gb3B0aW9ucy5pc1NldChXRVJST1IpOwoKICAgICAgICB2ZXJib3NlQ29tcGlsZVBvbGljeSA9IG9wdGlvbnMuaXNTZXQoInZlcmJvc2VDb21waWxlUG9saWN5Iik7CgogICAgICAgIGlmIChvcHRpb25zLmlzU2V0KCJzaG91bGQtc3RvcC5hdCIpICYmCiAgICAgICAgICAgIENvbXBpbGVTdGF0ZS52YWx1ZU9mKG9wdGlvbnMuZ2V0KCJzaG91bGQtc3RvcC5hdCIpKSA9PSBDb21waWxlU3RhdGUuQVRUUikKICAgICAgICAgICAgY29tcGlsZVBvbGljeSA9IENvbXBpbGVQb2xpY3kuQVRUUl9PTkxZOwogICAgICAgIGVsc2UKICAgICAgICAgICAgY29tcGlsZVBvbGljeSA9IENvbXBpbGVQb2xpY3kuZGVjb2RlKG9wdGlvbnMuZ2V0KCJjb21waWxlUG9saWN5IikpOwoKICAgICAgICBpbXBsaWNpdFNvdXJjZVBvbGljeSA9IEltcGxpY2l0U291cmNlUG9saWN5LmRlY29kZShvcHRpb25zLmdldCgiLWltcGxpY2l0IikpOwoKICAgICAgICBjb21wbGV0aW9uRmFpbHVyZU5hbWUgPQogICAgICAgICAgICBvcHRpb25zLmlzU2V0KCJmYWlsY29tcGxldGUiKQogICAgICAgICAgICA/IG5hbWVzLmZyb21TdHJpbmcob3B0aW9ucy5nZXQoImZhaWxjb21wbGV0ZSIpKQogICAgICAgICAgICA6IG51bGw7CgogICAgICAgIHNob3VsZFN0b3BQb2xpY3lJZkVycm9yID0KICAgICAgICAgICAgb3B0aW9ucy5pc1NldCgic2hvdWxkLXN0b3AuYXQiKSAvLyBiYWNrd2FyZHMgY29tcGF0aWJsZQogICAgICAgICAgICA/IENvbXBpbGVTdGF0ZS52YWx1ZU9mKG9wdGlvbnMuZ2V0KCJzaG91bGQtc3RvcC5hdCIpKQogICAgICAgICAgICA6IG9wdGlvbnMuaXNTZXQoInNob3VsZC1zdG9wLmlmRXJyb3IiKQogICAgICAgICAgICA/IENvbXBpbGVTdGF0ZS52YWx1ZU9mKG9wdGlvbnMuZ2V0KCJzaG91bGQtc3RvcC5pZkVycm9yIikpCiAgICAgICAgICAgIDogQ29tcGlsZVN0YXRlLklOSVQ7CiAgICAgICAgc2hvdWxkU3RvcFBvbGljeUlmTm9FcnJvciA9CiAgICAgICAgICAgIG9wdGlvbnMuaXNTZXQoInNob3VsZC1zdG9wLmlmTm9FcnJvciIpCiAgICAgICAgICAgID8gQ29tcGlsZVN0YXRlLnZhbHVlT2Yob3B0aW9ucy5nZXQoInNob3VsZC1zdG9wLmlmTm9FcnJvciIpKQogICAgICAgICAgICA6IENvbXBpbGVTdGF0ZS5HRU5FUkFURTsKCiAgICAgICAgaWYgKG9wdGlvbnMuaXNVbnNldCgiZGlhZ3MubGVnYWN5IikpCiAgICAgICAgICAgIGxvZy5zZXREaWFnbm9zdGljRm9ybWF0dGVyKFJpY2hEaWFnbm9zdGljRm9ybWF0dGVyLmluc3RhbmNlKGNvbnRleHQpKTsKCiAgICAgICAgUGxhdGZvcm1EZXNjcmlwdGlvbiBwbGF0Zm9ybVByb3ZpZGVyID0gY29udGV4dC5nZXQoUGxhdGZvcm1EZXNjcmlwdGlvbi5jbGFzcyk7CgogICAgICAgIGlmIChwbGF0Zm9ybVByb3ZpZGVyICE9IG51bGwpCiAgICAgICAgICAgIGNsb3NlYWJsZXMgPSBjbG9zZWFibGVzLnByZXBlbmQocGxhdGZvcm1Qcm92aWRlcik7CgogICAgICAgIHNpbGVudEZhaWwgPSBuZXcgU3ltYm9sKEFCU0VOVF9UWVAsIDAsIG5hbWVzLmVtcHR5LCBUeXBlLm5vVHlwZSwgc3ltcy5yb290UGFja2FnZSkgewogICAgICAgICAgICBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgICAgICAgICAgcHVibGljIDxSLCBQPiBSIGFjY2VwdChFbGVtZW50VmlzaXRvcjxSLCBQPiB2LCBQIHApIHsKICAgICAgICAgICAgICAgIHJldHVybiB2LnZpc2l0VW5rbm93bih0aGlzLCBwKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHVibGljIGJvb2xlYW4gZXhpc3RzKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfTsKCiAgICB9CgogICAgLyogU3dpdGNoZXM6CiAgICAgKi8KCiAgICAvKiogVmVyYm9zZSBvdXRwdXQuCiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIHZlcmJvc2U7CgogICAgLyoqIEVtaXQgcGxhaW4gSmF2YSBzb3VyY2UgZmlsZXMgcmF0aGVyIHRoYW4gY2xhc3MgZmlsZXMuCiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIHNvdXJjZU91dHB1dDsKCgogICAgLyoqIEdlbmVyYXRlIGNvZGUgd2l0aCB0aGUgTGluZU51bWJlclRhYmxlIGF0dHJpYnV0ZSBmb3IgZGVidWdnaW5nCiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGxpbmVEZWJ1Z0luZm87CgogICAgLyoqIFN3aXRjaDogc2hvdWxkIHdlIHN0b3JlIHRoZSBlbmRpbmcgcG9zaXRpb25zPwogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBnZW5FbmRQb3M7CgogICAgLyoqIFN3aXRjaDogc2hvdWxkIHdlIGRlYnVnIGlnbm9yZWQgZXhjZXB0aW9ucwogICAgICovCiAgICBwcm90ZWN0ZWQgYm9vbGVhbiBkZXZWZXJib3NlOwoKICAgIC8qKiBTd2l0Y2g6IHNob3VsZCB3ZSAoYW5ub3RhdGlvbikgcHJvY2VzcyBwYWNrYWdlcyBhcyB3ZWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCBib29sZWFuIHByb2Nlc3NQY2tzOwoKICAgIC8qKiBTd2l0Y2g6IHRyZWF0IHdhcm5pbmdzIGFzIGVycm9ycwogICAgICovCiAgICBwcm90ZWN0ZWQgYm9vbGVhbiB3ZXJyb3I7CgogICAgLyoqIFN3aXRjaDogaXMgYW5ub3RhdGlvbiBwcm9jZXNzaW5nIHJlcXVlc3RlZCBleHBsaWNpdGx5IHZpYQogICAgICogQ29tcGlsYXRpb25UYXNrLnNldFByb2Nlc3NvcnM/CiAgICAgKi8KICAgIHByb3RlY3RlZCBib29sZWFuIGV4cGxpY2l0QW5ub3RhdGlvblByb2Nlc3NpbmdSZXF1ZXN0ZWQgPSBmYWxzZTsKCiAgICAvKioKICAgICAqIFRoZSBwb2xpY3kgZm9yIHRoZSBvcmRlciBpbiB3aGljaCB0byBwZXJmb3JtIHRoZSBjb21waWxhdGlvbgogICAgICovCiAgICBwcm90ZWN0ZWQgQ29tcGlsZVBvbGljeSBjb21waWxlUG9saWN5OwoKICAgIC8qKgogICAgICogVGhlIHBvbGljeSBmb3Igd2hhdCB0byBkbyB3aXRoIGltcGxpY2l0bHkgcmVhZCBzb3VyY2UgZmlsZXMKICAgICAqLwogICAgcHJvdGVjdGVkIEltcGxpY2l0U291cmNlUG9saWN5IGltcGxpY2l0U291cmNlUG9saWN5OwoKICAgIC8qKgogICAgICogUmVwb3J0IGFjdGl2aXR5IHJlbGF0ZWQgdG8gY29tcGlsZVBvbGljeQogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiB2ZXJib3NlQ29tcGlsZVBvbGljeTsKCiAgICAvKioKICAgICAqIFBvbGljeSBvZiBob3cgZmFyIHRvIGNvbnRpbnVlIGNvbXBpbGF0aW9uIGFmdGVyIGVycm9ycyBoYXZlIG9jY3VycmVkLgogICAgICogU2V0IHRoaXMgdG8gbWluaW11bSBDb21waWxlU3RhdGUgKElOSVQpIHRvIHN0b3AgYXMgc29vbiBhcyBwb3NzaWJsZQogICAgICogYWZ0ZXIgZXJyb3JzLgogICAgICovCiAgICBwdWJsaWMgQ29tcGlsZVN0YXRlIHNob3VsZFN0b3BQb2xpY3lJZkVycm9yOwoKICAgIC8qKgogICAgICogUG9saWN5IG9mIGhvdyBmYXIgdG8gY29udGludWUgY29tcGlsYXRpb24gd2hlbiBubyBlcnJvcnMgaGF2ZSBvY2N1cnJlZC4KICAgICAqIFNldCB0aGlzIHRvIG1heGltdW0gQ29tcGlsZVN0YXRlIChHRU5FUkFURSkgdG8gcGVyZm9ybSBmdWxsIGNvbXBpbGF0aW9uLgogICAgICogU2V0IHRoaXMgbG93ZXIgdG8gcGVyZm9ybSBwYXJ0aWFsIGNvbXBpbGF0aW9uLCBzdWNoIGFzIC1wcm9jOm9ubHkuCiAgICAgKi8KICAgIHB1YmxpYyBDb21waWxlU3RhdGUgc2hvdWxkU3RvcFBvbGljeUlmTm9FcnJvcjsKCiAgICAvKiogQSBxdWV1ZSBvZiBhbGwgYXMgeWV0IHVuYXR0cmlidXRlZCBjbGFzc2VzLgogICAgICovCiAgICBwdWJsaWMgVG9kbyB0b2RvOwoKICAgIC8qKiBBIGxpc3Qgb2YgaXRlbXMgdG8gYmUgY2xvc2VkIHdoZW4gdGhlIGNvbXBpbGF0aW9uIGlzIGNvbXBsZXRlLgogICAgICovCiAgICBwdWJsaWMgTGlzdDxDbG9zZWFibGU+IGNsb3NlYWJsZXMgPSBMaXN0Lm5pbCgpOwoKICAgIC8qKiBUaGUgc2V0IG9mIGN1cnJlbnRseSBjb21waWxlZCBpbnB1dGZpbGVzLCBuZWVkZWQgdG8gZW5zdXJlCiAgICAgKiAgd2UgZG9uJ3QgYWNjaWRlbnRhbGx5IG92ZXJ3cml0ZSBhbiBpbnB1dCBmaWxlIHdoZW4gLXMgaXMgc2V0LgogICAgICogIGluaXRpYWxpemVkIGJ5IGBjb21waWxlJy4KICAgICAqLwogICAgcHJvdGVjdGVkIFNldDxKYXZhRmlsZU9iamVjdD4gaW5wdXRGaWxlcyA9IG5ldyBIYXNoU2V0PD4oKTsKCiAgICAvKiogVXNlZCBieSB0aGUgcmVzb2x2ZUJpbmFyeU5hbWVPcklkZW50IHRvIHNheSB0aGF0IHRoZSBnaXZlbiB0eXBlIGNhbm5vdCBiZSBmb3VuZCwgYW5kIHRoYXQKICAgICAqICBhbiBlcnJvciBoYXMgYWxyZWFkeSBiZWVuIHByb2R1Y2VkIGFib3V0IHRoYXQuCiAgICAgKi8KICAgIHByaXZhdGUgZmluYWwgU3ltYm9sIHNpbGVudEZhaWw7CgogICAgcHJvdGVjdGVkIGJvb2xlYW4gc2hvdWxkU3RvcChDb21waWxlU3RhdGUgY3MpIHsKICAgICAgICBDb21waWxlU3RhdGUgc2hvdWxkU3RvcFBvbGljeSA9IChlcnJvckNvdW50KCkgPiAwIHx8IHVucmVjb3ZlcmFibGVFcnJvcigpKQogICAgICAgICAgICA/IHNob3VsZFN0b3BQb2xpY3lJZkVycm9yCiAgICAgICAgICAgIDogc2hvdWxkU3RvcFBvbGljeUlmTm9FcnJvcjsKICAgICAgICByZXR1cm4gY3MuaXNBZnRlcihzaG91bGRTdG9wUG9saWN5KTsKICAgIH0KCiAgICAvKiogVGhlIG51bWJlciBvZiBlcnJvcnMgcmVwb3J0ZWQgc28gZmFyLgogICAgICovCiAgICBwdWJsaWMgaW50IGVycm9yQ291bnQoKSB7CiAgICAgICAgaWYgKHdlcnJvciAmJiBsb2cubmVycm9ycyA9PSAwICYmIGxvZy5ud2FybmluZ3MgPiAwKSB7CiAgICAgICAgICAgIGxvZy5lcnJvcigid2FybmluZ3MuYW5kLndlcnJvciIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbG9nLm5lcnJvcnM7CiAgICB9CgogICAgcHJvdGVjdGVkIGZpbmFsIDxUPiBRdWV1ZTxUPiBzdG9wSWZFcnJvcihDb21waWxlU3RhdGUgY3MsIFF1ZXVlPFQ+IHF1ZXVlKSB7CiAgICAgICAgcmV0dXJuIHNob3VsZFN0b3AoY3MpID8gbmV3IExpc3RCdWZmZXI8VD4oKSA6IHF1ZXVlOwogICAgfQoKICAgIHByb3RlY3RlZCBmaW5hbCA8VD4gTGlzdDxUPiBzdG9wSWZFcnJvcihDb21waWxlU3RhdGUgY3MsIExpc3Q8VD4gbGlzdCkgewogICAgICAgIHJldHVybiBzaG91bGRTdG9wKGNzKSA/IExpc3QubmlsKCkgOiBsaXN0OwogICAgfQoKICAgIC8qKiBUaGUgbnVtYmVyIG9mIHdhcm5pbmdzIHJlcG9ydGVkIHNvIGZhci4KICAgICAqLwogICAgcHVibGljIGludCB3YXJuaW5nQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGxvZy5ud2FybmluZ3M7CiAgICB9CgogICAgLyoqIFRyeSB0byBvcGVuIGlucHV0IHN0cmVhbSB3aXRoIGdpdmVuIG5hbWUuCiAgICAgKiAgUmVwb3J0IGFuIGVycm9yIGlmIHRoaXMgZmFpbHMuCiAgICAgKiAgQHBhcmFtIGZpbGVuYW1lICAgVGhlIGZpbGUgbmFtZSBvZiB0aGUgaW5wdXQgc3RyZWFtIHRvIGJlIG9wZW5lZC4KICAgICAqLwogICAgcHVibGljIENoYXJTZXF1ZW5jZSByZWFkU291cmNlKEphdmFGaWxlT2JqZWN0IGZpbGVuYW1lKSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgaW5wdXRGaWxlcy5hZGQoZmlsZW5hbWUpOwogICAgICAgICAgICByZXR1cm4gZmlsZW5hbWUuZ2V0Q2hhckNvbnRlbnQoZmFsc2UpOwogICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgbG9nLmVycm9yKCJlcnJvci5yZWFkaW5nLmZpbGUiLCBmaWxlbmFtZSwgSmF2YWNGaWxlTWFuYWdlci5nZXRNZXNzYWdlKGUpKTsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgfQoKICAgIC8qKiBQYXJzZSBjb250ZW50cyBvZiBpbnB1dCBzdHJlYW0uCiAgICAgKiAgQHBhcmFtIGZpbGVuYW1lICAgICBUaGUgbmFtZSBvZiB0aGUgZmlsZSBmcm9tIHdoaWNoIGlucHV0IHN0cmVhbSBjb21lcy4KICAgICAqICBAcGFyYW0gY29udGVudCAgICAgIFRoZSBjaGFyYWN0ZXJzIHRvIGJlIHBhcnNlZC4KICAgICAqLwogICAgcHJvdGVjdGVkIEpDQ29tcGlsYXRpb25Vbml0IHBhcnNlKEphdmFGaWxlT2JqZWN0IGZpbGVuYW1lLCBDaGFyU2VxdWVuY2UgY29udGVudCkgewogICAgICAgIGxvbmcgbXNlYyA9IG5vdygpOwogICAgICAgIEpDQ29tcGlsYXRpb25Vbml0IHRyZWUgPSBtYWtlLlRvcExldmVsKExpc3QubmlsKCkpOwogICAgICAgIGlmIChjb250ZW50ICE9IG51bGwpIHsKICAgICAgICAgICAgaWYgKHZlcmJvc2UpIHsKICAgICAgICAgICAgICAgIGxvZy5wcmludFZlcmJvc2UoInBhcnNpbmcuc3RhcnRlZCIsIGZpbGVuYW1lKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoIXRhc2tMaXN0ZW5lci5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICAgIFRhc2tFdmVudCBlID0gbmV3IFRhc2tFdmVudChUYXNrRXZlbnQuS2luZC5QQVJTRSwgZmlsZW5hbWUpOwogICAgICAgICAgICAgICAgdGFza0xpc3RlbmVyLnN0YXJ0ZWQoZSk7CiAgICAgICAgICAgICAgICBrZWVwQ29tbWVudHMgPSB0cnVlOwogICAgICAgICAgICAgICAgZ2VuRW5kUG9zID0gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBQYXJzZXIgcGFyc2VyID0gcGFyc2VyRmFjdG9yeS5uZXdQYXJzZXIoY29udGVudCwga2VlcENvbW1lbnRzKCksIGdlbkVuZFBvcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaW5lRGVidWdJbmZvLCBmaWxlbmFtZS5pc05hbWVDb21wYXRpYmxlKCJtb2R1bGUtaW5mbyIsIEtpbmQuU09VUkNFKSk7CiAgICAgICAgICAgIHRyZWUgPSBwYXJzZXIucGFyc2VDb21waWxhdGlvblVuaXQoKTsKICAgICAgICAgICAgaWYgKHZlcmJvc2UpIHsKICAgICAgICAgICAgICAgIGxvZy5wcmludFZlcmJvc2UoInBhcnNpbmcuZG9uZSIsIExvbmcudG9TdHJpbmcoZWxhcHNlZChtc2VjKSkpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICB0cmVlLnNvdXJjZWZpbGUgPSBmaWxlbmFtZTsKCiAgICAgICAgaWYgKGNvbnRlbnQgIT0gbnVsbCAmJiAhdGFza0xpc3RlbmVyLmlzRW1wdHkoKSkgewogICAgICAgICAgICBUYXNrRXZlbnQgZSA9IG5ldyBUYXNrRXZlbnQoVGFza0V2ZW50LktpbmQuUEFSU0UsIHRyZWUpOwogICAgICAgICAgICB0YXNrTGlzdGVuZXIuZmluaXNoZWQoZSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gdHJlZTsKICAgIH0KICAgIC8vIHdoZXJlCiAgICAgICAgcHVibGljIGJvb2xlYW4ga2VlcENvbW1lbnRzID0gZmFsc2U7CiAgICAgICAgcHJvdGVjdGVkIGJvb2xlYW4ga2VlcENvbW1lbnRzKCkgewogICAgICAgICAgICByZXR1cm4ga2VlcENvbW1lbnRzIHx8IHNvdXJjZU91dHB1dDsKICAgICAgICB9CgoKICAgIC8qKiBQYXJzZSBjb250ZW50cyBvZiBmaWxlLgogICAgICogIEBwYXJhbSBmaWxlbmFtZSAgICAgVGhlIG5hbWUgb2YgdGhlIGZpbGUgdG8gYmUgcGFyc2VkLgogICAgICovCiAgICBARGVwcmVjYXRlZAogICAgcHVibGljIEpDVHJlZS5KQ0NvbXBpbGF0aW9uVW5pdCBwYXJzZShTdHJpbmcgZmlsZW5hbWUpIHsKICAgICAgICBKYXZhY0ZpbGVNYW5hZ2VyIGZtID0gKEphdmFjRmlsZU1hbmFnZXIpZmlsZU1hbmFnZXI7CiAgICAgICAgcmV0dXJuIHBhcnNlKGZtLmdldEphdmFGaWxlT2JqZWN0c0Zyb21TdHJpbmdzKExpc3Qub2YoZmlsZW5hbWUpKS5pdGVyYXRvcigpLm5leHQoKSk7CiAgICB9CgogICAgLyoqIFBhcnNlIGNvbnRlbnRzIG9mIGZpbGUuCiAgICAgKiAgQHBhcmFtIGZpbGVuYW1lICAgICBUaGUgbmFtZSBvZiB0aGUgZmlsZSB0byBiZSBwYXJzZWQuCiAgICAgKi8KICAgIHB1YmxpYyBKQ1RyZWUuSkNDb21waWxhdGlvblVuaXQgcGFyc2UoSmF2YUZpbGVPYmplY3QgZmlsZW5hbWUpIHsKICAgICAgICBKYXZhRmlsZU9iamVjdCBwcmV2ID0gbG9nLnVzZVNvdXJjZShmaWxlbmFtZSk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgSkNUcmVlLkpDQ29tcGlsYXRpb25Vbml0IHQgPSBwYXJzZShmaWxlbmFtZSwgcmVhZFNvdXJjZShmaWxlbmFtZSkpOwogICAgICAgICAgICBpZiAodC5lbmRQb3NpdGlvbnMgIT0gbnVsbCkKICAgICAgICAgICAgICAgIGxvZy5zZXRFbmRQb3NUYWJsZShmaWxlbmFtZSwgdC5lbmRQb3NpdGlvbnMpOwogICAgICAgICAgICByZXR1cm4gdDsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICBsb2cudXNlU291cmNlKHByZXYpOwogICAgICAgIH0KICAgIH0KCiAgICAvKiogUmVzb2x2ZSBhbiBpZGVudGlmaWVyIHdoaWNoIG1heSBiZSB0aGUgYmluYXJ5IG5hbWUgb2YgYSBjbGFzcyBvcgogICAgICogdGhlIEphdmEgbmFtZSBvZiBhIGNsYXNzIG9yIHBhY2thZ2UuCiAgICAgKiBAcGFyYW0gbmFtZSAgICAgIFRoZSBuYW1lIHRvIHJlc29sdmUKICAgICAqLwogICAgcHVibGljIFN5bWJvbCByZXNvbHZlQmluYXJ5TmFtZU9ySWRlbnQoU3RyaW5nIG5hbWUpIHsKICAgICAgICBNb2R1bGVTeW1ib2wgbXN5bTsKICAgICAgICBTdHJpbmcgdHlwZU5hbWU7CiAgICAgICAgaW50IHNlcCA9IG5hbWUuaW5kZXhPZignLycpOwogICAgICAgIGlmIChzZXAgPT0gLTEpIHsKICAgICAgICAgICAgbXN5bSA9IG1vZHVsZXMuZ2V0RGVmYXVsdE1vZHVsZSgpOwogICAgICAgICAgICB0eXBlTmFtZSA9IG5hbWU7CiAgICAgICAgfSBlbHNlIGlmIChzb3VyY2UuYWxsb3dNb2R1bGVzKCkpIHsKICAgICAgICAgICAgTmFtZSBtb2ROYW1lID0gbmFtZXMuZnJvbVN0cmluZyhuYW1lLnN1YnN0cmluZygwLCBzZXApKTsKCiAgICAgICAgICAgIG1zeW0gPSBtb2R1bGVGaW5kZXIuZmluZE1vZHVsZShtb2ROYW1lKTsKICAgICAgICAgICAgdHlwZU5hbWUgPSBuYW1lLnN1YnN0cmluZyhzZXAgKyAxKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBsb2cuZXJyb3IoRXJyb3JzLkludmFsaWRNb2R1bGVTcGVjaWZpZXIobmFtZSkpOwogICAgICAgICAgICByZXR1cm4gc2lsZW50RmFpbDsKICAgICAgICB9CgogICAgICAgIHJldHVybiByZXNvbHZlQmluYXJ5TmFtZU9ySWRlbnQobXN5bSwgdHlwZU5hbWUpOwogICAgfQoKICAgIC8qKiBSZXNvbHZlIGFuIGlkZW50aWZpZXIgd2hpY2ggbWF5IGJlIHRoZSBiaW5hcnkgbmFtZSBvZiBhIGNsYXNzIG9yCiAgICAgKiB0aGUgSmF2YSBuYW1lIG9mIGEgY2xhc3Mgb3IgcGFja2FnZS4KICAgICAqIEBwYXJhbSBtc3ltICAgICAgVGhlIG1vZHVsZSBpbiB3aGljaCB0aGUgc2VhcmNoIHNob3VsZCBiZSBwZXJmb3JtZWQKICAgICAqIEBwYXJhbSBuYW1lICAgICAgVGhlIG5hbWUgdG8gcmVzb2x2ZQogICAgICovCiAgICBwdWJsaWMgU3ltYm9sIHJlc29sdmVCaW5hcnlOYW1lT3JJZGVudChNb2R1bGVTeW1ib2wgbXN5bSwgU3RyaW5nIG5hbWUpIHsKICAgICAgICB0cnkgewogICAgICAgICAgICBOYW1lIGZsYXRuYW1lID0gbmFtZXMuZnJvbVN0cmluZyhuYW1lLnJlcGxhY2UoIi8iLCAiLiIpKTsKICAgICAgICAgICAgcmV0dXJuIGZpbmRlci5sb2FkQ2xhc3MobXN5bSwgZmxhdG5hbWUpOwogICAgICAgIH0gY2F0Y2ggKENvbXBsZXRpb25GYWlsdXJlIGlnbm9yZSkgewogICAgICAgICAgICByZXR1cm4gcmVzb2x2ZUlkZW50KG1zeW0sIG5hbWUpOwogICAgICAgIH0KICAgIH0KCiAgICAvKiogUmVzb2x2ZSBhbiBpZGVudGlmaWVyLgogICAgICogQHBhcmFtIG1zeW0gICAgICBUaGUgbW9kdWxlIGluIHdoaWNoIHRoZSBzZWFyY2ggc2hvdWxkIGJlIHBlcmZvcm1lZAogICAgICogQHBhcmFtIG5hbWUgICAgICBUaGUgaWRlbnRpZmllciB0byByZXNvbHZlCiAgICAgKi8KICAgIHB1YmxpYyBTeW1ib2wgcmVzb2x2ZUlkZW50KE1vZHVsZVN5bWJvbCBtc3ltLCBTdHJpbmcgbmFtZSkgewogICAgICAgIGlmIChuYW1lLmVxdWFscygiIikpCiAgICAgICAgICAgIHJldHVybiBzeW1zLmVyclN5bWJvbDsKICAgICAgICBKYXZhRmlsZU9iamVjdCBwcmV2ID0gbG9nLnVzZVNvdXJjZShudWxsKTsKICAgICAgICB0cnkgewogICAgICAgICAgICBKQ0V4cHJlc3Npb24gdHJlZSA9IG51bGw7CiAgICAgICAgICAgIGZvciAoU3RyaW5nIHMgOiBuYW1lLnNwbGl0KCJcXC4iLCAtMSkpIHsKICAgICAgICAgICAgICAgIGlmICghU291cmNlVmVyc2lvbi5pc0lkZW50aWZpZXIocykpIC8vIFRPRE86IGNoZWNrIGZvciBrZXl3b3JkcwogICAgICAgICAgICAgICAgICAgIHJldHVybiBzeW1zLmVyclN5bWJvbDsKICAgICAgICAgICAgICAgIHRyZWUgPSAodHJlZSA9PSBudWxsKSA/IG1ha2UuSWRlbnQobmFtZXMuZnJvbVN0cmluZyhzKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IG1ha2UuU2VsZWN0KHRyZWUsIG5hbWVzLmZyb21TdHJpbmcocykpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIEpDQ29tcGlsYXRpb25Vbml0IHRvcGxldmVsID0KICAgICAgICAgICAgICAgIG1ha2UuVG9wTGV2ZWwoTGlzdC5uaWwoKSk7CiAgICAgICAgICAgIHRvcGxldmVsLm1vZGxlID0gbXN5bTsKICAgICAgICAgICAgdG9wbGV2ZWwucGFja2dlID0gbXN5bS51bm5hbWVkUGFja2FnZTsKICAgICAgICAgICAgcmV0dXJuIGF0dHIuYXR0cmliSWRlbnQodHJlZSwgdG9wbGV2ZWwpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgIGxvZy51c2VTb3VyY2UocHJldik7CiAgICAgICAgfQogICAgfQoKICAgIC8qKiBHZW5lcmF0ZSBjb2RlIGFuZCBlbWl0IGEgY2xhc3MgZmlsZSBmb3IgYSBnaXZlbiBjbGFzcwogICAgICogIEBwYXJhbSBlbnYgICAgVGhlIGF0dHJpYnV0aW9uIGVudmlyb25tZW50IG9mIHRoZSBvdXRlcm1vc3QgY2xhc3MKICAgICAqICAgICAgICAgICAgICAgIGNvbnRhaW5pbmcgdGhpcyBjbGFzcy4KICAgICAqICBAcGFyYW0gY2RlZiAgIFRoZSBjbGFzcyBkZWZpbml0aW9uIGZyb20gd2hpY2ggY29kZSBpcyBnZW5lcmF0ZWQuCiAgICAgKi8KICAgIEphdmFGaWxlT2JqZWN0IGdlbkNvZGUoRW52PEF0dHJDb250ZXh0PiBlbnYsIEpDQ2xhc3NEZWNsIGNkZWYpIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgaWYgKGdlbi5nZW5DbGFzcyhlbnYsIGNkZWYpICYmIChlcnJvckNvdW50KCkgPT0gMCkpCiAgICAgICAgICAgICAgICByZXR1cm4gd3JpdGVyLndyaXRlQ2xhc3MoY2RlZi5zeW0pOwogICAgICAgIH0gY2F0Y2ggKENsYXNzV3JpdGVyLlBvb2xPdmVyZmxvdyBleCkgewogICAgICAgICAgICBsb2cuZXJyb3IoY2RlZi5wb3MoKSwgImxpbWl0LnBvb2wiKTsKICAgICAgICB9IGNhdGNoIChDbGFzc1dyaXRlci5TdHJpbmdPdmVyZmxvdyBleCkgewogICAgICAgICAgICBsb2cuZXJyb3IoY2RlZi5wb3MoKSwgImxpbWl0LnN0cmluZy5vdmVyZmxvdyIsCiAgICAgICAgICAgICAgICAgICAgICBleC52YWx1ZS5zdWJzdHJpbmcoMCwgMjApKTsKICAgICAgICB9IGNhdGNoIChDb21wbGV0aW9uRmFpbHVyZSBleCkgewogICAgICAgICAgICBjaGsuY29tcGxldGlvbkVycm9yKGNkZWYucG9zKCksIGV4KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgLyoqIEVtaXQgcGxhaW4gSmF2YSBzb3VyY2UgZm9yIGEgY2xhc3MuCiAgICAgKiAgQHBhcmFtIGVudiAgICBUaGUgYXR0cmlidXRpb24gZW52aXJvbm1lbnQgb2YgdGhlIG91dGVybW9zdCBjbGFzcwogICAgICogICAgICAgICAgICAgICAgY29udGFpbmluZyB0aGlzIGNsYXNzLgogICAgICogIEBwYXJhbSBjZGVmICAgVGhlIGNsYXNzIGRlZmluaXRpb24gdG8gYmUgcHJpbnRlZC4KICAgICAqLwogICAgSmF2YUZpbGVPYmplY3QgcHJpbnRTb3VyY2UoRW52PEF0dHJDb250ZXh0PiBlbnYsIEpDQ2xhc3NEZWNsIGNkZWYpIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgSmF2YUZpbGVPYmplY3Qgb3V0RmlsZQogICAgICAgICAgID0gZmlsZU1hbmFnZXIuZ2V0SmF2YUZpbGVGb3JPdXRwdXQoQ0xBU1NfT1VUUFVULAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNkZWYuc3ltLmZsYXRuYW1lLnRvU3RyaW5nKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSmF2YUZpbGVPYmplY3QuS2luZC5TT1VSQ0UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCk7CiAgICAgICAgaWYgKGlucHV0RmlsZXMuY29udGFpbnMob3V0RmlsZSkpIHsKICAgICAgICAgICAgbG9nLmVycm9yKGNkZWYucG9zKCksICJzb3VyY2UuY2FudC5vdmVyd3JpdGUuaW5wdXQuZmlsZSIsIG91dEZpbGUpOwogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB0cnkgKEJ1ZmZlcmVkV3JpdGVyIG91dCA9IG5ldyBCdWZmZXJlZFdyaXRlcihvdXRGaWxlLm9wZW5Xcml0ZXIoKSkpIHsKICAgICAgICAgICAgICAgIG5ldyBQcmV0dHkob3V0LCB0cnVlKS5wcmludFVuaXQoZW52LnRvcGxldmVsLCBjZGVmKTsKICAgICAgICAgICAgICAgIGlmICh2ZXJib3NlKQogICAgICAgICAgICAgICAgICAgIGxvZy5wcmludFZlcmJvc2UoIndyb3RlLmZpbGUiLCBvdXRGaWxlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gb3V0RmlsZTsKICAgICAgICB9CiAgICB9CgogICAgLyoqIENvbXBpbGUgYSBzb3VyY2UgZmlsZSB0aGF0IGhhcyBiZWVuIGFjY2Vzc2VkIGJ5IHRoZSBjbGFzcyBmaW5kZXIuCiAgICAgKiAgQHBhcmFtIGMgICAgICAgICAgVGhlIGNsYXNzIHRoZSBzb3VyY2UgZmlsZSBvZiB3aGljaCBuZWVkcyB0byBiZSBjb21waWxlZC4KICAgICAqLwogICAgcHJpdmF0ZSB2b2lkIHJlYWRTb3VyY2VGaWxlKENsYXNzU3ltYm9sIGMpIHRocm93cyBDb21wbGV0aW9uRmFpbHVyZSB7CiAgICAgICAgcmVhZFNvdXJjZUZpbGUobnVsbCwgYyk7CiAgICB9CgogICAgcHJpdmF0ZSBKQ1RyZWUuSkNDb21waWxhdGlvblVuaXQgcGFyc2VJbXBsaWNpdEZpbGUoSmF2YUZpbGVPYmplY3QgZmlsZW5hbWUpIHsKICAgICAgICBKYXZhRmlsZU9iamVjdCBwcmV2ID0gbG9nLnVzZVNvdXJjZShmaWxlbmFtZSk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgSkNUcmVlLkpDQ29tcGlsYXRpb25Vbml0IHQgPSBwYXJzZShmaWxlbmFtZSwgZmlsZW5hbWUuZ2V0Q2hhckNvbnRlbnQoZmFsc2UpKTsKICAgICAgICAgICAgcmV0dXJuIHQ7CiAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICBsb2cuZXJyb3IoImVycm9yLnJlYWRpbmcuZmlsZSIsIGZpbGVuYW1lLCBKYXZhY0ZpbGVNYW5hZ2VyLmdldE1lc3NhZ2UoZSkpOwogICAgICAgICAgICByZXR1cm4gbWFrZS5Ub3BMZXZlbChMaXN0Lm5pbCgpKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICBsb2cudXNlU291cmNlKHByZXYpOwogICAgICAgIH0KICAgIH0KCiAgICAvKiogQ29tcGlsZSBhIENsYXNzU3ltYm9sIGZyb20gc291cmNlLCBvcHRpb25hbGx5IHVzaW5nIHRoZSBnaXZlbiBjb21waWxhdGlvbiB1bml0IGFzCiAgICAgKiAgdGhlIHNvdXJjZSB0cmVlLgogICAgICogIEBwYXJhbSB0cmVlIHRoZSBjb21waWxhdGlvbiB1bml0IGluIHdoaWNoIHRoZSBnaXZlbiBDbGFzc1N5bWJvbCByZXNpZGVzLAogICAgICogICAgICAgICAgICAgIG9yIG51bGwgaWYgc2hvdWxkIGJlIHBhcnNlZCBmcm9tIHNvdXJjZQogICAgICogIEBwYXJhbSBjICAgIHRoZSBDbGFzc1N5bWJvbCB0byBjb21wbGV0ZQogICAgICovCiAgICBwdWJsaWMgdm9pZCByZWFkU291cmNlRmlsZShKQ0NvbXBpbGF0aW9uVW5pdCB0cmVlLCBDbGFzc1N5bWJvbCBjKSB0aHJvd3MgQ29tcGxldGlvbkZhaWx1cmUgewogICAgICAgIGlmIChjb21wbGV0aW9uRmFpbHVyZU5hbWUgPT0gYy5mdWxsbmFtZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgQ29tcGxldGlvbkZhaWx1cmUoYywgInVzZXItc2VsZWN0ZWQgY29tcGxldGlvbiBmYWlsdXJlIGJ5IGNsYXNzIG5hbWUiKTsKICAgICAgICB9CgogICAgICAgIGlmICh0cmVlID09IG51bGwpIHsKICAgICAgICAgICAgdHJlZSA9IHBhcnNlSW1wbGljaXRGaWxlKGMuY2xhc3NmaWxlKTsKICAgICAgICB9CgogICAgICAgIHJlYWRTb3VyY2VGaWxlKHRyZWUsIGMsIGN1dCAtPiBjKTsKICAgIH0KCiAgICBwcml2YXRlIENsYXNzU3ltYm9sIHJlYWRTb3VyY2VGaWxlKEpDQ29tcGlsYXRpb25Vbml0IHRyZWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENsYXNzU3ltYm9sIGV4cGVjdGVkU3ltYm9sLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGdW5jdGlvbjxKQ0NvbXBpbGF0aW9uVW5pdCwgQ2xhc3NTeW1ib2w+IHN5bWJvbEdldHRlcikKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBDb21wbGV0aW9uRmFpbHVyZSB7CiAgICAgICAgQXNzZXJ0LmNoZWNrTm9uTnVsbCh0cmVlKTsKCiAgICAgICAgaWYgKCF0YXNrTGlzdGVuZXIuaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIFRhc2tFdmVudCBlID0gbmV3IFRhc2tFdmVudChUYXNrRXZlbnQuS2luZC5FTlRFUiwgdHJlZSk7CiAgICAgICAgICAgIHRhc2tMaXN0ZW5lci5zdGFydGVkKGUpOwogICAgICAgIH0KCiAgICAgICAgLy8gUHJvY2VzcyBtb2R1bGUgZGVjbGFyYXRpb25zLgogICAgICAgIC8vIElmIG1vZHVsZSByZXNvbHV0aW9uIGZhaWxzLCBpZ25vcmUgdHJlZXMsIGFuZCBpZiB0cnlpbmcgdG8KICAgICAgICAvLyBjb21wbGV0ZSBhIHNwZWNpZmljIHN5bWJvbCwgdGhyb3cgQ29tcGxldGlvbkZhaWx1cmUuCiAgICAgICAgLy8gTm90ZSB0aGF0IGlmIG1vZHVsZSByZXNvbHV0aW9uIGZhaWxlZCwgd2UgbWF5IG5vdCBldmVuCiAgICAgICAgLy8gaGF2ZSBlbm91Z2ggbW9kdWxlcyBhdmFpbGFibGUgdG8gYWNjZXNzIGphdmEubGFuZywgYW5kCiAgICAgICAgLy8gc28gcmlzayBnZXR0aW5nIEZhdGFsRXJyb3IoIm5vLmphdmEubGFuZyIpIGZyb20gTWVtYmVyRW50ZXIuCiAgICAgICAgaWYgKCFtb2R1bGVzLmVudGVyKExpc3Qub2YodHJlZSksIGV4cGVjdGVkU3ltYm9sKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgQ29tcGxldGlvbkZhaWx1cmUoc3ltYm9sR2V0dGVyLmFwcGx5KHRyZWUpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlhZ3MuZnJhZ21lbnQoImNhbnQucmVzb2x2ZS5tb2R1bGVzIikpOwogICAgICAgIH0KCiAgICAgICAgZW50ZXIuY29tcGxldGUoTGlzdC5vZih0cmVlKSwgZXhwZWN0ZWRTeW1ib2wpOwoKICAgICAgICBpZiAoIXRhc2tMaXN0ZW5lci5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgVGFza0V2ZW50IGUgPSBuZXcgVGFza0V2ZW50KFRhc2tFdmVudC5LaW5kLkVOVEVSLCB0cmVlKTsKICAgICAgICAgICAgdGFza0xpc3RlbmVyLmZpbmlzaGVkKGUpOwogICAgICAgIH0KCiAgICAgICAgQ2xhc3NTeW1ib2wgc3ltID0gc3ltYm9sR2V0dGVyLmFwcGx5KHRyZWUpOwogICAgICAgIGlmIChzeW0gPT0gbnVsbCB8fCBlbnRlci5nZXRFbnYoc3ltKSA9PSBudWxsKSB7CiAgICAgICAgICAgIGJvb2xlYW4gaXNQa2dJbmZvID0KICAgICAgICAgICAgICAgIHRyZWUuc291cmNlZmlsZS5pc05hbWVDb21wYXRpYmxlKCJwYWNrYWdlLWluZm8iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSmF2YUZpbGVPYmplY3QuS2luZC5TT1VSQ0UpOwogICAgICAgICAgICBib29sZWFuIGlzTW9kdWxlSW5mbyA9CiAgICAgICAgICAgICAgICB0cmVlLnNvdXJjZWZpbGUuaXNOYW1lQ29tcGF0aWJsZSgibW9kdWxlLWluZm8iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSmF2YUZpbGVPYmplY3QuS2luZC5TT1VSQ0UpOwogICAgICAgICAgICBpZiAoaXNNb2R1bGVJbmZvKSB7CiAgICAgICAgICAgICAgICBpZiAoZW50ZXIuZ2V0RW52KHRyZWUubW9kbGUpID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICBKQ0RpYWdub3N0aWMgZGlhZyA9CiAgICAgICAgICAgICAgICAgICAgICAgIGRpYWdGYWN0b3J5LmZyYWdtZW50KCJmaWxlLmRvZXMubm90LmNvbnRhaW4ubW9kdWxlIik7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IENsYXNzRmluZGVyLkJhZENsYXNzRmlsZShzeW0sIHRyZWUuc291cmNlZmlsZSwgZGlhZywgZGlhZ0ZhY3RvcnkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgaWYgKGlzUGtnSW5mbykgewogICAgICAgICAgICAgICAgaWYgKGVudGVyLmdldEVudih0cmVlLnBhY2tnZSkgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIEpDRGlhZ25vc3RpYyBkaWFnID0KICAgICAgICAgICAgICAgICAgICAgICAgZGlhZ0ZhY3RvcnkuZnJhZ21lbnQoImZpbGUuZG9lcy5ub3QuY29udGFpbi5wYWNrYWdlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5bS5sb2NhdGlvbigpKTsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQ2xhc3NGaW5kZXIuQmFkQ2xhc3NGaWxlKHN5bSwgdHJlZS5zb3VyY2VmaWxlLCBkaWFnLCBkaWFnRmFjdG9yeSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBKQ0RpYWdub3N0aWMgZGlhZyA9CiAgICAgICAgICAgICAgICAgICAgICAgIGRpYWdGYWN0b3J5LmZyYWdtZW50KCJmaWxlLmRvZXNudC5jb250YWluLmNsYXNzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeW0uZ2V0UXVhbGlmaWVkTmFtZSgpKTsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBDbGFzc0ZpbmRlci5CYWRDbGFzc0ZpbGUoc3ltLCB0cmVlLnNvdXJjZWZpbGUsIGRpYWcsIGRpYWdGYWN0b3J5KTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaW1wbGljaXRTb3VyY2VGaWxlc1JlYWQgPSB0cnVlOwoKICAgICAgICByZXR1cm4gc3ltOwogICAgfQoKICAgIC8qKiBUcmFjayB3aGVuIHRoZSBKYXZhQ29tcGlsZXIgaGFzIGJlZW4gdXNlZCB0byBjb21waWxlIHNvbWV0aGluZy4gKi8KICAgIHByaXZhdGUgYm9vbGVhbiBoYXNCZWVuVXNlZCA9IGZhbHNlOwogICAgcHJpdmF0ZSBsb25nIHN0YXJ0X21zZWMgPSAwOwogICAgcHVibGljIGxvbmcgZWxhcHNlZF9tc2VjID0gMDsKCiAgICBwdWJsaWMgdm9pZCBjb21waWxlKExpc3Q8SmF2YUZpbGVPYmplY3Q+IHNvdXJjZUZpbGVPYmplY3QpCiAgICAgICAgdGhyb3dzIFRocm93YWJsZSB7CiAgICAgICAgY29tcGlsZShzb3VyY2VGaWxlT2JqZWN0LCBMaXN0Lm5pbCgpLCBudWxsLCBMaXN0Lm5pbCgpKTsKICAgIH0KCiAgICAvKioKICAgICAqIE1haW4gbWV0aG9kOiBjb21waWxlIGEgbGlzdCBvZiBmaWxlcywgcmV0dXJuIGFsbCBjb21waWxlZCBjbGFzc2VzCiAgICAgKgogICAgICogQHBhcmFtIHNvdXJjZUZpbGVPYmplY3RzIGZpbGUgb2JqZWN0cyB0byBiZSBjb21waWxlZAogICAgICogQHBhcmFtIGNsYXNzbmFtZXMgY2xhc3MgbmFtZXMgdG8gcHJvY2VzcyBmb3IgYW5ub3RhdGlvbnMKICAgICAqIEBwYXJhbSBwcm9jZXNzb3JzIHVzZXIgcHJvdmlkZWQgYW5ub3RhdGlvbiBwcm9jZXNzb3JzIHRvIGJ5cGFzcwogICAgICogZGlzY292ZXJ5LCB7QGNvZGUgbnVsbH0gbWVhbnMgdGhhdCBubyBwcm9jZXNzb3JzIHdlcmUgcHJvdmlkZWQKICAgICAqIEBwYXJhbSBhZGRNb2R1bGVzIGFkZGl0aW9uYWwgcm9vdCBtb2R1bGVzIHRvIGJlIHVzZWQgZHVyaW5nCiAgICAgKiBtb2R1bGUgcmVzb2x1dGlvbi4KICAgICAqLwogICAgcHVibGljIHZvaWQgY29tcGlsZShDb2xsZWN0aW9uPEphdmFGaWxlT2JqZWN0PiBzb3VyY2VGaWxlT2JqZWN0cywKICAgICAgICAgICAgICAgICAgICAgICAgQ29sbGVjdGlvbjxTdHJpbmc+IGNsYXNzbmFtZXMsCiAgICAgICAgICAgICAgICAgICAgICAgIEl0ZXJhYmxlPD8gZXh0ZW5kcyBQcm9jZXNzb3I+IHByb2Nlc3NvcnMsCiAgICAgICAgICAgICAgICAgICAgICAgIENvbGxlY3Rpb248U3RyaW5nPiBhZGRNb2R1bGVzKQogICAgewogICAgICAgIGlmICghdGFza0xpc3RlbmVyLmlzRW1wdHkoKSkgewogICAgICAgICAgICB0YXNrTGlzdGVuZXIuc3RhcnRlZChuZXcgVGFza0V2ZW50KFRhc2tFdmVudC5LaW5kLkNPTVBJTEFUSU9OKSk7CiAgICAgICAgfQoKICAgICAgICBpZiAocHJvY2Vzc29ycyAhPSBudWxsICYmIHByb2Nlc3NvcnMuaXRlcmF0b3IoKS5oYXNOZXh0KCkpCiAgICAgICAgICAgIGV4cGxpY2l0QW5ub3RhdGlvblByb2Nlc3NpbmdSZXF1ZXN0ZWQgPSB0cnVlOwogICAgICAgIC8vIGFzIGEgSmF2YUNvbXBpbGVyIGNhbiBvbmx5IGJlIHVzZWQgb25jZSwgdGhyb3cgYW4gZXhjZXB0aW9uIGlmCiAgICAgICAgLy8gaXQgaGFzIGJlZW4gdXNlZCBiZWZvcmUuCiAgICAgICAgaWYgKGhhc0JlZW5Vc2VkKQogICAgICAgICAgICBjaGVja1JldXNhYmxlKCk7CiAgICAgICAgaGFzQmVlblVzZWQgPSB0cnVlOwoKICAgICAgICAvLyBmb3JjaWJseSBzZXQgdGhlIGVxdWl2YWxlbnQgb2YgLVhsaW50Oi1vcHRpb25zLCBzbyB0aGF0IG5vIGZ1cnRoZXIKICAgICAgICAvLyB3YXJuaW5ncyBhYm91dCBjb21tYW5kIGxpbmUgb3B0aW9ucyBhcmUgZ2VuZXJhdGVkIGZyb20gdGhpcyBwb2ludCBvbgogICAgICAgIG9wdGlvbnMucHV0KFhMSU5UX0NVU1RPTS5wcmltYXJ5TmFtZSArICItIiArIExpbnRDYXRlZ29yeS5PUFRJT05TLm9wdGlvbiwgInRydWUiKTsKICAgICAgICBvcHRpb25zLnJlbW92ZShYTElOVF9DVVNUT00ucHJpbWFyeU5hbWUgKyBMaW50Q2F0ZWdvcnkuT1BUSU9OUy5vcHRpb24pOwoKICAgICAgICBzdGFydF9tc2VjID0gbm93KCk7CgogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGluaXRQcm9jZXNzQW5ub3RhdGlvbnMocHJvY2Vzc29ycywgc291cmNlRmlsZU9iamVjdHMsIGNsYXNzbmFtZXMpOwoKICAgICAgICAgICAgZm9yIChTdHJpbmcgY2xhc3NOYW1lIDogY2xhc3NuYW1lcykgewogICAgICAgICAgICAgICAgaW50IHNlcCA9IGNsYXNzTmFtZS5pbmRleE9mKCcvJyk7CiAgICAgICAgICAgICAgICBpZiAoc2VwICE9IC0xKSB7CiAgICAgICAgICAgICAgICAgICAgbW9kdWxlcy5hZGRFeHRyYUFkZE1vZHVsZXMoY2xhc3NOYW1lLnN1YnN0cmluZygwLCBzZXApKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgZm9yIChTdHJpbmcgbW9kdWxlTmFtZSA6IGFkZE1vZHVsZXMpIHsKICAgICAgICAgICAgICAgIG1vZHVsZXMuYWRkRXh0cmFBZGRNb2R1bGVzKG1vZHVsZU5hbWUpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBUaGVzZSBtZXRob2QgY2FsbHMgbXVzdCBiZSBjaGFpbmVkIHRvIGF2b2lkIG1lbW9yeSBsZWFrcwogICAgICAgICAgICBwcm9jZXNzQW5ub3RhdGlvbnMoCiAgICAgICAgICAgICAgICBlbnRlclRyZWVzKAogICAgICAgICAgICAgICAgICAgICAgICBzdG9wSWZFcnJvcihDb21waWxlU3RhdGUuUEFSU0UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5pdE1vZHVsZXMoc3RvcElmRXJyb3IoQ29tcGlsZVN0YXRlLlBBUlNFLCBwYXJzZUZpbGVzKHNvdXJjZUZpbGVPYmplY3RzKSkpKQogICAgICAgICAgICAgICAgKSwKICAgICAgICAgICAgICAgIGNsYXNzbmFtZXMKICAgICAgICAgICAgKTsKCiAgICAgICAgICAgIC8vIElmIGl0J3Mgc2FmZSB0byBkbyBzbywgc2tpcCBhdHRyIC8gZmxvdyAvIGdlbiBmb3IgaW1wbGljaXQgY2xhc3NlcwogICAgICAgICAgICBpZiAodGFza0xpc3RlbmVyLmlzRW1wdHkoKSAmJgogICAgICAgICAgICAgICAgICAgIGltcGxpY2l0U291cmNlUG9saWN5ID09IEltcGxpY2l0U291cmNlUG9saWN5Lk5PTkUpIHsKICAgICAgICAgICAgICAgIHRvZG8ucmV0YWluRmlsZXMoaW5wdXRGaWxlcyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHN3aXRjaCAoY29tcGlsZVBvbGljeSkgewogICAgICAgICAgICBjYXNlIEFUVFJfT05MWToKICAgICAgICAgICAgICAgIGF0dHJpYnV0ZSh0b2RvKTsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBDSEVDS19PTkxZOgogICAgICAgICAgICAgICAgZmxvdyhhdHRyaWJ1dGUodG9kbykpOwogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIFNJTVBMRToKICAgICAgICAgICAgICAgIGdlbmVyYXRlKGRlc3VnYXIoZmxvdyhhdHRyaWJ1dGUodG9kbykpKSk7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgQllfRklMRTogewogICAgICAgICAgICAgICAgICAgIFF1ZXVlPFF1ZXVlPEVudjxBdHRyQ29udGV4dD4+PiBxID0gdG9kby5ncm91cEJ5RmlsZSgpOwogICAgICAgICAgICAgICAgICAgIHdoaWxlICghcS5pc0VtcHR5KCkgJiYgIXNob3VsZFN0b3AoQ29tcGlsZVN0YXRlLkFUVFIpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGdlbmVyYXRlKGRlc3VnYXIoZmxvdyhhdHRyaWJ1dGUocS5yZW1vdmUoKSkpKSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIEJZX1RPRE86CiAgICAgICAgICAgICAgICB3aGlsZSAoIXRvZG8uaXNFbXB0eSgpKQogICAgICAgICAgICAgICAgICAgIGdlbmVyYXRlKGRlc3VnYXIoZmxvdyhhdHRyaWJ1dGUodG9kby5yZW1vdmUoKSkpKSk7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICBBc3NlcnQuZXJyb3IoInVua25vd24gY29tcGlsZSBwb2xpY3kiKTsKICAgICAgICAgICAgfQogICAgICAgIH0gY2F0Y2ggKEFib3J0IGV4KSB7CiAgICAgICAgICAgIGlmIChkZXZWZXJib3NlKQogICAgICAgICAgICAgICAgZXgucHJpbnRTdGFja1RyYWNlKFN5c3RlbS5lcnIpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgIGlmICh2ZXJib3NlKSB7CiAgICAgICAgICAgICAgICBlbGFwc2VkX21zZWMgPSBlbGFwc2VkKHN0YXJ0X21zZWMpOwogICAgICAgICAgICAgICAgbG9nLnByaW50VmVyYm9zZSgidG90YWwiLCBMb25nLnRvU3RyaW5nKGVsYXBzZWRfbXNlYykpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXBvcnREZWZlcnJlZERpYWdub3N0aWNzKCk7CgogICAgICAgICAgICBpZiAoIWxvZy5oYXNEaWFnbm9zdGljTGlzdGVuZXIoKSkgewogICAgICAgICAgICAgICAgcHJpbnRDb3VudCgiZXJyb3IiLCBlcnJvckNvdW50KCkpOwogICAgICAgICAgICAgICAgcHJpbnRDb3VudCgid2FybiIsIHdhcm5pbmdDb3VudCgpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoIXRhc2tMaXN0ZW5lci5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICAgIHRhc2tMaXN0ZW5lci5maW5pc2hlZChuZXcgVGFza0V2ZW50KFRhc2tFdmVudC5LaW5kLkNPTVBJTEFUSU9OKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY2xvc2UoKTsKICAgICAgICAgICAgaWYgKHByb2NFbnZJbXBsICE9IG51bGwpCiAgICAgICAgICAgICAgICBwcm9jRW52SW1wbC5jbG9zZSgpOwogICAgICAgIH0KICAgIH0KCiAgICBwcm90ZWN0ZWQgdm9pZCBjaGVja1JldXNhYmxlKCkgewogICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigiYXR0ZW1wdCB0byByZXVzZSBKYXZhQ29tcGlsZXIiKTsKICAgIH0KCiAgICAvKioKICAgICAqIFRoZSBsaXN0IG9mIGNsYXNzZXMgZXhwbGljaXRseSBzdXBwbGllZCBvbiB0aGUgY29tbWFuZCBsaW5lIGZvciBjb21waWxhdGlvbi4KICAgICAqIE5vdCBhbHdheXMgcG9wdWxhdGVkLgogICAgICovCiAgICBwcml2YXRlIExpc3Q8SkNDbGFzc0RlY2w+IHJvb3RDbGFzc2VzOwoKICAgIC8qKgogICAgICogUGFyc2VzIGEgbGlzdCBvZiBmaWxlcy4KICAgICAqLwogICBwdWJsaWMgTGlzdDxKQ0NvbXBpbGF0aW9uVW5pdD4gcGFyc2VGaWxlcyhJdGVyYWJsZTxKYXZhRmlsZU9iamVjdD4gZmlsZU9iamVjdHMpIHsKICAgICAgIGlmIChzaG91bGRTdG9wKENvbXBpbGVTdGF0ZS5QQVJTRSkpCiAgICAgICAgICAgcmV0dXJuIExpc3QubmlsKCk7CgogICAgICAgIC8vcGFyc2UgYWxsIGZpbGVzCiAgICAgICAgTGlzdEJ1ZmZlcjxKQ0NvbXBpbGF0aW9uVW5pdD4gdHJlZXMgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgU2V0PEphdmFGaWxlT2JqZWN0PiBmaWxlc1NvRmFyID0gbmV3IEhhc2hTZXQ8PigpOwogICAgICAgIGZvciAoSmF2YUZpbGVPYmplY3QgZmlsZU9iamVjdCA6IGZpbGVPYmplY3RzKSB7CiAgICAgICAgICAgIGlmICghZmlsZXNTb0Zhci5jb250YWlucyhmaWxlT2JqZWN0KSkgewogICAgICAgICAgICAgICAgZmlsZXNTb0Zhci5hZGQoZmlsZU9iamVjdCk7CiAgICAgICAgICAgICAgICB0cmVlcy5hcHBlbmQocGFyc2UoZmlsZU9iamVjdCkpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiB0cmVlcy50b0xpc3QoKTsKICAgIH0KCiAgICAvKioKICAgICAqIEVudGVyIHRoZSBzeW1ib2xzIGZvdW5kIGluIGEgbGlzdCBvZiBwYXJzZSB0cmVlcyBpZiB0aGUgY29tcGlsYXRpb24KICAgICAqIGlzIGV4cGVjdGVkIHRvIHByb2NlZWQgYmV5b25kIGFubm8gcHJvY2Vzc2luZyBpbnRvIGF0dHIuCiAgICAgKiBBcyBhIHNpZGUtZWZmZWN0LCB0aGlzIHB1dHMgZWxlbWVudHMgb24gdGhlICJ0b2RvIiBsaXN0LgogICAgICogQWxzbyBzdG9yZXMgYSBsaXN0IG9mIGFsbCB0b3AgbGV2ZWwgY2xhc3NlcyBpbiByb290Q2xhc3Nlcy4KICAgICAqLwogICAgcHVibGljIExpc3Q8SkNDb21waWxhdGlvblVuaXQ+IGVudGVyVHJlZXNJZk5lZWRlZChMaXN0PEpDQ29tcGlsYXRpb25Vbml0PiByb290cykgewogICAgICAgaWYgKHNob3VsZFN0b3AoQ29tcGlsZVN0YXRlLkFUVFIpKQogICAgICAgICAgIHJldHVybiBMaXN0Lm5pbCgpOwogICAgICAgIHJldHVybiBlbnRlclRyZWVzKGluaXRNb2R1bGVzKHJvb3RzKSk7CiAgICB9CgogICAgcHVibGljIExpc3Q8SkNDb21waWxhdGlvblVuaXQ+IGluaXRNb2R1bGVzKExpc3Q8SkNDb21waWxhdGlvblVuaXQ+IHJvb3RzKSB7CiAgICAgICAgbW9kdWxlcy5pbml0TW9kdWxlcyhyb290cyk7CiAgICAgICAgaWYgKHJvb3RzLmlzRW1wdHkoKSkgewogICAgICAgICAgICBlbnRlckRvbmUoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJvb3RzOwogICAgfQoKICAgIC8qKgogICAgICogRW50ZXIgdGhlIHN5bWJvbHMgZm91bmQgaW4gYSBsaXN0IG9mIHBhcnNlIHRyZWVzLgogICAgICogQXMgYSBzaWRlLWVmZmVjdCwgdGhpcyBwdXRzIGVsZW1lbnRzIG9uIHRoZSAidG9kbyIgbGlzdC4KICAgICAqIEFsc28gc3RvcmVzIGEgbGlzdCBvZiBhbGwgdG9wIGxldmVsIGNsYXNzZXMgaW4gcm9vdENsYXNzZXMuCiAgICAgKi8KICAgIHB1YmxpYyBMaXN0PEpDQ29tcGlsYXRpb25Vbml0PiBlbnRlclRyZWVzKExpc3Q8SkNDb21waWxhdGlvblVuaXQ+IHJvb3RzKSB7CiAgICAgICAgLy9lbnRlciBzeW1ib2xzIGZvciBhbGwgZmlsZXMKICAgICAgICBpZiAoIXRhc2tMaXN0ZW5lci5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgZm9yIChKQ0NvbXBpbGF0aW9uVW5pdCB1bml0OiByb290cykgewogICAgICAgICAgICAgICAgVGFza0V2ZW50IGUgPSBuZXcgVGFza0V2ZW50KFRhc2tFdmVudC5LaW5kLkVOVEVSLCB1bml0KTsKICAgICAgICAgICAgICAgIHRhc2tMaXN0ZW5lci5zdGFydGVkKGUpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBlbnRlci5tYWluKHJvb3RzKTsKCiAgICAgICAgZW50ZXJEb25lKCk7CgogICAgICAgIGlmICghdGFza0xpc3RlbmVyLmlzRW1wdHkoKSkgewogICAgICAgICAgICBmb3IgKEpDQ29tcGlsYXRpb25Vbml0IHVuaXQ6IHJvb3RzKSB7CiAgICAgICAgICAgICAgICBUYXNrRXZlbnQgZSA9IG5ldyBUYXNrRXZlbnQoVGFza0V2ZW50LktpbmQuRU5URVIsIHVuaXQpOwogICAgICAgICAgICAgICAgdGFza0xpc3RlbmVyLmZpbmlzaGVkKGUpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBJZiBnZW5lcmF0aW5nIHNvdXJjZSwgb3IgaWYgdHJhY2tpbmcgcHVibGljIGFwaXMsCiAgICAgICAgLy8gdGhlbiByZW1lbWJlciB0aGUgY2xhc3NlcyBkZWNsYXJlZCBpbgogICAgICAgIC8vIHRoZSBvcmlnaW5hbCBjb21waWxhdGlvbiB1bml0cyBsaXN0ZWQgb24gdGhlIGNvbW1hbmQgbGluZS4KICAgICAgICBpZiAoc291cmNlT3V0cHV0KSB7CiAgICAgICAgICAgIExpc3RCdWZmZXI8SkNDbGFzc0RlY2w+IGNkZWZzID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgICAgICBmb3IgKEpDQ29tcGlsYXRpb25Vbml0IHVuaXQgOiByb290cykgewogICAgICAgICAgICAgICAgZm9yIChMaXN0PEpDVHJlZT4gZGVmcyA9IHVuaXQuZGVmczsKICAgICAgICAgICAgICAgICAgICAgZGVmcy5ub25FbXB0eSgpOwogICAgICAgICAgICAgICAgICAgICBkZWZzID0gZGVmcy50YWlsKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGRlZnMuaGVhZCBpbnN0YW5jZW9mIEpDQ2xhc3NEZWNsKQogICAgICAgICAgICAgICAgICAgICAgICBjZGVmcy5hcHBlbmQoKEpDQ2xhc3NEZWNsKWRlZnMuaGVhZCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcm9vdENsYXNzZXMgPSBjZGVmcy50b0xpc3QoKTsKICAgICAgICB9CgogICAgICAgIC8vIEVuc3VyZSB0aGUgaW5wdXQgZmlsZXMgaGF2ZSBiZWVuIHJlY29yZGVkLiBBbHRob3VnaCB0aGlzIGlzIG5vcm1hbGx5CiAgICAgICAgLy8gZG9uZSBieSByZWFkU291cmNlLCBpdCBtYXkgbm90IGhhdmUgYmVlbiBkb25lIGlmIHRoZSB0cmVlcyB3ZXJlIHJlYWQKICAgICAgICAvLyBpbiBhIHByaW9yIHJvdW5kIG9mIGFubm90YXRpb24gcHJvY2Vzc2luZywgYW5kIHRoZSB0cmVlcyBoYXZlIGJlZW4KICAgICAgICAvLyBjbGVhbmVkIGFuZCBhcmUgYmVpbmcgcmV1c2VkLgogICAgICAgIGZvciAoSkNDb21waWxhdGlvblVuaXQgdW5pdCA6IHJvb3RzKSB7CiAgICAgICAgICAgIGlucHV0RmlsZXMuYWRkKHVuaXQuc291cmNlZmlsZSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gcm9vdHM7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXQgdG8gdHJ1ZSB0byBlbmFibGUgc2tlbGV0b24gYW5ub3RhdGlvbiBwcm9jZXNzaW5nIGNvZGUuCiAgICAgKiBDdXJyZW50bHksIHdlIGFzc3VtZSB0aGlzIHZhcmlhYmxlIHdpbGwgYmUgcmVwbGFjZWQgbW9yZQogICAgICogYWR2YW5jZWQgbG9naWMgdG8gZmlndXJlIG91dCBpZiBhbm5vdGF0aW9uIHByb2Nlc3NpbmcgaXMKICAgICAqIG5lZWRlZC4KICAgICAqLwogICAgYm9vbGVhbiBwcm9jZXNzQW5ub3RhdGlvbnMgPSBmYWxzZTsKCiAgICBMb2cuRGVmZXJyZWREaWFnbm9zdGljSGFuZGxlciBkZWZlcnJlZERpYWdub3N0aWNIYW5kbGVyOwoKICAgIC8qKgogICAgICogT2JqZWN0IHRvIGhhbmRsZSBhbm5vdGF0aW9uIHByb2Nlc3NpbmcuCiAgICAgKi8KICAgIHByaXZhdGUgSmF2YWNQcm9jZXNzaW5nRW52aXJvbm1lbnQgcHJvY0VudkltcGwgPSBudWxsOwoKICAgIC8qKgogICAgICogQ2hlY2sgaWYgd2Ugc2hvdWxkIHByb2Nlc3MgYW5ub3RhdGlvbnMuCiAgICAgKiBJZiBzbywgYW5kIGlmIG5vIHNjYW5uZXIgaXMgeWV0IHJlZ2lzdGVyZWQsIHRoZW4gc2V0IHVwIHRoZSBEb2NDb21tZW50U2Nhbm5lcgogICAgICogdG8gY2F0Y2ggZG9jIGNvbW1lbnRzLCBhbmQgc2V0IGtlZXBDb21tZW50cyBzbyB0aGUgcGFyc2VyIHJlY29yZHMgdGhlbSBpbgogICAgICogdGhlIGNvbXBpbGF0aW9uIHVuaXQuCiAgICAgKgogICAgICogQHBhcmFtIHByb2Nlc3NvcnMgdXNlciBwcm92aWRlZCBhbm5vdGF0aW9uIHByb2Nlc3NvcnMgdG8gYnlwYXNzCiAgICAgKiBkaXNjb3ZlcnksIHtAY29kZSBudWxsfSBtZWFucyB0aGF0IG5vIHByb2Nlc3NvcnMgd2VyZSBwcm92aWRlZAogICAgICovCiAgICBwdWJsaWMgdm9pZCBpbml0UHJvY2Vzc0Fubm90YXRpb25zKEl0ZXJhYmxlPD8gZXh0ZW5kcyBQcm9jZXNzb3I+IHByb2Nlc3NvcnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbGxlY3Rpb248PyBleHRlbmRzIEphdmFGaWxlT2JqZWN0PiBpbml0aWFsRmlsZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbGxlY3Rpb248U3RyaW5nPiBpbml0aWFsQ2xhc3NOYW1lcykgewogICAgICAgIC8vIFByb2Nlc3MgYW5ub3RhdGlvbnMgaWYgcHJvY2Vzc2luZyBpcyBub3QgZGlzYWJsZWQgYW5kIHRoZXJlCiAgICAgICAgLy8gaXMgYXQgbGVhc3Qgb25lIFByb2Nlc3NvciBhdmFpbGFibGUuCiAgICAgICAgaWYgKG9wdGlvbnMuaXNTZXQoUFJPQywgIm5vbmUiKSkgewogICAgICAgICAgICBwcm9jZXNzQW5ub3RhdGlvbnMgPSBmYWxzZTsKICAgICAgICB9IGVsc2UgaWYgKHByb2NFbnZJbXBsID09IG51bGwpIHsKICAgICAgICAgICAgcHJvY0VudkltcGwgPSBKYXZhY1Byb2Nlc3NpbmdFbnZpcm9ubWVudC5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICAgICAgcHJvY0VudkltcGwuc2V0UHJvY2Vzc29ycyhwcm9jZXNzb3JzKTsKICAgICAgICAgICAgcHJvY2Vzc0Fubm90YXRpb25zID0gcHJvY0VudkltcGwuYXRMZWFzdE9uZVByb2Nlc3NvcigpOwoKICAgICAgICAgICAgaWYgKHByb2Nlc3NBbm5vdGF0aW9ucykgewogICAgICAgICAgICAgICAgb3B0aW9ucy5wdXQoInBhcmFtZXRlcnMiLCAicGFyYW1ldGVycyIpOwogICAgICAgICAgICAgICAgcmVhZGVyLnNhdmVQYXJhbWV0ZXJOYW1lcyA9IHRydWU7CiAgICAgICAgICAgICAgICBrZWVwQ29tbWVudHMgPSB0cnVlOwogICAgICAgICAgICAgICAgZ2VuRW5kUG9zID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGlmICghdGFza0xpc3RlbmVyLmlzRW1wdHkoKSkKICAgICAgICAgICAgICAgICAgICB0YXNrTGlzdGVuZXIuc3RhcnRlZChuZXcgVGFza0V2ZW50KFRhc2tFdmVudC5LaW5kLkFOTk9UQVRJT05fUFJPQ0VTU0lORykpOwogICAgICAgICAgICAgICAgZGVmZXJyZWREaWFnbm9zdGljSGFuZGxlciA9IG5ldyBMb2cuRGVmZXJyZWREaWFnbm9zdGljSGFuZGxlcihsb2cpOwogICAgICAgICAgICAgICAgcHJvY0VudkltcGwuZ2V0RmlsZXIoKS5zZXRJbml0aWFsU3RhdGUoaW5pdGlhbEZpbGVzLCBpbml0aWFsQ2xhc3NOYW1lcyk7CiAgICAgICAgICAgIH0gZWxzZSB7IC8vIGZyZWUgcmVzb3VyY2VzCiAgICAgICAgICAgICAgICBwcm9jRW52SW1wbC5jbG9zZSgpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8vIFRPRE86IGNhbGxlZCBieSBKYXZhY1Rhc2tJbXBsCiAgICBwdWJsaWMgdm9pZCBwcm9jZXNzQW5ub3RhdGlvbnMoTGlzdDxKQ0NvbXBpbGF0aW9uVW5pdD4gcm9vdHMpIHsKICAgICAgICBwcm9jZXNzQW5ub3RhdGlvbnMocm9vdHMsIExpc3QubmlsKCkpOwogICAgfQoKICAgIC8qKgogICAgICogUHJvY2VzcyBhbnkgYW5ub3RhdGlvbnMgZm91bmQgaW4gdGhlIHNwZWNpZmllZCBjb21waWxhdGlvbiB1bml0cy4KICAgICAqIEBwYXJhbSByb290cyBhIGxpc3Qgb2YgY29tcGlsYXRpb24gdW5pdHMKICAgICAqLwogICAgLy8gSW1wbGVtZW50YXRpb24gbm90ZTogd2hlbiB0aGlzIG1ldGhvZCBpcyBjYWxsZWQsIGxvZy5kZWZlcnJlZERpYWdub3N0aWNzCiAgICAvLyB3aWxsIGhhdmUgYmVlbiBzZXQgdHJ1ZSBieSBpbml0UHJvY2Vzc0Fubm90YXRpb25zLCBtZWFuaW5nIHRoYXQgYW55IGRpYWdub3N0aWNzCiAgICAvLyB0aGF0IGFyZSByZXBvcnRlZCB3aWxsIGdvIGludG8gdGhlIGxvZy5kZWZlcnJlZERpYWdub3N0aWNzIHF1ZXVlLgogICAgLy8gQnkgdGhlIHRpbWUgdGhpcyBtZXRob2QgZXhpdHMsIGxvZy5kZWZlckRpYWdub3N0aWNzIG11c3QgYmUgc2V0IGJhY2sgdG8gZmFsc2UsCiAgICAvLyBhbmQgYWxsIGRlZmVycmVkRGlhZ25vc3RpY3MgbXVzdCBoYXZlIGJlZW4gaGFuZGxlZDogaS5lLiBlaXRoZXIgcmVwb3J0ZWQKICAgIC8vIG9yIGRldGVybWluZWQgdG8gYmUgdHJhbnNpZW50LCBhbmQgdGhlcmVmb3JlIHN1cHByZXNzZWQuCiAgICBwdWJsaWMgdm9pZCBwcm9jZXNzQW5ub3RhdGlvbnMoTGlzdDxKQ0NvbXBpbGF0aW9uVW5pdD4gcm9vdHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29sbGVjdGlvbjxTdHJpbmc+IGNsYXNzbmFtZXMpIHsKICAgICAgICBpZiAoc2hvdWxkU3RvcChDb21waWxlU3RhdGUuUFJPQ0VTUykpIHsKICAgICAgICAgICAgLy8gRXJyb3JzIHdlcmUgZW5jb3VudGVyZWQuCiAgICAgICAgICAgIC8vIFVubGVzcyBhbGwgdGhlIGVycm9ycyBhcmUgcmVzb2x2ZSBlcnJvcnMsIHRoZSBlcnJvcnMgd2VyZSBwYXJzZSBlcnJvcnMKICAgICAgICAgICAgLy8gb3Igb3RoZXIgZXJyb3JzIGR1cmluZyBlbnRlciB3aGljaCBjYW5ub3QgYmUgZml4ZWQgYnkgcnVubmluZwogICAgICAgICAgICAvLyBhbnkgYW5ub3RhdGlvbiBwcm9jZXNzb3JzLgogICAgICAgICAgICBpZiAodW5yZWNvdmVyYWJsZUVycm9yKCkpIHsKICAgICAgICAgICAgICAgIGRlZmVycmVkRGlhZ25vc3RpY0hhbmRsZXIucmVwb3J0RGVmZXJyZWREaWFnbm9zdGljcygpOwogICAgICAgICAgICAgICAgbG9nLnBvcERpYWdub3N0aWNIYW5kbGVyKGRlZmVycmVkRGlhZ25vc3RpY0hhbmRsZXIpOwogICAgICAgICAgICAgICAgcmV0dXJuIDsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gQVNTRVJUOiBwcm9jZXNzQW5ub3RhdGlvbnMgYW5kIHByb2NFbnZJbXBsIHNob3VsZCBoYXZlIGJlZW4gc2V0IHVwIGJ5CiAgICAgICAgLy8gYnkgaW5pdFByb2Nlc3NBbm5vdGF0aW9ucwoKICAgICAgICAvLyBOT1RFOiBUaGUgIWNsYXNzbmFtZXMuaXNFbXB0eSgpIGNoZWNrcyBzaG91bGQgYmUgcmVmYWN0b3JlZCB0byBNYWluLgoKICAgICAgICBpZiAoIXByb2Nlc3NBbm5vdGF0aW9ucykgewogICAgICAgICAgICAvLyBJZiB0aGVyZSBhcmUgbm8gYW5ub3RhdGlvbiBwcm9jZXNzb3JzIHByZXNlbnQsIGFuZAogICAgICAgICAgICAvLyBhbm5vdGF0aW9uIHByb2Nlc3NpbmcgaXMgdG8gb2NjdXIgd2l0aCBjb21waWxhdGlvbiwKICAgICAgICAgICAgLy8gZW1pdCBhIHdhcm5pbmcuCiAgICAgICAgICAgIGlmIChvcHRpb25zLmlzU2V0KFBST0MsICJvbmx5IikpIHsKICAgICAgICAgICAgICAgIGxvZy53YXJuaW5nKCJwcm9jLnByb2Mtb25seS5yZXF1ZXN0ZWQubm8ucHJvY3MiKTsKICAgICAgICAgICAgICAgIHRvZG8uY2xlYXIoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvLyBJZiBub3QgcHJvY2Vzc2luZyBhbm5vdGF0aW9ucywgY2xhc3NuYW1lcyBtdXN0IGJlIGVtcHR5CiAgICAgICAgICAgIGlmICghY2xhc3NuYW1lcy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICAgIGxvZy5lcnJvcigicHJvYy5uby5leHBsaWNpdC5hbm5vdGF0aW9uLnByb2Nlc3NpbmcucmVxdWVzdGVkIiwKICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzc25hbWVzKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBBc3NlcnQuY2hlY2tOdWxsKGRlZmVycmVkRGlhZ25vc3RpY0hhbmRsZXIpOwogICAgICAgICAgICByZXR1cm4gOyAvLyBjb250aW51ZSByZWd1bGFyIGNvbXBpbGF0aW9uCiAgICAgICAgfQoKICAgICAgICBBc3NlcnQuY2hlY2tOb25OdWxsKGRlZmVycmVkRGlhZ25vc3RpY0hhbmRsZXIpOwoKICAgICAgICB0cnkgewogICAgICAgICAgICBMaXN0PENsYXNzU3ltYm9sPiBjbGFzc1N5bWJvbHMgPSBMaXN0Lm5pbCgpOwogICAgICAgICAgICBMaXN0PFBhY2thZ2VTeW1ib2w+IHBja1N5bWJvbHMgPSBMaXN0Lm5pbCgpOwogICAgICAgICAgICBpZiAoIWNsYXNzbmFtZXMuaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgICAgLy8gQ2hlY2sgZm9yIGV4cGxpY2l0IHJlcXVlc3QgZm9yIGFubm90YXRpb24KICAgICAgICAgICAgICAgICAvLyBwcm9jZXNzaW5nCiAgICAgICAgICAgICAgICBpZiAoIWV4cGxpY2l0QW5ub3RhdGlvblByb2Nlc3NpbmdSZXF1ZXN0ZWQoKSkgewogICAgICAgICAgICAgICAgICAgIGxvZy5lcnJvcigicHJvYy5uby5leHBsaWNpdC5hbm5vdGF0aW9uLnByb2Nlc3NpbmcucmVxdWVzdGVkIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3NuYW1lcyk7CiAgICAgICAgICAgICAgICAgICAgZGVmZXJyZWREaWFnbm9zdGljSGFuZGxlci5yZXBvcnREZWZlcnJlZERpYWdub3N0aWNzKCk7CiAgICAgICAgICAgICAgICAgICAgbG9nLnBvcERpYWdub3N0aWNIYW5kbGVyKGRlZmVycmVkRGlhZ25vc3RpY0hhbmRsZXIpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiA7IC8vIFRPRE86IFdpbGwgdGhpcyBoYWx0IGNvbXBpbGF0aW9uPwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBib29sZWFuIGVycm9ycyA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgIGZvciAoU3RyaW5nIG5hbWVTdHIgOiBjbGFzc25hbWVzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIFN5bWJvbCBzeW0gPSByZXNvbHZlQmluYXJ5TmFtZU9ySWRlbnQobmFtZVN0cik7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzeW0gPT0gbnVsbCB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKHN5bS5raW5kID09IFBDSyAmJiAhcHJvY2Vzc1Bja3MpIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeW0ua2luZCA9PSBBQlNFTlRfVFlQKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3ltICE9IHNpbGVudEZhaWwpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9nLmVycm9yKEVycm9ycy5Qcm9jQ2FudEZpbmRDbGFzcyhuYW1lU3RyKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvcnMgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzeW0ua2luZCA9PSBQQ0spCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ltLmNvbXBsZXRlKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3ltLmV4aXN0cygpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN5bS5raW5kID09IFBDSykKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGNrU3ltYm9scyA9IHBja1N5bWJvbHMucHJlcGVuZCgoUGFja2FnZVN5bWJvbClzeW0pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3NTeW1ib2xzID0gY2xhc3NTeW1ib2xzLnByZXBlbmQoKENsYXNzU3ltYm9sKXN5bSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBBc3NlcnQuY2hlY2soc3ltLmtpbmQgPT0gUENLKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZy53YXJuaW5nKFdhcm5pbmdzLlByb2NQYWNrYWdlRG9lc05vdEV4aXN0KG5hbWVTdHIpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBja1N5bWJvbHMgPSBwY2tTeW1ib2xzLnByZXBlbmQoKFBhY2thZ2VTeW1ib2wpc3ltKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoQ29tcGxldGlvbkZhaWx1cmUgZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9nLmVycm9yKEVycm9ycy5Qcm9jQ2FudEZpbmRDbGFzcyhuYW1lU3RyKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvcnMgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9ycykgewogICAgICAgICAgICAgICAgICAgICAgICBkZWZlcnJlZERpYWdub3N0aWNIYW5kbGVyLnJlcG9ydERlZmVycmVkRGlhZ25vc3RpY3MoKTsKICAgICAgICAgICAgICAgICAgICAgICAgbG9nLnBvcERpYWdub3N0aWNIYW5kbGVyKGRlZmVycmVkRGlhZ25vc3RpY0hhbmRsZXIpOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgYW5ub3RhdGlvblByb2Nlc3NpbmdPY2N1cnJlZCA9CiAgICAgICAgICAgICAgICAgICAgICAgIHByb2NFbnZJbXBsLmRvUHJvY2Vzc2luZyhyb290cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzU3ltYm9scywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBja1N5bWJvbHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWZlcnJlZERpYWdub3N0aWNIYW5kbGVyKTsKICAgICAgICAgICAgICAgIC8vIGRvUHJvY2Vzc2luZyB3aWxsIGhhdmUgaGFuZGxlZCBkZWZlcnJlZCBkaWFnbm9zdGljcwogICAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAgICAgcHJvY0VudkltcGwuY2xvc2UoKTsKICAgICAgICAgICAgfQogICAgICAgIH0gY2F0Y2ggKENvbXBsZXRpb25GYWlsdXJlIGV4KSB7CiAgICAgICAgICAgIGxvZy5lcnJvcigiY2FudC5hY2Nlc3MiLCBleC5zeW0sIGV4LmdldERldGFpbFZhbHVlKCkpOwogICAgICAgICAgICBpZiAoZGVmZXJyZWREaWFnbm9zdGljSGFuZGxlciAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICBkZWZlcnJlZERpYWdub3N0aWNIYW5kbGVyLnJlcG9ydERlZmVycmVkRGlhZ25vc3RpY3MoKTsKICAgICAgICAgICAgICAgIGxvZy5wb3BEaWFnbm9zdGljSGFuZGxlcihkZWZlcnJlZERpYWdub3N0aWNIYW5kbGVyKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIGJvb2xlYW4gdW5yZWNvdmVyYWJsZUVycm9yKCkgewogICAgICAgIGlmIChkZWZlcnJlZERpYWdub3N0aWNIYW5kbGVyICE9IG51bGwpIHsKICAgICAgICAgICAgZm9yIChKQ0RpYWdub3N0aWMgZDogZGVmZXJyZWREaWFnbm9zdGljSGFuZGxlci5nZXREaWFnbm9zdGljcygpKSB7CiAgICAgICAgICAgICAgICBpZiAoZC5nZXRLaW5kKCkgPT0gSkNEaWFnbm9zdGljLktpbmQuRVJST1IgJiYgIWQuaXNGbGFnU2V0KFJFQ09WRVJBQkxFKSkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgYm9vbGVhbiBleHBsaWNpdEFubm90YXRpb25Qcm9jZXNzaW5nUmVxdWVzdGVkKCkgewogICAgICAgIHJldHVybgogICAgICAgICAgICBleHBsaWNpdEFubm90YXRpb25Qcm9jZXNzaW5nUmVxdWVzdGVkIHx8CiAgICAgICAgICAgIGV4cGxpY2l0QW5ub3RhdGlvblByb2Nlc3NpbmdSZXF1ZXN0ZWQob3B0aW9ucyk7CiAgICB9CgogICAgc3RhdGljIGJvb2xlYW4gZXhwbGljaXRBbm5vdGF0aW9uUHJvY2Vzc2luZ1JlcXVlc3RlZChPcHRpb25zIG9wdGlvbnMpIHsKICAgICAgICByZXR1cm4KICAgICAgICAgICAgb3B0aW9ucy5pc1NldChQUk9DRVNTT1IpIHx8CiAgICAgICAgICAgIG9wdGlvbnMuaXNTZXQoUFJPQ0VTU09SX1BBVEgpIHx8CiAgICAgICAgICAgIG9wdGlvbnMuaXNTZXQoUFJPQ0VTU09SX01PRFVMRV9QQVRIKSB8fAogICAgICAgICAgICBvcHRpb25zLmlzU2V0KFBST0MsICJvbmx5IikgfHwKICAgICAgICAgICAgb3B0aW9ucy5pc1NldChYUFJJTlQpOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHNldERlZmVycmVkRGlhZ25vc3RpY0hhbmRsZXIoTG9nLkRlZmVycmVkRGlhZ25vc3RpY0hhbmRsZXIgZGVmZXJyZWREaWFnbm9zdGljSGFuZGxlcikgewogICAgICAgIHRoaXMuZGVmZXJyZWREaWFnbm9zdGljSGFuZGxlciA9IGRlZmVycmVkRGlhZ25vc3RpY0hhbmRsZXI7CiAgICB9CgogICAgLyoqCiAgICAgKiBBdHRyaWJ1dGUgYSBsaXN0IG9mIHBhcnNlIHRyZWVzLCBzdWNoIGFzIGZvdW5kIG9uIHRoZSAidG9kbyIgbGlzdC4KICAgICAqIE5vdGUgdGhhdCBhdHRyaWJ1dGluZyBjbGFzc2VzIG1heSBjYXVzZSBhZGRpdGlvbmFsIGZpbGVzIHRvIGJlCiAgICAgKiBwYXJzZWQgYW5kIGVudGVyZWQgdmlhIHRoZSBTb3VyY2VDb21wbGV0ZXIuCiAgICAgKiBBdHRyaWJ1dGlvbiBvZiB0aGUgZW50cmllcyBpbiB0aGUgbGlzdCBkb2VzIG5vdCBzdG9wIGlmIGFueSBlcnJvcnMgb2NjdXIuCiAgICAgKiBAcmV0dXJuIGEgbGlzdCBvZiBlbnZpcm9ubWVudHMgZm9yIGF0dHJpYnV0ZSBjbGFzc2VzLgogICAgICovCiAgICBwdWJsaWMgUXVldWU8RW52PEF0dHJDb250ZXh0Pj4gYXR0cmlidXRlKFF1ZXVlPEVudjxBdHRyQ29udGV4dD4+IGVudnMpIHsKICAgICAgICBMaXN0QnVmZmVyPEVudjxBdHRyQ29udGV4dD4+IHJlc3VsdHMgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgd2hpbGUgKCFlbnZzLmlzRW1wdHkoKSkKICAgICAgICAgICAgcmVzdWx0cy5hcHBlbmQoYXR0cmlidXRlKGVudnMucmVtb3ZlKCkpKTsKICAgICAgICByZXR1cm4gc3RvcElmRXJyb3IoQ29tcGlsZVN0YXRlLkFUVFIsIHJlc3VsdHMpOwogICAgfQoKICAgIC8qKgogICAgICogQXR0cmlidXRlIGEgcGFyc2UgdHJlZS4KICAgICAqIEByZXR1cm4gdGhlIGF0dHJpYnV0ZWQgcGFyc2UgdHJlZQogICAgICovCiAgICBwdWJsaWMgRW52PEF0dHJDb250ZXh0PiBhdHRyaWJ1dGUoRW52PEF0dHJDb250ZXh0PiBlbnYpIHsKICAgICAgICBpZiAoY29tcGlsZVN0YXRlcy5pc0RvbmUoZW52LCBDb21waWxlU3RhdGUuQVRUUikpCiAgICAgICAgICAgIHJldHVybiBlbnY7CgogICAgICAgIGlmICh2ZXJib3NlQ29tcGlsZVBvbGljeSkKICAgICAgICAgICAgcHJpbnROb3RlKCJbYXR0cmlidXRlICIgKyBlbnYuZW5jbENsYXNzLnN5bSArICJdIik7CiAgICAgICAgaWYgKHZlcmJvc2UpCiAgICAgICAgICAgIGxvZy5wcmludFZlcmJvc2UoImNoZWNraW5nLmF0dHJpYnV0aW9uIiwgZW52LmVuY2xDbGFzcy5zeW0pOwoKICAgICAgICBpZiAoIXRhc2tMaXN0ZW5lci5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgVGFza0V2ZW50IGUgPSBuZXcgVGFza0V2ZW50KFRhc2tFdmVudC5LaW5kLkFOQUxZWkUsIGVudi50b3BsZXZlbCwgZW52LmVuY2xDbGFzcy5zeW0pOwogICAgICAgICAgICB0YXNrTGlzdGVuZXIuc3RhcnRlZChlKTsKICAgICAgICB9CgogICAgICAgIEphdmFGaWxlT2JqZWN0IHByZXYgPSBsb2cudXNlU291cmNlKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW52LmVuY2xDbGFzcy5zeW0uc291cmNlZmlsZSAhPSBudWxsID8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVudi5lbmNsQ2xhc3Muc3ltLnNvdXJjZWZpbGUgOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW52LnRvcGxldmVsLnNvdXJjZWZpbGUpOwogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGF0dHIuYXR0cmliKGVudik7CiAgICAgICAgICAgIGlmIChlcnJvckNvdW50KCkgPiAwICYmICFzaG91bGRTdG9wKENvbXBpbGVTdGF0ZS5BVFRSKSkgewogICAgICAgICAgICAgICAgLy9pZiBpbiBmYWlsLW92ZXIgbW9kZSwgZW5zdXJlIHRoYXQgQVNUIGV4cHJlc3Npb24gbm9kZXMKICAgICAgICAgICAgICAgIC8vYXJlIGNvcnJlY3RseSBpbml0aWFsaXplZCAoZS5nLiB0aGV5IGhhdmUgYSB0eXBlL3N5bWJvbCkKICAgICAgICAgICAgICAgIGF0dHIucG9zdEF0dHIoZW52LnRyZWUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGNvbXBpbGVTdGF0ZXMucHV0KGVudiwgQ29tcGlsZVN0YXRlLkFUVFIpOwogICAgICAgIH0KICAgICAgICBmaW5hbGx5IHsKICAgICAgICAgICAgbG9nLnVzZVNvdXJjZShwcmV2KTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBlbnY7CiAgICB9CgogICAgLyoqCiAgICAgKiBQZXJmb3JtIGRhdGFmbG93IGNoZWNrcyBvbiBhdHRyaWJ1dGVkIHBhcnNlIHRyZWVzLgogICAgICogVGhlc2UgaW5jbHVkZSBjaGVja3MgZm9yIGRlZmluaXRlIGFzc2lnbm1lbnQgYW5kIHVucmVhY2hhYmxlIHN0YXRlbWVudHMuCiAgICAgKiBJZiBhbnkgZXJyb3JzIG9jY3VyLCBhbiBlbXB0eSBsaXN0IHdpbGwgYmUgcmV0dXJuZWQuCiAgICAgKiBAcmV0dXJuIHRoZSBsaXN0IG9mIGF0dHJpYnV0ZWQgcGFyc2UgdHJlZXMKICAgICAqLwogICAgcHVibGljIFF1ZXVlPEVudjxBdHRyQ29udGV4dD4+IGZsb3coUXVldWU8RW52PEF0dHJDb250ZXh0Pj4gZW52cykgewogICAgICAgIExpc3RCdWZmZXI8RW52PEF0dHJDb250ZXh0Pj4gcmVzdWx0cyA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICBmb3IgKEVudjxBdHRyQ29udGV4dD4gZW52OiBlbnZzKSB7CiAgICAgICAgICAgIGZsb3coZW52LCByZXN1bHRzKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHN0b3BJZkVycm9yKENvbXBpbGVTdGF0ZS5GTE9XLCByZXN1bHRzKTsKICAgIH0KCiAgICAvKioKICAgICAqIFBlcmZvcm0gZGF0YWZsb3cgY2hlY2tzIG9uIGFuIGF0dHJpYnV0ZWQgcGFyc2UgdHJlZS4KICAgICAqLwogICAgcHVibGljIFF1ZXVlPEVudjxBdHRyQ29udGV4dD4+IGZsb3coRW52PEF0dHJDb250ZXh0PiBlbnYpIHsKICAgICAgICBMaXN0QnVmZmVyPEVudjxBdHRyQ29udGV4dD4+IHJlc3VsdHMgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgZmxvdyhlbnYsIHJlc3VsdHMpOwogICAgICAgIHJldHVybiBzdG9wSWZFcnJvcihDb21waWxlU3RhdGUuRkxPVywgcmVzdWx0cyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBQZXJmb3JtIGRhdGFmbG93IGNoZWNrcyBvbiBhbiBhdHRyaWJ1dGVkIHBhcnNlIHRyZWUuCiAgICAgKi8KICAgIHByb3RlY3RlZCB2b2lkIGZsb3coRW52PEF0dHJDb250ZXh0PiBlbnYsIFF1ZXVlPEVudjxBdHRyQ29udGV4dD4+IHJlc3VsdHMpIHsKICAgICAgICBpZiAoY29tcGlsZVN0YXRlcy5pc0RvbmUoZW52LCBDb21waWxlU3RhdGUuRkxPVykpIHsKICAgICAgICAgICAgcmVzdWx0cy5hZGQoZW52KTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgaWYgKHNob3VsZFN0b3AoQ29tcGlsZVN0YXRlLkZMT1cpKQogICAgICAgICAgICAgICAgcmV0dXJuOwoKICAgICAgICAgICAgaWYgKHZlcmJvc2VDb21waWxlUG9saWN5KQogICAgICAgICAgICAgICAgcHJpbnROb3RlKCJbZmxvdyAiICsgZW52LmVuY2xDbGFzcy5zeW0gKyAiXSIpOwogICAgICAgICAgICBKYXZhRmlsZU9iamVjdCBwcmV2ID0gbG9nLnVzZVNvdXJjZSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW52LmVuY2xDbGFzcy5zeW0uc291cmNlZmlsZSAhPSBudWxsID8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW52LmVuY2xDbGFzcy5zeW0uc291cmNlZmlsZSA6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVudi50b3BsZXZlbC5zb3VyY2VmaWxlKTsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIG1ha2UuYXQoUG9zaXRpb24uRklSU1RQT1MpOwogICAgICAgICAgICAgICAgVHJlZU1ha2VyIGxvY2FsTWFrZSA9IG1ha2UuZm9yVG9wbGV2ZWwoZW52LnRvcGxldmVsKTsKICAgICAgICAgICAgICAgIGZsb3cuYW5hbHl6ZVRyZWUoZW52LCBsb2NhbE1ha2UpOwogICAgICAgICAgICAgICAgY29tcGlsZVN0YXRlcy5wdXQoZW52LCBDb21waWxlU3RhdGUuRkxPVyk7CgogICAgICAgICAgICAgICAgaWYgKHNob3VsZFN0b3AoQ29tcGlsZVN0YXRlLkZMT1cpKQogICAgICAgICAgICAgICAgICAgIHJldHVybjsKCiAgICAgICAgICAgICAgICByZXN1bHRzLmFkZChlbnYpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGZpbmFsbHkgewogICAgICAgICAgICAgICAgbG9nLnVzZVNvdXJjZShwcmV2KTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBmaW5hbGx5IHsKICAgICAgICAgICAgaWYgKCF0YXNrTGlzdGVuZXIuaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgICBUYXNrRXZlbnQgZSA9IG5ldyBUYXNrRXZlbnQoVGFza0V2ZW50LktpbmQuQU5BTFlaRSwgZW52LnRvcGxldmVsLCBlbnYuZW5jbENsYXNzLnN5bSk7CiAgICAgICAgICAgICAgICB0YXNrTGlzdGVuZXIuZmluaXNoZWQoZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBQcmVwYXJlIGF0dHJpYnV0ZWQgcGFyc2UgdHJlZXMsIGluIGNvbmp1bmN0aW9uIHdpdGggdGhlaXIgYXR0cmlidXRpb24gY29udGV4dHMsCiAgICAgKiBmb3Igc291cmNlIG9yIGNvZGUgZ2VuZXJhdGlvbi4KICAgICAqIElmIGFueSBlcnJvcnMgb2NjdXIsIGFuIGVtcHR5IGxpc3Qgd2lsbCBiZSByZXR1cm5lZC4KICAgICAqIEByZXR1cm4gYSBsaXN0IGNvbnRhaW5pbmcgdGhlIGNsYXNzZXMgdG8gYmUgZ2VuZXJhdGVkCiAgICAgKi8KICAgIHB1YmxpYyBRdWV1ZTxQYWlyPEVudjxBdHRyQ29udGV4dD4sIEpDQ2xhc3NEZWNsPj4gZGVzdWdhcihRdWV1ZTxFbnY8QXR0ckNvbnRleHQ+PiBlbnZzKSB7CiAgICAgICAgTGlzdEJ1ZmZlcjxQYWlyPEVudjxBdHRyQ29udGV4dD4sIEpDQ2xhc3NEZWNsPj4gcmVzdWx0cyA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICBmb3IgKEVudjxBdHRyQ29udGV4dD4gZW52OiBlbnZzKQogICAgICAgICAgICBkZXN1Z2FyKGVudiwgcmVzdWx0cyk7CiAgICAgICAgcmV0dXJuIHN0b3BJZkVycm9yKENvbXBpbGVTdGF0ZS5GTE9XLCByZXN1bHRzKTsKICAgIH0KCiAgICBIYXNoTWFwPEVudjxBdHRyQ29udGV4dD4sIFF1ZXVlPFBhaXI8RW52PEF0dHJDb250ZXh0PiwgSkNDbGFzc0RlY2w+Pj4gZGVzdWdhcmVkRW52cyA9IG5ldyBIYXNoTWFwPD4oKTsKCiAgICAvKioKICAgICAqIFByZXBhcmUgYXR0cmlidXRlZCBwYXJzZSB0cmVlcywgaW4gY29uanVuY3Rpb24gd2l0aCB0aGVpciBhdHRyaWJ1dGlvbiBjb250ZXh0cywKICAgICAqIGZvciBzb3VyY2Ugb3IgY29kZSBnZW5lcmF0aW9uLiBJZiB0aGUgZmlsZSB3YXMgbm90IGxpc3RlZCBvbiB0aGUgY29tbWFuZCBsaW5lLAogICAgICogdGhlIGN1cnJlbnQgaW1wbGljaXRTb3VyY2VQb2xpY3kgaXMgdGFrZW4gaW50byBhY2NvdW50LgogICAgICogVGhlIHByZXBhcmF0aW9uIHN0b3BzIGFzIHNvb24gYXMgYW4gZXJyb3IgaXMgZm91bmQuCiAgICAgKi8KICAgIHByb3RlY3RlZCB2b2lkIGRlc3VnYXIoZmluYWwgRW52PEF0dHJDb250ZXh0PiBlbnYsIFF1ZXVlPFBhaXI8RW52PEF0dHJDb250ZXh0PiwgSkNDbGFzc0RlY2w+PiByZXN1bHRzKSB7CiAgICAgICAgaWYgKHNob3VsZFN0b3AoQ29tcGlsZVN0YXRlLlRSQU5TVFlQRVMpKQogICAgICAgICAgICByZXR1cm47CgogICAgICAgIGlmIChpbXBsaWNpdFNvdXJjZVBvbGljeSA9PSBJbXBsaWNpdFNvdXJjZVBvbGljeS5OT05FCiAgICAgICAgICAgICAgICAmJiAhaW5wdXRGaWxlcy5jb250YWlucyhlbnYudG9wbGV2ZWwuc291cmNlZmlsZSkpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFtb2R1bGVzLm11bHRpTW9kdWxlTW9kZSAmJiBlbnYudG9wbGV2ZWwubW9kbGUgIT0gbW9kdWxlcy5nZXREZWZhdWx0TW9kdWxlKCkpIHsKICAgICAgICAgICAgLy9jYW4gb25seSBnZW5lcmF0ZSBjbGFzc2ZpbGVzIGZvciBhIHNpbmdsZSBtb2R1bGU6CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIGlmIChjb21waWxlU3RhdGVzLmlzRG9uZShlbnYsIENvbXBpbGVTdGF0ZS5MT1dFUikpIHsKICAgICAgICAgICAgcmVzdWx0cy5hZGRBbGwoZGVzdWdhcmVkRW52cy5nZXQoZW52KSk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIEVuc3VyZSB0aGF0IHN1cGVyY2xhc3NlcyBvZiBDIGFyZSBkZXN1Z2FyZWQgYmVmb3JlIEMgaXRzZWxmLiBUaGlzIGlzCiAgICAgICAgICogcmVxdWlyZWQgZm9yIHR3byByZWFzb25zOiAoaSkgYXMgZXJhc3VyZSAoVHJhbnNUeXBlcykgZGVzdHJveXMKICAgICAgICAgKiBpbmZvcm1hdGlvbiBuZWVkZWQgaW4gZmxvdyBhbmFseXNpcyBhbmQgKGlpKSBhcyBzb21lIGNoZWNrcyBjYXJyaWVkCiAgICAgICAgICogb3V0IGR1cmluZyBsb3dlcmluZyByZXF1aXJlIHRoYXQgYWxsIHN5bnRoZXRpYyBmaWVsZHMvbWV0aG9kcyBoYXZlCiAgICAgICAgICogYWxyZWFkeSBiZWVuIGFkZGVkIHRvIEMgYW5kIGl0cyBzdXBlcmNsYXNzZXMuCiAgICAgICAgICovCiAgICAgICAgY2xhc3MgU2Nhbk5lc3RlZCBleHRlbmRzIFRyZWVTY2FubmVyIHsKICAgICAgICAgICAgU2V0PEVudjxBdHRyQ29udGV4dD4+IGRlcGVuZGVuY2llcyA9IG5ldyBMaW5rZWRIYXNoU2V0PD4oKTsKICAgICAgICAgICAgcHJvdGVjdGVkIGJvb2xlYW4gaGFzTGFtYmRhczsKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0Q2xhc3NEZWYoSkNDbGFzc0RlY2wgbm9kZSkgewogICAgICAgICAgICAgICAgVHlwZSBzdCA9IHR5cGVzLnN1cGVydHlwZShub2RlLnN5bS50eXBlKTsKICAgICAgICAgICAgICAgIGJvb2xlYW4gZW52Rm9yU3VwZXJUeXBlRm91bmQgPSBmYWxzZTsKICAgICAgICAgICAgICAgIHdoaWxlICghZW52Rm9yU3VwZXJUeXBlRm91bmQgJiYgc3QuaGFzVGFnKENMQVNTKSkgewogICAgICAgICAgICAgICAgICAgIENsYXNzU3ltYm9sIGMgPSBzdC50c3ltLm91dGVybW9zdENsYXNzKCk7CiAgICAgICAgICAgICAgICAgICAgRW52PEF0dHJDb250ZXh0PiBzdEVudiA9IGVudGVyLmdldEVudihjKTsKICAgICAgICAgICAgICAgICAgICBpZiAoc3RFbnYgIT0gbnVsbCAmJiBlbnYgIT0gc3RFbnYpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRlcGVuZGVuY2llcy5hZGQoc3RFbnYpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIHByZXZIYXNMYW1iZGFzID0gaGFzTGFtYmRhczsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NhbihzdEVudi50cmVlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBpZ25vcmUgYW55IHVwZGF0ZXMgdG8gaGFzTGFtYmRhcyBtYWRlIGR1cmluZwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIHRoZSBuZXN0ZWQgc2NhbiwgdGhpcyBlbnN1cmVzIGFuIGluaXRhbGl6ZWQKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBMYW1iZGFUb01ldGhvZCBpcyBhdmFpbGFibGUgb25seSB0byB0aG9zZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIGNsYXNzZXMgdGhhdCBjb250YWluIGxhbWJkYXMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoYXNMYW1iZGFzID0gcHJldkhhc0xhbWJkYXM7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZW52Rm9yU3VwZXJUeXBlRm91bmQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBzdCA9IHR5cGVzLnN1cGVydHlwZShzdCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBzdXBlci52aXNpdENsYXNzRGVmKG5vZGUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdExhbWJkYShKQ0xhbWJkYSB0cmVlKSB7CiAgICAgICAgICAgICAgICBoYXNMYW1iZGFzID0gdHJ1ZTsKICAgICAgICAgICAgICAgIHN1cGVyLnZpc2l0TGFtYmRhKHRyZWUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdFJlZmVyZW5jZShKQ01lbWJlclJlZmVyZW5jZSB0cmVlKSB7CiAgICAgICAgICAgICAgICBoYXNMYW1iZGFzID0gdHJ1ZTsKICAgICAgICAgICAgICAgIHN1cGVyLnZpc2l0UmVmZXJlbmNlKHRyZWUpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIFNjYW5OZXN0ZWQgc2Nhbm5lciA9IG5ldyBTY2FuTmVzdGVkKCk7CiAgICAgICAgc2Nhbm5lci5zY2FuKGVudi50cmVlKTsKICAgICAgICBmb3IgKEVudjxBdHRyQ29udGV4dD4gZGVwOiBzY2FubmVyLmRlcGVuZGVuY2llcykgewogICAgICAgIGlmICghY29tcGlsZVN0YXRlcy5pc0RvbmUoZGVwLCBDb21waWxlU3RhdGUuRkxPVykpCiAgICAgICAgICAgIGRlc3VnYXJlZEVudnMucHV0KGRlcCwgZGVzdWdhcihmbG93KGF0dHJpYnV0ZShkZXApKSkpOwogICAgICAgIH0KCiAgICAgICAgLy9XZSBuZWVkIHRvIGNoZWNrIGZvciBlcnJvciBhbm90aGVyIHRpbWUgYXMgbW9yZSBjbGFzc2VzIG1pZ2h0CiAgICAgICAgLy9oYXZlIGJlZW4gYXR0cmlidXRlZCBhbmQgYW5hbHl6ZWQgYXQgdGhpcyBzdGFnZQogICAgICAgIGlmIChzaG91bGRTdG9wKENvbXBpbGVTdGF0ZS5UUkFOU1RZUEVTKSkKICAgICAgICAgICAgcmV0dXJuOwoKICAgICAgICBpZiAodmVyYm9zZUNvbXBpbGVQb2xpY3kpCiAgICAgICAgICAgIHByaW50Tm90ZSgiW2Rlc3VnYXIgIiArIGVudi5lbmNsQ2xhc3Muc3ltICsgIl0iKTsKCiAgICAgICAgSmF2YUZpbGVPYmplY3QgcHJldiA9IGxvZy51c2VTb3VyY2UoZW52LmVuY2xDbGFzcy5zeW0uc291cmNlZmlsZSAhPSBudWxsID8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVudi5lbmNsQ2xhc3Muc3ltLnNvdXJjZWZpbGUgOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW52LnRvcGxldmVsLnNvdXJjZWZpbGUpOwogICAgICAgIHRyeSB7CiAgICAgICAgICAgIC8vc2F2ZSB0cmVlIHByaW9yIHRvIHJld3JpdGluZwogICAgICAgICAgICBKQ1RyZWUgdW50cmFuc2xhdGVkID0gZW52LnRyZWU7CgogICAgICAgICAgICBtYWtlLmF0KFBvc2l0aW9uLkZJUlNUUE9TKTsKICAgICAgICAgICAgVHJlZU1ha2VyIGxvY2FsTWFrZSA9IG1ha2UuZm9yVG9wbGV2ZWwoZW52LnRvcGxldmVsKTsKCiAgICAgICAgICAgIGlmIChlbnYudHJlZS5oYXNUYWcoSkNUcmVlLlRhZy5QQUNLQUdFREVGKSB8fCBlbnYudHJlZS5oYXNUYWcoSkNUcmVlLlRhZy5NT0RVTEVERUYpKSB7CiAgICAgICAgICAgICAgICBpZiAoIShzb3VyY2VPdXRwdXQpKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHNob3VsZFN0b3AoQ29tcGlsZVN0YXRlLkxPV0VSKSkKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgIExpc3Q8SkNUcmVlPiBkZWYgPSBsb3dlci50cmFuc2xhdGVUb3BMZXZlbENsYXNzKGVudiwgZW52LnRyZWUsIGxvY2FsTWFrZSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKGRlZi5oZWFkICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgQXNzZXJ0LmNoZWNrKGRlZi50YWlsLmlzRW1wdHkoKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdHMuYWRkKG5ldyBQYWlyPD4oZW52LCAoSkNDbGFzc0RlY2wpZGVmLmhlYWQpKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChzaG91bGRTdG9wKENvbXBpbGVTdGF0ZS5UUkFOU1RZUEVTKSkKICAgICAgICAgICAgICAgIHJldHVybjsKCiAgICAgICAgICAgIGVudi50cmVlID0gdHJhbnNUeXBlcy50cmFuc2xhdGVUb3BMZXZlbENsYXNzKGVudi50cmVlLCBsb2NhbE1ha2UpOwogICAgICAgICAgICBjb21waWxlU3RhdGVzLnB1dChlbnYsIENvbXBpbGVTdGF0ZS5UUkFOU1RZUEVTKTsKCiAgICAgICAgICAgIGlmIChzb3VyY2UuYWxsb3dMYW1iZGEoKSAmJiBzY2FubmVyLmhhc0xhbWJkYXMpIHsKICAgICAgICAgICAgICAgIGlmIChzaG91bGRTdG9wKENvbXBpbGVTdGF0ZS5VTkxBTUJEQSkpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwoKICAgICAgICAgICAgICAgIGVudi50cmVlID0gTGFtYmRhVG9NZXRob2QuaW5zdGFuY2UoY29udGV4dCkudHJhbnNsYXRlVG9wTGV2ZWxDbGFzcyhlbnYsIGVudi50cmVlLCBsb2NhbE1ha2UpOwogICAgICAgICAgICAgICAgY29tcGlsZVN0YXRlcy5wdXQoZW52LCBDb21waWxlU3RhdGUuVU5MQU1CREEpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoc2hvdWxkU3RvcChDb21waWxlU3RhdGUuTE9XRVIpKQogICAgICAgICAgICAgICAgcmV0dXJuOwoKICAgICAgICAgICAgaWYgKHNvdXJjZU91dHB1dCkgewogICAgICAgICAgICAgICAgLy9lbWl0IHN0YW5kYXJkIEphdmEgc291cmNlIGZpbGUsIG9ubHkgZm9yIGNvbXBpbGF0aW9uCiAgICAgICAgICAgICAgICAvL3VuaXRzIGVudW1lcmF0ZWQgZXhwbGljaXRseSBvbiB0aGUgY29tbWFuZCBsaW5lCiAgICAgICAgICAgICAgICBKQ0NsYXNzRGVjbCBjZGVmID0gKEpDQ2xhc3NEZWNsKWVudi50cmVlOwogICAgICAgICAgICAgICAgaWYgKHVudHJhbnNsYXRlZCBpbnN0YW5jZW9mIEpDQ2xhc3NEZWNsICYmCiAgICAgICAgICAgICAgICAgICAgcm9vdENsYXNzZXMuY29udGFpbnMoKEpDQ2xhc3NEZWNsKXVudHJhbnNsYXRlZCkpIHsKICAgICAgICAgICAgICAgICAgICByZXN1bHRzLmFkZChuZXcgUGFpcjw+KGVudiwgY2RlZikpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvL3RyYW5zbGF0ZSBvdXQgaW5uZXIgY2xhc3NlcwogICAgICAgICAgICBMaXN0PEpDVHJlZT4gY2RlZnMgPSBsb3dlci50cmFuc2xhdGVUb3BMZXZlbENsYXNzKGVudiwgZW52LnRyZWUsIGxvY2FsTWFrZSk7CiAgICAgICAgICAgIGNvbXBpbGVTdGF0ZXMucHV0KGVudiwgQ29tcGlsZVN0YXRlLkxPV0VSKTsKCiAgICAgICAgICAgIGlmIChzaG91bGRTdG9wKENvbXBpbGVTdGF0ZS5MT1dFUikpCiAgICAgICAgICAgICAgICByZXR1cm47CgogICAgICAgICAgICAvL2dlbmVyYXRlIGNvZGUgZm9yIGVhY2ggY2xhc3MKICAgICAgICAgICAgZm9yIChMaXN0PEpDVHJlZT4gbCA9IGNkZWZzOyBsLm5vbkVtcHR5KCk7IGwgPSBsLnRhaWwpIHsKICAgICAgICAgICAgICAgIEpDQ2xhc3NEZWNsIGNkZWYgPSAoSkNDbGFzc0RlY2wpbC5oZWFkOwogICAgICAgICAgICAgICAgcmVzdWx0cy5hZGQobmV3IFBhaXI8PihlbnYsIGNkZWYpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBmaW5hbGx5IHsKICAgICAgICAgICAgbG9nLnVzZVNvdXJjZShwcmV2KTsKICAgICAgICB9CgogICAgfQoKICAgIC8qKiBHZW5lcmF0ZXMgdGhlIHNvdXJjZSBvciBjbGFzcyBmaWxlIGZvciBhIGxpc3Qgb2YgY2xhc3Nlcy4KICAgICAqIFRoZSBkZWNpc2lvbiB0byBnZW5lcmF0ZSBhIHNvdXJjZSBmaWxlIG9yIGEgY2xhc3MgZmlsZSBpcwogICAgICogYmFzZWQgdXBvbiB0aGUgY29tcGlsZXIncyBvcHRpb25zLgogICAgICogR2VuZXJhdGlvbiBzdG9wcyBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgd3JpdGluZyBmaWxlcy4KICAgICAqLwogICAgcHVibGljIHZvaWQgZ2VuZXJhdGUoUXVldWU8UGFpcjxFbnY8QXR0ckNvbnRleHQ+LCBKQ0NsYXNzRGVjbD4+IHF1ZXVlKSB7CiAgICAgICAgZ2VuZXJhdGUocXVldWUsIG51bGwpOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIGdlbmVyYXRlKFF1ZXVlPFBhaXI8RW52PEF0dHJDb250ZXh0PiwgSkNDbGFzc0RlY2w+PiBxdWV1ZSwgUXVldWU8SmF2YUZpbGVPYmplY3Q+IHJlc3VsdHMpIHsKICAgICAgICBpZiAoc2hvdWxkU3RvcChDb21waWxlU3RhdGUuR0VORVJBVEUpKQogICAgICAgICAgICByZXR1cm47CgogICAgICAgIGZvciAoUGFpcjxFbnY8QXR0ckNvbnRleHQ+LCBKQ0NsYXNzRGVjbD4geDogcXVldWUpIHsKICAgICAgICAgICAgRW52PEF0dHJDb250ZXh0PiBlbnYgPSB4LmZzdDsKICAgICAgICAgICAgSkNDbGFzc0RlY2wgY2RlZiA9IHguc25kOwoKICAgICAgICAgICAgaWYgKHZlcmJvc2VDb21waWxlUG9saWN5KSB7CiAgICAgICAgICAgICAgICBwcmludE5vdGUoIltnZW5lcmF0ZSAiICsgKHNvdXJjZU91dHB1dCA/ICIgc291cmNlIiA6ICJjb2RlIikgKyAiICIgKyBjZGVmLnN5bSArICJdIik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICghdGFza0xpc3RlbmVyLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgICAgVGFza0V2ZW50IGUgPSBuZXcgVGFza0V2ZW50KFRhc2tFdmVudC5LaW5kLkdFTkVSQVRFLCBlbnYudG9wbGV2ZWwsIGNkZWYuc3ltKTsKICAgICAgICAgICAgICAgIHRhc2tMaXN0ZW5lci5zdGFydGVkKGUpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBKYXZhRmlsZU9iamVjdCBwcmV2ID0gbG9nLnVzZVNvdXJjZShlbnYuZW5jbENsYXNzLnN5bS5zb3VyY2VmaWxlICE9IG51bGwgPwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVudi5lbmNsQ2xhc3Muc3ltLnNvdXJjZWZpbGUgOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVudi50b3BsZXZlbC5zb3VyY2VmaWxlKTsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIEphdmFGaWxlT2JqZWN0IGZpbGU7CiAgICAgICAgICAgICAgICBpZiAoc291cmNlT3V0cHV0KSB7CiAgICAgICAgICAgICAgICAgICAgZmlsZSA9IHByaW50U291cmNlKGVudiwgY2RlZik7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGlmIChmaWxlTWFuYWdlci5oYXNMb2NhdGlvbihTdGFuZGFyZExvY2F0aW9uLk5BVElWRV9IRUFERVJfT1VUUFVUKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgam5pV3JpdGVyLm5lZWRzSGVhZGVyKGNkZWYuc3ltKSkgewogICAgICAgICAgICAgICAgICAgICAgICBqbmlXcml0ZXIud3JpdGUoY2RlZi5zeW0pOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBmaWxlID0gZ2VuQ29kZShlbnYsIGNkZWYpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKHJlc3VsdHMgIT0gbnVsbCAmJiBmaWxlICE9IG51bGwpCiAgICAgICAgICAgICAgICAgICAgcmVzdWx0cy5hZGQoZmlsZSk7CiAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7CiAgICAgICAgICAgICAgICBsb2cuZXJyb3IoY2RlZi5wb3MoKSwgImNsYXNzLmNhbnQud3JpdGUiLAogICAgICAgICAgICAgICAgICAgICAgICAgIGNkZWYuc3ltLCBleC5nZXRNZXNzYWdlKCkpOwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAgICAgbG9nLnVzZVNvdXJjZShwcmV2KTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCF0YXNrTGlzdGVuZXIuaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgICBUYXNrRXZlbnQgZSA9IG5ldyBUYXNrRXZlbnQoVGFza0V2ZW50LktpbmQuR0VORVJBVEUsIGVudi50b3BsZXZlbCwgY2RlZi5zeW0pOwogICAgICAgICAgICAgICAgdGFza0xpc3RlbmVyLmZpbmlzaGVkKGUpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgICAgICAvLyB3aGVyZQogICAgICAgIE1hcDxKQ0NvbXBpbGF0aW9uVW5pdCwgUXVldWU8RW52PEF0dHJDb250ZXh0Pj4+IGdyb3VwQnlGaWxlKFF1ZXVlPEVudjxBdHRyQ29udGV4dD4+IGVudnMpIHsKICAgICAgICAgICAgLy8gdXNlIGEgTGlua2VkSGFzaE1hcCB0byBwcmVzZXJ2ZSB0aGUgb3JkZXIgb2YgdGhlIG9yaWdpbmFsIGxpc3QgYXMgbXVjaCBhcyBwb3NzaWJsZQogICAgICAgICAgICBNYXA8SkNDb21waWxhdGlvblVuaXQsIFF1ZXVlPEVudjxBdHRyQ29udGV4dD4+PiBtYXAgPSBuZXcgTGlua2VkSGFzaE1hcDw+KCk7CiAgICAgICAgICAgIGZvciAoRW52PEF0dHJDb250ZXh0PiBlbnY6IGVudnMpIHsKICAgICAgICAgICAgICAgIFF1ZXVlPEVudjxBdHRyQ29udGV4dD4+IHN1Ymxpc3QgPSBtYXAuZ2V0KGVudi50b3BsZXZlbCk7CiAgICAgICAgICAgICAgICBpZiAoc3VibGlzdCA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgc3VibGlzdCA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICAgICAgICAgICAgICBtYXAucHV0KGVudi50b3BsZXZlbCwgc3VibGlzdCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBzdWJsaXN0LmFkZChlbnYpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBtYXA7CiAgICAgICAgfQoKICAgICAgICBKQ0NsYXNzRGVjbCByZW1vdmVNZXRob2RCb2RpZXMoSkNDbGFzc0RlY2wgY2RlZikgewogICAgICAgICAgICBmaW5hbCBib29sZWFuIGlzSW50ZXJmYWNlID0gKGNkZWYubW9kcy5mbGFncyAmIEZsYWdzLklOVEVSRkFDRSkgIT0gMDsKICAgICAgICAgICAgY2xhc3MgTWV0aG9kQm9keVJlbW92ZXIgZXh0ZW5kcyBUcmVlVHJhbnNsYXRvciB7CiAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0TWV0aG9kRGVmKEpDTWV0aG9kRGVjbCB0cmVlKSB7CiAgICAgICAgICAgICAgICAgICAgdHJlZS5tb2RzLmZsYWdzICY9IH5GbGFncy5TWU5DSFJPTklaRUQ7CiAgICAgICAgICAgICAgICAgICAgZm9yIChKQ1ZhcmlhYmxlRGVjbCB2ZCA6IHRyZWUucGFyYW1zKQogICAgICAgICAgICAgICAgICAgICAgICB2ZC5tb2RzLmZsYWdzICY9IH5GbGFncy5GSU5BTDsKICAgICAgICAgICAgICAgICAgICB0cmVlLmJvZHkgPSBudWxsOwogICAgICAgICAgICAgICAgICAgIHN1cGVyLnZpc2l0TWV0aG9kRGVmKHRyZWUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdFZhckRlZihKQ1ZhcmlhYmxlRGVjbCB0cmVlKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHRyZWUuaW5pdCAhPSBudWxsICYmIHRyZWUuaW5pdC50eXBlLmNvbnN0VmFsdWUoKSA9PSBudWxsKQogICAgICAgICAgICAgICAgICAgICAgICB0cmVlLmluaXQgPSBudWxsOwogICAgICAgICAgICAgICAgICAgIHN1cGVyLnZpc2l0VmFyRGVmKHRyZWUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdENsYXNzRGVmKEpDQ2xhc3NEZWNsIHRyZWUpIHsKICAgICAgICAgICAgICAgICAgICBMaXN0QnVmZmVyPEpDVHJlZT4gbmV3ZGVmcyA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICAgICAgICAgICAgICBmb3IgKExpc3Q8SkNUcmVlPiBpdCA9IHRyZWUuZGVmczsgaXQudGFpbCAhPSBudWxsOyBpdCA9IGl0LnRhaWwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgSkNUcmVlIHQgPSBpdC5oZWFkOwogICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKHQuZ2V0VGFnKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBDTEFTU0RFRjoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc0ludGVyZmFjZSB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoKEpDQ2xhc3NEZWNsKSB0KS5tb2RzLmZsYWdzICYgKEZsYWdzLlBST1RFQ1RFRHxGbGFncy5QVUJMSUMpKSAhPSAwIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCgoSkNDbGFzc0RlY2wpIHQpLm1vZHMuZmxhZ3MgJiAoRmxhZ3MuUFJJVkFURSkpID09IDAgJiYgKChKQ0NsYXNzRGVjbCkgdCkuc3ltLnBhY2tnZSgpLmdldFF1YWxpZmllZE5hbWUoKSA9PSBuYW1lcy5qYXZhX2xhbmcpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3ZGVmcy5hcHBlbmQodCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBNRVRIT0RERUY6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNJbnRlcmZhY2UgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKChKQ01ldGhvZERlY2wpIHQpLm1vZHMuZmxhZ3MgJiAoRmxhZ3MuUFJPVEVDVEVEfEZsYWdzLlBVQkxJQykpICE9IDAgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKEpDTWV0aG9kRGVjbCkgdCkuc3ltLm5hbWUgPT0gbmFtZXMuaW5pdCB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoKEpDTWV0aG9kRGVjbCkgdCkubW9kcy5mbGFncyAmIChGbGFncy5QUklWQVRFKSkgPT0gMCAmJiAoKEpDTWV0aG9kRGVjbCkgdCkuc3ltLnBhY2tnZSgpLmdldFF1YWxpZmllZE5hbWUoKSA9PSBuYW1lcy5qYXZhX2xhbmcpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3ZGVmcy5hcHBlbmQodCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBWQVJERUY6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNJbnRlcmZhY2UgfHwgKCgoSkNWYXJpYWJsZURlY2wpIHQpLm1vZHMuZmxhZ3MgJiAoRmxhZ3MuUFJPVEVDVEVEfEZsYWdzLlBVQkxJQykpICE9IDAgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKChKQ1ZhcmlhYmxlRGVjbCkgdCkubW9kcy5mbGFncyAmIChGbGFncy5QUklWQVRFKSkgPT0gMCAmJiAoKEpDVmFyaWFibGVEZWNsKSB0KS5zeW0ucGFja2dlKCkuZ2V0UXVhbGlmaWVkTmFtZSgpID09IG5hbWVzLmphdmFfbGFuZykKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdkZWZzLmFwcGVuZCh0KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgdHJlZS5kZWZzID0gbmV3ZGVmcy50b0xpc3QoKTsKICAgICAgICAgICAgICAgICAgICBzdXBlci52aXNpdENsYXNzRGVmKHRyZWUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIE1ldGhvZEJvZHlSZW1vdmVyIHIgPSBuZXcgTWV0aG9kQm9keVJlbW92ZXIoKTsKICAgICAgICAgICAgcmV0dXJuIHIudHJhbnNsYXRlKGNkZWYpOwogICAgICAgIH0KCiAgICBwdWJsaWMgdm9pZCByZXBvcnREZWZlcnJlZERpYWdub3N0aWNzKCkgewogICAgICAgIGlmIChlcnJvckNvdW50KCkgPT0gMAogICAgICAgICAgICAgICAgJiYgYW5ub3RhdGlvblByb2Nlc3NpbmdPY2N1cnJlZAogICAgICAgICAgICAgICAgJiYgaW1wbGljaXRTb3VyY2VGaWxlc1JlYWQKICAgICAgICAgICAgICAgICYmIGltcGxpY2l0U291cmNlUG9saWN5ID09IEltcGxpY2l0U291cmNlUG9saWN5LlVOU0VUKSB7CiAgICAgICAgICAgIGlmIChleHBsaWNpdEFubm90YXRpb25Qcm9jZXNzaW5nUmVxdWVzdGVkKCkpCiAgICAgICAgICAgICAgICBsb2cud2FybmluZygicHJvYy51c2UuaW1wbGljaXQiKTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgbG9nLndhcm5pbmcoInByb2MudXNlLnByb2Mub3IuaW1wbGljaXQiKTsKICAgICAgICB9CiAgICAgICAgY2hrLnJlcG9ydERlZmVycmVkRGlhZ25vc3RpY3MoKTsKICAgICAgICBpZiAobG9nLmNvbXByZXNzZWRPdXRwdXQpIHsKICAgICAgICAgICAgbG9nLm1hbmRhdG9yeU5vdGUobnVsbCwgImNvbXByZXNzZWQuZGlhZ3MiKTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHZvaWQgZW50ZXJEb25lKCkgewogICAgICAgIGVudGVyRG9uZSA9IHRydWU7CiAgICAgICAgYW5ub3RhdGUuZW50ZXJEb25lKCk7CiAgICB9CgogICAgcHVibGljIGJvb2xlYW4gaXNFbnRlckRvbmUoKSB7CiAgICAgICAgcmV0dXJuIGVudGVyRG9uZTsKICAgIH0KCiAgICAvKiogQ2xvc2UgdGhlIGNvbXBpbGVyLCBmbHVzaGluZyB0aGUgbG9ncwogICAgICovCiAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHsKICAgICAgICByb290Q2xhc3NlcyA9IG51bGw7CiAgICAgICAgZmluZGVyID0gbnVsbDsKICAgICAgICByZWFkZXIgPSBudWxsOwogICAgICAgIG1ha2UgPSBudWxsOwogICAgICAgIHdyaXRlciA9IG51bGw7CiAgICAgICAgZW50ZXIgPSBudWxsOwogICAgICAgIGlmICh0b2RvICE9IG51bGwpCiAgICAgICAgICAgIHRvZG8uY2xlYXIoKTsKICAgICAgICB0b2RvID0gbnVsbDsKICAgICAgICBwYXJzZXJGYWN0b3J5ID0gbnVsbDsKICAgICAgICBzeW1zID0gbnVsbDsKICAgICAgICBzb3VyY2UgPSBudWxsOwogICAgICAgIGF0dHIgPSBudWxsOwogICAgICAgIGNoayA9IG51bGw7CiAgICAgICAgZ2VuID0gbnVsbDsKICAgICAgICBmbG93ID0gbnVsbDsKICAgICAgICB0cmFuc1R5cGVzID0gbnVsbDsKICAgICAgICBsb3dlciA9IG51bGw7CiAgICAgICAgYW5ub3RhdGUgPSBudWxsOwogICAgICAgIHR5cGVzID0gbnVsbDsKCiAgICAgICAgbG9nLmZsdXNoKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgZmlsZU1hbmFnZXIuZmx1c2goKTsKICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBBYm9ydChlKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICBpZiAobmFtZXMgIT0gbnVsbCkKICAgICAgICAgICAgICAgIG5hbWVzLmRpc3Bvc2UoKTsKICAgICAgICAgICAgbmFtZXMgPSBudWxsOwoKICAgICAgICAgICAgZm9yIChDbG9zZWFibGUgYzogY2xvc2VhYmxlcykgewogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICBjLmNsb3NlKCk7CiAgICAgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gV2hlbiBqYXZhYyB1c2VzIEpESyA3IGFzIGEgYmFzZWxpbmUsIHRoaXMgY29kZSB3b3VsZCBiZQogICAgICAgICAgICAgICAgICAgIC8vIGJldHRlciB3cml0dGVuIHRvIHNldCBhbnkvYWxsIGV4Y2VwdGlvbnMgZnJvbSBhbGwgdGhlCiAgICAgICAgICAgICAgICAgICAgLy8gQ2xvc2VhYmxlcyBhcyBzdXBwcmVzc2VkIGV4Y2VwdGlvbnMgb24gdGhlIEZhdGFsRXJyb3IKICAgICAgICAgICAgICAgICAgICAvLyB0aGF0IGlzIHRocm93bi4KICAgICAgICAgICAgICAgICAgICBKQ0RpYWdub3N0aWMgbXNnID0gZGlhZ0ZhY3RvcnkuZnJhZ21lbnQoImZhdGFsLmVyci5jYW50LmNsb3NlIik7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEZhdGFsRXJyb3IobXNnLCBlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBjbG9zZWFibGVzID0gTGlzdC5uaWwoKTsKICAgICAgICB9CiAgICB9CgogICAgcHJvdGVjdGVkIHZvaWQgcHJpbnROb3RlKFN0cmluZyBsaW5lcykgewogICAgICAgIGxvZy5wcmludFJhd0xpbmVzKExvZy5Xcml0ZXJLaW5kLk5PVElDRSwgbGluZXMpOwogICAgfQoKICAgIC8qKiBQcmludCBudW1iZXJzIG9mIGVycm9ycyBhbmQgd2FybmluZ3MuCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHByaW50Q291bnQoU3RyaW5nIGtpbmQsIGludCBjb3VudCkgewogICAgICAgIGlmIChjb3VudCAhPSAwKSB7CiAgICAgICAgICAgIFN0cmluZyBrZXk7CiAgICAgICAgICAgIGlmIChjb3VudCA9PSAxKQogICAgICAgICAgICAgICAga2V5ID0gImNvdW50LiIgKyBraW5kOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBrZXkgPSAiY291bnQuIiArIGtpbmQgKyAiLnBsdXJhbCI7CiAgICAgICAgICAgIGxvZy5wcmludExpbmVzKFdyaXRlcktpbmQuRVJST1IsIGtleSwgU3RyaW5nLnZhbHVlT2YoY291bnQpKTsKICAgICAgICAgICAgbG9nLmZsdXNoKExvZy5Xcml0ZXJLaW5kLkVSUk9SKTsKICAgICAgICB9CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgbG9uZyBub3coKSB7CiAgICAgICAgcmV0dXJuIFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGxvbmcgZWxhcHNlZChsb25nIHRoZW4pIHsKICAgICAgICByZXR1cm4gbm93KCkgLSB0aGVuOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIG5ld1JvdW5kKCkgewogICAgICAgIGlucHV0RmlsZXMuY2xlYXIoKTsKICAgICAgICB0b2RvLmNsZWFyKCk7CiAgICB9Cn0KUEsDBAoAAAgAAAY7qUrEpWvpgS0AAIEtAAApAAAAY29tL3N1bi90b29scy9qYXZhYy9tYWluL0NvbW1hbmRMaW5lLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDE5OTksIDIwMTcsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhYy5tYWluOwoKaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CmltcG9ydCBqYXZhLmlvLlJlYWRlcjsKaW1wb3J0IGphdmEubmlvLmZpbGUuRmlsZXM7CmltcG9ydCBqYXZhLm5pby5maWxlLlBhdGhzOwppbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CmltcG9ydCBqYXZhLnV0aWwuTGlzdDsKCi8qKgogKiBWYXJpb3VzIHV0aWxpdHkgbWV0aG9kcyBmb3IgcHJvY2Vzc2luZyBKYXZhIHRvb2wgY29tbWFuZCBsaW5lIGFyZ3VtZW50cy4KICoKICogIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqICBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqICBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogKiAgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPgogKi8KcHVibGljIGNsYXNzIENvbW1hbmRMaW5lIHsKICAgIC8qKgogICAgICogUHJvY2VzcyBXaW4zMi1zdHlsZSBjb21tYW5kIGZpbGVzIGZvciB0aGUgc3BlY2lmaWVkIGNvbW1hbmQgbGluZQogICAgICogYXJndW1lbnRzIGFuZCByZXR1cm4gdGhlIHJlc3VsdGluZyBhcmd1bWVudHMuIEEgY29tbWFuZCBmaWxlIGFyZ3VtZW50CiAgICAgKiBpcyBvZiB0aGUgZm9ybSAnQGZpbGUnIHdoZXJlICdmaWxlJyBpcyB0aGUgbmFtZSBvZiB0aGUgZmlsZSB3aG9zZQogICAgICogY29udGVudHMgYXJlIHRvIGJlIHBhcnNlZCBmb3IgYWRkaXRpb25hbCBhcmd1bWVudHMuIFRoZSBjb250ZW50cyBvZgogICAgICogdGhlIGNvbW1hbmQgZmlsZSBhcmUgcGFyc2VkIHVzaW5nIFN0cmVhbVRva2VuaXplciBhbmQgdGhlIG9yaWdpbmFsCiAgICAgKiAnQGZpbGUnIGFyZ3VtZW50IHJlcGxhY2VkIHdpdGggdGhlIHJlc3VsdGluZyB0b2tlbnMuIFJlY3Vyc2l2ZSBjb21tYW5kCiAgICAgKiBmaWxlcyBhcmUgbm90IHN1cHBvcnRlZC4gVGhlICdAJyBjaGFyYWN0ZXIgaXRzZWxmIGNhbiBiZSBxdW90ZWQgd2l0aAogICAgICogdGhlIHNlcXVlbmNlICdAQCcuCiAgICAgKiBAcGFyYW0gYXJncyB0aGUgYXJndW1lbnRzIHRoYXQgbWF5IGNvbnRhaW4gQGZpbGVzCiAgICAgKiBAcmV0dXJuIHRoZSBhcmd1bWVudHMsIHdpdGggQGZpbGVzIGV4cGFuZGVkCiAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIHRoZXJlIGlzIGEgcHJvYmxlbSByZWFkaW5nIGFueSBvZiB0aGUgQGZpbGVzCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nW10gcGFyc2UoU3RyaW5nW10gYXJncykgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICBMaXN0PFN0cmluZz4gbmV3QXJncyA9IG5ldyBBcnJheUxpc3Q8PigpOwogICAgICAgIGFwcGVuZFBhcnNlZENvbW1hbmRBcmdzKG5ld0FyZ3MsIEFycmF5cy5hc0xpc3QoYXJncykpOwogICAgICAgIHJldHVybiBuZXdBcmdzLnRvQXJyYXkobmV3IFN0cmluZ1tuZXdBcmdzLnNpemUoKV0pOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIHZvaWQgYXBwZW5kUGFyc2VkQ29tbWFuZEFyZ3MoTGlzdDxTdHJpbmc+IG5ld0FyZ3MsIExpc3Q8U3RyaW5nPiBhcmdzKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgIGZvciAoU3RyaW5nIGFyZyA6IGFyZ3MpIHsKICAgICAgICAgICAgaWYgKGFyZy5sZW5ndGgoKSA+IDEgJiYgYXJnLmNoYXJBdCgwKSA9PSAnQCcpIHsKICAgICAgICAgICAgICAgIGFyZyA9IGFyZy5zdWJzdHJpbmcoMSk7CiAgICAgICAgICAgICAgICBpZiAoYXJnLmNoYXJBdCgwKSA9PSAnQCcpIHsKICAgICAgICAgICAgICAgICAgICBuZXdBcmdzLmFkZChhcmcpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBsb2FkQ21kRmlsZShhcmcsIG5ld0FyZ3MpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgbmV3QXJncy5hZGQoYXJnKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFByb2Nlc3MgdGhlIGdpdmVuIGVudmlyb25tZW50IHZhcmlhYmxlIGFuZCBhcHBlbmRzIGFueSBXaW4zMi1zdHlsZQogICAgICogY29tbWFuZCBmaWxlcyBmb3IgdGhlIHNwZWNpZmllZCBjb21tYW5kIGxpbmUgYXJndW1lbnRzIGFuZCByZXR1cm4KICAgICAqIHRoZSByZXN1bHRpbmcgYXJndW1lbnRzLiBBIGNvbW1hbmQgZmlsZSBhcmd1bWVudAogICAgICogaXMgb2YgdGhlIGZvcm0gJ0BmaWxlJyB3aGVyZSAnZmlsZScgaXMgdGhlIG5hbWUgb2YgdGhlIGZpbGUgd2hvc2UKICAgICAqIGNvbnRlbnRzIGFyZSB0byBiZSBwYXJzZWQgZm9yIGFkZGl0aW9uYWwgYXJndW1lbnRzLiBUaGUgY29udGVudHMgb2YKICAgICAqIHRoZSBjb21tYW5kIGZpbGUgYXJlIHBhcnNlZCB1c2luZyBTdHJlYW1Ub2tlbml6ZXIgYW5kIHRoZSBvcmlnaW5hbAogICAgICogJ0BmaWxlJyBhcmd1bWVudCByZXBsYWNlZCB3aXRoIHRoZSByZXN1bHRpbmcgdG9rZW5zLiBSZWN1cnNpdmUgY29tbWFuZAogICAgICogZmlsZXMgYXJlIG5vdCBzdXBwb3J0ZWQuIFRoZSAnQCcgY2hhcmFjdGVyIGl0c2VsZiBjYW4gYmUgcXVvdGVkIHdpdGgKICAgICAqIHRoZSBzZXF1ZW5jZSAnQEAnLgogICAgICogQHBhcmFtIGVudlZhcmlhYmxlIHRoZSBlbnYgdmFyaWFibGUgdG8gcHJvY2VzcwogICAgICogQHBhcmFtIGFyZ3MgdGhlIGFyZ3VtZW50cyB0aGF0IG1heSBjb250YWluIEBmaWxlcwogICAgICogQHJldHVybiB0aGUgYXJndW1lbnRzLCB3aXRoIGVudmlyb25tZW50IHZhcmlhYmxlJ3MgY29udGVudCBhbmQgZXhwYW5zaW9uIG9mIEBmaWxlcwogICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiB0aGVyZSBpcyBhIHByb2JsZW0gcmVhZGluZyBhbnkgb2YgdGhlIEBmaWxlcwogICAgICogQHRocm93cyBjb20uc3VuLnRvb2xzLmphdmFjLm1haW4uQ29tbWFuZExpbmUuVW5tYXRjaGVkUXVvdGUKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBMaXN0PFN0cmluZz4gcGFyc2UoU3RyaW5nIGVudlZhcmlhYmxlLCBMaXN0PFN0cmluZz4gYXJncykKICAgICAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBVbm1hdGNoZWRRdW90ZSB7CgogICAgICAgIExpc3Q8U3RyaW5nPiBpbkFyZ3MgPSBuZXcgQXJyYXlMaXN0PD4oKTsKICAgICAgICBhcHBlbmRQYXJzZWRFbnZWYXJpYWJsZXMoaW5BcmdzLCBlbnZWYXJpYWJsZSk7CiAgICAgICAgaW5BcmdzLmFkZEFsbChhcmdzKTsKICAgICAgICBMaXN0PFN0cmluZz4gbmV3QXJncyA9IG5ldyBBcnJheUxpc3Q8PigpOwogICAgICAgIGFwcGVuZFBhcnNlZENvbW1hbmRBcmdzKG5ld0FyZ3MsIGluQXJncyk7CiAgICAgICAgcmV0dXJuIG5ld0FyZ3M7CiAgICB9CgogICAgLyoqCiAgICAgKiBQcm9jZXNzIHRoZSBnaXZlbiBlbnZpcm9ubWVudCB2YXJpYWJsZSBhbmQgYXBwZW5kcyBhbnkgV2luMzItc3R5bGUKICAgICAqIGNvbW1hbmQgZmlsZXMgZm9yIHRoZSBzcGVjaWZpZWQgY29tbWFuZCBsaW5lIGFyZ3VtZW50cyBhbmQgcmV0dXJuCiAgICAgKiB0aGUgcmVzdWx0aW5nIGFyZ3VtZW50cy4gQSBjb21tYW5kIGZpbGUgYXJndW1lbnQKICAgICAqIGlzIG9mIHRoZSBmb3JtICdAZmlsZScgd2hlcmUgJ2ZpbGUnIGlzIHRoZSBuYW1lIG9mIHRoZSBmaWxlIHdob3NlCiAgICAgKiBjb250ZW50cyBhcmUgdG8gYmUgcGFyc2VkIGZvciBhZGRpdGlvbmFsIGFyZ3VtZW50cy4gVGhlIGNvbnRlbnRzIG9mCiAgICAgKiB0aGUgY29tbWFuZCBmaWxlIGFyZSBwYXJzZWQgdXNpbmcgU3RyZWFtVG9rZW5pemVyIGFuZCB0aGUgb3JpZ2luYWwKICAgICAqICdAZmlsZScgYXJndW1lbnQgcmVwbGFjZWQgd2l0aCB0aGUgcmVzdWx0aW5nIHRva2Vucy4gUmVjdXJzaXZlIGNvbW1hbmQKICAgICAqIGZpbGVzIGFyZSBub3Qgc3VwcG9ydGVkLiBUaGUgJ0AnIGNoYXJhY3RlciBpdHNlbGYgY2FuIGJlIHF1b3RlZCB3aXRoCiAgICAgKiB0aGUgc2VxdWVuY2UgJ0BAJy4KICAgICAqIEBwYXJhbSBlbnZWYXJpYWJsZSB0aGUgZW52IHZhcmlhYmxlIHRvIHByb2Nlc3MKICAgICAqIEBwYXJhbSBhcmdzIHRoZSBhcmd1bWVudHMgdGhhdCBtYXkgY29udGFpbiBAZmlsZXMKICAgICAqIEByZXR1cm4gdGhlIGFyZ3VtZW50cywgd2l0aCBlbnZpcm9ubWVudCB2YXJpYWJsZSdzIGNvbnRlbnQgYW5kIGV4cGFuc2lvbiBvZiBAZmlsZXMKICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgdGhlcmUgaXMgYSBwcm9ibGVtIHJlYWRpbmcgYW55IG9mIHRoZSBAZmlsZXMKICAgICAqIEB0aHJvd3MgY29tLnN1bi50b29scy5qYXZhYy5tYWluLkNvbW1hbmRMaW5lLlVubWF0Y2hlZFF1b3RlCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nW10gcGFyc2UoU3RyaW5nIGVudlZhcmlhYmxlLCBTdHJpbmdbXSBhcmdzKSB0aHJvd3MgSU9FeGNlcHRpb24sIFVubWF0Y2hlZFF1b3RlIHsKICAgICAgICBMaXN0PFN0cmluZz4gb3V0ID0gcGFyc2UoZW52VmFyaWFibGUsIEFycmF5cy5hc0xpc3QoYXJncykpOwogICAgICAgIHJldHVybiBvdXQudG9BcnJheShuZXcgU3RyaW5nW291dC5zaXplKCldKTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGxvYWRDbWRGaWxlKFN0cmluZyBuYW1lLCBMaXN0PFN0cmluZz4gYXJncykgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICB0cnkgKFJlYWRlciByID0gRmlsZXMubmV3QnVmZmVyZWRSZWFkZXIoUGF0aHMuZ2V0KG5hbWUpKSkgewogICAgICAgICAgICBUb2tlbml6ZXIgdCA9IG5ldyBUb2tlbml6ZXIocik7CiAgICAgICAgICAgIFN0cmluZyBzOwogICAgICAgICAgICB3aGlsZSAoKHMgPSB0Lm5leHRUb2tlbigpKSAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICBhcmdzLmFkZChzKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIFRva2VuaXplciB7CiAgICAgICAgcHJpdmF0ZSBmaW5hbCBSZWFkZXIgaW47CiAgICAgICAgcHJpdmF0ZSBpbnQgY2g7CgogICAgICAgIHB1YmxpYyBUb2tlbml6ZXIoUmVhZGVyIGluKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgICAgICB0aGlzLmluID0gaW47CiAgICAgICAgICAgIGNoID0gaW4ucmVhZCgpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIFN0cmluZyBuZXh0VG9rZW4oKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgICAgICBza2lwV2hpdGUoKTsKICAgICAgICAgICAgaWYgKGNoID09IC0xKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CiAgICAgICAgICAgIGNoYXIgcXVvdGVDaGFyID0gMDsKCiAgICAgICAgICAgIHdoaWxlIChjaCAhPSAtMSkgewogICAgICAgICAgICAgICAgc3dpdGNoIChjaCkgewogICAgICAgICAgICAgICAgICAgIGNhc2UgJyAnOgogICAgICAgICAgICAgICAgICAgIGNhc2UgJ1x0JzoKICAgICAgICAgICAgICAgICAgICBjYXNlICdcZic6CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChxdW90ZUNoYXIgPT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgc2IuYXBwZW5kKChjaGFyKSBjaCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgICAgICBjYXNlICdcbic6CiAgICAgICAgICAgICAgICAgICAgY2FzZSAnXHInOgogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc2IudG9TdHJpbmcoKTsKCiAgICAgICAgICAgICAgICAgICAgY2FzZSAnXCcnOgogICAgICAgICAgICAgICAgICAgIGNhc2UgJyInOgogICAgICAgICAgICAgICAgICAgICAgICBpZiAocXVvdGVDaGFyID09IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHF1b3RlQ2hhciA9IChjaGFyKSBjaDsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChxdW90ZUNoYXIgPT0gY2gpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHF1b3RlQ2hhciA9IDA7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzYi5hcHBlbmQoKGNoYXIpIGNoKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICAgICAgY2FzZSAnXFwnOgogICAgICAgICAgICAgICAgICAgICAgICBpZiAocXVvdGVDaGFyICE9IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoID0gaW4ucmVhZCgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChjaCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ1xuJzoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdccic6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChjaCA9PSAnICcgfHwgY2ggPT0gJ1xuJyB8fCBjaCA9PSAnXHInIHx8IGNoID09ICdcdCcgfHwgY2ggPT0gJ1xmJykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2ggPSBpbi5yZWFkKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ24nOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaCA9ICdcbic7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ3InOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaCA9ICdccic7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ3QnOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaCA9ICdcdCc7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ2YnOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaCA9ICdcZic7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIHNiLmFwcGVuZCgoY2hhcikgY2gpOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgICAgc2IuYXBwZW5kKChjaGFyKSBjaCk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgY2ggPSBpbi5yZWFkKCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBzYi50b1N0cmluZygpOwogICAgICAgIH0KCiAgICAgICAgdm9pZCBza2lwV2hpdGUoKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgICAgICB3aGlsZSAoY2ggIT0gLTEpIHsKICAgICAgICAgICAgICAgIHN3aXRjaCAoY2gpIHsKICAgICAgICAgICAgICAgICAgICBjYXNlICcgJzoKICAgICAgICAgICAgICAgICAgICBjYXNlICdcdCc6CiAgICAgICAgICAgICAgICAgICAgY2FzZSAnXG4nOgogICAgICAgICAgICAgICAgICAgIGNhc2UgJ1xyJzoKICAgICAgICAgICAgICAgICAgICBjYXNlICdcZic6CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgICAgICBjYXNlICcjJzoKICAgICAgICAgICAgICAgICAgICAgICAgY2ggPSBpbi5yZWFkKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChjaCAhPSAnXG4nICYmIGNoICE9ICdccicgJiYgY2ggIT0gLTEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoID0gaW4ucmVhZCgpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgY2ggPSBpbi5yZWFkKCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgQFN1cHByZXNzV2FybmluZ3MoImZhbGx0aHJvdWdoIikKICAgIHByaXZhdGUgc3RhdGljIHZvaWQgYXBwZW5kUGFyc2VkRW52VmFyaWFibGVzKExpc3Q8U3RyaW5nPiBuZXdBcmdzLCBTdHJpbmcgZW52VmFyaWFibGUpCiAgICAgICAgICAgIHRocm93cyBVbm1hdGNoZWRRdW90ZSB7CgogICAgICAgIGlmIChlbnZWYXJpYWJsZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgU3RyaW5nIGluID0gU3lzdGVtLmdldGVudihlbnZWYXJpYWJsZSk7CiAgICAgICAgaWYgKGluID09IG51bGwgfHwgaW4udHJpbSgpLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICBmaW5hbCBjaGFyIE5VTCA9IChjaGFyKTA7CiAgICAgICAgZmluYWwgaW50IGxlbiA9IGluLmxlbmd0aCgpOwoKICAgICAgICBpbnQgcG9zID0gMDsKICAgICAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKICAgICAgICBjaGFyIHF1b3RlID0gTlVMOwogICAgICAgIGNoYXIgY2g7CgogICAgICAgIGxvb3A6CiAgICAgICAgd2hpbGUgKHBvcyA8IGxlbikgewogICAgICAgICAgICBjaCA9IGluLmNoYXJBdChwb3MpOwogICAgICAgICAgICBzd2l0Y2ggKGNoKSB7CiAgICAgICAgICAgICAgICBjYXNlICdcIic6IGNhc2UgJ1wnJzoKICAgICAgICAgICAgICAgICAgICBpZiAocXVvdGUgPT0gTlVMKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHF1b3RlID0gY2g7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChxdW90ZSA9PSBjaCkgewogICAgICAgICAgICAgICAgICAgICAgICBxdW90ZSA9IE5VTDsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBzYi5hcHBlbmQoY2gpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBwb3MrKzsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgJ1xmJzogY2FzZSAnXG4nOiBjYXNlICdccic6IGNhc2UgJ1x0JzogY2FzZSAnICc6CiAgICAgICAgICAgICAgICAgICAgaWYgKHF1b3RlID09IE5VTCkgewogICAgICAgICAgICAgICAgICAgICAgICBuZXdBcmdzLmFkZChzYi50b1N0cmluZygpKTsKICAgICAgICAgICAgICAgICAgICAgICAgc2Iuc2V0TGVuZ3RoKDApOwogICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoY2ggPT0gJ1xmJyB8fCBjaCA9PSAnXG4nIHx8IGNoID09ICdccicgfHwgY2ggPT0gJ1x0JyB8fCBjaCA9PSAnICcpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvcysrOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBvcyA+PSBsZW4pIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhayBsb29wOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2ggPSBpbi5jaGFyQXQocG9zKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgLy8gZmFsbCB0aHJvdWdoCiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgIHNiLmFwcGVuZChjaCk7CiAgICAgICAgICAgICAgICAgICAgcG9zKys7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKHNiLmxlbmd0aCgpICE9IDApIHsKICAgICAgICAgICAgbmV3QXJncy5hZGQoc2IudG9TdHJpbmcoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChxdW90ZSAhPSBOVUwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFVubWF0Y2hlZFF1b3RlKGVudlZhcmlhYmxlKTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjbGFzcyBVbm1hdGNoZWRRdW90ZSBleHRlbmRzIEV4Y2VwdGlvbiB7CiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMDsKCiAgICAgICAgcHVibGljIGZpbmFsIFN0cmluZyB2YXJpYWJsZU5hbWU7CgogICAgICAgIFVubWF0Y2hlZFF1b3RlKFN0cmluZyB2YXJpYWJsZSkgewogICAgICAgICAgICB0aGlzLnZhcmlhYmxlTmFtZSA9IHZhcmlhYmxlOwogICAgICAgIH0KICAgIH0KfQpQSwMECgAACAAABjupShgutTA1kAAANZAAACcAAABjb20vc3VuL3Rvb2xzL2phdmFjL21haW4vQXJndW1lbnRzLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDE5OTksIDIwMTcsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhYy5tYWluOwoKaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CmltcG9ydCBqYXZhLm5pby5maWxlLkZpbGVzOwppbXBvcnQgamF2YS5uaW8uZmlsZS5QYXRoOwppbXBvcnQgamF2YS5uaW8uZmlsZS5QYXRoczsKaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CmltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbjsKaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKaW1wb3J0IGphdmEudXRpbC5FbnVtU2V0OwppbXBvcnQgamF2YS51dGlsLkhhc2hTZXQ7CmltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CmltcG9ydCBqYXZhLnV0aWwuTGlua2VkSGFzaE1hcDsKaW1wb3J0IGphdmEudXRpbC5MaW5rZWRIYXNoU2V0OwppbXBvcnQgamF2YS51dGlsLk1hcDsKaW1wb3J0IGphdmEudXRpbC5TZXQ7CmltcG9ydCBqYXZhLnV0aWwucmVnZXguTWF0Y2hlcjsKaW1wb3J0IGphdmEudXRpbC5yZWdleC5QYXR0ZXJuOwppbXBvcnQgamF2YS51dGlsLnN0cmVhbS5TdHJlYW07CgppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5Tb3VyY2VWZXJzaW9uOwppbXBvcnQgamF2YXgudG9vbHMuSmF2YUZpbGVNYW5hZ2VyOwppbXBvcnQgamF2YXgudG9vbHMuSmF2YUZpbGVNYW5hZ2VyLkxvY2F0aW9uOwppbXBvcnQgamF2YXgudG9vbHMuSmF2YUZpbGVPYmplY3Q7CmltcG9ydCBqYXZheC50b29scy5KYXZhRmlsZU9iamVjdC5LaW5kOwppbXBvcnQgamF2YXgudG9vbHMuU3RhbmRhcmRKYXZhRmlsZU1hbmFnZXI7CmltcG9ydCBqYXZheC50b29scy5TdGFuZGFyZExvY2F0aW9uOwoKaW1wb3J0IGNvbS5zdW4udG9vbHMuZG9jbGludC5Eb2NMaW50OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLkxpbnQuTGludENhdGVnb3J5OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlNvdXJjZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuZmlsZS5CYXNlRmlsZU1hbmFnZXI7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmZpbGUuSmF2YWNGaWxlTWFuYWdlcjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuanZtLlByb2ZpbGU7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmp2bS5UYXJnZXQ7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLm1haW4uT3B0aW9uSGVscGVyLkdydW1weUhlbHBlcjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMucGxhdGZvcm0uUGxhdGZvcm1EZXNjcmlwdGlvbjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMucGxhdGZvcm0uUGxhdGZvcm1VdGlsczsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMucmVzb3VyY2VzLkNvbXBpbGVyUHJvcGVydGllcy5FcnJvcnM7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnJlc291cmNlcy5Db21waWxlclByb3BlcnRpZXMuV2FybmluZ3M7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuQ29udGV4dDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5KQ0RpYWdub3N0aWM7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuTGlzdDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5MaXN0QnVmZmVyOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkxvZzsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5Mb2cuUHJlZml4S2luZDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5Mb2cuV3JpdGVyS2luZDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5PcHRpb25zOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLlByb3BhZ2F0ZWRFeGNlcHRpb247CgovKioKICogU2hhcmVkIG9wdGlvbiBhbmQgYXJndW1lbnQgaGFuZGxpbmcgZm9yIGNvbW1hbmQgbGluZSBhbmQgQVBJIHVzYWdlIG9mIGphdmFjLgogKi8KcHVibGljIGNsYXNzIEFyZ3VtZW50cyB7CgogICAgLyoqCiAgICAgKiBUaGUgY29udGV4dCBrZXkgZm9yIHRoZSBhcmd1bWVudHMuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgQ29udGV4dC5LZXk8QXJndW1lbnRzPiBhcmdzS2V5ID0gbmV3IENvbnRleHQuS2V5PD4oKTsKCiAgICBwcml2YXRlIFN0cmluZyBvd25OYW1lOwogICAgcHJpdmF0ZSBTZXQ8U3RyaW5nPiBjbGFzc05hbWVzOwogICAgcHJpdmF0ZSBTZXQ8UGF0aD4gZmlsZXM7CiAgICBwcml2YXRlIE1hcDxPcHRpb24sIFN0cmluZz4gZGVmZXJyZWRGaWxlTWFuYWdlck9wdGlvbnM7CiAgICBwcml2YXRlIFNldDxKYXZhRmlsZU9iamVjdD4gZmlsZU9iamVjdHM7CiAgICBwcml2YXRlIGJvb2xlYW4gZW1wdHlBbGxvd2VkOwogICAgcHJpdmF0ZSBmaW5hbCBPcHRpb25zIG9wdGlvbnM7CgogICAgcHJpdmF0ZSBKYXZhRmlsZU1hbmFnZXIgZmlsZU1hbmFnZXI7CiAgICBwcml2YXRlIGZpbmFsIExvZyBsb2c7CiAgICBwcml2YXRlIGZpbmFsIENvbnRleHQgY29udGV4dDsKCiAgICBwcml2YXRlIGVudW0gRXJyb3JNb2RlIHsgSUxMRUdBTF9BUkdVTUVOVCwgSUxMRUdBTF9TVEFURSwgTE9HIH07CiAgICBwcml2YXRlIEVycm9yTW9kZSBlcnJvck1vZGU7CiAgICBwcml2YXRlIGJvb2xlYW4gZXJyb3JzOwoKICAgIC8qKgogICAgICogR2V0cyB0aGUgQXJndW1lbnRzIGluc3RhbmNlIGZvciB0aGlzIGNvbnRleHQuCiAgICAgKgogICAgICogQHBhcmFtIGNvbnRleHQgdGhlIGNvbnRlbnQKICAgICAqIEByZXR1cm4gdGhlIEFyZ3VtZW50cyBpbnN0YW5jZSBmb3IgdGhpcyBjb250ZXh0LgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIEFyZ3VtZW50cyBpbnN0YW5jZShDb250ZXh0IGNvbnRleHQpIHsKICAgICAgICBBcmd1bWVudHMgaW5zdGFuY2UgPSBjb250ZXh0LmdldChhcmdzS2V5KTsKICAgICAgICBpZiAoaW5zdGFuY2UgPT0gbnVsbCkgewogICAgICAgICAgICBpbnN0YW5jZSA9IG5ldyBBcmd1bWVudHMoY29udGV4dCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBpbnN0YW5jZTsKICAgIH0KCiAgICBwcm90ZWN0ZWQgQXJndW1lbnRzKENvbnRleHQgY29udGV4dCkgewogICAgICAgIGNvbnRleHQucHV0KGFyZ3NLZXksIHRoaXMpOwogICAgICAgIG9wdGlvbnMgPSBPcHRpb25zLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIGxvZyA9IExvZy5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICB0aGlzLmNvbnRleHQgPSBjb250ZXh0OwoKICAgICAgICAvLyBJZGVhbGx5LCB3ZSBjb3VsZCBpbml0IHRoaXMgaGVyZSBhbmQgdXBkYXRlL2NvbmZpZ3VyZSBpdCBhcwogICAgICAgIC8vIG5lZWRlZCwgYnV0IHJpZ2h0IG5vdywgaW5pdGlhbGl6aW5nIGEgZmlsZSBtYW5hZ2VyIHRyaWdnZXJzCiAgICAgICAgLy8gaW5pdGlhbGl6YXRpb24gb2Ygb3RoZXIgaXRlbXMgaW4gdGhlIGNvbnRleHQsIHN1Y2ggYXMgTGludAogICAgICAgIC8vIGFuZCBGU0luZm8sIHdoaWNoIHNob3VsZCBub3QgYmUgaW5pdGlhbGl6ZWQgdW50aWwgYWZ0ZXIKICAgICAgICAvLyBwcm9jZXNzQXJncwogICAgICAgIC8vICAgICAgICBmaWxlTWFuYWdlciA9IGNvbnRleHQuZ2V0KEphdmFGaWxlTWFuYWdlci5jbGFzcyk7CiAgICB9CgogICAgcHJpdmF0ZSBmaW5hbCBPcHRpb25IZWxwZXIgY21kTGluZUhlbHBlciA9IG5ldyBPcHRpb25IZWxwZXIoKSB7CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFN0cmluZyBnZXQoT3B0aW9uIG9wdGlvbikgewogICAgICAgICAgICByZXR1cm4gb3B0aW9ucy5nZXQob3B0aW9uKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHB1dChTdHJpbmcgbmFtZSwgU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgICAgIG9wdGlvbnMucHV0KG5hbWUsIHZhbHVlKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHJlbW92ZShTdHJpbmcgbmFtZSkgewogICAgICAgICAgICBvcHRpb25zLnJlbW92ZShuYW1lKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBib29sZWFuIGhhbmRsZUZpbGVNYW5hZ2VyT3B0aW9uKE9wdGlvbiBvcHRpb24sIFN0cmluZyB2YWx1ZSkgewogICAgICAgICAgICBvcHRpb25zLnB1dChvcHRpb24sIHZhbHVlKTsKICAgICAgICAgICAgZGVmZXJyZWRGaWxlTWFuYWdlck9wdGlvbnMucHV0KG9wdGlvbiwgdmFsdWUpOwogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBMb2cgZ2V0TG9nKCkgewogICAgICAgICAgICByZXR1cm4gbG9nOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFN0cmluZyBnZXRPd25OYW1lKCkgewogICAgICAgICAgICByZXR1cm4gb3duTmFtZTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIGFkZEZpbGUoUGF0aCBwKSB7CiAgICAgICAgICAgIGZpbGVzLmFkZChwKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIGFkZENsYXNzTmFtZShTdHJpbmcgcykgewogICAgICAgICAgICBjbGFzc05hbWVzLmFkZChzKTsKICAgICAgICB9CgogICAgfTsKCiAgICAvKioKICAgICAqIEluaXRpYWxpemVzIHRoaXMgQXJncyBpbnN0YW5jZSB3aXRoIGEgc2V0IG9mIGNvbW1hbmQgbGluZSBhcmdzLgogICAgICogVGhlIGFyZ3Mgd2lsbCBiZSBwcm9jZXNzZWQgaW4gY29uanVuY3Rpb24gd2l0aCB0aGUgZnVsbCBzZXQgb2YKICAgICAqIGNvbW1hbmQgbGluZSBvcHRpb25zLCBpbmNsdWRpbmcgLWhlbHAsIC12ZXJzaW9uIGV0Yy4KICAgICAqIFRoZSBhcmdzIG1heSBhbHNvIGNvbnRhaW4gY2xhc3MgbmFtZXMgYW5kIGZpbGVuYW1lcy4KICAgICAqIEFueSBlcnJvcnMgZHVyaW5nIHRoaXMgY2FsbCwgYW5kIGxhdGVyIGR1cmluZyB2YWxpZGF0ZSwgd2lsbCBiZSByZXBvcnRlZAogICAgICogdG8gdGhlIGxvZy4KICAgICAqIEBwYXJhbSBvd25OYW1lIHRoZSBuYW1lIG9mIHRoaXMgdG9vbDsgdXNlZCB0byBwcmVmaXggbWVzc2FnZXMKICAgICAqIEBwYXJhbSBhcmdzIHRoZSBhcmdzIHRvIGJlIHByb2Nlc3NlZAogICAgICovCiAgICBwdWJsaWMgdm9pZCBpbml0KFN0cmluZyBvd25OYW1lLCBTdHJpbmcuLi4gYXJncykgewogICAgICAgIHRoaXMub3duTmFtZSA9IG93bk5hbWU7CiAgICAgICAgZXJyb3JNb2RlID0gRXJyb3JNb2RlLkxPRzsKICAgICAgICBmaWxlcyA9IG5ldyBMaW5rZWRIYXNoU2V0PD4oKTsKICAgICAgICBkZWZlcnJlZEZpbGVNYW5hZ2VyT3B0aW9ucyA9IG5ldyBMaW5rZWRIYXNoTWFwPD4oKTsKICAgICAgICBmaWxlT2JqZWN0cyA9IG51bGw7CiAgICAgICAgY2xhc3NOYW1lcyA9IG5ldyBMaW5rZWRIYXNoU2V0PD4oKTsKICAgICAgICBwcm9jZXNzQXJncyhMaXN0LmZyb20oYXJncyksIE9wdGlvbi5nZXRKYXZhQ29tcGlsZXJPcHRpb25zKCksIGNtZExpbmVIZWxwZXIsIHRydWUsIGZhbHNlKTsKICAgICAgICBpZiAoZXJyb3JzKSB7CiAgICAgICAgICAgIGxvZy5wcmludExpbmVzKFByZWZpeEtpbmQuSkFWQUMsICJtc2cudXNhZ2UiLCBvd25OYW1lKTsKICAgICAgICB9CiAgICB9CgogICAgcHJpdmF0ZSBmaW5hbCBPcHRpb25IZWxwZXIgYXBpSGVscGVyID0gbmV3IEdydW1weUhlbHBlcihudWxsKSB7CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFN0cmluZyBnZXQoT3B0aW9uIG9wdGlvbikgewogICAgICAgICAgICByZXR1cm4gb3B0aW9ucy5nZXQob3B0aW9uKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHB1dChTdHJpbmcgbmFtZSwgU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgICAgIG9wdGlvbnMucHV0KG5hbWUsIHZhbHVlKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHJlbW92ZShTdHJpbmcgbmFtZSkgewogICAgICAgICAgICBvcHRpb25zLnJlbW92ZShuYW1lKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBMb2cgZ2V0TG9nKCkgewogICAgICAgICAgICByZXR1cm4gQXJndW1lbnRzLnRoaXMubG9nOwogICAgICAgIH0KICAgIH07CgogICAgLyoqCiAgICAgKiBJbml0aWFsaXplcyB0aGlzIEFyZ3MgaW5zdGFuY2Ugd2l0aCB0aGUgcGFyYW1ldGVycyBmb3IgYSBKYXZhY1Rhc2suCiAgICAgKiBUaGUgb3B0aW9ucyB3aWxsIGJlIHByb2Nlc3NlZCBpbiBjb25qdW5jdGlvbiB3aXRoIHRoZSByZXN0cmljdGVkIHNldAogICAgICogb2YgdG9vbCBvcHRpb25zLCB3aGljaCBkb2VzIG5vdCBpbmNsdWRlIC1oZWxwLCAtdmVyc2lvbiwgZXRjLAogICAgICogbm9yIGRvZXMgaXQgaW5jbHVkZSBjbGFzc2VzIGFuZCBmaWxlbmFtZXMsIHdoaWNoIHNob3VsZCBiZSBzcGVjaWZpZWQKICAgICAqIHNlcGFyYXRlbHkuCiAgICAgKiBGaWxlIG1hbmFnZXIgb3B0aW9ucyBhcmUgaGFuZGxlZCBkaXJlY3RseSBieSB0aGUgZmlsZSBtYW5hZ2VyLgogICAgICogQW55IGVycm9ycyBmb3VuZCB3aGlsZSBwcm9jZXNzaW5nIGluZGl2aWR1YWwgYXJncyB3aWxsIGJlIHJlcG9ydGVkCiAgICAgKiB2aWEgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLgogICAgICogQW55IHN1YnNlcXVlbnQgZXJyb3JzIGR1cmluZyB2YWxpZGF0ZSB3aWxsIGJlIHJlcG9ydGVkIHZpYSBJbGxlZ2FsU3RhdGVFeGNlcHRpb24uCiAgICAgKiBAcGFyYW0gb3duTmFtZSB0aGUgbmFtZSBvZiB0aGlzIHRvb2w7IHVzZWQgdG8gcHJlZml4IG1lc3NhZ2VzCiAgICAgKiBAcGFyYW0gb3B0aW9ucyB0aGUgb3B0aW9ucyB0byBiZSBwcm9jZXNzZWQKICAgICAqIEBwYXJhbSBjbGFzc05hbWVzIHRoZSBjbGFzc2VzIHRvIGJlIHN1YmplY3QgdG8gYW5ub3RhdGlvbiBwcm9jZXNzaW5nCiAgICAgKiBAcGFyYW0gZmlsZXMgdGhlIGZpbGVzIHRvIGJlIGNvbXBpbGVkCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIGluaXQoU3RyaW5nIG93bk5hbWUsCiAgICAgICAgICAgIEl0ZXJhYmxlPFN0cmluZz4gb3B0aW9ucywKICAgICAgICAgICAgSXRlcmFibGU8U3RyaW5nPiBjbGFzc05hbWVzLAogICAgICAgICAgICBJdGVyYWJsZTw/IGV4dGVuZHMgSmF2YUZpbGVPYmplY3Q+IGZpbGVzKSB7CiAgICAgICAgdGhpcy5vd25OYW1lID0gb3duTmFtZTsKICAgICAgICB0aGlzLmNsYXNzTmFtZXMgPSB0b1NldChjbGFzc05hbWVzKTsKICAgICAgICB0aGlzLmZpbGVPYmplY3RzID0gdG9TZXQoZmlsZXMpOwogICAgICAgIHRoaXMuZmlsZXMgPSBudWxsOwogICAgICAgIGVycm9yTW9kZSA9IEVycm9yTW9kZS5JTExFR0FMX0FSR1VNRU5UOwogICAgICAgIGlmIChvcHRpb25zICE9IG51bGwpIHsKICAgICAgICAgICAgcHJvY2Vzc0FyZ3ModG9MaXN0KG9wdGlvbnMpLCBPcHRpb24uZ2V0SmF2YWNUb29sT3B0aW9ucygpLCBhcGlIZWxwZXIsIGZhbHNlLCB0cnVlKTsKICAgICAgICB9CiAgICAgICAgZXJyb3JNb2RlID0gRXJyb3JNb2RlLklMTEVHQUxfU1RBVEU7CiAgICB9CgogICAgLyoqCiAgICAgKiBNaW5pbWFsIGluaXRpYWxpemF0aW9uIGZvciB0b29scywgbGlrZSBqYXZhZG9jLAogICAgICogdG8gYmUgYWJsZSB0byBwcm9jZXNzIGphdmFjIG9wdGlvbnMgZm9yIHRoZW1zZWx2ZXMsCiAgICAgKiBhbmQgdGhlbiBjYWxsIHZhbGlkYXRlLgogICAgICogQHBhcmFtIG93bk5hbWUgIHRoZSBuYW1lIG9mIHRoaXMgdG9vbDsgdXNlZCB0byBwcmVmaXggbWVzc2FnZXMKICAgICAqLwogICAgcHVibGljIHZvaWQgaW5pdChTdHJpbmcgb3duTmFtZSkgewogICAgICAgIHRoaXMub3duTmFtZSA9IG93bk5hbWU7CiAgICAgICAgZXJyb3JNb2RlID0gRXJyb3JNb2RlLkxPRzsKICAgIH0KCiAgICAvKioKICAgICAqIEdldHMgdGhlIGZpbGVzIHRvIGJlIGNvbXBpbGVkLgogICAgICogQHJldHVybiB0aGUgZmlsZXMgdG8gYmUgY29tcGlsZWQKICAgICAqLwogICAgcHVibGljIFNldDxKYXZhRmlsZU9iamVjdD4gZ2V0RmlsZU9iamVjdHMoKSB7CiAgICAgICAgaWYgKGZpbGVPYmplY3RzID09IG51bGwpIHsKICAgICAgICAgICAgZmlsZU9iamVjdHMgPSBuZXcgTGlua2VkSGFzaFNldDw+KCk7CiAgICAgICAgfQogICAgICAgIGlmIChmaWxlcyAhPSBudWxsKSB7CiAgICAgICAgICAgIEphdmFjRmlsZU1hbmFnZXIgamZtID0gKEphdmFjRmlsZU1hbmFnZXIpIGdldEZpbGVNYW5hZ2VyKCk7CiAgICAgICAgICAgIGZvciAoSmF2YUZpbGVPYmplY3QgZm86IGpmbS5nZXRKYXZhRmlsZU9iamVjdHNGcm9tUGF0aHMoZmlsZXMpKQogICAgICAgICAgICAgICAgZmlsZU9iamVjdHMuYWRkKGZvKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpbGVPYmplY3RzOwogICAgfQoKICAgIC8qKgogICAgICogR2V0cyB0aGUgY2xhc3NlcyB0byBiZSBzdWJqZWN0IHRvIGFubm90YXRpb24gcHJvY2Vzc2luZy4KICAgICAqIEByZXR1cm4gdGhlIGNsYXNzZXMgdG8gYmUgc3ViamVjdCB0byBhbm5vdGF0aW9uIHByb2Nlc3NpbmcKICAgICAqLwogICAgcHVibGljIFNldDxTdHJpbmc+IGdldENsYXNzTmFtZXMoKSB7CiAgICAgICAgcmV0dXJuIGNsYXNzTmFtZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBQcm9jZXNzZXMgc3RyaW5ncyBjb250YWluaW5nIG9wdGlvbnMgYW5kIG9wZXJhbmRzLgogICAgICogQHBhcmFtIGFyZ3MgdGhlIHN0cmluZ3MgdG8gYmUgcHJvY2Vzc2VkCiAgICAgKiBAcGFyYW0gYWxsb3dhYmxlT3B0cyB0aGUgc2V0IG9mIG9wdGlvbiBkZWNsYXJhdGlvbnMgdGhhdCBhcmUgYXBwbGljYWJsZQogICAgICogQHBhcmFtIGhlbHBlciBhIGhlbHAgZm9yIHVzZSBieSBPcHRpb24ucHJvY2VzcwogICAgICogQHBhcmFtIGFsbG93T3BlcmFuZHMgd2hldGhlciBvciBub3QgdG8gY2hlY2sgZm9yIGZpbGVzIGFuZCBjbGFzc2VzCiAgICAgKiBAcGFyYW0gY2hlY2tGaWxlTWFuYWdlciB3aGV0aGVyIG9yIG5vdCB0byBjaGVjayBpZiB0aGUgZmlsZSBtYW5hZ2VyIGNhbiBoYW5kbGUKICAgICAqICAgICAgb3B0aW9ucyB3aGljaCBhcmUgbm90IHJlY29nbml6ZWQgYnkgYW55IG9mIGFsbG93YWJsZU9wdHMKICAgICAqIEByZXR1cm4gdHJ1ZSBpZiBhbGwgdGhlIHN0cmluZ3Mgd2VyZSBzdWNjZXNzZnVsbHkgcHJvY2Vzc2VkOyBmYWxzZSBvdGhlcndpc2UKICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIGEgcHJvYmxlbSBvY2N1cnMgYW5kIGVycm9yTW9kZSBpcyBzZXQgdG8KICAgICAqICAgICAgSUxMRUdBTF9BUkdVTUVOVAogICAgICovCiAgICBwcml2YXRlIGJvb2xlYW4gcHJvY2Vzc0FyZ3MoSXRlcmFibGU8U3RyaW5nPiBhcmdzLAogICAgICAgICAgICBTZXQ8T3B0aW9uPiBhbGxvd2FibGVPcHRzLCBPcHRpb25IZWxwZXIgaGVscGVyLAogICAgICAgICAgICBib29sZWFuIGFsbG93T3BlcmFuZHMsIGJvb2xlYW4gY2hlY2tGaWxlTWFuYWdlcikgewogICAgICAgIGlmICghZG9Qcm9jZXNzQXJncyhhcmdzLCBhbGxvd2FibGVPcHRzLCBoZWxwZXIsIGFsbG93T3BlcmFuZHMsIGNoZWNrRmlsZU1hbmFnZXIpKQogICAgICAgICAgICByZXR1cm4gZmFsc2U7CgogICAgICAgIFN0cmluZyBwbGF0Zm9ybVN0cmluZyA9IG9wdGlvbnMuZ2V0KE9wdGlvbi5SRUxFQVNFKTsKCiAgICAgICAgY2hlY2tPcHRpb25BbGxvd2VkKHBsYXRmb3JtU3RyaW5nID09IG51bGwsCiAgICAgICAgICAgICAgICBvcHRpb24gLT4gZXJyb3IoImVyci5yZWxlYXNlLmJvb3RjbGFzc3BhdGguY29uZmxpY3QiLCBvcHRpb24uZ2V0UHJpbWFyeU5hbWUoKSksCiAgICAgICAgICAgICAgICBPcHRpb24uQk9PVF9DTEFTU19QQVRILCBPcHRpb24uWEJPT1RDTEFTU1BBVEgsIE9wdGlvbi5YQk9PVENMQVNTUEFUSF9BUFBFTkQsCiAgICAgICAgICAgICAgICBPcHRpb24uWEJPT1RDTEFTU1BBVEhfUFJFUEVORCwKICAgICAgICAgICAgICAgIE9wdGlvbi5FTkRPUlNFRERJUlMsIE9wdGlvbi5ESkFWQV9FTkRPUlNFRF9ESVJTLAogICAgICAgICAgICAgICAgT3B0aW9uLkVYVERJUlMsIE9wdGlvbi5ESkFWQV9FWFRfRElSUywKICAgICAgICAgICAgICAgIE9wdGlvbi5TT1VSQ0UsIE9wdGlvbi5UQVJHRVQpOwoKICAgICAgICBpZiAocGxhdGZvcm1TdHJpbmcgIT0gbnVsbCkgewogICAgICAgICAgICBQbGF0Zm9ybURlc2NyaXB0aW9uIHBsYXRmb3JtRGVzY3JpcHRpb24gPSBQbGF0Zm9ybVV0aWxzLmxvb2t1cFBsYXRmb3JtRGVzY3JpcHRpb24ocGxhdGZvcm1TdHJpbmcpOwoKICAgICAgICAgICAgaWYgKHBsYXRmb3JtRGVzY3JpcHRpb24gPT0gbnVsbCkgewogICAgICAgICAgICAgICAgZXJyb3IoImVyci51bnN1cHBvcnRlZC5yZWxlYXNlLnZlcnNpb24iLCBwbGF0Zm9ybVN0cmluZyk7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIG9wdGlvbnMucHV0KE9wdGlvbi5TT1VSQ0UsIHBsYXRmb3JtRGVzY3JpcHRpb24uZ2V0U291cmNlVmVyc2lvbigpKTsKICAgICAgICAgICAgb3B0aW9ucy5wdXQoT3B0aW9uLlRBUkdFVCwgcGxhdGZvcm1EZXNjcmlwdGlvbi5nZXRUYXJnZXRWZXJzaW9uKCkpOwoKICAgICAgICAgICAgY29udGV4dC5wdXQoUGxhdGZvcm1EZXNjcmlwdGlvbi5jbGFzcywgcGxhdGZvcm1EZXNjcmlwdGlvbik7CgogICAgICAgICAgICBpZiAoIWRvUHJvY2Vzc0FyZ3MocGxhdGZvcm1EZXNjcmlwdGlvbi5nZXRBZGRpdGlvbmFsT3B0aW9ucygpLCBhbGxvd2FibGVPcHRzLCBoZWxwZXIsIGFsbG93T3BlcmFuZHMsIGNoZWNrRmlsZU1hbmFnZXIpKQogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwoKICAgICAgICAgICAgQ29sbGVjdGlvbjxQYXRoPiBwbGF0Zm9ybUNQID0gcGxhdGZvcm1EZXNjcmlwdGlvbi5nZXRQbGF0Zm9ybVBhdGgoKTsKCiAgICAgICAgICAgIGlmIChwbGF0Zm9ybUNQICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIEphdmFGaWxlTWFuYWdlciBmbSA9IGdldEZpbGVNYW5hZ2VyKCk7CgogICAgICAgICAgICAgICAgaWYgKCEoZm0gaW5zdGFuY2VvZiBTdGFuZGFyZEphdmFGaWxlTWFuYWdlcikpIHsKICAgICAgICAgICAgICAgICAgICBlcnJvcigiZXJyLnJlbGVhc2Uubm90LnN0YW5kYXJkLmZpbGUubWFuYWdlciIpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIFN0YW5kYXJkSmF2YUZpbGVNYW5hZ2VyIHNmbSA9IChTdGFuZGFyZEphdmFGaWxlTWFuYWdlcikgZm07CgogICAgICAgICAgICAgICAgICAgIHNmbS5zZXRMb2NhdGlvbkZyb21QYXRocyhTdGFuZGFyZExvY2F0aW9uLlBMQVRGT1JNX0NMQVNTX1BBVEgsIHBsYXRmb3JtQ1ApOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKICAgICAgICAgICAgICAgICAgICBsb2cucHJpbnRMaW5lcyhQcmVmaXhLaW5kLkpBVkFDLCAibXNnLmlvIik7CiAgICAgICAgICAgICAgICAgICAgZXgucHJpbnRTdGFja1RyYWNlKGxvZy5nZXRXcml0ZXIoV3JpdGVyS2luZC5OT1RJQ0UpKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIG9wdGlvbnMubm90aWZ5TGlzdGVuZXJzKCk7CgogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIHByaXZhdGUgYm9vbGVhbiBkb1Byb2Nlc3NBcmdzKEl0ZXJhYmxlPFN0cmluZz4gYXJncywKICAgICAgICAgICAgU2V0PE9wdGlvbj4gYWxsb3dhYmxlT3B0cywgT3B0aW9uSGVscGVyIGhlbHBlciwKICAgICAgICAgICAgYm9vbGVhbiBhbGxvd09wZXJhbmRzLCBib29sZWFuIGNoZWNrRmlsZU1hbmFnZXIpIHsKICAgICAgICBKYXZhRmlsZU1hbmFnZXIgZm0gPSBjaGVja0ZpbGVNYW5hZ2VyID8gZ2V0RmlsZU1hbmFnZXIoKSA6IG51bGw7CiAgICAgICAgSXRlcmF0b3I8U3RyaW5nPiBhcmdJdGVyID0gYXJncy5pdGVyYXRvcigpOwogICAgICAgIHdoaWxlIChhcmdJdGVyLmhhc05leHQoKSkgewogICAgICAgICAgICBTdHJpbmcgYXJnID0gYXJnSXRlci5uZXh0KCk7CiAgICAgICAgICAgIGlmIChhcmcuaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgICBlcnJvcigiZXJyLmludmFsaWQuZmxhZyIsIGFyZyk7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIE9wdGlvbiBvcHRpb24gPSBudWxsOwoKICAgICAgICAgICAgLy8gZmlyc3QsIGNoZWNrIHRoZSBwcm92aWRlZCBzZXQgb2YgamF2YWMgb3B0aW9ucwogICAgICAgICAgICBpZiAoYXJnLnN0YXJ0c1dpdGgoIi0iKSkgewogICAgICAgICAgICAgICAgb3B0aW9uID0gT3B0aW9uLmxvb2t1cChhcmcsIGFsbG93YWJsZU9wdHMpOwogICAgICAgICAgICB9IGVsc2UgaWYgKGFsbG93T3BlcmFuZHMgJiYgT3B0aW9uLlNPVVJDRUZJTEUubWF0Y2hlcyhhcmcpKSB7CiAgICAgICAgICAgICAgICBvcHRpb24gPSBPcHRpb24uU09VUkNFRklMRTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKG9wdGlvbiAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIG9wdGlvbi5oYW5kbGVPcHRpb24oaGVscGVyLCBhcmcsIGFyZ0l0ZXIpOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoT3B0aW9uLkludmFsaWRWYWx1ZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgICAgICAgZXJyb3IoZSk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIGNoZWNrIGZpbGUgbWFuYWdlciBvcHRpb24KICAgICAgICAgICAgaWYgKGZtICE9IG51bGwgJiYgZm0uaGFuZGxlT3B0aW9uKGFyZywgYXJnSXRlcikpIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBub25lIG9mIHRoZSBhYm92ZQogICAgICAgICAgICBlcnJvcigiZXJyLmludmFsaWQuZmxhZyIsIGFyZyk7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIC8qKgogICAgICogVmFsaWRhdGVzIHRoZSBvdmVyYWxsIGNvbnNpc3RlbmN5IG9mIHRoZSBvcHRpb25zIGFuZCBvcGVyYW5kcwogICAgICogcHJvY2Vzc2VkIGJ5IHByb2Nlc3NPcHRpb25zLgogICAgICogQHJldHVybiB0cnVlIGlmIGFsbCBhcmdzIGFyZSBzdWNjZXNzZnVsbHkgdmFsaWRhdGVkOyBmYWxzZSBvdGhlcndpc2UuCiAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiBhIHByb2JsZW0gaXMgZm91bmQgYW5kIGVycm9yTW9kZSBpcyBzZXQgdG8KICAgICAqICAgICAgSUxMRUdBTF9TVEFURQogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiB2YWxpZGF0ZSgpIHsKICAgICAgICBKYXZhRmlsZU1hbmFnZXIgZm0gPSBnZXRGaWxlTWFuYWdlcigpOwogICAgICAgIGlmIChvcHRpb25zLmlzU2V0KE9wdGlvbi5NT0RVTEUpKSB7CiAgICAgICAgICAgIGlmICghZm0uaGFzTG9jYXRpb24oU3RhbmRhcmRMb2NhdGlvbi5DTEFTU19PVVRQVVQpKSB7CiAgICAgICAgICAgICAgICBsb2cuZXJyb3IoRXJyb3JzLk91dHB1dERpck11c3RCZVNwZWNpZmllZFdpdGhEYXNoTU9wdGlvbik7CiAgICAgICAgICAgIH0gZWxzZSBpZiAoIWZtLmhhc0xvY2F0aW9uKFN0YW5kYXJkTG9jYXRpb24uTU9EVUxFX1NPVVJDRV9QQVRIKSkgewogICAgICAgICAgICAgICAgbG9nLmVycm9yKEVycm9ycy5Nb2R1bGVzb3VyY2VwYXRoTXVzdEJlU3BlY2lmaWVkV2l0aERhc2hNT3B0aW9uKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGphdmEudXRpbC5MaXN0PFN0cmluZz4gbW9kdWxlcyA9IEFycmF5cy5hc0xpc3Qob3B0aW9ucy5nZXQoT3B0aW9uLk1PRFVMRSkuc3BsaXQoIiwiKSk7CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIGZvciAoU3RyaW5nIG1vZHVsZSA6IG1vZHVsZXMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgTG9jYXRpb24gc291cmNlTG9jID0gZm0uZ2V0TG9jYXRpb25Gb3JNb2R1bGUoU3RhbmRhcmRMb2NhdGlvbi5NT0RVTEVfU09VUkNFX1BBVEgsIG1vZHVsZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzb3VyY2VMb2MgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9nLmVycm9yKEVycm9ycy5Nb2R1bGVOb3RGb3VuZEluTW9kdWxlU291cmNlUGF0aChtb2R1bGUpKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIExvY2F0aW9uIGNsYXNzTG9jID0gZm0uZ2V0TG9jYXRpb25Gb3JNb2R1bGUoU3RhbmRhcmRMb2NhdGlvbi5DTEFTU19PVVRQVVQsIG1vZHVsZSk7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChKYXZhRmlsZU9iamVjdCBmaWxlIDogZm0ubGlzdChzb3VyY2VMb2MsICIiLCBFbnVtU2V0Lm9mKEphdmFGaWxlT2JqZWN0LktpbmQuU09VUkNFKSwgdHJ1ZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgY2xhc3NOYW1lID0gZm0uaW5mZXJCaW5hcnlOYW1lKHNvdXJjZUxvYywgZmlsZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSmF2YUZpbGVPYmplY3QgY2xhc3NGaWxlID0gZm0uZ2V0SmF2YUZpbGVGb3JJbnB1dChjbGFzc0xvYywgY2xhc3NOYW1lLCBLaW5kLkNMQVNTKTsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNsYXNzRmlsZSA9PSBudWxsIHx8IGNsYXNzRmlsZS5nZXRMYXN0TW9kaWZpZWQoKSA8IGZpbGUuZ2V0TGFzdE1vZGlmaWVkKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZpbGVPYmplY3RzID09IG51bGwpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlT2JqZWN0cyA9IG5ldyBIYXNoU2V0PD4oKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZU9iamVjdHMuYWRkKGZpbGUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7CiAgICAgICAgICAgICAgICAgICAgbG9nLnByaW50TGluZXMoUHJlZml4S2luZC5KQVZBQywgIm1zZy5pbyIpOwogICAgICAgICAgICAgICAgICAgIGV4LnByaW50U3RhY2tUcmFjZShsb2cuZ2V0V3JpdGVyKFdyaXRlcktpbmQuTk9USUNFKSk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIC8vIEl0IGlzIGFsbG93ZWQgdG8gY29tcGlsZSBub3RoaW5nIGlmIGp1c3QgYXNraW5nIGZvciBoZWxwIG9yIHZlcnNpb24gaW5mby4KICAgICAgICAgICAgLy8gQnV0IGFsc28gbm90ZSB0aGF0IG5vbmUgb2YgdGhlc2Ugb3B0aW9ucyBhcmUgc3VwcG9ydGVkIGluIEFQSSBtb2RlLgogICAgICAgICAgICBpZiAob3B0aW9ucy5pc1NldChPcHRpb24uSEVMUCkKICAgICAgICAgICAgICAgICAgICB8fCBvcHRpb25zLmlzU2V0KE9wdGlvbi5YKQogICAgICAgICAgICAgICAgICAgIHx8IG9wdGlvbnMuaXNTZXQoT3B0aW9uLlZFUlNJT04pCiAgICAgICAgICAgICAgICAgICAgfHwgb3B0aW9ucy5pc1NldChPcHRpb24uRlVMTFZFUlNJT04pCiAgICAgICAgICAgICAgICAgICAgfHwgb3B0aW9ucy5pc1NldChPcHRpb24uTU9EVUxFKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICghZW1wdHlBbGxvd2VkKSB7CiAgICAgICAgICAgICAgICBpZiAoIWVycm9ycykgewogICAgICAgICAgICAgICAgICAgIGlmIChKYXZhQ29tcGlsZXIuZXhwbGljaXRBbm5vdGF0aW9uUHJvY2Vzc2luZ1JlcXVlc3RlZChvcHRpb25zKSkgewogICAgICAgICAgICAgICAgICAgICAgICBlcnJvcigiZXJyLm5vLnNvdXJjZS5maWxlcy5jbGFzc2VzIik7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3IoImVyci5uby5zb3VyY2UuZmlsZXMiKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICghY2hlY2tEaXJlY3RvcnkoT3B0aW9uLkQpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgaWYgKCFjaGVja0RpcmVjdG9yeShPcHRpb24uUykpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICBpZiAoIWNoZWNrRGlyZWN0b3J5KE9wdGlvbi5IKSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICAvLyBUaGUgZm9sbG93aW5nIGNoZWNrcyBhcmUgdG8gaGVscCBhdm9pZCBhY2NpZGVudGFsIGNvbmZ1c2lvbiBiZXR3ZWVuCiAgICAgICAgLy8gZGlyZWN0b3JpZXMgb2YgbW9kdWxlcyBhbmQgZXhwbG9kZWQgbW9kdWxlIGRpcmVjdG9yaWVzLgogICAgICAgIGlmIChmbSBpbnN0YW5jZW9mIFN0YW5kYXJkSmF2YUZpbGVNYW5hZ2VyKSB7CiAgICAgICAgICAgIFN0YW5kYXJkSmF2YUZpbGVNYW5hZ2VyIHNmbSA9IChTdGFuZGFyZEphdmFGaWxlTWFuYWdlcikgZmlsZU1hbmFnZXI7CiAgICAgICAgICAgIGlmIChzZm0uaGFzTG9jYXRpb24oU3RhbmRhcmRMb2NhdGlvbi5DTEFTU19PVVRQVVQpKSB7CiAgICAgICAgICAgICAgICBQYXRoIG91dERpciA9IHNmbS5nZXRMb2NhdGlvbkFzUGF0aHMoU3RhbmRhcmRMb2NhdGlvbi5DTEFTU19PVVRQVVQpLml0ZXJhdG9yKCkubmV4dCgpOwogICAgICAgICAgICAgICAgaWYgKHNmbS5oYXNMb2NhdGlvbihTdGFuZGFyZExvY2F0aW9uLk1PRFVMRV9TT1VSQ0VfUEFUSCkpIHsKICAgICAgICAgICAgICAgICAgICAvLyBtdWx0aS1tb2R1bGUgbW9kZQogICAgICAgICAgICAgICAgICAgIGlmIChGaWxlcy5leGlzdHMob3V0RGlyLnJlc29sdmUoIm1vZHVsZS1pbmZvLmNsYXNzIikpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGxvZy5lcnJvcihFcnJvcnMuTXVsdGlNb2R1bGVPdXRkaXJDYW5ub3RCZUV4cGxvZGVkTW9kdWxlKG91dERpcikpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgLy8gc2luZ2xlLW1vZHVsZSBvciBsZWdhY3kgbW9kZQogICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gbGludFBhdGhzID0gb3B0aW9ucy5pc1Vuc2V0KE9wdGlvbi5YTElOVF9DVVNUT00sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiLSIgKyBMaW50Q2F0ZWdvcnkuUEFUSC5vcHRpb24pOwogICAgICAgICAgICAgICAgICAgIGlmIChsaW50UGF0aHMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgUGF0aCBvdXREaXJQYXJlbnQgPSBvdXREaXIuZ2V0UGFyZW50KCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvdXREaXJQYXJlbnQgIT0gbnVsbCAmJiBGaWxlcy5leGlzdHMob3V0RGlyUGFyZW50LnJlc29sdmUoIm1vZHVsZS1pbmZvLmNsYXNzIikpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2cud2FybmluZyhMaW50Q2F0ZWdvcnkuUEFUSCwgV2FybmluZ3MuT3V0ZGlySXNJbkV4cGxvZGVkTW9kdWxlKG91dERpcikpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKCiAgICAgICAgU3RyaW5nIHNvdXJjZVN0cmluZyA9IG9wdGlvbnMuZ2V0KE9wdGlvbi5TT1VSQ0UpOwogICAgICAgIFNvdXJjZSBzb3VyY2UgPSAoc291cmNlU3RyaW5nICE9IG51bGwpCiAgICAgICAgICAgICAgICA/IFNvdXJjZS5sb29rdXAoc291cmNlU3RyaW5nKQogICAgICAgICAgICAgICAgOiBTb3VyY2UuREVGQVVMVDsKICAgICAgICBTdHJpbmcgdGFyZ2V0U3RyaW5nID0gb3B0aW9ucy5nZXQoT3B0aW9uLlRBUkdFVCk7CiAgICAgICAgVGFyZ2V0IHRhcmdldCA9ICh0YXJnZXRTdHJpbmcgIT0gbnVsbCkKICAgICAgICAgICAgICAgID8gVGFyZ2V0Lmxvb2t1cCh0YXJnZXRTdHJpbmcpCiAgICAgICAgICAgICAgICA6IFRhcmdldC5ERUZBVUxUOwoKICAgICAgICAvLyBXZSBkb24ndCBjaGVjayBzb3VyY2UvdGFyZ2V0IGNvbnNpc3RlbmN5IGZvciBDTERDLCBhcyBKMk1FCiAgICAgICAgLy8gcHJvZmlsZXMgYXJlIG5vdCBhbGlnbmVkIHdpdGggSjJTRSB0YXJnZXRzOyBtb3Jlb3ZlciwgYQogICAgICAgIC8vIHNpbmdsZSBDTERDIHRhcmdldCBtYXkgaGF2ZSBtYW55IHByb2ZpbGVzLiAgSW4gYWRkaXRpb24sCiAgICAgICAgLy8gdGhpcyBpcyBuZWVkZWQgZm9yIHRoZSBjb250aW51ZWQgZnVuY3Rpb25pbmcgb2YgdGhlIEpTUjE0CiAgICAgICAgLy8gcHJvdG90eXBlLgogICAgICAgIGlmIChDaGFyYWN0ZXIuaXNEaWdpdCh0YXJnZXQubmFtZS5jaGFyQXQoMCkpKSB7CiAgICAgICAgICAgIGlmICh0YXJnZXQuY29tcGFyZVRvKHNvdXJjZS5yZXF1aXJlZFRhcmdldCgpKSA8IDApIHsKICAgICAgICAgICAgICAgIGlmICh0YXJnZXRTdHJpbmcgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIGlmIChzb3VyY2VTdHJpbmcgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICBlcnJvcigid2Fybi50YXJnZXQuZGVmYXVsdC5zb3VyY2UuY29uZmxpY3QiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldFN0cmluZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzb3VyY2UucmVxdWlyZWRUYXJnZXQoKS5uYW1lKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBlcnJvcigid2Fybi5zb3VyY2UudGFyZ2V0LmNvbmZsaWN0IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzb3VyY2VTdHJpbmcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc291cmNlLnJlcXVpcmVkVGFyZ2V0KCkubmFtZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0ID0gc291cmNlLnJlcXVpcmVkVGFyZ2V0KCk7CiAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5wdXQoIi10YXJnZXQiLCB0YXJnZXQubmFtZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIFN0cmluZyBwcm9maWxlU3RyaW5nID0gb3B0aW9ucy5nZXQoT3B0aW9uLlBST0ZJTEUpOwogICAgICAgIGlmIChwcm9maWxlU3RyaW5nICE9IG51bGwpIHsKICAgICAgICAgICAgUHJvZmlsZSBwcm9maWxlID0gUHJvZmlsZS5sb29rdXAocHJvZmlsZVN0cmluZyk7CiAgICAgICAgICAgIGlmICghcHJvZmlsZS5pc1ZhbGlkKHRhcmdldCkpIHsKICAgICAgICAgICAgICAgIGVycm9yKCJ3YXJuLnByb2ZpbGUudGFyZ2V0LmNvbmZsaWN0IiwgcHJvZmlsZVN0cmluZywgdGFyZ2V0Lm5hbWUpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBUaGlzIGNoZWNrIGlzIG9ubHkgZWZmZWN0aXZlIGluIGNvbW1hbmQgbGluZSBtb2RlLAogICAgICAgICAgICAvLyB3aGVyZSB0aGUgZmlsZSBtYW5hZ2VyIG9wdGlvbnMgYXJlIGFkZGVkIHRvIG9wdGlvbnMKICAgICAgICAgICAgaWYgKG9wdGlvbnMuZ2V0KE9wdGlvbi5CT09UX0NMQVNTX1BBVEgpICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIGVycm9yKCJlcnIucHJvZmlsZS5ib290Y2xhc3NwYXRoLmNvbmZsaWN0Iik7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmIChvcHRpb25zLmlzU2V0KE9wdGlvbi5TT1VSQ0VfUEFUSCkgJiYgb3B0aW9ucy5pc1NldChPcHRpb24uTU9EVUxFX1NPVVJDRV9QQVRIKSkgewogICAgICAgICAgICBlcnJvcigiZXJyLnNvdXJjZXBhdGgubW9kdWxlc291cmNlcGF0aC5jb25mbGljdCIpOwogICAgICAgIH0KCiAgICAgICAgYm9vbGVhbiBsaW50T3B0aW9ucyA9IG9wdGlvbnMuaXNVbnNldChPcHRpb24uWExJTlRfQ1VTVE9NLCAiLSIgKyBMaW50Q2F0ZWdvcnkuT1BUSU9OUy5vcHRpb24pOwogICAgICAgIGlmIChsaW50T3B0aW9ucyAmJiBzb3VyY2UuY29tcGFyZVRvKFNvdXJjZS5ERUZBVUxUKSA8IDAgJiYgIW9wdGlvbnMuaXNTZXQoT3B0aW9uLlJFTEVBU0UpKSB7CiAgICAgICAgICAgIGlmIChmbSBpbnN0YW5jZW9mIEJhc2VGaWxlTWFuYWdlcikgewogICAgICAgICAgICAgICAgaWYgKCgoQmFzZUZpbGVNYW5hZ2VyKSBmbSkuaXNEZWZhdWx0Qm9vdENsYXNzUGF0aCgpKQogICAgICAgICAgICAgICAgICAgIGxvZy53YXJuaW5nKExpbnRDYXRlZ29yeS5PUFRJT05TLCAic291cmNlLm5vLmJvb3RjbGFzc3BhdGgiLCBzb3VyY2UubmFtZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGJvb2xlYW4gb2Jzb2xldGVPcHRpb25Gb3VuZCA9IGZhbHNlOwoKICAgICAgICBpZiAoc291cmNlLmNvbXBhcmVUbyhTb3VyY2UuTUlOKSA8IDApIHsKICAgICAgICAgICAgbG9nLmVycm9yKEVycm9ycy5PcHRpb25SZW1vdmVkU291cmNlKHNvdXJjZS5uYW1lLCBTb3VyY2UuTUlOLm5hbWUpKTsKICAgICAgICB9IGVsc2UgaWYgKHNvdXJjZSA9PSBTb3VyY2UuTUlOICYmIGxpbnRPcHRpb25zKSB7CiAgICAgICAgICAgIGxvZy53YXJuaW5nKExpbnRDYXRlZ29yeS5PUFRJT05TLCBXYXJuaW5ncy5PcHRpb25PYnNvbGV0ZVNvdXJjZShzb3VyY2UubmFtZSkpOwogICAgICAgICAgICBvYnNvbGV0ZU9wdGlvbkZvdW5kID0gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIGlmICh0YXJnZXQuY29tcGFyZVRvKFRhcmdldC5NSU4pIDwgMCkgewogICAgICAgICAgICBsb2cuZXJyb3IoRXJyb3JzLk9wdGlvblJlbW92ZWRUYXJnZXQodGFyZ2V0Lm5hbWUsIFRhcmdldC5NSU4ubmFtZSkpOwogICAgICAgIH0gZWxzZSBpZiAodGFyZ2V0ID09IFRhcmdldC5NSU4gJiYgbGludE9wdGlvbnMpIHsKICAgICAgICAgICAgbG9nLndhcm5pbmcoTGludENhdGVnb3J5Lk9QVElPTlMsIFdhcm5pbmdzLk9wdGlvbk9ic29sZXRlVGFyZ2V0KHRhcmdldC5uYW1lKSk7CiAgICAgICAgICAgIG9ic29sZXRlT3B0aW9uRm91bmQgPSB0cnVlOwogICAgICAgIH0KCiAgICAgICAgZmluYWwgVGFyZ2V0IHQgPSB0YXJnZXQ7CiAgICAgICAgY2hlY2tPcHRpb25BbGxvd2VkKHQuY29tcGFyZVRvKFRhcmdldC5KREsxXzgpIDw9IDAsCiAgICAgICAgICAgICAgICBvcHRpb24gLT4gZXJyb3IoImVyci5vcHRpb24ubm90LmFsbG93ZWQud2l0aC50YXJnZXQiLCBvcHRpb24uZ2V0UHJpbWFyeU5hbWUoKSwgdC5uYW1lKSwKICAgICAgICAgICAgICAgIE9wdGlvbi5CT09UX0NMQVNTX1BBVEgsCiAgICAgICAgICAgICAgICBPcHRpb24uWEJPT1RDTEFTU1BBVEhfUFJFUEVORCwgT3B0aW9uLlhCT09UQ0xBU1NQQVRILCBPcHRpb24uWEJPT1RDTEFTU1BBVEhfQVBQRU5ELAogICAgICAgICAgICAgICAgT3B0aW9uLkVORE9SU0VERElSUywgT3B0aW9uLkRKQVZBX0VORE9SU0VEX0RJUlMsCiAgICAgICAgICAgICAgICBPcHRpb24uRVhURElSUywgT3B0aW9uLkRKQVZBX0VYVF9ESVJTLAogICAgICAgICAgICAgICAgT3B0aW9uLlBST0ZJTEUpOwoKICAgICAgICBjaGVja09wdGlvbkFsbG93ZWQodC5jb21wYXJlVG8oVGFyZ2V0LkpESzFfOSkgPj0gMCwKICAgICAgICAgICAgICAgIG9wdGlvbiAtPiBlcnJvcigiZXJyLm9wdGlvbi5ub3QuYWxsb3dlZC53aXRoLnRhcmdldCIsIG9wdGlvbi5nZXRQcmltYXJ5TmFtZSgpLCB0Lm5hbWUpLAogICAgICAgICAgICAgICAgT3B0aW9uLk1PRFVMRV9TT1VSQ0VfUEFUSCwgT3B0aW9uLlVQR1JBREVfTU9EVUxFX1BBVEgsCiAgICAgICAgICAgICAgICBPcHRpb24uU1lTVEVNLCBPcHRpb24uTU9EVUxFX1BBVEgsIE9wdGlvbi5BRERfTU9EVUxFUywKICAgICAgICAgICAgICAgIE9wdGlvbi5BRERfRVhQT1JUUywgT3B0aW9uLkFERF9PUEVOUywgT3B0aW9uLkFERF9SRUFEUywKICAgICAgICAgICAgICAgIE9wdGlvbi5MSU1JVF9NT0RVTEVTLAogICAgICAgICAgICAgICAgT3B0aW9uLlBBVENIX01PRFVMRSk7CgogICAgICAgIGlmIChmbS5oYXNMb2NhdGlvbihTdGFuZGFyZExvY2F0aW9uLk1PRFVMRV9TT1VSQ0VfUEFUSCkpIHsKICAgICAgICAgICAgaWYgKCFvcHRpb25zLmlzU2V0KE9wdGlvbi5QUk9DLCAib25seSIpCiAgICAgICAgICAgICAgICAgICAgJiYgIWZtLmhhc0xvY2F0aW9uKFN0YW5kYXJkTG9jYXRpb24uQ0xBU1NfT1VUUFVUKSkgewogICAgICAgICAgICAgICAgbG9nLmVycm9yKEVycm9ycy5Ob091dHB1dERpcik7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmIChmbS5oYXNMb2NhdGlvbihTdGFuZGFyZExvY2F0aW9uLkFOTk9UQVRJT05fUFJPQ0VTU09SX01PRFVMRV9QQVRIKSAmJgogICAgICAgICAgICBmbS5oYXNMb2NhdGlvbihTdGFuZGFyZExvY2F0aW9uLkFOTk9UQVRJT05fUFJPQ0VTU09SX1BBVEgpKSB7CiAgICAgICAgICAgIGxvZy5lcnJvcihFcnJvcnMuUHJvY2Vzc29ycGF0aE5vUHJvY2Vzc29ybW9kdWxlcGF0aCk7CiAgICAgICAgfQoKICAgICAgICBpZiAob2Jzb2xldGVPcHRpb25Gb3VuZCAmJiBsaW50T3B0aW9ucykgewogICAgICAgICAgICBsb2cud2FybmluZyhMaW50Q2F0ZWdvcnkuT1BUSU9OUywgIm9wdGlvbi5vYnNvbGV0ZS5zdXBwcmVzc2lvbiIpOwogICAgICAgIH0KCiAgICAgICAgU291cmNlVmVyc2lvbiBzdiA9IFNvdXJjZS50b1NvdXJjZVZlcnNpb24oc291cmNlKTsKICAgICAgICB2YWxpZGF0ZUFkZEV4cG9ydHMoc3YpOwogICAgICAgIHZhbGlkYXRlQWRkTW9kdWxlcyhzdik7CiAgICAgICAgdmFsaWRhdGVBZGRSZWFkcyhzdik7CiAgICAgICAgdmFsaWRhdGVMaW1pdE1vZHVsZXMoc3YpOwoKICAgICAgICBpZiAobGludE9wdGlvbnMgJiYgb3B0aW9ucy5pc1NldChPcHRpb24uQUREX09QRU5TKSkgewogICAgICAgICAgICBsb2cud2FybmluZyhMaW50Q2F0ZWdvcnkuT1BUSU9OUywgV2FybmluZ3MuQWRkb3BlbnNJZ25vcmVkKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAhZXJyb3JzICYmIChsb2cubmVycm9ycyA9PSAwKTsKICAgIH0KCiAgICBwcml2YXRlIHZvaWQgdmFsaWRhdGVBZGRFeHBvcnRzKFNvdXJjZVZlcnNpb24gc3YpIHsKICAgICAgICBTdHJpbmcgYWRkRXhwb3J0cyA9IG9wdGlvbnMuZ2V0KE9wdGlvbi5BRERfRVhQT1JUUyk7CiAgICAgICAgaWYgKGFkZEV4cG9ydHMgIT0gbnVsbCkgewogICAgICAgICAgICAvLyBFYWNoIGVudHJ5IG11c3QgYmUgb2YgdGhlIGZvcm0gc291cmNlTW9kdWxlL3NvdXJjZVBhY2thZ2U9dGFyZ2V0LWxpc3Qgd2hlcmUKICAgICAgICAgICAgLy8gdGFyZ2V0LWxpc3QgaXMgYSBjb21tYSBzZXBhcmF0ZWQgbGlzdCBvZiBtb2R1bGUgb3IgQUxMLVVOTkFNRUQuCiAgICAgICAgICAgIC8vIEVtcHR5IGl0ZW1zIGluIHRoZSB0YXJnZXQtbGlzdCBhcmUgaWdub3JlZC4KICAgICAgICAgICAgLy8gVGhlcmUgbXVzdCBiZSBhdCBsZWFzdCBvbmUgaXRlbSBpbiB0aGUgbGlzdDsgdGhpcyBpcyBoYW5kbGVkIGluIE9wdGlvbi5BRERfRVhQT1JUUy4KICAgICAgICAgICAgUGF0dGVybiBwID0gT3B0aW9uLkFERF9FWFBPUlRTLmdldFBhdHRlcm4oKTsKICAgICAgICAgICAgZm9yIChTdHJpbmcgZSA6IGFkZEV4cG9ydHMuc3BsaXQoIlwwIikpIHsKICAgICAgICAgICAgICAgIE1hdGNoZXIgbSA9IHAubWF0Y2hlcihlKTsKICAgICAgICAgICAgICAgIGlmIChtLm1hdGNoZXMoKSkgewogICAgICAgICAgICAgICAgICAgIFN0cmluZyBzb3VyY2VNb2R1bGVOYW1lID0gbS5ncm91cCgxKTsKICAgICAgICAgICAgICAgICAgICBpZiAoIVNvdXJjZVZlcnNpb24uaXNOYW1lKHNvdXJjZU1vZHVsZU5hbWUsIHN2KSkgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBzeW50YWN0aWNhbGx5IGludmFsaWQgc291cmNlIG5hbWU6ICBlLmcuIC0tYWRkLWV4cG9ydHMgbSEvcDE9bTIKICAgICAgICAgICAgICAgICAgICAgICAgbG9nLndhcm5pbmcoV2FybmluZ3MuQmFkTmFtZUZvck9wdGlvbihPcHRpb24uQUREX0VYUE9SVFMsIHNvdXJjZU1vZHVsZU5hbWUpKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHNvdXJjZVBhY2thZ2VOYW1lID0gbS5ncm91cCgyKTsKICAgICAgICAgICAgICAgICAgICBpZiAoIVNvdXJjZVZlcnNpb24uaXNOYW1lKHNvdXJjZVBhY2thZ2VOYW1lLCBzdikpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gc3ludGFjdGljYWxseSBpbnZhbGlkIHNvdXJjZSBuYW1lOiAgZS5nLiAtLWFkZC1leHBvcnRzIG0xL3AhPW0yCiAgICAgICAgICAgICAgICAgICAgICAgIGxvZy53YXJuaW5nKFdhcm5pbmdzLkJhZE5hbWVGb3JPcHRpb24oT3B0aW9uLkFERF9FWFBPUlRTLCBzb3VyY2VQYWNrYWdlTmFtZSkpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHRhcmdldE5hbWVzID0gbS5ncm91cCgzKTsKICAgICAgICAgICAgICAgICAgICBmb3IgKFN0cmluZyB0YXJnZXROYW1lIDogdGFyZ2V0TmFtZXMuc3BsaXQoIiwiKSkgewogICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKHRhcmdldE5hbWUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgIiI6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlICJBTEwtVU5OQU1FRCI6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIVNvdXJjZVZlcnNpb24uaXNOYW1lKHRhcmdldE5hbWUsIHN2KSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBzeW50YWN0aWNhbGx5IGludmFsaWQgdGFyZ2V0IG5hbWU6ICBlLmcuIC0tYWRkLWV4cG9ydHMgbTEvcDE9bSEKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9nLndhcm5pbmcoV2FybmluZ3MuQmFkTmFtZUZvck9wdGlvbihPcHRpb24uQUREX0VYUE9SVFMsIHRhcmdldE5hbWUpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgcHJpdmF0ZSB2b2lkIHZhbGlkYXRlQWRkUmVhZHMoU291cmNlVmVyc2lvbiBzdikgewogICAgICAgIFN0cmluZyBhZGRSZWFkcyA9IG9wdGlvbnMuZ2V0KE9wdGlvbi5BRERfUkVBRFMpOwogICAgICAgIGlmIChhZGRSZWFkcyAhPSBudWxsKSB7CiAgICAgICAgICAgIC8vIEVhY2ggZW50cnkgbXVzdCBiZSBvZiB0aGUgZm9ybSBzb3VyY2U9dGFyZ2V0LWxpc3Qgd2hlcmUgdGFyZ2V0LWxpc3QgaXMgYQogICAgICAgICAgICAvLyBjb21tYS1zZXBhcmF0ZWQgbGlzdCBvZiBtb2R1bGUgb3IgQUxMLVVOTkFNRUQuCiAgICAgICAgICAgIC8vIEVtcHR5IGl0ZW1zIGluIHRoZSB0YXJnZXQgbGlzdCBhcmUgaWdub3JlZC4KICAgICAgICAgICAgLy8gVGhlcmUgbXVzdCBiZSBhdCBsZWFzdCBvbmUgaXRlbSBpbiB0aGUgbGlzdDsgdGhpcyBpcyBoYW5kbGVkIGluIE9wdGlvbi5BRERfUkVBRFMuCiAgICAgICAgICAgIFBhdHRlcm4gcCA9IE9wdGlvbi5BRERfUkVBRFMuZ2V0UGF0dGVybigpOwogICAgICAgICAgICBmb3IgKFN0cmluZyBlIDogYWRkUmVhZHMuc3BsaXQoIlwwIikpIHsKICAgICAgICAgICAgICAgIE1hdGNoZXIgbSA9IHAubWF0Y2hlcihlKTsKICAgICAgICAgICAgICAgIGlmIChtLm1hdGNoZXMoKSkgewogICAgICAgICAgICAgICAgICAgIFN0cmluZyBzb3VyY2VOYW1lID0gbS5ncm91cCgxKTsKICAgICAgICAgICAgICAgICAgICBpZiAoIVNvdXJjZVZlcnNpb24uaXNOYW1lKHNvdXJjZU5hbWUsIHN2KSkgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBzeW50YWN0aWNhbGx5IGludmFsaWQgc291cmNlIG5hbWU6ICBlLmcuIC0tYWRkLXJlYWRzIG0hPW0yCiAgICAgICAgICAgICAgICAgICAgICAgIGxvZy53YXJuaW5nKFdhcm5pbmdzLkJhZE5hbWVGb3JPcHRpb24oT3B0aW9uLkFERF9SRUFEUywgc291cmNlTmFtZSkpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHRhcmdldE5hbWVzID0gbS5ncm91cCgyKTsKICAgICAgICAgICAgICAgICAgICBmb3IgKFN0cmluZyB0YXJnZXROYW1lIDogdGFyZ2V0TmFtZXMuc3BsaXQoIiwiLCAtMSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgc3dpdGNoICh0YXJnZXROYW1lKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlICIiOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAiQUxMLVVOTkFNRUQiOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFTb3VyY2VWZXJzaW9uLmlzTmFtZSh0YXJnZXROYW1lLCBzdikpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc3ludGFjdGljYWxseSBpbnZhbGlkIHRhcmdldCBuYW1lOiAgZS5nLiAtLWFkZC1yZWFkcyBtMT1tIQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2cud2FybmluZyhXYXJuaW5ncy5CYWROYW1lRm9yT3B0aW9uKE9wdGlvbi5BRERfUkVBRFMsIHRhcmdldE5hbWUpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgcHJpdmF0ZSB2b2lkIHZhbGlkYXRlQWRkTW9kdWxlcyhTb3VyY2VWZXJzaW9uIHN2KSB7CiAgICAgICAgU3RyaW5nIGFkZE1vZHVsZXMgPSBvcHRpb25zLmdldChPcHRpb24uQUREX01PRFVMRVMpOwogICAgICAgIGlmIChhZGRNb2R1bGVzICE9IG51bGwpIHsKICAgICAgICAgICAgLy8gRWFjaCBlbnRyeSBtdXN0IGJlIG9mIHRoZSBmb3JtIHRhcmdldC1saXN0IHdoZXJlIHRhcmdldC1saXN0IGlzIGEKICAgICAgICAgICAgLy8gY29tbWEgc2VwYXJhdGVkIGxpc3Qgb2YgbW9kdWxlIG5hbWVzLCBvciBBTEwtREVGQVVMVCwgQUxMLVNZU1RFTSwKICAgICAgICAgICAgLy8gb3IgQUxMLU1PRFVMRV9QQVRILgogICAgICAgICAgICAvLyBFbXB0eSBpdGVtcyBpbiB0aGUgdGFyZ2V0IGxpc3QgYXJlIGlnbm9yZWQuCiAgICAgICAgICAgIC8vIFRoZXJlIG11c3QgYmUgYXQgbGVhc3Qgb25lIGl0ZW0gaW4gdGhlIGxpc3Q7IHRoaXMgaXMgaGFuZGxlZCBpbiBPcHRpb24uQUREX01PRFVMRVMuCiAgICAgICAgICAgIGZvciAoU3RyaW5nIG1vZHVsZU5hbWUgOiBhZGRNb2R1bGVzLnNwbGl0KCIsIikpIHsKICAgICAgICAgICAgICAgIHN3aXRjaCAobW9kdWxlTmFtZSkgewogICAgICAgICAgICAgICAgICAgIGNhc2UgIiI6CiAgICAgICAgICAgICAgICAgICAgY2FzZSAiQUxMLVNZU1RFTSI6CiAgICAgICAgICAgICAgICAgICAgY2FzZSAiQUxMLU1PRFVMRS1QQVRIIjoKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghU291cmNlVmVyc2lvbi5pc05hbWUobW9kdWxlTmFtZSwgc3YpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBzeW50YWN0aWNhbGx5IGludmFsaWQgbW9kdWxlIG5hbWU6ICBlLmcuIC0tYWRkLW1vZHVsZXMgbTEsbSEKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZy5lcnJvcihFcnJvcnMuQmFkTmFtZUZvck9wdGlvbihPcHRpb24uQUREX01PRFVMRVMsIG1vZHVsZU5hbWUpKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIHZvaWQgdmFsaWRhdGVMaW1pdE1vZHVsZXMoU291cmNlVmVyc2lvbiBzdikgewogICAgICAgIFN0cmluZyBsaW1pdE1vZHVsZXMgPSBvcHRpb25zLmdldChPcHRpb24uTElNSVRfTU9EVUxFUyk7CiAgICAgICAgaWYgKGxpbWl0TW9kdWxlcyAhPSBudWxsKSB7CiAgICAgICAgICAgIC8vIEVhY2ggZW50cnkgbXVzdCBiZSBvZiB0aGUgZm9ybSB0YXJnZXQtbGlzdCB3aGVyZSB0YXJnZXQtbGlzdCBpcyBhCiAgICAgICAgICAgIC8vIGNvbW1hIHNlcGFyYXRlZCBsaXN0IG9mIG1vZHVsZSBuYW1lcywgb3IgQUxMLURFRkFVTFQsIEFMTC1TWVNURU0sCiAgICAgICAgICAgIC8vIG9yIEFMTC1NT0RVTEVfUEFUSC4KICAgICAgICAgICAgLy8gRW1wdHkgaXRlbXMgaW4gdGhlIHRhcmdldCBsaXN0IGFyZSBpZ25vcmVkLgogICAgICAgICAgICAvLyBUaGVyZSBtdXN0IGJlIGF0IGxlYXN0IG9uZSBpdGVtIGluIHRoZSBsaXN0OyB0aGlzIGlzIGhhbmRsZWQgaW4gT3B0aW9uLkxJTUlUX0VYUE9SVFMuCiAgICAgICAgICAgIGZvciAoU3RyaW5nIG1vZHVsZU5hbWUgOiBsaW1pdE1vZHVsZXMuc3BsaXQoIiwiKSkgewogICAgICAgICAgICAgICAgc3dpdGNoIChtb2R1bGVOYW1lKSB7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAiIjoKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghU291cmNlVmVyc2lvbi5pc05hbWUobW9kdWxlTmFtZSwgc3YpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBzeW50YWN0aWNhbGx5IGludmFsaWQgbW9kdWxlIG5hbWU6ICBlLmcuIC0tbGltaXQtbW9kdWxlcyBtMSxtIQogICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9nLmVycm9yKEVycm9ycy5CYWROYW1lRm9yT3B0aW9uKE9wdGlvbi5MSU1JVF9NT0RVTEVTLCBtb2R1bGVOYW1lKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlcmUgYXJlIG5vIGZpbGVzIG9yIGNsYXNzZXMgc3BlY2lmaWVkIGZvciB1c2UuCiAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlcmUgYXJlIG5vIGZpbGVzIG9yIGNsYXNzZXMgc3BlY2lmaWVkIGZvciB1c2UKICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gaXNFbXB0eSgpIHsKICAgICAgICByZXR1cm4gKChmaWxlcyA9PSBudWxsKSB8fCBmaWxlcy5pc0VtcHR5KCkpCiAgICAgICAgICAgICAgICAmJiAoKGZpbGVPYmplY3RzID09IG51bGwpIHx8IGZpbGVPYmplY3RzLmlzRW1wdHkoKSkKICAgICAgICAgICAgICAgICYmIChjbGFzc05hbWVzID09IG51bGwgfHwgY2xhc3NOYW1lcy5pc0VtcHR5KCkpOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIGFsbG93RW1wdHkoKSB7CiAgICAgICAgdGhpcy5lbXB0eUFsbG93ZWQgPSB0cnVlOwogICAgfQoKICAgIC8qKgogICAgICogR2V0cyB0aGUgZmlsZSBtYW5hZ2VyIG9wdGlvbnMgd2hpY2ggbWF5IGhhdmUgYmVlbiBkZWZlcnJlZAogICAgICogZHVyaW5nIHByb2Nlc3NBcmdzLgogICAgICogQHJldHVybiB0aGUgZGVmZXJyZWQgZmlsZSBtYW5hZ2VyIG9wdGlvbnMKICAgICAqLwogICAgcHVibGljIE1hcDxPcHRpb24sIFN0cmluZz4gZ2V0RGVmZXJyZWRGaWxlTWFuYWdlck9wdGlvbnMoKSB7CiAgICAgICAgcmV0dXJuIGRlZmVycmVkRmlsZU1hbmFnZXJPcHRpb25zOwogICAgfQoKICAgIC8qKgogICAgICogR2V0cyBhbnkgb3B0aW9ucyBzcGVjaWZ5aW5nIHBsdWdpbnMgdG8gYmUgcnVuLgogICAgICogQHJldHVybiBvcHRpb25zIGZvciBwbHVnaW5zCiAgICAgKi8KICAgIHB1YmxpYyBTZXQ8TGlzdDxTdHJpbmc+PiBnZXRQbHVnaW5PcHRzKCkgewogICAgICAgIFN0cmluZyBwbHVnaW5zID0gb3B0aW9ucy5nZXQoT3B0aW9uLlBMVUdJTik7CiAgICAgICAgaWYgKHBsdWdpbnMgPT0gbnVsbCkKICAgICAgICAgICAgcmV0dXJuIENvbGxlY3Rpb25zLmVtcHR5U2V0KCk7CgogICAgICAgIFNldDxMaXN0PFN0cmluZz4+IHBsdWdpbk9wdHMgPSBuZXcgTGlua2VkSGFzaFNldDw+KCk7CiAgICAgICAgZm9yIChTdHJpbmcgcGx1Z2luOiBwbHVnaW5zLnNwbGl0KCJcXHgwMCIpKSB7CiAgICAgICAgICAgIHBsdWdpbk9wdHMuYWRkKExpc3QuZnJvbShwbHVnaW4uc3BsaXQoIlxccysiKSkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlU2V0KHBsdWdpbk9wdHMpOwogICAgfQoKICAgIC8qKgogICAgICogR2V0cyBhbnkgb3B0aW9ucyBzcGVjaWZ5aW5nIGhvdyBkb2NsaW50IHNob3VsZCBiZSBydW4uCiAgICAgKiBBbiBlbXB0eSBsaXN0IGlzIHJldHVybmVkIGlmIG5vIGRvY2xpbnQgb3B0aW9ucyBhcmUgc3BlY2lmaWVkCiAgICAgKiBvciBpZiB0aGUgb25seSBkb2NsaW50IG9wdGlvbiBpcyAtWGRvY2xpbnQ6bm9uZS4KICAgICAqIEByZXR1cm4gb3B0aW9ucyBmb3IgZG9jbGludAogICAgICovCiAgICBwdWJsaWMgTGlzdDxTdHJpbmc+IGdldERvY0xpbnRPcHRzKCkgewogICAgICAgIFN0cmluZyB4ZG9jbGludCA9IG9wdGlvbnMuZ2V0KE9wdGlvbi5YRE9DTElOVCk7CiAgICAgICAgU3RyaW5nIHhkb2NsaW50Q3VzdG9tID0gb3B0aW9ucy5nZXQoT3B0aW9uLlhET0NMSU5UX0NVU1RPTSk7CiAgICAgICAgaWYgKHhkb2NsaW50ID09IG51bGwgJiYgeGRvY2xpbnRDdXN0b20gPT0gbnVsbCkKICAgICAgICAgICAgcmV0dXJuIExpc3QubmlsKCk7CgogICAgICAgIFNldDxTdHJpbmc+IGRvY2xpbnRPcHRzID0gbmV3IExpbmtlZEhhc2hTZXQ8PigpOwogICAgICAgIGlmICh4ZG9jbGludCAhPSBudWxsKQogICAgICAgICAgICBkb2NsaW50T3B0cy5hZGQoRG9jTGludC5YTVNHU19PUFRJT04pOwogICAgICAgIGlmICh4ZG9jbGludEN1c3RvbSAhPSBudWxsKSB7CiAgICAgICAgICAgIGZvciAoU3RyaW5nIHM6IHhkb2NsaW50Q3VzdG9tLnNwbGl0KCJcXHMrIikpIHsKICAgICAgICAgICAgICAgIGlmIChzLmlzRW1wdHkoKSkKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIGRvY2xpbnRPcHRzLmFkZChEb2NMaW50LlhNU0dTX0NVU1RPTV9QUkVGSVggKyBzKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKGRvY2xpbnRPcHRzLmVxdWFscyhDb2xsZWN0aW9ucy5zaW5nbGV0b24oRG9jTGludC5YTVNHU19DVVNUT01fUFJFRklYICsgIm5vbmUiKSkpCiAgICAgICAgICAgIHJldHVybiBMaXN0Lm5pbCgpOwoKICAgICAgICBTdHJpbmcgY2hlY2tQYWNrYWdlcyA9IG9wdGlvbnMuZ2V0KE9wdGlvbi5YRE9DTElOVF9QQUNLQUdFKTsKICAgICAgICBpZiAoY2hlY2tQYWNrYWdlcyAhPSBudWxsKSB7CiAgICAgICAgICAgIGZvciAoU3RyaW5nIHMgOiBjaGVja1BhY2thZ2VzLnNwbGl0KCJcXHMrIikpIHsKICAgICAgICAgICAgICAgIGRvY2xpbnRPcHRzLmFkZChEb2NMaW50LlhDSEVDS19QQUNLQUdFICsgcyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIFN0cmluZyBmb3JtYXQgPSBvcHRpb25zLmdldChPcHRpb24uRE9DTElOVF9GT1JNQVQpOwogICAgICAgIGlmIChmb3JtYXQgIT0gbnVsbCkgewogICAgICAgICAgICBkb2NsaW50T3B0cy5hZGQoRG9jTGludC5YSFRNTF9WRVJTSU9OX1BSRUZJWCArIGZvcm1hdCk7CiAgICAgICAgfQoKICAgICAgICAvLyBzdGFuZGFyZCBkb2NsZXQgbm9ybWFsbHkgZ2VuZXJhdGVzIEgxLCBIMiwKICAgICAgICAvLyBzbyBmb3Igbm93LCBhbGxvdyB1c2VyIGNvbW1lbnRzIHRvIGFzc3VtZSB0aGF0CiAgICAgICAgZG9jbGludE9wdHMuYWRkKERvY0xpbnQuWElNUExJQ0lUX0hFQURFUlMgKyAiMiIpOwogICAgICAgIHJldHVybiBMaXN0LmZyb20oZG9jbGludE9wdHMudG9BcnJheShuZXcgU3RyaW5nW2RvY2xpbnRPcHRzLnNpemUoKV0pKTsKICAgIH0KCiAgICBwcml2YXRlIGJvb2xlYW4gY2hlY2tEaXJlY3RvcnkoT3B0aW9uIG9wdGlvbikgewogICAgICAgIFN0cmluZyB2YWx1ZSA9IG9wdGlvbnMuZ2V0KG9wdGlvbik7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgICAgIFBhdGggZmlsZSA9IFBhdGhzLmdldCh2YWx1ZSk7CiAgICAgICAgaWYgKEZpbGVzLmV4aXN0cyhmaWxlKSAmJiAhRmlsZXMuaXNEaXJlY3RvcnkoZmlsZSkpIHsKICAgICAgICAgICAgZXJyb3IoImVyci5maWxlLm5vdC5kaXJlY3RvcnkiLCB2YWx1ZSk7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgcHJpdmF0ZSBpbnRlcmZhY2UgRXJyb3JSZXBvcnRlciB7CiAgICAgICAgdm9pZCByZXBvcnQoT3B0aW9uIG8pOwogICAgfQoKICAgIHZvaWQgY2hlY2tPcHRpb25BbGxvd2VkKGJvb2xlYW4gYWxsb3dlZCwgRXJyb3JSZXBvcnRlciByLCBPcHRpb24uLi4gb3B0cykgewogICAgICAgIGlmICghYWxsb3dlZCkgewogICAgICAgICAgICBTdHJlYW0ub2Yob3B0cykKICAgICAgICAgICAgICAgICAgLmZpbHRlcihvcHRpb25zIDo6IGlzU2V0KQogICAgICAgICAgICAgICAgICAuZm9yRWFjaChyIDo6IHJlcG9ydCk7CiAgICAgICAgfQogICAgfQoKICAgIHZvaWQgZXJyb3IoSkNEaWFnbm9zdGljLkVycm9yIGVycm9yKSB7CiAgICAgICAgZXJyb3JzID0gdHJ1ZTsKICAgICAgICBzd2l0Y2ggKGVycm9yTW9kZSkgewogICAgICAgICAgICBjYXNlIElMTEVHQUxfQVJHVU1FTlQ6IHsKICAgICAgICAgICAgICAgIFN0cmluZyBtc2cgPSBsb2cubG9jYWxpemUoZXJyb3IpOwogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFByb3BhZ2F0ZWRFeGNlcHRpb24obmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihtc2cpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBjYXNlIElMTEVHQUxfU1RBVEU6IHsKICAgICAgICAgICAgICAgIFN0cmluZyBtc2cgPSBsb2cubG9jYWxpemUoZXJyb3IpOwogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFByb3BhZ2F0ZWRFeGNlcHRpb24obmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbihtc2cpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBjYXNlIExPRzoKICAgICAgICAgICAgICAgIHJlcG9ydChlcnJvcik7CiAgICAgICAgfQogICAgfQoKICAgIHZvaWQgZXJyb3IoU3RyaW5nIGtleSwgT2JqZWN0Li4uIGFyZ3MpIHsKICAgICAgICBlcnJvcnMgPSB0cnVlOwogICAgICAgIHN3aXRjaCAoZXJyb3JNb2RlKSB7CiAgICAgICAgICAgIGNhc2UgSUxMRUdBTF9BUkdVTUVOVDogewogICAgICAgICAgICAgICAgU3RyaW5nIG1zZyA9IGxvZy5sb2NhbGl6ZShQcmVmaXhLaW5kLkpBVkFDLCBrZXksIGFyZ3MpOwogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFByb3BhZ2F0ZWRFeGNlcHRpb24obmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihtc2cpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBjYXNlIElMTEVHQUxfU1RBVEU6IHsKICAgICAgICAgICAgICAgIFN0cmluZyBtc2cgPSBsb2cubG9jYWxpemUoUHJlZml4S2luZC5KQVZBQywga2V5LCBhcmdzKTsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBQcm9wYWdhdGVkRXhjZXB0aW9uKG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24obXNnKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY2FzZSBMT0c6CiAgICAgICAgICAgICAgICByZXBvcnQoa2V5LCBhcmdzKTsKICAgICAgICB9CiAgICB9CgogICAgdm9pZCBlcnJvcihPcHRpb24uSW52YWxpZFZhbHVlRXhjZXB0aW9uIGYpIHsKICAgICAgICBTdHJpbmcgbXNnID0gZi5nZXRNZXNzYWdlKCk7CiAgICAgICAgZXJyb3JzID0gdHJ1ZTsKICAgICAgICBzd2l0Y2ggKGVycm9yTW9kZSkgewogICAgICAgICAgICBjYXNlIElMTEVHQUxfQVJHVU1FTlQ6IHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBQcm9wYWdhdGVkRXhjZXB0aW9uKG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24obXNnLCBmLmdldENhdXNlKCkpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBjYXNlIElMTEVHQUxfU1RBVEU6IHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBQcm9wYWdhdGVkRXhjZXB0aW9uKG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24obXNnLCBmLmdldENhdXNlKCkpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBjYXNlIExPRzoKICAgICAgICAgICAgICAgIGxvZy5wcmludFJhd0xpbmVzKG93bk5hbWUgKyAiOiAiICsgbXNnKTsKICAgICAgICB9CiAgICB9CgogICAgdm9pZCB3YXJuaW5nKFN0cmluZyBrZXksIE9iamVjdC4uLiBhcmdzKSB7CiAgICAgICAgcmVwb3J0KGtleSwgYXJncyk7CiAgICB9CgogICAgcHJpdmF0ZSB2b2lkIHJlcG9ydChTdHJpbmcga2V5LCBPYmplY3QuLi4gYXJncykgewogICAgICAgIC8vIFdvdWxkIGJlIGdvb2QgdG8gaGF2ZSBzdXBwb3J0IGZvciAtWERyYXdEaWFnbm9zdGljcyBoZXJlCiAgICAgICAgbG9nLnByaW50UmF3TGluZXMob3duTmFtZSArICI6ICIgKyBsb2cubG9jYWxpemUoUHJlZml4S2luZC5KQVZBQywga2V5LCBhcmdzKSk7CiAgICB9CgogICAgcHJpdmF0ZSB2b2lkIHJlcG9ydChKQ0RpYWdub3N0aWMuRXJyb3IgZXJyb3IpIHsKICAgICAgICAvLyBXb3VsZCBiZSBnb29kIHRvIGhhdmUgc3VwcG9ydCBmb3IgLVhEcmF3RGlhZ25vc3RpY3MgaGVyZQogICAgICAgIGxvZy5wcmludFJhd0xpbmVzKG93bk5hbWUgKyAiOiAiICsgbG9nLmxvY2FsaXplKGVycm9yKSk7CiAgICB9CgogICAgcHJpdmF0ZSBKYXZhRmlsZU1hbmFnZXIgZ2V0RmlsZU1hbmFnZXIoKSB7CiAgICAgICAgaWYgKGZpbGVNYW5hZ2VyID09IG51bGwpCiAgICAgICAgICAgIGZpbGVNYW5hZ2VyID0gY29udGV4dC5nZXQoSmF2YUZpbGVNYW5hZ2VyLmNsYXNzKTsKICAgICAgICByZXR1cm4gZmlsZU1hbmFnZXI7CiAgICB9CgogICAgPFQ+IExpc3RCdWZmZXI8VD4gdG9MaXN0KEl0ZXJhYmxlPD8gZXh0ZW5kcyBUPiBpdGVtcykgewogICAgICAgIExpc3RCdWZmZXI8VD4gbGlzdCA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICBpZiAoaXRlbXMgIT0gbnVsbCkgewogICAgICAgICAgICBmb3IgKFQgaXRlbSA6IGl0ZW1zKSB7CiAgICAgICAgICAgICAgICBsaXN0LmFkZChpdGVtKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gbGlzdDsKICAgIH0KCiAgICA8VD4gU2V0PFQ+IHRvU2V0KEl0ZXJhYmxlPD8gZXh0ZW5kcyBUPiBpdGVtcykgewogICAgICAgIFNldDxUPiBzZXQgPSBuZXcgTGlua2VkSGFzaFNldDw+KCk7CiAgICAgICAgaWYgKGl0ZW1zICE9IG51bGwpIHsKICAgICAgICAgICAgZm9yIChUIGl0ZW0gOiBpdGVtcykgewogICAgICAgICAgICAgICAgc2V0LmFkZChpdGVtKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gc2V0OwogICAgfQp9ClBLAwQKAAAIAAAGO6lK+LyBm7ASAACwEgAAKgAAAGNvbS9zdW4vdG9vbHMvamF2YWMvbWFpbi9PcHRpb25IZWxwZXIuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNiwgMjAxNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLmphdmFjLm1haW47CgppbXBvcnQgamF2YS5uaW8uZmlsZS5QYXRoOwoKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5KQ0RpYWdub3N0aWM7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuTG9nOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkxvZy5QcmVmaXhLaW5kOwoKLyoqCiAqIEhlbHBlciBvYmplY3QgdG8gYmUgdXNlZCBieSB7QGxpbmsgT3B0aW9uI3Byb2Nlc3N9LCBwcm92aWRpbmcgYWNjZXNzIHRvCiAqIHRoZSBjb21waWxhdGlvbiBlbnZpcm9ubWVudC4KICoKICogPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93bgogKiByaXNrLiAgVGhpcyBjb2RlIGFuZCBpdHMgaW50ZXJuYWwgaW50ZXJmYWNlcyBhcmUgc3ViamVjdCB0byBjaGFuZ2UKICogb3IgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPjwvcD4KICovCgpwdWJsaWMgYWJzdHJhY3QgY2xhc3MgT3B0aW9uSGVscGVyIHsKCiAgICAvKioKICAgICAqIEdldCB0aGUgY3VycmVudCB2YWx1ZSBvZiBhbiBvcHRpb24uCiAgICAgKiBAcGFyYW0gb3B0aW9uIHRoZSBvcHRpb24KICAgICAqIEByZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSBvcHRpb24KICAgICAqLwogICAgcHVibGljIGFic3RyYWN0IFN0cmluZyBnZXQoT3B0aW9uIG9wdGlvbik7CgogICAgLyoqCiAgICAgKiBTZXQgdGhlIHZhbHVlIG9mIGFuIG9wdGlvbi4KICAgICAqIEBwYXJhbSBuYW1lIHRoZSBwcmltYXJ5IG5hbWUgb2YgdGhlIG9wdGlvbgogICAgICogQHBhcmFtIHZhbHVlIHRoZSB2YWx1ZSBmb3IgdGhlIG9wdGlvbgogICAgICovCiAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBwdXQoU3RyaW5nIG5hbWUsIFN0cmluZyB2YWx1ZSk7CgogICAgLyoqCiAgICAgKiBSZW1vdmUgYW55IHByaW9yIHZhbHVlIGZvciBhbiBvcHRpb24uCiAgICAgKiBAcGFyYW0gbmFtZSB0aGUgcHJpbWFyeSBuYW1lIG9mIHRoZSBvcHRpb24KICAgICAqLwogICAgcHVibGljIGFic3RyYWN0IHZvaWQgcmVtb3ZlKFN0cmluZyBuYW1lKTsKCiAgICAvKioKICAgICAqIEhhbmRsZSBhIGZpbGUgbWFuYWdlciBvcHRpb24uCiAgICAgKiBAcGFyYW0gb3B0aW9uIHRoZSBvcHRpb24KICAgICAqIEBwYXJhbSB2YWx1ZSB0aGUgdmFsdWUgZm9yIHRoZSBvcHRpb24KICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgb3B0aW9uIHdhcyBoYW5kbGVkIHN1Y2Nlc3NmdWxseSwgYW5kIGZhbHNlIG90aGVyd2lzZQogICAgICovCiAgICBwdWJsaWMgYWJzdHJhY3QgYm9vbGVhbiBoYW5kbGVGaWxlTWFuYWdlck9wdGlvbihPcHRpb24gb3B0aW9uLCBTdHJpbmcgdmFsdWUpOwoKICAgIC8qKgogICAgICogR2V0IGFjY2VzcyB0byB0aGUgTG9nIGZvciB0aGUgY29tcGlsYXRpb24uCiAgICAgKiBAcmV0dXJuIHRoZSBsb2cKICAgICAqLwogICAgcHVibGljIGFic3RyYWN0IExvZyBnZXRMb2coKTsKCiAgICAvKioKICAgICAqIEdldCB0aGUgbmFtZSBvZiB0aGUgdG9vbCwgc3VjaCBhcyAiamF2YWMiLCB0byBiZSB1c2VkIGluIGluZm8gbGlrZSAtaGVscC4KICAgICAqIEByZXR1cm4gdGhlIG5hbWUgb2YgdGhlIHRvb2wKICAgICAqLwogICAgcHVibGljIGFic3RyYWN0IFN0cmluZyBnZXRPd25OYW1lKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgbmV3IEludmFsaWRWYWx1ZUV4Y2VwdGlvbiwgd2l0aCBhIGxvY2FsaXplZCBkZXRhaWwgbWVzc2FnZS4KICAgICAqIEBwYXJhbSBrZXkgdGhlIHJlc291cmNlIGtleSBmb3IgdGhlIG1lc3NhZ2UKICAgICAqIEBwYXJhbSBhcmdzIHRoZSBhcmd1bWVudHMsIGlmIGFueSwgZm9yIHRoZSByZXNvdXJjZSBzdHJpbmcKICAgICAqIEByZXR1cm4gdGhlIEludmFsaWRWYWx1ZUV4Y2VwdGlvbgogICAgICovCiAgICBPcHRpb24uSW52YWxpZFZhbHVlRXhjZXB0aW9uIG5ld0ludmFsaWRWYWx1ZUV4Y2VwdGlvbihTdHJpbmcga2V5LCBPYmplY3QuLi4gYXJncykgewogICAgICAgIHJldHVybiBuZXcgT3B0aW9uLkludmFsaWRWYWx1ZUV4Y2VwdGlvbihnZXRMb2coKS5sb2NhbGl6ZShQcmVmaXhLaW5kLkpBVkFDLCBrZXksIGFyZ3MpKTsKICAgIH0KCiAgICAvKiogUmVjb3JkIGEgZmlsZSB0byBiZSBjb21waWxlZC4gKi8KICAgIGFic3RyYWN0IHZvaWQgYWRkRmlsZShQYXRoIHApOwoKICAgIC8qKiBSZWNvcmQgdGhlIG5hbWUgb2YgYSBjbGFzcyBmb3IgYW5ub3RhdGlvbiBwcm9jZXNzaW5nLiAqLwogICAgYWJzdHJhY3Qgdm9pZCBhZGRDbGFzc05hbWUoU3RyaW5nIHMpOwoKICAgIC8qKiBBbiBpbXBsZW1lbnRhdGlvbiBvZiBPcHRpb25IZWxwZXIgdGhhdCBtb3N0bHkgdGhyb3dzIGV4Y2VwdGlvbnMuICovCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIEdydW1weUhlbHBlciBleHRlbmRzIE9wdGlvbkhlbHBlciB7CiAgICAgICAgcHJpdmF0ZSBmaW5hbCBMb2cgbG9nOwoKICAgICAgICBwdWJsaWMgR3J1bXB5SGVscGVyKExvZyBsb2cpIHsKICAgICAgICAgICAgdGhpcy5sb2cgPSBsb2c7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgTG9nIGdldExvZygpIHsKICAgICAgICAgICAgcmV0dXJuIGxvZzsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0T3duTmFtZSgpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFN0cmluZyBnZXQoT3B0aW9uIG9wdGlvbikgewogICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCBwdXQoU3RyaW5nIG5hbWUsIFN0cmluZyB2YWx1ZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCByZW1vdmUoU3RyaW5nIG5hbWUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gaGFuZGxlRmlsZU1hbmFnZXJPcHRpb24oT3B0aW9uIG9wdGlvbiwgU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIGFkZEZpbGUoUGF0aCBwKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24ocC50b1N0cmluZygpKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIGFkZENsYXNzTmFtZShTdHJpbmcgcykgewogICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKHMpOwogICAgICAgIH0KICAgIH0KCn0KUEsDBAoAAAgAAAY7qUpW+rucVzsAAFc7AAAiAAAAY29tL3N1bi90b29scy9qYXZhYy9tYWluL01haW4uamF2YS8qCiAqIENvcHlyaWdodCAoYykgMTk5OSwgMjAxNywgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLmphdmFjLm1haW47CgppbXBvcnQgamF2YS5pby5GaWxlTm90Rm91bmRFeGNlcHRpb247CmltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwppbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKaW1wb3J0IGphdmEuaW8uUHJpbnRXcml0ZXI7CmltcG9ydCBqYXZhLm5ldC5VUkw7CmltcG9ydCBqYXZhLm5pby5maWxlLk5vU3VjaEZpbGVFeGNlcHRpb247CmltcG9ydCBqYXZhLnNlY3VyaXR5LkRpZ2VzdElucHV0U3RyZWFtOwppbXBvcnQgamF2YS5zZWN1cml0eS5NZXNzYWdlRGlnZXN0OwppbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hBbGdvcml0aG1FeGNlcHRpb247CmltcG9ydCBqYXZhLnV0aWwuU2V0OwoKaW1wb3J0IGphdmF4LnRvb2xzLkphdmFGaWxlTWFuYWdlcjsKCmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmFwaS5CYXNpY0phdmFjVGFzazsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuZmlsZS5DYWNoZUZTSW5mbzsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuZmlsZS5CYXNlRmlsZU1hbmFnZXI7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmZpbGUuSmF2YWNGaWxlTWFuYWdlcjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuanZtLlRhcmdldDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMubWFpbi5Db21tYW5kTGluZS5Vbm1hdGNoZWRRdW90ZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMucGxhdGZvcm0uUGxhdGZvcm1EZXNjcmlwdGlvbjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMucHJvY2Vzc2luZy5Bbm5vdGF0aW9uUHJvY2Vzc2luZ0Vycm9yOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLio7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuTG9nLlByZWZpeEtpbmQ7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuTG9nLldyaXRlcktpbmQ7CgovKiogVGhpcyBjbGFzcyBwcm92aWRlcyBhIGNvbW1hbmQgbGluZSBpbnRlcmZhY2UgdG8gdGhlIGphdmFjIGNvbXBpbGVyLgogKgogKiAgPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24gcmlzay4KICogIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yCiAqICBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+CiAqLwpwdWJsaWMgY2xhc3MgTWFpbiB7CgogICAgLyoqIFRoZSBuYW1lIG9mIHRoZSBjb21waWxlciwgZm9yIHVzZSBpbiBkaWFnbm9zdGljcy4KICAgICAqLwogICAgU3RyaW5nIG93bk5hbWU7CgogICAgLyoqIFRoZSB3cml0ZXIgdG8gdXNlIGZvciBub3JtYWwgb3V0cHV0LgogICAgICovCiAgICBQcmludFdyaXRlciBzdGRPdXQ7CgogICAgLyoqIFRoZSB3cml0ZXIgdG8gdXNlIGZvciBkaWFnbm9zdGljIG91dHB1dC4KICAgICAqLwogICAgUHJpbnRXcml0ZXIgc3RkRXJyOwoKICAgIC8qKiBUaGUgbG9nIHRvIHVzZSBmb3IgZGlhZ25vc3RpYyBvdXRwdXQuCiAgICAgKi8KICAgIHB1YmxpYyBMb2cgbG9nOwoKICAgIC8qKgogICAgICogSWYgdHJ1ZSwgY2VydGFpbiBlcnJvcnMgd2lsbCBjYXVzZSBhbiBleGNlcHRpb24sIHN1Y2ggYXMgY29tbWFuZCBsaW5lCiAgICAgKiBhcmcgZXJyb3JzLCBvciBleGNlcHRpb25zIGluIHVzZXIgcHJvdmlkZWQgY29kZS4KICAgICAqLwogICAgYm9vbGVhbiBhcGlNb2RlOwoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBFTlZfT1BUX05BTUUgPSAiSkRLX0pBVkFDX09QVElPTlMiOwoKICAgIC8qKiBSZXN1bHQgY29kZXMuCiAgICAgKi8KICAgIHB1YmxpYyBlbnVtIFJlc3VsdCB7CiAgICAgICAgT0soMCksICAgICAgICAvLyBDb21waWxhdGlvbiBjb21wbGV0ZWQgd2l0aCBubyBlcnJvcnMuCiAgICAgICAgRVJST1IoMSksICAgICAvLyBDb21wbGV0ZWQgYnV0IHJlcG9ydGVkIGVycm9ycy4KICAgICAgICBDTURFUlIoMiksICAgIC8vIEJhZCBjb21tYW5kLWxpbmUgYXJndW1lbnRzCiAgICAgICAgU1lTRVJSKDMpLCAgICAvLyBTeXN0ZW0gZXJyb3Igb3IgcmVzb3VyY2UgZXhoYXVzdGlvbi4KICAgICAgICBBQk5PUk1BTCg0KTsgIC8vIENvbXBpbGVyIHRlcm1pbmF0ZWQgYWJub3JtYWxseQoKICAgICAgICBSZXN1bHQoaW50IGV4aXRDb2RlKSB7CiAgICAgICAgICAgIHRoaXMuZXhpdENvZGUgPSBleGl0Q29kZTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBib29sZWFuIGlzT0soKSB7CiAgICAgICAgICAgIHJldHVybiAoZXhpdENvZGUgPT0gMCk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgZmluYWwgaW50IGV4aXRDb2RlOwogICAgfQoKICAgIC8qKgogICAgICogQ29uc3RydWN0IGEgY29tcGlsZXIgaW5zdGFuY2UuCiAgICAgKiBAcGFyYW0gbmFtZSB0aGUgbmFtZSBvZiB0aGlzIHRvb2wKICAgICAqLwogICAgcHVibGljIE1haW4oU3RyaW5nIG5hbWUpIHsKICAgICAgICB0aGlzLm93bk5hbWUgPSBuYW1lOwogICAgfQoKICAgIC8qKgogICAgICogQ29uc3RydWN0IGEgY29tcGlsZXIgaW5zdGFuY2UuCiAgICAgKiBAcGFyYW0gbmFtZSB0aGUgbmFtZSBvZiB0aGlzIHRvb2wKICAgICAqIEBwYXJhbSBvdXQgYSBzdHJlYW0gdG8gd2hpY2ggdG8gd3JpdGUgbWVzc2FnZXMKICAgICAqLwogICAgcHVibGljIE1haW4oU3RyaW5nIG5hbWUsIFByaW50V3JpdGVyIG91dCkgewogICAgICAgIHRoaXMub3duTmFtZSA9IG5hbWU7CiAgICAgICAgdGhpcy5zdGRPdXQgPSB0aGlzLnN0ZEVyciA9IG91dDsKICAgIH0KCiAgICAvKioKICAgICAqIENvbnN0cnVjdCBhIGNvbXBpbGVyIGluc3RhbmNlLgogICAgICogQHBhcmFtIG5hbWUgdGhlIG5hbWUgb2YgdGhpcyB0b29sCiAgICAgKiBAcGFyYW0gb3V0IGEgc3RyZWFtIHRvIHdoaWNoIHRvIHdyaXRlIGV4cGVjdGVkIG91dHB1dAogICAgICogQHBhcmFtIGVyciBhIHN0cmVhbSB0byB3aGljaCB0byB3cml0ZSBkaWFnbm9zdGljIG91dHB1dAogICAgICovCiAgICBwdWJsaWMgTWFpbihTdHJpbmcgbmFtZSwgUHJpbnRXcml0ZXIgb3V0LCBQcmludFdyaXRlciBlcnIpIHsKICAgICAgICB0aGlzLm93bk5hbWUgPSBuYW1lOwogICAgICAgIHRoaXMuc3RkT3V0ID0gb3V0OwogICAgICAgIHRoaXMuc3RkRXJyID0gZXJyOwogICAgfQoKICAgIC8qKiBSZXBvcnQgYSB1c2FnZSBlcnJvci4KICAgICAqLwogICAgdm9pZCBlcnJvcihTdHJpbmcga2V5LCBPYmplY3QuLi4gYXJncykgewogICAgICAgIGlmIChhcGlNb2RlKSB7CiAgICAgICAgICAgIFN0cmluZyBtc2cgPSBsb2cubG9jYWxpemUoUHJlZml4S2luZC5KQVZBQywga2V5LCBhcmdzKTsKICAgICAgICAgICAgdGhyb3cgbmV3IFByb3BhZ2F0ZWRFeGNlcHRpb24obmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbihtc2cpKTsKICAgICAgICB9CiAgICAgICAgd2FybmluZyhrZXksIGFyZ3MpOwogICAgICAgIGxvZy5wcmludExpbmVzKFByZWZpeEtpbmQuSkFWQUMsICJtc2cudXNhZ2UiLCBvd25OYW1lKTsKICAgIH0KCiAgICAvKiogUmVwb3J0IGEgd2FybmluZy4KICAgICAqLwogICAgdm9pZCB3YXJuaW5nKFN0cmluZyBrZXksIE9iamVjdC4uLiBhcmdzKSB7CiAgICAgICAgbG9nLnByaW50UmF3TGluZXMob3duTmFtZSArICI6ICIgKyBsb2cubG9jYWxpemUoUHJlZml4S2luZC5KQVZBQywga2V5LCBhcmdzKSk7CiAgICB9CgoKICAgIC8qKgogICAgICogUHJvZ3JhbW1hdGljIGludGVyZmFjZSBmb3IgbWFpbiBmdW5jdGlvbi4KICAgICAqIEBwYXJhbSBhcmdzICB0aGUgY29tbWFuZCBsaW5lIHBhcmFtZXRlcnMKICAgICAqIEByZXR1cm4gdGhlIHJlc3VsdCBvZiB0aGUgY29tcGlsYXRpb24KICAgICAqLwogICAgcHVibGljIFJlc3VsdCBjb21waWxlKFN0cmluZ1tdIGFyZ3MpIHsKICAgICAgICBDb250ZXh0IGNvbnRleHQgPSBuZXcgQ29udGV4dCgpOwogICAgICAgIEphdmFjRmlsZU1hbmFnZXIucHJlUmVnaXN0ZXIoY29udGV4dCk7IC8vIGNhbid0IGNyZWF0ZSBpdCB1bnRpbCBMb2cgaGFzIGJlZW4gc2V0IHVwCiAgICAgICAgUmVzdWx0IHJlc3VsdCA9IGNvbXBpbGUoYXJncywgY29udGV4dCk7CiAgICAgICAgaWYgKGZpbGVNYW5hZ2VyIGluc3RhbmNlb2YgSmF2YWNGaWxlTWFuYWdlcikgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgLy8gQSBmcmVzaCBjb250ZXh0IHdhcyBjcmVhdGVkIGFib3ZlLCBzbyBqZm0gbXVzdCBiZSBhIEphdmFjRmlsZU1hbmFnZXIKICAgICAgICAgICAgICAgICgoSmF2YWNGaWxlTWFuYWdlcilmaWxlTWFuYWdlcikuY2xvc2UoKTsKICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKICAgICAgICAgICAgICAgIGJ1Z01lc3NhZ2UoZXgpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBJbnRlcm5hbCB2ZXJzaW9uIG9mIGNvbXBpbGUsIGFsbG93aW5nIGNvbnRleHQgdG8gYmUgcHJvdmlkZWQuCiAgICAgKiBOb3RlIHRoYXQgdGhlIGNvbnRleHQgbmVlZHMgdG8gaGF2ZSBhIGZpbGUgbWFuYWdlciBzZXQgdXAuCiAgICAgKiBAcGFyYW0gYXJndiAgdGhlIGNvbW1hbmQgbGluZSBwYXJhbWV0ZXJzCiAgICAgKiBAcGFyYW0gY29udGV4dCB0aGUgY29udGV4dAogICAgICogQHJldHVybiB0aGUgcmVzdWx0IG9mIHRoZSBjb21waWxhdGlvbgogICAgICovCiAgICBwdWJsaWMgUmVzdWx0IGNvbXBpbGUoU3RyaW5nW10gYXJndiwgQ29udGV4dCBjb250ZXh0KSB7CiAgICAgICAgaWYgKHN0ZE91dCAhPSBudWxsKSB7CiAgICAgICAgICAgIGNvbnRleHQucHV0KExvZy5vdXRLZXksIHN0ZE91dCk7CiAgICAgICAgfQoKICAgICAgICBpZiAoc3RkRXJyICE9IG51bGwpIHsKICAgICAgICAgICAgY29udGV4dC5wdXQoTG9nLmVycktleSwgc3RkRXJyKTsKICAgICAgICB9CgogICAgICAgIGxvZyA9IExvZy5pbnN0YW5jZShjb250ZXh0KTsKCiAgICAgICAgaWYgKGFyZ3YubGVuZ3RoID09IDApIHsKICAgICAgICAgICAgT3B0aW9uSGVscGVyIGggPSBuZXcgT3B0aW9uSGVscGVyLkdydW1weUhlbHBlcihsb2cpIHsKICAgICAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICAgICAgcHVibGljIFN0cmluZyBnZXRPd25OYW1lKCkgeyByZXR1cm4gb3duTmFtZTsgfQogICAgICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCBwdXQoU3RyaW5nIG5hbWUsIFN0cmluZyB2YWx1ZSkgeyB9CiAgICAgICAgICAgIH07CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBPcHRpb24uSEVMUC5wcm9jZXNzKGgsICItaGVscCIpOwogICAgICAgICAgICB9IGNhdGNoIChPcHRpb24uSW52YWxpZFZhbHVlRXhjZXB0aW9uIGlnbm9yZSkgewogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBSZXN1bHQuQ01ERVJSOwogICAgICAgIH0KCiAgICAgICAgLy8gcHJlZml4IGFyZ3Ygd2l0aCBjb250ZW50cyBvZiBlbnZpcm9ubWVudCB2YXJpYWJsZSBhbmQgZXhwYW5kIEAtZmlsZXMKICAgICAgICB0cnkgewogICAgICAgICAgICBhcmd2ID0gQ29tbWFuZExpbmUucGFyc2UoRU5WX09QVF9OQU1FLCBhcmd2KTsKICAgICAgICB9IGNhdGNoIChVbm1hdGNoZWRRdW90ZSBleCkgewogICAgICAgICAgICBlcnJvcigiZXJyLnVubWF0Y2hlZC5xdW90ZSIsIGV4LnZhcmlhYmxlTmFtZSk7CiAgICAgICAgICAgIHJldHVybiBSZXN1bHQuQ01ERVJSOwogICAgICAgIH0gY2F0Y2ggKEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiB8IE5vU3VjaEZpbGVFeGNlcHRpb24gZSkgewogICAgICAgICAgICB3YXJuaW5nKCJlcnIuZmlsZS5ub3QuZm91bmQiLCBlLmdldE1lc3NhZ2UoKSk7CiAgICAgICAgICAgIHJldHVybiBSZXN1bHQuU1lTRVJSOwogICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7CiAgICAgICAgICAgIGxvZy5wcmludExpbmVzKFByZWZpeEtpbmQuSkFWQUMsICJtc2cuaW8iKTsKICAgICAgICAgICAgZXgucHJpbnRTdGFja1RyYWNlKGxvZy5nZXRXcml0ZXIoV3JpdGVyS2luZC5OT1RJQ0UpKTsKICAgICAgICAgICAgcmV0dXJuIFJlc3VsdC5TWVNFUlI7CiAgICAgICAgfQoKICAgICAgICBBcmd1bWVudHMgYXJncyA9IEFyZ3VtZW50cy5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBhcmdzLmluaXQob3duTmFtZSwgYXJndik7CgogICAgICAgIGlmIChsb2cubmVycm9ycyA+IDApCiAgICAgICAgICAgIHJldHVybiBSZXN1bHQuQ01ERVJSOwoKICAgICAgICBPcHRpb25zIG9wdGlvbnMgPSBPcHRpb25zLmluc3RhbmNlKGNvbnRleHQpOwoKICAgICAgICAvLyBpbml0IExvZwogICAgICAgIGJvb2xlYW4gZm9yY2VTdGRPdXQgPSBvcHRpb25zLmlzU2V0KCJzdGRvdXQiKTsKICAgICAgICBpZiAoZm9yY2VTdGRPdXQpIHsKICAgICAgICAgICAgbG9nLmZsdXNoKCk7CiAgICAgICAgICAgIGxvZy5zZXRXcml0ZXJzKG5ldyBQcmludFdyaXRlcihTeXN0ZW0ub3V0LCB0cnVlKSk7CiAgICAgICAgfQoKICAgICAgICAvLyBpbml0IENhY2hlRlNJbmZvCiAgICAgICAgLy8gYWxsb3cgU3lzdGVtIHByb3BlcnR5IGluIGZvbGxvd2luZyBsaW5lIGFzIGEgTXVzdGFuZyBsZWdhY3kKICAgICAgICBib29sZWFuIGJhdGNoTW9kZSA9IChvcHRpb25zLmlzVW5zZXQoIm5vbkJhdGNoTW9kZSIpCiAgICAgICAgICAgICAgICAgICAgJiYgU3lzdGVtLmdldFByb3BlcnR5KCJub25CYXRjaE1vZGUiKSA9PSBudWxsKTsKICAgICAgICBpZiAoYmF0Y2hNb2RlKQogICAgICAgICAgICBDYWNoZUZTSW5mby5wcmVSZWdpc3Rlcihjb250ZXh0KTsKCiAgICAgICAgYm9vbGVhbiBvayA9IHRydWU7CgogICAgICAgIC8vIGluaXQgZmlsZSBtYW5hZ2VyCiAgICAgICAgZmlsZU1hbmFnZXIgPSBjb250ZXh0LmdldChKYXZhRmlsZU1hbmFnZXIuY2xhc3MpOwogICAgICAgIGlmIChmaWxlTWFuYWdlciBpbnN0YW5jZW9mIEJhc2VGaWxlTWFuYWdlcikgewogICAgICAgICAgICAoKEJhc2VGaWxlTWFuYWdlcikgZmlsZU1hbmFnZXIpLnNldENvbnRleHQoY29udGV4dCk7IC8vIHJlaW5pdCB3aXRoIG9wdGlvbnMKICAgICAgICAgICAgb2sgJj0gKChCYXNlRmlsZU1hbmFnZXIpIGZpbGVNYW5hZ2VyKS5oYW5kbGVPcHRpb25zKGFyZ3MuZ2V0RGVmZXJyZWRGaWxlTWFuYWdlck9wdGlvbnMoKSk7CiAgICAgICAgfQoKICAgICAgICAvLyBoYW5kbGUgdGhpcyBoZXJlIHNvIGl0IHdvcmtzIGV2ZW4gaWYgbm8gb3RoZXIgb3B0aW9ucyBnaXZlbgogICAgICAgIFN0cmluZyBzaG93Q2xhc3MgPSBvcHRpb25zLmdldCgic2hvd0NsYXNzIik7CiAgICAgICAgaWYgKHNob3dDbGFzcyAhPSBudWxsKSB7CiAgICAgICAgICAgIGlmIChzaG93Q2xhc3MuZXF1YWxzKCJzaG93Q2xhc3MiKSkgLy8gbm8gdmFsdWUgZ2l2ZW4gZm9yIG9wdGlvbgogICAgICAgICAgICAgICAgc2hvd0NsYXNzID0gImNvbS5zdW4udG9vbHMuamF2YWMuTWFpbiI7CiAgICAgICAgICAgIHNob3dDbGFzcyhzaG93Q2xhc3MpOwogICAgICAgIH0KCiAgICAgICAgb2sgJj0gYXJncy52YWxpZGF0ZSgpOwogICAgICAgIGlmICghb2sgfHwgbG9nLm5lcnJvcnMgPiAwKQogICAgICAgICAgICByZXR1cm4gUmVzdWx0LkNNREVSUjsKCiAgICAgICAgaWYgKGFyZ3MuaXNFbXB0eSgpKQogICAgICAgICAgICByZXR1cm4gUmVzdWx0Lk9LOwoKICAgICAgICAvLyBpbml0IERlcGVuZGVuY2llcwogICAgICAgIGlmIChvcHRpb25zLmlzU2V0KCJkZWJ1Zy5jb21wbGV0aW9uRGVwcyIpKSB7CiAgICAgICAgICAgIERlcGVuZGVuY2llcy5HcmFwaERlcGVuZGVuY2llcy5wcmVSZWdpc3Rlcihjb250ZXh0KTsKICAgICAgICB9CgogICAgICAgIC8vIGluaXQgcGx1Z2lucwogICAgICAgIFNldDxMaXN0PFN0cmluZz4+IHBsdWdpbk9wdHMgPSBhcmdzLmdldFBsdWdpbk9wdHMoKTsKICAgICAgICBpZiAoIXBsdWdpbk9wdHMuaXNFbXB0eSgpIHx8IGNvbnRleHQuZ2V0KFBsYXRmb3JtRGVzY3JpcHRpb24uY2xhc3MpICE9IG51bGwpIHsKICAgICAgICAgICAgQmFzaWNKYXZhY1Rhc2sgdCA9IChCYXNpY0phdmFjVGFzaykgQmFzaWNKYXZhY1Rhc2suaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgICAgIHQuaW5pdFBsdWdpbnMocGx1Z2luT3B0cyk7CiAgICAgICAgfQoKICAgICAgICAvLyBpbml0IG11bHRpLXJlbGVhc2UgamFyIGhhbmRsaW5nCiAgICAgICAgaWYgKGZpbGVNYW5hZ2VyLmlzU3VwcG9ydGVkT3B0aW9uKE9wdGlvbi5NVUxUSVJFTEVBU0UucHJpbWFyeU5hbWUpID09IDEpIHsKICAgICAgICAgICAgVGFyZ2V0IHRhcmdldCA9IFRhcmdldC5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICAgICAgTGlzdDxTdHJpbmc+IGxpc3QgPSBMaXN0Lm9mKHRhcmdldC5tdWx0aVJlbGVhc2VWYWx1ZSgpKTsKICAgICAgICAgICAgZmlsZU1hbmFnZXIuaGFuZGxlT3B0aW9uKE9wdGlvbi5NVUxUSVJFTEVBU0UucHJpbWFyeU5hbWUsIGxpc3QuaXRlcmF0b3IoKSk7CiAgICAgICAgfQoKICAgICAgICAvLyBpbml0IEphdmFDb21waWxlcgogICAgICAgIEphdmFDb21waWxlciBjb21wID0gSmF2YUNvbXBpbGVyLmluc3RhbmNlKGNvbnRleHQpOwoKICAgICAgICAvLyBpbml0IGRvY2xpbnQKICAgICAgICBMaXN0PFN0cmluZz4gZG9jTGludE9wdHMgPSBhcmdzLmdldERvY0xpbnRPcHRzKCk7CiAgICAgICAgaWYgKCFkb2NMaW50T3B0cy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgQmFzaWNKYXZhY1Rhc2sgdCA9IChCYXNpY0phdmFjVGFzaykgQmFzaWNKYXZhY1Rhc2suaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgICAgIHQuaW5pdERvY0xpbnQoZG9jTGludE9wdHMpOwogICAgICAgIH0KCiAgICAgICAgaWYgKG9wdGlvbnMuZ2V0KE9wdGlvbi5YU1RET1VUKSAhPSBudWxsKSB7CiAgICAgICAgICAgIC8vIFN0ZG91dCByZWFzc2lnbmVkIC0gYXNrIGNvbXBpbGVyIHRvIGNsb3NlIGl0IHdoZW4gaXQgaXMgZG9uZQogICAgICAgICAgICBjb21wLmNsb3NlYWJsZXMgPSBjb21wLmNsb3NlYWJsZXMucHJlcGVuZChsb2cuZ2V0V3JpdGVyKFdyaXRlcktpbmQuTk9USUNFKSk7CiAgICAgICAgfQoKICAgICAgICB0cnkgewogICAgICAgICAgICBjb21wLmNvbXBpbGUoYXJncy5nZXRGaWxlT2JqZWN0cygpLCBhcmdzLmdldENsYXNzTmFtZXMoKSwgbnVsbCwgTGlzdC5uaWwoKSk7CgogICAgICAgICAgICBpZiAobG9nLmV4cGVjdERpYWdLZXlzICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIGlmIChsb2cuZXhwZWN0RGlhZ0tleXMuaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgICAgICAgbG9nLnByaW50UmF3TGluZXMoImFsbCBleHBlY3RlZCBkaWFnbm9zdGljcyBmb3VuZCIpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBSZXN1bHQuT0s7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGxvZy5wcmludFJhd0xpbmVzKCJleHBlY3RlZCBkaWFnbm9zdGljIGtleXMgbm90IGZvdW5kOiAiICsgbG9nLmV4cGVjdERpYWdLZXlzKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gUmVzdWx0LkVSUk9SOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gKGNvbXAuZXJyb3JDb3VudCgpID09IDApID8gUmVzdWx0Lk9LIDogUmVzdWx0LkVSUk9SOwoKICAgICAgICB9IGNhdGNoIChPdXRPZk1lbW9yeUVycm9yIHwgU3RhY2tPdmVyZmxvd0Vycm9yIGV4KSB7CiAgICAgICAgICAgIHJlc291cmNlTWVzc2FnZShleCk7CiAgICAgICAgICAgIHJldHVybiBSZXN1bHQuU1lTRVJSOwogICAgICAgIH0gY2F0Y2ggKEZhdGFsRXJyb3IgZXgpIHsKICAgICAgICAgICAgZmVNZXNzYWdlKGV4LCBvcHRpb25zKTsKICAgICAgICAgICAgcmV0dXJuIFJlc3VsdC5TWVNFUlI7CiAgICAgICAgfSBjYXRjaCAoQW5ub3RhdGlvblByb2Nlc3NpbmdFcnJvciBleCkgewogICAgICAgICAgICBhcE1lc3NhZ2UoZXgpOwogICAgICAgICAgICByZXR1cm4gUmVzdWx0LlNZU0VSUjsKICAgICAgICB9IGNhdGNoIChQcm9wYWdhdGVkRXhjZXB0aW9uIGV4KSB7CiAgICAgICAgICAgIC8vIFRPRE86IHdoYXQgYWJvdXQgZXJyb3JzIGZyb20gcGx1Z2lucz8gICBzaG91bGQgbm90IHNpbXBseSByZXRocm93IHRoZSBlcnJvciBoZXJlCiAgICAgICAgICAgIHRocm93IGV4LmdldENhdXNlKCk7CiAgICAgICAgfSBjYXRjaCAoVGhyb3dhYmxlIGV4KSB7CiAgICAgICAgICAgIC8vIE5hc3R5LiAgSWYgd2UndmUgYWxyZWFkeSByZXBvcnRlZCBhbiBlcnJvciwgY29tcGVuc2F0ZQogICAgICAgICAgICAvLyBmb3IgYnVnZ3kgY29tcGlsZXIgZXJyb3IgcmVjb3ZlcnkgYnkgc3dhbGxvd2luZyB0aHJvd24KICAgICAgICAgICAgLy8gZXhjZXB0aW9ucy4KICAgICAgICAgICAgaWYgKGNvbXAgPT0gbnVsbCB8fCBjb21wLmVycm9yQ291bnQoKSA9PSAwIHx8IG9wdGlvbnMuaXNTZXQoImRldiIpKQogICAgICAgICAgICAgICAgYnVnTWVzc2FnZShleCk7CiAgICAgICAgICAgIHJldHVybiBSZXN1bHQuQUJOT1JNQUw7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgaWYgKGNvbXAgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICBjb21wLmNsb3NlKCk7CiAgICAgICAgICAgICAgICB9IGNhdGNoIChDbGllbnRDb2RlRXhjZXB0aW9uIGV4KSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oZXguZ2V0Q2F1c2UoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqIFByaW50IGEgbWVzc2FnZSByZXBvcnRpbmcgYW4gaW50ZXJuYWwgZXJyb3IuCiAgICAgKi8KICAgIHZvaWQgYnVnTWVzc2FnZShUaHJvd2FibGUgZXgpIHsKICAgICAgICBsb2cucHJpbnRMaW5lcyhQcmVmaXhLaW5kLkpBVkFDLCAibXNnLmJ1ZyIsIEphdmFDb21waWxlci52ZXJzaW9uKCkpOwogICAgICAgIGV4LnByaW50U3RhY2tUcmFjZShsb2cuZ2V0V3JpdGVyKFdyaXRlcktpbmQuTk9USUNFKSk7CiAgICB9CgogICAgLyoqIFByaW50IGEgbWVzc2FnZSByZXBvcnRpbmcgYSBmYXRhbCBlcnJvci4KICAgICAqLwogICAgdm9pZCBmZU1lc3NhZ2UoVGhyb3dhYmxlIGV4LCBPcHRpb25zIG9wdGlvbnMpIHsKICAgICAgICBsb2cucHJpbnRSYXdMaW5lcyhleC5nZXRNZXNzYWdlKCkpOwogICAgICAgIGlmIChleC5nZXRDYXVzZSgpICE9IG51bGwgJiYgb3B0aW9ucy5pc1NldCgiZGV2IikpIHsKICAgICAgICAgICAgZXguZ2V0Q2F1c2UoKS5wcmludFN0YWNrVHJhY2UobG9nLmdldFdyaXRlcihXcml0ZXJLaW5kLk5PVElDRSkpOwogICAgICAgIH0KICAgIH0KCiAgICAvKiogUHJpbnQgYSBtZXNzYWdlIHJlcG9ydGluZyBhbiBpbnB1dC9vdXRwdXQgZXJyb3IuCiAgICAgKi8KICAgIHZvaWQgaW9NZXNzYWdlKFRocm93YWJsZSBleCkgewogICAgICAgIGxvZy5wcmludExpbmVzKFByZWZpeEtpbmQuSkFWQUMsICJtc2cuaW8iKTsKICAgICAgICBleC5wcmludFN0YWNrVHJhY2UobG9nLmdldFdyaXRlcihXcml0ZXJLaW5kLk5PVElDRSkpOwogICAgfQoKICAgIC8qKiBQcmludCBhIG1lc3NhZ2UgcmVwb3J0aW5nIGFuIG91dC1vZi1yZXNvdXJjZXMgZXJyb3IuCiAgICAgKi8KICAgIHZvaWQgcmVzb3VyY2VNZXNzYWdlKFRocm93YWJsZSBleCkgewogICAgICAgIGxvZy5wcmludExpbmVzKFByZWZpeEtpbmQuSkFWQUMsICJtc2cucmVzb3VyY2UiKTsKICAgICAgICBleC5wcmludFN0YWNrVHJhY2UobG9nLmdldFdyaXRlcihXcml0ZXJLaW5kLk5PVElDRSkpOwogICAgfQoKICAgIC8qKiBQcmludCBhIG1lc3NhZ2UgcmVwb3J0aW5nIGFuIHVuY2F1Z2h0IGV4Y2VwdGlvbiBmcm9tIGFuCiAgICAgKiBhbm5vdGF0aW9uIHByb2Nlc3Nvci4KICAgICAqLwogICAgdm9pZCBhcE1lc3NhZ2UoQW5ub3RhdGlvblByb2Nlc3NpbmdFcnJvciBleCkgewogICAgICAgIGxvZy5wcmludExpbmVzKFByZWZpeEtpbmQuSkFWQUMsICJtc2cucHJvYy5hbm5vdGF0aW9uLnVuY2F1Z2h0LmV4Y2VwdGlvbiIpOwogICAgICAgIGV4LmdldENhdXNlKCkucHJpbnRTdGFja1RyYWNlKGxvZy5nZXRXcml0ZXIoV3JpdGVyS2luZC5OT1RJQ0UpKTsKICAgIH0KCiAgICAvKiogUHJpbnQgYSBtZXNzYWdlIHJlcG9ydGluZyBhbiB1bmNhdWdodCBleGNlcHRpb24gZnJvbSBhbgogICAgICogYW5ub3RhdGlvbiBwcm9jZXNzb3IuCiAgICAgKi8KICAgIHZvaWQgcGx1Z2luTWVzc2FnZShUaHJvd2FibGUgZXgpIHsKICAgICAgICBsb2cucHJpbnRMaW5lcyhQcmVmaXhLaW5kLkpBVkFDLCAibXNnLnBsdWdpbi51bmNhdWdodC5leGNlcHRpb24iKTsKICAgICAgICBleC5wcmludFN0YWNrVHJhY2UobG9nLmdldFdyaXRlcihXcml0ZXJLaW5kLk5PVElDRSkpOwogICAgfQoKICAgIC8qKiBEaXNwbGF5IHRoZSBsb2NhdGlvbiBhbmQgY2hlY2tzdW0gb2YgYSBjbGFzcy4gKi8KICAgIHZvaWQgc2hvd0NsYXNzKFN0cmluZyBjbGFzc05hbWUpIHsKICAgICAgICBQcmludFdyaXRlciBwdyA9IGxvZy5nZXRXcml0ZXIoV3JpdGVyS2luZC5OT1RJQ0UpOwogICAgICAgIHB3LnByaW50bG4oImphdmFjOiBzaG93IGNsYXNzOiAiICsgY2xhc3NOYW1lKTsKCiAgICAgICAgVVJMIHVybCA9IGdldENsYXNzKCkuZ2V0UmVzb3VyY2UoJy8nICsgY2xhc3NOYW1lLnJlcGxhY2UoJy4nLCAnLycpICsgIi5jbGFzcyIpOwogICAgICAgIGlmICh1cmwgIT0gbnVsbCkgewogICAgICAgICAgICBwdy5wcmludGxuKCIgICIgKyB1cmwpOwogICAgICAgIH0KCiAgICAgICAgdHJ5IChJbnB1dFN0cmVhbSBpbiA9IGdldENsYXNzKCkuZ2V0UmVzb3VyY2VBc1N0cmVhbSgnLycgKyBjbGFzc05hbWUucmVwbGFjZSgnLicsICcvJykgKyAiLmNsYXNzIikpIHsKICAgICAgICAgICAgZmluYWwgU3RyaW5nIGFsZ29yaXRobSA9ICJNRDUiOwogICAgICAgICAgICBieXRlW10gZGlnZXN0OwogICAgICAgICAgICBNZXNzYWdlRGlnZXN0IG1kID0gTWVzc2FnZURpZ2VzdC5nZXRJbnN0YW5jZShhbGdvcml0aG0pOwogICAgICAgICAgICB0cnkgKERpZ2VzdElucHV0U3RyZWFtIGRpbiA9IG5ldyBEaWdlc3RJbnB1dFN0cmVhbShpbiwgbWQpKSB7CiAgICAgICAgICAgICAgICBieXRlW10gYnVmID0gbmV3IGJ5dGVbODE5Ml07CiAgICAgICAgICAgICAgICBpbnQgbjsKICAgICAgICAgICAgICAgIGRvIHsgbiA9IGRpbi5yZWFkKGJ1Zik7IH0gd2hpbGUgKG4gPiAwKTsKICAgICAgICAgICAgICAgIGRpZ2VzdCA9IG1kLmRpZ2VzdCgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigpOwogICAgICAgICAgICBmb3IgKGJ5dGUgYjogZGlnZXN0KQogICAgICAgICAgICAgICAgc2IuYXBwZW5kKFN0cmluZy5mb3JtYXQoIiUwMngiLCBiKSk7CiAgICAgICAgICAgIHB3LnByaW50bG4oIiAgIiArIGFsZ29yaXRobSArICIgY2hlY2tzdW06ICIgKyBzYik7CiAgICAgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIHwgSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICBwdy5wcmludGxuKCIgIGNhbm5vdCBjb21wdXRlIGRpZ2VzdDogIiArIGUpOwogICAgICAgIH0KICAgIH0KCiAgICAvLyBUT0RPOiB1cGRhdGUgdGhpcyB0byBKYXZhY0ZpbGVNYW5hZ2VyCiAgICBwcml2YXRlIEphdmFGaWxlTWFuYWdlciBmaWxlTWFuYWdlcjsKCiAgICAvKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICAgICAqIEludGVybmF0aW9uYWxpemF0aW9uCiAgICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBqYXZhY0J1bmRsZU5hbWUgPQogICAgICAgICJjb20uc3VuLnRvb2xzLmphdmFjLnJlc291cmNlcy5qYXZhYyI7Cn0KUEsDBAoAAAgAAAY7qUoAAAAAAAAAAAAAAAAYAAAAY29tL3N1bi90b29scy9qYXZhYy9qdm0vUEsDBAoAAAgAAAY7qUqrQai7bzIAAG8yAAAhAAAAY29tL3N1bi90b29scy9qYXZhYy9qdm0vUG9vbC5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAxOTk5LCAyMDEzLCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuamF2YWMuanZtOwoKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5TeW1ib2w7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuU3ltYm9sLio7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuVHlwZVRhZzsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5UeXBlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlR5cGVzOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlR5cGVzLlVuaXF1ZVR5cGU7CgppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkFycmF5VXRpbHM7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuQXNzZXJ0OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkZpbHRlcjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5OYW1lOwoKaW1wb3J0IGphdmEudXRpbC4qOwoKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5EZWZpbmVkQnk7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuRGVmaW5lZEJ5LkFwaTsKCmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLktpbmRzLio7CmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLktpbmRzLktpbmQuKjsKCi8qKiBBbiBpbnRlcm5hbCBzdHJ1Y3R1cmUgdGhhdCBjb3JyZXNwb25kcyB0byB0aGUgY29uc3RhbnQgcG9vbCBvZiBhIGNsYXNzZmlsZS4KICoKICogIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqICBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqICBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogKiAgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPgogKi8KcHVibGljIGNsYXNzIFBvb2wgewoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1BWF9FTlRSSUVTID0gMHhGRkZGOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFYX1NUUklOR19MRU5HVEggPSAweEZGRkY7CgogICAgLyoqIEluZGV4IG9mIG5leHQgY29uc3RhbnQgdG8gYmUgZW50ZXJlZC4KICAgICAqLwogICAgaW50IHBwOwoKICAgIC8qKiBUaGUgaW5pdGlhbCBwb29sIGJ1ZmZlci4KICAgICAqLwogICAgT2JqZWN0W10gcG9vbDsKCiAgICAvKiogQSBoYXNodGFibGUgY29udGFpbmluZyBhbGwgY29uc3RhbnRzIGluIHRoZSBwb29sLgogICAgICovCiAgICBNYXA8T2JqZWN0LEludGVnZXI+IGluZGljZXM7CgogICAgVHlwZXMgdHlwZXM7CgogICAgLyoqIENvbnN0cnVjdCBhIHBvb2wgd2l0aCBnaXZlbiBudW1iZXIgb2YgZWxlbWVudHMgYW5kIGVsZW1lbnQgYXJyYXkuCiAgICAgKi8KICAgIHB1YmxpYyBQb29sKGludCBwcCwgT2JqZWN0W10gcG9vbCwgVHlwZXMgdHlwZXMpIHsKICAgICAgICB0aGlzLnBwID0gcHA7CiAgICAgICAgdGhpcy5wb29sID0gcG9vbDsKICAgICAgICB0aGlzLnR5cGVzID0gdHlwZXM7CiAgICAgICAgdGhpcy5pbmRpY2VzID0gbmV3IEhhc2hNYXA8Pihwb29sLmxlbmd0aCk7CiAgICAgICAgZm9yIChpbnQgaSA9IDE7IGkgPCBwcDsgaSsrKSB7CiAgICAgICAgICAgIGlmIChwb29sW2ldICE9IG51bGwpIGluZGljZXMucHV0KHBvb2xbaV0sIGkpOwogICAgICAgIH0KICAgIH0KCiAgICAvKiogQ29uc3RydWN0IGFuIGVtcHR5IHBvb2wuCiAgICAgKi8KICAgIHB1YmxpYyBQb29sKFR5cGVzIHR5cGVzKSB7CiAgICAgICAgdGhpcygxLCBuZXcgT2JqZWN0WzY0XSwgdHlwZXMpOwogICAgfQoKICAgIC8qKiBSZXR1cm4gdGhlIG51bWJlciBvZiBlbnRyaWVzIGluIHRoZSBjb25zdGFudCBwb29sLgogICAgICovCiAgICBwdWJsaWMgaW50IG51bUVudHJpZXMoKSB7CiAgICAgICAgcmV0dXJuIHBwOwogICAgfQoKICAgIC8qKiBSZW1vdmUgZXZlcnl0aGluZyBmcm9tIHRoaXMgcG9vbC4KICAgICAqLwogICAgcHVibGljIHZvaWQgcmVzZXQoKSB7CiAgICAgICAgcHAgPSAxOwogICAgICAgIGluZGljZXMuY2xlYXIoKTsKICAgIH0KCiAgICAvKiogUGxhY2UgYW4gb2JqZWN0IGluIHRoZSBwb29sLCB1bmxlc3MgaXQgaXMgYWxyZWFkeSB0aGVyZS4KICAgICAqICBJZiBvYmplY3QgaXMgYSBzeW1ib2wgYWxzbyBlbnRlciBpdHMgb3duZXIgdW5sZXNzIHRoZSBvd25lciBpcyBhCiAgICAgKiAgcGFja2FnZS4gIFJldHVybiB0aGUgb2JqZWN0J3MgaW5kZXggaW4gdGhlIHBvb2wuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgcHV0KE9iamVjdCB2YWx1ZSkgewogICAgICAgIHZhbHVlID0gbWFrZVBvb2xWYWx1ZSh2YWx1ZSk7CiAgICAgICAgQXNzZXJ0LmNoZWNrKCEodmFsdWUgaW5zdGFuY2VvZiBUeXBlLlR5cGVWYXIpKTsKICAgICAgICBBc3NlcnQuY2hlY2soISh2YWx1ZSBpbnN0YW5jZW9mIFR5cGVzLlVuaXF1ZVR5cGUgJiYKICAgICAgICAgICAgICAgICAgICAgICAoKFVuaXF1ZVR5cGUpIHZhbHVlKS50eXBlIGluc3RhbmNlb2YgVHlwZS5UeXBlVmFyKSk7CiAgICAgICAgSW50ZWdlciBpbmRleCA9IGluZGljZXMuZ2V0KHZhbHVlKTsKICAgICAgICBpZiAoaW5kZXggPT0gbnVsbCkgewogICAgICAgICAgICBpbmRleCA9IHBwOwogICAgICAgICAgICBpbmRpY2VzLnB1dCh2YWx1ZSwgaW5kZXgpOwogICAgICAgICAgICBwb29sID0gQXJyYXlVdGlscy5lbnN1cmVDYXBhY2l0eShwb29sLCBwcCk7CiAgICAgICAgICAgIHBvb2xbcHArK10gPSB2YWx1ZTsKICAgICAgICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgTG9uZyB8fCB2YWx1ZSBpbnN0YW5jZW9mIERvdWJsZSkgewogICAgICAgICAgICAgICAgcG9vbCA9IEFycmF5VXRpbHMuZW5zdXJlQ2FwYWNpdHkocG9vbCwgcHApOwogICAgICAgICAgICAgICAgcG9vbFtwcCsrXSA9IG51bGw7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIGluZGV4LmludFZhbHVlKCk7CiAgICB9CgogICAgT2JqZWN0IG1ha2VQb29sVmFsdWUoT2JqZWN0IG8pIHsKICAgICAgICBpZiAobyBpbnN0YW5jZW9mIER5bmFtaWNNZXRob2RTeW1ib2wpIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyBEeW5hbWljTWV0aG9kKChEeW5hbWljTWV0aG9kU3ltYm9sKW8sIHR5cGVzKTsKICAgICAgICB9IGVsc2UgaWYgKG8gaW5zdGFuY2VvZiBNZXRob2RTeW1ib2wpIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyBNZXRob2QoKE1ldGhvZFN5bWJvbClvLCB0eXBlcyk7CiAgICAgICAgfSBlbHNlIGlmIChvIGluc3RhbmNlb2YgVmFyU3ltYm9sKSB7CiAgICAgICAgICAgIHJldHVybiBuZXcgVmFyaWFibGUoKFZhclN5bWJvbClvLCB0eXBlcyk7CiAgICAgICAgfSBlbHNlIGlmIChvIGluc3RhbmNlb2YgVHlwZSkgewogICAgICAgICAgICBUeXBlIHQgPSAoVHlwZSlvOwogICAgICAgICAgICAvLyBDbGFzc1JlZnMgY2FuIGNvbWUgZnJvbSBDbGFzc1N5bWJvbHMgb3IgZnJvbSBUeXBlcy4KICAgICAgICAgICAgLy8gUmV0dXJuIHRoZSBzeW1ib2wgZm9yIHRoZXNlIHR5cGVzIHRvIGF2b2lkIGR1cGxpY2F0ZXMKICAgICAgICAgICAgLy8gaW4gdGhlIGNvbnN0YW50IHBvb2wKICAgICAgICAgICAgaWYgKHQuaGFzVGFnKFR5cGVUYWcuQ0xBU1MpKQogICAgICAgICAgICAgICAgcmV0dXJuIHQudHN5bTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBVbmlxdWVUeXBlKHQsIHR5cGVzKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gbzsKICAgICAgICB9CiAgICB9CgogICAgLyoqIFJldHVybiB0aGUgZ2l2ZW4gb2JqZWN0J3MgaW5kZXggaW4gdGhlIHBvb2wsCiAgICAgKiAgb3IgLTEgaWYgb2JqZWN0IGlzIG5vdCBpbiB0aGVyZS4KICAgICAqLwogICAgcHVibGljIGludCBnZXQoT2JqZWN0IG8pIHsKICAgICAgICBJbnRlZ2VyIG4gPSBpbmRpY2VzLmdldChvKTsKICAgICAgICByZXR1cm4gbiA9PSBudWxsID8gLTEgOiBuLmludFZhbHVlKCk7CiAgICB9CgogICAgc3RhdGljIGNsYXNzIE1ldGhvZCBleHRlbmRzIERlbGVnYXRlZFN5bWJvbDxNZXRob2RTeW1ib2w+IHsKICAgICAgICBVbmlxdWVUeXBlIHVuaXF1ZVR5cGU7CiAgICAgICAgTWV0aG9kKE1ldGhvZFN5bWJvbCBtLCBUeXBlcyB0eXBlcykgewogICAgICAgICAgICBzdXBlcihtKTsKICAgICAgICAgICAgdGhpcy51bmlxdWVUeXBlID0gbmV3IFVuaXF1ZVR5cGUobS50eXBlLCB0eXBlcyk7CiAgICAgICAgfQogICAgICAgIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3QgYW55KSB7CiAgICAgICAgICAgIGlmICghKGFueSBpbnN0YW5jZW9mIE1ldGhvZCkpIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgTWV0aG9kU3ltYm9sIG8gPSAoKE1ldGhvZClhbnkpLm90aGVyOwogICAgICAgICAgICBNZXRob2RTeW1ib2wgbSA9IHRoaXMub3RoZXI7CiAgICAgICAgICAgIHJldHVybgogICAgICAgICAgICAgICAgby5uYW1lID09IG0ubmFtZSAmJgogICAgICAgICAgICAgICAgby5vd25lciA9PSBtLm93bmVyICYmCiAgICAgICAgICAgICAgICAoKE1ldGhvZClhbnkpLnVuaXF1ZVR5cGUuZXF1YWxzKHVuaXF1ZVR5cGUpOwogICAgICAgIH0KICAgICAgICBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgICAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICAgICAgICBNZXRob2RTeW1ib2wgbSA9IHRoaXMub3RoZXI7CiAgICAgICAgICAgIHJldHVybgogICAgICAgICAgICAgICAgbS5uYW1lLmhhc2hDb2RlKCkgKiAzMyArCiAgICAgICAgICAgICAgICBtLm93bmVyLmhhc2hDb2RlKCkgKiA5ICsKICAgICAgICAgICAgICAgIHVuaXF1ZVR5cGUuaGFzaENvZGUoKTsKICAgICAgICB9CiAgICB9CgogICAgc3RhdGljIGNsYXNzIER5bmFtaWNNZXRob2QgZXh0ZW5kcyBNZXRob2QgewogICAgICAgIHB1YmxpYyBPYmplY3RbXSB1bmlxdWVTdGF0aWNBcmdzOwoKICAgICAgICBEeW5hbWljTWV0aG9kKER5bmFtaWNNZXRob2RTeW1ib2wgbSwgVHlwZXMgdHlwZXMpIHsKICAgICAgICAgICAgc3VwZXIobSwgdHlwZXMpOwogICAgICAgICAgICB1bmlxdWVTdGF0aWNBcmdzID0gZ2V0VW5pcXVlVHlwZUFycmF5KG0uc3RhdGljQXJncywgdHlwZXMpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3QgYW55KSB7CiAgICAgICAgICAgIHJldHVybiBlcXVhbHNJbXBsKGFueSwgdHJ1ZSk7CiAgICAgICAgfQoKICAgICAgICBwcm90ZWN0ZWQgYm9vbGVhbiBlcXVhbHNJbXBsKE9iamVjdCBhbnksIGJvb2xlYW4gaW5jbHVkZUR5bmFtaWNBcmdzKSB7CiAgICAgICAgICAgIGlmIChpbmNsdWRlRHluYW1pY0FyZ3MgJiYgIXN1cGVyLmVxdWFscyhhbnkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIGlmICghKGFueSBpbnN0YW5jZW9mIER5bmFtaWNNZXRob2QpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIER5bmFtaWNNZXRob2RTeW1ib2wgZG0xID0gKER5bmFtaWNNZXRob2RTeW1ib2wpb3RoZXI7CiAgICAgICAgICAgIER5bmFtaWNNZXRob2RTeW1ib2wgZG0yID0gKER5bmFtaWNNZXRob2RTeW1ib2wpKChEeW5hbWljTWV0aG9kKWFueSkub3RoZXI7CiAgICAgICAgICAgIHJldHVybiBkbTEuYnNtID09IGRtMi5ic20gJiYKICAgICAgICAgICAgICAgICAgICAgICAgZG0xLmJzbUtpbmQgPT0gZG0yLmJzbUtpbmQgJiYKICAgICAgICAgICAgICAgICAgICAgICAgQXJyYXlzLmVxdWFscyh1bmlxdWVTdGF0aWNBcmdzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKChEeW5hbWljTWV0aG9kKWFueSkudW5pcXVlU3RhdGljQXJncyk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICAgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgICAgICAgcmV0dXJuIGhhc2hDb2RlSW1wbCh0cnVlKTsKICAgICAgICB9CgogICAgICAgIHByb3RlY3RlZCBpbnQgaGFzaENvZGVJbXBsKGJvb2xlYW4gaW5jbHVkZUR5bmFtaWNBcmdzKSB7CiAgICAgICAgICAgIGludCBoYXNoID0gaW5jbHVkZUR5bmFtaWNBcmdzID8gc3VwZXIuaGFzaENvZGUoKSA6IDA7CiAgICAgICAgICAgIER5bmFtaWNNZXRob2RTeW1ib2wgZG0gPSAoRHluYW1pY01ldGhvZFN5bWJvbClvdGhlcjsKICAgICAgICAgICAgaGFzaCArPSBkbS5ic21LaW5kICogNyArCiAgICAgICAgICAgICAgICAgICAgZG0uYnNtLmhhc2hDb2RlKCkgKiAxMTsKICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBkbS5zdGF0aWNBcmdzLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgICAgICBoYXNoICs9ICh1bmlxdWVTdGF0aWNBcmdzW2ldLmhhc2hDb2RlKCkgKiAyMyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGhhc2g7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIE9iamVjdFtdIGdldFVuaXF1ZVR5cGVBcnJheShPYmplY3RbXSBvYmplY3RzLCBUeXBlcyB0eXBlcykgewogICAgICAgICAgICBPYmplY3RbXSByZXN1bHQgPSBuZXcgT2JqZWN0W29iamVjdHMubGVuZ3RoXTsKICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBvYmplY3RzLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgICAgICBpZiAob2JqZWN0c1tpXSBpbnN0YW5jZW9mIFR5cGUpIHsKICAgICAgICAgICAgICAgICAgICByZXN1bHRbaV0gPSBuZXcgVW5pcXVlVHlwZSgoVHlwZSlvYmplY3RzW2ldLCB0eXBlcyk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHJlc3VsdFtpXSA9IG9iamVjdHNbaV07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CgogICAgICAgIHN0YXRpYyBjbGFzcyBCb290c3RyYXBNZXRob2RzS2V5IGV4dGVuZHMgRHluYW1pY01ldGhvZCB7CiAgICAgICAgICAgIEJvb3RzdHJhcE1ldGhvZHNLZXkoRHluYW1pY01ldGhvZFN5bWJvbCBtLCBUeXBlcyB0eXBlcykgewogICAgICAgICAgICAgICAgc3VwZXIobSwgdHlwZXMpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICAgICAgICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3QgYW55KSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZXF1YWxzSW1wbChhbnksIGZhbHNlKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgICAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIGhhc2hDb2RlSW1wbChmYWxzZSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIE9iamVjdFtdIGdldFVuaXF1ZUFyZ3MoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdW5pcXVlU3RhdGljQXJnczsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgc3RhdGljIGNsYXNzIEJvb3RzdHJhcE1ldGhvZHNWYWx1ZSB7CiAgICAgICAgICAgIGZpbmFsIE1ldGhvZEhhbmRsZSBtaDsKICAgICAgICAgICAgZmluYWwgaW50IGluZGV4OwoKICAgICAgICAgICAgcHVibGljIEJvb3RzdHJhcE1ldGhvZHNWYWx1ZShNZXRob2RIYW5kbGUgbWgsIGludCBpbmRleCkgewogICAgICAgICAgICAgICAgdGhpcy5taCA9IG1oOwogICAgICAgICAgICAgICAgdGhpcy5pbmRleCA9IGluZGV4OwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIHN0YXRpYyBjbGFzcyBWYXJpYWJsZSBleHRlbmRzIERlbGVnYXRlZFN5bWJvbDxWYXJTeW1ib2w+IHsKICAgICAgICBVbmlxdWVUeXBlIHVuaXF1ZVR5cGU7CiAgICAgICAgVmFyaWFibGUoVmFyU3ltYm9sIHYsIFR5cGVzIHR5cGVzKSB7CiAgICAgICAgICAgIHN1cGVyKHYpOwogICAgICAgICAgICB0aGlzLnVuaXF1ZVR5cGUgPSBuZXcgVW5pcXVlVHlwZSh2LnR5cGUsIHR5cGVzKTsKICAgICAgICB9CiAgICAgICAgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICAgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBhbnkpIHsKICAgICAgICAgICAgaWYgKCEoYW55IGluc3RhbmNlb2YgVmFyaWFibGUpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIFZhclN5bWJvbCBvID0gKChWYXJpYWJsZSlhbnkpLm90aGVyOwogICAgICAgICAgICBWYXJTeW1ib2wgdiA9IG90aGVyOwogICAgICAgICAgICByZXR1cm4KICAgICAgICAgICAgICAgIG8ubmFtZSA9PSB2Lm5hbWUgJiYKICAgICAgICAgICAgICAgIG8ub3duZXIgPT0gdi5vd25lciAmJgogICAgICAgICAgICAgICAgKChWYXJpYWJsZSlhbnkpLnVuaXF1ZVR5cGUuZXF1YWxzKHVuaXF1ZVR5cGUpOwogICAgICAgIH0KICAgICAgICBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgICAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICAgICAgICBWYXJTeW1ib2wgdiA9IG90aGVyOwogICAgICAgICAgICByZXR1cm4KICAgICAgICAgICAgICAgIHYubmFtZS5oYXNoQ29kZSgpICogMzMgKwogICAgICAgICAgICAgICAgdi5vd25lci5oYXNoQ29kZSgpICogOSArCiAgICAgICAgICAgICAgICB1bmlxdWVUeXBlLmhhc2hDb2RlKCk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgTWV0aG9kSGFuZGxlIHsKCiAgICAgICAgLyoqIFJlZmVyZW5jZSBraW5kIC0gc2VlIENsYXNzRmlsZSAqLwogICAgICAgIGludCByZWZLaW5kOwoKICAgICAgICAvKiogUmVmZXJlbmNlIHN5bWJvbCAqLwogICAgICAgIFN5bWJvbCByZWZTeW07CgogICAgICAgIFVuaXF1ZVR5cGUgdW5pcXVlVHlwZTsKCiAgICAgICAgcHVibGljIE1ldGhvZEhhbmRsZShpbnQgcmVmS2luZCwgU3ltYm9sIHJlZlN5bSwgVHlwZXMgdHlwZXMpIHsKICAgICAgICAgICAgdGhpcy5yZWZLaW5kID0gcmVmS2luZDsKICAgICAgICAgICAgdGhpcy5yZWZTeW0gPSByZWZTeW07CiAgICAgICAgICAgIHRoaXMudW5pcXVlVHlwZSA9IG5ldyBVbmlxdWVUeXBlKHRoaXMucmVmU3ltLnR5cGUsIHR5cGVzKTsKICAgICAgICAgICAgY2hlY2tDb25zaXN0ZW50KCk7CiAgICAgICAgfQogICAgICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb3RoZXIpIHsKICAgICAgICAgICAgaWYgKCEob3RoZXIgaW5zdGFuY2VvZiBNZXRob2RIYW5kbGUpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIE1ldGhvZEhhbmRsZSBtciA9IChNZXRob2RIYW5kbGUpIG90aGVyOwogICAgICAgICAgICBpZiAobXIucmVmS2luZCAhPSByZWZLaW5kKSAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICBTeW1ib2wgbyA9IG1yLnJlZlN5bTsKICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgICAgICAgICBvLm5hbWUgPT0gcmVmU3ltLm5hbWUgJiYKICAgICAgICAgICAgICAgIG8ub3duZXIgPT0gcmVmU3ltLm93bmVyICYmCiAgICAgICAgICAgICAgICAoKE1ldGhvZEhhbmRsZSlvdGhlcikudW5pcXVlVHlwZS5lcXVhbHModW5pcXVlVHlwZSk7CiAgICAgICAgfQogICAgICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgICAgICAgIHJldHVybgogICAgICAgICAgICAgICAgcmVmS2luZCAqIDY1ICsKICAgICAgICAgICAgICAgIHJlZlN5bS5uYW1lLmhhc2hDb2RlKCkgKiAzMyArCiAgICAgICAgICAgICAgICByZWZTeW0ub3duZXIuaGFzaENvZGUoKSAqIDkgKwogICAgICAgICAgICAgICAgdW5pcXVlVHlwZS5oYXNoQ29kZSgpOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogQ2hlY2sgY29uc2lzdGVuY3kgb2YgcmVmZXJlbmNlIGtpbmQgYW5kIHN5bWJvbCAoc2VlIEpWTVMgNC40LjgpCiAgICAgICAgICovCiAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoImZhbGx0aHJvdWdoIikKICAgICAgICBwcml2YXRlIHZvaWQgY2hlY2tDb25zaXN0ZW50KCkgewogICAgICAgICAgICBib29sZWFuIHN0YXRpY09rID0gZmFsc2U7CiAgICAgICAgICAgIEtpbmQgZXhwZWN0ZWRLaW5kID0gbnVsbDsKICAgICAgICAgICAgRmlsdGVyPE5hbWU+IG5hbWVGaWx0ZXIgPSBub25Jbml0RmlsdGVyOwogICAgICAgICAgICBib29sZWFuIGludGVyZmFjZU93bmVyID0gZmFsc2U7CiAgICAgICAgICAgIHN3aXRjaCAocmVmS2luZCkgewogICAgICAgICAgICAgICAgY2FzZSBDbGFzc0ZpbGUuUkVGX2dldFN0YXRpYzoKICAgICAgICAgICAgICAgIGNhc2UgQ2xhc3NGaWxlLlJFRl9wdXRTdGF0aWM6CiAgICAgICAgICAgICAgICAgICAgc3RhdGljT2sgPSB0cnVlOwogICAgICAgICAgICAgICAgY2FzZSBDbGFzc0ZpbGUuUkVGX2dldEZpZWxkOgogICAgICAgICAgICAgICAgY2FzZSBDbGFzc0ZpbGUuUkVGX3B1dEZpZWxkOgogICAgICAgICAgICAgICAgICAgIGV4cGVjdGVkS2luZCA9IFZBUjsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgQ2xhc3NGaWxlLlJFRl9uZXdJbnZva2VTcGVjaWFsOgogICAgICAgICAgICAgICAgICAgIG5hbWVGaWx0ZXIgPSBpbml0RmlsdGVyOwogICAgICAgICAgICAgICAgICAgIGV4cGVjdGVkS2luZCA9IE1USDsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgQ2xhc3NGaWxlLlJFRl9pbnZva2VJbnRlcmZhY2U6CiAgICAgICAgICAgICAgICAgICAgaW50ZXJmYWNlT3duZXIgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIGV4cGVjdGVkS2luZCA9IE1USDsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgQ2xhc3NGaWxlLlJFRl9pbnZva2VTdGF0aWM6CiAgICAgICAgICAgICAgICAgICAgaW50ZXJmYWNlT3duZXIgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIHN0YXRpY09rID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGNhc2UgQ2xhc3NGaWxlLlJFRl9pbnZva2VWaXJ0dWFsOgogICAgICAgICAgICAgICAgICAgIGV4cGVjdGVkS2luZCA9IE1USDsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgQ2xhc3NGaWxlLlJFRl9pbnZva2VTcGVjaWFsOgogICAgICAgICAgICAgICAgICAgIGludGVyZmFjZU93bmVyID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBleHBlY3RlZEtpbmQgPSBNVEg7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgQXNzZXJ0LmNoZWNrKCFyZWZTeW0uaXNTdGF0aWMoKSB8fCBzdGF0aWNPayk7CiAgICAgICAgICAgIEFzc2VydC5jaGVjayhyZWZTeW0ua2luZCA9PSBleHBlY3RlZEtpbmQpOwogICAgICAgICAgICBBc3NlcnQuY2hlY2sobmFtZUZpbHRlci5hY2NlcHRzKHJlZlN5bS5uYW1lKSk7CiAgICAgICAgICAgIEFzc2VydC5jaGVjayghcmVmU3ltLm93bmVyLmlzSW50ZXJmYWNlKCkgfHwgaW50ZXJmYWNlT3duZXIpOwogICAgICAgIH0KICAgICAgICAvL3doZXJlCiAgICAgICAgICAgICAgICBGaWx0ZXI8TmFtZT4gbm9uSW5pdEZpbHRlciA9IG4gLT4gKG4gIT0gbi50YWJsZS5uYW1lcy5pbml0ICYmIG4gIT0gbi50YWJsZS5uYW1lcy5jbGluaXQpOwoKICAgICAgICAgICAgICAgIEZpbHRlcjxOYW1lPiBpbml0RmlsdGVyID0gbiAtPiBuID09IG4udGFibGUubmFtZXMuaW5pdDsKICAgIH0KfQpQSwMECgAACAAABjupSivmqIpgSwAAYEsAACkAAABjb20vc3VuL3Rvb2xzL2phdmFjL2p2bS9TdHJpbmdDb25jYXQuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAxNSwgMjAxNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLmphdmFjLmp2bTsKCmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuKjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29tcC5SZXNvbHZlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkpDVHJlZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5UcmVlSW5mbzsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5UcmVlTWFrZXI7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuKjsKCmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLktpbmRzLktpbmQuTVRIOwppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5UeXBlVGFnLio7CmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5qdm0uQnl0ZUNvZGVzLio7CmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkpDVHJlZS5UYWcuUExVUzsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuanZtLkl0ZW1zLio7CgppbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CmltcG9ydCBqYXZhLnV0aWwuTWFwOwoKLyoqIFRoaXMgbG93ZXJzIHRoZSBTdHJpbmcgY29uY2F0ZW5hdGlvbiB0byBzb21ldGhpbmcgdGhhdCBKVk0gY2FuIHVuZGVyc3RhbmQuCiAqCiAqICA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiAgSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93biByaXNrLgogKiAgVGhpcyBjb2RlIGFuZCBpdHMgaW50ZXJuYWwgaW50ZXJmYWNlcyBhcmUgc3ViamVjdCB0byBjaGFuZ2Ugb3IKICogIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj4KICovCnB1YmxpYyBhYnN0cmFjdCBjbGFzcyBTdHJpbmdDb25jYXQgewoKICAgIC8qKgogICAgICogTWF4aW11bSBudW1iZXIgb2Ygc2xvdHMgZm9yIFN0cmluZyBDb25jYXQgY2FsbC4KICAgICAqIEpESydzIFN0cmluZ0NvbmNhdEZhY3RvcnkgZG9lcyBub3Qgc3VwcG9ydCBtb3JlIHRoYW4gdGhhdC4KICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IE1BWF9JTkRZX0NPTkNBVF9BUkdfU0xPVFMgPSAyMDA7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjaGFyIFRBR19BUkcgICA9ICdcdTAwMDEnOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2hhciBUQUdfQ09OU1QgPSAnXHUwMDAyJzsKCiAgICBwcm90ZWN0ZWQgZmluYWwgR2VuIGdlbjsKICAgIHByb3RlY3RlZCBmaW5hbCBTeW10YWIgc3ltczsKICAgIHByb3RlY3RlZCBmaW5hbCBOYW1lcyBuYW1lczsKICAgIHByb3RlY3RlZCBmaW5hbCBUcmVlTWFrZXIgbWFrZTsKICAgIHByb3RlY3RlZCBmaW5hbCBUeXBlcyB0eXBlczsKICAgIHByb3RlY3RlZCBmaW5hbCBNYXA8VHlwZSwgU3ltYm9sPiBzYkFwcGVuZHM7CiAgICBwcm90ZWN0ZWQgZmluYWwgUmVzb2x2ZSByczsKCiAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIENvbnRleHQuS2V5PFN0cmluZ0NvbmNhdD4gY29uY2F0S2V5ID0gbmV3IENvbnRleHQuS2V5PD4oKTsKCiAgICBwdWJsaWMgc3RhdGljIFN0cmluZ0NvbmNhdCBpbnN0YW5jZShDb250ZXh0IGNvbnRleHQpIHsKICAgICAgICBTdHJpbmdDb25jYXQgaW5zdGFuY2UgPSBjb250ZXh0LmdldChjb25jYXRLZXkpOwogICAgICAgIGlmIChpbnN0YW5jZSA9PSBudWxsKSB7CiAgICAgICAgICAgIGluc3RhbmNlID0gbWFrZUNvbmNhdChjb250ZXh0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGluc3RhbmNlOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIFN0cmluZ0NvbmNhdCBtYWtlQ29uY2F0KENvbnRleHQgY29udGV4dCkgewogICAgICAgIFRhcmdldCB0YXJnZXQgPSBUYXJnZXQuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgU3RyaW5nIG9wdCA9IE9wdGlvbnMuaW5zdGFuY2UoY29udGV4dCkuZ2V0KCJzdHJpbmdDb25jYXQiKTsKCiAgICAgICAgLy8gZGlzYWJsZSBpbmR5IHN0cmNhdCBieSBkZWZhdWx0CiAgICAgICAgaWYgKG9wdCA9PSBudWxsKSB7CiAgICAgICAgICAgIG9wdCA9ICJpbmxpbmUiOwogICAgICAgIH0KCiAgICAgICAgaWYgKHRhcmdldC5oYXNTdHJpbmdDb25jYXRGYWN0b3J5KCkpIHsKICAgICAgICAgICAgaWYgKG9wdCA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICBvcHQgPSAiaW5keVdpdGhDb25zdGFudHMiOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgaWYgKG9wdCAhPSBudWxsICYmICEiaW5saW5lIi5lcXVhbHMob3B0KSkgewogICAgICAgICAgICAgICAgQXNzZXJ0LmVycm9yKCJTdHJpbmdDb25jYXRGYWN0b3J5LWJhc2VkIHN0cmluZyBjb25jYXQgaXMgcmVxdWVzdGVkIG9uIGEgcGxhdGZvcm0gdGhhdCBkb2VzIG5vdCBzdXBwb3J0IGl0LiIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIG9wdCA9ICJpbmxpbmUiOwogICAgICAgIH0KCiAgICAgICAgc3dpdGNoIChvcHQpIHsKICAgICAgICAgICAgY2FzZSAiaW5saW5lIjoKICAgICAgICAgICAgICAgIHJldHVybiBuZXcgSW5saW5lKGNvbnRleHQpOwogICAgICAgICAgICBjYXNlICJpbmR5IjoKICAgICAgICAgICAgICAgIHJldHVybiBuZXcgSW5keVBsYWluKGNvbnRleHQpOwogICAgICAgICAgICBjYXNlICJpbmR5V2l0aENvbnN0YW50cyI6CiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEluZHlDb25zdGFudHMoY29udGV4dCk7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICBBc3NlcnQuZXJyb3IoIlVua25vd24gc3RyaW5nQ29uY2F0OiAiICsgb3B0KTsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oIlVua25vd24gc3RyaW5nQ29uY2F0OiAiICsgb3B0KTsKICAgICAgICB9CiAgICB9CgogICAgcHJvdGVjdGVkIFN0cmluZ0NvbmNhdChDb250ZXh0IGNvbnRleHQpIHsKICAgICAgICBjb250ZXh0LnB1dChjb25jYXRLZXksIHRoaXMpOwogICAgICAgIGdlbiA9IEdlbi5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBzeW1zID0gU3ltdGFiLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIHR5cGVzID0gVHlwZXMuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgbmFtZXMgPSBOYW1lcy5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBtYWtlID0gVHJlZU1ha2VyLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIHJzID0gUmVzb2x2ZS5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBzYkFwcGVuZHMgPSBuZXcgSGFzaE1hcDw+KCk7CiAgICB9CgogICAgcHVibGljIGFic3RyYWN0IEl0ZW0gbWFrZUNvbmNhdChKQ1RyZWUuSkNBc3NpZ25PcCB0cmVlKTsKICAgIHB1YmxpYyBhYnN0cmFjdCBJdGVtIG1ha2VDb25jYXQoSkNUcmVlLkpDQmluYXJ5IHRyZWUpOwoKICAgIHByb3RlY3RlZCBMaXN0PEpDVHJlZT4gY29sbGVjdEFsbChKQ1RyZWUgdHJlZSkgewogICAgICAgIHJldHVybiBjb2xsZWN0KHRyZWUsIExpc3QubmlsKCkpOwogICAgfQoKICAgIHByb3RlY3RlZCBMaXN0PEpDVHJlZT4gY29sbGVjdEFsbChKQ1RyZWUuSkNFeHByZXNzaW9uIGxocywgSkNUcmVlLkpDRXhwcmVzc2lvbiByaHMpIHsKICAgICAgICByZXR1cm4gTGlzdC48SkNUcmVlPm5pbCgpCiAgICAgICAgICAgICAgICAuYXBwZW5kTGlzdChjb2xsZWN0QWxsKGxocykpCiAgICAgICAgICAgICAgICAuYXBwZW5kTGlzdChjb2xsZWN0QWxsKHJocykpOwogICAgfQoKICAgIHByaXZhdGUgTGlzdDxKQ1RyZWU+IGNvbGxlY3QoSkNUcmVlIHRyZWUsIExpc3Q8SkNUcmVlPiByZXMpIHsKICAgICAgICB0cmVlID0gVHJlZUluZm8uc2tpcFBhcmVucyh0cmVlKTsKICAgICAgICBpZiAodHJlZS5oYXNUYWcoUExVUykgJiYgdHJlZS50eXBlLmNvbnN0VmFsdWUoKSA9PSBudWxsKSB7CiAgICAgICAgICAgIEpDVHJlZS5KQ0JpbmFyeSBvcCA9IChKQ1RyZWUuSkNCaW5hcnkpIHRyZWU7CiAgICAgICAgICAgIGlmIChvcC5vcGVyYXRvci5raW5kID09IE1USCAmJiBvcC5vcGVyYXRvci5vcGNvZGUgPT0gc3RyaW5nX2FkZCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHJlcwogICAgICAgICAgICAgICAgICAgICAgICAuYXBwZW5kTGlzdChjb2xsZWN0KG9wLmxocywgcmVzKSkKICAgICAgICAgICAgICAgICAgICAgICAgLmFwcGVuZExpc3QoY29sbGVjdChvcC5yaHMsIHJlcykpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXMuYXBwZW5kKHRyZWUpOwogICAgfQoKICAgIC8qKgogICAgICogSWYgdGhlIHR5cGUgaXMgbm90IGFjY2Vzc2libGUgZnJvbSBjdXJyZW50IGNvbnRleHQsIHRyeSB0byBmaWd1cmUgb3V0IHRoZQogICAgICogc2hhcnBlc3QgYWNjZXNzaWJsZSBzdXBlcnR5cGUuCiAgICAgKgogICAgICogQHBhcmFtIG9yaWdpbmFsVHlwZSB0eXBlIHRvIHNoYXJwZW4KICAgICAqIEByZXR1cm4gc2hhcnBlZCB0eXBlCiAgICAgKi8KICAgIFR5cGUgc2hhcnBlc3RBY2Nlc3NpYmxlKFR5cGUgb3JpZ2luYWxUeXBlKSB7CiAgICAgICAgaWYgKG9yaWdpbmFsVHlwZS5oYXNUYWcoQVJSQVkpKSB7CiAgICAgICAgICAgIHJldHVybiB0eXBlcy5tYWtlQXJyYXlUeXBlKHNoYXJwZXN0QWNjZXNzaWJsZSh0eXBlcy5lbGVtdHlwZShvcmlnaW5hbFR5cGUpKSk7CiAgICAgICAgfQoKICAgICAgICBUeXBlIHR5cGUgPSBvcmlnaW5hbFR5cGU7CiAgICAgICAgd2hpbGUgKCFycy5pc0FjY2Vzc2libGUoZ2VuLmdldEF0dHJFbnYoKSwgdHlwZS5hc0VsZW1lbnQoKSkpIHsKICAgICAgICAgICAgdHlwZSA9IHR5cGVzLnN1cGVydHlwZSh0eXBlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHR5cGU7CiAgICB9CgogICAgLyoqCiAgICAgKiAiTGVnYWN5IiBieXRlY29kZSBmbGF2b3I6IGVtaXQgdGhlIFN0cmluZ0J1aWxkZXIuYXBwZW5kIGNoYWlucyBmb3Igc3RyaW5nCiAgICAgKiBjb25jYXRlbmF0aW9uLgogICAgICovCiAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBJbmxpbmUgZXh0ZW5kcyBTdHJpbmdDb25jYXQgewogICAgICAgIHB1YmxpYyBJbmxpbmUoQ29udGV4dCBjb250ZXh0KSB7CiAgICAgICAgICAgIHN1cGVyKGNvbnRleHQpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIEl0ZW0gbWFrZUNvbmNhdChKQ1RyZWUuSkNBc3NpZ25PcCB0cmVlKSB7CiAgICAgICAgICAgIC8vIEdlbmVyYXRlIGNvZGUgdG8gbWFrZSBhIHN0cmluZyBidWlsZGVyCiAgICAgICAgICAgIEpDRGlhZ25vc3RpYy5EaWFnbm9zdGljUG9zaXRpb24gcG9zID0gdHJlZS5wb3MoKTsKCiAgICAgICAgICAgIC8vIENyZWF0ZSBhIHN0cmluZyBidWlsZGVyLgogICAgICAgICAgICBuZXdTdHJpbmdCdWlsZGVyKHRyZWUpOwoKICAgICAgICAgICAgLy8gR2VuZXJhdGUgY29kZSBmb3IgZmlyc3Qgc3RyaW5nLCBwb3NzaWJseSBzYXZlIG9uZQogICAgICAgICAgICAvLyBjb3B5IHVuZGVyIGJ1aWxkZXIKICAgICAgICAgICAgSXRlbSBsID0gZ2VuLmdlbkV4cHIodHJlZS5saHMsIHRyZWUubGhzLnR5cGUpOwogICAgICAgICAgICBpZiAobC53aWR0aCgpID4gMCkgewogICAgICAgICAgICAgICAgZ2VuLmdldENvZGUoKS5lbWl0b3AwKGR1cF94MSArIDMgKiAobC53aWR0aCgpIC0gMSkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBMb2FkIGZpcnN0IHN0cmluZyBhbmQgYXBwZW5kIHRvIGJ1aWxkZXIuCiAgICAgICAgICAgIGwubG9hZCgpOwogICAgICAgICAgICBhcHBlbmRTdHJpbmcodHJlZS5saHMpOwoKICAgICAgICAgICAgLy8gQXBwZW5kIGFsbCBvdGhlciBzdHJpbmdzIHRvIGJ1aWxkZXIuCiAgICAgICAgICAgIExpc3Q8SkNUcmVlPiBhcmdzID0gY29sbGVjdEFsbCh0cmVlLnJocyk7CiAgICAgICAgICAgIGZvciAoSkNUcmVlIHQgOiBhcmdzKSB7CiAgICAgICAgICAgICAgICBnZW4uZ2VuRXhwcih0LCB0LnR5cGUpLmxvYWQoKTsKICAgICAgICAgICAgICAgIGFwcGVuZFN0cmluZyh0KTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gQ29udmVydCBidWlsZGVyIHRvIHN0cmluZy4KICAgICAgICAgICAgYnVpbGRlclRvU3RyaW5nKHBvcyk7CgogICAgICAgICAgICByZXR1cm4gbDsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBJdGVtIG1ha2VDb25jYXQoSkNUcmVlLkpDQmluYXJ5IHRyZWUpIHsKICAgICAgICAgICAgSkNEaWFnbm9zdGljLkRpYWdub3N0aWNQb3NpdGlvbiBwb3MgPSB0cmVlLnBvcygpOwoKICAgICAgICAgICAgLy8gQ3JlYXRlIGEgc3RyaW5nIGJ1aWxkZXIuCiAgICAgICAgICAgIG5ld1N0cmluZ0J1aWxkZXIodHJlZSk7CgogICAgICAgICAgICAvLyBBcHBlbmQgYWxsIHN0cmluZ3MgdG8gYnVpbGRlci4KICAgICAgICAgICAgTGlzdDxKQ1RyZWU+IGFyZ3MgPSBjb2xsZWN0QWxsKHRyZWUpOwogICAgICAgICAgICBmb3IgKEpDVHJlZSB0IDogYXJncykgewogICAgICAgICAgICAgICAgZ2VuLmdlbkV4cHIodCwgdC50eXBlKS5sb2FkKCk7CiAgICAgICAgICAgICAgICBhcHBlbmRTdHJpbmcodCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIENvbnZlcnQgYnVpbGRlciB0byBzdHJpbmcuCiAgICAgICAgICAgIGJ1aWxkZXJUb1N0cmluZyhwb3MpOwoKICAgICAgICAgICAgcmV0dXJuIGdlbi5nZXRJdGVtcygpLm1ha2VTdGFja0l0ZW0oc3ltcy5zdHJpbmdUeXBlKTsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgSkNEaWFnbm9zdGljLkRpYWdub3N0aWNQb3NpdGlvbiBuZXdTdHJpbmdCdWlsZGVyKEpDVHJlZSB0cmVlKSB7CiAgICAgICAgICAgIEpDRGlhZ25vc3RpYy5EaWFnbm9zdGljUG9zaXRpb24gcG9zID0gdHJlZS5wb3MoKTsKICAgICAgICAgICAgZ2VuLmdldENvZGUoKS5lbWl0b3AyKG5ld18sIGdlbi5tYWtlUmVmKHBvcywgc3ltcy5zdHJpbmdCdWlsZGVyVHlwZSkpOwogICAgICAgICAgICBnZW4uZ2V0Q29kZSgpLmVtaXRvcDAoZHVwKTsKICAgICAgICAgICAgZ2VuLmNhbGxNZXRob2QocG9zLCBzeW1zLnN0cmluZ0J1aWxkZXJUeXBlLCBuYW1lcy5pbml0LCBMaXN0Lm5pbCgpLCBmYWxzZSk7CiAgICAgICAgICAgIHJldHVybiBwb3M7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIHZvaWQgYXBwZW5kU3RyaW5nKEpDVHJlZSB0cmVlKSB7CiAgICAgICAgICAgIFR5cGUgdCA9IHRyZWUudHlwZS5iYXNlVHlwZSgpOwogICAgICAgICAgICBpZiAoIXQuaXNQcmltaXRpdmUoKSAmJiB0LnRzeW0gIT0gc3ltcy5zdHJpbmdUeXBlLnRzeW0pIHsKICAgICAgICAgICAgICAgIHQgPSBzeW1zLm9iamVjdFR5cGU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEFzc2VydC5jaGVja051bGwodC5jb25zdFZhbHVlKCkpOwogICAgICAgICAgICBTeW1ib2wgbWV0aG9kID0gc2JBcHBlbmRzLmdldCh0KTsKICAgICAgICAgICAgaWYgKG1ldGhvZCA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICBtZXRob2QgPSBycy5yZXNvbHZlSW50ZXJuYWxNZXRob2QodHJlZS5wb3MoKSwgZ2VuLmdldEF0dHJFbnYoKSwgc3ltcy5zdHJpbmdCdWlsZGVyVHlwZSwgbmFtZXMuYXBwZW5kLCBMaXN0Lm9mKHQpLCBudWxsKTsKICAgICAgICAgICAgICAgIHNiQXBwZW5kcy5wdXQodCwgbWV0aG9kKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZ2VuLmdldEl0ZW1zKCkubWFrZU1lbWJlckl0ZW0obWV0aG9kLCBmYWxzZSkuaW52b2tlKCk7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIHZvaWQgYnVpbGRlclRvU3RyaW5nKEpDRGlhZ25vc3RpYy5EaWFnbm9zdGljUG9zaXRpb24gcG9zKSB7CiAgICAgICAgICAgIGdlbi5jYWxsTWV0aG9kKHBvcywgc3ltcy5zdHJpbmdCdWlsZGVyVHlwZSwgbmFtZXMudG9TdHJpbmcsIExpc3QubmlsKCksIGZhbHNlKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBCYXNlIGNsYXNzIGZvciBpbmRpZmllZCBjb25jYXRlbmF0aW9uIGJ5dGVjb2RlIGZsYXZvcnMuCiAgICAgKi8KICAgIHByaXZhdGUgc3RhdGljIGFic3RyYWN0IGNsYXNzIEluZHkgZXh0ZW5kcyBTdHJpbmdDb25jYXQgewogICAgICAgIHB1YmxpYyBJbmR5KENvbnRleHQgY29udGV4dCkgewogICAgICAgICAgICBzdXBlcihjb250ZXh0KTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBJdGVtIG1ha2VDb25jYXQoSkNUcmVlLkpDQXNzaWduT3AgdHJlZSkgewogICAgICAgICAgICBMaXN0PEpDVHJlZT4gYXJncyA9IGNvbGxlY3RBbGwodHJlZS5saHMsIHRyZWUucmhzKTsKICAgICAgICAgICAgSXRlbSBsID0gZ2VuLmdlbkV4cHIodHJlZS5saHMsIHRyZWUubGhzLnR5cGUpOwogICAgICAgICAgICBlbWl0KGFyZ3MsIHRyZWUudHlwZSwgdHJlZS5wb3MoKSk7CiAgICAgICAgICAgIHJldHVybiBsOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIEl0ZW0gbWFrZUNvbmNhdChKQ1RyZWUuSkNCaW5hcnkgdHJlZSkgewogICAgICAgICAgICBMaXN0PEpDVHJlZT4gYXJncyA9IGNvbGxlY3RBbGwodHJlZS5saHMsIHRyZWUucmhzKTsKICAgICAgICAgICAgZW1pdChhcmdzLCB0cmVlLnR5cGUsIHRyZWUucG9zKCkpOwogICAgICAgICAgICByZXR1cm4gZ2VuLmdldEl0ZW1zKCkubWFrZVN0YWNrSXRlbShzeW1zLnN0cmluZ1R5cGUpOwogICAgICAgIH0KCiAgICAgICAgcHJvdGVjdGVkIGFic3RyYWN0IHZvaWQgZW1pdChMaXN0PEpDVHJlZT4gYXJncywgVHlwZSB0eXBlLCBKQ0RpYWdub3N0aWMuRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcyk7CgogICAgICAgIC8qKiBQZWVsIHRoZSBhcmd1bWVudCBsaXN0IGludG8gc21hbGxlciBjaHVua3MuICovCiAgICAgICAgcHJvdGVjdGVkIExpc3Q8TGlzdDxKQ1RyZWU+PiBzcGxpdChMaXN0PEpDVHJlZT4gYXJncykgewogICAgICAgICAgICBMaXN0QnVmZmVyPExpc3Q8SkNUcmVlPj4gc3BsaXRzID0gbmV3IExpc3RCdWZmZXI8PigpOwoKICAgICAgICAgICAgaW50IHNsb3RzID0gMDsKCiAgICAgICAgICAgIC8vIE5lZWQgdG8gcGVlbCwgc28gdGhhdCBuZWl0aGVyIGNhbGwgaGFzIG1vcmUgdGhhbiBhY2NlcHRhYmxlIG51bWJlcgogICAgICAgICAgICAvLyBvZiBzbG90cyBmb3IgdGhlIGFyZ3VtZW50cy4KICAgICAgICAgICAgTGlzdEJ1ZmZlcjxKQ1RyZWU+IGNBcmdzID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgICAgICBmb3IgKEpDVHJlZSB0IDogYXJncykgewogICAgICAgICAgICAgICAgaW50IG5lZWRTbG90cyA9ICh0LnR5cGUuZ2V0VGFnKCkgPT0gTE9ORyB8fCB0LnR5cGUuZ2V0VGFnKCkgPT0gRE9VQkxFKSA/IDIgOiAxOwogICAgICAgICAgICAgICAgaWYgKHNsb3RzICsgbmVlZFNsb3RzID49IE1BWF9JTkRZX0NPTkNBVF9BUkdfU0xPVFMpIHsKICAgICAgICAgICAgICAgICAgICBzcGxpdHMuYWRkKGNBcmdzLnRvTGlzdCgpKTsKICAgICAgICAgICAgICAgICAgICBjQXJncy5jbGVhcigpOwogICAgICAgICAgICAgICAgICAgIHNsb3RzID0gMDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGNBcmdzLmFkZCh0KTsKICAgICAgICAgICAgICAgIHNsb3RzICs9IG5lZWRTbG90czsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gRmx1c2ggdGhlIHRhaWwgc2xpY2UKICAgICAgICAgICAgaWYgKCFjQXJncy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICAgIHNwbGl0cy5hZGQoY0FyZ3MudG9MaXN0KCkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gc3BsaXRzLnRvTGlzdCgpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEVtaXRzIHRoZSBpbnZva2VkeW5hbWljIGNhbGwgdG8gSkRLIGphdmEubGFuZy5pbnZva2UuU3RyaW5nQ29uY2F0RmFjdG9yeSwKICAgICAqIHdpdGhvdXQgaGFuZGxpbmcgY29uc3RhbnRzIHNwZWNpYWxseS4KICAgICAqCiAgICAgKiBXZSBieXBhc3MgZW1wdHkgc3RyaW5ncywgYmVjYXVzZSB0aGV5IGhhdmUgbm8gbWVhbmluZyBhdCB0aGlzIGxldmVsLiBUaGlzCiAgICAgKiBjYXB0dXJlcyB0aGUgSmF2YSBsYW5ndWFnZSB0cmljayB0byBmb3JjZSBTdHJpbmcgY29uY2F0IHdpdGggZS5nLiAoIiIgKyBpbnQpLWxpa2UKICAgICAqIGV4cHJlc3Npb24uIERvd24gaGVyZSwgd2UgYWxyZWFkeSBrbm93IHdlIGFyZSBpbiBTdHJpbmcgY29uY2F0IGJ1c2luZXNzLCBhbmQgZG8KICAgICAqIG5vdCByZXF1aXJlIHRoZXNlIG1hcmtlcnMuCiAgICAgKi8KICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIEluZHlQbGFpbiBleHRlbmRzIEluZHkgewogICAgICAgIHB1YmxpYyBJbmR5UGxhaW4oQ29udGV4dCBjb250ZXh0KSB7CiAgICAgICAgICAgIHN1cGVyKGNvbnRleHQpOwogICAgICAgIH0KCiAgICAgICAgLyoqIEVtaXQgdGhlIGluZHkgY29uY2F0IGZvciBhbGwgdGhlc2UgYXJndW1lbnRzLCBwb3NzaWJseSBwZWVsaW5nIGFsb25nIHRoZSB3YXkgKi8KICAgICAgICBwcm90ZWN0ZWQgdm9pZCBlbWl0KExpc3Q8SkNUcmVlPiBhcmdzLCBUeXBlIHR5cGUsIEpDRGlhZ25vc3RpYy5EaWFnbm9zdGljUG9zaXRpb24gcG9zKSB7CiAgICAgICAgICAgIExpc3Q8TGlzdDxKQ1RyZWU+PiBzcGxpdCA9IHNwbGl0KGFyZ3MpOwoKICAgICAgICAgICAgZm9yIChMaXN0PEpDVHJlZT4gdCA6IHNwbGl0KSB7CiAgICAgICAgICAgICAgICBBc3NlcnQuY2hlY2soIXQuaXNFbXB0eSgpLCAiQXJndW1lbnRzIGxpc3QgaXMgZW1wdHkiKTsKCiAgICAgICAgICAgICAgICBMaXN0QnVmZmVyPFR5cGU+IGR5bmFtaWNBcmdzID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgICAgICAgICAgZm9yIChKQ1RyZWUgYXJnIDogdCkgewogICAgICAgICAgICAgICAgICAgIE9iamVjdCBjb25zdFZhbCA9IGFyZy50eXBlLmNvbnN0VmFsdWUoKTsKICAgICAgICAgICAgICAgICAgICBpZiAoIiIuZXF1YWxzKGNvbnN0VmFsKSkgY29udGludWU7CiAgICAgICAgICAgICAgICAgICAgaWYgKGFyZy50eXBlID09IHN5bXMuYm90VHlwZSkgewogICAgICAgICAgICAgICAgICAgICAgICBkeW5hbWljQXJncy5hZGQodHlwZXMuYm94ZWRDbGFzcyhzeW1zLnZvaWRUeXBlKS50eXBlKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBkeW5hbWljQXJncy5hZGQoc2hhcnBlc3RBY2Nlc3NpYmxlKGFyZy50eXBlKSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGdlbi5nZW5FeHByKGFyZywgYXJnLnR5cGUpLmxvYWQoKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBkb0NhbGwodHlwZSwgcG9zLCBkeW5hbWljQXJncy50b0xpc3QoKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIE1vcmUgdGhhdCBvbmUgcGVlbCBzbGljZSBwcm9kdWNlZDogY29uY2F0ZW5hdGUgdGhlIHJlc3VsdHMKICAgICAgICAgICAgaWYgKHNwbGl0LnNpemUoKSA+IDEpIHsKICAgICAgICAgICAgICAgIExpc3RCdWZmZXI8VHlwZT4gYXJnVHlwZXMgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgICAgICBmb3IgKGludCBjID0gMDsgYyA8IHNwbGl0LnNpemUoKTsgYysrKSB7CiAgICAgICAgICAgICAgICAgICAgYXJnVHlwZXMuYXBwZW5kKHN5bXMuc3RyaW5nVHlwZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBkb0NhbGwodHlwZSwgcG9zLCBhcmdUeXBlcy50b0xpc3QoKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8qKiBQcm9kdWNlIHRoZSBhY3R1YWwgaW52b2tlZHluYW1pYyBjYWxsIHRvIFN0cmluZ0NvbmNhdEZhY3RvcnkgKi8KICAgICAgICBwcml2YXRlIHZvaWQgZG9DYWxsKFR5cGUgdHlwZSwgSkNEaWFnbm9zdGljLkRpYWdub3N0aWNQb3NpdGlvbiBwb3MsIExpc3Q8VHlwZT4gZHluYW1pY0FyZ1R5cGVzKSB7CiAgICAgICAgICAgIFR5cGUuTWV0aG9kVHlwZSBpbmR5VHlwZSA9IG5ldyBUeXBlLk1ldGhvZFR5cGUoZHluYW1pY0FyZ1R5cGVzLAogICAgICAgICAgICAgICAgICAgIHR5cGUsCiAgICAgICAgICAgICAgICAgICAgTGlzdC5uaWwoKSwKICAgICAgICAgICAgICAgICAgICBzeW1zLm1ldGhvZENsYXNzKTsKCiAgICAgICAgICAgIGludCBwcmV2UG9zID0gbWFrZS5wb3M7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBtYWtlLmF0KHBvcyk7CgogICAgICAgICAgICAgICAgTGlzdDxUeXBlPiBic21fc3RhdGljQXJncyA9IExpc3Qub2Yoc3ltcy5tZXRob2RIYW5kbGVMb29rdXBUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICBzeW1zLnN0cmluZ1R5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgIHN5bXMubWV0aG9kVHlwZVR5cGUpOwoKICAgICAgICAgICAgICAgIFN5bWJvbCBic20gPSBycy5yZXNvbHZlSW50ZXJuYWxNZXRob2QocG9zLAogICAgICAgICAgICAgICAgICAgICAgICBnZW4uZ2V0QXR0ckVudigpLAogICAgICAgICAgICAgICAgICAgICAgICBzeW1zLnN0cmluZ0NvbmNhdEZhY3RvcnksCiAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVzLm1ha2VDb25jYXQsCiAgICAgICAgICAgICAgICAgICAgICAgIGJzbV9zdGF0aWNBcmdzLAogICAgICAgICAgICAgICAgICAgICAgICBudWxsKTsKCiAgICAgICAgICAgICAgICBTeW1ib2wuRHluYW1pY01ldGhvZFN5bWJvbCBkeW5TeW0gPSBuZXcgU3ltYm9sLkR5bmFtaWNNZXRob2RTeW1ib2wobmFtZXMubWFrZUNvbmNhdCwKICAgICAgICAgICAgICAgICAgICAgICAgc3ltcy5ub1N5bWJvbCwKICAgICAgICAgICAgICAgICAgICAgICAgQ2xhc3NGaWxlLlJFRl9pbnZva2VTdGF0aWMsCiAgICAgICAgICAgICAgICAgICAgICAgIChTeW1ib2wuTWV0aG9kU3ltYm9sKWJzbSwKICAgICAgICAgICAgICAgICAgICAgICAgaW5keVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgIExpc3QubmlsKCkudG9BcnJheSgpKTsKCiAgICAgICAgICAgICAgICBJdGVtcy5JdGVtIGl0ZW0gPSBnZW4uZ2V0SXRlbXMoKS5tYWtlRHluYW1pY0l0ZW0oZHluU3ltKTsKICAgICAgICAgICAgICAgIGl0ZW0uaW52b2tlKCk7CiAgICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgICAgICBtYWtlLmF0KHByZXZQb3MpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogRW1pdHMgdGhlIGludm9rZWR5bmFtaWMgY2FsbCB0byBKREsgamF2YS5sYW5nLmludm9rZS5TdHJpbmdDb25jYXRGYWN0b3J5LgogICAgICogVGhpcyBjb2RlIGNvbmNhdGVuYXRlcyBhbGwga25vd24gY29uc3RhbnRzIGludG8gdGhlIHJlY2lwZSwgcG9zc2libHkgZXNjYXBpbmcKICAgICAqIHNvbWUgY29uc3RhbnRzIHNlcGFyYXRlbHkuCiAgICAgKgogICAgICogV2UgYWxzbyBieXBhc3MgZW1wdHkgc3RyaW5ncywgYmVjYXVzZSB0aGV5IGhhdmUgbm8gbWVhbmluZyBhdCB0aGlzIGxldmVsLiBUaGlzCiAgICAgKiBjYXB0dXJlcyB0aGUgSmF2YSBsYW5ndWFnZSB0cmljayB0byBmb3JjZSBTdHJpbmcgY29uY2F0IHdpdGggZS5nLiAoIiIgKyBpbnQpLWxpa2UKICAgICAqIGV4cHJlc3Npb24uIERvd24gaGVyZSwgd2UgYWxyZWFkeSBrbm93IHdlIGFyZSBpbiBTdHJpbmcgY29uY2F0IGJ1c2luZXNzLCBhbmQgZG8KICAgICAqIG5vdCByZXF1aXJlIHRoZXNlIG1hcmtlcnMuCiAgICAgKi8KICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEluZHlDb25zdGFudHMgZXh0ZW5kcyBJbmR5IHsKICAgICAgICBwdWJsaWMgSW5keUNvbnN0YW50cyhDb250ZXh0IGNvbnRleHQpIHsKICAgICAgICAgICAgc3VwZXIoY29udGV4dCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwcm90ZWN0ZWQgdm9pZCBlbWl0KExpc3Q8SkNUcmVlPiBhcmdzLCBUeXBlIHR5cGUsIEpDRGlhZ25vc3RpYy5EaWFnbm9zdGljUG9zaXRpb24gcG9zKSB7CiAgICAgICAgICAgIExpc3Q8TGlzdDxKQ1RyZWU+PiBzcGxpdCA9IHNwbGl0KGFyZ3MpOwoKICAgICAgICAgICAgZm9yIChMaXN0PEpDVHJlZT4gdCA6IHNwbGl0KSB7CiAgICAgICAgICAgICAgICBBc3NlcnQuY2hlY2soIXQuaXNFbXB0eSgpLCAiQXJndW1lbnRzIGxpc3QgaXMgZW1wdHkiKTsKCiAgICAgICAgICAgICAgICBTdHJpbmdCdWlsZGVyIHJlY2lwZSA9IG5ldyBTdHJpbmdCdWlsZGVyKHQuc2l6ZSgpKTsKICAgICAgICAgICAgICAgIExpc3RCdWZmZXI8VHlwZT4gZHluYW1pY0FyZ3MgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgICAgICBMaXN0QnVmZmVyPE9iamVjdD4gc3RhdGljQXJncyA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKCiAgICAgICAgICAgICAgICBmb3IgKEpDVHJlZSBhcmcgOiB0KSB7CiAgICAgICAgICAgICAgICAgICAgT2JqZWN0IGNvbnN0VmFsID0gYXJnLnR5cGUuY29uc3RWYWx1ZSgpOwogICAgICAgICAgICAgICAgICAgIGlmICgiIi5lcXVhbHMoY29uc3RWYWwpKSBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICBpZiAoYXJnLnR5cGUgPT0gc3ltcy5ib3RUeXBlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIENvbmNhdCB0aGUgbnVsbCBpbnRvIHRoZSByZWNpcGUgcmlnaHQgYXdheQogICAgICAgICAgICAgICAgICAgICAgICByZWNpcGUuYXBwZW5kKChTdHJpbmcpIG51bGwpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoY29uc3RWYWwgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBDb25jYXQgdGhlIFN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgY29uc3RhbnQsIGV4Y2VwdAogICAgICAgICAgICAgICAgICAgICAgICAvLyBmb3IgdGhlIGNhc2UgaXQgY29udGFpbnMgc3BlY2lhbCB0YWdzLCB3aGljaCByZXF1aXJlcyB1cwogICAgICAgICAgICAgICAgICAgICAgICAvLyB0byBleHBvc2UgaXQgYXMgZGV0YWNoZWQgY29uc3RhbnQuCiAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBhID0gYXJnLnR5cGUuc3RyaW5nVmFsdWUoKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGEuaW5kZXhPZihUQUdfQ09OU1QpICE9IC0xIHx8IGEuaW5kZXhPZihUQUdfQVJHKSAhPSAtMSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVjaXBlLmFwcGVuZChUQUdfQ09OU1QpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdGljQXJncy5hZGQoYSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWNpcGUuYXBwZW5kKGEpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gT3JkaW5hcnkgYXJndW1lbnRzIGNvbWUgdGhyb3VnaCB0aGUgZHluYW1pYyBhcmd1bWVudHMuCiAgICAgICAgICAgICAgICAgICAgICAgIHJlY2lwZS5hcHBlbmQoVEFHX0FSRyk7CiAgICAgICAgICAgICAgICAgICAgICAgIGR5bmFtaWNBcmdzLmFkZChzaGFycGVzdEFjY2Vzc2libGUoYXJnLnR5cGUpKTsKICAgICAgICAgICAgICAgICAgICAgICAgZ2VuLmdlbkV4cHIoYXJnLCBhcmcudHlwZSkubG9hZCgpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBkb0NhbGwodHlwZSwgcG9zLCByZWNpcGUudG9TdHJpbmcoKSwgc3RhdGljQXJncy50b0xpc3QoKSwgZHluYW1pY0FyZ3MudG9MaXN0KCkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBNb3JlIHRoYXQgb25lIHBlZWwgc2xpY2UgcHJvZHVjZWQ6IGNvbmNhdGVuYXRlIHRoZSByZXN1bHRzCiAgICAgICAgICAgIC8vIEFsbCBhcmd1bWVudHMgYXJlIGFzc3VtZWQgdG8gYmUgbm9uLWNvbnN0YW50IFN0cmluZ3MuCiAgICAgICAgICAgIGlmIChzcGxpdC5zaXplKCkgPiAxKSB7CiAgICAgICAgICAgICAgICBMaXN0QnVmZmVyPFR5cGU+IGFyZ1R5cGVzID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgICAgICAgICAgU3RyaW5nQnVpbGRlciByZWNpcGUgPSBuZXcgU3RyaW5nQnVpbGRlcigpOwogICAgICAgICAgICAgICAgZm9yIChpbnQgYyA9IDA7IGMgPCBzcGxpdC5zaXplKCk7IGMrKykgewogICAgICAgICAgICAgICAgICAgIGFyZ1R5cGVzLmFwcGVuZChzeW1zLnN0cmluZ1R5cGUpOwogICAgICAgICAgICAgICAgICAgIHJlY2lwZS5hcHBlbmQoVEFHX0FSRyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBkb0NhbGwodHlwZSwgcG9zLCByZWNpcGUudG9TdHJpbmcoKSwgTGlzdC5uaWwoKSwgYXJnVHlwZXMudG9MaXN0KCkpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvKiogUHJvZHVjZSB0aGUgYWN0dWFsIGludm9rZWR5bmFtaWMgY2FsbCB0byBTdHJpbmdDb25jYXRGYWN0b3J5ICovCiAgICAgICAgcHJpdmF0ZSB2b2lkIGRvQ2FsbChUeXBlIHR5cGUsIEpDRGlhZ25vc3RpYy5EaWFnbm9zdGljUG9zaXRpb24gcG9zLCBTdHJpbmcgcmVjaXBlLCBMaXN0PE9iamVjdD4gc3RhdGljQXJncywgTGlzdDxUeXBlPiBkeW5hbWljQXJnVHlwZXMpIHsKICAgICAgICAgICAgVHlwZS5NZXRob2RUeXBlIGluZHlUeXBlID0gbmV3IFR5cGUuTWV0aG9kVHlwZShkeW5hbWljQXJnVHlwZXMsCiAgICAgICAgICAgICAgICAgICAgdHlwZSwKICAgICAgICAgICAgICAgICAgICBMaXN0Lm5pbCgpLAogICAgICAgICAgICAgICAgICAgIHN5bXMubWV0aG9kQ2xhc3MpOwoKICAgICAgICAgICAgaW50IHByZXZQb3MgPSBtYWtlLnBvczsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIG1ha2UuYXQocG9zKTsKCiAgICAgICAgICAgICAgICBMaXN0QnVmZmVyPFR5cGU+IGNvbnN0VHlwZXMgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgICAgICBMaXN0QnVmZmVyPE9iamVjdD4gY29uc3RhbnRzID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgICAgICAgICAgZm9yIChPYmplY3QgdCA6IHN0YXRpY0FyZ3MpIHsKICAgICAgICAgICAgICAgICAgICBjb25zdGFudHMuYWRkKHQpOwogICAgICAgICAgICAgICAgICAgIGNvbnN0VHlwZXMuYWRkKHN5bXMuc3RyaW5nVHlwZSk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgTGlzdDxUeXBlPiBic21fc3RhdGljQXJncyA9IExpc3Qub2Yoc3ltcy5tZXRob2RIYW5kbGVMb29rdXBUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICBzeW1zLnN0cmluZ1R5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgIHN5bXMubWV0aG9kVHlwZVR5cGUpCiAgICAgICAgICAgICAgICAgICAgICAgIC5hcHBlbmQoc3ltcy5zdHJpbmdUeXBlKQogICAgICAgICAgICAgICAgICAgICAgICAuYXBwZW5kTGlzdChjb25zdFR5cGVzKTsKCiAgICAgICAgICAgICAgICBTeW1ib2wgYnNtID0gcnMucmVzb2x2ZUludGVybmFsTWV0aG9kKHBvcywKICAgICAgICAgICAgICAgICAgICAgICAgZ2VuLmdldEF0dHJFbnYoKSwKICAgICAgICAgICAgICAgICAgICAgICAgc3ltcy5zdHJpbmdDb25jYXRGYWN0b3J5LAogICAgICAgICAgICAgICAgICAgICAgICBuYW1lcy5tYWtlQ29uY2F0V2l0aENvbnN0YW50cywKICAgICAgICAgICAgICAgICAgICAgICAgYnNtX3N0YXRpY0FyZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgIG51bGwpOwoKICAgICAgICAgICAgICAgIFN5bWJvbC5EeW5hbWljTWV0aG9kU3ltYm9sIGR5blN5bSA9IG5ldyBTeW1ib2wuRHluYW1pY01ldGhvZFN5bWJvbChuYW1lcy5tYWtlQ29uY2F0V2l0aENvbnN0YW50cywKICAgICAgICAgICAgICAgICAgICAgICAgc3ltcy5ub1N5bWJvbCwKICAgICAgICAgICAgICAgICAgICAgICAgQ2xhc3NGaWxlLlJFRl9pbnZva2VTdGF0aWMsCiAgICAgICAgICAgICAgICAgICAgICAgIChTeW1ib2wuTWV0aG9kU3ltYm9sKWJzbSwKICAgICAgICAgICAgICAgICAgICAgICAgaW5keVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgIExpc3QuPE9iamVjdD5vZihyZWNpcGUpLmFwcGVuZExpc3QoY29uc3RhbnRzKS50b0FycmF5KCkpOwoKICAgICAgICAgICAgICAgIEl0ZW1zLkl0ZW0gaXRlbSA9IGdlbi5nZXRJdGVtcygpLm1ha2VEeW5hbWljSXRlbShkeW5TeW0pOwogICAgICAgICAgICAgICAgaXRlbS5pbnZva2UoKTsKICAgICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgICAgIG1ha2UuYXQocHJldlBvcyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9Cgp9ClBLAwQKAAAIAAAGO6lKYqDmVk0lAQBNJQEAIQAAAGNvbS9zdW4vdG9vbHMvamF2YWMvanZtL0NvZGUuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMTk5OSwgMjAxNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLmphdmFjLmp2bTsKCmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuKjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5TeW1ib2wuKjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5UeXBlcy5VbmlxdWVUeXBlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkpDVHJlZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC4qOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkpDRGlhZ25vc3RpYy5EaWFnbm9zdGljUG9zaXRpb247CgppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5UeXBlVGFnLkJPVDsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuVHlwZVRhZy5JTlQ7CmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5qdm0uQnl0ZUNvZGVzLio7CmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5qdm0uVW5pbml0aWFsaXplZFR5cGUuKjsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmp2bS5DbGFzc1dyaXRlci5TdGFja01hcFRhYmxlRnJhbWU7CgovKiogQW4gaW50ZXJuYWwgc3RydWN0dXJlIHRoYXQgY29ycmVzcG9uZHMgdG8gdGhlIGNvZGUgYXR0cmlidXRlIG9mCiAqICBtZXRob2RzIGluIGEgY2xhc3NmaWxlLiBUaGUgY2xhc3MgYWxzbyBwcm92aWRlcyBzb21lIHV0aWxpdHkgb3BlcmF0aW9ucyB0bwogKiAgZ2VuZXJhdGUgYnl0ZWNvZGUgaW5zdHJ1Y3Rpb25zLgogKgogKiAgPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24gcmlzay4KICogIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yCiAqICBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+CiAqLwpwdWJsaWMgY2xhc3MgQ29kZSB7CgogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gZGVidWdDb2RlOwogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gbmVlZFN0YWNrTWFwOwoKICAgIHB1YmxpYyBlbnVtIFN0YWNrTWFwRm9ybWF0IHsKICAgICAgICBOT05FLAogICAgICAgIENMREMgewogICAgICAgICAgICBOYW1lIGdldEF0dHJpYnV0ZU5hbWUoTmFtZXMgbmFtZXMpIHsKICAgICAgICAgICAgICAgIHJldHVybiBuYW1lcy5TdGFja01hcDsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgSlNSMjAyIHsKICAgICAgICAgICAgTmFtZSBnZXRBdHRyaWJ1dGVOYW1lKE5hbWVzIG5hbWVzKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gbmFtZXMuU3RhY2tNYXBUYWJsZTsKICAgICAgICAgICAgfQogICAgICAgIH07CiAgICAgICAgTmFtZSBnZXRBdHRyaWJ1dGVOYW1lKE5hbWVzIG5hbWVzKSB7CiAgICAgICAgICAgIHJldHVybiBuYW1lcy5lbXB0eTsKICAgICAgICB9CiAgICB9CgogICAgZmluYWwgVHlwZXMgdHlwZXM7CiAgICBmaW5hbCBTeW10YWIgc3ltczsKCi8qLS0tLS0tLS0tLSBjbGFzc2ZpbGUgZmllbGRzOiAtLS0tLS0tLS0tLS0tLS0gKi8KCiAgICAvKiogVGhlIG1heGltdW0gc3RhY2sgc2l6ZS4KICAgICAqLwogICAgcHVibGljIGludCBtYXhfc3RhY2sgPSAwOwoKICAgIC8qKiBUaGUgbWF4aW11bSBudW1iZXIgb2YgbG9jYWwgdmFyaWFibGUgc2xvdHMuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgbWF4X2xvY2FscyA9IDA7CgogICAgLyoqIFRoZSBjb2RlIGJ1ZmZlci4KICAgICAqLwogICAgcHVibGljIGJ5dGVbXSBjb2RlID0gbmV3IGJ5dGVbNjRdOwoKICAgIC8qKiB0aGUgY3VycmVudCBjb2RlIHBvaW50ZXIuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgY3AgPSAwOwoKICAgIC8qKiBDaGVjayB0aGUgY29kZSBhZ2FpbnN0IFZNIHNwZWMgbGltaXRzOyBpZgogICAgICogIHByb2JsZW1zIHJlcG9ydCB0aGVtIGFuZCByZXR1cm4gdHJ1ZS4KICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gY2hlY2tMaW1pdHMoRGlhZ25vc3RpY1Bvc2l0aW9uIHBvcywgTG9nIGxvZykgewogICAgICAgIGlmIChjcCA+IENsYXNzRmlsZS5NQVhfQ09ERSkgewogICAgICAgICAgICBsb2cuZXJyb3IocG9zLCAibGltaXQuY29kZSIpOwogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgaWYgKG1heF9sb2NhbHMgPiBDbGFzc0ZpbGUuTUFYX0xPQ0FMUykgewogICAgICAgICAgICBsb2cuZXJyb3IocG9zLCAibGltaXQubG9jYWxzIik7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KICAgICAgICBpZiAobWF4X3N0YWNrID4gQ2xhc3NGaWxlLk1BWF9TVEFDSykgewogICAgICAgICAgICBsb2cuZXJyb3IocG9zLCAibGltaXQuc3RhY2siKTsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICAvKiogQSBidWZmZXIgZm9yIGV4cHJlc3Npb24gY2F0Y2ggZGF0YS4gRWFjaCBlbnRlciBpcyBhIHZlY3RvcgogICAgICogIG9mIGZvdXIgdW5zaWduZWQgc2hvcnRzLgogICAgICovCiAgICBMaXN0QnVmZmVyPGNoYXJbXT4gY2F0Y2hJbmZvID0gbmV3IExpc3RCdWZmZXI8PigpOwoKICAgIC8qKiBBIGJ1ZmZlciBmb3IgbGluZSBudW1iZXIgaW5mb3JtYXRpb24uIEVhY2ggZW50cnkgaXMgYSB2ZWN0b3IKICAgICAqICBvZiB0d28gdW5zaWduZWQgc2hvcnRzLgogICAgICovCiAgICBMaXN0PGNoYXJbXT4gbGluZUluZm8gPSBMaXN0Lm5pbCgpOyAvLyBoYW5kbGVkIGluIHN0YWNrIGZhc2hpb24KCiAgICAvKiogVGhlIENoYXJhY3RlclJhbmdlVGFibGUKICAgICAqLwogICAgcHVibGljIENSVGFibGUgY3J0OwoKLyotLS0tLS0tLS0tIGludGVybmFsIGZpZWxkczogLS0tLS0tLS0tLS0tLS0tICovCgogICAgLyoqIEFyZSB3ZSBnZW5lcmF0aW5nIGNvZGUgd2l0aCBqdW1wcyAmZ2U7IDMySz8KICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gZmF0Y29kZTsKCiAgICAvKiogQ29kZSBnZW5lcmF0aW9uIGVuYWJsZWQ/CiAgICAgKi8KICAgIHByaXZhdGUgYm9vbGVhbiBhbGl2ZSA9IHRydWU7CgogICAgLyoqIFRoZSBjdXJyZW50IG1hY2hpbmUgc3RhdGUgKHJlZ2lzdGVycyBhbmQgc3RhY2spLgogICAgICovCiAgICBTdGF0ZSBzdGF0ZTsKCiAgICAvKiogSXMgaXQgZm9yYmlkZGVuIHRvIGNvbXBhY3RpZnkgY29kZSwgYmVjYXVzZSBzb21ldGhpbmcgaXMKICAgICAqICBwb2ludGluZyB0byBjdXJyZW50IGxvY2F0aW9uPwogICAgICovCiAgICBwcml2YXRlIGJvb2xlYW4gZml4ZWRQYyA9IGZhbHNlOwoKICAgIC8qKiBUaGUgbmV4dCBhdmFpbGFibGUgcmVnaXN0ZXIuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgbmV4dHJlZyA9IDA7CgogICAgLyoqIEEgY2hhaW4gZm9yIGp1bXBzIHRvIGJlIHJlc29sdmVkIGJlZm9yZSB0aGUgbmV4dCBvcGNvZGUgaXMgZW1pdHRlZC4KICAgICAqICBXZSBkbyB0aGlzIGxhemlseSB0byBhdm9pZCBqdW1wcyB0byBqdW1wcy4KICAgICAqLwogICAgQ2hhaW4gcGVuZGluZ0p1bXBzID0gbnVsbDsKCiAgICAvKiogVGhlIHBvc2l0aW9uIG9mIHRoZSBjdXJyZW50bHkgc3RhdGVtZW50LCBpZiB3ZSBhcmUgYXQgdGhlCiAgICAgKiAgc3RhcnQgb2YgdGhpcyBzdGF0ZW1lbnQsIE5PUE9TIG90aGVyd2lzZS4KICAgICAqICBXZSBuZWVkIHRoaXMgdG8gZW1pdCBsaW5lIG51bWJlcnMgbGF6aWx5LCB3aGljaCB3ZSBuZWVkIHRvIGRvCiAgICAgKiAgYmVjYXVzZSBvZiBqdW1wLXRvLWp1bXAgb3B0aW1pemF0aW9uLgogICAgICovCiAgICBpbnQgcGVuZGluZ1N0YXRQb3MgPSBQb3NpdGlvbi5OT1BPUzsKCiAgICAvKiogU2V0IHRydWUgd2hlbiBhIHN0YWNrTWFwIGlzIG5lZWRlZCBhdCB0aGUgY3VycmVudCBQQy4gKi8KICAgIGJvb2xlYW4gcGVuZGluZ1N0YWNrTWFwID0gZmFsc2U7CgogICAgLyoqIFRoZSBzdGFjayBtYXAgZm9ybWF0IHRvIGJlIGdlbmVyYXRlZC4gKi8KICAgIFN0YWNrTWFwRm9ybWF0IHN0YWNrTWFwOwoKICAgIC8qKiBTd2l0Y2g6IGVtaXQgdmFyaWFibGUgZGVidWcgaW5mby4KICAgICAqLwogICAgYm9vbGVhbiB2YXJEZWJ1Z0luZm87CgogICAgLyoqIFN3aXRjaDogZW1pdCBsaW5lIG51bWJlciBpbmZvLgogICAgICovCiAgICBib29sZWFuIGxpbmVEZWJ1Z0luZm87CgogICAgLyoqIEVtaXQgbGluZSBudW1iZXIgaW5mbyBpZiBtYXAgc3VwcGxpZWQKICAgICAqLwogICAgUG9zaXRpb24uTGluZU1hcCBsaW5lTWFwOwoKICAgIC8qKiBUaGUgY29uc3RhbnQgcG9vbCBvZiB0aGUgY3VycmVudCBjbGFzcy4KICAgICAqLwogICAgZmluYWwgUG9vbCBwb29sOwoKICAgIGZpbmFsIE1ldGhvZFN5bWJvbCBtZXRoOwoKICAgIC8qKiBDb25zdHJ1Y3QgYSBjb2RlIG9iamVjdCwgZ2l2ZW4gdGhlIHNldHRpbmdzIG9mIHRoZSBmYXRjb2RlLAogICAgICogIGRlYnVnZ2luZyBpbmZvIHN3aXRjaGVzIGFuZCB0aGUgQ2hhcmFjdGVyUmFuZ2VUYWJsZS4KICAgICAqLwogICAgcHVibGljIENvZGUoTWV0aG9kU3ltYm9sIG1ldGgsCiAgICAgICAgICAgICAgICBib29sZWFuIGZhdGNvZGUsCiAgICAgICAgICAgICAgICBQb3NpdGlvbi5MaW5lTWFwIGxpbmVNYXAsCiAgICAgICAgICAgICAgICBib29sZWFuIHZhckRlYnVnSW5mbywKICAgICAgICAgICAgICAgIFN0YWNrTWFwRm9ybWF0IHN0YWNrTWFwLAogICAgICAgICAgICAgICAgYm9vbGVhbiBkZWJ1Z0NvZGUsCiAgICAgICAgICAgICAgICBDUlRhYmxlIGNydCwKICAgICAgICAgICAgICAgIFN5bXRhYiBzeW1zLAogICAgICAgICAgICAgICAgVHlwZXMgdHlwZXMsCiAgICAgICAgICAgICAgICBQb29sIHBvb2wpIHsKICAgICAgICB0aGlzLm1ldGggPSBtZXRoOwogICAgICAgIHRoaXMuZmF0Y29kZSA9IGZhdGNvZGU7CiAgICAgICAgdGhpcy5saW5lTWFwID0gbGluZU1hcDsKICAgICAgICB0aGlzLmxpbmVEZWJ1Z0luZm8gPSBsaW5lTWFwICE9IG51bGw7CiAgICAgICAgdGhpcy52YXJEZWJ1Z0luZm8gPSB2YXJEZWJ1Z0luZm87CiAgICAgICAgdGhpcy5jcnQgPSBjcnQ7CiAgICAgICAgdGhpcy5zeW1zID0gc3ltczsKICAgICAgICB0aGlzLnR5cGVzID0gdHlwZXM7CiAgICAgICAgdGhpcy5kZWJ1Z0NvZGUgPSBkZWJ1Z0NvZGU7CiAgICAgICAgdGhpcy5zdGFja01hcCA9IHN0YWNrTWFwOwogICAgICAgIHN3aXRjaCAoc3RhY2tNYXApIHsKICAgICAgICBjYXNlIENMREM6CiAgICAgICAgY2FzZSBKU1IyMDI6CiAgICAgICAgICAgIHRoaXMubmVlZFN0YWNrTWFwID0gdHJ1ZTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgdGhpcy5uZWVkU3RhY2tNYXAgPSBmYWxzZTsKICAgICAgICB9CiAgICAgICAgc3RhdGUgPSBuZXcgU3RhdGUoKTsKICAgICAgICBsdmFyID0gbmV3IExvY2FsVmFyWzIwXTsKICAgICAgICB0aGlzLnBvb2wgPSBwb29sOwogICAgfQoKCi8qICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFR5cGVjb2RlcyAmIHJlbGF0ZWQgc3R1ZmYKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgogICAgLyoqIEdpdmVuIGEgdHlwZSwgcmV0dXJuIGl0cyB0eXBlIGNvZGUgKHVzZWQgaW1wbGljaXRseSBpbiB0aGUKICAgICAqICBKVk0gYXJjaGl0ZWN0dXJlKS4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBpbnQgdHlwZWNvZGUoVHlwZSB0eXBlKSB7CiAgICAgICAgc3dpdGNoICh0eXBlLmdldFRhZygpKSB7CiAgICAgICAgY2FzZSBCWVRFOiByZXR1cm4gQllURWNvZGU7CiAgICAgICAgY2FzZSBTSE9SVDogcmV0dXJuIFNIT1JUY29kZTsKICAgICAgICBjYXNlIENIQVI6IHJldHVybiBDSEFSY29kZTsKICAgICAgICBjYXNlIElOVDogcmV0dXJuIElOVGNvZGU7CiAgICAgICAgY2FzZSBMT05HOiByZXR1cm4gTE9OR2NvZGU7CiAgICAgICAgY2FzZSBGTE9BVDogcmV0dXJuIEZMT0FUY29kZTsKICAgICAgICBjYXNlIERPVUJMRTogcmV0dXJuIERPVUJMRWNvZGU7CiAgICAgICAgY2FzZSBCT09MRUFOOiByZXR1cm4gQllURWNvZGU7CiAgICAgICAgY2FzZSBWT0lEOiByZXR1cm4gVk9JRGNvZGU7CiAgICAgICAgY2FzZSBDTEFTUzoKICAgICAgICBjYXNlIEFSUkFZOgogICAgICAgIGNhc2UgTUVUSE9EOgogICAgICAgIGNhc2UgQk9UOgogICAgICAgIGNhc2UgVFlQRVZBUjoKICAgICAgICBjYXNlIFVOSU5JVElBTElaRURfVEhJUzoKICAgICAgICBjYXNlIFVOSU5JVElBTElaRURfT0JKRUNUOgogICAgICAgICAgICByZXR1cm4gT0JKRUNUY29kZTsKICAgICAgICBkZWZhdWx0OiB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoInR5cGVjb2RlICIgKyB0eXBlLmdldFRhZygpKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqIENvbGxhcHNlIHR5cGUgY29kZSBmb3Igc3VidHlwZXMgb2YgaW50IHRvIElOVGNvZGUuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgaW50IHRydW5jYXRlKGludCB0YykgewogICAgICAgIHN3aXRjaCAodGMpIHsKICAgICAgICBjYXNlIEJZVEVjb2RlOiBjYXNlIFNIT1JUY29kZTogY2FzZSBDSEFSY29kZTogcmV0dXJuIElOVGNvZGU7CiAgICAgICAgZGVmYXVsdDogcmV0dXJuIHRjOwogICAgICAgIH0KICAgIH0KCiAgICAvKiogVGhlIHdpZHRoIGluIGJ5dGVzIG9mIG9iamVjdHMgb2YgdGhlIHR5cGUuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgaW50IHdpZHRoKGludCB0eXBlY29kZSkgewogICAgICAgIHN3aXRjaCAodHlwZWNvZGUpIHsKICAgICAgICBjYXNlIExPTkdjb2RlOiBjYXNlIERPVUJMRWNvZGU6IHJldHVybiAyOwogICAgICAgIGNhc2UgVk9JRGNvZGU6IHJldHVybiAwOwogICAgICAgIGRlZmF1bHQ6IHJldHVybiAxOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGludCB3aWR0aChUeXBlIHR5cGUpIHsKICAgICAgICByZXR1cm4gdHlwZSA9PSBudWxsID8gMSA6IHdpZHRoKHR5cGVjb2RlKHR5cGUpKTsKICAgIH0KCiAgICAvKiogVGhlIHRvdGFsIHdpZHRoIHRha2VuIHVwIGJ5IGEgdmVjdG9yIG9mIG9iamVjdHMuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgaW50IHdpZHRoKExpc3Q8VHlwZT4gdHlwZXMpIHsKICAgICAgICBpbnQgdyA9IDA7CiAgICAgICAgZm9yIChMaXN0PFR5cGU+IGwgPSB0eXBlczsgbC5ub25FbXB0eSgpOyBsID0gbC50YWlsKQogICAgICAgICAgICB3ID0gdyArIHdpZHRoKGwuaGVhZCk7CiAgICAgICAgcmV0dXJuIHc7CiAgICB9CgogICAgLyoqIEdpdmVuIGEgdHlwZSwgcmV0dXJuIGl0cyBjb2RlIGZvciBhbGxvY2F0aW5nIGFycmF5cyBvZiB0aGF0IHR5cGUuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgaW50IGFycmF5Y29kZShUeXBlIHR5cGUpIHsKICAgICAgICBzd2l0Y2ggKHR5cGUuZ2V0VGFnKCkpIHsKICAgICAgICBjYXNlIEJZVEU6IHJldHVybiA4OwogICAgICAgIGNhc2UgQk9PTEVBTjogcmV0dXJuIDQ7CiAgICAgICAgY2FzZSBTSE9SVDogcmV0dXJuIDk7CiAgICAgICAgY2FzZSBDSEFSOiByZXR1cm4gNTsKICAgICAgICBjYXNlIElOVDogcmV0dXJuIDEwOwogICAgICAgIGNhc2UgTE9ORzogcmV0dXJuIDExOwogICAgICAgIGNhc2UgRkxPQVQ6IHJldHVybiA2OwogICAgICAgIGNhc2UgRE9VQkxFOiByZXR1cm4gNzsKICAgICAgICBjYXNlIENMQVNTOiByZXR1cm4gMDsKICAgICAgICBjYXNlIEFSUkFZOiByZXR1cm4gMTsKICAgICAgICBkZWZhdWx0OiB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoImFycmF5Y29kZSAiICsgdHlwZSk7CiAgICAgICAgfQogICAgfQoKCi8qICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEVtaXQgY29kZQogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiAgICAvKiogVGhlIGN1cnJlbnQgb3V0cHV0IGNvZGUgcG9pbnRlci4KICAgICAqLwogICAgcHVibGljIGludCBjdXJDUCgpIHsKICAgICAgICAvKgogICAgICAgICAqIFRoaXMgbWV0aG9kIGhhcyBzaWRlLWVmZmVjdHMgYmVjYXVzZSBjYWxsaW5nIGl0IGNhbiBpbmRpcmVjdGx5IHByb3Zva2UKICAgICAgICAgKiAgZXh0cmEgY29kZSBnZW5lcmF0aW9uLCBsaWtlIGdvdG8gaW5zdHJ1Y3Rpb25zLCBkZXBlbmRpbmcgb24gdGhlIGNvbnRleHQKICAgICAgICAgKiAgd2hlcmUgaXQncyBjYWxsZWQuCiAgICAgICAgICogIFVzZSB3aXRoIGNhcmUgb3IgZXZlbiBiZXR0ZXIgYXZvaWQgdXNpbmcgaXQuCiAgICAgICAgICovCiAgICAgICAgaWYgKHBlbmRpbmdKdW1wcyAhPSBudWxsKSB7CiAgICAgICAgICAgIHJlc29sdmVQZW5kaW5nKCk7CiAgICAgICAgfQogICAgICAgIGlmIChwZW5kaW5nU3RhdFBvcyAhPSBQb3NpdGlvbi5OT1BPUykgewogICAgICAgICAgICBtYXJrU3RhdEJlZ2luKCk7CiAgICAgICAgfQogICAgICAgIGZpeGVkUGMgPSB0cnVlOwogICAgICAgIHJldHVybiBjcDsKICAgIH0KCiAgICAvKiogRW1pdCBhIGJ5dGUgb2YgY29kZS4KICAgICAqLwogICAgcHJpdmF0ZSAgdm9pZCBlbWl0MShpbnQgb2QpIHsKICAgICAgICBpZiAoIWFsaXZlKSByZXR1cm47CiAgICAgICAgY29kZSA9IEFycmF5VXRpbHMuZW5zdXJlQ2FwYWNpdHkoY29kZSwgY3ApOwogICAgICAgIGNvZGVbY3ArK10gPSAoYnl0ZSlvZDsKICAgIH0KCiAgICAvKiogRW1pdCB0d28gYnl0ZXMgb2YgY29kZS4KICAgICAqLwogICAgcHJpdmF0ZSB2b2lkIGVtaXQyKGludCBvZCkgewogICAgICAgIGlmICghYWxpdmUpIHJldHVybjsKICAgICAgICBpZiAoY3AgKyAyID4gY29kZS5sZW5ndGgpIHsKICAgICAgICAgICAgZW1pdDEob2QgPj4gOCk7CiAgICAgICAgICAgIGVtaXQxKG9kKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBjb2RlW2NwKytdID0gKGJ5dGUpKG9kID4+IDgpOwogICAgICAgICAgICBjb2RlW2NwKytdID0gKGJ5dGUpb2Q7CiAgICAgICAgfQogICAgfQoKICAgIC8qKiBFbWl0IGZvdXIgYnl0ZXMgb2YgY29kZS4KICAgICAqLwogICAgcHVibGljIHZvaWQgZW1pdDQoaW50IG9kKSB7CiAgICAgICAgaWYgKCFhbGl2ZSkgcmV0dXJuOwogICAgICAgIGlmIChjcCArIDQgPiBjb2RlLmxlbmd0aCkgewogICAgICAgICAgICBlbWl0MShvZCA+PiAyNCk7CiAgICAgICAgICAgIGVtaXQxKG9kID4+IDE2KTsKICAgICAgICAgICAgZW1pdDEob2QgPj4gOCk7CiAgICAgICAgICAgIGVtaXQxKG9kKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBjb2RlW2NwKytdID0gKGJ5dGUpKG9kID4+IDI0KTsKICAgICAgICAgICAgY29kZVtjcCsrXSA9IChieXRlKShvZCA+PiAxNik7CiAgICAgICAgICAgIGNvZGVbY3ArK10gPSAoYnl0ZSkob2QgPj4gOCk7CiAgICAgICAgICAgIGNvZGVbY3ArK10gPSAoYnl0ZSlvZDsKICAgICAgICB9CiAgICB9CgogICAgLyoqIEVtaXQgYW4gb3Bjb2RlLgogICAgICovCiAgICBwcml2YXRlIHZvaWQgZW1pdG9wKGludCBvcCkgewogICAgICAgIGlmIChwZW5kaW5nSnVtcHMgIT0gbnVsbCkgcmVzb2x2ZVBlbmRpbmcoKTsKICAgICAgICBpZiAoYWxpdmUpIHsKICAgICAgICAgICAgaWYgKHBlbmRpbmdTdGF0UG9zICE9IFBvc2l0aW9uLk5PUE9TKQogICAgICAgICAgICAgICAgbWFya1N0YXRCZWdpbigpOwogICAgICAgICAgICBpZiAocGVuZGluZ1N0YWNrTWFwKSB7CiAgICAgICAgICAgICAgICBwZW5kaW5nU3RhY2tNYXAgPSBmYWxzZTsKICAgICAgICAgICAgICAgIGVtaXRTdGFja01hcCgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChkZWJ1Z0NvZGUpCiAgICAgICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oImVtaXRAIiArIGNwICsgIiBzdGFjaz0iICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0ZS5zdGFja3NpemUgKyAiOiAiICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtbmVtKG9wKSk7CiAgICAgICAgICAgIGVtaXQxKG9wKTsKICAgICAgICB9CiAgICB9CgogICAgdm9pZCBwb3N0b3AoKSB7CiAgICAgICAgQXNzZXJ0LmNoZWNrKGFsaXZlIHx8IHN0YXRlLnN0YWNrc2l6ZSA9PSAwKTsKICAgIH0KCiAgICAvKiogRW1pdCBhIGxkYyAob3IgbGRjX3cpIGluc3RydWN0aW9uLCB0YWtpbmcgaW50byBhY2NvdW50IG9wZXJhbmQgc2l6ZQogICAgKi8KICAgIHB1YmxpYyB2b2lkIGVtaXRMZGMoaW50IG9kKSB7CiAgICAgICAgaWYgKG9kIDw9IDI1NSkgewogICAgICAgICAgICBlbWl0b3AxKGxkYzEsIG9kKTsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIGVtaXRvcDIobGRjMiwgb2QpOwogICAgICAgIH0KICAgIH0KCiAgICAvKiogRW1pdCBhIG11bHRpbmV3YXJyYXkgaW5zdHJ1Y3Rpb24uCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIGVtaXRNdWx0aWFuZXdhcnJheShpbnQgbmRpbXMsIGludCB0eXBlLCBUeXBlIGFycmF5VHlwZSkgewogICAgICAgIGVtaXRvcChtdWx0aWFuZXdhcnJheSk7CiAgICAgICAgaWYgKCFhbGl2ZSkgcmV0dXJuOwogICAgICAgIGVtaXQyKHR5cGUpOwogICAgICAgIGVtaXQxKG5kaW1zKTsKICAgICAgICBzdGF0ZS5wb3AobmRpbXMpOwogICAgICAgIHN0YXRlLnB1c2goYXJyYXlUeXBlKTsKICAgIH0KCiAgICAvKiogRW1pdCBuZXdhcnJheS4KICAgICAqLwogICAgcHVibGljIHZvaWQgZW1pdE5ld2FycmF5KGludCBlbGVtY29kZSwgVHlwZSBhcnJheVR5cGUpIHsKICAgICAgICBlbWl0b3AobmV3YXJyYXkpOwogICAgICAgIGlmICghYWxpdmUpIHJldHVybjsKICAgICAgICBlbWl0MShlbGVtY29kZSk7CiAgICAgICAgc3RhdGUucG9wKDEpOyAvLyBjb3VudAogICAgICAgIHN0YXRlLnB1c2goYXJyYXlUeXBlKTsKICAgIH0KCiAgICAvKiogRW1pdCBhbmV3YXJyYXkuCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIGVtaXRBbmV3YXJyYXkoaW50IG9kLCBUeXBlIGFycmF5VHlwZSkgewogICAgICAgIGVtaXRvcChhbmV3YXJyYXkpOwogICAgICAgIGlmICghYWxpdmUpIHJldHVybjsKICAgICAgICBlbWl0MihvZCk7CiAgICAgICAgc3RhdGUucG9wKDEpOwogICAgICAgIHN0YXRlLnB1c2goYXJyYXlUeXBlKTsKICAgIH0KCiAgICAvKiogRW1pdCBhbiBpbnZva2VpbnRlcmZhY2UgaW5zdHJ1Y3Rpb24uCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIGVtaXRJbnZva2VpbnRlcmZhY2UoaW50IG1ldGgsIFR5cGUgbXR5cGUpIHsKICAgICAgICBpbnQgYXJnc2l6ZSA9IHdpZHRoKG10eXBlLmdldFBhcmFtZXRlclR5cGVzKCkpOwogICAgICAgIGVtaXRvcChpbnZva2VpbnRlcmZhY2UpOwogICAgICAgIGlmICghYWxpdmUpIHJldHVybjsKICAgICAgICBlbWl0MihtZXRoKTsKICAgICAgICBlbWl0MShhcmdzaXplICsgMSk7CiAgICAgICAgZW1pdDEoMCk7CiAgICAgICAgc3RhdGUucG9wKGFyZ3NpemUgKyAxKTsKICAgICAgICBzdGF0ZS5wdXNoKG10eXBlLmdldFJldHVyblR5cGUoKSk7CiAgICB9CgogICAgLyoqIEVtaXQgYW4gaW52b2tlc3BlY2lhbCBpbnN0cnVjdGlvbi4KICAgICAqLwogICAgcHVibGljIHZvaWQgZW1pdEludm9rZXNwZWNpYWwoaW50IG1ldGgsIFR5cGUgbXR5cGUpIHsKICAgICAgICBpbnQgYXJnc2l6ZSA9IHdpZHRoKG10eXBlLmdldFBhcmFtZXRlclR5cGVzKCkpOwogICAgICAgIGVtaXRvcChpbnZva2VzcGVjaWFsKTsKICAgICAgICBpZiAoIWFsaXZlKSByZXR1cm47CiAgICAgICAgZW1pdDIobWV0aCk7CiAgICAgICAgU3ltYm9sIHN5bSA9IChTeW1ib2wpcG9vbC5wb29sW21ldGhdOwogICAgICAgIHN0YXRlLnBvcChhcmdzaXplKTsKICAgICAgICBpZiAoc3ltLmlzQ29uc3RydWN0b3IoKSkKICAgICAgICAgICAgc3RhdGUubWFya0luaXRpYWxpemVkKChVbmluaXRpYWxpemVkVHlwZSlzdGF0ZS5wZWVrKCkpOwogICAgICAgIHN0YXRlLnBvcCgxKTsKICAgICAgICBzdGF0ZS5wdXNoKG10eXBlLmdldFJldHVyblR5cGUoKSk7CiAgICB9CgogICAgLyoqIEVtaXQgYW4gaW52b2tlc3RhdGljIGluc3RydWN0aW9uLgogICAgICovCiAgICBwdWJsaWMgdm9pZCBlbWl0SW52b2tlc3RhdGljKGludCBtZXRoLCBUeXBlIG10eXBlKSB7CiAgICAgICAgaW50IGFyZ3NpemUgPSB3aWR0aChtdHlwZS5nZXRQYXJhbWV0ZXJUeXBlcygpKTsKICAgICAgICBlbWl0b3AoaW52b2tlc3RhdGljKTsKICAgICAgICBpZiAoIWFsaXZlKSByZXR1cm47CiAgICAgICAgZW1pdDIobWV0aCk7CiAgICAgICAgc3RhdGUucG9wKGFyZ3NpemUpOwogICAgICAgIHN0YXRlLnB1c2gobXR5cGUuZ2V0UmV0dXJuVHlwZSgpKTsKICAgIH0KCiAgICAvKiogRW1pdCBhbiBpbnZva2V2aXJ0dWFsIGluc3RydWN0aW9uLgogICAgICovCiAgICBwdWJsaWMgdm9pZCBlbWl0SW52b2tldmlydHVhbChpbnQgbWV0aCwgVHlwZSBtdHlwZSkgewogICAgICAgIGludCBhcmdzaXplID0gd2lkdGgobXR5cGUuZ2V0UGFyYW1ldGVyVHlwZXMoKSk7CiAgICAgICAgZW1pdG9wKGludm9rZXZpcnR1YWwpOwogICAgICAgIGlmICghYWxpdmUpIHJldHVybjsKICAgICAgICBlbWl0MihtZXRoKTsKICAgICAgICBzdGF0ZS5wb3AoYXJnc2l6ZSArIDEpOwogICAgICAgIHN0YXRlLnB1c2gobXR5cGUuZ2V0UmV0dXJuVHlwZSgpKTsKICAgIH0KCiAgICAvKiogRW1pdCBhbiBpbnZva2VkeW5hbWljIGluc3RydWN0aW9uLgogICAgICovCiAgICBwdWJsaWMgdm9pZCBlbWl0SW52b2tlZHluYW1pYyhpbnQgZGVzYywgVHlwZSBtdHlwZSkgewogICAgICAgIGludCBhcmdzaXplID0gd2lkdGgobXR5cGUuZ2V0UGFyYW1ldGVyVHlwZXMoKSk7CiAgICAgICAgZW1pdG9wKGludm9rZWR5bmFtaWMpOwogICAgICAgIGlmICghYWxpdmUpIHJldHVybjsKICAgICAgICBlbWl0MihkZXNjKTsKICAgICAgICBlbWl0MigwKTsKICAgICAgICBzdGF0ZS5wb3AoYXJnc2l6ZSk7CiAgICAgICAgc3RhdGUucHVzaChtdHlwZS5nZXRSZXR1cm5UeXBlKCkpOwogICAgfQoKICAgIC8qKiBFbWl0IGFuIG9wY29kZSB3aXRoIG5vIG9wZXJhbmQgZmllbGQuCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIGVtaXRvcDAoaW50IG9wKSB7CiAgICAgICAgZW1pdG9wKG9wKTsKICAgICAgICBpZiAoIWFsaXZlKSByZXR1cm47CiAgICAgICAgc3dpdGNoIChvcCkgewogICAgICAgIGNhc2UgYWFsb2FkOiB7CiAgICAgICAgICAgIHN0YXRlLnBvcCgxKTsvLyBpbmRleAogICAgICAgICAgICBUeXBlIGEgPSBzdGF0ZS5zdGFja1tzdGF0ZS5zdGFja3NpemUtMV07CiAgICAgICAgICAgIEFzc2VydC5jaGVjayghYS5oYXNUYWcoQk9UKSk7IC8vIG51bGwgdHlwZSBhcyBpcyBjYW5ub3QgYmUgaW5kZXhlZC4KICAgICAgICAgICAgc3RhdGUucG9wKDEpOwogICAgICAgICAgICBzdGF0ZS5wdXNoKHR5cGVzLmVyYXN1cmUodHlwZXMuZWxlbXR5cGUoYSkpKTsgfQogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIGdvdG9fOgogICAgICAgICAgICBtYXJrRGVhZCgpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIG5vcDoKICAgICAgICBjYXNlIGluZWc6CiAgICAgICAgY2FzZSBsbmVnOgogICAgICAgIGNhc2UgZm5lZzoKICAgICAgICBjYXNlIGRuZWc6CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgYWNvbnN0X251bGw6CiAgICAgICAgICAgIHN0YXRlLnB1c2goc3ltcy5ib3RUeXBlKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBpY29uc3RfbTE6CiAgICAgICAgY2FzZSBpY29uc3RfMDoKICAgICAgICBjYXNlIGljb25zdF8xOgogICAgICAgIGNhc2UgaWNvbnN0XzI6CiAgICAgICAgY2FzZSBpY29uc3RfMzoKICAgICAgICBjYXNlIGljb25zdF80OgogICAgICAgIGNhc2UgaWNvbnN0XzU6CiAgICAgICAgY2FzZSBpbG9hZF8wOgogICAgICAgIGNhc2UgaWxvYWRfMToKICAgICAgICBjYXNlIGlsb2FkXzI6CiAgICAgICAgY2FzZSBpbG9hZF8zOgogICAgICAgICAgICBzdGF0ZS5wdXNoKHN5bXMuaW50VHlwZSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgbGNvbnN0XzA6CiAgICAgICAgY2FzZSBsY29uc3RfMToKICAgICAgICBjYXNlIGxsb2FkXzA6CiAgICAgICAgY2FzZSBsbG9hZF8xOgogICAgICAgIGNhc2UgbGxvYWRfMjoKICAgICAgICBjYXNlIGxsb2FkXzM6CiAgICAgICAgICAgIHN0YXRlLnB1c2goc3ltcy5sb25nVHlwZSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgZmNvbnN0XzA6CiAgICAgICAgY2FzZSBmY29uc3RfMToKICAgICAgICBjYXNlIGZjb25zdF8yOgogICAgICAgIGNhc2UgZmxvYWRfMDoKICAgICAgICBjYXNlIGZsb2FkXzE6CiAgICAgICAgY2FzZSBmbG9hZF8yOgogICAgICAgIGNhc2UgZmxvYWRfMzoKICAgICAgICAgICAgc3RhdGUucHVzaChzeW1zLmZsb2F0VHlwZSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgZGNvbnN0XzA6CiAgICAgICAgY2FzZSBkY29uc3RfMToKICAgICAgICBjYXNlIGRsb2FkXzA6CiAgICAgICAgY2FzZSBkbG9hZF8xOgogICAgICAgIGNhc2UgZGxvYWRfMjoKICAgICAgICBjYXNlIGRsb2FkXzM6CiAgICAgICAgICAgIHN0YXRlLnB1c2goc3ltcy5kb3VibGVUeXBlKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBhbG9hZF8wOgogICAgICAgICAgICBzdGF0ZS5wdXNoKGx2YXJbMF0uc3ltLnR5cGUpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIGFsb2FkXzE6CiAgICAgICAgICAgIHN0YXRlLnB1c2gobHZhclsxXS5zeW0udHlwZSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgYWxvYWRfMjoKICAgICAgICAgICAgc3RhdGUucHVzaChsdmFyWzJdLnN5bS50eXBlKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBhbG9hZF8zOgogICAgICAgICAgICBzdGF0ZS5wdXNoKGx2YXJbM10uc3ltLnR5cGUpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIGlhbG9hZDoKICAgICAgICBjYXNlIGJhbG9hZDoKICAgICAgICBjYXNlIGNhbG9hZDoKICAgICAgICBjYXNlIHNhbG9hZDoKICAgICAgICAgICAgc3RhdGUucG9wKDIpOwogICAgICAgICAgICBzdGF0ZS5wdXNoKHN5bXMuaW50VHlwZSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgbGFsb2FkOgogICAgICAgICAgICBzdGF0ZS5wb3AoMik7CiAgICAgICAgICAgIHN0YXRlLnB1c2goc3ltcy5sb25nVHlwZSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgZmFsb2FkOgogICAgICAgICAgICBzdGF0ZS5wb3AoMik7CiAgICAgICAgICAgIHN0YXRlLnB1c2goc3ltcy5mbG9hdFR5cGUpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIGRhbG9hZDoKICAgICAgICAgICAgc3RhdGUucG9wKDIpOwogICAgICAgICAgICBzdGF0ZS5wdXNoKHN5bXMuZG91YmxlVHlwZSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgaXN0b3JlXzA6CiAgICAgICAgY2FzZSBpc3RvcmVfMToKICAgICAgICBjYXNlIGlzdG9yZV8yOgogICAgICAgIGNhc2UgaXN0b3JlXzM6CiAgICAgICAgY2FzZSBmc3RvcmVfMDoKICAgICAgICBjYXNlIGZzdG9yZV8xOgogICAgICAgIGNhc2UgZnN0b3JlXzI6CiAgICAgICAgY2FzZSBmc3RvcmVfMzoKICAgICAgICBjYXNlIGFzdG9yZV8wOgogICAgICAgIGNhc2UgYXN0b3JlXzE6CiAgICAgICAgY2FzZSBhc3RvcmVfMjoKICAgICAgICBjYXNlIGFzdG9yZV8zOgogICAgICAgIGNhc2UgcG9wOgogICAgICAgIGNhc2UgbHNocjoKICAgICAgICBjYXNlIGxzaGw6CiAgICAgICAgY2FzZSBsdXNocjoKICAgICAgICAgICAgc3RhdGUucG9wKDEpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIGFyZXR1cm46CiAgICAgICAgY2FzZSBpcmV0dXJuOgogICAgICAgIGNhc2UgZnJldHVybjoKICAgICAgICAgICAgQXNzZXJ0LmNoZWNrKHN0YXRlLm5sb2NrcyA9PSAwKTsKICAgICAgICAgICAgc3RhdGUucG9wKDEpOwogICAgICAgICAgICBtYXJrRGVhZCgpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIGF0aHJvdzoKICAgICAgICAgICAgc3RhdGUucG9wKDEpOwogICAgICAgICAgICBtYXJrRGVhZCgpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIGxzdG9yZV8wOgogICAgICAgIGNhc2UgbHN0b3JlXzE6CiAgICAgICAgY2FzZSBsc3RvcmVfMjoKICAgICAgICBjYXNlIGxzdG9yZV8zOgogICAgICAgIGNhc2UgZHN0b3JlXzA6CiAgICAgICAgY2FzZSBkc3RvcmVfMToKICAgICAgICBjYXNlIGRzdG9yZV8yOgogICAgICAgIGNhc2UgZHN0b3JlXzM6CiAgICAgICAgY2FzZSBwb3AyOgogICAgICAgICAgICBzdGF0ZS5wb3AoMik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgbHJldHVybjoKICAgICAgICBjYXNlIGRyZXR1cm46CiAgICAgICAgICAgIEFzc2VydC5jaGVjayhzdGF0ZS5ubG9ja3MgPT0gMCk7CiAgICAgICAgICAgIHN0YXRlLnBvcCgyKTsKICAgICAgICAgICAgbWFya0RlYWQoKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBkdXA6CiAgICAgICAgICAgIHN0YXRlLnB1c2goc3RhdGUuc3RhY2tbc3RhdGUuc3RhY2tzaXplLTFdKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSByZXR1cm5fOgogICAgICAgICAgICBBc3NlcnQuY2hlY2soc3RhdGUubmxvY2tzID09IDApOwogICAgICAgICAgICBtYXJrRGVhZCgpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIGFycmF5bGVuZ3RoOgogICAgICAgICAgICBzdGF0ZS5wb3AoMSk7CiAgICAgICAgICAgIHN0YXRlLnB1c2goc3ltcy5pbnRUeXBlKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBpc3ViOgogICAgICAgIGNhc2UgaWFkZDoKICAgICAgICBjYXNlIGltdWw6CiAgICAgICAgY2FzZSBpZGl2OgogICAgICAgIGNhc2UgaW1vZDoKICAgICAgICBjYXNlIGlzaGw6CiAgICAgICAgY2FzZSBpc2hyOgogICAgICAgIGNhc2UgaXVzaHI6CiAgICAgICAgY2FzZSBpYW5kOgogICAgICAgIGNhc2UgaW9yOgogICAgICAgIGNhc2UgaXhvcjoKICAgICAgICAgICAgc3RhdGUucG9wKDEpOwogICAgICAgICAgICAvLyBzdGF0ZS5wb3AoMSk7CiAgICAgICAgICAgIC8vIHN0YXRlLnB1c2goc3ltcy5pbnRUeXBlKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBhYXN0b3JlOgogICAgICAgICAgICBzdGF0ZS5wb3AoMyk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgbGFuZDoKICAgICAgICBjYXNlIGxvcjoKICAgICAgICBjYXNlIGx4b3I6CiAgICAgICAgY2FzZSBsbW9kOgogICAgICAgIGNhc2UgbGRpdjoKICAgICAgICBjYXNlIGxtdWw6CiAgICAgICAgY2FzZSBsc3ViOgogICAgICAgIGNhc2UgbGFkZDoKICAgICAgICAgICAgc3RhdGUucG9wKDIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIGxjbXA6CiAgICAgICAgICAgIHN0YXRlLnBvcCg0KTsKICAgICAgICAgICAgc3RhdGUucHVzaChzeW1zLmludFR5cGUpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIGwyaToKICAgICAgICAgICAgc3RhdGUucG9wKDIpOwogICAgICAgICAgICBzdGF0ZS5wdXNoKHN5bXMuaW50VHlwZSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgaTJsOgogICAgICAgICAgICBzdGF0ZS5wb3AoMSk7CiAgICAgICAgICAgIHN0YXRlLnB1c2goc3ltcy5sb25nVHlwZSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgaTJmOgogICAgICAgICAgICBzdGF0ZS5wb3AoMSk7CiAgICAgICAgICAgIHN0YXRlLnB1c2goc3ltcy5mbG9hdFR5cGUpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIGkyZDoKICAgICAgICAgICAgc3RhdGUucG9wKDEpOwogICAgICAgICAgICBzdGF0ZS5wdXNoKHN5bXMuZG91YmxlVHlwZSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgbDJmOgogICAgICAgICAgICBzdGF0ZS5wb3AoMik7CiAgICAgICAgICAgIHN0YXRlLnB1c2goc3ltcy5mbG9hdFR5cGUpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIGwyZDoKICAgICAgICAgICAgc3RhdGUucG9wKDIpOwogICAgICAgICAgICBzdGF0ZS5wdXNoKHN5bXMuZG91YmxlVHlwZSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgZjJpOgogICAgICAgICAgICBzdGF0ZS5wb3AoMSk7CiAgICAgICAgICAgIHN0YXRlLnB1c2goc3ltcy5pbnRUeXBlKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBmMmw6CiAgICAgICAgICAgIHN0YXRlLnBvcCgxKTsKICAgICAgICAgICAgc3RhdGUucHVzaChzeW1zLmxvbmdUeXBlKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBmMmQ6CiAgICAgICAgICAgIHN0YXRlLnBvcCgxKTsKICAgICAgICAgICAgc3RhdGUucHVzaChzeW1zLmRvdWJsZVR5cGUpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIGQyaToKICAgICAgICAgICAgc3RhdGUucG9wKDIpOwogICAgICAgICAgICBzdGF0ZS5wdXNoKHN5bXMuaW50VHlwZSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgZDJsOgogICAgICAgICAgICBzdGF0ZS5wb3AoMik7CiAgICAgICAgICAgIHN0YXRlLnB1c2goc3ltcy5sb25nVHlwZSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgZDJmOgogICAgICAgICAgICBzdGF0ZS5wb3AoMik7CiAgICAgICAgICAgIHN0YXRlLnB1c2goc3ltcy5mbG9hdFR5cGUpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIHRhYmxlc3dpdGNoOgogICAgICAgIGNhc2UgbG9va3Vwc3dpdGNoOgogICAgICAgICAgICBzdGF0ZS5wb3AoMSk7CiAgICAgICAgICAgIC8vIHRoZSBjYWxsZXIgaXMgcmVzcG9uc2libGUgZm9yIHBhdGNoaW5nIHVwIHRoZSBzdGF0ZQogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIGR1cF94MTogewogICAgICAgICAgICBUeXBlIHZhbDEgPSBzdGF0ZS5wb3AxKCk7CiAgICAgICAgICAgIFR5cGUgdmFsMiA9IHN0YXRlLnBvcDEoKTsKICAgICAgICAgICAgc3RhdGUucHVzaCh2YWwxKTsKICAgICAgICAgICAgc3RhdGUucHVzaCh2YWwyKTsKICAgICAgICAgICAgc3RhdGUucHVzaCh2YWwxKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGNhc2UgYmFzdG9yZToKICAgICAgICAgICAgc3RhdGUucG9wKDMpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIGludDJieXRlOgogICAgICAgIGNhc2UgaW50MmNoYXI6CiAgICAgICAgY2FzZSBpbnQyc2hvcnQ6CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgZm11bDoKICAgICAgICBjYXNlIGZhZGQ6CiAgICAgICAgY2FzZSBmc3ViOgogICAgICAgIGNhc2UgZmRpdjoKICAgICAgICBjYXNlIGZtb2Q6CiAgICAgICAgICAgIHN0YXRlLnBvcCgxKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBjYXN0b3JlOgogICAgICAgIGNhc2UgaWFzdG9yZToKICAgICAgICBjYXNlIGZhc3RvcmU6CiAgICAgICAgY2FzZSBzYXN0b3JlOgogICAgICAgICAgICBzdGF0ZS5wb3AoMyk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgbGFzdG9yZToKICAgICAgICBjYXNlIGRhc3RvcmU6CiAgICAgICAgICAgIHN0YXRlLnBvcCg0KTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBkdXAyOgogICAgICAgICAgICBpZiAoc3RhdGUuc3RhY2tbc3RhdGUuc3RhY2tzaXplLTFdICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIFR5cGUgdmFsdWUxID0gc3RhdGUucG9wMSgpOwogICAgICAgICAgICAgICAgVHlwZSB2YWx1ZTIgPSBzdGF0ZS5wb3AxKCk7CiAgICAgICAgICAgICAgICBzdGF0ZS5wdXNoKHZhbHVlMik7CiAgICAgICAgICAgICAgICBzdGF0ZS5wdXNoKHZhbHVlMSk7CiAgICAgICAgICAgICAgICBzdGF0ZS5wdXNoKHZhbHVlMik7CiAgICAgICAgICAgICAgICBzdGF0ZS5wdXNoKHZhbHVlMSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBUeXBlIHZhbHVlID0gc3RhdGUucG9wMigpOwogICAgICAgICAgICAgICAgc3RhdGUucHVzaCh2YWx1ZSk7CiAgICAgICAgICAgICAgICBzdGF0ZS5wdXNoKHZhbHVlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIGR1cDJfeDE6CiAgICAgICAgICAgIGlmIChzdGF0ZS5zdGFja1tzdGF0ZS5zdGFja3NpemUtMV0gIT0gbnVsbCkgewogICAgICAgICAgICAgICAgVHlwZSB2YWx1ZTEgPSBzdGF0ZS5wb3AxKCk7CiAgICAgICAgICAgICAgICBUeXBlIHZhbHVlMiA9IHN0YXRlLnBvcDEoKTsKICAgICAgICAgICAgICAgIFR5cGUgdmFsdWUzID0gc3RhdGUucG9wMSgpOwogICAgICAgICAgICAgICAgc3RhdGUucHVzaCh2YWx1ZTIpOwogICAgICAgICAgICAgICAgc3RhdGUucHVzaCh2YWx1ZTEpOwogICAgICAgICAgICAgICAgc3RhdGUucHVzaCh2YWx1ZTMpOwogICAgICAgICAgICAgICAgc3RhdGUucHVzaCh2YWx1ZTIpOwogICAgICAgICAgICAgICAgc3RhdGUucHVzaCh2YWx1ZTEpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgVHlwZSB2YWx1ZTEgPSBzdGF0ZS5wb3AyKCk7CiAgICAgICAgICAgICAgICBUeXBlIHZhbHVlMiA9IHN0YXRlLnBvcDEoKTsKICAgICAgICAgICAgICAgIHN0YXRlLnB1c2godmFsdWUxKTsKICAgICAgICAgICAgICAgIHN0YXRlLnB1c2godmFsdWUyKTsKICAgICAgICAgICAgICAgIHN0YXRlLnB1c2godmFsdWUxKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIGR1cDJfeDI6CiAgICAgICAgICAgIGlmIChzdGF0ZS5zdGFja1tzdGF0ZS5zdGFja3NpemUtMV0gIT0gbnVsbCkgewogICAgICAgICAgICAgICAgVHlwZSB2YWx1ZTEgPSBzdGF0ZS5wb3AxKCk7CiAgICAgICAgICAgICAgICBUeXBlIHZhbHVlMiA9IHN0YXRlLnBvcDEoKTsKICAgICAgICAgICAgICAgIGlmIChzdGF0ZS5zdGFja1tzdGF0ZS5zdGFja3NpemUtMV0gIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIC8vIGZvcm0gMQogICAgICAgICAgICAgICAgICAgIFR5cGUgdmFsdWUzID0gc3RhdGUucG9wMSgpOwogICAgICAgICAgICAgICAgICAgIFR5cGUgdmFsdWU0ID0gc3RhdGUucG9wMSgpOwogICAgICAgICAgICAgICAgICAgIHN0YXRlLnB1c2godmFsdWUyKTsKICAgICAgICAgICAgICAgICAgICBzdGF0ZS5wdXNoKHZhbHVlMSk7CiAgICAgICAgICAgICAgICAgICAgc3RhdGUucHVzaCh2YWx1ZTQpOwogICAgICAgICAgICAgICAgICAgIHN0YXRlLnB1c2godmFsdWUzKTsKICAgICAgICAgICAgICAgICAgICBzdGF0ZS5wdXNoKHZhbHVlMik7CiAgICAgICAgICAgICAgICAgICAgc3RhdGUucHVzaCh2YWx1ZTEpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAvLyBmb3JtIDMKICAgICAgICAgICAgICAgICAgICBUeXBlIHZhbHVlMyA9IHN0YXRlLnBvcDIoKTsKICAgICAgICAgICAgICAgICAgICBzdGF0ZS5wdXNoKHZhbHVlMik7CiAgICAgICAgICAgICAgICAgICAgc3RhdGUucHVzaCh2YWx1ZTEpOwogICAgICAgICAgICAgICAgICAgIHN0YXRlLnB1c2godmFsdWUzKTsKICAgICAgICAgICAgICAgICAgICBzdGF0ZS5wdXNoKHZhbHVlMik7CiAgICAgICAgICAgICAgICAgICAgc3RhdGUucHVzaCh2YWx1ZTEpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgVHlwZSB2YWx1ZTEgPSBzdGF0ZS5wb3AyKCk7CiAgICAgICAgICAgICAgICBpZiAoc3RhdGUuc3RhY2tbc3RhdGUuc3RhY2tzaXplLTFdICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAvLyBmb3JtIDIKICAgICAgICAgICAgICAgICAgICBUeXBlIHZhbHVlMiA9IHN0YXRlLnBvcDEoKTsKICAgICAgICAgICAgICAgICAgICBUeXBlIHZhbHVlMyA9IHN0YXRlLnBvcDEoKTsKICAgICAgICAgICAgICAgICAgICBzdGF0ZS5wdXNoKHZhbHVlMSk7CiAgICAgICAgICAgICAgICAgICAgc3RhdGUucHVzaCh2YWx1ZTMpOwogICAgICAgICAgICAgICAgICAgIHN0YXRlLnB1c2godmFsdWUyKTsKICAgICAgICAgICAgICAgICAgICBzdGF0ZS5wdXNoKHZhbHVlMSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIC8vIGZvcm0gNAogICAgICAgICAgICAgICAgICAgIFR5cGUgdmFsdWUyID0gc3RhdGUucG9wMigpOwogICAgICAgICAgICAgICAgICAgIHN0YXRlLnB1c2godmFsdWUxKTsKICAgICAgICAgICAgICAgICAgICBzdGF0ZS5wdXNoKHZhbHVlMik7CiAgICAgICAgICAgICAgICAgICAgc3RhdGUucHVzaCh2YWx1ZTEpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgZHVwX3gyOiB7CiAgICAgICAgICAgIFR5cGUgdmFsdWUxID0gc3RhdGUucG9wMSgpOwogICAgICAgICAgICBpZiAoc3RhdGUuc3RhY2tbc3RhdGUuc3RhY2tzaXplLTFdICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIC8vIGZvcm0gMQogICAgICAgICAgICAgICAgVHlwZSB2YWx1ZTIgPSBzdGF0ZS5wb3AxKCk7CiAgICAgICAgICAgICAgICBUeXBlIHZhbHVlMyA9IHN0YXRlLnBvcDEoKTsKICAgICAgICAgICAgICAgIHN0YXRlLnB1c2godmFsdWUxKTsKICAgICAgICAgICAgICAgIHN0YXRlLnB1c2godmFsdWUzKTsKICAgICAgICAgICAgICAgIHN0YXRlLnB1c2godmFsdWUyKTsKICAgICAgICAgICAgICAgIHN0YXRlLnB1c2godmFsdWUxKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIC8vIGZvcm0gMgogICAgICAgICAgICAgICAgVHlwZSB2YWx1ZTIgPSBzdGF0ZS5wb3AyKCk7CiAgICAgICAgICAgICAgICBzdGF0ZS5wdXNoKHZhbHVlMSk7CiAgICAgICAgICAgICAgICBzdGF0ZS5wdXNoKHZhbHVlMik7CiAgICAgICAgICAgICAgICBzdGF0ZS5wdXNoKHZhbHVlMSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgZmNtcGw6CiAgICAgICAgY2FzZSBmY21wZzoKICAgICAgICAgICAgc3RhdGUucG9wKDIpOwogICAgICAgICAgICBzdGF0ZS5wdXNoKHN5bXMuaW50VHlwZSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgZGNtcGw6CiAgICAgICAgY2FzZSBkY21wZzoKICAgICAgICAgICAgc3RhdGUucG9wKDQpOwogICAgICAgICAgICBzdGF0ZS5wdXNoKHN5bXMuaW50VHlwZSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2Ugc3dhcDogewogICAgICAgICAgICBUeXBlIHZhbHVlMSA9IHN0YXRlLnBvcDEoKTsKICAgICAgICAgICAgVHlwZSB2YWx1ZTIgPSBzdGF0ZS5wb3AxKCk7CiAgICAgICAgICAgIHN0YXRlLnB1c2godmFsdWUxKTsKICAgICAgICAgICAgc3RhdGUucHVzaCh2YWx1ZTIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgY2FzZSBkYWRkOgogICAgICAgIGNhc2UgZHN1YjoKICAgICAgICBjYXNlIGRtdWw6CiAgICAgICAgY2FzZSBkZGl2OgogICAgICAgIGNhc2UgZG1vZDoKICAgICAgICAgICAgc3RhdGUucG9wKDIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIHJldDoKICAgICAgICAgICAgbWFya0RlYWQoKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSB3aWRlOgogICAgICAgICAgICAvLyBtdXN0IGJlIGhhbmRsZWQgYnkgdGhlIGNhbGxlci4KICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIGNhc2UgbW9uaXRvcmVudGVyOgogICAgICAgIGNhc2UgbW9uaXRvcmV4aXQ6CiAgICAgICAgICAgIHN0YXRlLnBvcCgxKTsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihtbmVtKG9wKSk7CiAgICAgICAgfQogICAgICAgIHBvc3RvcCgpOwogICAgfQoKICAgIC8qKiBFbWl0IGFuIG9wY29kZSB3aXRoIGEgb25lLWJ5dGUgb3BlcmFuZCBmaWVsZC4KICAgICAqLwogICAgcHVibGljIHZvaWQgZW1pdG9wMShpbnQgb3AsIGludCBvZCkgewogICAgICAgIGVtaXRvcChvcCk7CiAgICAgICAgaWYgKCFhbGl2ZSkgcmV0dXJuOwogICAgICAgIGVtaXQxKG9kKTsKICAgICAgICBzd2l0Y2ggKG9wKSB7CiAgICAgICAgY2FzZSBiaXB1c2g6CiAgICAgICAgICAgIHN0YXRlLnB1c2goc3ltcy5pbnRUeXBlKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBsZGMxOgogICAgICAgICAgICBzdGF0ZS5wdXNoKHR5cGVGb3JQb29sKHBvb2wucG9vbFtvZF0pKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKG1uZW0ob3ApKTsKICAgICAgICB9CiAgICAgICAgcG9zdG9wKCk7CiAgICB9CgogICAgLyoqIFRoZSB0eXBlIG9mIGEgY29uc3RhbnQgcG9vbCBlbnRyeS4gKi8KICAgIHByaXZhdGUgVHlwZSB0eXBlRm9yUG9vbChPYmplY3QgbykgewogICAgICAgIGlmIChvIGluc3RhbmNlb2YgSW50ZWdlcikgcmV0dXJuIHN5bXMuaW50VHlwZTsKICAgICAgICBpZiAobyBpbnN0YW5jZW9mIEZsb2F0KSByZXR1cm4gc3ltcy5mbG9hdFR5cGU7CiAgICAgICAgaWYgKG8gaW5zdGFuY2VvZiBTdHJpbmcpIHJldHVybiBzeW1zLnN0cmluZ1R5cGU7CiAgICAgICAgaWYgKG8gaW5zdGFuY2VvZiBMb25nKSByZXR1cm4gc3ltcy5sb25nVHlwZTsKICAgICAgICBpZiAobyBpbnN0YW5jZW9mIERvdWJsZSkgcmV0dXJuIHN5bXMuZG91YmxlVHlwZTsKICAgICAgICBpZiAobyBpbnN0YW5jZW9mIENsYXNzU3ltYm9sKSByZXR1cm4gc3ltcy5jbGFzc1R5cGU7CiAgICAgICAgaWYgKG8gaW5zdGFuY2VvZiBQb29sLk1ldGhvZEhhbmRsZSkgcmV0dXJuIHN5bXMubWV0aG9kSGFuZGxlVHlwZTsKICAgICAgICBpZiAobyBpbnN0YW5jZW9mIFVuaXF1ZVR5cGUpIHJldHVybiB0eXBlRm9yUG9vbCgoKFVuaXF1ZVR5cGUpbykudHlwZSk7CiAgICAgICAgaWYgKG8gaW5zdGFuY2VvZiBUeXBlKSB7CiAgICAgICAgICAgIFR5cGUgdHkgPSAoVHlwZSkgbzsKCiAgICAgICAgICAgIGlmICh0eSBpbnN0YW5jZW9mIFR5cGUuQXJyYXlUeXBlKSByZXR1cm4gc3ltcy5jbGFzc1R5cGU7CiAgICAgICAgICAgIGlmICh0eSBpbnN0YW5jZW9mIFR5cGUuTWV0aG9kVHlwZSkgcmV0dXJuIHN5bXMubWV0aG9kVHlwZVR5cGU7CiAgICAgICAgfQogICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigiSW52YWxpZCB0eXBlIG9mIGNvbnN0YW50IHBvb2wgZW50cnk6ICIgKyBvLmdldENsYXNzKCkpOwogICAgfQoKICAgIC8qKiBFbWl0IGFuIG9wY29kZSB3aXRoIGEgb25lLWJ5dGUgb3BlcmFuZCBmaWVsZDsKICAgICAqICB3aWRlbiBpZiBmaWVsZCBkb2VzIG5vdCBmaXQgaW4gYSBieXRlLgogICAgICovCiAgICBwdWJsaWMgdm9pZCBlbWl0b3AxdyhpbnQgb3AsIGludCBvZCkgewogICAgICAgIGlmIChvZCA+IDB4RkYpIHsKICAgICAgICAgICAgZW1pdG9wKHdpZGUpOwogICAgICAgICAgICBlbWl0b3Aob3ApOwogICAgICAgICAgICBlbWl0MihvZCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW1pdG9wKG9wKTsKICAgICAgICAgICAgZW1pdDEob2QpOwogICAgICAgIH0KICAgICAgICBpZiAoIWFsaXZlKSByZXR1cm47CiAgICAgICAgc3dpdGNoIChvcCkgewogICAgICAgIGNhc2UgaWxvYWQ6CiAgICAgICAgICAgIHN0YXRlLnB1c2goc3ltcy5pbnRUeXBlKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBsbG9hZDoKICAgICAgICAgICAgc3RhdGUucHVzaChzeW1zLmxvbmdUeXBlKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBmbG9hZDoKICAgICAgICAgICAgc3RhdGUucHVzaChzeW1zLmZsb2F0VHlwZSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgZGxvYWQ6CiAgICAgICAgICAgIHN0YXRlLnB1c2goc3ltcy5kb3VibGVUeXBlKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBhbG9hZDoKICAgICAgICAgICAgc3RhdGUucHVzaChsdmFyW29kXS5zeW0udHlwZSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgbHN0b3JlOgogICAgICAgIGNhc2UgZHN0b3JlOgogICAgICAgICAgICBzdGF0ZS5wb3AoMik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgaXN0b3JlOgogICAgICAgIGNhc2UgZnN0b3JlOgogICAgICAgIGNhc2UgYXN0b3JlOgogICAgICAgICAgICBzdGF0ZS5wb3AoMSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgcmV0OgogICAgICAgICAgICBtYXJrRGVhZCgpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IobW5lbShvcCkpOwogICAgICAgIH0KICAgICAgICBwb3N0b3AoKTsKICAgIH0KCiAgICAvKiogRW1pdCBhbiBvcGNvZGUgd2l0aCB0d28gb25lLWJ5dGUgb3BlcmFuZCBmaWVsZHM7CiAgICAgKiAgd2lkZW4gaWYgZWl0aGVyIGZpZWxkIGRvZXMgbm90IGZpdCBpbiBhIGJ5dGUuCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIGVtaXRvcDF3KGludCBvcCwgaW50IG9kMSwgaW50IG9kMikgewogICAgICAgIGlmIChvZDEgPiAweEZGIHx8IG9kMiA8IC0xMjggfHwgb2QyID4gMTI3KSB7CiAgICAgICAgICAgIGVtaXRvcCh3aWRlKTsKICAgICAgICAgICAgZW1pdG9wKG9wKTsKICAgICAgICAgICAgZW1pdDIob2QxKTsKICAgICAgICAgICAgZW1pdDIob2QyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbWl0b3Aob3ApOwogICAgICAgICAgICBlbWl0MShvZDEpOwogICAgICAgICAgICBlbWl0MShvZDIpOwogICAgICAgIH0KICAgICAgICBpZiAoIWFsaXZlKSByZXR1cm47CiAgICAgICAgc3dpdGNoIChvcCkgewogICAgICAgIGNhc2UgaWluYzoKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKG1uZW0ob3ApKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqIEVtaXQgYW4gb3Bjb2RlIHdpdGggYSB0d28tYnl0ZSBvcGVyYW5kIGZpZWxkLgogICAgICovCiAgICBwdWJsaWMgdm9pZCBlbWl0b3AyKGludCBvcCwgaW50IG9kKSB7CiAgICAgICAgZW1pdG9wKG9wKTsKICAgICAgICBpZiAoIWFsaXZlKSByZXR1cm47CiAgICAgICAgZW1pdDIob2QpOwogICAgICAgIHN3aXRjaCAob3ApIHsKICAgICAgICBjYXNlIGdldHN0YXRpYzoKICAgICAgICAgICAgc3RhdGUucHVzaCgoKFN5bWJvbCkocG9vbC5wb29sW29kXSkpLmVyYXN1cmUodHlwZXMpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBwdXRzdGF0aWM6CiAgICAgICAgICAgIHN0YXRlLnBvcCgoKFN5bWJvbCkocG9vbC5wb29sW29kXSkpLmVyYXN1cmUodHlwZXMpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBuZXdfOgogICAgICAgICAgICBTeW1ib2wgc3ltOwogICAgICAgICAgICBpZiAocG9vbC5wb29sW29kXSBpbnN0YW5jZW9mIFVuaXF1ZVR5cGUpIHsKICAgICAgICAgICAgICAgIC8vIFJlcXVpcmVkIGJ5IGNoYW5nZSBpbiBHZW4ubWFrZVJlZiB0byBhbGxvdwogICAgICAgICAgICAgICAgLy8gYW5ub3RhdGVkIHR5cGVzLgogICAgICAgICAgICAgICAgLy8gVE9ETzogaXMgdGhpcyBuZWVkZWQgYW55d2hlcmUgZWxzZT8KICAgICAgICAgICAgICAgIHN5bSA9ICgoVW5pcXVlVHlwZSkocG9vbC5wb29sW29kXSkpLnR5cGUudHN5bTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHN5bSA9IChTeW1ib2wpKHBvb2wucG9vbFtvZF0pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHN0YXRlLnB1c2godW5pbml0aWFsaXplZE9iamVjdChzeW0uZXJhc3VyZSh0eXBlcyksIGNwLTMpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBzaXB1c2g6CiAgICAgICAgICAgIHN0YXRlLnB1c2goc3ltcy5pbnRUeXBlKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBpZl9hY21wX251bGw6CiAgICAgICAgY2FzZSBpZl9hY21wX25vbm51bGw6CiAgICAgICAgY2FzZSBpZmVxOgogICAgICAgIGNhc2UgaWZuZToKICAgICAgICBjYXNlIGlmbHQ6CiAgICAgICAgY2FzZSBpZmdlOgogICAgICAgIGNhc2UgaWZndDoKICAgICAgICBjYXNlIGlmbGU6CiAgICAgICAgICAgIHN0YXRlLnBvcCgxKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBpZl9pY21wZXE6CiAgICAgICAgY2FzZSBpZl9pY21wbmU6CiAgICAgICAgY2FzZSBpZl9pY21wbHQ6CiAgICAgICAgY2FzZSBpZl9pY21wZ2U6CiAgICAgICAgY2FzZSBpZl9pY21wZ3Q6CiAgICAgICAgY2FzZSBpZl9pY21wbGU6CiAgICAgICAgY2FzZSBpZl9hY21wZXE6CiAgICAgICAgY2FzZSBpZl9hY21wbmU6CiAgICAgICAgICAgIHN0YXRlLnBvcCgyKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBnb3RvXzoKICAgICAgICAgICAgbWFya0RlYWQoKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBwdXRmaWVsZDoKICAgICAgICAgICAgc3RhdGUucG9wKCgoU3ltYm9sKShwb29sLnBvb2xbb2RdKSkuZXJhc3VyZSh0eXBlcykpOwogICAgICAgICAgICBzdGF0ZS5wb3AoMSk7IC8vIG9iamVjdCByZWYKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBnZXRmaWVsZDoKICAgICAgICAgICAgc3RhdGUucG9wKDEpOyAvLyBvYmplY3QgcmVmCiAgICAgICAgICAgIHN0YXRlLnB1c2goKChTeW1ib2wpKHBvb2wucG9vbFtvZF0pKS5lcmFzdXJlKHR5cGVzKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgY2hlY2tjYXN0OiB7CiAgICAgICAgICAgIHN0YXRlLnBvcCgxKTsgLy8gb2JqZWN0IHJlZgogICAgICAgICAgICBPYmplY3QgbyA9IHBvb2wucG9vbFtvZF07CiAgICAgICAgICAgIFR5cGUgdCA9IChvIGluc3RhbmNlb2YgU3ltYm9sKQogICAgICAgICAgICAgICAgPyAoKFN5bWJvbClvKS5lcmFzdXJlKHR5cGVzKQogICAgICAgICAgICAgICAgOiB0eXBlcy5lcmFzdXJlKCgoKFVuaXF1ZVR5cGUpbykudHlwZSkpOwogICAgICAgICAgICBzdGF0ZS5wdXNoKHQpOwogICAgICAgICAgICBicmVhazsgfQogICAgICAgIGNhc2UgbGRjMnc6CiAgICAgICAgICAgIHN0YXRlLnB1c2godHlwZUZvclBvb2wocG9vbC5wb29sW29kXSkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIGluc3RhbmNlb2ZfOgogICAgICAgICAgICBzdGF0ZS5wb3AoMSk7CiAgICAgICAgICAgIHN0YXRlLnB1c2goc3ltcy5pbnRUeXBlKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBsZGMyOgogICAgICAgICAgICBzdGF0ZS5wdXNoKHR5cGVGb3JQb29sKHBvb2wucG9vbFtvZF0pKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBqc3I6CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihtbmVtKG9wKSk7CiAgICAgICAgfQogICAgICAgIC8vIHBvc3RvcCgpOwogICAgfQoKICAgIC8qKiBFbWl0IGFuIG9wY29kZSB3aXRoIGEgZm91ci1ieXRlIG9wZXJhbmQgZmllbGQuCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIGVtaXRvcDQoaW50IG9wLCBpbnQgb2QpIHsKICAgICAgICBlbWl0b3Aob3ApOwogICAgICAgIGlmICghYWxpdmUpIHJldHVybjsKICAgICAgICBlbWl0NChvZCk7CiAgICAgICAgc3dpdGNoIChvcCkgewogICAgICAgIGNhc2UgZ290b193OgogICAgICAgICAgICBtYXJrRGVhZCgpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIGpzcl93OgogICAgICAgICAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IobW5lbShvcCkpOwogICAgICAgIH0KICAgICAgICAvLyBwb3N0b3AoKTsKICAgIH0KCiAgICAvKiogQWxpZ24gY29kZSBwb2ludGVyIHRvIG5leHQgYGluY3InIGJvdW5kYXJ5LgogICAgICovCiAgICBwdWJsaWMgdm9pZCBhbGlnbihpbnQgaW5jcikgewogICAgICAgIGlmIChhbGl2ZSkKICAgICAgICAgICAgd2hpbGUgKGNwICUgaW5jciAhPSAwKSBlbWl0b3AwKG5vcCk7CiAgICB9CgogICAgLyoqIFBsYWNlIGEgYnl0ZSBpbnRvIGNvZGUgYXQgYWRkcmVzcyBwYy4KICAgICAqICBQcmU6IHtAbGl0ZXJhbCBwYyArIDEgPD0gY3AgfS4KICAgICAqLwogICAgcHJpdmF0ZSB2b2lkIHB1dDEoaW50IHBjLCBpbnQgb3ApIHsKICAgICAgICBjb2RlW3BjXSA9IChieXRlKW9wOwogICAgfQoKICAgIC8qKiBQbGFjZSB0d28gYnl0ZXMgaW50byBjb2RlIGF0IGFkZHJlc3MgcGMuCiAgICAgKiAgUHJlOiB7QGxpdGVyYWwgcGMgKyAyIDw9IGNwIH0uCiAgICAgKi8KICAgIHByaXZhdGUgdm9pZCBwdXQyKGludCBwYywgaW50IG9kKSB7CiAgICAgICAgLy8gcHJlOiBwYyArIDIgPD0gY3AKICAgICAgICBwdXQxKHBjLCBvZCA+PiA4KTsKICAgICAgICBwdXQxKHBjKzEsIG9kKTsKICAgIH0KCiAgICAvKiogUGxhY2UgZm91ciAgYnl0ZXMgaW50byBjb2RlIGF0IGFkZHJlc3MgcGMuCiAgICAgKiAgUHJlOiB7QGxpdGVyYWwgcGMgKyA0IDw9IGNwIH0uCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHB1dDQoaW50IHBjLCBpbnQgb2QpIHsKICAgICAgICAvLyBwcmU6IHBjICsgNCA8PSBjcAogICAgICAgIHB1dDEocGMgICwgb2QgPj4gMjQpOwogICAgICAgIHB1dDEocGMrMSwgb2QgPj4gMTYpOwogICAgICAgIHB1dDEocGMrMiwgb2QgPj4gOCk7CiAgICAgICAgcHV0MShwYyszLCBvZCk7CiAgICB9CgogICAgLyoqIFJldHVybiBjb2RlIGJ5dGUgYXQgcG9zaXRpb24gcGMgYXMgYW4gdW5zaWduZWQgaW50LgogICAgICovCiAgICBwcml2YXRlIGludCBnZXQxKGludCBwYykgewogICAgICAgIHJldHVybiBjb2RlW3BjXSAmIDB4RkY7CiAgICB9CgogICAgLyoqIFJldHVybiB0d28gY29kZSBieXRlcyBhdCBwb3NpdGlvbiBwYyBhcyBhbiB1bnNpZ25lZCBpbnQuCiAgICAgKi8KICAgIHByaXZhdGUgaW50IGdldDIoaW50IHBjKSB7CiAgICAgICAgcmV0dXJuIChnZXQxKHBjKSA8PCA4KSB8IGdldDEocGMrMSk7CiAgICB9CgogICAgLyoqIFJldHVybiBmb3VyIGNvZGUgYnl0ZXMgYXQgcG9zaXRpb24gcGMgYXMgYW4gaW50LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldDQoaW50IHBjKSB7CiAgICAgICAgLy8gcHJlOiBwYyArIDQgPD0gY3AKICAgICAgICByZXR1cm4KICAgICAgICAgICAgKGdldDEocGMpIDw8IDI0KSB8CiAgICAgICAgICAgIChnZXQxKHBjKzEpIDw8IDE2KSB8CiAgICAgICAgICAgIChnZXQxKHBjKzIpIDw8IDgpIHwKICAgICAgICAgICAgKGdldDEocGMrMykpOwogICAgfQoKICAgIC8qKiBJcyBjb2RlIGdlbmVyYXRpb24gY3VycmVudGx5IGVuYWJsZWQ/CiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGlzQWxpdmUoKSB7CiAgICAgICAgcmV0dXJuIGFsaXZlIHx8IHBlbmRpbmdKdW1wcyAhPSBudWxsOwogICAgfQoKICAgIC8qKiBTd2l0Y2ggY29kZSBnZW5lcmF0aW9uIG9uL29mZi4KICAgICAqLwogICAgcHVibGljIHZvaWQgbWFya0RlYWQoKSB7CiAgICAgICAgYWxpdmUgPSBmYWxzZTsKICAgIH0KCiAgICAvKiogRGVjbGFyZSBhbiBlbnRyeSBwb2ludDsgcmV0dXJuIGN1cnJlbnQgY29kZSBwb2ludGVyCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZW50cnlQb2ludCgpIHsKICAgICAgICBpbnQgcGMgPSBjdXJDUCgpOwogICAgICAgIGFsaXZlID0gdHJ1ZTsKICAgICAgICBwZW5kaW5nU3RhY2tNYXAgPSBuZWVkU3RhY2tNYXA7CiAgICAgICAgcmV0dXJuIHBjOwogICAgfQoKICAgIC8qKiBEZWNsYXJlIGFuIGVudHJ5IHBvaW50IHdpdGggaW5pdGlhbCBzdGF0ZTsKICAgICAqICByZXR1cm4gY3VycmVudCBjb2RlIHBvaW50ZXIKICAgICAqLwogICAgcHVibGljIGludCBlbnRyeVBvaW50KFN0YXRlIHN0YXRlKSB7CiAgICAgICAgaW50IHBjID0gY3VyQ1AoKTsKICAgICAgICBhbGl2ZSA9IHRydWU7CiAgICAgICAgU3RhdGUgbmV3U3RhdGUgPSBzdGF0ZS5kdXAoKTsKICAgICAgICBzZXREZWZpbmVkKG5ld1N0YXRlLmRlZmluZWQpOwogICAgICAgIHRoaXMuc3RhdGUgPSBuZXdTdGF0ZTsKICAgICAgICBBc3NlcnQuY2hlY2soc3RhdGUuc3RhY2tzaXplIDw9IG1heF9zdGFjayk7CiAgICAgICAgaWYgKGRlYnVnQ29kZSkgU3lzdGVtLmVyci5wcmludGxuKCJlbnRyeSBwb2ludCAiICsgc3RhdGUpOwogICAgICAgIHBlbmRpbmdTdGFja01hcCA9IG5lZWRTdGFja01hcDsKICAgICAgICByZXR1cm4gcGM7CiAgICB9CgogICAgLyoqIERlY2xhcmUgYW4gZW50cnkgcG9pbnQgd2l0aCBpbml0aWFsIHN0YXRlIHBsdXMgYSBwdXNoZWQgdmFsdWU7CiAgICAgKiAgcmV0dXJuIGN1cnJlbnQgY29kZSBwb2ludGVyCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZW50cnlQb2ludChTdGF0ZSBzdGF0ZSwgVHlwZSBwdXNoZWQpIHsKICAgICAgICBpbnQgcGMgPSBjdXJDUCgpOwogICAgICAgIGFsaXZlID0gdHJ1ZTsKICAgICAgICBTdGF0ZSBuZXdTdGF0ZSA9IHN0YXRlLmR1cCgpOwogICAgICAgIHNldERlZmluZWQobmV3U3RhdGUuZGVmaW5lZCk7CiAgICAgICAgdGhpcy5zdGF0ZSA9IG5ld1N0YXRlOwogICAgICAgIEFzc2VydC5jaGVjayhzdGF0ZS5zdGFja3NpemUgPD0gbWF4X3N0YWNrKTsKICAgICAgICB0aGlzLnN0YXRlLnB1c2gocHVzaGVkKTsKICAgICAgICBpZiAoZGVidWdDb2RlKSBTeXN0ZW0uZXJyLnByaW50bG4oImVudHJ5IHBvaW50ICIgKyBzdGF0ZSk7CiAgICAgICAgcGVuZGluZ1N0YWNrTWFwID0gbmVlZFN0YWNrTWFwOwogICAgICAgIHJldHVybiBwYzsKICAgIH0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU3RhY2sgbWFwIGdlbmVyYXRpb24KICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgogICAgLyoqIEFuIGVudHJ5IGluIHRoZSBzdGFjayBtYXAuICovCiAgICBzdGF0aWMgY2xhc3MgU3RhY2tNYXBGcmFtZSB7CiAgICAgICAgaW50IHBjOwogICAgICAgIFR5cGVbXSBsb2NhbHM7CiAgICAgICAgVHlwZVtdIHN0YWNrOwogICAgfQoKICAgIC8qKiBBIGJ1ZmZlciBvZiBjbGRjIHN0YWNrIG1hcCBlbnRyaWVzLiAqLwogICAgU3RhY2tNYXBGcmFtZVtdIHN0YWNrTWFwQnVmZmVyID0gbnVsbDsKCiAgICAvKiogQSBidWZmZXIgb2YgY29tcHJlc3NlZCBTdGFja01hcFRhYmxlIGVudHJpZXMuICovCiAgICBTdGFja01hcFRhYmxlRnJhbWVbXSBzdGFja01hcFRhYmxlQnVmZmVyID0gbnVsbDsKICAgIGludCBzdGFja01hcEJ1ZmZlclNpemUgPSAwOwoKICAgIC8qKiBUaGUgbGFzdCBQQyBhdCB3aGljaCB3ZSBnZW5lcmF0ZWQgYSBzdGFjayBtYXAuICovCiAgICBpbnQgbGFzdFN0YWNrTWFwUEMgPSAtMTsKCiAgICAvKiogVGhlIGxhc3Qgc3RhY2sgbWFwIGZyYW1lIGluIFN0YWNrTWFwVGFibGUuICovCiAgICBTdGFja01hcEZyYW1lIGxhc3RGcmFtZSA9IG51bGw7CgogICAgLyoqIFRoZSBzdGFjayBtYXAgZnJhbWUgYmVmb3JlIHRoZSBsYXN0IG9uZS4gKi8KICAgIFN0YWNrTWFwRnJhbWUgZnJhbWVCZWZvcmVMYXN0ID0gbnVsbDsKCiAgICAvKiogRW1pdCBhIHN0YWNrIG1hcCBlbnRyeS4gICovCiAgICBwdWJsaWMgdm9pZCBlbWl0U3RhY2tNYXAoKSB7CiAgICAgICAgaW50IHBjID0gY3VyQ1AoKTsKICAgICAgICBpZiAoIW5lZWRTdGFja01hcCkgcmV0dXJuOwoKCgogICAgICAgIHN3aXRjaCAoc3RhY2tNYXApIHsKICAgICAgICAgICAgY2FzZSBDTERDOgogICAgICAgICAgICAgICAgZW1pdENMRENTdGFja01hcChwYywgZ2V0TG9jYWxzU2l6ZSgpKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIEpTUjIwMjoKICAgICAgICAgICAgICAgIGVtaXRTdGFja01hcEZyYW1lKHBjLCBnZXRMb2NhbHNTaXplKCkpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoIlNob3VsZCBoYXZlIGNob3NlbiBhIHN0YWNrbWFwIGZvcm1hdCIpOwogICAgICAgIH0KICAgICAgICAvLyBERUJVRyBjb2RlIGZvbGxvd3MKICAgICAgICBpZiAoZGVidWdDb2RlKSBzdGF0ZS5kdW1wKHBjKTsKICAgIH0KCiAgICBwcml2YXRlIGludCBnZXRMb2NhbHNTaXplKCkgewogICAgICAgIGludCBuZXh0TG9jYWwgPSAwOwogICAgICAgIGZvciAoaW50IGk9bWF4X2xvY2Fscy0xOyBpPj0wOyBpLS0pIHsKICAgICAgICAgICAgaWYgKHN0YXRlLmRlZmluZWQuaXNNZW1iZXIoaSkgJiYgbHZhcltpXSAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICBuZXh0TG9jYWwgPSBpICsgd2lkdGgobHZhcltpXS5zeW0uZXJhc3VyZSh0eXBlcykpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIG5leHRMb2NhbDsKICAgIH0KCiAgICAvKiogRW1pdCBhIENMREMgc3RhY2sgbWFwIGZyYW1lLiAqLwogICAgdm9pZCBlbWl0Q0xEQ1N0YWNrTWFwKGludCBwYywgaW50IGxvY2Fsc1NpemUpIHsKICAgICAgICBpZiAobGFzdFN0YWNrTWFwUEMgPT0gcGMpIHsKICAgICAgICAgICAgLy8gZHJvcCBleGlzdGluZyBzdGFja21hcCBhdCB0aGlzIG9mZnNldAogICAgICAgICAgICBzdGFja01hcEJ1ZmZlclstLXN0YWNrTWFwQnVmZmVyU2l6ZV0gPSBudWxsOwogICAgICAgIH0KICAgICAgICBsYXN0U3RhY2tNYXBQQyA9IHBjOwoKICAgICAgICBpZiAoc3RhY2tNYXBCdWZmZXIgPT0gbnVsbCkgewogICAgICAgICAgICBzdGFja01hcEJ1ZmZlciA9IG5ldyBTdGFja01hcEZyYW1lWzIwXTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzdGFja01hcEJ1ZmZlciA9IEFycmF5VXRpbHMuZW5zdXJlQ2FwYWNpdHkoc3RhY2tNYXBCdWZmZXIsIHN0YWNrTWFwQnVmZmVyU2l6ZSk7CiAgICAgICAgfQogICAgICAgIFN0YWNrTWFwRnJhbWUgZnJhbWUgPQogICAgICAgICAgICBzdGFja01hcEJ1ZmZlcltzdGFja01hcEJ1ZmZlclNpemUrK10gPSBuZXcgU3RhY2tNYXBGcmFtZSgpOwogICAgICAgIGZyYW1lLnBjID0gcGM7CgogICAgICAgIGZyYW1lLmxvY2FscyA9IG5ldyBUeXBlW2xvY2Fsc1NpemVdOwogICAgICAgIGZvciAoaW50IGk9MDsgaTxsb2NhbHNTaXplOyBpKyspIHsKICAgICAgICAgICAgaWYgKHN0YXRlLmRlZmluZWQuaXNNZW1iZXIoaSkgJiYgbHZhcltpXSAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICBUeXBlIHZ0eXBlID0gbHZhcltpXS5zeW0udHlwZTsKICAgICAgICAgICAgICAgIGlmICghKHZ0eXBlIGluc3RhbmNlb2YgVW5pbml0aWFsaXplZFR5cGUpKQogICAgICAgICAgICAgICAgICAgIHZ0eXBlID0gdHlwZXMuZXJhc3VyZSh2dHlwZSk7CiAgICAgICAgICAgICAgICBmcmFtZS5sb2NhbHNbaV0gPSB2dHlwZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBmcmFtZS5zdGFjayA9IG5ldyBUeXBlW3N0YXRlLnN0YWNrc2l6ZV07CiAgICAgICAgZm9yIChpbnQgaT0wOyBpPHN0YXRlLnN0YWNrc2l6ZTsgaSsrKQogICAgICAgICAgICBmcmFtZS5zdGFja1tpXSA9IHN0YXRlLnN0YWNrW2ldOwogICAgfQoKICAgIHZvaWQgZW1pdFN0YWNrTWFwRnJhbWUoaW50IHBjLCBpbnQgbG9jYWxzU2l6ZSkgewogICAgICAgIGlmIChsYXN0RnJhbWUgPT0gbnVsbCkgewogICAgICAgICAgICAvLyBmaXJzdCBmcmFtZQogICAgICAgICAgICBsYXN0RnJhbWUgPSBnZXRJbml0aWFsRnJhbWUoKTsKICAgICAgICB9IGVsc2UgaWYgKGxhc3RGcmFtZS5wYyA9PSBwYykgewogICAgICAgICAgICAvLyBkcm9wIGV4aXN0aW5nIHN0YWNrbWFwIGF0IHRoaXMgb2Zmc2V0CiAgICAgICAgICAgIHN0YWNrTWFwVGFibGVCdWZmZXJbLS1zdGFja01hcEJ1ZmZlclNpemVdID0gbnVsbDsKICAgICAgICAgICAgbGFzdEZyYW1lID0gZnJhbWVCZWZvcmVMYXN0OwogICAgICAgICAgICBmcmFtZUJlZm9yZUxhc3QgPSBudWxsOwogICAgICAgIH0KCiAgICAgICAgU3RhY2tNYXBGcmFtZSBmcmFtZSA9IG5ldyBTdGFja01hcEZyYW1lKCk7CiAgICAgICAgZnJhbWUucGMgPSBwYzsKCiAgICAgICAgaW50IGxvY2FsQ291bnQgPSAwOwogICAgICAgIFR5cGVbXSBsb2NhbHMgPSBuZXcgVHlwZVtsb2NhbHNTaXplXTsKICAgICAgICBmb3IgKGludCBpPTA7IGk8bG9jYWxzU2l6ZTsgaSsrLCBsb2NhbENvdW50KyspIHsKICAgICAgICAgICAgaWYgKHN0YXRlLmRlZmluZWQuaXNNZW1iZXIoaSkgJiYgbHZhcltpXSAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICBUeXBlIHZ0eXBlID0gbHZhcltpXS5zeW0udHlwZTsKICAgICAgICAgICAgICAgIGlmICghKHZ0eXBlIGluc3RhbmNlb2YgVW5pbml0aWFsaXplZFR5cGUpKQogICAgICAgICAgICAgICAgICAgIHZ0eXBlID0gdHlwZXMuZXJhc3VyZSh2dHlwZSk7CiAgICAgICAgICAgICAgICBsb2NhbHNbaV0gPSB2dHlwZTsKICAgICAgICAgICAgICAgIGlmICh3aWR0aCh2dHlwZSkgPiAxKSBpKys7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZnJhbWUubG9jYWxzID0gbmV3IFR5cGVbbG9jYWxDb3VudF07CiAgICAgICAgZm9yIChpbnQgaT0wLCBqPTA7IGk8bG9jYWxzU2l6ZTsgaSsrLCBqKyspIHsKICAgICAgICAgICAgQXNzZXJ0LmNoZWNrKGogPCBsb2NhbENvdW50KTsKICAgICAgICAgICAgZnJhbWUubG9jYWxzW2pdID0gbG9jYWxzW2ldOwogICAgICAgICAgICBpZiAod2lkdGgobG9jYWxzW2ldKSA+IDEpIGkrKzsKICAgICAgICB9CgogICAgICAgIGludCBzdGFja0NvdW50ID0gMDsKICAgICAgICBmb3IgKGludCBpPTA7IGk8c3RhdGUuc3RhY2tzaXplOyBpKyspIHsKICAgICAgICAgICAgaWYgKHN0YXRlLnN0YWNrW2ldICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIHN0YWNrQ291bnQrKzsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBmcmFtZS5zdGFjayA9IG5ldyBUeXBlW3N0YWNrQ291bnRdOwogICAgICAgIHN0YWNrQ291bnQgPSAwOwogICAgICAgIGZvciAoaW50IGk9MDsgaTxzdGF0ZS5zdGFja3NpemU7IGkrKykgewogICAgICAgICAgICBpZiAoc3RhdGUuc3RhY2tbaV0gIT0gbnVsbCkgewogICAgICAgICAgICAgICAgZnJhbWUuc3RhY2tbc3RhY2tDb3VudCsrXSA9IHR5cGVzLmVyYXN1cmUoc3RhdGUuc3RhY2tbaV0pOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoc3RhY2tNYXBUYWJsZUJ1ZmZlciA9PSBudWxsKSB7CiAgICAgICAgICAgIHN0YWNrTWFwVGFibGVCdWZmZXIgPSBuZXcgU3RhY2tNYXBUYWJsZUZyYW1lWzIwXTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzdGFja01hcFRhYmxlQnVmZmVyID0gQXJyYXlVdGlscy5lbnN1cmVDYXBhY2l0eSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhY2tNYXBUYWJsZUJ1ZmZlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhY2tNYXBCdWZmZXJTaXplKTsKICAgICAgICB9CiAgICAgICAgc3RhY2tNYXBUYWJsZUJ1ZmZlcltzdGFja01hcEJ1ZmZlclNpemUrK10gPQogICAgICAgICAgICAgICAgU3RhY2tNYXBUYWJsZUZyYW1lLmdldEluc3RhbmNlKGZyYW1lLCBsYXN0RnJhbWUucGMsIGxhc3RGcmFtZS5sb2NhbHMsIHR5cGVzKTsKCiAgICAgICAgZnJhbWVCZWZvcmVMYXN0ID0gbGFzdEZyYW1lOwogICAgICAgIGxhc3RGcmFtZSA9IGZyYW1lOwogICAgfQoKICAgIFN0YWNrTWFwRnJhbWUgZ2V0SW5pdGlhbEZyYW1lKCkgewogICAgICAgIFN0YWNrTWFwRnJhbWUgZnJhbWUgPSBuZXcgU3RhY2tNYXBGcmFtZSgpOwogICAgICAgIExpc3Q8VHlwZT4gYXJnX3R5cGVzID0gKChNZXRob2RUeXBlKW1ldGguZXh0ZXJuYWxUeXBlKHR5cGVzKSkuYXJndHlwZXM7CiAgICAgICAgaW50IGxlbiA9IGFyZ190eXBlcy5sZW5ndGgoKTsKICAgICAgICBpbnQgY291bnQgPSAwOwogICAgICAgIGlmICghbWV0aC5pc1N0YXRpYygpKSB7CiAgICAgICAgICAgIFR5cGUgdGhpc1R5cGUgPSBtZXRoLm93bmVyLnR5cGU7CiAgICAgICAgICAgIGZyYW1lLmxvY2FscyA9IG5ldyBUeXBlW2xlbisxXTsKICAgICAgICAgICAgaWYgKG1ldGguaXNDb25zdHJ1Y3RvcigpICYmIHRoaXNUeXBlICE9IHN5bXMub2JqZWN0VHlwZSkgewogICAgICAgICAgICAgICAgZnJhbWUubG9jYWxzW2NvdW50KytdID0gVW5pbml0aWFsaXplZFR5cGUudW5pbml0aWFsaXplZFRoaXModGhpc1R5cGUpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgZnJhbWUubG9jYWxzW2NvdW50KytdID0gdHlwZXMuZXJhc3VyZSh0aGlzVHlwZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBmcmFtZS5sb2NhbHMgPSBuZXcgVHlwZVtsZW5dOwogICAgICAgIH0KICAgICAgICBmb3IgKFR5cGUgYXJnX3R5cGUgOiBhcmdfdHlwZXMpIHsKICAgICAgICAgICAgZnJhbWUubG9jYWxzW2NvdW50KytdID0gdHlwZXMuZXJhc3VyZShhcmdfdHlwZSk7CiAgICAgICAgfQogICAgICAgIGZyYW1lLnBjID0gLTE7CiAgICAgICAgZnJhbWUuc3RhY2sgPSBudWxsOwogICAgICAgIHJldHVybiBmcmFtZTsKICAgIH0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogT3BlcmF0aW9ucyBoYXZpbmcgdG8gZG8gd2l0aCBqdW1wcwogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiAgICAvKiogQSBjaGFpbiByZXByZXNlbnRzIGEgbGlzdCBvZiB1bnJlc29sdmVkIGp1bXBzLiBKdW1wIGxvY2F0aW9ucwogICAgICogIGFyZSBzb3J0ZWQgaW4gZGVjcmVhc2luZyBvcmRlci4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBjbGFzcyBDaGFpbiB7CgogICAgICAgIC8qKiBUaGUgcG9zaXRpb24gb2YgdGhlIGp1bXAgaW5zdHJ1Y3Rpb24uCiAgICAgICAgICovCiAgICAgICAgcHVibGljIGZpbmFsIGludCBwYzsKCiAgICAgICAgLyoqIFRoZSBtYWNoaW5lIHN0YXRlIGFmdGVyIHRoZSBqdW1wIGluc3RydWN0aW9uLgogICAgICAgICAqICBJbnZhcmlhbnQ6IGFsbCBlbGVtZW50cyBvZiBhIGNoYWluIGxpc3QgaGF2ZSB0aGUgc2FtZSBzdGFja3NpemUKICAgICAgICAgKiAgYW5kIGNvbXBhdGlibGUgc3RhY2sgYW5kIHJlZ2lzdGVyIGNvbnRlbnRzLgogICAgICAgICAqLwogICAgICAgIENvZGUuU3RhdGUgc3RhdGU7CgogICAgICAgIC8qKiBUaGUgbmV4dCBqdW1wIGluIHRoZSBsaXN0LgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBmaW5hbCBDaGFpbiBuZXh0OwoKICAgICAgICAvKiogQ29uc3RydWN0IGEgY2hhaW4gZnJvbSBpdHMganVtcCBwb3NpdGlvbiwgc3RhY2tzaXplLCBwcmV2aW91cwogICAgICAgICAqICBjaGFpbiwgYW5kIG1hY2hpbmUgc3RhdGUuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIENoYWluKGludCBwYywgQ2hhaW4gbmV4dCwgQ29kZS5TdGF0ZSBzdGF0ZSkgewogICAgICAgICAgICB0aGlzLnBjID0gcGM7CiAgICAgICAgICAgIHRoaXMubmV4dCA9IG5leHQ7CiAgICAgICAgICAgIHRoaXMuc3RhdGUgPSBzdGF0ZTsKICAgICAgICB9CiAgICB9CgogICAgLyoqIE5lZ2F0ZSBhIGJyYW5jaCBvcGNvZGUuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgaW50IG5lZ2F0ZShpbnQgb3Bjb2RlKSB7CiAgICAgICAgaWYgKG9wY29kZSA9PSBpZl9hY21wX251bGwpIHJldHVybiBpZl9hY21wX25vbm51bGw7CiAgICAgICAgZWxzZSBpZiAob3Bjb2RlID09IGlmX2FjbXBfbm9ubnVsbCkgcmV0dXJuIGlmX2FjbXBfbnVsbDsKICAgICAgICBlbHNlIHJldHVybiAoKG9wY29kZSArIDEpIF4gMSkgLSAxOwogICAgfQoKICAgIC8qKiBFbWl0IGEganVtcCBpbnN0cnVjdGlvbi4KICAgICAqICBSZXR1cm4gY29kZSBwb2ludGVyIG9mIGluc3RydWN0aW9uIHRvIGJlIHBhdGNoZWQuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZW1pdEp1bXAoaW50IG9wY29kZSkgewogICAgICAgIGlmIChmYXRjb2RlKSB7CiAgICAgICAgICAgIGlmIChvcGNvZGUgPT0gZ290b18gfHwgb3Bjb2RlID09IGpzcikgewogICAgICAgICAgICAgICAgZW1pdG9wNChvcGNvZGUgKyBnb3RvX3cgLSBnb3RvXywgMCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBlbWl0b3AyKG5lZ2F0ZShvcGNvZGUpLCA4KTsKICAgICAgICAgICAgICAgIGVtaXRvcDQoZ290b193LCAwKTsKICAgICAgICAgICAgICAgIGFsaXZlID0gdHJ1ZTsKICAgICAgICAgICAgICAgIHBlbmRpbmdTdGFja01hcCA9IG5lZWRTdGFja01hcDsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gY3AgLSA1OwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVtaXRvcDIob3Bjb2RlLCAwKTsKICAgICAgICAgICAgcmV0dXJuIGNwIC0gMzsKICAgICAgICB9CiAgICB9CgogICAgLyoqIEVtaXQgYSBicmFuY2ggd2l0aCBnaXZlbiBvcGNvZGU7IHJldHVybiBpdHMgY2hhaW4uCiAgICAgKiAgYnJhbmNoIGRpZmZlcnMgZnJvbSBqdW1wIGluIHRoYXQganNyIGlzIHRyZWF0ZWQgYXMgbm8tb3AuCiAgICAgKi8KICAgIHB1YmxpYyBDaGFpbiBicmFuY2goaW50IG9wY29kZSkgewogICAgICAgIENoYWluIHJlc3VsdCA9IG51bGw7CiAgICAgICAgaWYgKG9wY29kZSA9PSBnb3RvXykgewogICAgICAgICAgICByZXN1bHQgPSBwZW5kaW5nSnVtcHM7CiAgICAgICAgICAgIHBlbmRpbmdKdW1wcyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIGlmIChvcGNvZGUgIT0gZG9udGdvdG8gJiYgaXNBbGl2ZSgpKSB7CiAgICAgICAgICAgIHJlc3VsdCA9IG5ldyBDaGFpbihlbWl0SnVtcChvcGNvZGUpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdGUuZHVwKCkpOwogICAgICAgICAgICBmaXhlZFBjID0gZmF0Y29kZTsKICAgICAgICAgICAgaWYgKG9wY29kZSA9PSBnb3RvXykgYWxpdmUgPSBmYWxzZTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KCiAgICAvKiogUmVzb2x2ZSBjaGFpbiB0byBwb2ludCB0byBnaXZlbiB0YXJnZXQuCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHJlc29sdmUoQ2hhaW4gY2hhaW4sIGludCB0YXJnZXQpIHsKICAgICAgICBib29sZWFuIGNoYW5nZWQgPSBmYWxzZTsKICAgICAgICBTdGF0ZSBuZXdTdGF0ZSA9IHN0YXRlOwogICAgICAgIGZvciAoOyBjaGFpbiAhPSBudWxsOyBjaGFpbiA9IGNoYWluLm5leHQpIHsKICAgICAgICAgICAgQXNzZXJ0LmNoZWNrKHN0YXRlICE9IGNoYWluLnN0YXRlCiAgICAgICAgICAgICAgICAgICAgJiYgKHRhcmdldCA+IGNoYWluLnBjIHx8IHN0YXRlLnN0YWNrc2l6ZSA9PSAwKSk7CiAgICAgICAgICAgIGlmICh0YXJnZXQgPj0gY3ApIHsKICAgICAgICAgICAgICAgIHRhcmdldCA9IGNwOwogICAgICAgICAgICB9IGVsc2UgaWYgKGdldDEodGFyZ2V0KSA9PSBnb3RvXykgewogICAgICAgICAgICAgICAgaWYgKGZhdGNvZGUpIHRhcmdldCA9IHRhcmdldCArIGdldDQodGFyZ2V0ICsgMSk7CiAgICAgICAgICAgICAgICBlbHNlIHRhcmdldCA9IHRhcmdldCArIGdldDIodGFyZ2V0ICsgMSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGdldDEoY2hhaW4ucGMpID09IGdvdG9fICYmCiAgICAgICAgICAgICAgICBjaGFpbi5wYyArIDMgPT0gdGFyZ2V0ICYmIHRhcmdldCA9PSBjcCAmJiAhZml4ZWRQYykgewogICAgICAgICAgICAgICAgLy8gSWYgZ290byB0aGUgbmV4dCBpbnN0cnVjdGlvbiwgdGhlIGp1bXAgaXMgbm90IG5lZWRlZDoKICAgICAgICAgICAgICAgIC8vIGNvbXBhY3QgdGhlIGNvZGUuCiAgICAgICAgICAgICAgICBpZiAodmFyRGVidWdJbmZvKSB7CiAgICAgICAgICAgICAgICAgICAgYWRqdXN0QWxpdmVSYW5nZXMoY3AsIC0zKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGNwID0gY3AgLSAzOwogICAgICAgICAgICAgICAgdGFyZ2V0ID0gdGFyZ2V0IC0gMzsKICAgICAgICAgICAgICAgIGlmIChjaGFpbi5uZXh0ID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAvLyBUaGlzIGlzIHRoZSBvbmx5IGp1bXAgdG8gdGhlIHRhcmdldC4gRXhpdCB0aGUgbG9vcAogICAgICAgICAgICAgICAgICAgIC8vIHdpdGhvdXQgc2V0dGluZyBuZXcgc3RhdGUuIFRoZSBjb2RlIGlzIHJlYWNoYWJsZQogICAgICAgICAgICAgICAgICAgIC8vIGZyb20gdGhlIGluc3RydWN0aW9uIGJlZm9yZSBnb3RvXy4KICAgICAgICAgICAgICAgICAgICBhbGl2ZSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBpZiAoZmF0Y29kZSkKICAgICAgICAgICAgICAgICAgICBwdXQ0KGNoYWluLnBjICsgMSwgdGFyZ2V0IC0gY2hhaW4ucGMpOwogICAgICAgICAgICAgICAgZWxzZSBpZiAodGFyZ2V0IC0gY2hhaW4ucGMgPCBTaG9ydC5NSU5fVkFMVUUgfHwKICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldCAtIGNoYWluLnBjID4gU2hvcnQuTUFYX1ZBTFVFKQogICAgICAgICAgICAgICAgICAgIGZhdGNvZGUgPSB0cnVlOwogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHB1dDIoY2hhaW4ucGMgKyAxLCB0YXJnZXQgLSBjaGFpbi5wYyk7CiAgICAgICAgICAgICAgICBBc3NlcnQuY2hlY2soIWFsaXZlIHx8CiAgICAgICAgICAgICAgICAgICAgY2hhaW4uc3RhdGUuc3RhY2tzaXplID09IG5ld1N0YXRlLnN0YWNrc2l6ZSAmJgogICAgICAgICAgICAgICAgICAgIGNoYWluLnN0YXRlLm5sb2NrcyA9PSBuZXdTdGF0ZS5ubG9ja3MpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGZpeGVkUGMgPSB0cnVlOwogICAgICAgICAgICBpZiAoY3AgPT0gdGFyZ2V0KSB7CiAgICAgICAgICAgICAgICBjaGFuZ2VkID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGlmIChkZWJ1Z0NvZGUpCiAgICAgICAgICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKCJyZXNvbHZpbmcgY2hhaW4gc3RhdGU9IiArIGNoYWluLnN0YXRlKTsKICAgICAgICAgICAgICAgIGlmIChhbGl2ZSkgewogICAgICAgICAgICAgICAgICAgIG5ld1N0YXRlID0gY2hhaW4uc3RhdGUuam9pbihuZXdTdGF0ZSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIG5ld1N0YXRlID0gY2hhaW4uc3RhdGU7CiAgICAgICAgICAgICAgICAgICAgYWxpdmUgPSB0cnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIEFzc2VydC5jaGVjayghY2hhbmdlZCB8fCBzdGF0ZSAhPSBuZXdTdGF0ZSk7CiAgICAgICAgaWYgKHN0YXRlICE9IG5ld1N0YXRlKSB7CiAgICAgICAgICAgIHNldERlZmluZWQobmV3U3RhdGUuZGVmaW5lZCk7CiAgICAgICAgICAgIHN0YXRlID0gbmV3U3RhdGU7CiAgICAgICAgICAgIHBlbmRpbmdTdGFja01hcCA9IG5lZWRTdGFja01hcDsKICAgICAgICB9CiAgICB9CgogICAgLyoqIFJlc29sdmUgY2hhaW4gdG8gcG9pbnQgdG8gY3VycmVudCBjb2RlIHBvaW50ZXIuCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHJlc29sdmUoQ2hhaW4gY2hhaW4pIHsKICAgICAgICBBc3NlcnQuY2hlY2soCiAgICAgICAgICAgICFhbGl2ZSB8fAogICAgICAgICAgICBjaGFpbj09bnVsbCB8fAogICAgICAgICAgICBzdGF0ZS5zdGFja3NpemUgPT0gY2hhaW4uc3RhdGUuc3RhY2tzaXplICYmCiAgICAgICAgICAgIHN0YXRlLm5sb2NrcyA9PSBjaGFpbi5zdGF0ZS5ubG9ja3MpOwogICAgICAgIHBlbmRpbmdKdW1wcyA9IG1lcmdlQ2hhaW5zKGNoYWluLCBwZW5kaW5nSnVtcHMpOwogICAgfQoKICAgIC8qKiBSZXNvbHZlIGFueSBwZW5kaW5nIGp1bXBzLgogICAgICovCiAgICBwdWJsaWMgdm9pZCByZXNvbHZlUGVuZGluZygpIHsKICAgICAgICBDaGFpbiB4ID0gcGVuZGluZ0p1bXBzOwogICAgICAgIHBlbmRpbmdKdW1wcyA9IG51bGw7CiAgICAgICAgcmVzb2x2ZSh4LCBjcCk7CiAgICB9CgogICAgLyoqIE1lcmdlIHRoZSBqdW1wcyBpbiBvZiB0d28gY2hhaW5zIGludG8gb25lLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIENoYWluIG1lcmdlQ2hhaW5zKENoYWluIGNoYWluMSwgQ2hhaW4gY2hhaW4yKSB7CiAgICAgICAgLy8gcmVjdXJzaXZlIG1lcmdlIHNvcnQKICAgICAgICBpZiAoY2hhaW4yID09IG51bGwpIHJldHVybiBjaGFpbjE7CiAgICAgICAgaWYgKGNoYWluMSA9PSBudWxsKSByZXR1cm4gY2hhaW4yOwogICAgICAgIEFzc2VydC5jaGVjaygKICAgICAgICAgICAgY2hhaW4xLnN0YXRlLnN0YWNrc2l6ZSA9PSBjaGFpbjIuc3RhdGUuc3RhY2tzaXplICYmCiAgICAgICAgICAgIGNoYWluMS5zdGF0ZS5ubG9ja3MgPT0gY2hhaW4yLnN0YXRlLm5sb2Nrcyk7CiAgICAgICAgaWYgKGNoYWluMS5wYyA8IGNoYWluMi5wYykKICAgICAgICAgICAgcmV0dXJuIG5ldyBDaGFpbigKICAgICAgICAgICAgICAgIGNoYWluMi5wYywKICAgICAgICAgICAgICAgIG1lcmdlQ2hhaW5zKGNoYWluMSwgY2hhaW4yLm5leHQpLAogICAgICAgICAgICAgICAgY2hhaW4yLnN0YXRlKTsKICAgICAgICByZXR1cm4gbmV3IENoYWluKAogICAgICAgICAgICAgICAgY2hhaW4xLnBjLAogICAgICAgICAgICAgICAgbWVyZ2VDaGFpbnMoY2hhaW4xLm5leHQsIGNoYWluMiksCiAgICAgICAgICAgICAgICBjaGFpbjEuc3RhdGUpOwogICAgfQoKCi8qICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIENhdGNoIGNsYXVzZXMKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgogICAgLyoqIEFkZCBhIGNhdGNoIGNsYXVzZSB0byBjb2RlLgogICAgICovCiAgICBwdWJsaWMgdm9pZCBhZGRDYXRjaChjaGFyIHN0YXJ0UGMsIGNoYXIgZW5kUGMsCiAgICAgICAgICAgICAgICAgICAgICAgICBjaGFyIGhhbmRsZXJQYywgY2hhciBjYXRjaFR5cGUpIHsKICAgICAgICAgICAgY2F0Y2hJbmZvLmFwcGVuZChuZXcgY2hhcltde3N0YXJ0UGMsIGVuZFBjLCBoYW5kbGVyUGMsIGNhdGNoVHlwZX0pOwogICAgICAgIH0KCgogICAgcHVibGljIHZvaWQgY29tcHJlc3NDYXRjaFRhYmxlKCkgewogICAgICAgIExpc3RCdWZmZXI8Y2hhcltdPiBjb21wcmVzc2VkQ2F0Y2hJbmZvID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgIExpc3Q8SW50ZWdlcj4gaGFuZGxlclBjcyA9IExpc3QubmlsKCk7CiAgICAgICAgZm9yIChjaGFyW10gY2F0Y2hFbnRyeSA6IGNhdGNoSW5mbykgewogICAgICAgICAgICBoYW5kbGVyUGNzID0gaGFuZGxlclBjcy5wcmVwZW5kKChpbnQpY2F0Y2hFbnRyeVsyXSk7CiAgICAgICAgfQogICAgICAgIGZvciAoY2hhcltdIGNhdGNoRW50cnkgOiBjYXRjaEluZm8pIHsKICAgICAgICAgICAgaW50IHN0YXJ0cGMgPSBjYXRjaEVudHJ5WzBdOwogICAgICAgICAgICBpbnQgZW5kcGMgPSBjYXRjaEVudHJ5WzFdOwogICAgICAgICAgICBpZiAoc3RhcnRwYyA9PSBlbmRwYyB8fAogICAgICAgICAgICAgICAgICAgIChzdGFydHBjID09IChlbmRwYyAtIDEpICYmCiAgICAgICAgICAgICAgICAgICAgaGFuZGxlclBjcy5jb250YWlucyhzdGFydHBjKSkpIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgY29tcHJlc3NlZENhdGNoSW5mby5hcHBlbmQoY2F0Y2hFbnRyeSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgY2F0Y2hJbmZvID0gY29tcHJlc3NlZENhdGNoSW5mbzsKICAgIH0KCgovKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBMaW5lIG51bWJlcnMKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgogICAgLyoqIEFkZCBhIGxpbmUgbnVtYmVyIGVudHJ5LgogICAgICovCiAgICBwdWJsaWMgdm9pZCBhZGRMaW5lTnVtYmVyKGNoYXIgc3RhcnRQYywgY2hhciBsaW5lTnVtYmVyKSB7CiAgICAgICAgaWYgKGxpbmVEZWJ1Z0luZm8pIHsKICAgICAgICAgICAgaWYgKGxpbmVJbmZvLm5vbkVtcHR5KCkgJiYgbGluZUluZm8uaGVhZFswXSA9PSBzdGFydFBjKQogICAgICAgICAgICAgICAgbGluZUluZm8gPSBsaW5lSW5mby50YWlsOwogICAgICAgICAgICBpZiAobGluZUluZm8uaXNFbXB0eSgpIHx8IGxpbmVJbmZvLmhlYWRbMV0gIT0gbGluZU51bWJlcikKICAgICAgICAgICAgICAgIGxpbmVJbmZvID0gbGluZUluZm8ucHJlcGVuZChuZXcgY2hhcltde3N0YXJ0UGMsIGxpbmVOdW1iZXJ9KTsKICAgICAgICB9CiAgICB9CgogICAgLyoqIE1hcmsgYmVnaW5uaW5nIG9mIHN0YXRlbWVudC4KICAgICAqLwogICAgcHVibGljIHZvaWQgc3RhdEJlZ2luKGludCBwb3MpIHsKICAgICAgICBpZiAocG9zICE9IFBvc2l0aW9uLk5PUE9TKSB7CiAgICAgICAgICAgIHBlbmRpbmdTdGF0UG9zID0gcG9zOwogICAgICAgIH0KICAgIH0KCiAgICAvKiogRm9yY2Ugc3RhdCBiZWdpbiBlYWdlcmx5CiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIG1hcmtTdGF0QmVnaW4oKSB7CiAgICAgICAgaWYgKGFsaXZlICYmIGxpbmVEZWJ1Z0luZm8pIHsKICAgICAgICAgICAgaW50IGxpbmUgPSBsaW5lTWFwLmdldExpbmVOdW1iZXIocGVuZGluZ1N0YXRQb3MpOwogICAgICAgICAgICBjaGFyIGNwMSA9IChjaGFyKWNwOwogICAgICAgICAgICBjaGFyIGxpbmUxID0gKGNoYXIpbGluZTsKICAgICAgICAgICAgaWYgKGNwMSA9PSBjcCAmJiBsaW5lMSA9PSBsaW5lKQogICAgICAgICAgICAgICAgYWRkTGluZU51bWJlcihjcDEsIGxpbmUxKTsKICAgICAgICB9CiAgICAgICAgcGVuZGluZ1N0YXRQb3MgPSBQb3NpdGlvbi5OT1BPUzsKICAgIH0KCgovKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTaW11bGF0ZWQgVk0gbWFjaGluZSBzdGF0ZQogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiAgICBjbGFzcyBTdGF0ZSBpbXBsZW1lbnRzIENsb25lYWJsZSB7CiAgICAgICAgLyoqIFRoZSBzZXQgb2YgcmVnaXN0ZXJzIGNvbnRhaW5pbmcgdmFsdWVzLiAqLwogICAgICAgIEJpdHMgZGVmaW5lZDsKCiAgICAgICAgLyoqIFRoZSAodHlwZXMgb2YgdGhlKSBjb250ZW50cyBvZiB0aGUgbWFjaGluZSBzdGFjay4gKi8KICAgICAgICBUeXBlW10gc3RhY2s7CgogICAgICAgIC8qKiBUaGUgZmlyc3Qgc3RhY2sgcG9zaXRpb24gY3VycmVudGx5IHVudXNlZC4gKi8KICAgICAgICBpbnQgc3RhY2tzaXplOwoKICAgICAgICAvKiogVGhlIG51bWJlcnMgb2YgcmVnaXN0ZXJzIGNvbnRhaW5pbmcgbG9ja2VkIG1vbml0b3JzLiAqLwogICAgICAgIGludFtdIGxvY2tzOwogICAgICAgIGludCBubG9ja3M7CgogICAgICAgIFN0YXRlKCkgewogICAgICAgICAgICBkZWZpbmVkID0gbmV3IEJpdHMoKTsKICAgICAgICAgICAgc3RhY2sgPSBuZXcgVHlwZVsxNl07CiAgICAgICAgfQoKICAgICAgICBTdGF0ZSBkdXAoKSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBTdGF0ZSBzdGF0ZSA9IChTdGF0ZSlzdXBlci5jbG9uZSgpOwogICAgICAgICAgICAgICAgc3RhdGUuZGVmaW5lZCA9IG5ldyBCaXRzKGRlZmluZWQpOwogICAgICAgICAgICAgICAgc3RhdGUuc3RhY2sgPSBzdGFjay5jbG9uZSgpOwogICAgICAgICAgICAgICAgaWYgKGxvY2tzICE9IG51bGwpIHN0YXRlLmxvY2tzID0gbG9ja3MuY2xvbmUoKTsKICAgICAgICAgICAgICAgIGlmIChkZWJ1Z0NvZGUpIHsKICAgICAgICAgICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oImR1cGluZyBzdGF0ZSAiICsgdGhpcyk7CiAgICAgICAgICAgICAgICAgICAgZHVtcCgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIHN0YXRlOwogICAgICAgICAgICB9IGNhdGNoIChDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBleCkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKGV4KTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgdm9pZCBsb2NrKGludCByZWdpc3RlcikgewogICAgICAgICAgICBpZiAobG9ja3MgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgbG9ja3MgPSBuZXcgaW50WzIwXTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGxvY2tzID0gQXJyYXlVdGlscy5lbnN1cmVDYXBhY2l0eShsb2NrcywgbmxvY2tzKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBsb2Nrc1tubG9ja3NdID0gcmVnaXN0ZXI7CiAgICAgICAgICAgIG5sb2NrcysrOwogICAgICAgIH0KCiAgICAgICAgdm9pZCB1bmxvY2soaW50IHJlZ2lzdGVyKSB7CiAgICAgICAgICAgIG5sb2Nrcy0tOwogICAgICAgICAgICBBc3NlcnQuY2hlY2sobG9ja3NbbmxvY2tzXSA9PSByZWdpc3Rlcik7CiAgICAgICAgICAgIGxvY2tzW25sb2Nrc10gPSAtMTsKICAgICAgICB9CgogICAgICAgIHZvaWQgcHVzaChUeXBlIHQpIHsKICAgICAgICAgICAgaWYgKGRlYnVnQ29kZSkgU3lzdGVtLmVyci5wcmludGxuKCIgICBwdXNoaW5nICIgKyB0KTsKICAgICAgICAgICAgc3dpdGNoICh0LmdldFRhZygpKSB7CiAgICAgICAgICAgIGNhc2UgVk9JRDoKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgY2FzZSBCWVRFOgogICAgICAgICAgICBjYXNlIENIQVI6CiAgICAgICAgICAgIGNhc2UgU0hPUlQ6CiAgICAgICAgICAgIGNhc2UgQk9PTEVBTjoKICAgICAgICAgICAgICAgIHQgPSBzeW1zLmludFR5cGU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHN0YWNrID0gQXJyYXlVdGlscy5lbnN1cmVDYXBhY2l0eShzdGFjaywgc3RhY2tzaXplKzIpOwogICAgICAgICAgICBzdGFja1tzdGFja3NpemUrK10gPSB0OwogICAgICAgICAgICBzd2l0Y2ggKHdpZHRoKHQpKSB7CiAgICAgICAgICAgIGNhc2UgMToKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIDI6CiAgICAgICAgICAgICAgICBzdGFja1tzdGFja3NpemUrK10gPSBudWxsOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IodCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHN0YWNrc2l6ZSA+IG1heF9zdGFjaykKICAgICAgICAgICAgICAgIG1heF9zdGFjayA9IHN0YWNrc2l6ZTsKICAgICAgICB9CgogICAgICAgIFR5cGUgcG9wMSgpIHsKICAgICAgICAgICAgaWYgKGRlYnVnQ29kZSkgU3lzdGVtLmVyci5wcmludGxuKCIgICBwb3BwaW5nICIgKyAxKTsKICAgICAgICAgICAgc3RhY2tzaXplLS07CiAgICAgICAgICAgIFR5cGUgcmVzdWx0ID0gc3RhY2tbc3RhY2tzaXplXTsKICAgICAgICAgICAgc3RhY2tbc3RhY2tzaXplXSA9IG51bGw7CiAgICAgICAgICAgIEFzc2VydC5jaGVjayhyZXN1bHQgIT0gbnVsbCAmJiB3aWR0aChyZXN1bHQpID09IDEpOwogICAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgIH0KCiAgICAgICAgVHlwZSBwZWVrKCkgewogICAgICAgICAgICByZXR1cm4gc3RhY2tbc3RhY2tzaXplLTFdOwogICAgICAgIH0KCiAgICAgICAgVHlwZSBwb3AyKCkgewogICAgICAgICAgICBpZiAoZGVidWdDb2RlKSBTeXN0ZW0uZXJyLnByaW50bG4oIiAgIHBvcHBpbmcgIiArIDIpOwogICAgICAgICAgICBzdGFja3NpemUgLT0gMjsKICAgICAgICAgICAgVHlwZSByZXN1bHQgPSBzdGFja1tzdGFja3NpemVdOwogICAgICAgICAgICBzdGFja1tzdGFja3NpemVdID0gbnVsbDsKICAgICAgICAgICAgQXNzZXJ0LmNoZWNrKHN0YWNrW3N0YWNrc2l6ZSsxXSA9PSBudWxsCiAgICAgICAgICAgICAgICAgICAgJiYgcmVzdWx0ICE9IG51bGwgJiYgd2lkdGgocmVzdWx0KSA9PSAyKTsKICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CgogICAgICAgIHZvaWQgcG9wKGludCBuKSB7CiAgICAgICAgICAgIGlmIChkZWJ1Z0NvZGUpIFN5c3RlbS5lcnIucHJpbnRsbigiICAgcG9wcGluZyAiICsgbik7CiAgICAgICAgICAgIHdoaWxlIChuID4gMCkgewogICAgICAgICAgICAgICAgc3RhY2tbLS1zdGFja3NpemVdID0gbnVsbDsKICAgICAgICAgICAgICAgIG4tLTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgdm9pZCBwb3AoVHlwZSB0KSB7CiAgICAgICAgICAgIHBvcCh3aWR0aCh0KSk7CiAgICAgICAgfQoKICAgICAgICAvKiogRm9yY2UgdGhlIHRvcCBvZiB0aGUgc3RhY2sgdG8gYmUgdHJlYXRlZCBhcyB0aGlzIHN1cGVydHlwZQogICAgICAgICAqICBvZiBpdHMgY3VycmVudCB0eXBlLiAqLwogICAgICAgIHZvaWQgZm9yY2VTdGFja1RvcChUeXBlIHQpIHsKICAgICAgICAgICAgaWYgKCFhbGl2ZSkgcmV0dXJuOwogICAgICAgICAgICBzd2l0Y2ggKHQuZ2V0VGFnKCkpIHsKICAgICAgICAgICAgY2FzZSBDTEFTUzoKICAgICAgICAgICAgY2FzZSBBUlJBWToKICAgICAgICAgICAgICAgIGludCB3aWR0aCA9IHdpZHRoKHQpOwogICAgICAgICAgICAgICAgVHlwZSBvbGQgPSBzdGFja1tzdGFja3NpemUtd2lkdGhdOwogICAgICAgICAgICAgICAgQXNzZXJ0LmNoZWNrKHR5cGVzLmlzU3VidHlwZSh0eXBlcy5lcmFzdXJlKG9sZCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVzLmVyYXN1cmUodCkpKTsKICAgICAgICAgICAgICAgIHN0YWNrW3N0YWNrc2l6ZS13aWR0aF0gPSB0OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHZvaWQgbWFya0luaXRpYWxpemVkKFVuaW5pdGlhbGl6ZWRUeXBlIG9sZCkgewogICAgICAgICAgICBUeXBlIG5ld3R5cGUgPSBvbGQuaW5pdGlhbGl6ZWRUeXBlKCk7CiAgICAgICAgICAgIGZvciAoaW50IGk9MDsgaTxzdGFja3NpemU7IGkrKykgewogICAgICAgICAgICAgICAgaWYgKHN0YWNrW2ldID09IG9sZCkgc3RhY2tbaV0gPSBuZXd0eXBlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGZvciAoaW50IGk9MDsgaTxsdmFyLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgICAgICBMb2NhbFZhciBsdiA9IGx2YXJbaV07CiAgICAgICAgICAgICAgICBpZiAobHYgIT0gbnVsbCAmJiBsdi5zeW0udHlwZSA9PSBvbGQpIHsKICAgICAgICAgICAgICAgICAgICBWYXJTeW1ib2wgc3ltID0gbHYuc3ltOwogICAgICAgICAgICAgICAgICAgIHN5bSA9IHN5bS5jbG9uZShzeW0ub3duZXIpOwogICAgICAgICAgICAgICAgICAgIHN5bS50eXBlID0gbmV3dHlwZTsKICAgICAgICAgICAgICAgICAgICBMb2NhbFZhciBuZXdsdiA9IGx2YXJbaV0gPSBuZXcgTG9jYWxWYXIoc3ltKTsKICAgICAgICAgICAgICAgICAgICBuZXdsdi5hbGl2ZVJhbmdlcyA9IGx2LmFsaXZlUmFuZ2VzOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBTdGF0ZSBqb2luKFN0YXRlIG90aGVyKSB7CiAgICAgICAgICAgIGRlZmluZWQuYW5kU2V0KG90aGVyLmRlZmluZWQpOwogICAgICAgICAgICBBc3NlcnQuY2hlY2soc3RhY2tzaXplID09IG90aGVyLnN0YWNrc2l6ZQogICAgICAgICAgICAgICAgICAgICYmIG5sb2NrcyA9PSBvdGhlci5ubG9ja3MpOwogICAgICAgICAgICBmb3IgKGludCBpPTA7IGk8c3RhY2tzaXplOyApIHsKICAgICAgICAgICAgICAgIFR5cGUgdCA9IHN0YWNrW2ldOwogICAgICAgICAgICAgICAgVHlwZSB0b3RoZXIgPSBvdGhlci5zdGFja1tpXTsKICAgICAgICAgICAgICAgIFR5cGUgcmVzdWx0ID0KICAgICAgICAgICAgICAgICAgICB0PT10b3RoZXIgPyB0IDoKICAgICAgICAgICAgICAgICAgICB0eXBlcy5pc1N1YnR5cGUodCwgdG90aGVyKSA/IHRvdGhlciA6CiAgICAgICAgICAgICAgICAgICAgdHlwZXMuaXNTdWJ0eXBlKHRvdGhlciwgdCkgPyB0IDoKICAgICAgICAgICAgICAgICAgICBlcnJvcigpOwogICAgICAgICAgICAgICAgaW50IHcgPSB3aWR0aChyZXN1bHQpOwogICAgICAgICAgICAgICAgc3RhY2tbaV0gPSByZXN1bHQ7CiAgICAgICAgICAgICAgICBpZiAodyA9PSAyKSBBc3NlcnQuY2hlY2tOdWxsKHN0YWNrW2krMV0pOwogICAgICAgICAgICAgICAgaSArPSB3OwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgVHlwZSBlcnJvcigpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCJpbmNvbnNpc3RlbnQgc3RhY2sgdHlwZXMgYXQgam9pbiBwb2ludCIpOwogICAgICAgIH0KCiAgICAgICAgdm9pZCBkdW1wKCkgewogICAgICAgICAgICBkdW1wKC0xKTsKICAgICAgICB9CgogICAgICAgIHZvaWQgZHVtcChpbnQgcGMpIHsKICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludCgic3RhY2tNYXAgZm9yICIgKyBtZXRoLm93bmVyICsgIi4iICsgbWV0aCk7CiAgICAgICAgICAgIGlmIChwYyA9PSAtMSkKICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigpOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIiBhdCAiICsgcGMpOwogICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oIiBzdGFjayAoZnJvbSBib3R0b20pOiIpOwogICAgICAgICAgICBmb3IgKGludCBpPTA7IGk8c3RhY2tzaXplOyBpKyspCiAgICAgICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oIiAgIiArIGkgKyAiOiAiICsgc3RhY2tbaV0pOwoKICAgICAgICAgICAgaW50IGxhc3RMb2NhbCA9IDA7CiAgICAgICAgICAgIGZvciAoaW50IGk9bWF4X2xvY2Fscy0xOyBpPj0wOyBpLS0pIHsKICAgICAgICAgICAgICAgIGlmIChkZWZpbmVkLmlzTWVtYmVyKGkpKSB7CiAgICAgICAgICAgICAgICAgICAgbGFzdExvY2FsID0gaTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAobGFzdExvY2FsID49IDApCiAgICAgICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oIiBsb2NhbHM6Iik7CiAgICAgICAgICAgIGZvciAoaW50IGk9MDsgaTw9bGFzdExvY2FsOyBpKyspIHsKICAgICAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnQoIiAgIiArIGkgKyAiOiAiKTsKICAgICAgICAgICAgICAgIGlmIChkZWZpbmVkLmlzTWVtYmVyKGkpKSB7CiAgICAgICAgICAgICAgICAgICAgTG9jYWxWYXIgdmFyID0gbHZhcltpXTsKICAgICAgICAgICAgICAgICAgICBpZiAodmFyID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKCIobm9uZSkiKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHZhci5zeW0gPT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKCJVTktOT1dOISIpOwogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKCIiICsgdmFyLnN5bSArICIgb2YgdHlwZSAiICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhci5zeW0uZXJhc3VyZSh0eXBlcykpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oInVuZGVmaW5lZCIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChubG9ja3MgIT0gMCkgewogICAgICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludCgiIGxvY2tzOiIpOwogICAgICAgICAgICAgICAgZm9yIChpbnQgaT0wOyBpPG5sb2NrczsgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludCgiICIgKyBsb2Nrc1tpXSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBzdGF0aWMgZmluYWwgVHlwZSBqc3JSZXR1cm5WYWx1ZSA9IG5ldyBKQ1ByaW1pdGl2ZVR5cGUoSU5ULCBudWxsKTsKCgovKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBMb2NhbCB2YXJpYWJsZXMKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgogICAgLyoqIEEgbGl2ZSByYW5nZSBvZiBhIGxvY2FsIHZhcmlhYmxlLiAqLwogICAgc3RhdGljIGNsYXNzIExvY2FsVmFyIHsKICAgICAgICBmaW5hbCBWYXJTeW1ib2wgc3ltOwogICAgICAgIGZpbmFsIGNoYXIgcmVnOwoKICAgICAgICBjbGFzcyBSYW5nZSB7CiAgICAgICAgICAgIGNoYXIgc3RhcnRfcGMgPSBDaGFyYWN0ZXIuTUFYX1ZBTFVFOwogICAgICAgICAgICBjaGFyIGxlbmd0aCA9IENoYXJhY3Rlci5NQVhfVkFMVUU7CgogICAgICAgICAgICBSYW5nZSgpIHt9CgogICAgICAgICAgICBSYW5nZShjaGFyIHN0YXJ0KSB7CiAgICAgICAgICAgICAgICB0aGlzLnN0YXJ0X3BjID0gc3RhcnQ7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIFJhbmdlKGNoYXIgc3RhcnQsIGNoYXIgbGVuZ3RoKSB7CiAgICAgICAgICAgICAgICB0aGlzLnN0YXJ0X3BjID0gc3RhcnQ7CiAgICAgICAgICAgICAgICB0aGlzLmxlbmd0aCA9IGxlbmd0aDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgYm9vbGVhbiBjbG9zZWQoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gc3RhcnRfcGMgIT0gQ2hhcmFjdGVyLk1BWF9WQUxVRSAmJiBsZW5ndGggIT0gQ2hhcmFjdGVyLk1BWF9WQUxVRTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CiAgICAgICAgICAgICAgICBpbnQgY3VycmVudFN0YXJ0UEMgPSBzdGFydF9wYzsKICAgICAgICAgICAgICAgIGludCBjdXJyZW50TGVuZ3RoID0gbGVuZ3RoOwogICAgICAgICAgICAgICAgcmV0dXJuICJzdGFydHBjID0gIiArIGN1cnJlbnRTdGFydFBDICsgIiBsZW5ndGggIiArIGN1cnJlbnRMZW5ndGg7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGphdmEudXRpbC5MaXN0PFJhbmdlPiBhbGl2ZVJhbmdlcyA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0PD4oKTsKCiAgICAgICAgTG9jYWxWYXIoVmFyU3ltYm9sIHYpIHsKICAgICAgICAgICAgdGhpcy5zeW0gPSB2OwogICAgICAgICAgICB0aGlzLnJlZyA9IChjaGFyKXYuYWRyOwogICAgICAgIH0KICAgICAgICBwdWJsaWMgTG9jYWxWYXIgZHVwKCkgewogICAgICAgICAgICByZXR1cm4gbmV3IExvY2FsVmFyKHN5bSk7CiAgICAgICAgfQoKICAgICAgICBSYW5nZSBmaXJzdFJhbmdlKCkgewogICAgICAgICAgICByZXR1cm4gYWxpdmVSYW5nZXMuaXNFbXB0eSgpID8gbnVsbCA6IGFsaXZlUmFuZ2VzLmdldCgwKTsKICAgICAgICB9CgogICAgICAgIFJhbmdlIGxhc3RSYW5nZSgpIHsKICAgICAgICAgICAgcmV0dXJuIGFsaXZlUmFuZ2VzLmlzRW1wdHkoKSA/IG51bGwgOiBhbGl2ZVJhbmdlcy5nZXQoYWxpdmVSYW5nZXMuc2l6ZSgpIC0gMSk7CiAgICAgICAgfQoKICAgICAgICB2b2lkIHJlbW92ZUxhc3RSYW5nZSgpIHsKICAgICAgICAgICAgUmFuZ2UgbGFzdFJhbmdlID0gbGFzdFJhbmdlKCk7CiAgICAgICAgICAgIGlmIChsYXN0UmFuZ2UgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgYWxpdmVSYW5nZXMucmVtb3ZlKGxhc3RSYW5nZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CiAgICAgICAgICAgIGlmIChhbGl2ZVJhbmdlcyA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gImVtcHR5IGxvY2FsIHZhciI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKCkuYXBwZW5kKHN5bSkKICAgICAgICAgICAgICAgICAgICAuYXBwZW5kKCIgaW4gcmVnaXN0ZXIgIikuYXBwZW5kKChpbnQpcmVnKS5hcHBlbmQoIiBcbiIpOwogICAgICAgICAgICBmb3IgKFJhbmdlIHIgOiBhbGl2ZVJhbmdlcykgewogICAgICAgICAgICAgICAgc2IuYXBwZW5kKCIgc3RhcnRzIGF0IHBjPSIpLmFwcGVuZChJbnRlZ2VyLnRvU3RyaW5nKCgoaW50KXIuc3RhcnRfcGMpKSkKICAgICAgICAgICAgICAgICAgICAuYXBwZW5kKCIgbGVuZ3RoPSIpLmFwcGVuZChJbnRlZ2VyLnRvU3RyaW5nKCgoaW50KXIubGVuZ3RoKSkpCiAgICAgICAgICAgICAgICAgICAgLmFwcGVuZCgiXG4iKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gc2IudG9TdHJpbmcoKTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyB2b2lkIG9wZW5SYW5nZShjaGFyIHN0YXJ0KSB7CiAgICAgICAgICAgIGlmICghaGFzT3BlblJhbmdlKCkpIHsKICAgICAgICAgICAgICAgIGFsaXZlUmFuZ2VzLmFkZChuZXcgUmFuZ2Uoc3RhcnQpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHVibGljIHZvaWQgY2xvc2VSYW5nZShjaGFyIGxlbmd0aCkgewogICAgICAgICAgICBpZiAoaXNMYXN0UmFuZ2VJbml0aWFsaXplZCgpICYmIGxlbmd0aCA+IDApIHsKICAgICAgICAgICAgICAgIFJhbmdlIHJhbmdlID0gbGFzdFJhbmdlKCk7CiAgICAgICAgICAgICAgICBpZiAocmFuZ2UgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIGlmIChyYW5nZS5sZW5ndGggPT0gQ2hhcmFjdGVyLk1BWF9WQUxVRSkgewogICAgICAgICAgICAgICAgICAgICAgICByYW5nZS5sZW5ndGggPSBsZW5ndGg7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcmVtb3ZlTGFzdFJhbmdlKCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wZW5SYW5nZSgpIHsKICAgICAgICAgICAgaWYgKGFsaXZlUmFuZ2VzLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBsYXN0UmFuZ2UoKS5sZW5ndGggPT0gQ2hhcmFjdGVyLk1BWF9WQUxVRTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBib29sZWFuIGlzTGFzdFJhbmdlSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgICAgIGlmIChhbGl2ZVJhbmdlcy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gbGFzdFJhbmdlKCkuc3RhcnRfcGMgIT0gQ2hhcmFjdGVyLk1BWF9WQUxVRTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBSYW5nZSBnZXRXaWRlc3RSYW5nZSgpIHsKICAgICAgICAgICAgaWYgKGFsaXZlUmFuZ2VzLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBSYW5nZSgpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgUmFuZ2UgZmlyc3RSYW5nZSA9IGZpcnN0UmFuZ2UoKTsKICAgICAgICAgICAgICAgIFJhbmdlIGxhc3RSYW5nZSA9IGxhc3RSYW5nZSgpOwogICAgICAgICAgICAgICAgY2hhciBsZW5ndGggPSAoY2hhcikobGFzdFJhbmdlLmxlbmd0aCArIChsYXN0UmFuZ2Uuc3RhcnRfcGMgLSBmaXJzdFJhbmdlLnN0YXJ0X3BjKSk7CiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFJhbmdlKGZpcnN0UmFuZ2Uuc3RhcnRfcGMsIGxlbmd0aCk7CiAgICAgICAgICAgIH0KICAgICAgICAgfQoKICAgIH0KCiAgICAvKiogTG9jYWwgdmFyaWFibGVzLCBpbmRleGVkIGJ5IHJlZ2lzdGVyLiAqLwogICAgTG9jYWxWYXJbXSBsdmFyOwoKICAgIC8qKiBBZGQgYSBuZXcgbG9jYWwgdmFyaWFibGUuICovCiAgICBwcml2YXRlIHZvaWQgYWRkTG9jYWxWYXIoVmFyU3ltYm9sIHYpIHsKICAgICAgICBpbnQgYWRyID0gdi5hZHI7CiAgICAgICAgbHZhciA9IEFycmF5VXRpbHMuZW5zdXJlQ2FwYWNpdHkobHZhciwgYWRyKzEpOwogICAgICAgIEFzc2VydC5jaGVja051bGwobHZhclthZHJdKTsKICAgICAgICBpZiAocGVuZGluZ0p1bXBzICE9IG51bGwpIHsKICAgICAgICAgICAgcmVzb2x2ZVBlbmRpbmcoKTsKICAgICAgICB9CiAgICAgICAgbHZhclthZHJdID0gbmV3IExvY2FsVmFyKHYpOwogICAgICAgIHN0YXRlLmRlZmluZWQuZXhjbChhZHIpOwogICAgfQoKICAgIHZvaWQgYWRqdXN0QWxpdmVSYW5nZXMoaW50IG9sZENQLCBpbnQgZGVsdGEpIHsKICAgICAgICBmb3IgKExvY2FsVmFyIGxvY2FsVmFyOiBsdmFyKSB7CiAgICAgICAgICAgIGlmIChsb2NhbFZhciAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICBmb3IgKExvY2FsVmFyLlJhbmdlIHJhbmdlOiBsb2NhbFZhci5hbGl2ZVJhbmdlcykgewogICAgICAgICAgICAgICAgICAgIGlmIChyYW5nZS5jbG9zZWQoKSAmJiByYW5nZS5zdGFydF9wYyArIHJhbmdlLmxlbmd0aCA+PSBvbGRDUCkgewogICAgICAgICAgICAgICAgICAgICAgICByYW5nZS5sZW5ndGggKz0gZGVsdGE7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQ2FsY3VsYXRlcyB0aGUgc2l6ZSBvZiB0aGUgTG9jYWxWYXJpYWJsZVRhYmxlLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldExWVFNpemUoKSB7CiAgICAgICAgaW50IHJlc3VsdCA9IHZhckJ1ZmZlclNpemU7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB2YXJCdWZmZXJTaXplOyBpKyspIHsKICAgICAgICAgICAgTG9jYWxWYXIgdmFyID0gdmFyQnVmZmVyW2ldOwogICAgICAgICAgICByZXN1bHQgKz0gdmFyLmFsaXZlUmFuZ2VzLnNpemUoKSAtIDE7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9CgogICAgLyoqIFNldCB0aGUgY3VycmVudCB2YXJpYWJsZSBkZWZpbmVkIHN0YXRlLiAqLwogICAgcHVibGljIHZvaWQgc2V0RGVmaW5lZChCaXRzIG5ld0RlZmluZWQpIHsKICAgICAgICBpZiAoYWxpdmUgJiYgbmV3RGVmaW5lZCAhPSBzdGF0ZS5kZWZpbmVkKSB7CiAgICAgICAgICAgIEJpdHMgZGlmZiA9IG5ldyBCaXRzKHN0YXRlLmRlZmluZWQpLnhvclNldChuZXdEZWZpbmVkKTsKICAgICAgICAgICAgZm9yIChpbnQgYWRyID0gZGlmZi5uZXh0Qml0KDApOwogICAgICAgICAgICAgICAgIGFkciA+PSAwOwogICAgICAgICAgICAgICAgIGFkciA9IGRpZmYubmV4dEJpdChhZHIrMSkpIHsKICAgICAgICAgICAgICAgIGlmIChhZHIgPj0gbmV4dHJlZykKICAgICAgICAgICAgICAgICAgICBzdGF0ZS5kZWZpbmVkLmV4Y2woYWRyKTsKICAgICAgICAgICAgICAgIGVsc2UgaWYgKHN0YXRlLmRlZmluZWQuaXNNZW1iZXIoYWRyKSkKICAgICAgICAgICAgICAgICAgICBzZXRVbmRlZmluZWQoYWRyKTsKICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICBzZXREZWZpbmVkKGFkcik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqIE1hcmsgYSByZWdpc3RlciBhcyBiZWluZyAocG9zc2libHkpIGRlZmluZWQuICovCiAgICBwdWJsaWMgdm9pZCBzZXREZWZpbmVkKGludCBhZHIpIHsKICAgICAgICBMb2NhbFZhciB2ID0gbHZhclthZHJdOwogICAgICAgIGlmICh2ID09IG51bGwpIHsKICAgICAgICAgICAgc3RhdGUuZGVmaW5lZC5leGNsKGFkcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc3RhdGUuZGVmaW5lZC5pbmNsKGFkcik7CiAgICAgICAgICAgIGlmIChjcCA8IENoYXJhY3Rlci5NQVhfVkFMVUUpIHsKICAgICAgICAgICAgICAgIHYub3BlblJhbmdlKChjaGFyKWNwKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKiogTWFyayBhIHJlZ2lzdGVyIGFzIGJlaW5nIHVuZGVmaW5lZC4gKi8KICAgIHB1YmxpYyB2b2lkIHNldFVuZGVmaW5lZChpbnQgYWRyKSB7CiAgICAgICAgc3RhdGUuZGVmaW5lZC5leGNsKGFkcik7CiAgICAgICAgaWYgKGFkciA8IGx2YXIubGVuZ3RoICYmCiAgICAgICAgICAgIGx2YXJbYWRyXSAhPSBudWxsICYmCiAgICAgICAgICAgIGx2YXJbYWRyXS5pc0xhc3RSYW5nZUluaXRpYWxpemVkKCkpIHsKICAgICAgICAgICAgTG9jYWxWYXIgdiA9IGx2YXJbYWRyXTsKICAgICAgICAgICAgY2hhciBsZW5ndGggPSAoY2hhcikoY3VyQ1AoKSAtIHYubGFzdFJhbmdlKCkuc3RhcnRfcGMpOwogICAgICAgICAgICBpZiAobGVuZ3RoIDwgQ2hhcmFjdGVyLk1BWF9WQUxVRSkgewogICAgICAgICAgICAgICAgbHZhclthZHJdID0gdi5kdXAoKTsKICAgICAgICAgICAgICAgIHYuY2xvc2VSYW5nZShsZW5ndGgpOwogICAgICAgICAgICAgICAgcHV0VmFyKHYpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdi5yZW1vdmVMYXN0UmFuZ2UoKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKiogRW5kIHRoZSBzY29wZSBvZiBhIHZhcmlhYmxlLiAqLwogICAgcHJpdmF0ZSB2b2lkIGVuZFNjb3BlKGludCBhZHIpIHsKICAgICAgICBMb2NhbFZhciB2ID0gbHZhclthZHJdOwogICAgICAgIGlmICh2ICE9IG51bGwpIHsKICAgICAgICAgICAgaWYgKHYuaXNMYXN0UmFuZ2VJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICAgICAgICBjaGFyIGxlbmd0aCA9IChjaGFyKShjdXJDUCgpIC0gdi5sYXN0UmFuZ2UoKS5zdGFydF9wYyk7CiAgICAgICAgICAgICAgICBpZiAobGVuZ3RoIDwgQ2hhcmFjdGVyLk1BWF9WQUxVRSkgewogICAgICAgICAgICAgICAgICAgIHYuY2xvc2VSYW5nZShsZW5ndGgpOwogICAgICAgICAgICAgICAgICAgIHB1dFZhcih2KTsKICAgICAgICAgICAgICAgICAgICBmaWxsTG9jYWxWYXJQb3NpdGlvbih2KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICAvKiogdGhlIGNhbGwgdG8gY3VyQ1AoKSBjYW4gaW1wbGljaXRseSBhZGp1c3QgdGhlIGN1cnJlbnQgY3AsIGlmIHNvCiAgICAgICAgICAgICAqIHRoZSBhbGl2ZSByYW5nZSBvZiBsb2NhbCB2YXJpYWJsZXMgbWF5IGJlIG1vZGlmaWVkLiBUaHVzIHdlIG5lZWQKICAgICAgICAgICAgICogYWxsIG9mIHRoZW0uIEZvciB0aGlzIHJlYXNvbiBhc3NpZ25pbmcgbnVsbCB0byB0aGUgZ2l2ZW4gYWRkcmVzcwogICAgICAgICAgICAgKiBzaG91bGQgYmUgdGhlIGxhc3QgYWN0aW9uIHRvIGRvLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgbHZhclthZHJdID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgc3RhdGUuZGVmaW5lZC5leGNsKGFkcik7CiAgICB9CgogICAgcHJpdmF0ZSB2b2lkIGZpbGxMb2NhbFZhclBvc2l0aW9uKExvY2FsVmFyIGx2KSB7CiAgICAgICAgaWYgKGx2ID09IG51bGwgfHwgbHYuc3ltID09IG51bGwgfHwgIWx2LnN5bS5oYXNUeXBlQW5ub3RhdGlvbnMoKSkKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIGZvciAoQXR0cmlidXRlLlR5cGVDb21wb3VuZCB0YSA6IGx2LnN5bS5nZXRSYXdUeXBlQXR0cmlidXRlcygpKSB7CiAgICAgICAgICAgIFR5cGVBbm5vdGF0aW9uUG9zaXRpb24gcCA9IHRhLnBvc2l0aW9uOwogICAgICAgICAgICBMb2NhbFZhci5SYW5nZSB3aWRlc3RSYW5nZSA9IGx2LmdldFdpZGVzdFJhbmdlKCk7CiAgICAgICAgICAgIHAubHZhck9mZnNldCA9IG5ldyBpbnRbXSB7IChpbnQpd2lkZXN0UmFuZ2Uuc3RhcnRfcGMgfTsKICAgICAgICAgICAgcC5sdmFyTGVuZ3RoID0gbmV3IGludFtdIHsgKGludCl3aWRlc3RSYW5nZS5sZW5ndGggfTsKICAgICAgICAgICAgcC5sdmFySW5kZXggPSBuZXcgaW50W10geyAoaW50KWx2LnJlZyB9OwogICAgICAgICAgICBwLmlzVmFsaWRPZmZzZXQgPSB0cnVlOwogICAgICAgIH0KICAgIH0KCiAgICAvLyBNZXRob2QgdG8gYmUgY2FsbGVkIGFmdGVyIGNvbXByZXNzQ2F0Y2hUYWJsZSB0bwogICAgLy8gZmlsbCBpbiB0aGUgZXhjZXB0aW9uIHRhYmxlIGluZGV4IGZvciB0eXBlCiAgICAvLyBhbm5vdGF0aW9ucyBvbiBleGNlcHRpb24gcGFyYW1ldGVycy4KICAgIHB1YmxpYyB2b2lkIGZpbGxFeGNlcHRpb25QYXJhbWV0ZXJQb3NpdGlvbnMoKSB7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB2YXJCdWZmZXJTaXplOyArK2kpIHsKICAgICAgICAgICAgTG9jYWxWYXIgbHYgPSB2YXJCdWZmZXJbaV07CiAgICAgICAgICAgIGlmIChsdiA9PSBudWxsIHx8IGx2LnN5bSA9PSBudWxsCiAgICAgICAgICAgICAgICAgICAgfHwgIWx2LnN5bS5oYXNUeXBlQW5ub3RhdGlvbnMoKQogICAgICAgICAgICAgICAgICAgIHx8ICFsdi5zeW0uaXNFeGNlcHRpb25QYXJhbWV0ZXIoKSkKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwoKICAgICAgICAgICAgZm9yIChBdHRyaWJ1dGUuVHlwZUNvbXBvdW5kIHRhIDogbHYuc3ltLmdldFJhd1R5cGVBdHRyaWJ1dGVzKCkpIHsKICAgICAgICAgICAgICAgIFR5cGVBbm5vdGF0aW9uUG9zaXRpb24gcCA9IHRhLnBvc2l0aW9uOwogICAgICAgICAgICAgICAgaWYgKHAuaGFzQ2F0Y2hUeXBlKCkpIHsKICAgICAgICAgICAgICAgICAgICBmaW5hbCBpbnQgaWR4ID0gZmluZEV4Y2VwdGlvbkluZGV4KHApOwogICAgICAgICAgICAgICAgICAgIGlmIChpZHggPT0gLTEpCiAgICAgICAgICAgICAgICAgICAgICAgIEFzc2VydC5lcnJvcigiQ291bGQgbm90IGZpbmQgZXhjZXB0aW9uIGluZGV4IGZvciB0eXBlIGFubm90YXRpb24gIiArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YSArICIgb24gZXhjZXB0aW9uIHBhcmFtZXRlciIpOwogICAgICAgICAgICAgICAgICAgIHAuc2V0RXhjZXB0aW9uSW5kZXgoaWR4KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIGludCBmaW5kRXhjZXB0aW9uSW5kZXgoVHlwZUFubm90YXRpb25Qb3NpdGlvbiBwKSB7CiAgICAgICAgZmluYWwgaW50IGNhdGNoVHlwZSA9IHAuZ2V0Q2F0Y2hUeXBlKCk7CiAgICAgICAgZmluYWwgaW50IHN0YXJ0UG9zID0gcC5nZXRTdGFydFBvcygpOwogICAgICAgIGZpbmFsIGludCBsZW4gPSBjYXRjaEluZm8ubGVuZ3RoKCk7CiAgICAgICAgTGlzdDxjaGFyW10+IGl0ZXIgPSBjYXRjaEluZm8udG9MaXN0KCk7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW47ICsraSkgewogICAgICAgICAgICBjaGFyW10gY2F0Y2hFbnRyeSA9IGl0ZXIuaGVhZDsKICAgICAgICAgICAgaXRlciA9IGl0ZXIudGFpbDsKICAgICAgICAgICAgaW50IGN0ID0gY2F0Y2hFbnRyeVszXTsKICAgICAgICAgICAgaW50IHNwID0gY2F0Y2hFbnRyeVswXTsKICAgICAgICAgICAgaWYgKGNhdGNoVHlwZSA9PSBjdCAmJiBzcCA9PSBzdGFydFBvcykgewogICAgICAgICAgICAgICAgcmV0dXJuIGk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIC0xOwogICAgfQoKICAgIC8qKiBQdXQgYSBsaXZlIHZhcmlhYmxlIHJhbmdlIGludG8gdGhlIGJ1ZmZlciB0byBiZSBvdXRwdXQgdG8gdGhlCiAgICAgKiAgY2xhc3MgZmlsZS4KICAgICAqLwogICAgdm9pZCBwdXRWYXIoTG9jYWxWYXIgdmFyKSB7CiAgICAgICAgLy8gS2VlcCBsb2NhbCB2YXJpYWJsZXMgaWYKICAgICAgICAvLyAxKSB3ZSBuZWVkIHRoZW0gZm9yIGRlYnVnIGluZm9ybWF0aW9uCiAgICAgICAgLy8gMikgaXQgaXMgYW4gZXhjZXB0aW9uIHR5cGUgYW5kIGl0IGNvbnRhaW5zIHR5cGUgYW5ub3RhdGlvbnMKICAgICAgICBib29sZWFuIGtlZXBMb2NhbFZhcmlhYmxlcyA9IHZhckRlYnVnSW5mbyB8fAogICAgICAgICAgICAodmFyLnN5bS5pc0V4Y2VwdGlvblBhcmFtZXRlcigpICYmIHZhci5zeW0uaGFzVHlwZUFubm90YXRpb25zKCkpOwogICAgICAgIGlmICgha2VlcExvY2FsVmFyaWFibGVzKSByZXR1cm47CiAgICAgICAgLy9kb24ndCBrZWVwIHN5bnRoZXRpYyB2YXJzLCB1bmxlc3MgdGhleSBhcmUgbGFtYmRhIG1ldGhvZCBwYXJhbWV0ZXJzCiAgICAgICAgYm9vbGVhbiBpZ25vcmVkU3ludGhldGljVmFyID0gKHZhci5zeW0uZmxhZ3MoKSAmIEZsYWdzLlNZTlRIRVRJQykgIT0gMCAmJgogICAgICAgICAgICAgICAgKCh2YXIuc3ltLm93bmVyLmZsYWdzKCkgJiBGbGFncy5MQU1CREFfTUVUSE9EKSA9PSAwIHx8CiAgICAgICAgICAgICAgICAgKHZhci5zeW0uZmxhZ3MoKSAmIEZsYWdzLlBBUkFNRVRFUikgPT0gMCk7CiAgICAgICAgaWYgKGlnbm9yZWRTeW50aGV0aWNWYXIpIHJldHVybjsKICAgICAgICBpZiAodmFyQnVmZmVyID09IG51bGwpCiAgICAgICAgICAgIHZhckJ1ZmZlciA9IG5ldyBMb2NhbFZhclsyMF07CiAgICAgICAgZWxzZQogICAgICAgICAgICB2YXJCdWZmZXIgPSBBcnJheVV0aWxzLmVuc3VyZUNhcGFjaXR5KHZhckJ1ZmZlciwgdmFyQnVmZmVyU2l6ZSk7CiAgICAgICAgdmFyQnVmZmVyW3ZhckJ1ZmZlclNpemUrK10gPSB2YXI7CiAgICB9CgogICAgLyoqIFByZXZpb3VzbHkgbGl2ZSBsb2NhbCB2YXJpYWJsZXMsIHRvIGJlIHB1dCBpbnRvIHRoZSB2YXJpYWJsZSB0YWJsZS4gKi8KICAgIExvY2FsVmFyW10gdmFyQnVmZmVyOwogICAgaW50IHZhckJ1ZmZlclNpemU7CgogICAgLyoqIENyZWF0ZSBhIG5ldyBsb2NhbCB2YXJpYWJsZSBhZGRyZXNzIGFuZCByZXR1cm4gaXQuCiAgICAgKi8KICAgIHByaXZhdGUgaW50IG5ld0xvY2FsKGludCB0eXBlY29kZSkgewogICAgICAgIGludCByZWcgPSBuZXh0cmVnOwogICAgICAgIGludCB3ID0gd2lkdGgodHlwZWNvZGUpOwogICAgICAgIG5leHRyZWcgPSByZWcgKyB3OwogICAgICAgIGlmIChuZXh0cmVnID4gbWF4X2xvY2FscykgbWF4X2xvY2FscyA9IG5leHRyZWc7CiAgICAgICAgcmV0dXJuIHJlZzsKICAgIH0KCiAgICBwcml2YXRlIGludCBuZXdMb2NhbChUeXBlIHR5cGUpIHsKICAgICAgICByZXR1cm4gbmV3TG9jYWwodHlwZWNvZGUodHlwZSkpOwogICAgfQoKICAgIHB1YmxpYyBpbnQgbmV3TG9jYWwoVmFyU3ltYm9sIHYpIHsKICAgICAgICBpbnQgcmVnID0gdi5hZHIgPSBuZXdMb2NhbCh2LmVyYXN1cmUodHlwZXMpKTsKICAgICAgICBhZGRMb2NhbFZhcih2KTsKICAgICAgICByZXR1cm4gcmVnOwogICAgfQoKICAgIC8qKiBTdGFydCBhIHNldCBvZiBmcmVzaCByZWdpc3RlcnMuCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIG5ld1JlZ1NlZ21lbnQoKSB7CiAgICAgICAgbmV4dHJlZyA9IG1heF9sb2NhbHM7CiAgICB9CgogICAgLyoqIEVuZCBzY29wZXMgb2YgYWxsIHZhcmlhYmxlcyB3aXRoIHJlZ2lzdGVycyAmZ2U7IGZpcnN0LgogICAgICovCiAgICBwdWJsaWMgdm9pZCBlbmRTY29wZXMoaW50IGZpcnN0KSB7CiAgICAgICAgaW50IHByZXZOZXh0UmVnID0gbmV4dHJlZzsKICAgICAgICBuZXh0cmVnID0gZmlyc3Q7CiAgICAgICAgZm9yIChpbnQgaSA9IG5leHRyZWc7IGkgPCBwcmV2TmV4dFJlZzsgaSsrKSBlbmRTY29wZShpKTsKICAgIH0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBzdGF0aWMgdGFibGVzCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIG1uZW0oaW50IG9wY29kZSkgewogICAgICAgIHJldHVybiBNbmV1bW9uaWNzLm1uZW1bb3Bjb2RlXTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBNbmV1bW9uaWNzIHsKICAgICAgICBwcml2YXRlIGZpbmFsIHN0YXRpYyBTdHJpbmdbXSBtbmVtID0gbmV3IFN0cmluZ1tCeXRlQ29kZUNvdW50XTsKICAgICAgICBzdGF0aWMgewogICAgICAgICAgICBtbmVtW25vcF0gPSAibm9wIjsKICAgICAgICAgICAgbW5lbVthY29uc3RfbnVsbF0gPSAiYWNvbnN0X251bGwiOwogICAgICAgICAgICBtbmVtW2ljb25zdF9tMV0gPSAiaWNvbnN0X20xIjsKICAgICAgICAgICAgbW5lbVtpY29uc3RfMF0gPSAiaWNvbnN0XzAiOwogICAgICAgICAgICBtbmVtW2ljb25zdF8xXSA9ICJpY29uc3RfMSI7CiAgICAgICAgICAgIG1uZW1baWNvbnN0XzJdID0gImljb25zdF8yIjsKICAgICAgICAgICAgbW5lbVtpY29uc3RfM10gPSAiaWNvbnN0XzMiOwogICAgICAgICAgICBtbmVtW2ljb25zdF80XSA9ICJpY29uc3RfNCI7CiAgICAgICAgICAgIG1uZW1baWNvbnN0XzVdID0gImljb25zdF81IjsKICAgICAgICAgICAgbW5lbVtsY29uc3RfMF0gPSAibGNvbnN0XzAiOwogICAgICAgICAgICBtbmVtW2xjb25zdF8xXSA9ICJsY29uc3RfMSI7CiAgICAgICAgICAgIG1uZW1bZmNvbnN0XzBdID0gImZjb25zdF8wIjsKICAgICAgICAgICAgbW5lbVtmY29uc3RfMV0gPSAiZmNvbnN0XzEiOwogICAgICAgICAgICBtbmVtW2Zjb25zdF8yXSA9ICJmY29uc3RfMiI7CiAgICAgICAgICAgIG1uZW1bZGNvbnN0XzBdID0gImRjb25zdF8wIjsKICAgICAgICAgICAgbW5lbVtkY29uc3RfMV0gPSAiZGNvbnN0XzEiOwogICAgICAgICAgICBtbmVtW2JpcHVzaF0gPSAiYmlwdXNoIjsKICAgICAgICAgICAgbW5lbVtzaXB1c2hdID0gInNpcHVzaCI7CiAgICAgICAgICAgIG1uZW1bbGRjMV0gPSAibGRjMSI7CiAgICAgICAgICAgIG1uZW1bbGRjMl0gPSAibGRjMiI7CiAgICAgICAgICAgIG1uZW1bbGRjMnddID0gImxkYzJ3IjsKICAgICAgICAgICAgbW5lbVtpbG9hZF0gPSAiaWxvYWQiOwogICAgICAgICAgICBtbmVtW2xsb2FkXSA9ICJsbG9hZCI7CiAgICAgICAgICAgIG1uZW1bZmxvYWRdID0gImZsb2FkIjsKICAgICAgICAgICAgbW5lbVtkbG9hZF0gPSAiZGxvYWQiOwogICAgICAgICAgICBtbmVtW2Fsb2FkXSA9ICJhbG9hZCI7CiAgICAgICAgICAgIG1uZW1baWxvYWRfMF0gPSAiaWxvYWRfMCI7CiAgICAgICAgICAgIG1uZW1bbGxvYWRfMF0gPSAibGxvYWRfMCI7CiAgICAgICAgICAgIG1uZW1bZmxvYWRfMF0gPSAiZmxvYWRfMCI7CiAgICAgICAgICAgIG1uZW1bZGxvYWRfMF0gPSAiZGxvYWRfMCI7CiAgICAgICAgICAgIG1uZW1bYWxvYWRfMF0gPSAiYWxvYWRfMCI7CiAgICAgICAgICAgIG1uZW1baWxvYWRfMV0gPSAiaWxvYWRfMSI7CiAgICAgICAgICAgIG1uZW1bbGxvYWRfMV0gPSAibGxvYWRfMSI7CiAgICAgICAgICAgIG1uZW1bZmxvYWRfMV0gPSAiZmxvYWRfMSI7CiAgICAgICAgICAgIG1uZW1bZGxvYWRfMV0gPSAiZGxvYWRfMSI7CiAgICAgICAgICAgIG1uZW1bYWxvYWRfMV0gPSAiYWxvYWRfMSI7CiAgICAgICAgICAgIG1uZW1baWxvYWRfMl0gPSAiaWxvYWRfMiI7CiAgICAgICAgICAgIG1uZW1bbGxvYWRfMl0gPSAibGxvYWRfMiI7CiAgICAgICAgICAgIG1uZW1bZmxvYWRfMl0gPSAiZmxvYWRfMiI7CiAgICAgICAgICAgIG1uZW1bZGxvYWRfMl0gPSAiZGxvYWRfMiI7CiAgICAgICAgICAgIG1uZW1bYWxvYWRfMl0gPSAiYWxvYWRfMiI7CiAgICAgICAgICAgIG1uZW1baWxvYWRfM10gPSAiaWxvYWRfMyI7CiAgICAgICAgICAgIG1uZW1bbGxvYWRfM10gPSAibGxvYWRfMyI7CiAgICAgICAgICAgIG1uZW1bZmxvYWRfM10gPSAiZmxvYWRfMyI7CiAgICAgICAgICAgIG1uZW1bZGxvYWRfM10gPSAiZGxvYWRfMyI7CiAgICAgICAgICAgIG1uZW1bYWxvYWRfM10gPSAiYWxvYWRfMyI7CiAgICAgICAgICAgIG1uZW1baWFsb2FkXSA9ICJpYWxvYWQiOwogICAgICAgICAgICBtbmVtW2xhbG9hZF0gPSAibGFsb2FkIjsKICAgICAgICAgICAgbW5lbVtmYWxvYWRdID0gImZhbG9hZCI7CiAgICAgICAgICAgIG1uZW1bZGFsb2FkXSA9ICJkYWxvYWQiOwogICAgICAgICAgICBtbmVtW2FhbG9hZF0gPSAiYWFsb2FkIjsKICAgICAgICAgICAgbW5lbVtiYWxvYWRdID0gImJhbG9hZCI7CiAgICAgICAgICAgIG1uZW1bY2Fsb2FkXSA9ICJjYWxvYWQiOwogICAgICAgICAgICBtbmVtW3NhbG9hZF0gPSAic2Fsb2FkIjsKICAgICAgICAgICAgbW5lbVtpc3RvcmVdID0gImlzdG9yZSI7CiAgICAgICAgICAgIG1uZW1bbHN0b3JlXSA9ICJsc3RvcmUiOwogICAgICAgICAgICBtbmVtW2ZzdG9yZV0gPSAiZnN0b3JlIjsKICAgICAgICAgICAgbW5lbVtkc3RvcmVdID0gImRzdG9yZSI7CiAgICAgICAgICAgIG1uZW1bYXN0b3JlXSA9ICJhc3RvcmUiOwogICAgICAgICAgICBtbmVtW2lzdG9yZV8wXSA9ICJpc3RvcmVfMCI7CiAgICAgICAgICAgIG1uZW1bbHN0b3JlXzBdID0gImxzdG9yZV8wIjsKICAgICAgICAgICAgbW5lbVtmc3RvcmVfMF0gPSAiZnN0b3JlXzAiOwogICAgICAgICAgICBtbmVtW2RzdG9yZV8wXSA9ICJkc3RvcmVfMCI7CiAgICAgICAgICAgIG1uZW1bYXN0b3JlXzBdID0gImFzdG9yZV8wIjsKICAgICAgICAgICAgbW5lbVtpc3RvcmVfMV0gPSAiaXN0b3JlXzEiOwogICAgICAgICAgICBtbmVtW2xzdG9yZV8xXSA9ICJsc3RvcmVfMSI7CiAgICAgICAgICAgIG1uZW1bZnN0b3JlXzFdID0gImZzdG9yZV8xIjsKICAgICAgICAgICAgbW5lbVtkc3RvcmVfMV0gPSAiZHN0b3JlXzEiOwogICAgICAgICAgICBtbmVtW2FzdG9yZV8xXSA9ICJhc3RvcmVfMSI7CiAgICAgICAgICAgIG1uZW1baXN0b3JlXzJdID0gImlzdG9yZV8yIjsKICAgICAgICAgICAgbW5lbVtsc3RvcmVfMl0gPSAibHN0b3JlXzIiOwogICAgICAgICAgICBtbmVtW2ZzdG9yZV8yXSA9ICJmc3RvcmVfMiI7CiAgICAgICAgICAgIG1uZW1bZHN0b3JlXzJdID0gImRzdG9yZV8yIjsKICAgICAgICAgICAgbW5lbVthc3RvcmVfMl0gPSAiYXN0b3JlXzIiOwogICAgICAgICAgICBtbmVtW2lzdG9yZV8zXSA9ICJpc3RvcmVfMyI7CiAgICAgICAgICAgIG1uZW1bbHN0b3JlXzNdID0gImxzdG9yZV8zIjsKICAgICAgICAgICAgbW5lbVtmc3RvcmVfM10gPSAiZnN0b3JlXzMiOwogICAgICAgICAgICBtbmVtW2RzdG9yZV8zXSA9ICJkc3RvcmVfMyI7CiAgICAgICAgICAgIG1uZW1bYXN0b3JlXzNdID0gImFzdG9yZV8zIjsKICAgICAgICAgICAgbW5lbVtpYXN0b3JlXSA9ICJpYXN0b3JlIjsKICAgICAgICAgICAgbW5lbVtsYXN0b3JlXSA9ICJsYXN0b3JlIjsKICAgICAgICAgICAgbW5lbVtmYXN0b3JlXSA9ICJmYXN0b3JlIjsKICAgICAgICAgICAgbW5lbVtkYXN0b3JlXSA9ICJkYXN0b3JlIjsKICAgICAgICAgICAgbW5lbVthYXN0b3JlXSA9ICJhYXN0b3JlIjsKICAgICAgICAgICAgbW5lbVtiYXN0b3JlXSA9ICJiYXN0b3JlIjsKICAgICAgICAgICAgbW5lbVtjYXN0b3JlXSA9ICJjYXN0b3JlIjsKICAgICAgICAgICAgbW5lbVtzYXN0b3JlXSA9ICJzYXN0b3JlIjsKICAgICAgICAgICAgbW5lbVtwb3BdID0gInBvcCI7CiAgICAgICAgICAgIG1uZW1bcG9wMl0gPSAicG9wMiI7CiAgICAgICAgICAgIG1uZW1bZHVwXSA9ICJkdXAiOwogICAgICAgICAgICBtbmVtW2R1cF94MV0gPSAiZHVwX3gxIjsKICAgICAgICAgICAgbW5lbVtkdXBfeDJdID0gImR1cF94MiI7CiAgICAgICAgICAgIG1uZW1bZHVwMl0gPSAiZHVwMiI7CiAgICAgICAgICAgIG1uZW1bZHVwMl94MV0gPSAiZHVwMl94MSI7CiAgICAgICAgICAgIG1uZW1bZHVwMl94Ml0gPSAiZHVwMl94MiI7CiAgICAgICAgICAgIG1uZW1bc3dhcF0gPSAic3dhcCI7CiAgICAgICAgICAgIG1uZW1baWFkZF0gPSAiaWFkZCI7CiAgICAgICAgICAgIG1uZW1bbGFkZF0gPSAibGFkZCI7CiAgICAgICAgICAgIG1uZW1bZmFkZF0gPSAiZmFkZCI7CiAgICAgICAgICAgIG1uZW1bZGFkZF0gPSAiZGFkZCI7CiAgICAgICAgICAgIG1uZW1baXN1Yl0gPSAiaXN1YiI7CiAgICAgICAgICAgIG1uZW1bbHN1Yl0gPSAibHN1YiI7CiAgICAgICAgICAgIG1uZW1bZnN1Yl0gPSAiZnN1YiI7CiAgICAgICAgICAgIG1uZW1bZHN1Yl0gPSAiZHN1YiI7CiAgICAgICAgICAgIG1uZW1baW11bF0gPSAiaW11bCI7CiAgICAgICAgICAgIG1uZW1bbG11bF0gPSAibG11bCI7CiAgICAgICAgICAgIG1uZW1bZm11bF0gPSAiZm11bCI7CiAgICAgICAgICAgIG1uZW1bZG11bF0gPSAiZG11bCI7CiAgICAgICAgICAgIG1uZW1baWRpdl0gPSAiaWRpdiI7CiAgICAgICAgICAgIG1uZW1bbGRpdl0gPSAibGRpdiI7CiAgICAgICAgICAgIG1uZW1bZmRpdl0gPSAiZmRpdiI7CiAgICAgICAgICAgIG1uZW1bZGRpdl0gPSAiZGRpdiI7CiAgICAgICAgICAgIG1uZW1baW1vZF0gPSAiaW1vZCI7CiAgICAgICAgICAgIG1uZW1bbG1vZF0gPSAibG1vZCI7CiAgICAgICAgICAgIG1uZW1bZm1vZF0gPSAiZm1vZCI7CiAgICAgICAgICAgIG1uZW1bZG1vZF0gPSAiZG1vZCI7CiAgICAgICAgICAgIG1uZW1baW5lZ10gPSAiaW5lZyI7CiAgICAgICAgICAgIG1uZW1bbG5lZ10gPSAibG5lZyI7CiAgICAgICAgICAgIG1uZW1bZm5lZ10gPSAiZm5lZyI7CiAgICAgICAgICAgIG1uZW1bZG5lZ10gPSAiZG5lZyI7CiAgICAgICAgICAgIG1uZW1baXNobF0gPSAiaXNobCI7CiAgICAgICAgICAgIG1uZW1bbHNobF0gPSAibHNobCI7CiAgICAgICAgICAgIG1uZW1baXNocl0gPSAiaXNociI7CiAgICAgICAgICAgIG1uZW1bbHNocl0gPSAibHNociI7CiAgICAgICAgICAgIG1uZW1baXVzaHJdID0gIml1c2hyIjsKICAgICAgICAgICAgbW5lbVtsdXNocl0gPSAibHVzaHIiOwogICAgICAgICAgICBtbmVtW2lhbmRdID0gImlhbmQiOwogICAgICAgICAgICBtbmVtW2xhbmRdID0gImxhbmQiOwogICAgICAgICAgICBtbmVtW2lvcl0gPSAiaW9yIjsKICAgICAgICAgICAgbW5lbVtsb3JdID0gImxvciI7CiAgICAgICAgICAgIG1uZW1baXhvcl0gPSAiaXhvciI7CiAgICAgICAgICAgIG1uZW1bbHhvcl0gPSAibHhvciI7CiAgICAgICAgICAgIG1uZW1baWluY10gPSAiaWluYyI7CiAgICAgICAgICAgIG1uZW1baTJsXSA9ICJpMmwiOwogICAgICAgICAgICBtbmVtW2kyZl0gPSAiaTJmIjsKICAgICAgICAgICAgbW5lbVtpMmRdID0gImkyZCI7CiAgICAgICAgICAgIG1uZW1bbDJpXSA9ICJsMmkiOwogICAgICAgICAgICBtbmVtW2wyZl0gPSAibDJmIjsKICAgICAgICAgICAgbW5lbVtsMmRdID0gImwyZCI7CiAgICAgICAgICAgIG1uZW1bZjJpXSA9ICJmMmkiOwogICAgICAgICAgICBtbmVtW2YybF0gPSAiZjJsIjsKICAgICAgICAgICAgbW5lbVtmMmRdID0gImYyZCI7CiAgICAgICAgICAgIG1uZW1bZDJpXSA9ICJkMmkiOwogICAgICAgICAgICBtbmVtW2QybF0gPSAiZDJsIjsKICAgICAgICAgICAgbW5lbVtkMmZdID0gImQyZiI7CiAgICAgICAgICAgIG1uZW1baW50MmJ5dGVdID0gImludDJieXRlIjsKICAgICAgICAgICAgbW5lbVtpbnQyY2hhcl0gPSAiaW50MmNoYXIiOwogICAgICAgICAgICBtbmVtW2ludDJzaG9ydF0gPSAiaW50MnNob3J0IjsKICAgICAgICAgICAgbW5lbVtsY21wXSA9ICJsY21wIjsKICAgICAgICAgICAgbW5lbVtmY21wbF0gPSAiZmNtcGwiOwogICAgICAgICAgICBtbmVtW2ZjbXBnXSA9ICJmY21wZyI7CiAgICAgICAgICAgIG1uZW1bZGNtcGxdID0gImRjbXBsIjsKICAgICAgICAgICAgbW5lbVtkY21wZ10gPSAiZGNtcGciOwogICAgICAgICAgICBtbmVtW2lmZXFdID0gImlmZXEiOwogICAgICAgICAgICBtbmVtW2lmbmVdID0gImlmbmUiOwogICAgICAgICAgICBtbmVtW2lmbHRdID0gImlmbHQiOwogICAgICAgICAgICBtbmVtW2lmZ2VdID0gImlmZ2UiOwogICAgICAgICAgICBtbmVtW2lmZ3RdID0gImlmZ3QiOwogICAgICAgICAgICBtbmVtW2lmbGVdID0gImlmbGUiOwogICAgICAgICAgICBtbmVtW2lmX2ljbXBlcV0gPSAiaWZfaWNtcGVxIjsKICAgICAgICAgICAgbW5lbVtpZl9pY21wbmVdID0gImlmX2ljbXBuZSI7CiAgICAgICAgICAgIG1uZW1baWZfaWNtcGx0XSA9ICJpZl9pY21wbHQiOwogICAgICAgICAgICBtbmVtW2lmX2ljbXBnZV0gPSAiaWZfaWNtcGdlIjsKICAgICAgICAgICAgbW5lbVtpZl9pY21wZ3RdID0gImlmX2ljbXBndCI7CiAgICAgICAgICAgIG1uZW1baWZfaWNtcGxlXSA9ICJpZl9pY21wbGUiOwogICAgICAgICAgICBtbmVtW2lmX2FjbXBlcV0gPSAiaWZfYWNtcGVxIjsKICAgICAgICAgICAgbW5lbVtpZl9hY21wbmVdID0gImlmX2FjbXBuZSI7CiAgICAgICAgICAgIG1uZW1bZ290b19dID0gImdvdG9fIjsKICAgICAgICAgICAgbW5lbVtqc3JdID0gImpzciI7CiAgICAgICAgICAgIG1uZW1bcmV0XSA9ICJyZXQiOwogICAgICAgICAgICBtbmVtW3RhYmxlc3dpdGNoXSA9ICJ0YWJsZXN3aXRjaCI7CiAgICAgICAgICAgIG1uZW1bbG9va3Vwc3dpdGNoXSA9ICJsb29rdXBzd2l0Y2giOwogICAgICAgICAgICBtbmVtW2lyZXR1cm5dID0gImlyZXR1cm4iOwogICAgICAgICAgICBtbmVtW2xyZXR1cm5dID0gImxyZXR1cm4iOwogICAgICAgICAgICBtbmVtW2ZyZXR1cm5dID0gImZyZXR1cm4iOwogICAgICAgICAgICBtbmVtW2RyZXR1cm5dID0gImRyZXR1cm4iOwogICAgICAgICAgICBtbmVtW2FyZXR1cm5dID0gImFyZXR1cm4iOwogICAgICAgICAgICBtbmVtW3JldHVybl9dID0gInJldHVybl8iOwogICAgICAgICAgICBtbmVtW2dldHN0YXRpY10gPSAiZ2V0c3RhdGljIjsKICAgICAgICAgICAgbW5lbVtwdXRzdGF0aWNdID0gInB1dHN0YXRpYyI7CiAgICAgICAgICAgIG1uZW1bZ2V0ZmllbGRdID0gImdldGZpZWxkIjsKICAgICAgICAgICAgbW5lbVtwdXRmaWVsZF0gPSAicHV0ZmllbGQiOwogICAgICAgICAgICBtbmVtW2ludm9rZXZpcnR1YWxdID0gImludm9rZXZpcnR1YWwiOwogICAgICAgICAgICBtbmVtW2ludm9rZXNwZWNpYWxdID0gImludm9rZXNwZWNpYWwiOwogICAgICAgICAgICBtbmVtW2ludm9rZXN0YXRpY10gPSAiaW52b2tlc3RhdGljIjsKICAgICAgICAgICAgbW5lbVtpbnZva2VpbnRlcmZhY2VdID0gImludm9rZWludGVyZmFjZSI7CiAgICAgICAgICAgIG1uZW1baW52b2tlZHluYW1pY10gPSAiaW52b2tlZHluYW1pYyI7CiAgICAgICAgICAgIG1uZW1bbmV3X10gPSAibmV3XyI7CiAgICAgICAgICAgIG1uZW1bbmV3YXJyYXldID0gIm5ld2FycmF5IjsKICAgICAgICAgICAgbW5lbVthbmV3YXJyYXldID0gImFuZXdhcnJheSI7CiAgICAgICAgICAgIG1uZW1bYXJyYXlsZW5ndGhdID0gImFycmF5bGVuZ3RoIjsKICAgICAgICAgICAgbW5lbVthdGhyb3ddID0gImF0aHJvdyI7CiAgICAgICAgICAgIG1uZW1bY2hlY2tjYXN0XSA9ICJjaGVja2Nhc3QiOwogICAgICAgICAgICBtbmVtW2luc3RhbmNlb2ZfXSA9ICJpbnN0YW5jZW9mXyI7CiAgICAgICAgICAgIG1uZW1bbW9uaXRvcmVudGVyXSA9ICJtb25pdG9yZW50ZXIiOwogICAgICAgICAgICBtbmVtW21vbml0b3JleGl0XSA9ICJtb25pdG9yZXhpdCI7CiAgICAgICAgICAgIG1uZW1bd2lkZV0gPSAid2lkZSI7CiAgICAgICAgICAgIG1uZW1bbXVsdGlhbmV3YXJyYXldID0gIm11bHRpYW5ld2FycmF5IjsKICAgICAgICAgICAgbW5lbVtpZl9hY21wX251bGxdID0gImlmX2FjbXBfbnVsbCI7CiAgICAgICAgICAgIG1uZW1baWZfYWNtcF9ub25udWxsXSA9ICJpZl9hY21wX25vbm51bGwiOwogICAgICAgICAgICBtbmVtW2dvdG9fd10gPSAiZ290b193IjsKICAgICAgICAgICAgbW5lbVtqc3Jfd10gPSAianNyX3ciOwogICAgICAgICAgICBtbmVtW2JyZWFrcG9pbnRdID0gImJyZWFrcG9pbnQiOwogICAgICAgIH0KICAgIH0KfQpQSwMECgAACAAABjupStRELOmrIQAAqyEAAC0AAABjb20vc3VuL3Rvb2xzL2phdmFjL2p2bS9Nb2R1bGVOYW1lUmVhZGVyLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDE5OTksIDIwMTYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KcGFja2FnZSBjb20uc3VuLnRvb2xzLmphdmFjLmp2bTsKCmltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwppbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKaW1wb3J0IGphdmEubmlvLmZpbGUuRmlsZXM7CmltcG9ydCBqYXZhLm5pby5maWxlLlBhdGg7CgppbXBvcnQgamF2YXgudG9vbHMuSmF2YUZpbGVPYmplY3Q7CgppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMuanZtLkNsYXNzRmlsZS4qOwoKCi8qKgogKiBTdHJpcHBlZCBkb3duIENsYXNzUmVhZGVyLCBqdXN0IHN1ZmZpY2llbnQgdG8gcmVhZCBtb2R1bGUgbmFtZXMgZnJvbSBtb2R1bGUtaW5mby5jbGFzcyBmaWxlcwogKiB3aGlsZSBhbmFseXppbmcgdGhlIG1vZHVsZSBwYXRoLgogKgogKiA8cD4KICogPGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4gSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdAogKiB5b3VyIG93biByaXNrLiBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvciBkZWxldGlvbiB3aXRob3V0CiAqIG5vdGljZS48L2I+CiAqLwpwdWJsaWMgY2xhc3MgTW9kdWxlTmFtZVJlYWRlciB7CiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIEJhZENsYXNzRmlsZSBleHRlbmRzIEV4Y2VwdGlvbiB7CiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMDsKICAgICAgICBCYWRDbGFzc0ZpbGUoU3RyaW5nIG1zZykgewogICAgICAgICAgICBzdXBlcihtc2cpOwogICAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgSU5JVElBTF9CVUZGRVJfU0laRSA9IDB4MGZmZjA7CgogICAgLyoqIFRoZSBidWZmZXIgY29udGFpbmluZyB0aGUgY3VycmVudGx5IHJlYWQgY2xhc3MgZmlsZS4KICAgICAqLwogICAgcHJpdmF0ZSBieXRlW10gYnVmID0gbmV3IGJ5dGVbSU5JVElBTF9CVUZGRVJfU0laRV07CgogICAgLyoqIFRoZSBjdXJyZW50IGlucHV0IHBvaW50ZXIuCiAgICAgKi8KICAgIHByaXZhdGUgaW50IGJwOwoKICAgIC8qKiBGb3IgZXZlcnkgY29uc3RhbnQgcG9vbCBlbnRyeSwgYW4gaW5kZXggaW50byBidWYgd2hlcmUgdGhlCiAgICAgKiAgZGVmaW5pbmcgc2VjdGlvbiBvZiB0aGUgZW50cnkgaXMgZm91bmQuCiAgICAgKi8KICAgIHByaXZhdGUgaW50W10gcG9vbElkeDsKCiAgICBwdWJsaWMgTW9kdWxlTmFtZVJlYWRlcigpIHsKICAgIH0KCiAgICBwdWJsaWMgU3RyaW5nIHJlYWRNb2R1bGVOYW1lKFBhdGggcCkgdGhyb3dzIElPRXhjZXB0aW9uLCBCYWRDbGFzc0ZpbGUgewogICAgICAgIHRyeSAoSW5wdXRTdHJlYW0gaW4gPSBGaWxlcy5uZXdJbnB1dFN0cmVhbShwKSkgewogICAgICAgICAgICByZXR1cm4gcmVhZE1vZHVsZU5hbWUoaW4pOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgU3RyaW5nIHJlYWRNb2R1bGVOYW1lKEphdmFGaWxlT2JqZWN0IGpmbykgdGhyb3dzIElPRXhjZXB0aW9uLCBCYWRDbGFzc0ZpbGUgewogICAgICAgIHRyeSAoSW5wdXRTdHJlYW0gaW4gPSBqZm8ub3BlbklucHV0U3RyZWFtKCkpIHsKICAgICAgICAgICAgcmV0dXJuIHJlYWRNb2R1bGVOYW1lKGluKTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIFN0cmluZyByZWFkTW9kdWxlTmFtZShJbnB1dFN0cmVhbSBpbikgdGhyb3dzIElPRXhjZXB0aW9uLCBCYWRDbGFzc0ZpbGUgewogICAgICAgIGJwID0gMDsKICAgICAgICBidWYgPSByZWFkSW5wdXRTdHJlYW0oYnVmLCBpbik7CgogICAgICAgIGludCBtYWdpYyA9IG5leHRJbnQoKTsKICAgICAgICBpZiAobWFnaWMgIT0gSkFWQV9NQUdJQykKICAgICAgICAgICAgdGhyb3cgbmV3IEJhZENsYXNzRmlsZSgiaWxsZWdhbC5zdGFydC5vZi5jbGFzcy5maWxlIik7CgogICAgICAgIGludCBtaW5vclZlcnNpb24gPSBuZXh0Q2hhcigpOwogICAgICAgIGludCBtYWpvclZlcnNpb24gPSBuZXh0Q2hhcigpOwogICAgICAgIGlmIChtYWpvclZlcnNpb24gPCA1MykKICAgICAgICAgICAgdGhyb3cgbmV3IEJhZENsYXNzRmlsZSgiYmFkIG1ham9yIHZlcnNpb24gbnVtYmVyIGZvciBtb2R1bGU6ICIgKyBtYWpvclZlcnNpb24pOwoKICAgICAgICBpbmRleFBvb2woKTsKCiAgICAgICAgaW50IGFjY2Vzc19mbGFncyA9IG5leHRDaGFyKCk7CiAgICAgICAgaWYgKGFjY2Vzc19mbGFncyAhPSAweDgwMDApCiAgICAgICAgICAgIHRocm93IG5ldyBCYWRDbGFzc0ZpbGUoImludmFsaWQgYWNjZXNzIGZsYWdzIGZvciBtb2R1bGU6IDB4IiArIEludGVnZXIudG9IZXhTdHJpbmcoYWNjZXNzX2ZsYWdzKSk7CgogICAgICAgIGludCB0aGlzX2NsYXNzID0gbmV4dENoYXIoKTsKICAgICAgICAvLyBjb3VsZCwgc2hvdWxkLCBjaGVjayB0aGlzX2NsYXNzID09IENPTlNUQU5UX0NsYXNzKCJtZG91bGUtaW5mbyIpCiAgICAgICAgY2hlY2taZXJvKG5leHRDaGFyKCksICJzdXBlcl9jbGFzcyIpOwogICAgICAgIGNoZWNrWmVybyhuZXh0Q2hhcigpLCAiaW50ZXJmYWNlX2NvdW50Iik7CiAgICAgICAgY2hlY2taZXJvKG5leHRDaGFyKCksICJmaWVsZHNfY291bnQiKTsKICAgICAgICBjaGVja1plcm8obmV4dENoYXIoKSwgIm1ldGhvZHNfY291bnQiKTsKICAgICAgICBpbnQgYXR0cmlidXRlc19jb3VudCA9IG5leHRDaGFyKCk7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhdHRyaWJ1dGVzX2NvdW50OyBpKyspIHsKICAgICAgICAgICAgaW50IGF0dHJfbmFtZSA9IG5leHRDaGFyKCk7CiAgICAgICAgICAgIGludCBhdHRyX2xlbmd0aCA9IG5leHRJbnQoKTsKICAgICAgICAgICAgaWYgKGdldFV0ZjhWYWx1ZShhdHRyX25hbWUsIGZhbHNlKS5lcXVhbHMoIk1vZHVsZSIpICYmIGF0dHJfbGVuZ3RoID4gMikgewogICAgICAgICAgICAgICAgcmV0dXJuIGdldE1vZHVsZU5hbWUobmV4dENoYXIoKSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvLyBza2lwIG92ZXIgdW5rbm93biBhdHRyaWJ1dGVzCiAgICAgICAgICAgICAgICBicCArPSBhdHRyX2xlbmd0aDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB0aHJvdyBuZXcgQmFkQ2xhc3NGaWxlKCJubyBNb2R1bGUgYXR0cmlidXRlIik7CiAgICB9CgogICAgdm9pZCBjaGVja1plcm8oaW50IGNvdW50LCBTdHJpbmcgbmFtZSkgdGhyb3dzIEJhZENsYXNzRmlsZSB7CiAgICAgICAgaWYgKGNvdW50ICE9IDApCiAgICAgICAgICAgIHRocm93IG5ldyBCYWRDbGFzc0ZpbGUoImludmFsaWQgIiArIG5hbWUgKyAiIGZvciBtb2R1bGU6ICIgKyBjb3VudCk7CiAgICB9CgogICAgLyoqIEV4dHJhY3QgYSBjaGFyYWN0ZXIgYXQgcG9zaXRpb24gYnAgZnJvbSBidWYuCiAgICAgKi8KICAgIGNoYXIgZ2V0Q2hhcihpbnQgYnApIHsKICAgICAgICByZXR1cm4KICAgICAgICAgICAgKGNoYXIpKCgoYnVmW2JwXSAmIDB4RkYpIDw8IDgpICsgKGJ1ZlticCsxXSAmIDB4RkYpKTsKICAgIH0KCiAgICAvKiogUmVhZCBhIGNoYXJhY3Rlci4KICAgICAqLwogICAgY2hhciBuZXh0Q2hhcigpIHsKICAgICAgICByZXR1cm4gKGNoYXIpKCgoYnVmW2JwKytdICYgMHhGRikgPDwgOCkgKyAoYnVmW2JwKytdICYgMHhGRikpOwogICAgfQoKICAgIC8qKiBSZWFkIGFuIGludGVnZXIuCiAgICAgKi8KICAgIGludCBuZXh0SW50KCkgewogICAgICAgIHJldHVybgogICAgICAgICAgICAoKGJ1ZlticCsrXSAmIDB4RkYpIDw8IDI0KSArCiAgICAgICAgICAgICgoYnVmW2JwKytdICYgMHhGRikgPDwgMTYpICsKICAgICAgICAgICAgKChidWZbYnArK10gJiAweEZGKSA8PCA4KSArCiAgICAgICAgICAgIChidWZbYnArK10gJiAweEZGKTsKICAgIH0KCiAgICAvKiogSW5kZXggYWxsIGNvbnN0YW50IHBvb2wgZW50cmllcywgd3JpdGluZyB0aGVpciBzdGFydCBhZGRyZXNzZXMgaW50bwogICAgICogIHBvb2xJZHguCiAgICAgKi8KICAgIHZvaWQgaW5kZXhQb29sKCkgdGhyb3dzIEJhZENsYXNzRmlsZSB7CiAgICAgICAgcG9vbElkeCA9IG5ldyBpbnRbbmV4dENoYXIoKV07CiAgICAgICAgaW50IGkgPSAxOwogICAgICAgIHdoaWxlIChpIDwgcG9vbElkeC5sZW5ndGgpIHsKICAgICAgICAgICAgcG9vbElkeFtpKytdID0gYnA7CiAgICAgICAgICAgIGJ5dGUgdGFnID0gYnVmW2JwKytdOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICBjYXNlIENPTlNUQU5UX1V0Zjg6IGNhc2UgQ09OU1RBTlRfVW5pY29kZTogewogICAgICAgICAgICAgICAgaW50IGxlbiA9IG5leHRDaGFyKCk7CiAgICAgICAgICAgICAgICBicCA9IGJwICsgbGVuOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY2FzZSBDT05TVEFOVF9DbGFzczoKICAgICAgICAgICAgY2FzZSBDT05TVEFOVF9TdHJpbmc6CiAgICAgICAgICAgIGNhc2UgQ09OU1RBTlRfTWV0aG9kVHlwZToKICAgICAgICAgICAgY2FzZSBDT05TVEFOVF9Nb2R1bGU6CiAgICAgICAgICAgIGNhc2UgQ09OU1RBTlRfUGFja2FnZToKICAgICAgICAgICAgICAgIGJwID0gYnAgKyAyOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgQ09OU1RBTlRfTWV0aG9kSGFuZGxlOgogICAgICAgICAgICAgICAgYnAgPSBicCArIDM7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBDT05TVEFOVF9GaWVsZHJlZjoKICAgICAgICAgICAgY2FzZSBDT05TVEFOVF9NZXRob2RyZWY6CiAgICAgICAgICAgIGNhc2UgQ09OU1RBTlRfSW50ZXJmYWNlTWV0aG9kcmVmOgogICAgICAgICAgICBjYXNlIENPTlNUQU5UX05hbWVhbmRUeXBlOgogICAgICAgICAgICBjYXNlIENPTlNUQU5UX0ludGVnZXI6CiAgICAgICAgICAgIGNhc2UgQ09OU1RBTlRfRmxvYXQ6CiAgICAgICAgICAgIGNhc2UgQ09OU1RBTlRfSW52b2tlRHluYW1pYzoKICAgICAgICAgICAgICAgIGJwID0gYnAgKyA0OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgQ09OU1RBTlRfTG9uZzoKICAgICAgICAgICAgY2FzZSBDT05TVEFOVF9Eb3VibGU6CiAgICAgICAgICAgICAgICBicCA9IGJwICsgODsKICAgICAgICAgICAgICAgIGkrKzsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEJhZENsYXNzRmlsZSgibWFsZm9ybWVkIGNvbnN0YW50IHBvb2wiKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBTdHJpbmcgZ2V0VXRmOFZhbHVlKGludCBpbmRleCwgYm9vbGVhbiBpbnRlcm5hbGl6ZSkgdGhyb3dzIEJhZENsYXNzRmlsZSB7CiAgICAgICAgaW50IHV0ZjhJbmRleCA9IHBvb2xJZHhbaW5kZXhdOwogICAgICAgIGlmIChidWZbdXRmOEluZGV4XSA9PSBDT05TVEFOVF9VdGY4KSB7CiAgICAgICAgICAgIGludCBsZW4gPSBnZXRDaGFyKHV0ZjhJbmRleCArIDEpOwogICAgICAgICAgICBpbnQgc3RhcnQgPSB1dGY4SW5kZXggKyAzOwogICAgICAgICAgICBpZiAoaW50ZXJuYWxpemUpIHsKICAgICAgICAgICAgICAgIHJldHVybiBuZXcgU3RyaW5nKENsYXNzRmlsZS5pbnRlcm5hbGl6ZShidWYsIHN0YXJ0LCBsZW4pKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHJldHVybiBuZXcgU3RyaW5nKGJ1Ziwgc3RhcnQsIGxlbik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgdGhyb3cgbmV3IEJhZENsYXNzRmlsZSgiYmFkIG5hbWUgYXQgaW5kZXggIiArIGluZGV4KTsKICAgIH0KCiAgICBTdHJpbmcgZ2V0TW9kdWxlTmFtZShpbnQgaW5kZXgpIHRocm93cyBCYWRDbGFzc0ZpbGUgewogICAgICAgIGludCBpbmZvSW5kZXggPSBwb29sSWR4W2luZGV4XTsKICAgICAgICBpZiAoYnVmW2luZm9JbmRleF0gPT0gQ09OU1RBTlRfTW9kdWxlKSB7CiAgICAgICAgICAgIHJldHVybiBnZXRVdGY4VmFsdWUoZ2V0Q2hhcihpbmZvSW5kZXggKyAxKSwgdHJ1ZSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEJhZENsYXNzRmlsZSgiYmFkIG1vZHVsZSBuYW1lIGF0IGluZGV4ICIgKyBpbmRleCk7CiAgICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGJ5dGVbXSByZWFkSW5wdXRTdHJlYW0oYnl0ZVtdIGJ1ZiwgSW5wdXRTdHJlYW0gcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICB0cnkgewogICAgICAgICAgICBidWYgPSBlbnN1cmVDYXBhY2l0eShidWYsIHMuYXZhaWxhYmxlKCkpOwogICAgICAgICAgICBpbnQgciA9IHMucmVhZChidWYpOwogICAgICAgICAgICBpbnQgYnAgPSAwOwogICAgICAgICAgICB3aGlsZSAociAhPSAtMSkgewogICAgICAgICAgICAgICAgYnAgKz0gcjsKICAgICAgICAgICAgICAgIGJ1ZiA9IGVuc3VyZUNhcGFjaXR5KGJ1ZiwgYnApOwogICAgICAgICAgICAgICAgciA9IHMucmVhZChidWYsIGJwLCBidWYubGVuZ3RoIC0gYnApOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBidWY7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIHMuY2xvc2UoKTsKICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICAgICAgLyogSWdub3JlIGFueSBlcnJvcnMsIGFzIHRoaXMgc3RyZWFtIG1heSBoYXZlIGFscmVhZHkKICAgICAgICAgICAgICAgICAqIHRocm93biBhIHJlbGF0ZWQgZXhjZXB0aW9uIHdoaWNoIGlzIHRoZSBvbmUgdGhhdAogICAgICAgICAgICAgICAgICogc2hvdWxkIGJlIHJlcG9ydGVkLgogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoKICAgICAqIGVuc3VyZUNhcGFjaXR5IHdpbGwgaW5jcmVhc2UgdGhlIGJ1ZmZlciBhcyBuZWVkZWQsIHRha2luZyBub3RlIHRoYXQKICAgICAqIHRoZSBuZXcgYnVmZmVyIHdpbGwgYWx3YXlzIGJlIGdyZWF0ZXIgdGhhbiB0aGUgbmVlZGVkIGFuZCBuZXZlcgogICAgICogZXhhY3RseSBlcXVhbCB0byB0aGUgbmVlZGVkIHNpemUgb3IgYnAuIElmIGVxdWFsIHRoZW4gdGhlIHJlYWQgKGFib3ZlKQogICAgICogd2lsbCBpbmZpbml0ZWx5IGxvb3AgYXMgYnVmLmxlbmd0aCAtIGJwID09IDAuCiAgICAgKi8KICAgIHByaXZhdGUgc3RhdGljIGJ5dGVbXSBlbnN1cmVDYXBhY2l0eShieXRlW10gYnVmLCBpbnQgbmVlZGVkKSB7CiAgICAgICAgaWYgKGJ1Zi5sZW5ndGggPD0gbmVlZGVkKSB7CiAgICAgICAgICAgIGJ5dGVbXSBvbGQgPSBidWY7CiAgICAgICAgICAgIGJ1ZiA9IG5ldyBieXRlW0ludGVnZXIuaGlnaGVzdE9uZUJpdChuZWVkZWQpIDw8IDFdOwogICAgICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KG9sZCwgMCwgYnVmLCAwLCBvbGQubGVuZ3RoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1ZjsKICAgIH0KfQpQSwMECgAACAAABjupSv/Hmn6sDQAArA0AACQAAABjb20vc3VuL3Rvb2xzL2phdmFjL2p2bS9Qcm9maWxlLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDIsIDIwMTMsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhYy5qdm07CgppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkNvbnRleHQ7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuT3B0aW9uczsKaW1wb3J0IGphdmEudXRpbC5FbnVtU2V0OwppbXBvcnQgamF2YS51dGlsLlNldDsKCmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5tYWluLk9wdGlvbi5QUk9GSUxFOwoKLyoqIFRoZSB0YXJnZXQgcHJvZmlsZS4KICoKICogIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqICBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqICBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogKiAgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPgogKi8KcHVibGljIGVudW0gUHJvZmlsZSB7CiAgICBDT01QQUNUMSgiY29tcGFjdDEiLCAxLCBUYXJnZXQuSkRLMV84LCBUYXJnZXQuSkRLMV85KSwKICAgIENPTVBBQ1QyKCJjb21wYWN0MiIsIDIsIFRhcmdldC5KREsxXzgsIFRhcmdldC5KREsxXzkpLAogICAgQ09NUEFDVDMoImNvbXBhY3QzIiwgMywgVGFyZ2V0LkpESzFfOCwgVGFyZ2V0LkpESzFfOSksCgogICAgREVGQVVMVCB7CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gaXNWYWxpZChUYXJnZXQgdCkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICB9OwoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIENvbnRleHQuS2V5PFByb2ZpbGU+IHByb2ZpbGVLZXkgPSBuZXcgQ29udGV4dC5LZXk8PigpOwoKICAgIHB1YmxpYyBzdGF0aWMgUHJvZmlsZSBpbnN0YW5jZShDb250ZXh0IGNvbnRleHQpIHsKICAgICAgICBQcm9maWxlIGluc3RhbmNlID0gY29udGV4dC5nZXQocHJvZmlsZUtleSk7CiAgICAgICAgaWYgKGluc3RhbmNlID09IG51bGwpIHsKICAgICAgICAgICAgT3B0aW9ucyBvcHRpb25zID0gT3B0aW9ucy5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICAgICAgU3RyaW5nIHByb2ZpbGVTdHJpbmcgPSBvcHRpb25zLmdldChQUk9GSUxFKTsKICAgICAgICAgICAgaWYgKHByb2ZpbGVTdHJpbmcgIT0gbnVsbCkgaW5zdGFuY2UgPSBsb29rdXAocHJvZmlsZVN0cmluZyk7CiAgICAgICAgICAgIGlmIChpbnN0YW5jZSA9PSBudWxsKSBpbnN0YW5jZSA9IERFRkFVTFQ7CiAgICAgICAgICAgIGNvbnRleHQucHV0KHByb2ZpbGVLZXksIGluc3RhbmNlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGluc3RhbmNlOwogICAgfQoKICAgIHB1YmxpYyBmaW5hbCBTdHJpbmcgbmFtZTsKICAgIHB1YmxpYyBmaW5hbCBpbnQgdmFsdWU7CiAgICBmaW5hbCBTZXQ8VGFyZ2V0PiB0YXJnZXRzOwoKICAgIFByb2ZpbGUoKSB7CiAgICAgICAgbmFtZSA9IG51bGw7CiAgICAgICAgdmFsdWUgPSBJbnRlZ2VyLk1BWF9WQUxVRTsKICAgICAgICB0YXJnZXRzID0gbnVsbDsKICAgIH0KCiAgICBQcm9maWxlKFN0cmluZyBuYW1lLCBpbnQgdmFsdWUsIFRhcmdldCB0LCBUYXJnZXQuLi4gdGFyZ2V0cykgewogICAgICAgIHRoaXMubmFtZSA9IG5hbWU7CiAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlOwogICAgICAgIHRoaXMudGFyZ2V0cyA9IEVudW1TZXQub2YodCwgdGFyZ2V0cyk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBQcm9maWxlIGxvb2t1cChTdHJpbmcgbmFtZSkgewogICAgICAgIC8vIHRoZSBzZXQgb2YgdmFsdWVzIGlzIHNtYWxsIGVub3VnaCB0byBkbyBsaW5lYXIgc2VhcmNoCiAgICAgICAgZm9yIChQcm9maWxlIHA6IHZhbHVlcygpKSB7CiAgICAgICAgICAgIGlmIChuYW1lLmVxdWFscyhwLm5hbWUpKQogICAgICAgICAgICAgICAgcmV0dXJuIHA7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgUHJvZmlsZSBsb29rdXAoaW50IHZhbHVlKSB7CiAgICAgICAgLy8gdGhlIHNldCBvZiB2YWx1ZXMgaXMgc21hbGwgZW5vdWdoIHRvIGRvIGxpbmVhciBzZWFyY2gKICAgICAgICBmb3IgKFByb2ZpbGUgcDogdmFsdWVzKCkpIHsKICAgICAgICAgICAgaWYgKHZhbHVlID09IHAudmFsdWUpCiAgICAgICAgICAgICAgICByZXR1cm4gcDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgcHVibGljIGJvb2xlYW4gaXNWYWxpZChUYXJnZXQgdCkgewogICAgICAgIHJldHVybiB0YXJnZXRzLmNvbnRhaW5zKHQpOwogICAgfQp9ClBLAwQKAAAIAAAGO6lKquQxZFvPAQBbzwEAKAAAAGNvbS9zdW4vdG9vbHMvamF2YWMvanZtL0NsYXNzUmVhZGVyLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDE5OTksIDIwMTcsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhYy5qdm07CgppbXBvcnQgamF2YS5pby4qOwppbXBvcnQgamF2YS5uZXQuVVJJOwppbXBvcnQgamF2YS5uZXQuVVJJU3ludGF4RXhjZXB0aW9uOwppbXBvcnQgamF2YS5uaW8uQ2hhckJ1ZmZlcjsKaW1wb3J0IGphdmEubmlvLmZpbGUuQ2xvc2VkRmlsZVN5c3RlbUV4Y2VwdGlvbjsKaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CmltcG9ydCBqYXZhLnV0aWwuRW51bVNldDsKaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOwppbXBvcnQgamF2YS51dGlsLkhhc2hTZXQ7CmltcG9ydCBqYXZhLnV0aWwuTWFwOwppbXBvcnQgamF2YS51dGlsLlNldDsKCmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuTW9kaWZpZXI7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuTmVzdGluZ0tpbmQ7CmltcG9ydCBqYXZheC50b29scy5KYXZhRmlsZU1hbmFnZXI7CmltcG9ydCBqYXZheC50b29scy5KYXZhRmlsZU9iamVjdDsKCmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvbXAuQW5ub3RhdGU7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvbXAuQW5ub3RhdGUuQW5ub3RhdGlvblR5cGVDb21wbGV0ZXI7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuKjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5EaXJlY3RpdmUuKjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5MaW50LkxpbnRDYXRlZ29yeTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5TY29wZS5Xcml0ZWFibGVTY29wZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5TeW1ib2wuKjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5TeW10YWI7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuVHlwZS4qOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb21wLkFubm90YXRlLkFubm90YXRpb25UeXBlTWV0YWRhdGE7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmZpbGUuQmFzZUZpbGVNYW5hZ2VyOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5maWxlLlBhdGhGaWxlT2JqZWN0OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5qdm0uQ2xhc3NGaWxlLk5hbWVBbmRUeXBlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5qdm0uQ2xhc3NGaWxlLlZlcnNpb247CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLm1haW4uT3B0aW9uOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLio7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuRGVmaW5lZEJ5LkFwaTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5KQ0RpYWdub3N0aWMuRGlhZ25vc3RpY1Bvc2l0aW9uOwoKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuRmxhZ3MuKjsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuS2luZHMuS2luZC4qOwoKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5TY29wZS5Mb29rdXBLaW5kOwoKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuVHlwZVRhZy5BUlJBWTsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuVHlwZVRhZy5DTEFTUzsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuVHlwZVRhZy5UWVBFVkFSOwppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMuanZtLkNsYXNzRmlsZS4qOwppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMuanZtLkNsYXNzRmlsZS5WZXJzaW9uLio7CgppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMubWFpbi5PcHRpb24uUEFSQU1FVEVSUzsKCi8qKiBUaGlzIGNsYXNzIHByb3ZpZGVzIG9wZXJhdGlvbnMgdG8gcmVhZCBhIGNsYXNzZmlsZSBpbnRvIGFuIGludGVybmFsCiAqICByZXByZXNlbnRhdGlvbi4gVGhlIGludGVybmFsIHJlcHJlc2VudGF0aW9uIGlzIGFuY2hvcmVkIGluIGEKICogIENsYXNzU3ltYm9sIHdoaWNoIGNvbnRhaW5zIGluIGl0cyBzY29wZSBzeW1ib2wgcmVwcmVzZW50YXRpb25zCiAqICBmb3IgYWxsIG90aGVyIGRlZmluaXRpb25zIGluIHRoZSBjbGFzc2ZpbGUuIFRvcC1sZXZlbCBDbGFzc2VzIHRoZW1zZWx2ZXMKICogIGFwcGVhciBhcyBtZW1iZXJzIG9mIHRoZSBzY29wZXMgb2YgUGFja2FnZVN5bWJvbHMuCiAqCiAqICA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiAgSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93biByaXNrLgogKiAgVGhpcyBjb2RlIGFuZCBpdHMgaW50ZXJuYWwgaW50ZXJmYWNlcyBhcmUgc3ViamVjdCB0byBjaGFuZ2Ugb3IKICogIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj4KICovCnB1YmxpYyBjbGFzcyBDbGFzc1JlYWRlciB7CiAgICAvKiogVGhlIGNvbnRleHQga2V5IGZvciB0aGUgY2xhc3MgcmVhZGVyLiAqLwogICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBDb250ZXh0LktleTxDbGFzc1JlYWRlcj4gY2xhc3NSZWFkZXJLZXkgPSBuZXcgQ29udGV4dC5LZXk8PigpOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElOSVRJQUxfQlVGRkVSX1NJWkUgPSAweDBmZmYwOwoKICAgIHByaXZhdGUgZmluYWwgQW5ub3RhdGUgYW5ub3RhdGU7CgogICAgLyoqIFN3aXRjaDogdmVyYm9zZSBvdXRwdXQuCiAgICAgKi8KICAgIGJvb2xlYW4gdmVyYm9zZTsKCiAgICAvKiogU3dpdGNoOiByZWFkIGNvbnN0YW50IHBvb2wgYW5kIGNvZGUgc2VjdGlvbnMuIFRoaXMgc3dpdGNoIGlzIGluaXRpYWxseQogICAgICogIHNldCB0byBmYWxzZSBidXQgY2FuIGJlIHR1cm5lZCBvbiBmcm9tIG91dHNpZGUuCiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIHJlYWRBbGxPZkNsYXNzRmlsZSA9IGZhbHNlOwoKICAgIC8qKiBTd2l0Y2g6IGFsbG93IHNpbXBsaWZpZWQgdmFyYXJncy4KICAgICAqLwogICAgYm9vbGVhbiBhbGxvd1NpbXBsaWZpZWRWYXJhcmdzOwoKICAgIC8qKiBTd2l0Y2g6IGFsbG93IG1vZHVsZXMuCiAgICAgKi8KICAgIGJvb2xlYW4gYWxsb3dNb2R1bGVzOwoKICAgLyoqIExpbnQgb3B0aW9uOiB3YXJuIGFib3V0IGNsYXNzZmlsZSBpc3N1ZXMKICAgICAqLwogICAgYm9vbGVhbiBsaW50Q2xhc3NmaWxlOwoKICAgIC8qKiBTd2l0Y2g6IHByZXNlcnZlIHBhcmFtZXRlciBuYW1lcyBmcm9tIHRoZSB2YXJpYWJsZSB0YWJsZS4KICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gc2F2ZVBhcmFtZXRlck5hbWVzOwoKICAgIC8qKgogICAgICogVGhlIGN1cnJlbnRseSBzZWxlY3RlZCBwcm9maWxlLgogICAgICovCiAgICBwdWJsaWMgZmluYWwgUHJvZmlsZSBwcm9maWxlOwoKICAgIC8qKiBUaGUgbG9nIHRvIHVzZSBmb3IgdmVyYm9zZSBvdXRwdXQKICAgICAqLwogICAgZmluYWwgTG9nIGxvZzsKCiAgICAvKiogVGhlIHN5bWJvbCB0YWJsZS4gKi8KICAgIFN5bXRhYiBzeW1zOwoKICAgIFR5cGVzIHR5cGVzOwoKICAgIC8qKiBUaGUgbmFtZSB0YWJsZS4gKi8KICAgIGZpbmFsIE5hbWVzIG5hbWVzOwoKICAgIC8qKiBBY2Nlc3MgdG8gZmlsZXMKICAgICAqLwogICAgcHJpdmF0ZSBmaW5hbCBKYXZhRmlsZU1hbmFnZXIgZmlsZU1hbmFnZXI7CgogICAgLyoqIEZhY3RvcnkgZm9yIGRpYWdub3N0aWNzCiAgICAgKi8KICAgIEpDRGlhZ25vc3RpYy5GYWN0b3J5IGRpYWdGYWN0b3J5OwoKICAgIC8qKiBUaGUgY3VycmVudCBzY29wZSB3aGVyZSB0eXBlIHZhcmlhYmxlcyBhcmUgZW50ZXJlZC4KICAgICAqLwogICAgcHJvdGVjdGVkIFdyaXRlYWJsZVNjb3BlIHR5cGV2YXJzOwoKICAgIHByaXZhdGUgTGlzdDxJbnRlcmltVXNlc0RpcmVjdGl2ZT4gaW50ZXJpbVVzZXMgPSBMaXN0Lm5pbCgpOwogICAgcHJpdmF0ZSBMaXN0PEludGVyaW1Qcm92aWRlc0RpcmVjdGl2ZT4gaW50ZXJpbVByb3ZpZGVzID0gTGlzdC5uaWwoKTsKCiAgICAvKiogVGhlIHBhdGggbmFtZSBvZiB0aGUgY2xhc3MgZmlsZSBjdXJyZW50bHkgYmVpbmcgcmVhZC4KICAgICAqLwogICAgcHJvdGVjdGVkIEphdmFGaWxlT2JqZWN0IGN1cnJlbnRDbGFzc0ZpbGUgPSBudWxsOwoKICAgIC8qKiBUaGUgY2xhc3Mgb3IgbWV0aG9kIGN1cnJlbnRseSBiZWluZyByZWFkLgogICAgICovCiAgICBwcm90ZWN0ZWQgU3ltYm9sIGN1cnJlbnRPd25lciA9IG51bGw7CgogICAgLyoqIFRoZSBtb2R1bGUgY29udGFpbmluZyB0aGUgY2xhc3MgY3VycmVudGx5IGJlaW5nIHJlYWQuCiAgICAgKi8KICAgIHByb3RlY3RlZCBNb2R1bGVTeW1ib2wgY3VycmVudE1vZHVsZSA9IG51bGw7CgogICAgLyoqIFRoZSBidWZmZXIgY29udGFpbmluZyB0aGUgY3VycmVudGx5IHJlYWQgY2xhc3MgZmlsZS4KICAgICAqLwogICAgYnl0ZVtdIGJ1ZiA9IG5ldyBieXRlW0lOSVRJQUxfQlVGRkVSX1NJWkVdOwoKICAgIC8qKiBUaGUgY3VycmVudCBpbnB1dCBwb2ludGVyLgogICAgICovCiAgICBwcm90ZWN0ZWQgaW50IGJwOwoKICAgIC8qKiBUaGUgb2JqZWN0cyBvZiB0aGUgY29uc3RhbnQgcG9vbC4KICAgICAqLwogICAgT2JqZWN0W10gcG9vbE9iajsKCiAgICAvKiogRm9yIGV2ZXJ5IGNvbnN0YW50IHBvb2wgZW50cnksIGFuIGluZGV4IGludG8gYnVmIHdoZXJlIHRoZQogICAgICogIGRlZmluaW5nIHNlY3Rpb24gb2YgdGhlIGVudHJ5IGlzIGZvdW5kLgogICAgICovCiAgICBpbnRbXSBwb29sSWR4OwoKICAgIC8qKiBUaGUgbWFqb3IgdmVyc2lvbiBudW1iZXIgb2YgdGhlIGNsYXNzIGZpbGUgYmVpbmcgcmVhZC4gKi8KICAgIGludCBtYWpvclZlcnNpb247CiAgICAvKiogVGhlIG1pbm9yIHZlcnNpb24gbnVtYmVyIG9mIHRoZSBjbGFzcyBmaWxlIGJlaW5nIHJlYWQuICovCiAgICBpbnQgbWlub3JWZXJzaW9uOwoKICAgIC8qKiBBIHRhYmxlIHRvIGhvbGQgdGhlIGNvbnN0YW50IHBvb2wgaW5kaWNlcyBmb3IgbWV0aG9kIHBhcmFtZXRlcgogICAgICogbmFtZXMsIGFzIGdpdmVuIGluIExvY2FsVmFyaWFibGVUYWJsZSBhdHRyaWJ1dGVzLgogICAgICovCiAgICBpbnRbXSBwYXJhbWV0ZXJOYW1lSW5kaWNlczsKCiAgICAvKioKICAgICAqIFdoZXRoZXIgb3Igbm90IGFueSBwYXJhbWV0ZXIgbmFtZXMgaGF2ZSBiZWVuIGZvdW5kLgogICAgICovCiAgICBib29sZWFuIGhhdmVQYXJhbWV0ZXJOYW1lSW5kaWNlczsKCiAgICAvKiogU2V0IHRoaXMgdG8gZmFsc2UgZXZlcnkgdGltZSB3ZSBzdGFydCByZWFkaW5nIGEgbWV0aG9kCiAgICAgKiBhbmQgYXJlIHNhdmluZyBwYXJhbWV0ZXIgbmFtZXMuICBTZXQgaXQgdG8gdHJ1ZSB3aGVuIHdlIHNlZQogICAgICogTWV0aG9kUGFyYW1ldGVycywgaWYgaXQncyBzZXQgd2hlbiB3ZSBzZWUgYSBMb2NhbFZhcmlhYmxlVGFibGUsCiAgICAgKiB0aGVuIHdlIGlnbm9yZSB0aGUgcGFyYW1ldGVyIG5hbWVzIGZyb20gdGhlIExWVC4KICAgICAqLwogICAgYm9vbGVhbiBzYXdNZXRob2RQYXJhbWV0ZXJzOwoKICAgIC8qKgogICAgICogVGhlIHNldCBvZiBhdHRyaWJ1dGUgbmFtZXMgZm9yIHdoaWNoIHdhcm5pbmdzIGhhdmUgYmVlbiBnZW5lcmF0ZWQgZm9yIHRoZSBjdXJyZW50IGNsYXNzCiAgICAgKi8KICAgIFNldDxOYW1lPiB3YXJuZWRBdHRycyA9IG5ldyBIYXNoU2V0PD4oKTsKCiAgICAvKioKICAgICAqIFRoZSBwcm90b3R5cGUgQFRhcmdldCBBdHRyaWJ1dGUuQ29tcG91bmQgaWYgdGhpcyBjbGFzcyBpcyBhbiBhbm5vdGF0aW9uIGFubm90YXRlZCB3aXRoCiAgICAgKiBAVGFyZ2V0CiAgICAgKi8KICAgIENvbXBvdW5kQW5ub3RhdGlvblByb3h5IHRhcmdldDsKCiAgICAvKioKICAgICAqIFRoZSBwcm90b3R5cGUgQFJlcGV0YWJsZSBBdHRyaWJ1dGUuQ29tcG91bmQgaWYgdGhpcyBjbGFzcyBpcyBhbiBhbm5vdGF0aW9uIGFubm90YXRlZCB3aXRoCiAgICAgKiBAUmVwZWF0YWJsZQogICAgICovCiAgICBDb21wb3VuZEFubm90YXRpb25Qcm94eSByZXBlYXRhYmxlOwoKICAgIC8qKiBHZXQgdGhlIENsYXNzUmVhZGVyIGluc3RhbmNlIGZvciB0aGlzIGludm9jYXRpb24uICovCiAgICBwdWJsaWMgc3RhdGljIENsYXNzUmVhZGVyIGluc3RhbmNlKENvbnRleHQgY29udGV4dCkgewogICAgICAgIENsYXNzUmVhZGVyIGluc3RhbmNlID0gY29udGV4dC5nZXQoY2xhc3NSZWFkZXJLZXkpOwogICAgICAgIGlmIChpbnN0YW5jZSA9PSBudWxsKQogICAgICAgICAgICBpbnN0YW5jZSA9IG5ldyBDbGFzc1JlYWRlcihjb250ZXh0KTsKICAgICAgICByZXR1cm4gaW5zdGFuY2U7CiAgICB9CgogICAgLyoqIENvbnN0cnVjdCBhIG5ldyBjbGFzcyByZWFkZXIuICovCiAgICBwcm90ZWN0ZWQgQ2xhc3NSZWFkZXIoQ29udGV4dCBjb250ZXh0KSB7CiAgICAgICAgY29udGV4dC5wdXQoY2xhc3NSZWFkZXJLZXksIHRoaXMpOwogICAgICAgIGFubm90YXRlID0gQW5ub3RhdGUuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgbmFtZXMgPSBOYW1lcy5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBzeW1zID0gU3ltdGFiLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIHR5cGVzID0gVHlwZXMuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgZmlsZU1hbmFnZXIgPSBjb250ZXh0LmdldChKYXZhRmlsZU1hbmFnZXIuY2xhc3MpOwogICAgICAgIGlmIChmaWxlTWFuYWdlciA9PSBudWxsKQogICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoIkZpbGVNYW5hZ2VyIGluaXRpYWxpemF0aW9uIGVycm9yIik7CiAgICAgICAgZGlhZ0ZhY3RvcnkgPSBKQ0RpYWdub3N0aWMuRmFjdG9yeS5pbnN0YW5jZShjb250ZXh0KTsKCiAgICAgICAgbG9nID0gTG9nLmluc3RhbmNlKGNvbnRleHQpOwoKICAgICAgICBPcHRpb25zIG9wdGlvbnMgPSBPcHRpb25zLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIHZlcmJvc2UgICAgICAgICA9IG9wdGlvbnMuaXNTZXQoT3B0aW9uLlZFUkJPU0UpOwoKICAgICAgICBTb3VyY2Ugc291cmNlID0gU291cmNlLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIGFsbG93U2ltcGxpZmllZFZhcmFyZ3MgPSBzb3VyY2UuYWxsb3dTaW1wbGlmaWVkVmFyYXJncygpOwogICAgICAgIGFsbG93TW9kdWxlcyAgICAgPSBzb3VyY2UuYWxsb3dNb2R1bGVzKCk7CgogICAgICAgIHNhdmVQYXJhbWV0ZXJOYW1lcyA9IG9wdGlvbnMuaXNTZXQoUEFSQU1FVEVSUyk7CgogICAgICAgIHByb2ZpbGUgPSBQcm9maWxlLmluc3RhbmNlKGNvbnRleHQpOwoKICAgICAgICB0eXBldmFycyA9IFdyaXRlYWJsZVNjb3BlLmNyZWF0ZShzeW1zLm5vU3ltYm9sKTsKCiAgICAgICAgbGludENsYXNzZmlsZSA9IExpbnQuaW5zdGFuY2UoY29udGV4dCkuaXNFbmFibGVkKExpbnRDYXRlZ29yeS5DTEFTU0ZJTEUpOwoKICAgICAgICBpbml0QXR0cmlidXRlUmVhZGVycygpOwogICAgfQoKICAgIC8qKiBBZGQgbWVtYmVyIHRvIGNsYXNzIHVubGVzcyBpdCBpcyBzeW50aGV0aWMuCiAgICAgKi8KICAgIHByaXZhdGUgdm9pZCBlbnRlck1lbWJlcihDbGFzc1N5bWJvbCBjLCBTeW1ib2wgc3ltKSB7CiAgICAgICAgLy8gU3ludGhldGljIG1lbWJlcnMgYXJlIG5vdCBlbnRlcmVkIC0tIHJlYXNvbiBsb3N0IHRvIGhpc3RvcnkgKG9wdGltaXphdGlvbj8pLgogICAgICAgIC8vIExhbWJkYSBtZXRob2RzIG11c3QgYmUgZW50ZXJlZCBiZWNhdXNlIHRoZXkgbWF5IGhhdmUgaW5uZXIgY2xhc3NlcyAod2hpY2ggcmVmZXJlbmNlIHRoZW0pCiAgICAgICAgaWYgKChzeW0uZmxhZ3NfZmllbGQgJiAoU1lOVEhFVElDfEJSSURHRSkpICE9IFNZTlRIRVRJQyB8fCBzeW0ubmFtZS5zdGFydHNXaXRoKG5hbWVzLmxhbWJkYSkpCiAgICAgICAgICAgIGMubWVtYmVyc19maWVsZC5lbnRlcihzeW0pOwogICAgfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBFcnJvciBEaWFnbm9zZXMKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKICAgIHB1YmxpYyBDbGFzc0ZpbmRlci5CYWRDbGFzc0ZpbGUgYmFkQ2xhc3NGaWxlKFN0cmluZyBrZXksIE9iamVjdC4uLiBhcmdzKSB7CiAgICAgICAgcmV0dXJuIG5ldyBDbGFzc0ZpbmRlci5CYWRDbGFzc0ZpbGUgKAogICAgICAgICAgICBjdXJyZW50T3duZXIuZW5jbENsYXNzKCksCiAgICAgICAgICAgIGN1cnJlbnRDbGFzc0ZpbGUsCiAgICAgICAgICAgIGRpYWdGYWN0b3J5LmZyYWdtZW50KGtleSwgYXJncyksCiAgICAgICAgICAgIGRpYWdGYWN0b3J5KTsKICAgIH0KCiAgICBwdWJsaWMgQ2xhc3NGaW5kZXIuQmFkRW5jbG9zaW5nTWV0aG9kQXR0ciBiYWRFbmNsb3NpbmdNZXRob2QoT2JqZWN0Li4uIGFyZ3MpIHsKICAgICAgICByZXR1cm4gbmV3IENsYXNzRmluZGVyLkJhZEVuY2xvc2luZ01ldGhvZEF0dHIgKAogICAgICAgICAgICBjdXJyZW50T3duZXIuZW5jbENsYXNzKCksCiAgICAgICAgICAgIGN1cnJlbnRDbGFzc0ZpbGUsCiAgICAgICAgICAgIGRpYWdGYWN0b3J5LmZyYWdtZW50KCJiYWQuZW5jbG9zaW5nLm1ldGhvZCIsIGFyZ3MpLAogICAgICAgICAgICBkaWFnRmFjdG9yeSk7CiAgICB9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEJ1ZmZlciBBY2Nlc3MKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKICAgIC8qKiBSZWFkIGEgY2hhcmFjdGVyLgogICAgICovCiAgICBjaGFyIG5leHRDaGFyKCkgewogICAgICAgIHJldHVybiAoY2hhcikoKChidWZbYnArK10gJiAweEZGKSA8PCA4KSArIChidWZbYnArK10gJiAweEZGKSk7CiAgICB9CgogICAgLyoqIFJlYWQgYSBieXRlLgogICAgICovCiAgICBpbnQgbmV4dEJ5dGUoKSB7CiAgICAgICAgcmV0dXJuIGJ1ZlticCsrXSAmIDB4RkY7CiAgICB9CgogICAgLyoqIFJlYWQgYW4gaW50ZWdlci4KICAgICAqLwogICAgaW50IG5leHRJbnQoKSB7CiAgICAgICAgcmV0dXJuCiAgICAgICAgICAgICgoYnVmW2JwKytdICYgMHhGRikgPDwgMjQpICsKICAgICAgICAgICAgKChidWZbYnArK10gJiAweEZGKSA8PCAxNikgKwogICAgICAgICAgICAoKGJ1ZlticCsrXSAmIDB4RkYpIDw8IDgpICsKICAgICAgICAgICAgKGJ1ZlticCsrXSAmIDB4RkYpOwogICAgfQoKICAgIC8qKiBFeHRyYWN0IGEgY2hhcmFjdGVyIGF0IHBvc2l0aW9uIGJwIGZyb20gYnVmLgogICAgICovCiAgICBjaGFyIGdldENoYXIoaW50IGJwKSB7CiAgICAgICAgcmV0dXJuCiAgICAgICAgICAgIChjaGFyKSgoKGJ1ZlticF0gJiAweEZGKSA8PCA4KSArIChidWZbYnArMV0gJiAweEZGKSk7CiAgICB9CgogICAgLyoqIEV4dHJhY3QgYW4gaW50ZWdlciBhdCBwb3NpdGlvbiBicCBmcm9tIGJ1Zi4KICAgICAqLwogICAgaW50IGdldEludChpbnQgYnApIHsKICAgICAgICByZXR1cm4KICAgICAgICAgICAgKChidWZbYnBdICYgMHhGRikgPDwgMjQpICsKICAgICAgICAgICAgKChidWZbYnArMV0gJiAweEZGKSA8PCAxNikgKwogICAgICAgICAgICAoKGJ1ZlticCsyXSAmIDB4RkYpIDw8IDgpICsKICAgICAgICAgICAgKGJ1ZlticCszXSAmIDB4RkYpOwogICAgfQoKCiAgICAvKiogRXh0cmFjdCBhIGxvbmcgaW50ZWdlciBhdCBwb3NpdGlvbiBicCBmcm9tIGJ1Zi4KICAgICAqLwogICAgbG9uZyBnZXRMb25nKGludCBicCkgewogICAgICAgIERhdGFJbnB1dFN0cmVhbSBidWZpbiA9CiAgICAgICAgICAgIG5ldyBEYXRhSW5wdXRTdHJlYW0obmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGJ1ZiwgYnAsIDgpKTsKICAgICAgICB0cnkgewogICAgICAgICAgICByZXR1cm4gYnVmaW4ucmVhZExvbmcoKTsKICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihlKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqIEV4dHJhY3QgYSBmbG9hdCBhdCBwb3NpdGlvbiBicCBmcm9tIGJ1Zi4KICAgICAqLwogICAgZmxvYXQgZ2V0RmxvYXQoaW50IGJwKSB7CiAgICAgICAgRGF0YUlucHV0U3RyZWFtIGJ1ZmluID0KICAgICAgICAgICAgbmV3IERhdGFJbnB1dFN0cmVhbShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oYnVmLCBicCwgNCkpOwogICAgICAgIHRyeSB7CiAgICAgICAgICAgIHJldHVybiBidWZpbi5yZWFkRmxvYXQoKTsKICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihlKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqIEV4dHJhY3QgYSBkb3VibGUgYXQgcG9zaXRpb24gYnAgZnJvbSBidWYuCiAgICAgKi8KICAgIGRvdWJsZSBnZXREb3VibGUoaW50IGJwKSB7CiAgICAgICAgRGF0YUlucHV0U3RyZWFtIGJ1ZmluID0KICAgICAgICAgICAgbmV3IERhdGFJbnB1dFN0cmVhbShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oYnVmLCBicCwgOCkpOwogICAgICAgIHRyeSB7CiAgICAgICAgICAgIHJldHVybiBidWZpbi5yZWFkRG91YmxlKCk7CiAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoZSk7CiAgICAgICAgfQogICAgfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBDb25zdGFudCBQb29sIEFjY2VzcwogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgogICAgLyoqIEluZGV4IGFsbCBjb25zdGFudCBwb29sIGVudHJpZXMsIHdyaXRpbmcgdGhlaXIgc3RhcnQgYWRkcmVzc2VzIGludG8KICAgICAqICBwb29sSWR4LgogICAgICovCiAgICB2b2lkIGluZGV4UG9vbCgpIHsKICAgICAgICBwb29sSWR4ID0gbmV3IGludFtuZXh0Q2hhcigpXTsKICAgICAgICBwb29sT2JqID0gbmV3IE9iamVjdFtwb29sSWR4Lmxlbmd0aF07CiAgICAgICAgaW50IGkgPSAxOwogICAgICAgIHdoaWxlIChpIDwgcG9vbElkeC5sZW5ndGgpIHsKICAgICAgICAgICAgcG9vbElkeFtpKytdID0gYnA7CiAgICAgICAgICAgIGJ5dGUgdGFnID0gYnVmW2JwKytdOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICBjYXNlIENPTlNUQU5UX1V0Zjg6IGNhc2UgQ09OU1RBTlRfVW5pY29kZTogewogICAgICAgICAgICAgICAgaW50IGxlbiA9IG5leHRDaGFyKCk7CiAgICAgICAgICAgICAgICBicCA9IGJwICsgbGVuOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY2FzZSBDT05TVEFOVF9DbGFzczoKICAgICAgICAgICAgY2FzZSBDT05TVEFOVF9TdHJpbmc6CiAgICAgICAgICAgIGNhc2UgQ09OU1RBTlRfTWV0aG9kVHlwZToKICAgICAgICAgICAgY2FzZSBDT05TVEFOVF9Nb2R1bGU6CiAgICAgICAgICAgIGNhc2UgQ09OU1RBTlRfUGFja2FnZToKICAgICAgICAgICAgICAgIGJwID0gYnAgKyAyOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgQ09OU1RBTlRfTWV0aG9kSGFuZGxlOgogICAgICAgICAgICAgICAgYnAgPSBicCArIDM7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBDT05TVEFOVF9GaWVsZHJlZjoKICAgICAgICAgICAgY2FzZSBDT05TVEFOVF9NZXRob2RyZWY6CiAgICAgICAgICAgIGNhc2UgQ09OU1RBTlRfSW50ZXJmYWNlTWV0aG9kcmVmOgogICAgICAgICAgICBjYXNlIENPTlNUQU5UX05hbWVhbmRUeXBlOgogICAgICAgICAgICBjYXNlIENPTlNUQU5UX0ludGVnZXI6CiAgICAgICAgICAgIGNhc2UgQ09OU1RBTlRfRmxvYXQ6CiAgICAgICAgICAgIGNhc2UgQ09OU1RBTlRfSW52b2tlRHluYW1pYzoKICAgICAgICAgICAgICAgIGJwID0gYnAgKyA0OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgQ09OU1RBTlRfTG9uZzoKICAgICAgICAgICAgY2FzZSBDT05TVEFOVF9Eb3VibGU6CiAgICAgICAgICAgICAgICBicCA9IGJwICsgODsKICAgICAgICAgICAgICAgIGkrKzsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgdGhyb3cgYmFkQ2xhc3NGaWxlKCJiYWQuY29uc3QucG9vbC50YWcuYXQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJ5dGUudG9TdHJpbmcodGFnKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbnRlZ2VyLnRvU3RyaW5nKGJwIC0xKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqIFJlYWQgY29uc3RhbnQgcG9vbCBlbnRyeSBhdCBzdGFydCBhZGRyZXNzIGksIHVzZSBwb29sIGFzIGEgY2FjaGUuCiAgICAgKi8KICAgIE9iamVjdCByZWFkUG9vbChpbnQgaSkgewogICAgICAgIE9iamVjdCByZXN1bHQgPSBwb29sT2JqW2ldOwogICAgICAgIGlmIChyZXN1bHQgIT0gbnVsbCkgcmV0dXJuIHJlc3VsdDsKCiAgICAgICAgaW50IGluZGV4ID0gcG9vbElkeFtpXTsKICAgICAgICBpZiAoaW5kZXggPT0gMCkgcmV0dXJuIG51bGw7CgogICAgICAgIGJ5dGUgdGFnID0gYnVmW2luZGV4XTsKICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgIGNhc2UgQ09OU1RBTlRfVXRmODoKICAgICAgICAgICAgcG9vbE9ialtpXSA9IG5hbWVzLmZyb21VdGYoYnVmLCBpbmRleCArIDMsIGdldENoYXIoaW5kZXggKyAxKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgQ09OU1RBTlRfVW5pY29kZToKICAgICAgICAgICAgdGhyb3cgYmFkQ2xhc3NGaWxlKCJ1bmljb2RlLnN0ci5ub3Quc3VwcG9ydGVkIik7CiAgICAgICAgY2FzZSBDT05TVEFOVF9DbGFzczoKICAgICAgICAgICAgcG9vbE9ialtpXSA9IHJlYWRDbGFzc09yVHlwZShnZXRDaGFyKGluZGV4ICsgMSkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIENPTlNUQU5UX1N0cmluZzoKICAgICAgICAgICAgLy8gRklYTUU6IChmb290cHJpbnQpIGRvIG5vdCB1c2UgdG9TdHJpbmcgaGVyZQogICAgICAgICAgICBwb29sT2JqW2ldID0gcmVhZE5hbWUoZ2V0Q2hhcihpbmRleCArIDEpKS50b1N0cmluZygpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIENPTlNUQU5UX0ZpZWxkcmVmOiB7CiAgICAgICAgICAgIENsYXNzU3ltYm9sIG93bmVyID0gcmVhZENsYXNzU3ltYm9sKGdldENoYXIoaW5kZXggKyAxKSk7CiAgICAgICAgICAgIE5hbWVBbmRUeXBlIG50ID0gcmVhZE5hbWVBbmRUeXBlKGdldENoYXIoaW5kZXggKyAzKSk7CiAgICAgICAgICAgIHBvb2xPYmpbaV0gPSBuZXcgVmFyU3ltYm9sKDAsIG50Lm5hbWUsIG50LnVuaXF1ZVR5cGUudHlwZSwgb3duZXIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgY2FzZSBDT05TVEFOVF9NZXRob2RyZWY6CiAgICAgICAgY2FzZSBDT05TVEFOVF9JbnRlcmZhY2VNZXRob2RyZWY6IHsKICAgICAgICAgICAgQ2xhc3NTeW1ib2wgb3duZXIgPSByZWFkQ2xhc3NTeW1ib2woZ2V0Q2hhcihpbmRleCArIDEpKTsKICAgICAgICAgICAgTmFtZUFuZFR5cGUgbnQgPSByZWFkTmFtZUFuZFR5cGUoZ2V0Q2hhcihpbmRleCArIDMpKTsKICAgICAgICAgICAgcG9vbE9ialtpXSA9IG5ldyBNZXRob2RTeW1ib2woMCwgbnQubmFtZSwgbnQudW5pcXVlVHlwZS50eXBlLCBvd25lcik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBjYXNlIENPTlNUQU5UX05hbWVhbmRUeXBlOgogICAgICAgICAgICBwb29sT2JqW2ldID0gbmV3IE5hbWVBbmRUeXBlKAogICAgICAgICAgICAgICAgcmVhZE5hbWUoZ2V0Q2hhcihpbmRleCArIDEpKSwKICAgICAgICAgICAgICAgIHJlYWRUeXBlKGdldENoYXIoaW5kZXggKyAzKSksIHR5cGVzKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBDT05TVEFOVF9JbnRlZ2VyOgogICAgICAgICAgICBwb29sT2JqW2ldID0gZ2V0SW50KGluZGV4ICsgMSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgQ09OU1RBTlRfRmxvYXQ6CiAgICAgICAgICAgIHBvb2xPYmpbaV0gPSBGbG9hdC52YWx1ZU9mKGdldEZsb2F0KGluZGV4ICsgMSkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIENPTlNUQU5UX0xvbmc6CiAgICAgICAgICAgIHBvb2xPYmpbaV0gPSBMb25nLnZhbHVlT2YoZ2V0TG9uZyhpbmRleCArIDEpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBDT05TVEFOVF9Eb3VibGU6CiAgICAgICAgICAgIHBvb2xPYmpbaV0gPSBEb3VibGUudmFsdWVPZihnZXREb3VibGUoaW5kZXggKyAxKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgQ09OU1RBTlRfTWV0aG9kSGFuZGxlOgogICAgICAgICAgICBza2lwQnl0ZXMoNCk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgQ09OU1RBTlRfTWV0aG9kVHlwZToKICAgICAgICAgICAgc2tpcEJ5dGVzKDMpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIENPTlNUQU5UX0ludm9rZUR5bmFtaWM6CiAgICAgICAgICAgIHNraXBCeXRlcyg1KTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBDT05TVEFOVF9Nb2R1bGU6CiAgICAgICAgY2FzZSBDT05TVEFOVF9QYWNrYWdlOgogICAgICAgICAgICAvLyB0aGlzIGlzIHRlbXBvcmFyeSBmb3Igbm93OiB0cmVhdCBhcyBhIHNpbXBsZSByZWZlcmVuY2UgdG8gdGhlIHVuZGVybHlpbmcgVXRmOC4KICAgICAgICAgICAgcG9vbE9ialtpXSA9IHJlYWROYW1lKGdldENoYXIoaW5kZXggKyAxKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHRocm93IGJhZENsYXNzRmlsZSgiYmFkLmNvbnN0LnBvb2wudGFnIiwgQnl0ZS50b1N0cmluZyh0YWcpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHBvb2xPYmpbaV07CiAgICB9CgogICAgLyoqIFJlYWQgc2lnbmF0dXJlIGFuZCBjb252ZXJ0IHRvIHR5cGUuCiAgICAgKi8KICAgIFR5cGUgcmVhZFR5cGUoaW50IGkpIHsKICAgICAgICBpbnQgaW5kZXggPSBwb29sSWR4W2ldOwogICAgICAgIHJldHVybiBzaWdUb1R5cGUoYnVmLCBpbmRleCArIDMsIGdldENoYXIoaW5kZXggKyAxKSk7CiAgICB9CgogICAgLyoqIElmIG5hbWUgaXMgYW4gYXJyYXkgdHlwZSBvciBjbGFzcyBzaWduYXR1cmUsIHJldHVybiB0aGUKICAgICAqICBjb3JyZXNwb25kaW5nIHR5cGU7IG90aGVyd2lzZSByZXR1cm4gYSBDbGFzc1N5bWJvbCB3aXRoIGdpdmVuIG5hbWUuCiAgICAgKi8KICAgIE9iamVjdCByZWFkQ2xhc3NPclR5cGUoaW50IGkpIHsKICAgICAgICBpbnQgaW5kZXggPSAgcG9vbElkeFtpXTsKICAgICAgICBpbnQgbGVuID0gZ2V0Q2hhcihpbmRleCArIDEpOwogICAgICAgIGludCBzdGFydCA9IGluZGV4ICsgMzsKICAgICAgICBBc3NlcnQuY2hlY2soYnVmW3N0YXJ0XSA9PSAnWycgfHwgYnVmW3N0YXJ0ICsgbGVuIC0gMV0gIT0gJzsnKTsKICAgICAgICAvLyBieSB0aGUgYWJvdmUgYXNzZXJ0aW9uLCB0aGUgZm9sbG93aW5nIHRlc3QgY2FuIGJlCiAgICAgICAgLy8gc2ltcGxpZmllZCB0byAoYnVmW3N0YXJ0XSA9PSAnWycpCiAgICAgICAgcmV0dXJuIChidWZbc3RhcnRdID09ICdbJyB8fCBidWZbc3RhcnQgKyBsZW4gLSAxXSA9PSAnOycpCiAgICAgICAgICAgID8gKE9iamVjdClzaWdUb1R5cGUoYnVmLCBzdGFydCwgbGVuKQogICAgICAgICAgICA6IChPYmplY3QpZW50ZXJDbGFzcyhuYW1lcy5mcm9tVXRmKGludGVybmFsaXplKGJ1Ziwgc3RhcnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGVuKSkpOwogICAgfQoKICAgIC8qKiBSZWFkIHNpZ25hdHVyZSBhbmQgY29udmVydCB0byB0eXBlIHBhcmFtZXRlcnMuCiAgICAgKi8KICAgIExpc3Q8VHlwZT4gcmVhZFR5cGVQYXJhbXMoaW50IGkpIHsKICAgICAgICBpbnQgaW5kZXggPSBwb29sSWR4W2ldOwogICAgICAgIHJldHVybiBzaWdUb1R5cGVQYXJhbXMoYnVmLCBpbmRleCArIDMsIGdldENoYXIoaW5kZXggKyAxKSk7CiAgICB9CgogICAgLyoqIFJlYWQgY2xhc3MgZW50cnkuCiAgICAgKi8KICAgIENsYXNzU3ltYm9sIHJlYWRDbGFzc1N5bWJvbChpbnQgaSkgewogICAgICAgIE9iamVjdCBvYmogPSByZWFkUG9vbChpKTsKICAgICAgICBpZiAob2JqICE9IG51bGwgJiYgIShvYmogaW5zdGFuY2VvZiBDbGFzc1N5bWJvbCkpCiAgICAgICAgICAgIHRocm93IGJhZENsYXNzRmlsZSgiYmFkLmNvbnN0LnBvb2wuZW50cnkiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudENsYXNzRmlsZS50b1N0cmluZygpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNPTlNUQU5UX0NsYXNzX2luZm8iLCBpKTsKICAgICAgICByZXR1cm4gKENsYXNzU3ltYm9sKW9iajsKICAgIH0KCiAgICBOYW1lIHJlYWRDbGFzc05hbWUoaW50IGkpIHsKICAgICAgICBpbnQgaW5kZXggPSBwb29sSWR4W2ldOwogICAgICAgIGlmIChpbmRleCA9PSAwKSByZXR1cm4gbnVsbDsKICAgICAgICBieXRlIHRhZyA9IGJ1ZltpbmRleF07CiAgICAgICAgaWYgKHRhZyAhPSBDT05TVEFOVF9DbGFzcykgewogICAgICAgICAgICB0aHJvdyBiYWRDbGFzc0ZpbGUoImJhZC5jb25zdC5wb29sLmVudHJ5IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRDbGFzc0ZpbGUudG9TdHJpbmcoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDT05TVEFOVF9DbGFzc19pbmZvIiwgaSk7CiAgICAgICAgfQogICAgICAgIGludCBuYW1lSW5kZXggPSAgcG9vbElkeFtnZXRDaGFyKGluZGV4ICsgMSldOwogICAgICAgIGludCBsZW4gPSBnZXRDaGFyKG5hbWVJbmRleCArIDEpOwogICAgICAgIGludCBzdGFydCA9IG5hbWVJbmRleCArIDM7CiAgICAgICAgaWYgKGJ1ZltzdGFydF0gPT0gJ1snIHx8IGJ1ZltzdGFydCArIGxlbiAtIDFdID09ICc7JykKICAgICAgICAgICAgdGhyb3cgYmFkQ2xhc3NGaWxlKCJ3cm9uZyBjbGFzcyBuYW1lIik7IC8vVE9ETzogcHJvcGVyIGRpYWdub3N0aWNzCiAgICAgICAgcmV0dXJuIG5hbWVzLmZyb21VdGYoaW50ZXJuYWxpemUoYnVmLCBzdGFydCwgbGVuKSk7CiAgICB9CgogICAgLyoqIFJlYWQgbmFtZS4KICAgICAqLwogICAgTmFtZSByZWFkTmFtZShpbnQgaSkgewogICAgICAgIE9iamVjdCBvYmogPSByZWFkUG9vbChpKTsKICAgICAgICBpZiAob2JqICE9IG51bGwgJiYgIShvYmogaW5zdGFuY2VvZiBOYW1lKSkKICAgICAgICAgICAgdGhyb3cgYmFkQ2xhc3NGaWxlKCJiYWQuY29uc3QucG9vbC5lbnRyeSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50Q2xhc3NGaWxlLnRvU3RyaW5nKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ09OU1RBTlRfVXRmOF9pbmZvIG9yIENPTlNUQU5UX1N0cmluZ19pbmZvIiwgaSk7CiAgICAgICAgcmV0dXJuIChOYW1lKW9iajsKICAgIH0KCiAgICAvKiogUmVhZCBuYW1lIGFuZCB0eXBlLgogICAgICovCiAgICBOYW1lQW5kVHlwZSByZWFkTmFtZUFuZFR5cGUoaW50IGkpIHsKICAgICAgICBPYmplY3Qgb2JqID0gcmVhZFBvb2woaSk7CiAgICAgICAgaWYgKG9iaiAhPSBudWxsICYmICEob2JqIGluc3RhbmNlb2YgTmFtZUFuZFR5cGUpKQogICAgICAgICAgICB0aHJvdyBiYWRDbGFzc0ZpbGUoImJhZC5jb25zdC5wb29sLmVudHJ5IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRDbGFzc0ZpbGUudG9TdHJpbmcoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDT05TVEFOVF9OYW1lQW5kVHlwZV9pbmZvIiwgaSk7CiAgICAgICAgcmV0dXJuIChOYW1lQW5kVHlwZSlvYmo7CiAgICB9CgogICAgLyoqIFJlYWQgdGhlIG5hbWUgb2YgYSBtb2R1bGUuCiAgICAgKiBUaGUgbmFtZSBpcyBzdG9yZWQgaW4gYSBDT05TVEFOVF9Nb2R1bGUgZW50cnksIGluCiAgICAgKiBKVk1TIDQuMiBiaW5hcnkgZm9ybSAodXNpbmcgIi4iLCBub3QgIi8iKQogICAgICovCiAgICBOYW1lIHJlYWRNb2R1bGVOYW1lKGludCBpKSB7CiAgICAgICAgcmV0dXJuIHJlYWROYW1lKGkpOwogICAgfQoKICAgIC8qKiBSZWFkIG1vZHVsZV9mbGFncy4KICAgICAqLwogICAgU2V0PE1vZHVsZUZsYWdzPiByZWFkTW9kdWxlRmxhZ3MoaW50IGZsYWdzKSB7CiAgICAgICAgU2V0PE1vZHVsZUZsYWdzPiBzZXQgPSBFbnVtU2V0Lm5vbmVPZihNb2R1bGVGbGFncy5jbGFzcyk7CiAgICAgICAgZm9yIChNb2R1bGVGbGFncyBmIDogTW9kdWxlRmxhZ3MudmFsdWVzKCkpIHsKICAgICAgICAgICAgaWYgKChmbGFncyAmIGYudmFsdWUpICE9IDApCiAgICAgICAgICAgICAgICBzZXQuYWRkKGYpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gc2V0OwogICAgfQoKICAgIC8qKiBSZWFkIHJlc29sdXRpb25fZmxhZ3MuCiAgICAgKi8KICAgIFNldDxNb2R1bGVSZXNvbHV0aW9uRmxhZ3M+IHJlYWRNb2R1bGVSZXNvbHV0aW9uRmxhZ3MoaW50IGZsYWdzKSB7CiAgICAgICAgU2V0PE1vZHVsZVJlc29sdXRpb25GbGFncz4gc2V0ID0gRW51bVNldC5ub25lT2YoTW9kdWxlUmVzb2x1dGlvbkZsYWdzLmNsYXNzKTsKICAgICAgICBmb3IgKE1vZHVsZVJlc29sdXRpb25GbGFncyBmIDogTW9kdWxlUmVzb2x1dGlvbkZsYWdzLnZhbHVlcygpKSB7CiAgICAgICAgICAgIGlmICgoZmxhZ3MgJiBmLnZhbHVlKSAhPSAwKQogICAgICAgICAgICAgICAgc2V0LmFkZChmKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHNldDsKICAgIH0KCiAgICAvKiogUmVhZCBleHBvcnRzX2ZsYWdzLgogICAgICovCiAgICBTZXQ8RXhwb3J0c0ZsYWc+IHJlYWRFeHBvcnRzRmxhZ3MoaW50IGZsYWdzKSB7CiAgICAgICAgU2V0PEV4cG9ydHNGbGFnPiBzZXQgPSBFbnVtU2V0Lm5vbmVPZihFeHBvcnRzRmxhZy5jbGFzcyk7CiAgICAgICAgZm9yIChFeHBvcnRzRmxhZyBmOiBFeHBvcnRzRmxhZy52YWx1ZXMoKSkgewogICAgICAgICAgICBpZiAoKGZsYWdzICYgZi52YWx1ZSkgIT0gMCkKICAgICAgICAgICAgICAgIHNldC5hZGQoZik7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzZXQ7CiAgICB9CgogICAgLyoqIFJlYWQgb3BlbnNfZmxhZ3MuCiAgICAgKi8KICAgIFNldDxPcGVuc0ZsYWc+IHJlYWRPcGVuc0ZsYWdzKGludCBmbGFncykgewogICAgICAgIFNldDxPcGVuc0ZsYWc+IHNldCA9IEVudW1TZXQubm9uZU9mKE9wZW5zRmxhZy5jbGFzcyk7CiAgICAgICAgZm9yIChPcGVuc0ZsYWcgZjogT3BlbnNGbGFnLnZhbHVlcygpKSB7CiAgICAgICAgICAgIGlmICgoZmxhZ3MgJiBmLnZhbHVlKSAhPSAwKQogICAgICAgICAgICAgICAgc2V0LmFkZChmKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHNldDsKICAgIH0KCiAgICAvKiogUmVhZCByZXF1aXJlc19mbGFncy4KICAgICAqLwogICAgU2V0PFJlcXVpcmVzRmxhZz4gcmVhZFJlcXVpcmVzRmxhZ3MoaW50IGZsYWdzKSB7CiAgICAgICAgU2V0PFJlcXVpcmVzRmxhZz4gc2V0ID0gRW51bVNldC5ub25lT2YoUmVxdWlyZXNGbGFnLmNsYXNzKTsKICAgICAgICBmb3IgKFJlcXVpcmVzRmxhZyBmOiBSZXF1aXJlc0ZsYWcudmFsdWVzKCkpIHsKICAgICAgICAgICAgaWYgKChmbGFncyAmIGYudmFsdWUpICE9IDApCiAgICAgICAgICAgICAgICBzZXQuYWRkKGYpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gc2V0OwogICAgfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWFkaW5nIFR5cGVzCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiAgICAvKiogVGhlIHVucmVhZCBwb3J0aW9uIG9mIHRoZSBjdXJyZW50bHkgcmVhZCB0eXBlIGlzCiAgICAgKiAgc2lnbmF0dXJlW3NpZ3AuLnNpZ2xpbWl0LTFdLgogICAgICovCiAgICBieXRlW10gc2lnbmF0dXJlOwogICAgaW50IHNpZ3A7CiAgICBpbnQgc2lnbGltaXQ7CiAgICBib29sZWFuIHNpZ0VudGVyUGhhc2UgPSBmYWxzZTsKCiAgICAvKiogQ29udmVydCBzaWduYXR1cmUgdG8gdHlwZSwgd2hlcmUgc2lnbmF0dXJlIGlzIGEgYnl0ZSBhcnJheSBzZWdtZW50LgogICAgICovCiAgICBUeXBlIHNpZ1RvVHlwZShieXRlW10gc2lnLCBpbnQgb2Zmc2V0LCBpbnQgbGVuKSB7CiAgICAgICAgc2lnbmF0dXJlID0gc2lnOwogICAgICAgIHNpZ3AgPSBvZmZzZXQ7CiAgICAgICAgc2lnbGltaXQgPSBvZmZzZXQgKyBsZW47CiAgICAgICAgcmV0dXJuIHNpZ1RvVHlwZSgpOwogICAgfQoKICAgIC8qKiBDb252ZXJ0IHNpZ25hdHVyZSB0byB0eXBlLCB3aGVyZSBzaWduYXR1cmUgaXMgaW1wbGljaXQuCiAgICAgKi8KICAgIFR5cGUgc2lnVG9UeXBlKCkgewogICAgICAgIHN3aXRjaCAoKGNoYXIpIHNpZ25hdHVyZVtzaWdwXSkgewogICAgICAgIGNhc2UgJ1QnOgogICAgICAgICAgICBzaWdwKys7CiAgICAgICAgICAgIGludCBzdGFydCA9IHNpZ3A7CiAgICAgICAgICAgIHdoaWxlIChzaWduYXR1cmVbc2lncF0gIT0gJzsnKSBzaWdwKys7CiAgICAgICAgICAgIHNpZ3ArKzsKICAgICAgICAgICAgcmV0dXJuIHNpZ0VudGVyUGhhc2UKICAgICAgICAgICAgICAgID8gVHlwZS5ub1R5cGUKICAgICAgICAgICAgICAgIDogZmluZFR5cGVWYXIobmFtZXMuZnJvbVV0ZihzaWduYXR1cmUsIHN0YXJ0LCBzaWdwIC0gMSAtIHN0YXJ0KSk7CiAgICAgICAgY2FzZSAnKyc6IHsKICAgICAgICAgICAgc2lncCsrOwogICAgICAgICAgICBUeXBlIHQgPSBzaWdUb1R5cGUoKTsKICAgICAgICAgICAgcmV0dXJuIG5ldyBXaWxkY2FyZFR5cGUodCwgQm91bmRLaW5kLkVYVEVORFMsIHN5bXMuYm91bmRDbGFzcyk7CiAgICAgICAgfQogICAgICAgIGNhc2UgJyonOgogICAgICAgICAgICBzaWdwKys7CiAgICAgICAgICAgIHJldHVybiBuZXcgV2lsZGNhcmRUeXBlKHN5bXMub2JqZWN0VHlwZSwgQm91bmRLaW5kLlVOQk9VTkQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5bXMuYm91bmRDbGFzcyk7CiAgICAgICAgY2FzZSAnLSc6IHsKICAgICAgICAgICAgc2lncCsrOwogICAgICAgICAgICBUeXBlIHQgPSBzaWdUb1R5cGUoKTsKICAgICAgICAgICAgcmV0dXJuIG5ldyBXaWxkY2FyZFR5cGUodCwgQm91bmRLaW5kLlNVUEVSLCBzeW1zLmJvdW5kQ2xhc3MpOwogICAgICAgIH0KICAgICAgICBjYXNlICdCJzoKICAgICAgICAgICAgc2lncCsrOwogICAgICAgICAgICByZXR1cm4gc3ltcy5ieXRlVHlwZTsKICAgICAgICBjYXNlICdDJzoKICAgICAgICAgICAgc2lncCsrOwogICAgICAgICAgICByZXR1cm4gc3ltcy5jaGFyVHlwZTsKICAgICAgICBjYXNlICdEJzoKICAgICAgICAgICAgc2lncCsrOwogICAgICAgICAgICByZXR1cm4gc3ltcy5kb3VibGVUeXBlOwogICAgICAgIGNhc2UgJ0YnOgogICAgICAgICAgICBzaWdwKys7CiAgICAgICAgICAgIHJldHVybiBzeW1zLmZsb2F0VHlwZTsKICAgICAgICBjYXNlICdJJzoKICAgICAgICAgICAgc2lncCsrOwogICAgICAgICAgICByZXR1cm4gc3ltcy5pbnRUeXBlOwogICAgICAgIGNhc2UgJ0onOgogICAgICAgICAgICBzaWdwKys7CiAgICAgICAgICAgIHJldHVybiBzeW1zLmxvbmdUeXBlOwogICAgICAgIGNhc2UgJ0wnOgogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvLyBpbnQgb2xkc2lncCA9IHNpZ3A7CiAgICAgICAgICAgICAgICBUeXBlIHQgPSBjbGFzc1NpZ1RvVHlwZSgpOwogICAgICAgICAgICAgICAgaWYgKHNpZ3AgPCBzaWdsaW1pdCAmJiBzaWduYXR1cmVbc2lncF0gPT0gJy4nKQogICAgICAgICAgICAgICAgICAgIHRocm93IGJhZENsYXNzRmlsZSgiZGVwcmVjYXRlZCBpbm5lciBjbGFzcyBzaWduYXR1cmUgc3ludGF4ICIgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKHBsZWFzZSByZWNvbXBpbGUgZnJvbSBzb3VyY2UpIik7CiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKCIgZGVjb2RlZCAiICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgU3RyaW5nKHNpZ25hdHVyZSwgb2xkc2lncCwgc2lncC1vbGRzaWdwKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiA9PiAiICsgdCArICIgb3V0ZXIgIiArIHQub3V0ZXIoKSk7CiAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgcmV0dXJuIHQ7CiAgICAgICAgICAgIH0KICAgICAgICBjYXNlICdTJzoKICAgICAgICAgICAgc2lncCsrOwogICAgICAgICAgICByZXR1cm4gc3ltcy5zaG9ydFR5cGU7CiAgICAgICAgY2FzZSAnVic6CiAgICAgICAgICAgIHNpZ3ArKzsKICAgICAgICAgICAgcmV0dXJuIHN5bXMudm9pZFR5cGU7CiAgICAgICAgY2FzZSAnWic6CiAgICAgICAgICAgIHNpZ3ArKzsKICAgICAgICAgICAgcmV0dXJuIHN5bXMuYm9vbGVhblR5cGU7CiAgICAgICAgY2FzZSAnWyc6CiAgICAgICAgICAgIHNpZ3ArKzsKICAgICAgICAgICAgcmV0dXJuIG5ldyBBcnJheVR5cGUoc2lnVG9UeXBlKCksIHN5bXMuYXJyYXlDbGFzcyk7CiAgICAgICAgY2FzZSAnKCc6CiAgICAgICAgICAgIHNpZ3ArKzsKICAgICAgICAgICAgTGlzdDxUeXBlPiBhcmd0eXBlcyA9IHNpZ1RvVHlwZXMoJyknKTsKICAgICAgICAgICAgVHlwZSByZXN0eXBlID0gc2lnVG9UeXBlKCk7CiAgICAgICAgICAgIExpc3Q8VHlwZT4gdGhyb3duID0gTGlzdC5uaWwoKTsKICAgICAgICAgICAgd2hpbGUgKHNpZ25hdHVyZVtzaWdwXSA9PSAnXicpIHsKICAgICAgICAgICAgICAgIHNpZ3ArKzsKICAgICAgICAgICAgICAgIHRocm93biA9IHRocm93bi5wcmVwZW5kKHNpZ1RvVHlwZSgpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvLyBpZiB0aGVyZSBpcyBhIHR5cGV2YXIgaW4gdGhlIHRocm93cyBjbGF1c2Ugd2Ugc2hvdWxkIHN0YXRlIGl0LgogICAgICAgICAgICBmb3IgKExpc3Q8VHlwZT4gbCA9IHRocm93bjsgbC5ub25FbXB0eSgpOyBsID0gbC50YWlsKSB7CiAgICAgICAgICAgICAgICBpZiAobC5oZWFkLmhhc1RhZyhUWVBFVkFSKSkgewogICAgICAgICAgICAgICAgICAgIGwuaGVhZC50c3ltLmZsYWdzX2ZpZWxkIHw9IFRIUk9XUzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gbmV3IE1ldGhvZFR5cGUoYXJndHlwZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN0eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3duLnJldmVyc2UoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5bXMubWV0aG9kQ2xhc3MpOwogICAgICAgIGNhc2UgJzwnOgogICAgICAgICAgICB0eXBldmFycyA9IHR5cGV2YXJzLmR1cChjdXJyZW50T3duZXIpOwogICAgICAgICAgICBUeXBlIHBvbHkgPSBuZXcgRm9yQWxsKHNpZ1RvVHlwZVBhcmFtcygpLCBzaWdUb1R5cGUoKSk7CiAgICAgICAgICAgIHR5cGV2YXJzID0gdHlwZXZhcnMubGVhdmUoKTsKICAgICAgICAgICAgcmV0dXJuIHBvbHk7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgdGhyb3cgYmFkQ2xhc3NGaWxlKCJiYWQuc2lnbmF0dXJlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbnZlcnQudXRmMnN0cmluZyhzaWduYXR1cmUsIHNpZ3AsIDEwKSk7CiAgICAgICAgfQogICAgfQoKICAgIGJ5dGVbXSBzaWduYXR1cmVCdWZmZXIgPSBuZXcgYnl0ZVswXTsKICAgIGludCBzYnAgPSAwOwogICAgLyoqIENvbnZlcnQgY2xhc3Mgc2lnbmF0dXJlIHRvIHR5cGUsIHdoZXJlIHNpZ25hdHVyZSBpcyBpbXBsaWNpdC4KICAgICAqLwogICAgVHlwZSBjbGFzc1NpZ1RvVHlwZSgpIHsKICAgICAgICBpZiAoc2lnbmF0dXJlW3NpZ3BdICE9ICdMJykKICAgICAgICAgICAgdGhyb3cgYmFkQ2xhc3NGaWxlKCJiYWQuY2xhc3Muc2lnbmF0dXJlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbnZlcnQudXRmMnN0cmluZyhzaWduYXR1cmUsIHNpZ3AsIDEwKSk7CiAgICAgICAgc2lncCsrOwogICAgICAgIFR5cGUgb3V0ZXIgPSBUeXBlLm5vVHlwZTsKICAgICAgICBpbnQgc3RhcnRTYnAgPSBzYnA7CgogICAgICAgIHdoaWxlICh0cnVlKSB7CiAgICAgICAgICAgIGZpbmFsIGJ5dGUgYyA9IHNpZ25hdHVyZVtzaWdwKytdOwogICAgICAgICAgICBzd2l0Y2ggKGMpIHsKCiAgICAgICAgICAgIGNhc2UgJzsnOiB7ICAgICAgICAgLy8gZW5kCiAgICAgICAgICAgICAgICBDbGFzc1N5bWJvbCB0ID0gZW50ZXJDbGFzcyhuYW1lcy5mcm9tVXRmKHNpZ25hdHVyZUJ1ZmZlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhcnRTYnAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNicCAtIHN0YXJ0U2JwKSk7CgogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gKG91dGVyID09IFR5cGUubm9UeXBlKSA/CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0LmVyYXN1cmUodHlwZXMpIDoKICAgICAgICAgICAgICAgICAgICAgICAgbmV3IENsYXNzVHlwZShvdXRlciwgTGlzdC5uaWwoKSwgdCk7CiAgICAgICAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAgICAgICAgIHNicCA9IHN0YXJ0U2JwOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBjYXNlICc8JzogICAgICAgICAgIC8vIGdlbmVyaWMgYXJndW1lbnRzCiAgICAgICAgICAgICAgICBDbGFzc1N5bWJvbCB0ID0gZW50ZXJDbGFzcyhuYW1lcy5mcm9tVXRmKHNpZ25hdHVyZUJ1ZmZlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhcnRTYnAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNicCAtIHN0YXJ0U2JwKSk7CiAgICAgICAgICAgICAgICBvdXRlciA9IG5ldyBDbGFzc1R5cGUob3V0ZXIsIHNpZ1RvVHlwZXMoJz4nKSwgdCkgewogICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGNvbXBsZXRlZCA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICAgICAgICAgICAgICAgICAgICAgIHB1YmxpYyBUeXBlIGdldEVuY2xvc2luZ1R5cGUoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWNvbXBsZXRlZCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBsZXRlZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHN5bS5jb21wbGV0ZSgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFR5cGUgZW5jbG9zaW5nVHlwZSA9IHRzeW0udHlwZS5nZXRFbmNsb3NpbmdUeXBlKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVuY2xvc2luZ1R5cGUgIT0gVHlwZS5ub1R5cGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTGlzdDxUeXBlPiB0eXBlQXJncyA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdXBlci5nZXRFbmNsb3NpbmdUeXBlKCkuYWxscGFyYW1zKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExpc3Q8VHlwZT4gdHlwZVBhcmFtcyA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmNsb3NpbmdUeXBlLmFsbHBhcmFtcygpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZVBhcmFtcy5sZW5ndGgoKSAhPSB0eXBlQXJncy5sZW5ndGgoKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbm8gInJhcmUiIHR5cGVzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdXBlci5zZXRFbmNsb3NpbmdUeXBlKHR5cGVzLmVyYXN1cmUoZW5jbG9zaW5nVHlwZSkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VwZXIuc2V0RW5jbG9zaW5nVHlwZSh0eXBlcy5zdWJzdChlbmNsb3NpbmdUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlUGFyYW1zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlQXJncykpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VwZXIuc2V0RW5jbG9zaW5nVHlwZShUeXBlLm5vVHlwZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmdldEVuY2xvc2luZ1R5cGUoKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgICAgICAgICAgICAgcHVibGljIHZvaWQgc2V0RW5jbG9zaW5nVHlwZShUeXBlIG91dGVyKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICBzd2l0Y2ggKHNpZ25hdHVyZVtzaWdwKytdKSB7CiAgICAgICAgICAgICAgICBjYXNlICc7JzoKICAgICAgICAgICAgICAgICAgICBpZiAoc2lncCA8IHNpZ25hdHVyZS5sZW5ndGggJiYgc2lnbmF0dXJlW3NpZ3BdID09ICcuJykgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBzdXBwb3J0IG9sZC1zdHlsZSBHSkMgc2lnbmF0dXJlcwogICAgICAgICAgICAgICAgICAgICAgICAvLyBUaGUgc2lnbmF0dXJlIHByb2R1Y2VkIHdhcwogICAgICAgICAgICAgICAgICAgICAgICAvLyBMZm9vL091dGVyPExmb28vWDs+Oy5MZm9vL091dGVyJElubmVyPExmb28vWTs+OwogICAgICAgICAgICAgICAgICAgICAgICAvLyByYXRoZXIgdGhhbiBzYXkKICAgICAgICAgICAgICAgICAgICAgICAgLy8gTGZvby9PdXRlcjxMZm9vL1g7Pi5Jbm5lcjxMZm9vL1k7PjsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gc28gd2Ugc2tpcCBwYXN0ICIuTGZvby9PdXRlciQiCiAgICAgICAgICAgICAgICAgICAgICAgIHNpZ3AgKz0gKHNicCAtIHN0YXJ0U2JwKSArIC8vICJmb28vT3V0ZXIiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAzOyAgLy8gIi5MIiBhbmQgIiQiCiAgICAgICAgICAgICAgICAgICAgICAgIHNpZ25hdHVyZUJ1ZmZlcltzYnArK10gPSAoYnl0ZSknJCc7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHNicCA9IHN0YXJ0U2JwOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gb3V0ZXI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgY2FzZSAnLic6CiAgICAgICAgICAgICAgICAgICAgc2lnbmF0dXJlQnVmZmVyW3NicCsrXSA9IChieXRlKSckJzsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKHNpZ25hdHVyZVtzaWdwLTFdKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGNvbnRpbnVlOwoKICAgICAgICAgICAgY2FzZSAnLic6CiAgICAgICAgICAgICAgICAvL3dlIGhhdmUgc2VlbiBhbiBlbmNsb3Npbmcgbm9uLWdlbmVyaWMgY2xhc3MKICAgICAgICAgICAgICAgIGlmIChvdXRlciAhPSBUeXBlLm5vVHlwZSkgewogICAgICAgICAgICAgICAgICAgIHQgPSBlbnRlckNsYXNzKG5hbWVzLmZyb21VdGYoc2lnbmF0dXJlQnVmZmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhcnRTYnAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzYnAgLSBzdGFydFNicCkpOwogICAgICAgICAgICAgICAgICAgIG91dGVyID0gbmV3IENsYXNzVHlwZShvdXRlciwgTGlzdC5uaWwoKSwgdCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBzaWduYXR1cmVCdWZmZXJbc2JwKytdID0gKGJ5dGUpJyQnOwogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIGNhc2UgJy8nOgogICAgICAgICAgICAgICAgc2lnbmF0dXJlQnVmZmVyW3NicCsrXSA9IChieXRlKScuJzsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgc2lnbmF0dXJlQnVmZmVyW3NicCsrXSA9IGM7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKiogQ29udmVydCAoaW1wbGljaXQpIHNpZ25hdHVyZSB0byBsaXN0IG9mIHR5cGVzCiAgICAgKiAgdW50aWwgYHRlcm1pbmF0b3InIGlzIGVuY291bnRlcmVkLgogICAgICovCiAgICBMaXN0PFR5cGU+IHNpZ1RvVHlwZXMoY2hhciB0ZXJtaW5hdG9yKSB7CiAgICAgICAgTGlzdDxUeXBlPiBoZWFkID0gTGlzdC5vZihudWxsKTsKICAgICAgICBMaXN0PFR5cGU+IHRhaWwgPSBoZWFkOwogICAgICAgIHdoaWxlIChzaWduYXR1cmVbc2lncF0gIT0gdGVybWluYXRvcikKICAgICAgICAgICAgdGFpbCA9IHRhaWwuc2V0VGFpbChMaXN0Lm9mKHNpZ1RvVHlwZSgpKSk7CiAgICAgICAgc2lncCsrOwogICAgICAgIHJldHVybiBoZWFkLnRhaWw7CiAgICB9CgogICAgLyoqIENvbnZlcnQgc2lnbmF0dXJlIHRvIHR5cGUgcGFyYW1ldGVycywgd2hlcmUgc2lnbmF0dXJlIGlzIGEgYnl0ZQogICAgICogIGFycmF5IHNlZ21lbnQuCiAgICAgKi8KICAgIExpc3Q8VHlwZT4gc2lnVG9UeXBlUGFyYW1zKGJ5dGVbXSBzaWcsIGludCBvZmZzZXQsIGludCBsZW4pIHsKICAgICAgICBzaWduYXR1cmUgPSBzaWc7CiAgICAgICAgc2lncCA9IG9mZnNldDsKICAgICAgICBzaWdsaW1pdCA9IG9mZnNldCArIGxlbjsKICAgICAgICByZXR1cm4gc2lnVG9UeXBlUGFyYW1zKCk7CiAgICB9CgogICAgLyoqIENvbnZlcnQgc2lnbmF0dXJlIHRvIHR5cGUgcGFyYW1ldGVycywgd2hlcmUgc2lnbmF0dXJlIGlzIGltcGxpY2l0LgogICAgICovCiAgICBMaXN0PFR5cGU+IHNpZ1RvVHlwZVBhcmFtcygpIHsKICAgICAgICBMaXN0PFR5cGU+IHR2YXJzID0gTGlzdC5uaWwoKTsKICAgICAgICBpZiAoc2lnbmF0dXJlW3NpZ3BdID09ICc8JykgewogICAgICAgICAgICBzaWdwKys7CiAgICAgICAgICAgIGludCBzdGFydCA9IHNpZ3A7CiAgICAgICAgICAgIHNpZ0VudGVyUGhhc2UgPSB0cnVlOwogICAgICAgICAgICB3aGlsZSAoc2lnbmF0dXJlW3NpZ3BdICE9ICc+JykKICAgICAgICAgICAgICAgIHR2YXJzID0gdHZhcnMucHJlcGVuZChzaWdUb1R5cGVQYXJhbSgpKTsKICAgICAgICAgICAgc2lnRW50ZXJQaGFzZSA9IGZhbHNlOwogICAgICAgICAgICBzaWdwID0gc3RhcnQ7CiAgICAgICAgICAgIHdoaWxlIChzaWduYXR1cmVbc2lncF0gIT0gJz4nKQogICAgICAgICAgICAgICAgc2lnVG9UeXBlUGFyYW0oKTsKICAgICAgICAgICAgc2lncCsrOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdHZhcnMucmV2ZXJzZSgpOwogICAgfQoKICAgIC8qKiBDb252ZXJ0IChpbXBsaWNpdCkgc2lnbmF0dXJlIHRvIHR5cGUgcGFyYW1ldGVyLgogICAgICovCiAgICBUeXBlIHNpZ1RvVHlwZVBhcmFtKCkgewogICAgICAgIGludCBzdGFydCA9IHNpZ3A7CiAgICAgICAgd2hpbGUgKHNpZ25hdHVyZVtzaWdwXSAhPSAnOicpIHNpZ3ArKzsKICAgICAgICBOYW1lIG5hbWUgPSBuYW1lcy5mcm9tVXRmKHNpZ25hdHVyZSwgc3RhcnQsIHNpZ3AgLSBzdGFydCk7CiAgICAgICAgVHlwZVZhciB0dmFyOwogICAgICAgIGlmIChzaWdFbnRlclBoYXNlKSB7CiAgICAgICAgICAgIHR2YXIgPSBuZXcgVHlwZVZhcihuYW1lLCBjdXJyZW50T3duZXIsIHN5bXMuYm90VHlwZSk7CiAgICAgICAgICAgIHR5cGV2YXJzLmVudGVyKHR2YXIudHN5bSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgdHZhciA9IChUeXBlVmFyKWZpbmRUeXBlVmFyKG5hbWUpOwogICAgICAgIH0KICAgICAgICBMaXN0PFR5cGU+IGJvdW5kcyA9IExpc3QubmlsKCk7CiAgICAgICAgYm9vbGVhbiBhbGxJbnRlcmZhY2VzID0gZmFsc2U7CiAgICAgICAgaWYgKHNpZ25hdHVyZVtzaWdwXSA9PSAnOicgJiYgc2lnbmF0dXJlW3NpZ3ArMV0gPT0gJzonKSB7CiAgICAgICAgICAgIHNpZ3ArKzsKICAgICAgICAgICAgYWxsSW50ZXJmYWNlcyA9IHRydWU7CiAgICAgICAgfQogICAgICAgIHdoaWxlIChzaWduYXR1cmVbc2lncF0gPT0gJzonKSB7CiAgICAgICAgICAgIHNpZ3ArKzsKICAgICAgICAgICAgYm91bmRzID0gYm91bmRzLnByZXBlbmQoc2lnVG9UeXBlKCkpOwogICAgICAgIH0KICAgICAgICBpZiAoIXNpZ0VudGVyUGhhc2UpIHsKICAgICAgICAgICAgdHlwZXMuc2V0Qm91bmRzKHR2YXIsIGJvdW5kcy5yZXZlcnNlKCksIGFsbEludGVyZmFjZXMpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdHZhcjsKICAgIH0KCiAgICAvKiogRmluZCB0eXBlIHZhcmlhYmxlIHdpdGggZ2l2ZW4gbmFtZSBpbiBgdHlwZXZhcnMnIHNjb3BlLgogICAgICovCiAgICBUeXBlIGZpbmRUeXBlVmFyKE5hbWUgbmFtZSkgewogICAgICAgIFN5bWJvbCBzID0gdHlwZXZhcnMuZmluZEZpcnN0KG5hbWUpOwogICAgICAgIGlmIChzICE9IG51bGwpIHsKICAgICAgICAgICAgcmV0dXJuIHMudHlwZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBpZiAocmVhZGluZ0NsYXNzQXR0cikgewogICAgICAgICAgICAgICAgLy8gV2hpbGUgcmVhZGluZyB0aGUgY2xhc3MgYXR0cmlidXRlLCB0aGUgc3VwZXJ0eXBlcwogICAgICAgICAgICAgICAgLy8gbWlnaHQgcmVmZXIgdG8gYSB0eXBlIHZhcmlhYmxlIGZyb20gYW4gZW5jbG9zaW5nIGVsZW1lbnQKICAgICAgICAgICAgICAgIC8vIChtZXRob2Qgb3IgY2xhc3MpLgogICAgICAgICAgICAgICAgLy8gSWYgdGhlIHR5cGUgdmFyaWFibGUgaXMgZGVmaW5lZCBpbiB0aGUgZW5jbG9zaW5nIGNsYXNzLAogICAgICAgICAgICAgICAgLy8gd2UgY2FuIGFjdHVhbGx5IGZpbmQgaXQgaW4KICAgICAgICAgICAgICAgIC8vIGN1cnJlbnRPd25lci5vd25lci50eXBlLmdldFR5cGVBcmd1bWVudHMoKQogICAgICAgICAgICAgICAgLy8gSG93ZXZlciwgdW50aWwgd2UgaGF2ZSByZWFkIHRoZSBlbmNsb3NpbmcgbWV0aG9kIGF0dHJpYnV0ZQogICAgICAgICAgICAgICAgLy8gd2UgZG9uJ3Qga25vdyBmb3Igc3VyZSBpZiB0aGlzIG93bmVyIGlzIGNvcnJlY3QuICBJdCBjb3VsZAogICAgICAgICAgICAgICAgLy8gYmUgYSBtZXRob2QgYW5kIHRoZXJlIGlzIG5vIHdheSB0byB0ZWxsIGJlZm9yZSByZWFkaW5nIHRoZQogICAgICAgICAgICAgICAgLy8gZW5jbG9zaW5nIG1ldGhvZCBhdHRyaWJ1dGUuCiAgICAgICAgICAgICAgICBUeXBlVmFyIHQgPSBuZXcgVHlwZVZhcihuYW1lLCBjdXJyZW50T3duZXIsIHN5bXMuYm90VHlwZSk7CiAgICAgICAgICAgICAgICBtaXNzaW5nVHlwZVZhcmlhYmxlcyA9IG1pc3NpbmdUeXBlVmFyaWFibGVzLnByZXBlbmQodCk7CiAgICAgICAgICAgICAgICAvLyBTeXN0ZW0uZXJyLnByaW50bG4oIk1pc3NpbmcgdHlwZSB2YXIgIiArIG5hbWUpOwogICAgICAgICAgICAgICAgcmV0dXJuIHQ7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdGhyb3cgYmFkQ2xhc3NGaWxlKCJ1bmRlY2wudHlwZS52YXIiLCBuYW1lKTsKICAgICAgICB9CiAgICB9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlYWRpbmcgQXR0cmlidXRlcwogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgogICAgcHJvdGVjdGVkIGVudW0gQXR0cmlidXRlS2luZCB7IENMQVNTLCBNRU1CRVIgfQoKICAgIHByb3RlY3RlZCBhYnN0cmFjdCBjbGFzcyBBdHRyaWJ1dGVSZWFkZXIgewogICAgICAgIHByb3RlY3RlZCBBdHRyaWJ1dGVSZWFkZXIoTmFtZSBuYW1lLCBDbGFzc0ZpbGUuVmVyc2lvbiB2ZXJzaW9uLCBTZXQ8QXR0cmlidXRlS2luZD4ga2luZHMpIHsKICAgICAgICAgICAgdGhpcy5uYW1lID0gbmFtZTsKICAgICAgICAgICAgdGhpcy52ZXJzaW9uID0gdmVyc2lvbjsKICAgICAgICAgICAgdGhpcy5raW5kcyA9IGtpbmRzOwogICAgICAgIH0KCiAgICAgICAgcHJvdGVjdGVkIGJvb2xlYW4gYWNjZXB0cyhBdHRyaWJ1dGVLaW5kIGtpbmQpIHsKICAgICAgICAgICAgaWYgKGtpbmRzLmNvbnRhaW5zKGtpbmQpKSB7CiAgICAgICAgICAgICAgICBpZiAobWFqb3JWZXJzaW9uID4gdmVyc2lvbi5tYWpvciB8fCAobWFqb3JWZXJzaW9uID09IHZlcnNpb24ubWFqb3IgJiYgbWlub3JWZXJzaW9uID49IHZlcnNpb24ubWlub3IpKQogICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwoKICAgICAgICAgICAgICAgIGlmIChsaW50Q2xhc3NmaWxlICYmICF3YXJuZWRBdHRycy5jb250YWlucyhuYW1lKSkgewogICAgICAgICAgICAgICAgICAgIEphdmFGaWxlT2JqZWN0IHByZXYgPSBsb2cudXNlU291cmNlKGN1cnJlbnRDbGFzc0ZpbGUpOwogICAgICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGxvZy53YXJuaW5nKExpbnRDYXRlZ29yeS5DTEFTU0ZJTEUsIChEaWFnbm9zdGljUG9zaXRpb24pIG51bGwsICJmdXR1cmUuYXR0ciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSwgdmVyc2lvbi5tYWpvciwgdmVyc2lvbi5taW5vciwgbWFqb3JWZXJzaW9uLCBtaW5vclZlcnNpb24pOwogICAgICAgICAgICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGxvZy51c2VTb3VyY2UocHJldik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHdhcm5lZEF0dHJzLmFkZChuYW1lKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICBwcm90ZWN0ZWQgYWJzdHJhY3Qgdm9pZCByZWFkKFN5bWJvbCBzeW0sIGludCBhdHRyTGVuKTsKCiAgICAgICAgcHJvdGVjdGVkIGZpbmFsIE5hbWUgbmFtZTsKICAgICAgICBwcm90ZWN0ZWQgZmluYWwgQ2xhc3NGaWxlLlZlcnNpb24gdmVyc2lvbjsKICAgICAgICBwcm90ZWN0ZWQgZmluYWwgU2V0PEF0dHJpYnV0ZUtpbmQ+IGtpbmRzOwogICAgfQoKICAgIHByb3RlY3RlZCBTZXQ8QXR0cmlidXRlS2luZD4gQ0xBU1NfQVRUUklCVVRFID0KICAgICAgICAgICAgRW51bVNldC5vZihBdHRyaWJ1dGVLaW5kLkNMQVNTKTsKICAgIHByb3RlY3RlZCBTZXQ8QXR0cmlidXRlS2luZD4gTUVNQkVSX0FUVFJJQlVURSA9CiAgICAgICAgICAgIEVudW1TZXQub2YoQXR0cmlidXRlS2luZC5NRU1CRVIpOwogICAgcHJvdGVjdGVkIFNldDxBdHRyaWJ1dGVLaW5kPiBDTEFTU19PUl9NRU1CRVJfQVRUUklCVVRFID0KICAgICAgICAgICAgRW51bVNldC5vZihBdHRyaWJ1dGVLaW5kLkNMQVNTLCBBdHRyaWJ1dGVLaW5kLk1FTUJFUik7CgogICAgcHJvdGVjdGVkIE1hcDxOYW1lLCBBdHRyaWJ1dGVSZWFkZXI+IGF0dHJpYnV0ZVJlYWRlcnMgPSBuZXcgSGFzaE1hcDw+KCk7CgogICAgcHJpdmF0ZSB2b2lkIGluaXRBdHRyaWJ1dGVSZWFkZXJzKCkgewogICAgICAgIEF0dHJpYnV0ZVJlYWRlcltdIHJlYWRlcnMgPSB7CiAgICAgICAgICAgIC8vIHY0NS4zIGF0dHJpYnV0ZXMKCiAgICAgICAgICAgIG5ldyBBdHRyaWJ1dGVSZWFkZXIobmFtZXMuQ29kZSwgVjQ1XzMsIE1FTUJFUl9BVFRSSUJVVEUpIHsKICAgICAgICAgICAgICAgIHByb3RlY3RlZCB2b2lkIHJlYWQoU3ltYm9sIHN5bSwgaW50IGF0dHJMZW4pIHsKICAgICAgICAgICAgICAgICAgICBpZiAocmVhZEFsbE9mQ2xhc3NGaWxlIHx8IHNhdmVQYXJhbWV0ZXJOYW1lcykKICAgICAgICAgICAgICAgICAgICAgICAgKChNZXRob2RTeW1ib2wpc3ltKS5jb2RlID0gcmVhZENvZGUoc3ltKTsKICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIGJwID0gYnAgKyBhdHRyTGVuOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAoKICAgICAgICAgICAgbmV3IEF0dHJpYnV0ZVJlYWRlcihuYW1lcy5Db25zdGFudFZhbHVlLCBWNDVfMywgTUVNQkVSX0FUVFJJQlVURSkgewogICAgICAgICAgICAgICAgcHJvdGVjdGVkIHZvaWQgcmVhZChTeW1ib2wgc3ltLCBpbnQgYXR0ckxlbikgewogICAgICAgICAgICAgICAgICAgIE9iamVjdCB2ID0gcmVhZFBvb2wobmV4dENoYXIoKSk7CiAgICAgICAgICAgICAgICAgICAgLy8gSWdub3JlIENvbnN0YW50VmFsdWUgYXR0cmlidXRlIGlmIGZpZWxkIG5vdCBmaW5hbC4KICAgICAgICAgICAgICAgICAgICBpZiAoKHN5bS5mbGFncygpICYgRklOQUwpID09IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBWYXJTeW1ib2wgdmFyID0gKFZhclN5bWJvbCkgc3ltOwogICAgICAgICAgICAgICAgICAgIHN3aXRjaCAodmFyLnR5cGUuZ2V0VGFnKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICBjYXNlIEJPT0xFQU46CiAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBCWVRFOgogICAgICAgICAgICAgICAgICAgICAgIGNhc2UgQ0hBUjoKICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFNIT1JUOgogICAgICAgICAgICAgICAgICAgICAgIGNhc2UgSU5UOgogICAgICAgICAgICAgICAgICAgICAgICAgICBjaGVja1R5cGUodmFyLCBJbnRlZ2VyLmNsYXNzLCB2KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBMT05HOgogICAgICAgICAgICAgICAgICAgICAgICAgICBjaGVja1R5cGUodmFyLCBMb25nLmNsYXNzLCB2KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBGTE9BVDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tUeXBlKHZhciwgRmxvYXQuY2xhc3MsIHYpOwogICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICBjYXNlIERPVUJMRToKICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tUeXBlKHZhciwgRG91YmxlLmNsYXNzLCB2KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBDTEFTUzoKICAgICAgICAgICAgICAgICAgICAgICAgICAgQXNzZXJ0LmNoZWNrKHZhci50eXBlLnRzeW0gPT0gc3ltcy5zdHJpbmdUeXBlLnRzeW0pOwogICAgICAgICAgICAgICAgICAgICAgICAgICBjaGVja1R5cGUodmFyLCBTdHJpbmcuY2xhc3MsIHYpOwogICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpZ25vcmUgQ29uc3RhbnRWYWx1ZSBhdHRyaWJ1dGUgaWYgdHlwZSBpcyBub3QgcHJpbWl0aXZlIG9yIFN0cmluZwogICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmICh2IGluc3RhbmNlb2YgSW50ZWdlciAmJiAhdmFyLnR5cGUuZ2V0VGFnKCkuY2hlY2tSYW5nZSgoSW50ZWdlcikgdikpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgYmFkQ2xhc3NGaWxlKCJiYWQuY29uc3RhbnQucmFuZ2UiLCB2LCB2YXIsIHZhci50eXBlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgdmFyLnNldERhdGEodik7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgdm9pZCBjaGVja1R5cGUoU3ltYm9sIHZhciwgQ2xhc3M8Pz4gY2xhenosIE9iamVjdCB2YWx1ZSkgewogICAgICAgICAgICAgICAgICAgIGlmICghY2xhenouaXNJbnN0YW5jZSh2YWx1ZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgYmFkQ2xhc3NGaWxlKCJiYWQuY29uc3RhbnQudmFsdWUiLCB2YWx1ZSwgdmFyLCBjbGF6ei5nZXRTaW1wbGVOYW1lKCkpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIG5ldyBBdHRyaWJ1dGVSZWFkZXIobmFtZXMuRGVwcmVjYXRlZCwgVjQ1XzMsIENMQVNTX09SX01FTUJFUl9BVFRSSUJVVEUpIHsKICAgICAgICAgICAgICAgIHByb3RlY3RlZCB2b2lkIHJlYWQoU3ltYm9sIHN5bSwgaW50IGF0dHJMZW4pIHsKICAgICAgICAgICAgICAgICAgICBTeW1ib2wgcyA9IHN5bS5vd25lci5raW5kID09IE1ETCA/IHN5bS5vd25lciA6IHN5bTsKCiAgICAgICAgICAgICAgICAgICAgcy5mbGFnc19maWVsZCB8PSBERVBSRUNBVEVEOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAoKICAgICAgICAgICAgbmV3IEF0dHJpYnV0ZVJlYWRlcihuYW1lcy5FeGNlcHRpb25zLCBWNDVfMywgQ0xBU1NfT1JfTUVNQkVSX0FUVFJJQlVURSkgewogICAgICAgICAgICAgICAgcHJvdGVjdGVkIHZvaWQgcmVhZChTeW1ib2wgc3ltLCBpbnQgYXR0ckxlbikgewogICAgICAgICAgICAgICAgICAgIGludCBuZXhjZXB0aW9ucyA9IG5leHRDaGFyKCk7CiAgICAgICAgICAgICAgICAgICAgTGlzdDxUeXBlPiB0aHJvd24gPSBMaXN0Lm5pbCgpOwogICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgbmV4Y2VwdGlvbnM7IGorKykKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3duID0gdGhyb3duLnByZXBlbmQocmVhZENsYXNzU3ltYm9sKG5leHRDaGFyKCkpLnR5cGUpOwogICAgICAgICAgICAgICAgICAgIGlmIChzeW0udHlwZS5nZXRUaHJvd25UeXBlcygpLmlzRW1wdHkoKSkKICAgICAgICAgICAgICAgICAgICAgICAgc3ltLnR5cGUuYXNNZXRob2RUeXBlKCkudGhyb3duID0gdGhyb3duLnJldmVyc2UoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIG5ldyBBdHRyaWJ1dGVSZWFkZXIobmFtZXMuSW5uZXJDbGFzc2VzLCBWNDVfMywgQ0xBU1NfQVRUUklCVVRFKSB7CiAgICAgICAgICAgICAgICBwcm90ZWN0ZWQgdm9pZCByZWFkKFN5bWJvbCBzeW0sIGludCBhdHRyTGVuKSB7CiAgICAgICAgICAgICAgICAgICAgQ2xhc3NTeW1ib2wgYyA9IChDbGFzc1N5bWJvbCkgc3ltOwogICAgICAgICAgICAgICAgICAgIGlmIChjdXJyZW50TW9kdWxlLm1vZHVsZV9pbmZvID09IGMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy9wcmV2ZW50IGVudGVyaW5nIHRoZSBjbGFzc2VzIHRvbyBzb29uOgogICAgICAgICAgICAgICAgICAgICAgICBza2lwSW5uZXJDbGFzc2VzKCk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmVhZElubmVyQ2xhc3NlcyhjKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICBuZXcgQXR0cmlidXRlUmVhZGVyKG5hbWVzLkxvY2FsVmFyaWFibGVUYWJsZSwgVjQ1XzMsIENMQVNTX09SX01FTUJFUl9BVFRSSUJVVEUpIHsKICAgICAgICAgICAgICAgIHByb3RlY3RlZCB2b2lkIHJlYWQoU3ltYm9sIHN5bSwgaW50IGF0dHJMZW4pIHsKICAgICAgICAgICAgICAgICAgICBpbnQgbmV3YnAgPSBicCArIGF0dHJMZW47CiAgICAgICAgICAgICAgICAgICAgaWYgKHNhdmVQYXJhbWV0ZXJOYW1lcyAmJiAhc2F3TWV0aG9kUGFyYW1ldGVycykgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBQaWNrIHVwIHBhcmFtZXRlciBuYW1lcyBmcm9tIHRoZSB2YXJpYWJsZSB0YWJsZS4KICAgICAgICAgICAgICAgICAgICAgICAgLy8gUGFyYW1ldGVyIG5hbWVzIGFyZSBub3QgZXhwbGljaXRseSBpZGVudGlmaWVkIGFzIHN1Y2gsCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGJ1dCBhbGwgcGFyYW1ldGVyIG5hbWUgZW50cmllcyBpbiB0aGUgTG9jYWxWYXJpYWJsZVRhYmxlCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGhhdmUgYSBzdGFydF9wYyBvZiAwLiAgVGhlcmVmb3JlLCB3ZSByZWNvcmQgdGhlIG5hbWUKICAgICAgICAgICAgICAgICAgICAgICAgLy8gaW5kaWNpZXMgb2YgYWxsIHNsb3RzIHdpdGggYSBzdGFydF9wYyBvZiB6ZXJvIGluIHRoZQogICAgICAgICAgICAgICAgICAgICAgICAvLyBwYXJhbWV0ZXJOYW1lSW5kaWNpZXMgYXJyYXkuCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIE5vdGUgdGhhdCB0aGlzIGltcGxpY2l0bHkgaG9ub3JzIHRoZSBKVk1TIHNwZWMgdGhhdAogICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGVyZSBtYXkgYmUgbW9yZSB0aGFuIG9uZSBMb2NhbFZhcmlhYmxlVGFibGUsIGFuZCB0aGF0CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRoZXJlIGlzIG5vIHNwZWNpZmllZCBvcmRlcmluZyBmb3IgdGhlIGVudHJpZXMuCiAgICAgICAgICAgICAgICAgICAgICAgIGludCBudW1FbnRyaWVzID0gbmV4dENoYXIoKTsKICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBudW1FbnRyaWVzOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBzdGFydF9wYyA9IG5leHRDaGFyKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gbmV4dENoYXIoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBuYW1lSW5kZXggPSBuZXh0Q2hhcigpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHNpZ0luZGV4ID0gbmV4dENoYXIoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCByZWdpc3RlciA9IG5leHRDaGFyKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3RhcnRfcGMgPT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGVuc3VyZSBhcnJheSBsYXJnZSBlbm91Z2gKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVnaXN0ZXIgPj0gcGFyYW1ldGVyTmFtZUluZGljZXMubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBuZXdTaXplID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYXRoLm1heChyZWdpc3RlciArIDEsIHBhcmFtZXRlck5hbWVJbmRpY2VzLmxlbmd0aCArIDgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJhbWV0ZXJOYW1lSW5kaWNlcyA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXJyYXlzLmNvcHlPZihwYXJhbWV0ZXJOYW1lSW5kaWNlcywgbmV3U2l6ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtZXRlck5hbWVJbmRpY2VzW3JlZ2lzdGVyXSA9IG5hbWVJbmRleDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoYXZlUGFyYW1ldGVyTmFtZUluZGljZXMgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJwID0gbmV3YnA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICBuZXcgQXR0cmlidXRlUmVhZGVyKG5hbWVzLlNvdXJjZUZpbGUsIFY0NV8zLCBDTEFTU19BVFRSSUJVVEUpIHsKICAgICAgICAgICAgICAgIHByb3RlY3RlZCB2b2lkIHJlYWQoU3ltYm9sIHN5bSwgaW50IGF0dHJMZW4pIHsKICAgICAgICAgICAgICAgICAgICBDbGFzc1N5bWJvbCBjID0gKENsYXNzU3ltYm9sKSBzeW07CiAgICAgICAgICAgICAgICAgICAgTmFtZSBuID0gcmVhZE5hbWUobmV4dENoYXIoKSk7CiAgICAgICAgICAgICAgICAgICAgYy5zb3VyY2VmaWxlID0gbmV3IFNvdXJjZUZpbGVPYmplY3QobiwgYy5mbGF0bmFtZSk7CiAgICAgICAgICAgICAgICAgICAgLy8gSWYgdGhlIGNsYXNzIGlzIGEgdG9wbGV2ZWwgY2xhc3MsIG9yaWdpbmF0aW5nIGZyb20gYSBKYXZhIHNvdXJjZSBmaWxlLAogICAgICAgICAgICAgICAgICAgIC8vIGJ1dCB0aGUgY2xhc3MgbmFtZSBkb2VzIG5vdCBtYXRjaCB0aGUgZmlsZSBuYW1lLCB0aGVuIGl0IGlzCiAgICAgICAgICAgICAgICAgICAgLy8gYW4gYXV4aWxpYXJ5IGNsYXNzLgogICAgICAgICAgICAgICAgICAgIFN0cmluZyBzbiA9IG4udG9TdHJpbmcoKTsKICAgICAgICAgICAgICAgICAgICBpZiAoYy5vd25lci5raW5kID09IFBDSyAmJgogICAgICAgICAgICAgICAgICAgICAgICBzbi5lbmRzV2l0aCgiLmphdmEiKSAmJgogICAgICAgICAgICAgICAgICAgICAgICAhc24uZXF1YWxzKGMubmFtZS50b1N0cmluZygpKyIuamF2YSIpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGMuZmxhZ3NfZmllbGQgfD0gQVVYSUxJQVJZOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIG5ldyBBdHRyaWJ1dGVSZWFkZXIobmFtZXMuU3ludGhldGljLCBWNDVfMywgQ0xBU1NfT1JfTUVNQkVSX0FUVFJJQlVURSkgewogICAgICAgICAgICAgICAgcHJvdGVjdGVkIHZvaWQgcmVhZChTeW1ib2wgc3ltLCBpbnQgYXR0ckxlbikgewogICAgICAgICAgICAgICAgICAgIHN5bS5mbGFnc19maWVsZCB8PSBTWU5USEVUSUM7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICAvLyBzdGFuZGFyZCB2NDkgYXR0cmlidXRlcwoKICAgICAgICAgICAgbmV3IEF0dHJpYnV0ZVJlYWRlcihuYW1lcy5FbmNsb3NpbmdNZXRob2QsIFY0OSwgQ0xBU1NfQVRUUklCVVRFKSB7CiAgICAgICAgICAgICAgICBwcm90ZWN0ZWQgdm9pZCByZWFkKFN5bWJvbCBzeW0sIGludCBhdHRyTGVuKSB7CiAgICAgICAgICAgICAgICAgICAgaW50IG5ld2JwID0gYnAgKyBhdHRyTGVuOwogICAgICAgICAgICAgICAgICAgIHJlYWRFbmNsb3NpbmdNZXRob2RBdHRyKHN5bSk7CiAgICAgICAgICAgICAgICAgICAgYnAgPSBuZXdicDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIG5ldyBBdHRyaWJ1dGVSZWFkZXIobmFtZXMuU2lnbmF0dXJlLCBWNDksIENMQVNTX09SX01FTUJFUl9BVFRSSUJVVEUpIHsKICAgICAgICAgICAgICAgIHByb3RlY3RlZCB2b2lkIHJlYWQoU3ltYm9sIHN5bSwgaW50IGF0dHJMZW4pIHsKICAgICAgICAgICAgICAgICAgICBpZiAoc3ltLmtpbmQgPT0gVFlQKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIENsYXNzU3ltYm9sIGMgPSAoQ2xhc3NTeW1ib2wpIHN5bTsKICAgICAgICAgICAgICAgICAgICAgICAgcmVhZGluZ0NsYXNzQXR0ciA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBDbGFzc1R5cGUgY3QxID0gKENsYXNzVHlwZSljLnR5cGU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBBc3NlcnQuY2hlY2soYyA9PSBjdXJyZW50T3duZXIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgY3QxLnR5cGFyYW1zX2ZpZWxkID0gcmVhZFR5cGVQYXJhbXMobmV4dENoYXIoKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdDEuc3VwZXJ0eXBlX2ZpZWxkID0gc2lnVG9UeXBlKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0QnVmZmVyPFR5cGU+IGlzID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHNpZ3AgIT0gc2lnbGltaXQpIGlzLmFwcGVuZChzaWdUb1R5cGUoKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdDEuaW50ZXJmYWNlc19maWVsZCA9IGlzLnRvTGlzdCgpOwogICAgICAgICAgICAgICAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVhZGluZ0NsYXNzQXR0ciA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgTGlzdDxUeXBlPiB0aHJvd24gPSBzeW0udHlwZS5nZXRUaHJvd25UeXBlcygpOwogICAgICAgICAgICAgICAgICAgICAgICBzeW0udHlwZSA9IHJlYWRUeXBlKG5leHRDaGFyKCkpOwogICAgICAgICAgICAgICAgICAgICAgICAvLy0gU3lzdGVtLmVyci5wcmludGxuKCIgIyAiICsgc3ltLnR5cGUpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3ltLmtpbmQgPT0gTVRIICYmIHN5bS50eXBlLmdldFRocm93blR5cGVzKCkuaXNFbXB0eSgpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ltLnR5cGUuYXNNZXRob2RUeXBlKCkudGhyb3duID0gdGhyb3duOwoKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICAvLyB2NDkgYW5ub3RhdGlvbiBhdHRyaWJ1dGVzCgogICAgICAgICAgICBuZXcgQXR0cmlidXRlUmVhZGVyKG5hbWVzLkFubm90YXRpb25EZWZhdWx0LCBWNDksIENMQVNTX09SX01FTUJFUl9BVFRSSUJVVEUpIHsKICAgICAgICAgICAgICAgIHByb3RlY3RlZCB2b2lkIHJlYWQoU3ltYm9sIHN5bSwgaW50IGF0dHJMZW4pIHsKICAgICAgICAgICAgICAgICAgICBhdHRhY2hBbm5vdGF0aW9uRGVmYXVsdChzeW0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAoKICAgICAgICAgICAgbmV3IEF0dHJpYnV0ZVJlYWRlcihuYW1lcy5SdW50aW1lSW52aXNpYmxlQW5ub3RhdGlvbnMsIFY0OSwgQ0xBU1NfT1JfTUVNQkVSX0FUVFJJQlVURSkgewogICAgICAgICAgICAgICAgcHJvdGVjdGVkIHZvaWQgcmVhZChTeW1ib2wgc3ltLCBpbnQgYXR0ckxlbikgewogICAgICAgICAgICAgICAgICAgIGF0dGFjaEFubm90YXRpb25zKHN5bSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICBuZXcgQXR0cmlidXRlUmVhZGVyKG5hbWVzLlJ1bnRpbWVJbnZpc2libGVQYXJhbWV0ZXJBbm5vdGF0aW9ucywgVjQ5LCBDTEFTU19PUl9NRU1CRVJfQVRUUklCVVRFKSB7CiAgICAgICAgICAgICAgICBwcm90ZWN0ZWQgdm9pZCByZWFkKFN5bWJvbCBzeW0sIGludCBhdHRyTGVuKSB7CiAgICAgICAgICAgICAgICAgICAgYXR0YWNoUGFyYW1ldGVyQW5ub3RhdGlvbnMoc3ltKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIG5ldyBBdHRyaWJ1dGVSZWFkZXIobmFtZXMuUnVudGltZVZpc2libGVBbm5vdGF0aW9ucywgVjQ5LCBDTEFTU19PUl9NRU1CRVJfQVRUUklCVVRFKSB7CiAgICAgICAgICAgICAgICBwcm90ZWN0ZWQgdm9pZCByZWFkKFN5bWJvbCBzeW0sIGludCBhdHRyTGVuKSB7CiAgICAgICAgICAgICAgICAgICAgYXR0YWNoQW5ub3RhdGlvbnMoc3ltKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIG5ldyBBdHRyaWJ1dGVSZWFkZXIobmFtZXMuUnVudGltZVZpc2libGVQYXJhbWV0ZXJBbm5vdGF0aW9ucywgVjQ5LCBDTEFTU19PUl9NRU1CRVJfQVRUUklCVVRFKSB7CiAgICAgICAgICAgICAgICBwcm90ZWN0ZWQgdm9pZCByZWFkKFN5bWJvbCBzeW0sIGludCBhdHRyTGVuKSB7CiAgICAgICAgICAgICAgICAgICAgYXR0YWNoUGFyYW1ldGVyQW5ub3RhdGlvbnMoc3ltKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIC8vIGFkZGl0aW9uYWwgImxlZ2FjeSIgdjQ5IGF0dHJpYnV0ZXMsIHN1cGVyY2VkZWQgYnkgZmxhZ3MKCiAgICAgICAgICAgIG5ldyBBdHRyaWJ1dGVSZWFkZXIobmFtZXMuQW5ub3RhdGlvbiwgVjQ5LCBDTEFTU19PUl9NRU1CRVJfQVRUUklCVVRFKSB7CiAgICAgICAgICAgICAgICBwcm90ZWN0ZWQgdm9pZCByZWFkKFN5bWJvbCBzeW0sIGludCBhdHRyTGVuKSB7CiAgICAgICAgICAgICAgICAgICAgc3ltLmZsYWdzX2ZpZWxkIHw9IEFOTk9UQVRJT047CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICBuZXcgQXR0cmlidXRlUmVhZGVyKG5hbWVzLkJyaWRnZSwgVjQ5LCBNRU1CRVJfQVRUUklCVVRFKSB7CiAgICAgICAgICAgICAgICBwcm90ZWN0ZWQgdm9pZCByZWFkKFN5bWJvbCBzeW0sIGludCBhdHRyTGVuKSB7CiAgICAgICAgICAgICAgICAgICAgc3ltLmZsYWdzX2ZpZWxkIHw9IEJSSURHRTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIG5ldyBBdHRyaWJ1dGVSZWFkZXIobmFtZXMuRW51bSwgVjQ5LCBDTEFTU19PUl9NRU1CRVJfQVRUUklCVVRFKSB7CiAgICAgICAgICAgICAgICBwcm90ZWN0ZWQgdm9pZCByZWFkKFN5bWJvbCBzeW0sIGludCBhdHRyTGVuKSB7CiAgICAgICAgICAgICAgICAgICAgc3ltLmZsYWdzX2ZpZWxkIHw9IEVOVU07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICBuZXcgQXR0cmlidXRlUmVhZGVyKG5hbWVzLlZhcmFyZ3MsIFY0OSwgQ0xBU1NfT1JfTUVNQkVSX0FUVFJJQlVURSkgewogICAgICAgICAgICAgICAgcHJvdGVjdGVkIHZvaWQgcmVhZChTeW1ib2wgc3ltLCBpbnQgYXR0ckxlbikgewogICAgICAgICAgICAgICAgICAgIHN5bS5mbGFnc19maWVsZCB8PSBWQVJBUkdTOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAoKICAgICAgICAgICAgbmV3IEF0dHJpYnV0ZVJlYWRlcihuYW1lcy5SdW50aW1lVmlzaWJsZVR5cGVBbm5vdGF0aW9ucywgVjUyLCBDTEFTU19PUl9NRU1CRVJfQVRUUklCVVRFKSB7CiAgICAgICAgICAgICAgICBwcm90ZWN0ZWQgdm9pZCByZWFkKFN5bWJvbCBzeW0sIGludCBhdHRyTGVuKSB7CiAgICAgICAgICAgICAgICAgICAgYXR0YWNoVHlwZUFubm90YXRpb25zKHN5bSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICBuZXcgQXR0cmlidXRlUmVhZGVyKG5hbWVzLlJ1bnRpbWVJbnZpc2libGVUeXBlQW5ub3RhdGlvbnMsIFY1MiwgQ0xBU1NfT1JfTUVNQkVSX0FUVFJJQlVURSkgewogICAgICAgICAgICAgICAgcHJvdGVjdGVkIHZvaWQgcmVhZChTeW1ib2wgc3ltLCBpbnQgYXR0ckxlbikgewogICAgICAgICAgICAgICAgICAgIGF0dGFjaFR5cGVBbm5vdGF0aW9ucyhzeW0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAoKICAgICAgICAgICAgLy8gVGhlIGZvbGxvd2luZyBhdHRyaWJ1dGVzIGZvciBhIENvZGUgYXR0cmlidXRlIGFyZSBub3QgY3VycmVudGx5IGhhbmRsZWQKICAgICAgICAgICAgLy8gU3RhY2tNYXBUYWJsZQogICAgICAgICAgICAvLyBTb3VyY2VEZWJ1Z0V4dGVuc2lvbgogICAgICAgICAgICAvLyBMaW5lTnVtYmVyVGFibGUKICAgICAgICAgICAgLy8gTG9jYWxWYXJpYWJsZVR5cGVUYWJsZQoKICAgICAgICAgICAgLy8gc3RhbmRhcmQgdjUyIGF0dHJpYnV0ZXMKCiAgICAgICAgICAgIG5ldyBBdHRyaWJ1dGVSZWFkZXIobmFtZXMuTWV0aG9kUGFyYW1ldGVycywgVjUyLCBNRU1CRVJfQVRUUklCVVRFKSB7CiAgICAgICAgICAgICAgICBwcm90ZWN0ZWQgdm9pZCByZWFkKFN5bWJvbCBzeW0sIGludCBhdHRybGVuKSB7CiAgICAgICAgICAgICAgICAgICAgaW50IG5ld2JwID0gYnAgKyBhdHRybGVuOwogICAgICAgICAgICAgICAgICAgIGlmIChzYXZlUGFyYW1ldGVyTmFtZXMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgc2F3TWV0aG9kUGFyYW1ldGVycyA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIGludCBudW1FbnRyaWVzID0gbmV4dEJ5dGUoKTsKICAgICAgICAgICAgICAgICAgICAgICAgcGFyYW1ldGVyTmFtZUluZGljZXMgPSBuZXcgaW50W251bUVudHJpZXNdOwogICAgICAgICAgICAgICAgICAgICAgICBoYXZlUGFyYW1ldGVyTmFtZUluZGljZXMgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bUVudHJpZXM7IGkrKykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IG5hbWVJbmRleCA9IG5leHRDaGFyKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgZmxhZ3MgPSBuZXh0Q2hhcigpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyYW1ldGVyTmFtZUluZGljZXNbaV0gPSBuYW1lSW5kZXg7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnAgPSBuZXdicDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIC8vIHN0YW5kYXJkIHY1MyBhdHRyaWJ1dGVzCgogICAgICAgICAgICBuZXcgQXR0cmlidXRlUmVhZGVyKG5hbWVzLk1vZHVsZSwgVjUzLCBDTEFTU19BVFRSSUJVVEUpIHsKICAgICAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICAgICAgcHJvdGVjdGVkIGJvb2xlYW4gYWNjZXB0cyhBdHRyaWJ1dGVLaW5kIGtpbmQpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3VwZXIuYWNjZXB0cyhraW5kKSAmJiBhbGxvd01vZHVsZXM7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBwcm90ZWN0ZWQgdm9pZCByZWFkKFN5bWJvbCBzeW0sIGludCBhdHRyTGVuKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHN5bS5raW5kID09IFRZUCAmJiBzeW0ub3duZXIua2luZCA9PSBNREwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgTW9kdWxlU3ltYm9sIG1zeW0gPSAoTW9kdWxlU3ltYm9sKSBzeW0ub3duZXI7CiAgICAgICAgICAgICAgICAgICAgICAgIExpc3RCdWZmZXI8RGlyZWN0aXZlPiBkaXJlY3RpdmVzID0gbmV3IExpc3RCdWZmZXI8PigpOwoKICAgICAgICAgICAgICAgICAgICAgICAgTmFtZSBtb2R1bGVOYW1lID0gcmVhZE1vZHVsZU5hbWUobmV4dENoYXIoKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjdXJyZW50TW9kdWxlLm5hbWUgIT0gbW9kdWxlTmFtZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgYmFkQ2xhc3NGaWxlKCJtb2R1bGUubmFtZS5taXNtYXRjaCIsIG1vZHVsZU5hbWUsIGN1cnJlbnRNb2R1bGUubmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIG1zeW0uZmxhZ3MuYWRkQWxsKHJlYWRNb2R1bGVGbGFncyhuZXh0Q2hhcigpKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIG1zeW0udmVyc2lvbiA9IHJlYWROYW1lKG5leHRDaGFyKCkpOwoKICAgICAgICAgICAgICAgICAgICAgICAgTGlzdEJ1ZmZlcjxSZXF1aXJlc0RpcmVjdGl2ZT4gcmVxdWlyZXMgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGludCBucmVxdWlyZXMgPSBuZXh0Q2hhcigpOwogICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG5yZXF1aXJlczsgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBNb2R1bGVTeW1ib2wgcnN5bSA9IHN5bXMuZW50ZXJNb2R1bGUocmVhZE1vZHVsZU5hbWUobmV4dENoYXIoKSkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgU2V0PFJlcXVpcmVzRmxhZz4gZmxhZ3MgPSByZWFkUmVxdWlyZXNGbGFncyhuZXh0Q2hhcigpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5leHRDaGFyKCk7IC8vIHNraXAgY29tcGlsZWQgdmVyc2lvbgogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWlyZXMuYWRkKG5ldyBSZXF1aXJlc0RpcmVjdGl2ZShyc3ltLCBmbGFncykpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIG1zeW0ucmVxdWlyZXMgPSByZXF1aXJlcy50b0xpc3QoKTsKICAgICAgICAgICAgICAgICAgICAgICAgZGlyZWN0aXZlcy5hZGRBbGwobXN5bS5yZXF1aXJlcyk7CgogICAgICAgICAgICAgICAgICAgICAgICBMaXN0QnVmZmVyPEV4cG9ydHNEaXJlY3RpdmU+IGV4cG9ydHMgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGludCBuZXhwb3J0cyA9IG5leHRDaGFyKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbmV4cG9ydHM7IGkrKykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgTmFtZSBuID0gcmVhZE5hbWUobmV4dENoYXIoKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBQYWNrYWdlU3ltYm9sIHAgPSBzeW1zLmVudGVyUGFja2FnZShjdXJyZW50TW9kdWxlLCBuYW1lcy5mcm9tVXRmKGludGVybmFsaXplKG4pKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBTZXQ8RXhwb3J0c0ZsYWc+IGZsYWdzID0gcmVhZEV4cG9ydHNGbGFncyhuZXh0Q2hhcigpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBudG8gPSBuZXh0Q2hhcigpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgTGlzdDxNb2R1bGVTeW1ib2w+IHRvOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG50byA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG8gPSBudWxsOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0QnVmZmVyPE1vZHVsZVN5bWJvbD4gbGIgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgdCA9IDA7IHQgPCBudG87IHQrKykKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGIuYXBwZW5kKHN5bXMuZW50ZXJNb2R1bGUocmVhZE1vZHVsZU5hbWUobmV4dENoYXIoKSkpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0byA9IGxiLnRvTGlzdCgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhwb3J0cy5hZGQobmV3IEV4cG9ydHNEaXJlY3RpdmUocCwgdG8sIGZsYWdzKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgbXN5bS5leHBvcnRzID0gZXhwb3J0cy50b0xpc3QoKTsKICAgICAgICAgICAgICAgICAgICAgICAgZGlyZWN0aXZlcy5hZGRBbGwobXN5bS5leHBvcnRzKTsKICAgICAgICAgICAgICAgICAgICAgICAgTGlzdEJ1ZmZlcjxPcGVuc0RpcmVjdGl2ZT4gb3BlbnMgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGludCBub3BlbnMgPSBuZXh0Q2hhcigpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAobm9wZW5zICE9IDAgJiYgbXN5bS5mbGFncy5jb250YWlucyhNb2R1bGVGbGFncy5PUEVOKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgYmFkQ2xhc3NGaWxlKCJtb2R1bGUubm9uLnplcm8ub3BlbnMiLCBjdXJyZW50TW9kdWxlLm5hbWUpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbm9wZW5zOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5hbWUgbiA9IHJlYWROYW1lKG5leHRDaGFyKCkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgUGFja2FnZVN5bWJvbCBwID0gc3ltcy5lbnRlclBhY2thZ2UoY3VycmVudE1vZHVsZSwgbmFtZXMuZnJvbVV0ZihpbnRlcm5hbGl6ZShuKSkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgU2V0PE9wZW5zRmxhZz4gZmxhZ3MgPSByZWFkT3BlbnNGbGFncyhuZXh0Q2hhcigpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBudG8gPSBuZXh0Q2hhcigpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgTGlzdDxNb2R1bGVTeW1ib2w+IHRvOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG50byA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG8gPSBudWxsOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0QnVmZmVyPE1vZHVsZVN5bWJvbD4gbGIgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgdCA9IDA7IHQgPCBudG87IHQrKykKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGIuYXBwZW5kKHN5bXMuZW50ZXJNb2R1bGUocmVhZE1vZHVsZU5hbWUobmV4dENoYXIoKSkpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0byA9IGxiLnRvTGlzdCgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgb3BlbnMuYWRkKG5ldyBPcGVuc0RpcmVjdGl2ZShwLCB0bywgZmxhZ3MpKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBtc3ltLm9wZW5zID0gb3BlbnMudG9MaXN0KCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGRpcmVjdGl2ZXMuYWRkQWxsKG1zeW0ub3BlbnMpOwoKICAgICAgICAgICAgICAgICAgICAgICAgbXN5bS5kaXJlY3RpdmVzID0gZGlyZWN0aXZlcy50b0xpc3QoKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIExpc3RCdWZmZXI8SW50ZXJpbVVzZXNEaXJlY3RpdmU+IHVzZXMgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGludCBudXNlcyA9IG5leHRDaGFyKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnVzZXM7IGkrKykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgTmFtZSBzcnZjID0gcmVhZENsYXNzTmFtZShuZXh0Q2hhcigpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVzZXMuYWRkKG5ldyBJbnRlcmltVXNlc0RpcmVjdGl2ZShzcnZjKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgaW50ZXJpbVVzZXMgPSB1c2VzLnRvTGlzdCgpOwoKICAgICAgICAgICAgICAgICAgICAgICAgTGlzdEJ1ZmZlcjxJbnRlcmltUHJvdmlkZXNEaXJlY3RpdmU+IHByb3ZpZGVzID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgICAgICAgICAgICAgICAgICBpbnQgbnByb3ZpZGVzID0gbmV4dENoYXIoKTsKICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgcCA9IDA7IHAgPCBucHJvdmlkZXM7IHArKykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgTmFtZSBzcnZjID0gcmVhZENsYXNzTmFtZShuZXh0Q2hhcigpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBuaW1wbHMgPSBuZXh0Q2hhcigpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgTGlzdEJ1ZmZlcjxOYW1lPiBpbXBscyA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbmltcGxzOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbXBscy5hcHBlbmQocmVhZENsYXNzTmFtZShuZXh0Q2hhcigpKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm92aWRlcy5hZGQobmV3IEludGVyaW1Qcm92aWRlc0RpcmVjdGl2ZShzcnZjLCBpbXBscy50b0xpc3QoKSkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGludGVyaW1Qcm92aWRlcyA9IHByb3ZpZGVzLnRvTGlzdCgpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIG5ldyBBdHRyaWJ1dGVSZWFkZXIobmFtZXMuTW9kdWxlUmVzb2x1dGlvbiwgVjUzLCBDTEFTU19BVFRSSUJVVEUpIHsKICAgICAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICAgICAgcHJvdGVjdGVkIGJvb2xlYW4gYWNjZXB0cyhBdHRyaWJ1dGVLaW5kIGtpbmQpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3VwZXIuYWNjZXB0cyhraW5kKSAmJiBhbGxvd01vZHVsZXM7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBwcm90ZWN0ZWQgdm9pZCByZWFkKFN5bWJvbCBzeW0sIGludCBhdHRyTGVuKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHN5bS5raW5kID09IFRZUCAmJiBzeW0ub3duZXIua2luZCA9PSBNREwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgTW9kdWxlU3ltYm9sIG1zeW0gPSAoTW9kdWxlU3ltYm9sKSBzeW0ub3duZXI7CiAgICAgICAgICAgICAgICAgICAgICAgIG1zeW0ucmVzb2x1dGlvbkZsYWdzLmFkZEFsbChyZWFkTW9kdWxlUmVzb2x1dGlvbkZsYWdzKG5leHRDaGFyKCkpKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCiAgICAgICAgfTsKCiAgICAgICAgZm9yIChBdHRyaWJ1dGVSZWFkZXIgcjogcmVhZGVycykKICAgICAgICAgICAgYXR0cmlidXRlUmVhZGVycy5wdXQoci5uYW1lLCByKTsKICAgIH0KCiAgICBwcm90ZWN0ZWQgdm9pZCByZWFkRW5jbG9zaW5nTWV0aG9kQXR0cihTeW1ib2wgc3ltKSB7CiAgICAgICAgLy8gc3ltIGlzIGEgbmVzdGVkIGNsYXNzIHdpdGggYW4gIkVuY2xvc2luZyBNZXRob2QiIGF0dHJpYnV0ZQogICAgICAgIC8vIHJlbW92ZSBzeW0gZnJvbSBpdCdzIGN1cnJlbnQgb3duZXJzIHNjb3BlIGFuZCBwbGFjZSBpdCBpbgogICAgICAgIC8vIHRoZSBzY29wZSBzcGVjaWZpZWQgYnkgdGhlIGF0dHJpYnV0ZQogICAgICAgIHN5bS5vd25lci5tZW1iZXJzKCkucmVtb3ZlKHN5bSk7CiAgICAgICAgQ2xhc3NTeW1ib2wgc2VsZiA9IChDbGFzc1N5bWJvbClzeW07CiAgICAgICAgQ2xhc3NTeW1ib2wgYyA9IHJlYWRDbGFzc1N5bWJvbChuZXh0Q2hhcigpKTsKICAgICAgICBOYW1lQW5kVHlwZSBudCA9IHJlYWROYW1lQW5kVHlwZShuZXh0Q2hhcigpKTsKCiAgICAgICAgaWYgKGMubWVtYmVyc19maWVsZCA9PSBudWxsKQogICAgICAgICAgICB0aHJvdyBiYWRDbGFzc0ZpbGUoImJhZC5lbmNsb3NpbmcuY2xhc3MiLCBzZWxmLCBjKTsKCiAgICAgICAgTWV0aG9kU3ltYm9sIG0gPSBmaW5kTWV0aG9kKG50LCBjLm1lbWJlcnNfZmllbGQsIHNlbGYuZmxhZ3MoKSk7CiAgICAgICAgaWYgKG50ICE9IG51bGwgJiYgbSA9PSBudWxsKQogICAgICAgICAgICB0aHJvdyBiYWRFbmNsb3NpbmdNZXRob2Qoc2VsZik7CgogICAgICAgIHNlbGYubmFtZSA9IHNpbXBsZUJpbmFyeU5hbWUoc2VsZi5mbGF0bmFtZSwgYy5mbGF0bmFtZSkgOwogICAgICAgIHNlbGYub3duZXIgPSBtICE9IG51bGwgPyBtIDogYzsKICAgICAgICBpZiAoc2VsZi5uYW1lLmlzRW1wdHkoKSkKICAgICAgICAgICAgc2VsZi5mdWxsbmFtZSA9IG5hbWVzLmVtcHR5OwogICAgICAgIGVsc2UKICAgICAgICAgICAgc2VsZi5mdWxsbmFtZSA9IENsYXNzU3ltYm9sLmZvcm1GdWxsTmFtZShzZWxmLm5hbWUsIHNlbGYub3duZXIpOwoKICAgICAgICBpZiAobSAhPSBudWxsKSB7CiAgICAgICAgICAgICgoQ2xhc3NUeXBlKXN5bS50eXBlKS5zZXRFbmNsb3NpbmdUeXBlKG0udHlwZSk7CiAgICAgICAgfSBlbHNlIGlmICgoc2VsZi5mbGFnc19maWVsZCAmIFNUQVRJQykgPT0gMCkgewogICAgICAgICAgICAoKENsYXNzVHlwZSlzeW0udHlwZSkuc2V0RW5jbG9zaW5nVHlwZShjLnR5cGUpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICgoQ2xhc3NUeXBlKXN5bS50eXBlKS5zZXRFbmNsb3NpbmdUeXBlKFR5cGUubm9UeXBlKTsKICAgICAgICB9CiAgICAgICAgZW50ZXJUeXBldmFycyhzZWxmLCBzZWxmLnR5cGUpOwogICAgICAgIGlmICghbWlzc2luZ1R5cGVWYXJpYWJsZXMuaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIExpc3RCdWZmZXI8VHlwZT4gdHlwZVZhcnMgPSAgbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgICAgICBmb3IgKFR5cGUgdHlwZXZhciA6IG1pc3NpbmdUeXBlVmFyaWFibGVzKSB7CiAgICAgICAgICAgICAgICB0eXBlVmFycy5hcHBlbmQoZmluZFR5cGVWYXIodHlwZXZhci50c3ltLm5hbWUpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBmb3VuZFR5cGVWYXJpYWJsZXMgPSB0eXBlVmFycy50b0xpc3QoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBmb3VuZFR5cGVWYXJpYWJsZXMgPSBMaXN0Lm5pbCgpOwogICAgICAgIH0KICAgIH0KCiAgICAvLyBTZWUgamF2YS5sYW5nLkNsYXNzCiAgICBwcml2YXRlIE5hbWUgc2ltcGxlQmluYXJ5TmFtZShOYW1lIHNlbGYsIE5hbWUgZW5jbG9zaW5nKSB7CiAgICAgICAgU3RyaW5nIHNpbXBsZUJpbmFyeU5hbWUgPSBzZWxmLnRvU3RyaW5nKCkuc3Vic3RyaW5nKGVuY2xvc2luZy50b1N0cmluZygpLmxlbmd0aCgpKTsKICAgICAgICBpZiAoc2ltcGxlQmluYXJ5TmFtZS5sZW5ndGgoKSA8IDEgfHwgc2ltcGxlQmluYXJ5TmFtZS5jaGFyQXQoMCkgIT0gJyQnKQogICAgICAgICAgICB0aHJvdyBiYWRDbGFzc0ZpbGUoImJhZC5lbmNsb3NpbmcubWV0aG9kIiwgc2VsZik7CiAgICAgICAgaW50IGluZGV4ID0gMTsKICAgICAgICB3aGlsZSAoaW5kZXggPCBzaW1wbGVCaW5hcnlOYW1lLmxlbmd0aCgpICYmCiAgICAgICAgICAgICAgIGlzQXNjaWlEaWdpdChzaW1wbGVCaW5hcnlOYW1lLmNoYXJBdChpbmRleCkpKQogICAgICAgICAgICBpbmRleCsrOwogICAgICAgIHJldHVybiBuYW1lcy5mcm9tU3RyaW5nKHNpbXBsZUJpbmFyeU5hbWUuc3Vic3RyaW5nKGluZGV4KSk7CiAgICB9CgogICAgcHJpdmF0ZSBNZXRob2RTeW1ib2wgZmluZE1ldGhvZChOYW1lQW5kVHlwZSBudCwgU2NvcGUgc2NvcGUsIGxvbmcgZmxhZ3MpIHsKICAgICAgICBpZiAobnQgPT0gbnVsbCkKICAgICAgICAgICAgcmV0dXJuIG51bGw7CgogICAgICAgIE1ldGhvZFR5cGUgdHlwZSA9IG50LnVuaXF1ZVR5cGUudHlwZS5hc01ldGhvZFR5cGUoKTsKCiAgICAgICAgZm9yIChTeW1ib2wgc3ltIDogc2NvcGUuZ2V0U3ltYm9sc0J5TmFtZShudC5uYW1lKSkgewogICAgICAgICAgICBpZiAoc3ltLmtpbmQgPT0gTVRIICYmIGlzU2FtZUJpbmFyeVR5cGUoc3ltLnR5cGUuYXNNZXRob2RUeXBlKCksIHR5cGUpKQogICAgICAgICAgICAgICAgcmV0dXJuIChNZXRob2RTeW1ib2wpc3ltOwogICAgICAgIH0KCiAgICAgICAgaWYgKG50Lm5hbWUgIT0gbmFtZXMuaW5pdCkKICAgICAgICAgICAgLy8gbm90IGEgY29uc3RydWN0b3IKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgaWYgKChmbGFncyAmIElOVEVSRkFDRSkgIT0gMCkKICAgICAgICAgICAgLy8gbm8gZW5jbG9zaW5nIGluc3RhbmNlCiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIGlmIChudC51bmlxdWVUeXBlLnR5cGUuZ2V0UGFyYW1ldGVyVHlwZXMoKS5pc0VtcHR5KCkpCiAgICAgICAgICAgIC8vIG5vIHBhcmFtZXRlcnMKICAgICAgICAgICAgcmV0dXJuIG51bGw7CgogICAgICAgIC8vIEEgY29uc3RydWN0b3Igb2YgYW4gaW5uZXIgY2xhc3MuCiAgICAgICAgLy8gUmVtb3ZlIHRoZSBmaXJzdCBhcmd1bWVudCAodGhlIGVuY2xvc2luZyBpbnN0YW5jZSkKICAgICAgICBudC5zZXRUeXBlKG5ldyBNZXRob2RUeXBlKG50LnVuaXF1ZVR5cGUudHlwZS5nZXRQYXJhbWV0ZXJUeXBlcygpLnRhaWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG50LnVuaXF1ZVR5cGUudHlwZS5nZXRSZXR1cm5UeXBlKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG50LnVuaXF1ZVR5cGUudHlwZS5nZXRUaHJvd25UeXBlcygpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeW1zLm1ldGhvZENsYXNzKSk7CiAgICAgICAgLy8gVHJ5IHNlYXJjaGluZyBhZ2FpbgogICAgICAgIHJldHVybiBmaW5kTWV0aG9kKG50LCBzY29wZSwgZmxhZ3MpOwogICAgfQoKICAgIC8qKiBTaW1pbGFyIHRvIFR5cGVzLmlzU2FtZVR5cGUgYnV0IGF2b2lkcyBjb21wbGV0aW9uICovCiAgICBwcml2YXRlIGJvb2xlYW4gaXNTYW1lQmluYXJ5VHlwZShNZXRob2RUeXBlIG10MSwgTWV0aG9kVHlwZSBtdDIpIHsKICAgICAgICBMaXN0PFR5cGU+IHR5cGVzMSA9IHR5cGVzLmVyYXN1cmUobXQxLmdldFBhcmFtZXRlclR5cGVzKCkpCiAgICAgICAgICAgIC5wcmVwZW5kKHR5cGVzLmVyYXN1cmUobXQxLmdldFJldHVyblR5cGUoKSkpOwogICAgICAgIExpc3Q8VHlwZT4gdHlwZXMyID0gbXQyLmdldFBhcmFtZXRlclR5cGVzKCkucHJlcGVuZChtdDIuZ2V0UmV0dXJuVHlwZSgpKTsKICAgICAgICB3aGlsZSAoIXR5cGVzMS5pc0VtcHR5KCkgJiYgIXR5cGVzMi5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgaWYgKHR5cGVzMS5oZWFkLnRzeW0gIT0gdHlwZXMyLmhlYWQudHN5bSkKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgdHlwZXMxID0gdHlwZXMxLnRhaWw7CiAgICAgICAgICAgIHR5cGVzMiA9IHR5cGVzMi50YWlsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdHlwZXMxLmlzRW1wdHkoKSAmJiB0eXBlczIuaXNFbXB0eSgpOwogICAgfQoKICAgIC8qKgogICAgICogQ2hhcmFjdGVyLmlzRGlnaXQgYW5zd2VycyA8dHQ+dHJ1ZTwvdHQ+IHRvIHNvbWUgbm9uLWFzY2lpCiAgICAgKiBkaWdpdHMuICBUaGlzIG9uZSBkb2VzIG5vdC4gIDxiPmNvcGllZCBmcm9tIGphdmEubGFuZy5DbGFzczwvYj4KICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBpc0FzY2lpRGlnaXQoY2hhciBjKSB7CiAgICAgICAgcmV0dXJuICcwJyA8PSBjICYmIGMgPD0gJzknOwogICAgfQoKICAgIC8qKiBSZWFkIG1lbWJlciBhdHRyaWJ1dGVzLgogICAgICovCiAgICB2b2lkIHJlYWRNZW1iZXJBdHRycyhTeW1ib2wgc3ltKSB7CiAgICAgICAgcmVhZEF0dHJzKHN5bSwgQXR0cmlidXRlS2luZC5NRU1CRVIpOwogICAgfQoKICAgIHZvaWQgcmVhZEF0dHJzKFN5bWJvbCBzeW0sIEF0dHJpYnV0ZUtpbmQga2luZCkgewogICAgICAgIGNoYXIgYWMgPSBuZXh0Q2hhcigpOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYWM7IGkrKykgewogICAgICAgICAgICBOYW1lIGF0dHJOYW1lID0gcmVhZE5hbWUobmV4dENoYXIoKSk7CiAgICAgICAgICAgIGludCBhdHRyTGVuID0gbmV4dEludCgpOwogICAgICAgICAgICBBdHRyaWJ1dGVSZWFkZXIgciA9IGF0dHJpYnV0ZVJlYWRlcnMuZ2V0KGF0dHJOYW1lKTsKICAgICAgICAgICAgaWYgKHIgIT0gbnVsbCAmJiByLmFjY2VwdHMoa2luZCkpCiAgICAgICAgICAgICAgICByLnJlYWQoc3ltLCBhdHRyTGVuKTsKICAgICAgICAgICAgZWxzZSAgewogICAgICAgICAgICAgICAgYnAgPSBicCArIGF0dHJMZW47CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgcHJpdmF0ZSBib29sZWFuIHJlYWRpbmdDbGFzc0F0dHIgPSBmYWxzZTsKICAgIHByaXZhdGUgTGlzdDxUeXBlPiBtaXNzaW5nVHlwZVZhcmlhYmxlcyA9IExpc3QubmlsKCk7CiAgICBwcml2YXRlIExpc3Q8VHlwZT4gZm91bmRUeXBlVmFyaWFibGVzID0gTGlzdC5uaWwoKTsKCiAgICAvKiogUmVhZCBjbGFzcyBhdHRyaWJ1dGVzLgogICAgICovCiAgICB2b2lkIHJlYWRDbGFzc0F0dHJzKENsYXNzU3ltYm9sIGMpIHsKICAgICAgICByZWFkQXR0cnMoYywgQXR0cmlidXRlS2luZC5DTEFTUyk7CiAgICB9CgogICAgLyoqIFJlYWQgY29kZSBibG9jay4KICAgICAqLwogICAgQ29kZSByZWFkQ29kZShTeW1ib2wgb3duZXIpIHsKICAgICAgICBuZXh0Q2hhcigpOyAvLyBtYXhfc3RhY2sKICAgICAgICBuZXh0Q2hhcigpOyAvLyBtYXhfbG9jYWxzCiAgICAgICAgZmluYWwgaW50ICBjb2RlX2xlbmd0aCA9IG5leHRJbnQoKTsKICAgICAgICBicCArPSBjb2RlX2xlbmd0aDsKICAgICAgICBmaW5hbCBjaGFyIGV4Y2VwdGlvbl90YWJsZV9sZW5ndGggPSBuZXh0Q2hhcigpOwogICAgICAgIGJwICs9IGV4Y2VwdGlvbl90YWJsZV9sZW5ndGggKiA4OwogICAgICAgIHJlYWRNZW1iZXJBdHRycyhvd25lcik7CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlYWRpbmcgSmF2YS1sYW5ndWFnZSBhbm5vdGF0aW9ucwogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgogICAgLyoqIEF0dGFjaCBhbm5vdGF0aW9ucy4KICAgICAqLwogICAgdm9pZCBhdHRhY2hBbm5vdGF0aW9ucyhmaW5hbCBTeW1ib2wgc3ltKSB7CiAgICAgICAgaW50IG51bUF0dHJpYnV0ZXMgPSBuZXh0Q2hhcigpOwogICAgICAgIGlmIChudW1BdHRyaWJ1dGVzICE9IDApIHsKICAgICAgICAgICAgTGlzdEJ1ZmZlcjxDb21wb3VuZEFubm90YXRpb25Qcm94eT4gcHJveGllcyA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGk8bnVtQXR0cmlidXRlczsgaSsrKSB7CiAgICAgICAgICAgICAgICBDb21wb3VuZEFubm90YXRpb25Qcm94eSBwcm94eSA9IHJlYWRDb21wb3VuZEFubm90YXRpb24oKTsKICAgICAgICAgICAgICAgIGlmIChwcm94eS50eXBlLnRzeW0gPT0gc3ltcy5wcm9wcmlldGFyeVR5cGUudHN5bSkKICAgICAgICAgICAgICAgICAgICBzeW0uZmxhZ3NfZmllbGQgfD0gUFJPUFJJRVRBUlk7CiAgICAgICAgICAgICAgICBlbHNlIGlmIChwcm94eS50eXBlLnRzeW0gPT0gc3ltcy5wcm9maWxlVHlwZS50c3ltKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHByb2ZpbGUgIT0gUHJvZmlsZS5ERUZBVUxUKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoUGFpcjxOYW1lLEF0dHJpYnV0ZT4gdjogcHJveHkudmFsdWVzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodi5mc3QgPT0gbmFtZXMudmFsdWUgJiYgdi5zbmQgaW5zdGFuY2VvZiBBdHRyaWJ1dGUuQ29uc3RhbnQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdHRyaWJ1dGUuQ29uc3RhbnQgYyA9IChBdHRyaWJ1dGUuQ29uc3RhbnQpIHYuc25kOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjLnR5cGUgPT0gc3ltcy5pbnRUeXBlICYmICgoSW50ZWdlcikgYy52YWx1ZSkgPiBwcm9maWxlLnZhbHVlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5bS5mbGFnc19maWVsZCB8PSBOT1RfSU5fUFJPRklMRTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGlmIChwcm94eS50eXBlLnRzeW0gPT0gc3ltcy5hbm5vdGF0aW9uVGFyZ2V0VHlwZS50c3ltKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldCA9IHByb3h5OwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocHJveHkudHlwZS50c3ltID09IHN5bXMucmVwZWF0YWJsZVR5cGUudHN5bSkgewogICAgICAgICAgICAgICAgICAgICAgICByZXBlYXRhYmxlID0gcHJveHk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChwcm94eS50eXBlLnRzeW0gPT0gc3ltcy5kZXByZWNhdGVkVHlwZS50c3ltKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHN5bS5mbGFnc19maWVsZCB8PSAoREVQUkVDQVRFRCB8IERFUFJFQ0FURURfQU5OT1RBVElPTik7CiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoUGFpcjxOYW1lLCBBdHRyaWJ1dGU+IHYgOiBwcm94eS52YWx1ZXMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2LmZzdCA9PSBuYW1lcy5mb3JSZW1vdmFsICYmIHYuc25kIGluc3RhbmNlb2YgQXR0cmlidXRlLkNvbnN0YW50KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXR0cmlidXRlLkNvbnN0YW50IGMgPSAoQXR0cmlidXRlLkNvbnN0YW50KSB2LnNuZDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYy50eXBlID09IHN5bXMuYm9vbGVhblR5cGUgJiYgKChJbnRlZ2VyKSBjLnZhbHVlKSAhPSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5bS5mbGFnc19maWVsZCB8PSBERVBSRUNBVEVEX1JFTU9WQUw7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBwcm94aWVzLmFwcGVuZChwcm94eSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYW5ub3RhdGUubm9ybWFsKG5ldyBBbm5vdGF0aW9uQ29tcGxldGVyKHN5bSwgcHJveGllcy50b0xpc3QoKSkpOwogICAgICAgIH0KICAgIH0KCiAgICAvKiogQXR0YWNoIHBhcmFtZXRlciBhbm5vdGF0aW9ucy4KICAgICAqLwogICAgdm9pZCBhdHRhY2hQYXJhbWV0ZXJBbm5vdGF0aW9ucyhmaW5hbCBTeW1ib2wgbWV0aG9kKSB7CiAgICAgICAgZmluYWwgTWV0aG9kU3ltYm9sIG1ldGggPSAoTWV0aG9kU3ltYm9sKW1ldGhvZDsKICAgICAgICBpbnQgbnVtUGFyYW1ldGVycyA9IGJ1ZlticCsrXSAmIDB4RkY7CiAgICAgICAgTGlzdDxWYXJTeW1ib2w+IHBhcmFtZXRlcnMgPSBtZXRoLnBhcmFtcygpOwogICAgICAgIGludCBwbnVtID0gMDsKICAgICAgICB3aGlsZSAocGFyYW1ldGVycy50YWlsICE9IG51bGwpIHsKICAgICAgICAgICAgYXR0YWNoQW5ub3RhdGlvbnMocGFyYW1ldGVycy5oZWFkKTsKICAgICAgICAgICAgcGFyYW1ldGVycyA9IHBhcmFtZXRlcnMudGFpbDsKICAgICAgICAgICAgcG51bSsrOwogICAgICAgIH0KICAgICAgICBpZiAocG51bSAhPSBudW1QYXJhbWV0ZXJzKSB7CiAgICAgICAgICAgIHRocm93IGJhZENsYXNzRmlsZSgiYmFkLnJ1bnRpbWUuaW52aXNpYmxlLnBhcmFtLmFubm90YXRpb25zIiwgbWV0aCk7CiAgICAgICAgfQogICAgfQoKICAgIHZvaWQgYXR0YWNoVHlwZUFubm90YXRpb25zKGZpbmFsIFN5bWJvbCBzeW0pIHsKICAgICAgICBpbnQgbnVtQXR0cmlidXRlcyA9IG5leHRDaGFyKCk7CiAgICAgICAgaWYgKG51bUF0dHJpYnV0ZXMgIT0gMCkgewogICAgICAgICAgICBMaXN0QnVmZmVyPFR5cGVBbm5vdGF0aW9uUHJveHk+IHByb3hpZXMgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnVtQXR0cmlidXRlczsgaSsrKQogICAgICAgICAgICAgICAgcHJveGllcy5hcHBlbmQocmVhZFR5cGVBbm5vdGF0aW9uKCkpOwogICAgICAgICAgICBhbm5vdGF0ZS5ub3JtYWwobmV3IFR5cGVBbm5vdGF0aW9uQ29tcGxldGVyKHN5bSwgcHJveGllcy50b0xpc3QoKSkpOwogICAgICAgIH0KICAgIH0KCiAgICAvKiogQXR0YWNoIHRoZSBkZWZhdWx0IHZhbHVlIGZvciBhbiBhbm5vdGF0aW9uIGVsZW1lbnQuCiAgICAgKi8KICAgIHZvaWQgYXR0YWNoQW5ub3RhdGlvbkRlZmF1bHQoZmluYWwgU3ltYm9sIHN5bSkgewogICAgICAgIGZpbmFsIE1ldGhvZFN5bWJvbCBtZXRoID0gKE1ldGhvZFN5bWJvbClzeW07IC8vIG9ubHkgb24gbWV0aG9kcwogICAgICAgIGZpbmFsIEF0dHJpYnV0ZSB2YWx1ZSA9IHJlYWRBdHRyaWJ1dGVWYWx1ZSgpOwoKICAgICAgICAvLyBUaGUgZGVmYXVsdCB2YWx1ZSBpcyBzZXQgbGF0ZXIgZHVyaW5nIGFubm90YXRpb24uIEl0IG1pZ2h0CiAgICAgICAgLy8gYmUgdGhlIGNhc2UgdGhhdCB0aGUgU3ltYm9sIHN5bSBpcyBhbm5vdGF0ZWQgX2FmdGVyXyB0aGUKICAgICAgICAvLyByZXBlYXRpbmcgaW5zdGFuY2VzIHRoYXQgZGVwZW5kIG9uIHRoaXMgZGVmYXVsdCB2YWx1ZSwKICAgICAgICAvLyBiZWNhdXNlIG9mIHRoaXMgd2Ugc2V0IGFuIGludGVyaW0gdmFsdWUgdGhhdCB0ZWxscyB1cyB0aGlzCiAgICAgICAgLy8gZWxlbWVudCAobW9zdCBsaWtlbHkpIGhhcyBhIGRlZmF1bHQuCiAgICAgICAgLy8KICAgICAgICAvLyBTZXQgaW50ZXJpbSB2YWx1ZSBmb3Igbm93LCByZXNldCBqdXN0IGJlZm9yZSB3ZSBkbyB0aGlzCiAgICAgICAgLy8gcHJvcGVybHkgYXQgYW5ub3RhdGUgdGltZS4KICAgICAgICBtZXRoLmRlZmF1bHRWYWx1ZSA9IHZhbHVlOwogICAgICAgIGFubm90YXRlLm5vcm1hbChuZXcgQW5ub3RhdGlvbkRlZmF1bHRDb21wbGV0ZXIobWV0aCwgdmFsdWUpKTsKICAgIH0KCiAgICBUeXBlIHJlYWRUeXBlT3JDbGFzc1N5bWJvbChpbnQgaSkgewogICAgICAgIC8vIHN1cHBvcnQgcHJlbGltaW5hcnkganNyMTc1LWZvcm1hdCBjbGFzcyBmaWxlcwogICAgICAgIGlmIChidWZbcG9vbElkeFtpXV0gPT0gQ09OU1RBTlRfQ2xhc3MpCiAgICAgICAgICAgIHJldHVybiByZWFkQ2xhc3NTeW1ib2woaSkudHlwZTsKICAgICAgICByZXR1cm4gcmVhZFR5cGVUb1Byb3h5KGkpOwogICAgfQogICAgVHlwZSByZWFkRW51bVR5cGUoaW50IGkpIHsKICAgICAgICAvLyBzdXBwb3J0IHByZWxpbWluYXJ5IGpzcjE3NS1mb3JtYXQgY2xhc3MgZmlsZXMKICAgICAgICBpbnQgaW5kZXggPSBwb29sSWR4W2ldOwogICAgICAgIGludCBsZW5ndGggPSBnZXRDaGFyKGluZGV4ICsgMSk7CiAgICAgICAgaWYgKGJ1ZltpbmRleCArIGxlbmd0aCArIDJdICE9ICc7JykKICAgICAgICAgICAgcmV0dXJuIGVudGVyQ2xhc3MocmVhZE5hbWUoaSkpLnR5cGU7CiAgICAgICAgcmV0dXJuIHJlYWRUeXBlVG9Qcm94eShpKTsKICAgIH0KICAgIFR5cGUgcmVhZFR5cGVUb1Byb3h5KGludCBpKSB7CiAgICAgICAgaWYgKGN1cnJlbnRNb2R1bGUubW9kdWxlX2luZm8gPT0gY3VycmVudE93bmVyKSB7CiAgICAgICAgICAgIGludCBpbmRleCA9IHBvb2xJZHhbaV07CiAgICAgICAgICAgIHJldHVybiBuZXcgUHJveHlUeXBlKEFycmF5cy5jb3B5T2ZSYW5nZShidWYsIGluZGV4ICsgMywgaW5kZXggKyAzICsgZ2V0Q2hhcihpbmRleCArIDEpKSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIHJlYWRUeXBlKGkpOwogICAgICAgIH0KICAgIH0KCiAgICBDb21wb3VuZEFubm90YXRpb25Qcm94eSByZWFkQ29tcG91bmRBbm5vdGF0aW9uKCkgewogICAgICAgIFR5cGUgdDsKICAgICAgICBpZiAoY3VycmVudE1vZHVsZS5tb2R1bGVfaW5mbyA9PSBjdXJyZW50T3duZXIpIHsKICAgICAgICAgICAgaW50IGluZGV4ID0gcG9vbElkeFtuZXh0Q2hhcigpXTsKICAgICAgICAgICAgdCA9IG5ldyBQcm94eVR5cGUoQXJyYXlzLmNvcHlPZlJhbmdlKGJ1ZiwgaW5kZXggKyAzLCBpbmRleCArIDMgKyBnZXRDaGFyKGluZGV4ICsgMSkpKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB0ID0gcmVhZFR5cGVPckNsYXNzU3ltYm9sKG5leHRDaGFyKCkpOwogICAgICAgIH0KICAgICAgICBpbnQgbnVtRmllbGRzID0gbmV4dENoYXIoKTsKICAgICAgICBMaXN0QnVmZmVyPFBhaXI8TmFtZSxBdHRyaWJ1dGU+PiBwYWlycyA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICBmb3IgKGludCBpPTA7IGk8bnVtRmllbGRzOyBpKyspIHsKICAgICAgICAgICAgTmFtZSBuYW1lID0gcmVhZE5hbWUobmV4dENoYXIoKSk7CiAgICAgICAgICAgIEF0dHJpYnV0ZSB2YWx1ZSA9IHJlYWRBdHRyaWJ1dGVWYWx1ZSgpOwogICAgICAgICAgICBwYWlycy5hcHBlbmQobmV3IFBhaXI8PihuYW1lLCB2YWx1ZSkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbmV3IENvbXBvdW5kQW5ub3RhdGlvblByb3h5KHQsIHBhaXJzLnRvTGlzdCgpKTsKICAgIH0KCiAgICBUeXBlQW5ub3RhdGlvblByb3h5IHJlYWRUeXBlQW5ub3RhdGlvbigpIHsKICAgICAgICBUeXBlQW5ub3RhdGlvblBvc2l0aW9uIHBvc2l0aW9uID0gcmVhZFBvc2l0aW9uKCk7CiAgICAgICAgQ29tcG91bmRBbm5vdGF0aW9uUHJveHkgcHJveHkgPSByZWFkQ29tcG91bmRBbm5vdGF0aW9uKCk7CgogICAgICAgIHJldHVybiBuZXcgVHlwZUFubm90YXRpb25Qcm94eShwcm94eSwgcG9zaXRpb24pOwogICAgfQoKICAgIFR5cGVBbm5vdGF0aW9uUG9zaXRpb24gcmVhZFBvc2l0aW9uKCkgewogICAgICAgIGludCB0YWcgPSBuZXh0Qnl0ZSgpOyAvLyBUYXJnZXRUeXBlIHRhZyBpcyBhIGJ5dGUKCiAgICAgICAgaWYgKCFUYXJnZXRUeXBlLmlzVmFsaWRUYXJnZXRUeXBlVmFsdWUodGFnKSkKICAgICAgICAgICAgdGhyb3cgYmFkQ2xhc3NGaWxlKCJiYWQudHlwZS5hbm5vdGF0aW9uLnZhbHVlIiwgU3RyaW5nLmZvcm1hdCgiMHglMDJYIiwgdGFnKSk7CgogICAgICAgIFRhcmdldFR5cGUgdHlwZSA9IFRhcmdldFR5cGUuZnJvbVRhcmdldFR5cGVWYWx1ZSh0YWcpOwoKICAgICAgICBzd2l0Y2ggKHR5cGUpIHsKICAgICAgICAvLyBpbnN0YW5jZW9mCiAgICAgICAgY2FzZSBJTlNUQU5DRU9GOiB7CiAgICAgICAgICAgIGZpbmFsIGludCBvZmZzZXQgPSBuZXh0Q2hhcigpOwogICAgICAgICAgICBmaW5hbCBUeXBlQW5ub3RhdGlvblBvc2l0aW9uIHBvc2l0aW9uID0KICAgICAgICAgICAgICAgIFR5cGVBbm5vdGF0aW9uUG9zaXRpb24uaW5zdGFuY2VPZihyZWFkVHlwZVBhdGgoKSk7CiAgICAgICAgICAgIHBvc2l0aW9uLm9mZnNldCA9IG9mZnNldDsKICAgICAgICAgICAgcmV0dXJuIHBvc2l0aW9uOwogICAgICAgIH0KICAgICAgICAvLyBuZXcgZXhwcmVzc2lvbgogICAgICAgIGNhc2UgTkVXOiB7CiAgICAgICAgICAgIGZpbmFsIGludCBvZmZzZXQgPSBuZXh0Q2hhcigpOwogICAgICAgICAgICBmaW5hbCBUeXBlQW5ub3RhdGlvblBvc2l0aW9uIHBvc2l0aW9uID0KICAgICAgICAgICAgICAgIFR5cGVBbm5vdGF0aW9uUG9zaXRpb24ubmV3T2JqKHJlYWRUeXBlUGF0aCgpKTsKICAgICAgICAgICAgcG9zaXRpb24ub2Zmc2V0ID0gb2Zmc2V0OwogICAgICAgICAgICByZXR1cm4gcG9zaXRpb247CiAgICAgICAgfQogICAgICAgIC8vIGNvbnN0cnVjdG9yL21ldGhvZCByZWZlcmVuY2UgcmVjZWl2ZXIKICAgICAgICBjYXNlIENPTlNUUlVDVE9SX1JFRkVSRU5DRTogewogICAgICAgICAgICBmaW5hbCBpbnQgb2Zmc2V0ID0gbmV4dENoYXIoKTsKICAgICAgICAgICAgZmluYWwgVHlwZUFubm90YXRpb25Qb3NpdGlvbiBwb3NpdGlvbiA9CiAgICAgICAgICAgICAgICBUeXBlQW5ub3RhdGlvblBvc2l0aW9uLmNvbnN0cnVjdG9yUmVmKHJlYWRUeXBlUGF0aCgpKTsKICAgICAgICAgICAgcG9zaXRpb24ub2Zmc2V0ID0gb2Zmc2V0OwogICAgICAgICAgICByZXR1cm4gcG9zaXRpb247CiAgICAgICAgfQogICAgICAgIGNhc2UgTUVUSE9EX1JFRkVSRU5DRTogewogICAgICAgICAgICBmaW5hbCBpbnQgb2Zmc2V0ID0gbmV4dENoYXIoKTsKICAgICAgICAgICAgZmluYWwgVHlwZUFubm90YXRpb25Qb3NpdGlvbiBwb3NpdGlvbiA9CiAgICAgICAgICAgICAgICBUeXBlQW5ub3RhdGlvblBvc2l0aW9uLm1ldGhvZFJlZihyZWFkVHlwZVBhdGgoKSk7CiAgICAgICAgICAgIHBvc2l0aW9uLm9mZnNldCA9IG9mZnNldDsKICAgICAgICAgICAgcmV0dXJuIHBvc2l0aW9uOwogICAgICAgIH0KICAgICAgICAvLyBsb2NhbCB2YXJpYWJsZQogICAgICAgIGNhc2UgTE9DQUxfVkFSSUFCTEU6IHsKICAgICAgICAgICAgZmluYWwgaW50IHRhYmxlX2xlbmd0aCA9IG5leHRDaGFyKCk7CiAgICAgICAgICAgIGZpbmFsIGludFtdIG5ld0x2YXJPZmZzZXQgPSBuZXcgaW50W3RhYmxlX2xlbmd0aF07CiAgICAgICAgICAgIGZpbmFsIGludFtdIG5ld0x2YXJMZW5ndGggPSBuZXcgaW50W3RhYmxlX2xlbmd0aF07CiAgICAgICAgICAgIGZpbmFsIGludFtdIG5ld0x2YXJJbmRleCA9IG5ldyBpbnRbdGFibGVfbGVuZ3RoXTsKCiAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdGFibGVfbGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgICAgIG5ld0x2YXJPZmZzZXRbaV0gPSBuZXh0Q2hhcigpOwogICAgICAgICAgICAgICAgbmV3THZhckxlbmd0aFtpXSA9IG5leHRDaGFyKCk7CiAgICAgICAgICAgICAgICBuZXdMdmFySW5kZXhbaV0gPSBuZXh0Q2hhcigpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBmaW5hbCBUeXBlQW5ub3RhdGlvblBvc2l0aW9uIHBvc2l0aW9uID0KICAgICAgICAgICAgICAgICAgICBUeXBlQW5ub3RhdGlvblBvc2l0aW9uLmxvY2FsVmFyaWFibGUocmVhZFR5cGVQYXRoKCkpOwogICAgICAgICAgICBwb3NpdGlvbi5sdmFyT2Zmc2V0ID0gbmV3THZhck9mZnNldDsKICAgICAgICAgICAgcG9zaXRpb24ubHZhckxlbmd0aCA9IG5ld0x2YXJMZW5ndGg7CiAgICAgICAgICAgIHBvc2l0aW9uLmx2YXJJbmRleCA9IG5ld0x2YXJJbmRleDsKICAgICAgICAgICAgcmV0dXJuIHBvc2l0aW9uOwogICAgICAgIH0KICAgICAgICAvLyByZXNvdXJjZSB2YXJpYWJsZQogICAgICAgIGNhc2UgUkVTT1VSQ0VfVkFSSUFCTEU6IHsKICAgICAgICAgICAgZmluYWwgaW50IHRhYmxlX2xlbmd0aCA9IG5leHRDaGFyKCk7CiAgICAgICAgICAgIGZpbmFsIGludFtdIG5ld0x2YXJPZmZzZXQgPSBuZXcgaW50W3RhYmxlX2xlbmd0aF07CiAgICAgICAgICAgIGZpbmFsIGludFtdIG5ld0x2YXJMZW5ndGggPSBuZXcgaW50W3RhYmxlX2xlbmd0aF07CiAgICAgICAgICAgIGZpbmFsIGludFtdIG5ld0x2YXJJbmRleCA9IG5ldyBpbnRbdGFibGVfbGVuZ3RoXTsKCiAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdGFibGVfbGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgICAgIG5ld0x2YXJPZmZzZXRbaV0gPSBuZXh0Q2hhcigpOwogICAgICAgICAgICAgICAgbmV3THZhckxlbmd0aFtpXSA9IG5leHRDaGFyKCk7CiAgICAgICAgICAgICAgICBuZXdMdmFySW5kZXhbaV0gPSBuZXh0Q2hhcigpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBmaW5hbCBUeXBlQW5ub3RhdGlvblBvc2l0aW9uIHBvc2l0aW9uID0KICAgICAgICAgICAgICAgICAgICBUeXBlQW5ub3RhdGlvblBvc2l0aW9uLnJlc291cmNlVmFyaWFibGUocmVhZFR5cGVQYXRoKCkpOwogICAgICAgICAgICBwb3NpdGlvbi5sdmFyT2Zmc2V0ID0gbmV3THZhck9mZnNldDsKICAgICAgICAgICAgcG9zaXRpb24ubHZhckxlbmd0aCA9IG5ld0x2YXJMZW5ndGg7CiAgICAgICAgICAgIHBvc2l0aW9uLmx2YXJJbmRleCA9IG5ld0x2YXJJbmRleDsKICAgICAgICAgICAgcmV0dXJuIHBvc2l0aW9uOwogICAgICAgIH0KICAgICAgICAvLyBleGNlcHRpb24gcGFyYW1ldGVyCiAgICAgICAgY2FzZSBFWENFUFRJT05fUEFSQU1FVEVSOiB7CiAgICAgICAgICAgIGZpbmFsIGludCBleGNlcHRpb25faW5kZXggPSBuZXh0Q2hhcigpOwogICAgICAgICAgICBmaW5hbCBUeXBlQW5ub3RhdGlvblBvc2l0aW9uIHBvc2l0aW9uID0KICAgICAgICAgICAgICAgIFR5cGVBbm5vdGF0aW9uUG9zaXRpb24uZXhjZXB0aW9uUGFyYW1ldGVyKHJlYWRUeXBlUGF0aCgpKTsKICAgICAgICAgICAgcG9zaXRpb24uc2V0RXhjZXB0aW9uSW5kZXgoZXhjZXB0aW9uX2luZGV4KTsKICAgICAgICAgICAgcmV0dXJuIHBvc2l0aW9uOwogICAgICAgIH0KICAgICAgICAvLyBtZXRob2QgcmVjZWl2ZXIKICAgICAgICBjYXNlIE1FVEhPRF9SRUNFSVZFUjoKICAgICAgICAgICAgcmV0dXJuIFR5cGVBbm5vdGF0aW9uUG9zaXRpb24ubWV0aG9kUmVjZWl2ZXIocmVhZFR5cGVQYXRoKCkpOwogICAgICAgIC8vIHR5cGUgcGFyYW1ldGVyCiAgICAgICAgY2FzZSBDTEFTU19UWVBFX1BBUkFNRVRFUjogewogICAgICAgICAgICBmaW5hbCBpbnQgcGFyYW1ldGVyX2luZGV4ID0gbmV4dEJ5dGUoKTsKICAgICAgICAgICAgcmV0dXJuIFR5cGVBbm5vdGF0aW9uUG9zaXRpb24KICAgICAgICAgICAgICAgIC50eXBlUGFyYW1ldGVyKHJlYWRUeXBlUGF0aCgpLCBwYXJhbWV0ZXJfaW5kZXgpOwogICAgICAgIH0KICAgICAgICBjYXNlIE1FVEhPRF9UWVBFX1BBUkFNRVRFUjogewogICAgICAgICAgICBmaW5hbCBpbnQgcGFyYW1ldGVyX2luZGV4ID0gbmV4dEJ5dGUoKTsKICAgICAgICAgICAgcmV0dXJuIFR5cGVBbm5vdGF0aW9uUG9zaXRpb24KICAgICAgICAgICAgICAgIC5tZXRob2RUeXBlUGFyYW1ldGVyKHJlYWRUeXBlUGF0aCgpLCBwYXJhbWV0ZXJfaW5kZXgpOwogICAgICAgIH0KICAgICAgICAvLyB0eXBlIHBhcmFtZXRlciBib3VuZAogICAgICAgIGNhc2UgQ0xBU1NfVFlQRV9QQVJBTUVURVJfQk9VTkQ6IHsKICAgICAgICAgICAgZmluYWwgaW50IHBhcmFtZXRlcl9pbmRleCA9IG5leHRCeXRlKCk7CiAgICAgICAgICAgIGZpbmFsIGludCBib3VuZF9pbmRleCA9IG5leHRCeXRlKCk7CiAgICAgICAgICAgIHJldHVybiBUeXBlQW5ub3RhdGlvblBvc2l0aW9uCiAgICAgICAgICAgICAgICAudHlwZVBhcmFtZXRlckJvdW5kKHJlYWRUeXBlUGF0aCgpLCBwYXJhbWV0ZXJfaW5kZXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvdW5kX2luZGV4KTsKICAgICAgICB9CiAgICAgICAgY2FzZSBNRVRIT0RfVFlQRV9QQVJBTUVURVJfQk9VTkQ6IHsKICAgICAgICAgICAgZmluYWwgaW50IHBhcmFtZXRlcl9pbmRleCA9IG5leHRCeXRlKCk7CiAgICAgICAgICAgIGZpbmFsIGludCBib3VuZF9pbmRleCA9IG5leHRCeXRlKCk7CiAgICAgICAgICAgIHJldHVybiBUeXBlQW5ub3RhdGlvblBvc2l0aW9uCiAgICAgICAgICAgICAgICAubWV0aG9kVHlwZVBhcmFtZXRlckJvdW5kKHJlYWRUeXBlUGF0aCgpLCBwYXJhbWV0ZXJfaW5kZXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvdW5kX2luZGV4KTsKICAgICAgICB9CiAgICAgICAgLy8gY2xhc3MgZXh0ZW5kcyBvciBpbXBsZW1lbnRzIGNsYXVzZQogICAgICAgIGNhc2UgQ0xBU1NfRVhURU5EUzogewogICAgICAgICAgICBmaW5hbCBpbnQgdHlwZV9pbmRleCA9IG5leHRDaGFyKCk7CiAgICAgICAgICAgIHJldHVybiBUeXBlQW5ub3RhdGlvblBvc2l0aW9uLmNsYXNzRXh0ZW5kcyhyZWFkVHlwZVBhdGgoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVfaW5kZXgpOwogICAgICAgIH0KICAgICAgICAvLyB0aHJvd3MKICAgICAgICBjYXNlIFRIUk9XUzogewogICAgICAgICAgICBmaW5hbCBpbnQgdHlwZV9pbmRleCA9IG5leHRDaGFyKCk7CiAgICAgICAgICAgIHJldHVybiBUeXBlQW5ub3RhdGlvblBvc2l0aW9uLm1ldGhvZFRocm93cyhyZWFkVHlwZVBhdGgoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVfaW5kZXgpOwogICAgICAgIH0KICAgICAgICAvLyBtZXRob2QgcGFyYW1ldGVyCiAgICAgICAgY2FzZSBNRVRIT0RfRk9STUFMX1BBUkFNRVRFUjogewogICAgICAgICAgICBmaW5hbCBpbnQgcGFyYW1ldGVyX2luZGV4ID0gbmV4dEJ5dGUoKTsKICAgICAgICAgICAgcmV0dXJuIFR5cGVBbm5vdGF0aW9uUG9zaXRpb24ubWV0aG9kUGFyYW1ldGVyKHJlYWRUeXBlUGF0aCgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyYW1ldGVyX2luZGV4KTsKICAgICAgICB9CiAgICAgICAgLy8gdHlwZSBjYXN0CiAgICAgICAgY2FzZSBDQVNUOiB7CiAgICAgICAgICAgIGZpbmFsIGludCBvZmZzZXQgPSBuZXh0Q2hhcigpOwogICAgICAgICAgICBmaW5hbCBpbnQgdHlwZV9pbmRleCA9IG5leHRCeXRlKCk7CiAgICAgICAgICAgIGZpbmFsIFR5cGVBbm5vdGF0aW9uUG9zaXRpb24gcG9zaXRpb24gPQogICAgICAgICAgICAgICAgVHlwZUFubm90YXRpb25Qb3NpdGlvbi50eXBlQ2FzdChyZWFkVHlwZVBhdGgoKSwgdHlwZV9pbmRleCk7CiAgICAgICAgICAgIHBvc2l0aW9uLm9mZnNldCA9IG9mZnNldDsKICAgICAgICAgICAgcmV0dXJuIHBvc2l0aW9uOwogICAgICAgIH0KICAgICAgICAvLyBtZXRob2QvY29uc3RydWN0b3IvcmVmZXJlbmNlIHR5cGUgYXJndW1lbnQKICAgICAgICBjYXNlIENPTlNUUlVDVE9SX0lOVk9DQVRJT05fVFlQRV9BUkdVTUVOVDogewogICAgICAgICAgICBmaW5hbCBpbnQgb2Zmc2V0ID0gbmV4dENoYXIoKTsKICAgICAgICAgICAgZmluYWwgaW50IHR5cGVfaW5kZXggPSBuZXh0Qnl0ZSgpOwogICAgICAgICAgICBmaW5hbCBUeXBlQW5ub3RhdGlvblBvc2l0aW9uIHBvc2l0aW9uID0gVHlwZUFubm90YXRpb25Qb3NpdGlvbgogICAgICAgICAgICAgICAgLmNvbnN0cnVjdG9ySW52b2NhdGlvblR5cGVBcmcocmVhZFR5cGVQYXRoKCksIHR5cGVfaW5kZXgpOwogICAgICAgICAgICBwb3NpdGlvbi5vZmZzZXQgPSBvZmZzZXQ7CiAgICAgICAgICAgIHJldHVybiBwb3NpdGlvbjsKICAgICAgICB9CiAgICAgICAgY2FzZSBNRVRIT0RfSU5WT0NBVElPTl9UWVBFX0FSR1VNRU5UOiB7CiAgICAgICAgICAgIGZpbmFsIGludCBvZmZzZXQgPSBuZXh0Q2hhcigpOwogICAgICAgICAgICBmaW5hbCBpbnQgdHlwZV9pbmRleCA9IG5leHRCeXRlKCk7CiAgICAgICAgICAgIGZpbmFsIFR5cGVBbm5vdGF0aW9uUG9zaXRpb24gcG9zaXRpb24gPSBUeXBlQW5ub3RhdGlvblBvc2l0aW9uCiAgICAgICAgICAgICAgICAubWV0aG9kSW52b2NhdGlvblR5cGVBcmcocmVhZFR5cGVQYXRoKCksIHR5cGVfaW5kZXgpOwogICAgICAgICAgICBwb3NpdGlvbi5vZmZzZXQgPSBvZmZzZXQ7CiAgICAgICAgICAgIHJldHVybiBwb3NpdGlvbjsKICAgICAgICB9CiAgICAgICAgY2FzZSBDT05TVFJVQ1RPUl9SRUZFUkVOQ0VfVFlQRV9BUkdVTUVOVDogewogICAgICAgICAgICBmaW5hbCBpbnQgb2Zmc2V0ID0gbmV4dENoYXIoKTsKICAgICAgICAgICAgZmluYWwgaW50IHR5cGVfaW5kZXggPSBuZXh0Qnl0ZSgpOwogICAgICAgICAgICBmaW5hbCBUeXBlQW5ub3RhdGlvblBvc2l0aW9uIHBvc2l0aW9uID0gVHlwZUFubm90YXRpb25Qb3NpdGlvbgogICAgICAgICAgICAgICAgLmNvbnN0cnVjdG9yUmVmVHlwZUFyZyhyZWFkVHlwZVBhdGgoKSwgdHlwZV9pbmRleCk7CiAgICAgICAgICAgIHBvc2l0aW9uLm9mZnNldCA9IG9mZnNldDsKICAgICAgICAgICAgcmV0dXJuIHBvc2l0aW9uOwogICAgICAgIH0KICAgICAgICBjYXNlIE1FVEhPRF9SRUZFUkVOQ0VfVFlQRV9BUkdVTUVOVDogewogICAgICAgICAgICBmaW5hbCBpbnQgb2Zmc2V0ID0gbmV4dENoYXIoKTsKICAgICAgICAgICAgZmluYWwgaW50IHR5cGVfaW5kZXggPSBuZXh0Qnl0ZSgpOwogICAgICAgICAgICBmaW5hbCBUeXBlQW5ub3RhdGlvblBvc2l0aW9uIHBvc2l0aW9uID0gVHlwZUFubm90YXRpb25Qb3NpdGlvbgogICAgICAgICAgICAgICAgLm1ldGhvZFJlZlR5cGVBcmcocmVhZFR5cGVQYXRoKCksIHR5cGVfaW5kZXgpOwogICAgICAgICAgICBwb3NpdGlvbi5vZmZzZXQgPSBvZmZzZXQ7CiAgICAgICAgICAgIHJldHVybiBwb3NpdGlvbjsKICAgICAgICB9CiAgICAgICAgLy8gV2UgZG9uJ3QgbmVlZCB0byB3b3JyeSBhYm91dCB0aGVzZQogICAgICAgIGNhc2UgTUVUSE9EX1JFVFVSTjoKICAgICAgICAgICAgcmV0dXJuIFR5cGVBbm5vdGF0aW9uUG9zaXRpb24ubWV0aG9kUmV0dXJuKHJlYWRUeXBlUGF0aCgpKTsKICAgICAgICBjYXNlIEZJRUxEOgogICAgICAgICAgICByZXR1cm4gVHlwZUFubm90YXRpb25Qb3NpdGlvbi5maWVsZChyZWFkVHlwZVBhdGgoKSk7CiAgICAgICAgY2FzZSBVTktOT1dOOgogICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoImp2bS5DbGFzc1JlYWRlcjogVU5LTk9XTiB0YXJnZXQgdHlwZSBzaG91bGQgbmV2ZXIgb2NjdXIhIik7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCJqdm0uQ2xhc3NSZWFkZXI6IFVua25vd24gdGFyZ2V0IHR5cGUgZm9yIHBvc2l0aW9uOiAiICsgdHlwZSk7CiAgICAgICAgfQogICAgfQoKICAgIExpc3Q8VHlwZUFubm90YXRpb25Qb3NpdGlvbi5UeXBlUGF0aEVudHJ5PiByZWFkVHlwZVBhdGgoKSB7CiAgICAgICAgaW50IGxlbiA9IG5leHRCeXRlKCk7CiAgICAgICAgTGlzdEJ1ZmZlcjxJbnRlZ2VyPiBsb2MgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW4gKiBUeXBlQW5ub3RhdGlvblBvc2l0aW9uLlR5cGVQYXRoRW50cnkuYnl0ZXNQZXJFbnRyeTsgKytpKQogICAgICAgICAgICBsb2MgPSBsb2MuYXBwZW5kKG5leHRCeXRlKCkpOwoKICAgICAgICByZXR1cm4gVHlwZUFubm90YXRpb25Qb3NpdGlvbi5nZXRUeXBlUGF0aEZyb21CaW5hcnkobG9jLnRvTGlzdCgpKTsKCiAgICB9CgogICAgQXR0cmlidXRlIHJlYWRBdHRyaWJ1dGVWYWx1ZSgpIHsKICAgICAgICBjaGFyIGMgPSAoY2hhcikgYnVmW2JwKytdOwogICAgICAgIHN3aXRjaCAoYykgewogICAgICAgIGNhc2UgJ0InOgogICAgICAgICAgICByZXR1cm4gbmV3IEF0dHJpYnV0ZS5Db25zdGFudChzeW1zLmJ5dGVUeXBlLCByZWFkUG9vbChuZXh0Q2hhcigpKSk7CiAgICAgICAgY2FzZSAnQyc6CiAgICAgICAgICAgIHJldHVybiBuZXcgQXR0cmlidXRlLkNvbnN0YW50KHN5bXMuY2hhclR5cGUsIHJlYWRQb29sKG5leHRDaGFyKCkpKTsKICAgICAgICBjYXNlICdEJzoKICAgICAgICAgICAgcmV0dXJuIG5ldyBBdHRyaWJ1dGUuQ29uc3RhbnQoc3ltcy5kb3VibGVUeXBlLCByZWFkUG9vbChuZXh0Q2hhcigpKSk7CiAgICAgICAgY2FzZSAnRic6CiAgICAgICAgICAgIHJldHVybiBuZXcgQXR0cmlidXRlLkNvbnN0YW50KHN5bXMuZmxvYXRUeXBlLCByZWFkUG9vbChuZXh0Q2hhcigpKSk7CiAgICAgICAgY2FzZSAnSSc6CiAgICAgICAgICAgIHJldHVybiBuZXcgQXR0cmlidXRlLkNvbnN0YW50KHN5bXMuaW50VHlwZSwgcmVhZFBvb2wobmV4dENoYXIoKSkpOwogICAgICAgIGNhc2UgJ0onOgogICAgICAgICAgICByZXR1cm4gbmV3IEF0dHJpYnV0ZS5Db25zdGFudChzeW1zLmxvbmdUeXBlLCByZWFkUG9vbChuZXh0Q2hhcigpKSk7CiAgICAgICAgY2FzZSAnUyc6CiAgICAgICAgICAgIHJldHVybiBuZXcgQXR0cmlidXRlLkNvbnN0YW50KHN5bXMuc2hvcnRUeXBlLCByZWFkUG9vbChuZXh0Q2hhcigpKSk7CiAgICAgICAgY2FzZSAnWic6CiAgICAgICAgICAgIHJldHVybiBuZXcgQXR0cmlidXRlLkNvbnN0YW50KHN5bXMuYm9vbGVhblR5cGUsIHJlYWRQb29sKG5leHRDaGFyKCkpKTsKICAgICAgICBjYXNlICdzJzoKICAgICAgICAgICAgcmV0dXJuIG5ldyBBdHRyaWJ1dGUuQ29uc3RhbnQoc3ltcy5zdHJpbmdUeXBlLCByZWFkUG9vbChuZXh0Q2hhcigpKS50b1N0cmluZygpKTsKICAgICAgICBjYXNlICdlJzoKICAgICAgICAgICAgcmV0dXJuIG5ldyBFbnVtQXR0cmlidXRlUHJveHkocmVhZEVudW1UeXBlKG5leHRDaGFyKCkpLCByZWFkTmFtZShuZXh0Q2hhcigpKSk7CiAgICAgICAgY2FzZSAnYyc6CiAgICAgICAgICAgIHJldHVybiBuZXcgQ2xhc3NBdHRyaWJ1dGVQcm94eShyZWFkVHlwZU9yQ2xhc3NTeW1ib2wobmV4dENoYXIoKSkpOwogICAgICAgIGNhc2UgJ1snOiB7CiAgICAgICAgICAgIGludCBuID0gbmV4dENoYXIoKTsKICAgICAgICAgICAgTGlzdEJ1ZmZlcjxBdHRyaWJ1dGU+IGwgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgIGZvciAoaW50IGk9MDsgaTxuOyBpKyspCiAgICAgICAgICAgICAgICBsLmFwcGVuZChyZWFkQXR0cmlidXRlVmFsdWUoKSk7CiAgICAgICAgICAgIHJldHVybiBuZXcgQXJyYXlBdHRyaWJ1dGVQcm94eShsLnRvTGlzdCgpKTsKICAgICAgICB9CiAgICAgICAgY2FzZSAnQCc6CiAgICAgICAgICAgIHJldHVybiByZWFkQ29tcG91bmRBbm5vdGF0aW9uKCk7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCJ1bmtub3duIGFubm90YXRpb24gdGFnICciICsgYyArICInIik7CiAgICAgICAgfQogICAgfQoKICAgIGludGVyZmFjZSBQcm94eVZpc2l0b3IgZXh0ZW5kcyBBdHRyaWJ1dGUuVmlzaXRvciB7CiAgICAgICAgdm9pZCB2aXNpdEVudW1BdHRyaWJ1dGVQcm94eShFbnVtQXR0cmlidXRlUHJveHkgcHJveHkpOwogICAgICAgIHZvaWQgdmlzaXRDbGFzc0F0dHJpYnV0ZVByb3h5KENsYXNzQXR0cmlidXRlUHJveHkgcHJveHkpOwogICAgICAgIHZvaWQgdmlzaXRBcnJheUF0dHJpYnV0ZVByb3h5KEFycmF5QXR0cmlidXRlUHJveHkgcHJveHkpOwogICAgICAgIHZvaWQgdmlzaXRDb21wb3VuZEFubm90YXRpb25Qcm94eShDb21wb3VuZEFubm90YXRpb25Qcm94eSBwcm94eSk7CiAgICB9CgogICAgc3RhdGljIGNsYXNzIEVudW1BdHRyaWJ1dGVQcm94eSBleHRlbmRzIEF0dHJpYnV0ZSB7CiAgICAgICAgVHlwZSBlbnVtVHlwZTsKICAgICAgICBOYW1lIGVudW1lcmF0b3I7CiAgICAgICAgcHVibGljIEVudW1BdHRyaWJ1dGVQcm94eShUeXBlIGVudW1UeXBlLCBOYW1lIGVudW1lcmF0b3IpIHsKICAgICAgICAgICAgc3VwZXIobnVsbCk7CiAgICAgICAgICAgIHRoaXMuZW51bVR5cGUgPSBlbnVtVHlwZTsKICAgICAgICAgICAgdGhpcy5lbnVtZXJhdG9yID0gZW51bWVyYXRvcjsKICAgICAgICB9CiAgICAgICAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgeyAoKFByb3h5VmlzaXRvcil2KS52aXNpdEVudW1BdHRyaWJ1dGVQcm94eSh0aGlzKTsgfQogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5MQU5HVUFHRV9NT0RFTCkKICAgICAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewogICAgICAgICAgICByZXR1cm4gIi8qcHJveHkgZW51bSovIiArIGVudW1UeXBlICsgIi4iICsgZW51bWVyYXRvcjsKICAgICAgICB9CiAgICB9CgogICAgc3RhdGljIGNsYXNzIENsYXNzQXR0cmlidXRlUHJveHkgZXh0ZW5kcyBBdHRyaWJ1dGUgewogICAgICAgIFR5cGUgY2xhc3NUeXBlOwogICAgICAgIHB1YmxpYyBDbGFzc0F0dHJpYnV0ZVByb3h5KFR5cGUgY2xhc3NUeXBlKSB7CiAgICAgICAgICAgIHN1cGVyKG51bGwpOwogICAgICAgICAgICB0aGlzLmNsYXNzVHlwZSA9IGNsYXNzVHlwZTsKICAgICAgICB9CiAgICAgICAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgeyAoKFByb3h5VmlzaXRvcil2KS52aXNpdENsYXNzQXR0cmlidXRlUHJveHkodGhpcyk7IH0KICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuTEFOR1VBR0VfTU9ERUwpCiAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKICAgICAgICAgICAgcmV0dXJuICIvKnByb3h5IGNsYXNzKi8iICsgY2xhc3NUeXBlICsgIi5jbGFzcyI7CiAgICAgICAgfQogICAgfQoKICAgIHN0YXRpYyBjbGFzcyBBcnJheUF0dHJpYnV0ZVByb3h5IGV4dGVuZHMgQXR0cmlidXRlIHsKICAgICAgICBMaXN0PEF0dHJpYnV0ZT4gdmFsdWVzOwogICAgICAgIEFycmF5QXR0cmlidXRlUHJveHkoTGlzdDxBdHRyaWJ1dGU+IHZhbHVlcykgewogICAgICAgICAgICBzdXBlcihudWxsKTsKICAgICAgICAgICAgdGhpcy52YWx1ZXMgPSB2YWx1ZXM7CiAgICAgICAgfQogICAgICAgIHB1YmxpYyB2b2lkIGFjY2VwdChWaXNpdG9yIHYpIHsgKChQcm94eVZpc2l0b3IpdikudmlzaXRBcnJheUF0dHJpYnV0ZVByb3h5KHRoaXMpOyB9CiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CiAgICAgICAgICAgIHJldHVybiAieyIgKyB2YWx1ZXMgKyAifSI7CiAgICAgICAgfQogICAgfQoKICAgIC8qKiBBIHRlbXBvcmFyeSBwcm94eSByZXByZXNlbnRpbmcgYSBjb21wb3VuZCBhdHRyaWJ1dGUuCiAgICAgKi8KICAgIHN0YXRpYyBjbGFzcyBDb21wb3VuZEFubm90YXRpb25Qcm94eSBleHRlbmRzIEF0dHJpYnV0ZSB7CiAgICAgICAgZmluYWwgTGlzdDxQYWlyPE5hbWUsQXR0cmlidXRlPj4gdmFsdWVzOwogICAgICAgIHB1YmxpYyBDb21wb3VuZEFubm90YXRpb25Qcm94eShUeXBlIHR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTGlzdDxQYWlyPE5hbWUsQXR0cmlidXRlPj4gdmFsdWVzKSB7CiAgICAgICAgICAgIHN1cGVyKHR5cGUpOwogICAgICAgICAgICB0aGlzLnZhbHVlcyA9IHZhbHVlczsKICAgICAgICB9CiAgICAgICAgcHVibGljIHZvaWQgYWNjZXB0KFZpc2l0b3IgdikgeyAoKFByb3h5VmlzaXRvcil2KS52aXNpdENvbXBvdW5kQW5ub3RhdGlvblByb3h5KHRoaXMpOyB9CiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CiAgICAgICAgICAgIFN0cmluZ0J1aWxkZXIgYnVmID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKICAgICAgICAgICAgYnVmLmFwcGVuZCgiQCIpOwogICAgICAgICAgICBidWYuYXBwZW5kKHR5cGUudHN5bS5nZXRRdWFsaWZpZWROYW1lKCkpOwogICAgICAgICAgICBidWYuYXBwZW5kKCIvKnByb3h5Ki97Iik7CiAgICAgICAgICAgIGJvb2xlYW4gZmlyc3QgPSB0cnVlOwogICAgICAgICAgICBmb3IgKExpc3Q8UGFpcjxOYW1lLEF0dHJpYnV0ZT4+IHYgPSB2YWx1ZXM7CiAgICAgICAgICAgICAgICAgdi5ub25FbXB0eSgpOyB2ID0gdi50YWlsKSB7CiAgICAgICAgICAgICAgICBQYWlyPE5hbWUsQXR0cmlidXRlPiB2YWx1ZSA9IHYuaGVhZDsKICAgICAgICAgICAgICAgIGlmICghZmlyc3QpIGJ1Zi5hcHBlbmQoIiwiKTsKICAgICAgICAgICAgICAgIGZpcnN0ID0gZmFsc2U7CiAgICAgICAgICAgICAgICBidWYuYXBwZW5kKHZhbHVlLmZzdCk7CiAgICAgICAgICAgICAgICBidWYuYXBwZW5kKCI9Iik7CiAgICAgICAgICAgICAgICBidWYuYXBwZW5kKHZhbHVlLnNuZCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnVmLmFwcGVuZCgifSIpOwogICAgICAgICAgICByZXR1cm4gYnVmLnRvU3RyaW5nKCk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKiBBIHRlbXBvcmFyeSBwcm94eSByZXByZXNlbnRpbmcgYSB0eXBlIGFubm90YXRpb24uCiAgICAgKi8KICAgIHN0YXRpYyBjbGFzcyBUeXBlQW5ub3RhdGlvblByb3h5IHsKICAgICAgICBmaW5hbCBDb21wb3VuZEFubm90YXRpb25Qcm94eSBjb21wb3VuZDsKICAgICAgICBmaW5hbCBUeXBlQW5ub3RhdGlvblBvc2l0aW9uIHBvc2l0aW9uOwogICAgICAgIHB1YmxpYyBUeXBlQW5ub3RhdGlvblByb3h5KENvbXBvdW5kQW5ub3RhdGlvblByb3h5IGNvbXBvdW5kLAogICAgICAgICAgICAgICAgVHlwZUFubm90YXRpb25Qb3NpdGlvbiBwb3NpdGlvbikgewogICAgICAgICAgICB0aGlzLmNvbXBvdW5kID0gY29tcG91bmQ7CiAgICAgICAgICAgIHRoaXMucG9zaXRpb24gPSBwb3NpdGlvbjsKICAgICAgICB9CiAgICB9CgogICAgY2xhc3MgQW5ub3RhdGlvbkRlcHJveHkgaW1wbGVtZW50cyBQcm94eVZpc2l0b3IgewogICAgICAgIHByaXZhdGUgQ2xhc3NTeW1ib2wgcmVxdWVzdGluZ093bmVyOwoKICAgICAgICBBbm5vdGF0aW9uRGVwcm94eShDbGFzc1N5bWJvbCBvd25lcikgewogICAgICAgICAgICB0aGlzLnJlcXVlc3RpbmdPd25lciA9IG93bmVyOwogICAgICAgIH0KCiAgICAgICAgTGlzdDxBdHRyaWJ1dGUuQ29tcG91bmQ+IGRlcHJveHlDb21wb3VuZExpc3QoTGlzdDxDb21wb3VuZEFubm90YXRpb25Qcm94eT4gcGwpIHsKICAgICAgICAgICAgLy8gYWxzbyBtdXN0IGZpbGwgaW4gdHlwZXMhISEhCiAgICAgICAgICAgIExpc3RCdWZmZXI8QXR0cmlidXRlLkNvbXBvdW5kPiBidWYgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgIGZvciAoTGlzdDxDb21wb3VuZEFubm90YXRpb25Qcm94eT4gbCA9IHBsOyBsLm5vbkVtcHR5KCk7IGw9bC50YWlsKSB7CiAgICAgICAgICAgICAgICBidWYuYXBwZW5kKGRlcHJveHlDb21wb3VuZChsLmhlYWQpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gYnVmLnRvTGlzdCgpOwogICAgICAgIH0KCiAgICAgICAgQXR0cmlidXRlLkNvbXBvdW5kIGRlcHJveHlDb21wb3VuZChDb21wb3VuZEFubm90YXRpb25Qcm94eSBhKSB7CiAgICAgICAgICAgIFR5cGUgYW5ub3RhdGlvblR5cGUgPSByZXNvbHZlUG9zc2libGVQcm94eVR5cGUoYS50eXBlKTsKICAgICAgICAgICAgTGlzdEJ1ZmZlcjxQYWlyPFN5bWJvbC5NZXRob2RTeW1ib2wsQXR0cmlidXRlPj4gYnVmID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgICAgICBmb3IgKExpc3Q8UGFpcjxOYW1lLEF0dHJpYnV0ZT4+IGwgPSBhLnZhbHVlczsKICAgICAgICAgICAgICAgICBsLm5vbkVtcHR5KCk7CiAgICAgICAgICAgICAgICAgbCA9IGwudGFpbCkgewogICAgICAgICAgICAgICAgTWV0aG9kU3ltYm9sIG1ldGggPSBmaW5kQWNjZXNzTWV0aG9kKGFubm90YXRpb25UeXBlLCBsLmhlYWQuZnN0KTsKICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQobmV3IFBhaXI8PihtZXRoLCBkZXByb3h5KG1ldGgudHlwZS5nZXRSZXR1cm5UeXBlKCksIGwuaGVhZC5zbmQpKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG5ldyBBdHRyaWJ1dGUuQ29tcG91bmQoYW5ub3RhdGlvblR5cGUsIGJ1Zi50b0xpc3QoKSk7CiAgICAgICAgfQoKICAgICAgICBNZXRob2RTeW1ib2wgZmluZEFjY2Vzc01ldGhvZChUeXBlIGNvbnRhaW5lciwgTmFtZSBuYW1lKSB7CiAgICAgICAgICAgIENvbXBsZXRpb25GYWlsdXJlIGZhaWx1cmUgPSBudWxsOwogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgZm9yIChTeW1ib2wgc3ltIDogY29udGFpbmVyLnRzeW0ubWVtYmVycygpLmdldFN5bWJvbHNCeU5hbWUobmFtZSkpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoc3ltLmtpbmQgPT0gTVRIICYmIHN5bS50eXBlLmdldFBhcmFtZXRlclR5cGVzKCkubGVuZ3RoKCkgPT0gMCkKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChNZXRob2RTeW1ib2wpIHN5bTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBjYXRjaCAoQ29tcGxldGlvbkZhaWx1cmUgZXgpIHsKICAgICAgICAgICAgICAgIGZhaWx1cmUgPSBleDsKICAgICAgICAgICAgfQogICAgICAgICAgICAvLyBUaGUgbWV0aG9kIHdhc24ndCBmb3VuZDogZW1pdCBhIHdhcm5pbmcgYW5kIHJlY292ZXIKICAgICAgICAgICAgSmF2YUZpbGVPYmplY3QgcHJldlNvdXJjZSA9IGxvZy51c2VTb3VyY2UocmVxdWVzdGluZ093bmVyLmNsYXNzZmlsZSk7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBpZiAobGludENsYXNzZmlsZSkgewogICAgICAgICAgICAgICAgICAgIGlmIChmYWlsdXJlID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgbG9nLndhcm5pbmcoImFubm90YXRpb24ubWV0aG9kLm5vdC5mb3VuZCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRhaW5lciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgbG9nLndhcm5pbmcoImFubm90YXRpb24ubWV0aG9kLm5vdC5mb3VuZC5yZWFzb24iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250YWluZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhaWx1cmUuZ2V0RGV0YWlsVmFsdWUoKSk7Ly9kaWFnbm9zdGljLCBpZiBwcmVzZW50CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAgICAgbG9nLnVzZVNvdXJjZShwcmV2U291cmNlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvLyBDb25zdHJ1Y3QgYSBuZXcgbWV0aG9kIHR5cGUgYW5kIHN5bWJvbC4gIFVzZSBib3R0b20KICAgICAgICAgICAgLy8gdHlwZSAodHlwZW9mIG51bGwpIGFzIHJldHVybiB0eXBlIGJlY2F1c2UgdGhpcyB0eXBlIGlzCiAgICAgICAgICAgIC8vIGEgc3VidHlwZSBvZiBhbGwgcmVmZXJlbmNlIHR5cGVzIGFuZCBjYW4gYmUgY29udmVydGVkCiAgICAgICAgICAgIC8vIHRvIHByaW1pdGl2ZSB0eXBlcyBieSB1bmJveGluZy4KICAgICAgICAgICAgTWV0aG9kVHlwZSBtdCA9IG5ldyBNZXRob2RUeXBlKExpc3QubmlsKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeW1zLmJvdFR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0Lm5pbCgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ltcy5tZXRob2RDbGFzcyk7CiAgICAgICAgICAgIHJldHVybiBuZXcgTWV0aG9kU3ltYm9sKFBVQkxJQyB8IEFCU1RSQUNULCBuYW1lLCBtdCwgY29udGFpbmVyLnRzeW0pOwogICAgICAgIH0KCiAgICAgICAgQXR0cmlidXRlIHJlc3VsdDsKICAgICAgICBUeXBlIHR5cGU7CiAgICAgICAgQXR0cmlidXRlIGRlcHJveHkoVHlwZSB0LCBBdHRyaWJ1dGUgYSkgewogICAgICAgICAgICBUeXBlIG9sZFR5cGUgPSB0eXBlOwogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgdHlwZSA9IHQ7CiAgICAgICAgICAgICAgICBhLmFjY2VwdCh0aGlzKTsKICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgICAgICB0eXBlID0gb2xkVHlwZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gaW1wbGVtZW50IEF0dHJpYnV0ZS5WaXNpdG9yIGJlbG93CgogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0Q29uc3RhbnQoQXR0cmlidXRlLkNvbnN0YW50IHZhbHVlKSB7CiAgICAgICAgICAgIC8vIGFzc2VydCB2YWx1ZS50eXBlID09IHR5cGU7CiAgICAgICAgICAgIHJlc3VsdCA9IHZhbHVlOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRDbGFzcyhBdHRyaWJ1dGUuQ2xhc3MgY2xhenopIHsKICAgICAgICAgICAgcmVzdWx0ID0gY2xheno7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdEVudW0oQXR0cmlidXRlLkVudW0gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoKTsgLy8gc2hvdWxkbid0IGhhcHBlbgogICAgICAgIH0KCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRDb21wb3VuZChBdHRyaWJ1dGUuQ29tcG91bmQgY29tcG91bmQpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCk7IC8vIHNob3VsZG4ndCBoYXBwZW4KICAgICAgICB9CgogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0QXJyYXkoQXR0cmlidXRlLkFycmF5IGFycmF5KSB7CiAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigpOyAvLyBzaG91bGRuJ3QgaGFwcGVuCiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdEVycm9yKEF0dHJpYnV0ZS5FcnJvciBlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigpOyAvLyBzaG91bGRuJ3QgaGFwcGVuCiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdEVudW1BdHRyaWJ1dGVQcm94eShFbnVtQXR0cmlidXRlUHJveHkgcHJveHkpIHsKICAgICAgICAgICAgLy8gdHlwZS50c3ltLmZsYXROYW1lKCkgc2hvdWxkID09IHByb3h5LmVudW1GbGF0TmFtZQogICAgICAgICAgICBUeXBlIGVudW1UeXBlID0gcmVzb2x2ZVBvc3NpYmxlUHJveHlUeXBlKHByb3h5LmVudW1UeXBlKTsKICAgICAgICAgICAgVHlwZVN5bWJvbCBlbnVtVHlwZVN5bSA9IGVudW1UeXBlLnRzeW07CiAgICAgICAgICAgIFZhclN5bWJvbCBlbnVtZXJhdG9yID0gbnVsbDsKICAgICAgICAgICAgQ29tcGxldGlvbkZhaWx1cmUgZmFpbHVyZSA9IG51bGw7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBmb3IgKFN5bWJvbCBzeW0gOiBlbnVtVHlwZVN5bS5tZW1iZXJzKCkuZ2V0U3ltYm9sc0J5TmFtZShwcm94eS5lbnVtZXJhdG9yKSkgewogICAgICAgICAgICAgICAgICAgIGlmIChzeW0ua2luZCA9PSBWQVIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgZW51bWVyYXRvciA9IChWYXJTeW1ib2wpc3ltOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY2F0Y2ggKENvbXBsZXRpb25GYWlsdXJlIGV4KSB7CiAgICAgICAgICAgICAgICBmYWlsdXJlID0gZXg7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGVudW1lcmF0b3IgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgaWYgKGZhaWx1cmUgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIGxvZy53YXJuaW5nKCJ1bmtub3duLmVudW0uY29uc3RhbnQucmVhc29uIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudENsYXNzRmlsZSwgZW51bVR5cGVTeW0sIHByb3h5LmVudW1lcmF0b3IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhaWx1cmUuZ2V0RGlhZ25vc3RpYygpKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgbG9nLndhcm5pbmcoInVua25vd24uZW51bS5jb25zdGFudCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRDbGFzc0ZpbGUsIGVudW1UeXBlU3ltLCBwcm94eS5lbnVtZXJhdG9yKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJlc3VsdCA9IG5ldyBBdHRyaWJ1dGUuRW51bShlbnVtVHlwZVN5bS50eXBlLAogICAgICAgICAgICAgICAgICAgICAgICBuZXcgVmFyU3ltYm9sKDAsIHByb3h5LmVudW1lcmF0b3IsIHN5bXMuYm90VHlwZSwgZW51bVR5cGVTeW0pKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHJlc3VsdCA9IG5ldyBBdHRyaWJ1dGUuRW51bShlbnVtVHlwZVN5bS50eXBlLCBlbnVtZXJhdG9yKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRDbGFzc0F0dHJpYnV0ZVByb3h5KENsYXNzQXR0cmlidXRlUHJveHkgcHJveHkpIHsKICAgICAgICAgICAgVHlwZSBjbGFzc1R5cGUgPSByZXNvbHZlUG9zc2libGVQcm94eVR5cGUocHJveHkuY2xhc3NUeXBlKTsKICAgICAgICAgICAgcmVzdWx0ID0gbmV3IEF0dHJpYnV0ZS5DbGFzcyh0eXBlcywgY2xhc3NUeXBlKTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0QXJyYXlBdHRyaWJ1dGVQcm94eShBcnJheUF0dHJpYnV0ZVByb3h5IHByb3h5KSB7CiAgICAgICAgICAgIGludCBsZW5ndGggPSBwcm94eS52YWx1ZXMubGVuZ3RoKCk7CiAgICAgICAgICAgIEF0dHJpYnV0ZVtdIGF0cyA9IG5ldyBBdHRyaWJ1dGVbbGVuZ3RoXTsKICAgICAgICAgICAgVHlwZSBlbGVtdHlwZSA9IHR5cGVzLmVsZW10eXBlKHR5cGUpOwogICAgICAgICAgICBpbnQgaSA9IDA7CiAgICAgICAgICAgIGZvciAoTGlzdDxBdHRyaWJ1dGU+IHAgPSBwcm94eS52YWx1ZXM7IHAubm9uRW1wdHkoKTsgcCA9IHAudGFpbCkgewogICAgICAgICAgICAgICAgYXRzW2krK10gPSBkZXByb3h5KGVsZW10eXBlLCBwLmhlYWQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJlc3VsdCA9IG5ldyBBdHRyaWJ1dGUuQXJyYXkodHlwZSwgYXRzKTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0Q29tcG91bmRBbm5vdGF0aW9uUHJveHkoQ29tcG91bmRBbm5vdGF0aW9uUHJveHkgcHJveHkpIHsKICAgICAgICAgICAgcmVzdWx0ID0gZGVwcm94eUNvbXBvdW5kKHByb3h5KTsKICAgICAgICB9CgogICAgICAgIFR5cGUgcmVzb2x2ZVBvc3NpYmxlUHJveHlUeXBlKFR5cGUgdCkgewogICAgICAgICAgICBpZiAodCBpbnN0YW5jZW9mIFByb3h5VHlwZSkgewogICAgICAgICAgICAgICAgQXNzZXJ0LmNoZWNrKHJlcXVlc3RpbmdPd25lci5vd25lci5raW5kID09IE1ETCk7CiAgICAgICAgICAgICAgICBNb2R1bGVTeW1ib2wgcHJldkN1cnJlbnRNb2R1bGUgPSBjdXJyZW50TW9kdWxlOwogICAgICAgICAgICAgICAgY3VycmVudE1vZHVsZSA9IChNb2R1bGVTeW1ib2wpIHJlcXVlc3RpbmdPd25lci5vd25lcjsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICgoUHJveHlUeXBlKSB0KS5yZXNvbHZlKCk7CiAgICAgICAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAgICAgICAgIGN1cnJlbnRNb2R1bGUgPSBwcmV2Q3VycmVudE1vZHVsZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHJldHVybiB0OwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIGNsYXNzIEFubm90YXRpb25EZWZhdWx0Q29tcGxldGVyIGV4dGVuZHMgQW5ub3RhdGlvbkRlcHJveHkgaW1wbGVtZW50cyBSdW5uYWJsZSB7CiAgICAgICAgZmluYWwgTWV0aG9kU3ltYm9sIHN5bTsKICAgICAgICBmaW5hbCBBdHRyaWJ1dGUgdmFsdWU7CiAgICAgICAgZmluYWwgSmF2YUZpbGVPYmplY3QgY2xhc3NGaWxlID0gY3VycmVudENsYXNzRmlsZTsKCiAgICAgICAgQW5ub3RhdGlvbkRlZmF1bHRDb21wbGV0ZXIoTWV0aG9kU3ltYm9sIHN5bSwgQXR0cmlidXRlIHZhbHVlKSB7CiAgICAgICAgICAgIHN1cGVyKGN1cnJlbnRPd25lci5raW5kID09IE1USAogICAgICAgICAgICAgICAgICAgID8gY3VycmVudE93bmVyLmVuY2xDbGFzcygpIDogKENsYXNzU3ltYm9sKWN1cnJlbnRPd25lcik7CiAgICAgICAgICAgIHRoaXMuc3ltID0gc3ltOwogICAgICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCBydW4oKSB7CiAgICAgICAgICAgIEphdmFGaWxlT2JqZWN0IHByZXZpb3VzQ2xhc3NGaWxlID0gY3VycmVudENsYXNzRmlsZTsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIC8vIFJlc2V0IHRoZSBpbnRlcmltIHZhbHVlIHNldCBlYXJsaWVyIGluCiAgICAgICAgICAgICAgICAvLyBhdHRhY2hBbm5vdGF0aW9uRGVmYXVsdCgpLgogICAgICAgICAgICAgICAgc3ltLmRlZmF1bHRWYWx1ZSA9IG51bGw7CiAgICAgICAgICAgICAgICBjdXJyZW50Q2xhc3NGaWxlID0gY2xhc3NGaWxlOwogICAgICAgICAgICAgICAgc3ltLmRlZmF1bHRWYWx1ZSA9IGRlcHJveHkoc3ltLnR5cGUuZ2V0UmV0dXJuVHlwZSgpLCB2YWx1ZSk7CiAgICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgICAgICBjdXJyZW50Q2xhc3NGaWxlID0gcHJldmlvdXNDbGFzc0ZpbGU7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CiAgICAgICAgICAgIHJldHVybiAiIENsYXNzUmVhZGVyIHN0b3JlIGRlZmF1bHQgZm9yICIgKyBzeW0ub3duZXIgKyAiLiIgKyBzeW0gKyAiIGlzICIgKyB2YWx1ZTsKICAgICAgICB9CiAgICB9CgogICAgY2xhc3MgQW5ub3RhdGlvbkNvbXBsZXRlciBleHRlbmRzIEFubm90YXRpb25EZXByb3h5IGltcGxlbWVudHMgUnVubmFibGUgewogICAgICAgIGZpbmFsIFN5bWJvbCBzeW07CiAgICAgICAgZmluYWwgTGlzdDxDb21wb3VuZEFubm90YXRpb25Qcm94eT4gbDsKICAgICAgICBmaW5hbCBKYXZhRmlsZU9iamVjdCBjbGFzc0ZpbGU7CgogICAgICAgIEFubm90YXRpb25Db21wbGV0ZXIoU3ltYm9sIHN5bSwgTGlzdDxDb21wb3VuZEFubm90YXRpb25Qcm94eT4gbCkgewogICAgICAgICAgICBzdXBlcihjdXJyZW50T3duZXIua2luZCA9PSBNVEgKICAgICAgICAgICAgICAgICAgICA/IGN1cnJlbnRPd25lci5lbmNsQ2xhc3MoKSA6IChDbGFzc1N5bWJvbCljdXJyZW50T3duZXIpOwogICAgICAgICAgICBpZiAoc3ltLmtpbmQgPT0gVFlQICYmIHN5bS5vd25lci5raW5kID09IE1ETCkgewogICAgICAgICAgICAgICAgdGhpcy5zeW0gPSBzeW0ub3duZXI7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB0aGlzLnN5bSA9IHN5bTsKICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLmwgPSBsOwogICAgICAgICAgICB0aGlzLmNsYXNzRmlsZSA9IGN1cnJlbnRDbGFzc0ZpbGU7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCBydW4oKSB7CiAgICAgICAgICAgIEphdmFGaWxlT2JqZWN0IHByZXZpb3VzQ2xhc3NGaWxlID0gY3VycmVudENsYXNzRmlsZTsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIGN1cnJlbnRDbGFzc0ZpbGUgPSBjbGFzc0ZpbGU7CiAgICAgICAgICAgICAgICBMaXN0PEF0dHJpYnV0ZS5Db21wb3VuZD4gbmV3TGlzdCA9IGRlcHJveHlDb21wb3VuZExpc3QobCk7CiAgICAgICAgICAgICAgICBmb3IgKEF0dHJpYnV0ZS5Db21wb3VuZCBhdHRyIDogbmV3TGlzdCkgewogICAgICAgICAgICAgICAgICAgIGlmIChhdHRyLnR5cGUudHN5bSA9PSBzeW1zLmRlcHJlY2F0ZWRUeXBlLnRzeW0pIHsKICAgICAgICAgICAgICAgICAgICAgICAgc3ltLmZsYWdzX2ZpZWxkIHw9IChERVBSRUNBVEVEIHwgREVQUkVDQVRFRF9BTk5PVEFUSU9OKTsKICAgICAgICAgICAgICAgICAgICAgICAgQXR0cmlidXRlIGZvclJlbW92YWwgPSBhdHRyLm1lbWJlcihuYW1lcy5mb3JSZW1vdmFsKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZvclJlbW92YWwgaW5zdGFuY2VvZiBBdHRyaWJ1dGUuQ29uc3RhbnQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0dHJpYnV0ZS5Db25zdGFudCBjID0gKEF0dHJpYnV0ZS5Db25zdGFudCkgZm9yUmVtb3ZhbDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjLnR5cGUgPT0gc3ltcy5ib29sZWFuVHlwZSAmJiAoKEludGVnZXIpIGMudmFsdWUpICE9IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeW0uZmxhZ3NfZmllbGQgfD0gREVQUkVDQVRFRF9SRU1PVkFMOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKHN5bS5hbm5vdGF0aW9uc1BlbmRpbmdDb21wbGV0aW9uKCkpIHsKICAgICAgICAgICAgICAgICAgICBzeW0uc2V0RGVjbGFyYXRpb25BdHRyaWJ1dGVzKG5ld0xpc3QpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBzeW0uYXBwZW5kQXR0cmlidXRlcyhuZXdMaXN0KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgICAgIGN1cnJlbnRDbGFzc0ZpbGUgPSBwcmV2aW91c0NsYXNzRmlsZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKICAgICAgICAgICAgcmV0dXJuICIgQ2xhc3NSZWFkZXIgYW5ub3RhdGUgIiArIHN5bS5vd25lciArICIuIiArIHN5bSArICIgd2l0aCAiICsgbDsKICAgICAgICB9CiAgICB9CgogICAgY2xhc3MgVHlwZUFubm90YXRpb25Db21wbGV0ZXIgZXh0ZW5kcyBBbm5vdGF0aW9uQ29tcGxldGVyIHsKCiAgICAgICAgTGlzdDxUeXBlQW5ub3RhdGlvblByb3h5PiBwcm94aWVzOwoKICAgICAgICBUeXBlQW5ub3RhdGlvbkNvbXBsZXRlcihTeW1ib2wgc3ltLAogICAgICAgICAgICAgICAgTGlzdDxUeXBlQW5ub3RhdGlvblByb3h5PiBwcm94aWVzKSB7CiAgICAgICAgICAgIHN1cGVyKHN5bSwgTGlzdC5uaWwoKSk7CiAgICAgICAgICAgIHRoaXMucHJveGllcyA9IHByb3hpZXM7CiAgICAgICAgfQoKICAgICAgICBMaXN0PEF0dHJpYnV0ZS5UeXBlQ29tcG91bmQ+IGRlcHJveHlUeXBlQ29tcG91bmRMaXN0KExpc3Q8VHlwZUFubm90YXRpb25Qcm94eT4gcHJveGllcykgewogICAgICAgICAgICBMaXN0QnVmZmVyPEF0dHJpYnV0ZS5UeXBlQ29tcG91bmQ+IGJ1ZiA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICAgICAgZm9yIChUeXBlQW5ub3RhdGlvblByb3h5IHByb3h5OiBwcm94aWVzKSB7CiAgICAgICAgICAgICAgICBBdHRyaWJ1dGUuQ29tcG91bmQgY29tcG91bmQgPSBkZXByb3h5Q29tcG91bmQocHJveHkuY29tcG91bmQpOwogICAgICAgICAgICAgICAgQXR0cmlidXRlLlR5cGVDb21wb3VuZCB0eXBlQ29tcG91bmQgPSBuZXcgQXR0cmlidXRlLlR5cGVDb21wb3VuZChjb21wb3VuZCwgcHJveHkucG9zaXRpb24pOwogICAgICAgICAgICAgICAgYnVmLmFkZCh0eXBlQ29tcG91bmQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBidWYudG9MaXN0KCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCBydW4oKSB7CiAgICAgICAgICAgIEphdmFGaWxlT2JqZWN0IHByZXZpb3VzQ2xhc3NGaWxlID0gY3VycmVudENsYXNzRmlsZTsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIGN1cnJlbnRDbGFzc0ZpbGUgPSBjbGFzc0ZpbGU7CiAgICAgICAgICAgICAgICBMaXN0PEF0dHJpYnV0ZS5UeXBlQ29tcG91bmQ+IG5ld0xpc3QgPSBkZXByb3h5VHlwZUNvbXBvdW5kTGlzdChwcm94aWVzKTsKICAgICAgICAgICAgICAgIHN5bS5zZXRUeXBlQXR0cmlidXRlcyhuZXdMaXN0LnByZXBlbmRMaXN0KHN5bS5nZXRSYXdUeXBlQXR0cmlidXRlcygpKSk7CiAgICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgICAgICBjdXJyZW50Q2xhc3NGaWxlID0gcHJldmlvdXNDbGFzc0ZpbGU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWFkaW5nIFN5bWJvbHMKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKICAgIC8qKiBSZWFkIGEgZmllbGQuCiAgICAgKi8KICAgIFZhclN5bWJvbCByZWFkRmllbGQoKSB7CiAgICAgICAgbG9uZyBmbGFncyA9IGFkanVzdEZpZWxkRmxhZ3MobmV4dENoYXIoKSk7CiAgICAgICAgTmFtZSBuYW1lID0gcmVhZE5hbWUobmV4dENoYXIoKSk7CiAgICAgICAgVHlwZSB0eXBlID0gcmVhZFR5cGUobmV4dENoYXIoKSk7CiAgICAgICAgVmFyU3ltYm9sIHYgPSBuZXcgVmFyU3ltYm9sKGZsYWdzLCBuYW1lLCB0eXBlLCBjdXJyZW50T3duZXIpOwogICAgICAgIHJlYWRNZW1iZXJBdHRycyh2KTsKICAgICAgICByZXR1cm4gdjsKICAgIH0KCiAgICAvKiogUmVhZCBhIG1ldGhvZC4KICAgICAqLwogICAgTWV0aG9kU3ltYm9sIHJlYWRNZXRob2QoKSB7CiAgICAgICAgbG9uZyBmbGFncyA9IGFkanVzdE1ldGhvZEZsYWdzKG5leHRDaGFyKCkpOwogICAgICAgIE5hbWUgbmFtZSA9IHJlYWROYW1lKG5leHRDaGFyKCkpOwogICAgICAgIFR5cGUgdHlwZSA9IHJlYWRUeXBlKG5leHRDaGFyKCkpOwogICAgICAgIGlmIChjdXJyZW50T3duZXIuaXNJbnRlcmZhY2UoKSAmJgogICAgICAgICAgICAgICAgKGZsYWdzICYgQUJTVFJBQ1QpID09IDAgJiYgIW5hbWUuZXF1YWxzKG5hbWVzLmNsaW5pdCkpIHsKICAgICAgICAgICAgaWYgKG1ham9yVmVyc2lvbiA+IFZlcnNpb24uVjUyLm1ham9yIHx8CiAgICAgICAgICAgICAgICAgICAgKG1ham9yVmVyc2lvbiA9PSBWZXJzaW9uLlY1Mi5tYWpvciAmJiBtaW5vclZlcnNpb24gPj0gVmVyc2lvbi5WNTIubWlub3IpKSB7CiAgICAgICAgICAgICAgICBpZiAoKGZsYWdzICYgU1RBVElDKSA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgY3VycmVudE93bmVyLmZsYWdzX2ZpZWxkIHw9IERFRkFVTFQ7CiAgICAgICAgICAgICAgICAgICAgZmxhZ3MgfD0gREVGQVVMVCB8IEFCU1RSQUNUOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgLy9wcm90ZWN0IGFnYWluc3QgaWxsLWZvcm1lZCBjbGFzc2ZpbGVzCiAgICAgICAgICAgICAgICB0aHJvdyBiYWRDbGFzc0ZpbGUoKGZsYWdzICYgU1RBVElDKSA9PSAwID8gImludmFsaWQuZGVmYXVsdC5pbnRlcmZhY2UiIDogImludmFsaWQuc3RhdGljLmludGVyZmFjZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW50ZWdlci50b1N0cmluZyhtYWpvclZlcnNpb24pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEludGVnZXIudG9TdHJpbmcobWlub3JWZXJzaW9uKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKG5hbWUgPT0gbmFtZXMuaW5pdCAmJiBjdXJyZW50T3duZXIuaGFzT3V0ZXJJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIC8vIFNvbWV0aW1lcyBhbm9ueW1vdXMgY2xhc3NlcyBkb24ndCBoYXZlIGFuIG91dGVyCiAgICAgICAgICAgIC8vIGluc3RhbmNlLCBob3dldmVyLCB0aGVyZSBpcyBubyByZWxpYWJsZSB3YXkgdG8gdGVsbCBzbwogICAgICAgICAgICAvLyB3ZSBuZXZlciBzdHJpcCB0aGlzJG4KICAgICAgICAgICAgLy8gZGl0dG8gZm9yIGxvY2FsIGNsYXNzZXMuIExvY2FsIGNsYXNzZXMgdGhhdCBoYXZlIGFuIGVuY2xvc2luZyBtZXRob2Qgc2V0CiAgICAgICAgICAgIC8vIHdvbid0IHBhc3MgdGhlICJoYXNPdXRlckluc3RhbmNlIiBjaGVjayBhYm92ZSwgYnV0IHRob3NlIHRoYXQgZG9uJ3QgaGF2ZSBhbgogICAgICAgICAgICAvLyBlbmNsb3NpbmcgbWV0aG9kIChpLmUuIGZyb20gaW5pdGlhbGl6ZXJzKSB3aWxsIHBhc3MgdGhhdCBjaGVjay4KICAgICAgICAgICAgYm9vbGVhbiBsb2NhbCA9ICFjdXJyZW50T3duZXIub3duZXIubWVtYmVycygpLmluY2x1ZGVzKGN1cnJlbnRPd25lciwgTG9va3VwS2luZC5OT05fUkVDVVJTSVZFKTsKICAgICAgICAgICAgaWYgKCFjdXJyZW50T3duZXIubmFtZS5pc0VtcHR5KCkgJiYgIWxvY2FsKQogICAgICAgICAgICAgICAgdHlwZSA9IG5ldyBNZXRob2RUeXBlKGFkanVzdE1ldGhvZFBhcmFtcyhmbGFncywgdHlwZS5nZXRQYXJhbWV0ZXJUeXBlcygpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlLmdldFJldHVyblR5cGUoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlLmdldFRocm93blR5cGVzKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ltcy5tZXRob2RDbGFzcyk7CiAgICAgICAgfQogICAgICAgIE1ldGhvZFN5bWJvbCBtID0gbmV3IE1ldGhvZFN5bWJvbChmbGFncywgbmFtZSwgdHlwZSwgY3VycmVudE93bmVyKTsKICAgICAgICBpZiAodHlwZXMuaXNTaWduYXR1cmVQb2x5bW9ycGhpYyhtKSkgewogICAgICAgICAgICBtLmZsYWdzX2ZpZWxkIHw9IFNJR05BVFVSRV9QT0xZTU9SUEhJQzsKICAgICAgICB9CiAgICAgICAgaWYgKHNhdmVQYXJhbWV0ZXJOYW1lcykKICAgICAgICAgICAgaW5pdFBhcmFtZXRlck5hbWVzKG0pOwogICAgICAgIFN5bWJvbCBwcmV2T3duZXIgPSBjdXJyZW50T3duZXI7CiAgICAgICAgY3VycmVudE93bmVyID0gbTsKICAgICAgICB0cnkgewogICAgICAgICAgICByZWFkTWVtYmVyQXR0cnMobSk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgY3VycmVudE93bmVyID0gcHJldk93bmVyOwogICAgICAgIH0KICAgICAgICBpZiAoc2F2ZVBhcmFtZXRlck5hbWVzKQogICAgICAgICAgICBzZXRQYXJhbWV0ZXJOYW1lcyhtLCB0eXBlKTsKCiAgICAgICAgaWYgKChmbGFncyAmIFZBUkFSR1MpICE9IDApIHsKICAgICAgICAgICAgZmluYWwgVHlwZSBsYXN0ID0gdHlwZS5nZXRQYXJhbWV0ZXJUeXBlcygpLmxhc3QoKTsKICAgICAgICAgICAgaWYgKGxhc3QgPT0gbnVsbCB8fCAhbGFzdC5oYXNUYWcoQVJSQVkpKSB7CiAgICAgICAgICAgICAgICBtLmZsYWdzX2ZpZWxkICY9IH5WQVJBUkdTOwogICAgICAgICAgICAgICAgdGhyb3cgYmFkQ2xhc3NGaWxlKCJtYWxmb3JtZWQudmFyYXJnLm1ldGhvZCIsIG0pOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gbTsKICAgIH0KCiAgICBwcml2YXRlIExpc3Q8VHlwZT4gYWRqdXN0TWV0aG9kUGFyYW1zKGxvbmcgZmxhZ3MsIExpc3Q8VHlwZT4gYXJncykgewogICAgICAgIGJvb2xlYW4gaXNWYXJhcmdzID0gKGZsYWdzICYgVkFSQVJHUykgIT0gMDsKICAgICAgICBpZiAoaXNWYXJhcmdzKSB7CiAgICAgICAgICAgIFR5cGUgdmFyYXJnc0VsZW0gPSBhcmdzLmxhc3QoKTsKICAgICAgICAgICAgTGlzdEJ1ZmZlcjxUeXBlPiBhZGp1c3RlZEFyZ3MgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgIGZvciAoVHlwZSB0IDogYXJncykgewogICAgICAgICAgICAgICAgYWRqdXN0ZWRBcmdzLmFwcGVuZCh0ICE9IHZhcmFyZ3NFbGVtID8KICAgICAgICAgICAgICAgICAgICB0IDoKICAgICAgICAgICAgICAgICAgICAoKEFycmF5VHlwZSl0KS5tYWtlVmFyYXJncygpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBhcmdzID0gYWRqdXN0ZWRBcmdzLnRvTGlzdCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYXJncy50YWlsOwogICAgfQoKICAgIC8qKgogICAgICogSW5pdCB0aGUgcGFyYW1ldGVyIG5hbWVzIGFycmF5LgogICAgICogUGFyYW1ldGVyIG5hbWVzIGFyZSBjdXJyZW50bHkgaW5mZXJyZWQgZnJvbSB0aGUgbmFtZXMgaW4gdGhlCiAgICAgKiBMb2NhbFZhcmlhYmxlVGFibGUgYXR0cmlidXRlcyBvZiBhIENvZGUgYXR0cmlidXRlLgogICAgICogKE5vdGU6IHRoaXMgbWVhbnMgcGFyYW1ldGVyIG5hbWVzIGFyZSBjdXJyZW50bHkgbm90IGF2YWlsYWJsZSBmb3IKICAgICAqIG1ldGhvZHMgd2l0aG91dCBhIENvZGUgYXR0cmlidXRlLikKICAgICAqIFRoaXMgbWV0aG9kIGluaXRpYWxpemVzIGFuIGFycmF5IGluIHdoaWNoIHRvIHN0b3JlIHRoZSBuYW1lIGluZGV4ZXMKICAgICAqIG9mIHBhcmFtZXRlciBuYW1lcyBmb3VuZCBpbiBMb2NhbFZhcmlhYmxlVGFibGUgYXR0cmlidXRlcy4gSXQgaXMKICAgICAqIHNsaWdodGx5IHN1cGVyc2l6ZWQgdG8gYWxsb3cgZm9yIGFkZGl0aW9uYWwgc2xvdHMgd2l0aCBhIHN0YXJ0X3BjIG9mIDAuCiAgICAgKi8KICAgIHZvaWQgaW5pdFBhcmFtZXRlck5hbWVzKE1ldGhvZFN5bWJvbCBzeW0pIHsKICAgICAgICAvLyBtYWtlIGFsbG93YW5jZSBmb3Igc3ludGhldGljIHBhcmFtZXRlcnMuCiAgICAgICAgZmluYWwgaW50IGV4Y2Vzc1Nsb3RzID0gNDsKICAgICAgICBpbnQgZXhwZWN0ZWRQYXJhbWV0ZXJTbG90cyA9CiAgICAgICAgICAgICAgICBDb2RlLndpZHRoKHN5bS50eXBlLmdldFBhcmFtZXRlclR5cGVzKCkpICsgZXhjZXNzU2xvdHM7CiAgICAgICAgaWYgKHBhcmFtZXRlck5hbWVJbmRpY2VzID09IG51bGwKICAgICAgICAgICAgICAgIHx8IHBhcmFtZXRlck5hbWVJbmRpY2VzLmxlbmd0aCA8IGV4cGVjdGVkUGFyYW1ldGVyU2xvdHMpIHsKICAgICAgICAgICAgcGFyYW1ldGVyTmFtZUluZGljZXMgPSBuZXcgaW50W2V4cGVjdGVkUGFyYW1ldGVyU2xvdHNdOwogICAgICAgIH0gZWxzZQogICAgICAgICAgICBBcnJheXMuZmlsbChwYXJhbWV0ZXJOYW1lSW5kaWNlcywgMCk7CiAgICAgICAgaGF2ZVBhcmFtZXRlck5hbWVJbmRpY2VzID0gZmFsc2U7CiAgICAgICAgc2F3TWV0aG9kUGFyYW1ldGVycyA9IGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICogU2V0IHRoZSBwYXJhbWV0ZXIgbmFtZXMgZm9yIGEgc3ltYm9sIGZyb20gdGhlIG5hbWUgaW5kZXggaW4gdGhlCiAgICAgKiBwYXJhbWV0ZXJOYW1lSW5kaWNpZXMgYXJyYXkuIFRoZSB0eXBlIG9mIHRoZSBzeW1ib2wgbWF5IGhhdmUgY2hhbmdlZAogICAgICogd2hpbGUgcmVhZGluZyB0aGUgbWV0aG9kIGF0dHJpYnV0ZXMgKHNlZSB0aGUgU2lnbmF0dXJlIGF0dHJpYnV0ZSkuCiAgICAgKiBUaGlzIG1heSBiZSBiZWNhdXNlIG9mIGdlbmVyaWMgaW5mb3JtYXRpb24gb3IgYmVjYXVzZSBhbm9ueW1vdXMKICAgICAqIHN5bnRoZXRpYyBwYXJhbWV0ZXJzIHdlcmUgYWRkZWQuICAgVGhlIG9yaWdpbmFsIHR5cGUgKGFzIHJlYWQgZnJvbQogICAgICogdGhlIG1ldGhvZCBkZXNjcmlwdG9yKSBpcyB1c2VkIHRvIGhlbHAgZ3Vlc3MgdGhlIGV4aXN0ZW5jZSBvZgogICAgICogYW5vbnltb3VzIHN5bnRoZXRpYyBwYXJhbWV0ZXJzLgogICAgICogT24gY29tcGxldGlvbiwgc3ltLnNhdmVkUGFyYW1ldGVyIG5hbWVzIHdpbGwgZWl0aGVyIGJlIG51bGwgKGlmCiAgICAgKiBubyBwYXJhbWV0ZXIgbmFtZXMgd2VyZSBmb3VuZCBpbiB0aGUgY2xhc3MgZmlsZSkgb3Igd2lsbCBiZSBzZXQgdG8gYQogICAgICogbGlzdCBvZiBuYW1lcywgb25lIHBlciBlbnRyeSBpbiBzeW0udHlwZS5nZXRQYXJhbWV0ZXJUeXBlcywgd2l0aAogICAgICogYW55IG1pc3NpbmcgbmFtZXMgcmVwcmVzZW50ZWQgYnkgdGhlIGVtcHR5IG5hbWUuCiAgICAgKi8KICAgIHZvaWQgc2V0UGFyYW1ldGVyTmFtZXMoTWV0aG9kU3ltYm9sIHN5bSwgVHlwZSBqdm1UeXBlKSB7CiAgICAgICAgLy8gaWYgbm8gbmFtZXMgd2VyZSBmb3VuZCBpbiB0aGUgY2xhc3MgZmlsZSwgdGhlcmUncyBub3RoaW5nIG1vcmUgdG8gZG8KICAgICAgICBpZiAoIWhhdmVQYXJhbWV0ZXJOYW1lSW5kaWNlcykKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIC8vIElmIHdlIGdldCBwYXJhbWV0ZXIgbmFtZXMgZnJvbSBNZXRob2RQYXJhbWV0ZXJzLCB0aGVuIHdlCiAgICAgICAgLy8gZG9uJ3QgbmVlZCB0byBza2lwLgogICAgICAgIGludCBmaXJzdFBhcmFtID0gMDsKICAgICAgICBpZiAoIXNhd01ldGhvZFBhcmFtZXRlcnMpIHsKICAgICAgICAgICAgZmlyc3RQYXJhbSA9ICgoc3ltLmZsYWdzKCkgJiBTVEFUSUMpID09IDApID8gMSA6IDA7CiAgICAgICAgICAgIC8vIHRoZSBjb2RlIGluIHJlYWRNZXRob2QgbWF5IGhhdmUgc2tpcHBlZCB0aGUgZmlyc3QKICAgICAgICAgICAgLy8gcGFyYW1ldGVyIHdoZW4gc2V0dGluZyB1cCB0aGUgTWV0aG9kVHlwZS4gSWYgc28sIHdlCiAgICAgICAgICAgIC8vIG1ha2UgYSBjb3JyZXNwb25kaW5nIGFsbG93YW5jZSBoZXJlIGZvciB0aGUgcG9zaXRpb24gb2YKICAgICAgICAgICAgLy8gdGhlIGZpcnN0IHBhcmFtZXRlci4gIE5vdGUgdGhhdCB0aGlzIGFzc3VtZXMgdGhlCiAgICAgICAgICAgIC8vIHNraXBwZWQgcGFyYW1ldGVyIGhhcyBhIHdpZHRoIG9mIDEgLS0gaS5lLiBpdCBpcyBub3QKICAgICAgICAvLyBhIGRvdWJsZSB3aWR0aCB0eXBlIChsb25nIG9yIGRvdWJsZS4pCiAgICAgICAgaWYgKHN5bS5uYW1lID09IG5hbWVzLmluaXQgJiYgY3VycmVudE93bmVyLmhhc091dGVySW5zdGFuY2UoKSkgewogICAgICAgICAgICAvLyBTb21ldGltZXMgYW5vbnltb3VzIGNsYXNzZXMgZG9uJ3QgaGF2ZSBhbiBvdXRlcgogICAgICAgICAgICAvLyBpbnN0YW5jZSwgaG93ZXZlciwgdGhlcmUgaXMgbm8gcmVsaWFibGUgd2F5IHRvIHRlbGwgc28KICAgICAgICAgICAgLy8gd2UgbmV2ZXIgc3RyaXAgdGhpcyRuCiAgICAgICAgICAgIGlmICghY3VycmVudE93bmVyLm5hbWUuaXNFbXB0eSgpKQogICAgICAgICAgICAgICAgZmlyc3RQYXJhbSArPSAxOwogICAgICAgIH0KCiAgICAgICAgaWYgKHN5bS50eXBlICE9IGp2bVR5cGUpIHsKICAgICAgICAgICAgICAgIC8vIHJlYWRpbmcgdGhlIG1ldGhvZCBhdHRyaWJ1dGVzIGhhcyBjYXVzZWQgdGhlCiAgICAgICAgICAgICAgICAvLyBzeW1ib2wncyB0eXBlIHRvIGJlIGNoYW5nZWQuIChpLmUuIHRoZSBTaWduYXR1cmUKICAgICAgICAgICAgICAgIC8vIGF0dHJpYnV0ZS4pICBUaGlzIG1heSBoYXBwZW4gaWYgdGhlcmUgYXJlIGhpZGRlbgogICAgICAgICAgICAgICAgLy8gKHN5bnRoZXRpYykgcGFyYW1ldGVycyBpbiB0aGUgZGVzY3JpcHRvciwgYnV0IG5vdAogICAgICAgICAgICAgICAgLy8gaW4gdGhlIFNpZ25hdHVyZS4gIFRoZSBwb3NpdGlvbiBvZiB0aGVzZSBoaWRkZW4KICAgICAgICAgICAgICAgIC8vIHBhcmFtZXRlcnMgaXMgdW5zcGVjaWZpZWQ7IGZvciBub3csIGFzc3VtZSB0aGV5IGFyZQogICAgICAgICAgICAgICAgLy8gYXQgdGhlIGJlZ2lubmluZywgYW5kIHNvIHNraXAgb3ZlciB0aGVtLiBUaGUKICAgICAgICAgICAgICAgIC8vIHByaW1hcnkgY2FzZSBmb3IgdGhpcyBpcyB0d28gaGlkZGVuIHBhcmFtZXRlcnMKICAgICAgICAgICAgICAgIC8vIHBhc3NlZCBpbnRvIEVudW0gY29uc3RydWN0b3JzLgogICAgICAgICAgICBpbnQgc2tpcCA9IENvZGUud2lkdGgoanZtVHlwZS5nZXRQYXJhbWV0ZXJUeXBlcygpKQogICAgICAgICAgICAgICAgICAgIC0gQ29kZS53aWR0aChzeW0udHlwZS5nZXRQYXJhbWV0ZXJUeXBlcygpKTsKICAgICAgICAgICAgZmlyc3RQYXJhbSArPSBza2lwOwogICAgICAgIH0KICAgICAgICB9CiAgICAgICAgTGlzdDxOYW1lPiBwYXJhbU5hbWVzID0gTGlzdC5uaWwoKTsKICAgICAgICBpbnQgaW5kZXggPSBmaXJzdFBhcmFtOwogICAgICAgIGZvciAoVHlwZSB0OiBzeW0udHlwZS5nZXRQYXJhbWV0ZXJUeXBlcygpKSB7CiAgICAgICAgICAgIGludCBuYW1lSWR4ID0gKGluZGV4IDwgcGFyYW1ldGVyTmFtZUluZGljZXMubGVuZ3RoCiAgICAgICAgICAgICAgICAgICAgPyBwYXJhbWV0ZXJOYW1lSW5kaWNlc1tpbmRleF0gOiAwKTsKICAgICAgICAgICAgTmFtZSBuYW1lID0gbmFtZUlkeCA9PSAwID8gbmFtZXMuZW1wdHkgOiByZWFkTmFtZShuYW1lSWR4KTsKICAgICAgICAgICAgcGFyYW1OYW1lcyA9IHBhcmFtTmFtZXMucHJlcGVuZChuYW1lKTsKICAgICAgICAgICAgaW5kZXggKz0gc2F3TWV0aG9kUGFyYW1ldGVycyA/IDEgOiBDb2RlLndpZHRoKHQpOwogICAgICAgIH0KICAgICAgICBzeW0uc2F2ZWRQYXJhbWV0ZXJOYW1lcyA9IHBhcmFtTmFtZXMucmV2ZXJzZSgpOwogICAgfQoKICAgIC8qKgogICAgICogc2tpcCBuIGJ5dGVzCiAgICAgKi8KICAgIHZvaWQgc2tpcEJ5dGVzKGludCBuKSB7CiAgICAgICAgYnAgPSBicCArIG47CiAgICB9CgogICAgLyoqIFNraXAgYSBmaWVsZCBvciBtZXRob2QKICAgICAqLwogICAgdm9pZCBza2lwTWVtYmVyKCkgewogICAgICAgIGJwID0gYnAgKyA2OwogICAgICAgIGNoYXIgYWMgPSBuZXh0Q2hhcigpOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYWM7IGkrKykgewogICAgICAgICAgICBicCA9IGJwICsgMjsKICAgICAgICAgICAgaW50IGF0dHJMZW4gPSBuZXh0SW50KCk7CiAgICAgICAgICAgIGJwID0gYnAgKyBhdHRyTGVuOwogICAgICAgIH0KICAgIH0KCiAgICB2b2lkIHNraXBJbm5lckNsYXNzZXMoKSB7CiAgICAgICAgaW50IG4gPSBuZXh0Q2hhcigpOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKSB7CiAgICAgICAgICAgIG5leHRDaGFyKCk7CiAgICAgICAgICAgIG5leHRDaGFyKCk7CiAgICAgICAgICAgIG5leHRDaGFyKCk7CiAgICAgICAgICAgIG5leHRDaGFyKCk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKiBFbnRlciB0eXBlIHZhcmlhYmxlcyBvZiB0aGlzIGNsYXNzdHlwZSBhbmQgYWxsIGVuY2xvc2luZyBvbmVzIGluCiAgICAgKiAgYHR5cGV2YXJzJy4KICAgICAqLwogICAgcHJvdGVjdGVkIHZvaWQgZW50ZXJUeXBldmFycyhTeW1ib2wgc3ltLCBUeXBlIHQpIHsKICAgICAgICBpZiAodC5nZXRFbmNsb3NpbmdUeXBlKCkgIT0gbnVsbCkgewogICAgICAgICAgICBpZiAoIXQuZ2V0RW5jbG9zaW5nVHlwZSgpLmhhc1RhZyhUeXBlVGFnLk5PTkUpKSB7CiAgICAgICAgICAgICAgICBlbnRlclR5cGV2YXJzKHN5bS5vd25lciwgdC5nZXRFbmNsb3NpbmdUeXBlKCkpOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmIChzeW0ua2luZCA9PSBNVEggJiYgIXN5bS5pc1N0YXRpYygpKSB7CiAgICAgICAgICAgIGVudGVyVHlwZXZhcnMoc3ltLm93bmVyLCBzeW0ub3duZXIudHlwZSk7CiAgICAgICAgfQogICAgICAgIGZvciAoTGlzdDxUeXBlPiB4cyA9IHQuZ2V0VHlwZUFyZ3VtZW50cygpOyB4cy5ub25FbXB0eSgpOyB4cyA9IHhzLnRhaWwpIHsKICAgICAgICAgICAgdHlwZXZhcnMuZW50ZXIoeHMuaGVhZC50c3ltKTsKICAgICAgICB9CiAgICB9CgogICAgcHJvdGVjdGVkIENsYXNzU3ltYm9sIGVudGVyQ2xhc3MoTmFtZSBuYW1lKSB7CiAgICAgICAgcmV0dXJuIHN5bXMuZW50ZXJDbGFzcyhjdXJyZW50TW9kdWxlLCBuYW1lKTsKICAgIH0KCiAgICBwcm90ZWN0ZWQgQ2xhc3NTeW1ib2wgZW50ZXJDbGFzcyhOYW1lIG5hbWUsIFR5cGVTeW1ib2wgb3duZXIpIHsKICAgICAgICByZXR1cm4gc3ltcy5lbnRlckNsYXNzKGN1cnJlbnRNb2R1bGUsIG5hbWUsIG93bmVyKTsKICAgIH0KCiAgICAvKiogUmVhZCBjb250ZW50cyBvZiBhIGdpdmVuIGNsYXNzIHN5bWJvbCBgYycuIEJvdGggZXh0ZXJuYWwgYW5kIGludGVybmFsCiAgICAgKiAgdmVyc2lvbnMgb2YgYW4gaW5uZXIgY2xhc3MgYXJlIHJlYWQuCiAgICAgKi8KICAgIHZvaWQgcmVhZENsYXNzKENsYXNzU3ltYm9sIGMpIHsKICAgICAgICBDbGFzc1R5cGUgY3QgPSAoQ2xhc3NUeXBlKWMudHlwZTsKCiAgICAgICAgLy8gYWxsb2NhdGUgc2NvcGUgZm9yIG1lbWJlcnMKICAgICAgICBjLm1lbWJlcnNfZmllbGQgPSBXcml0ZWFibGVTY29wZS5jcmVhdGUoYyk7CgogICAgICAgIC8vIHByZXBhcmUgdHlwZSB2YXJpYWJsZSB0YWJsZQogICAgICAgIHR5cGV2YXJzID0gdHlwZXZhcnMuZHVwKGN1cnJlbnRPd25lcik7CiAgICAgICAgaWYgKGN0LmdldEVuY2xvc2luZ1R5cGUoKS5oYXNUYWcoQ0xBU1MpKQogICAgICAgICAgICBlbnRlclR5cGV2YXJzKGMub3duZXIsIGN0LmdldEVuY2xvc2luZ1R5cGUoKSk7CgogICAgICAgIC8vIHJlYWQgZmxhZ3MsIG9yIHNraXAgaWYgdGhpcyBpcyBhbiBpbm5lciBjbGFzcwogICAgICAgIGxvbmcgZiA9IG5leHRDaGFyKCk7CiAgICAgICAgbG9uZyBmbGFncyA9IGFkanVzdENsYXNzRmxhZ3MoZik7CiAgICAgICAgaWYgKChmbGFncyAmIE1PRFVMRSkgPT0gMCkgewogICAgICAgICAgICBpZiAoYy5vd25lci5raW5kID09IFBDSykgYy5mbGFnc19maWVsZCA9IGZsYWdzOwogICAgICAgICAgICAvLyByZWFkIG93biBjbGFzcyBuYW1lIGFuZCBjaGVjayB0aGF0IGl0IG1hdGNoZXMKICAgICAgICAgICAgY3VycmVudE1vZHVsZSA9IGMucGFja2dlKCkubW9kbGU7CiAgICAgICAgICAgIENsYXNzU3ltYm9sIHNlbGYgPSByZWFkQ2xhc3NTeW1ib2wobmV4dENoYXIoKSk7CiAgICAgICAgICAgIGlmIChjICE9IHNlbGYpIHsKICAgICAgICAgICAgICAgIHRocm93IGJhZENsYXNzRmlsZSgiY2xhc3MuZmlsZS53cm9uZy5jbGFzcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5mbGF0bmFtZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBpZiAobWFqb3JWZXJzaW9uIDwgVmVyc2lvbi5WNTMubWFqb3IpIHsKICAgICAgICAgICAgICAgIHRocm93IGJhZENsYXNzRmlsZSgiYW5hY2hyb25pc3RpYy5tb2R1bGUuaW5mbyIsCiAgICAgICAgICAgICAgICAgICAgICAgIEludGVnZXIudG9TdHJpbmcobWFqb3JWZXJzaW9uKSwKICAgICAgICAgICAgICAgICAgICAgICAgSW50ZWdlci50b1N0cmluZyhtaW5vclZlcnNpb24pKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBjLmZsYWdzX2ZpZWxkID0gZmxhZ3M7CiAgICAgICAgICAgIGN1cnJlbnRNb2R1bGUgPSAoTW9kdWxlU3ltYm9sKSBjLm93bmVyOwogICAgICAgICAgICBpbnQgdGhpc19jbGFzcyA9IG5leHRDaGFyKCk7CiAgICAgICAgICAgIC8vIHRlbXAsIG5vIGNoZWNrIG9uIHRoaXNfY2xhc3MKICAgICAgICB9CgogICAgICAgIC8vIGNsYXNzIGF0dHJpYnV0ZXMgbXVzdCBiZSByZWFkIGJlZm9yZSBjbGFzcwogICAgICAgIC8vIHNraXAgYWhlYWQgdG8gcmVhZCBjbGFzcyBhdHRyaWJ1dGVzCiAgICAgICAgaW50IHN0YXJ0YnAgPSBicDsKICAgICAgICBuZXh0Q2hhcigpOwogICAgICAgIGNoYXIgaW50ZXJmYWNlQ291bnQgPSBuZXh0Q2hhcigpOwogICAgICAgIGJwICs9IGludGVyZmFjZUNvdW50ICogMjsKICAgICAgICBjaGFyIGZpZWxkQ291bnQgPSBuZXh0Q2hhcigpOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRDb3VudDsgaSsrKSBza2lwTWVtYmVyKCk7CiAgICAgICAgY2hhciBtZXRob2RDb3VudCA9IG5leHRDaGFyKCk7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtZXRob2RDb3VudDsgaSsrKSBza2lwTWVtYmVyKCk7CiAgICAgICAgcmVhZENsYXNzQXR0cnMoYyk7CgogICAgICAgIGlmIChyZWFkQWxsT2ZDbGFzc0ZpbGUpIHsKICAgICAgICAgICAgZm9yIChpbnQgaSA9IDE7IGkgPCBwb29sT2JqLmxlbmd0aDsgaSsrKSByZWFkUG9vbChpKTsKICAgICAgICAgICAgYy5wb29sID0gbmV3IFBvb2wocG9vbE9iai5sZW5ndGgsIHBvb2xPYmosIHR5cGVzKTsKICAgICAgICB9CgogICAgICAgIC8vIHJlc2V0IGFuZCByZWFkIHJlc3Qgb2YgY2xhc3NpbmZvCiAgICAgICAgYnAgPSBzdGFydGJwOwogICAgICAgIGludCBuID0gbmV4dENoYXIoKTsKICAgICAgICBpZiAoKGZsYWdzICYgTU9EVUxFKSAhPSAwICYmIG4gPiAwKSB7CiAgICAgICAgICAgIHRocm93IGJhZENsYXNzRmlsZSgibW9kdWxlLmluZm8uaW52YWxpZC5zdXBlci5jbGFzcyIpOwogICAgICAgIH0KICAgICAgICBpZiAoY3Quc3VwZXJ0eXBlX2ZpZWxkID09IG51bGwpCiAgICAgICAgICAgIGN0LnN1cGVydHlwZV9maWVsZCA9IChuID09IDApCiAgICAgICAgICAgICAgICA/IFR5cGUubm9UeXBlCiAgICAgICAgICAgICAgICA6IHJlYWRDbGFzc1N5bWJvbChuKS5lcmFzdXJlKHR5cGVzKTsKICAgICAgICBuID0gbmV4dENoYXIoKTsKICAgICAgICBMaXN0PFR5cGU+IGlzID0gTGlzdC5uaWwoKTsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykgewogICAgICAgICAgICBUeXBlIF9pbnRlciA9IHJlYWRDbGFzc1N5bWJvbChuZXh0Q2hhcigpKS5lcmFzdXJlKHR5cGVzKTsKICAgICAgICAgICAgaXMgPSBpcy5wcmVwZW5kKF9pbnRlcik7CiAgICAgICAgfQogICAgICAgIGlmIChjdC5pbnRlcmZhY2VzX2ZpZWxkID09IG51bGwpCiAgICAgICAgICAgIGN0LmludGVyZmFjZXNfZmllbGQgPSBpcy5yZXZlcnNlKCk7CgogICAgICAgIEFzc2VydC5jaGVjayhmaWVsZENvdW50ID09IG5leHRDaGFyKCkpOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGRDb3VudDsgaSsrKSBlbnRlck1lbWJlcihjLCByZWFkRmllbGQoKSk7CiAgICAgICAgQXNzZXJ0LmNoZWNrKG1ldGhvZENvdW50ID09IG5leHRDaGFyKCkpOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbWV0aG9kQ291bnQ7IGkrKykgZW50ZXJNZW1iZXIoYywgcmVhZE1ldGhvZCgpKTsKCiAgICAgICAgdHlwZXZhcnMgPSB0eXBldmFycy5sZWF2ZSgpOwogICAgfQoKICAgIC8qKiBSZWFkIGlubmVyIGNsYXNzIGluZm8uIEZvciBlYWNoIGlubmVyL291dGVyIHBhaXIgYWxsb2NhdGUgYQogICAgICogIG1lbWJlciBjbGFzcy4KICAgICAqLwogICAgdm9pZCByZWFkSW5uZXJDbGFzc2VzKENsYXNzU3ltYm9sIGMpIHsKICAgICAgICBpbnQgbiA9IG5leHRDaGFyKCk7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspIHsKICAgICAgICAgICAgbmV4dENoYXIoKTsgLy8gc2tpcCBpbm5lciBjbGFzcyBzeW1ib2wKICAgICAgICAgICAgQ2xhc3NTeW1ib2wgb3V0ZXIgPSByZWFkQ2xhc3NTeW1ib2wobmV4dENoYXIoKSk7CiAgICAgICAgICAgIE5hbWUgbmFtZSA9IHJlYWROYW1lKG5leHRDaGFyKCkpOwogICAgICAgICAgICBpZiAobmFtZSA9PSBudWxsKSBuYW1lID0gbmFtZXMuZW1wdHk7CiAgICAgICAgICAgIGxvbmcgZmxhZ3MgPSBhZGp1c3RDbGFzc0ZsYWdzKG5leHRDaGFyKCkpOwogICAgICAgICAgICBpZiAob3V0ZXIgIT0gbnVsbCkgeyAvLyB3ZSBoYXZlIGEgbWVtYmVyIGNsYXNzCiAgICAgICAgICAgICAgICBpZiAobmFtZSA9PSBuYW1lcy5lbXB0eSkKICAgICAgICAgICAgICAgICAgICBuYW1lID0gbmFtZXMub25lOwogICAgICAgICAgICAgICAgQ2xhc3NTeW1ib2wgbWVtYmVyID0gZW50ZXJDbGFzcyhuYW1lLCBvdXRlcik7CiAgICAgICAgICAgICAgICBpZiAoKGZsYWdzICYgU1RBVElDKSA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgKChDbGFzc1R5cGUpbWVtYmVyLnR5cGUpLnNldEVuY2xvc2luZ1R5cGUob3V0ZXIudHlwZSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKG1lbWJlci5lcmFzdXJlX2ZpZWxkICE9IG51bGwpCiAgICAgICAgICAgICAgICAgICAgICAgICgoQ2xhc3NUeXBlKW1lbWJlci5lcmFzdXJlX2ZpZWxkKS5zZXRFbmNsb3NpbmdUeXBlKHR5cGVzLmVyYXN1cmUob3V0ZXIudHlwZSkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKGMgPT0gb3V0ZXIpIHsKICAgICAgICAgICAgICAgICAgICBtZW1iZXIuZmxhZ3NfZmllbGQgPSBmbGFnczsKICAgICAgICAgICAgICAgICAgICBlbnRlck1lbWJlcihjLCBtZW1iZXIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKiBSZWFkIGEgY2xhc3MgZGVmaW5pdGlvbiBmcm9tIHRoZSBieXRlcyBpbiBidWYuCiAgICAgKi8KICAgIHByaXZhdGUgdm9pZCByZWFkQ2xhc3NCdWZmZXIoQ2xhc3NTeW1ib2wgYykgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICBpbnQgbWFnaWMgPSBuZXh0SW50KCk7CiAgICAgICAgaWYgKG1hZ2ljICE9IEpBVkFfTUFHSUMpCiAgICAgICAgICAgIHRocm93IGJhZENsYXNzRmlsZSgiaWxsZWdhbC5zdGFydC5vZi5jbGFzcy5maWxlIik7CgogICAgICAgIG1pbm9yVmVyc2lvbiA9IG5leHRDaGFyKCk7CiAgICAgICAgbWFqb3JWZXJzaW9uID0gbmV4dENoYXIoKTsKICAgICAgICBpbnQgbWF4TWFqb3IgPSA1MzsgLy8gVmVyc2lvbi5NQVgoKS5tYWpvcjsgIC8vKioqKioqKiBURU1QT1JBUlkgKioqKioqKgogICAgICAgIGludCBtYXhNaW5vciA9IFZlcnNpb24uTUFYKCkubWlub3I7CiAgICAgICAgaWYgKG1ham9yVmVyc2lvbiA+IG1heE1ham9yIHx8CiAgICAgICAgICAgIG1ham9yVmVyc2lvbiAqIDEwMDAgKyBtaW5vclZlcnNpb24gPAogICAgICAgICAgICBWZXJzaW9uLk1JTigpLm1ham9yICogMTAwMCArIFZlcnNpb24uTUlOKCkubWlub3IpIHsKICAgICAgICAgICAgaWYgKG1ham9yVmVyc2lvbiA9PSAobWF4TWFqb3IgKyAxKSkKICAgICAgICAgICAgICAgIGxvZy53YXJuaW5nKCJiaWcubWFqb3IudmVyc2lvbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50Q2xhc3NGaWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFqb3JWZXJzaW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF4TWFqb3IpOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB0aHJvdyBiYWRDbGFzc0ZpbGUoIndyb25nLnZlcnNpb24iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEludGVnZXIudG9TdHJpbmcobWFqb3JWZXJzaW9uKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbnRlZ2VyLnRvU3RyaW5nKG1pbm9yVmVyc2lvbiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW50ZWdlci50b1N0cmluZyhtYXhNYWpvciksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW50ZWdlci50b1N0cmluZyhtYXhNaW5vcikpOwogICAgICAgIH0KCiAgICAgICAgaW5kZXhQb29sKCk7CiAgICAgICAgaWYgKHNpZ25hdHVyZUJ1ZmZlci5sZW5ndGggPCBicCkgewogICAgICAgICAgICBpbnQgbnMgPSBJbnRlZ2VyLmhpZ2hlc3RPbmVCaXQoYnApIDw8IDE7CiAgICAgICAgICAgIHNpZ25hdHVyZUJ1ZmZlciA9IG5ldyBieXRlW25zXTsKICAgICAgICB9CiAgICAgICAgcmVhZENsYXNzKGMpOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHJlYWRDbGFzc0ZpbGUoQ2xhc3NTeW1ib2wgYykgewogICAgICAgIGN1cnJlbnRPd25lciA9IGM7CiAgICAgICAgY3VycmVudENsYXNzRmlsZSA9IGMuY2xhc3NmaWxlOwogICAgICAgIHdhcm5lZEF0dHJzLmNsZWFyKCk7CiAgICAgICAgZmlsbGluZyA9IHRydWU7CiAgICAgICAgdGFyZ2V0ID0gbnVsbDsKICAgICAgICByZXBlYXRhYmxlID0gbnVsbDsKICAgICAgICB0cnkgewogICAgICAgICAgICBicCA9IDA7CiAgICAgICAgICAgIGJ1ZiA9IHJlYWRJbnB1dFN0cmVhbShidWYsIGMuY2xhc3NmaWxlLm9wZW5JbnB1dFN0cmVhbSgpKTsKICAgICAgICAgICAgcmVhZENsYXNzQnVmZmVyKGMpOwogICAgICAgICAgICBpZiAoIW1pc3NpbmdUeXBlVmFyaWFibGVzLmlzRW1wdHkoKSAmJiAhZm91bmRUeXBlVmFyaWFibGVzLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgICAgTGlzdDxUeXBlPiBtaXNzaW5nID0gbWlzc2luZ1R5cGVWYXJpYWJsZXM7CiAgICAgICAgICAgICAgICBMaXN0PFR5cGU+IGZvdW5kID0gZm91bmRUeXBlVmFyaWFibGVzOwogICAgICAgICAgICAgICAgbWlzc2luZ1R5cGVWYXJpYWJsZXMgPSBMaXN0Lm5pbCgpOwogICAgICAgICAgICAgICAgZm91bmRUeXBlVmFyaWFibGVzID0gTGlzdC5uaWwoKTsKICAgICAgICAgICAgICAgIGludGVyaW1Vc2VzID0gTGlzdC5uaWwoKTsKICAgICAgICAgICAgICAgIGludGVyaW1Qcm92aWRlcyA9IExpc3QubmlsKCk7CiAgICAgICAgICAgICAgICBmaWxsaW5nID0gZmFsc2U7CiAgICAgICAgICAgICAgICBDbGFzc1R5cGUgY3QgPSAoQ2xhc3NUeXBlKWN1cnJlbnRPd25lci50eXBlOwogICAgICAgICAgICAgICAgY3Quc3VwZXJ0eXBlX2ZpZWxkID0KICAgICAgICAgICAgICAgICAgICB0eXBlcy5zdWJzdChjdC5zdXBlcnR5cGVfZmllbGQsIG1pc3NpbmcsIGZvdW5kKTsKICAgICAgICAgICAgICAgIGN0LmludGVyZmFjZXNfZmllbGQgPQogICAgICAgICAgICAgICAgICAgIHR5cGVzLnN1YnN0KGN0LmludGVyZmFjZXNfZmllbGQsIG1pc3NpbmcsIGZvdW5kKTsKICAgICAgICAgICAgICAgIGN0LnR5cGFyYW1zX2ZpZWxkID0KICAgICAgICAgICAgICAgICAgICB0eXBlcy5zdWJzdEJvdW5kcyhjdC50eXBhcmFtc19maWVsZCwgbWlzc2luZywgZm91bmQpOwogICAgICAgICAgICAgICAgZm9yIChMaXN0PFR5cGU+IHR5cGVzID0gY3QudHlwYXJhbXNfZmllbGQ7IHR5cGVzLm5vbkVtcHR5KCk7IHR5cGVzID0gdHlwZXMudGFpbCkgewogICAgICAgICAgICAgICAgICAgIHR5cGVzLmhlYWQudHN5bS50eXBlID0gdHlwZXMuaGVhZDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIGlmIChtaXNzaW5nVHlwZVZhcmlhYmxlcy5pc0VtcHR5KCkgIT0KICAgICAgICAgICAgICAgICAgICAgICBmb3VuZFR5cGVWYXJpYWJsZXMuaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgICBOYW1lIG5hbWUgPSBtaXNzaW5nVHlwZVZhcmlhYmxlcy5oZWFkLnRzeW0ubmFtZTsKICAgICAgICAgICAgICAgIHRocm93IGJhZENsYXNzRmlsZSgidW5kZWNsLnR5cGUudmFyIiwgbmFtZSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgoYy5mbGFnc19maWVsZCAmIEZsYWdzLkFOTk9UQVRJT04pICE9IDApIHsKICAgICAgICAgICAgICAgIGMuc2V0QW5ub3RhdGlvblR5cGVNZXRhZGF0YShuZXcgQW5ub3RhdGlvblR5cGVNZXRhZGF0YShjLCBuZXcgQ29tcGxldGVyRGVwcm94eShjLCB0YXJnZXQsIHJlcGVhdGFibGUpKSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBjLnNldEFubm90YXRpb25UeXBlTWV0YWRhdGEoQW5ub3RhdGlvblR5cGVNZXRhZGF0YS5ub3RBbkFubm90YXRpb25UeXBlKCkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoYyA9PSBjdXJyZW50TW9kdWxlLm1vZHVsZV9pbmZvKSB7CiAgICAgICAgICAgICAgICBpZiAoaW50ZXJpbVVzZXMubm9uRW1wdHkoKSB8fCBpbnRlcmltUHJvdmlkZXMubm9uRW1wdHkoKSkgewogICAgICAgICAgICAgICAgICAgIEFzc2VydC5jaGVjayhjdXJyZW50TW9kdWxlLmlzQ29tcGxldGVkKCkpOwogICAgICAgICAgICAgICAgICAgIGN1cnJlbnRNb2R1bGUudXNlc1Byb3ZpZGVzQ29tcGxldGVyID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBVc2VzUHJvdmlkZXNDb21wbGV0ZXIoY3VycmVudE1vZHVsZSwgaW50ZXJpbVVzZXMsIGludGVyaW1Qcm92aWRlcyk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGN1cnJlbnRNb2R1bGUudXNlcyA9IExpc3QubmlsKCk7CiAgICAgICAgICAgICAgICAgICAgY3VycmVudE1vZHVsZS5wcm92aWRlcyA9IExpc3QubmlsKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiB8IENsb3NlZEZpbGVTeXN0ZW1FeGNlcHRpb24gZXgpIHsKICAgICAgICAgICAgdGhyb3cgYmFkQ2xhc3NGaWxlKCJ1bmFibGUudG8uYWNjZXNzLmZpbGUiLCBleC50b1N0cmluZygpKTsKICAgICAgICB9IGNhdGNoIChBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gZXgpIHsKICAgICAgICAgICAgdGhyb3cgYmFkQ2xhc3NGaWxlKCJiYWQuY2xhc3MuZmlsZSIsIGMuZmxhdG5hbWUpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgIGludGVyaW1Vc2VzID0gTGlzdC5uaWwoKTsKICAgICAgICAgICAgaW50ZXJpbVByb3ZpZGVzID0gTGlzdC5uaWwoKTsKICAgICAgICAgICAgbWlzc2luZ1R5cGVWYXJpYWJsZXMgPSBMaXN0Lm5pbCgpOwogICAgICAgICAgICBmb3VuZFR5cGVWYXJpYWJsZXMgPSBMaXN0Lm5pbCgpOwogICAgICAgICAgICBmaWxsaW5nID0gZmFsc2U7CiAgICAgICAgfQogICAgfQogICAgLy8gd2hlcmUKICAgICAgICBwcml2YXRlIHN0YXRpYyBieXRlW10gcmVhZElucHV0U3RyZWFtKGJ5dGVbXSBidWYsIElucHV0U3RyZWFtIHMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBidWYgPSBlbnN1cmVDYXBhY2l0eShidWYsIHMuYXZhaWxhYmxlKCkpOwogICAgICAgICAgICAgICAgaW50IHIgPSBzLnJlYWQoYnVmKTsKICAgICAgICAgICAgICAgIGludCBicCA9IDA7CiAgICAgICAgICAgICAgICB3aGlsZSAociAhPSAtMSkgewogICAgICAgICAgICAgICAgICAgIGJwICs9IHI7CiAgICAgICAgICAgICAgICAgICAgYnVmID0gZW5zdXJlQ2FwYWNpdHkoYnVmLCBicCk7CiAgICAgICAgICAgICAgICAgICAgciA9IHMucmVhZChidWYsIGJwLCBidWYubGVuZ3RoIC0gYnApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIGJ1ZjsKICAgICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgcy5jbG9zZSgpOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICAgICAgICAgIC8qIElnbm9yZSBhbnkgZXJyb3JzLCBhcyB0aGlzIHN0cmVhbSBtYXkgaGF2ZSBhbHJlYWR5CiAgICAgICAgICAgICAgICAgICAgICogdGhyb3duIGEgcmVsYXRlZCBleGNlcHRpb24gd2hpY2ggaXMgdGhlIG9uZSB0aGF0CiAgICAgICAgICAgICAgICAgICAgICogc2hvdWxkIGJlIHJlcG9ydGVkLgogICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8qCiAgICAgICAgICogZW5zdXJlQ2FwYWNpdHkgd2lsbCBpbmNyZWFzZSB0aGUgYnVmZmVyIGFzIG5lZWRlZCwgdGFraW5nIG5vdGUgdGhhdAogICAgICAgICAqIHRoZSBuZXcgYnVmZmVyIHdpbGwgYWx3YXlzIGJlIGdyZWF0ZXIgdGhhbiB0aGUgbmVlZGVkIGFuZCBuZXZlcgogICAgICAgICAqIGV4YWN0bHkgZXF1YWwgdG8gdGhlIG5lZWRlZCBzaXplIG9yIGJwLiBJZiBlcXVhbCB0aGVuIHRoZSByZWFkIChhYm92ZSkKICAgICAgICAgKiB3aWxsIGluZmluaXRlbHkgbG9vcCBhcyBidWYubGVuZ3RoIC0gYnAgPT0gMC4KICAgICAgICAgKi8KICAgICAgICBwcml2YXRlIHN0YXRpYyBieXRlW10gZW5zdXJlQ2FwYWNpdHkoYnl0ZVtdIGJ1ZiwgaW50IG5lZWRlZCkgewogICAgICAgICAgICBpZiAoYnVmLmxlbmd0aCA8PSBuZWVkZWQpIHsKICAgICAgICAgICAgICAgIGJ5dGVbXSBvbGQgPSBidWY7CiAgICAgICAgICAgICAgICBidWYgPSBuZXcgYnl0ZVtJbnRlZ2VyLmhpZ2hlc3RPbmVCaXQobmVlZGVkKSA8PCAxXTsKICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkob2xkLCAwLCBidWYsIDAsIG9sZC5sZW5ndGgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBidWY7CiAgICAgICAgfQoKICAgIC8qKiBXZSBjYW4gb25seSByZWFkIGEgc2luZ2xlIGNsYXNzIGZpbGUgYXQgYSB0aW1lOyB0aGlzCiAgICAgKiAgZmxhZyBrZWVwcyB0cmFjayBvZiB3aGVuIHdlIGFyZSBjdXJyZW50bHkgcmVhZGluZyBhIGNsYXNzCiAgICAgKiAgZmlsZS4KICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gZmlsbGluZyA9IGZhbHNlOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBBZGp1c3RpbmcgZmxhZ3MKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKICAgIGxvbmcgYWRqdXN0RmllbGRGbGFncyhsb25nIGZsYWdzKSB7CiAgICAgICAgcmV0dXJuIGZsYWdzOwogICAgfQoKICAgIGxvbmcgYWRqdXN0TWV0aG9kRmxhZ3MobG9uZyBmbGFncykgewogICAgICAgIGlmICgoZmxhZ3MgJiBBQ0NfQlJJREdFKSAhPSAwKSB7CiAgICAgICAgICAgIGZsYWdzICY9IH5BQ0NfQlJJREdFOwogICAgICAgICAgICBmbGFncyB8PSBCUklER0U7CiAgICAgICAgfQogICAgICAgIGlmICgoZmxhZ3MgJiBBQ0NfVkFSQVJHUykgIT0gMCkgewogICAgICAgICAgICBmbGFncyAmPSB+QUNDX1ZBUkFSR1M7CiAgICAgICAgICAgIGZsYWdzIHw9IFZBUkFSR1M7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmbGFnczsKICAgIH0KCiAgICBsb25nIGFkanVzdENsYXNzRmxhZ3MobG9uZyBmbGFncykgewogICAgICAgIGlmICgoZmxhZ3MgJiBBQ0NfTU9EVUxFKSAhPSAwKSB7CiAgICAgICAgICAgIGZsYWdzICY9IH5BQ0NfTU9EVUxFOwogICAgICAgICAgICBmbGFncyB8PSBNT0RVTEU7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmbGFncyAmIH5BQ0NfU1VQRVI7IC8vIFNVUEVSIGFuZCBTWU5DSFJPTklaRUQgYml0cyBvdmVybG9hZGVkCiAgICB9CgogICAgLyoqCiAgICAgKiBBIHN1YmNsYXNzIG9mIEphdmFGaWxlT2JqZWN0IGZvciB0aGUgc291cmNlZmlsZSBhdHRyaWJ1dGUgZm91bmQgaW4gYSBjbGFzc2ZpbGUuCiAgICAgKiBUaGUgYXR0cmlidXRlIGlzIG9ubHkgdGhlIGxhc3QgY29tcG9uZW50IG9mIHRoZSBvcmlnaW5hbCBmaWxlbmFtZSwgc28gaXMgdW5saWtlbHkKICAgICAqIHRvIGJlIHZhbGlkIGFzIGlzLCBzbyBvcGVyYXRpb25zIG90aGVyIHRoYW4gdGhvc2UgdG8gYWNjZXNzIHRoZSBuYW1lIHRocm93CiAgICAgKiBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbgogICAgICovCiAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBTb3VyY2VGaWxlT2JqZWN0IGltcGxlbWVudHMgSmF2YUZpbGVPYmplY3QgewoKICAgICAgICAvKiogVGhlIGZpbGUncyBuYW1lLgogICAgICAgICAqLwogICAgICAgIHByaXZhdGUgZmluYWwgTmFtZSBuYW1lOwogICAgICAgIHByaXZhdGUgZmluYWwgTmFtZSBmbGF0bmFtZTsKCiAgICAgICAgcHVibGljIFNvdXJjZUZpbGVPYmplY3QoTmFtZSBuYW1lLCBOYW1lIGZsYXRuYW1lKSB7CiAgICAgICAgICAgIHRoaXMubmFtZSA9IG5hbWU7CiAgICAgICAgICAgIHRoaXMuZmxhdG5hbWUgPSBmbGF0bmFtZTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgICAgICBwdWJsaWMgVVJJIHRvVXJpKCkgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBVUkkobnVsbCwgbmFtZS50b1N0cmluZygpLCBudWxsKTsKICAgICAgICAgICAgfSBjYXRjaCAoVVJJU3ludGF4RXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBQYXRoRmlsZU9iamVjdC5DYW5ub3RDcmVhdGVVcmlFcnJvcihuYW1lLnRvU3RyaW5nKCksIGUpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICAgICAgcHVibGljIFN0cmluZyBnZXROYW1lKCkgewogICAgICAgICAgICByZXR1cm4gbmFtZS50b1N0cmluZygpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSKQogICAgICAgIHB1YmxpYyBKYXZhRmlsZU9iamVjdC5LaW5kIGdldEtpbmQoKSB7CiAgICAgICAgICAgIHJldHVybiBCYXNlRmlsZU1hbmFnZXIuZ2V0S2luZChnZXROYW1lKCkpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSKQogICAgICAgIHB1YmxpYyBJbnB1dFN0cmVhbSBvcGVuSW5wdXRTdHJlYW0oKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSKQogICAgICAgIHB1YmxpYyBPdXRwdXRTdHJlYW0gb3Blbk91dHB1dFN0cmVhbSgpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICAgICAgcHVibGljIENoYXJCdWZmZXIgZ2V0Q2hhckNvbnRlbnQoYm9vbGVhbiBpZ25vcmVFbmNvZGluZ0Vycm9ycykgewogICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgICAgICBwdWJsaWMgUmVhZGVyIG9wZW5SZWFkZXIoYm9vbGVhbiBpZ25vcmVFbmNvZGluZ0Vycm9ycykgewogICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgICAgICBwdWJsaWMgV3JpdGVyIG9wZW5Xcml0ZXIoKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSKQogICAgICAgIHB1YmxpYyBsb25nIGdldExhc3RNb2RpZmllZCgpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICAgICAgcHVibGljIGJvb2xlYW4gZGVsZXRlKCkgewogICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc05hbWVDb21wYXRpYmxlKFN0cmluZyBzaW1wbGVOYW1lLCBKYXZhRmlsZU9iamVjdC5LaW5kIGtpbmQpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7IC8vIGZhaWwtc2FmZSBtb2RlCiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVIpCiAgICAgICAgcHVibGljIE5lc3RpbmdLaW5kIGdldE5lc3RpbmdLaW5kKCkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUikKICAgICAgICBwdWJsaWMgTW9kaWZpZXIgZ2V0QWNjZXNzTGV2ZWwoKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogQ2hlY2sgaWYgdHdvIGZpbGUgb2JqZWN0cyBhcmUgZXF1YWwuCiAgICAgICAgICogU291cmNlRmlsZU9iamVjdHMgYXJlIGp1c3QgcGxhY2Vob2xkZXIgb2JqZWN0cyBmb3IgdGhlIHZhbHVlIG9mIGEKICAgICAgICAgKiBTb3VyY2VGaWxlIGF0dHJpYnV0ZSwgYW5kIGRvIG5vdCBkaXJlY3RseSByZXByZXNlbnQgc3BlY2lmaWMgZmlsZXMuCiAgICAgICAgICogVHdvIFNvdXJjZUZpbGVPYmplY3RzIGFyZSBlcXVhbCBpZiB0aGVpciBuYW1lcyBhcmUgZXF1YWwuCiAgICAgICAgICovCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvdGhlcikgewogICAgICAgICAgICBpZiAodGhpcyA9PSBvdGhlcikKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwoKICAgICAgICAgICAgaWYgKCEob3RoZXIgaW5zdGFuY2VvZiBTb3VyY2VGaWxlT2JqZWN0KSkKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKCiAgICAgICAgICAgIFNvdXJjZUZpbGVPYmplY3QgbyA9IChTb3VyY2VGaWxlT2JqZWN0KSBvdGhlcjsKICAgICAgICAgICAgcmV0dXJuIG5hbWUuZXF1YWxzKG8ubmFtZSk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICAgICAgICByZXR1cm4gbmFtZS5oYXNoQ29kZSgpOwogICAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIGNsYXNzIENvbXBsZXRlckRlcHJveHkgaW1wbGVtZW50cyBBbm5vdGF0aW9uVHlwZUNvbXBsZXRlciB7CiAgICAgICAgQ2xhc3NTeW1ib2wgcHJveHlPbjsKICAgICAgICBDb21wb3VuZEFubm90YXRpb25Qcm94eSB0YXJnZXQ7CiAgICAgICAgQ29tcG91bmRBbm5vdGF0aW9uUHJveHkgcmVwZWF0YWJsZTsKCiAgICAgICAgcHVibGljIENvbXBsZXRlckRlcHJveHkoQ2xhc3NTeW1ib2wgYywgQ29tcG91bmRBbm5vdGF0aW9uUHJveHkgdGFyZ2V0LAogICAgICAgICAgICAgICAgQ29tcG91bmRBbm5vdGF0aW9uUHJveHkgcmVwZWF0YWJsZSkKICAgICAgICB7CiAgICAgICAgICAgIHRoaXMucHJveHlPbiA9IGM7CiAgICAgICAgICAgIHRoaXMudGFyZ2V0ID0gdGFyZ2V0OwogICAgICAgICAgICB0aGlzLnJlcGVhdGFibGUgPSByZXBlYXRhYmxlOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgY29tcGxldGUoQ2xhc3NTeW1ib2wgc3ltKSB7CiAgICAgICAgICAgIEFzc2VydC5jaGVjayhwcm94eU9uID09IHN5bSk7CiAgICAgICAgICAgIEF0dHJpYnV0ZS5Db21wb3VuZCB0aGVUYXJnZXQgPSBudWxsLCB0aGVSZXBlYXRhYmxlID0gbnVsbDsKICAgICAgICAgICAgQW5ub3RhdGlvbkRlcHJveHkgZGVwcm94eTsKCiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBpZiAodGFyZ2V0ICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICBkZXByb3h5ID0gbmV3IEFubm90YXRpb25EZXByb3h5KHByb3h5T24pOwogICAgICAgICAgICAgICAgICAgIHRoZVRhcmdldCA9IGRlcHJveHkuZGVwcm94eUNvbXBvdW5kKHRhcmdldCk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKHJlcGVhdGFibGUgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIGRlcHJveHkgPSBuZXcgQW5ub3RhdGlvbkRlcHJveHkocHJveHlPbik7CiAgICAgICAgICAgICAgICAgICAgdGhlUmVwZWF0YWJsZSA9IGRlcHJveHkuZGVwcm94eUNvbXBvdW5kKHJlcGVhdGFibGUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IENvbXBsZXRpb25GYWlsdXJlKHN5bSwgZS5nZXRNZXNzYWdlKCkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBzeW0uZ2V0QW5ub3RhdGlvblR5cGVNZXRhZGF0YSgpLnNldFRhcmdldCh0aGVUYXJnZXQpOwogICAgICAgICAgICBzeW0uZ2V0QW5ub3RhdGlvblR5cGVNZXRhZGF0YSgpLnNldFJlcGVhdGFibGUodGhlUmVwZWF0YWJsZSk7CiAgICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgY2xhc3MgUHJveHlUeXBlIGV4dGVuZHMgVHlwZSB7CgogICAgICAgIHByaXZhdGUgZmluYWwgYnl0ZVtdIGNvbnRlbnQ7CgogICAgICAgIHB1YmxpYyBQcm94eVR5cGUoYnl0ZVtdIGNvbnRlbnQpIHsKICAgICAgICAgICAgc3VwZXIoc3ltcy5ub1N5bWJvbCwgVHlwZU1ldGFkYXRhLkVNUFRZKTsKICAgICAgICAgICAgdGhpcy5jb250ZW50ID0gY29udGVudDsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBUeXBlVGFnIGdldFRhZygpIHsKICAgICAgICAgICAgcmV0dXJuIFR5cGVUYWcuTk9ORTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBUeXBlIGNsb25lV2l0aE1ldGFkYXRhKFR5cGVNZXRhZGF0YSBtZXRhZGF0YSkgewogICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBUeXBlIHJlc29sdmUoKSB7CiAgICAgICAgICAgIHJldHVybiBzaWdUb1R5cGUoY29udGVudCwgMCwgY29udGVudC5sZW5ndGgpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkxBTkdVQUdFX01PREVMKQogICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CiAgICAgICAgICAgIHJldHVybiAiPFByb3h5VHlwZT4iOwogICAgICAgIH0KCiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgSW50ZXJpbVVzZXNEaXJlY3RpdmUgewogICAgICAgIHB1YmxpYyBmaW5hbCBOYW1lIHNlcnZpY2U7CgogICAgICAgIHB1YmxpYyBJbnRlcmltVXNlc0RpcmVjdGl2ZShOYW1lIHNlcnZpY2UpIHsKICAgICAgICAgICAgdGhpcy5zZXJ2aWNlID0gc2VydmljZTsKICAgICAgICB9CgogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEludGVyaW1Qcm92aWRlc0RpcmVjdGl2ZSB7CiAgICAgICAgcHVibGljIGZpbmFsIE5hbWUgc2VydmljZTsKICAgICAgICBwdWJsaWMgZmluYWwgTGlzdDxOYW1lPiBpbXBsczsKCiAgICAgICAgcHVibGljIEludGVyaW1Qcm92aWRlc0RpcmVjdGl2ZShOYW1lIHNlcnZpY2UsIExpc3Q8TmFtZT4gaW1wbHMpIHsKICAgICAgICAgICAgdGhpcy5zZXJ2aWNlID0gc2VydmljZTsKICAgICAgICAgICAgdGhpcy5pbXBscyA9IGltcGxzOwogICAgICAgIH0KCiAgICB9CgogICAgcHJpdmF0ZSBmaW5hbCBjbGFzcyBVc2VzUHJvdmlkZXNDb21wbGV0ZXIgaW1wbGVtZW50cyBDb21wbGV0ZXIgewogICAgICAgIHByaXZhdGUgZmluYWwgTW9kdWxlU3ltYm9sIGN1cnJlbnRNb2R1bGU7CiAgICAgICAgcHJpdmF0ZSBmaW5hbCBMaXN0PEludGVyaW1Vc2VzRGlyZWN0aXZlPiBpbnRlcmltVXNlc0NvcHk7CiAgICAgICAgcHJpdmF0ZSBmaW5hbCBMaXN0PEludGVyaW1Qcm92aWRlc0RpcmVjdGl2ZT4gaW50ZXJpbVByb3ZpZGVzQ29weTsKCiAgICAgICAgcHVibGljIFVzZXNQcm92aWRlc0NvbXBsZXRlcihNb2R1bGVTeW1ib2wgY3VycmVudE1vZHVsZSwgTGlzdDxJbnRlcmltVXNlc0RpcmVjdGl2ZT4gaW50ZXJpbVVzZXNDb3B5LCBMaXN0PEludGVyaW1Qcm92aWRlc0RpcmVjdGl2ZT4gaW50ZXJpbVByb3ZpZGVzQ29weSkgewogICAgICAgICAgICB0aGlzLmN1cnJlbnRNb2R1bGUgPSBjdXJyZW50TW9kdWxlOwogICAgICAgICAgICB0aGlzLmludGVyaW1Vc2VzQ29weSA9IGludGVyaW1Vc2VzQ29weTsKICAgICAgICAgICAgdGhpcy5pbnRlcmltUHJvdmlkZXNDb3B5ID0gaW50ZXJpbVByb3ZpZGVzQ29weTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIGNvbXBsZXRlKFN5bWJvbCBzeW0pIHRocm93cyBDb21wbGV0aW9uRmFpbHVyZSB7CiAgICAgICAgICAgIExpc3RCdWZmZXI8RGlyZWN0aXZlPiBkaXJlY3RpdmVzID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgICAgICBkaXJlY3RpdmVzLmFkZEFsbChjdXJyZW50TW9kdWxlLmRpcmVjdGl2ZXMpOwogICAgICAgICAgICBMaXN0QnVmZmVyPFVzZXNEaXJlY3RpdmU+IHVzZXMgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgIGZvciAoSW50ZXJpbVVzZXNEaXJlY3RpdmUgaW50ZXJpbSA6IGludGVyaW1Vc2VzQ29weSkgewogICAgICAgICAgICAgICAgVXNlc0RpcmVjdGl2ZSBkID0gbmV3IFVzZXNEaXJlY3RpdmUoc3ltcy5lbnRlckNsYXNzKGN1cnJlbnRNb2R1bGUsIGludGVyaW0uc2VydmljZSkpOwogICAgICAgICAgICAgICAgdXNlcy5hZGQoZCk7CiAgICAgICAgICAgICAgICBkaXJlY3RpdmVzLmFkZChkKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBjdXJyZW50TW9kdWxlLnVzZXMgPSB1c2VzLnRvTGlzdCgpOwogICAgICAgICAgICBMaXN0QnVmZmVyPFByb3ZpZGVzRGlyZWN0aXZlPiBwcm92aWRlcyA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICAgICAgZm9yIChJbnRlcmltUHJvdmlkZXNEaXJlY3RpdmUgaW50ZXJpbSA6IGludGVyaW1Qcm92aWRlc0NvcHkpIHsKICAgICAgICAgICAgICAgIExpc3RCdWZmZXI8Q2xhc3NTeW1ib2w+IGltcGxzID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgICAgICAgICAgZm9yIChOYW1lIGltcGwgOiBpbnRlcmltLmltcGxzKSB7CiAgICAgICAgICAgICAgICAgICAgaW1wbHMuYXBwZW5kKHN5bXMuZW50ZXJDbGFzcyhjdXJyZW50TW9kdWxlLCBpbXBsKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBQcm92aWRlc0RpcmVjdGl2ZSBkID0gbmV3IFByb3ZpZGVzRGlyZWN0aXZlKHN5bXMuZW50ZXJDbGFzcyhjdXJyZW50TW9kdWxlLCBpbnRlcmltLnNlcnZpY2UpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbXBscy50b0xpc3QoKSk7CiAgICAgICAgICAgICAgICBwcm92aWRlcy5hZGQoZCk7CiAgICAgICAgICAgICAgICBkaXJlY3RpdmVzLmFkZChkKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBjdXJyZW50TW9kdWxlLnByb3ZpZGVzID0gcHJvdmlkZXMudG9MaXN0KCk7CiAgICAgICAgICAgIGN1cnJlbnRNb2R1bGUuZGlyZWN0aXZlcyA9IGRpcmVjdGl2ZXMudG9MaXN0KCk7CiAgICAgICAgfQogICAgfQp9ClBLAwQKAAAIAAAGO6lKffzUktcKAADXCgAALgAAAGNvbS9zdW4vdG9vbHMvamF2YWMvanZtL1VuaW5pdGlhbGl6ZWRUeXBlLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDMsIDIwMTUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhYy5qdm07CgppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLio7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuTGlzdDsKCmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlR5cGVUYWcuVU5JTklUSUFMSVpFRF9PQkpFQ1Q7CmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlR5cGVUYWcuVU5JTklUSUFMSVpFRF9USElTOwoKLyoqIFRoZXNlIHBzZXVkby10eXBlcyBhcHBlYXIgaW4gdGhlIGdlbmVyYXRlZCB2ZXJpZmllciB0YWJsZXMgdG8KICogIGluZGljYXRlIG9iamVjdHMgdGhhdCBoYXZlIGJlZW4gYWxsb2NhdGVkIGJ1dCBub3QgeWV0IGNvbnN0cnVjdGVkLgogKgogKiAgPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24gcmlzay4KICogIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yCiAqICBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+CiAqLwpjbGFzcyBVbmluaXRpYWxpemVkVHlwZSBleHRlbmRzIFR5cGUuRGVsZWdhdGVkVHlwZSB7CgogICAgcHVibGljIHN0YXRpYyBVbmluaXRpYWxpemVkVHlwZSB1bmluaXRpYWxpemVkVGhpcyhUeXBlIHF0eXBlKSB7CiAgICAgICAgcmV0dXJuIG5ldyBVbmluaXRpYWxpemVkVHlwZShVTklOSVRJQUxJWkVEX1RISVMsIHF0eXBlLCAtMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHF0eXBlLmdldE1ldGFkYXRhKCkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgVW5pbml0aWFsaXplZFR5cGUgdW5pbml0aWFsaXplZE9iamVjdChUeXBlIHF0eXBlLCBpbnQgb2Zmc2V0KSB7CiAgICAgICAgcmV0dXJuIG5ldyBVbmluaXRpYWxpemVkVHlwZShVTklOSVRJQUxJWkVEX09CSkVDVCwgcXR5cGUsIG9mZnNldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHF0eXBlLmdldE1ldGFkYXRhKCkpOwogICAgfQoKICAgIHB1YmxpYyBmaW5hbCBpbnQgb2Zmc2V0OyAvLyBQQyB3aGVyZSBhbGxvY2F0aW9uIHRvb2sgcGxhY2UKICAgIHByaXZhdGUgVW5pbml0aWFsaXplZFR5cGUoVHlwZVRhZyB0YWcsIFR5cGUgcXR5cGUsIGludCBvZmZzZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFR5cGVNZXRhZGF0YSBtZXRhZGF0YSkgewogICAgICAgIHN1cGVyKHRhZywgcXR5cGUsIG1ldGFkYXRhKTsKICAgICAgICB0aGlzLm9mZnNldCA9IG9mZnNldDsKICAgIH0KCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBVbmluaXRpYWxpemVkVHlwZSBjbG9uZVdpdGhNZXRhZGF0YShmaW5hbCBUeXBlTWV0YWRhdGEgbWQpIHsKICAgICAgICByZXR1cm4gbmV3IFVuaW5pdGlhbGl6ZWRUeXBlKHRhZywgcXR5cGUsIG9mZnNldCwgbWQpOwogICAgfQoKICAgIFR5cGUgaW5pdGlhbGl6ZWRUeXBlKCkgewogICAgICAgIHJldHVybiBxdHlwZTsKICAgIH0KfQpQSwMECgAACAAABjupSutbAFnOXAEAzlwBACAAAABjb20vc3VuL3Rvb2xzL2phdmFjL2p2bS9HZW4uamF2YS8qCiAqIENvcHlyaWdodCAoYykgMTk5OSwgMjAxNywgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLmphdmFjLmp2bTsKCmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuKjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5KQ0RpYWdub3N0aWMuRGlhZ25vc3RpY1Bvc2l0aW9uOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkxpc3Q7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuKjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5BdHRyaWJ1dGUuVHlwZUNvbXBvdW5kOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlN5bWJvbC5WYXJTeW1ib2w7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvbXAuKjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS4qOwoKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5TeW1ib2wuKjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5UeXBlLio7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmp2bS5Db2RlLio7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmp2bS5JdGVtcy4qOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkVuZFBvc1RhYmxlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkpDVHJlZS4qOwoKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuRmxhZ3MuKjsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuS2luZHMuS2luZC4qOwppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5UeXBlVGFnLio7CmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5qdm0uQnl0ZUNvZGVzLio7CmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5qdm0uQ1JURmxhZ3MuKjsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLm1haW4uT3B0aW9uLio7CmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkpDVHJlZS5UYWcuKjsKCi8qKiBUaGlzIHBhc3MgbWFwcyBmbGF0IEphdmEgKGkuZS4gd2l0aG91dCBpbm5lciBjbGFzc2VzKSB0byBieXRlY29kZXMuCiAqCiAqICA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiAgSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93biByaXNrLgogKiAgVGhpcyBjb2RlIGFuZCBpdHMgaW50ZXJuYWwgaW50ZXJmYWNlcyBhcmUgc3ViamVjdCB0byBjaGFuZ2Ugb3IKICogIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj4KICovCnB1YmxpYyBjbGFzcyBHZW4gZXh0ZW5kcyBKQ1RyZWUuVmlzaXRvciB7CiAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIENvbnRleHQuS2V5PEdlbj4gZ2VuS2V5ID0gbmV3IENvbnRleHQuS2V5PD4oKTsKCiAgICBwcml2YXRlIGZpbmFsIExvZyBsb2c7CiAgICBwcml2YXRlIGZpbmFsIFN5bXRhYiBzeW1zOwogICAgcHJpdmF0ZSBmaW5hbCBDaGVjayBjaGs7CiAgICBwcml2YXRlIGZpbmFsIFJlc29sdmUgcnM7CiAgICBwcml2YXRlIGZpbmFsIFRyZWVNYWtlciBtYWtlOwogICAgcHJpdmF0ZSBmaW5hbCBOYW1lcyBuYW1lczsKICAgIHByaXZhdGUgZmluYWwgVGFyZ2V0IHRhcmdldDsKICAgIHByaXZhdGUgZmluYWwgTmFtZSBhY2Nlc3NEb2xsYXI7CiAgICBwcml2YXRlIGZpbmFsIFR5cGVzIHR5cGVzOwogICAgcHJpdmF0ZSBmaW5hbCBMb3dlciBsb3dlcjsKICAgIHByaXZhdGUgZmluYWwgQW5ub3RhdGUgYW5ub3RhdGU7CiAgICBwcml2YXRlIGZpbmFsIFN0cmluZ0NvbmNhdCBjb25jYXQ7CgogICAgLyoqIEZvcm1hdCBvZiBzdGFja21hcCB0YWJsZXMgdG8gYmUgZ2VuZXJhdGVkLiAqLwogICAgcHJpdmF0ZSBmaW5hbCBDb2RlLlN0YWNrTWFwRm9ybWF0IHN0YWNrTWFwOwoKICAgIC8qKiBBIHR5cGUgdGhhdCBzZXJ2ZXMgYXMgdGhlIGV4cGVjdGVkIHR5cGUgZm9yIGFsbCBtZXRob2QgZXhwcmVzc2lvbnMuCiAgICAgKi8KICAgIHByaXZhdGUgZmluYWwgVHlwZSBtZXRob2RUeXBlOwoKICAgIC8qKgogICAgICogQXJlIHdlIHByZXNlbnRseSB0cmF2ZXJzaW5nIGEgbGV0IGV4cHJlc3Npb24gPyBZZXMgaWYgZGVwdGggIT0gMAogICAgICovCiAgICBwcml2YXRlIGludCBsZXRFeHByRGVwdGg7CgogICAgcHVibGljIHN0YXRpYyBHZW4gaW5zdGFuY2UoQ29udGV4dCBjb250ZXh0KSB7CiAgICAgICAgR2VuIGluc3RhbmNlID0gY29udGV4dC5nZXQoZ2VuS2V5KTsKICAgICAgICBpZiAoaW5zdGFuY2UgPT0gbnVsbCkKICAgICAgICAgICAgaW5zdGFuY2UgPSBuZXcgR2VuKGNvbnRleHQpOwogICAgICAgIHJldHVybiBpbnN0YW5jZTsKICAgIH0KCiAgICAvKiogQ29uc3RhbnQgcG9vbCwgcmVzZXQgYnkgZ2VuQ2xhc3MuCiAgICAgKi8KICAgIHByaXZhdGUgZmluYWwgUG9vbCBwb29sOwoKICAgIHByb3RlY3RlZCBHZW4oQ29udGV4dCBjb250ZXh0KSB7CiAgICAgICAgY29udGV4dC5wdXQoZ2VuS2V5LCB0aGlzKTsKCiAgICAgICAgbmFtZXMgPSBOYW1lcy5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBsb2cgPSBMb2cuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgc3ltcyA9IFN5bXRhYi5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBjaGsgPSBDaGVjay5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBycyA9IFJlc29sdmUuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgbWFrZSA9IFRyZWVNYWtlci5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICB0YXJnZXQgPSBUYXJnZXQuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgdHlwZXMgPSBUeXBlcy5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICBjb25jYXQgPSBTdHJpbmdDb25jYXQuaW5zdGFuY2UoY29udGV4dCk7CgogICAgICAgIG1ldGhvZFR5cGUgPSBuZXcgTWV0aG9kVHlwZShudWxsLCBudWxsLCBudWxsLCBzeW1zLm1ldGhvZENsYXNzKTsKICAgICAgICBhY2Nlc3NEb2xsYXIgPSBuYW1lcy4KICAgICAgICAgICAgZnJvbVN0cmluZygiYWNjZXNzIiArIHRhcmdldC5zeW50aGV0aWNOYW1lQ2hhcigpKTsKICAgICAgICBsb3dlciA9IExvd2VyLmluc3RhbmNlKGNvbnRleHQpOwoKICAgICAgICBPcHRpb25zIG9wdGlvbnMgPSBPcHRpb25zLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIGxpbmVEZWJ1Z0luZm8gPQogICAgICAgICAgICBvcHRpb25zLmlzVW5zZXQoR19DVVNUT00pIHx8CiAgICAgICAgICAgIG9wdGlvbnMuaXNTZXQoR19DVVNUT00sICJsaW5lcyIpOwogICAgICAgIHZhckRlYnVnSW5mbyA9CiAgICAgICAgICAgIG9wdGlvbnMuaXNVbnNldChHX0NVU1RPTSkKICAgICAgICAgICAgPyBvcHRpb25zLmlzU2V0KEcpCiAgICAgICAgICAgIDogb3B0aW9ucy5pc1NldChHX0NVU1RPTSwgInZhcnMiKTsKICAgICAgICBnZW5DcnQgPSBvcHRpb25zLmlzU2V0KFhKQ09WKTsKICAgICAgICBkZWJ1Z0NvZGUgPSBvcHRpb25zLmlzU2V0KCJkZWJ1Zy5jb2RlIik7CiAgICAgICAgYWxsb3dCZXR0ZXJOdWxsQ2hlY2tzID0gb3B0aW9ucy5nZXRCb29sZWFuKCJhbGxvd0JldHRlck51bGxDaGVja3MiLCB0YXJnZXQuaGFzT2JqZWN0cygpKTsKICAgICAgICBwb29sID0gbmV3IFBvb2wodHlwZXMpOwoKICAgICAgICAvLyBpZ25vcmUgY2xkYyBiZWNhdXNlIHdlIGNhbm5vdCBoYXZlIGJvdGggc3RhY2ttYXAgZm9ybWF0cwogICAgICAgIHRoaXMuc3RhY2tNYXAgPSBTdGFja01hcEZvcm1hdC5KU1IyMDI7CiAgICAgICAgYW5ub3RhdGUgPSBBbm5vdGF0ZS5pbnN0YW5jZShjb250ZXh0KTsKICAgIH0KCiAgICAvKiogU3dpdGNoZXMKICAgICAqLwogICAgcHJpdmF0ZSBmaW5hbCBib29sZWFuIGxpbmVEZWJ1Z0luZm87CiAgICBwcml2YXRlIGZpbmFsIGJvb2xlYW4gdmFyRGVidWdJbmZvOwogICAgcHJpdmF0ZSBmaW5hbCBib29sZWFuIGdlbkNydDsKICAgIHByaXZhdGUgZmluYWwgYm9vbGVhbiBkZWJ1Z0NvZGU7CiAgICBwcml2YXRlIGZpbmFsIGJvb2xlYW4gYWxsb3dCZXR0ZXJOdWxsQ2hlY2tzOwoKICAgIC8qKiBDb2RlIGJ1ZmZlciwgc2V0IGJ5IGdlbk1ldGhvZC4KICAgICAqLwogICAgcHJpdmF0ZSBDb2RlIGNvZGU7CgogICAgLyoqIEl0ZW1zIHN0cnVjdHVyZSwgc2V0IGJ5IGdlbk1ldGhvZC4KICAgICAqLwogICAgcHJpdmF0ZSBJdGVtcyBpdGVtczsKCiAgICAvKiogRW52aXJvbm1lbnQgZm9yIHN5bWJvbCBsb29rdXAsIHNldCBieSBnZW5DbGFzcwogICAgICovCiAgICBwcml2YXRlIEVudjxBdHRyQ29udGV4dD4gYXR0ckVudjsKCiAgICAvKiogVGhlIHRvcCBsZXZlbCB0cmVlLgogICAgICovCiAgICBwcml2YXRlIEpDQ29tcGlsYXRpb25Vbml0IHRvcGxldmVsOwoKICAgIC8qKiBUaGUgbnVtYmVyIG9mIGNvZGUtZ2VuIGVycm9ycyBpbiB0aGlzIGNsYXNzLgogICAgICovCiAgICBwcml2YXRlIGludCBuZXJycyA9IDA7CgogICAgLyoqIEFuIG9iamVjdCBjb250YWluaW5nIG1hcHBpbmdzIG9mIHN5bnRheCB0cmVlcyB0byB0aGVpcgogICAgICogIGVuZGluZyBzb3VyY2UgcG9zaXRpb25zLgogICAgICovCiAgICBFbmRQb3NUYWJsZSBlbmRQb3NUYWJsZTsKCiAgICAvKiogR2VuZXJhdGUgY29kZSB0byBsb2FkIGFuIGludGVnZXIgY29uc3RhbnQuCiAgICAgKiAgQHBhcmFtIG4gICAgIFRoZSBpbnRlZ2VyIHRvIGJlIGxvYWRlZC4KICAgICAqLwogICAgdm9pZCBsb2FkSW50Q29uc3QoaW50IG4pIHsKICAgICAgICBpdGVtcy5tYWtlSW1tZWRpYXRlSXRlbShzeW1zLmludFR5cGUsIG4pLmxvYWQoKTsKICAgIH0KCiAgICAvKiogVGhlIG9wY29kZSB0aGF0IGxvYWRzIGEgemVybyBjb25zdGFudCBvZiBhIGdpdmVuIHR5cGUgY29kZS4KICAgICAqICBAcGFyYW0gdGMgICBUaGUgZ2l2ZW4gdHlwZSBjb2RlIChAc2VlIEJ5dGVDb2RlKS4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBpbnQgemVybyhpbnQgdGMpIHsKICAgICAgICBzd2l0Y2godGMpIHsKICAgICAgICBjYXNlIElOVGNvZGU6IGNhc2UgQllURWNvZGU6IGNhc2UgU0hPUlRjb2RlOiBjYXNlIENIQVJjb2RlOgogICAgICAgICAgICByZXR1cm4gaWNvbnN0XzA7CiAgICAgICAgY2FzZSBMT05HY29kZToKICAgICAgICAgICAgcmV0dXJuIGxjb25zdF8wOwogICAgICAgIGNhc2UgRkxPQVRjb2RlOgogICAgICAgICAgICByZXR1cm4gZmNvbnN0XzA7CiAgICAgICAgY2FzZSBET1VCTEVjb2RlOgogICAgICAgICAgICByZXR1cm4gZGNvbnN0XzA7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCJ6ZXJvIik7CiAgICAgICAgfQogICAgfQoKICAgIC8qKiBUaGUgb3Bjb2RlIHRoYXQgbG9hZHMgYSBvbmUgY29uc3RhbnQgb2YgYSBnaXZlbiB0eXBlIGNvZGUuCiAgICAgKiAgQHBhcmFtIHRjICAgVGhlIGdpdmVuIHR5cGUgY29kZSAoQHNlZSBCeXRlQ29kZSkuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgaW50IG9uZShpbnQgdGMpIHsKICAgICAgICByZXR1cm4gemVybyh0YykgKyAxOwogICAgfQoKICAgIC8qKiBHZW5lcmF0ZSBjb2RlIHRvIGxvYWQgLTEgb2YgdGhlIGdpdmVuIHR5cGUgY29kZSAoZWl0aGVyIGludCBvciBsb25nKS4KICAgICAqICBAcGFyYW0gdGMgICBUaGUgZ2l2ZW4gdHlwZSBjb2RlIChAc2VlIEJ5dGVDb2RlKS4KICAgICAqLwogICAgdm9pZCBlbWl0TWludXNPbmUoaW50IHRjKSB7CiAgICAgICAgaWYgKHRjID09IExPTkdjb2RlKSB7CiAgICAgICAgICAgIGl0ZW1zLm1ha2VJbW1lZGlhdGVJdGVtKHN5bXMubG9uZ1R5cGUsIExvbmcudmFsdWVPZigtMSkpLmxvYWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBjb2RlLmVtaXRvcDAoaWNvbnN0X20xKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqIENvbnN0cnVjdCBhIHN5bWJvbCB0byByZWZsZWN0IHRoZSBxdWFsaWZ5aW5nIHR5cGUgdGhhdCBzaG91bGQKICAgICAqICBhcHBlYXIgaW4gdGhlIGJ5dGUgY29kZSBhcyBwZXIgSkxTIDEzLjEuCiAgICAgKgogICAgICogIEZvciB7QGxpdGVyYWwgdGFyZ2V0ID49IDEuMn06IENsb25lIGEgbWV0aG9kIHdpdGggdGhlIHF1YWxpZmllciBhcyBvd25lciAoZXhjZXB0CiAgICAgKiAgZm9yIHRob3NlIGNhc2VzIHdoZXJlIHdlIG5lZWQgdG8gd29yayBhcm91bmQgVk0gYnVncykuCiAgICAgKgogICAgICogIEZvciB7QGxpdGVyYWwgdGFyZ2V0IDw9IDEuMX06IElmIHF1YWxpZmllZCB2YXJpYWJsZSBvciBtZXRob2QgaXMgZGVmaW5lZCBpbiBhCiAgICAgKiAgbm9uLWFjY2Vzc2libGUgY2xhc3MsIGNsb25lIGl0IHdpdGggdGhlIHF1YWxpZmllciBjbGFzcyBhcyBvd25lci4KICAgICAqCiAgICAgKiAgQHBhcmFtIHN5bSAgICBUaGUgYWNjZXNzZWQgc3ltYm9sCiAgICAgKiAgQHBhcmFtIHNpdGUgICBUaGUgcXVhbGlmaWVyJ3MgdHlwZS4KICAgICAqLwogICAgU3ltYm9sIGJpbmFyeVF1YWxpZmllcihTeW1ib2wgc3ltLCBUeXBlIHNpdGUpIHsKCiAgICAgICAgaWYgKHNpdGUuaGFzVGFnKEFSUkFZKSkgewogICAgICAgICAgICBpZiAoc3ltID09IHN5bXMubGVuZ3RoVmFyIHx8CiAgICAgICAgICAgICAgICBzeW0ub3duZXIgIT0gc3ltcy5hcnJheUNsYXNzKQogICAgICAgICAgICAgICAgcmV0dXJuIHN5bTsKICAgICAgICAgICAgLy8gYXJyYXkgY2xvbmUgY2FuIGJlIHF1YWxpZmllZCBieSB0aGUgYXJyYXkgdHlwZSBpbiBsYXRlciB0YXJnZXRzCiAgICAgICAgICAgIFN5bWJvbCBxdWFsaWZpZXIgPSBuZXcgQ2xhc3NTeW1ib2woRmxhZ3MuUFVCTElDLCBzaXRlLnRzeW0ubmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXRlLCBzeW1zLm5vU3ltYm9sKTsKICAgICAgICAgICAgcmV0dXJuIHN5bS5jbG9uZShxdWFsaWZpZXIpOwogICAgICAgIH0KCiAgICAgICAgaWYgKHN5bS5vd25lciA9PSBzaXRlLnRzeW0gfHwKICAgICAgICAgICAgKHN5bS5mbGFncygpICYgKFNUQVRJQyB8IFNZTlRIRVRJQykpID09IChTVEFUSUMgfCBTWU5USEVUSUMpKSB7CiAgICAgICAgICAgIHJldHVybiBzeW07CiAgICAgICAgfQoKICAgICAgICAvLyBsZWF2ZSBhbG9uZSBtZXRob2RzIGluaGVyaXRlZCBmcm9tIE9iamVjdAogICAgICAgIC8vIEpMUyAxMy4xLgogICAgICAgIGlmIChzeW0ub3duZXIgPT0gc3ltcy5vYmplY3RUeXBlLnRzeW0pCiAgICAgICAgICAgIHJldHVybiBzeW07CgogICAgICAgIHJldHVybiBzeW0uY2xvbmUoc2l0ZS50c3ltKTsKICAgIH0KCiAgICAvKiogSW5zZXJ0IGEgcmVmZXJlbmNlIHRvIGdpdmVuIHR5cGUgaW4gdGhlIGNvbnN0YW50IHBvb2wsCiAgICAgKiAgY2hlY2tpbmcgZm9yIGFuIGFycmF5IHdpdGggdG9vIG1hbnkgZGltZW5zaW9uczsKICAgICAqICByZXR1cm4gdGhlIHJlZmVyZW5jZSdzIGluZGV4LgogICAgICogIEBwYXJhbSB0eXBlICAgVGhlIHR5cGUgZm9yIHdoaWNoIGEgcmVmZXJlbmNlIGlzIGluc2VydGVkLgogICAgICovCiAgICBpbnQgbWFrZVJlZihEaWFnbm9zdGljUG9zaXRpb24gcG9zLCBUeXBlIHR5cGUpIHsKICAgICAgICBjaGVja0RpbWVuc2lvbihwb3MsIHR5cGUpOwogICAgICAgIGlmICh0eXBlLmlzQW5ub3RhdGVkKCkpIHsKICAgICAgICAgICAgcmV0dXJuIHBvb2wucHV0KChPYmplY3QpdHlwZSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIHBvb2wucHV0KHR5cGUuaGFzVGFnKENMQVNTKSA/IChPYmplY3QpdHlwZS50c3ltIDogKE9iamVjdCl0eXBlKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqIENoZWNrIGlmIHRoZSBnaXZlbiB0eXBlIGlzIGFuIGFycmF5IHdpdGggdG9vIG1hbnkgZGltZW5zaW9ucy4KICAgICAqLwogICAgcHJpdmF0ZSB2b2lkIGNoZWNrRGltZW5zaW9uKERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIFR5cGUgdCkgewogICAgICAgIHN3aXRjaCAodC5nZXRUYWcoKSkgewogICAgICAgIGNhc2UgTUVUSE9EOgogICAgICAgICAgICBjaGVja0RpbWVuc2lvbihwb3MsIHQuZ2V0UmV0dXJuVHlwZSgpKTsKICAgICAgICAgICAgZm9yIChMaXN0PFR5cGU+IGFyZ3MgPSB0LmdldFBhcmFtZXRlclR5cGVzKCk7IGFyZ3Mubm9uRW1wdHkoKTsgYXJncyA9IGFyZ3MudGFpbCkKICAgICAgICAgICAgICAgIGNoZWNrRGltZW5zaW9uKHBvcywgYXJncy5oZWFkKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBBUlJBWToKICAgICAgICAgICAgaWYgKHR5cGVzLmRpbWVuc2lvbnModCkgPiBDbGFzc0ZpbGUuTUFYX0RJTUVOU0lPTlMpIHsKICAgICAgICAgICAgICAgIGxvZy5lcnJvcihwb3MsICJsaW1pdC5kaW1lbnNpb25zIik7CiAgICAgICAgICAgICAgICBuZXJycysrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgIH0KCiAgICAvKiogQ3JlYXRlIGEgdGVtcG9yeSB2YXJpYWJsZS4KICAgICAqICBAcGFyYW0gdHlwZSAgIFRoZSB2YXJpYWJsZSdzIHR5cGUuCiAgICAgKi8KICAgIExvY2FsSXRlbSBtYWtlVGVtcChUeXBlIHR5cGUpIHsKICAgICAgICBWYXJTeW1ib2wgdiA9IG5ldyBWYXJTeW1ib2woRmxhZ3MuU1lOVEhFVElDLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lcy5lbXB0eSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW52LmVuY2xNZXRob2Quc3ltKTsKICAgICAgICBjb2RlLm5ld0xvY2FsKHYpOwogICAgICAgIHJldHVybiBpdGVtcy5tYWtlTG9jYWxJdGVtKHYpOwogICAgfQoKICAgIC8qKiBHZW5lcmF0ZSBjb2RlIHRvIGNhbGwgYSBub24tcHJpdmF0ZSBtZXRob2Qgb3IgY29uc3RydWN0b3IuCiAgICAgKiAgQHBhcmFtIHBvcyAgICAgICAgIFBvc2l0aW9uIHRvIGJlIHVzZWQgZm9yIGVycm9yIHJlcG9ydGluZy4KICAgICAqICBAcGFyYW0gc2l0ZSAgICAgICAgVGhlIHR5cGUgb2Ygd2hpY2ggdGhlIG1ldGhvZCBpcyBhIG1lbWJlci4KICAgICAqICBAcGFyYW0gbmFtZSAgICAgICAgVGhlIG1ldGhvZCdzIG5hbWUuCiAgICAgKiAgQHBhcmFtIGFyZ3R5cGVzICAgIFRoZSBtZXRob2QncyBhcmd1bWVudCB0eXBlcy4KICAgICAqICBAcGFyYW0gaXNTdGF0aWMgICAgQSBmbGFnIHRoYXQgaW5kaWNhdGVzIHdoZXRoZXIgd2UgY2FsbCBhCiAgICAgKiAgICAgICAgICAgICAgICAgICAgIHN0YXRpYyBvciBpbnN0YW5jZSBtZXRob2QuCiAgICAgKi8KICAgIHZvaWQgY2FsbE1ldGhvZChEaWFnbm9zdGljUG9zaXRpb24gcG9zLAogICAgICAgICAgICAgICAgICAgIFR5cGUgc2l0ZSwgTmFtZSBuYW1lLCBMaXN0PFR5cGU+IGFyZ3R5cGVzLAogICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gaXNTdGF0aWMpIHsKICAgICAgICBTeW1ib2wgbXN5bSA9IHJzLgogICAgICAgICAgICByZXNvbHZlSW50ZXJuYWxNZXRob2QocG9zLCBhdHRyRW52LCBzaXRlLCBuYW1lLCBhcmd0eXBlcywgbnVsbCk7CiAgICAgICAgaWYgKGlzU3RhdGljKSBpdGVtcy5tYWtlU3RhdGljSXRlbShtc3ltKS5pbnZva2UoKTsKICAgICAgICBlbHNlIGl0ZW1zLm1ha2VNZW1iZXJJdGVtKG1zeW0sIG5hbWUgPT0gbmFtZXMuaW5pdCkuaW52b2tlKCk7CiAgICB9CgogICAgLyoqIElzIHRoZSBnaXZlbiBtZXRob2QgZGVmaW5pdGlvbiBhbiBhY2Nlc3MgbWV0aG9kCiAgICAgKiAgcmVzdWx0aW5nIGZyb20gYSBxdWFsaWZpZWQgc3VwZXI/IFRoaXMgaXMgc2lnbmlmaWVkIGJ5IGFuIG9kZAogICAgICogIGFjY2VzcyBjb2RlLgogICAgICovCiAgICBwcml2YXRlIGJvb2xlYW4gaXNBY2Nlc3NTdXBlcihKQ01ldGhvZERlY2wgZW5jbE1ldGhvZCkgewogICAgICAgIHJldHVybgogICAgICAgICAgICAoZW5jbE1ldGhvZC5tb2RzLmZsYWdzICYgU1lOVEhFVElDKSAhPSAwICYmCiAgICAgICAgICAgIGlzT2RkQWNjZXNzTmFtZShlbmNsTWV0aG9kLm5hbWUpOwogICAgfQoKICAgIC8qKiBEb2VzIGdpdmVuIG5hbWUgc3RhcnQgd2l0aCAiYWNjZXNzJCIgYW5kIGVuZCBpbiBhbiBvZGQgZGlnaXQ/CiAgICAgKi8KICAgIHByaXZhdGUgYm9vbGVhbiBpc09kZEFjY2Vzc05hbWUoTmFtZSBuYW1lKSB7CiAgICAgICAgcmV0dXJuCiAgICAgICAgICAgIG5hbWUuc3RhcnRzV2l0aChhY2Nlc3NEb2xsYXIpICYmCiAgICAgICAgICAgIChuYW1lLmdldEJ5dGVBdChuYW1lLmdldEJ5dGVMZW5ndGgoKSAtIDEpICYgMSkgPT0gMTsKICAgIH0KCi8qICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBOb24tbG9jYWwgZXhpdHMKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgogICAgLyoqIEdlbmVyYXRlIGNvZGUgdG8gaW52b2tlIHRoZSBmaW5hbGl6ZXIgYXNzb2NpYXRlZCB3aXRoIGdpdmVuCiAgICAgKiAgZW52aXJvbm1lbnQuCiAgICAgKiAgQW55IGNhbGxzIHRvIGZpbmFsaXplcnMgYXJlIGFwcGVuZGVkIHRvIHRoZSBlbnZpcm9ubWVudHMgYGNvbnQnIGNoYWluLgogICAgICogIE1hcmsgYmVnaW5uaW5nIG9mIGdhcCBpbiBjYXRjaCBhbGwgcmFuZ2UgZm9yIGZpbmFsaXplci4KICAgICAqLwogICAgdm9pZCBnZW5GaW5hbGl6ZXIoRW52PEdlbkNvbnRleHQ+IGVudikgewogICAgICAgIGlmIChjb2RlLmlzQWxpdmUoKSAmJiBlbnYuaW5mby5maW5hbGl6ZSAhPSBudWxsKQogICAgICAgICAgICBlbnYuaW5mby5maW5hbGl6ZS5nZW4oKTsKICAgIH0KCiAgICAvKiogR2VuZXJhdGUgY29kZSB0byBjYWxsIGFsbCBmaW5hbGl6ZXJzIG9mIHN0cnVjdHVyZXMgYWJvcnRlZCBieQogICAgICogIGEgbm9uLWxvY2FsCiAgICAgKiAgZXhpdC4gIFJldHVybiB0YXJnZXQgZW52aXJvbm1lbnQgb2YgdGhlIG5vbi1sb2NhbCBleGl0LgogICAgICogIEBwYXJhbSB0YXJnZXQgICAgICBUaGUgdHJlZSByZXByZXNlbnRpbmcgdGhlIHN0cnVjdHVyZSB0aGF0J3MgYWJvcnRlZAogICAgICogIEBwYXJhbSBlbnYgICAgICAgICBUaGUgZW52aXJvbm1lbnQgY3VycmVudCBhdCB0aGUgbm9uLWxvY2FsIGV4aXQuCiAgICAgKi8KICAgIEVudjxHZW5Db250ZXh0PiB1bndpbmQoSkNUcmVlIHRhcmdldCwgRW52PEdlbkNvbnRleHQ+IGVudikgewogICAgICAgIEVudjxHZW5Db250ZXh0PiBlbnYxID0gZW52OwogICAgICAgIHdoaWxlICh0cnVlKSB7CiAgICAgICAgICAgIGdlbkZpbmFsaXplcihlbnYxKTsKICAgICAgICAgICAgaWYgKGVudjEudHJlZSA9PSB0YXJnZXQpIGJyZWFrOwogICAgICAgICAgICBlbnYxID0gZW52MS5uZXh0OwogICAgICAgIH0KICAgICAgICByZXR1cm4gZW52MTsKICAgIH0KCiAgICAvKiogTWFyayBlbmQgb2YgZ2FwIGluIGNhdGNoLWFsbCByYW5nZSBmb3IgZmluYWxpemVyLgogICAgICogIEBwYXJhbSBlbnYgICB0aGUgZW52aXJvbm1lbnQgd2hpY2ggbWlnaHQgY29udGFpbiB0aGUgZmluYWxpemVyCiAgICAgKiAgICAgICAgICAgICAgIChpZiBpdCBkb2VzLCBlbnYuaW5mby5nYXBzICE9IG51bGwpLgogICAgICovCiAgICB2b2lkIGVuZEZpbmFsaXplckdhcChFbnY8R2VuQ29udGV4dD4gZW52KSB7CiAgICAgICAgaWYgKGVudi5pbmZvLmdhcHMgIT0gbnVsbCAmJiBlbnYuaW5mby5nYXBzLmxlbmd0aCgpICUgMiA9PSAxKQogICAgICAgICAgICBlbnYuaW5mby5nYXBzLmFwcGVuZChjb2RlLmN1ckNQKCkpOwogICAgfQoKICAgIC8qKiBNYXJrIGVuZCBvZiBhbGwgZ2FwcyBpbiBjYXRjaC1hbGwgcmFuZ2VzIGZvciBmaW5hbGl6ZXJzIG9mIGVudmlyb25tZW50cwogICAgICogIGx5aW5nIGJldHdlZW4sIGFuZCBpbmNsdWRpbmcgdG8gdHdvIGVudmlyb25tZW50cy4KICAgICAqICBAcGFyYW0gZnJvbSAgICB0aGUgbW9zdCBkZWVwbHkgbmVzdGVkIGVudmlyb25tZW50IHRvIG1hcmsKICAgICAqICBAcGFyYW0gdG8gICAgICB0aGUgbGVhc3QgZGVlcGx5IG5lc3RlZCBlbnZpcm9ubWVudCB0byBtYXJrCiAgICAgKi8KICAgIHZvaWQgZW5kRmluYWxpemVyR2FwcyhFbnY8R2VuQ29udGV4dD4gZnJvbSwgRW52PEdlbkNvbnRleHQ+IHRvKSB7CiAgICAgICAgRW52PEdlbkNvbnRleHQ+IGxhc3QgPSBudWxsOwogICAgICAgIHdoaWxlIChsYXN0ICE9IHRvKSB7CiAgICAgICAgICAgIGVuZEZpbmFsaXplckdhcChmcm9tKTsKICAgICAgICAgICAgbGFzdCA9IGZyb207CiAgICAgICAgICAgIGZyb20gPSBmcm9tLm5leHQ7CiAgICAgICAgfQogICAgfQoKICAgIC8qKiBEbyBhbnkgb2YgdGhlIHN0cnVjdHVyZXMgYWJvcnRlZCBieSBhIG5vbi1sb2NhbCBleGl0IGhhdmUKICAgICAqICBmaW5hbGl6ZXJzIHRoYXQgcmVxdWlyZSBhbiBlbXB0eSBzdGFjaz8KICAgICAqICBAcGFyYW0gdGFyZ2V0ICAgICAgVGhlIHRyZWUgcmVwcmVzZW50aW5nIHRoZSBzdHJ1Y3R1cmUgdGhhdCdzIGFib3J0ZWQKICAgICAqICBAcGFyYW0gZW52ICAgICAgICAgVGhlIGVudmlyb25tZW50IGN1cnJlbnQgYXQgdGhlIG5vbi1sb2NhbCBleGl0LgogICAgICovCiAgICBib29sZWFuIGhhc0ZpbmFsbHkoSkNUcmVlIHRhcmdldCwgRW52PEdlbkNvbnRleHQ+IGVudikgewogICAgICAgIHdoaWxlIChlbnYudHJlZSAhPSB0YXJnZXQpIHsKICAgICAgICAgICAgaWYgKGVudi50cmVlLmhhc1RhZyhUUlkpICYmIGVudi5pbmZvLmZpbmFsaXplLmhhc0ZpbmFsaXplcigpKQogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIGVudiA9IGVudi5uZXh0OwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgovKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogTm9ybWFsaXppbmcgY2xhc3MtbWVtYmVycy4KICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgogICAgLyoqIERpc3RyaWJ1dGUgbWVtYmVyIGluaXRpYWxpemVyIGNvZGUgaW50byBjb25zdHJ1Y3RvcnMgYW5kIHtAY29kZSA8Y2xpbml0Pn0KICAgICAqICBtZXRob2QuCiAgICAgKiAgQHBhcmFtIGRlZnMgICAgICAgICBUaGUgbGlzdCBvZiBjbGFzcyBtZW1iZXIgZGVjbGFyYXRpb25zLgogICAgICogIEBwYXJhbSBjICAgICAgICAgICAgVGhlIGVuY2xvc2luZyBjbGFzcy4KICAgICAqLwogICAgTGlzdDxKQ1RyZWU+IG5vcm1hbGl6ZURlZnMoTGlzdDxKQ1RyZWU+IGRlZnMsIENsYXNzU3ltYm9sIGMpIHsKICAgICAgICBMaXN0QnVmZmVyPEpDU3RhdGVtZW50PiBpbml0Q29kZSA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICBMaXN0QnVmZmVyPEF0dHJpYnV0ZS5UeXBlQ29tcG91bmQ+IGluaXRUQXMgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgTGlzdEJ1ZmZlcjxKQ1N0YXRlbWVudD4gY2xpbml0Q29kZSA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICBMaXN0QnVmZmVyPEF0dHJpYnV0ZS5UeXBlQ29tcG91bmQ+IGNsaW5pdFRBcyA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICBMaXN0QnVmZmVyPEpDVHJlZT4gbWV0aG9kRGVmcyA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICAvLyBTb3J0IGRlZmluaXRpb25zIGludG8gdGhyZWUgbGlzdGJ1ZmZlcnM6CiAgICAgICAgLy8gIC0gaW5pdENvZGUgZm9yIGluc3RhbmNlIGluaXRpYWxpemVycwogICAgICAgIC8vICAtIGNsaW5pdENvZGUgZm9yIGNsYXNzIGluaXRpYWxpemVycwogICAgICAgIC8vICAtIG1ldGhvZERlZnMgZm9yIG1ldGhvZCBkZWZpbml0aW9ucwogICAgICAgIGZvciAoTGlzdDxKQ1RyZWU+IGwgPSBkZWZzOyBsLm5vbkVtcHR5KCk7IGwgPSBsLnRhaWwpIHsKICAgICAgICAgICAgSkNUcmVlIGRlZiA9IGwuaGVhZDsKICAgICAgICAgICAgc3dpdGNoIChkZWYuZ2V0VGFnKCkpIHsKICAgICAgICAgICAgY2FzZSBCTE9DSzoKICAgICAgICAgICAgICAgIEpDQmxvY2sgYmxvY2sgPSAoSkNCbG9jaylkZWY7CiAgICAgICAgICAgICAgICBpZiAoKGJsb2NrLmZsYWdzICYgU1RBVElDKSAhPSAwKQogICAgICAgICAgICAgICAgICAgIGNsaW5pdENvZGUuYXBwZW5kKGJsb2NrKTsKICAgICAgICAgICAgICAgIGVsc2UgaWYgKChibG9jay5mbGFncyAmIFNZTlRIRVRJQykgPT0gMCkKICAgICAgICAgICAgICAgICAgICBpbml0Q29kZS5hcHBlbmQoYmxvY2spOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgTUVUSE9EREVGOgogICAgICAgICAgICAgICAgbWV0aG9kRGVmcy5hcHBlbmQoZGVmKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFZBUkRFRjoKICAgICAgICAgICAgICAgIEpDVmFyaWFibGVEZWNsIHZkZWYgPSAoSkNWYXJpYWJsZURlY2wpIGRlZjsKICAgICAgICAgICAgICAgIFZhclN5bWJvbCBzeW0gPSB2ZGVmLnN5bTsKICAgICAgICAgICAgICAgIGNoZWNrRGltZW5zaW9uKHZkZWYucG9zKCksIHN5bS50eXBlKTsKICAgICAgICAgICAgICAgIGlmICh2ZGVmLmluaXQgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIGlmICgoc3ltLmZsYWdzKCkgJiBTVEFUSUMpID09IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gQWx3YXlzIGluaXRpYWxpemUgaW5zdGFuY2UgdmFyaWFibGVzLgogICAgICAgICAgICAgICAgICAgICAgICBKQ1N0YXRlbWVudCBpbml0ID0gbWFrZS5hdCh2ZGVmLnBvcygpKS4KICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFzc2lnbm1lbnQoc3ltLCB2ZGVmLmluaXQpOwogICAgICAgICAgICAgICAgICAgICAgICBpbml0Q29kZS5hcHBlbmQoaW5pdCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGVuZFBvc1RhYmxlLnJlcGxhY2VUcmVlKHZkZWYsIGluaXQpOwogICAgICAgICAgICAgICAgICAgICAgICBpbml0VEFzLmFkZEFsbChnZXRBbmRSZW1vdmVOb25GaWVsZFRBcyhzeW0pKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHN5bS5nZXRDb25zdFZhbHVlKCkgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBJbml0aWFsaXplIGNsYXNzIChzdGF0aWMpIHZhcmlhYmxlcyBvbmx5IGlmCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRoZXkgYXJlIG5vdCBjb21waWxlLXRpbWUgY29uc3RhbnRzLgogICAgICAgICAgICAgICAgICAgICAgICBKQ1N0YXRlbWVudCBpbml0ID0gbWFrZS5hdCh2ZGVmLnBvcykuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBBc3NpZ25tZW50KHN5bSwgdmRlZi5pbml0KTsKICAgICAgICAgICAgICAgICAgICAgICAgY2xpbml0Q29kZS5hcHBlbmQoaW5pdCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGVuZFBvc1RhYmxlLnJlcGxhY2VUcmVlKHZkZWYsIGluaXQpOwogICAgICAgICAgICAgICAgICAgICAgICBjbGluaXRUQXMuYWRkQWxsKGdldEFuZFJlbW92ZU5vbkZpZWxkVEFzKHN5bSkpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNoZWNrU3RyaW5nQ29uc3RhbnQodmRlZi5pbml0LnBvcygpLCBzeW0uZ2V0Q29uc3RWYWx1ZSgpKTsKICAgICAgICAgICAgICAgICAgICAgICAgLyogaWYgdGhlIGluaXQgY29udGFpbnMgYSByZWZlcmVuY2UgdG8gYW4gZXh0ZXJuYWwgY2xhc3MsIGFkZCBpdCB0byB0aGUKICAgICAgICAgICAgICAgICAgICAgICAgICogY29uc3RhbnQncyBwb29sCiAgICAgICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgICAgICB2ZGVmLmluaXQuYWNjZXB0KGNsYXNzUmVmZXJlbmNlVmlzaXRvcik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICBBc3NlcnQuZXJyb3IoKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvLyBJbnNlcnQgYW55IGluc3RhbmNlIGluaXRpYWxpemVycyBpbnRvIGFsbCBjb25zdHJ1Y3RvcnMuCiAgICAgICAgaWYgKGluaXRDb2RlLmxlbmd0aCgpICE9IDApIHsKICAgICAgICAgICAgTGlzdDxKQ1N0YXRlbWVudD4gaW5pdHMgPSBpbml0Q29kZS50b0xpc3QoKTsKICAgICAgICAgICAgaW5pdFRBcy5hZGRBbGwoYy5nZXRJbml0VHlwZUF0dHJpYnV0ZXMoKSk7CiAgICAgICAgICAgIExpc3Q8QXR0cmlidXRlLlR5cGVDb21wb3VuZD4gaW5pdFRBbGlzdCA9IGluaXRUQXMudG9MaXN0KCk7CiAgICAgICAgICAgIGZvciAoSkNUcmVlIHQgOiBtZXRob2REZWZzKSB7CiAgICAgICAgICAgICAgICBub3JtYWxpemVNZXRob2QoKEpDTWV0aG9kRGVjbCl0LCBpbml0cywgaW5pdFRBbGlzdCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLy8gSWYgdGhlcmUgYXJlIGNsYXNzIGluaXRpYWxpemVycywgY3JlYXRlIGEgPGNsaW5pdD4gbWV0aG9kCiAgICAgICAgLy8gdGhhdCBjb250YWlucyB0aGVtIGFzIGl0cyBib2R5LgogICAgICAgIGlmIChjbGluaXRDb2RlLmxlbmd0aCgpICE9IDApIHsKICAgICAgICAgICAgTWV0aG9kU3ltYm9sIGNsaW5pdCA9IG5ldyBNZXRob2RTeW1ib2woCiAgICAgICAgICAgICAgICBTVEFUSUMgfCAoYy5mbGFncygpICYgU1RSSUNURlApLAogICAgICAgICAgICAgICAgbmFtZXMuY2xpbml0LAogICAgICAgICAgICAgICAgbmV3IE1ldGhvZFR5cGUoCiAgICAgICAgICAgICAgICAgICAgTGlzdC5uaWwoKSwgc3ltcy52b2lkVHlwZSwKICAgICAgICAgICAgICAgICAgICBMaXN0Lm5pbCgpLCBzeW1zLm1ldGhvZENsYXNzKSwKICAgICAgICAgICAgICAgIGMpOwogICAgICAgICAgICBjLm1lbWJlcnMoKS5lbnRlcihjbGluaXQpOwogICAgICAgICAgICBMaXN0PEpDU3RhdGVtZW50PiBjbGluaXRTdGF0cyA9IGNsaW5pdENvZGUudG9MaXN0KCk7CiAgICAgICAgICAgIEpDQmxvY2sgYmxvY2sgPSBtYWtlLmF0KGNsaW5pdFN0YXRzLmhlYWQucG9zKCkpLkJsb2NrKDAsIGNsaW5pdFN0YXRzKTsKICAgICAgICAgICAgYmxvY2suZW5kcG9zID0gVHJlZUluZm8uZW5kUG9zKGNsaW5pdFN0YXRzLmxhc3QoKSk7CiAgICAgICAgICAgIG1ldGhvZERlZnMuYXBwZW5kKG1ha2UuTWV0aG9kRGVmKGNsaW5pdCwgYmxvY2spKTsKCiAgICAgICAgICAgIGlmICghY2xpbml0VEFzLmlzRW1wdHkoKSkKICAgICAgICAgICAgICAgIGNsaW5pdC5hcHBlbmRVbmlxdWVUeXBlQXR0cmlidXRlcyhjbGluaXRUQXMudG9MaXN0KCkpOwogICAgICAgICAgICBpZiAoIWMuZ2V0Q2xhc3NJbml0VHlwZUF0dHJpYnV0ZXMoKS5pc0VtcHR5KCkpCiAgICAgICAgICAgICAgICBjbGluaXQuYXBwZW5kVW5pcXVlVHlwZUF0dHJpYnV0ZXMoYy5nZXRDbGFzc0luaXRUeXBlQXR0cmlidXRlcygpKTsKICAgICAgICB9CiAgICAgICAgLy8gUmV0dXJuIGFsbCBtZXRob2QgZGVmaW5pdGlvbnMuCiAgICAgICAgcmV0dXJuIG1ldGhvZERlZnMudG9MaXN0KCk7CiAgICB9CgogICAgcHJpdmF0ZSBMaXN0PEF0dHJpYnV0ZS5UeXBlQ29tcG91bmQ+IGdldEFuZFJlbW92ZU5vbkZpZWxkVEFzKFZhclN5bWJvbCBzeW0pIHsKICAgICAgICBMaXN0PFR5cGVDb21wb3VuZD4gdGFzID0gc3ltLmdldFJhd1R5cGVBdHRyaWJ1dGVzKCk7CiAgICAgICAgTGlzdEJ1ZmZlcjxBdHRyaWJ1dGUuVHlwZUNvbXBvdW5kPiBmaWVsZFRBcyA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICBMaXN0QnVmZmVyPEF0dHJpYnV0ZS5UeXBlQ29tcG91bmQ+IG5vbmZpZWxkVEFzID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgIGZvciAoVHlwZUNvbXBvdW5kIHRhIDogdGFzKSB7CiAgICAgICAgICAgIEFzc2VydC5jaGVjayh0YS5nZXRQb3NpdGlvbigpLnR5cGUgIT0gVGFyZ2V0VHlwZS5VTktOT1dOKTsKICAgICAgICAgICAgaWYgKHRhLmdldFBvc2l0aW9uKCkudHlwZSA9PSBUYXJnZXRUeXBlLkZJRUxEKSB7CiAgICAgICAgICAgICAgICBmaWVsZFRBcy5hZGQodGEpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgbm9uZmllbGRUQXMuYWRkKHRhKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBzeW0uc2V0VHlwZUF0dHJpYnV0ZXMoZmllbGRUQXMudG9MaXN0KCkpOwogICAgICAgIHJldHVybiBub25maWVsZFRBcy50b0xpc3QoKTsKICAgIH0KCiAgICAvKiogQ2hlY2sgYSBjb25zdGFudCB2YWx1ZSBhbmQgcmVwb3J0IGlmIGl0IGlzIGEgc3RyaW5nIHRoYXQgaXMKICAgICAqICB0b28gbGFyZ2UuCiAgICAgKi8KICAgIHByaXZhdGUgdm9pZCBjaGVja1N0cmluZ0NvbnN0YW50KERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIE9iamVjdCBjb25zdFZhbHVlKSB7CiAgICAgICAgaWYgKG5lcnJzICE9IDAgfHwgLy8gb25seSBjb21wbGFpbiBhYm91dCBhIGxvbmcgc3RyaW5nIG9uY2UKICAgICAgICAgICAgY29uc3RWYWx1ZSA9PSBudWxsIHx8CiAgICAgICAgICAgICEoY29uc3RWYWx1ZSBpbnN0YW5jZW9mIFN0cmluZykgfHwKICAgICAgICAgICAgKChTdHJpbmcpY29uc3RWYWx1ZSkubGVuZ3RoKCkgPCBQb29sLk1BWF9TVFJJTkdfTEVOR1RIKQogICAgICAgICAgICByZXR1cm47CiAgICAgICAgbG9nLmVycm9yKHBvcywgImxpbWl0LnN0cmluZyIpOwogICAgICAgIG5lcnJzKys7CiAgICB9CgogICAgLyoqIEluc2VydCBpbnN0YW5jZSBpbml0aWFsaXplciBjb2RlIGludG8gaW5pdGlhbCBjb25zdHJ1Y3Rvci4KICAgICAqICBAcGFyYW0gbWQgICAgICAgIFRoZSB0cmVlIHBvdGVudGlhbGx5IHJlcHJlc2VudGluZyBhCiAgICAgKiAgICAgICAgICAgICAgICAgICBjb25zdHJ1Y3RvcidzIGRlZmluaXRpb24uCiAgICAgKiAgQHBhcmFtIGluaXRDb2RlICBUaGUgbGlzdCBvZiBpbnN0YW5jZSBpbml0aWFsaXplciBzdGF0ZW1lbnRzLgogICAgICogIEBwYXJhbSBpbml0VEFzICBUeXBlIGFubm90YXRpb25zIGZyb20gdGhlIGluaXRpYWxpemVyIGV4cHJlc3Npb24uCiAgICAgKi8KICAgIHZvaWQgbm9ybWFsaXplTWV0aG9kKEpDTWV0aG9kRGVjbCBtZCwgTGlzdDxKQ1N0YXRlbWVudD4gaW5pdENvZGUsIExpc3Q8VHlwZUNvbXBvdW5kPiBpbml0VEFzKSB7CiAgICAgICAgaWYgKG1kLm5hbWUgPT0gbmFtZXMuaW5pdCAmJiBUcmVlSW5mby5pc0luaXRpYWxDb25zdHJ1Y3RvcihtZCkpIHsKICAgICAgICAgICAgLy8gV2UgYXJlIHNlZWluZyBhIGNvbnN0cnVjdG9yIHRoYXQgZG9lcyBub3QgY2FsbCBhbm90aGVyCiAgICAgICAgICAgIC8vIGNvbnN0cnVjdG9yIG9mIHRoZSBzYW1lIGNsYXNzLgogICAgICAgICAgICBMaXN0PEpDU3RhdGVtZW50PiBzdGF0cyA9IG1kLmJvZHkuc3RhdHM7CiAgICAgICAgICAgIExpc3RCdWZmZXI8SkNTdGF0ZW1lbnQ+IG5ld3N0YXRzID0gbmV3IExpc3RCdWZmZXI8PigpOwoKICAgICAgICAgICAgaWYgKHN0YXRzLm5vbkVtcHR5KCkpIHsKICAgICAgICAgICAgICAgIC8vIENvcHkgaW5pdGlhbGl6ZXJzIG9mIHN5bnRoZXRpYyB2YXJpYWJsZXMgZ2VuZXJhdGVkIGluCiAgICAgICAgICAgICAgICAvLyB0aGUgdHJhbnNsYXRpb24gb2YgaW5uZXIgY2xhc3Nlcy4KICAgICAgICAgICAgICAgIHdoaWxlIChUcmVlSW5mby5pc1N5bnRoZXRpY0luaXQoc3RhdHMuaGVhZCkpIHsKICAgICAgICAgICAgICAgICAgICBuZXdzdGF0cy5hcHBlbmQoc3RhdHMuaGVhZCk7CiAgICAgICAgICAgICAgICAgICAgc3RhdHMgPSBzdGF0cy50YWlsOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgLy8gQ29weSBzdXBlcmNsYXNzIGNvbnN0cnVjdG9yIGNhbGwKICAgICAgICAgICAgICAgIG5ld3N0YXRzLmFwcGVuZChzdGF0cy5oZWFkKTsKICAgICAgICAgICAgICAgIHN0YXRzID0gc3RhdHMudGFpbDsKICAgICAgICAgICAgICAgIC8vIENvcHkgcmVtYWluaW5nIHN5bnRoZXRpYyBpbml0aWFsaXplcnMuCiAgICAgICAgICAgICAgICB3aGlsZSAoc3RhdHMubm9uRW1wdHkoKSAmJgogICAgICAgICAgICAgICAgICAgICAgIFRyZWVJbmZvLmlzU3ludGhldGljSW5pdChzdGF0cy5oZWFkKSkgewogICAgICAgICAgICAgICAgICAgIG5ld3N0YXRzLmFwcGVuZChzdGF0cy5oZWFkKTsKICAgICAgICAgICAgICAgICAgICBzdGF0cyA9IHN0YXRzLnRhaWw7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvLyBOb3cgaW5zZXJ0IHRoZSBpbml0aWFsaXplciBjb2RlLgogICAgICAgICAgICAgICAgbmV3c3RhdHMuYXBwZW5kTGlzdChpbml0Q29kZSk7CiAgICAgICAgICAgICAgICAvLyBBbmQgY29weSBhbGwgcmVtYWluaW5nIHN0YXRlbWVudHMuCiAgICAgICAgICAgICAgICB3aGlsZSAoc3RhdHMubm9uRW1wdHkoKSkgewogICAgICAgICAgICAgICAgICAgIG5ld3N0YXRzLmFwcGVuZChzdGF0cy5oZWFkKTsKICAgICAgICAgICAgICAgICAgICBzdGF0cyA9IHN0YXRzLnRhaWw7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgbWQuYm9keS5zdGF0cyA9IG5ld3N0YXRzLnRvTGlzdCgpOwogICAgICAgICAgICBpZiAobWQuYm9keS5lbmRwb3MgPT0gUG9zaXRpb24uTk9QT1MpCiAgICAgICAgICAgICAgICBtZC5ib2R5LmVuZHBvcyA9IFRyZWVJbmZvLmVuZFBvcyhtZC5ib2R5LnN0YXRzLmxhc3QoKSk7CgogICAgICAgICAgICBtZC5zeW0uYXBwZW5kVW5pcXVlVHlwZUF0dHJpYnV0ZXMoaW5pdFRBcyk7CiAgICAgICAgfQogICAgfQoKLyogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFRyYXZlcnNhbCBtZXRob2RzCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKICAgIC8qKiBWaXNpdG9yIGFyZ3VtZW50OiBUaGUgY3VycmVudCBlbnZpcm9ubWVudC4KICAgICAqLwogICAgRW52PEdlbkNvbnRleHQ+IGVudjsKCiAgICAvKiogVmlzaXRvciBhcmd1bWVudDogVGhlIGV4cGVjdGVkIHR5cGUgKHByb3RvdHlwZSkuCiAgICAgKi8KICAgIFR5cGUgcHQ7CgogICAgLyoqIFZpc2l0b3IgcmVzdWx0OiBUaGUgaXRlbSByZXByZXNlbnRpbmcgdGhlIGNvbXB1dGVkIHZhbHVlLgogICAgICovCiAgICBJdGVtIHJlc3VsdDsKCiAgICAvKiogVmlzaXRvciBtZXRob2Q6IGdlbmVyYXRlIGNvZGUgZm9yIGEgZGVmaW5pdGlvbiwgY2F0Y2hpbmcgYW5kIHJlcG9ydGluZwogICAgICogIGFueSBjb21wbGV0aW9uIGZhaWx1cmVzLgogICAgICogIEBwYXJhbSB0cmVlICAgIFRoZSBkZWZpbml0aW9uIHRvIGJlIHZpc2l0ZWQuCiAgICAgKiAgQHBhcmFtIGVudiAgICAgVGhlIGVudmlyb25tZW50IGN1cnJlbnQgYXQgdGhlIGRlZmluaXRpb24uCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIGdlbkRlZihKQ1RyZWUgdHJlZSwgRW52PEdlbkNvbnRleHQ+IGVudikgewogICAgICAgIEVudjxHZW5Db250ZXh0PiBwcmV2RW52ID0gdGhpcy5lbnY7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgdGhpcy5lbnYgPSBlbnY7CiAgICAgICAgICAgIHRyZWUuYWNjZXB0KHRoaXMpOwogICAgICAgIH0gY2F0Y2ggKENvbXBsZXRpb25GYWlsdXJlIGV4KSB7CiAgICAgICAgICAgIGNoay5jb21wbGV0aW9uRXJyb3IodHJlZS5wb3MoKSwgZXgpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgIHRoaXMuZW52ID0gcHJldkVudjsKICAgICAgICB9CiAgICB9CgogICAgLyoqIERlcml2ZWQgdmlzaXRvciBtZXRob2Q6IGNoZWNrIHdoZXRoZXIgQ2hhcmFjdGVyUmFuZ2VUYWJsZQogICAgICogIHNob3VsZCBiZSBlbWl0dGVkLCBpZiBzbywgcHV0IGEgbmV3IGVudHJ5IGludG8gQ1JUYWJsZQogICAgICogIGFuZCBjYWxsIG1ldGhvZCB0byBnZW5lcmF0ZSBieXRlY29kZS4KICAgICAqICBJZiBub3QsIGp1c3QgY2FsbCBtZXRob2QgdG8gZ2VuZXJhdGUgYnl0ZWNvZGUuCiAgICAgKiAgQHNlZSAgICAjZ2VuU3RhdChKQ1RyZWUsIEVudikKICAgICAqCiAgICAgKiAgQHBhcmFtICB0cmVlICAgICBUaGUgdHJlZSB0byBiZSB2aXNpdGVkLgogICAgICogIEBwYXJhbSAgZW52ICAgICAgVGhlIGVudmlyb25tZW50IHRvIHVzZS4KICAgICAqICBAcGFyYW0gIGNydEZsYWdzIFRoZSBDaGFyYWN0ZXJSYW5nZVRhYmxlIGZsYWdzCiAgICAgKiAgICAgICAgICAgICAgICAgICBpbmRpY2F0aW5nIHR5cGUgb2YgdGhlIGVudHJ5LgogICAgICovCiAgICBwdWJsaWMgdm9pZCBnZW5TdGF0KEpDVHJlZSB0cmVlLCBFbnY8R2VuQ29udGV4dD4gZW52LCBpbnQgY3J0RmxhZ3MpIHsKICAgICAgICBpZiAoIWdlbkNydCkgewogICAgICAgICAgICBnZW5TdGF0KHRyZWUsIGVudik7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgaW50IHN0YXJ0cGMgPSBjb2RlLmN1ckNQKCk7CiAgICAgICAgZ2VuU3RhdCh0cmVlLCBlbnYpOwogICAgICAgIGlmICh0cmVlLmhhc1RhZyhUYWcuQkxPQ0spKSBjcnRGbGFncyB8PSBDUlRfQkxPQ0s7CiAgICAgICAgY29kZS5jcnQucHV0KHRyZWUsIGNydEZsYWdzLCBzdGFydHBjLCBjb2RlLmN1ckNQKCkpOwogICAgfQoKICAgIC8qKiBEZXJpdmVkIHZpc2l0b3IgbWV0aG9kOiBnZW5lcmF0ZSBjb2RlIGZvciBhIHN0YXRlbWVudC4KICAgICAqLwogICAgcHVibGljIHZvaWQgZ2VuU3RhdChKQ1RyZWUgdHJlZSwgRW52PEdlbkNvbnRleHQ+IGVudikgewogICAgICAgIGlmIChjb2RlLmlzQWxpdmUoKSkgewogICAgICAgICAgICBjb2RlLnN0YXRCZWdpbih0cmVlLnBvcyk7CiAgICAgICAgICAgIGdlbkRlZih0cmVlLCBlbnYpOwogICAgICAgIH0gZWxzZSBpZiAoZW52LmluZm8uaXNTd2l0Y2ggJiYgdHJlZS5oYXNUYWcoVkFSREVGKSkgewogICAgICAgICAgICAvLyB2YXJpYWJsZXMgd2hvc2UgZGVjbGFyYXRpb25zIGFyZSBpbiBhIHN3aXRjaAogICAgICAgICAgICAvLyBjYW4gYmUgdXNlZCBldmVuIGlmIHRoZSBkZWNsIGlzIHVucmVhY2hhYmxlLgogICAgICAgICAgICBjb2RlLm5ld0xvY2FsKCgoSkNWYXJpYWJsZURlY2wpIHRyZWUpLnN5bSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKiBEZXJpdmVkIHZpc2l0b3IgbWV0aG9kOiBjaGVjayB3aGV0aGVyIENoYXJhY3RlclJhbmdlVGFibGUKICAgICAqICBzaG91bGQgYmUgZW1pdHRlZCwgaWYgc28sIHB1dCBhIG5ldyBlbnRyeSBpbnRvIENSVGFibGUKICAgICAqICBhbmQgY2FsbCBtZXRob2QgdG8gZ2VuZXJhdGUgYnl0ZWNvZGUuCiAgICAgKiAgSWYgbm90LCBqdXN0IGNhbGwgbWV0aG9kIHRvIGdlbmVyYXRlIGJ5dGVjb2RlLgogICAgICogIEBzZWUgICAgI2dlblN0YXRzKExpc3QsIEVudikKICAgICAqCiAgICAgKiAgQHBhcmFtICB0cmVlcyAgICBUaGUgbGlzdCBvZiB0cmVlcyB0byBiZSB2aXNpdGVkLgogICAgICogIEBwYXJhbSAgZW52ICAgICAgVGhlIGVudmlyb25tZW50IHRvIHVzZS4KICAgICAqICBAcGFyYW0gIGNydEZsYWdzIFRoZSBDaGFyYWN0ZXJSYW5nZVRhYmxlIGZsYWdzCiAgICAgKiAgICAgICAgICAgICAgICAgICBpbmRpY2F0aW5nIHR5cGUgb2YgdGhlIGVudHJ5LgogICAgICovCiAgICBwdWJsaWMgdm9pZCBnZW5TdGF0cyhMaXN0PEpDU3RhdGVtZW50PiB0cmVlcywgRW52PEdlbkNvbnRleHQ+IGVudiwgaW50IGNydEZsYWdzKSB7CiAgICAgICAgaWYgKCFnZW5DcnQpIHsKICAgICAgICAgICAgZ2VuU3RhdHModHJlZXMsIGVudik7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgaWYgKHRyZWVzLmxlbmd0aCgpID09IDEpIHsgICAgICAgIC8vIG1hcmsgb25lIHN0YXRlbWVudCB3aXRoIHRoZSBmbGFncwogICAgICAgICAgICBnZW5TdGF0KHRyZWVzLmhlYWQsIGVudiwgY3J0RmxhZ3MgfCBDUlRfU1RBVEVNRU5UKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBpbnQgc3RhcnRwYyA9IGNvZGUuY3VyQ1AoKTsKICAgICAgICAgICAgZ2VuU3RhdHModHJlZXMsIGVudik7CiAgICAgICAgICAgIGNvZGUuY3J0LnB1dCh0cmVlcywgY3J0RmxhZ3MsIHN0YXJ0cGMsIGNvZGUuY3VyQ1AoKSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKiBEZXJpdmVkIHZpc2l0b3IgbWV0aG9kOiBnZW5lcmF0ZSBjb2RlIGZvciBhIGxpc3Qgb2Ygc3RhdGVtZW50cy4KICAgICAqLwogICAgcHVibGljIHZvaWQgZ2VuU3RhdHMoTGlzdDw/IGV4dGVuZHMgSkNUcmVlPiB0cmVlcywgRW52PEdlbkNvbnRleHQ+IGVudikgewogICAgICAgIGZvciAoTGlzdDw/IGV4dGVuZHMgSkNUcmVlPiBsID0gdHJlZXM7IGwubm9uRW1wdHkoKTsgbCA9IGwudGFpbCkKICAgICAgICAgICAgZ2VuU3RhdChsLmhlYWQsIGVudiwgQ1JUX1NUQVRFTUVOVCk7CiAgICB9CgogICAgLyoqIERlcml2ZWQgdmlzaXRvciBtZXRob2Q6IGNoZWNrIHdoZXRoZXIgQ2hhcmFjdGVyUmFuZ2VUYWJsZQogICAgICogIHNob3VsZCBiZSBlbWl0dGVkLCBpZiBzbywgcHV0IGEgbmV3IGVudHJ5IGludG8gQ1JUYWJsZQogICAgICogIGFuZCBjYWxsIG1ldGhvZCB0byBnZW5lcmF0ZSBieXRlY29kZS4KICAgICAqICBJZiBub3QsIGp1c3QgY2FsbCBtZXRob2QgdG8gZ2VuZXJhdGUgYnl0ZWNvZGUuCiAgICAgKiAgQHNlZSAgICAjZ2VuQ29uZChKQ1RyZWUsYm9vbGVhbikKICAgICAqCiAgICAgKiAgQHBhcmFtICB0cmVlICAgICBUaGUgdHJlZSB0byBiZSB2aXNpdGVkLgogICAgICogIEBwYXJhbSAgY3J0RmxhZ3MgVGhlIENoYXJhY3RlclJhbmdlVGFibGUgZmxhZ3MKICAgICAqICAgICAgICAgICAgICAgICAgIGluZGljYXRpbmcgdHlwZSBvZiB0aGUgZW50cnkuCiAgICAgKi8KICAgIHB1YmxpYyBDb25kSXRlbSBnZW5Db25kKEpDVHJlZSB0cmVlLCBpbnQgY3J0RmxhZ3MpIHsKICAgICAgICBpZiAoIWdlbkNydCkgcmV0dXJuIGdlbkNvbmQodHJlZSwgZmFsc2UpOwogICAgICAgIGludCBzdGFydHBjID0gY29kZS5jdXJDUCgpOwogICAgICAgIENvbmRJdGVtIGl0ZW0gPSBnZW5Db25kKHRyZWUsIChjcnRGbGFncyAmIENSVF9GTE9XX0NPTlRST0xMRVIpICE9IDApOwogICAgICAgIGNvZGUuY3J0LnB1dCh0cmVlLCBjcnRGbGFncywgc3RhcnRwYywgY29kZS5jdXJDUCgpKTsKICAgICAgICByZXR1cm4gaXRlbTsKICAgIH0KCiAgICAvKiogRGVyaXZlZCB2aXNpdG9yIG1ldGhvZDogZ2VuZXJhdGUgY29kZSBmb3IgYSBib29sZWFuCiAgICAgKiAgZXhwcmVzc2lvbiBpbiBhIGNvbnRyb2wtZmxvdyBjb250ZXh0LgogICAgICogIEBwYXJhbSBfdHJlZSAgICAgICAgIFRoZSBleHByZXNzaW9uIHRvIGJlIHZpc2l0ZWQuCiAgICAgKiAgQHBhcmFtIG1hcmtCcmFuY2hlcyBUaGUgZmxhZyB0byBpbmRpY2F0ZSB0aGF0IHRoZSBjb25kaXRpb24gaXMKICAgICAqICAgICAgICAgICAgICAgICAgICAgIGEgZmxvdyBjb250cm9sbGVyIHNvIHByb2R1Y2VkIGNvbmRpdGlvbnMKICAgICAqICAgICAgICAgICAgICAgICAgICAgIHNob3VsZCBjb250YWluIGEgcHJvcGVyIHRyZWUgdG8gZ2VuZXJhdGUKICAgICAqICAgICAgICAgICAgICAgICAgICAgIENoYXJhY3RlclJhbmdlVGFibGUgYnJhbmNoZXMgZm9yIHRoZW0uCiAgICAgKi8KICAgIHB1YmxpYyBDb25kSXRlbSBnZW5Db25kKEpDVHJlZSBfdHJlZSwgYm9vbGVhbiBtYXJrQnJhbmNoZXMpIHsKICAgICAgICBKQ1RyZWUgaW5uZXJfdHJlZSA9IFRyZWVJbmZvLnNraXBQYXJlbnMoX3RyZWUpOwogICAgICAgIGlmIChpbm5lcl90cmVlLmhhc1RhZyhDT05ERVhQUikpIHsKICAgICAgICAgICAgSkNDb25kaXRpb25hbCB0cmVlID0gKEpDQ29uZGl0aW9uYWwpaW5uZXJfdHJlZTsKICAgICAgICAgICAgQ29uZEl0ZW0gY29uZCA9IGdlbkNvbmQodHJlZS5jb25kLCBDUlRfRkxPV19DT05UUk9MTEVSKTsKICAgICAgICAgICAgaWYgKGNvbmQuaXNUcnVlKCkpIHsKICAgICAgICAgICAgICAgIGNvZGUucmVzb2x2ZShjb25kLnRydWVKdW1wcyk7CiAgICAgICAgICAgICAgICBDb25kSXRlbSByZXN1bHQgPSBnZW5Db25kKHRyZWUudHJ1ZXBhcnQsIENSVF9GTE9XX1RBUkdFVCk7CiAgICAgICAgICAgICAgICBpZiAobWFya0JyYW5jaGVzKSByZXN1bHQudHJlZSA9IHRyZWUudHJ1ZXBhcnQ7CiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChjb25kLmlzRmFsc2UoKSkgewogICAgICAgICAgICAgICAgY29kZS5yZXNvbHZlKGNvbmQuZmFsc2VKdW1wcyk7CiAgICAgICAgICAgICAgICBDb25kSXRlbSByZXN1bHQgPSBnZW5Db25kKHRyZWUuZmFsc2VwYXJ0LCBDUlRfRkxPV19UQVJHRVQpOwogICAgICAgICAgICAgICAgaWYgKG1hcmtCcmFuY2hlcykgcmVzdWx0LnRyZWUgPSB0cmVlLmZhbHNlcGFydDsKICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgQ2hhaW4gc2Vjb25kSnVtcHMgPSBjb25kLmp1bXBGYWxzZSgpOwogICAgICAgICAgICBjb2RlLnJlc29sdmUoY29uZC50cnVlSnVtcHMpOwogICAgICAgICAgICBDb25kSXRlbSBmaXJzdCA9IGdlbkNvbmQodHJlZS50cnVlcGFydCwgQ1JUX0ZMT1dfVEFSR0VUKTsKICAgICAgICAgICAgaWYgKG1hcmtCcmFuY2hlcykgZmlyc3QudHJlZSA9IHRyZWUudHJ1ZXBhcnQ7CiAgICAgICAgICAgIENoYWluIGZhbHNlSnVtcHMgPSBmaXJzdC5qdW1wRmFsc2UoKTsKICAgICAgICAgICAgY29kZS5yZXNvbHZlKGZpcnN0LnRydWVKdW1wcyk7CiAgICAgICAgICAgIENoYWluIHRydWVKdW1wcyA9IGNvZGUuYnJhbmNoKGdvdG9fKTsKICAgICAgICAgICAgY29kZS5yZXNvbHZlKHNlY29uZEp1bXBzKTsKICAgICAgICAgICAgQ29uZEl0ZW0gc2Vjb25kID0gZ2VuQ29uZCh0cmVlLmZhbHNlcGFydCwgQ1JUX0ZMT1dfVEFSR0VUKTsKICAgICAgICAgICAgQ29uZEl0ZW0gcmVzdWx0ID0gaXRlbXMubWFrZUNvbmRJdGVtKHNlY29uZC5vcGNvZGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29kZS5tZXJnZUNoYWlucyh0cnVlSnVtcHMsIHNlY29uZC50cnVlSnVtcHMpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvZGUubWVyZ2VDaGFpbnMoZmFsc2VKdW1wcywgc2Vjb25kLmZhbHNlSnVtcHMpKTsKICAgICAgICAgICAgaWYgKG1hcmtCcmFuY2hlcykgcmVzdWx0LnRyZWUgPSB0cmVlLmZhbHNlcGFydDsKICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBDb25kSXRlbSByZXN1bHQgPSBnZW5FeHByKF90cmVlLCBzeW1zLmJvb2xlYW5UeXBlKS5ta0NvbmQoKTsKICAgICAgICAgICAgaWYgKG1hcmtCcmFuY2hlcykgcmVzdWx0LnRyZWUgPSBfdHJlZTsKICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIENvZGUgZ2V0Q29kZSgpIHsKICAgICAgICByZXR1cm4gY29kZTsKICAgIH0KCiAgICBwdWJsaWMgSXRlbXMgZ2V0SXRlbXMoKSB7CiAgICAgICAgcmV0dXJuIGl0ZW1zOwogICAgfQoKICAgIHB1YmxpYyBFbnY8QXR0ckNvbnRleHQ+IGdldEF0dHJFbnYoKSB7CiAgICAgICAgcmV0dXJuIGF0dHJFbnY7CiAgICB9CgogICAgLyoqIFZpc2l0b3IgY2xhc3MgZm9yIGV4cHJlc3Npb25zIHdoaWNoIG1pZ2h0IGJlIGNvbnN0YW50IGV4cHJlc3Npb25zLgogICAgICogIFRoaXMgY2xhc3MgaXMgYSBzdWJzZXQgb2YgVHJlZVNjYW5uZXIuIEludGVuZGVkIHRvIHZpc2l0IHRyZWVzIHBydW5lZCBieQogICAgICogIExvd2VyIGFzIGxvbmcgYXMgY29uc3RhbnQgZXhwcmVzc2lvbnMgbG9va2luZyBmb3IgcmVmZXJlbmNlcyB0byBhbnkKICAgICAqICBDbGFzc1N5bWJvbC4gQW55IHN1Y2ggcmVmZXJlbmNlIHdpbGwgYmUgYWRkZWQgdG8gdGhlIGNvbnN0YW50IHBvb2wgc28KICAgICAqICBhdXRvbWF0ZWQgdG9vbHMgY2FuIGRldGVjdCBjbGFzcyBkZXBlbmRlbmNpZXMgYmV0dGVyLgogICAgICovCiAgICBjbGFzcyBDbGFzc1JlZmVyZW5jZVZpc2l0b3IgZXh0ZW5kcyBKQ1RyZWUuVmlzaXRvciB7CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0VHJlZShKQ1RyZWUgdHJlZSkge30KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRCaW5hcnkoSkNCaW5hcnkgdHJlZSkgewogICAgICAgICAgICB0cmVlLmxocy5hY2NlcHQodGhpcyk7CiAgICAgICAgICAgIHRyZWUucmhzLmFjY2VwdCh0aGlzKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0U2VsZWN0KEpDRmllbGRBY2Nlc3MgdHJlZSkgewogICAgICAgICAgICBpZiAodHJlZS5zZWxlY3RlZC50eXBlLmhhc1RhZyhDTEFTUykpIHsKICAgICAgICAgICAgICAgIG1ha2VSZWYodHJlZS5zZWxlY3RlZC5wb3MoKSwgdHJlZS5zZWxlY3RlZC50eXBlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRJZGVudChKQ0lkZW50IHRyZWUpIHsKICAgICAgICAgICAgaWYgKHRyZWUuc3ltLm93bmVyIGluc3RhbmNlb2YgQ2xhc3NTeW1ib2wpIHsKICAgICAgICAgICAgICAgIHBvb2wucHV0KHRyZWUuc3ltLm93bmVyKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRDb25kaXRpb25hbChKQ0NvbmRpdGlvbmFsIHRyZWUpIHsKICAgICAgICAgICAgdHJlZS5jb25kLmFjY2VwdCh0aGlzKTsKICAgICAgICAgICAgdHJlZS50cnVlcGFydC5hY2NlcHQodGhpcyk7CiAgICAgICAgICAgIHRyZWUuZmFsc2VwYXJ0LmFjY2VwdCh0aGlzKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0VW5hcnkoSkNVbmFyeSB0cmVlKSB7CiAgICAgICAgICAgIHRyZWUuYXJnLmFjY2VwdCh0aGlzKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0UGFyZW5zKEpDUGFyZW5zIHRyZWUpIHsKICAgICAgICAgICAgdHJlZS5leHByLmFjY2VwdCh0aGlzKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0VHlwZUNhc3QoSkNUeXBlQ2FzdCB0cmVlKSB7CiAgICAgICAgICAgIHRyZWUuZXhwci5hY2NlcHQodGhpcyk7CiAgICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgQ2xhc3NSZWZlcmVuY2VWaXNpdG9yIGNsYXNzUmVmZXJlbmNlVmlzaXRvciA9IG5ldyBDbGFzc1JlZmVyZW5jZVZpc2l0b3IoKTsKCiAgICAvKiogVmlzaXRvciBtZXRob2Q6IGdlbmVyYXRlIGNvZGUgZm9yIGFuIGV4cHJlc3Npb24sIGNhdGNoaW5nIGFuZCByZXBvcnRpbmcKICAgICAqICBhbnkgY29tcGxldGlvbiBmYWlsdXJlcy4KICAgICAqICBAcGFyYW0gdHJlZSAgICBUaGUgZXhwcmVzc2lvbiB0byBiZSB2aXNpdGVkLgogICAgICogIEBwYXJhbSBwdCAgICAgIFRoZSBleHByZXNzaW9uJ3MgZXhwZWN0ZWQgdHlwZSAocHJvdG8tdHlwZSkuCiAgICAgKi8KICAgIHB1YmxpYyBJdGVtIGdlbkV4cHIoSkNUcmVlIHRyZWUsIFR5cGUgcHQpIHsKICAgICAgICBUeXBlIHByZXZQdCA9IHRoaXMucHQ7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgaWYgKHRyZWUudHlwZS5jb25zdFZhbHVlKCkgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgLy8gU2hvcnQgY2lyY3VpdCBhbnkgZXhwcmVzc2lvbnMgd2hpY2ggYXJlIGNvbnN0YW50cwogICAgICAgICAgICAgICAgdHJlZS5hY2NlcHQoY2xhc3NSZWZlcmVuY2VWaXNpdG9yKTsKICAgICAgICAgICAgICAgIGNoZWNrU3RyaW5nQ29uc3RhbnQodHJlZS5wb3MoKSwgdHJlZS50eXBlLmNvbnN0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICByZXN1bHQgPSBpdGVtcy5tYWtlSW1tZWRpYXRlSXRlbSh0cmVlLnR5cGUsIHRyZWUudHlwZS5jb25zdFZhbHVlKCkpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdGhpcy5wdCA9IHB0OwogICAgICAgICAgICAgICAgdHJlZS5hY2NlcHQodGhpcyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHJlc3VsdC5jb2VyY2UocHQpOwogICAgICAgIH0gY2F0Y2ggKENvbXBsZXRpb25GYWlsdXJlIGV4KSB7CiAgICAgICAgICAgIGNoay5jb21wbGV0aW9uRXJyb3IodHJlZS5wb3MoKSwgZXgpOwogICAgICAgICAgICBjb2RlLnN0YXRlLnN0YWNrc2l6ZSA9IDE7CiAgICAgICAgICAgIHJldHVybiBpdGVtcy5tYWtlU3RhY2tJdGVtKHB0KTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICB0aGlzLnB0ID0gcHJldlB0OwogICAgICAgIH0KICAgIH0KCiAgICAvKiogRGVyaXZlZCB2aXNpdG9yIG1ldGhvZDogZ2VuZXJhdGUgY29kZSBmb3IgYSBsaXN0IG9mIG1ldGhvZCBhcmd1bWVudHMuCiAgICAgKiAgQHBhcmFtIHRyZWVzICAgIFRoZSBhcmd1bWVudCBleHByZXNzaW9ucyB0byBiZSB2aXNpdGVkLgogICAgICogIEBwYXJhbSBwdHMgICAgICBUaGUgZXhwcmVzc2lvbidzIGV4cGVjdGVkIHR5cGVzIChpLmUuIHRoZSBmb3JtYWwgcGFyYW1ldGVyCiAgICAgKiAgICAgICAgICAgICAgICAgIHR5cGVzIG9mIHRoZSBpbnZva2VkIG1ldGhvZCkuCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIGdlbkFyZ3MoTGlzdDxKQ0V4cHJlc3Npb24+IHRyZWVzLCBMaXN0PFR5cGU+IHB0cykgewogICAgICAgIGZvciAoTGlzdDxKQ0V4cHJlc3Npb24+IGwgPSB0cmVlczsgbC5ub25FbXB0eSgpOyBsID0gbC50YWlsKSB7CiAgICAgICAgICAgIGdlbkV4cHIobC5oZWFkLCBwdHMuaGVhZCkubG9hZCgpOwogICAgICAgICAgICBwdHMgPSBwdHMudGFpbDsKICAgICAgICB9CiAgICAgICAgLy8gcmVxdWlyZSBsaXN0cyBiZSBvZiBzYW1lIGxlbmd0aAogICAgICAgIEFzc2VydC5jaGVjayhwdHMuaXNFbXB0eSgpKTsKICAgIH0KCi8qICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBWaXNpdG9yIG1ldGhvZHMgZm9yIHN0YXRlbWVudHMgYW5kIGRlZmluaXRpb25zCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKICAgIC8qKiBUaHJvd24gd2hlbiB0aGUgYnl0ZSBjb2RlIHNpemUgZXhjZWVkcyBsaW1pdC4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBjbGFzcyBDb2RlU2l6ZU92ZXJmbG93IGV4dGVuZHMgUnVudGltZUV4Y2VwdGlvbiB7CiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMDsKICAgICAgICBwdWJsaWMgQ29kZVNpemVPdmVyZmxvdygpIHt9CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRNZXRob2REZWYoSkNNZXRob2REZWNsIHRyZWUpIHsKICAgICAgICAvLyBDcmVhdGUgYSBuZXcgbG9jYWwgZW52aXJvbm1lbnQgdGhhdCBwb2ludHMgcGFjayBhdCBtZXRob2QKICAgICAgICAvLyBkZWZpbml0aW9uLgogICAgICAgIEVudjxHZW5Db250ZXh0PiBsb2NhbEVudiA9IGVudi5kdXAodHJlZSk7CiAgICAgICAgbG9jYWxFbnYuZW5jbE1ldGhvZCA9IHRyZWU7CiAgICAgICAgLy8gVGhlIGV4cGVjdGVkIHR5cGUgb2YgZXZlcnkgcmV0dXJuIHN0YXRlbWVudCBpbiB0aGlzIG1ldGhvZAogICAgICAgIC8vIGlzIHRoZSBtZXRob2QncyByZXR1cm4gdHlwZS4KICAgICAgICB0aGlzLnB0ID0gdHJlZS5zeW0uZXJhc3VyZSh0eXBlcykuZ2V0UmV0dXJuVHlwZSgpOwoKICAgICAgICBjaGVja0RpbWVuc2lvbih0cmVlLnBvcygpLCB0cmVlLnN5bS5lcmFzdXJlKHR5cGVzKSk7CiAgICAgICAgZ2VuTWV0aG9kKHRyZWUsIGxvY2FsRW52LCBmYWxzZSk7CiAgICB9Ci8vd2hlcmUKICAgICAgICAvKiogR2VuZXJhdGUgY29kZSBmb3IgYSBtZXRob2QuCiAgICAgICAgICogIEBwYXJhbSB0cmVlICAgICBUaGUgdHJlZSByZXByZXNlbnRpbmcgdGhlIG1ldGhvZCBkZWZpbml0aW9uLgogICAgICAgICAqICBAcGFyYW0gZW52ICAgICAgVGhlIGVudmlyb25tZW50IGN1cnJlbnQgZm9yIHRoZSBtZXRob2QgYm9keS4KICAgICAgICAgKiAgQHBhcmFtIGZhdGNvZGUgIEEgZmxhZyB0aGF0IGluZGljYXRlcyB3aGV0aGVyIGFsbCBqdW1wcyBhcmUKICAgICAgICAgKiAgICAgICAgICAgICAgICAgIHdpdGhpbiAzMksuICBXZSBmaXJzdCBpbnZva2UgdGhpcyBtZXRob2QgdW5kZXIKICAgICAgICAgKiAgICAgICAgICAgICAgICAgIHRoZSBhc3N1bXB0aW9uIHRoYXQgZmF0Y29kZSA9PSBmYWxzZSwgaS5lLiBhbGwKICAgICAgICAgKiAgICAgICAgICAgICAgICAgIGp1bXBzIGFyZSB3aXRoaW4gMzJLLiAgSWYgdGhpcyBmYWlscywgZmF0Y29kZQogICAgICAgICAqICAgICAgICAgICAgICAgICAgaXMgc2V0IHRvIHRydWUgYW5kIHdlIHRyeSBhZ2Fpbi4KICAgICAgICAgKi8KICAgICAgICB2b2lkIGdlbk1ldGhvZChKQ01ldGhvZERlY2wgdHJlZSwgRW52PEdlbkNvbnRleHQ+IGVudiwgYm9vbGVhbiBmYXRjb2RlKSB7CiAgICAgICAgICAgIE1ldGhvZFN5bWJvbCBtZXRoID0gdHJlZS5zeW07CiAgICAgICAgICAgIGludCBleHRyYXMgPSAwOwogICAgICAgICAgICAvLyBDb3VudCB1cCBleHRyYSBwYXJhbWV0ZXJzCiAgICAgICAgICAgIGlmIChtZXRoLmlzQ29uc3RydWN0b3IoKSkgewogICAgICAgICAgICAgICAgZXh0cmFzKys7CiAgICAgICAgICAgICAgICBpZiAobWV0aC5lbmNsQ2xhc3MoKS5pc0lubmVyKCkgJiYKICAgICAgICAgICAgICAgICAgICAhbWV0aC5lbmNsQ2xhc3MoKS5pc1N0YXRpYygpKSB7CiAgICAgICAgICAgICAgICAgICAgZXh0cmFzKys7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSBpZiAoKHRyZWUubW9kcy5mbGFncyAmIFNUQVRJQykgPT0gMCkgewogICAgICAgICAgICAgICAgZXh0cmFzKys7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gICAgICBTeXN0ZW0uZXJyLnByaW50bG4oIkdlbmVyYXRpbmcgIiArIG1ldGggKyAiIGluICIgKyBtZXRoLm93bmVyKTsgLy9ERUJVRwogICAgICAgICAgICBpZiAoQ29kZS53aWR0aCh0eXBlcy5lcmFzdXJlKGVudi5lbmNsTWV0aG9kLnN5bS50eXBlKS5nZXRQYXJhbWV0ZXJUeXBlcygpKSArIGV4dHJhcyA+CiAgICAgICAgICAgICAgICBDbGFzc0ZpbGUuTUFYX1BBUkFNRVRFUlMpIHsKICAgICAgICAgICAgICAgIGxvZy5lcnJvcih0cmVlLnBvcygpLCAibGltaXQucGFyYW1ldGVycyIpOwogICAgICAgICAgICAgICAgbmVycnMrKzsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZWxzZSBpZiAodHJlZS5ib2R5ICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIC8vIENyZWF0ZSBhIG5ldyBjb2RlIHN0cnVjdHVyZSBhbmQgaW5pdGlhbGl6ZSBpdC4KICAgICAgICAgICAgICAgIGludCBzdGFydHBjQ3J0ID0gaW5pdENvZGUodHJlZSwgZW52LCBmYXRjb2RlKTsKCiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIGdlblN0YXQodHJlZS5ib2R5LCBlbnYpOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoQ29kZVNpemVPdmVyZmxvdyBlKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gRmFpbGVkIGR1ZSB0byBjb2RlIGxpbWl0LCB0cnkgYWdhaW4gd2l0aCBqc3IvcmV0CiAgICAgICAgICAgICAgICAgICAgc3RhcnRwY0NydCA9IGluaXRDb2RlKHRyZWUsIGVudiwgZmF0Y29kZSk7CiAgICAgICAgICAgICAgICAgICAgZ2VuU3RhdCh0cmVlLmJvZHksIGVudik7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKGNvZGUuc3RhdGUuc3RhY2tzaXplICE9IDApIHsKICAgICAgICAgICAgICAgICAgICBsb2cuZXJyb3IodHJlZS5ib2R5LnBvcygpLCAic3RhY2suc2ltLmVycm9yIiwgdHJlZSk7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gSWYgbGFzdCBzdGF0ZW1lbnQgY291bGQgY29tcGxldGUgbm9ybWFsbHksIGluc2VydCBhCiAgICAgICAgICAgICAgICAvLyByZXR1cm4gYXQgdGhlIGVuZC4KICAgICAgICAgICAgICAgIGlmIChjb2RlLmlzQWxpdmUoKSkgewogICAgICAgICAgICAgICAgICAgIGNvZGUuc3RhdEJlZ2luKFRyZWVJbmZvLmVuZFBvcyh0cmVlLmJvZHkpKTsKICAgICAgICAgICAgICAgICAgICBpZiAoZW52LmVuY2xNZXRob2QgPT0gbnVsbCB8fAogICAgICAgICAgICAgICAgICAgICAgICBlbnYuZW5jbE1ldGhvZC5zeW0udHlwZS5nZXRSZXR1cm5UeXBlKCkuaGFzVGFnKFZPSUQpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvZGUuZW1pdG9wMChyZXR1cm5fKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBzb21ldGltZSBkZWFkIGNvZGUgc2VlbXMgYWxpdmUgKDQ0MTU5OTEpOwogICAgICAgICAgICAgICAgICAgICAgICAvLyBnZW5lcmF0ZSBhIHNtYWxsIGxvb3AgaW5zdGVhZAogICAgICAgICAgICAgICAgICAgICAgICBpbnQgc3RhcnRwYyA9IGNvZGUuZW50cnlQb2ludCgpOwogICAgICAgICAgICAgICAgICAgICAgICBDb25kSXRlbSBjID0gaXRlbXMubWFrZUNvbmRJdGVtKGdvdG9fKTsKICAgICAgICAgICAgICAgICAgICAgICAgY29kZS5yZXNvbHZlKGMuanVtcFRydWUoKSwgc3RhcnRwYyk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKGdlbkNydCkKICAgICAgICAgICAgICAgICAgICBjb2RlLmNydC5wdXQodHJlZS5ib2R5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDUlRfQkxPQ0ssCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0cGNDcnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvZGUuY3VyQ1AoKSk7CgogICAgICAgICAgICAgICAgY29kZS5lbmRTY29wZXMoMCk7CgogICAgICAgICAgICAgICAgLy8gSWYgd2UgZXhjZWVkZWQgbGltaXRzLCBwYW5pYwogICAgICAgICAgICAgICAgaWYgKGNvZGUuY2hlY2tMaW1pdHModHJlZS5wb3MoKSwgbG9nKSkgewogICAgICAgICAgICAgICAgICAgIG5lcnJzKys7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIElmIHdlIGdlbmVyYXRlZCBzaG9ydCBjb2RlIGJ1dCBnb3QgYSBsb25nIGp1bXAsIGRvIGl0IGFnYWluCiAgICAgICAgICAgICAgICAvLyB3aXRoIGZhdENvZGUgPSB0cnVlLgogICAgICAgICAgICAgICAgaWYgKCFmYXRjb2RlICYmIGNvZGUuZmF0Y29kZSkgZ2VuTWV0aG9kKHRyZWUsIGVudiwgdHJ1ZSk7CgogICAgICAgICAgICAgICAgLy8gQ2xlYW4gdXAKICAgICAgICAgICAgICAgIGlmKHN0YWNrTWFwID09IFN0YWNrTWFwRm9ybWF0LkpTUjIwMikgewogICAgICAgICAgICAgICAgICAgIGNvZGUubGFzdEZyYW1lID0gbnVsbDsKICAgICAgICAgICAgICAgICAgICBjb2RlLmZyYW1lQmVmb3JlTGFzdCA9IG51bGw7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gQ29tcHJlc3MgZXhjZXB0aW9uIHRhYmxlCiAgICAgICAgICAgICAgICBjb2RlLmNvbXByZXNzQ2F0Y2hUYWJsZSgpOwoKICAgICAgICAgICAgICAgIC8vIEZpbGwgaW4gdHlwZSBhbm5vdGF0aW9uIHBvc2l0aW9ucyBmb3IgZXhjZXB0aW9uIHBhcmFtZXRlcnMKICAgICAgICAgICAgICAgIGNvZGUuZmlsbEV4Y2VwdGlvblBhcmFtZXRlclBvc2l0aW9ucygpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIGludCBpbml0Q29kZShKQ01ldGhvZERlY2wgdHJlZSwgRW52PEdlbkNvbnRleHQ+IGVudiwgYm9vbGVhbiBmYXRjb2RlKSB7CiAgICAgICAgICAgIE1ldGhvZFN5bWJvbCBtZXRoID0gdHJlZS5zeW07CgogICAgICAgICAgICAvLyBDcmVhdGUgYSBuZXcgY29kZSBzdHJ1Y3R1cmUuCiAgICAgICAgICAgIG1ldGguY29kZSA9IGNvZGUgPSBuZXcgQ29kZShtZXRoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmF0Y29kZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpbmVEZWJ1Z0luZm8gPyB0b3BsZXZlbC5saW5lTWFwIDogbnVsbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhckRlYnVnSW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YWNrTWFwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVidWdDb2RlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2VuQ3J0ID8gbmV3IENSVGFibGUodHJlZSwgZW52LnRvcGxldmVsLmVuZFBvc2l0aW9ucykKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IG51bGwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeW1zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb29sKTsKICAgICAgICAgICAgaXRlbXMgPSBuZXcgSXRlbXMocG9vbCwgY29kZSwgc3ltcywgdHlwZXMpOwogICAgICAgICAgICBpZiAoY29kZS5kZWJ1Z0NvZGUpIHsKICAgICAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbihtZXRoICsgIiBmb3IgYm9keSAiICsgdHJlZSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIElmIG1ldGhvZCBpcyBub3Qgc3RhdGljLCBjcmVhdGUgYSBuZXcgbG9jYWwgdmFyaWFibGUgYWRkcmVzcwogICAgICAgICAgICAvLyBmb3IgYHRoaXMnLgogICAgICAgICAgICBpZiAoKHRyZWUubW9kcy5mbGFncyAmIFNUQVRJQykgPT0gMCkgewogICAgICAgICAgICAgICAgVHlwZSBzZWxmVHlwZSA9IG1ldGgub3duZXIudHlwZTsKICAgICAgICAgICAgICAgIGlmIChtZXRoLmlzQ29uc3RydWN0b3IoKSAmJiBzZWxmVHlwZSAhPSBzeW1zLm9iamVjdFR5cGUpCiAgICAgICAgICAgICAgICAgICAgc2VsZlR5cGUgPSBVbmluaXRpYWxpemVkVHlwZS51bmluaXRpYWxpemVkVGhpcyhzZWxmVHlwZSk7CiAgICAgICAgICAgICAgICBjb2RlLnNldERlZmluZWQoCiAgICAgICAgICAgICAgICAgICAgICAgIGNvZGUubmV3TG9jYWwoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgVmFyU3ltYm9sKEZJTkFMLCBuYW1lcy5fdGhpcywgc2VsZlR5cGUsIG1ldGgub3duZXIpKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIE1hcmsgYWxsIHBhcmFtZXRlcnMgYXMgZGVmaW5lZCBmcm9tIHRoZSBiZWdpbm5pbmcgb2YKICAgICAgICAgICAgLy8gdGhlIG1ldGhvZC4KICAgICAgICAgICAgZm9yIChMaXN0PEpDVmFyaWFibGVEZWNsPiBsID0gdHJlZS5wYXJhbXM7IGwubm9uRW1wdHkoKTsgbCA9IGwudGFpbCkgewogICAgICAgICAgICAgICAgY2hlY2tEaW1lbnNpb24obC5oZWFkLnBvcygpLCBsLmhlYWQuc3ltLnR5cGUpOwogICAgICAgICAgICAgICAgY29kZS5zZXREZWZpbmVkKGNvZGUubmV3TG9jYWwobC5oZWFkLnN5bSkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBHZXQgcmVhZHkgdG8gZ2VuZXJhdGUgY29kZSBmb3IgbWV0aG9kIGJvZHkuCiAgICAgICAgICAgIGludCBzdGFydHBjQ3J0ID0gZ2VuQ3J0ID8gY29kZS5jdXJDUCgpIDogMDsKICAgICAgICAgICAgY29kZS5lbnRyeVBvaW50KCk7CgogICAgICAgICAgICAvLyBTdXBwcmVzcyBpbml0aWFsIHN0YWNrbWFwCiAgICAgICAgICAgIGNvZGUucGVuZGluZ1N0YWNrTWFwID0gZmFsc2U7CgogICAgICAgICAgICByZXR1cm4gc3RhcnRwY0NydDsKICAgICAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRWYXJEZWYoSkNWYXJpYWJsZURlY2wgdHJlZSkgewogICAgICAgIFZhclN5bWJvbCB2ID0gdHJlZS5zeW07CiAgICAgICAgY29kZS5uZXdMb2NhbCh2KTsKICAgICAgICBpZiAodHJlZS5pbml0ICE9IG51bGwpIHsKICAgICAgICAgICAgY2hlY2tTdHJpbmdDb25zdGFudCh0cmVlLmluaXQucG9zKCksIHYuZ2V0Q29uc3RWYWx1ZSgpKTsKICAgICAgICAgICAgaWYgKHYuZ2V0Q29uc3RWYWx1ZSgpID09IG51bGwgfHwgdmFyRGVidWdJbmZvKSB7CiAgICAgICAgICAgICAgICBBc3NlcnQuY2hlY2sobGV0RXhwckRlcHRoICE9IDAgfHwgY29kZS5zdGF0ZS5zdGFja3NpemUgPT0gMCk7CiAgICAgICAgICAgICAgICBnZW5FeHByKHRyZWUuaW5pdCwgdi5lcmFzdXJlKHR5cGVzKSkubG9hZCgpOwogICAgICAgICAgICAgICAgaXRlbXMubWFrZUxvY2FsSXRlbSh2KS5zdG9yZSgpOwogICAgICAgICAgICAgICAgQXNzZXJ0LmNoZWNrKGxldEV4cHJEZXB0aCAhPSAwIHx8IGNvZGUuc3RhdGUuc3RhY2tzaXplID09IDApOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGNoZWNrRGltZW5zaW9uKHRyZWUucG9zKCksIHYudHlwZSk7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRTa2lwKEpDU2tpcCB0cmVlKSB7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRCbG9jayhKQ0Jsb2NrIHRyZWUpIHsKICAgICAgICBpbnQgbGltaXQgPSBjb2RlLm5leHRyZWc7CiAgICAgICAgRW52PEdlbkNvbnRleHQ+IGxvY2FsRW52ID0gZW52LmR1cCh0cmVlLCBuZXcgR2VuQ29udGV4dCgpKTsKICAgICAgICBnZW5TdGF0cyh0cmVlLnN0YXRzLCBsb2NhbEVudik7CiAgICAgICAgLy8gRW5kIHRoZSBzY29wZSBvZiBhbGwgYmxvY2stbG9jYWwgdmFyaWFibGVzIGluIHZhcmlhYmxlIGluZm8uCiAgICAgICAgaWYgKCFlbnYudHJlZS5oYXNUYWcoTUVUSE9EREVGKSkgewogICAgICAgICAgICBjb2RlLnN0YXRCZWdpbih0cmVlLmVuZHBvcyk7CiAgICAgICAgICAgIGNvZGUuZW5kU2NvcGVzKGxpbWl0KTsKICAgICAgICAgICAgY29kZS5wZW5kaW5nU3RhdFBvcyA9IFBvc2l0aW9uLk5PUE9TOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdERvTG9vcChKQ0RvV2hpbGVMb29wIHRyZWUpIHsKICAgICAgICBnZW5Mb29wKHRyZWUsIHRyZWUuYm9keSwgdHJlZS5jb25kLCBMaXN0Lm5pbCgpLCBmYWxzZSk7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRXaGlsZUxvb3AoSkNXaGlsZUxvb3AgdHJlZSkgewogICAgICAgIGdlbkxvb3AodHJlZSwgdHJlZS5ib2R5LCB0cmVlLmNvbmQsIExpc3QubmlsKCksIHRydWUpOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0Rm9yTG9vcChKQ0Zvckxvb3AgdHJlZSkgewogICAgICAgIGludCBsaW1pdCA9IGNvZGUubmV4dHJlZzsKICAgICAgICBnZW5TdGF0cyh0cmVlLmluaXQsIGVudik7CiAgICAgICAgZ2VuTG9vcCh0cmVlLCB0cmVlLmJvZHksIHRyZWUuY29uZCwgdHJlZS5zdGVwLCB0cnVlKTsKICAgICAgICBjb2RlLmVuZFNjb3BlcyhsaW1pdCk7CiAgICB9CiAgICAvL3doZXJlCiAgICAgICAgLyoqIEdlbmVyYXRlIGNvZGUgZm9yIGEgbG9vcC4KICAgICAgICAgKiAgQHBhcmFtIGxvb3AgICAgICAgVGhlIHRyZWUgcmVwcmVzZW50aW5nIHRoZSBsb29wLgogICAgICAgICAqICBAcGFyYW0gYm9keSAgICAgICBUaGUgbG9vcCdzIGJvZHkuCiAgICAgICAgICogIEBwYXJhbSBjb25kICAgICAgIFRoZSBsb29wJ3MgY29udHJvbGluZyBjb25kaXRpb24uCiAgICAgICAgICogIEBwYXJhbSBzdGVwICAgICAgICJTdGVwIiBzdGF0ZW1lbnRzIHRvIGJlIGluc2VydGVkIGF0IGVuZCBvZgogICAgICAgICAqICAgICAgICAgICAgICAgICAgICBlYWNoIGl0ZXJhdGlvbi4KICAgICAgICAgKiAgQHBhcmFtIHRlc3RGaXJzdCAgVHJ1ZSBpZiB0aGUgbG9vcCB0ZXN0IGJlbG9uZ3MgYmVmb3JlIHRoZSBib2R5LgogICAgICAgICAqLwogICAgICAgIHByaXZhdGUgdm9pZCBnZW5Mb29wKEpDU3RhdGVtZW50IGxvb3AsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSkNTdGF0ZW1lbnQgYm9keSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBKQ0V4cHJlc3Npb24gY29uZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaXN0PEpDRXhwcmVzc2lvblN0YXRlbWVudD4gc3RlcCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIHRlc3RGaXJzdCkgewogICAgICAgICAgICBFbnY8R2VuQ29udGV4dD4gbG9vcEVudiA9IGVudi5kdXAobG9vcCwgbmV3IEdlbkNvbnRleHQoKSk7CiAgICAgICAgICAgIGludCBzdGFydHBjID0gY29kZS5lbnRyeVBvaW50KCk7CiAgICAgICAgICAgIGlmICh0ZXN0Rmlyc3QpIHsgLy93aGlsZSBvciBmb3IgbG9vcAogICAgICAgICAgICAgICAgQ29uZEl0ZW0gYzsKICAgICAgICAgICAgICAgIGlmIChjb25kICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICBjb2RlLnN0YXRCZWdpbihjb25kLnBvcyk7CiAgICAgICAgICAgICAgICAgICAgQXNzZXJ0LmNoZWNrKGNvZGUuc3RhdGUuc3RhY2tzaXplID09IDApOwogICAgICAgICAgICAgICAgICAgIGMgPSBnZW5Db25kKFRyZWVJbmZvLnNraXBQYXJlbnMoY29uZCksIENSVF9GTE9XX0NPTlRST0xMRVIpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBjID0gaXRlbXMubWFrZUNvbmRJdGVtKGdvdG9fKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIENoYWluIGxvb3BEb25lID0gYy5qdW1wRmFsc2UoKTsKICAgICAgICAgICAgICAgIGNvZGUucmVzb2x2ZShjLnRydWVKdW1wcyk7CiAgICAgICAgICAgICAgICBBc3NlcnQuY2hlY2soY29kZS5zdGF0ZS5zdGFja3NpemUgPT0gMCk7CiAgICAgICAgICAgICAgICBnZW5TdGF0KGJvZHksIGxvb3BFbnYsIENSVF9TVEFURU1FTlQgfCBDUlRfRkxPV19UQVJHRVQpOwogICAgICAgICAgICAgICAgY29kZS5yZXNvbHZlKGxvb3BFbnYuaW5mby5jb250KTsKICAgICAgICAgICAgICAgIGdlblN0YXRzKHN0ZXAsIGxvb3BFbnYpOwogICAgICAgICAgICAgICAgY29kZS5yZXNvbHZlKGNvZGUuYnJhbmNoKGdvdG9fKSwgc3RhcnRwYyk7CiAgICAgICAgICAgICAgICBjb2RlLnJlc29sdmUobG9vcERvbmUpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgZ2VuU3RhdChib2R5LCBsb29wRW52LCBDUlRfU1RBVEVNRU5UIHwgQ1JUX0ZMT1dfVEFSR0VUKTsKICAgICAgICAgICAgICAgIGNvZGUucmVzb2x2ZShsb29wRW52LmluZm8uY29udCk7CiAgICAgICAgICAgICAgICBnZW5TdGF0cyhzdGVwLCBsb29wRW52KTsKICAgICAgICAgICAgICAgIGlmIChjb2RlLmlzQWxpdmUoKSkgewogICAgICAgICAgICAgICAgICAgIENvbmRJdGVtIGM7CiAgICAgICAgICAgICAgICAgICAgaWYgKGNvbmQgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICBjb2RlLnN0YXRCZWdpbihjb25kLnBvcyk7CiAgICAgICAgICAgICAgICAgICAgICAgIEFzc2VydC5jaGVjayhjb2RlLnN0YXRlLnN0YWNrc2l6ZSA9PSAwKTsKICAgICAgICAgICAgICAgICAgICAgICAgYyA9IGdlbkNvbmQoVHJlZUluZm8uc2tpcFBhcmVucyhjb25kKSwgQ1JUX0ZMT1dfQ09OVFJPTExFUik7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgYyA9IGl0ZW1zLm1ha2VDb25kSXRlbShnb3RvXyk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGNvZGUucmVzb2x2ZShjLmp1bXBUcnVlKCksIHN0YXJ0cGMpOwogICAgICAgICAgICAgICAgICAgIEFzc2VydC5jaGVjayhjb2RlLnN0YXRlLnN0YWNrc2l6ZSA9PSAwKTsKICAgICAgICAgICAgICAgICAgICBjb2RlLnJlc29sdmUoYy5mYWxzZUp1bXBzKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBDaGFpbiBleGl0ID0gbG9vcEVudi5pbmZvLmV4aXQ7CiAgICAgICAgICAgIGlmIChleGl0ICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIGNvZGUucmVzb2x2ZShleGl0KTsKICAgICAgICAgICAgICAgIGV4aXQuc3RhdGUuZGVmaW5lZC5leGNsdWRlRnJvbShjb2RlLm5leHRyZWcpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0Rm9yZWFjaExvb3AoSkNFbmhhbmNlZEZvckxvb3AgdHJlZSkgewogICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigpOyAvLyBzaG91bGQgaGF2ZSBiZWVuIHJlbW92ZWQgYnkgTG93ZXIuCiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRMYWJlbGxlZChKQ0xhYmVsZWRTdGF0ZW1lbnQgdHJlZSkgewogICAgICAgIEVudjxHZW5Db250ZXh0PiBsb2NhbEVudiA9IGVudi5kdXAodHJlZSwgbmV3IEdlbkNvbnRleHQoKSk7CiAgICAgICAgZ2VuU3RhdCh0cmVlLmJvZHksIGxvY2FsRW52LCBDUlRfU1RBVEVNRU5UKTsKICAgICAgICBDaGFpbiBleGl0ID0gbG9jYWxFbnYuaW5mby5leGl0OwogICAgICAgIGlmIChleGl0ICE9IG51bGwpIHsKICAgICAgICAgICAgY29kZS5yZXNvbHZlKGV4aXQpOwogICAgICAgICAgICBleGl0LnN0YXRlLmRlZmluZWQuZXhjbHVkZUZyb20oY29kZS5uZXh0cmVnKTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRTd2l0Y2goSkNTd2l0Y2ggdHJlZSkgewogICAgICAgIGludCBsaW1pdCA9IGNvZGUubmV4dHJlZzsKICAgICAgICBBc3NlcnQuY2hlY2soIXRyZWUuc2VsZWN0b3IudHlwZS5oYXNUYWcoQ0xBU1MpKTsKICAgICAgICBpbnQgc3RhcnRwY0NydCA9IGdlbkNydCA/IGNvZGUuY3VyQ1AoKSA6IDA7CiAgICAgICAgQXNzZXJ0LmNoZWNrKGNvZGUuc3RhdGUuc3RhY2tzaXplID09IDApOwogICAgICAgIEl0ZW0gc2VsID0gZ2VuRXhwcih0cmVlLnNlbGVjdG9yLCBzeW1zLmludFR5cGUpOwogICAgICAgIExpc3Q8SkNDYXNlPiBjYXNlcyA9IHRyZWUuY2FzZXM7CiAgICAgICAgaWYgKGNhc2VzLmlzRW1wdHkoKSkgewogICAgICAgICAgICAvLyBXZSBhcmUgc2VlaW5nOiAgc3dpdGNoIDxzZWw+IHt9CiAgICAgICAgICAgIHNlbC5sb2FkKCkuZHJvcCgpOwogICAgICAgICAgICBpZiAoZ2VuQ3J0KQogICAgICAgICAgICAgICAgY29kZS5jcnQucHV0KFRyZWVJbmZvLnNraXBQYXJlbnModHJlZS5zZWxlY3RvciksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ1JUX0ZMT1dfQ09OVFJPTExFUiwgc3RhcnRwY0NydCwgY29kZS5jdXJDUCgpKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvLyBXZSBhcmUgc2VlaW5nIGEgbm9uZW1wdHkgc3dpdGNoLgogICAgICAgICAgICBzZWwubG9hZCgpOwogICAgICAgICAgICBpZiAoZ2VuQ3J0KQogICAgICAgICAgICAgICAgY29kZS5jcnQucHV0KFRyZWVJbmZvLnNraXBQYXJlbnModHJlZS5zZWxlY3RvciksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ1JUX0ZMT1dfQ09OVFJPTExFUiwgc3RhcnRwY0NydCwgY29kZS5jdXJDUCgpKTsKICAgICAgICAgICAgRW52PEdlbkNvbnRleHQ+IHN3aXRjaEVudiA9IGVudi5kdXAodHJlZSwgbmV3IEdlbkNvbnRleHQoKSk7CiAgICAgICAgICAgIHN3aXRjaEVudi5pbmZvLmlzU3dpdGNoID0gdHJ1ZTsKCiAgICAgICAgICAgIC8vIENvbXB1dGUgbnVtYmVyIG9mIGxhYmVscyBhbmQgbWluaW11bSBhbmQgbWF4aW11bSBsYWJlbCB2YWx1ZXMuCiAgICAgICAgICAgIC8vIEZvciBlYWNoIGNhc2UsIHN0b3JlIGl0cyBsYWJlbCBpbiBhbiBhcnJheS4KICAgICAgICAgICAgaW50IGxvID0gSW50ZWdlci5NQVhfVkFMVUU7ICAvLyBtaW5pbXVtIGxhYmVsLgogICAgICAgICAgICBpbnQgaGkgPSBJbnRlZ2VyLk1JTl9WQUxVRTsgIC8vIG1heGltdW0gbGFiZWwuCiAgICAgICAgICAgIGludCBubGFiZWxzID0gMDsgICAgICAgICAgICAgICAvLyBudW1iZXIgb2YgbGFiZWxzLgoKICAgICAgICAgICAgaW50W10gbGFiZWxzID0gbmV3IGludFtjYXNlcy5sZW5ndGgoKV07ICAvLyB0aGUgbGFiZWwgYXJyYXkuCiAgICAgICAgICAgIGludCBkZWZhdWx0SW5kZXggPSAtMTsgICAgIC8vIHRoZSBpbmRleCBvZiB0aGUgZGVmYXVsdCBjbGF1c2UuCgogICAgICAgICAgICBMaXN0PEpDQ2FzZT4gbCA9IGNhc2VzOwogICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxhYmVscy5sZW5ndGg7IGkrKykgewogICAgICAgICAgICAgICAgaWYgKGwuaGVhZC5wYXQgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIGludCB2YWwgPSAoKE51bWJlcilsLmhlYWQucGF0LnR5cGUuY29uc3RWYWx1ZSgpKS5pbnRWYWx1ZSgpOwogICAgICAgICAgICAgICAgICAgIGxhYmVsc1tpXSA9IHZhbDsKICAgICAgICAgICAgICAgICAgICBpZiAodmFsIDwgbG8pIGxvID0gdmFsOwogICAgICAgICAgICAgICAgICAgIGlmIChoaSA8IHZhbCkgaGkgPSB2YWw7CiAgICAgICAgICAgICAgICAgICAgbmxhYmVscysrOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBBc3NlcnQuY2hlY2soZGVmYXVsdEluZGV4ID09IC0xKTsKICAgICAgICAgICAgICAgICAgICBkZWZhdWx0SW5kZXggPSBpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgbCA9IGwudGFpbDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gRGV0ZXJtaW5lIHdoZXRoZXIgdG8gaXNzdWUgYSB0YWJsZXN3aXRjaCBvciBhIGxvb2t1cHN3aXRjaAogICAgICAgICAgICAvLyBpbnN0cnVjdGlvbi4KICAgICAgICAgICAgbG9uZyB0YWJsZV9zcGFjZV9jb3N0ID0gNCArICgobG9uZykgaGkgLSBsbyArIDEpOyAvLyB3b3JkcwogICAgICAgICAgICBsb25nIHRhYmxlX3RpbWVfY29zdCA9IDM7IC8vIGNvbXBhcmlzb25zCiAgICAgICAgICAgIGxvbmcgbG9va3VwX3NwYWNlX2Nvc3QgPSAzICsgMiAqIChsb25nKSBubGFiZWxzOwogICAgICAgICAgICBsb25nIGxvb2t1cF90aW1lX2Nvc3QgPSBubGFiZWxzOwogICAgICAgICAgICBpbnQgb3Bjb2RlID0KICAgICAgICAgICAgICAgIG5sYWJlbHMgPiAwICYmCiAgICAgICAgICAgICAgICB0YWJsZV9zcGFjZV9jb3N0ICsgMyAqIHRhYmxlX3RpbWVfY29zdCA8PQogICAgICAgICAgICAgICAgbG9va3VwX3NwYWNlX2Nvc3QgKyAzICogbG9va3VwX3RpbWVfY29zdAogICAgICAgICAgICAgICAgPwogICAgICAgICAgICAgICAgdGFibGVzd2l0Y2ggOiBsb29rdXBzd2l0Y2g7CgogICAgICAgICAgICBpbnQgc3RhcnRwYyA9IGNvZGUuY3VyQ1AoKTsgICAgLy8gdGhlIHBvc2l0aW9uIG9mIHRoZSBzZWxlY3RvciBvcGVyYXRpb24KICAgICAgICAgICAgY29kZS5lbWl0b3AwKG9wY29kZSk7CiAgICAgICAgICAgIGNvZGUuYWxpZ24oNCk7CiAgICAgICAgICAgIGludCB0YWJsZUJhc2UgPSBjb2RlLmN1ckNQKCk7ICAvLyB0aGUgc3RhcnQgb2YgdGhlIGp1bXAgdGFibGUKICAgICAgICAgICAgaW50W10gb2Zmc2V0cyA9IG51bGw7ICAgICAgICAgIC8vIGEgdGFibGUgb2Ygb2Zmc2V0cyBmb3IgYSBsb29rdXBzd2l0Y2gKICAgICAgICAgICAgY29kZS5lbWl0NCgtMSk7ICAgICAgICAgICAgICAgIC8vIGxlYXZlIHNwYWNlIGZvciBkZWZhdWx0IG9mZnNldAogICAgICAgICAgICBpZiAob3Bjb2RlID09IHRhYmxlc3dpdGNoKSB7CiAgICAgICAgICAgICAgICBjb2RlLmVtaXQ0KGxvKTsgICAgICAgICAgICAvLyBtaW5pbXVtIGxhYmVsCiAgICAgICAgICAgICAgICBjb2RlLmVtaXQ0KGhpKTsgICAgICAgICAgICAvLyBtYXhpbXVtIGxhYmVsCiAgICAgICAgICAgICAgICBmb3IgKGxvbmcgaSA9IGxvOyBpIDw9IGhpOyBpKyspIHsgIC8vIGxlYXZlIHNwYWNlIGZvciBqdW1wIHRhYmxlCiAgICAgICAgICAgICAgICAgICAgY29kZS5lbWl0NCgtMSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBjb2RlLmVtaXQ0KG5sYWJlbHMpOyAgICAvLyBudW1iZXIgb2YgbGFiZWxzCiAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG5sYWJlbHM7IGkrKykgewogICAgICAgICAgICAgICAgICAgIGNvZGUuZW1pdDQoLTEpOyBjb2RlLmVtaXQ0KC0xKTsgLy8gbGVhdmUgc3BhY2UgZm9yIGxvb2t1cCB0YWJsZQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgb2Zmc2V0cyA9IG5ldyBpbnRbbGFiZWxzLmxlbmd0aF07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgQ29kZS5TdGF0ZSBzdGF0ZVN3aXRjaCA9IGNvZGUuc3RhdGUuZHVwKCk7CiAgICAgICAgICAgIGNvZGUubWFya0RlYWQoKTsKCiAgICAgICAgICAgIC8vIEZvciBlYWNoIGNhc2UgZG86CiAgICAgICAgICAgIGwgPSBjYXNlczsKICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsYWJlbHMubGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgICAgIEpDQ2FzZSBjID0gbC5oZWFkOwogICAgICAgICAgICAgICAgbCA9IGwudGFpbDsKCiAgICAgICAgICAgICAgICBpbnQgcGMgPSBjb2RlLmVudHJ5UG9pbnQoc3RhdGVTd2l0Y2gpOwogICAgICAgICAgICAgICAgLy8gSW5zZXJ0IG9mZnNldCBkaXJlY3RseSBpbnRvIGNvZGUgb3IgZWxzZSBpbnRvIHRoZQogICAgICAgICAgICAgICAgLy8gb2Zmc2V0cyB0YWJsZS4KICAgICAgICAgICAgICAgIGlmIChpICE9IGRlZmF1bHRJbmRleCkgewogICAgICAgICAgICAgICAgICAgIGlmIChvcGNvZGUgPT0gdGFibGVzd2l0Y2gpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY29kZS5wdXQ0KAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFibGVCYXNlICsgNCAqIChsYWJlbHNbaV0gLSBsbyArIDMpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcGMgLSBzdGFydHBjKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXRzW2ldID0gcGMgLSBzdGFydHBjOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgY29kZS5wdXQ0KHRhYmxlQmFzZSwgcGMgLSBzdGFydHBjKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBHZW5lcmF0ZSBjb2RlIGZvciB0aGUgc3RhdGVtZW50cyBpbiB0aGlzIGNhc2UuCiAgICAgICAgICAgICAgICBnZW5TdGF0cyhjLnN0YXRzLCBzd2l0Y2hFbnYsIENSVF9GTE9XX1RBUkdFVCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIFJlc29sdmUgYWxsIGJyZWFrcy4KICAgICAgICAgICAgQ2hhaW4gZXhpdCA9IHN3aXRjaEVudi5pbmZvLmV4aXQ7CiAgICAgICAgICAgIGlmICAoZXhpdCAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICBjb2RlLnJlc29sdmUoZXhpdCk7CiAgICAgICAgICAgICAgICBleGl0LnN0YXRlLmRlZmluZWQuZXhjbHVkZUZyb20obGltaXQpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBJZiB3ZSBoYXZlIG5vdCBzZXQgdGhlIGRlZmF1bHQgb2Zmc2V0LCB3ZSBkbyBzbyBub3cuCiAgICAgICAgICAgIGlmIChjb2RlLmdldDQodGFibGVCYXNlKSA9PSAtMSkgewogICAgICAgICAgICAgICAgY29kZS5wdXQ0KHRhYmxlQmFzZSwgY29kZS5lbnRyeVBvaW50KHN0YXRlU3dpdGNoKSAtIHN0YXJ0cGMpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAob3Bjb2RlID09IHRhYmxlc3dpdGNoKSB7CiAgICAgICAgICAgICAgICAvLyBMZXQgYW55IHVuZmlsbGVkIHNsb3RzIHBvaW50IHRvIHRoZSBkZWZhdWx0IGNhc2UuCiAgICAgICAgICAgICAgICBpbnQgZGVmYXVsdE9mZnNldCA9IGNvZGUuZ2V0NCh0YWJsZUJhc2UpOwogICAgICAgICAgICAgICAgZm9yIChsb25nIGkgPSBsbzsgaSA8PSBoaTsgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgaW50IHQgPSAoaW50KSh0YWJsZUJhc2UgKyA0ICogKGkgLSBsbyArIDMpKTsKICAgICAgICAgICAgICAgICAgICBpZiAoY29kZS5nZXQ0KHQpID09IC0xKQogICAgICAgICAgICAgICAgICAgICAgICBjb2RlLnB1dDQodCwgZGVmYXVsdE9mZnNldCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvLyBTb3J0IG5vbi1kZWZhdWx0IG9mZnNldHMgYW5kIGNvcHkgaW50byBsb29rdXAgdGFibGUuCiAgICAgICAgICAgICAgICBpZiAoZGVmYXVsdEluZGV4ID49IDApCiAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IGRlZmF1bHRJbmRleDsgaSA8IGxhYmVscy5sZW5ndGggLSAxOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzW2ldID0gbGFiZWxzW2krMV07CiAgICAgICAgICAgICAgICAgICAgICAgIG9mZnNldHNbaV0gPSBvZmZzZXRzW2krMV07CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKG5sYWJlbHMgPiAwKQogICAgICAgICAgICAgICAgICAgIHFzb3J0MihsYWJlbHMsIG9mZnNldHMsIDAsIG5sYWJlbHMgLSAxKTsKICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbmxhYmVsczsgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgaW50IGNhc2VpZHggPSB0YWJsZUJhc2UgKyA4ICogKGkgKyAxKTsKICAgICAgICAgICAgICAgICAgICBjb2RlLnB1dDQoY2FzZWlkeCwgbGFiZWxzW2ldKTsKICAgICAgICAgICAgICAgICAgICBjb2RlLnB1dDQoY2FzZWlkeCArIDQsIG9mZnNldHNbaV0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGNvZGUuZW5kU2NvcGVzKGxpbWl0KTsKICAgIH0KLy93aGVyZQogICAgICAgIC8qKiBTb3J0IChpbnQpIGFycmF5cyBvZiBrZXlzIGFuZCB2YWx1ZXMKICAgICAgICAgKi8KICAgICAgIHN0YXRpYyB2b2lkIHFzb3J0MihpbnRbXSBrZXlzLCBpbnRbXSB2YWx1ZXMsIGludCBsbywgaW50IGhpKSB7CiAgICAgICAgICAgIGludCBpID0gbG87CiAgICAgICAgICAgIGludCBqID0gaGk7CiAgICAgICAgICAgIGludCBwaXZvdCA9IGtleXNbKGkraikvMl07CiAgICAgICAgICAgIGRvIHsKICAgICAgICAgICAgICAgIHdoaWxlIChrZXlzW2ldIDwgcGl2b3QpIGkrKzsKICAgICAgICAgICAgICAgIHdoaWxlIChwaXZvdCA8IGtleXNbal0pIGotLTsKICAgICAgICAgICAgICAgIGlmIChpIDw9IGopIHsKICAgICAgICAgICAgICAgICAgICBpbnQgdGVtcDEgPSBrZXlzW2ldOwogICAgICAgICAgICAgICAgICAgIGtleXNbaV0gPSBrZXlzW2pdOwogICAgICAgICAgICAgICAgICAgIGtleXNbal0gPSB0ZW1wMTsKICAgICAgICAgICAgICAgICAgICBpbnQgdGVtcDIgPSB2YWx1ZXNbaV07CiAgICAgICAgICAgICAgICAgICAgdmFsdWVzW2ldID0gdmFsdWVzW2pdOwogICAgICAgICAgICAgICAgICAgIHZhbHVlc1tqXSA9IHRlbXAyOwogICAgICAgICAgICAgICAgICAgIGkrKzsKICAgICAgICAgICAgICAgICAgICBqLS07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gd2hpbGUgKGkgPD0gaik7CiAgICAgICAgICAgIGlmIChsbyA8IGopIHFzb3J0MihrZXlzLCB2YWx1ZXMsIGxvLCBqKTsKICAgICAgICAgICAgaWYgKGkgPCBoaSkgcXNvcnQyKGtleXMsIHZhbHVlcywgaSwgaGkpOwogICAgICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdFN5bmNocm9uaXplZChKQ1N5bmNocm9uaXplZCB0cmVlKSB7CiAgICAgICAgaW50IGxpbWl0ID0gY29kZS5uZXh0cmVnOwogICAgICAgIC8vIEdlbmVyYXRlIGNvZGUgdG8gZXZhbHVhdGUgbG9jayBhbmQgc2F2ZSBpbiB0ZW1wb3JhcnkgdmFyaWFibGUuCiAgICAgICAgZmluYWwgTG9jYWxJdGVtIGxvY2tWYXIgPSBtYWtlVGVtcChzeW1zLm9iamVjdFR5cGUpOwogICAgICAgIEFzc2VydC5jaGVjayhjb2RlLnN0YXRlLnN0YWNrc2l6ZSA9PSAwKTsKICAgICAgICBnZW5FeHByKHRyZWUubG9jaywgdHJlZS5sb2NrLnR5cGUpLmxvYWQoKS5kdXBsaWNhdGUoKTsKICAgICAgICBsb2NrVmFyLnN0b3JlKCk7CgogICAgICAgIC8vIEdlbmVyYXRlIGNvZGUgdG8gZW50ZXIgbW9uaXRvci4KICAgICAgICBjb2RlLmVtaXRvcDAobW9uaXRvcmVudGVyKTsKICAgICAgICBjb2RlLnN0YXRlLmxvY2sobG9ja1Zhci5yZWcpOwoKICAgICAgICAvLyBHZW5lcmF0ZSBjb2RlIGZvciBhIHRyeSBzdGF0ZW1lbnQgd2l0aCBnaXZlbiBib2R5LCBubyBjYXRjaCBjbGF1c2VzCiAgICAgICAgLy8gaW4gYSBuZXcgZW52aXJvbm1lbnQgd2l0aCB0aGUgImV4aXQtbW9uaXRvciIgb3BlcmF0aW9uIGFzIGZpbmFsaXplci4KICAgICAgICBmaW5hbCBFbnY8R2VuQ29udGV4dD4gc3luY0VudiA9IGVudi5kdXAodHJlZSwgbmV3IEdlbkNvbnRleHQoKSk7CiAgICAgICAgc3luY0Vudi5pbmZvLmZpbmFsaXplID0gbmV3IEdlbkZpbmFsaXplcigpIHsKICAgICAgICAgICAgdm9pZCBnZW4oKSB7CiAgICAgICAgICAgICAgICBnZW5MYXN0KCk7CiAgICAgICAgICAgICAgICBBc3NlcnQuY2hlY2soc3luY0Vudi5pbmZvLmdhcHMubGVuZ3RoKCkgJSAyID09IDApOwogICAgICAgICAgICAgICAgc3luY0Vudi5pbmZvLmdhcHMuYXBwZW5kKGNvZGUuY3VyQ1AoKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdm9pZCBnZW5MYXN0KCkgewogICAgICAgICAgICAgICAgaWYgKGNvZGUuaXNBbGl2ZSgpKSB7CiAgICAgICAgICAgICAgICAgICAgbG9ja1Zhci5sb2FkKCk7CiAgICAgICAgICAgICAgICAgICAgY29kZS5lbWl0b3AwKG1vbml0b3JleGl0KTsKICAgICAgICAgICAgICAgICAgICBjb2RlLnN0YXRlLnVubG9jayhsb2NrVmFyLnJlZyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9OwogICAgICAgIHN5bmNFbnYuaW5mby5nYXBzID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgIGdlblRyeSh0cmVlLmJvZHksIExpc3QubmlsKCksIHN5bmNFbnYpOwogICAgICAgIGNvZGUuZW5kU2NvcGVzKGxpbWl0KTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdFRyeShmaW5hbCBKQ1RyeSB0cmVlKSB7CiAgICAgICAgLy8gR2VuZXJhdGUgY29kZSBmb3IgYSB0cnkgc3RhdGVtZW50IHdpdGggZ2l2ZW4gYm9keSBhbmQgY2F0Y2ggY2xhdXNlcywKICAgICAgICAvLyBpbiBhIG5ldyBlbnZpcm9ubWVudCB3aGljaCBjYWxscyB0aGUgZmluYWxseSBibG9jayBpZiB0aGVyZSBpcyBvbmUuCiAgICAgICAgZmluYWwgRW52PEdlbkNvbnRleHQ+IHRyeUVudiA9IGVudi5kdXAodHJlZSwgbmV3IEdlbkNvbnRleHQoKSk7CiAgICAgICAgZmluYWwgRW52PEdlbkNvbnRleHQ+IG9sZEVudiA9IGVudjsKICAgICAgICB0cnlFbnYuaW5mby5maW5hbGl6ZSA9IG5ldyBHZW5GaW5hbGl6ZXIoKSB7CiAgICAgICAgICAgIHZvaWQgZ2VuKCkgewogICAgICAgICAgICAgICAgQXNzZXJ0LmNoZWNrKHRyeUVudi5pbmZvLmdhcHMubGVuZ3RoKCkgJSAyID09IDApOwogICAgICAgICAgICAgICAgdHJ5RW52LmluZm8uZ2Fwcy5hcHBlbmQoY29kZS5jdXJDUCgpKTsKICAgICAgICAgICAgICAgIGdlbkxhc3QoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICB2b2lkIGdlbkxhc3QoKSB7CiAgICAgICAgICAgICAgICBpZiAodHJlZS5maW5hbGl6ZXIgIT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICBnZW5TdGF0KHRyZWUuZmluYWxpemVyLCBvbGRFbnYsIENSVF9CTE9DSyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYm9vbGVhbiBoYXNGaW5hbGl6ZXIoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJlZS5maW5hbGl6ZXIgIT0gbnVsbDsKICAgICAgICAgICAgfQogICAgICAgIH07CiAgICAgICAgdHJ5RW52LmluZm8uZ2FwcyA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICBnZW5UcnkodHJlZS5ib2R5LCB0cmVlLmNhdGNoZXJzLCB0cnlFbnYpOwogICAgfQogICAgLy93aGVyZQogICAgICAgIC8qKiBHZW5lcmF0ZSBjb2RlIGZvciBhIHRyeSBvciBzeW5jaHJvbml6ZWQgc3RhdGVtZW50CiAgICAgICAgICogIEBwYXJhbSBib2R5ICAgICAgVGhlIGJvZHkgb2YgdGhlIHRyeSBvciBzeW5jaHJvbml6ZWQgc3RhdGVtZW50LgogICAgICAgICAqICBAcGFyYW0gY2F0Y2hlcnMgIFRoZSBsaXMgb2YgY2F0Y2ggY2xhdXNlcy4KICAgICAgICAgKiAgQHBhcmFtIGVudiAgICAgICB0aGUgZW52aXJvbm1lbnQgY3VycmVudCBmb3IgdGhlIGJvZHkuCiAgICAgICAgICovCiAgICAgICAgdm9pZCBnZW5UcnkoSkNUcmVlIGJvZHksIExpc3Q8SkNDYXRjaD4gY2F0Y2hlcnMsIEVudjxHZW5Db250ZXh0PiBlbnYpIHsKICAgICAgICAgICAgaW50IGxpbWl0ID0gY29kZS5uZXh0cmVnOwogICAgICAgICAgICBpbnQgc3RhcnRwYyA9IGNvZGUuY3VyQ1AoKTsKICAgICAgICAgICAgQ29kZS5TdGF0ZSBzdGF0ZVRyeSA9IGNvZGUuc3RhdGUuZHVwKCk7CiAgICAgICAgICAgIGdlblN0YXQoYm9keSwgZW52LCBDUlRfQkxPQ0spOwogICAgICAgICAgICBpbnQgZW5kcGMgPSBjb2RlLmN1ckNQKCk7CiAgICAgICAgICAgIGJvb2xlYW4gaGFzRmluYWxpemVyID0KICAgICAgICAgICAgICAgIGVudi5pbmZvLmZpbmFsaXplICE9IG51bGwgJiYKICAgICAgICAgICAgICAgIGVudi5pbmZvLmZpbmFsaXplLmhhc0ZpbmFsaXplcigpOwogICAgICAgICAgICBMaXN0PEludGVnZXI+IGdhcHMgPSBlbnYuaW5mby5nYXBzLnRvTGlzdCgpOwogICAgICAgICAgICBjb2RlLnN0YXRCZWdpbihUcmVlSW5mby5lbmRQb3MoYm9keSkpOwogICAgICAgICAgICBnZW5GaW5hbGl6ZXIoZW52KTsKICAgICAgICAgICAgY29kZS5zdGF0QmVnaW4oVHJlZUluZm8uZW5kUG9zKGVudi50cmVlKSk7CiAgICAgICAgICAgIENoYWluIGV4aXRDaGFpbiA9IGNvZGUuYnJhbmNoKGdvdG9fKTsKICAgICAgICAgICAgZW5kRmluYWxpemVyR2FwKGVudik7CiAgICAgICAgICAgIGlmIChzdGFydHBjICE9IGVuZHBjKSBmb3IgKExpc3Q8SkNDYXRjaD4gbCA9IGNhdGNoZXJzOyBsLm5vbkVtcHR5KCk7IGwgPSBsLnRhaWwpIHsKICAgICAgICAgICAgICAgIC8vIHN0YXJ0IG9mZiB3aXRoIGV4Y2VwdGlvbiBvbiBzdGFjawogICAgICAgICAgICAgICAgY29kZS5lbnRyeVBvaW50KHN0YXRlVHJ5LCBsLmhlYWQucGFyYW0uc3ltLnR5cGUpOwogICAgICAgICAgICAgICAgZ2VuQ2F0Y2gobC5oZWFkLCBlbnYsIHN0YXJ0cGMsIGVuZHBjLCBnYXBzKTsKICAgICAgICAgICAgICAgIGdlbkZpbmFsaXplcihlbnYpOwogICAgICAgICAgICAgICAgaWYgKGhhc0ZpbmFsaXplciB8fCBsLnRhaWwubm9uRW1wdHkoKSkgewogICAgICAgICAgICAgICAgICAgIGNvZGUuc3RhdEJlZ2luKFRyZWVJbmZvLmVuZFBvcyhlbnYudHJlZSkpOwogICAgICAgICAgICAgICAgICAgIGV4aXRDaGFpbiA9IENvZGUubWVyZ2VDaGFpbnMoZXhpdENoYWluLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29kZS5icmFuY2goZ290b18pKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVuZEZpbmFsaXplckdhcChlbnYpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChoYXNGaW5hbGl6ZXIpIHsKICAgICAgICAgICAgICAgIC8vIENyZWF0ZSBhIG5ldyByZWdpc3RlciBzZWdlbWVudCB0byBhdm9pZCBhbGxvY2F0aW5nCiAgICAgICAgICAgICAgICAvLyB0aGUgc2FtZSB2YXJpYWJsZXMgaW4gZmluYWxpemVycyBhbmQgb3RoZXIgc3RhdGVtZW50cy4KICAgICAgICAgICAgICAgIGNvZGUubmV3UmVnU2VnbWVudCgpOwoKICAgICAgICAgICAgICAgIC8vIEFkZCBhIGNhdGNoLWFsbCBjbGF1c2UuCgogICAgICAgICAgICAgICAgLy8gc3RhcnQgb2ZmIHdpdGggZXhjZXB0aW9uIG9uIHN0YWNrCiAgICAgICAgICAgICAgICBpbnQgY2F0Y2hhbGxwYyA9IGNvZGUuZW50cnlQb2ludChzdGF0ZVRyeSwgc3ltcy50aHJvd2FibGVUeXBlKTsKCiAgICAgICAgICAgICAgICAvLyBSZWdpc3RlciBhbGwgZXhjZXB0aW9uIHJhbmdlcyBmb3IgY2F0Y2ggYWxsIGNsYXVzZS4KICAgICAgICAgICAgICAgIC8vIFRoZSByYW5nZSBvZiB0aGUgY2F0Y2ggYWxsIGNsYXVzZSBpcyBmcm9tIHRoZSBiZWdpbm5pbmcKICAgICAgICAgICAgICAgIC8vIG9mIHRoZSB0cnkgb3Igc3luY2hyb25pemVkIGJsb2NrIHVudGlsIHRoZSBwcmVzZW50CiAgICAgICAgICAgICAgICAvLyBjb2RlIHBvaW50ZXIgZXhjbHVkaW5nIGFsbCBnYXBzIGluIHRoZSBjdXJyZW50CiAgICAgICAgICAgICAgICAvLyBlbnZpcm9ubWVudCdzIEdlbkNvbnRleHQuCiAgICAgICAgICAgICAgICBpbnQgc3RhcnRzZWcgPSBzdGFydHBjOwogICAgICAgICAgICAgICAgd2hpbGUgKGVudi5pbmZvLmdhcHMubm9uRW1wdHkoKSkgewogICAgICAgICAgICAgICAgICAgIGludCBlbmRzZWcgPSBlbnYuaW5mby5nYXBzLm5leHQoKS5pbnRWYWx1ZSgpOwogICAgICAgICAgICAgICAgICAgIHJlZ2lzdGVyQ2F0Y2goYm9keS5wb3MoKSwgc3RhcnRzZWcsIGVuZHNlZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhdGNoYWxscGMsIDApOwogICAgICAgICAgICAgICAgICAgIHN0YXJ0c2VnID0gZW52LmluZm8uZ2Fwcy5uZXh0KCkuaW50VmFsdWUoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGNvZGUuc3RhdEJlZ2luKFRyZWVJbmZvLmZpbmFsaXplclBvcyhlbnYudHJlZSkpOwogICAgICAgICAgICAgICAgY29kZS5tYXJrU3RhdEJlZ2luKCk7CgogICAgICAgICAgICAgICAgSXRlbSBleGNWYXIgPSBtYWtlVGVtcChzeW1zLnRocm93YWJsZVR5cGUpOwogICAgICAgICAgICAgICAgZXhjVmFyLnN0b3JlKCk7CiAgICAgICAgICAgICAgICBnZW5GaW5hbGl6ZXIoZW52KTsKICAgICAgICAgICAgICAgIGV4Y1Zhci5sb2FkKCk7CiAgICAgICAgICAgICAgICByZWdpc3RlckNhdGNoKGJvZHkucG9zKCksIHN0YXJ0c2VnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbnYuaW5mby5nYXBzLm5leHQoKS5pbnRWYWx1ZSgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXRjaGFsbHBjLCAwKTsKICAgICAgICAgICAgICAgIGNvZGUuZW1pdG9wMChhdGhyb3cpOwogICAgICAgICAgICAgICAgY29kZS5tYXJrRGVhZCgpOwoKICAgICAgICAgICAgICAgIC8vIElmIHRoZXJlIGFyZSBqc3IncyB0byB0aGlzIGZpbmFsaXplciwgLi4uCiAgICAgICAgICAgICAgICBpZiAoZW52LmluZm8uY29udCAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gUmVzb2x2ZSBhbGwganNyJ3MuCiAgICAgICAgICAgICAgICAgICAgY29kZS5yZXNvbHZlKGVudi5pbmZvLmNvbnQpOwoKICAgICAgICAgICAgICAgICAgICAvLyBNYXJrIHN0YXRlbWVudCBsaW5lIG51bWJlcgogICAgICAgICAgICAgICAgICAgIGNvZGUuc3RhdEJlZ2luKFRyZWVJbmZvLmZpbmFsaXplclBvcyhlbnYudHJlZSkpOwogICAgICAgICAgICAgICAgICAgIGNvZGUubWFya1N0YXRCZWdpbigpOwoKICAgICAgICAgICAgICAgICAgICAvLyBTYXZlIHJldHVybiBhZGRyZXNzLgogICAgICAgICAgICAgICAgICAgIExvY2FsSXRlbSByZXRWYXIgPSBtYWtlVGVtcChzeW1zLnRocm93YWJsZVR5cGUpOwogICAgICAgICAgICAgICAgICAgIHJldFZhci5zdG9yZSgpOwoKICAgICAgICAgICAgICAgICAgICAvLyBHZW5lcmF0ZSBmaW5hbGl6ZXIgY29kZS4KICAgICAgICAgICAgICAgICAgICBlbnYuaW5mby5maW5hbGl6ZS5nZW5MYXN0KCk7CgogICAgICAgICAgICAgICAgICAgIC8vIFJldHVybi4KICAgICAgICAgICAgICAgICAgICBjb2RlLmVtaXRvcDF3KHJldCwgcmV0VmFyLnJlZyk7CiAgICAgICAgICAgICAgICAgICAgY29kZS5tYXJrRGVhZCgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIFJlc29sdmUgYWxsIGJyZWFrcy4KICAgICAgICAgICAgY29kZS5yZXNvbHZlKGV4aXRDaGFpbik7CgogICAgICAgICAgICBjb2RlLmVuZFNjb3BlcyhsaW1pdCk7CiAgICAgICAgfQoKICAgICAgICAvKiogR2VuZXJhdGUgY29kZSBmb3IgYSBjYXRjaCBjbGF1c2UuCiAgICAgICAgICogIEBwYXJhbSB0cmVlICAgICBUaGUgY2F0Y2ggY2xhdXNlLgogICAgICAgICAqICBAcGFyYW0gZW52ICAgICAgVGhlIGVudmlyb25tZW50IGN1cnJlbnQgaW4gdGhlIGVuY2xvc2luZyB0cnkuCiAgICAgICAgICogIEBwYXJhbSBzdGFydHBjICBTdGFydCBwYyBvZiB0cnktYmxvY2suCiAgICAgICAgICogIEBwYXJhbSBlbmRwYyAgICBFbmQgcGMgb2YgdHJ5LWJsb2NrLgogICAgICAgICAqLwogICAgICAgIHZvaWQgZ2VuQ2F0Y2goSkNDYXRjaCB0cmVlLAogICAgICAgICAgICAgICAgICAgICAgRW52PEdlbkNvbnRleHQ+IGVudiwKICAgICAgICAgICAgICAgICAgICAgIGludCBzdGFydHBjLCBpbnQgZW5kcGMsCiAgICAgICAgICAgICAgICAgICAgICBMaXN0PEludGVnZXI+IGdhcHMpIHsKICAgICAgICAgICAgaWYgKHN0YXJ0cGMgIT0gZW5kcGMpIHsKICAgICAgICAgICAgICAgIExpc3Q8UGFpcjxMaXN0PEF0dHJpYnV0ZS5UeXBlQ29tcG91bmQ+LCBKQ0V4cHJlc3Npb24+PiBjYXRjaFR5cGVFeHBycwogICAgICAgICAgICAgICAgICAgICAgICA9IGNhdGNoVHlwZXNXaXRoQW5ub3RhdGlvbnModHJlZSk7CiAgICAgICAgICAgICAgICB3aGlsZSAoZ2Fwcy5ub25FbXB0eSgpKSB7CiAgICAgICAgICAgICAgICAgICAgZm9yIChQYWlyPExpc3Q8QXR0cmlidXRlLlR5cGVDb21wb3VuZD4sIEpDRXhwcmVzc2lvbj4gc3ViQ2F0Y2gxIDogY2F0Y2hUeXBlRXhwcnMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgSkNFeHByZXNzaW9uIHN1YkNhdGNoID0gc3ViQ2F0Y2gxLnNuZDsKICAgICAgICAgICAgICAgICAgICAgICAgaW50IGNhdGNoVHlwZSA9IG1ha2VSZWYodHJlZS5wb3MoKSwgc3ViQ2F0Y2gudHlwZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGludCBlbmQgPSBnYXBzLmhlYWQuaW50VmFsdWUoKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmVnaXN0ZXJDYXRjaCh0cmVlLnBvcygpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0cGMsICBlbmQsIGNvZGUuY3VyQ1AoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXRjaFR5cGUpOwogICAgICAgICAgICAgICAgICAgICAgICBmb3IgKEF0dHJpYnV0ZS5UeXBlQ29tcG91bmQgdGMgOiAgc3ViQ2F0Y2gxLmZzdCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRjLnBvc2l0aW9uLnNldENhdGNoSW5mbyhjYXRjaFR5cGUsIHN0YXJ0cGMpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGdhcHMgPSBnYXBzLnRhaWw7CiAgICAgICAgICAgICAgICAgICAgc3RhcnRwYyA9IGdhcHMuaGVhZC5pbnRWYWx1ZSgpOwogICAgICAgICAgICAgICAgICAgIGdhcHMgPSBnYXBzLnRhaWw7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoc3RhcnRwYyA8IGVuZHBjKSB7CiAgICAgICAgICAgICAgICAgICAgZm9yIChQYWlyPExpc3Q8QXR0cmlidXRlLlR5cGVDb21wb3VuZD4sIEpDRXhwcmVzc2lvbj4gc3ViQ2F0Y2gxIDogY2F0Y2hUeXBlRXhwcnMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgSkNFeHByZXNzaW9uIHN1YkNhdGNoID0gc3ViQ2F0Y2gxLnNuZDsKICAgICAgICAgICAgICAgICAgICAgICAgaW50IGNhdGNoVHlwZSA9IG1ha2VSZWYodHJlZS5wb3MoKSwgc3ViQ2F0Y2gudHlwZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJlZ2lzdGVyQ2F0Y2godHJlZS5wb3MoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGFydHBjLCBlbmRwYywgY29kZS5jdXJDUCgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhdGNoVHlwZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoQXR0cmlidXRlLlR5cGVDb21wb3VuZCB0YyA6ICBzdWJDYXRjaDEuZnN0KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0Yy5wb3NpdGlvbi5zZXRDYXRjaEluZm8oY2F0Y2hUeXBlLCBzdGFydHBjKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIFZhclN5bWJvbCBleHBhcmFtID0gdHJlZS5wYXJhbS5zeW07CiAgICAgICAgICAgICAgICBjb2RlLnN0YXRCZWdpbih0cmVlLnBvcyk7CiAgICAgICAgICAgICAgICBjb2RlLm1hcmtTdGF0QmVnaW4oKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGNvZGUubmV4dHJlZzsKICAgICAgICAgICAgICAgIGNvZGUubmV3TG9jYWwoZXhwYXJhbSk7CiAgICAgICAgICAgICAgICBpdGVtcy5tYWtlTG9jYWxJdGVtKGV4cGFyYW0pLnN0b3JlKCk7CiAgICAgICAgICAgICAgICBjb2RlLnN0YXRCZWdpbihUcmVlSW5mby5maXJzdFN0YXRQb3ModHJlZS5ib2R5KSk7CiAgICAgICAgICAgICAgICBnZW5TdGF0KHRyZWUuYm9keSwgZW52LCBDUlRfQkxPQ0spOwogICAgICAgICAgICAgICAgY29kZS5lbmRTY29wZXMobGltaXQpOwogICAgICAgICAgICAgICAgY29kZS5zdGF0QmVnaW4oVHJlZUluZm8uZW5kUG9zKHRyZWUuYm9keSkpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8vIHdoZXJlCiAgICAgICAgTGlzdDxQYWlyPExpc3Q8QXR0cmlidXRlLlR5cGVDb21wb3VuZD4sIEpDRXhwcmVzc2lvbj4+IGNhdGNoVHlwZXNXaXRoQW5ub3RhdGlvbnMoSkNDYXRjaCB0cmVlKSB7CiAgICAgICAgICAgIHJldHVybiBUcmVlSW5mby5pc011bHRpQ2F0Y2godHJlZSkgPwogICAgICAgICAgICAgICAgICAgIGNhdGNoVHlwZXNXaXRoQW5ub3RhdGlvbnNGcm9tTXVsdGljYXRjaCgoSkNUeXBlVW5pb24pdHJlZS5wYXJhbS52YXJ0eXBlLCB0cmVlLnBhcmFtLnN5bS5nZXRSYXdUeXBlQXR0cmlidXRlcygpKSA6CiAgICAgICAgICAgICAgICAgICAgTGlzdC5vZihuZXcgUGFpcjw+KHRyZWUucGFyYW0uc3ltLmdldFJhd1R5cGVBdHRyaWJ1dGVzKCksIHRyZWUucGFyYW0udmFydHlwZSkpOwogICAgICAgIH0KICAgICAgICAvLyB3aGVyZQogICAgICAgIExpc3Q8UGFpcjxMaXN0PEF0dHJpYnV0ZS5UeXBlQ29tcG91bmQ+LCBKQ0V4cHJlc3Npb24+PiBjYXRjaFR5cGVzV2l0aEFubm90YXRpb25zRnJvbU11bHRpY2F0Y2goSkNUeXBlVW5pb24gdHJlZSwgTGlzdDxUeXBlQ29tcG91bmQ+IGZpcnN0KSB7CiAgICAgICAgICAgIExpc3Q8SkNFeHByZXNzaW9uPiBhbHRzID0gdHJlZS5hbHRlcm5hdGl2ZXM7CiAgICAgICAgICAgIExpc3Q8UGFpcjxMaXN0PFR5cGVDb21wb3VuZD4sIEpDRXhwcmVzc2lvbj4+IHJlcyA9IExpc3Qub2YobmV3IFBhaXI8PihmaXJzdCwgYWx0cy5oZWFkKSk7CiAgICAgICAgICAgIGFsdHMgPSBhbHRzLnRhaWw7CgogICAgICAgICAgICB3aGlsZShhbHRzICE9IG51bGwgJiYgYWx0cy5oZWFkICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIEpDRXhwcmVzc2lvbiBhbHQgPSBhbHRzLmhlYWQ7CiAgICAgICAgICAgICAgICBpZiAoYWx0IGluc3RhbmNlb2YgSkNBbm5vdGF0ZWRUeXBlKSB7CiAgICAgICAgICAgICAgICAgICAgSkNBbm5vdGF0ZWRUeXBlIGEgPSAoSkNBbm5vdGF0ZWRUeXBlKWFsdDsKICAgICAgICAgICAgICAgICAgICByZXMgPSByZXMucHJlcGVuZChuZXcgUGFpcjw+KGFubm90YXRlLmZyb21Bbm5vdGF0aW9ucyhhLmFubm90YXRpb25zKSwgYWx0KSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHJlcyA9IHJlcy5wcmVwZW5kKG5ldyBQYWlyPD4oTGlzdC5uaWwoKSwgYWx0KSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBhbHRzID0gYWx0cy50YWlsOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiByZXMucmV2ZXJzZSgpOwogICAgICAgIH0KCiAgICAgICAgLyoqIFJlZ2lzdGVyIGEgY2F0Y2ggY2xhdXNlIGluIHRoZSAiRXhjZXB0aW9ucyIgY29kZS1hdHRyaWJ1dGUuCiAgICAgICAgICovCiAgICAgICAgdm9pZCByZWdpc3RlckNhdGNoKERpYWdub3N0aWNQb3NpdGlvbiBwb3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBzdGFydHBjLCBpbnQgZW5kcGMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBoYW5kbGVyX3BjLCBpbnQgY2F0Y2hfdHlwZSkgewogICAgICAgICAgICBjaGFyIHN0YXJ0cGMxID0gKGNoYXIpc3RhcnRwYzsKICAgICAgICAgICAgY2hhciBlbmRwYzEgPSAoY2hhcillbmRwYzsKICAgICAgICAgICAgY2hhciBoYW5kbGVyX3BjMSA9IChjaGFyKWhhbmRsZXJfcGM7CiAgICAgICAgICAgIGlmIChzdGFydHBjMSA9PSBzdGFydHBjICYmCiAgICAgICAgICAgICAgICBlbmRwYzEgPT0gZW5kcGMgJiYKICAgICAgICAgICAgICAgIGhhbmRsZXJfcGMxID09IGhhbmRsZXJfcGMpIHsKICAgICAgICAgICAgICAgIGNvZGUuYWRkQ2F0Y2goc3RhcnRwYzEsIGVuZHBjMSwgaGFuZGxlcl9wYzEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjaGFyKWNhdGNoX3R5cGUpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgbG9nLmVycm9yKHBvcywgImxpbWl0LmNvZGUudG9vLmxhcmdlLmZvci50cnkuc3RtdCIpOwogICAgICAgICAgICAgICAgbmVycnMrKzsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdElmKEpDSWYgdHJlZSkgewogICAgICAgIGludCBsaW1pdCA9IGNvZGUubmV4dHJlZzsKICAgICAgICBDaGFpbiB0aGVuRXhpdCA9IG51bGw7CiAgICAgICAgQXNzZXJ0LmNoZWNrKGNvZGUuc3RhdGUuc3RhY2tzaXplID09IDApOwogICAgICAgIENvbmRJdGVtIGMgPSBnZW5Db25kKFRyZWVJbmZvLnNraXBQYXJlbnModHJlZS5jb25kKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDUlRfRkxPV19DT05UUk9MTEVSKTsKICAgICAgICBDaGFpbiBlbHNlQ2hhaW4gPSBjLmp1bXBGYWxzZSgpOwogICAgICAgIEFzc2VydC5jaGVjayhjb2RlLnN0YXRlLnN0YWNrc2l6ZSA9PSAwKTsKICAgICAgICBpZiAoIWMuaXNGYWxzZSgpKSB7CiAgICAgICAgICAgIGNvZGUucmVzb2x2ZShjLnRydWVKdW1wcyk7CiAgICAgICAgICAgIGdlblN0YXQodHJlZS50aGVucGFydCwgZW52LCBDUlRfU1RBVEVNRU5UIHwgQ1JUX0ZMT1dfVEFSR0VUKTsKICAgICAgICAgICAgdGhlbkV4aXQgPSBjb2RlLmJyYW5jaChnb3RvXyk7CiAgICAgICAgfQogICAgICAgIGlmIChlbHNlQ2hhaW4gIT0gbnVsbCkgewogICAgICAgICAgICBjb2RlLnJlc29sdmUoZWxzZUNoYWluKTsKICAgICAgICAgICAgaWYgKHRyZWUuZWxzZXBhcnQgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgZ2VuU3RhdCh0cmVlLmVsc2VwYXJ0LCBlbnYsQ1JUX1NUQVRFTUVOVCB8IENSVF9GTE9XX1RBUkdFVCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgY29kZS5yZXNvbHZlKHRoZW5FeGl0KTsKICAgICAgICBjb2RlLmVuZFNjb3BlcyhsaW1pdCk7CiAgICAgICAgQXNzZXJ0LmNoZWNrKGNvZGUuc3RhdGUuc3RhY2tzaXplID09IDApOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0RXhlYyhKQ0V4cHJlc3Npb25TdGF0ZW1lbnQgdHJlZSkgewogICAgICAgIC8vIE9wdGltaXplIHgrKyB0byArK3ggYW5kIHgtLSB0byAtLXguCiAgICAgICAgSkNFeHByZXNzaW9uIGUgPSB0cmVlLmV4cHI7CiAgICAgICAgc3dpdGNoIChlLmdldFRhZygpKSB7CiAgICAgICAgICAgIGNhc2UgUE9TVElOQzoKICAgICAgICAgICAgICAgICgoSkNVbmFyeSkgZSkuc2V0VGFnKFBSRUlOQyk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBQT1NUREVDOgogICAgICAgICAgICAgICAgKChKQ1VuYXJ5KSBlKS5zZXRUYWcoUFJFREVDKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBBc3NlcnQuY2hlY2soY29kZS5zdGF0ZS5zdGFja3NpemUgPT0gMCk7CiAgICAgICAgZ2VuRXhwcih0cmVlLmV4cHIsIHRyZWUuZXhwci50eXBlKS5kcm9wKCk7CiAgICAgICAgQXNzZXJ0LmNoZWNrKGNvZGUuc3RhdGUuc3RhY2tzaXplID09IDApOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0QnJlYWsoSkNCcmVhayB0cmVlKSB7CiAgICAgICAgRW52PEdlbkNvbnRleHQ+IHRhcmdldEVudiA9IHVud2luZCh0cmVlLnRhcmdldCwgZW52KTsKICAgICAgICBBc3NlcnQuY2hlY2soY29kZS5zdGF0ZS5zdGFja3NpemUgPT0gMCk7CiAgICAgICAgdGFyZ2V0RW52LmluZm8uYWRkRXhpdChjb2RlLmJyYW5jaChnb3RvXykpOwogICAgICAgIGVuZEZpbmFsaXplckdhcHMoZW52LCB0YXJnZXRFbnYpOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0Q29udGludWUoSkNDb250aW51ZSB0cmVlKSB7CiAgICAgICAgRW52PEdlbkNvbnRleHQ+IHRhcmdldEVudiA9IHVud2luZCh0cmVlLnRhcmdldCwgZW52KTsKICAgICAgICBBc3NlcnQuY2hlY2soY29kZS5zdGF0ZS5zdGFja3NpemUgPT0gMCk7CiAgICAgICAgdGFyZ2V0RW52LmluZm8uYWRkQ29udChjb2RlLmJyYW5jaChnb3RvXykpOwogICAgICAgIGVuZEZpbmFsaXplckdhcHMoZW52LCB0YXJnZXRFbnYpOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0UmV0dXJuKEpDUmV0dXJuIHRyZWUpIHsKICAgICAgICBpbnQgbGltaXQgPSBjb2RlLm5leHRyZWc7CiAgICAgICAgZmluYWwgRW52PEdlbkNvbnRleHQ+IHRhcmdldEVudjsKCiAgICAgICAgLyogU2F2ZSBhbmQgdGhlbiByZXN0b3JlIHRoZSBsb2NhdGlvbiBvZiB0aGUgcmV0dXJuIGluIGNhc2UgYSBmaW5hbGx5CiAgICAgICAgICogaXMgZXhwYW5kZWQgKHdpdGggdW53aW5kKCkpIGluIHRoZSBtaWRkbGUgb2Ygb3VyIGJ5dGVjb2Rlcy4KICAgICAgICAgKi8KICAgICAgICBpbnQgdG1wUG9zID0gY29kZS5wZW5kaW5nU3RhdFBvczsKICAgICAgICBpZiAodHJlZS5leHByICE9IG51bGwpIHsKICAgICAgICAgICAgQXNzZXJ0LmNoZWNrKGNvZGUuc3RhdGUuc3RhY2tzaXplID09IDApOwogICAgICAgICAgICBJdGVtIHIgPSBnZW5FeHByKHRyZWUuZXhwciwgcHQpLmxvYWQoKTsKICAgICAgICAgICAgaWYgKGhhc0ZpbmFsbHkoZW52LmVuY2xNZXRob2QsIGVudikpIHsKICAgICAgICAgICAgICAgIHIgPSBtYWtlVGVtcChwdCk7CiAgICAgICAgICAgICAgICByLnN0b3JlKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdGFyZ2V0RW52ID0gdW53aW5kKGVudi5lbmNsTWV0aG9kLCBlbnYpOwogICAgICAgICAgICBjb2RlLnBlbmRpbmdTdGF0UG9zID0gdG1wUG9zOwogICAgICAgICAgICByLmxvYWQoKTsKICAgICAgICAgICAgY29kZS5lbWl0b3AwKGlyZXR1cm4gKyBDb2RlLnRydW5jYXRlKENvZGUudHlwZWNvZGUocHQpKSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgdGFyZ2V0RW52ID0gdW53aW5kKGVudi5lbmNsTWV0aG9kLCBlbnYpOwogICAgICAgICAgICBjb2RlLnBlbmRpbmdTdGF0UG9zID0gdG1wUG9zOwogICAgICAgICAgICBjb2RlLmVtaXRvcDAocmV0dXJuXyk7CiAgICAgICAgfQogICAgICAgIGVuZEZpbmFsaXplckdhcHMoZW52LCB0YXJnZXRFbnYpOwogICAgICAgIGNvZGUuZW5kU2NvcGVzKGxpbWl0KTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdFRocm93KEpDVGhyb3cgdHJlZSkgewogICAgICAgIEFzc2VydC5jaGVjayhjb2RlLnN0YXRlLnN0YWNrc2l6ZSA9PSAwKTsKICAgICAgICBnZW5FeHByKHRyZWUuZXhwciwgdHJlZS5leHByLnR5cGUpLmxvYWQoKTsKICAgICAgICBjb2RlLmVtaXRvcDAoYXRocm93KTsKICAgICAgICBBc3NlcnQuY2hlY2soY29kZS5zdGF0ZS5zdGFja3NpemUgPT0gMCk7CiAgICB9CgovKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogVmlzaXRvciBtZXRob2RzIGZvciBleHByZXNzaW9ucwogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiAgICBwdWJsaWMgdm9pZCB2aXNpdEFwcGx5KEpDTWV0aG9kSW52b2NhdGlvbiB0cmVlKSB7CiAgICAgICAgc2V0VHlwZUFubm90YXRpb25Qb3NpdGlvbnModHJlZS5wb3MpOwogICAgICAgIC8vIEdlbmVyYXRlIGNvZGUgZm9yIG1ldGhvZC4KICAgICAgICBJdGVtIG0gPSBnZW5FeHByKHRyZWUubWV0aCwgbWV0aG9kVHlwZSk7CiAgICAgICAgLy8gR2VuZXJhdGUgY29kZSBmb3IgYWxsIGFyZ3VtZW50cywgd2hlcmUgdGhlIGV4cGVjdGVkIHR5cGVzIGFyZQogICAgICAgIC8vIHRoZSBwYXJhbWV0ZXJzIG9mIHRoZSBtZXRob2QncyBleHRlcm5hbCB0eXBlICh0aGF0IGlzLCBhbnkgaW1wbGljaXQKICAgICAgICAvLyBvdXRlciBpbnN0YW5jZSBvZiBhIHN1cGVyKC4uLikgY2FsbCBhcHBlYXJzIGFzIGZpcnN0IHBhcmFtZXRlcikuCiAgICAgICAgTWV0aG9kU3ltYm9sIG1zeW0gPSAoTWV0aG9kU3ltYm9sKVRyZWVJbmZvLnN5bWJvbCh0cmVlLm1ldGgpOwogICAgICAgIGdlbkFyZ3ModHJlZS5hcmdzLAogICAgICAgICAgICAgICAgbXN5bS5leHRlcm5hbFR5cGUodHlwZXMpLmdldFBhcmFtZXRlclR5cGVzKCkpOwogICAgICAgIGlmICghbXN5bS5pc0R5bmFtaWMoKSkgewogICAgICAgICAgICBjb2RlLnN0YXRCZWdpbih0cmVlLnBvcyk7CiAgICAgICAgfQogICAgICAgIHJlc3VsdCA9IG0uaW52b2tlKCk7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRDb25kaXRpb25hbChKQ0NvbmRpdGlvbmFsIHRyZWUpIHsKICAgICAgICBDaGFpbiB0aGVuRXhpdCA9IG51bGw7CiAgICAgICAgY29kZS5zdGF0QmVnaW4odHJlZS5jb25kLnBvcyk7CiAgICAgICAgQ29uZEl0ZW0gYyA9IGdlbkNvbmQodHJlZS5jb25kLCBDUlRfRkxPV19DT05UUk9MTEVSKTsKICAgICAgICBDaGFpbiBlbHNlQ2hhaW4gPSBjLmp1bXBGYWxzZSgpOwogICAgICAgIGlmICghYy5pc0ZhbHNlKCkpIHsKICAgICAgICAgICAgY29kZS5yZXNvbHZlKGMudHJ1ZUp1bXBzKTsKICAgICAgICAgICAgaW50IHN0YXJ0cGMgPSBnZW5DcnQgPyBjb2RlLmN1ckNQKCkgOiAwOwogICAgICAgICAgICBjb2RlLnN0YXRCZWdpbih0cmVlLnRydWVwYXJ0LnBvcyk7CiAgICAgICAgICAgIGdlbkV4cHIodHJlZS50cnVlcGFydCwgcHQpLmxvYWQoKTsKICAgICAgICAgICAgY29kZS5zdGF0ZS5mb3JjZVN0YWNrVG9wKHRyZWUudHlwZSk7CiAgICAgICAgICAgIGlmIChnZW5DcnQpIGNvZGUuY3J0LnB1dCh0cmVlLnRydWVwYXJ0LCBDUlRfRkxPV19UQVJHRVQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGFydHBjLCBjb2RlLmN1ckNQKCkpOwogICAgICAgICAgICB0aGVuRXhpdCA9IGNvZGUuYnJhbmNoKGdvdG9fKTsKICAgICAgICB9CiAgICAgICAgaWYgKGVsc2VDaGFpbiAhPSBudWxsKSB7CiAgICAgICAgICAgIGNvZGUucmVzb2x2ZShlbHNlQ2hhaW4pOwogICAgICAgICAgICBpbnQgc3RhcnRwYyA9IGdlbkNydCA/IGNvZGUuY3VyQ1AoKSA6IDA7CiAgICAgICAgICAgIGNvZGUuc3RhdEJlZ2luKHRyZWUuZmFsc2VwYXJ0LnBvcyk7CiAgICAgICAgICAgIGdlbkV4cHIodHJlZS5mYWxzZXBhcnQsIHB0KS5sb2FkKCk7CiAgICAgICAgICAgIGNvZGUuc3RhdGUuZm9yY2VTdGFja1RvcCh0cmVlLnR5cGUpOwogICAgICAgICAgICBpZiAoZ2VuQ3J0KSBjb2RlLmNydC5wdXQodHJlZS5mYWxzZXBhcnQsIENSVF9GTE9XX1RBUkdFVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0cGMsIGNvZGUuY3VyQ1AoKSk7CiAgICAgICAgfQogICAgICAgIGNvZGUucmVzb2x2ZSh0aGVuRXhpdCk7CiAgICAgICAgcmVzdWx0ID0gaXRlbXMubWFrZVN0YWNrSXRlbShwdCk7CiAgICB9CgogICAgcHJpdmF0ZSB2b2lkIHNldFR5cGVBbm5vdGF0aW9uUG9zaXRpb25zKGludCB0cmVlUG9zKSB7CiAgICAgICAgTWV0aG9kU3ltYm9sIG1ldGggPSBjb2RlLm1ldGg7CiAgICAgICAgYm9vbGVhbiBpbml0T3JDbGluaXQgPSBjb2RlLm1ldGguZ2V0S2luZCgpID09IGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC5FbGVtZW50S2luZC5DT05TVFJVQ1RPUgogICAgICAgICAgICAgICAgfHwgY29kZS5tZXRoLmdldEtpbmQoKSA9PSBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuRWxlbWVudEtpbmQuU1RBVElDX0lOSVQ7CgogICAgICAgIGZvciAoQXR0cmlidXRlLlR5cGVDb21wb3VuZCB0YSA6IG1ldGguZ2V0UmF3VHlwZUF0dHJpYnV0ZXMoKSkgewogICAgICAgICAgICBpZiAodGEuaGFzVW5rbm93blBvc2l0aW9uKCkpCiAgICAgICAgICAgICAgICB0YS50cnlGaXhQb3NpdGlvbigpOwoKICAgICAgICAgICAgaWYgKHRhLnBvc2l0aW9uLm1hdGNoZXNQb3ModHJlZVBvcykpCiAgICAgICAgICAgICAgICB0YS5wb3NpdGlvbi51cGRhdGVQb3NPZmZzZXQoY29kZS5jcCk7CiAgICAgICAgfQoKICAgICAgICBpZiAoIWluaXRPckNsaW5pdCkKICAgICAgICAgICAgcmV0dXJuOwoKICAgICAgICBmb3IgKEF0dHJpYnV0ZS5UeXBlQ29tcG91bmQgdGEgOiBtZXRoLm93bmVyLmdldFJhd1R5cGVBdHRyaWJ1dGVzKCkpIHsKICAgICAgICAgICAgaWYgKHRhLmhhc1Vua25vd25Qb3NpdGlvbigpKQogICAgICAgICAgICAgICAgdGEudHJ5Rml4UG9zaXRpb24oKTsKCiAgICAgICAgICAgIGlmICh0YS5wb3NpdGlvbi5tYXRjaGVzUG9zKHRyZWVQb3MpKQogICAgICAgICAgICAgICAgdGEucG9zaXRpb24udXBkYXRlUG9zT2Zmc2V0KGNvZGUuY3ApOwogICAgICAgIH0KCiAgICAgICAgQ2xhc3NTeW1ib2wgY2xhenogPSBtZXRoLmVuY2xDbGFzcygpOwogICAgICAgIGZvciAoU3ltYm9sIHMgOiBuZXcgY29tLnN1bi50b29scy5qYXZhYy5tb2RlbC5GaWx0ZXJlZE1lbWJlckxpc3QoY2xhenoubWVtYmVycygpKSkgewogICAgICAgICAgICBpZiAoIXMuZ2V0S2luZCgpLmlzRmllbGQoKSkKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwoKICAgICAgICAgICAgZm9yIChBdHRyaWJ1dGUuVHlwZUNvbXBvdW5kIHRhIDogcy5nZXRSYXdUeXBlQXR0cmlidXRlcygpKSB7CiAgICAgICAgICAgICAgICBpZiAodGEuaGFzVW5rbm93blBvc2l0aW9uKCkpCiAgICAgICAgICAgICAgICAgICAgdGEudHJ5Rml4UG9zaXRpb24oKTsKCiAgICAgICAgICAgICAgICBpZiAodGEucG9zaXRpb24ubWF0Y2hlc1Bvcyh0cmVlUG9zKSkKICAgICAgICAgICAgICAgICAgICB0YS5wb3NpdGlvbi51cGRhdGVQb3NPZmZzZXQoY29kZS5jcCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXROZXdDbGFzcyhKQ05ld0NsYXNzIHRyZWUpIHsKICAgICAgICAvLyBFbmNsb3NpbmcgaW5zdGFuY2VzIG9yIGFub255bW91cyBjbGFzc2VzIHNob3VsZCBoYXZlIGJlZW4gZWxpbWluYXRlZAogICAgICAgIC8vIGJ5IG5vdy4KICAgICAgICBBc3NlcnQuY2hlY2sodHJlZS5lbmNsID09IG51bGwgJiYgdHJlZS5kZWYgPT0gbnVsbCk7CiAgICAgICAgc2V0VHlwZUFubm90YXRpb25Qb3NpdGlvbnModHJlZS5wb3MpOwoKICAgICAgICBjb2RlLmVtaXRvcDIobmV3XywgbWFrZVJlZih0cmVlLnBvcygpLCB0cmVlLnR5cGUpKTsKICAgICAgICBjb2RlLmVtaXRvcDAoZHVwKTsKCiAgICAgICAgLy8gR2VuZXJhdGUgY29kZSBmb3IgYWxsIGFyZ3VtZW50cywgd2hlcmUgdGhlIGV4cGVjdGVkIHR5cGVzIGFyZQogICAgICAgIC8vIHRoZSBwYXJhbWV0ZXJzIG9mIHRoZSBjb25zdHJ1Y3RvcidzIGV4dGVybmFsIHR5cGUgKHRoYXQgaXMsCiAgICAgICAgLy8gYW55IGltcGxpY2l0IG91dGVyIGluc3RhbmNlIGFwcGVhcnMgYXMgZmlyc3QgcGFyYW1ldGVyKS4KICAgICAgICBnZW5BcmdzKHRyZWUuYXJncywgdHJlZS5jb25zdHJ1Y3Rvci5leHRlcm5hbFR5cGUodHlwZXMpLmdldFBhcmFtZXRlclR5cGVzKCkpOwoKICAgICAgICBpdGVtcy5tYWtlTWVtYmVySXRlbSh0cmVlLmNvbnN0cnVjdG9yLCB0cnVlKS5pbnZva2UoKTsKICAgICAgICByZXN1bHQgPSBpdGVtcy5tYWtlU3RhY2tJdGVtKHRyZWUudHlwZSk7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXROZXdBcnJheShKQ05ld0FycmF5IHRyZWUpIHsKICAgICAgICBzZXRUeXBlQW5ub3RhdGlvblBvc2l0aW9ucyh0cmVlLnBvcyk7CgogICAgICAgIGlmICh0cmVlLmVsZW1zICE9IG51bGwpIHsKICAgICAgICAgICAgVHlwZSBlbGVtdHlwZSA9IHR5cGVzLmVsZW10eXBlKHRyZWUudHlwZSk7CiAgICAgICAgICAgIGxvYWRJbnRDb25zdCh0cmVlLmVsZW1zLmxlbmd0aCgpKTsKICAgICAgICAgICAgSXRlbSBhcnIgPSBtYWtlTmV3QXJyYXkodHJlZS5wb3MoKSwgdHJlZS50eXBlLCAxKTsKICAgICAgICAgICAgaW50IGkgPSAwOwogICAgICAgICAgICBmb3IgKExpc3Q8SkNFeHByZXNzaW9uPiBsID0gdHJlZS5lbGVtczsgbC5ub25FbXB0eSgpOyBsID0gbC50YWlsKSB7CiAgICAgICAgICAgICAgICBhcnIuZHVwbGljYXRlKCk7CiAgICAgICAgICAgICAgICBsb2FkSW50Q29uc3QoaSk7CiAgICAgICAgICAgICAgICBpKys7CiAgICAgICAgICAgICAgICBnZW5FeHByKGwuaGVhZCwgZWxlbXR5cGUpLmxvYWQoKTsKICAgICAgICAgICAgICAgIGl0ZW1zLm1ha2VJbmRleGVkSXRlbShlbGVtdHlwZSkuc3RvcmUoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXN1bHQgPSBhcnI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZm9yIChMaXN0PEpDRXhwcmVzc2lvbj4gbCA9IHRyZWUuZGltczsgbC5ub25FbXB0eSgpOyBsID0gbC50YWlsKSB7CiAgICAgICAgICAgICAgICBnZW5FeHByKGwuaGVhZCwgc3ltcy5pbnRUeXBlKS5sb2FkKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmVzdWx0ID0gbWFrZU5ld0FycmF5KHRyZWUucG9zKCksIHRyZWUudHlwZSwgdHJlZS5kaW1zLmxlbmd0aCgpKTsKICAgICAgICB9CiAgICB9Ci8vd2hlcmUKICAgICAgICAvKiogR2VuZXJhdGUgY29kZSB0byBjcmVhdGUgYW4gYXJyYXkgd2l0aCBnaXZlbiBlbGVtZW50IHR5cGUgYW5kIG51bWJlcgogICAgICAgICAqICBvZiBkaW1lbnNpb25zLgogICAgICAgICAqLwogICAgICAgIEl0ZW0gbWFrZU5ld0FycmF5KERpYWdub3N0aWNQb3NpdGlvbiBwb3MsIFR5cGUgdHlwZSwgaW50IG5kaW1zKSB7CiAgICAgICAgICAgIFR5cGUgZWxlbXR5cGUgPSB0eXBlcy5lbGVtdHlwZSh0eXBlKTsKICAgICAgICAgICAgaWYgKHR5cGVzLmRpbWVuc2lvbnModHlwZSkgPiBDbGFzc0ZpbGUuTUFYX0RJTUVOU0lPTlMpIHsKICAgICAgICAgICAgICAgIGxvZy5lcnJvcihwb3MsICJsaW1pdC5kaW1lbnNpb25zIik7CiAgICAgICAgICAgICAgICBuZXJycysrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGludCBlbGVtY29kZSA9IENvZGUuYXJyYXljb2RlKGVsZW10eXBlKTsKICAgICAgICAgICAgaWYgKGVsZW1jb2RlID09IDAgfHwgKGVsZW1jb2RlID09IDEgJiYgbmRpbXMgPT0gMSkpIHsKICAgICAgICAgICAgICAgIGNvZGUuZW1pdEFuZXdhcnJheShtYWtlUmVmKHBvcywgZWxlbXR5cGUpLCB0eXBlKTsKICAgICAgICAgICAgfSBlbHNlIGlmIChlbGVtY29kZSA9PSAxKSB7CiAgICAgICAgICAgICAgICBjb2RlLmVtaXRNdWx0aWFuZXdhcnJheShuZGltcywgbWFrZVJlZihwb3MsIHR5cGUpLCB0eXBlKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGNvZGUuZW1pdE5ld2FycmF5KGVsZW1jb2RlLCB0eXBlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gaXRlbXMubWFrZVN0YWNrSXRlbSh0eXBlKTsKICAgICAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRQYXJlbnMoSkNQYXJlbnMgdHJlZSkgewogICAgICAgIHJlc3VsdCA9IGdlbkV4cHIodHJlZS5leHByLCB0cmVlLmV4cHIudHlwZSk7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRBc3NpZ24oSkNBc3NpZ24gdHJlZSkgewogICAgICAgIEl0ZW0gbCA9IGdlbkV4cHIodHJlZS5saHMsIHRyZWUubGhzLnR5cGUpOwogICAgICAgIGdlbkV4cHIodHJlZS5yaHMsIHRyZWUubGhzLnR5cGUpLmxvYWQoKTsKICAgICAgICBpZiAodHJlZS5yaHMudHlwZS5oYXNUYWcoQk9UKSkgewogICAgICAgICAgICAvKiBUaGlzIGlzIGp1c3QgYSBjYXNlIG9mIHdpZGVuaW5nIHJlZmVyZW5jZSBjb252ZXJzaW9uIHRoYXQgcGVyIDUuMS41IHNpbXBseSBjYWxscwogICAgICAgICAgICAgICBmb3IgInJlZ2FyZGluZyBhIHJlZmVyZW5jZSBhcyBoYXZpbmcgc29tZSBvdGhlciB0eXBlIGluIGEgbWFubmVyIHRoYXQgY2FuIGJlIHByb3ZlZAogICAgICAgICAgICAgICBjb3JyZWN0IGF0IGNvbXBpbGUgdGltZS4iCiAgICAgICAgICAgICovCiAgICAgICAgICAgIGNvZGUuc3RhdGUuZm9yY2VTdGFja1RvcCh0cmVlLmxocy50eXBlKTsKICAgICAgICB9CiAgICAgICAgcmVzdWx0ID0gaXRlbXMubWFrZUFzc2lnbkl0ZW0obCk7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRBc3NpZ25vcChKQ0Fzc2lnbk9wIHRyZWUpIHsKICAgICAgICBPcGVyYXRvclN5bWJvbCBvcGVyYXRvciA9IHRyZWUub3BlcmF0b3I7CiAgICAgICAgSXRlbSBsOwogICAgICAgIGlmIChvcGVyYXRvci5vcGNvZGUgPT0gc3RyaW5nX2FkZCkgewogICAgICAgICAgICBsID0gY29uY2F0Lm1ha2VDb25jYXQodHJlZSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLy8gR2VuZXJhdGUgY29kZSBmb3IgZmlyc3QgZXhwcmVzc2lvbgogICAgICAgICAgICBsID0gZ2VuRXhwcih0cmVlLmxocywgdHJlZS5saHMudHlwZSk7CgogICAgICAgICAgICAvLyBJZiB3ZSBoYXZlIGFuIGluY3JlbWVudCBvZiAtMzI3NjggdG8gKzMyNzY3IG9mIGEgbG9jYWwKICAgICAgICAgICAgLy8gaW50IHZhcmlhYmxlIHdlIGNhbiB1c2UgYW4gaW5jciBpbnN0cnVjdGlvbiBpbnN0ZWFkIG9mCiAgICAgICAgICAgIC8vIHByb2NlZWRpbmcgZnVydGhlci4KICAgICAgICAgICAgaWYgKCh0cmVlLmhhc1RhZyhQTFVTX0FTRykgfHwgdHJlZS5oYXNUYWcoTUlOVVNfQVNHKSkgJiYKICAgICAgICAgICAgICAgIGwgaW5zdGFuY2VvZiBMb2NhbEl0ZW0gJiYKICAgICAgICAgICAgICAgIHRyZWUubGhzLnR5cGUuZ2V0VGFnKCkuaXNTdWJSYW5nZU9mKElOVCkgJiYKICAgICAgICAgICAgICAgIHRyZWUucmhzLnR5cGUuZ2V0VGFnKCkuaXNTdWJSYW5nZU9mKElOVCkgJiYKICAgICAgICAgICAgICAgIHRyZWUucmhzLnR5cGUuY29uc3RWYWx1ZSgpICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIGludCBpdmFsID0gKChOdW1iZXIpIHRyZWUucmhzLnR5cGUuY29uc3RWYWx1ZSgpKS5pbnRWYWx1ZSgpOwogICAgICAgICAgICAgICAgaWYgKHRyZWUuaGFzVGFnKE1JTlVTX0FTRykpIGl2YWwgPSAtaXZhbDsKICAgICAgICAgICAgICAgICgoTG9jYWxJdGVtKWwpLmluY3IoaXZhbCk7CiAgICAgICAgICAgICAgICByZXN1bHQgPSBsOwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIE90aGVyd2lzZSwgZHVwbGljYXRlIGV4cHJlc3Npb24sIGxvYWQgb25lIGNvcHkKICAgICAgICAgICAgLy8gYW5kIGNvbXBsZXRlIGJpbmFyeSBvcGVyYXRpb24uCiAgICAgICAgICAgIGwuZHVwbGljYXRlKCk7CiAgICAgICAgICAgIGwuY29lcmNlKG9wZXJhdG9yLnR5cGUuZ2V0UGFyYW1ldGVyVHlwZXMoKS5oZWFkKS5sb2FkKCk7CiAgICAgICAgICAgIGNvbXBsZXRlQmlub3AodHJlZS5saHMsIHRyZWUucmhzLCBvcGVyYXRvcikuY29lcmNlKHRyZWUubGhzLnR5cGUpOwogICAgICAgIH0KICAgICAgICByZXN1bHQgPSBpdGVtcy5tYWtlQXNzaWduSXRlbShsKTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdFVuYXJ5KEpDVW5hcnkgdHJlZSkgewogICAgICAgIE9wZXJhdG9yU3ltYm9sIG9wZXJhdG9yID0gdHJlZS5vcGVyYXRvcjsKICAgICAgICBpZiAodHJlZS5oYXNUYWcoTk9UKSkgewogICAgICAgICAgICBDb25kSXRlbSBvZCA9IGdlbkNvbmQodHJlZS5hcmcsIGZhbHNlKTsKICAgICAgICAgICAgcmVzdWx0ID0gb2QubmVnYXRlKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgSXRlbSBvZCA9IGdlbkV4cHIodHJlZS5hcmcsIG9wZXJhdG9yLnR5cGUuZ2V0UGFyYW1ldGVyVHlwZXMoKS5oZWFkKTsKICAgICAgICAgICAgc3dpdGNoICh0cmVlLmdldFRhZygpKSB7CiAgICAgICAgICAgIGNhc2UgUE9TOgogICAgICAgICAgICAgICAgcmVzdWx0ID0gb2QubG9hZCgpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgTkVHOgogICAgICAgICAgICAgICAgcmVzdWx0ID0gb2QubG9hZCgpOwogICAgICAgICAgICAgICAgY29kZS5lbWl0b3AwKG9wZXJhdG9yLm9wY29kZSk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBDT01QTDoKICAgICAgICAgICAgICAgIHJlc3VsdCA9IG9kLmxvYWQoKTsKICAgICAgICAgICAgICAgIGVtaXRNaW51c09uZShvZC50eXBlY29kZSk7CiAgICAgICAgICAgICAgICBjb2RlLmVtaXRvcDAob3BlcmF0b3Iub3Bjb2RlKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFBSRUlOQzogY2FzZSBQUkVERUM6CiAgICAgICAgICAgICAgICBvZC5kdXBsaWNhdGUoKTsKICAgICAgICAgICAgICAgIGlmIChvZCBpbnN0YW5jZW9mIExvY2FsSXRlbSAmJgogICAgICAgICAgICAgICAgICAgIChvcGVyYXRvci5vcGNvZGUgPT0gaWFkZCB8fCBvcGVyYXRvci5vcGNvZGUgPT0gaXN1YikpIHsKICAgICAgICAgICAgICAgICAgICAoKExvY2FsSXRlbSlvZCkuaW5jcih0cmVlLmhhc1RhZyhQUkVJTkMpID8gMSA6IC0xKTsKICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBvZDsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgb2QubG9hZCgpOwogICAgICAgICAgICAgICAgICAgIGNvZGUuZW1pdG9wMChvbmUob2QudHlwZWNvZGUpKTsKICAgICAgICAgICAgICAgICAgICBjb2RlLmVtaXRvcDAob3BlcmF0b3Iub3Bjb2RlKTsKICAgICAgICAgICAgICAgICAgICAvLyBQZXJmb3JtIG5hcnJvd2luZyBwcmltaXRpdmUgY29udmVyc2lvbiBpZiBieXRlLAogICAgICAgICAgICAgICAgICAgIC8vIGNoYXIsIG9yIHNob3J0LiAgRml4IGZvciA0MzA0NjU1LgogICAgICAgICAgICAgICAgICAgIGlmIChvZC50eXBlY29kZSAhPSBJTlRjb2RlICYmCiAgICAgICAgICAgICAgICAgICAgICAgIENvZGUudHJ1bmNhdGUob2QudHlwZWNvZGUpID09IElOVGNvZGUpCiAgICAgICAgICAgICAgICAgICAgICBjb2RlLmVtaXRvcDAoaW50MmJ5dGUgKyBvZC50eXBlY29kZSAtIEJZVEVjb2RlKTsKICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBpdGVtcy5tYWtlQXNzaWduSXRlbShvZCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBQT1NUSU5DOiBjYXNlIFBPU1RERUM6CiAgICAgICAgICAgICAgICBvZC5kdXBsaWNhdGUoKTsKICAgICAgICAgICAgICAgIGlmIChvZCBpbnN0YW5jZW9mIExvY2FsSXRlbSAmJgogICAgICAgICAgICAgICAgICAgIChvcGVyYXRvci5vcGNvZGUgPT0gaWFkZCB8fCBvcGVyYXRvci5vcGNvZGUgPT0gaXN1YikpIHsKICAgICAgICAgICAgICAgICAgICBJdGVtIHJlcyA9IG9kLmxvYWQoKTsKICAgICAgICAgICAgICAgICAgICAoKExvY2FsSXRlbSlvZCkuaW5jcih0cmVlLmhhc1RhZyhQT1NUSU5DKSA/IDEgOiAtMSk7CiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gcmVzOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBJdGVtIHJlcyA9IG9kLmxvYWQoKTsKICAgICAgICAgICAgICAgICAgICBvZC5zdGFzaChvZC50eXBlY29kZSk7CiAgICAgICAgICAgICAgICAgICAgY29kZS5lbWl0b3AwKG9uZShvZC50eXBlY29kZSkpOwogICAgICAgICAgICAgICAgICAgIGNvZGUuZW1pdG9wMChvcGVyYXRvci5vcGNvZGUpOwogICAgICAgICAgICAgICAgICAgIC8vIFBlcmZvcm0gbmFycm93aW5nIHByaW1pdGl2ZSBjb252ZXJzaW9uIGlmIGJ5dGUsCiAgICAgICAgICAgICAgICAgICAgLy8gY2hhciwgb3Igc2hvcnQuICBGaXggZm9yIDQzMDQ2NTUuCiAgICAgICAgICAgICAgICAgICAgaWYgKG9kLnR5cGVjb2RlICE9IElOVGNvZGUgJiYKICAgICAgICAgICAgICAgICAgICAgICAgQ29kZS50cnVuY2F0ZShvZC50eXBlY29kZSkgPT0gSU5UY29kZSkKICAgICAgICAgICAgICAgICAgICAgIGNvZGUuZW1pdG9wMChpbnQyYnl0ZSArIG9kLnR5cGVjb2RlIC0gQllURWNvZGUpOwogICAgICAgICAgICAgICAgICAgIG9kLnN0b3JlKCk7CiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gcmVzOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgTlVMTENISzoKICAgICAgICAgICAgICAgIHJlc3VsdCA9IG9kLmxvYWQoKTsKICAgICAgICAgICAgICAgIGNvZGUuZW1pdG9wMChkdXApOwogICAgICAgICAgICAgICAgZ2VuTnVsbENoZWNrKHRyZWUucG9zKCkpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICBBc3NlcnQuZXJyb3IoKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKiogR2VuZXJhdGUgYSBudWxsIGNoZWNrIGZyb20gdGhlIG9iamVjdCB2YWx1ZSBhdCBzdGFjayB0b3AuICovCiAgICBwcml2YXRlIHZvaWQgZ2VuTnVsbENoZWNrKERpYWdub3N0aWNQb3NpdGlvbiBwb3MpIHsKICAgICAgICBpZiAoYWxsb3dCZXR0ZXJOdWxsQ2hlY2tzKSB7CiAgICAgICAgICAgIGNhbGxNZXRob2QocG9zLCBzeW1zLm9iamVjdHNUeXBlLCBuYW1lcy5yZXF1aXJlTm9uTnVsbCwKICAgICAgICAgICAgICAgICAgICBMaXN0Lm9mKHN5bXMub2JqZWN0VHlwZSksIHRydWUpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGNhbGxNZXRob2QocG9zLCBzeW1zLm9iamVjdFR5cGUsIG5hbWVzLmdldENsYXNzLAogICAgICAgICAgICAgICAgICAgIExpc3QubmlsKCksIGZhbHNlKTsKICAgICAgICB9CiAgICAgICAgY29kZS5lbWl0b3AwKHBvcCk7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRCaW5hcnkoSkNCaW5hcnkgdHJlZSkgewogICAgICAgIE9wZXJhdG9yU3ltYm9sIG9wZXJhdG9yID0gdHJlZS5vcGVyYXRvcjsKICAgICAgICBpZiAob3BlcmF0b3Iub3Bjb2RlID09IHN0cmluZ19hZGQpIHsKICAgICAgICAgICAgcmVzdWx0ID0gY29uY2F0Lm1ha2VDb25jYXQodHJlZSk7CiAgICAgICAgfSBlbHNlIGlmICh0cmVlLmhhc1RhZyhBTkQpKSB7CiAgICAgICAgICAgIENvbmRJdGVtIGxjb25kID0gZ2VuQ29uZCh0cmVlLmxocywgQ1JUX0ZMT1dfQ09OVFJPTExFUik7CiAgICAgICAgICAgIGlmICghbGNvbmQuaXNGYWxzZSgpKSB7CiAgICAgICAgICAgICAgICBDaGFpbiBmYWxzZUp1bXBzID0gbGNvbmQuanVtcEZhbHNlKCk7CiAgICAgICAgICAgICAgICBjb2RlLnJlc29sdmUobGNvbmQudHJ1ZUp1bXBzKTsKICAgICAgICAgICAgICAgIENvbmRJdGVtIHJjb25kID0gZ2VuQ29uZCh0cmVlLnJocywgQ1JUX0ZMT1dfVEFSR0VUKTsKICAgICAgICAgICAgICAgIHJlc3VsdCA9IGl0ZW1zLgogICAgICAgICAgICAgICAgICAgIG1ha2VDb25kSXRlbShyY29uZC5vcGNvZGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJjb25kLnRydWVKdW1wcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29kZS5tZXJnZUNoYWlucyhmYWxzZUp1bXBzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJjb25kLmZhbHNlSnVtcHMpKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHJlc3VsdCA9IGxjb25kOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmICh0cmVlLmhhc1RhZyhPUikpIHsKICAgICAgICAgICAgQ29uZEl0ZW0gbGNvbmQgPSBnZW5Db25kKHRyZWUubGhzLCBDUlRfRkxPV19DT05UUk9MTEVSKTsKICAgICAgICAgICAgaWYgKCFsY29uZC5pc1RydWUoKSkgewogICAgICAgICAgICAgICAgQ2hhaW4gdHJ1ZUp1bXBzID0gbGNvbmQuanVtcFRydWUoKTsKICAgICAgICAgICAgICAgIGNvZGUucmVzb2x2ZShsY29uZC5mYWxzZUp1bXBzKTsKICAgICAgICAgICAgICAgIENvbmRJdGVtIHJjb25kID0gZ2VuQ29uZCh0cmVlLnJocywgQ1JUX0ZMT1dfVEFSR0VUKTsKICAgICAgICAgICAgICAgIHJlc3VsdCA9IGl0ZW1zLgogICAgICAgICAgICAgICAgICAgIG1ha2VDb25kSXRlbShyY29uZC5vcGNvZGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvZGUubWVyZ2VDaGFpbnModHJ1ZUp1bXBzLCByY29uZC50cnVlSnVtcHMpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByY29uZC5mYWxzZUp1bXBzKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHJlc3VsdCA9IGxjb25kOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgSXRlbSBvZCA9IGdlbkV4cHIodHJlZS5saHMsIG9wZXJhdG9yLnR5cGUuZ2V0UGFyYW1ldGVyVHlwZXMoKS5oZWFkKTsKICAgICAgICAgICAgb2QubG9hZCgpOwogICAgICAgICAgICByZXN1bHQgPSBjb21wbGV0ZUJpbm9wKHRyZWUubGhzLCB0cmVlLnJocywgb3BlcmF0b3IpOwogICAgICAgIH0KICAgIH0KCgogICAgICAgIC8qKiBDb21wbGV0ZSBnZW5lcmF0aW5nIGNvZGUgZm9yIG9wZXJhdGlvbiwgd2l0aCBsZWZ0IG9wZXJhbmQKICAgICAgICAgKiAgYWxyZWFkeSBvbiBzdGFjay4KICAgICAgICAgKiAgQHBhcmFtIGxocyAgICAgICBUaGUgdHJlZSByZXByZXNlbnRpbmcgdGhlIGxlZnQgb3BlcmFuZC4KICAgICAgICAgKiAgQHBhcmFtIHJocyAgICAgICBUaGUgdHJlZSByZXByZXNlbnRpbmcgdGhlIHJpZ2h0IG9wZXJhbmQuCiAgICAgICAgICogIEBwYXJhbSBvcGVyYXRvciAgVGhlIG9wZXJhdG9yIHN5bWJvbC4KICAgICAgICAgKi8KICAgICAgICBJdGVtIGNvbXBsZXRlQmlub3AoSkNUcmVlIGxocywgSkNUcmVlIHJocywgT3BlcmF0b3JTeW1ib2wgb3BlcmF0b3IpIHsKICAgICAgICAgICAgTWV0aG9kVHlwZSBvcHR5cGUgPSAoTWV0aG9kVHlwZSlvcGVyYXRvci50eXBlOwogICAgICAgICAgICBpbnQgb3Bjb2RlID0gb3BlcmF0b3Iub3Bjb2RlOwogICAgICAgICAgICBpZiAob3Bjb2RlID49IGlmX2ljbXBlcSAmJiBvcGNvZGUgPD0gaWZfaWNtcGxlICYmCiAgICAgICAgICAgICAgICByaHMudHlwZS5jb25zdFZhbHVlKCkgaW5zdGFuY2VvZiBOdW1iZXIgJiYKICAgICAgICAgICAgICAgICgoTnVtYmVyKSByaHMudHlwZS5jb25zdFZhbHVlKCkpLmludFZhbHVlKCkgPT0gMCkgewogICAgICAgICAgICAgICAgb3Bjb2RlID0gb3Bjb2RlICsgKGlmZXEgLSBpZl9pY21wZXEpOwogICAgICAgICAgICB9IGVsc2UgaWYgKG9wY29kZSA+PSBpZl9hY21wZXEgJiYgb3Bjb2RlIDw9IGlmX2FjbXBuZSAmJgogICAgICAgICAgICAgICAgICAgICAgIFRyZWVJbmZvLmlzTnVsbChyaHMpKSB7CiAgICAgICAgICAgICAgICBvcGNvZGUgPSBvcGNvZGUgKyAoaWZfYWNtcF9udWxsIC0gaWZfYWNtcGVxKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIC8vIFRoZSBleHBlY3RlZCB0eXBlIG9mIHRoZSByaWdodCBvcGVyYW5kIGlzCiAgICAgICAgICAgICAgICAvLyB0aGUgc2Vjb25kIHBhcmFtZXRlciB0eXBlIG9mIHRoZSBvcGVyYXRvciwgZXhjZXB0IGZvcgogICAgICAgICAgICAgICAgLy8gc2hpZnRzIHdpdGggbG9uZyBzaGlmdGNvdW50LCB3aGVyZSB3ZSBjb252ZXJ0IHRoZSBvcGNvZGUKICAgICAgICAgICAgICAgIC8vIHRvIGEgc2hvcnQgc2hpZnQgYW5kIHRoZSBleHBlY3RlZCB0eXBlIHRvIGludC4KICAgICAgICAgICAgICAgIFR5cGUgcnR5cGUgPSBvcGVyYXRvci5lcmFzdXJlKHR5cGVzKS5nZXRQYXJhbWV0ZXJUeXBlcygpLnRhaWwuaGVhZDsKICAgICAgICAgICAgICAgIGlmIChvcGNvZGUgPj0gaXNobGwgJiYgb3Bjb2RlIDw9IGx1c2hybCkgewogICAgICAgICAgICAgICAgICAgIG9wY29kZSA9IG9wY29kZSArIChpc2hsIC0gaXNobGwpOwogICAgICAgICAgICAgICAgICAgIHJ0eXBlID0gc3ltcy5pbnRUeXBlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgLy8gR2VuZXJhdGUgY29kZSBmb3IgcmlnaHQgb3BlcmFuZCBhbmQgbG9hZC4KICAgICAgICAgICAgICAgIGdlbkV4cHIocmhzLCBydHlwZSkubG9hZCgpOwogICAgICAgICAgICAgICAgLy8gSWYgdGhlcmUgYXJlIHR3byBjb25zZWN1dGl2ZSBvcGNvZGUgaW5zdHJ1Y3Rpb25zLAogICAgICAgICAgICAgICAgLy8gZW1pdCB0aGUgZmlyc3Qgbm93LgogICAgICAgICAgICAgICAgaWYgKG9wY29kZSA+PSAoMSA8PCBwcmVTaGlmdCkpIHsKICAgICAgICAgICAgICAgICAgICBjb2RlLmVtaXRvcDAob3Bjb2RlID4+IHByZVNoaWZ0KTsKICAgICAgICAgICAgICAgICAgICBvcGNvZGUgPSBvcGNvZGUgJiAweEZGOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChvcGNvZGUgPj0gaWZlcSAmJiBvcGNvZGUgPD0gaWZfYWNtcG5lIHx8CiAgICAgICAgICAgICAgICBvcGNvZGUgPT0gaWZfYWNtcF9udWxsIHx8IG9wY29kZSA9PSBpZl9hY21wX25vbm51bGwpIHsKICAgICAgICAgICAgICAgIHJldHVybiBpdGVtcy5tYWtlQ29uZEl0ZW0ob3Bjb2RlKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGNvZGUuZW1pdG9wMChvcGNvZGUpOwogICAgICAgICAgICAgICAgcmV0dXJuIGl0ZW1zLm1ha2VTdGFja0l0ZW0ob3B0eXBlLnJlc3R5cGUpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0VHlwZUNhc3QoSkNUeXBlQ2FzdCB0cmVlKSB7CiAgICAgICAgcmVzdWx0ID0gZ2VuRXhwcih0cmVlLmV4cHIsIHRyZWUuY2xhenoudHlwZSkubG9hZCgpOwogICAgICAgIHNldFR5cGVBbm5vdGF0aW9uUG9zaXRpb25zKHRyZWUucG9zKTsKICAgICAgICAvLyBBZGRpdGlvbmFsIGNvZGUgaXMgb25seSBuZWVkZWQgaWYgd2UgY2FzdCB0byBhIHJlZmVyZW5jZSB0eXBlCiAgICAgICAgLy8gd2hpY2ggaXMgbm90IHN0YXRpY2FsbHkgYSBzdXBlcnR5cGUgb2YgdGhlIGV4cHJlc3Npb24ncyB0eXBlLgogICAgICAgIC8vIEZvciBiYXNpYyB0eXBlcywgdGhlIGNvZXJjZSguLi4pIGluIGdlbkV4cHIoLi4uKSB3aWxsIGRvCiAgICAgICAgLy8gdGhlIGNvbnZlcnNpb24uCiAgICAgICAgaWYgKCF0cmVlLmNsYXp6LnR5cGUuaXNQcmltaXRpdmUoKSAmJgogICAgICAgICAgICF0eXBlcy5pc1NhbWVUeXBlKHRyZWUuZXhwci50eXBlLCB0cmVlLmNsYXp6LnR5cGUpICYmCiAgICAgICAgICAgdHlwZXMuYXNTdXBlcih0cmVlLmV4cHIudHlwZSwgdHJlZS5jbGF6ei50eXBlLnRzeW0pID09IG51bGwpIHsKICAgICAgICAgICAgY29kZS5lbWl0b3AyKGNoZWNrY2FzdCwgbWFrZVJlZih0cmVlLnBvcygpLCB0cmVlLmNsYXp6LnR5cGUpKTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRXaWxkY2FyZChKQ1dpbGRjYXJkIHRyZWUpIHsKICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IodGhpcy5nZXRDbGFzcygpLmdldE5hbWUoKSk7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRUeXBlVGVzdChKQ0luc3RhbmNlT2YgdHJlZSkgewogICAgICAgIGdlbkV4cHIodHJlZS5leHByLCB0cmVlLmV4cHIudHlwZSkubG9hZCgpOwogICAgICAgIHNldFR5cGVBbm5vdGF0aW9uUG9zaXRpb25zKHRyZWUucG9zKTsKICAgICAgICBjb2RlLmVtaXRvcDIoaW5zdGFuY2VvZl8sIG1ha2VSZWYodHJlZS5wb3MoKSwgdHJlZS5jbGF6ei50eXBlKSk7CiAgICAgICAgcmVzdWx0ID0gaXRlbXMubWFrZVN0YWNrSXRlbShzeW1zLmJvb2xlYW5UeXBlKTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdEluZGV4ZWQoSkNBcnJheUFjY2VzcyB0cmVlKSB7CiAgICAgICAgZ2VuRXhwcih0cmVlLmluZGV4ZWQsIHRyZWUuaW5kZXhlZC50eXBlKS5sb2FkKCk7CiAgICAgICAgZ2VuRXhwcih0cmVlLmluZGV4LCBzeW1zLmludFR5cGUpLmxvYWQoKTsKICAgICAgICByZXN1bHQgPSBpdGVtcy5tYWtlSW5kZXhlZEl0ZW0odHJlZS50eXBlKTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCB2aXNpdElkZW50KEpDSWRlbnQgdHJlZSkgewogICAgICAgIFN5bWJvbCBzeW0gPSB0cmVlLnN5bTsKICAgICAgICBpZiAodHJlZS5uYW1lID09IG5hbWVzLl90aGlzIHx8IHRyZWUubmFtZSA9PSBuYW1lcy5fc3VwZXIpIHsKICAgICAgICAgICAgSXRlbSByZXMgPSB0cmVlLm5hbWUgPT0gbmFtZXMuX3RoaXMKICAgICAgICAgICAgICAgID8gaXRlbXMubWFrZVRoaXNJdGVtKCkKICAgICAgICAgICAgICAgIDogaXRlbXMubWFrZVN1cGVySXRlbSgpOwogICAgICAgICAgICBpZiAoc3ltLmtpbmQgPT0gTVRIKSB7CiAgICAgICAgICAgICAgICAvLyBHZW5lcmF0ZSBjb2RlIHRvIGFkZHJlc3MgdGhlIGNvbnN0cnVjdG9yLgogICAgICAgICAgICAgICAgcmVzLmxvYWQoKTsKICAgICAgICAgICAgICAgIHJlcyA9IGl0ZW1zLm1ha2VNZW1iZXJJdGVtKHN5bSwgdHJ1ZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmVzdWx0ID0gcmVzOwogICAgICAgIH0gZWxzZSBpZiAoc3ltLmtpbmQgPT0gVkFSICYmIHN5bS5vd25lci5raW5kID09IE1USCkgewogICAgICAgICAgICByZXN1bHQgPSBpdGVtcy5tYWtlTG9jYWxJdGVtKChWYXJTeW1ib2wpc3ltKTsKICAgICAgICB9IGVsc2UgaWYgKGlzSW52b2tlRHluYW1pYyhzeW0pKSB7CiAgICAgICAgICAgIHJlc3VsdCA9IGl0ZW1zLm1ha2VEeW5hbWljSXRlbShzeW0pOwogICAgICAgIH0gZWxzZSBpZiAoKHN5bS5mbGFncygpICYgU1RBVElDKSAhPSAwKSB7CiAgICAgICAgICAgIGlmICghaXNBY2Nlc3NTdXBlcihlbnYuZW5jbE1ldGhvZCkpCiAgICAgICAgICAgICAgICBzeW0gPSBiaW5hcnlRdWFsaWZpZXIoc3ltLCBlbnYuZW5jbENsYXNzLnR5cGUpOwogICAgICAgICAgICByZXN1bHQgPSBpdGVtcy5tYWtlU3RhdGljSXRlbShzeW0pOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGl0ZW1zLm1ha2VUaGlzSXRlbSgpLmxvYWQoKTsKICAgICAgICAgICAgc3ltID0gYmluYXJ5UXVhbGlmaWVyKHN5bSwgZW52LmVuY2xDbGFzcy50eXBlKTsKICAgICAgICAgICAgcmVzdWx0ID0gaXRlbXMubWFrZU1lbWJlckl0ZW0oc3ltLCAoc3ltLmZsYWdzKCkgJiBQUklWQVRFKSAhPSAwKTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRTZWxlY3QoSkNGaWVsZEFjY2VzcyB0cmVlKSB7CiAgICAgICAgU3ltYm9sIHN5bSA9IHRyZWUuc3ltOwoKICAgICAgICBpZiAodHJlZS5uYW1lID09IG5hbWVzLl9jbGFzcykgewogICAgICAgICAgICBjb2RlLmVtaXRMZGMobWFrZVJlZih0cmVlLnBvcygpLCB0cmVlLnNlbGVjdGVkLnR5cGUpKTsKICAgICAgICAgICAgcmVzdWx0ID0gaXRlbXMubWFrZVN0YWNrSXRlbShwdCk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgIH0KCiAgICAgICAgU3ltYm9sIHNzeW0gPSBUcmVlSW5mby5zeW1ib2wodHJlZS5zZWxlY3RlZCk7CgogICAgICAgIC8vIEFyZSB3ZSBzZWxlY3RpbmcgdmlhIHN1cGVyPwogICAgICAgIGJvb2xlYW4gc2VsZWN0U3VwZXIgPQogICAgICAgICAgICBzc3ltICE9IG51bGwgJiYgKHNzeW0ua2luZCA9PSBUWVAgfHwgc3N5bS5uYW1lID09IG5hbWVzLl9zdXBlcik7CgogICAgICAgIC8vIEFyZSB3ZSBhY2Nlc3NpbmcgYSBtZW1iZXIgb2YgdGhlIHN1cGVyY2xhc3MgaW4gYW4gYWNjZXNzIG1ldGhvZAogICAgICAgIC8vIHJlc3VsdGluZyBmcm9tIGEgcXVhbGlmaWVkIHN1cGVyPwogICAgICAgIGJvb2xlYW4gYWNjZXNzU3VwZXIgPSBpc0FjY2Vzc1N1cGVyKGVudi5lbmNsTWV0aG9kKTsKCiAgICAgICAgSXRlbSBiYXNlID0gKHNlbGVjdFN1cGVyKQogICAgICAgICAgICA/IGl0ZW1zLm1ha2VTdXBlckl0ZW0oKQogICAgICAgICAgICA6IGdlbkV4cHIodHJlZS5zZWxlY3RlZCwgdHJlZS5zZWxlY3RlZC50eXBlKTsKCiAgICAgICAgaWYgKHN5bS5raW5kID09IFZBUiAmJiAoKFZhclN5bWJvbCkgc3ltKS5nZXRDb25zdFZhbHVlKCkgIT0gbnVsbCkgewogICAgICAgICAgICAvLyBXZSBhcmUgc2VlaW5nIGEgdmFyaWFibGUgdGhhdCBpcyBjb25zdGFudCBidXQgaXRzIHNlbGVjdGluZwogICAgICAgICAgICAvLyBleHByZXNzaW9uIGlzIG5vdC4KICAgICAgICAgICAgaWYgKChzeW0uZmxhZ3MoKSAmIFNUQVRJQykgIT0gMCkgewogICAgICAgICAgICAgICAgaWYgKCFzZWxlY3RTdXBlciAmJiAoc3N5bSA9PSBudWxsIHx8IHNzeW0ua2luZCAhPSBUWVApKQogICAgICAgICAgICAgICAgICAgIGJhc2UgPSBiYXNlLmxvYWQoKTsKICAgICAgICAgICAgICAgIGJhc2UuZHJvcCgpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgYmFzZS5sb2FkKCk7CiAgICAgICAgICAgICAgICBnZW5OdWxsQ2hlY2sodHJlZS5zZWxlY3RlZC5wb3MoKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmVzdWx0ID0gaXRlbXMuCiAgICAgICAgICAgICAgICBtYWtlSW1tZWRpYXRlSXRlbShzeW0udHlwZSwgKChWYXJTeW1ib2wpIHN5bSkuZ2V0Q29uc3RWYWx1ZSgpKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBpZiAoaXNJbnZva2VEeW5hbWljKHN5bSkpIHsKICAgICAgICAgICAgICAgIHJlc3VsdCA9IGl0ZW1zLm1ha2VEeW5hbWljSXRlbShzeW0pOwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgc3ltID0gYmluYXJ5UXVhbGlmaWVyKHN5bSwgdHJlZS5zZWxlY3RlZC50eXBlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoKHN5bS5mbGFncygpICYgU1RBVElDKSAhPSAwKSB7CiAgICAgICAgICAgICAgICBpZiAoIXNlbGVjdFN1cGVyICYmIChzc3ltID09IG51bGwgfHwgc3N5bS5raW5kICE9IFRZUCkpCiAgICAgICAgICAgICAgICAgICAgYmFzZSA9IGJhc2UubG9hZCgpOwogICAgICAgICAgICAgICAgYmFzZS5kcm9wKCk7CiAgICAgICAgICAgICAgICByZXN1bHQgPSBpdGVtcy5tYWtlU3RhdGljSXRlbShzeW0pOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgYmFzZS5sb2FkKCk7CiAgICAgICAgICAgICAgICBpZiAoc3ltID09IHN5bXMubGVuZ3RoVmFyKSB7CiAgICAgICAgICAgICAgICAgICAgY29kZS5lbWl0b3AwKGFycmF5bGVuZ3RoKTsKICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBpdGVtcy5tYWtlU3RhY2tJdGVtKHN5bXMuaW50VHlwZSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IGl0ZW1zLgogICAgICAgICAgICAgICAgICAgICAgICBtYWtlTWVtYmVySXRlbShzeW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChzeW0uZmxhZ3MoKSAmIFBSSVZBVEUpICE9IDAgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0U3VwZXIgfHwgYWNjZXNzU3VwZXIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBib29sZWFuIGlzSW52b2tlRHluYW1pYyhTeW1ib2wgc3ltKSB7CiAgICAgICAgcmV0dXJuIHN5bS5raW5kID09IE1USCAmJiAoKE1ldGhvZFN5bWJvbClzeW0pLmlzRHluYW1pYygpOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHZpc2l0TGl0ZXJhbChKQ0xpdGVyYWwgdHJlZSkgewogICAgICAgIGlmICh0cmVlLnR5cGUuaGFzVGFnKEJPVCkpIHsKICAgICAgICAgICAgY29kZS5lbWl0b3AwKGFjb25zdF9udWxsKTsKICAgICAgICAgICAgcmVzdWx0ID0gaXRlbXMubWFrZVN0YWNrSXRlbSh0cmVlLnR5cGUpOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgICAgIHJlc3VsdCA9IGl0ZW1zLm1ha2VJbW1lZGlhdGVJdGVtKHRyZWUudHlwZSwgdHJlZS52YWx1ZSk7CiAgICB9CgogICAgcHVibGljIHZvaWQgdmlzaXRMZXRFeHByKExldEV4cHIgdHJlZSkgewogICAgICAgIGxldEV4cHJEZXB0aCsrOwogICAgICAgIGludCBsaW1pdCA9IGNvZGUubmV4dHJlZzsKICAgICAgICBnZW5TdGF0cyh0cmVlLmRlZnMsIGVudik7CiAgICAgICAgcmVzdWx0ID0gZ2VuRXhwcih0cmVlLmV4cHIsIHRyZWUuZXhwci50eXBlKS5sb2FkKCk7CiAgICAgICAgY29kZS5lbmRTY29wZXMobGltaXQpOwogICAgICAgIGxldEV4cHJEZXB0aC0tOwogICAgfQoKICAgIHByaXZhdGUgdm9pZCBnZW5lcmF0ZVJlZmVyZW5jZXNUb1BydW5lZFRyZWUoQ2xhc3NTeW1ib2wgY2xhc3NTeW1ib2wsIFBvb2wgcG9vbCkgewogICAgICAgIExpc3Q8SkNUcmVlPiBwcnVuZWRJbmZvID0gbG93ZXIucHJ1bmVkVHJlZS5nZXQoY2xhc3NTeW1ib2wpOwogICAgICAgIGlmIChwcnVuZWRJbmZvICE9IG51bGwpIHsKICAgICAgICAgICAgZm9yIChKQ1RyZWUgcHJ1bmVkVHJlZTogcHJ1bmVkSW5mbykgewogICAgICAgICAgICAgICAgcHJ1bmVkVHJlZS5hY2NlcHQoY2xhc3NSZWZlcmVuY2VWaXNpdG9yKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCi8qICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBtYWluIG1ldGhvZAogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiAgICAvKiogR2VuZXJhdGUgY29kZSBmb3IgYSBjbGFzcyBkZWZpbml0aW9uLgogICAgICogIEBwYXJhbSBlbnYgICBUaGUgYXR0cmlidXRpb24gZW52aXJvbm1lbnQgdGhhdCBiZWxvbmdzIHRvIHRoZQogICAgICogICAgICAgICAgICAgICBvdXRlcm1vc3QgY2xhc3MgY29udGFpbmluZyB0aGlzIGNsYXNzIGRlZmluaXRpb24uCiAgICAgKiAgICAgICAgICAgICAgIFdlIG5lZWQgdGhpcyBmb3IgcmVzb2x2aW5nIHNvbWUgYWRkaXRpb25hbCBzeW1ib2xzLgogICAgICogIEBwYXJhbSBjZGVmICBUaGUgdHJlZSByZXByZXNlbnRpbmcgdGhlIGNsYXNzIGRlZmluaXRpb24uCiAgICAgKiAgQHJldHVybiAgICAgIFRydWUgaWYgY29kZSBpcyBnZW5lcmF0ZWQgd2l0aCBubyBlcnJvcnMuCiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGdlbkNsYXNzKEVudjxBdHRyQ29udGV4dD4gZW52LCBKQ0NsYXNzRGVjbCBjZGVmKSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgYXR0ckVudiA9IGVudjsKICAgICAgICAgICAgQ2xhc3NTeW1ib2wgYyA9IGNkZWYuc3ltOwogICAgICAgICAgICB0aGlzLnRvcGxldmVsID0gZW52LnRvcGxldmVsOwogICAgICAgICAgICB0aGlzLmVuZFBvc1RhYmxlID0gdG9wbGV2ZWwuZW5kUG9zaXRpb25zOwogICAgICAgICAgICBjLnBvb2wgPSBwb29sOwogICAgICAgICAgICBwb29sLnJlc2V0KCk7CiAgICAgICAgICAgIC8qIG1ldGhvZCBub3JtYWxpemVEZWZzKCkgY2FuIGFkZCByZWZlcmVuY2VzIHRvIGV4dGVybmFsIGNsYXNzZXMgaW50byB0aGUgY29uc3RhbnQgcG9vbAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgY2RlZi5kZWZzID0gbm9ybWFsaXplRGVmcyhjZGVmLmRlZnMsIGMpOwogICAgICAgICAgICBnZW5lcmF0ZVJlZmVyZW5jZXNUb1BydW5lZFRyZWUoYywgcG9vbCk7CiAgICAgICAgICAgIEVudjxHZW5Db250ZXh0PiBsb2NhbEVudiA9IG5ldyBFbnY8PihjZGVmLCBuZXcgR2VuQ29udGV4dCgpKTsKICAgICAgICAgICAgbG9jYWxFbnYudG9wbGV2ZWwgPSBlbnYudG9wbGV2ZWw7CiAgICAgICAgICAgIGxvY2FsRW52LmVuY2xDbGFzcyA9IGNkZWY7CgogICAgICAgICAgICBmb3IgKExpc3Q8SkNUcmVlPiBsID0gY2RlZi5kZWZzOyBsLm5vbkVtcHR5KCk7IGwgPSBsLnRhaWwpIHsKICAgICAgICAgICAgICAgIGdlbkRlZihsLmhlYWQsIGxvY2FsRW52KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAocG9vbC5udW1FbnRyaWVzKCkgPiBQb29sLk1BWF9FTlRSSUVTKSB7CiAgICAgICAgICAgICAgICBsb2cuZXJyb3IoY2RlZi5wb3MoKSwgImxpbWl0LnBvb2wiKTsKICAgICAgICAgICAgICAgIG5lcnJzKys7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKG5lcnJzICE9IDApIHsKICAgICAgICAgICAgICAgIC8vIGlmIGVycm9ycywgZGlzY2FyZCBjb2RlCiAgICAgICAgICAgICAgICBmb3IgKExpc3Q8SkNUcmVlPiBsID0gY2RlZi5kZWZzOyBsLm5vbkVtcHR5KCk7IGwgPSBsLnRhaWwpIHsKICAgICAgICAgICAgICAgICAgICBpZiAobC5oZWFkLmhhc1RhZyhNRVRIT0RERUYpKQogICAgICAgICAgICAgICAgICAgICAgICAoKEpDTWV0aG9kRGVjbCkgbC5oZWFkKS5zeW0uY29kZSA9IG51bGw7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY2RlZi5kZWZzID0gTGlzdC5uaWwoKTsgLy8gZGlzY2FyZCB0cmVlcwogICAgICAgICAgICByZXR1cm4gbmVycnMgPT0gMDsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAvLyBub3RlOiB0aGlzIG1ldGhvZCBkb2VzIE5PVCBzdXBwb3J0IHJlY3Vyc2lvbi4KICAgICAgICAgICAgYXR0ckVudiA9IG51bGw7CiAgICAgICAgICAgIHRoaXMuZW52ID0gbnVsbDsKICAgICAgICAgICAgdG9wbGV2ZWwgPSBudWxsOwogICAgICAgICAgICBlbmRQb3NUYWJsZSA9IG51bGw7CiAgICAgICAgICAgIG5lcnJzID0gMDsKICAgICAgICB9CiAgICB9CgovKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQXV4aWxpYXJ5IGNsYXNzZXMKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgogICAgLyoqIEFuIGFic3RyYWN0IGNsYXNzIGZvciBmaW5hbGl6ZXIgZ2VuZXJhdGlvbi4KICAgICAqLwogICAgYWJzdHJhY3QgY2xhc3MgR2VuRmluYWxpemVyIHsKICAgICAgICAvKiogR2VuZXJhdGUgY29kZSB0byBjbGVhbiB1cCB3aGVuIHVud2luZGluZy4gKi8KICAgICAgICBhYnN0cmFjdCB2b2lkIGdlbigpOwoKICAgICAgICAvKiogR2VuZXJhdGUgY29kZSB0byBjbGVhbiB1cCBhdCBsYXN0LiAqLwogICAgICAgIGFic3RyYWN0IHZvaWQgZ2VuTGFzdCgpOwoKICAgICAgICAvKiogRG9lcyB0aGlzIGZpbmFsaXplciBoYXZlIHNvbWUgbm9udHJpdmlhbCBjbGVhbnVwIHRvIHBlcmZvcm0/ICovCiAgICAgICAgYm9vbGVhbiBoYXNGaW5hbGl6ZXIoKSB7IHJldHVybiB0cnVlOyB9CiAgICB9CgogICAgLyoqIGNvZGUgZ2VuZXJhdGlvbiBjb250ZXh0cywKICAgICAqICB0byBiZSB1c2VkIGFzIHR5cGUgcGFyYW1ldGVyIGZvciBlbnZpcm9ubWVudHMuCiAgICAgKi8KICAgIHN0YXRpYyBjbGFzcyBHZW5Db250ZXh0IHsKCiAgICAgICAgLyoqIEEgY2hhaW4gZm9yIGFsbCB1bnJlc29sdmVkIGp1bXBzIHRoYXQgZXhpdCB0aGUgY3VycmVudCBlbnZpcm9ubWVudC4KICAgICAgICAgKi8KICAgICAgICBDaGFpbiBleGl0ID0gbnVsbDsKCiAgICAgICAgLyoqIEEgY2hhaW4gZm9yIGFsbCB1bnJlc29sdmVkIGp1bXBzIHRoYXQgY29udGludWUgaW4gdGhlCiAgICAgICAgICogIGN1cnJlbnQgZW52aXJvbm1lbnQuCiAgICAgICAgICovCiAgICAgICAgQ2hhaW4gY29udCA9IG51bGw7CgogICAgICAgIC8qKiBBIGNsb3N1cmUgdGhhdCBnZW5lcmF0ZXMgdGhlIGZpbmFsaXplciBvZiB0aGUgY3VycmVudCBlbnZpcm9ubWVudC4KICAgICAgICAgKiAgT25seSBzZXQgZm9yIFN5bmNocm9uaXplZCBhbmQgVHJ5IGNvbnRleHRzLgogICAgICAgICAqLwogICAgICAgIEdlbkZpbmFsaXplciBmaW5hbGl6ZSA9IG51bGw7CgogICAgICAgIC8qKiBJcyB0aGlzIGEgc3dpdGNoIHN0YXRlbWVudD8gIElmIHNvLCBhbGxvY2F0ZSByZWdpc3RlcnMKICAgICAgICAgKiBldmVuIHdoZW4gdGhlIHZhcmlhYmxlIGRlY2xhcmF0aW9uIGlzIHVucmVhY2hhYmxlLgogICAgICAgICAqLwogICAgICAgIGJvb2xlYW4gaXNTd2l0Y2ggPSBmYWxzZTsKCiAgICAgICAgLyoqIEEgbGlzdCBidWZmZXIgY29udGFpbmluZyBhbGwgZ2FwcyBpbiB0aGUgZmluYWxpemVyIHJhbmdlLAogICAgICAgICAqICB3aGVyZSBhIGNhdGNoIGFsbCBleGNlcHRpb24gc2hvdWxkIG5vdCBhcHBseS4KICAgICAgICAgKi8KICAgICAgICBMaXN0QnVmZmVyPEludGVnZXI+IGdhcHMgPSBudWxsOwoKICAgICAgICAvKiogQWRkIGdpdmVuIGNoYWluIHRvIGV4aXQgY2hhaW4uCiAgICAgICAgICovCiAgICAgICAgdm9pZCBhZGRFeGl0KENoYWluIGMpICB7CiAgICAgICAgICAgIGV4aXQgPSBDb2RlLm1lcmdlQ2hhaW5zKGMsIGV4aXQpOwogICAgICAgIH0KCiAgICAgICAgLyoqIEFkZCBnaXZlbiBjaGFpbiB0byBjb250IGNoYWluLgogICAgICAgICAqLwogICAgICAgIHZvaWQgYWRkQ29udChDaGFpbiBjKSB7CiAgICAgICAgICAgIGNvbnQgPSBDb2RlLm1lcmdlQ2hhaW5zKGMsIGNvbnQpOwogICAgICAgIH0KICAgIH0KCn0KUEsDBAoAAAgAAAY7qUpGZs5LZGAAAGRgAAAmAAAAY29tL3N1bi90b29scy9qYXZhYy9qdm0vSk5JV3JpdGVyLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDE5OTksIDIwMTYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhYy5qdm07CgppbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKaW1wb3J0IGphdmEuaW8uUHJpbnRXcml0ZXI7CmltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OwppbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOwppbXBvcnQgamF2YS51dGlsLkxpc3Q7CgppbXBvcnQgamF2YXgudG9vbHMuRmlsZU9iamVjdDsKaW1wb3J0IGphdmF4LnRvb2xzLkphdmFGaWxlTWFuYWdlcjsKaW1wb3J0IGphdmF4LnRvb2xzLkphdmFGaWxlTWFuYWdlci5Mb2NhdGlvbjsKaW1wb3J0IGphdmF4LnRvb2xzLlN0YW5kYXJkTG9jYXRpb247CgppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLkF0dHJpYnV0ZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5GbGFnczsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5TeW1ib2w7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuU3ltYm9sLkNsYXNzU3ltYm9sOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlN5bWJvbC5Nb2R1bGVTeW1ib2w7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuU3ltYm9sLlZhclN5bWJvbDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5TeW10YWI7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuVHlwZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5UeXBlczsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMubW9kZWwuSmF2YWNFbGVtZW50czsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5Bc3NlcnQ7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuQ29udGV4dDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5Mb2c7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuT3B0aW9uczsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5QYWlyOwoKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLm1haW4uT3B0aW9uLio7CmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLktpbmRzLktpbmQuKjsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuU2NvcGUuTG9va3VwS2luZC5OT05fUkVDVVJTSVZFOwoKLyoqIFRoaXMgY2xhc3MgcHJvdmlkZXMgb3BlcmF0aW9ucyB0byB3cml0ZSBuYXRpdmUgaGVhZGVyIGZpbGVzIGZvciBjbGFzc2VzLgogKgogKiAgPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24gcmlzay4KICogIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yCiAqICBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+CiAqLwpwdWJsaWMgY2xhc3MgSk5JV3JpdGVyIHsKICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgQ29udGV4dC5LZXk8Sk5JV3JpdGVyPiBqbmlXcml0ZXJLZXkgPSBuZXcgQ29udGV4dC5LZXk8PigpOwoKICAgIC8qKiBBY2Nlc3MgdG8gZmlsZXMuICovCiAgICBwcml2YXRlIGZpbmFsIEphdmFGaWxlTWFuYWdlciBmaWxlTWFuYWdlcjsKCiAgICBUeXBlcyAgICAgIHR5cGVzOwogICAgU3ltdGFiICAgICBzeW1zOwoKICAgIC8qKiBUaGUgbG9nIHRvIHVzZSBmb3IgdmVyYm9zZSBvdXRwdXQuCiAgICAgKi8KICAgIHByaXZhdGUgZmluYWwgTG9nIGxvZzsKCiAgICAvKiogU3dpdGNoOiB2ZXJib3NlIG91dHB1dC4KICAgICAqLwogICAgcHJpdmF0ZSBib29sZWFuIHZlcmJvc2U7CgogICAgLyoqIFN3aXRjaDogY2hlY2sgYWxsIG5lc3RlZCBjbGFzc2VzIG9mIHRvcCBsZXZlbCBjbGFzcwogICAgICovCiAgICBwcml2YXRlIGJvb2xlYW4gY2hlY2tBbGw7CgogICAgLyoqCiAgICAgKiBJZiB0cnVlLCBjbGFzcyBmaWxlcyB3aWxsIGJlIHdyaXR0ZW4gaW4gbW9kdWxlLXNwZWNpZmljIHN1YmRpcmVjdG9yaWVzCiAgICAgKiBvZiB0aGUgTkFUSVZFX0hFQURFUl9PVVRQVVQgbG9jYXRpb24uCiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIG11bHRpTW9kdWxlTW9kZTsKCiAgICBwcml2YXRlIENvbnRleHQgY29udGV4dDsKCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuIGlzV2luZG93cyA9CiAgICAgICAgU3lzdGVtLmdldFByb3BlcnR5KCJvcy5uYW1lIikuc3RhcnRzV2l0aCgiV2luZG93cyIpOwoKICAgIC8qKiBHZXQgdGhlIENsYXNzV3JpdGVyIGluc3RhbmNlIGZvciB0aGlzIGNvbnRleHQuICovCiAgICBwdWJsaWMgc3RhdGljIEpOSVdyaXRlciBpbnN0YW5jZShDb250ZXh0IGNvbnRleHQpIHsKICAgICAgICBKTklXcml0ZXIgaW5zdGFuY2UgPSBjb250ZXh0LmdldChqbmlXcml0ZXJLZXkpOwogICAgICAgIGlmIChpbnN0YW5jZSA9PSBudWxsKQogICAgICAgICAgICBpbnN0YW5jZSA9IG5ldyBKTklXcml0ZXIoY29udGV4dCk7CiAgICAgICAgcmV0dXJuIGluc3RhbmNlOwogICAgfQoKICAgIC8qKiBDb25zdHJ1Y3QgYSBjbGFzcyB3cml0ZXIsIGdpdmVuIGFuIG9wdGlvbnMgdGFibGUuCiAgICAgKi8KICAgIHByaXZhdGUgSk5JV3JpdGVyKENvbnRleHQgY29udGV4dCkgewogICAgICAgIGNvbnRleHQucHV0KGpuaVdyaXRlcktleSwgdGhpcyk7CiAgICAgICAgZmlsZU1hbmFnZXIgPSBjb250ZXh0LmdldChKYXZhRmlsZU1hbmFnZXIuY2xhc3MpOwogICAgICAgIGxvZyA9IExvZy5pbnN0YW5jZShjb250ZXh0KTsKCiAgICAgICAgT3B0aW9ucyBvcHRpb25zID0gT3B0aW9ucy5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICB2ZXJib3NlID0gb3B0aW9ucy5pc1NldChWRVJCT1NFKTsKICAgICAgICBjaGVja0FsbCA9IG9wdGlvbnMuaXNTZXQoImphdmFoOmZ1bGwiKTsKCiAgICAgICAgdGhpcy5jb250ZXh0ID0gY29udGV4dDsgLy8gZm9yIGxhenlJbml0KCkKICAgIH0KCiAgICBwcml2YXRlIHZvaWQgbGF6eUluaXQoKSB7CiAgICAgICAgaWYgKHR5cGVzID09IG51bGwpCiAgICAgICAgICAgIHR5cGVzID0gVHlwZXMuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgaWYgKHN5bXMgPT0gbnVsbCkKICAgICAgICAgICAgc3ltcyA9IFN5bXRhYi5pbnN0YW5jZShjb250ZXh0KTsKCiAgICB9CgogICAgc3RhdGljIGJvb2xlYW4gaXNTeW50aGV0aWMoU3ltYm9sIHMpIHsKICAgICAgICByZXR1cm4gaGFzRmxhZyhzLCBGbGFncy5TWU5USEVUSUMpOwogICAgfQogICAgc3RhdGljIGJvb2xlYW4gaXNTdGF0aWMoU3ltYm9sIHMpIHsKICAgICAgICByZXR1cm4gaGFzRmxhZyhzLCBGbGFncy5TVEFUSUMpOwogICAgfQogICAgc3RhdGljIGJvb2xlYW4gaXNGaW5hbChTeW1ib2wgcykgewogICAgICAgIHJldHVybiBoYXNGbGFnKHMsIEZsYWdzLkZJTkFMKTsKICAgIH0KICAgIHN0YXRpYyBib29sZWFuIGlzTmF0aXZlKFN5bWJvbCBzKSB7CiAgICAgICAgcmV0dXJuIGhhc0ZsYWcocywgRmxhZ3MuTkFUSVZFKTsKICAgIH0KICAgIHN0YXRpYyBwcml2YXRlIGJvb2xlYW4gaGFzRmxhZyhTeW1ib2wgbSwgaW50IGZsYWcpIHsKICAgICAgICByZXR1cm4gKG0uZmxhZ3MoKSAmIGZsYWcpICE9IDA7CiAgICB9CgogICAgcHVibGljIGJvb2xlYW4gbmVlZHNIZWFkZXIoQ2xhc3NTeW1ib2wgYykgewogICAgICAgIGxhenlJbml0KCk7CiAgICAgICAgaWYgKGMuaXNMb2NhbCgpIHx8IGlzU3ludGhldGljKGMpKQogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgcmV0dXJuIChjaGVja0FsbCkKICAgICAgICAgICAgICAgID8gbmVlZHNIZWFkZXIoYy5vdXRlcm1vc3RDbGFzcygpLCB0cnVlKQogICAgICAgICAgICAgICAgOiBuZWVkc0hlYWRlcihjLCBmYWxzZSk7CiAgICB9CgogICAgcHJpdmF0ZSBib29sZWFuIG5lZWRzSGVhZGVyKENsYXNzU3ltYm9sIGMsIGJvb2xlYW4gY2hlY2tOZXN0ZWRDbGFzc2VzKSB7CiAgICAgICAgaWYgKGMuaXNMb2NhbCgpIHx8IGlzU3ludGhldGljKGMpKQogICAgICAgICAgICByZXR1cm4gZmFsc2U7CgogICAgICAgIGZvciAoU3ltYm9sIHN5bSA6IGMubWVtYmVyc19maWVsZC5nZXRTeW1ib2xzKE5PTl9SRUNVUlNJVkUpKSB7CiAgICAgICAgICAgIGlmIChzeW0ua2luZCA9PSBNVEggJiYgaXNOYXRpdmUoc3ltKSkKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICBmb3IgKEF0dHJpYnV0ZS5Db21wb3VuZCBhOiBzeW0uZ2V0RGVjbGFyYXRpb25BdHRyaWJ1dGVzKCkpIHsKICAgICAgICAgICAgICAgIGlmIChhLnR5cGUudHN5bSA9PSBzeW1zLm5hdGl2ZUhlYWRlclR5cGUudHN5bSkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoY2hlY2tOZXN0ZWRDbGFzc2VzKSB7CiAgICAgICAgICAgIGZvciAoU3ltYm9sIHN5bSA6IGMubWVtYmVyc19maWVsZC5nZXRTeW1ib2xzKE5PTl9SRUNVUlNJVkUpKSB7CiAgICAgICAgICAgICAgICBpZiAoKHN5bS5raW5kID09IFRZUCkgJiYgbmVlZHNIZWFkZXIoKChDbGFzc1N5bWJvbCkgc3ltKSwgdHJ1ZSkpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIC8qKiBFbWl0IGEgY2xhc3MgZmlsZSBmb3IgYSBnaXZlbiBjbGFzcy4KICAgICAqICBAcGFyYW0gYyAgICAgIFRoZSBjbGFzcyBmcm9tIHdoaWNoIGEgY2xhc3MgZmlsZSBpcyBnZW5lcmF0ZWQuCiAgICAgKi8KICAgIHB1YmxpYyBGaWxlT2JqZWN0IHdyaXRlKENsYXNzU3ltYm9sIGMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgU3RyaW5nIGNsYXNzTmFtZSA9IGMuZmxhdE5hbWUoKS50b1N0cmluZygpOwogICAgICAgIExvY2F0aW9uIG91dExvY247CiAgICAgICAgaWYgKG11bHRpTW9kdWxlTW9kZSkgewogICAgICAgICAgICBNb2R1bGVTeW1ib2wgbXN5bSA9IGMub3duZXIua2luZCA9PSBNREwgPyAoTW9kdWxlU3ltYm9sKSBjLm93bmVyIDogYy5wYWNrZ2UoKS5tb2RsZTsKICAgICAgICAgICAgb3V0TG9jbiA9IGZpbGVNYW5hZ2VyLmdldExvY2F0aW9uRm9yTW9kdWxlKFN0YW5kYXJkTG9jYXRpb24uTkFUSVZFX0hFQURFUl9PVVRQVVQsIG1zeW0ubmFtZS50b1N0cmluZygpKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBvdXRMb2NuID0gU3RhbmRhcmRMb2NhdGlvbi5OQVRJVkVfSEVBREVSX09VVFBVVDsKICAgICAgICB9CiAgICAgICAgRmlsZU9iamVjdCBvdXRGaWxlCiAgICAgICAgICAgID0gZmlsZU1hbmFnZXIuZ2V0RmlsZUZvck91dHB1dChvdXRMb2NuLAogICAgICAgICAgICAgICAgIiIsIGNsYXNzTmFtZS5yZXBsYWNlQWxsKCJbLiRdIiwgIl8iKSArICIuaCIsIG51bGwpOwogICAgICAgIFByaW50V3JpdGVyIG91dCA9IG5ldyBQcmludFdyaXRlcihvdXRGaWxlLm9wZW5Xcml0ZXIoKSk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgd3JpdGUob3V0LCBjKTsKICAgICAgICAgICAgaWYgKHZlcmJvc2UpCiAgICAgICAgICAgICAgICBsb2cucHJpbnRWZXJib3NlKCJ3cm90ZS5maWxlIiwgb3V0RmlsZSk7CiAgICAgICAgICAgIG91dC5jbG9zZSgpOwogICAgICAgICAgICBvdXQgPSBudWxsOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgIGlmIChvdXQgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgLy8gaWYgd2UgYXJlIHByb3BvZ2F0aW5nIGFuIGV4Y2VwdGlvbiwgZGVsZXRlIHRoZSBmaWxlCiAgICAgICAgICAgICAgICBvdXQuY2xvc2UoKTsKICAgICAgICAgICAgICAgIG91dEZpbGUuZGVsZXRlKCk7CiAgICAgICAgICAgICAgICBvdXRGaWxlID0gbnVsbDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gb3V0RmlsZTsgLy8gbWF5IGJlIG51bGwgaWYgd3JpdGUgZmFpbGVkCiAgICB9CgogICAgcHVibGljIHZvaWQgd3JpdGUoUHJpbnRXcml0ZXIgb3V0LCBDbGFzc1N5bWJvbCBzeW0pIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgbGF6eUluaXQoKTsKICAgICAgICB0cnkgewogICAgICAgICAgICBTdHJpbmcgY25hbWUgPSBlbmNvZGUoc3ltLmZ1bGxuYW1lLCBFbmNvZGVyVHlwZS5DTEFTUyk7CiAgICAgICAgICAgIGZpbGVUb3Aob3V0KTsKICAgICAgICAgICAgaW5jbHVkZXMob3V0KTsKICAgICAgICAgICAgZ3VhcmRCZWdpbihvdXQsIGNuYW1lKTsKICAgICAgICAgICAgY3BwR3VhcmRCZWdpbihvdXQpOwoKICAgICAgICAgICAgd3JpdGVTdGF0aWNzKG91dCwgc3ltKTsKICAgICAgICAgICAgd3JpdGVNZXRob2RzKG91dCwgc3ltLCBjbmFtZSk7CgogICAgICAgICAgICBjcHBHdWFyZEVuZChvdXQpOwogICAgICAgICAgICBndWFyZEVuZChvdXQpOwogICAgICAgIH0gY2F0Y2ggKFR5cGVTaWduYXR1cmUuU2lnbmF0dXJlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKGUpOwogICAgICAgIH0KICAgIH0KICAgIHByb3RlY3RlZCB2b2lkIHdyaXRlU3RhdGljcyhQcmludFdyaXRlciBvdXQsIENsYXNzU3ltYm9sIHN5bSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICBMaXN0PENsYXNzU3ltYm9sPiBjbGlzdCA9IG5ldyBBcnJheUxpc3Q8PigpOwogICAgICAgIGZvciAoQ2xhc3NTeW1ib2wgY2QgPSBzeW07IGNkICE9IG51bGw7CiAgICAgICAgICAgICAgICBjZCA9IChDbGFzc1N5bWJvbCkgY2QuZ2V0U3VwZXJjbGFzcygpLnRzeW0pIHsKICAgICAgICAgICAgY2xpc3QuYWRkKGNkKTsKICAgICAgICB9CiAgICAgICAgLyoKICAgICAgICAgKiBsaXN0IG5lZWRzIHRvIGJlIHN1cGVyLWNsYXNzLCBiYXNlLWNsYXNzMSwgYmFzZS1jbGFzczIgYW5kIHNvIG9uLAogICAgICAgICAqIHNvIHdlIHJldmVyc2UgY2xhc3MgaGllcmFyY2h5CiAgICAgICAgICovCiAgICAgICAgQ29sbGVjdGlvbnMucmV2ZXJzZShjbGlzdCk7CiAgICAgICAgZm9yIChDbGFzc1N5bWJvbCBjZCA6IGNsaXN0KSB7CiAgICAgICAgICAgIGZvciAoU3ltYm9sIGkgOiBjZC5nZXRFbmNsb3NlZEVsZW1lbnRzKCkpIHsKICAgICAgICAgICAgICAgIC8vIGNvbnNpZGVyIG9ubHkgZmluYWwsIHN0YXRpYyBhbmQgZmllbGRzIHdpdGggQ29uc3RhbnRFeHByZXNzaW9ucwogICAgICAgICAgICAgICAgaWYgKGlzRmluYWwoaSkgJiYgaS5pc1N0YXRpYygpICYmIGkua2luZCA9PSBWQVIpIHsKICAgICAgICAgICAgICAgICAgICBWYXJTeW1ib2wgdiA9IChWYXJTeW1ib2wpIGk7CiAgICAgICAgICAgICAgICAgICAgaWYgKHYuZ2V0Q29uc3RhbnRWYWx1ZSgpICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgUGFpcjxDbGFzc1N5bWJvbCwgVmFyU3ltYm9sPiBwID0gbmV3IFBhaXI8PihzeW0sIHYpOwogICAgICAgICAgICAgICAgICAgICAgICBwcmludFN0YXRpY0RlZmluZXMob3V0LCBwKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICBzdGF0aWMgdm9pZCBwcmludFN0YXRpY0RlZmluZXMoUHJpbnRXcml0ZXIgb3V0LCBQYWlyPENsYXNzU3ltYm9sLCBWYXJTeW1ib2w+IHApIHsKICAgICAgICBDbGFzc1N5bWJvbCBjbHMgPSBwLmZzdDsKICAgICAgICBWYXJTeW1ib2wgZiA9IHAuc25kOwogICAgICAgIE9iamVjdCB2YWx1ZSA9IGYuZ2V0Q29uc3RhbnRWYWx1ZSgpOwogICAgICAgIFN0cmluZyB2YWx1ZVN0ciA9IG51bGw7CiAgICAgICAgc3dpdGNoIChmLmFzVHlwZSgpLmdldEtpbmQoKSkgewogICAgICAgICAgICBjYXNlIEJPT0xFQU46CiAgICAgICAgICAgICAgICB2YWx1ZVN0ciA9ICgoKEJvb2xlYW4pIHZhbHVlKSA/ICIxTCIgOiAiMEwiKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIEJZVEU6IGNhc2UgU0hPUlQ6IGNhc2UgSU5UOgogICAgICAgICAgICAgICAgdmFsdWVTdHIgPSB2YWx1ZS50b1N0cmluZygpICsgIkwiOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgTE9ORzoKICAgICAgICAgICAgICAgIC8vIFZpc3VhbCBDKysgc3VwcG9ydHMgdGhlIGk2NCBzdWZmaXgsIG5vdCBMTC4KICAgICAgICAgICAgICAgIHZhbHVlU3RyID0gdmFsdWUudG9TdHJpbmcoKSArICgoaXNXaW5kb3dzKSA/ICJpNjQiIDogIkxMIik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBDSEFSOgogICAgICAgICAgICAgICAgQ2hhcmFjdGVyIGNoID0gKENoYXJhY3RlcikgdmFsdWU7CiAgICAgICAgICAgICAgICB2YWx1ZVN0ciA9IFN0cmluZy52YWx1ZU9mKCgoaW50KSBjaCkgJiAweGZmZmYpICsgIkwiOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgRkxPQVQ6CiAgICAgICAgICAgICAgICAvLyBidWcgY29tcGF0aWJsZQogICAgICAgICAgICAgICAgZmxvYXQgZnYgPSAoKEZsb2F0KSB2YWx1ZSkuZmxvYXRWYWx1ZSgpOwogICAgICAgICAgICAgICAgdmFsdWVTdHIgPSAoRmxvYXQuaXNJbmZpbml0ZShmdikpCiAgICAgICAgICAgICAgICAgICAgICAgID8gKChmdiA8IDApID8gIi0iIDogIiIpICsgIkluZmYiCiAgICAgICAgICAgICAgICAgICAgICAgIDogdmFsdWUudG9TdHJpbmcoKSArICJmIjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIERPVUJMRToKICAgICAgICAgICAgICAgIC8vIGJ1ZyBjb21wYXRpYmxlCiAgICAgICAgICAgICAgICBkb3VibGUgZCA9ICgoRG91YmxlKSB2YWx1ZSkuZG91YmxlVmFsdWUoKTsKICAgICAgICAgICAgICAgIHZhbHVlU3RyID0gKERvdWJsZS5pc0luZmluaXRlKGQpKQogICAgICAgICAgICAgICAgICAgICAgICA/ICgoZCA8IDApID8gIi0iIDogIiIpICsgIkluZkQiCiAgICAgICAgICAgICAgICAgICAgICAgIDogdmFsdWUudG9TdHJpbmcoKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgdmFsdWVTdHIgPSBudWxsOwogICAgICAgIH0KICAgICAgICBpZiAodmFsdWVTdHIgIT0gbnVsbCkgewogICAgICAgICAgICBvdXQucHJpbnQoIiN1bmRlZiAiKTsKICAgICAgICAgICAgU3RyaW5nIGNuYW1lID0gZW5jb2RlKGNscy5nZXRRdWFsaWZpZWROYW1lKCksIEVuY29kZXJUeXBlLkNMQVNTKTsKICAgICAgICAgICAgU3RyaW5nIGZuYW1lID0gZW5jb2RlKGYuZ2V0U2ltcGxlTmFtZSgpLCBFbmNvZGVyVHlwZS5GSUVMRFNUVUIpOwogICAgICAgICAgICBvdXQucHJpbnRsbihjbmFtZSArICJfIiArIGZuYW1lKTsKICAgICAgICAgICAgb3V0LnByaW50KCIjZGVmaW5lICIgKyBjbmFtZSArICJfIik7CiAgICAgICAgICAgIG91dC5wcmludGxuKGZuYW1lICsgIiAiICsgdmFsdWVTdHIpOwogICAgICAgIH0KICAgIH0KICAgIHByb3RlY3RlZCB2b2lkIHdyaXRlTWV0aG9kcyhQcmludFdyaXRlciBvdXQsIENsYXNzU3ltYm9sIHN5bSwgU3RyaW5nIGNuYW1lKQogICAgICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIFR5cGVTaWduYXR1cmUuU2lnbmF0dXJlRXhjZXB0aW9uIHsKICAgICAgICBMaXN0PFN5bWJvbD4gY2xhc3NtZXRob2RzID0gc3ltLmdldEVuY2xvc2VkRWxlbWVudHMoKTsKICAgICAgICBmb3IgKFN5bWJvbCBtZCA6IGNsYXNzbWV0aG9kcykgewogICAgICAgICAgICBpZiAoaXNOYXRpdmUobWQpKSB7CiAgICAgICAgICAgICAgICBUeXBlU2lnbmF0dXJlIG5ld3R5cGVzaWcgPSBuZXcgVHlwZVNpZ25hdHVyZSh0eXBlcyk7CiAgICAgICAgICAgICAgICBDaGFyU2VxdWVuY2UgbWV0aG9kTmFtZSA9IG1kLmdldFNpbXBsZU5hbWUoKTsKICAgICAgICAgICAgICAgIGJvb2xlYW4gaXNPdmVybG9hZGVkID0gZmFsc2U7CiAgICAgICAgICAgICAgICBmb3IgKFN5bWJvbCBtZDIgOiBjbGFzc21ldGhvZHMpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoKG1kMiAhPSBtZCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICYmIChtZXRob2ROYW1lLmVxdWFscyhtZDIuZ2V0U2ltcGxlTmFtZSgpKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICYmIGlzTmF0aXZlKG1kMikpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaXNPdmVybG9hZGVkID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBvdXQucHJpbnRsbigiLyoiKTsKICAgICAgICAgICAgICAgIG91dC5wcmludGxuKCIgKiBDbGFzczogICAgICIgKyBjbmFtZSk7CiAgICAgICAgICAgICAgICBvdXQucHJpbnRsbigiICogTWV0aG9kOiAgICAiICsgZW5jb2RlKG1ldGhvZE5hbWUsIEVuY29kZXJUeXBlLkZJRUxEU1RVQikpOwogICAgICAgICAgICAgICAgb3V0LnByaW50bG4oIiAqIFNpZ25hdHVyZTogIiArIG5ld3R5cGVzaWcuZ2V0U2lnbmF0dXJlKG1kLnR5cGUpKTsKICAgICAgICAgICAgICAgIG91dC5wcmludGxuKCIgKi8iKTsKICAgICAgICAgICAgICAgIG91dC5wcmludGxuKCJKTklFWFBPUlQgIiArIGpuaVR5cGUodHlwZXMuZXJhc3VyZShtZC50eXBlLmdldFJldHVyblR5cGUoKSkpCiAgICAgICAgICAgICAgICAgICAgICAgICsgIiBKTklDQUxMICIgKyBlbmNvZGVNZXRob2QobWQsIHN5bSwgaXNPdmVybG9hZGVkKSk7CiAgICAgICAgICAgICAgICBvdXQucHJpbnQoIiAgKEpOSUVudiAqLCAiKTsKICAgICAgICAgICAgICAgIG91dC5wcmludCgobWQuaXNTdGF0aWMoKSkKICAgICAgICAgICAgICAgICAgICAgICAgPyAiamNsYXNzIgogICAgICAgICAgICAgICAgICAgICAgICA6ICJqb2JqZWN0Iik7CiAgICAgICAgICAgICAgICBmb3IgKFR5cGUgYXJnIDogdHlwZXMuZXJhc3VyZShtZC50eXBlLmdldFBhcmFtZXRlclR5cGVzKCkpKSB7CiAgICAgICAgICAgICAgICAgICAgb3V0LnByaW50KCIsICIpOwogICAgICAgICAgICAgICAgICAgIG91dC5wcmludChqbmlUeXBlKGFyZykpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgb3V0LnByaW50bG4oIik7Iik7CiAgICAgICAgICAgICAgICBvdXQucHJpbnRsbigpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoImZhbGx0aHJvdWdoIikKICAgIHByb3RlY3RlZCBmaW5hbCBTdHJpbmcgam5pVHlwZShUeXBlIHQpIHsKICAgICAgICBzd2l0Y2ggKHQuZ2V0S2luZCgpKSB7CiAgICAgICAgICAgIGNhc2UgQVJSQVk6IHsKICAgICAgICAgICAgICAgIFR5cGUgY3QgPSAoKFR5cGUuQXJyYXlUeXBlKXQpLmdldENvbXBvbmVudFR5cGUoKTsKICAgICAgICAgICAgICAgIHN3aXRjaCAoY3QuZ2V0S2luZCgpKSB7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBCT09MRUFOOiAgcmV0dXJuICJqYm9vbGVhbkFycmF5IjsKICAgICAgICAgICAgICAgICAgICBjYXNlIEJZVEU6ICAgICByZXR1cm4gImpieXRlQXJyYXkiOwogICAgICAgICAgICAgICAgICAgIGNhc2UgQ0hBUjogICAgIHJldHVybiAiamNoYXJBcnJheSI7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBTSE9SVDogICAgcmV0dXJuICJqc2hvcnRBcnJheSI7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBJTlQ6ICAgICAgcmV0dXJuICJqaW50QXJyYXkiOwogICAgICAgICAgICAgICAgICAgIGNhc2UgTE9ORzogICAgIHJldHVybiAiamxvbmdBcnJheSI7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBGTE9BVDogICAgcmV0dXJuICJqZmxvYXRBcnJheSI7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBET1VCTEU6ICAgcmV0dXJuICJqZG91YmxlQXJyYXkiOwogICAgICAgICAgICAgICAgICAgIGNhc2UgQVJSQVk6CiAgICAgICAgICAgICAgICAgICAgY2FzZSBERUNMQVJFRDogcmV0dXJuICJqb2JqZWN0QXJyYXkiOwogICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHRocm93IG5ldyBFcnJvcihjdC50b1N0cmluZygpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgY2FzZSBWT0lEOiAgICAgcmV0dXJuICJ2b2lkIjsKICAgICAgICAgICAgY2FzZSBCT09MRUFOOiAgcmV0dXJuICJqYm9vbGVhbiI7CiAgICAgICAgICAgIGNhc2UgQllURTogICAgIHJldHVybiAiamJ5dGUiOwogICAgICAgICAgICBjYXNlIENIQVI6ICAgICByZXR1cm4gImpjaGFyIjsKICAgICAgICAgICAgY2FzZSBTSE9SVDogICAgcmV0dXJuICJqc2hvcnQiOwogICAgICAgICAgICBjYXNlIElOVDogICAgICByZXR1cm4gImppbnQiOwogICAgICAgICAgICBjYXNlIExPTkc6ICAgICByZXR1cm4gImpsb25nIjsKICAgICAgICAgICAgY2FzZSBGTE9BVDogICAgcmV0dXJuICJqZmxvYXQiOwogICAgICAgICAgICBjYXNlIERPVUJMRTogICByZXR1cm4gImpkb3VibGUiOwogICAgICAgICAgICBjYXNlIERFQ0xBUkVEOiB7CiAgICAgICAgICAgICAgICBpZiAodC50c3ltLnR5cGUgPT0gc3ltcy5zdHJpbmdUeXBlKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICJqc3RyaW5nIjsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZXMuaXNBc3NpZ25hYmxlKHQsIHN5bXMudGhyb3dhYmxlVHlwZSkpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gImp0aHJvd2FibGUiOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlcy5pc0Fzc2lnbmFibGUodCwgc3ltcy5jbGFzc1R5cGUpKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICJqY2xhc3MiOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gImpvYmplY3QiOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBBc3NlcnQuY2hlY2soZmFsc2UsICJqbmkgdW5rbm93biB0eXBlIik7CiAgICAgICAgcmV0dXJuIG51bGw7IC8qIGRlYWQgY29kZS4gKi8KICAgIH0KCiAgICBwcm90ZWN0ZWQgdm9pZCAgZmlsZVRvcChQcmludFdyaXRlciBvdXQpIHsKICAgICAgICBvdXQucHJpbnRsbigiLyogRE8gTk9UIEVESVQgVEhJUyBGSUxFIC0gaXQgaXMgbWFjaGluZSBnZW5lcmF0ZWQgKi8iKTsKICAgIH0KCiAgICBwcm90ZWN0ZWQgdm9pZCBpbmNsdWRlcyhQcmludFdyaXRlciBvdXQpIHsKICAgICAgICBvdXQucHJpbnRsbigiI2luY2x1ZGUgPGpuaS5oPiIpOwogICAgfQoKICAgIC8qCiAgICAgKiBEZWFsIHdpdGggdGhlIEMgcHJlLXByb2Nlc3Nvci4KICAgICAqLwogICAgcHJvdGVjdGVkIHZvaWQgY3BwR3VhcmRCZWdpbihQcmludFdyaXRlciBvdXQpIHsKICAgICAgICBvdXQucHJpbnRsbigiI2lmZGVmIF9fY3BsdXNwbHVzIik7CiAgICAgICAgb3V0LnByaW50bG4oImV4dGVybiBcIkNcIiB7Iik7CiAgICAgICAgb3V0LnByaW50bG4oIiNlbmRpZiIpOwogICAgfQoKICAgIHByb3RlY3RlZCB2b2lkIGNwcEd1YXJkRW5kKFByaW50V3JpdGVyIG91dCkgewogICAgICAgIG91dC5wcmludGxuKCIjaWZkZWYgX19jcGx1c3BsdXMiKTsKICAgICAgICBvdXQucHJpbnRsbigifSIpOwogICAgICAgIG91dC5wcmludGxuKCIjZW5kaWYiKTsKICAgIH0KCiAgICBwcm90ZWN0ZWQgdm9pZCBndWFyZEJlZ2luKFByaW50V3JpdGVyIG91dCwgU3RyaW5nIGNuYW1lKSB7CiAgICAgICAgb3V0LnByaW50bG4oIi8qIEhlYWRlciBmb3IgY2xhc3MgIiArIGNuYW1lICsgIiAqLyIpOwogICAgICAgIG91dC5wcmludGxuKCk7CiAgICAgICAgb3V0LnByaW50bG4oIiNpZm5kZWYgX0luY2x1ZGVkXyIgKyBjbmFtZSk7CiAgICAgICAgb3V0LnByaW50bG4oIiNkZWZpbmUgX0luY2x1ZGVkXyIgKyBjbmFtZSk7CiAgICB9CgogICAgcHJvdGVjdGVkIHZvaWQgZ3VhcmRFbmQoUHJpbnRXcml0ZXIgb3V0KSB7CiAgICAgICAgb3V0LnByaW50bG4oIiNlbmRpZiIpOwogICAgfQoKICAgIFN0cmluZyBlbmNvZGVNZXRob2QoU3ltYm9sIG1zeW0sIENsYXNzU3ltYm9sIGNsYXp6LAogICAgICAgICAgICBib29sZWFuIGlzT3ZlcmxvYWRlZCkgdGhyb3dzIFR5cGVTaWduYXR1cmUuU2lnbmF0dXJlRXhjZXB0aW9uIHsKICAgICAgICBTdHJpbmdCdWlsZGVyIHJlc3VsdCA9IG5ldyBTdHJpbmdCdWlsZGVyKDEwMCk7CiAgICAgICAgcmVzdWx0LmFwcGVuZCgiSmF2YV8iKTsKICAgICAgICAvKiBKTkkgKi8KICAgICAgICByZXN1bHQuYXBwZW5kKGVuY29kZShjbGF6ei5mbGF0bmFtZS50b1N0cmluZygpLCBFbmNvZGVyVHlwZS5KTkkpKTsKICAgICAgICByZXN1bHQuYXBwZW5kKCdfJyk7CiAgICAgICAgcmVzdWx0LmFwcGVuZChlbmNvZGUobXN5bS5nZXRTaW1wbGVOYW1lKCksIEVuY29kZXJUeXBlLkpOSSkpOwogICAgICAgIGlmIChpc092ZXJsb2FkZWQpIHsKICAgICAgICAgICAgVHlwZVNpZ25hdHVyZSB0eXBlU2lnID0gbmV3IFR5cGVTaWduYXR1cmUodHlwZXMpOwogICAgICAgICAgICBTdHJpbmdCdWlsZGVyIHNpZyA9IHR5cGVTaWcuZ2V0UGFyYW1ldGVyU2lnbmF0dXJlKG1zeW0udHlwZSk7CiAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoIl9fIikuYXBwZW5kKGVuY29kZShzaWcsIEVuY29kZXJUeXBlLkpOSSkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0LnRvU3RyaW5nKCk7CiAgICB9CgogICAgc3RhdGljIGVudW0gRW5jb2RlclR5cGUgewogICAgICAgIENMQVNTLAogICAgICAgIEZJRUxEU1RVQiwKICAgICAgICBGSUVMRCwKICAgICAgICBKTkksCiAgICAgICAgU0lHTkFUVVJFCiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygiZmFsbHRocm91Z2giKQogICAgc3RhdGljIFN0cmluZyBlbmNvZGUoQ2hhclNlcXVlbmNlIG5hbWUsIEVuY29kZXJUeXBlIG10eXBlKSB7CiAgICAgICAgU3RyaW5nQnVpbGRlciByZXN1bHQgPSBuZXcgU3RyaW5nQnVpbGRlcigxMDApOwogICAgICAgIGludCBsZW5ndGggPSBuYW1lLmxlbmd0aCgpOwoKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgIGNoYXIgY2ggPSBuYW1lLmNoYXJBdChpKTsKICAgICAgICAgICAgaWYgKGlzYWxudW0oY2gpKSB7CiAgICAgICAgICAgICAgICByZXN1bHQuYXBwZW5kKGNoKTsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHN3aXRjaCAobXR5cGUpIHsKICAgICAgICAgICAgICAgIGNhc2UgQ0xBU1M6CiAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChjaCkgewogICAgICAgICAgICAgICAgICAgICAgICBjYXNlICcuJzoKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnXyc6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQuYXBwZW5kKCJfIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnJCc6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQuYXBwZW5kKCJfXyIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQuYXBwZW5kKGVuY29kZUNoYXIoY2gpKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIEpOSToKICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKGNoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJy8nOgogICAgICAgICAgICAgICAgICAgICAgICBjYXNlICcuJzoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoIl8iKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdfJzoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoIl8xIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnOyc6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQuYXBwZW5kKCJfMiIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ1snOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0LmFwcGVuZCgiXzMiKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0LmFwcGVuZChlbmNvZGVDaGFyKGNoKSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBTSUdOQVRVUkU6CiAgICAgICAgICAgICAgICAgICAgcmVzdWx0LmFwcGVuZChpc3ByaW50KGNoKSA/IGNoIDogZW5jb2RlQ2hhcihjaCkpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBGSUVMRFNUVUI6CiAgICAgICAgICAgICAgICAgICAgcmVzdWx0LmFwcGVuZChjaCA9PSAnXycgPyBjaCA6IGVuY29kZUNoYXIoY2gpKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgcmVzdWx0LmFwcGVuZChlbmNvZGVDaGFyKGNoKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdC50b1N0cmluZygpOwogICAgfQoKICAgIHN0YXRpYyBTdHJpbmcgZW5jb2RlQ2hhcihjaGFyIGNoKSB7CiAgICAgICAgU3RyaW5nIHMgPSBJbnRlZ2VyLnRvSGV4U3RyaW5nKGNoKTsKICAgICAgICBpbnQgbnplcm9zID0gNSAtIHMubGVuZ3RoKCk7CiAgICAgICAgY2hhcltdIHJlc3VsdCA9IG5ldyBjaGFyWzZdOwogICAgICAgIHJlc3VsdFswXSA9ICdfJzsKICAgICAgICBmb3IgKGludCBpID0gMTsgaSA8PSBuemVyb3M7IGkrKykgewogICAgICAgICAgICByZXN1bHRbaV0gPSAnMCc7CiAgICAgICAgfQogICAgICAgIGZvciAoaW50IGkgPSBuemVyb3MgKyAxLCBqID0gMDsgaSA8IDY7IGkrKywgaisrKSB7CiAgICAgICAgICAgIHJlc3VsdFtpXSA9IHMuY2hhckF0KGopOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbmV3IFN0cmluZyhyZXN1bHQpOwogICAgfQoKICAgIC8qIFdhcm5pbmc6IEludGVudGlvbmFsIEFTQ0lJIG9wZXJhdGlvbi4gKi8KICAgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gaXNhbG51bShjaGFyIGNoKSB7CiAgICAgICAgcmV0dXJuIGNoIDw9IDB4N2YgJiYgLyogcXVpY2sgdGVzdCAqLwogICAgICAgICAgICAgICAgKChjaCA+PSAnQScgJiYgY2ggPD0gJ1onKSAgfHwKICAgICAgICAgICAgICAgICAoY2ggPj0gJ2EnICYmIGNoIDw9ICd6JykgIHx8CiAgICAgICAgICAgICAgICAgKGNoID49ICcwJyAmJiBjaCA8PSAnOScpKTsKICAgIH0KCiAgICAvKiBXYXJuaW5nOiBJbnRlbnRpb25hbCBBU0NJSSBvcGVyYXRpb24uICovCiAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGlzcHJpbnQoY2hhciBjaCkgewogICAgICAgIHJldHVybiBjaCA+PSAzMiAmJiBjaCA8PSAxMjY7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgVHlwZVNpZ25hdHVyZSB7CiAgICAgICAgc3RhdGljIGNsYXNzIFNpZ25hdHVyZUV4Y2VwdGlvbiBleHRlbmRzIEV4Y2VwdGlvbiB7CiAgICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDFMOwogICAgICAgICAgICBTaWduYXR1cmVFeGNlcHRpb24oU3RyaW5nIHJlYXNvbikgewogICAgICAgICAgICAgICAgc3VwZXIocmVhc29uKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgSmF2YWNFbGVtZW50cyBlbGVtczsKICAgICAgICBUeXBlcyAgICB0eXBlczsKCiAgICAgICAgLyogU2lnbmF0dXJlIENoYXJhY3RlcnMgKi8KICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgU0lHX1ZPSUQgICAgICAgICAgICAgICAgICAgPSAiViI7CiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFNJR19CT09MRUFOICAgICAgICAgICAgICAgID0gIloiOwogICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBTSUdfQllURSAgICAgICAgICAgICAgICAgICA9ICJCIjsKICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgU0lHX0NIQVIgICAgICAgICAgICAgICAgICAgPSAiQyI7CiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFNJR19TSE9SVCAgICAgICAgICAgICAgICAgID0gIlMiOwogICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBTSUdfSU5UICAgICAgICAgICAgICAgICAgICA9ICJJIjsKICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgU0lHX0xPTkcgICAgICAgICAgICAgICAgICAgPSAiSiI7CiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFNJR19GTE9BVCAgICAgICAgICAgICAgICAgID0gIkYiOwogICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBTSUdfRE9VQkxFICAgICAgICAgICAgICAgICA9ICJEIjsKICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgU0lHX0FSUkFZICAgICAgICAgICAgICAgICAgPSAiWyI7CiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFNJR19DTEFTUyAgICAgICAgICAgICAgICAgID0gIkwiOwoKICAgICAgICBwdWJsaWMgVHlwZVNpZ25hdHVyZShUeXBlcyB0eXBlcykgewogICAgICAgICAgICB0aGlzLnR5cGVzID0gdHlwZXM7CiAgICAgICAgfQoKICAgICAgICBTdHJpbmdCdWlsZGVyIGdldFBhcmFtZXRlclNpZ25hdHVyZShUeXBlIG1UeXBlKQogICAgICAgICAgICAgICAgdGhyb3dzIFNpZ25hdHVyZUV4Y2VwdGlvbiB7CiAgICAgICAgICAgIFN0cmluZ0J1aWxkZXIgcmVzdWx0ID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKICAgICAgICAgICAgZm9yIChUeXBlIHBUeXBlIDogbVR5cGUuZ2V0UGFyYW1ldGVyVHlwZXMoKSkgewogICAgICAgICAgICAgICAgcmVzdWx0LmFwcGVuZChnZXRKdm1TaWduYXR1cmUocFR5cGUpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgIH0KCiAgICAgICAgU3RyaW5nQnVpbGRlciBnZXRSZXR1cm5TaWduYXR1cmUoVHlwZSBtVHlwZSkKICAgICAgICAgICAgICAgIHRocm93cyBTaWduYXR1cmVFeGNlcHRpb24gewogICAgICAgICAgICByZXR1cm4gZ2V0SnZtU2lnbmF0dXJlKG1UeXBlLmdldFJldHVyblR5cGUoKSk7CiAgICAgICAgfQoKICAgICAgICBTdHJpbmdCdWlsZGVyIGdldFNpZ25hdHVyZShUeXBlIG1UeXBlKSB0aHJvd3MgU2lnbmF0dXJlRXhjZXB0aW9uIHsKICAgICAgICAgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CiAgICAgICAgICAgIHNiLmFwcGVuZCgiKCIpLmFwcGVuZChnZXRQYXJhbWV0ZXJTaWduYXR1cmUobVR5cGUpKS5hcHBlbmQoIikiKTsKICAgICAgICAgICAgc2IuYXBwZW5kKGdldFJldHVyblNpZ25hdHVyZShtVHlwZSkpOwogICAgICAgICAgICByZXR1cm4gc2I7CiAgICAgICAgfQoKICAgICAgICAvKgogICAgICAgICAqIFJldHVybnMganZtIGludGVybmFsIHNpZ25hdHVyZS4KICAgICAgICAgKi8KICAgICAgICBzdGF0aWMgY2xhc3MgSnZtVHlwZVZpc2l0b3IgZXh0ZW5kcyBKTklXcml0ZXIuU2ltcGxlVHlwZVZpc2l0b3I8VHlwZSwgU3RyaW5nQnVpbGRlcj4gewoKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHB1YmxpYyBUeXBlIHZpc2l0Q2xhc3NUeXBlKFR5cGUuQ2xhc3NUeXBlIHQsIFN0cmluZ0J1aWxkZXIgcykgewogICAgICAgICAgICAgICAgc2V0RGVjbGFyZWRUeXBlKHQsIHMpOwogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgVHlwZSB2aXNpdEFycmF5VHlwZShUeXBlLkFycmF5VHlwZSB0LCBTdHJpbmdCdWlsZGVyIHMpIHsKICAgICAgICAgICAgICAgIHMuYXBwZW5kKCJbIik7CiAgICAgICAgICAgICAgICByZXR1cm4gdC5nZXRDb21wb25lbnRUeXBlKCkuYWNjZXB0KHRoaXMsIHMpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHVibGljIFR5cGUgdmlzaXRUeXBlKFR5cGUgdCwgU3RyaW5nQnVpbGRlciBzKSB7CiAgICAgICAgICAgICAgICBpZiAodC5pc1ByaW1pdGl2ZU9yVm9pZCgpKSB7CiAgICAgICAgICAgICAgICAgICAgcy5hcHBlbmQoZ2V0SnZtUHJpbWl0aXZlU2lnbmF0dXJlKHQpKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiB0LmFjY2VwdCh0aGlzLCBzKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBwcml2YXRlIHZvaWQgc2V0RGVjbGFyZWRUeXBlKFR5cGUgdCwgU3RyaW5nQnVpbGRlciBzKSB7CiAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGNsYXNzbmFtZSA9IHQudHN5bS5nZXRRdWFsaWZpZWROYW1lKCkudG9TdHJpbmcoKTsKICAgICAgICAgICAgICAgICAgICBjbGFzc25hbWUgPSBjbGFzc25hbWUucmVwbGFjZSgnLicsICcvJyk7CiAgICAgICAgICAgICAgICAgICAgcy5hcHBlbmQoIkwiKS5hcHBlbmQoY2xhc3NuYW1lKS5hcHBlbmQoIjsiKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBwcml2YXRlIFN0cmluZyBnZXRKdm1QcmltaXRpdmVTaWduYXR1cmUoVHlwZSB0KSB7CiAgICAgICAgICAgICAgICBzd2l0Y2ggKHQuZ2V0S2luZCgpKSB7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBWT0lEOiAgICAgIHJldHVybiBTSUdfVk9JRDsKICAgICAgICAgICAgICAgICAgICBjYXNlIEJPT0xFQU46ICAgcmV0dXJuIFNJR19CT09MRUFOOwogICAgICAgICAgICAgICAgICAgIGNhc2UgQllURTogICAgICByZXR1cm4gU0lHX0JZVEU7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBDSEFSOiAgICAgIHJldHVybiBTSUdfQ0hBUjsKICAgICAgICAgICAgICAgICAgICBjYXNlIFNIT1JUOiAgICAgcmV0dXJuIFNJR19TSE9SVDsKICAgICAgICAgICAgICAgICAgICBjYXNlIElOVDogICAgICAgcmV0dXJuIFNJR19JTlQ7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBMT05HOiAgICAgIHJldHVybiBTSUdfTE9ORzsKICAgICAgICAgICAgICAgICAgICBjYXNlIEZMT0FUOiAgICAgcmV0dXJuIFNJR19GTE9BVDsKICAgICAgICAgICAgICAgICAgICBjYXNlIERPVUJMRTogICAgcmV0dXJuIFNJR19ET1VCTEU7CiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgICAgQXNzZXJ0LmVycm9yKCJ1bmtub3duIHR5cGU6IHNob3VsZCBub3QgaGFwcGVuIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgU3RyaW5nQnVpbGRlciBnZXRKdm1TaWduYXR1cmUoVHlwZSB0eXBlKSB7CiAgICAgICAgICAgIFR5cGUgdCA9IHR5cGVzLmVyYXN1cmUodHlwZSk7CiAgICAgICAgICAgIFN0cmluZ0J1aWxkZXIgc2lnID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKICAgICAgICAgICAgSnZtVHlwZVZpc2l0b3IganYgPSBuZXcgSnZtVHlwZVZpc2l0b3IoKTsKICAgICAgICAgICAganYudmlzaXRUeXBlKHQsIHNpZyk7CiAgICAgICAgICAgIHJldHVybiBzaWc7CiAgICAgICAgfQogICAgfQoKICAgIHN0YXRpYyBjbGFzcyBTaW1wbGVUeXBlVmlzaXRvcjxSLCBQPiBpbXBsZW1lbnRzIFR5cGUuVmlzaXRvcjxSLCBQPiB7CgogICAgICAgIHByb3RlY3RlZCBmaW5hbCBSIERFRkFVTFRfVkFMVUU7CgogICAgICAgIHByb3RlY3RlZCBTaW1wbGVUeXBlVmlzaXRvcigpIHsKICAgICAgICAgICAgREVGQVVMVF9WQUxVRSA9IG51bGw7CiAgICAgICAgfQoKICAgICAgICBwcm90ZWN0ZWQgU2ltcGxlVHlwZVZpc2l0b3IoUiBkZWZhdWx0VmFsdWUpIHsKICAgICAgICAgICAgREVGQVVMVF9WQUxVRSA9IGRlZmF1bHRWYWx1ZTsKICAgICAgICB9CgogICAgICAgIHByb3RlY3RlZCBSIGRlZmF1bHRBY3Rpb24oVHlwZSB0LCBQIHApIHsKICAgICAgICAgICAgcmV0dXJuIERFRkFVTFRfVkFMVUU7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgUiB2aXNpdENsYXNzVHlwZShUeXBlLkNsYXNzVHlwZSB0LCBQIHApIHsKICAgICAgICAgICAgcmV0dXJuIGRlZmF1bHRBY3Rpb24odCwgcCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgUiB2aXNpdFdpbGRjYXJkVHlwZShUeXBlLldpbGRjYXJkVHlwZSB0LCBQIHApIHsKICAgICAgICAgICAgcmV0dXJuIGRlZmF1bHRBY3Rpb24odCwgcCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgUiB2aXNpdEFycmF5VHlwZShUeXBlLkFycmF5VHlwZSB0LCBQIHApIHsKICAgICAgICAgICAgcmV0dXJuIGRlZmF1bHRBY3Rpb24odCwgcCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgUiB2aXNpdE1ldGhvZFR5cGUoVHlwZS5NZXRob2RUeXBlIHQsIFAgcCkgewogICAgICAgICAgICByZXR1cm4gZGVmYXVsdEFjdGlvbih0LCBwKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBSIHZpc2l0UGFja2FnZVR5cGUoVHlwZS5QYWNrYWdlVHlwZSB0LCBQIHApIHsKICAgICAgICAgICAgcmV0dXJuIGRlZmF1bHRBY3Rpb24odCwgcCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgUiB2aXNpdFR5cGVWYXIoVHlwZS5UeXBlVmFyIHQsIFAgcCkgewogICAgICAgICAgICByZXR1cm4gZGVmYXVsdEFjdGlvbih0LCBwKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBSIHZpc2l0Q2FwdHVyZWRUeXBlKFR5cGUuQ2FwdHVyZWRUeXBlIHQsIFAgcCkgewogICAgICAgICAgICByZXR1cm4gZGVmYXVsdEFjdGlvbih0LCBwKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBSIHZpc2l0Rm9yQWxsKFR5cGUuRm9yQWxsIHQsIFAgcCkgewogICAgICAgICAgICByZXR1cm4gZGVmYXVsdEFjdGlvbih0LCBwKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBSIHZpc2l0VW5kZXRWYXIoVHlwZS5VbmRldFZhciB0LCBQIHApIHsKICAgICAgICAgICAgcmV0dXJuIGRlZmF1bHRBY3Rpb24odCwgcCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgUiB2aXNpdEVycm9yVHlwZShUeXBlLkVycm9yVHlwZSB0LCBQIHApIHsKICAgICAgICAgICAgcmV0dXJuIGRlZmF1bHRBY3Rpb24odCwgcCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgUiB2aXNpdFR5cGUoVHlwZSB0LCBQIHApIHsKICAgICAgICAgICAgcmV0dXJuIGRlZmF1bHRBY3Rpb24odCwgcCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgUiB2aXNpdE1vZHVsZVR5cGUoVHlwZS5Nb2R1bGVUeXBlIHQsIFAgcCkgewogICAgICAgICAgICByZXR1cm4gZGVmYXVsdEFjdGlvbih0LCBwKTsKICAgICAgICB9CiAgICB9Cn0KUEsDBAoAAAgAAAY7qUoI/jMEShIAAEoSAAAjAAAAY29tL3N1bi90b29scy9qYXZhYy9qdm0vVGFyZ2V0LmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDIsIDIwMTYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhYy5qdm07CgppbXBvcnQgamF2YS51dGlsLio7CgppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLkZsYWdzOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlN5bWJvbDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC4qOwoKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLm1haW4uT3B0aW9uLlRBUkdFVDsKCi8qKiBUaGUgY2xhc3NmaWxlIHZlcnNpb24gdGFyZ2V0LgogKgogKiAgPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24gcmlzay4KICogIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yCiAqICBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+CiAqLwpwdWJsaWMgZW51bSBUYXJnZXQgewogICAgSkRLMV8xKCIxLjEiLCA0NSwgMyksCiAgICBKREsxXzIoIjEuMiIsIDQ2LCAwKSwKICAgIEpESzFfMygiMS4zIiwgNDcsIDApLAoKICAgIC8qKiBKMlNFMS40ID0gTWVybGluLiAqLwogICAgSkRLMV80KCIxLjQiLCA0OCwgMCksCgogICAgLyoqIEpESyA1LCBjb2RlbmFtZSBUaWdlci4gKi8KICAgIEpESzFfNSgiMS41IiwgNDksIDApLAoKICAgIC8qKiBKREsgNi4gKi8KICAgIEpESzFfNigiMS42IiwgNTAsIDApLAoKICAgIC8qKiBKREsgNy4gKi8KICAgIEpESzFfNygiMS43IiwgNTEsIDApLAoKICAgIC8qKiBKREsgOC4gKi8KICAgIEpESzFfOCgiMS44IiwgNTIsIDApLAoKICAgIC8qKiBKREsgOS4gKi8KICAgIEpESzFfOSgiMS45IiwgNTMsIDApOwoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIENvbnRleHQuS2V5PFRhcmdldD4gdGFyZ2V0S2V5ID0gbmV3IENvbnRleHQuS2V5PD4oKTsKCiAgICBwdWJsaWMgc3RhdGljIFRhcmdldCBpbnN0YW5jZShDb250ZXh0IGNvbnRleHQpIHsKICAgICAgICBUYXJnZXQgaW5zdGFuY2UgPSBjb250ZXh0LmdldCh0YXJnZXRLZXkpOwogICAgICAgIGlmIChpbnN0YW5jZSA9PSBudWxsKSB7CiAgICAgICAgICAgIE9wdGlvbnMgb3B0aW9ucyA9IE9wdGlvbnMuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgICAgIFN0cmluZyB0YXJnZXRTdHJpbmcgPSBvcHRpb25zLmdldChUQVJHRVQpOwogICAgICAgICAgICBpZiAodGFyZ2V0U3RyaW5nICE9IG51bGwpIGluc3RhbmNlID0gbG9va3VwKHRhcmdldFN0cmluZyk7CiAgICAgICAgICAgIGlmIChpbnN0YW5jZSA9PSBudWxsKSBpbnN0YW5jZSA9IERFRkFVTFQ7CiAgICAgICAgICAgIGNvbnRleHQucHV0KHRhcmdldEtleSwgaW5zdGFuY2UpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gaW5zdGFuY2U7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBUYXJnZXQgTUlOID0gVGFyZ2V0LkpESzFfNjsKCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBUYXJnZXQgTUFYID0gdmFsdWVzKClbdmFsdWVzKCkubGVuZ3RoIC0gMV07CgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgTWFwPFN0cmluZyxUYXJnZXQ+IHRhYiA9IG5ldyBIYXNoTWFwPD4oKTsKICAgIHN0YXRpYyB7CiAgICAgICAgZm9yIChUYXJnZXQgdCA6IHZhbHVlcygpKSB7CiAgICAgICAgICAgIHRhYi5wdXQodC5uYW1lLCB0KTsKICAgICAgICB9CiAgICAgICAgdGFiLnB1dCgiNSIsIEpESzFfNSk7CiAgICAgICAgdGFiLnB1dCgiNiIsIEpESzFfNik7CiAgICAgICAgdGFiLnB1dCgiNyIsIEpESzFfNyk7CiAgICAgICAgdGFiLnB1dCgiOCIsIEpESzFfOCk7CiAgICAgICAgdGFiLnB1dCgiOSIsIEpESzFfOSk7CiAgICB9CgogICAgcHVibGljIGZpbmFsIFN0cmluZyBuYW1lOwogICAgcHVibGljIGZpbmFsIGludCBtYWpvclZlcnNpb247CiAgICBwdWJsaWMgZmluYWwgaW50IG1pbm9yVmVyc2lvbjsKICAgIHByaXZhdGUgVGFyZ2V0KFN0cmluZyBuYW1lLCBpbnQgbWFqb3JWZXJzaW9uLCBpbnQgbWlub3JWZXJzaW9uKSB7CiAgICAgICAgdGhpcy5uYW1lID0gbmFtZTsKICAgICAgICB0aGlzLm1ham9yVmVyc2lvbiA9IG1ham9yVmVyc2lvbjsKICAgICAgICB0aGlzLm1pbm9yVmVyc2lvbiA9IG1pbm9yVmVyc2lvbjsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFRhcmdldCBERUZBVUxUID0gSkRLMV84OwoKICAgIHB1YmxpYyBzdGF0aWMgVGFyZ2V0IGxvb2t1cChTdHJpbmcgbmFtZSkgewogICAgICAgIHJldHVybiB0YWIuZ2V0KG5hbWUpOwogICAgfQoKICAgIC8qKiBSZXR1cm4gdGhlIGNoYXJhY3RlciB0byBiZSB1c2VkIGluIGNvbnN0cnVjdGluZyBzeW50aGV0aWMKICAgICAqICBpZGVudGlmaWVycywgd2hlcmUgbm90IHNwZWNpZmllZCBieSB0aGUgSkxTLgogICAgICovCiAgICBwdWJsaWMgY2hhciBzeW50aGV0aWNOYW1lQ2hhcigpIHsKICAgICAgICByZXR1cm4gJyQnOwogICAgfQoKICAgIC8qKiBEb2VzIHRoZSBWTSBzdXBwb3J0IGFuIGludm9rZWR5bmFtaWMgaW5zdHJ1Y3Rpb24/CiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGhhc0ludm9rZWR5bmFtaWMoKSB7CiAgICAgICAgcmV0dXJuIGNvbXBhcmVUbyhKREsxXzcpID49IDA7CiAgICB9CgogICAgLyoqIERvZXMgdGhlIHRhcmdldCBKREsgY29udGFpbnMgdGhlIGphdmEudXRpbC5PYmplY3RzIGNsYXNzPwogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPYmplY3RzKCkgewogICAgICAgIHJldHVybiBjb21wYXJlVG8oSkRLMV83KSA+PSAwOwogICAgfQoKICAgIC8qKiBEb2VzIHRoZSBWTSBzdXBwb3J0IHBvbHltb3JwaGljIG1ldGhvZCBoYW5kbGUgaW52b2NhdGlvbj8KICAgICAqICBBZmZlY3RzIHRoZSBsaW5rYWdlIGluZm9ybWF0aW9uIG91dHB1dCB0byB0aGUgY2xhc3NmaWxlLgogICAgICogIEFuIGFsaWFzIGZvciB7QGNvZGUgaGFzSW52b2tlZHluYW1pY30sIHNpbmNlIGFsbCB0aGUgSlNSIDI5MiBmZWF0dXJlcyBhcHBlYXIgdG9nZXRoZXIuCiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGhhc01ldGhvZEhhbmRsZXMoKSB7CiAgICAgICAgcmV0dXJuIGhhc0ludm9rZWR5bmFtaWMoKTsKICAgIH0KCiAgICAvKiogRG9lcyB0aGUgdGFyZ2V0IEpESyBjb250YWluIFN0cmluZ0NvbmNhdEZhY3RvcnkgY2xhc3M/CiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGhhc1N0cmluZ0NvbmNhdEZhY3RvcnkoKSB7CiAgICAgICAgcmV0dXJuIGNvbXBhcmVUbyhKREsxXzkpID49IDA7CiAgICB9CgogICAgLyoqIFZhbHVlIG9mIHBsYXRmb3JtIHJlbGVhc2UgdXNlZCB0byBhY2Nlc3MgbXVsdGktcmVsZWFzZSBqYXIgZmlsZXMKICAgICAqLwogICAgcHVibGljIFN0cmluZyBtdWx0aVJlbGVhc2VWYWx1ZSgpIHsKICAgICAgICByZXR1cm4gSW50ZWdlci50b1N0cmluZyh0aGlzLm9yZGluYWwoKSAtIFRhcmdldC5KREsxXzEub3JkaW5hbCgpICsgMSk7CiAgICB9Cgp9ClBLAwQKAAAIAADSfU1K9eOd2JQJAACUCQAAJQAAAGNvbS9zdW4vdG9vbHMvamF2YWMvanZtL0NSVEZsYWdzLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDEsIDIwMDUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhYy5qdm07CgoKLyoqIFRoZSBDaGFyYWN0ZXJSYW5nZVRhYmxlIGZsYWdzIGluZGljYXRpbmcgdHlwZSBvZiBhbiBlbnRyeS4KICoKICogIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqICBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqICBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogKiAgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPgogKi8KcHVibGljIGludGVyZmFjZSBDUlRGbGFncyB7CgogICAgLyoqIENSVEVudHJ5IGZsYWdzLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBDUlRfU1RBVEVNRU5UICAgICAgID0gMHgwMDAxOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ1JUX0JMT0NLICAgICAgICAgICA9IDB4MDAwMjsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENSVF9BU1NJR05NRU5UICAgICAgPSAweDAwMDQ7CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBDUlRfRkxPV19DT05UUk9MTEVSID0gMHgwMDA4OwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ1JUX0ZMT1dfVEFSR0VUICAgICA9IDB4MDAxMDsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENSVF9JTlZPS0UgICAgICAgICAgPSAweDAwMjA7CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBDUlRfQ1JFQVRFICAgICAgICAgID0gMHgwMDQwOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ1JUX0JSQU5DSF9UUlVFICAgICA9IDB4MDA4MDsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENSVF9CUkFOQ0hfRkFMU0UgICAgPSAweDAxMDA7CgogICAgLyoqIFRoZSBtYXNrIGZvciB2YWxpZCBmbGFncwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBDUlRfVkFMSURfRkxBR1MgPSBDUlRfU1RBVEVNRU5UIHwgQ1JUX0JMT0NLIHwgQ1JUX0FTU0lHTk1FTlQgfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ1JUX0ZMT1dfQ09OVFJPTExFUiB8IENSVF9GTE9XX1RBUkdFVCB8IENSVF9JTlZPS0UgfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ1JUX0NSRUFURSB8IENSVF9CUkFOQ0hfVFJVRSB8IENSVF9CUkFOQ0hfRkFMU0U7Cn0KUEsDBAoAAAgAAAY7qUqTLJuL7BQBAOwUAQAoAAAAY29tL3N1bi90b29scy9qYXZhYy9qdm0vQ2xhc3NXcml0ZXIuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMTk5OSwgMjAxNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLmphdmFjLmp2bTsKCmltcG9ydCBqYXZhLmlvLio7CmltcG9ydCBqYXZhLnV0aWwuTGlua2VkSGFzaE1hcDsKaW1wb3J0IGphdmEudXRpbC5NYXA7CmltcG9ydCBqYXZhLnV0aWwuU2V0OwppbXBvcnQgamF2YS51dGlsLkhhc2hTZXQ7CmltcG9ydCBqYXZhLnV0aWwuTGlua2VkSGFzaFNldDsKCmltcG9ydCBqYXZheC50b29scy5KYXZhRmlsZU1hbmFnZXI7CmltcG9ydCBqYXZheC50b29scy5GaWxlT2JqZWN0OwppbXBvcnQgamF2YXgudG9vbHMuSmF2YUZpbGVNYW5hZ2VyLkxvY2F0aW9uOwppbXBvcnQgamF2YXgudG9vbHMuSmF2YUZpbGVPYmplY3Q7CgppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLio7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuQXR0cmlidXRlLlJldGVudGlvblBvbGljeTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5EaXJlY3RpdmUuKjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5TeW1ib2wuKjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5UeXBlLio7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuVHlwZXMuVW5pcXVlVHlwZTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuZmlsZS5QYXRoRmlsZU9iamVjdDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuanZtLlBvb2wuRHluYW1pY01ldGhvZDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuanZtLlBvb2wuTWV0aG9kOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5qdm0uUG9vbC5NZXRob2RIYW5kbGU7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmp2bS5Qb29sLlZhcmlhYmxlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5tYWluLk9wdGlvbjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC4qOwoKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuRmxhZ3MuKjsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuS2luZHMuS2luZC4qOwppbXBvcnQgc3RhdGljIGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5TY29wZS5Mb29rdXBLaW5kLk5PTl9SRUNVUlNJVkU7CmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlR5cGVUYWcuKjsKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmphdmFjLm1haW4uT3B0aW9uLio7CgppbXBvcnQgc3RhdGljIGphdmF4LnRvb2xzLlN0YW5kYXJkTG9jYXRpb24uQ0xBU1NfT1VUUFVUOwoKLyoqIFRoaXMgY2xhc3MgcHJvdmlkZXMgb3BlcmF0aW9ucyB0byBtYXAgYW4gaW50ZXJuYWwgc3ltYm9sIHRhYmxlIGdyYXBoCiAqICByb290ZWQgaW4gYSBDbGFzc1N5bWJvbCBpbnRvIGEgY2xhc3NmaWxlLgogKgogKiAgPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24gcmlzay4KICogIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yCiAqICBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+CiAqLwpwdWJsaWMgY2xhc3MgQ2xhc3NXcml0ZXIgZXh0ZW5kcyBDbGFzc0ZpbGUgewogICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBDb250ZXh0LktleTxDbGFzc1dyaXRlcj4gY2xhc3NXcml0ZXJLZXkgPSBuZXcgQ29udGV4dC5LZXk8PigpOwoKICAgIHByaXZhdGUgZmluYWwgT3B0aW9ucyBvcHRpb25zOwoKICAgIC8qKiBTd2l0Y2g6IHZlcmJvc2Ugb3V0cHV0LgogICAgICovCiAgICBwcml2YXRlIGJvb2xlYW4gdmVyYm9zZTsKCiAgICAvKiogU3dpdGNoOiBlbWl0IHNvdXJjZSBmaWxlIGF0dHJpYnV0ZS4KICAgICAqLwogICAgcHJpdmF0ZSBib29sZWFuIGVtaXRTb3VyY2VGaWxlOwoKICAgIC8qKiBTd2l0Y2g6IGdlbmVyYXRlIENoYXJhY3RlclJhbmdlVGFibGUgYXR0cmlidXRlLgogICAgICovCiAgICBwcml2YXRlIGJvb2xlYW4gZ2VuQ3J0OwoKICAgIC8qKiBTd2l0Y2g6IGRlc2NyaWJlIHRoZSBnZW5lcmF0ZWQgc3RhY2ttYXAuCiAgICAgKi8KICAgIHByaXZhdGUgYm9vbGVhbiBkZWJ1Z3N0YWNrbWFwOwoKICAgIC8qKgogICAgICogVGFyZ2V0IGNsYXNzIHZlcnNpb24uCiAgICAgKi8KICAgIHByaXZhdGUgVGFyZ2V0IHRhcmdldDsKCiAgICAvKioKICAgICAqIFNvdXJjZSBsYW5ndWFnZSB2ZXJzaW9uLgogICAgICovCiAgICBwcml2YXRlIFNvdXJjZSBzb3VyY2U7CgogICAgLyoqIFR5cGUgdXRpbGl0aWVzLiAqLwogICAgcHJpdmF0ZSBUeXBlcyB0eXBlczsKCiAgICAvKioKICAgICAqIElmIHRydWUsIGNsYXNzIGZpbGVzIHdpbGwgYmUgd3JpdHRlbiBpbiBtb2R1bGUtc3BlY2lmaWMgc3ViZGlyZWN0b3JpZXMKICAgICAqIG9mIHRoZSBDTEFTU19PVVRQVVQgbG9jYXRpb24uCiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIG11bHRpTW9kdWxlTW9kZTsKCiAgICAvKiogVGhlIGluaXRpYWwgc2l6ZXMgb2YgdGhlIGRhdGEgYW5kIGNvbnN0YW50IHBvb2wgYnVmZmVycy4KICAgICAqICBTaXplcyBhcmUgaW5jcmVhc2VkIHdoZW4gYnVmZmVycyBnZXQgZnVsbC4KICAgICAqLwogICAgc3RhdGljIGZpbmFsIGludCBEQVRBX0JVRl9TSVpFID0gMHgwZmZmMDsKICAgIHN0YXRpYyBmaW5hbCBpbnQgUE9PTF9CVUZfU0laRSA9IDB4MWZmZjA7CgogICAgLyoqIEFuIG91dHB1dCBidWZmZXIgZm9yIG1lbWJlciBpbmZvLgogICAgICovCiAgICBCeXRlQnVmZmVyIGRhdGFidWYgPSBuZXcgQnl0ZUJ1ZmZlcihEQVRBX0JVRl9TSVpFKTsKCiAgICAvKiogQW4gb3V0cHV0IGJ1ZmZlciBmb3IgdGhlIGNvbnN0YW50IHBvb2wuCiAgICAgKi8KICAgIEJ5dGVCdWZmZXIgcG9vbGJ1ZiA9IG5ldyBCeXRlQnVmZmVyKFBPT0xfQlVGX1NJWkUpOwoKICAgIC8qKiBUaGUgY29uc3RhbnQgcG9vbC4KICAgICAqLwogICAgUG9vbCBwb29sOwoKICAgIC8qKiBUaGUgaW5uZXIgY2xhc3NlcyB0byBiZSB3cml0dGVuLCBhcyBhIHNldC4KICAgICAqLwogICAgU2V0PENsYXNzU3ltYm9sPiBpbm5lckNsYXNzZXM7CgogICAgLyoqIFRoZSBpbm5lciBjbGFzc2VzIHRvIGJlIHdyaXR0ZW4sIGFzIGEgcXVldWUgd2hlcmUKICAgICAqICBlbmNsb3NpbmcgY2xhc3NlcyBjb21lIGZpcnN0LgogICAgICovCiAgICBMaXN0QnVmZmVyPENsYXNzU3ltYm9sPiBpbm5lckNsYXNzZXNRdWV1ZTsKCiAgICAvKiogVGhlIGJvb3RzdHJhcCBtZXRob2RzIHRvIGJlIHdyaXR0ZW4gaW4gdGhlIGNvcnJlc3BvbmRpbmcgY2xhc3MgYXR0cmlidXRlCiAgICAgKiAgKG9uZSBmb3IgZWFjaCBpbnZva2VkeW5hbWljKQogICAgICovCiAgICBNYXA8RHluYW1pY01ldGhvZC5Cb290c3RyYXBNZXRob2RzS2V5LCBEeW5hbWljTWV0aG9kLkJvb3RzdHJhcE1ldGhvZHNWYWx1ZT4gYm9vdHN0cmFwTWV0aG9kczsKCiAgICAvKiogVGhlIGxvZyB0byB1c2UgZm9yIHZlcmJvc2Ugb3V0cHV0LgogICAgICovCiAgICBwcml2YXRlIGZpbmFsIExvZyBsb2c7CgogICAgLyoqIFRoZSBuYW1lIHRhYmxlLiAqLwogICAgcHJpdmF0ZSBmaW5hbCBOYW1lcyBuYW1lczsKCiAgICAvKiogQWNjZXNzIHRvIGZpbGVzLiAqLwogICAgcHJpdmF0ZSBmaW5hbCBKYXZhRmlsZU1hbmFnZXIgZmlsZU1hbmFnZXI7CgogICAgLyoqIFNvbGUgc2lnbmF0dXJlIGdlbmVyYXRvciAqLwogICAgcHJpdmF0ZSBmaW5hbCBDV1NpZ25hdHVyZUdlbmVyYXRvciBzaWduYXR1cmVHZW47CgogICAgLyoqIFRoZSB0YWdzIGFuZCBjb25zdGFudHMgdXNlZCBpbiBjb21wcmVzc2VkIHN0YWNrbWFwLiAqLwogICAgc3RhdGljIGZpbmFsIGludCBTQU1FX0ZSQU1FX1NJWkUgPSA2NDsKICAgIHN0YXRpYyBmaW5hbCBpbnQgU0FNRV9MT0NBTFNfMV9TVEFDS19JVEVNX0VYVEVOREVEID0gMjQ3OwogICAgc3RhdGljIGZpbmFsIGludCBTQU1FX0ZSQU1FX0VYVEVOREVEID0gMjUxOwogICAgc3RhdGljIGZpbmFsIGludCBGVUxMX0ZSQU1FID0gMjU1OwogICAgc3RhdGljIGZpbmFsIGludCBNQVhfTE9DQUxfTEVOR1RIX0RJRkYgPSA0OwoKICAgIC8qKiBHZXQgdGhlIENsYXNzV3JpdGVyIGluc3RhbmNlIGZvciB0aGlzIGNvbnRleHQuICovCiAgICBwdWJsaWMgc3RhdGljIENsYXNzV3JpdGVyIGluc3RhbmNlKENvbnRleHQgY29udGV4dCkgewogICAgICAgIENsYXNzV3JpdGVyIGluc3RhbmNlID0gY29udGV4dC5nZXQoY2xhc3NXcml0ZXJLZXkpOwogICAgICAgIGlmIChpbnN0YW5jZSA9PSBudWxsKQogICAgICAgICAgICBpbnN0YW5jZSA9IG5ldyBDbGFzc1dyaXRlcihjb250ZXh0KTsKICAgICAgICByZXR1cm4gaW5zdGFuY2U7CiAgICB9CgogICAgLyoqIENvbnN0cnVjdCBhIGNsYXNzIHdyaXRlciwgZ2l2ZW4gYW4gb3B0aW9ucyB0YWJsZS4KICAgICAqLwogICAgcHJvdGVjdGVkIENsYXNzV3JpdGVyKENvbnRleHQgY29udGV4dCkgewogICAgICAgIGNvbnRleHQucHV0KGNsYXNzV3JpdGVyS2V5LCB0aGlzKTsKCiAgICAgICAgbG9nID0gTG9nLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIG5hbWVzID0gTmFtZXMuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgb3B0aW9ucyA9IE9wdGlvbnMuaW5zdGFuY2UoY29udGV4dCk7CiAgICAgICAgdGFyZ2V0ID0gVGFyZ2V0Lmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIHNvdXJjZSA9IFNvdXJjZS5pbnN0YW5jZShjb250ZXh0KTsKICAgICAgICB0eXBlcyA9IFR5cGVzLmluc3RhbmNlKGNvbnRleHQpOwogICAgICAgIGZpbGVNYW5hZ2VyID0gY29udGV4dC5nZXQoSmF2YUZpbGVNYW5hZ2VyLmNsYXNzKTsKICAgICAgICBzaWduYXR1cmVHZW4gPSBuZXcgQ1dTaWduYXR1cmVHZW5lcmF0b3IodHlwZXMpOwoKICAgICAgICB2ZXJib3NlICAgICAgICA9IG9wdGlvbnMuaXNTZXQoVkVSQk9TRSk7CiAgICAgICAgZ2VuQ3J0ICAgICAgICAgPSBvcHRpb25zLmlzU2V0KFhKQ09WKTsKICAgICAgICBkZWJ1Z3N0YWNrbWFwID0gb3B0aW9ucy5pc1NldCgiZGVidWcuc3RhY2ttYXAiKTsKCiAgICAgICAgZW1pdFNvdXJjZUZpbGUgPSBvcHRpb25zLmlzVW5zZXQoR19DVVNUT00pIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zLmlzU2V0KEdfQ1VTVE9NLCAic291cmNlIik7CgogICAgICAgIFN0cmluZyBtb2RpZmllckZsYWdzID0gb3B0aW9ucy5nZXQoImRlYnVnLmR1bXBtb2RpZmllcnMiKTsKICAgICAgICBpZiAobW9kaWZpZXJGbGFncyAhPSBudWxsKSB7CiAgICAgICAgICAgIGR1bXBDbGFzc01vZGlmaWVycyA9IG1vZGlmaWVyRmxhZ3MuaW5kZXhPZignYycpICE9IC0xOwogICAgICAgICAgICBkdW1wRmllbGRNb2RpZmllcnMgPSBtb2RpZmllckZsYWdzLmluZGV4T2YoJ2YnKSAhPSAtMTsKICAgICAgICAgICAgZHVtcElubmVyQ2xhc3NNb2RpZmllcnMgPSBtb2RpZmllckZsYWdzLmluZGV4T2YoJ2knKSAhPSAtMTsKICAgICAgICAgICAgZHVtcE1ldGhvZE1vZGlmaWVycyA9IG1vZGlmaWVyRmxhZ3MuaW5kZXhPZignbScpICE9IC0xOwogICAgICAgIH0KICAgIH0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRGlhZ25vc3RpY3M6IGR1bXAgZ2VuZXJhdGVkIGNsYXNzIG5hbWVzIGFuZCBtb2RpZmllcnMKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiAgICAvKiogVmFsdWUgb2Ygb3B0aW9uICdkdW1wbW9kaWZpZXJzJyBpcyBhIHN0cmluZwogICAgICogIGluZGljYXRpbmcgd2hpY2ggbW9kaWZpZXJzIHNob3VsZCBiZSBkdW1wZWQgZm9yIGRlYnVnZ2luZzoKICAgICAqICAgICdjJyAtLSBjbGFzc2VzCiAgICAgKiAgICAnZicgLS0gZmllbGRzCiAgICAgKiAgICAnaScgLS0gaW5uZXJjbGFzcyBhdHRyaWJ1dGVzCiAgICAgKiAgICAnbScgLS0gbWV0aG9kcwogICAgICogIEZvciBleGFtcGxlLCB0byBkdW1wIGV2ZXJ5dGhpbmc6CiAgICAgKiAgICBqYXZhYyAtWERkdW1wbW9kaWZpZXJzPWNpZm0gTXlQcm9nLmphdmEKICAgICAqLwogICAgcHJpdmF0ZSBib29sZWFuIGR1bXBDbGFzc01vZGlmaWVyczsgLy8gLVhEZHVtcG1vZGlmaWVycz1jCiAgICBwcml2YXRlIGJvb2xlYW4gZHVtcEZpZWxkTW9kaWZpZXJzOyAvLyAtWERkdW1wbW9kaWZpZXJzPWYKICAgIHByaXZhdGUgYm9vbGVhbiBkdW1wSW5uZXJDbGFzc01vZGlmaWVyczsgLy8gLVhEZHVtcG1vZGlmaWVycz1pCiAgICBwcml2YXRlIGJvb2xlYW4gZHVtcE1ldGhvZE1vZGlmaWVyczsgLy8gLVhEZHVtcG1vZGlmaWVycz1tCgoKICAgIC8qKiBSZXR1cm4gZmxhZ3MgYXMgYSBzdHJpbmcsIHNlcGFyYXRlZCBieSAiICIuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGZsYWdOYW1lcyhsb25nIGZsYWdzKSB7CiAgICAgICAgU3RyaW5nQnVpbGRlciBzYnVmID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKICAgICAgICBpbnQgaSA9IDA7CiAgICAgICAgbG9uZyBmID0gZmxhZ3MgJiBTdGFuZGFyZEZsYWdzOwogICAgICAgIHdoaWxlIChmICE9IDApIHsKICAgICAgICAgICAgaWYgKChmICYgMSkgIT0gMCkgewogICAgICAgICAgICAgICAgc2J1Zi5hcHBlbmQoIiAiKTsKICAgICAgICAgICAgICAgIHNidWYuYXBwZW5kKGZsYWdOYW1lW2ldKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBmID0gZiA+PiAxOwogICAgICAgICAgICBpKys7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzYnVmLnRvU3RyaW5nKCk7CiAgICB9CiAgICAvL3doZXJlCiAgICAgICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgU3RyaW5nW10gZmxhZ05hbWUgPSB7CiAgICAgICAgICAgICJQVUJMSUMiLCAiUFJJVkFURSIsICJQUk9URUNURUQiLCAiU1RBVElDIiwgIkZJTkFMIiwKICAgICAgICAgICAgIlNVUEVSIiwgIlZPTEFUSUxFIiwgIlRSQU5TSUVOVCIsICJOQVRJVkUiLCAiSU5URVJGQUNFIiwKICAgICAgICAgICAgIkFCU1RSQUNUIiwgIlNUUklDVEZQIn07CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIE91dHB1dCByb3V0aW5lcwogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKICAgIC8qKiBXcml0ZSBhIGNoYXJhY3RlciBpbnRvIGdpdmVuIGJ5dGUgYnVmZmVyOwogICAgICogIGJ5dGUgYnVmZmVyIHdpbGwgbm90IGJlIGdyb3duLgogICAgICovCiAgICB2b2lkIHB1dENoYXIoQnl0ZUJ1ZmZlciBidWYsIGludCBvcCwgaW50IHgpIHsKICAgICAgICBidWYuZWxlbXNbb3AgIF0gPSAoYnl0ZSkoKHggPj4gIDgpICYgMHhGRik7CiAgICAgICAgYnVmLmVsZW1zW29wKzFdID0gKGJ5dGUpKCh4ICAgICAgKSAmIDB4RkYpOwogICAgfQoKICAgIC8qKiBXcml0ZSBhbiBpbnRlZ2VyIGludG8gZ2l2ZW4gYnl0ZSBidWZmZXI7CiAgICAgKiAgYnl0ZSBidWZmZXIgd2lsbCBub3QgYmUgZ3Jvd24uCiAgICAgKi8KICAgIHZvaWQgcHV0SW50KEJ5dGVCdWZmZXIgYnVmLCBpbnQgYWRyLCBpbnQgeCkgewogICAgICAgIGJ1Zi5lbGVtc1thZHIgIF0gPSAoYnl0ZSkoKHggPj4gMjQpICYgMHhGRik7CiAgICAgICAgYnVmLmVsZW1zW2FkcisxXSA9IChieXRlKSgoeCA+PiAxNikgJiAweEZGKTsKICAgICAgICBidWYuZWxlbXNbYWRyKzJdID0gKGJ5dGUpKCh4ID4+ICA4KSAmIDB4RkYpOwogICAgICAgIGJ1Zi5lbGVtc1thZHIrM10gPSAoYnl0ZSkoKHggICAgICApICYgMHhGRik7CiAgICB9CgogICAgLyoqCiAgICAgKiBTaWduYXR1cmUgR2VuZXJhdGlvbgogICAgICovCiAgICBwcml2YXRlIGNsYXNzIENXU2lnbmF0dXJlR2VuZXJhdG9yIGV4dGVuZHMgVHlwZXMuU2lnbmF0dXJlR2VuZXJhdG9yIHsKCiAgICAgICAgLyoqCiAgICAgICAgICogQW4gb3V0cHV0IGJ1ZmZlciBmb3IgdHlwZSBzaWduYXR1cmVzLgogICAgICAgICAqLwogICAgICAgIEJ5dGVCdWZmZXIgc2lnYnVmID0gbmV3IEJ5dGVCdWZmZXIoKTsKCiAgICAgICAgQ1dTaWduYXR1cmVHZW5lcmF0b3IoVHlwZXMgdHlwZXMpIHsKICAgICAgICAgICAgc3VwZXIodHlwZXMpOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogQXNzZW1ibGUgc2lnbmF0dXJlIG9mIGdpdmVuIHR5cGUgaW4gc3RyaW5nIGJ1ZmZlci4KICAgICAgICAgKiBDaGVjayBmb3IgdW5pbml0aWFsaXplZCB0eXBlcyBiZWZvcmUgY2FsbGluZyB0aGUgZ2VuZXJhbCBjYXNlLgogICAgICAgICAqLwogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIGFzc2VtYmxlU2lnKFR5cGUgdHlwZSkgewogICAgICAgICAgICBzd2l0Y2ggKHR5cGUuZ2V0VGFnKCkpIHsKICAgICAgICAgICAgICAgIGNhc2UgVU5JTklUSUFMSVpFRF9USElTOgogICAgICAgICAgICAgICAgY2FzZSBVTklOSVRJQUxJWkVEX09CSkVDVDoKICAgICAgICAgICAgICAgICAgICAvLyB3ZSBkb24ndCB5ZXQgaGF2ZSBhIHNwZWMgZm9yIHVuaW5pdGlhbGl6ZWQgdHlwZXMgaW4gdGhlCiAgICAgICAgICAgICAgICAgICAgLy8gbG9jYWwgdmFyaWFibGUgdGFibGUKICAgICAgICAgICAgICAgICAgICBhc3NlbWJsZVNpZyh0eXBlcy5lcmFzdXJlKCgoVW5pbml0aWFsaXplZFR5cGUpdHlwZSkucXR5cGUpKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgc3VwZXIuYXNzZW1ibGVTaWcodHlwZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHByb3RlY3RlZCB2b2lkIGFwcGVuZChjaGFyIGNoKSB7CiAgICAgICAgICAgIHNpZ2J1Zi5hcHBlbmRCeXRlKGNoKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHByb3RlY3RlZCB2b2lkIGFwcGVuZChieXRlW10gYmEpIHsKICAgICAgICAgICAgc2lnYnVmLmFwcGVuZEJ5dGVzKGJhKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHByb3RlY3RlZCB2b2lkIGFwcGVuZChOYW1lIG5hbWUpIHsKICAgICAgICAgICAgc2lnYnVmLmFwcGVuZE5hbWUobmFtZSk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwcm90ZWN0ZWQgdm9pZCBjbGFzc1JlZmVyZW5jZShDbGFzc1N5bWJvbCBjKSB7CiAgICAgICAgICAgIGVudGVySW5uZXIoYyk7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIHZvaWQgcmVzZXQoKSB7CiAgICAgICAgICAgIHNpZ2J1Zi5yZXNldCgpOwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBOYW1lIHRvTmFtZSgpIHsKICAgICAgICAgICAgcmV0dXJuIHNpZ2J1Zi50b05hbWUobmFtZXMpOwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBib29sZWFuIGlzRW1wdHkoKSB7CiAgICAgICAgICAgIHJldHVybiBzaWdidWYubGVuZ3RoID09IDA7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJuIHNpZ25hdHVyZSBvZiBnaXZlbiB0eXBlCiAgICAgKi8KICAgIE5hbWUgdHlwZVNpZyhUeXBlIHR5cGUpIHsKICAgICAgICBBc3NlcnQuY2hlY2soc2lnbmF0dXJlR2VuLmlzRW1wdHkoKSk7CiAgICAgICAgLy8tIFN5c3RlbS5vdXQucHJpbnRsbigiID8gIiArIHR5cGUpOwogICAgICAgIHNpZ25hdHVyZUdlbi5hc3NlbWJsZVNpZyh0eXBlKTsKICAgICAgICBOYW1lIG4gPSBzaWduYXR1cmVHZW4udG9OYW1lKCk7CiAgICAgICAgc2lnbmF0dXJlR2VuLnJlc2V0KCk7CiAgICAgICAgLy8tIFN5c3RlbS5vdXQucHJpbnRsbigiICAgIiArIG4pOwogICAgICAgIHJldHVybiBuOwogICAgfQoKICAgIC8qKiBHaXZlbiBhIHR5cGUgdCwgcmV0dXJuIHRoZSBleHRlbmRlZCBjbGFzcyBuYW1lIG9mIGl0cyBlcmFzdXJlIGluCiAgICAgKiAgZXh0ZXJuYWwgcmVwcmVzZW50YXRpb24uCiAgICAgKi8KICAgIHB1YmxpYyBOYW1lIHhDbGFzc05hbWUoVHlwZSB0KSB7CiAgICAgICAgaWYgKHQuaGFzVGFnKENMQVNTKSkgewogICAgICAgICAgICByZXR1cm4gbmFtZXMuZnJvbVV0ZihleHRlcm5hbGl6ZSh0LnRzeW0uZmxhdE5hbWUoKSkpOwogICAgICAgIH0gZWxzZSBpZiAodC5oYXNUYWcoQVJSQVkpKSB7CiAgICAgICAgICAgIHJldHVybiB0eXBlU2lnKHR5cGVzLmVyYXN1cmUodCkpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigieENsYXNzTmFtZSBleHBlY3RzIGNsYXNzIG9yIGFycmF5IHR5cGUsIGdvdCAiICsgdCk7CiAgICAgICAgfQogICAgfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBXcml0aW5nIHRoZSBDb25zdGFudCBQb29sCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgogICAgLyoqIFRocm93biB3aGVuIHRoZSBjb25zdGFudCBwb29sIGlzIG92ZXIgZnVsbC4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBjbGFzcyBQb29sT3ZlcmZsb3cgZXh0ZW5kcyBFeGNlcHRpb24gewogICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDA7CiAgICAgICAgcHVibGljIFBvb2xPdmVyZmxvdygpIHt9CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIFN0cmluZ092ZXJmbG93IGV4dGVuZHMgRXhjZXB0aW9uIHsKICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwOwogICAgICAgIHB1YmxpYyBmaW5hbCBTdHJpbmcgdmFsdWU7CiAgICAgICAgcHVibGljIFN0cmluZ092ZXJmbG93KFN0cmluZyBzKSB7CiAgICAgICAgICAgIHZhbHVlID0gczsKICAgICAgICB9CiAgICB9CgogICAgLyoqIFdyaXRlIGNvbnN0YW50IHBvb2wgdG8gcG9vbCBidWZmZXIuCiAgICAgKiAgTm90ZTogZHVyaW5nIHdyaXRpbmcsIGNvbnN0YW50IHBvb2wKICAgICAqICBtaWdodCBncm93IHNpbmNlIHNvbWUgcGFydHMgb2YgY29uc3RhbnRzIHN0aWxsIG5lZWQgdG8gYmUgZW50ZXJlZC4KICAgICAqLwogICAgdm9pZCB3cml0ZVBvb2woUG9vbCBwb29sKSB0aHJvd3MgUG9vbE92ZXJmbG93LCBTdHJpbmdPdmVyZmxvdyB7CiAgICAgICAgaW50IHBvb2xDb3VudElkeCA9IHBvb2xidWYubGVuZ3RoOwogICAgICAgIHBvb2xidWYuYXBwZW5kQ2hhcigwKTsKICAgICAgICBpbnQgaSA9IDE7CiAgICAgICAgd2hpbGUgKGkgPCBwb29sLnBwKSB7CiAgICAgICAgICAgIE9iamVjdCB2YWx1ZSA9IHBvb2wucG9vbFtpXTsKICAgICAgICAgICAgQXNzZXJ0LmNoZWNrTm9uTnVsbCh2YWx1ZSk7CiAgICAgICAgICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIE1ldGhvZCB8fCB2YWx1ZSBpbnN0YW5jZW9mIFZhcmlhYmxlKQogICAgICAgICAgICAgICAgdmFsdWUgPSAoKERlbGVnYXRlZFN5bWJvbCl2YWx1ZSkuZ2V0VW5kZXJseWluZ1N5bWJvbCgpOwoKICAgICAgICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgTWV0aG9kU3ltYm9sKSB7CiAgICAgICAgICAgICAgICBNZXRob2RTeW1ib2wgbSA9IChNZXRob2RTeW1ib2wpdmFsdWU7CiAgICAgICAgICAgICAgICBpZiAoIW0uaXNEeW5hbWljKCkpIHsKICAgICAgICAgICAgICAgICAgICBwb29sYnVmLmFwcGVuZEJ5dGUoKG0ub3duZXIuZmxhZ3MoKSAmIElOVEVSRkFDRSkgIT0gMAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IENPTlNUQU5UX0ludGVyZmFjZU1ldGhvZHJlZgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IENPTlNUQU5UX01ldGhvZHJlZik7CiAgICAgICAgICAgICAgICAgICAgcG9vbGJ1Zi5hcHBlbmRDaGFyKHBvb2wucHV0KG0ub3duZXIpKTsKICAgICAgICAgICAgICAgICAgICBwb29sYnVmLmFwcGVuZENoYXIocG9vbC5wdXQobmFtZVR5cGUobSkpKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgLy9pbnZva2VkeW5hbWljCiAgICAgICAgICAgICAgICAgICAgRHluYW1pY01ldGhvZFN5bWJvbCBkeW5TeW0gPSAoRHluYW1pY01ldGhvZFN5bWJvbCltOwogICAgICAgICAgICAgICAgICAgIE1ldGhvZEhhbmRsZSBoYW5kbGUgPSBuZXcgTWV0aG9kSGFuZGxlKGR5blN5bS5ic21LaW5kLCBkeW5TeW0uYnNtLCB0eXBlcyk7CiAgICAgICAgICAgICAgICAgICAgRHluYW1pY01ldGhvZC5Cb290c3RyYXBNZXRob2RzS2V5IGtleSA9IG5ldyBEeW5hbWljTWV0aG9kLkJvb3RzdHJhcE1ldGhvZHNLZXkoZHluU3ltLCB0eXBlcyk7CgogICAgICAgICAgICAgICAgICAgIC8vIEZpZ3VyZSBvdXQgdGhlIGluZGV4IGZvciBleGlzdGluZyBCU007IGNyZWF0ZSBhIG5ldyBCU00gaWYgbm8ga2V5CiAgICAgICAgICAgICAgICAgICAgRHluYW1pY01ldGhvZC5Cb290c3RyYXBNZXRob2RzVmFsdWUgdmFsID0gYm9vdHN0cmFwTWV0aG9kcy5nZXQoa2V5KTsKICAgICAgICAgICAgICAgICAgICBpZiAodmFsID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaW50IGluZGV4ID0gYm9vdHN0cmFwTWV0aG9kcy5zaXplKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhbCA9IG5ldyBEeW5hbWljTWV0aG9kLkJvb3RzdHJhcE1ldGhvZHNWYWx1ZShoYW5kbGUsIGluZGV4KTsKICAgICAgICAgICAgICAgICAgICAgICAgYm9vdHN0cmFwTWV0aG9kcy5wdXQoa2V5LCB2YWwpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy9pbml0IGNwIGVudHJpZXMKICAgICAgICAgICAgICAgICAgICBwb29sLnB1dChuYW1lcy5Cb290c3RyYXBNZXRob2RzKTsKICAgICAgICAgICAgICAgICAgICBwb29sLnB1dChoYW5kbGUpOwogICAgICAgICAgICAgICAgICAgIGZvciAoT2JqZWN0IHN0YXRpY0FyZyA6IGR5blN5bS5zdGF0aWNBcmdzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHBvb2wucHV0KHN0YXRpY0FyZyk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHBvb2xidWYuYXBwZW5kQnl0ZShDT05TVEFOVF9JbnZva2VEeW5hbWljKTsKICAgICAgICAgICAgICAgICAgICBwb29sYnVmLmFwcGVuZENoYXIodmFsLmluZGV4KTsKICAgICAgICAgICAgICAgICAgICBwb29sYnVmLmFwcGVuZENoYXIocG9vbC5wdXQobmFtZVR5cGUoZHluU3ltKSkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgaWYgKHZhbHVlIGluc3RhbmNlb2YgVmFyU3ltYm9sKSB7CiAgICAgICAgICAgICAgICBWYXJTeW1ib2wgdiA9IChWYXJTeW1ib2wpdmFsdWU7CiAgICAgICAgICAgICAgICBwb29sYnVmLmFwcGVuZEJ5dGUoQ09OU1RBTlRfRmllbGRyZWYpOwogICAgICAgICAgICAgICAgcG9vbGJ1Zi5hcHBlbmRDaGFyKHBvb2wucHV0KHYub3duZXIpKTsKICAgICAgICAgICAgICAgIHBvb2xidWYuYXBwZW5kQ2hhcihwb29sLnB1dChuYW1lVHlwZSh2KSkpOwogICAgICAgICAgICB9IGVsc2UgaWYgKHZhbHVlIGluc3RhbmNlb2YgTmFtZSkgewogICAgICAgICAgICAgICAgcG9vbGJ1Zi5hcHBlbmRCeXRlKENPTlNUQU5UX1V0ZjgpOwogICAgICAgICAgICAgICAgYnl0ZVtdIGJzID0gKChOYW1lKXZhbHVlKS50b1V0ZigpOwogICAgICAgICAgICAgICAgcG9vbGJ1Zi5hcHBlbmRDaGFyKGJzLmxlbmd0aCk7CiAgICAgICAgICAgICAgICBwb29sYnVmLmFwcGVuZEJ5dGVzKGJzLCAwLCBicy5sZW5ndGgpOwogICAgICAgICAgICAgICAgaWYgKGJzLmxlbmd0aCA+IFBvb2wuTUFYX1NUUklOR19MRU5HVEgpCiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFN0cmluZ092ZXJmbG93KHZhbHVlLnRvU3RyaW5nKCkpOwogICAgICAgICAgICB9IGVsc2UgaWYgKHZhbHVlIGluc3RhbmNlb2YgQ2xhc3NTeW1ib2wpIHsKICAgICAgICAgICAgICAgIENsYXNzU3ltYm9sIGMgPSAoQ2xhc3NTeW1ib2wpdmFsdWU7CiAgICAgICAgICAgICAgICBpZiAoYy5vd25lci5raW5kID09IFRZUCkgcG9vbC5wdXQoYy5vd25lcik7CiAgICAgICAgICAgICAgICBwb29sYnVmLmFwcGVuZEJ5dGUoQ09OU1RBTlRfQ2xhc3MpOwogICAgICAgICAgICAgICAgaWYgKGMudHlwZS5oYXNUYWcoQVJSQVkpKSB7CiAgICAgICAgICAgICAgICAgICAgcG9vbGJ1Zi5hcHBlbmRDaGFyKHBvb2wucHV0KHR5cGVTaWcoYy50eXBlKSkpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBwb29sYnVmLmFwcGVuZENoYXIocG9vbC5wdXQobmFtZXMuZnJvbVV0ZihleHRlcm5hbGl6ZShjLmZsYXRuYW1lKSkpKTsKICAgICAgICAgICAgICAgICAgICBlbnRlcklubmVyKGMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgaWYgKHZhbHVlIGluc3RhbmNlb2YgTmFtZUFuZFR5cGUpIHsKICAgICAgICAgICAgICAgIE5hbWVBbmRUeXBlIG50ID0gKE5hbWVBbmRUeXBlKXZhbHVlOwogICAgICAgICAgICAgICAgcG9vbGJ1Zi5hcHBlbmRCeXRlKENPTlNUQU5UX05hbWVhbmRUeXBlKTsKICAgICAgICAgICAgICAgIHBvb2xidWYuYXBwZW5kQ2hhcihwb29sLnB1dChudC5uYW1lKSk7CiAgICAgICAgICAgICAgICBwb29sYnVmLmFwcGVuZENoYXIocG9vbC5wdXQodHlwZVNpZyhudC51bmlxdWVUeXBlLnR5cGUpKSk7CiAgICAgICAgICAgIH0gZWxzZSBpZiAodmFsdWUgaW5zdGFuY2VvZiBJbnRlZ2VyKSB7CiAgICAgICAgICAgICAgICBwb29sYnVmLmFwcGVuZEJ5dGUoQ09OU1RBTlRfSW50ZWdlcik7CiAgICAgICAgICAgICAgICBwb29sYnVmLmFwcGVuZEludCgoKEludGVnZXIpdmFsdWUpLmludFZhbHVlKCkpOwogICAgICAgICAgICB9IGVsc2UgaWYgKHZhbHVlIGluc3RhbmNlb2YgTG9uZykgewogICAgICAgICAgICAgICAgcG9vbGJ1Zi5hcHBlbmRCeXRlKENPTlNUQU5UX0xvbmcpOwogICAgICAgICAgICAgICAgcG9vbGJ1Zi5hcHBlbmRMb25nKCgoTG9uZyl2YWx1ZSkubG9uZ1ZhbHVlKCkpOwogICAgICAgICAgICAgICAgaSsrOwogICAgICAgICAgICB9IGVsc2UgaWYgKHZhbHVlIGluc3RhbmNlb2YgRmxvYXQpIHsKICAgICAgICAgICAgICAgIHBvb2xidWYuYXBwZW5kQnl0ZShDT05TVEFOVF9GbG9hdCk7CiAgICAgICAgICAgICAgICBwb29sYnVmLmFwcGVuZEZsb2F0KCgoRmxvYXQpdmFsdWUpLmZsb2F0VmFsdWUoKSk7CiAgICAgICAgICAgIH0gZWxzZSBpZiAodmFsdWUgaW5zdGFuY2VvZiBEb3VibGUpIHsKICAgICAgICAgICAgICAgIHBvb2xidWYuYXBwZW5kQnl0ZShDT05TVEFOVF9Eb3VibGUpOwogICAgICAgICAgICAgICAgcG9vbGJ1Zi5hcHBlbmREb3VibGUoKChEb3VibGUpdmFsdWUpLmRvdWJsZVZhbHVlKCkpOwogICAgICAgICAgICAgICAgaSsrOwogICAgICAgICAgICB9IGVsc2UgaWYgKHZhbHVlIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICAgICAgICBwb29sYnVmLmFwcGVuZEJ5dGUoQ09OU1RBTlRfU3RyaW5nKTsKICAgICAgICAgICAgICAgIHBvb2xidWYuYXBwZW5kQ2hhcihwb29sLnB1dChuYW1lcy5mcm9tU3RyaW5nKChTdHJpbmcpdmFsdWUpKSk7CiAgICAgICAgICAgIH0gZWxzZSBpZiAodmFsdWUgaW5zdGFuY2VvZiBVbmlxdWVUeXBlKSB7CiAgICAgICAgICAgICAgICBUeXBlIHR5cGUgPSAoKFVuaXF1ZVR5cGUpdmFsdWUpLnR5cGU7CiAgICAgICAgICAgICAgICBpZiAodHlwZS5oYXNUYWcoTUVUSE9EKSkgewogICAgICAgICAgICAgICAgICAgIHBvb2xidWYuYXBwZW5kQnl0ZShDT05TVEFOVF9NZXRob2RUeXBlKTsKICAgICAgICAgICAgICAgICAgICBwb29sYnVmLmFwcGVuZENoYXIocG9vbC5wdXQodHlwZVNpZygoTWV0aG9kVHlwZSl0eXBlKSkpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBBc3NlcnQuY2hlY2sodHlwZS5oYXNUYWcoQVJSQVkpKTsKICAgICAgICAgICAgICAgICAgICBwb29sYnVmLmFwcGVuZEJ5dGUoQ09OU1RBTlRfQ2xhc3MpOwogICAgICAgICAgICAgICAgICAgIHBvb2xidWYuYXBwZW5kQ2hhcihwb29sLnB1dCh4Q2xhc3NOYW1lKHR5cGUpKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSBpZiAodmFsdWUgaW5zdGFuY2VvZiBNZXRob2RIYW5kbGUpIHsKICAgICAgICAgICAgICAgIE1ldGhvZEhhbmRsZSByZWYgPSAoTWV0aG9kSGFuZGxlKXZhbHVlOwogICAgICAgICAgICAgICAgcG9vbGJ1Zi5hcHBlbmRCeXRlKENPTlNUQU5UX01ldGhvZEhhbmRsZSk7CiAgICAgICAgICAgICAgICBwb29sYnVmLmFwcGVuZEJ5dGUocmVmLnJlZktpbmQpOwogICAgICAgICAgICAgICAgcG9vbGJ1Zi5hcHBlbmRDaGFyKHBvb2wucHV0KHJlZi5yZWZTeW0pKTsKICAgICAgICAgICAgfSBlbHNlIGlmICh2YWx1ZSBpbnN0YW5jZW9mIE1vZHVsZVN5bWJvbCkgewogICAgICAgICAgICAgICAgTW9kdWxlU3ltYm9sIG0gPSAoTW9kdWxlU3ltYm9sKXZhbHVlOwogICAgICAgICAgICAgICAgcG9vbGJ1Zi5hcHBlbmRCeXRlKENPTlNUQU5UX01vZHVsZSk7CiAgICAgICAgICAgICAgICBwb29sYnVmLmFwcGVuZENoYXIocG9vbC5wdXQobS5uYW1lKSk7CiAgICAgICAgICAgIH0gZWxzZSBpZiAodmFsdWUgaW5zdGFuY2VvZiBQYWNrYWdlU3ltYm9sKSB7CiAgICAgICAgICAgICAgICBQYWNrYWdlU3ltYm9sIG0gPSAoUGFja2FnZVN5bWJvbCl2YWx1ZTsKICAgICAgICAgICAgICAgIHBvb2xidWYuYXBwZW5kQnl0ZShDT05TVEFOVF9QYWNrYWdlKTsKICAgICAgICAgICAgICAgIHBvb2xidWYuYXBwZW5kQ2hhcihwb29sLnB1dChuYW1lcy5mcm9tVXRmKGV4dGVybmFsaXplKG0uZnVsbG5hbWUpKSkpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgQXNzZXJ0LmVycm9yKCJ3cml0ZVBvb2wgIiArIHZhbHVlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpKys7CiAgICAgICAgfQogICAgICAgIGlmIChwb29sLnBwID4gUG9vbC5NQVhfRU5UUklFUykKICAgICAgICAgICAgdGhyb3cgbmV3IFBvb2xPdmVyZmxvdygpOwogICAgICAgIHB1dENoYXIocG9vbGJ1ZiwgcG9vbENvdW50SWR4LCBwb29sLnBwKTsKICAgIH0KCiAgICAvKiogR2l2ZW4gYSBzeW1ib2wsIHJldHVybiBpdHMgbmFtZS1hbmQtdHlwZS4KICAgICAqLwogICAgTmFtZUFuZFR5cGUgbmFtZVR5cGUoU3ltYm9sIHN5bSkgewogICAgICAgIHJldHVybiBuZXcgTmFtZUFuZFR5cGUoc3ltLm5hbWUsIHN5bS5leHRlcm5hbFR5cGUodHlwZXMpLCB0eXBlcyk7CiAgICAgICAgLy8gdGhlIE5hbWVBbmRUeXBlIGlzIGdlbmVyYXRlZCBmcm9tIGEgc3ltYm9sIHJlZmVyZW5jZSwgYW5kIHRoZQogICAgICAgIC8vIGFkanVzdG1lbnQgb2YgYWRkaW5nIGFuIGFkZGl0aW9uYWwgdGhpcyRuIHBhcmFtZXRlciBuZWVkcyB0byBiZSBtYWRlLgogICAgfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBXcml0aW5nIEF0dHJpYnV0ZXMKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiAgICAvKiogV3JpdGUgaGVhZGVyIGZvciBhbiBhdHRyaWJ1dGUgdG8gZGF0YSBidWZmZXIgYW5kIHJldHVybgogICAgICogIHBvc2l0aW9uIHBhc3QgYXR0cmlidXRlIGxlbmd0aCBpbmRleC4KICAgICAqLwogICAgaW50IHdyaXRlQXR0cihOYW1lIGF0dHJOYW1lKSB7CiAgICAgICAgZGF0YWJ1Zi5hcHBlbmRDaGFyKHBvb2wucHV0KGF0dHJOYW1lKSk7CiAgICAgICAgZGF0YWJ1Zi5hcHBlbmRJbnQoMCk7CiAgICAgICAgcmV0dXJuIGRhdGFidWYubGVuZ3RoOwogICAgfQoKICAgIC8qKiBGaWxsIGluIGF0dHJpYnV0ZSBsZW5ndGguCiAgICAgKi8KICAgIHZvaWQgZW5kQXR0cihpbnQgaW5kZXgpIHsKICAgICAgICBwdXRJbnQoZGF0YWJ1ZiwgaW5kZXggLSA0LCBkYXRhYnVmLmxlbmd0aCAtIGluZGV4KTsKICAgIH0KCiAgICAvKiogTGVhdmUgc3BhY2UgZm9yIGF0dHJpYnV0ZSBjb3VudCBhbmQgcmV0dXJuIGluZGV4IGZvcgogICAgICogIG51bWJlciBvZiBhdHRyaWJ1dGVzIGZpZWxkLgogICAgICovCiAgICBpbnQgYmVnaW5BdHRycygpIHsKICAgICAgICBkYXRhYnVmLmFwcGVuZENoYXIoMCk7CiAgICAgICAgcmV0dXJuIGRhdGFidWYubGVuZ3RoOwogICAgfQoKICAgIC8qKiBGaWxsIGluIG51bWJlciBvZiBhdHRyaWJ1dGVzLgogICAgICovCiAgICB2b2lkIGVuZEF0dHJzKGludCBpbmRleCwgaW50IGNvdW50KSB7CiAgICAgICAgcHV0Q2hhcihkYXRhYnVmLCBpbmRleCAtIDIsIGNvdW50KTsKICAgIH0KCiAgICAvKiogV3JpdGUgdGhlIEVuY2xvc2luZ01ldGhvZCBhdHRyaWJ1dGUgaWYgbmVlZGVkLgogICAgICogIFJldHVybnMgdGhlIG51bWJlciBvZiBhdHRyaWJ1dGVzIHdyaXR0ZW4gKDAgb3IgMSkuCiAgICAgKi8KICAgIGludCB3cml0ZUVuY2xvc2luZ01ldGhvZEF0dHJpYnV0ZShDbGFzc1N5bWJvbCBjKSB7CiAgICAgICAgcmV0dXJuIHdyaXRlRW5jbG9zaW5nTWV0aG9kQXR0cmlidXRlKG5hbWVzLkVuY2xvc2luZ01ldGhvZCwgYyk7CiAgICB9CgogICAgLyoqIFdyaXRlIHRoZSBFbmNsb3NpbmdNZXRob2QgYXR0cmlidXRlIHdpdGggYSBzcGVjaWZpZWQgbmFtZS4KICAgICAqICBSZXR1cm5zIHRoZSBudW1iZXIgb2YgYXR0cmlidXRlcyB3cml0dGVuICgwIG9yIDEpLgogICAgICovCiAgICBwcm90ZWN0ZWQgaW50IHdyaXRlRW5jbG9zaW5nTWV0aG9kQXR0cmlidXRlKE5hbWUgYXR0cmlidXRlTmFtZSwgQ2xhc3NTeW1ib2wgYykgewogICAgICAgIGlmIChjLm93bmVyLmtpbmQgIT0gTVRIICYmIC8vIG5laXRoZXIgYSBsb2NhbCBjbGFzcwogICAgICAgICAgICBjLm5hbWUgIT0gbmFtZXMuZW1wdHkpIC8vIG5vciBhbm9ueW1vdXMKICAgICAgICAgICAgcmV0dXJuIDA7CgogICAgICAgIGludCBhbGVuSWR4ID0gd3JpdGVBdHRyKGF0dHJpYnV0ZU5hbWUpOwogICAgICAgIENsYXNzU3ltYm9sIGVuY2xDbGFzcyA9IGMub3duZXIuZW5jbENsYXNzKCk7CiAgICAgICAgTWV0aG9kU3ltYm9sIGVuY2xNZXRob2QgPQogICAgICAgICAgICAoYy5vd25lci50eXBlID09IG51bGwgLy8gbG9jYWwgdG8gaW5pdCBibG9jawogICAgICAgICAgICAgfHwgYy5vd25lci5raW5kICE9IE1USCkgLy8gb3IgbWVtYmVyIGluaXQKICAgICAgICAgICAgPyBudWxsCiAgICAgICAgICAgIDogKE1ldGhvZFN5bWJvbCljLm93bmVyOwogICAgICAgIGRhdGFidWYuYXBwZW5kQ2hhcihwb29sLnB1dChlbmNsQ2xhc3MpKTsKICAgICAgICBkYXRhYnVmLmFwcGVuZENoYXIoZW5jbE1ldGhvZCA9PSBudWxsID8gMCA6IHBvb2wucHV0KG5hbWVUeXBlKGMub3duZXIpKSk7CiAgICAgICAgZW5kQXR0cihhbGVuSWR4KTsKICAgICAgICByZXR1cm4gMTsKICAgIH0KCiAgICAvKiogV3JpdGUgZmxhZyBhdHRyaWJ1dGVzOyByZXR1cm4gbnVtYmVyIG9mIGF0dHJpYnV0ZXMgd3JpdHRlbi4KICAgICAqLwogICAgaW50IHdyaXRlRmxhZ0F0dHJzKGxvbmcgZmxhZ3MpIHsKICAgICAgICBpbnQgYWNvdW50ID0gMDsKICAgICAgICBpZiAoKGZsYWdzICYgREVQUkVDQVRFRCkgIT0gMCkgewogICAgICAgICAgICBpbnQgYWxlbklkeCA9IHdyaXRlQXR0cihuYW1lcy5EZXByZWNhdGVkKTsKICAgICAgICAgICAgZW5kQXR0cihhbGVuSWR4KTsKICAgICAgICAgICAgYWNvdW50Kys7CiAgICAgICAgfQogICAgICAgIHJldHVybiBhY291bnQ7CiAgICB9CgogICAgLyoqIFdyaXRlIG1lbWJlciAoZmllbGQgb3IgbWV0aG9kKSBhdHRyaWJ1dGVzOwogICAgICogIHJldHVybiBudW1iZXIgb2YgYXR0cmlidXRlcyB3cml0dGVuLgogICAgICovCiAgICBpbnQgd3JpdGVNZW1iZXJBdHRycyhTeW1ib2wgc3ltKSB7CiAgICAgICAgaW50IGFjb3VudCA9IHdyaXRlRmxhZ0F0dHJzKHN5bS5mbGFncygpKTsKICAgICAgICBsb25nIGZsYWdzID0gc3ltLmZsYWdzKCk7CiAgICAgICAgaWYgKChmbGFncyAmIChTWU5USEVUSUMgfCBCUklER0UpKSAhPSBTWU5USEVUSUMgJiYKICAgICAgICAgICAgKGZsYWdzICYgQU5PTkNPTlNUUikgPT0gMCAmJgogICAgICAgICAgICAoIXR5cGVzLmlzU2FtZVR5cGUoc3ltLnR5cGUsIHN5bS5lcmFzdXJlKHR5cGVzKSkgfHwKICAgICAgICAgICAgIHNpZ25hdHVyZUdlbi5oYXNUeXBlVmFyKHN5bS50eXBlLmdldFRocm93blR5cGVzKCkpKSkgewogICAgICAgICAgICAvLyBub3RlIHRoYXQgYSBsb2NhbCBjbGFzcyB3aXRoIGNhcHR1cmVkIHZhcmlhYmxlcwogICAgICAgICAgICAvLyB3aWxsIGdldCBhIHNpZ25hdHVyZSBhdHRyaWJ1dGUKICAgICAgICAgICAgaW50IGFsZW5JZHggPSB3cml0ZUF0dHIobmFtZXMuU2lnbmF0dXJlKTsKICAgICAgICAgICAgZGF0YWJ1Zi5hcHBlbmRDaGFyKHBvb2wucHV0KHR5cGVTaWcoc3ltLnR5cGUpKSk7CiAgICAgICAgICAgIGVuZEF0dHIoYWxlbklkeCk7CiAgICAgICAgICAgIGFjb3VudCsrOwogICAgICAgIH0KICAgICAgICBhY291bnQgKz0gd3JpdGVKYXZhQW5ub3RhdGlvbnMoc3ltLmdldFJhd0F0dHJpYnV0ZXMoKSk7CiAgICAgICAgYWNvdW50ICs9IHdyaXRlVHlwZUFubm90YXRpb25zKHN5bS5nZXRSYXdUeXBlQXR0cmlidXRlcygpLCBmYWxzZSk7CiAgICAgICAgcmV0dXJuIGFjb3VudDsKICAgIH0KCiAgICAvKioKICAgICAqIFdyaXRlIG1ldGhvZCBwYXJhbWV0ZXIgbmFtZXMgYXR0cmlidXRlLgogICAgICovCiAgICBpbnQgd3JpdGVNZXRob2RQYXJhbWV0ZXJzQXR0cihNZXRob2RTeW1ib2wgbSkgewogICAgICAgIE1ldGhvZFR5cGUgdHkgPSBtLmV4dGVybmFsVHlwZSh0eXBlcykuYXNNZXRob2RUeXBlKCk7CiAgICAgICAgZmluYWwgaW50IGFsbHBhcmFtcyA9IHR5LmFyZ3R5cGVzLnNpemUoKTsKICAgICAgICBpZiAobS5wYXJhbXMgIT0gbnVsbCAmJiBhbGxwYXJhbXMgIT0gMCkgewogICAgICAgICAgICBmaW5hbCBpbnQgYXR0ckluZGV4ID0gd3JpdGVBdHRyKG5hbWVzLk1ldGhvZFBhcmFtZXRlcnMpOwogICAgICAgICAgICBkYXRhYnVmLmFwcGVuZEJ5dGUoYWxscGFyYW1zKTsKICAgICAgICAgICAgLy8gV3JpdGUgZXh0cmEgcGFyYW1ldGVycyBmaXJzdAogICAgICAgICAgICBmb3IgKFZhclN5bWJvbCBzIDogbS5leHRyYVBhcmFtcykgewogICAgICAgICAgICAgICAgZmluYWwgaW50IGZsYWdzID0KICAgICAgICAgICAgICAgICAgICAoKGludCkgcy5mbGFncygpICYgKEZJTkFMIHwgU1lOVEhFVElDIHwgTUFOREFURUQpKSB8CiAgICAgICAgICAgICAgICAgICAgKChpbnQpIG0uZmxhZ3MoKSAmIFNZTlRIRVRJQyk7CiAgICAgICAgICAgICAgICBkYXRhYnVmLmFwcGVuZENoYXIocG9vbC5wdXQocy5uYW1lKSk7CiAgICAgICAgICAgICAgICBkYXRhYnVmLmFwcGVuZENoYXIoZmxhZ3MpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIE5vdyB3cml0ZSB0aGUgcmVhbCBwYXJhbWV0ZXJzCiAgICAgICAgICAgIGZvciAoVmFyU3ltYm9sIHMgOiBtLnBhcmFtcykgewogICAgICAgICAgICAgICAgZmluYWwgaW50IGZsYWdzID0KICAgICAgICAgICAgICAgICAgICAoKGludCkgcy5mbGFncygpICYgKEZJTkFMIHwgU1lOVEhFVElDIHwgTUFOREFURUQpKSB8CiAgICAgICAgICAgICAgICAgICAgKChpbnQpIG0uZmxhZ3MoKSAmIFNZTlRIRVRJQyk7CiAgICAgICAgICAgICAgICBkYXRhYnVmLmFwcGVuZENoYXIocG9vbC5wdXQocy5uYW1lKSk7CiAgICAgICAgICAgICAgICBkYXRhYnVmLmFwcGVuZENoYXIoZmxhZ3MpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIE5vdyB3cml0ZSB0aGUgY2FwdHVyZWQgbG9jYWxzCiAgICAgICAgICAgIGZvciAoVmFyU3ltYm9sIHMgOiBtLmNhcHR1cmVkTG9jYWxzKSB7CiAgICAgICAgICAgICAgICBmaW5hbCBpbnQgZmxhZ3MgPQogICAgICAgICAgICAgICAgICAgICgoaW50KSBzLmZsYWdzKCkgJiAoRklOQUwgfCBTWU5USEVUSUMgfCBNQU5EQVRFRCkpIHwKICAgICAgICAgICAgICAgICAgICAoKGludCkgbS5mbGFncygpICYgU1lOVEhFVElDKTsKICAgICAgICAgICAgICAgIGRhdGFidWYuYXBwZW5kQ2hhcihwb29sLnB1dChzLm5hbWUpKTsKICAgICAgICAgICAgICAgIGRhdGFidWYuYXBwZW5kQ2hhcihmbGFncyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZW5kQXR0cihhdHRySW5kZXgpOwogICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICB9IGVsc2UKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICB9CgoKICAgIHByaXZhdGUgdm9pZCB3cml0ZVBhcmFtQW5ub3RhdGlvbnMoTGlzdDxWYXJTeW1ib2w+IHBhcmFtcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmV0ZW50aW9uUG9saWN5IHJldGVudGlvbikgewogICAgICAgIGZvciAoVmFyU3ltYm9sIHMgOiBwYXJhbXMpIHsKICAgICAgICAgICAgTGlzdEJ1ZmZlcjxBdHRyaWJ1dGUuQ29tcG91bmQ+IGJ1ZiA9IG5ldyBMaXN0QnVmZmVyPD4oKTsKICAgICAgICAgICAgZm9yIChBdHRyaWJ1dGUuQ29tcG91bmQgYSA6IHMuZ2V0UmF3QXR0cmlidXRlcygpKQogICAgICAgICAgICAgICAgaWYgKHR5cGVzLmdldFJldGVudGlvbihhKSA9PSByZXRlbnRpb24pCiAgICAgICAgICAgICAgICAgICAgYnVmLmFwcGVuZChhKTsKICAgICAgICAgICAgZGF0YWJ1Zi5hcHBlbmRDaGFyKGJ1Zi5sZW5ndGgoKSk7CiAgICAgICAgICAgIGZvciAoQXR0cmlidXRlLkNvbXBvdW5kIGEgOiBidWYpCiAgICAgICAgICAgICAgICB3cml0ZUNvbXBvdW5kQXR0cmlidXRlKGEpOwogICAgICAgIH0KCiAgICB9CgogICAgcHJpdmF0ZSB2b2lkIHdyaXRlUGFyYW1Bbm5vdGF0aW9ucyhNZXRob2RTeW1ib2wgbSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmV0ZW50aW9uUG9saWN5IHJldGVudGlvbikgewogICAgICAgIGRhdGFidWYuYXBwZW5kQnl0ZShtLnBhcmFtcy5sZW5ndGgoKSk7CiAgICAgICAgd3JpdGVQYXJhbUFubm90YXRpb25zKG0ucGFyYW1zLCByZXRlbnRpb24pOwogICAgfQoKICAgIC8qKiBXcml0ZSBtZXRob2QgcGFyYW1ldGVyIGFubm90YXRpb25zOwogICAgICogIHJldHVybiBudW1iZXIgb2YgYXR0cmlidXRlcyB3cml0dGVuLgogICAgICovCiAgICBpbnQgd3JpdGVQYXJhbWV0ZXJBdHRycyhNZXRob2RTeW1ib2wgbSkgewogICAgICAgIGJvb2xlYW4gaGFzVmlzaWJsZSA9IGZhbHNlOwogICAgICAgIGJvb2xlYW4gaGFzSW52aXNpYmxlID0gZmFsc2U7CiAgICAgICAgaWYgKG0ucGFyYW1zICE9IG51bGwpIHsKICAgICAgICAgICAgZm9yIChWYXJTeW1ib2wgcyA6IG0ucGFyYW1zKSB7CiAgICAgICAgICAgICAgICBmb3IgKEF0dHJpYnV0ZS5Db21wb3VuZCBhIDogcy5nZXRSYXdBdHRyaWJ1dGVzKCkpIHsKICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKHR5cGVzLmdldFJldGVudGlvbihhKSkgewogICAgICAgICAgICAgICAgICAgIGNhc2UgU09VUkNFOiBicmVhazsKICAgICAgICAgICAgICAgICAgICBjYXNlIENMQVNTOiBoYXNJbnZpc2libGUgPSB0cnVlOyBicmVhazsKICAgICAgICAgICAgICAgICAgICBjYXNlIFJVTlRJTUU6IGhhc1Zpc2libGUgPSB0cnVlOyBicmVhazsKICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OiAvLyAvKiBmYWlsIHNvZnQgKi8gdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKHZpcyk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpbnQgYXR0ckNvdW50ID0gMDsKICAgICAgICBpZiAoaGFzVmlzaWJsZSkgewogICAgICAgICAgICBpbnQgYXR0ckluZGV4ID0gd3JpdGVBdHRyKG5hbWVzLlJ1bnRpbWVWaXNpYmxlUGFyYW1ldGVyQW5ub3RhdGlvbnMpOwogICAgICAgICAgICB3cml0ZVBhcmFtQW5ub3RhdGlvbnMobSwgUmV0ZW50aW9uUG9saWN5LlJVTlRJTUUpOwogICAgICAgICAgICBlbmRBdHRyKGF0dHJJbmRleCk7CiAgICAgICAgICAgIGF0dHJDb3VudCsrOwogICAgICAgIH0KICAgICAgICBpZiAoaGFzSW52aXNpYmxlKSB7CiAgICAgICAgICAgIGludCBhdHRySW5kZXggPSB3cml0ZUF0dHIobmFtZXMuUnVudGltZUludmlzaWJsZVBhcmFtZXRlckFubm90YXRpb25zKTsKICAgICAgICAgICAgd3JpdGVQYXJhbUFubm90YXRpb25zKG0sIFJldGVudGlvblBvbGljeS5DTEFTUyk7CiAgICAgICAgICAgIGVuZEF0dHIoYXR0ckluZGV4KTsKICAgICAgICAgICAgYXR0ckNvdW50Kys7CiAgICAgICAgfQogICAgICAgIHJldHVybiBhdHRyQ291bnQ7CiAgICB9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBXcml0aW5nIEphdmEtbGFuZ3VhZ2UgYW5ub3RhdGlvbnMgKGFrYSBtZXRhZGF0YSwgYXR0cmlidXRlcykKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgogICAgLyoqIFdyaXRlIEphdmEtbGFuZ3VhZ2UgYW5ub3RhdGlvbnM7IHJldHVybiBudW1iZXIgb2YgSlZNCiAgICAgKiAgYXR0cmlidXRlcyB3cml0dGVuICh6ZXJvIG9yIG9uZSkuCiAgICAgKi8KICAgIGludCB3cml0ZUphdmFBbm5vdGF0aW9ucyhMaXN0PEF0dHJpYnV0ZS5Db21wb3VuZD4gYXR0cnMpIHsKICAgICAgICBpZiAoYXR0cnMuaXNFbXB0eSgpKSByZXR1cm4gMDsKICAgICAgICBMaXN0QnVmZmVyPEF0dHJpYnV0ZS5Db21wb3VuZD4gdmlzaWJsZXMgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgTGlzdEJ1ZmZlcjxBdHRyaWJ1dGUuQ29tcG91bmQ+IGludmlzaWJsZXMgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgZm9yIChBdHRyaWJ1dGUuQ29tcG91bmQgYSA6IGF0dHJzKSB7CiAgICAgICAgICAgIHN3aXRjaCAodHlwZXMuZ2V0UmV0ZW50aW9uKGEpKSB7CiAgICAgICAgICAgIGNhc2UgU09VUkNFOiBicmVhazsKICAgICAgICAgICAgY2FzZSBDTEFTUzogaW52aXNpYmxlcy5hcHBlbmQoYSk7IGJyZWFrOwogICAgICAgICAgICBjYXNlIFJVTlRJTUU6IHZpc2libGVzLmFwcGVuZChhKTsgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6IC8vIC8qIGZhaWwgc29mdCAqLyB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IodmlzKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaW50IGF0dHJDb3VudCA9IDA7CiAgICAgICAgaWYgKHZpc2libGVzLmxlbmd0aCgpICE9IDApIHsKICAgICAgICAgICAgaW50IGF0dHJJbmRleCA9IHdyaXRlQXR0cihuYW1lcy5SdW50aW1lVmlzaWJsZUFubm90YXRpb25zKTsKICAgICAgICAgICAgZGF0YWJ1Zi5hcHBlbmRDaGFyKHZpc2libGVzLmxlbmd0aCgpKTsKICAgICAgICAgICAgZm9yIChBdHRyaWJ1dGUuQ29tcG91bmQgYSA6IHZpc2libGVzKQogICAgICAgICAgICAgICAgd3JpdGVDb21wb3VuZEF0dHJpYnV0ZShhKTsKICAgICAgICAgICAgZW5kQXR0cihhdHRySW5kZXgpOwogICAgICAgICAgICBhdHRyQ291bnQrKzsKICAgICAgICB9CiAgICAgICAgaWYgKGludmlzaWJsZXMubGVuZ3RoKCkgIT0gMCkgewogICAgICAgICAgICBpbnQgYXR0ckluZGV4ID0gd3JpdGVBdHRyKG5hbWVzLlJ1bnRpbWVJbnZpc2libGVBbm5vdGF0aW9ucyk7CiAgICAgICAgICAgIGRhdGFidWYuYXBwZW5kQ2hhcihpbnZpc2libGVzLmxlbmd0aCgpKTsKICAgICAgICAgICAgZm9yIChBdHRyaWJ1dGUuQ29tcG91bmQgYSA6IGludmlzaWJsZXMpCiAgICAgICAgICAgICAgICB3cml0ZUNvbXBvdW5kQXR0cmlidXRlKGEpOwogICAgICAgICAgICBlbmRBdHRyKGF0dHJJbmRleCk7CiAgICAgICAgICAgIGF0dHJDb3VudCsrOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYXR0ckNvdW50OwogICAgfQoKICAgIGludCB3cml0ZVR5cGVBbm5vdGF0aW9ucyhMaXN0PEF0dHJpYnV0ZS5UeXBlQ29tcG91bmQ+IHR5cGVBbm5vcywgYm9vbGVhbiBpbkNvZGUpIHsKICAgICAgICBpZiAodHlwZUFubm9zLmlzRW1wdHkoKSkgcmV0dXJuIDA7CgogICAgICAgIExpc3RCdWZmZXI8QXR0cmlidXRlLlR5cGVDb21wb3VuZD4gdmlzaWJsZXMgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgTGlzdEJ1ZmZlcjxBdHRyaWJ1dGUuVHlwZUNvbXBvdW5kPiBpbnZpc2libGVzID0gbmV3IExpc3RCdWZmZXI8PigpOwoKICAgICAgICBmb3IgKEF0dHJpYnV0ZS5UeXBlQ29tcG91bmQgdGMgOiB0eXBlQW5ub3MpIHsKICAgICAgICAgICAgaWYgKHRjLmhhc1Vua25vd25Qb3NpdGlvbigpKSB7CiAgICAgICAgICAgICAgICBib29sZWFuIGZpeGVkID0gdGMudHJ5Rml4UG9zaXRpb24oKTsKCiAgICAgICAgICAgICAgICAvLyBDb3VsZCB3ZSBmaXggaXQ/CiAgICAgICAgICAgICAgICBpZiAoIWZpeGVkKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gVGhpcyBoYXBwZW5zIGZvciBuZXN0ZWQgdHlwZXMgbGlrZSBAQSBPdXRlci4gQEIgSW5uZXIuCiAgICAgICAgICAgICAgICAgICAgLy8gRm9yIG1ldGhvZCBwYXJhbWV0ZXJzIHdlIGdldCB0aGUgYW5ub3RhdGlvbiB0d2ljZSEgT25jZSB3aXRoCiAgICAgICAgICAgICAgICAgICAgLy8gYSB2YWxpZCBwb3NpdGlvbiwgb25jZSB1bmtub3duLgogICAgICAgICAgICAgICAgICAgIC8vIFRPRE86IGZpbmQgYSBjbGVhbmVyIHNvbHV0aW9uLgogICAgICAgICAgICAgICAgICAgIFByaW50V3JpdGVyIHB3ID0gbG9nLmdldFdyaXRlcihMb2cuV3JpdGVyS2luZC5FUlJPUik7CiAgICAgICAgICAgICAgICAgICAgcHcucHJpbnRsbigiQ2xhc3NXcml0ZXI6IFBvc2l0aW9uIFVOS05PV04gaW4gdHlwZSBhbm5vdGF0aW9uOiAiICsgdGMpOwogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAodGMucG9zaXRpb24udHlwZS5pc0xvY2FsKCkgIT0gaW5Db2RlKQogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIGlmICghdGMucG9zaXRpb24uZW1pdFRvQ2xhc3NmaWxlKCkpCiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgc3dpdGNoICh0eXBlcy5nZXRSZXRlbnRpb24odGMpKSB7CiAgICAgICAgICAgIGNhc2UgU09VUkNFOiBicmVhazsKICAgICAgICAgICAgY2FzZSBDTEFTUzogaW52aXNpYmxlcy5hcHBlbmQodGMpOyBicmVhazsKICAgICAgICAgICAgY2FzZSBSVU5USU1FOiB2aXNpYmxlcy5hcHBlbmQodGMpOyBicmVhazsKICAgICAgICAgICAgZGVmYXVsdDogLy8gLyogZmFpbCBzb2Z0ICovIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcih2aXMpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpbnQgYXR0ckNvdW50ID0gMDsKICAgICAgICBpZiAodmlzaWJsZXMubGVuZ3RoKCkgIT0gMCkgewogICAgICAgICAgICBpbnQgYXR0ckluZGV4ID0gd3JpdGVBdHRyKG5hbWVzLlJ1bnRpbWVWaXNpYmxlVHlwZUFubm90YXRpb25zKTsKICAgICAgICAgICAgZGF0YWJ1Zi5hcHBlbmRDaGFyKHZpc2libGVzLmxlbmd0aCgpKTsKICAgICAgICAgICAgZm9yIChBdHRyaWJ1dGUuVHlwZUNvbXBvdW5kIHAgOiB2aXNpYmxlcykKICAgICAgICAgICAgICAgIHdyaXRlVHlwZUFubm90YXRpb24ocCk7CiAgICAgICAgICAgIGVuZEF0dHIoYXR0ckluZGV4KTsKICAgICAgICAgICAgYXR0ckNvdW50Kys7CiAgICAgICAgfQoKICAgICAgICBpZiAoaW52aXNpYmxlcy5sZW5ndGgoKSAhPSAwKSB7CiAgICAgICAgICAgIGludCBhdHRySW5kZXggPSB3cml0ZUF0dHIobmFtZXMuUnVudGltZUludmlzaWJsZVR5cGVBbm5vdGF0aW9ucyk7CiAgICAgICAgICAgIGRhdGFidWYuYXBwZW5kQ2hhcihpbnZpc2libGVzLmxlbmd0aCgpKTsKICAgICAgICAgICAgZm9yIChBdHRyaWJ1dGUuVHlwZUNvbXBvdW5kIHAgOiBpbnZpc2libGVzKQogICAgICAgICAgICAgICAgd3JpdGVUeXBlQW5ub3RhdGlvbihwKTsKICAgICAgICAgICAgZW5kQXR0cihhdHRySW5kZXgpOwogICAgICAgICAgICBhdHRyQ291bnQrKzsKICAgICAgICB9CgogICAgICAgIHJldHVybiBhdHRyQ291bnQ7CiAgICB9CgogICAgLyoqIEEgdmlzaXRvciB0byB3cml0ZSBhbiBhdHRyaWJ1dGUgaW5jbHVkaW5nIGl0cyBsZWFkaW5nCiAgICAgKiAgc2luZ2xlLWNoYXJhY3RlciBtYXJrZXIuCiAgICAgKi8KICAgIGNsYXNzIEF0dHJpYnV0ZVdyaXRlciBpbXBsZW1lbnRzIEF0dHJpYnV0ZS5WaXNpdG9yIHsKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdENvbnN0YW50KEF0dHJpYnV0ZS5Db25zdGFudCBfdmFsdWUpIHsKICAgICAgICAgICAgT2JqZWN0IHZhbHVlID0gX3ZhbHVlLnZhbHVlOwogICAgICAgICAgICBzd2l0Y2ggKF92YWx1ZS50eXBlLmdldFRhZygpKSB7CiAgICAgICAgICAgIGNhc2UgQllURToKICAgICAgICAgICAgICAgIGRhdGFidWYuYXBwZW5kQnl0ZSgnQicpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgQ0hBUjoKICAgICAgICAgICAgICAgIGRhdGFidWYuYXBwZW5kQnl0ZSgnQycpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgU0hPUlQ6CiAgICAgICAgICAgICAgICBkYXRhYnVmLmFwcGVuZEJ5dGUoJ1MnKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIElOVDoKICAgICAgICAgICAgICAgIGRhdGFidWYuYXBwZW5kQnl0ZSgnSScpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgTE9ORzoKICAgICAgICAgICAgICAgIGRhdGFidWYuYXBwZW5kQnl0ZSgnSicpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgRkxPQVQ6CiAgICAgICAgICAgICAgICBkYXRhYnVmLmFwcGVuZEJ5dGUoJ0YnKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIERPVUJMRToKICAgICAgICAgICAgICAgIGRhdGFidWYuYXBwZW5kQnl0ZSgnRCcpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgQk9PTEVBTjoKICAgICAgICAgICAgICAgIGRhdGFidWYuYXBwZW5kQnl0ZSgnWicpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgQ0xBU1M6CiAgICAgICAgICAgICAgICBBc3NlcnQuY2hlY2sodmFsdWUgaW5zdGFuY2VvZiBTdHJpbmcpOwogICAgICAgICAgICAgICAgZGF0YWJ1Zi5hcHBlbmRCeXRlKCdzJyk7CiAgICAgICAgICAgICAgICB2YWx1ZSA9IG5hbWVzLmZyb21TdHJpbmcodmFsdWUudG9TdHJpbmcoKSk7IC8vIENPTlNUQU5UX1V0ZjgKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKF92YWx1ZS50eXBlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBkYXRhYnVmLmFwcGVuZENoYXIocG9vbC5wdXQodmFsdWUpKTsKICAgICAgICB9CiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRFbnVtKEF0dHJpYnV0ZS5FbnVtIGUpIHsKICAgICAgICAgICAgZGF0YWJ1Zi5hcHBlbmRCeXRlKCdlJyk7CiAgICAgICAgICAgIGRhdGFidWYuYXBwZW5kQ2hhcihwb29sLnB1dCh0eXBlU2lnKGUudmFsdWUudHlwZSkpKTsKICAgICAgICAgICAgZGF0YWJ1Zi5hcHBlbmRDaGFyKHBvb2wucHV0KGUudmFsdWUubmFtZSkpOwogICAgICAgIH0KICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdENsYXNzKEF0dHJpYnV0ZS5DbGFzcyBjbGF6eikgewogICAgICAgICAgICBkYXRhYnVmLmFwcGVuZEJ5dGUoJ2MnKTsKICAgICAgICAgICAgZGF0YWJ1Zi5hcHBlbmRDaGFyKHBvb2wucHV0KHR5cGVTaWcodHlwZXMuZXJhc3VyZShjbGF6ei5jbGFzc1R5cGUpKSkpOwogICAgICAgIH0KICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdENvbXBvdW5kKEF0dHJpYnV0ZS5Db21wb3VuZCBjb21wb3VuZCkgewogICAgICAgICAgICBkYXRhYnVmLmFwcGVuZEJ5dGUoJ0AnKTsKICAgICAgICAgICAgd3JpdGVDb21wb3VuZEF0dHJpYnV0ZShjb21wb3VuZCk7CiAgICAgICAgfQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0RXJyb3IoQXR0cmlidXRlLkVycm9yIHgpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKHgpOwogICAgICAgIH0KICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdEFycmF5KEF0dHJpYnV0ZS5BcnJheSBhcnJheSkgewogICAgICAgICAgICBkYXRhYnVmLmFwcGVuZEJ5dGUoJ1snKTsKICAgICAgICAgICAgZGF0YWJ1Zi5hcHBlbmRDaGFyKGFycmF5LnZhbHVlcy5sZW5ndGgpOwogICAgICAgICAgICBmb3IgKEF0dHJpYnV0ZSBhIDogYXJyYXkudmFsdWVzKSB7CiAgICAgICAgICAgICAgICBhLmFjY2VwdCh0aGlzKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIEF0dHJpYnV0ZVdyaXRlciBhd3JpdGVyID0gbmV3IEF0dHJpYnV0ZVdyaXRlcigpOwoKICAgIC8qKiBXcml0ZSBhIGNvbXBvdW5kIGF0dHJpYnV0ZSBleGNsdWRpbmcgdGhlICdAJyBtYXJrZXIuICovCiAgICB2b2lkIHdyaXRlQ29tcG91bmRBdHRyaWJ1dGUoQXR0cmlidXRlLkNvbXBvdW5kIGMpIHsKICAgICAgICBkYXRhYnVmLmFwcGVuZENoYXIocG9vbC5wdXQodHlwZVNpZyhjLnR5cGUpKSk7CiAgICAgICAgZGF0YWJ1Zi5hcHBlbmRDaGFyKGMudmFsdWVzLmxlbmd0aCgpKTsKICAgICAgICBmb3IgKFBhaXI8U3ltYm9sLk1ldGhvZFN5bWJvbCxBdHRyaWJ1dGU+IHAgOiBjLnZhbHVlcykgewogICAgICAgICAgICBkYXRhYnVmLmFwcGVuZENoYXIocG9vbC5wdXQocC5mc3QubmFtZSkpOwogICAgICAgICAgICBwLnNuZC5hY2NlcHQoYXdyaXRlcik7CiAgICAgICAgfQogICAgfQoKICAgIHZvaWQgd3JpdGVUeXBlQW5ub3RhdGlvbihBdHRyaWJ1dGUuVHlwZUNvbXBvdW5kIGMpIHsKICAgICAgICB3cml0ZVBvc2l0aW9uKGMucG9zaXRpb24pOwogICAgICAgIHdyaXRlQ29tcG91bmRBdHRyaWJ1dGUoYyk7CiAgICB9CgogICAgdm9pZCB3cml0ZVBvc2l0aW9uKFR5cGVBbm5vdGF0aW9uUG9zaXRpb24gcCkgewogICAgICAgIGRhdGFidWYuYXBwZW5kQnl0ZShwLnR5cGUudGFyZ2V0VHlwZVZhbHVlKCkpOyAvLyBUYXJnZXRUeXBlIHRhZyBpcyBhIGJ5dGUKICAgICAgICBzd2l0Y2ggKHAudHlwZSkgewogICAgICAgIC8vIGluc3RhbmNlb2YKICAgICAgICBjYXNlIElOU1RBTkNFT0Y6CiAgICAgICAgLy8gbmV3IGV4cHJlc3Npb24KICAgICAgICBjYXNlIE5FVzoKICAgICAgICAvLyBjb25zdHJ1Y3Rvci9tZXRob2QgcmVmZXJlbmNlIHJlY2VpdmVyCiAgICAgICAgY2FzZSBDT05TVFJVQ1RPUl9SRUZFUkVOQ0U6CiAgICAgICAgY2FzZSBNRVRIT0RfUkVGRVJFTkNFOgogICAgICAgICAgICBkYXRhYnVmLmFwcGVuZENoYXIocC5vZmZzZXQpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAvLyBsb2NhbCB2YXJpYWJsZQogICAgICAgIGNhc2UgTE9DQUxfVkFSSUFCTEU6CiAgICAgICAgLy8gcmVzb3VyY2UgdmFyaWFibGUKICAgICAgICBjYXNlIFJFU09VUkNFX1ZBUklBQkxFOgogICAgICAgICAgICBkYXRhYnVmLmFwcGVuZENoYXIocC5sdmFyT2Zmc2V0Lmxlbmd0aCk7ICAvLyBmb3IgdGFibGUgbGVuZ3RoCiAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcC5sdmFyT2Zmc2V0Lmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgICAgICBkYXRhYnVmLmFwcGVuZENoYXIocC5sdmFyT2Zmc2V0W2ldKTsKICAgICAgICAgICAgICAgIGRhdGFidWYuYXBwZW5kQ2hhcihwLmx2YXJMZW5ndGhbaV0pOwogICAgICAgICAgICAgICAgZGF0YWJ1Zi5hcHBlbmRDaGFyKHAubHZhckluZGV4W2ldKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICAvLyBleGNlcHRpb24gcGFyYW1ldGVyCiAgICAgICAgY2FzZSBFWENFUFRJT05fUEFSQU1FVEVSOgogICAgICAgICAgICBkYXRhYnVmLmFwcGVuZENoYXIocC5nZXRFeGNlcHRpb25JbmRleCgpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgLy8gbWV0aG9kIHJlY2VpdmVyCiAgICAgICAgY2FzZSBNRVRIT0RfUkVDRUlWRVI6CiAgICAgICAgICAgIC8vIERvIG5vdGhpbmcKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgLy8gdHlwZSBwYXJhbWV0ZXIKICAgICAgICBjYXNlIENMQVNTX1RZUEVfUEFSQU1FVEVSOgogICAgICAgIGNhc2UgTUVUSE9EX1RZUEVfUEFSQU1FVEVSOgogICAgICAgICAgICBkYXRhYnVmLmFwcGVuZEJ5dGUocC5wYXJhbWV0ZXJfaW5kZXgpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAvLyB0eXBlIHBhcmFtZXRlciBib3VuZAogICAgICAgIGNhc2UgQ0xBU1NfVFlQRV9QQVJBTUVURVJfQk9VTkQ6CiAgICAgICAgY2FzZSBNRVRIT0RfVFlQRV9QQVJBTUVURVJfQk9VTkQ6CiAgICAgICAgICAgIGRhdGFidWYuYXBwZW5kQnl0ZShwLnBhcmFtZXRlcl9pbmRleCk7CiAgICAgICAgICAgIGRhdGFidWYuYXBwZW5kQnl0ZShwLmJvdW5kX2luZGV4KTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgLy8gY2xhc3MgZXh0ZW5kcyBvciBpbXBsZW1lbnRzIGNsYXVzZQogICAgICAgIGNhc2UgQ0xBU1NfRVhURU5EUzoKICAgICAgICAgICAgZGF0YWJ1Zi5hcHBlbmRDaGFyKHAudHlwZV9pbmRleCk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIC8vIHRocm93cwogICAgICAgIGNhc2UgVEhST1dTOgogICAgICAgICAgICBkYXRhYnVmLmFwcGVuZENoYXIocC50eXBlX2luZGV4KTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgLy8gbWV0aG9kIHBhcmFtZXRlcgogICAgICAgIGNhc2UgTUVUSE9EX0ZPUk1BTF9QQVJBTUVURVI6CiAgICAgICAgICAgIGRhdGFidWYuYXBwZW5kQnl0ZShwLnBhcmFtZXRlcl9pbmRleCk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIC8vIHR5cGUgY2FzdAogICAgICAgIGNhc2UgQ0FTVDoKICAgICAgICAvLyBtZXRob2QvY29uc3RydWN0b3IvcmVmZXJlbmNlIHR5cGUgYXJndW1lbnQKICAgICAgICBjYXNlIENPTlNUUlVDVE9SX0lOVk9DQVRJT05fVFlQRV9BUkdVTUVOVDoKICAgICAgICBjYXNlIE1FVEhPRF9JTlZPQ0FUSU9OX1RZUEVfQVJHVU1FTlQ6CiAgICAgICAgY2FzZSBDT05TVFJVQ1RPUl9SRUZFUkVOQ0VfVFlQRV9BUkdVTUVOVDoKICAgICAgICBjYXNlIE1FVEhPRF9SRUZFUkVOQ0VfVFlQRV9BUkdVTUVOVDoKICAgICAgICAgICAgZGF0YWJ1Zi5hcHBlbmRDaGFyKHAub2Zmc2V0KTsKICAgICAgICAgICAgZGF0YWJ1Zi5hcHBlbmRCeXRlKHAudHlwZV9pbmRleCk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIC8vIFdlIGRvbid0IG5lZWQgdG8gd29ycnkgYWJvdXQgdGhlc2UKICAgICAgICBjYXNlIE1FVEhPRF9SRVRVUk46CiAgICAgICAgY2FzZSBGSUVMRDoKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBVTktOT1dOOgogICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoImp2bS5DbGFzc1dyaXRlcjogVU5LTk9XTiB0YXJnZXQgdHlwZSBzaG91bGQgbmV2ZXIgb2NjdXIhIik7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCJqdm0uQ2xhc3NXcml0ZXI6IFVua25vd24gdGFyZ2V0IHR5cGUgZm9yIHBvc2l0aW9uOiAiICsgcCk7CiAgICAgICAgfQoKICAgICAgICB7IC8vIEFwcGVuZCBsb2NhdGlvbiBkYXRhIGZvciBnZW5lcmljcy9hcnJheXMuCiAgICAgICAgICAgIGRhdGFidWYuYXBwZW5kQnl0ZShwLmxvY2F0aW9uLnNpemUoKSk7CiAgICAgICAgICAgIGphdmEudXRpbC5MaXN0PEludGVnZXI+IGxvYyA9IFR5cGVBbm5vdGF0aW9uUG9zaXRpb24uZ2V0QmluYXJ5RnJvbVR5cGVQYXRoKHAubG9jYXRpb24pOwogICAgICAgICAgICBmb3IgKGludCBpIDogbG9jKQogICAgICAgICAgICAgICAgZGF0YWJ1Zi5hcHBlbmRCeXRlKChieXRlKWkpOwogICAgICAgIH0KICAgIH0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFdyaXRpbmcgbW9kdWxlIGF0dHJpYnV0ZXMKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgogICAgLyoqIFdyaXRlIHRoZSBNb2R1bGUgYXR0cmlidXRlIGlmIG5lZWRlZC4KICAgICAqICBSZXR1cm5zIHRoZSBudW1iZXIgb2YgYXR0cmlidXRlcyB3cml0dGVuICgwIG9yIDEpLgogICAgICovCiAgICBpbnQgd3JpdGVNb2R1bGVBdHRyaWJ1dGUoQ2xhc3NTeW1ib2wgYykgewogICAgICAgIE1vZHVsZVN5bWJvbCBtID0gKE1vZHVsZVN5bWJvbCkgYy5vd25lcjsKCiAgICAgICAgaW50IGFsZW5JZHggPSB3cml0ZUF0dHIobmFtZXMuTW9kdWxlKTsKCiAgICAgICAgZGF0YWJ1Zi5hcHBlbmRDaGFyKHBvb2wucHV0KG0pKTsKICAgICAgICBkYXRhYnVmLmFwcGVuZENoYXIoTW9kdWxlRmxhZ3MudmFsdWUobS5mbGFncykpOyAvLyBtb2R1bGVfZmxhZ3MKICAgICAgICBkYXRhYnVmLmFwcGVuZENoYXIobS52ZXJzaW9uICE9IG51bGwgPyBwb29sLnB1dChtLnZlcnNpb24pIDogMCk7CgogICAgICAgIExpc3RCdWZmZXI8UmVxdWlyZXNEaXJlY3RpdmU+IHJlcXVpcmVzID0gbmV3IExpc3RCdWZmZXI8PigpOwogICAgICAgIGZvciAoUmVxdWlyZXNEaXJlY3RpdmUgcjogbS5yZXF1aXJlcykgewogICAgICAgICAgICBpZiAoIXIuZmxhZ3MuY29udGFpbnMoUmVxdWlyZXNGbGFnLkVYVFJBKSkKICAgICAgICAgICAgICAgIHJlcXVpcmVzLmFkZChyKTsKICAgICAgICB9CiAgICAgICAgZGF0YWJ1Zi5hcHBlbmRDaGFyKHJlcXVpcmVzLnNpemUoKSk7CiAgICAgICAgZm9yIChSZXF1aXJlc0RpcmVjdGl2ZSByOiByZXF1aXJlcykgewogICAgICAgICAgICBkYXRhYnVmLmFwcGVuZENoYXIocG9vbC5wdXQoci5tb2R1bGUpKTsKICAgICAgICAgICAgZGF0YWJ1Zi5hcHBlbmRDaGFyKFJlcXVpcmVzRmxhZy52YWx1ZShyLmZsYWdzKSk7CiAgICAgICAgICAgIGRhdGFidWYuYXBwZW5kQ2hhcihyLm1vZHVsZS52ZXJzaW9uICE9IG51bGwgPyBwb29sLnB1dChyLm1vZHVsZS52ZXJzaW9uKSA6IDApOwogICAgICAgIH0KCiAgICAgICAgTGlzdDxFeHBvcnRzRGlyZWN0aXZlPiBleHBvcnRzID0gbS5leHBvcnRzOwogICAgICAgIGRhdGFidWYuYXBwZW5kQ2hhcihleHBvcnRzLnNpemUoKSk7CiAgICAgICAgZm9yIChFeHBvcnRzRGlyZWN0aXZlIGU6IGV4cG9ydHMpIHsKICAgICAgICAgICAgZGF0YWJ1Zi5hcHBlbmRDaGFyKHBvb2wucHV0KGUucGFja2dlKSk7CiAgICAgICAgICAgIGRhdGFidWYuYXBwZW5kQ2hhcihFeHBvcnRzRmxhZy52YWx1ZShlLmZsYWdzKSk7CiAgICAgICAgICAgIGlmIChlLm1vZHVsZXMgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgZGF0YWJ1Zi5hcHBlbmRDaGFyKDApOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgZGF0YWJ1Zi5hcHBlbmRDaGFyKGUubW9kdWxlcy5zaXplKCkpOwogICAgICAgICAgICAgICAgZm9yIChNb2R1bGVTeW1ib2wgbXN5bTogZS5tb2R1bGVzKSB7CiAgICAgICAgICAgICAgICAgICAgZGF0YWJ1Zi5hcHBlbmRDaGFyKHBvb2wucHV0KG1zeW0pKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgTGlzdDxPcGVuc0RpcmVjdGl2ZT4gb3BlbnMgPSBtLm9wZW5zOwogICAgICAgIGRhdGFidWYuYXBwZW5kQ2hhcihvcGVucy5zaXplKCkpOwogICAgICAgIGZvciAoT3BlbnNEaXJlY3RpdmUgbzogb3BlbnMpIHsKICAgICAgICAgICAgZGF0YWJ1Zi5hcHBlbmRDaGFyKHBvb2wucHV0KG8ucGFja2dlKSk7CiAgICAgICAgICAgIGRhdGFidWYuYXBwZW5kQ2hhcihPcGVuc0ZsYWcudmFsdWUoby5mbGFncykpOwogICAgICAgICAgICBpZiAoby5tb2R1bGVzID09IG51bGwpIHsKICAgICAgICAgICAgICAgIGRhdGFidWYuYXBwZW5kQ2hhcigwKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGRhdGFidWYuYXBwZW5kQ2hhcihvLm1vZHVsZXMuc2l6ZSgpKTsKICAgICAgICAgICAgICAgIGZvciAoTW9kdWxlU3ltYm9sIG1zeW06IG8ubW9kdWxlcykgewogICAgICAgICAgICAgICAgICAgIGRhdGFidWYuYXBwZW5kQ2hhcihwb29sLnB1dChtc3ltKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIExpc3Q8VXNlc0RpcmVjdGl2ZT4gdXNlcyA9IG0udXNlczsKICAgICAgICBkYXRhYnVmLmFwcGVuZENoYXIodXNlcy5zaXplKCkpOwogICAgICAgIGZvciAoVXNlc0RpcmVjdGl2ZSBzOiB1c2VzKSB7CiAgICAgICAgICAgIGRhdGFidWYuYXBwZW5kQ2hhcihwb29sLnB1dChzLnNlcnZpY2UpKTsKICAgICAgICB9CgogICAgICAgIC8vIHRlbXBvcmFyeSBmaXggdG8gbWVyZ2UgcmVwZWF0ZWQgcHJvdmlkZXMgY2xhdXNlIGZvciBzYW1lIHNlcnZpY2U7CiAgICAgICAgLy8gZXZlbnR1YWxseSB0aGlzIHNob3VsZCBiZSBkaXNhbGxvd2VkIHdoZW4gYW5hbHl6aW5nIHRoZSBtb2R1bGUsCiAgICAgICAgLy8gc28gdGhhdCBlYWNoIHNlcnZpY2UgdHlwZSBvbmx5IGFwcGVhcnMgb25jZS4KICAgICAgICBNYXA8Q2xhc3NTeW1ib2wsIFNldDxDbGFzc1N5bWJvbD4+IG1lcmdlZFByb3ZpZGVzID0gbmV3IExpbmtlZEhhc2hNYXA8PigpOwogICAgICAgIGZvciAoUHJvdmlkZXNEaXJlY3RpdmUgcCA6IG0ucHJvdmlkZXMpIHsKICAgICAgICAgICAgbWVyZ2VkUHJvdmlkZXMuY29tcHV0ZUlmQWJzZW50KHAuc2VydmljZSwgcyAtPiBuZXcgTGlua2VkSGFzaFNldDw+KCkpLmFkZEFsbChwLmltcGxzKTsKICAgICAgICB9CiAgICAgICAgZGF0YWJ1Zi5hcHBlbmRDaGFyKG1lcmdlZFByb3ZpZGVzLnNpemUoKSk7CiAgICAgICAgbWVyZ2VkUHJvdmlkZXMuZm9yRWFjaCgoc3J2YywgaW1wbHMpIC0+IHsKICAgICAgICAgICAgZGF0YWJ1Zi5hcHBlbmRDaGFyKHBvb2wucHV0KHNydmMpKTsKICAgICAgICAgICAgZGF0YWJ1Zi5hcHBlbmRDaGFyKGltcGxzLnNpemUoKSk7CiAgICAgICAgICAgIGltcGxzLmZvckVhY2goaW1wbCAtPiBkYXRhYnVmLmFwcGVuZENoYXIocG9vbC5wdXQoaW1wbCkpKTsKICAgICAgICB9KTsKCiAgICAgICAgZW5kQXR0cihhbGVuSWR4KTsKICAgICAgICByZXR1cm4gMTsKICAgIH0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFdyaXRpbmcgT2JqZWN0cwogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiAgICAvKiogRW50ZXIgYW4gaW5uZXIgY2xhc3MgaW50byB0aGUgYGlubmVyQ2xhc3Nlcycgc2V0L3F1ZXVlLgogICAgICovCiAgICB2b2lkIGVudGVySW5uZXIoQ2xhc3NTeW1ib2wgYykgewogICAgICAgIGlmIChjLnR5cGUuaXNDb21wb3VuZCgpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigiVW5leHBlY3RlZCBpbnRlcnNlY3Rpb24gdHlwZTogIiArIGMudHlwZSk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGMuY29tcGxldGUoKTsKICAgICAgICB9IGNhdGNoIChDb21wbGV0aW9uRmFpbHVyZSBleCkgewogICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oImVycm9yOiAiICsgYyArICI6ICIgKyBleC5nZXRNZXNzYWdlKCkpOwogICAgICAgICAgICB0aHJvdyBleDsKICAgICAgICB9CiAgICAgICAgaWYgKCFjLnR5cGUuaGFzVGFnKENMQVNTKSkgcmV0dXJuOyAvLyBhcnJheXMKICAgICAgICBpZiAocG9vbCAhPSBudWxsICYmIC8vIHBvb2wgbWlnaHQgYmUgbnVsbCBpZiBjYWxsZWQgZnJvbSB4Q2xhc3NOYW1lCiAgICAgICAgICAgIGMub3duZXIuZW5jbENsYXNzKCkgIT0gbnVsbCAmJgogICAgICAgICAgICAoaW5uZXJDbGFzc2VzID09IG51bGwgfHwgIWlubmVyQ2xhc3Nlcy5jb250YWlucyhjKSkpIHsKLy8gICAgICAgICAgbG9nLmVycldyaXRlci5wcmludGxuKCJlbnRlciBpbm5lciAiICsgYyk7Ly9ERUJVRwogICAgICAgICAgICBlbnRlcklubmVyKGMub3duZXIuZW5jbENsYXNzKCkpOwogICAgICAgICAgICBwb29sLnB1dChjKTsKICAgICAgICAgICAgaWYgKGMubmFtZSAhPSBuYW1lcy5lbXB0eSkKICAgICAgICAgICAgICAgIHBvb2wucHV0KGMubmFtZSk7CiAgICAgICAgICAgIGlmIChpbm5lckNsYXNzZXMgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgaW5uZXJDbGFzc2VzID0gbmV3IEhhc2hTZXQ8PigpOwogICAgICAgICAgICAgICAgaW5uZXJDbGFzc2VzUXVldWUgPSBuZXcgTGlzdEJ1ZmZlcjw+KCk7CiAgICAgICAgICAgICAgICBwb29sLnB1dChuYW1lcy5Jbm5lckNsYXNzZXMpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlubmVyQ2xhc3Nlcy5hZGQoYyk7CiAgICAgICAgICAgIGlubmVyQ2xhc3Nlc1F1ZXVlLmFwcGVuZChjKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqIFdyaXRlICJpbm5lciBjbGFzc2VzIiBhdHRyaWJ1dGUuCiAgICAgKi8KICAgIHZvaWQgd3JpdGVJbm5lckNsYXNzZXMoKSB7CiAgICAgICAgaW50IGFsZW5JZHggPSB3cml0ZUF0dHIobmFtZXMuSW5uZXJDbGFzc2VzKTsKICAgICAgICBkYXRhYnVmLmFwcGVuZENoYXIoaW5uZXJDbGFzc2VzUXVldWUubGVuZ3RoKCkpOwogICAgICAgIGZvciAoTGlzdDxDbGFzc1N5bWJvbD4gbCA9IGlubmVyQ2xhc3Nlc1F1ZXVlLnRvTGlzdCgpOwogICAgICAgICAgICAgbC5ub25FbXB0eSgpOwogICAgICAgICAgICAgbCA9IGwudGFpbCkgewogICAgICAgICAgICBDbGFzc1N5bWJvbCBpbm5lciA9IGwuaGVhZDsKICAgICAgICAgICAgaW5uZXIubWFya0Fic3RyYWN0SWZOZWVkZWQodHlwZXMpOwogICAgICAgICAgICBjaGFyIGZsYWdzID0gKGNoYXIpIGFkanVzdEZsYWdzKGlubmVyLmZsYWdzX2ZpZWxkKTsKICAgICAgICAgICAgaWYgKChmbGFncyAmIElOVEVSRkFDRSkgIT0gMCkgZmxhZ3MgfD0gQUJTVFJBQ1Q7IC8vIEludGVyZmFjZXMgYXJlIGFsd2F5cyBBQlNUUkFDVAogICAgICAgICAgICBmbGFncyAmPSB+U1RSSUNURlA7IC8vaW5uZXIgY2xhc3NlcyBzaG91bGQgbm90IGhhdmUgdGhlIHN0cmljdGZwIGZsYWcgc2V0LgogICAgICAgICAgICBpZiAoZHVtcElubmVyQ2xhc3NNb2RpZmllcnMpIHsKICAgICAgICAgICAgICAgIFByaW50V3JpdGVyIHB3ID0gbG9nLmdldFdyaXRlcihMb2cuV3JpdGVyS2luZC5FUlJPUik7CiAgICAgICAgICAgICAgICBwdy5wcmludGxuKCJJTk5FUkNMQVNTICAiICsgaW5uZXIubmFtZSk7CiAgICAgICAgICAgICAgICBwdy5wcmludGxuKCItLS0iICsgZmxhZ05hbWVzKGZsYWdzKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZGF0YWJ1Zi5hcHBlbmRDaGFyKHBvb2wuZ2V0KGlubmVyKSk7CiAgICAgICAgICAgIGRhdGFidWYuYXBwZW5kQ2hhcigKICAgICAgICAgICAgICAgIGlubmVyLm93bmVyLmtpbmQgPT0gVFlQICYmICFpbm5lci5uYW1lLmlzRW1wdHkoKSA/IHBvb2wuZ2V0KGlubmVyLm93bmVyKSA6IDApOwogICAgICAgICAgICBkYXRhYnVmLmFwcGVuZENoYXIoCiAgICAgICAgICAgICAgICAhaW5uZXIubmFtZS5pc0VtcHR5KCkgPyBwb29sLmdldChpbm5lci5uYW1lKSA6IDApOwogICAgICAgICAgICBkYXRhYnVmLmFwcGVuZENoYXIoZmxhZ3MpOwogICAgICAgIH0KICAgICAgICBlbmRBdHRyKGFsZW5JZHgpOwogICAgfQoKICAgIC8qKiBXcml0ZSAiYm9vdHN0cmFwTWV0aG9kcyIgYXR0cmlidXRlLgogICAgICovCiAgICB2b2lkIHdyaXRlQm9vdHN0cmFwTWV0aG9kcygpIHsKICAgICAgICBpbnQgYWxlbklkeCA9IHdyaXRlQXR0cihuYW1lcy5Cb290c3RyYXBNZXRob2RzKTsKICAgICAgICBkYXRhYnVmLmFwcGVuZENoYXIoYm9vdHN0cmFwTWV0aG9kcy5zaXplKCkpOwogICAgICAgIGZvciAoTWFwLkVudHJ5PER5bmFtaWNNZXRob2QuQm9vdHN0cmFwTWV0aG9kc0tleSwgRHluYW1pY01ldGhvZC5Cb290c3RyYXBNZXRob2RzVmFsdWU+IGVudHJ5IDogYm9vdHN0cmFwTWV0aG9kcy5lbnRyeVNldCgpKSB7CiAgICAgICAgICAgIER5bmFtaWNNZXRob2QuQm9vdHN0cmFwTWV0aG9kc0tleSBic21LZXkgPSBlbnRyeS5nZXRLZXkoKTsKICAgICAgICAgICAgLy93cml0ZSBCU00gaGFuZGxlCiAgICAgICAgICAgIGRhdGFidWYuYXBwZW5kQ2hhcihwb29sLmdldChlbnRyeS5nZXRWYWx1ZSgpLm1oKSk7CiAgICAgICAgICAgIE9iamVjdFtdIHVuaXF1ZUFyZ3MgPSBic21LZXkuZ2V0VW5pcXVlQXJncygpOwogICAgICAgICAgICAvL3dyaXRlIHN0YXRpYyBhcmdzIGxlbmd0aAogICAgICAgICAgICBkYXRhYnVmLmFwcGVuZENoYXIodW5pcXVlQXJncy5sZW5ndGgpOwogICAgICAgICAgICAvL3dyaXRlIHN0YXRpYyBhcmdzIGFycmF5CiAgICAgICAgICAgIGZvciAoT2JqZWN0IG8gOiB1bmlxdWVBcmdzKSB7CiAgICAgICAgICAgICAgICBkYXRhYnVmLmFwcGVuZENoYXIocG9vbC5nZXQobykpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVuZEF0dHIoYWxlbklkeCk7CiAgICB9CgogICAgLyoqIFdyaXRlIGZpZWxkIHN5bWJvbCwgZW50ZXJpbmcgYWxsIHJlZmVyZW5jZXMgaW50byBjb25zdGFudCBwb29sLgogICAgICovCiAgICB2b2lkIHdyaXRlRmllbGQoVmFyU3ltYm9sIHYpIHsKICAgICAgICBpbnQgZmxhZ3MgPSBhZGp1c3RGbGFncyh2LmZsYWdzKCkpOwogICAgICAgIGRhdGFidWYuYXBwZW5kQ2hhcihmbGFncyk7CiAgICAgICAgaWYgKGR1bXBGaWVsZE1vZGlmaWVycykgewogICAgICAgICAgICBQcmludFdyaXRlciBwdyA9IGxvZy5nZXRXcml0ZXIoTG9nLldyaXRlcktpbmQuRVJST1IpOwogICAgICAgICAgICBwdy5wcmludGxuKCJGSUVMRCAgIiArIHYubmFtZSk7CiAgICAgICAgICAgIHB3LnByaW50bG4oIi0tLSIgKyBmbGFnTmFtZXModi5mbGFncygpKSk7CiAgICAgICAgfQogICAgICAgIGRhdGFidWYuYXBwZW5kQ2hhcihwb29sLnB1dCh2Lm5hbWUpKTsKICAgICAgICBkYXRhYnVmLmFwcGVuZENoYXIocG9vbC5wdXQodHlwZVNpZyh2LmVyYXN1cmUodHlwZXMpKSkpOwogICAgICAgIGludCBhY291bnRJZHggPSBiZWdpbkF0dHJzKCk7CiAgICAgICAgaW50IGFjb3VudCA9IDA7CiAgICAgICAgaWYgKHYuZ2V0Q29uc3RWYWx1ZSgpICE9IG51bGwpIHsKICAgICAgICAgICAgaW50IGFsZW5JZHggPSB3cml0ZUF0dHIobmFtZXMuQ29uc3RhbnRWYWx1ZSk7CiAgICAgICAgICAgIGRhdGFidWYuYXBwZW5kQ2hhcihwb29sLnB1dCh2LmdldENvbnN0VmFsdWUoKSkpOwogICAgICAgICAgICBlbmRBdHRyKGFsZW5JZHgpOwogICAgICAgICAgICBhY291bnQrKzsKICAgICAgICB9CiAgICAgICAgYWNvdW50ICs9IHdyaXRlTWVtYmVyQXR0cnModik7CiAgICAgICAgZW5kQXR0cnMoYWNvdW50SWR4LCBhY291bnQpOwogICAgfQoKICAgIC8qKiBXcml0ZSBtZXRob2Qgc3ltYm9sLCBlbnRlcmluZyBhbGwgcmVmZXJlbmNlcyBpbnRvIGNvbnN0YW50IHBvb2wuCiAgICAgKi8KICAgIHZvaWQgd3JpdGVNZXRob2QoTWV0aG9kU3ltYm9sIG0pIHsKICAgICAgICBpbnQgZmxhZ3MgPSBhZGp1c3RGbGFncyhtLmZsYWdzKCkpOwogICAgICAgIGRhdGFidWYuYXBwZW5kQ2hhcihmbGFncyk7CiAgICAgICAgaWYgKGR1bXBNZXRob2RNb2RpZmllcnMpIHsKICAgICAgICAgICAgUHJpbnRXcml0ZXIgcHcgPSBsb2cuZ2V0V3JpdGVyKExvZy5Xcml0ZXJLaW5kLkVSUk9SKTsKICAgICAgICAgICAgcHcucHJpbnRsbigiTUVUSE9EICAiICsgbS5uYW1lKTsKICAgICAgICAgICAgcHcucHJpbnRsbigiLS0tIiArIGZsYWdOYW1lcyhtLmZsYWdzKCkpKTsKICAgICAgICB9CiAgICAgICAgZGF0YWJ1Zi5hcHBlbmRDaGFyKHBvb2wucHV0KG0ubmFtZSkpOwogICAgICAgIGRhdGFidWYuYXBwZW5kQ2hhcihwb29sLnB1dCh0eXBlU2lnKG0uZXh0ZXJuYWxUeXBlKHR5cGVzKSkpKTsKICAgICAgICBpbnQgYWNvdW50SWR4ID0gYmVnaW5BdHRycygpOwogICAgICAgIGludCBhY291bnQgPSAwOwogICAgICAgIGlmIChtLmNvZGUgIT0gbnVsbCkgewogICAgICAgICAgICBpbnQgYWxlbklkeCA9IHdyaXRlQXR0cihuYW1lcy5Db2RlKTsKICAgICAgICAgICAgd3JpdGVDb2RlKG0uY29kZSk7CiAgICAgICAgICAgIG0uY29kZSA9IG51bGw7IC8vIHRvIGNvbnNlcnZlIHNwYWNlCiAgICAgICAgICAgIGVuZEF0dHIoYWxlbklkeCk7CiAgICAgICAgICAgIGFjb3VudCsrOwogICAgICAgIH0KICAgICAgICBMaXN0PFR5cGU+IHRocm93biA9IG0uZXJhc3VyZSh0eXBlcykuZ2V0VGhyb3duVHlwZXMoKTsKICAgICAgICBpZiAodGhyb3duLm5vbkVtcHR5KCkpIHsKICAgICAgICAgICAgaW50IGFsZW5JZHggPSB3cml0ZUF0dHIobmFtZXMuRXhjZXB0aW9ucyk7CiAgICAgICAgICAgIGRhdGFidWYuYXBwZW5kQ2hhcih0aHJvd24ubGVuZ3RoKCkpOwogICAgICAgICAgICBmb3IgKExpc3Q8VHlwZT4gbCA9IHRocm93bjsgbC5ub25FbXB0eSgpOyBsID0gbC50YWlsKQogICAgICAgICAgICAgICAgZGF0YWJ1Zi5hcHBlbmRDaGFyKHBvb2wucHV0KGwuaGVhZC50c3ltKSk7CiAgICAgICAgICAgIGVuZEF0dHIoYWxlbklkeCk7CiAgICAgICAgICAgIGFjb3VudCsrOwogICAgICAgIH0KICAgICAgICBpZiAobS5kZWZhdWx0VmFsdWUgIT0gbnVsbCkgewogICAgICAgICAgICBpbnQgYWxlbklkeCA9IHdyaXRlQXR0cihuYW1lcy5Bbm5vdGF0aW9uRGVmYXVsdCk7CiAgICAgICAgICAgIG0uZGVmYXVsdFZhbHVlLmFjY2VwdChhd3JpdGVyKTsKICAgICAgICAgICAgZW5kQXR0cihhbGVuSWR4KTsKICAgICAgICAgICAgYWNvdW50Kys7CiAgICAgICAgfQogICAgICAgIGlmIChvcHRpb25zLmlzU2V0KFBBUkFNRVRFUlMpKSB7CiAgICAgICAgICAgIGlmICghbS5pc0xhbWJkYU1ldGhvZCgpKSAvLyBQZXIgSkRLLTgxMzg3MjksIGRvIG5vdCBlbWl0IHBhcmFtZXRlcnMgdGFibGUgZm9yIGxhbWJkYSBib2RpZXMuCiAgICAgICAgICAgICAgICBhY291bnQgKz0gd3JpdGVNZXRob2RQYXJhbWV0ZXJzQXR0cihtKTsKICAgICAgICB9CiAgICAgICAgYWNvdW50ICs9IHdyaXRlTWVtYmVyQXR0cnMobSk7CiAgICAgICAgaWYgKCFtLmlzTGFtYmRhTWV0aG9kKCkpCiAgICAgICAgICAgIGFjb3VudCArPSB3cml0ZVBhcmFtZXRlckF0dHJzKG0pOwogICAgICAgIGVuZEF0dHJzKGFjb3VudElkeCwgYWNvdW50KTsKICAgIH0KCiAgICAvKiogV3JpdGUgY29kZSBhdHRyaWJ1dGUgb2YgbWV0aG9kLgogICAgICovCiAgICB2b2lkIHdyaXRlQ29kZShDb2RlIGNvZGUpIHsKICAgICAgICBkYXRhYnVmLmFwcGVuZENoYXIoY29kZS5tYXhfc3RhY2spOwogICAgICAgIGRhdGFidWYuYXBwZW5kQ2hhcihjb2RlLm1heF9sb2NhbHMpOwogICAgICAgIGRhdGFidWYuYXBwZW5kSW50KGNvZGUuY3ApOwogICAgICAgIGRhdGFidWYuYXBwZW5kQnl0ZXMoY29kZS5jb2RlLCAwLCBjb2RlLmNwKTsKICAgICAgICBkYXRhYnVmLmFwcGVuZENoYXIoY29kZS5jYXRjaEluZm8ubGVuZ3RoKCkpOwogICAgICAgIGZvciAoTGlzdDxjaGFyW10+IGwgPSBjb2RlLmNhdGNoSW5mby50b0xpc3QoKTsKICAgICAgICAgICAgIGwubm9uRW1wdHkoKTsKICAgICAgICAgICAgIGwgPSBsLnRhaWwpIHsKICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsLmhlYWQubGVuZ3RoOyBpKyspCiAgICAgICAgICAgICAgICBkYXRhYnVmLmFwcGVuZENoYXIobC5oZWFkW2ldKTsKICAgICAgICB9CiAgICAgICAgaW50IGFjb3VudElkeCA9IGJlZ2luQXR0cnMoKTsKICAgICAgICBpbnQgYWNvdW50ID0gMDsKCiAgICAgICAgaWYgKGNvZGUubGluZUluZm8ubm9uRW1wdHkoKSkgewogICAgICAgICAgICBpbnQgYWxlbklkeCA9IHdyaXRlQXR0cihuYW1lcy5MaW5lTnVtYmVyVGFibGUpOwogICAgICAgICAgICBkYXRhYnVmLmFwcGVuZENoYXIoY29kZS5saW5lSW5mby5sZW5ndGgoKSk7CiAgICAgICAgICAgIGZvciAoTGlzdDxjaGFyW10+IGwgPSBjb2RlLmxpbmVJbmZvLnJldmVyc2UoKTsKICAgICAgICAgICAgICAgICBsLm5vbkVtcHR5KCk7CiAgICAgICAgICAgICAgICAgbCA9IGwudGFpbCkKICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbC5oZWFkLmxlbmd0aDsgaSsrKQogICAgICAgICAgICAgICAgICAgIGRhdGFidWYuYXBwZW5kQ2hhcihsLmhlYWRbaV0pOwogICAgICAgICAgICBlbmRBdHRyKGFsZW5JZHgpOwogICAgICAgICAgICBhY291bnQrKzsKICAgICAgICB9CgogICAgICAgIGlmIChnZW5DcnQgJiYgKGNvZGUuY3J0ICE9IG51bGwpKSB7CiAgICAgICAgICAgIENSVGFibGUgY3J0ID0gY29kZS5jcnQ7CiAgICAgICAgICAgIGludCBhbGVuSWR4ID0gd3JpdGVBdHRyKG5hbWVzLkNoYXJhY3RlclJhbmdlVGFibGUpOwogICAgICAgICAgICBpbnQgY3J0SWR4ID0gYmVnaW5BdHRycygpOwogICAgICAgICAgICBpbnQgY3J0RW50cmllcyA9IGNydC53cml0ZUNSVChkYXRhYnVmLCBjb2RlLmxpbmVNYXAsIGxvZyk7CiAgICAgICAgICAgIGVuZEF0dHJzKGNydElkeCwgY3J0RW50cmllcyk7CiAgICAgICAgICAgIGVuZEF0dHIoYWxlbklkeCk7CiAgICAgICAgICAgIGFjb3VudCsrOwogICAgICAgIH0KCiAgICAgICAgLy8gY291bnRlciBmb3IgbnVtYmVyIG9mIGdlbmVyaWMgbG9jYWwgdmFyaWFibGVzCiAgICAgICAgaWYgKGNvZGUudmFyRGVidWdJbmZvICYmIGNvZGUudmFyQnVmZmVyU2l6ZSA+IDApIHsKICAgICAgICAgICAgaW50IG5HZW5lcmljVmFycyA9IDA7CiAgICAgICAgICAgIGludCBhbGVuSWR4ID0gd3JpdGVBdHRyKG5hbWVzLkxvY2FsVmFyaWFibGVUYWJsZSk7CiAgICAgICAgICAgIGRhdGFidWYuYXBwZW5kQ2hhcihjb2RlLmdldExWVFNpemUoKSk7CiAgICAgICAgICAgIGZvciAoaW50IGk9MDsgaTxjb2RlLnZhckJ1ZmZlclNpemU7IGkrKykgewogICAgICAgICAgICAgICAgQ29kZS5Mb2NhbFZhciB2YXIgPSBjb2RlLnZhckJ1ZmZlcltpXTsKCiAgICAgICAgICAgICAgICBmb3IgKENvZGUuTG9jYWxWYXIuUmFuZ2UgcjogdmFyLmFsaXZlUmFuZ2VzKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gd3JpdGUgdmFyaWFibGUgaW5mbwogICAgICAgICAgICAgICAgICAgIEFzc2VydC5jaGVjayhyLnN0YXJ0X3BjID49IDAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICYmIHIuc3RhcnRfcGMgPD0gY29kZS5jcCk7CiAgICAgICAgICAgICAgICAgICAgZGF0YWJ1Zi5hcHBlbmRDaGFyKHIuc3RhcnRfcGMpOwogICAgICAgICAgICAgICAgICAgIEFzc2VydC5jaGVjayhyLmxlbmd0aCA+IDAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICYmIChyLnN0YXJ0X3BjICsgci5sZW5ndGgpIDw9IGNvZGUuY3ApOwogICAgICAgICAgICAgICAgICAgIGRhdGFidWYuYXBwZW5kQ2hhcihyLmxlbmd0aCk7CiAgICAgICAgICAgICAgICAgICAgVmFyU3ltYm9sIHN5bSA9IHZhci5zeW07CiAgICAgICAgICAgICAgICAgICAgZGF0YWJ1Zi5hcHBlbmRDaGFyKHBvb2wucHV0KHN5bS5uYW1lKSk7CiAgICAgICAgICAgICAgICAgICAgVHlwZSB2YXJ0eXBlID0gc3ltLmVyYXN1cmUodHlwZXMpOwogICAgICAgICAgICAgICAgICAgIGRhdGFidWYuYXBwZW5kQ2hhcihwb29sLnB1dCh0eXBlU2lnKHZhcnR5cGUpKSk7CiAgICAgICAgICAgICAgICAgICAgZGF0YWJ1Zi5hcHBlbmRDaGFyKHZhci5yZWcpOwogICAgICAgICAgICAgICAgICAgIGlmIChuZWVkc0xvY2FsVmFyaWFibGVUeXBlRW50cnkodmFyLnN5bS50eXBlKSkgewogICAgICAgICAgICAgICAgICAgICAgICBuR2VuZXJpY1ZhcnMrKzsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZW5kQXR0cihhbGVuSWR4KTsKICAgICAgICAgICAgYWNvdW50Kys7CgogICAgICAgICAgICBpZiAobkdlbmVyaWNWYXJzID4gMCkgewogICAgICAgICAgICAgICAgYWxlbklkeCA9IHdyaXRlQXR0cihuYW1lcy5Mb2NhbFZhcmlhYmxlVHlwZVRhYmxlKTsKICAgICAgICAgICAgICAgIGRhdGFidWYuYXBwZW5kQ2hhcihuR2VuZXJpY1ZhcnMpOwogICAgICAgICAgICAgICAgaW50IGNvdW50ID0gMDsKCiAgICAgICAgICAgICAgICBmb3IgKGludCBpPTA7IGk8Y29kZS52YXJCdWZmZXJTaXplOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICBDb2RlLkxvY2FsVmFyIHZhciA9IGNvZGUudmFyQnVmZmVyW2ldOwogICAgICAgICAgICAgICAgICAgIFZhclN5bWJvbCBzeW0gPSB2YXIuc3ltOwogICAgICAgICAgICAgICAgICAgIGlmICghbmVlZHNMb2NhbFZhcmlhYmxlVHlwZUVudHJ5KHN5bS50eXBlKSkKICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICAgICAgZm9yIChDb2RlLkxvY2FsVmFyLlJhbmdlIHIgOiB2YXIuYWxpdmVSYW5nZXMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gd3JpdGUgdmFyaWFibGUgaW5mbwogICAgICAgICAgICAgICAgICAgICAgICBkYXRhYnVmLmFwcGVuZENoYXIoci5zdGFydF9wYyk7CiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFidWYuYXBwZW5kQ2hhcihyLmxlbmd0aCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFidWYuYXBwZW5kQ2hhcihwb29sLnB1dChzeW0ubmFtZSkpOwogICAgICAgICAgICAgICAgICAgICAgICBkYXRhYnVmLmFwcGVuZENoYXIocG9vbC5wdXQodHlwZVNpZyhzeW0udHlwZSkpKTsKICAgICAgICAgICAgICAgICAgICAgICAgZGF0YWJ1Zi5hcHBlbmRDaGFyKHZhci5yZWcpOwogICAgICAgICAgICAgICAgICAgICAgICBjb3VudCsrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIEFzc2VydC5jaGVjayhjb3VudCA9PSBuR2VuZXJpY1ZhcnMpOwogICAgICAgICAgICAgICAgZW5kQXR0cihhbGVuSWR4KTsKICAgICAgICAgICAgICAgIGFjb3VudCsrOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoY29kZS5zdGFja01hcEJ1ZmZlclNpemUgPiAwKSB7CiAgICAgICAgICAgIGlmIChkZWJ1Z3N0YWNrbWFwKSBTeXN0ZW0ub3V0LnByaW50bG4oIlN0YWNrIG1hcCBmb3IgIiArIGNvZGUubWV0aCk7CiAgICAgICAgICAgIGludCBhbGVuSWR4ID0gd3JpdGVBdHRyKGNvZGUuc3RhY2tNYXAuZ2V0QXR0cmlidXRlTmFtZShuYW1lcykpOwogICAgICAgICAgICB3cml0ZVN0YWNrTWFwKGNvZGUpOwogICAgICAgICAgICBlbmRBdHRyKGFsZW5JZHgpOwogICAgICAgICAgICBhY291bnQrKzsKICAgICAgICB9CgogICAgICAgIGFjb3VudCArPSB3cml0ZVR5cGVBbm5vdGF0aW9ucyhjb2RlLm1ldGguZ2V0UmF3VHlwZUF0dHJpYnV0ZXMoKSwgdHJ1ZSk7CgogICAgICAgIGVuZEF0dHJzKGFjb3VudElkeCwgYWNvdW50KTsKICAgIH0KICAgIC8vd2hlcmUKICAgIHByaXZhdGUgYm9vbGVhbiBuZWVkc0xvY2FsVmFyaWFibGVUeXBlRW50cnkoVHlwZSB0KSB7CiAgICAgICAgLy9hIGxvY2FsIHZhcmlhYmxlIG5lZWRzIGEgdHlwZS1lbnRyeSBpZiBpdHMgdHlwZSBUIGlzIGdlbmVyaWMKICAgICAgICAvLyhpLmUuIHxUfCAhPSBUKSBhbmQgaWYgaXQncyBub3QgYW4gaW50ZXJzZWN0aW9uIHR5cGUgKG5vdCBzdXBwb3J0ZWQKICAgICAgICAvL2luIHNpZ25hdHVyZSBhdHRyaWJ1dGUgZ3JhbW1hcikKICAgICAgICByZXR1cm4gKCF0eXBlcy5pc1NhbWVUeXBlKHQsIHR5cGVzLmVyYXN1cmUodCkpICYmCiAgICAgICAgICAgICAgICAhdC5pc0NvbXBvdW5kKCkpOwogICAgfQoKICAgIHZvaWQgd3JpdGVTdGFja01hcChDb2RlIGNvZGUpIHsKICAgICAgICBpbnQgbmZyYW1lcyA9IGNvZGUuc3RhY2tNYXBCdWZmZXJTaXplOwogICAgICAgIGlmIChkZWJ1Z3N0YWNrbWFwKSBTeXN0ZW0ub3V0LnByaW50bG4oIiBuZnJhbWVzID0gIiArIG5mcmFtZXMpOwogICAgICAgIGRhdGFidWYuYXBwZW5kQ2hhcihuZnJhbWVzKTsKCiAgICAgICAgc3dpdGNoIChjb2RlLnN0YWNrTWFwKSB7CiAgICAgICAgY2FzZSBDTERDOgogICAgICAgICAgICBmb3IgKGludCBpPTA7IGk8bmZyYW1lczsgaSsrKSB7CiAgICAgICAgICAgICAgICBpZiAoZGVidWdzdGFja21hcCkgU3lzdGVtLm91dC5wcmludCgiICAiICsgaSArICI6Iik7CiAgICAgICAgICAgICAgICBDb2RlLlN0YWNrTWFwRnJhbWUgZnJhbWUgPSBjb2RlLnN0YWNrTWFwQnVmZmVyW2ldOwoKICAgICAgICAgICAgICAgIC8vIG91dHB1dCBQQwogICAgICAgICAgICAgICAgaWYgKGRlYnVnc3RhY2ttYXApIFN5c3RlbS5vdXQucHJpbnQoIiBwYz0iICsgZnJhbWUucGMpOwogICAgICAgICAgICAgICAgZGF0YWJ1Zi5hcHBlbmRDaGFyKGZyYW1lLnBjKTsKCiAgICAgICAgICAgICAgICAvLyBvdXRwdXQgbG9jYWxzCiAgICAgICAgICAgICAgICBpbnQgbG9jYWxDb3VudCA9IDA7CiAgICAgICAgICAgICAgICBmb3IgKGludCBqPTA7IGo8ZnJhbWUubG9jYWxzLmxlbmd0aDsKICAgICAgICAgICAgICAgICAgICAgaiArPSBDb2RlLndpZHRoKGZyYW1lLmxvY2Fsc1tqXSkpIHsKICAgICAgICAgICAgICAgICAgICBsb2NhbENvdW50Kys7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoZGVidWdzdGFja21hcCkgU3lzdGVtLm91dC5wcmludCgiIG5sb2NhbHM9IiArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2NhbENvdW50KTsKICAgICAgICAgICAgICAgIGRhdGFidWYuYXBwZW5kQ2hhcihsb2NhbENvdW50KTsKICAgICAgICAgICAgICAgIGZvciAoaW50IGo9MDsgajxmcmFtZS5sb2NhbHMubGVuZ3RoOwogICAgICAgICAgICAgICAgICAgICBqICs9IENvZGUud2lkdGgoZnJhbWUubG9jYWxzW2pdKSkgewogICAgICAgICAgICAgICAgICAgIGlmIChkZWJ1Z3N0YWNrbWFwKSBTeXN0ZW0ub3V0LnByaW50KCIgbG9jYWxbIiArIGogKyAiXT0iKTsKICAgICAgICAgICAgICAgICAgICB3cml0ZVN0YWNrTWFwVHlwZShmcmFtZS5sb2NhbHNbal0pOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIG91dHB1dCBzdGFjawogICAgICAgICAgICAgICAgaW50IHN0YWNrQ291bnQgPSAwOwogICAgICAgICAgICAgICAgZm9yIChpbnQgaj0wOyBqPGZyYW1lLnN0YWNrLmxlbmd0aDsKICAgICAgICAgICAgICAgICAgICAgaiArPSBDb2RlLndpZHRoKGZyYW1lLnN0YWNrW2pdKSkgewogICAgICAgICAgICAgICAgICAgIHN0YWNrQ291bnQrKzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChkZWJ1Z3N0YWNrbWFwKSBTeXN0ZW0ub3V0LnByaW50KCIgbnN0YWNrPSIgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhY2tDb3VudCk7CiAgICAgICAgICAgICAgICBkYXRhYnVmLmFwcGVuZENoYXIoc3RhY2tDb3VudCk7CiAgICAgICAgICAgICAgICBmb3IgKGludCBqPTA7IGo8ZnJhbWUuc3RhY2subGVuZ3RoOwogICAgICAgICAgICAgICAgICAgICBqICs9IENvZGUud2lkdGgoZnJhbWUuc3RhY2tbal0pKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGRlYnVnc3RhY2ttYXApIFN5c3RlbS5vdXQucHJpbnQoIiBzdGFja1siICsgaiArICJdPSIpOwogICAgICAgICAgICAgICAgICAgIHdyaXRlU3RhY2tNYXBUeXBlKGZyYW1lLnN0YWNrW2pdKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChkZWJ1Z3N0YWNrbWFwKSBTeXN0ZW0ub3V0LnByaW50bG4oKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIEpTUjIwMjogewogICAgICAgICAgICBBc3NlcnQuY2hlY2tOdWxsKGNvZGUuc3RhY2tNYXBCdWZmZXIpOwogICAgICAgICAgICBmb3IgKGludCBpPTA7IGk8bmZyYW1lczsgaSsrKSB7CiAgICAgICAgICAgICAgICBpZiAoZGVidWdzdGFja21hcCkgU3lzdGVtLm91dC5wcmludCgiICAiICsgaSArICI6Iik7CiAgICAgICAgICAgICAgICBTdGFja01hcFRhYmxlRnJhbWUgZnJhbWUgPSBjb2RlLnN0YWNrTWFwVGFibGVCdWZmZXJbaV07CiAgICAgICAgICAgICAgICBmcmFtZS53cml0ZSh0aGlzKTsKICAgICAgICAgICAgICAgIGlmIChkZWJ1Z3N0YWNrbWFwKSBTeXN0ZW0ub3V0LnByaW50bG4oKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCJVbmV4cGVjdGVkIHN0YWNrbWFwIGZvcm1hdCB2YWx1ZSIpOwogICAgICAgIH0KICAgIH0KCiAgICAgICAgLy93aGVyZQogICAgICAgIHZvaWQgd3JpdGVTdGFja01hcFR5cGUoVHlwZSB0KSB7CiAgICAgICAgICAgIGlmICh0ID09IG51bGwpIHsKICAgICAgICAgICAgICAgIGlmIChkZWJ1Z3N0YWNrbWFwKSBTeXN0ZW0ub3V0LnByaW50KCJlbXB0eSIpOwogICAgICAgICAgICAgICAgZGF0YWJ1Zi5hcHBlbmRCeXRlKDApOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2Ugc3dpdGNoKHQuZ2V0VGFnKCkpIHsKICAgICAgICAgICAgY2FzZSBCWVRFOgogICAgICAgICAgICBjYXNlIENIQVI6CiAgICAgICAgICAgIGNhc2UgU0hPUlQ6CiAgICAgICAgICAgIGNhc2UgSU5UOgogICAgICAgICAgICBjYXNlIEJPT0xFQU46CiAgICAgICAgICAgICAgICBpZiAoZGVidWdzdGFja21hcCkgU3lzdGVtLm91dC5wcmludCgiaW50Iik7CiAgICAgICAgICAgICAgICBkYXRhYnVmLmFwcGVuZEJ5dGUoMSk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBGTE9BVDoKICAgICAgICAgICAgICAgIGlmIChkZWJ1Z3N0YWNrbWFwKSBTeXN0ZW0ub3V0LnByaW50KCJmbG9hdCIpOwogICAgICAgICAgICAgICAgZGF0YWJ1Zi5hcHBlbmRCeXRlKDIpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgRE9VQkxFOgogICAgICAgICAgICAgICAgaWYgKGRlYnVnc3RhY2ttYXApIFN5c3RlbS5vdXQucHJpbnQoImRvdWJsZSIpOwogICAgICAgICAgICAgICAgZGF0YWJ1Zi5hcHBlbmRCeXRlKDMpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgTE9ORzoKICAgICAgICAgICAgICAgIGlmIChkZWJ1Z3N0YWNrbWFwKSBTeXN0ZW0ub3V0LnByaW50KCJsb25nIik7CiAgICAgICAgICAgICAgICBkYXRhYnVmLmFwcGVuZEJ5dGUoNCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBCT1Q6IC8vIG51bGwKICAgICAgICAgICAgICAgIGlmIChkZWJ1Z3N0YWNrbWFwKSBTeXN0ZW0ub3V0LnByaW50KCJudWxsIik7CiAgICAgICAgICAgICAgICBkYXRhYnVmLmFwcGVuZEJ5dGUoNSk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBDTEFTUzoKICAgICAgICAgICAgY2FzZSBBUlJBWToKICAgICAgICAgICAgICAgIGlmIChkZWJ1Z3N0YWNrbWFwKSBTeXN0ZW0ub3V0LnByaW50KCJvYmplY3QoIiArIHQgKyAiKSIpOwogICAgICAgICAgICAgICAgZGF0YWJ1Zi5hcHBlbmRCeXRlKDcpOwogICAgICAgICAgICAgICAgZGF0YWJ1Zi5hcHBlbmRDaGFyKHBvb2wucHV0KHQpKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFRZUEVWQVI6CiAgICAgICAgICAgICAgICBpZiAoZGVidWdzdGFja21hcCkgU3lzdGVtLm91dC5wcmludCgib2JqZWN0KCIgKyB0eXBlcy5lcmFzdXJlKHQpLnRzeW0gKyAiKSIpOwogICAgICAgICAgICAgICAgZGF0YWJ1Zi5hcHBlbmRCeXRlKDcpOwogICAgICAgICAgICAgICAgZGF0YWJ1Zi5hcHBlbmRDaGFyKHBvb2wucHV0KHR5cGVzLmVyYXN1cmUodCkudHN5bSkpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgVU5JTklUSUFMSVpFRF9USElTOgogICAgICAgICAgICAgICAgaWYgKGRlYnVnc3RhY2ttYXApIFN5c3RlbS5vdXQucHJpbnQoInVuaW5pdF90aGlzIik7CiAgICAgICAgICAgICAgICBkYXRhYnVmLmFwcGVuZEJ5dGUoNik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBVTklOSVRJQUxJWkVEX09CSkVDVDoKICAgICAgICAgICAgICAgIHsgVW5pbml0aWFsaXplZFR5cGUgdW5pbml0VHlwZSA9IChVbmluaXRpYWxpemVkVHlwZSl0OwogICAgICAgICAgICAgICAgZGF0YWJ1Zi5hcHBlbmRCeXRlKDgpOwogICAgICAgICAgICAgICAgaWYgKGRlYnVnc3RhY2ttYXApIFN5c3RlbS5vdXQucHJpbnQoInVuaW5pdF9vYmplY3RAIiArIHVuaW5pdFR5cGUub2Zmc2V0KTsKICAgICAgICAgICAgICAgIGRhdGFidWYuYXBwZW5kQ2hhcih1bmluaXRUeXBlLm9mZnNldCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgIC8qKiBBbiBlbnRyeSBpbiB0aGUgSlNSMjAyIFN0YWNrTWFwVGFibGUgKi8KICAgIGFic3RyYWN0IHN0YXRpYyBjbGFzcyBTdGFja01hcFRhYmxlRnJhbWUgewogICAgICAgIGFic3RyYWN0IGludCBnZXRGcmFtZVR5cGUoKTsKCiAgICAgICAgdm9pZCB3cml0ZShDbGFzc1dyaXRlciB3cml0ZXIpIHsKICAgICAgICAgICAgaW50IGZyYW1lVHlwZSA9IGdldEZyYW1lVHlwZSgpOwogICAgICAgICAgICB3cml0ZXIuZGF0YWJ1Zi5hcHBlbmRCeXRlKGZyYW1lVHlwZSk7CiAgICAgICAgICAgIGlmICh3cml0ZXIuZGVidWdzdGFja21hcCkgU3lzdGVtLm91dC5wcmludCgiIGZyYW1lX3R5cGU9IiArIGZyYW1lVHlwZSk7CiAgICAgICAgfQoKICAgICAgICBzdGF0aWMgY2xhc3MgU2FtZUZyYW1lIGV4dGVuZHMgU3RhY2tNYXBUYWJsZUZyYW1lIHsKICAgICAgICAgICAgZmluYWwgaW50IG9mZnNldERlbHRhOwogICAgICAgICAgICBTYW1lRnJhbWUoaW50IG9mZnNldERlbHRhKSB7CiAgICAgICAgICAgICAgICB0aGlzLm9mZnNldERlbHRhID0gb2Zmc2V0RGVsdGE7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaW50IGdldEZyYW1lVHlwZSgpIHsKICAgICAgICAgICAgICAgIHJldHVybiAob2Zmc2V0RGVsdGEgPCBTQU1FX0ZSQU1FX1NJWkUpID8gb2Zmc2V0RGVsdGEgOiBTQU1FX0ZSQU1FX0VYVEVOREVEOwogICAgICAgICAgICB9CiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICB2b2lkIHdyaXRlKENsYXNzV3JpdGVyIHdyaXRlcikgewogICAgICAgICAgICAgICAgc3VwZXIud3JpdGUod3JpdGVyKTsKICAgICAgICAgICAgICAgIGlmIChnZXRGcmFtZVR5cGUoKSA9PSBTQU1FX0ZSQU1FX0VYVEVOREVEKSB7CiAgICAgICAgICAgICAgICAgICAgd3JpdGVyLmRhdGFidWYuYXBwZW5kQ2hhcihvZmZzZXREZWx0YSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKHdyaXRlci5kZWJ1Z3N0YWNrbWFwKXsKICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiIG9mZnNldF9kZWx0YT0iICsgb2Zmc2V0RGVsdGEpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgc3RhdGljIGNsYXNzIFNhbWVMb2NhbHMxU3RhY2tJdGVtRnJhbWUgZXh0ZW5kcyBTdGFja01hcFRhYmxlRnJhbWUgewogICAgICAgICAgICBmaW5hbCBpbnQgb2Zmc2V0RGVsdGE7CiAgICAgICAgICAgIGZpbmFsIFR5cGUgc3RhY2s7CiAgICAgICAgICAgIFNhbWVMb2NhbHMxU3RhY2tJdGVtRnJhbWUoaW50IG9mZnNldERlbHRhLCBUeXBlIHN0YWNrKSB7CiAgICAgICAgICAgICAgICB0aGlzLm9mZnNldERlbHRhID0gb2Zmc2V0RGVsdGE7CiAgICAgICAgICAgICAgICB0aGlzLnN0YWNrID0gc3RhY2s7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaW50IGdldEZyYW1lVHlwZSgpIHsKICAgICAgICAgICAgICAgIHJldHVybiAob2Zmc2V0RGVsdGEgPCBTQU1FX0ZSQU1FX1NJWkUpID8KICAgICAgICAgICAgICAgICAgICAgICAoU0FNRV9GUkFNRV9TSVpFICsgb2Zmc2V0RGVsdGEpIDoKICAgICAgICAgICAgICAgICAgICAgICBTQU1FX0xPQ0FMU18xX1NUQUNLX0lURU1fRVhURU5ERUQ7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHZvaWQgd3JpdGUoQ2xhc3NXcml0ZXIgd3JpdGVyKSB7CiAgICAgICAgICAgICAgICBzdXBlci53cml0ZSh3cml0ZXIpOwogICAgICAgICAgICAgICAgaWYgKGdldEZyYW1lVHlwZSgpID09IFNBTUVfTE9DQUxTXzFfU1RBQ0tfSVRFTV9FWFRFTkRFRCkgewogICAgICAgICAgICAgICAgICAgIHdyaXRlci5kYXRhYnVmLmFwcGVuZENoYXIob2Zmc2V0RGVsdGEpOwogICAgICAgICAgICAgICAgICAgIGlmICh3cml0ZXIuZGVidWdzdGFja21hcCkgewogICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCIgb2Zmc2V0X2RlbHRhPSIgKyBvZmZzZXREZWx0YSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKHdyaXRlci5kZWJ1Z3N0YWNrbWFwKSB7CiAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiIHN0YWNrWyIgKyAwICsgIl09Iik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB3cml0ZXIud3JpdGVTdGFja01hcFR5cGUoc3RhY2spOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBzdGF0aWMgY2xhc3MgQ2hvcEZyYW1lIGV4dGVuZHMgU3RhY2tNYXBUYWJsZUZyYW1lIHsKICAgICAgICAgICAgZmluYWwgaW50IGZyYW1lVHlwZTsKICAgICAgICAgICAgZmluYWwgaW50IG9mZnNldERlbHRhOwogICAgICAgICAgICBDaG9wRnJhbWUoaW50IGZyYW1lVHlwZSwgaW50IG9mZnNldERlbHRhKSB7CiAgICAgICAgICAgICAgICB0aGlzLmZyYW1lVHlwZSA9IGZyYW1lVHlwZTsKICAgICAgICAgICAgICAgIHRoaXMub2Zmc2V0RGVsdGEgPSBvZmZzZXREZWx0YTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpbnQgZ2V0RnJhbWVUeXBlKCkgeyByZXR1cm4gZnJhbWVUeXBlOyB9CiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICB2b2lkIHdyaXRlKENsYXNzV3JpdGVyIHdyaXRlcikgewogICAgICAgICAgICAgICAgc3VwZXIud3JpdGUod3JpdGVyKTsKICAgICAgICAgICAgICAgIHdyaXRlci5kYXRhYnVmLmFwcGVuZENoYXIob2Zmc2V0RGVsdGEpOwogICAgICAgICAgICAgICAgaWYgKHdyaXRlci5kZWJ1Z3N0YWNrbWFwKSB7CiAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiIG9mZnNldF9kZWx0YT0iICsgb2Zmc2V0RGVsdGEpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBzdGF0aWMgY2xhc3MgQXBwZW5kRnJhbWUgZXh0ZW5kcyBTdGFja01hcFRhYmxlRnJhbWUgewogICAgICAgICAgICBmaW5hbCBpbnQgZnJhbWVUeXBlOwogICAgICAgICAgICBmaW5hbCBpbnQgb2Zmc2V0RGVsdGE7CiAgICAgICAgICAgIGZpbmFsIFR5cGVbXSBsb2NhbHM7CiAgICAgICAgICAgIEFwcGVuZEZyYW1lKGludCBmcmFtZVR5cGUsIGludCBvZmZzZXREZWx0YSwgVHlwZVtdIGxvY2FscykgewogICAgICAgICAgICAgICAgdGhpcy5mcmFtZVR5cGUgPSBmcmFtZVR5cGU7CiAgICAgICAgICAgICAgICB0aGlzLm9mZnNldERlbHRhID0gb2Zmc2V0RGVsdGE7CiAgICAgICAgICAgICAgICB0aGlzLmxvY2FscyA9IGxvY2FsczsKICAgICAgICAgICAgfQogICAgICAgICAgICBpbnQgZ2V0RnJhbWVUeXBlKCkgeyByZXR1cm4gZnJhbWVUeXBlOyB9CiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICB2b2lkIHdyaXRlKENsYXNzV3JpdGVyIHdyaXRlcikgewogICAgICAgICAgICAgICAgc3VwZXIud3JpdGUod3JpdGVyKTsKICAgICAgICAgICAgICAgIHdyaXRlci5kYXRhYnVmLmFwcGVuZENoYXIob2Zmc2V0RGVsdGEpOwogICAgICAgICAgICAgICAgaWYgKHdyaXRlci5kZWJ1Z3N0YWNrbWFwKSB7CiAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiIG9mZnNldF9kZWx0YT0iICsgb2Zmc2V0RGVsdGEpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZm9yIChpbnQgaT0wOyBpPGxvY2Fscy5sZW5ndGg7IGkrKykgewogICAgICAgICAgICAgICAgICAgICBpZiAod3JpdGVyLmRlYnVnc3RhY2ttYXApIFN5c3RlbS5vdXQucHJpbnQoIiBsb2NhbHNbIiArIGkgKyAiXT0iKTsKICAgICAgICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlU3RhY2tNYXBUeXBlKGxvY2Fsc1tpXSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHN0YXRpYyBjbGFzcyBGdWxsRnJhbWUgZXh0ZW5kcyBTdGFja01hcFRhYmxlRnJhbWUgewogICAgICAgICAgICBmaW5hbCBpbnQgb2Zmc2V0RGVsdGE7CiAgICAgICAgICAgIGZpbmFsIFR5cGVbXSBsb2NhbHM7CiAgICAgICAgICAgIGZpbmFsIFR5cGVbXSBzdGFjazsKICAgICAgICAgICAgRnVsbEZyYW1lKGludCBvZmZzZXREZWx0YSwgVHlwZVtdIGxvY2FscywgVHlwZVtdIHN0YWNrKSB7CiAgICAgICAgICAgICAgICB0aGlzLm9mZnNldERlbHRhID0gb2Zmc2V0RGVsdGE7CiAgICAgICAgICAgICAgICB0aGlzLmxvY2FscyA9IGxvY2FsczsKICAgICAgICAgICAgICAgIHRoaXMuc3RhY2sgPSBzdGFjazsKICAgICAgICAgICAgfQogICAgICAgICAgICBpbnQgZ2V0RnJhbWVUeXBlKCkgeyByZXR1cm4gRlVMTF9GUkFNRTsgfQogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgdm9pZCB3cml0ZShDbGFzc1dyaXRlciB3cml0ZXIpIHsKICAgICAgICAgICAgICAgIHN1cGVyLndyaXRlKHdyaXRlcik7CiAgICAgICAgICAgICAgICB3cml0ZXIuZGF0YWJ1Zi5hcHBlbmRDaGFyKG9mZnNldERlbHRhKTsKICAgICAgICAgICAgICAgIHdyaXRlci5kYXRhYnVmLmFwcGVuZENoYXIobG9jYWxzLmxlbmd0aCk7CiAgICAgICAgICAgICAgICBpZiAod3JpdGVyLmRlYnVnc3RhY2ttYXApIHsKICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KCIgb2Zmc2V0X2RlbHRhPSIgKyBvZmZzZXREZWx0YSk7CiAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludCgiIG5sb2NhbHM9IiArIGxvY2Fscy5sZW5ndGgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZm9yIChpbnQgaT0wOyBpPGxvY2Fscy5sZW5ndGg7IGkrKykgewogICAgICAgICAgICAgICAgICAgIGlmICh3cml0ZXIuZGVidWdzdGFja21hcCkgU3lzdGVtLm91dC5wcmludCgiIGxvY2Fsc1siICsgaSArICJdPSIpOwogICAgICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZVN0YWNrTWFwVHlwZShsb2NhbHNbaV0pOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHdyaXRlci5kYXRhYnVmLmFwcGVuZENoYXIoc3RhY2subGVuZ3RoKTsKICAgICAgICAgICAgICAgIGlmICh3cml0ZXIuZGVidWdzdGFja21hcCkgeyBTeXN0ZW0ub3V0LnByaW50KCIgbnN0YWNrPSIgKyBzdGFjay5sZW5ndGgpOyB9CiAgICAgICAgICAgICAgICBmb3IgKGludCBpPTA7IGk8c3RhY2subGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICBpZiAod3JpdGVyLmRlYnVnc3RhY2ttYXApIFN5c3RlbS5vdXQucHJpbnQoIiBzdGFja1siICsgaSArICJdPSIpOwogICAgICAgICAgICAgICAgICAgIHdyaXRlci53cml0ZVN0YWNrTWFwVHlwZShzdGFja1tpXSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgLyoqIENvbXBhcmUgdGhpcyBmcmFtZSB3aXRoIHRoZSBwcmV2aW91cyBmcmFtZSBhbmQgcHJvZHVjZQogICAgICAgICogIGFuIGVudHJ5IG9mIGNvbXByZXNzZWQgc3RhY2sgbWFwIGZyYW1lLiAqLwogICAgICAgIHN0YXRpYyBTdGFja01hcFRhYmxlRnJhbWUgZ2V0SW5zdGFuY2UoQ29kZS5TdGFja01hcEZyYW1lIHRoaXNfZnJhbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgcHJldl9wYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFR5cGVbXSBwcmV2X2xvY2FscywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFR5cGVzIHR5cGVzKSB7CiAgICAgICAgICAgIFR5cGVbXSBsb2NhbHMgPSB0aGlzX2ZyYW1lLmxvY2FsczsKICAgICAgICAgICAgVHlwZVtdIHN0YWNrID0gdGhpc19mcmFtZS5zdGFjazsKICAgICAgICAgICAgaW50IG9mZnNldF9kZWx0YSA9IHRoaXNfZnJhbWUucGMgLSBwcmV2X3BjIC0gMTsKICAgICAgICAgICAgaWYgKHN0YWNrLmxlbmd0aCA9PSAxKSB7CiAgICAgICAgICAgICAgICBpZiAobG9jYWxzLmxlbmd0aCA9PSBwcmV2X2xvY2Fscy5sZW5ndGgKICAgICAgICAgICAgICAgICAgICAmJiBjb21wYXJlKHByZXZfbG9jYWxzLCBsb2NhbHMsIHR5cGVzKSA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBTYW1lTG9jYWxzMVN0YWNrSXRlbUZyYW1lKG9mZnNldF9kZWx0YSwgc3RhY2tbMF0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgaWYgKHN0YWNrLmxlbmd0aCA9PSAwKSB7CiAgICAgICAgICAgICAgICBpbnQgZGlmZl9sZW5ndGggPSBjb21wYXJlKHByZXZfbG9jYWxzLCBsb2NhbHMsIHR5cGVzKTsKICAgICAgICAgICAgICAgIGlmIChkaWZmX2xlbmd0aCA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBTYW1lRnJhbWUob2Zmc2V0X2RlbHRhKTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoLU1BWF9MT0NBTF9MRU5HVEhfRElGRiA8IGRpZmZfbGVuZ3RoICYmIGRpZmZfbGVuZ3RoIDwgMCkgewogICAgICAgICAgICAgICAgICAgIC8vIEFQUEVORAogICAgICAgICAgICAgICAgICAgIFR5cGVbXSBsb2NhbF9kaWZmID0gbmV3IFR5cGVbLWRpZmZfbGVuZ3RoXTsKICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpPXByZXZfbG9jYWxzLmxlbmd0aCwgaj0wOyBpPGxvY2Fscy5sZW5ndGg7IGkrKyxqKyspIHsKICAgICAgICAgICAgICAgICAgICAgICAgbG9jYWxfZGlmZltqXSA9IGxvY2Fsc1tpXTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBBcHBlbmRGcmFtZShTQU1FX0ZSQU1FX0VYVEVOREVEIC0gZGlmZl9sZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXRfZGVsdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2NhbF9kaWZmKTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoMCA8IGRpZmZfbGVuZ3RoICYmIGRpZmZfbGVuZ3RoIDwgTUFYX0xPQ0FMX0xFTkdUSF9ESUZGKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gQ0hPUAogICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgQ2hvcEZyYW1lKFNBTUVfRlJBTUVfRVhURU5ERUQgLSBkaWZmX2xlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXRfZGVsdGEpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIEZVTExfRlJBTUUKICAgICAgICAgICAgcmV0dXJuIG5ldyBGdWxsRnJhbWUob2Zmc2V0X2RlbHRhLCBsb2NhbHMsIHN0YWNrKTsKICAgICAgICB9CgogICAgICAgIHN0YXRpYyBib29sZWFuIGlzSW50KFR5cGUgdCkgewogICAgICAgICAgICByZXR1cm4gKHQuZ2V0VGFnKCkuaXNTdHJpY3RTdWJSYW5nZU9mKElOVCkgIHx8IHQuaGFzVGFnKEJPT0xFQU4pKTsKICAgICAgICB9CgogICAgICAgIHN0YXRpYyBib29sZWFuIGlzU2FtZVR5cGUoVHlwZSB0MSwgVHlwZSB0MiwgVHlwZXMgdHlwZXMpIHsKICAgICAgICAgICAgaWYgKHQxID09IG51bGwpIHsgcmV0dXJuIHQyID09IG51bGw7IH0KICAgICAgICAgICAgaWYgKHQyID09IG51bGwpIHsgcmV0dXJuIGZhbHNlOyB9CgogICAgICAgICAgICBpZiAoaXNJbnQodDEpICYmIGlzSW50KHQyKSkgeyByZXR1cm4gdHJ1ZTsgfQoKICAgICAgICAgICAgaWYgKHQxLmhhc1RhZyhVTklOSVRJQUxJWkVEX1RISVMpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdDIuaGFzVGFnKFVOSU5JVElBTElaRURfVEhJUyk7CiAgICAgICAgICAgIH0gZWxzZSBpZiAodDEuaGFzVGFnKFVOSU5JVElBTElaRURfT0JKRUNUKSkgewogICAgICAgICAgICAgICAgaWYgKHQyLmhhc1RhZyhVTklOSVRJQUxJWkVEX09CSkVDVCkpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gKChVbmluaXRpYWxpemVkVHlwZSl0MSkub2Zmc2V0ID09ICgoVW5pbml0aWFsaXplZFR5cGUpdDIpLm9mZnNldDsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgaWYgKHQyLmhhc1RhZyhVTklOSVRJQUxJWkVEX1RISVMpIHx8IHQyLmhhc1RhZyhVTklOSVRJQUxJWkVEX09CSkVDVCkpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIHR5cGVzLmlzU2FtZVR5cGUodDEsIHQyKTsKICAgICAgICB9CgogICAgICAgIHN0YXRpYyBpbnQgY29tcGFyZShUeXBlW10gYXJyMSwgVHlwZVtdIGFycjIsIFR5cGVzIHR5cGVzKSB7CiAgICAgICAgICAgIGludCBkaWZmX2xlbmd0aCA9IGFycjEubGVuZ3RoIC0gYXJyMi5sZW5ndGg7CiAgICAgICAgICAgIGlmIChkaWZmX2xlbmd0aCA+IE1BWF9MT0NBTF9MRU5HVEhfRElGRiB8fCBkaWZmX2xlbmd0aCA8IC1NQVhfTE9DQUxfTEVOR1RIX0RJRkYpIHsKICAgICAgICAgICAgICAgIHJldHVybiBJbnRlZ2VyLk1BWF9WQUxVRTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpbnQgbGVuID0gKGRpZmZfbGVuZ3RoID4gMCkgPyBhcnIyLmxlbmd0aCA6IGFycjEubGVuZ3RoOwogICAgICAgICAgICBmb3IgKGludCBpPTA7IGk8bGVuOyBpKyspIHsKICAgICAgICAgICAgICAgIGlmICghaXNTYW1lVHlwZShhcnIxW2ldLCBhcnIyW2ldLCB0eXBlcykpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gSW50ZWdlci5NQVhfVkFMVUU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGRpZmZfbGVuZ3RoOwogICAgICAgIH0KICAgIH0KCiAgICB2b2lkIHdyaXRlRmllbGRzKFNjb3BlIHMpIHsKICAgICAgICAvLyBwcm9jZXNzIHRoZW0gaW4gcmV2ZXJzZSBzaWJsaW5nIG9yZGVyOwogICAgICAgIC8vIGkuZS4sIHByb2Nlc3MgdGhlbSBpbiBkZWNsYXJhdGlvbiBvcmRlci4KICAgICAgICBMaXN0PFZhclN5bWJvbD4gdmFycyA9IExpc3QubmlsKCk7CiAgICAgICAgZm9yIChTeW1ib2wgc3ltIDogcy5nZXRTeW1ib2xzKE5PTl9SRUNVUlNJVkUpKSB7CiAgICAgICAgICAgIGlmIChzeW0ua2luZCA9PSBWQVIpIHZhcnMgPSB2YXJzLnByZXBlbmQoKFZhclN5bWJvbClzeW0pOwogICAgICAgIH0KICAgICAgICB3aGlsZSAodmFycy5ub25FbXB0eSgpKSB7CiAgICAgICAgICAgIHdyaXRlRmllbGQodmFycy5oZWFkKTsKICAgICAgICAgICAgdmFycyA9IHZhcnMudGFpbDsKICAgICAgICB9CiAgICB9CgogICAgdm9pZCB3cml0ZU1ldGhvZHMoU2NvcGUgcykgewogICAgICAgIExpc3Q8TWV0aG9kU3ltYm9sPiBtZXRob2RzID0gTGlzdC5uaWwoKTsKICAgICAgICBmb3IgKFN5bWJvbCBzeW0gOiBzLmdldFN5bWJvbHMoTk9OX1JFQ1VSU0lWRSkpIHsKICAgICAgICAgICAgaWYgKHN5bS5raW5kID09IE1USCAmJiAoc3ltLmZsYWdzKCkgJiBIWVBPVEhFVElDQUwpID09IDApCiAgICAgICAgICAgICAgICBtZXRob2RzID0gbWV0aG9kcy5wcmVwZW5kKChNZXRob2RTeW1ib2wpc3ltKTsKICAgICAgICB9CiAgICAgICAgd2hpbGUgKG1ldGhvZHMubm9uRW1wdHkoKSkgewogICAgICAgICAgICB3cml0ZU1ldGhvZChtZXRob2RzLmhlYWQpOwogICAgICAgICAgICBtZXRob2RzID0gbWV0aG9kcy50YWlsOwogICAgICAgIH0KICAgIH0KCiAgICAvKiogRW1pdCBhIGNsYXNzIGZpbGUgZm9yIGEgZ2l2ZW4gY2xhc3MuCiAgICAgKiAgQHBhcmFtIGMgICAgICBUaGUgY2xhc3MgZnJvbSB3aGljaCBhIGNsYXNzIGZpbGUgaXMgZ2VuZXJhdGVkLgogICAgICovCiAgICBwdWJsaWMgSmF2YUZpbGVPYmplY3Qgd3JpdGVDbGFzcyhDbGFzc1N5bWJvbCBjKQogICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgUG9vbE92ZXJmbG93LCBTdHJpbmdPdmVyZmxvdwogICAgewogICAgICAgIFN0cmluZyBuYW1lID0gKGMub3duZXIua2luZCA9PSBNREwgPyBjLm5hbWUgOiBjLmZsYXRuYW1lKS50b1N0cmluZygpOwogICAgICAgIExvY2F0aW9uIG91dExvY247CiAgICAgICAgaWYgKG11bHRpTW9kdWxlTW9kZSkgewogICAgICAgICAgICBNb2R1bGVTeW1ib2wgbXN5bSA9IGMub3duZXIua2luZCA9PSBNREwgPyAoTW9kdWxlU3ltYm9sKSBjLm93bmVyIDogYy5wYWNrZ2UoKS5tb2RsZTsKICAgICAgICAgICAgb3V0TG9jbiA9IGZpbGVNYW5hZ2VyLmdldExvY2F0aW9uRm9yTW9kdWxlKENMQVNTX09VVFBVVCwgbXN5bS5uYW1lLnRvU3RyaW5nKCkpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIG91dExvY24gPSBDTEFTU19PVVRQVVQ7CiAgICAgICAgfQogICAgICAgIEphdmFGaWxlT2JqZWN0IG91dEZpbGUKICAgICAgICAgICAgPSBmaWxlTWFuYWdlci5nZXRKYXZhRmlsZUZvck91dHB1dChvdXRMb2NuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSmF2YUZpbGVPYmplY3QuS2luZC5DTEFTUywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjLnNvdXJjZWZpbGUpOwogICAgICAgIE91dHB1dFN0cmVhbSBvdXQgPSBvdXRGaWxlLm9wZW5PdXRwdXRTdHJlYW0oKTsKICAgICAgICB0cnkgewogICAgICAgICAgICB3cml0ZUNsYXNzRmlsZShvdXQsIGMpOwogICAgICAgICAgICBpZiAodmVyYm9zZSkKICAgICAgICAgICAgICAgIGxvZy5wcmludFZlcmJvc2UoIndyb3RlLmZpbGUiLCBvdXRGaWxlKTsKICAgICAgICAgICAgb3V0LmNsb3NlKCk7CiAgICAgICAgICAgIG91dCA9IG51bGw7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgaWYgKG91dCAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAvLyBpZiB3ZSBhcmUgcHJvcGFnYXRpbmcgYW4gZXhjZXB0aW9uLCBkZWxldGUgdGhlIGZpbGUKICAgICAgICAgICAgICAgIG91dC5jbG9zZSgpOwogICAgICAgICAgICAgICAgb3V0RmlsZS5kZWxldGUoKTsKICAgICAgICAgICAgICAgIG91dEZpbGUgPSBudWxsOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBvdXRGaWxlOyAvLyBtYXkgYmUgbnVsbCBpZiB3cml0ZSBmYWlsZWQKICAgIH0KCiAgICAvKiogV3JpdGUgY2xhc3MgYGMnIHRvIG91dHN0cmVhbSBgb3V0Jy4KICAgICAqLwogICAgcHVibGljIHZvaWQgd3JpdGVDbGFzc0ZpbGUoT3V0cHV0U3RyZWFtIG91dCwgQ2xhc3NTeW1ib2wgYykKICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIFBvb2xPdmVyZmxvdywgU3RyaW5nT3ZlcmZsb3cgewogICAgICAgIEFzc2VydC5jaGVjaygoYy5mbGFncygpICYgQ09NUE9VTkQpID09IDApOwogICAgICAgIGRhdGFidWYucmVzZXQoKTsKICAgICAgICBwb29sYnVmLnJlc2V0KCk7CiAgICAgICAgc2lnbmF0dXJlR2VuLnJlc2V0KCk7CiAgICAgICAgcG9vbCA9IGMucG9vbDsKICAgICAgICBpbm5lckNsYXNzZXMgPSBudWxsOwogICAgICAgIGlubmVyQ2xhc3Nlc1F1ZXVlID0gbnVsbDsKICAgICAgICBib290c3RyYXBNZXRob2RzID0gbmV3IExpbmtlZEhhc2hNYXA8PigpOwoKICAgICAgICBUeXBlIHN1cGVydHlwZSA9IHR5cGVzLnN1cGVydHlwZShjLnR5cGUpOwogICAgICAgIExpc3Q8VHlwZT4gaW50ZXJmYWNlcyA9IHR5cGVzLmludGVyZmFjZXMoYy50eXBlKTsKICAgICAgICBMaXN0PFR5cGU+IHR5cGFyYW1zID0gYy50eXBlLmdldFR5cGVBcmd1bWVudHMoKTsKCiAgICAgICAgaW50IGZsYWdzOwogICAgICAgIGlmIChjLm93bmVyLmtpbmQgPT0gTURMKSB7CiAgICAgICAgICAgIGZsYWdzID0gQUNDX01PRFVMRTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBmbGFncyA9IGFkanVzdEZsYWdzKGMuZmxhZ3MoKSAmIH5ERUZBVUxUKTsKICAgICAgICAgICAgaWYgKChmbGFncyAmIFBST1RFQ1RFRCkgIT0gMCkgZmxhZ3MgfD0gUFVCTElDOwogICAgICAgICAgICBmbGFncyA9IGZsYWdzICYgQ2xhc3NGbGFncyAmIH5TVFJJQ1RGUDsKICAgICAgICAgICAgaWYgKChmbGFncyAmIElOVEVSRkFDRSkgPT0gMCkgZmxhZ3MgfD0gQUNDX1NVUEVSOwogICAgICAgIH0KCiAgICAgICAgaWYgKGR1bXBDbGFzc01vZGlmaWVycykgewogICAgICAgICAgICBQcmludFdyaXRlciBwdyA9IGxvZy5nZXRXcml0ZXIoTG9nLldyaXRlcktpbmQuRVJST1IpOwogICAgICAgICAgICBwdy5wcmludGxuKCk7CiAgICAgICAgICAgIHB3LnByaW50bG4oIkNMQVNTRklMRSAgIiArIGMuZ2V0UXVhbGlmaWVkTmFtZSgpKTsKICAgICAgICAgICAgcHcucHJpbnRsbigiLS0tIiArIGZsYWdOYW1lcyhmbGFncykpOwogICAgICAgIH0KICAgICAgICBkYXRhYnVmLmFwcGVuZENoYXIoZmxhZ3MpOwoKICAgICAgICBpZiAoYy5vd25lci5raW5kID09IE1ETCkgewogICAgICAgICAgICBQYWNrYWdlU3ltYm9sIHVubmFtZWQgPSAoKE1vZHVsZVN5bWJvbCkgYy5vd25lcikudW5uYW1lZFBhY2thZ2U7CiAgICAgICAgICAgIGRhdGFidWYuYXBwZW5kQ2hhcihwb29sLnB1dChuZXcgQ2xhc3NTeW1ib2woMCwgbmFtZXMubW9kdWxlX2luZm8sIHVubmFtZWQpKSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZGF0YWJ1Zi5hcHBlbmRDaGFyKHBvb2wucHV0KGMpKTsKICAgICAgICB9CiAgICAgICAgZGF0YWJ1Zi5hcHBlbmRDaGFyKHN1cGVydHlwZS5oYXNUYWcoQ0xBU1MpID8gcG9vbC5wdXQoc3VwZXJ0eXBlLnRzeW0pIDogMCk7CiAgICAgICAgZGF0YWJ1Zi5hcHBlbmRDaGFyKGludGVyZmFjZXMubGVuZ3RoKCkpOwogICAgICAgIGZvciAoTGlzdDxUeXBlPiBsID0gaW50ZXJmYWNlczsgbC5ub25FbXB0eSgpOyBsID0gbC50YWlsKQogICAgICAgICAgICBkYXRhYnVmLmFwcGVuZENoYXIocG9vbC5wdXQobC5oZWFkLnRzeW0pKTsKICAgICAgICBpbnQgZmllbGRzQ291bnQgPSAwOwogICAgICAgIGludCBtZXRob2RzQ291bnQgPSAwOwogICAgICAgIGZvciAoU3ltYm9sIHN5bSA6IGMubWVtYmVycygpLmdldFN5bWJvbHMoTk9OX1JFQ1VSU0lWRSkpIHsKICAgICAgICAgICAgc3dpdGNoIChzeW0ua2luZCkgewogICAgICAgICAgICBjYXNlIFZBUjogZmllbGRzQ291bnQrKzsgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgTVRIOiBpZiAoKHN5bS5mbGFncygpICYgSFlQT1RIRVRJQ0FMKSA9PSAwKSBtZXRob2RzQ291bnQrKzsKICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFRZUDogZW50ZXJJbm5lcigoQ2xhc3NTeW1ib2wpc3ltKTsgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQgOiBBc3NlcnQuZXJyb3IoKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKGMudHJhbnNfbG9jYWwgIT0gbnVsbCkgewogICAgICAgICAgICBmb3IgKENsYXNzU3ltYm9sIGxvY2FsIDogYy50cmFuc19sb2NhbCkgewogICAgICAgICAgICAgICAgZW50ZXJJbm5lcihsb2NhbCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGRhdGFidWYuYXBwZW5kQ2hhcihmaWVsZHNDb3VudCk7CiAgICAgICAgd3JpdGVGaWVsZHMoYy5tZW1iZXJzKCkpOwogICAgICAgIGRhdGFidWYuYXBwZW5kQ2hhcihtZXRob2RzQ291bnQpOwogICAgICAgIHdyaXRlTWV0aG9kcyhjLm1lbWJlcnMoKSk7CgogICAgICAgIGludCBhY291bnRJZHggPSBiZWdpbkF0dHJzKCk7CiAgICAgICAgaW50IGFjb3VudCA9IDA7CgogICAgICAgIGJvb2xlYW4gc2lnUmVxID0KICAgICAgICAgICAgdHlwYXJhbXMubGVuZ3RoKCkgIT0gMCB8fCBzdXBlcnR5cGUuYWxscGFyYW1zKCkubGVuZ3RoKCkgIT0gMDsKICAgICAgICBmb3IgKExpc3Q8VHlwZT4gbCA9IGludGVyZmFjZXM7ICFzaWdSZXEgJiYgbC5ub25FbXB0eSgpOyBsID0gbC50YWlsKQogICAgICAgICAgICBzaWdSZXEgPSBsLmhlYWQuYWxscGFyYW1zKCkubGVuZ3RoKCkgIT0gMDsKICAgICAgICBpZiAoc2lnUmVxKSB7CiAgICAgICAgICAgIGludCBhbGVuSWR4ID0gd3JpdGVBdHRyKG5hbWVzLlNpZ25hdHVyZSk7CiAgICAgICAgICAgIGlmICh0eXBhcmFtcy5sZW5ndGgoKSAhPSAwKSBzaWduYXR1cmVHZW4uYXNzZW1ibGVQYXJhbXNTaWcodHlwYXJhbXMpOwogICAgICAgICAgICBzaWduYXR1cmVHZW4uYXNzZW1ibGVTaWcoc3VwZXJ0eXBlKTsKICAgICAgICAgICAgZm9yIChMaXN0PFR5cGU+IGwgPSBpbnRlcmZhY2VzOyBsLm5vbkVtcHR5KCk7IGwgPSBsLnRhaWwpCiAgICAgICAgICAgICAgICBzaWduYXR1cmVHZW4uYXNzZW1ibGVTaWcobC5oZWFkKTsKICAgICAgICAgICAgZGF0YWJ1Zi5hcHBlbmRDaGFyKHBvb2wucHV0KHNpZ25hdHVyZUdlbi50b05hbWUoKSkpOwogICAgICAgICAgICBzaWduYXR1cmVHZW4ucmVzZXQoKTsKICAgICAgICAgICAgZW5kQXR0cihhbGVuSWR4KTsKICAgICAgICAgICAgYWNvdW50Kys7CiAgICAgICAgfQoKICAgICAgICBpZiAoYy5zb3VyY2VmaWxlICE9IG51bGwgJiYgZW1pdFNvdXJjZUZpbGUpIHsKICAgICAgICAgICAgaW50IGFsZW5JZHggPSB3cml0ZUF0dHIobmFtZXMuU291cmNlRmlsZSk7CiAgICAgICAgICAgIC8vIFdITSA2LzI5LzE5OTk6IFN0cmlwIGZpbGUgcGF0aCBwcmVmaXguICBXZSBkbyBpdCBoZXJlIGF0CiAgICAgICAgICAgIC8vIHRoZSBsYXN0IHBvc3NpYmxlIG1vbWVudCBiZWNhdXNlIHRoZSBzb3VyY2VmaWxlIG1heSBiZSB1c2VkCiAgICAgICAgICAgIC8vIGVsc2V3aGVyZSBpbiBlcnJvciBkaWFnbm9zdGljcy4gRml4ZXMgNDI0MTU3My4KICAgICAgICAgICAgLy9kYXRhYnVmLmFwcGVuZENoYXIoYy5wb29sLnB1dChjLnNvdXJjZWZpbGUpKTsKICAgICAgICAgICAgU3RyaW5nIHNpbXBsZU5hbWUgPSBQYXRoRmlsZU9iamVjdC5nZXRTaW1wbGVOYW1lKGMuc291cmNlZmlsZSk7CiAgICAgICAgICAgIGRhdGFidWYuYXBwZW5kQ2hhcihjLnBvb2wucHV0KG5hbWVzLmZyb21TdHJpbmcoc2ltcGxlTmFtZSkpKTsKICAgICAgICAgICAgZW5kQXR0cihhbGVuSWR4KTsKICAgICAgICAgICAgYWNvdW50Kys7CiAgICAgICAgfQoKICAgICAgICBpZiAoZ2VuQ3J0KSB7CiAgICAgICAgICAgIC8vIEFwcGVuZCBTb3VyY2VJRCBhdHRyaWJ1dGUKICAgICAgICAgICAgaW50IGFsZW5JZHggPSB3cml0ZUF0dHIobmFtZXMuU291cmNlSUQpOwogICAgICAgICAgICBkYXRhYnVmLmFwcGVuZENoYXIoYy5wb29sLnB1dChuYW1lcy5mcm9tU3RyaW5nKExvbmcudG9TdHJpbmcoZ2V0TGFzdE1vZGlmaWVkKGMuc291cmNlZmlsZSkpKSkpOwogICAgICAgICAgICBlbmRBdHRyKGFsZW5JZHgpOwogICAgICAgICAgICBhY291bnQrKzsKICAgICAgICAgICAgLy8gQXBwZW5kIENvbXBpbGF0aW9uSUQgYXR0cmlidXRlCiAgICAgICAgICAgIGFsZW5JZHggPSB3cml0ZUF0dHIobmFtZXMuQ29tcGlsYXRpb25JRCk7CiAgICAgICAgICAgIGRhdGFidWYuYXBwZW5kQ2hhcihjLnBvb2wucHV0KG5hbWVzLmZyb21TdHJpbmcoTG9uZy50b1N0cmluZyhTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSkpKSk7CiAgICAgICAgICAgIGVuZEF0dHIoYWxlbklkeCk7CiAgICAgICAgICAgIGFjb3VudCsrOwogICAgICAgIH0KCiAgICAgICAgYWNvdW50ICs9IHdyaXRlRmxhZ0F0dHJzKGMuZmxhZ3MoKSk7CiAgICAgICAgYWNvdW50ICs9IHdyaXRlSmF2YUFubm90YXRpb25zKGMuZ2V0UmF3QXR0cmlidXRlcygpKTsKICAgICAgICBhY291bnQgKz0gd3JpdGVUeXBlQW5ub3RhdGlvbnMoYy5nZXRSYXdUeXBlQXR0cmlidXRlcygpLCBmYWxzZSk7CiAgICAgICAgYWNvdW50ICs9IHdyaXRlRW5jbG9zaW5nTWV0aG9kQXR0cmlidXRlKGMpOwogICAgICAgIGlmIChjLm93bmVyLmtpbmQgPT0gTURMKSB7CiAgICAgICAgICAgIGFjb3VudCArPSB3cml0ZU1vZHVsZUF0dHJpYnV0ZShjKTsKICAgICAgICAgICAgYWNvdW50ICs9IHdyaXRlRmxhZ0F0dHJzKGMub3duZXIuZmxhZ3MoKSAmIH5ERVBSRUNBVEVEKTsKICAgICAgICB9CiAgICAgICAgYWNvdW50ICs9IHdyaXRlRXh0cmFDbGFzc0F0dHJpYnV0ZXMoYyk7CgogICAgICAgIHBvb2xidWYuYXBwZW5kSW50KEpBVkFfTUFHSUMpOwoKICAgICAgICBpZiAoYy5vd25lci5raW5kID09IE1ETCkgewogICAgICAgICAgICAvLyB0ZW1wb3JhcmlseSBvdmVyaWRlIHRvIGZvcmNlIHVzZSBvZiB2NTMgZm9yIG1vZHVsZS1pbmZvLmNsYXNzCiAgICAgICAgICAgIHBvb2xidWYuYXBwZW5kQ2hhcigwKTsKICAgICAgICAgICAgcG9vbGJ1Zi5hcHBlbmRDaGFyKDUzKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBwb29sYnVmLmFwcGVuZENoYXIodGFyZ2V0Lm1pbm9yVmVyc2lvbik7CiAgICAgICAgICAgIHBvb2xidWYuYXBwZW5kQ2hhcih0YXJnZXQubWFqb3JWZXJzaW9uKTsKICAgICAgICB9CgogICAgICAgIHdyaXRlUG9vbChjLnBvb2wpOwoKICAgICAgICBpZiAoaW5uZXJDbGFzc2VzICE9IG51bGwpIHsKICAgICAgICAgICAgd3JpdGVJbm5lckNsYXNzZXMoKTsKICAgICAgICAgICAgYWNvdW50Kys7CiAgICAgICAgfQoKICAgICAgICBpZiAoIWJvb3RzdHJhcE1ldGhvZHMuaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHdyaXRlQm9vdHN0cmFwTWV0aG9kcygpOwogICAgICAgICAgICBhY291bnQrKzsKICAgICAgICB9CgogICAgICAgIGVuZEF0dHJzKGFjb3VudElkeCwgYWNvdW50KTsKCiAgICAgICAgcG9vbGJ1Zi5hcHBlbmRCeXRlcyhkYXRhYnVmLmVsZW1zLCAwLCBkYXRhYnVmLmxlbmd0aCk7CiAgICAgICAgb3V0LndyaXRlKHBvb2xidWYuZWxlbXMsIDAsIHBvb2xidWYubGVuZ3RoKTsKCiAgICAgICAgcG9vbCA9IGMucG9vbCA9IG51bGw7IC8vIHRvIGNvbnNlcnZlIHNwYWNlCiAgICAgfQoKICAgIC8qKkFsbG93cyBzdWJjbGFzc2VzIHRvIHdyaXRlIGFkZGl0aW9uYWwgY2xhc3MgYXR0cmlidXRlcwogICAgICoKICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBhdHRyaWJ1dGVzIHdyaXR0ZW4KICAgICAqLwogICAgcHJvdGVjdGVkIGludCB3cml0ZUV4dHJhQ2xhc3NBdHRyaWJ1dGVzKENsYXNzU3ltYm9sIGMpIHsKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICBpbnQgYWRqdXN0RmxhZ3MoZmluYWwgbG9uZyBmbGFncykgewogICAgICAgIGludCByZXN1bHQgPSAoaW50KWZsYWdzOwoKICAgICAgICBpZiAoKGZsYWdzICYgQlJJREdFKSAhPSAwKQogICAgICAgICAgICByZXN1bHQgfD0gQUNDX0JSSURHRTsKICAgICAgICBpZiAoKGZsYWdzICYgVkFSQVJHUykgIT0gMCkKICAgICAgICAgICAgcmVzdWx0IHw9IEFDQ19WQVJBUkdTOwogICAgICAgIGlmICgoZmxhZ3MgJiBERUZBVUxUKSAhPSAwKQogICAgICAgICAgICByZXN1bHQgJj0gfkFCU1RSQUNUOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9CgogICAgbG9uZyBnZXRMYXN0TW9kaWZpZWQoRmlsZU9iamVjdCBmaWxlbmFtZSkgewogICAgICAgIGxvbmcgbW9kID0gMDsKICAgICAgICB0cnkgewogICAgICAgICAgICBtb2QgPSBmaWxlbmFtZS5nZXRMYXN0TW9kaWZpZWQoKTsKICAgICAgICB9IGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigiQ1JUOiBjb3VsZG4ndCBnZXQgc291cmNlIGZpbGUgbW9kaWZpY2F0aW9uIGRhdGU6ICIgKyBlLmdldE1lc3NhZ2UoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtb2Q7CiAgICB9Cn0KUEsDBAoAAAgAANJ9TUqKkO1V4SYAAOEmAAAmAAAAY29tL3N1bi90b29scy9qYXZhYy9qdm0vQnl0ZUNvZGVzLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDE5OTksIDIwMTIsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhYy5qdm07CgoKLyoqIEJ5dGVjb2RlIGluc3RydWN0aW9uIGNvZGVzLCBhcyB3ZWxsIGFzIHR5cGVjb2RlcyB1c2VkIGFzCiAqICBpbnN0cnVjdGlvbiBtb2RpZmllcnMuCiAqCiAqICA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiAgSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93biByaXNrLgogKiAgVGhpcyBjb2RlIGFuZCBpdHMgaW50ZXJuYWwgaW50ZXJmYWNlcyBhcmUgc3ViamVjdCB0byBjaGFuZ2Ugb3IKICogIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj4KICovCnB1YmxpYyBpbnRlcmZhY2UgQnl0ZUNvZGVzIHsKCiAgICAvKiogQnl0ZSBjb2RlIGluc3RydWN0aW9uIGNvZGVzLgogICAgICovCiAgICBpbnQgaWxsZWdhbCAgICAgICAgID0gLTEsCiAgICAgICAgbm9wICAgICAgICAgICAgID0gMCwKICAgICAgICBhY29uc3RfbnVsbCAgICAgPSAxLAogICAgICAgIGljb25zdF9tMSAgICAgICA9IDIsCiAgICAgICAgaWNvbnN0XzAgICAgICAgID0gMywKICAgICAgICBpY29uc3RfMSAgICAgICAgPSA0LAogICAgICAgIGljb25zdF8yICAgICAgICA9IDUsCiAgICAgICAgaWNvbnN0XzMgICAgICAgID0gNiwKICAgICAgICBpY29uc3RfNCAgICAgICAgPSA3LAogICAgICAgIGljb25zdF81ICAgICAgICA9IDgsCiAgICAgICAgbGNvbnN0XzAgICAgICAgID0gOSwKICAgICAgICBsY29uc3RfMSAgICAgICAgPSAxMCwKICAgICAgICBmY29uc3RfMCAgICAgICAgPSAxMSwKICAgICAgICBmY29uc3RfMSAgICAgICAgPSAxMiwKICAgICAgICBmY29uc3RfMiAgICAgICAgPSAxMywKICAgICAgICBkY29uc3RfMCAgICAgICAgPSAxNCwKICAgICAgICBkY29uc3RfMSAgICAgICAgPSAxNSwKICAgICAgICBiaXB1c2ggICAgICAgICAgPSAxNiwKICAgICAgICBzaXB1c2ggICAgICAgICAgPSAxNywKICAgICAgICBsZGMxICAgICAgICAgICAgPSAxOCwKICAgICAgICBsZGMyICAgICAgICAgICAgPSAxOSwKICAgICAgICBsZGMydyAgICAgICAgICAgPSAyMCwKICAgICAgICBpbG9hZCAgICAgICAgICAgPSAyMSwKICAgICAgICBsbG9hZCAgICAgICAgICAgPSAyMiwKICAgICAgICBmbG9hZCAgICAgICAgICAgPSAyMywKICAgICAgICBkbG9hZCAgICAgICAgICAgPSAyNCwKICAgICAgICBhbG9hZCAgICAgICAgICAgPSAyNSwKICAgICAgICBpbG9hZF8wICAgICAgICAgPSAyNiwKICAgICAgICBpbG9hZF8xICAgICAgICAgPSAyNywKICAgICAgICBpbG9hZF8yICAgICAgICAgPSAyOCwKICAgICAgICBpbG9hZF8zICAgICAgICAgPSAyOSwKICAgICAgICBsbG9hZF8wICAgICAgICAgPSAzMCwKICAgICAgICBsbG9hZF8xICAgICAgICAgPSAzMSwKICAgICAgICBsbG9hZF8yICAgICAgICAgPSAzMiwKICAgICAgICBsbG9hZF8zICAgICAgICAgPSAzMywKICAgICAgICBmbG9hZF8wICAgICAgICAgPSAzNCwKICAgICAgICBmbG9hZF8xICAgICAgICAgPSAzNSwKICAgICAgICBmbG9hZF8yICAgICAgICAgPSAzNiwKICAgICAgICBmbG9hZF8zICAgICAgICAgPSAzNywKICAgICAgICBkbG9hZF8wICAgICAgICAgPSAzOCwKICAgICAgICBkbG9hZF8xICAgICAgICAgPSAzOSwKICAgICAgICBkbG9hZF8yICAgICAgICAgPSA0MCwKICAgICAgICBkbG9hZF8zICAgICAgICAgPSA0MSwKICAgICAgICBhbG9hZF8wICAgICAgICAgPSA0MiwKICAgICAgICBhbG9hZF8xICAgICAgICAgPSA0MywKICAgICAgICBhbG9hZF8yICAgICAgICAgPSA0NCwKICAgICAgICBhbG9hZF8zICAgICAgICAgPSA0NSwKICAgICAgICBpYWxvYWQgICAgICAgICAgPSA0NiwKICAgICAgICBsYWxvYWQgICAgICAgICAgPSA0NywKICAgICAgICBmYWxvYWQgICAgICAgICAgPSA0OCwKICAgICAgICBkYWxvYWQgICAgICAgICAgPSA0OSwKICAgICAgICBhYWxvYWQgICAgICAgICAgPSA1MCwKICAgICAgICBiYWxvYWQgICAgICAgICAgPSA1MSwKICAgICAgICBjYWxvYWQgICAgICAgICAgPSA1MiwKICAgICAgICBzYWxvYWQgICAgICAgICAgPSA1MywKICAgICAgICBpc3RvcmUgICAgICAgICAgPSA1NCwKICAgICAgICBsc3RvcmUgICAgICAgICAgPSA1NSwKICAgICAgICBmc3RvcmUgICAgICAgICAgPSA1NiwKICAgICAgICBkc3RvcmUgICAgICAgICAgPSA1NywKICAgICAgICBhc3RvcmUgICAgICAgICAgPSA1OCwKICAgICAgICBpc3RvcmVfMCAgICAgICAgPSA1OSwKICAgICAgICBpc3RvcmVfMSAgICAgICAgPSA2MCwKICAgICAgICBpc3RvcmVfMiAgICAgICAgPSA2MSwKICAgICAgICBpc3RvcmVfMyAgICAgICAgPSA2MiwKICAgICAgICBsc3RvcmVfMCAgICAgICAgPSA2MywKICAgICAgICBsc3RvcmVfMSAgICAgICAgPSA2NCwKICAgICAgICBsc3RvcmVfMiAgICAgICAgPSA2NSwKICAgICAgICBsc3RvcmVfMyAgICAgICAgPSA2NiwKICAgICAgICBmc3RvcmVfMCAgICAgICAgPSA2NywKICAgICAgICBmc3RvcmVfMSAgICAgICAgPSA2OCwKICAgICAgICBmc3RvcmVfMiAgICAgICAgPSA2OSwKICAgICAgICBmc3RvcmVfMyAgICAgICAgPSA3MCwKICAgICAgICBkc3RvcmVfMCAgICAgICAgPSA3MSwKICAgICAgICBkc3RvcmVfMSAgICAgICAgPSA3MiwKICAgICAgICBkc3RvcmVfMiAgICAgICAgPSA3MywKICAgICAgICBkc3RvcmVfMyAgICAgICAgPSA3NCwKICAgICAgICBhc3RvcmVfMCAgICAgICAgPSA3NSwKICAgICAgICBhc3RvcmVfMSAgICAgICAgPSA3NiwKICAgICAgICBhc3RvcmVfMiAgICAgICAgPSA3NywKICAgICAgICBhc3RvcmVfMyAgICAgICAgPSA3OCwKICAgICAgICBpYXN0b3JlICAgICAgICAgPSA3OSwKICAgICAgICBsYXN0b3JlICAgICAgICAgPSA4MCwKICAgICAgICBmYXN0b3JlICAgICAgICAgPSA4MSwKICAgICAgICBkYXN0b3JlICAgICAgICAgPSA4MiwKICAgICAgICBhYXN0b3JlICAgICAgICAgPSA4MywKICAgICAgICBiYXN0b3JlICAgICAgICAgPSA4NCwKICAgICAgICBjYXN0b3JlICAgICAgICAgPSA4NSwKICAgICAgICBzYXN0b3JlICAgICAgICAgPSA4NiwKICAgICAgICBwb3AgICAgICAgICAgICAgPSA4NywKICAgICAgICBwb3AyICAgICAgICAgICAgPSA4OCwKICAgICAgICBkdXAgICAgICAgICAgICAgPSA4OSwKICAgICAgICBkdXBfeDEgICAgICAgICAgPSA5MCwKICAgICAgICBkdXBfeDIgICAgICAgICAgPSA5MSwKICAgICAgICBkdXAyICAgICAgICAgICAgPSA5MiwKICAgICAgICBkdXAyX3gxICAgICAgICAgPSA5MywKICAgICAgICBkdXAyX3gyICAgICAgICAgPSA5NCwKICAgICAgICBzd2FwICAgICAgICAgICAgPSA5NSwKICAgICAgICBpYWRkICAgICAgICAgICAgPSA5NiwKICAgICAgICBsYWRkICAgICAgICAgICAgPSA5NywKICAgICAgICBmYWRkICAgICAgICAgICAgPSA5OCwKICAgICAgICBkYWRkICAgICAgICAgICAgPSA5OSwKICAgICAgICBpc3ViICAgICAgICAgICAgPSAxMDAsCiAgICAgICAgbHN1YiAgICAgICAgICAgID0gMTAxLAogICAgICAgIGZzdWIgICAgICAgICAgICA9IDEwMiwKICAgICAgICBkc3ViICAgICAgICAgICAgPSAxMDMsCiAgICAgICAgaW11bCAgICAgICAgICAgID0gMTA0LAogICAgICAgIGxtdWwgICAgICAgICAgICA9IDEwNSwKICAgICAgICBmbXVsICAgICAgICAgICAgPSAxMDYsCiAgICAgICAgZG11bCAgICAgICAgICAgID0gMTA3LAogICAgICAgIGlkaXYgICAgICAgICAgICA9IDEwOCwKICAgICAgICBsZGl2ICAgICAgICAgICAgPSAxMDksCiAgICAgICAgZmRpdiAgICAgICAgICAgID0gMTEwLAogICAgICAgIGRkaXYgICAgICAgICAgICA9IDExMSwKICAgICAgICBpbW9kICAgICAgICAgICAgPSAxMTIsCiAgICAgICAgbG1vZCAgICAgICAgICAgID0gMTEzLAogICAgICAgIGZtb2QgICAgICAgICAgICA9IDExNCwKICAgICAgICBkbW9kICAgICAgICAgICAgPSAxMTUsCiAgICAgICAgaW5lZyAgICAgICAgICAgID0gMTE2LAogICAgICAgIGxuZWcgICAgICAgICAgICA9IDExNywKICAgICAgICBmbmVnICAgICAgICAgICAgPSAxMTgsCiAgICAgICAgZG5lZyAgICAgICAgICAgID0gMTE5LAogICAgICAgIGlzaGwgICAgICAgICAgICA9IDEyMCwKICAgICAgICBsc2hsICAgICAgICAgICAgPSAxMjEsCiAgICAgICAgaXNociAgICAgICAgICAgID0gMTIyLAogICAgICAgIGxzaHIgICAgICAgICAgICA9IDEyMywKICAgICAgICBpdXNociAgICAgICAgICAgPSAxMjQsCiAgICAgICAgbHVzaHIgICAgICAgICAgID0gMTI1LAogICAgICAgIGlhbmQgICAgICAgICAgICA9IDEyNiwKICAgICAgICBsYW5kICAgICAgICAgICAgPSAxMjcsCiAgICAgICAgaW9yICAgICAgICAgICAgID0gMTI4LAogICAgICAgIGxvciAgICAgICAgICAgICA9IDEyOSwKICAgICAgICBpeG9yICAgICAgICAgICAgPSAxMzAsCiAgICAgICAgbHhvciAgICAgICAgICAgID0gMTMxLAogICAgICAgIGlpbmMgICAgICAgICAgICA9IDEzMiwKICAgICAgICBpMmwgICAgICAgICAgICAgPSAxMzMsCiAgICAgICAgaTJmICAgICAgICAgICAgID0gMTM0LAogICAgICAgIGkyZCAgICAgICAgICAgICA9IDEzNSwKICAgICAgICBsMmkgICAgICAgICAgICAgPSAxMzYsCiAgICAgICAgbDJmICAgICAgICAgICAgID0gMTM3LAogICAgICAgIGwyZCAgICAgICAgICAgICA9IDEzOCwKICAgICAgICBmMmkgICAgICAgICAgICAgPSAxMzksCiAgICAgICAgZjJsICAgICAgICAgICAgID0gMTQwLAogICAgICAgIGYyZCAgICAgICAgICAgICA9IDE0MSwKICAgICAgICBkMmkgICAgICAgICAgICAgPSAxNDIsCiAgICAgICAgZDJsICAgICAgICAgICAgID0gMTQzLAogICAgICAgIGQyZiAgICAgICAgICAgICA9IDE0NCwKICAgICAgICBpbnQyYnl0ZSAgICAgICAgPSAxNDUsCiAgICAgICAgaW50MmNoYXIgICAgICAgID0gMTQ2LAogICAgICAgIGludDJzaG9ydCAgICAgICA9IDE0NywKICAgICAgICBsY21wICAgICAgICAgICAgPSAxNDgsCiAgICAgICAgZmNtcGwgICAgICAgICAgID0gMTQ5LAogICAgICAgIGZjbXBnICAgICAgICAgICA9IDE1MCwKICAgICAgICBkY21wbCAgICAgICAgICAgPSAxNTEsCiAgICAgICAgZGNtcGcgICAgICAgICAgID0gMTUyLAogICAgICAgIGlmZXEgICAgICAgICAgICA9IDE1MywKICAgICAgICBpZm5lICAgICAgICAgICAgPSAxNTQsCiAgICAgICAgaWZsdCAgICAgICAgICAgID0gMTU1LAogICAgICAgIGlmZ2UgICAgICAgICAgICA9IDE1NiwKICAgICAgICBpZmd0ICAgICAgICAgICAgPSAxNTcsCiAgICAgICAgaWZsZSAgICAgICAgICAgID0gMTU4LAogICAgICAgIGlmX2ljbXBlcSAgICAgICA9IDE1OSwKICAgICAgICBpZl9pY21wbmUgICAgICAgPSAxNjAsCiAgICAgICAgaWZfaWNtcGx0ICAgICAgID0gMTYxLAogICAgICAgIGlmX2ljbXBnZSAgICAgICA9IDE2MiwKICAgICAgICBpZl9pY21wZ3QgICAgICAgPSAxNjMsCiAgICAgICAgaWZfaWNtcGxlICAgICAgID0gMTY0LAogICAgICAgIGlmX2FjbXBlcSAgICAgICA9IDE2NSwKICAgICAgICBpZl9hY21wbmUgICAgICAgPSAxNjYsCiAgICAgICAgZ290b18gICAgICAgICAgID0gMTY3LAogICAgICAgIGpzciAgICAgICAgICAgICA9IDE2OCwKICAgICAgICByZXQgICAgICAgICAgICAgPSAxNjksCiAgICAgICAgdGFibGVzd2l0Y2ggICAgID0gMTcwLAogICAgICAgIGxvb2t1cHN3aXRjaCAgICA9IDE3MSwKICAgICAgICBpcmV0dXJuICAgICAgICAgPSAxNzIsCiAgICAgICAgbHJldHVybiAgICAgICAgID0gMTczLAogICAgICAgIGZyZXR1cm4gICAgICAgICA9IDE3NCwKICAgICAgICBkcmV0dXJuICAgICAgICAgPSAxNzUsCiAgICAgICAgYXJldHVybiAgICAgICAgID0gMTc2LAogICAgICAgIHJldHVybl8gICAgICAgICA9IDE3NywKICAgICAgICBnZXRzdGF0aWMgICAgICAgPSAxNzgsCiAgICAgICAgcHV0c3RhdGljICAgICAgID0gMTc5LAogICAgICAgIGdldGZpZWxkICAgICAgICA9IDE4MCwKICAgICAgICBwdXRmaWVsZCAgICAgICAgPSAxODEsCiAgICAgICAgaW52b2tldmlydHVhbCAgID0gMTgyLAogICAgICAgIGludm9rZXNwZWNpYWwgICA9IDE4MywKICAgICAgICBpbnZva2VzdGF0aWMgICAgPSAxODQsCiAgICAgICAgaW52b2tlaW50ZXJmYWNlID0gMTg1LAogICAgICAgIGludm9rZWR5bmFtaWMgICA9IDE4NiwKICAgICAgICBuZXdfICAgICAgICAgICAgPSAxODcsCiAgICAgICAgbmV3YXJyYXkgICAgICAgID0gMTg4LAogICAgICAgIGFuZXdhcnJheSAgICAgICA9IDE4OSwKICAgICAgICBhcnJheWxlbmd0aCAgICAgPSAxOTAsCiAgICAgICAgYXRocm93ICAgICAgICAgID0gMTkxLAogICAgICAgIGNoZWNrY2FzdCAgICAgICA9IDE5MiwKICAgICAgICBpbnN0YW5jZW9mXyAgICAgPSAxOTMsCiAgICAgICAgbW9uaXRvcmVudGVyICAgID0gMTk0LAogICAgICAgIG1vbml0b3JleGl0ICAgICA9IDE5NSwKICAgICAgICB3aWRlICAgICAgICAgICAgPSAxOTYsCiAgICAgICAgbXVsdGlhbmV3YXJyYXkgID0gMTk3LAogICAgICAgIGlmX2FjbXBfbnVsbCAgICA9IDE5OCwKICAgICAgICBpZl9hY21wX25vbm51bGwgPSAxOTksCiAgICAgICAgZ290b193ICAgICAgICAgID0gMjAwLAogICAgICAgIGpzcl93ICAgICAgICAgICA9IDIwMSwKICAgICAgICBicmVha3BvaW50ICAgICAgPSAyMDIsCiAgICAgICAgQnl0ZUNvZGVDb3VudCAgID0gMjAzOwoKICAgIC8qKiBWaXJ0dWFsIGluc3RydWN0aW9uIGNvZGVzOyB1c2VkIGZvciBjb25zdGFudCBmb2xkaW5nLgogICAgICovCiAgICBpbnQgc3RyaW5nX2FkZCAgICAgID0gMjU2LCAgLy8gc3RyaW5nICsKICAgICAgICBib29sX25vdCAgICAgICAgPSAyNTcsICAvLyBib29sZWFuICEKICAgICAgICBib29sX2FuZCAgICAgICAgPSAyNTgsICAvLyBib29sZWFuICYmCiAgICAgICAgYm9vbF9vciAgICAgICAgID0gMjU5OyAgLy8gYm9vbGVhbiB8fAoKICAgIC8qKiBWaXJ0dWFsIG9wY29kZXM7IHVzZWQgZm9yIHNoaWZ0cyB3aXRoIGxvbmcgc2hpZnRjb3VudAogICAgICovCiAgICBpbnQgaXNobGwgICAgICAgICAgID0gMjcwLCAgLy8gaW50IHNoaWZ0IGxlZnQgd2l0aCBsb25nIGNvdW50CiAgICAgICAgbHNobGwgICAgICAgICAgID0gMjcxLCAgLy8gbG9uZyBzaGlmdCBsZWZ0IHdpdGggbG9uZyBjb3VudAogICAgICAgIGlzaHJsICAgICAgICAgICA9IDI3MiwgIC8vIGludCBzaGlmdCByaWdodCB3aXRoIGxvbmcgY291bnQKICAgICAgICBsc2hybCAgICAgICAgICAgPSAyNzMsICAvLyBsb25nIHNoaWZ0IHJpZ2h0IHdpdGggbG9uZyBjb3VudAogICAgICAgIGl1c2hybCAgICAgICAgICA9IDI3NCwgIC8vIGludCB1bnNpZ25lZCBzaGlmdCByaWdodCB3aXRoIGxvbmcgY291bnQKICAgICAgICBsdXNocmwgICAgICAgICAgPSAyNzU7ICAvLyBsb25nIHVuc2lnbmVkIHNoaWZ0IHJpZ2h0IHdpdGggbG9uZyBjb3VudAoKICAgIC8qKiBWaXJ0dWFsIG9wY29kZSBmb3IgbnVsbCByZWZlcmVuY2UgY2hlY2tzCiAgICAgKi8KICAgIGludCBudWxsY2hrICAgICAgICAgPSAyNzY7ICAvLyByZXR1cm4gb3BlcmFuZCBpZiBub24tbnVsbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBvdGhlcndpc2UgdGhyb3cgTnVsbFBvaW50ZXJFeGNlcHRpb24uCgogICAgLyoqIFZpcnR1YWwgb3Bjb2RlIGZvciBkaXNhbGxvd2VkIG9wZXJhdGlvbnMuCiAgICAgKi8KICAgIGludCBlcnJvciAgICAgICAgICAgPSAyNzc7CgogICAgLyoqIEFsbCBjb25kaXRpb25hbCBqdW1wcyBjb21lIGluIHBhaXJzLiBUbyBzdHJlYW1saW5lIHRoZQogICAgICogIHRyZWF0bWVudCBvZiBqdW1wcywgd2UgYWxzbyBpbnRyb2R1Y2UgYSBuZWdhdGlvbiBvZiBhbgogICAgICogIHVuY29uZGl0aW9uYWwganVtcC4gVGhhdCBvcGNvZGUgaGFwcGVucyB0byBiZSBqc3IuCiAgICAgKi8KICAgIGludCBkb250Z290byAgICAgICAgPSBqc3I7CgogICAgLyoqIFNoaWZ0IGFuZCBtYXNrIGNvbnN0YW50cyBmb3Igc2hpZnRpbmcgcHJlZml4IGluc3RydWN0aW9ucy4KICAgICAqICBhIHBhaXIgb2YgaW5zdHJ1Y3Rpb24gY29kZXMgc3VjaCBhcyBMQ01QIDsgSUZFUSBpcyBlbmNvZGVkCiAgICAgKiAgaW4gU3ltdGFiIGFzIHtAbGl0ZXJhbCAoTENNUCA8PCBwcmVTaGlmdCkgKyBJRkVRIH0uCiAgICAgKi8KICAgIGludCBwcmVTaGlmdCAgICAgICAgPSA5OwogICAgaW50IHByZU1hc2sgICAgICAgICA9ICgxIDw8IHByZVNoaWZ0KSAtIDE7CgogICAgLyoqIFR5cGUgY29kZXMuCiAgICAgKi8KICAgIGludCBJTlRjb2RlICAgICAgICAgPSAwLAogICAgICAgIExPTkdjb2RlICAgICAgICA9IDEsCiAgICAgICAgRkxPQVRjb2RlICAgICAgID0gMiwKICAgICAgICBET1VCTEVjb2RlICAgICAgPSAzLAogICAgICAgIE9CSkVDVGNvZGUgICAgICA9IDQsCiAgICAgICAgQllURWNvZGUgICAgICAgID0gNSwKICAgICAgICBDSEFSY29kZSAgICAgICAgPSA2LAogICAgICAgIFNIT1JUY29kZSAgICAgICA9IDcsCiAgICAgICAgVk9JRGNvZGUgICAgICAgID0gOCwKICAgICAgICBUeXBlQ29kZUNvdW50ICAgPSA5OwoKICAgIHN0YXRpYyBmaW5hbCBTdHJpbmdbXSB0eXBlY29kZU5hbWVzID0gewogICAgICAgICJpbnQiLAogICAgICAgICJsb25nIiwKICAgICAgICAiZmxvYXQiLAogICAgICAgICJkb3VibGUiLAogICAgICAgICJvYmplY3QiLAogICAgICAgICJieXRlIiwKICAgICAgICAiY2hhciIsCiAgICAgICAgInNob3J0IiwKICAgICAgICAidm9pZCIsCiAgICAgICAgIm9vcHMiCiAgICB9Owp9ClBLAwQKAAAIAAAGO6lKUWHtjJwhAACcIQAAJgAAAGNvbS9zdW4vdG9vbHMvamF2YWMvanZtL0NsYXNzRmlsZS5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAxOTk5LCAyMDE2LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuamF2YWMuanZtOwoKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5UeXBlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlR5cGVzOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy5jb2RlLlR5cGVzLlVuaXF1ZVR5cGU7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuTmFtZTsKCgovKiogQSBKVk0gY2xhc3MgZmlsZS4KICoKICogIDxwPkdlbmVyaWMgSmF2YSBjbGFzc2ZpbGVzIGhhdmUgb25lIGFkZGl0aW9uYWwgYXR0cmlidXRlIGZvciBjbGFzc2VzLAogKiAgbWV0aG9kcyBhbmQgZmllbGRzOgogKiAgPHByZT4KICogICAiU2lnbmF0dXJlIiAodTQgYXR0ci1sZW5ndGgsIHUyIHNpZ25hdHVyZS1pbmRleCkKICogIDwvcHJlPgogKgogKiAgPHA+QSBzaWduYXR1cmUgZ2l2ZXMgdGhlIGZ1bGwgSmF2YSB0eXBlIG9mIGEgbWV0aG9kIG9yIGZpZWxkLiBXaGVuCiAqICB1c2VkIGFzIGEgY2xhc3MgYXR0cmlidXRlLCBpdCBpbmRpY2F0ZXMgdHlwZSBwYXJhbWV0ZXJzLCBmb2xsb3dlZAogKiAgYnkgc3VwZXJ0eXBlLCBmb2xsb3dlZCBieSBhbGwgaW50ZXJmYWNlcy4KICogIDxwcmU+CiAqICAgICBtZXRob2RPckZpZWxkU2lnbmF0dXJlIDo6PSB0eXBlCiAqICAgICBjbGFzc1NpZ25hdHVyZSAgICAgICAgIDo6PSBbIHR5cGVwYXJhbXMgXSBzdXBlcnR5cGUgeyBpbnRlcmZhY2V0eXBlIH0KICogIDwvcHJlPgogKiAgPHA+VGhlIHR5cGUgc3ludGF4IGluIHNpZ25hdHVyZXMgaXMgZXh0ZW5kZWQgYXMgZm9sbG93czoKICogIDxwcmU+e0BsaXRlcmFsCiAqICAgICB0eXBlICAgICAgIDo6PSAuLi4gfCBjbGFzc3R5cGUgfCBtZXRob2R0eXBlIHwgdHlwZXZhcgogKiAgICAgY2xhc3N0eXBlICA6Oj0gY2xhc3NzaWcgeyAnLicgY2xhc3NzaWcgfQogKiAgICAgY2xhc3NpZyAgICA6Oj0gJ0wnIG5hbWUgW3R5cGVhcmdzXSAnOycKICogICAgIG1ldGhvZHR5cGUgOjo9IFsgdHlwZXBhcmFtcyBdICcoJyB7IHR5cGUgfSAnKScgdHlwZQogKiAgICAgdHlwZXZhciAgICA6Oj0gJ1QnIG5hbWUgJzsnCiAqICAgICB0eXBlYXJncyAgIDo6PSAnPCcgdHlwZSB7IHR5cGUgfSAnPicKICogICAgIHR5cGVwYXJhbXMgOjo9ICc8JyB0eXBlcGFyYW0geyB0eXBlcGFyYW0gfSAnPicKICogICAgIHR5cGVwYXJhbSAgOjo9IG5hbWUgJzonIHR5cGUKICogIH08L3ByZT4KICogIDxwPlRoaXMgY2xhc3MgZGVmaW5lcyBjb25zdGFudHMgdXNlZCBpbiBjbGFzcyBmaWxlcyBhcyB3ZWxsCiAqICBhcyByb3V0aW5lcyB0byBjb252ZXJ0IGJldHdlZW4gaW50ZXJuYWwgYGAuJycgYW5kIGV4dGVybmFsIGBgLycnCiAqICBzZXBhcmF0b3JzIGluIGNsYXNzIG5hbWVzLgogKgogKiAgPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24gcmlzay4KICogIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlIG9yCiAqICBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+ICovCnB1YmxpYyBjbGFzcyBDbGFzc0ZpbGUgewoKICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgaW50IEpBVkFfTUFHSUMgPSAweENBRkVCQUJFOwoKICAgIC8vIHNlZSBUYXJnZXQKICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgaW50IENPTlNUQU5UX1V0ZjggPSAxOwogICAgcHVibGljIGZpbmFsIHN0YXRpYyBpbnQgQ09OU1RBTlRfVW5pY29kZSA9IDI7CiAgICBwdWJsaWMgZmluYWwgc3RhdGljIGludCBDT05TVEFOVF9JbnRlZ2VyID0gMzsKICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgaW50IENPTlNUQU5UX0Zsb2F0ID0gNDsKICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgaW50IENPTlNUQU5UX0xvbmcgPSA1OwogICAgcHVibGljIGZpbmFsIHN0YXRpYyBpbnQgQ09OU1RBTlRfRG91YmxlID0gNjsKICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgaW50IENPTlNUQU5UX0NsYXNzID0gNzsKICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgaW50IENPTlNUQU5UX1N0cmluZyA9IDg7CiAgICBwdWJsaWMgZmluYWwgc3RhdGljIGludCBDT05TVEFOVF9GaWVsZHJlZiA9IDk7CiAgICBwdWJsaWMgZmluYWwgc3RhdGljIGludCBDT05TVEFOVF9NZXRob2RyZWYgPSAxMDsKICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgaW50IENPTlNUQU5UX0ludGVyZmFjZU1ldGhvZHJlZiA9IDExOwogICAgcHVibGljIGZpbmFsIHN0YXRpYyBpbnQgQ09OU1RBTlRfTmFtZWFuZFR5cGUgPSAxMjsKICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgaW50IENPTlNUQU5UX01ldGhvZEhhbmRsZSA9IDE1OwogICAgcHVibGljIGZpbmFsIHN0YXRpYyBpbnQgQ09OU1RBTlRfTWV0aG9kVHlwZSA9IDE2OwogICAgcHVibGljIGZpbmFsIHN0YXRpYyBpbnQgQ09OU1RBTlRfSW52b2tlRHluYW1pYyA9IDE4OwogICAgcHVibGljIGZpbmFsIHN0YXRpYyBpbnQgQ09OU1RBTlRfTW9kdWxlID0gMTk7CiAgICBwdWJsaWMgZmluYWwgc3RhdGljIGludCBDT05TVEFOVF9QYWNrYWdlID0gMjA7CgogICAgcHVibGljIGZpbmFsIHN0YXRpYyBpbnQgUkVGX2dldEZpZWxkID0gMTsKICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgaW50IFJFRl9nZXRTdGF0aWMgPSAyOwogICAgcHVibGljIGZpbmFsIHN0YXRpYyBpbnQgUkVGX3B1dEZpZWxkID0gMzsKICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgaW50IFJFRl9wdXRTdGF0aWMgPSA0OwogICAgcHVibGljIGZpbmFsIHN0YXRpYyBpbnQgUkVGX2ludm9rZVZpcnR1YWwgPSA1OwogICAgcHVibGljIGZpbmFsIHN0YXRpYyBpbnQgUkVGX2ludm9rZVN0YXRpYyA9IDY7CiAgICBwdWJsaWMgZmluYWwgc3RhdGljIGludCBSRUZfaW52b2tlU3BlY2lhbCA9IDc7CiAgICBwdWJsaWMgZmluYWwgc3RhdGljIGludCBSRUZfbmV3SW52b2tlU3BlY2lhbCA9IDg7CiAgICBwdWJsaWMgZmluYWwgc3RhdGljIGludCBSRUZfaW52b2tlSW50ZXJmYWNlID0gOTsKCiAgICBwdWJsaWMgZmluYWwgc3RhdGljIGludCBNQVhfUEFSQU1FVEVSUyA9IDB4ZmY7CiAgICBwdWJsaWMgZmluYWwgc3RhdGljIGludCBNQVhfRElNRU5TSU9OUyA9IDB4ZmY7CiAgICBwdWJsaWMgZmluYWwgc3RhdGljIGludCBNQVhfQ09ERSA9IDB4ZmZmZjsKICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgaW50IE1BWF9MT0NBTFMgPSAweGZmZmY7CiAgICBwdWJsaWMgZmluYWwgc3RhdGljIGludCBNQVhfU1RBQ0sgPSAweGZmZmY7CgogICAgcHVibGljIGVudW0gVmVyc2lvbiB7CiAgICAgICAgVjQ1XzMoNDUsIDMpLCAvLyBiYXNlIGxldmVsIGZvciBhbGwgYXR0cmlidXRlcwogICAgICAgIFY0OSg0OSwgMCksICAgLy8gSkRLIDEuNTogZW51bSwgZ2VuZXJpY3MsIGFubm90YXRpb25zCiAgICAgICAgVjUwKDUwLCAwKSwgICAvLyBKREsgMS42OiBzdGFja21hcHMKICAgICAgICBWNTEoNTEsIDApLCAgIC8vIEpESyAxLjcKICAgICAgICBWNTIoNTIsIDApLCAgIC8vIEpESyAxLjg6IGxhbWJkYSwgdHlwZSBhbm5vcywgcGFyYW0gbmFtZXMKICAgICAgICBWNTMoNTMsIDApOyAgIC8vIEpESyAxLjk6IG1vZHVsZXMsIGluZHkgc3RyaW5nIGNvbmNhdAogICAgICAgIFZlcnNpb24oaW50IG1ham9yLCBpbnQgbWlub3IpIHsKICAgICAgICAgICAgdGhpcy5tYWpvciA9IG1ham9yOwogICAgICAgICAgICB0aGlzLm1pbm9yID0gbWlub3I7CiAgICAgICAgfQogICAgICAgIHB1YmxpYyBmaW5hbCBpbnQgbWFqb3IsIG1pbm9yOwoKICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBWZXJzaW9uIE1JTiA9IHZhbHVlcygpWzBdOwogICAgICAgIC8qKiBSZXR1cm4gdGhlIGxlYXN0IHZlcnNpb24gc3VwcG9ydGVkLCBNSU4gKi8KICAgICAgICBwdWJsaWMgc3RhdGljIFZlcnNpb24gTUlOKCkgeyByZXR1cm4gTUlOOyB9CgogICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFZlcnNpb24gTUFYID0gdmFsdWVzKClbdmFsdWVzKCkubGVuZ3RoLTFdOwogICAgICAgIC8qKiBSZXR1cm4gdGhlIGxhcmdlc3QgdmVyc2lvbiBzdXBwb3J0ZWQsIE1BWCAqLwogICAgICAgIHB1YmxpYyBzdGF0aWMgVmVyc2lvbiBNQVgoKSB7IHJldHVybiBNQVg7IH0KICAgIH0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFN0cmluZyBUcmFuc2xhdGlvbiBSb3V0aW5lcwogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgogICAgLyoqCiAgICAgKiBSZXR1cm4gaW50ZXJuYWwgcmVwcmVzZW50YXRpb24gb2YgYnVmW29mZnNldC4ub2Zmc2V0K2xlbi0xXSwgY29udmVydGluZyAnLycgdG8gJy4nLgogICAgICoKICAgICAqIE5vdGU6IHRoZSBuYW1pbmcgaXMgdGhlIGludmVyc2Ugb2YgdGhhdCB1c2VkIGJ5IEpWTVMgNC4yIFRoZSBJbnRlcm5hbCBGb3JtIE9mIE5hbWVzLAogICAgICogd2hpY2ggZGVmaW5lcyAiaW50ZXJuYWwgbmFtZSIgdG8gYmUgdGhlIGZvcm0gdXNpbmcgIi8iIGluc3RlYWQgb2YgIi4iCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgYnl0ZVtdIGludGVybmFsaXplKGJ5dGVbXSBidWYsIGludCBvZmZzZXQsIGludCBsZW4pIHsKICAgICAgICBieXRlW10gdHJhbnNsYXRlZCA9IG5ldyBieXRlW2xlbl07CiAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBsZW47IGorKykgewogICAgICAgICAgICBieXRlIGIgPSBidWZbb2Zmc2V0ICsgal07CiAgICAgICAgICAgIGlmIChiID09ICcvJykgdHJhbnNsYXRlZFtqXSA9IChieXRlKSAnLic7CiAgICAgICAgICAgIGVsc2UgdHJhbnNsYXRlZFtqXSA9IGI7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0cmFuc2xhdGVkOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJuIGludGVybmFsIHJlcHJlc2VudGF0aW9uIG9mIGdpdmVuIG5hbWUsIGNvbnZlcnRpbmcgJy8nIHRvICcuJy4KICAgICAqCiAgICAgKiBOb3RlOiB0aGUgbmFtaW5nIGlzIHRoZSBpbnZlcnNlIG9mIHRoYXQgdXNlZCBieSBKVk1TIDQuMiBUaGUgSW50ZXJuYWwgRm9ybSBPZiBOYW1lcywKICAgICAqIHdoaWNoIGRlZmluZXMgImludGVybmFsIG5hbWUiIHRvIGJlIHRoZSBmb3JtIHVzaW5nICIvIiBpbnN0ZWFkIG9mICIuIgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGJ5dGVbXSBpbnRlcm5hbGl6ZShOYW1lIG5hbWUpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxpemUobmFtZS5nZXRCeXRlQXJyYXkoKSwgbmFtZS5nZXRCeXRlT2Zmc2V0KCksIG5hbWUuZ2V0Qnl0ZUxlbmd0aCgpKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybiBleHRlcm5hbCByZXByZXNlbnRhdGlvbiBvZiBidWZbb2Zmc2V0Li5vZmZzZXQrbGVuLTFdLCBjb252ZXJ0aW5nICcuJyB0byAnLycuCiAgICAgKgogICAgICogTm90ZTogdGhlIG5hbWluZyBpcyB0aGUgaW52ZXJzZSBvZiB0aGF0IHVzZWQgYnkgSlZNUyA0LjIgVGhlIEludGVybmFsIEZvcm0gT2YgTmFtZXMsCiAgICAgKiB3aGljaCBkZWZpbmVzICJpbnRlcm5hbCBuYW1lIiB0byBiZSB0aGUgZm9ybSB1c2luZyAiLyIgaW5zdGVhZCBvZiAiLiIKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBieXRlW10gZXh0ZXJuYWxpemUoYnl0ZVtdIGJ1ZiwgaW50IG9mZnNldCwgaW50IGxlbikgewogICAgICAgIGJ5dGVbXSB0cmFuc2xhdGVkID0gbmV3IGJ5dGVbbGVuXTsKICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IGxlbjsgaisrKSB7CiAgICAgICAgICAgIGJ5dGUgYiA9IGJ1ZltvZmZzZXQgKyBqXTsKICAgICAgICAgICAgaWYgKGIgPT0gJy4nKSB0cmFuc2xhdGVkW2pdID0gKGJ5dGUpICcvJzsKICAgICAgICAgICAgZWxzZSB0cmFuc2xhdGVkW2pdID0gYjsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRyYW5zbGF0ZWQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm4gZXh0ZXJuYWwgcmVwcmVzZW50YXRpb24gb2YgZ2l2ZW4gbmFtZSwgY29udmVydGluZyAnLycgdG8gJy4nLgogICAgICoKICAgICAqIE5vdGU6IHRoZSBuYW1pbmcgaXMgdGhlIGludmVyc2Ugb2YgdGhhdCB1c2VkIGJ5IEpWTVMgNC4yIFRoZSBJbnRlcm5hbCBGb3JtIE9mIE5hbWVzLAogICAgICogd2hpY2ggZGVmaW5lcyAiaW50ZXJuYWwgbmFtZSIgdG8gYmUgdGhlIGZvcm0gdXNpbmcgIi8iIGluc3RlYWQgb2YgIi4iCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgYnl0ZVtdIGV4dGVybmFsaXplKE5hbWUgbmFtZSkgewogICAgICAgIHJldHVybiBleHRlcm5hbGl6ZShuYW1lLmdldEJ5dGVBcnJheSgpLCBuYW1lLmdldEJ5dGVPZmZzZXQoKSwgbmFtZS5nZXRCeXRlTGVuZ3RoKCkpOwogICAgfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBOYW1lLWFuZC10eXBlCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiAgICAvKiogQSBjbGFzcyBmb3IgdGhlIG5hbWUtYW5kLXR5cGUgc2lnbmF0dXJlIG9mIGEgbWV0aG9kIG9yIGZpZWxkLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIE5hbWVBbmRUeXBlIHsKICAgICAgICBOYW1lIG5hbWU7CiAgICAgICAgVW5pcXVlVHlwZSB1bmlxdWVUeXBlOwogICAgICAgIFR5cGVzIHR5cGVzOwoKICAgICAgICBOYW1lQW5kVHlwZShOYW1lIG5hbWUsIFR5cGUgdHlwZSwgVHlwZXMgdHlwZXMpIHsKICAgICAgICAgICAgdGhpcy5uYW1lID0gbmFtZTsKICAgICAgICAgICAgdGhpcy51bmlxdWVUeXBlID0gbmV3IFVuaXF1ZVR5cGUodHlwZSwgdHlwZXMpOwogICAgICAgICAgICB0aGlzLnR5cGVzID0gdHlwZXM7CiAgICAgICAgfQoKICAgICAgICB2b2lkIHNldFR5cGUoVHlwZSB0eXBlKSB7CiAgICAgICAgICAgIHRoaXMudW5pcXVlVHlwZSA9IG5ldyBVbmlxdWVUeXBlKHR5cGUsIHR5cGVzKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb3RoZXIpIHsKICAgICAgICAgICAgcmV0dXJuIChvdGhlciBpbnN0YW5jZW9mIE5hbWVBbmRUeXBlICYmCiAgICAgICAgICAgICAgICAgICAgbmFtZSA9PSAoKE5hbWVBbmRUeXBlKSBvdGhlcikubmFtZSAmJgogICAgICAgICAgICAgICAgICAgICAgICB1bmlxdWVUeXBlLmVxdWFscygoKE5hbWVBbmRUeXBlKSBvdGhlcikudW5pcXVlVHlwZSkpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgICAgICAgcmV0dXJuIG5hbWUuaGFzaENvZGUoKSAqIHVuaXF1ZVR5cGUuaGFzaENvZGUoKTsKICAgICAgICB9CiAgICB9Cn0KUEsDBAoAAAgAANJ9TUrVckTkcV8AAHFfAAAiAAAAY29tL3N1bi90b29scy9qYXZhYy9qdm0vSXRlbXMuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMTk5OSwgMjAxMywgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLmphdmFjLmp2bTsKCmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmNvZGUuKjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5TeW1ib2wuKjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuY29kZS5UeXBlLio7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmp2bS5Db2RlLio7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnRyZWUuSkNUcmVlOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkFzc2VydDsKCmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5qYXZhYy5qdm0uQnl0ZUNvZGVzLio7CgovKiogQSBoZWxwZXIgY2xhc3MgZm9yIGNvZGUgZ2VuZXJhdGlvbi4gSXRlbXMgYXJlIG9iamVjdHMKICogIHRoYXQgc3RhbmQgZm9yIGFkZHJlc3NhYmxlIGVudGl0aWVzIGluIHRoZSBieXRlY29kZS4gRWFjaCBpdGVtCiAqICBzdXBwb3J0cyBhIGZpeGVkIHByb3RvY29sIGZvciBsb2FkaW5nIHRoZSBpdGVtIG9uIHRoZSBzdGFjaywgc3RvcmluZwogKiAgaW50byBpdCwgY29udmVydGluZyBpdCBpbnRvIGEganVtcCBjb25kaXRpb24sIGFuZCBzZXZlcmFsIG90aGVycy4KICogIFRoZXJlIGFyZSBtYW55IGluZGl2aWR1YWwgZm9ybXMgb2YgaXRlbXMsIHN1Y2ggYXMgbG9jYWwsIHN0YXRpYywKICogIGluZGV4ZWQsIG9yIGluc3RhbmNlIHZhcmlhYmxlcywgdmFsdWVzIG9uIHRoZSB0b3Agb2Ygc3RhY2ssIHRoZQogKiAgc3BlY2lhbCB2YWx1ZXMgdGhpcyBvciBzdXBlciwgZXRjLiBJbmRpdmlkdWFsIGl0ZW1zIGFyZSByZXByZXNlbnRlZCBhcwogKiAgaW5uZXIgY2xhc3NlcyBpbiBjbGFzcyBJdGVtcy4KICoKICogIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqICBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqICBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogKiAgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPgogKi8KcHVibGljIGNsYXNzIEl0ZW1zIHsKCiAgICAvKiogVGhlIGN1cnJlbnQgY29uc3RhbnQgcG9vbC4KICAgICAqLwogICAgUG9vbCBwb29sOwoKICAgIC8qKiBUaGUgY3VycmVudCBjb2RlIGJ1ZmZlci4KICAgICAqLwogICAgQ29kZSBjb2RlOwoKICAgIC8qKiBUaGUgY3VycmVudCBzeW1ib2wgdGFibGUuCiAgICAgKi8KICAgIFN5bXRhYiBzeW1zOwoKICAgIC8qKiBUeXBlIHV0aWxpdGllcy4gKi8KICAgIFR5cGVzIHR5cGVzOwoKICAgIC8qKiBJdGVtcyB0aGF0IGV4aXN0IG9ubHkgb25jZSAoZmx5d2VpZ2h0IHBhdHRlcm4pLgogICAgICovCiAgICBwcml2YXRlIGZpbmFsIEl0ZW0gdm9pZEl0ZW07CiAgICBwcml2YXRlIGZpbmFsIEl0ZW0gdGhpc0l0ZW07CiAgICBwcml2YXRlIGZpbmFsIEl0ZW0gc3VwZXJJdGVtOwogICAgcHJpdmF0ZSBmaW5hbCBJdGVtW10gc3RhY2tJdGVtID0gbmV3IEl0ZW1bVHlwZUNvZGVDb3VudF07CgogICAgcHVibGljIEl0ZW1zKFBvb2wgcG9vbCwgQ29kZSBjb2RlLCBTeW10YWIgc3ltcywgVHlwZXMgdHlwZXMpIHsKICAgICAgICB0aGlzLmNvZGUgPSBjb2RlOwogICAgICAgIHRoaXMucG9vbCA9IHBvb2w7CiAgICAgICAgdGhpcy50eXBlcyA9IHR5cGVzOwogICAgICAgIHZvaWRJdGVtID0gbmV3IEl0ZW0oVk9JRGNvZGUpIHsKICAgICAgICAgICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7IHJldHVybiAidm9pZCI7IH0KICAgICAgICAgICAgfTsKICAgICAgICB0aGlzSXRlbSA9IG5ldyBTZWxmSXRlbShmYWxzZSk7CiAgICAgICAgc3VwZXJJdGVtID0gbmV3IFNlbGZJdGVtKHRydWUpOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgVk9JRGNvZGU7IGkrKykgc3RhY2tJdGVtW2ldID0gbmV3IFN0YWNrSXRlbShpKTsKICAgICAgICBzdGFja0l0ZW1bVk9JRGNvZGVdID0gdm9pZEl0ZW07CiAgICAgICAgdGhpcy5zeW1zID0gc3ltczsKICAgIH0KCiAgICAvKiogTWFrZSBhIHZvaWQgaXRlbQogICAgICovCiAgICBJdGVtIG1ha2VWb2lkSXRlbSgpIHsKICAgICAgICByZXR1cm4gdm9pZEl0ZW07CiAgICB9CiAgICAvKiogTWFrZSBhbiBpdGVtIHJlcHJlc2VudGluZyBgdGhpcycuCiAgICAgKi8KICAgIEl0ZW0gbWFrZVRoaXNJdGVtKCkgewogICAgICAgIHJldHVybiB0aGlzSXRlbTsKICAgIH0KCiAgICAvKiogTWFrZSBhbiBpdGVtIHJlcHJlc2VudGluZyBgc3VwZXInLgogICAgICovCiAgICBJdGVtIG1ha2VTdXBlckl0ZW0oKSB7CiAgICAgICAgcmV0dXJuIHN1cGVySXRlbTsKICAgIH0KCiAgICAvKiogTWFrZSBhbiBpdGVtIHJlcHJlc2VudGluZyBhIHZhbHVlIG9uIHN0YWNrLgogICAgICogIEBwYXJhbSB0eXBlICAgIFRoZSB2YWx1ZSdzIHR5cGUuCiAgICAgKi8KICAgIEl0ZW0gbWFrZVN0YWNrSXRlbShUeXBlIHR5cGUpIHsKICAgICAgICByZXR1cm4gc3RhY2tJdGVtW0NvZGUudHlwZWNvZGUodHlwZSldOwogICAgfQoKICAgIC8qKiBNYWtlIGFuIGl0ZW0gcmVwcmVzZW50aW5nIGEgZHluYW1pY2FsbHkgaW52b2tlZCBtZXRob2QuCiAgICAgKiAgQHBhcmFtIG1lbWJlciAgIFRoZSByZXByZXNlbnRlZCBzeW1ib2wuCiAgICAgKi8KICAgIEl0ZW0gbWFrZUR5bmFtaWNJdGVtKFN5bWJvbCBtZW1iZXIpIHsKICAgICAgICByZXR1cm4gbmV3IER5bmFtaWNJdGVtKG1lbWJlcik7CiAgICB9CgogICAgLyoqIE1ha2UgYW4gaXRlbSByZXByZXNlbnRpbmcgYW4gaW5kZXhlZCBleHByZXNzaW9uLgogICAgICogIEBwYXJhbSB0eXBlICAgIFRoZSBleHByZXNzaW9uJ3MgdHlwZS4KICAgICAqLwogICAgSXRlbSBtYWtlSW5kZXhlZEl0ZW0oVHlwZSB0eXBlKSB7CiAgICAgICAgcmV0dXJuIG5ldyBJbmRleGVkSXRlbSh0eXBlKTsKICAgIH0KCiAgICAvKiogTWFrZSBhbiBpdGVtIHJlcHJlc2VudGluZyBhIGxvY2FsIHZhcmlhYmxlLgogICAgICogIEBwYXJhbSB2ICAgIFRoZSByZXByZXNlbnRlZCB2YXJpYWJsZS4KICAgICAqLwogICAgTG9jYWxJdGVtIG1ha2VMb2NhbEl0ZW0oVmFyU3ltYm9sIHYpIHsKICAgICAgICByZXR1cm4gbmV3IExvY2FsSXRlbSh2LmVyYXN1cmUodHlwZXMpLCB2LmFkcik7CiAgICB9CgogICAgLyoqIE1ha2UgYW4gaXRlbSByZXByZXNlbnRpbmcgYSBsb2NhbCBhbm9ueW1vdXMgdmFyaWFibGUuCiAgICAgKiAgQHBhcmFtIHR5cGUgIFRoZSByZXByZXNlbnRlZCB2YXJpYWJsZSdzIHR5cGUuCiAgICAgKiAgQHBhcmFtIHJlZyAgIFRoZSByZXByZXNlbnRlZCB2YXJpYWJsZSdzIHJlZ2lzdGVyLgogICAgICovCiAgICBwcml2YXRlIExvY2FsSXRlbSBtYWtlTG9jYWxJdGVtKFR5cGUgdHlwZSwgaW50IHJlZykgewogICAgICAgIHJldHVybiBuZXcgTG9jYWxJdGVtKHR5cGUsIHJlZyk7CiAgICB9CgogICAgLyoqIE1ha2UgYW4gaXRlbSByZXByZXNlbnRpbmcgYSBzdGF0aWMgdmFyaWFibGUgb3IgbWV0aG9kLgogICAgICogIEBwYXJhbSBtZW1iZXIgICBUaGUgcmVwcmVzZW50ZWQgc3ltYm9sLgogICAgICovCiAgICBJdGVtIG1ha2VTdGF0aWNJdGVtKFN5bWJvbCBtZW1iZXIpIHsKICAgICAgICByZXR1cm4gbmV3IFN0YXRpY0l0ZW0obWVtYmVyKTsKICAgIH0KCiAgICAvKiogTWFrZSBhbiBpdGVtIHJlcHJlc2VudGluZyBhbiBpbnN0YW5jZSB2YXJpYWJsZSBvciBtZXRob2QuCiAgICAgKiAgQHBhcmFtIG1lbWJlciAgICAgICBUaGUgcmVwcmVzZW50ZWQgc3ltYm9sLgogICAgICogIEBwYXJhbSBub252aXJ0dWFsICAgSXMgdGhlIHJlZmVyZW5jZSBub3QgdmlydHVhbD8gKHRydWUgZm9yIGNvbnN0cnVjdG9ycwogICAgICogICAgICAgICAgICAgICAgICAgICAgYW5kIHByaXZhdGUgbWVtYmVycykuCiAgICAgKi8KICAgIEl0ZW0gbWFrZU1lbWJlckl0ZW0oU3ltYm9sIG1lbWJlciwgYm9vbGVhbiBub252aXJ0dWFsKSB7CiAgICAgICAgcmV0dXJuIG5ldyBNZW1iZXJJdGVtKG1lbWJlciwgbm9udmlydHVhbCk7CiAgICB9CgogICAgLyoqIE1ha2UgYW4gaXRlbSByZXByZXNlbnRpbmcgYSBsaXRlcmFsLgogICAgICogIEBwYXJhbSB0eXBlICAgICBUaGUgbGl0ZXJhbCdzIHR5cGUuCiAgICAgKiAgQHBhcmFtIHZhbHVlICAgIFRoZSBsaXRlcmFsJ3MgdmFsdWUuCiAgICAgKi8KICAgIEl0ZW0gbWFrZUltbWVkaWF0ZUl0ZW0oVHlwZSB0eXBlLCBPYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gbmV3IEltbWVkaWF0ZUl0ZW0odHlwZSwgdmFsdWUpOwogICAgfQoKICAgIC8qKiBNYWtlIGFuIGl0ZW0gcmVwcmVzZW50aW5nIGFuIGFzc2lnbm1lbnQgZXhwcmVzc2lvbi4KICAgICAqICBAcGFyYW0gbGhzICAgICAgVGhlIGl0ZW0gcmVwcmVzZW50aW5nIHRoZSBhc3NpZ25tZW50J3MgbGVmdCBoYW5kIHNpZGUuCiAgICAgKi8KICAgIEl0ZW0gbWFrZUFzc2lnbkl0ZW0oSXRlbSBsaHMpIHsKICAgICAgICByZXR1cm4gbmV3IEFzc2lnbkl0ZW0obGhzKTsKICAgIH0KCiAgICAvKiogTWFrZSBhbiBpdGVtIHJlcHJlc2VudGluZyBhIGNvbmRpdGlvbmFsIG9yIHVuY29uZGl0aW9uYWwganVtcC4KICAgICAqICBAcGFyYW0gb3Bjb2RlICAgICAgVGhlIGp1bXAncyBvcGNvZGUuCiAgICAgKiAgQHBhcmFtIHRydWVKdW1wcyAgIEEgY2hhaW4gZW5jb21hc3NpbmcgYWxsIGp1bXBzIHRoYXQgY2FuIGJlIHRha2VuCiAgICAgKiAgICAgICAgICAgICAgICAgICAgIGlmIHRoZSBjb25kaXRpb24gZXZhbHVhdGVzIHRvIHRydWUuCiAgICAgKiAgQHBhcmFtIGZhbHNlSnVtcHMgIEEgY2hhaW4gZW5jb21hc3NpbmcgYWxsIGp1bXBzIHRoYXQgY2FuIGJlIHRha2VuCiAgICAgKiAgICAgICAgICAgICAgICAgICAgIGlmIHRoZSBjb25kaXRpb24gZXZhbHVhdGVzIHRvIGZhbHNlLgogICAgICovCiAgICBDb25kSXRlbSBtYWtlQ29uZEl0ZW0oaW50IG9wY29kZSwgQ2hhaW4gdHJ1ZUp1bXBzLCBDaGFpbiBmYWxzZUp1bXBzKSB7CiAgICAgICAgcmV0dXJuIG5ldyBDb25kSXRlbShvcGNvZGUsIHRydWVKdW1wcywgZmFsc2VKdW1wcyk7CiAgICB9CgogICAgLyoqIE1ha2UgYW4gaXRlbSByZXByZXNlbnRpbmcgYSBjb25kaXRpb25hbCBvciB1bmNvbmRpdGlvbmFsIGp1bXAuCiAgICAgKiAgQHBhcmFtIG9wY29kZSAgICAgIFRoZSBqdW1wJ3Mgb3Bjb2RlLgogICAgICovCiAgICBDb25kSXRlbSBtYWtlQ29uZEl0ZW0oaW50IG9wY29kZSkgewogICAgICAgIHJldHVybiBtYWtlQ29uZEl0ZW0ob3Bjb2RlLCBudWxsLCBudWxsKTsKICAgIH0KCiAgICAvKiogVGhlIGJhc2UgY2xhc3Mgb2YgYWxsIGl0ZW1zLCB3aGljaCBpbXBsZW1lbnRzIGRlZmF1bHQgYmVoYXZpb3IuCiAgICAgKi8KICAgIGFic3RyYWN0IGNsYXNzIEl0ZW0gewoKICAgICAgICAvKiogVGhlIHR5cGUgY29kZSBvZiB2YWx1ZXMgcmVwcmVzZW50ZWQgYnkgdGhpcyBpdGVtLgogICAgICAgICAqLwogICAgICAgIGludCB0eXBlY29kZTsKCiAgICAgICAgSXRlbShpbnQgdHlwZWNvZGUpIHsKICAgICAgICAgICAgdGhpcy50eXBlY29kZSA9IHR5cGVjb2RlOwogICAgICAgIH0KCiAgICAgICAgLyoqIEdlbmVyYXRlIGNvZGUgdG8gbG9hZCB0aGlzIGl0ZW0gb250byBzdGFjay4KICAgICAgICAgKi8KICAgICAgICBJdGVtIGxvYWQoKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigpOwogICAgICAgIH0KCiAgICAgICAgLyoqIEdlbmVyYXRlIGNvZGUgdG8gc3RvcmUgdG9wIG9mIHN0YWNrIGludG8gdGhpcyBpdGVtLgogICAgICAgICAqLwogICAgICAgIHZvaWQgc3RvcmUoKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigic3RvcmUgdW5zdXBwb3J0ZWQ6ICIgKyB0aGlzKTsKICAgICAgICB9CgogICAgICAgIC8qKiBHZW5lcmF0ZSBjb2RlIHRvIGludm9rZSBtZXRob2QgcmVwcmVzZW50ZWQgYnkgdGhpcyBpdGVtLgogICAgICAgICAqLwogICAgICAgIEl0ZW0gaW52b2tlKCkgewogICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IodGhpcyk7CiAgICAgICAgfQoKICAgICAgICAvKiogR2VuZXJhdGUgY29kZSB0byB1c2UgdGhpcyBpdGVtIHR3aWNlLgogICAgICAgICAqLwogICAgICAgIHZvaWQgZHVwbGljYXRlKCkge30KCiAgICAgICAgLyoqIEdlbmVyYXRlIGNvZGUgdG8gYXZvaWQgaGF2aW5nIHRvIHVzZSB0aGlzIGl0ZW0uCiAgICAgICAgICovCiAgICAgICAgdm9pZCBkcm9wKCkge30KCiAgICAgICAgLyoqIEdlbmVyYXRlIGNvZGUgdG8gc3Rhc2ggYSBjb3B5IG9mIHRvcCBvZiBzdGFjayAtIG9mIHR5cGVjb2RlIHRvc2NvZGUgLQogICAgICAgICAqICB1bmRlciB0aGlzIGl0ZW0uCiAgICAgICAgICovCiAgICAgICAgdm9pZCBzdGFzaChpbnQgdG9zY29kZSkgewogICAgICAgICAgICBzdGFja0l0ZW1bdG9zY29kZV0uZHVwbGljYXRlKCk7CiAgICAgICAgfQoKICAgICAgICAvKiogR2VuZXJhdGUgY29kZSB0byB0dXJuIGl0ZW0gaW50byBhIHRlc3RhYmxlIGNvbmRpdGlvbi4KICAgICAgICAgKi8KICAgICAgICBDb25kSXRlbSBta0NvbmQoKSB7CiAgICAgICAgICAgIGxvYWQoKTsKICAgICAgICAgICAgcmV0dXJuIG1ha2VDb25kSXRlbShpZm5lKTsKICAgICAgICB9CgogICAgICAgIC8qKiBHZW5lcmF0ZSBjb2RlIHRvIGNvZXJjZSBpdGVtIHRvIGdpdmVuIHR5cGUgY29kZS4KICAgICAgICAgKiAgQHBhcmFtIHRhcmdldGNvZGUgICAgVGhlIHR5cGUgY29kZSB0byBjb2VyY2UgdG8uCiAgICAgICAgICovCiAgICAgICAgSXRlbSBjb2VyY2UoaW50IHRhcmdldGNvZGUpIHsKICAgICAgICAgICAgaWYgKHR5cGVjb2RlID09IHRhcmdldGNvZGUpCiAgICAgICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICBsb2FkKCk7CiAgICAgICAgICAgICAgICBpbnQgdHlwZWNvZGUxID0gQ29kZS50cnVuY2F0ZSh0eXBlY29kZSk7CiAgICAgICAgICAgICAgICBpbnQgdGFyZ2V0Y29kZTEgPSBDb2RlLnRydW5jYXRlKHRhcmdldGNvZGUpOwogICAgICAgICAgICAgICAgaWYgKHR5cGVjb2RlMSAhPSB0YXJnZXRjb2RlMSkgewogICAgICAgICAgICAgICAgICAgIGludCBvZmZzZXQgPSB0YXJnZXRjb2RlMSA+IHR5cGVjb2RlMSA/IHRhcmdldGNvZGUxIC0gMQogICAgICAgICAgICAgICAgICAgICAgICA6IHRhcmdldGNvZGUxOwogICAgICAgICAgICAgICAgICAgIGNvZGUuZW1pdG9wMChpMmwgKyB0eXBlY29kZTEgKiAzICsgb2Zmc2V0KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICh0YXJnZXRjb2RlICE9IHRhcmdldGNvZGUxKSB7CiAgICAgICAgICAgICAgICAgICAgY29kZS5lbWl0b3AwKGludDJieXRlICsgdGFyZ2V0Y29kZSAtIEJZVEVjb2RlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBzdGFja0l0ZW1bdGFyZ2V0Y29kZV07CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8qKiBHZW5lcmF0ZSBjb2RlIHRvIGNvZXJjZSBpdGVtIHRvIGdpdmVuIHR5cGUuCiAgICAgICAgICogIEBwYXJhbSB0YXJnZXR0eXBlICAgIFRoZSB0eXBlIHRvIGNvZXJjZSB0by4KICAgICAgICAgKi8KICAgICAgICBJdGVtIGNvZXJjZShUeXBlIHRhcmdldHR5cGUpIHsKICAgICAgICAgICAgcmV0dXJuIGNvZXJjZShDb2RlLnR5cGVjb2RlKHRhcmdldHR5cGUpKTsKICAgICAgICB9CgogICAgICAgIC8qKiBSZXR1cm4gdGhlIHdpZHRoIG9mIHRoaXMgaXRlbSBvbiBzdGFjayBhcyBhIG51bWJlciBvZiB3b3Jkcy4KICAgICAgICAgKi8KICAgICAgICBpbnQgd2lkdGgoKSB7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIGFic3RyYWN0IFN0cmluZyB0b1N0cmluZygpOwogICAgfQoKICAgIC8qKiBBbiBpdGVtIHJlcHJlc2VudGluZyBhIHZhbHVlIG9uIHN0YWNrLgogICAgICovCiAgICBjbGFzcyBTdGFja0l0ZW0gZXh0ZW5kcyBJdGVtIHsKCiAgICAgICAgU3RhY2tJdGVtKGludCB0eXBlY29kZSkgewogICAgICAgICAgICBzdXBlcih0eXBlY29kZSk7CiAgICAgICAgfQoKICAgICAgICBJdGVtIGxvYWQoKSB7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgdm9pZCBkdXBsaWNhdGUoKSB7CiAgICAgICAgICAgIGNvZGUuZW1pdG9wMCh3aWR0aCgpID09IDIgPyBkdXAyIDogZHVwKTsKICAgICAgICB9CgogICAgICAgIHZvaWQgZHJvcCgpIHsKICAgICAgICAgICAgY29kZS5lbWl0b3AwKHdpZHRoKCkgPT0gMiA/IHBvcDIgOiBwb3ApOwogICAgICAgIH0KCiAgICAgICAgdm9pZCBzdGFzaChpbnQgdG9zY29kZSkgewogICAgICAgICAgICBjb2RlLmVtaXRvcDAoCiAgICAgICAgICAgICAgICAod2lkdGgoKSA9PSAyID8gZHVwX3gyIDogZHVwX3gxKSArIDMgKiAoQ29kZS53aWR0aCh0b3Njb2RlKSAtIDEpKTsKICAgICAgICB9CgogICAgICAgIGludCB3aWR0aCgpIHsKICAgICAgICAgICAgcmV0dXJuIENvZGUud2lkdGgodHlwZWNvZGUpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKICAgICAgICAgICAgcmV0dXJuICJzdGFjaygiICsgdHlwZWNvZGVOYW1lc1t0eXBlY29kZV0gKyAiKSI7CiAgICAgICAgfQogICAgfQoKICAgIC8qKiBBbiBpdGVtIHJlcHJlc2VudGluZyBhbiBpbmRleGVkIGV4cHJlc3Npb24uCiAgICAgKi8KICAgIGNsYXNzIEluZGV4ZWRJdGVtIGV4dGVuZHMgSXRlbSB7CgogICAgICAgIEluZGV4ZWRJdGVtKFR5cGUgdHlwZSkgewogICAgICAgICAgICBzdXBlcihDb2RlLnR5cGVjb2RlKHR5cGUpKTsKICAgICAgICB9CgogICAgICAgIEl0ZW0gbG9hZCgpIHsKICAgICAgICAgICAgY29kZS5lbWl0b3AwKGlhbG9hZCArIHR5cGVjb2RlKTsKICAgICAgICAgICAgcmV0dXJuIHN0YWNrSXRlbVt0eXBlY29kZV07CiAgICAgICAgfQoKICAgICAgICB2b2lkIHN0b3JlKCkgewogICAgICAgICAgICBjb2RlLmVtaXRvcDAoaWFzdG9yZSArIHR5cGVjb2RlKTsKICAgICAgICB9CgogICAgICAgIHZvaWQgZHVwbGljYXRlKCkgewogICAgICAgICAgICBjb2RlLmVtaXRvcDAoZHVwMik7CiAgICAgICAgfQoKICAgICAgICB2b2lkIGRyb3AoKSB7CiAgICAgICAgICAgIGNvZGUuZW1pdG9wMChwb3AyKTsKICAgICAgICB9CgogICAgICAgIHZvaWQgc3Rhc2goaW50IHRvc2NvZGUpIHsKICAgICAgICAgICAgY29kZS5lbWl0b3AwKGR1cF94MiArIDMgKiAoQ29kZS53aWR0aCh0b3Njb2RlKSAtIDEpKTsKICAgICAgICB9CgogICAgICAgIGludCB3aWR0aCgpIHsKICAgICAgICAgICAgcmV0dXJuIDI7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewogICAgICAgICAgICByZXR1cm4gImluZGV4ZWQoIiArIEJ5dGVDb2Rlcy50eXBlY29kZU5hbWVzW3R5cGVjb2RlXSArICIpIjsKICAgICAgICB9CiAgICB9CgogICAgLyoqIEFuIGl0ZW0gcmVwcmVzZW50aW5nIGB0aGlzJyBvciBgc3VwZXInLgogICAgICovCiAgICBjbGFzcyBTZWxmSXRlbSBleHRlbmRzIEl0ZW0gewoKICAgICAgICAvKiogRmxhZyB3aGljaCBkZXRlcm1pbmVzIHdoZXRoZXIgdGhpcyBpdGVtIHJlcHJlc2VudHMgYHRoaXMnIG9yIGBzdXBlcicuCiAgICAgICAgICovCiAgICAgICAgYm9vbGVhbiBpc1N1cGVyOwoKICAgICAgICBTZWxmSXRlbShib29sZWFuIGlzU3VwZXIpIHsKICAgICAgICAgICAgc3VwZXIoT0JKRUNUY29kZSk7CiAgICAgICAgICAgIHRoaXMuaXNTdXBlciA9IGlzU3VwZXI7CiAgICAgICAgfQoKICAgICAgICBJdGVtIGxvYWQoKSB7CiAgICAgICAgICAgIGNvZGUuZW1pdG9wMChhbG9hZF8wKTsKICAgICAgICAgICAgcmV0dXJuIHN0YWNrSXRlbVt0eXBlY29kZV07CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewogICAgICAgICAgICByZXR1cm4gaXNTdXBlciA/ICJzdXBlciIgOiAidGhpcyI7CiAgICAgICAgfQogICAgfQoKICAgIC8qKiBBbiBpdGVtIHJlcHJlc2VudGluZyBhIGxvY2FsIHZhcmlhYmxlLgogICAgICovCiAgICBjbGFzcyBMb2NhbEl0ZW0gZXh0ZW5kcyBJdGVtIHsKCiAgICAgICAgLyoqIFRoZSB2YXJpYWJsZSdzIHJlZ2lzdGVyLgogICAgICAgICAqLwogICAgICAgIGludCByZWc7CgogICAgICAgIC8qKiBUaGUgdmFyaWFibGUncyB0eXBlLgogICAgICAgICAqLwogICAgICAgIFR5cGUgdHlwZTsKCiAgICAgICAgTG9jYWxJdGVtKFR5cGUgdHlwZSwgaW50IHJlZykgewogICAgICAgICAgICBzdXBlcihDb2RlLnR5cGVjb2RlKHR5cGUpKTsKICAgICAgICAgICAgQXNzZXJ0LmNoZWNrKHJlZyA+PSAwKTsKICAgICAgICAgICAgdGhpcy50eXBlID0gdHlwZTsKICAgICAgICAgICAgdGhpcy5yZWcgPSByZWc7CiAgICAgICAgfQoKICAgICAgICBJdGVtIGxvYWQoKSB7CiAgICAgICAgICAgIGlmIChyZWcgPD0gMykKICAgICAgICAgICAgICAgIGNvZGUuZW1pdG9wMChpbG9hZF8wICsgQ29kZS50cnVuY2F0ZSh0eXBlY29kZSkgKiA0ICsgcmVnKTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgY29kZS5lbWl0b3AxdyhpbG9hZCArIENvZGUudHJ1bmNhdGUodHlwZWNvZGUpLCByZWcpOwogICAgICAgICAgICByZXR1cm4gc3RhY2tJdGVtW3R5cGVjb2RlXTsKICAgICAgICB9CgogICAgICAgIHZvaWQgc3RvcmUoKSB7CiAgICAgICAgICAgIGlmIChyZWcgPD0gMykKICAgICAgICAgICAgICAgIGNvZGUuZW1pdG9wMChpc3RvcmVfMCArIENvZGUudHJ1bmNhdGUodHlwZWNvZGUpICogNCArIHJlZyk7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIGNvZGUuZW1pdG9wMXcoaXN0b3JlICsgQ29kZS50cnVuY2F0ZSh0eXBlY29kZSksIHJlZyk7CiAgICAgICAgICAgIGNvZGUuc2V0RGVmaW5lZChyZWcpOwogICAgICAgIH0KCiAgICAgICAgdm9pZCBpbmNyKGludCB4KSB7CiAgICAgICAgICAgIGlmICh0eXBlY29kZSA9PSBJTlRjb2RlICYmIHggPj0gLTMyNzY4ICYmIHggPD0gMzI3NjcpIHsKICAgICAgICAgICAgICAgIGNvZGUuZW1pdG9wMXcoaWluYywgcmVnLCB4KTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGxvYWQoKTsKICAgICAgICAgICAgICAgIGlmICh4ID49IDApIHsKICAgICAgICAgICAgICAgICAgICBtYWtlSW1tZWRpYXRlSXRlbShzeW1zLmludFR5cGUsIHgpLmxvYWQoKTsKICAgICAgICAgICAgICAgICAgICBjb2RlLmVtaXRvcDAoaWFkZCk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIG1ha2VJbW1lZGlhdGVJdGVtKHN5bXMuaW50VHlwZSwgLXgpLmxvYWQoKTsKICAgICAgICAgICAgICAgICAgICBjb2RlLmVtaXRvcDAoaXN1Yik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBtYWtlU3RhY2tJdGVtKHN5bXMuaW50VHlwZSkuY29lcmNlKHR5cGVjb2RlKTsKICAgICAgICAgICAgICAgIHN0b3JlKCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CiAgICAgICAgICAgIHJldHVybiAibG9jYWxJdGVtKHR5cGU9IiArIHR5cGUgKyAiOyByZWc9IiArIHJlZyArICIpIjsKICAgICAgICB9CiAgICB9CgogICAgLyoqIEFuIGl0ZW0gcmVwcmVzZW50aW5nIGEgc3RhdGljIHZhcmlhYmxlIG9yIG1ldGhvZC4KICAgICAqLwogICAgY2xhc3MgU3RhdGljSXRlbSBleHRlbmRzIEl0ZW0gewoKICAgICAgICAvKiogVGhlIHJlcHJlc2VudGVkIHN5bWJvbC4KICAgICAgICAgKi8KICAgICAgICBTeW1ib2wgbWVtYmVyOwoKICAgICAgICBTdGF0aWNJdGVtKFN5bWJvbCBtZW1iZXIpIHsKICAgICAgICAgICAgc3VwZXIoQ29kZS50eXBlY29kZShtZW1iZXIuZXJhc3VyZSh0eXBlcykpKTsKICAgICAgICAgICAgdGhpcy5tZW1iZXIgPSBtZW1iZXI7CiAgICAgICAgfQoKICAgICAgICBJdGVtIGxvYWQoKSB7CiAgICAgICAgICAgIGNvZGUuZW1pdG9wMihnZXRzdGF0aWMsIHBvb2wucHV0KG1lbWJlcikpOwogICAgICAgICAgICByZXR1cm4gc3RhY2tJdGVtW3R5cGVjb2RlXTsKICAgICAgICB9CgogICAgICAgIHZvaWQgc3RvcmUoKSB7CiAgICAgICAgICAgIGNvZGUuZW1pdG9wMihwdXRzdGF0aWMsIHBvb2wucHV0KG1lbWJlcikpOwogICAgICAgIH0KCiAgICAgICAgSXRlbSBpbnZva2UoKSB7CiAgICAgICAgICAgIE1ldGhvZFR5cGUgbXR5cGUgPSAoTWV0aG9kVHlwZSltZW1iZXIuZXJhc3VyZSh0eXBlcyk7CiAgICAgICAgICAgIGludCByZXNjb2RlID0gQ29kZS50eXBlY29kZShtdHlwZS5yZXN0eXBlKTsKICAgICAgICAgICAgY29kZS5lbWl0SW52b2tlc3RhdGljKHBvb2wucHV0KG1lbWJlciksIG10eXBlKTsKICAgICAgICAgICAgcmV0dXJuIHN0YWNrSXRlbVtyZXNjb2RlXTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CiAgICAgICAgICAgIHJldHVybiAic3RhdGljKCIgKyBtZW1iZXIgKyAiKSI7CiAgICAgICAgfQogICAgfQoKICAgIC8qKiBBbiBpdGVtIHJlcHJlc2VudGluZyBhIGR5bmFtaWMgY2FsbCBzaXRlLgogICAgICovCiAgICBjbGFzcyBEeW5hbWljSXRlbSBleHRlbmRzIFN0YXRpY0l0ZW0gewogICAgICAgIER5bmFtaWNJdGVtKFN5bWJvbCBtZW1iZXIpIHsKICAgICAgICAgICAgc3VwZXIobWVtYmVyKTsKICAgICAgICB9CgogICAgICAgIEl0ZW0gbG9hZCgpIHsKICAgICAgICAgICAgYXNzZXJ0IGZhbHNlOwogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgIHZvaWQgc3RvcmUoKSB7CiAgICAgICAgICAgIGFzc2VydCBmYWxzZTsKICAgICAgICB9CgogICAgICAgIEl0ZW0gaW52b2tlKCkgewogICAgICAgICAgICAvLyBhc3NlcnQgdGFyZ2V0Lmhhc05hdGl2ZUludm9rZUR5bmFtaWMoKTsKICAgICAgICAgICAgTWV0aG9kVHlwZSBtdHlwZSA9IChNZXRob2RUeXBlKW1lbWJlci5lcmFzdXJlKHR5cGVzKTsKICAgICAgICAgICAgaW50IHJlc2NvZGUgPSBDb2RlLnR5cGVjb2RlKG10eXBlLnJlc3R5cGUpOwogICAgICAgICAgICBjb2RlLmVtaXRJbnZva2VkeW5hbWljKHBvb2wucHV0KG1lbWJlciksIG10eXBlKTsKICAgICAgICAgICAgcmV0dXJuIHN0YWNrSXRlbVtyZXNjb2RlXTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CiAgICAgICAgICAgIHJldHVybiAiZHluYW1pYygiICsgbWVtYmVyICsgIikiOwogICAgICAgIH0KICAgIH0KCiAgICAvKiogQW4gaXRlbSByZXByZXNlbnRpbmcgYW4gaW5zdGFuY2UgdmFyaWFibGUgb3IgbWV0aG9kLgogICAgICovCiAgICBjbGFzcyBNZW1iZXJJdGVtIGV4dGVuZHMgSXRlbSB7CgogICAgICAgIC8qKiBUaGUgcmVwcmVzZW50ZWQgc3ltYm9sLgogICAgICAgICAqLwogICAgICAgIFN5bWJvbCBtZW1iZXI7CgogICAgICAgIC8qKiBGbGFnIHRoYXQgZGV0ZXJtaW5lcyB3aGV0aGVyIG9yIG5vdCBhY2Nlc3MgaXMgdmlydHVhbC4KICAgICAgICAgKi8KICAgICAgICBib29sZWFuIG5vbnZpcnR1YWw7CgogICAgICAgIE1lbWJlckl0ZW0oU3ltYm9sIG1lbWJlciwgYm9vbGVhbiBub252aXJ0dWFsKSB7CiAgICAgICAgICAgIHN1cGVyKENvZGUudHlwZWNvZGUobWVtYmVyLmVyYXN1cmUodHlwZXMpKSk7CiAgICAgICAgICAgIHRoaXMubWVtYmVyID0gbWVtYmVyOwogICAgICAgICAgICB0aGlzLm5vbnZpcnR1YWwgPSBub252aXJ0dWFsOwogICAgICAgIH0KCiAgICAgICAgSXRlbSBsb2FkKCkgewogICAgICAgICAgICBjb2RlLmVtaXRvcDIoZ2V0ZmllbGQsIHBvb2wucHV0KG1lbWJlcikpOwogICAgICAgICAgICByZXR1cm4gc3RhY2tJdGVtW3R5cGVjb2RlXTsKICAgICAgICB9CgogICAgICAgIHZvaWQgc3RvcmUoKSB7CiAgICAgICAgICAgIGNvZGUuZW1pdG9wMihwdXRmaWVsZCwgcG9vbC5wdXQobWVtYmVyKSk7CiAgICAgICAgfQoKICAgICAgICBJdGVtIGludm9rZSgpIHsKICAgICAgICAgICAgTWV0aG9kVHlwZSBtdHlwZSA9IChNZXRob2RUeXBlKW1lbWJlci5leHRlcm5hbFR5cGUodHlwZXMpOwogICAgICAgICAgICBpbnQgcmVzY29kZSA9IENvZGUudHlwZWNvZGUobXR5cGUucmVzdHlwZSk7CiAgICAgICAgICAgIGlmICgobWVtYmVyLm93bmVyLmZsYWdzKCkgJiBGbGFncy5JTlRFUkZBQ0UpICE9IDAgJiYgIW5vbnZpcnR1YWwpIHsKICAgICAgICAgICAgICAgIGNvZGUuZW1pdEludm9rZWludGVyZmFjZShwb29sLnB1dChtZW1iZXIpLCBtdHlwZSk7CiAgICAgICAgICAgIH0gZWxzZSBpZiAobm9udmlydHVhbCkgewogICAgICAgICAgICAgICAgY29kZS5lbWl0SW52b2tlc3BlY2lhbChwb29sLnB1dChtZW1iZXIpLCBtdHlwZSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBjb2RlLmVtaXRJbnZva2V2aXJ0dWFsKHBvb2wucHV0KG1lbWJlciksIG10eXBlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gc3RhY2tJdGVtW3Jlc2NvZGVdOwogICAgICAgIH0KCiAgICAgICAgdm9pZCBkdXBsaWNhdGUoKSB7CiAgICAgICAgICAgIHN0YWNrSXRlbVtPQkpFQ1Rjb2RlXS5kdXBsaWNhdGUoKTsKICAgICAgICB9CgogICAgICAgIHZvaWQgZHJvcCgpIHsKICAgICAgICAgICAgc3RhY2tJdGVtW09CSkVDVGNvZGVdLmRyb3AoKTsKICAgICAgICB9CgogICAgICAgIHZvaWQgc3Rhc2goaW50IHRvc2NvZGUpIHsKICAgICAgICAgICAgc3RhY2tJdGVtW09CSkVDVGNvZGVdLnN0YXNoKHRvc2NvZGUpOwogICAgICAgIH0KCiAgICAgICAgaW50IHdpZHRoKCkgewogICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CiAgICAgICAgICAgIHJldHVybiAibWVtYmVyKCIgKyBtZW1iZXIgKyAobm9udmlydHVhbCA/ICIgbm9udmlydHVhbCkiIDogIikiKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqIEFuIGl0ZW0gcmVwcmVzZW50aW5nIGEgbGl0ZXJhbC4KICAgICAqLwogICAgY2xhc3MgSW1tZWRpYXRlSXRlbSBleHRlbmRzIEl0ZW0gewoKICAgICAgICAvKiogVGhlIGxpdGVyYWwncyB2YWx1ZS4KICAgICAgICAgKi8KICAgICAgICBPYmplY3QgdmFsdWU7CgogICAgICAgIEltbWVkaWF0ZUl0ZW0oVHlwZSB0eXBlLCBPYmplY3QgdmFsdWUpIHsKICAgICAgICAgICAgc3VwZXIoQ29kZS50eXBlY29kZSh0eXBlKSk7CiAgICAgICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgdm9pZCBsZGMoKSB7CiAgICAgICAgICAgIGludCBpZHggPSBwb29sLnB1dCh2YWx1ZSk7CiAgICAgICAgICAgIGlmICh0eXBlY29kZSA9PSBMT05HY29kZSB8fCB0eXBlY29kZSA9PSBET1VCTEVjb2RlKSB7CiAgICAgICAgICAgICAgICBjb2RlLmVtaXRvcDIobGRjMncsIGlkeCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBjb2RlLmVtaXRMZGMoaWR4KTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgSXRlbSBsb2FkKCkgewogICAgICAgICAgICBzd2l0Y2ggKHR5cGVjb2RlKSB7CiAgICAgICAgICAgIGNhc2UgSU5UY29kZTogY2FzZSBCWVRFY29kZTogY2FzZSBTSE9SVGNvZGU6IGNhc2UgQ0hBUmNvZGU6CiAgICAgICAgICAgICAgICBpbnQgaXZhbCA9ICgoTnVtYmVyKXZhbHVlKS5pbnRWYWx1ZSgpOwogICAgICAgICAgICAgICAgaWYgKC0xIDw9IGl2YWwgJiYgaXZhbCA8PSA1KQogICAgICAgICAgICAgICAgICAgIGNvZGUuZW1pdG9wMChpY29uc3RfMCArIGl2YWwpOwogICAgICAgICAgICAgICAgZWxzZSBpZiAoQnl0ZS5NSU5fVkFMVUUgPD0gaXZhbCAmJiBpdmFsIDw9IEJ5dGUuTUFYX1ZBTFVFKQogICAgICAgICAgICAgICAgICAgIGNvZGUuZW1pdG9wMShiaXB1c2gsIGl2YWwpOwogICAgICAgICAgICAgICAgZWxzZSBpZiAoU2hvcnQuTUlOX1ZBTFVFIDw9IGl2YWwgJiYgaXZhbCA8PSBTaG9ydC5NQVhfVkFMVUUpCiAgICAgICAgICAgICAgICAgICAgY29kZS5lbWl0b3AyKHNpcHVzaCwgaXZhbCk7CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgbGRjKCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBMT05HY29kZToKICAgICAgICAgICAgICAgIGxvbmcgbHZhbCA9ICgoTnVtYmVyKXZhbHVlKS5sb25nVmFsdWUoKTsKICAgICAgICAgICAgICAgIGlmIChsdmFsID09IDAgfHwgbHZhbCA9PSAxKQogICAgICAgICAgICAgICAgICAgIGNvZGUuZW1pdG9wMChsY29uc3RfMCArIChpbnQpbHZhbCk7CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgbGRjKCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBGTE9BVGNvZGU6CiAgICAgICAgICAgICAgICBmbG9hdCBmdmFsID0gKChOdW1iZXIpdmFsdWUpLmZsb2F0VmFsdWUoKTsKICAgICAgICAgICAgICAgIGlmIChpc1Bvc1plcm8oZnZhbCkgfHwgZnZhbCA9PSAxLjAgfHwgZnZhbCA9PSAyLjApCiAgICAgICAgICAgICAgICAgICAgY29kZS5lbWl0b3AwKGZjb25zdF8wICsgKGludClmdmFsKTsKICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgIGxkYygpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgRE9VQkxFY29kZToKICAgICAgICAgICAgICAgIGRvdWJsZSBkdmFsID0gKChOdW1iZXIpdmFsdWUpLmRvdWJsZVZhbHVlKCk7CiAgICAgICAgICAgICAgICBpZiAoaXNQb3NaZXJvKGR2YWwpIHx8IGR2YWwgPT0gMS4wKQogICAgICAgICAgICAgICAgICAgIGNvZGUuZW1pdG9wMChkY29uc3RfMCArIChpbnQpZHZhbCk7CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgbGRjKCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBPQkpFQ1Rjb2RlOgogICAgICAgICAgICAgICAgbGRjKCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIEFzc2VydC5lcnJvcigpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBzdGFja0l0ZW1bdHlwZWNvZGVdOwogICAgICAgIH0KICAgICAgICAvL3doZXJlCiAgICAgICAgICAgIC8qKiBSZXR1cm4gdHJ1ZSBpZmYgZmxvYXQgbnVtYmVyIGlzIHBvc2l0aXZlIDAuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBwcml2YXRlIGJvb2xlYW4gaXNQb3NaZXJvKGZsb2F0IHgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB4ID09IDAuMGYgJiYgMS4wZiAvIHggPiAwLjBmOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8qKiBSZXR1cm4gdHJ1ZSBpZmYgZG91YmxlIG51bWJlciBpcyBwb3NpdGl2ZSAwLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgcHJpdmF0ZSBib29sZWFuIGlzUG9zWmVybyhkb3VibGUgeCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHggPT0gMC4wZCAmJiAxLjBkIC8geCA+IDAuMGQ7CiAgICAgICAgICAgIH0KCiAgICAgICAgQ29uZEl0ZW0gbWtDb25kKCkgewogICAgICAgICAgICBpbnQgaXZhbCA9ICgoTnVtYmVyKXZhbHVlKS5pbnRWYWx1ZSgpOwogICAgICAgICAgICByZXR1cm4gbWFrZUNvbmRJdGVtKGl2YWwgIT0gMCA/IGdvdG9fIDogZG9udGdvdG8pOwogICAgICAgIH0KCiAgICAgICAgSXRlbSBjb2VyY2UoaW50IHRhcmdldGNvZGUpIHsKICAgICAgICAgICAgaWYgKHR5cGVjb2RlID09IHRhcmdldGNvZGUpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgc3dpdGNoICh0YXJnZXRjb2RlKSB7CiAgICAgICAgICAgICAgICBjYXNlIElOVGNvZGU6CiAgICAgICAgICAgICAgICAgICAgaWYgKENvZGUudHJ1bmNhdGUodHlwZWNvZGUpID09IElOVGNvZGUpCiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBJbW1lZGlhdGVJdGVtKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ltcy5pbnRUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKChOdW1iZXIpdmFsdWUpLmludFZhbHVlKCkpOwogICAgICAgICAgICAgICAgY2FzZSBMT05HY29kZToKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEltbWVkaWF0ZUl0ZW0oCiAgICAgICAgICAgICAgICAgICAgICAgIHN5bXMubG9uZ1R5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICgoTnVtYmVyKXZhbHVlKS5sb25nVmFsdWUoKSk7CiAgICAgICAgICAgICAgICBjYXNlIEZMT0FUY29kZToKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEltbWVkaWF0ZUl0ZW0oCiAgICAgICAgICAgICAgICAgICAgICAgIHN5bXMuZmxvYXRUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAoKE51bWJlcil2YWx1ZSkuZmxvYXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGNhc2UgRE9VQkxFY29kZToKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEltbWVkaWF0ZUl0ZW0oCiAgICAgICAgICAgICAgICAgICAgICAgIHN5bXMuZG91YmxlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgKChOdW1iZXIpdmFsdWUpLmRvdWJsZVZhbHVlKCkpOwogICAgICAgICAgICAgICAgY2FzZSBCWVRFY29kZToKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEltbWVkaWF0ZUl0ZW0oCiAgICAgICAgICAgICAgICAgICAgICAgIHN5bXMuYnl0ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgIChpbnQpKGJ5dGUpKChOdW1iZXIpdmFsdWUpLmludFZhbHVlKCkpOwogICAgICAgICAgICAgICAgY2FzZSBDSEFSY29kZToKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEltbWVkaWF0ZUl0ZW0oCiAgICAgICAgICAgICAgICAgICAgICAgIHN5bXMuY2hhclR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgIChpbnQpKGNoYXIpKChOdW1iZXIpdmFsdWUpLmludFZhbHVlKCkpOwogICAgICAgICAgICAgICAgY2FzZSBTSE9SVGNvZGU6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBJbW1lZGlhdGVJdGVtKAogICAgICAgICAgICAgICAgICAgICAgICBzeW1zLnNob3J0VHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgKGludCkoc2hvcnQpKChOdW1iZXIpdmFsdWUpLmludFZhbHVlKCkpOwogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3VwZXIuY29lcmNlKHRhcmdldGNvZGUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewogICAgICAgICAgICByZXR1cm4gImltbWVkaWF0ZSgiICsgdmFsdWUgKyAiKSI7CiAgICAgICAgfQogICAgfQoKICAgIC8qKiBBbiBpdGVtIHJlcHJlc2VudGluZyBhbiBhc3NpZ25tZW50IGV4cHJlc3Npb25zLgogICAgICovCiAgICBjbGFzcyBBc3NpZ25JdGVtIGV4dGVuZHMgSXRlbSB7CgogICAgICAgIC8qKiBUaGUgaXRlbSByZXByZXNlbnRpbmcgdGhlIGFzc2lnbm1lbnQncyBsZWZ0IGhhbmQgc2lkZS4KICAgICAgICAgKi8KICAgICAgICBJdGVtIGxoczsKCiAgICAgICAgQXNzaWduSXRlbShJdGVtIGxocykgewogICAgICAgICAgICBzdXBlcihsaHMudHlwZWNvZGUpOwogICAgICAgICAgICB0aGlzLmxocyA9IGxoczsKICAgICAgICB9CgogICAgICAgIEl0ZW0gbG9hZCgpIHsKICAgICAgICAgICAgbGhzLnN0YXNoKHR5cGVjb2RlKTsKICAgICAgICAgICAgbGhzLnN0b3JlKCk7CiAgICAgICAgICAgIHJldHVybiBzdGFja0l0ZW1bdHlwZWNvZGVdOwogICAgICAgIH0KCiAgICAgICAgdm9pZCBkdXBsaWNhdGUoKSB7CiAgICAgICAgICAgIGxvYWQoKS5kdXBsaWNhdGUoKTsKICAgICAgICB9CgogICAgICAgIHZvaWQgZHJvcCgpIHsKICAgICAgICAgICAgbGhzLnN0b3JlKCk7CiAgICAgICAgfQoKICAgICAgICB2b2lkIHN0YXNoKGludCB0b3Njb2RlKSB7CiAgICAgICAgICAgIEFzc2VydC5lcnJvcigpOwogICAgICAgIH0KCiAgICAgICAgaW50IHdpZHRoKCkgewogICAgICAgICAgICByZXR1cm4gbGhzLndpZHRoKCkgKyBDb2RlLndpZHRoKHR5cGVjb2RlKTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CiAgICAgICAgICAgIHJldHVybiAiYXNzaWduKGxocyA9ICIgKyBsaHMgKyAiKSI7CiAgICAgICAgfQogICAgfQoKICAgIC8qKiBBbiBpdGVtIHJlcHJlc2VudGluZyBhIGNvbmRpdGlvbmFsIG9yIHVuY29uZGl0aW9uYWwganVtcC4KICAgICAqLwogICAgY2xhc3MgQ29uZEl0ZW0gZXh0ZW5kcyBJdGVtIHsKCiAgICAgICAgLyoqIEEgY2hhaW4gZW5jb21hc3NpbmcgYWxsIGp1bXBzIHRoYXQgY2FuIGJlIHRha2VuCiAgICAgICAgICogIGlmIHRoZSBjb25kaXRpb24gZXZhbHVhdGVzIHRvIHRydWUuCiAgICAgICAgICovCiAgICAgICAgQ2hhaW4gdHJ1ZUp1bXBzOwoKICAgICAgICAvKiogQSBjaGFpbiBlbmNvbWFzc2luZyBhbGwganVtcHMgdGhhdCBjYW4gYmUgdGFrZW4KICAgICAgICAgKiAgaWYgdGhlIGNvbmRpdGlvbiBldmFsdWF0ZXMgdG8gZmFsc2UuCiAgICAgICAgICovCiAgICAgICAgQ2hhaW4gZmFsc2VKdW1wczsKCiAgICAgICAgLyoqIFRoZSBqdW1wJ3Mgb3Bjb2RlLgogICAgICAgICAqLwogICAgICAgIGludCBvcGNvZGU7CgogICAgICAgIC8qCiAgICAgICAgICogIEFuIGFic3RyYWN0IHN5bnRheCB0cmVlIG9mIHRoaXMgaXRlbS4gSXQgaXMgbmVlZGVkCiAgICAgICAgICogIGZvciBicmFuY2ggZW50cmllcyBpbiAnQ2hhcmFjdGVyUmFuZ2VUYWJsZScgYXR0cmlidXRlLgogICAgICAgICAqLwogICAgICAgIEpDVHJlZSB0cmVlOwoKICAgICAgICBDb25kSXRlbShpbnQgb3Bjb2RlLCBDaGFpbiB0cnVlanVtcHMsIENoYWluIGZhbHNlanVtcHMpIHsKICAgICAgICAgICAgc3VwZXIoQllURWNvZGUpOwogICAgICAgICAgICB0aGlzLm9wY29kZSA9IG9wY29kZTsKICAgICAgICAgICAgdGhpcy50cnVlSnVtcHMgPSB0cnVlanVtcHM7CiAgICAgICAgICAgIHRoaXMuZmFsc2VKdW1wcyA9IGZhbHNlanVtcHM7CiAgICAgICAgfQoKICAgICAgICBJdGVtIGxvYWQoKSB7CiAgICAgICAgICAgIENoYWluIHRydWVDaGFpbiA9IG51bGw7CiAgICAgICAgICAgIENoYWluIGZhbHNlQ2hhaW4gPSBqdW1wRmFsc2UoKTsKICAgICAgICAgICAgaWYgKCFpc0ZhbHNlKCkpIHsKICAgICAgICAgICAgICAgIGNvZGUucmVzb2x2ZSh0cnVlSnVtcHMpOwogICAgICAgICAgICAgICAgY29kZS5lbWl0b3AwKGljb25zdF8xKTsKICAgICAgICAgICAgICAgIHRydWVDaGFpbiA9IGNvZGUuYnJhbmNoKGdvdG9fKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoZmFsc2VDaGFpbiAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICBjb2RlLnJlc29sdmUoZmFsc2VDaGFpbik7CiAgICAgICAgICAgICAgICBjb2RlLmVtaXRvcDAoaWNvbnN0XzApOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGNvZGUucmVzb2x2ZSh0cnVlQ2hhaW4pOwogICAgICAgICAgICByZXR1cm4gc3RhY2tJdGVtW3R5cGVjb2RlXTsKICAgICAgICB9CgogICAgICAgIHZvaWQgZHVwbGljYXRlKCkgewogICAgICAgICAgICBsb2FkKCkuZHVwbGljYXRlKCk7CiAgICAgICAgfQoKICAgICAgICB2b2lkIGRyb3AoKSB7CiAgICAgICAgICAgIGxvYWQoKS5kcm9wKCk7CiAgICAgICAgfQoKICAgICAgICB2b2lkIHN0YXNoKGludCB0b3Njb2RlKSB7CiAgICAgICAgICAgIEFzc2VydC5lcnJvcigpOwogICAgICAgIH0KCiAgICAgICAgQ29uZEl0ZW0gbWtDb25kKCkgewogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIENoYWluIGp1bXBUcnVlKCkgewogICAgICAgICAgICBpZiAodHJlZSA9PSBudWxsKSByZXR1cm4gQ29kZS5tZXJnZUNoYWlucyh0cnVlSnVtcHMsIGNvZGUuYnJhbmNoKG9wY29kZSkpOwogICAgICAgICAgICAvLyB3ZSBzaG91bGQgcHJvY2VlZCBmdXJ0aGVyIGluIC1YamNvdiBtb2RlIG9ubHkKICAgICAgICAgICAgaW50IHN0YXJ0cGMgPSBjb2RlLmN1ckNQKCk7CiAgICAgICAgICAgIENoYWluIGMgPSBDb2RlLm1lcmdlQ2hhaW5zKHRydWVKdW1wcywgY29kZS5icmFuY2gob3Bjb2RlKSk7CiAgICAgICAgICAgIGNvZGUuY3J0LnB1dCh0cmVlLCBDUlRhYmxlLkNSVF9CUkFOQ0hfVFJVRSwgc3RhcnRwYywgY29kZS5jdXJDUCgpKTsKICAgICAgICAgICAgcmV0dXJuIGM7CiAgICAgICAgfQoKICAgICAgICBDaGFpbiBqdW1wRmFsc2UoKSB7CiAgICAgICAgICAgIGlmICh0cmVlID09IG51bGwpIHJldHVybiBDb2RlLm1lcmdlQ2hhaW5zKGZhbHNlSnVtcHMsIGNvZGUuYnJhbmNoKENvZGUubmVnYXRlKG9wY29kZSkpKTsKICAgICAgICAgICAgLy8gd2Ugc2hvdWxkIHByb2NlZWQgZnVydGhlciBpbiAtWGpjb3YgbW9kZSBvbmx5CiAgICAgICAgICAgIGludCBzdGFydHBjID0gY29kZS5jdXJDUCgpOwogICAgICAgICAgICBDaGFpbiBjID0gQ29kZS5tZXJnZUNoYWlucyhmYWxzZUp1bXBzLCBjb2RlLmJyYW5jaChDb2RlLm5lZ2F0ZShvcGNvZGUpKSk7CiAgICAgICAgICAgIGNvZGUuY3J0LnB1dCh0cmVlLCBDUlRhYmxlLkNSVF9CUkFOQ0hfRkFMU0UsIHN0YXJ0cGMsIGNvZGUuY3VyQ1AoKSk7CiAgICAgICAgICAgIHJldHVybiBjOwogICAgICAgIH0KCiAgICAgICAgQ29uZEl0ZW0gbmVnYXRlKCkgewogICAgICAgICAgICBDb25kSXRlbSBjID0gbmV3IENvbmRJdGVtKENvZGUubmVnYXRlKG9wY29kZSksIGZhbHNlSnVtcHMsIHRydWVKdW1wcyk7CiAgICAgICAgICAgIGMudHJlZSA9IHRyZWU7CiAgICAgICAgICAgIHJldHVybiBjOwogICAgICAgIH0KCiAgICAgICAgaW50IHdpZHRoKCkgewogICAgICAgICAgICAvLyBhIENvbmRJdGVtIGRvZXNuJ3QgaGF2ZSBhIHNpemUgb24gdGhlIHN0YWNrIHBlciBzZS4KICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCk7CiAgICAgICAgfQoKICAgICAgICBib29sZWFuIGlzVHJ1ZSgpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlSnVtcHMgPT0gbnVsbCAmJiBvcGNvZGUgPT0gZ290b187CiAgICAgICAgfQoKICAgICAgICBib29sZWFuIGlzRmFsc2UoKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlSnVtcHMgPT0gbnVsbCAmJiBvcGNvZGUgPT0gZG9udGdvdG87CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewogICAgICAgICAgICByZXR1cm4gImNvbmQoIiArIENvZGUubW5lbShvcGNvZGUpICsgIikiOwogICAgICAgIH0KICAgIH0KfQpQSwMECgAACAAABjupSj9dAzroVQAA6FUAACQAAABjb20vc3VuL3Rvb2xzL2phdmFjL2p2bS9DUlRhYmxlLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDEsIDIwMTIsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5qYXZhYy5qdm07CgppbXBvcnQgamF2YS51dGlsLio7CgppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLio7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuKjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5MaXN0OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkpDVHJlZS4qOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy50cmVlLkVuZFBvc1RhYmxlOwoKLyoqIFRoaXMgY2xhc3MgY29udGFpbnMgdGhlIENoYXJhY3RlclJhbmdlVGFibGUgZm9yIHNvbWUgbWV0aG9kCiAqICBhbmQgdGhlIGhhc2h0YWJsZSBmb3IgbWFwcGluZyB0cmVlcyBvciBsaXN0cyBvZiB0cmVlcyB0byB0aGVpcgogKiAgZW5kaW5nIHBvc2l0aW9ucy4KICoKICogIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqICBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duIHJpc2suCiAqICBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZSBvcgogKiAgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPgogKi8KcHVibGljIGNsYXNzIENSVGFibGUKaW1wbGVtZW50cyBDUlRGbGFncyB7CgogICAgcHJpdmF0ZSBmaW5hbCBib29sZWFuIGNydERlYnVnID0gZmFsc2U7CgogICAgLyoqIFRoZSBsaXN0IG9mIENSVGFibGUgZW50cmllcy4KICAgICAqLwogICAgcHJpdmF0ZSBMaXN0QnVmZmVyPENSVEVudHJ5PiBlbnRyaWVzID0gbmV3IExpc3RCdWZmZXI8PigpOwoKICAgIC8qKiBUaGUgaGFzaHRhYmxlIGZvciBzb3VyY2UgcG9zaXRpb25zLgogICAgICovCiAgICBwcml2YXRlIE1hcDxPYmplY3QsU291cmNlUmFuZ2U+IHBvc2l0aW9ucyA9IG5ldyBIYXNoTWFwPD4oKTsKCiAgICAvKiogVGhlIG9iamVjdCBmb3IgZW5kaW5nIHBvc2l0aW9ucyBzdG9yZWQgaW4gdGhlIHBhcnNlci4KICAgICAqLwogICAgcHJpdmF0ZSBFbmRQb3NUYWJsZSBlbmRQb3NUYWJsZTsKCiAgICAvKiogVGhlIHRyZWUgb2YgdGhlIG1ldGhvZCB0aGlzIHRhYmxlIGlzIGludGVuZGVkIGZvci4KICAgICAqICBXZSBzaG91bGQgdHJhdmVyc2UgdGhpcyB0cmVlIHRvIGdldCBzb3VyY2UgcmFuZ2VzLgogICAgICovCiAgICBKQ1RyZWUuSkNNZXRob2REZWNsIG1ldGhvZFRyZWU7CgogICAgLyoqIENvbnN0cnVjdG9yCiAgICAgKi8KICAgIHB1YmxpYyBDUlRhYmxlKEpDVHJlZS5KQ01ldGhvZERlY2wgdHJlZSwgRW5kUG9zVGFibGUgZW5kUG9zVGFibGUpIHsKICAgICAgICB0aGlzLm1ldGhvZFRyZWUgPSB0cmVlOwogICAgICAgIHRoaXMuZW5kUG9zVGFibGUgPSBlbmRQb3NUYWJsZTsKICAgIH0KCiAgICAvKiogQ3JlYXRlIGEgbmV3IENSVEVudHJ5IGFuZCBhZGQgaXQgdG8gdGhlIGVudHJpZXMuCiAgICAgKiAgQHBhcmFtIHRyZWUgICAgIFRoZSB0cmVlIG9yIHRoZSBsaXN0IG9mIHRyZWVzIGZvciB3aGljaAogICAgICogICAgICAgICAgICAgICAgICB3ZSBhcmUgc3RvcmluZyB0aGUgY29kZSBwb2ludGVycy4KICAgICAqICBAcGFyYW0gZmxhZ3MgICAgVGhlIHNldCBvZiBmbGFncyBkZXNpZ25hdGluZyB0eXBlIG9mIHRoZSBlbnRyeS4KICAgICAqICBAcGFyYW0gc3RhcnRQYyAgVGhlIHN0YXJ0aW5nIGNvZGUgcG9zaXRpb24uCiAgICAgKiAgQHBhcmFtIGVuZFBjICAgIFRoZSBlbmRpbmcgY29kZSBwb3NpdGlvbi4KICAgICAqLwogICAgcHVibGljIHZvaWQgcHV0KE9iamVjdCB0cmVlLCBpbnQgZmxhZ3MsIGludCBzdGFydFBjLCBpbnQgZW5kUGMpIHsKICAgICAgICBlbnRyaWVzLmFwcGVuZChuZXcgQ1JURW50cnkodHJlZSwgZmxhZ3MsIHN0YXJ0UGMsIGVuZFBjKSk7CiAgICB9CgogICAgLyoqIENvbXB1dGUgc291cmNlIHBvc2l0aW9ucyBhbmQgd3JpdGUgQ1JUIHRvIHRoZSBkYXRhYnVmLgogICAgICogIEBwYXJhbSBkYXRhYnVmICBUaGUgYnVmZmVyIHRvIHdyaXRlIGJ5dGVjb2RlcyB0by4KICAgICAqLwogICAgcHVibGljIGludCB3cml0ZUNSVChCeXRlQnVmZmVyIGRhdGFidWYsIFBvc2l0aW9uLkxpbmVNYXAgbGluZU1hcCwgTG9nIGxvZykgewoKICAgICAgICBpbnQgY3J0RW50cmllcyA9IDA7CgogICAgICAgIC8vIGNvbXB1dGUgc291cmNlIHBvc2l0aW9ucyBmb3IgdGhlIG1ldGhvZAogICAgICAgIG5ldyBTb3VyY2VDb21wdXRlcigpLmNzcChtZXRob2RUcmVlKTsKCiAgICAgICAgZm9yIChMaXN0PENSVEVudHJ5PiBsID0gZW50cmllcy50b0xpc3QoKTsgbC5ub25FbXB0eSgpOyBsID0gbC50YWlsKSB7CgogICAgICAgICAgICBDUlRFbnRyeSBlbnRyeSA9IGwuaGVhZDsKCiAgICAgICAgICAgIC8vIGVsaW1pbmF0ZSBlbnRyaWVzIHRoYXQgZG8gbm90IHByb2R1Y2UgYnl0ZWNvZGVzOgogICAgICAgICAgICAvLyBmb3IgZXhhbXBsZSwgZW1wdHkgYmxvY2tzIGFuZCBzdGF0ZW1lbnRzCiAgICAgICAgICAgIGlmIChlbnRyeS5zdGFydFBjID09IGVudHJ5LmVuZFBjKQogICAgICAgICAgICAgICAgY29udGludWU7CgogICAgICAgICAgICBTb3VyY2VSYW5nZSBwb3MgPSBwb3NpdGlvbnMuZ2V0KGVudHJ5LnRyZWUpOwogICAgICAgICAgICBBc3NlcnQuY2hlY2tOb25OdWxsKHBvcywgIkNSVDogdHJlZSBzb3VyY2UgcG9zaXRpb25zIGFyZSB1bmRlZmluZWQiKTsKICAgICAgICAgICAgaWYgKChwb3Muc3RhcnRQb3MgPT0gUG9zaXRpb24uTk9QT1MpIHx8IChwb3MuZW5kUG9zID09IFBvc2l0aW9uLk5PUE9TKSkKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwoKICAgICAgICAgICAgaWYgKGNydERlYnVnKSB7CiAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlRyZWU6ICIgKyBlbnRyeS50cmVlICsgIiwgdHlwZToiICsgZ2V0VHlwZXMoZW50cnkuZmxhZ3MpKTsKICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIlN0YXJ0OiBwb3MgPSAiICsgcG9zLnN0YXJ0UG9zICsgIiwgcGMgPSAiICsgZW50cnkuc3RhcnRQYyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIGVuY29kZSBzdGFydFBvcyBpbnRvIGxpbmUvY29sdW1uIHJlcHJlc2VudGF0aW9uCiAgICAgICAgICAgIGludCBzdGFydFBvcyA9IGVuY29kZVBvc2l0aW9uKHBvcy5zdGFydFBvcywgbGluZU1hcCwgbG9nKTsKICAgICAgICAgICAgaWYgKHN0YXJ0UG9zID09IFBvc2l0aW9uLk5PUE9TKQogICAgICAgICAgICAgICAgY29udGludWU7CgogICAgICAgICAgICBpZiAoY3J0RGVidWcpIHsKICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnQoIkVuZDogICBwb3MgPSAiICsgcG9zLmVuZFBvcyArICIsIHBjID0gIiArIChlbnRyeS5lbmRQYyAtIDEpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gZW5jb2RlIGVuZFBvcyBpbnRvIGxpbmUvY29sdW1uIHJlcHJlc2VudGF0aW9uCiAgICAgICAgICAgIGludCBlbmRQb3MgPSBlbmNvZGVQb3NpdGlvbihwb3MuZW5kUG9zLCBsaW5lTWFwLCBsb2cpOwogICAgICAgICAgICBpZiAoZW5kUG9zID09IFBvc2l0aW9uLk5PUE9TKQogICAgICAgICAgICAgICAgY29udGludWU7CgogICAgICAgICAgICAvLyB3cml0ZSBhdHRyaWJ1dGUKICAgICAgICAgICAgZGF0YWJ1Zi5hcHBlbmRDaGFyKGVudHJ5LnN0YXJ0UGMpOwogICAgICAgICAgICAvLyAnZW5kUGMgLSAxJyBiZWNhdXNlIGVuZFBjIGFjdHVhbGx5IHBvaW50cyB0byBzdGFydCBvZiB0aGUgbmV4dCBjb21tYW5kCiAgICAgICAgICAgIGRhdGFidWYuYXBwZW5kQ2hhcihlbnRyeS5lbmRQYyAtIDEpOwogICAgICAgICAgICBkYXRhYnVmLmFwcGVuZEludChzdGFydFBvcyk7CiAgICAgICAgICAgIGRhdGFidWYuYXBwZW5kSW50KGVuZFBvcyk7CiAgICAgICAgICAgIGRhdGFidWYuYXBwZW5kQ2hhcihlbnRyeS5mbGFncyk7CgogICAgICAgICAgICBjcnRFbnRyaWVzKys7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gY3J0RW50cmllczsKICAgIH0KCiAgICAvKiogUmV0dXJuIHRoZSBudW1iZXIgb2YgdGhlIGVudHJpZXMuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgbGVuZ3RoKCkgewogICAgICAgIHJldHVybiBlbnRyaWVzLmxlbmd0aCgpOwogICAgfQoKICAgIC8qKiBSZXR1cm4gc3RyaW5nIGRlc2NyaWJpbmcgZmxhZ3MgZW5hYmxlZC4KICAgICAqLwogICAgcHJpdmF0ZSBTdHJpbmcgZ2V0VHlwZXMoaW50IGZsYWdzKSB7CiAgICAgICAgU3RyaW5nIHR5cGVzID0gIiI7CiAgICAgICAgaWYgKChmbGFncyAmIENSVF9TVEFURU1FTlQpICAgICAgICE9IDApIHR5cGVzICs9ICIgQ1JUX1NUQVRFTUVOVCI7CiAgICAgICAgaWYgKChmbGFncyAmIENSVF9CTE9DSykgICAgICAgICAgICE9IDApIHR5cGVzICs9ICIgQ1JUX0JMT0NLIjsKICAgICAgICBpZiAoKGZsYWdzICYgQ1JUX0FTU0lHTk1FTlQpICAgICAgIT0gMCkgdHlwZXMgKz0gIiBDUlRfQVNTSUdOTUVOVCI7CiAgICAgICAgaWYgKChmbGFncyAmIENSVF9GTE9XX0NPTlRST0xMRVIpICE9IDApIHR5cGVzICs9ICIgQ1JUX0ZMT1dfQ09OVFJPTExFUiI7CiAgICAgICAgaWYgKChmbGFncyAmIENSVF9GTE9XX1RBUkdFVCkgICAgICE9IDApIHR5cGVzICs9ICIgQ1JUX0ZMT1dfVEFSR0VUIjsKICAgICAgICBpZiAoKGZsYWdzICYgQ1JUX0lOVk9LRSkgICAgICAgICAgIT0gMCkgdHlwZXMgKz0gIiBDUlRfSU5WT0tFIjsKICAgICAgICBpZiAoKGZsYWdzICYgQ1JUX0NSRUFURSkgICAgICAgICAgIT0gMCkgdHlwZXMgKz0gIiBDUlRfQ1JFQVRFIjsKICAgICAgICBpZiAoKGZsYWdzICYgQ1JUX0JSQU5DSF9UUlVFKSAgICAgIT0gMCkgdHlwZXMgKz0gIiBDUlRfQlJBTkNIX1RSVUUiOwogICAgICAgIGlmICgoZmxhZ3MgJiBDUlRfQlJBTkNIX0ZBTFNFKSAgICAhPSAwKSB0eXBlcyArPSAiIENSVF9CUkFOQ0hfRkFMU0UiOwogICAgICAgIHJldHVybiB0eXBlczsKICAgIH0KCiAgICAvKiogU291cmNlIGZpbGUgcG9zaXRpb25zIGluIENSVCBhcmUgaW50ZWdlcnMgaW4gdGhlIGZvcm1hdDoKICAgICAqICB7QGxpdGVyYWwgbGluZS1udW1iZXIgPDwgTElORVNISUZUICsgY29sdW1uLW51bWJlciB9CiAgICAgKi8KICAgICBwcml2YXRlIGludCBlbmNvZGVQb3NpdGlvbihpbnQgcG9zLCBQb3NpdGlvbi5MaW5lTWFwIGxpbmVNYXAsIExvZyBsb2cpIHsKICAgICAgICAgaW50IGxpbmUgPSBsaW5lTWFwLmdldExpbmVOdW1iZXIocG9zKTsKICAgICAgICAgaW50IGNvbCA9IGxpbmVNYXAuZ2V0Q29sdW1uTnVtYmVyKHBvcyk7CiAgICAgICAgIGludCBuZXdfcG9zID0gUG9zaXRpb24uZW5jb2RlUG9zaXRpb24obGluZSwgY29sKTsKICAgICAgICAgaWYgKGNydERlYnVnKSB7CiAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIiwgbGluZSA9ICIgKyBsaW5lICsgIiwgY29sdW1uID0gIiArIGNvbCArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiwgbmV3X3BvcyA9ICIgKyBuZXdfcG9zKTsKICAgICAgICAgfQogICAgICAgICBpZiAobmV3X3BvcyA9PSBQb3NpdGlvbi5OT1BPUykKICAgICAgICAgICAgIGxvZy53YXJuaW5nKHBvcywgInBvc2l0aW9uLm92ZXJmbG93IiwgbGluZSk7CgogICAgICAgIHJldHVybiBuZXdfcG9zOwogICAgIH0KCi8qICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBUcmF2ZXJzYWwgbWV0aG9kcwogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiAgICAvKioKICAgICAqICBUaGlzIGNsYXNzIGNvbnRhaW5zIG1ldGhvZHMgdG8gY29tcHV0ZSBzb3VyY2UgcG9zaXRpb25zIGZvciB0cmVlcy4KICAgICAqICBFeHRlbmRzIFRyZWUuVmlzaXRvciB0byB0cmF2ZXJzZSB0aGUgYWJzdHJhY3Qgc3ludGF4IHRyZWUuCiAgICAgKi8KICAgIGNsYXNzIFNvdXJjZUNvbXB1dGVyIGV4dGVuZHMgSkNUcmVlLlZpc2l0b3IgewoKICAgICAgICAvKiogVGhlIHJlc3VsdCBvZiB0aGUgdHJlZSB0cmF2ZXJzYWwgbWV0aG9kcy4KICAgICAgICAgKi8KICAgICAgICBTb3VyY2VSYW5nZSByZXN1bHQ7CgogICAgICAgIC8qKiBWaXNpdG9yIG1ldGhvZDogY29tcHV0ZSBzb3VyY2UgcG9zaXRpb25zIGZvciBhIHNpbmdsZSBub2RlLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBTb3VyY2VSYW5nZSBjc3AoSkNUcmVlIHRyZWUpIHsKICAgICAgICAgICAgaWYgKHRyZWUgPT0gbnVsbCkgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIHRyZWUuYWNjZXB0KHRoaXMpOwogICAgICAgICAgICBpZiAocmVzdWx0ICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIHBvc2l0aW9ucy5wdXQodHJlZSwgcmVzdWx0KTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgIH0KCiAgICAgICAgLyoqIFZpc2l0b3IgbWV0aG9kOiBjb21wdXRlIHNvdXJjZSBwb3NpdGlvbnMgZm9yIGEgbGlzdCBvZiBub2Rlcy4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgU291cmNlUmFuZ2UgY3NwKExpc3Q8PyBleHRlbmRzIEpDVHJlZT4gdHJlZXMpIHsKICAgICAgICAgICAgaWYgKCh0cmVlcyA9PSBudWxsKSB8fCAhKHRyZWVzLm5vbkVtcHR5KCkpKSByZXR1cm4gbnVsbDsKICAgICAgICAgICAgU291cmNlUmFuZ2UgbGlzdF9zciA9IG5ldyBTb3VyY2VSYW5nZSgpOwogICAgICAgICAgICBmb3IgKExpc3Q8PyBleHRlbmRzIEpDVHJlZT4gbCA9IHRyZWVzOyBsLm5vbkVtcHR5KCk7IGwgPSBsLnRhaWwpIHsKICAgICAgICAgICAgICAgIGxpc3Rfc3IubWVyZ2VXaXRoKGNzcChsLmhlYWQpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBwb3NpdGlvbnMucHV0KHRyZWVzLCBsaXN0X3NyKTsKICAgICAgICAgICAgcmV0dXJuIGxpc3Rfc3I7CiAgICAgICAgfQoKICAgICAgICAvKiogIFZpc2l0b3IgbWV0aG9kOiBjb21wdXRlIHNvdXJjZSBwb3NpdGlvbnMgZm9yCiAgICAgICAgICogICAgYSBsaXN0IG9mIGNhc2UgYmxvY2tzIG9mIHN3aXRjaCBzdGF0ZW1lbnRzLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBTb3VyY2VSYW5nZSBjc3BDYXNlcyhMaXN0PEpDQ2FzZT4gdHJlZXMpIHsKICAgICAgICAgICAgaWYgKCh0cmVlcyA9PSBudWxsKSB8fCAhKHRyZWVzLm5vbkVtcHR5KCkpKSByZXR1cm4gbnVsbDsKICAgICAgICAgICAgU291cmNlUmFuZ2UgbGlzdF9zciA9IG5ldyBTb3VyY2VSYW5nZSgpOwogICAgICAgICAgICBmb3IgKExpc3Q8SkNDYXNlPiBsID0gdHJlZXM7IGwubm9uRW1wdHkoKTsgbCA9IGwudGFpbCkgewogICAgICAgICAgICAgICAgbGlzdF9zci5tZXJnZVdpdGgoY3NwKGwuaGVhZCkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHBvc2l0aW9ucy5wdXQodHJlZXMsIGxpc3Rfc3IpOwogICAgICAgICAgICByZXR1cm4gbGlzdF9zcjsKICAgICAgICB9CgogICAgICAgIC8qKiAgVmlzaXRvciBtZXRob2Q6IGNvbXB1dGUgc291cmNlIHBvc2l0aW9ucyBmb3IKICAgICAgICAgKiAgIGEgbGlzdCBvZiBjYXRjaCBjbGF1c2VzIGluIHRyeSBzdGF0ZW1lbnRzLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBTb3VyY2VSYW5nZSBjc3BDYXRjaGVycyhMaXN0PEpDQ2F0Y2g+IHRyZWVzKSB7CiAgICAgICAgICAgIGlmICgodHJlZXMgPT0gbnVsbCkgfHwgISh0cmVlcy5ub25FbXB0eSgpKSkgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIFNvdXJjZVJhbmdlIGxpc3Rfc3IgPSBuZXcgU291cmNlUmFuZ2UoKTsKICAgICAgICAgICAgZm9yIChMaXN0PEpDQ2F0Y2g+IGwgPSB0cmVlczsgbC5ub25FbXB0eSgpOyBsID0gbC50YWlsKSB7CiAgICAgICAgICAgICAgICBsaXN0X3NyLm1lcmdlV2l0aChjc3AobC5oZWFkKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcG9zaXRpb25zLnB1dCh0cmVlcywgbGlzdF9zcik7CiAgICAgICAgICAgIHJldHVybiBsaXN0X3NyOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRNZXRob2REZWYoSkNNZXRob2REZWNsIHRyZWUpIHsKICAgICAgICAgICAgU291cmNlUmFuZ2Ugc3IgPSBuZXcgU291cmNlUmFuZ2Uoc3RhcnRQb3ModHJlZSksIGVuZFBvcyh0cmVlKSk7CiAgICAgICAgICAgIHNyLm1lcmdlV2l0aChjc3AodHJlZS5ib2R5KSk7CiAgICAgICAgICAgIHJlc3VsdCA9IHNyOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRWYXJEZWYoSkNWYXJpYWJsZURlY2wgdHJlZSkgewogICAgICAgICAgICBTb3VyY2VSYW5nZSBzciA9IG5ldyBTb3VyY2VSYW5nZShzdGFydFBvcyh0cmVlKSwgZW5kUG9zKHRyZWUpKTsKICAgICAgICAgICAgY3NwKHRyZWUudmFydHlwZSk7CiAgICAgICAgICAgIHNyLm1lcmdlV2l0aChjc3AodHJlZS5pbml0KSk7CiAgICAgICAgICAgIHJlc3VsdCA9IHNyOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRTa2lwKEpDU2tpcCB0cmVlKSB7CiAgICAgICAgICAgIC8vIGVuZFBvcyBpcyB0aGUgc2FtZSBhcyBzdGFydFBvcyBmb3IgdGhlIGVtcHR5IHN0YXRlbWVudAogICAgICAgICAgICBTb3VyY2VSYW5nZSBzciA9IG5ldyBTb3VyY2VSYW5nZShzdGFydFBvcyh0cmVlKSwgc3RhcnRQb3ModHJlZSkpOwogICAgICAgICAgICByZXN1bHQgPSBzcjsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0QmxvY2soSkNCbG9jayB0cmVlKSB7CiAgICAgICAgICAgIFNvdXJjZVJhbmdlIHNyID0gbmV3IFNvdXJjZVJhbmdlKHN0YXJ0UG9zKHRyZWUpLCBlbmRQb3ModHJlZSkpOwogICAgICAgICAgICBjc3AodHJlZS5zdGF0cyk7ICAgIC8vIGRvZXNuJ3QgY29tcGFyZSBiZWNhdXNlIGJsb2NrJ3MgZW5kaW5nIHBvc2l0aW9uIGlzIGRlZmluZWQKICAgICAgICAgICAgcmVzdWx0ID0gc3I7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdERvTG9vcChKQ0RvV2hpbGVMb29wIHRyZWUpIHsKICAgICAgICAgICAgU291cmNlUmFuZ2Ugc3IgPSBuZXcgU291cmNlUmFuZ2Uoc3RhcnRQb3ModHJlZSksIGVuZFBvcyh0cmVlKSk7CiAgICAgICAgICAgIHNyLm1lcmdlV2l0aChjc3AodHJlZS5ib2R5KSk7CiAgICAgICAgICAgIHNyLm1lcmdlV2l0aChjc3AodHJlZS5jb25kKSk7CiAgICAgICAgICAgIHJlc3VsdCA9IHNyOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRXaGlsZUxvb3AoSkNXaGlsZUxvb3AgdHJlZSkgewogICAgICAgICAgICBTb3VyY2VSYW5nZSBzciA9IG5ldyBTb3VyY2VSYW5nZShzdGFydFBvcyh0cmVlKSwgZW5kUG9zKHRyZWUpKTsKICAgICAgICAgICAgc3IubWVyZ2VXaXRoKGNzcCh0cmVlLmNvbmQpKTsKICAgICAgICAgICAgc3IubWVyZ2VXaXRoKGNzcCh0cmVlLmJvZHkpKTsKICAgICAgICAgICAgcmVzdWx0ID0gc3I7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdEZvckxvb3AoSkNGb3JMb29wIHRyZWUpIHsKICAgICAgICAgICAgU291cmNlUmFuZ2Ugc3IgPSBuZXcgU291cmNlUmFuZ2Uoc3RhcnRQb3ModHJlZSksIGVuZFBvcyh0cmVlKSk7CiAgICAgICAgICAgIHNyLm1lcmdlV2l0aChjc3AodHJlZS5pbml0KSk7CiAgICAgICAgICAgIHNyLm1lcmdlV2l0aChjc3AodHJlZS5jb25kKSk7CiAgICAgICAgICAgIHNyLm1lcmdlV2l0aChjc3AodHJlZS5zdGVwKSk7CiAgICAgICAgICAgIHNyLm1lcmdlV2l0aChjc3AodHJlZS5ib2R5KSk7CiAgICAgICAgICAgIHJlc3VsdCA9IHNyOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRGb3JlYWNoTG9vcChKQ0VuaGFuY2VkRm9yTG9vcCB0cmVlKSB7CiAgICAgICAgICAgIFNvdXJjZVJhbmdlIHNyID0gbmV3IFNvdXJjZVJhbmdlKHN0YXJ0UG9zKHRyZWUpLCBlbmRQb3ModHJlZSkpOwogICAgICAgICAgICBzci5tZXJnZVdpdGgoY3NwKHRyZWUudmFyKSk7CiAgICAgICAgICAgIHNyLm1lcmdlV2l0aChjc3AodHJlZS5leHByKSk7CiAgICAgICAgICAgIHNyLm1lcmdlV2l0aChjc3AodHJlZS5ib2R5KSk7CiAgICAgICAgICAgIHJlc3VsdCA9IHNyOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRMYWJlbGxlZChKQ0xhYmVsZWRTdGF0ZW1lbnQgdHJlZSkgewogICAgICAgICAgICBTb3VyY2VSYW5nZSBzciA9IG5ldyBTb3VyY2VSYW5nZShzdGFydFBvcyh0cmVlKSwgZW5kUG9zKHRyZWUpKTsKICAgICAgICAgICAgc3IubWVyZ2VXaXRoKGNzcCh0cmVlLmJvZHkpKTsKICAgICAgICAgICAgcmVzdWx0ID0gc3I7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdFN3aXRjaChKQ1N3aXRjaCB0cmVlKSB7CiAgICAgICAgICAgIFNvdXJjZVJhbmdlIHNyID0gbmV3IFNvdXJjZVJhbmdlKHN0YXJ0UG9zKHRyZWUpLCBlbmRQb3ModHJlZSkpOwogICAgICAgICAgICBzci5tZXJnZVdpdGgoY3NwKHRyZWUuc2VsZWN0b3IpKTsKICAgICAgICAgICAgc3IubWVyZ2VXaXRoKGNzcENhc2VzKHRyZWUuY2FzZXMpKTsKICAgICAgICAgICAgcmVzdWx0ID0gc3I7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdENhc2UoSkNDYXNlIHRyZWUpIHsKICAgICAgICAgICAgU291cmNlUmFuZ2Ugc3IgPSBuZXcgU291cmNlUmFuZ2Uoc3RhcnRQb3ModHJlZSksIGVuZFBvcyh0cmVlKSk7CiAgICAgICAgICAgIHNyLm1lcmdlV2l0aChjc3AodHJlZS5wYXQpKTsKICAgICAgICAgICAgc3IubWVyZ2VXaXRoKGNzcCh0cmVlLnN0YXRzKSk7CiAgICAgICAgICAgIHJlc3VsdCA9IHNyOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRTeW5jaHJvbml6ZWQoSkNTeW5jaHJvbml6ZWQgdHJlZSkgewogICAgICAgICAgICBTb3VyY2VSYW5nZSBzciA9IG5ldyBTb3VyY2VSYW5nZShzdGFydFBvcyh0cmVlKSwgZW5kUG9zKHRyZWUpKTsKICAgICAgICAgICAgc3IubWVyZ2VXaXRoKGNzcCh0cmVlLmxvY2spKTsKICAgICAgICAgICAgc3IubWVyZ2VXaXRoKGNzcCh0cmVlLmJvZHkpKTsKICAgICAgICAgICAgcmVzdWx0ID0gc3I7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdFRyeShKQ1RyeSB0cmVlKSB7CiAgICAgICAgICAgIFNvdXJjZVJhbmdlIHNyID0gbmV3IFNvdXJjZVJhbmdlKHN0YXJ0UG9zKHRyZWUpLCBlbmRQb3ModHJlZSkpOwogICAgICAgICAgICBzci5tZXJnZVdpdGgoY3NwKHRyZWUucmVzb3VyY2VzKSk7CiAgICAgICAgICAgIHNyLm1lcmdlV2l0aChjc3AodHJlZS5ib2R5KSk7CiAgICAgICAgICAgIHNyLm1lcmdlV2l0aChjc3BDYXRjaGVycyh0cmVlLmNhdGNoZXJzKSk7CiAgICAgICAgICAgIHNyLm1lcmdlV2l0aChjc3AodHJlZS5maW5hbGl6ZXIpKTsKICAgICAgICAgICAgcmVzdWx0ID0gc3I7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdENhdGNoKEpDQ2F0Y2ggdHJlZSkgewogICAgICAgICAgICBTb3VyY2VSYW5nZSBzciA9IG5ldyBTb3VyY2VSYW5nZShzdGFydFBvcyh0cmVlKSwgZW5kUG9zKHRyZWUpKTsKICAgICAgICAgICAgc3IubWVyZ2VXaXRoKGNzcCh0cmVlLnBhcmFtKSk7CiAgICAgICAgICAgIHNyLm1lcmdlV2l0aChjc3AodHJlZS5ib2R5KSk7CiAgICAgICAgICAgIHJlc3VsdCA9IHNyOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRDb25kaXRpb25hbChKQ0NvbmRpdGlvbmFsIHRyZWUpIHsKICAgICAgICAgICAgU291cmNlUmFuZ2Ugc3IgPSBuZXcgU291cmNlUmFuZ2Uoc3RhcnRQb3ModHJlZSksIGVuZFBvcyh0cmVlKSk7CiAgICAgICAgICAgIHNyLm1lcmdlV2l0aChjc3AodHJlZS5jb25kKSk7CiAgICAgICAgICAgIHNyLm1lcmdlV2l0aChjc3AodHJlZS50cnVlcGFydCkpOwogICAgICAgICAgICBzci5tZXJnZVdpdGgoY3NwKHRyZWUuZmFsc2VwYXJ0KSk7CiAgICAgICAgICAgIHJlc3VsdCA9IHNyOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRJZihKQ0lmIHRyZWUpIHsKICAgICAgICAgICAgU291cmNlUmFuZ2Ugc3IgPSBuZXcgU291cmNlUmFuZ2Uoc3RhcnRQb3ModHJlZSksIGVuZFBvcyh0cmVlKSk7CiAgICAgICAgICAgIHNyLm1lcmdlV2l0aChjc3AodHJlZS5jb25kKSk7CiAgICAgICAgICAgIHNyLm1lcmdlV2l0aChjc3AodHJlZS50aGVucGFydCkpOwogICAgICAgICAgICBzci5tZXJnZVdpdGgoY3NwKHRyZWUuZWxzZXBhcnQpKTsKICAgICAgICAgICAgcmVzdWx0ID0gc3I7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdEV4ZWMoSkNFeHByZXNzaW9uU3RhdGVtZW50IHRyZWUpIHsKICAgICAgICAgICAgU291cmNlUmFuZ2Ugc3IgPSBuZXcgU291cmNlUmFuZ2Uoc3RhcnRQb3ModHJlZSksIGVuZFBvcyh0cmVlKSk7CiAgICAgICAgICAgIHNyLm1lcmdlV2l0aChjc3AodHJlZS5leHByKSk7CiAgICAgICAgICAgIHJlc3VsdCA9IHNyOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRCcmVhayhKQ0JyZWFrIHRyZWUpIHsKICAgICAgICAgICAgU291cmNlUmFuZ2Ugc3IgPSBuZXcgU291cmNlUmFuZ2Uoc3RhcnRQb3ModHJlZSksIGVuZFBvcyh0cmVlKSk7CiAgICAgICAgICAgIHJlc3VsdCA9IHNyOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRDb250aW51ZShKQ0NvbnRpbnVlIHRyZWUpIHsKICAgICAgICAgICAgU291cmNlUmFuZ2Ugc3IgPSBuZXcgU291cmNlUmFuZ2Uoc3RhcnRQb3ModHJlZSksIGVuZFBvcyh0cmVlKSk7CiAgICAgICAgICAgIHJlc3VsdCA9IHNyOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRSZXR1cm4oSkNSZXR1cm4gdHJlZSkgewogICAgICAgICAgICBTb3VyY2VSYW5nZSBzciA9IG5ldyBTb3VyY2VSYW5nZShzdGFydFBvcyh0cmVlKSwgZW5kUG9zKHRyZWUpKTsKICAgICAgICAgICAgc3IubWVyZ2VXaXRoKGNzcCh0cmVlLmV4cHIpKTsKICAgICAgICAgICAgcmVzdWx0ID0gc3I7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdFRocm93KEpDVGhyb3cgdHJlZSkgewogICAgICAgICAgICBTb3VyY2VSYW5nZSBzciA9IG5ldyBTb3VyY2VSYW5nZShzdGFydFBvcyh0cmVlKSwgZW5kUG9zKHRyZWUpKTsKICAgICAgICAgICAgc3IubWVyZ2VXaXRoKGNzcCh0cmVlLmV4cHIpKTsKICAgICAgICAgICAgcmVzdWx0ID0gc3I7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdEFzc2VydChKQ0Fzc2VydCB0cmVlKSB7CiAgICAgICAgICAgIFNvdXJjZVJhbmdlIHNyID0gbmV3IFNvdXJjZVJhbmdlKHN0YXJ0UG9zKHRyZWUpLCBlbmRQb3ModHJlZSkpOwogICAgICAgICAgICBzci5tZXJnZVdpdGgoY3NwKHRyZWUuY29uZCkpOwogICAgICAgICAgICBzci5tZXJnZVdpdGgoY3NwKHRyZWUuZGV0YWlsKSk7CiAgICAgICAgICAgIHJlc3VsdCA9IHNyOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRBcHBseShKQ01ldGhvZEludm9jYXRpb24gdHJlZSkgewogICAgICAgICAgICBTb3VyY2VSYW5nZSBzciA9IG5ldyBTb3VyY2VSYW5nZShzdGFydFBvcyh0cmVlKSwgZW5kUG9zKHRyZWUpKTsKICAgICAgICAgICAgc3IubWVyZ2VXaXRoKGNzcCh0cmVlLm1ldGgpKTsKICAgICAgICAgICAgc3IubWVyZ2VXaXRoKGNzcCh0cmVlLmFyZ3MpKTsKICAgICAgICAgICAgcmVzdWx0ID0gc3I7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdE5ld0NsYXNzKEpDTmV3Q2xhc3MgdHJlZSkgewogICAgICAgICAgICBTb3VyY2VSYW5nZSBzciA9IG5ldyBTb3VyY2VSYW5nZShzdGFydFBvcyh0cmVlKSwgZW5kUG9zKHRyZWUpKTsKICAgICAgICAgICAgc3IubWVyZ2VXaXRoKGNzcCh0cmVlLmVuY2wpKTsKICAgICAgICAgICAgc3IubWVyZ2VXaXRoKGNzcCh0cmVlLmNsYXp6KSk7CiAgICAgICAgICAgIHNyLm1lcmdlV2l0aChjc3AodHJlZS5hcmdzKSk7CiAgICAgICAgICAgIHNyLm1lcmdlV2l0aChjc3AodHJlZS5kZWYpKTsKICAgICAgICAgICAgcmVzdWx0ID0gc3I7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdE5ld0FycmF5KEpDTmV3QXJyYXkgdHJlZSkgewogICAgICAgICAgICBTb3VyY2VSYW5nZSBzciA9IG5ldyBTb3VyY2VSYW5nZShzdGFydFBvcyh0cmVlKSwgZW5kUG9zKHRyZWUpKTsKICAgICAgICAgICAgc3IubWVyZ2VXaXRoKGNzcCh0cmVlLmVsZW10eXBlKSk7CiAgICAgICAgICAgIHNyLm1lcmdlV2l0aChjc3AodHJlZS5kaW1zKSk7CiAgICAgICAgICAgIHNyLm1lcmdlV2l0aChjc3AodHJlZS5lbGVtcykpOwogICAgICAgICAgICByZXN1bHQgPSBzcjsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0UGFyZW5zKEpDUGFyZW5zIHRyZWUpIHsKICAgICAgICAgICAgU291cmNlUmFuZ2Ugc3IgPSBuZXcgU291cmNlUmFuZ2Uoc3RhcnRQb3ModHJlZSksIGVuZFBvcyh0cmVlKSk7CiAgICAgICAgICAgIHNyLm1lcmdlV2l0aChjc3AodHJlZS5leHByKSk7CiAgICAgICAgICAgIHJlc3VsdCA9IHNyOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRBc3NpZ24oSkNBc3NpZ24gdHJlZSkgewogICAgICAgICAgICBTb3VyY2VSYW5nZSBzciA9IG5ldyBTb3VyY2VSYW5nZShzdGFydFBvcyh0cmVlKSwgZW5kUG9zKHRyZWUpKTsKICAgICAgICAgICAgc3IubWVyZ2VXaXRoKGNzcCh0cmVlLmxocykpOwogICAgICAgICAgICBzci5tZXJnZVdpdGgoY3NwKHRyZWUucmhzKSk7CiAgICAgICAgICAgIHJlc3VsdCA9IHNyOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRBc3NpZ25vcChKQ0Fzc2lnbk9wIHRyZWUpIHsKICAgICAgICAgICAgU291cmNlUmFuZ2Ugc3IgPSBuZXcgU291cmNlUmFuZ2Uoc3RhcnRQb3ModHJlZSksIGVuZFBvcyh0cmVlKSk7CiAgICAgICAgICAgIHNyLm1lcmdlV2l0aChjc3AodHJlZS5saHMpKTsKICAgICAgICAgICAgc3IubWVyZ2VXaXRoKGNzcCh0cmVlLnJocykpOwogICAgICAgICAgICByZXN1bHQgPSBzcjsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0VW5hcnkoSkNVbmFyeSB0cmVlKSB7CiAgICAgICAgICAgIFNvdXJjZVJhbmdlIHNyID0gbmV3IFNvdXJjZVJhbmdlKHN0YXJ0UG9zKHRyZWUpLCBlbmRQb3ModHJlZSkpOwogICAgICAgICAgICBzci5tZXJnZVdpdGgoY3NwKHRyZWUuYXJnKSk7CiAgICAgICAgICAgIHJlc3VsdCA9IHNyOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRCaW5hcnkoSkNCaW5hcnkgdHJlZSkgewogICAgICAgICAgICBTb3VyY2VSYW5nZSBzciA9IG5ldyBTb3VyY2VSYW5nZShzdGFydFBvcyh0cmVlKSwgZW5kUG9zKHRyZWUpKTsKICAgICAgICAgICAgc3IubWVyZ2VXaXRoKGNzcCh0cmVlLmxocykpOwogICAgICAgICAgICBzci5tZXJnZVdpdGgoY3NwKHRyZWUucmhzKSk7CiAgICAgICAgICAgIHJlc3VsdCA9IHNyOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRUeXBlQ2FzdChKQ1R5cGVDYXN0IHRyZWUpIHsKICAgICAgICAgICAgU291cmNlUmFuZ2Ugc3IgPSBuZXcgU291cmNlUmFuZ2Uoc3RhcnRQb3ModHJlZSksIGVuZFBvcyh0cmVlKSk7CiAgICAgICAgICAgIHNyLm1lcmdlV2l0aChjc3AodHJlZS5jbGF6eikpOwogICAgICAgICAgICBzci5tZXJnZVdpdGgoY3NwKHRyZWUuZXhwcikpOwogICAgICAgICAgICByZXN1bHQgPSBzcjsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0VHlwZVRlc3QoSkNJbnN0YW5jZU9mIHRyZWUpIHsKICAgICAgICAgICAgU291cmNlUmFuZ2Ugc3IgPSBuZXcgU291cmNlUmFuZ2Uoc3RhcnRQb3ModHJlZSksIGVuZFBvcyh0cmVlKSk7CiAgICAgICAgICAgIHNyLm1lcmdlV2l0aChjc3AodHJlZS5leHByKSk7CiAgICAgICAgICAgIHNyLm1lcmdlV2l0aChjc3AodHJlZS5jbGF6eikpOwogICAgICAgICAgICByZXN1bHQgPSBzcjsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0SW5kZXhlZChKQ0FycmF5QWNjZXNzIHRyZWUpIHsKICAgICAgICAgICAgU291cmNlUmFuZ2Ugc3IgPSBuZXcgU291cmNlUmFuZ2Uoc3RhcnRQb3ModHJlZSksIGVuZFBvcyh0cmVlKSk7CiAgICAgICAgICAgIHNyLm1lcmdlV2l0aChjc3AodHJlZS5pbmRleGVkKSk7CiAgICAgICAgICAgIHNyLm1lcmdlV2l0aChjc3AodHJlZS5pbmRleCkpOwogICAgICAgICAgICByZXN1bHQgPSBzcjsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0U2VsZWN0KEpDRmllbGRBY2Nlc3MgdHJlZSkgewogICAgICAgICAgICBTb3VyY2VSYW5nZSBzciA9IG5ldyBTb3VyY2VSYW5nZShzdGFydFBvcyh0cmVlKSwgZW5kUG9zKHRyZWUpKTsKICAgICAgICAgICAgc3IubWVyZ2VXaXRoKGNzcCh0cmVlLnNlbGVjdGVkKSk7CiAgICAgICAgICAgIHJlc3VsdCA9IHNyOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRJZGVudChKQ0lkZW50IHRyZWUpIHsKICAgICAgICAgICAgU291cmNlUmFuZ2Ugc3IgPSBuZXcgU291cmNlUmFuZ2Uoc3RhcnRQb3ModHJlZSksIGVuZFBvcyh0cmVlKSk7CiAgICAgICAgICAgIHJlc3VsdCA9IHNyOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRMaXRlcmFsKEpDTGl0ZXJhbCB0cmVlKSB7CiAgICAgICAgICAgIFNvdXJjZVJhbmdlIHNyID0gbmV3IFNvdXJjZVJhbmdlKHN0YXJ0UG9zKHRyZWUpLCBlbmRQb3ModHJlZSkpOwogICAgICAgICAgICByZXN1bHQgPSBzcjsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0VHlwZUlkZW50KEpDUHJpbWl0aXZlVHlwZVRyZWUgdHJlZSkgewogICAgICAgICAgICBTb3VyY2VSYW5nZSBzciA9IG5ldyBTb3VyY2VSYW5nZShzdGFydFBvcyh0cmVlKSwgZW5kUG9zKHRyZWUpKTsKICAgICAgICAgICAgcmVzdWx0ID0gc3I7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdFR5cGVBcnJheShKQ0FycmF5VHlwZVRyZWUgdHJlZSkgewogICAgICAgICAgICBTb3VyY2VSYW5nZSBzciA9IG5ldyBTb3VyY2VSYW5nZShzdGFydFBvcyh0cmVlKSwgZW5kUG9zKHRyZWUpKTsKICAgICAgICAgICAgc3IubWVyZ2VXaXRoKGNzcCh0cmVlLmVsZW10eXBlKSk7CiAgICAgICAgICAgIHJlc3VsdCA9IHNyOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRUeXBlQXBwbHkoSkNUeXBlQXBwbHkgdHJlZSkgewogICAgICAgICAgICBTb3VyY2VSYW5nZSBzciA9IG5ldyBTb3VyY2VSYW5nZShzdGFydFBvcyh0cmVlKSwgZW5kUG9zKHRyZWUpKTsKICAgICAgICAgICAgc3IubWVyZ2VXaXRoKGNzcCh0cmVlLmNsYXp6KSk7CiAgICAgICAgICAgIHNyLm1lcmdlV2l0aChjc3AodHJlZS5hcmd1bWVudHMpKTsKICAgICAgICAgICAgcmVzdWx0ID0gc3I7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdExldEV4cHIoTGV0RXhwciB0cmVlKSB7CiAgICAgICAgICAgIFNvdXJjZVJhbmdlIHNyID0gbmV3IFNvdXJjZVJhbmdlKHN0YXJ0UG9zKHRyZWUpLCBlbmRQb3ModHJlZSkpOwogICAgICAgICAgICBzci5tZXJnZVdpdGgoY3NwKHRyZWUuZGVmcykpOwogICAgICAgICAgICBzci5tZXJnZVdpdGgoY3NwKHRyZWUuZXhwcikpOwogICAgICAgICAgICByZXN1bHQgPSBzcjsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0VHlwZVBhcmFtZXRlcihKQ1R5cGVQYXJhbWV0ZXIgdHJlZSkgewogICAgICAgICAgICBTb3VyY2VSYW5nZSBzciA9IG5ldyBTb3VyY2VSYW5nZShzdGFydFBvcyh0cmVlKSwgZW5kUG9zKHRyZWUpKTsKICAgICAgICAgICAgc3IubWVyZ2VXaXRoKGNzcCh0cmVlLmJvdW5kcykpOwogICAgICAgICAgICByZXN1bHQgPSBzcjsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHZpc2l0VHlwZVVuaW9uKEpDVHlwZVVuaW9uIHRyZWUpIHsKICAgICAgICAgICAgU291cmNlUmFuZ2Ugc3IgPSBuZXcgU291cmNlUmFuZ2Uoc3RhcnRQb3ModHJlZSksIGVuZFBvcyh0cmVlKSk7CiAgICAgICAgICAgIHNyLm1lcmdlV2l0aChjc3AodHJlZS5hbHRlcm5hdGl2ZXMpKTsKICAgICAgICAgICAgcmVzdWx0ID0gc3I7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgdm9pZCB2aXNpdFdpbGRjYXJkKEpDV2lsZGNhcmQgdHJlZSkgewogICAgICAgICAgICByZXN1bHQgPSBudWxsOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRFcnJvbmVvdXMoSkNFcnJvbmVvdXMgdHJlZSkgewogICAgICAgICAgICByZXN1bHQgPSBudWxsOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHZvaWQgdmlzaXRUcmVlKEpDVHJlZSB0cmVlKSB7CiAgICAgICAgICAgIEFzc2VydC5lcnJvcigpOwogICAgICAgIH0KCiAgICAgICAgLyoqIFRoZSBzdGFydCBwb3NpdGlvbiBvZiBnaXZlbiB0cmVlLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBpbnQgc3RhcnRQb3MoSkNUcmVlIHRyZWUpIHsKICAgICAgICAgICAgaWYgKHRyZWUgPT0gbnVsbCkgcmV0dXJuIFBvc2l0aW9uLk5PUE9TOwogICAgICAgICAgICByZXR1cm4gVHJlZUluZm8uZ2V0U3RhcnRQb3ModHJlZSk7CiAgICAgICAgfQoKICAgICAgICAvKiogVGhlIGVuZCBwb3NpdGlvbiBvZiBnaXZlbiB0cmVlLCBpZiBpdCBoYXMKICAgICAgICAgKiAgZGVmaW5lZCBlbmRwb3MsIE5PUE9TIG90aGVyd2lzZS4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgaW50IGVuZFBvcyhKQ1RyZWUgdHJlZSkgewogICAgICAgICAgICBpZiAodHJlZSA9PSBudWxsKSByZXR1cm4gUG9zaXRpb24uTk9QT1M7CiAgICAgICAgICAgIHJldHVybiBUcmVlSW5mby5nZXRFbmRQb3ModHJlZSwgZW5kUG9zVGFibGUpOwogICAgICAgIH0KICAgIH0KCiAgICAvKiogVGhpcyBjbGFzcyBjb250YWlucyBhIENoYXJhY3RlclJhbmdlVGFibGVFbnRyeS4KICAgICAqLwogICAgc3RhdGljIGNsYXNzIENSVEVudHJ5IHsKCiAgICAgICAgLyoqIEEgdHJlZSBvciBhIGxpc3Qgb2YgdHJlZXMgdG8gb2J0YWluIHNvdXJjZSBwb3NpdGlvbnMuCiAgICAgICAgICovCiAgICAgICAgT2JqZWN0IHRyZWU7CgogICAgICAgIC8qKiBUaGUgZmxhZ3MgZGVzY3JpYmVkIGluIHRoZSBDaGFyYWN0ZXJSYW5nZVRhYmxlIHNwZWMuCiAgICAgICAgICovCiAgICAgICAgaW50IGZsYWdzOwoKICAgICAgICAvKiogVGhlIHN0YXJ0aW5nIGNvZGUgcG9zaXRpb24gb2YgdGhpcyBlbnRyeS4KICAgICAgICAgKi8KICAgICAgICBpbnQgc3RhcnRQYzsKCiAgICAgICAgLyoqIFRoZSBlbmRpbmcgY29kZSBwb3NpdGlvbiBvZiB0aGlzIGVudHJ5LgogICAgICAgICAqLwogICAgICAgIGludCBlbmRQYzsKCiAgICAgICAgLyoqIENvbnN0cnVjdG9yICovCiAgICAgICAgQ1JURW50cnkoT2JqZWN0IHRyZWUsIGludCBmbGFncywgaW50IHN0YXJ0UGMsIGludCBlbmRQYykgewogICAgICAgICAgICB0aGlzLnRyZWUgPSB0cmVlOwogICAgICAgICAgICB0aGlzLmZsYWdzID0gZmxhZ3M7CiAgICAgICAgICAgIHRoaXMuc3RhcnRQYyA9IHN0YXJ0UGM7CiAgICAgICAgICAgIHRoaXMuZW5kUGMgPSBlbmRQYzsKICAgICAgICB9CiAgICB9CgoKICAgIC8qKiBUaGlzIGNsYXNzIGNvbnRhaW5zIHNvdXJjZSBwb3NpdGlvbnMKICAgICAqICBmb3Igc29tZSB0cmVlIG9yIGxpc3Qgb2YgdHJlZXMuCiAgICAgKi8KICAgIHN0YXRpYyBjbGFzcyBTb3VyY2VSYW5nZSB7CgogICAgICAgIC8qKiBUaGUgc3RhcnRpbmcgc291cmNlIHBvc2l0aW9uLgogICAgICAgICAqLwogICAgICAgIGludCBzdGFydFBvczsKCiAgICAgICAgLyoqIFRoZSBlbmRpbmcgc291cmNlIHBvc2l0aW9uLgogICAgICAgICAqLwogICAgICAgIGludCBlbmRQb3M7CgogICAgICAgIC8qKiBDb25zdHJ1Y3RvciAqLwogICAgICAgIFNvdXJjZVJhbmdlKCkgewogICAgICAgICAgICBzdGFydFBvcyA9IFBvc2l0aW9uLk5PUE9TOwogICAgICAgICAgICBlbmRQb3MgPSBQb3NpdGlvbi5OT1BPUzsKICAgICAgICB9CgogICAgICAgIC8qKiBDb25zdHJ1Y3RvciAqLwogICAgICAgIFNvdXJjZVJhbmdlKGludCBzdGFydFBvcywgaW50IGVuZFBvcykgewogICAgICAgICAgICB0aGlzLnN0YXJ0UG9zID0gc3RhcnRQb3M7CiAgICAgICAgICAgIHRoaXMuZW5kUG9zID0gZW5kUG9zOwogICAgICAgIH0KCiAgICAgICAgLyoqIENvbXBhcmUgdGhlIHN0YXJ0aW5nIGFuZCB0aGUgZW5kaW5nIHBvc2l0aW9ucwogICAgICAgICAqICBvZiB0aGUgc291cmNlIHJhbmdlIGFuZCBjb21iaW5lcyB0aGVtIGFzc2lnbmluZwogICAgICAgICAqICB0aGUgd2lkZXN0IHJhbmdlIHRvIHRoaXMuCiAgICAgICAgICovCiAgICAgICAgU291cmNlUmFuZ2UgbWVyZ2VXaXRoKFNvdXJjZVJhbmdlIHNyKSB7CiAgICAgICAgICAgIGlmIChzciA9PSBudWxsKSByZXR1cm4gdGhpczsKICAgICAgICAgICAgaWYgKHN0YXJ0UG9zID09IFBvc2l0aW9uLk5PUE9TKQogICAgICAgICAgICAgICAgc3RhcnRQb3MgPSBzci5zdGFydFBvczsKICAgICAgICAgICAgZWxzZSBpZiAoc3Iuc3RhcnRQb3MgIT0gUG9zaXRpb24uTk9QT1MpCiAgICAgICAgICAgICAgICBzdGFydFBvcyA9IChzdGFydFBvcyA8IHNyLnN0YXJ0UG9zID8gc3RhcnRQb3MgOiBzci5zdGFydFBvcyk7CiAgICAgICAgICAgIGlmIChlbmRQb3MgPT0gUG9zaXRpb24uTk9QT1MpCiAgICAgICAgICAgICAgICBlbmRQb3MgPSBzci5lbmRQb3M7CiAgICAgICAgICAgIGVsc2UgaWYgKHNyLmVuZFBvcyAhPSBQb3NpdGlvbi5OT1BPUykKICAgICAgICAgICAgICAgIGVuZFBvcyA9IChlbmRQb3MgPiBzci5lbmRQb3MgPyBlbmRQb3MgOiBzci5lbmRQb3MpOwogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICB9Cgp9ClBLAwQKAAAIAAAGO6lKwX+4Yy0LAAAtCwAAHQAAAGNvbS9zdW4vdG9vbHMvamF2YWMvTWFpbi5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAxOTk5LCAyMDEzLCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuamF2YWM7CgppbXBvcnQgamF2YS5pby5QcmludFdyaXRlcjsKCi8qKgogKiBUaGUgcHJvZ3JhbW1hdGljIGludGVyZmFjZSBmb3IgdGhlIEphdmEgUHJvZ3JhbW1pbmcgTGFuZ3VhZ2UKICogY29tcGlsZXIsIGphdmFjLgogKi8KcHVibGljIGNsYXNzIE1haW4gewoKICAgIC8qKiBNYWluIGVudHJ5IHBvaW50IGZvciB0aGUgbGF1bmNoZXIuCiAgICAgKiAgTm90ZTogVGhpcyBtZXRob2QgY2FsbHMgU3lzdGVtLmV4aXQuCiAgICAgKiAgQHBhcmFtIGFyZ3MgY29tbWFuZCBsaW5lIGFyZ3VtZW50cwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmdbXSBhcmdzKSB0aHJvd3MgRXhjZXB0aW9uIHsKICAgICAgICBTeXN0ZW0uZXhpdChjb21waWxlKGFyZ3MpKTsKICAgIH0KCiAgICAvKiogUHJvZ3JhbW1hdGljIGludGVyZmFjZSB0byB0aGUgSmF2YSBQcm9ncmFtbWluZyBMYW5ndWFnZQogICAgICogY29tcGlsZXIsIGphdmFjLgogICAgICoKICAgICAqIEBwYXJhbSBhcmdzIFRoZSBjb21tYW5kIGxpbmUgYXJndW1lbnRzIHRoYXQgd291bGQgbm9ybWFsbHkgYmUKICAgICAqIHBhc3NlZCB0byB0aGUgamF2YWMgcHJvZ3JhbSBhcyBkZXNjcmliZWQgaW4gdGhlIG1hbiBwYWdlLgogICAgICogQHJldHVybiBhbiBpbnRlZ2VyIGVxdWl2YWxlbnQgdG8gdGhlIGV4aXQgdmFsdWUgZnJvbSBpbnZva2luZwogICAgICogamF2YWMsIHNlZSB0aGUgbWFuIHBhZ2UgZm9yIGRldGFpbHMuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgaW50IGNvbXBpbGUoU3RyaW5nW10gYXJncykgewogICAgICAgIGNvbS5zdW4udG9vbHMuamF2YWMubWFpbi5NYWluIGNvbXBpbGVyID0KICAgICAgICAgICAgbmV3IGNvbS5zdW4udG9vbHMuamF2YWMubWFpbi5NYWluKCJqYXZhYyIpOwogICAgICAgIHJldHVybiBjb21waWxlci5jb21waWxlKGFyZ3MpLmV4aXRDb2RlOwogICAgfQoKCgogICAgLyoqIFByb2dyYW1tYXRpYyBpbnRlcmZhY2UgdG8gdGhlIEphdmEgUHJvZ3JhbW1pbmcgTGFuZ3VhZ2UKICAgICAqIGNvbXBpbGVyLCBqYXZhYy4KICAgICAqCiAgICAgKiBAcGFyYW0gYXJncyBUaGUgY29tbWFuZCBsaW5lIGFyZ3VtZW50cyB0aGF0IHdvdWxkIG5vcm1hbGx5IGJlCiAgICAgKiBwYXNzZWQgdG8gdGhlIGphdmFjIHByb2dyYW0gYXMgZGVzY3JpYmVkIGluIHRoZSBtYW4gcGFnZS4KICAgICAqIEBwYXJhbSBvdXQgUHJpbnRXcml0ZXIgdG8gd2hpY2ggdGhlIGNvbXBpbGVyJ3MgZGlhZ25vc3RpYwogICAgICogb3V0cHV0IGlzIGRpcmVjdGVkLgogICAgICogQHJldHVybiBhbiBpbnRlZ2VyIGVxdWl2YWxlbnQgdG8gdGhlIGV4aXQgdmFsdWUgZnJvbSBpbnZva2luZwogICAgICogamF2YWMsIHNlZSB0aGUgbWFuIHBhZ2UgZm9yIGRldGFpbHMuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgaW50IGNvbXBpbGUoU3RyaW5nW10gYXJncywgUHJpbnRXcml0ZXIgb3V0KSB7CiAgICAgICAgY29tLnN1bi50b29scy5qYXZhYy5tYWluLk1haW4gY29tcGlsZXIgPQogICAgICAgICAgICBuZXcgY29tLnN1bi50b29scy5qYXZhYy5tYWluLk1haW4oImphdmFjIiwgb3V0KTsKICAgICAgICByZXR1cm4gY29tcGlsZXIuY29tcGlsZShhcmdzKS5leGl0Q29kZTsKICAgIH0KfQpQSwMECgAACAAABjupSgAAAAAAAAAAAAAAABYAAABjb20vc3VuL3Rvb2xzL2RvY2xpbnQvUEsDBAoAAAgAAAY7qUoAAAAAAAAAAAAAAAAgAAAAY29tL3N1bi90b29scy9kb2NsaW50L3Jlc291cmNlcy9QSwMECgAACAAABjupSmJrJ2g4GgAAOBoAADIAAABjb20vc3VuL3Rvb2xzL2RvY2xpbnQvcmVzb3VyY2VzL2RvY2xpbnQucHJvcGVydGllcyMKIyBDb3B5cmlnaHQgKGMpIDIwMTIsIDIwMTcsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiMgRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgojCiMgVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKIyB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwojIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwojIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKIyBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KIwojIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAojIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgojIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQojIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiMgYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KIwojIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KIyAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiMgSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgojCiMgUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKIyBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiMgcXVlc3Rpb25zLgojCgpkYy5hbmNob3IuYWxyZWFkeS5kZWZpbmVkID0gYW5jaG9yIGFscmVhZHkgZGVmaW5lZDogInswfSIKZGMuYW5jaG9yLnZhbHVlLm1pc3NpbmcgPSBubyB2YWx1ZSBnaXZlbiBmb3IgYW5jaG9yCmRjLmF0dHIubGFja3MudmFsdWUgPSBhdHRyaWJ1dGUgbGFja3MgdmFsdWUKZGMuYXR0ci5ub3QubnVtYmVyID0gYXR0cmlidXRlIHZhbHVlIGlzIG5vdCBhIG51bWJlcgpkYy5hdHRyLm5vdC5zdXBwb3J0ZWQuaHRtbDQgPSBhdHRyaWJ1dGUgbm90IHN1cHBvcnRlZCBpbiBIVE1MNDogezB9CmRjLmF0dHIubm90LnN1cHBvcnRlZC5odG1sNSA9IGF0dHJpYnV0ZSBub3Qgc3VwcG9ydGVkIGluIEhUTUw1OiB7MH0KZGMuYXR0ci5vYnNvbGV0ZSA9IGF0dHJpYnV0ZSBvYnNvbGV0ZTogezB9CmRjLmF0dHIub2Jzb2xldGUudXNlLmNzcyA9IGF0dHJpYnV0ZSBvYnNvbGV0ZSwgdXNlIENTUyBpbnN0ZWFkOiB7MH0KZGMuYXR0ci5yZXBlYXRlZCA9IHJlcGVhdGVkIGF0dHJpYnV0ZTogezB9CmRjLmF0dHIudGFibGUuYm9yZGVyLmh0bWw1ID0gYXR0cmlidXRlIGJvcmRlciBmb3IgdGFibGUgb25seSBhY2NlcHRzICIiIG9yICIxIiwgdXNlIENTUyBpbnN0ZWFkOiB7MH0KZGMuYXR0ci51bmtub3duID0gdW5rbm93biBhdHRyaWJ1dGU6IHswfQpkYy5iYWQub3B0aW9uID0gYmFkIG9wdGlvbjogezB9CmRjLmJhZC52YWx1ZS5mb3Iub3B0aW9uID0gYmFkIHZhbHVlIGZvciBvcHRpb246IHswfSB7MX0KZGMuZW1wdHkgPSBubyBkZXNjcmlwdGlvbiBmb3IgQHswfQpkYy5lbnRpdHkuaW52YWxpZCA9IGludmFsaWQgZW50aXR5ICZ7MH07CmRjLmV4Y2VwdGlvbi5ub3QudGhyb3duID0gZXhjZXB0aW9uIG5vdCB0aHJvd246IHswfQpkYy5leGlzdHMucGFyYW0gPSBAcGFyYW0gInswfSIgaGFzIGFscmVhZHkgYmVlbiBzcGVjaWZpZWQKZGMuZXhpc3RzLnJldHVybiA9IEByZXR1cm4gaGFzIGFscmVhZHkgYmVlbiBzcGVjaWZpZWQKZGMuaW52YWxpZC5hbmNob3IgPSBpbnZhbGlkIG5hbWUgZm9yIGFuY2hvcjogInswfSIKZGMuaW52YWxpZC5wYXJhbSA9IGludmFsaWQgdXNlIG9mIEBwYXJhbQpkYy5pbnZhbGlkLnByb3ZpZGVzID0gaW52YWxpZCB1c2Ugb2YgQHByb3ZpZGVzCmRjLmludmFsaWQucmV0dXJuID0gaW52YWxpZCB1c2Ugb2YgQHJldHVybgpkYy5pbnZhbGlkLnRocm93cyA9IGludmFsaWQgdXNlIG9mIEB0aHJvd3MKZGMuaW52YWxpZC51c2VzID0gaW52YWxpZCB1c2Ugb2YgQHVzZXMKZGMuaW52YWxpZC51cmkgPSBpbnZhbGlkIHVyaTogInswfSIKZGMubWlzc2luZy5jb21tZW50ID0gbm8gY29tbWVudApkYy5taXNzaW5nLnBhcmFtID0gbm8gQHBhcmFtIGZvciB7MH0KZGMubWlzc2luZy5yZXR1cm4gPSBubyBAcmV0dXJuCmRjLm1pc3NpbmcudGhyb3dzID0gbm8gQHRocm93cyBmb3IgezB9CmRjLm5vLmFsdC5hdHRyLmZvci5pbWFnZSA9IG5vICJhbHQiIGF0dHJpYnV0ZSBmb3IgaW1hZ2UKZGMubm8uc3VtbWFyeS5vci5jYXB0aW9uLmZvci50YWJsZT1ubyBzdW1tYXJ5IG9yIGNhcHRpb24gZm9yIHRhYmxlCmRjLnBhcmFtLm5hbWUubm90LmZvdW5kID0gQHBhcmFtIG5hbWUgbm90IGZvdW5kCmRjLnJlZi5ub3QuZm91bmQgPSByZWZlcmVuY2Ugbm90IGZvdW5kCmRjLnNlcnZpY2Uubm90LmZvdW5kID0gc2VydmljZS10eXBlIG5vdCBmb3VuZApkYy50YWcuY29kZS53aXRoaW4uY29kZSA9ICd7QGNvZGUnfSB3aXRoaW4gPGNvZGU+CmRjLnRhZy5lbXB0eSA9IGVtcHR5IDx7MH0+IHRhZwpkYy50YWcuZW5kLm5vdC5wZXJtaXR0ZWQgPSBpbnZhbGlkIGVuZCB0YWc6IDwvezB9PgpkYy50YWcuZW5kLnVuZXhwZWN0ZWQgPSB1bmV4cGVjdGVkIGVuZCB0YWc6IDwvezB9PgpkYy50YWcuaGVhZGVyLnNlcXVlbmNlLjEgPSBoZWFkZXIgdXNlZCBvdXQgb2Ygc2VxdWVuY2U6IDx7MH0+CmRjLnRhZy5oZWFkZXIuc2VxdWVuY2UuMiA9IGhlYWRlciB1c2VkIG91dCBvZiBzZXF1ZW5jZTogPHswfT4KZGMudGFnLm5lc3RlZC5ub3QuYWxsb3dlZD1uZXN0ZWQgdGFnIG5vdCBhbGxvd2VkOiA8ezB9PgpkYy50YWcubm90LmFsbG93ZWQuaGVyZSA9IHRhZyBub3QgYWxsb3dlZCBoZXJlOiA8ezB9PgpkYy50YWcubm90LmFsbG93ZWQgPSBlbGVtZW50IG5vdCBhbGxvd2VkIGluIGRvY3VtZW50YXRpb24gY29tbWVudHM6IDx7MH0+CmRjLnRhZy5ub3QuYWxsb3dlZC5pbmxpbmUuZWxlbWVudCA9IGJsb2NrIGVsZW1lbnQgbm90IGFsbG93ZWQgd2l0aGluIGlubGluZSBlbGVtZW50IDx7MX0+OiB7MH0KZGMudGFnLm5vdC5hbGxvd2VkLmlubGluZS50YWcgPSBibG9jayBlbGVtZW50IG5vdCBhbGxvd2VkIHdpdGhpbiBAezF9OiB7MH0KZGMudGFnLm5vdC5hbGxvd2VkLmlubGluZS5vdGhlciA9IGJsb2NrIGVsZW1lbnQgbm90IGFsbG93ZWQgaGVyZTogezB9CmRjLnRhZy5ub3QuY2xvc2VkPSBlbGVtZW50IG5vdCBjbG9zZWQ6IHswfQpkYy50YWcucC5pbi5wcmU9IHVuZXhwZWN0ZWQgdXNlIG9mIDxwPiBpbnNpZGUgPHByZT4gZWxlbWVudApkYy50YWcucmVxdWlyZXMuaGVhZGluZyA9IGhlYWRpbmcgbm90IGZvdW5kIGZvciA8L3swfT4KZGMudGFnLnNlbGYuY2xvc2luZyA9IHNlbGYtY2xvc2luZyBlbGVtZW50IG5vdCBhbGxvd2VkCmRjLnRhZy5zdGFydC51bm1hdGNoZWQgPSBlbmQgdGFnIG1pc3Npbmc6IDwvezB9PgpkYy50YWcudW5rbm93biA9IHVua25vd24gdGFnOiB7MH0KZGMudGFnLm5vdC5zdXBwb3J0ZWQgPSB0YWcgbm90IHN1cHBvcnRlZCBpbiB0aGUgZ2VuZXJhdGVkIEhUTUwgdmVyc2lvbjogezB9CmRjLnRleHQubm90LmFsbG93ZWQgPSB0ZXh0IG5vdCBhbGxvd2VkIGluIDx7MH0+IGVsZW1lbnQKZGMudHlwZS5hcmcubm90LmFsbG93ZWQgPSB0eXBlIGFyZ3VtZW50cyBub3QgYWxsb3dlZCBoZXJlCmRjLnVuZXhwZWN0ZWQuY29tbWVudD1kb2N1bWVudGF0aW9uIGNvbW1lbnQgbm90IGV4cGVjdGVkIGhlcmUKZGMudmFsdWUubm90LmFsbG93ZWQuaGVyZT0ne0B2YWx1ZX0nIG5vdCBhbGxvd2VkIGhlcmUKZGMudmFsdWUubm90LmEuY29uc3RhbnQ9dmFsdWUgZG9lcyBub3QgcmVmZXIgdG8gYSBjb25zdGFudAoKZGMubWFpbi5pb2Vycm9yPUlPIGVycm9yOiB7MH0KZGMubWFpbi5uby5maWxlcy5naXZlbj1ObyBmaWxlcyBnaXZlbgpkYy5tYWluLnVzYWdlPVwKVXNhZ2U6XG5cClwgICAgZG9jbGludCBbb3B0aW9uc10gc291cmNlLWZpbGVzLi4uXG5cClxuXApPcHRpb25zOlxuXApcICAtWG1zZ3MgIFxuXApcICAgIFNhbWUgYXMgLVhtc2dzOmFsbFxuXApcICAtWG1zZ3M6dmFsdWVzXG5cClwgICAgU3BlY2lmeSBjYXRlZ29yaWVzIG9mIGlzc3VlcyB0byBiZSBjaGVja2VkLCB3aGVyZSAnJ3ZhbHVlcycnXG5cClwgICAgaXMgYSBjb21tYS1zZXBhcmF0ZWQgbGlzdCBvZiBhbnkgb2YgdGhlIGZvbGxvd2luZzpcblwKXCAgICAgIHJlZmVyZW5jZSAgICAgIHNob3cgcGxhY2VzIHdoZXJlIGNvbW1lbnRzIGNvbnRhaW4gaW5jb3JyZWN0XG5cClwgICAgICAgICAgICAgICAgICAgICByZWZlcmVuY2VzIHRvIEphdmEgc291cmNlIGNvZGUgZWxlbWVudHNcblwKXCAgICAgIHN5bnRheCAgICAgICAgIHNob3cgYmFzaWMgc3ludGF4IGVycm9ycyB3aXRoaW4gY29tbWVudHNcblwKXCAgICAgIGh0bWwgICAgICAgICAgIHNob3cgaXNzdWVzIHdpdGggSFRNTCB0YWdzIGFuZCBhdHRyaWJ1dGVzXG5cClwgICAgICBhY2Nlc3NpYmlsaXR5ICBzaG93IGlzc3VlcyBmb3IgYWNjZXNzaWJpbGl0eVxuXApcICAgICAgbWlzc2luZyAgICAgICAgc2hvdyBpc3N1ZXMgd2l0aCBtaXNzaW5nIGRvY3VtZW50YXRpb25cblwKXCAgICAgIGFsbCAgICAgICAgICAgIGFsbCBvZiB0aGUgYWJvdmVcblwKXCAgICBQcmVjZWRlIGEgdmFsdWUgd2l0aCAnJy0nJyB0byBuZWdhdGUgaXRcblwKXCAgICBDYXRlZ29yaWVzIG1heSBiZSBxdWFsaWZpZWQgYnkgb25lIG9mOlxuXApcICAgICAgL3B1YmxpYyAvcHJvdGVjdGVkIC9wYWNrYWdlIC9wcml2YXRlXG5cClwgICAgRm9yIHBvc2l0aXZlIGNhdGVnb3JpZXMgKG5vdCBiZWdpbm5pbmcgd2l0aCAnJy0nJylcblwKXCAgICB0aGUgcXVhbGlmaWVyIGFwcGxpZXMgdG8gdGhhdCBhY2Nlc3MgbGV2ZWwgYW5kIGFib3ZlLlxuXApcICAgIEZvciBuZWdhdGl2ZSBjYXRlZ29yaWVzIChiZWdpbm5pbmcgd2l0aCAnJy0nJylcblwKXCAgICB0aGUgcXVhbGlmaWVyIGFwcGxpZXMgdG8gdGhhdCBhY2Nlc3MgbGV2ZWwgYW5kIGJlbG93LlxuXApcICAgIElmIGEgcXVhbGlmaWVyIGlzIG1pc3NpbmcsIHRoZSBjYXRlZ29yeSBhcHBsaWVzIHRvXG5cClwgICAgYWxsIGFjY2VzcyBsZXZlbHMuXG5cClwgICAgRm9yIGV4YW1wbGUsIC1YbXNnczphbGwsLXN5bnRheC9wcml2YXRlXG5cClwgICAgVGhpcyB3aWxsIGVuYWJsZSBhbGwgbWVzc2FnZXMsIGV4Y2VwdCBzeW50YXggZXJyb3JzXG5cClwgICAgaW4gdGhlIGRvYyBjb21tZW50cyBvZiBwcml2YXRlIG1ldGhvZHMuXG5cClwgICAgSWYgbm8gLVhtc2dzIG9wdGlvbnMgYXJlIHByb3ZpZGVkLCB0aGUgZGVmYXVsdCBpc1xuXApcICAgIGVxdWl2YWxlbnQgdG8gLVhtc2dzOmFsbC9wcm90ZWN0ZWQsIG1lYW5pbmcgdGhhdFxuXApcICAgIGFsbCBtZXNzYWdlcyBhcmUgcmVwb3J0ZWQgZm9yIHByb3RlY3RlZCBhbmQgcHVibGljXG5cClwgICAgZGVjbGFyYXRpb25zIG9ubHkuIFxuXApcICAtWGNoZWNrUGFja2FnZTo8cGFja2FnZXM+XG5cClwgICAgRW5hYmxlIG9yIGRpc2FibGUgY2hlY2tzIGluIHNwZWNpZmljIHBhY2thZ2VzLlxuXApcICAgIDxwYWNrYWdlcz4gaXMgYSBjb21tYSBzZXBhcmF0ZWQgbGlzdCBvZiBwYWNrYWdlIHNwZWNpZmllcnMuXG5cClwgICAgUGFja2FnZSBzcGVjaWZpZXIgaXMgZWl0aGVyIGEgcXVhbGlmaWVkIG5hbWUgb2YgYSBwYWNrYWdlXG5cClwgICAgb3IgYSBwYWNrYWdlIG5hbWUgcHJlZml4IGZvbGxvd2VkIGJ5ICcnLionJywgd2hpY2ggZXhwYW5kcyB0b1xuXApcICAgIGFsbCBzdWItcGFja2FnZXMgb2YgdGhlIGdpdmVuIHBhY2thZ2UuIFByZWZpeCB0aGUgcGFja2FnZSBzcGVjaWZpZXJcblwKXCAgICB3aXRoICcnLScnIHRvIGRpc2FibGUgY2hlY2tzIGZvciB0aGUgc3BlY2lmaWVkIHBhY2thZ2VzLlxuXApcICAtc3RhdHNcblwKXCAgICBSZXBvcnQgc3RhdGlzdGljcyBvbiB0aGUgcmVwb3J0ZWQgaXNzdWVzLlxuXApcICAtaCAtaGVscCAtLWhlbHAgLXVzYWdlIC0/XG5cClwgICAgU2hvdyB0aGlzIG1lc3NhZ2UuXG5cClxuXApUaGUgZm9sbG93aW5nIGphdmFjIG9wdGlvbnMgYXJlIGFsc28gc3VwcG9ydGVkXG5cClwgIC1ib290Y2xhc3NwYXRoLCAtY2xhc3NwYXRoLCAtY3AsIC1zb3VyY2VwYXRoLCAtWG1heGVycnMsIC1YbWF4d2FybnNcblwKXG5cClRvIHJ1biBkb2NsaW50IG9uIHBhcnQgb2YgYSBwcm9qZWN0LCBwdXQgdGhlIGNvbXBpbGVkIGNsYXNzZXMgZm9yIHlvdXJcblwKcHJvamVjdCBvbiB0aGUgY2xhc3NwYXRoIChvciBib290Y2xhc3NwYXRoKSwgdGhlbiBzcGVjaWZ5IHRoZSBzb3VyY2UgZmlsZXNcblwKdG8gYmUgY2hlY2tlZCBvbiB0aGUgY29tbWFuZCBsaW5lLgpQSwMECgAACAAABjupSqref/SvMAAArzAAADUAAABjb20vc3VuL3Rvb2xzL2RvY2xpbnQvcmVzb3VyY2VzL2RvY2xpbnRfamEucHJvcGVydGllcyMKIyBDb3B5cmlnaHQgKGMpIDIwMTIsIDIwMTcsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiMgRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgojCiMgVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKIyB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwojIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwojIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKIyBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KIwojIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAojIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgojIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQojIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiMgYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KIwojIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KIyAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiMgSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgojCiMgUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKIyBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiMgcXVlc3Rpb25zLgojCgpkYy5hbmNob3IuYWxyZWFkeS5kZWZpbmVkID0gXHUzMEEyXHUzMEYzXHUzMEFCXHUzMEZDXHUzMDRDXHUzMDU5XHUzMDY3XHUzMDZCXHU1QjlBXHU3RkE5XHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5OiAiezB9IgpkYy5hbmNob3IudmFsdWUubWlzc2luZyA9IFx1MzBBMlx1MzBGM1x1MzBBQlx1MzBGQ1x1MzA2Qlx1NTAyNFx1MzA0Q1x1NjMwN1x1NUI5QVx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1Qlx1MzA5MwpkYy5hdHRyLmxhY2tzLnZhbHVlID0gXHU1QzVFXHU2MDI3XHUzMDZCXHU1MDI0XHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzCmRjLmF0dHIubm90Lm51bWJlciA9IFx1NUM1RVx1NjAyN1x1NTAyNFx1MzA0Q1x1NjU3MFx1NUI1N1x1MzA2N1x1MzA2Rlx1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5MwpkYy5hdHRyLm5vdC5zdXBwb3J0ZWQuaHRtbDQgPSBcdTVDNUVcdTYwMjdcdTMwNkZIVE1MNFx1MzA2N1x1MzA2Rlx1MzBCNVx1MzBERFx1MzBGQ1x1MzBDOFx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1Qlx1MzA5MzogezB9CmRjLmF0dHIubm90LnN1cHBvcnRlZC5odG1sNSA9IFx1NUM1RVx1NjAyN1x1MzA2RkhUTUw1XHUzMDY3XHUzMDZGXHUzMEI1XHUzMEREXHUzMEZDXHUzMEM4XHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDVCXHUzMDkzOiB7MH0KZGMuYXR0ci5vYnNvbGV0ZSA9IFx1NUM1RVx1NjAyN1x1MzA2Rlx1NUVDM1x1NkI2Mlx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1OTogezB9CmRjLmF0dHIub2Jzb2xldGUudXNlLmNzcyA9IFx1NUM1RVx1NjAyN1x1MzA2Rlx1NUVDM1x1NkI2Mlx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1OVx1MzAwMlx1MzA0Qlx1MzA4Rlx1MzA4QVx1MzA2QkNTU1x1MzA5Mlx1NEY3Rlx1NzUyOFx1MzA1N1x1MzA2Nlx1MzA0Rlx1MzA2MFx1MzA1NVx1MzA0NDogezB9CmRjLmF0dHIucmVwZWF0ZWQgPSBcdTdFNzBcdTMwOEFcdThGRDRcdTMwNTVcdTMwOENcdTMwNUZcdTVDNUVcdTYwMjc6IHswfQpkYy5hdHRyLnRhYmxlLmJvcmRlci5odG1sNSA9IFx1ODg2OFx1MzA2RVx1NUM1RVx1NjAyN1x1MzBEQ1x1MzBGQ1x1MzBDMFx1MzBGQ1x1MzA2RiIiXHUzMDdFXHUzMDVGXHUzMDZGIjEiXHUzMDZFXHUzMDdGXHU1M0Q3XHUzMDUxXHU1MTY1XHUzMDhDXHUzMDdFXHUzMDU5XHUzMDAyXHUzMDRCXHUzMDhGXHUzMDhBXHUzMDZCQ1NTXHUzMDkyXHU0RjdGXHU3NTI4XHUzMDU3XHUzMDY2XHUzMDRGXHUzMDYwXHUzMDU1XHUzMDQ0OiB7MH0KZGMuYXR0ci51bmtub3duID0gXHU0RTBEXHU2NjBFXHUzMDZBXHU1QzVFXHU2MDI3OiB7MH0KZGMuYmFkLm9wdGlvbiA9IFx1NzEyMVx1NTJCOVx1MzA2QVx1MzBBQVx1MzBEN1x1MzBCN1x1MzBFN1x1MzBGMzogezB9CmRjLmJhZC52YWx1ZS5mb3Iub3B0aW9uID0gXHUzMEFBXHUzMEQ3XHUzMEI3XHUzMEU3XHUzMEYzXHUzMDZFXHU1MDI0XHUzMDRDXHU0RTBEXHU2QjYzXHUzMDY3XHUzMDU5OiB7MH0gezF9CmRjLmVtcHR5ID0gQHswfVx1MzA2RVx1OEFBQ1x1NjYwRVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5MwpkYy5lbnRpdHkuaW52YWxpZCA9IFx1NzEyMVx1NTJCOVx1MzA2QVx1MzBBOFx1MzBGM1x1MzBDNlx1MzBBM1x1MzBDNlx1MzBBMyZ7MH07CmRjLmV4Y2VwdGlvbi5ub3QudGhyb3duID0gXHU0RjhCXHU1OTE2XHUzMDRDXHUzMEI5XHUzMEVEXHUzMEZDXHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDVCXHUzMDkzOiB7MH0KZGMuaW52YWxpZC5hbmNob3IgPSBcdTMwQTJcdTMwRjNcdTMwQUJcdTMwRkNcdTMwNkVcdTU0MERcdTUyNERcdTMwNENcdTcxMjFcdTUyQjlcdTMwNjdcdTMwNTk6ICJ7MH0iCmRjLmludmFsaWQucGFyYW0gPSBcdTcxMjFcdTUyQjlcdTMwNkFAcGFyYW1cdTMwNkVcdTRGN0ZcdTc1MjgKZGMuaW52YWxpZC5wcm92aWRlcyA9IFx1NzEyMVx1NTJCOVx1MzA2QUBwcm92aWRlc1x1MzA2RVx1NEY3Rlx1NzUyOApkYy5pbnZhbGlkLnJldHVybiA9IFx1NzEyMVx1NTJCOVx1MzA2QUByZXR1cm5cdTMwNkVcdTRGN0ZcdTc1MjgKZGMuaW52YWxpZC50aHJvd3MgPSBcdTcxMjFcdTUyQjlcdTMwNkFAdGhyb3dzXHUzMDZFXHU0RjdGXHU3NTI4CmRjLmludmFsaWQudXNlcyA9IFx1NzEyMVx1NTJCOVx1MzA2QUB1c2VzXHUzMDZFXHU0RjdGXHU3NTI4CmRjLmludmFsaWQudXJpID0gXHU3MTIxXHU1MkI5XHUzMDZBVVJJOiAiezB9IgpkYy5taXNzaW5nLmNvbW1lbnQgPSBcdTMwQjNcdTMwRTFcdTMwRjNcdTMwQzhcdTMwNkFcdTMwNTcKZGMubWlzc2luZy5wYXJhbSA9IHswfVx1MzA2RUBwYXJhbVx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5MwpkYy5taXNzaW5nLnJldHVybiA9IEByZXR1cm5cdTMwNENcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTMKZGMubWlzc2luZy50aHJvd3MgPSB7MH1cdTMwNkVAdGhyb3dzXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzCmRjLm5vLmFsdC5hdHRyLmZvci5pbWFnZSA9IFx1MzBBNFx1MzBFMVx1MzBGQ1x1MzBCOFx1MzA2RSJhbHQiXHU1QzVFXHU2MDI3XHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzCmRjLm5vLnN1bW1hcnkub3IuY2FwdGlvbi5mb3IudGFibGU9XHU4ODY4XHUzMDZFXHU4OTgxXHU3RDA0XHUzMDdFXHUzMDVGXHUzMDZGXHUzMEFEXHUzMEUzXHUzMEQ3XHUzMEI3XHUzMEU3XHUzMEYzXHUzMDRDXHUzMDQyXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzCmRjLnBhcmFtLm5hbWUubm90LmZvdW5kID0gQHBhcmFtIG5hbWVcdTMwNENcdTg5OEJcdTMwNjRcdTMwNEJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTMKZGMucmVmLm5vdC5mb3VuZCA9IFx1NTNDMlx1NzE2N1x1MzA0Q1x1ODk4Qlx1MzA2NFx1MzA0Qlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5MwpkYy5zZXJ2aWNlLm5vdC5mb3VuZCA9IFx1MzBCNVx1MzBGQ1x1MzBEM1x1MzBCOVx1MzBGQlx1MzBCRlx1MzBBNFx1MzBEN1x1MzA0Q1x1ODk4Qlx1MzA2NFx1MzA0Qlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5MwpkYy50YWcuY29kZS53aXRoaW4uY29kZSA9IDxjb2RlPlx1NTE4NVx1MzA2RSd7QGNvZGUnfQpkYy50YWcuZW1wdHkgPSBcdTdBN0FcdTMwNkU8ezB9Plx1MzBCRlx1MzBCMApkYy50YWcuZW5kLm5vdC5wZXJtaXR0ZWQgPSBcdTcxMjFcdTUyQjlcdTMwNkFcdTdENDJcdTRFODZcdTMwQkZcdTMwQjA6IDwvezB9PgpkYy50YWcuZW5kLnVuZXhwZWN0ZWQgPSBcdTRFODhcdTY3MUZcdTMwNTdcdTMwNkFcdTMwNDRcdTdENDJcdTRFODZcdTMwQkZcdTMwQjA6IDwvezB9PgpkYy50YWcuaGVhZGVyLnNlcXVlbmNlLjEgPSBcdTMwRDhcdTMwQzNcdTMwQzBcdTMwRkNcdTMwNkVcdTYzMDdcdTVCOUFcdTk4MDZcdTVFOEZcdTMwNENcdTZCNjNcdTMwNTdcdTMwNEZcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTM6IDx7MH0+CmRjLnRhZy5oZWFkZXIuc2VxdWVuY2UuMiA9IFx1MzBEOFx1MzBDM1x1MzBDMFx1MzBGQ1x1MzA2RVx1NjMwN1x1NUI5QVx1OTgwNlx1NUU4Rlx1MzA0Q1x1NkI2M1x1MzA1N1x1MzA0Rlx1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5MzogPHswfT4KZGMudGFnLm5lc3RlZC5ub3QuYWxsb3dlZD1cdTMwQ0RcdTMwQjlcdTMwQzhcdTMwNTdcdTMwNUZcdTMwQkZcdTMwQjBcdTMwNkZcdTRGN0ZcdTc1MjhcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTM6IDx7MH0+CmRjLnRhZy5ub3QuYWxsb3dlZC5oZXJlID0gXHUzMDUzXHUzMDUzXHUzMDY3XHUzMDZGXHUzMEJGXHUzMEIwXHUzMDkyXHU0RjdGXHU3NTI4XHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzOiA8ezB9PgpkYy50YWcubm90LmFsbG93ZWQgPSBcdTMwQzlcdTMwQURcdTMwRTVcdTMwRTFcdTMwRjNcdTMwQzhcdTMwRkJcdTMwQjNcdTMwRTFcdTMwRjNcdTMwQzhcdTMwNjdcdTRGN0ZcdTc1MjhcdTMwNjdcdTMwNERcdTMwNkFcdTMwNDRcdTg5ODFcdTdEMjBcdTMwNjdcdTMwNTk6IDx7MH0+CmRjLnRhZy5ub3QuYWxsb3dlZC5pbmxpbmUuZWxlbWVudCA9IFx1MzBBNFx1MzBGM1x1MzBFOVx1MzBBNFx1MzBGM1x1ODk4MVx1N0QyMDx7MX0+XHU1MTg1XHUzMDY3XHU0RjdGXHU3NTI4XHUzMDY3XHUzMDREXHUzMDZBXHUzMDQ0XHUzMEQ2XHUzMEVEXHUzMEMzXHUzMEFGXHU4OTgxXHU3RDIwXHUzMDY3XHUzMDU5OiB7MH0KZGMudGFnLm5vdC5hbGxvd2VkLmlubGluZS50YWcgPSBAezF9XHU1MTg1XHUzMDY3XHU0RjdGXHU3NTI4XHUzMDY3XHUzMDREXHUzMDZBXHUzMDQ0XHUzMEQ2XHUzMEVEXHUzMEMzXHUzMEFGXHU4OTgxXHU3RDIwXHUzMDY3XHUzMDU5OiB7MH0KZGMudGFnLm5vdC5hbGxvd2VkLmlubGluZS5vdGhlciA9IFx1MzA1M1x1MzA1M1x1MzA2N1x1MzA2Rlx1MzBENlx1MzBFRFx1MzBDM1x1MzBBRlx1ODk4MVx1N0QyMFx1MzA5Mlx1NEY3Rlx1NzUyOFx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1Qlx1MzA5MzogezB9CmRjLnRhZy5ub3QuY2xvc2VkPSBcdTg5ODFcdTdEMjBcdTMwNENcdTk1ODlcdTMwNThcdTMwODlcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNUJcdTMwOTM6IHswfQpkYy50YWcucC5pbi5wcmU9IDxwcmU+XHU4OTgxXHU3RDIwXHU1MTg1XHUzMDY3XHU0RTg4XHU2NzFGXHUzMDU3XHUzMDZBXHUzMDQ0PHA+XHUzMDRDXHU0RjdGXHU3NTI4XHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDU5CmRjLnRhZy5yZXF1aXJlcy5oZWFkaW5nID0gPC97MH0+XHUzMDZFXHU4OThCXHU1MUZBXHUzMDU3XHUzMDRDXHU4OThCXHUzMDY0XHUzMDRCXHUzMDhBXHUzMDdFXHUzMDVCXHUzMDkzCmRjLnRhZy5zZWxmLmNsb3NpbmcgPSBcdTgxRUFcdTVERjFcdTdENDJcdTRFODZcdTg5ODFcdTdEMjBcdTMwNkZcdTRGN0ZcdTc1MjhcdTMwNjdcdTMwNERcdTMwN0VcdTMwNUJcdTMwOTMKZGMudGFnLnN0YXJ0LnVubWF0Y2hlZCA9IFx1N0Q0Mlx1NEU4Nlx1MzBCRlx1MzBCMFx1MzA0Q1x1MzA0Mlx1MzA4QVx1MzA3RVx1MzA1Qlx1MzA5MzogPC97MH0+CmRjLnRhZy51bmtub3duID0gXHU0RTBEXHU2NjBFXHUzMDZBXHUzMEJGXHUzMEIwOiB7MH0KZGMudGFnLm5vdC5zdXBwb3J0ZWQgPSBcdTMwQkZcdTMwQjBcdTMwNkZcdTMwMDFcdTc1MUZcdTYyMTBcdTZFMDhIVE1MXHUzMEQwXHUzMEZDXHUzMEI4XHUzMEU3XHUzMEYzXHUzMDY3XHUzMDZGXHUzMEI1XHUzMEREXHUzMEZDXHUzMEM4XHUzMDU1XHUzMDhDXHUzMDY2XHUzMDQ0XHUzMDdFXHUzMDVCXHUzMDkzOiB7MH0KZGMudGV4dC5ub3QuYWxsb3dlZCA9IDx7MH0+XHU4OTgxXHU3RDIwXHUzMDY3XHUzMDZGXHUzMEM2XHUzMEFEXHUzMEI5XHUzMEM4XHUzMDkyXHU0RjdGXHU3NTI4XHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzCmRjLnR5cGUuYXJnLm5vdC5hbGxvd2VkID0gXHU1NzhCXHU1RjE1XHU2NTcwXHUzMDZGXHUzMDUzXHUzMDUzXHUzMDY3XHUzMDZGXHU0RjdGXHU3NTI4XHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzCmRjLnVuZXhwZWN0ZWQuY29tbWVudD1cdTMwQzlcdTMwQURcdTMwRTVcdTMwRTFcdTMwRjNcdTMwQzhcdTMwRkJcdTMwQjNcdTMwRTFcdTMwRjNcdTMwQzhcdTMwNkZcdTMwNTNcdTMwNTNcdTMwNjdcdTMwNkZcdTVGQzVcdTg5ODFcdTMwNDJcdTMwOEFcdTMwN0VcdTMwNUJcdTMwOTMKZGMudmFsdWUubm90LmFsbG93ZWQuaGVyZT0ne0B2YWx1ZX0nXHUzMDZGXHUzMDUzXHUzMDUzXHUzMDY3XHUzMDZGXHU0RjdGXHU3NTI4XHUzMDY3XHUzMDREXHUzMDdFXHUzMDVCXHUzMDkzCmRjLnZhbHVlLm5vdC5hLmNvbnN0YW50PVx1NTAyNFx1MzA0Q1x1NUI5QVx1NjU3MFx1MzA5Mlx1NTNDMlx1NzE2N1x1MzA1N1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1Qlx1MzA5MwoKZGMubWFpbi5pb2Vycm9yPUlPXHUzMEE4XHUzMEU5XHUzMEZDOiB7MH0KZGMubWFpbi5uby5maWxlcy5naXZlbj1cdTMwRDVcdTMwQTFcdTMwQTRcdTMwRUJcdTMwNENcdTYzMDdcdTVCOUFcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwN0VcdTMwNUJcdTMwOTMKZGMubWFpbi51c2FnZT1cdTRGN0ZcdTc1MjhcdTY1QjlcdTZDRDU6XG4gICAgZG9jbGludCBbb3B0aW9uc10gc291cmNlLWZpbGVzLi4uXG5cblx1MzBBQVx1MzBEN1x1MzBCN1x1MzBFN1x1MzBGMzpcbiAgLVhtc2dzICBcbiAgICAtWG1zZ3M6YWxsXHUzMDY4XHU1NDBDXHUzMDU4XG4gIC1YbXNnczp2YWx1ZXNcbiAgICBcdTMwQzFcdTMwQTdcdTMwQzNcdTMwQUZcdTMwNTlcdTMwOEJcdTU1NEZcdTk4NENcdTMwNkVcdTMwQUJcdTMwQzZcdTMwQjRcdTMwRUFcdTMwOTJcdTYzMDdcdTVCOUFcdTMwNTdcdTMwN0VcdTMwNTlcdTMwMDJcdTMwNTNcdTMwNTNcdTMwNjdcdTMwNkUnJ3ZhbHVlcycnXHUzMDZGXHUzMDAxXG4gICAgXHUzMEFCXHUzMEYzXHUzMERFXHUzMDY3XHU1MzNBXHU1MjA3XHUzMDg5XHUzMDhDXHUzMDVGXHU2QjIxXHUzMDZFXHU1MDI0XHUzMDZFXHUzMEVBXHUzMEI5XHUzMEM4XHUzMDY3XHUzMDU5OlxuICAgICAgcmVmZXJlbmNlICAgICAgSmF2YVx1MzBCRFx1MzBGQ1x1MzBCOVx1MzBGQlx1MzBCM1x1MzBGQ1x1MzBDOVx1ODk4MVx1N0QyMFx1MzA3OFx1MzA2RVx1NEUwRFx1NkI2M1x1MzA2QVx1NTNDMlx1NzE2N1x1MzA5Mlx1NTQyQlx1MzA4MFx1MzBCM1x1MzBFMVx1MzBGM1x1MzBDOFx1MzA2RVxuICAgICAgICAgICAgICAgICAgICAgXHU1ODM0XHU2MjQwXHUzMDkyXHU4ODY4XHU3OTNBXHUzMDU3XHUzMDdFXHUzMDU5XG4gICAgICBzeW50YXggICAgICAgICBcdTMwQjNcdTMwRTFcdTMwRjNcdTMwQzhcdTUxODVcdTMwNkVcdTU3RkFcdTY3MkNcdTY5Q0JcdTY1ODdcdTMwQThcdTMwRTlcdTMwRkNcdTMwOTJcdTg4NjhcdTc5M0FcdTMwNTdcdTMwN0VcdTMwNTlcbiAgICAgIGh0bWwgICAgICAgICAgIEhUTUxcdTMwQkZcdTMwRDZcdTMwNEFcdTMwODhcdTMwNzNcdTVDNUVcdTYwMjdcdTMwNkVcdTU1NEZcdTk4NENcdTMwOTJcdTg4NjhcdTc5M0FcdTMwNTdcdTMwN0VcdTMwNTlcbiAgICAgIGFjY2Vzc2liaWxpdHkgIFx1MzBBMlx1MzBBRlx1MzBCQlx1MzBCN1x1MzBEM1x1MzBFQVx1MzBDNlx1MzBBM1x1MzA2RVx1NTU0Rlx1OTg0Q1x1MzA5Mlx1ODg2OFx1NzkzQVx1MzA1N1x1MzA3RVx1MzA1OVxuICAgICAgbWlzc2luZyAgICAgICAgXHU2QjIwXHU4NDNEXHUzMDU3XHUzMDY2XHUzMDQ0XHUzMDhCXHUzMEM5XHUzMEFEXHUzMEU1XHUzMEUxXHUzMEYzXHUzMEM4XHUzMDZFXHU1NTRGXHU5ODRDXHUzMDkyXHU4ODY4XHU3OTNBXHUzMDU3XHUzMDdFXHUzMDU5XG4gICAgICBhbGwgICAgICAgICAgICBcdTUyNERcdThGRjBcdTMwNkVcdTMwNTlcdTMwNzlcdTMwNjZcbiAgICBcdTMwNTNcdTMwOENcdTMwOTJcdTU0MjZcdTVCOUFcdTMwNTlcdTMwOEJcdTMwNkJcdTMwNkZcdTMwMDFcdTUwMjRcdTMwNkVcdTUyNERcdTMwNkInJy0nJ1x1MzA5Mlx1NjMwN1x1NUI5QVx1MzA1N1x1MzA3RVx1MzA1OVxuICAgIFx1MzBBQlx1MzBDNlx1MzBCNFx1MzBFQVx1MzA2Rlx1MzAwMVx1NkIyMVx1MzA2RVx1MzA0NFx1MzA1QVx1MzA4Q1x1MzA0Qlx1MzA2N1x1NEZFRVx1OThGRVx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1OTpcbiAgICAgIC9wdWJsaWMgL3Byb3RlY3RlZCAvcGFja2FnZSAvcHJpdmF0ZVxuICAgIFx1NkI2M1x1MzA2RVx1MzBBQlx1MzBDNlx1MzBCNFx1MzBFQSgnJy0nJ1x1MzA2N1x1NTlDQlx1MzA3RVx1MzA4OVx1MzA2QVx1MzA0NClcdTMwNkVcdTU4MzRcdTU0MDhcbiAgICBcdTRGRUVcdTk4RkVcdTVCNTBcdTMwNkZcdTMwMDFcdTMwNURcdTMwNkVcdTMwQTJcdTMwQUZcdTMwQkJcdTMwQjlcdTMwRkJcdTMwRUNcdTMwRDlcdTMwRUJcdTRFRTVcdTRFMEFcdTMwNkJcdTkwNjlcdTc1MjhcdTMwNTVcdTMwOENcdTMwN0VcdTMwNTlcdTMwMDJcbiAgICBcdThDQTBcdTMwNkVcdTMwQUJcdTMwQzZcdTMwQjRcdTMwRUEoJyctJydcdTMwNjdcdTU5Q0JcdTMwN0VcdTMwOEIpXHUzMDZFXHU1ODM0XHU1NDA4XG4gICAgXHU0RkVFXHU5OEZFXHU1QjUwXHUzMDZGXHUzMDAxXHUzMDVEXHUzMDZFXHUzMEEyXHUzMEFGXHUzMEJCXHUzMEI5XHUzMEZCXHUzMEVDXHUzMEQ5XHUzMEVCXHU0RUU1XHU0RTBCXHUzMDZCXHU5MDY5XHU3NTI4XHUzMDU1XHUzMDhDXHUzMDdFXHUzMDU5XHUzMDAyXG4gICAgXHU0RkVFXHU5OEZFXHU1QjUwXHUzMDRDXHUzMDZBXHUzMDQ0XHU1ODM0XHU1NDA4XHUzMDAxXHUzMEFCXHUzMEM2XHUzMEI0XHUzMEVBXHUzMDZGXHUzMDU5XHUzMDc5XHUzMDY2XHUzMDZFXHUzMEEyXHUzMEFGXHUzMEJCXHUzMEI5XHUzMEZCXHUzMEVDXHUzMEQ5XHUzMEVCXHUzMDZCXG4gICAgXHU5MDY5XHU3NTI4XHUzMDU1XHUzMDhDXHUzMDdFXHUzMDU5XHUzMDAyXG4gICAgXHU0RjhCOiAtWG1zZ3M6YWxsLC1zeW50YXgvcHJpdmF0ZVxuICAgIFx1MzA1M1x1MzA2RVx1NTgzNFx1NTQwOFx1MzAwMXByaXZhdGVcdTMwRTFcdTMwQkRcdTMwQzNcdTMwQzlcdTMwNkVkb2NcdTMwQjNcdTMwRTFcdTMwRjNcdTMwQzhcdTUxODVcdTMwNkVcdTY5Q0JcdTY1ODdcdTMwQThcdTMwRTlcdTMwRkNcdTMwOTJcdTk2NjRcdTMwNERcdTMwMDFcbiAgICBcdTMwNTlcdTMwNzlcdTMwNjZcdTMwNkVcdTMwRTFcdTMwQzNcdTMwQkJcdTMwRkNcdTMwQjhcdTMwNENcdTY3MDlcdTUyQjlcdTUzMTZcdTMwNTVcdTMwOENcdTMwN0VcdTMwNTlcdTMwMDJcbiAgICAtWG1zZ3NcdTMwQUFcdTMwRDdcdTMwQjdcdTMwRTdcdTMwRjNcdTMwNENcdTYzMDdcdTVCOUFcdTMwNTVcdTMwOENcdTMwNjZcdTMwNDRcdTMwNkFcdTMwNDRcdTU4MzRcdTU0MDhcdTMwMDFcdTMwQzdcdTMwRDVcdTMwQTlcdTMwRUJcdTMwQzhcdTMwNkZcdTMwMDFcbiAgICAtWG1zZ3M6YWxsL3Byb3RlY3RlZFx1MzA2OFx1NTQwQ1x1N0I0OVx1MzA2Qlx1MzA2QVx1MzA4QVx1MzAwMVx1MzA1M1x1MzA4Q1x1MzA2RlxuICAgIFx1MzA1OVx1MzA3OVx1MzA2Nlx1MzA2RVx1MzBFMVx1MzBDM1x1MzBCQlx1MzBGQ1x1MzBCOFx1MzA0Q1x1MzAwMXByb3RlY3RlZFx1MzA0QVx1MzA4OFx1MzA3M3B1YmxpY1x1MzA2RVx1NUJBM1x1OEEwMFx1MzA2RVx1MzA3Rlx1MzA2Qlx1NTgzMVx1NTQ0QVx1MzA1NVx1MzA4Q1x1MzA4Qlx1MzA1M1x1MzA2OFx1MzA5MlxuICAgIFx1NjEwRlx1NTQ3M1x1MzA1N1x1MzA3RVx1MzA1OVx1MzAwMlxuICAtWGNoZWNrUGFja2FnZTo8cGFja2FnZXM+XG4gICAgXHU3Mjc5XHU1QjlBXHUzMDZFXHUzMEQxXHUzMEMzXHUzMEIxXHUzMEZDXHUzMEI4XHUzMDZFXHUzMEMxXHUzMEE3XHUzMEMzXHUzMEFGXHUzMDkyXHU2NzA5XHU1MkI5XHUzMDdFXHUzMDVGXHUzMDZGXHU3MTIxXHU1MkI5XHUzMDZCXHUzMDU3XHUzMDdFXHUzMDU5XHUzMDAyXG4gICAgPHBhY2thZ2VzPlx1MzA2Rlx1MzBBQlx1MzBGM1x1MzBERVx1MzA2N1x1NTMzQVx1NTIwN1x1MzA4OVx1MzA4Q1x1MzA1Rlx1MzBEMVx1MzBDM1x1MzBCMVx1MzBGQ1x1MzBCOFx1NjMwN1x1NUI5QVx1NUI1MFx1MzA2RVx1MzBFQVx1MzBCOVx1MzBDOFx1MzA2N1x1MzA1OVx1MzAwMlxuICAgIFx1MzBEMVx1MzBDM1x1MzBCMVx1MzBGQ1x1MzBCOFx1NjMwN1x1NUI5QVx1NUI1MFx1MzA2Rlx1MzAwMVx1MzBEMVx1MzBDM1x1MzBCMVx1MzBGQ1x1MzBCOFx1MzA2RVx1NEZFRVx1OThGRVx1MzA1NVx1MzA4Q1x1MzA1Rlx1NTQwRFx1NTI0RFx1MzAwMVx1MzA3RVx1MzA1Rlx1MzA2RlxuICAgIFx1MzBEMVx1MzBDM1x1MzBCMVx1MzBGQ1x1MzBCOFx1NTQwRFx1MzA2RVx1NjNBNVx1OTgyRFx1OEY5RVx1MzA2RVx1NUY4Q1x1MzA2QicnLionJ1x1MzA5Mlx1NjMwN1x1NUI5QShcdTYzMDdcdTVCOUFcdTMwNTdcdTMwNUZcdTMwRDFcdTMwQzNcdTMwQjFcdTMwRkNcdTMwQjhcdTMwNkVcbiAgICBcClx1MzA1OVx1MzA3OVx1MzA2Nlx1MzA2RVx1MzBCNVx1MzBENlx1MzBEMVx1MzBDM1x1MzBCMVx1MzBGQ1x1MzBCOFx1MzA2Qlx1NjJFMVx1NUYzNSlcdTMwNTdcdTMwNUZcdTMwODJcdTMwNkVcdTMwNjdcdTMwNTlcdTMwMDJcdTMwRDFcdTMwQzNcdTMwQjFcdTMwRkNcdTMwQjhcdTYzMDdcdTVCOUFcdTVCNTBcdTMwNkVcdTUyNERcdTMwNkJcbiAgICAnJy0nJ1x1MzA5Mlx1NjMwN1x1NUI5QVx1MzA1OVx1MzA4Qlx1MzA2OFx1MzAwMVx1NjMwN1x1NUI5QVx1MzA1N1x1MzA1Rlx1MzBEMVx1MzBDM1x1MzBCMVx1MzBGQ1x1MzBCOFx1MzA2Qlx1OTVBMlx1MzA1OVx1MzA4Qlx1MzBDMVx1MzBBN1x1MzBDM1x1MzBBRlx1MzA5Mlx1NzEyMVx1NTJCOVx1MzA2Qlx1MzA2N1x1MzA0RFx1MzA3RVx1MzA1OVx1MzAwMlxuICAtc3RhdHNcbiAgICBcdTU4MzFcdTU0NEFcdTMwNTVcdTMwOENcdTMwNUZcdTU1NEZcdTk4NENcdTMwNkJcdTVCRkVcdTMwNTdcdTMwNjZcdTdENzFcdThBMDhcdTMwOTJcdTU4MzFcdTU0NEFcdTMwNTdcdTMwN0VcdTMwNTlcdTMwMDJcbiAgLWggLWhlbHAgLS1oZWxwIC11c2FnZSAtP1xuICAgIFx1MzA1M1x1MzA2RVx1MzBFMVx1MzBDM1x1MzBCQlx1MzBGQ1x1MzBCOFx1MzA0Q1x1ODg2OFx1NzkzQVx1MzA1NVx1MzA4Q1x1MzA3RVx1MzA1OVx1MzAwMlxuXG5cdTZCMjFcdTMwNkVqYXZhY1x1MzBBQVx1MzBEN1x1MzBCN1x1MzBFN1x1MzBGM1x1MzA4Mlx1MzBCNVx1MzBERFx1MzBGQ1x1MzBDOFx1MzA1NVx1MzA4Q1x1MzA2Nlx1MzA0NFx1MzA3RVx1MzA1OVxuICAtYm9vdGNsYXNzcGF0aFx1MzAwMS1jbGFzc3BhdGhcdTMwMDEtY3BcdTMwMDEtc291cmNlcGF0aFx1MzAwMS1YbWF4ZXJyc1x1MzAwMS1YbWF4d2FybnNcblxuXHUzMEQ3XHUzMEVEXHUzMEI4XHUzMEE3XHUzMEFGXHUzMEM4XHUzMDZFXHU0RTAwXHU5MEU4XHUzMDZCXHU1QkZFXHUzMDU3XHUzMDY2ZG9jbGludFx1MzA5Mlx1NUI5Rlx1ODg0Q1x1MzA1OVx1MzA4Qlx1MzA2Qlx1MzA2Rlx1MzAwMVx1MzBEN1x1MzBFRFx1MzBCOFx1MzBBN1x1MzBBRlx1MzBDOFx1MzA2RVx1MzBCM1x1MzBGM1x1MzBEMVx1MzBBNFx1MzBFQlx1MzA1NVx1MzA4Q1x1MzA1Rlx1MzBBRlx1MzBFOVx1MzBCOVx1MzA5MlxuXHUzMEFGXHUzMEU5XHUzMEI5XHUzMEQxXHUzMEI5KFx1MzA3RVx1MzA1Rlx1MzA2Rlx1MzBENlx1MzBGQ1x1MzBDOFx1MzBGQlx1MzBBRlx1MzBFOVx1MzBCOVx1MzBEMVx1MzBCOSlcdTMwNkJcdTYzMDdcdTVCOUFcdTMwNTdcdTMwMDFcdTMwQjNcdTMwREVcdTMwRjNcdTMwQzlcdTg4NENcdTMwNjdcblx1MzBDMVx1MzBBN1x1MzBDM1x1MzBBRlx1MzA1OVx1MzA4Qlx1MzBCRFx1MzBGQ1x1MzBCOVx1MzBGQlx1MzBENVx1MzBBMVx1MzBBNFx1MzBFQlx1MzA5Mlx1NjMwN1x1NUI5QVx1MzA1N1x1MzA3RVx1MzA1OVx1MzAwMgpQSwMECgAACAAABjupSu7j+6PNIQAAzSEAADgAAABjb20vc3VuL3Rvb2xzL2RvY2xpbnQvcmVzb3VyY2VzL2RvY2xpbnRfemhfQ04ucHJvcGVydGllcyMKIyBDb3B5cmlnaHQgKGMpIDIwMTIsIDIwMTcsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiMgRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgojCiMgVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKIyB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwojIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwojIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKIyBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KIwojIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAojIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgojIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQojIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiMgYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KIwojIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KIyAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiMgSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgojCiMgUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKIyBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiMgcXVlc3Rpb25zLgojCgpkYy5hbmNob3IuYWxyZWFkeS5kZWZpbmVkID0gXHU5NTFBXHU1QjlBXHU3MEI5XHU1REYyXHU1QjlBXHU0RTQ5OiAiezB9IgpkYy5hbmNob3IudmFsdWUubWlzc2luZyA9IFx1NkNBMVx1NjcwOVx1NEUzQVx1OTUxQVx1NUI5QVx1NzBCOVx1NjMwN1x1NUI5QVx1NTAzQwpkYy5hdHRyLmxhY2tzLnZhbHVlID0gXHU1QzVFXHU2MDI3XHU3RjNBXHU1QzExXHU1MDNDCmRjLmF0dHIubm90Lm51bWJlciA9IFx1NUM1RVx1NjAyN1x1NTAzQ1x1NEUwRFx1NjYyRlx1NjU3MFx1NUI1NwpkYy5hdHRyLm5vdC5zdXBwb3J0ZWQuaHRtbDQgPSBcdTVDNUVcdTYwMjdcdTU3MjggSFRNTDQgXHU0RTJEXHU0RTBEXHU1M0Q3XHU2NTJGXHU2MzAxOiB7MH0KZGMuYXR0ci5ub3Quc3VwcG9ydGVkLmh0bWw1ID0gXHU1QzVFXHU2MDI3XHU1NzI4IEhUTUw1IFx1NEUyRFx1NEUwRFx1NTNEN1x1NjUyRlx1NjMwMTogezB9CmRjLmF0dHIub2Jzb2xldGUgPSBcdTVDNUVcdTYwMjdcdTVERjJcdThGQzdcdTY1RjY6IHswfQpkYy5hdHRyLm9ic29sZXRlLnVzZS5jc3MgPSBcdTVDNUVcdTYwMjdcdTVERjJcdThGQzdcdTY1RjYsIFx1OEJGN1x1NjUzOVx1NzUyOCBDU1M6IHswfQpkYy5hdHRyLnJlcGVhdGVkID0gXHU1QzVFXHU2MDI3XHU5MUNEXHU1OTBEOiB7MH0KZGMuYXR0ci50YWJsZS5ib3JkZXIuaHRtbDUgPSBcdTg4NjhcdTc2ODRcdTVDNUVcdTYwMjdcdThGQjlcdTY4NDZcdTUzRUFcdTYzQTVcdTUzRDcgIiIgXHU2MjE2ICIxIiwgXHU2NTM5XHU0RTNBXHU0RjdGXHU3NTI4IENTUzogezB9CmRjLmF0dHIudW5rbm93biA9IFx1NjcyQVx1NzdFNVx1NUM1RVx1NjAyNzogezB9CmRjLmJhZC5vcHRpb24gPSBcdTkwMDlcdTk4NzlcdTk1MTlcdThCRUY6IHswfQpkYy5iYWQudmFsdWUuZm9yLm9wdGlvbiA9IFx1OTAwOVx1OTg3OVx1NzY4NFx1NTAzQ1x1OTUxOVx1OEJFRjogezB9IHsxfQpkYy5lbXB0eSA9IEB7MH0gXHU2Q0ExXHU2NzA5XHU4QkY0XHU2NjBFCmRjLmVudGl0eS5pbnZhbGlkID0gXHU1QjlFXHU0RjUzICZ7MH07IFx1NjVFMFx1NjU0OApkYy5leGNlcHRpb24ubm90LnRocm93biA9IFx1NjcyQVx1NjI5Qlx1NTFGQVx1NUYwMlx1NUUzOFx1OTUxOVx1OEJFRjogezB9CmRjLmludmFsaWQuYW5jaG9yID0gXHU5NTFBXHU1QjlBXHU3MEI5XHU3Njg0XHU1NDBEXHU3OUYwXHU2NUUwXHU2NTQ4OiAiezB9IgpkYy5pbnZhbGlkLnBhcmFtID0gQHBhcmFtIFx1NzY4NFx1NzUyOFx1NkNENVx1NjVFMFx1NjU0OApkYy5pbnZhbGlkLnByb3ZpZGVzID0gQHByb3ZpZGVzIFx1NzY4NFx1NzUyOFx1NkNENVx1NjVFMFx1NjU0OApkYy5pbnZhbGlkLnJldHVybiA9IEByZXR1cm4gXHU3Njg0XHU3NTI4XHU2Q0Q1XHU2NUUwXHU2NTQ4CmRjLmludmFsaWQudGhyb3dzID0gQHRocm93cyBcdTc2ODRcdTc1MjhcdTZDRDVcdTY1RTBcdTY1NDgKZGMuaW52YWxpZC51c2VzID0gQHVzZXMgXHU3Njg0XHU3NTI4XHU2Q0Q1XHU2NUUwXHU2NTQ4CmRjLmludmFsaWQudXJpID0gVVJJIFx1NjVFMFx1NjU0ODogInswfSIKZGMubWlzc2luZy5jb21tZW50ID0gXHU2Q0ExXHU2NzA5XHU2Q0U4XHU5MUNBCmRjLm1pc3NpbmcucGFyYW0gPSB7MH1cdTZDQTFcdTY3MDkgQHBhcmFtCmRjLm1pc3NpbmcucmV0dXJuID0gXHU2Q0ExXHU2NzA5IEByZXR1cm4KZGMubWlzc2luZy50aHJvd3MgPSB7MH1cdTZDQTFcdTY3MDkgQHRocm93cwpkYy5uby5hbHQuYXR0ci5mb3IuaW1hZ2UgPSBcdTU2RkVcdTUwQ0ZcdTZDQTFcdTY3MDkgImFsdCIgXHU1QzVFXHU2MDI3CmRjLm5vLnN1bW1hcnkub3IuY2FwdGlvbi5mb3IudGFibGU9XHU4ODY4XHU2Q0ExXHU2NzA5XHU2OTgyXHU4OTgxXHU2MjE2XHU2ODA3XHU5ODk4CmRjLnBhcmFtLm5hbWUubm90LmZvdW5kID0gQHBhcmFtIG5hbWUgXHU2NzJBXHU2MjdFXHU1MjMwCmRjLnJlZi5ub3QuZm91bmQgPSBcdTYyN0VcdTRFMERcdTUyMzBcdTVGMTVcdTc1MjgKZGMuc2VydmljZS5ub3QuZm91bmQgPSBcdTYyN0VcdTRFMERcdTUyMzBcdTY3MERcdTUyQTFcdTdDN0JcdTU3OEIKZGMudGFnLmNvZGUud2l0aGluLmNvZGUgPSAne0Bjb2RlJ30gXHU1NzI4IDxjb2RlPiBcdTRFMkQKZGMudGFnLmVtcHR5ID0gPHswfT4gXHU2ODA3XHU4QkIwXHU0RTNBXHU3QTdBCmRjLnRhZy5lbmQubm90LnBlcm1pdHRlZCA9IFx1NjVFMFx1NjU0OFx1NzY4NFx1N0VEM1x1Njc1Rlx1NjgwN1x1OEJCMDogPC97MH0+CmRjLnRhZy5lbmQudW5leHBlY3RlZCA9IFx1NjEwRlx1NTkxNlx1NzY4NFx1N0VEM1x1Njc1Rlx1NjgwN1x1OEJCMDogPC97MH0+CmRjLnRhZy5oZWFkZXIuc2VxdWVuY2UuMSA9IFx1NEY3Rlx1NzUyOFx1NzY4NFx1NjgwN1x1OTg5OFx1OEQ4NVx1NTFGQVx1NUU4Rlx1NTIxNzogPHswfT4KZGMudGFnLmhlYWRlci5zZXF1ZW5jZS4yID0gXHU0RjdGXHU3NTI4XHU3Njg0XHU2ODA3XHU5ODk4XHU4RDg1XHU1MUZBXHU1RThGXHU1MjE3OiA8ezB9PgpkYy50YWcubmVzdGVkLm5vdC5hbGxvd2VkPVx1NEUwRFx1NTE0MVx1OEJCOFx1NEY3Rlx1NzUyOFx1NUQ0Q1x1NTk1N1x1NjgwN1x1OEJCMDogPHswfT4KZGMudGFnLm5vdC5hbGxvd2VkLmhlcmUgPSBcdTZCNjRcdTU5MDRcdTRFMERcdTUxNDFcdThCQjhcdTRGN0ZcdTc1MjhcdTY4MDdcdThCQjA6IDx7MH0+CmRjLnRhZy5ub3QuYWxsb3dlZCA9IFx1NjU4N1x1Njg2M1x1NkNFOFx1OTFDQVx1NEUyRFx1NEUwRFx1NTE0MVx1OEJCOFx1NEY3Rlx1NzUyOFx1NTE0M1x1N0QyMDogPHswfT4KZGMudGFnLm5vdC5hbGxvd2VkLmlubGluZS5lbGVtZW50ID0gXHU1MTg1XHU1RDRDXHU1MTQzXHU3RDIwIDx7MX0+IFx1NEUyRFx1NEUwRFx1NTE0MVx1OEJCOFx1NEY3Rlx1NzUyOFx1NTc1N1x1NTE0M1x1N0QyMDogezB9CmRjLnRhZy5ub3QuYWxsb3dlZC5pbmxpbmUudGFnID0gQHsxfSBcdTRFMkRcdTRFMERcdTUxNDFcdThCQjhcdTRGN0ZcdTc1MjhcdTU3NTdcdTUxNDNcdTdEMjA6IHswfQpkYy50YWcubm90LmFsbG93ZWQuaW5saW5lLm90aGVyID0gXHU2QjY0XHU1OTA0XHU0RTBEXHU1MTQxXHU4QkI4XHU0RjdGXHU3NTI4XHU1NzU3XHU1MTQzXHU3RDIwOiB7MH0KZGMudGFnLm5vdC5jbG9zZWQ9IFx1NTE0M1x1N0QyMFx1NjcyQVx1NTE3M1x1OTVFRDogezB9CmRjLnRhZy5wLmluLnByZT0gPHByZT4gXHU1MTQzXHU3RDIwXHU1MTg1XHU5MEU4XHU2MTBGXHU1OTE2XHU1NzMwXHU0RjdGXHU3NTI4XHU0RTg2IDxwPgpkYy50YWcucmVxdWlyZXMuaGVhZGluZyA9IFx1NjcyQVx1NjI3RVx1NTIzMCA8L3swfT4gXHU3Njg0XHU2ODA3XHU5ODk4CmRjLnRhZy5zZWxmLmNsb3NpbmcgPSBcdTRFMERcdTUxNDFcdThCQjhcdTRGN0ZcdTc1MjhcdTgxRUFcdTUxNzNcdTk1RURcdTUxNDNcdTdEMjAKZGMudGFnLnN0YXJ0LnVubWF0Y2hlZCA9IFx1N0YzQVx1NUMxMVx1N0VEM1x1Njc1Rlx1NjgwN1x1OEJCMDogPC97MH0+CmRjLnRhZy51bmtub3duID0gXHU2NzJBXHU3N0U1XHU2ODA3XHU4QkIwOiB7MH0KZGMudGFnLm5vdC5zdXBwb3J0ZWQgPSBcdTY4MDdcdThCQjBcdTU3MjhcdTc1MUZcdTYyMTBcdTc2ODQgSFRNTCBcdTcyNDhcdTY3MkNcdTRFMkRcdTRFMERcdTUzRDdcdTY1MkZcdTYzMDE6IHswfQpkYy50ZXh0Lm5vdC5hbGxvd2VkID0gPHswfT4gXHU1MTQzXHU3RDIwXHU0RTJEXHU0RTBEXHU1MTQxXHU4QkI4XHU0RjdGXHU3NTI4XHU2NTg3XHU2NzJDCmRjLnR5cGUuYXJnLm5vdC5hbGxvd2VkID0gXHU2QjY0XHU1OTA0XHU0RTBEXHU1MTQxXHU4QkI4XHU0RjdGXHU3NTI4XHU3QzdCXHU1NzhCXHU1M0MyXHU2NTcwCmRjLnVuZXhwZWN0ZWQuY29tbWVudD1cdTZCNjRcdTU5MDRcdTY3MkFcdTk4ODRcdTY3MUZcdTY1ODdcdTY4NjNcdTZDRThcdTkxQ0EKZGMudmFsdWUubm90LmFsbG93ZWQuaGVyZT1cdTZCNjRcdTU5MDRcdTRFMERcdTUxNDFcdThCQjhcdTRGN0ZcdTc1MjggJ3tAdmFsdWV9JwpkYy52YWx1ZS5ub3QuYS5jb25zdGFudD1cdTUwM0NcdTRFMERcdTVGMTVcdTc1MjhcdTVFMzhcdTkxQ0YKCmRjLm1haW4uaW9lcnJvcj1JTyBcdTk1MTlcdThCRUY6IHswfQpkYy5tYWluLm5vLmZpbGVzLmdpdmVuPVx1NjcyQVx1NjMwN1x1NUI5QVx1NjU4N1x1NEVGNgpkYy5tYWluLnVzYWdlPVx1NzUyOFx1NkNENTpcbiAgICBkb2NsaW50IFtvcHRpb25zXSBzb3VyY2UtZmlsZXMuLi5cblxuXHU5MDA5XHU5ODc5OlxuICAtWG1zZ3MgIFxuICAgIFx1NEUwRSAtWG1zZ3M6YWxsIFx1NzZGOFx1NTQwQ1xuICAtWG1zZ3M6dmFsdWVzXG4gICAgXHU2MzA3XHU1QjlBXHU4OTgxXHU2OEMwXHU2N0U1XHU3Njg0XHU5NUVFXHU5ODk4XHU3Njg0XHU3QzdCXHU1MjJCLCBcdTUxNzZcdTRFMkQgJyd2YWx1ZXMnJ1xuICAgIFx1NjYyRlx1NEVGQlx1NjEwRlx1NEVFNVx1NEUwQlx1NTE4NVx1NUJCOVx1NzY4NFx1NEVFNVx1OTAxN1x1NTNGN1x1NTIwNlx1OTY5NFx1NzY4NFx1NTIxN1x1ODg2ODpcbiAgICAgIHJlZmVyZW5jZSAgICAgIFx1NjYzRVx1NzkzQVx1NTMwNVx1NTQyQlx1NUJGOSBKYXZhIFx1NkU5MFx1NEVFM1x1NzgwMVx1NTE0M1x1N0QyMFxuICAgICAgICAgICAgICAgICAgICAgXHU5NTE5XHU4QkVGXHU1RjE1XHU3NTI4XHU3Njg0XHU2Q0U4XHU5MUNBXHU3Njg0XHU0RjREXHU3RjZFXG4gICAgICBzeW50YXggICAgICAgICBcdTY2M0VcdTc5M0FcdTZDRThcdTkxQ0FcdTRFMkRcdTc2ODRcdTU3RkFcdTY3MkNcdThCRURcdTZDRDVcdTk1MTlcdThCRUZcbiAgICAgIGh0bWwgICAgICAgICAgIFx1NjYzRVx1NzkzQSBIVE1MIFx1NjgwN1x1OEJCMFx1NTQ4Q1x1NUM1RVx1NjAyN1x1OTVFRVx1OTg5OFxuICAgICAgYWNjZXNzaWJpbGl0eSAgXHU2NjNFXHU3OTNBXHU1M0VGXHU4QkJGXHU5NUVFXHU2MDI3XHU3Njg0XHU5NUVFXHU5ODk4XG4gICAgICBtaXNzaW5nICAgICAgICBcdTY2M0VcdTc5M0FcdTdGM0FcdTVDMTFcdTY1ODdcdTY4NjNcdTc2ODRcdTk1RUVcdTk4OThcbiAgICAgIGFsbCAgICAgICAgICAgIFx1NjI0MFx1NjcwOVx1NEVFNVx1NEUwQVx1NTE4NVx1NUJCOVxuICAgIFx1NTcyOFx1NTAzQ1x1NEU0Qlx1NTI0RFx1NEY3Rlx1NzUyOCAnJy0nJyBcdTUzRUZcdTRGN0ZcdTc1MjhcdTUxNzZcdTUzQ0RcdTUwM0NcbiAgICBcdTUzRUZcdTRFRTVcdTRGN0ZcdTc1MjhcdTRFRTVcdTRFMEJcdTRFMDBcdTk4NzlcdTY3NjVcdTk2NTBcdTVCOUFcdTdDN0JcdTUyMkI6XG4gICAgICAvcHVibGljIC9wcm90ZWN0ZWQgL3BhY2thZ2UgL3ByaXZhdGVcbiAgICBcdTVCRjlcdTRFOEVcdTZCNjNcdTdDN0JcdTUyMkIgKFx1NEUwRFx1NEVFNSAnJy0nJyBcdTVGMDBcdTU5MzQpXG4gICAgXHU5NjUwXHU1QjlBXHU3QjI2XHU5MDAyXHU3NTI4XHU0RThFXHU4QkU1XHU4QkJGXHU5NUVFXHU3RUE3XHU1MjJCXHU1M0NBXHU2NkY0XHU5QUQ4XHU3RUE3XHU1MjJCXHUzMDAyXG4gICAgXHU1QkY5XHU0RThFXHU4RDFGXHU3QzdCXHU1MjJCIChcdTRFRTUgJyctJycgXHU1RjAwXHU1OTM0KVxuICAgIFx1OTY1MFx1NUI5QVx1N0IyNlx1OTAwMlx1NzUyOFx1NEU4RVx1OEJFNVx1OEJCRlx1OTVFRVx1N0VBN1x1NTIyQlx1NTNDQVx1NjZGNFx1NEY0RVx1N0VBN1x1NTIyQlx1MzAwMlxuICAgIFx1NTk4Mlx1Njc5Q1x1NkNBMVx1NjcwOVx1OTY1MFx1NUI5QVx1N0IyNiwgXHU1MjE5XHU4QkU1XHU3QzdCXHU1MjJCXHU5MDAyXHU3NTI4XHU0RThFXG4gICAgXHU2MjQwXHU2NzA5XHU4QkJGXHU5NUVFXHU3RUE3XHU1MjJCXHUzMDAyXG4gICAgXHU0RjhCXHU1OTgyLCAtWG1zZ3M6YWxsLC1zeW50YXgvcHJpdmF0ZVxuICAgIFx1OEZEOVx1NUMwNlx1NTcyOFx1NEUxM1x1NzUyOFx1NjVCOVx1NkNENVx1NzY4NFx1NjU4N1x1Njg2M1x1NkNFOFx1OTFDQVx1NEUyRFxuICAgIFx1NTQyRlx1NzUyOFx1OTY2NFx1OEJFRFx1NkNENVx1OTUxOVx1OEJFRlx1NEU0Qlx1NTkxNlx1NzY4NFx1NjI0MFx1NjcwOVx1NkQ4OFx1NjA2Rlx1MzAwMlxuICAgIFx1NTk4Mlx1Njc5Q1x1NjcyQVx1NjNEMFx1NEY5QiAtWG1zZ3MgXHU5MDA5XHU5ODc5LCBcdTUyMTlcdTlFRDhcdThCQTRcdTUwM0NcbiAgICBcdTdCNDlcdTU0MENcdTRFOEUgLVhtc2dzOmFsbC9wcm90ZWN0ZWQsIFx1ODg2OFx1NzkzQVxuICAgIFx1NEVDNVx1NjJBNVx1NTQ0QVx1NTNEN1x1NEZERFx1NjJBNFx1NTQ4Q1x1NTE2Q1x1NTE3MVx1NThGMFx1NjYwRVx1NEUyRFx1NzY4NFxuICAgIFx1NjI0MFx1NjcwOVx1NkQ4OFx1NjA2Rlx1MzAwMlxuICAtWGNoZWNrUGFja2FnZTo8cGFja2FnZXM+XG4gICAgXHU1NzI4XHU3Mjc5XHU1QjlBXHU3Njg0XHU3QTBCXHU1RThGXHU1MzA1XHU0RTJEXHU1NDJGXHU3NTI4XHU2MjE2XHU3OTgxXHU3NTI4XHU2OEMwXHU2N0U1XHUzMDAyXG4gICAgPHBhY2thZ2VzPiBcdTY2MkZcdTkwMTdcdTUzRjdcdTUyMDZcdTk2OTRcdTc2ODRcdTdBMEJcdTVFOEZcdTUzMDVcdThCRjRcdTY2MEVcdTdCMjZcdTUyMTdcdTg4NjhcdTMwMDJcbiAgICBcdTdBMEJcdTVFOEZcdTUzMDVcdThCRjRcdTY2MEVcdTdCMjZcdTY2MkZcdTdBMEJcdTVFOEZcdTUzMDVcdTc2ODRcdTk2NTBcdTVCOUFcdTU0MERcdTc5RjBcbiAgICBcdTYyMTZcdTdBMEJcdTVFOEZcdTUzMDVcdTU0MERcdTc5RjBcdTUyNERcdTdGMDBcdTU0MEVcdThEREYgJycuKicnLCBcdTVCODNcdTYyNjlcdTVDNTVcdTUyMzBcbiAgICBcdTdFRDlcdTVCOUFcdTdBMEJcdTVFOEZcdTUzMDVcdTc2ODRcdTYyNDBcdTY3MDlcdTVCNTBcdTdBMEJcdTVFOEZcdTUzMDVcdTMwMDJcdTU3MjhcdTdBMEJcdTVFOEZcdTUzMDVcdThCRjRcdTY2MEVcdTdCMjZcdTUyNERcdTk3NjJcbiAgICBcdTUyQTBcdTRFMEEgJyctJycgXHU1M0VGXHU0RUU1XHU0RTNBXHU2MzA3XHU1QjlBXHU3QTBCXHU1RThGXHU1MzA1XHU3OTgxXHU3NTI4XHU2OEMwXHU2N0U1XHUzMDAyXG4gIC1zdGF0c1xuICAgIFx1NjJBNVx1NTQ0QVx1NjI0MFx1NjJBNVx1NTQ0QVx1OTVFRVx1OTg5OFx1NzY4NFx1N0VERlx1OEJBMVx1NEZFMVx1NjA2Rlx1MzAwMlxuICAtaCAtaGVscCAtLWhlbHAgLXVzYWdlIC0/XG4gICAgXHU2NjNFXHU3OTNBXHU2QjY0XHU2RDg4XHU2MDZGXHUzMDAyXG5cblx1OEZEOFx1NjUyRlx1NjMwMVx1NEVFNVx1NEUwQiBqYXZhYyBcdTkwMDlcdTk4NzlcbiAgLWJvb3RjbGFzc3BhdGgsIC1jbGFzc3BhdGgsIC1jcCwgLXNvdXJjZXBhdGgsIC1YbWF4ZXJycywgLVhtYXh3YXJuc1xuXG5cdTg5ODFcdTU3MjhcdTk4NzlcdTc2RUVcdTc2ODRcdTRFMDBcdTkwRThcdTUyMDZcdTRFMEFcdThGRDBcdTg4NEMgZG9jbGludCwgXHU4QkY3XHU1QzA2XHU5ODc5XHU3NkVFXHU0RTJEXHU1REYyXHU3RjE2XHU4QkQxXHU3Njg0XHU3QzdCXG5cdTY1M0VcdTU3MjhcdTdDN0JcdThERUZcdTVGODQgKFx1NjIxNlx1NUYxNVx1NUJGQ1x1N0M3Qlx1OERFRlx1NUY4NCkgXHU0RTBBLCBcdTcxMzZcdTU0MEVcdTU3MjhcdTU0N0RcdTRFRTRcdTg4NENcdTRFMEFcdTYzMDdcdTVCOUFcblx1ODk4MVx1NjhDMFx1NjdFNVx1NzY4NFx1NkU5MFx1NjU4N1x1NEVGNlx1MzAwMgpQSwMECgAACAAABjupSoRE/VRWGgAAVhoAACEAAABjb20vc3VuL3Rvb2xzL2RvY2xpbnQvRW50aXR5LmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTIsIDIwMTMsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5kb2NsaW50OwoKaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOwppbXBvcnQgamF2YS51dGlsLk1hcDsKCi8qKgogKiBUYWJsZSBvZiBlbnRpdGllcyBkZWZpbmVkIGluIEhUTUwgNC4wMS4KICoKICogPHA+IERlcml2ZWQgZnJvbQogKiA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9odG1sNC9zZ21sL2VudGl0aWVzLmh0bWwiPkNoYXJhY3RlciBlbnRpdHkgcmVmZXJlbmNlcyBpbiBIVE1MIDQ8L2E+LgogKgogKiBUaGUgbmFtZSBvZiB0aGUgbWVtYmVyIGZvbGxvd3MgdGhlIG5hbWUgb2YgdGhlIGVudGl0eSwKICogZXhjZXB0IHdoZW4gaXQgY2xhc2hlcyB3aXRoIGEga2V5d29yZCwgaW4gd2hpY2ggY2FzZQogKiBpdCBpcyBwcmVmaXhlZCBieSAnXycuCiAqCiAqIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24KICogcmlzay4gIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlCiAqIG9yIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj48L3A+CiAqLwpwdWJsaWMgZW51bSBFbnRpdHkgewogICAgbmJzcCgxNjApLAogICAgaWV4Y2woMTYxKSwKICAgIGNlbnQoMTYyKSwKICAgIHBvdW5kKDE2MyksCiAgICBjdXJyZW4oMTY0KSwKICAgIHllbigxNjUpLAogICAgYnJ2YmFyKDE2NiksCiAgICBzZWN0KDE2NyksCiAgICB1bWwoMTY4KSwKICAgIGNvcHkoMTY5KSwKICAgIG9yZGYoMTcwKSwKICAgIGxhcXVvKDE3MSksCiAgICBub3QoMTcyKSwKICAgIHNoeSgxNzMpLAogICAgcmVnKDE3NCksCiAgICBtYWNyKDE3NSksCiAgICBkZWcoMTc2KSwKICAgIHBsdXNtbigxNzcpLAogICAgc3VwMigxNzgpLAogICAgc3VwMygxNzkpLAogICAgYWN1dGUoMTgwKSwKICAgIG1pY3JvKDE4MSksCiAgICBwYXJhKDE4MiksCiAgICBtaWRkb3QoMTgzKSwKICAgIGNlZGlsKDE4NCksCiAgICBzdXAxKDE4NSksCiAgICBvcmRtKDE4NiksCiAgICByYXF1bygxODcpLAogICAgZnJhYzE0KDE4OCksCiAgICBmcmFjMTIoMTg5KSwKICAgIGZyYWMzNCgxOTApLAogICAgaXF1ZXN0KDE5MSksCiAgICBBZ3JhdmUoMTkyKSwKICAgIEFhY3V0ZSgxOTMpLAogICAgQWNpcmMoMTk0KSwKICAgIEF0aWxkZSgxOTUpLAogICAgQXVtbCgxOTYpLAogICAgQXJpbmcoMTk3KSwKICAgIEFFbGlnKDE5OCksCiAgICBDY2VkaWwoMTk5KSwKICAgIEVncmF2ZSgyMDApLAogICAgRWFjdXRlKDIwMSksCiAgICBFY2lyYygyMDIpLAogICAgRXVtbCgyMDMpLAogICAgSWdyYXZlKDIwNCksCiAgICBJYWN1dGUoMjA1KSwKICAgIEljaXJjKDIwNiksCiAgICBJdW1sKDIwNyksCiAgICBFVEgoMjA4KSwKICAgIE50aWxkZSgyMDkpLAogICAgT2dyYXZlKDIxMCksCiAgICBPYWN1dGUoMjExKSwKICAgIE9jaXJjKDIxMiksCiAgICBPdGlsZGUoMjEzKSwKICAgIE91bWwoMjE0KSwKICAgIHRpbWVzKDIxNSksCiAgICBPc2xhc2goMjE2KSwKICAgIFVncmF2ZSgyMTcpLAogICAgVWFjdXRlKDIxOCksCiAgICBVY2lyYygyMTkpLAogICAgVXVtbCgyMjApLAogICAgWWFjdXRlKDIyMSksCiAgICBUSE9STigyMjIpLAogICAgc3psaWcoMjIzKSwKICAgIGFncmF2ZSgyMjQpLAogICAgYWFjdXRlKDIyNSksCiAgICBhY2lyYygyMjYpLAogICAgYXRpbGRlKDIyNyksCiAgICBhdW1sKDIyOCksCiAgICBhcmluZygyMjkpLAogICAgYWVsaWcoMjMwKSwKICAgIGNjZWRpbCgyMzEpLAogICAgZWdyYXZlKDIzMiksCiAgICBlYWN1dGUoMjMzKSwKICAgIGVjaXJjKDIzNCksCiAgICBldW1sKDIzNSksCiAgICBpZ3JhdmUoMjM2KSwKICAgIGlhY3V0ZSgyMzcpLAogICAgaWNpcmMoMjM4KSwKICAgIGl1bWwoMjM5KSwKICAgIGV0aCgyNDApLAogICAgbnRpbGRlKDI0MSksCiAgICBvZ3JhdmUoMjQyKSwKICAgIG9hY3V0ZSgyNDMpLAogICAgb2NpcmMoMjQ0KSwKICAgIG90aWxkZSgyNDUpLAogICAgb3VtbCgyNDYpLAogICAgZGl2aWRlKDI0NyksCiAgICBvc2xhc2goMjQ4KSwKICAgIHVncmF2ZSgyNDkpLAogICAgdWFjdXRlKDI1MCksCiAgICB1Y2lyYygyNTEpLAogICAgdXVtbCgyNTIpLAogICAgeWFjdXRlKDI1MyksCiAgICB0aG9ybigyNTQpLAogICAgeXVtbCgyNTUpLAogICAgZm5vZig0MDIpLAogICAgQWxwaGEoOTEzKSwKICAgIEJldGEoOTE0KSwKICAgIEdhbW1hKDkxNSksCiAgICBEZWx0YSg5MTYpLAogICAgRXBzaWxvbig5MTcpLAogICAgWmV0YSg5MTgpLAogICAgRXRhKDkxOSksCiAgICBUaGV0YSg5MjApLAogICAgSW90YSg5MjEpLAogICAgS2FwcGEoOTIyKSwKICAgIExhbWJkYSg5MjMpLAogICAgTXUoOTI0KSwKICAgIE51KDkyNSksCiAgICBYaSg5MjYpLAogICAgT21pY3Jvbig5MjcpLAogICAgUGkoOTI4KSwKICAgIFJobyg5MjkpLAogICAgU2lnbWEoOTMxKSwKICAgIFRhdSg5MzIpLAogICAgVXBzaWxvbig5MzMpLAogICAgUGhpKDkzNCksCiAgICBDaGkoOTM1KSwKICAgIFBzaSg5MzYpLAogICAgT21lZ2EoOTM3KSwKICAgIGFscGhhKDk0NSksCiAgICBiZXRhKDk0NiksCiAgICBnYW1tYSg5NDcpLAogICAgZGVsdGEoOTQ4KSwKICAgIGVwc2lsb24oOTQ5KSwKICAgIHpldGEoOTUwKSwKICAgIGV0YSg5NTEpLAogICAgdGhldGEoOTUyKSwKICAgIGlvdGEoOTUzKSwKICAgIGthcHBhKDk1NCksCiAgICBsYW1iZGEoOTU1KSwKICAgIG11KDk1NiksCiAgICBudSg5NTcpLAogICAgeGkoOTU4KSwKICAgIG9taWNyb24oOTU5KSwKICAgIHBpKDk2MCksCiAgICByaG8oOTYxKSwKICAgIHNpZ21hZig5NjIpLAogICAgc2lnbWEoOTYzKSwKICAgIHRhdSg5NjQpLAogICAgdXBzaWxvbig5NjUpLAogICAgcGhpKDk2NiksCiAgICBjaGkoOTY3KSwKICAgIHBzaSg5NjgpLAogICAgb21lZ2EoOTY5KSwKICAgIHRoZXRhc3ltKDk3NyksCiAgICB1cHNpaCg5NzgpLAogICAgcGl2KDk4MiksCiAgICBidWxsKDgyMjYpLAogICAgaGVsbGlwKDgyMzApLAogICAgcHJpbWUoODI0MiksCiAgICBQcmltZSg4MjQzKSwKICAgIG9saW5lKDgyNTQpLAogICAgZnJhc2woODI2MCksCiAgICB3ZWllcnAoODQ3MiksCiAgICBpbWFnZSg4NDY1KSwKICAgIHJlYWwoODQ3NiksCiAgICB0cmFkZSg4NDgyKSwKICAgIGFsZWZzeW0oODUwMSksCiAgICBsYXJyKDg1OTIpLAogICAgdWFycig4NTkzKSwKICAgIHJhcnIoODU5NCksCiAgICBkYXJyKDg1OTUpLAogICAgaGFycig4NTk2KSwKICAgIGNyYXJyKDg2MjkpLAogICAgbEFycig4NjU2KSwKICAgIHVBcnIoODY1NyksCiAgICByQXJyKDg2NTgpLAogICAgZEFycig4NjU5KSwKICAgIGhBcnIoODY2MCksCiAgICBmb3JhbGwoODcwNCksCiAgICBwYXJ0KDg3MDYpLAogICAgZXhpc3QoODcwNyksCiAgICBlbXB0eSg4NzA5KSwKICAgIG5hYmxhKDg3MTEpLAogICAgaXNpbig4NzEyKSwKICAgIG5vdGluKDg3MTMpLAogICAgbmkoODcxNSksCiAgICBwcm9kKDg3MTkpLAogICAgc3VtKDg3MjEpLAogICAgbWludXMoODcyMiksCiAgICBsb3dhc3QoODcyNyksCiAgICByYWRpYyg4NzMwKSwKICAgIHByb3AoODczMyksCiAgICBpbmZpbig4NzM0KSwKICAgIGFuZyg4NzM2KSwKICAgIGFuZCg4NzQzKSwKICAgIG9yKDg3NDQpLAogICAgY2FwKDg3NDUpLAogICAgY3VwKDg3NDYpLAogICAgX2ludCg4NzQ3KSwKICAgIHRoZXJlNCg4NzU2KSwKICAgIHNpbSg4NzY0KSwKICAgIGNvbmcoODc3MyksCiAgICBhc3ltcCg4Nzc2KSwKICAgIG5lKDg4MDApLAogICAgZXF1aXYoODgwMSksCiAgICBsZSg4ODA0KSwKICAgIGdlKDg4MDUpLAogICAgc3ViKDg4MzQpLAogICAgc3VwKDg4MzUpLAogICAgbnN1Yig4ODM2KSwKICAgIHN1YmUoODgzOCksCiAgICBzdXBlKDg4MzkpLAogICAgb3BsdXMoODg1MyksCiAgICBvdGltZXMoODg1NSksCiAgICBwZXJwKDg4NjkpLAogICAgc2RvdCg4OTAxKSwKICAgIGxjZWlsKDg5NjgpLAogICAgcmNlaWwoODk2OSksCiAgICBsZmxvb3IoODk3MCksCiAgICByZmxvb3IoODk3MSksCiAgICBsYW5nKDkwMDEpLAogICAgcmFuZyg5MDAyKSwKICAgIGxveig5Njc0KSwKICAgIHNwYWRlcyg5ODI0KSwKICAgIGNsdWJzKDk4MjcpLAogICAgaGVhcnRzKDk4MjkpLAogICAgZGlhbXMoOTgzMCksCiAgICBxdW90KDM0KSwKICAgIGFtcCgzOCksCiAgICBsdCg2MCksCiAgICBndCg2MiksCiAgICBPRWxpZygzMzgpLAogICAgb2VsaWcoMzM5KSwKICAgIFNjYXJvbigzNTIpLAogICAgc2Nhcm9uKDM1MyksCiAgICBZdW1sKDM3NiksCiAgICBjaXJjKDcxMCksCiAgICB0aWxkZSg3MzIpLAogICAgZW5zcCg4MTk0KSwKICAgIGVtc3AoODE5NSksCiAgICB0aGluc3AoODIwMSksCiAgICB6d25qKDgyMDQpLAogICAgendqKDgyMDUpLAogICAgbHJtKDgyMDYpLAogICAgcmxtKDgyMDcpLAogICAgbmRhc2goODIxMSksCiAgICBtZGFzaCg4MjEyKSwKICAgIGxzcXVvKDgyMTYpLAogICAgcnNxdW8oODIxNyksCiAgICBzYnF1byg4MjE4KSwKICAgIGxkcXVvKDgyMjApLAogICAgcmRxdW8oODIyMSksCiAgICBiZHF1byg4MjIyKSwKICAgIGRhZ2dlcig4MjI0KSwKICAgIERhZ2dlcig4MjI1KSwKICAgIHBlcm1pbCg4MjQwKSwKICAgIGxzYXF1byg4MjQ5KSwKICAgIHJzYXF1byg4MjUwKSwKICAgIGV1cm8oODM2NCk7CgogICAgcHVibGljIGZpbmFsIGludCBjb2RlOwoKICAgIHByaXZhdGUgRW50aXR5KGludCBjb2RlKSB7CiAgICAgICAgdGhpcy5jb2RlID0gY29kZTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNWYWxpZChTdHJpbmcgbmFtZSkgewogICAgICAgIHJldHVybiBuYW1lcy5jb250YWluc0tleShuYW1lKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIEVudGl0eSBnZXQoU3RyaW5nIG5hbWUpIHsKICAgICAgICByZXR1cm4gbmFtZXMuZ2V0KG5hbWUpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc1ZhbGlkKGludCBjb2RlKSB7CiAgICAgICAgLy8gYWxsb3cgbnVtZXJpYyBjb2RlcyBmb3Igc3RhbmRhcmQgQU5TSSBjaGFyYWN0ZXJzCiAgICAgICAgcmV0dXJuIGNvZGVzLmNvbnRhaW5zS2V5KGNvZGUpIHx8ICggMzIgPD0gY29kZSAmJiBjb2RlIDwgMjEyNyk7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgTWFwPFN0cmluZyxFbnRpdHk+IG5hbWVzID0gbmV3IEhhc2hNYXA8PigpOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgTWFwPEludGVnZXIsRW50aXR5PiBjb2RlcyA9IG5ldyBIYXNoTWFwPD4oKTsKICAgIHN0YXRpYyB7CiAgICAgICAgZm9yIChFbnRpdHkgZTogdmFsdWVzKCkpIHsKICAgICAgICAgICAgU3RyaW5nIG5hbWUgPSBlLm5hbWUoKTsKICAgICAgICAgICAgaW50IGNvZGUgPSBlLmNvZGU7CiAgICAgICAgICAgIGlmIChuYW1lLnN0YXJ0c1dpdGgoIl8iKSkgbmFtZSA9IG5hbWUuc3Vic3RyaW5nKDEpOwogICAgICAgICAgICBuYW1lcy5wdXQobmFtZSwgZSk7CiAgICAgICAgICAgIGNvZGVzLnB1dChjb2RlLCBlKTsKICAgICAgICB9CiAgICB9Cn0KUEsDBAoAAAgAAAY7qUrAjq93uDwAALg8AAAiAAAAY29tL3N1bi90b29scy9kb2NsaW50L0RvY0xpbnQuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAxMiwgMjAxNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLmRvY2xpbnQ7CgppbXBvcnQgamF2YS5pby5GaWxlOwppbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKaW1wb3J0IGphdmEuaW8uUHJpbnRXcml0ZXI7CmltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OwppbXBvcnQgamF2YS51dGlsLkxpbmtlZExpc3Q7CmltcG9ydCBqYXZhLnV0aWwuTGlzdDsKaW1wb3J0IGphdmEudXRpbC5RdWV1ZTsKaW1wb3J0IGphdmEudXRpbC5yZWdleC5QYXR0ZXJuOwoKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC5OYW1lOwppbXBvcnQgamF2YXgudG9vbHMuU3RhbmRhcmRMb2NhdGlvbjsKCmltcG9ydCBjb20uc3VuLnNvdXJjZS5kb2N0cmVlLkRvY0NvbW1lbnRUcmVlOwppbXBvcnQgY29tLnN1bi5zb3VyY2UudHJlZS5DbGFzc1RyZWU7CmltcG9ydCBjb20uc3VuLnNvdXJjZS50cmVlLkNvbXBpbGF0aW9uVW5pdFRyZWU7CmltcG9ydCBjb20uc3VuLnNvdXJjZS50cmVlLk1vZHVsZVRyZWU7CmltcG9ydCBjb20uc3VuLnNvdXJjZS50cmVlLlBhY2thZ2VUcmVlOwppbXBvcnQgY29tLnN1bi5zb3VyY2UudHJlZS5NZXRob2RUcmVlOwppbXBvcnQgY29tLnN1bi5zb3VyY2UudHJlZS5UcmVlOwppbXBvcnQgY29tLnN1bi5zb3VyY2UudHJlZS5WYXJpYWJsZVRyZWU7CmltcG9ydCBjb20uc3VuLnNvdXJjZS51dGlsLkphdmFjVGFzazsKaW1wb3J0IGNvbS5zdW4uc291cmNlLnV0aWwuUGx1Z2luOwppbXBvcnQgY29tLnN1bi5zb3VyY2UudXRpbC5UYXNrRXZlbnQ7CmltcG9ydCBjb20uc3VuLnNvdXJjZS51dGlsLlRhc2tMaXN0ZW5lcjsKaW1wb3J0IGNvbS5zdW4uc291cmNlLnV0aWwuVHJlZVBhdGg7CmltcG9ydCBjb20uc3VuLnNvdXJjZS51dGlsLlRyZWVQYXRoU2Nhbm5lcjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMuYXBpLkphdmFjVGFza0ltcGw7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmFwaS5KYXZhY1Rvb2w7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLmZpbGUuSmF2YWNGaWxlTWFuYWdlcjsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMubWFpbi5KYXZhQ29tcGlsZXI7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuQ29udGV4dDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5EZWZpbmVkQnk7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuRGVmaW5lZEJ5LkFwaTsKCi8qKgogKiBNdWx0aS1mdW5jdGlvbiBlbnRyeSBwb2ludCBmb3IgdGhlIGRvYyBjaGVjayB1dGlsaXR5LgogKgogKiBUaGlzIGNsYXNzIGNhbiBiZSBpbnZva2VkIGluIHRoZSBmb2xsb3dpbmcgd2F5czoKICogPHVsPgogKiA8bGk+RnJvbSB0aGUgY29tbWFuZCBsaW5lCiAqIDxsaT5Gcm9tIGphdmFjLCBhcyBhIHBsdWdpbgogKiA8bGk+RGlyZWN0bHksIHZpYSBhIHNpbXBsZSBBUEkKICogPC91bD4KICoKICogPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93bgogKiByaXNrLiAgVGhpcyBjb2RlIGFuZCBpdHMgaW50ZXJuYWwgaW50ZXJmYWNlcyBhcmUgc3ViamVjdCB0byBjaGFuZ2UKICogb3IgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPjwvcD4KICovCnB1YmxpYyBjbGFzcyBEb2NMaW50IGltcGxlbWVudHMgUGx1Z2luIHsKCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBYTVNHU19PUFRJT04gPSAiLVhtc2dzIjsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFhNU0dTX0NVU1RPTV9QUkVGSVggPSAiLVhtc2dzOiI7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1RBVFMgPSAiLXN0YXRzIjsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFhJTVBMSUNJVF9IRUFERVJTID0gIi1YaW1wbGljaXRIZWFkZXJzOiI7CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBYQ1VTVE9NX1RBR1NfUFJFRklYID0gIi1YY3VzdG9tVGFnczoiOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgWEhUTUxfVkVSU0lPTl9QUkVGSVggPSAiLVhodG1sVmVyc2lvbjoiOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgWENIRUNLX1BBQ0tBR0UgPSAiLVhjaGVja1BhY2thZ2U6IjsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFNFUEFSQVRPUiA9ICIsIjsKCiAgICAvLyA8ZWRpdG9yLWZvbGQgZGVmYXVsdHN0YXRlPSJjb2xsYXBzZWQiIGRlc2M9IkNvbW1hbmQtbGluZSBlbnRyeSBwb2ludCI+CiAgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmcuLi4gYXJncykgewogICAgICAgIERvY0xpbnQgZGwgPSBuZXcgRG9jTGludCgpOwogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGRsLnJ1bihhcmdzKTsKICAgICAgICB9IGNhdGNoIChCYWRBcmdzIGUpIHsKICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKGUuZ2V0TWVzc2FnZSgpKTsKICAgICAgICAgICAgU3lzdGVtLmV4aXQoMSk7CiAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oZGwubG9jYWxpemUoImRjLm1haW4uaW9lcnJvciIsIGUuZ2V0TG9jYWxpemVkTWVzc2FnZSgpKSk7CiAgICAgICAgICAgIFN5c3RlbS5leGl0KDIpOwogICAgICAgIH0KICAgIH0KCiAgICAvLyA8L2VkaXRvci1mb2xkPgoKICAgIC8vIDxlZGl0b3ItZm9sZCBkZWZhdWx0c3RhdGU9ImNvbGxhcHNlZCIgZGVzYz0iU2ltcGxlIEFQSSI+CgogICAgcHVibGljIGNsYXNzIEJhZEFyZ3MgZXh0ZW5kcyBFeGNlcHRpb24gewogICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDA7CiAgICAgICAgQmFkQXJncyhTdHJpbmcgY29kZSwgT2JqZWN0Li4uIGFyZ3MpIHsKICAgICAgICAgICAgc3VwZXIobG9jYWxpemUoY29kZSwgYXJncykpOwogICAgICAgICAgICB0aGlzLmNvZGUgPSBjb2RlOwogICAgICAgICAgICB0aGlzLmFyZ3MgPSBhcmdzOwogICAgICAgIH0KCiAgICAgICAgZmluYWwgU3RyaW5nIGNvZGU7CiAgICAgICAgZmluYWwgT2JqZWN0W10gYXJnczsKICAgIH0KCiAgICAvKioKICAgICAqIFNpbXBsZSBBUEkgZW50cnkgcG9pbnQuCiAgICAgKiBAcGFyYW0gYXJncyBPcHRpb25zIGFuZCBvcGVyYW5kcyBmb3IgZG9jbGludAogICAgICogQHRocm93cyBCYWRBcmdzIGlmIGFuIGVycm9yIGlzIGRldGVjdGVkIGluIGFueSBhcmdzCiAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIHRoZXJlIGFyZSBwcm9ibGVtcyB3aXRoIGFueSBvZiB0aGUgZmlsZSBhcmd1bWVudHMKICAgICAqLwogICAgcHVibGljIHZvaWQgcnVuKFN0cmluZy4uLiBhcmdzKSB0aHJvd3MgQmFkQXJncywgSU9FeGNlcHRpb24gewogICAgICAgIFByaW50V3JpdGVyIG91dCA9IG5ldyBQcmludFdyaXRlcihTeXN0ZW0ub3V0KTsKICAgICAgICB0cnkgewogICAgICAgICAgICBydW4ob3V0LCBhcmdzKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICBvdXQuZmx1c2goKTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHZvaWQgcnVuKFByaW50V3JpdGVyIG91dCwgU3RyaW5nLi4uIGFyZ3MpIHRocm93cyBCYWRBcmdzLCBJT0V4Y2VwdGlvbiB7CiAgICAgICAgZW52ID0gbmV3IEVudigpOwogICAgICAgIHByb2Nlc3NBcmdzKGFyZ3MpOwoKICAgICAgICBib29sZWFuIG5vRmlsZXMgPSBqYXZhY0ZpbGVzLmlzRW1wdHkoKTsKICAgICAgICBpZiAobmVlZEhlbHApIHsKICAgICAgICAgICAgc2hvd0hlbHAob3V0KTsKICAgICAgICAgICAgaWYgKG5vRmlsZXMpCiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgfSBlbHNlIGlmIChub0ZpbGVzKSB7CiAgICAgICAgICAgIG91dC5wcmludGxuKGxvY2FsaXplKCJkYy5tYWluLm5vLmZpbGVzLmdpdmVuIikpOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICBKYXZhY1Rvb2wgdG9vbCA9IEphdmFjVG9vbC5jcmVhdGUoKTsKCiAgICAgICAgSmF2YWNGaWxlTWFuYWdlciBmbSA9IG5ldyBKYXZhY0ZpbGVNYW5hZ2VyKG5ldyBDb250ZXh0KCksIGZhbHNlLCBudWxsKTsKICAgICAgICBmbS5zZXRTeW1ib2xGaWxlRW5hYmxlZChmYWxzZSk7CiAgICAgICAgZm0uc2V0TG9jYXRpb24oU3RhbmRhcmRMb2NhdGlvbi5QTEFURk9STV9DTEFTU19QQVRILCBqYXZhY0Jvb3RDbGFzc1BhdGgpOwogICAgICAgIGZtLnNldExvY2F0aW9uKFN0YW5kYXJkTG9jYXRpb24uQ0xBU1NfUEFUSCwgamF2YWNDbGFzc1BhdGgpOwogICAgICAgIGZtLnNldExvY2F0aW9uKFN0YW5kYXJkTG9jYXRpb24uU09VUkNFX1BBVEgsIGphdmFjU291cmNlUGF0aCk7CgogICAgICAgIEphdmFjVGFzayB0YXNrID0gdG9vbC5nZXRUYXNrKG91dCwgZm0sIG51bGwsIGphdmFjT3B0cywgbnVsbCwKICAgICAgICAgICAgICAgIGZtLmdldEphdmFGaWxlT2JqZWN0c0Zyb21GaWxlcyhqYXZhY0ZpbGVzKSk7CiAgICAgICAgSXRlcmFibGU8PyBleHRlbmRzIENvbXBpbGF0aW9uVW5pdFRyZWU+IHVuaXRzID0gdGFzay5wYXJzZSgpOwogICAgICAgICgoSmF2YWNUYXNrSW1wbCkgdGFzaykuZW50ZXIoKTsKCiAgICAgICAgZW52LmluaXQodGFzayk7CiAgICAgICAgY2hlY2tlciA9IG5ldyBDaGVja2VyKGVudik7CgogICAgICAgIERlY2xTY2FubmVyIGRzID0gbmV3IERlY2xTY2FubmVyKGVudikgewogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgdm9pZCB2aXNpdERlY2woVHJlZSB0cmVlLCBOYW1lIG5hbWUpIHsKICAgICAgICAgICAgICAgIFRyZWVQYXRoIHAgPSBnZXRDdXJyZW50UGF0aCgpOwogICAgICAgICAgICAgICAgRG9jQ29tbWVudFRyZWUgZGMgPSBlbnYudHJlZXMuZ2V0RG9jQ29tbWVudFRyZWUocCk7CgogICAgICAgICAgICAgICAgY2hlY2tlci5zY2FuKGRjLCBwKTsKICAgICAgICAgICAgfQogICAgICAgIH07CgogICAgICAgIGRzLnNjYW4odW5pdHMsIG51bGwpOwoKICAgICAgICByZXBvcnRTdGF0cyhvdXQpOwoKICAgICAgICBDb250ZXh0IGN0eCA9ICgoSmF2YWNUYXNrSW1wbCkgdGFzaykuZ2V0Q29udGV4dCgpOwogICAgICAgIEphdmFDb21waWxlciBjID0gSmF2YUNvbXBpbGVyLmluc3RhbmNlKGN0eCk7CiAgICAgICAgYy5wcmludENvdW50KCJlcnJvciIsIGMuZXJyb3JDb3VudCgpKTsKICAgICAgICBjLnByaW50Q291bnQoIndhcm4iLCBjLndhcm5pbmdDb3VudCgpKTsKICAgIH0KCiAgICB2b2lkIHByb2Nlc3NBcmdzKFN0cmluZy4uLiBhcmdzKSB0aHJvd3MgQmFkQXJncyB7CiAgICAgICAgamF2YWNPcHRzID0gbmV3IEFycmF5TGlzdDw+KCk7CiAgICAgICAgamF2YWNGaWxlcyA9IG5ldyBBcnJheUxpc3Q8PigpOwoKICAgICAgICBpZiAoYXJncy5sZW5ndGggPT0gMCkKICAgICAgICAgICAgbmVlZEhlbHAgPSB0cnVlOwoKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGFyZ3MubGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgU3RyaW5nIGFyZyA9IGFyZ3NbaV07CiAgICAgICAgICAgIGlmIChhcmcubWF0Y2hlcygiLVhtYXgoZXJyc3x3YXJucykiKSAmJiBpICsgMSA8IGFyZ3MubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICBpZiAoYXJnc1srK2ldLm1hdGNoZXMoIlswLTldKyIpKSB7CiAgICAgICAgICAgICAgICAgICAgamF2YWNPcHRzLmFkZChhcmcpOwogICAgICAgICAgICAgICAgICAgIGphdmFjT3B0cy5hZGQoYXJnc1tpXSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBCYWRBcmdzKCJkYy5iYWQudmFsdWUuZm9yLm9wdGlvbiIsIGFyZywgYXJnc1tpXSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSBpZiAoKGFyZy5lcXVhbHMoIi10YXJnZXQiKSB8fCBhcmcuZXF1YWxzKCItc291cmNlIikpICYmIGkgKyAxIDwgYXJncy5sZW5ndGgpIHsKICAgICAgICAgICAgICAgIGphdmFjT3B0cy5hZGQoYXJnKTsKICAgICAgICAgICAgICAgIGphdmFjT3B0cy5hZGQoYXJnc1srK2ldKTsKICAgICAgICAgICAgfSBlbHNlIGlmIChhcmcuZXF1YWxzKFNUQVRTKSkgewogICAgICAgICAgICAgICAgZW52Lm1lc3NhZ2VzLnNldFN0YXRzRW5hYmxlZCh0cnVlKTsKICAgICAgICAgICAgfSBlbHNlIGlmIChhcmcuZXF1YWxzKCItYm9vdGNsYXNzcGF0aCIpICYmIGkgKyAxIDwgYXJncy5sZW5ndGgpIHsKICAgICAgICAgICAgICAgIGphdmFjQm9vdENsYXNzUGF0aCA9IHNwbGl0UGF0aChhcmdzWysraV0pOwogICAgICAgICAgICB9IGVsc2UgaWYgKGFyZy5lcXVhbHMoIi1jbGFzc3BhdGgiKSAmJiBpICsgMSA8IGFyZ3MubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICBqYXZhY0NsYXNzUGF0aCA9IHNwbGl0UGF0aChhcmdzWysraV0pOwogICAgICAgICAgICB9IGVsc2UgaWYgKGFyZy5lcXVhbHMoIi1jcCIpICYmIGkgKyAxIDwgYXJncy5sZW5ndGgpIHsKICAgICAgICAgICAgICAgIGphdmFjQ2xhc3NQYXRoID0gc3BsaXRQYXRoKGFyZ3NbKytpXSk7CiAgICAgICAgICAgIH0gZWxzZSBpZiAoYXJnLmVxdWFscygiLXNvdXJjZXBhdGgiKSAmJiBpICsgMSA8IGFyZ3MubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICBqYXZhY1NvdXJjZVBhdGggPSBzcGxpdFBhdGgoYXJnc1srK2ldKTsKICAgICAgICAgICAgfSBlbHNlIGlmIChhcmcuZXF1YWxzKFhNU0dTX09QVElPTikpIHsKICAgICAgICAgICAgICAgIGVudi5tZXNzYWdlcy5zZXRPcHRpb25zKG51bGwpOwogICAgICAgICAgICB9IGVsc2UgaWYgKGFyZy5zdGFydHNXaXRoKFhNU0dTX0NVU1RPTV9QUkVGSVgpKSB7CiAgICAgICAgICAgICAgICBlbnYubWVzc2FnZXMuc2V0T3B0aW9ucyhhcmcuc3Vic3RyaW5nKGFyZy5pbmRleE9mKCI6IikgKyAxKSk7CiAgICAgICAgICAgIH0gZWxzZSBpZiAoYXJnLnN0YXJ0c1dpdGgoWENVU1RPTV9UQUdTX1BSRUZJWCkpIHsKICAgICAgICAgICAgICAgIGVudi5zZXRDdXN0b21UYWdzKGFyZy5zdWJzdHJpbmcoYXJnLmluZGV4T2YoIjoiKSArIDEpKTsKICAgICAgICAgICAgfSBlbHNlIGlmIChhcmcuc3RhcnRzV2l0aChYSFRNTF9WRVJTSU9OX1BSRUZJWCkpIHsKICAgICAgICAgICAgICAgIFN0cmluZyBhcmdzVmVyc2lvbiA9IGFyZy5zdWJzdHJpbmcoYXJnLmluZGV4T2YoIjoiKSArIDEpOwogICAgICAgICAgICAgICAgSHRtbFZlcnNpb24gaHRtbFZlcnNpb24gPSBIdG1sVmVyc2lvbi5nZXRIdG1sVmVyc2lvbihhcmdzVmVyc2lvbik7CiAgICAgICAgICAgICAgICBpZiAoaHRtbFZlcnNpb24gIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIGVudi5zZXRIdG1sVmVyc2lvbihodG1sVmVyc2lvbik7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBCYWRBcmdzKCJkYy5iYWQudmFsdWUuZm9yLm9wdGlvbiIsIGFyZywgYXJnc1ZlcnNpb24pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgaWYgKGFyZy5lcXVhbHMoIi1oIikgfHwgYXJnLmVxdWFscygiLWhlbHAiKSB8fCBhcmcuZXF1YWxzKCItLWhlbHAiKQogICAgICAgICAgICAgICAgICAgIHx8IGFyZy5lcXVhbHMoIi0/IikgfHwgYXJnLmVxdWFscygiLXVzYWdlIikpIHsKICAgICAgICAgICAgICAgIG5lZWRIZWxwID0gdHJ1ZTsKICAgICAgICAgICAgfSBlbHNlIGlmIChhcmcuc3RhcnRzV2l0aCgiLSIpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQmFkQXJncygiZGMuYmFkLm9wdGlvbiIsIGFyZyk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB3aGlsZSAoaSA8IGFyZ3MubGVuZ3RoKQogICAgICAgICAgICAgICAgICAgIGphdmFjRmlsZXMuYWRkKG5ldyBGaWxlKGFyZ3NbaSsrXSkpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIHZvaWQgc2hvd0hlbHAoUHJpbnRXcml0ZXIgb3V0KSB7CiAgICAgICAgU3RyaW5nIG1zZyA9IGxvY2FsaXplKCJkYy5tYWluLnVzYWdlIik7CiAgICAgICAgZm9yIChTdHJpbmcgbGluZTogbXNnLnNwbGl0KCJcbiIpKQogICAgICAgICAgICBvdXQucHJpbnRsbihsaW5lKTsKICAgIH0KCiAgICBMaXN0PEZpbGU+IHNwbGl0UGF0aChTdHJpbmcgcGF0aCkgewogICAgICAgIExpc3Q8RmlsZT4gZmlsZXMgPSBuZXcgQXJyYXlMaXN0PD4oKTsKICAgICAgICBmb3IgKFN0cmluZyBmOiBwYXRoLnNwbGl0KEZpbGUucGF0aFNlcGFyYXRvcikpIHsKICAgICAgICAgICAgaWYgKGYubGVuZ3RoKCkgPiAwKQogICAgICAgICAgICAgICAgZmlsZXMuYWRkKG5ldyBGaWxlKGYpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpbGVzOwogICAgfQoKICAgIExpc3Q8RmlsZT4gamF2YWNCb290Q2xhc3NQYXRoOwogICAgTGlzdDxGaWxlPiBqYXZhY0NsYXNzUGF0aDsKICAgIExpc3Q8RmlsZT4gamF2YWNTb3VyY2VQYXRoOwogICAgTGlzdDxTdHJpbmc+IGphdmFjT3B0czsKICAgIExpc3Q8RmlsZT4gamF2YWNGaWxlczsKICAgIGJvb2xlYW4gbmVlZEhlbHAgPSBmYWxzZTsKCiAgICAvLyA8L2VkaXRvci1mb2xkPgoKICAgIC8vIDxlZGl0b3ItZm9sZCBkZWZhdWx0c3RhdGU9ImNvbGxhcHNlZCIgZGVzYz0iamF2YWMgUGx1Z2luIj4KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZSgpIHsKICAgICAgICByZXR1cm4gImRvY2xpbnQiOwogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIHZvaWQgaW5pdChKYXZhY1Rhc2sgdGFzaywgU3RyaW5nLi4uIGFyZ3MpIHsKICAgICAgICBpbml0KHRhc2ssIGFyZ3MsIHRydWUpOwogICAgfQoKICAgIC8vIDwvZWRpdG9yLWZvbGQ+CgogICAgLy8gPGVkaXRvci1mb2xkIGRlZmF1bHRzdGF0ZT0iY29sbGFwc2VkIiBkZXNjPSJFbWJlZGRpbmcgQVBJIj4KCiAgICBwdWJsaWMgdm9pZCBpbml0KEphdmFjVGFzayB0YXNrLCBTdHJpbmdbXSBhcmdzLCBib29sZWFuIGFkZFRhc2tMaXN0ZW5lcikgewogICAgICAgIGVudiA9IG5ldyBFbnYoKTsKICAgICAgICBmb3IgKFN0cmluZyBhcmcgOiBhcmdzKSB7CiAgICAgICAgICAgIGlmIChhcmcuZXF1YWxzKFhNU0dTX09QVElPTikpIHsKICAgICAgICAgICAgICAgIGVudi5tZXNzYWdlcy5zZXRPcHRpb25zKG51bGwpOwogICAgICAgICAgICB9IGVsc2UgaWYgKGFyZy5zdGFydHNXaXRoKFhNU0dTX0NVU1RPTV9QUkVGSVgpKSB7CiAgICAgICAgICAgICAgICBlbnYubWVzc2FnZXMuc2V0T3B0aW9ucyhhcmcuc3Vic3RyaW5nKGFyZy5pbmRleE9mKCI6IikgKyAxKSk7CiAgICAgICAgICAgIH0gZWxzZSBpZiAoYXJnLm1hdGNoZXMoWElNUExJQ0lUX0hFQURFUlMgKyAiWzEtNl0iKSkgewogICAgICAgICAgICAgICAgY2hhciBjaCA9IGFyZy5jaGFyQXQoYXJnLmxlbmd0aCgpIC0gMSk7CiAgICAgICAgICAgICAgICBlbnYuc2V0SW1wbGljaXRIZWFkZXJzKENoYXJhY3Rlci5kaWdpdChjaCwgMTApKTsKICAgICAgICAgICAgfSBlbHNlIGlmIChhcmcuc3RhcnRzV2l0aChYQ1VTVE9NX1RBR1NfUFJFRklYKSkgewogICAgICAgICAgICAgICAgZW52LnNldEN1c3RvbVRhZ3MoYXJnLnN1YnN0cmluZyhhcmcuaW5kZXhPZigiOiIpICsgMSkpOwogICAgICAgICAgICB9IGVsc2UgaWYgKGFyZy5zdGFydHNXaXRoKFhIVE1MX1ZFUlNJT05fUFJFRklYKSkgewogICAgICAgICAgICAgICAgU3RyaW5nIGFyZ3NWZXJzaW9uID0gYXJnLnN1YnN0cmluZyhhcmcuaW5kZXhPZigiOiIpICsgMSk7CiAgICAgICAgICAgICAgICBIdG1sVmVyc2lvbiBodG1sVmVyc2lvbiA9IEh0bWxWZXJzaW9uLmdldEh0bWxWZXJzaW9uKGFyZ3NWZXJzaW9uKTsKICAgICAgICAgICAgICAgIGlmIChodG1sVmVyc2lvbiAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgZW52LnNldEh0bWxWZXJzaW9uKGh0bWxWZXJzaW9uKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihhcmdzVmVyc2lvbik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSBpZiAoYXJnLnN0YXJ0c1dpdGgoWENIRUNLX1BBQ0tBR0UpKSB7CiAgICAgICAgICAgICAgICBlbnYuc2V0Q2hlY2tQYWNrYWdlcyhhcmcuc3Vic3RyaW5nKGFyZy5pbmRleE9mKCI6IikgKyAxKSk7CiAgICAgICAgICAgIH0gZWxzZQogICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihhcmcpOwogICAgICAgIH0KICAgICAgICBlbnYuaW5pdCh0YXNrKTsKCiAgICAgICAgY2hlY2tlciA9IG5ldyBDaGVja2VyKGVudik7CgogICAgICAgIGlmIChhZGRUYXNrTGlzdGVuZXIpIHsKICAgICAgICAgICAgZmluYWwgRGVjbFNjYW5uZXIgZHMgPSBuZXcgRGVjbFNjYW5uZXIoZW52KSB7CiAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgICAgIHZvaWQgdmlzaXREZWNsKFRyZWUgdHJlZSwgTmFtZSBuYW1lKSB7CiAgICAgICAgICAgICAgICAgICAgVHJlZVBhdGggcCA9IGdldEN1cnJlbnRQYXRoKCk7CiAgICAgICAgICAgICAgICAgICAgRG9jQ29tbWVudFRyZWUgZGMgPSBlbnYudHJlZXMuZ2V0RG9jQ29tbWVudFRyZWUocCk7CgogICAgICAgICAgICAgICAgICAgIGNoZWNrZXIuc2NhbihkYywgcCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CgogICAgICAgICAgICBUYXNrTGlzdGVuZXIgdGwgPSBuZXcgVGFza0xpc3RlbmVyKCkgewogICAgICAgICAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCBzdGFydGVkKFRhc2tFdmVudCBlKSB7CiAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChlLmdldEtpbmQoKSkgewogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIEFOQUxZWkU6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb21waWxhdGlvblVuaXRUcmVlIHRyZWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoKHRyZWUgPSB0b2RvLnBvbGwoKSkgIT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkcy5zY2FuKHRyZWUsIG51bGwpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgICAgICAgICAgcHVibGljIHZvaWQgZmluaXNoZWQoVGFza0V2ZW50IGUpIHsKICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKGUuZ2V0S2luZCgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgUEFSU0U6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b2RvLmFkZChlLmdldENvbXBpbGF0aW9uVW5pdCgpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBRdWV1ZTxDb21waWxhdGlvblVuaXRUcmVlPiB0b2RvID0gbmV3IExpbmtlZExpc3Q8PigpOwogICAgICAgICAgICB9OwoKICAgICAgICAgICAgdGFzay5hZGRUYXNrTGlzdGVuZXIodGwpOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgdm9pZCBzY2FuKFRyZWVQYXRoIHApIHsKICAgICAgICBEb2NDb21tZW50VHJlZSBkYyA9IGVudi50cmVlcy5nZXREb2NDb21tZW50VHJlZShwKTsKICAgICAgICBjaGVja2VyLnNjYW4oZGMsIHApOwogICAgfQoKICAgIHB1YmxpYyBib29sZWFuIHNob3VsZENoZWNrKENvbXBpbGF0aW9uVW5pdFRyZWUgdW5pdCkgewogICAgICAgIHJldHVybiBlbnYuc2hvdWxkQ2hlY2sodW5pdCk7CiAgICB9CgogICAgcHVibGljIHZvaWQgcmVwb3J0U3RhdHMoUHJpbnRXcml0ZXIgb3V0KSB7CiAgICAgICAgZW52Lm1lc3NhZ2VzLnJlcG9ydFN0YXRzKG91dCk7CiAgICB9CgogICAgLy8gPC9lZGl0b3ItZm9sZD4KCiAgICBFbnYgZW52OwogICAgQ2hlY2tlciBjaGVja2VyOwoKICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc1ZhbGlkT3B0aW9uKFN0cmluZyBvcHQpIHsKICAgICAgICBpZiAob3B0LmVxdWFscyhYTVNHU19PUFRJT04pKQogICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIGlmIChvcHQuc3RhcnRzV2l0aChYTVNHU19DVVNUT01fUFJFRklYKSkKICAgICAgICAgICByZXR1cm4gTWVzc2FnZXMuT3B0aW9ucy5pc1ZhbGlkT3B0aW9ucyhvcHQuc3Vic3RyaW5nKFhNU0dTX0NVU1RPTV9QUkVGSVgubGVuZ3RoKCkpKTsKICAgICAgICBpZiAob3B0LnN0YXJ0c1dpdGgoWENIRUNLX1BBQ0tBR0UpKSB7CiAgICAgICAgICAgIHJldHVybiBFbnYudmFsaWRhdGVQYWNrYWdlcyhvcHQuc3Vic3RyaW5nKG9wdC5pbmRleE9mKCI6IikgKyAxKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICBwcml2YXRlIFN0cmluZyBsb2NhbGl6ZShTdHJpbmcgY29kZSwgT2JqZWN0Li4uIGFyZ3MpIHsKICAgICAgICBNZXNzYWdlcyBtID0gKGVudiAhPSBudWxsKSA/IGVudi5tZXNzYWdlcyA6IG5ldyBNZXNzYWdlcyhudWxsKTsKICAgICAgICByZXR1cm4gbS5sb2NhbGl6ZShjb2RlLCBhcmdzKTsKICAgIH0KCiAgICAvLyA8ZWRpdG9yLWZvbGQgZGVmYXVsdHN0YXRlPSJjb2xsYXBzZWQiIGRlc2M9IkRlY2xTY2FubmVyIj4KCiAgICBzdGF0aWMgYWJzdHJhY3QgY2xhc3MgRGVjbFNjYW5uZXIgZXh0ZW5kcyBUcmVlUGF0aFNjYW5uZXI8Vm9pZCwgVm9pZD4gewogICAgICAgIGZpbmFsIEVudiBlbnY7CgogICAgICAgIHB1YmxpYyBEZWNsU2Nhbm5lcihFbnYgZW52KSB7CiAgICAgICAgICAgIHRoaXMuZW52ID0gZW52OwogICAgICAgIH0KCiAgICAgICAgYWJzdHJhY3Qgdm9pZCB2aXNpdERlY2woVHJlZSB0cmVlLCBOYW1lIG5hbWUpOwoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgVm9pZCB2aXNpdFBhY2thZ2UoUGFja2FnZVRyZWUgdHJlZSwgVm9pZCBpZ25vcmUpIHsKICAgICAgICAgICAgdmlzaXREZWNsKHRyZWUsIG51bGwpOwogICAgICAgICAgICByZXR1cm4gc3VwZXIudmlzaXRQYWNrYWdlKHRyZWUsIGlnbm9yZSk7CiAgICAgICAgfQogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBWb2lkIHZpc2l0Q2xhc3MoQ2xhc3NUcmVlIHRyZWUsIFZvaWQgaWdub3JlKSB7CiAgICAgICAgICAgIHZpc2l0RGVjbCh0cmVlLCB0cmVlLmdldFNpbXBsZU5hbWUoKSk7CiAgICAgICAgICAgIHJldHVybiBzdXBlci52aXNpdENsYXNzKHRyZWUsIGlnbm9yZSk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgICAgICBwdWJsaWMgVm9pZCB2aXNpdE1ldGhvZChNZXRob2RUcmVlIHRyZWUsIFZvaWQgaWdub3JlKSB7CiAgICAgICAgICAgIHZpc2l0RGVjbCh0cmVlLCB0cmVlLmdldE5hbWUoKSk7CiAgICAgICAgICAgIC8vcmV0dXJuIHN1cGVyLnZpc2l0TWV0aG9kKHRyZWUsIGlnbm9yZSk7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIFZvaWQgdmlzaXRNb2R1bGUoTW9kdWxlVHJlZSB0cmVlLCBWb2lkIGlnbm9yZSkgewogICAgICAgICAgICB2aXNpdERlY2wodHJlZSwgbnVsbCk7CiAgICAgICAgICAgIHJldHVybiBzdXBlci52aXNpdE1vZHVsZSh0cmVlLCBpZ25vcmUpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICAgICAgcHVibGljIFZvaWQgdmlzaXRWYXJpYWJsZShWYXJpYWJsZVRyZWUgdHJlZSwgVm9pZCBpZ25vcmUpIHsKICAgICAgICAgICAgdmlzaXREZWNsKHRyZWUsIHRyZWUuZ2V0TmFtZSgpKTsKICAgICAgICAgICAgcmV0dXJuIHN1cGVyLnZpc2l0VmFyaWFibGUodHJlZSwgaWdub3JlKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgICAgIHB1YmxpYyBWb2lkIHZpc2l0Q29tcGlsYXRpb25Vbml0KENvbXBpbGF0aW9uVW5pdFRyZWUgbm9kZSwgVm9pZCBwKSB7CiAgICAgICAgICAgIGlmICghZW52LnNob3VsZENoZWNrKG5vZGUpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gc3VwZXIudmlzaXRDb21waWxhdGlvblVuaXQobm9kZSwgcCk7CiAgICAgICAgfQoKICAgIH0KCiAgICAvLyA8L2VkaXRvci1mb2xkPgoKfQpQSwMECgAACAAABjupSjZPsY2lBgAApQYAACYAAABjb20vc3VuL3Rvb2xzL2RvY2xpbnQvSHRtbFZlcnNpb24uamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAxNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLmRvY2xpbnQ7CgovKioKICogRW51bSByZXByZXNlbnRpbmcgSFRNTCB2ZXJzaW9uIG9mIHRoZSBkb2N1bWVudGF0aW9uIGNvbW1lbnQuCiAqCiAqIEBhdXRob3IgQmhhdmVzaCBQYXRlbAogKi8KcHVibGljIGVudW0gSHRtbFZlcnNpb24gewoKICAgIEhUTUw0LAogICAgSFRNTDUsCiAgICBBTEw7CgogICAgcHVibGljIHN0YXRpYyBIdG1sVmVyc2lvbiBnZXRIdG1sVmVyc2lvbihTdHJpbmcgYXJnc1ZlcnNpb24pIHsKICAgICAgICBzd2l0Y2ggKGFyZ3NWZXJzaW9uKSB7CiAgICAgICAgICAgIGNhc2UgImh0bWw0IjoKICAgICAgICAgICAgICAgIHJldHVybiBIdG1sVmVyc2lvbi5IVE1MNDsKICAgICAgICAgICAgY2FzZSAiaHRtbDUiOgogICAgICAgICAgICAgICAgcmV0dXJuIEh0bWxWZXJzaW9uLkhUTUw1OwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgfQp9ClBLAwQKAAAIAAAGO6lKyg9lqW4tAABuLQAAIwAAAGNvbS9zdW4vdG9vbHMvZG9jbGludC9NZXNzYWdlcy5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDEyLCAyMDEzLCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuZG9jbGludDsKCmltcG9ydCBqYXZhLmlvLlByaW50V3JpdGVyOwppbXBvcnQgamF2YS50ZXh0Lk1lc3NhZ2VGb3JtYXQ7CmltcG9ydCBqYXZhLnV0aWwuQ29tcGFyYXRvcjsKaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOwppbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKaW1wb3J0IGphdmEudXRpbC5NYXA7CmltcG9ydCBqYXZhLnV0aWwuTWlzc2luZ1Jlc291cmNlRXhjZXB0aW9uOwppbXBvcnQgamF2YS51dGlsLlJlc291cmNlQnVuZGxlOwppbXBvcnQgamF2YS51dGlsLlNldDsKaW1wb3J0IGphdmEudXRpbC5UcmVlTWFwOwppbXBvcnQgamF2YS51dGlsLlRyZWVTZXQ7CgppbXBvcnQgamF2YXgudG9vbHMuRGlhZ25vc3RpYzsKCmltcG9ydCBjb20uc3VuLnNvdXJjZS5kb2N0cmVlLkRvY1RyZWU7CmltcG9ydCBjb20uc3VuLnNvdXJjZS50cmVlLlRyZWU7CmltcG9ydCBjb20uc3VuLnRvb2xzLmRvY2xpbnQuRW52LkFjY2Vzc0tpbmQ7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuU3RyaW5nVXRpbHM7CgovKioKICogTWVzc2FnZSByZXBvcnRpbmcgZm9yIERvY0xpbnQuCiAqCiAqIE9wdGlvbnMgYXJlIHVzZWQgdG8gZmlsdGVyIG91dCBtZXNzYWdlcyBiYXNlZCBvbiBncm91cCBhbmQgYWNjZXNzIGxldmVsLgogKiBTdXBwb3J0IGNhbiBiZSBlbmFibGVkIGZvciBhY2N1bXVsYXRpbmcgc3RhdGlzdGljcyBvZiBkaWZmZXJlbnQga2luZHMgb2YKICogbWVzc2FnZXMuCiAqCiAqIDxwPjxiPlRoaXMgaXMgTk9UIHBhcnQgb2YgYW55IHN1cHBvcnRlZCBBUEkuCiAqIElmIHlvdSB3cml0ZSBjb2RlIHRoYXQgZGVwZW5kcyBvbiB0aGlzLCB5b3UgZG8gc28gYXQgeW91ciBvd24KICogcmlzay4gIFRoaXMgY29kZSBhbmQgaXRzIGludGVybmFsIGludGVyZmFjZXMgYXJlIHN1YmplY3QgdG8gY2hhbmdlCiAqIG9yIGRlbGV0aW9uIHdpdGhvdXQgbm90aWNlLjwvYj48L3A+CiAqLwpwdWJsaWMgY2xhc3MgTWVzc2FnZXMgewogICAgLyoqCiAgICAgKiBHcm91cHMgdXNlZCB0byBjYXRlZ29yaXplIG1lc3NhZ2VzLCBzbyB0aGF0IG1lc3NhZ2VzIGluIGVhY2ggZ3JvdXAKICAgICAqIGNhbiBiZSBlbmFibGVkIG9yIGRpc2FibGVkIHZpYSBvcHRpb25zLgogICAgICovCiAgICBwdWJsaWMgZW51bSBHcm91cCB7CiAgICAgICAgQUNDRVNTSUJJTElUWSwKICAgICAgICBIVE1MLAogICAgICAgIE1JU1NJTkcsCiAgICAgICAgU1lOVEFYLAogICAgICAgIFJFRkVSRU5DRTsKCiAgICAgICAgU3RyaW5nIG9wdE5hbWUoKSB7IHJldHVybiBTdHJpbmdVdGlscy50b0xvd2VyQ2FzZShuYW1lKCkpOyB9CiAgICAgICAgU3RyaW5nIG5vdE9wdE5hbWUoKSB7IHJldHVybiAiLSIgKyBvcHROYW1lKCk7IH0KCiAgICAgICAgc3RhdGljIGJvb2xlYW4gYWNjZXB0cyhTdHJpbmcgb3B0KSB7CiAgICAgICAgICAgIGZvciAoR3JvdXAgZzogdmFsdWVzKCkpCiAgICAgICAgICAgICAgICBpZiAob3B0LmVxdWFscyhnLm9wdE5hbWUoKSkpIHJldHVybiB0cnVlOwogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgZmluYWwgT3B0aW9ucyBvcHRpb25zOwogICAgcHJpdmF0ZSBmaW5hbCBTdGF0cyBzdGF0czsKCiAgICBSZXNvdXJjZUJ1bmRsZSBidW5kbGU7CiAgICBFbnYgZW52OwoKICAgIE1lc3NhZ2VzKEVudiBlbnYpIHsKICAgICAgICB0aGlzLmVudiA9IGVudjsKICAgICAgICBTdHJpbmcgbmFtZSA9IGdldENsYXNzKCkuZ2V0UGFja2FnZSgpLmdldE5hbWUoKSArICIucmVzb3VyY2VzLmRvY2xpbnQiOwogICAgICAgIGJ1bmRsZSA9IFJlc291cmNlQnVuZGxlLmdldEJ1bmRsZShuYW1lLCBMb2NhbGUuRU5HTElTSCk7CgogICAgICAgIHN0YXRzID0gbmV3IFN0YXRzKGJ1bmRsZSk7CiAgICAgICAgb3B0aW9ucyA9IG5ldyBPcHRpb25zKHN0YXRzKTsKICAgIH0KCiAgICB2b2lkIGVycm9yKEdyb3VwIGdyb3VwLCBEb2NUcmVlIHRyZWUsIFN0cmluZyBjb2RlLCBPYmplY3QuLi4gYXJncykgewogICAgICAgIHJlcG9ydChncm91cCwgRGlhZ25vc3RpYy5LaW5kLkVSUk9SLCB0cmVlLCBjb2RlLCBhcmdzKTsKICAgIH0KCiAgICB2b2lkIHdhcm5pbmcoR3JvdXAgZ3JvdXAsIERvY1RyZWUgdHJlZSwgU3RyaW5nIGNvZGUsIE9iamVjdC4uLiBhcmdzKSB7CiAgICAgICAgcmVwb3J0KGdyb3VwLCBEaWFnbm9zdGljLktpbmQuV0FSTklORywgdHJlZSwgY29kZSwgYXJncyk7CiAgICB9CgogICAgdm9pZCBzZXRPcHRpb25zKFN0cmluZyBvcHRzKSB7CiAgICAgICAgb3B0aW9ucy5zZXRPcHRpb25zKG9wdHMpOwogICAgfQoKICAgIHZvaWQgc2V0U3RhdHNFbmFibGVkKGJvb2xlYW4gYikgewogICAgICAgIHN0YXRzLnNldEVuYWJsZWQoYik7CiAgICB9CgogICAgdm9pZCByZXBvcnRTdGF0cyhQcmludFdyaXRlciBvdXQpIHsKICAgICAgICBzdGF0cy5yZXBvcnQob3V0KTsKICAgIH0KCiAgICBwcm90ZWN0ZWQgdm9pZCByZXBvcnQoR3JvdXAgZ3JvdXAsIERpYWdub3N0aWMuS2luZCBka2luZCwgRG9jVHJlZSB0cmVlLCBTdHJpbmcgY29kZSwgT2JqZWN0Li4uIGFyZ3MpIHsKICAgICAgICBpZiAob3B0aW9ucy5pc0VuYWJsZWQoZ3JvdXAsIGVudi5jdXJyQWNjZXNzKSkgewogICAgICAgICAgICBTdHJpbmcgbXNnID0gKGNvZGUgPT0gbnVsbCkgPyAoU3RyaW5nKSBhcmdzWzBdIDogbG9jYWxpemUoY29kZSwgYXJncyk7CiAgICAgICAgICAgIGVudi50cmVlcy5wcmludE1lc3NhZ2UoZGtpbmQsIG1zZywgdHJlZSwKICAgICAgICAgICAgICAgICAgICBlbnYuY3VyckRvY0NvbW1lbnQsIGVudi5jdXJyUGF0aC5nZXRDb21waWxhdGlvblVuaXQoKSk7CgogICAgICAgICAgICBzdGF0cy5yZWNvcmQoZ3JvdXAsIGRraW5kLCBjb2RlKTsKICAgICAgICB9CiAgICB9CgogICAgcHJvdGVjdGVkIHZvaWQgcmVwb3J0KEdyb3VwIGdyb3VwLCBEaWFnbm9zdGljLktpbmQgZGtpbmQsIFRyZWUgdHJlZSwgU3RyaW5nIGNvZGUsIE9iamVjdC4uLiBhcmdzKSB7CiAgICAgICAgaWYgKG9wdGlvbnMuaXNFbmFibGVkKGdyb3VwLCBlbnYuY3VyckFjY2VzcykpIHsKICAgICAgICAgICAgU3RyaW5nIG1zZyA9IGxvY2FsaXplKGNvZGUsIGFyZ3MpOwogICAgICAgICAgICBlbnYudHJlZXMucHJpbnRNZXNzYWdlKGRraW5kLCBtc2csIHRyZWUsIGVudi5jdXJyUGF0aC5nZXRDb21waWxhdGlvblVuaXQoKSk7CgogICAgICAgICAgICBzdGF0cy5yZWNvcmQoZ3JvdXAsIGRraW5kLCBjb2RlKTsKICAgICAgICB9CiAgICB9CgogICAgU3RyaW5nIGxvY2FsaXplKFN0cmluZyBjb2RlLCBPYmplY3QuLi4gYXJncykgewogICAgICAgIFN0cmluZyBtc2cgPSBidW5kbGUuZ2V0U3RyaW5nKGNvZGUpOwogICAgICAgIGlmIChtc2cgPT0gbnVsbCkgewogICAgICAgICAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKICAgICAgICAgICAgc2IuYXBwZW5kKCJtZXNzYWdlIGZpbGUgYnJva2VuOiBjb2RlPSIpLmFwcGVuZChjb2RlKTsKICAgICAgICAgICAgaWYgKGFyZ3MubGVuZ3RoID4gMCkgewogICAgICAgICAgICAgICAgc2IuYXBwZW5kKCIgYXJndW1lbnRzPXswfSIpOwogICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDE7IGkgPCBhcmdzLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgc2IuYXBwZW5kKCIsIHsiKS5hcHBlbmQoaSkuYXBwZW5kKCJ9Iik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgbXNnID0gc2IudG9TdHJpbmcoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIE1lc3NhZ2VGb3JtYXQuZm9ybWF0KG1zZywgYXJncyk7CiAgICB9CgogICAgLy8gPGVkaXRvci1mb2xkIGRlZmF1bHRzdGF0ZT0iY29sbGFwc2VkIiBkZXNjPSJPcHRpb25zIj4KCiAgICAvKioKICAgICAqIEhhbmRsZXIgZm9yIChzdWIpb3B0aW9ucyBzcGVjaWZpYyB0byBtZXNzYWdlIGhhbmRsaW5nLgogICAgICovCiAgICBzdGF0aWMgY2xhc3MgT3B0aW9ucyB7CiAgICAgICAgTWFwPFN0cmluZywgRW52LkFjY2Vzc0tpbmQ+IG1hcCA9IG5ldyBIYXNoTWFwPD4oKTsKICAgICAgICBwcml2YXRlIGZpbmFsIFN0YXRzIHN0YXRzOwoKICAgICAgICBzdGF0aWMgYm9vbGVhbiBpc1ZhbGlkT3B0aW9ucyhTdHJpbmcgb3B0cykgewogICAgICAgICAgICBmb3IgKFN0cmluZyBvcHQ6IG9wdHMuc3BsaXQoIiwiKSkgewogICAgICAgICAgICAgICAgaWYgKCFpc1ZhbGlkT3B0aW9uKFN0cmluZ1V0aWxzLnRvTG93ZXJDYXNlKG9wdC50cmltKCkpKSkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGlzVmFsaWRPcHRpb24oU3RyaW5nIG9wdCkgewogICAgICAgICAgICBpZiAob3B0LmVxdWFscygibm9uZSIpIHx8IG9wdC5lcXVhbHMoU3RhdHMuT1BUKSkKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwoKICAgICAgICAgICAgaW50IGJlZ2luID0gb3B0LnN0YXJ0c1dpdGgoIi0iKSA/IDEgOiAwOwogICAgICAgICAgICBpbnQgc2VwID0gb3B0LmluZGV4T2YoIi8iKTsKICAgICAgICAgICAgU3RyaW5nIGdycCA9IG9wdC5zdWJzdHJpbmcoYmVnaW4sIChzZXAgIT0gLTEpID8gc2VwIDogb3B0Lmxlbmd0aCgpKTsKICAgICAgICAgICAgcmV0dXJuICgoYmVnaW4gPT0gMCAmJiBncnAuZXF1YWxzKCJhbGwiKSkgfHwgR3JvdXAuYWNjZXB0cyhncnApKQogICAgICAgICAgICAgICAgICAgICYmICgoc2VwID09IC0xKSB8fCBBY2Nlc3NLaW5kLmFjY2VwdHMob3B0LnN1YnN0cmluZyhzZXAgKyAxKSkpOwogICAgICAgIH0KCiAgICAgICAgT3B0aW9ucyhTdGF0cyBzdGF0cykgewogICAgICAgICAgICB0aGlzLnN0YXRzID0gc3RhdHM7CiAgICAgICAgfQoKICAgICAgICAvKiogRGV0ZXJtaW5lIGlmIGEgbWVzc2FnZSBncm91cCBpcyBlbmFibGVkIGZvciBhIHBhcnRpY3VsYXIgYWNjZXNzIGxldmVsLiAqLwogICAgICAgIGJvb2xlYW4gaXNFbmFibGVkKEdyb3VwIGcsIEVudi5BY2Nlc3NLaW5kIGFjY2VzcykgewogICAgICAgICAgICBpZiAobWFwLmlzRW1wdHkoKSkKICAgICAgICAgICAgICAgIG1hcC5wdXQoImFsbCIsIEVudi5BY2Nlc3NLaW5kLlBST1RFQ1RFRCk7CgogICAgICAgICAgICBFbnYuQWNjZXNzS2luZCBhayA9IG1hcC5nZXQoZy5vcHROYW1lKCkpOwogICAgICAgICAgICBpZiAoYWsgIT0gbnVsbCAmJiBhY2Nlc3MuY29tcGFyZVRvKGFrKSA+PSAwKQogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CgogICAgICAgICAgICBhayA9IG1hcC5nZXQoQUxMKTsKICAgICAgICAgICAgaWYgKGFrICE9IG51bGwgJiYgYWNjZXNzLmNvbXBhcmVUbyhhaykgPj0gMCkgewogICAgICAgICAgICAgICAgYWsgPSBtYXAuZ2V0KGcubm90T3B0TmFtZSgpKTsKICAgICAgICAgICAgICAgIGlmIChhayA9PSBudWxsIHx8IGFjY2Vzcy5jb21wYXJlVG8oYWspID4gMCkgLy8gbm90ZSA+LCBub3QgPj0KICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgdm9pZCBzZXRPcHRpb25zKFN0cmluZyBvcHRzKSB7CiAgICAgICAgICAgIGlmIChvcHRzID09IG51bGwpCiAgICAgICAgICAgICAgICBzZXRPcHRpb24oQUxMLCBFbnYuQWNjZXNzS2luZC5QUklWQVRFKTsKICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICBmb3IgKFN0cmluZyBvcHQ6IG9wdHMuc3BsaXQoIiwiKSkKICAgICAgICAgICAgICAgICAgICBzZXRPcHRpb24oU3RyaW5nVXRpbHMudG9Mb3dlckNhc2Uob3B0LnRyaW0oKSkpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIHZvaWQgc2V0T3B0aW9uKFN0cmluZyBhcmcpIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gewogICAgICAgICAgICBpZiAoYXJnLmVxdWFscyhTdGF0cy5PUFQpKSB7CiAgICAgICAgICAgICAgICBzdGF0cy5zZXRFbmFibGVkKHRydWUpOwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpbnQgc2VwID0gYXJnLmluZGV4T2YoIi8iKTsKICAgICAgICAgICAgaWYgKHNlcCA+IDApIHsKICAgICAgICAgICAgICAgIEVudi5BY2Nlc3NLaW5kIGFrID0gRW52LkFjY2Vzc0tpbmQudmFsdWVPZihTdHJpbmdVdGlscy50b1VwcGVyQ2FzZShhcmcuc3Vic3RyaW5nKHNlcCArIDEpKSk7CiAgICAgICAgICAgICAgICBzZXRPcHRpb24oYXJnLnN1YnN0cmluZygwLCBzZXApLCBhayk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBzZXRPcHRpb24oYXJnLCBudWxsKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSB2b2lkIHNldE9wdGlvbihTdHJpbmcgb3B0LCBFbnYuQWNjZXNzS2luZCBhaykgewogICAgICAgICAgICBtYXAucHV0KG9wdCwgKGFrICE9IG51bGwpID8gYWsKICAgICAgICAgICAgICAgICAgICA6IG9wdC5zdGFydHNXaXRoKCItIikgPyBFbnYuQWNjZXNzS2luZC5QVUJMSUMgOiBFbnYuQWNjZXNzS2luZC5QUklWQVRFKTsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBBTEwgPSAiYWxsIjsKICAgIH0KCiAgICAvLyA8L2VkaXRvci1mb2xkPgoKICAgIC8vIDxlZGl0b3ItZm9sZCBkZWZhdWx0c3RhdGU9ImNvbGxhcHNlZCIgZGVzYz0iU3RhdGlzdGljcyI+CgogICAgLyoqCiAgICAgKiBPcHRpb25hbGx5IHJlY29yZCBzdGF0aXN0aWNzIG9mIGRpZmZlcmVudCBraW5kcyBvZiBtZXNzYWdlLgogICAgICovCiAgICBzdGF0aWMgY2xhc3MgU3RhdHMgewogICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIE9QVCA9ICJzdGF0cyI7CiAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTk9fQ09ERSA9ICIiOwogICAgICAgIGZpbmFsIFJlc291cmNlQnVuZGxlIGJ1bmRsZTsKCiAgICAgICAgLy8gdGFibGVzIG9ubHkgaW5pdGlhbGl6ZWQgaWYgZW5hYmxlZAogICAgICAgIGludFtdIGdyb3VwQ291bnRzOwogICAgICAgIGludFtdIGRraW5kQ291bnRzOwogICAgICAgIE1hcDxTdHJpbmcsIEludGVnZXI+IGNvZGVDb3VudHM7CgogICAgICAgIFN0YXRzKFJlc291cmNlQnVuZGxlIGJ1bmRsZSkgewogICAgICAgICAgICB0aGlzLmJ1bmRsZSA9IGJ1bmRsZTsKICAgICAgICB9CgogICAgICAgIHZvaWQgc2V0RW5hYmxlZChib29sZWFuIGIpIHsKICAgICAgICAgICAgaWYgKGIpIHsKICAgICAgICAgICAgICAgIGdyb3VwQ291bnRzID0gbmV3IGludFtNZXNzYWdlcy5Hcm91cC52YWx1ZXMoKS5sZW5ndGhdOwogICAgICAgICAgICAgICAgZGtpbmRDb3VudHMgPSBuZXcgaW50W0RpYWdub3N0aWMuS2luZC52YWx1ZXMoKS5sZW5ndGhdOwogICAgICAgICAgICAgICAgY29kZUNvdW50cyA9IG5ldyBIYXNoTWFwPD4oKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGdyb3VwQ291bnRzID0gbnVsbDsKICAgICAgICAgICAgICAgIGRraW5kQ291bnRzID0gbnVsbDsKICAgICAgICAgICAgICAgIGNvZGVDb3VudHMgPSBudWxsOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICB2b2lkIHJlY29yZChNZXNzYWdlcy5Hcm91cCBnLCBEaWFnbm9zdGljLktpbmQgZGtpbmQsIFN0cmluZyBjb2RlKSB7CiAgICAgICAgICAgIGlmIChjb2RlQ291bnRzID09IG51bGwpIHsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgICAgICBncm91cENvdW50c1tnLm9yZGluYWwoKV0rKzsKICAgICAgICAgICAgZGtpbmRDb3VudHNbZGtpbmQub3JkaW5hbCgpXSsrOwogICAgICAgICAgICBpZiAoY29kZSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICBjb2RlID0gTk9fQ09ERTsKICAgICAgICAgICAgfQogICAgICAgICAgICBJbnRlZ2VyIGkgPSBjb2RlQ291bnRzLmdldChjb2RlKTsKICAgICAgICAgICAgY29kZUNvdW50cy5wdXQoY29kZSwgKGkgPT0gbnVsbCkgPyAxIDogaSArIDEpOwogICAgICAgIH0KCiAgICAgICAgdm9pZCByZXBvcnQoUHJpbnRXcml0ZXIgb3V0KSB7CiAgICAgICAgICAgIGlmIChjb2RlQ291bnRzID09IG51bGwpIHsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgICAgICBvdXQucHJpbnRsbigiQnkgZ3JvdXAuLi4iKTsKICAgICAgICAgICAgVGFibGUgZ3JvdXBUYWJsZSA9IG5ldyBUYWJsZSgpOwogICAgICAgICAgICBmb3IgKE1lc3NhZ2VzLkdyb3VwIGcgOiBNZXNzYWdlcy5Hcm91cC52YWx1ZXMoKSkgewogICAgICAgICAgICAgICAgZ3JvdXBUYWJsZS5wdXQoZy5vcHROYW1lKCksIGdyb3VwQ291bnRzW2cub3JkaW5hbCgpXSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZ3JvdXBUYWJsZS5wcmludChvdXQpOwogICAgICAgICAgICBvdXQucHJpbnRsbigpOwogICAgICAgICAgICBvdXQucHJpbnRsbigiQnkgZGlhZ25vc3RpYyBraW5kLi4uIik7CiAgICAgICAgICAgIFRhYmxlIGRraW5kVGFibGUgPSBuZXcgVGFibGUoKTsKICAgICAgICAgICAgZm9yIChEaWFnbm9zdGljLktpbmQgayA6IERpYWdub3N0aWMuS2luZC52YWx1ZXMoKSkgewogICAgICAgICAgICAgICAgZGtpbmRUYWJsZS5wdXQoU3RyaW5nVXRpbHMudG9Mb3dlckNhc2Uoay50b1N0cmluZygpKSwgZGtpbmRDb3VudHNbay5vcmRpbmFsKCldKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBka2luZFRhYmxlLnByaW50KG91dCk7CiAgICAgICAgICAgIG91dC5wcmludGxuKCk7CiAgICAgICAgICAgIG91dC5wcmludGxuKCJCeSBtZXNzYWdlIGtpbmQuLi4iKTsKICAgICAgICAgICAgVGFibGUgY29kZVRhYmxlID0gbmV3IFRhYmxlKCk7CiAgICAgICAgICAgIGZvciAoTWFwLkVudHJ5PFN0cmluZywgSW50ZWdlcj4gZSA6IGNvZGVDb3VudHMuZW50cnlTZXQoKSkgewogICAgICAgICAgICAgICAgU3RyaW5nIGNvZGUgPSBlLmdldEtleSgpOwogICAgICAgICAgICAgICAgU3RyaW5nIG1zZzsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgbXNnID0gY29kZS5lcXVhbHMoTk9fQ09ERSkgPyAiT1RIRVIiIDogYnVuZGxlLmdldFN0cmluZyhjb2RlKTsKICAgICAgICAgICAgICAgIH0gY2F0Y2ggKE1pc3NpbmdSZXNvdXJjZUV4Y2VwdGlvbiBleCkgewogICAgICAgICAgICAgICAgICAgIG1zZyA9IGNvZGU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBjb2RlVGFibGUucHV0KG1zZywgZS5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBjb2RlVGFibGUucHJpbnQob3V0KTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIEEgdGFibGUgb2YgKGludCwgU3RyaW5nKSBzb3J0ZWQgYnkgZGVjcmVhc2luZyBpbnQuCiAgICAgICAgICovCiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgVGFibGUgewoKICAgICAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQ29tcGFyYXRvcjxJbnRlZ2VyPiBERUNSRUFTSU5HID0gKG8xLCBvMikgLT4gbzIuY29tcGFyZVRvKG8xKTsKICAgICAgICAgICAgcHJpdmF0ZSBmaW5hbCBUcmVlTWFwPEludGVnZXIsIFNldDxTdHJpbmc+PiBtYXAgPSBuZXcgVHJlZU1hcDw+KERFQ1JFQVNJTkcpOwoKICAgICAgICAgICAgdm9pZCBwdXQoU3RyaW5nIGxhYmVsLCBpbnQgbikgewogICAgICAgICAgICAgICAgaWYgKG4gPT0gMCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIFNldDxTdHJpbmc+IGxhYmVscyA9IG1hcC5nZXQobik7CiAgICAgICAgICAgICAgICBpZiAobGFiZWxzID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICBtYXAucHV0KG4sIGxhYmVscyA9IG5ldyBUcmVlU2V0PD4oKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBsYWJlbHMuYWRkKGxhYmVsKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdm9pZCBwcmludChQcmludFdyaXRlciBvdXQpIHsKICAgICAgICAgICAgICAgIGZvciAoTWFwLkVudHJ5PEludGVnZXIsIFNldDxTdHJpbmc+PiBlIDogbWFwLmVudHJ5U2V0KCkpIHsKICAgICAgICAgICAgICAgICAgICBpbnQgY291bnQgPSBlLmdldEtleSgpOwogICAgICAgICAgICAgICAgICAgIFNldDxTdHJpbmc+IGxhYmVscyA9IGUuZ2V0VmFsdWUoKTsKICAgICAgICAgICAgICAgICAgICBmb3IgKFN0cmluZyBsYWJlbCA6IGxhYmVscykgewogICAgICAgICAgICAgICAgICAgICAgICBvdXQucHJpbnRsbihTdHJpbmcuZm9ybWF0KCIlNmQ6ICVzIiwgY291bnQsIGxhYmVsKSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgLy8gPC9lZGl0b3ItZm9sZD4KfQpQSwMECgAACAAABjupSnvuv1RxVAAAcVQAACIAAABjb20vc3VuL3Rvb2xzL2RvY2xpbnQvSHRtbFRhZy5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDEwLCAyMDE2LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGNvbS5zdW4udG9vbHMuZG9jbGludDsKCmltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbnM7CmltcG9ydCBqYXZhLnV0aWwuRW51bU1hcDsKaW1wb3J0IGphdmEudXRpbC5FbnVtU2V0OwppbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CmltcG9ydCBqYXZhLnV0aWwuTWFwOwppbXBvcnQgamF2YS51dGlsLlNldDsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC5OYW1lOwoKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5TdHJpbmdVdGlsczsKCmltcG9ydCBzdGF0aWMgY29tLnN1bi50b29scy5kb2NsaW50Lkh0bWxUYWcuQXR0ci4qOwoKLyoqCiAqIEVudW0gcmVwcmVzZW50aW5nIEhUTUwgdGFncy4KICoKICogVGhlIGludGVudCBvZiB0aGlzIGNsYXNzIGlzIHRvIGVtYm9keSB0aGUgc2VtYW50aWNzIG9mIFczQyBIVE1MIDQuMDEKICogdG8gdGhlIGV4dGVudCBzdXBwb3J0ZWQvdXNlZCBieSBqYXZhZG9jLgogKiBJbiB0aW1lLCB3ZSBtYXkgd2lzaCB0byB0cmFuc2l0aW9uIGphdmFkb2MgYW5kIGRvY2xpbnQgdG8gdXNpbmcgSFRNTCA1LgogKgogKiBUaGlzIGlzIGRlcml2YXRpdmUgb2YgY29tLnN1bi50b29scy5kb2NsZXRzLmZvcm1hdHMuaHRtbC5tYXJrdXAuSHRtbFRhZy4KICogRXZlbnR1YWxseSwgdGhlc2UgdHdvIHNob3VsZCBiZSBtZXJnZWQgYmFjayB0b2dldGhlciwgYW5kIHBvc3NpYmx5IG1hZGUKICogcHVibGljLgogKgogKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL1JFQy1odG1sNDAvIj5IVE1MIDQuMDEgU3BlY2lmaWNhdGlvbjwvYT4KICogQHNlZSA8YSBocmVmPSJodHRwOi8vd3d3LnczLm9yZy9UUi9odG1sNS8iPkhUTUwgNSBTcGVjaWZpY2F0aW9uPC9hPgogKiBAc2VlIDxhIGhyZWY9Imh0dHA6Ly93d3cudzMub3JnL1RSL3dhaS1hcmlhLyAiPldBSS1BUklBIFNwZWNpZmljYXRpb248L2E+CiAqIEBzZWUgPGEgaHJlZj0iaHR0cDovL3d3dy53My5vcmcvVFIvYXJpYS1pbi1odG1sLyNyZWNvbW1lbmRhdGlvbnMtdGFibGUiPldBSS1BUklBIFJlY29tbWVuZGF0aW9ucyBUYWJsZTwvYT4KICogQGF1dGhvciBCaGF2ZXNoIFBhdGVsCiAqIEBhdXRob3IgSm9uYXRoYW4gR2liYm9ucyAocmV2aXNlZCkKICovCnB1YmxpYyBlbnVtIEh0bWxUYWcgewogICAgQShCbG9ja1R5cGUuSU5MSU5FLCBFbmRLaW5kLlJFUVVJUkVELAogICAgICAgICAgICBhdHRycyhBdHRyS2luZC5BTEwsIEhSRUYsIFRBUkdFVCwgSUQpLAogICAgICAgICAgICBhdHRycyhBdHRyS2luZC5IVE1MNCwgUkVWLCBDSEFSU0VULCBTSEFQRSwgQ09PUkRTLCBOQU1FKSksCgogICAgQUJCUihCbG9ja1R5cGUuSU5MSU5FLCBFbmRLaW5kLlJFUVVJUkVELAogICAgICAgICAgICBFbnVtU2V0Lm9mKEZsYWcuRVhQRUNUX0NPTlRFTlQsIEZsYWcuTk9fTkVTVCkpLAoKICAgIEFDUk9OWU0oSHRtbFZlcnNpb24uSFRNTDQsIEJsb2NrVHlwZS5JTkxJTkUsIEVuZEtpbmQuUkVRVUlSRUQsCiAgICAgICAgICAgIEVudW1TZXQub2YoRmxhZy5FWFBFQ1RfQ09OVEVOVCwgRmxhZy5OT19ORVNUKSksCgogICAgQUREUkVTUyhCbG9ja1R5cGUuSU5MSU5FLCBFbmRLaW5kLlJFUVVJUkVELAogICAgICAgICAgICBFbnVtU2V0Lm9mKEZsYWcuRVhQRUNUX0NPTlRFTlQsIEZsYWcuTk9fTkVTVCkpLAoKICAgIEFSVElDTEUoSHRtbFZlcnNpb24uSFRNTDUsIEJsb2NrVHlwZS5CTE9DSywgRW5kS2luZC5SRVFVSVJFRCwKICAgICAgICAgICAgRW51bVNldC5vZihGbGFnLkFDQ0VQVFNfQkxPQ0ssIEZsYWcuQUNDRVBUU19JTkxJTkUpKSwKCiAgICBBU0lERShIdG1sVmVyc2lvbi5IVE1MNSwgQmxvY2tUeXBlLkJMT0NLLCBFbmRLaW5kLlJFUVVJUkVELAogICAgICAgICAgICBFbnVtU2V0Lm9mKEZsYWcuQUNDRVBUU19CTE9DSywgRmxhZy5BQ0NFUFRTX0lOTElORSkpLAoKICAgIEIoQmxvY2tUeXBlLklOTElORSwgRW5kS2luZC5SRVFVSVJFRCwKICAgICAgICAgICAgRW51bVNldC5vZihGbGFnLkVYUEVDVF9DT05URU5ULCBGbGFnLk5PX05FU1QpKSwKCiAgICBCREkoSHRtbFZlcnNpb24uSFRNTDUsIEJsb2NrVHlwZS5JTkxJTkUsIEVuZEtpbmQuUkVRVUlSRUQpLAoKICAgIEJJRyhIdG1sVmVyc2lvbi5IVE1MNCwgQmxvY2tUeXBlLklOTElORSwgRW5kS2luZC5SRVFVSVJFRCwKICAgICAgICAgICAgRW51bVNldC5vZihGbGFnLkVYUEVDVF9DT05URU5UKSksCgogICAgQkxPQ0tRVU9URShCbG9ja1R5cGUuQkxPQ0ssIEVuZEtpbmQuUkVRVUlSRUQsCiAgICAgICAgICAgIEVudW1TZXQub2YoRmxhZy5BQ0NFUFRTX0JMT0NLLCBGbGFnLkFDQ0VQVFNfSU5MSU5FKSksCgogICAgQk9EWShCbG9ja1R5cGUuT1RIRVIsIEVuZEtpbmQuUkVRVUlSRUQpLAoKICAgIEJSKEJsb2NrVHlwZS5JTkxJTkUsIEVuZEtpbmQuTk9ORSwKICAgICAgICAgICAgYXR0cnMoQXR0cktpbmQuVVNFX0NTUywgQ0xFQVIpKSwKCiAgICBDQVBUSU9OKEJsb2NrVHlwZS5UQUJMRV9JVEVNLCBFbmRLaW5kLlJFUVVJUkVELAogICAgICAgICAgICBFbnVtU2V0Lm9mKEZsYWcuQUNDRVBUU19JTkxJTkUsIEZsYWcuRVhQRUNUX0NPTlRFTlQpLAogICAgICAgICAgICBhdHRycyhBdHRyS2luZC5VU0VfQ1NTLCBBTElHTikpLAoKICAgIENFTlRFUihIdG1sVmVyc2lvbi5IVE1MNCwgQmxvY2tUeXBlLkJMT0NLLCBFbmRLaW5kLlJFUVVJUkVELAogICAgICAgICAgICBFbnVtU2V0Lm9mKEZsYWcuQUNDRVBUU19CTE9DSywgRmxhZy5BQ0NFUFRTX0lOTElORSkpLAoKICAgIENJVEUoQmxvY2tUeXBlLklOTElORSwgRW5kS2luZC5SRVFVSVJFRCwKICAgICAgICAgICAgRW51bVNldC5vZihGbGFnLkVYUEVDVF9DT05URU5ULCBGbGFnLk5PX05FU1QpKSwKCiAgICBDT0RFKEJsb2NrVHlwZS5JTkxJTkUsIEVuZEtpbmQuUkVRVUlSRUQsCiAgICAgICAgICAgIEVudW1TZXQub2YoRmxhZy5FWFBFQ1RfQ09OVEVOVCwgRmxhZy5OT19ORVNUKSksCgogICAgQ09MKEJsb2NrVHlwZS5UQUJMRV9JVEVNLCBFbmRLaW5kLk5PTkUsCiAgICAgICAgICAgIGF0dHJzKEF0dHJLaW5kLkhUTUw0LCBBTElHTiwgQ0hBUiwgQ0hBUk9GRiwgVkFMSUdOLCBXSURUSCkpLAoKICAgIENPTEdST1VQKEJsb2NrVHlwZS5UQUJMRV9JVEVNLCBFbmRLaW5kLlJFUVVJUkVELAogICAgICAgICAgICBhdHRycyhBdHRyS2luZC5IVE1MNCwgQUxJR04sIENIQVIsIENIQVJPRkYsIFZBTElHTiwgV0lEVEgpKSB7CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gYWNjZXB0cyhIdG1sVGFnIHQpIHsKICAgICAgICAgICAgcmV0dXJuICh0ID09IENPTCk7CiAgICAgICAgfQogICAgfSwKCiAgICBERChCbG9ja1R5cGUuTElTVF9JVEVNLCBFbmRLaW5kLk9QVElPTkFMLAogICAgICAgICAgICBFbnVtU2V0Lm9mKEZsYWcuQUNDRVBUU19CTE9DSywgRmxhZy5BQ0NFUFRTX0lOTElORSwgRmxhZy5FWFBFQ1RfQ09OVEVOVCkpLAoKICAgIERFTChCbG9ja1R5cGUuSU5MSU5FLCBFbmRLaW5kLlJFUVVJUkVELAogICAgICAgICAgICBFbnVtU2V0Lm9mKEZsYWcuRVhQRUNUX0NPTlRFTlQsIEZsYWcuTk9fTkVTVCksCiAgICAgICAgICAgIGF0dHJzKEF0dHJLaW5kLkFMTCwgQXR0ci5DSVRFLCBBdHRyLkRBVEVUSU1FKSksCgogICAgREZOKEJsb2NrVHlwZS5JTkxJTkUsIEVuZEtpbmQuUkVRVUlSRUQsCiAgICAgICAgICAgIEVudW1TZXQub2YoRmxhZy5FWFBFQ1RfQ09OVEVOVCwgRmxhZy5OT19ORVNUKSksCgogICAgRElWKEJsb2NrVHlwZS5CTE9DSywgRW5kS2luZC5SRVFVSVJFRCwKICAgICAgICAgICAgRW51bVNldC5vZihGbGFnLkFDQ0VQVFNfQkxPQ0ssIEZsYWcuQUNDRVBUU19JTkxJTkUpLAogICAgICAgICAgICBhdHRycyhBdHRyS2luZC5VU0VfQ1NTLCBBTElHTikpLAoKICAgIERMKEJsb2NrVHlwZS5CTE9DSywgRW5kS2luZC5SRVFVSVJFRCwKICAgICAgICAgICAgRW51bVNldC5vZihGbGFnLkVYUEVDVF9DT05URU5UKSwKICAgICAgICAgICAgYXR0cnMoQXR0cktpbmQuVVNFX0NTUywgQ09NUEFDVCkpIHsKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgYm9vbGVhbiBhY2NlcHRzKEh0bWxUYWcgdCkgewogICAgICAgICAgICByZXR1cm4gKHQgPT0gRFQpIHx8ICh0ID09IEREKTsKICAgICAgICB9CiAgICB9LAoKICAgIERUKEJsb2NrVHlwZS5MSVNUX0lURU0sIEVuZEtpbmQuT1BUSU9OQUwsCiAgICAgICAgICAgIEVudW1TZXQub2YoRmxhZy5BQ0NFUFRTX0lOTElORSwgRmxhZy5FWFBFQ1RfQ09OVEVOVCkpLAoKICAgIEVNKEJsb2NrVHlwZS5JTkxJTkUsIEVuZEtpbmQuUkVRVUlSRUQsCiAgICAgICAgICAgIEVudW1TZXQub2YoRmxhZy5OT19ORVNUKSksCgogICAgRk9OVChIdG1sVmVyc2lvbi5IVE1MNCwgQmxvY2tUeXBlLklOTElORSwgRW5kS2luZC5SRVFVSVJFRCwgLy8gdGFnIGl0c2VsZiBpcyBkZXByZWNhdGVkCiAgICAgICAgICAgIEVudW1TZXQub2YoRmxhZy5FWFBFQ1RfQ09OVEVOVCksCiAgICAgICAgICAgIGF0dHJzKEF0dHJLaW5kLlVTRV9DU1MsIFNJWkUsIENPTE9SLCBGQUNFKSksCgogICAgRk9PVEVSKEh0bWxWZXJzaW9uLkhUTUw1LCBCbG9ja1R5cGUuQkxPQ0ssIEVuZEtpbmQuUkVRVUlSRUQsCiAgICAgICAgICAgIEVudW1TZXQub2YoRmxhZy5BQ0NFUFRTX0JMT0NLLCBGbGFnLkFDQ0VQVFNfSU5MSU5FKSkgewogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBib29sZWFuIGFjY2VwdHMoSHRtbFRhZyB0KSB7CiAgICAgICAgICAgIHN3aXRjaCAodCkgewogICAgICAgICAgICAgICAgY2FzZSBIRUFERVI6IGNhc2UgRk9PVEVSOiBjYXNlIE1BSU46CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gKHQuYmxvY2tUeXBlID09IEJsb2NrVHlwZS5CTE9DSykgfHwgKHQuYmxvY2tUeXBlID09IEJsb2NrVHlwZS5JTkxJTkUpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSwKCiAgICBGSUdVUkUoSHRtbFZlcnNpb24uSFRNTDUsIEJsb2NrVHlwZS5CTE9DSywgRW5kS2luZC5SRVFVSVJFRCwKICAgICAgICAgICAgRW51bVNldC5vZihGbGFnLkFDQ0VQVFNfQkxPQ0ssIEZsYWcuQUNDRVBUU19JTkxJTkUpKSwKCiAgICBGSUdDQVBUSU9OKEh0bWxWZXJzaW9uLkhUTUw1LCBCbG9ja1R5cGUuQkxPQ0ssIEVuZEtpbmQuUkVRVUlSRUQpLAoKICAgIEZSQU1FKEh0bWxWZXJzaW9uLkhUTUw0LCBCbG9ja1R5cGUuT1RIRVIsIEVuZEtpbmQuTk9ORSksCgogICAgRlJBTUVTRVQoSHRtbFZlcnNpb24uSFRNTDQsIEJsb2NrVHlwZS5PVEhFUiwgRW5kS2luZC5SRVFVSVJFRCksCgogICAgSDEoQmxvY2tUeXBlLkJMT0NLLCBFbmRLaW5kLlJFUVVJUkVELAogICAgICAgICAgICBhdHRycyhBdHRyS2luZC5VU0VfQ1NTLCBBTElHTikpLAogICAgSDIoQmxvY2tUeXBlLkJMT0NLLCBFbmRLaW5kLlJFUVVJUkVELAogICAgICAgICAgICBhdHRycyhBdHRyS2luZC5VU0VfQ1NTLCBBTElHTikpLAogICAgSDMoQmxvY2tUeXBlLkJMT0NLLCBFbmRLaW5kLlJFUVVJUkVELAogICAgICAgICAgICBhdHRycyhBdHRyS2luZC5VU0VfQ1NTLCBBTElHTikpLAogICAgSDQoQmxvY2tUeXBlLkJMT0NLLCBFbmRLaW5kLlJFUVVJUkVELAogICAgICAgICAgICBhdHRycyhBdHRyS2luZC5VU0VfQ1NTLCBBTElHTikpLAogICAgSDUoQmxvY2tUeXBlLkJMT0NLLCBFbmRLaW5kLlJFUVVJUkVELAogICAgICAgICAgICBhdHRycyhBdHRyS2luZC5VU0VfQ1NTLCBBTElHTikpLAogICAgSDYoQmxvY2tUeXBlLkJMT0NLLCBFbmRLaW5kLlJFUVVJUkVELAogICAgICAgICAgICBhdHRycyhBdHRyS2luZC5VU0VfQ1NTLCBBTElHTikpLAoKICAgIEhFQUQoQmxvY2tUeXBlLk9USEVSLCBFbmRLaW5kLlJFUVVJUkVEKSwKCiAgICBIRUFERVIoSHRtbFZlcnNpb24uSFRNTDUsIEJsb2NrVHlwZS5CTE9DSywgRW5kS2luZC5SRVFVSVJFRCwKICAgICAgICAgICAgRW51bVNldC5vZihGbGFnLkFDQ0VQVFNfQkxPQ0ssIEZsYWcuQUNDRVBUU19JTkxJTkUpKSB7CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gYWNjZXB0cyhIdG1sVGFnIHQpIHsKICAgICAgICAgICAgc3dpdGNoICh0KSB7CiAgICAgICAgICAgICAgICBjYXNlIEhFQURFUjogY2FzZSBGT09URVI6IGNhc2UgTUFJTjoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgIHJldHVybiAodC5ibG9ja1R5cGUgPT0gQmxvY2tUeXBlLkJMT0NLKSB8fCAodC5ibG9ja1R5cGUgPT0gQmxvY2tUeXBlLklOTElORSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9LAoKICAgIEhSKEJsb2NrVHlwZS5CTE9DSywgRW5kS2luZC5OT05FLAogICAgICAgICAgICBhdHRycyhBdHRyS2luZC5IVE1MNCwgV0lEVEgpLAogICAgICAgICAgICBhdHRycyhBdHRyS2luZC5VU0VfQ1NTLCBBTElHTiwgTk9TSEFERSwgU0laRSkpLAoKICAgIEhUTUwoQmxvY2tUeXBlLk9USEVSLCBFbmRLaW5kLlJFUVVJUkVEKSwKCiAgICBJKEJsb2NrVHlwZS5JTkxJTkUsIEVuZEtpbmQuUkVRVUlSRUQsCiAgICAgICAgICAgIEVudW1TZXQub2YoRmxhZy5FWFBFQ1RfQ09OVEVOVCwgRmxhZy5OT19ORVNUKSksCgogICAgSUZSQU1FKEJsb2NrVHlwZS5PVEhFUiwgRW5kS2luZC5SRVFVSVJFRCksCgogICAgSU1HKEJsb2NrVHlwZS5JTkxJTkUsIEVuZEtpbmQuTk9ORSwKICAgICAgICAgICAgYXR0cnMoQXR0cktpbmQuQUxMLCBTUkMsIEFMVCwgSEVJR0hULCBXSURUSCksCiAgICAgICAgICAgIGF0dHJzKEF0dHJLaW5kLkhUTUw1LCBDUk9TU09SSUdJTiksCiAgICAgICAgICAgIGF0dHJzKEF0dHJLaW5kLk9CU09MRVRFLCBOQU1FKSwKICAgICAgICAgICAgYXR0cnMoQXR0cktpbmQuVVNFX0NTUywgQUxJR04sIEhTUEFDRSwgVlNQQUNFLCBCT1JERVIpKSwKCiAgICBJTlMoQmxvY2tUeXBlLklOTElORSwgRW5kS2luZC5SRVFVSVJFRCwKICAgICAgICAgICAgRW51bVNldC5vZihGbGFnLkVYUEVDVF9DT05URU5ULCBGbGFnLk5PX05FU1QpLAogICAgICAgICAgICBhdHRycyhBdHRyS2luZC5BTEwsIEF0dHIuQ0lURSwgQXR0ci5EQVRFVElNRSkpLAoKICAgIEtCRChCbG9ja1R5cGUuSU5MSU5FLCBFbmRLaW5kLlJFUVVJUkVELAogICAgICAgICAgICBFbnVtU2V0Lm9mKEZsYWcuRVhQRUNUX0NPTlRFTlQsIEZsYWcuTk9fTkVTVCkpLAoKICAgIExJKEJsb2NrVHlwZS5MSVNUX0lURU0sIEVuZEtpbmQuT1BUSU9OQUwsCiAgICAgICAgICAgIEVudW1TZXQub2YoRmxhZy5BQ0NFUFRTX0JMT0NLLCBGbGFnLkFDQ0VQVFNfSU5MSU5FKSwKICAgICAgICAgICAgYXR0cnMoQXR0cktpbmQuQUxMLCBWQUxVRSksCiAgICAgICAgICAgIGF0dHJzKEF0dHJLaW5kLlVTRV9DU1MsIFRZUEUpKSwKCiAgICBMSU5LKEJsb2NrVHlwZS5PVEhFUiwgRW5kS2luZC5OT05FKSwKCiAgICBNQUlOKEh0bWxWZXJzaW9uLkhUTUw1LCBCbG9ja1R5cGUuT1RIRVIsIEVuZEtpbmQuUkVRVUlSRUQpLAoKICAgIE1BUksoSHRtbFZlcnNpb24uSFRNTDUsIEJsb2NrVHlwZS5JTkxJTkUsIEVuZEtpbmQuUkVRVUlSRUQpLAoKICAgIE1FTlUoQmxvY2tUeXBlLkJMT0NLLCBFbmRLaW5kLlJFUVVJUkVEKSB7CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gYWNjZXB0cyhIdG1sVGFnIHQpIHsKICAgICAgICAgICAgcmV0dXJuICh0ID09IExJKTsKICAgICAgICB9CiAgICB9LAoKICAgIE1FVEEoQmxvY2tUeXBlLk9USEVSLCBFbmRLaW5kLk5PTkUpLAoKICAgIE5BVihIdG1sVmVyc2lvbi5IVE1MNSwgQmxvY2tUeXBlLkJMT0NLLCBFbmRLaW5kLlJFUVVJUkVELAogICAgICAgICAgICBFbnVtU2V0Lm9mKEZsYWcuQUNDRVBUU19CTE9DSywgRmxhZy5BQ0NFUFRTX0lOTElORSkpLAoKICAgIE5PRlJBTUVTKEh0bWxWZXJzaW9uLkhUTUw0LCBCbG9ja1R5cGUuT1RIRVIsIEVuZEtpbmQuUkVRVUlSRUQpLAoKICAgIE5PU0NSSVBUKEJsb2NrVHlwZS5CTE9DSywgRW5kS2luZC5SRVFVSVJFRCksCgogICAgT0woQmxvY2tUeXBlLkJMT0NLLCBFbmRLaW5kLlJFUVVJUkVELAogICAgICAgICAgICBFbnVtU2V0Lm9mKEZsYWcuRVhQRUNUX0NPTlRFTlQpLAogICAgICAgICAgICBhdHRycyhBdHRyS2luZC5BTEwsIFNUQVJULCBUWVBFKSwKICAgICAgICAgICAgYXR0cnMoQXR0cktpbmQuSFRNTDUsIFJFVkVSU0VEKSwKICAgICAgICAgICAgYXR0cnMoQXR0cktpbmQuVVNFX0NTUywgQ09NUEFDVCkpIHsKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgYm9vbGVhbiBhY2NlcHRzKEh0bWxUYWcgdCkgewogICAgICAgICAgICByZXR1cm4gKHQgPT0gTEkpOwogICAgICAgIH0KICAgIH0sCgogICAgUChCbG9ja1R5cGUuQkxPQ0ssIEVuZEtpbmQuT1BUSU9OQUwsCiAgICAgICAgICAgIEVudW1TZXQub2YoRmxhZy5FWFBFQ1RfQ09OVEVOVCksCiAgICAgICAgICAgIGF0dHJzKEF0dHJLaW5kLlVTRV9DU1MsIEFMSUdOKSksCgogICAgUFJFKEJsb2NrVHlwZS5CTE9DSywgRW5kS2luZC5SRVFVSVJFRCwKICAgICAgICAgICAgRW51bVNldC5vZihGbGFnLkVYUEVDVF9DT05URU5UKSwKICAgICAgICAgICAgYXR0cnMoQXR0cktpbmQuVVNFX0NTUywgV0lEVEgpKSB7CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gYWNjZXB0cyhIdG1sVGFnIHQpIHsKICAgICAgICAgICAgc3dpdGNoICh0KSB7CiAgICAgICAgICAgICAgICBjYXNlIElNRzogY2FzZSBCSUc6IGNhc2UgU01BTEw6IGNhc2UgU1VCOiBjYXNlIFNVUDoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgIHJldHVybiAodC5ibG9ja1R5cGUgPT0gQmxvY2tUeXBlLklOTElORSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9LAoKICAgIFEoQmxvY2tUeXBlLklOTElORSwgRW5kS2luZC5SRVFVSVJFRCwKICAgICAgICAgICAgRW51bVNldC5vZihGbGFnLkVYUEVDVF9DT05URU5ULCBGbGFnLk5PX05FU1QpKSwKCiAgICBTKEJsb2NrVHlwZS5JTkxJTkUsIEVuZEtpbmQuUkVRVUlSRUQsCiAgICAgICAgICAgIEVudW1TZXQub2YoRmxhZy5FWFBFQ1RfQ09OVEVOVCwgRmxhZy5OT19ORVNUKSksCgogICAgU0FNUChCbG9ja1R5cGUuSU5MSU5FLCBFbmRLaW5kLlJFUVVJUkVELAogICAgICAgICAgICBFbnVtU2V0Lm9mKEZsYWcuRVhQRUNUX0NPTlRFTlQsIEZsYWcuTk9fTkVTVCkpLAoKICAgIFNDUklQVChCbG9ja1R5cGUuT1RIRVIsIEVuZEtpbmQuUkVRVUlSRUQsCiAgICAgICAgICAgIGF0dHJzKEF0dHJLaW5kLkFMTCwgU1JDKSksCgogICAgU0VDVElPTihIdG1sVmVyc2lvbi5IVE1MNSwgQmxvY2tUeXBlLkJMT0NLLCBFbmRLaW5kLlJFUVVJUkVELAogICAgICAgICAgICBFbnVtU2V0Lm9mKEZsYWcuQUNDRVBUU19CTE9DSywgRmxhZy5BQ0NFUFRTX0lOTElORSkpLAoKICAgIFNNQUxMKEJsb2NrVHlwZS5JTkxJTkUsIEVuZEtpbmQuUkVRVUlSRUQsCiAgICAgICAgICAgIEVudW1TZXQub2YoRmxhZy5FWFBFQ1RfQ09OVEVOVCkpLAoKICAgIFNQQU4oQmxvY2tUeXBlLklOTElORSwgRW5kS2luZC5SRVFVSVJFRCwKICAgICAgICAgICAgRW51bVNldC5vZihGbGFnLkVYUEVDVF9DT05URU5UKSksCgogICAgU1RSSUtFKEh0bWxWZXJzaW9uLkhUTUw0LCBCbG9ja1R5cGUuSU5MSU5FLCBFbmRLaW5kLlJFUVVJUkVELAogICAgICAgICAgICBFbnVtU2V0Lm9mKEZsYWcuRVhQRUNUX0NPTlRFTlQpKSwKCiAgICBTVFJPTkcoQmxvY2tUeXBlLklOTElORSwgRW5kS2luZC5SRVFVSVJFRCwKICAgICAgICAgICAgRW51bVNldC5vZihGbGFnLkVYUEVDVF9DT05URU5UKSksCgogICAgU1VCKEJsb2NrVHlwZS5JTkxJTkUsIEVuZEtpbmQuUkVRVUlSRUQsCiAgICAgICAgICAgIEVudW1TZXQub2YoRmxhZy5FWFBFQ1RfQ09OVEVOVCwgRmxhZy5OT19ORVNUKSksCgogICAgU1VQKEJsb2NrVHlwZS5JTkxJTkUsIEVuZEtpbmQuUkVRVUlSRUQsCiAgICAgICAgICAgIEVudW1TZXQub2YoRmxhZy5FWFBFQ1RfQ09OVEVOVCwgRmxhZy5OT19ORVNUKSksCgogICAgVEFCTEUoQmxvY2tUeXBlLkJMT0NLLCBFbmRLaW5kLlJFUVVJUkVELAogICAgICAgICAgICBFbnVtU2V0Lm9mKEZsYWcuRVhQRUNUX0NPTlRFTlQpLAogICAgICAgICAgICBhdHRycyhBdHRyS2luZC5BTEwsIEJPUkRFUiksCiAgICAgICAgICAgIGF0dHJzKEF0dHJLaW5kLkhUTUw0LCBTVU1NQVJZLCBDRUxMUEFERElORywgQ0VMTFNQQUNJTkcsIEF0dHIuRlJBTUUsIFJVTEVTLCBXSURUSCksCiAgICAgICAgICAgIGF0dHJzKEF0dHJLaW5kLlVTRV9DU1MsIEFMSUdOLCBCR0NPTE9SKSkgewogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBib29sZWFuIGFjY2VwdHMoSHRtbFRhZyB0KSB7CiAgICAgICAgICAgIHN3aXRjaCAodCkgewogICAgICAgICAgICAgICAgY2FzZSBDQVBUSU9OOgogICAgICAgICAgICAgICAgY2FzZSBDT0xHUk9VUDoKICAgICAgICAgICAgICAgIGNhc2UgVEhFQUQ6IGNhc2UgVEJPRFk6IGNhc2UgVEZPT1Q6CiAgICAgICAgICAgICAgICBjYXNlIFRSOiAvLyBIVE1MIDMuMgogICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9LAoKICAgIFRCT0RZKEJsb2NrVHlwZS5UQUJMRV9JVEVNLCBFbmRLaW5kLlJFUVVJUkVELAogICAgICAgICAgICBFbnVtU2V0Lm9mKEZsYWcuRVhQRUNUX0NPTlRFTlQpLAogICAgICAgICAgICBhdHRycyhBdHRyS2luZC5BTEwsIFZBTElHTiksCiAgICAgICAgICAgIGF0dHJzKEF0dHJLaW5kLkhUTUw0LCBBTElHTiwgQ0hBUiwgQ0hBUk9GRikpIHsKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgYm9vbGVhbiBhY2NlcHRzKEh0bWxUYWcgdCkgewogICAgICAgICAgICByZXR1cm4gKHQgPT0gVFIpOwogICAgICAgIH0KICAgIH0sCgogICAgVEQoQmxvY2tUeXBlLlRBQkxFX0lURU0sIEVuZEtpbmQuT1BUSU9OQUwsCiAgICAgICAgICAgIEVudW1TZXQub2YoRmxhZy5BQ0NFUFRTX0JMT0NLLCBGbGFnLkFDQ0VQVFNfSU5MSU5FKSwKICAgICAgICAgICAgYXR0cnMoQXR0cktpbmQuQUxMLCBDT0xTUEFOLCBST1dTUEFOLCBIRUFERVJTLCBWQUxJR04pLAogICAgICAgICAgICBhdHRycyhBdHRyS2luZC5IVE1MNCwgQVhJUywgQXR0ci5BQkJSLCBTQ09QRSwgQUxJR04sIENIQVIsIENIQVJPRkYpLAogICAgICAgICAgICBhdHRycyhBdHRyS2luZC5VU0VfQ1NTLCBXSURUSCwgQkdDT0xPUiwgSEVJR0hULCBOT1dSQVApKSwKCiAgICBURU1QTEFURShIdG1sVmVyc2lvbi5IVE1MNSwgQmxvY2tUeXBlLkJMT0NLLCBFbmRLaW5kLlJFUVVJUkVELAogICAgICAgICAgICBFbnVtU2V0Lm9mKEZsYWcuQUNDRVBUU19CTE9DSywgRmxhZy5BQ0NFUFRTX0lOTElORSkpLAoKICAgIFRGT09UKEJsb2NrVHlwZS5UQUJMRV9JVEVNLCBFbmRLaW5kLlJFUVVJUkVELAogICAgICAgICAgICBhdHRycyhBdHRyS2luZC5BTEwsIFZBTElHTiksCiAgICAgICAgICAgIGF0dHJzKEF0dHJLaW5kLkhUTUw0LCBBTElHTiwgQ0hBUiwgQ0hBUk9GRikpIHsKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgYm9vbGVhbiBhY2NlcHRzKEh0bWxUYWcgdCkgewogICAgICAgICAgICByZXR1cm4gKHQgPT0gVFIpOwogICAgICAgIH0KICAgIH0sCgogICAgVEgoQmxvY2tUeXBlLlRBQkxFX0lURU0sIEVuZEtpbmQuT1BUSU9OQUwsCiAgICAgICAgICAgIEVudW1TZXQub2YoRmxhZy5BQ0NFUFRTX0JMT0NLLCBGbGFnLkFDQ0VQVFNfSU5MSU5FKSwKICAgICAgICAgICAgYXR0cnMoQXR0cktpbmQuQUxMLCBDT0xTUEFOLCBST1dTUEFOLCBIRUFERVJTLCBTQ09QRSwgQXR0ci5BQkJSLAogICAgICAgICAgICAgICAgVkFMSUdOKSwKICAgICAgICAgICAgYXR0cnMoQXR0cktpbmQuSFRNTDQsIEFYSVMsIEFMSUdOLCBDSEFSLCBDSEFST0ZGKSwKICAgICAgICAgICAgYXR0cnMoQXR0cktpbmQuVVNFX0NTUywgV0lEVEgsIEJHQ09MT1IsIEhFSUdIVCwgTk9XUkFQKSksCgogICAgVEhFQUQoQmxvY2tUeXBlLlRBQkxFX0lURU0sIEVuZEtpbmQuUkVRVUlSRUQsCiAgICAgICAgICAgIGF0dHJzKEF0dHJLaW5kLkFMTCwgVkFMSUdOKSwKICAgICAgICAgICAgYXR0cnMoQXR0cktpbmQuSFRNTDQsIEFMSUdOLCBDSEFSLCBDSEFST0ZGKSkgewogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBib29sZWFuIGFjY2VwdHMoSHRtbFRhZyB0KSB7CiAgICAgICAgICAgIHJldHVybiAodCA9PSBUUik7CiAgICAgICAgfQogICAgfSwKCiAgICBUSU1FKEh0bWxWZXJzaW9uLkhUTUw1LCBCbG9ja1R5cGUuSU5MSU5FLCBFbmRLaW5kLlJFUVVJUkVEKSwKCiAgICBUSVRMRShCbG9ja1R5cGUuT1RIRVIsIEVuZEtpbmQuUkVRVUlSRUQpLAoKICAgIFRSKEJsb2NrVHlwZS5UQUJMRV9JVEVNLCBFbmRLaW5kLk9QVElPTkFMLAogICAgICAgICAgICBhdHRycyhBdHRyS2luZC5BTEwsIFZBTElHTiksCiAgICAgICAgICAgIGF0dHJzKEF0dHJLaW5kLkhUTUw0LCBBTElHTiwgQ0hBUiwgQ0hBUk9GRiksCiAgICAgICAgICAgIGF0dHJzKEF0dHJLaW5kLlVTRV9DU1MsIEJHQ09MT1IpKSB7CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gYWNjZXB0cyhIdG1sVGFnIHQpIHsKICAgICAgICAgICAgcmV0dXJuICh0ID09IFRIKSB8fCAodCA9PSBURCk7CiAgICAgICAgfQogICAgfSwKCiAgICBUVChIdG1sVmVyc2lvbi5IVE1MNCwgQmxvY2tUeXBlLklOTElORSwgRW5kS2luZC5SRVFVSVJFRCwKICAgICAgICAgICAgRW51bVNldC5vZihGbGFnLkVYUEVDVF9DT05URU5ULCBGbGFnLk5PX05FU1QpKSwKCiAgICBVKEJsb2NrVHlwZS5JTkxJTkUsIEVuZEtpbmQuUkVRVUlSRUQsCiAgICAgICAgICAgIEVudW1TZXQub2YoRmxhZy5FWFBFQ1RfQ09OVEVOVCwgRmxhZy5OT19ORVNUKSksCgogICAgVUwoQmxvY2tUeXBlLkJMT0NLLCBFbmRLaW5kLlJFUVVJUkVELAogICAgICAgICAgICBFbnVtU2V0Lm9mKEZsYWcuRVhQRUNUX0NPTlRFTlQpLAogICAgICAgICAgICBhdHRycyhBdHRyS2luZC5IVE1MNCwgQ09NUEFDVCwgVFlQRSkpIHsKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgYm9vbGVhbiBhY2NlcHRzKEh0bWxUYWcgdCkgewogICAgICAgICAgICByZXR1cm4gKHQgPT0gTEkpOwogICAgICAgIH0KICAgIH0sCgogICAgV0JSKEh0bWxWZXJzaW9uLkhUTUw1LCBCbG9ja1R5cGUuSU5MSU5FLCBFbmRLaW5kLlJFUVVJUkVEKSwKCiAgICBWQVIoQmxvY2tUeXBlLklOTElORSwgRW5kS2luZC5SRVFVSVJFRCk7CgogICAgLyoqCiAgICAgKiBFbnVtIHJlcHJlc2VudGluZyB0aGUgdHlwZSBvZiBIVE1MIGVsZW1lbnQuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZW51bSBCbG9ja1R5cGUgewogICAgICAgIEJMT0NLLAogICAgICAgIElOTElORSwKICAgICAgICBMSVNUX0lURU0sCiAgICAgICAgVEFCTEVfSVRFTSwKICAgICAgICBPVEhFUgogICAgfQoKICAgIC8qKgogICAgICogRW51bSByZXByZXNlbnRpbmcgSFRNTCBlbmQgdGFnIHJlcXVpcmVtZW50LgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGVudW0gRW5kS2luZCB7CiAgICAgICAgTk9ORSwKICAgICAgICBPUFRJT05BTCwKICAgICAgICBSRVFVSVJFRAogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZW51bSBGbGFnIHsKICAgICAgICBBQ0NFUFRTX0JMT0NLLAogICAgICAgIEFDQ0VQVFNfSU5MSU5FLAogICAgICAgIEVYUEVDVF9DT05URU5ULAogICAgICAgIE5PX05FU1QKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGVudW0gQXR0ciB7CiAgICAgICAgQUJCUiwKICAgICAgICBBTElHTiwKICAgICAgICBBTElOSywKICAgICAgICBBTFQsCiAgICAgICAgQVJJQV9BQ1RJVkVERVNDRU5EQU5ULAogICAgICAgIEFSSUFfQ09OVFJPTFMsCiAgICAgICAgQVJJQV9ERVNDUklCRURCWSwKICAgICAgICBBUklBX0VYUEFOREVELAogICAgICAgIEFSSUFfTEFCRUwsCiAgICAgICAgQVJJQV9MQUJFTExFREJZLAogICAgICAgIEFSSUFfTEVWRUwsCiAgICAgICAgQVJJQV9NVUxUSVNFTEVDVEFCTEUsCiAgICAgICAgQVJJQV9PV05TLAogICAgICAgIEFSSUFfUE9TSU5TRVQsCiAgICAgICAgQVJJQV9TRVRTSVpFLAogICAgICAgIEFSSUFfUkVBRE9OTFksCiAgICAgICAgQVJJQV9SRVFVSVJFRCwKICAgICAgICBBUklBX1NFTEVDVEVELAogICAgICAgIEFSSUFfU09SVCwKICAgICAgICBBWElTLAogICAgICAgIEJBQ0tHUk9VTkQsCiAgICAgICAgQkdDT0xPUiwKICAgICAgICBCT1JERVIsCiAgICAgICAgQ0VMTFNQQUNJTkcsCiAgICAgICAgQ0VMTFBBRERJTkcsCiAgICAgICAgQ0hBUiwKICAgICAgICBDSEFST0ZGLAogICAgICAgIENIQVJTRVQsCiAgICAgICAgQ0lURSwKICAgICAgICBDTEVBUiwKICAgICAgICBDTEFTUywKICAgICAgICBDT0xPUiwKICAgICAgICBDT0xTUEFOLAogICAgICAgIENPTVBBQ1QsCiAgICAgICAgQ09PUkRTLAogICAgICAgIENST1NTT1JJR0lOLAogICAgICAgIERBVEVUSU1FLAogICAgICAgIEZBQ0UsCiAgICAgICAgRlJBTUUsCiAgICAgICAgRlJBTUVCT1JERVIsCiAgICAgICAgSEVBREVSUywKICAgICAgICBIRUlHSFQsCiAgICAgICAgSFJFRiwKICAgICAgICBIU1BBQ0UsCiAgICAgICAgSUQsCiAgICAgICAgTElOSywKICAgICAgICBMT05HREVTQywKICAgICAgICBNQVJHSU5IRUlHSFQsCiAgICAgICAgTUFSR0lOV0lEVEgsCiAgICAgICAgTkFNRSwKICAgICAgICBOT1NIQURFLAogICAgICAgIE5PV1JBUCwKICAgICAgICBQUk9GSUxFLAogICAgICAgIFJFViwKICAgICAgICBSRVZFUlNFRCwKICAgICAgICBST0xFLAogICAgICAgIFJPV1NQQU4sCiAgICAgICAgUlVMRVMsCiAgICAgICAgU0NIRU1FLAogICAgICAgIFNDT1BFLAogICAgICAgIFNDUk9MTElORywKICAgICAgICBTSEFQRSwKICAgICAgICBTSVpFLAogICAgICAgIFNQQUNFLAogICAgICAgIFNSQywKICAgICAgICBTVEFSVCwKICAgICAgICBTVFlMRSwKICAgICAgICBTVU1NQVJZLAogICAgICAgIFRBUkdFVCwKICAgICAgICBURVhULAogICAgICAgIFRZUEUsCiAgICAgICAgVkFMSUdOLAogICAgICAgIFZBTFVFLAogICAgICAgIFZFUlNJT04sCiAgICAgICAgVkxJTkssCiAgICAgICAgVlNQQUNFLAogICAgICAgIFdJRFRIOwoKICAgICAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBuYW1lOwoKICAgICAgICBBdHRyKCkgewogICAgICAgICAgICBuYW1lID0gU3RyaW5nVXRpbHMudG9Mb3dlckNhc2UobmFtZSgpLnJlcGxhY2UoIl8iLCAiLSIpKTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0VGV4dCgpIHsKICAgICAgICAgICAgcmV0dXJuIG5hbWU7CiAgICAgICAgfQoKICAgICAgICBzdGF0aWMgZmluYWwgTWFwPFN0cmluZyxBdHRyPiBpbmRleCA9IG5ldyBIYXNoTWFwPD4oKTsKICAgICAgICBzdGF0aWMgewogICAgICAgICAgICBmb3IgKEF0dHIgdDogdmFsdWVzKCkpIHsKICAgICAgICAgICAgICAgIGluZGV4LnB1dCh0LmdldFRleHQoKSwgdCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBlbnVtIEF0dHJLaW5kIHsKICAgICAgICBIVE1MNCwKICAgICAgICBIVE1MNSwKICAgICAgICBJTlZBTElELAogICAgICAgIE9CU09MRVRFLAogICAgICAgIFVTRV9DU1MsCiAgICAgICAgQUxMCiAgICB9CgogICAgLy8gVGhpcyBjbGFzcyBleGlzdHMgdG8gYXZvaWQgd2FybmluZ3MgZnJvbSB1c2luZyBwYXJhbWV0ZXJpemVkIHZhcmFyZyB0eXBlCiAgICAvLyBNYXA8QXR0cixBdHRyS2luZD4gaW4gc2lnbmF0dXJlIG9mIEh0bWxUYWcgY29uc3RydWN0b3IuCiAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBBdHRyTWFwIGV4dGVuZHMgRW51bU1hcDxBdHRyLEF0dHJLaW5kPiAgewogICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDA7CiAgICAgICAgQXR0ck1hcCgpIHsKICAgICAgICAgICAgc3VwZXIoQXR0ci5jbGFzcyk7CiAgICAgICAgfQogICAgfQoKCiAgICBwdWJsaWMgZmluYWwgSHRtbFZlcnNpb24gYWxsb3dlZFZlcnNpb247CiAgICBwdWJsaWMgZmluYWwgQmxvY2tUeXBlIGJsb2NrVHlwZTsKICAgIHB1YmxpYyBmaW5hbCBFbmRLaW5kIGVuZEtpbmQ7CiAgICBwdWJsaWMgZmluYWwgU2V0PEZsYWc+IGZsYWdzOwogICAgcHJpdmF0ZSBmaW5hbCBNYXA8QXR0cixBdHRyS2luZD4gYXR0cnM7CgogICAgSHRtbFRhZyhCbG9ja1R5cGUgYmxvY2tUeXBlLCBFbmRLaW5kIGVuZEtpbmQsIEF0dHJNYXAuLi4gYXR0ck1hcHMpIHsKICAgICAgICB0aGlzKEh0bWxWZXJzaW9uLkFMTCwgYmxvY2tUeXBlLCBlbmRLaW5kLCBDb2xsZWN0aW9ucy5lbXB0eVNldCgpLCBhdHRyTWFwcyk7CiAgICB9CgogICAgSHRtbFRhZyhIdG1sVmVyc2lvbiBhbGxvd2VkVmVyc2lvbiwgQmxvY2tUeXBlIGJsb2NrVHlwZSwgRW5kS2luZCBlbmRLaW5kLCBBdHRyTWFwLi4uIGF0dHJNYXBzKSB7CiAgICAgICAgdGhpcyhhbGxvd2VkVmVyc2lvbiwgYmxvY2tUeXBlLCBlbmRLaW5kLCBDb2xsZWN0aW9ucy5lbXB0eVNldCgpLCBhdHRyTWFwcyk7CiAgICB9CgogICAgSHRtbFRhZyhCbG9ja1R5cGUgYmxvY2tUeXBlLCBFbmRLaW5kIGVuZEtpbmQsIFNldDxGbGFnPiBmbGFncywgQXR0ck1hcC4uLiBhdHRyTWFwcykgewogICAgICAgIHRoaXMoSHRtbFZlcnNpb24uQUxMLCBibG9ja1R5cGUsIGVuZEtpbmQsIGZsYWdzLCBhdHRyTWFwcyk7CiAgICB9CgogICAgSHRtbFRhZyhIdG1sVmVyc2lvbiBhbGxvd2VkVmVyc2lvbiwgQmxvY2tUeXBlIGJsb2NrVHlwZSwgRW5kS2luZCBlbmRLaW5kLCBTZXQ8RmxhZz4gZmxhZ3MsIEF0dHJNYXAuLi4gYXR0ck1hcHMpIHsKICAgICAgICB0aGlzLmFsbG93ZWRWZXJzaW9uID0gYWxsb3dlZFZlcnNpb247CiAgICAgICAgdGhpcy5ibG9ja1R5cGUgPSBibG9ja1R5cGU7CiAgICAgICAgdGhpcy5lbmRLaW5kID0gZW5kS2luZDsKICAgICAgICB0aGlzLmZsYWdzID0gZmxhZ3M7CiAgICAgICAgdGhpcy5hdHRycyA9IG5ldyBFbnVtTWFwPD4oQXR0ci5jbGFzcyk7CiAgICAgICAgZm9yIChNYXA8QXR0cixBdHRyS2luZD4gbTogYXR0ck1hcHMpCiAgICAgICAgICAgIHRoaXMuYXR0cnMucHV0QWxsKG0pOwogICAgICAgIGF0dHJzLnB1dChBdHRyLkNMQVNTLCBBdHRyS2luZC5BTEwpOwogICAgICAgIGF0dHJzLnB1dChBdHRyLklELCBBdHRyS2luZC5BTEwpOwogICAgICAgIGF0dHJzLnB1dChBdHRyLlNUWUxFLCBBdHRyS2luZC5BTEwpOwogICAgICAgIGF0dHJzLnB1dChBdHRyLlJPTEUsIEF0dHJLaW5kLkhUTUw1KTsKICAgICAgICAvLyBmb3Igbm93LCBhc3N1bWUgdGhhdCBhbGwgQVJJQSBhdHRyaWJ1dGVzIGFyZSBhbGxvd2VkIG9uIGFsbCB0YWdzLgogICAgICAgIGF0dHJzLnB1dChBdHRyLkFSSUFfQUNUSVZFREVTQ0VOREFOVCwgQXR0cktpbmQuSFRNTDUpOwogICAgICAgIGF0dHJzLnB1dChBdHRyLkFSSUFfQ09OVFJPTFMsIEF0dHJLaW5kLkhUTUw1KTsKICAgICAgICBhdHRycy5wdXQoQXR0ci5BUklBX0RFU0NSSUJFREJZLCBBdHRyS2luZC5IVE1MNSk7CiAgICAgICAgYXR0cnMucHV0KEF0dHIuQVJJQV9FWFBBTkRFRCwgQXR0cktpbmQuSFRNTDUpOwogICAgICAgIGF0dHJzLnB1dChBdHRyLkFSSUFfTEFCRUwsIEF0dHJLaW5kLkhUTUw1KTsKICAgICAgICBhdHRycy5wdXQoQXR0ci5BUklBX0xBQkVMTEVEQlksIEF0dHJLaW5kLkhUTUw1KTsKICAgICAgICBhdHRycy5wdXQoQXR0ci5BUklBX0xFVkVMLCBBdHRyS2luZC5IVE1MNSk7CiAgICAgICAgYXR0cnMucHV0KEF0dHIuQVJJQV9NVUxUSVNFTEVDVEFCTEUsIEF0dHJLaW5kLkhUTUw1KTsKICAgICAgICBhdHRycy5wdXQoQXR0ci5BUklBX09XTlMsIEF0dHJLaW5kLkhUTUw1KTsKICAgICAgICBhdHRycy5wdXQoQXR0ci5BUklBX1BPU0lOU0VULCBBdHRyS2luZC5IVE1MNSk7CiAgICAgICAgYXR0cnMucHV0KEF0dHIuQVJJQV9SRUFET05MWSwgQXR0cktpbmQuSFRNTDUpOwogICAgICAgIGF0dHJzLnB1dChBdHRyLkFSSUFfUkVRVUlSRUQsIEF0dHJLaW5kLkhUTUw1KTsKICAgICAgICBhdHRycy5wdXQoQXR0ci5BUklBX1NFTEVDVEVELCBBdHRyS2luZC5IVE1MNSk7CiAgICAgICAgYXR0cnMucHV0KEF0dHIuQVJJQV9TRVRTSVpFLCBBdHRyS2luZC5IVE1MNSk7CiAgICAgICAgYXR0cnMucHV0KEF0dHIuQVJJQV9TT1JULCBBdHRyS2luZC5IVE1MNSk7CiAgICB9CgogICAgcHVibGljIGJvb2xlYW4gYWNjZXB0cyhIdG1sVGFnIHQpIHsKICAgICAgICBpZiAoZmxhZ3MuY29udGFpbnMoRmxhZy5BQ0NFUFRTX0JMT0NLKSAmJiBmbGFncy5jb250YWlucyhGbGFnLkFDQ0VQVFNfSU5MSU5FKSkgewogICAgICAgICAgICByZXR1cm4gKHQuYmxvY2tUeXBlID09IEJsb2NrVHlwZS5CTE9DSykgfHwgKHQuYmxvY2tUeXBlID09IEJsb2NrVHlwZS5JTkxJTkUpOwogICAgICAgIH0gZWxzZSBpZiAoZmxhZ3MuY29udGFpbnMoRmxhZy5BQ0NFUFRTX0JMT0NLKSkgewogICAgICAgICAgICByZXR1cm4gKHQuYmxvY2tUeXBlID09IEJsb2NrVHlwZS5CTE9DSyk7CiAgICAgICAgfSBlbHNlIGlmIChmbGFncy5jb250YWlucyhGbGFnLkFDQ0VQVFNfSU5MSU5FKSkgewogICAgICAgICAgICByZXR1cm4gKHQuYmxvY2tUeXBlID09IEJsb2NrVHlwZS5JTkxJTkUpOwogICAgICAgIH0gZWxzZQogICAgICAgICAgICBzd2l0Y2ggKGJsb2NrVHlwZSkgewogICAgICAgICAgICAgICAgY2FzZSBCTE9DSzoKICAgICAgICAgICAgICAgIGNhc2UgSU5MSU5FOgogICAgICAgICAgICAgICAgICAgIHJldHVybiAodC5ibG9ja1R5cGUgPT0gQmxvY2tUeXBlLklOTElORSk7CiAgICAgICAgICAgICAgICBjYXNlIE9USEVSOgogICAgICAgICAgICAgICAgICAgIC8vIE9USEVSIHRhZ3MgYXJlIGludmFsaWQgaW4gZG9jIGNvbW1lbnRzLCBhbmQgd2lsbCBiZQogICAgICAgICAgICAgICAgICAgIC8vIHJlcG9ydGVkIHNlcGFyYXRlbHksIHNvIHNpbGVudGx5IGFjY2VwdC9pZ25vcmUgYW55IGNvbnRlbnQKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgLy8gYW55IGNvbWJpbmF0aW9uIHdoaWNoIGNvdWxkIG90aGVyd2lzZSBhcnJpdmUgaGVyZQogICAgICAgICAgICAgICAgICAgIC8vIG91Z2h0IHRvIGhhdmUgYmVlbiBoYW5kbGVkIGluIGFuIG92ZXJyaWRpbmcgbWV0aG9kCiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKHRoaXMgKyAiOiIgKyB0KTsKICAgICAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBib29sZWFuIGFjY2VwdHNUZXh0KCkgewogICAgICAgIC8vIGdlbmVyYWxseSwgYW55d2hlcmUgd2UgY2FuIHB1dCB0ZXh0IHdlIGNhbiBhbHNvIHB1dCBpbmxpbmUgdGFnCiAgICAgICAgLy8gc28gY2hlY2sgaWYgYSB0eXBpY2FsIGlubGluZSB0YWcgaXMgYWxsb3dlZAogICAgICAgIHJldHVybiBhY2NlcHRzKEIpOwogICAgfQoKICAgIHB1YmxpYyBTdHJpbmcgZ2V0VGV4dCgpIHsKICAgICAgICByZXR1cm4gU3RyaW5nVXRpbHMudG9Mb3dlckNhc2UobmFtZSgpKTsKICAgIH0KCiAgICBwdWJsaWMgQXR0ciBnZXRBdHRyKE5hbWUgYXR0ck5hbWUpIHsKICAgICAgICByZXR1cm4gQXR0ci5pbmRleC5nZXQoU3RyaW5nVXRpbHMudG9Mb3dlckNhc2UoYXR0ck5hbWUudG9TdHJpbmcoKSkpOwogICAgfQoKICAgIHB1YmxpYyBBdHRyS2luZCBnZXRBdHRyS2luZChOYW1lIGF0dHJOYW1lKSB7CiAgICAgICAgQXR0cktpbmQgayA9IGF0dHJzLmdldChnZXRBdHRyKGF0dHJOYW1lKSk7IC8vIG51bGwtc2FmZQogICAgICAgIHJldHVybiAoayA9PSBudWxsKSA/IEF0dHJLaW5kLklOVkFMSUQgOiBrOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIEF0dHJNYXAgYXR0cnMoQXR0cktpbmQgaywgQXR0ci4uLiBhdHRycykgewogICAgICAgIEF0dHJNYXAgbWFwID0gbmV3IEF0dHJNYXAoKTsKICAgICAgICBmb3IgKEF0dHIgYTogYXR0cnMpIG1hcC5wdXQoYSwgayk7CiAgICAgICAgcmV0dXJuIG1hcDsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBNYXA8U3RyaW5nLCBIdG1sVGFnPiBpbmRleCA9IG5ldyBIYXNoTWFwPD4oKTsKICAgIHN0YXRpYyB7CiAgICAgICAgZm9yIChIdG1sVGFnIHQ6IHZhbHVlcygpKSB7CiAgICAgICAgICAgIGluZGV4LnB1dCh0LmdldFRleHQoKSwgdCk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgSHRtbFRhZyBnZXQoTmFtZSB0YWdOYW1lKSB7CiAgICAgICAgcmV0dXJuIGluZGV4LmdldChTdHJpbmdVdGlscy50b0xvd2VyQ2FzZSh0YWdOYW1lLnRvU3RyaW5nKCkpKTsKICAgIH0KfQpQSwMECgAACAAABjupSme0r4x+IgAAfiIAAB4AAABjb20vc3VuL3Rvb2xzL2RvY2xpbnQvRW52LmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTIsIDIwMTYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgY29tLnN1bi50b29scy5kb2NsaW50OwoKCmltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOwppbXBvcnQgamF2YS51dGlsLkhhc2hTZXQ7CmltcG9ydCBqYXZhLnV0aWwuTGlua2VkSGFzaFNldDsKaW1wb3J0IGphdmEudXRpbC5MaXN0OwppbXBvcnQgamF2YS51dGlsLlNldDsKaW1wb3J0IGphdmEudXRpbC5yZWdleC5QYXR0ZXJuOwoKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC5FbGVtZW50OwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5lbGVtZW50LkVsZW1lbnRLaW5kOwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5lbGVtZW50LkV4ZWN1dGFibGVFbGVtZW50OwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5lbGVtZW50Lk1vZGlmaWVyOwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC50eXBlLlR5cGVNaXJyb3I7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLnV0aWwuRWxlbWVudHM7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLnV0aWwuVHlwZXM7CmltcG9ydCBqYXZheC50b29scy5EaWFnbm9zdGljLktpbmQ7CgppbXBvcnQgY29tLnN1bi5zb3VyY2UuZG9jdHJlZS5Eb2NDb21tZW50VHJlZTsKaW1wb3J0IGNvbS5zdW4uc291cmNlLnRyZWUuQ29tcGlsYXRpb25Vbml0VHJlZTsKaW1wb3J0IGNvbS5zdW4uc291cmNlLnV0aWwuRG9jVHJlZXM7CmltcG9ydCBjb20uc3VuLnNvdXJjZS51dGlsLkphdmFjVGFzazsKaW1wb3J0IGNvbS5zdW4uc291cmNlLnV0aWwuU291cmNlUG9zaXRpb25zOwppbXBvcnQgY29tLnN1bi5zb3VyY2UudXRpbC5UcmVlUGF0aDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMubW9kZWwuSmF2YWNUeXBlczsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5KQ1RyZWU7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuTWF0Y2hpbmdVdGlsczsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5TdHJpbmdVdGlsczsKCi8qKgogKiBVdGlsaXR5IGNvbnRhaW5lciBmb3IgY3VycmVudCBleGVjdXRpb24gZW52aXJvbm1lbnQsCiAqIHByb3ZpZGluZyB0aGUgY3VycmVudCBkZWNsYXJhdGlvbiBhbmQgaXRzIGRvYyBjb21tZW50LgogKgogKiA8cD48Yj5UaGlzIGlzIE5PVCBwYXJ0IG9mIGFueSBzdXBwb3J0ZWQgQVBJLgogKiBJZiB5b3Ugd3JpdGUgY29kZSB0aGF0IGRlcGVuZHMgb24gdGhpcywgeW91IGRvIHNvIGF0IHlvdXIgb3duCiAqIHJpc2suICBUaGlzIGNvZGUgYW5kIGl0cyBpbnRlcm5hbCBpbnRlcmZhY2VzIGFyZSBzdWJqZWN0IHRvIGNoYW5nZQogKiBvciBkZWxldGlvbiB3aXRob3V0IG5vdGljZS48L2I+PC9wPgogKi8KcHVibGljIGNsYXNzIEVudiB7CiAgICAvKioKICAgICAqIEFjY2VzcyBraW5kcyBmb3IgZGVjbGFyYXRpb25zLgogICAgICovCiAgICBwdWJsaWMgZW51bSBBY2Nlc3NLaW5kIHsKICAgICAgICBQUklWQVRFLAogICAgICAgIFBBQ0tBR0UsCiAgICAgICAgUFJPVEVDVEVELAogICAgICAgIFBVQkxJQzsKCiAgICAgICAgc3RhdGljIGJvb2xlYW4gYWNjZXB0cyhTdHJpbmcgb3B0KSB7CiAgICAgICAgICAgIGZvciAoQWNjZXNzS2luZCBnOiB2YWx1ZXMoKSkKICAgICAgICAgICAgICAgIGlmIChvcHQuZXF1YWxzKFN0cmluZ1V0aWxzLnRvTG93ZXJDYXNlKGcubmFtZSgpKSkpIHJldHVybiB0cnVlOwogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICBzdGF0aWMgQWNjZXNzS2luZCBvZihTZXQ8TW9kaWZpZXI+IG1vZHMpIHsKICAgICAgICAgICAgaWYgKG1vZHMuY29udGFpbnMoTW9kaWZpZXIuUFVCTElDKSkKICAgICAgICAgICAgICAgIHJldHVybiBBY2Nlc3NLaW5kLlBVQkxJQzsKICAgICAgICAgICAgZWxzZSBpZiAobW9kcy5jb250YWlucyhNb2RpZmllci5QUk9URUNURUQpKQogICAgICAgICAgICAgICAgcmV0dXJuIEFjY2Vzc0tpbmQuUFJPVEVDVEVEOwogICAgICAgICAgICBlbHNlIGlmIChtb2RzLmNvbnRhaW5zKE1vZGlmaWVyLlBSSVZBVEUpKQogICAgICAgICAgICAgICAgcmV0dXJuIEFjY2Vzc0tpbmQuUFJJVkFURTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgcmV0dXJuIEFjY2Vzc0tpbmQuUEFDS0FHRTsKICAgICAgICB9CiAgICB9CgogICAgLyoqIE1lc3NhZ2UgaGFuZGxlci4gKi8KICAgIGZpbmFsIE1lc3NhZ2VzIG1lc3NhZ2VzOwoKICAgIGludCBpbXBsaWNpdEhlYWRlckxldmVsID0gMDsKCiAgICBTZXQ8U3RyaW5nPiBjdXN0b21UYWdzOwoKICAgIFNldDxQYXR0ZXJuPiBpbmNsdWRlUGFja2FnZXM7CiAgICBTZXQ8UGF0dGVybj4gZXhjbHVkZVBhY2thZ2VzOwoKICAgIEh0bWxWZXJzaW9uIGh0bWxWZXJzaW9uID0gSHRtbFZlcnNpb24uSFRNTDQ7CgogICAgLy8gVXRpbGl0eSBjbGFzc2VzCiAgICBEb2NUcmVlcyB0cmVlczsKICAgIEVsZW1lbnRzIGVsZW1lbnRzOwogICAgVHlwZXMgdHlwZXM7CgogICAgLy8gVHlwZXMgdXNlZCB3aGVuIGFuYWx5c2luZyBkb2MgY29tbWVudHMuCiAgICBUeXBlTWlycm9yIGphdmFfbGFuZ19FcnJvcjsKICAgIFR5cGVNaXJyb3IgamF2YV9sYW5nX1J1bnRpbWVFeGNlcHRpb247CiAgICBUeXBlTWlycm9yIGphdmFfbGFuZ19UaHJvd2FibGU7CiAgICBUeXBlTWlycm9yIGphdmFfbGFuZ19Wb2lkOwoKICAgIC8qKiBUaGUgcGF0aCBmb3IgdGhlIGRlY2xhcmF0aW9uIGNvbnRhaW5pbmcgdGhlIGNvbW1lbnQgY3VycmVudGx5IGJlaW5nIGFuYWx5emVkLiAqLwogICAgVHJlZVBhdGggY3VyclBhdGg7CiAgICAvKiogVGhlIGVsZW1lbnQgZm9yIHRoZSBkZWNsYXJhdGlvbiBjb250YWluaW5nIHRoZSBjb21tZW50IGN1cnJlbnRseSBiZWluZyBhbmFseXplZC4gKi8KICAgIEVsZW1lbnQgY3VyckVsZW1lbnQ7CiAgICAvKiogVGhlIGNvbW1lbnQgY3VycmVudCBiZWluZyBhbmFseXplZC4gKi8KICAgIERvY0NvbW1lbnRUcmVlIGN1cnJEb2NDb21tZW50OwogICAgLyoqCiAgICAgKiBUaGUgYWNjZXNzIGtpbmQgb2YgdGhlIGRlY2xhcmF0aW9uIGNvbnRhaW5pbmcgdGhlIGNvbW1lbnQgY3VycmVudGx5IGJlaW5nIGFuYWx5emVkLgogICAgICogVGhpcyBpcyB0aGUgbWluaW11bSAobW9zdCByZXN0cmljdGl2ZSkgYWNjZXNzIGtpbmQgb2YgdGhlIGRlY2xhcmF0aW9uIGl0c2VsZgogICAgICogYW5kIHRoYXQgb2YgaXRzIGNvbnRhaW5lcnMuIEZvciBleGFtcGxlLCBhIHB1YmxpYyBtZXRob2QgaW4gYSBwcml2YXRlIGNsYXNzIGlzCiAgICAgKiBub3RlZCBhcyBwcml2YXRlLgogICAgICovCiAgICBBY2Nlc3NLaW5kIGN1cnJBY2Nlc3M7CiAgICAvKiogVGhlIHNldCBvZiBtZXRob2RzLCBpZiBhbnksIHRoYXQgdGhlIGN1cnJlbnQgZGVjbGFyYXRpb24gb3ZlcnJpZGVzLiAqLwogICAgU2V0PD8gZXh0ZW5kcyBFeGVjdXRhYmxlRWxlbWVudD4gY3Vyck92ZXJyaWRkZW5NZXRob2RzOwoKICAgIEVudigpIHsKICAgICAgICBtZXNzYWdlcyA9IG5ldyBNZXNzYWdlcyh0aGlzKTsKICAgIH0KCiAgICB2b2lkIGluaXQoSmF2YWNUYXNrIHRhc2spIHsKICAgICAgICBpbml0KERvY1RyZWVzLmluc3RhbmNlKHRhc2spLCB0YXNrLmdldEVsZW1lbnRzKCksIHRhc2suZ2V0VHlwZXMoKSk7CiAgICB9CgogICAgdm9pZCBpbml0KERvY1RyZWVzIHRyZWVzLCBFbGVtZW50cyBlbGVtZW50cywgVHlwZXMgdHlwZXMpIHsKICAgICAgICB0aGlzLnRyZWVzID0gdHJlZXM7CiAgICAgICAgdGhpcy5lbGVtZW50cyA9IGVsZW1lbnRzOwogICAgICAgIHRoaXMudHlwZXMgPSB0eXBlczsKICAgIH0KCiAgICB2b2lkIGluaXRUeXBlcygpIHsKICAgICAgICBpZiAoamF2YV9sYW5nX0Vycm9yICE9IG51bGwpCiAgICAgICAgICAgIHJldHVybiA7CgogICAgICAgIGphdmFfbGFuZ19FcnJvciA9IGVsZW1lbnRzLmdldFR5cGVFbGVtZW50KCJqYXZhLmxhbmcuRXJyb3IiKS5hc1R5cGUoKTsKICAgICAgICBqYXZhX2xhbmdfUnVudGltZUV4Y2VwdGlvbiA9IGVsZW1lbnRzLmdldFR5cGVFbGVtZW50KCJqYXZhLmxhbmcuUnVudGltZUV4Y2VwdGlvbiIpLmFzVHlwZSgpOwogICAgICAgIGphdmFfbGFuZ19UaHJvd2FibGUgPSBlbGVtZW50cy5nZXRUeXBlRWxlbWVudCgiamF2YS5sYW5nLlRocm93YWJsZSIpLmFzVHlwZSgpOwogICAgICAgIGphdmFfbGFuZ19Wb2lkID0gZWxlbWVudHMuZ2V0VHlwZUVsZW1lbnQoImphdmEubGFuZy5Wb2lkIikuYXNUeXBlKCk7CiAgICB9CgogICAgdm9pZCBzZXRJbXBsaWNpdEhlYWRlcnMoaW50IG4pIHsKICAgICAgICBpbXBsaWNpdEhlYWRlckxldmVsID0gbjsKICAgIH0KCiAgICB2b2lkIHNldEN1c3RvbVRhZ3MoU3RyaW5nIGNUYWdzKSB7CiAgICAgICAgY3VzdG9tVGFncyA9IG5ldyBMaW5rZWRIYXNoU2V0PD4oKTsKICAgICAgICBmb3IgKFN0cmluZyBzIDogY1RhZ3Muc3BsaXQoRG9jTGludC5TRVBBUkFUT1IpKSB7CiAgICAgICAgICAgIGlmICghcy5pc0VtcHR5KCkpCiAgICAgICAgICAgICAgICBjdXN0b21UYWdzLmFkZChzKTsKICAgICAgICB9CiAgICB9CgogICAgdm9pZCBzZXRDaGVja1BhY2thZ2VzKFN0cmluZyBwYWNrYWdlcykgewogICAgICAgIGluY2x1ZGVQYWNrYWdlcyA9IG5ldyBIYXNoU2V0PD4oKTsKICAgICAgICBleGNsdWRlUGFja2FnZXMgPSBuZXcgSGFzaFNldDw+KCk7CiAgICAgICAgZm9yIChTdHJpbmcgcGFjayA6IHBhY2thZ2VzLnNwbGl0KERvY0xpbnQuU0VQQVJBVE9SKSkgewogICAgICAgICAgICBib29sZWFuIGV4Y2x1ZGVkID0gZmFsc2U7CiAgICAgICAgICAgIGlmIChwYWNrLnN0YXJ0c1dpdGgoIi0iKSkgewogICAgICAgICAgICAgICAgcGFjayA9IHBhY2suc3Vic3RyaW5nKDEpOwogICAgICAgICAgICAgICAgZXhjbHVkZWQgPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChwYWNrLmlzRW1wdHkoKSkKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICBQYXR0ZXJuIHBhdHRlcm4gPSBNYXRjaGluZ1V0aWxzLnZhbGlkSW1wb3J0U3RyaW5nVG9QYXR0ZXJuKHBhY2spOwogICAgICAgICAgICBpZiAoZXhjbHVkZWQpIHsKICAgICAgICAgICAgICAgIGV4Y2x1ZGVQYWNrYWdlcy5hZGQocGF0dGVybik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBpbmNsdWRlUGFja2FnZXMuYWRkKHBhdHRlcm4pOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIHN0YXRpYyBib29sZWFuIHZhbGlkYXRlUGFja2FnZXMoU3RyaW5nIHBhY2thZ2VzKSB7CiAgICAgICAgZm9yIChTdHJpbmcgcGFjayA6IHBhY2thZ2VzLnNwbGl0KERvY0xpbnQuU0VQQVJBVE9SKSkgewogICAgICAgICAgICBpZiAocGFjay5zdGFydHNXaXRoKCItIikpIHsKICAgICAgICAgICAgICAgIHBhY2sgPSBwYWNrLnN1YnN0cmluZygxKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoIXBhY2suaXNFbXB0eSgpICYmICFNYXRjaGluZ1V0aWxzLmlzVmFsaWRJbXBvcnRTdHJpbmcocGFjaykpCiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIHZvaWQgc2V0SHRtbFZlcnNpb24oSHRtbFZlcnNpb24gdmVyc2lvbikgewogICAgICAgIGh0bWxWZXJzaW9uID0gdmVyc2lvbjsKICAgIH0KCiAgICAvKiogU2V0IHRoZSBjdXJyZW50IGRlY2xhcmF0aW9uIGFuZCBpdHMgZG9jIGNvbW1lbnQuICovCiAgICB2b2lkIHNldEN1cnJlbnQoVHJlZVBhdGggcGF0aCwgRG9jQ29tbWVudFRyZWUgY29tbWVudCkgewogICAgICAgIGN1cnJQYXRoID0gcGF0aDsKICAgICAgICBjdXJyRG9jQ29tbWVudCA9IGNvbW1lbnQ7CiAgICAgICAgY3VyckVsZW1lbnQgPSB0cmVlcy5nZXRFbGVtZW50KGN1cnJQYXRoKTsKICAgICAgICBjdXJyT3ZlcnJpZGRlbk1ldGhvZHMgPSAoKEphdmFjVHlwZXMpIHR5cGVzKS5nZXRPdmVycmlkZGVuTWV0aG9kcyhjdXJyRWxlbWVudCk7CgogICAgICAgIEFjY2Vzc0tpbmQgYWsgPSBBY2Nlc3NLaW5kLlBVQkxJQzsKICAgICAgICBmb3IgKFRyZWVQYXRoIHAgPSBwYXRoOyBwICE9IG51bGw7IHAgPSBwLmdldFBhcmVudFBhdGgoKSkgewogICAgICAgICAgICBFbGVtZW50IGUgPSB0cmVlcy5nZXRFbGVtZW50KHApOwogICAgICAgICAgICBpZiAoZSAhPSBudWxsICYmIGUuZ2V0S2luZCgpICE9IEVsZW1lbnRLaW5kLlBBQ0tBR0UgJiYgZS5nZXRLaW5kKCkgIT0gRWxlbWVudEtpbmQuTU9EVUxFKSB7CiAgICAgICAgICAgICAgICBhayA9IG1pbihhaywgQWNjZXNzS2luZC5vZihlLmdldE1vZGlmaWVycygpKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgY3VyckFjY2VzcyA9IGFrOwogICAgfQoKICAgIEFjY2Vzc0tpbmQgZ2V0QWNjZXNzS2luZCgpIHsKICAgICAgICByZXR1cm4gY3VyckFjY2VzczsKICAgIH0KCiAgICBsb25nIGdldFBvcyhUcmVlUGF0aCBwKSB7CiAgICAgICAgcmV0dXJuICgoSkNUcmVlKSBwLmdldExlYWYoKSkucG9zOwogICAgfQoKICAgIGxvbmcgZ2V0U3RhcnRQb3MoVHJlZVBhdGggcCkgewogICAgICAgIFNvdXJjZVBvc2l0aW9ucyBzcCA9IHRyZWVzLmdldFNvdXJjZVBvc2l0aW9ucygpOwogICAgICAgIHJldHVybiBzcC5nZXRTdGFydFBvc2l0aW9uKHAuZ2V0Q29tcGlsYXRpb25Vbml0KCksIHAuZ2V0TGVhZigpKTsKICAgIH0KCiAgICBib29sZWFuIHNob3VsZENoZWNrKENvbXBpbGF0aW9uVW5pdFRyZWUgdW5pdCkgewogICAgICAgIGlmIChpbmNsdWRlUGFja2FnZXMgPT0gbnVsbCkKICAgICAgICAgICAgcmV0dXJuIHRydWU7CgogICAgICAgIFN0cmluZyBwYWNrYWdlTmFtZSA9ICAgdW5pdC5nZXRQYWNrYWdlTmFtZSgpICE9IG51bGwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IHVuaXQuZ2V0UGFja2FnZU5hbWUoKS50b1N0cmluZygpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiAiIjsKCiAgICAgICAgaWYgKCFpbmNsdWRlUGFja2FnZXMuaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGJvb2xlYW4gaW5jbHVkZWQgPSBmYWxzZTsKICAgICAgICAgICAgZm9yIChQYXR0ZXJuIHBhY2sgOiBpbmNsdWRlUGFja2FnZXMpIHsKICAgICAgICAgICAgICAgIGlmIChwYWNrLm1hdGNoZXIocGFja2FnZU5hbWUpLm1hdGNoZXMoKSkgewogICAgICAgICAgICAgICAgICAgIGluY2x1ZGVkID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoIWluY2x1ZGVkKQogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgZm9yIChQYXR0ZXJuIHBhY2sgOiBleGNsdWRlUGFja2FnZXMpIHsKICAgICAgICAgICAgaWYgKHBhY2subWF0Y2hlcihwYWNrYWdlTmFtZSkubWF0Y2hlcygpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIHByaXZhdGUgPFQgZXh0ZW5kcyBDb21wYXJhYmxlPFQ+PiBUIG1pbihUIGl0ZW0xLCBUIGl0ZW0yKSB7CiAgICAgICAgcmV0dXJuIChpdGVtMSA9PSBudWxsKSA/IGl0ZW0yCiAgICAgICAgICAgICAgICA6IChpdGVtMiA9PSBudWxsKSA/IGl0ZW0xCiAgICAgICAgICAgICAgICA6IGl0ZW0xLmNvbXBhcmVUbyhpdGVtMikgPD0gMCA/IGl0ZW0xIDogaXRlbTI7CiAgICB9Cn0KUEsDBAoAAAgAAAY7qUrHWXCud6AAAHegAAAiAAAAY29tL3N1bi90b29scy9kb2NsaW50L0NoZWNrZXIuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAxMiwgMjAxNywgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBjb20uc3VuLnRvb2xzLmRvY2xpbnQ7CgppbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKaW1wb3J0IGphdmEuaW8uU3RyaW5nV3JpdGVyOwppbXBvcnQgamF2YS5uZXQuVVJJOwppbXBvcnQgamF2YS5uZXQuVVJJU3ludGF4RXhjZXB0aW9uOwppbXBvcnQgamF2YS51dGlsLkRlcXVlOwppbXBvcnQgamF2YS51dGlsLkVudW1TZXQ7CmltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKaW1wb3J0IGphdmEudXRpbC5IYXNoU2V0OwppbXBvcnQgamF2YS51dGlsLkxpbmtlZExpc3Q7CmltcG9ydCBqYXZhLnV0aWwuTGlzdDsKaW1wb3J0IGphdmEudXRpbC5NYXA7CmltcG9ydCBqYXZhLnV0aWwuU2V0OwppbXBvcnQgamF2YS51dGlsLnJlZ2V4Lk1hdGNoZXI7CmltcG9ydCBqYXZhLnV0aWwucmVnZXguUGF0dGVybjsKCmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuRWxlbWVudDsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC5FbGVtZW50S2luZDsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC5FeGVjdXRhYmxlRWxlbWVudDsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC5OYW1lOwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5lbGVtZW50LlZhcmlhYmxlRWxlbWVudDsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwudHlwZS5UeXBlS2luZDsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwudHlwZS5UeXBlTWlycm9yOwppbXBvcnQgamF2YXgudG9vbHMuRGlhZ25vc3RpYy5LaW5kOwppbXBvcnQgamF2YXgudG9vbHMuSmF2YUZpbGVPYmplY3Q7CgppbXBvcnQgY29tLnN1bi5zb3VyY2UuZG9jdHJlZS5BdHRyaWJ1dGVUcmVlOwppbXBvcnQgY29tLnN1bi5zb3VyY2UuZG9jdHJlZS5BdXRob3JUcmVlOwppbXBvcnQgY29tLnN1bi5zb3VyY2UuZG9jdHJlZS5Eb2NDb21tZW50VHJlZTsKaW1wb3J0IGNvbS5zdW4uc291cmNlLmRvY3RyZWUuRG9jUm9vdFRyZWU7CmltcG9ydCBjb20uc3VuLnNvdXJjZS5kb2N0cmVlLkRvY1RyZWU7CmltcG9ydCBjb20uc3VuLnNvdXJjZS5kb2N0cmVlLkVuZEVsZW1lbnRUcmVlOwppbXBvcnQgY29tLnN1bi5zb3VyY2UuZG9jdHJlZS5FbnRpdHlUcmVlOwppbXBvcnQgY29tLnN1bi5zb3VyY2UuZG9jdHJlZS5FcnJvbmVvdXNUcmVlOwppbXBvcnQgY29tLnN1bi5zb3VyY2UuZG9jdHJlZS5JZGVudGlmaWVyVHJlZTsKaW1wb3J0IGNvbS5zdW4uc291cmNlLmRvY3RyZWUuSW5oZXJpdERvY1RyZWU7CmltcG9ydCBjb20uc3VuLnNvdXJjZS5kb2N0cmVlLkxpbmtUcmVlOwppbXBvcnQgY29tLnN1bi5zb3VyY2UuZG9jdHJlZS5MaXRlcmFsVHJlZTsKaW1wb3J0IGNvbS5zdW4uc291cmNlLmRvY3RyZWUuUGFyYW1UcmVlOwppbXBvcnQgY29tLnN1bi5zb3VyY2UuZG9jdHJlZS5Qcm92aWRlc1RyZWU7CmltcG9ydCBjb20uc3VuLnNvdXJjZS5kb2N0cmVlLlJlZmVyZW5jZVRyZWU7CmltcG9ydCBjb20uc3VuLnNvdXJjZS5kb2N0cmVlLlJldHVyblRyZWU7CmltcG9ydCBjb20uc3VuLnNvdXJjZS5kb2N0cmVlLlNlcmlhbERhdGFUcmVlOwppbXBvcnQgY29tLnN1bi5zb3VyY2UuZG9jdHJlZS5TZXJpYWxGaWVsZFRyZWU7CmltcG9ydCBjb20uc3VuLnNvdXJjZS5kb2N0cmVlLlNpbmNlVHJlZTsKaW1wb3J0IGNvbS5zdW4uc291cmNlLmRvY3RyZWUuU3RhcnRFbGVtZW50VHJlZTsKaW1wb3J0IGNvbS5zdW4uc291cmNlLmRvY3RyZWUuVGV4dFRyZWU7CmltcG9ydCBjb20uc3VuLnNvdXJjZS5kb2N0cmVlLlRocm93c1RyZWU7CmltcG9ydCBjb20uc3VuLnNvdXJjZS5kb2N0cmVlLlVua25vd25CbG9ja1RhZ1RyZWU7CmltcG9ydCBjb20uc3VuLnNvdXJjZS5kb2N0cmVlLlVua25vd25JbmxpbmVUYWdUcmVlOwppbXBvcnQgY29tLnN1bi5zb3VyY2UuZG9jdHJlZS5Vc2VzVHJlZTsKaW1wb3J0IGNvbS5zdW4uc291cmNlLmRvY3RyZWUuVmFsdWVUcmVlOwppbXBvcnQgY29tLnN1bi5zb3VyY2UuZG9jdHJlZS5WZXJzaW9uVHJlZTsKaW1wb3J0IGNvbS5zdW4uc291cmNlLnRyZWUuVHJlZTsKaW1wb3J0IGNvbS5zdW4uc291cmNlLnV0aWwuRG9jVHJlZVBhdGg7CmltcG9ydCBjb20uc3VuLnNvdXJjZS51dGlsLkRvY1RyZWVQYXRoU2Nhbm5lcjsKaW1wb3J0IGNvbS5zdW4uc291cmNlLnV0aWwuVHJlZVBhdGg7CmltcG9ydCBjb20uc3VuLnRvb2xzLmRvY2xpbnQuSHRtbFRhZy5BdHRyS2luZDsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudHJlZS5Eb2NQcmV0dHk7CmltcG9ydCBjb20uc3VuLnRvb2xzLmphdmFjLnV0aWwuQXNzZXJ0OwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLkRlZmluZWRCeTsKaW1wb3J0IGNvbS5zdW4udG9vbHMuamF2YWMudXRpbC5EZWZpbmVkQnkuQXBpOwppbXBvcnQgY29tLnN1bi50b29scy5qYXZhYy51dGlsLlN0cmluZ1V0aWxzOwoKaW1wb3J0IHN0YXRpYyBjb20uc3VuLnRvb2xzLmRvY2xpbnQuTWVzc2FnZXMuR3JvdXAuKjsKCgovKioKICogVmFsaWRhdGUgYSBkb2MgY29tbWVudC4KICoKICogPHA+PGI+VGhpcyBpcyBOT1QgcGFydCBvZiBhbnkgc3VwcG9ydGVkIEFQSS4KICogSWYgeW91IHdyaXRlIGNvZGUgdGhhdCBkZXBlbmRzIG9uIHRoaXMsIHlvdSBkbyBzbyBhdCB5b3VyIG93bgogKiByaXNrLiAgVGhpcyBjb2RlIGFuZCBpdHMgaW50ZXJuYWwgaW50ZXJmYWNlcyBhcmUgc3ViamVjdCB0byBjaGFuZ2UKICogb3IgZGVsZXRpb24gd2l0aG91dCBub3RpY2UuPC9iPjwvcD4KICovCnB1YmxpYyBjbGFzcyBDaGVja2VyIGV4dGVuZHMgRG9jVHJlZVBhdGhTY2FubmVyPFZvaWQsIFZvaWQ+IHsKICAgIGZpbmFsIEVudiBlbnY7CgogICAgU2V0PEVsZW1lbnQ+IGZvdW5kUGFyYW1zID0gbmV3IEhhc2hTZXQ8PigpOwogICAgU2V0PFR5cGVNaXJyb3I+IGZvdW5kVGhyb3dzID0gbmV3IEhhc2hTZXQ8PigpOwogICAgTWFwPEVsZW1lbnQsIFNldDxTdHJpbmc+PiBmb3VuZEFuY2hvcnMgPSBuZXcgSGFzaE1hcDw+KCk7CiAgICBib29sZWFuIGZvdW5kSW5oZXJpdERvYyA9IGZhbHNlOwogICAgYm9vbGVhbiBmb3VuZFJldHVybiA9IGZhbHNlOwoKICAgIHB1YmxpYyBlbnVtIEZsYWcgewogICAgICAgIFRBQkxFX0hBU19DQVBUSU9OLAogICAgICAgIEhBU19FTEVNRU5ULAogICAgICAgIEhBU19IRUFESU5HLAogICAgICAgIEhBU19JTkxJTkVfVEFHLAogICAgICAgIEhBU19URVhULAogICAgICAgIFJFUE9SVEVEX0JBRF9JTkxJTkUKICAgIH0KCiAgICBzdGF0aWMgY2xhc3MgVGFnU3RhY2tJdGVtIHsKICAgICAgICBmaW5hbCBEb2NUcmVlIHRyZWU7IC8vIHR5cGljYWxseSwgYnV0IG5vdCBhbHdheXMsIFN0YXJ0RWxlbWVudFRyZWUKICAgICAgICBmaW5hbCBIdG1sVGFnIHRhZzsKICAgICAgICBmaW5hbCBTZXQ8SHRtbFRhZy5BdHRyPiBhdHRyczsKICAgICAgICBmaW5hbCBTZXQ8RmxhZz4gZmxhZ3M7CiAgICAgICAgVGFnU3RhY2tJdGVtKERvY1RyZWUgdHJlZSwgSHRtbFRhZyB0YWcpIHsKICAgICAgICAgICAgdGhpcy50cmVlID0gdHJlZTsKICAgICAgICAgICAgdGhpcy50YWcgPSB0YWc7CiAgICAgICAgICAgIGF0dHJzID0gRW51bVNldC5ub25lT2YoSHRtbFRhZy5BdHRyLmNsYXNzKTsKICAgICAgICAgICAgZmxhZ3MgPSBFbnVtU2V0Lm5vbmVPZihGbGFnLmNsYXNzKTsKICAgICAgICB9CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKICAgICAgICAgICAgcmV0dXJuIFN0cmluZy52YWx1ZU9mKHRhZyk7CiAgICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgZmluYWwgRGVxdWU8VGFnU3RhY2tJdGVtPiB0YWdTdGFjazsgLy8gVE9ETzogbWF5YmUgd2FudCB0byByZWNvcmQgc3RhcnRpbmcgdHJlZSBhcyB3ZWxsCiAgICBwcml2YXRlIEh0bWxUYWcgY3VyckhlYWRlclRhZzsKCiAgICBwcml2YXRlIGZpbmFsIGludCBpbXBsaWNpdEhlYWRlckxldmVsOwoKICAgIC8vIDxlZGl0b3ItZm9sZCBkZWZhdWx0c3RhdGU9ImNvbGxhcHNlZCIgZGVzYz0iVG9wIGxldmVsIj4KCiAgICBDaGVja2VyKEVudiBlbnYpIHsKICAgICAgICB0aGlzLmVudiA9IEFzc2VydC5jaGVja05vbk51bGwoZW52KTsKICAgICAgICB0YWdTdGFjayA9IG5ldyBMaW5rZWRMaXN0PD4oKTsKICAgICAgICBpbXBsaWNpdEhlYWRlckxldmVsID0gZW52LmltcGxpY2l0SGVhZGVyTGV2ZWw7CiAgICB9CgogICAgcHVibGljIFZvaWQgc2NhbihEb2NDb21tZW50VHJlZSB0cmVlLCBUcmVlUGF0aCBwKSB7CiAgICAgICAgZW52LmluaXRUeXBlcygpOwogICAgICAgIGVudi5zZXRDdXJyZW50KHAsIHRyZWUpOwoKICAgICAgICBib29sZWFuIGlzT3ZlcnJpZGluZ01ldGhvZCA9ICFlbnYuY3Vyck92ZXJyaWRkZW5NZXRob2RzLmlzRW1wdHkoKTsKICAgICAgICBKYXZhRmlsZU9iamVjdCBmbyA9IHAuZ2V0Q29tcGlsYXRpb25Vbml0KCkuZ2V0U291cmNlRmlsZSgpOwoKICAgICAgICBpZiAocC5nZXRMZWFmKCkuZ2V0S2luZCgpID09IFRyZWUuS2luZC5QQUNLQUdFKSB7CiAgICAgICAgICAgIC8vIElmIHAgcG9pbnRzIHRvIGEgcGFja2FnZSwgdGhlIGltcGxpZWQgZGVjbGFyYXRpb24gaXMgdGhlCiAgICAgICAgICAgIC8vIHBhY2thZ2UgZGVjbGFyYXRpb24gKGlmIGFueSkgZm9yIHRoZSBjb21waWxhdGlvbiB1bml0LgogICAgICAgICAgICAvLyBIYW5kbGUgdGhpcyBjYXNlIHNwZWNpYWxseSwgYmVjYXVzZSBkb2MgY29tbWVudHMgYXJlIG9ubHkKICAgICAgICAgICAgLy8gZXhwZWN0ZWQgaW4gcGFja2FnZS1pbmZvIGZpbGVzLgogICAgICAgICAgICBib29sZWFuIGlzUGtnSW5mbyA9IGZvLmlzTmFtZUNvbXBhdGlibGUoInBhY2thZ2UtaW5mbyIsIEphdmFGaWxlT2JqZWN0LktpbmQuU09VUkNFKTsKICAgICAgICAgICAgaWYgKHRyZWUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgaWYgKGlzUGtnSW5mbykKICAgICAgICAgICAgICAgICAgICByZXBvcnRNaXNzaW5nKCJkYy5taXNzaW5nLmNvbW1lbnQiKTsKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgaWYgKCFpc1BrZ0luZm8pCiAgICAgICAgICAgICAgICAgICAgcmVwb3J0UmVmZXJlbmNlKCJkYy51bmV4cGVjdGVkLmNvbW1lbnQiKTsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSBpZiAodHJlZSAhPSBudWxsICYmIGZvLmlzTmFtZUNvbXBhdGlibGUoInBhY2thZ2UiLCBKYXZhRmlsZU9iamVjdC5LaW5kLkhUTUwpKSB7CiAgICAgICAgICAgIC8vIGEgcGFja2FnZS5odG1sIGZpbGUgd2l0aCBhIERvY0NvbW1lbnRUcmVlCiAgICAgICAgICAgIGlmICh0cmVlLmdldEZ1bGxCb2R5KCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgICByZXBvcnRNaXNzaW5nKCJkYy5taXNzaW5nLmNvbW1lbnQiKTsKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgaWYgKHRyZWUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgaWYgKCFpc1N5bnRoZXRpYygpICYmICFpc092ZXJyaWRpbmdNZXRob2QpCiAgICAgICAgICAgICAgICAgICAgcmVwb3J0TWlzc2luZygiZGMubWlzc2luZy5jb21tZW50Iik7CiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgdGFnU3RhY2suY2xlYXIoKTsKICAgICAgICBjdXJySGVhZGVyVGFnID0gbnVsbDsKCiAgICAgICAgZm91bmRQYXJhbXMuY2xlYXIoKTsKICAgICAgICBmb3VuZFRocm93cy5jbGVhcigpOwogICAgICAgIGZvdW5kSW5oZXJpdERvYyA9IGZhbHNlOwogICAgICAgIGZvdW5kUmV0dXJuID0gZmFsc2U7CgogICAgICAgIHNjYW4obmV3IERvY1RyZWVQYXRoKHAsIHRyZWUpLCBudWxsKTsKCiAgICAgICAgaWYgKCFpc092ZXJyaWRpbmdNZXRob2QpIHsKICAgICAgICAgICAgc3dpdGNoIChlbnYuY3VyckVsZW1lbnQuZ2V0S2luZCgpKSB7CiAgICAgICAgICAgICAgICBjYXNlIE1FVEhPRDoKICAgICAgICAgICAgICAgIGNhc2UgQ09OU1RSVUNUT1I6IHsKICAgICAgICAgICAgICAgICAgICBFeGVjdXRhYmxlRWxlbWVudCBlZSA9IChFeGVjdXRhYmxlRWxlbWVudCkgZW52LmN1cnJFbGVtZW50OwogICAgICAgICAgICAgICAgICAgIGNoZWNrUGFyYW1zRG9jdW1lbnRlZChlZS5nZXRUeXBlUGFyYW1ldGVycygpKTsKICAgICAgICAgICAgICAgICAgICBjaGVja1BhcmFtc0RvY3VtZW50ZWQoZWUuZ2V0UGFyYW1ldGVycygpKTsKICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKGVlLmdldFJldHVyblR5cGUoKS5nZXRLaW5kKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBWT0lEOgogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIE5PTkU6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghZm91bmRSZXR1cm4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgIWZvdW5kSW5oZXJpdERvYwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiAhZW52LnR5cGVzLmlzU2FtZVR5cGUoZWUuZ2V0UmV0dXJuVHlwZSgpLCBlbnYuamF2YV9sYW5nX1ZvaWQpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwb3J0TWlzc2luZygiZGMubWlzc2luZy5yZXR1cm4iKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgY2hlY2tUaHJvd3NEb2N1bWVudGVkKGVlLmdldFRocm93blR5cGVzKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICBwcml2YXRlIHZvaWQgcmVwb3J0TWlzc2luZyhTdHJpbmcgY29kZSwgT2JqZWN0Li4uIGFyZ3MpIHsKICAgICAgICBlbnYubWVzc2FnZXMucmVwb3J0KE1JU1NJTkcsIEtpbmQuV0FSTklORywgZW52LmN1cnJQYXRoLmdldExlYWYoKSwgY29kZSwgYXJncyk7CiAgICB9CgogICAgcHJpdmF0ZSB2b2lkIHJlcG9ydFJlZmVyZW5jZShTdHJpbmcgY29kZSwgT2JqZWN0Li4uIGFyZ3MpIHsKICAgICAgICBlbnYubWVzc2FnZXMucmVwb3J0KFJFRkVSRU5DRSwgS2luZC5XQVJOSU5HLCBlbnYuY3VyclBhdGguZ2V0TGVhZigpLCBjb2RlLCBhcmdzKTsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBWb2lkIHZpc2l0RG9jQ29tbWVudChEb2NDb21tZW50VHJlZSB0cmVlLCBWb2lkIGlnbm9yZSkgewogICAgICAgIHN1cGVyLnZpc2l0RG9jQ29tbWVudCh0cmVlLCBpZ25vcmUpOwogICAgICAgIGZvciAoVGFnU3RhY2tJdGVtIHRzaTogdGFnU3RhY2spIHsKICAgICAgICAgICAgd2FybklmRW1wdHkodHNpLCBudWxsKTsKICAgICAgICAgICAgaWYgKHRzaS50cmVlLmdldEtpbmQoKSA9PSBEb2NUcmVlLktpbmQuU1RBUlRfRUxFTUVOVAogICAgICAgICAgICAgICAgICAgICYmIHRzaS50YWcuZW5kS2luZCA9PSBIdG1sVGFnLkVuZEtpbmQuUkVRVUlSRUQpIHsKICAgICAgICAgICAgICAgIFN0YXJ0RWxlbWVudFRyZWUgdCA9IChTdGFydEVsZW1lbnRUcmVlKSB0c2kudHJlZTsKICAgICAgICAgICAgICAgIGVudi5tZXNzYWdlcy5lcnJvcihIVE1MLCB0LCAiZGMudGFnLm5vdC5jbG9zZWQiLCB0LmdldE5hbWUoKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICAvLyA8L2VkaXRvci1mb2xkPgoKICAgIC8vIDxlZGl0b3ItZm9sZCBkZWZhdWx0c3RhdGU9ImNvbGxhcHNlZCIgZGVzYz0iVGV4dCBhbmQgZW50aXRpZXMuIj4KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBWb2lkIHZpc2l0VGV4dChUZXh0VHJlZSB0cmVlLCBWb2lkIGlnbm9yZSkgewogICAgICAgIGlmIChoYXNOb25XaGl0ZXNwYWNlKHRyZWUpKSB7CiAgICAgICAgICAgIGNoZWNrQWxsb3dzVGV4dCh0cmVlKTsKICAgICAgICAgICAgbWFya0VuY2xvc2luZ1RhZyhGbGFnLkhBU19URVhUKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICBwdWJsaWMgVm9pZCB2aXNpdEVudGl0eShFbnRpdHlUcmVlIHRyZWUsIFZvaWQgaWdub3JlKSB7CiAgICAgICAgY2hlY2tBbGxvd3NUZXh0KHRyZWUpOwogICAgICAgIG1hcmtFbmNsb3NpbmdUYWcoRmxhZy5IQVNfVEVYVCk7CiAgICAgICAgU3RyaW5nIG5hbWUgPSB0cmVlLmdldE5hbWUoKS50b1N0cmluZygpOwogICAgICAgIGlmIChuYW1lLnN0YXJ0c1dpdGgoIiMiKSkgewogICAgICAgICAgICBpbnQgdiA9IFN0cmluZ1V0aWxzLnRvTG93ZXJDYXNlKG5hbWUpLnN0YXJ0c1dpdGgoIiN4IikKICAgICAgICAgICAgICAgICAgICA/IEludGVnZXIucGFyc2VJbnQobmFtZS5zdWJzdHJpbmcoMiksIDE2KQogICAgICAgICAgICAgICAgICAgIDogSW50ZWdlci5wYXJzZUludChuYW1lLnN1YnN0cmluZygxKSwgMTApOwogICAgICAgICAgICBpZiAoIUVudGl0eS5pc1ZhbGlkKHYpKSB7CiAgICAgICAgICAgICAgICBlbnYubWVzc2FnZXMuZXJyb3IoSFRNTCwgdHJlZSwgImRjLmVudGl0eS5pbnZhbGlkIiwgbmFtZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgaWYgKCFFbnRpdHkuaXNWYWxpZChuYW1lKSkgewogICAgICAgICAgICBlbnYubWVzc2FnZXMuZXJyb3IoSFRNTCwgdHJlZSwgImRjLmVudGl0eS5pbnZhbGlkIiwgbmFtZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIHZvaWQgY2hlY2tBbGxvd3NUZXh0KERvY1RyZWUgdHJlZSkgewogICAgICAgIFRhZ1N0YWNrSXRlbSB0b3AgPSB0YWdTdGFjay5wZWVrKCk7CiAgICAgICAgaWYgKHRvcCAhPSBudWxsCiAgICAgICAgICAgICAgICAmJiB0b3AudHJlZS5nZXRLaW5kKCkgPT0gRG9jVHJlZS5LaW5kLlNUQVJUX0VMRU1FTlQKICAgICAgICAgICAgICAgICYmICF0b3AudGFnLmFjY2VwdHNUZXh0KCkpIHsKICAgICAgICAgICAgaWYgKHRvcC5mbGFncy5hZGQoRmxhZy5SRVBPUlRFRF9CQURfSU5MSU5FKSkgewogICAgICAgICAgICAgICAgZW52Lm1lc3NhZ2VzLmVycm9yKEhUTUwsIHRyZWUsICJkYy50ZXh0Lm5vdC5hbGxvd2VkIiwKICAgICAgICAgICAgICAgICAgICAgICAgKChTdGFydEVsZW1lbnRUcmVlKSB0b3AudHJlZSkuZ2V0TmFtZSgpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvLyA8L2VkaXRvci1mb2xkPgoKICAgIC8vIDxlZGl0b3ItZm9sZCBkZWZhdWx0c3RhdGU9ImNvbGxhcHNlZCIgZGVzYz0iSFRNTCBlbGVtZW50cyI+CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICBwdWJsaWMgVm9pZCB2aXNpdFN0YXJ0RWxlbWVudChTdGFydEVsZW1lbnRUcmVlIHRyZWUsIFZvaWQgaWdub3JlKSB7CiAgICAgICAgZmluYWwgTmFtZSB0cmVlTmFtZSA9IHRyZWUuZ2V0TmFtZSgpOwogICAgICAgIGZpbmFsIEh0bWxUYWcgdCA9IEh0bWxUYWcuZ2V0KHRyZWVOYW1lKTsKICAgICAgICBpZiAodCA9PSBudWxsKSB7CiAgICAgICAgICAgIGVudi5tZXNzYWdlcy5lcnJvcihIVE1MLCB0cmVlLCAiZGMudGFnLnVua25vd24iLCB0cmVlTmFtZSk7CiAgICAgICAgfSBlbHNlIGlmICh0LmFsbG93ZWRWZXJzaW9uICE9IEh0bWxWZXJzaW9uLkFMTCAmJiB0LmFsbG93ZWRWZXJzaW9uICE9IGVudi5odG1sVmVyc2lvbikgewogICAgICAgICAgICBlbnYubWVzc2FnZXMuZXJyb3IoSFRNTCwgdHJlZSwgImRjLnRhZy5ub3Quc3VwcG9ydGVkIiwgdHJlZU5hbWUpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgICBmb3IgKFRhZ1N0YWNrSXRlbSB0c2k6IHRhZ1N0YWNrKSB7CiAgICAgICAgICAgICAgICBpZiAodHNpLnRhZy5hY2NlcHRzKHQpKSB7CiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHRhZ1N0YWNrLnBlZWsoKSAhPSB0c2kpIHsKICAgICAgICAgICAgICAgICAgICAgICAgd2FybklmRW1wdHkodGFnU3RhY2sucGVlaygpLCBudWxsKTsKICAgICAgICAgICAgICAgICAgICAgICAgdGFnU3RhY2sucG9wKCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmICh0c2kudGFnLmVuZEtpbmQgIT0gSHRtbFRhZy5FbmRLaW5kLk9QVElPTkFMKSB7CiAgICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCFkb25lICYmIEh0bWxUYWcuQk9EWS5hY2NlcHRzKHQpKSB7CiAgICAgICAgICAgICAgICB3aGlsZSAoIXRhZ1N0YWNrLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgICAgICAgIHdhcm5JZkVtcHR5KHRhZ1N0YWNrLnBlZWsoKSwgbnVsbCk7CiAgICAgICAgICAgICAgICAgICAgdGFnU3RhY2sucG9wKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIG1hcmtFbmNsb3NpbmdUYWcoRmxhZy5IQVNfRUxFTUVOVCk7CiAgICAgICAgICAgIGNoZWNrU3RydWN0dXJlKHRyZWUsIHQpOwoKICAgICAgICAgICAgLy8gdGFnIHNwZWNpZmljIGNoZWNrcwogICAgICAgICAgICBzd2l0Y2ggKHQpIHsKICAgICAgICAgICAgICAgIC8vIGNoZWNrIGZvciBvdXQgb2Ygc2VxdWVuY2UgaGVhZGVycywgc3VjaCBhcyA8aDE+Li4uPC9oMT4gIDxoMz4uLi48L2gzPgogICAgICAgICAgICAgICAgY2FzZSBIMTogY2FzZSBIMjogY2FzZSBIMzogY2FzZSBINDogY2FzZSBINTogY2FzZSBINjoKICAgICAgICAgICAgICAgICAgICBjaGVja0hlYWRlcih0cmVlLCB0KTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKHQuZmxhZ3MuY29udGFpbnMoSHRtbFRhZy5GbGFnLk5PX05FU1QpKSB7CiAgICAgICAgICAgICAgICBmb3IgKFRhZ1N0YWNrSXRlbSBpOiB0YWdTdGFjaykgewogICAgICAgICAgICAgICAgICAgIGlmICh0ID09IGkudGFnKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGVudi5tZXNzYWdlcy53YXJuaW5nKEhUTUwsIHRyZWUsICJkYy50YWcubmVzdGVkLm5vdC5hbGxvd2VkIiwgdHJlZU5hbWUpOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIGNoZWNrIGZvciBzZWxmIGNsb3NpbmcgdGFncywgc3VjaCBhcyA8YSBpZD0ibmFtZSIvPgogICAgICAgIGlmICh0cmVlLmlzU2VsZkNsb3NpbmcoKSkgewogICAgICAgICAgICBlbnYubWVzc2FnZXMuZXJyb3IoSFRNTCwgdHJlZSwgImRjLnRhZy5zZWxmLmNsb3NpbmciLCB0cmVlTmFtZSk7CiAgICAgICAgfQoKICAgICAgICB0cnkgewogICAgICAgICAgICBUYWdTdGFja0l0ZW0gcGFyZW50ID0gdGFnU3RhY2sucGVlaygpOwogICAgICAgICAgICBUYWdTdGFja0l0ZW0gdG9wID0gbmV3IFRhZ1N0YWNrSXRlbSh0cmVlLCB0KTsKICAgICAgICAgICAgdGFnU3RhY2sucHVzaCh0b3ApOwoKICAgICAgICAgICAgc3VwZXIudmlzaXRTdGFydEVsZW1lbnQodHJlZSwgaWdub3JlKTsKCiAgICAgICAgICAgIC8vIGhhbmRsZSBhdHRyaWJ1dGVzIHRoYXQgbWF5IG9yIG1heSBub3QgaGF2ZSBiZWVuIGZvdW5kIGluIHN0YXJ0IGVsZW1lbnQKICAgICAgICAgICAgaWYgKHQgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgc3dpdGNoICh0KSB7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBDQVBUSU9OOgogICAgICAgICAgICAgICAgICAgICAgICBpZiAocGFyZW50ICE9IG51bGwgJiYgcGFyZW50LnRhZyA9PSBIdG1sVGFnLlRBQkxFKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50LmZsYWdzLmFkZChGbGFnLlRBQkxFX0hBU19DQVBUSU9OKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgICAgIGNhc2UgSDE6IGNhc2UgSDI6IGNhc2UgSDM6IGNhc2UgSDQ6IGNhc2UgSDU6IGNhc2UgSDY6CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwYXJlbnQgIT0gbnVsbCAmJiAocGFyZW50LnRhZyA9PSBIdG1sVGFnLlNFQ1RJT04gfHwgcGFyZW50LnRhZyA9PSBIdG1sVGFnLkFSVElDTEUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnQuZmxhZ3MuYWRkKEZsYWcuSEFTX0hFQURJTkcpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgICAgICBjYXNlIElNRzoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCF0b3AuYXR0cnMuY29udGFpbnMoSHRtbFRhZy5BdHRyLkFMVCkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbnYubWVzc2FnZXMuZXJyb3IoQUNDRVNTSUJJTElUWSwgdHJlZSwgImRjLm5vLmFsdC5hdHRyLmZvci5pbWFnZSIpOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfSBmaW5hbGx5IHsKCiAgICAgICAgICAgIGlmICh0ID09IG51bGwgfHwgdC5lbmRLaW5kID09IEh0bWxUYWcuRW5kS2luZC5OT05FKQogICAgICAgICAgICAgICAgdGFnU3RhY2sucG9wKCk7CiAgICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgdm9pZCBjaGVja1N0cnVjdHVyZShTdGFydEVsZW1lbnRUcmVlIHRyZWUsIEh0bWxUYWcgdCkgewogICAgICAgIE5hbWUgdHJlZU5hbWUgPSB0cmVlLmdldE5hbWUoKTsKICAgICAgICBUYWdTdGFja0l0ZW0gdG9wID0gdGFnU3RhY2sucGVlaygpOwogICAgICAgIHN3aXRjaCAodC5ibG9ja1R5cGUpIHsKICAgICAgICAgICAgY2FzZSBCTE9DSzoKICAgICAgICAgICAgICAgIGlmICh0b3AgPT0gbnVsbCB8fCB0b3AudGFnLmFjY2VwdHModCkpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwoKICAgICAgICAgICAgICAgIHN3aXRjaCAodG9wLnRyZWUuZ2V0S2luZCgpKSB7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBTVEFSVF9FTEVNRU5UOiB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0b3AudGFnLmJsb2NrVHlwZSA9PSBIdG1sVGFnLkJsb2NrVHlwZS5JTkxJTkUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5hbWUgbmFtZSA9ICgoU3RhcnRFbGVtZW50VHJlZSkgdG9wLnRyZWUpLmdldE5hbWUoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVudi5tZXNzYWdlcy5lcnJvcihIVE1MLCB0cmVlLCAiZGMudGFnLm5vdC5hbGxvd2VkLmlubGluZS5lbGVtZW50IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJlZU5hbWUsIG5hbWUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgICAgICBjYXNlIExJTks6CiAgICAgICAgICAgICAgICAgICAgY2FzZSBMSU5LX1BMQUlOOiB7CiAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBuYW1lID0gdG9wLnRyZWUuZ2V0S2luZCgpLnRhZ05hbWU7CiAgICAgICAgICAgICAgICAgICAgICAgIGVudi5tZXNzYWdlcy5lcnJvcihIVE1MLCB0cmVlLCAiZGMudGFnLm5vdC5hbGxvd2VkLmlubGluZS50YWciLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyZWVOYW1lLCBuYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBJTkxJTkU6CiAgICAgICAgICAgICAgICBpZiAodG9wID09IG51bGwgfHwgdG9wLnRhZy5hY2NlcHRzKHQpKQogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBMSVNUX0lURU06CiAgICAgICAgICAgIGNhc2UgVEFCTEVfSVRFTToKICAgICAgICAgICAgICAgIGlmICh0b3AgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIC8vIHJlc2V0IHRoaXMgZmxhZyBzbyBzdWJzZXF1ZW50IGJhZCBpbmxpbmUgY29udGVudCBnZXRzIHJlcG9ydGVkCiAgICAgICAgICAgICAgICAgICAgdG9wLmZsYWdzLnJlbW92ZShGbGFnLlJFUE9SVEVEX0JBRF9JTkxJTkUpOwogICAgICAgICAgICAgICAgICAgIGlmICh0b3AudGFnLmFjY2VwdHModCkpCiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBPVEhFUjoKICAgICAgICAgICAgICAgIHN3aXRjaCAodCkgewogICAgICAgICAgICAgICAgICAgIGNhc2UgU0NSSVBUOgogICAgICAgICAgICAgICAgICAgICAgICAvLyA8c2NyaXB0PiBtYXkgb3IgbWF5IG5vdCBiZSBhbGxvd2VkLCBkZXBlbmRpbmcgb24gLS1hbGxvdy1zY3JpcHQtaW4tY29tbWVudHMKICAgICAgICAgICAgICAgICAgICAgICAgLy8gYnV0IHdlIGFsbG93IGl0IGhlcmUsIGFuZCByZWx5IG9uIGEgc2VwYXJhdGUgc2Nhbm5lciB0byBkZXRlY3QgYWxsIHVzZXMKICAgICAgICAgICAgICAgICAgICAgICAgLy8gb2YgSmF2YVNjcmlwdCwgaW5jbHVkaW5nIDxzY3JpcHQ+IHRhZ3MsIGFuZCB1c2UgaW4gYXR0cmlidXRlcywgZXRjLgogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgICAgZW52Lm1lc3NhZ2VzLmVycm9yKEhUTUwsIHRyZWUsICJkYy50YWcubm90LmFsbG93ZWQiLCB0cmVlTmFtZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICBlbnYubWVzc2FnZXMuZXJyb3IoSFRNTCwgdHJlZSwgImRjLnRhZy5ub3QuYWxsb3dlZC5oZXJlIiwgdHJlZU5hbWUpOwogICAgfQoKICAgIHByaXZhdGUgdm9pZCBjaGVja0hlYWRlcihTdGFydEVsZW1lbnRUcmVlIHRyZWUsIEh0bWxUYWcgdGFnKSB7CiAgICAgICAgLy8gdmVyaWZ5IHRoZSBuZXcgdGFnCiAgICAgICAgaWYgKGdldEhlYWRlckxldmVsKHRhZykgPiBnZXRIZWFkZXJMZXZlbChjdXJySGVhZGVyVGFnKSArIDEpIHsKICAgICAgICAgICAgaWYgKGN1cnJIZWFkZXJUYWcgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgZW52Lm1lc3NhZ2VzLmVycm9yKEFDQ0VTU0lCSUxJVFksIHRyZWUsICJkYy50YWcuaGVhZGVyLnNlcXVlbmNlLjEiLCB0YWcpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgZW52Lm1lc3NhZ2VzLmVycm9yKEFDQ0VTU0lCSUxJVFksIHRyZWUsICJkYy50YWcuaGVhZGVyLnNlcXVlbmNlLjIiLAogICAgICAgICAgICAgICAgICAgIHRhZywgY3VyckhlYWRlclRhZyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGN1cnJIZWFkZXJUYWcgPSB0YWc7CiAgICB9CgogICAgcHJpdmF0ZSBpbnQgZ2V0SGVhZGVyTGV2ZWwoSHRtbFRhZyB0YWcpIHsKICAgICAgICBpZiAodGFnID09IG51bGwpCiAgICAgICAgICAgIHJldHVybiBpbXBsaWNpdEhlYWRlckxldmVsOwogICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgIGNhc2UgSDE6IHJldHVybiAxOwogICAgICAgICAgICBjYXNlIEgyOiByZXR1cm4gMjsKICAgICAgICAgICAgY2FzZSBIMzogcmV0dXJuIDM7CiAgICAgICAgICAgIGNhc2UgSDQ6IHJldHVybiA0OwogICAgICAgICAgICBjYXNlIEg1OiByZXR1cm4gNTsKICAgICAgICAgICAgY2FzZSBINjogcmV0dXJuIDY7CiAgICAgICAgICAgIGRlZmF1bHQ6IHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICBwdWJsaWMgVm9pZCB2aXNpdEVuZEVsZW1lbnQoRW5kRWxlbWVudFRyZWUgdHJlZSwgVm9pZCBpZ25vcmUpIHsKICAgICAgICBmaW5hbCBOYW1lIHRyZWVOYW1lID0gdHJlZS5nZXROYW1lKCk7CiAgICAgICAgZmluYWwgSHRtbFRhZyB0ID0gSHRtbFRhZy5nZXQodHJlZU5hbWUpOwogICAgICAgIGlmICh0ID09IG51bGwpIHsKICAgICAgICAgICAgZW52Lm1lc3NhZ2VzLmVycm9yKEhUTUwsIHRyZWUsICJkYy50YWcudW5rbm93biIsIHRyZWVOYW1lKTsKICAgICAgICB9IGVsc2UgaWYgKHQuZW5kS2luZCA9PSBIdG1sVGFnLkVuZEtpbmQuTk9ORSkgewogICAgICAgICAgICBlbnYubWVzc2FnZXMuZXJyb3IoSFRNTCwgdHJlZSwgImRjLnRhZy5lbmQubm90LnBlcm1pdHRlZCIsIHRyZWVOYW1lKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgICAgd2hpbGUgKCF0YWdTdGFjay5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICAgIFRhZ1N0YWNrSXRlbSB0b3AgPSB0YWdTdGFjay5wZWVrKCk7CiAgICAgICAgICAgICAgICBpZiAodCA9PSB0b3AudGFnKSB7CiAgICAgICAgICAgICAgICAgICAgc3dpdGNoICh0KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgVEFCTEU6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXRvcC5hdHRycy5jb250YWlucyhIdG1sVGFnLkF0dHIuU1VNTUFSWSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgIXRvcC5mbGFncy5jb250YWlucyhGbGFnLlRBQkxFX0hBU19DQVBUSU9OKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVudi5tZXNzYWdlcy5lcnJvcihBQ0NFU1NJQklMSVRZLCB0cmVlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImRjLm5vLnN1bW1hcnkub3IuY2FwdGlvbi5mb3IudGFibGUiKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBTRUNUSU9OOgogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIEFSVElDTEU6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZW52Lmh0bWxWZXJzaW9uID09IEh0bWxWZXJzaW9uLkhUTUw1ICYmICF0b3AuZmxhZ3MuY29udGFpbnMoRmxhZy5IQVNfSEVBRElORykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbnYubWVzc2FnZXMuZXJyb3IoSFRNTCwgdHJlZSwgImRjLnRhZy5yZXF1aXJlcy5oZWFkaW5nIiwgdHJlZU5hbWUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHdhcm5JZkVtcHR5KHRvcCwgdHJlZSk7CiAgICAgICAgICAgICAgICAgICAgdGFnU3RhY2sucG9wKCk7CiAgICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHRvcC50YWcgPT0gbnVsbCB8fCB0b3AudGFnLmVuZEtpbmQgIT0gSHRtbFRhZy5FbmRLaW5kLlJFUVVJUkVEKSB7CiAgICAgICAgICAgICAgICAgICAgdGFnU3RhY2sucG9wKCk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gZm91bmQgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICBmb3IgKFRhZ1N0YWNrSXRlbSBzaTogdGFnU3RhY2spIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNpLnRhZyA9PSB0KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3VuZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoZm91bmQgJiYgdG9wLnRyZWUuZ2V0S2luZCgpID09IERvY1RyZWUuS2luZC5TVEFSVF9FTEVNRU5UKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGVudi5tZXNzYWdlcy5lcnJvcihIVE1MLCB0b3AudHJlZSwgImRjLnRhZy5zdGFydC51bm1hdGNoZWQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoU3RhcnRFbGVtZW50VHJlZSkgdG9wLnRyZWUpLmdldE5hbWUoKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHRhZ1N0YWNrLnBvcCgpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGVudi5tZXNzYWdlcy5lcnJvcihIVE1MLCB0cmVlLCAiZGMudGFnLmVuZC51bmV4cGVjdGVkIiwgdHJlZU5hbWUpOwogICAgICAgICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoIWRvbmUgJiYgdGFnU3RhY2suaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgICBlbnYubWVzc2FnZXMuZXJyb3IoSFRNTCwgdHJlZSwgImRjLnRhZy5lbmQudW5leHBlY3RlZCIsIHRyZWVOYW1lKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHN1cGVyLnZpc2l0RW5kRWxlbWVudCh0cmVlLCBpZ25vcmUpOwogICAgfQoKICAgIHZvaWQgd2FybklmRW1wdHkoVGFnU3RhY2tJdGVtIHRzaSwgRG9jVHJlZSBlbmRUcmVlKSB7CiAgICAgICAgaWYgKHRzaS50YWcgIT0gbnVsbCAmJiB0c2kudHJlZSBpbnN0YW5jZW9mIFN0YXJ0RWxlbWVudFRyZWUpIHsKICAgICAgICAgICAgaWYgKHRzaS50YWcuZmxhZ3MuY29udGFpbnMoSHRtbFRhZy5GbGFnLkVYUEVDVF9DT05URU5UKQogICAgICAgICAgICAgICAgICAgICYmICF0c2kuZmxhZ3MuY29udGFpbnMoRmxhZy5IQVNfVEVYVCkKICAgICAgICAgICAgICAgICAgICAmJiAhdHNpLmZsYWdzLmNvbnRhaW5zKEZsYWcuSEFTX0VMRU1FTlQpCiAgICAgICAgICAgICAgICAgICAgJiYgIXRzaS5mbGFncy5jb250YWlucyhGbGFnLkhBU19JTkxJTkVfVEFHKSkgewogICAgICAgICAgICAgICAgRG9jVHJlZSB0cmVlID0gKGVuZFRyZWUgIT0gbnVsbCkgPyBlbmRUcmVlIDogdHNpLnRyZWU7CiAgICAgICAgICAgICAgICBOYW1lIHRyZWVOYW1lID0gKChTdGFydEVsZW1lbnRUcmVlKSB0c2kudHJlZSkuZ2V0TmFtZSgpOwogICAgICAgICAgICAgICAgZW52Lm1lc3NhZ2VzLndhcm5pbmcoSFRNTCwgdHJlZSwgImRjLnRhZy5lbXB0eSIsIHRyZWVOYW1lKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvLyA8L2VkaXRvci1mb2xkPgoKICAgIC8vIDxlZGl0b3ItZm9sZCBkZWZhdWx0c3RhdGU9ImNvbGxhcHNlZCIgZGVzYz0iSFRNTCBhdHRyaWJ1dGVzIj4KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkgQFN1cHByZXNzV2FybmluZ3MoImZhbGx0aHJvdWdoIikKICAgIHB1YmxpYyBWb2lkIHZpc2l0QXR0cmlidXRlKEF0dHJpYnV0ZVRyZWUgdHJlZSwgVm9pZCBpZ25vcmUpIHsKICAgICAgICBIdG1sVGFnIGN1cnJUYWcgPSB0YWdTdGFjay5wZWVrKCkudGFnOwogICAgICAgIGlmIChjdXJyVGFnICE9IG51bGwpIHsKICAgICAgICAgICAgTmFtZSBuYW1lID0gdHJlZS5nZXROYW1lKCk7CiAgICAgICAgICAgIEh0bWxUYWcuQXR0ciBhdHRyID0gY3VyclRhZy5nZXRBdHRyKG5hbWUpOwogICAgICAgICAgICBpZiAoYXR0ciAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICBpZiAoZW52Lmh0bWxWZXJzaW9uID09IEh0bWxWZXJzaW9uLkhUTUw0ICYmIGF0dHIubmFtZSgpLmNvbnRhaW5zKCItIikpIHsKICAgICAgICAgICAgICAgICAgICBlbnYubWVzc2FnZXMuZXJyb3IoSFRNTCwgdHJlZSwgImRjLmF0dHIubm90LnN1cHBvcnRlZC5odG1sNCIsIG5hbWUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYm9vbGVhbiBmaXJzdCA9IHRhZ1N0YWNrLnBlZWsoKS5hdHRycy5hZGQoYXR0cik7CiAgICAgICAgICAgICAgICBpZiAoIWZpcnN0KQogICAgICAgICAgICAgICAgICAgIGVudi5tZXNzYWdlcy5lcnJvcihIVE1MLCB0cmVlLCAiZGMuYXR0ci5yZXBlYXRlZCIsIG5hbWUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIGZvciBub3csIGRvY2xpbnQgYWxsb3dzIGFsbCBhdHRyaWJ1dGUgbmFtZXMgYmVnaW5uaW5nIHdpdGggIm9uIiBhcyBldmVudCBoYW5kbGVyIG5hbWVzLAogICAgICAgICAgICAvLyB3aXRob3V0IGNoZWNraW5nIHRoZSB2YWxpZGl0eSBvciBhcHBsaWNhYmlsaXR5IG9mIHRoZSBuYW1lCiAgICAgICAgICAgIGlmICghbmFtZS50b1N0cmluZygpLnN0YXJ0c1dpdGgoIm9uIikpIHsKICAgICAgICAgICAgICAgIEF0dHJLaW5kIGsgPSBjdXJyVGFnLmdldEF0dHJLaW5kKG5hbWUpOwogICAgICAgICAgICAgICAgc3dpdGNoIChlbnYuaHRtbFZlcnNpb24pIHsKICAgICAgICAgICAgICAgICAgICBjYXNlIEhUTUw0OgogICAgICAgICAgICAgICAgICAgICAgICB2YWxpZGF0ZUh0bWw0QXR0cnModHJlZSwgbmFtZSwgayk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgICAgICBjYXNlIEhUTUw1OgogICAgICAgICAgICAgICAgICAgICAgICB2YWxpZGF0ZUh0bWw1QXR0cnModHJlZSwgbmFtZSwgayk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoYXR0ciAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICBzd2l0Y2ggKGF0dHIpIHsKICAgICAgICAgICAgICAgICAgICBjYXNlIE5BTUU6CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjdXJyVGFnICE9IEh0bWxUYWcuQSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgLy8gZmFsbHRocm91Z2gKICAgICAgICAgICAgICAgICAgICBjYXNlIElEOgogICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgdmFsdWUgPSBnZXRBdHRyVmFsdWUodHJlZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbnYubWVzc2FnZXMuZXJyb3IoSFRNTCwgdHJlZSwgImRjLmFuY2hvci52YWx1ZS5taXNzaW5nIik7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXZhbGlkTmFtZS5tYXRjaGVyKHZhbHVlKS5tYXRjaGVzKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbnYubWVzc2FnZXMuZXJyb3IoSFRNTCwgdHJlZSwgImRjLmludmFsaWQuYW5jaG9yIiwgdmFsdWUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFjaGVja0FuY2hvcih2YWx1ZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbnYubWVzc2FnZXMuZXJyb3IoSFRNTCwgdHJlZSwgImRjLmFuY2hvci5hbHJlYWR5LmRlZmluZWQiLCB2YWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgICAgIGNhc2UgSFJFRjoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGN1cnJUYWcgPT0gSHRtbFRhZy5BKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgdiA9IGdldEF0dHJWYWx1ZSh0cmVlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2ID09IG51bGwgfHwgdi5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbnYubWVzc2FnZXMuZXJyb3IoSFRNTCwgdHJlZSwgImRjLmF0dHIubGFja3MudmFsdWUiKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWF0Y2hlciBtID0gZG9jUm9vdC5tYXRjaGVyKHYpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChtLm1hdGNoZXMoKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcmVzdCA9IG0uZ3JvdXAoMik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghcmVzdC5pc0VtcHR5KCkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGVja1VSSSh0cmVlLCByZXN0KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGVja1VSSSh0cmVlLCB2KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgICAgIGNhc2UgVkFMVUU6CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjdXJyVGFnID09IEh0bWxUYWcuTEkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyB2ID0gZ2V0QXR0clZhbHVlKHRyZWUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHYgPT0gbnVsbCB8fCB2LmlzRW1wdHkoKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVudi5tZXNzYWdlcy5lcnJvcihIVE1MLCB0cmVlLCAiZGMuYXR0ci5sYWNrcy52YWx1ZSIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICghdmFsaWROdW1iZXIubWF0Y2hlcih2KS5tYXRjaGVzKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbnYubWVzc2FnZXMuZXJyb3IoSFRNTCwgdHJlZSwgImRjLmF0dHIubm90Lm51bWJlciIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgICAgICBjYXNlIEJPUkRFUjoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGN1cnJUYWcgPT0gSHRtbFRhZy5UQUJMRSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHYgPSBnZXRBdHRyVmFsdWUodHJlZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlbnYuaHRtbFZlcnNpb24gPT0gSHRtbFZlcnNpb24uSFRNTDUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICYmICh2ID09IG51bGwgfHwgKCF2LmlzRW1wdHkoKSAmJiBJbnRlZ2VyLnBhcnNlSW50KHYpICE9IDEpKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbnYubWVzc2FnZXMuZXJyb3IoSFRNTCwgdHJlZSwgImRjLmF0dHIudGFibGUuYm9yZGVyLmh0bWw1IiwgYXR0cik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGV4KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW52Lm1lc3NhZ2VzLmVycm9yKEhUTUwsIHRyZWUsICJkYy5hdHRyLnRhYmxlLmJvcmRlci5odG1sNSIsIGF0dHIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBUT0RPOiBiYXNpYyBjaGVjayBvbiB2YWx1ZQoKICAgICAgICByZXR1cm4gc3VwZXIudmlzaXRBdHRyaWJ1dGUodHJlZSwgaWdub3JlKTsKICAgIH0KCiAgICBwcml2YXRlIHZvaWQgdmFsaWRhdGVIdG1sNEF0dHJzKEF0dHJpYnV0ZVRyZWUgdHJlZSwgTmFtZSBuYW1lLCBBdHRyS2luZCBrKSB7CiAgICAgICAgc3dpdGNoIChrKSB7CiAgICAgICAgICAgIGNhc2UgQUxMOgogICAgICAgICAgICBjYXNlIEhUTUw0OgogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIElOVkFMSUQ6CiAgICAgICAgICAgICAgICBlbnYubWVzc2FnZXMuZXJyb3IoSFRNTCwgdHJlZSwgImRjLmF0dHIudW5rbm93biIsIG5hbWUpOwogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIE9CU09MRVRFOgogICAgICAgICAgICAgICAgZW52Lm1lc3NhZ2VzLndhcm5pbmcoQUNDRVNTSUJJTElUWSwgdHJlZSwgImRjLmF0dHIub2Jzb2xldGUiLCBuYW1lKTsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBVU0VfQ1NTOgogICAgICAgICAgICAgICAgZW52Lm1lc3NhZ2VzLndhcm5pbmcoQUNDRVNTSUJJTElUWSwgdHJlZSwgImRjLmF0dHIub2Jzb2xldGUudXNlLmNzcyIsIG5hbWUpOwogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIEhUTUw1OgogICAgICAgICAgICAgICAgZW52Lm1lc3NhZ2VzLmVycm9yKEhUTUwsIHRyZWUsICJkYy5hdHRyLm5vdC5zdXBwb3J0ZWQuaHRtbDQiLCBuYW1lKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIHZvaWQgdmFsaWRhdGVIdG1sNUF0dHJzKEF0dHJpYnV0ZVRyZWUgdHJlZSwgTmFtZSBuYW1lLCBBdHRyS2luZCBrKSB7CiAgICAgICAgc3dpdGNoIChrKSB7CiAgICAgICAgICAgIGNhc2UgQUxMOgogICAgICAgICAgICBjYXNlIEhUTUw1OgogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIElOVkFMSUQ6CiAgICAgICAgICAgIGNhc2UgT0JTT0xFVEU6CiAgICAgICAgICAgIGNhc2UgVVNFX0NTUzoKICAgICAgICAgICAgY2FzZSBIVE1MNDoKICAgICAgICAgICAgICAgIGVudi5tZXNzYWdlcy5lcnJvcihIVE1MLCB0cmVlLCAiZGMuYXR0ci5ub3Quc3VwcG9ydGVkLmh0bWw1IiwgbmFtZSk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICB9CgogICAgcHJpdmF0ZSBib29sZWFuIGNoZWNrQW5jaG9yKFN0cmluZyBuYW1lKSB7CiAgICAgICAgRWxlbWVudCBlID0gZ2V0RW5jbG9zaW5nUGFja2FnZU9yQ2xhc3MoZW52LmN1cnJFbGVtZW50KTsKICAgICAgICBpZiAoZSA9PSBudWxsKQogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICBTZXQ8U3RyaW5nPiBzZXQgPSBmb3VuZEFuY2hvcnMuZ2V0KGUpOwogICAgICAgIGlmIChzZXQgPT0gbnVsbCkKICAgICAgICAgICAgZm91bmRBbmNob3JzLnB1dChlLCBzZXQgPSBuZXcgSGFzaFNldDw+KCkpOwogICAgICAgIHJldHVybiBzZXQuYWRkKG5hbWUpOwogICAgfQoKICAgIHByaXZhdGUgRWxlbWVudCBnZXRFbmNsb3NpbmdQYWNrYWdlT3JDbGFzcyhFbGVtZW50IGUpIHsKICAgICAgICB3aGlsZSAoZSAhPSBudWxsKSB7CiAgICAgICAgICAgIHN3aXRjaCAoZS5nZXRLaW5kKCkpIHsKICAgICAgICAgICAgICAgIGNhc2UgQ0xBU1M6CiAgICAgICAgICAgICAgICBjYXNlIEVOVU06CiAgICAgICAgICAgICAgICBjYXNlIElOVEVSRkFDRToKICAgICAgICAgICAgICAgIGNhc2UgUEFDS0FHRToKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZTsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgZSA9IGUuZ2V0RW5jbG9zaW5nRWxlbWVudCgpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBlOwogICAgfQoKICAgIC8vIGh0dHA6Ly93d3cudzMub3JnL1RSL2h0bWw0MDEvdHlwZXMuaHRtbCN0eXBlLW5hbWUKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFBhdHRlcm4gdmFsaWROYW1lID0gUGF0dGVybi5jb21waWxlKCJbQS1aYS16XVtBLVphLXowLTktXzouXSoiKTsKCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBQYXR0ZXJuIHZhbGlkTnVtYmVyID0gUGF0dGVybi5jb21waWxlKCItP1swLTldKyIpOwoKICAgIC8vIHBhdHRlcm4gdG8gcmVtb3ZlIGxlYWRpbmcge0Bkb2NSb290fS8/CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBQYXR0ZXJuIGRvY1Jvb3QgPSBQYXR0ZXJuLmNvbXBpbGUoIig/aSkoXFx7QGRvY1Jvb3QgKlxcfS8/KT8oLiopIik7CgogICAgcHJpdmF0ZSBTdHJpbmcgZ2V0QXR0clZhbHVlKEF0dHJpYnV0ZVRyZWUgdHJlZSkgewogICAgICAgIGlmICh0cmVlLmdldFZhbHVlKCkgPT0gbnVsbCkKICAgICAgICAgICAgcmV0dXJuIG51bGw7CgogICAgICAgIFN0cmluZ1dyaXRlciBzdyA9IG5ldyBTdHJpbmdXcml0ZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgICBuZXcgRG9jUHJldHR5KHN3KS5wcmludCh0cmVlLmdldFZhbHVlKCkpOwogICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgLy8gY2Fubm90IGhhcHBlbgogICAgICAgIH0KICAgICAgICAvLyBpZ25vcmUgcG90ZW50aWFsIHVzZSBvZiBlbnRpdGllcyBmb3Igbm93CiAgICAgICAgcmV0dXJuIHN3LnRvU3RyaW5nKCk7CiAgICB9CgogICAgcHJpdmF0ZSB2b2lkIGNoZWNrVVJJKEF0dHJpYnV0ZVRyZWUgdHJlZSwgU3RyaW5nIHVyaSkgewogICAgICAgIC8vIGFsbG93IFVSSXMgYmVnaW5uaW5nIHdpdGggamF2YXNjcmlwdDosIHdoaWNoIHdvdWxkIG90aGVyd2lzZSBiZSByZWplY3RlZCBieSB0aGUgVVJJIEFQSS4KICAgICAgICBpZiAodXJpLnN0YXJ0c1dpdGgoImphdmFzY3JpcHQ6IikpCiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB0cnkgewogICAgICAgICAgICBVUkkgdSA9IG5ldyBVUkkodXJpKTsKICAgICAgICB9IGNhdGNoIChVUklTeW50YXhFeGNlcHRpb24gZSkgewogICAgICAgICAgICBlbnYubWVzc2FnZXMuZXJyb3IoSFRNTCwgdHJlZSwgImRjLmludmFsaWQudXJpIiwgdXJpKTsKICAgICAgICB9CiAgICB9CiAgICAvLyA8L2VkaXRvci1mb2xkPgoKICAgIC8vIDxlZGl0b3ItZm9sZCBkZWZhdWx0c3RhdGU9ImNvbGxhcHNlZCIgZGVzYz0iamF2YWRvYyB0YWdzIj4KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBWb2lkIHZpc2l0QXV0aG9yKEF1dGhvclRyZWUgdHJlZSwgVm9pZCBpZ25vcmUpIHsKICAgICAgICB3YXJuSWZFbXB0eSh0cmVlLCB0cmVlLmdldE5hbWUoKSk7CiAgICAgICAgcmV0dXJuIHN1cGVyLnZpc2l0QXV0aG9yKHRyZWUsIGlnbm9yZSk7CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICBwdWJsaWMgVm9pZCB2aXNpdERvY1Jvb3QoRG9jUm9vdFRyZWUgdHJlZSwgVm9pZCBpZ25vcmUpIHsKICAgICAgICBtYXJrRW5jbG9zaW5nVGFnKEZsYWcuSEFTX0lOTElORV9UQUcpOwogICAgICAgIHJldHVybiBzdXBlci52aXNpdERvY1Jvb3QodHJlZSwgaWdub3JlKTsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBWb2lkIHZpc2l0SW5oZXJpdERvYyhJbmhlcml0RG9jVHJlZSB0cmVlLCBWb2lkIGlnbm9yZSkgewogICAgICAgIG1hcmtFbmNsb3NpbmdUYWcoRmxhZy5IQVNfSU5MSU5FX1RBRyk7CiAgICAgICAgLy8gVE9ETzogdmVyaWZ5IG9uIG92ZXJyaWRkZW4gbWV0aG9kCiAgICAgICAgZm91bmRJbmhlcml0RG9jID0gdHJ1ZTsKICAgICAgICByZXR1cm4gc3VwZXIudmlzaXRJbmhlcml0RG9jKHRyZWUsIGlnbm9yZSk7CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICBwdWJsaWMgVm9pZCB2aXNpdExpbmsoTGlua1RyZWUgdHJlZSwgVm9pZCBpZ25vcmUpIHsKICAgICAgICBtYXJrRW5jbG9zaW5nVGFnKEZsYWcuSEFTX0lOTElORV9UQUcpOwogICAgICAgIC8vIHNpbXVsYXRlIGlubGluZSBjb250ZXh0IG9uIHRhZyBzdGFjawogICAgICAgIEh0bWxUYWcgdCA9ICh0cmVlLmdldEtpbmQoKSA9PSBEb2NUcmVlLktpbmQuTElOSykKICAgICAgICAgICAgICAgID8gSHRtbFRhZy5DT0RFIDogSHRtbFRhZy5TUEFOOwogICAgICAgIHRhZ1N0YWNrLnB1c2gobmV3IFRhZ1N0YWNrSXRlbSh0cmVlLCB0KSk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgcmV0dXJuIHN1cGVyLnZpc2l0TGluayh0cmVlLCBpZ25vcmUpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgIHRhZ1N0YWNrLnBvcCgpOwogICAgICAgIH0KICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBWb2lkIHZpc2l0TGl0ZXJhbChMaXRlcmFsVHJlZSB0cmVlLCBWb2lkIGlnbm9yZSkgewogICAgICAgIG1hcmtFbmNsb3NpbmdUYWcoRmxhZy5IQVNfSU5MSU5FX1RBRyk7CiAgICAgICAgaWYgKHRyZWUuZ2V0S2luZCgpID09IERvY1RyZWUuS2luZC5DT0RFKSB7CiAgICAgICAgICAgIGZvciAoVGFnU3RhY2tJdGVtIHRzaTogdGFnU3RhY2spIHsKICAgICAgICAgICAgICAgIGlmICh0c2kudGFnID09IEh0bWxUYWcuQ09ERSkgewogICAgICAgICAgICAgICAgICAgIGVudi5tZXNzYWdlcy53YXJuaW5nKEhUTUwsIHRyZWUsICJkYy50YWcuY29kZS53aXRoaW4uY29kZSIpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBzdXBlci52aXNpdExpdGVyYWwodHJlZSwgaWdub3JlKTsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJmYWxsdGhyb3VnaCIpCiAgICBwdWJsaWMgVm9pZCB2aXNpdFBhcmFtKFBhcmFtVHJlZSB0cmVlLCBWb2lkIGlnbm9yZSkgewogICAgICAgIGJvb2xlYW4gdHlwYXJhbSA9IHRyZWUuaXNUeXBlUGFyYW1ldGVyKCk7CiAgICAgICAgSWRlbnRpZmllclRyZWUgbmFtZVRyZWUgPSB0cmVlLmdldE5hbWUoKTsKICAgICAgICBFbGVtZW50IHBhcmFtRWxlbWVudCA9IG5hbWVUcmVlICE9IG51bGwgPyBlbnYudHJlZXMuZ2V0RWxlbWVudChuZXcgRG9jVHJlZVBhdGgoZ2V0Q3VycmVudFBhdGgoKSwgbmFtZVRyZWUpKSA6IG51bGw7CgogICAgICAgIGlmIChwYXJhbUVsZW1lbnQgPT0gbnVsbCkgewogICAgICAgICAgICBzd2l0Y2ggKGVudi5jdXJyRWxlbWVudC5nZXRLaW5kKCkpIHsKICAgICAgICAgICAgICAgIGNhc2UgQ0xBU1M6IGNhc2UgSU5URVJGQUNFOiB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCF0eXBhcmFtKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGVudi5tZXNzYWdlcy5lcnJvcihSRUZFUkVOQ0UsIHRyZWUsICJkYy5pbnZhbGlkLnBhcmFtIik7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGNhc2UgTUVUSE9EOiBjYXNlIENPTlNUUlVDVE9SOiB7CiAgICAgICAgICAgICAgICAgICAgZW52Lm1lc3NhZ2VzLmVycm9yKFJFRkVSRU5DRSwgbmFtZVRyZWUsICJkYy5wYXJhbS5uYW1lLm5vdC5mb3VuZCIpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgZW52Lm1lc3NhZ2VzLmVycm9yKFJFRkVSRU5DRSwgdHJlZSwgImRjLmludmFsaWQucGFyYW0iKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGJvb2xlYW4gdW5pcXVlID0gZm91bmRQYXJhbXMuYWRkKHBhcmFtRWxlbWVudCk7CgogICAgICAgICAgICBpZiAoIXVuaXF1ZSkgewogICAgICAgICAgICAgICAgZW52Lm1lc3NhZ2VzLndhcm5pbmcoUkVGRVJFTkNFLCB0cmVlLCAiZGMuZXhpc3RzLnBhcmFtIiwgbmFtZVRyZWUpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICB3YXJuSWZFbXB0eSh0cmVlLCB0cmVlLmdldERlc2NyaXB0aW9uKCkpOwogICAgICAgIHJldHVybiBzdXBlci52aXNpdFBhcmFtKHRyZWUsIGlnbm9yZSk7CiAgICB9CgogICAgcHJpdmF0ZSB2b2lkIGNoZWNrUGFyYW1zRG9jdW1lbnRlZChMaXN0PD8gZXh0ZW5kcyBFbGVtZW50PiBsaXN0KSB7CiAgICAgICAgaWYgKGZvdW5kSW5oZXJpdERvYykKICAgICAgICAgICAgcmV0dXJuOwoKICAgICAgICBmb3IgKEVsZW1lbnQgZTogbGlzdCkgewogICAgICAgICAgICBpZiAoIWZvdW5kUGFyYW1zLmNvbnRhaW5zKGUpKSB7CiAgICAgICAgICAgICAgICBDaGFyU2VxdWVuY2UgcGFyYW1OYW1lID0gKGUuZ2V0S2luZCgpID09IEVsZW1lbnRLaW5kLlRZUEVfUEFSQU1FVEVSKQogICAgICAgICAgICAgICAgICAgICAgICA/ICI8IiArIGUuZ2V0U2ltcGxlTmFtZSgpICsgIj4iCiAgICAgICAgICAgICAgICAgICAgICAgIDogZS5nZXRTaW1wbGVOYW1lKCk7CiAgICAgICAgICAgICAgICByZXBvcnRNaXNzaW5nKCJkYy5taXNzaW5nLnBhcmFtIiwgcGFyYW1OYW1lKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBWb2lkIHZpc2l0UHJvdmlkZXMoUHJvdmlkZXNUcmVlIHRyZWUsIFZvaWQgaWdub3JlKSB7CiAgICAgICAgRWxlbWVudCBlID0gZW52LnRyZWVzLmdldEVsZW1lbnQoZW52LmN1cnJQYXRoKTsKICAgICAgICBpZiAoZS5nZXRLaW5kKCkgIT0gRWxlbWVudEtpbmQuTU9EVUxFKSB7CiAgICAgICAgICAgIGVudi5tZXNzYWdlcy5lcnJvcihSRUZFUkVOQ0UsIHRyZWUsICJkYy5pbnZhbGlkLnByb3ZpZGVzIik7CiAgICAgICAgfQogICAgICAgIFJlZmVyZW5jZVRyZWUgc2VydmljZVR5cGUgPSB0cmVlLmdldFNlcnZpY2VUeXBlKCk7CiAgICAgICAgRWxlbWVudCBzZSA9IGVudi50cmVlcy5nZXRFbGVtZW50KG5ldyBEb2NUcmVlUGF0aChnZXRDdXJyZW50UGF0aCgpLCBzZXJ2aWNlVHlwZSkpOwogICAgICAgIGlmIChzZSA9PSBudWxsKSB7CiAgICAgICAgICAgIGVudi5tZXNzYWdlcy5lcnJvcihSRUZFUkVOQ0UsIHRyZWUsICJkYy5zZXJ2aWNlLm5vdC5mb3VuZCIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gc3VwZXIudmlzaXRQcm92aWRlcyh0cmVlLCBpZ25vcmUpOwogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIFZvaWQgdmlzaXRSZWZlcmVuY2UoUmVmZXJlbmNlVHJlZSB0cmVlLCBWb2lkIGlnbm9yZSkgewogICAgICAgIFN0cmluZyBzaWcgPSB0cmVlLmdldFNpZ25hdHVyZSgpOwogICAgICAgIGlmIChzaWcuY29udGFpbnMoIjwiKSB8fCBzaWcuY29udGFpbnMoIj4iKSkKICAgICAgICAgICAgZW52Lm1lc3NhZ2VzLmVycm9yKFJFRkVSRU5DRSwgdHJlZSwgImRjLnR5cGUuYXJnLm5vdC5hbGxvd2VkIik7CgogICAgICAgIEVsZW1lbnQgZSA9IGVudi50cmVlcy5nZXRFbGVtZW50KGdldEN1cnJlbnRQYXRoKCkpOwogICAgICAgIGlmIChlID09IG51bGwpCiAgICAgICAgICAgIGVudi5tZXNzYWdlcy5lcnJvcihSRUZFUkVOQ0UsIHRyZWUsICJkYy5yZWYubm90LmZvdW5kIik7CiAgICAgICAgcmV0dXJuIHN1cGVyLnZpc2l0UmVmZXJlbmNlKHRyZWUsIGlnbm9yZSk7CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICBwdWJsaWMgVm9pZCB2aXNpdFJldHVybihSZXR1cm5UcmVlIHRyZWUsIFZvaWQgaWdub3JlKSB7CiAgICAgICAgaWYgKGZvdW5kUmV0dXJuKSB7CiAgICAgICAgICAgIGVudi5tZXNzYWdlcy53YXJuaW5nKFJFRkVSRU5DRSwgdHJlZSwgImRjLmV4aXN0cy5yZXR1cm4iKTsKICAgICAgICB9CgogICAgICAgIEVsZW1lbnQgZSA9IGVudi50cmVlcy5nZXRFbGVtZW50KGVudi5jdXJyUGF0aCk7CiAgICAgICAgaWYgKGUuZ2V0S2luZCgpICE9IEVsZW1lbnRLaW5kLk1FVEhPRAogICAgICAgICAgICAgICAgfHwgKChFeGVjdXRhYmxlRWxlbWVudCkgZSkuZ2V0UmV0dXJuVHlwZSgpLmdldEtpbmQoKSA9PSBUeXBlS2luZC5WT0lEKQogICAgICAgICAgICBlbnYubWVzc2FnZXMuZXJyb3IoUkVGRVJFTkNFLCB0cmVlLCAiZGMuaW52YWxpZC5yZXR1cm4iKTsKICAgICAgICBmb3VuZFJldHVybiA9IHRydWU7CiAgICAgICAgd2FybklmRW1wdHkodHJlZSwgdHJlZS5nZXREZXNjcmlwdGlvbigpKTsKICAgICAgICByZXR1cm4gc3VwZXIudmlzaXRSZXR1cm4odHJlZSwgaWdub3JlKTsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBWb2lkIHZpc2l0U2VyaWFsRGF0YShTZXJpYWxEYXRhVHJlZSB0cmVlLCBWb2lkIGlnbm9yZSkgewogICAgICAgIHdhcm5JZkVtcHR5KHRyZWUsIHRyZWUuZ2V0RGVzY3JpcHRpb24oKSk7CiAgICAgICAgcmV0dXJuIHN1cGVyLnZpc2l0U2VyaWFsRGF0YSh0cmVlLCBpZ25vcmUpOwogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIFZvaWQgdmlzaXRTZXJpYWxGaWVsZChTZXJpYWxGaWVsZFRyZWUgdHJlZSwgVm9pZCBpZ25vcmUpIHsKICAgICAgICB3YXJuSWZFbXB0eSh0cmVlLCB0cmVlLmdldERlc2NyaXB0aW9uKCkpOwogICAgICAgIHJldHVybiBzdXBlci52aXNpdFNlcmlhbEZpZWxkKHRyZWUsIGlnbm9yZSk7CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICBwdWJsaWMgVm9pZCB2aXNpdFNpbmNlKFNpbmNlVHJlZSB0cmVlLCBWb2lkIGlnbm9yZSkgewogICAgICAgIHdhcm5JZkVtcHR5KHRyZWUsIHRyZWUuZ2V0Qm9keSgpKTsKICAgICAgICByZXR1cm4gc3VwZXIudmlzaXRTaW5jZSh0cmVlLCBpZ25vcmUpOwogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIFZvaWQgdmlzaXRUaHJvd3MoVGhyb3dzVHJlZSB0cmVlLCBWb2lkIGlnbm9yZSkgewogICAgICAgIFJlZmVyZW5jZVRyZWUgZXhOYW1lID0gdHJlZS5nZXRFeGNlcHRpb25OYW1lKCk7CiAgICAgICAgRWxlbWVudCBleCA9IGVudi50cmVlcy5nZXRFbGVtZW50KG5ldyBEb2NUcmVlUGF0aChnZXRDdXJyZW50UGF0aCgpLCBleE5hbWUpKTsKICAgICAgICBpZiAoZXggPT0gbnVsbCkgewogICAgICAgICAgICBlbnYubWVzc2FnZXMuZXJyb3IoUkVGRVJFTkNFLCB0cmVlLCAiZGMucmVmLm5vdC5mb3VuZCIpOwogICAgICAgIH0gZWxzZSBpZiAoaXNUaHJvd2FibGUoZXguYXNUeXBlKCkpKSB7CiAgICAgICAgICAgIHN3aXRjaCAoZW52LmN1cnJFbGVtZW50LmdldEtpbmQoKSkgewogICAgICAgICAgICAgICAgY2FzZSBDT05TVFJVQ1RPUjoKICAgICAgICAgICAgICAgIGNhc2UgTUVUSE9EOgogICAgICAgICAgICAgICAgICAgIGlmIChpc0NoZWNrZWRFeGNlcHRpb24oZXguYXNUeXBlKCkpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIEV4ZWN1dGFibGVFbGVtZW50IGVlID0gKEV4ZWN1dGFibGVFbGVtZW50KSBlbnYuY3VyckVsZW1lbnQ7CiAgICAgICAgICAgICAgICAgICAgICAgIGNoZWNrVGhyb3dzRGVjbGFyZWQoZXhOYW1lLCBleC5hc1R5cGUoKSwgZWUuZ2V0VGhyb3duVHlwZXMoKSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICBlbnYubWVzc2FnZXMuZXJyb3IoUkVGRVJFTkNFLCB0cmVlLCAiZGMuaW52YWxpZC50aHJvd3MiKTsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVudi5tZXNzYWdlcy5lcnJvcihSRUZFUkVOQ0UsIHRyZWUsICJkYy5pbnZhbGlkLnRocm93cyIpOwogICAgICAgIH0KICAgICAgICB3YXJuSWZFbXB0eSh0cmVlLCB0cmVlLmdldERlc2NyaXB0aW9uKCkpOwogICAgICAgIHJldHVybiBzY2FuKHRyZWUuZ2V0RGVzY3JpcHRpb24oKSwgaWdub3JlKTsKICAgIH0KCiAgICBwcml2YXRlIGJvb2xlYW4gaXNUaHJvd2FibGUoVHlwZU1pcnJvciB0bSkgewogICAgICAgIHN3aXRjaCAodG0uZ2V0S2luZCgpKSB7CiAgICAgICAgICAgIGNhc2UgREVDTEFSRUQ6CiAgICAgICAgICAgIGNhc2UgVFlQRVZBUjoKICAgICAgICAgICAgICAgIHJldHVybiBlbnYudHlwZXMuaXNBc3NpZ25hYmxlKHRtLCBlbnYuamF2YV9sYW5nX1Rocm93YWJsZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICBwcml2YXRlIHZvaWQgY2hlY2tUaHJvd3NEZWNsYXJlZChSZWZlcmVuY2VUcmVlIHRyZWUsIFR5cGVNaXJyb3IgdCwgTGlzdDw/IGV4dGVuZHMgVHlwZU1pcnJvcj4gbGlzdCkgewogICAgICAgIGJvb2xlYW4gZm91bmQgPSBmYWxzZTsKICAgICAgICBmb3IgKFR5cGVNaXJyb3IgdGwgOiBsaXN0KSB7CiAgICAgICAgICAgIGlmIChlbnYudHlwZXMuaXNBc3NpZ25hYmxlKHQsIHRsKSkgewogICAgICAgICAgICAgICAgZm91bmRUaHJvd3MuYWRkKHRsKTsKICAgICAgICAgICAgICAgIGZvdW5kID0gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoIWZvdW5kKQogICAgICAgICAgICBlbnYubWVzc2FnZXMuZXJyb3IoUkVGRVJFTkNFLCB0cmVlLCAiZGMuZXhjZXB0aW9uLm5vdC50aHJvd24iLCB0KTsKICAgIH0KCiAgICBwcml2YXRlIHZvaWQgY2hlY2tUaHJvd3NEb2N1bWVudGVkKExpc3Q8PyBleHRlbmRzIFR5cGVNaXJyb3I+IGxpc3QpIHsKICAgICAgICBpZiAoZm91bmRJbmhlcml0RG9jKQogICAgICAgICAgICByZXR1cm47CgogICAgICAgIGZvciAoVHlwZU1pcnJvciB0bDogbGlzdCkgewogICAgICAgICAgICBpZiAoaXNDaGVja2VkRXhjZXB0aW9uKHRsKSAmJiAhZm91bmRUaHJvd3MuY29udGFpbnModGwpKQogICAgICAgICAgICAgICAgcmVwb3J0TWlzc2luZygiZGMubWlzc2luZy50aHJvd3MiLCB0bCk7CiAgICAgICAgfQogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIFZvaWQgdmlzaXRVbmtub3duQmxvY2tUYWcoVW5rbm93bkJsb2NrVGFnVHJlZSB0cmVlLCBWb2lkIGlnbm9yZSkgewogICAgICAgIGNoZWNrVW5rbm93blRhZyh0cmVlLCB0cmVlLmdldFRhZ05hbWUoKSk7CiAgICAgICAgcmV0dXJuIHN1cGVyLnZpc2l0VW5rbm93bkJsb2NrVGFnKHRyZWUsIGlnbm9yZSk7CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICBwdWJsaWMgVm9pZCB2aXNpdFVua25vd25JbmxpbmVUYWcoVW5rbm93bklubGluZVRhZ1RyZWUgdHJlZSwgVm9pZCBpZ25vcmUpIHsKICAgICAgICBjaGVja1Vua25vd25UYWcodHJlZSwgdHJlZS5nZXRUYWdOYW1lKCkpOwogICAgICAgIHJldHVybiBzdXBlci52aXNpdFVua25vd25JbmxpbmVUYWcodHJlZSwgaWdub3JlKTsKICAgIH0KCiAgICBwcml2YXRlIHZvaWQgY2hlY2tVbmtub3duVGFnKERvY1RyZWUgdHJlZSwgU3RyaW5nIHRhZ05hbWUpIHsKICAgICAgICBpZiAoZW52LmN1c3RvbVRhZ3MgIT0gbnVsbCAmJiAhZW52LmN1c3RvbVRhZ3MuY29udGFpbnModGFnTmFtZSkpCiAgICAgICAgICAgIGVudi5tZXNzYWdlcy5lcnJvcihTWU5UQVgsIHRyZWUsICJkYy50YWcudW5rbm93biIsIHRhZ05hbWUpOwogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIFZvaWQgdmlzaXRVc2VzKFVzZXNUcmVlIHRyZWUsIFZvaWQgaWdub3JlKSB7CiAgICAgICAgRWxlbWVudCBlID0gZW52LnRyZWVzLmdldEVsZW1lbnQoZW52LmN1cnJQYXRoKTsKICAgICAgICBpZiAoZS5nZXRLaW5kKCkgIT0gRWxlbWVudEtpbmQuTU9EVUxFKSB7CiAgICAgICAgICAgIGVudi5tZXNzYWdlcy5lcnJvcihSRUZFUkVOQ0UsIHRyZWUsICJkYy5pbnZhbGlkLnVzZXMiKTsKICAgICAgICB9CiAgICAgICAgUmVmZXJlbmNlVHJlZSBzZXJ2aWNlVHlwZSA9IHRyZWUuZ2V0U2VydmljZVR5cGUoKTsKICAgICAgICBFbGVtZW50IHNlID0gZW52LnRyZWVzLmdldEVsZW1lbnQobmV3IERvY1RyZWVQYXRoKGdldEN1cnJlbnRQYXRoKCksIHNlcnZpY2VUeXBlKSk7CiAgICAgICAgaWYgKHNlID09IG51bGwpIHsKICAgICAgICAgICAgZW52Lm1lc3NhZ2VzLmVycm9yKFJFRkVSRU5DRSwgdHJlZSwgImRjLnNlcnZpY2Uubm90LmZvdW5kIik7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzdXBlci52aXNpdFVzZXModHJlZSwgaWdub3JlKTsKICAgIH0KCiAgICBAT3ZlcnJpZGUgQERlZmluZWRCeShBcGkuQ09NUElMRVJfVFJFRSkKICAgIHB1YmxpYyBWb2lkIHZpc2l0VmFsdWUoVmFsdWVUcmVlIHRyZWUsIFZvaWQgaWdub3JlKSB7CiAgICAgICAgUmVmZXJlbmNlVHJlZSByZWYgPSB0cmVlLmdldFJlZmVyZW5jZSgpOwogICAgICAgIGlmIChyZWYgPT0gbnVsbCB8fCByZWYuZ2V0U2lnbmF0dXJlKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGlmICghaXNDb25zdGFudChlbnYuY3VyckVsZW1lbnQpKQogICAgICAgICAgICAgICAgZW52Lm1lc3NhZ2VzLmVycm9yKFJFRkVSRU5DRSwgdHJlZSwgImRjLnZhbHVlLm5vdC5hbGxvd2VkLmhlcmUiKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBFbGVtZW50IGUgPSBlbnYudHJlZXMuZ2V0RWxlbWVudChuZXcgRG9jVHJlZVBhdGgoZ2V0Q3VycmVudFBhdGgoKSwgcmVmKSk7CiAgICAgICAgICAgIGlmICghaXNDb25zdGFudChlKSkKICAgICAgICAgICAgICAgIGVudi5tZXNzYWdlcy5lcnJvcihSRUZFUkVOQ0UsIHRyZWUsICJkYy52YWx1ZS5ub3QuYS5jb25zdGFudCIpOwogICAgICAgIH0KCiAgICAgICAgbWFya0VuY2xvc2luZ1RhZyhGbGFnLkhBU19JTkxJTkVfVEFHKTsKICAgICAgICByZXR1cm4gc3VwZXIudmlzaXRWYWx1ZSh0cmVlLCBpZ25vcmUpOwogICAgfQoKICAgIHByaXZhdGUgYm9vbGVhbiBpc0NvbnN0YW50KEVsZW1lbnQgZSkgewogICAgICAgIGlmIChlID09IG51bGwpCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKCiAgICAgICAgc3dpdGNoIChlLmdldEtpbmQoKSkgewogICAgICAgICAgICBjYXNlIEZJRUxEOgogICAgICAgICAgICAgICAgT2JqZWN0IHZhbHVlID0gKChWYXJpYWJsZUVsZW1lbnQpIGUpLmdldENvbnN0YW50VmFsdWUoKTsKICAgICAgICAgICAgICAgIHJldHVybiAodmFsdWUgIT0gbnVsbCk7IC8vIGNhbid0IGRpc3Rpbmd1aXNoICJub3QgYSBjb25zdGFudCIgZnJvbSAiY29uc3RhbnQgaXMgbnVsbCIKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICB9CgogICAgQE92ZXJyaWRlIEBEZWZpbmVkQnkoQXBpLkNPTVBJTEVSX1RSRUUpCiAgICBwdWJsaWMgVm9pZCB2aXNpdFZlcnNpb24oVmVyc2lvblRyZWUgdHJlZSwgVm9pZCBpZ25vcmUpIHsKICAgICAgICB3YXJuSWZFbXB0eSh0cmVlLCB0cmVlLmdldEJvZHkoKSk7CiAgICAgICAgcmV0dXJuIHN1cGVyLnZpc2l0VmVyc2lvbih0cmVlLCBpZ25vcmUpOwogICAgfQoKICAgIEBPdmVycmlkZSBARGVmaW5lZEJ5KEFwaS5DT01QSUxFUl9UUkVFKQogICAgcHVibGljIFZvaWQgdmlzaXRFcnJvbmVvdXMoRXJyb25lb3VzVHJlZSB0cmVlLCBWb2lkIGlnbm9yZSkgewogICAgICAgIGVudi5tZXNzYWdlcy5lcnJvcihTWU5UQVgsIHRyZWUsIG51bGwsIHRyZWUuZ2V0RGlhZ25vc3RpYygpLmdldE1lc3NhZ2UobnVsbCkpOwogICAgICAgIHJldHVybiBudWxsOwogICAgfQogICAgLy8gPC9lZGl0b3ItZm9sZD4KCiAgICAvLyA8ZWRpdG9yLWZvbGQgZGVmYXVsdHN0YXRlPSJjb2xsYXBzZWQiIGRlc2M9IlV0aWxpdHkgbWV0aG9kcyI+CgogICAgcHJpdmF0ZSBib29sZWFuIGlzQ2hlY2tlZEV4Y2VwdGlvbihUeXBlTWlycm9yIHQpIHsKICAgICAgICByZXR1cm4gIShlbnYudHlwZXMuaXNBc3NpZ25hYmxlKHQsIGVudi5qYXZhX2xhbmdfRXJyb3IpCiAgICAgICAgICAgICAgICB8fCBlbnYudHlwZXMuaXNBc3NpZ25hYmxlKHQsIGVudi5qYXZhX2xhbmdfUnVudGltZUV4Y2VwdGlvbikpOwogICAgfQoKICAgIHByaXZhdGUgYm9vbGVhbiBpc1N5bnRoZXRpYygpIHsKICAgICAgICBzd2l0Y2ggKGVudi5jdXJyRWxlbWVudC5nZXRLaW5kKCkpIHsKICAgICAgICAgICAgY2FzZSBDT05TVFJVQ1RPUjoKICAgICAgICAgICAgICAgIC8vIEEgc3ludGhldGljIGRlZmF1bHQgY29uc3RydWN0b3IgaGFzIHRoZSBzYW1lIHBvcyBhcyB0aGUKICAgICAgICAgICAgICAgIC8vIGVuY2xvc2luZyBjbGFzcwogICAgICAgICAgICAgICAgVHJlZVBhdGggcCA9IGVudi5jdXJyUGF0aDsKICAgICAgICAgICAgICAgIHJldHVybiBlbnYuZ2V0UG9zKHApID09IGVudi5nZXRQb3MocC5nZXRQYXJlbnRQYXRoKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgdm9pZCBtYXJrRW5jbG9zaW5nVGFnKEZsYWcgZmxhZykgewogICAgICAgIFRhZ1N0YWNrSXRlbSB0b3AgPSB0YWdTdGFjay5wZWVrKCk7CiAgICAgICAgaWYgKHRvcCAhPSBudWxsKQogICAgICAgICAgICB0b3AuZmxhZ3MuYWRkKGZsYWcpOwogICAgfQoKICAgIFN0cmluZyB0b1N0cmluZyhUcmVlUGF0aCBwKSB7CiAgICAgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKCJUcmVlUGF0aFsiKTsKICAgICAgICB0b1N0cmluZyhwLCBzYik7CiAgICAgICAgc2IuYXBwZW5kKCJdIik7CiAgICAgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7CiAgICB9CgogICAgdm9pZCB0b1N0cmluZyhUcmVlUGF0aCBwLCBTdHJpbmdCdWlsZGVyIHNiKSB7CiAgICAgICAgVHJlZVBhdGggcGFyZW50ID0gcC5nZXRQYXJlbnRQYXRoKCk7CiAgICAgICAgaWYgKHBhcmVudCAhPSBudWxsKSB7CiAgICAgICAgICAgIHRvU3RyaW5nKHBhcmVudCwgc2IpOwogICAgICAgICAgICBzYi5hcHBlbmQoIiwiKTsKICAgICAgICB9CiAgICAgICBzYi5hcHBlbmQocC5nZXRMZWFmKCkuZ2V0S2luZCgpKS5hcHBlbmQoIjoiKS5hcHBlbmQoZW52LmdldFBvcyhwKSkuYXBwZW5kKCI6UyIpLmFwcGVuZChlbnYuZ2V0U3RhcnRQb3MocCkpOwogICAgfQoKICAgIHZvaWQgd2FybklmRW1wdHkoRG9jVHJlZSB0cmVlLCBMaXN0PD8gZXh0ZW5kcyBEb2NUcmVlPiBsaXN0KSB7CiAgICAgICAgZm9yIChEb2NUcmVlIGQ6IGxpc3QpIHsKICAgICAgICAgICAgc3dpdGNoIChkLmdldEtpbmQoKSkgewogICAgICAgICAgICAgICAgY2FzZSBURVhUOgogICAgICAgICAgICAgICAgICAgIGlmIChoYXNOb25XaGl0ZXNwYWNlKChUZXh0VHJlZSkgZCkpCiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVudi5tZXNzYWdlcy53YXJuaW5nKFNZTlRBWCwgdHJlZSwgImRjLmVtcHR5IiwgdHJlZS5nZXRLaW5kKCkudGFnTmFtZSk7CiAgICB9CgogICAgYm9vbGVhbiBoYXNOb25XaGl0ZXNwYWNlKFRleHRUcmVlIHRyZWUpIHsKICAgICAgICBTdHJpbmcgcyA9IHRyZWUuZ2V0Qm9keSgpOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcy5sZW5ndGgoKTsgaSsrKSB7CiAgICAgICAgICAgIGlmICghQ2hhcmFjdGVyLmlzV2hpdGVzcGFjZShzLmNoYXJBdChpKSkpCiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIC8vIDwvZWRpdG9yLWZvbGQ+Cgp9ClBLAwQKAAAIAADSfU1KAAAAAAAAAAAAAAAABgAAAGphdmF4L1BLAwQKAAAIAADSfU1KAAAAAAAAAAAAAAAAEQAAAGphdmF4L2Fubm90YXRpb24vUEsDBAoAAAgAAAY7qUoAAAAAAAAAAAAAAAAcAAAAamF2YXgvYW5ub3RhdGlvbi9wcm9jZXNzaW5nL1BLAwQKAAAIAADSfU1K27cO7FUHAABVBwAALQAAAGphdmF4L2Fubm90YXRpb24vcHJvY2Vzc2luZy9wYWNrYWdlLWluZm8uamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAwNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKLyoqCiAqIEZhY2lsaXRpZXMgZm9yIGRlY2xhcmluZyBhbm5vdGF0aW9uIHByb2Nlc3NvcnMgYW5kIGZvcgogKiBhbGxvd2luZyBhbm5vdGF0aW9uIHByb2Nlc3NvcnMgdG8gY29tbXVuaWNhdGUgd2l0aCBhbiBhbm5vdGF0aW9uIHByb2Nlc3NpbmcKICogdG9vbCBlbnZpcm9ubWVudC4KICoKICogPHA+IFVubGVzcyBvdGhlcndpc2Ugc3BlY2lmaWVkIGluIGEgcGFydGljdWxhciBpbXBsZW1lbnRhdGlvbiwgdGhlCiAqIGNvbGxlY3Rpb25zIHJldHVybmVkIGJ5IG1ldGhvZHMgaW4gdGhpcyBwYWNrYWdlIHNob3VsZCBiZSBleHBlY3RlZAogKiB0byBiZSB1bm1vZGlmaWFibGUgYnkgdGhlIGNhbGxlciBhbmQgdW5zYWZlIGZvciBjb25jdXJyZW50IGFjY2Vzcy4KICoKICogPHA+IFVubGVzcyBvdGhlcndpc2Ugc3BlY2lmaWVkLCBtZXRob2RzIGluIHRoaXMgcGFja2FnZSB3aWxsIHRocm93CiAqIGEge0Bjb2RlIE51bGxQb2ludGVyRXhjZXB0aW9ufSBpZiBnaXZlbiBhIHtAY29kZSBudWxsfSBhcmd1bWVudC4KICoKICogQGF1dGhvciBKb3NlcGggRC4gRGFyY3kKICogQGF1dGhvciBTY290dCBTZWxpZ21hbgogKiBAYXV0aG9yIFBldGVyIHZvbiBkZXIgQWgmZWFjdXRlOwogKiBAc2luY2UgMS42CiAqLwpwYWNrYWdlIGphdmF4LmFubm90YXRpb24ucHJvY2Vzc2luZzsKUEsDBAoAAAgAANJ9TUoXAHDMJBQAACQUAAA2AAAAamF2YXgvYW5ub3RhdGlvbi9wcm9jZXNzaW5nL1Byb2Nlc3NpbmdFbnZpcm9ubWVudC5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDA1LCAyMDEyLCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGphdmF4LmFubm90YXRpb24ucHJvY2Vzc2luZzsKCmltcG9ydCBqYXZhLnV0aWwuTWFwOwppbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuU291cmNlVmVyc2lvbjsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwudXRpbC5FbGVtZW50czsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwudXRpbC5UeXBlczsKCi8qKgogKiBBbiBhbm5vdGF0aW9uIHByb2Nlc3NpbmcgdG9vbCBmcmFtZXdvcmsgd2lsbCB7QGxpbmtwbGFpbgogKiBQcm9jZXNzb3IjaW5pdCBwcm92aWRlIGFuIGFubm90YXRpb24gcHJvY2Vzc29yIHdpdGggYW4gb2JqZWN0CiAqIGltcGxlbWVudGluZyB0aGlzIGludGVyZmFjZX0gc28gdGhlIHByb2Nlc3NvciBjYW4gdXNlIGZhY2lsaXRpZXMKICogcHJvdmlkZWQgYnkgdGhlIGZyYW1ld29yayB0byB3cml0ZSBuZXcgZmlsZXMsIHJlcG9ydCBlcnJvcgogKiBtZXNzYWdlcywgYW5kIGZpbmQgb3RoZXIgdXRpbGl0aWVzLgogKgogKiA8cD5UaGlyZCBwYXJ0aWVzIG1heSB3aXNoIHRvIHByb3ZpZGUgdmFsdWUtYWRkIHdyYXBwZXJzIGFyb3VuZCB0aGUKICogZmFjaWxpdHkgb2JqZWN0cyBmcm9tIHRoaXMgaW50ZXJmYWNlLCBmb3IgZXhhbXBsZSBhIHtAY29kZSBGaWxlcn0KICogZXh0ZW5zaW9uIHRoYXQgYWxsb3dzIG11bHRpcGxlIHByb2Nlc3NvcnMgdG8gY29vcmRpbmF0ZSB3cml0aW5nIG91dAogKiBhIHNpbmdsZSBzb3VyY2UgZmlsZS4gIFRvIGVuYWJsZSB0aGlzLCBmb3IgcHJvY2Vzc29ycyBydW5uaW5nIGluIGEKICogY29udGV4dCB3aGVyZSB0aGVpciBzaWRlIGVmZmVjdHMgdmlhIHRoZSBBUEkgY291bGQgYmUgdmlzaWJsZSB0bwogKiBlYWNoIG90aGVyLCB0aGUgdG9vbCBpbmZyYXN0cnVjdHVyZSBtdXN0IHByb3ZpZGUgY29ycmVzcG9uZGluZwogKiBmYWNpbGl0eSBvYmplY3RzIHRoYXQgYXJlIHtAY29kZSAuZXF1YWxzfSwge0Bjb2RlIEZpbGVyfXMgdGhhdCBhcmUKICoge0Bjb2RlIC5lcXVhbHN9LCBhbmQgc28gb24uICBJbiBhZGRpdGlvbiwgdGhlIHRvb2wgaW52b2NhdGlvbiBtdXN0CiAqIGJlIGFibGUgdG8gYmUgY29uZmlndXJlZCBzdWNoIHRoYXQgZnJvbSB0aGUgcGVyc3BlY3RpdmUgb2YgdGhlCiAqIHJ1bm5pbmcgYW5ub3RhdGlvbiBwcm9jZXNzb3JzLCBhdCBsZWFzdCB0aGUgY2hvc2VuIHN1YnNldCBvZiBoZWxwZXIKICogY2xhc3NlcyBhcmUgdmlld2VkIGFzIGJlaW5nIGxvYWRlZCBieSB0aGUgc2FtZSBjbGFzcyBsb2FkZXIuCiAqIChTaW5jZSB0aGUgZmFjaWxpdHkgb2JqZWN0cyBtYW5hZ2Ugc2hhcmVkIHN0YXRlLCB0aGUgaW1wbGVtZW50YXRpb24KICogb2YgYSB3cmFwcGVyIGNsYXNzIG11c3Qga25vdyB3aGV0aGVyIG9yIG5vdCB0aGUgc2FtZSBiYXNlIGZhY2lsaXR5CiAqIG9iamVjdCBoYXMgYmVlbiB3cmFwcGVkIGJlZm9yZS4pCiAqCiAqIEBhdXRob3IgSm9zZXBoIEQuIERhcmN5CiAqIEBhdXRob3IgU2NvdHQgU2VsaWdtYW4KICogQGF1dGhvciBQZXRlciB2b24gZGVyIEFoJmVhY3V0ZTsKICogQHNpbmNlIDEuNgogKi8KcHVibGljIGludGVyZmFjZSBQcm9jZXNzaW5nRW52aXJvbm1lbnQgewogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBwcm9jZXNzb3Itc3BlY2lmaWMgb3B0aW9ucyBwYXNzZWQgdG8gdGhlIGFubm90YXRpb24KICAgICAqIHByb2Nlc3NpbmcgdG9vbC4gIE9wdGlvbnMgYXJlIHJldHVybmVkIGluIHRoZSBmb3JtIG9mIGEgbWFwIGZyb20KICAgICAqIG9wdGlvbiBuYW1lIHRvIG9wdGlvbiB2YWx1ZS4gIEZvciBhbiBvcHRpb24gd2l0aCBubyB2YWx1ZSwgdGhlCiAgICAgKiBjb3JyZXNwb25kaW5nIHZhbHVlIGluIHRoZSBtYXAgaXMge0Bjb2RlIG51bGx9LgogICAgICoKICAgICAqIDxwPlNlZSBkb2N1bWVudGF0aW9uIG9mIHRoZSBwYXJ0aWN1bGFyIHRvb2wgaW5mcmFzdHJ1Y3R1cmUKICAgICAqIGJlaW5nIHVzZWQgZm9yIGRldGFpbHMgb24gaG93IHRvIHBhc3MgaW4gcHJvY2Vzc29yLXNwZWNpZmljCiAgICAgKiBvcHRpb25zLiAgRm9yIGV4YW1wbGUsIGEgY29tbWFuZC1saW5lIGltcGxlbWVudGF0aW9uIG1heQogICAgICogZGlzdGluZ3Vpc2ggcHJvY2Vzc29yLXNwZWNpZmljIG9wdGlvbnMgYnkgcHJlZml4aW5nIHRoZW0gd2l0aCBhCiAgICAgKiBrbm93biBzdHJpbmcgbGlrZSB7QGNvZGUgIi1BIn07IG90aGVyIHRvb2wgaW1wbGVtZW50YXRpb25zIG1heQogICAgICogZm9sbG93IGRpZmZlcmVudCBjb252ZW50aW9ucyBvciBwcm92aWRlIGFsdGVybmF0aXZlIG1lY2hhbmlzbXMuCiAgICAgKiBBIGdpdmVuIGltcGxlbWVudGF0aW9uIG1heSBhbHNvIHByb3ZpZGUgaW1wbGVtZW50YXRpb24tc3BlY2lmaWMKICAgICAqIHdheXMgb2YgZmluZGluZyBvcHRpb25zIHBhc3NlZCB0byB0aGUgdG9vbCBpbiBhZGRpdGlvbiB0byB0aGUKICAgICAqIHByb2Nlc3Nvci1zcGVjaWZpYyBvcHRpb25zLgogICAgICoKICAgICAqIEByZXR1cm4gdGhlIHByb2Nlc3Nvci1zcGVjaWZpYyBvcHRpb25zIHBhc3NlZCB0byB0aGUgdG9vbAogICAgICovCiAgICBNYXA8U3RyaW5nLFN0cmluZz4gZ2V0T3B0aW9ucygpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgbWVzc2FnZXIgdXNlZCB0byByZXBvcnQgZXJyb3JzLCB3YXJuaW5ncywgYW5kIG90aGVyCiAgICAgKiBub3RpY2VzLgogICAgICoKICAgICAqIEByZXR1cm4gdGhlIG1lc3NhZ2VyCiAgICAgKi8KICAgIE1lc3NhZ2VyIGdldE1lc3NhZ2VyKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBmaWxlciB1c2VkIHRvIGNyZWF0ZSBuZXcgc291cmNlLCBjbGFzcywgb3IgYXV4aWxpYXJ5CiAgICAgKiBmaWxlcy4KICAgICAqCiAgICAgKiBAcmV0dXJuIHRoZSBmaWxlcgogICAgICovCiAgICBGaWxlciBnZXRGaWxlcigpOwoKICAgIC8qKgogICAgICogUmV0dXJucyBhbiBpbXBsZW1lbnRhdGlvbiBvZiBzb21lIHV0aWxpdHkgbWV0aG9kcyBmb3IKICAgICAqIG9wZXJhdGluZyBvbiBlbGVtZW50cwogICAgICoKICAgICAqIEByZXR1cm4gZWxlbWVudCB1dGlsaXRpZXMKICAgICAqLwogICAgRWxlbWVudHMgZ2V0RWxlbWVudFV0aWxzKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGFuIGltcGxlbWVudGF0aW9uIG9mIHNvbWUgdXRpbGl0eSBtZXRob2RzIGZvcgogICAgICogb3BlcmF0aW5nIG9uIHR5cGVzLgogICAgICoKICAgICAqIEByZXR1cm4gdHlwZSB1dGlsaXRpZXMKICAgICAqLwogICAgVHlwZXMgZ2V0VHlwZVV0aWxzKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBzb3VyY2UgdmVyc2lvbiB0aGF0IGFueSBnZW5lcmF0ZWQge0BsaW5rcGxhaW4KICAgICAqIEZpbGVyI2NyZWF0ZVNvdXJjZUZpbGUgc291cmNlfSBhbmQge0BsaW5rcGxhaW4KICAgICAqIEZpbGVyI2NyZWF0ZUNsYXNzRmlsZSBjbGFzc30gZmlsZXMgc2hvdWxkIGNvbmZvcm0gdG8uCiAgICAgKgogICAgICogQHJldHVybiB0aGUgc291cmNlIHZlcnNpb24gdG8gd2hpY2ggZ2VuZXJhdGVkIHNvdXJjZSBhbmQgY2xhc3MKICAgICAqICAgICAgICAgZmlsZXMgc2hvdWxkIGNvbmZvcm0gdG8KICAgICAqIEBzZWUgUHJvY2Vzc29yI2dldFN1cHBvcnRlZFNvdXJjZVZlcnNpb24KICAgICAqLwogICAgU291cmNlVmVyc2lvbiBnZXRTb3VyY2VWZXJzaW9uKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBjdXJyZW50IGxvY2FsZSBvciB7QGNvZGUgbnVsbH0gaWYgbm8gbG9jYWxlIGlzIGluCiAgICAgKiBlZmZlY3QuICBUaGUgbG9jYWxlIGNhbiBiZSBiZSB1c2VkIHRvIHByb3ZpZGUgbG9jYWxpemVkCiAgICAgKiB7QGxpbmtwbGFpbiBNZXNzYWdlciBtZXNzYWdlc30uCiAgICAgKgogICAgICogQHJldHVybiB0aGUgY3VycmVudCBsb2NhbGUgb3Ige0Bjb2RlIG51bGx9IGlmIG5vIGxvY2FsZSBpcyBpbgogICAgICogZWZmZWN0CiAgICAgKi8KICAgIExvY2FsZSBnZXRMb2NhbGUoKTsKfQpQSwMECgAACAAA0n1NSpwWHCBaBwAAWgcAACsAAABqYXZheC9hbm5vdGF0aW9uL3Byb2Nlc3NpbmcvQ29tcGxldGlvbi5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDA2LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGphdmF4LmFubm90YXRpb24ucHJvY2Vzc2luZzsKCi8qKgogKiBBIHN1Z2dlc3RlZCB7QGxpbmtwbGFpbiBQcm9jZXNzb3IjZ2V0Q29tcGxldGlvbnMgPGVtPmNvbXBsZXRpb248L2VtPn0gZm9yIGFuCiAqIGFubm90YXRpb24uICBBIGNvbXBsZXRpb24gaXMgdGV4dCBtZWFudCB0byBiZSBpbnNlcnRlZCBpbnRvIGEKICogcHJvZ3JhbSBhcyBwYXJ0IG9mIGFuIGFubm90YXRpb24uCiAqCiAqIEBhdXRob3IgSm9zZXBoIEQuIERhcmN5CiAqIEBhdXRob3IgU2NvdHQgU2VsaWdtYW4KICogQGF1dGhvciBQZXRlciB2b24gZGVyIEFoJmVhY3V0ZTsKICogQHNpbmNlIDEuNgogKi8KcHVibGljIGludGVyZmFjZSBDb21wbGV0aW9uIHsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHRleHQgb2YgdGhlIHN1Z2dlc3RlZCBjb21wbGV0aW9uLgogICAgICogQHJldHVybiB0aGUgdGV4dCBvZiB0aGUgc3VnZ2VzdGVkIGNvbXBsZXRpb24uCiAgICAgKi8KICAgIFN0cmluZyBnZXRWYWx1ZSgpOwoKICAgIC8qKgogICAgICogUmV0dXJucyBhbiBpbmZvcm1hdGl2ZSBtZXNzYWdlIGFib3V0IHRoZSBjb21wbGV0aW9uLgogICAgICogQHJldHVybiBhbiBpbmZvcm1hdGl2ZSBtZXNzYWdlIGFib3V0IHRoZSBjb21wbGV0aW9uLgogICAgICovCiAgICBTdHJpbmcgZ2V0TWVzc2FnZSgpOwp9ClBLAwQKAAAIAADSfU1KKdj26HIIAAByCAAAOQAAAGphdmF4L2Fubm90YXRpb24vcHJvY2Vzc2luZy9TdXBwb3J0ZWRBbm5vdGF0aW9uVHlwZXMuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAxMywgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBqYXZheC5hbm5vdGF0aW9uLnByb2Nlc3Npbmc7CgppbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uKjsKaW1wb3J0IHN0YXRpYyBqYXZhLmxhbmcuYW5ub3RhdGlvbi5SZXRlbnRpb25Qb2xpY3kuKjsKaW1wb3J0IHN0YXRpYyBqYXZhLmxhbmcuYW5ub3RhdGlvbi5FbGVtZW50VHlwZS4qOwoKLyoqCiAqIEFuIGFubm90YXRpb24gdXNlZCB0byBpbmRpY2F0ZSB3aGF0IGFubm90YXRpb24gdHlwZXMgYW4gYW5ub3RhdGlvbgogKiBwcm9jZXNzb3Igc3VwcG9ydHMuICBUaGUge0BsaW5rCiAqIFByb2Nlc3NvciNnZXRTdXBwb3J0ZWRBbm5vdGF0aW9uVHlwZXN9IG1ldGhvZCBjYW4gY29uc3RydWN0IGl0cwogKiByZXN1bHQgZnJvbSB0aGUgdmFsdWUgb2YgdGhpcyBhbm5vdGF0aW9uLCBhcyBkb25lIGJ5IHtAbGluawogKiBBYnN0cmFjdFByb2Nlc3NvciNnZXRTdXBwb3J0ZWRBbm5vdGF0aW9uVHlwZXN9LiAgT25seSB7QGxpbmtwbGFpbgogKiBQcm9jZXNzb3IjZ2V0U3VwcG9ydGVkQW5ub3RhdGlvblR5cGVzIHN0cmluZ3MgY29uZm9ybWluZyB0byB0aGUKICogZ3JhbW1hcn0gc2hvdWxkIGJlIHVzZWQgYXMgdmFsdWVzLgogKgogKiBAYXV0aG9yIEpvc2VwaCBELiBEYXJjeQogKiBAYXV0aG9yIFNjb3R0IFNlbGlnbWFuCiAqIEBhdXRob3IgUGV0ZXIgdm9uIGRlciBBaCZlYWN1dGU7CiAqIEBzaW5jZSAxLjYKICovCkBEb2N1bWVudGVkCkBUYXJnZXQoVFlQRSkKQFJldGVudGlvbihSVU5USU1FKQpwdWJsaWMgQGludGVyZmFjZSBTdXBwb3J0ZWRBbm5vdGF0aW9uVHlwZXMgewogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBuYW1lcyBvZiB0aGUgc3VwcG9ydGVkIGFubm90YXRpb24gdHlwZXMuCiAgICAgKiBAcmV0dXJuIHRoZSBuYW1lcyBvZiB0aGUgc3VwcG9ydGVkIGFubm90YXRpb24gdHlwZXMKICAgICAqLwogICAgU3RyaW5nIFtdIHZhbHVlKCk7Cn0KUEsDBAoAAAgAANJ9TUrYZZ1QGggAABoIAAAxAAAAamF2YXgvYW5ub3RhdGlvbi9wcm9jZXNzaW5nL1N1cHBvcnRlZE9wdGlvbnMuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAxMywgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBqYXZheC5hbm5vdGF0aW9uLnByb2Nlc3Npbmc7CgppbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uKjsKaW1wb3J0IHN0YXRpYyBqYXZhLmxhbmcuYW5ub3RhdGlvbi5SZXRlbnRpb25Qb2xpY3kuKjsKaW1wb3J0IHN0YXRpYyBqYXZhLmxhbmcuYW5ub3RhdGlvbi5FbGVtZW50VHlwZS4qOwoKLyoqCiAqIEFuIGFubm90YXRpb24gdXNlZCB0byBpbmRpY2F0ZSB3aGF0IG9wdGlvbnMgYW4gYW5ub3RhdGlvbiBwcm9jZXNzb3IKICogc3VwcG9ydHMuICBUaGUge0BsaW5rIFByb2Nlc3NvciNnZXRTdXBwb3J0ZWRPcHRpb25zfSBtZXRob2QgY2FuCiAqIGNvbnN0cnVjdCBpdHMgcmVzdWx0IGZyb20gdGhlIHZhbHVlIG9mIHRoaXMgYW5ub3RhdGlvbiwgYXMgZG9uZSBieQogKiB7QGxpbmsgQWJzdHJhY3RQcm9jZXNzb3IjZ2V0U3VwcG9ydGVkT3B0aW9uc30uICBPbmx5IHtAbGlua3BsYWluCiAqIFByb2Nlc3NvciNnZXRTdXBwb3J0ZWRPcHRpb25zIHN0cmluZ3MgY29uZm9ybWluZyB0byB0aGUKICogZ3JhbW1hcn0gc2hvdWxkIGJlIHVzZWQgYXMgdmFsdWVzLgogKgogKiBAYXV0aG9yIEpvc2VwaCBELiBEYXJjeQogKiBAYXV0aG9yIFNjb3R0IFNlbGlnbWFuCiAqIEBhdXRob3IgUGV0ZXIgdm9uIGRlciBBaCZlYWN1dGU7CiAqIEBzaW5jZSAxLjYKICovCkBEb2N1bWVudGVkCkBUYXJnZXQoVFlQRSkKQFJldGVudGlvbihSVU5USU1FKQpwdWJsaWMgQGludGVyZmFjZSBTdXBwb3J0ZWRPcHRpb25zIHsKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgc3VwcG9ydGVkIG9wdGlvbnMuCiAgICAgKiBAcmV0dXJuIHRoZSBzdXBwb3J0ZWQgb3B0aW9ucwogICAgICovCiAgICBTdHJpbmcgW10gdmFsdWUoKTsKfQpQSwMECgAACAAABjupSh9WXDYaUgAAGlIAACoAAABqYXZheC9hbm5vdGF0aW9uL3Byb2Nlc3NpbmcvUHJvY2Vzc29yLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMTcsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgamF2YXguYW5ub3RhdGlvbi5wcm9jZXNzaW5nOwoKaW1wb3J0IGphdmEudXRpbC5TZXQ7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLnV0aWwuRWxlbWVudHM7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLkFubm90YXRlZENvbnN0cnVjdDsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC4qOwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5Tb3VyY2VWZXJzaW9uOwoKLyoqCiAqIFRoZSBpbnRlcmZhY2UgZm9yIGFuIGFubm90YXRpb24gcHJvY2Vzc29yLgogKgogKiA8cD5Bbm5vdGF0aW9uIHByb2Nlc3NpbmcgaGFwcGVucyBpbiBhIHNlcXVlbmNlIG9mIHtAbGlua3BsYWluCiAqIGphdmF4LmFubm90YXRpb24ucHJvY2Vzc2luZy5Sb3VuZEVudmlyb25tZW50IHJvdW5kc30uICBPbiBlYWNoCiAqIHJvdW5kLCBhIHByb2Nlc3NvciBtYXkgYmUgYXNrZWQgdG8ge0BsaW5rcGxhaW4gI3Byb2Nlc3MgcHJvY2Vzc30gYQogKiBzdWJzZXQgb2YgdGhlIGFubm90YXRpb25zIGZvdW5kIG9uIHRoZSBzb3VyY2UgYW5kIGNsYXNzIGZpbGVzCiAqIHByb2R1Y2VkIGJ5IGEgcHJpb3Igcm91bmQuICBUaGUgaW5wdXRzIHRvIHRoZSBmaXJzdCByb3VuZCBvZgogKiBwcm9jZXNzaW5nIGFyZSB0aGUgaW5pdGlhbCBpbnB1dHMgdG8gYSBydW4gb2YgdGhlIHRvb2w7IHRoZXNlCiAqIGluaXRpYWwgaW5wdXRzIGNhbiBiZSByZWdhcmRlZCBhcyB0aGUgb3V0cHV0IG9mIGEgdmlydHVhbCB6ZXJvdGgKICogcm91bmQgb2YgcHJvY2Vzc2luZy4gIElmIGEgcHJvY2Vzc29yIHdhcyBhc2tlZCB0byBwcm9jZXNzIG9uIGEKICogZ2l2ZW4gcm91bmQsIGl0IHdpbGwgYmUgYXNrZWQgdG8gcHJvY2VzcyBvbiBzdWJzZXF1ZW50IHJvdW5kcywKICogaW5jbHVkaW5nIHRoZSBsYXN0IHJvdW5kLCBldmVuIGlmIHRoZXJlIGFyZSBubyBhbm5vdGF0aW9ucyBmb3IgaXQKICogdG8gcHJvY2Vzcy4gIFRoZSB0b29sIGluZnJhc3RydWN0dXJlIG1heSBhbHNvIGFzayBhIHByb2Nlc3NvciB0bwogKiBwcm9jZXNzIGZpbGVzIGdlbmVyYXRlZCBpbXBsaWNpdGx5IGJ5IHRoZSB0b29sJ3Mgb3BlcmF0aW9uLgogKgogKiA8cD4gRWFjaCBpbXBsZW1lbnRhdGlvbiBvZiBhIHtAY29kZSBQcm9jZXNzb3J9IG11c3QgcHJvdmlkZSBhCiAqIHB1YmxpYyBuby1hcmd1bWVudCBjb25zdHJ1Y3RvciB0byBiZSB1c2VkIGJ5IHRvb2xzIHRvIGluc3RhbnRpYXRlCiAqIHRoZSBwcm9jZXNzb3IuICBUaGUgdG9vbCBpbmZyYXN0cnVjdHVyZSB3aWxsIGludGVyYWN0IHdpdGggY2xhc3NlcwogKiBpbXBsZW1lbnRpbmcgdGhpcyBpbnRlcmZhY2UgYXMgZm9sbG93czoKICoKICogPG9sPgogKgogKiA8bGk+SWYgYW4gZXhpc3Rpbmcge0Bjb2RlIFByb2Nlc3Nvcn0gb2JqZWN0IGlzIG5vdCBiZWluZyB1c2VkLCB0bwogKiBjcmVhdGUgYW4gaW5zdGFuY2Ugb2YgYSBwcm9jZXNzb3IgdGhlIHRvb2wgY2FsbHMgdGhlIG5vLWFyZwogKiBjb25zdHJ1Y3RvciBvZiB0aGUgcHJvY2Vzc29yIGNsYXNzLgogKgogKiA8bGk+TmV4dCwgdGhlIHRvb2wgY2FsbHMgdGhlIHtAbGluayAjaW5pdCBpbml0fSBtZXRob2Qgd2l0aAogKiBhbiBhcHByb3ByaWF0ZSB7QGNvZGUgUHJvY2Vzc2luZ0Vudmlyb25tZW50fS4KICoKICogPGxpPkFmdGVyd2FyZHMsIHRoZSB0b29sIGNhbGxzIHtAbGluayAjZ2V0U3VwcG9ydGVkQW5ub3RhdGlvblR5cGVzCiAqIGdldFN1cHBvcnRlZEFubm90YXRpb25UeXBlc30sIHtAbGluayAjZ2V0U3VwcG9ydGVkT3B0aW9ucwogKiBnZXRTdXBwb3J0ZWRPcHRpb25zfSwgYW5kIHtAbGluayAjZ2V0U3VwcG9ydGVkU291cmNlVmVyc2lvbgogKiBnZXRTdXBwb3J0ZWRTb3VyY2VWZXJzaW9ufS4gIFRoZXNlIG1ldGhvZHMgYXJlIG9ubHkgY2FsbGVkIG9uY2UgcGVyCiAqIHJ1biwgbm90IG9uIGVhY2ggcm91bmQuCiAqCiAqIDxsaT5BcyBhcHByb3ByaWF0ZSwgdGhlIHRvb2wgY2FsbHMgdGhlIHtAbGluayAjcHJvY2VzcyBwcm9jZXNzfQogKiBtZXRob2Qgb24gdGhlIHtAY29kZSBQcm9jZXNzb3J9IG9iamVjdDsgYSBuZXcge0Bjb2RlIFByb2Nlc3Nvcn0KICogb2JqZWN0IGlzIDxlbT5ub3Q8L2VtPiBjcmVhdGVkIGZvciBlYWNoIHJvdW5kLgogKgogKiA8L29sPgogKgogKiBJZiBhIHByb2Nlc3NvciBvYmplY3QgaXMgY3JlYXRlZCBhbmQgdXNlZCB3aXRob3V0IHRoZSBhYm92ZQogKiBwcm90b2NvbCBiZWluZyBmb2xsb3dlZCwgdGhlbiB0aGUgcHJvY2Vzc29yJ3MgYmVoYXZpb3IgaXMgbm90CiAqIGRlZmluZWQgYnkgdGhpcyBpbnRlcmZhY2Ugc3BlY2lmaWNhdGlvbi4KICoKICogPHA+IFRoZSB0b29sIHVzZXMgYSA8aT5kaXNjb3ZlcnkgcHJvY2VzczwvaT4gdG8gZmluZCBhbm5vdGF0aW9uCiAqIHByb2Nlc3NvcnMgYW5kIGRlY2lkZSB3aGV0aGVyIG9yIG5vdCB0aGV5IHNob3VsZCBiZSBydW4uICBCeQogKiBjb25maWd1cmluZyB0aGUgdG9vbCwgdGhlIHNldCBvZiBwb3RlbnRpYWwgcHJvY2Vzc29ycyBjYW4gYmUKICogY29udHJvbGxlZC4gIEZvciBleGFtcGxlLCBmb3IgYSB7QGxpbmsgamF2YXgudG9vbHMuSmF2YUNvbXBpbGVyCiAqIEphdmFDb21waWxlcn0gdGhlIGxpc3Qgb2YgY2FuZGlkYXRlIHByb2Nlc3NvcnMgdG8gcnVuIGNhbiBiZQogKiB7QGxpbmtwbGFpbiBqYXZheC50b29scy5KYXZhQ29tcGlsZXIuQ29tcGlsYXRpb25UYXNrI3NldFByb2Nlc3NvcnMKICogc2V0IGRpcmVjdGx5fSBvciBjb250cm9sbGVkIGJ5IGEge0BsaW5rcGxhaW4KICogamF2YXgudG9vbHMuU3RhbmRhcmRMb2NhdGlvbiNBTk5PVEFUSU9OX1BST0NFU1NPUl9QQVRIIHNlYXJjaCBwYXRofQogKiB1c2VkIGZvciBhIHtAbGlua3BsYWluIGphdmEudXRpbC5TZXJ2aWNlTG9hZGVyIHNlcnZpY2Utc3R5bGV9CiAqIGxvb2t1cC4gIE90aGVyIHRvb2wgaW1wbGVtZW50YXRpb25zIG1heSBoYXZlIGRpZmZlcmVudAogKiBjb25maWd1cmF0aW9uIG1lY2hhbmlzbXMsIHN1Y2ggYXMgY29tbWFuZCBsaW5lIG9wdGlvbnM7IGZvcgogKiBkZXRhaWxzLCByZWZlciB0byB0aGUgcGFydGljdWxhciB0b29sJ3MgZG9jdW1lbnRhdGlvbi4gIFdoaWNoCiAqIHByb2Nlc3NvcnMgdGhlIHRvb2wgYXNrcyB0byB7QGxpbmtwbGFpbiAjcHJvY2VzcyBydW59IGlzIGEgZnVuY3Rpb24KICogb2YgdGhlIHR5cGVzIG9mIHRoZSBhbm5vdGF0aW9ucyA8ZW0+e0BsaW5rcGxhaW4gQW5ub3RhdGVkQ29uc3RydWN0IHByZXNlbnR9PC9lbT4KICogb24gdGhlIHtAbGlua3BsYWluCiAqIFJvdW5kRW52aXJvbm1lbnQjZ2V0Um9vdEVsZW1lbnRzIHJvb3QgZWxlbWVudHN9LCB3aGF0IHtAbGlua3BsYWluCiAqICNnZXRTdXBwb3J0ZWRBbm5vdGF0aW9uVHlwZXMgYW5ub3RhdGlvbiB0eXBlcyBhIHByb2Nlc3NvcgogKiBzdXBwb3J0c30sIGFuZCB3aGV0aGVyIG9yIG5vdCBhIHByb2Nlc3NvciB7QGxpbmtwbGFpbiAjcHJvY2VzcwogKiBjbGFpbXMgdGhlIGFubm90YXRpb24gdHlwZXMgaXQgcHJvY2Vzc2VzfS4gIEEgcHJvY2Vzc29yIHdpbGwgYmUgYXNrZWQgdG8KICogcHJvY2VzcyBhIHN1YnNldCBvZiB0aGUgYW5ub3RhdGlvbiB0eXBlcyBpdCBzdXBwb3J0cywgcG9zc2libHkgYW4KICogZW1wdHkgc2V0LgogKgogKiBGb3IgYSBnaXZlbiByb3VuZCwgdGhlIHRvb2wgY29tcHV0ZXMgdGhlIHNldCBvZiBhbm5vdGF0aW9uIHR5cGVzCiAqIHRoYXQgYXJlIHByZXNlbnQgb24gdGhlIGVsZW1lbnRzIGVuY2xvc2VkIHdpdGhpbiB0aGUgcm9vdCBlbGVtZW50cy4KICogSWYgdGhlcmUgaXMgYXQgbGVhc3Qgb25lIGFubm90YXRpb24gdHlwZSBwcmVzZW50LCB0aGVuIGFzCiAqIHByb2Nlc3NvcnMgY2xhaW0gYW5ub3RhdGlvbiB0eXBlcywgdGhleSBhcmUgcmVtb3ZlZCBmcm9tIHRoZSBzZXQgb2YKICogdW5tYXRjaGVkIGFubm90YXRpb24gdHlwZXMuICBXaGVuIHRoZSBzZXQgaXMgZW1wdHkgb3Igbm8gbW9yZQogKiBwcm9jZXNzb3JzIGFyZSBhdmFpbGFibGUsIHRoZSByb3VuZCBoYXMgcnVuIHRvIGNvbXBsZXRpb24uICBJZgogKiB0aGVyZSBhcmUgbm8gYW5ub3RhdGlvbiB0eXBlcyBwcmVzZW50LCBhbm5vdGF0aW9uIHByb2Nlc3Npbmcgc3RpbGwKICogb2NjdXJzIGJ1dCBvbmx5IDxpPnVuaXZlcnNhbCBwcm9jZXNzb3JzPC9pPiB3aGljaCBzdXBwb3J0CiAqIHByb2Nlc3NpbmcgYWxsIGFubm90YXRpb24gdHlwZXMsIHtAY29kZSAiKiJ9LCBjYW4gY2xhaW0gdGhlIChlbXB0eSkKICogc2V0IG9mIGFubm90YXRpb24gdHlwZXMuCiAqCiAqIDxwPkFuIGFubm90YXRpb24gdHlwZSBpcyBjb25zaWRlcmVkIHByZXNlbnQgaWYgdGhlcmUgaXMgYXQgbGVhc3QKICogb25lIGFubm90YXRpb24gb2YgdGhhdCB0eXBlIHByZXNlbnQgb24gYW4gZWxlbWVudCBlbmNsb3NlZCB3aXRoaW4KICogdGhlIHJvb3QgZWxlbWVudHMgb2YgYSByb3VuZC4gRm9yIHRoaXMgcHVycG9zZSwgYSB0eXBlIHBhcmFtZXRlciBpcwogKiBjb25zaWRlcmVkIHRvIGJlIGVuY2xvc2VkIGJ5IGl0cyB7QGxpbmtwbGFpbgogKiBUeXBlUGFyYW1ldGVyRWxlbWVudCNnZXRHZW5lcmljRWxlbWVudCBnZW5lcmljCiAqIGVsZW1lbnR9LgoKICogRm9yIHRoaXMgcHVycG9zZSwgYSBwYWNrYWdlIGVsZW1lbnQgaXMgPGVtPm5vdDwvZW0+IGNvbnNpZGVyZWQgdG8KICogZW5jbG9zZSB0aGUgdG9wLWxldmVsIHR5cGVzIHdpdGhpbiB0aGF0IHBhY2thZ2UuIChBIHJvb3QgZWxlbWVudAogKiByZXByZXNlbnRpbmcgYSBwYWNrYWdlIGlzIGNyZWF0ZWQgd2hlbiBhIHtAY29kZSBwYWNrYWdlLWluZm99IGZpbGUKICogaXMgcHJvY2Vzc2VkLikgTGlrZXdpc2UsIGZvciB0aGlzIHB1cnBvc2UsIGEgbW9kdWxlIGVsZW1lbnQgaXMKICogPGVtPm5vdDwvZW0+IGNvbnNpZGVyZWQgdG8gZW5jbG9zZSB0aGUgcGFja2FnZXMgd2l0aGluIHRoYXQKICogbW9kdWxlLiAoQSByb290IGVsZW1lbnQgcmVwcmVzZW50aW5nIGEgbW9kdWxlIGlzIGNyZWF0ZWQgd2hlbiBhCiAqIHtAY29kZSBtb2R1bGUtaW5mb30gZmlsZSBpcyBwcm9jZXNzZWQuKQogKgogKiBBbm5vdGF0aW9ucyBvbiB7QGxpbmtwbGFpbgogKiBqYXZhLmxhbmcuYW5ub3RhdGlvbi5FbGVtZW50VHlwZSNUWVBFX1VTRSB0eXBlIHVzZXN9LCBhcyBvcHBvc2VkIHRvCiAqIGFubm90YXRpb25zIG9uIGVsZW1lbnRzLCBhcmUgaWdub3JlZCB3aGVuIGNvbXB1dGluZyB3aGV0aGVyIG9yIG5vdAogKiBhbiBhbm5vdGF0aW9uIHR5cGUgaXMgcHJlc2VudC4KICoKICogPHA+QW4gYW5ub3RhdGlvbiBpcyBwcmVzZW50IGlmIGl0IG1lZXRzIHRoZSBkZWZpbml0aW9uIG9mIGJlaW5nCiAqIHByZXNlbnQgZ2l2ZW4gaW4ge0BsaW5rIEFubm90YXRlZENvbnN0cnVjdH0uIEluIGJyaWVmLCBhbgogKiBhbm5vdGF0aW9uIGlzIGNvbnNpZGVyZWQgcHJlc2VudCBmb3IgdGhlIHB1cnBvc2VzIG9mIGRpc2NvdmVyeSBpZgogKiBpdCBpcyBkaXJlY3RseSBwcmVzZW50IG9yIHByZXNlbnQgdmlhIGluaGVyaXRhbmNlLiBBbiBhbm5vdGF0aW9uIGlzCiAqIDxlbT5ub3Q8L2VtPiBjb25zaWRlcmVkIHByZXNlbnQgYnkgdmlydHVlIG9mIGJlaW5nIHdyYXBwZWQgYnkgYQogKiBjb250YWluZXIgYW5ub3RhdGlvbi4gT3BlcmF0aW9uYWxseSwgdGhpcyBpcyBlcXVpdmFsZW50IHRvIGFuCiAqIGFubm90YXRpb24gYmVpbmcgcHJlc2VudCBvbiBhbiBlbGVtZW50IGlmIGFuZCBvbmx5IGlmIGl0IHdvdWxkIGJlCiAqIGluY2x1ZGVkIGluIHRoZSByZXN1bHRzIG9mIHtAbGluawogKiBFbGVtZW50cyNnZXRBbGxBbm5vdGF0aW9uTWlycm9ycyhFbGVtZW50KX0gY2FsbGVkIG9uIHRoYXQgZWxlbWVudC4gU2luY2UKICogYW5ub3RhdGlvbnMgaW5zaWRlIGNvbnRhaW5lciBhbm5vdGF0aW9ucyBhcmUgbm90IGNvbnNpZGVyZWQKICogcHJlc2VudCwgdG8gcHJvcGVybHkgcHJvY2VzcyB7QGxpbmtwbGFpbgogKiBqYXZhLmxhbmcuYW5ub3RhdGlvbi5SZXBlYXRhYmxlIHJlcGVhdGFibGUgYW5ub3RhdGlvbiB0eXBlc30sCiAqIHByb2Nlc3NvcnMgYXJlIGFkdmlzZWQgdG8gaW5jbHVkZSBib3RoIHRoZSByZXBlYXRhYmxlIGFubm90YXRpb24KICogdHlwZSBhbmQgaXRzIGNvbnRhaW5pbmcgYW5ub3RhdGlvbiB0eXBlIGluIHRoZSBzZXQgb2Yge0BsaW5rcGxhaW4KICogI2dldFN1cHBvcnRlZEFubm90YXRpb25UeXBlcygpIHN1cHBvcnRlZCBhbm5vdGF0aW9uIHR5cGVzfSBvZiBhCiAqIHByb2Nlc3Nvci4KICoKICogPHA+Tm90ZSB0aGF0IGlmIGEgcHJvY2Vzc29yIHN1cHBvcnRzIHtAY29kZSAiKiJ9IGFuZCByZXR1cm5zIHtAY29kZQogKiB0cnVlfSwgYWxsIGFubm90YXRpb25zIGFyZSBjbGFpbWVkLiAgVGhlcmVmb3JlLCBhIHVuaXZlcnNhbAogKiBwcm9jZXNzb3IgYmVpbmcgdXNlZCB0bywgZm9yIGV4YW1wbGUsIGltcGxlbWVudCBhZGRpdGlvbmFsIHZhbGlkaXR5CiAqIGNoZWNrcyBzaG91bGQgcmV0dXJuIHtAY29kZSBmYWxzZX0gc28gYXMgdG8gbm90IHByZXZlbnQgb3RoZXIgc3VjaAogKiBjaGVja2VycyBmcm9tIGJlaW5nIGFibGUgdG8gcnVuLgogKgogKiA8cD5JZiBhIHByb2Nlc3NvciB0aHJvd3MgYW4gdW5jYXVnaHQgZXhjZXB0aW9uLCB0aGUgdG9vbCBtYXkgY2Vhc2UKICogb3RoZXIgYWN0aXZlIGFubm90YXRpb24gcHJvY2Vzc29ycy4gIElmIGEgcHJvY2Vzc29yIHJhaXNlcyBhbgogKiBlcnJvciwgdGhlIGN1cnJlbnQgcm91bmQgd2lsbCBydW4gdG8gY29tcGxldGlvbiBhbmQgdGhlIHN1YnNlcXVlbnQKICogcm91bmQgd2lsbCBpbmRpY2F0ZSBhbiB7QGxpbmtwbGFpbiBSb3VuZEVudmlyb25tZW50I2Vycm9yUmFpc2VkCiAqIGVycm9yIHdhcyByYWlzZWR9LiAgU2luY2UgYW5ub3RhdGlvbiBwcm9jZXNzb3JzIGFyZSBydW4gaW4gYQogKiBjb29wZXJhdGl2ZSBlbnZpcm9ubWVudCwgYSBwcm9jZXNzb3Igc2hvdWxkIHRocm93IGFuIHVuY2F1Z2h0CiAqIGV4Y2VwdGlvbiBvbmx5IGluIHNpdHVhdGlvbnMgd2hlcmUgbm8gZXJyb3IgcmVjb3Zlcnkgb3IgcmVwb3J0aW5nCiAqIGlzIGZlYXNpYmxlLgogKgogKiA8cD5UaGUgdG9vbCBlbnZpcm9ubWVudCBpcyBub3QgcmVxdWlyZWQgdG8gc3VwcG9ydCBhbm5vdGF0aW9uCiAqIHByb2Nlc3NvcnMgdGhhdCBhY2Nlc3MgZW52aXJvbm1lbnRhbCByZXNvdXJjZXMsIGVpdGhlciB7QGxpbmtwbGFpbgogKiBSb3VuZEVudmlyb25tZW50IHBlciByb3VuZH0gb3Ige0BsaW5rcGxhaW4gUHJvY2Vzc2luZ0Vudmlyb25tZW50CiAqIGNyb3NzLXJvdW5kfSwgaW4gYSBtdWx0aS10aHJlYWRlZCBmYXNoaW9uLgogKgogKiA8cD5JZiB0aGUgbWV0aG9kcyB0aGF0IHJldHVybiBjb25maWd1cmF0aW9uIGluZm9ybWF0aW9uIGFib3V0IHRoZQogKiBhbm5vdGF0aW9uIHByb2Nlc3NvciByZXR1cm4ge0Bjb2RlIG51bGx9LCByZXR1cm4gb3RoZXIgaW52YWxpZAogKiBpbnB1dCwgb3IgdGhyb3cgYW4gZXhjZXB0aW9uLCB0aGUgdG9vbCBpbmZyYXN0cnVjdHVyZSBtdXN0IHRyZWF0CiAqIHRoaXMgYXMgYW4gZXJyb3IgY29uZGl0aW9uLgogKgogKiA8cD5UbyBiZSByb2J1c3Qgd2hlbiBydW5uaW5nIGluIGRpZmZlcmVudCB0b29sIGltcGxlbWVudGF0aW9ucywgYW4KICogYW5ub3RhdGlvbiBwcm9jZXNzb3Igc2hvdWxkIGhhdmUgdGhlIGZvbGxvd2luZyBwcm9wZXJ0aWVzOgogKgogKiA8b2w+CiAqCiAqIDxsaT5UaGUgcmVzdWx0IG9mIHByb2Nlc3NpbmcgYSBnaXZlbiBpbnB1dCBpcyBub3QgYSBmdW5jdGlvbiBvZiB0aGUgcHJlc2VuY2Ugb3IgYWJzZW5jZQogKiBvZiBvdGhlciBpbnB1dHMgKG9ydGhvZ29uYWxpdHkpLgogKgogKiA8bGk+UHJvY2Vzc2luZyB0aGUgc2FtZSBpbnB1dCBwcm9kdWNlcyB0aGUgc2FtZSBvdXRwdXQgKGNvbnNpc3RlbmN5KS4KICoKICogPGxpPlByb2Nlc3NpbmcgaW5wdXQgPGk+QTwvaT4gZm9sbG93ZWQgYnkgcHJvY2Vzc2luZyBpbnB1dCA8aT5CPC9pPgogKiBpcyBlcXVpdmFsZW50IHRvIHByb2Nlc3NpbmcgPGk+QjwvaT4gdGhlbiA8aT5BPC9pPgogKiAoY29tbXV0YXRpdml0eSkKICoKICogPGxpPlByb2Nlc3NpbmcgYW4gaW5wdXQgZG9lcyBub3QgcmVseSBvbiB0aGUgcHJlc2VuY2Ugb2YgdGhlIG91dHB1dAogKiBvZiBvdGhlciBhbm5vdGF0aW9uIHByb2Nlc3NvcnMgKGluZGVwZW5kZW5jZSkKICoKICogPC9vbD4KICoKICogPHA+VGhlIHtAbGluayBGaWxlcn0gaW50ZXJmYWNlIGRpc2N1c3NlcyByZXN0cmljdGlvbnMgb24gaG93CiAqIHByb2Nlc3NvcnMgY2FuIG9wZXJhdGUgb24gZmlsZXMuCiAqCiAqIEBhcGlOb3RlIEltcGxlbWVudG9ycyBvZiB0aGlzIGludGVyZmFjZSBtYXkgZmluZCBpdCBjb252ZW5pZW50CiAqIHRvIGV4dGVuZCB7QGxpbmsgQWJzdHJhY3RQcm9jZXNzb3J9IHJhdGhlciB0aGFuIGltcGxlbWVudGluZyB0aGlzCiAqIGludGVyZmFjZSBkaXJlY3RseS4KICoKICogQGF1dGhvciBKb3NlcGggRC4gRGFyY3kKICogQGF1dGhvciBTY290dCBTZWxpZ21hbgogKiBAYXV0aG9yIFBldGVyIHZvbiBkZXIgQWgmZWFjdXRlOwogKiBAc2luY2UgMS42CiAqLwpwdWJsaWMgaW50ZXJmYWNlIFByb2Nlc3NvciB7CiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIG9wdGlvbnMgcmVjb2duaXplZCBieSB0aGlzIHByb2Nlc3Nvci4gIEFuCiAgICAgKiBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgcHJvY2Vzc2luZyB0b29sIG11c3QgcHJvdmlkZSBhIHdheSB0bwogICAgICogcGFzcyBwcm9jZXNzb3Itc3BlY2lmaWMgb3B0aW9ucyBkaXN0aW5jdGx5IGZyb20gb3B0aW9ucyBwYXNzZWQKICAgICAqIHRvIHRoZSB0b29sIGl0c2VsZiwgc2VlIHtAbGluayBQcm9jZXNzaW5nRW52aXJvbm1lbnQjZ2V0T3B0aW9ucwogICAgICogZ2V0T3B0aW9uc30uCiAgICAgKgogICAgICogPHA+RWFjaCBzdHJpbmcgcmV0dXJuZWQgaW4gdGhlIHNldCBtdXN0IGJlIGEgcGVyaW9kIHNlcGFyYXRlZAogICAgICogc2VxdWVuY2Ugb2Yge0BsaW5rcGxhaW4KICAgICAqIGphdmF4LmxhbmcubW9kZWwuU291cmNlVmVyc2lvbiNpc0lkZW50aWZpZXIgaWRlbnRpZmllcnN9OgogICAgICoKICAgICAqIDxibG9ja3F1b3RlPgogICAgICogPGRsPgogICAgICogPGR0PjxpPlN1cHBvcnRlZE9wdGlvblN0cmluZzo8L2k+CiAgICAgKiA8ZGQ+PGk+SWRlbnRpZmllcnM8L2k+CiAgICAgKgogICAgICogPGR0PjxpPklkZW50aWZpZXJzOjwvaT4KICAgICAqIDxkZD4gPGk+SWRlbnRpZmllcjwvaT4KICAgICAqIDxkZD4gPGk+SWRlbnRpZmllcjwvaT4ge0Bjb2RlIC59IDxpPklkZW50aWZpZXJzPC9pPgogICAgICoKICAgICAqIDxkdD48aT5JZGVudGlmaWVyOjwvaT4KICAgICAqIDxkZD5TeW50YWN0aWMgaWRlbnRpZmllciwgaW5jbHVkaW5nIGtleXdvcmRzIGFuZCBsaXRlcmFscwogICAgICogPC9kbD4KICAgICAqIDwvYmxvY2txdW90ZT4KICAgICAqCiAgICAgKiA8cD4gQSB0b29sIG1pZ2h0IHVzZSB0aGlzIGluZm9ybWF0aW9uIHRvIGRldGVybWluZSBpZiBhbnkKICAgICAqIG9wdGlvbnMgcHJvdmlkZWQgYnkgYSB1c2VyIGFyZSB1bnJlY29nbml6ZWQgYnkgYW55IHByb2Nlc3NvciwKICAgICAqIGluIHdoaWNoIGNhc2UgaXQgbWF5IHdpc2ggdG8gcmVwb3J0IGEgd2FybmluZy4KICAgICAqCiAgICAgKiBAcmV0dXJuIHRoZSBvcHRpb25zIHJlY29nbml6ZWQgYnkgdGhpcyBwcm9jZXNzb3Igb3IgYW4KICAgICAqICAgICAgICAgZW1wdHkgY29sbGVjdGlvbiBpZiBub25lCiAgICAgKiBAc2VlIGphdmF4LmFubm90YXRpb24ucHJvY2Vzc2luZy5TdXBwb3J0ZWRPcHRpb25zCiAgICAgKi8KICAgIFNldDxTdHJpbmc+IGdldFN1cHBvcnRlZE9wdGlvbnMoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIG5hbWVzIG9mIHRoZSBhbm5vdGF0aW9uIHR5cGVzIHN1cHBvcnRlZCBieSB0aGlzCiAgICAgKiBwcm9jZXNzb3IuICBBbiBlbGVtZW50IG9mIHRoZSByZXN1bHQgbWF5IGJlIHRoZSBjYW5vbmljYWwKICAgICAqIChmdWxseSBxdWFsaWZpZWQpIG5hbWUgb2YgYSBzdXBwb3J0ZWQgYW5ub3RhdGlvbiB0eXBlLgogICAgICogQWx0ZXJuYXRlbHkgaXQgbWF5IGJlIG9mIHRoZSBmb3JtICZxdW90Ozxjb2RlPjxpPm5hbWU8L2k+Lio8L2NvZGU+JnF1b3Q7CiAgICAgKiByZXByZXNlbnRpbmcgdGhlIHNldCBvZiBhbGwgYW5ub3RhdGlvbiB0eXBlcyB3aXRoIGNhbm9uaWNhbAogICAgICogbmFtZXMgYmVnaW5uaW5nIHdpdGggJnF1b3Q7PGNvZGU+PGk+bmFtZS48L2k+PC9jb2RlPiZxdW90Oy4KICAgICAqCiAgICAgKiBJbiBlaXRoZXIgb2YgdGhvc2UgY2FzZXMsIHRoZSBuYW1lIG9mIHRoZSBhbm5vdGF0aW9uIHR5cGUgY2FuCiAgICAgKiBiZSBvcHRpb25hbGx5IHByZWNlZGVkIGJ5IGEgbW9kdWxlIG5hbWUgZm9sbG93ZWQgYnkgYSB7QGNvZGUKICAgICAqICIvIn0gY2hhcmFjdGVyLiBGb3IgZXhhbXBsZSwgaWYgYSBwcm9jZXNzb3Igc3VwcG9ydHMge0Bjb2RlCiAgICAgKiAiYS5CIn0sIHRoaXMgY2FuIGluY2x1ZGUgbXVsdGlwbGUgYW5ub3RhdGlvbiB0eXBlcyBuYW1lZCB7QGNvZGUKICAgICAqIGEuQn0gd2hpY2ggcmVzaWRlIGluIGRpZmZlcmVudCBtb2R1bGVzLiBUbyBvbmx5IHN1cHBvcnQge0Bjb2RlCiAgICAgKiBhLkJ9IGluIHRoZSB7QGNvZGUgRm9vfSBtb2R1bGUsIGluc3RlYWQgdXNlIHtAY29kZSAiRm9vL2EuQiJ9LgogICAgICoKICAgICAqIElmIGEgbW9kdWxlIG5hbWUgaXMgaW5jbHVkZWQsIG9ubHkgYW4gYW5ub3RhdGlvbiBpbiB0aGF0IG1vZHVsZQogICAgICogaXMgbWF0Y2hlZC4gSW4gcGFydGljdWxhciwgaWYgYSBtb2R1bGUgbmFtZSBpcyBnaXZlbiBpbiBhbgogICAgICogZW52aXJvbm1lbnQgd2hlcmUgbW9kdWxlcyBhcmUgbm90IHN1cHBvcnRlZCwgc3VjaCBhcyBhbgogICAgICogYW5ub3RhdGlvbiBwcm9jZXNzaW5nIGVudmlyb25tZW50IGNvbmZpZ3VyZWQgZm9yIGEge0BsaW5rcGxhaW4KICAgICAqIGphdmF4LmFubm90YXRpb24ucHJvY2Vzc2luZy5Qcm9jZXNzaW5nRW52aXJvbm1lbnQjZ2V0U291cmNlVmVyc2lvbgogICAgICogc291cmNlIHZlcnNpb259IHdpdGhvdXQgbW9kdWxlcywgdGhlbiB0aGUgYW5ub3RhdGlvbiB0eXBlcyB3aXRoCiAgICAgKiBhIG1vZHVsZSBuYW1lIGRvIDxlbT5ub3Q8L2VtPiBtYXRjaC4KICAgICAqCiAgICAgKiBGaW5hbGx5LCB7QGNvZGUgIioifSBieSBpdHNlbGYgcmVwcmVzZW50cyB0aGUgc2V0IG9mIGFsbAogICAgICogYW5ub3RhdGlvbiB0eXBlcywgaW5jbHVkaW5nIHRoZSBlbXB0eSBzZXQuICBOb3RlIHRoYXQgYQogICAgICogcHJvY2Vzc29yIHNob3VsZCBub3QgY2xhaW0ge0Bjb2RlICIqIn0gdW5sZXNzIGl0IGlzIGFjdHVhbGx5CiAgICAgKiBwcm9jZXNzaW5nIGFsbCBmaWxlczsgY2xhaW1pbmcgdW5uZWNlc3NhcnkgYW5ub3RhdGlvbnMgbWF5CiAgICAgKiBjYXVzZSBhIHBlcmZvcm1hbmNlIHNsb3dkb3duIGluIHNvbWUgZW52aXJvbm1lbnRzLgogICAgICoKICAgICAqIDxwPkVhY2ggc3RyaW5nIHJldHVybmVkIGluIHRoZSBzZXQgbXVzdCBiZSBhY2NlcHRlZCBieSB0aGUKICAgICAqIGZvbGxvd2luZyBncmFtbWFyOgogICAgICoKICAgICAqIDxibG9ja3F1b3RlPgogICAgICogPGRsPgogICAgICogPGR0PjxpPlN1cHBvcnRlZEFubm90YXRpb25UeXBlU3RyaW5nOjwvaT4KICAgICAqIDxkZD48aT5Nb2R1bGVQcmVmaXg8L2k+PHN1Yj48aT5vcHQ8L2k+PC9zdWI+IDxpPlR5cGVOYW1lPC9pPiA8aT5Eb3RTdGFyPC9pPjxzdWI+PGk+b3B0PC9pPjwvc3ViPgogICAgICogPGRkPjxjb2RlPio8L2NvZGU+CiAgICAgKgogICAgICogPGR0PjxpPk1vZHVsZVByZWZpeDo8L2k+CiAgICAgKiA8ZGQ+PGk+VHlwZU5hbWU8L2k+IDxjb2RlPi88L2NvZGU+CiAgICAgKgogICAgICogPGR0PjxpPkRvdFN0YXI6PC9pPgogICAgICogPGRkPjxjb2RlPi48L2NvZGU+IDxjb2RlPio8L2NvZGU+CiAgICAgKiA8L2RsPgogICAgICogPC9ibG9ja3F1b3RlPgogICAgICoKICAgICAqIHdoZXJlIDxpPlR5cGVOYW1lPC9pPiBpcyBhcyBkZWZpbmVkIGluCiAgICAgKiA8Y2l0ZT5UaGUgSmF2YSZ0cmFkZTsgTGFuZ3VhZ2UgU3BlY2lmaWNhdGlvbjwvY2l0ZT4uCiAgICAgKgogICAgICogQGFwaU5vdGUgV2hlbiBydW5uaW5nIGluIGFuIGVudmlyb25tZW50IHdoaWNoIHN1cHBvcnRzIG1vZHVsZXMsCiAgICAgKiBwcm9jZXNzb3JzIGFyZSBlbmNvdXJhZ2VkIHRvIGluY2x1ZGUgdGhlIG1vZHVsZSBwcmVmaXggd2hlbgogICAgICogZGVzY3JpYmluZyB0aGVpciBzdXBwb3J0ZWQgYW5ub3RhdGlvbiB0eXBlcy4gVGhlIG1ldGhvZCB7QGxpbmsKICAgICAqIEFic3RyYWN0UHJvY2Vzc29yI2dldFN1cHBvcnRlZEFubm90YXRpb25UeXBlcwogICAgICogQWJzdHJhY3RQcm9jZXNzb3IuZ2V0U3VwcG9ydGVkQW5ub3RhdGlvblR5cGVzfSBwcm92aWRlcyBzdXBwb3J0CiAgICAgKiBmb3Igc3RyaXBwaW5nIG9mZiB0aGUgbW9kdWxlIHByZWZpeCB3aGVuIHJ1bm5pbmcgaW4gYW4KICAgICAqIGVudmlyb25tZW50IHdpdGhvdXQgbW9kdWxlcy4KICAgICAqCiAgICAgKiBAcmV0dXJuIHRoZSBuYW1lcyBvZiB0aGUgYW5ub3RhdGlvbiB0eXBlcyBzdXBwb3J0ZWQgYnkgdGhpcyBwcm9jZXNzb3IKICAgICAqIEBzZWUgamF2YXguYW5ub3RhdGlvbi5wcm9jZXNzaW5nLlN1cHBvcnRlZEFubm90YXRpb25UeXBlcwogICAgICogQGpscyAzLjggSWRlbnRpZmllcnMKICAgICAqIEBqbHMgNi41LjUgTWVhbmluZyBvZiBUeXBlIE5hbWVzCiAgICAgKi8KICAgIFNldDxTdHJpbmc+IGdldFN1cHBvcnRlZEFubm90YXRpb25UeXBlcygpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgbGF0ZXN0IHNvdXJjZSB2ZXJzaW9uIHN1cHBvcnRlZCBieSB0aGlzIGFubm90YXRpb24KICAgICAqIHByb2Nlc3Nvci4KICAgICAqCiAgICAgKiBAcmV0dXJuIHRoZSBsYXRlc3Qgc291cmNlIHZlcnNpb24gc3VwcG9ydGVkIGJ5IHRoaXMgYW5ub3RhdGlvbgogICAgICogcHJvY2Vzc29yLgogICAgICogQHNlZSBqYXZheC5hbm5vdGF0aW9uLnByb2Nlc3NpbmcuU3VwcG9ydGVkU291cmNlVmVyc2lvbgogICAgICogQHNlZSBQcm9jZXNzaW5nRW52aXJvbm1lbnQjZ2V0U291cmNlVmVyc2lvbgogICAgICovCiAgICBTb3VyY2VWZXJzaW9uIGdldFN1cHBvcnRlZFNvdXJjZVZlcnNpb24oKTsKCiAgICAvKioKICAgICAqIEluaXRpYWxpemVzIHRoZSBwcm9jZXNzb3Igd2l0aCB0aGUgcHJvY2Vzc2luZyBlbnZpcm9ubWVudC4KICAgICAqCiAgICAgKiBAcGFyYW0gcHJvY2Vzc2luZ0VudiBlbnZpcm9ubWVudCBmb3IgZmFjaWxpdGllcyB0aGUgdG9vbCBmcmFtZXdvcmsKICAgICAqIHByb3ZpZGVzIHRvIHRoZSBwcm9jZXNzb3IKICAgICAqLwogICAgdm9pZCBpbml0KFByb2Nlc3NpbmdFbnZpcm9ubWVudCBwcm9jZXNzaW5nRW52KTsKCiAgICAvKioKICAgICAqIFByb2Nlc3NlcyBhIHNldCBvZiBhbm5vdGF0aW9uIHR5cGVzIG9uIHR5cGUgZWxlbWVudHMKICAgICAqIG9yaWdpbmF0aW5nIGZyb20gdGhlIHByaW9yIHJvdW5kIGFuZCByZXR1cm5zIHdoZXRoZXIgb3Igbm90CiAgICAgKiB0aGVzZSBhbm5vdGF0aW9uIHR5cGVzIGFyZSBjbGFpbWVkIGJ5IHRoaXMgcHJvY2Vzc29yLiAgSWYge0Bjb2RlCiAgICAgKiB0cnVlfSBpcyByZXR1cm5lZCwgdGhlIGFubm90YXRpb24gdHlwZXMgYXJlIGNsYWltZWQgYW5kIHN1YnNlcXVlbnQKICAgICAqIHByb2Nlc3NvcnMgd2lsbCBub3QgYmUgYXNrZWQgdG8gcHJvY2VzcyB0aGVtOyBpZiB7QGNvZGUgZmFsc2V9CiAgICAgKiBpcyByZXR1cm5lZCwgdGhlIGFubm90YXRpb24gdHlwZXMgYXJlIHVuY2xhaW1lZCBhbmQgc3Vic2VxdWVudAogICAgICogcHJvY2Vzc29ycyBtYXkgYmUgYXNrZWQgdG8gcHJvY2VzcyB0aGVtLiAgQSBwcm9jZXNzb3IgbWF5CiAgICAgKiBhbHdheXMgcmV0dXJuIHRoZSBzYW1lIGJvb2xlYW4gdmFsdWUgb3IgbWF5IHZhcnkgdGhlIHJlc3VsdAogICAgICogYmFzZWQgb24gaXRzIG93biBjaG9zZW4gY3JpdGVyaWEuCiAgICAgKgogICAgICogPHA+VGhlIGlucHV0IHNldCB3aWxsIGJlIGVtcHR5IGlmIHRoZSBwcm9jZXNzb3Igc3VwcG9ydHMge0Bjb2RlCiAgICAgKiAiKiJ9IGFuZCB0aGUgcm9vdCBlbGVtZW50cyBoYXZlIG5vIGFubm90YXRpb25zLiAgQSB7QGNvZGUKICAgICAqIFByb2Nlc3Nvcn0gbXVzdCBncmFjZWZ1bGx5IGhhbmRsZSBhbiBlbXB0eSBzZXQgb2YgYW5ub3RhdGlvbnMuCiAgICAgKgogICAgICogQHBhcmFtIGFubm90YXRpb25zIHRoZSBhbm5vdGF0aW9uIHR5cGVzIHJlcXVlc3RlZCB0byBiZSBwcm9jZXNzZWQKICAgICAqIEBwYXJhbSByb3VuZEVudiAgZW52aXJvbm1lbnQgZm9yIGluZm9ybWF0aW9uIGFib3V0IHRoZSBjdXJyZW50IGFuZCBwcmlvciByb3VuZAogICAgICogQHJldHVybiB3aGV0aGVyIG9yIG5vdCB0aGUgc2V0IG9mIGFubm90YXRpb24gdHlwZXMgYXJlIGNsYWltZWQgYnkgdGhpcyBwcm9jZXNzb3IKICAgICAqLwogICAgYm9vbGVhbiBwcm9jZXNzKFNldDw/IGV4dGVuZHMgVHlwZUVsZW1lbnQ+IGFubm90YXRpb25zLAogICAgICAgICAgICAgICAgICAgIFJvdW5kRW52aXJvbm1lbnQgcm91bmRFbnYpOwoKICAgLyoqCiAgICAqIFJldHVybnMgdG8gdGhlIHRvb2wgaW5mcmFzdHJ1Y3R1cmUgYW4gaXRlcmFibGUgb2Ygc3VnZ2VzdGVkCiAgICAqIGNvbXBsZXRpb25zIHRvIGFuIGFubm90YXRpb24uICBTaW5jZSBjb21wbGV0aW9ucyBhcmUgYmVpbmcgYXNrZWQKICAgICogZm9yLCB0aGUgaW5mb3JtYXRpb24gcHJvdmlkZWQgYWJvdXQgdGhlIGFubm90YXRpb24gbWF5IGJlCiAgICAqIGluY29tcGxldGUsIGFzIGlmIGZvciBhIHNvdXJjZSBjb2RlIGZyYWdtZW50LiBBIHByb2Nlc3NvciBtYXkKICAgICogcmV0dXJuIGFuIGVtcHR5IGl0ZXJhYmxlLiAgQW5ub3RhdGlvbiBwcm9jZXNzb3JzIHNob3VsZCBmb2N1cwogICAgKiB0aGVpciBlZmZvcnRzIG9uIHByb3ZpZGluZyBjb21wbGV0aW9ucyBmb3IgYW5ub3RhdGlvbiBtZW1iZXJzCiAgICAqIHdpdGggYWRkaXRpb25hbCB2YWxpZGl0eSBjb25zdHJhaW50cyBrbm93biB0byB0aGUgcHJvY2Vzc29yLCBmb3IKICAgICogZXhhbXBsZSBhbiB7QGNvZGUgaW50fSBtZW1iZXIgd2hvc2UgdmFsdWUgc2hvdWxkIGxpZSBiZXR3ZWVuIDEKICAgICogYW5kIDEwIG9yIGEgc3RyaW5nIG1lbWJlciB0aGF0IHNob3VsZCBiZSByZWNvZ25pemVkIGJ5IGEga25vd24KICAgICogZ3JhbW1hciwgc3VjaCBhcyBhIHJlZ3VsYXIgZXhwcmVzc2lvbiBvciBhIFVSTC4KICAgICoKICAgICogPHA+U2luY2UgaW5jb21wbGV0ZSBwcm9ncmFtcyBhcmUgYmVpbmcgbW9kZWxlZCwgc29tZSBvZiB0aGUKICAgICogcGFyYW1ldGVycyBtYXkgb25seSBoYXZlIHBhcnRpYWwgaW5mb3JtYXRpb24gb3IgbWF5IGJlIHtAY29kZQogICAgKiBudWxsfS4gIEF0IGxlYXN0IG9uZSBvZiB7QGNvZGUgZWxlbWVudH0gYW5kIHtAY29kZSB1c2VyVGV4dH0KICAgICogbXVzdCBiZSBub24te0Bjb2RlIG51bGx9LiAgSWYge0Bjb2RlIGVsZW1lbnR9IGlzIG5vbi17QGNvZGUgbnVsbH0sCiAgICAqIHtAY29kZSBhbm5vdGF0aW9ufSBhbmQge0Bjb2RlIG1lbWJlcn0gbWF5IGJlIHtAY29kZQogICAgKiBudWxsfS4gIFByb2Nlc3NvcnMgbWF5IG5vdCB0aHJvdyBhIHtAY29kZSBOdWxsUG9pbnRlckV4Y2VwdGlvbn0KICAgICogaWYgc29tZSBwYXJhbWV0ZXJzIGFyZSB7QGNvZGUgbnVsbH07IGlmIGEgcHJvY2Vzc29yIGhhcyBubwogICAgKiBjb21wbGV0aW9ucyB0byBvZmZlciBiYXNlZCBvbiB0aGUgcHJvdmlkZWQgaW5mb3JtYXRpb24sIGFuCiAgICAqIGVtcHR5IGl0ZXJhYmxlIGNhbiBiZSByZXR1cm5lZC4gIFRoZSBwcm9jZXNzb3IgbWF5IGFsc28gcmV0dXJuCiAgICAqIGEgc2luZ2xlIGNvbXBsZXRpb24gd2l0aCBhbiBlbXB0eSB2YWx1ZSBzdHJpbmcgYW5kIGEgbWVzc2FnZQogICAgKiBkZXNjcmliaW5nIHdoeSB0aGVyZSBhcmUgbm8gY29tcGxldGlvbnMuCiAgICAqCiAgICAqIDxwPkNvbXBsZXRpb25zIGFyZSBpbmZvcm1hdGl2ZSBhbmQgbWF5IHJlZmxlY3QgYWRkaXRpb25hbAogICAgKiB2YWxpZGl0eSBjaGVja3MgcGVyZm9ybWVkIGJ5IGFubm90YXRpb24gcHJvY2Vzc29ycy4gIEZvcgogICAgKiBleGFtcGxlLCBjb25zaWRlciB0aGUgc2ltcGxlIGFubm90YXRpb246CiAgICAqCiAgICAqIDxibG9ja3F1b3RlPgogICAgKiA8cHJlPgogICAgKiAmIzA2NDtNZXJzZW5uZVByaW1lIHsKICAgICogICAgaW50IHZhbHVlKCk7CiAgICAqIH0KICAgICogPC9wcmU+CiAgICAqIDwvYmxvY2txdW90ZT4KICAgICoKICAgICogKEEgTWVyc2VubmUgcHJpbWUgaXMgcHJpbWUgbnVtYmVyIG9mIHRoZSBmb3JtCiAgICAqIDI8c3VwPjxpPm48L2k+PC9zdXA+IC0gMS4pIEdpdmVuIGFuIHtAY29kZSBBbm5vdGF0aW9uTWlycm9yfQogICAgKiBmb3IgdGhpcyBhbm5vdGF0aW9uIHR5cGUsIGEgbGlzdCBvZiBhbGwgc3VjaCBwcmltZXMgaW4gdGhlCiAgICAqIHtAY29kZSBpbnR9IHJhbmdlIGNvdWxkIGJlIHJldHVybmVkIHdpdGhvdXQgZXhhbWluaW5nIGFueSBvdGhlcgogICAgKiBhcmd1bWVudHMgdG8ge0Bjb2RlIGdldENvbXBsZXRpb25zfToKICAgICoKICAgICogPGJsb2NrcXVvdGU+CiAgICAqIDxwcmU+CiAgICAqIGltcG9ydCBzdGF0aWMgamF2YXguYW5ub3RhdGlvbi5wcm9jZXNzaW5nLkNvbXBsZXRpb25zLio7CiAgICAqIC4uLgogICAgKiByZXR1cm4gQXJyYXlzLmFzTGlzdCh7QGxpbmsgQ29tcGxldGlvbnMjb2YoU3RyaW5nKSBvZn0oJnF1b3Q7MyZxdW90OyksCiAgICAqICAgICAgICAgICAgICAgICAgICAgIG9mKCZxdW90OzcmcXVvdDspLAogICAgKiAgICAgICAgICAgICAgICAgICAgICBvZigmcXVvdDszMSZxdW90OyksCiAgICAqICAgICAgICAgICAgICAgICAgICAgIG9mKCZxdW90OzEyNyZxdW90OyksCiAgICAqICAgICAgICAgICAgICAgICAgICAgIG9mKCZxdW90OzgxOTEmcXVvdDspLAogICAgKiAgICAgICAgICAgICAgICAgICAgICBvZigmcXVvdDsxMzEwNzEmcXVvdDspLAogICAgKiAgICAgICAgICAgICAgICAgICAgICBvZigmcXVvdDs1MjQyODcmcXVvdDspLAogICAgKiAgICAgICAgICAgICAgICAgICAgICBvZigmcXVvdDsyMTQ3NDgzNjQ3JnF1b3Q7KSk7CiAgICAqIDwvcHJlPgogICAgKiA8L2Jsb2NrcXVvdGU+CiAgICAqCiAgICAqIEEgbW9yZSBpbmZvcm1hdGl2ZSBzZXQgb2YgY29tcGxldGlvbnMgd291bGQgaW5jbHVkZSB0aGUgbnVtYmVyCiAgICAqIG9mIGVhY2ggcHJpbWU6CiAgICAqCiAgICAqIDxibG9ja3F1b3RlPgogICAgKiA8cHJlPgogICAgKiByZXR1cm4gQXJyYXlzLmFzTGlzdCh7QGxpbmsgQ29tcGxldGlvbnMjb2YoU3RyaW5nLCBTdHJpbmcpIG9mfSgmcXVvdDszJnF1b3Q7LCAgICAgICAgICAmcXVvdDtNMiZxdW90OyksCiAgICAqICAgICAgICAgICAgICAgICAgICAgIG9mKCZxdW90OzcmcXVvdDssICAgICAgICAgICZxdW90O00zJnF1b3Q7KSwKICAgICogICAgICAgICAgICAgICAgICAgICAgb2YoJnF1b3Q7MzEmcXVvdDssICAgICAgICAgJnF1b3Q7TTUmcXVvdDspLAogICAgKiAgICAgICAgICAgICAgICAgICAgICBvZigmcXVvdDsxMjcmcXVvdDssICAgICAgICAmcXVvdDtNNyZxdW90OyksCiAgICAqICAgICAgICAgICAgICAgICAgICAgIG9mKCZxdW90OzgxOTEmcXVvdDssICAgICAgICZxdW90O00xMyZxdW90OyksCiAgICAqICAgICAgICAgICAgICAgICAgICAgIG9mKCZxdW90OzEzMTA3MSZxdW90OywgICAgICZxdW90O00xNyZxdW90OyksCiAgICAqICAgICAgICAgICAgICAgICAgICAgIG9mKCZxdW90OzUyNDI4NyZxdW90OywgICAgICZxdW90O00xOSZxdW90OyksCiAgICAqICAgICAgICAgICAgICAgICAgICAgIG9mKCZxdW90OzIxNDc0ODM2NDcmcXVvdDssICZxdW90O00zMSZxdW90OykpOwogICAgKiA8L3ByZT4KICAgICogPC9ibG9ja3F1b3RlPgogICAgKgogICAgKiBIb3dldmVyLCBpZiB0aGUge0Bjb2RlIHVzZXJUZXh0fSBpcyBhdmFpbGFibGUsIGl0IGNhbiBiZSBjaGVja2VkCiAgICAqIHRvIHNlZSBpZiBvbmx5IGEgc3Vic2V0IG9mIHRoZSBNZXJzZW5uZSBwcmltZXMgYXJlIHZhbGlkLiAgRm9yCiAgICAqIGV4YW1wbGUsIGlmIHRoZSB1c2VyIGhhcyB0eXBlZAogICAgKgogICAgKiA8YmxvY2txdW90ZT4KICAgICogPGNvZGU+CiAgICAqICYjMDY0O01lcnNlbm5lUHJpbWUoMQogICAgKiA8L2NvZGU+CiAgICAqIDwvYmxvY2txdW90ZT4KICAgICoKICAgICogdGhlIHZhbHVlIG9mIHtAY29kZSB1c2VyVGV4dH0gd2lsbCBiZSB7QGNvZGUgIjEifTsgYW5kIG9ubHkKICAgICogdHdvIG9mIHRoZSBwcmltZXMgYXJlIHBvc3NpYmxlIGNvbXBsZXRpb25zOgogICAgKgogICAgKiA8YmxvY2txdW90ZT4KICAgICogPHByZT4KICAgICogcmV0dXJuIEFycmF5cy5hc0xpc3Qob2YoJnF1b3Q7MTI3JnF1b3Q7LCAgICAgICAgJnF1b3Q7TTcmcXVvdDspLAogICAgKiAgICAgICAgICAgICAgICAgICAgICBvZigmcXVvdDsxMzEwNzEmcXVvdDssICAgICAmcXVvdDtNMTcmcXVvdDspKTsKICAgICogPC9wcmU+CiAgICAqIDwvYmxvY2txdW90ZT4KICAgICoKICAgICogU29tZXRpbWVzIG5vIHZhbGlkIGNvbXBsZXRpb24gaXMgcG9zc2libGUuICBGb3IgZXhhbXBsZSwgdGhlcmUKICAgICogaXMgbm8gaW4tcmFuZ2UgTWVyc2VubmUgcHJpbWUgc3RhcnRpbmcgd2l0aCA5OgogICAgKgogICAgKiA8YmxvY2txdW90ZT4KICAgICogPGNvZGU+CiAgICAqICYjMDY0O01lcnNlbm5lUHJpbWUoOQogICAgKiA8L2NvZGU+CiAgICAqIDwvYmxvY2txdW90ZT4KICAgICoKICAgICogQW4gYXBwcm9wcmlhdGUgcmVzcG9uc2UgaW4gdGhpcyBjYXNlIGlzIHRvIGVpdGhlciByZXR1cm4gYW4KICAgICogZW1wdHkgbGlzdCBvZiBjb21wbGV0aW9ucywKICAgICoKICAgICogPGJsb2NrcXVvdGU+CiAgICAqIDxwcmU+CiAgICAqIHJldHVybiBDb2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICogPC9wcmU+CiAgICAqIDwvYmxvY2txdW90ZT4KICAgICoKICAgICogb3IgYSBzaW5nbGUgZW1wdHkgY29tcGxldGlvbiB3aXRoIGEgaGVscGZ1bCBtZXNzYWdlCiAgICAqCiAgICAqIDxibG9ja3F1b3RlPgogICAgKiA8cHJlPgogICAgKiByZXR1cm4gQXJyYXlzLmFzTGlzdChvZigmcXVvdDsmcXVvdDssICZxdW90O05vIGluLXJhbmdlIE1lcnNlbm5lIHByaW1lcyBzdGFydCB3aXRoIDkmcXVvdDspKTsKICAgICogPC9wcmU+CiAgICAqIDwvYmxvY2txdW90ZT4KICAgICoKICAgICogQHBhcmFtIGVsZW1lbnQgdGhlIGVsZW1lbnQgYmVpbmcgYW5ub3RhdGVkCiAgICAqIEBwYXJhbSBhbm5vdGF0aW9uIHRoZSAocGVyaGFwcyBwYXJ0aWFsKSBhbm5vdGF0aW9uIGJlaW5nCiAgICAqICAgICAgICAgICAgICAgICAgIGFwcGxpZWQgdG8gdGhlIGVsZW1lbnQKICAgICogQHBhcmFtIG1lbWJlciB0aGUgYW5ub3RhdGlvbiBtZW1iZXIgdG8gcmV0dXJuIHBvc3NpYmxlIGNvbXBsZXRpb25zIGZvcgogICAgKiBAcGFyYW0gdXNlclRleHQgc291cmNlIGNvZGUgdGV4dCB0byBiZSBjb21wbGV0ZWQKICAgICoKICAgICogQHJldHVybiBzdWdnZXN0ZWQgY29tcGxldGlvbnMgdG8gdGhlIGFubm90YXRpb24KICAgICovCiAgICBJdGVyYWJsZTw/IGV4dGVuZHMgQ29tcGxldGlvbj4gZ2V0Q29tcGxldGlvbnMoRWxlbWVudCBlbGVtZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFubm90YXRpb25NaXJyb3IgYW5ub3RhdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFeGVjdXRhYmxlRWxlbWVudCBtZW1iZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHVzZXJUZXh0KTsKfQpQSwMECgAACAAA0n1NSqLXw6VcCwAAXAsAACwAAABqYXZheC9hbm5vdGF0aW9uL3Byb2Nlc3NpbmcvQ29tcGxldGlvbnMuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNiwgMjAxMiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBqYXZheC5hbm5vdGF0aW9uLnByb2Nlc3Npbmc7CgovKioKICogVXRpbGl0eSBjbGFzcyBmb3IgYXNzZW1ibGluZyB7QGxpbmsgQ29tcGxldGlvbn0gb2JqZWN0cy4KICoKICogQGF1dGhvciBKb3NlcGggRC4gRGFyY3kKICogQGF1dGhvciBTY290dCBTZWxpZ21hbgogKiBAYXV0aG9yIFBldGVyIHZvbiBkZXIgQWgmZWFjdXRlOwogKiBAc2luY2UgMS42CiAqLwpwdWJsaWMgY2xhc3MgQ29tcGxldGlvbnMgewogICAgLy8gTm8gaW5zdGFuY2VzIGZvciB5b3UuCiAgICBwcml2YXRlIENvbXBsZXRpb25zKCkge30KCiAgICBwcml2YXRlIHN0YXRpYyBjbGFzcyBTaW1wbGVDb21wbGV0aW9uIGltcGxlbWVudHMgQ29tcGxldGlvbiB7CiAgICAgICAgcHJpdmF0ZSBTdHJpbmcgdmFsdWU7CiAgICAgICAgcHJpdmF0ZSBTdHJpbmcgbWVzc2FnZTsKCiAgICAgICAgU2ltcGxlQ29tcGxldGlvbihTdHJpbmcgdmFsdWUsIFN0cmluZyBtZXNzYWdlKSB7CiAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsIHx8IG1lc3NhZ2UgPT0gbnVsbCkKICAgICAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigiTnVsbCBjb21wbGV0aW9uIHN0cmluZ3Mgbm90IGFjY2VwdGVkLiIpOwogICAgICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7CiAgICAgICAgICAgIHRoaXMubWVzc2FnZSA9IG1lc3NhZ2U7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgU3RyaW5nIGdldFZhbHVlKCkgewogICAgICAgICAgICByZXR1cm4gdmFsdWU7CiAgICAgICAgfQoKCiAgICAgICAgcHVibGljIFN0cmluZyBnZXRNZXNzYWdlKCkgewogICAgICAgICAgICByZXR1cm4gbWVzc2FnZTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CiAgICAgICAgICAgIHJldHVybiAiW1wiIiArIHZhbHVlICsgIlwiLCBcIiIgKyBtZXNzYWdlICsgIlwiXSI7CiAgICAgICAgfQogICAgICAgIC8vIERlZmF1bHQgZXF1YWxzIGFuZCBoYXNoQ29kZSBhcmUgZmluZS4KICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgYSBjb21wbGV0aW9uIG9mIHRoZSB2YWx1ZSBhbmQgbWVzc2FnZS4KICAgICAqCiAgICAgKiBAcGFyYW0gdmFsdWUgdGhlIHRleHQgb2YgdGhlIGNvbXBsZXRpb24KICAgICAqIEBwYXJhbSBtZXNzYWdlIGEgbWVzc2FnZSBhYm91dCB0aGUgY29tcGxldGlvbgogICAgICogQHJldHVybiBhIGNvbXBsZXRpb24gb2YgdGhlIHByb3ZpZGVkIHZhbHVlIGFuZCBtZXNzYWdlCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgQ29tcGxldGlvbiBvZihTdHJpbmcgdmFsdWUsIFN0cmluZyBtZXNzYWdlKSB7CiAgICAgICAgcmV0dXJuIG5ldyBTaW1wbGVDb21wbGV0aW9uKHZhbHVlLCBtZXNzYWdlKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgYSBjb21wbGV0aW9uIG9mIHRoZSB2YWx1ZSBhbmQgYW4gZW1wdHkgbWVzc2FnZQogICAgICoKICAgICAqIEBwYXJhbSB2YWx1ZSB0aGUgdGV4dCBvZiB0aGUgY29tcGxldGlvbgogICAgICogQHJldHVybiBhIGNvbXBsZXRpb24gb2YgdGhlIHZhbHVlIGFuZCBhbiBlbXB0eSBtZXNzYWdlCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgQ29tcGxldGlvbiBvZihTdHJpbmcgdmFsdWUpIHsKICAgICAgICByZXR1cm4gbmV3IFNpbXBsZUNvbXBsZXRpb24odmFsdWUsICIiKTsKICAgIH0KfQpQSwMECgAACAAA0n1NSqlpbpR6DwAAeg8AACkAAABqYXZheC9hbm5vdGF0aW9uL3Byb2Nlc3NpbmcvTWVzc2FnZXIuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAwNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBqYXZheC5hbm5vdGF0aW9uLnByb2Nlc3Npbmc7CgppbXBvcnQgamF2YXguYW5ub3RhdGlvbi4qOwppbXBvcnQgamF2YXgudG9vbHMuRGlhZ25vc3RpYzsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC4qOwoKLyoqCiAqIEEge0Bjb2RlIE1lc3NhZ2VyfSBwcm92aWRlcyB0aGUgd2F5IGZvciBhbiBhbm5vdGF0aW9uIHByb2Nlc3NvciB0bwogKiByZXBvcnQgZXJyb3IgbWVzc2FnZXMsIHdhcm5pbmdzLCBhbmQgb3RoZXIgbm90aWNlcy4gIEVsZW1lbnRzLAogKiBhbm5vdGF0aW9ucywgYW5kIGFubm90YXRpb24gdmFsdWVzIGNhbiBiZSBwYXNzZWQgdG8gcHJvdmlkZSBhCiAqIGxvY2F0aW9uIGhpbnQgZm9yIHRoZSBtZXNzYWdlLiAgSG93ZXZlciwgc3VjaCBsb2NhdGlvbiBoaW50cyBtYXkgYmUKICogdW5hdmFpbGFibGUgb3Igb25seSBhcHByb3hpbWF0ZS4KICoKICogPHA+UHJpbnRpbmcgYSBtZXNzYWdlIHdpdGggYW4ge0BsaW5rcGxhaW4KICogamF2YXgudG9vbHMuRGlhZ25vc3RpYy5LaW5kI0VSUk9SIGVycm9yIGtpbmR9IHdpbGwge0BsaW5rcGxhaW4KICogUm91bmRFbnZpcm9ubWVudCNlcnJvclJhaXNlZCByYWlzZSBhbiBlcnJvcn0uCiAqCiAqIDxwPk5vdGUgdGhhdCB0aGUgbWVzc2FnZXMgJnF1b3Q7cHJpbnRlZCZxdW90OyBieSBtZXRob2RzIGluIHRoaXMKICogaW50ZXJmYWNlIG1heSBvciBtYXkgbm90IGFwcGVhciBhcyB0ZXh0dWFsIG91dHB1dCB0byBhIGxvY2F0aW9uCiAqIGxpa2Uge0BsaW5rIFN5c3RlbSNvdXR9IG9yIHtAbGluayBTeXN0ZW0jZXJyfS4gIEltcGxlbWVudGF0aW9ucyBtYXkKICogY2hvb3NlIHRvIHByZXNlbnQgdGhpcyBpbmZvcm1hdGlvbiBpbiBhIGRpZmZlcmVudCBmYXNoaW9uLCBzdWNoIGFzCiAqIG1lc3NhZ2VzIGluIGEgd2luZG93LgogKgogKiBAYXV0aG9yIEpvc2VwaCBELiBEYXJjeQogKiBAYXV0aG9yIFNjb3R0IFNlbGlnbWFuCiAqIEBhdXRob3IgUGV0ZXIgdm9uIGRlciBBaCZlYWN1dGU7CiAqIEBzZWUgUHJvY2Vzc2luZ0Vudmlyb25tZW50I2dldExvY2FsZQogKiBAc2luY2UgMS42CiAqLwpwdWJsaWMgaW50ZXJmYWNlIE1lc3NhZ2VyIHsKICAgIC8qKgogICAgICogUHJpbnRzIGEgbWVzc2FnZSBvZiB0aGUgc3BlY2lmaWVkIGtpbmQuCiAgICAgKgogICAgICogQHBhcmFtIGtpbmQgdGhlIGtpbmQgb2YgbWVzc2FnZQogICAgICogQHBhcmFtIG1zZyAgdGhlIG1lc3NhZ2UsIG9yIGFuIGVtcHR5IHN0cmluZyBpZiBub25lCiAgICAgKi8KICAgIHZvaWQgcHJpbnRNZXNzYWdlKERpYWdub3N0aWMuS2luZCBraW5kLCBDaGFyU2VxdWVuY2UgbXNnKTsKCiAgICAvKioKICAgICAqIFByaW50cyBhIG1lc3NhZ2Ugb2YgdGhlIHNwZWNpZmllZCBraW5kIGF0IHRoZSBsb2NhdGlvbiBvZiB0aGUKICAgICAqIGVsZW1lbnQuCiAgICAgKgogICAgICogQHBhcmFtIGtpbmQgdGhlIGtpbmQgb2YgbWVzc2FnZQogICAgICogQHBhcmFtIG1zZyAgdGhlIG1lc3NhZ2UsIG9yIGFuIGVtcHR5IHN0cmluZyBpZiBub25lCiAgICAgKiBAcGFyYW0gZSAgICB0aGUgZWxlbWVudCB0byB1c2UgYXMgYSBwb3NpdGlvbiBoaW50CiAgICAgKi8KICAgIHZvaWQgcHJpbnRNZXNzYWdlKERpYWdub3N0aWMuS2luZCBraW5kLCBDaGFyU2VxdWVuY2UgbXNnLCBFbGVtZW50IGUpOwoKICAgIC8qKgogICAgICogUHJpbnRzIGEgbWVzc2FnZSBvZiB0aGUgc3BlY2lmaWVkIGtpbmQgYXQgdGhlIGxvY2F0aW9uIG9mIHRoZQogICAgICogYW5ub3RhdGlvbiBtaXJyb3Igb2YgdGhlIGFubm90YXRlZCBlbGVtZW50LgogICAgICoKICAgICAqIEBwYXJhbSBraW5kIHRoZSBraW5kIG9mIG1lc3NhZ2UKICAgICAqIEBwYXJhbSBtc2cgIHRoZSBtZXNzYWdlLCBvciBhbiBlbXB0eSBzdHJpbmcgaWYgbm9uZQogICAgICogQHBhcmFtIGUgICAgdGhlIGFubm90YXRlZCBlbGVtZW50CiAgICAgKiBAcGFyYW0gYSAgICB0aGUgYW5ub3RhdGlvbiB0byB1c2UgYXMgYSBwb3NpdGlvbiBoaW50CiAgICAgKi8KICAgIHZvaWQgcHJpbnRNZXNzYWdlKERpYWdub3N0aWMuS2luZCBraW5kLCBDaGFyU2VxdWVuY2UgbXNnLCBFbGVtZW50IGUsIEFubm90YXRpb25NaXJyb3IgYSk7CgogICAgLyoqCiAgICAgKiBQcmludHMgYSBtZXNzYWdlIG9mIHRoZSBzcGVjaWZpZWQga2luZCBhdCB0aGUgbG9jYXRpb24gb2YgdGhlCiAgICAgKiBhbm5vdGF0aW9uIHZhbHVlIGluc2lkZSB0aGUgYW5ub3RhdGlvbiBtaXJyb3Igb2YgdGhlIGFubm90YXRlZAogICAgICogZWxlbWVudC4KICAgICAqCiAgICAgKiBAcGFyYW0ga2luZCB0aGUga2luZCBvZiBtZXNzYWdlCiAgICAgKiBAcGFyYW0gbXNnICB0aGUgbWVzc2FnZSwgb3IgYW4gZW1wdHkgc3RyaW5nIGlmIG5vbmUKICAgICAqIEBwYXJhbSBlICAgIHRoZSBhbm5vdGF0ZWQgZWxlbWVudAogICAgICogQHBhcmFtIGEgICAgdGhlIGFubm90YXRpb24gY29udGFpbmluZyB0aGUgYW5ub3RhdGlvbiB2YWx1ZQogICAgICogQHBhcmFtIHYgICAgdGhlIGFubm90YXRpb24gdmFsdWUgdG8gdXNlIGFzIGEgcG9zaXRpb24gaGludAogICAgICovCiAgICB2b2lkIHByaW50TWVzc2FnZShEaWFnbm9zdGljLktpbmQga2luZCwKICAgICAgICAgICAgICAgICAgICAgIENoYXJTZXF1ZW5jZSBtc2csCiAgICAgICAgICAgICAgICAgICAgICBFbGVtZW50IGUsCiAgICAgICAgICAgICAgICAgICAgICBBbm5vdGF0aW9uTWlycm9yIGEsCiAgICAgICAgICAgICAgICAgICAgICBBbm5vdGF0aW9uVmFsdWUgdik7Cn0KUEsDBAoAAAgAAAY7qUrk5bAqbD0AAGw9AAAmAAAAamF2YXgvYW5ub3RhdGlvbi9wcm9jZXNzaW5nL0ZpbGVyLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMTcsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgamF2YXguYW5ub3RhdGlvbi5wcm9jZXNzaW5nOwoKaW1wb3J0IGphdmF4LnRvb2xzLkphdmFGaWxlTWFuYWdlcjsKaW1wb3J0IGphdmF4LnRvb2xzLio7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuRWxlbWVudDsKaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CgovKioKICogVGhpcyBpbnRlcmZhY2Ugc3VwcG9ydHMgdGhlIGNyZWF0aW9uIG9mIG5ldyBmaWxlcyBieSBhbiBhbm5vdGF0aW9uCiAqIHByb2Nlc3Nvci4gIEZpbGVzIGNyZWF0ZWQgaW4gdGhpcyB3YXkgd2lsbCBiZSBrbm93biB0byB0aGUKICogYW5ub3RhdGlvbiBwcm9jZXNzaW5nIHRvb2wgaW1wbGVtZW50aW5nIHRoaXMgaW50ZXJmYWNlLCBiZXR0ZXIKICogZW5hYmxpbmcgdGhlIHRvb2wgdG8gbWFuYWdlIHRoZW0uICBTb3VyY2UgYW5kIGNsYXNzIGZpbGVzIHNvCiAqIGNyZWF0ZWQgd2lsbCBiZSB7QGxpbmtwbGFpbiBSb3VuZEVudmlyb25tZW50I2dldFJvb3RFbGVtZW50cwogKiBjb25zaWRlcmVkIGZvciBwcm9jZXNzaW5nfSBieSB0aGUgdG9vbCBpbiBhIHN1YnNlcXVlbnQge0BsaW5rcGxhaW4KICogUm91bmRFbnZpcm9ubWVudCByb3VuZCBvZiBwcm9jZXNzaW5nfSBhZnRlciB0aGUge0Bjb2RlIGNsb3NlfQogKiBtZXRob2QgaGFzIGJlZW4gY2FsbGVkIG9uIHRoZSB7QGNvZGUgV3JpdGVyfSBvciB7QGNvZGUKICogT3V0cHV0U3RyZWFtfSB1c2VkIHRvIHdyaXRlIHRoZSBjb250ZW50cyBvZiB0aGUgZmlsZS4KICoKICogVGhyZWUga2luZHMgb2YgZmlsZXMgYXJlIGRpc3Rpbmd1aXNoZWQ6IHNvdXJjZSBmaWxlcywgY2xhc3MgZmlsZXMsCiAqIGFuZCBhdXhpbGlhcnkgcmVzb3VyY2UgZmlsZXMuCiAqCiAqIDxwPiBUaGVyZSBhcmUgdHdvIGRpc3Rpbmd1aXNoZWQgc3VwcG9ydGVkIGxvY2F0aW9ucyAoc3VidHJlZXMKICogd2l0aGluIHRoZSBsb2dpY2FsIGZpbGUgc3lzdGVtKSB3aGVyZSBuZXdseSBjcmVhdGVkIGZpbGVzIGFyZQogKiBwbGFjZWQ6IG9uZSBmb3Ige0BsaW5rcGxhaW4KICogamF2YXgudG9vbHMuU3RhbmRhcmRMb2NhdGlvbiNTT1VSQ0VfT1VUUFVUIG5ldyBzb3VyY2UgZmlsZXN9LCBhbmQKICogb25lIGZvciB7QGxpbmtwbGFpbiBqYXZheC50b29scy5TdGFuZGFyZExvY2F0aW9uI0NMQVNTX09VVFBVVCBuZXcKICogY2xhc3MgZmlsZXN9LiAgKFRoZXNlIG1pZ2h0IGJlIHNwZWNpZmllZCBvbiBhIHRvb2wncyBjb21tYW5kIGxpbmUsCiAqIGZvciBleGFtcGxlLCB1c2luZyBmbGFncyBzdWNoIGFzIHtAY29kZSAtc30gYW5kIHtAY29kZSAtZH0uKSAgVGhlCiAqIGFjdHVhbCBsb2NhdGlvbnMgZm9yIG5ldyBzb3VyY2UgZmlsZXMgYW5kIG5ldyBjbGFzcyBmaWxlcyBtYXkgb3IKICogbWF5IG5vdCBiZSBkaXN0aW5jdCBvbiBhIHBhcnRpY3VsYXIgcnVuIG9mIHRoZSB0b29sLiAgUmVzb3VyY2UKICogZmlsZXMgbWF5IGJlIGNyZWF0ZWQgaW4gZWl0aGVyIGxvY2F0aW9uLiAgVGhlIG1ldGhvZHMgZm9yIHJlYWRpbmcKICogYW5kIHdyaXRpbmcgcmVzb3VyY2VzIHRha2UgYSByZWxhdGl2ZSBuYW1lIGFyZ3VtZW50LiAgQSByZWxhdGl2ZQogKiBuYW1lIGlzIGEgbm9uLW51bGwsIG5vbi1lbXB0eSBzZXF1ZW5jZSBvZiBwYXRoIHNlZ21lbnRzIHNlcGFyYXRlZAogKiBieSB7QGNvZGUgJy8nfTsge0Bjb2RlICcuJ30gYW5kIHtAY29kZSAnLi4nfSBhcmUgaW52YWxpZCBwYXRoCiAqIHNlZ21lbnRzLiAgQSB2YWxpZCByZWxhdGl2ZSBuYW1lIG11c3QgbWF0Y2ggdGhlCiAqICZxdW90O3BhdGgtcm9vdGxlc3MmcXVvdDsgcnVsZSBvZiA8YQogKiBocmVmPSJodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMzOTg2LnR4dCI+UkZDIDM5ODY8L2E+LCBzZWN0aW9uCiAqIDMuMy4KICoKICogPHA+VGhlIGZpbGUgY3JlYXRpb24gbWV0aG9kcyB0YWtlIGEgdmFyaWFibGUgbnVtYmVyIG9mIGFyZ3VtZW50cyB0bwogKiBhbGxvdyB0aGUgPGVtPm9yaWdpbmF0aW5nIGVsZW1lbnRzPC9lbT4gdG8gYmUgcHJvdmlkZWQgYXMgaGludHMgdG8KICogdGhlIHRvb2wgaW5mcmFzdHJ1Y3R1cmUgdG8gYmV0dGVyIG1hbmFnZSBkZXBlbmRlbmNpZXMuICBUaGUKICogb3JpZ2luYXRpbmcgZWxlbWVudHMgYXJlIHRoZSB0eXBlcyBvciBwYWNrYWdlcyAocmVwcmVzZW50aW5nIHtAY29kZQogKiBwYWNrYWdlLWluZm99IGZpbGVzKSBvciBtb2R1bGVzIChyZXByZXNlbnRpbmcge0Bjb2RlCiAqIG1vZHVsZS1pbmZvfSBmaWxlcykgd2hpY2ggY2F1c2VkIGFuIGFubm90YXRpb24gcHJvY2Vzc29yIHRvCiAqIGF0dGVtcHQgdG8gY3JlYXRlIGEgbmV3IGZpbGUuICBGb3IgZXhhbXBsZSwgaWYgYW4gYW5ub3RhdGlvbgogKiBwcm9jZXNzb3IgdHJpZXMgdG8gY3JlYXRlIGEgc291cmNlIGZpbGUsIHtAY29kZQogKiBHZW5lcmF0ZWRGcm9tVXNlclNvdXJjZX0sIGluIHJlc3BvbnNlIHRvIHByb2Nlc3NpbmcKICoKICogPGJsb2NrcXVvdGU+PHByZT4KICogICYjNjQ7R2VuZXJhdGUKICogIHB1YmxpYyBjbGFzcyBVc2VyU291cmNlIHt9CiAqIDwvcHJlPjwvYmxvY2txdW90ZT4KICoKICogdGhlIHR5cGUgZWxlbWVudCBmb3Ige0Bjb2RlIFVzZXJTb3VyY2V9IHNob3VsZCBiZSBwYXNzZWQgYXMgcGFydCBvZgogKiB0aGUgY3JlYXRpb24gbWV0aG9kIGNhbGwgYXMgaW46CiAqCiAqIDxibG9ja3F1b3RlPjxwcmU+CiAqICAgICAgZmlsZXIuY3JlYXRlU291cmNlRmlsZSgiR2VuZXJhdGVkRnJvbVVzZXJTb3VyY2UiLAogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWx0VXRpbHMuZ2V0VHlwZUVsZW1lbnQoIlVzZXJTb3VyY2UiKSk7CiAqIDwvcHJlPjwvYmxvY2txdW90ZT4KICoKICogSWYgdGhlcmUgYXJlIG5vIG9yaWdpbmF0aW5nIGVsZW1lbnRzLCBub25lIG5lZWQgdG8gYmUgcGFzc2VkLiAgVGhpcwogKiBpbmZvcm1hdGlvbiBtYXkgYmUgdXNlZCBpbiBhbiBpbmNyZW1lbnRhbCBlbnZpcm9ubWVudCB0byBkZXRlcm1pbmUKICogdGhlIG5lZWQgdG8gcmVydW4gcHJvY2Vzc29ycyBvciByZW1vdmUgZ2VuZXJhdGVkIGZpbGVzLgogKiBOb24taW5jcmVtZW50YWwgZW52aXJvbm1lbnRzIG1heSBpZ25vcmUgdGhlIG9yaWdpbmF0aW5nIGVsZW1lbnQKICogaW5mb3JtYXRpb24uCiAqCiAqIDxwPiBEdXJpbmcgZWFjaCBydW4gb2YgYW4gYW5ub3RhdGlvbiBwcm9jZXNzaW5nIHRvb2wsIGEgZmlsZSB3aXRoIGEKICogZ2l2ZW4gcGF0aG5hbWUgbWF5IGJlIGNyZWF0ZWQgb25seSBvbmNlLiAgSWYgdGhhdCBmaWxlIGFscmVhZHkKICogZXhpc3RzIGJlZm9yZSB0aGUgZmlyc3QgYXR0ZW1wdCB0byBjcmVhdGUgaXQsIHRoZSBvbGQgY29udGVudHMgd2lsbAogKiBiZSBkZWxldGVkLiAgQW55IHN1YnNlcXVlbnQgYXR0ZW1wdCB0byBjcmVhdGUgdGhlIHNhbWUgZmlsZSBkdXJpbmcKICogYSBydW4gd2lsbCB0aHJvdyBhIHtAbGluayBGaWxlckV4Y2VwdGlvbn0sIGFzIHdpbGwgYXR0ZW1wdGluZyB0bwogKiBjcmVhdGUgYm90aCBhIGNsYXNzIGZpbGUgYW5kIHNvdXJjZSBmaWxlIGZvciB0aGUgc2FtZSB0eXBlIG5hbWUgb3IKICogc2FtZSBwYWNrYWdlIG5hbWUuICBUaGUge0BsaW5rcGxhaW4gUHJvY2Vzc29yIGluaXRpYWwgaW5wdXRzfSB0bwogKiB0aGUgdG9vbCBhcmUgY29uc2lkZXJlZCB0byBiZSBjcmVhdGVkIGJ5IHRoZSB6ZXJvdGggcm91bmQ7CiAqIHRoZXJlZm9yZSwgYXR0ZW1wdGluZyB0byBjcmVhdGUgYSBzb3VyY2Ugb3IgY2xhc3MgZmlsZQogKiBjb3JyZXNwb25kaW5nIHRvIG9uZSBvZiB0aG9zZSBpbnB1dHMgd2lsbCByZXN1bHQgaW4gYSB7QGxpbmsKICogRmlsZXJFeGNlcHRpb259LgogKgogKiA8cD4gSW4gZ2VuZXJhbCwgcHJvY2Vzc29ycyBtdXN0IG5vdCBrbm93aW5nbHkgYXR0ZW1wdCB0byBvdmVyd3JpdGUKICogZXhpc3RpbmcgZmlsZXMgdGhhdCB3ZXJlIG5vdCBnZW5lcmF0ZWQgYnkgc29tZSBwcm9jZXNzb3IuICBBIHtAY29kZQogKiBGaWxlcn0gbWF5IHJlamVjdCBhdHRlbXB0cyB0byBvcGVuIGEgZmlsZSBjb3JyZXNwb25kaW5nIHRvIGFuCiAqIGV4aXN0aW5nIHR5cGUsIGxpa2Uge0Bjb2RlIGphdmEubGFuZy5PYmplY3R9LiAgTGlrZXdpc2UsIHRoZQogKiBpbnZva2VyIG9mIHRoZSBhbm5vdGF0aW9uIHByb2Nlc3NpbmcgdG9vbCBtdXN0IG5vdCBrbm93aW5nbHkKICogY29uZmlndXJlIHRoZSB0b29sIHN1Y2ggdGhhdCB0aGUgZGlzY292ZXJlZCBwcm9jZXNzb3JzIHdpbGwgYXR0ZW1wdAogKiB0byBvdmVyd3JpdGUgZXhpc3RpbmcgZmlsZXMgdGhhdCB3ZXJlIG5vdCBnZW5lcmF0ZWQuCiAqCiAqIDxwPiBQcm9jZXNzb3JzIGNhbiBpbmRpY2F0ZSBhIHNvdXJjZSBvciBjbGFzcyBmaWxlIGlzIGdlbmVyYXRlZCBieQogKiBpbmNsdWRpbmcgYSB7QGNvZGUgamF2YXguYW5ub3RhdGlvbi5HZW5lcmF0ZWR9IGFubm90YXRpb24gaWYgdGhlCiAqIGVudmlyb25tZW50IGlzIGNvbmZpZ3VyZWQgc28gdGhhdCB0aGF0IHR5cGUgaXMgYWNjZXNzaWJsZS4KICoKICogQGFwaU5vdGUgU29tZSBvZiB0aGUgZWZmZWN0IG9mIG92ZXJ3cml0aW5nIGEgZmlsZSBjYW4gYmUKICogYWNoaWV2ZWQgYnkgdXNpbmcgYSA8aT5kZWNvcmF0b3I8L2k+LXN0eWxlIHBhdHRlcm4uICBJbnN0ZWFkIG9mCiAqIG1vZGlmeWluZyBhIGNsYXNzIGRpcmVjdGx5LCB0aGUgY2xhc3MgaXMgZGVzaWduZWQgc28gdGhhdCBlaXRoZXIKICogaXRzIHN1cGVyY2xhc3MgaXMgZ2VuZXJhdGVkIGJ5IGFubm90YXRpb24gcHJvY2Vzc2luZyBvciBzdWJjbGFzc2VzCiAqIG9mIHRoZSBjbGFzcyBhcmUgZ2VuZXJhdGVkIGJ5IGFubm90YXRpb24gcHJvY2Vzc2luZy4gIElmIHRoZQogKiBzdWJjbGFzc2VzIGFyZSBnZW5lcmF0ZWQsIHRoZSBwYXJlbnQgY2xhc3MgbWF5IGJlIGRlc2lnbmVkIHRvIHVzZQogKiBmYWN0b3JpZXMgaW5zdGVhZCBvZiBwdWJsaWMgY29uc3RydWN0b3JzIHNvIHRoYXQgb25seSBzdWJjbGFzcwogKiBpbnN0YW5jZXMgd291bGQgYmUgcHJlc2VudGVkIHRvIGNsaWVudHMgb2YgdGhlIHBhcmVudCBjbGFzcy4KICoKICogQGF1dGhvciBKb3NlcGggRC4gRGFyY3kKICogQGF1dGhvciBTY290dCBTZWxpZ21hbgogKiBAYXV0aG9yIFBldGVyIHZvbiBkZXIgQWgmZWFjdXRlOwogKiBAc2luY2UgMS42CiAqLwpwdWJsaWMgaW50ZXJmYWNlIEZpbGVyIHsKICAgIC8qKgogICAgICogQ3JlYXRlcyBhIG5ldyBzb3VyY2UgZmlsZSBhbmQgcmV0dXJucyBhbiBvYmplY3QgdG8gYWxsb3cKICAgICAqIHdyaXRpbmcgdG8gaXQuIEEgc291cmNlIGZpbGUgZm9yIGEgdHlwZSwgb3IgYSBwYWNrYWdlIGNhbgogICAgICogYmUgY3JlYXRlZC4KICAgICAqCiAgICAgKiBUaGUgZmlsZSdzIG5hbWUgYW5kIHBhdGggKHJlbGF0aXZlIHRvIHRoZSB7QGxpbmtwbGFpbgogICAgICogU3RhbmRhcmRMb2NhdGlvbiNTT1VSQ0VfT1VUUFVUIHJvb3Qgb3V0cHV0IGxvY2F0aW9uIGZvciBzb3VyY2UKICAgICAqIGZpbGVzfSkgYXJlIGJhc2VkIG9uIHRoZSBuYW1lIG9mIHRoZSBpdGVtIHRvIGJlIGRlY2xhcmVkIGluCiAgICAgKiB0aGF0IGZpbGUgYXMgd2VsbCBhcyB0aGUgc3BlY2lmaWVkIG1vZHVsZSBmb3IgdGhlIGl0ZW0gKGlmCiAgICAgKiBhbnkpLgogICAgICoKICAgICAqIElmIG1vcmUgdGhhbiBvbmUgdHlwZSBpcyBiZWluZyBkZWNsYXJlZCBpbiBhIHNpbmdsZSBmaWxlICh0aGF0CiAgICAgKiBpcywgYSBzaW5nbGUgY29tcGlsYXRpb24gdW5pdCksIHRoZSBuYW1lIG9mIHRoZSBmaWxlIHNob3VsZAogICAgICogY29ycmVzcG9uZCB0byB0aGUgbmFtZSBvZiB0aGUgcHJpbmNpcGFsIHRvcC1sZXZlbCB0eXBlICh0aGUKICAgICAqIHB1YmxpYyBvbmUsIGZvciBleGFtcGxlKS4KICAgICAqCiAgICAgKiA8cD5BIHNvdXJjZSBmaWxlIGNhbiBhbHNvIGJlIGNyZWF0ZWQgdG8gaG9sZCBpbmZvcm1hdGlvbiBhYm91dAogICAgICogYSBwYWNrYWdlLCBpbmNsdWRpbmcgcGFja2FnZSBhbm5vdGF0aW9ucy4gIFRvIGNyZWF0ZSBhIHNvdXJjZQogICAgICogZmlsZSBmb3IgYSBuYW1lZCBwYWNrYWdlLCBoYXZlIHRoZSB7QGNvZGUgbmFtZX0gYXJndW1lbnQgYmUgdGhlCiAgICAgKiBwYWNrYWdlJ3MgbmFtZSBmb2xsb3dlZCBieSB7QGNvZGUgIi5wYWNrYWdlLWluZm8ifTsgdG8gY3JlYXRlIGEKICAgICAqIHNvdXJjZSBmaWxlIGZvciBhbiB1bm5hbWVkIHBhY2thZ2UsIHVzZSB7QGNvZGUgInBhY2thZ2UtaW5mbyJ9LgogICAgICoKICAgICAqIDxwPlRoZSBvcHRpb25hbCBtb2R1bGUgbmFtZSBpcyBwcmVmaXhlZCB0byB0aGUgdHlwZSBuYW1lIG9yCiAgICAgKiBwYWNrYWdlIG5hbWUgYW5kIHNlcGFyYXRlZCB1c2luZyBhICJ7QGNvZGUgL30iIGNoYXJhY3Rlci4gRm9yCiAgICAgKiBleGFtcGxlLCB0byBjcmVhdGUgYSBzb3VyY2UgZmlsZSBmb3IgdHlwZSB7QGNvZGUgYS5CfSBpbiBtb2R1bGUKICAgICAqIHtAY29kZSBmb299LCB1c2UgYSB7QGNvZGUgbmFtZX0gYXJndW1lbnQgb2Yge0Bjb2RlICJmb28vYS5CIn0uCiAgICAgKgogICAgICogPHA+Q3JlYXRpbmcgYSBzb3VyY2UgZmlsZSBpbiBvciBmb3IgYW4gdW5uYW1lZCBwYWNrYWdlIGluIGEgbmFtZWQKICAgICAqIG1vZHVsZSBpcyA8ZW0+bm90PC9lbT4gc3VwcG9ydGVkLgogICAgICoKICAgICAqIEBhcGlOb3RlIFRvIHVzZSBhIHBhcnRpY3VsYXIge0BsaW5rcGxhaW4KICAgICAqIGphdmEubmlvLmNoYXJzZXQuQ2hhcnNldCBjaGFyc2V0fSB0byBlbmNvZGUgdGhlIGNvbnRlbnRzIG9mIHRoZQogICAgICogZmlsZSwgYW4ge0Bjb2RlIE91dHB1dFN0cmVhbVdyaXRlcn0gd2l0aCB0aGUgY2hvc2VuIGNoYXJzZXQgY2FuCiAgICAgKiBiZSBjcmVhdGVkIGZyb20gdGhlIHtAY29kZSBPdXRwdXRTdHJlYW19IGZyb20gdGhlIHJldHVybmVkCiAgICAgKiBvYmplY3QuIElmIHRoZSB7QGNvZGUgV3JpdGVyfSBmcm9tIHRoZSByZXR1cm5lZCBvYmplY3QgaXMKICAgICAqIGRpcmVjdGx5IHVzZWQgZm9yIHdyaXRpbmcsIGl0cyBjaGFyc2V0IGlzIGRldGVybWluZWQgYnkgdGhlCiAgICAgKiBpbXBsZW1lbnRhdGlvbi4gIEFuIGFubm90YXRpb24gcHJvY2Vzc2luZyB0b29sIG1heSBoYXZlIGFuCiAgICAgKiB7QGNvZGUgLWVuY29kaW5nfSBmbGFnIG9yIGFuYWxvZ291cyBvcHRpb24gZm9yIHNwZWNpZnlpbmcgdGhpczsKICAgICAqIG90aGVyd2lzZSwgaXQgd2lsbCB0eXBpY2FsbHkgYmUgdGhlIHBsYXRmb3JtJ3MgZGVmYXVsdAogICAgICogZW5jb2RpbmcuCiAgICAgKgogICAgICogPHA+VG8gYXZvaWQgc3Vic2VxdWVudCBlcnJvcnMsIHRoZSBjb250ZW50cyBvZiB0aGUgc291cmNlIGZpbGUKICAgICAqIHNob3VsZCBiZSBjb21wYXRpYmxlIHdpdGggdGhlIHtAbGlua3BsYWluCiAgICAgKiBQcm9jZXNzaW5nRW52aXJvbm1lbnQjZ2V0U291cmNlVmVyc2lvbiBzb3VyY2UgdmVyc2lvbn0gYmVpbmcgdXNlZAogICAgICogZm9yIHRoaXMgcnVuLgogICAgICoKICAgICAqIEBwYXJhbSBuYW1lICBjYW5vbmljYWwgKGZ1bGx5IHF1YWxpZmllZCkgbmFtZSBvZiB0aGUgcHJpbmNpcGFsIHR5cGUKICAgICAqICAgICAgICAgIGJlaW5nIGRlY2xhcmVkIGluIHRoaXMgZmlsZSBvciBhIHBhY2thZ2UgbmFtZSBmb2xsb3dlZCBieQogICAgICogICAgICAgICAge0Bjb2RlICIucGFja2FnZS1pbmZvIn0gZm9yIGEgcGFja2FnZSBpbmZvcm1hdGlvbiBmaWxlCiAgICAgKiBAcGFyYW0gb3JpZ2luYXRpbmdFbGVtZW50cyB0eXBlIG9yIHBhY2thZ2Ugb3IgbW9kdWxlIGVsZW1lbnRzIGNhdXNhbGx5CiAgICAgKiBhc3NvY2lhdGVkIHdpdGggdGhlIGNyZWF0aW9uIG9mIHRoaXMgZmlsZSwgbWF5IGJlIGVsaWRlZCBvcgogICAgICoge0Bjb2RlIG51bGx9CiAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIEphdmFGaWxlT2JqZWN0fSB0byB3cml0ZSB0aGUgbmV3IHNvdXJjZSBmaWxlCiAgICAgKiBAdGhyb3dzIEZpbGVyRXhjZXB0aW9uIGlmIHRoZSBzYW1lIHBhdGhuYW1lIGhhcyBhbHJlYWR5IGJlZW4KICAgICAqIGNyZWF0ZWQsIHRoZSBzYW1lIHR5cGUgaGFzIGFscmVhZHkgYmVlbiBjcmVhdGVkLCBvciB0aGUgbmFtZSBpcwogICAgICogb3RoZXJ3aXNlIG5vdCB2YWxpZCBmb3IgdGhlIGVudGl0eSByZXF1ZXN0ZWQgdG8gYmVpbmcgY3JlYXRlZAogICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiB0aGUgZmlsZSBjYW5ub3QgYmUgY3JlYXRlZAogICAgICogQGpscyA3LjMgQ29tcGlsYXRpb24gVW5pdHMKICAgICAqLwogICAgSmF2YUZpbGVPYmplY3QgY3JlYXRlU291cmNlRmlsZShDaGFyU2VxdWVuY2UgbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRWxlbWVudC4uLiBvcmlnaW5hdGluZ0VsZW1lbnRzKSB0aHJvd3MgSU9FeGNlcHRpb247CgogICAgLyoqCiAgICAgKiBDcmVhdGVzIGEgbmV3IGNsYXNzIGZpbGUsIGFuZCByZXR1cm5zIGFuIG9iamVjdCB0byBhbGxvdwogICAgICogd3JpdGluZyB0byBpdC4gQSBjbGFzcyBmaWxlIGZvciBhIHR5cGUsIG9yIGEgcGFja2FnZSBjYW4KICAgICAqIGJlIGNyZWF0ZWQuCiAgICAgKgogICAgICogVGhlIGZpbGUncyBuYW1lIGFuZCBwYXRoIChyZWxhdGl2ZSB0byB0aGUge0BsaW5rcGxhaW4KICAgICAqIFN0YW5kYXJkTG9jYXRpb24jQ0xBU1NfT1VUUFVUIHJvb3Qgb3V0cHV0IGxvY2F0aW9uIGZvciBjbGFzcwogICAgICogZmlsZXN9KSBhcmUgYmFzZWQgb24gdGhlIG5hbWUgb2YgdGhlIGl0ZW0gdG8gYmUgZGVjbGFyZWQgYXMKICAgICAqIHdlbGwgYXMgdGhlIHNwZWNpZmllZCBtb2R1bGUgZm9yIHRoZSBpdGVtIChpZiBhbnkpLgogICAgICoKICAgICAqIDxwPkEgY2xhc3MgZmlsZSBjYW4gYWxzbyBiZSBjcmVhdGVkIHRvIGhvbGQgaW5mb3JtYXRpb24gYWJvdXQgYQogICAgICogcGFja2FnZSwgaW5jbHVkaW5nIHBhY2thZ2UgYW5ub3RhdGlvbnMuIFRvIGNyZWF0ZSBhIGNsYXNzIGZpbGUKICAgICAqIGZvciBhIG5hbWVkIHBhY2thZ2UsIGhhdmUgdGhlIHtAY29kZSBuYW1lfSBhcmd1bWVudCBiZSB0aGUKICAgICAqIHBhY2thZ2UncyBuYW1lIGZvbGxvd2VkIGJ5IHtAY29kZSAiLnBhY2thZ2UtaW5mbyJ9OyBjcmVhdGluZyBhCiAgICAgKiBjbGFzcyBmaWxlIGZvciBhbiB1bm5hbWVkIHBhY2thZ2UgaXMgbm90IHN1cHBvcnRlZC4KICAgICAqCiAgICAgKiA8cD5UaGUgb3B0aW9uYWwgbW9kdWxlIG5hbWUgaXMgcHJlZml4ZWQgdG8gdGhlIHR5cGUgbmFtZSBvcgogICAgICogcGFja2FnZSBuYW1lIGFuZCBzZXBhcmF0ZWQgdXNpbmcgYSAie0Bjb2RlIC99IiBjaGFyYWN0ZXIuIEZvcgogICAgICogZXhhbXBsZSwgdG8gY3JlYXRlIGEgY2xhc3MgZmlsZSBmb3IgdHlwZSB7QGNvZGUgYS5CfSBpbiBtb2R1bGUKICAgICAqIHtAY29kZSBmb299LCB1c2UgYSB7QGNvZGUgbmFtZX0gYXJndW1lbnQgb2Yge0Bjb2RlICJmb28vYS5CIn0uCiAgICAgKgogICAgICogPHA+Q3JlYXRpbmcgYSBjbGFzcyBmaWxlIGluIG9yIGZvciBhbiB1bm5hbWVkIHBhY2thZ2UgaW4gYSBuYW1lZAogICAgICogbW9kdWxlIGlzIDxlbT5ub3Q8L2VtPiBzdXBwb3J0ZWQuCiAgICAgKgogICAgICogQGFwaU5vdGUgVG8gYXZvaWQgc3Vic2VxdWVudCBlcnJvcnMsIHRoZSBjb250ZW50cyBvZiB0aGUgY2xhc3MKICAgICAqIGZpbGUgc2hvdWxkIGJlIGNvbXBhdGlibGUgd2l0aCB0aGUge0BsaW5rcGxhaW4KICAgICAqIFByb2Nlc3NpbmdFbnZpcm9ubWVudCNnZXRTb3VyY2VWZXJzaW9uIHNvdXJjZSB2ZXJzaW9ufSBiZWluZwogICAgICogdXNlZCBmb3IgdGhpcyBydW4uCiAgICAgKgogICAgICogQHBhcmFtIG5hbWUgYmluYXJ5IG5hbWUgb2YgdGhlIHR5cGUgYmVpbmcgd3JpdHRlbiBvciBhIHBhY2thZ2UgbmFtZSBmb2xsb3dlZCBieQogICAgICogICAgICAgICAge0Bjb2RlICIucGFja2FnZS1pbmZvIn0gZm9yIGEgcGFja2FnZSBpbmZvcm1hdGlvbiBmaWxlCiAgICAgKiBAcGFyYW0gb3JpZ2luYXRpbmdFbGVtZW50cyB0eXBlIG9yIHBhY2thZ2Ugb3IgbW9kdWxlIGVsZW1lbnRzIGNhdXNhbGx5CiAgICAgKiBhc3NvY2lhdGVkIHdpdGggdGhlIGNyZWF0aW9uIG9mIHRoaXMgZmlsZSwgbWF5IGJlIGVsaWRlZCBvcgogICAgICoge0Bjb2RlIG51bGx9CiAgICAgKiBAcmV0dXJuIGEge0Bjb2RlIEphdmFGaWxlT2JqZWN0fSB0byB3cml0ZSB0aGUgbmV3IGNsYXNzIGZpbGUKICAgICAqIEB0aHJvd3MgRmlsZXJFeGNlcHRpb24gaWYgdGhlIHNhbWUgcGF0aG5hbWUgaGFzIGFscmVhZHkgYmVlbgogICAgICogY3JlYXRlZCwgdGhlIHNhbWUgdHlwZSBoYXMgYWxyZWFkeSBiZWVuIGNyZWF0ZWQsIG9yIHRoZSBuYW1lIGlzCiAgICAgKiBub3QgdmFsaWQgZm9yIGEgdHlwZQogICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiB0aGUgZmlsZSBjYW5ub3QgYmUgY3JlYXRlZAogICAgICovCiAgICBKYXZhRmlsZU9iamVjdCBjcmVhdGVDbGFzc0ZpbGUoQ2hhclNlcXVlbmNlIG5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRWxlbWVudC4uLiBvcmlnaW5hdGluZ0VsZW1lbnRzKSB0aHJvd3MgSU9FeGNlcHRpb247CgogICAgLyoqCiAgICAgKiBDcmVhdGVzIGEgbmV3IGF1eGlsaWFyeSByZXNvdXJjZSBmaWxlIGZvciB3cml0aW5nIGFuZCByZXR1cm5zIGEKICAgICAqIGZpbGUgb2JqZWN0IGZvciBpdC4gIFRoZSBmaWxlIG1heSBiZSBsb2NhdGVkIGFsb25nIHdpdGggdGhlCiAgICAgKiBuZXdseSBjcmVhdGVkIHNvdXJjZSBmaWxlcywgbmV3bHkgY3JlYXRlZCBiaW5hcnkgZmlsZXMsIG9yCiAgICAgKiBvdGhlciBzdXBwb3J0ZWQgbG9jYXRpb24uICBUaGUgbG9jYXRpb25zIHtAbGluawogICAgICogU3RhbmRhcmRMb2NhdGlvbiNDTEFTU19PVVRQVVQgQ0xBU1NfT1VUUFVUfSBhbmQge0BsaW5rCiAgICAgKiBTdGFuZGFyZExvY2F0aW9uI1NPVVJDRV9PVVRQVVQgU09VUkNFX09VVFBVVH0gbXVzdCBiZQogICAgICogc3VwcG9ydGVkLiBUaGUgcmVzb3VyY2UgbWF5IGJlIG5hbWVkIHJlbGF0aXZlIHRvIHNvbWUgbW9kdWxlCiAgICAgKiBhbmQvb3IgcGFja2FnZSAoYXMgYXJlIHNvdXJjZSBhbmQgY2xhc3MgZmlsZXMpLCBhbmQgZnJvbSB0aGVyZQogICAgICogYnkgYSByZWxhdGl2ZSBwYXRobmFtZS4gIEluIGEgbG9vc2Ugc2Vuc2UsIHRoZSBmdWxsIHBhdGhuYW1lIG9mCiAgICAgKiB0aGUgbmV3IGZpbGUgd2lsbCBiZSB0aGUgY29uY2F0ZW5hdGlvbiBvZiB7QGNvZGUgbG9jYXRpb259LAogICAgICoge0Bjb2RlIG1vZHVsZUFuZFBrZ30sIGFuZCB7QGNvZGUgcmVsYXRpdmVOYW1lfS4KICAgICAqCiAgICAgKiBJZiB7QGNvZGUgbW9kdWxlQW5kUGtnfSBjb250YWlucyBhICJ7QGNvZGUgL30iIGNoYXJhY3RlciwgdGhlCiAgICAgKiBwcmVmaXggYmVmb3JlIHRoZSAie0Bjb2RlIC99IiBjaGFyYWN0ZXIgaXMgdGhlIG1vZHVsZSBuYW1lIGFuZAogICAgICogdGhlIHN1ZmZpeCBhZnRlciB0aGUgIntAY29kZSAvfSIgY2hhcmFjdGVyIGlzIHRoZSBwYWNrYWdlCiAgICAgKiBuYW1lLiBUaGUgcGFja2FnZSBzdWZmaXggbWF5IGJlIGVtcHR5LiBJZiB7QGNvZGUgbW9kdWxlQW5kUGtnfQogICAgICogZG9lcyBub3QgY29udGFpbiBhICJ7QGNvZGUgL30iIGNoYXJhY3RlciwgdGhlIGVudGlyZSBhcmd1bWVudAogICAgICogaXMgaW50ZXJwcmV0ZWQgYXMgYSBwYWNrYWdlIG5hbWUuCiAgICAgKgogICAgICogPHA+RmlsZXMgY3JlYXRlZCB2aWEgdGhpcyBtZXRob2QgYXJlIDxlbT5ub3Q8L2VtPiByZWdpc3RlcmVkIGZvcgogICAgICogYW5ub3RhdGlvbiBwcm9jZXNzaW5nLCBldmVuIGlmIHRoZSBmdWxsIHBhdGhuYW1lIG9mIHRoZSBmaWxlCiAgICAgKiB3b3VsZCBjb3JyZXNwb25kIHRvIHRoZSBmdWxsIHBhdGhuYW1lIG9mIGEgbmV3IHNvdXJjZSBmaWxlCiAgICAgKiBvciBuZXcgY2xhc3MgZmlsZS4KICAgICAqCiAgICAgKiBAcGFyYW0gbG9jYXRpb24gbG9jYXRpb24gb2YgdGhlIG5ldyBmaWxlCiAgICAgKiBAcGFyYW0gbW9kdWxlQW5kUGtnIG1vZHVsZSBhbmQvb3IgcGFja2FnZSByZWxhdGl2ZSB0byB3aGljaCB0aGUgZmlsZQogICAgICogICAgICAgICAgIHNob3VsZCBiZSBuYW1lZCwgb3IgdGhlIGVtcHR5IHN0cmluZyBpZiBub25lCiAgICAgKiBAcGFyYW0gcmVsYXRpdmVOYW1lIGZpbmFsIHBhdGhuYW1lIGNvbXBvbmVudHMgb2YgdGhlIGZpbGUKICAgICAqIEBwYXJhbSBvcmlnaW5hdGluZ0VsZW1lbnRzIHR5cGUgb3IgcGFja2FnZSBvciBtb2R1bGUgZWxlbWVudHMgY2F1c2FsbHkKICAgICAqIGFzc29jaWF0ZWQgd2l0aCB0aGUgY3JlYXRpb24gb2YgdGhpcyBmaWxlLCBtYXkgYmUgZWxpZGVkIG9yCiAgICAgKiB7QGNvZGUgbnVsbH0KICAgICAqIEByZXR1cm4gYSB7QGNvZGUgRmlsZU9iamVjdH0gdG8gd3JpdGUgdGhlIG5ldyByZXNvdXJjZQogICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiB0aGUgZmlsZSBjYW5ub3QgYmUgY3JlYXRlZAogICAgICogQHRocm93cyBGaWxlckV4Y2VwdGlvbiBpZiB0aGUgc2FtZSBwYXRobmFtZSBoYXMgYWxyZWFkeSBiZWVuCiAgICAgKiBjcmVhdGVkCiAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBmb3IgYW4gdW5zdXBwb3J0ZWQgbG9jYXRpb24KICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHtAY29kZSBtb2R1bGVBbmRQa2d9IGlzIGlsbC1mb3JtZWQKICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHtAY29kZSByZWxhdGl2ZU5hbWV9IGlzIG5vdCByZWxhdGl2ZQogICAgICovCiAgIEZpbGVPYmplY3QgY3JlYXRlUmVzb3VyY2UoSmF2YUZpbGVNYW5hZ2VyLkxvY2F0aW9uIGxvY2F0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIENoYXJTZXF1ZW5jZSBtb2R1bGVBbmRQa2csCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2hhclNlcXVlbmNlIHJlbGF0aXZlTmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFbGVtZW50Li4uIG9yaWdpbmF0aW5nRWxlbWVudHMpIHRocm93cyBJT0V4Y2VwdGlvbjsKCiAgICAvKioKICAgICAqIFJldHVybnMgYW4gb2JqZWN0IGZvciByZWFkaW5nIGFuIGV4aXN0aW5nIHJlc291cmNlLiAgVGhlCiAgICAgKiBsb2NhdGlvbnMge0BsaW5rIFN0YW5kYXJkTG9jYXRpb24jQ0xBU1NfT1VUUFVUIENMQVNTX09VVFBVVH0KICAgICAqIGFuZCB7QGxpbmsgU3RhbmRhcmRMb2NhdGlvbiNTT1VSQ0VfT1VUUFVUIFNPVVJDRV9PVVRQVVR9IG11c3QKICAgICAqIGJlIHN1cHBvcnRlZC4KICAgICAqCiAgICAgKiA8cD5JZiB7QGNvZGUgbW9kdWxlQW5kUGtnfSBjb250YWlucyBhICJ7QGNvZGUgL30iIGNoYXJhY3RlciwgdGhlCiAgICAgKiBwcmVmaXggYmVmb3JlIHRoZSAie0Bjb2RlIC99IiBjaGFyYWN0ZXIgaXMgdGhlIG1vZHVsZSBuYW1lIGFuZAogICAgICogdGhlIHN1ZmZpeCBhZnRlciB0aGUgIntAY29kZSAvfSIgY2hhcmFjdGVyIGlzIHRoZSBwYWNrYWdlCiAgICAgKiBuYW1lLiBUaGUgcGFja2FnZSBzdWZmaXggbWF5IGJlIGVtcHR5OyBob3dldmVyLCBpZiBhIG1vZHVsZQogICAgICogbmFtZSBpcyBwcmVzZW50LCBpdCBtdXN0IGJlIG5vbmVtcHR5LiBJZiB7QGNvZGUgbW9kdWxlQW5kUGtnfQogICAgICogZG9lcyBub3QgY29udGFpbiBhICJ7QGNvZGUgL30iIGNoYXJhY3RlciwgdGhlIGVudGlyZSBhcmd1bWVudAogICAgICogaXMgaW50ZXJwcmV0ZWQgYXMgYSBwYWNrYWdlIG5hbWUuCiAgICAgKgogICAgICogQHBhcmFtIGxvY2F0aW9uIGxvY2F0aW9uIG9mIHRoZSBmaWxlCiAgICAgKiBAcGFyYW0gbW9kdWxlQW5kUGtnIG1vZHVsZSBhbmQvb3IgcGFja2FnZSByZWxhdGl2ZSB0byB3aGljaCB0aGUgZmlsZQogICAgICogICAgICAgICAgc2hvdWxkIGJlIHNlYXJjaGVkIGZvciwgb3IgdGhlIGVtcHR5IHN0cmluZyBpZiBub25lCiAgICAgKiBAcGFyYW0gcmVsYXRpdmVOYW1lIGZpbmFsIHBhdGhuYW1lIGNvbXBvbmVudHMgb2YgdGhlIGZpbGUKICAgICAqIEByZXR1cm4gYW4gb2JqZWN0IHRvIHJlYWQgdGhlIGZpbGUKICAgICAqIEB0aHJvd3MgRmlsZXJFeGNlcHRpb24gaWYgdGhlIHNhbWUgcGF0aG5hbWUgaGFzIGFscmVhZHkgYmVlbgogICAgICogb3BlbmVkIGZvciB3cml0aW5nCiAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIHRoZSBmaWxlIGNhbm5vdCBiZSBvcGVuZWQKICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGZvciBhbiB1bnN1cHBvcnRlZCBsb2NhdGlvbgogICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYge0Bjb2RlIG1vZHVsZUFuZFBrZ30gaXMgaWxsLWZvcm1lZAogICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYge0Bjb2RlIHJlbGF0aXZlTmFtZX0gaXMgbm90IHJlbGF0aXZlCiAgICAgKi8KICAgIEZpbGVPYmplY3QgZ2V0UmVzb3VyY2UoSmF2YUZpbGVNYW5hZ2VyLkxvY2F0aW9uIGxvY2F0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICBDaGFyU2VxdWVuY2UgbW9kdWxlQW5kUGtnLAogICAgICAgICAgICAgICAgICAgICAgICAgICBDaGFyU2VxdWVuY2UgcmVsYXRpdmVOYW1lKSB0aHJvd3MgSU9FeGNlcHRpb247Cn0KUEsDBAoAAAgAANJ9TUofCQcUEQgAABEIAAA3AAAAamF2YXgvYW5ub3RhdGlvbi9wcm9jZXNzaW5nL1N1cHBvcnRlZFNvdXJjZVZlcnNpb24uamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAxMywgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBqYXZheC5hbm5vdGF0aW9uLnByb2Nlc3Npbmc7CgppbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uKjsKaW1wb3J0IHN0YXRpYyBqYXZhLmxhbmcuYW5ub3RhdGlvbi5SZXRlbnRpb25Qb2xpY3kuKjsKaW1wb3J0IHN0YXRpYyBqYXZhLmxhbmcuYW5ub3RhdGlvbi5FbGVtZW50VHlwZS4qOwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5Tb3VyY2VWZXJzaW9uOwoKCi8qKgogKiBBbiBhbm5vdGF0aW9uIHVzZWQgdG8gaW5kaWNhdGUgdGhlIGxhdGVzdCBzb3VyY2UgdmVyc2lvbiBhbgogKiBhbm5vdGF0aW9uIHByb2Nlc3NvciBzdXBwb3J0cy4gIFRoZSB7QGxpbmsKICogUHJvY2Vzc29yI2dldFN1cHBvcnRlZFNvdXJjZVZlcnNpb259IG1ldGhvZCBjYW4gY29uc3RydWN0IGl0cwogKiByZXN1bHQgZnJvbSB0aGUgdmFsdWUgb2YgdGhpcyBhbm5vdGF0aW9uLCBhcyBkb25lIGJ5IHtAbGluawogKiBBYnN0cmFjdFByb2Nlc3NvciNnZXRTdXBwb3J0ZWRTb3VyY2VWZXJzaW9ufS4KICoKICogQGF1dGhvciBKb3NlcGggRC4gRGFyY3kKICogQGF1dGhvciBTY290dCBTZWxpZ21hbgogKiBAYXV0aG9yIFBldGVyIHZvbiBkZXIgQWgmZWFjdXRlOwogKiBAc2luY2UgMS42CiAqLwpARG9jdW1lbnRlZApAVGFyZ2V0KFRZUEUpCkBSZXRlbnRpb24oUlVOVElNRSkKcHVibGljIEBpbnRlcmZhY2UgU3VwcG9ydGVkU291cmNlVmVyc2lvbiB7CiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGxhdGVzdCBzdXBwb3J0ZWQgc291cmNlIHZlcnNpb24uCiAgICAgKiBAcmV0dXJuIHRoZSBsYXRlc3Qgc3VwcG9ydGVkIHNvdXJjZSB2ZXJzaW9uCiAgICAgKi8KICAgIFNvdXJjZVZlcnNpb24gdmFsdWUoKTsKfQpQSwMECgAACAAABjupSmHGjzzEHwAAxB8AADEAAABqYXZheC9hbm5vdGF0aW9uL3Byb2Nlc3NpbmcvUm91bmRFbnZpcm9ubWVudC5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDA1LCAyMDE3LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGphdmF4LmFubm90YXRpb24ucHJvY2Vzc2luZzsKCmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuRWxlbWVudDsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC5UeXBlRWxlbWVudDsKaW1wb3J0IGphdmEudXRpbC5MaW5rZWRIYXNoU2V0OwppbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOwppbXBvcnQgamF2YS51dGlsLlNldDsKaW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLkFubm90YXRpb247CgovKioKICogQW4gYW5ub3RhdGlvbiBwcm9jZXNzaW5nIHRvb2wgZnJhbWV3b3JrIHdpbGwge0BsaW5rcGxhaW4KICogUHJvY2Vzc29yI3Byb2Nlc3MgcHJvdmlkZSBhbiBhbm5vdGF0aW9uIHByb2Nlc3NvciB3aXRoIGFuIG9iamVjdAogKiBpbXBsZW1lbnRpbmcgdGhpcyBpbnRlcmZhY2V9IHNvIHRoYXQgdGhlIHByb2Nlc3NvciBjYW4gcXVlcnkgZm9yCiAqIGluZm9ybWF0aW9uIGFib3V0IGEgcm91bmQgb2YgYW5ub3RhdGlvbiBwcm9jZXNzaW5nLgogKgogKiBAYXV0aG9yIEpvc2VwaCBELiBEYXJjeQogKiBAYXV0aG9yIFNjb3R0IFNlbGlnbWFuCiAqIEBhdXRob3IgUGV0ZXIgdm9uIGRlciBBaCZlYWN1dGU7CiAqIEBzaW5jZSAxLjYKICovCnB1YmxpYyBpbnRlcmZhY2UgUm91bmRFbnZpcm9ubWVudCB7CiAgICAvKioKICAgICAqIFJldHVybnMge0Bjb2RlIHRydWV9IGlmIHR5cGVzIGdlbmVyYXRlZCBieSB0aGlzIHJvdW5kIHdpbGwgbm90CiAgICAgKiBiZSBzdWJqZWN0IHRvIGEgc3Vic2VxdWVudCByb3VuZCBvZiBhbm5vdGF0aW9uIHByb2Nlc3Npbmc7CiAgICAgKiByZXR1cm5zIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgogICAgICoKICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHR5cGVzIGdlbmVyYXRlZCBieSB0aGlzIHJvdW5kIHdpbGwgbm90CiAgICAgKiBiZSBzdWJqZWN0IHRvIGEgc3Vic2VxdWVudCByb3VuZCBvZiBhbm5vdGF0aW9uIHByb2Nlc3Npbmc7CiAgICAgKiByZXR1cm5zIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlCiAgICAgKi8KICAgIGJvb2xlYW4gcHJvY2Vzc2luZ092ZXIoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMge0Bjb2RlIHRydWV9IGlmIGFuIGVycm9yIHdhcyByYWlzZWQgaW4gdGhlIHByaW9yIHJvdW5kCiAgICAgKiBvZiBwcm9jZXNzaW5nOyByZXR1cm5zIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgogICAgICoKICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIGFuIGVycm9yIHdhcyByYWlzZWQgaW4gdGhlIHByaW9yIHJvdW5kCiAgICAgKiBvZiBwcm9jZXNzaW5nOyByZXR1cm5zIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlCiAgICAgKi8KICAgIGJvb2xlYW4gZXJyb3JSYWlzZWQoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHtAbGlua3BsYWluIFByb2Nlc3NvciByb290IGVsZW1lbnRzfSBmb3IgYW5ub3RhdGlvbiBwcm9jZXNzaW5nIGdlbmVyYXRlZAogICAgICogYnkgdGhlIHByaW9yIHJvdW5kLgogICAgICoKICAgICAqIEByZXR1cm4gdGhlIHJvb3QgZWxlbWVudHMgZm9yIGFubm90YXRpb24gcHJvY2Vzc2luZyBnZW5lcmF0ZWQKICAgICAqIGJ5IHRoZSBwcmlvciByb3VuZCwgb3IgYW4gZW1wdHkgc2V0IGlmIHRoZXJlIHdlcmUgbm9uZQogICAgICovCiAgICBTZXQ8PyBleHRlbmRzIEVsZW1lbnQ+IGdldFJvb3RFbGVtZW50cygpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgZWxlbWVudHMgYW5ub3RhdGVkIHdpdGggdGhlIGdpdmVuIGFubm90YXRpb24gdHlwZS4KICAgICAqIFRoZSBhbm5vdGF0aW9uIG1heSBhcHBlYXIgZGlyZWN0bHkgb3IgYmUgaW5oZXJpdGVkLiAgT25seQogICAgICogcGFja2FnZSBlbGVtZW50cywgbW9kdWxlIGVsZW1lbnRzLCBhbmQgdHlwZSBlbGVtZW50cyA8aT5pbmNsdWRlZDwvaT4gaW4gdGhpcwogICAgICogcm91bmQgb2YgYW5ub3RhdGlvbiBwcm9jZXNzaW5nLCBvciBkZWNsYXJhdGlvbnMgb2YgbWVtYmVycywKICAgICAqIGNvbnN0cnVjdG9ycywgcGFyYW1ldGVycywgb3IgdHlwZSBwYXJhbWV0ZXJzIGRlY2xhcmVkIHdpdGhpbgogICAgICogdGhvc2UsIGFyZSByZXR1cm5lZC4gIEluY2x1ZGVkIHR5cGUgZWxlbWVudHMgYXJlIHtAbGlua3BsYWluCiAgICAgKiAjZ2V0Um9vdEVsZW1lbnRzIHJvb3QgdHlwZXN9IGFuZCBhbnkgbWVtYmVyIHR5cGVzIG5lc3RlZCB3aXRoaW4KICAgICAqIHRoZW0uICBFbGVtZW50cyBvZiBhIHBhY2thZ2UgYXJlIG5vdCBjb25zaWRlcmVkIGluY2x1ZGVkIHNpbXBseQogICAgICogYmVjYXVzZSBhIHtAY29kZSBwYWNrYWdlLWluZm99IGZpbGUgZm9yIHRoYXQgcGFja2FnZSB3YXMKICAgICAqIGNyZWF0ZWQuCiAgICAgKiBMaWtld2lzZSwgZWxlbWVudHMgb2YgYSBtb2R1bGUgYXJlIG5vdCBjb25zaWRlcmVkIGluY2x1ZGVkCiAgICAgKiBzaW1wbHkgYmVjYXVzZSBhIHtAY29kZSBtb2R1bGUtaW5mb30gZmlsZSBmb3IgdGhhdCBtb2R1bGUgd2FzCiAgICAgKiBjcmVhdGVkCiAgICAgKgogICAgICogQHBhcmFtIGEgIGFubm90YXRpb24gdHlwZSBiZWluZyByZXF1ZXN0ZWQKICAgICAqIEByZXR1cm4gdGhlIGVsZW1lbnRzIGFubm90YXRlZCB3aXRoIHRoZSBnaXZlbiBhbm5vdGF0aW9uIHR5cGUsCiAgICAgKiBvciBhbiBlbXB0eSBzZXQgaWYgdGhlcmUgYXJlIG5vbmUKICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHRoZSBhcmd1bWVudCBkb2VzIG5vdAogICAgICogcmVwcmVzZW50IGFuIGFubm90YXRpb24gdHlwZQogICAgICovCiAgICBTZXQ8PyBleHRlbmRzIEVsZW1lbnQ+IGdldEVsZW1lbnRzQW5ub3RhdGVkV2l0aChUeXBlRWxlbWVudCBhKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGVsZW1lbnRzIGFubm90YXRlZCB3aXRoIG9uZSBvciBtb3JlIG9mIHRoZSBnaXZlbgogICAgICogYW5ub3RhdGlvbiB0eXBlcy4KICAgICAqCiAgICAgKiBAYXBpTm90ZSBUaGlzIG1ldGhvZCBtYXkgYmUgdXNlZnVsIHdoZW4gcHJvY2Vzc2luZyByZXBlYXRpbmcKICAgICAqIGFubm90YXRpb25zIGJ5IGxvb2tpbmcgZm9yIGFuIGFubm90YXRpb24gdHlwZSBhbmQgaXRzCiAgICAgKiBjb250YWluaW5nIGFubm90YXRpb24gdHlwZSBhdCB0aGUgc2FtZSB0aW1lLgogICAgICoKICAgICAqIEBpbXBsU3BlYyBUaGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGlzIG1ldGhvZCBjcmVhdGVzIGFuCiAgICAgKiBlbXB0eSByZXN1bHQgc2V0LCBpdGVyYXRlcyBvdmVyIHRoZSBhbm5vdGF0aW9ucyBpbiB0aGUgYXJndW1lbnQKICAgICAqIGFycmF5IGNhbGxpbmcge0BsaW5rICNnZXRFbGVtZW50c0Fubm90YXRlZFdpdGgoVHlwZUVsZW1lbnQpfSBvbgogICAgICogZWFjaCBhbm5vdGF0aW9uIGFuZCBhZGRpbmcgdGhvc2UgcmVzdWx0cyB0byB0aGUgcmVzdWx0CiAgICAgKiBzZXQuIEZpbmFsbHksIHRoZSBjb250ZW50cyBvZiB0aGUgcmVzdWx0IHNldCBhcmUgcmV0dXJuZWQgYXMgYW4KICAgICAqIHVubW9kaWZpYWJsZSBzZXQuCiAgICAgKgogICAgICogQHBhcmFtIGFubm90YXRpb25zICBhbm5vdGF0aW9uIHR5cGVzIGJlaW5nIHJlcXVlc3RlZAogICAgICogQHJldHVybiB0aGUgZWxlbWVudHMgYW5ub3RhdGVkIHdpdGggb25lIG9yIG1vcmUgb2YgdGhlIGdpdmVuCiAgICAgKiBhbm5vdGF0aW9uIHR5cGVzLCBvciBhbiBlbXB0eSBzZXQgaWYgdGhlcmUgYXJlIG5vbmUKICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHRoZSBhbnkgZWxlbWVudHMgb2YgdGhlCiAgICAgKiBhcmd1bWVudCBzZXQgZG8gbm90IHJlcHJlc2VudCBhbiBhbm5vdGF0aW9uIHR5cGUKICAgICAqIEBqbHMgOS42LjMgUmVwZWF0YWJsZSBBbm5vdGF0aW9uIFR5cGVzCiAgICAgKiBAc2luY2UgOQogICAgICovCiAgICBkZWZhdWx0IFNldDw/IGV4dGVuZHMgRWxlbWVudD4gZ2V0RWxlbWVudHNBbm5vdGF0ZWRXaXRoQW55KFR5cGVFbGVtZW50Li4uIGFubm90YXRpb25zKXsKICAgICAgICAvLyBVc2UgTGlua2VkSGFzaFNldCByYXRoZXIgdGhhbiBIYXNoU2V0IGZvciBwcmVkaWN0YWJpbGl0eQogICAgICAgIFNldDxFbGVtZW50PiByZXN1bHQgPSBuZXcgTGlua2VkSGFzaFNldDw+KCk7CiAgICAgICAgZm9yIChUeXBlRWxlbWVudCBhbm5vdGF0aW9uIDogYW5ub3RhdGlvbnMpIHsKICAgICAgICAgICAgcmVzdWx0LmFkZEFsbChnZXRFbGVtZW50c0Fubm90YXRlZFdpdGgoYW5ub3RhdGlvbikpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlU2V0KHJlc3VsdCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBlbGVtZW50cyBhbm5vdGF0ZWQgd2l0aCB0aGUgZ2l2ZW4gYW5ub3RhdGlvbiB0eXBlLgogICAgICogVGhlIGFubm90YXRpb24gbWF5IGFwcGVhciBkaXJlY3RseSBvciBiZSBpbmhlcml0ZWQuICBPbmx5CiAgICAgKiBwYWNrYWdlIGVsZW1lbnRzLCBtb2R1bGUgZWxlbWVudHMsIGFuZCB0eXBlIGVsZW1lbnRzIDxpPmluY2x1ZGVkPC9pPiBpbiB0aGlzCiAgICAgKiByb3VuZCBvZiBhbm5vdGF0aW9uIHByb2Nlc3NpbmcsIG9yIGRlY2xhcmF0aW9ucyBvZiBtZW1iZXJzLAogICAgICogY29uc3RydWN0b3JzLCBwYXJhbWV0ZXJzLCBvciB0eXBlIHBhcmFtZXRlcnMgZGVjbGFyZWQgd2l0aGluCiAgICAgKiB0aG9zZSwgYXJlIHJldHVybmVkLiAgSW5jbHVkZWQgdHlwZSBlbGVtZW50cyBhcmUge0BsaW5rcGxhaW4KICAgICAqICNnZXRSb290RWxlbWVudHMgcm9vdCB0eXBlc30gYW5kIGFueSBtZW1iZXIgdHlwZXMgbmVzdGVkIHdpdGhpbgogICAgICogdGhlbS4gIEVsZW1lbnRzIGluIGEgcGFja2FnZSBhcmUgbm90IGNvbnNpZGVyZWQgaW5jbHVkZWQgc2ltcGx5CiAgICAgKiBiZWNhdXNlIGEge0Bjb2RlIHBhY2thZ2UtaW5mb30gZmlsZSBmb3IgdGhhdCBwYWNrYWdlIHdhcwogICAgICogY3JlYXRlZC4KICAgICAqIExpa2V3aXNlLCBlbGVtZW50cyBvZiBhIG1vZHVsZSBhcmUgbm90IGNvbnNpZGVyZWQgaW5jbHVkZWQKICAgICAqIHNpbXBseSBiZWNhdXNlIGEge0Bjb2RlIG1vZHVsZS1pbmZvfSBmaWxlIGZvciB0aGF0IG1vZHVsZSB3YXMKICAgICAqIGNyZWF0ZWQKICAgICAqCiAgICAgKiBAcGFyYW0gYSAgYW5ub3RhdGlvbiB0eXBlIGJlaW5nIHJlcXVlc3RlZAogICAgICogQHJldHVybiB0aGUgZWxlbWVudHMgYW5ub3RhdGVkIHdpdGggdGhlIGdpdmVuIGFubm90YXRpb24gdHlwZSwKICAgICAqIG9yIGFuIGVtcHR5IHNldCBpZiB0aGVyZSBhcmUgbm9uZQogICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgdGhlIGFyZ3VtZW50IGRvZXMgbm90CiAgICAgKiByZXByZXNlbnQgYW4gYW5ub3RhdGlvbiB0eXBlCiAgICAgKi8KICAgIFNldDw/IGV4dGVuZHMgRWxlbWVudD4gZ2V0RWxlbWVudHNBbm5vdGF0ZWRXaXRoKENsYXNzPD8gZXh0ZW5kcyBBbm5vdGF0aW9uPiBhKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGVsZW1lbnRzIGFubm90YXRlZCB3aXRoIG9uZSBvciBtb3JlIG9mIHRoZSBnaXZlbgogICAgICogYW5ub3RhdGlvbiB0eXBlcy4KICAgICAqCiAgICAgKiBAYXBpTm90ZSBUaGlzIG1ldGhvZCBtYXkgYmUgdXNlZnVsIHdoZW4gcHJvY2Vzc2luZyByZXBlYXRpbmcKICAgICAqIGFubm90YXRpb25zIGJ5IGxvb2tpbmcgZm9yIGFuIGFubm90YXRpb24gdHlwZSBhbmQgaXRzCiAgICAgKiBjb250YWluaW5nIGFubm90YXRpb24gdHlwZSBhdCB0aGUgc2FtZSB0aW1lLgogICAgICoKICAgICAqIEBpbXBsU3BlYyBUaGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGlzIG1ldGhvZCBjcmVhdGVzIGFuCiAgICAgKiBlbXB0eSByZXN1bHQgc2V0LCBpdGVyYXRlcyBvdmVyIHRoZSBhbm5vdGF0aW9ucyBpbiB0aGUgYXJndW1lbnQKICAgICAqIHNldCBjYWxsaW5nIHtAbGluayAjZ2V0RWxlbWVudHNBbm5vdGF0ZWRXaXRoKENsYXNzKX0gb24KICAgICAqIGVhY2ggYW5ub3RhdGlvbiBhbmQgYWRkaW5nIHRob3NlIHJlc3VsdHMgdG8gdGhlIHJlc3VsdAogICAgICogc2V0LiBGaW5hbGx5LCB0aGUgY29udGVudHMgb2YgdGhlIHJlc3VsdCBzZXQgYXJlIHJldHVybmVkIGFzIGFuCiAgICAgKiB1bm1vZGlmaWFibGUgc2V0LgogICAgICoKICAgICAqIEBwYXJhbSBhbm5vdGF0aW9ucyAgYW5ub3RhdGlvbiB0eXBlcyBiZWluZyByZXF1ZXN0ZWQKICAgICAqIEByZXR1cm4gdGhlIGVsZW1lbnRzIGFubm90YXRlZCB3aXRoIG9uZSBvciBtb3JlIG9mIHRoZSBnaXZlbgogICAgICogYW5ub3RhdGlvbiB0eXBlcywgb3IgYW4gZW1wdHkgc2V0IGlmIHRoZXJlIGFyZSBub25lCiAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgYW55IGVsZW1lbnRzIG9mIHRoZQogICAgICogYXJndW1lbnQgc2V0IGRvIG5vdCByZXByZXNlbnQgYW4gYW5ub3RhdGlvbiB0eXBlCiAgICAgKiBAamxzIDkuNi4zIFJlcGVhdGFibGUgQW5ub3RhdGlvbiBUeXBlcwogICAgICogQHNpbmNlIDkKICAgICAqLwogICAgZGVmYXVsdCBTZXQ8PyBleHRlbmRzIEVsZW1lbnQ+IGdldEVsZW1lbnRzQW5ub3RhdGVkV2l0aEFueShTZXQ8Q2xhc3M8PyBleHRlbmRzIEFubm90YXRpb24+PiBhbm5vdGF0aW9ucyl7CiAgICAgICAgLy8gVXNlIExpbmtlZEhhc2hTZXQgcmF0aGVyIHRoYW4gSGFzaFNldCBmb3IgcHJlZGljdGFiaWxpdHkKICAgICAgICBTZXQ8RWxlbWVudD4gcmVzdWx0ID0gbmV3IExpbmtlZEhhc2hTZXQ8PigpOwogICAgICAgIGZvciAoQ2xhc3M8PyBleHRlbmRzIEFubm90YXRpb24+IGFubm90YXRpb24gOiBhbm5vdGF0aW9ucykgewogICAgICAgICAgICByZXN1bHQuYWRkQWxsKGdldEVsZW1lbnRzQW5ub3RhdGVkV2l0aChhbm5vdGF0aW9uKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVTZXQocmVzdWx0KTsKICAgIH0KfQpQSwMECgAACAAABjupSlyM6zRGCAAARggAAC8AAABqYXZheC9hbm5vdGF0aW9uL3Byb2Nlc3NpbmcvRmlsZXJFeGNlcHRpb24uamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAxNywgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBqYXZheC5hbm5vdGF0aW9uLnByb2Nlc3Npbmc7CgppbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKCi8qKgogKiBJbmRpY2F0ZXMgYSB7QGxpbmsgRmlsZXJ9IGRldGVjdGVkIGFuIGF0dGVtcHQgdG8gb3BlbiBhIGZpbGUgdGhhdAogKiB3b3VsZCB2aW9sYXRlIHRoZSBndWFyYW50ZWVzIHByb3ZpZGVkIGJ5IHRoZSB7QGNvZGUgRmlsZXJ9LiAgVGhvc2UKICogZ3VhcmFudGVlcyBpbmNsdWRlIG5vdCBjcmVhdGluZyB0aGUgc2FtZSBmaWxlIG1vcmUgdGhhbiBvbmNlLCBub3QKICogY3JlYXRpbmcgbXVsdGlwbGUgZmlsZXMgY29ycmVzcG9uZGluZyB0byB0aGUgc2FtZSB0eXBlIG9yIHBhY2thZ2UsIGFuZCBub3QKICogY3JlYXRpbmcgZmlsZXMgZm9yIHR5cGVzIHdpdGggaW52YWxpZCBuYW1lcy4KICoKICogQGF1dGhvciBKb3NlcGggRC4gRGFyY3kKICogQGF1dGhvciBTY290dCBTZWxpZ21hbgogKiBAYXV0aG9yIFBldGVyIHZvbiBkZXIgQWgmZWFjdXRlOwogKiBAc2luY2UgMS42CiAqLwpwdWJsaWMgY2xhc3MgRmlsZXJFeGNlcHRpb24gZXh0ZW5kcyBJT0V4Y2VwdGlvbiB7CiAgICBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gODQyNjQyMzEwNjQ1MzE2MzI5M0w7CiAgICAvKioKICAgICAqIENvbnN0cnVjdHMgYW4gZXhjZXB0aW9uIHdpdGggdGhlIHNwZWNpZmllZCBkZXRhaWwgbWVzc2FnZS4KICAgICAqIEBwYXJhbSBzIHRoZSBkZXRhaWwgbWVzc2FnZSwgd2hpY2ggc2hvdWxkIGluY2x1ZGUgdGhlIG5hbWUgb2YKICAgICAqIHRoZSBmaWxlIGF0dGVtcHRpbmcgdG8gYmUgb3BlbmVkOyBtYXkgYmUge0Bjb2RlIG51bGx9CiAgICAgKi8KICAgIHB1YmxpYyBGaWxlckV4Y2VwdGlvbihTdHJpbmcgcykgewogICAgICAgIHN1cGVyKHMpOwogICAgfQp9ClBLAwQKAAAIAAAGO6lKD+aLKIAhAACAIQAAMgAAAGphdmF4L2Fubm90YXRpb24vcHJvY2Vzc2luZy9BYnN0cmFjdFByb2Nlc3Nvci5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDA1LCAyMDE3LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGphdmF4LmFubm90YXRpb24ucHJvY2Vzc2luZzsKCmltcG9ydCBqYXZhLnV0aWwuU2V0OwppbXBvcnQgamF2YS51dGlsLkhhc2hTZXQ7CmltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbnM7CmltcG9ydCBqYXZhLnV0aWwuT2JqZWN0czsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC4qOwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5Tb3VyY2VWZXJzaW9uOwppbXBvcnQgamF2YXgudG9vbHMuRGlhZ25vc3RpYzsKCi8qKgogKiBBbiBhYnN0cmFjdCBhbm5vdGF0aW9uIHByb2Nlc3NvciBkZXNpZ25lZCB0byBiZSBhIGNvbnZlbmllbnQKICogc3VwZXJjbGFzcyBmb3IgbW9zdCBjb25jcmV0ZSBhbm5vdGF0aW9uIHByb2Nlc3NvcnMuICBUaGlzIGNsYXNzCiAqIGV4YW1pbmVzIGFubm90YXRpb24gdmFsdWVzIHRvIGNvbXB1dGUgdGhlIHtAbGlua3BsYWluCiAqICNnZXRTdXBwb3J0ZWRPcHRpb25zIG9wdGlvbnN9LCB7QGxpbmtwbGFpbgogKiAjZ2V0U3VwcG9ydGVkQW5ub3RhdGlvblR5cGVzIGFubm90YXRpb24gdHlwZXN9LCBhbmQge0BsaW5rcGxhaW4KICogI2dldFN1cHBvcnRlZFNvdXJjZVZlcnNpb24gc291cmNlIHZlcnNpb259IHN1cHBvcnRlZCBieSBpdHMKICogc3VidHlwZXMuCiAqCiAqIDxwPlRoZSBnZXR0ZXIgbWV0aG9kcyBtYXkge0BsaW5rcGxhaW4gTWVzc2FnZXIjcHJpbnRNZXNzYWdlIGlzc3VlCiAqIHdhcm5pbmdzfSBhYm91dCBub3Rld29ydGh5IGNvbmRpdGlvbnMgdXNpbmcgdGhlIGZhY2lsaXRpZXMgYXZhaWxhYmxlCiAqIGFmdGVyIHRoZSBwcm9jZXNzb3IgaGFzIGJlZW4ge0BsaW5rcGxhaW4gI2lzSW5pdGlhbGl6ZWQKICogaW5pdGlhbGl6ZWR9LgogKgogKiA8cD5TdWJjbGFzc2VzIGFyZSBmcmVlIHRvIG92ZXJyaWRlIHRoZSBpbXBsZW1lbnRhdGlvbiBhbmQKICogc3BlY2lmaWNhdGlvbiBvZiBhbnkgb2YgdGhlIG1ldGhvZHMgaW4gdGhpcyBjbGFzcyBhcyBsb25nIGFzIHRoZQogKiBnZW5lcmFsIHtAbGluayBqYXZheC5hbm5vdGF0aW9uLnByb2Nlc3NpbmcuUHJvY2Vzc29yIFByb2Nlc3Nvcn0KICogY29udHJhY3QgZm9yIHRoYXQgbWV0aG9kIGlzIG9iZXllZC4KICoKICogQGF1dGhvciBKb3NlcGggRC4gRGFyY3kKICogQGF1dGhvciBTY290dCBTZWxpZ21hbgogKiBAYXV0aG9yIFBldGVyIHZvbiBkZXIgQWgmZWFjdXRlOwogKiBAc2luY2UgMS42CiAqLwpwdWJsaWMgYWJzdHJhY3QgY2xhc3MgQWJzdHJhY3RQcm9jZXNzb3IgaW1wbGVtZW50cyBQcm9jZXNzb3IgewogICAgLyoqCiAgICAgKiBQcm9jZXNzaW5nIGVudmlyb25tZW50IHByb3ZpZGluZyBieSB0aGUgdG9vbCBmcmFtZXdvcmsuCiAgICAgKi8KICAgIHByb3RlY3RlZCBQcm9jZXNzaW5nRW52aXJvbm1lbnQgcHJvY2Vzc2luZ0VudjsKICAgIHByaXZhdGUgYm9vbGVhbiBpbml0aWFsaXplZCA9IGZhbHNlOwoKICAgIC8qKgogICAgICogQ29uc3RydWN0b3IgZm9yIHN1YmNsYXNzZXMgdG8gY2FsbC4KICAgICAqLwogICAgcHJvdGVjdGVkIEFic3RyYWN0UHJvY2Vzc29yKCkge30KCiAgICAvKioKICAgICAqIElmIHRoZSBwcm9jZXNzb3IgY2xhc3MgaXMgYW5ub3RhdGVkIHdpdGgge0BsaW5rCiAgICAgKiBTdXBwb3J0ZWRPcHRpb25zfSwgcmV0dXJuIGFuIHVubW9kaWZpYWJsZSBzZXQgd2l0aCB0aGUgc2FtZSBzZXQKICAgICAqIG9mIHN0cmluZ3MgYXMgdGhlIGFubm90YXRpb24uICBJZiB0aGUgY2xhc3MgaXMgbm90IHNvCiAgICAgKiBhbm5vdGF0ZWQsIGFuIGVtcHR5IHNldCBpcyByZXR1cm5lZC4KICAgICAqCiAgICAgKiBAcmV0dXJuIHRoZSBvcHRpb25zIHJlY29nbml6ZWQgYnkgdGhpcyBwcm9jZXNzb3IsIG9yIGFuIGVtcHR5CiAgICAgKiBzZXQgaWYgbm9uZQogICAgICovCiAgICBwdWJsaWMgU2V0PFN0cmluZz4gZ2V0U3VwcG9ydGVkT3B0aW9ucygpIHsKICAgICAgICBTdXBwb3J0ZWRPcHRpb25zIHNvID0gdGhpcy5nZXRDbGFzcygpLmdldEFubm90YXRpb24oU3VwcG9ydGVkT3B0aW9ucy5jbGFzcyk7CiAgICAgICAgaWYgIChzbyA9PSBudWxsKQogICAgICAgICAgICByZXR1cm4gQ29sbGVjdGlvbnMuZW1wdHlTZXQoKTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIHJldHVybiBhcnJheVRvU2V0KHNvLnZhbHVlKCksIGZhbHNlKTsKICAgIH0KCiAgICAvKioKICAgICAqIElmIHRoZSBwcm9jZXNzb3IgY2xhc3MgaXMgYW5ub3RhdGVkIHdpdGgge0BsaW5rCiAgICAgKiBTdXBwb3J0ZWRBbm5vdGF0aW9uVHlwZXN9LCByZXR1cm4gYW4gdW5tb2RpZmlhYmxlIHNldCB3aXRoIHRoZQogICAgICogc2FtZSBzZXQgb2Ygc3RyaW5ncyBhcyB0aGUgYW5ub3RhdGlvbi4gIElmIHRoZSBjbGFzcyBpcyBub3Qgc28KICAgICAqIGFubm90YXRlZCwgYW4gZW1wdHkgc2V0IGlzIHJldHVybmVkLgogICAgICoKICAgICAqIElmIHRoZSB7QGxpbmsgUHJvY2Vzc2luZ0Vudmlyb25tZW50I2dldFNvdXJjZVZlcnNpb24gc291cmNlCiAgICAgKiB2ZXJzaW9ufSBkb2VzIG5vdCBzdXBwb3J0IG1vZHVsZXMsIGluIG90aGVyIHdvcmRzIGlmIGl0IGlzIGxlc3MKICAgICAqIHRoYW4gb3IgZXF1YWwgdG8ge0BsaW5rIFNvdXJjZVZlcnNpb24jUkVMRUFTRV84IFJFTEVBU0VfOH0sCiAgICAgKiB0aGVuIGFueSBsZWFkaW5nIHtAbGluayBQcm9jZXNzb3IjZ2V0U3VwcG9ydGVkQW5ub3RhdGlvblR5cGVzCiAgICAgKiBtb2R1bGUgcHJlZml4ZXN9IGFyZSBzdHJpcHBlZCBmcm9tIHRoZSBuYW1lcy4KICAgICAqCiAgICAgKiBAcmV0dXJuIHRoZSBuYW1lcyBvZiB0aGUgYW5ub3RhdGlvbiB0eXBlcyBzdXBwb3J0ZWQgYnkgdGhpcwogICAgICogcHJvY2Vzc29yLCBvciBhbiBlbXB0eSBzZXQgaWYgbm9uZQogICAgICovCiAgICBwdWJsaWMgU2V0PFN0cmluZz4gZ2V0U3VwcG9ydGVkQW5ub3RhdGlvblR5cGVzKCkgewogICAgICAgICAgICBTdXBwb3J0ZWRBbm5vdGF0aW9uVHlwZXMgc2F0ID0gdGhpcy5nZXRDbGFzcygpLmdldEFubm90YXRpb24oU3VwcG9ydGVkQW5ub3RhdGlvblR5cGVzLmNsYXNzKTsKICAgICAgICAgICAgYm9vbGVhbiBpbml0aWFsaXplZCA9IGlzSW5pdGlhbGl6ZWQoKTsKICAgICAgICAgICAgaWYgIChzYXQgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgaWYgKGluaXRpYWxpemVkKQogICAgICAgICAgICAgICAgICAgIHByb2Nlc3NpbmdFbnYuZ2V0TWVzc2FnZXIoKS5wcmludE1lc3NhZ2UoRGlhZ25vc3RpYy5LaW5kLldBUk5JTkcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTm8gU3VwcG9ydGVkQW5ub3RhdGlvblR5cGVzIGFubm90YXRpb24gIiArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZm91bmQgb24gIiArIHRoaXMuZ2V0Q2xhc3MoKS5nZXROYW1lKCkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiwgcmV0dXJuaW5nIGFuIGVtcHR5IHNldC4iKTsKICAgICAgICAgICAgICAgIHJldHVybiBDb2xsZWN0aW9ucy5lbXB0eVNldCgpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgYm9vbGVhbiBzdHJpcE1vZHVsZVByZWZpeGVzID0KICAgICAgICAgICAgICAgICAgICAgICAgaW5pdGlhbGl6ZWQgJiYKICAgICAgICAgICAgICAgICAgICAgICAgcHJvY2Vzc2luZ0Vudi5nZXRTb3VyY2VWZXJzaW9uKCkuY29tcGFyZVRvKFNvdXJjZVZlcnNpb24uUkVMRUFTRV84KSA8PSAwOwogICAgICAgICAgICAgICAgcmV0dXJuIGFycmF5VG9TZXQoc2F0LnZhbHVlKCksIHN0cmlwTW9kdWxlUHJlZml4ZXMpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgIC8qKgogICAgICogSWYgdGhlIHByb2Nlc3NvciBjbGFzcyBpcyBhbm5vdGF0ZWQgd2l0aCB7QGxpbmsKICAgICAqIFN1cHBvcnRlZFNvdXJjZVZlcnNpb259LCByZXR1cm4gdGhlIHNvdXJjZSB2ZXJzaW9uIGluIHRoZQogICAgICogYW5ub3RhdGlvbi4gIElmIHRoZSBjbGFzcyBpcyBub3Qgc28gYW5ub3RhdGVkLCB7QGxpbmsKICAgICAqIFNvdXJjZVZlcnNpb24jUkVMRUFTRV82fSBpcyByZXR1cm5lZC4KICAgICAqCiAgICAgKiBAcmV0dXJuIHRoZSBsYXRlc3Qgc291cmNlIHZlcnNpb24gc3VwcG9ydGVkIGJ5IHRoaXMgcHJvY2Vzc29yCiAgICAgKi8KICAgIHB1YmxpYyBTb3VyY2VWZXJzaW9uIGdldFN1cHBvcnRlZFNvdXJjZVZlcnNpb24oKSB7CiAgICAgICAgU3VwcG9ydGVkU291cmNlVmVyc2lvbiBzc3YgPSB0aGlzLmdldENsYXNzKCkuZ2V0QW5ub3RhdGlvbihTdXBwb3J0ZWRTb3VyY2VWZXJzaW9uLmNsYXNzKTsKICAgICAgICBTb3VyY2VWZXJzaW9uIHN2ID0gbnVsbDsKICAgICAgICBpZiAoc3N2ID09IG51bGwpIHsKICAgICAgICAgICAgc3YgPSBTb3VyY2VWZXJzaW9uLlJFTEVBU0VfNjsKICAgICAgICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQoKSkKICAgICAgICAgICAgICAgIHByb2Nlc3NpbmdFbnYuZ2V0TWVzc2FnZXIoKS5wcmludE1lc3NhZ2UoRGlhZ25vc3RpYy5LaW5kLldBUk5JTkcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJObyBTdXBwb3J0ZWRTb3VyY2VWZXJzaW9uIGFubm90YXRpb24gIiArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJmb3VuZCBvbiAiICsgdGhpcy5nZXRDbGFzcygpLmdldE5hbWUoKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIsIHJldHVybmluZyAiICsgc3YgKyAiLiIpOwogICAgICAgIH0gZWxzZQogICAgICAgICAgICBzdiA9IHNzdi52YWx1ZSgpOwogICAgICAgIHJldHVybiBzdjsKICAgIH0KCgogICAgLyoqCiAgICAgKiBJbml0aWFsaXplcyB0aGUgcHJvY2Vzc29yIHdpdGggdGhlIHByb2Nlc3NpbmcgZW52aXJvbm1lbnQgYnkKICAgICAqIHNldHRpbmcgdGhlIHtAY29kZSBwcm9jZXNzaW5nRW52fSBmaWVsZCB0byB0aGUgdmFsdWUgb2YgdGhlCiAgICAgKiB7QGNvZGUgcHJvY2Vzc2luZ0Vudn0gYXJndW1lbnQuICBBbiB7QGNvZGUKICAgICAqIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbn0gd2lsbCBiZSB0aHJvd24gaWYgdGhpcyBtZXRob2QgaXMgY2FsbGVkCiAgICAgKiBtb3JlIHRoYW4gb25jZSBvbiB0aGUgc2FtZSBvYmplY3QuCiAgICAgKgogICAgICogQHBhcmFtIHByb2Nlc3NpbmdFbnYgZW52aXJvbm1lbnQgdG8gYWNjZXNzIGZhY2lsaXRpZXMgdGhlIHRvb2wgZnJhbWV3b3JrCiAgICAgKiBwcm92aWRlcyB0byB0aGUgcHJvY2Vzc29yCiAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB0aGlzIG1ldGhvZCBpcyBjYWxsZWQgbW9yZSB0aGFuIG9uY2UuCiAgICAgKi8KICAgIHB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBpbml0KFByb2Nlc3NpbmdFbnZpcm9ubWVudCBwcm9jZXNzaW5nRW52KSB7CiAgICAgICAgaWYgKGluaXRpYWxpemVkKQogICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJDYW5ub3QgY2FsbCBpbml0IG1vcmUgdGhhbiBvbmNlLiIpOwogICAgICAgIE9iamVjdHMucmVxdWlyZU5vbk51bGwocHJvY2Vzc2luZ0VudiwgIlRvb2wgcHJvdmlkZWQgbnVsbCBQcm9jZXNzaW5nRW52aXJvbm1lbnQiKTsKCiAgICAgICAgdGhpcy5wcm9jZXNzaW5nRW52ID0gcHJvY2Vzc2luZ0VudjsKICAgICAgICBpbml0aWFsaXplZCA9IHRydWU7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIHByb2Nlc3MoU2V0PD8gZXh0ZW5kcyBUeXBlRWxlbWVudD4gYW5ub3RhdGlvbnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJvdW5kRW52aXJvbm1lbnQgcm91bmRFbnYpOwoKICAgIC8qKgogICAgICogUmV0dXJucyBhbiBlbXB0eSBpdGVyYWJsZSBvZiBjb21wbGV0aW9ucy4KICAgICAqCiAgICAgKiBAcGFyYW0gZWxlbWVudCB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gYW5ub3RhdGlvbiB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gbWVtYmVyIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSB1c2VyVGV4dCB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBJdGVyYWJsZTw/IGV4dGVuZHMgQ29tcGxldGlvbj4gZ2V0Q29tcGxldGlvbnMoRWxlbWVudCBlbGVtZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBbm5vdGF0aW9uTWlycm9yIGFubm90YXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEV4ZWN1dGFibGVFbGVtZW50IG1lbWJlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHVzZXJUZXh0KSB7CiAgICAgICAgcmV0dXJuIENvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyBvYmplY3QgaGFzIGJlZW4ge0BsaW5rcGxhaW4gI2luaXQKICAgICAqIGluaXRpYWxpemVkfSwge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCiAgICAgKgogICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyBvYmplY3QgaGFzIGJlZW4gaW5pdGlhbGl6ZWQsCiAgICAgKiB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KICAgICAqLwogICAgcHJvdGVjdGVkIHN5bmNocm9uaXplZCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIGluaXRpYWxpemVkOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIFNldDxTdHJpbmc+IGFycmF5VG9TZXQoU3RyaW5nW10gYXJyYXksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gc3RyaXBNb2R1bGVQcmVmaXhlcykgewogICAgICAgIGFzc2VydCBhcnJheSAhPSBudWxsOwogICAgICAgIFNldDxTdHJpbmc+IHNldCA9IG5ldyBIYXNoU2V0PD4oYXJyYXkubGVuZ3RoKTsKICAgICAgICBmb3IgKFN0cmluZyBzIDogYXJyYXkpIHsKICAgICAgICAgICAgaWYgKHN0cmlwTW9kdWxlUHJlZml4ZXMpIHsKICAgICAgICAgICAgICAgIGludCBpbmRleCA9IHMuaW5kZXhPZignLycpOwogICAgICAgICAgICAgICAgaWYgKGluZGV4ICE9IC0xKQogICAgICAgICAgICAgICAgICAgIHMgPSBzLnN1YnN0cmluZyhpbmRleCArIDEpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHNldC5hZGQocyk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVTZXQoc2V0KTsKICAgIH0KfQpQSwMECgAACAAA0n1NSgAAAAAAAAAAAAAAAAsAAABqYXZheC9sYW5nL1BLAwQKAAAIAAAGO6lKAAAAAAAAAAAAAAAAEQAAAGphdmF4L2xhbmcvbW9kZWwvUEsDBAoAAAgAANJ9TUqss+48bgUAAG4FAAAeAAAAamF2YXgvbGFuZy9tb2RlbC9vdmVydmlldy5odG1sPCFET0NUWVBFIEhUTUwgUFVCTElDICItLy9XM0MvL0RURCBIVE1MIDMuMiBGaW5hbC8vRU4iPgo8IS0tCkNvcHlyaWdodCAoYykgMjAwNSwgMjAxMywgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgoKVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCnBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCgpUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCkZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQp2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAphY2NvbXBhbmllZCB0aGlzIGNvZGUpLgoKWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgoyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCkluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KClBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCm9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKcXVlc3Rpb25zLgotLT4KPGh0bWw+CjxoZWFkPgo8dGl0bGU+amF2YXgubGFuZy5tb2RlbDwvdGl0bGU+CjwvaGVhZD4KCjxib2R5IGJnY29sb3I9IndoaXRlIj4KClBhY2thZ2VzIHVzZWQgdG8gbW9kZWwgdmFyaW91cyBhc3BlY3RzIG9mIHRoZSBKYXZhIHByb2dyYW1taW5nIGxhbmd1YWdlLgoKQHNpbmNlIDEuNgoKPC9ib2R5Pgo8L2h0bWw+ClBLAwQKAAAIAADSfU1KPNyj2hYKAAAWCgAAIgAAAGphdmF4L2xhbmcvbW9kZWwvcGFja2FnZS1pbmZvLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMDYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCi8qKgogKiBDbGFzc2VzIGFuZCBoaWVyYXJjaGllcyBvZiBwYWNrYWdlcyB1c2VkIHRvIG1vZGVsIHRoZSBKYXZhCiAqIHByb2dyYW1taW5nIGxhbmd1YWdlLgogKgogKiBUaGUgbWVtYmVycyBvZiB0aGlzIHBhY2thZ2UgYW5kIGl0cyBzdWJwYWNrYWdlcyBhcmUgZm9yIHVzZSBpbgogKiBsYW5ndWFnZSBtb2RlbGluZyBhbmQgbGFuZ3VhZ2UgcHJvY2Vzc2luZyB0YXNrcyBhbmQgQVBJcyBpbmNsdWRpbmcsCiAqIGJ1dCBub3QgbGltaXRlZCB0bywgdGhlIHtAbGlua3BsYWluIGphdmF4LmFubm90YXRpb24ucHJvY2Vzc2luZwogKiBhbm5vdGF0aW9uIHByb2Nlc3Npbmd9IGZyYW1ld29yay4KICoKICogPHA+IFRoaXMgbGFuZ3VhZ2UgbW9kZWwgZm9sbG93cyBhIDxpPm1pcnJvcjwvaT4tYmFzZWQgZGVzaWduOyBzZWUKICoKICogPGJsb2NrcXVvdGU+CiAqIEdpbGFkIEJyYWNoYSBhbmQgRGF2aWQgVW5nYXIuIDxpPk1pcnJvcnM6IERlc2lnbiBQcmluY2lwbGVzIGZvcgogKiBNZXRhLWxldmVsIEZhY2lsaXRpZXMgb2YgT2JqZWN0LU9yaWVudGVkIFByb2dyYW1taW5nIExhbmd1YWdlczwvaT4uCiAqIEluIFByb2MuIG9mIHRoZSBBQ00gQ29uZi4gb24gT2JqZWN0LU9yaWVudGVkIFByb2dyYW1taW5nLCBTeXN0ZW1zLAogKiBMYW5ndWFnZXMgYW5kIEFwcGxpY2F0aW9ucywgT2N0b2JlciAyMDA0LgogKiA8L2Jsb2NrcXVvdGU+CiAqCiAqIEluIHBhcnRpY3VsYXIsIHRoZSBtb2RlbCBtYWtlcyBhIGRpc3RpbmN0aW9uIGJldHdlZW4gc3RhdGljCiAqIGxhbmd1YWdlIGNvbnN0cnVjdHMsIGxpa2UgdGhlIHtAbGlua3BsYWluIGphdmF4LmxhbmcubW9kZWwuZWxlbWVudAogKiBlbGVtZW50fSByZXByZXNlbnRpbmcge0Bjb2RlIGphdmEudXRpbC5TZXR9LCBhbmQgdGhlIGZhbWlseSBvZgogKiB7QGxpbmtwbGFpbiBqYXZheC5sYW5nLm1vZGVsLnR5cGUgdHlwZXN9IHRoYXQgbWF5IGJlIGFzc29jaWF0ZWQKICogd2l0aCBhbiBlbGVtZW50LCBsaWtlIHRoZSByYXcgdHlwZSB7QGNvZGUgamF2YS51dGlsLlNldH0sIHtAY29kZQogKiBqYXZhLnV0aWwuU2V0PFN0cmluZz59LCBhbmQge0Bjb2RlIGphdmEudXRpbC5TZXQ8VD59LgogKgogKiA8cD4gVW5sZXNzIG90aGVyd2lzZSBzcGVjaWZpZWQsIG1ldGhvZHMgaW4gdGhpcyBwYWNrYWdlIHdpbGwgdGhyb3cKICogYSB7QGNvZGUgTnVsbFBvaW50ZXJFeGNlcHRpb259IGlmIGdpdmVuIGEge0Bjb2RlIG51bGx9IGFyZ3VtZW50LgogKgogKiBAYXV0aG9yIEpvc2VwaCBELiBEYXJjeQogKiBAYXV0aG9yIFNjb3R0IFNlbGlnbWFuCiAqIEBhdXRob3IgUGV0ZXIgdm9uIGRlciBBaCZlYWN1dGU7CiAqIEBzaW5jZSAxLjYKICovCgpwYWNrYWdlIGphdmF4LmxhbmcubW9kZWw7ClBLAwQKAAAIAAAGO6lKAAAAAAAAAAAAAAAAFgAAAGphdmF4L2xhbmcvbW9kZWwvdHlwZS9QSwMECgAACAAA0n1NSpFFjAD/CwAA/wsAACcAAABqYXZheC9sYW5nL21vZGVsL3R5cGUvVHlwZVZhcmlhYmxlLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMTMsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgamF2YXgubGFuZy5tb2RlbC50eXBlOwoKCmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuRWxlbWVudDsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC5UeXBlUGFyYW1ldGVyRWxlbWVudDsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwudXRpbC5UeXBlczsKCgovKioKICogUmVwcmVzZW50cyBhIHR5cGUgdmFyaWFibGUuCiAqIEEgdHlwZSB2YXJpYWJsZSBtYXkgYmUgZXhwbGljaXRseSBkZWNsYXJlZCBieSBhCiAqIHtAbGlua3BsYWluIFR5cGVQYXJhbWV0ZXJFbGVtZW50IHR5cGUgcGFyYW1ldGVyfSBvZiBhCiAqIHR5cGUsIG1ldGhvZCwgb3IgY29uc3RydWN0b3IuCiAqIEEgdHlwZSB2YXJpYWJsZSBtYXkgYWxzbyBiZSBkZWNsYXJlZCBpbXBsaWNpdGx5LCBhcyBieQogKiB0aGUgY2FwdHVyZSBjb252ZXJzaW9uIG9mIGEgd2lsZGNhcmQgdHlwZSBhcmd1bWVudAogKiAoc2VlIGNoYXB0ZXIgNSBvZgogKiA8Y2l0ZT5UaGUgSmF2YSZ0cmFkZTsgTGFuZ3VhZ2UgU3BlY2lmaWNhdGlvbjwvY2l0ZT4pLgogKgogKiBAYXV0aG9yIEpvc2VwaCBELiBEYXJjeQogKiBAYXV0aG9yIFNjb3R0IFNlbGlnbWFuCiAqIEBhdXRob3IgUGV0ZXIgdm9uIGRlciBBaCZlYWN1dGU7CiAqIEBzZWUgVHlwZVBhcmFtZXRlckVsZW1lbnQKICogQHNpbmNlIDEuNgogKi8KcHVibGljIGludGVyZmFjZSBUeXBlVmFyaWFibGUgZXh0ZW5kcyBSZWZlcmVuY2VUeXBlIHsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGVsZW1lbnQgY29ycmVzcG9uZGluZyB0byB0aGlzIHR5cGUgdmFyaWFibGUuCiAgICAgKgogICAgICogQHJldHVybiB0aGUgZWxlbWVudCBjb3JyZXNwb25kaW5nIHRvIHRoaXMgdHlwZSB2YXJpYWJsZQogICAgICovCiAgICBFbGVtZW50IGFzRWxlbWVudCgpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgdXBwZXIgYm91bmQgb2YgdGhpcyB0eXBlIHZhcmlhYmxlLgogICAgICoKICAgICAqIDxwPiBJZiB0aGlzIHR5cGUgdmFyaWFibGUgd2FzIGRlY2xhcmVkIHdpdGggbm8gZXhwbGljaXQKICAgICAqIHVwcGVyIGJvdW5kcywgdGhlIHJlc3VsdCBpcyB7QGNvZGUgamF2YS5sYW5nLk9iamVjdH0uCiAgICAgKiBJZiBpdCB3YXMgZGVjbGFyZWQgd2l0aCBtdWx0aXBsZSB1cHBlciBib3VuZHMsCiAgICAgKiB0aGUgcmVzdWx0IGlzIGFuIHtAbGlua3BsYWluIEludGVyc2VjdGlvblR5cGUgaW50ZXJzZWN0aW9uIHR5cGV9OwogICAgICogaW5kaXZpZHVhbCBib3VuZHMgY2FuIGJlIGZvdW5kIGJ5IGV4YW1pbmluZyB0aGUgcmVzdWx0J3MKICAgICAqIHtAbGlua3BsYWluIEludGVyc2VjdGlvblR5cGUjZ2V0Qm91bmRzKCkgYm91bmRzfS4KICAgICAqCiAgICAgKiBAcmV0dXJuIHRoZSB1cHBlciBib3VuZCBvZiB0aGlzIHR5cGUgdmFyaWFibGUKICAgICAqLwogICAgVHlwZU1pcnJvciBnZXRVcHBlckJvdW5kKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBsb3dlciBib3VuZCBvZiB0aGlzIHR5cGUgdmFyaWFibGUuICBXaGlsZSBhIHR5cGUKICAgICAqIHBhcmFtZXRlciBjYW5ub3QgaW5jbHVkZSBhbiBleHBsaWNpdCBsb3dlciBib3VuZCBkZWNsYXJhdGlvbiwKICAgICAqIGNhcHR1cmUgY29udmVyc2lvbiBjYW4gcHJvZHVjZSBhIHR5cGUgdmFyaWFibGUgd2l0aCBhCiAgICAgKiBub24tdHJpdmlhbCBsb3dlciBib3VuZC4gIFR5cGUgdmFyaWFibGVzIG90aGVyd2lzZSBoYXZlIGEKICAgICAqIGxvd2VyIGJvdW5kIG9mIHtAbGluayBOdWxsVHlwZX0uCiAgICAgKgogICAgICogQHJldHVybiB0aGUgbG93ZXIgYm91bmQgb2YgdGhpcyB0eXBlIHZhcmlhYmxlCiAgICAgKi8KICAgIFR5cGVNaXJyb3IgZ2V0TG93ZXJCb3VuZCgpOwp9ClBLAwQKAAAIAAAGO6lKoxyf1m0QAABtEAAAJQAAAGphdmF4L2xhbmcvbW9kZWwvdHlwZS9UeXBlTWlycm9yLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMTcsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgamF2YXgubGFuZy5tb2RlbC50eXBlOwoKaW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLkFubm90YXRpb247CmltcG9ydCBqYXZhLnV0aWwuTGlzdDsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC4qOwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC51dGlsLlR5cGVzOwoKLyoqCiAqIFJlcHJlc2VudHMgYSB0eXBlIGluIHRoZSBKYXZhIHByb2dyYW1taW5nIGxhbmd1YWdlLgogKiBUeXBlcyBpbmNsdWRlIHByaW1pdGl2ZSB0eXBlcywgZGVjbGFyZWQgdHlwZXMgKGNsYXNzIGFuZCBpbnRlcmZhY2UgdHlwZXMpLAogKiBhcnJheSB0eXBlcywgdHlwZSB2YXJpYWJsZXMsIGFuZCB0aGUgbnVsbCB0eXBlLgogKiBBbHNvIHJlcHJlc2VudGVkIGFyZSB3aWxkY2FyZCB0eXBlIGFyZ3VtZW50cywgdGhlIHNpZ25hdHVyZSBhbmQKICogcmV0dXJuIHR5cGVzIG9mIGV4ZWN1dGFibGVzLCBhbmQgcHNldWRvLXR5cGVzIGNvcnJlc3BvbmRpbmcgdG8KICogcGFja2FnZXMsIG1vZHVsZXMsIGFuZCB0aGUga2V5d29yZCB7QGNvZGUgdm9pZH0uCiAqCiAqIDxwPiBUeXBlcyBzaG91bGQgYmUgY29tcGFyZWQgdXNpbmcgdGhlIHV0aWxpdHkgbWV0aG9kcyBpbiB7QGxpbmsKICogVHlwZXN9LiAgVGhlcmUgaXMgbm8gZ3VhcmFudGVlIHRoYXQgYW55IHBhcnRpY3VsYXIgdHlwZSB3aWxsIGFsd2F5cwogKiBiZSByZXByZXNlbnRlZCBieSB0aGUgc2FtZSBvYmplY3QuCiAqCiAqIDxwPiBUbyBpbXBsZW1lbnQgb3BlcmF0aW9ucyBiYXNlZCBvbiB0aGUgY2xhc3Mgb2YgYW4ge0Bjb2RlCiAqIFR5cGVNaXJyb3J9IG9iamVjdCwgZWl0aGVyIHVzZSBhIHtAbGlua3BsYWluIFR5cGVWaXNpdG9yIHZpc2l0b3J9CiAqIG9yIHVzZSB0aGUgcmVzdWx0IG9mIHRoZSB7QGxpbmsgI2dldEtpbmR9IG1ldGhvZC4gIFVzaW5nIHtAY29kZQogKiBpbnN0YW5jZW9mfSBpcyA8ZW0+bm90PC9lbT4gbmVjZXNzYXJpbHkgYSByZWxpYWJsZSBpZGlvbSBmb3IKICogZGV0ZXJtaW5pbmcgdGhlIGVmZmVjdGl2ZSBjbGFzcyBvZiBhbiBvYmplY3QgaW4gdGhpcyBtb2RlbGluZwogKiBoaWVyYXJjaHkgc2luY2UgYW4gaW1wbGVtZW50YXRpb24gbWF5IGNob29zZSB0byBoYXZlIGEgc2luZ2xlCiAqIG9iamVjdCBpbXBsZW1lbnQgbXVsdGlwbGUge0Bjb2RlIFR5cGVNaXJyb3J9IHN1YmludGVyZmFjZXMuCiAqCiAqIEBhdXRob3IgSm9zZXBoIEQuIERhcmN5CiAqIEBhdXRob3IgU2NvdHQgU2VsaWdtYW4KICogQGF1dGhvciBQZXRlciB2b24gZGVyIEFoJmVhY3V0ZTsKICogQHNlZSBFbGVtZW50CiAqIEBzZWUgVHlwZXMKICogQHNpbmNlIDEuNgogKi8KcHVibGljIGludGVyZmFjZSBUeXBlTWlycm9yIGV4dGVuZHMgamF2YXgubGFuZy5tb2RlbC5Bbm5vdGF0ZWRDb25zdHJ1Y3QgewoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUge0Bjb2RlIGtpbmR9IG9mIHRoaXMgdHlwZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIHRoZSBraW5kIG9mIHRoaXMgdHlwZQogICAgICovCiAgICBUeXBlS2luZCBnZXRLaW5kKCk7CgogICAgLyoqCiAgICAgKiBPYmV5cyB0aGUgZ2VuZXJhbCBjb250cmFjdCBvZiB7QGxpbmsgT2JqZWN0I2VxdWFscyBPYmplY3QuZXF1YWxzfS4KICAgICAqIFRoaXMgbWV0aG9kIGRvZXMgbm90LCBob3dldmVyLCBpbmRpY2F0ZSB3aGV0aGVyIHR3byB0eXBlcyByZXByZXNlbnQKICAgICAqIHRoZSBzYW1lIHR5cGUuCiAgICAgKiBTZW1hbnRpYyBjb21wYXJpc29ucyBvZiB0eXBlIGVxdWFsaXR5IHNob3VsZCBpbnN0ZWFkIHVzZQogICAgICoge0BsaW5rIFR5cGVzI2lzU2FtZVR5cGUoVHlwZU1pcnJvciwgVHlwZU1pcnJvcil9LgogICAgICogVGhlIHJlc3VsdHMgb2Yge0Bjb2RlIHQxLmVxdWFscyh0Mil9IGFuZAogICAgICoge0Bjb2RlIFR5cGVzLmlzU2FtZVR5cGUodDEsIHQyKX0gbWF5IGRpZmZlci4KICAgICAqCiAgICAgKiBAcGFyYW0gb2JqICB0aGUgb2JqZWN0IHRvIGJlIGNvbXBhcmVkIHdpdGggdGhpcyB0eXBlCiAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgc3BlY2lmaWVkIG9iamVjdCBpcyBlcXVhbCB0byB0aGlzIG9uZQogICAgICovCiAgICBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqKTsKCiAgICAvKioKICAgICAqIE9iZXlzIHRoZSBnZW5lcmFsIGNvbnRyYWN0IG9mIHtAbGluayBPYmplY3QjaGFzaENvZGUgT2JqZWN0Lmhhc2hDb2RlfS4KICAgICAqCiAgICAgKiBAc2VlICNlcXVhbHMKICAgICAqLwogICAgaW50IGhhc2hDb2RlKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGFuIGluZm9ybWF0aXZlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIHR5cGUuICBJZgogICAgICogcG9zc2libGUsIHRoZSBzdHJpbmcgc2hvdWxkIGJlIG9mIGEgZm9ybSBzdWl0YWJsZSBmb3IKICAgICAqIHJlcHJlc2VudGluZyB0aGlzIHR5cGUgaW4gc291cmNlIGNvZGUuICBBbnkgbmFtZXMgZW1iZWRkZWQgaW4KICAgICAqIHRoZSByZXN1bHQgYXJlIHF1YWxpZmllZCBpZiBwb3NzaWJsZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgdHlwZQogICAgICovCiAgICBTdHJpbmcgdG9TdHJpbmcoKTsKCiAgICAvKioKICAgICAqIEFwcGxpZXMgYSB2aXNpdG9yIHRvIHRoaXMgdHlwZS4KICAgICAqCiAgICAgKiBAcGFyYW0gPFI+IHRoZSByZXR1cm4gdHlwZSBvZiB0aGUgdmlzaXRvcidzIG1ldGhvZHMKICAgICAqIEBwYXJhbSA8UD4gdGhlIHR5cGUgb2YgdGhlIGFkZGl0aW9uYWwgcGFyYW1ldGVyIHRvIHRoZSB2aXNpdG9yJ3MgbWV0aG9kcwogICAgICogQHBhcmFtIHYgICB0aGUgdmlzaXRvciBvcGVyYXRpbmcgb24gdGhpcyB0eXBlCiAgICAgKiBAcGFyYW0gcCAgIGFkZGl0aW9uYWwgcGFyYW1ldGVyIHRvIHRoZSB2aXNpdG9yCiAgICAgKiBAcmV0dXJuIGEgdmlzaXRvci1zcGVjaWZpZWQgcmVzdWx0CiAgICAgKi8KICAgIDxSLCBQPiBSIGFjY2VwdChUeXBlVmlzaXRvcjxSLCBQPiB2LCBQIHApOwp9ClBLAwQKAAAIAAAGO6lKRm2E0HAGAABwBgAAJAAAAGphdmF4L2xhbmcvbW9kZWwvdHlwZS9VbmlvblR5cGUuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAxMCwgMjAxNywgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBqYXZheC5sYW5nLm1vZGVsLnR5cGU7CgppbXBvcnQgamF2YS51dGlsLkxpc3Q7CgovKioKICogUmVwcmVzZW50cyBhIHVuaW9uIHR5cGUuCiAqCiAqIFVuaW9uIHR5cGVzIGNhbiBhcHBlYXIgYXMgdGhlIHR5cGUgb2YgYSBtdWx0aS1jYXRjaCBleGNlcHRpb24KICogcGFyYW1ldGVyLgogKgogKiBAc2luY2UgMS43CiAqLwpwdWJsaWMgaW50ZXJmYWNlIFVuaW9uVHlwZSBleHRlbmRzIFR5cGVNaXJyb3IgewoKICAgIC8qKgogICAgICogUmV0dXJuIHRoZSBhbHRlcm5hdGl2ZXMgY29tcHJpc2luZyB0aGlzIHVuaW9uIHR5cGUuCiAgICAgKgogICAgICogQHJldHVybiB0aGUgYWx0ZXJuYXRpdmVzIGNvbXByaXNpbmcgdGhpcyB1bmlvbiB0eXBlLgogICAgICovCiAgICBMaXN0PD8gZXh0ZW5kcyBUeXBlTWlycm9yPiBnZXRBbHRlcm5hdGl2ZXMoKTsKfQpQSwMECgAACAAA0n1NSibuvxDuBgAA7gYAACcAAABqYXZheC9sYW5nL21vZGVsL3R5cGUvcGFja2FnZS1pbmZvLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMDYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCi8qKgogKiBJbnRlcmZhY2VzIHVzZWQgdG8gbW9kZWwgSmF2YSBwcm9ncmFtbWluZyBsYW5ndWFnZSB0eXBlcy4KICoKICogPHA+IFVubGVzcyBvdGhlcndpc2Ugc3BlY2lmaWVkIGluIGEgcGFydGljdWxhciBpbXBsZW1lbnRhdGlvbiwgdGhlCiAqIGNvbGxlY3Rpb25zIHJldHVybmVkIGJ5IG1ldGhvZHMgaW4gdGhpcyBwYWNrYWdlIHNob3VsZCBiZSBleHBlY3RlZAogKiB0byBiZSB1bm1vZGlmaWFibGUgYnkgdGhlIGNhbGxlciBhbmQgdW5zYWZlIGZvciBjb25jdXJyZW50IGFjY2Vzcy4KICoKICogPHA+IFVubGVzcyBvdGhlcndpc2Ugc3BlY2lmaWVkLCBtZXRob2RzIGluIHRoaXMgcGFja2FnZSB3aWxsIHRocm93CiAqIGEge0Bjb2RlIE51bGxQb2ludGVyRXhjZXB0aW9ufSBpZiBnaXZlbiBhIHtAY29kZSBudWxsfSBhcmd1bWVudC4KICoKICogQGF1dGhvciBKb3NlcGggRC4gRGFyY3kKICogQGF1dGhvciBTY290dCBTZWxpZ21hbgogKiBAYXV0aG9yIFBldGVyIHZvbiBkZXIgQWgmZWFjdXRlOwogKiBAc2luY2UgMS42CiAqLwpwYWNrYWdlIGphdmF4LmxhbmcubW9kZWwudHlwZTsKUEsDBAoAAAgAANJ9TUoVpzttNgYAADYGAAAoAAAAamF2YXgvbGFuZy9tb2RlbC90eXBlL1ByaW1pdGl2ZVR5cGUuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAwNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBqYXZheC5sYW5nLm1vZGVsLnR5cGU7CgoKLyoqCiAqIFJlcHJlc2VudHMgYSBwcmltaXRpdmUgdHlwZS4gIFRoZXNlIGluY2x1ZGUKICoge0Bjb2RlIGJvb2xlYW59LCB7QGNvZGUgYnl0ZX0sIHtAY29kZSBzaG9ydH0sIHtAY29kZSBpbnR9LAogKiB7QGNvZGUgbG9uZ30sIHtAY29kZSBjaGFyfSwge0Bjb2RlIGZsb2F0fSwgYW5kIHtAY29kZSBkb3VibGV9LgogKgogKiBAYXV0aG9yIEpvc2VwaCBELiBEYXJjeQogKiBAYXV0aG9yIFNjb3R0IFNlbGlnbWFuCiAqIEBhdXRob3IgUGV0ZXIgdm9uIGRlciBBaCZlYWN1dGU7CiAqIEBzaW5jZSAxLjYKICovCnB1YmxpYyBpbnRlcmZhY2UgUHJpbWl0aXZlVHlwZSBleHRlbmRzIFR5cGVNaXJyb3Igewp9ClBLAwQKAAAIAAAGO6lKPUzjwJ0IAACdCAAAJwAAAGphdmF4L2xhbmcvbW9kZWwvdHlwZS9XaWxkY2FyZFR5cGUuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAwNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBqYXZheC5sYW5nLm1vZGVsLnR5cGU7CgoKLyoqCiAqIFJlcHJlc2VudHMgYSB3aWxkY2FyZCB0eXBlIGFyZ3VtZW50LgogKiBFeGFtcGxlcyBpbmNsdWRlOiAgICA8cHJlPjxjb2RlPgogKiAgID8KICogICA/IGV4dGVuZHMgTnVtYmVyCiAqICAgPyBzdXBlciBUCiAqIDwvY29kZT48L3ByZT4KICoKICogPHA+IEEgd2lsZGNhcmQgbWF5IGhhdmUgaXRzIHVwcGVyIGJvdW5kIGV4cGxpY2l0bHkgc2V0IGJ5IGFuCiAqIHtAY29kZSBleHRlbmRzfSBjbGF1c2UsIGl0cyBsb3dlciBib3VuZCBleHBsaWNpdGx5IHNldCBieSBhCiAqIHtAY29kZSBzdXBlcn0gY2xhdXNlLCBvciBuZWl0aGVyIChidXQgbm90IGJvdGgpLgogKgogKiBAYXV0aG9yIEpvc2VwaCBELiBEYXJjeQogKiBAYXV0aG9yIFNjb3R0IFNlbGlnbWFuCiAqIEBhdXRob3IgUGV0ZXIgdm9uIGRlciBBaCZlYWN1dGU7CiAqIEBzaW5jZSAxLjYKICovCnB1YmxpYyBpbnRlcmZhY2UgV2lsZGNhcmRUeXBlIGV4dGVuZHMgVHlwZU1pcnJvciB7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSB1cHBlciBib3VuZCBvZiB0aGlzIHdpbGRjYXJkLgogICAgICogSWYgbm8gdXBwZXIgYm91bmQgaXMgZXhwbGljaXRseSBkZWNsYXJlZCwKICAgICAqIHtAY29kZSBudWxsfSBpcyByZXR1cm5lZC4KICAgICAqCiAgICAgKiBAcmV0dXJuIHRoZSB1cHBlciBib3VuZCBvZiB0aGlzIHdpbGRjYXJkCiAgICAgKi8KICAgIFR5cGVNaXJyb3IgZ2V0RXh0ZW5kc0JvdW5kKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBsb3dlciBib3VuZCBvZiB0aGlzIHdpbGRjYXJkLgogICAgICogSWYgbm8gbG93ZXIgYm91bmQgaXMgZXhwbGljaXRseSBkZWNsYXJlZCwKICAgICAqIHtAY29kZSBudWxsfSBpcyByZXR1cm5lZC4KICAgICAqCiAgICAgKiBAcmV0dXJuIHRoZSBsb3dlciBib3VuZCBvZiB0aGlzIHdpbGRjYXJkCiAgICAgKi8KICAgIFR5cGVNaXJyb3IgZ2V0U3VwZXJCb3VuZCgpOwp9ClBLAwQKAAAIAAAGO6lKC2VxRfgLAAD4CwAALwAAAGphdmF4L2xhbmcvbW9kZWwvdHlwZS9Vbmtub3duVHlwZUV4Y2VwdGlvbi5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDA1LCAyMDE3LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGphdmF4LmxhbmcubW9kZWwudHlwZTsKCmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLlVua25vd25FbnRpdHlFeGNlcHRpb247CgovKioKICogSW5kaWNhdGVzIHRoYXQgYW4gdW5rbm93biBraW5kIG9mIHR5cGUgd2FzIGVuY291bnRlcmVkLiAgVGhpcyBjYW4KICogb2NjdXIgaWYgdGhlIGxhbmd1YWdlIGV2b2x2ZXMgYW5kIG5ldyBraW5kcyBvZiB0eXBlcyBhcmUgYWRkZWQgdG8KICogdGhlIHtAY29kZSBUeXBlTWlycm9yfSBoaWVyYXJjaHkuICBNYXkgYmUgdGhyb3duIGJ5IGEge0BsaW5rcGxhaW4KICogVHlwZVZpc2l0b3IgdHlwZSB2aXNpdG9yfSB0byBpbmRpY2F0ZSB0aGF0IHRoZSB2aXNpdG9yIHdhcyBjcmVhdGVkCiAqIGZvciBhIHByaW9yIHZlcnNpb24gb2YgdGhlIGxhbmd1YWdlLgogKgogKiBAYXV0aG9yIEpvc2VwaCBELiBEYXJjeQogKiBAYXV0aG9yIFNjb3R0IFNlbGlnbWFuCiAqIEBhdXRob3IgUGV0ZXIgdm9uIGRlciBBaCZlYWN1dGU7CiAqIEBzZWUgVHlwZVZpc2l0b3IjdmlzaXRVbmtub3duCiAqIEBzaW5jZSAxLjYKICovCnB1YmxpYyBjbGFzcyBVbmtub3duVHlwZUV4Y2VwdGlvbiBleHRlbmRzIFVua25vd25FbnRpdHlFeGNlcHRpb24gewoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDI2OUw7CgogICAgcHJpdmF0ZSB0cmFuc2llbnQgVHlwZU1pcnJvciB0eXBlOwogICAgcHJpdmF0ZSB0cmFuc2llbnQgT2JqZWN0IHBhcmFtZXRlcjsKCiAgICAvKioKICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIFVua25vd25UeXBlRXhjZXB0aW9ufS5UaGUge0Bjb2RlIHB9CiAgICAgKiBwYXJhbWV0ZXIgbWF5IGJlIHVzZWQgdG8gcGFzcyBpbiBhbiBhZGRpdGlvbmFsIGFyZ3VtZW50IHdpdGgKICAgICAqIGluZm9ybWF0aW9uIGFib3V0IHRoZSBjb250ZXh0IGluIHdoaWNoIHRoZSB1bmtub3duIHR5cGUgd2FzCiAgICAgKiBlbmNvdW50ZXJlZDsgZm9yIGV4YW1wbGUsIHRoZSB2aXNpdCBtZXRob2RzIG9mIHtAbGluawogICAgICogVHlwZVZpc2l0b3J9IG1heSBwYXNzIGluIHRoZWlyIGFkZGl0aW9uYWwgcGFyYW1ldGVyLgogICAgICoKICAgICAqIEBwYXJhbSB0IHRoZSB1bmtub3duIHR5cGUsIG1heSBiZSB7QGNvZGUgbnVsbH0KICAgICAqIEBwYXJhbSBwIGFuIGFkZGl0aW9uYWwgcGFyYW1ldGVyLCBtYXkgYmUge0Bjb2RlIG51bGx9CiAgICAgKi8KICAgIHB1YmxpYyBVbmtub3duVHlwZUV4Y2VwdGlvbihUeXBlTWlycm9yIHQsIE9iamVjdCBwKSB7CiAgICAgICAgc3VwZXIoIlVua25vd24gdHlwZTogIiArIHQpOwogICAgICAgIHR5cGUgPSB0OwogICAgICAgIHRoaXMucGFyYW1ldGVyID0gcDsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHVua25vd24gdHlwZS4KICAgICAqIFRoZSB2YWx1ZSBtYXkgYmUgdW5hdmFpbGFibGUgaWYgdGhpcyBleGNlcHRpb24gaGFzIGJlZW4KICAgICAqIHNlcmlhbGl6ZWQgYW5kIHRoZW4gcmVhZCBiYWNrIGluLgogICAgICoKICAgICAqIEByZXR1cm4gdGhlIHVua25vd24gdHlwZSwgb3Ige0Bjb2RlIG51bGx9IGlmIHVuYXZhaWxhYmxlCiAgICAgKi8KICAgIHB1YmxpYyBUeXBlTWlycm9yIGdldFVua25vd25UeXBlKCkgewogICAgICAgIHJldHVybiB0eXBlOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgYWRkaXRpb25hbCBhcmd1bWVudC4KICAgICAqCiAgICAgKiBAcmV0dXJuIHRoZSBhZGRpdGlvbmFsIGFyZ3VtZW50LCBvciB7QGNvZGUgbnVsbH0gaWYgdW5hdmFpbGFibGUKICAgICAqLwogICAgcHVibGljIE9iamVjdCBnZXRBcmd1bWVudCgpIHsKICAgICAgICByZXR1cm4gcGFyYW1ldGVyOwogICAgfQp9ClBLAwQKAAAIAAAGO6lKsrcD09kHAADZBwAAIQAAAGphdmF4L2xhbmcvbW9kZWwvdHlwZS9Ob1R5cGUuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAxNywgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBqYXZheC5sYW5nLm1vZGVsLnR5cGU7CgppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5lbGVtZW50LkV4ZWN1dGFibGVFbGVtZW50OwoKCi8qKgogKiBBIHBzZXVkby10eXBlIHVzZWQgd2hlcmUgbm8gYWN0dWFsIHR5cGUgaXMgYXBwcm9wcmlhdGUuCiAqIFRoZSBraW5kcyBvZiB7QGNvZGUgTm9UeXBlfSBhcmU6CiAqIDx1bD4KICogPGxpPntAbGluayBUeXBlS2luZCNWT0lEIFZPSUR9IC0gY29ycmVzcG9uZHMgdG8gdGhlIGtleXdvcmQge0Bjb2RlIHZvaWR9LgogKiA8bGk+e0BsaW5rIFR5cGVLaW5kI1BBQ0tBR0UgUEFDS0FHRX0gLSB0aGUgcHNldWRvLXR5cGUgb2YgYSBwYWNrYWdlIGVsZW1lbnQuCiAqIDxsaT57QGxpbmsgVHlwZUtpbmQjTU9EVUxFIE1PRFVMRX0gLSB0aGUgcHNldWRvLXR5cGUgb2YgYSBtb2R1bGUgZWxlbWVudC4KICogPGxpPntAbGluayBUeXBlS2luZCNOT05FIE5PTkV9IC0gdXNlZCBpbiBvdGhlciBjYXNlcwogKiAgIHdoZXJlIG5vIGFjdHVhbCB0eXBlIGlzIGFwcHJvcHJpYXRlOyBmb3IgZXhhbXBsZSwgdGhlIHN1cGVyY2xhc3MKICogICBvZiB7QGNvZGUgamF2YS5sYW5nLk9iamVjdH0uCiAqIDwvdWw+CiAqCiAqIEBhdXRob3IgSm9zZXBoIEQuIERhcmN5CiAqIEBhdXRob3IgU2NvdHQgU2VsaWdtYW4KICogQGF1dGhvciBQZXRlciB2b24gZGVyIEFoJmVhY3V0ZTsKICogQHNlZSBFeGVjdXRhYmxlRWxlbWVudCNnZXRSZXR1cm5UeXBlKCkKICogQHNpbmNlIDEuNgogKi8KCnB1YmxpYyBpbnRlcmZhY2UgTm9UeXBlIGV4dGVuZHMgVHlwZU1pcnJvciB7Cn0KUEsDBAoAAAgAANJ9TUrako+5BgYAAAYGAAAoAAAAamF2YXgvbGFuZy9tb2RlbC90eXBlL1JlZmVyZW5jZVR5cGUuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAwNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBqYXZheC5sYW5nLm1vZGVsLnR5cGU7CgoKLyoqCiAqIFJlcHJlc2VudHMgYSByZWZlcmVuY2UgdHlwZS4KICogVGhlc2UgaW5jbHVkZSBjbGFzcyBhbmQgaW50ZXJmYWNlIHR5cGVzLCBhcnJheSB0eXBlcywgdHlwZSB2YXJpYWJsZXMsCiAqIGFuZCB0aGUgbnVsbCB0eXBlLgogKgogKiBAYXV0aG9yIEpvc2VwaCBELiBEYXJjeQogKiBAYXV0aG9yIFNjb3R0IFNlbGlnbWFuCiAqIEBhdXRob3IgUGV0ZXIgdm9uIGRlciBBaCZlYWN1dGU7CiAqIEBzaW5jZSAxLjYKICovCnB1YmxpYyBpbnRlcmZhY2UgUmVmZXJlbmNlVHlwZSBleHRlbmRzIFR5cGVNaXJyb3Igewp9ClBLAwQKAAAIAADSfU1Ken6WhB4PAAAeDwAAKQAAAGphdmF4L2xhbmcvbW9kZWwvdHlwZS9FeGVjdXRhYmxlVHlwZS5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDA1LCAyMDEzLCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGphdmF4LmxhbmcubW9kZWwudHlwZTsKCgppbXBvcnQgamF2YS51dGlsLkxpc3Q7CgppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5lbGVtZW50LkV4ZWN1dGFibGVFbGVtZW50OwoKLyoqCiAqIFJlcHJlc2VudHMgdGhlIHR5cGUgb2YgYW4gZXhlY3V0YWJsZS4gIEFuIDxpPmV4ZWN1dGFibGU8L2k+CiAqIGlzIGEgbWV0aG9kLCBjb25zdHJ1Y3Rvciwgb3IgaW5pdGlhbGl6ZXIuCiAqCiAqIDxwPiBUaGUgZXhlY3V0YWJsZSBpcwogKiByZXByZXNlbnRlZCBhcyB3aGVuIHZpZXdlZCBhcyBhIG1ldGhvZCAob3IgY29uc3RydWN0b3Igb3IKICogaW5pdGlhbGl6ZXIpIG9mIHNvbWUgcmVmZXJlbmNlIHR5cGUuCiAqIElmIHRoYXQgcmVmZXJlbmNlIHR5cGUgaXMgcGFyYW1ldGVyaXplZCwgdGhlbiBpdHMgYWN0dWFsCiAqIHR5cGUgYXJndW1lbnRzIGFyZSBzdWJzdGl0dXRlZCBpbnRvIGFueSB0eXBlcyByZXR1cm5lZCBieSB0aGUgbWV0aG9kcyBvZgogKiB0aGlzIGludGVyZmFjZS4KICoKICogQGF1dGhvciBKb3NlcGggRC4gRGFyY3kKICogQGF1dGhvciBTY290dCBTZWxpZ21hbgogKiBAYXV0aG9yIFBldGVyIHZvbiBkZXIgQWgmZWFjdXRlOwogKiBAc2VlIEV4ZWN1dGFibGVFbGVtZW50CiAqIEBzaW5jZSAxLjYKICovCnB1YmxpYyBpbnRlcmZhY2UgRXhlY3V0YWJsZVR5cGUgZXh0ZW5kcyBUeXBlTWlycm9yIHsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHR5cGUgdmFyaWFibGVzIGRlY2xhcmVkIGJ5IHRoZSBmb3JtYWwgdHlwZSBwYXJhbWV0ZXJzCiAgICAgKiBvZiB0aGlzIGV4ZWN1dGFibGUuCiAgICAgKgogICAgICogQHJldHVybiB0aGUgdHlwZSB2YXJpYWJsZXMgZGVjbGFyZWQgYnkgdGhlIGZvcm1hbCB0eXBlIHBhcmFtZXRlcnMsCiAgICAgKiAgICAgICAgICBvciBhbiBlbXB0eSBsaXN0IGlmIHRoZXJlIGFyZSBub25lCiAgICAgKi8KICAgIExpc3Q8PyBleHRlbmRzIFR5cGVWYXJpYWJsZT4gZ2V0VHlwZVZhcmlhYmxlcygpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgcmV0dXJuIHR5cGUgb2YgdGhpcyBleGVjdXRhYmxlLgogICAgICogUmV0dXJucyBhIHtAbGluayBOb1R5cGV9IHdpdGgga2luZCB7QGxpbmsgVHlwZUtpbmQjVk9JRCBWT0lEfQogICAgICogaWYgdGhpcyBleGVjdXRhYmxlIGlzIG5vdCBhIG1ldGhvZCwgb3IgaXMgYSBtZXRob2QgdGhhdCBkb2VzIG5vdAogICAgICogcmV0dXJuIGEgdmFsdWUuCiAgICAgKgogICAgICogQHJldHVybiB0aGUgcmV0dXJuIHR5cGUgb2YgdGhpcyBleGVjdXRhYmxlCiAgICAgKi8KICAgIFR5cGVNaXJyb3IgZ2V0UmV0dXJuVHlwZSgpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgdHlwZXMgb2YgdGhpcyBleGVjdXRhYmxlJ3MgZm9ybWFsIHBhcmFtZXRlcnMuCiAgICAgKgogICAgICogQHJldHVybiB0aGUgdHlwZXMgb2YgdGhpcyBleGVjdXRhYmxlJ3MgZm9ybWFsIHBhcmFtZXRlcnMsCiAgICAgKiAgICAgICAgICBvciBhbiBlbXB0eSBsaXN0IGlmIHRoZXJlIGFyZSBub25lCiAgICAgKi8KICAgIExpc3Q8PyBleHRlbmRzIFR5cGVNaXJyb3I+IGdldFBhcmFtZXRlclR5cGVzKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSByZWNlaXZlciB0eXBlIG9mIHRoaXMgZXhlY3V0YWJsZSwKICAgICAqIG9yIHtAbGluayBqYXZheC5sYW5nLm1vZGVsLnR5cGUuTm9UeXBlIE5vVHlwZX0gd2l0aAogICAgICoga2luZCB7QGxpbmsgamF2YXgubGFuZy5tb2RlbC50eXBlLlR5cGVLaW5kI05PTkUgTk9ORX0KICAgICAqIGlmIHRoZSBleGVjdXRhYmxlIGhhcyBubyByZWNlaXZlciB0eXBlLgogICAgICoKICAgICAqIEFuIGV4ZWN1dGFibGUgd2hpY2ggaXMgYW4gaW5zdGFuY2UgbWV0aG9kLCBvciBhIGNvbnN0cnVjdG9yIG9mIGFuCiAgICAgKiBpbm5lciBjbGFzcywgaGFzIGEgcmVjZWl2ZXIgdHlwZSBkZXJpdmVkIGZyb20gdGhlIHtAbGlua3BsYWluCiAgICAgKiBFeGVjdXRhYmxlRWxlbWVudCNnZXRFbmNsb3NpbmdFbGVtZW50IGRlY2xhcmluZyB0eXBlfS4KICAgICAqCiAgICAgKiBBbiBleGVjdXRhYmxlIHdoaWNoIGlzIGEgc3RhdGljIG1ldGhvZCwgb3IgYSBjb25zdHJ1Y3RvciBvZiBhCiAgICAgKiBub24taW5uZXIgY2xhc3MsIG9yIGFuIGluaXRpYWxpemVyIChzdGF0aWMgb3IgaW5zdGFuY2UpLCBoYXMgbm8KICAgICAqIHJlY2VpdmVyIHR5cGUuCiAgICAgKgogICAgICogQHJldHVybiB0aGUgcmVjZWl2ZXIgdHlwZSBvZiB0aGlzIGV4ZWN1dGFibGUKICAgICAqIEBzaW5jZSAxLjgKICAgICAqLwogICAgVHlwZU1pcnJvciBnZXRSZWNlaXZlclR5cGUoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGV4Y2VwdGlvbnMgYW5kIG90aGVyIHRocm93YWJsZXMgbGlzdGVkIGluIHRoaXMKICAgICAqIGV4ZWN1dGFibGUncyB7QGNvZGUgdGhyb3dzfSBjbGF1c2UuCiAgICAgKgogICAgICogQHJldHVybiB0aGUgZXhjZXB0aW9ucyBhbmQgb3RoZXIgdGhyb3dhYmxlcyBsaXN0ZWQgaW4gdGhpcwogICAgICogICAgICAgICAgZXhlY3V0YWJsZSdzIHtAY29kZSB0aHJvd3N9IGNsYXVzZSwKICAgICAqICAgICAgICAgIG9yIGFuIGVtcHR5IGxpc3QgaWYgdGhlcmUgYXJlIG5vbmUuCiAgICAgKi8KICAgIExpc3Q8PyBleHRlbmRzIFR5cGVNaXJyb3I+IGdldFRocm93blR5cGVzKCk7Cn0KUEsDBAoAAAgAAAY7qUoUFRMp/QcAAP0HAAArAAAAamF2YXgvbGFuZy9tb2RlbC90eXBlL0ludGVyc2VjdGlvblR5cGUuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAxMiwgMjAxNywgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBqYXZheC5sYW5nLm1vZGVsLnR5cGU7CgppbXBvcnQgamF2YS51dGlsLkxpc3Q7CgovKioKICogUmVwcmVzZW50cyBhbiBpbnRlcnNlY3Rpb24gdHlwZS4KICoKICogPHA+QW4gaW50ZXJzZWN0aW9uIHR5cGUgY2FuIGJlIGVpdGhlciBpbXBsaWNpdGx5IG9yIGV4cGxpY2l0bHkKICogZGVjbGFyZWQgaW4gYSBwcm9ncmFtLiBGb3IgZXhhbXBsZSwgdGhlIGJvdW5kIG9mIHRoZSB0eXBlIHBhcmFtZXRlcgogKiB7QGNvZGUgPFQgZXh0ZW5kcyBOdW1iZXIgJiBSdW5uYWJsZT59IGlzIGFuIChpbXBsaWNpdCkgaW50ZXJzZWN0aW9uCiAqIHR5cGUuICBUaGlzIGlzIHJlcHJlc2VudGVkIGJ5IGFuIHtAY29kZSBJbnRlcnNlY3Rpb25UeXBlfSB3aXRoCiAqIHtAY29kZSBOdW1iZXJ9IGFuZCB7QGNvZGUgUnVubmFibGV9IGFzIGl0cyBib3VuZHMuCiAqCiAqIEBpbXBsTm90ZSBJbiB0aGUgcmVmZXJlbmNlIGltcGxlbWVudGF0aW9uIGFuIHtAY29kZQogKiBJbnRlcnNlY3Rpb25UeXBlfSBpcyB1c2VkIHRvIG1vZGVsIHRoZSBleHBsaWNpdCB0YXJnZXQgdHlwZSBvZiBhCiAqIGNhc3QgZXhwcmVzc2lvbi4KICoKICogQHNpbmNlIDEuOAogKi8KcHVibGljIGludGVyZmFjZSBJbnRlcnNlY3Rpb25UeXBlIGV4dGVuZHMgVHlwZU1pcnJvciB7CgogICAgLyoqCiAgICAgKiBSZXR1cm4gdGhlIGJvdW5kcyBjb21wcmlzaW5nIHRoaXMgaW50ZXJzZWN0aW9uIHR5cGUuCiAgICAgKgogICAgICogQHJldHVybiB0aGUgYm91bmRzIG9mIHRoaXMgaW50ZXJzZWN0aW9uIHR5cGUKICAgICAqLwogICAgTGlzdDw/IGV4dGVuZHMgVHlwZU1pcnJvcj4gZ2V0Qm91bmRzKCk7Cn0KUEsDBAoAAAgAAAY7qUrIFj9jLg8AAC4PAAAjAAAAamF2YXgvbGFuZy9tb2RlbC90eXBlL1R5cGVLaW5kLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMTYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgamF2YXgubGFuZy5tb2RlbC50eXBlOwoKCi8qKgogKiBUaGUga2luZCBvZiBhIHR5cGUgbWlycm9yLgogKgogKiA8cD5Ob3RlIHRoYXQgaXQgaXMgcG9zc2libGUgYWRkaXRpb25hbCB0eXBlIGtpbmRzIHdpbGwgYmUgYWRkZWQgdG8KICogYWNjb21tb2RhdGUgbmV3LCBjdXJyZW50bHkgdW5rbm93biwgbGFuZ3VhZ2Ugc3RydWN0dXJlcyBhZGRlZCB0bwogKiBmdXR1cmUgdmVyc2lvbnMgb2YgdGhlIEphdmEmdHJhZGU7IHByb2dyYW1taW5nIGxhbmd1YWdlLgogKgogKiBAYXV0aG9yIEpvc2VwaCBELiBEYXJjeQogKiBAYXV0aG9yIFNjb3R0IFNlbGlnbWFuCiAqIEBhdXRob3IgUGV0ZXIgdm9uIGRlciBBaCZlYWN1dGU7CiAqIEBzZWUgVHlwZU1pcnJvcgogKiBAc2luY2UgMS42CiAqLwpwdWJsaWMgZW51bSBUeXBlS2luZCB7CiAgICAvKioKICAgICAqIFRoZSBwcmltaXRpdmUgdHlwZSB7QGNvZGUgYm9vbGVhbn0uCiAgICAgKi8KICAgIEJPT0xFQU4sCgogICAgLyoqCiAgICAgKiBUaGUgcHJpbWl0aXZlIHR5cGUge0Bjb2RlIGJ5dGV9LgogICAgICovCiAgICBCWVRFLAoKICAgIC8qKgogICAgICogVGhlIHByaW1pdGl2ZSB0eXBlIHtAY29kZSBzaG9ydH0uCiAgICAgKi8KICAgIFNIT1JULAoKICAgIC8qKgogICAgICogVGhlIHByaW1pdGl2ZSB0eXBlIHtAY29kZSBpbnR9LgogICAgICovCiAgICBJTlQsCgogICAgLyoqCiAgICAgKiBUaGUgcHJpbWl0aXZlIHR5cGUge0Bjb2RlIGxvbmd9LgogICAgICovCiAgICBMT05HLAoKICAgIC8qKgogICAgICogVGhlIHByaW1pdGl2ZSB0eXBlIHtAY29kZSBjaGFyfS4KICAgICAqLwogICAgQ0hBUiwKCiAgICAvKioKICAgICAqIFRoZSBwcmltaXRpdmUgdHlwZSB7QGNvZGUgZmxvYXR9LgogICAgICovCiAgICBGTE9BVCwKCiAgICAvKioKICAgICAqIFRoZSBwcmltaXRpdmUgdHlwZSB7QGNvZGUgZG91YmxlfS4KICAgICAqLwogICAgRE9VQkxFLAoKICAgIC8qKgogICAgICogVGhlIHBzZXVkby10eXBlIGNvcnJlc3BvbmRpbmcgdG8gdGhlIGtleXdvcmQge0Bjb2RlIHZvaWR9LgogICAgICogQHNlZSBOb1R5cGUKICAgICAqLwogICAgVk9JRCwKCiAgICAvKioKICAgICAqIEEgcHNldWRvLXR5cGUgdXNlZCB3aGVyZSBubyBhY3R1YWwgdHlwZSBpcyBhcHByb3ByaWF0ZS4KICAgICAqIEBzZWUgTm9UeXBlCiAgICAgKi8KICAgIE5PTkUsCgogICAgLyoqCiAgICAgKiBUaGUgbnVsbCB0eXBlLgogICAgICovCiAgICBOVUxMLAoKICAgIC8qKgogICAgICogQW4gYXJyYXkgdHlwZS4KICAgICAqLwogICAgQVJSQVksCgogICAgLyoqCiAgICAgKiBBIGNsYXNzIG9yIGludGVyZmFjZSB0eXBlLgogICAgICovCiAgICBERUNMQVJFRCwKCiAgICAvKioKICAgICAqIEEgY2xhc3Mgb3IgaW50ZXJmYWNlIHR5cGUgdGhhdCBjb3VsZCBub3QgYmUgcmVzb2x2ZWQuCiAgICAgKi8KICAgIEVSUk9SLAoKICAgIC8qKgogICAgICogQSB0eXBlIHZhcmlhYmxlLgogICAgICovCiAgICBUWVBFVkFSLAoKICAgIC8qKgogICAgICogQSB3aWxkY2FyZCB0eXBlIGFyZ3VtZW50LgogICAgICovCiAgICBXSUxEQ0FSRCwKCiAgICAvKioKICAgICAqIEEgcHNldWRvLXR5cGUgY29ycmVzcG9uZGluZyB0byBhIHBhY2thZ2UgZWxlbWVudC4KICAgICAqIEBzZWUgTm9UeXBlCiAgICAgKi8KICAgIFBBQ0tBR0UsCgogICAgLyoqCiAgICAgKiBBIG1ldGhvZCwgY29uc3RydWN0b3IsIG9yIGluaXRpYWxpemVyLgogICAgICovCiAgICBFWEVDVVRBQkxFLAoKICAgIC8qKgogICAgICogQW4gaW1wbGVtZW50YXRpb24tcmVzZXJ2ZWQgdHlwZS4KICAgICAqIFRoaXMgaXMgbm90IHRoZSB0eXBlIHlvdSBhcmUgbG9va2luZyBmb3IuCiAgICAgKi8KICAgIE9USEVSLAoKICAgIC8qKgogICAgICAqIEEgdW5pb24gdHlwZS4KICAgICAgKgogICAgICAqIEBzaW5jZSAxLjcKICAgICAgKi8KICAgIFVOSU9OLAoKICAgIC8qKgogICAgICAqIEFuIGludGVyc2VjdGlvbiB0eXBlLgogICAgICAqCiAgICAgICogQHNpbmNlIDEuOAogICAgICAqLwogICAgSU5URVJTRUNUSU9OLAoKICAgIC8qKgogICAgICogQSBwc2V1ZG8tdHlwZSBjb3JyZXNwb25kaW5nIHRvIGEgbW9kdWxlIGVsZW1lbnQuCiAgICAgKiBAc2VlIE5vVHlwZQogICAgICogQHNpbmNlIDkKICAgICAqIEBzcGVjIEpQTVMKICAgICAqLwogICAgTU9EVUxFOwoKICAgIC8qKgogICAgICogUmV0dXJucyB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyBraW5kIGNvcnJlc3BvbmRzIHRvIGEgcHJpbWl0aXZlCiAgICAgKiB0eXBlIGFuZCB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoaXMga2luZCBjb3JyZXNwb25kcyB0byBhIHByaW1pdGl2ZSB0eXBlCiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGlzUHJpbWl0aXZlKCkgewogICAgICAgIHN3aXRjaCh0aGlzKSB7CiAgICAgICAgY2FzZSBCT09MRUFOOgogICAgICAgIGNhc2UgQllURToKICAgICAgICBjYXNlIFNIT1JUOgogICAgICAgIGNhc2UgSU5UOgogICAgICAgIGNhc2UgTE9ORzoKICAgICAgICBjYXNlIENIQVI6CiAgICAgICAgY2FzZSBGTE9BVDoKICAgICAgICBjYXNlIERPVUJMRToKICAgICAgICAgICAgcmV0dXJuIHRydWU7CgogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICB9Cn0KUEsDBAoAAAgAANJ9TUqz/cV5uQYAALkGAAAkAAAAamF2YXgvbGFuZy9tb2RlbC90eXBlL0FycmF5VHlwZS5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDA1LCAyMDA2LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGphdmF4LmxhbmcubW9kZWwudHlwZTsKCgovKioKICogUmVwcmVzZW50cyBhbiBhcnJheSB0eXBlLgogKiBBIG11bHRpZGltZW5zaW9uYWwgYXJyYXkgdHlwZSBpcyByZXByZXNlbnRlZCBhcyBhbiBhcnJheSB0eXBlCiAqIHdob3NlIGNvbXBvbmVudCB0eXBlIGlzIGFsc28gYW4gYXJyYXkgdHlwZS4KICoKICogQGF1dGhvciBKb3NlcGggRC4gRGFyY3kKICogQGF1dGhvciBTY290dCBTZWxpZ21hbgogKiBAYXV0aG9yIFBldGVyIHZvbiBkZXIgQWgmZWFjdXRlOwogKiBAc2luY2UgMS42CiAqLwpwdWJsaWMgaW50ZXJmYWNlIEFycmF5VHlwZSBleHRlbmRzIFJlZmVyZW5jZVR5cGUgewoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgY29tcG9uZW50IHR5cGUgb2YgdGhpcyBhcnJheSB0eXBlLgogICAgICoKICAgICAqIEByZXR1cm4gdGhlIGNvbXBvbmVudCB0eXBlIG9mIHRoaXMgYXJyYXkgdHlwZQogICAgICovCiAgICBUeXBlTWlycm9yIGdldENvbXBvbmVudFR5cGUoKTsKfQpQSwMECgAACAAA0n1NSnPSu7/PBgAAzwYAACQAAABqYXZheC9sYW5nL21vZGVsL3R5cGUvRXJyb3JUeXBlLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMDgsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgamF2YXgubGFuZy5tb2RlbC50eXBlOwoKLyoqCiAqIFJlcHJlc2VudHMgYSBjbGFzcyBvciBpbnRlcmZhY2UgdHlwZSB0aGF0IGNhbm5vdCBiZSBwcm9wZXJseSBtb2RlbGVkLgogKiBUaGlzIG1heSBiZSB0aGUgcmVzdWx0IG9mIGEgcHJvY2Vzc2luZyBlcnJvciwKICogc3VjaCBhcyBhIG1pc3NpbmcgY2xhc3MgZmlsZSBvciBlcnJvbmVvdXMgc291cmNlIGNvZGUuCiAqIE1vc3QgcXVlcmllcyBmb3IKICogaW5mb3JtYXRpb24gZGVyaXZlZCBmcm9tIHN1Y2ggYSB0eXBlIChzdWNoIGFzIGl0cyBtZW1iZXJzIG9yIGl0cwogKiBzdXBlcnR5cGUpIHdpbGwgbm90LCBpbiBnZW5lcmFsLCByZXR1cm4gbWVhbmluZ2Z1bCByZXN1bHRzLgogKgogKiBAYXV0aG9yIEpvc2VwaCBELiBEYXJjeQogKiBAYXV0aG9yIFNjb3R0IFNlbGlnbWFuCiAqIEBhdXRob3IgUGV0ZXIgdm9uIGRlciBBaCZlYWN1dGU7CiAqIEBzaW5jZSAxLjYKICovCnB1YmxpYyBpbnRlcmZhY2UgRXJyb3JUeXBlIGV4dGVuZHMgRGVjbGFyZWRUeXBlIHsKfQpQSwMECgAACAAABjupSotccquSGwAAkhsAACYAAABqYXZheC9sYW5nL21vZGVsL3R5cGUvVHlwZVZpc2l0b3IuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAxNywgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBqYXZheC5sYW5nLm1vZGVsLnR5cGU7CgppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5lbGVtZW50Lio7CgovKioKICogQSB2aXNpdG9yIG9mIHR5cGVzLCBpbiB0aGUgc3R5bGUgb2YgdGhlCiAqIHZpc2l0b3IgZGVzaWduIHBhdHRlcm4uICBDbGFzc2VzIGltcGxlbWVudGluZyB0aGlzCiAqIGludGVyZmFjZSBhcmUgdXNlZCB0byBvcGVyYXRlIG9uIGEgdHlwZSB3aGVuIHRoZSBraW5kIG9mCiAqIHR5cGUgaXMgdW5rbm93biBhdCBjb21waWxlIHRpbWUuICBXaGVuIGEgdmlzaXRvciBpcyBwYXNzZWQgdG8gYQogKiB0eXBlJ3Mge0BsaW5rIFR5cGVNaXJyb3IjYWNjZXB0IGFjY2VwdH0gbWV0aG9kLCB0aGUgPGNvZGU+dmlzaXQ8aT5YeXo8L2k+PC9jb2RlPgogKiBtZXRob2QgbW9zdCBhcHBsaWNhYmxlIHRvIHRoYXQgdHlwZSBpcyBpbnZva2VkLgogKgogKiA8cD4gQ2xhc3NlcyBpbXBsZW1lbnRpbmcgdGhpcyBpbnRlcmZhY2UgbWF5IG9yIG1heSBub3QgdGhyb3cgYQogKiB7QGNvZGUgTnVsbFBvaW50ZXJFeGNlcHRpb259IGlmIHRoZSBhZGRpdGlvbmFsIHBhcmFtZXRlciB7QGNvZGUgcH0KICogaXMge0Bjb2RlIG51bGx9OyBzZWUgZG9jdW1lbnRhdGlvbiBvZiB0aGUgaW1wbGVtZW50aW5nIGNsYXNzIGZvcgogKiBkZXRhaWxzLgogKgogKiA8cD4gPGI+V0FSTklORzo8L2I+IEl0IGlzIHBvc3NpYmxlIHRoYXQgbWV0aG9kcyB3aWxsIGJlIGFkZGVkIHRvCiAqIHRoaXMgaW50ZXJmYWNlIHRvIGFjY29tbW9kYXRlIG5ldywgY3VycmVudGx5IHVua25vd24sIGxhbmd1YWdlCiAqIHN0cnVjdHVyZXMgYWRkZWQgdG8gZnV0dXJlIHZlcnNpb25zIG9mIHRoZSBKYXZhJnRyYWRlOyBwcm9ncmFtbWluZwogKiBsYW5ndWFnZS4gIFRoZXJlZm9yZSwgdmlzaXRvciBjbGFzc2VzIGRpcmVjdGx5IGltcGxlbWVudGluZyB0aGlzCiAqIGludGVyZmFjZSBtYXkgYmUgc291cmNlIGluY29tcGF0aWJsZSB3aXRoIGZ1dHVyZSB2ZXJzaW9ucyBvZiB0aGUKICogcGxhdGZvcm0uICBUbyBhdm9pZCB0aGlzIHNvdXJjZSBpbmNvbXBhdGliaWxpdHksIHZpc2l0b3IKICogaW1wbGVtZW50YXRpb25zIGFyZSBlbmNvdXJhZ2VkIHRvIGluc3RlYWQgZXh0ZW5kIHRoZSBhcHByb3ByaWF0ZQogKiBhYnN0cmFjdCB2aXNpdG9yIGNsYXNzIHRoYXQgaW1wbGVtZW50cyB0aGlzIGludGVyZmFjZS4gIEhvd2V2ZXIsIGFuCiAqIEFQSSBzaG91bGQgZ2VuZXJhbGx5IHVzZSB0aGlzIHZpc2l0b3IgaW50ZXJmYWNlIGFzIHRoZSB0eXBlIGZvcgogKiBwYXJhbWV0ZXJzLCByZXR1cm4gdHlwZSwgZXRjLiByYXRoZXIgdGhhbiBvbmUgb2YgdGhlIGFic3RyYWN0CiAqIGNsYXNzZXMuCiAqCiAqIDxwPk5vdGUgdGhhdCBtZXRob2RzIHRvIGFjY29tbW9kYXRlIG5ldyBsYW5ndWFnZSBjb25zdHJ1Y3RzIGNvdWxkCiAqIGJlIGFkZGVkIGluIGEgc291cmNlIDxlbT5jb21wYXRpYmxlPC9lbT4gd2F5IGlmIHRoZXkgd2VyZSBhZGRlZCBhcwogKiA8ZW0+ZGVmYXVsdCBtZXRob2RzPC9lbT4uICBIb3dldmVyLCBkZWZhdWx0IG1ldGhvZHMgYXJlIG9ubHkKICogYXZhaWxhYmxlIG9uIEphdmEgU0UgOCBhbmQgaGlnaGVyIHJlbGVhc2VzIGFuZCB0aGUge0Bjb2RlCiAqIGphdmF4LmxhbmcubW9kZWwuKn0gcGFja2FnZXMgYnVuZGxlZCBpbiBKYXZhIFNFIDggd2VyZSByZXF1aXJlZCB0bwogKiBhbHNvIGJlIHJ1bm5hYmxlIG9uIEphdmEgU0UgNy4gIFRoZXJlZm9yZSwgZGVmYXVsdCBtZXRob2RzCiAqIHdlcmUgPGVtPm5vdDwvZW0+IHVzZWQgd2hlbiBleHRlbmRpbmcge0Bjb2RlIGphdmF4LmxhbmcubW9kZWwuKn0KICogdG8gY292ZXIgSmF2YSBTRSA4IGxhbmd1YWdlIGZlYXR1cmVzLiAgSG93ZXZlciwgZGVmYXVsdCBtZXRob2RzCiAqIGFyZSB1c2VkIGluIHN1YnNlcXVlbnQgcmV2aXNpb25zIG9mIHRoZSB7QGNvZGUgamF2YXgubGFuZy5tb2RlbC4qfQogKiBwYWNrYWdlcyB0aGF0IGFyZSBvbmx5IHJlcXVpcmVkIHRvIHJ1biBvbiBKYXZhIFNFIDggYW5kIGhpZ2hlcgogKiBwbGF0Zm9ybSB2ZXJzaW9ucy4KICoKICogQHBhcmFtIDxSPiB0aGUgcmV0dXJuIHR5cGUgb2YgdGhpcyB2aXNpdG9yJ3MgbWV0aG9kcy4gIFVzZSB7QGxpbmsKICogICAgICAgICAgICBWb2lkfSBmb3IgdmlzaXRvcnMgdGhhdCBkbyBub3QgbmVlZCB0byByZXR1cm4gcmVzdWx0cy4KICogQHBhcmFtIDxQPiB0aGUgdHlwZSBvZiB0aGUgYWRkaXRpb25hbCBwYXJhbWV0ZXIgdG8gdGhpcyB2aXNpdG9yJ3MKICogICAgICAgICAgICBtZXRob2RzLiAgVXNlIHtAY29kZSBWb2lkfSBmb3IgdmlzaXRvcnMgdGhhdCBkbyBub3QgbmVlZCBhbgogKiAgICAgICAgICAgIGFkZGl0aW9uYWwgcGFyYW1ldGVyLgogKgogKiBAYXV0aG9yIEpvc2VwaCBELiBEYXJjeQogKiBAYXV0aG9yIFNjb3R0IFNlbGlnbWFuCiAqIEBhdXRob3IgUGV0ZXIgdm9uIGRlciBBaCZlYWN1dGU7CiAqIEBzaW5jZSAxLjYKICovCnB1YmxpYyBpbnRlcmZhY2UgVHlwZVZpc2l0b3I8UiwgUD4gewogICAgLyoqCiAgICAgKiBWaXNpdHMgYSB0eXBlLgogICAgICogQHBhcmFtIHQgdGhlIHR5cGUgdG8gdmlzaXQKICAgICAqIEBwYXJhbSBwIGEgdmlzaXRvci1zcGVjaWZpZWQgcGFyYW1ldGVyCiAgICAgKiBAcmV0dXJuICBhIHZpc2l0b3Itc3BlY2lmaWVkIHJlc3VsdAogICAgICovCiAgICBSIHZpc2l0KFR5cGVNaXJyb3IgdCwgUCBwKTsKCiAgICAvKioKICAgICAqIEEgY29udmVuaWVuY2UgbWV0aG9kIGVxdWl2YWxlbnQgdG8ge0Bjb2RlIHZpc2l0KHQsIG51bGwpfS4KICAgICAqCiAgICAgKiBAaW1wbFNwZWMgVGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gaXMge0Bjb2RlIHZpc2l0KHQsIG51bGwpfS4KICAgICAqCiAgICAgKiBAcGFyYW0gdCB0aGUgZWxlbWVudCB0byB2aXNpdAogICAgICogQHJldHVybiAgYSB2aXNpdG9yLXNwZWNpZmllZCByZXN1bHQKICAgICAqLwogICAgZGVmYXVsdCBSIHZpc2l0KFR5cGVNaXJyb3IgdCkgewogICAgICAgIHJldHVybiB2aXNpdCh0LCBudWxsKTsKICAgIH0KCiAgICAvKioKICAgICAqIFZpc2l0cyBhIHByaW1pdGl2ZSB0eXBlLgogICAgICogQHBhcmFtIHQgdGhlIHR5cGUgdG8gdmlzaXQKICAgICAqIEBwYXJhbSBwIGEgdmlzaXRvci1zcGVjaWZpZWQgcGFyYW1ldGVyCiAgICAgKiBAcmV0dXJuICBhIHZpc2l0b3Itc3BlY2lmaWVkIHJlc3VsdAogICAgICovCiAgICBSIHZpc2l0UHJpbWl0aXZlKFByaW1pdGl2ZVR5cGUgdCwgUCBwKTsKCiAgICAvKioKICAgICAqIFZpc2l0cyB0aGUgbnVsbCB0eXBlLgogICAgICogQHBhcmFtIHQgdGhlIHR5cGUgdG8gdmlzaXQKICAgICAqIEBwYXJhbSBwIGEgdmlzaXRvci1zcGVjaWZpZWQgcGFyYW1ldGVyCiAgICAgKiBAcmV0dXJuICBhIHZpc2l0b3Itc3BlY2lmaWVkIHJlc3VsdAogICAgICovCiAgICBSIHZpc2l0TnVsbChOdWxsVHlwZSB0LCBQIHApOwoKICAgIC8qKgogICAgICogVmlzaXRzIGFuIGFycmF5IHR5cGUuCiAgICAgKiBAcGFyYW0gdCB0aGUgdHlwZSB0byB2aXNpdAogICAgICogQHBhcmFtIHAgYSB2aXNpdG9yLXNwZWNpZmllZCBwYXJhbWV0ZXIKICAgICAqIEByZXR1cm4gIGEgdmlzaXRvci1zcGVjaWZpZWQgcmVzdWx0CiAgICAgKi8KICAgIFIgdmlzaXRBcnJheShBcnJheVR5cGUgdCwgUCBwKTsKCiAgICAvKioKICAgICAqIFZpc2l0cyBhIGRlY2xhcmVkIHR5cGUuCiAgICAgKiBAcGFyYW0gdCB0aGUgdHlwZSB0byB2aXNpdAogICAgICogQHBhcmFtIHAgYSB2aXNpdG9yLXNwZWNpZmllZCBwYXJhbWV0ZXIKICAgICAqIEByZXR1cm4gIGEgdmlzaXRvci1zcGVjaWZpZWQgcmVzdWx0CiAgICAgKi8KICAgIFIgdmlzaXREZWNsYXJlZChEZWNsYXJlZFR5cGUgdCwgUCBwKTsKCiAgICAvKioKICAgICAqIFZpc2l0cyBhbiBlcnJvciB0eXBlLgogICAgICogQHBhcmFtIHQgdGhlIHR5cGUgdG8gdmlzaXQKICAgICAqIEBwYXJhbSBwIGEgdmlzaXRvci1zcGVjaWZpZWQgcGFyYW1ldGVyCiAgICAgKiBAcmV0dXJuICBhIHZpc2l0b3Itc3BlY2lmaWVkIHJlc3VsdAogICAgICovCiAgICBSIHZpc2l0RXJyb3IoRXJyb3JUeXBlIHQsIFAgcCk7CgogICAgLyoqCiAgICAgKiBWaXNpdHMgYSB0eXBlIHZhcmlhYmxlLgogICAgICogQHBhcmFtIHQgdGhlIHR5cGUgdG8gdmlzaXQKICAgICAqIEBwYXJhbSBwIGEgdmlzaXRvci1zcGVjaWZpZWQgcGFyYW1ldGVyCiAgICAgKiBAcmV0dXJuICBhIHZpc2l0b3Itc3BlY2lmaWVkIHJlc3VsdAogICAgICovCiAgICBSIHZpc2l0VHlwZVZhcmlhYmxlKFR5cGVWYXJpYWJsZSB0LCBQIHApOwoKICAgIC8qKgogICAgICogVmlzaXRzIGEgd2lsZGNhcmQgdHlwZS4KICAgICAqIEBwYXJhbSB0IHRoZSB0eXBlIHRvIHZpc2l0CiAgICAgKiBAcGFyYW0gcCBhIHZpc2l0b3Itc3BlY2lmaWVkIHBhcmFtZXRlcgogICAgICogQHJldHVybiAgYSB2aXNpdG9yLXNwZWNpZmllZCByZXN1bHQKICAgICAqLwogICAgUiB2aXNpdFdpbGRjYXJkKFdpbGRjYXJkVHlwZSB0LCBQIHApOwoKICAgIC8qKgogICAgICogVmlzaXRzIGFuIGV4ZWN1dGFibGUgdHlwZS4KICAgICAqIEBwYXJhbSB0IHRoZSB0eXBlIHRvIHZpc2l0CiAgICAgKiBAcGFyYW0gcCBhIHZpc2l0b3Itc3BlY2lmaWVkIHBhcmFtZXRlcgogICAgICogQHJldHVybiAgYSB2aXNpdG9yLXNwZWNpZmllZCByZXN1bHQKICAgICAqLwogICAgUiB2aXNpdEV4ZWN1dGFibGUoRXhlY3V0YWJsZVR5cGUgdCwgUCBwKTsKCiAgICAvKioKICAgICAqIFZpc2l0cyBhIHtAbGluayBOb1R5cGV9IGluc3RhbmNlLgogICAgICogQHBhcmFtIHQgdGhlIHR5cGUgdG8gdmlzaXQKICAgICAqIEBwYXJhbSBwIGEgdmlzaXRvci1zcGVjaWZpZWQgcGFyYW1ldGVyCiAgICAgKiBAcmV0dXJuICBhIHZpc2l0b3Itc3BlY2lmaWVkIHJlc3VsdAogICAgICovCiAgICBSIHZpc2l0Tm9UeXBlKE5vVHlwZSB0LCBQIHApOwoKICAgIC8qKgogICAgICogVmlzaXRzIGFuIHVua25vd24ga2luZCBvZiB0eXBlLgogICAgICogVGhpcyBjYW4gb2NjdXIgaWYgdGhlIGxhbmd1YWdlIGV2b2x2ZXMgYW5kIG5ldyBraW5kcwogICAgICogb2YgdHlwZXMgYXJlIGFkZGVkIHRvIHRoZSB7QGNvZGUgVHlwZU1pcnJvcn0gaGllcmFyY2h5LgogICAgICogQHBhcmFtIHQgdGhlIHR5cGUgdG8gdmlzaXQKICAgICAqIEBwYXJhbSBwIGEgdmlzaXRvci1zcGVjaWZpZWQgcGFyYW1ldGVyCiAgICAgKiBAcmV0dXJuICBhIHZpc2l0b3Itc3BlY2lmaWVkIHJlc3VsdAogICAgICogQHRocm93cyBVbmtub3duVHlwZUV4Y2VwdGlvbgogICAgICogIGEgdmlzaXRvciBpbXBsZW1lbnRhdGlvbiBtYXkgb3B0aW9uYWxseSB0aHJvdyB0aGlzIGV4Y2VwdGlvbgogICAgICovCiAgICBSIHZpc2l0VW5rbm93bihUeXBlTWlycm9yIHQsIFAgcCk7CgogICAgLyoqCiAgICAgKiBWaXNpdHMgYSB1bmlvbiB0eXBlLgogICAgICoKICAgICAqIEBwYXJhbSB0IHRoZSB0eXBlIHRvIHZpc2l0CiAgICAgKiBAcGFyYW0gcCBhIHZpc2l0b3Itc3BlY2lmaWVkIHBhcmFtZXRlcgogICAgICogQHJldHVybiAgYSB2aXNpdG9yLXNwZWNpZmllZCByZXN1bHQKICAgICAqIEBzaW5jZSAxLjcKICAgICAqLwogICAgUiB2aXNpdFVuaW9uKFVuaW9uVHlwZSB0LCBQIHApOwoKICAgIC8qKgogICAgICogVmlzaXRzIGFuIGludGVyc2VjdGlvbiB0eXBlLgogICAgICoKICAgICAqIEBwYXJhbSB0IHRoZSB0eXBlIHRvIHZpc2l0CiAgICAgKiBAcGFyYW0gcCBhIHZpc2l0b3Itc3BlY2lmaWVkIHBhcmFtZXRlcgogICAgICogQHJldHVybiAgYSB2aXNpdG9yLXNwZWNpZmllZCByZXN1bHQKICAgICAqIEBzaW5jZSAxLjgKICAgICAqLwogICAgUiB2aXNpdEludGVyc2VjdGlvbihJbnRlcnNlY3Rpb25UeXBlIHQsIFAgcCk7Cn0KUEsDBAoAAAgAANJ9TUq8QnFAcAsAAHALAAAwAAAAamF2YXgvbGFuZy9tb2RlbC90eXBlL01pcnJvcmVkVHlwZUV4Y2VwdGlvbi5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDA1LCAyMDE0LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGphdmF4LmxhbmcubW9kZWwudHlwZTsKCmltcG9ydCBqYXZhLmlvLk9iamVjdElucHV0U3RyZWFtOwppbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC5FbGVtZW50OwoKCi8qKgogKiBUaHJvd24gd2hlbiBhbiBhcHBsaWNhdGlvbiBhdHRlbXB0cyB0byBhY2Nlc3MgdGhlIHtAbGluayBDbGFzc30gb2JqZWN0CiAqIGNvcnJlc3BvbmRpbmcgdG8gYSB7QGxpbmsgVHlwZU1pcnJvcn0uCiAqCiAqIEBhdXRob3IgSm9zZXBoIEQuIERhcmN5CiAqIEBhdXRob3IgU2NvdHQgU2VsaWdtYW4KICogQGF1dGhvciBQZXRlciB2b24gZGVyIEFoJmVhY3V0ZTsKICogQHNlZSBNaXJyb3JlZFR5cGVzRXhjZXB0aW9uCiAqIEBzZWUgRWxlbWVudCNnZXRBbm5vdGF0aW9uKENsYXNzKQogKiBAc2luY2UgMS42CiAqLwpwdWJsaWMgY2xhc3MgTWlycm9yZWRUeXBlRXhjZXB0aW9uIGV4dGVuZHMgTWlycm9yZWRUeXBlc0V4Y2VwdGlvbiB7CgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMjY5OwoKICAgIHByaXZhdGUgdHJhbnNpZW50IFR5cGVNaXJyb3IgdHlwZTsgICAgICAgICAgLy8gY2Fubm90IGJlIHNlcmlhbGl6ZWQKCiAgICAvKioKICAgICAqIENvbnN0cnVjdHMgYSBuZXcgTWlycm9yZWRUeXBlRXhjZXB0aW9uIGZvciB0aGUgc3BlY2lmaWVkIHR5cGUuCiAgICAgKgogICAgICogQHBhcmFtIHR5cGUgIHRoZSB0eXBlIGJlaW5nIGFjY2Vzc2VkCiAgICAgKi8KICAgIHB1YmxpYyBNaXJyb3JlZFR5cGVFeGNlcHRpb24oVHlwZU1pcnJvciB0eXBlKSB7CiAgICAgICAgc3VwZXIoIkF0dGVtcHQgdG8gYWNjZXNzIENsYXNzIG9iamVjdCBmb3IgVHlwZU1pcnJvciAiICsgdHlwZS50b1N0cmluZygpLCB0eXBlKTsKICAgICAgICB0aGlzLnR5cGUgPSB0eXBlOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgdHlwZSBtaXJyb3IgY29ycmVzcG9uZGluZyB0byB0aGUgdHlwZSBiZWluZyBhY2Nlc3NlZC4KICAgICAqIFRoZSB0eXBlIG1pcnJvciBtYXkgYmUgdW5hdmFpbGFibGUgaWYgdGhpcyBleGNlcHRpb24gaGFzIGJlZW4KICAgICAqIHNlcmlhbGl6ZWQgYW5kIHRoZW4gcmVhZCBiYWNrIGluLgogICAgICoKICAgICAqIEByZXR1cm4gdGhlIHR5cGUgbWlycm9yLCBvciB7QGNvZGUgbnVsbH0gaWYgdW5hdmFpbGFibGUKICAgICAqLwogICAgcHVibGljIFR5cGVNaXJyb3IgZ2V0VHlwZU1pcnJvcigpIHsKICAgICAgICByZXR1cm4gdHlwZTsKICAgIH0KCiAgICAvKioKICAgICAqIEV4cGxpY2l0bHkgc2V0IGFsbCB0cmFuc2llbnQgZmllbGRzLgogICAgICogQHBhcmFtIHMgdGhlIHNlcmlhbCBzdHJlYW0KICAgICAqIEB0aHJvd3MgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiBmb3IgYSBtaXNzaW5nIGNsYXNzIGR1cmluZwogICAgICogZGVzZXJpYWxpemF0aW9uCiAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGZvciBhbiBJTyBwcm9ibGVtIGR1cmluZyBkZXNlcmlhbGl6YXRpb24KICAgICAqLwogICAgcHJpdmF0ZSB2b2lkIHJlYWRPYmplY3QoT2JqZWN0SW5wdXRTdHJlYW0gcykKICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIENsYXNzTm90Rm91bmRFeGNlcHRpb24gewogICAgICAgIHMuZGVmYXVsdFJlYWRPYmplY3QoKTsKICAgICAgICB0eXBlID0gbnVsbDsKICAgICAgICB0eXBlcyA9IG51bGw7CiAgICB9Cn0KUEsDBAoAAAgAANJ9TUpK7snx1wUAANcFAAAjAAAAamF2YXgvbGFuZy9tb2RlbC90eXBlL051bGxUeXBlLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMDYsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgamF2YXgubGFuZy5tb2RlbC50eXBlOwoKCi8qKgogKiBSZXByZXNlbnRzIHRoZSBudWxsIHR5cGUuCiAqIFRoaXMgaXMgdGhlIHR5cGUgb2YgdGhlIGV4cHJlc3Npb24ge0Bjb2RlIG51bGx9LAogKgogKiBAYXV0aG9yIEpvc2VwaCBELiBEYXJjeQogKiBAYXV0aG9yIFNjb3R0IFNlbGlnbWFuCiAqIEBhdXRob3IgUGV0ZXIgdm9uIGRlciBBaCZlYWN1dGU7CiAqIEBzaW5jZSAxLjYKICovCgpwdWJsaWMgaW50ZXJmYWNlIE51bGxUeXBlIGV4dGVuZHMgUmVmZXJlbmNlVHlwZSB7Cn0KUEsDBAoAAAgAANJ9TUqDHKXayQwAAMkMAAAnAAAAamF2YXgvbGFuZy9tb2RlbC90eXBlL0RlY2xhcmVkVHlwZS5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDA1LCAyMDEzLCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGphdmF4LmxhbmcubW9kZWwudHlwZTsKCgppbXBvcnQgamF2YS51dGlsLkxpc3Q7CgppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5lbGVtZW50LkVsZW1lbnQ7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuVHlwZUVsZW1lbnQ7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLnV0aWwuVHlwZXM7CgoKLyoqCiAqIFJlcHJlc2VudHMgYSBkZWNsYXJlZCB0eXBlLCBlaXRoZXIgYSBjbGFzcyB0eXBlIG9yIGFuIGludGVyZmFjZSB0eXBlLgogKiBUaGlzIGluY2x1ZGVzIHBhcmFtZXRlcml6ZWQgdHlwZXMgc3VjaCBhcyB7QGNvZGUgamF2YS51dGlsLlNldDxTdHJpbmc+fQogKiBhcyB3ZWxsIGFzIHJhdyB0eXBlcy4KICoKICogPHA+IFdoaWxlIGEge0Bjb2RlIFR5cGVFbGVtZW50fSByZXByZXNlbnRzIGEgY2xhc3Mgb3IgaW50ZXJmYWNlCiAqIDxpPmVsZW1lbnQ8L2k+LCBhIHtAY29kZSBEZWNsYXJlZFR5cGV9IHJlcHJlc2VudHMgYSBjbGFzcwogKiBvciBpbnRlcmZhY2UgPGk+dHlwZTwvaT4sIHRoZSBsYXR0ZXIgYmVpbmcgYSB1c2UKICogKG9yIDxpPmludm9jYXRpb248L2k+KSBvZiB0aGUgZm9ybWVyLgogKiBTZWUge0BsaW5rIFR5cGVFbGVtZW50fSBmb3IgbW9yZSBvbiB0aGlzIGRpc3RpbmN0aW9uLgogKgogKiA8cD4gVGhlIHN1cGVydHlwZXMgKGJvdGggY2xhc3MgYW5kIGludGVyZmFjZSB0eXBlcykgb2YgYSBkZWNsYXJlZAogKiB0eXBlIG1heSBiZSBmb3VuZCB1c2luZyB0aGUge0BsaW5rCiAqIFR5cGVzI2RpcmVjdFN1cGVydHlwZXMoVHlwZU1pcnJvcil9IG1ldGhvZC4gIFRoaXMgcmV0dXJucyB0aGUKICogc3VwZXJ0eXBlcyB3aXRoIGFueSB0eXBlIGFyZ3VtZW50cyBzdWJzdGl0dXRlZCBpbi4KICoKICogQGF1dGhvciBKb3NlcGggRC4gRGFyY3kKICogQGF1dGhvciBTY290dCBTZWxpZ21hbgogKiBAYXV0aG9yIFBldGVyIHZvbiBkZXIgQWgmZWFjdXRlOwogKiBAc2VlIFR5cGVFbGVtZW50CiAqIEBzaW5jZSAxLjYKICovCnB1YmxpYyBpbnRlcmZhY2UgRGVjbGFyZWRUeXBlIGV4dGVuZHMgUmVmZXJlbmNlVHlwZSB7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBlbGVtZW50IGNvcnJlc3BvbmRpbmcgdG8gdGhpcyB0eXBlLgogICAgICoKICAgICAqIEByZXR1cm4gdGhlIGVsZW1lbnQgY29ycmVzcG9uZGluZyB0byB0aGlzIHR5cGUKICAgICAqLwogICAgRWxlbWVudCBhc0VsZW1lbnQoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHR5cGUgb2YgdGhlIGlubmVybW9zdCBlbmNsb3NpbmcgaW5zdGFuY2Ugb3IgYQogICAgICoge0Bjb2RlIE5vVHlwZX0gb2Yga2luZCB7QGNvZGUgTk9ORX0gaWYgdGhlcmUgaXMgbm8gZW5jbG9zaW5nCiAgICAgKiBpbnN0YW5jZS4gIE9ubHkgdHlwZXMgY29ycmVzcG9uZGluZyB0byBpbm5lciBjbGFzc2VzIGhhdmUgYW4KICAgICAqIGVuY2xvc2luZyBpbnN0YW5jZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIGEgdHlwZSBtaXJyb3IgZm9yIHRoZSBlbmNsb3NpbmcgdHlwZQogICAgICogQGpscyA4LjEuMyBJbm5lciBDbGFzc2VzIGFuZCBFbmNsb3NpbmcgSW5zdGFuY2VzCiAgICAgKiBAamxzIDE1LjkuMiBEZXRlcm1pbmluZyBFbmNsb3NpbmcgSW5zdGFuY2VzCiAgICAgKi8KICAgIFR5cGVNaXJyb3IgZ2V0RW5jbG9zaW5nVHlwZSgpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgYWN0dWFsIHR5cGUgYXJndW1lbnRzIG9mIHRoaXMgdHlwZS4KICAgICAqIEZvciBhIHR5cGUgbmVzdGVkIHdpdGhpbiBhIHBhcmFtZXRlcml6ZWQgdHlwZQogICAgICogKHN1Y2ggYXMge0Bjb2RlIE91dGVyPFN0cmluZz4uSW5uZXI8TnVtYmVyPn0pLCBvbmx5IHRoZSB0eXBlCiAgICAgKiBhcmd1bWVudHMgb2YgdGhlIGlubmVybW9zdCB0eXBlIGFyZSBpbmNsdWRlZC4KICAgICAqCiAgICAgKiBAcmV0dXJuIHRoZSBhY3R1YWwgdHlwZSBhcmd1bWVudHMgb2YgdGhpcyB0eXBlLCBvciBhbiBlbXB0eSBsaXN0CiAgICAgKiAgICAgICAgICAgaWYgbm9uZQogICAgICovCiAgICBMaXN0PD8gZXh0ZW5kcyBUeXBlTWlycm9yPiBnZXRUeXBlQXJndW1lbnRzKCk7Cn0KUEsDBAoAAAgAANJ9TUpNUCA3jA0AAIwNAAAxAAAAamF2YXgvbGFuZy9tb2RlbC90eXBlL01pcnJvcmVkVHlwZXNFeGNlcHRpb24uamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAxNCwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBqYXZheC5sYW5nLm1vZGVsLnR5cGU7CgppbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKaW1wb3J0IGphdmEudXRpbC5MaXN0OwppbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOwppbXBvcnQgamF2YS5pby5PYmplY3RJbnB1dFN0cmVhbTsKaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuRWxlbWVudDsKCgovKioKICogVGhyb3duIHdoZW4gYW4gYXBwbGljYXRpb24gYXR0ZW1wdHMgdG8gYWNjZXNzIGEgc2VxdWVuY2Ugb2Yge0BsaW5rCiAqIENsYXNzfSBvYmplY3RzIGVhY2ggY29ycmVzcG9uZGluZyB0byBhIHtAbGluayBUeXBlTWlycm9yfS4KICoKICogQGF1dGhvciBKb3NlcGggRC4gRGFyY3kKICogQGF1dGhvciBTY290dCBTZWxpZ21hbgogKiBAYXV0aG9yIFBldGVyIHZvbiBkZXIgQWgmZWFjdXRlOwogKiBAc2VlIE1pcnJvcmVkVHlwZUV4Y2VwdGlvbgogKiBAc2VlIEVsZW1lbnQjZ2V0QW5ub3RhdGlvbihDbGFzcykKICogQHNpbmNlIDEuNgogKi8KcHVibGljIGNsYXNzIE1pcnJvcmVkVHlwZXNFeGNlcHRpb24gZXh0ZW5kcyBSdW50aW1lRXhjZXB0aW9uIHsKCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAyNjk7CgogICAgdHJhbnNpZW50IExpc3Q8PyBleHRlbmRzIFR5cGVNaXJyb3I+IHR5cGVzOyAvLyBjYW5ub3QgYmUgc2VyaWFsaXplZAoKICAgIC8qCiAgICAgKiBUcnVzdGVkIGNvbnN0cnVjdG9yIHRvIGJlIGNhbGxlZCBieSBNaXJyb3JlZFR5cGVFeGNlcHRpb24uCiAgICAgKi8KICAgIE1pcnJvcmVkVHlwZXNFeGNlcHRpb24oU3RyaW5nIG1lc3NhZ2UsIFR5cGVNaXJyb3IgdHlwZSkgewogICAgICAgIHN1cGVyKG1lc3NhZ2UpOwogICAgICAgIExpc3Q8VHlwZU1pcnJvcj4gdG1wID0gKG5ldyBBcnJheUxpc3Q8PigpKTsKICAgICAgICB0bXAuYWRkKHR5cGUpOwogICAgICAgIHR5cGVzID0gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdCh0bXApOwogICAgfQoKICAgIC8qKgogICAgICogQ29uc3RydWN0cyBhIG5ldyBNaXJyb3JlZFR5cGVzRXhjZXB0aW9uIGZvciB0aGUgc3BlY2lmaWVkIHR5cGVzLgogICAgICoKICAgICAqIEBwYXJhbSB0eXBlcyAgdGhlIHR5cGVzIGJlaW5nIGFjY2Vzc2VkCiAgICAgKi8KICAgIHB1YmxpYyBNaXJyb3JlZFR5cGVzRXhjZXB0aW9uKExpc3Q8PyBleHRlbmRzIFR5cGVNaXJyb3I+IHR5cGVzKSB7CiAgICAgICAgc3VwZXIoIkF0dGVtcHQgdG8gYWNjZXNzIENsYXNzIG9iamVjdHMgZm9yIFR5cGVNaXJyb3JzICIgKwogICAgICAgICAgICAgICh0eXBlcyA9IC8vIGRlZmVuc2l2ZSBjb3B5CiAgICAgICAgICAgICAgIG5ldyBBcnJheUxpc3Q8Pih0eXBlcykpLnRvU3RyaW5nKCkgKTsKICAgICAgICB0aGlzLnR5cGVzID0gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdCh0eXBlcyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSB0eXBlIG1pcnJvcnMgY29ycmVzcG9uZGluZyB0byB0aGUgdHlwZXMgYmVpbmcgYWNjZXNzZWQuCiAgICAgKiBUaGUgdHlwZSBtaXJyb3JzIG1heSBiZSB1bmF2YWlsYWJsZSBpZiB0aGlzIGV4Y2VwdGlvbiBoYXMgYmVlbgogICAgICogc2VyaWFsaXplZCBhbmQgdGhlbiByZWFkIGJhY2sgaW4uCiAgICAgKgogICAgICogQHJldHVybiB0aGUgdHlwZSBtaXJyb3JzIGluIGNvbnN0cnVjdGlvbiBvcmRlciwgb3Ige0Bjb2RlIG51bGx9IGlmIHVuYXZhaWxhYmxlCiAgICAgKi8KICAgIHB1YmxpYyBMaXN0PD8gZXh0ZW5kcyBUeXBlTWlycm9yPiBnZXRUeXBlTWlycm9ycygpIHsKICAgICAgICByZXR1cm4gdHlwZXM7CiAgICB9CgogICAgLyoqCiAgICAgKiBFeHBsaWNpdGx5IHNldCBhbGwgdHJhbnNpZW50IGZpZWxkcy4KICAgICAqIEBwYXJhbSBzIHRoZSBzZXJpYWwgc3RyZWFtCiAgICAgKiBAdGhyb3dzIENsYXNzTm90Rm91bmRFeGNlcHRpb24gZm9yIGEgbWlzc2luZyBjbGFzcyBkdXJpbmcKICAgICAqIGRlc2VyaWFsaXphdGlvbgogICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBmb3IgYW4gSU8gcHJvYmxlbSBkdXJpbmcgZGVzZXJpYWxpemF0aW9uCiAgICAgKi8KICAgIHByaXZhdGUgdm9pZCByZWFkT2JqZWN0KE9iamVjdElucHV0U3RyZWFtIHMpCiAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBDbGFzc05vdEZvdW5kRXhjZXB0aW9uIHsKICAgICAgICBzLmRlZmF1bHRSZWFkT2JqZWN0KCk7CiAgICAgICAgdHlwZXMgPSBudWxsOwogICAgfQp9ClBLAwQKAAAIAAAGO6lKAAAAAAAAAAAAAAAAGQAAAGphdmF4L2xhbmcvbW9kZWwvZWxlbWVudC9QSwMECgAACAAABjupSvqSBjs4JgAAOCYAACUAAABqYXZheC9sYW5nL21vZGVsL2VsZW1lbnQvRWxlbWVudC5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDA1LCAyMDE3LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGphdmF4LmxhbmcubW9kZWwuZWxlbWVudDsKCgppbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uQW5ub3RhdGlvbjsKaW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLkFubm90YXRpb25UeXBlTWlzbWF0Y2hFeGNlcHRpb247CmltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5JbmNvbXBsZXRlQW5ub3RhdGlvbkV4Y2VwdGlvbjsKaW1wb3J0IGphdmEudXRpbC5MaXN0OwppbXBvcnQgamF2YS51dGlsLlNldDsKCmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLnR5cGUuKjsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwudXRpbC4qOwoKCi8qKgogKiBSZXByZXNlbnRzIGEgcHJvZ3JhbSBlbGVtZW50IHN1Y2ggYXMgYSBtb2R1bGUsIHBhY2thZ2UsIGNsYXNzLCBvciBtZXRob2QuCiAqIEVhY2ggZWxlbWVudCByZXByZXNlbnRzIGEgc3RhdGljLCBsYW5ndWFnZS1sZXZlbCBjb25zdHJ1Y3QKICogKGFuZCBub3QsIGZvciBleGFtcGxlLCBhIHJ1bnRpbWUgY29uc3RydWN0IG9mIHRoZSB2aXJ0dWFsIG1hY2hpbmUpLgogKgogKiA8cD4gRWxlbWVudHMgc2hvdWxkIGJlIGNvbXBhcmVkIHVzaW5nIHRoZSB7QGxpbmsgI2VxdWFscyhPYmplY3QpfQogKiBtZXRob2QuICBUaGVyZSBpcyBubyBndWFyYW50ZWUgdGhhdCBhbnkgcGFydGljdWxhciBlbGVtZW50IHdpbGwKICogYWx3YXlzIGJlIHJlcHJlc2VudGVkIGJ5IHRoZSBzYW1lIG9iamVjdC4KICoKICogPHA+IFRvIGltcGxlbWVudCBvcGVyYXRpb25zIGJhc2VkIG9uIHRoZSBjbGFzcyBvZiBhbiB7QGNvZGUKICogRWxlbWVudH0gb2JqZWN0LCBlaXRoZXIgdXNlIGEge0BsaW5rcGxhaW4gRWxlbWVudFZpc2l0b3IgdmlzaXRvcn0gb3IKICogdXNlIHRoZSByZXN1bHQgb2YgdGhlIHtAbGluayAjZ2V0S2luZH0gbWV0aG9kLiAgVXNpbmcge0Bjb2RlCiAqIGluc3RhbmNlb2Z9IGlzIDxlbT5ub3Q8L2VtPiBuZWNlc3NhcmlseSBhIHJlbGlhYmxlIGlkaW9tIGZvcgogKiBkZXRlcm1pbmluZyB0aGUgZWZmZWN0aXZlIGNsYXNzIG9mIGFuIG9iamVjdCBpbiB0aGlzIG1vZGVsaW5nCiAqIGhpZXJhcmNoeSBzaW5jZSBhbiBpbXBsZW1lbnRhdGlvbiBtYXkgY2hvb3NlIHRvIGhhdmUgYSBzaW5nbGUgb2JqZWN0CiAqIGltcGxlbWVudCBtdWx0aXBsZSB7QGNvZGUgRWxlbWVudH0gc3ViaW50ZXJmYWNlcy4KICoKICogQGF1dGhvciBKb3NlcGggRC4gRGFyY3kKICogQGF1dGhvciBTY290dCBTZWxpZ21hbgogKiBAYXV0aG9yIFBldGVyIHZvbiBkZXIgQWgmZWFjdXRlOwogKiBAc2VlIEVsZW1lbnRzCiAqIEBzZWUgVHlwZU1pcnJvcgogKiBAc2luY2UgMS42CiAqLwpwdWJsaWMgaW50ZXJmYWNlIEVsZW1lbnQgZXh0ZW5kcyBqYXZheC5sYW5nLm1vZGVsLkFubm90YXRlZENvbnN0cnVjdCB7CiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHR5cGUgZGVmaW5lZCBieSB0aGlzIGVsZW1lbnQuCiAgICAgKgogICAgICogPHA+IEEgZ2VuZXJpYyBlbGVtZW50IGRlZmluZXMgYSBmYW1pbHkgb2YgdHlwZXMsIG5vdCBqdXN0IG9uZS4KICAgICAqIElmIHRoaXMgaXMgYSBnZW5lcmljIGVsZW1lbnQsIGEgPGk+cHJvdG90eXBpY2FsPC9pPiB0eXBlIGlzCiAgICAgKiByZXR1cm5lZC4gIFRoaXMgaXMgdGhlIGVsZW1lbnQncyBpbnZvY2F0aW9uIG9uIHRoZQogICAgICogdHlwZSB2YXJpYWJsZXMgY29ycmVzcG9uZGluZyB0byBpdHMgb3duIGZvcm1hbCB0eXBlIHBhcmFtZXRlcnMuCiAgICAgKiBGb3IgZXhhbXBsZSwKICAgICAqIGZvciB0aGUgZ2VuZXJpYyBjbGFzcyBlbGVtZW50IHtAY29kZSBDPE4gZXh0ZW5kcyBOdW1iZXI+fSwKICAgICAqIHRoZSBwYXJhbWV0ZXJpemVkIHR5cGUge0Bjb2RlIEM8Tj59IGlzIHJldHVybmVkLgogICAgICogVGhlIHtAbGluayBUeXBlc30gdXRpbGl0eSBpbnRlcmZhY2UgaGFzIG1vcmUgZ2VuZXJhbCBtZXRob2RzCiAgICAgKiBmb3Igb2J0YWluaW5nIHRoZSBmdWxsIHJhbmdlIG9mIHR5cGVzIGRlZmluZWQgYnkgYW4gZWxlbWVudC4KICAgICAqCiAgICAgKiBAc2VlIFR5cGVzCiAgICAgKgogICAgICogQHJldHVybiB0aGUgdHlwZSBkZWZpbmVkIGJ5IHRoaXMgZWxlbWVudAogICAgICovCiAgICBUeXBlTWlycm9yIGFzVHlwZSgpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUge0Bjb2RlIGtpbmR9IG9mIHRoaXMgZWxlbWVudC4KICAgICAqCiAgICAgKiBAcmV0dXJuIHRoZSBraW5kIG9mIHRoaXMgZWxlbWVudAogICAgICovCiAgICBFbGVtZW50S2luZCBnZXRLaW5kKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBtb2RpZmllcnMgb2YgdGhpcyBlbGVtZW50LCBleGNsdWRpbmcgYW5ub3RhdGlvbnMuCiAgICAgKiBJbXBsaWNpdCBtb2RpZmllcnMsIHN1Y2ggYXMgdGhlIHtAY29kZSBwdWJsaWN9IGFuZCB7QGNvZGUgc3RhdGljfQogICAgICogbW9kaWZpZXJzIG9mIGludGVyZmFjZSBtZW1iZXJzLCBhcmUgaW5jbHVkZWQuCiAgICAgKgogICAgICogQHJldHVybiB0aGUgbW9kaWZpZXJzIG9mIHRoaXMgZWxlbWVudCwgb3IgYW4gZW1wdHkgc2V0IGlmIHRoZXJlIGFyZSBub25lCiAgICAgKi8KICAgIFNldDxNb2RpZmllcj4gZ2V0TW9kaWZpZXJzKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBzaW1wbGUgKHVucXVhbGlmaWVkKSBuYW1lIG9mIHRoaXMgZWxlbWVudC4gIFRoZQogICAgICogbmFtZSBvZiBhIGdlbmVyaWMgdHlwZSBkb2VzIG5vdCBpbmNsdWRlIGFueSByZWZlcmVuY2UgdG8gaXRzCiAgICAgKiBmb3JtYWwgdHlwZSBwYXJhbWV0ZXJzLgogICAgICoKICAgICAqIEZvciBleGFtcGxlLCB0aGUgc2ltcGxlIG5hbWUgb2YgdGhlIHR5cGUgZWxlbWVudCB7QGNvZGUKICAgICAqIGphdmEudXRpbC5TZXQ8RT59IGlzIHtAY29kZSAiU2V0In0uCiAgICAgKgogICAgICogSWYgdGhpcyBlbGVtZW50IHJlcHJlc2VudHMgYW4gdW5uYW1lZCB7QGxpbmtwbGFpbgogICAgICogUGFja2FnZUVsZW1lbnQjZ2V0U2ltcGxlTmFtZSBwYWNrYWdlfSBvciB1bm5hbWVkIHtAbGlua3BsYWluCiAgICAgKiBNb2R1bGVFbGVtZW50I2dldFNpbXBsZU5hbWUgbW9kdWxlfSwgYW4gZW1wdHkgbmFtZSBpcyByZXR1cm5lZC4KICAgICAqCiAgICAgKiBJZiBpdCByZXByZXNlbnRzIGEge0BsaW5rcGxhaW4gRXhlY3V0YWJsZUVsZW1lbnQjZ2V0U2ltcGxlTmFtZQogICAgICogY29uc3RydWN0b3J9LCB0aGUgbmFtZSAie0Bjb2RlIDxpbml0Pn0iIGlzIHJldHVybmVkLiAgSWYgaXQKICAgICAqIHJlcHJlc2VudHMgYSB7QGxpbmtwbGFpbiBFeGVjdXRhYmxlRWxlbWVudCNnZXRTaW1wbGVOYW1lIHN0YXRpYwogICAgICogaW5pdGlhbGl6ZXJ9LCB0aGUgbmFtZSAie0Bjb2RlIDxjbGluaXQ+fSIgaXMgcmV0dXJuZWQuCiAgICAgKgogICAgICogSWYgaXQgcmVwcmVzZW50cyBhbiB7QGxpbmtwbGFpbiBUeXBlRWxlbWVudCNnZXRTaW1wbGVOYW1lCiAgICAgKiBhbm9ueW1vdXMgY2xhc3N9IG9yIHtAbGlua3BsYWluIEV4ZWN1dGFibGVFbGVtZW50I2dldFNpbXBsZU5hbWUKICAgICAqIGluc3RhbmNlIGluaXRpYWxpemVyfSwgYW4gZW1wdHkgbmFtZSBpcyByZXR1cm5lZC4KICAgICAqCiAgICAgKiBAcmV0dXJuIHRoZSBzaW1wbGUgbmFtZSBvZiB0aGlzIGVsZW1lbnQKICAgICAqIEBzZWUgUGFja2FnZUVsZW1lbnQjZ2V0U2ltcGxlTmFtZQogICAgICogQHNlZSBFeGVjdXRhYmxlRWxlbWVudCNnZXRTaW1wbGVOYW1lCiAgICAgKiBAc2VlIFR5cGVFbGVtZW50I2dldFNpbXBsZU5hbWUKICAgICAqIEBzZWUgVmFyaWFibGVFbGVtZW50I2dldFNpbXBsZU5hbWUKICAgICAqIEBzZWUgTW9kdWxlRWxlbWVudCNnZXRTaW1wbGVOYW1lCiAgICAgKiBAcmV2aXNlZCA5CiAgICAgKiBAc3BlYyBKUE1TCiAgICAgKi8KICAgIE5hbWUgZ2V0U2ltcGxlTmFtZSgpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgaW5uZXJtb3N0IGVsZW1lbnQKICAgICAqIHdpdGhpbiB3aGljaCB0aGlzIGVsZW1lbnQgaXMsIGxvb3NlbHkgc3BlYWtpbmcsIGVuY2xvc2VkLgogICAgICogPHVsPgogICAgICogPGxpPiBJZiB0aGlzIGVsZW1lbnQgaXMgb25lIHdob3NlIGRlY2xhcmF0aW9uIGlzIGxleGljYWxseSBlbmNsb3NlZAogICAgICogaW1tZWRpYXRlbHkgd2l0aGluIHRoZSBkZWNsYXJhdGlvbiBvZiBhbm90aGVyIGVsZW1lbnQsIHRoYXQgb3RoZXIKICAgICAqIGVsZW1lbnQgaXMgcmV0dXJuZWQuCiAgICAgKgogICAgICogPGxpPiBJZiB0aGlzIGlzIGEge0BsaW5rcGxhaW4gVHlwZUVsZW1lbnQjZ2V0RW5jbG9zaW5nRWxlbWVudAogICAgICogdG9wLWxldmVsIHR5cGV9LCBpdHMgcGFja2FnZSBpcyByZXR1cm5lZC4KICAgICAqCiAgICAgKiA8bGk+IElmIHRoaXMgaXMgYSB7QGxpbmtwbGFpbgogICAgICogUGFja2FnZUVsZW1lbnQjZ2V0RW5jbG9zaW5nRWxlbWVudCBwYWNrYWdlfSwgaXRzIG1vZHVsZSBpcwogICAgICogcmV0dXJuZWQgaWYgc3VjaCBhIG1vZHVsZSBleGlzdHMuIE90aGVyd2lzZSwge0Bjb2RlIG51bGx9IGlzIHJldHVybmVkLgogICAgICoKICAgICAqIDxsaT4gSWYgdGhpcyBpcyBhIHtAbGlua3BsYWluCiAgICAgKiBUeXBlUGFyYW1ldGVyRWxlbWVudCNnZXRFbmNsb3NpbmdFbGVtZW50IHR5cGUgcGFyYW1ldGVyfSwKICAgICAqIHtAbGlua3BsYWluIFR5cGVQYXJhbWV0ZXJFbGVtZW50I2dldEdlbmVyaWNFbGVtZW50IHRoZQogICAgICogZ2VuZXJpYyBlbGVtZW50fSBvZiB0aGUgdHlwZSBwYXJhbWV0ZXIgaXMgcmV0dXJuZWQuCiAgICAgKgogICAgICogPGxpPiBJZiB0aGlzIGlzIGEge0BsaW5rcGxhaW4KICAgICAqIFZhcmlhYmxlRWxlbWVudCNnZXRFbmNsb3NpbmdFbGVtZW50IG1ldGhvZCBvciBjb25zdHJ1Y3RvcgogICAgICogcGFyYW1ldGVyfSwge0BsaW5rcGxhaW4gRXhlY3V0YWJsZUVsZW1lbnQgdGhlIGV4ZWN1dGFibGUKICAgICAqIGVsZW1lbnR9IHdoaWNoIGRlY2xhcmVzIHRoZSBwYXJhbWV0ZXIgaXMgcmV0dXJuZWQuCiAgICAgKgogICAgICogPGxpPiBJZiB0aGlzIGlzIGEge0BsaW5rcGxhaW4gTW9kdWxlRWxlbWVudCNnZXRFbmNsb3NpbmdFbGVtZW50CiAgICAgKiBtb2R1bGV9LCB7QGNvZGUgbnVsbH0gaXMgcmV0dXJuZWQuCiAgICAgKgogICAgICogPC91bD4KICAgICAqCiAgICAgKiBAcmV0dXJuIHRoZSBlbmNsb3NpbmcgZWxlbWVudCwgb3Ige0Bjb2RlIG51bGx9IGlmIHRoZXJlIGlzIG5vbmUKICAgICAqIEBzZWUgRWxlbWVudHMjZ2V0UGFja2FnZU9mCiAgICAgKiBAcmV2aXNlZCA5CiAgICAgKiBAc3BlYyBKUE1TCiAgICAgKi8KICAgIEVsZW1lbnQgZ2V0RW5jbG9zaW5nRWxlbWVudCgpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgZWxlbWVudHMgdGhhdCBhcmUsIGxvb3NlbHkgc3BlYWtpbmcsIGRpcmVjdGx5CiAgICAgKiBlbmNsb3NlZCBieSB0aGlzIGVsZW1lbnQuCiAgICAgKgogICAgICogQSB7QGxpbmtwbGFpbiBUeXBlRWxlbWVudCNnZXRFbmNsb3NlZEVsZW1lbnRzIGNsYXNzIG9yCiAgICAgKiBpbnRlcmZhY2V9IGlzIGNvbnNpZGVyZWQgdG8gZW5jbG9zZSB0aGUgZmllbGRzLCBtZXRob2RzLAogICAgICogY29uc3RydWN0b3JzLCBhbmQgbWVtYmVyIHR5cGVzIHRoYXQgaXQgZGlyZWN0bHkgZGVjbGFyZXMuCiAgICAgKgogICAgICogQSB7QGxpbmtwbGFpbiBQYWNrYWdlRWxlbWVudCNnZXRFbmNsb3NlZEVsZW1lbnRzIHBhY2thZ2V9CiAgICAgKiBlbmNsb3NlcyB0aGUgdG9wLWxldmVsIGNsYXNzZXMgYW5kIGludGVyZmFjZXMgd2l0aGluIGl0LCBidXQgaXMKICAgICAqIG5vdCBjb25zaWRlcmVkIHRvIGVuY2xvc2Ugc3VicGFja2FnZXMuCiAgICAgKgogICAgICogQSB7QGxpbmtwbGFpbiBNb2R1bGVFbGVtZW50I2dldEVuY2xvc2VkRWxlbWVudHMgbW9kdWxlfQogICAgICogZW5jbG9zZXMgcGFja2FnZXMgd2l0aGluIGl0LgogICAgICoKICAgICAqIEVuY2xvc2VkIGVsZW1lbnRzIG1heSBpbmNsdWRlIGltcGxpY2l0bHkgZGVjbGFyZWQge0BsaW5rcGxhaW4KICAgICAqIEVsZW1lbnRzLk9yaWdpbiNNQU5EQVRFRCBtYW5kYXRlZH0gZWxlbWVudHMuCiAgICAgKgogICAgICogT3RoZXIga2luZHMgb2YgZWxlbWVudHMgYXJlIG5vdCBjdXJyZW50bHkgY29uc2lkZXJlZCB0byBlbmNsb3NlCiAgICAgKiBhbnkgZWxlbWVudHM7IGhvd2V2ZXIsIHRoYXQgbWF5IGNoYW5nZSBhcyB0aGlzIEFQSSBvciB0aGUKICAgICAqIHByb2dyYW1taW5nIGxhbmd1YWdlIGV2b2x2ZXMuCiAgICAgKgogICAgICogQGFwaU5vdGUgRWxlbWVudHMgb2YgY2VydGFpbiBraW5kcyBjYW4gYmUgaXNvbGF0ZWQgdXNpbmcKICAgICAqIG1ldGhvZHMgaW4ge0BsaW5rIEVsZW1lbnRGaWx0ZXJ9LgogICAgICoKICAgICAqIEByZXR1cm4gdGhlIGVuY2xvc2VkIGVsZW1lbnRzLCBvciBhbiBlbXB0eSBsaXN0IGlmIG5vbmUKICAgICAqIEBzZWUgVHlwZUVsZW1lbnQjZ2V0RW5jbG9zZWRFbGVtZW50cwogICAgICogQHNlZSBQYWNrYWdlRWxlbWVudCNnZXRFbmNsb3NlZEVsZW1lbnRzCiAgICAgKiBAc2VlIE1vZHVsZUVsZW1lbnQjZ2V0RW5jbG9zZWRFbGVtZW50cwogICAgICogQHNlZSBFbGVtZW50cyNnZXRBbGxNZW1iZXJzCiAgICAgKiBAamxzIDguOC45IERlZmF1bHQgQ29uc3RydWN0b3IKICAgICAqIEBqbHMgOC45IEVudW1zCiAgICAgKiBAcmV2aXNlZCA5CiAgICAgKiBAc3BlYyBKUE1TCiAgICAgKi8KICAgIExpc3Q8PyBleHRlbmRzIEVsZW1lbnQ+IGdldEVuY2xvc2VkRWxlbWVudHMoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMge0Bjb2RlIHRydWV9IGlmIHRoZSBhcmd1bWVudCByZXByZXNlbnRzIHRoZSBzYW1lCiAgICAgKiBlbGVtZW50IGFzIHtAY29kZSB0aGlzfSwgb3Ige0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCiAgICAgKgogICAgICogQGFwaU5vdGUgVGhlIGlkZW50aXR5IG9mIGFuIGVsZW1lbnQgaW52b2x2ZXMgaW1wbGljaXQgc3RhdGUKICAgICAqIG5vdCBkaXJlY3RseSBhY2Nlc3NpYmxlIGZyb20gdGhlIGVsZW1lbnQncyBtZXRob2RzLCBpbmNsdWRpbmcKICAgICAqIHN0YXRlIGFib3V0IHRoZSBwcmVzZW5jZSBvZiB1bnJlbGF0ZWQgdHlwZXMuICBFbGVtZW50IG9iamVjdHMKICAgICAqIGNyZWF0ZWQgYnkgZGlmZmVyZW50IGltcGxlbWVudGF0aW9ucyBvZiB0aGVzZSBpbnRlcmZhY2VzIHNob3VsZAogICAgICogPGk+bm90PC9pPiBiZSBleHBlY3RlZCB0byBiZSBlcXVhbCBldmVuIGlmICZxdW90O3RoZSBzYW1lJnF1b3Q7CiAgICAgKiBlbGVtZW50IGlzIGJlaW5nIG1vZGVsZWQ7IHRoaXMgaXMgYW5hbG9nb3VzIHRvIHRoZSBpbmVxdWFsaXR5CiAgICAgKiBvZiB7QGNvZGUgQ2xhc3N9IG9iamVjdHMgZm9yIHRoZSBzYW1lIGNsYXNzIGZpbGUgbG9hZGVkIHRocm91Z2gKICAgICAqIGRpZmZlcmVudCBjbGFzcyBsb2FkZXJzLgogICAgICoKICAgICAqIEBwYXJhbSBvYmogIHRoZSBvYmplY3QgdG8gYmUgY29tcGFyZWQgd2l0aCB0aGlzIGVsZW1lbnQKICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBzcGVjaWZpZWQgb2JqZWN0IHJlcHJlc2VudHMgdGhlIHNhbWUKICAgICAqICAgICAgICAgIGVsZW1lbnQgYXMgdGhpcwogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmopOwoKICAgIC8qKgogICAgICogT2JleXMgdGhlIGdlbmVyYWwgY29udHJhY3Qgb2Yge0BsaW5rIE9iamVjdCNoYXNoQ29kZSBPYmplY3QuaGFzaENvZGV9LgogICAgICoKICAgICAqIEBzZWUgI2VxdWFscwogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIGludCBoYXNoQ29kZSgpOwoKCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqCiAgICAgKiA8cD4gVG8gZ2V0IGluaGVyaXRlZCBhbm5vdGF0aW9ucyBhcyB3ZWxsLCB1c2Uge0BsaW5rCiAgICAgKiBFbGVtZW50cyNnZXRBbGxBbm5vdGF0aW9uTWlycm9ycyhFbGVtZW50KQogICAgICogZ2V0QWxsQW5ub3RhdGlvbk1pcnJvcnN9LgogICAgICoKICAgICAqIEBzaW5jZSAxLjYKICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBMaXN0PD8gZXh0ZW5kcyBBbm5vdGF0aW9uTWlycm9yPiBnZXRBbm5vdGF0aW9uTWlycm9ycygpOwoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICogQHNpbmNlIDEuNgogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIDxBIGV4dGVuZHMgQW5ub3RhdGlvbj4gQSBnZXRBbm5vdGF0aW9uKENsYXNzPEE+IGFubm90YXRpb25UeXBlKTsKCiAgICAvKioKICAgICAqIEFwcGxpZXMgYSB2aXNpdG9yIHRvIHRoaXMgZWxlbWVudC4KICAgICAqCiAgICAgKiBAcGFyYW0gPFI+IHRoZSByZXR1cm4gdHlwZSBvZiB0aGUgdmlzaXRvcidzIG1ldGhvZHMKICAgICAqIEBwYXJhbSA8UD4gdGhlIHR5cGUgb2YgdGhlIGFkZGl0aW9uYWwgcGFyYW1ldGVyIHRvIHRoZSB2aXNpdG9yJ3MgbWV0aG9kcwogICAgICogQHBhcmFtIHYgICB0aGUgdmlzaXRvciBvcGVyYXRpbmcgb24gdGhpcyBlbGVtZW50CiAgICAgKiBAcGFyYW0gcCAgIGFkZGl0aW9uYWwgcGFyYW1ldGVyIHRvIHRoZSB2aXNpdG9yCiAgICAgKiBAcmV0dXJuIGEgdmlzaXRvci1zcGVjaWZpZWQgcmVzdWx0CiAgICAgKi8KICAgIDxSLCBQPiBSIGFjY2VwdChFbGVtZW50VmlzaXRvcjxSLCBQPiB2LCBQIHApOwp9ClBLAwQKAAAIAAAGO6lKnsQ3apgVAACYFQAAKgAAAGphdmF4L2xhbmcvbW9kZWwvZWxlbWVudC9wYWNrYWdlLWluZm8uamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAxNywgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKLyoqCiAqIEludGVyZmFjZXMgdXNlZCB0byBtb2RlbCBlbGVtZW50cyBvZiB0aGUgSmF2YSBwcm9ncmFtbWluZyBsYW5ndWFnZS4KICoKICogVGhlIHRlcm0gImVsZW1lbnQiIGluIHRoaXMgcGFja2FnZSBpcyB1c2VkIHRvIHJlZmVyIHRvIHByb2dyYW0KICogZWxlbWVudHMsIHRoZSBkZWNsYXJlZCBlbnRpdGllcyB0aGF0IG1ha2UgdXAgYSBwcm9ncmFtLiAgRWxlbWVudHMKICogaW5jbHVkZSBjbGFzc2VzLCBpbnRlcmZhY2VzLCBtZXRob2RzLCBjb25zdHJ1Y3RvcnMsIGFuZCBmaWVsZHMuCiAqIFRoZSBpbnRlcmZhY2VzIGluIHRoaXMgcGFja2FnZSBkbyBub3QgbW9kZWwgdGhlIHN0cnVjdHVyZSBvZiBhCiAqIHByb2dyYW0gaW5zaWRlIGEgbWV0aG9kIGJvZHk7IGZvciBleGFtcGxlIHRoZXJlIGlzIG5vCiAqIHJlcHJlc2VudGF0aW9uIG9mIGEge0Bjb2RlIGZvcn0gbG9vcCBvciB7QGNvZGUgdHJ5fS17QGNvZGUgZmluYWxseX0KICogYmxvY2suICBIb3dldmVyLCB0aGUgaW50ZXJmYWNlcyBjYW4gbW9kZWwgc29tZSBzdHJ1Y3R1cmVzIG9ubHkKICogYXBwZWFyaW5nIGluc2lkZSBtZXRob2QgYm9kaWVzLCBzdWNoIGFzIGxvY2FsIHZhcmlhYmxlcyBhbmQKICogYW5vbnltb3VzIGNsYXNzZXMuCiAqCiAqIDxwPldoZW4gdXNlZCBpbiB0aGUgY29udGV4dCBvZiBhbm5vdGF0aW9uIHByb2Nlc3NpbmcsIGFuIGFjY3VyYXRlCiAqIG1vZGVsIG9mIHRoZSBlbGVtZW50IGJlaW5nIHJlcHJlc2VudGVkIG11c3QgYmUgcmV0dXJuZWQuICBBcyB0aGlzCiAqIGlzIGEgbGFuZ3VhZ2UgbW9kZWwsIHRoZSBzb3VyY2UgY29kZSBwcm92aWRlcyB0aGUgZmlkdWNpYWwKICogKHJlZmVyZW5jZSkgcmVwcmVzZW50YXRpb24gb2YgdGhlIGNvbnN0cnVjdCBpbiBxdWVzdGlvbiByYXRoZXIgdGhhbgogKiBhIHJlcHJlc2VudGF0aW9uIGluIGFuIGV4ZWN1dGFibGUgb3V0cHV0IGxpa2UgYSBjbGFzcyBmaWxlLgogKiBFeGVjdXRhYmxlIG91dHB1dCBtYXkgc2VydmUgYXMgdGhlIGJhc2lzIGZvciBjcmVhdGluZyBhIG1vZGVsaW5nCiAqIGVsZW1lbnQuICBIb3dldmVyLCB0aGUgcHJvY2VzcyBvZiB0cmFuc2xhdGluZyBzb3VyY2UgY29kZSB0bwogKiBleGVjdXRhYmxlIG91dHB1dCBtYXkgbm90IHBlcm1pdCByZWNvdmVyaW5nIHNvbWUgYXNwZWN0cyBvZiB0aGUKICogc291cmNlIGNvZGUgcmVwcmVzZW50YXRpb24uICBGb3IgZXhhbXBsZSwgYW5ub3RhdGlvbnMgd2l0aAogKiB7QGxpbmtwbGFpbiBqYXZhLmxhbmcuYW5ub3RhdGlvbi5SZXRlbnRpb25Qb2xpY3kjU09VUkNFIHNvdXJjZX0KICoge0BsaW5rcGxhaW4gamF2YS5sYW5nLmFubm90YXRpb24uUmV0ZW50aW9uIHJldGVudGlvbn0gY2Fubm90IGJlCiAqIHJlY292ZXJlZCBmcm9tIGNsYXNzIGZpbGVzIGFuZCBjbGFzcyBmaWxlcyBtaWdodCBub3QgYmUgYWJsZSB0bwogKiBwcm92aWRlIHNvdXJjZSBwb3NpdGlvbiBpbmZvcm1hdGlvbi4KICoKICogTmFtZXMgb2YgcGFyYW1ldGVycyBtYXkgbm90IGJlIHJlY292ZXJhYmxlIGZyb20gY2xhc3MgZmlsZXMuCiAqCiAqIFRoZSB7QGxpbmtwbGFpbiBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuTW9kaWZpZXIgbW9kaWZpZXJzfSBvbiBhbgogKiBlbGVtZW50IGNyZWF0ZWQgZnJvbSBhIGNsYXNzIGZpbGUgbWF5IGRpZmZlciBpbiBzb21lIGNhc2VzIGZyb20gYW4KICogZWxlbWVudCBmb3IgdGhlIHNhbWUgZGVjbGFyYXRpb24gY3JlYXRlZCBmcm9tIGEgc291cmNlIGZpbGUKICogaW5jbHVkaW5nOgogKgogKiA8dWw+CiAqIDxsaT4ge0Bjb2RlIHN0cmljdGZwfSBvbiBhIGNsYXNzIG9yIGludGVyZmFjZQogKiA8bGk+IHtAY29kZSBmaW5hbH0gb24gYSBwYXJhbWV0ZXIKICogPGxpPiB7QGNvZGUgcHJvdGVjdGVkfSwge0Bjb2RlIHByaXZhdGV9LCBhbmQge0Bjb2RlIHN0YXRpY30gb24gY2xhc3NlcyBhbmQgaW50ZXJmYWNlcwogKiA8L3VsPgogKgogKiBTb21lIGVsZW1lbnRzIHdoaWNoIGFyZSB7QGxpbmtwbGFpbgogKiBqYXZheC5sYW5nLm1vZGVsLnV0aWwuRWxlbWVudHMuT3JpZ2luI01BTkRBVEVEIG1hbmRhdGVkfSBtYXkgbm90IGJlCiAqIG1hcmtlZCBhcyBzdWNoIHdoZW4gY3JlYXRlZCBmcm9tIGNsYXNzIGZpbGVzLgogKgogKiBBZGRpdGlvbmFsbHksIHtAbGlua3BsYWluCiAqIGphdmF4LmxhbmcubW9kZWwudXRpbC5FbGVtZW50cy5PcmlnaW4jU1lOVEhFVElDIHN5bnRoZXRpY30KICogY29uc3RydWN0cyBpbiBhIGNsYXNzIGZpbGUsIHN1Y2ggYXMgYWNjZXNzb3IgbWV0aG9kcyB1c2VkIGluCiAqIGltcGxlbWVudGluZyBuZXN0ZWQgY2xhc3NlcyBhbmQge0BsaW5rcGxhaW4KICogamF2YXgubGFuZy5tb2RlbC51dGlsLkVsZW1lbnRzLk9yaWdpbiNpc0JyaWRnZShFeGVjdXRhYmxlRWxlbWVudCkKICogYnJpZGdlIG1ldGhvZHN9IHVzZWQgaW4gaW1wbGVtZW50aW5nIGNvdmFyaWFudCByZXR1cm5zLCBhcmUKICogdHJhbnNsYXRpb24gYXJ0aWZhY3RzIHN0cmljdGx5IG91dHNpZGUgb2YgdGhpcyBtb2RlbC4gSG93ZXZlciwgd2hlbgogKiBvcGVyYXRpbmcgb24gY2xhc3MgZmlsZXMsIGl0IGlzIGhlbHBmdWwgYmUgYWJsZSB0byBvcGVyYXRlIG9uIHN1Y2gKICogZWxlbWVudHMsIHNjcmVlbmluZyB0aGVtIG91dCB3aGVuIGFwcHJvcHJpYXRlLgogKgogKiA8cD5EdXJpbmcgYW5ub3RhdGlvbiBwcm9jZXNzaW5nLCBvcGVyYXRpbmcgb24gaW5jb21wbGV0ZSBvcgogKiBlcnJvbmVvdXMgcHJvZ3JhbXMgaXMgbmVjZXNzYXJ5OyBob3dldmVyLCB0aGVyZSBhcmUgZmV3ZXIKICogZ3VhcmFudGVlcyBhYm91dCB0aGUgbmF0dXJlIG9mIHRoZSByZXN1bHRpbmcgbW9kZWwuICBJZiB0aGUgc291cmNlCiAqIGNvZGUgaXMgbm90IHN5bnRhY3RpY2FsbHkgd2VsbC1mb3JtZWQgb3IgaGFzIHNvbWUgb3RoZXIKICogaXJyZWNvdmVyYWJsZSBlcnJvciB0aGF0IGNvdWxkIG5vdCBiZSByZW1vdmVkIGJ5IHRoZSBnZW5lcmF0aW9uIG9mCiAqIG5ldyB0eXBlcywgYSBtb2RlbCBtYXkgb3IgbWF5IG5vdCBiZSBwcm92aWRlZCBhcyBhIHF1YWxpdHkgb2YKICogaW1wbGVtZW50YXRpb24gaXNzdWUuCiAqIElmIGEgcHJvZ3JhbSBpcyBzeW50YWN0aWNhbGx5IHZhbGlkIGJ1dCBlcnJvbmVvdXMgaW4gc29tZSBvdGhlcgogKiBmYXNoaW9uLCBhbnkgcmV0dXJuZWQgbW9kZWwgbXVzdCBoYXZlIG5vIGxlc3MgaW5mb3JtYXRpb24gdGhhbiBpZgogKiBhbGwgdGhlIG1ldGhvZCBib2RpZXMgaW4gdGhlIHByb2dyYW0gd2VyZSByZXBsYWNlZCBieSB7QGNvZGUgInRocm93CiAqIG5ldyBSdW50aW1lRXhjZXB0aW9uKCk7In0uICBJZiBhIHByb2dyYW0gcmVmZXJzIHRvIGEgbWlzc2luZyB0eXBlIFh5eiwKICogdGhlIHJldHVybmVkIG1vZGVsIG11c3QgY29udGFpbiBubyBsZXNzIGluZm9ybWF0aW9uIHRoYW4gaWYgdGhlCiAqIGRlY2xhcmF0aW9uIG9mIHR5cGUgWHl6IHdlcmUgYXNzdW1lZCB0byBiZSB7QGNvZGUgImNsYXNzIFh5eiB7fSJ9LAogKiB7QGNvZGUgImludGVyZmFjZSBYeXoge30ifSwge0Bjb2RlICJlbnVtIFh5eiB7fSJ9LCBvciB7QGNvZGUKICogIkBpbnRlcmZhY2UgWHl6IHt9In0uIElmIGEgcHJvZ3JhbSByZWZlcnMgdG8gYSBtaXNzaW5nIHR5cGUge0Bjb2RlCiAqIFh5ejxLMSwgLi4uICxLbj59LCB0aGUgcmV0dXJuZWQgbW9kZWwgbXVzdCBjb250YWluIG5vIGxlc3MKICogaW5mb3JtYXRpb24gdGhhbiBpZiB0aGUgZGVjbGFyYXRpb24gb2YgWHl6IHdlcmUgYXNzdW1lZCB0byBiZQogKiB7QGNvZGUgImNsYXNzIFh5ejxUMSwgLi4uICxUbj4ge30ifSBvciB7QGNvZGUgImludGVyZmFjZSBYeXo8VDEsCiAqIC4uLiAsVG4+IHt9In0KICoKICogPHA+IFVubGVzcyBvdGhlcndpc2Ugc3BlY2lmaWVkIGluIGEgcGFydGljdWxhciBpbXBsZW1lbnRhdGlvbiwgdGhlCiAqIGNvbGxlY3Rpb25zIHJldHVybmVkIGJ5IG1ldGhvZHMgaW4gdGhpcyBwYWNrYWdlIHNob3VsZCBiZSBleHBlY3RlZAogKiB0byBiZSB1bm1vZGlmaWFibGUgYnkgdGhlIGNhbGxlciBhbmQgdW5zYWZlIGZvciBjb25jdXJyZW50IGFjY2Vzcy4KICoKICogPHA+IFVubGVzcyBvdGhlcndpc2Ugc3BlY2lmaWVkLCBtZXRob2RzIGluIHRoaXMgcGFja2FnZSB3aWxsIHRocm93CiAqIGEge0Bjb2RlIE51bGxQb2ludGVyRXhjZXB0aW9ufSBpZiBnaXZlbiBhIHtAY29kZSBudWxsfSBhcmd1bWVudC4KICoKICogQGF1dGhvciBKb3NlcGggRC4gRGFyY3kKICogQGF1dGhvciBTY290dCBTZWxpZ21hbgogKiBAYXV0aG9yIFBldGVyIHZvbiBkZXIgQWgmZWFjdXRlOwogKiBAc2luY2UgMS42CiAqLwpwYWNrYWdlIGphdmF4LmxhbmcubW9kZWwuZWxlbWVudDsKUEsDBAoAAAgAANJ9TUrh2ib1JgYAACYGAAAvAAAAamF2YXgvbGFuZy9tb2RlbC9lbGVtZW50L1F1YWxpZmllZE5hbWVhYmxlLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDksIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgamF2YXgubGFuZy5tb2RlbC5lbGVtZW50OwoKLyoqCiAqIEEgbWl4aW4gaW50ZXJmYWNlIGZvciBhbiBlbGVtZW50IHRoYXQgaGFzIGEgcXVhbGlmaWVkIG5hbWUuCiAqCiAqIEBhdXRob3IgSm9zZXBoIEQuIERhcmN5CiAqIEBzaW5jZSAxLjcKICovCnB1YmxpYyBpbnRlcmZhY2UgUXVhbGlmaWVkTmFtZWFibGUgZXh0ZW5kcyBFbGVtZW50IHsKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgZnVsbHkgcXVhbGlmaWVkIG5hbWUgb2YgYW4gZWxlbWVudC4KICAgICAqCiAgICAgKiBAcmV0dXJuIHRoZSBmdWxseSBxdWFsaWZpZWQgbmFtZSBvZiBhbiBlbGVtZW50CiAgICAgKi8KICAgIE5hbWUgZ2V0UXVhbGlmaWVkTmFtZSgpOwp9ClBLAwQKAAAIAAAGO6lK3N0DuK4MAACuDAAAPQAAAGphdmF4L2xhbmcvbW9kZWwvZWxlbWVudC9Vbmtub3duQW5ub3RhdGlvblZhbHVlRXhjZXB0aW9uLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMTcsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgamF2YXgubGFuZy5tb2RlbC5lbGVtZW50OwoKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuVW5rbm93bkVudGl0eUV4Y2VwdGlvbjsKCi8qKgogKiBJbmRpY2F0ZXMgdGhhdCBhbiB1bmtub3duIGtpbmQgb2YgYW5ub3RhdGlvbiB2YWx1ZSB3YXMgZW5jb3VudGVyZWQuCiAqIFRoaXMgY2FuIG9jY3VyIGlmIHRoZSBsYW5ndWFnZSBldm9sdmVzIGFuZCBuZXcga2luZHMgb2YgYW5ub3RhdGlvbgogKiB2YWx1ZXMgY2FuIGJlIHN0b3JlZCBpbiBhbiBhbm5vdGF0aW9uLiAgTWF5IGJlIHRocm93biBieSBhbgogKiB7QGxpbmtwbGFpbiBBbm5vdGF0aW9uVmFsdWVWaXNpdG9yIGFubm90YXRpb24gdmFsdWUgdmlzaXRvcn0gdG8KICogaW5kaWNhdGUgdGhhdCB0aGUgdmlzaXRvciB3YXMgY3JlYXRlZCBmb3IgYSBwcmlvciB2ZXJzaW9uIG9mIHRoZQogKiBsYW5ndWFnZS4KICoKICogQGF1dGhvciBKb3NlcGggRC4gRGFyY3kKICogQGF1dGhvciBTY290dCBTZWxpZ21hbgogKiBAYXV0aG9yIFBldGVyIHZvbiBkZXIgQWgmZWFjdXRlOwogKiBAc2VlIEFubm90YXRpb25WYWx1ZVZpc2l0b3IjdmlzaXRVbmtub3duCiAqIEBzaW5jZSAxLjYKICovCnB1YmxpYyBjbGFzcyBVbmtub3duQW5ub3RhdGlvblZhbHVlRXhjZXB0aW9uIGV4dGVuZHMgVW5rbm93bkVudGl0eUV4Y2VwdGlvbiB7CgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMjY5TDsKCiAgICBwcml2YXRlIHRyYW5zaWVudCBBbm5vdGF0aW9uVmFsdWUgYXY7CiAgICBwcml2YXRlIHRyYW5zaWVudCBPYmplY3QgcGFyYW1ldGVyOwoKICAgIC8qKgogICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgVW5rbm93bkFubm90YXRpb25WYWx1ZUV4Y2VwdGlvbn0uICBUaGUKICAgICAqIHtAY29kZSBwfSBwYXJhbWV0ZXIgbWF5IGJlIHVzZWQgdG8gcGFzcyBpbiBhbiBhZGRpdGlvbmFsCiAgICAgKiBhcmd1bWVudCB3aXRoIGluZm9ybWF0aW9uIGFib3V0IHRoZSBjb250ZXh0IGluIHdoaWNoIHRoZQogICAgICogdW5rbm93biBhbm5vdGF0aW9uIHZhbHVlIHdhcyBlbmNvdW50ZXJlZDsgZm9yIGV4YW1wbGUsIHRoZQogICAgICogdmlzaXQgbWV0aG9kcyBvZiB7QGxpbmsgQW5ub3RhdGlvblZhbHVlVmlzaXRvcn0gbWF5IHBhc3MgaW4KICAgICAqIHRoZWlyIGFkZGl0aW9uYWwgcGFyYW1ldGVyLgogICAgICoKICAgICAqIEBwYXJhbSBhdiB0aGUgdW5rbm93biBhbm5vdGF0aW9uIHZhbHVlLCBtYXkgYmUge0Bjb2RlIG51bGx9CiAgICAgKiBAcGFyYW0gcCBhbiBhZGRpdGlvbmFsIHBhcmFtZXRlciwgbWF5IGJlIHtAY29kZSBudWxsfQogICAgICovCiAgICBwdWJsaWMgVW5rbm93bkFubm90YXRpb25WYWx1ZUV4Y2VwdGlvbihBbm5vdGF0aW9uVmFsdWUgYXYsIE9iamVjdCBwKSB7CiAgICAgICAgc3VwZXIoIlVua25vd24gYW5ub3RhdGlvbiB2YWx1ZTogIiArIGF2KTsKICAgICAgICB0aGlzLmF2ID0gYXY7CiAgICAgICAgdGhpcy5wYXJhbWV0ZXIgPSBwOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgdW5rbm93biBhbm5vdGF0aW9uIHZhbHVlLgogICAgICogVGhlIHZhbHVlIG1heSBiZSB1bmF2YWlsYWJsZSBpZiB0aGlzIGV4Y2VwdGlvbiBoYXMgYmVlbgogICAgICogc2VyaWFsaXplZCBhbmQgdGhlbiByZWFkIGJhY2sgaW4uCiAgICAgKgogICAgICogQHJldHVybiB0aGUgdW5rbm93biBlbGVtZW50LCBvciB7QGNvZGUgbnVsbH0gaWYgdW5hdmFpbGFibGUKICAgICAqLwogICAgcHVibGljIEFubm90YXRpb25WYWx1ZSBnZXRVbmtub3duQW5ub3RhdGlvblZhbHVlKCkgewogICAgICAgIHJldHVybiBhdjsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGFkZGl0aW9uYWwgYXJndW1lbnQuCiAgICAgKgogICAgICogQHJldHVybiB0aGUgYWRkaXRpb25hbCBhcmd1bWVudCwgb3Ige0Bjb2RlIG51bGx9IGlmIHVuYXZhaWxhYmxlCiAgICAgKi8KICAgIHB1YmxpYyBPYmplY3QgZ2V0QXJndW1lbnQoKSB7CiAgICAgICAgcmV0dXJuIHBhcmFtZXRlcjsKICAgIH0KfQpQSwMECgAACAAABjupShTVZypuGQAAbhkAACkAAABqYXZheC9sYW5nL21vZGVsL2VsZW1lbnQvVHlwZUVsZW1lbnQuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAxNywgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQ7CgppbXBvcnQgamF2YS51dGlsLkxpc3Q7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLnR5cGUuKjsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwudXRpbC4qOwoKLyoqCiAqIFJlcHJlc2VudHMgYSBjbGFzcyBvciBpbnRlcmZhY2UgcHJvZ3JhbSBlbGVtZW50LiAgUHJvdmlkZXMgYWNjZXNzCiAqIHRvIGluZm9ybWF0aW9uIGFib3V0IHRoZSB0eXBlIGFuZCBpdHMgbWVtYmVycy4gIE5vdGUgdGhhdCBhbiBlbnVtCiAqIHR5cGUgaXMgYSBraW5kIG9mIGNsYXNzIGFuZCBhbiBhbm5vdGF0aW9uIHR5cGUgaXMgYSBraW5kIG9mCiAqIGludGVyZmFjZS4KICoKICogPHA+IFdoaWxlIGEge0Bjb2RlIFR5cGVFbGVtZW50fSByZXByZXNlbnRzIGEgY2xhc3Mgb3IgaW50ZXJmYWNlCiAqIDxpPmVsZW1lbnQ8L2k+LCBhIHtAbGluayBEZWNsYXJlZFR5cGV9IHJlcHJlc2VudHMgYSBjbGFzcwogKiBvciBpbnRlcmZhY2UgPGk+dHlwZTwvaT4sIHRoZSBsYXR0ZXIgYmVpbmcgYSB1c2UKICogKG9yIDxpPmludm9jYXRpb248L2k+KSBvZiB0aGUgZm9ybWVyLgogKiBUaGUgZGlzdGluY3Rpb24gaXMgbW9zdCBhcHBhcmVudCB3aXRoIGdlbmVyaWMgdHlwZXMsCiAqIGZvciB3aGljaCBhIHNpbmdsZSBlbGVtZW50IGNhbiBkZWZpbmUgYSB3aG9sZQogKiBmYW1pbHkgb2YgdHlwZXMuICBGb3IgZXhhbXBsZSwgdGhlIGVsZW1lbnQKICoge0Bjb2RlIGphdmEudXRpbC5TZXR9IGNvcnJlc3BvbmRzIHRvIHRoZSBwYXJhbWV0ZXJpemVkIHR5cGVzCiAqIHtAY29kZSBqYXZhLnV0aWwuU2V0PFN0cmluZz59IGFuZCB7QGNvZGUgamF2YS51dGlsLlNldDxOdW1iZXI+fQogKiAoYW5kIG1hbnkgb3RoZXJzKSwgYW5kIHRvIHRoZSByYXcgdHlwZSB7QGNvZGUgamF2YS51dGlsLlNldH0uCiAqCiAqIDxwPiBFYWNoIG1ldGhvZCBvZiB0aGlzIGludGVyZmFjZSB0aGF0IHJldHVybnMgYSBsaXN0IG9mIGVsZW1lbnRzCiAqIHdpbGwgcmV0dXJuIHRoZW0gaW4gdGhlIG9yZGVyIHRoYXQgaXMgbmF0dXJhbCBmb3IgdGhlIHVuZGVybHlpbmcKICogc291cmNlIG9mIHByb2dyYW0gaW5mb3JtYXRpb24uICBGb3IgZXhhbXBsZSwgaWYgdGhlIHVuZGVybHlpbmcKICogc291cmNlIG9mIGluZm9ybWF0aW9uIGlzIEphdmEgc291cmNlIGNvZGUsIHRoZW4gdGhlIGVsZW1lbnRzIHdpbGwgYmUKICogcmV0dXJuZWQgaW4gc291cmNlIGNvZGUgb3JkZXIuCiAqCiAqIEBhdXRob3IgSm9zZXBoIEQuIERhcmN5CiAqIEBhdXRob3IgU2NvdHQgU2VsaWdtYW4KICogQGF1dGhvciBQZXRlciB2b24gZGVyIEFoJmVhY3V0ZTsKICogQHNlZSBEZWNsYXJlZFR5cGUKICogQHNpbmNlIDEuNgogKi8KcHVibGljIGludGVyZmFjZSBUeXBlRWxlbWVudCBleHRlbmRzIEVsZW1lbnQsIFBhcmFtZXRlcml6YWJsZSwgUXVhbGlmaWVkTmFtZWFibGUgewogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBmaWVsZHMsIG1ldGhvZHMsIGNvbnN0cnVjdG9ycywgYW5kIG1lbWJlciB0eXBlcwogICAgICogdGhhdCBhcmUgZGlyZWN0bHkgZGVjbGFyZWQgaW4gdGhpcyBjbGFzcyBvciBpbnRlcmZhY2UuCiAgICAgKgogICAgICogVGhpcyBpbmNsdWRlcyBhbnkge0BsaW5rcGxhaW4gRWxlbWVudHMuT3JpZ2luI01BTkRBVEVECiAgICAgKiBtYW5kYXRlZH0gZWxlbWVudHMgc3VjaCBhcyB0aGUgKGltcGxpY2l0KSBkZWZhdWx0IGNvbnN0cnVjdG9yCiAgICAgKiBhbmQgdGhlIGltcGxpY2l0IHtAY29kZSB2YWx1ZXN9IGFuZCB7QGNvZGUgdmFsdWVPZn0gbWV0aG9kcyBvZgogICAgICogYW4gZW51bSB0eXBlLgogICAgICoKICAgICAqIEBhcGlOb3RlIEFzIGEgcGFydGljdWxhciBpbnN0YW5jZSBvZiB0aGUge0BsaW5rcGxhaW4KICAgICAqIGphdmF4LmxhbmcubW9kZWwuZWxlbWVudCBnZW5lcmFsIGFjY3VyYWN5IHJlcXVpcmVtZW50c30gYW5kIHRoZQogICAgICogb3JkZXJpbmcgYmVoYXZpb3IgcmVxdWlyZWQgb2YgdGhpcyBpbnRlcmZhY2UsIHRoZSBsaXN0IG9mCiAgICAgKiBlbmNsb3NlZCBlbGVtZW50cyB3aWxsIGJlIHJldHVybmVkIGluIHRoZSBuYXR1cmFsIG9yZGVyIGZvciB0aGUKICAgICAqIG9yaWdpbmF0aW5nIHNvdXJjZSBvZiBpbmZvcm1hdGlvbiBhYm91dCB0aGUgdHlwZS4gIEZvciBleGFtcGxlLAogICAgICogaWYgdGhlIGluZm9ybWF0aW9uIGFib3V0IHRoZSB0eXBlIGlzIG9yaWdpbmF0aW5nIGZyb20gYSBzb3VyY2UKICAgICAqIGZpbGUsIHRoZSBlbGVtZW50cyB3aWxsIGJlIHJldHVybmVkIGluIHNvdXJjZSBjb2RlIG9yZGVyLgogICAgICogKEhvd2V2ZXIsIGluIHRoYXQgY2FzZSB0aGUgdGhlIG9yZGVyaW5nIG9mIHtAbGlua3BsYWluCiAgICAgKiBFbGVtZW50cy5PcmlnaW4jTUFOREFURUQgaW1wbGljaXRseSBkZWNsYXJlZH0gZWxlbWVudHMsIHN1Y2ggYXMKICAgICAqIGRlZmF1bHQgY29uc3RydWN0b3JzLCBpcyBub3Qgc3BlY2lmaWVkLikKICAgICAqCiAgICAgKiBAcmV0dXJuIHRoZSBlbmNsb3NlZCBlbGVtZW50cyBpbiBwcm9wZXIgb3JkZXIsIG9yIGFuIGVtcHR5IGxpc3QgaWYgbm9uZQogICAgICoKICAgICAqIEBqbHMgOC44LjkgRGVmYXVsdCBDb25zdHJ1Y3RvcgogICAgICogQGpscyA4LjkuMyBFbnVtIE1lbWJlcnMKICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBMaXN0PD8gZXh0ZW5kcyBFbGVtZW50PiBnZXRFbmNsb3NlZEVsZW1lbnRzKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSA8aT5uZXN0aW5nIGtpbmQ8L2k+IG9mIHRoaXMgdHlwZSBlbGVtZW50LgogICAgICoKICAgICAqIEByZXR1cm4gdGhlIG5lc3Rpbmcga2luZCBvZiB0aGlzIHR5cGUgZWxlbWVudAogICAgICovCiAgICBOZXN0aW5nS2luZCBnZXROZXN0aW5nS2luZCgpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgZnVsbHkgcXVhbGlmaWVkIG5hbWUgb2YgdGhpcyB0eXBlIGVsZW1lbnQuCiAgICAgKiBNb3JlIHByZWNpc2VseSwgaXQgcmV0dXJucyB0aGUgPGk+Y2Fub25pY2FsPC9pPiBuYW1lLgogICAgICogRm9yIGxvY2FsIGFuZCBhbm9ueW1vdXMgY2xhc3Nlcywgd2hpY2ggZG8gbm90IGhhdmUgY2Fub25pY2FsIG5hbWVzLAogICAgICogYW4gZW1wdHkgbmFtZSBpcyByZXR1cm5lZC4KICAgICAqCiAgICAgKiA8cD5UaGUgbmFtZSBvZiBhIGdlbmVyaWMgdHlwZSBkb2VzIG5vdCBpbmNsdWRlIGFueSByZWZlcmVuY2UKICAgICAqIHRvIGl0cyBmb3JtYWwgdHlwZSBwYXJhbWV0ZXJzLgogICAgICogRm9yIGV4YW1wbGUsIHRoZSBmdWxseSBxdWFsaWZpZWQgbmFtZSBvZiB0aGUgaW50ZXJmYWNlCiAgICAgKiB7QGNvZGUgamF2YS51dGlsLlNldDxFPn0gaXMgIntAY29kZSBqYXZhLnV0aWwuU2V0fSIuCiAgICAgKiBOZXN0ZWQgdHlwZXMgdXNlICJ7QGNvZGUgLn0iIGFzIGEgc2VwYXJhdG9yLCBhcyBpbgogICAgICogIntAY29kZSBqYXZhLnV0aWwuTWFwLkVudHJ5fSIuCiAgICAgKgogICAgICogQHJldHVybiB0aGUgZnVsbHkgcXVhbGlmaWVkIG5hbWUgb2YgdGhpcyBjbGFzcyBvciBpbnRlcmZhY2UsIG9yCiAgICAgKiBhbiBlbXB0eSBuYW1lIGlmIG5vbmUKICAgICAqCiAgICAgKiBAc2VlIEVsZW1lbnRzI2dldEJpbmFyeU5hbWUKICAgICAqIEBqbHMgNi43IEZ1bGx5IFF1YWxpZmllZCBOYW1lcyBhbmQgQ2Fub25pY2FsIE5hbWVzCiAgICAgKi8KICAgIE5hbWUgZ2V0UXVhbGlmaWVkTmFtZSgpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgc2ltcGxlIG5hbWUgb2YgdGhpcyB0eXBlIGVsZW1lbnQuCiAgICAgKgogICAgICogRm9yIGFuIGFub255bW91cyBjbGFzcywgYW4gZW1wdHkgbmFtZSBpcyByZXR1cm5lZC4KICAgICAqCiAgICAgKiBAcmV0dXJuIHRoZSBzaW1wbGUgbmFtZSBvZiB0aGlzIGNsYXNzIG9yIGludGVyZmFjZSwKICAgICAqIGFuIGVtcHR5IG5hbWUgZm9yIGFuIGFub255bW91cyBjbGFzcwogICAgICoKICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBOYW1lIGdldFNpbXBsZU5hbWUoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGRpcmVjdCBzdXBlcmNsYXNzIG9mIHRoaXMgdHlwZSBlbGVtZW50LgogICAgICogSWYgdGhpcyB0eXBlIGVsZW1lbnQgcmVwcmVzZW50cyBhbiBpbnRlcmZhY2Ugb3IgdGhlIGNsYXNzCiAgICAgKiB7QGNvZGUgamF2YS5sYW5nLk9iamVjdH0sIHRoZW4gYSB7QGxpbmsgTm9UeXBlfQogICAgICogd2l0aCBraW5kIHtAbGluayBUeXBlS2luZCNOT05FIE5PTkV9IGlzIHJldHVybmVkLgogICAgICoKICAgICAqIEByZXR1cm4gdGhlIGRpcmVjdCBzdXBlcmNsYXNzLCBvciBhIHtAY29kZSBOb1R5cGV9IGlmIHRoZXJlIGlzIG5vbmUKICAgICAqLwogICAgVHlwZU1pcnJvciBnZXRTdXBlcmNsYXNzKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBpbnRlcmZhY2UgdHlwZXMgZGlyZWN0bHkgaW1wbGVtZW50ZWQgYnkgdGhpcyBjbGFzcwogICAgICogb3IgZXh0ZW5kZWQgYnkgdGhpcyBpbnRlcmZhY2UuCiAgICAgKgogICAgICogQHJldHVybiB0aGUgaW50ZXJmYWNlIHR5cGVzIGRpcmVjdGx5IGltcGxlbWVudGVkIGJ5IHRoaXMgY2xhc3MKICAgICAqIG9yIGV4dGVuZGVkIGJ5IHRoaXMgaW50ZXJmYWNlLCBvciBhbiBlbXB0eSBsaXN0IGlmIHRoZXJlIGFyZSBub25lCiAgICAgKi8KICAgIExpc3Q8PyBleHRlbmRzIFR5cGVNaXJyb3I+IGdldEludGVyZmFjZXMoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGZvcm1hbCB0eXBlIHBhcmFtZXRlcnMgb2YgdGhpcyB0eXBlIGVsZW1lbnQKICAgICAqIGluIGRlY2xhcmF0aW9uIG9yZGVyLgogICAgICoKICAgICAqIEByZXR1cm4gdGhlIGZvcm1hbCB0eXBlIHBhcmFtZXRlcnMsIG9yIGFuIGVtcHR5IGxpc3QKICAgICAqIGlmIHRoZXJlIGFyZSBub25lCiAgICAgKi8KICAgIExpc3Q8PyBleHRlbmRzIFR5cGVQYXJhbWV0ZXJFbGVtZW50PiBnZXRUeXBlUGFyYW1ldGVycygpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgcGFja2FnZSBvZiBhIHRvcC1sZXZlbCB0eXBlIGFuZCByZXR1cm5zIHRoZQogICAgICogaW1tZWRpYXRlbHkgbGV4aWNhbGx5IGVuY2xvc2luZyBlbGVtZW50IGZvciBhIHtAbGlua3BsYWluCiAgICAgKiBOZXN0aW5nS2luZCNpc05lc3RlZCBuZXN0ZWR9IHR5cGUuCiAgICAgKgogICAgICogQHJldHVybiB0aGUgcGFja2FnZSBvZiBhIHRvcC1sZXZlbCB0eXBlLCB0aGUgaW1tZWRpYXRlbHkKICAgICAqIGxleGljYWxseSBlbmNsb3NpbmcgZWxlbWVudCBmb3IgYSBuZXN0ZWQgdHlwZQogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIEVsZW1lbnQgZ2V0RW5jbG9zaW5nRWxlbWVudCgpOwp9ClBLAwQKAAAIAAAGO6lKM4Tax58GAACfBgAALQAAAGphdmF4L2xhbmcvbW9kZWwvZWxlbWVudC9QYXJhbWV0ZXJpemFibGUuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwOSwgMjAxNywgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQ7CgppbXBvcnQgamF2YS51dGlsLkxpc3Q7CgovKioKICogQSBtaXhpbiBpbnRlcmZhY2UgZm9yIGFuIGVsZW1lbnQgdGhhdCBoYXMgdHlwZSBwYXJhbWV0ZXJzLgogKgogKiBAYXV0aG9yIEpvc2VwaCBELiBEYXJjeQogKiBAc2luY2UgMS43CiAqLwpwdWJsaWMgaW50ZXJmYWNlIFBhcmFtZXRlcml6YWJsZSBleHRlbmRzIEVsZW1lbnQgewogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBmb3JtYWwgdHlwZSBwYXJhbWV0ZXJzIG9mIGFuIGVsZW1lbnQgaW4KICAgICAqIGRlY2xhcmF0aW9uIG9yZGVyLgogICAgICoKICAgICAqIEByZXR1cm4gdGhlIGZvcm1hbCB0eXBlIHBhcmFtZXRlcnMsIG9yIGFuIGVtcHR5IGxpc3QKICAgICAqIGlmIHRoZXJlIGFyZSBub25lCiAgICAgKi8KICAgIExpc3Q8PyBleHRlbmRzIFR5cGVQYXJhbWV0ZXJFbGVtZW50PiBnZXRUeXBlUGFyYW1ldGVycygpOwp9ClBLAwQKAAAIAAAGO6lKupnd4AsfAAALHwAANAAAAGphdmF4L2xhbmcvbW9kZWwvZWxlbWVudC9Bbm5vdGF0aW9uVmFsdWVWaXNpdG9yLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMTcsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgamF2YXgubGFuZy5tb2RlbC5lbGVtZW50OwoKCmltcG9ydCBqYXZhLnV0aWwuTGlzdDsKCmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLnR5cGUuVHlwZU1pcnJvcjsKCgovKioKICogQSB2aXNpdG9yIG9mIHRoZSB2YWx1ZXMgb2YgYW5ub3RhdGlvbiB0eXBlIGVsZW1lbnRzLCB1c2luZyBhCiAqIHZhcmlhbnQgb2YgdGhlIHZpc2l0b3IgZGVzaWduIHBhdHRlcm4uICBVbmxpa2UgYSBzdGFuZGFyZCB2aXNpdG9yCiAqIHdoaWNoIGRpc3BhdGNoZXMgYmFzZWQgb24gdGhlIGNvbmNyZXRlIHR5cGUgb2YgYSBtZW1iZXIgb2YgYSB0eXBlCiAqIGhpZXJhcmNoeSwgdGhpcyB2aXNpdG9yIGRpc3BhdGNoZXMgYmFzZWQgb24gdGhlIHR5cGUgb2YgZGF0YQogKiBzdG9yZWQ7IHRoZXJlIGFyZSBubyBkaXN0aW5jdCBzdWJjbGFzc2VzIGZvciBzdG9yaW5nLCBmb3IgZXhhbXBsZSwKICoge0Bjb2RlIGJvb2xlYW59IHZhbHVlcyB2ZXJzdXMge0Bjb2RlIGludH0gdmFsdWVzLiAgQ2xhc3NlcwogKiBpbXBsZW1lbnRpbmcgdGhpcyBpbnRlcmZhY2UgYXJlIHVzZWQgdG8gb3BlcmF0ZSBvbiBhIHZhbHVlIHdoZW4gdGhlCiAqIHR5cGUgb2YgdGhhdCB2YWx1ZSBpcyB1bmtub3duIGF0IGNvbXBpbGUgdGltZS4gIFdoZW4gYSB2aXNpdG9yIGlzCiAqIHBhc3NlZCB0byBhIHZhbHVlJ3Mge0BsaW5rIEFubm90YXRpb25WYWx1ZSNhY2NlcHQgYWNjZXB0fSBtZXRob2QsCiAqIHRoZSA8Y29kZT52aXNpdDxpPlh5ejwvaT48L2NvZGU+IG1ldGhvZCBhcHBsaWNhYmxlIHRvIHRoYXQgdmFsdWUgaXMKICogaW52b2tlZC4KICoKICogPHA+IENsYXNzZXMgaW1wbGVtZW50aW5nIHRoaXMgaW50ZXJmYWNlIG1heSBvciBtYXkgbm90IHRocm93IGEKICoge0Bjb2RlIE51bGxQb2ludGVyRXhjZXB0aW9ufSBpZiB0aGUgYWRkaXRpb25hbCBwYXJhbWV0ZXIge0Bjb2RlIHB9CiAqIGlzIHtAY29kZSBudWxsfTsgc2VlIGRvY3VtZW50YXRpb24gb2YgdGhlIGltcGxlbWVudGluZyBjbGFzcyBmb3IKICogZGV0YWlscy4KICoKICogPHA+IDxiPldBUk5JTkc6PC9iPiBJdCBpcyBwb3NzaWJsZSB0aGF0IG1ldGhvZHMgd2lsbCBiZSBhZGRlZCB0bwogKiB0aGlzIGludGVyZmFjZSB0byBhY2NvbW1vZGF0ZSBuZXcsIGN1cnJlbnRseSB1bmtub3duLCBsYW5ndWFnZQogKiBzdHJ1Y3R1cmVzIGFkZGVkIHRvIGZ1dHVyZSB2ZXJzaW9ucyBvZiB0aGUgSmF2YSZ0cmFkZTsgcHJvZ3JhbW1pbmcKICogbGFuZ3VhZ2UuICBUaGVyZWZvcmUsIHZpc2l0b3IgY2xhc3NlcyBkaXJlY3RseSBpbXBsZW1lbnRpbmcgdGhpcwogKiBpbnRlcmZhY2UgbWF5IGJlIHNvdXJjZSBpbmNvbXBhdGlibGUgd2l0aCBmdXR1cmUgdmVyc2lvbnMgb2YgdGhlCiAqIHBsYXRmb3JtLiAgVG8gYXZvaWQgdGhpcyBzb3VyY2UgaW5jb21wYXRpYmlsaXR5LCB2aXNpdG9yCiAqIGltcGxlbWVudGF0aW9ucyBhcmUgZW5jb3VyYWdlZCB0byBpbnN0ZWFkIGV4dGVuZCB0aGUgYXBwcm9wcmlhdGUKICogYWJzdHJhY3QgdmlzaXRvciBjbGFzcyB0aGF0IGltcGxlbWVudHMgdGhpcyBpbnRlcmZhY2UuICBIb3dldmVyLCBhbgogKiBBUEkgc2hvdWxkIGdlbmVyYWxseSB1c2UgdGhpcyB2aXNpdG9yIGludGVyZmFjZSBhcyB0aGUgdHlwZSBmb3IKICogcGFyYW1ldGVycywgcmV0dXJuIHR5cGUsIGV0Yy4gcmF0aGVyIHRoYW4gb25lIG9mIHRoZSBhYnN0cmFjdAogKiBjbGFzc2VzLgogKgogKiA8cD5Ob3RlIHRoYXQgbWV0aG9kcyB0byBhY2NvbW1vZGF0ZSBuZXcgbGFuZ3VhZ2UgY29uc3RydWN0cyBjb3VsZAogKiBiZSBhZGRlZCBpbiBhIHNvdXJjZSA8ZW0+Y29tcGF0aWJsZTwvZW0+IHdheSBpZiB0aGV5IHdlcmUgYWRkZWQgYXMKICogPGVtPmRlZmF1bHQgbWV0aG9kczwvZW0+LiAgSG93ZXZlciwgZGVmYXVsdCBtZXRob2RzIGFyZSBvbmx5CiAqIGF2YWlsYWJsZSBvbiBKYXZhIFNFIDggYW5kIGhpZ2hlciByZWxlYXNlcyBhbmQgdGhlIHtAY29kZQogKiBqYXZheC5sYW5nLm1vZGVsLip9IHBhY2thZ2VzIGJ1bmRsZWQgaW4gSmF2YSBTRSA4IHdlcmUgcmVxdWlyZWQgdG8KICogYWxzbyBiZSBydW5uYWJsZSBvbiBKYXZhIFNFIDcuICBUaGVyZWZvcmUsIGRlZmF1bHQgbWV0aG9kcwogKiB3ZXJlIDxlbT5ub3Q8L2VtPiB1c2VkIHdoZW4gZXh0ZW5kaW5nIHtAY29kZSBqYXZheC5sYW5nLm1vZGVsLip9CiAqIHRvIGNvdmVyIEphdmEgU0UgOCBsYW5ndWFnZSBmZWF0dXJlcy4gIEhvd2V2ZXIsIGRlZmF1bHQgbWV0aG9kcwogKiBhcmUgdXNlZCBpbiBzdWJzZXF1ZW50IHJldmlzaW9ucyBvZiB0aGUge0Bjb2RlIGphdmF4LmxhbmcubW9kZWwuKn0KICogcGFja2FnZXMgdGhhdCBhcmUgb25seSByZXF1aXJlZCB0byBydW4gb24gSmF2YSBTRSA4IGFuZCBoaWdoZXIKICogcGxhdGZvcm0gdmVyc2lvbnMuCiAqCiAqIEBwYXJhbSA8Uj4gdGhlIHJldHVybiB0eXBlIG9mIHRoaXMgdmlzaXRvcidzIG1ldGhvZHMKICogQHBhcmFtIDxQPiB0aGUgdHlwZSBvZiB0aGUgYWRkaXRpb25hbCBwYXJhbWV0ZXIgdG8gdGhpcyB2aXNpdG9yJ3MgbWV0aG9kcy4KICogQGF1dGhvciBKb3NlcGggRC4gRGFyY3kKICogQGF1dGhvciBTY290dCBTZWxpZ21hbgogKiBAYXV0aG9yIFBldGVyIHZvbiBkZXIgQWgmZWFjdXRlOwogKiBAc2luY2UgMS42CiAqLwpwdWJsaWMgaW50ZXJmYWNlIEFubm90YXRpb25WYWx1ZVZpc2l0b3I8UiwgUD4gewogICAgLyoqCiAgICAgKiBWaXNpdHMgYW4gYW5ub3RhdGlvbiB2YWx1ZS4KICAgICAqIEBwYXJhbSBhdiB0aGUgdmFsdWUgdG8gdmlzaXQKICAgICAqIEBwYXJhbSBwIGEgdmlzaXRvci1zcGVjaWZpZWQgcGFyYW1ldGVyCiAgICAgKiBAcmV0dXJuICBhIHZpc2l0b3Itc3BlY2lmaWVkIHJlc3VsdAogICAgICovCiAgICBSIHZpc2l0KEFubm90YXRpb25WYWx1ZSBhdiwgUCBwKTsKCiAgICAvKioKICAgICAqIEEgY29udmVuaWVuY2UgbWV0aG9kIGVxdWl2YWxlbnQgdG8ge0Bjb2RlIHZpc2l0KGF2LCBudWxsKX0uCiAgICAgKgogICAgICogQGltcGxTcGVjIFRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIGlzIHtAY29kZSB2aXNpdChhdiwgbnVsbCl9LgogICAgICoKICAgICAqIEBwYXJhbSBhdiB0aGUgdmFsdWUgdG8gdmlzaXQKICAgICAqIEByZXR1cm4gIGEgdmlzaXRvci1zcGVjaWZpZWQgcmVzdWx0CiAgICAgKi8KICAgIGRlZmF1bHQgUiB2aXNpdChBbm5vdGF0aW9uVmFsdWUgYXYpIHsKICAgICAgICByZXR1cm4gdmlzaXQoYXYsIG51bGwpOwogICAgfQoKICAgIC8qKgogICAgICogVmlzaXRzIGEge0Bjb2RlIGJvb2xlYW59IHZhbHVlIGluIGFuIGFubm90YXRpb24uCiAgICAgKiBAcGFyYW0gYiB0aGUgdmFsdWUgYmVpbmcgdmlzaXRlZAogICAgICogQHBhcmFtIHAgYSB2aXNpdG9yLXNwZWNpZmllZCBwYXJhbWV0ZXIKICAgICAqIEByZXR1cm4gdGhlIHJlc3VsdCBvZiB0aGUgdmlzaXQKICAgICAqLwogICAgUiB2aXNpdEJvb2xlYW4oYm9vbGVhbiBiLCBQIHApOwoKICAgIC8qKgogICAgICogVmlzaXRzIGEge0Bjb2RlIGJ5dGV9IHZhbHVlIGluIGFuIGFubm90YXRpb24uCiAgICAgKiBAcGFyYW0gIGIgdGhlIHZhbHVlIGJlaW5nIHZpc2l0ZWQKICAgICAqIEBwYXJhbSAgcCBhIHZpc2l0b3Itc3BlY2lmaWVkIHBhcmFtZXRlcgogICAgICogQHJldHVybiB0aGUgcmVzdWx0IG9mIHRoZSB2aXNpdAogICAgICovCiAgICBSIHZpc2l0Qnl0ZShieXRlIGIsIFAgcCk7CgogICAgLyoqCiAgICAgKiBWaXNpdHMgYSB7QGNvZGUgY2hhcn0gdmFsdWUgaW4gYW4gYW5ub3RhdGlvbi4KICAgICAqIEBwYXJhbSAgYyB0aGUgdmFsdWUgYmVpbmcgdmlzaXRlZAogICAgICogQHBhcmFtICBwIGEgdmlzaXRvci1zcGVjaWZpZWQgcGFyYW1ldGVyCiAgICAgKiBAcmV0dXJuIHRoZSByZXN1bHQgb2YgdGhlIHZpc2l0CiAgICAgKi8KICAgIFIgdmlzaXRDaGFyKGNoYXIgYywgUCBwKTsKCiAgICAvKioKICAgICAqIFZpc2l0cyBhIHtAY29kZSBkb3VibGV9IHZhbHVlIGluIGFuIGFubm90YXRpb24uCiAgICAgKiBAcGFyYW0gIGQgdGhlIHZhbHVlIGJlaW5nIHZpc2l0ZWQKICAgICAqIEBwYXJhbSAgcCBhIHZpc2l0b3Itc3BlY2lmaWVkIHBhcmFtZXRlcgogICAgICogQHJldHVybiB0aGUgcmVzdWx0IG9mIHRoZSB2aXNpdAogICAgICovCiAgICBSIHZpc2l0RG91YmxlKGRvdWJsZSBkLCBQIHApOwoKICAgIC8qKgogICAgICogVmlzaXRzIGEge0Bjb2RlIGZsb2F0fSB2YWx1ZSBpbiBhbiBhbm5vdGF0aW9uLgogICAgICogQHBhcmFtICBmIHRoZSB2YWx1ZSBiZWluZyB2aXNpdGVkCiAgICAgKiBAcGFyYW0gIHAgYSB2aXNpdG9yLXNwZWNpZmllZCBwYXJhbWV0ZXIKICAgICAqIEByZXR1cm4gdGhlIHJlc3VsdCBvZiB0aGUgdmlzaXQKICAgICAqLwogICAgUiB2aXNpdEZsb2F0KGZsb2F0IGYsIFAgcCk7CgogICAgLyoqCiAgICAgKiBWaXNpdHMgYW4ge0Bjb2RlIGludH0gdmFsdWUgaW4gYW4gYW5ub3RhdGlvbi4KICAgICAqIEBwYXJhbSAgaSB0aGUgdmFsdWUgYmVpbmcgdmlzaXRlZAogICAgICogQHBhcmFtICBwIGEgdmlzaXRvci1zcGVjaWZpZWQgcGFyYW1ldGVyCiAgICAgKiBAcmV0dXJuIHRoZSByZXN1bHQgb2YgdGhlIHZpc2l0CiAgICAgKi8KICAgIFIgdmlzaXRJbnQoaW50IGksIFAgcCk7CgogICAgLyoqCiAgICAgKiBWaXNpdHMgYSB7QGNvZGUgbG9uZ30gdmFsdWUgaW4gYW4gYW5ub3RhdGlvbi4KICAgICAqIEBwYXJhbSAgaSB0aGUgdmFsdWUgYmVpbmcgdmlzaXRlZAogICAgICogQHBhcmFtICBwIGEgdmlzaXRvci1zcGVjaWZpZWQgcGFyYW1ldGVyCiAgICAgKiBAcmV0dXJuIHRoZSByZXN1bHQgb2YgdGhlIHZpc2l0CiAgICAgKi8KICAgIFIgdmlzaXRMb25nKGxvbmcgaSwgUCBwKTsKCiAgICAvKioKICAgICAqIFZpc2l0cyBhIHtAY29kZSBzaG9ydH0gdmFsdWUgaW4gYW4gYW5ub3RhdGlvbi4KICAgICAqIEBwYXJhbSAgcyB0aGUgdmFsdWUgYmVpbmcgdmlzaXRlZAogICAgICogQHBhcmFtICBwIGEgdmlzaXRvci1zcGVjaWZpZWQgcGFyYW1ldGVyCiAgICAgKiBAcmV0dXJuIHRoZSByZXN1bHQgb2YgdGhlIHZpc2l0CiAgICAgKi8KICAgIFIgdmlzaXRTaG9ydChzaG9ydCBzLCBQIHApOwoKICAgIC8qKgogICAgICogVmlzaXRzIGEgc3RyaW5nIHZhbHVlIGluIGFuIGFubm90YXRpb24uCiAgICAgKiBAcGFyYW0gIHMgdGhlIHZhbHVlIGJlaW5nIHZpc2l0ZWQKICAgICAqIEBwYXJhbSAgcCBhIHZpc2l0b3Itc3BlY2lmaWVkIHBhcmFtZXRlcgogICAgICogQHJldHVybiB0aGUgcmVzdWx0IG9mIHRoZSB2aXNpdAogICAgICovCiAgICBSIHZpc2l0U3RyaW5nKFN0cmluZyBzLCBQIHApOwoKICAgIC8qKgogICAgICogVmlzaXRzIGEgdHlwZSB2YWx1ZSBpbiBhbiBhbm5vdGF0aW9uLgogICAgICogQHBhcmFtICB0IHRoZSB2YWx1ZSBiZWluZyB2aXNpdGVkCiAgICAgKiBAcGFyYW0gIHAgYSB2aXNpdG9yLXNwZWNpZmllZCBwYXJhbWV0ZXIKICAgICAqIEByZXR1cm4gdGhlIHJlc3VsdCBvZiB0aGUgdmlzaXQKICAgICAqLwogICAgUiB2aXNpdFR5cGUoVHlwZU1pcnJvciB0LCBQIHApOwoKICAgIC8qKgogICAgICogVmlzaXRzIGFuIHtAY29kZSBlbnVtfSB2YWx1ZSBpbiBhbiBhbm5vdGF0aW9uLgogICAgICogQHBhcmFtICBjIHRoZSB2YWx1ZSBiZWluZyB2aXNpdGVkCiAgICAgKiBAcGFyYW0gIHAgYSB2aXNpdG9yLXNwZWNpZmllZCBwYXJhbWV0ZXIKICAgICAqIEByZXR1cm4gdGhlIHJlc3VsdCBvZiB0aGUgdmlzaXQKICAgICAqLwogICAgUiB2aXNpdEVudW1Db25zdGFudChWYXJpYWJsZUVsZW1lbnQgYywgUCBwKTsKCiAgICAvKioKICAgICAqIFZpc2l0cyBhbiBhbm5vdGF0aW9uIHZhbHVlIGluIGFuIGFubm90YXRpb24uCiAgICAgKiBAcGFyYW0gIGEgdGhlIHZhbHVlIGJlaW5nIHZpc2l0ZWQKICAgICAqIEBwYXJhbSAgcCBhIHZpc2l0b3Itc3BlY2lmaWVkIHBhcmFtZXRlcgogICAgICogQHJldHVybiB0aGUgcmVzdWx0IG9mIHRoZSB2aXNpdAogICAgICovCiAgICBSIHZpc2l0QW5ub3RhdGlvbihBbm5vdGF0aW9uTWlycm9yIGEsIFAgcCk7CgogICAgLyoqCiAgICAgKiBWaXNpdHMgYW4gYXJyYXkgdmFsdWUgaW4gYW4gYW5ub3RhdGlvbi4KICAgICAqIEBwYXJhbSAgdmFscyB0aGUgdmFsdWUgYmVpbmcgdmlzaXRlZAogICAgICogQHBhcmFtICBwIGEgdmlzaXRvci1zcGVjaWZpZWQgcGFyYW1ldGVyCiAgICAgKiBAcmV0dXJuIHRoZSByZXN1bHQgb2YgdGhlIHZpc2l0CiAgICAgKi8KICAgIFIgdmlzaXRBcnJheShMaXN0PD8gZXh0ZW5kcyBBbm5vdGF0aW9uVmFsdWU+IHZhbHMsIFAgcCk7CgogICAgLyoqCiAgICAgKiBWaXNpdHMgYW4gdW5rbm93biBraW5kIG9mIGFubm90YXRpb24gdmFsdWUuCiAgICAgKiBUaGlzIGNhbiBvY2N1ciBpZiB0aGUgbGFuZ3VhZ2UgZXZvbHZlcyBhbmQgbmV3IGtpbmRzCiAgICAgKiBvZiB2YWx1ZSBjYW4gYmUgc3RvcmVkIGluIGFuIGFubm90YXRpb24uCiAgICAgKiBAcGFyYW0gIGF2IHRoZSB1bmtub3duIHZhbHVlIGJlaW5nIHZpc2l0ZWQKICAgICAqIEBwYXJhbSAgcCBhIHZpc2l0b3Itc3BlY2lmaWVkIHBhcmFtZXRlcgogICAgICogQHJldHVybiB0aGUgcmVzdWx0IG9mIHRoZSB2aXNpdAogICAgICogQHRocm93cyBVbmtub3duQW5ub3RhdGlvblZhbHVlRXhjZXB0aW9uCiAgICAgKiAgYSB2aXNpdG9yIGltcGxlbWVudGF0aW9uIG1heSBvcHRpb25hbGx5IHRocm93IHRoaXMgZXhjZXB0aW9uCiAgICAgKi8KICAgIFIgdmlzaXRVbmtub3duKEFubm90YXRpb25WYWx1ZSBhdiwgUCBwKTsKfQpQSwMECgAACAAA0n1NSmoUYqmECgAAhAoAADIAAABqYXZheC9sYW5nL21vZGVsL2VsZW1lbnQvVHlwZVBhcmFtZXRlckVsZW1lbnQuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAxMSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQ7CgppbXBvcnQgamF2YS51dGlsLkxpc3Q7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLnR5cGUuVHlwZU1pcnJvcjsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwudHlwZS5UeXBlVmFyaWFibGU7CgovKioKICogUmVwcmVzZW50cyBhIGZvcm1hbCB0eXBlIHBhcmFtZXRlciBvZiBhIGdlbmVyaWMgY2xhc3MsIGludGVyZmFjZSwgbWV0aG9kLAogKiBvciBjb25zdHJ1Y3RvciBlbGVtZW50LgogKiBBIHR5cGUgcGFyYW1ldGVyIGRlY2xhcmVzIGEge0BsaW5rIFR5cGVWYXJpYWJsZX0uCiAqCiAqIEBhdXRob3IgSm9zZXBoIEQuIERhcmN5CiAqIEBhdXRob3IgU2NvdHQgU2VsaWdtYW4KICogQGF1dGhvciBQZXRlciB2b24gZGVyIEFoJmVhY3V0ZTsKICogQHNlZSBUeXBlVmFyaWFibGUKICogQHNpbmNlIDEuNgogKi8KcHVibGljIGludGVyZmFjZSBUeXBlUGFyYW1ldGVyRWxlbWVudCBleHRlbmRzIEVsZW1lbnQgewoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgZ2VuZXJpYyBjbGFzcywgaW50ZXJmYWNlLCBtZXRob2QsIG9yIGNvbnN0cnVjdG9yIHRoYXQgaXMKICAgICAqIHBhcmFtZXRlcml6ZWQgYnkgdGhpcyB0eXBlIHBhcmFtZXRlci4KICAgICAqCiAgICAgKiBAcmV0dXJuIHRoZSBnZW5lcmljIGNsYXNzLCBpbnRlcmZhY2UsIG1ldGhvZCwgb3IgY29uc3RydWN0b3IgdGhhdCBpcwogICAgICogcGFyYW1ldGVyaXplZCBieSB0aGlzIHR5cGUgcGFyYW1ldGVyCiAgICAgKi8KICAgIEVsZW1lbnQgZ2V0R2VuZXJpY0VsZW1lbnQoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGJvdW5kcyBvZiB0aGlzIHR5cGUgcGFyYW1ldGVyLgogICAgICogVGhlc2UgYXJlIHRoZSB0eXBlcyBnaXZlbiBieSB0aGUge0Bjb2RlIGV4dGVuZHN9IGNsYXVzZQogICAgICogdXNlZCB0byBkZWNsYXJlIHRoaXMgdHlwZSBwYXJhbWV0ZXIuCiAgICAgKiBJZiBubyBleHBsaWNpdCB7QGNvZGUgZXh0ZW5kc30gY2xhdXNlIHdhcyB1c2VkLAogICAgICogdGhlbiB7QGNvZGUgamF2YS5sYW5nLk9iamVjdH0gaXMgY29uc2lkZXJlZCB0byBiZSB0aGUgc29sZSBib3VuZC4KICAgICAqCiAgICAgKiBAcmV0dXJuIHRoZSBib3VuZHMgb2YgdGhpcyB0eXBlIHBhcmFtZXRlciwgb3IgYW4gZW1wdHkgbGlzdCBpZgogICAgICogdGhlcmUgYXJlIG5vbmUKICAgICAqLwogICAgTGlzdDw/IGV4dGVuZHMgVHlwZU1pcnJvcj4gZ2V0Qm91bmRzKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSB7QGxpbmtwbGFpbiBUeXBlUGFyYW1ldGVyRWxlbWVudCNnZXRHZW5lcmljRWxlbWVudCBnZW5lcmljIGVsZW1lbnR9IG9mIHRoaXMgdHlwZSBwYXJhbWV0ZXIuCiAgICAgKgogICAgICogQHJldHVybiB0aGUgZ2VuZXJpYyBlbGVtZW50IG9mIHRoaXMgdHlwZSBwYXJhbWV0ZXIKICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBFbGVtZW50IGdldEVuY2xvc2luZ0VsZW1lbnQoKTsKfQpQSwMECgAACAAABjupSgD6hWjWDAAA1gwAADcAAABqYXZheC9sYW5nL21vZGVsL2VsZW1lbnQvVW5rbm93bkRpcmVjdGl2ZUV4Y2VwdGlvbi5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDA1LCAyMDE3LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGphdmF4LmxhbmcubW9kZWwuZWxlbWVudDsKCmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLlVua25vd25FbnRpdHlFeGNlcHRpb247CgovKioKICogSW5kaWNhdGVzIHRoYXQgYW4gdW5rbm93biBraW5kIG9mIG1vZHVsZSBkaXJlY3RpdmUgd2FzIGVuY291bnRlcmVkLgogKiBUaGlzIGNhbiBvY2N1ciBpZiB0aGUgbGFuZ3VhZ2UgZXZvbHZlcyBhbmQgbmV3IGtpbmRzIG9mIGRpcmVjdGl2ZXMgYXJlCiAqIGFkZGVkIHRvIHRoZSB7QGNvZGUgRGlyZWN0aXZlfSBoaWVyYXJjaHkuICBNYXkgYmUgdGhyb3duIGJ5IGEKICoge0BsaW5rcGxhaW4gTW9kdWxlRWxlbWVudC5EaXJlY3RpdmVWaXNpdG9yIGRpcmVjdGl2ZSB2aXNpdG9yfSB0bwogKiBpbmRpY2F0ZSB0aGF0IHRoZSB2aXNpdG9yIHdhcyBjcmVhdGVkIGZvciBhIHByaW9yIHZlcnNpb24gb2YgdGhlIGxhbmd1YWdlLgogKgogKiBAYXV0aG9yIEpvc2VwaCBELiBEYXJjeQogKiBAYXV0aG9yIFNjb3R0IFNlbGlnbWFuCiAqIEBhdXRob3IgUGV0ZXIgdm9uIGRlciBBaCZlYWN1dGU7CiAqIEBzZWUgTW9kdWxlRWxlbWVudC5EaXJlY3RpdmVWaXNpdG9yI3Zpc2l0VW5rbm93bgogKiBAc2luY2UgOQogKiBAc3BlYyBKUE1TCiAqLwpwdWJsaWMgY2xhc3MgVW5rbm93bkRpcmVjdGl2ZUV4Y2VwdGlvbiBleHRlbmRzIFVua25vd25FbnRpdHlFeGNlcHRpb24gewoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDI2OUw7CgogICAgcHJpdmF0ZSBmaW5hbCB0cmFuc2llbnQgTW9kdWxlRWxlbWVudC5EaXJlY3RpdmUgZGlyZWN0aXZlOwogICAgcHJpdmF0ZSBmaW5hbCB0cmFuc2llbnQgT2JqZWN0IHBhcmFtZXRlcjsKCiAgICAvKioKICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIFVua25vd25FbGVtZW50RXhjZXB0aW9ufS4gIFRoZSB7QGNvZGUgcH0KICAgICAqIHBhcmFtZXRlciBtYXkgYmUgdXNlZCB0byBwYXNzIGluIGFuIGFkZGl0aW9uYWwgYXJndW1lbnQgd2l0aAogICAgICogaW5mb3JtYXRpb24gYWJvdXQgdGhlIGNvbnRleHQgaW4gd2hpY2ggdGhlIHVua25vd24gZGlyZWN0aXZlIHdhcwogICAgICogZW5jb3VudGVyZWQ7IGZvciBleGFtcGxlLCB0aGUgdmlzaXQgbWV0aG9kcyBvZiB7QGxpbmsKICAgICAqIE1vZHVsZUVsZW1lbnQuRGlyZWN0aXZlVmlzaXRvciBEaXJlY3RpdmVWaXNpdG9yfSBtYXkgcGFzcyBpbgogICAgICogdGhlaXIgYWRkaXRpb25hbCBwYXJhbWV0ZXIuCiAgICAgKgogICAgICogQHBhcmFtIGQgdGhlIHVua25vd24gZGlyZWN0aXZlLCBtYXkgYmUge0Bjb2RlIG51bGx9CiAgICAgKiBAcGFyYW0gcCBhbiBhZGRpdGlvbmFsIHBhcmFtZXRlciwgbWF5IGJlIHtAY29kZSBudWxsfQogICAgICovCiAgICBwdWJsaWMgVW5rbm93bkRpcmVjdGl2ZUV4Y2VwdGlvbihNb2R1bGVFbGVtZW50LkRpcmVjdGl2ZSBkLCBPYmplY3QgcCkgewogICAgICAgIHN1cGVyKCJVbmtub3duIGRpcmVjdGl2ZTogIiArIGQpOwogICAgICAgIGRpcmVjdGl2ZSA9IGQ7CiAgICAgICAgcGFyYW1ldGVyID0gcDsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHVua25vd24gZGlyZWN0aXZlLgogICAgICogVGhlIHZhbHVlIG1heSBiZSB1bmF2YWlsYWJsZSBpZiB0aGlzIGV4Y2VwdGlvbiBoYXMgYmVlbgogICAgICogc2VyaWFsaXplZCBhbmQgdGhlbiByZWFkIGJhY2sgaW4uCiAgICAgKgogICAgICogQHJldHVybiB0aGUgdW5rbm93biBkaXJlY3RpdmUsIG9yIHtAY29kZSBudWxsfSBpZiB1bmF2YWlsYWJsZQogICAgICovCiAgICBwdWJsaWMgTW9kdWxlRWxlbWVudC5EaXJlY3RpdmUgZ2V0VW5rbm93bkRpcmVjdGl2ZSgpIHsKICAgICAgICByZXR1cm4gZGlyZWN0aXZlOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgYWRkaXRpb25hbCBhcmd1bWVudC4KICAgICAqCiAgICAgKiBAcmV0dXJuIHRoZSBhZGRpdGlvbmFsIGFyZ3VtZW50LCBvciB7QGNvZGUgbnVsbH0gaWYgdW5hdmFpbGFibGUKICAgICAqLwogICAgcHVibGljIE9iamVjdCBnZXRBcmd1bWVudCgpIHsKICAgICAgICByZXR1cm4gcGFyYW1ldGVyOwogICAgfQp9ClBLAwQKAAAIAAAGO6lKNaz+6t8OAADfDgAAKQAAAGphdmF4L2xhbmcvbW9kZWwvZWxlbWVudC9OZXN0aW5nS2luZC5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDA1LCAyMDE3LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGphdmF4LmxhbmcubW9kZWwuZWxlbWVudDsKCi8qKgogKiBUaGUgPGk+bmVzdGluZyBraW5kPC9pPiBvZiBhIHR5cGUgZWxlbWVudC4KICogVHlwZSBlbGVtZW50cyBjb21lIGluIGZvdXIgdmFyaWV0aWVzOgogKiB0b3AtbGV2ZWwsIG1lbWJlciwgbG9jYWwsIGFuZCBhbm9ueW1vdXMuCiAqIDxpPk5lc3Rpbmcga2luZDwvaT4gaXMgYSBub24tc3RhbmRhcmQgdGVybSB1c2VkIGhlcmUgdG8gZGVub3RlIHRoaXMKICogY2xhc3NpZmljYXRpb24uCiAqCiAqIDxwPk5vdGUgdGhhdCBpdCBpcyBwb3NzaWJsZSBhZGRpdGlvbmFsIG5lc3Rpbmcga2luZHMgd2lsbCBiZSBhZGRlZAogKiBpbiBmdXR1cmUgdmVyc2lvbnMgb2YgdGhlIHBsYXRmb3JtLgogKgogKiA8cD48Yj5FeGFtcGxlOjwvYj4gVGhlIGNsYXNzZXMgYmVsb3cgYXJlIGFubm90YXRlZCB3aXRoIHRoZWlyIG5lc3Rpbmcga2luZC4KICogPGJsb2NrcXVvdGU+PHByZT4KICoKICogaW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLio7CiAqIGltcG9ydCBzdGF0aWMgamF2YS5sYW5nLmFubm90YXRpb24uUmV0ZW50aW9uUG9saWN5Lio7CiAqIGltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuKjsKICogaW1wb3J0IHN0YXRpYyBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuTmVzdGluZ0tpbmQuKjsKICoKICogJiM2NDtOZXN0aW5nKFRPUF9MRVZFTCkKICogcHVibGljIGNsYXNzIE5lc3RpbmdFeGFtcGxlcyB7CiAqICAgICAmIzY0O05lc3RpbmcoTUVNQkVSKQogKiAgICAgc3RhdGljIGNsYXNzIE1lbWJlckNsYXNzMXt9CiAqCiAqICAgICAmIzY0O05lc3RpbmcoTUVNQkVSKQogKiAgICAgY2xhc3MgTWVtYmVyQ2xhc3Mye30KICoKICogICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZy4uLiBhcmd2KSB7CiAqICAgICAgICAgJiM2NDtOZXN0aW5nKExPQ0FMKQogKiAgICAgICAgIGNsYXNzIExvY2FsQ2xhc3N7fTsKICoKICogICAgICAgICBDbGFzcyZsdDs/Jmd0O1tdIGNsYXNzZXMgPSB7CiAqICAgICAgICAgICAgIE5lc3RpbmdFeGFtcGxlcy5jbGFzcywKICogICAgICAgICAgICAgTWVtYmVyQ2xhc3MxLmNsYXNzLAogKiAgICAgICAgICAgICBNZW1iZXJDbGFzczIuY2xhc3MsCiAqICAgICAgICAgICAgIExvY2FsQ2xhc3MuY2xhc3MKICogICAgICAgICB9OwogKgogKiAgICAgICAgIGZvcihDbGFzcyZsdDs/Jmd0OyBjbGF6eiA6IGNsYXNzZXMpIHsKICogICAgICAgICAgICAgU3lzdGVtLm91dC5mb3JtYXQoIiVzIGlzICVzJW4iLAogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGF6ei5nZXROYW1lKCksCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXp6LmdldEFubm90YXRpb24oTmVzdGluZy5jbGFzcykudmFsdWUoKSk7CiAqICAgICAgICAgfQogKiAgICAgfQogKiB9CiAqCiAqICYjNjQ7UmV0ZW50aW9uKFJVTlRJTUUpCiAqICYjNjQ7aW50ZXJmYWNlIE5lc3RpbmcgewogKiAgICAgTmVzdGluZ0tpbmQgdmFsdWUoKTsKICogfQogKiA8L3ByZT48L2Jsb2NrcXVvdGU+CiAqCiAqIEBhdXRob3IgSm9zZXBoIEQuIERhcmN5CiAqIEBhdXRob3IgU2NvdHQgU2VsaWdtYW4KICogQGF1dGhvciBQZXRlciB2b24gZGVyIEFoJmVhY3V0ZTsKICogQHNpbmNlIDEuNgogKi8KcHVibGljIGVudW0gTmVzdGluZ0tpbmQgewogICAgLyoqCiAgICAgKiBBIHRvcC1sZXZlbCB0eXBlLCBub3QgY29udGFpbmVkIHdpdGhpbiBhbm90aGVyIHR5cGUuCiAgICAgKi8KICAgIFRPUF9MRVZFTCwKCiAgICAvKioKICAgICAqIEEgdHlwZSB0aGF0IGlzIGEgbmFtZWQgbWVtYmVyIG9mIGFub3RoZXIgdHlwZS4KICAgICAqIEBqbHMgOC41IE1lbWJlciBUeXBlIERlY2xhcmF0aW9ucwogICAgICovCiAgICBNRU1CRVIsCgogICAgLyoqCiAgICAgKiBBIG5hbWVkIHR5cGUgZGVjbGFyZWQgd2l0aGluIGEgY29uc3RydWN0IG90aGVyIHRoYW4gYSB0eXBlLgogICAgICogQGpscyAxNC4zIExvY2FsIENsYXNzIERlY2xhcmF0aW9ucwogICAgICovCiAgICBMT0NBTCwKCiAgICAvKioKICAgICAqIEEgdHlwZSB3aXRob3V0IGEgbmFtZS4KICAgICAqIEBqbHMgMTUuOS41IEFub255bW91cyBDbGFzcyBEZWNsYXJhdGlvbnMKICAgICAqLwogICAgQU5PTllNT1VTOwoKICAgIC8qKgogICAgICogRG9lcyB0aGlzIGNvbnN0YW50IGNvcnJlc3BvbmQgdG8gYSBuZXN0ZWQgdHlwZSBlbGVtZW50PwogICAgICogQSA8aT5uZXN0ZWQ8L2k+IHR5cGUgZWxlbWVudCBpcyBhbnkgdGhhdCBpcyBub3QgdG9wLWxldmVsLgogICAgICogTW9yZSBzcGVjaWZpY2FsbHksIGFuIDxpPmlubmVyPC9pPiB0eXBlIGVsZW1lbnQgaXMgYW55IG5lc3RlZCB0eXBlIGVsZW1lbnQgdGhhdAogICAgICogaXMgbm90IHtAbGlua3BsYWluIE1vZGlmaWVyI1NUQVRJQyBzdGF0aWN9LgogICAgICogQHJldHVybiB3aGV0aGVyIG9yIG5vdCB0aGUgY29uc3RhbnQgaXMgbmVzdGVkCiAgICAgKiBAamxzIDE0LjMgSW5uZXIgQ2xhc3NlcyBhbmQgRW5jbG9zaW5nIEluc3RhbmNlcwogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBpc05lc3RlZCgpIHsKICAgICAgICByZXR1cm4gdGhpcyAhPSBUT1BfTEVWRUw7CiAgICB9Cn0KUEsDBAoAAAgAANJ9TUpyS8dXaAoAAGgKAAAtAAAAamF2YXgvbGFuZy9tb2RlbC9lbGVtZW50L0Fubm90YXRpb25WYWx1ZS5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDA1LCAyMDEyLCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGphdmF4LmxhbmcubW9kZWwuZWxlbWVudDsKCi8qKgogKiBSZXByZXNlbnRzIGEgdmFsdWUgb2YgYW4gYW5ub3RhdGlvbiB0eXBlIGVsZW1lbnQuCiAqIEEgdmFsdWUgaXMgb2Ygb25lIG9mIHRoZSBmb2xsb3dpbmcgdHlwZXM6CiAqIDx1bD48bGk+IGEgd3JhcHBlciBjbGFzcyAoc3VjaCBhcyB7QGxpbmsgSW50ZWdlcn0pIGZvciBhIHByaW1pdGl2ZSB0eXBlCiAqICAgICA8bGk+IHtAY29kZSBTdHJpbmd9CiAqICAgICA8bGk+IHtAY29kZSBUeXBlTWlycm9yfQogKiAgICAgPGxpPiB7QGNvZGUgVmFyaWFibGVFbGVtZW50fSAocmVwcmVzZW50aW5nIGFuIGVudW0gY29uc3RhbnQpCiAqICAgICA8bGk+IHtAY29kZSBBbm5vdGF0aW9uTWlycm9yfQogKiAgICAgPGxpPiB7QGNvZGUgTGlzdDw/IGV4dGVuZHMgQW5ub3RhdGlvblZhbHVlPn0KICogICAgICAgICAgICAgIChyZXByZXNlbnRpbmcgdGhlIGVsZW1lbnRzLCBpbiBkZWNsYXJlZCBvcmRlciwgaWYgdGhlIHZhbHVlIGlzIGFuIGFycmF5KQogKiA8L3VsPgogKgogKiBAYXV0aG9yIEpvc2VwaCBELiBEYXJjeQogKiBAYXV0aG9yIFNjb3R0IFNlbGlnbWFuCiAqIEBhdXRob3IgUGV0ZXIgdm9uIGRlciBBaCZlYWN1dGU7CiAqIEBzaW5jZSAxLjYKICovCnB1YmxpYyBpbnRlcmZhY2UgQW5ub3RhdGlvblZhbHVlIHsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHZhbHVlLgogICAgICoKICAgICAqIEByZXR1cm4gdGhlIHZhbHVlCiAgICAgKi8KICAgIE9iamVjdCBnZXRWYWx1ZSgpOwoKICAgIC8qKgogICAgICogUmV0dXJucyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIHZhbHVlLgogICAgICogVGhpcyBpcyByZXR1cm5lZCBpbiBhIGZvcm0gc3VpdGFibGUgZm9yIHJlcHJlc2VudGluZyB0aGlzIHZhbHVlCiAgICAgKiBpbiB0aGUgc291cmNlIGNvZGUgb2YgYW4gYW5ub3RhdGlvbi4KICAgICAqCiAgICAgKiBAcmV0dXJuIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgdmFsdWUKICAgICAqLwogICAgU3RyaW5nIHRvU3RyaW5nKCk7CgogICAgLyoqCiAgICAgKiBBcHBsaWVzIGEgdmlzaXRvciB0byB0aGlzIHZhbHVlLgogICAgICoKICAgICAqIEBwYXJhbSA8Uj4gdGhlIHJldHVybiB0eXBlIG9mIHRoZSB2aXNpdG9yJ3MgbWV0aG9kcwogICAgICogQHBhcmFtIDxQPiB0aGUgdHlwZSBvZiB0aGUgYWRkaXRpb25hbCBwYXJhbWV0ZXIgdG8gdGhlIHZpc2l0b3IncyBtZXRob2RzCiAgICAgKiBAcGFyYW0gdiAgIHRoZSB2aXNpdG9yIG9wZXJhdGluZyBvbiB0aGlzIHZhbHVlCiAgICAgKiBAcGFyYW0gcCAgIGFkZGl0aW9uYWwgcGFyYW1ldGVyIHRvIHRoZSB2aXNpdG9yCiAgICAgKiBAcmV0dXJuIGEgdmlzaXRvci1zcGVjaWZpZWQgcmVzdWx0CiAgICAgKi8KICAgIDxSLCBQPiBSIGFjY2VwdChBbm5vdGF0aW9uVmFsdWVWaXNpdG9yPFIsIFA+IHYsIFAgcCk7Cn0KUEsDBAoAAAgAANJ9TUr46JuzOgsAADoLAAAmAAAAamF2YXgvbGFuZy9tb2RlbC9lbGVtZW50L01vZGlmaWVyLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMTMsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgamF2YXgubGFuZy5tb2RlbC5lbGVtZW50OwoKCi8qKgogKiBSZXByZXNlbnRzIGEgbW9kaWZpZXIgb24gYSBwcm9ncmFtIGVsZW1lbnQgc3VjaAogKiBhcyBhIGNsYXNzLCBtZXRob2QsIG9yIGZpZWxkLgogKgogKiA8cD5Ob3QgYWxsIG1vZGlmaWVycyBhcmUgYXBwbGljYWJsZSB0byBhbGwga2luZHMgb2YgZWxlbWVudHMuCiAqIFdoZW4gdHdvIG9yIG1vcmUgbW9kaWZpZXJzIGFwcGVhciBpbiB0aGUgc291cmNlIGNvZGUgb2YgYW4gZWxlbWVudAogKiB0aGVuIGl0IGlzIGN1c3RvbWFyeSwgdGhvdWdoIG5vdCByZXF1aXJlZCwgdGhhdCB0aGV5IGFwcGVhciBpbiB0aGUgc2FtZQogKiBvcmRlciBhcyB0aGUgY29uc3RhbnRzIGxpc3RlZCBpbiB0aGUgZGV0YWlsIHNlY3Rpb24gYmVsb3cuCiAqCiAqIDxwPk5vdGUgdGhhdCBpdCBpcyBwb3NzaWJsZSBhZGRpdGlvbmFsIG1vZGlmaWVycyB3aWxsIGJlIGFkZGVkIGluCiAqIGZ1dHVyZSB2ZXJzaW9ucyBvZiB0aGUgcGxhdGZvcm0uCiAqCiAqIEBhdXRob3IgSm9zZXBoIEQuIERhcmN5CiAqIEBhdXRob3IgU2NvdHQgU2VsaWdtYW4KICogQGF1dGhvciBQZXRlciB2b24gZGVyIEFoJmVhY3V0ZTsKICogQHNpbmNlIDEuNgogKi8KCnB1YmxpYyBlbnVtIE1vZGlmaWVyIHsKCiAgICAvLyBTZWUgSkxTIHNlY3Rpb25zIDguMS4xLCA4LjMuMSwgOC40LjMsIDguOC4zLCBhbmQgOS4xLjEuCiAgICAvLyBqYXZhLmxhbmcucmVmbGVjdC5Nb2RpZmllciBpbmNsdWRlcyBJTlRFUkZBQ0UsIGJ1dCB0aGF0J3MgYSBWTWlzbS4KCiAgICAvKiogVGhlIG1vZGlmaWVyIHtAY29kZSBwdWJsaWN9ICovICAgICAgICAgIFBVQkxJQywKICAgIC8qKiBUaGUgbW9kaWZpZXIge0Bjb2RlIHByb3RlY3RlZH0gKi8gICAgICAgUFJPVEVDVEVELAogICAgLyoqIFRoZSBtb2RpZmllciB7QGNvZGUgcHJpdmF0ZX0gKi8gICAgICAgICBQUklWQVRFLAogICAgLyoqIFRoZSBtb2RpZmllciB7QGNvZGUgYWJzdHJhY3R9ICovICAgICAgICBBQlNUUkFDVCwKICAgIC8qKgogICAgICogVGhlIG1vZGlmaWVyIHtAY29kZSBkZWZhdWx0fQogICAgICogQHNpbmNlIDEuOAogICAgICovCiAgICAgREVGQVVMVCwKICAgIC8qKiBUaGUgbW9kaWZpZXIge0Bjb2RlIHN0YXRpY30gKi8gICAgICAgICAgU1RBVElDLAogICAgLyoqIFRoZSBtb2RpZmllciB7QGNvZGUgZmluYWx9ICovICAgICAgICAgICBGSU5BTCwKICAgIC8qKiBUaGUgbW9kaWZpZXIge0Bjb2RlIHRyYW5zaWVudH0gKi8gICAgICAgVFJBTlNJRU5ULAogICAgLyoqIFRoZSBtb2RpZmllciB7QGNvZGUgdm9sYXRpbGV9ICovICAgICAgICBWT0xBVElMRSwKICAgIC8qKiBUaGUgbW9kaWZpZXIge0Bjb2RlIHN5bmNocm9uaXplZH0gKi8gICAgU1lOQ0hST05JWkVELAogICAgLyoqIFRoZSBtb2RpZmllciB7QGNvZGUgbmF0aXZlfSAqLyAgICAgICAgICBOQVRJVkUsCiAgICAvKiogVGhlIG1vZGlmaWVyIHtAY29kZSBzdHJpY3RmcH0gKi8gICAgICAgIFNUUklDVEZQOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGlzIG1vZGlmaWVyJ3MgbmFtZSBpbiBsb3dlcmNhc2UuCiAgICAgKi8KICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CiAgICAgICAgcmV0dXJuIG5hbWUoKS50b0xvd2VyQ2FzZShqYXZhLnV0aWwuTG9jYWxlLlVTKTsKICAgIH0KfQpQSwMECgAACAAA0n1NSrYv3NA8DgAAPA4AACIAAABqYXZheC9sYW5nL21vZGVsL2VsZW1lbnQvTmFtZS5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDA2LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGphdmF4LmxhbmcubW9kZWwuZWxlbWVudDsKCi8qKgogKiBBbiBpbW11dGFibGUgc2VxdWVuY2Ugb2YgY2hhcmFjdGVycy4gIFdoZW4gY3JlYXRlZCBieSB0aGUgc2FtZQogKiBpbXBsZW1lbnRhdGlvbiwgb2JqZWN0cyBpbXBsZW1lbnRpbmcgdGhpcyBpbnRlcmZhY2UgbXVzdCBvYmV5IHRoZQogKiBnZW5lcmFsIHtAbGlua3BsYWluIE9iamVjdCNlcXVhbHMgZXF1YWxzIGNvbnRyYWN0fSB3aGVuIGNvbXBhcmVkCiAqIHdpdGggZWFjaCBvdGhlci4gIFRoZXJlZm9yZSwge0Bjb2RlIE5hbWV9IG9iamVjdHMgZnJvbSB0aGUgc2FtZQogKiBpbXBsZW1lbnRhdGlvbiBhcmUgdXNhYmxlIGluIGNvbGxlY3Rpb25zIHdoaWxlIHtAY29kZSBOYW1lfXMgZnJvbQogKiBkaWZmZXJlbnQgaW1wbGVtZW50YXRpb25zIG1heSBub3Qgd29yayBwcm9wZXJseSBpbiBjb2xsZWN0aW9ucy4KICoKICogPHA+QW4gZW1wdHkge0Bjb2RlIE5hbWV9IGhhcyBhIGxlbmd0aCBvZiB6ZXJvLgogKgogKiA8cD5JbiB0aGUgY29udGV4dCBvZiB7QGxpbmtwbGFpbgogKiBqYXZheC5hbm5vdGF0aW9uLnByb2Nlc3NpbmcuUHJvY2Vzc2luZ0Vudmlyb25tZW50IGFubm90YXRpb24KICogcHJvY2Vzc2luZ30sIHRoZSBndWFyYW50ZWVzIGZvciAidGhlIHNhbWUiIGltcGxlbWVudGF0aW9uIG11c3QKICogaW5jbHVkZSBjb250ZXh0cyB3aGVyZSB0aGUge0BsaW5rcGxhaW4gamF2YXguYW5ub3RhdGlvbi5wcm9jZXNzaW5nCiAqIEFQSSBtZWRpYXRlZH0gc2lkZSBlZmZlY3RzIG9mIHtAbGlua3BsYWluCiAqIGphdmF4LmFubm90YXRpb24ucHJvY2Vzc2luZy5Qcm9jZXNzb3IgcHJvY2Vzc29yc30gY291bGQgYmUgdmlzaWJsZQogKiB0byBlYWNoIG90aGVyLCBpbmNsdWRpbmcgc3VjY2Vzc2l2ZSBhbm5vdGF0aW9uIHByb2Nlc3NpbmcKICoge0BsaW5rcGxhaW4gamF2YXguYW5ub3RhdGlvbi5wcm9jZXNzaW5nLlJvdW5kRW52aXJvbm1lbnQgcm91bmRzfS4KICoKICogQGF1dGhvciBKb3NlcGggRC4gRGFyY3kKICogQGF1dGhvciBTY290dCBTZWxpZ21hbgogKiBAYXV0aG9yIFBldGVyIHZvbiBkZXIgQWgmZWFjdXRlOwogKiBAc2VlIGphdmF4LmxhbmcubW9kZWwudXRpbC5FbGVtZW50cyNnZXROYW1lCiAqIEBzaW5jZSAxLjYKICovCnB1YmxpYyBpbnRlcmZhY2UgTmFtZSBleHRlbmRzIENoYXJTZXF1ZW5jZSB7CiAgICAvKioKICAgICAqIFJldHVybnMge0Bjb2RlIHRydWV9IGlmIHRoZSBhcmd1bWVudCByZXByZXNlbnRzIHRoZSBzYW1lCiAgICAgKiBuYW1lIGFzIHtAY29kZSB0aGlzfSwgYW5kIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgogICAgICoKICAgICAqIDxwPk5vdGUgdGhhdCB0aGUgaWRlbnRpdHkgb2YgYSB7QGNvZGUgTmFtZX0gaXMgYSBmdW5jdGlvbiBib3RoCiAgICAgKiBvZiBpdHMgY29udGVudCBpbiB0ZXJtcyBvZiBhIHNlcXVlbmNlIG9mIGNoYXJhY3RlcnMgYXMgd2VsbCBhcwogICAgICogdGhlIGltcGxlbWVudGF0aW9uIHdoaWNoIGNyZWF0ZWQgaXQuCiAgICAgKgogICAgICogQHBhcmFtIG9iaiAgdGhlIG9iamVjdCB0byBiZSBjb21wYXJlZCB3aXRoIHRoaXMgZWxlbWVudAogICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhlIHNwZWNpZmllZCBvYmplY3QgcmVwcmVzZW50cyB0aGUgc2FtZQogICAgICogICAgICAgICAgbmFtZSBhcyB0aGlzCiAgICAgKiBAc2VlIEVsZW1lbnQjZXF1YWxzCiAgICAgKi8KICAgIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmopOwoKICAgIC8qKgogICAgICogT2JleXMgdGhlIGdlbmVyYWwgY29udHJhY3Qgb2Yge0BsaW5rIE9iamVjdCNoYXNoQ29kZSBPYmplY3QuaGFzaENvZGV9LgogICAgICoKICAgICAqIEBzZWUgI2VxdWFscwogICAgICovCiAgICBpbnQgaGFzaENvZGUoKTsKCiAgICAvKioKICAgICAqIENvbXBhcmVzIHRoaXMgbmFtZSB0byB0aGUgc3BlY2lmaWVkIHtAY29kZSBDaGFyU2VxdWVuY2V9LiBUaGUgcmVzdWx0CiAgICAgKiBpcyB7QGNvZGUgdHJ1ZX0gaWYgYW5kIG9ubHkgaWYgdGhpcyBuYW1lIHJlcHJlc2VudHMgdGhlIHNhbWUgc2VxdWVuY2UKICAgICAqIG9mIHtAY29kZSBjaGFyfSB2YWx1ZXMgYXMgdGhlIHNwZWNpZmllZCBzZXF1ZW5jZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIG5hbWUgcmVwcmVzZW50cyB0aGUgc2FtZSBzZXF1ZW5jZQogICAgICogb2Yge0Bjb2RlIGNoYXJ9IHZhbHVlcyBhcyB0aGUgc3BlY2lmaWVkIHNlcXVlbmNlLCB7QGNvZGUgZmFsc2V9CiAgICAgKiBvdGhlcndpc2UKICAgICAqCiAgICAgKiBAcGFyYW0gY3MgVGhlIHNlcXVlbmNlIHRvIGNvbXBhcmUgdGhpcyBuYW1lIGFnYWluc3QKICAgICAqIEBzZWUgU3RyaW5nI2NvbnRlbnRFcXVhbHMoQ2hhclNlcXVlbmNlKQogICAgICovCiAgICBib29sZWFuIGNvbnRlbnRFcXVhbHMoQ2hhclNlcXVlbmNlIGNzKTsKfQpQSwMECgAACAAABjupSqB87Ly9DgAAvQ4AACkAAABqYXZheC9sYW5nL21vZGVsL2VsZW1lbnQvRWxlbWVudEtpbmQuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAxNSwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQ7CgovKioKICogVGhlIHtAY29kZSBraW5kfSBvZiBhbiBlbGVtZW50LgogKgogKiA8cD5Ob3RlIHRoYXQgaXQgaXMgcG9zc2libGUgYWRkaXRpb25hbCBlbGVtZW50IGtpbmRzIHdpbGwgYmUgYWRkZWQKICogdG8gYWNjb21tb2RhdGUgbmV3LCBjdXJyZW50bHkgdW5rbm93biwgbGFuZ3VhZ2Ugc3RydWN0dXJlcyBhZGRlZCB0bwogKiBmdXR1cmUgdmVyc2lvbnMgb2YgdGhlIEphdmEmdHJhZGU7IHByb2dyYW1taW5nIGxhbmd1YWdlLgogKgogKiBAYXV0aG9yIEpvc2VwaCBELiBEYXJjeQogKiBAYXV0aG9yIFNjb3R0IFNlbGlnbWFuCiAqIEBhdXRob3IgUGV0ZXIgdm9uIGRlciBBaCZlYWN1dGU7CiAqIEBzZWUgRWxlbWVudAogKiBAc2luY2UgMS42CiAqLwpwdWJsaWMgZW51bSBFbGVtZW50S2luZCB7CgogICAgLyoqIEEgcGFja2FnZS4gKi8KICAgIFBBQ0tBR0UsCgogICAgLy8gRGVjbGFyZWQgdHlwZXMKICAgIC8qKiBBbiBlbnVtIHR5cGUuICovCiAgICBFTlVNLAogICAgLyoqIEEgY2xhc3Mgbm90IGRlc2NyaWJlZCBieSBhIG1vcmUgc3BlY2lmaWMga2luZCAobGlrZSB7QGNvZGUgRU5VTX0pLiAqLwogICAgQ0xBU1MsCiAgICAvKiogQW4gYW5ub3RhdGlvbiB0eXBlLiAqLwogICAgQU5OT1RBVElPTl9UWVBFLAogICAgLyoqCiAgICAgKiBBbiBpbnRlcmZhY2Ugbm90IGRlc2NyaWJlZCBieSBhIG1vcmUgc3BlY2lmaWMga2luZCAobGlrZQogICAgICoge0Bjb2RlIEFOTk9UQVRJT05fVFlQRX0pLgogICAgICovCiAgICBJTlRFUkZBQ0UsCgogICAgLy8gVmFyaWFibGVzCiAgICAvKiogQW4gZW51bSBjb25zdGFudC4gKi8KICAgIEVOVU1fQ09OU1RBTlQsCiAgICAvKioKICAgICAqIEEgZmllbGQgbm90IGRlc2NyaWJlZCBieSBhIG1vcmUgc3BlY2lmaWMga2luZCAobGlrZQogICAgICoge0Bjb2RlIEVOVU1fQ09OU1RBTlR9KS4KICAgICAqLwogICAgRklFTEQsCiAgICAvKiogQSBwYXJhbWV0ZXIgb2YgYSBtZXRob2Qgb3IgY29uc3RydWN0b3IuICovCiAgICBQQVJBTUVURVIsCiAgICAvKiogQSBsb2NhbCB2YXJpYWJsZS4gKi8KICAgIExPQ0FMX1ZBUklBQkxFLAogICAgLyoqIEEgcGFyYW1ldGVyIG9mIGFuIGV4Y2VwdGlvbiBoYW5kbGVyLiAqLwogICAgRVhDRVBUSU9OX1BBUkFNRVRFUiwKCiAgICAvLyBFeGVjdXRhYmxlcwogICAgLyoqIEEgbWV0aG9kLiAqLwogICAgTUVUSE9ELAogICAgLyoqIEEgY29uc3RydWN0b3IuICovCiAgICBDT05TVFJVQ1RPUiwKICAgIC8qKiBBIHN0YXRpYyBpbml0aWFsaXplci4gKi8KICAgIFNUQVRJQ19JTklULAogICAgLyoqIEFuIGluc3RhbmNlIGluaXRpYWxpemVyLiAqLwogICAgSU5TVEFOQ0VfSU5JVCwKCiAgICAvKiogQSB0eXBlIHBhcmFtZXRlci4gKi8KICAgIFRZUEVfUEFSQU1FVEVSLAoKICAgIC8qKgogICAgICogQW4gaW1wbGVtZW50YXRpb24tcmVzZXJ2ZWQgZWxlbWVudC4gIFRoaXMgaXMgbm90IHRoZSBlbGVtZW50CiAgICAgKiB5b3UgYXJlIGxvb2tpbmcgZm9yLgogICAgICovCiAgICBPVEhFUiwKCiAgICAvKioKICAgICAqIEEgcmVzb3VyY2UgdmFyaWFibGUuCiAgICAgKiBAc2luY2UgMS43CiAgICAgKi8KICAgICBSRVNPVVJDRV9WQVJJQUJMRSwKCiAgICAvKioKICAgICAqIEEgbW9kdWxlLgogICAgICogQHNpbmNlIDkKICAgICAqIEBzcGVjIEpQTVMKICAgICAqLwogICAgIE1PRFVMRTsKCgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHtAY29kZSB0cnVlfSBpZiB0aGlzIGlzIGEga2luZCBvZiBjbGFzczoKICAgICAqIGVpdGhlciB7QGNvZGUgQ0xBU1N9IG9yIHtAY29kZSBFTlVNfS4KICAgICAqCiAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIGlzIGEga2luZCBvZiBjbGFzcwogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBpc0NsYXNzKCkgewogICAgICAgIHJldHVybiB0aGlzID09IENMQVNTIHx8IHRoaXMgPT0gRU5VTTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMge0Bjb2RlIHRydWV9IGlmIHRoaXMgaXMgYSBraW5kIG9mIGludGVyZmFjZToKICAgICAqIGVpdGhlciB7QGNvZGUgSU5URVJGQUNFfSBvciB7QGNvZGUgQU5OT1RBVElPTl9UWVBFfS4KICAgICAqCiAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIGlzIGEga2luZCBvZiBpbnRlcmZhY2UKICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gaXNJbnRlcmZhY2UoKSB7CiAgICAgICAgcmV0dXJuIHRoaXMgPT0gSU5URVJGQUNFIHx8IHRoaXMgPT0gQU5OT1RBVElPTl9UWVBFOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyBpcyBhIGtpbmQgb2YgZmllbGQ6CiAgICAgKiBlaXRoZXIge0Bjb2RlIEZJRUxEfSBvciB7QGNvZGUgRU5VTV9DT05TVEFOVH0uCiAgICAgKgogICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyBpcyBhIGtpbmQgb2YgZmllbGQKICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gaXNGaWVsZCgpIHsKICAgICAgICByZXR1cm4gdGhpcyA9PSBGSUVMRCB8fCB0aGlzID09IEVOVU1fQ09OU1RBTlQ7CiAgICB9Cn0KUEsDBAoAAAgAANJ9TUpswZQ/YBMAAGATAAAvAAAAamF2YXgvbGFuZy9tb2RlbC9lbGVtZW50L0V4ZWN1dGFibGVFbGVtZW50LmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMTMsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgamF2YXgubGFuZy5tb2RlbC5lbGVtZW50OwoKaW1wb3J0IGphdmEudXRpbC5MaXN0OwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC50eXBlLio7CgovKioKICogUmVwcmVzZW50cyBhIG1ldGhvZCwgY29uc3RydWN0b3IsIG9yIGluaXRpYWxpemVyIChzdGF0aWMgb3IKICogaW5zdGFuY2UpIG9mIGEgY2xhc3Mgb3IgaW50ZXJmYWNlLCBpbmNsdWRpbmcgYW5ub3RhdGlvbiB0eXBlCiAqIGVsZW1lbnRzLgogKgogKiBAYXV0aG9yIEpvc2VwaCBELiBEYXJjeQogKiBAYXV0aG9yIFNjb3R0IFNlbGlnbWFuCiAqIEBhdXRob3IgUGV0ZXIgdm9uIGRlciBBaCZlYWN1dGU7CiAqIEBzZWUgRXhlY3V0YWJsZVR5cGUKICogQHNpbmNlIDEuNgogKi8KcHVibGljIGludGVyZmFjZSBFeGVjdXRhYmxlRWxlbWVudCBleHRlbmRzIEVsZW1lbnQsIFBhcmFtZXRlcml6YWJsZSB7CiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGZvcm1hbCB0eXBlIHBhcmFtZXRlcnMgb2YgdGhpcyBleGVjdXRhYmxlCiAgICAgKiBpbiBkZWNsYXJhdGlvbiBvcmRlci4KICAgICAqCiAgICAgKiBAcmV0dXJuIHRoZSBmb3JtYWwgdHlwZSBwYXJhbWV0ZXJzLCBvciBhbiBlbXB0eSBsaXN0CiAgICAgKiBpZiB0aGVyZSBhcmUgbm9uZQogICAgICovCiAgICBMaXN0PD8gZXh0ZW5kcyBUeXBlUGFyYW1ldGVyRWxlbWVudD4gZ2V0VHlwZVBhcmFtZXRlcnMoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHJldHVybiB0eXBlIG9mIHRoaXMgZXhlY3V0YWJsZS4KICAgICAqIFJldHVybnMgYSB7QGxpbmsgTm9UeXBlfSB3aXRoIGtpbmQge0BsaW5rIFR5cGVLaW5kI1ZPSUQgVk9JRH0KICAgICAqIGlmIHRoaXMgZXhlY3V0YWJsZSBpcyBub3QgYSBtZXRob2QsIG9yIGlzIGEgbWV0aG9kIHRoYXQgZG9lcyBub3QKICAgICAqIHJldHVybiBhIHZhbHVlLgogICAgICoKICAgICAqIEByZXR1cm4gdGhlIHJldHVybiB0eXBlIG9mIHRoaXMgZXhlY3V0YWJsZQogICAgICovCiAgICBUeXBlTWlycm9yIGdldFJldHVyblR5cGUoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGZvcm1hbCBwYXJhbWV0ZXJzIG9mIHRoaXMgZXhlY3V0YWJsZS4KICAgICAqIFRoZXkgYXJlIHJldHVybmVkIGluIGRlY2xhcmF0aW9uIG9yZGVyLgogICAgICoKICAgICAqIEByZXR1cm4gdGhlIGZvcm1hbCBwYXJhbWV0ZXJzLAogICAgICogb3IgYW4gZW1wdHkgbGlzdCBpZiB0aGVyZSBhcmUgbm9uZQogICAgICovCiAgICBMaXN0PD8gZXh0ZW5kcyBWYXJpYWJsZUVsZW1lbnQ+IGdldFBhcmFtZXRlcnMoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHJlY2VpdmVyIHR5cGUgb2YgdGhpcyBleGVjdXRhYmxlLAogICAgICogb3Ige0BsaW5rIGphdmF4LmxhbmcubW9kZWwudHlwZS5Ob1R5cGUgTm9UeXBlfSB3aXRoCiAgICAgKiBraW5kIHtAbGluayBqYXZheC5sYW5nLm1vZGVsLnR5cGUuVHlwZUtpbmQjTk9ORSBOT05FfQogICAgICogaWYgdGhlIGV4ZWN1dGFibGUgaGFzIG5vIHJlY2VpdmVyIHR5cGUuCiAgICAgKgogICAgICogQW4gZXhlY3V0YWJsZSB3aGljaCBpcyBhbiBpbnN0YW5jZSBtZXRob2QsIG9yIGEgY29uc3RydWN0b3Igb2YgYW4KICAgICAqIGlubmVyIGNsYXNzLCBoYXMgYSByZWNlaXZlciB0eXBlIGRlcml2ZWQgZnJvbSB0aGUge0BsaW5rcGxhaW4KICAgICAqICNnZXRFbmNsb3NpbmdFbGVtZW50IGRlY2xhcmluZyB0eXBlfS4KICAgICAqCiAgICAgKiBBbiBleGVjdXRhYmxlIHdoaWNoIGlzIGEgc3RhdGljIG1ldGhvZCwgb3IgYSBjb25zdHJ1Y3RvciBvZiBhCiAgICAgKiBub24taW5uZXIgY2xhc3MsIG9yIGFuIGluaXRpYWxpemVyIChzdGF0aWMgb3IgaW5zdGFuY2UpLCBoYXMgbm8KICAgICAqIHJlY2VpdmVyIHR5cGUuCiAgICAgKgogICAgICogQHJldHVybiB0aGUgcmVjZWl2ZXIgdHlwZSBvZiB0aGlzIGV4ZWN1dGFibGUKICAgICAqIEBzaW5jZSAxLjgKICAgICAqLwogICAgVHlwZU1pcnJvciBnZXRSZWNlaXZlclR5cGUoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMge0Bjb2RlIHRydWV9IGlmIHRoaXMgbWV0aG9kIG9yIGNvbnN0cnVjdG9yIGFjY2VwdHMgYSB2YXJpYWJsZQogICAgICogbnVtYmVyIG9mIGFyZ3VtZW50cyBhbmQgcmV0dXJucyB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIG1ldGhvZCBvciBjb25zdHJ1Y3RvciBhY2NlcHRzIGEgdmFyaWFibGUKICAgICAqIG51bWJlciBvZiBhcmd1bWVudHMgYW5kIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlCiAgICAgKi8KICAgIGJvb2xlYW4gaXNWYXJBcmdzKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHtAY29kZSB0cnVlfSBpZiB0aGlzIG1ldGhvZCBpcyBhIGRlZmF1bHQgbWV0aG9kIGFuZAogICAgICogcmV0dXJucyB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIG1ldGhvZCBpcyBhIGRlZmF1bHQgbWV0aG9kIGFuZAogICAgICoge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UKICAgICAqIEBzaW5jZSAxLjgKICAgICAqLwogICAgYm9vbGVhbiBpc0RlZmF1bHQoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGV4Y2VwdGlvbnMgYW5kIG90aGVyIHRocm93YWJsZXMgbGlzdGVkIGluIHRoaXMKICAgICAqIG1ldGhvZCBvciBjb25zdHJ1Y3RvcidzIHtAY29kZSB0aHJvd3N9IGNsYXVzZSBpbiBkZWNsYXJhdGlvbgogICAgICogb3JkZXIuCiAgICAgKgogICAgICogQHJldHVybiB0aGUgZXhjZXB0aW9ucyBhbmQgb3RoZXIgdGhyb3dhYmxlcyBsaXN0ZWQgaW4gdGhlCiAgICAgKiB7QGNvZGUgdGhyb3dzfSBjbGF1c2UsIG9yIGFuIGVtcHR5IGxpc3QgaWYgdGhlcmUgYXJlIG5vbmUKICAgICAqLwogICAgTGlzdDw/IGV4dGVuZHMgVHlwZU1pcnJvcj4gZ2V0VGhyb3duVHlwZXMoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGRlZmF1bHQgdmFsdWUgaWYgdGhpcyBleGVjdXRhYmxlIGlzIGFuIGFubm90YXRpb24KICAgICAqIHR5cGUgZWxlbWVudC4gIFJldHVybnMge0Bjb2RlIG51bGx9IGlmIHRoaXMgbWV0aG9kIGlzIG5vdCBhbgogICAgICogYW5ub3RhdGlvbiB0eXBlIGVsZW1lbnQsIG9yIGlmIGl0IGlzIGFuIGFubm90YXRpb24gdHlwZSBlbGVtZW50CiAgICAgKiB3aXRoIG5vIGRlZmF1bHQgdmFsdWUuCiAgICAgKgogICAgICogQHJldHVybiB0aGUgZGVmYXVsdCB2YWx1ZSwgb3Ige0Bjb2RlIG51bGx9IGlmIG5vbmUKICAgICAqLwogICAgQW5ub3RhdGlvblZhbHVlIGdldERlZmF1bHRWYWx1ZSgpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgc2ltcGxlIG5hbWUgb2YgYSBjb25zdHJ1Y3RvciwgbWV0aG9kLCBvcgogICAgICogaW5pdGlhbGl6ZXIuICBGb3IgYSBjb25zdHJ1Y3RvciwgdGhlIG5hbWUge0Bjb2RlICI8aW5pdD4ifSBpcwogICAgICogcmV0dXJuZWQsIGZvciBhIHN0YXRpYyBpbml0aWFsaXplciwgdGhlIG5hbWUge0Bjb2RlICI8Y2xpbml0PiJ9CiAgICAgKiBpcyByZXR1cm5lZCwgYW5kIGZvciBhbiBhbm9ueW1vdXMgY2xhc3Mgb3IgaW5zdGFuY2UKICAgICAqIGluaXRpYWxpemVyLCBhbiBlbXB0eSBuYW1lIGlzIHJldHVybmVkLgogICAgICoKICAgICAqIEByZXR1cm4gdGhlIHNpbXBsZSBuYW1lIG9mIGEgY29uc3RydWN0b3IsIG1ldGhvZCwgb3IKICAgICAqIGluaXRpYWxpemVyCiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgTmFtZSBnZXRTaW1wbGVOYW1lKCk7Cn0KUEsDBAoAAAgAAAY7qUokcrakdC8AAHQvAAArAAAAamF2YXgvbGFuZy9tb2RlbC9lbGVtZW50L01vZHVsZUVsZW1lbnQuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAxNywgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQ7CgppbXBvcnQgamF2YS51dGlsLkxpc3Q7CgovKioKICogUmVwcmVzZW50cyBhIG1vZHVsZSBwcm9ncmFtIGVsZW1lbnQuICBQcm92aWRlcyBhY2Nlc3MgdG8gaW5mb3JtYXRpb24KICogYWJvdXQgdGhlIG1vZHVsZSBhbmQgaXRzIG1lbWJlcnMuCiAqCiAqIEBzZWUgamF2YXgubGFuZy5tb2RlbC51dGlsLkVsZW1lbnRzI2dldE1vZHVsZU9mCiAqIEBzaW5jZSA5CiAqIEBzcGVjIEpQTVMKICovICAvLyBUT0RPOiBhZGQgQGpscyB0byBtb2R1bGUgc2VjdGlvbgpwdWJsaWMgaW50ZXJmYWNlIE1vZHVsZUVsZW1lbnQgZXh0ZW5kcyBFbGVtZW50LCBRdWFsaWZpZWROYW1lYWJsZSB7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBmdWxseSBxdWFsaWZpZWQgbmFtZSBvZiB0aGlzIG1vZHVsZS4gIEZvciBhbgogICAgICoge0BsaW5rcGxhaW4gI2lzVW5uYW1lZCgpIHVubmFtZWQgbW9kdWxlfSwgYW4gZW1wdHkgbmFtZSBpcyByZXR1cm5lZC4KICAgICAqCiAgICAgKiBAcmV0dXJuIHRoZSBmdWxseSBxdWFsaWZpZWQgbmFtZSBvZiB0aGlzIG1vZHVsZSwgb3IgYW4KICAgICAqIGVtcHR5IG5hbWUgaWYgdGhpcyBpcyBhbiB1bm5hbWVkIG1vZHVsZQogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIE5hbWUgZ2V0UXVhbGlmaWVkTmFtZSgpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgc2ltcGxlIG5hbWUgb2YgdGhpcyBtb2R1bGUuICBGb3IgYW4ge0BsaW5rcGxhaW4KICAgICAqICNpc1VubmFtZWQoKSB1bm5hbWVkIG1vZHVsZX0sIGFuIGVtcHR5IG5hbWUgaXMgcmV0dXJuZWQuCiAgICAgKgogICAgICogQHJldHVybiB0aGUgc2ltcGxlIG5hbWUgb2YgdGhpcyBtb2R1bGUgb3IgYW4gZW1wdHkgbmFtZSBpZgogICAgICogdGhpcyBpcyBhbiB1bm5hbWVkIG1vZHVsZQogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIE5hbWUgZ2V0U2ltcGxlTmFtZSgpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgcGFja2FnZXMgd2l0aGluIHRoaXMgbW9kdWxlLgogICAgICogQHJldHVybiB0aGUgcGFja2FnZXMgd2l0aGluIHRoaXMgbW9kdWxlCiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgTGlzdDw/IGV4dGVuZHMgRWxlbWVudD4gZ2V0RW5jbG9zZWRFbGVtZW50cygpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyBpcyBhbiBvcGVuIG1vZHVsZSBhbmQge0Bjb2RlCiAgICAgKiBmYWxzZX0gb3RoZXJ3aXNlLgogICAgICoKICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoaXMgaXMgYW4gb3BlbiBtb2R1bGUgYW5kIHtAY29kZQogICAgICogZmFsc2V9IG90aGVyd2lzZQogICAgICovIC8vIFRPRE86IGFkZCBAamxzIHRvIHVubmFtZWQgbW9kdWxlIHNlY3Rpb24KICAgIGJvb2xlYW4gaXNPcGVuKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHtAY29kZSB0cnVlfSBpZiB0aGlzIGlzIGFuIHVubmFtZWQgbW9kdWxlIGFuZCB7QGNvZGUKICAgICAqIGZhbHNlfSBvdGhlcndpc2UuCiAgICAgKgogICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyBpcyBhbiB1bm5hbWVkIG1vZHVsZSBhbmQge0Bjb2RlCiAgICAgKiBmYWxzZX0gb3RoZXJ3aXNlCiAgICAgKi8gLy8gVE9ETzogYWRkIEBqbHMgdG8gdW5uYW1lZCBtb2R1bGUgc2VjdGlvbgogICAgYm9vbGVhbiBpc1VubmFtZWQoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMge0Bjb2RlIG51bGx9IHNpbmNlIGEgbW9kdWxlIGlzIG5vdCBlbmNsb3NlZCBieSBhbm90aGVyCiAgICAgKiBlbGVtZW50LgogICAgICoKICAgICAqIEByZXR1cm4ge0Bjb2RlIG51bGx9CiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgRWxlbWVudCBnZXRFbmNsb3NpbmdFbGVtZW50KCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBkaXJlY3RpdmVzIGNvbnRhaW5lZCBpbiB0aGUgZGVjbGFyYXRpb24gb2YgdGhpcyBtb2R1bGUuCiAgICAgKiBAcmV0dXJuICB0aGUgZGlyZWN0aXZlcyBpbiB0aGUgZGVjbGFyYXRpb24gb2YgdGhpcyBtb2R1bGUKICAgICAqLwogICAgTGlzdDw/IGV4dGVuZHMgRGlyZWN0aXZlPiBnZXREaXJlY3RpdmVzKCk7CgogICAgLyoqCiAgICAgKiBUaGUge0Bjb2RlIGtpbmR9IG9mIGEgZGlyZWN0aXZlLgogICAgICoKICAgICAqIDxwPk5vdGUgdGhhdCBpdCBpcyBwb3NzaWJsZSBhZGRpdGlvbmFsIGRpcmVjdGl2ZSBraW5kcyB3aWxsIGJlIGFkZGVkCiAgICAgKiB0byBhY2NvbW1vZGF0ZSBuZXcsIGN1cnJlbnRseSB1bmtub3duLCBsYW5ndWFnZSBzdHJ1Y3R1cmVzIGFkZGVkIHRvCiAgICAgKiBmdXR1cmUgdmVyc2lvbnMgb2YgdGhlIEphdmEmdHJhZGU7IHByb2dyYW1taW5nIGxhbmd1YWdlLgogICAgICoKICAgICAqIEBzaW5jZSA5CiAgICAgKiBAc3BlYyBKUE1TCiAgICAgKi8KICAgIGVudW0gRGlyZWN0aXZlS2luZCB7CiAgICAgICAgLyoqIEEgInJlcXVpcmVzIChzdGF0aWN8dHJhbnNpdGl2ZSkqIG1vZHVsZS1uYW1lIiBkaXJlY3RpdmUuICovCiAgICAgICAgUkVRVUlSRVMsCiAgICAgICAgLyoqIEFuICJleHBvcnRzIHBhY2thZ2UtbmFtZSBbdG8gbW9kdWxlLW5hbWUtbGlzdF0iIGRpcmVjdGl2ZS4gKi8KICAgICAgICBFWFBPUlRTLAogICAgICAgIC8qKiBBbiAib3BlbnMgcGFja2FnZS1uYW1lIFt0byBtb2R1bGUtbmFtZS1saXN0XSIgZGlyZWN0aXZlLiAqLwogICAgICAgIE9QRU5TLAogICAgICAgIC8qKiBBICJ1c2VzIHNlcnZpY2UtbmFtZSIgZGlyZWN0aXZlLiAqLwogICAgICAgIFVTRVMsCiAgICAgICAgLyoqIEEgInByb3ZpZGVzIHNlcnZpY2UtbmFtZSB3aXRoIGltcGxlbWVudGF0aW9uLW5hbWUiIGRpcmVjdGl2ZS4gKi8KICAgICAgICBQUk9WSURFUwogICAgfTsKCiAgICAvKioKICAgICAqIFJlcHJlc2VudHMgYSAibW9kdWxlIHN0YXRlbWVudCIgd2l0aGluIHRoZSBkZWNsYXJhdGlvbiBvZiB0aGlzIG1vZHVsZS4KICAgICAqCiAgICAgKiBAc2luY2UgOQogICAgICogQHNwZWMgSlBNUwogICAgICoKICAgICAqLyAvLyBUT0RPOiBhZGQgamxzIHRvIE1vZHVsZSBTdGF0ZW1lbnQKICAgIGludGVyZmFjZSBEaXJlY3RpdmUgewogICAgICAgIC8qKgogICAgICAgICAqIFJldHVybnMgdGhlIHtAY29kZSBraW5kfSBvZiB0aGlzIGRpcmVjdGl2ZS4KICAgICAgICAgKgogICAgICAgICAqIEByZXR1cm4gdGhlIGtpbmQgb2YgdGhpcyBkaXJlY3RpdmUKICAgICAgICAgKi8KICAgICAgICBEaXJlY3RpdmVLaW5kIGdldEtpbmQoKTsKCiAgICAgICAgLyoqCiAgICAgICAgICogQXBwbGllcyBhIHZpc2l0b3IgdG8gdGhpcyBkaXJlY3RpdmUuCiAgICAgICAgICoKICAgICAgICAgKiBAcGFyYW0gPFI+IHRoZSByZXR1cm4gdHlwZSBvZiB0aGUgdmlzaXRvcidzIG1ldGhvZHMKICAgICAgICAgKiBAcGFyYW0gPFA+IHRoZSB0eXBlIG9mIHRoZSBhZGRpdGlvbmFsIHBhcmFtZXRlciB0byB0aGUgdmlzaXRvcidzIG1ldGhvZHMKICAgICAgICAgKiBAcGFyYW0gdiAgIHRoZSB2aXNpdG9yIG9wZXJhdGluZyBvbiB0aGlzIGRpcmVjdGl2ZQogICAgICAgICAqIEBwYXJhbSBwICAgYWRkaXRpb25hbCBwYXJhbWV0ZXIgdG8gdGhlIHZpc2l0b3IKICAgICAgICAgKiBAcmV0dXJuIGEgdmlzaXRvci1zcGVjaWZpZWQgcmVzdWx0CiAgICAgICAgICovCiAgICAgICAgPFIsIFA+IFIgYWNjZXB0KERpcmVjdGl2ZVZpc2l0b3I8UiwgUD4gdiwgUCBwKTsKICAgIH0KCiAgICAvKioKICAgICAqIEEgdmlzaXRvciBvZiBtb2R1bGUgZGlyZWN0aXZlcywgaW4gdGhlIHN0eWxlIG9mIHRoZSB2aXNpdG9yIGRlc2lnbgogICAgICogcGF0dGVybi4gIENsYXNzZXMgaW1wbGVtZW50aW5nIHRoaXMgaW50ZXJmYWNlIGFyZSB1c2VkIHRvIG9wZXJhdGUKICAgICAqIG9uIGEgZGlyZWN0aXZlIHdoZW4gdGhlIGtpbmQgb2YgZGlyZWN0aXZlIGlzIHVua25vd24gYXQgY29tcGlsZSB0aW1lLgogICAgICogV2hlbiBhIHZpc2l0b3IgaXMgcGFzc2VkIHRvIGEgZGlyZWN0aXZlJ3Mge0BsaW5rIERpcmVjdGl2ZSNhY2NlcHQKICAgICAqIGFjY2VwdH0gbWV0aG9kLCB0aGUgPHR0PnZpc2l0PGk+WHl6PC9pPjwvdHQ+IG1ldGhvZCBhcHBsaWNhYmxlCiAgICAgKiB0byB0aGF0IGRpcmVjdGl2ZSBpcyBpbnZva2VkLgogICAgICoKICAgICAqIDxwPiBDbGFzc2VzIGltcGxlbWVudGluZyB0aGlzIGludGVyZmFjZSBtYXkgb3IgbWF5IG5vdCB0aHJvdyBhCiAgICAgKiB7QGNvZGUgTnVsbFBvaW50ZXJFeGNlcHRpb259IGlmIHRoZSBhZGRpdGlvbmFsIHBhcmFtZXRlciB7QGNvZGUgcH0KICAgICAqIGlzIHtAY29kZSBudWxsfTsgc2VlIGRvY3VtZW50YXRpb24gb2YgdGhlIGltcGxlbWVudGluZyBjbGFzcyBmb3IKICAgICAqIGRldGFpbHMuCiAgICAgKgogICAgICogPHA+IDxiPldBUk5JTkc6PC9iPiBJdCBpcyBwb3NzaWJsZSB0aGF0IG1ldGhvZHMgd2lsbCBiZSBhZGRlZCB0bwogICAgICogdGhpcyBpbnRlcmZhY2UgdG8gYWNjb21tb2RhdGUgbmV3LCBjdXJyZW50bHkgdW5rbm93biwgbGFuZ3VhZ2UKICAgICAqIHN0cnVjdHVyZXMgYWRkZWQgdG8gZnV0dXJlIHZlcnNpb25zIG9mIHRoZSBKYXZhJnRyYWRlOyBwcm9ncmFtbWluZwogICAgICogbGFuZ3VhZ2UuIE1ldGhvZHMgdG8gYWNjb21tb2RhdGUgbmV3IGxhbmd1YWdlIGNvbnN0cnVjdHMgd2lsbAogICAgICogYmUgYWRkZWQgaW4gYSBzb3VyY2UgPGVtPmNvbXBhdGlibGU8L2VtPiB3YXkgdXNpbmcKICAgICAqIDxlbT5kZWZhdWx0IG1ldGhvZHM8L2VtPi4KICAgICAqCiAgICAgKiBAcGFyYW0gPFI+IHRoZSByZXR1cm4gdHlwZSBvZiB0aGlzIHZpc2l0b3IncyBtZXRob2RzLiAgVXNlIHtAbGluawogICAgICogICAgICAgICAgICBWb2lkfSBmb3IgdmlzaXRvcnMgdGhhdCBkbyBub3QgbmVlZCB0byByZXR1cm4gcmVzdWx0cy4KICAgICAqIEBwYXJhbSA8UD4gdGhlIHR5cGUgb2YgdGhlIGFkZGl0aW9uYWwgcGFyYW1ldGVyIHRvIHRoaXMgdmlzaXRvcidzCiAgICAgKiAgICAgICAgICAgIG1ldGhvZHMuICBVc2Uge0Bjb2RlIFZvaWR9IGZvciB2aXNpdG9ycyB0aGF0IGRvIG5vdCBuZWVkIGFuCiAgICAgKiAgICAgICAgICAgIGFkZGl0aW9uYWwgcGFyYW1ldGVyLgogICAgICoKICAgICAqIEBzaW5jZSA5CiAgICAgKiBAc3BlYyBKUE1TCiAgICAgKi8KICAgIGludGVyZmFjZSBEaXJlY3RpdmVWaXNpdG9yPFIsIFA+IHsKICAgICAgICAvKioKICAgICAgICAgKiBWaXNpdHMgYW55IGRpcmVjdGl2ZSBhcyBpZiBieSBwYXNzaW5nIGl0c2VsZiB0byB0aGF0CiAgICAgICAgICogZGlyZWN0aXZlJ3Mge0BsaW5rIERpcmVjdGl2ZSNhY2NlcHQgYWNjZXB0fSBtZXRob2QgYW5kIHBhc3NpbmcKICAgICAgICAgKiB7QGNvZGUgbnVsbH0gZm9yIHRoZSBhZGRpdGlvbmFsIHBhcmFtZXRlci4KICAgICAgICAgKiBUaGUgaW52b2NhdGlvbiB7QGNvZGUgdi52aXNpdChkKX0gaXMgZXF1aXZhbGVudCB0bwogICAgICAgICAqIHtAY29kZSBkLmFjY2VwdCh2LCBudWxsKX0uCiAgICAgICAgICogQHBhcmFtIGQgIHRoZSBkaXJlY3RpdmUgdG8gdmlzaXQKICAgICAgICAgKiBAcmV0dXJuIGEgdmlzaXRvci1zcGVjaWZpZWQgcmVzdWx0CiAgICAgICAgICogQGltcGxTcGVjIFRoaXMgaW1wbGVtZW50YXRpb24gaXMge0Bjb2RlIHZpc2l0KGQsIG51bGwpfQogICAgICAgICAqLwogICAgICAgIGRlZmF1bHQgUiB2aXNpdChEaXJlY3RpdmUgZCkgewogICAgICAgICAgICByZXR1cm4gZC5hY2NlcHQodGhpcywgbnVsbCk7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBWaXNpdHMgYW55IGRpcmVjdGl2ZSBhcyBpZiBieSBwYXNzaW5nIGl0c2VsZiB0byB0aGF0CiAgICAgICAgICogZGlyZWN0aXZlJ3Mge0BsaW5rIERpcmVjdGl2ZSNhY2NlcHQgYWNjZXB0fSBtZXRob2QuCiAgICAgICAgICogVGhlIGludm9jYXRpb24ge0Bjb2RlIHYudmlzaXQoZCwgcCl9IGlzIGVxdWl2YWxlbnQgdG8KICAgICAgICAgKiB7QGNvZGUgZC5hY2NlcHQodiwgcCl9LgogICAgICAgICAqIEBwYXJhbSBkICB0aGUgZGlyZWN0aXZlIHRvIHZpc2l0CiAgICAgICAgICogQHBhcmFtIHAgIGEgdmlzaXRvci1zcGVjaWZpZWQgcGFyYW1ldGVyCiAgICAgICAgICogQHJldHVybiBhIHZpc2l0b3Itc3BlY2lmaWVkIHJlc3VsdAogICAgICAgICAqLwogICAgICAgIGRlZmF1bHQgUiB2aXNpdChEaXJlY3RpdmUgZCwgUCBwKSB7CiAgICAgICAgICAgIHJldHVybiBkLmFjY2VwdCh0aGlzLCBwKTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIFZpc2l0cyBhIHtAY29kZSByZXF1aXJlc30gZGlyZWN0aXZlLgogICAgICAgICAqIEBwYXJhbSBkICB0aGUgZGlyZWN0aXZlIHRvIHZpc2l0CiAgICAgICAgICogQHBhcmFtIHAgIGEgdmlzaXRvci1zcGVjaWZpZWQgcGFyYW1ldGVyCiAgICAgICAgICogQHJldHVybiBhIHZpc2l0b3Itc3BlY2lmaWVkIHJlc3VsdAogICAgICAgICAqLwogICAgICAgIFIgdmlzaXRSZXF1aXJlcyhSZXF1aXJlc0RpcmVjdGl2ZSBkLCBQIHApOwoKICAgICAgICAvKioKICAgICAgICAgKiBWaXNpdHMgYW4ge0Bjb2RlIGV4cG9ydHN9IGRpcmVjdGl2ZS4KICAgICAgICAgKiBAcGFyYW0gZCAgdGhlIGRpcmVjdGl2ZSB0byB2aXNpdAogICAgICAgICAqIEBwYXJhbSBwICBhIHZpc2l0b3Itc3BlY2lmaWVkIHBhcmFtZXRlcgogICAgICAgICAqIEByZXR1cm4gYSB2aXNpdG9yLXNwZWNpZmllZCByZXN1bHQKICAgICAgICAgKi8KICAgICAgICBSIHZpc2l0RXhwb3J0cyhFeHBvcnRzRGlyZWN0aXZlIGQsIFAgcCk7CgogICAgICAgIC8qKgogICAgICAgICAqIFZpc2l0cyBhbiB7QGNvZGUgb3BlbnN9IGRpcmVjdGl2ZS4KICAgICAgICAgKiBAcGFyYW0gZCAgdGhlIGRpcmVjdGl2ZSB0byB2aXNpdAogICAgICAgICAqIEBwYXJhbSBwICBhIHZpc2l0b3Itc3BlY2lmaWVkIHBhcmFtZXRlcgogICAgICAgICAqIEByZXR1cm4gYSB2aXNpdG9yLXNwZWNpZmllZCByZXN1bHQKICAgICAgICAgKi8KICAgICAgICBSIHZpc2l0T3BlbnMoT3BlbnNEaXJlY3RpdmUgZCwgUCBwKTsKCiAgICAgICAgLyoqCiAgICAgICAgICogVmlzaXRzIGEge0Bjb2RlIHVzZXN9IGRpcmVjdGl2ZS4KICAgICAgICAgKiBAcGFyYW0gZCAgdGhlIGRpcmVjdGl2ZSB0byB2aXNpdAogICAgICAgICAqIEBwYXJhbSBwICBhIHZpc2l0b3Itc3BlY2lmaWVkIHBhcmFtZXRlcgogICAgICAgICAqIEByZXR1cm4gYSB2aXNpdG9yLXNwZWNpZmllZCByZXN1bHQKICAgICAgICAgKi8KICAgICAgICBSIHZpc2l0VXNlcyhVc2VzRGlyZWN0aXZlIGQsIFAgcCk7CgogICAgICAgIC8qKgogICAgICAgICAqIFZpc2l0cyBhIHtAY29kZSBwcm92aWRlc30gZGlyZWN0aXZlLgogICAgICAgICAqIEBwYXJhbSBkICB0aGUgZGlyZWN0aXZlIHRvIHZpc2l0CiAgICAgICAgICogQHBhcmFtIHAgIGEgdmlzaXRvci1zcGVjaWZpZWQgcGFyYW1ldGVyCiAgICAgICAgICogQHJldHVybiBhIHZpc2l0b3Itc3BlY2lmaWVkIHJlc3VsdAogICAgICAgICAqLwogICAgICAgIFIgdmlzaXRQcm92aWRlcyhQcm92aWRlc0RpcmVjdGl2ZSBkLCBQIHApOwoKICAgICAgICAvKioKICAgICAgICAgKiBWaXNpdHMgYW4gdW5rbm93biBkaXJlY3RpdmUuCiAgICAgICAgICogVGhpcyBjYW4gb2NjdXIgaWYgdGhlIGxhbmd1YWdlIGV2b2x2ZXMgYW5kIG5ldyBraW5kcyBvZiBkaXJlY3RpdmUgYXJlIGFkZGVkLgogICAgICAgICAqIEBwYXJhbSBkICB0aGUgZGlyZWN0aXZlIHRvIHZpc2l0CiAgICAgICAgICogQHBhcmFtIHAgIGEgdmlzaXRvci1zcGVjaWZpZWQgcGFyYW1ldGVyCiAgICAgICAgICogQHJldHVybiBhIHZpc2l0b3Itc3BlY2lmaWVkIHJlc3VsdAogICAgICAgICAqIEB0aHJvd3MgVW5rbm93bkRpcmVjdGl2ZUV4Y2VwdGlvbiBhIHZpc2l0b3IgaW1wbGVtZW50YXRpb24gbWF5IG9wdGlvbmFsbHkgdGhyb3cgdGhpcyBleGNlcHRpb24KICAgICAgICAgKiBAaW1wbFNwZWMgVGhpcyBpbXBsZW1lbnRhdGlvbiB0aHJvd3Mge0Bjb2RlIG5ldyBVbmtub3duRGlyZWN0aXZlRXhjZXB0aW9uKGQsIHApfS4KICAgICAgICAgKi8KICAgICAgICBkZWZhdWx0IFIgdmlzaXRVbmtub3duKERpcmVjdGl2ZSBkLCBQIHApIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFVua25vd25EaXJlY3RpdmVFeGNlcHRpb24oZCwgcCk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQSBkZXBlbmRlbmN5IG9mIGEgbW9kdWxlLgogICAgICogQHNpbmNlIDkKICAgICAqIEBzcGVjIEpQTVMKICAgICAqLwogICAgaW50ZXJmYWNlIFJlcXVpcmVzRGlyZWN0aXZlIGV4dGVuZHMgRGlyZWN0aXZlIHsKICAgICAgICAvKioKICAgICAgICAgKiBSZXR1cm5zIHdoZXRoZXIgb3Igbm90IHRoaXMgaXMgYSBzdGF0aWMgZGVwZW5kZW5jeS4KICAgICAgICAgKiBAcmV0dXJuIHdoZXRoZXIgb3Igbm90IHRoaXMgaXMgYSBzdGF0aWMgZGVwZW5kZW5jeQogICAgICAgICAqLwogICAgICAgIGJvb2xlYW4gaXNTdGF0aWMoKTsKCiAgICAgICAgLyoqCiAgICAgICAgICogUmV0dXJucyB3aGV0aGVyIG9yIG5vdCB0aGlzIGlzIGEgdHJhbnNpdGl2ZSBkZXBlbmRlbmN5LgogICAgICAgICAqIEByZXR1cm4gd2hldGhlciBvciBub3QgdGhpcyBpcyBhIHRyYW5zaXRpdmUgZGVwZW5kZW5jeQogICAgICAgICAqLwogICAgICAgIGJvb2xlYW4gaXNUcmFuc2l0aXZlKCk7CgogICAgICAgIC8qKgogICAgICAgICAqIFJldHVybnMgdGhlIG1vZHVsZSB0aGF0IGlzIHJlcXVpcmVkCiAgICAgICAgICogQHJldHVybiB0aGUgbW9kdWxlIHRoYXQgaXMgcmVxdWlyZWQKICAgICAgICAgKi8KICAgICAgICBNb2R1bGVFbGVtZW50IGdldERlcGVuZGVuY3koKTsKICAgIH0KCiAgICAvKioKICAgICAqIEFuIGV4cG9ydGVkIHBhY2thZ2Ugb2YgYSBtb2R1bGUuCiAgICAgKiBAc2luY2UgOQogICAgICogQHNwZWMgSlBNUwogICAgICovCiAgICBpbnRlcmZhY2UgRXhwb3J0c0RpcmVjdGl2ZSBleHRlbmRzIERpcmVjdGl2ZSB7CgogICAgICAgIC8qKgogICAgICAgICAqIFJldHVybnMgdGhlIHBhY2thZ2UgYmVpbmcgZXhwb3J0ZWQuCiAgICAgICAgICogQHJldHVybiB0aGUgcGFja2FnZSBiZWluZyBleHBvcnRlZAogICAgICAgICAqLwogICAgICAgIFBhY2thZ2VFbGVtZW50IGdldFBhY2thZ2UoKTsKCiAgICAgICAgLyoqCiAgICAgICAgICogUmV0dXJucyB0aGUgc3BlY2lmaWMgbW9kdWxlcyB0byB3aGljaCB0aGUgcGFja2FnZSBpcyBiZWluZyBleHBvcnRlZCwKICAgICAgICAgKiBvciBudWxsLCBpZiB0aGUgcGFja2FnZSBpcyBleHBvcnRlZCB0byBhbGwgbW9kdWxlcyB3aGljaAogICAgICAgICAqIGhhdmUgcmVhZGFiaWxpdHkgdG8gdGhpcyBtb2R1bGUuCiAgICAgICAgICogQHJldHVybiB0aGUgc3BlY2lmaWMgbW9kdWxlcyB0byB3aGljaCB0aGUgcGFja2FnZSBpcyBiZWluZyBleHBvcnRlZAogICAgICAgICAqLwogICAgICAgIExpc3Q8PyBleHRlbmRzIE1vZHVsZUVsZW1lbnQ+IGdldFRhcmdldE1vZHVsZXMoKTsKICAgIH0KCiAgICAvKioKICAgICAqIEFuIG9wZW5lZCBwYWNrYWdlIG9mIGEgbW9kdWxlLgogICAgICogQHNpbmNlIDkKICAgICAqIEBzcGVjIEpQTVMKICAgICAqLwogICAgaW50ZXJmYWNlIE9wZW5zRGlyZWN0aXZlIGV4dGVuZHMgRGlyZWN0aXZlIHsKCiAgICAgICAgLyoqCiAgICAgICAgICogUmV0dXJucyB0aGUgcGFja2FnZSBiZWluZyBvcGVuZWQuCiAgICAgICAgICogQHJldHVybiB0aGUgcGFja2FnZSBiZWluZyBvcGVuZWQKICAgICAgICAgKi8KICAgICAgICBQYWNrYWdlRWxlbWVudCBnZXRQYWNrYWdlKCk7CgogICAgICAgIC8qKgogICAgICAgICAqIFJldHVybnMgdGhlIHNwZWNpZmljIG1vZHVsZXMgdG8gd2hpY2ggdGhlIHBhY2thZ2UgaXMgYmVpbmcgb3BlbgogICAgICAgICAqIG9yIG51bGwsIGlmIHRoZSBwYWNrYWdlIGlzIG9wZW4gYWxsIG1vZHVsZXMgd2hpY2gKICAgICAgICAgKiBoYXZlIHJlYWRhYmlsaXR5IHRvIHRoaXMgbW9kdWxlLgogICAgICAgICAqIEByZXR1cm4gdGhlIHNwZWNpZmljIG1vZHVsZXMgdG8gd2hpY2ggdGhlIHBhY2thZ2UgaXMgYmVpbmcgb3BlbmVkCiAgICAgICAgICovCiAgICAgICAgTGlzdDw/IGV4dGVuZHMgTW9kdWxlRWxlbWVudD4gZ2V0VGFyZ2V0TW9kdWxlcygpOwogICAgfQoKICAgIC8qKgogICAgICogQW4gaW1wbGVtZW50YXRpb24gb2YgYSBzZXJ2aWNlIHByb3ZpZGVkIGJ5IGEgbW9kdWxlLgogICAgICogQHNpbmNlIDkKICAgICAqIEBzcGVjIEpQTVMKICAgICAqLwogICAgaW50ZXJmYWNlIFByb3ZpZGVzRGlyZWN0aXZlIGV4dGVuZHMgRGlyZWN0aXZlIHsKICAgICAgICAvKioKICAgICAgICAgKiBSZXR1cm5zIHRoZSBzZXJ2aWNlIGJlaW5nIHByb3ZpZGVkLgogICAgICAgICAqIEByZXR1cm4gdGhlIHNlcnZpY2UgYmVpbmcgcHJvdmlkZWQKICAgICAgICAgKi8KICAgICAgICBUeXBlRWxlbWVudCBnZXRTZXJ2aWNlKCk7CgogICAgICAgIC8qKgogICAgICAgICAqIFJldHVybnMgdGhlIGltcGxlbWVudGF0aW9ucyBvZiB0aGUgc2VydmljZSBiZWluZyBwcm92aWRlZC4KICAgICAgICAgKiBAcmV0dXJuIHRoZSBpbXBsZW1lbnRhdGlvbnMgb2YgdGhlIHNlcnZpY2UgYmVpbmcgcHJvdmlkZWQKICAgICAgICAgKi8KICAgICAgICBMaXN0PD8gZXh0ZW5kcyBUeXBlRWxlbWVudD4gZ2V0SW1wbGVtZW50YXRpb25zKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBBIHJlZmVyZW5jZSB0byBhIHNlcnZpY2UgdXNlZCBieSBhIG1vZHVsZS4KICAgICAqIEBzaW5jZSA5CiAgICAgKiBAc3BlYyBKUE1TCiAgICAgKi8KICAgIGludGVyZmFjZSBVc2VzRGlyZWN0aXZlIGV4dGVuZHMgRGlyZWN0aXZlIHsKICAgICAgICAvKioKICAgICAgICAgKiBSZXR1cm5zIHRoZSBzZXJ2aWNlIHRoYXQgaXMgdXNlZC4KICAgICAgICAgKiBAcmV0dXJuIHRoZSBzZXJ2aWNlIHRoYXQgaXMgdXNlZAogICAgICAgICAqLwogICAgICAgIFR5cGVFbGVtZW50IGdldFNlcnZpY2UoKTsKICAgIH0KfQpQSwMECgAACAAABjupSjifdDgoDAAAKAwAADUAAABqYXZheC9sYW5nL21vZGVsL2VsZW1lbnQvVW5rbm93bkVsZW1lbnRFeGNlcHRpb24uamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAxNywgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQ7CgppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5Vbmtub3duRW50aXR5RXhjZXB0aW9uOwoKLyoqCiAqIEluZGljYXRlcyB0aGF0IGFuIHVua25vd24ga2luZCBvZiBlbGVtZW50IHdhcyBlbmNvdW50ZXJlZC4gIFRoaXMKICogY2FuIG9jY3VyIGlmIHRoZSBsYW5ndWFnZSBldm9sdmVzIGFuZCBuZXcga2luZHMgb2YgZWxlbWVudHMgYXJlCiAqIGFkZGVkIHRvIHRoZSB7QGNvZGUgRWxlbWVudH0gaGllcmFyY2h5LiAgTWF5IGJlIHRocm93biBieSBhbgogKiB7QGxpbmtwbGFpbiBFbGVtZW50VmlzaXRvciBlbGVtZW50IHZpc2l0b3J9IHRvIGluZGljYXRlIHRoYXQgdGhlCiAqIHZpc2l0b3Igd2FzIGNyZWF0ZWQgZm9yIGEgcHJpb3IgdmVyc2lvbiBvZiB0aGUgbGFuZ3VhZ2UuCiAqCiAqIEBhdXRob3IgSm9zZXBoIEQuIERhcmN5CiAqIEBhdXRob3IgU2NvdHQgU2VsaWdtYW4KICogQGF1dGhvciBQZXRlciB2b24gZGVyIEFoJmVhY3V0ZTsKICogQHNlZSBFbGVtZW50VmlzaXRvciN2aXNpdFVua25vd24KICogQHNpbmNlIDEuNgogKi8KcHVibGljIGNsYXNzIFVua25vd25FbGVtZW50RXhjZXB0aW9uIGV4dGVuZHMgVW5rbm93bkVudGl0eUV4Y2VwdGlvbiB7CgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMjY5TDsKCiAgICBwcml2YXRlIHRyYW5zaWVudCBFbGVtZW50IGVsZW1lbnQ7CiAgICBwcml2YXRlIHRyYW5zaWVudCBPYmplY3QgcGFyYW1ldGVyOwoKICAgIC8qKgogICAgICogQ3JlYXRlcyBhIG5ldyB7QGNvZGUgVW5rbm93bkVsZW1lbnRFeGNlcHRpb259LiAgVGhlIHtAY29kZSBwfQogICAgICogcGFyYW1ldGVyIG1heSBiZSB1c2VkIHRvIHBhc3MgaW4gYW4gYWRkaXRpb25hbCBhcmd1bWVudCB3aXRoCiAgICAgKiBpbmZvcm1hdGlvbiBhYm91dCB0aGUgY29udGV4dCBpbiB3aGljaCB0aGUgdW5rbm93biBlbGVtZW50IHdhcwogICAgICogZW5jb3VudGVyZWQ7IGZvciBleGFtcGxlLCB0aGUgdmlzaXQgbWV0aG9kcyBvZiB7QGxpbmsKICAgICAqIEVsZW1lbnRWaXNpdG9yfSBtYXkgcGFzcyBpbiB0aGVpciBhZGRpdGlvbmFsIHBhcmFtZXRlci4KICAgICAqCiAgICAgKiBAcGFyYW0gZSB0aGUgdW5rbm93biBlbGVtZW50LCBtYXkgYmUge0Bjb2RlIG51bGx9CiAgICAgKiBAcGFyYW0gcCBhbiBhZGRpdGlvbmFsIHBhcmFtZXRlciwgbWF5IGJlIHtAY29kZSBudWxsfQogICAgICovCiAgICBwdWJsaWMgVW5rbm93bkVsZW1lbnRFeGNlcHRpb24oRWxlbWVudCBlLCBPYmplY3QgcCkgewogICAgICAgIHN1cGVyKCJVbmtub3duIGVsZW1lbnQ6ICIgKyBlKTsKICAgICAgICBlbGVtZW50ID0gZTsKICAgICAgICB0aGlzLnBhcmFtZXRlciA9IHA7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSB1bmtub3duIGVsZW1lbnQuCiAgICAgKiBUaGUgdmFsdWUgbWF5IGJlIHVuYXZhaWxhYmxlIGlmIHRoaXMgZXhjZXB0aW9uIGhhcyBiZWVuCiAgICAgKiBzZXJpYWxpemVkIGFuZCB0aGVuIHJlYWQgYmFjayBpbi4KICAgICAqCiAgICAgKiBAcmV0dXJuIHRoZSB1bmtub3duIGVsZW1lbnQsIG9yIHtAY29kZSBudWxsfSBpZiB1bmF2YWlsYWJsZQogICAgICovCiAgICBwdWJsaWMgRWxlbWVudCBnZXRVbmtub3duRWxlbWVudCgpIHsKICAgICAgICByZXR1cm4gZWxlbWVudDsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGFkZGl0aW9uYWwgYXJndW1lbnQuCiAgICAgKgogICAgICogQHJldHVybiB0aGUgYWRkaXRpb25hbCBhcmd1bWVudCwgb3Ige0Bjb2RlIG51bGx9IGlmIHVuYXZhaWxhYmxlCiAgICAgKi8KICAgIHB1YmxpYyBPYmplY3QgZ2V0QXJndW1lbnQoKSB7CiAgICAgICAgcmV0dXJuIHBhcmFtZXRlcjsKICAgIH0KfQpQSwMECgAACAAABjupSgeQKokbDgAAGw4AACwAAABqYXZheC9sYW5nL21vZGVsL2VsZW1lbnQvUGFja2FnZUVsZW1lbnQuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAxNywgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQ7CgppbXBvcnQgamF2YS51dGlsLkxpc3Q7CgovKioKICogUmVwcmVzZW50cyBhIHBhY2thZ2UgcHJvZ3JhbSBlbGVtZW50LiAgUHJvdmlkZXMgYWNjZXNzIHRvIGluZm9ybWF0aW9uCiAqIGFib3V0IHRoZSBwYWNrYWdlIGFuZCBpdHMgbWVtYmVycy4KICoKICogQGF1dGhvciBKb3NlcGggRC4gRGFyY3kKICogQGF1dGhvciBTY290dCBTZWxpZ21hbgogKiBAYXV0aG9yIFBldGVyIHZvbiBkZXIgQWgmZWFjdXRlOwogKiBAc2VlIGphdmF4LmxhbmcubW9kZWwudXRpbC5FbGVtZW50cyNnZXRQYWNrYWdlT2YKICogQHNpbmNlIDEuNgogKi8KcHVibGljIGludGVyZmFjZSBQYWNrYWdlRWxlbWVudCBleHRlbmRzIEVsZW1lbnQsIFF1YWxpZmllZE5hbWVhYmxlIHsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGZ1bGx5IHF1YWxpZmllZCBuYW1lIG9mIHRoaXMgcGFja2FnZS4KICAgICAqIFRoaXMgaXMgYWxzbyBrbm93biBhcyB0aGUgcGFja2FnZSdzIDxpPmNhbm9uaWNhbDwvaT4gbmFtZS4KICAgICAqIEZvciBhbiB7QGxpbmtwbGFpbiAjaXNVbm5hbWVkKCkgdW5uYW1lZCBwYWNrYWdlfSwgYW4gZW1wdHkgbmFtZSBpcyByZXR1cm5lZC4KICAgICAqCiAgICAgKiBAcmV0dXJuIHRoZSBmdWxseSBxdWFsaWZpZWQgbmFtZSBvZiB0aGlzIHBhY2thZ2UsIG9yIGFuCiAgICAgKiBlbXB0eSBuYW1lIGlmIHRoaXMgaXMgYW4gdW5uYW1lZCBwYWNrYWdlCiAgICAgKiBAamxzIDYuNyBGdWxseSBRdWFsaWZpZWQgTmFtZXMgYW5kIENhbm9uaWNhbCBOYW1lcwogICAgICovCiAgICBOYW1lIGdldFF1YWxpZmllZE5hbWUoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHNpbXBsZSBuYW1lIG9mIHRoaXMgcGFja2FnZS4gIEZvciBhbiB7QGxpbmtwbGFpbgogICAgICogI2lzVW5uYW1lZCgpIHVubmFtZWQgcGFja2FnZX0sIGFuIGVtcHR5IG5hbWUgaXMgcmV0dXJuZWQuCiAgICAgKgogICAgICogQHJldHVybiB0aGUgc2ltcGxlIG5hbWUgb2YgdGhpcyBwYWNrYWdlIG9yIGFuIGVtcHR5IG5hbWUgaWYKICAgICAqIHRoaXMgaXMgYW4gdW5uYW1lZCBwYWNrYWdlCiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgTmFtZSBnZXRTaW1wbGVOYW1lKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSB7QGxpbmtwbGFpbiBOZXN0aW5nS2luZCNUT1BfTEVWRUwgdG9wLWxldmVsfQogICAgICogY2xhc3NlcyBhbmQgaW50ZXJmYWNlcyB3aXRoaW4gdGhpcyBwYWNrYWdlLiAgTm90ZSB0aGF0CiAgICAgKiBzdWJwYWNrYWdlcyBhcmUgPGVtPm5vdDwvZW0+IGNvbnNpZGVyZWQgdG8gYmUgZW5jbG9zZWQgYnkgYQogICAgICogcGFja2FnZS4KICAgICAqCiAgICAgKiBAcmV0dXJuIHRoZSB0b3AtbGV2ZWwgY2xhc3NlcyBhbmQgaW50ZXJmYWNlcyB3aXRoaW4gdGhpcwogICAgICogcGFja2FnZQogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIExpc3Q8PyBleHRlbmRzIEVsZW1lbnQ+IGdldEVuY2xvc2VkRWxlbWVudHMoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMge0Bjb2RlIHRydWV9IGlmIHRoaXMgaXMgYW4gdW5uYW1lZCBwYWNrYWdlIGFuZCB7QGNvZGUKICAgICAqIGZhbHNlfSBvdGhlcndpc2UuCiAgICAgKgogICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgdGhpcyBpcyBhbiB1bm5hbWVkIHBhY2thZ2UgYW5kIHtAY29kZQogICAgICogZmFsc2V9IG90aGVyd2lzZQogICAgICogQGpscyA3LjQuMiBVbm5hbWVkIFBhY2thZ2VzCiAgICAgKi8KICAgIGJvb2xlYW4gaXNVbm5hbWVkKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBlbmNsb3NpbmcgbW9kdWxlIGlmIHN1Y2ggYSBtb2R1bGUgZXhpc3RzOyBvdGhlcndpc2UKICAgICAqIHJldHVybnMge0Bjb2RlIG51bGx9LgogICAgICoKICAgICAqIE9uZSBzaXR1YXRpb24gd2hlcmUgYSBtb2R1bGUgZG9lcyBub3QgZXhpc3QgZm9yIGEgcGFja2FnZSBpcyBpZgogICAgICogdGhlIGVudmlyb25tZW50IGRvZXMgbm90IGluY2x1ZGUgbW9kdWxlcywgc3VjaCBhcyBhbiBhbm5vdGF0aW9uCiAgICAgKiBwcm9jZXNzaW5nIGVudmlyb25tZW50IGNvbmZpZ3VyZWQgZm9yIGEge0BsaW5rcGxhaW4KICAgICAqIGphdmF4LmFubm90YXRpb24ucHJvY2Vzc2luZy5Qcm9jZXNzaW5nRW52aXJvbm1lbnQjZ2V0U291cmNlVmVyc2lvbgogICAgICogc291cmNlIHZlcnNpb259IHdpdGhvdXQgbW9kdWxlcy4KICAgICAqCiAgICAgKiBAcmV0dXJuIHRoZSBlbmNsb3NpbmcgbW9kdWxlIG9yIHtAY29kZSBudWxsfSBpZiBubyBzdWNoIG1vZHVsZSBleGlzdHMKICAgICAqCiAgICAgKiBAcmV2aXNlZCA5CiAgICAgKiBAc3BlYyBKUE1TCiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgRWxlbWVudCBnZXRFbmNsb3NpbmdFbGVtZW50KCk7Cn0KUEsDBAoAAAgAAAY7qUqH/5R7YxgAAGMYAAAsAAAAamF2YXgvbGFuZy9tb2RlbC9lbGVtZW50L0VsZW1lbnRWaXNpdG9yLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMTcsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgamF2YXgubGFuZy5tb2RlbC5lbGVtZW50OwoKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwudXRpbC4qOwoKLyoqCiAqIEEgdmlzaXRvciBvZiBwcm9ncmFtIGVsZW1lbnRzLCBpbiB0aGUgc3R5bGUgb2YgdGhlIHZpc2l0b3IgZGVzaWduCiAqIHBhdHRlcm4uICBDbGFzc2VzIGltcGxlbWVudGluZyB0aGlzIGludGVyZmFjZSBhcmUgdXNlZCB0byBvcGVyYXRlCiAqIG9uIGFuIGVsZW1lbnQgd2hlbiB0aGUga2luZCBvZiBlbGVtZW50IGlzIHVua25vd24gYXQgY29tcGlsZSB0aW1lLgogKiBXaGVuIGEgdmlzaXRvciBpcyBwYXNzZWQgdG8gYW4gZWxlbWVudCdzIHtAbGluayBFbGVtZW50I2FjY2VwdAogKiBhY2NlcHR9IG1ldGhvZCwgdGhlIDxjb2RlPnZpc2l0PGk+WHl6PC9pPjwvY29kZT4gbWV0aG9kIG1vc3QgYXBwbGljYWJsZQogKiB0byB0aGF0IGVsZW1lbnQgaXMgaW52b2tlZC4KICoKICogPHA+IENsYXNzZXMgaW1wbGVtZW50aW5nIHRoaXMgaW50ZXJmYWNlIG1heSBvciBtYXkgbm90IHRocm93IGEKICoge0Bjb2RlIE51bGxQb2ludGVyRXhjZXB0aW9ufSBpZiB0aGUgYWRkaXRpb25hbCBwYXJhbWV0ZXIge0Bjb2RlIHB9CiAqIGlzIHtAY29kZSBudWxsfTsgc2VlIGRvY3VtZW50YXRpb24gb2YgdGhlIGltcGxlbWVudGluZyBjbGFzcyBmb3IKICogZGV0YWlscy4KICoKICogPHA+IDxiPldBUk5JTkc6PC9iPiBJdCBpcyBwb3NzaWJsZSB0aGF0IG1ldGhvZHMgd2lsbCBiZSBhZGRlZCB0bwogKiB0aGlzIGludGVyZmFjZSB0byBhY2NvbW1vZGF0ZSBuZXcsIGN1cnJlbnRseSB1bmtub3duLCBsYW5ndWFnZQogKiBzdHJ1Y3R1cmVzIGFkZGVkIHRvIGZ1dHVyZSB2ZXJzaW9ucyBvZiB0aGUgSmF2YSZ0cmFkZTsgcHJvZ3JhbW1pbmcKICogbGFuZ3VhZ2UuICBUaGVyZWZvcmUsIHZpc2l0b3IgY2xhc3NlcyBkaXJlY3RseSBpbXBsZW1lbnRpbmcgdGhpcwogKiBpbnRlcmZhY2UgbWF5IGJlIHNvdXJjZSBpbmNvbXBhdGlibGUgd2l0aCBmdXR1cmUgdmVyc2lvbnMgb2YgdGhlCiAqIHBsYXRmb3JtLiAgVG8gYXZvaWQgdGhpcyBzb3VyY2UgaW5jb21wYXRpYmlsaXR5LCB2aXNpdG9yCiAqIGltcGxlbWVudGF0aW9ucyBhcmUgZW5jb3VyYWdlZCB0byBpbnN0ZWFkIGV4dGVuZCB0aGUgYXBwcm9wcmlhdGUKICogYWJzdHJhY3QgdmlzaXRvciBjbGFzcyB0aGF0IGltcGxlbWVudHMgdGhpcyBpbnRlcmZhY2UuICBIb3dldmVyLCBhbgogKiBBUEkgc2hvdWxkIGdlbmVyYWxseSB1c2UgdGhpcyB2aXNpdG9yIGludGVyZmFjZSBhcyB0aGUgdHlwZSBmb3IKICogcGFyYW1ldGVycywgcmV0dXJuIHR5cGUsIGV0Yy4gcmF0aGVyIHRoYW4gb25lIG9mIHRoZSBhYnN0cmFjdAogKiBjbGFzc2VzLgogKgogKiA8cD5Ob3RlIHRoYXQgbWV0aG9kcyB0byBhY2NvbW1vZGF0ZSBuZXcgbGFuZ3VhZ2UgY29uc3RydWN0cyBjb3VsZAogKiBiZSBhZGRlZCBpbiBhIHNvdXJjZSA8ZW0+Y29tcGF0aWJsZTwvZW0+IHdheSBpZiB0aGV5IHdlcmUgYWRkZWQgYXMKICogPGVtPmRlZmF1bHQgbWV0aG9kczwvZW0+LiAgSG93ZXZlciwgZGVmYXVsdCBtZXRob2RzIGFyZSBvbmx5CiAqIGF2YWlsYWJsZSBvbiBKYXZhIFNFIDggYW5kIGhpZ2hlciByZWxlYXNlcyBhbmQgdGhlIHtAY29kZQogKiBqYXZheC5sYW5nLm1vZGVsLip9IHBhY2thZ2VzIGJ1bmRsZWQgaW4gSmF2YSBTRSA4IHdlcmUgcmVxdWlyZWQgdG8KICogYWxzbyBiZSBydW5uYWJsZSBvbiBKYXZhIFNFIDcuICBUaGVyZWZvcmUsIGRlZmF1bHQgbWV0aG9kcwogKiB3ZXJlIDxlbT5ub3Q8L2VtPiB1c2VkIHdoZW4gZXh0ZW5kaW5nIHtAY29kZSBqYXZheC5sYW5nLm1vZGVsLip9CiAqIHRvIGNvdmVyIEphdmEgU0UgOCBsYW5ndWFnZSBmZWF0dXJlcy4gIEhvd2V2ZXIsIGRlZmF1bHQgbWV0aG9kcwogKiBhcmUgdXNlZCBpbiBzdWJzZXF1ZW50IHJldmlzaW9ucyBvZiB0aGUge0Bjb2RlIGphdmF4LmxhbmcubW9kZWwuKn0KICogcGFja2FnZXMgdGhhdCBhcmUgb25seSByZXF1aXJlZCB0byBydW4gb24gSmF2YSBTRSA4IGFuZCBoaWdoZXIKICogcGxhdGZvcm0gdmVyc2lvbnMuCiAqCiAqIEBwYXJhbSA8Uj4gdGhlIHJldHVybiB0eXBlIG9mIHRoaXMgdmlzaXRvcidzIG1ldGhvZHMuICBVc2Uge0BsaW5rCiAqICAgICAgICAgICAgVm9pZH0gZm9yIHZpc2l0b3JzIHRoYXQgZG8gbm90IG5lZWQgdG8gcmV0dXJuIHJlc3VsdHMuCiAqIEBwYXJhbSA8UD4gdGhlIHR5cGUgb2YgdGhlIGFkZGl0aW9uYWwgcGFyYW1ldGVyIHRvIHRoaXMgdmlzaXRvcidzCiAqICAgICAgICAgICAgbWV0aG9kcy4gIFVzZSB7QGNvZGUgVm9pZH0gZm9yIHZpc2l0b3JzIHRoYXQgZG8gbm90IG5lZWQgYW4KICogICAgICAgICAgICBhZGRpdGlvbmFsIHBhcmFtZXRlci4KICoKICogQGF1dGhvciBKb3NlcGggRC4gRGFyY3kKICogQGF1dGhvciBTY290dCBTZWxpZ21hbgogKiBAYXV0aG9yIFBldGVyIHZvbiBkZXIgQWgmZWFjdXRlOwogKiBAc2luY2UgMS42CiAqLwpwdWJsaWMgaW50ZXJmYWNlIEVsZW1lbnRWaXNpdG9yPFIsIFA+IHsKICAgIC8qKgogICAgICogVmlzaXRzIGFuIGVsZW1lbnQuCiAgICAgKiBAcGFyYW0gZSAgdGhlIGVsZW1lbnQgdG8gdmlzaXQKICAgICAqIEBwYXJhbSBwICBhIHZpc2l0b3Itc3BlY2lmaWVkIHBhcmFtZXRlcgogICAgICogQHJldHVybiBhIHZpc2l0b3Itc3BlY2lmaWVkIHJlc3VsdAogICAgICovCiAgICBSIHZpc2l0KEVsZW1lbnQgZSwgUCBwKTsKCiAgICAvKioKICAgICAqIEEgY29udmVuaWVuY2UgbWV0aG9kIGVxdWl2YWxlbnQgdG8ge0Bjb2RlIHZpc2l0KGUsIG51bGwpfS4KICAgICAqCiAgICAgKiBAaW1wbFNwZWMgVGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gaXMge0Bjb2RlIHZpc2l0KGUsIG51bGwpfS4KICAgICAqCiAgICAgKiBAcGFyYW0gZSAgdGhlIGVsZW1lbnQgdG8gdmlzaXQKICAgICAqIEByZXR1cm4gYSB2aXNpdG9yLXNwZWNpZmllZCByZXN1bHQKICAgICAqLwogICAgZGVmYXVsdCBSIHZpc2l0KEVsZW1lbnQgZSkgewogICAgICAgIHJldHVybiB2aXNpdChlLCBudWxsKTsKICAgIH0KCiAgICAvKioKICAgICAqIFZpc2l0cyBhIHBhY2thZ2UgZWxlbWVudC4KICAgICAqIEBwYXJhbSBlICB0aGUgZWxlbWVudCB0byB2aXNpdAogICAgICogQHBhcmFtIHAgIGEgdmlzaXRvci1zcGVjaWZpZWQgcGFyYW1ldGVyCiAgICAgKiBAcmV0dXJuIGEgdmlzaXRvci1zcGVjaWZpZWQgcmVzdWx0CiAgICAgKi8KICAgIFIgdmlzaXRQYWNrYWdlKFBhY2thZ2VFbGVtZW50IGUsIFAgcCk7CgogICAgLyoqCiAgICAgKiBWaXNpdHMgYSB0eXBlIGVsZW1lbnQuCiAgICAgKiBAcGFyYW0gZSAgdGhlIGVsZW1lbnQgdG8gdmlzaXQKICAgICAqIEBwYXJhbSBwICBhIHZpc2l0b3Itc3BlY2lmaWVkIHBhcmFtZXRlcgogICAgICogQHJldHVybiBhIHZpc2l0b3Itc3BlY2lmaWVkIHJlc3VsdAogICAgICovCiAgICBSIHZpc2l0VHlwZShUeXBlRWxlbWVudCBlLCBQIHApOwoKICAgIC8qKgogICAgICogVmlzaXRzIGEgdmFyaWFibGUgZWxlbWVudC4KICAgICAqIEBwYXJhbSBlICB0aGUgZWxlbWVudCB0byB2aXNpdAogICAgICogQHBhcmFtIHAgIGEgdmlzaXRvci1zcGVjaWZpZWQgcGFyYW1ldGVyCiAgICAgKiBAcmV0dXJuIGEgdmlzaXRvci1zcGVjaWZpZWQgcmVzdWx0CiAgICAgKi8KICAgIFIgdmlzaXRWYXJpYWJsZShWYXJpYWJsZUVsZW1lbnQgZSwgUCBwKTsKCiAgICAvKioKICAgICAqIFZpc2l0cyBhbiBleGVjdXRhYmxlIGVsZW1lbnQuCiAgICAgKiBAcGFyYW0gZSAgdGhlIGVsZW1lbnQgdG8gdmlzaXQKICAgICAqIEBwYXJhbSBwICBhIHZpc2l0b3Itc3BlY2lmaWVkIHBhcmFtZXRlcgogICAgICogQHJldHVybiBhIHZpc2l0b3Itc3BlY2lmaWVkIHJlc3VsdAogICAgICovCiAgICBSIHZpc2l0RXhlY3V0YWJsZShFeGVjdXRhYmxlRWxlbWVudCBlLCBQIHApOwoKICAgIC8qKgogICAgICogVmlzaXRzIGEgdHlwZSBwYXJhbWV0ZXIgZWxlbWVudC4KICAgICAqIEBwYXJhbSBlICB0aGUgZWxlbWVudCB0byB2aXNpdAogICAgICogQHBhcmFtIHAgIGEgdmlzaXRvci1zcGVjaWZpZWQgcGFyYW1ldGVyCiAgICAgKiBAcmV0dXJuIGEgdmlzaXRvci1zcGVjaWZpZWQgcmVzdWx0CiAgICAgKi8KICAgIFIgdmlzaXRUeXBlUGFyYW1ldGVyKFR5cGVQYXJhbWV0ZXJFbGVtZW50IGUsIFAgcCk7CgogICAgLyoqCiAgICAgKiBWaXNpdHMgYW4gdW5rbm93biBraW5kIG9mIGVsZW1lbnQuCiAgICAgKiBUaGlzIGNhbiBvY2N1ciBpZiB0aGUgbGFuZ3VhZ2UgZXZvbHZlcyBhbmQgbmV3IGtpbmRzCiAgICAgKiBvZiBlbGVtZW50cyBhcmUgYWRkZWQgdG8gdGhlIHtAY29kZSBFbGVtZW50fSBoaWVyYXJjaHkuCiAgICAgKgogICAgICogQHBhcmFtIGUgIHRoZSBlbGVtZW50IHRvIHZpc2l0CiAgICAgKiBAcGFyYW0gcCAgYSB2aXNpdG9yLXNwZWNpZmllZCBwYXJhbWV0ZXIKICAgICAqIEByZXR1cm4gYSB2aXNpdG9yLXNwZWNpZmllZCByZXN1bHQKICAgICAqIEB0aHJvd3MgVW5rbm93bkVsZW1lbnRFeGNlcHRpb24KICAgICAqICBhIHZpc2l0b3IgaW1wbGVtZW50YXRpb24gbWF5IG9wdGlvbmFsbHkgdGhyb3cgdGhpcyBleGNlcHRpb24KICAgICAqLwogICAgUiB2aXNpdFVua25vd24oRWxlbWVudCBlLCBQIHApOwoKICAgIC8qKgogICAgICogVmlzaXRzIGEgbW9kdWxlIGVsZW1lbnQuCiAgICAgKgogICAgICogQGltcGxTcGVjIFZpc2l0cyBhIHtAY29kZSBNb2R1bGVFbGVtZW50fSBieSBjYWxsaW5nIHtAY29kZQogICAgICogdmlzaXRVbmtub3duKGUsIHApfS4KICAgICAqCiAgICAgKiBAcGFyYW0gZSAgdGhlIGVsZW1lbnQgdG8gdmlzaXQKICAgICAqIEBwYXJhbSBwICBhIHZpc2l0b3Itc3BlY2lmaWVkIHBhcmFtZXRlcgogICAgICogQHJldHVybiBhIHZpc2l0b3Itc3BlY2lmaWVkIHJlc3VsdAogICAgICogQHNpbmNlIDkKICAgICAqIEBzcGVjIEpQTVMKICAgICAqLwogICAgZGVmYXVsdCBSIHZpc2l0TW9kdWxlKE1vZHVsZUVsZW1lbnQgZSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIHZpc2l0VW5rbm93bihlLCBwKTsKICAgIH0KfQpQSwMECgAACAAA0n1NSgqoFX0YCwAAGAsAAC4AAABqYXZheC9sYW5nL21vZGVsL2VsZW1lbnQvQW5ub3RhdGlvbk1pcnJvci5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDA1LCAyMDA2LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGphdmF4LmxhbmcubW9kZWwuZWxlbWVudDsKCmltcG9ydCBqYXZhLnV0aWwuTWFwOwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC50eXBlLkRlY2xhcmVkVHlwZTsKCi8qKgogKiBSZXByZXNlbnRzIGFuIGFubm90YXRpb24uICBBbiBhbm5vdGF0aW9uIGFzc29jaWF0ZXMgYSB2YWx1ZSB3aXRoCiAqIGVhY2ggZWxlbWVudCBvZiBhbiBhbm5vdGF0aW9uIHR5cGUuCiAqCiAqIDxwPiBBbm5vdGF0aW9ucyBzaG91bGQgYmUgY29tcGFyZWQgdXNpbmcgdGhlIHtAY29kZSBlcXVhbHN9CiAqIG1ldGhvZC4gIFRoZXJlIGlzIG5vIGd1YXJhbnRlZSB0aGF0IGFueSBwYXJ0aWN1bGFyIGFubm90YXRpb24gd2lsbAogKiBhbHdheXMgYmUgcmVwcmVzZW50ZWQgYnkgdGhlIHNhbWUgb2JqZWN0LgogKgogKiBAYXV0aG9yIEpvc2VwaCBELiBEYXJjeQogKiBAYXV0aG9yIFNjb3R0IFNlbGlnbWFuCiAqIEBhdXRob3IgUGV0ZXIgdm9uIGRlciBBaCZlYWN1dGU7CiAqIEBzaW5jZSAxLjYKICovCnB1YmxpYyBpbnRlcmZhY2UgQW5ub3RhdGlvbk1pcnJvciB7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSB0eXBlIG9mIHRoaXMgYW5ub3RhdGlvbi4KICAgICAqCiAgICAgKiBAcmV0dXJuIHRoZSB0eXBlIG9mIHRoaXMgYW5ub3RhdGlvbgogICAgICovCiAgICBEZWNsYXJlZFR5cGUgZ2V0QW5ub3RhdGlvblR5cGUoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHZhbHVlcyBvZiB0aGlzIGFubm90YXRpb24ncyBlbGVtZW50cy4KICAgICAqIFRoaXMgaXMgcmV0dXJuZWQgaW4gdGhlIGZvcm0gb2YgYSBtYXAgdGhhdCBhc3NvY2lhdGVzIGVsZW1lbnRzCiAgICAgKiB3aXRoIHRoZWlyIGNvcnJlc3BvbmRpbmcgdmFsdWVzLgogICAgICogT25seSB0aG9zZSBlbGVtZW50cyB3aXRoIHZhbHVlcyBleHBsaWNpdGx5IHByZXNlbnQgaW4gdGhlCiAgICAgKiBhbm5vdGF0aW9uIGFyZSBpbmNsdWRlZCwgbm90IHRob3NlIHRoYXQgYXJlIGltcGxpY2l0bHkgYXNzdW1pbmcKICAgICAqIHRoZWlyIGRlZmF1bHQgdmFsdWVzLgogICAgICogVGhlIG9yZGVyIG9mIHRoZSBtYXAgbWF0Y2hlcyB0aGUgb3JkZXIgaW4gd2hpY2ggdGhlCiAgICAgKiB2YWx1ZXMgYXBwZWFyIGluIHRoZSBhbm5vdGF0aW9uJ3Mgc291cmNlLgogICAgICoKICAgICAqIDxwPk5vdGUgdGhhdCBhbiBhbm5vdGF0aW9uIG1pcnJvciBvZiBhIG1hcmtlciBhbm5vdGF0aW9uIHR5cGUKICAgICAqIHdpbGwgYnkgZGVmaW5pdGlvbiBoYXZlIGFuIGVtcHR5IG1hcC4KICAgICAqCiAgICAgKiA8cD5UbyBmaWxsIGluIGRlZmF1bHQgdmFsdWVzLCB1c2Uge0BsaW5rCiAgICAgKiBqYXZheC5sYW5nLm1vZGVsLnV0aWwuRWxlbWVudHMjZ2V0RWxlbWVudFZhbHVlc1dpdGhEZWZhdWx0cwogICAgICogZ2V0RWxlbWVudFZhbHVlc1dpdGhEZWZhdWx0c30uCiAgICAgKgogICAgICogQHJldHVybiB0aGUgdmFsdWVzIG9mIHRoaXMgYW5ub3RhdGlvbidzIGVsZW1lbnRzLAogICAgICogICAgICAgICAgb3IgYW4gZW1wdHkgbWFwIGlmIHRoZXJlIGFyZSBub25lCiAgICAgKi8KICAgIE1hcDw/IGV4dGVuZHMgRXhlY3V0YWJsZUVsZW1lbnQsID8gZXh0ZW5kcyBBbm5vdGF0aW9uVmFsdWU+IGdldEVsZW1lbnRWYWx1ZXMoKTsKfQpQSwMECgAACAAA0n1NSvSi8/9NDQAATQ0AAC0AAABqYXZheC9sYW5nL21vZGVsL2VsZW1lbnQvVmFyaWFibGVFbGVtZW50LmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMTMsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgamF2YXgubGFuZy5tb2RlbC5lbGVtZW50OwoKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwudXRpbC5FbGVtZW50czsKCi8qKgogKiBSZXByZXNlbnRzIGEgZmllbGQsIHtAY29kZSBlbnVtfSBjb25zdGFudCwgbWV0aG9kIG9yIGNvbnN0cnVjdG9yCiAqIHBhcmFtZXRlciwgbG9jYWwgdmFyaWFibGUsIHJlc291cmNlIHZhcmlhYmxlLCBvciBleGNlcHRpb24KICogcGFyYW1ldGVyLgogKgogKiBAYXV0aG9yIEpvc2VwaCBELiBEYXJjeQogKiBAYXV0aG9yIFNjb3R0IFNlbGlnbWFuCiAqIEBhdXRob3IgUGV0ZXIgdm9uIGRlciBBaCZlYWN1dGU7CiAqIEBzaW5jZSAxLjYKICovCnB1YmxpYyBpbnRlcmZhY2UgVmFyaWFibGVFbGVtZW50IGV4dGVuZHMgRWxlbWVudCB7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiB0aGlzIHZhcmlhYmxlIGlmIHRoaXMgaXMgYSB7QGNvZGUgZmluYWx9CiAgICAgKiBmaWVsZCBpbml0aWFsaXplZCB0byBhIGNvbXBpbGUtdGltZSBjb25zdGFudC4gIFJldHVybnMge0Bjb2RlCiAgICAgKiBudWxsfSBvdGhlcndpc2UuICBUaGUgdmFsdWUgd2lsbCBiZSBvZiBhIHByaW1pdGl2ZSB0eXBlIG9yIGEKICAgICAqIHtAY29kZSBTdHJpbmd9LiAgSWYgdGhlIHZhbHVlIGlzIG9mIGEgcHJpbWl0aXZlIHR5cGUsIGl0IGlzCiAgICAgKiB3cmFwcGVkIGluIHRoZSBhcHByb3ByaWF0ZSB3cmFwcGVyIGNsYXNzIChzdWNoIGFzIHtAbGluawogICAgICogSW50ZWdlcn0pLgogICAgICoKICAgICAqIDxwPk5vdGUgdGhhdCBub3QgYWxsIHtAY29kZSBmaW5hbH0gZmllbGRzIHdpbGwgaGF2ZQogICAgICogY29uc3RhbnQgdmFsdWVzLiAgSW4gcGFydGljdWxhciwge0Bjb2RlIGVudW19IGNvbnN0YW50cyBhcmUKICAgICAqIDxlbT5ub3Q8L2VtPiBjb25zaWRlcmVkIHRvIGJlIGNvbXBpbGUtdGltZSBjb25zdGFudHMuICBUbyBoYXZlIGEKICAgICAqIGNvbnN0YW50IHZhbHVlLCBhIGZpZWxkJ3MgdHlwZSBtdXN0IGJlIGVpdGhlciBhIHByaW1pdGl2ZSB0eXBlCiAgICAgKiBvciB7QGNvZGUgU3RyaW5nfS4KICAgICAqCiAgICAgKiBAcmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGlzIHZhcmlhYmxlIGlmIHRoaXMgaXMgYSB7QGNvZGUgZmluYWx9CiAgICAgKiBmaWVsZCBpbml0aWFsaXplZCB0byBhIGNvbXBpbGUtdGltZSBjb25zdGFudCwgb3Ige0Bjb2RlIG51bGx9CiAgICAgKiBvdGhlcndpc2UKICAgICAqCiAgICAgKiBAc2VlIEVsZW1lbnRzI2dldENvbnN0YW50RXhwcmVzc2lvbihPYmplY3QpCiAgICAgKiBAamxzIDE1LjI4IENvbnN0YW50IEV4cHJlc3Npb24KICAgICAqIEBqbHMgNC4xMi40IGZpbmFsIFZhcmlhYmxlcwogICAgICovCiAgICBPYmplY3QgZ2V0Q29uc3RhbnRWYWx1ZSgpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgc2ltcGxlIG5hbWUgb2YgdGhpcyB2YXJpYWJsZSBlbGVtZW50LgogICAgICoKICAgICAqIDxwPkZvciBtZXRob2QgYW5kIGNvbnN0cnVjdG9yIHBhcmFtZXRlcnMsIHRoZSBuYW1lIG9mIGVhY2gKICAgICAqIHBhcmFtZXRlciBtdXN0IGJlIGRpc3RpbmN0IGZyb20gdGhlIG5hbWVzIG9mIGFsbCBvdGhlcgogICAgICogcGFyYW1ldGVycyBvZiB0aGUgc2FtZSBleGVjdXRhYmxlLiAgSWYgdGhlIG9yaWdpbmFsIHNvdXJjZQogICAgICogbmFtZXMgYXJlIG5vdCBhdmFpbGFibGUsIGFuIGltcGxlbWVudGF0aW9uIG1heSBzeW50aGVzaXplIG5hbWVzCiAgICAgKiBzdWJqZWN0IHRvIHRoZSBkaXN0aW5jdG5lc3MgcmVxdWlyZW1lbnQgYWJvdmUuCiAgICAgKgogICAgICogQHJldHVybiB0aGUgc2ltcGxlIG5hbWUgb2YgdGhpcyB2YXJpYWJsZSBlbGVtZW50CiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgTmFtZSBnZXRTaW1wbGVOYW1lKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBlbmNsb3NpbmcgZWxlbWVudCBvZiB0aGlzIHZhcmlhYmxlLgogICAgICoKICAgICAqIFRoZSBlbmNsb3NpbmcgZWxlbWVudCBvZiBhIG1ldGhvZCBvciBjb25zdHJ1Y3RvciBwYXJhbWV0ZXIgaXMKICAgICAqIHRoZSBleGVjdXRhYmxlIGRlY2xhcmluZyB0aGUgcGFyYW1ldGVyLgogICAgICoKICAgICAqIEByZXR1cm4gdGhlIGVuY2xvc2luZyBlbGVtZW50IG9mIHRoaXMgdmFyaWFibGUKICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBFbGVtZW50IGdldEVuY2xvc2luZ0VsZW1lbnQoKTsKfQpQSwMECgAACAAABjupSlA7TG8HLQAABy0AACMAAABqYXZheC9sYW5nL21vZGVsL1NvdXJjZVZlcnNpb24uamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAxNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBqYXZheC5sYW5nLm1vZGVsOwoKaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKaW1wb3J0IGphdmEudXRpbC5TZXQ7CmltcG9ydCBqYXZhLnV0aWwuSGFzaFNldDsKCi8qKgogKiBTb3VyY2UgdmVyc2lvbnMgb2YgdGhlIEphdmEmdHJhZGU7IHByb2dyYW1taW5nIGxhbmd1YWdlLgogKgogKiBTZWUgdGhlIGFwcHJvcHJpYXRlIGVkaXRpb24gb2YKICogPGNpdGU+VGhlIEphdmEmdHJhZGU7IExhbmd1YWdlIFNwZWNpZmljYXRpb248L2NpdGU+CiAqIGZvciBpbmZvcm1hdGlvbiBhYm91dCBhIHBhcnRpY3VsYXIgc291cmNlIHZlcnNpb24uCiAqCiAqIDxwPk5vdGUgdGhhdCBhZGRpdGlvbmFsIHNvdXJjZSB2ZXJzaW9uIGNvbnN0YW50cyB3aWxsIGJlIGFkZGVkIHRvCiAqIG1vZGVsIGZ1dHVyZSByZWxlYXNlcyBvZiB0aGUgbGFuZ3VhZ2UuCiAqCiAqIEBhdXRob3IgSm9zZXBoIEQuIERhcmN5CiAqIEBhdXRob3IgU2NvdHQgU2VsaWdtYW4KICogQGF1dGhvciBQZXRlciB2b24gZGVyIEFoJmVhY3V0ZTsKICogQHNpbmNlIDEuNgogKi8KcHVibGljIGVudW0gU291cmNlVmVyc2lvbiB7CiAgICAvKgogICAgICogU3VtbWFyeSBvZiBsYW5ndWFnZSBldm9sdXRpb24KICAgICAqIDEuMTogbmVzdGVkIGNsYXNzZXMKICAgICAqIDEuMjogc3RyaWN0ZnAKICAgICAqIDEuMzogbm8gY2hhbmdlcwogICAgICogMS40OiBhc3NlcnQKICAgICAqIDEuNTogYW5ub3RhdGlvbnMsIGdlbmVyaWNzLCBhdXRvYm94aW5nLCB2YXItYXJncy4uLgogICAgICogMS42OiBubyBjaGFuZ2VzCiAgICAgKiAxLjc6IGRpYW1vbmQgc3ludGF4LCB0cnktd2l0aC1yZXNvdXJjZXMsIGV0Yy4KICAgICAqIDEuODogbGFtYmRhIGV4cHJlc3Npb25zIGFuZCBkZWZhdWx0IG1ldGhvZHMKICAgICAqICAgOTogbW9kdWxlcywgc21hbGwgY2xlYW51cHMgdG8gMS43IGFuZCAxLjggY2hhbmdlcwogICAgICovCgogICAgLyoqCiAgICAgKiBUaGUgb3JpZ2luYWwgdmVyc2lvbi4KICAgICAqCiAgICAgKiBUaGUgbGFuZ3VhZ2UgZGVzY3JpYmVkIGluCiAgICAgKiA8Y2l0ZT5UaGUgSmF2YSZ0cmFkZTsgTGFuZ3VhZ2UgU3BlY2lmaWNhdGlvbiwgRmlyc3QgRWRpdGlvbjwvY2l0ZT4uCiAgICAgKi8KICAgIFJFTEVBU0VfMCwKCiAgICAvKioKICAgICAqIFRoZSB2ZXJzaW9uIHJlY29nbml6ZWQgYnkgdGhlIEphdmEgUGxhdGZvcm0gMS4xLgogICAgICoKICAgICAqIFRoZSBsYW5ndWFnZSBpcyB7QGNvZGUgUkVMRUFTRV8wfSBhdWdtZW50ZWQgd2l0aCBuZXN0ZWQgY2xhc3NlcyBhcyBkZXNjcmliZWQgaW4gdGhlIDEuMSB1cGRhdGUgdG8KICAgICAqIDxjaXRlPlRoZSBKYXZhJnRyYWRlOyBMYW5ndWFnZSBTcGVjaWZpY2F0aW9uLCBGaXJzdCBFZGl0aW9uPC9jaXRlPi4KICAgICAqLwogICAgUkVMRUFTRV8xLAoKICAgIC8qKgogICAgICogVGhlIHZlcnNpb24gcmVjb2duaXplZCBieSB0aGUgSmF2YSAyIFBsYXRmb3JtLCBTdGFuZGFyZCBFZGl0aW9uLAogICAgICogdiAxLjIuCiAgICAgKgogICAgICogVGhlIGxhbmd1YWdlIGRlc2NyaWJlZCBpbgogICAgICogPGNpdGU+VGhlIEphdmEmdHJhZGU7IExhbmd1YWdlIFNwZWNpZmljYXRpb24sCiAgICAgKiBTZWNvbmQgRWRpdGlvbjwvY2l0ZT4sIHdoaWNoIGluY2x1ZGVzIHRoZSB7QGNvZGUKICAgICAqIHN0cmljdGZwfSBtb2RpZmllci4KICAgICAqLwogICAgUkVMRUFTRV8yLAoKICAgIC8qKgogICAgICogVGhlIHZlcnNpb24gcmVjb2duaXplZCBieSB0aGUgSmF2YSAyIFBsYXRmb3JtLCBTdGFuZGFyZCBFZGl0aW9uLAogICAgICogdiAxLjMuCiAgICAgKgogICAgICogTm8gbWFqb3IgY2hhbmdlcyBmcm9tIHtAY29kZSBSRUxFQVNFXzJ9LgogICAgICovCiAgICBSRUxFQVNFXzMsCgogICAgLyoqCiAgICAgKiBUaGUgdmVyc2lvbiByZWNvZ25pemVkIGJ5IHRoZSBKYXZhIDIgUGxhdGZvcm0sIFN0YW5kYXJkIEVkaXRpb24sCiAgICAgKiB2IDEuNC4KICAgICAqCiAgICAgKiBBZGRlZCBhIHNpbXBsZSBhc3NlcnRpb24gZmFjaWxpdHkuCiAgICAgKi8KICAgIFJFTEVBU0VfNCwKCiAgICAvKioKICAgICAqIFRoZSB2ZXJzaW9uIHJlY29nbml6ZWQgYnkgdGhlIEphdmEgMiBQbGF0Zm9ybSwgU3RhbmRhcmQKICAgICAqIEVkaXRpb24gNS4wLgogICAgICoKICAgICAqIFRoZSBsYW5ndWFnZSBkZXNjcmliZWQgaW4KICAgICAqIDxjaXRlPlRoZSBKYXZhJnRyYWRlOyBMYW5ndWFnZSBTcGVjaWZpY2F0aW9uLAogICAgICogVGhpcmQgRWRpdGlvbjwvY2l0ZT4uICBGaXJzdCByZWxlYXNlIHRvIHN1cHBvcnQKICAgICAqIGdlbmVyaWNzLCBhbm5vdGF0aW9ucywgYXV0b2JveGluZywgdmFyLWFyZ3MsIGVuaGFuY2VkIHtAY29kZQogICAgICogZm9yfSBsb29wLCBhbmQgaGV4YWRlY2ltYWwgZmxvYXRpbmctcG9pbnQgbGl0ZXJhbHMuCiAgICAgKi8KICAgIFJFTEVBU0VfNSwKCiAgICAvKioKICAgICAqIFRoZSB2ZXJzaW9uIHJlY29nbml6ZWQgYnkgdGhlIEphdmEgUGxhdGZvcm0sIFN0YW5kYXJkIEVkaXRpb24KICAgICAqIDYuCiAgICAgKgogICAgICogTm8gbWFqb3IgY2hhbmdlcyBmcm9tIHtAY29kZSBSRUxFQVNFXzV9LgogICAgICovCiAgICBSRUxFQVNFXzYsCgogICAgLyoqCiAgICAgKiBUaGUgdmVyc2lvbiByZWNvZ25pemVkIGJ5IHRoZSBKYXZhIFBsYXRmb3JtLCBTdGFuZGFyZCBFZGl0aW9uCiAgICAgKiA3LgogICAgICoKICAgICAqIEFkZGl0aW9ucyBpbiB0aGlzIHJlbGVhc2UgaW5jbHVkZSwgZGlhbW9uZCBzeW50YXggZm9yCiAgICAgKiBjb25zdHJ1Y3RvcnMsIHtAY29kZSB0cnl9LXdpdGgtcmVzb3VyY2VzLCBzdHJpbmdzIGluIHN3aXRjaCwKICAgICAqIGJpbmFyeSBsaXRlcmFscywgYW5kIG11bHRpLWNhdGNoLgogICAgICogQHNpbmNlIDEuNwogICAgICovCiAgICBSRUxFQVNFXzcsCgogICAgLyoqCiAgICAgKiBUaGUgdmVyc2lvbiByZWNvZ25pemVkIGJ5IHRoZSBKYXZhIFBsYXRmb3JtLCBTdGFuZGFyZCBFZGl0aW9uCiAgICAgKiA4LgogICAgICoKICAgICAqIEFkZGl0aW9ucyBpbiB0aGlzIHJlbGVhc2UgaW5jbHVkZSBsYW1iZGEgZXhwcmVzc2lvbnMgYW5kIGRlZmF1bHQgbWV0aG9kcy4KICAgICAqIEBzaW5jZSAxLjgKICAgICAqLwogICAgUkVMRUFTRV84LAoKICAgIC8qKgogICAgICogVGhlIHZlcnNpb24gcmVjb2duaXplZCBieSB0aGUgSmF2YSBQbGF0Zm9ybSwgU3RhbmRhcmQgRWRpdGlvbgogICAgICogOS4KICAgICAqCiAgICAgKiBBZGRpdGlvbnMgaW4gdGhpcyByZWxlYXNlIGluY2x1ZGUgbW9kdWxlcyBhbmQgcmVtb3ZhbCBvZiBhCiAgICAgKiBzaW5nbGUgdW5kZXJzY29yZSBmcm9tIHRoZSBzZXQgb2YgbGVnYWwgaWRlbnRpZmllciBuYW1lcy4KICAgICAqCiAgICAgKiBAc2luY2UgOQogICAgICovCiAgICAgUkVMRUFTRV85OwoKICAgIC8vIE5vdGUgdGhhdCB3aGVuIGFkZGluZyBjb25zdGFudHMgZm9yIG5ld2VyIHJlbGVhc2VzLCB0aGUKICAgIC8vIGJlaGF2aW9yIG9mIGxhdGVzdCgpIGFuZCBsYXRlc3RTdXBwb3J0ZWQoKSBtdXN0IGJlIHVwZGF0ZWQgdG9vLgoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgbGF0ZXN0IHNvdXJjZSB2ZXJzaW9uIHRoYXQgY2FuIGJlIG1vZGVsZWQuCiAgICAgKgogICAgICogQHJldHVybiB0aGUgbGF0ZXN0IHNvdXJjZSB2ZXJzaW9uIHRoYXQgY2FuIGJlIG1vZGVsZWQKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBTb3VyY2VWZXJzaW9uIGxhdGVzdCgpIHsKICAgICAgICByZXR1cm4gUkVMRUFTRV85OwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFNvdXJjZVZlcnNpb24gbGF0ZXN0U3VwcG9ydGVkID0gZ2V0TGF0ZXN0U3VwcG9ydGVkKCk7CgogICAgcHJpdmF0ZSBzdGF0aWMgU291cmNlVmVyc2lvbiBnZXRMYXRlc3RTdXBwb3J0ZWQoKSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgU3RyaW5nIHNwZWNWZXJzaW9uID0gU3lzdGVtLmdldFByb3BlcnR5KCJqYXZhLnNwZWNpZmljYXRpb24udmVyc2lvbiIpOwoKICAgICAgICAgICAgc3dpdGNoIChzcGVjVmVyc2lvbikgewogICAgICAgICAgICAgICAgY2FzZSAiOSI6CiAgICAgICAgICAgICAgICBjYXNlICIxLjkiOgogICAgICAgICAgICAgICAgICAgIHJldHVybiBSRUxFQVNFXzk7CiAgICAgICAgICAgICAgICBjYXNlICIxLjgiOgogICAgICAgICAgICAgICAgICAgIHJldHVybiBSRUxFQVNFXzg7CiAgICAgICAgICAgICAgICBjYXNlICIxLjciOgogICAgICAgICAgICAgICAgICAgIHJldHVybiBSRUxFQVNFXzc7CiAgICAgICAgICAgICAgICBjYXNlICIxLjYiOgogICAgICAgICAgICAgICAgICAgIHJldHVybiBSRUxFQVNFXzY7CiAgICAgICAgICAgIH0KICAgICAgICB9IGNhdGNoIChTZWN1cml0eUV4Y2VwdGlvbiBzZSkge30KCiAgICAgICAgcmV0dXJuIFJFTEVBU0VfNTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGxhdGVzdCBzb3VyY2UgdmVyc2lvbiBmdWxseSBzdXBwb3J0ZWQgYnkgdGhlCiAgICAgKiBjdXJyZW50IGV4ZWN1dGlvbiBlbnZpcm9ubWVudC4gIHtAY29kZSBSRUxFQVNFXzV9IG9yIGxhdGVyIG11c3QKICAgICAqIGJlIHJldHVybmVkLgogICAgICoKICAgICAqIEByZXR1cm4gdGhlIGxhdGVzdCBzb3VyY2UgdmVyc2lvbiB0aGF0IGlzIGZ1bGx5IHN1cHBvcnRlZAogICAgICovCiAgICBwdWJsaWMgc3RhdGljIFNvdXJjZVZlcnNpb24gbGF0ZXN0U3VwcG9ydGVkKCkgewogICAgICAgIHJldHVybiBsYXRlc3RTdXBwb3J0ZWQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHdoZXRoZXIgb3Igbm90IHtAY29kZSBuYW1lfSBpcyBhIHN5bnRhY3RpY2FsbHkgdmFsaWQKICAgICAqIGlkZW50aWZpZXIgKHNpbXBsZSBuYW1lKSBvciBrZXl3b3JkIGluIHRoZSBsYXRlc3Qgc291cmNlCiAgICAgKiB2ZXJzaW9uLiAgVGhlIG1ldGhvZCByZXR1cm5zIHtAY29kZSB0cnVlfSBpZiB0aGUgbmFtZSBjb25zaXN0cwogICAgICogb2YgYW4gaW5pdGlhbCBjaGFyYWN0ZXIgZm9yIHdoaWNoIHtAbGluawogICAgICogQ2hhcmFjdGVyI2lzSmF2YUlkZW50aWZpZXJTdGFydChpbnQpfSByZXR1cm5zIHtAY29kZSB0cnVlfSwKICAgICAqIGZvbGxvd2VkIG9ubHkgYnkgY2hhcmFjdGVycyBmb3Igd2hpY2gge0BsaW5rCiAgICAgKiBDaGFyYWN0ZXIjaXNKYXZhSWRlbnRpZmllclBhcnQoaW50KX0gcmV0dXJucyB7QGNvZGUgdHJ1ZX0uCiAgICAgKiBUaGlzIHBhdHRlcm4gbWF0Y2hlcyByZWd1bGFyIGlkZW50aWZpZXJzLCBrZXl3b3JkcywgYW5kIHRoZQogICAgICogbGl0ZXJhbHMge0Bjb2RlICJ0cnVlIn0sIHtAY29kZSAiZmFsc2UifSwgYW5kIHtAY29kZSAibnVsbCJ9LgogICAgICogVGhlIG1ldGhvZCByZXR1cm5zIHtAY29kZSBmYWxzZX0gZm9yIGFsbCBvdGhlciBzdHJpbmdzLgogICAgICoKICAgICAqIEBwYXJhbSBuYW1lIHRoZSBzdHJpbmcgdG8gY2hlY2sKICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoaXMgc3RyaW5nIGlzIGEKICAgICAqIHN5bnRhY3RpY2FsbHkgdmFsaWQgaWRlbnRpZmllciBvciBrZXl3b3JkLCB7QGNvZGUgZmFsc2V9CiAgICAgKiBvdGhlcndpc2UuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc0lkZW50aWZpZXIoQ2hhclNlcXVlbmNlIG5hbWUpIHsKICAgICAgICBTdHJpbmcgaWQgPSBuYW1lLnRvU3RyaW5nKCk7CgogICAgICAgIGlmIChpZC5sZW5ndGgoKSA9PSAwKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgaW50IGNwID0gaWQuY29kZVBvaW50QXQoMCk7CiAgICAgICAgaWYgKCFDaGFyYWN0ZXIuaXNKYXZhSWRlbnRpZmllclN0YXJ0KGNwKSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIGZvciAoaW50IGkgPSBDaGFyYWN0ZXIuY2hhckNvdW50KGNwKTsKICAgICAgICAgICAgICAgIGkgPCBpZC5sZW5ndGgoKTsKICAgICAgICAgICAgICAgIGkgKz0gQ2hhcmFjdGVyLmNoYXJDb3VudChjcCkpIHsKICAgICAgICAgICAgY3AgPSBpZC5jb2RlUG9pbnRBdChpKTsKICAgICAgICAgICAgaWYgKCFDaGFyYWN0ZXIuaXNKYXZhSWRlbnRpZmllclBhcnQoY3ApKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHdoZXRoZXIgb3Igbm90IHtAY29kZSBuYW1lfSBpcyBhIHN5bnRhY3RpY2FsbHkgdmFsaWQKICAgICAqIHF1YWxpZmllZCBuYW1lIGluIHRoZSBsYXRlc3Qgc291cmNlIHZlcnNpb24uICBVbmxpa2Uge0BsaW5rCiAgICAgKiAjaXNJZGVudGlmaWVyIGlzSWRlbnRpZmllcn0sIHRoaXMgbWV0aG9kIHJldHVybnMge0Bjb2RlIGZhbHNlfQogICAgICogZm9yIGtleXdvcmRzLCBib29sZWFuIGxpdGVyYWxzLCBhbmQgdGhlIG51bGwgbGl0ZXJhbC4KICAgICAqCiAgICAgKiBAcGFyYW0gbmFtZSB0aGUgc3RyaW5nIHRvIGNoZWNrCiAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIHN0cmluZyBpcyBhCiAgICAgKiBzeW50YWN0aWNhbGx5IHZhbGlkIG5hbWUsIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgogICAgICogQGpscyA2LjIgTmFtZXMgYW5kIElkZW50aWZpZXJzCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc05hbWUoQ2hhclNlcXVlbmNlIG5hbWUpIHsKICAgICAgICByZXR1cm4gaXNOYW1lKG5hbWUsIGxhdGVzdCgpKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgd2hldGhlciBvciBub3Qge0Bjb2RlIG5hbWV9IGlzIGEgc3ludGFjdGljYWxseSB2YWxpZAogICAgICogcXVhbGlmaWVkIG5hbWUgaW4gdGhlIGdpdmVuIHNvdXJjZSB2ZXJzaW9uLiAgVW5saWtlIHtAbGluawogICAgICogI2lzSWRlbnRpZmllciBpc0lkZW50aWZpZXJ9LCB0aGlzIG1ldGhvZCByZXR1cm5zIHtAY29kZSBmYWxzZX0KICAgICAqIGZvciBrZXl3b3JkcywgYm9vbGVhbiBsaXRlcmFscywgYW5kIHRoZSBudWxsIGxpdGVyYWwuCiAgICAgKgogICAgICogQHBhcmFtIG5hbWUgdGhlIHN0cmluZyB0byBjaGVjawogICAgICogQHBhcmFtIHZlcnNpb24gdGhlIHZlcnNpb24gdG8gdXNlCiAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIHN0cmluZyBpcyBhCiAgICAgKiBzeW50YWN0aWNhbGx5IHZhbGlkIG5hbWUsIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgogICAgICogQGpscyA2LjIgTmFtZXMgYW5kIElkZW50aWZpZXJzCiAgICAgKiBAc2luY2UgOQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNOYW1lKENoYXJTZXF1ZW5jZSBuYW1lLCBTb3VyY2VWZXJzaW9uIHZlcnNpb24pIHsKICAgICAgICBTdHJpbmcgaWQgPSBuYW1lLnRvU3RyaW5nKCk7CgogICAgICAgIGZvcihTdHJpbmcgcyA6IGlkLnNwbGl0KCJcXC4iLCAtMSkpIHsKICAgICAgICAgICAgaWYgKCFpc0lkZW50aWZpZXIocykgfHwgaXNLZXl3b3JkKHMsIHZlcnNpb24pKQogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgd2hldGhlciBvciBub3Qge0Bjb2RlIHN9IGlzIGEga2V5d29yZCwgYm9vbGVhbiBsaXRlcmFsLAogICAgICogb3IgbnVsbCBsaXRlcmFsIGluIHRoZSBsYXRlc3Qgc291cmNlIHZlcnNpb24uCiAgICAgKgogICAgICogQHBhcmFtIHMgdGhlIHN0cmluZyB0byBjaGVjawogICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYge0Bjb2RlIHN9IGlzIGEga2V5d29yZCwgb3IgYm9vbGVhbgogICAgICogbGl0ZXJhbCwgb3IgbnVsbCBsaXRlcmFsLCB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KICAgICAqIEBqbHMgMy45IEtleXdvcmRzCiAgICAgKiBAamxzIDMuMTAuMyBCb29sZWFuIExpdGVyYWxzCiAgICAgKiBAamxzIDMuMTAuNyBUaGUgTnVsbCBMaXRlcmFsCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc0tleXdvcmQoQ2hhclNlcXVlbmNlIHMpIHsKICAgICAgICByZXR1cm4gaXNLZXl3b3JkKHMsIGxhdGVzdCgpKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgd2hldGhlciBvciBub3Qge0Bjb2RlIHN9IGlzIGEga2V5d29yZCwgYm9vbGVhbiBsaXRlcmFsLAogICAgICogb3IgbnVsbCBsaXRlcmFsIGluIHRoZSBnaXZlbiBzb3VyY2UgdmVyc2lvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gcyB0aGUgc3RyaW5nIHRvIGNoZWNrCiAgICAgKiBAcGFyYW0gdmVyc2lvbiB0aGUgdmVyc2lvbiB0byB1c2UKICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHtAY29kZSBzfSBpcyBhIGtleXdvcmQsIG9yIGJvb2xlYW4KICAgICAqIGxpdGVyYWwsIG9yIG51bGwgbGl0ZXJhbCwge0Bjb2RlIGZhbHNlfSBvdGhlcndpc2UuCiAgICAgKiBAamxzIDMuOSBLZXl3b3JkcwogICAgICogQGpscyAzLjEwLjMgQm9vbGVhbiBMaXRlcmFscwogICAgICogQGpscyAzLjEwLjcgVGhlIE51bGwgTGl0ZXJhbAogICAgICogQHNpbmNlIDkKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzS2V5d29yZChDaGFyU2VxdWVuY2UgcywgU291cmNlVmVyc2lvbiB2ZXJzaW9uKSB7CiAgICAgICAgU3RyaW5nIGlkID0gcy50b1N0cmluZygpOwogICAgICAgIHN3aXRjaChpZCkgewogICAgICAgICAgICAvLyBBIHRyaXAgdGhyb3VnaCBoaXN0b3J5CiAgICAgICAgY2FzZSAic3RyaWN0ZnAiOgogICAgICAgICAgICByZXR1cm4gdmVyc2lvbi5jb21wYXJlVG8oUkVMRUFTRV8yKSA+PSAwOwoKICAgICAgICBjYXNlICJhc3NlcnQiOgogICAgICAgICAgICByZXR1cm4gdmVyc2lvbi5jb21wYXJlVG8oUkVMRUFTRV80KSA+PSAwOwoKICAgICAgICBjYXNlICJlbnVtIjoKICAgICAgICAgICAgcmV0dXJuIHZlcnNpb24uY29tcGFyZVRvKFJFTEVBU0VfNSkgPj0gMDsKCiAgICAgICAgY2FzZSAiXyI6CiAgICAgICAgICAgIHJldHVybiB2ZXJzaW9uLmNvbXBhcmVUbyhSRUxFQVNFXzkpID49IDA7CgogICAgICAgICAgICAvLyBLZXl3b3JkcyBjb21tb24gYWNyb3NzIHZlcnNpb25zCgogICAgICAgICAgICAvLyBNb2RpZmllcnMKICAgICAgICBjYXNlICJwdWJsaWMiOiAgICBjYXNlICJwcm90ZWN0ZWQiOiBjYXNlICJwcml2YXRlIjoKICAgICAgICBjYXNlICJhYnN0cmFjdCI6ICBjYXNlICJzdGF0aWMiOiAgICBjYXNlICJmaW5hbCI6CiAgICAgICAgY2FzZSAidHJhbnNpZW50IjogY2FzZSAidm9sYXRpbGUiOiAgY2FzZSAic3luY2hyb25pemVkIjoKICAgICAgICBjYXNlICJuYXRpdmUiOgoKICAgICAgICAgICAgLy8gRGVjbGFyYXRpb25zCiAgICAgICAgY2FzZSAiY2xhc3MiOiAgICAgY2FzZSAiaW50ZXJmYWNlIjogY2FzZSAiZXh0ZW5kcyI6CiAgICAgICAgY2FzZSAicGFja2FnZSI6ICAgY2FzZSAidGhyb3dzIjogICAgY2FzZSAiaW1wbGVtZW50cyI6CgogICAgICAgICAgICAvLyBQcmltaXRpdmUgdHlwZXMgYW5kIHZvaWQKICAgICAgICBjYXNlICJib29sZWFuIjogICBjYXNlICJieXRlIjogICAgICBjYXNlICJjaGFyIjoKICAgICAgICBjYXNlICJzaG9ydCI6ICAgICBjYXNlICJpbnQiOiAgICAgICBjYXNlICJsb25nIjoKICAgICAgICBjYXNlICJmbG9hdCI6ICAgICBjYXNlICJkb3VibGUiOgogICAgICAgIGNhc2UgInZvaWQiOgoKICAgICAgICAgICAgLy8gQ29udHJvbCBmbG93CiAgICAgICAgY2FzZSAiaWYiOiAgICAgIGNhc2UgImVsc2UiOgogICAgICAgIGNhc2UgInRyeSI6ICAgICBjYXNlICJjYXRjaCI6ICAgIGNhc2UgImZpbmFsbHkiOgogICAgICAgIGNhc2UgImRvIjogICAgICBjYXNlICJ3aGlsZSI6CiAgICAgICAgY2FzZSAiZm9yIjogICAgIGNhc2UgImNvbnRpbnVlIjoKICAgICAgICBjYXNlICJzd2l0Y2giOiAgY2FzZSAiY2FzZSI6ICAgICBjYXNlICJkZWZhdWx0IjoKICAgICAgICBjYXNlICJicmVhayI6ICAgY2FzZSAidGhyb3ciOiAgICBjYXNlICJyZXR1cm4iOgoKICAgICAgICAgICAgLy8gT3RoZXIga2V5d29yZHMKICAgICAgICBjYXNlICAidGhpcyI6ICAgY2FzZSAibmV3IjogICAgICBjYXNlICJzdXBlciI6CiAgICAgICAgY2FzZSAiaW1wb3J0IjogIGNhc2UgImluc3RhbmNlb2YiOgoKICAgICAgICAgICAgLy8gRm9yYmlkZGVuIQogICAgICAgIGNhc2UgImdvdG8iOiAgICAgICAgY2FzZSAiY29uc3QiOgoKICAgICAgICAgICAgLy8gbGl0ZXJhbHMKICAgICAgICBjYXNlICJudWxsIjogICAgICAgICBjYXNlICJ0cnVlIjogICAgICAgY2FzZSAiZmFsc2UiOgogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKCiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgIH0KfQpQSwMECgAACAAABjupSgAAAAAAAAAAAAAAABYAAABqYXZheC9sYW5nL21vZGVsL3V0aWwvUEsDBAoAAAgAAAY7qUqaT7TjyA4AAMgOAAA4AAAAamF2YXgvbGFuZy9tb2RlbC91dGlsL1NpbXBsZUFubm90YXRpb25WYWx1ZVZpc2l0b3I5LmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTEsIDIwMTQsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgamF2YXgubGFuZy5tb2RlbC51dGlsOwoKaW1wb3J0IGphdmF4LmFubm90YXRpb24ucHJvY2Vzc2luZy5TdXBwb3J0ZWRTb3VyY2VWZXJzaW9uOwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5Tb3VyY2VWZXJzaW9uOwppbXBvcnQgc3RhdGljIGphdmF4LmxhbmcubW9kZWwuU291cmNlVmVyc2lvbi4qOwoKLyoqCiAqIEEgc2ltcGxlIHZpc2l0b3IgZm9yIGFubm90YXRpb24gdmFsdWVzIHdpdGggZGVmYXVsdCBiZWhhdmlvcgogKiBhcHByb3ByaWF0ZSBmb3IgdGhlIHtAbGluayBTb3VyY2VWZXJzaW9uI1JFTEVBU0VfOSBSRUxFQVNFXzl9CiAqIHNvdXJjZSB2ZXJzaW9uLiAgVmlzaXQgbWV0aG9kcyBjYWxsIHtAbGluayAjZGVmYXVsdEFjdGlvbgogKiBkZWZhdWx0QWN0aW9ufSBwYXNzaW5nIHRoZWlyIGFyZ3VtZW50cyB0byB7QGNvZGUgZGVmYXVsdEFjdGlvbn0ncwogKiBjb3JyZXNwb25kaW5nIHBhcmFtZXRlcnMuCiAqCiAqIDxwPiBNZXRob2RzIGluIHRoaXMgY2xhc3MgbWF5IGJlIG92ZXJyaWRkZW4gc3ViamVjdCB0byB0aGVpcgogKiBnZW5lcmFsIGNvbnRyYWN0LiAgTm90ZSB0aGF0IGFubm90YXRpbmcgbWV0aG9kcyBpbiBjb25jcmV0ZQogKiBzdWJjbGFzc2VzIHdpdGgge0BsaW5rIGphdmEubGFuZy5PdmVycmlkZSBAT3ZlcnJpZGV9IHdpbGwgaGVscAogKiBlbnN1cmUgdGhhdCBtZXRob2RzIGFyZSBvdmVycmlkZGVuIGFzIGludGVuZGVkLgogKgogKiA8cD4gPGI+V0FSTklORzo8L2I+IFRoZSB7QGNvZGUgQW5ub3RhdGlvblZhbHVlVmlzaXRvcn0gaW50ZXJmYWNlCiAqIGltcGxlbWVudGVkIGJ5IHRoaXMgY2xhc3MgbWF5IGhhdmUgbWV0aG9kcyBhZGRlZCB0byBpdCBpbiB0aGUKICogZnV0dXJlIHRvIGFjY29tbW9kYXRlIG5ldywgY3VycmVudGx5IHVua25vd24sIGxhbmd1YWdlIHN0cnVjdHVyZXMKICogYWRkZWQgdG8gZnV0dXJlIHZlcnNpb25zIG9mIHRoZSBKYXZhJnRyYWRlOyBwcm9ncmFtbWluZyBsYW5ndWFnZS4KICogVGhlcmVmb3JlLCBtZXRob2RzIHdob3NlIG5hbWVzIGJlZ2luIHdpdGgge0Bjb2RlICJ2aXNpdCJ9IG1heSBiZQogKiBhZGRlZCB0byB0aGlzIGNsYXNzIGluIHRoZSBmdXR1cmU7IHRvIGF2b2lkIGluY29tcGF0aWJpbGl0aWVzLAogKiBjbGFzc2VzIHdoaWNoIGV4dGVuZCB0aGlzIGNsYXNzIHNob3VsZCBub3QgZGVjbGFyZSBhbnkgaW5zdGFuY2UKICogbWV0aG9kcyB3aXRoIG5hbWVzIGJlZ2lubmluZyB3aXRoIHtAY29kZSAidmlzaXQifS4KICoKICogPHA+V2hlbiBzdWNoIGEgbmV3IHZpc2l0IG1ldGhvZCBpcyBhZGRlZCwgdGhlIGRlZmF1bHQKICogaW1wbGVtZW50YXRpb24gaW4gdGhpcyBjbGFzcyB3aWxsIGJlIHRvIGNhbGwgdGhlIHtAbGluawogKiAjdmlzaXRVbmtub3duIHZpc2l0VW5rbm93bn0gbWV0aG9kLiAgQSBuZXcgc2ltcGxlIGFubm90YXRpb24KICogdmFsdWUgdmlzaXRvciBjbGFzcyB3aWxsIGFsc28gYmUgaW50cm9kdWNlZCB0byBjb3JyZXNwb25kIHRvIHRoZQogKiBuZXcgbGFuZ3VhZ2UgbGV2ZWw7IHRoaXMgdmlzaXRvciB3aWxsIGhhdmUgZGlmZmVyZW50IGRlZmF1bHQKICogYmVoYXZpb3IgZm9yIHRoZSB2aXNpdCBtZXRob2QgaW4gcXVlc3Rpb24uICBXaGVuIHRoZSBuZXcgdmlzaXRvciBpcwogKiBpbnRyb2R1Y2VkLCBhbGwgb3IgcG9ydGlvbnMgb2YgdGhpcyB2aXNpdG9yIG1heSBiZSBkZXByZWNhdGVkLgogKgogKiBAcGFyYW0gPFI+IHRoZSByZXR1cm4gdHlwZSBvZiB0aGlzIHZpc2l0b3IncyBtZXRob2RzCiAqIEBwYXJhbSA8UD4gdGhlIHR5cGUgb2YgdGhlIGFkZGl0aW9uYWwgcGFyYW1ldGVyIHRvIHRoaXMgdmlzaXRvcidzIG1ldGhvZHMuCiAqCiAqIEBzZWUgU2ltcGxlQW5ub3RhdGlvblZhbHVlVmlzaXRvcjYKICogQHNlZSBTaW1wbGVBbm5vdGF0aW9uVmFsdWVWaXNpdG9yNwogKiBAc2VlIFNpbXBsZUFubm90YXRpb25WYWx1ZVZpc2l0b3I4CiAqIEBzaW5jZSA5CiAqLwpAU3VwcG9ydGVkU291cmNlVmVyc2lvbihSRUxFQVNFXzkpCnB1YmxpYyBjbGFzcyBTaW1wbGVBbm5vdGF0aW9uVmFsdWVWaXNpdG9yOTxSLCBQPiBleHRlbmRzIFNpbXBsZUFubm90YXRpb25WYWx1ZVZpc2l0b3I4PFIsIFA+IHsKICAgIC8qKgogICAgICogQ29uc3RydWN0b3IgZm9yIGNvbmNyZXRlIHN1YmNsYXNzZXM7IHVzZXMge0Bjb2RlIG51bGx9IGZvciB0aGUKICAgICAqIGRlZmF1bHQgdmFsdWUuCiAgICAgKi8KICAgIHByb3RlY3RlZCBTaW1wbGVBbm5vdGF0aW9uVmFsdWVWaXNpdG9yOSgpIHsKICAgICAgICBzdXBlcihudWxsKTsKICAgIH0KCiAgICAvKioKICAgICAqIENvbnN0cnVjdG9yIGZvciBjb25jcmV0ZSBzdWJjbGFzc2VzOyB1c2VzIHRoZSBhcmd1bWVudCBmb3IgdGhlCiAgICAgKiBkZWZhdWx0IHZhbHVlLgogICAgICoKICAgICAqIEBwYXJhbSBkZWZhdWx0VmFsdWUgdGhlIHZhbHVlIHRvIGFzc2lnbiB0byB7QGxpbmsgI0RFRkFVTFRfVkFMVUV9CiAgICAgKi8KICAgIHByb3RlY3RlZCBTaW1wbGVBbm5vdGF0aW9uVmFsdWVWaXNpdG9yOShSIGRlZmF1bHRWYWx1ZSkgewogICAgICAgIHN1cGVyKGRlZmF1bHRWYWx1ZSk7CiAgICB9Cn0KUEsDBAoAAAgAAAY7qUquTGsZcAwAAHAMAAAvAAAAamF2YXgvbGFuZy9tb2RlbC91dGlsL0Fic3RyYWN0VHlwZVZpc2l0b3I5LmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTEsIDIwMTQsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgamF2YXgubGFuZy5tb2RlbC51dGlsOwoKaW1wb3J0IGphdmF4LmFubm90YXRpb24ucHJvY2Vzc2luZy5TdXBwb3J0ZWRTb3VyY2VWZXJzaW9uOwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC50eXBlLio7CgppbXBvcnQgc3RhdGljIGphdmF4LmxhbmcubW9kZWwuU291cmNlVmVyc2lvbi4qOwoKLyoqCiAqIEEgc2tlbGV0YWwgdmlzaXRvciBvZiB0eXBlcyB3aXRoIGRlZmF1bHQgYmVoYXZpb3IgYXBwcm9wcmlhdGUgZm9yCiAqIHRoZSB7QGxpbmsgamF2YXgubGFuZy5tb2RlbC5Tb3VyY2VWZXJzaW9uI1JFTEVBU0VfOSBSRUxFQVNFXzl9CiAqIHNvdXJjZSB2ZXJzaW9uLgogKgogKiA8cD4gPGI+V0FSTklORzo8L2I+IFRoZSB7QGNvZGUgVHlwZVZpc2l0b3J9IGludGVyZmFjZSBpbXBsZW1lbnRlZAogKiBieSB0aGlzIGNsYXNzIG1heSBoYXZlIG1ldGhvZHMgYWRkZWQgdG8gaXQgaW4gdGhlIGZ1dHVyZSB0bwogKiBhY2NvbW1vZGF0ZSBuZXcsIGN1cnJlbnRseSB1bmtub3duLCBsYW5ndWFnZSBzdHJ1Y3R1cmVzIGFkZGVkIHRvCiAqIGZ1dHVyZSB2ZXJzaW9ucyBvZiB0aGUgSmF2YSZ0cmFkZTsgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2UuCiAqIFRoZXJlZm9yZSwgbWV0aG9kcyB3aG9zZSBuYW1lcyBiZWdpbiB3aXRoIHtAY29kZSAidmlzaXQifSBtYXkgYmUKICogYWRkZWQgdG8gdGhpcyBjbGFzcyBpbiB0aGUgZnV0dXJlOyB0byBhdm9pZCBpbmNvbXBhdGliaWxpdGllcywKICogY2xhc3NlcyB3aGljaCBleHRlbmQgdGhpcyBjbGFzcyBzaG91bGQgbm90IGRlY2xhcmUgYW55IGluc3RhbmNlCiAqIG1ldGhvZHMgd2l0aCBuYW1lcyBiZWdpbm5pbmcgd2l0aCB7QGNvZGUgInZpc2l0In0uCiAqCiAqIDxwPldoZW4gc3VjaCBhIG5ldyB2aXNpdCBtZXRob2QgaXMgYWRkZWQsIHRoZSBkZWZhdWx0CiAqIGltcGxlbWVudGF0aW9uIGluIHRoaXMgY2xhc3Mgd2lsbCBiZSB0byBjYWxsIHRoZSB7QGxpbmsKICogI3Zpc2l0VW5rbm93biB2aXNpdFVua25vd259IG1ldGhvZC4gIEEgbmV3IGFic3RyYWN0IHR5cGUgdmlzaXRvcgogKiBjbGFzcyB3aWxsIGFsc28gYmUgaW50cm9kdWNlZCB0byBjb3JyZXNwb25kIHRvIHRoZSBuZXcgbGFuZ3VhZ2UKICogbGV2ZWw7IHRoaXMgdmlzaXRvciB3aWxsIGhhdmUgZGlmZmVyZW50IGRlZmF1bHQgYmVoYXZpb3IgZm9yIHRoZQogKiB2aXNpdCBtZXRob2QgaW4gcXVlc3Rpb24uICBXaGVuIHRoZSBuZXcgdmlzaXRvciBpcyBpbnRyb2R1Y2VkLCBhbGwKICogb3IgcG9ydGlvbnMgb2YgdGhpcyB2aXNpdG9yIG1heSBiZSBkZXByZWNhdGVkLgogKgogKiBAcGFyYW0gPFI+IHRoZSByZXR1cm4gdHlwZSBvZiB0aGlzIHZpc2l0b3IncyBtZXRob2RzLiAgVXNlIHtAbGluawogKiAgICAgICAgICAgIFZvaWR9IGZvciB2aXNpdG9ycyB0aGF0IGRvIG5vdCBuZWVkIHRvIHJldHVybiByZXN1bHRzLgogKiBAcGFyYW0gPFA+IHRoZSB0eXBlIG9mIHRoZSBhZGRpdGlvbmFsIHBhcmFtZXRlciB0byB0aGlzIHZpc2l0b3IncwogKiAgICAgICAgICAgIG1ldGhvZHMuICBVc2Uge0Bjb2RlIFZvaWR9IGZvciB2aXNpdG9ycyB0aGF0IGRvIG5vdCBuZWVkIGFuCiAqICAgICAgICAgICAgYWRkaXRpb25hbCBwYXJhbWV0ZXIuCiAqCiAqIEBzZWUgQWJzdHJhY3RUeXBlVmlzaXRvcjYKICogQHNlZSBBYnN0cmFjdFR5cGVWaXNpdG9yNwogKiBAc2VlIEFic3RyYWN0VHlwZVZpc2l0b3I4CiAqIEBzaW5jZSA5CiAqLwpAU3VwcG9ydGVkU291cmNlVmVyc2lvbihSRUxFQVNFXzkpCnB1YmxpYyBhYnN0cmFjdCBjbGFzcyBBYnN0cmFjdFR5cGVWaXNpdG9yOTxSLCBQPiBleHRlbmRzIEFic3RyYWN0VHlwZVZpc2l0b3I4PFIsIFA+IHsKICAgIC8qKgogICAgICogQ29uc3RydWN0b3IgZm9yIGNvbmNyZXRlIHN1YmNsYXNzZXMgdG8gY2FsbC4KICAgICAqLwogICAgcHJvdGVjdGVkIEFic3RyYWN0VHlwZVZpc2l0b3I5KCkgewogICAgICAgIHN1cGVyKCk7CiAgICB9Cn0KUEsDBAoAAAgAAAY7qUr7edB/FwwAABcMAAA6AAAAamF2YXgvbGFuZy9tb2RlbC91dGlsL0Fic3RyYWN0QW5ub3RhdGlvblZhbHVlVmlzaXRvcjguamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAxMSwgMjAxNywgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBqYXZheC5sYW5nLm1vZGVsLnV0aWw7CgppbXBvcnQgc3RhdGljIGphdmF4LmxhbmcubW9kZWwuU291cmNlVmVyc2lvbi4qOwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5Tb3VyY2VWZXJzaW9uOwppbXBvcnQgamF2YXguYW5ub3RhdGlvbi5wcm9jZXNzaW5nLlN1cHBvcnRlZFNvdXJjZVZlcnNpb247CgovKioKICogQSBza2VsZXRhbCB2aXNpdG9yIGZvciBhbm5vdGF0aW9uIHZhbHVlcyB3aXRoIGRlZmF1bHQgYmVoYXZpb3IKICogYXBwcm9wcmlhdGUgZm9yIHRoZSB7QGxpbmsgU291cmNlVmVyc2lvbiNSRUxFQVNFXzggUkVMRUFTRV84fQogKiBzb3VyY2UgdmVyc2lvbi4KICoKICogPHA+IDxiPldBUk5JTkc6PC9iPiBUaGUge0Bjb2RlIEFubm90YXRpb25WYWx1ZVZpc2l0b3J9IGludGVyZmFjZQogKiBpbXBsZW1lbnRlZCBieSB0aGlzIGNsYXNzIG1heSBoYXZlIG1ldGhvZHMgYWRkZWQgdG8gaXQgaW4gdGhlCiAqIGZ1dHVyZSB0byBhY2NvbW1vZGF0ZSBuZXcsIGN1cnJlbnRseSB1bmtub3duLCBsYW5ndWFnZSBzdHJ1Y3R1cmVzCiAqIGFkZGVkIHRvIGZ1dHVyZSB2ZXJzaW9ucyBvZiB0aGUgSmF2YSZ0cmFkZTsgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2UuCiAqIFRoZXJlZm9yZSwgbWV0aG9kcyB3aG9zZSBuYW1lcyBiZWdpbiB3aXRoIHtAY29kZSAidmlzaXQifSBtYXkgYmUKICogYWRkZWQgdG8gdGhpcyBjbGFzcyBpbiB0aGUgZnV0dXJlOyB0byBhdm9pZCBpbmNvbXBhdGliaWxpdGllcywKICogY2xhc3NlcyB3aGljaCBleHRlbmQgdGhpcyBjbGFzcyBzaG91bGQgbm90IGRlY2xhcmUgYW55IGluc3RhbmNlCiAqIG1ldGhvZHMgd2l0aCBuYW1lcyBiZWdpbm5pbmcgd2l0aCB7QGNvZGUgInZpc2l0In0uCiAqCiAqIDxwPldoZW4gc3VjaCBhIG5ldyB2aXNpdCBtZXRob2QgaXMgYWRkZWQsIHRoZSBkZWZhdWx0CiAqIGltcGxlbWVudGF0aW9uIGluIHRoaXMgY2xhc3Mgd2lsbCBiZSB0byBjYWxsIHRoZSB7QGxpbmsKICogI3Zpc2l0VW5rbm93biB2aXNpdFVua25vd259IG1ldGhvZC4gIEEgbmV3IGFic3RyYWN0IGFubm90YXRpb24KICogdmFsdWUgdmlzaXRvciBjbGFzcyB3aWxsIGFsc28gYmUgaW50cm9kdWNlZCB0byBjb3JyZXNwb25kIHRvIHRoZQogKiBuZXcgbGFuZ3VhZ2UgbGV2ZWw7IHRoaXMgdmlzaXRvciB3aWxsIGhhdmUgZGlmZmVyZW50IGRlZmF1bHQKICogYmVoYXZpb3IgZm9yIHRoZSB2aXNpdCBtZXRob2QgaW4gcXVlc3Rpb24uICBXaGVuIHRoZSBuZXcgdmlzaXRvciBpcwogKiBpbnRyb2R1Y2VkLCBhbGwgb3IgcG9ydGlvbnMgb2YgdGhpcyB2aXNpdG9yIG1heSBiZSBkZXByZWNhdGVkLgogKgogKiBAcGFyYW0gPFI+IHRoZSByZXR1cm4gdHlwZSBvZiB0aGlzIHZpc2l0b3IncyBtZXRob2RzCiAqIEBwYXJhbSA8UD4gdGhlIHR5cGUgb2YgdGhlIGFkZGl0aW9uYWwgcGFyYW1ldGVyIHRvIHRoaXMgdmlzaXRvcidzIG1ldGhvZHMuCiAqCiAqIEBzZWUgQWJzdHJhY3RBbm5vdGF0aW9uVmFsdWVWaXNpdG9yNgogKiBAc2VlIEFic3RyYWN0QW5ub3RhdGlvblZhbHVlVmlzaXRvcjcKICogQHNlZSBBYnN0cmFjdEFubm90YXRpb25WYWx1ZVZpc2l0b3I5CiAqIEBzaW5jZSAxLjgKICovCkBTdXBwb3J0ZWRTb3VyY2VWZXJzaW9uKFJFTEVBU0VfOCkKcHVibGljIGFic3RyYWN0IGNsYXNzIEFic3RyYWN0QW5ub3RhdGlvblZhbHVlVmlzaXRvcjg8UiwgUD4gZXh0ZW5kcyBBYnN0cmFjdEFubm90YXRpb25WYWx1ZVZpc2l0b3I3PFIsIFA+IHsKCiAgICAvKioKICAgICAqIENvbnN0cnVjdG9yIGZvciBjb25jcmV0ZSBzdWJjbGFzc2VzIHRvIGNhbGwuCiAgICAgKi8KICAgIHByb3RlY3RlZCBBYnN0cmFjdEFubm90YXRpb25WYWx1ZVZpc2l0b3I4KCkgewogICAgICAgIHN1cGVyKCk7CiAgICB9Cn0KUEsDBAoAAAgAAAY7qUoC40SZmhoAAJoaAAAwAAAAamF2YXgvbGFuZy9tb2RlbC91dGlsL1NpbXBsZUVsZW1lbnRWaXNpdG9yNi5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDA1LCAyMDE3LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGphdmF4LmxhbmcubW9kZWwudXRpbDsKCmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuKjsKaW1wb3J0IGphdmF4LmFubm90YXRpb24ucHJvY2Vzc2luZy5TdXBwb3J0ZWRTb3VyY2VWZXJzaW9uOwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5Tb3VyY2VWZXJzaW9uOwppbXBvcnQgc3RhdGljIGphdmF4LmxhbmcubW9kZWwuU291cmNlVmVyc2lvbi4qOwoKCi8qKgogKiBBIHNpbXBsZSB2aXNpdG9yIG9mIHByb2dyYW0gZWxlbWVudHMgd2l0aCBkZWZhdWx0IGJlaGF2aW9yCiAqIGFwcHJvcHJpYXRlIGZvciB0aGUge0BsaW5rIFNvdXJjZVZlcnNpb24jUkVMRUFTRV82IFJFTEVBU0VfNn0KICogc291cmNlIHZlcnNpb24uCiAqCiAqIFZpc2l0IG1ldGhvZHMgY29ycmVzcG9uZGluZyB0byB7QGNvZGUgUkVMRUFTRV82fSBsYW5ndWFnZQogKiBjb25zdHJ1Y3RzIGNhbGwge0BsaW5rICNkZWZhdWx0QWN0aW9uIGRlZmF1bHRBY3Rpb259LCBwYXNzaW5nIHRoZWlyCiAqIGFyZ3VtZW50cyB0byB7QGNvZGUgZGVmYXVsdEFjdGlvbn0ncyBjb3JyZXNwb25kaW5nIHBhcmFtZXRlcnMuCiAqCiAqIEZvciBjb25zdHJ1Y3RzIGludHJvZHVjZWQgaW4ge0Bjb2RlIFJFTEVBU0VfN30gYW5kIGxhdGVyLCB7QGNvZGUKICogdmlzaXRVbmtub3dufSBpcyBjYWxsZWQgaW5zdGVhZC4KICoKICogPHA+IE1ldGhvZHMgaW4gdGhpcyBjbGFzcyBtYXkgYmUgb3ZlcnJpZGRlbiBzdWJqZWN0IHRvIHRoZWlyCiAqIGdlbmVyYWwgY29udHJhY3QuICBOb3RlIHRoYXQgYW5ub3RhdGluZyBtZXRob2RzIGluIGNvbmNyZXRlCiAqIHN1YmNsYXNzZXMgd2l0aCB7QGxpbmsgamF2YS5sYW5nLk92ZXJyaWRlIEBPdmVycmlkZX0gd2lsbCBoZWxwCiAqIGVuc3VyZSB0aGF0IG1ldGhvZHMgYXJlIG92ZXJyaWRkZW4gYXMgaW50ZW5kZWQuCiAqCiAqIDxwPiA8Yj5XQVJOSU5HOjwvYj4gVGhlIHtAY29kZSBFbGVtZW50VmlzaXRvcn0gaW50ZXJmYWNlCiAqIGltcGxlbWVudGVkIGJ5IHRoaXMgY2xhc3MgbWF5IGhhdmUgbWV0aG9kcyBhZGRlZCB0byBpdCBpbiB0aGUKICogZnV0dXJlIHRvIGFjY29tbW9kYXRlIG5ldywgY3VycmVudGx5IHVua25vd24sIGxhbmd1YWdlIHN0cnVjdHVyZXMKICogYWRkZWQgdG8gZnV0dXJlIHZlcnNpb25zIG9mIHRoZSBKYXZhJnRyYWRlOyBwcm9ncmFtbWluZyBsYW5ndWFnZS4KICogVGhlcmVmb3JlLCBtZXRob2RzIHdob3NlIG5hbWVzIGJlZ2luIHdpdGgge0Bjb2RlICJ2aXNpdCJ9IG1heSBiZQogKiBhZGRlZCB0byB0aGlzIGNsYXNzIGluIHRoZSBmdXR1cmU7IHRvIGF2b2lkIGluY29tcGF0aWJpbGl0aWVzLAogKiBjbGFzc2VzIHdoaWNoIGV4dGVuZCB0aGlzIGNsYXNzIHNob3VsZCBub3QgZGVjbGFyZSBhbnkgaW5zdGFuY2UKICogbWV0aG9kcyB3aXRoIG5hbWVzIGJlZ2lubmluZyB3aXRoIHtAY29kZSAidmlzaXQifS4KICoKICogPHA+V2hlbiBzdWNoIGEgbmV3IHZpc2l0IG1ldGhvZCBpcyBhZGRlZCwgdGhlIGRlZmF1bHQKICogaW1wbGVtZW50YXRpb24gaW4gdGhpcyBjbGFzcyB3aWxsIGJlIHRvIGNhbGwgdGhlIHtAbGluawogKiAjdmlzaXRVbmtub3duIHZpc2l0VW5rbm93bn0gbWV0aG9kLiAgQSBuZXcgc2ltcGxlIGVsZW1lbnQgdmlzaXRvcgogKiBjbGFzcyB3aWxsIGFsc28gYmUgaW50cm9kdWNlZCB0byBjb3JyZXNwb25kIHRvIHRoZSBuZXcgbGFuZ3VhZ2UKICogbGV2ZWw7IHRoaXMgdmlzaXRvciB3aWxsIGhhdmUgZGlmZmVyZW50IGRlZmF1bHQgYmVoYXZpb3IgZm9yIHRoZQogKiB2aXNpdCBtZXRob2QgaW4gcXVlc3Rpb24uICBXaGVuIHRoZSBuZXcgdmlzaXRvciBpcyBpbnRyb2R1Y2VkLCBhbGwKICogb3IgcG9ydGlvbnMgb2YgdGhpcyB2aXNpdG9yIG1heSBiZSBkZXByZWNhdGVkLgogKgogKiBAcGFyYW0gPFI+IHRoZSByZXR1cm4gdHlwZSBvZiB0aGlzIHZpc2l0b3IncyBtZXRob2RzLiAgVXNlIHtAY29kZSBWb2lkfQogKiAgICAgICAgICAgICBmb3IgdmlzaXRvcnMgdGhhdCBkbyBub3QgbmVlZCB0byByZXR1cm4gcmVzdWx0cy4KICogQHBhcmFtIDxQPiB0aGUgdHlwZSBvZiB0aGUgYWRkaXRpb25hbCBwYXJhbWV0ZXIgdG8gdGhpcyB2aXNpdG9yJ3MgbWV0aG9kcy4gIFVzZSB7QGNvZGUgVm9pZH0KICogICAgICAgICAgICAgIGZvciB2aXNpdG9ycyB0aGF0IGRvIG5vdCBuZWVkIGFuIGFkZGl0aW9uYWwgcGFyYW1ldGVyLgogKgogKiBAYXV0aG9yIEpvc2VwaCBELiBEYXJjeQogKiBAYXV0aG9yIFNjb3R0IFNlbGlnbWFuCiAqIEBhdXRob3IgUGV0ZXIgdm9uIGRlciBBaCZlYWN1dGU7CiAqCiAqIEBzZWUgU2ltcGxlRWxlbWVudFZpc2l0b3I3CiAqIEBzZWUgU2ltcGxlRWxlbWVudFZpc2l0b3I4CiAqIEBzZWUgU2ltcGxlRWxlbWVudFZpc2l0b3I5CiAqIEBzaW5jZSAxLjYKICovCkBTdXBwb3J0ZWRTb3VyY2VWZXJzaW9uKFJFTEVBU0VfNikKcHVibGljIGNsYXNzIFNpbXBsZUVsZW1lbnRWaXNpdG9yNjxSLCBQPiBleHRlbmRzIEFic3RyYWN0RWxlbWVudFZpc2l0b3I2PFIsIFA+IHsKICAgIC8qKgogICAgICogRGVmYXVsdCB2YWx1ZSB0byBiZSByZXR1cm5lZDsge0BsaW5rICNkZWZhdWx0QWN0aW9uCiAgICAgKiBkZWZhdWx0QWN0aW9ufSByZXR1cm5zIHRoaXMgdmFsdWUgdW5sZXNzIHRoZSBtZXRob2QgaXMKICAgICAqIG92ZXJyaWRkZW4uCiAgICAgKi8KICAgIHByb3RlY3RlZCBmaW5hbCBSIERFRkFVTFRfVkFMVUU7CgogICAgLyoqCiAgICAgKiBDb25zdHJ1Y3RvciBmb3IgY29uY3JldGUgc3ViY2xhc3NlczsgdXNlcyB7QGNvZGUgbnVsbH0gZm9yIHRoZQogICAgICogZGVmYXVsdCB2YWx1ZS4KICAgICAqIEBkZXByZWNhdGVkIFJlbGVhc2UgNiBpcyBvYnNvbGV0ZTsgdXBkYXRlIHRvIGEgdmlzaXRvciBmb3IgYSBuZXdlcgogICAgICogcmVsZWFzZSBsZXZlbC4KICAgICAqLwogICAgQERlcHJlY2F0ZWQKICAgIHByb3RlY3RlZCBTaW1wbGVFbGVtZW50VmlzaXRvcjYoKXsKICAgICAgICBERUZBVUxUX1ZBTFVFID0gbnVsbDsKICAgIH0KCiAgICAvKioKICAgICAqIENvbnN0cnVjdG9yIGZvciBjb25jcmV0ZSBzdWJjbGFzc2VzOyB1c2VzIHRoZSBhcmd1bWVudCBmb3IgdGhlCiAgICAgKiBkZWZhdWx0IHZhbHVlLgogICAgICoKICAgICAqIEBwYXJhbSBkZWZhdWx0VmFsdWUgdGhlIHZhbHVlIHRvIGFzc2lnbiB0byB7QGxpbmsgI0RFRkFVTFRfVkFMVUV9CiAgICAgKiBAZGVwcmVjYXRlZCBSZWxlYXNlIDYgaXMgb2Jzb2xldGU7IHVwZGF0ZSB0byBhIHZpc2l0b3IgZm9yIGEgbmV3ZXIKICAgICAqIHJlbGVhc2UgbGV2ZWwuCiAgICAgKi8KICAgIEBEZXByZWNhdGVkCiAgICBwcm90ZWN0ZWQgU2ltcGxlRWxlbWVudFZpc2l0b3I2KFIgZGVmYXVsdFZhbHVlKXsKICAgICAgICBERUZBVUxUX1ZBTFVFID0gZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiBUaGUgZGVmYXVsdCBhY3Rpb24gZm9yIHZpc2l0IG1ldGhvZHMuICBUaGUgaW1wbGVtZW50YXRpb24gaW4KICAgICAqIHRoaXMgY2xhc3MganVzdCByZXR1cm5zIHtAbGluayAjREVGQVVMVF9WQUxVRX07IHN1YmNsYXNzZXMgd2lsbAogICAgICogY29tbW9ubHkgb3ZlcnJpZGUgdGhpcyBtZXRob2QuCiAgICAgKgogICAgICogQHBhcmFtIGUgdGhlIGVsZW1lbnQgdG8gcHJvY2VzcwogICAgICogQHBhcmFtIHAgYSB2aXNpdG9yLXNwZWNpZmllZCBwYXJhbWV0ZXIKICAgICAqIEByZXR1cm4ge0Bjb2RlIERFRkFVTFRfVkFMVUV9IHVubGVzcyBvdmVycmlkZGVuCiAgICAgKi8KICAgIHByb3RlY3RlZCBSIGRlZmF1bHRBY3Rpb24oRWxlbWVudCBlLCBQIHApIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9WQUxVRTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30gVGhpcyBpbXBsZW1lbnRhdGlvbiBjYWxscyB7QGNvZGUgZGVmYXVsdEFjdGlvbn0uCiAgICAgKgogICAgICogQHBhcmFtIGUge0Bpbmhlcml0RG9jfQogICAgICogQHBhcmFtIHAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiAgdGhlIHJlc3VsdCBvZiB7QGNvZGUgZGVmYXVsdEFjdGlvbn0KICAgICAqLwogICAgcHVibGljIFIgdmlzaXRQYWNrYWdlKFBhY2thZ2VFbGVtZW50IGUsIFAgcCkgewogICAgICAgIHJldHVybiBkZWZhdWx0QWN0aW9uKGUsIHApOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIGNhbGxzIHtAY29kZSBkZWZhdWx0QWN0aW9ufS4KICAgICAqCiAgICAgKiBAcGFyYW0gZSB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuICB0aGUgcmVzdWx0IG9mIHtAY29kZSBkZWZhdWx0QWN0aW9ufQogICAgICovCiAgICBwdWJsaWMgUiB2aXNpdFR5cGUoVHlwZUVsZW1lbnQgZSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIGRlZmF1bHRBY3Rpb24oZSwgcCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKgogICAgICogVGhpcyBpbXBsZW1lbnRhdGlvbiBjYWxscyB7QGNvZGUgZGVmYXVsdEFjdGlvbn0sIHVubGVzcyB0aGUKICAgICAqIGVsZW1lbnQgaXMgYSB7QGNvZGUgUkVTT1VSQ0VfVkFSSUFCTEV9IGluIHdoaWNoIGNhc2Uge0Bjb2RlCiAgICAgKiB2aXNpdFVua25vd259IGlzIGNhbGxlZC4KICAgICAqCiAgICAgKiBAcGFyYW0gZSB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuICB0aGUgcmVzdWx0IG9mIHtAY29kZSBkZWZhdWx0QWN0aW9ufSBvciB7QGNvZGUgdmlzaXRVbmtub3dufQogICAgICovCiAgICBwdWJsaWMgUiB2aXNpdFZhcmlhYmxlKFZhcmlhYmxlRWxlbWVudCBlLCBQIHApIHsKICAgICAgICBpZiAoZS5nZXRLaW5kKCkgIT0gRWxlbWVudEtpbmQuUkVTT1VSQ0VfVkFSSUFCTEUpCiAgICAgICAgICAgIHJldHVybiBkZWZhdWx0QWN0aW9uKGUsIHApOwogICAgICAgIGVsc2UKICAgICAgICAgICAgcmV0dXJuIHZpc2l0VW5rbm93bihlLCBwKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30gVGhpcyBpbXBsZW1lbnRhdGlvbiBjYWxscyB7QGNvZGUgZGVmYXVsdEFjdGlvbn0uCiAgICAgKgogICAgICogQHBhcmFtIGUge0Bpbmhlcml0RG9jfQogICAgICogQHBhcmFtIHAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiAgdGhlIHJlc3VsdCBvZiB7QGNvZGUgZGVmYXVsdEFjdGlvbn0KICAgICAqLwogICAgcHVibGljIFIgdmlzaXRFeGVjdXRhYmxlKEV4ZWN1dGFibGVFbGVtZW50IGUsIFAgcCkgewogICAgICAgIHJldHVybiBkZWZhdWx0QWN0aW9uKGUsIHApOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIGNhbGxzIHtAY29kZSBkZWZhdWx0QWN0aW9ufS4KICAgICAqCiAgICAgKiBAcGFyYW0gZSB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuICB0aGUgcmVzdWx0IG9mIHtAY29kZSBkZWZhdWx0QWN0aW9ufQogICAgICovCiAgICBwdWJsaWMgUiB2aXNpdFR5cGVQYXJhbWV0ZXIoVHlwZVBhcmFtZXRlckVsZW1lbnQgZSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIGRlZmF1bHRBY3Rpb24oZSwgcCk7CiAgICB9Cn0KUEsDBAoAAAgAAAY7qUo/fVzl2Q0AANkNAAAvAAAAamF2YXgvbGFuZy9tb2RlbC91dGlsL0Fic3RyYWN0VHlwZVZpc2l0b3I3LmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTAsIDIwMTcsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgamF2YXgubGFuZy5tb2RlbC51dGlsOwoKaW1wb3J0IGphdmF4LmFubm90YXRpb24ucHJvY2Vzc2luZy5TdXBwb3J0ZWRTb3VyY2VWZXJzaW9uOwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC50eXBlLio7CgppbXBvcnQgc3RhdGljIGphdmF4LmxhbmcubW9kZWwuU291cmNlVmVyc2lvbi4qOwoKLyoqCiAqIEEgc2tlbGV0YWwgdmlzaXRvciBvZiB0eXBlcyB3aXRoIGRlZmF1bHQgYmVoYXZpb3IgYXBwcm9wcmlhdGUgZm9yCiAqIHRoZSB7QGxpbmsgamF2YXgubGFuZy5tb2RlbC5Tb3VyY2VWZXJzaW9uI1JFTEVBU0VfNyBSRUxFQVNFXzd9CiAqIHNvdXJjZSB2ZXJzaW9uLgogKgogKiA8cD4gPGI+V0FSTklORzo8L2I+IFRoZSB7QGNvZGUgVHlwZVZpc2l0b3J9IGludGVyZmFjZSBpbXBsZW1lbnRlZAogKiBieSB0aGlzIGNsYXNzIG1heSBoYXZlIG1ldGhvZHMgYWRkZWQgdG8gaXQgaW4gdGhlIGZ1dHVyZSB0bwogKiBhY2NvbW1vZGF0ZSBuZXcsIGN1cnJlbnRseSB1bmtub3duLCBsYW5ndWFnZSBzdHJ1Y3R1cmVzIGFkZGVkIHRvCiAqIGZ1dHVyZSB2ZXJzaW9ucyBvZiB0aGUgSmF2YSZ0cmFkZTsgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2UuCiAqIFRoZXJlZm9yZSwgbWV0aG9kcyB3aG9zZSBuYW1lcyBiZWdpbiB3aXRoIHtAY29kZSAidmlzaXQifSBtYXkgYmUKICogYWRkZWQgdG8gdGhpcyBjbGFzcyBpbiB0aGUgZnV0dXJlOyB0byBhdm9pZCBpbmNvbXBhdGliaWxpdGllcywKICogY2xhc3NlcyB3aGljaCBleHRlbmQgdGhpcyBjbGFzcyBzaG91bGQgbm90IGRlY2xhcmUgYW55IGluc3RhbmNlCiAqIG1ldGhvZHMgd2l0aCBuYW1lcyBiZWdpbm5pbmcgd2l0aCB7QGNvZGUgInZpc2l0In0uCiAqCiAqIDxwPldoZW4gc3VjaCBhIG5ldyB2aXNpdCBtZXRob2QgaXMgYWRkZWQsIHRoZSBkZWZhdWx0CiAqIGltcGxlbWVudGF0aW9uIGluIHRoaXMgY2xhc3Mgd2lsbCBiZSB0byBjYWxsIHRoZSB7QGxpbmsKICogI3Zpc2l0VW5rbm93biB2aXNpdFVua25vd259IG1ldGhvZC4gIEEgbmV3IGFic3RyYWN0IHR5cGUgdmlzaXRvcgogKiBjbGFzcyB3aWxsIGFsc28gYmUgaW50cm9kdWNlZCB0byBjb3JyZXNwb25kIHRvIHRoZSBuZXcgbGFuZ3VhZ2UKICogbGV2ZWw7IHRoaXMgdmlzaXRvciB3aWxsIGhhdmUgZGlmZmVyZW50IGRlZmF1bHQgYmVoYXZpb3IgZm9yIHRoZQogKiB2aXNpdCBtZXRob2QgaW4gcXVlc3Rpb24uICBXaGVuIHRoZSBuZXcgdmlzaXRvciBpcyBpbnRyb2R1Y2VkLCBhbGwKICogb3IgcG9ydGlvbnMgb2YgdGhpcyB2aXNpdG9yIG1heSBiZSBkZXByZWNhdGVkLgogKgogKiBAcGFyYW0gPFI+IHRoZSByZXR1cm4gdHlwZSBvZiB0aGlzIHZpc2l0b3IncyBtZXRob2RzLiAgVXNlIHtAbGluawogKiAgICAgICAgICAgIFZvaWR9IGZvciB2aXNpdG9ycyB0aGF0IGRvIG5vdCBuZWVkIHRvIHJldHVybiByZXN1bHRzLgogKiBAcGFyYW0gPFA+IHRoZSB0eXBlIG9mIHRoZSBhZGRpdGlvbmFsIHBhcmFtZXRlciB0byB0aGlzIHZpc2l0b3IncwogKiAgICAgICAgICAgIG1ldGhvZHMuICBVc2Uge0Bjb2RlIFZvaWR9IGZvciB2aXNpdG9ycyB0aGF0IGRvIG5vdCBuZWVkIGFuCiAqICAgICAgICAgICAgYWRkaXRpb25hbCBwYXJhbWV0ZXIuCiAqCiAqIEBzZWUgQWJzdHJhY3RUeXBlVmlzaXRvcjYKICogQHNlZSBBYnN0cmFjdFR5cGVWaXNpdG9yOAogKiBAc2VlIEFic3RyYWN0VHlwZVZpc2l0b3I5CiAqIEBzaW5jZSAxLjcKICovCkBTdXBwb3J0ZWRTb3VyY2VWZXJzaW9uKFJFTEVBU0VfNykKcHVibGljIGFic3RyYWN0IGNsYXNzIEFic3RyYWN0VHlwZVZpc2l0b3I3PFIsIFA+IGV4dGVuZHMgQWJzdHJhY3RUeXBlVmlzaXRvcjY8UiwgUD4gewogICAgLyoqCiAgICAgKiBDb25zdHJ1Y3RvciBmb3IgY29uY3JldGUgc3ViY2xhc3NlcyB0byBjYWxsLgogICAgICovCiAgICBAU3VwcHJlc3NXYXJuaW5ncygiZGVwcmVjYXRpb24iKSAvLyBTdXBlcmNsYXNzIGNvbnN0cnVjdG9yIGRlcHJlY2F0ZWQKICAgIHByb3RlY3RlZCBBYnN0cmFjdFR5cGVWaXNpdG9yNygpIHsKICAgICAgICBzdXBlcigpOwogICAgfQoKICAgIC8qKgogICAgICogVmlzaXRzIGEge0Bjb2RlIFVuaW9uVHlwZX0gaW4gYSBtYW5uZXIgZGVmaW5lZCBieSBhIHN1YmNsYXNzLgogICAgICoKICAgICAqIEBwYXJhbSB0ICB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiB0aGUgcmVzdWx0IG9mIHRoZSB2aXNpdCBhcyBkZWZpbmVkIGJ5IGEgc3ViY2xhc3MKICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgYWJzdHJhY3QgUiB2aXNpdFVuaW9uKFVuaW9uVHlwZSB0LCBQIHApOwp9ClBLAwQKAAAIAADSfU1KNVhdQ0gHAABIBwAAJwAAAGphdmF4L2xhbmcvbW9kZWwvdXRpbC9wYWNrYWdlLWluZm8uamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAwNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKLyoqCiAqIFV0aWxpdGllcyB0byBhc3Npc3QgaW4gdGhlIHByb2Nlc3Npbmcgb2YKICoge0BsaW5rcGxhaW4gamF2YXgubGFuZy5tb2RlbC5lbGVtZW50IHByb2dyYW0gZWxlbWVudHN9IGFuZAogKiB7QGxpbmtwbGFpbiBqYXZheC5sYW5nLm1vZGVsLnR5cGUgdHlwZXN9LgogKgogKiA8cD4gVW5sZXNzIG90aGVyd2lzZSBzcGVjaWZpZWQgaW4gYSBwYXJ0aWN1bGFyIGltcGxlbWVudGF0aW9uLCB0aGUKICogY29sbGVjdGlvbnMgcmV0dXJuZWQgYnkgbWV0aG9kcyBpbiB0aGlzIHBhY2thZ2Ugc2hvdWxkIGJlIGV4cGVjdGVkCiAqIHRvIGJlIHVubW9kaWZpYWJsZSBieSB0aGUgY2FsbGVyIGFuZCB1bnNhZmUgZm9yIGNvbmN1cnJlbnQgYWNjZXNzLgogKgogKiA8cD4gVW5sZXNzIG90aGVyd2lzZSBzcGVjaWZpZWQsIG1ldGhvZHMgaW4gdGhpcyBwYWNrYWdlIHdpbGwgdGhyb3cKICogYSB7QGNvZGUgTnVsbFBvaW50ZXJFeGNlcHRpb259IGlmIGdpdmVuIGEge0Bjb2RlIG51bGx9IGFyZ3VtZW50LgogKgogKiBAYXV0aG9yIEpvc2VwaCBELiBEYXJjeQogKiBAYXV0aG9yIFNjb3R0IFNlbGlnbWFuCiAqIEBhdXRob3IgUGV0ZXIgdm9uIGRlciBBaCZlYWN1dGU7CiAqIEBzaW5jZSAxLjYKICovCnBhY2thZ2UgamF2YXgubGFuZy5tb2RlbC51dGlsOwpQSwMECgAACAAABjupSurj4VN/FQAAfxUAACoAAABqYXZheC9sYW5nL21vZGVsL3V0aWwvRWxlbWVudFNjYW5uZXI3LmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTAsIDIwMTcsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgamF2YXgubGFuZy5tb2RlbC51dGlsOwoKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC4qOwppbXBvcnQgamF2YXguYW5ub3RhdGlvbi5wcm9jZXNzaW5nLlN1cHBvcnRlZFNvdXJjZVZlcnNpb247CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLlNvdXJjZVZlcnNpb247CmltcG9ydCBzdGF0aWMgamF2YXgubGFuZy5tb2RlbC5Tb3VyY2VWZXJzaW9uLio7CgoKLyoqCiAqIEEgc2Nhbm5pbmcgdmlzaXRvciBvZiBwcm9ncmFtIGVsZW1lbnRzIHdpdGggZGVmYXVsdCBiZWhhdmlvcgogKiBhcHByb3ByaWF0ZSBmb3IgdGhlIHtAbGluayBTb3VyY2VWZXJzaW9uI1JFTEVBU0VfNyBSRUxFQVNFXzd9CiAqIHNvdXJjZSB2ZXJzaW9uLiAgVGhlIDxjb2RlPnZpc2l0PGk+WHl6PC9pPjwvY29kZT4gbWV0aG9kcyBpbiB0aGlzCiAqIGNsYXNzIHNjYW4gdGhlaXIgY29tcG9uZW50IGVsZW1lbnRzIGJ5IGNhbGxpbmcge0Bjb2RlIHNjYW59IG9uCiAqIHRoZWlyIHtAbGlua3BsYWluIEVsZW1lbnQjZ2V0RW5jbG9zZWRFbGVtZW50cyBlbmNsb3NlZCBlbGVtZW50c30sCiAqIHtAbGlua3BsYWluIEV4ZWN1dGFibGVFbGVtZW50I2dldFBhcmFtZXRlcnMgcGFyYW1ldGVyc30sIGV0Yy4sIGFzCiAqIGluZGljYXRlZCBpbiB0aGUgaW5kaXZpZHVhbCBtZXRob2Qgc3BlY2lmaWNhdGlvbnMuICBBIHN1YmNsYXNzIGNhbgogKiBjb250cm9sIHRoZSBvcmRlciBlbGVtZW50cyBhcmUgdmlzaXRlZCBieSBvdmVycmlkaW5nIHRoZQogKiA8Y29kZT52aXNpdDxpPlh5ejwvaT48L2NvZGU+IG1ldGhvZHMuICBOb3RlIHRoYXQgY2xpZW50cyBvZiBhIHNjYW5uZXIKICogbWF5IGdldCB0aGUgZGVzaXJlZCBiZWhhdmlvciBiZSBpbnZva2luZyB7QGNvZGUgdi5zY2FuKGUsIHApfSByYXRoZXIKICogdGhhbiB7QGNvZGUgdi52aXNpdChlLCBwKX0gb24gdGhlIHJvb3Qgb2JqZWN0cyBvZiBpbnRlcmVzdC4KICoKICogPHA+V2hlbiBhIHN1YmNsYXNzIG92ZXJyaWRlcyBhIDxjb2RlPnZpc2l0PGk+WHl6PC9pPjwvY29kZT4gbWV0aG9kLCB0aGUKICogbmV3IG1ldGhvZCBjYW4gY2F1c2UgdGhlIGVuY2xvc2VkIGVsZW1lbnRzIHRvIGJlIHNjYW5uZWQgaW4gdGhlCiAqIGRlZmF1bHQgd2F5IGJ5IGNhbGxpbmcgPGNvZGU+c3VwZXIudmlzaXQ8aT5YeXo8L2k+PC9jb2RlPi4gIEluIHRoaXMKICogZmFzaGlvbiwgdGhlIGNvbmNyZXRlIHZpc2l0b3IgY2FuIGNvbnRyb2wgdGhlIG9yZGVyaW5nIG9mIHRyYXZlcnNhbAogKiBvdmVyIHRoZSBjb21wb25lbnQgZWxlbWVudHMgd2l0aCByZXNwZWN0IHRvIHRoZSBhZGRpdGlvbmFsCiAqIHByb2Nlc3Npbmc7IGZvciBleGFtcGxlLCBjb25zaXN0ZW50bHkgY2FsbGluZwogKiA8Y29kZT5zdXBlci52aXNpdDxpPlh5ejwvaT48L2NvZGU+IGF0IHRoZSBzdGFydCBvZiB0aGUgb3ZlcnJpZGRlbgogKiBtZXRob2RzIHdpbGwgeWllbGQgYSBwcmVvcmRlciB0cmF2ZXJzYWwsIGV0Yy4gIElmIHRoZSBjb21wb25lbnQKICogZWxlbWVudHMgc2hvdWxkIGJlIHRyYXZlcnNlZCBpbiBzb21lIG90aGVyIG9yZGVyLCBpbnN0ZWFkIG9mCiAqIGNhbGxpbmcgPGNvZGU+c3VwZXIudmlzaXQ8aT5YeXo8L2k+PC9jb2RlPiwgYW4gb3ZlcnJpZGluZyB2aXNpdCBtZXRob2QKICogc2hvdWxkIGNhbGwge0Bjb2RlIHNjYW59IHdpdGggdGhlIGVsZW1lbnRzIGluIHRoZSBkZXNpcmVkIG9yZGVyLgogKgogKiA8cD4gTWV0aG9kcyBpbiB0aGlzIGNsYXNzIG1heSBiZSBvdmVycmlkZGVuIHN1YmplY3QgdG8gdGhlaXIKICogZ2VuZXJhbCBjb250cmFjdC4gIE5vdGUgdGhhdCBhbm5vdGF0aW5nIG1ldGhvZHMgaW4gY29uY3JldGUKICogc3ViY2xhc3NlcyB3aXRoIHtAbGluayBqYXZhLmxhbmcuT3ZlcnJpZGUgQE92ZXJyaWRlfSB3aWxsIGhlbHAKICogZW5zdXJlIHRoYXQgbWV0aG9kcyBhcmUgb3ZlcnJpZGRlbiBhcyBpbnRlbmRlZC4KICoKICogPHA+IDxiPldBUk5JTkc6PC9iPiBUaGUge0Bjb2RlIEVsZW1lbnRWaXNpdG9yfSBpbnRlcmZhY2UKICogaW1wbGVtZW50ZWQgYnkgdGhpcyBjbGFzcyBtYXkgaGF2ZSBtZXRob2RzIGFkZGVkIHRvIGl0IGluIHRoZQogKiBmdXR1cmUgdG8gYWNjb21tb2RhdGUgbmV3LCBjdXJyZW50bHkgdW5rbm93biwgbGFuZ3VhZ2Ugc3RydWN0dXJlcwogKiBhZGRlZCB0byBmdXR1cmUgdmVyc2lvbnMgb2YgdGhlIEphdmEmdHJhZGU7IHByb2dyYW1taW5nIGxhbmd1YWdlLgogKiBUaGVyZWZvcmUsIG1ldGhvZHMgd2hvc2UgbmFtZXMgYmVnaW4gd2l0aCB7QGNvZGUgInZpc2l0In0gbWF5IGJlCiAqIGFkZGVkIHRvIHRoaXMgY2xhc3MgaW4gdGhlIGZ1dHVyZTsgdG8gYXZvaWQgaW5jb21wYXRpYmlsaXRpZXMsCiAqIGNsYXNzZXMgd2hpY2ggZXh0ZW5kIHRoaXMgY2xhc3Mgc2hvdWxkIG5vdCBkZWNsYXJlIGFueSBpbnN0YW5jZQogKiBtZXRob2RzIHdpdGggbmFtZXMgYmVnaW5uaW5nIHdpdGgge0Bjb2RlICJ2aXNpdCJ9LgogKgogKiA8cD5XaGVuIHN1Y2ggYSBuZXcgdmlzaXQgbWV0aG9kIGlzIGFkZGVkLCB0aGUgZGVmYXVsdAogKiBpbXBsZW1lbnRhdGlvbiBpbiB0aGlzIGNsYXNzIHdpbGwgYmUgdG8gY2FsbCB0aGUge0BsaW5rCiAqICN2aXNpdFVua25vd24gdmlzaXRVbmtub3dufSBtZXRob2QuICBBIG5ldyBlbGVtZW50IHNjYW5uZXIgdmlzaXRvcgogKiBjbGFzcyB3aWxsIGFsc28gYmUgaW50cm9kdWNlZCB0byBjb3JyZXNwb25kIHRvIHRoZSBuZXcgbGFuZ3VhZ2UKICogbGV2ZWw7IHRoaXMgdmlzaXRvciB3aWxsIGhhdmUgZGlmZmVyZW50IGRlZmF1bHQgYmVoYXZpb3IgZm9yIHRoZQogKiB2aXNpdCBtZXRob2QgaW4gcXVlc3Rpb24uICBXaGVuIHRoZSBuZXcgdmlzaXRvciBpcyBpbnRyb2R1Y2VkLCBhbGwKICogb3IgcG9ydGlvbnMgb2YgdGhpcyB2aXNpdG9yIG1heSBiZSBkZXByZWNhdGVkLgogKgogKiBAcGFyYW0gPFI+IHRoZSByZXR1cm4gdHlwZSBvZiB0aGlzIHZpc2l0b3IncyBtZXRob2RzLiAgVXNlIHtAbGluawogKiAgICAgICAgICAgIFZvaWR9IGZvciB2aXNpdG9ycyB0aGF0IGRvIG5vdCBuZWVkIHRvIHJldHVybiByZXN1bHRzLgogKiBAcGFyYW0gPFA+IHRoZSB0eXBlIG9mIHRoZSBhZGRpdGlvbmFsIHBhcmFtZXRlciB0byB0aGlzIHZpc2l0b3IncwogKiAgICAgICAgICAgIG1ldGhvZHMuICBVc2Uge0Bjb2RlIFZvaWR9IGZvciB2aXNpdG9ycyB0aGF0IGRvIG5vdCBuZWVkIGFuCiAqICAgICAgICAgICAgYWRkaXRpb25hbCBwYXJhbWV0ZXIuCiAqCiAqIEBzZWUgRWxlbWVudFNjYW5uZXI2CiAqIEBzZWUgRWxlbWVudFNjYW5uZXI4CiAqIEBzZWUgRWxlbWVudFNjYW5uZXI5CiAqIEBzaW5jZSAxLjcKICovCkBTdXBwb3J0ZWRTb3VyY2VWZXJzaW9uKFJFTEVBU0VfNykKcHVibGljIGNsYXNzIEVsZW1lbnRTY2FubmVyNzxSLCBQPiBleHRlbmRzIEVsZW1lbnRTY2FubmVyNjxSLCBQPiB7CiAgICAvKioKICAgICAqIENvbnN0cnVjdG9yIGZvciBjb25jcmV0ZSBzdWJjbGFzc2VzOyB1c2VzIHtAY29kZSBudWxsfSBmb3IgdGhlCiAgICAgKiBkZWZhdWx0IHZhbHVlLgogICAgICovCiAgICBAU3VwcHJlc3NXYXJuaW5ncygiZGVwcmVjYXRpb24iKSAvLyBTdXBlcmNsYXNzIGNvbnN0cnVjdG9yIGRlcHJlY2F0ZWQKICAgIHByb3RlY3RlZCBFbGVtZW50U2Nhbm5lcjcoKXsKICAgICAgICBzdXBlcihudWxsKTsKICAgIH0KCiAgICAvKioKICAgICAqIENvbnN0cnVjdG9yIGZvciBjb25jcmV0ZSBzdWJjbGFzc2VzOyB1c2VzIHRoZSBhcmd1bWVudCBmb3IgdGhlCiAgICAgKiBkZWZhdWx0IHZhbHVlLgogICAgICoKICAgICAqIEBwYXJhbSBkZWZhdWx0VmFsdWUgdGhlIGRlZmF1bHQgdmFsdWUKICAgICAqLwogICAgQFN1cHByZXNzV2FybmluZ3MoImRlcHJlY2F0aW9uIikgLy8gU3VwZXJjbGFzcyBjb25zdHJ1Y3RvciBkZXByZWNhdGVkCiAgICBwcm90ZWN0ZWQgRWxlbWVudFNjYW5uZXI3KFIgZGVmYXVsdFZhbHVlKXsKICAgICAgICBzdXBlcihkZWZhdWx0VmFsdWUpOwogICAgfQoKICAgIC8qKgogICAgICogVGhpcyBpbXBsZW1lbnRhdGlvbiBzY2FucyB0aGUgZW5jbG9zZWQgZWxlbWVudHMuCiAgICAgKgogICAgICogQHBhcmFtIGUgIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwICB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuIHRoZSByZXN1bHQgb2Ygc2Nhbm5pbmcKICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgUiB2aXNpdFZhcmlhYmxlKFZhcmlhYmxlRWxlbWVudCBlLCBQIHApIHsKICAgICAgICByZXR1cm4gc2NhbihlLmdldEVuY2xvc2VkRWxlbWVudHMoKSwgcCk7CiAgICB9Cn0KUEsDBAoAAAgAAAY7qUoC1ses7SEAAO0hAAA4AAAAamF2YXgvbGFuZy9tb2RlbC91dGlsL1NpbXBsZUFubm90YXRpb25WYWx1ZVZpc2l0b3I2LmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMTcsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgamF2YXgubGFuZy5tb2RlbC51dGlsOwoKCmltcG9ydCBqYXZhLnV0aWwuTGlzdDsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC4qOwoKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwudHlwZS5UeXBlTWlycm9yOwppbXBvcnQgc3RhdGljIGphdmF4LmxhbmcubW9kZWwuU291cmNlVmVyc2lvbi4qOwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5Tb3VyY2VWZXJzaW9uOwppbXBvcnQgamF2YXguYW5ub3RhdGlvbi5wcm9jZXNzaW5nLlN1cHBvcnRlZFNvdXJjZVZlcnNpb247CgovKioKICogQSBzaW1wbGUgdmlzaXRvciBmb3IgYW5ub3RhdGlvbiB2YWx1ZXMgd2l0aCBkZWZhdWx0IGJlaGF2aW9yCiAqIGFwcHJvcHJpYXRlIGZvciB0aGUge0BsaW5rIFNvdXJjZVZlcnNpb24jUkVMRUFTRV82IFJFTEVBU0VfNn0KICogc291cmNlIHZlcnNpb24uICBWaXNpdCBtZXRob2RzIGNhbGwge0BsaW5rCiAqICNkZWZhdWx0QWN0aW9ufSBwYXNzaW5nIHRoZWlyIGFyZ3VtZW50cyB0byB7QGNvZGUgZGVmYXVsdEFjdGlvbn0ncwogKiBjb3JyZXNwb25kaW5nIHBhcmFtZXRlcnMuCiAqCiAqIDxwPiBNZXRob2RzIGluIHRoaXMgY2xhc3MgbWF5IGJlIG92ZXJyaWRkZW4gc3ViamVjdCB0byB0aGVpcgogKiBnZW5lcmFsIGNvbnRyYWN0LiAgTm90ZSB0aGF0IGFubm90YXRpbmcgbWV0aG9kcyBpbiBjb25jcmV0ZQogKiBzdWJjbGFzc2VzIHdpdGgge0BsaW5rIGphdmEubGFuZy5PdmVycmlkZSBAT3ZlcnJpZGV9IHdpbGwgaGVscAogKiBlbnN1cmUgdGhhdCBtZXRob2RzIGFyZSBvdmVycmlkZGVuIGFzIGludGVuZGVkLgogKgogKiA8cD4gPGI+V0FSTklORzo8L2I+IFRoZSB7QGNvZGUgQW5ub3RhdGlvblZhbHVlVmlzaXRvcn0gaW50ZXJmYWNlCiAqIGltcGxlbWVudGVkIGJ5IHRoaXMgY2xhc3MgbWF5IGhhdmUgbWV0aG9kcyBhZGRlZCB0byBpdCBpbiB0aGUKICogZnV0dXJlIHRvIGFjY29tbW9kYXRlIG5ldywgY3VycmVudGx5IHVua25vd24sIGxhbmd1YWdlIHN0cnVjdHVyZXMKICogYWRkZWQgdG8gZnV0dXJlIHZlcnNpb25zIG9mIHRoZSBKYXZhJnRyYWRlOyBwcm9ncmFtbWluZyBsYW5ndWFnZS4KICogVGhlcmVmb3JlLCBtZXRob2RzIHdob3NlIG5hbWVzIGJlZ2luIHdpdGgge0Bjb2RlICJ2aXNpdCJ9IG1heSBiZQogKiBhZGRlZCB0byB0aGlzIGNsYXNzIGluIHRoZSBmdXR1cmU7IHRvIGF2b2lkIGluY29tcGF0aWJpbGl0aWVzLAogKiBjbGFzc2VzIHdoaWNoIGV4dGVuZCB0aGlzIGNsYXNzIHNob3VsZCBub3QgZGVjbGFyZSBhbnkgaW5zdGFuY2UKICogbWV0aG9kcyB3aXRoIG5hbWVzIGJlZ2lubmluZyB3aXRoIHtAY29kZSAidmlzaXQifS4KICoKICogPHA+V2hlbiBzdWNoIGEgbmV3IHZpc2l0IG1ldGhvZCBpcyBhZGRlZCwgdGhlIGRlZmF1bHQKICogaW1wbGVtZW50YXRpb24gaW4gdGhpcyBjbGFzcyB3aWxsIGJlIHRvIGNhbGwgdGhlIHtAbGluawogKiAjdmlzaXRVbmtub3duIHZpc2l0VW5rbm93bn0gbWV0aG9kLiAgQSBuZXcgc2ltcGxlIGFubm90YXRpb24KICogdmFsdWUgdmlzaXRvciBjbGFzcyB3aWxsIGFsc28gYmUgaW50cm9kdWNlZCB0byBjb3JyZXNwb25kIHRvIHRoZQogKiBuZXcgbGFuZ3VhZ2UgbGV2ZWw7IHRoaXMgdmlzaXRvciB3aWxsIGhhdmUgZGlmZmVyZW50IGRlZmF1bHQKICogYmVoYXZpb3IgZm9yIHRoZSB2aXNpdCBtZXRob2QgaW4gcXVlc3Rpb24uICBXaGVuIHRoZSBuZXcgdmlzaXRvciBpcwogKiBpbnRyb2R1Y2VkLCBhbGwgb3IgcG9ydGlvbnMgb2YgdGhpcyB2aXNpdG9yIG1heSBiZSBkZXByZWNhdGVkLgogKgogKiBAcGFyYW0gPFI+IHRoZSByZXR1cm4gdHlwZSBvZiB0aGlzIHZpc2l0b3IncyBtZXRob2RzCiAqIEBwYXJhbSA8UD4gdGhlIHR5cGUgb2YgdGhlIGFkZGl0aW9uYWwgcGFyYW1ldGVyIHRvIHRoaXMgdmlzaXRvcidzIG1ldGhvZHMuCiAqCiAqIEBhdXRob3IgSm9zZXBoIEQuIERhcmN5CiAqIEBhdXRob3IgU2NvdHQgU2VsaWdtYW4KICogQGF1dGhvciBQZXRlciB2b24gZGVyIEFoJmVhY3V0ZTsKICoKICogQHNlZSBTaW1wbGVBbm5vdGF0aW9uVmFsdWVWaXNpdG9yNwogKiBAc2VlIFNpbXBsZUFubm90YXRpb25WYWx1ZVZpc2l0b3I4CiAqIEBzZWUgU2ltcGxlQW5ub3RhdGlvblZhbHVlVmlzaXRvcjkKICogQHNpbmNlIDEuNgogKi8KQFN1cHBvcnRlZFNvdXJjZVZlcnNpb24oUkVMRUFTRV82KQpwdWJsaWMgY2xhc3MgU2ltcGxlQW5ub3RhdGlvblZhbHVlVmlzaXRvcjY8UiwgUD4KICAgIGV4dGVuZHMgQWJzdHJhY3RBbm5vdGF0aW9uVmFsdWVWaXNpdG9yNjxSLCBQPiB7CgogICAgLyoqCiAgICAgKiBEZWZhdWx0IHZhbHVlIHRvIGJlIHJldHVybmVkOyB7QGxpbmsgI2RlZmF1bHRBY3Rpb24KICAgICAqIGRlZmF1bHRBY3Rpb259IHJldHVybnMgdGhpcyB2YWx1ZSB1bmxlc3MgdGhlIG1ldGhvZCBpcwogICAgICogb3ZlcnJpZGRlbi4KICAgICAqLwogICAgcHJvdGVjdGVkIGZpbmFsIFIgREVGQVVMVF9WQUxVRTsKCiAgICAvKioKICAgICAqIENvbnN0cnVjdG9yIGZvciBjb25jcmV0ZSBzdWJjbGFzc2VzOyB1c2VzIHtAY29kZSBudWxsfSBmb3IgdGhlCiAgICAgKiBkZWZhdWx0IHZhbHVlLgogICAgICogQGRlcHJlY2F0ZWQgUmVsZWFzZSA2IGlzIG9ic29sZXRlOyB1cGRhdGUgdG8gYSB2aXNpdG9yIGZvciBhIG5ld2VyCiAgICAgKiByZWxlYXNlIGxldmVsLgogICAgICovCiAgICBARGVwcmVjYXRlZAogICAgcHJvdGVjdGVkIFNpbXBsZUFubm90YXRpb25WYWx1ZVZpc2l0b3I2KCkgewogICAgICAgIHN1cGVyKCk7CiAgICAgICAgREVGQVVMVF9WQUxVRSA9IG51bGw7CiAgICB9CgogICAgLyoqCiAgICAgKiBDb25zdHJ1Y3RvciBmb3IgY29uY3JldGUgc3ViY2xhc3NlczsgdXNlcyB0aGUgYXJndW1lbnQgZm9yIHRoZQogICAgICogZGVmYXVsdCB2YWx1ZS4KICAgICAqCiAgICAgKiBAcGFyYW0gZGVmYXVsdFZhbHVlIHRoZSB2YWx1ZSB0byBhc3NpZ24gdG8ge0BsaW5rICNERUZBVUxUX1ZBTFVFfQogICAgICogQGRlcHJlY2F0ZWQgUmVsZWFzZSA2IGlzIG9ic29sZXRlOyB1cGRhdGUgdG8gYSB2aXNpdG9yIGZvciBhIG5ld2VyCiAgICAgKiByZWxlYXNlIGxldmVsLgogICAgICovCiAgICBARGVwcmVjYXRlZAogICAgcHJvdGVjdGVkIFNpbXBsZUFubm90YXRpb25WYWx1ZVZpc2l0b3I2KFIgZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgc3VwZXIoKTsKICAgICAgICBERUZBVUxUX1ZBTFVFID0gZGVmYXVsdFZhbHVlOwogICAgfQoKICAgIC8qKgogICAgICogVGhlIGRlZmF1bHQgYWN0aW9uIGZvciB2aXNpdCBtZXRob2RzLiAgVGhlIGltcGxlbWVudGF0aW9uIGluCiAgICAgKiB0aGlzIGNsYXNzIGp1c3QgcmV0dXJucyB7QGxpbmsgI0RFRkFVTFRfVkFMVUV9OyBzdWJjbGFzc2VzIHdpbGwKICAgICAqIGNvbW1vbmx5IG92ZXJyaWRlIHRoaXMgbWV0aG9kLgogICAgICoKICAgICAqIEBwYXJhbSBvIHRoZSB2YWx1ZSBvZiB0aGUgYW5ub3RhdGlvbgogICAgICogQHBhcmFtIHAgYSB2aXNpdG9yLXNwZWNpZmllZCBwYXJhbWV0ZXIKICAgICAqIEByZXR1cm4ge0Bjb2RlIERFRkFVTFRfVkFMVUV9IHVubGVzcyBvdmVycmlkZGVuCiAgICAgKi8KICAgIHByb3RlY3RlZCBSIGRlZmF1bHRBY3Rpb24oT2JqZWN0IG8sIFAgcCkgewogICAgICAgIHJldHVybiBERUZBVUxUX1ZBTFVFOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIGNhbGxzIHtAY29kZSBkZWZhdWx0QWN0aW9ufS4KICAgICAqCiAgICAgKiBAcGFyYW0gYiB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuICB0aGUgcmVzdWx0IG9mIHtAY29kZSBkZWZhdWx0QWN0aW9ufQogICAgICovCiAgICBwdWJsaWMgUiB2aXNpdEJvb2xlYW4oYm9vbGVhbiBiLCBQIHApIHsKICAgICAgICByZXR1cm4gZGVmYXVsdEFjdGlvbihiLCBwKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30gVGhpcyBpbXBsZW1lbnRhdGlvbiBjYWxscyB7QGNvZGUgZGVmYXVsdEFjdGlvbn0uCiAgICAgKgogICAgICogQHBhcmFtIGIge0Bpbmhlcml0RG9jfQogICAgICogQHBhcmFtIHAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiAgdGhlIHJlc3VsdCBvZiB7QGNvZGUgZGVmYXVsdEFjdGlvbn0KICAgICAqLwogICAgcHVibGljIFIgdmlzaXRCeXRlKGJ5dGUgYiwgUCBwKSB7CiAgICAgICAgcmV0dXJuIGRlZmF1bHRBY3Rpb24oYiwgcCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gY2FsbHMge0Bjb2RlIGRlZmF1bHRBY3Rpb259LgogICAgICoKICAgICAqIEBwYXJhbSBjIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gIHRoZSByZXN1bHQgb2Yge0Bjb2RlIGRlZmF1bHRBY3Rpb259CiAgICAgKi8KICAgIHB1YmxpYyBSIHZpc2l0Q2hhcihjaGFyIGMsIFAgcCkgewogICAgICAgIHJldHVybiBkZWZhdWx0QWN0aW9uKGMsIHApOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIGNhbGxzIHtAY29kZSBkZWZhdWx0QWN0aW9ufS4KICAgICAqCiAgICAgKiBAcGFyYW0gZCB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuICB0aGUgcmVzdWx0IG9mIHtAY29kZSBkZWZhdWx0QWN0aW9ufQogICAgICovCiAgICBwdWJsaWMgUiB2aXNpdERvdWJsZShkb3VibGUgZCwgUCBwKSB7CiAgICAgICAgcmV0dXJuIGRlZmF1bHRBY3Rpb24oZCwgcCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gY2FsbHMge0Bjb2RlIGRlZmF1bHRBY3Rpb259LgogICAgICoKICAgICAqIEBwYXJhbSBmIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gIHRoZSByZXN1bHQgb2Yge0Bjb2RlIGRlZmF1bHRBY3Rpb259CiAgICAgKi8KICAgIHB1YmxpYyBSIHZpc2l0RmxvYXQoZmxvYXQgZiwgUCBwKSB7CiAgICAgICAgcmV0dXJuIGRlZmF1bHRBY3Rpb24oZiwgcCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gY2FsbHMge0Bjb2RlIGRlZmF1bHRBY3Rpb259LgogICAgICoKICAgICAqIEBwYXJhbSBpIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gIHRoZSByZXN1bHQgb2Yge0Bjb2RlIGRlZmF1bHRBY3Rpb259CiAgICAgKi8KICAgIHB1YmxpYyBSIHZpc2l0SW50KGludCBpLCBQIHApIHsKICAgICAgICByZXR1cm4gZGVmYXVsdEFjdGlvbihpLCBwKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30gVGhpcyBpbXBsZW1lbnRhdGlvbiBjYWxscyB7QGNvZGUgZGVmYXVsdEFjdGlvbn0uCiAgICAgKgogICAgICogQHBhcmFtIGkge0Bpbmhlcml0RG9jfQogICAgICogQHBhcmFtIHAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiAgdGhlIHJlc3VsdCBvZiB7QGNvZGUgZGVmYXVsdEFjdGlvbn0KICAgICAqLwogICAgcHVibGljIFIgdmlzaXRMb25nKGxvbmcgaSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIGRlZmF1bHRBY3Rpb24oaSwgcCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gY2FsbHMge0Bjb2RlIGRlZmF1bHRBY3Rpb259LgogICAgICoKICAgICAqIEBwYXJhbSBzIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gIHRoZSByZXN1bHQgb2Yge0Bjb2RlIGRlZmF1bHRBY3Rpb259CiAgICAgKi8KICAgIHB1YmxpYyBSIHZpc2l0U2hvcnQoc2hvcnQgcywgUCBwKSB7CiAgICAgICAgcmV0dXJuIGRlZmF1bHRBY3Rpb24ocywgcCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gY2FsbHMge0Bjb2RlIGRlZmF1bHRBY3Rpb259LgogICAgICoKICAgICAqIEBwYXJhbSBzIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gIHRoZSByZXN1bHQgb2Yge0Bjb2RlIGRlZmF1bHRBY3Rpb259CiAgICAgKi8KICAgIHB1YmxpYyBSIHZpc2l0U3RyaW5nKFN0cmluZyBzLCBQIHApIHsKICAgICAgICByZXR1cm4gZGVmYXVsdEFjdGlvbihzLCBwKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30gVGhpcyBpbXBsZW1lbnRhdGlvbiBjYWxscyB7QGNvZGUgZGVmYXVsdEFjdGlvbn0uCiAgICAgKgogICAgICogQHBhcmFtIHQge0Bpbmhlcml0RG9jfQogICAgICogQHBhcmFtIHAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiAgdGhlIHJlc3VsdCBvZiB7QGNvZGUgZGVmYXVsdEFjdGlvbn0KICAgICAqLwogICAgcHVibGljIFIgdmlzaXRUeXBlKFR5cGVNaXJyb3IgdCwgUCBwKSB7CiAgICAgICAgcmV0dXJuIGRlZmF1bHRBY3Rpb24odCwgcCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gY2FsbHMge0Bjb2RlIGRlZmF1bHRBY3Rpb259LgogICAgICoKICAgICAqIEBwYXJhbSBjIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gIHRoZSByZXN1bHQgb2Yge0Bjb2RlIGRlZmF1bHRBY3Rpb259CiAgICAgKi8KICAgIHB1YmxpYyBSIHZpc2l0RW51bUNvbnN0YW50KFZhcmlhYmxlRWxlbWVudCBjLCBQIHApIHsKICAgICAgICByZXR1cm4gZGVmYXVsdEFjdGlvbihjLCBwKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30gVGhpcyBpbXBsZW1lbnRhdGlvbiBjYWxscyB7QGNvZGUgZGVmYXVsdEFjdGlvbn0uCiAgICAgKgogICAgICogQHBhcmFtIGEge0Bpbmhlcml0RG9jfQogICAgICogQHBhcmFtIHAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiAgdGhlIHJlc3VsdCBvZiB7QGNvZGUgZGVmYXVsdEFjdGlvbn0KICAgICAqLwogICAgcHVibGljIFIgdmlzaXRBbm5vdGF0aW9uKEFubm90YXRpb25NaXJyb3IgYSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIGRlZmF1bHRBY3Rpb24oYSwgcCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gY2FsbHMge0Bjb2RlIGRlZmF1bHRBY3Rpb259LgogICAgICoKICAgICAqIEBwYXJhbSB2YWxzIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gIHRoZSByZXN1bHQgb2Yge0Bjb2RlIGRlZmF1bHRBY3Rpb259CiAgICAgKi8KICAgIHB1YmxpYyBSIHZpc2l0QXJyYXkoTGlzdDw/IGV4dGVuZHMgQW5ub3RhdGlvblZhbHVlPiB2YWxzLCBQIHApIHsKICAgICAgICByZXR1cm4gZGVmYXVsdEFjdGlvbih2YWxzLCBwKTsKICAgIH0KfQpQSwMECgAACAAABjupSsbsZBrKDgAAyg4AADgAAABqYXZheC9sYW5nL21vZGVsL3V0aWwvU2ltcGxlQW5ub3RhdGlvblZhbHVlVmlzaXRvcjguamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAxMSwgMjAxNywgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBqYXZheC5sYW5nLm1vZGVsLnV0aWw7CgppbXBvcnQgamF2YXguYW5ub3RhdGlvbi5wcm9jZXNzaW5nLlN1cHBvcnRlZFNvdXJjZVZlcnNpb247CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLlNvdXJjZVZlcnNpb247CmltcG9ydCBzdGF0aWMgamF2YXgubGFuZy5tb2RlbC5Tb3VyY2VWZXJzaW9uLio7CgovKioKICogQSBzaW1wbGUgdmlzaXRvciBmb3IgYW5ub3RhdGlvbiB2YWx1ZXMgd2l0aCBkZWZhdWx0IGJlaGF2aW9yCiAqIGFwcHJvcHJpYXRlIGZvciB0aGUge0BsaW5rIFNvdXJjZVZlcnNpb24jUkVMRUFTRV84IFJFTEVBU0VfOH0KICogc291cmNlIHZlcnNpb24uICBWaXNpdCBtZXRob2RzIGNhbGwge0BsaW5rICNkZWZhdWx0QWN0aW9uCiAqIGRlZmF1bHRBY3Rpb259IHBhc3NpbmcgdGhlaXIgYXJndW1lbnRzIHRvIHtAY29kZSBkZWZhdWx0QWN0aW9ufSdzCiAqIGNvcnJlc3BvbmRpbmcgcGFyYW1ldGVycy4KICoKICogPHA+IE1ldGhvZHMgaW4gdGhpcyBjbGFzcyBtYXkgYmUgb3ZlcnJpZGRlbiBzdWJqZWN0IHRvIHRoZWlyCiAqIGdlbmVyYWwgY29udHJhY3QuICBOb3RlIHRoYXQgYW5ub3RhdGluZyBtZXRob2RzIGluIGNvbmNyZXRlCiAqIHN1YmNsYXNzZXMgd2l0aCB7QGxpbmsgamF2YS5sYW5nLk92ZXJyaWRlIEBPdmVycmlkZX0gd2lsbCBoZWxwCiAqIGVuc3VyZSB0aGF0IG1ldGhvZHMgYXJlIG92ZXJyaWRkZW4gYXMgaW50ZW5kZWQuCiAqCiAqIDxwPiA8Yj5XQVJOSU5HOjwvYj4gVGhlIHtAY29kZSBBbm5vdGF0aW9uVmFsdWVWaXNpdG9yfSBpbnRlcmZhY2UKICogaW1wbGVtZW50ZWQgYnkgdGhpcyBjbGFzcyBtYXkgaGF2ZSBtZXRob2RzIGFkZGVkIHRvIGl0IGluIHRoZQogKiBmdXR1cmUgdG8gYWNjb21tb2RhdGUgbmV3LCBjdXJyZW50bHkgdW5rbm93biwgbGFuZ3VhZ2Ugc3RydWN0dXJlcwogKiBhZGRlZCB0byBmdXR1cmUgdmVyc2lvbnMgb2YgdGhlIEphdmEmdHJhZGU7IHByb2dyYW1taW5nIGxhbmd1YWdlLgogKiBUaGVyZWZvcmUsIG1ldGhvZHMgd2hvc2UgbmFtZXMgYmVnaW4gd2l0aCB7QGNvZGUgInZpc2l0In0gbWF5IGJlCiAqIGFkZGVkIHRvIHRoaXMgY2xhc3MgaW4gdGhlIGZ1dHVyZTsgdG8gYXZvaWQgaW5jb21wYXRpYmlsaXRpZXMsCiAqIGNsYXNzZXMgd2hpY2ggZXh0ZW5kIHRoaXMgY2xhc3Mgc2hvdWxkIG5vdCBkZWNsYXJlIGFueSBpbnN0YW5jZQogKiBtZXRob2RzIHdpdGggbmFtZXMgYmVnaW5uaW5nIHdpdGgge0Bjb2RlICJ2aXNpdCJ9LgogKgogKiA8cD5XaGVuIHN1Y2ggYSBuZXcgdmlzaXQgbWV0aG9kIGlzIGFkZGVkLCB0aGUgZGVmYXVsdAogKiBpbXBsZW1lbnRhdGlvbiBpbiB0aGlzIGNsYXNzIHdpbGwgYmUgdG8gY2FsbCB0aGUge0BsaW5rCiAqICN2aXNpdFVua25vd24gdmlzaXRVbmtub3dufSBtZXRob2QuICBBIG5ldyBzaW1wbGUgYW5ub3RhdGlvbgogKiB2YWx1ZSB2aXNpdG9yIGNsYXNzIHdpbGwgYWxzbyBiZSBpbnRyb2R1Y2VkIHRvIGNvcnJlc3BvbmQgdG8gdGhlCiAqIG5ldyBsYW5ndWFnZSBsZXZlbDsgdGhpcyB2aXNpdG9yIHdpbGwgaGF2ZSBkaWZmZXJlbnQgZGVmYXVsdAogKiBiZWhhdmlvciBmb3IgdGhlIHZpc2l0IG1ldGhvZCBpbiBxdWVzdGlvbi4gIFdoZW4gdGhlIG5ldyB2aXNpdG9yIGlzCiAqIGludHJvZHVjZWQsIGFsbCBvciBwb3J0aW9ucyBvZiB0aGlzIHZpc2l0b3IgbWF5IGJlIGRlcHJlY2F0ZWQuCiAqCiAqIEBwYXJhbSA8Uj4gdGhlIHJldHVybiB0eXBlIG9mIHRoaXMgdmlzaXRvcidzIG1ldGhvZHMKICogQHBhcmFtIDxQPiB0aGUgdHlwZSBvZiB0aGUgYWRkaXRpb25hbCBwYXJhbWV0ZXIgdG8gdGhpcyB2aXNpdG9yJ3MgbWV0aG9kcy4KICoKICogQHNlZSBTaW1wbGVBbm5vdGF0aW9uVmFsdWVWaXNpdG9yNgogKiBAc2VlIFNpbXBsZUFubm90YXRpb25WYWx1ZVZpc2l0b3I3CiAqIEBzZWUgU2ltcGxlQW5ub3RhdGlvblZhbHVlVmlzaXRvcjgKICogQHNpbmNlIDEuOAogKi8KQFN1cHBvcnRlZFNvdXJjZVZlcnNpb24oUkVMRUFTRV84KQpwdWJsaWMgY2xhc3MgU2ltcGxlQW5ub3RhdGlvblZhbHVlVmlzaXRvcjg8UiwgUD4gZXh0ZW5kcyBTaW1wbGVBbm5vdGF0aW9uVmFsdWVWaXNpdG9yNzxSLCBQPiB7CiAgICAvKioKICAgICAqIENvbnN0cnVjdG9yIGZvciBjb25jcmV0ZSBzdWJjbGFzc2VzOyB1c2VzIHtAY29kZSBudWxsfSBmb3IgdGhlCiAgICAgKiBkZWZhdWx0IHZhbHVlLgogICAgICovCiAgICBwcm90ZWN0ZWQgU2ltcGxlQW5ub3RhdGlvblZhbHVlVmlzaXRvcjgoKSB7CiAgICAgICAgc3VwZXIobnVsbCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDb25zdHJ1Y3RvciBmb3IgY29uY3JldGUgc3ViY2xhc3NlczsgdXNlcyB0aGUgYXJndW1lbnQgZm9yIHRoZQogICAgICogZGVmYXVsdCB2YWx1ZS4KICAgICAqCiAgICAgKiBAcGFyYW0gZGVmYXVsdFZhbHVlIHRoZSB2YWx1ZSB0byBhc3NpZ24gdG8ge0BsaW5rICNERUZBVUxUX1ZBTFVFfQogICAgICovCiAgICBwcm90ZWN0ZWQgU2ltcGxlQW5ub3RhdGlvblZhbHVlVmlzaXRvcjgoUiBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBzdXBlcihkZWZhdWx0VmFsdWUpOwogICAgfQp9ClBLAwQKAAAIAAAGO6lKGzdlbNIRAADSEQAAKwAAAGphdmF4L2xhbmcvbW9kZWwvdXRpbC9UeXBlS2luZFZpc2l0b3I4LmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTEsIDIwMTcsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgamF2YXgubGFuZy5tb2RlbC51dGlsOwoKaW1wb3J0IGphdmF4LmFubm90YXRpb24ucHJvY2Vzc2luZy5TdXBwb3J0ZWRTb3VyY2VWZXJzaW9uOwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5Tb3VyY2VWZXJzaW9uOwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC50eXBlLio7CmltcG9ydCBzdGF0aWMgamF2YXgubGFuZy5tb2RlbC5Tb3VyY2VWZXJzaW9uLio7CgovKioKICogQSB2aXNpdG9yIG9mIHR5cGVzIGJhc2VkIG9uIHRoZWlyIHtAbGlua3BsYWluIFR5cGVLaW5kIGtpbmR9IHdpdGgKICogZGVmYXVsdCBiZWhhdmlvciBhcHByb3ByaWF0ZSBmb3IgdGhlIHtAbGluayBTb3VyY2VWZXJzaW9uI1JFTEVBU0VfOAogKiBSRUxFQVNFXzh9IHNvdXJjZSB2ZXJzaW9uLiAgRm9yIHtAbGlua3BsYWluCiAqIFR5cGVNaXJyb3IgdHlwZXN9IDxjb2RlPjxpPlh5ejwvaT48L2NvZGU+IHRoYXQgbWF5IGhhdmUgbW9yZSB0aGFuIG9uZQogKiBraW5kLCB0aGUgPGNvZGU+dmlzaXQ8aT5YeXo8L2k+PC9jb2RlPiBtZXRob2RzIGluIHRoaXMgY2xhc3MgZGVsZWdhdGUKICogdG8gdGhlIDxjb2RlPnZpc2l0PGk+WHl6PC9pPkFzPGk+S2luZDwvaT48L2NvZGU+IG1ldGhvZCBjb3JyZXNwb25kaW5nIHRvIHRoZQogKiBmaXJzdCBhcmd1bWVudCdzIGtpbmQuICBUaGUgPGNvZGU+dmlzaXQ8aT5YeXo8L2k+QXM8aT5LaW5kPC9pPjwvY29kZT4gbWV0aG9kcwogKiBjYWxsIHtAbGluayAjZGVmYXVsdEFjdGlvbiBkZWZhdWx0QWN0aW9ufSwgcGFzc2luZyB0aGVpciBhcmd1bWVudHMKICogdG8ge0Bjb2RlIGRlZmF1bHRBY3Rpb259J3MgY29ycmVzcG9uZGluZyBwYXJhbWV0ZXJzLgogKgogKiA8cD4gTWV0aG9kcyBpbiB0aGlzIGNsYXNzIG1heSBiZSBvdmVycmlkZGVuIHN1YmplY3QgdG8gdGhlaXIKICogZ2VuZXJhbCBjb250cmFjdC4gIE5vdGUgdGhhdCBhbm5vdGF0aW5nIG1ldGhvZHMgaW4gY29uY3JldGUKICogc3ViY2xhc3NlcyB3aXRoIHtAbGluayBqYXZhLmxhbmcuT3ZlcnJpZGUgQE92ZXJyaWRlfSB3aWxsIGhlbHAKICogZW5zdXJlIHRoYXQgbWV0aG9kcyBhcmUgb3ZlcnJpZGRlbiBhcyBpbnRlbmRlZC4KICoKICogPHA+IDxiPldBUk5JTkc6PC9iPiBUaGUge0Bjb2RlIFR5cGVWaXNpdG9yfSBpbnRlcmZhY2UgaW1wbGVtZW50ZWQKICogYnkgdGhpcyBjbGFzcyBtYXkgaGF2ZSBtZXRob2RzIGFkZGVkIHRvIGl0IGluIHRoZSBmdXR1cmUgdG8KICogYWNjb21tb2RhdGUgbmV3LCBjdXJyZW50bHkgdW5rbm93biwgbGFuZ3VhZ2Ugc3RydWN0dXJlcyBhZGRlZCB0bwogKiBmdXR1cmUgdmVyc2lvbnMgb2YgdGhlIEphdmEmdHJhZGU7IHByb2dyYW1taW5nIGxhbmd1YWdlLgogKiBUaGVyZWZvcmUsIG1ldGhvZHMgd2hvc2UgbmFtZXMgYmVnaW4gd2l0aCB7QGNvZGUgInZpc2l0In0gbWF5IGJlCiAqIGFkZGVkIHRvIHRoaXMgY2xhc3MgaW4gdGhlIGZ1dHVyZTsgdG8gYXZvaWQgaW5jb21wYXRpYmlsaXRpZXMsCiAqIGNsYXNzZXMgd2hpY2ggZXh0ZW5kIHRoaXMgY2xhc3Mgc2hvdWxkIG5vdCBkZWNsYXJlIGFueSBpbnN0YW5jZQogKiBtZXRob2RzIHdpdGggbmFtZXMgYmVnaW5uaW5nIHdpdGgge0Bjb2RlICJ2aXNpdCJ9LgogKgogKiA8cD5XaGVuIHN1Y2ggYSBuZXcgdmlzaXQgbWV0aG9kIGlzIGFkZGVkLCB0aGUgZGVmYXVsdAogKiBpbXBsZW1lbnRhdGlvbiBpbiB0aGlzIGNsYXNzIHdpbGwgYmUgdG8gY2FsbCB0aGUge0BsaW5rCiAqICN2aXNpdFVua25vd24gdmlzaXRVbmtub3dufSBtZXRob2QuICBBIG5ldyB0eXBlIGtpbmQgdmlzaXRvciBjbGFzcwogKiB3aWxsIGFsc28gYmUgaW50cm9kdWNlZCB0byBjb3JyZXNwb25kIHRvIHRoZSBuZXcgbGFuZ3VhZ2UgbGV2ZWw7CiAqIHRoaXMgdmlzaXRvciB3aWxsIGhhdmUgZGlmZmVyZW50IGRlZmF1bHQgYmVoYXZpb3IgZm9yIHRoZSB2aXNpdAogKiBtZXRob2QgaW4gcXVlc3Rpb24uICBXaGVuIHRoZSBuZXcgdmlzaXRvciBpcyBpbnRyb2R1Y2VkLCBhbGwgb3IKICogcG9ydGlvbnMgb2YgdGhpcyB2aXNpdG9yIG1heSBiZSBkZXByZWNhdGVkLgogKgogKiBAcGFyYW0gPFI+IHRoZSByZXR1cm4gdHlwZSBvZiB0aGlzIHZpc2l0b3IncyBtZXRob2RzLiAgVXNlIHtAbGluawogKiAgICAgICAgICAgIFZvaWR9IGZvciB2aXNpdG9ycyB0aGF0IGRvIG5vdCBuZWVkIHRvIHJldHVybiByZXN1bHRzLgogKiBAcGFyYW0gPFA+IHRoZSB0eXBlIG9mIHRoZSBhZGRpdGlvbmFsIHBhcmFtZXRlciB0byB0aGlzIHZpc2l0b3IncwogKiAgICAgICAgICAgIG1ldGhvZHMuICBVc2Uge0Bjb2RlIFZvaWR9IGZvciB2aXNpdG9ycyB0aGF0IGRvIG5vdCBuZWVkIGFuCiAqICAgICAgICAgICAgYWRkaXRpb25hbCBwYXJhbWV0ZXIuCiAqCiAqIEBzZWUgVHlwZUtpbmRWaXNpdG9yNgogKiBAc2VlIFR5cGVLaW5kVmlzaXRvcjcKICogQHNpbmNlIDEuOAogKi8KQFN1cHBvcnRlZFNvdXJjZVZlcnNpb24oUkVMRUFTRV84KQpwdWJsaWMgY2xhc3MgVHlwZUtpbmRWaXNpdG9yODxSLCBQPiBleHRlbmRzIFR5cGVLaW5kVmlzaXRvcjc8UiwgUD4gewogICAgLyoqCiAgICAgKiBDb25zdHJ1Y3RvciBmb3IgY29uY3JldGUgc3ViY2xhc3NlcyB0byBjYWxsOyB1c2VzIHtAY29kZSBudWxsfQogICAgICogZm9yIHRoZSBkZWZhdWx0IHZhbHVlLgogICAgICovCiAgICBwcm90ZWN0ZWQgVHlwZUtpbmRWaXNpdG9yOCgpIHsKICAgICAgICBzdXBlcihudWxsKTsKICAgIH0KCiAgICAvKioKICAgICAqIENvbnN0cnVjdG9yIGZvciBjb25jcmV0ZSBzdWJjbGFzc2VzIHRvIGNhbGw7IHVzZXMgdGhlIGFyZ3VtZW50CiAgICAgKiBmb3IgdGhlIGRlZmF1bHQgdmFsdWUuCiAgICAgKgogICAgICogQHBhcmFtIGRlZmF1bHRWYWx1ZSB0aGUgdmFsdWUgdG8gYXNzaWduIHRvIHtAbGluayAjREVGQVVMVF9WQUxVRX0KICAgICAqLwogICAgcHJvdGVjdGVkIFR5cGVLaW5kVmlzaXRvcjgoUiBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBzdXBlcihkZWZhdWx0VmFsdWUpOwogICAgfQoKICAgIC8qKgogICAgICogVGhpcyBpbXBsZW1lbnRhdGlvbiB2aXNpdHMgYW4ge0Bjb2RlIEludGVyc2VjdGlvblR5cGV9IGJ5IGNhbGxpbmcKICAgICAqIHtAY29kZSBkZWZhdWx0QWN0aW9ufS4KICAgICAqCiAgICAgKiBAcGFyYW0gdCAge0Bpbmhlcml0RG9jfQogICAgICogQHBhcmFtIHAgIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gdGhlIHJlc3VsdCBvZiB7QGNvZGUgZGVmYXVsdEFjdGlvbn0KICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgUiB2aXNpdEludGVyc2VjdGlvbihJbnRlcnNlY3Rpb25UeXBlIHQsIFAgcCkgewogICAgICAgIHJldHVybiBkZWZhdWx0QWN0aW9uKHQsIHApOwogICAgfQp9ClBLAwQKAAAIAAAGO6lK2cvyXV4PAABeDwAAOAAAAGphdmF4L2xhbmcvbW9kZWwvdXRpbC9TaW1wbGVBbm5vdGF0aW9uVmFsdWVWaXNpdG9yNy5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDEwLCAyMDE3LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGphdmF4LmxhbmcubW9kZWwudXRpbDsKCmltcG9ydCBqYXZheC5hbm5vdGF0aW9uLnByb2Nlc3NpbmcuU3VwcG9ydGVkU291cmNlVmVyc2lvbjsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuU291cmNlVmVyc2lvbjsKaW1wb3J0IHN0YXRpYyBqYXZheC5sYW5nLm1vZGVsLlNvdXJjZVZlcnNpb24uKjsKCi8qKgogKiBBIHNpbXBsZSB2aXNpdG9yIGZvciBhbm5vdGF0aW9uIHZhbHVlcyB3aXRoIGRlZmF1bHQgYmVoYXZpb3IKICogYXBwcm9wcmlhdGUgZm9yIHRoZSB7QGxpbmsgU291cmNlVmVyc2lvbiNSRUxFQVNFXzcgUkVMRUFTRV83fQogKiBzb3VyY2UgdmVyc2lvbi4gIFZpc2l0IG1ldGhvZHMgY2FsbCB7QGxpbmsgI2RlZmF1bHRBY3Rpb24KICogZGVmYXVsdEFjdGlvbn0gcGFzc2luZyB0aGVpciBhcmd1bWVudHMgdG8ge0Bjb2RlIGRlZmF1bHRBY3Rpb259J3MKICogY29ycmVzcG9uZGluZyBwYXJhbWV0ZXJzLgogKgogKiA8cD4gTWV0aG9kcyBpbiB0aGlzIGNsYXNzIG1heSBiZSBvdmVycmlkZGVuIHN1YmplY3QgdG8gdGhlaXIKICogZ2VuZXJhbCBjb250cmFjdC4gIE5vdGUgdGhhdCBhbm5vdGF0aW5nIG1ldGhvZHMgaW4gY29uY3JldGUKICogc3ViY2xhc3NlcyB3aXRoIHtAbGluayBqYXZhLmxhbmcuT3ZlcnJpZGUgQE92ZXJyaWRlfSB3aWxsIGhlbHAKICogZW5zdXJlIHRoYXQgbWV0aG9kcyBhcmUgb3ZlcnJpZGRlbiBhcyBpbnRlbmRlZC4KICoKICogPHA+IDxiPldBUk5JTkc6PC9iPiBUaGUge0Bjb2RlIEFubm90YXRpb25WYWx1ZVZpc2l0b3J9IGludGVyZmFjZQogKiBpbXBsZW1lbnRlZCBieSB0aGlzIGNsYXNzIG1heSBoYXZlIG1ldGhvZHMgYWRkZWQgdG8gaXQgaW4gdGhlCiAqIGZ1dHVyZSB0byBhY2NvbW1vZGF0ZSBuZXcsIGN1cnJlbnRseSB1bmtub3duLCBsYW5ndWFnZSBzdHJ1Y3R1cmVzCiAqIGFkZGVkIHRvIGZ1dHVyZSB2ZXJzaW9ucyBvZiB0aGUgSmF2YSZ0cmFkZTsgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2UuCiAqIFRoZXJlZm9yZSwgbWV0aG9kcyB3aG9zZSBuYW1lcyBiZWdpbiB3aXRoIHtAY29kZSAidmlzaXQifSBtYXkgYmUKICogYWRkZWQgdG8gdGhpcyBjbGFzcyBpbiB0aGUgZnV0dXJlOyB0byBhdm9pZCBpbmNvbXBhdGliaWxpdGllcywKICogY2xhc3NlcyB3aGljaCBleHRlbmQgdGhpcyBjbGFzcyBzaG91bGQgbm90IGRlY2xhcmUgYW55IGluc3RhbmNlCiAqIG1ldGhvZHMgd2l0aCBuYW1lcyBiZWdpbm5pbmcgd2l0aCB7QGNvZGUgInZpc2l0In0uCiAqCiAqIDxwPldoZW4gc3VjaCBhIG5ldyB2aXNpdCBtZXRob2QgaXMgYWRkZWQsIHRoZSBkZWZhdWx0CiAqIGltcGxlbWVudGF0aW9uIGluIHRoaXMgY2xhc3Mgd2lsbCBiZSB0byBjYWxsIHRoZSB7QGxpbmsKICogI3Zpc2l0VW5rbm93biB2aXNpdFVua25vd259IG1ldGhvZC4gIEEgbmV3IHNpbXBsZSBhbm5vdGF0aW9uCiAqIHZhbHVlIHZpc2l0b3IgY2xhc3Mgd2lsbCBhbHNvIGJlIGludHJvZHVjZWQgdG8gY29ycmVzcG9uZCB0byB0aGUKICogbmV3IGxhbmd1YWdlIGxldmVsOyB0aGlzIHZpc2l0b3Igd2lsbCBoYXZlIGRpZmZlcmVudCBkZWZhdWx0CiAqIGJlaGF2aW9yIGZvciB0aGUgdmlzaXQgbWV0aG9kIGluIHF1ZXN0aW9uLiAgV2hlbiB0aGUgbmV3IHZpc2l0b3IgaXMKICogaW50cm9kdWNlZCwgYWxsIG9yIHBvcnRpb25zIG9mIHRoaXMgdmlzaXRvciBtYXkgYmUgZGVwcmVjYXRlZC4KICoKICogQHBhcmFtIDxSPiB0aGUgcmV0dXJuIHR5cGUgb2YgdGhpcyB2aXNpdG9yJ3MgbWV0aG9kcwogKiBAcGFyYW0gPFA+IHRoZSB0eXBlIG9mIHRoZSBhZGRpdGlvbmFsIHBhcmFtZXRlciB0byB0aGlzIHZpc2l0b3IncyBtZXRob2RzLgogKgogKiBAc2VlIFNpbXBsZUFubm90YXRpb25WYWx1ZVZpc2l0b3I2CiAqIEBzZWUgU2ltcGxlQW5ub3RhdGlvblZhbHVlVmlzaXRvcjgKICogQHNlZSBTaW1wbGVBbm5vdGF0aW9uVmFsdWVWaXNpdG9yOQogKiBAc2luY2UgMS43CiAqLwpAU3VwcG9ydGVkU291cmNlVmVyc2lvbihSRUxFQVNFXzcpCnB1YmxpYyBjbGFzcyBTaW1wbGVBbm5vdGF0aW9uVmFsdWVWaXNpdG9yNzxSLCBQPiBleHRlbmRzIFNpbXBsZUFubm90YXRpb25WYWx1ZVZpc2l0b3I2PFIsIFA+IHsKICAgIC8qKgogICAgICogQ29uc3RydWN0b3IgZm9yIGNvbmNyZXRlIHN1YmNsYXNzZXM7IHVzZXMge0Bjb2RlIG51bGx9IGZvciB0aGUKICAgICAqIGRlZmF1bHQgdmFsdWUuCiAgICAgKi8KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJkZXByZWNhdGlvbiIpIC8vIFN1cGVyY2xhc3MgY29uc3RydWN0b3IgZGVwcmVjYXRlZAogICAgcHJvdGVjdGVkIFNpbXBsZUFubm90YXRpb25WYWx1ZVZpc2l0b3I3KCkgewogICAgICAgIHN1cGVyKG51bGwpOwogICAgfQoKICAgIC8qKgogICAgICogQ29uc3RydWN0b3IgZm9yIGNvbmNyZXRlIHN1YmNsYXNzZXM7IHVzZXMgdGhlIGFyZ3VtZW50IGZvciB0aGUKICAgICAqIGRlZmF1bHQgdmFsdWUuCiAgICAgKgogICAgICogQHBhcmFtIGRlZmF1bHRWYWx1ZSB0aGUgdmFsdWUgdG8gYXNzaWduIHRvIHtAbGluayAjREVGQVVMVF9WQUxVRX0KICAgICAqLwogICAgQFN1cHByZXNzV2FybmluZ3MoImRlcHJlY2F0aW9uIikgLy8gU3VwZXJjbGFzcyBjb25zdHJ1Y3RvciBkZXByZWNhdGVkCiAgICBwcm90ZWN0ZWQgU2ltcGxlQW5ub3RhdGlvblZhbHVlVmlzaXRvcjcoUiBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBzdXBlcihkZWZhdWx0VmFsdWUpOwogICAgfQp9ClBLAwQKAAAIAAAGO6lKgvn7ZLleAAC5XgAAIwAAAGphdmF4L2xhbmcvbW9kZWwvdXRpbC9FbGVtZW50cy5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDA1LCAyMDE3LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGphdmF4LmxhbmcubW9kZWwudXRpbDsKCmltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OwppbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOwppbXBvcnQgamF2YS51dGlsLkxpc3Q7CmltcG9ydCBqYXZhLnV0aWwuTWFwOwppbXBvcnQgamF2YS51dGlsLlNldDsKaW1wb3J0IGphdmEudXRpbC5MaW5rZWRIYXNoU2V0OwoKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuQW5ub3RhdGVkQ29uc3RydWN0OwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5lbGVtZW50Lio7CgoKLyoqCiAqIFV0aWxpdHkgbWV0aG9kcyBmb3Igb3BlcmF0aW5nIG9uIHByb2dyYW0gZWxlbWVudHMuCiAqCiAqIDxwPjxiPkNvbXBhdGliaWxpdHkgTm90ZTo8L2I+IE1ldGhvZHMgbWF5IGJlIGFkZGVkIHRvIHRoaXMgaW50ZXJmYWNlCiAqIGluIGZ1dHVyZSByZWxlYXNlcyBvZiB0aGUgcGxhdGZvcm0uCiAqCiAqIEBhdXRob3IgSm9zZXBoIEQuIERhcmN5CiAqIEBhdXRob3IgU2NvdHQgU2VsaWdtYW4KICogQGF1dGhvciBQZXRlciB2b24gZGVyIEFoJmVhY3V0ZTsKICogQHNlZSBqYXZheC5hbm5vdGF0aW9uLnByb2Nlc3NpbmcuUHJvY2Vzc2luZ0Vudmlyb25tZW50I2dldEVsZW1lbnRVdGlscwogKiBAc2luY2UgMS42CiAqLwpwdWJsaWMgaW50ZXJmYWNlIEVsZW1lbnRzIHsKCiAgICAvKioKICAgICAqIFJldHVybnMgYSBwYWNrYWdlIGdpdmVuIGl0cyBmdWxseSBxdWFsaWZpZWQgbmFtZSBpZiB0aGUgcGFja2FnZSBpcyB1bmlxdWUgaW4gdGhlIGVudmlyb25tZW50LgogICAgICogSWYgcnVubmluZyB3aXRoIG1vZHVsZXMsIGFsbCBtb2R1bGVzIGluIHRoZSBtb2R1bGVzIGdyYXBoIGFyZSBzZWFyY2hlZCBmb3IgbWF0Y2hpbmcgcGFja2FnZXMuCiAgICAgKgogICAgICogQHBhcmFtIG5hbWUgIGZ1bGx5IHF1YWxpZmllZCBwYWNrYWdlIG5hbWUsIG9yIGFuIGVtcHR5IHN0cmluZyBmb3IgYW4gdW5uYW1lZCBwYWNrYWdlCiAgICAgKiBAcmV0dXJuIHRoZSBzcGVjaWZpZWQgcGFja2FnZSwgb3Ige0Bjb2RlIG51bGx9IGlmIGl0IGNhbm5vdCBiZSB1bmlxdWVseSBmb3VuZAogICAgICovCiAgICBQYWNrYWdlRWxlbWVudCBnZXRQYWNrYWdlRWxlbWVudChDaGFyU2VxdWVuY2UgbmFtZSk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgcGFja2FnZSBnaXZlbiBpdHMgZnVsbHkgcXVhbGlmaWVkIG5hbWUsIGFzIHNlZW4gZnJvbSB0aGUgZ2l2ZW4gbW9kdWxlLgogICAgICoKICAgICAqIEBpbXBsU3BlYyBUaGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGlzIG1ldGhvZCByZXR1cm5zCiAgICAgKiB7QGNvZGUgbnVsbH0uCiAgICAgKgogICAgICogQHBhcmFtIG5hbWUgIGZ1bGx5IHF1YWxpZmllZCBwYWNrYWdlIG5hbWUsIG9yIGFuIGVtcHR5IHN0cmluZyBmb3IgYW4gdW5uYW1lZCBwYWNrYWdlCiAgICAgKiBAcGFyYW0gbW9kdWxlIG1vZHVsZSByZWxhdGl2ZSB0byB3aGljaCB0aGUgbG9va3VwIHNob3VsZCBoYXBwZW4KICAgICAqIEByZXR1cm4gdGhlIHNwZWNpZmllZCBwYWNrYWdlLCBvciB7QGNvZGUgbnVsbH0gaWYgaXQgY2Fubm90IGJlIGZvdW5kCiAgICAgKiBAc2VlICNnZXRBbGxQYWNrYWdlRWxlbWVudHMKICAgICAqIEBzaW5jZSA5CiAgICAgKi8KICAgIGRlZmF1bHQgUGFja2FnZUVsZW1lbnQgZ2V0UGFja2FnZUVsZW1lbnQoTW9kdWxlRWxlbWVudCBtb2R1bGUsIENoYXJTZXF1ZW5jZSBuYW1lKSB7CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGFsbCBwYWNrYWdlIGVsZW1lbnRzIHdpdGggdGhlIGdpdmVuIGNhbm9uaWNhbCBuYW1lLgogICAgICoKICAgICAqIFRoZXJlIG1heSBiZSBtb3JlIHRoYW4gb25lIHBhY2thZ2UgZWxlbWVudCB3aXRoIHRoZSBzYW1lIGNhbm9uaWNhbAogICAgICogbmFtZSBpZiB0aGUgcGFja2FnZSBlbGVtZW50cyBhcmUgaW4gZGlmZmVyZW50IG1vZHVsZXMuCiAgICAgKgogICAgICogQGltcGxTcGVjIFRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIG9mIHRoaXMgbWV0aG9kIGNhbGxzCiAgICAgKiB7QGxpbmsgI2dldEFsbE1vZHVsZUVsZW1lbnRzKCkgZ2V0QWxsTW9kdWxlRWxlbWVudHN9IGFuZCBzdG9yZXMKICAgICAqIHRoZSByZXN1bHQuIElmIHRoZSBzZXQgb2YgbW9kdWxlcyBpcyBlbXB0eSwge0BsaW5rCiAgICAgKiAjZ2V0UGFja2FnZUVsZW1lbnQoQ2hhclNlcXVlbmNlKSBnZXRQYWNrYWdlRWxlbWVudChuYW1lKX0gaXMKICAgICAqIGNhbGxlZCBwYXNzaW5nIHRocm91Z2ggdGhlIG5hbWUgYXJndW1lbnQuIElmIHtAY29kZQogICAgICogZ2V0UGFja2FnZUVsZW1lbnQobmFtZSl9IGlzIHtAY29kZSBudWxsfSwgYW4gZW1wdHkgc2V0IG9mCiAgICAgKiBwYWNrYWdlIGVsZW1lbnRzIGlzIHJldHVybmVkOyBvdGhlcndpc2UsIGEgc2luZ2xlLWVsZW1lbnQgc2V0CiAgICAgKiB3aXRoIHRoZSBmb3VuZCBwYWNrYWdlIGVsZW1lbnQgaXMgcmV0dXJuZWQuIElmIHRoZSBzZXQgb2YKICAgICAqIG1vZHVsZXMgaXMgbm9uZW1wdHksIHRoZSBtb2R1bGVzIGFyZSBpdGVyYXRlZCBvdmVyIGFuZCBhbnkKICAgICAqIG5vbi17QGNvZGUgbnVsbH0gcmVzdWx0cyBvZiB7QGxpbmsKICAgICAqICNnZXRQYWNrYWdlRWxlbWVudChNb2R1bGVFbGVtZW50LCBDaGFyU2VxdWVuY2UpCiAgICAgKiBnZXRQYWNrYWdlRWxlbWVudChtb2R1bGUsIG5hbWUpfSBhcmUgYWNjdW11bGF0ZWQgaW50byBhCiAgICAgKiBzZXQuIFRoZSBzZXQgaXMgdGhlbiByZXR1cm5lZC4KICAgICAqCiAgICAgKiBAcGFyYW0gbmFtZSAgdGhlIGNhbm9uaWNhbCBuYW1lCiAgICAgKiBAcmV0dXJuIHRoZSBwYWNrYWdlIGVsZW1lbnRzLCBvciBhbiBlbXB0eSBzZXQgaWYgbm8gcGFja2FnZSB3aXRoIHRoZSBuYW1lIGNhbiBiZSBmb3VuZAogICAgICogQHNlZSAjZ2V0UGFja2FnZUVsZW1lbnQoTW9kdWxlRWxlbWVudCwgQ2hhclNlcXVlbmNlKQogICAgICogQHNpbmNlIDkKICAgICAqLwogICAgZGVmYXVsdCBTZXQ8PyBleHRlbmRzIFBhY2thZ2VFbGVtZW50PiBnZXRBbGxQYWNrYWdlRWxlbWVudHMoQ2hhclNlcXVlbmNlIG5hbWUpIHsKICAgICAgICBTZXQ8PyBleHRlbmRzIE1vZHVsZUVsZW1lbnQ+IG1vZHVsZXMgPSBnZXRBbGxNb2R1bGVFbGVtZW50cygpOwogICAgICAgIGlmIChtb2R1bGVzLmlzRW1wdHkoKSkgewogICAgICAgICAgICBQYWNrYWdlRWxlbWVudCBwYWNrYWdlRWx0ID0gZ2V0UGFja2FnZUVsZW1lbnQobmFtZSk7CiAgICAgICAgICAgIHJldHVybiAocGFja2FnZUVsdCAhPSBudWxsKSA/CiAgICAgICAgICAgICAgICBDb2xsZWN0aW9ucy5zaW5nbGV0b24ocGFja2FnZUVsdCk6CiAgICAgICAgICAgICAgICBDb2xsZWN0aW9ucy5lbXB0eVNldCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIFNldDxQYWNrYWdlRWxlbWVudD4gcmVzdWx0ID0gbmV3IExpbmtlZEhhc2hTZXQ8PigxKTsgLy8gVXN1YWxseSBleHBlY3QgYXQgbW9zdCAxIHJlc3VsdAogICAgICAgICAgICBmb3IgKE1vZHVsZUVsZW1lbnQgbW9kdWxlOiBtb2R1bGVzKSB7CiAgICAgICAgICAgICAgICBQYWNrYWdlRWxlbWVudCBwYWNrYWdlRWx0ID0gZ2V0UGFja2FnZUVsZW1lbnQobW9kdWxlLCBuYW1lKTsKICAgICAgICAgICAgICAgIGlmIChwYWNrYWdlRWx0ICE9IG51bGwpCiAgICAgICAgICAgICAgICAgICAgcmVzdWx0LmFkZChwYWNrYWdlRWx0KTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlU2V0KHJlc3VsdCk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyBhIHR5cGUgZWxlbWVudCBnaXZlbiBpdHMgY2Fub25pY2FsIG5hbWUgaWYgdGhlIHR5cGUgZWxlbWVudCBpcyB1bmlxdWUgaW4gdGhlIGVudmlyb25tZW50LgogICAgICogSWYgcnVubmluZyB3aXRoIG1vZHVsZXMsIGFsbCBtb2R1bGVzIGluIHRoZSBtb2R1bGVzIGdyYXBoIGFyZSBzZWFyY2hlZCBmb3IgbWF0Y2hpbmcKICAgICAqIHR5cGUgZWxlbWVudHMuCiAgICAgKgogICAgICogQHBhcmFtIG5hbWUgIHRoZSBjYW5vbmljYWwgbmFtZQogICAgICogQHJldHVybiB0aGUgbmFtZWQgdHlwZSBlbGVtZW50LCBvciB7QGNvZGUgbnVsbH0gaWYgaXQgY2Fubm90IGJlIHVuaXF1ZWx5IGZvdW5kCiAgICAgKi8KICAgIFR5cGVFbGVtZW50IGdldFR5cGVFbGVtZW50KENoYXJTZXF1ZW5jZSBuYW1lKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgYSB0eXBlIGVsZW1lbnQgZ2l2ZW4gaXRzIGNhbm9uaWNhbCBuYW1lLCBhcyBzZWVuIGZyb20gdGhlIGdpdmVuIG1vZHVsZS4KICAgICAqCiAgICAgKiBAaW1wbFNwZWMgVGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gb2YgdGhpcyBtZXRob2QgcmV0dXJucwogICAgICoge0Bjb2RlIG51bGx9LgogICAgICoKICAgICAqIEBwYXJhbSBuYW1lICB0aGUgY2Fub25pY2FsIG5hbWUKICAgICAqIEBwYXJhbSBtb2R1bGUgbW9kdWxlIHJlbGF0aXZlIHRvIHdoaWNoIHRoZSBsb29rdXAgc2hvdWxkIGhhcHBlbgogICAgICogQHJldHVybiB0aGUgbmFtZWQgdHlwZSBlbGVtZW50LCBvciB7QGNvZGUgbnVsbH0gaWYgaXQgY2Fubm90IGJlIGZvdW5kCiAgICAgKiBAc2VlICNnZXRBbGxUeXBlRWxlbWVudHMKICAgICAqIEBzaW5jZSA5CiAgICAgKi8KICAgIGRlZmF1bHQgVHlwZUVsZW1lbnQgZ2V0VHlwZUVsZW1lbnQoTW9kdWxlRWxlbWVudCBtb2R1bGUsIENoYXJTZXF1ZW5jZSBuYW1lKSB7CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGFsbCB0eXBlIGVsZW1lbnRzIHdpdGggdGhlIGdpdmVuIGNhbm9uaWNhbCBuYW1lLgogICAgICoKICAgICAqIFRoZXJlIG1heSBiZSBtb3JlIHRoYW4gb25lIHR5cGUgZWxlbWVudCB3aXRoIHRoZSBzYW1lIGNhbm9uaWNhbAogICAgICogbmFtZSBpZiB0aGUgdHlwZSBlbGVtZW50cyBhcmUgaW4gZGlmZmVyZW50IG1vZHVsZXMuCiAgICAgKgogICAgICogQGltcGxTcGVjIFRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIG9mIHRoaXMgbWV0aG9kIGNhbGxzCiAgICAgKiB7QGxpbmsgI2dldEFsbE1vZHVsZUVsZW1lbnRzKCkgZ2V0QWxsTW9kdWxlRWxlbWVudHN9IGFuZCBzdG9yZXMKICAgICAqIHRoZSByZXN1bHQuIElmIHRoZSBzZXQgb2YgbW9kdWxlcyBpcyBlbXB0eSwge0BsaW5rCiAgICAgKiAjZ2V0VHlwZUVsZW1lbnQoQ2hhclNlcXVlbmNlKSBnZXRUeXBlRWxlbWVudChuYW1lKX0gaXMgY2FsbGVkCiAgICAgKiBwYXNzaW5nIHRocm91Z2ggdGhlIG5hbWUgYXJndW1lbnQuIElmIHtAY29kZQogICAgICogZ2V0VHlwZUVsZW1lbnQobmFtZSl9IGlzIHtAY29kZSBudWxsfSwgYW4gZW1wdHkgc2V0IG9mIHR5cGUKICAgICAqIGVsZW1lbnRzIGlzIHJldHVybmVkOyBvdGhlcndpc2UsIGEgc2luZ2xlLWVsZW1lbnQgc2V0IHdpdGggdGhlCiAgICAgKiBmb3VuZCB0eXBlIGVsZW1lbnQgaXMgcmV0dXJuZWQuIElmIHRoZSBzZXQgb2YgbW9kdWxlcyBpcwogICAgICogbm9uZW1wdHksIHRoZSBtb2R1bGVzIGFyZSBpdGVyYXRlZCBvdmVyIGFuZCBhbnkgbm9uLXtAY29kZSBudWxsfQogICAgICogcmVzdWx0cyBvZiB7QGxpbmsgI2dldFR5cGVFbGVtZW50KE1vZHVsZUVsZW1lbnQsCiAgICAgKiBDaGFyU2VxdWVuY2UpIGdldFR5cGVFbGVtZW50KG1vZHVsZSwgbmFtZSl9IGFyZSBhY2N1bXVsYXRlZAogICAgICogaW50byBhIHNldC4gVGhlIHNldCBpcyB0aGVuIHJldHVybmVkLgogICAgICoKICAgICAqIEBwYXJhbSBuYW1lICB0aGUgY2Fub25pY2FsIG5hbWUKICAgICAqIEByZXR1cm4gdGhlIHR5cGUgZWxlbWVudHMsIG9yIGFuIGVtcHR5IHNldCBpZiBubyB0eXBlIHdpdGggdGhlIG5hbWUgY2FuIGJlIGZvdW5kCiAgICAgKiBAc2VlICNnZXRUeXBlRWxlbWVudChNb2R1bGVFbGVtZW50LCBDaGFyU2VxdWVuY2UpCiAgICAgKiBAc2luY2UgOQogICAgICovCiAgICBkZWZhdWx0IFNldDw/IGV4dGVuZHMgVHlwZUVsZW1lbnQ+IGdldEFsbFR5cGVFbGVtZW50cyhDaGFyU2VxdWVuY2UgbmFtZSkgewogICAgICAgIFNldDw/IGV4dGVuZHMgTW9kdWxlRWxlbWVudD4gbW9kdWxlcyA9IGdldEFsbE1vZHVsZUVsZW1lbnRzKCk7CiAgICAgICAgaWYgKG1vZHVsZXMuaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIFR5cGVFbGVtZW50IHR5cGVFbHQgPSBnZXRUeXBlRWxlbWVudChuYW1lKTsKICAgICAgICAgICAgcmV0dXJuICh0eXBlRWx0ICE9IG51bGwpID8KICAgICAgICAgICAgICAgIENvbGxlY3Rpb25zLnNpbmdsZXRvbih0eXBlRWx0KToKICAgICAgICAgICAgICAgIENvbGxlY3Rpb25zLmVtcHR5U2V0KCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgU2V0PFR5cGVFbGVtZW50PiByZXN1bHQgPSBuZXcgTGlua2VkSGFzaFNldDw+KDEpOyAvLyBVc3VhbGx5IGV4cGVjdCBhdCBtb3N0IDEgcmVzdWx0CiAgICAgICAgICAgIGZvciAoTW9kdWxlRWxlbWVudCBtb2R1bGU6IG1vZHVsZXMpIHsKICAgICAgICAgICAgICAgIFR5cGVFbGVtZW50IHR5cGVFbHQgPSBnZXRUeXBlRWxlbWVudChtb2R1bGUsIG5hbWUpOwogICAgICAgICAgICAgICAgaWYgKHR5cGVFbHQgIT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICByZXN1bHQuYWRkKHR5cGVFbHQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVTZXQocmVzdWx0KTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgbW9kdWxlIGVsZW1lbnQgZ2l2ZW4gaXRzIGZ1bGx5IHF1YWxpZmllZCBuYW1lLgogICAgICoKICAgICAqIElmIHRoZSBuYW1lZCBtb2R1bGUgY2Fubm90IGJlIGZvdW5kLCB7QGNvZGUgbnVsbH0gaXMKICAgICAqIHJldHVybmVkLiBPbmUgc2l0dWF0aW9uIHdoZXJlIGEgbW9kdWxlIGNhbm5vdCBiZSBmb3VuZCBpcyBpZgogICAgICogdGhlIGVudmlyb25tZW50IGRvZXMgbm90IGluY2x1ZGUgbW9kdWxlcywgc3VjaCBhcyBhbiBhbm5vdGF0aW9uCiAgICAgKiBwcm9jZXNzaW5nIGVudmlyb25tZW50IGNvbmZpZ3VyZWQgZm9yIGEge0BsaW5rcGxhaW4KICAgICAqIGphdmF4LmFubm90YXRpb24ucHJvY2Vzc2luZy5Qcm9jZXNzaW5nRW52aXJvbm1lbnQjZ2V0U291cmNlVmVyc2lvbgogICAgICogc291cmNlIHZlcnNpb259IHdpdGhvdXQgbW9kdWxlcy4KICAgICAqCiAgICAgKiBAaW1wbFNwZWMgVGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gb2YgdGhpcyBtZXRob2QgcmV0dXJucwogICAgICoge0Bjb2RlIG51bGx9LgogICAgICoKICAgICAqIEBwYXJhbSBuYW1lICB0aGUgbmFtZQogICAgICogQHJldHVybiB0aGUgbmFtZWQgbW9kdWxlIGVsZW1lbnQsIG9yIHtAY29kZSBudWxsfSBpZiBpdCBjYW5ub3QgYmUgZm91bmQKICAgICAqIEBzZWUgI2dldEFsbE1vZHVsZUVsZW1lbnRzCiAgICAgKiBAc2luY2UgOQogICAgICogQHNwZWMgSlBNUwogICAgICovCiAgICBkZWZhdWx0IE1vZHVsZUVsZW1lbnQgZ2V0TW9kdWxlRWxlbWVudChDaGFyU2VxdWVuY2UgbmFtZSkgewogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyBhbGwgbW9kdWxlIGVsZW1lbnRzIGluIHRoZSBjdXJyZW50IGVudmlyb25tZW50LgogICAgICoKICAgICAqIElmIG5vIG1vZHVsZXMgYXJlIHByZXNlbnQsIGFuIGVtcHR5IHNldCBpcyByZXR1cm5lZC4gT25lCiAgICAgKiBzaXR1YXRpb24gd2hlcmUgbm8gbW9kdWxlcyBhcmUgcHJlc2VudCBvY2N1cnMgd2hlbiB0aGUKICAgICAqIGVudmlyb25tZW50IGRvZXMgbm90IGluY2x1ZGUgbW9kdWxlcywgc3VjaCBhcyBhbiBhbm5vdGF0aW9uCiAgICAgKiBwcm9jZXNzaW5nIGVudmlyb25tZW50IGNvbmZpZ3VyZWQgZm9yIGEge0BsaW5rcGxhaW4KICAgICAqIGphdmF4LmFubm90YXRpb24ucHJvY2Vzc2luZy5Qcm9jZXNzaW5nRW52aXJvbm1lbnQjZ2V0U291cmNlVmVyc2lvbgogICAgICogc291cmNlIHZlcnNpb259IHdpdGhvdXQgbW9kdWxlcy4KICAgICAqCiAgICAgKiBAaW1wbFNwZWMgVGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gb2YgdGhpcyBtZXRob2QgcmV0dXJucwogICAgICogYW4gZW1wdHkgc2V0LgogICAgICoKICAgICAqIEByZXR1cm4gdGhlIGtub3duIG1vZHVsZSBlbGVtZW50cywgb3IgYW4gZW1wdHkgc2V0IGlmIHRoZXJlIGFyZSBubyBtb2R1bGVzCiAgICAgKiBAc2VlICNnZXRNb2R1bGVFbGVtZW50KENoYXJTZXF1ZW5jZSkKICAgICAqIEBzaW5jZSA5CiAgICAgKi8KICAgIGRlZmF1bHQgU2V0PD8gZXh0ZW5kcyBNb2R1bGVFbGVtZW50PiBnZXRBbGxNb2R1bGVFbGVtZW50cygpIHsKICAgICAgICByZXR1cm4gQ29sbGVjdGlvbnMuZW1wdHlTZXQoKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHZhbHVlcyBvZiBhbiBhbm5vdGF0aW9uJ3MgZWxlbWVudHMsIGluY2x1ZGluZyBkZWZhdWx0cy4KICAgICAqCiAgICAgKiBAc2VlIEFubm90YXRpb25NaXJyb3IjZ2V0RWxlbWVudFZhbHVlcygpCiAgICAgKiBAcGFyYW0gYSAgYW5ub3RhdGlvbiB0byBleGFtaW5lCiAgICAgKiBAcmV0dXJuIHRoZSB2YWx1ZXMgb2YgdGhlIGFubm90YXRpb24ncyBlbGVtZW50cywgaW5jbHVkaW5nIGRlZmF1bHRzCiAgICAgKi8KICAgIE1hcDw/IGV4dGVuZHMgRXhlY3V0YWJsZUVsZW1lbnQsID8gZXh0ZW5kcyBBbm5vdGF0aW9uVmFsdWU+CiAgICAgICAgICAgIGdldEVsZW1lbnRWYWx1ZXNXaXRoRGVmYXVsdHMoQW5ub3RhdGlvbk1pcnJvciBhKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHRleHQgb2YgdGhlIGRvY3VtZW50YXRpb24gKCZxdW90O0phdmFkb2MmcXVvdDspCiAgICAgKiBjb21tZW50IG9mIGFuIGVsZW1lbnQuCiAgICAgKgogICAgICogPHA+IEEgZG9jdW1lbnRhdGlvbiBjb21tZW50IG9mIGFuIGVsZW1lbnQgaXMgYSBjb21tZW50IHRoYXQKICAgICAqIGJlZ2lucyB3aXRoICJ7QGNvZGUgLyoqfSIgLCBlbmRzIHdpdGggYSBzZXBhcmF0ZQogICAgICogIjxjb2RlPiomIzQ3OzwvY29kZT4iLCBhbmQgaW1tZWRpYXRlbHkgcHJlY2VkZXMgdGhlIGVsZW1lbnQsCiAgICAgKiBpZ25vcmluZyB3aGl0ZSBzcGFjZS4gIFRoZXJlZm9yZSwgYSBkb2N1bWVudGF0aW9uIGNvbW1lbnQKICAgICAqIGNvbnRhaW5zIGF0IGxlYXN0IHRocmVlIntAY29kZSAqfSIgY2hhcmFjdGVycy4gIFRoZSB0ZXh0CiAgICAgKiByZXR1cm5lZCBmb3IgdGhlIGRvY3VtZW50YXRpb24gY29tbWVudCBpcyBhIHByb2Nlc3NlZCBmb3JtIG9mCiAgICAgKiB0aGUgY29tbWVudCBhcyBpdCBhcHBlYXJzIGluIHNvdXJjZSBjb2RlLiAgVGhlIGxlYWRpbmcgIntAY29kZQogICAgICogLyoqfSIgYW5kIHRyYWlsaW5nICI8Y29kZT4qJiM0Nzs8L2NvZGU+IiBhcmUgcmVtb3ZlZC4gIEZvciBsaW5lcwogICAgICogb2YgdGhlIGNvbW1lbnQgc3RhcnRpbmcgYWZ0ZXIgdGhlIGluaXRpYWwgIntAY29kZSAvKip9IiwKICAgICAqIGxlYWRpbmcgd2hpdGUgc3BhY2UgY2hhcmFjdGVycyBhcmUgZGlzY2FyZGVkIGFzIGFyZSBhbnkKICAgICAqIGNvbnNlY3V0aXZlICJ7QGNvZGUgKn0iIGNoYXJhY3RlcnMgYXBwZWFyaW5nIGFmdGVyIHRoZSB3aGl0ZQogICAgICogc3BhY2Ugb3Igc3RhcnRpbmcgdGhlIGxpbmUuICBUaGUgcHJvY2Vzc2VkIGxpbmVzIGFyZSB0aGVuCiAgICAgKiBjb25jYXRlbmF0ZWQgdG9nZXRoZXIgKGluY2x1ZGluZyBsaW5lIHRlcm1pbmF0b3JzKSBhbmQKICAgICAqIHJldHVybmVkLgogICAgICoKICAgICAqIEBwYXJhbSBlICB0aGUgZWxlbWVudCBiZWluZyBleGFtaW5lZAogICAgICogQHJldHVybiB0aGUgZG9jdW1lbnRhdGlvbiBjb21tZW50IG9mIHRoZSBlbGVtZW50LCBvciB7QGNvZGUgbnVsbH0KICAgICAqICAgICAgICAgIGlmIHRoZXJlIGlzIG5vbmUKICAgICAqIEBqbHMgMy42IFdoaXRlIFNwYWNlCiAgICAgKi8KICAgIFN0cmluZyBnZXREb2NDb21tZW50KEVsZW1lbnQgZSk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHtAY29kZSB0cnVlfSBpZiB0aGUgZWxlbWVudCBpcyBkZXByZWNhdGVkLCB7QGNvZGUgZmFsc2V9IG90aGVyd2lzZS4KICAgICAqCiAgICAgKiBAcGFyYW0gZSAgdGhlIGVsZW1lbnQgYmVpbmcgZXhhbWluZWQKICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBlbGVtZW50IGlzIGRlcHJlY2F0ZWQsIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlCiAgICAgKi8KICAgIGJvb2xlYW4gaXNEZXByZWNhdGVkKEVsZW1lbnQgZSk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSA8ZW0+b3JpZ2luPC9lbT4gb2YgdGhlIGdpdmVuIGVsZW1lbnQuCiAgICAgKgogICAgICogPHA+Tm90ZSB0aGF0IGlmIHRoaXMgbWV0aG9kIHJldHVybnMge0BsaW5rIE9yaWdpbiNFWFBMSUNJVAogICAgICogRVhQTElDSVR9IGFuZCB0aGUgZWxlbWVudCB3YXMgY3JlYXRlZCBmcm9tIGEgY2xhc3MgZmlsZSwgdGhlbgogICAgICogdGhlIGVsZW1lbnQgbWF5IG5vdCwgaW4gZmFjdCwgY29ycmVzcG9uZCB0byBhbiBleHBsaWNpdGx5CiAgICAgKiBkZWNsYXJlZCBjb25zdHJ1Y3QgaW4gc291cmNlIGNvZGUuIFRoaXMgaXMgZHVlIHRvIGxpbWl0YXRpb25zCiAgICAgKiBvZiB0aGUgZmlkZWxpdHkgb2YgdGhlIGNsYXNzIGZpbGUgZm9ybWF0IGluIHByZXNlcnZpbmcKICAgICAqIGluZm9ybWF0aW9uIGZyb20gc291cmNlIGNvZGUuIEZvciBleGFtcGxlLCBhdCBsZWFzdCBzb21lCiAgICAgKiB2ZXJzaW9ucyBvZiB0aGUgY2xhc3MgZmlsZSBmb3JtYXQgZG8gbm90IHByZXNlcnZlIHdoZXRoZXIgYQogICAgICogY29uc3RydWN0b3Igd2FzIGV4cGxpY2l0bHkgZGVjbGFyZWQgYnkgdGhlIHByb2dyYW1tZXIgb3Igd2FzCiAgICAgKiBpbXBsaWNpdGx5IGRlY2xhcmVkIGFzIHRoZSA8ZW0+ZGVmYXVsdCBjb25zdHJ1Y3RvcjwvZW0+LgogICAgICoKICAgICAqIEBpbXBsU3BlYyBUaGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGlzIG1ldGhvZCByZXR1cm5zCiAgICAgKiB7QGxpbmsgT3JpZ2luI0VYUExJQ0lUIEVYUExJQ0lUfS4KICAgICAqCiAgICAgKiBAcGFyYW0gZSAgdGhlIGVsZW1lbnQgYmVpbmcgZXhhbWluZWQKICAgICAqIEByZXR1cm4gdGhlIG9yaWdpbiBvZiB0aGUgZ2l2ZW4gZWxlbWVudAogICAgICogQHNpbmNlIDkKICAgICAqLwogICAgZGVmYXVsdCBPcmlnaW4gZ2V0T3JpZ2luKEVsZW1lbnQgZSkgewogICAgICAgIHJldHVybiBPcmlnaW4uRVhQTElDSVQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSA8ZW0+b3JpZ2luPC9lbT4gb2YgdGhlIGdpdmVuIGFubm90YXRpb24gbWlycm9yLgogICAgICoKICAgICAqIEFuIGFubm90YXRpb24gbWlycm9yIGlzIHtAbGlua3BsYWluIE9yaWdpbiNNQU5EQVRFRCBtYW5kYXRlZH0KICAgICAqIGlmIGl0IGlzIGFuIGltcGxpY2l0bHkgZGVjbGFyZWQgPGVtPmNvbnRhaW5lciBhbm5vdGF0aW9uPC9lbT4KICAgICAqIHVzZWQgdG8gaG9sZCByZXBlYXRlZCBhbm5vdGF0aW9ucyBvZiBhIHJlcGVhdGFibGUgYW5ub3RhdGlvbgogICAgICogdHlwZS4KICAgICAqCiAgICAgKiA8cD5Ob3RlIHRoYXQgaWYgdGhpcyBtZXRob2QgcmV0dXJucyB7QGxpbmsgT3JpZ2luI0VYUExJQ0lUCiAgICAgKiBFWFBMSUNJVH0gYW5kIHRoZSBhbm5vdGF0aW9uIG1pcnJvciB3YXMgY3JlYXRlZCBmcm9tIGEgY2xhc3MKICAgICAqIGZpbGUsIHRoZW4gdGhlIGVsZW1lbnQgbWF5IG5vdCwgaW4gZmFjdCwgY29ycmVzcG9uZCB0byBhbgogICAgICogZXhwbGljaXRseSBkZWNsYXJlZCBjb25zdHJ1Y3QgaW4gc291cmNlIGNvZGUuIFRoaXMgaXMgZHVlIHRvCiAgICAgKiBsaW1pdGF0aW9ucyBvZiB0aGUgZmlkZWxpdHkgb2YgdGhlIGNsYXNzIGZpbGUgZm9ybWF0IGluCiAgICAgKiBwcmVzZXJ2aW5nIGluZm9ybWF0aW9uIGZyb20gc291cmNlIGNvZGUuIEZvciBleGFtcGxlLCBhdCBsZWFzdAogICAgICogc29tZSB2ZXJzaW9ucyBvZiB0aGUgY2xhc3MgZmlsZSBmb3JtYXQgZG8gbm90IHByZXNlcnZlIHdoZXRoZXIKICAgICAqIGFuIGFubm90YXRpb24gd2FzIGV4cGxpY2l0bHkgZGVjbGFyZWQgYnkgdGhlIHByb2dyYW1tZXIgb3Igd2FzCiAgICAgKiBpbXBsaWNpdGx5IGRlY2xhcmVkIGFzIGEgPGVtPmNvbnRhaW5lciBhbm5vdGF0aW9uPC9lbT4uCiAgICAgKgogICAgICogQGltcGxTcGVjIFRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIG9mIHRoaXMgbWV0aG9kIHJldHVybnMKICAgICAqIHtAbGluayBPcmlnaW4jRVhQTElDSVQgRVhQTElDSVR9LgogICAgICoKICAgICAqIEBwYXJhbSBjIHRoZSBjb25zdHJ1Y3QgdGhlIGFubm90YXRpb24gbWlycm9yIG1vZGlmaWVzCiAgICAgKiBAcGFyYW0gYSB0aGUgYW5ub3RhdGlvbiBtaXJyb3IgYmVpbmcgZXhhbWluZWQKICAgICAqIEByZXR1cm4gdGhlIG9yaWdpbiBvZiB0aGUgZ2l2ZW4gYW5ub3RhdGlvbiBtaXJyb3IKICAgICAqIEBqbHMgOS42LjMgUmVwZWF0YWJsZSBBbm5vdGF0aW9uIFR5cGVzCiAgICAgKiBAamxzIDkuNy41IE11bHRpcGxlIEFubm90YXRpb25zIG9mIHRoZSBTYW1lIFR5cGUKICAgICAqIEBzaW5jZSA5CiAgICAgKi8KICAgIGRlZmF1bHQgT3JpZ2luIGdldE9yaWdpbihBbm5vdGF0ZWRDb25zdHJ1Y3QgYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBbm5vdGF0aW9uTWlycm9yIGEpIHsKICAgICAgICByZXR1cm4gT3JpZ2luLkVYUExJQ0lUOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgPGVtPm9yaWdpbjwvZW0+IG9mIHRoZSBnaXZlbiBtb2R1bGUgZGlyZWN0aXZlLgogICAgICoKICAgICAqIDxwPk5vdGUgdGhhdCBpZiB0aGlzIG1ldGhvZCByZXR1cm5zIHtAbGluayBPcmlnaW4jRVhQTElDSVQKICAgICAqIEVYUExJQ0lUfSBhbmQgdGhlIG1vZHVsZSBkaXJlY3RpdmUgd2FzIGNyZWF0ZWQgZnJvbSBhIGNsYXNzCiAgICAgKiBmaWxlLCB0aGVuIHRoZSBtb2R1bGUgZGlyZWN0aXZlIG1heSBub3QsIGluIGZhY3QsIGNvcnJlc3BvbmQgdG8KICAgICAqIGFuIGV4cGxpY2l0bHkgZGVjbGFyZWQgY29uc3RydWN0IGluIHNvdXJjZSBjb2RlLiBUaGlzIGlzIGR1ZSB0bwogICAgICogbGltaXRhdGlvbnMgb2YgdGhlIGZpZGVsaXR5IG9mIHRoZSBjbGFzcyBmaWxlIGZvcm1hdCBpbgogICAgICogcHJlc2VydmluZyBpbmZvcm1hdGlvbiBmcm9tIHNvdXJjZSBjb2RlLiBGb3IgZXhhbXBsZSwgYXQgbGVhc3QKICAgICAqIHNvbWUgdmVyc2lvbnMgb2YgdGhlIGNsYXNzIGZpbGUgZm9ybWF0IGRvIG5vdCBwcmVzZXJ2ZSB3aGV0aGVyCiAgICAgKiBhIHtAY29kZSB1c2VzfSBkaXJlY3RpdmUgd2FzIGV4cGxpY2l0bHkgZGVjbGFyZWQgYnkgdGhlCiAgICAgKiBwcm9ncmFtbWVyIG9yIHdhcyBhZGRlZCBhcyBhIHN5bnRoZXRpYyBjb25zdHJ1Y3QuCiAgICAgKgogICAgICogPHA+Tm90ZSB0aGF0IGFuIGltcGxlbWVudGF0aW9uIG1heSBub3QgYmUgYWJsZSB0byByZWxpYWJseQogICAgICogZGV0ZXJtaW5lIHRoZSBvcmlnaW4gc3RhdHVzIG9mIHRoZSBkaXJlY3RpdmUgaWYgdGhlIGRpcmVjdGl2ZQogICAgICogaXMgY3JlYXRlZCBmcm9tIGEgY2xhc3MgZmlsZSBkdWUgdG8gbGltaXRhdGlvbnMgb2YgdGhlIGZpZGVsaXR5CiAgICAgKiBvZiB0aGUgY2xhc3MgZmlsZSBmb3JtYXQgaW4gcHJlc2VydmluZyBpbmZvcm1hdGlvbiBmcm9tIHNvdXJjZQogICAgICogY29kZS4KICAgICAqCiAgICAgKiBAaW1wbFNwZWMgVGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gb2YgdGhpcyBtZXRob2QgcmV0dXJucwogICAgICoge0BsaW5rIE9yaWdpbiNFWFBMSUNJVCBFWFBMSUNJVH0uCiAgICAgKgogICAgICogQHBhcmFtIG0gdGhlIG1vZHVsZSBvZiB0aGUgZGlyZWN0aXZlCiAgICAgKiBAcGFyYW0gZGlyZWN0aXZlICB0aGUgbW9kdWxlIGRpcmVjdGl2ZSBiZWluZyBleGFtaW5lZAogICAgICogQHJldHVybiB0aGUgb3JpZ2luIG9mIHRoZSBnaXZlbiBkaXJlY3RpdmUKICAgICAqIEBzaW5jZSA5CiAgICAgKi8KICAgIGRlZmF1bHQgT3JpZ2luIGdldE9yaWdpbihNb2R1bGVFbGVtZW50IG0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTW9kdWxlRWxlbWVudC5EaXJlY3RpdmUgZGlyZWN0aXZlKSB7CiAgICAgICAgcmV0dXJuIE9yaWdpbi5FWFBMSUNJVDsKICAgIH0KCiAgICAvKioKICAgICAqIFRoZSA8ZW0+b3JpZ2luPC9lbT4gb2YgYW4gZWxlbWVudCBvciBvdGhlciBsYW5ndWFnZSBtb2RlbAogICAgICogaXRlbS4gVGhlIG9yaWdpbiBvZiBhbiBlbGVtZW50IG9yIGl0ZW0gbW9kZWxzIGhvdyBhIGNvbnN0cnVjdAogICAgICogaW4gYSBwcm9ncmFtIGlzIGRlY2xhcmVkIGluIHRoZSBzb3VyY2UgY29kZSwgZXhwbGljaXRseSwKICAgICAqIGltcGxpY2l0bHksIGV0Yy4KICAgICAqCiAgICAgKiA8cD5Ob3RlIHRoYXQgaXQgaXMgcG9zc2libGUgYWRkaXRpb25hbCBraW5kcyBvZiBvcmlnaW4gdmFsdWVzCiAgICAgKiB3aWxsIGJlIGFkZGVkIGluIGZ1dHVyZSB2ZXJzaW9ucyBvZiB0aGUgcGxhdGZvcm0uCiAgICAgKgogICAgICogQGpscyAxMy4xIFRoZSBGb3JtIG9mIGEgQmluYXJ5CiAgICAgKiBAc2luY2UgOQogICAgICovCiAgICBwdWJsaWMgZW51bSBPcmlnaW4gewogICAgICAgIC8qKgogICAgICAgICAqIERlc2NyaWJlcyBhIGNvbnN0cnVjdCBleHBsaWNpdGx5IGRlY2xhcmVkIGluIHNvdXJjZSBjb2RlLgogICAgICAgICAqLwogICAgICAgIEVYUExJQ0lULAoKICAgICAgIC8qKgogICAgICAgICAqIEEgbWFuZGF0ZWQgY29uc3RydWN0IGlzIG9uZSB0aGF0IGlzIG5vdCBleHBsaWNpdGx5IGRlY2xhcmVkCiAgICAgICAgICogaW4gdGhlIHNvdXJjZSBjb2RlLCBidXQgd2hvc2UgcHJlc2VuY2UgaXMgbWFuZGF0ZWQgYnkgdGhlCiAgICAgICAgICogc3BlY2lmaWNhdGlvbi4gU3VjaCBhIGNvbnN0cnVjdCBpcyBzYWlkIHRvIGJlIGltcGxpY2l0bHkKICAgICAgICAgKiBkZWNsYXJlZC4KICAgICAgICAgKgogICAgICAgICAqIE9uZSBleGFtcGxlIG9mIGEgbWFuZGF0ZWQgZWxlbWVudCBpcyBhIDxlbT5kZWZhdWx0CiAgICAgICAgICogY29uc3RydWN0b3I8L2VtPiBpbiBhIGNsYXNzIHRoYXQgY29udGFpbnMgbm8gZXhwbGljaXQKICAgICAgICAgKiBjb25zdHJ1Y3RvciBkZWNsYXJhdGlvbnMuCiAgICAgICAgICoKICAgICAgICAgKiBBbm90aGVyIGV4YW1wbGUgb2YgYSBtYW5kYXRlZCBjb25zdHJ1Y3QgaXMgYW4gaW1wbGljaXRseQogICAgICAgICAqIGRlY2xhcmVkIDxlbT5jb250YWluZXIgYW5ub3RhdGlvbjwvZW0+IHVzZWQgdG8gaG9sZAogICAgICAgICAqIG11bHRpcGxlIGFubm90YXRpb25zIG9mIGEgcmVwZWF0YWJsZSBhbm5vdGF0aW9uIHR5cGUuCiAgICAgICAgICoKICAgICAgICAgKiBAamxzIDguOC45IERlZmF1bHQgQ29uc3RydWN0b3IKICAgICAgICAgKiBAamxzIDguOS4zIEVudW0gTWVtYmVycwogICAgICAgICAqIEBqbHMgOS42LjMgUmVwZWF0YWJsZSBBbm5vdGF0aW9uIFR5cGVzCiAgICAgICAgICogQGpscyA5LjcuNSBNdWx0aXBsZSBBbm5vdGF0aW9ucyBvZiB0aGUgU2FtZSBUeXBlCiAgICAgICAgICovCiAgICAgICAgTUFOREFURUQsCgogICAgICAgLyoqCiAgICAgICAgICogQSBzeW50aGV0aWMgY29uc3RydWN0IGlzIG9uZSB0aGF0IGlzIG5laXRoZXIgaW1wbGljaXRseSBub3IKICAgICAgICAgKiBleHBsaWNpdGx5IGRlY2xhcmVkIGluIHRoZSBzb3VyY2UgY29kZS4gU3VjaCBhIGNvbnN0cnVjdCBpcwogICAgICAgICAqIHR5cGljYWxseSBhIHRyYW5zbGF0aW9uIGFydGlmYWN0IGNyZWF0ZWQgYnkgYSBjb21waWxlci4KICAgICAgICAgKi8KICAgICAgICBTWU5USEVUSUM7CgogICAgICAgIC8qKgogICAgICAgICAqIFJldHVybnMge0Bjb2RlIHRydWV9IGZvciB2YWx1ZXMgY29ycmVzcG9uZGluZyB0byBjb25zdHJ1Y3RzCiAgICAgICAgICogdGhhdCBhcmUgaW1wbGljaXRseSBvciBleHBsaWNpdGx5IGRlY2xhcmVkLCB7QGNvZGUgZmFsc2V9CiAgICAgICAgICogb3RoZXJ3aXNlLgogICAgICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGZvciB7QGxpbmsgRVhQTElDSVR9IGFuZCB7QGxpbmsKICAgICAgICAgKiBNQU5EQVRFRH0sIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBib29sZWFuIGlzRGVjbGFyZWQoKSB7CiAgICAgICAgICAgIHJldHVybiB0aGlzICE9IFNZTlRIRVRJQzsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHtAY29kZSB0cnVlfSBpZiB0aGUgZXhlY3V0YWJsZSBlbGVtZW50IGlzIGEgYnJpZGdlCiAgICAgKiBtZXRob2QsIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgogICAgICoKICAgICAqIEBpbXBsU3BlYyBUaGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGlzIG1ldGhvZCByZXR1cm5zIHtAY29kZSBmYWxzZX0uCiAgICAgKgogICAgICogQHBhcmFtIGUgIHRoZSBleGVjdXRhYmxlIGJlaW5nIGV4YW1pbmVkCiAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGUgZXhlY3V0YWJsZSBlbGVtZW50IGlzIGEgYnJpZGdlCiAgICAgKiBtZXRob2QsIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlCiAgICAgKiBAc2luY2UgOQogICAgICovCiAgICBkZWZhdWx0IGJvb2xlYW4gaXNCcmlkZ2UoRXhlY3V0YWJsZUVsZW1lbnQgZSkgewogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIDxpPmJpbmFyeSBuYW1lPC9pPiBvZiBhIHR5cGUgZWxlbWVudC4KICAgICAqCiAgICAgKiBAcGFyYW0gdHlwZSAgdGhlIHR5cGUgZWxlbWVudCBiZWluZyBleGFtaW5lZAogICAgICogQHJldHVybiB0aGUgYmluYXJ5IG5hbWUKICAgICAqCiAgICAgKiBAc2VlIFR5cGVFbGVtZW50I2dldFF1YWxpZmllZE5hbWUKICAgICAqIEBqbHMgMTMuMSBUaGUgRm9ybSBvZiBhIEJpbmFyeQogICAgICovCiAgICBOYW1lIGdldEJpbmFyeU5hbWUoVHlwZUVsZW1lbnQgdHlwZSk7CgoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgcGFja2FnZSBvZiBhbiBlbGVtZW50LiAgVGhlIHBhY2thZ2Ugb2YgYSBwYWNrYWdlIGlzCiAgICAgKiBpdHNlbGYuCiAgICAgKgogICAgICogQHBhcmFtIHR5cGUgdGhlIGVsZW1lbnQgYmVpbmcgZXhhbWluZWQKICAgICAqIEByZXR1cm4gdGhlIHBhY2thZ2Ugb2YgYW4gZWxlbWVudAogICAgICovCiAgICBQYWNrYWdlRWxlbWVudCBnZXRQYWNrYWdlT2YoRWxlbWVudCB0eXBlKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIG1vZHVsZSBvZiBhbiBlbGVtZW50LiAgVGhlIG1vZHVsZSBvZiBhIG1vZHVsZSBpcwogICAgICogaXRzZWxmLgogICAgICogSWYgdGhlcmUgaXMgbm8gbW9kdWxlIGZvciB0aGUgZWxlbWVudCwgbnVsbCBpcyByZXR1cm5lZC4gT25lIHNpdHVhdGlvbiB3aGVyZSB0aGVyZSBpcwogICAgICogbm8gbW9kdWxlIGZvciBhbiBlbGVtZW50IGlzIGlmIHRoZSBlbnZpcm9ubWVudCBkb2VzIG5vdCBpbmNsdWRlIG1vZHVsZXMsIHN1Y2ggYXMKICAgICAqIGFuIGFubm90YXRpb24gcHJvY2Vzc2luZyBlbnZpcm9ubWVudCBjb25maWd1cmVkIGZvcgogICAgICogYSB7QGxpbmtwbGFpbgogICAgICogamF2YXguYW5ub3RhdGlvbi5wcm9jZXNzaW5nLlByb2Nlc3NpbmdFbnZpcm9ubWVudCNnZXRTb3VyY2VWZXJzaW9uCiAgICAgKiBzb3VyY2UgdmVyc2lvbn0gd2l0aG91dCBtb2R1bGVzLgogICAgICoKICAgICAqIEBpbXBsU3BlYyBUaGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGlzIG1ldGhvZCByZXR1cm5zCiAgICAgKiB7QGNvZGUgbnVsbH0uCiAgICAgKgogICAgICogQHBhcmFtIHR5cGUgdGhlIGVsZW1lbnQgYmVpbmcgZXhhbWluZWQKICAgICAqIEByZXR1cm4gdGhlIG1vZHVsZSBvZiBhbiBlbGVtZW50CiAgICAgKiBAc2luY2UgOQogICAgICogQHNwZWMgSlBNUwogICAgICovCiAgICBkZWZhdWx0IE1vZHVsZUVsZW1lbnQgZ2V0TW9kdWxlT2YoRWxlbWVudCB0eXBlKSB7CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGFsbCBtZW1iZXJzIG9mIGEgdHlwZSBlbGVtZW50LCB3aGV0aGVyIGluaGVyaXRlZCBvcgogICAgICogZGVjbGFyZWQgZGlyZWN0bHkuICBGb3IgYSBjbGFzcyB0aGUgcmVzdWx0IGFsc28gaW5jbHVkZXMgaXRzCiAgICAgKiBjb25zdHJ1Y3RvcnMsIGJ1dCBub3QgbG9jYWwgb3IgYW5vbnltb3VzIGNsYXNzZXMuCiAgICAgKgogICAgICogQGFwaU5vdGUgRWxlbWVudHMgb2YgY2VydGFpbiBraW5kcyBjYW4gYmUgaXNvbGF0ZWQgdXNpbmcKICAgICAqIG1ldGhvZHMgaW4ge0BsaW5rIEVsZW1lbnRGaWx0ZXJ9LgogICAgICoKICAgICAqIEBwYXJhbSB0eXBlICB0aGUgdHlwZSBiZWluZyBleGFtaW5lZAogICAgICogQHJldHVybiBhbGwgbWVtYmVycyBvZiB0aGUgdHlwZQogICAgICogQHNlZSBFbGVtZW50I2dldEVuY2xvc2VkRWxlbWVudHMKICAgICAqLwogICAgTGlzdDw/IGV4dGVuZHMgRWxlbWVudD4gZ2V0QWxsTWVtYmVycyhUeXBlRWxlbWVudCB0eXBlKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgYWxsIGFubm90YXRpb25zIDxpPnByZXNlbnQ8L2k+IG9uIGFuIGVsZW1lbnQsIHdoZXRoZXIKICAgICAqIGRpcmVjdGx5IHByZXNlbnQgb3IgcHJlc2VudCB2aWEgaW5oZXJpdGFuY2UuCiAgICAgKgogICAgICogQHBhcmFtIGUgIHRoZSBlbGVtZW50IGJlaW5nIGV4YW1pbmVkCiAgICAgKiBAcmV0dXJuIGFsbCBhbm5vdGF0aW9ucyBvZiB0aGUgZWxlbWVudAogICAgICogQHNlZSBFbGVtZW50I2dldEFubm90YXRpb25NaXJyb3JzCiAgICAgKiBAc2VlIGphdmF4LmxhbmcubW9kZWwuQW5ub3RhdGVkQ29uc3RydWN0CiAgICAgKi8KICAgIExpc3Q8PyBleHRlbmRzIEFubm90YXRpb25NaXJyb3I+IGdldEFsbEFubm90YXRpb25NaXJyb3JzKEVsZW1lbnQgZSk7CgogICAgLyoqCiAgICAgKiBUZXN0cyB3aGV0aGVyIG9uZSB0eXBlLCBtZXRob2QsIG9yIGZpZWxkIGhpZGVzIGFub3RoZXIuCiAgICAgKgogICAgICogQHBhcmFtIGhpZGVyICAgdGhlIGZpcnN0IGVsZW1lbnQKICAgICAqIEBwYXJhbSBoaWRkZW4gIHRoZSBzZWNvbmQgZWxlbWVudAogICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgYW5kIG9ubHkgaWYgdGhlIGZpcnN0IGVsZW1lbnQgaGlkZXMKICAgICAqICAgICAgICAgIHRoZSBzZWNvbmQKICAgICAqLwogICAgYm9vbGVhbiBoaWRlcyhFbGVtZW50IGhpZGVyLCBFbGVtZW50IGhpZGRlbik7CgogICAgLyoqCiAgICAgKiBUZXN0cyB3aGV0aGVyIG9uZSBtZXRob2QsIGFzIGEgbWVtYmVyIG9mIGEgZ2l2ZW4gdHlwZSwKICAgICAqIG92ZXJyaWRlcyBhbm90aGVyIG1ldGhvZC4KICAgICAqIFdoZW4gYSBub24tYWJzdHJhY3QgbWV0aG9kIG92ZXJyaWRlcyBhbiBhYnN0cmFjdCBvbmUsIHRoZQogICAgICogZm9ybWVyIGlzIGFsc28gc2FpZCB0byA8aT5pbXBsZW1lbnQ8L2k+IHRoZSBsYXR0ZXIuCiAgICAgKgogICAgICogPHA+IEluIHRoZSBzaW1wbGVzdCBhbmQgbW9zdCB0eXBpY2FsIHVzYWdlLCB0aGUgdmFsdWUgb2YgdGhlCiAgICAgKiB7QGNvZGUgdHlwZX0gcGFyYW1ldGVyIHdpbGwgc2ltcGx5IGJlIHRoZSBjbGFzcyBvciBpbnRlcmZhY2UKICAgICAqIGRpcmVjdGx5IGVuY2xvc2luZyB7QGNvZGUgb3ZlcnJpZGVyfSAodGhlIHBvc3NpYmx5LW92ZXJyaWRpbmcKICAgICAqIG1ldGhvZCkuICBGb3IgZXhhbXBsZSwgc3VwcG9zZSB7QGNvZGUgbTF9IHJlcHJlc2VudHMgdGhlIG1ldGhvZAogICAgICoge0Bjb2RlIFN0cmluZy5oYXNoQ29kZX0gYW5kIHtAY29kZSBtMn0gcmVwcmVzZW50cyB7QGNvZGUKICAgICAqIE9iamVjdC5oYXNoQ29kZX0uICBXZSBjYW4gdGhlbiBhc2sgd2hldGhlciB7QGNvZGUgbTF9IG92ZXJyaWRlcwogICAgICoge0Bjb2RlIG0yfSB3aXRoaW4gdGhlIGNsYXNzIHtAY29kZSBTdHJpbmd9IChpdCBkb2VzKToKICAgICAqCiAgICAgKiA8YmxvY2txdW90ZT4KICAgICAqIHtAY29kZSBhc3NlcnQgZWxlbWVudHMub3ZlcnJpZGVzKG0xLCBtMiwKICAgICAqICAgICAgICAgIGVsZW1lbnRzLmdldFR5cGVFbGVtZW50KCJqYXZhLmxhbmcuU3RyaW5nIikpOyB9CiAgICAgKiA8L2Jsb2NrcXVvdGU+CiAgICAgKgogICAgICogQSBtb3JlIGludGVyZXN0aW5nIGNhc2UgY2FuIGJlIGlsbHVzdHJhdGVkIGJ5IHRoZSBmb2xsb3dpbmcgZXhhbXBsZQogICAgICogaW4gd2hpY2ggYSBtZXRob2QgaW4gdHlwZSB7QGNvZGUgQX0gZG9lcyBub3Qgb3ZlcnJpZGUgYQogICAgICogbGlrZS1uYW1lZCBtZXRob2QgaW4gdHlwZSB7QGNvZGUgQn06CiAgICAgKgogICAgICogPGJsb2NrcXVvdGU+CiAgICAgKiB7QGNvZGUgY2xhc3MgQSB7IHB1YmxpYyB2b2lkIG0oKSB7fSB9IH08YnI+CiAgICAgKiB7QGNvZGUgaW50ZXJmYWNlIEIgeyB2b2lkIG0oKTsgfSB9PGJyPgogICAgICogLi4uPGJyPgogICAgICoge0Bjb2RlIG0xID0gLi4uOyAgLy8gQS5tIH08YnI+CiAgICAgKiB7QGNvZGUgbTIgPSAuLi47ICAvLyBCLm0gfTxicj4KICAgICAqIHtAY29kZSBhc3NlcnQgISBlbGVtZW50cy5vdmVycmlkZXMobTEsIG0yLAogICAgICogICAgICAgICAgZWxlbWVudHMuZ2V0VHlwZUVsZW1lbnQoIkEiKSk7IH0KICAgICAqIDwvYmxvY2txdW90ZT4KICAgICAqCiAgICAgKiBXaGVuIHZpZXdlZCBhcyBhIG1lbWJlciBvZiBhIHRoaXJkIHR5cGUge0Bjb2RlIEN9LCBob3dldmVyLAogICAgICogdGhlIG1ldGhvZCBpbiB7QGNvZGUgQX0gZG9lcyBvdmVycmlkZSB0aGUgb25lIGluIHtAY29kZSBCfToKICAgICAqCiAgICAgKiA8YmxvY2txdW90ZT4KICAgICAqIHtAY29kZSBjbGFzcyBDIGV4dGVuZHMgQSBpbXBsZW1lbnRzIEIge30gfTxicj4KICAgICAqIC4uLjxicj4KICAgICAqIHtAY29kZSBhc3NlcnQgZWxlbWVudHMub3ZlcnJpZGVzKG0xLCBtMiwKICAgICAqICAgICAgICAgIGVsZW1lbnRzLmdldFR5cGVFbGVtZW50KCJDIikpOyB9CiAgICAgKiA8L2Jsb2NrcXVvdGU+CiAgICAgKgogICAgICogQHBhcmFtIG92ZXJyaWRlciAgdGhlIGZpcnN0IG1ldGhvZCwgcG9zc2libGUgb3ZlcnJpZGVyCiAgICAgKiBAcGFyYW0gb3ZlcnJpZGRlbiAgdGhlIHNlY29uZCBtZXRob2QsIHBvc3NpYmx5IGJlaW5nIG92ZXJyaWRkZW4KICAgICAqIEBwYXJhbSB0eXBlICAgdGhlIHR5cGUgb2Ygd2hpY2ggdGhlIGZpcnN0IG1ldGhvZCBpcyBhIG1lbWJlcgogICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgYW5kIG9ubHkgaWYgdGhlIGZpcnN0IG1ldGhvZCBvdmVycmlkZXMKICAgICAqICAgICAgICAgIHRoZSBzZWNvbmQKICAgICAqIEBqbHMgOC40LjggSW5oZXJpdGFuY2UsIE92ZXJyaWRpbmcsIGFuZCBIaWRpbmcKICAgICAqIEBqbHMgOS40LjEgSW5oZXJpdGFuY2UgYW5kIE92ZXJyaWRpbmcKICAgICAqLwogICAgYm9vbGVhbiBvdmVycmlkZXMoRXhlY3V0YWJsZUVsZW1lbnQgb3ZlcnJpZGVyLCBFeGVjdXRhYmxlRWxlbWVudCBvdmVycmlkZGVuLAogICAgICAgICAgICAgICAgICAgICAgVHlwZUVsZW1lbnQgdHlwZSk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSB0ZXh0IG9mIGEgPGk+Y29uc3RhbnQgZXhwcmVzc2lvbjwvaT4gcmVwcmVzZW50aW5nIGEKICAgICAqIHByaW1pdGl2ZSB2YWx1ZSBvciBhIHN0cmluZy4KICAgICAqIFRoZSB0ZXh0IHJldHVybmVkIGlzIGluIGEgZm9ybSBzdWl0YWJsZSBmb3IgcmVwcmVzZW50aW5nIHRoZSB2YWx1ZQogICAgICogaW4gc291cmNlIGNvZGUuCiAgICAgKgogICAgICogQHBhcmFtIHZhbHVlICBhIHByaW1pdGl2ZSB2YWx1ZSBvciBzdHJpbmcKICAgICAqIEByZXR1cm4gdGhlIHRleHQgb2YgYSBjb25zdGFudCBleHByZXNzaW9uCiAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgYXJndW1lbnQgaXMgbm90IGEgcHJpbWl0aXZlCiAgICAgKiAgICAgICAgICB2YWx1ZSBvciBzdHJpbmcKICAgICAqCiAgICAgKiBAc2VlIFZhcmlhYmxlRWxlbWVudCNnZXRDb25zdGFudFZhbHVlKCkKICAgICAqLwogICAgU3RyaW5nIGdldENvbnN0YW50RXhwcmVzc2lvbihPYmplY3QgdmFsdWUpOwoKICAgIC8qKgogICAgICogUHJpbnRzIGEgcmVwcmVzZW50YXRpb24gb2YgdGhlIGVsZW1lbnRzIHRvIHRoZSBnaXZlbiB3cml0ZXIgaW4KICAgICAqIHRoZSBzcGVjaWZpZWQgb3JkZXIuICBUaGUgbWFpbiBwdXJwb3NlIG9mIHRoaXMgbWV0aG9kIGlzIGZvcgogICAgICogZGlhZ25vc3RpY3MuICBUaGUgZXhhY3QgZm9ybWF0IG9mIHRoZSBvdXRwdXQgaXMgPGVtPm5vdDwvZW0+CiAgICAgKiBzcGVjaWZpZWQgYW5kIGlzIHN1YmplY3QgdG8gY2hhbmdlLgogICAgICoKICAgICAqIEBwYXJhbSB3IHRoZSB3cml0ZXIgdG8gcHJpbnQgdGhlIG91dHB1dCB0bwogICAgICogQHBhcmFtIGVsZW1lbnRzIHRoZSBlbGVtZW50cyB0byBwcmludAogICAgICovCiAgICB2b2lkIHByaW50RWxlbWVudHMoamF2YS5pby5Xcml0ZXIgdywgRWxlbWVudC4uLiBlbGVtZW50cyk7CgogICAgLyoqCiAgICAgKiBSZXR1cm4gYSBuYW1lIHdpdGggdGhlIHNhbWUgc2VxdWVuY2Ugb2YgY2hhcmFjdGVycyBhcyB0aGUKICAgICAqIGFyZ3VtZW50LgogICAgICoKICAgICAqIEBwYXJhbSBjcyB0aGUgY2hhcmFjdGVyIHNlcXVlbmNlIHRvIHJldHVybiBhcyBhIG5hbWUKICAgICAqIEByZXR1cm4gYSBuYW1lIHdpdGggdGhlIHNhbWUgc2VxdWVuY2Ugb2YgY2hhcmFjdGVycyBhcyB0aGUgYXJndW1lbnQKICAgICAqLwogICAgTmFtZSBnZXROYW1lKENoYXJTZXF1ZW5jZSBjcyk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHtAY29kZSB0cnVlfSBpZiB0aGUgdHlwZSBlbGVtZW50IGlzIGEgZnVuY3Rpb25hbCBpbnRlcmZhY2UsIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlLgogICAgICoKICAgICAqIEBwYXJhbSB0eXBlIHRoZSB0eXBlIGVsZW1lbnQgYmVpbmcgZXhhbWluZWQKICAgICAqIEByZXR1cm4ge0Bjb2RlIHRydWV9IGlmIHRoZSBlbGVtZW50IGlzIGEgZnVuY3Rpb25hbCBpbnRlcmZhY2UsIHtAY29kZSBmYWxzZX0gb3RoZXJ3aXNlCiAgICAgKiBAamxzIDkuOCBGdW5jdGlvbmFsIEludGVyZmFjZXMKICAgICAqIEBzaW5jZSAxLjgKICAgICAqLwogICAgYm9vbGVhbiBpc0Z1bmN0aW9uYWxJbnRlcmZhY2UoVHlwZUVsZW1lbnQgdHlwZSk7Cn0KUEsDBAoAAAgAAAY7qUrw+GVp8g0AAPINAAAyAAAAamF2YXgvbGFuZy9tb2RlbC91dGlsL0Fic3RyYWN0RWxlbWVudFZpc2l0b3I5LmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTEsIDIwMTUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgamF2YXgubGFuZy5tb2RlbC51dGlsOwoKaW1wb3J0IGphdmF4LmFubm90YXRpb24ucHJvY2Vzc2luZy5TdXBwb3J0ZWRTb3VyY2VWZXJzaW9uOwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5Tb3VyY2VWZXJzaW9uOwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5lbGVtZW50Lk1vZHVsZUVsZW1lbnQ7CmltcG9ydCBzdGF0aWMgamF2YXgubGFuZy5tb2RlbC5Tb3VyY2VWZXJzaW9uLio7CgoKLyoqCiAqIEEgc2tlbGV0YWwgdmlzaXRvciBvZiBwcm9ncmFtIGVsZW1lbnRzIHdpdGggZGVmYXVsdCBiZWhhdmlvcgogKiBhcHByb3ByaWF0ZSBmb3IgdGhlIHtAbGluayBTb3VyY2VWZXJzaW9uI1JFTEVBU0VfOSBSRUxFQVNFXzl9CiAqIHNvdXJjZSB2ZXJzaW9uLgogKgogKiA8cD4gPGI+V0FSTklORzo8L2I+IFRoZSB7QGNvZGUgRWxlbWVudFZpc2l0b3J9IGludGVyZmFjZQogKiBpbXBsZW1lbnRlZCBieSB0aGlzIGNsYXNzIG1heSBoYXZlIG1ldGhvZHMgYWRkZWQgdG8gaXQgaW4gdGhlCiAqIGZ1dHVyZSB0byBhY2NvbW1vZGF0ZSBuZXcsIGN1cnJlbnRseSB1bmtub3duLCBsYW5ndWFnZSBzdHJ1Y3R1cmVzCiAqIGFkZGVkIHRvIGZ1dHVyZSB2ZXJzaW9ucyBvZiB0aGUgSmF2YSZ0cmFkZTsgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2UuCiAqIFRoZXJlZm9yZSwgbWV0aG9kcyB3aG9zZSBuYW1lcyBiZWdpbiB3aXRoIHtAY29kZSAidmlzaXQifSBtYXkgYmUKICogYWRkZWQgdG8gdGhpcyBjbGFzcyBpbiB0aGUgZnV0dXJlOyB0byBhdm9pZCBpbmNvbXBhdGliaWxpdGllcywKICogY2xhc3NlcyB3aGljaCBleHRlbmQgdGhpcyBjbGFzcyBzaG91bGQgbm90IGRlY2xhcmUgYW55IGluc3RhbmNlCiAqIG1ldGhvZHMgd2l0aCBuYW1lcyBiZWdpbm5pbmcgd2l0aCB7QGNvZGUgInZpc2l0In0uCiAqCiAqIDxwPldoZW4gc3VjaCBhIG5ldyB2aXNpdCBtZXRob2QgaXMgYWRkZWQsIHRoZSBkZWZhdWx0CiAqIGltcGxlbWVudGF0aW9uIGluIHRoaXMgY2xhc3Mgd2lsbCBiZSB0byBjYWxsIHRoZSB7QGxpbmsKICogI3Zpc2l0VW5rbm93biB2aXNpdFVua25vd259IG1ldGhvZC4gIEEgbmV3IGFic3RyYWN0IGVsZW1lbnQgdmlzaXRvcgogKiBjbGFzcyB3aWxsIGFsc28gYmUgaW50cm9kdWNlZCB0byBjb3JyZXNwb25kIHRvIHRoZSBuZXcgbGFuZ3VhZ2UKICogbGV2ZWw7IHRoaXMgdmlzaXRvciB3aWxsIGhhdmUgZGlmZmVyZW50IGRlZmF1bHQgYmVoYXZpb3IgZm9yIHRoZQogKiB2aXNpdCBtZXRob2QgaW4gcXVlc3Rpb24uICBXaGVuIHRoZSBuZXcgdmlzaXRvciBpcyBpbnRyb2R1Y2VkLCBhbGwKICogb3IgcG9ydGlvbnMgb2YgdGhpcyB2aXNpdG9yIG1heSBiZSBkZXByZWNhdGVkLgogKgogKiBAcGFyYW0gPFI+IHRoZSByZXR1cm4gdHlwZSBvZiB0aGlzIHZpc2l0b3IncyBtZXRob2RzLiAgVXNlIHtAbGluawogKiAgICAgICAgICAgIFZvaWR9IGZvciB2aXNpdG9ycyB0aGF0IGRvIG5vdCBuZWVkIHRvIHJldHVybiByZXN1bHRzLgogKiBAcGFyYW0gPFA+IHRoZSB0eXBlIG9mIHRoZSBhZGRpdGlvbmFsIHBhcmFtZXRlciB0byB0aGlzIHZpc2l0b3IncwogKiAgICAgICAgICAgIG1ldGhvZHMuICBVc2Uge0Bjb2RlIFZvaWR9IGZvciB2aXNpdG9ycyB0aGF0IGRvIG5vdCBuZWVkIGFuCiAqICAgICAgICAgICAgYWRkaXRpb25hbCBwYXJhbWV0ZXIuCiAqCiAqIEBzZWUgQWJzdHJhY3RFbGVtZW50VmlzaXRvcjYKICogQHNlZSBBYnN0cmFjdEVsZW1lbnRWaXNpdG9yNwogKiBAc2VlIEFic3RyYWN0RWxlbWVudFZpc2l0b3I4CiAqIEBzaW5jZSA5CiAqIEBzcGVjIEpQTVMKICovCkBTdXBwb3J0ZWRTb3VyY2VWZXJzaW9uKFJFTEVBU0VfOSkKcHVibGljIGFic3RyYWN0IGNsYXNzIEFic3RyYWN0RWxlbWVudFZpc2l0b3I5PFIsIFA+IGV4dGVuZHMgQWJzdHJhY3RFbGVtZW50VmlzaXRvcjg8UiwgUD4gewogICAgLyoqCiAgICAgKiBDb25zdHJ1Y3RvciBmb3IgY29uY3JldGUgc3ViY2xhc3NlcyB0byBjYWxsLgogICAgICovCiAgICBwcm90ZWN0ZWQgQWJzdHJhY3RFbGVtZW50VmlzaXRvcjkoKXsKICAgICAgICBzdXBlcigpOwogICAgfQoKICAgIC8qKgogICAgICogVmlzaXRzIGEge0Bjb2RlIE1vZHVsZUVsZW1lbnR9IGluIGEgbWFubmVyIGRlZmluZWQgYnkgYQogICAgICogc3ViY2xhc3MuCiAgICAgKgogICAgICogQHBhcmFtIHQgIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwICB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuIHRoZSByZXN1bHQgb2YgdGhlIHZpc2l0IGFzIGRlZmluZWQgYnkgYSBzdWJjbGFzcwogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBhYnN0cmFjdCBSIHZpc2l0TW9kdWxlKE1vZHVsZUVsZW1lbnQgdCwgUCBwKTsKfQpQSwMECgAACAAABjupShFDV9FIFQAASBUAACoAAABqYXZheC9sYW5nL21vZGVsL3V0aWwvRWxlbWVudFNjYW5uZXI5LmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTEsIDIwMTcsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgamF2YXgubGFuZy5tb2RlbC51dGlsOwoKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC4qOwppbXBvcnQgamF2YXguYW5ub3RhdGlvbi5wcm9jZXNzaW5nLlN1cHBvcnRlZFNvdXJjZVZlcnNpb247CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLlNvdXJjZVZlcnNpb247CmltcG9ydCBzdGF0aWMgamF2YXgubGFuZy5tb2RlbC5Tb3VyY2VWZXJzaW9uLio7CgoKLyoqCiAqIEEgc2Nhbm5pbmcgdmlzaXRvciBvZiBwcm9ncmFtIGVsZW1lbnRzIHdpdGggZGVmYXVsdCBiZWhhdmlvcgogKiBhcHByb3ByaWF0ZSBmb3IgdGhlIHtAbGluayBTb3VyY2VWZXJzaW9uI1JFTEVBU0VfOSBSRUxFQVNFXzl9CiAqIHNvdXJjZSB2ZXJzaW9uLiAgVGhlIDxjb2RlPnZpc2l0PGk+WHl6PC9pPjwvY29kZT4gbWV0aG9kcyBpbiB0aGlzCiAqIGNsYXNzIHNjYW4gdGhlaXIgY29tcG9uZW50IGVsZW1lbnRzIGJ5IGNhbGxpbmcge0Bjb2RlIHNjYW59IG9uCiAqIHRoZWlyIHtAbGlua3BsYWluIEVsZW1lbnQjZ2V0RW5jbG9zZWRFbGVtZW50cyBlbmNsb3NlZCBlbGVtZW50c30sCiAqIHtAbGlua3BsYWluIEV4ZWN1dGFibGVFbGVtZW50I2dldFBhcmFtZXRlcnMgcGFyYW1ldGVyc30sIGV0Yy4sIGFzCiAqIGluZGljYXRlZCBpbiB0aGUgaW5kaXZpZHVhbCBtZXRob2Qgc3BlY2lmaWNhdGlvbnMuICBBIHN1YmNsYXNzIGNhbgogKiBjb250cm9sIHRoZSBvcmRlciBlbGVtZW50cyBhcmUgdmlzaXRlZCBieSBvdmVycmlkaW5nIHRoZQogKiA8Y29kZT52aXNpdDxpPlh5ejwvaT48L2NvZGU+IG1ldGhvZHMuICBOb3RlIHRoYXQgY2xpZW50cyBvZiBhIHNjYW5uZXIKICogbWF5IGdldCB0aGUgZGVzaXJlZCBiZWhhdmlvciBiZSBpbnZva2luZyB7QGNvZGUgdi5zY2FuKGUsIHApfSByYXRoZXIKICogdGhhbiB7QGNvZGUgdi52aXNpdChlLCBwKX0gb24gdGhlIHJvb3Qgb2JqZWN0cyBvZiBpbnRlcmVzdC4KICoKICogPHA+V2hlbiBhIHN1YmNsYXNzIG92ZXJyaWRlcyBhIDxjb2RlPnZpc2l0PGk+WHl6PC9pPjwvY29kZT4gbWV0aG9kLCB0aGUKICogbmV3IG1ldGhvZCBjYW4gY2F1c2UgdGhlIGVuY2xvc2VkIGVsZW1lbnRzIHRvIGJlIHNjYW5uZWQgaW4gdGhlCiAqIGRlZmF1bHQgd2F5IGJ5IGNhbGxpbmcgPGNvZGU+c3VwZXIudmlzaXQ8aT5YeXo8L2k+PC9jb2RlPi4gIEluIHRoaXMKICogZmFzaGlvbiwgdGhlIGNvbmNyZXRlIHZpc2l0b3IgY2FuIGNvbnRyb2wgdGhlIG9yZGVyaW5nIG9mIHRyYXZlcnNhbAogKiBvdmVyIHRoZSBjb21wb25lbnQgZWxlbWVudHMgd2l0aCByZXNwZWN0IHRvIHRoZSBhZGRpdGlvbmFsCiAqIHByb2Nlc3Npbmc7IGZvciBleGFtcGxlLCBjb25zaXN0ZW50bHkgY2FsbGluZwogKiA8Y29kZT5zdXBlci52aXNpdDxpPlh5ejwvaT48L2NvZGU+IGF0IHRoZSBzdGFydCBvZiB0aGUgb3ZlcnJpZGRlbgogKiBtZXRob2RzIHdpbGwgeWllbGQgYSBwcmVvcmRlciB0cmF2ZXJzYWwsIGV0Yy4gIElmIHRoZSBjb21wb25lbnQKICogZWxlbWVudHMgc2hvdWxkIGJlIHRyYXZlcnNlZCBpbiBzb21lIG90aGVyIG9yZGVyLCBpbnN0ZWFkIG9mCiAqIGNhbGxpbmcgPGNvZGU+c3VwZXIudmlzaXQ8aT5YeXo8L2k+PC9jb2RlPiwgYW4gb3ZlcnJpZGluZyB2aXNpdCBtZXRob2QKICogc2hvdWxkIGNhbGwge0Bjb2RlIHNjYW59IHdpdGggdGhlIGVsZW1lbnRzIGluIHRoZSBkZXNpcmVkIG9yZGVyLgogKgogKiA8cD4gTWV0aG9kcyBpbiB0aGlzIGNsYXNzIG1heSBiZSBvdmVycmlkZGVuIHN1YmplY3QgdG8gdGhlaXIKICogZ2VuZXJhbCBjb250cmFjdC4gIE5vdGUgdGhhdCBhbm5vdGF0aW5nIG1ldGhvZHMgaW4gY29uY3JldGUKICogc3ViY2xhc3NlcyB3aXRoIHtAbGluayBqYXZhLmxhbmcuT3ZlcnJpZGUgQE92ZXJyaWRlfSB3aWxsIGhlbHAKICogZW5zdXJlIHRoYXQgbWV0aG9kcyBhcmUgb3ZlcnJpZGRlbiBhcyBpbnRlbmRlZC4KICoKICogPHA+IDxiPldBUk5JTkc6PC9iPiBUaGUge0Bjb2RlIEVsZW1lbnRWaXNpdG9yfSBpbnRlcmZhY2UKICogaW1wbGVtZW50ZWQgYnkgdGhpcyBjbGFzcyBtYXkgaGF2ZSBtZXRob2RzIGFkZGVkIHRvIGl0IGluIHRoZQogKiBmdXR1cmUgdG8gYWNjb21tb2RhdGUgbmV3LCBjdXJyZW50bHkgdW5rbm93biwgbGFuZ3VhZ2Ugc3RydWN0dXJlcwogKiBhZGRlZCB0byBmdXR1cmUgdmVyc2lvbnMgb2YgdGhlIEphdmEmdHJhZGU7IHByb2dyYW1taW5nIGxhbmd1YWdlLgogKiBUaGVyZWZvcmUsIG1ldGhvZHMgd2hvc2UgbmFtZXMgYmVnaW4gd2l0aCB7QGNvZGUgInZpc2l0In0gbWF5IGJlCiAqIGFkZGVkIHRvIHRoaXMgY2xhc3MgaW4gdGhlIGZ1dHVyZTsgdG8gYXZvaWQgaW5jb21wYXRpYmlsaXRpZXMsCiAqIGNsYXNzZXMgd2hpY2ggZXh0ZW5kIHRoaXMgY2xhc3Mgc2hvdWxkIG5vdCBkZWNsYXJlIGFueSBpbnN0YW5jZQogKiBtZXRob2RzIHdpdGggbmFtZXMgYmVnaW5uaW5nIHdpdGgge0Bjb2RlICJ2aXNpdCJ9LgogKgogKiA8cD5XaGVuIHN1Y2ggYSBuZXcgdmlzaXQgbWV0aG9kIGlzIGFkZGVkLCB0aGUgZGVmYXVsdAogKiBpbXBsZW1lbnRhdGlvbiBpbiB0aGlzIGNsYXNzIHdpbGwgYmUgdG8gY2FsbCB0aGUge0BsaW5rCiAqICN2aXNpdFVua25vd24gdmlzaXRVbmtub3dufSBtZXRob2QuICBBIG5ldyBlbGVtZW50IHNjYW5uZXIgdmlzaXRvcgogKiBjbGFzcyB3aWxsIGFsc28gYmUgaW50cm9kdWNlZCB0byBjb3JyZXNwb25kIHRvIHRoZSBuZXcgbGFuZ3VhZ2UKICogbGV2ZWw7IHRoaXMgdmlzaXRvciB3aWxsIGhhdmUgZGlmZmVyZW50IGRlZmF1bHQgYmVoYXZpb3IgZm9yIHRoZQogKiB2aXNpdCBtZXRob2QgaW4gcXVlc3Rpb24uICBXaGVuIHRoZSBuZXcgdmlzaXRvciBpcyBpbnRyb2R1Y2VkLCBhbGwKICogb3IgcG9ydGlvbnMgb2YgdGhpcyB2aXNpdG9yIG1heSBiZSBkZXByZWNhdGVkLgogKgogKiBAcGFyYW0gPFI+IHRoZSByZXR1cm4gdHlwZSBvZiB0aGlzIHZpc2l0b3IncyBtZXRob2RzLiAgVXNlIHtAbGluawogKiAgICAgICAgICAgIFZvaWR9IGZvciB2aXNpdG9ycyB0aGF0IGRvIG5vdCBuZWVkIHRvIHJldHVybiByZXN1bHRzLgogKiBAcGFyYW0gPFA+IHRoZSB0eXBlIG9mIHRoZSBhZGRpdGlvbmFsIHBhcmFtZXRlciB0byB0aGlzIHZpc2l0b3IncwogKiAgICAgICAgICAgIG1ldGhvZHMuICBVc2Uge0Bjb2RlIFZvaWR9IGZvciB2aXNpdG9ycyB0aGF0IGRvIG5vdCBuZWVkIGFuCiAqICAgICAgICAgICAgYWRkaXRpb25hbCBwYXJhbWV0ZXIuCiAqCiAqIEBzZWUgRWxlbWVudFNjYW5uZXI2CiAqIEBzZWUgRWxlbWVudFNjYW5uZXI3CiAqIEBzZWUgRWxlbWVudFNjYW5uZXI4CiAqIEBzaW5jZSA5CiAqIEBzcGVjIEpQTVMKICovCkBTdXBwb3J0ZWRTb3VyY2VWZXJzaW9uKFJFTEVBU0VfOSkKcHVibGljIGNsYXNzIEVsZW1lbnRTY2FubmVyOTxSLCBQPiBleHRlbmRzIEVsZW1lbnRTY2FubmVyODxSLCBQPiB7CiAgICAvKioKICAgICAqIENvbnN0cnVjdG9yIGZvciBjb25jcmV0ZSBzdWJjbGFzc2VzOyB1c2VzIHtAY29kZSBudWxsfSBmb3IgdGhlCiAgICAgKiBkZWZhdWx0IHZhbHVlLgogICAgICovCiAgICBwcm90ZWN0ZWQgRWxlbWVudFNjYW5uZXI5KCl7CiAgICAgICAgc3VwZXIobnVsbCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDb25zdHJ1Y3RvciBmb3IgY29uY3JldGUgc3ViY2xhc3NlczsgdXNlcyB0aGUgYXJndW1lbnQgZm9yIHRoZQogICAgICogZGVmYXVsdCB2YWx1ZS4KICAgICAqCiAgICAgKiBAcGFyYW0gZGVmYXVsdFZhbHVlIHRoZSBkZWZhdWx0IHZhbHVlCiAgICAgKi8KICAgIHByb3RlY3RlZCBFbGVtZW50U2Nhbm5lcjkoUiBkZWZhdWx0VmFsdWUpewogICAgICAgIHN1cGVyKGRlZmF1bHRWYWx1ZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBWaXNpdHMgYSB7QGNvZGUgTW9kdWxlRWxlbWVudH0gYnkgc2Nhbm5pbmcgdGhlIGVuY2xvc2VkCiAgICAgKiBlbGVtZW50cy4KICAgICAqCiAgICAgKiBAcGFyYW0gZSB0aGUgZWxlbWVudCB0byB2aXNpdAogICAgICogQHBhcmFtIHAgYSB2aXNpdG9yLXNwZWNpZmllZCBwYXJhbWV0ZXIKICAgICAqIEByZXR1cm4gIHRoZSByZXN1bHQgb2YgdGhlIHNjYW4KICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgUiB2aXNpdE1vZHVsZShNb2R1bGVFbGVtZW50IGUsIFAgcCkgewogICAgICAgIHJldHVybiBzY2FuKGUuZ2V0RW5jbG9zZWRFbGVtZW50cygpLCBwKTsgLy8gVE9ETzogSG1tbSwgdGhpcyBtaWdodCBub3QgYmUgcmlnaHQKICAgIH0KfQpQSwMECgAACAAABjupSjuizJClDQAApQ0AAC8AAABqYXZheC9sYW5nL21vZGVsL3V0aWwvQWJzdHJhY3RUeXBlVmlzaXRvcjguamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAxMSwgMjAxNywgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBqYXZheC5sYW5nLm1vZGVsLnV0aWw7CgppbXBvcnQgamF2YXguYW5ub3RhdGlvbi5wcm9jZXNzaW5nLlN1cHBvcnRlZFNvdXJjZVZlcnNpb247CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLnR5cGUuKjsKCmltcG9ydCBzdGF0aWMgamF2YXgubGFuZy5tb2RlbC5Tb3VyY2VWZXJzaW9uLio7CgovKioKICogQSBza2VsZXRhbCB2aXNpdG9yIG9mIHR5cGVzIHdpdGggZGVmYXVsdCBiZWhhdmlvciBhcHByb3ByaWF0ZSBmb3IKICogdGhlIHtAbGluayBqYXZheC5sYW5nLm1vZGVsLlNvdXJjZVZlcnNpb24jUkVMRUFTRV84IFJFTEVBU0VfOH0KICogc291cmNlIHZlcnNpb24uCiAqCiAqIDxwPiA8Yj5XQVJOSU5HOjwvYj4gVGhlIHtAY29kZSBUeXBlVmlzaXRvcn0gaW50ZXJmYWNlIGltcGxlbWVudGVkCiAqIGJ5IHRoaXMgY2xhc3MgbWF5IGhhdmUgbWV0aG9kcyBhZGRlZCB0byBpdCBpbiB0aGUgZnV0dXJlIHRvCiAqIGFjY29tbW9kYXRlIG5ldywgY3VycmVudGx5IHVua25vd24sIGxhbmd1YWdlIHN0cnVjdHVyZXMgYWRkZWQgdG8KICogZnV0dXJlIHZlcnNpb25zIG9mIHRoZSBKYXZhJnRyYWRlOyBwcm9ncmFtbWluZyBsYW5ndWFnZS4KICogVGhlcmVmb3JlLCBtZXRob2RzIHdob3NlIG5hbWVzIGJlZ2luIHdpdGgge0Bjb2RlICJ2aXNpdCJ9IG1heSBiZQogKiBhZGRlZCB0byB0aGlzIGNsYXNzIGluIHRoZSBmdXR1cmU7IHRvIGF2b2lkIGluY29tcGF0aWJpbGl0aWVzLAogKiBjbGFzc2VzIHdoaWNoIGV4dGVuZCB0aGlzIGNsYXNzIHNob3VsZCBub3QgZGVjbGFyZSBhbnkgaW5zdGFuY2UKICogbWV0aG9kcyB3aXRoIG5hbWVzIGJlZ2lubmluZyB3aXRoIHtAY29kZSAidmlzaXQifS4KICoKICogPHA+V2hlbiBzdWNoIGEgbmV3IHZpc2l0IG1ldGhvZCBpcyBhZGRlZCwgdGhlIGRlZmF1bHQKICogaW1wbGVtZW50YXRpb24gaW4gdGhpcyBjbGFzcyB3aWxsIGJlIHRvIGNhbGwgdGhlIHtAbGluawogKiAjdmlzaXRVbmtub3duIHZpc2l0VW5rbm93bn0gbWV0aG9kLiAgQSBuZXcgYWJzdHJhY3QgdHlwZSB2aXNpdG9yCiAqIGNsYXNzIHdpbGwgYWxzbyBiZSBpbnRyb2R1Y2VkIHRvIGNvcnJlc3BvbmQgdG8gdGhlIG5ldyBsYW5ndWFnZQogKiBsZXZlbDsgdGhpcyB2aXNpdG9yIHdpbGwgaGF2ZSBkaWZmZXJlbnQgZGVmYXVsdCBiZWhhdmlvciBmb3IgdGhlCiAqIHZpc2l0IG1ldGhvZCBpbiBxdWVzdGlvbi4gIFdoZW4gdGhlIG5ldyB2aXNpdG9yIGlzIGludHJvZHVjZWQsIGFsbAogKiBvciBwb3J0aW9ucyBvZiB0aGlzIHZpc2l0b3IgbWF5IGJlIGRlcHJlY2F0ZWQuCiAqCiAqIEBwYXJhbSA8Uj4gdGhlIHJldHVybiB0eXBlIG9mIHRoaXMgdmlzaXRvcidzIG1ldGhvZHMuICBVc2Uge0BsaW5rCiAqICAgICAgICAgICAgVm9pZH0gZm9yIHZpc2l0b3JzIHRoYXQgZG8gbm90IG5lZWQgdG8gcmV0dXJuIHJlc3VsdHMuCiAqIEBwYXJhbSA8UD4gdGhlIHR5cGUgb2YgdGhlIGFkZGl0aW9uYWwgcGFyYW1ldGVyIHRvIHRoaXMgdmlzaXRvcidzCiAqICAgICAgICAgICAgbWV0aG9kcy4gIFVzZSB7QGNvZGUgVm9pZH0gZm9yIHZpc2l0b3JzIHRoYXQgZG8gbm90IG5lZWQgYW4KICogICAgICAgICAgICBhZGRpdGlvbmFsIHBhcmFtZXRlci4KICoKICogQHNlZSBBYnN0cmFjdFR5cGVWaXNpdG9yNgogKiBAc2VlIEFic3RyYWN0VHlwZVZpc2l0b3I3CiAqIEBzZWUgQWJzdHJhY3RUeXBlVmlzaXRvcjkKICogQHNpbmNlIDEuOAogKi8KQFN1cHBvcnRlZFNvdXJjZVZlcnNpb24oUkVMRUFTRV84KQpwdWJsaWMgYWJzdHJhY3QgY2xhc3MgQWJzdHJhY3RUeXBlVmlzaXRvcjg8UiwgUD4gZXh0ZW5kcyBBYnN0cmFjdFR5cGVWaXNpdG9yNzxSLCBQPiB7CiAgICAvKioKICAgICAqIENvbnN0cnVjdG9yIGZvciBjb25jcmV0ZSBzdWJjbGFzc2VzIHRvIGNhbGwuCiAgICAgKi8KICAgIHByb3RlY3RlZCBBYnN0cmFjdFR5cGVWaXNpdG9yOCgpIHsKICAgICAgICBzdXBlcigpOwogICAgfQoKICAgIC8qKgogICAgICogVmlzaXRzIGFuIHtAY29kZSBJbnRlcnNlY3Rpb25UeXBlfSBpbiBhIG1hbm5lciBkZWZpbmVkIGJ5IGEgc3ViY2xhc3MuCiAgICAgKgogICAgICogQHBhcmFtIHQgIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwICB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuIHRoZSByZXN1bHQgb2YgdGhlIHZpc2l0IGFzIGRlZmluZWQgYnkgYSBzdWJjbGFzcwogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBhYnN0cmFjdCBSIHZpc2l0SW50ZXJzZWN0aW9uKEludGVyc2VjdGlvblR5cGUgdCwgUCBwKTsKfQpQSwMECgAACAAABjupSsf1ipE3LgAANy4AACgAAABqYXZheC9sYW5nL21vZGVsL3V0aWwvRWxlbWVudEZpbHRlci5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDA1LCAyMDE3LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGphdmF4LmxhbmcubW9kZWwudXRpbDsKCmltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbnM7CmltcG9ydCBqYXZhLnV0aWwuTGlzdDsKaW1wb3J0IGphdmEudXRpbC5TZXQ7CmltcG9ydCBqYXZhLnV0aWwuRW51bVNldDsKaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CmltcG9ydCBqYXZhLnV0aWwuTGlua2VkSGFzaFNldDsKCmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuKjsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC5Nb2R1bGVFbGVtZW50LkRpcmVjdGl2ZTsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC5Nb2R1bGVFbGVtZW50LkRpcmVjdGl2ZUtpbmQ7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuTW9kdWxlRWxlbWVudC5FeHBvcnRzRGlyZWN0aXZlOwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5lbGVtZW50Lk1vZHVsZUVsZW1lbnQuT3BlbnNEaXJlY3RpdmU7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuTW9kdWxlRWxlbWVudC5Qcm92aWRlc0RpcmVjdGl2ZTsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC5Nb2R1bGVFbGVtZW50LlJlcXVpcmVzRGlyZWN0aXZlOwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5lbGVtZW50Lk1vZHVsZUVsZW1lbnQuVXNlc0RpcmVjdGl2ZTsKCgovKioKICogRmlsdGVycyBmb3Igc2VsZWN0aW5nIGp1c3QgdGhlIGVsZW1lbnRzIG9mIGludGVyZXN0IGZyb20gYQogKiBjb2xsZWN0aW9uIG9mIGVsZW1lbnRzLiAgVGhlIHJldHVybmVkIHNldHMgYW5kIGxpc3RzIGFyZSBuZXcKICogY29sbGVjdGlvbnMgYW5kIGRvIHVzZSB0aGUgYXJndW1lbnQgYXMgYSBiYWNraW5nIHN0b3JlLiAgVGhlCiAqIG1ldGhvZHMgaW4gdGhpcyBjbGFzcyBkbyBub3QgbWFrZSBhbnkgYXR0ZW1wdHMgdG8gZ3VhcmQgYWdhaW5zdAogKiBjb25jdXJyZW50IG1vZGlmaWNhdGlvbnMgb2YgdGhlIGFyZ3VtZW50cy4gIFRoZSByZXR1cm5lZCBzZXRzIGFuZAogKiBsaXN0cyBhcmUgbXV0YWJsZSBidXQgdW5zYWZlIGZvciBjb25jdXJyZW50IGFjY2Vzcy4gIEEgcmV0dXJuZWQgc2V0CiAqIGhhcyB0aGUgc2FtZSBpdGVyYXRpb24gb3JkZXIgYXMgdGhlIGFyZ3VtZW50IHNldCB0byBhIG1ldGhvZC4KICoKICogPHA+SWYgaXRlcmFibGVzIGFuZCBzZXRzIGNvbnRhaW5pbmcge0Bjb2RlIG51bGx9IGFyZSBwYXNzZWQgYXMKICogYXJndW1lbnRzIHRvIG1ldGhvZHMgaW4gdGhpcyBjbGFzcywgYSB7QGNvZGUgTnVsbFBvaW50ZXJFeGNlcHRpb259CiAqIHdpbGwgYmUgdGhyb3duLgogKgogKiBAYXV0aG9yIEpvc2VwaCBELiBEYXJjeQogKiBAYXV0aG9yIFNjb3R0IFNlbGlnbWFuCiAqIEBhdXRob3IgUGV0ZXIgdm9uIGRlciBBaCZlYWN1dGU7CiAqIEBhdXRob3IgTWFydGluIEJ1Y2hob2x6CiAqIEBzaW5jZSAxLjYKICovCnB1YmxpYyBjbGFzcyBFbGVtZW50RmlsdGVyIHsKICAgIHByaXZhdGUgRWxlbWVudEZpbHRlcigpIHt9IC8vIERvIG5vdCBpbnN0YW50aWF0ZS4KCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTZXQ8RWxlbWVudEtpbmQ+IENPTlNUUlVDVE9SX0tJTkQgPQogICAgICAgIENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZVNldChFbnVtU2V0Lm9mKEVsZW1lbnRLaW5kLkNPTlNUUlVDVE9SKSk7CgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU2V0PEVsZW1lbnRLaW5kPiBGSUVMRF9LSU5EUyA9CiAgICAgICAgQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlU2V0KEVudW1TZXQub2YoRWxlbWVudEtpbmQuRklFTEQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRWxlbWVudEtpbmQuRU5VTV9DT05TVEFOVCkpOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU2V0PEVsZW1lbnRLaW5kPiBNRVRIT0RfS0lORCA9CiAgICAgICAgQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlU2V0KEVudW1TZXQub2YoRWxlbWVudEtpbmQuTUVUSE9EKSk7CgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU2V0PEVsZW1lbnRLaW5kPiBQQUNLQUdFX0tJTkQgPQogICAgICAgIENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZVNldChFbnVtU2V0Lm9mKEVsZW1lbnRLaW5kLlBBQ0tBR0UpKTsKCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTZXQ8RWxlbWVudEtpbmQ+IE1PRFVMRV9LSU5EID0KICAgICAgICBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVTZXQoRW51bVNldC5vZihFbGVtZW50S2luZC5NT0RVTEUpKTsKCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTZXQ8RWxlbWVudEtpbmQ+IFRZUEVfS0lORFMgPQogICAgICAgIENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZVNldChFbnVtU2V0Lm9mKEVsZW1lbnRLaW5kLkNMQVNTLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVsZW1lbnRLaW5kLkVOVU0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRWxlbWVudEtpbmQuSU5URVJGQUNFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVsZW1lbnRLaW5kLkFOTk9UQVRJT05fVFlQRSkpOwogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgbGlzdCBvZiBmaWVsZHMgaW4ge0Bjb2RlIGVsZW1lbnRzfS4KICAgICAqIEByZXR1cm4gYSBsaXN0IG9mIGZpZWxkcyBpbiB7QGNvZGUgZWxlbWVudHN9CiAgICAgKiBAcGFyYW0gZWxlbWVudHMgdGhlIGVsZW1lbnRzIHRvIGZpbHRlcgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIExpc3Q8VmFyaWFibGVFbGVtZW50PgogICAgICAgICAgICBmaWVsZHNJbihJdGVyYWJsZTw/IGV4dGVuZHMgRWxlbWVudD4gZWxlbWVudHMpIHsKICAgICAgICByZXR1cm4gbGlzdEZpbHRlcihlbGVtZW50cywgRklFTERfS0lORFMsIFZhcmlhYmxlRWxlbWVudC5jbGFzcyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgc2V0IG9mIGZpZWxkcyBpbiB7QGNvZGUgZWxlbWVudHN9LgogICAgICogQHJldHVybiBhIHNldCBvZiBmaWVsZHMgaW4ge0Bjb2RlIGVsZW1lbnRzfQogICAgICogQHBhcmFtIGVsZW1lbnRzIHRoZSBlbGVtZW50cyB0byBmaWx0ZXIKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBTZXQ8VmFyaWFibGVFbGVtZW50PgogICAgICAgICAgICBmaWVsZHNJbihTZXQ8PyBleHRlbmRzIEVsZW1lbnQ+IGVsZW1lbnRzKSB7CiAgICAgICAgcmV0dXJuIHNldEZpbHRlcihlbGVtZW50cywgRklFTERfS0lORFMsIFZhcmlhYmxlRWxlbWVudC5jbGFzcyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgbGlzdCBvZiBjb25zdHJ1Y3RvcnMgaW4ge0Bjb2RlIGVsZW1lbnRzfS4KICAgICAqIEByZXR1cm4gYSBsaXN0IG9mIGNvbnN0cnVjdG9ycyBpbiB7QGNvZGUgZWxlbWVudHN9CiAgICAgKiBAcGFyYW0gZWxlbWVudHMgdGhlIGVsZW1lbnRzIHRvIGZpbHRlcgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIExpc3Q8RXhlY3V0YWJsZUVsZW1lbnQ+CiAgICAgICAgICAgIGNvbnN0cnVjdG9yc0luKEl0ZXJhYmxlPD8gZXh0ZW5kcyBFbGVtZW50PiBlbGVtZW50cykgewogICAgICAgIHJldHVybiBsaXN0RmlsdGVyKGVsZW1lbnRzLCBDT05TVFJVQ1RPUl9LSU5ELCBFeGVjdXRhYmxlRWxlbWVudC5jbGFzcyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgc2V0IG9mIGNvbnN0cnVjdG9ycyBpbiB7QGNvZGUgZWxlbWVudHN9LgogICAgICogQHJldHVybiBhIHNldCBvZiBjb25zdHJ1Y3RvcnMgaW4ge0Bjb2RlIGVsZW1lbnRzfQogICAgICogQHBhcmFtIGVsZW1lbnRzIHRoZSBlbGVtZW50cyB0byBmaWx0ZXIKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBTZXQ8RXhlY3V0YWJsZUVsZW1lbnQ+CiAgICAgICAgICAgIGNvbnN0cnVjdG9yc0luKFNldDw/IGV4dGVuZHMgRWxlbWVudD4gZWxlbWVudHMpIHsKICAgICAgICByZXR1cm4gc2V0RmlsdGVyKGVsZW1lbnRzLCBDT05TVFJVQ1RPUl9LSU5ELCBFeGVjdXRhYmxlRWxlbWVudC5jbGFzcyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgbGlzdCBvZiBtZXRob2RzIGluIHtAY29kZSBlbGVtZW50c30uCiAgICAgKiBAcmV0dXJuIGEgbGlzdCBvZiBtZXRob2RzIGluIHtAY29kZSBlbGVtZW50c30KICAgICAqIEBwYXJhbSBlbGVtZW50cyB0aGUgZWxlbWVudHMgdG8gZmlsdGVyCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgTGlzdDxFeGVjdXRhYmxlRWxlbWVudD4KICAgICAgICAgICAgbWV0aG9kc0luKEl0ZXJhYmxlPD8gZXh0ZW5kcyBFbGVtZW50PiBlbGVtZW50cykgewogICAgICAgIHJldHVybiBsaXN0RmlsdGVyKGVsZW1lbnRzLCBNRVRIT0RfS0lORCwgRXhlY3V0YWJsZUVsZW1lbnQuY2xhc3MpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyBhIHNldCBvZiBtZXRob2RzIGluIHtAY29kZSBlbGVtZW50c30uCiAgICAgKiBAcmV0dXJuIGEgc2V0IG9mIG1ldGhvZHMgaW4ge0Bjb2RlIGVsZW1lbnRzfQogICAgICogQHBhcmFtIGVsZW1lbnRzIHRoZSBlbGVtZW50cyB0byBmaWx0ZXIKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBTZXQ8RXhlY3V0YWJsZUVsZW1lbnQ+CiAgICAgICAgICAgIG1ldGhvZHNJbihTZXQ8PyBleHRlbmRzIEVsZW1lbnQ+IGVsZW1lbnRzKSB7CiAgICAgICAgcmV0dXJuIHNldEZpbHRlcihlbGVtZW50cywgTUVUSE9EX0tJTkQsIEV4ZWN1dGFibGVFbGVtZW50LmNsYXNzKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgYSBsaXN0IG9mIHR5cGVzIGluIHtAY29kZSBlbGVtZW50c30uCiAgICAgKiBAcmV0dXJuIGEgbGlzdCBvZiB0eXBlcyBpbiB7QGNvZGUgZWxlbWVudHN9CiAgICAgKiBAcGFyYW0gZWxlbWVudHMgdGhlIGVsZW1lbnRzIHRvIGZpbHRlcgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIExpc3Q8VHlwZUVsZW1lbnQ+CiAgICAgICAgICAgIHR5cGVzSW4oSXRlcmFibGU8PyBleHRlbmRzIEVsZW1lbnQ+IGVsZW1lbnRzKSB7CiAgICAgICAgcmV0dXJuIGxpc3RGaWx0ZXIoZWxlbWVudHMsIFRZUEVfS0lORFMsIFR5cGVFbGVtZW50LmNsYXNzKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgYSBzZXQgb2YgdHlwZXMgaW4ge0Bjb2RlIGVsZW1lbnRzfS4KICAgICAqIEByZXR1cm4gYSBzZXQgb2YgdHlwZXMgaW4ge0Bjb2RlIGVsZW1lbnRzfQogICAgICogQHBhcmFtIGVsZW1lbnRzIHRoZSBlbGVtZW50cyB0byBmaWx0ZXIKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBTZXQ8VHlwZUVsZW1lbnQ+CiAgICAgICAgICAgIHR5cGVzSW4oU2V0PD8gZXh0ZW5kcyBFbGVtZW50PiBlbGVtZW50cykgewogICAgICAgIHJldHVybiBzZXRGaWx0ZXIoZWxlbWVudHMsIFRZUEVfS0lORFMsIFR5cGVFbGVtZW50LmNsYXNzKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgYSBsaXN0IG9mIHBhY2thZ2VzIGluIHtAY29kZSBlbGVtZW50c30uCiAgICAgKiBAcmV0dXJuIGEgbGlzdCBvZiBwYWNrYWdlcyBpbiB7QGNvZGUgZWxlbWVudHN9CiAgICAgKiBAcGFyYW0gZWxlbWVudHMgdGhlIGVsZW1lbnRzIHRvIGZpbHRlcgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIExpc3Q8UGFja2FnZUVsZW1lbnQ+CiAgICAgICAgICAgIHBhY2thZ2VzSW4oSXRlcmFibGU8PyBleHRlbmRzIEVsZW1lbnQ+IGVsZW1lbnRzKSB7CiAgICAgICAgcmV0dXJuIGxpc3RGaWx0ZXIoZWxlbWVudHMsIFBBQ0tBR0VfS0lORCwgUGFja2FnZUVsZW1lbnQuY2xhc3MpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyBhIHNldCBvZiBwYWNrYWdlcyBpbiB7QGNvZGUgZWxlbWVudHN9LgogICAgICogQHJldHVybiBhIHNldCBvZiBwYWNrYWdlcyBpbiB7QGNvZGUgZWxlbWVudHN9CiAgICAgKiBAcGFyYW0gZWxlbWVudHMgdGhlIGVsZW1lbnRzIHRvIGZpbHRlcgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIFNldDxQYWNrYWdlRWxlbWVudD4KICAgICAgICAgICAgcGFja2FnZXNJbihTZXQ8PyBleHRlbmRzIEVsZW1lbnQ+IGVsZW1lbnRzKSB7CiAgICAgICAgcmV0dXJuIHNldEZpbHRlcihlbGVtZW50cywgUEFDS0FHRV9LSU5ELCBQYWNrYWdlRWxlbWVudC5jbGFzcyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgbGlzdCBvZiBtb2R1bGVzIGluIHtAY29kZSBlbGVtZW50c30uCiAgICAgKiBAcmV0dXJuIGEgbGlzdCBvZiBtb2R1bGVzIGluIHtAY29kZSBlbGVtZW50c30KICAgICAqIEBwYXJhbSBlbGVtZW50cyB0aGUgZWxlbWVudHMgdG8gZmlsdGVyCiAgICAgKiBAc2luY2UgOQogICAgICogQHNwZWMgSlBNUwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIExpc3Q8TW9kdWxlRWxlbWVudD4KICAgICAgICAgICAgbW9kdWxlc0luKEl0ZXJhYmxlPD8gZXh0ZW5kcyBFbGVtZW50PiBlbGVtZW50cykgewogICAgICAgIHJldHVybiBsaXN0RmlsdGVyKGVsZW1lbnRzLCBNT0RVTEVfS0lORCwgTW9kdWxlRWxlbWVudC5jbGFzcyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgc2V0IG9mIG1vZHVsZXMgaW4ge0Bjb2RlIGVsZW1lbnRzfS4KICAgICAqIEByZXR1cm4gYSBzZXQgb2YgbW9kdWxlcyBpbiB7QGNvZGUgZWxlbWVudHN9CiAgICAgKiBAcGFyYW0gZWxlbWVudHMgdGhlIGVsZW1lbnRzIHRvIGZpbHRlcgogICAgICogQHNpbmNlIDkKICAgICAqIEBzcGVjIEpQTVMKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBTZXQ8TW9kdWxlRWxlbWVudD4KICAgICAgICAgICAgbW9kdWxlc0luKFNldDw/IGV4dGVuZHMgRWxlbWVudD4gZWxlbWVudHMpIHsKICAgICAgICByZXR1cm4gc2V0RmlsdGVyKGVsZW1lbnRzLCBNT0RVTEVfS0lORCwgTW9kdWxlRWxlbWVudC5jbGFzcyk7CiAgICB9CgogICAgLy8gQXNzdW1lcyB0YXJnZXRLaW5kcyBhbmQgRSBhcmUgc2Vuc2libGUuCiAgICBwcml2YXRlIHN0YXRpYyA8RSBleHRlbmRzIEVsZW1lbnQ+IExpc3Q8RT4gbGlzdEZpbHRlcihJdGVyYWJsZTw/IGV4dGVuZHMgRWxlbWVudD4gZWxlbWVudHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTZXQ8RWxlbWVudEtpbmQ+IHRhcmdldEtpbmRzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2xhc3M8RT4gY2xhenopIHsKICAgICAgICBMaXN0PEU+IGxpc3QgPSBuZXcgQXJyYXlMaXN0PD4oKTsKICAgICAgICBmb3IgKEVsZW1lbnQgZSA6IGVsZW1lbnRzKSB7CiAgICAgICAgICAgIGlmICh0YXJnZXRLaW5kcy5jb250YWlucyhlLmdldEtpbmQoKSkpCiAgICAgICAgICAgICAgICBsaXN0LmFkZChjbGF6ei5jYXN0KGUpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGxpc3Q7CiAgICB9CgogICAgLy8gQXNzdW1lcyB0YXJnZXRLaW5kcyBhbmQgRSBhcmUgc2Vuc2libGUuCiAgICBwcml2YXRlIHN0YXRpYyA8RSBleHRlbmRzIEVsZW1lbnQ+IFNldDxFPiBzZXRGaWx0ZXIoU2V0PD8gZXh0ZW5kcyBFbGVtZW50PiBlbGVtZW50cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTZXQ8RWxlbWVudEtpbmQ+IHRhcmdldEtpbmRzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENsYXNzPEU+IGNsYXp6KSB7CiAgICAgICAgLy8gUmV0dXJuIHNldCBwcmVzZXJ2aW5nIGl0ZXJhdGlvbiBvcmRlciBvZiBpbnB1dCBzZXQuCiAgICAgICAgU2V0PEU+IHNldCA9IG5ldyBMaW5rZWRIYXNoU2V0PD4oKTsKICAgICAgICBmb3IgKEVsZW1lbnQgZSA6IGVsZW1lbnRzKSB7CiAgICAgICAgICAgIGlmICh0YXJnZXRLaW5kcy5jb250YWlucyhlLmdldEtpbmQoKSkpCiAgICAgICAgICAgICAgICBzZXQuYWRkKGNsYXp6LmNhc3QoZSkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gc2V0OwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyBhIGxpc3Qgb2Yge0Bjb2RlIGV4cG9ydHN9IGRpcmVjdGl2ZXMgaW4ge0Bjb2RlIGRpcmVjdGl2ZXN9LgogICAgICogQHJldHVybiBhIGxpc3Qgb2Yge0Bjb2RlIGV4cG9ydHN9IGRpcmVjdGl2ZXMgaW4ge0Bjb2RlIGRpcmVjdGl2ZXN9CiAgICAgKiBAcGFyYW0gZGlyZWN0aXZlcyB0aGUgZGlyZWN0aXZlcyB0byBmaWx0ZXIKICAgICAqIEBzaW5jZSA5CiAgICAgKiBAc3BlYyBKUE1TCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgTGlzdDxFeHBvcnRzRGlyZWN0aXZlPgogICAgICAgICAgICBleHBvcnRzSW4oSXRlcmFibGU8PyBleHRlbmRzIERpcmVjdGl2ZT4gZGlyZWN0aXZlcykgewogICAgICAgIHJldHVybiBsaXN0RmlsdGVyKGRpcmVjdGl2ZXMsIERpcmVjdGl2ZUtpbmQuRVhQT1JUUywgRXhwb3J0c0RpcmVjdGl2ZS5jbGFzcyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgbGlzdCBvZiB7QGNvZGUgb3BlbnN9IGRpcmVjdGl2ZXMgaW4ge0Bjb2RlIGRpcmVjdGl2ZXN9LgogICAgICogQHJldHVybiBhIGxpc3Qgb2Yge0Bjb2RlIG9wZW5zfSBkaXJlY3RpdmVzIGluIHtAY29kZSBkaXJlY3RpdmVzfQogICAgICogQHBhcmFtIGRpcmVjdGl2ZXMgdGhlIGRpcmVjdGl2ZXMgdG8gZmlsdGVyCiAgICAgKiBAc2luY2UgOQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIExpc3Q8T3BlbnNEaXJlY3RpdmU+CiAgICAgICAgICAgIG9wZW5zSW4oSXRlcmFibGU8PyBleHRlbmRzIERpcmVjdGl2ZT4gZGlyZWN0aXZlcykgewogICAgICAgIHJldHVybiBsaXN0RmlsdGVyKGRpcmVjdGl2ZXMsIERpcmVjdGl2ZUtpbmQuT1BFTlMsIE9wZW5zRGlyZWN0aXZlLmNsYXNzKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgYSBsaXN0IG9mIHtAY29kZSBwcm92aWRlc30gZGlyZWN0aXZlcyBpbiB7QGNvZGUgZGlyZWN0aXZlc30uCiAgICAgKiBAcmV0dXJuIGEgbGlzdCBvZiB7QGNvZGUgcHJvdmlkZXN9IGRpcmVjdGl2ZXMgaW4ge0Bjb2RlIGRpcmVjdGl2ZXN9CiAgICAgKiBAcGFyYW0gZGlyZWN0aXZlcyB0aGUgZGlyZWN0aXZlcyB0byBmaWx0ZXIKICAgICAqIEBzaW5jZSA5CiAgICAgKiBAc3BlYyBKUE1TCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgTGlzdDxQcm92aWRlc0RpcmVjdGl2ZT4KICAgICAgICAgICAgcHJvdmlkZXNJbihJdGVyYWJsZTw/IGV4dGVuZHMgRGlyZWN0aXZlPiBkaXJlY3RpdmVzKSB7CiAgICAgICAgcmV0dXJuIGxpc3RGaWx0ZXIoZGlyZWN0aXZlcywgRGlyZWN0aXZlS2luZC5QUk9WSURFUywgUHJvdmlkZXNEaXJlY3RpdmUuY2xhc3MpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyBhIGxpc3Qgb2Yge0Bjb2RlIHJlcXVpcmVzfSBkaXJlY3RpdmVzIGluIHtAY29kZSBkaXJlY3RpdmVzfS4KICAgICAqIEByZXR1cm4gYSBsaXN0IG9mIHtAY29kZSByZXF1aXJlc30gZGlyZWN0aXZlcyBpbiB7QGNvZGUgZGlyZWN0aXZlc30KICAgICAqIEBwYXJhbSBkaXJlY3RpdmVzIHRoZSBkaXJlY3RpdmVzIHRvIGZpbHRlcgogICAgICogQHNpbmNlIDkKICAgICAqIEBzcGVjIEpQTVMKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBMaXN0PFJlcXVpcmVzRGlyZWN0aXZlPgogICAgICAgICAgICByZXF1aXJlc0luKEl0ZXJhYmxlPD8gZXh0ZW5kcyBEaXJlY3RpdmU+IGRpcmVjdGl2ZXMpIHsKICAgICAgICByZXR1cm4gbGlzdEZpbHRlcihkaXJlY3RpdmVzLCBEaXJlY3RpdmVLaW5kLlJFUVVJUkVTLCBSZXF1aXJlc0RpcmVjdGl2ZS5jbGFzcyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgbGlzdCBvZiB7QGNvZGUgdXNlc30gZGlyZWN0aXZlcyBpbiB7QGNvZGUgZGlyZWN0aXZlc30uCiAgICAgKiBAcmV0dXJuIGEgbGlzdCBvZiB7QGNvZGUgdXNlc30gZGlyZWN0aXZlcyBpbiB7QGNvZGUgZGlyZWN0aXZlc30KICAgICAqIEBwYXJhbSBkaXJlY3RpdmVzIHRoZSBkaXJlY3RpdmVzIHRvIGZpbHRlcgogICAgICogQHNpbmNlIDkKICAgICAqIEBzcGVjIEpQTVMKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBMaXN0PFVzZXNEaXJlY3RpdmU+CiAgICAgICAgICAgIHVzZXNJbihJdGVyYWJsZTw/IGV4dGVuZHMgRGlyZWN0aXZlPiBkaXJlY3RpdmVzKSB7CiAgICAgICAgcmV0dXJuIGxpc3RGaWx0ZXIoZGlyZWN0aXZlcywgRGlyZWN0aXZlS2luZC5VU0VTLCBVc2VzRGlyZWN0aXZlLmNsYXNzKTsKICAgIH0KCiAgICAvLyBBc3N1bWVzIGRpcmVjdGl2ZUtpbmQgYW5kIEQgYXJlIHNlbnNpYmxlLgogICAgcHJpdmF0ZSBzdGF0aWMgPEQgZXh0ZW5kcyBEaXJlY3RpdmU+IExpc3Q8RD4gbGlzdEZpbHRlcihJdGVyYWJsZTw/IGV4dGVuZHMgRGlyZWN0aXZlPiBkaXJlY3RpdmVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRGlyZWN0aXZlS2luZCBkaXJlY3RpdmVLaW5kLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2xhc3M8RD4gY2xhenopIHsKICAgICAgICBMaXN0PEQ+IGxpc3QgPSBuZXcgQXJyYXlMaXN0PD4oKTsKICAgICAgICBmb3IgKERpcmVjdGl2ZSBkIDogZGlyZWN0aXZlcykgewogICAgICAgICAgICBpZiAoZC5nZXRLaW5kKCkgPT0gZGlyZWN0aXZlS2luZCkKICAgICAgICAgICAgICAgIGxpc3QuYWRkKGNsYXp6LmNhc3QoZCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbGlzdDsKICAgIH0KfQpQSwMECgAACAAABjupSihPy/8uFQAALhUAADIAAABqYXZheC9sYW5nL21vZGVsL3V0aWwvQWJzdHJhY3RFbGVtZW50VmlzaXRvcjYuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAxNywgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBqYXZheC5sYW5nLm1vZGVsLnV0aWw7CgppbXBvcnQgamF2YXguYW5ub3RhdGlvbi5wcm9jZXNzaW5nLlN1cHBvcnRlZFNvdXJjZVZlcnNpb247CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLlNvdXJjZVZlcnNpb247CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuKjsKaW1wb3J0IHN0YXRpYyBqYXZheC5sYW5nLm1vZGVsLlNvdXJjZVZlcnNpb24uKjsKCgovKioKICogQSBza2VsZXRhbCB2aXNpdG9yIG9mIHByb2dyYW0gZWxlbWVudHMgd2l0aCBkZWZhdWx0IGJlaGF2aW9yCiAqIGFwcHJvcHJpYXRlIGZvciB0aGUge0BsaW5rIFNvdXJjZVZlcnNpb24jUkVMRUFTRV82IFJFTEVBU0VfNn0KICogc291cmNlIHZlcnNpb24uCiAqCiAqIDxwPiA8Yj5XQVJOSU5HOjwvYj4gVGhlIHtAY29kZSBFbGVtZW50VmlzaXRvcn0gaW50ZXJmYWNlCiAqIGltcGxlbWVudGVkIGJ5IHRoaXMgY2xhc3MgbWF5IGhhdmUgbWV0aG9kcyBhZGRlZCB0byBpdCBpbiB0aGUKICogZnV0dXJlIHRvIGFjY29tbW9kYXRlIG5ldywgY3VycmVudGx5IHVua25vd24sIGxhbmd1YWdlIHN0cnVjdHVyZXMKICogYWRkZWQgdG8gZnV0dXJlIHZlcnNpb25zIG9mIHRoZSBKYXZhJnRyYWRlOyBwcm9ncmFtbWluZyBsYW5ndWFnZS4KICogVGhlcmVmb3JlLCBtZXRob2RzIHdob3NlIG5hbWVzIGJlZ2luIHdpdGgge0Bjb2RlICJ2aXNpdCJ9IG1heSBiZQogKiBhZGRlZCB0byB0aGlzIGNsYXNzIGluIHRoZSBmdXR1cmU7IHRvIGF2b2lkIGluY29tcGF0aWJpbGl0aWVzLAogKiBjbGFzc2VzIHdoaWNoIGV4dGVuZCB0aGlzIGNsYXNzIHNob3VsZCBub3QgZGVjbGFyZSBhbnkgaW5zdGFuY2UKICogbWV0aG9kcyB3aXRoIG5hbWVzIGJlZ2lubmluZyB3aXRoIHtAY29kZSAidmlzaXQifS4KICoKICogPHA+V2hlbiBzdWNoIGEgbmV3IHZpc2l0IG1ldGhvZCBpcyBhZGRlZCwgdGhlIGRlZmF1bHQKICogaW1wbGVtZW50YXRpb24gaW4gdGhpcyBjbGFzcyB3aWxsIGJlIHRvIGNhbGwgdGhlIHtAbGluawogKiAjdmlzaXRVbmtub3duIHZpc2l0VW5rbm93bn0gbWV0aG9kLiAgQSBuZXcgYWJzdHJhY3QgZWxlbWVudCB2aXNpdG9yCiAqIGNsYXNzIHdpbGwgYWxzbyBiZSBpbnRyb2R1Y2VkIHRvIGNvcnJlc3BvbmQgdG8gdGhlIG5ldyBsYW5ndWFnZQogKiBsZXZlbDsgdGhpcyB2aXNpdG9yIHdpbGwgaGF2ZSBkaWZmZXJlbnQgZGVmYXVsdCBiZWhhdmlvciBmb3IgdGhlCiAqIHZpc2l0IG1ldGhvZCBpbiBxdWVzdGlvbi4gIFdoZW4gdGhlIG5ldyB2aXNpdG9yIGlzIGludHJvZHVjZWQsIGFsbAogKiBvciBwb3J0aW9ucyBvZiB0aGlzIHZpc2l0b3IgbWF5IGJlIGRlcHJlY2F0ZWQuCiAqCiAqIEBwYXJhbSA8Uj4gdGhlIHJldHVybiB0eXBlIG9mIHRoaXMgdmlzaXRvcidzIG1ldGhvZHMuICBVc2Uge0BsaW5rCiAqICAgICAgICAgICAgVm9pZH0gZm9yIHZpc2l0b3JzIHRoYXQgZG8gbm90IG5lZWQgdG8gcmV0dXJuIHJlc3VsdHMuCiAqIEBwYXJhbSA8UD4gdGhlIHR5cGUgb2YgdGhlIGFkZGl0aW9uYWwgcGFyYW1ldGVyIHRvIHRoaXMgdmlzaXRvcidzCiAqICAgICAgICAgICAgbWV0aG9kcy4gIFVzZSB7QGNvZGUgVm9pZH0gZm9yIHZpc2l0b3JzIHRoYXQgZG8gbm90IG5lZWQgYW4KICogICAgICAgICAgICBhZGRpdGlvbmFsIHBhcmFtZXRlci4KICoKICogQGF1dGhvciBKb3NlcGggRC4gRGFyY3kKICogQGF1dGhvciBTY290dCBTZWxpZ21hbgogKiBAYXV0aG9yIFBldGVyIHZvbiBkZXIgQWgmZWFjdXRlOwogKgogKiBAc2VlIEFic3RyYWN0RWxlbWVudFZpc2l0b3I3CiAqIEBzZWUgQWJzdHJhY3RFbGVtZW50VmlzaXRvcjgKICogQHNlZSBBYnN0cmFjdEVsZW1lbnRWaXNpdG9yOQogKiBAc2luY2UgMS42CiAqLwpAU3VwcG9ydGVkU291cmNlVmVyc2lvbihSRUxFQVNFXzYpCnB1YmxpYyBhYnN0cmFjdCBjbGFzcyBBYnN0cmFjdEVsZW1lbnRWaXNpdG9yNjxSLCBQPiBpbXBsZW1lbnRzIEVsZW1lbnRWaXNpdG9yPFIsIFA+IHsKICAgIC8qKgogICAgICogQ29uc3RydWN0b3IgZm9yIGNvbmNyZXRlIHN1YmNsYXNzZXMgdG8gY2FsbC4KICAgICAqIEBkZXByZWNhdGVkIFJlbGVhc2UgNiBpcyBvYnNvbGV0ZTsgdXBkYXRlIHRvIGEgdmlzaXRvciBmb3IgYSBuZXdlcgogICAgICogcmVsZWFzZSBsZXZlbC4KICAgICAqLwogICAgQERlcHJlY2F0ZWQKICAgIHByb3RlY3RlZCBBYnN0cmFjdEVsZW1lbnRWaXNpdG9yNigpe30KCiAgICAvKioKICAgICAqIFZpc2l0cyBhbnkgcHJvZ3JhbSBlbGVtZW50IGFzIGlmIGJ5IHBhc3NpbmcgaXRzZWxmIHRvIHRoYXQKICAgICAqIGVsZW1lbnQncyB7QGxpbmsgRWxlbWVudCNhY2NlcHQgYWNjZXB0fSBtZXRob2QuICBUaGUgaW52b2NhdGlvbgogICAgICoge0Bjb2RlIHYudmlzaXQoZWxlbSwgcCl9IGlzIGVxdWl2YWxlbnQgdG8ge0Bjb2RlIGVsZW0uYWNjZXB0KHYsCiAgICAgKiBwKX0uCiAgICAgKgogICAgICogQHBhcmFtIGUgIHRoZSBlbGVtZW50IHRvIHZpc2l0CiAgICAgKiBAcGFyYW0gcCAgYSB2aXNpdG9yLXNwZWNpZmllZCBwYXJhbWV0ZXIKICAgICAqIEByZXR1cm4gYSB2aXNpdG9yLXNwZWNpZmllZCByZXN1bHQKICAgICAqLwogICAgcHVibGljIGZpbmFsIFIgdmlzaXQoRWxlbWVudCBlLCBQIHApIHsKICAgICAgICByZXR1cm4gZS5hY2NlcHQodGhpcywgcCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBWaXNpdHMgYW55IHByb2dyYW0gZWxlbWVudCBhcyBpZiBieSBwYXNzaW5nIGl0c2VsZiB0byB0aGF0CiAgICAgKiBlbGVtZW50J3Mge0BsaW5rIEVsZW1lbnQjYWNjZXB0IGFjY2VwdH0gbWV0aG9kIGFuZCBwYXNzaW5nCiAgICAgKiB7QGNvZGUgbnVsbH0gZm9yIHRoZSBhZGRpdGlvbmFsIHBhcmFtZXRlci4gIFRoZSBpbnZvY2F0aW9uCiAgICAgKiB7QGNvZGUgdi52aXNpdChlbGVtKX0gaXMgZXF1aXZhbGVudCB0byB7QGNvZGUgZWxlbS5hY2NlcHQodiwKICAgICAqIG51bGwpfS4KICAgICAqCiAgICAgKiBAcGFyYW0gZSAgdGhlIGVsZW1lbnQgdG8gdmlzaXQKICAgICAqIEByZXR1cm4gYSB2aXNpdG9yLXNwZWNpZmllZCByZXN1bHQKICAgICAqLwogICAgcHVibGljIGZpbmFsIFIgdmlzaXQoRWxlbWVudCBlKSB7CiAgICAgICAgcmV0dXJuIGUuYWNjZXB0KHRoaXMsIG51bGwpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICoKICAgICAqIEBpbXBsU3BlYyBUaGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGlzIG1ldGhvZCBpbgogICAgICoge0Bjb2RlIEFic3RyYWN0RWxlbWVudFZpc2l0b3I2fSB3aWxsIGFsd2F5cyB0aHJvdwogICAgICoge0Bjb2RlIG5ldyBVbmtub3duRWxlbWVudEV4Y2VwdGlvbihlLCBwKX0uCiAgICAgKiBUaGlzIGJlaGF2aW9yIGlzIG5vdCByZXF1aXJlZCBvZiBhIHN1YmNsYXNzLgogICAgICoKICAgICAqIEBwYXJhbSBlIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gYSB2aXNpdG9yLXNwZWNpZmllZCByZXN1bHQKICAgICAqIEB0aHJvd3MgVW5rbm93bkVsZW1lbnRFeGNlcHRpb24KICAgICAqICAgICAgICAgIGEgdmlzaXRvciBpbXBsZW1lbnRhdGlvbiBtYXkgb3B0aW9uYWxseSB0aHJvdyB0aGlzIGV4Y2VwdGlvbgogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0VW5rbm93bihFbGVtZW50IGUsIFAgcCkgewogICAgICAgIHRocm93IG5ldyBVbmtub3duRWxlbWVudEV4Y2VwdGlvbihlLCBwKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqCiAgICAgKiBAaW1wbFNwZWMgVmlzaXRzIGEge0Bjb2RlIE1vZHVsZUVsZW1lbnR9IGJ5IGNhbGxpbmcge0Bjb2RlCiAgICAgKiB2aXNpdFVua25vd259LgogICAgICoKICAgICAqIEBwYXJhbSBlICB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiB0aGUgcmVzdWx0IG9mIHtAY29kZSB2aXNpdFVua25vd259CiAgICAgKgogICAgICogQHNpbmNlIDkKICAgICAqIEBzcGVjIEpQTVMKICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgUiB2aXNpdE1vZHVsZShNb2R1bGVFbGVtZW50IGUsIFAgcCkgewogICAgICAgIC8vIFVzZSBpbXBsZW1lbnRhdGlvbiBmcm9tIGludGVyZmFjZSBkZWZhdWx0IG1ldGhvZAogICAgICAgIHJldHVybiBFbGVtZW50VmlzaXRvci5zdXBlci52aXNpdE1vZHVsZShlLCBwKTsKICAgIH0KfQpQSwMECgAACAAABjupSij7xmxXEQAAVxEAAC0AAABqYXZheC9sYW5nL21vZGVsL3V0aWwvU2ltcGxlVHlwZVZpc2l0b3I3LmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTAsIDIwMTcsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgamF2YXgubGFuZy5tb2RlbC51dGlsOwoKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwudHlwZS4qOwppbXBvcnQgamF2YXguYW5ub3RhdGlvbi5wcm9jZXNzaW5nLlN1cHBvcnRlZFNvdXJjZVZlcnNpb247CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLlNvdXJjZVZlcnNpb247CmltcG9ydCBzdGF0aWMgamF2YXgubGFuZy5tb2RlbC5Tb3VyY2VWZXJzaW9uLio7CgovKioKICogQSBzaW1wbGUgdmlzaXRvciBvZiB0eXBlcyB3aXRoIGRlZmF1bHQgYmVoYXZpb3IgYXBwcm9wcmlhdGUgZm9yIHRoZQogKiB7QGxpbmsgU291cmNlVmVyc2lvbiNSRUxFQVNFXzcgUkVMRUFTRV83fSBzb3VyY2UgdmVyc2lvbi4KICoKICogVmlzaXQgbWV0aG9kcyBjb3JyZXNwb25kaW5nIHRvIHtAY29kZSBSRUxFQVNFXzd9IGFuZCBlYXJsaWVyCiAqIGxhbmd1YWdlIGNvbnN0cnVjdHMgY2FsbCB7QGxpbmsgI2RlZmF1bHRBY3Rpb24gZGVmYXVsdEFjdGlvbn0sCiAqIHBhc3NpbmcgdGhlaXIgYXJndW1lbnRzIHRvIHtAY29kZSBkZWZhdWx0QWN0aW9ufSdzIGNvcnJlc3BvbmRpbmcKICogcGFyYW1ldGVycy4KICoKICogPHA+IE1ldGhvZHMgaW4gdGhpcyBjbGFzcyBtYXkgYmUgb3ZlcnJpZGRlbiBzdWJqZWN0IHRvIHRoZWlyCiAqIGdlbmVyYWwgY29udHJhY3QuICBOb3RlIHRoYXQgYW5ub3RhdGluZyBtZXRob2RzIGluIGNvbmNyZXRlCiAqIHN1YmNsYXNzZXMgd2l0aCB7QGxpbmsgamF2YS5sYW5nLk92ZXJyaWRlIEBPdmVycmlkZX0gd2lsbCBoZWxwCiAqIGVuc3VyZSB0aGF0IG1ldGhvZHMgYXJlIG92ZXJyaWRkZW4gYXMgaW50ZW5kZWQuCiAqCiAqIDxwPiA8Yj5XQVJOSU5HOjwvYj4gVGhlIHtAY29kZSBUeXBlVmlzaXRvcn0gaW50ZXJmYWNlIGltcGxlbWVudGVkCiAqIGJ5IHRoaXMgY2xhc3MgbWF5IGhhdmUgbWV0aG9kcyBhZGRlZCB0byBpdCBpbiB0aGUgZnV0dXJlIHRvCiAqIGFjY29tbW9kYXRlIG5ldywgY3VycmVudGx5IHVua25vd24sIGxhbmd1YWdlIHN0cnVjdHVyZXMgYWRkZWQgdG8KICogZnV0dXJlIHZlcnNpb25zIG9mIHRoZSBKYXZhJnRyYWRlOyBwcm9ncmFtbWluZyBsYW5ndWFnZS4KICogVGhlcmVmb3JlLCBtZXRob2RzIHdob3NlIG5hbWVzIGJlZ2luIHdpdGgge0Bjb2RlICJ2aXNpdCJ9IG1heSBiZQogKiBhZGRlZCB0byB0aGlzIGNsYXNzIGluIHRoZSBmdXR1cmU7IHRvIGF2b2lkIGluY29tcGF0aWJpbGl0aWVzLAogKiBjbGFzc2VzIHdoaWNoIGV4dGVuZCB0aGlzIGNsYXNzIHNob3VsZCBub3QgZGVjbGFyZSBhbnkgaW5zdGFuY2UKICogbWV0aG9kcyB3aXRoIG5hbWVzIGJlZ2lubmluZyB3aXRoIHtAY29kZSAidmlzaXQifS4KICoKICogPHA+V2hlbiBzdWNoIGEgbmV3IHZpc2l0IG1ldGhvZCBpcyBhZGRlZCwgdGhlIGRlZmF1bHQKICogaW1wbGVtZW50YXRpb24gaW4gdGhpcyBjbGFzcyB3aWxsIGJlIHRvIGNhbGwgdGhlIHtAbGluawogKiAjdmlzaXRVbmtub3duIHZpc2l0VW5rbm93bn0gbWV0aG9kLiAgQSBuZXcgc2ltcGxlIHR5cGUgdmlzaXRvcgogKiBjbGFzcyB3aWxsIGFsc28gYmUgaW50cm9kdWNlZCB0byBjb3JyZXNwb25kIHRvIHRoZSBuZXcgbGFuZ3VhZ2UKICogbGV2ZWw7IHRoaXMgdmlzaXRvciB3aWxsIGhhdmUgZGlmZmVyZW50IGRlZmF1bHQgYmVoYXZpb3IgZm9yIHRoZQogKiB2aXNpdCBtZXRob2QgaW4gcXVlc3Rpb24uICBXaGVuIHRoZSBuZXcgdmlzaXRvciBpcyBpbnRyb2R1Y2VkLCBhbGwKICogb3IgcG9ydGlvbnMgb2YgdGhpcyB2aXNpdG9yIG1heSBiZSBkZXByZWNhdGVkLgogKgogKiBAcGFyYW0gPFI+IHRoZSByZXR1cm4gdHlwZSBvZiB0aGlzIHZpc2l0b3IncyBtZXRob2RzLiAgVXNlIHtAbGluawogKiAgICAgICAgICAgIFZvaWR9IGZvciB2aXNpdG9ycyB0aGF0IGRvIG5vdCBuZWVkIHRvIHJldHVybiByZXN1bHRzLgogKiBAcGFyYW0gPFA+IHRoZSB0eXBlIG9mIHRoZSBhZGRpdGlvbmFsIHBhcmFtZXRlciB0byB0aGlzIHZpc2l0b3IncwogKiAgICAgICAgICAgIG1ldGhvZHMuICBVc2Uge0Bjb2RlIFZvaWR9IGZvciB2aXNpdG9ycyB0aGF0IGRvIG5vdCBuZWVkIGFuCiAqICAgICAgICAgICAgYWRkaXRpb25hbCBwYXJhbWV0ZXIuCiAqCiAqIEBzZWUgU2ltcGxlVHlwZVZpc2l0b3I2CiAqIEBzZWUgU2ltcGxlVHlwZVZpc2l0b3I4CiAqIEBzZWUgU2ltcGxlVHlwZVZpc2l0b3I5CiAqIEBzaW5jZSAxLjcKICovCkBTdXBwb3J0ZWRTb3VyY2VWZXJzaW9uKFJFTEVBU0VfNykKcHVibGljIGNsYXNzIFNpbXBsZVR5cGVWaXNpdG9yNzxSLCBQPiBleHRlbmRzIFNpbXBsZVR5cGVWaXNpdG9yNjxSLCBQPiB7CiAgICAvKioKICAgICAqIENvbnN0cnVjdG9yIGZvciBjb25jcmV0ZSBzdWJjbGFzc2VzOyB1c2VzIHtAY29kZSBudWxsfSBmb3IgdGhlCiAgICAgKiBkZWZhdWx0IHZhbHVlLgogICAgICovCiAgICBAU3VwcHJlc3NXYXJuaW5ncygiZGVwcmVjYXRpb24iKSAvLyBTdXBlcmNsYXNzIGNvbnN0cnVjdG9yIGRlcHJlY2F0ZWQKICAgIHByb3RlY3RlZCBTaW1wbGVUeXBlVmlzaXRvcjcoKXsKICAgICAgICBzdXBlcihudWxsKTsKICAgIH0KCiAgICAvKioKICAgICAqIENvbnN0cnVjdG9yIGZvciBjb25jcmV0ZSBzdWJjbGFzc2VzOyB1c2VzIHRoZSBhcmd1bWVudCBmb3IgdGhlCiAgICAgKiBkZWZhdWx0IHZhbHVlLgogICAgICoKICAgICAqIEBwYXJhbSBkZWZhdWx0VmFsdWUgdGhlIHZhbHVlIHRvIGFzc2lnbiB0byB7QGxpbmsgI0RFRkFVTFRfVkFMVUV9CiAgICAgKi8KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJkZXByZWNhdGlvbiIpIC8vIFN1cGVyY2xhc3MgY29uc3RydWN0b3IgZGVwcmVjYXRlZAogICAgcHJvdGVjdGVkIFNpbXBsZVR5cGVWaXNpdG9yNyhSIGRlZmF1bHRWYWx1ZSl7CiAgICAgICAgc3VwZXIoZGVmYXVsdFZhbHVlKTsKICAgIH0KCiAgICAvKioKICAgICAqIFRoaXMgaW1wbGVtZW50YXRpb24gdmlzaXRzIGEge0Bjb2RlIFVuaW9uVHlwZX0gYnkgY2FsbGluZwogICAgICoge0Bjb2RlIGRlZmF1bHRBY3Rpb259LgogICAgICoKICAgICAqIEBwYXJhbSB0ICB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiB0aGUgcmVzdWx0IG9mIHtAY29kZSBkZWZhdWx0QWN0aW9ufQogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0VW5pb24oVW5pb25UeXBlIHQsIFAgcCkgewogICAgICAgIHJldHVybiBkZWZhdWx0QWN0aW9uKHQsIHApOwogICAgfQp9ClBLAwQKAAAIAAAGO6lKLl4tKFASAABQEgAAKwAAAGphdmF4L2xhbmcvbW9kZWwvdXRpbC9UeXBlS2luZFZpc2l0b3I3LmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTAsIDIwMTcsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgamF2YXgubGFuZy5tb2RlbC51dGlsOwoKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwudHlwZS4qOwppbXBvcnQgamF2YXguYW5ub3RhdGlvbi5wcm9jZXNzaW5nLlN1cHBvcnRlZFNvdXJjZVZlcnNpb247CmltcG9ydCBzdGF0aWMgamF2YXgubGFuZy5tb2RlbC5Tb3VyY2VWZXJzaW9uLio7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLlNvdXJjZVZlcnNpb247CgovKioKICogQSB2aXNpdG9yIG9mIHR5cGVzIGJhc2VkIG9uIHRoZWlyIHtAbGlua3BsYWluIFR5cGVLaW5kIGtpbmR9IHdpdGgKICogZGVmYXVsdCBiZWhhdmlvciBhcHByb3ByaWF0ZSBmb3IgdGhlIHtAbGluayBTb3VyY2VWZXJzaW9uI1JFTEVBU0VfNwogKiBSRUxFQVNFXzd9IHNvdXJjZSB2ZXJzaW9uLiAgRm9yIHtAbGlua3BsYWluCiAqIFR5cGVNaXJyb3IgdHlwZXN9IDxjb2RlPjxpPlh5ejwvaT48L2NvZGU+IHRoYXQgbWF5IGhhdmUgbW9yZSB0aGFuIG9uZQogKiBraW5kLCB0aGUgPGNvZGU+dmlzaXQ8aT5YeXo8L2k+PC9jb2RlPiBtZXRob2RzIGluIHRoaXMgY2xhc3MgZGVsZWdhdGUKICogdG8gdGhlIDxjb2RlPnZpc2l0PGk+WHl6PC9pPkFzPGk+S2luZDwvaT48L2NvZGU+IG1ldGhvZCBjb3JyZXNwb25kaW5nIHRvIHRoZQogKiBmaXJzdCBhcmd1bWVudCdzIGtpbmQuICBUaGUgPGNvZGU+dmlzaXQ8aT5YeXo8L2k+QXM8aT5LaW5kPC9pPjwvY29kZT4gbWV0aG9kcwogKiBjYWxsIHtAbGluayAjZGVmYXVsdEFjdGlvbiBkZWZhdWx0QWN0aW9ufSwgcGFzc2luZyB0aGVpciBhcmd1bWVudHMKICogdG8ge0Bjb2RlIGRlZmF1bHRBY3Rpb259J3MgY29ycmVzcG9uZGluZyBwYXJhbWV0ZXJzLgogKgogKiA8cD4gTWV0aG9kcyBpbiB0aGlzIGNsYXNzIG1heSBiZSBvdmVycmlkZGVuIHN1YmplY3QgdG8gdGhlaXIKICogZ2VuZXJhbCBjb250cmFjdC4gIE5vdGUgdGhhdCBhbm5vdGF0aW5nIG1ldGhvZHMgaW4gY29uY3JldGUKICogc3ViY2xhc3NlcyB3aXRoIHtAbGluayBqYXZhLmxhbmcuT3ZlcnJpZGUgQE92ZXJyaWRlfSB3aWxsIGhlbHAKICogZW5zdXJlIHRoYXQgbWV0aG9kcyBhcmUgb3ZlcnJpZGRlbiBhcyBpbnRlbmRlZC4KICoKICogPHA+IDxiPldBUk5JTkc6PC9iPiBUaGUge0Bjb2RlIFR5cGVWaXNpdG9yfSBpbnRlcmZhY2UgaW1wbGVtZW50ZWQKICogYnkgdGhpcyBjbGFzcyBtYXkgaGF2ZSBtZXRob2RzIGFkZGVkIHRvIGl0IGluIHRoZSBmdXR1cmUgdG8KICogYWNjb21tb2RhdGUgbmV3LCBjdXJyZW50bHkgdW5rbm93biwgbGFuZ3VhZ2Ugc3RydWN0dXJlcyBhZGRlZCB0bwogKiBmdXR1cmUgdmVyc2lvbnMgb2YgdGhlIEphdmEmdHJhZGU7IHByb2dyYW1taW5nIGxhbmd1YWdlLgogKiBUaGVyZWZvcmUsIG1ldGhvZHMgd2hvc2UgbmFtZXMgYmVnaW4gd2l0aCB7QGNvZGUgInZpc2l0In0gbWF5IGJlCiAqIGFkZGVkIHRvIHRoaXMgY2xhc3MgaW4gdGhlIGZ1dHVyZTsgdG8gYXZvaWQgaW5jb21wYXRpYmlsaXRpZXMsCiAqIGNsYXNzZXMgd2hpY2ggZXh0ZW5kIHRoaXMgY2xhc3Mgc2hvdWxkIG5vdCBkZWNsYXJlIGFueSBpbnN0YW5jZQogKiBtZXRob2RzIHdpdGggbmFtZXMgYmVnaW5uaW5nIHdpdGgge0Bjb2RlICJ2aXNpdCJ9LgogKgogKiA8cD5XaGVuIHN1Y2ggYSBuZXcgdmlzaXQgbWV0aG9kIGlzIGFkZGVkLCB0aGUgZGVmYXVsdAogKiBpbXBsZW1lbnRhdGlvbiBpbiB0aGlzIGNsYXNzIHdpbGwgYmUgdG8gY2FsbCB0aGUge0BsaW5rCiAqICN2aXNpdFVua25vd24gdmlzaXRVbmtub3dufSBtZXRob2QuICBBIG5ldyB0eXBlIGtpbmQgdmlzaXRvciBjbGFzcwogKiB3aWxsIGFsc28gYmUgaW50cm9kdWNlZCB0byBjb3JyZXNwb25kIHRvIHRoZSBuZXcgbGFuZ3VhZ2UgbGV2ZWw7CiAqIHRoaXMgdmlzaXRvciB3aWxsIGhhdmUgZGlmZmVyZW50IGRlZmF1bHQgYmVoYXZpb3IgZm9yIHRoZSB2aXNpdAogKiBtZXRob2QgaW4gcXVlc3Rpb24uICBXaGVuIHRoZSBuZXcgdmlzaXRvciBpcyBpbnRyb2R1Y2VkLCBhbGwgb3IKICogcG9ydGlvbnMgb2YgdGhpcyB2aXNpdG9yIG1heSBiZSBkZXByZWNhdGVkLgogKgogKiBAcGFyYW0gPFI+IHRoZSByZXR1cm4gdHlwZSBvZiB0aGlzIHZpc2l0b3IncyBtZXRob2RzLiAgVXNlIHtAbGluawogKiAgICAgICAgICAgIFZvaWR9IGZvciB2aXNpdG9ycyB0aGF0IGRvIG5vdCBuZWVkIHRvIHJldHVybiByZXN1bHRzLgogKiBAcGFyYW0gPFA+IHRoZSB0eXBlIG9mIHRoZSBhZGRpdGlvbmFsIHBhcmFtZXRlciB0byB0aGlzIHZpc2l0b3IncwogKiAgICAgICAgICAgIG1ldGhvZHMuICBVc2Uge0Bjb2RlIFZvaWR9IGZvciB2aXNpdG9ycyB0aGF0IGRvIG5vdCBuZWVkIGFuCiAqICAgICAgICAgICAgYWRkaXRpb25hbCBwYXJhbWV0ZXIuCiAqCiAqIEBzZWUgVHlwZUtpbmRWaXNpdG9yNgogKiBAc2VlIFR5cGVLaW5kVmlzaXRvcjgKICogQHNpbmNlIDEuNwogKi8KQFN1cHBvcnRlZFNvdXJjZVZlcnNpb24oUkVMRUFTRV83KQpwdWJsaWMgY2xhc3MgVHlwZUtpbmRWaXNpdG9yNzxSLCBQPiBleHRlbmRzIFR5cGVLaW5kVmlzaXRvcjY8UiwgUD4gewogICAgLyoqCiAgICAgKiBDb25zdHJ1Y3RvciBmb3IgY29uY3JldGUgc3ViY2xhc3NlcyB0byBjYWxsOyB1c2VzIHtAY29kZSBudWxsfQogICAgICogZm9yIHRoZSBkZWZhdWx0IHZhbHVlLgogICAgICovCiAgICBAU3VwcHJlc3NXYXJuaW5ncygiZGVwcmVjYXRpb24iKSAvLyBTdXBlcmNsYXNzIGNvbnN0cnVjdG9yIGRlcHJlY2F0ZWQKICAgIHByb3RlY3RlZCBUeXBlS2luZFZpc2l0b3I3KCkgewogICAgICAgIHN1cGVyKG51bGwpOwogICAgfQoKICAgIC8qKgogICAgICogQ29uc3RydWN0b3IgZm9yIGNvbmNyZXRlIHN1YmNsYXNzZXMgdG8gY2FsbDsgdXNlcyB0aGUgYXJndW1lbnQKICAgICAqIGZvciB0aGUgZGVmYXVsdCB2YWx1ZS4KICAgICAqCiAgICAgKiBAcGFyYW0gZGVmYXVsdFZhbHVlIHRoZSB2YWx1ZSB0byBhc3NpZ24gdG8ge0BsaW5rICNERUZBVUxUX1ZBTFVFfQogICAgICovCiAgICBAU3VwcHJlc3NXYXJuaW5ncygiZGVwcmVjYXRpb24iKSAvLyBTdXBlcmNsYXNzIGNvbnN0cnVjdG9yIGRlcHJlY2F0ZWQKICAgIHByb3RlY3RlZCBUeXBlS2luZFZpc2l0b3I3KFIgZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgc3VwZXIoZGVmYXVsdFZhbHVlKTsKICAgIH0KCiAgICAvKioKICAgICAqIFRoaXMgaW1wbGVtZW50YXRpb24gdmlzaXRzIGEge0Bjb2RlIFVuaW9uVHlwZX0gYnkgY2FsbGluZwogICAgICoge0Bjb2RlIGRlZmF1bHRBY3Rpb259LgogICAgICoKICAgICAqIEBwYXJhbSB0ICB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiB0aGUgcmVzdWx0IG9mIHtAY29kZSBkZWZhdWx0QWN0aW9ufQogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0VW5pb24oVW5pb25UeXBlIHQsIFAgcCkgewogICAgICAgIHJldHVybiBkZWZhdWx0QWN0aW9uKHQsIHApOwogICAgfQp9ClBLAwQKAAAIAAAGO6lKx/j9VvsVAAD7FQAALwAAAGphdmF4L2xhbmcvbW9kZWwvdXRpbC9BYnN0cmFjdFR5cGVWaXNpdG9yNi5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDA1LCAyMDE3LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGphdmF4LmxhbmcubW9kZWwudXRpbDsKCmltcG9ydCBqYXZheC5hbm5vdGF0aW9uLnByb2Nlc3NpbmcuU3VwcG9ydGVkU291cmNlVmVyc2lvbjsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwudHlwZS4qOwoKaW1wb3J0IHN0YXRpYyBqYXZheC5sYW5nLm1vZGVsLlNvdXJjZVZlcnNpb24uKjsKCi8qKgogKiBBIHNrZWxldGFsIHZpc2l0b3Igb2YgdHlwZXMgd2l0aCBkZWZhdWx0IGJlaGF2aW9yIGFwcHJvcHJpYXRlIGZvcgogKiB0aGUge0BsaW5rIGphdmF4LmxhbmcubW9kZWwuU291cmNlVmVyc2lvbiNSRUxFQVNFXzYgUkVMRUFTRV82fQogKiBzb3VyY2UgdmVyc2lvbi4KICoKICogPHA+IDxiPldBUk5JTkc6PC9iPiBUaGUge0Bjb2RlIFR5cGVWaXNpdG9yfSBpbnRlcmZhY2UgaW1wbGVtZW50ZWQKICogYnkgdGhpcyBjbGFzcyBtYXkgaGF2ZSBtZXRob2RzIGFkZGVkIHRvIGl0IGluIHRoZSBmdXR1cmUgdG8KICogYWNjb21tb2RhdGUgbmV3LCBjdXJyZW50bHkgdW5rbm93biwgbGFuZ3VhZ2Ugc3RydWN0dXJlcyBhZGRlZCB0bwogKiBmdXR1cmUgdmVyc2lvbnMgb2YgdGhlIEphdmEmdHJhZGU7IHByb2dyYW1taW5nIGxhbmd1YWdlLgogKiBUaGVyZWZvcmUsIG1ldGhvZHMgd2hvc2UgbmFtZXMgYmVnaW4gd2l0aCB7QGNvZGUgInZpc2l0In0gbWF5IGJlCiAqIGFkZGVkIHRvIHRoaXMgY2xhc3MgaW4gdGhlIGZ1dHVyZTsgdG8gYXZvaWQgaW5jb21wYXRpYmlsaXRpZXMsCiAqIGNsYXNzZXMgd2hpY2ggZXh0ZW5kIHRoaXMgY2xhc3Mgc2hvdWxkIG5vdCBkZWNsYXJlIGFueSBpbnN0YW5jZQogKiBtZXRob2RzIHdpdGggbmFtZXMgYmVnaW5uaW5nIHdpdGgge0Bjb2RlICJ2aXNpdCJ9LgogKgogKiA8cD5XaGVuIHN1Y2ggYSBuZXcgdmlzaXQgbWV0aG9kIGlzIGFkZGVkLCB0aGUgZGVmYXVsdAogKiBpbXBsZW1lbnRhdGlvbiBpbiB0aGlzIGNsYXNzIHdpbGwgYmUgdG8gY2FsbCB0aGUge0BsaW5rCiAqICN2aXNpdFVua25vd24gdmlzaXRVbmtub3dufSBtZXRob2QuICBBIG5ldyBhYnN0cmFjdCB0eXBlIHZpc2l0b3IKICogY2xhc3Mgd2lsbCBhbHNvIGJlIGludHJvZHVjZWQgdG8gY29ycmVzcG9uZCB0byB0aGUgbmV3IGxhbmd1YWdlCiAqIGxldmVsOyB0aGlzIHZpc2l0b3Igd2lsbCBoYXZlIGRpZmZlcmVudCBkZWZhdWx0IGJlaGF2aW9yIGZvciB0aGUKICogdmlzaXQgbWV0aG9kIGluIHF1ZXN0aW9uLiAgV2hlbiB0aGUgbmV3IHZpc2l0b3IgaXMgaW50cm9kdWNlZCwgYWxsCiAqIG9yIHBvcnRpb25zIG9mIHRoaXMgdmlzaXRvciBtYXkgYmUgZGVwcmVjYXRlZC4KICoKICogQHBhcmFtIDxSPiB0aGUgcmV0dXJuIHR5cGUgb2YgdGhpcyB2aXNpdG9yJ3MgbWV0aG9kcy4gIFVzZSB7QGxpbmsKICogICAgICAgICAgICBWb2lkfSBmb3IgdmlzaXRvcnMgdGhhdCBkbyBub3QgbmVlZCB0byByZXR1cm4gcmVzdWx0cy4KICogQHBhcmFtIDxQPiB0aGUgdHlwZSBvZiB0aGUgYWRkaXRpb25hbCBwYXJhbWV0ZXIgdG8gdGhpcyB2aXNpdG9yJ3MKICogICAgICAgICAgICBtZXRob2RzLiAgVXNlIHtAY29kZSBWb2lkfSBmb3IgdmlzaXRvcnMgdGhhdCBkbyBub3QgbmVlZCBhbgogKiAgICAgICAgICAgIGFkZGl0aW9uYWwgcGFyYW1ldGVyLgogKgogKiBAYXV0aG9yIEpvc2VwaCBELiBEYXJjeQogKiBAYXV0aG9yIFNjb3R0IFNlbGlnbWFuCiAqIEBhdXRob3IgUGV0ZXIgdm9uIGRlciBBaCZlYWN1dGU7CiAqCiAqIEBzZWUgQWJzdHJhY3RUeXBlVmlzaXRvcjcKICogQHNlZSBBYnN0cmFjdFR5cGVWaXNpdG9yOAogKiBAc2VlIEFic3RyYWN0VHlwZVZpc2l0b3I5CiAqIEBzaW5jZSAxLjYKICovCkBTdXBwb3J0ZWRTb3VyY2VWZXJzaW9uKFJFTEVBU0VfNikKcHVibGljIGFic3RyYWN0IGNsYXNzIEFic3RyYWN0VHlwZVZpc2l0b3I2PFIsIFA+IGltcGxlbWVudHMgVHlwZVZpc2l0b3I8UiwgUD4gewogICAgLyoqCiAgICAgKiBDb25zdHJ1Y3RvciBmb3IgY29uY3JldGUgc3ViY2xhc3NlcyB0byBjYWxsLgogICAgICogQGRlcHJlY2F0ZWQgUmVsZWFzZSA2IGlzIG9ic29sZXRlOyB1cGRhdGUgdG8gYSB2aXNpdG9yIGZvciBhIG5ld2VyCiAgICAgKiByZWxlYXNlIGxldmVsLgogICAgICovCiAgICBARGVwcmVjYXRlZAogICAgcHJvdGVjdGVkIEFic3RyYWN0VHlwZVZpc2l0b3I2KCkge30KCiAgICAvKioKICAgICAqIFZpc2l0cyBhbnkgdHlwZSBtaXJyb3IgYXMgaWYgYnkgcGFzc2luZyBpdHNlbGYgdG8gdGhhdCB0eXBlCiAgICAgKiBtaXJyb3IncyB7QGxpbmsgVHlwZU1pcnJvciNhY2NlcHQgYWNjZXB0fSBtZXRob2QuICBUaGUKICAgICAqIGludm9jYXRpb24ge0Bjb2RlIHYudmlzaXQodCwgcCl9IGlzIGVxdWl2YWxlbnQgdG8ge0Bjb2RlCiAgICAgKiB0LmFjY2VwdCh2LCBwKX0uCiAgICAgKgogICAgICogQHBhcmFtIHQgIHRoZSB0eXBlIHRvIHZpc2l0CiAgICAgKiBAcGFyYW0gcCAgYSB2aXNpdG9yLXNwZWNpZmllZCBwYXJhbWV0ZXIKICAgICAqIEByZXR1cm4gYSB2aXNpdG9yLXNwZWNpZmllZCByZXN1bHQKICAgICAqLwogICAgcHVibGljIGZpbmFsIFIgdmlzaXQoVHlwZU1pcnJvciB0LCBQIHApIHsKICAgICAgICByZXR1cm4gdC5hY2NlcHQodGhpcywgcCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBWaXNpdHMgYW55IHR5cGUgbWlycm9yIGFzIGlmIGJ5IHBhc3NpbmcgaXRzZWxmIHRvIHRoYXQgdHlwZQogICAgICogbWlycm9yJ3Mge0BsaW5rIFR5cGVNaXJyb3IjYWNjZXB0IGFjY2VwdH0gbWV0aG9kIGFuZCBwYXNzaW5nCiAgICAgKiB7QGNvZGUgbnVsbH0gZm9yIHRoZSBhZGRpdGlvbmFsIHBhcmFtZXRlci4gIFRoZSBpbnZvY2F0aW9uCiAgICAgKiB7QGNvZGUgdi52aXNpdCh0KX0gaXMgZXF1aXZhbGVudCB0byB7QGNvZGUgdC5hY2NlcHQodiwgbnVsbCl9LgogICAgICoKICAgICAqIEBwYXJhbSB0ICB0aGUgdHlwZSB0byB2aXNpdAogICAgICogQHJldHVybiBhIHZpc2l0b3Itc3BlY2lmaWVkIHJlc3VsdAogICAgICovCiAgICBwdWJsaWMgZmluYWwgUiB2aXNpdChUeXBlTWlycm9yIHQpIHsKICAgICAgICByZXR1cm4gdC5hY2NlcHQodGhpcywgbnVsbCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKgogICAgICogQGltcGxTcGVjIFZpc2l0cyBhIHtAY29kZSBVbmlvblR5cGV9IGVsZW1lbnQgYnkgY2FsbGluZyB7QGNvZGUKICAgICAqIHZpc2l0VW5rbm93bn0uCiAgICAgKgogICAgICogQHBhcmFtIHQgIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwICB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuIHRoZSByZXN1bHQgb2Yge0Bjb2RlIHZpc2l0VW5rbm93bn0KICAgICAqCiAgICAgKiBAc2luY2UgMS43CiAgICAgKi8KICAgIHB1YmxpYyBSIHZpc2l0VW5pb24oVW5pb25UeXBlIHQsIFAgcCkgewogICAgICAgIHJldHVybiB2aXNpdFVua25vd24odCwgcCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKgogICAgICogQGltcGxTcGVjIFZpc2l0cyBhbiB7QGNvZGUgSW50ZXJzZWN0aW9uVHlwZX0gZWxlbWVudCBieSBjYWxsaW5nIHtAY29kZQogICAgICogdmlzaXRVbmtub3dufS4KICAgICAqCiAgICAgKiBAcGFyYW0gdCAge0Bpbmhlcml0RG9jfQogICAgICogQHBhcmFtIHAgIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gdGhlIHJlc3VsdCBvZiB7QGNvZGUgdmlzaXRVbmtub3dufQogICAgICoKICAgICAqIEBzaW5jZSAxLjgKICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgUiB2aXNpdEludGVyc2VjdGlvbihJbnRlcnNlY3Rpb25UeXBlIHQsIFAgcCkgewogICAgICAgIHJldHVybiB2aXNpdFVua25vd24odCwgcCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9CiAgICAgKgogICAgICogQGltcGxTcGVjIFRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIG9mIHRoaXMgbWV0aG9kIGluIHtAY29kZQogICAgICogQWJzdHJhY3RUeXBlVmlzaXRvcjZ9IHdpbGwgYWx3YXlzIHRocm93IHtAY29kZQogICAgICogbmV3IFVua25vd25UeXBlRXhjZXB0aW9uKHQsIHApfS4gIFRoaXMgYmVoYXZpb3IgaXMgbm90IHJlcXVpcmVkIG9mIGEKICAgICAqIHN1YmNsYXNzLgogICAgICoKICAgICAqIEBwYXJhbSB0ICB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiBhIHZpc2l0b3Itc3BlY2lmaWVkIHJlc3VsdAogICAgICogQHRocm93cyBVbmtub3duVHlwZUV4Y2VwdGlvbgogICAgICogIGEgdmlzaXRvciBpbXBsZW1lbnRhdGlvbiBtYXkgb3B0aW9uYWxseSB0aHJvdyB0aGlzIGV4Y2VwdGlvbgogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0VW5rbm93bihUeXBlTWlycm9yIHQsIFAgcCkgewogICAgICAgIHRocm93IG5ldyBVbmtub3duVHlwZUV4Y2VwdGlvbih0LCBwKTsKICAgIH0KfQpQSwMECgAACAAABjupSk3B+fxhDAAAYQwAADoAAABqYXZheC9sYW5nL21vZGVsL3V0aWwvQWJzdHJhY3RBbm5vdGF0aW9uVmFsdWVWaXNpdG9yNy5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDEwLCAyMDE3LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGphdmF4LmxhbmcubW9kZWwudXRpbDsKCmltcG9ydCBzdGF0aWMgamF2YXgubGFuZy5tb2RlbC5Tb3VyY2VWZXJzaW9uLio7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLlNvdXJjZVZlcnNpb247CmltcG9ydCBqYXZheC5hbm5vdGF0aW9uLnByb2Nlc3NpbmcuU3VwcG9ydGVkU291cmNlVmVyc2lvbjsKCi8qKgogKiBBIHNrZWxldGFsIHZpc2l0b3IgZm9yIGFubm90YXRpb24gdmFsdWVzIHdpdGggZGVmYXVsdCBiZWhhdmlvcgogKiBhcHByb3ByaWF0ZSBmb3IgdGhlIHtAbGluayBTb3VyY2VWZXJzaW9uI1JFTEVBU0VfNyBSRUxFQVNFXzd9CiAqIHNvdXJjZSB2ZXJzaW9uLgogKgogKiA8cD4gPGI+V0FSTklORzo8L2I+IFRoZSB7QGNvZGUgQW5ub3RhdGlvblZhbHVlVmlzaXRvcn0gaW50ZXJmYWNlCiAqIGltcGxlbWVudGVkIGJ5IHRoaXMgY2xhc3MgbWF5IGhhdmUgbWV0aG9kcyBhZGRlZCB0byBpdCBpbiB0aGUKICogZnV0dXJlIHRvIGFjY29tbW9kYXRlIG5ldywgY3VycmVudGx5IHVua25vd24sIGxhbmd1YWdlIHN0cnVjdHVyZXMKICogYWRkZWQgdG8gZnV0dXJlIHZlcnNpb25zIG9mIHRoZSBKYXZhJnRyYWRlOyBwcm9ncmFtbWluZyBsYW5ndWFnZS4KICogVGhlcmVmb3JlLCBtZXRob2RzIHdob3NlIG5hbWVzIGJlZ2luIHdpdGgge0Bjb2RlICJ2aXNpdCJ9IG1heSBiZQogKiBhZGRlZCB0byB0aGlzIGNsYXNzIGluIHRoZSBmdXR1cmU7IHRvIGF2b2lkIGluY29tcGF0aWJpbGl0aWVzLAogKiBjbGFzc2VzIHdoaWNoIGV4dGVuZCB0aGlzIGNsYXNzIHNob3VsZCBub3QgZGVjbGFyZSBhbnkgaW5zdGFuY2UKICogbWV0aG9kcyB3aXRoIG5hbWVzIGJlZ2lubmluZyB3aXRoIHtAY29kZSAidmlzaXQifS4KICoKICogPHA+V2hlbiBzdWNoIGEgbmV3IHZpc2l0IG1ldGhvZCBpcyBhZGRlZCwgdGhlIGRlZmF1bHQKICogaW1wbGVtZW50YXRpb24gaW4gdGhpcyBjbGFzcyB3aWxsIGJlIHRvIGNhbGwgdGhlIHtAbGluawogKiAjdmlzaXRVbmtub3duIHZpc2l0VW5rbm93bn0gbWV0aG9kLiAgQSBuZXcgYWJzdHJhY3QgYW5ub3RhdGlvbgogKiB2YWx1ZSB2aXNpdG9yIGNsYXNzIHdpbGwgYWxzbyBiZSBpbnRyb2R1Y2VkIHRvIGNvcnJlc3BvbmQgdG8gdGhlCiAqIG5ldyBsYW5ndWFnZSBsZXZlbDsgdGhpcyB2aXNpdG9yIHdpbGwgaGF2ZSBkaWZmZXJlbnQgZGVmYXVsdAogKiBiZWhhdmlvciBmb3IgdGhlIHZpc2l0IG1ldGhvZCBpbiBxdWVzdGlvbi4gIFdoZW4gdGhlIG5ldyB2aXNpdG9yIGlzCiAqIGludHJvZHVjZWQsIGFsbCBvciBwb3J0aW9ucyBvZiB0aGlzIHZpc2l0b3IgbWF5IGJlIGRlcHJlY2F0ZWQuCiAqCiAqIEBwYXJhbSA8Uj4gdGhlIHJldHVybiB0eXBlIG9mIHRoaXMgdmlzaXRvcidzIG1ldGhvZHMKICogQHBhcmFtIDxQPiB0aGUgdHlwZSBvZiB0aGUgYWRkaXRpb25hbCBwYXJhbWV0ZXIgdG8gdGhpcyB2aXNpdG9yJ3MgbWV0aG9kcy4KICoKICogQHNlZSBBYnN0cmFjdEFubm90YXRpb25WYWx1ZVZpc2l0b3I2CiAqIEBzZWUgQWJzdHJhY3RBbm5vdGF0aW9uVmFsdWVWaXNpdG9yOAogKiBAc2VlIEFic3RyYWN0QW5ub3RhdGlvblZhbHVlVmlzaXRvcjkKICogQHNpbmNlIDEuNwogKi8KQFN1cHBvcnRlZFNvdXJjZVZlcnNpb24oUkVMRUFTRV83KQpwdWJsaWMgYWJzdHJhY3QgY2xhc3MgQWJzdHJhY3RBbm5vdGF0aW9uVmFsdWVWaXNpdG9yNzxSLCBQPiBleHRlbmRzIEFic3RyYWN0QW5ub3RhdGlvblZhbHVlVmlzaXRvcjY8UiwgUD4gewoKICAgIC8qKgogICAgICogQ29uc3RydWN0b3IgZm9yIGNvbmNyZXRlIHN1YmNsYXNzZXMgdG8gY2FsbC4KICAgICAqLwogICAgQFN1cHByZXNzV2FybmluZ3MoImRlcHJlY2F0aW9uIikgLy8gU3VwZXJjbGFzcyBjb25zdHJ1Y3RvciBkZXByZWNhdGVkCiAgICBwcm90ZWN0ZWQgQWJzdHJhY3RBbm5vdGF0aW9uVmFsdWVWaXNpdG9yNygpIHsKICAgICAgICBzdXBlcigpOwogICAgfQp9ClBLAwQKAAAIAABmh4VKpHukkWsPAABrDwAALQAAAGphdmF4L2xhbmcvbW9kZWwvdXRpbC9TaW1wbGVUeXBlVmlzaXRvcjkuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAxMSwgMjAxNCwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBqYXZheC5sYW5nLm1vZGVsLnV0aWw7CgppbXBvcnQgamF2YXguYW5ub3RhdGlvbi5wcm9jZXNzaW5nLlN1cHBvcnRlZFNvdXJjZVZlcnNpb247CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLlNvdXJjZVZlcnNpb247CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLnR5cGUuSW50ZXJzZWN0aW9uVHlwZTsKaW1wb3J0IHN0YXRpYyBqYXZheC5sYW5nLm1vZGVsLlNvdXJjZVZlcnNpb24uKjsKCi8qKgogKiBBIHNpbXBsZSB2aXNpdG9yIG9mIHR5cGVzIHdpdGggZGVmYXVsdCBiZWhhdmlvciBhcHByb3ByaWF0ZSBmb3IgdGhlCiAqIHtAbGluayBTb3VyY2VWZXJzaW9uI1JFTEVBU0VfOSBSRUxFQVNFXzl9IHNvdXJjZSB2ZXJzaW9uLgogKgogKiBWaXNpdCBtZXRob2RzIGNvcnJlc3BvbmRpbmcgdG8ge0Bjb2RlIFJFTEVBU0VfOX0gYW5kIGVhcmxpZXIKICogbGFuZ3VhZ2UgY29uc3RydWN0cyBjYWxsIHtAbGluayAjZGVmYXVsdEFjdGlvbiBkZWZhdWx0QWN0aW9ufSwKICogcGFzc2luZyB0aGVpciBhcmd1bWVudHMgdG8ge0Bjb2RlIGRlZmF1bHRBY3Rpb259J3MgY29ycmVzcG9uZGluZwogKiBwYXJhbWV0ZXJzLgogKgogKiA8cD4gTWV0aG9kcyBpbiB0aGlzIGNsYXNzIG1heSBiZSBvdmVycmlkZGVuIHN1YmplY3QgdG8gdGhlaXIKICogZ2VuZXJhbCBjb250cmFjdC4gIE5vdGUgdGhhdCBhbm5vdGF0aW5nIG1ldGhvZHMgaW4gY29uY3JldGUKICogc3ViY2xhc3NlcyB3aXRoIHtAbGluayBqYXZhLmxhbmcuT3ZlcnJpZGUgQE92ZXJyaWRlfSB3aWxsIGhlbHAKICogZW5zdXJlIHRoYXQgbWV0aG9kcyBhcmUgb3ZlcnJpZGRlbiBhcyBpbnRlbmRlZC4KICoKICogPHA+IDxiPldBUk5JTkc6PC9iPiBUaGUge0Bjb2RlIFR5cGVWaXNpdG9yfSBpbnRlcmZhY2UgaW1wbGVtZW50ZWQKICogYnkgdGhpcyBjbGFzcyBtYXkgaGF2ZSBtZXRob2RzIGFkZGVkIHRvIGl0IGluIHRoZSBmdXR1cmUgdG8KICogYWNjb21tb2RhdGUgbmV3LCBjdXJyZW50bHkgdW5rbm93biwgbGFuZ3VhZ2Ugc3RydWN0dXJlcyBhZGRlZCB0bwogKiBmdXR1cmUgdmVyc2lvbnMgb2YgdGhlIEphdmEmdHJhZGU7IHByb2dyYW1taW5nIGxhbmd1YWdlLgogKiBUaGVyZWZvcmUsIG1ldGhvZHMgd2hvc2UgbmFtZXMgYmVnaW4gd2l0aCB7QGNvZGUgInZpc2l0In0gbWF5IGJlCiAqIGFkZGVkIHRvIHRoaXMgY2xhc3MgaW4gdGhlIGZ1dHVyZTsgdG8gYXZvaWQgaW5jb21wYXRpYmlsaXRpZXMsCiAqIGNsYXNzZXMgd2hpY2ggZXh0ZW5kIHRoaXMgY2xhc3Mgc2hvdWxkIG5vdCBkZWNsYXJlIGFueSBpbnN0YW5jZQogKiBtZXRob2RzIHdpdGggbmFtZXMgYmVnaW5uaW5nIHdpdGgge0Bjb2RlICJ2aXNpdCJ9LgogKgogKiA8cD5XaGVuIHN1Y2ggYSBuZXcgdmlzaXQgbWV0aG9kIGlzIGFkZGVkLCB0aGUgZGVmYXVsdAogKiBpbXBsZW1lbnRhdGlvbiBpbiB0aGlzIGNsYXNzIHdpbGwgYmUgdG8gY2FsbCB0aGUge0BsaW5rCiAqICN2aXNpdFVua25vd24gdmlzaXRVbmtub3dufSBtZXRob2QuICBBIG5ldyBzaW1wbGUgdHlwZSB2aXNpdG9yCiAqIGNsYXNzIHdpbGwgYWxzbyBiZSBpbnRyb2R1Y2VkIHRvIGNvcnJlc3BvbmQgdG8gdGhlIG5ldyBsYW5ndWFnZQogKiBsZXZlbDsgdGhpcyB2aXNpdG9yIHdpbGwgaGF2ZSBkaWZmZXJlbnQgZGVmYXVsdCBiZWhhdmlvciBmb3IgdGhlCiAqIHZpc2l0IG1ldGhvZCBpbiBxdWVzdGlvbi4gIFdoZW4gdGhlIG5ldyB2aXNpdG9yIGlzIGludHJvZHVjZWQsIGFsbAogKiBvciBwb3J0aW9ucyBvZiB0aGlzIHZpc2l0b3IgbWF5IGJlIGRlcHJlY2F0ZWQuCiAqCiAqIEBwYXJhbSA8Uj4gdGhlIHJldHVybiB0eXBlIG9mIHRoaXMgdmlzaXRvcidzIG1ldGhvZHMuICBVc2Uge0BsaW5rCiAqICAgICAgICAgICAgVm9pZH0gZm9yIHZpc2l0b3JzIHRoYXQgZG8gbm90IG5lZWQgdG8gcmV0dXJuIHJlc3VsdHMuCiAqIEBwYXJhbSA8UD4gdGhlIHR5cGUgb2YgdGhlIGFkZGl0aW9uYWwgcGFyYW1ldGVyIHRvIHRoaXMgdmlzaXRvcidzCiAqICAgICAgICAgICAgbWV0aG9kcy4gIFVzZSB7QGNvZGUgVm9pZH0gZm9yIHZpc2l0b3JzIHRoYXQgZG8gbm90IG5lZWQgYW4KICogICAgICAgICAgICBhZGRpdGlvbmFsIHBhcmFtZXRlci4KICoKICogQHNlZSBTaW1wbGVUeXBlVmlzaXRvcjYKICogQHNlZSBTaW1wbGVUeXBlVmlzaXRvcjcKICogQHNpbmNlIDEuOAogKi8KQFN1cHBvcnRlZFNvdXJjZVZlcnNpb24oUkVMRUFTRV85KQpwdWJsaWMgY2xhc3MgU2ltcGxlVHlwZVZpc2l0b3I5PFIsIFA+IGV4dGVuZHMgU2ltcGxlVHlwZVZpc2l0b3I4PFIsIFA+IHsKICAgIC8qKgogICAgICogQ29uc3RydWN0b3IgZm9yIGNvbmNyZXRlIHN1YmNsYXNzZXM7IHVzZXMge0Bjb2RlIG51bGx9IGZvciB0aGUKICAgICAqIGRlZmF1bHQgdmFsdWUuCiAgICAgKi8KICAgIHByb3RlY3RlZCBTaW1wbGVUeXBlVmlzaXRvcjkoKXsKICAgICAgICBzdXBlcihudWxsKTsKICAgIH0KCiAgICAvKioKICAgICAqIENvbnN0cnVjdG9yIGZvciBjb25jcmV0ZSBzdWJjbGFzc2VzOyB1c2VzIHRoZSBhcmd1bWVudCBmb3IgdGhlCiAgICAgKiBkZWZhdWx0IHZhbHVlLgogICAgICoKICAgICAqIEBwYXJhbSBkZWZhdWx0VmFsdWUgdGhlIHZhbHVlIHRvIGFzc2lnbiB0byB7QGxpbmsgI0RFRkFVTFRfVkFMVUV9CiAgICAgKi8KICAgIHByb3RlY3RlZCBTaW1wbGVUeXBlVmlzaXRvcjkoUiBkZWZhdWx0VmFsdWUpewogICAgICAgIHN1cGVyKGRlZmF1bHRWYWx1ZSk7CiAgICB9Cn0KUEsDBAoAAAgAAAY7qUqq28xZhxAAAIcQAAArAAAAamF2YXgvbGFuZy9tb2RlbC91dGlsL1R5cGVLaW5kVmlzaXRvcjkuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAxMSwgMjAxNywgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBqYXZheC5sYW5nLm1vZGVsLnV0aWw7CgppbXBvcnQgamF2YXguYW5ub3RhdGlvbi5wcm9jZXNzaW5nLlN1cHBvcnRlZFNvdXJjZVZlcnNpb247CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLlNvdXJjZVZlcnNpb247CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLnR5cGUuKjsKaW1wb3J0IHN0YXRpYyBqYXZheC5sYW5nLm1vZGVsLlNvdXJjZVZlcnNpb24uKjsKCi8qKgogKiBBIHZpc2l0b3Igb2YgdHlwZXMgYmFzZWQgb24gdGhlaXIge0BsaW5rcGxhaW4gVHlwZUtpbmQga2luZH0gd2l0aAogKiBkZWZhdWx0IGJlaGF2aW9yIGFwcHJvcHJpYXRlIGZvciB0aGUge0BsaW5rIFNvdXJjZVZlcnNpb24jUkVMRUFTRV85CiAqIFJFTEVBU0VfOX0gc291cmNlIHZlcnNpb24uICBGb3Ige0BsaW5rcGxhaW4KICogVHlwZU1pcnJvciB0eXBlc30gPGNvZGU+PGk+WHl6PC9pPjwvY29kZT4gdGhhdCBtYXkgaGF2ZSBtb3JlIHRoYW4gb25lCiAqIGtpbmQsIHRoZSA8Y29kZT52aXNpdDxpPlh5ejwvaT48L2NvZGU+IG1ldGhvZHMgaW4gdGhpcyBjbGFzcyBkZWxlZ2F0ZQogKiB0byB0aGUgPGNvZGU+dmlzaXQ8aT5YeXo8L2k+QXM8aT5LaW5kPC9pPjwvY29kZT4gbWV0aG9kIGNvcnJlc3BvbmRpbmcgdG8gdGhlCiAqIGZpcnN0IGFyZ3VtZW50J3Mga2luZC4gIFRoZSA8Y29kZT52aXNpdDxpPlh5ejwvaT5BczxpPktpbmQ8L2k+PC9jb2RlPiBtZXRob2RzCiAqIGNhbGwge0BsaW5rICNkZWZhdWx0QWN0aW9uIGRlZmF1bHRBY3Rpb259LCBwYXNzaW5nIHRoZWlyIGFyZ3VtZW50cwogKiB0byB7QGNvZGUgZGVmYXVsdEFjdGlvbn0ncyBjb3JyZXNwb25kaW5nIHBhcmFtZXRlcnMuCiAqCiAqIDxwPiBNZXRob2RzIGluIHRoaXMgY2xhc3MgbWF5IGJlIG92ZXJyaWRkZW4gc3ViamVjdCB0byB0aGVpcgogKiBnZW5lcmFsIGNvbnRyYWN0LiAgTm90ZSB0aGF0IGFubm90YXRpbmcgbWV0aG9kcyBpbiBjb25jcmV0ZQogKiBzdWJjbGFzc2VzIHdpdGgge0BsaW5rIGphdmEubGFuZy5PdmVycmlkZSBAT3ZlcnJpZGV9IHdpbGwgaGVscAogKiBlbnN1cmUgdGhhdCBtZXRob2RzIGFyZSBvdmVycmlkZGVuIGFzIGludGVuZGVkLgogKgogKiA8cD4gPGI+V0FSTklORzo8L2I+IFRoZSB7QGNvZGUgVHlwZVZpc2l0b3J9IGludGVyZmFjZSBpbXBsZW1lbnRlZAogKiBieSB0aGlzIGNsYXNzIG1heSBoYXZlIG1ldGhvZHMgYWRkZWQgdG8gaXQgaW4gdGhlIGZ1dHVyZSB0bwogKiBhY2NvbW1vZGF0ZSBuZXcsIGN1cnJlbnRseSB1bmtub3duLCBsYW5ndWFnZSBzdHJ1Y3R1cmVzIGFkZGVkIHRvCiAqIGZ1dHVyZSB2ZXJzaW9ucyBvZiB0aGUgSmF2YSZ0cmFkZTsgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2UuCiAqIFRoZXJlZm9yZSwgbWV0aG9kcyB3aG9zZSBuYW1lcyBiZWdpbiB3aXRoIHtAY29kZSAidmlzaXQifSBtYXkgYmUKICogYWRkZWQgdG8gdGhpcyBjbGFzcyBpbiB0aGUgZnV0dXJlOyB0byBhdm9pZCBpbmNvbXBhdGliaWxpdGllcywKICogY2xhc3NlcyB3aGljaCBleHRlbmQgdGhpcyBjbGFzcyBzaG91bGQgbm90IGRlY2xhcmUgYW55IGluc3RhbmNlCiAqIG1ldGhvZHMgd2l0aCBuYW1lcyBiZWdpbm5pbmcgd2l0aCB7QGNvZGUgInZpc2l0In0uCiAqCiAqIDxwPldoZW4gc3VjaCBhIG5ldyB2aXNpdCBtZXRob2QgaXMgYWRkZWQsIHRoZSBkZWZhdWx0CiAqIGltcGxlbWVudGF0aW9uIGluIHRoaXMgY2xhc3Mgd2lsbCBiZSB0byBjYWxsIHRoZSB7QGxpbmsKICogI3Zpc2l0VW5rbm93biB2aXNpdFVua25vd259IG1ldGhvZC4gIEEgbmV3IHR5cGUga2luZCB2aXNpdG9yIGNsYXNzCiAqIHdpbGwgYWxzbyBiZSBpbnRyb2R1Y2VkIHRvIGNvcnJlc3BvbmQgdG8gdGhlIG5ldyBsYW5ndWFnZSBsZXZlbDsKICogdGhpcyB2aXNpdG9yIHdpbGwgaGF2ZSBkaWZmZXJlbnQgZGVmYXVsdCBiZWhhdmlvciBmb3IgdGhlIHZpc2l0CiAqIG1ldGhvZCBpbiBxdWVzdGlvbi4gIFdoZW4gdGhlIG5ldyB2aXNpdG9yIGlzIGludHJvZHVjZWQsIGFsbCBvcgogKiBwb3J0aW9ucyBvZiB0aGlzIHZpc2l0b3IgbWF5IGJlIGRlcHJlY2F0ZWQuCiAqCiAqIEBwYXJhbSA8Uj4gdGhlIHJldHVybiB0eXBlIG9mIHRoaXMgdmlzaXRvcidzIG1ldGhvZHMuICBVc2Uge0BsaW5rCiAqICAgICAgICAgICAgVm9pZH0gZm9yIHZpc2l0b3JzIHRoYXQgZG8gbm90IG5lZWQgdG8gcmV0dXJuIHJlc3VsdHMuCiAqIEBwYXJhbSA8UD4gdGhlIHR5cGUgb2YgdGhlIGFkZGl0aW9uYWwgcGFyYW1ldGVyIHRvIHRoaXMgdmlzaXRvcidzCiAqICAgICAgICAgICAgbWV0aG9kcy4gIFVzZSB7QGNvZGUgVm9pZH0gZm9yIHZpc2l0b3JzIHRoYXQgZG8gbm90IG5lZWQgYW4KICogICAgICAgICAgICBhZGRpdGlvbmFsIHBhcmFtZXRlci4KICoKICogQHNlZSBUeXBlS2luZFZpc2l0b3I2CiAqIEBzZWUgVHlwZUtpbmRWaXNpdG9yNwogKiBAc2VlIFR5cGVLaW5kVmlzaXRvcjgKICogQHNpbmNlIDkKICovCkBTdXBwb3J0ZWRTb3VyY2VWZXJzaW9uKFJFTEVBU0VfOSkKcHVibGljIGNsYXNzIFR5cGVLaW5kVmlzaXRvcjk8UiwgUD4gZXh0ZW5kcyBUeXBlS2luZFZpc2l0b3I4PFIsIFA+IHsKICAgIC8qKgogICAgICogQ29uc3RydWN0b3IgZm9yIGNvbmNyZXRlIHN1YmNsYXNzZXMgdG8gY2FsbDsgdXNlcyB7QGNvZGUgbnVsbH0KICAgICAqIGZvciB0aGUgZGVmYXVsdCB2YWx1ZS4KICAgICAqLwogICAgcHJvdGVjdGVkIFR5cGVLaW5kVmlzaXRvcjkoKSB7CiAgICAgICAgc3VwZXIobnVsbCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDb25zdHJ1Y3RvciBmb3IgY29uY3JldGUgc3ViY2xhc3NlcyB0byBjYWxsOyB1c2VzIHRoZSBhcmd1bWVudAogICAgICogZm9yIHRoZSBkZWZhdWx0IHZhbHVlLgogICAgICoKICAgICAqIEBwYXJhbSBkZWZhdWx0VmFsdWUgdGhlIHZhbHVlIHRvIGFzc2lnbiB0byB7QGxpbmsgI0RFRkFVTFRfVkFMVUV9CiAgICAgKi8KICAgIHByb3RlY3RlZCBUeXBlS2luZFZpc2l0b3I5KFIgZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgc3VwZXIoZGVmYXVsdFZhbHVlKTsKICAgIH0KfQpQSwMECgAACAAABjupStLVpKgrMgAAKzIAACAAAABqYXZheC9sYW5nL21vZGVsL3V0aWwvVHlwZXMuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAxNywgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBqYXZheC5sYW5nLm1vZGVsLnV0aWw7CgppbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uQW5ub3RhdGlvbjsKaW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLkFubm90YXRpb25UeXBlTWlzbWF0Y2hFeGNlcHRpb247CmltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5JbmNvbXBsZXRlQW5ub3RhdGlvbkV4Y2VwdGlvbjsKaW1wb3J0IGphdmEudXRpbC5MaXN0OwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5lbGVtZW50Lio7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLnR5cGUuKjsKCi8qKgogKiBVdGlsaXR5IG1ldGhvZHMgZm9yIG9wZXJhdGluZyBvbiB0eXBlcy4KICoKICogPHA+PGI+Q29tcGF0aWJpbGl0eSBOb3RlOjwvYj4gTWV0aG9kcyBtYXkgYmUgYWRkZWQgdG8gdGhpcyBpbnRlcmZhY2UKICogaW4gZnV0dXJlIHJlbGVhc2VzIG9mIHRoZSBwbGF0Zm9ybS4KICoKICogQGF1dGhvciBKb3NlcGggRC4gRGFyY3kKICogQGF1dGhvciBTY290dCBTZWxpZ21hbgogKiBAYXV0aG9yIFBldGVyIHZvbiBkZXIgQWgmZWFjdXRlOwogKiBAc2VlIGphdmF4LmFubm90YXRpb24ucHJvY2Vzc2luZy5Qcm9jZXNzaW5nRW52aXJvbm1lbnQjZ2V0VHlwZVV0aWxzCiAqIEBzaW5jZSAxLjYKICovCnB1YmxpYyBpbnRlcmZhY2UgVHlwZXMgewoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgZWxlbWVudCBjb3JyZXNwb25kaW5nIHRvIGEgdHlwZS4KICAgICAqIFRoZSB0eXBlIG1heSBiZSBhIHtAY29kZSBEZWNsYXJlZFR5cGV9IG9yIHtAY29kZSBUeXBlVmFyaWFibGV9LgogICAgICogUmV0dXJucyB7QGNvZGUgbnVsbH0gaWYgdGhlIHR5cGUgaXMgbm90IG9uZSB3aXRoIGEKICAgICAqIGNvcnJlc3BvbmRpbmcgZWxlbWVudC4KICAgICAqCiAgICAgKiBAcGFyYW0gdCB0aGUgdHlwZSB0byBtYXAgdG8gYW4gZWxlbWVudAogICAgICogQHJldHVybiB0aGUgZWxlbWVudCBjb3JyZXNwb25kaW5nIHRvIHRoZSBnaXZlbiB0eXBlCiAgICAgKi8KICAgIEVsZW1lbnQgYXNFbGVtZW50KFR5cGVNaXJyb3IgdCk7CgogICAgLyoqCiAgICAgKiBUZXN0cyB3aGV0aGVyIHR3byB7QGNvZGUgVHlwZU1pcnJvcn0gb2JqZWN0cyByZXByZXNlbnQgdGhlIHNhbWUgdHlwZS4KICAgICAqCiAgICAgKiA8cD5DYXZlYXQ6IGlmIGVpdGhlciBvZiB0aGUgYXJndW1lbnRzIHRvIHRoaXMgbWV0aG9kIHJlcHJlc2VudHMgYQogICAgICogd2lsZGNhcmQsIHRoaXMgbWV0aG9kIHdpbGwgcmV0dXJuIGZhbHNlLiAgQXMgYSBjb25zZXF1ZW5jZSwgYSB3aWxkY2FyZAogICAgICogaXMgbm90IHRoZSBzYW1lIHR5cGUgYXMgaXRzZWxmLiAgVGhpcyBtaWdodCBiZSBzdXJwcmlzaW5nIGF0IGZpcnN0LAogICAgICogYnV0IG1ha2VzIHNlbnNlIG9uY2UgeW91IGNvbnNpZGVyIHRoYXQgYW4gZXhhbXBsZSBsaWtlIHRoaXMgbXVzdCBiZQogICAgICogcmVqZWN0ZWQgYnkgdGhlIGNvbXBpbGVyOgogICAgICogPHByZT4KICAgICAqICAge0Bjb2RlIExpc3Q8Pz4gbGlzdCA9IG5ldyBBcnJheUxpc3Q8T2JqZWN0PigpO30KICAgICAqICAge0Bjb2RlIGxpc3QuYWRkKGxpc3QuZ2V0KDApKTt9CiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8cD5TaW5jZSBhbm5vdGF0aW9ucyBhcmUgb25seSBtZXRhLWRhdGEgYXNzb2NpYXRlZCB3aXRoIGEgdHlwZSwKICAgICAqIHRoZSBzZXQgb2YgYW5ub3RhdGlvbnMgb24gZWl0aGVyIGFyZ3VtZW50IGlzIDxlbT5ub3Q8L2VtPiB0YWtlbgogICAgICogaW50byBhY2NvdW50IHdoZW4gY29tcHV0aW5nIHdoZXRoZXIgb3Igbm90IHR3byB7QGNvZGUKICAgICAqIFR5cGVNaXJyb3J9IG9iamVjdHMgYXJlIHRoZSBzYW1lIHR5cGUuIEluIHBhcnRpY3VsYXIsIHR3bwogICAgICoge0Bjb2RlIFR5cGVNaXJyb3J9IG9iamVjdHMgY2FuIGhhdmUgZGlmZmVyZW50IGFubm90YXRpb25zIGFuZAogICAgICogc3RpbGwgYmUgY29uc2lkZXJlZCB0aGUgc2FtZS4KICAgICAqCiAgICAgKiBAcGFyYW0gdDEgIHRoZSBmaXJzdCB0eXBlCiAgICAgKiBAcGFyYW0gdDIgIHRoZSBzZWNvbmQgdHlwZQogICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgYW5kIG9ubHkgaWYgdGhlIHR3byB0eXBlcyBhcmUgdGhlIHNhbWUKICAgICAqLwogICAgYm9vbGVhbiBpc1NhbWVUeXBlKFR5cGVNaXJyb3IgdDEsIFR5cGVNaXJyb3IgdDIpOwoKICAgIC8qKgogICAgICogVGVzdHMgd2hldGhlciBvbmUgdHlwZSBpcyBhIHN1YnR5cGUgb2YgYW5vdGhlci4KICAgICAqIEFueSB0eXBlIGlzIGNvbnNpZGVyZWQgdG8gYmUgYSBzdWJ0eXBlIG9mIGl0c2VsZi4KICAgICAqCiAgICAgKiBAcGFyYW0gdDEgIHRoZSBmaXJzdCB0eXBlCiAgICAgKiBAcGFyYW0gdDIgIHRoZSBzZWNvbmQgdHlwZQogICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgYW5kIG9ubHkgaWYgdGhlIGZpcnN0IHR5cGUgaXMgYSBzdWJ0eXBlCiAgICAgKiAgICAgICAgICBvZiB0aGUgc2Vjb25kCiAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiBnaXZlbiBhIHR5cGUgZm9yIGFuIGV4ZWN1dGFibGUsIHBhY2thZ2UsIG9yIG1vZHVsZQogICAgICogQGpscyA0LjEwIFN1YnR5cGluZwogICAgICovCiAgICBib29sZWFuIGlzU3VidHlwZShUeXBlTWlycm9yIHQxLCBUeXBlTWlycm9yIHQyKTsKCiAgICAvKioKICAgICAqIFRlc3RzIHdoZXRoZXIgb25lIHR5cGUgaXMgYXNzaWduYWJsZSB0byBhbm90aGVyLgogICAgICoKICAgICAqIEBwYXJhbSB0MSAgdGhlIGZpcnN0IHR5cGUKICAgICAqIEBwYXJhbSB0MiAgdGhlIHNlY29uZCB0eXBlCiAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiBhbmQgb25seSBpZiB0aGUgZmlyc3QgdHlwZSBpcyBhc3NpZ25hYmxlCiAgICAgKiAgICAgICAgICB0byB0aGUgc2Vjb25kCiAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiBnaXZlbiBhIHR5cGUgZm9yIGFuIGV4ZWN1dGFibGUsIHBhY2thZ2UsIG9yIG1vZHVsZQogICAgICogQGpscyA1LjIgQXNzaWdubWVudCBDb252ZXJzaW9uCiAgICAgKi8KICAgIGJvb2xlYW4gaXNBc3NpZ25hYmxlKFR5cGVNaXJyb3IgdDEsIFR5cGVNaXJyb3IgdDIpOwoKICAgIC8qKgogICAgICogVGVzdHMgd2hldGhlciBvbmUgdHlwZSBhcmd1bWVudCA8aT5jb250YWluczwvaT4gYW5vdGhlci4KICAgICAqCiAgICAgKiBAcGFyYW0gdDEgIHRoZSBmaXJzdCB0eXBlCiAgICAgKiBAcGFyYW0gdDIgIHRoZSBzZWNvbmQgdHlwZQogICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgYW5kIG9ubHkgaWYgdGhlIGZpcnN0IHR5cGUgY29udGFpbnMgdGhlIHNlY29uZAogICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgZ2l2ZW4gYSB0eXBlIGZvciBhbiBleGVjdXRhYmxlLCBwYWNrYWdlLCBvciBtb2R1bGUKICAgICAqIEBqbHMgNC41LjEuMSBUeXBlIEFyZ3VtZW50IENvbnRhaW5tZW50IGFuZCBFcXVpdmFsZW5jZQogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zKFR5cGVNaXJyb3IgdDEsIFR5cGVNaXJyb3IgdDIpOwoKICAgIC8qKgogICAgICogVGVzdHMgd2hldGhlciB0aGUgc2lnbmF0dXJlIG9mIG9uZSBtZXRob2QgaXMgYSA8aT5zdWJzaWduYXR1cmU8L2k+CiAgICAgKiBvZiBhbm90aGVyLgogICAgICoKICAgICAqIEBwYXJhbSBtMSAgdGhlIGZpcnN0IG1ldGhvZAogICAgICogQHBhcmFtIG0yICB0aGUgc2Vjb25kIG1ldGhvZAogICAgICogQHJldHVybiB7QGNvZGUgdHJ1ZX0gaWYgYW5kIG9ubHkgaWYgdGhlIGZpcnN0IHNpZ25hdHVyZSBpcyBhCiAgICAgKiAgICAgICAgICBzdWJzaWduYXR1cmUgb2YgdGhlIHNlY29uZAogICAgICogQGpscyA4LjQuMiBNZXRob2QgU2lnbmF0dXJlCiAgICAgKi8KICAgIGJvb2xlYW4gaXNTdWJzaWduYXR1cmUoRXhlY3V0YWJsZVR5cGUgbTEsIEV4ZWN1dGFibGVUeXBlIG0yKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGRpcmVjdCBzdXBlcnR5cGVzIG9mIGEgdHlwZS4gVGhlIGludGVyZmFjZSB0eXBlcywgaWYgYW55LAogICAgICogd2lsbCBhcHBlYXIgbGFzdCBpbiB0aGUgbGlzdC4gRm9yIGFuIGludGVyZmFjZSB0eXBlIHdpdGggbm8gZGlyZWN0CiAgICAgKiBzdXBlci1pbnRlcmZhY2VzLCBhIHR5cGUgbWlycm9yIHJlcHJlc2VudGluZyB7QGNvZGUgamF2YS5sYW5nLk9iamVjdH0KICAgICAqIGlzIHJldHVybmVkLgogICAgICoKICAgICAqIEBwYXJhbSB0ICB0aGUgdHlwZSBiZWluZyBleGFtaW5lZAogICAgICogQHJldHVybiB0aGUgZGlyZWN0IHN1cGVydHlwZXMsIG9yIGFuIGVtcHR5IGxpc3QgaWYgbm9uZQogICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgZ2l2ZW4gYSB0eXBlIGZvciBhbiBleGVjdXRhYmxlLCBwYWNrYWdlLCBvciBtb2R1bGUKICAgICAqIEBqbHMgNC4xMCBTdWJ0eXBpbmcKICAgICAqLwogICAgTGlzdDw/IGV4dGVuZHMgVHlwZU1pcnJvcj4gZGlyZWN0U3VwZXJ0eXBlcyhUeXBlTWlycm9yIHQpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgZXJhc3VyZSBvZiBhIHR5cGUuCiAgICAgKgogICAgICogQHBhcmFtIHQgIHRoZSB0eXBlIHRvIGJlIGVyYXNlZAogICAgICogQHJldHVybiB0aGUgZXJhc3VyZSBvZiB0aGUgZ2l2ZW4gdHlwZQogICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgZ2l2ZW4gYSB0eXBlIGZvciBhIHBhY2thZ2Ugb3IgbW9kdWxlCiAgICAgKiBAamxzIDQuNiBUeXBlIEVyYXN1cmUKICAgICAqLwogICAgVHlwZU1pcnJvciBlcmFzdXJlKFR5cGVNaXJyb3IgdCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBjbGFzcyBvZiBhIGJveGVkIHZhbHVlIG9mIGEgZ2l2ZW4gcHJpbWl0aXZlIHR5cGUuCiAgICAgKiBUaGF0IGlzLCA8aT5ib3hpbmcgY29udmVyc2lvbjwvaT4gaXMgYXBwbGllZC4KICAgICAqCiAgICAgKiBAcGFyYW0gcCAgdGhlIHByaW1pdGl2ZSB0eXBlIHRvIGJlIGNvbnZlcnRlZAogICAgICogQHJldHVybiB0aGUgY2xhc3Mgb2YgYSBib3hlZCB2YWx1ZSBvZiB0eXBlIHtAY29kZSBwfQogICAgICogQGpscyA1LjEuNyBCb3hpbmcgQ29udmVyc2lvbgogICAgICovCiAgICBUeXBlRWxlbWVudCBib3hlZENsYXNzKFByaW1pdGl2ZVR5cGUgcCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSB0eXBlIChhIHByaW1pdGl2ZSB0eXBlKSBvZiB1bmJveGVkIHZhbHVlcyBvZiBhIGdpdmVuIHR5cGUuCiAgICAgKiBUaGF0IGlzLCA8aT51bmJveGluZyBjb252ZXJzaW9uPC9pPiBpcyBhcHBsaWVkLgogICAgICoKICAgICAqIEBwYXJhbSB0ICB0aGUgdHlwZSB0byBiZSB1bmJveGVkCiAgICAgKiBAcmV0dXJuIHRoZSB0eXBlIG9mIGFuIHVuYm94ZWQgdmFsdWUgb2YgdHlwZSB7QGNvZGUgdH0KICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHRoZSBnaXZlbiB0eXBlIGhhcyBubwogICAgICogICAgICAgICAgdW5ib3hpbmcgY29udmVyc2lvbgogICAgICogQGpscyA1LjEuOCBVbmJveGluZyBDb252ZXJzaW9uCiAgICAgKi8KICAgIFByaW1pdGl2ZVR5cGUgdW5ib3hlZFR5cGUoVHlwZU1pcnJvciB0KTsKCiAgICAvKioKICAgICAqIEFwcGxpZXMgY2FwdHVyZSBjb252ZXJzaW9uIHRvIGEgdHlwZS4KICAgICAqCiAgICAgKiBAcGFyYW0gdCAgdGhlIHR5cGUgdG8gYmUgY29udmVydGVkCiAgICAgKiBAcmV0dXJuIHRoZSByZXN1bHQgb2YgYXBwbHlpbmcgY2FwdHVyZSBjb252ZXJzaW9uCiAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiBnaXZlbiBhIHR5cGUgZm9yIGFuIGV4ZWN1dGFibGUsIHBhY2thZ2UsIG9yIG1vZHVsZQogICAgICogQGpscyA1LjEuMTAgQ2FwdHVyZSBDb252ZXJzaW9uCiAgICAgKi8KICAgIFR5cGVNaXJyb3IgY2FwdHVyZShUeXBlTWlycm9yIHQpOwoKICAgIC8qKgogICAgICogUmV0dXJucyBhIHByaW1pdGl2ZSB0eXBlLgogICAgICoKICAgICAqIEBwYXJhbSBraW5kICB0aGUga2luZCBvZiBwcmltaXRpdmUgdHlwZSB0byByZXR1cm4KICAgICAqIEByZXR1cm4gYSBwcmltaXRpdmUgdHlwZQogICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYge0Bjb2RlIGtpbmR9IGlzIG5vdCBhIHByaW1pdGl2ZSBraW5kCiAgICAgKi8KICAgIFByaW1pdGl2ZVR5cGUgZ2V0UHJpbWl0aXZlVHlwZShUeXBlS2luZCBraW5kKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIG51bGwgdHlwZS4gIFRoaXMgaXMgdGhlIHR5cGUgb2Yge0Bjb2RlIG51bGx9LgogICAgICoKICAgICAqIEByZXR1cm4gdGhlIG51bGwgdHlwZQogICAgICovCiAgICBOdWxsVHlwZSBnZXROdWxsVHlwZSgpOwoKICAgIC8qKgogICAgICogUmV0dXJucyBhIHBzZXVkby10eXBlIHVzZWQgd2hlcmUgbm8gYWN0dWFsIHR5cGUgaXMgYXBwcm9wcmlhdGUuCiAgICAgKiBUaGUga2luZCBvZiB0eXBlIHRvIHJldHVybiBtYXkgYmUgZWl0aGVyCiAgICAgKiB7QGxpbmsgVHlwZUtpbmQjVk9JRCBWT0lEfSBvciB7QGxpbmsgVHlwZUtpbmQjTk9ORSBOT05FfS4KICAgICAqCiAgICAgKiA8cD5UbyBnZXQgdGhlIHBzZXVkby10eXBlIGNvcnJlc3BvbmRpbmcgdG8gYSBwYWNrYWdlIG9yIG1vZHVsZSwKICAgICAqIGNhbGwge0Bjb2RlIGFzVHlwZSgpfSBvbiB0aGUgZWxlbWVudCBtb2RlbGluZyB0aGUge0BsaW5rcGxhaW4KICAgICAqIFBhY2thZ2VFbGVtZW50IHBhY2thZ2V9IG9yIHtAbGlua3BsYWluIE1vZHVsZUVsZW1lbnQKICAgICAqIG1vZHVsZX0uIE5hbWVzIGNhbiBiZSBjb252ZXJ0ZWQgdG8gZWxlbWVudHMgZm9yIHBhY2thZ2VzIG9yCiAgICAgKiBtb2R1bGVzIHVzaW5nIHtAbGluayBFbGVtZW50cyNnZXRQYWNrYWdlRWxlbWVudChDaGFyU2VxdWVuY2UpfQogICAgICogb3Ige0BsaW5rIEVsZW1lbnRzI2dldE1vZHVsZUVsZW1lbnQoQ2hhclNlcXVlbmNlKX0sCiAgICAgKiByZXNwZWN0aXZlbHkuCiAgICAgKgogICAgICogQHBhcmFtIGtpbmQgIHRoZSBraW5kIG9mIHR5cGUgdG8gcmV0dXJuCiAgICAgKiBAcmV0dXJuIGEgcHNldWRvLXR5cGUgb2Yga2luZCB7QGNvZGUgVk9JRH0gb3Ige0Bjb2RlIE5PTkV9CiAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB7QGNvZGUga2luZH0gaXMgbm90IHZhbGlkCiAgICAgKi8KICAgIE5vVHlwZSBnZXROb1R5cGUoVHlwZUtpbmQga2luZCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGFuIGFycmF5IHR5cGUgd2l0aCB0aGUgc3BlY2lmaWVkIGNvbXBvbmVudCB0eXBlLgogICAgICoKICAgICAqIEBwYXJhbSBjb21wb25lbnRUeXBlICB0aGUgY29tcG9uZW50IHR5cGUKICAgICAqIEByZXR1cm4gYW4gYXJyYXkgdHlwZSB3aXRoIHRoZSBzcGVjaWZpZWQgY29tcG9uZW50IHR5cGUuCiAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgY29tcG9uZW50IHR5cGUgaXMgbm90IHZhbGlkIGZvcgogICAgICogICAgICAgICAgYW4gYXJyYXkKICAgICAqLwogICAgQXJyYXlUeXBlIGdldEFycmF5VHlwZShUeXBlTWlycm9yIGNvbXBvbmVudFR5cGUpOwoKICAgIC8qKgogICAgICogUmV0dXJucyBhIG5ldyB3aWxkY2FyZCB0eXBlIGFyZ3VtZW50LiAgRWl0aGVyIG9mIHRoZSB3aWxkY2FyZCdzCiAgICAgKiBib3VuZHMgbWF5IGJlIHNwZWNpZmllZCwgb3IgbmVpdGhlciwgYnV0IG5vdCBib3RoLgogICAgICoKICAgICAqIEBwYXJhbSBleHRlbmRzQm91bmQgIHRoZSBleHRlbmRzICh1cHBlcikgYm91bmQsIG9yIHtAY29kZSBudWxsfSBpZiBub25lCiAgICAgKiBAcGFyYW0gc3VwZXJCb3VuZCAgICB0aGUgc3VwZXIgKGxvd2VyKSBib3VuZCwgb3Ige0Bjb2RlIG51bGx9IGlmIG5vbmUKICAgICAqIEByZXR1cm4gYSBuZXcgd2lsZGNhcmQKICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIGJvdW5kcyBhcmUgbm90IHZhbGlkCiAgICAgKi8KICAgIFdpbGRjYXJkVHlwZSBnZXRXaWxkY2FyZFR5cGUoVHlwZU1pcnJvciBleHRlbmRzQm91bmQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFR5cGVNaXJyb3Igc3VwZXJCb3VuZCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSB0eXBlIGNvcnJlc3BvbmRpbmcgdG8gYSB0eXBlIGVsZW1lbnQgYW5kCiAgICAgKiBhY3R1YWwgdHlwZSBhcmd1bWVudHMuCiAgICAgKiBHaXZlbiB0aGUgdHlwZSBlbGVtZW50IGZvciB7QGNvZGUgU2V0fSBhbmQgdGhlIHR5cGUgbWlycm9yCiAgICAgKiBmb3Ige0Bjb2RlIFN0cmluZ30sCiAgICAgKiBmb3IgZXhhbXBsZSwgdGhpcyBtZXRob2QgbWF5IGJlIHVzZWQgdG8gZ2V0IHRoZQogICAgICogcGFyYW1ldGVyaXplZCB0eXBlIHtAY29kZSBTZXQ8U3RyaW5nPn0uCiAgICAgKgogICAgICogPHA+IFRoZSBudW1iZXIgb2YgdHlwZSBhcmd1bWVudHMgbXVzdCBlaXRoZXIgZXF1YWwgdGhlCiAgICAgKiBudW1iZXIgb2YgdGhlIHR5cGUgZWxlbWVudCdzIGZvcm1hbCB0eXBlIHBhcmFtZXRlcnMsIG9yIG11c3QgYmUKICAgICAqIHplcm8uICBJZiB6ZXJvLCBhbmQgaWYgdGhlIHR5cGUgZWxlbWVudCBpcyBnZW5lcmljLAogICAgICogdGhlbiB0aGUgdHlwZSBlbGVtZW50J3MgcmF3IHR5cGUgaXMgcmV0dXJuZWQuCiAgICAgKgogICAgICogPHA+IElmIGEgcGFyYW1ldGVyaXplZCB0eXBlIGlzIGJlaW5nIHJldHVybmVkLCBpdHMgdHlwZSBlbGVtZW50CiAgICAgKiBtdXN0IG5vdCBiZSBjb250YWluZWQgd2l0aGluIGEgZ2VuZXJpYyBvdXRlciBjbGFzcy4KICAgICAqIFRoZSBwYXJhbWV0ZXJpemVkIHR5cGUge0Bjb2RlIE91dGVyPFN0cmluZz4uSW5uZXI8TnVtYmVyPn0sCiAgICAgKiBmb3IgZXhhbXBsZSwgbWF5IGJlIGNvbnN0cnVjdGVkIGJ5IGZpcnN0IHVzaW5nIHRoaXMKICAgICAqIG1ldGhvZCB0byBnZXQgdGhlIHR5cGUge0Bjb2RlIE91dGVyPFN0cmluZz59LCBhbmQgdGhlbiBpbnZva2luZwogICAgICoge0BsaW5rICNnZXREZWNsYXJlZFR5cGUoRGVjbGFyZWRUeXBlLCBUeXBlRWxlbWVudCwgVHlwZU1pcnJvci4uLil9LgogICAgICoKICAgICAqIEBwYXJhbSB0eXBlRWxlbSAgdGhlIHR5cGUgZWxlbWVudAogICAgICogQHBhcmFtIHR5cGVBcmdzICB0aGUgYWN0dWFsIHR5cGUgYXJndW1lbnRzCiAgICAgKiBAcmV0dXJuIHRoZSB0eXBlIGNvcnJlc3BvbmRpbmcgdG8gdGhlIHR5cGUgZWxlbWVudCBhbmQKICAgICAqICAgICAgICAgIGFjdHVhbCB0eXBlIGFyZ3VtZW50cwogICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgdG9vIG1hbnkgb3IgdG9vIGZldwogICAgICogICAgICAgICAgdHlwZSBhcmd1bWVudHMgYXJlIGdpdmVuLCBvciBpZiBhbiBpbmFwcHJvcHJpYXRlIHR5cGUKICAgICAqICAgICAgICAgIGFyZ3VtZW50IG9yIHR5cGUgZWxlbWVudCBpcyBwcm92aWRlZAogICAgICovCiAgICBEZWNsYXJlZFR5cGUgZ2V0RGVjbGFyZWRUeXBlKFR5cGVFbGVtZW50IHR5cGVFbGVtLCBUeXBlTWlycm9yLi4uIHR5cGVBcmdzKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHR5cGUgY29ycmVzcG9uZGluZyB0byBhIHR5cGUgZWxlbWVudAogICAgICogYW5kIGFjdHVhbCB0eXBlIGFyZ3VtZW50cywgZ2l2ZW4gYQogICAgICoge0BsaW5rcGxhaW4gRGVjbGFyZWRUeXBlI2dldEVuY2xvc2luZ1R5cGUoKSBjb250YWluaW5nIHR5cGV9CiAgICAgKiBvZiB3aGljaCBpdCBpcyBhIG1lbWJlci4KICAgICAqIFRoZSBwYXJhbWV0ZXJpemVkIHR5cGUge0Bjb2RlIE91dGVyPFN0cmluZz4uSW5uZXI8TnVtYmVyPn0sCiAgICAgKiBmb3IgZXhhbXBsZSwgbWF5IGJlIGNvbnN0cnVjdGVkIGJ5IGZpcnN0IHVzaW5nCiAgICAgKiB7QGxpbmsgI2dldERlY2xhcmVkVHlwZShUeXBlRWxlbWVudCwgVHlwZU1pcnJvci4uLil9CiAgICAgKiB0byBnZXQgdGhlIHR5cGUge0Bjb2RlIE91dGVyPFN0cmluZz59LCBhbmQgdGhlbiBpbnZva2luZwogICAgICogdGhpcyBtZXRob2QuCiAgICAgKgogICAgICogPHA+IElmIHRoZSBjb250YWluaW5nIHR5cGUgaXMgYSBwYXJhbWV0ZXJpemVkIHR5cGUsCiAgICAgKiB0aGUgbnVtYmVyIG9mIHR5cGUgYXJndW1lbnRzIG11c3QgZXF1YWwgdGhlCiAgICAgKiBudW1iZXIgb2Yge0Bjb2RlIHR5cGVFbGVtfSdzIGZvcm1hbCB0eXBlIHBhcmFtZXRlcnMuCiAgICAgKiBJZiBpdCBpcyBub3QgcGFyYW1ldGVyaXplZCBvciBpZiBpdCBpcyB7QGNvZGUgbnVsbH0sIHRoaXMgbWV0aG9kIGlzCiAgICAgKiBlcXVpdmFsZW50IHRvIHtAY29kZSBnZXREZWNsYXJlZFR5cGUodHlwZUVsZW0sIHR5cGVBcmdzKX0uCiAgICAgKgogICAgICogQHBhcmFtIGNvbnRhaW5pbmcgIHRoZSBjb250YWluaW5nIHR5cGUsIG9yIHtAY29kZSBudWxsfSBpZiBub25lCiAgICAgKiBAcGFyYW0gdHlwZUVsZW0gICAgdGhlIHR5cGUgZWxlbWVudAogICAgICogQHBhcmFtIHR5cGVBcmdzICAgIHRoZSBhY3R1YWwgdHlwZSBhcmd1bWVudHMKICAgICAqIEByZXR1cm4gdGhlIHR5cGUgY29ycmVzcG9uZGluZyB0byB0aGUgdHlwZSBlbGVtZW50IGFuZAogICAgICogICAgICAgICAgYWN0dWFsIHR5cGUgYXJndW1lbnRzLCBjb250YWluZWQgd2l0aGluIHRoZSBnaXZlbiB0eXBlCiAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0b28gbWFueSBvciB0b28gZmV3CiAgICAgKiAgICAgICAgICB0eXBlIGFyZ3VtZW50cyBhcmUgZ2l2ZW4sIG9yIGlmIGFuIGluYXBwcm9wcmlhdGUgdHlwZQogICAgICogICAgICAgICAgYXJndW1lbnQsIHR5cGUgZWxlbWVudCwgb3IgY29udGFpbmluZyB0eXBlIGlzIHByb3ZpZGVkCiAgICAgKi8KICAgIERlY2xhcmVkVHlwZSBnZXREZWNsYXJlZFR5cGUoRGVjbGFyZWRUeXBlIGNvbnRhaW5pbmcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFR5cGVFbGVtZW50IHR5cGVFbGVtLCBUeXBlTWlycm9yLi4uIHR5cGVBcmdzKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHR5cGUgb2YgYW4gZWxlbWVudCB3aGVuIHRoYXQgZWxlbWVudCBpcyB2aWV3ZWQgYXMKICAgICAqIGEgbWVtYmVyIG9mLCBvciBvdGhlcndpc2UgZGlyZWN0bHkgY29udGFpbmVkIGJ5LCBhIGdpdmVuIHR5cGUuCiAgICAgKiBGb3IgZXhhbXBsZSwKICAgICAqIHdoZW4gdmlld2VkIGFzIGEgbWVtYmVyIG9mIHRoZSBwYXJhbWV0ZXJpemVkIHR5cGUge0Bjb2RlIFNldDxTdHJpbmc+fSwKICAgICAqIHRoZSB7QGNvZGUgU2V0LmFkZH0gbWV0aG9kIGlzIGFuIHtAY29kZSBFeGVjdXRhYmxlVHlwZX0KICAgICAqIHdob3NlIHBhcmFtZXRlciBpcyBvZiB0eXBlIHtAY29kZSBTdHJpbmd9LgogICAgICoKICAgICAqIEBwYXJhbSBjb250YWluaW5nICB0aGUgY29udGFpbmluZyB0eXBlCiAgICAgKiBAcGFyYW0gZWxlbWVudCAgICAgdGhlIGVsZW1lbnQKICAgICAqIEByZXR1cm4gdGhlIHR5cGUgb2YgdGhlIGVsZW1lbnQgYXMgdmlld2VkIGZyb20gdGhlIGNvbnRhaW5pbmcgdHlwZQogICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgdGhlIGVsZW1lbnQgaXMgbm90IGEgdmFsaWQgb25lCiAgICAgKiAgICAgICAgICBmb3IgdGhlIGdpdmVuIHR5cGUKICAgICAqLwogICAgVHlwZU1pcnJvciBhc01lbWJlck9mKERlY2xhcmVkVHlwZSBjb250YWluaW5nLCBFbGVtZW50IGVsZW1lbnQpOwp9ClBLAwQKAAAIAAAGO6lKZTr67vAdAADwHQAALQAAAGphdmF4L2xhbmcvbW9kZWwvdXRpbC9TaW1wbGVUeXBlVmlzaXRvcjYuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAxNywgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBqYXZheC5sYW5nLm1vZGVsLnV0aWw7CgppbXBvcnQgamF2YXgubGFuZy5tb2RlbC50eXBlLio7CmltcG9ydCBqYXZheC5hbm5vdGF0aW9uLnByb2Nlc3NpbmcuU3VwcG9ydGVkU291cmNlVmVyc2lvbjsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuU291cmNlVmVyc2lvbjsKaW1wb3J0IHN0YXRpYyBqYXZheC5sYW5nLm1vZGVsLlNvdXJjZVZlcnNpb24uKjsKCgovKioKICogQSBzaW1wbGUgdmlzaXRvciBvZiB0eXBlcyB3aXRoIGRlZmF1bHQgYmVoYXZpb3IgYXBwcm9wcmlhdGUgZm9yIHRoZQogKiB7QGxpbmsgU291cmNlVmVyc2lvbiNSRUxFQVNFXzYgUkVMRUFTRV82fSBzb3VyY2UgdmVyc2lvbi4KICoKICogVmlzaXQgbWV0aG9kcyBjb3JyZXNwb25kaW5nIHRvIHtAY29kZSBSRUxFQVNFXzZ9IGxhbmd1YWdlCiAqIGNvbnN0cnVjdHMgY2FsbCB7QGxpbmsgI2RlZmF1bHRBY3Rpb24gZGVmYXVsdEFjdGlvbn0sIHBhc3NpbmcgdGhlaXIKICogYXJndW1lbnRzIHRvIHtAY29kZSBkZWZhdWx0QWN0aW9ufSdzIGNvcnJlc3BvbmRpbmcgcGFyYW1ldGVycy4KICoKICogRm9yIGNvbnN0cnVjdHMgaW50cm9kdWNlZCBpbiB7QGNvZGUgUkVMRUFTRV83fSBhbmQgbGF0ZXIsIHtAY29kZQogKiB2aXNpdFVua25vd259IGlzIGNhbGxlZCBpbnN0ZWFkLgogKgogKiA8cD4gTWV0aG9kcyBpbiB0aGlzIGNsYXNzIG1heSBiZSBvdmVycmlkZGVuIHN1YmplY3QgdG8gdGhlaXIKICogZ2VuZXJhbCBjb250cmFjdC4gIE5vdGUgdGhhdCBhbm5vdGF0aW5nIG1ldGhvZHMgaW4gY29uY3JldGUKICogc3ViY2xhc3NlcyB3aXRoIHtAbGluayBqYXZhLmxhbmcuT3ZlcnJpZGUgQE92ZXJyaWRlfSB3aWxsIGhlbHAKICogZW5zdXJlIHRoYXQgbWV0aG9kcyBhcmUgb3ZlcnJpZGRlbiBhcyBpbnRlbmRlZC4KICoKICogPHA+IDxiPldBUk5JTkc6PC9iPiBUaGUge0Bjb2RlIFR5cGVWaXNpdG9yfSBpbnRlcmZhY2UgaW1wbGVtZW50ZWQKICogYnkgdGhpcyBjbGFzcyBtYXkgaGF2ZSBtZXRob2RzIGFkZGVkIHRvIGl0IGluIHRoZSBmdXR1cmUgdG8KICogYWNjb21tb2RhdGUgbmV3LCBjdXJyZW50bHkgdW5rbm93biwgbGFuZ3VhZ2Ugc3RydWN0dXJlcyBhZGRlZCB0bwogKiBmdXR1cmUgdmVyc2lvbnMgb2YgdGhlIEphdmEmdHJhZGU7IHByb2dyYW1taW5nIGxhbmd1YWdlLgogKiBUaGVyZWZvcmUsIG1ldGhvZHMgd2hvc2UgbmFtZXMgYmVnaW4gd2l0aCB7QGNvZGUgInZpc2l0In0gbWF5IGJlCiAqIGFkZGVkIHRvIHRoaXMgY2xhc3MgaW4gdGhlIGZ1dHVyZTsgdG8gYXZvaWQgaW5jb21wYXRpYmlsaXRpZXMsCiAqIGNsYXNzZXMgd2hpY2ggZXh0ZW5kIHRoaXMgY2xhc3Mgc2hvdWxkIG5vdCBkZWNsYXJlIGFueSBpbnN0YW5jZQogKiBtZXRob2RzIHdpdGggbmFtZXMgYmVnaW5uaW5nIHdpdGgge0Bjb2RlICJ2aXNpdCJ9LgogKgogKiA8cD5XaGVuIHN1Y2ggYSBuZXcgdmlzaXQgbWV0aG9kIGlzIGFkZGVkLCB0aGUgZGVmYXVsdAogKiBpbXBsZW1lbnRhdGlvbiBpbiB0aGlzIGNsYXNzIHdpbGwgYmUgdG8gY2FsbCB0aGUge0BsaW5rCiAqICN2aXNpdFVua25vd24gdmlzaXRVbmtub3dufSBtZXRob2QuICBBIG5ldyBzaW1wbGUgdHlwZSB2aXNpdG9yCiAqIGNsYXNzIHdpbGwgYWxzbyBiZSBpbnRyb2R1Y2VkIHRvIGNvcnJlc3BvbmQgdG8gdGhlIG5ldyBsYW5ndWFnZQogKiBsZXZlbDsgdGhpcyB2aXNpdG9yIHdpbGwgaGF2ZSBkaWZmZXJlbnQgZGVmYXVsdCBiZWhhdmlvciBmb3IgdGhlCiAqIHZpc2l0IG1ldGhvZCBpbiBxdWVzdGlvbi4gIFdoZW4gdGhlIG5ldyB2aXNpdG9yIGlzIGludHJvZHVjZWQsIGFsbAogKiBvciBwb3J0aW9ucyBvZiB0aGlzIHZpc2l0b3IgbWF5IGJlIGRlcHJlY2F0ZWQuCiAqCiAqIEBwYXJhbSA8Uj4gdGhlIHJldHVybiB0eXBlIG9mIHRoaXMgdmlzaXRvcidzIG1ldGhvZHMuICBVc2Uge0BsaW5rCiAqICAgICAgICAgICAgVm9pZH0gZm9yIHZpc2l0b3JzIHRoYXQgZG8gbm90IG5lZWQgdG8gcmV0dXJuIHJlc3VsdHMuCiAqIEBwYXJhbSA8UD4gdGhlIHR5cGUgb2YgdGhlIGFkZGl0aW9uYWwgcGFyYW1ldGVyIHRvIHRoaXMgdmlzaXRvcidzCiAqICAgICAgICAgICAgbWV0aG9kcy4gIFVzZSB7QGNvZGUgVm9pZH0gZm9yIHZpc2l0b3JzIHRoYXQgZG8gbm90IG5lZWQgYW4KICogICAgICAgICAgICBhZGRpdGlvbmFsIHBhcmFtZXRlci4KICoKICogQGF1dGhvciBKb3NlcGggRC4gRGFyY3kKICogQGF1dGhvciBTY290dCBTZWxpZ21hbgogKiBAYXV0aG9yIFBldGVyIHZvbiBkZXIgQWgmZWFjdXRlOwogKgogKiBAc2VlIFNpbXBsZVR5cGVWaXNpdG9yNwogKiBAc2VlIFNpbXBsZVR5cGVWaXNpdG9yOAogKiBAc2VlIFNpbXBsZVR5cGVWaXNpdG9yOQogKiBAc2luY2UgMS42CiAqLwpAU3VwcG9ydGVkU291cmNlVmVyc2lvbihSRUxFQVNFXzYpCnB1YmxpYyBjbGFzcyBTaW1wbGVUeXBlVmlzaXRvcjY8UiwgUD4gZXh0ZW5kcyBBYnN0cmFjdFR5cGVWaXNpdG9yNjxSLCBQPiB7CiAgICAvKioKICAgICAqIERlZmF1bHQgdmFsdWUgdG8gYmUgcmV0dXJuZWQ7IHtAbGluayAjZGVmYXVsdEFjdGlvbgogICAgICogZGVmYXVsdEFjdGlvbn0gcmV0dXJucyB0aGlzIHZhbHVlIHVubGVzcyB0aGUgbWV0aG9kIGlzCiAgICAgKiBvdmVycmlkZGVuLgogICAgICovCiAgICBwcm90ZWN0ZWQgZmluYWwgUiBERUZBVUxUX1ZBTFVFOwoKICAgIC8qKgogICAgICogQ29uc3RydWN0b3IgZm9yIGNvbmNyZXRlIHN1YmNsYXNzZXM7IHVzZXMge0Bjb2RlIG51bGx9IGZvciB0aGUKICAgICAqIGRlZmF1bHQgdmFsdWUuCiAgICAgKiBAZGVwcmVjYXRlZCBSZWxlYXNlIDYgaXMgb2Jzb2xldGU7IHVwZGF0ZSB0byBhIHZpc2l0b3IgZm9yIGEgbmV3ZXIKICAgICAqIHJlbGVhc2UgbGV2ZWwuCiAgICAgKi8KICAgIEBEZXByZWNhdGVkCiAgICBwcm90ZWN0ZWQgU2ltcGxlVHlwZVZpc2l0b3I2KCl7CiAgICAgICAgREVGQVVMVF9WQUxVRSA9IG51bGw7CiAgICB9CgogICAgLyoqCiAgICAgKiBDb25zdHJ1Y3RvciBmb3IgY29uY3JldGUgc3ViY2xhc3NlczsgdXNlcyB0aGUgYXJndW1lbnQgZm9yIHRoZQogICAgICogZGVmYXVsdCB2YWx1ZS4KICAgICAqCiAgICAgKiBAcGFyYW0gZGVmYXVsdFZhbHVlIHRoZSB2YWx1ZSB0byBhc3NpZ24gdG8ge0BsaW5rICNERUZBVUxUX1ZBTFVFfQogICAgICogQGRlcHJlY2F0ZWQgUmVsZWFzZSA2IGlzIG9ic29sZXRlOyB1cGRhdGUgdG8gYSB2aXNpdG9yIGZvciBhIG5ld2VyCiAgICAgKiByZWxlYXNlIGxldmVsLgogICAgICovCiAgICBARGVwcmVjYXRlZAogICAgcHJvdGVjdGVkIFNpbXBsZVR5cGVWaXNpdG9yNihSIGRlZmF1bHRWYWx1ZSl7CiAgICAgICAgREVGQVVMVF9WQUxVRSA9IGRlZmF1bHRWYWx1ZTsKICAgIH0KCiAgICAvKioKICAgICAqIFRoZSBkZWZhdWx0IGFjdGlvbiBmb3IgdmlzaXQgbWV0aG9kcy4gIFRoZSBpbXBsZW1lbnRhdGlvbiBpbgogICAgICogdGhpcyBjbGFzcyBqdXN0IHJldHVybnMge0BsaW5rICNERUZBVUxUX1ZBTFVFfTsgc3ViY2xhc3NlcyB3aWxsCiAgICAgKiBjb21tb25seSBvdmVycmlkZSB0aGlzIG1ldGhvZC4KICAgICAqCiAgICAgKiBAcGFyYW0gZSB0aGUgdHlwZSB0byBwcm9jZXNzCiAgICAgKiBAcGFyYW0gcCBhIHZpc2l0b3Itc3BlY2lmaWVkIHBhcmFtZXRlcgogICAgICogQHJldHVybiB7QGNvZGUgREVGQVVMVF9WQUxVRX0gdW5sZXNzIG92ZXJyaWRkZW4KICAgICAqLwogICAgcHJvdGVjdGVkIFIgZGVmYXVsdEFjdGlvbihUeXBlTWlycm9yIGUsIFAgcCkgewogICAgICAgIHJldHVybiBERUZBVUxUX1ZBTFVFOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIGNhbGxzIHtAY29kZSBkZWZhdWx0QWN0aW9ufS4KICAgICAqCiAgICAgKiBAcGFyYW0gdCB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuICB0aGUgcmVzdWx0IG9mIHtAY29kZSBkZWZhdWx0QWN0aW9ufQogICAgICovCiAgICBwdWJsaWMgUiB2aXNpdFByaW1pdGl2ZShQcmltaXRpdmVUeXBlIHQsIFAgcCkgewogICAgICAgIHJldHVybiBkZWZhdWx0QWN0aW9uKHQsIHApOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIGNhbGxzIHtAY29kZSBkZWZhdWx0QWN0aW9ufS4KICAgICAqCiAgICAgKiBAcGFyYW0gdCB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuICB0aGUgcmVzdWx0IG9mIHtAY29kZSBkZWZhdWx0QWN0aW9ufQogICAgICovCiAgICBwdWJsaWMgUiB2aXNpdE51bGwoTnVsbFR5cGUgdCwgUCBwKXsKICAgICAgICByZXR1cm4gZGVmYXVsdEFjdGlvbih0LCBwKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30gVGhpcyBpbXBsZW1lbnRhdGlvbiBjYWxscyB7QGNvZGUgZGVmYXVsdEFjdGlvbn0uCiAgICAgKgogICAgICogQHBhcmFtIHQge0Bpbmhlcml0RG9jfQogICAgICogQHBhcmFtIHAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiAgdGhlIHJlc3VsdCBvZiB7QGNvZGUgZGVmYXVsdEFjdGlvbn0KICAgICAqLwogICAgcHVibGljIFIgdmlzaXRBcnJheShBcnJheVR5cGUgdCwgUCBwKXsKICAgICAgICByZXR1cm4gZGVmYXVsdEFjdGlvbih0LCBwKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30gVGhpcyBpbXBsZW1lbnRhdGlvbiBjYWxscyB7QGNvZGUgZGVmYXVsdEFjdGlvbn0uCiAgICAgKgogICAgICogQHBhcmFtIHQge0Bpbmhlcml0RG9jfQogICAgICogQHBhcmFtIHAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiAgdGhlIHJlc3VsdCBvZiB7QGNvZGUgZGVmYXVsdEFjdGlvbn0KICAgICAqLwogICAgcHVibGljIFIgdmlzaXREZWNsYXJlZChEZWNsYXJlZFR5cGUgdCwgUCBwKXsKICAgICAgICByZXR1cm4gZGVmYXVsdEFjdGlvbih0LCBwKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30gVGhpcyBpbXBsZW1lbnRhdGlvbiBjYWxscyB7QGNvZGUgZGVmYXVsdEFjdGlvbn0uCiAgICAgKgogICAgICogQHBhcmFtIHQge0Bpbmhlcml0RG9jfQogICAgICogQHBhcmFtIHAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiAgdGhlIHJlc3VsdCBvZiB7QGNvZGUgZGVmYXVsdEFjdGlvbn0KICAgICAqLwogICAgcHVibGljIFIgdmlzaXRFcnJvcihFcnJvclR5cGUgdCwgUCBwKXsKICAgICAgICByZXR1cm4gZGVmYXVsdEFjdGlvbih0LCBwKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30gVGhpcyBpbXBsZW1lbnRhdGlvbiBjYWxscyB7QGNvZGUgZGVmYXVsdEFjdGlvbn0uCiAgICAgKgogICAgICogQHBhcmFtIHQge0Bpbmhlcml0RG9jfQogICAgICogQHBhcmFtIHAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiAgdGhlIHJlc3VsdCBvZiB7QGNvZGUgZGVmYXVsdEFjdGlvbn0KICAgICAqLwogICAgcHVibGljIFIgdmlzaXRUeXBlVmFyaWFibGUoVHlwZVZhcmlhYmxlIHQsIFAgcCl7CiAgICAgICAgcmV0dXJuIGRlZmF1bHRBY3Rpb24odCwgcCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gY2FsbHMge0Bjb2RlIGRlZmF1bHRBY3Rpb259LgogICAgICoKICAgICAqIEBwYXJhbSB0IHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gIHRoZSByZXN1bHQgb2Yge0Bjb2RlIGRlZmF1bHRBY3Rpb259CiAgICAgKi8KICAgIHB1YmxpYyBSIHZpc2l0V2lsZGNhcmQoV2lsZGNhcmRUeXBlIHQsIFAgcCl7CiAgICAgICAgcmV0dXJuIGRlZmF1bHRBY3Rpb24odCwgcCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gY2FsbHMge0Bjb2RlIGRlZmF1bHRBY3Rpb259LgogICAgICoKICAgICAqIEBwYXJhbSB0IHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gIHRoZSByZXN1bHQgb2Yge0Bjb2RlIGRlZmF1bHRBY3Rpb259CiAgICAgKi8KICAgIHB1YmxpYyBSIHZpc2l0RXhlY3V0YWJsZShFeGVjdXRhYmxlVHlwZSB0LCBQIHApIHsKICAgICAgICByZXR1cm4gZGVmYXVsdEFjdGlvbih0LCBwKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30gVGhpcyBpbXBsZW1lbnRhdGlvbiBjYWxscyB7QGNvZGUgZGVmYXVsdEFjdGlvbn0uCiAgICAgKgogICAgICogQHBhcmFtIHQge0Bpbmhlcml0RG9jfQogICAgICogQHBhcmFtIHAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiAgdGhlIHJlc3VsdCBvZiB7QGNvZGUgZGVmYXVsdEFjdGlvbn0KICAgICAqLwogICAgcHVibGljIFIgdmlzaXROb1R5cGUoTm9UeXBlIHQsIFAgcCl7CiAgICAgICAgcmV0dXJuIGRlZmF1bHRBY3Rpb24odCwgcCk7CiAgICB9Cn0KUEsDBAoAAAgAAAY7qUqV0METticAALYnAAArAAAAamF2YXgvbGFuZy9tb2RlbC91dGlsL1R5cGVLaW5kVmlzaXRvcjYuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAxNywgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBqYXZheC5sYW5nLm1vZGVsLnV0aWw7CgppbXBvcnQgamF2YXguYW5ub3RhdGlvbi5wcm9jZXNzaW5nLlN1cHBvcnRlZFNvdXJjZVZlcnNpb247CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLlNvdXJjZVZlcnNpb247CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLnR5cGUuKjsKaW1wb3J0IHN0YXRpYyBqYXZheC5sYW5nLm1vZGVsLlNvdXJjZVZlcnNpb24uKjsKCi8qKgogKiBBIHZpc2l0b3Igb2YgdHlwZXMgYmFzZWQgb24gdGhlaXIge0BsaW5rcGxhaW4gVHlwZUtpbmQga2luZH0gd2l0aAogKiBkZWZhdWx0IGJlaGF2aW9yIGFwcHJvcHJpYXRlIGZvciB0aGUge0BsaW5rIFNvdXJjZVZlcnNpb24jUkVMRUFTRV82CiAqIFJFTEVBU0VfNn0gc291cmNlIHZlcnNpb24uICBGb3Ige0BsaW5rcGxhaW4KICogVHlwZU1pcnJvciB0eXBlc30gPGNvZGU+PGk+WHl6PC9pPjwvY29kZT4gdGhhdCBtYXkgaGF2ZSBtb3JlIHRoYW4gb25lCiAqIGtpbmQsIHRoZSA8Y29kZT52aXNpdDxpPlh5ejwvaT48L2NvZGU+IG1ldGhvZHMgaW4gdGhpcyBjbGFzcyBkZWxlZ2F0ZQogKiB0byB0aGUgPGNvZGU+dmlzaXQ8aT5YeXo8L2k+QXM8aT5LaW5kPC9pPjwvY29kZT4gbWV0aG9kIGNvcnJlc3BvbmRpbmcgdG8gdGhlCiAqIGZpcnN0IGFyZ3VtZW50J3Mga2luZC4gIFRoZSA8Y29kZT52aXNpdDxpPlh5ejwvaT5BczxpPktpbmQ8L2k+PC9jb2RlPiBtZXRob2RzCiAqIGNhbGwge0BsaW5rICNkZWZhdWx0QWN0aW9uIGRlZmF1bHRBY3Rpb259LCBwYXNzaW5nIHRoZWlyIGFyZ3VtZW50cwogKiB0byB7QGNvZGUgZGVmYXVsdEFjdGlvbn0ncyBjb3JyZXNwb25kaW5nIHBhcmFtZXRlcnMuCiAqCiAqIDxwPiBNZXRob2RzIGluIHRoaXMgY2xhc3MgbWF5IGJlIG92ZXJyaWRkZW4gc3ViamVjdCB0byB0aGVpcgogKiBnZW5lcmFsIGNvbnRyYWN0LiAgTm90ZSB0aGF0IGFubm90YXRpbmcgbWV0aG9kcyBpbiBjb25jcmV0ZQogKiBzdWJjbGFzc2VzIHdpdGgge0BsaW5rIGphdmEubGFuZy5PdmVycmlkZSBAT3ZlcnJpZGV9IHdpbGwgaGVscAogKiBlbnN1cmUgdGhhdCBtZXRob2RzIGFyZSBvdmVycmlkZGVuIGFzIGludGVuZGVkLgogKgogKiA8cD4gPGI+V0FSTklORzo8L2I+IFRoZSB7QGNvZGUgVHlwZVZpc2l0b3J9IGludGVyZmFjZSBpbXBsZW1lbnRlZAogKiBieSB0aGlzIGNsYXNzIG1heSBoYXZlIG1ldGhvZHMgYWRkZWQgdG8gaXQgaW4gdGhlIGZ1dHVyZSB0bwogKiBhY2NvbW1vZGF0ZSBuZXcsIGN1cnJlbnRseSB1bmtub3duLCBsYW5ndWFnZSBzdHJ1Y3R1cmVzIGFkZGVkIHRvCiAqIGZ1dHVyZSB2ZXJzaW9ucyBvZiB0aGUgSmF2YSZ0cmFkZTsgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2UuCiAqIFRoZXJlZm9yZSwgbWV0aG9kcyB3aG9zZSBuYW1lcyBiZWdpbiB3aXRoIHtAY29kZSAidmlzaXQifSBtYXkgYmUKICogYWRkZWQgdG8gdGhpcyBjbGFzcyBpbiB0aGUgZnV0dXJlOyB0byBhdm9pZCBpbmNvbXBhdGliaWxpdGllcywKICogY2xhc3NlcyB3aGljaCBleHRlbmQgdGhpcyBjbGFzcyBzaG91bGQgbm90IGRlY2xhcmUgYW55IGluc3RhbmNlCiAqIG1ldGhvZHMgd2l0aCBuYW1lcyBiZWdpbm5pbmcgd2l0aCB7QGNvZGUgInZpc2l0In0uCiAqCiAqIDxwPldoZW4gc3VjaCBhIG5ldyB2aXNpdCBtZXRob2QgaXMgYWRkZWQsIHRoZSBkZWZhdWx0CiAqIGltcGxlbWVudGF0aW9uIGluIHRoaXMgY2xhc3Mgd2lsbCBiZSB0byBjYWxsIHRoZSB7QGxpbmsKICogI3Zpc2l0VW5rbm93biB2aXNpdFVua25vd259IG1ldGhvZC4gIEEgbmV3IHR5cGUga2luZCB2aXNpdG9yIGNsYXNzCiAqIHdpbGwgYWxzbyBiZSBpbnRyb2R1Y2VkIHRvIGNvcnJlc3BvbmQgdG8gdGhlIG5ldyBsYW5ndWFnZSBsZXZlbDsKICogdGhpcyB2aXNpdG9yIHdpbGwgaGF2ZSBkaWZmZXJlbnQgZGVmYXVsdCBiZWhhdmlvciBmb3IgdGhlIHZpc2l0CiAqIG1ldGhvZCBpbiBxdWVzdGlvbi4gIFdoZW4gdGhlIG5ldyB2aXNpdG9yIGlzIGludHJvZHVjZWQsIGFsbCBvcgogKiBwb3J0aW9ucyBvZiB0aGlzIHZpc2l0b3IgbWF5IGJlIGRlcHJlY2F0ZWQuCiAqCiAqIEBwYXJhbSA8Uj4gdGhlIHJldHVybiB0eXBlIG9mIHRoaXMgdmlzaXRvcidzIG1ldGhvZHMuICBVc2Uge0BsaW5rCiAqICAgICAgICAgICAgVm9pZH0gZm9yIHZpc2l0b3JzIHRoYXQgZG8gbm90IG5lZWQgdG8gcmV0dXJuIHJlc3VsdHMuCiAqIEBwYXJhbSA8UD4gdGhlIHR5cGUgb2YgdGhlIGFkZGl0aW9uYWwgcGFyYW1ldGVyIHRvIHRoaXMgdmlzaXRvcidzCiAqICAgICAgICAgICAgbWV0aG9kcy4gIFVzZSB7QGNvZGUgVm9pZH0gZm9yIHZpc2l0b3JzIHRoYXQgZG8gbm90IG5lZWQgYW4KICogICAgICAgICAgICBhZGRpdGlvbmFsIHBhcmFtZXRlci4KICoKICogQGF1dGhvciBKb3NlcGggRC4gRGFyY3kKICogQGF1dGhvciBTY290dCBTZWxpZ21hbgogKiBAYXV0aG9yIFBldGVyIHZvbiBkZXIgQWgmZWFjdXRlOwogKgogKiBAc2VlIFR5cGVLaW5kVmlzaXRvcjcKICogQHNlZSBUeXBlS2luZFZpc2l0b3I4CiAqIEBzaW5jZSAxLjYKICovCkBTdXBwb3J0ZWRTb3VyY2VWZXJzaW9uKFJFTEVBU0VfNikKcHVibGljIGNsYXNzIFR5cGVLaW5kVmlzaXRvcjY8UiwgUD4gZXh0ZW5kcyBTaW1wbGVUeXBlVmlzaXRvcjY8UiwgUD4gewogICAgLyoqCiAgICAgKiBDb25zdHJ1Y3RvciBmb3IgY29uY3JldGUgc3ViY2xhc3NlcyB0byBjYWxsOyB1c2VzIHtAY29kZSBudWxsfQogICAgICogZm9yIHRoZSBkZWZhdWx0IHZhbHVlLgogICAgICogQGRlcHJlY2F0ZWQgUmVsZWFzZSA2IGlzIG9ic29sZXRlOyB1cGRhdGUgdG8gYSB2aXNpdG9yIGZvciBhIG5ld2VyCiAgICAgKiByZWxlYXNlIGxldmVsLgogICAgICovCiAgICBARGVwcmVjYXRlZAogICAgcHJvdGVjdGVkIFR5cGVLaW5kVmlzaXRvcjYoKSB7CiAgICAgICAgc3VwZXIobnVsbCk7CiAgICB9CgoKICAgIC8qKgogICAgICogQ29uc3RydWN0b3IgZm9yIGNvbmNyZXRlIHN1YmNsYXNzZXMgdG8gY2FsbDsgdXNlcyB0aGUgYXJndW1lbnQKICAgICAqIGZvciB0aGUgZGVmYXVsdCB2YWx1ZS4KICAgICAqCiAgICAgKiBAcGFyYW0gZGVmYXVsdFZhbHVlIHRoZSB2YWx1ZSB0byBhc3NpZ24gdG8ge0BsaW5rICNERUZBVUxUX1ZBTFVFfQogICAgICogQGRlcHJlY2F0ZWQgUmVsZWFzZSA2IGlzIG9ic29sZXRlOyB1cGRhdGUgdG8gYSB2aXNpdG9yIGZvciBhIG5ld2VyCiAgICAgKiByZWxlYXNlIGxldmVsLgogICAgICovCiAgICBARGVwcmVjYXRlZAogICAgcHJvdGVjdGVkIFR5cGVLaW5kVmlzaXRvcjYoUiBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBzdXBlcihkZWZhdWx0VmFsdWUpOwogICAgfQoKICAgIC8qKgogICAgICogVmlzaXRzIGEgcHJpbWl0aXZlIHR5cGUsIGRpc3BhdGNoaW5nIHRvIHRoZSB2aXNpdCBtZXRob2QgZm9yCiAgICAgKiB0aGUgc3BlY2lmaWMge0BsaW5rcGxhaW4gVHlwZUtpbmQga2luZH0gb2YgcHJpbWl0aXZlIHR5cGU6CiAgICAgKiB7QGNvZGUgQk9PTEVBTn0sIHtAY29kZSBCWVRFfSwgZXRjLgogICAgICoKICAgICAqIEBwYXJhbSB0IHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gIHRoZSByZXN1bHQgb2YgdGhlIGtpbmQtc3BlY2lmaWMgdmlzaXQgbWV0aG9kCiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRQcmltaXRpdmUoUHJpbWl0aXZlVHlwZSB0LCBQIHApIHsKICAgICAgICBUeXBlS2luZCBrID0gdC5nZXRLaW5kKCk7CiAgICAgICAgc3dpdGNoIChrKSB7CiAgICAgICAgY2FzZSBCT09MRUFOOgogICAgICAgICAgICByZXR1cm4gdmlzaXRQcmltaXRpdmVBc0Jvb2xlYW4odCwgcCk7CgogICAgICAgIGNhc2UgQllURToKICAgICAgICAgICAgcmV0dXJuIHZpc2l0UHJpbWl0aXZlQXNCeXRlKHQsIHApOwoKICAgICAgICBjYXNlIFNIT1JUOgogICAgICAgICAgICByZXR1cm4gdmlzaXRQcmltaXRpdmVBc1Nob3J0KHQsIHApOwoKICAgICAgICBjYXNlIElOVDoKICAgICAgICAgICAgcmV0dXJuIHZpc2l0UHJpbWl0aXZlQXNJbnQodCwgcCk7CgogICAgICAgIGNhc2UgTE9ORzoKICAgICAgICAgICAgcmV0dXJuIHZpc2l0UHJpbWl0aXZlQXNMb25nKHQsIHApOwoKICAgICAgICBjYXNlIENIQVI6CiAgICAgICAgICAgIHJldHVybiB2aXNpdFByaW1pdGl2ZUFzQ2hhcih0LCBwKTsKCiAgICAgICAgY2FzZSBGTE9BVDoKICAgICAgICAgICAgcmV0dXJuIHZpc2l0UHJpbWl0aXZlQXNGbG9hdCh0LCBwKTsKCiAgICAgICAgY2FzZSBET1VCTEU6CiAgICAgICAgICAgIHJldHVybiB2aXNpdFByaW1pdGl2ZUFzRG91YmxlKHQsIHApOwoKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoIkJhZCBraW5kICIgKyBrICsgIiBmb3IgUHJpbWl0aXZlVHlwZSIgKyB0KTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBWaXNpdHMgYSB7QGNvZGUgQk9PTEVBTn0gcHJpbWl0aXZlIHR5cGUgYnkgY2FsbGluZwogICAgICoge0Bjb2RlIGRlZmF1bHRBY3Rpb259LgogICAgICoKICAgICAqIEBwYXJhbSB0IHRoZSB0eXBlIHRvIHZpc2l0CiAgICAgKiBAcGFyYW0gcCBhIHZpc2l0b3Itc3BlY2lmaWVkIHBhcmFtZXRlcgogICAgICogQHJldHVybiAgdGhlIHJlc3VsdCBvZiB7QGNvZGUgZGVmYXVsdEFjdGlvbn0KICAgICAqLwogICAgcHVibGljIFIgdmlzaXRQcmltaXRpdmVBc0Jvb2xlYW4oUHJpbWl0aXZlVHlwZSB0LCBQIHApIHsKICAgICAgICByZXR1cm4gZGVmYXVsdEFjdGlvbih0LCBwKTsKICAgIH0KCiAgICAvKioKICAgICAqIFZpc2l0cyBhIHtAY29kZSBCWVRFfSBwcmltaXRpdmUgdHlwZSBieSBjYWxsaW5nCiAgICAgKiB7QGNvZGUgZGVmYXVsdEFjdGlvbn0uCiAgICAgKgogICAgICogQHBhcmFtIHQgdGhlIHR5cGUgdG8gdmlzaXQKICAgICAqIEBwYXJhbSBwIGEgdmlzaXRvci1zcGVjaWZpZWQgcGFyYW1ldGVyCiAgICAgKiBAcmV0dXJuICB0aGUgcmVzdWx0IG9mIHtAY29kZSBkZWZhdWx0QWN0aW9ufQogICAgICovCiAgICBwdWJsaWMgUiB2aXNpdFByaW1pdGl2ZUFzQnl0ZShQcmltaXRpdmVUeXBlIHQsIFAgcCkgewogICAgICAgIHJldHVybiBkZWZhdWx0QWN0aW9uKHQsIHApOwogICAgfQoKICAgIC8qKgogICAgICogVmlzaXRzIGEge0Bjb2RlIFNIT1JUfSBwcmltaXRpdmUgdHlwZSBieSBjYWxsaW5nCiAgICAgKiB7QGNvZGUgZGVmYXVsdEFjdGlvbn0uCiAgICAgKgogICAgICogQHBhcmFtIHQgdGhlIHR5cGUgdG8gdmlzaXQKICAgICAqIEBwYXJhbSBwIGEgdmlzaXRvci1zcGVjaWZpZWQgcGFyYW1ldGVyCiAgICAgKiBAcmV0dXJuICB0aGUgcmVzdWx0IG9mIHtAY29kZSBkZWZhdWx0QWN0aW9ufQogICAgICovCiAgICBwdWJsaWMgUiB2aXNpdFByaW1pdGl2ZUFzU2hvcnQoUHJpbWl0aXZlVHlwZSB0LCBQIHApIHsKICAgICAgICByZXR1cm4gZGVmYXVsdEFjdGlvbih0LCBwKTsKICAgIH0KCiAgICAvKioKICAgICAqIFZpc2l0cyBhbiB7QGNvZGUgSU5UfSBwcmltaXRpdmUgdHlwZSBieSBjYWxsaW5nCiAgICAgKiB7QGNvZGUgZGVmYXVsdEFjdGlvbn0uCiAgICAgKgogICAgICogQHBhcmFtIHQgdGhlIHR5cGUgdG8gdmlzaXQKICAgICAqIEBwYXJhbSBwIGEgdmlzaXRvci1zcGVjaWZpZWQgcGFyYW1ldGVyCiAgICAgKiBAcmV0dXJuICB0aGUgcmVzdWx0IG9mIHtAY29kZSBkZWZhdWx0QWN0aW9ufQogICAgICovCiAgICBwdWJsaWMgUiB2aXNpdFByaW1pdGl2ZUFzSW50KFByaW1pdGl2ZVR5cGUgdCwgUCBwKSB7CiAgICAgICAgcmV0dXJuIGRlZmF1bHRBY3Rpb24odCwgcCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBWaXNpdHMgYSB7QGNvZGUgTE9OR30gcHJpbWl0aXZlIHR5cGUgYnkgY2FsbGluZwogICAgICoge0Bjb2RlIGRlZmF1bHRBY3Rpb259LgogICAgICoKICAgICAqIEBwYXJhbSB0IHRoZSB0eXBlIHRvIHZpc2l0CiAgICAgKiBAcGFyYW0gcCBhIHZpc2l0b3Itc3BlY2lmaWVkIHBhcmFtZXRlcgogICAgICogQHJldHVybiAgdGhlIHJlc3VsdCBvZiB7QGNvZGUgZGVmYXVsdEFjdGlvbn0KICAgICAqLwogICAgcHVibGljIFIgdmlzaXRQcmltaXRpdmVBc0xvbmcoUHJpbWl0aXZlVHlwZSB0LCBQIHApIHsKICAgICAgICByZXR1cm4gZGVmYXVsdEFjdGlvbih0LCBwKTsKICAgIH0KCiAgICAvKioKICAgICAqIFZpc2l0cyBhIHtAY29kZSBDSEFSfSBwcmltaXRpdmUgdHlwZSBieSBjYWxsaW5nCiAgICAgKiB7QGNvZGUgZGVmYXVsdEFjdGlvbn0uCiAgICAgKgogICAgICogQHBhcmFtIHQgdGhlIHR5cGUgdG8gdmlzaXQKICAgICAqIEBwYXJhbSBwIGEgdmlzaXRvci1zcGVjaWZpZWQgcGFyYW1ldGVyCiAgICAgKiBAcmV0dXJuICB0aGUgcmVzdWx0IG9mIHtAY29kZSBkZWZhdWx0QWN0aW9ufQogICAgICovCiAgICBwdWJsaWMgUiB2aXNpdFByaW1pdGl2ZUFzQ2hhcihQcmltaXRpdmVUeXBlIHQsIFAgcCkgewogICAgICAgIHJldHVybiBkZWZhdWx0QWN0aW9uKHQsIHApOwogICAgfQoKICAgIC8qKgogICAgICogVmlzaXRzIGEge0Bjb2RlIEZMT0FUfSBwcmltaXRpdmUgdHlwZSBieSBjYWxsaW5nCiAgICAgKiB7QGNvZGUgZGVmYXVsdEFjdGlvbn0uCiAgICAgKgogICAgICogQHBhcmFtIHQgdGhlIHR5cGUgdG8gdmlzaXQKICAgICAqIEBwYXJhbSBwIGEgdmlzaXRvci1zcGVjaWZpZWQgcGFyYW1ldGVyCiAgICAgKiBAcmV0dXJuICB0aGUgcmVzdWx0IG9mIHtAY29kZSBkZWZhdWx0QWN0aW9ufQogICAgICovCiAgICBwdWJsaWMgUiB2aXNpdFByaW1pdGl2ZUFzRmxvYXQoUHJpbWl0aXZlVHlwZSB0LCBQIHApIHsKICAgICAgICByZXR1cm4gZGVmYXVsdEFjdGlvbih0LCBwKTsKICAgIH0KCiAgICAvKioKICAgICAqIFZpc2l0cyBhIHtAY29kZSBET1VCTEV9IHByaW1pdGl2ZSB0eXBlIGJ5IGNhbGxpbmcKICAgICAqIHtAY29kZSBkZWZhdWx0QWN0aW9ufS4KICAgICAqCiAgICAgKiBAcGFyYW0gdCB0aGUgdHlwZSB0byB2aXNpdAogICAgICogQHBhcmFtIHAgYSB2aXNpdG9yLXNwZWNpZmllZCBwYXJhbWV0ZXIKICAgICAqIEByZXR1cm4gIHRoZSByZXN1bHQgb2Yge0Bjb2RlIGRlZmF1bHRBY3Rpb259CiAgICAgKi8KICAgIHB1YmxpYyBSIHZpc2l0UHJpbWl0aXZlQXNEb3VibGUoUHJpbWl0aXZlVHlwZSB0LCBQIHApIHsKICAgICAgICByZXR1cm4gZGVmYXVsdEFjdGlvbih0LCBwKTsKICAgIH0KCiAgICAvKioKICAgICAqIFZpc2l0cyBhIHtAbGluayBOb1R5cGV9IGluc3RhbmNlLCBkaXNwYXRjaGluZyB0byB0aGUgdmlzaXQgbWV0aG9kIGZvcgogICAgICogdGhlIHNwZWNpZmljIHtAbGlua3BsYWluIFR5cGVLaW5kIGtpbmR9IG9mIHBzZXVkby10eXBlOgogICAgICoge0Bjb2RlIFZPSUR9LCB7QGNvZGUgUEFDS0FHRX0sIG9yIHtAY29kZSBOT05FfS4KICAgICAqCiAgICAgKiBAcGFyYW0gdCB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuICB0aGUgcmVzdWx0IG9mIHRoZSBraW5kLXNwZWNpZmljIHZpc2l0IG1ldGhvZAogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0Tm9UeXBlKE5vVHlwZSB0LCBQIHApIHsKICAgICAgICBUeXBlS2luZCBrID0gdC5nZXRLaW5kKCk7CiAgICAgICAgc3dpdGNoIChrKSB7CiAgICAgICAgY2FzZSBWT0lEOgogICAgICAgICAgICByZXR1cm4gdmlzaXROb1R5cGVBc1ZvaWQodCwgcCk7CgogICAgICAgIGNhc2UgUEFDS0FHRToKICAgICAgICAgICAgcmV0dXJuIHZpc2l0Tm9UeXBlQXNQYWNrYWdlKHQsIHApOwoKICAgICAgICBjYXNlIE5PTkU6CiAgICAgICAgICAgIHJldHVybiB2aXNpdE5vVHlwZUFzTm9uZSh0LCBwKTsKCiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCJCYWQga2luZCAiICsgayArICIgZm9yIE5vVHlwZSIgKyB0KTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBWaXNpdHMgYSB7QGxpbmsgVHlwZUtpbmQjVk9JRCBWT0lEfSBwc2V1ZG8tdHlwZSBieSBjYWxsaW5nCiAgICAgKiB7QGNvZGUgZGVmYXVsdEFjdGlvbn0uCiAgICAgKgogICAgICogQHBhcmFtIHQgdGhlIHR5cGUgdG8gdmlzaXQKICAgICAqIEBwYXJhbSBwIGEgdmlzaXRvci1zcGVjaWZpZWQgcGFyYW1ldGVyCiAgICAgKiBAcmV0dXJuICB0aGUgcmVzdWx0IG9mIHtAY29kZSBkZWZhdWx0QWN0aW9ufQogICAgICovCiAgICBwdWJsaWMgUiB2aXNpdE5vVHlwZUFzVm9pZChOb1R5cGUgdCwgUCBwKSB7CiAgICAgICAgcmV0dXJuIGRlZmF1bHRBY3Rpb24odCwgcCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBWaXNpdHMgYSB7QGxpbmsgVHlwZUtpbmQjUEFDS0FHRSBQQUNLQUdFfSBwc2V1ZG8tdHlwZSBieSBjYWxsaW5nCiAgICAgKiB7QGNvZGUgZGVmYXVsdEFjdGlvbn0uCiAgICAgKgogICAgICogQHBhcmFtIHQgdGhlIHR5cGUgdG8gdmlzaXQKICAgICAqIEBwYXJhbSBwIGEgdmlzaXRvci1zcGVjaWZpZWQgcGFyYW1ldGVyCiAgICAgKiBAcmV0dXJuICB0aGUgcmVzdWx0IG9mIHtAY29kZSBkZWZhdWx0QWN0aW9ufQogICAgICovCiAgICBwdWJsaWMgUiB2aXNpdE5vVHlwZUFzUGFja2FnZShOb1R5cGUgdCwgUCBwKSB7CiAgICAgICAgcmV0dXJuIGRlZmF1bHRBY3Rpb24odCwgcCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBWaXNpdHMgYSB7QGxpbmsgVHlwZUtpbmQjTk9ORSBOT05FfSBwc2V1ZG8tdHlwZSBieSBjYWxsaW5nCiAgICAgKiB7QGNvZGUgZGVmYXVsdEFjdGlvbn0uCiAgICAgKgogICAgICogQHBhcmFtIHQgdGhlIHR5cGUgdG8gdmlzaXQKICAgICAqIEBwYXJhbSBwIGEgdmlzaXRvci1zcGVjaWZpZWQgcGFyYW1ldGVyCiAgICAgKiBAcmV0dXJuICB0aGUgcmVzdWx0IG9mIHtAY29kZSBkZWZhdWx0QWN0aW9ufQogICAgICovCiAgICBwdWJsaWMgUiB2aXNpdE5vVHlwZUFzTm9uZShOb1R5cGUgdCwgUCBwKSB7CiAgICAgICAgcmV0dXJuIGRlZmF1bHRBY3Rpb24odCwgcCk7CiAgICB9Cn0KUEsDBAoAAAgAAAY7qUrKpsuk1AwAANQMAAAyAAAAamF2YXgvbGFuZy9tb2RlbC91dGlsL0Fic3RyYWN0RWxlbWVudFZpc2l0b3I3LmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTAsIDIwMTcsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgamF2YXgubGFuZy5tb2RlbC51dGlsOwoKaW1wb3J0IGphdmF4LmFubm90YXRpb24ucHJvY2Vzc2luZy5TdXBwb3J0ZWRTb3VyY2VWZXJzaW9uOwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5Tb3VyY2VWZXJzaW9uOwppbXBvcnQgc3RhdGljIGphdmF4LmxhbmcubW9kZWwuU291cmNlVmVyc2lvbi4qOwoKCi8qKgogKiBBIHNrZWxldGFsIHZpc2l0b3Igb2YgcHJvZ3JhbSBlbGVtZW50cyB3aXRoIGRlZmF1bHQgYmVoYXZpb3IKICogYXBwcm9wcmlhdGUgZm9yIHRoZSB7QGxpbmsgU291cmNlVmVyc2lvbiNSRUxFQVNFXzcgUkVMRUFTRV83fQogKiBzb3VyY2UgdmVyc2lvbi4KICoKICogPHA+IDxiPldBUk5JTkc6PC9iPiBUaGUge0Bjb2RlIEVsZW1lbnRWaXNpdG9yfSBpbnRlcmZhY2UKICogaW1wbGVtZW50ZWQgYnkgdGhpcyBjbGFzcyBtYXkgaGF2ZSBtZXRob2RzIGFkZGVkIHRvIGl0IGluIHRoZQogKiBmdXR1cmUgdG8gYWNjb21tb2RhdGUgbmV3LCBjdXJyZW50bHkgdW5rbm93biwgbGFuZ3VhZ2Ugc3RydWN0dXJlcwogKiBhZGRlZCB0byBmdXR1cmUgdmVyc2lvbnMgb2YgdGhlIEphdmEmdHJhZGU7IHByb2dyYW1taW5nIGxhbmd1YWdlLgogKiBUaGVyZWZvcmUsIG1ldGhvZHMgd2hvc2UgbmFtZXMgYmVnaW4gd2l0aCB7QGNvZGUgInZpc2l0In0gbWF5IGJlCiAqIGFkZGVkIHRvIHRoaXMgY2xhc3MgaW4gdGhlIGZ1dHVyZTsgdG8gYXZvaWQgaW5jb21wYXRpYmlsaXRpZXMsCiAqIGNsYXNzZXMgd2hpY2ggZXh0ZW5kIHRoaXMgY2xhc3Mgc2hvdWxkIG5vdCBkZWNsYXJlIGFueSBpbnN0YW5jZQogKiBtZXRob2RzIHdpdGggbmFtZXMgYmVnaW5uaW5nIHdpdGgge0Bjb2RlICJ2aXNpdCJ9LgogKgogKiA8cD5XaGVuIHN1Y2ggYSBuZXcgdmlzaXQgbWV0aG9kIGlzIGFkZGVkLCB0aGUgZGVmYXVsdAogKiBpbXBsZW1lbnRhdGlvbiBpbiB0aGlzIGNsYXNzIHdpbGwgYmUgdG8gY2FsbCB0aGUge0BsaW5rCiAqICN2aXNpdFVua25vd24gdmlzaXRVbmtub3dufSBtZXRob2QuICBBIG5ldyBhYnN0cmFjdCBlbGVtZW50IHZpc2l0b3IKICogY2xhc3Mgd2lsbCBhbHNvIGJlIGludHJvZHVjZWQgdG8gY29ycmVzcG9uZCB0byB0aGUgbmV3IGxhbmd1YWdlCiAqIGxldmVsOyB0aGlzIHZpc2l0b3Igd2lsbCBoYXZlIGRpZmZlcmVudCBkZWZhdWx0IGJlaGF2aW9yIGZvciB0aGUKICogdmlzaXQgbWV0aG9kIGluIHF1ZXN0aW9uLiAgV2hlbiB0aGUgbmV3IHZpc2l0b3IgaXMgaW50cm9kdWNlZCwgYWxsCiAqIG9yIHBvcnRpb25zIG9mIHRoaXMgdmlzaXRvciBtYXkgYmUgZGVwcmVjYXRlZC4KICoKICogQHBhcmFtIDxSPiB0aGUgcmV0dXJuIHR5cGUgb2YgdGhpcyB2aXNpdG9yJ3MgbWV0aG9kcy4gIFVzZSB7QGxpbmsKICogICAgICAgICAgICBWb2lkfSBmb3IgdmlzaXRvcnMgdGhhdCBkbyBub3QgbmVlZCB0byByZXR1cm4gcmVzdWx0cy4KICogQHBhcmFtIDxQPiB0aGUgdHlwZSBvZiB0aGUgYWRkaXRpb25hbCBwYXJhbWV0ZXIgdG8gdGhpcyB2aXNpdG9yJ3MKICogICAgICAgICAgICBtZXRob2RzLiAgVXNlIHtAY29kZSBWb2lkfSBmb3IgdmlzaXRvcnMgdGhhdCBkbyBub3QgbmVlZCBhbgogKiAgICAgICAgICAgIGFkZGl0aW9uYWwgcGFyYW1ldGVyLgogKgogKiBAc2VlIEFic3RyYWN0RWxlbWVudFZpc2l0b3I2CiAqIEBzZWUgQWJzdHJhY3RFbGVtZW50VmlzaXRvcjgKICogQHNlZSBBYnN0cmFjdEVsZW1lbnRWaXNpdG9yOQogKiBAc2luY2UgMS43CiAqLwpAU3VwcG9ydGVkU291cmNlVmVyc2lvbihSRUxFQVNFXzcpCnB1YmxpYyBhYnN0cmFjdCBjbGFzcyBBYnN0cmFjdEVsZW1lbnRWaXNpdG9yNzxSLCBQPiBleHRlbmRzIEFic3RyYWN0RWxlbWVudFZpc2l0b3I2PFIsIFA+IHsKICAgIC8qKgogICAgICogQ29uc3RydWN0b3IgZm9yIGNvbmNyZXRlIHN1YmNsYXNzZXMgdG8gY2FsbC4KICAgICAqLwogICAgQFN1cHByZXNzV2FybmluZ3MoImRlcHJlY2F0aW9uIikgLy8gU3VwZXJjbGFzcyBjb25zdHJ1Y3RvciBkZXByZWNhdGVkCiAgICBwcm90ZWN0ZWQgQWJzdHJhY3RFbGVtZW50VmlzaXRvcjcoKXsKICAgICAgICBzdXBlcigpOwogICAgfQp9ClBLAwQKAAAIAAAGO6lKZyP0Tb0TAAC9EwAAKgAAAGphdmF4L2xhbmcvbW9kZWwvdXRpbC9FbGVtZW50U2Nhbm5lcjguamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAxMSwgMjAxNywgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBqYXZheC5sYW5nLm1vZGVsLnV0aWw7CgppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5lbGVtZW50Lio7CmltcG9ydCBqYXZheC5hbm5vdGF0aW9uLnByb2Nlc3NpbmcuU3VwcG9ydGVkU291cmNlVmVyc2lvbjsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuU291cmNlVmVyc2lvbjsKaW1wb3J0IHN0YXRpYyBqYXZheC5sYW5nLm1vZGVsLlNvdXJjZVZlcnNpb24uKjsKCgovKioKICogQSBzY2FubmluZyB2aXNpdG9yIG9mIHByb2dyYW0gZWxlbWVudHMgd2l0aCBkZWZhdWx0IGJlaGF2aW9yCiAqIGFwcHJvcHJpYXRlIGZvciB0aGUge0BsaW5rIFNvdXJjZVZlcnNpb24jUkVMRUFTRV84IFJFTEVBU0VfOH0KICogc291cmNlIHZlcnNpb24uICBUaGUgPGNvZGU+dmlzaXQ8aT5YeXo8L2k+PC9jb2RlPiBtZXRob2RzIGluIHRoaXMKICogY2xhc3Mgc2NhbiB0aGVpciBjb21wb25lbnQgZWxlbWVudHMgYnkgY2FsbGluZyB7QGNvZGUgc2Nhbn0gb24KICogdGhlaXIge0BsaW5rcGxhaW4gRWxlbWVudCNnZXRFbmNsb3NlZEVsZW1lbnRzIGVuY2xvc2VkIGVsZW1lbnRzfSwKICoge0BsaW5rcGxhaW4gRXhlY3V0YWJsZUVsZW1lbnQjZ2V0UGFyYW1ldGVycyBwYXJhbWV0ZXJzfSwgZXRjLiwgYXMKICogaW5kaWNhdGVkIGluIHRoZSBpbmRpdmlkdWFsIG1ldGhvZCBzcGVjaWZpY2F0aW9ucy4gIEEgc3ViY2xhc3MgY2FuCiAqIGNvbnRyb2wgdGhlIG9yZGVyIGVsZW1lbnRzIGFyZSB2aXNpdGVkIGJ5IG92ZXJyaWRpbmcgdGhlCiAqIDxjb2RlPnZpc2l0PGk+WHl6PC9pPjwvY29kZT4gbWV0aG9kcy4gIE5vdGUgdGhhdCBjbGllbnRzIG9mIGEgc2Nhbm5lcgogKiBtYXkgZ2V0IHRoZSBkZXNpcmVkIGJlaGF2aW9yIGJlIGludm9raW5nIHtAY29kZSB2LnNjYW4oZSwgcCl9IHJhdGhlcgogKiB0aGFuIHtAY29kZSB2LnZpc2l0KGUsIHApfSBvbiB0aGUgcm9vdCBvYmplY3RzIG9mIGludGVyZXN0LgogKgogKiA8cD5XaGVuIGEgc3ViY2xhc3Mgb3ZlcnJpZGVzIGEgPGNvZGU+dmlzaXQ8aT5YeXo8L2k+PC9jb2RlPiBtZXRob2QsIHRoZQogKiBuZXcgbWV0aG9kIGNhbiBjYXVzZSB0aGUgZW5jbG9zZWQgZWxlbWVudHMgdG8gYmUgc2Nhbm5lZCBpbiB0aGUKICogZGVmYXVsdCB3YXkgYnkgY2FsbGluZyA8Y29kZT5zdXBlci52aXNpdDxpPlh5ejwvaT48L2NvZGU+LiAgSW4gdGhpcwogKiBmYXNoaW9uLCB0aGUgY29uY3JldGUgdmlzaXRvciBjYW4gY29udHJvbCB0aGUgb3JkZXJpbmcgb2YgdHJhdmVyc2FsCiAqIG92ZXIgdGhlIGNvbXBvbmVudCBlbGVtZW50cyB3aXRoIHJlc3BlY3QgdG8gdGhlIGFkZGl0aW9uYWwKICogcHJvY2Vzc2luZzsgZm9yIGV4YW1wbGUsIGNvbnNpc3RlbnRseSBjYWxsaW5nCiAqIDxjb2RlPnN1cGVyLnZpc2l0PGk+WHl6PC9pPjwvY29kZT4gYXQgdGhlIHN0YXJ0IG9mIHRoZSBvdmVycmlkZGVuCiAqIG1ldGhvZHMgd2lsbCB5aWVsZCBhIHByZW9yZGVyIHRyYXZlcnNhbCwgZXRjLiAgSWYgdGhlIGNvbXBvbmVudAogKiBlbGVtZW50cyBzaG91bGQgYmUgdHJhdmVyc2VkIGluIHNvbWUgb3RoZXIgb3JkZXIsIGluc3RlYWQgb2YKICogY2FsbGluZyA8Y29kZT5zdXBlci52aXNpdDxpPlh5ejwvaT48L2NvZGU+LCBhbiBvdmVycmlkaW5nIHZpc2l0IG1ldGhvZAogKiBzaG91bGQgY2FsbCB7QGNvZGUgc2Nhbn0gd2l0aCB0aGUgZWxlbWVudHMgaW4gdGhlIGRlc2lyZWQgb3JkZXIuCiAqCiAqIDxwPiBNZXRob2RzIGluIHRoaXMgY2xhc3MgbWF5IGJlIG92ZXJyaWRkZW4gc3ViamVjdCB0byB0aGVpcgogKiBnZW5lcmFsIGNvbnRyYWN0LiAgTm90ZSB0aGF0IGFubm90YXRpbmcgbWV0aG9kcyBpbiBjb25jcmV0ZQogKiBzdWJjbGFzc2VzIHdpdGgge0BsaW5rIGphdmEubGFuZy5PdmVycmlkZSBAT3ZlcnJpZGV9IHdpbGwgaGVscAogKiBlbnN1cmUgdGhhdCBtZXRob2RzIGFyZSBvdmVycmlkZGVuIGFzIGludGVuZGVkLgogKgogKiA8cD4gPGI+V0FSTklORzo8L2I+IFRoZSB7QGNvZGUgRWxlbWVudFZpc2l0b3J9IGludGVyZmFjZQogKiBpbXBsZW1lbnRlZCBieSB0aGlzIGNsYXNzIG1heSBoYXZlIG1ldGhvZHMgYWRkZWQgdG8gaXQgaW4gdGhlCiAqIGZ1dHVyZSB0byBhY2NvbW1vZGF0ZSBuZXcsIGN1cnJlbnRseSB1bmtub3duLCBsYW5ndWFnZSBzdHJ1Y3R1cmVzCiAqIGFkZGVkIHRvIGZ1dHVyZSB2ZXJzaW9ucyBvZiB0aGUgSmF2YSZ0cmFkZTsgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2UuCiAqIFRoZXJlZm9yZSwgbWV0aG9kcyB3aG9zZSBuYW1lcyBiZWdpbiB3aXRoIHtAY29kZSAidmlzaXQifSBtYXkgYmUKICogYWRkZWQgdG8gdGhpcyBjbGFzcyBpbiB0aGUgZnV0dXJlOyB0byBhdm9pZCBpbmNvbXBhdGliaWxpdGllcywKICogY2xhc3NlcyB3aGljaCBleHRlbmQgdGhpcyBjbGFzcyBzaG91bGQgbm90IGRlY2xhcmUgYW55IGluc3RhbmNlCiAqIG1ldGhvZHMgd2l0aCBuYW1lcyBiZWdpbm5pbmcgd2l0aCB7QGNvZGUgInZpc2l0In0uCiAqCiAqIDxwPldoZW4gc3VjaCBhIG5ldyB2aXNpdCBtZXRob2QgaXMgYWRkZWQsIHRoZSBkZWZhdWx0CiAqIGltcGxlbWVudGF0aW9uIGluIHRoaXMgY2xhc3Mgd2lsbCBiZSB0byBjYWxsIHRoZSB7QGxpbmsKICogI3Zpc2l0VW5rbm93biB2aXNpdFVua25vd259IG1ldGhvZC4gIEEgbmV3IGVsZW1lbnQgc2Nhbm5lciB2aXNpdG9yCiAqIGNsYXNzIHdpbGwgYWxzbyBiZSBpbnRyb2R1Y2VkIHRvIGNvcnJlc3BvbmQgdG8gdGhlIG5ldyBsYW5ndWFnZQogKiBsZXZlbDsgdGhpcyB2aXNpdG9yIHdpbGwgaGF2ZSBkaWZmZXJlbnQgZGVmYXVsdCBiZWhhdmlvciBmb3IgdGhlCiAqIHZpc2l0IG1ldGhvZCBpbiBxdWVzdGlvbi4gIFdoZW4gdGhlIG5ldyB2aXNpdG9yIGlzIGludHJvZHVjZWQsIGFsbAogKiBvciBwb3J0aW9ucyBvZiB0aGlzIHZpc2l0b3IgbWF5IGJlIGRlcHJlY2F0ZWQuCiAqCiAqIEBwYXJhbSA8Uj4gdGhlIHJldHVybiB0eXBlIG9mIHRoaXMgdmlzaXRvcidzIG1ldGhvZHMuICBVc2Uge0BsaW5rCiAqICAgICAgICAgICAgVm9pZH0gZm9yIHZpc2l0b3JzIHRoYXQgZG8gbm90IG5lZWQgdG8gcmV0dXJuIHJlc3VsdHMuCiAqIEBwYXJhbSA8UD4gdGhlIHR5cGUgb2YgdGhlIGFkZGl0aW9uYWwgcGFyYW1ldGVyIHRvIHRoaXMgdmlzaXRvcidzCiAqICAgICAgICAgICAgbWV0aG9kcy4gIFVzZSB7QGNvZGUgVm9pZH0gZm9yIHZpc2l0b3JzIHRoYXQgZG8gbm90IG5lZWQgYW4KICogICAgICAgICAgICBhZGRpdGlvbmFsIHBhcmFtZXRlci4KICoKICogQHNlZSBFbGVtZW50U2Nhbm5lcjYKICogQHNlZSBFbGVtZW50U2Nhbm5lcjcKICogQHNlZSBFbGVtZW50U2Nhbm5lcjkKICogQHNpbmNlIDEuOAogKi8KQFN1cHBvcnRlZFNvdXJjZVZlcnNpb24oUkVMRUFTRV84KQpwdWJsaWMgY2xhc3MgRWxlbWVudFNjYW5uZXI4PFIsIFA+IGV4dGVuZHMgRWxlbWVudFNjYW5uZXI3PFIsIFA+IHsKICAgIC8qKgogICAgICogQ29uc3RydWN0b3IgZm9yIGNvbmNyZXRlIHN1YmNsYXNzZXM7IHVzZXMge0Bjb2RlIG51bGx9IGZvciB0aGUKICAgICAqIGRlZmF1bHQgdmFsdWUuCiAgICAgKi8KICAgIHByb3RlY3RlZCBFbGVtZW50U2Nhbm5lcjgoKXsKICAgICAgICBzdXBlcihudWxsKTsKICAgIH0KCiAgICAvKioKICAgICAqIENvbnN0cnVjdG9yIGZvciBjb25jcmV0ZSBzdWJjbGFzc2VzOyB1c2VzIHRoZSBhcmd1bWVudCBmb3IgdGhlCiAgICAgKiBkZWZhdWx0IHZhbHVlLgogICAgICoKICAgICAqIEBwYXJhbSBkZWZhdWx0VmFsdWUgdGhlIGRlZmF1bHQgdmFsdWUKICAgICAqLwogICAgcHJvdGVjdGVkIEVsZW1lbnRTY2FubmVyOChSIGRlZmF1bHRWYWx1ZSl7CiAgICAgICAgc3VwZXIoZGVmYXVsdFZhbHVlKTsKICAgIH0KfQpQSwMECgAACAAABjupSvcUmOdxEgAAcRIAAC4AAABqYXZheC9sYW5nL21vZGVsL3V0aWwvRWxlbWVudEtpbmRWaXNpdG9yOS5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDExLCAyMDE3LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGphdmF4LmxhbmcubW9kZWwudXRpbDsKCmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuKjsKaW1wb3J0IGphdmF4LmFubm90YXRpb24ucHJvY2Vzc2luZy5TdXBwb3J0ZWRTb3VyY2VWZXJzaW9uOwppbXBvcnQgc3RhdGljIGphdmF4LmxhbmcubW9kZWwuU291cmNlVmVyc2lvbi4qOwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5Tb3VyY2VWZXJzaW9uOwoKLyoqCiAqIEEgdmlzaXRvciBvZiBwcm9ncmFtIGVsZW1lbnRzIGJhc2VkIG9uIHRoZWlyIHtAbGlua3BsYWluCiAqIEVsZW1lbnRLaW5kIGtpbmR9IHdpdGggZGVmYXVsdCBiZWhhdmlvciBhcHByb3ByaWF0ZSBmb3IgdGhlIHtAbGluawogKiBTb3VyY2VWZXJzaW9uI1JFTEVBU0VfOSBSRUxFQVNFXzl9IHNvdXJjZSB2ZXJzaW9uLiAgRm9yIHtAbGlua3BsYWluCiAqIEVsZW1lbnQgZWxlbWVudHN9IDxjb2RlPjxpPlh5ejwvaT48L2NvZGU+IHRoYXQgbWF5IGhhdmUgbW9yZSB0aGFuIG9uZQogKiBraW5kLCB0aGUgPGNvZGU+dmlzaXQ8aT5YeXo8L2k+PC9jb2RlPiBtZXRob2RzIGluIHRoaXMgY2xhc3MgZGVsZWdhdGUKICogdG8gdGhlIDxjb2RlPnZpc2l0PGk+WHl6PC9pPkFzPGk+S2luZDwvaT48L2NvZGU+IG1ldGhvZCBjb3JyZXNwb25kaW5nIHRvIHRoZQogKiBmaXJzdCBhcmd1bWVudCdzIGtpbmQuICBUaGUgPGNvZGU+dmlzaXQ8aT5YeXo8L2k+QXM8aT5LaW5kPC9pPjwvY29kZT4gbWV0aG9kcwogKiBjYWxsIHtAbGluayAjZGVmYXVsdEFjdGlvbiBkZWZhdWx0QWN0aW9ufSwgcGFzc2luZyB0aGVpciBhcmd1bWVudHMKICogdG8ge0Bjb2RlIGRlZmF1bHRBY3Rpb259J3MgY29ycmVzcG9uZGluZyBwYXJhbWV0ZXJzLgogKgogKiA8cD4gTWV0aG9kcyBpbiB0aGlzIGNsYXNzIG1heSBiZSBvdmVycmlkZGVuIHN1YmplY3QgdG8gdGhlaXIKICogZ2VuZXJhbCBjb250cmFjdC4gIE5vdGUgdGhhdCBhbm5vdGF0aW5nIG1ldGhvZHMgaW4gY29uY3JldGUKICogc3ViY2xhc3NlcyB3aXRoIHtAbGluayBqYXZhLmxhbmcuT3ZlcnJpZGUgQE92ZXJyaWRlfSB3aWxsIGhlbHAKICogZW5zdXJlIHRoYXQgbWV0aG9kcyBhcmUgb3ZlcnJpZGRlbiBhcyBpbnRlbmRlZC4KICoKICogPHA+IDxiPldBUk5JTkc6PC9iPiBUaGUge0Bjb2RlIEVsZW1lbnRWaXNpdG9yfSBpbnRlcmZhY2UKICogaW1wbGVtZW50ZWQgYnkgdGhpcyBjbGFzcyBtYXkgaGF2ZSBtZXRob2RzIGFkZGVkIHRvIGl0IG9yIHRoZQogKiB7QGNvZGUgRWxlbWVudEtpbmR9IHtAY29kZSBlbnVtfSB1c2VkIGluIHRoaXMgY2FzZSBtYXkgaGF2ZQogKiBjb25zdGFudHMgYWRkZWQgdG8gaXQgaW4gdGhlIGZ1dHVyZSB0byBhY2NvbW1vZGF0ZSBuZXcsIGN1cnJlbnRseQogKiB1bmtub3duLCBsYW5ndWFnZSBzdHJ1Y3R1cmVzIGFkZGVkIHRvIGZ1dHVyZSB2ZXJzaW9ucyBvZiB0aGUKICogSmF2YSZ0cmFkZTsgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2UuICBUaGVyZWZvcmUsIG1ldGhvZHMgd2hvc2UgbmFtZXMKICogYmVnaW4gd2l0aCB7QGNvZGUgInZpc2l0In0gbWF5IGJlIGFkZGVkIHRvIHRoaXMgY2xhc3MgaW4gdGhlCiAqIGZ1dHVyZTsgdG8gYXZvaWQgaW5jb21wYXRpYmlsaXRpZXMsIGNsYXNzZXMgd2hpY2ggZXh0ZW5kIHRoaXMgY2xhc3MKICogc2hvdWxkIG5vdCBkZWNsYXJlIGFueSBpbnN0YW5jZSBtZXRob2RzIHdpdGggbmFtZXMgYmVnaW5uaW5nIHdpdGgKICoge0Bjb2RlICJ2aXNpdCJ9LgogKgogKiA8cD5XaGVuIHN1Y2ggYSBuZXcgdmlzaXQgbWV0aG9kIGlzIGFkZGVkLCB0aGUgZGVmYXVsdAogKiBpbXBsZW1lbnRhdGlvbiBpbiB0aGlzIGNsYXNzIHdpbGwgYmUgdG8gY2FsbCB0aGUge0BsaW5rCiAqICN2aXNpdFVua25vd24gdmlzaXRVbmtub3dufSBtZXRob2QuICBBIG5ldyBhYnN0cmFjdCBlbGVtZW50IGtpbmQKICogdmlzaXRvciBjbGFzcyB3aWxsIGFsc28gYmUgaW50cm9kdWNlZCB0byBjb3JyZXNwb25kIHRvIHRoZSBuZXcKICogbGFuZ3VhZ2UgbGV2ZWw7IHRoaXMgdmlzaXRvciB3aWxsIGhhdmUgZGlmZmVyZW50IGRlZmF1bHQgYmVoYXZpb3IKICogZm9yIHRoZSB2aXNpdCBtZXRob2QgaW4gcXVlc3Rpb24uICBXaGVuIHRoZSBuZXcgdmlzaXRvciBpcwogKiBpbnRyb2R1Y2VkLCBhbGwgb3IgcG9ydGlvbnMgb2YgdGhpcyB2aXNpdG9yIG1heSBiZSBkZXByZWNhdGVkLgogKgogKiBAcGFyYW0gPFI+IHRoZSByZXR1cm4gdHlwZSBvZiB0aGlzIHZpc2l0b3IncyBtZXRob2RzLiAgVXNlIHtAbGluawogKiAgICAgICAgICAgIFZvaWR9IGZvciB2aXNpdG9ycyB0aGF0IGRvIG5vdCBuZWVkIHRvIHJldHVybiByZXN1bHRzLgogKiBAcGFyYW0gPFA+IHRoZSB0eXBlIG9mIHRoZSBhZGRpdGlvbmFsIHBhcmFtZXRlciB0byB0aGlzIHZpc2l0b3IncwogKiAgICAgICAgICAgIG1ldGhvZHMuICBVc2Uge0Bjb2RlIFZvaWR9IGZvciB2aXNpdG9ycyB0aGF0IGRvIG5vdCBuZWVkIGFuCiAqICAgICAgICAgICAgYWRkaXRpb25hbCBwYXJhbWV0ZXIuCiAqCiAqIEBzZWUgRWxlbWVudEtpbmRWaXNpdG9yNgogKiBAc2VlIEVsZW1lbnRLaW5kVmlzaXRvcjcKICogQHNlZSBFbGVtZW50S2luZFZpc2l0b3I4CiAqIEBzaW5jZSA5CiAqIEBzcGVjIEpQTVMKICovCkBTdXBwb3J0ZWRTb3VyY2VWZXJzaW9uKFJFTEVBU0VfOSkKcHVibGljIGNsYXNzIEVsZW1lbnRLaW5kVmlzaXRvcjk8UiwgUD4gZXh0ZW5kcyBFbGVtZW50S2luZFZpc2l0b3I4PFIsIFA+IHsKICAgIC8qKgogICAgICogQ29uc3RydWN0b3IgZm9yIGNvbmNyZXRlIHN1YmNsYXNzZXM7IHVzZXMge0Bjb2RlIG51bGx9IGZvciB0aGUKICAgICAqIGRlZmF1bHQgdmFsdWUuCiAgICAgKi8KICAgIHByb3RlY3RlZCBFbGVtZW50S2luZFZpc2l0b3I5KCkgewogICAgICAgIHN1cGVyKG51bGwpOwogICAgfQoKICAgIC8qKgogICAgICogQ29uc3RydWN0b3IgZm9yIGNvbmNyZXRlIHN1YmNsYXNzZXM7IHVzZXMgdGhlIGFyZ3VtZW50IGZvciB0aGUKICAgICAqIGRlZmF1bHQgdmFsdWUuCiAgICAgKgogICAgICogQHBhcmFtIGRlZmF1bHRWYWx1ZSB0aGUgdmFsdWUgdG8gYXNzaWduIHRvIHtAbGluayAjREVGQVVMVF9WQUxVRX0KICAgICAqLwogICAgcHJvdGVjdGVkIEVsZW1lbnRLaW5kVmlzaXRvcjkoUiBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBzdXBlcihkZWZhdWx0VmFsdWUpOwogICAgfQoKICAgIC8qKgogICAgICogVmlzaXRzIGEge0Bjb2RlIE1vZHVsZUVsZW1lbnR9IGJ5IGNhbGxpbmcge0Bjb2RlCiAgICAgKiBkZWZhdWx0QWN0aW9ufS4KICAgICAqCiAgICAgKiBAcGFyYW0gZSB0aGUgZWxlbWVudCB0byB2aXNpdAogICAgICogQHBhcmFtIHAgYSB2aXNpdG9yLXNwZWNpZmllZCBwYXJhbWV0ZXIKICAgICAqIEByZXR1cm4gIHRoZSByZXN1bHQgb2Yge0Bjb2RlIGRlZmF1bHRBY3Rpb259CiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRNb2R1bGUoTW9kdWxlRWxlbWVudCBlLCBQIHApIHsKICAgICAgICByZXR1cm4gZGVmYXVsdEFjdGlvbihlLCBwKTsKICAgIH0KfQpQSwMECgAACAAABjupSipRrxgNEwAADRMAAC4AAABqYXZheC9sYW5nL21vZGVsL3V0aWwvRWxlbWVudEtpbmRWaXNpdG9yNy5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDEwLCAyMDE3LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGphdmF4LmxhbmcubW9kZWwudXRpbDsKCmltcG9ydCBqYXZheC5hbm5vdGF0aW9uLnByb2Nlc3NpbmcuU3VwcG9ydGVkU291cmNlVmVyc2lvbjsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuU291cmNlVmVyc2lvbjsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC4qOwppbXBvcnQgc3RhdGljIGphdmF4LmxhbmcubW9kZWwuU291cmNlVmVyc2lvbi4qOwoKLyoqCiAqIEEgdmlzaXRvciBvZiBwcm9ncmFtIGVsZW1lbnRzIGJhc2VkIG9uIHRoZWlyIHtAbGlua3BsYWluCiAqIEVsZW1lbnRLaW5kIGtpbmR9IHdpdGggZGVmYXVsdCBiZWhhdmlvciBhcHByb3ByaWF0ZSBmb3IgdGhlIHtAbGluawogKiBTb3VyY2VWZXJzaW9uI1JFTEVBU0VfNyBSRUxFQVNFXzd9IHNvdXJjZSB2ZXJzaW9uLiAgRm9yIHtAbGlua3BsYWluCiAqIEVsZW1lbnQgZWxlbWVudHN9IDxjb2RlPjxpPlh5ejwvaT48L2NvZGU+IHRoYXQgbWF5IGhhdmUgbW9yZSB0aGFuIG9uZQogKiBraW5kLCB0aGUgPGNvZGU+dmlzaXQ8aT5YeXo8L2k+PC9jb2RlPiBtZXRob2RzIGluIHRoaXMgY2xhc3MgZGVsZWdhdGUKICogdG8gdGhlIDxjb2RlPnZpc2l0PGk+WHl6PC9pPkFzPGk+S2luZDwvaT48L2NvZGU+IG1ldGhvZCBjb3JyZXNwb25kaW5nIHRvIHRoZQogKiBmaXJzdCBhcmd1bWVudCdzIGtpbmQuICBUaGUgPGNvZGU+dmlzaXQ8aT5YeXo8L2k+QXM8aT5LaW5kPC9pPjwvY29kZT4gbWV0aG9kcwogKiBjYWxsIHtAbGluayAjZGVmYXVsdEFjdGlvbiBkZWZhdWx0QWN0aW9ufSwgcGFzc2luZyB0aGVpciBhcmd1bWVudHMKICogdG8ge0Bjb2RlIGRlZmF1bHRBY3Rpb259J3MgY29ycmVzcG9uZGluZyBwYXJhbWV0ZXJzLgogKgogKiA8cD4gTWV0aG9kcyBpbiB0aGlzIGNsYXNzIG1heSBiZSBvdmVycmlkZGVuIHN1YmplY3QgdG8gdGhlaXIKICogZ2VuZXJhbCBjb250cmFjdC4gIE5vdGUgdGhhdCBhbm5vdGF0aW5nIG1ldGhvZHMgaW4gY29uY3JldGUKICogc3ViY2xhc3NlcyB3aXRoIHtAbGluayBqYXZhLmxhbmcuT3ZlcnJpZGUgQE92ZXJyaWRlfSB3aWxsIGhlbHAKICogZW5zdXJlIHRoYXQgbWV0aG9kcyBhcmUgb3ZlcnJpZGRlbiBhcyBpbnRlbmRlZC4KICoKICogPHA+IDxiPldBUk5JTkc6PC9iPiBUaGUge0Bjb2RlIEVsZW1lbnRWaXNpdG9yfSBpbnRlcmZhY2UKICogaW1wbGVtZW50ZWQgYnkgdGhpcyBjbGFzcyBtYXkgaGF2ZSBtZXRob2RzIGFkZGVkIHRvIGl0IG9yIHRoZQogKiB7QGNvZGUgRWxlbWVudEtpbmR9IHtAY29kZSBlbnVtfSB1c2VkIGluIHRoaXMgY2FzZSBtYXkgaGF2ZQogKiBjb25zdGFudHMgYWRkZWQgdG8gaXQgaW4gdGhlIGZ1dHVyZSB0byBhY2NvbW1vZGF0ZSBuZXcsIGN1cnJlbnRseQogKiB1bmtub3duLCBsYW5ndWFnZSBzdHJ1Y3R1cmVzIGFkZGVkIHRvIGZ1dHVyZSB2ZXJzaW9ucyBvZiB0aGUKICogSmF2YSZ0cmFkZTsgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2UuICBUaGVyZWZvcmUsIG1ldGhvZHMgd2hvc2UgbmFtZXMKICogYmVnaW4gd2l0aCB7QGNvZGUgInZpc2l0In0gbWF5IGJlIGFkZGVkIHRvIHRoaXMgY2xhc3MgaW4gdGhlCiAqIGZ1dHVyZTsgdG8gYXZvaWQgaW5jb21wYXRpYmlsaXRpZXMsIGNsYXNzZXMgd2hpY2ggZXh0ZW5kIHRoaXMgY2xhc3MKICogc2hvdWxkIG5vdCBkZWNsYXJlIGFueSBpbnN0YW5jZSBtZXRob2RzIHdpdGggbmFtZXMgYmVnaW5uaW5nIHdpdGgKICoge0Bjb2RlICJ2aXNpdCJ9LgogKgogKiA8cD5XaGVuIHN1Y2ggYSBuZXcgdmlzaXQgbWV0aG9kIGlzIGFkZGVkLCB0aGUgZGVmYXVsdAogKiBpbXBsZW1lbnRhdGlvbiBpbiB0aGlzIGNsYXNzIHdpbGwgYmUgdG8gY2FsbCB0aGUge0BsaW5rCiAqICN2aXNpdFVua25vd24gdmlzaXRVbmtub3dufSBtZXRob2QuICBBIG5ldyBhYnN0cmFjdCBlbGVtZW50IGtpbmQKICogdmlzaXRvciBjbGFzcyB3aWxsIGFsc28gYmUgaW50cm9kdWNlZCB0byBjb3JyZXNwb25kIHRvIHRoZSBuZXcKICogbGFuZ3VhZ2UgbGV2ZWw7IHRoaXMgdmlzaXRvciB3aWxsIGhhdmUgZGlmZmVyZW50IGRlZmF1bHQgYmVoYXZpb3IKICogZm9yIHRoZSB2aXNpdCBtZXRob2QgaW4gcXVlc3Rpb24uICBXaGVuIHRoZSBuZXcgdmlzaXRvciBpcwogKiBpbnRyb2R1Y2VkLCBhbGwgb3IgcG9ydGlvbnMgb2YgdGhpcyB2aXNpdG9yIG1heSBiZSBkZXByZWNhdGVkLgogKgogKiBAcGFyYW0gPFI+IHRoZSByZXR1cm4gdHlwZSBvZiB0aGlzIHZpc2l0b3IncyBtZXRob2RzLiAgVXNlIHtAbGluawogKiAgICAgICAgICAgIFZvaWR9IGZvciB2aXNpdG9ycyB0aGF0IGRvIG5vdCBuZWVkIHRvIHJldHVybiByZXN1bHRzLgogKiBAcGFyYW0gPFA+IHRoZSB0eXBlIG9mIHRoZSBhZGRpdGlvbmFsIHBhcmFtZXRlciB0byB0aGlzIHZpc2l0b3IncwogKiAgICAgICAgICAgIG1ldGhvZHMuICBVc2Uge0Bjb2RlIFZvaWR9IGZvciB2aXNpdG9ycyB0aGF0IGRvIG5vdCBuZWVkIGFuCiAqICAgICAgICAgICAgYWRkaXRpb25hbCBwYXJhbWV0ZXIuCiAqCiAqIEBzZWUgRWxlbWVudEtpbmRWaXNpdG9yNgogKiBAc2VlIEVsZW1lbnRLaW5kVmlzaXRvcjgKICogQHNlZSBFbGVtZW50S2luZFZpc2l0b3I5CiAqIEBzaW5jZSAxLjcKICovCkBTdXBwb3J0ZWRTb3VyY2VWZXJzaW9uKFJFTEVBU0VfNykKcHVibGljIGNsYXNzIEVsZW1lbnRLaW5kVmlzaXRvcjc8UiwgUD4gZXh0ZW5kcyBFbGVtZW50S2luZFZpc2l0b3I2PFIsIFA+IHsKICAgIC8qKgogICAgICogQ29uc3RydWN0b3IgZm9yIGNvbmNyZXRlIHN1YmNsYXNzZXM7IHVzZXMge0Bjb2RlIG51bGx9IGZvciB0aGUKICAgICAqIGRlZmF1bHQgdmFsdWUuCiAgICAgKi8KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJkZXByZWNhdGlvbiIpIC8vIFN1cGVyY2xhc3MgY29uc3RydWN0b3IgZGVwcmVjYXRlZAogICAgcHJvdGVjdGVkIEVsZW1lbnRLaW5kVmlzaXRvcjcoKSB7CiAgICAgICAgc3VwZXIobnVsbCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDb25zdHJ1Y3RvciBmb3IgY29uY3JldGUgc3ViY2xhc3NlczsgdXNlcyB0aGUgYXJndW1lbnQgZm9yIHRoZQogICAgICogZGVmYXVsdCB2YWx1ZS4KICAgICAqCiAgICAgKiBAcGFyYW0gZGVmYXVsdFZhbHVlIHRoZSB2YWx1ZSB0byBhc3NpZ24gdG8ge0BsaW5rICNERUZBVUxUX1ZBTFVFfQogICAgICovCiAgICBAU3VwcHJlc3NXYXJuaW5ncygiZGVwcmVjYXRpb24iKSAvLyBTdXBlcmNsYXNzIGNvbnN0cnVjdG9yIGRlcHJlY2F0ZWQKICAgIHByb3RlY3RlZCBFbGVtZW50S2luZFZpc2l0b3I3KFIgZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgc3VwZXIoZGVmYXVsdFZhbHVlKTsKICAgIH0KCiAgICAvKioKICAgICAqIFZpc2l0cyBhIHtAY29kZSBSRVNPVVJDRV9WQVJJQUJMRX0gdmFyaWFibGUgZWxlbWVudCBieSBjYWxsaW5nCiAgICAgKiB7QGNvZGUgZGVmYXVsdEFjdGlvbn0uCiAgICAgKgogICAgICogQHBhcmFtIGUge0Bpbmhlcml0RG9jfQogICAgICogQHBhcmFtIHAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiAgdGhlIHJlc3VsdCBvZiB7QGNvZGUgZGVmYXVsdEFjdGlvbn0KICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgUiB2aXNpdFZhcmlhYmxlQXNSZXNvdXJjZVZhcmlhYmxlKFZhcmlhYmxlRWxlbWVudCBlLCBQIHApIHsKICAgICAgICByZXR1cm4gZGVmYXVsdEFjdGlvbihlLCBwKTsKICAgIH0KfQpQSwMECgAACAAABjupSs8JScUHEQAABxEAADAAAABqYXZheC9sYW5nL21vZGVsL3V0aWwvU2ltcGxlRWxlbWVudFZpc2l0b3I5LmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTEsIDIwMTUsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgamF2YXgubGFuZy5tb2RlbC51dGlsOwoKaW1wb3J0IGphdmF4LmFubm90YXRpb24ucHJvY2Vzc2luZy5TdXBwb3J0ZWRTb3VyY2VWZXJzaW9uOwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5Tb3VyY2VWZXJzaW9uOwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5lbGVtZW50Lk1vZHVsZUVsZW1lbnQ7CmltcG9ydCBzdGF0aWMgamF2YXgubGFuZy5tb2RlbC5Tb3VyY2VWZXJzaW9uLio7CgovKioKICogQSBzaW1wbGUgdmlzaXRvciBvZiBwcm9ncmFtIGVsZW1lbnRzIHdpdGggZGVmYXVsdCBiZWhhdmlvcgogKiBhcHByb3ByaWF0ZSBmb3IgdGhlIHtAbGluayBTb3VyY2VWZXJzaW9uI1JFTEVBU0VfOSBSRUxFQVNFXzl9CiAqIHNvdXJjZSB2ZXJzaW9uLgogKgogKiBWaXNpdCBtZXRob2RzIGNvcnJlc3BvbmRpbmcgdG8ge0Bjb2RlIFJFTEVBU0VfOX0gYW5kIGVhcmxpZXIKICogbGFuZ3VhZ2UgY29uc3RydWN0cyBjYWxsIHtAbGluayAjZGVmYXVsdEFjdGlvbiBkZWZhdWx0QWN0aW9ufSwKICogcGFzc2luZyB0aGVpciBhcmd1bWVudHMgdG8ge0Bjb2RlIGRlZmF1bHRBY3Rpb259J3MgY29ycmVzcG9uZGluZwogKiBwYXJhbWV0ZXJzLgogKgogKiA8cD4gTWV0aG9kcyBpbiB0aGlzIGNsYXNzIG1heSBiZSBvdmVycmlkZGVuIHN1YmplY3QgdG8gdGhlaXIKICogZ2VuZXJhbCBjb250cmFjdC4gIE5vdGUgdGhhdCBhbm5vdGF0aW5nIG1ldGhvZHMgaW4gY29uY3JldGUKICogc3ViY2xhc3NlcyB3aXRoIHtAbGluayBqYXZhLmxhbmcuT3ZlcnJpZGUgQE92ZXJyaWRlfSB3aWxsIGhlbHAKICogZW5zdXJlIHRoYXQgbWV0aG9kcyBhcmUgb3ZlcnJpZGRlbiBhcyBpbnRlbmRlZC4KICoKICogPHA+IDxiPldBUk5JTkc6PC9iPiBUaGUge0Bjb2RlIEVsZW1lbnRWaXNpdG9yfSBpbnRlcmZhY2UKICogaW1wbGVtZW50ZWQgYnkgdGhpcyBjbGFzcyBtYXkgaGF2ZSBtZXRob2RzIGFkZGVkIHRvIGl0IGluIHRoZQogKiBmdXR1cmUgdG8gYWNjb21tb2RhdGUgbmV3LCBjdXJyZW50bHkgdW5rbm93biwgbGFuZ3VhZ2Ugc3RydWN0dXJlcwogKiBhZGRlZCB0byBmdXR1cmUgdmVyc2lvbnMgb2YgdGhlIEphdmEmdHJhZGU7IHByb2dyYW1taW5nIGxhbmd1YWdlLgogKiBUaGVyZWZvcmUsIG1ldGhvZHMgd2hvc2UgbmFtZXMgYmVnaW4gd2l0aCB7QGNvZGUgInZpc2l0In0gbWF5IGJlCiAqIGFkZGVkIHRvIHRoaXMgY2xhc3MgaW4gdGhlIGZ1dHVyZTsgdG8gYXZvaWQgaW5jb21wYXRpYmlsaXRpZXMsCiAqIGNsYXNzZXMgd2hpY2ggZXh0ZW5kIHRoaXMgY2xhc3Mgc2hvdWxkIG5vdCBkZWNsYXJlIGFueSBpbnN0YW5jZQogKiBtZXRob2RzIHdpdGggbmFtZXMgYmVnaW5uaW5nIHdpdGgge0Bjb2RlICJ2aXNpdCJ9LgogKgogKiA8cD5XaGVuIHN1Y2ggYSBuZXcgdmlzaXQgbWV0aG9kIGlzIGFkZGVkLCB0aGUgZGVmYXVsdAogKiBpbXBsZW1lbnRhdGlvbiBpbiB0aGlzIGNsYXNzIHdpbGwgYmUgdG8gY2FsbCB0aGUge0BsaW5rCiAqICN2aXNpdFVua25vd24gdmlzaXRVbmtub3dufSBtZXRob2QuICBBIG5ldyBzaW1wbGUgZWxlbWVudCB2aXNpdG9yCiAqIGNsYXNzIHdpbGwgYWxzbyBiZSBpbnRyb2R1Y2VkIHRvIGNvcnJlc3BvbmQgdG8gdGhlIG5ldyBsYW5ndWFnZQogKiBsZXZlbDsgdGhpcyB2aXNpdG9yIHdpbGwgaGF2ZSBkaWZmZXJlbnQgZGVmYXVsdCBiZWhhdmlvciBmb3IgdGhlCiAqIHZpc2l0IG1ldGhvZCBpbiBxdWVzdGlvbi4gIFdoZW4gdGhlIG5ldyB2aXNpdG9yIGlzIGludHJvZHVjZWQsIGFsbAogKiBvciBwb3J0aW9ucyBvZiB0aGlzIHZpc2l0b3IgbWF5IGJlIGRlcHJlY2F0ZWQuCiAqCiAqIEBwYXJhbSA8Uj4gdGhlIHJldHVybiB0eXBlIG9mIHRoaXMgdmlzaXRvcidzIG1ldGhvZHMuICBVc2Uge0Bjb2RlIFZvaWR9CiAqICAgICAgICAgICAgIGZvciB2aXNpdG9ycyB0aGF0IGRvIG5vdCBuZWVkIHRvIHJldHVybiByZXN1bHRzLgogKiBAcGFyYW0gPFA+IHRoZSB0eXBlIG9mIHRoZSBhZGRpdGlvbmFsIHBhcmFtZXRlciB0byB0aGlzIHZpc2l0b3IncyBtZXRob2RzLiAgVXNlIHtAY29kZSBWb2lkfQogKiAgICAgICAgICAgICAgZm9yIHZpc2l0b3JzIHRoYXQgZG8gbm90IG5lZWQgYW4gYWRkaXRpb25hbCBwYXJhbWV0ZXIuCiAqCiAqIEBzZWUgU2ltcGxlRWxlbWVudFZpc2l0b3I2CiAqIEBzZWUgU2ltcGxlRWxlbWVudFZpc2l0b3I3CiAqIEBzZWUgU2ltcGxlRWxlbWVudFZpc2l0b3I4CiAqIEBzaW5jZSA5CiAqIEBzcGVjIEpQTVMKICovCkBTdXBwb3J0ZWRTb3VyY2VWZXJzaW9uKFJFTEVBU0VfOSkKcHVibGljIGNsYXNzIFNpbXBsZUVsZW1lbnRWaXNpdG9yOTxSLCBQPiBleHRlbmRzIFNpbXBsZUVsZW1lbnRWaXNpdG9yODxSLCBQPiB7CiAgICAvKioKICAgICAqIENvbnN0cnVjdG9yIGZvciBjb25jcmV0ZSBzdWJjbGFzc2VzOyB1c2VzIHtAY29kZSBudWxsfSBmb3IgdGhlCiAgICAgKiBkZWZhdWx0IHZhbHVlLgogICAgICovCiAgICBwcm90ZWN0ZWQgU2ltcGxlRWxlbWVudFZpc2l0b3I5KCl7CiAgICAgICAgc3VwZXIobnVsbCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDb25zdHJ1Y3RvciBmb3IgY29uY3JldGUgc3ViY2xhc3NlczsgdXNlcyB0aGUgYXJndW1lbnQgZm9yIHRoZQogICAgICogZGVmYXVsdCB2YWx1ZS4KICAgICAqCiAgICAgKiBAcGFyYW0gZGVmYXVsdFZhbHVlIHRoZSB2YWx1ZSB0byBhc3NpZ24gdG8ge0BsaW5rICNERUZBVUxUX1ZBTFVFfQogICAgICovCiAgICBwcm90ZWN0ZWQgU2ltcGxlRWxlbWVudFZpc2l0b3I5KFIgZGVmYXVsdFZhbHVlKXsKICAgICAgICBzdXBlcihkZWZhdWx0VmFsdWUpOwogICAgfQoKICAgIC8qKgogICAgICogVmlzaXRzIGEge0Bjb2RlIE1vZHVsZUVsZW1lbnR9IGJ5IGNhbGxpbmcge0Bjb2RlCiAgICAgKiBkZWZhdWx0QWN0aW9ufS4KICAgICAqCiAgICAgKiBAcGFyYW0gZSB0aGUgZWxlbWVudCB0byB2aXNpdAogICAgICogQHBhcmFtIHAgYSB2aXNpdG9yLXNwZWNpZmllZCBwYXJhbWV0ZXIKICAgICAqIEByZXR1cm4gIHRoZSByZXN1bHQgb2Yge0Bjb2RlIGRlZmF1bHRBY3Rpb259CiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRNb2R1bGUoTW9kdWxlRWxlbWVudCBlLCBQIHApIHsKICAgICAgICByZXR1cm4gZGVmYXVsdEFjdGlvbihlLCBwKTsKICAgIH0KfQpQSwMECgAACAAABjupSrKvnfoVDAAAFQwAADoAAABqYXZheC9sYW5nL21vZGVsL3V0aWwvQWJzdHJhY3RBbm5vdGF0aW9uVmFsdWVWaXNpdG9yOS5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDExLCAyMDE0LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGphdmF4LmxhbmcubW9kZWwudXRpbDsKCmltcG9ydCBzdGF0aWMgamF2YXgubGFuZy5tb2RlbC5Tb3VyY2VWZXJzaW9uLio7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLlNvdXJjZVZlcnNpb247CmltcG9ydCBqYXZheC5hbm5vdGF0aW9uLnByb2Nlc3NpbmcuU3VwcG9ydGVkU291cmNlVmVyc2lvbjsKCi8qKgogKiBBIHNrZWxldGFsIHZpc2l0b3IgZm9yIGFubm90YXRpb24gdmFsdWVzIHdpdGggZGVmYXVsdCBiZWhhdmlvcgogKiBhcHByb3ByaWF0ZSBmb3IgdGhlIHtAbGluayBTb3VyY2VWZXJzaW9uI1JFTEVBU0VfOSBSRUxFQVNFXzl9CiAqIHNvdXJjZSB2ZXJzaW9uLgogKgogKiA8cD4gPGI+V0FSTklORzo8L2I+IFRoZSB7QGNvZGUgQW5ub3RhdGlvblZhbHVlVmlzaXRvcn0gaW50ZXJmYWNlCiAqIGltcGxlbWVudGVkIGJ5IHRoaXMgY2xhc3MgbWF5IGhhdmUgbWV0aG9kcyBhZGRlZCB0byBpdCBpbiB0aGUKICogZnV0dXJlIHRvIGFjY29tbW9kYXRlIG5ldywgY3VycmVudGx5IHVua25vd24sIGxhbmd1YWdlIHN0cnVjdHVyZXMKICogYWRkZWQgdG8gZnV0dXJlIHZlcnNpb25zIG9mIHRoZSBKYXZhJnRyYWRlOyBwcm9ncmFtbWluZyBsYW5ndWFnZS4KICogVGhlcmVmb3JlLCBtZXRob2RzIHdob3NlIG5hbWVzIGJlZ2luIHdpdGgge0Bjb2RlICJ2aXNpdCJ9IG1heSBiZQogKiBhZGRlZCB0byB0aGlzIGNsYXNzIGluIHRoZSBmdXR1cmU7IHRvIGF2b2lkIGluY29tcGF0aWJpbGl0aWVzLAogKiBjbGFzc2VzIHdoaWNoIGV4dGVuZCB0aGlzIGNsYXNzIHNob3VsZCBub3QgZGVjbGFyZSBhbnkgaW5zdGFuY2UKICogbWV0aG9kcyB3aXRoIG5hbWVzIGJlZ2lubmluZyB3aXRoIHtAY29kZSAidmlzaXQifS4KICoKICogPHA+V2hlbiBzdWNoIGEgbmV3IHZpc2l0IG1ldGhvZCBpcyBhZGRlZCwgdGhlIGRlZmF1bHQKICogaW1wbGVtZW50YXRpb24gaW4gdGhpcyBjbGFzcyB3aWxsIGJlIHRvIGNhbGwgdGhlIHtAbGluawogKiAjdmlzaXRVbmtub3duIHZpc2l0VW5rbm93bn0gbWV0aG9kLiAgQSBuZXcgYWJzdHJhY3QgYW5ub3RhdGlvbgogKiB2YWx1ZSB2aXNpdG9yIGNsYXNzIHdpbGwgYWxzbyBiZSBpbnRyb2R1Y2VkIHRvIGNvcnJlc3BvbmQgdG8gdGhlCiAqIG5ldyBsYW5ndWFnZSBsZXZlbDsgdGhpcyB2aXNpdG9yIHdpbGwgaGF2ZSBkaWZmZXJlbnQgZGVmYXVsdAogKiBiZWhhdmlvciBmb3IgdGhlIHZpc2l0IG1ldGhvZCBpbiBxdWVzdGlvbi4gIFdoZW4gdGhlIG5ldyB2aXNpdG9yIGlzCiAqIGludHJvZHVjZWQsIGFsbCBvciBwb3J0aW9ucyBvZiB0aGlzIHZpc2l0b3IgbWF5IGJlIGRlcHJlY2F0ZWQuCiAqCiAqIEBwYXJhbSA8Uj4gdGhlIHJldHVybiB0eXBlIG9mIHRoaXMgdmlzaXRvcidzIG1ldGhvZHMKICogQHBhcmFtIDxQPiB0aGUgdHlwZSBvZiB0aGUgYWRkaXRpb25hbCBwYXJhbWV0ZXIgdG8gdGhpcyB2aXNpdG9yJ3MgbWV0aG9kcy4KICoKICogQHNlZSBBYnN0cmFjdEFubm90YXRpb25WYWx1ZVZpc2l0b3I2CiAqIEBzZWUgQWJzdHJhY3RBbm5vdGF0aW9uVmFsdWVWaXNpdG9yNwogKiBAc2VlIEFic3RyYWN0QW5ub3RhdGlvblZhbHVlVmlzaXRvcjgKICogQHNpbmNlIDkKICovCkBTdXBwb3J0ZWRTb3VyY2VWZXJzaW9uKFJFTEVBU0VfOSkKcHVibGljIGFic3RyYWN0IGNsYXNzIEFic3RyYWN0QW5ub3RhdGlvblZhbHVlVmlzaXRvcjk8UiwgUD4gZXh0ZW5kcyBBYnN0cmFjdEFubm90YXRpb25WYWx1ZVZpc2l0b3I4PFIsIFA+IHsKCiAgICAvKioKICAgICAqIENvbnN0cnVjdG9yIGZvciBjb25jcmV0ZSBzdWJjbGFzc2VzIHRvIGNhbGwuCiAgICAgKi8KICAgIHByb3RlY3RlZCBBYnN0cmFjdEFubm90YXRpb25WYWx1ZVZpc2l0b3I5KCkgewogICAgICAgIHN1cGVyKCk7CiAgICB9Cn0KUEsDBAoAAAgAAAY7qUp8RmRnDhEAAA4RAAAuAAAAamF2YXgvbGFuZy9tb2RlbC91dGlsL0VsZW1lbnRLaW5kVmlzaXRvcjguamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAxMSwgMjAxNywgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBqYXZheC5sYW5nLm1vZGVsLnV0aWw7CgppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5lbGVtZW50Lio7CmltcG9ydCBqYXZheC5hbm5vdGF0aW9uLnByb2Nlc3NpbmcuU3VwcG9ydGVkU291cmNlVmVyc2lvbjsKaW1wb3J0IHN0YXRpYyBqYXZheC5sYW5nLm1vZGVsLlNvdXJjZVZlcnNpb24uKjsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuU291cmNlVmVyc2lvbjsKCi8qKgogKiBBIHZpc2l0b3Igb2YgcHJvZ3JhbSBlbGVtZW50cyBiYXNlZCBvbiB0aGVpciB7QGxpbmtwbGFpbgogKiBFbGVtZW50S2luZCBraW5kfSB3aXRoIGRlZmF1bHQgYmVoYXZpb3IgYXBwcm9wcmlhdGUgZm9yIHRoZSB7QGxpbmsKICogU291cmNlVmVyc2lvbiNSRUxFQVNFXzggUkVMRUFTRV84fSBzb3VyY2UgdmVyc2lvbi4gIEZvciB7QGxpbmtwbGFpbgogKiBFbGVtZW50IGVsZW1lbnRzfSA8Y29kZT48aT5YeXo8L2k+PC9jb2RlPiB0aGF0IG1heSBoYXZlIG1vcmUgdGhhbiBvbmUKICoga2luZCwgdGhlIDxjb2RlPnZpc2l0PGk+WHl6PC9pPjwvY29kZT4gbWV0aG9kcyBpbiB0aGlzIGNsYXNzIGRlbGVnYXRlCiAqIHRvIHRoZSA8Y29kZT52aXNpdDxpPlh5ejwvaT5BczxpPktpbmQ8L2k+PC9jb2RlPiBtZXRob2QgY29ycmVzcG9uZGluZyB0byB0aGUKICogZmlyc3QgYXJndW1lbnQncyBraW5kLiAgVGhlIDxjb2RlPnZpc2l0PGk+WHl6PC9pPkFzPGk+S2luZDwvaT48L2NvZGU+IG1ldGhvZHMKICogY2FsbCB7QGxpbmsgI2RlZmF1bHRBY3Rpb24gZGVmYXVsdEFjdGlvbn0sIHBhc3NpbmcgdGhlaXIgYXJndW1lbnRzCiAqIHRvIHtAY29kZSBkZWZhdWx0QWN0aW9ufSdzIGNvcnJlc3BvbmRpbmcgcGFyYW1ldGVycy4KICoKICogPHA+IE1ldGhvZHMgaW4gdGhpcyBjbGFzcyBtYXkgYmUgb3ZlcnJpZGRlbiBzdWJqZWN0IHRvIHRoZWlyCiAqIGdlbmVyYWwgY29udHJhY3QuICBOb3RlIHRoYXQgYW5ub3RhdGluZyBtZXRob2RzIGluIGNvbmNyZXRlCiAqIHN1YmNsYXNzZXMgd2l0aCB7QGxpbmsgamF2YS5sYW5nLk92ZXJyaWRlIEBPdmVycmlkZX0gd2lsbCBoZWxwCiAqIGVuc3VyZSB0aGF0IG1ldGhvZHMgYXJlIG92ZXJyaWRkZW4gYXMgaW50ZW5kZWQuCiAqCiAqIDxwPiA8Yj5XQVJOSU5HOjwvYj4gVGhlIHtAY29kZSBFbGVtZW50VmlzaXRvcn0gaW50ZXJmYWNlCiAqIGltcGxlbWVudGVkIGJ5IHRoaXMgY2xhc3MgbWF5IGhhdmUgbWV0aG9kcyBhZGRlZCB0byBpdCBvciB0aGUKICoge0Bjb2RlIEVsZW1lbnRLaW5kfSB7QGNvZGUgZW51bX0gdXNlZCBpbiB0aGlzIGNhc2UgbWF5IGhhdmUKICogY29uc3RhbnRzIGFkZGVkIHRvIGl0IGluIHRoZSBmdXR1cmUgdG8gYWNjb21tb2RhdGUgbmV3LCBjdXJyZW50bHkKICogdW5rbm93biwgbGFuZ3VhZ2Ugc3RydWN0dXJlcyBhZGRlZCB0byBmdXR1cmUgdmVyc2lvbnMgb2YgdGhlCiAqIEphdmEmdHJhZGU7IHByb2dyYW1taW5nIGxhbmd1YWdlLiAgVGhlcmVmb3JlLCBtZXRob2RzIHdob3NlIG5hbWVzCiAqIGJlZ2luIHdpdGgge0Bjb2RlICJ2aXNpdCJ9IG1heSBiZSBhZGRlZCB0byB0aGlzIGNsYXNzIGluIHRoZQogKiBmdXR1cmU7IHRvIGF2b2lkIGluY29tcGF0aWJpbGl0aWVzLCBjbGFzc2VzIHdoaWNoIGV4dGVuZCB0aGlzIGNsYXNzCiAqIHNob3VsZCBub3QgZGVjbGFyZSBhbnkgaW5zdGFuY2UgbWV0aG9kcyB3aXRoIG5hbWVzIGJlZ2lubmluZyB3aXRoCiAqIHtAY29kZSAidmlzaXQifS4KICoKICogPHA+V2hlbiBzdWNoIGEgbmV3IHZpc2l0IG1ldGhvZCBpcyBhZGRlZCwgdGhlIGRlZmF1bHQKICogaW1wbGVtZW50YXRpb24gaW4gdGhpcyBjbGFzcyB3aWxsIGJlIHRvIGNhbGwgdGhlIHtAbGluawogKiAjdmlzaXRVbmtub3duIHZpc2l0VW5rbm93bn0gbWV0aG9kLiAgQSBuZXcgYWJzdHJhY3QgZWxlbWVudCBraW5kCiAqIHZpc2l0b3IgY2xhc3Mgd2lsbCBhbHNvIGJlIGludHJvZHVjZWQgdG8gY29ycmVzcG9uZCB0byB0aGUgbmV3CiAqIGxhbmd1YWdlIGxldmVsOyB0aGlzIHZpc2l0b3Igd2lsbCBoYXZlIGRpZmZlcmVudCBkZWZhdWx0IGJlaGF2aW9yCiAqIGZvciB0aGUgdmlzaXQgbWV0aG9kIGluIHF1ZXN0aW9uLiAgV2hlbiB0aGUgbmV3IHZpc2l0b3IgaXMKICogaW50cm9kdWNlZCwgYWxsIG9yIHBvcnRpb25zIG9mIHRoaXMgdmlzaXRvciBtYXkgYmUgZGVwcmVjYXRlZC4KICoKICogQHBhcmFtIDxSPiB0aGUgcmV0dXJuIHR5cGUgb2YgdGhpcyB2aXNpdG9yJ3MgbWV0aG9kcy4gIFVzZSB7QGxpbmsKICogICAgICAgICAgICBWb2lkfSBmb3IgdmlzaXRvcnMgdGhhdCBkbyBub3QgbmVlZCB0byByZXR1cm4gcmVzdWx0cy4KICogQHBhcmFtIDxQPiB0aGUgdHlwZSBvZiB0aGUgYWRkaXRpb25hbCBwYXJhbWV0ZXIgdG8gdGhpcyB2aXNpdG9yJ3MKICogICAgICAgICAgICBtZXRob2RzLiAgVXNlIHtAY29kZSBWb2lkfSBmb3IgdmlzaXRvcnMgdGhhdCBkbyBub3QgbmVlZCBhbgogKiAgICAgICAgICAgIGFkZGl0aW9uYWwgcGFyYW1ldGVyLgogKgogKiBAc2VlIEVsZW1lbnRLaW5kVmlzaXRvcjYKICogQHNlZSBFbGVtZW50S2luZFZpc2l0b3I3CiAqIEBzZWUgRWxlbWVudEtpbmRWaXNpdG9yOQogKiBAc2luY2UgMS44CiAqLwpAU3VwcG9ydGVkU291cmNlVmVyc2lvbihSRUxFQVNFXzgpCnB1YmxpYyBjbGFzcyBFbGVtZW50S2luZFZpc2l0b3I4PFIsIFA+IGV4dGVuZHMgRWxlbWVudEtpbmRWaXNpdG9yNzxSLCBQPiB7CiAgICAvKioKICAgICAqIENvbnN0cnVjdG9yIGZvciBjb25jcmV0ZSBzdWJjbGFzc2VzOyB1c2VzIHtAY29kZSBudWxsfSBmb3IgdGhlCiAgICAgKiBkZWZhdWx0IHZhbHVlLgogICAgICovCiAgICBwcm90ZWN0ZWQgRWxlbWVudEtpbmRWaXNpdG9yOCgpIHsKICAgICAgICBzdXBlcihudWxsKTsKICAgIH0KCiAgICAvKioKICAgICAqIENvbnN0cnVjdG9yIGZvciBjb25jcmV0ZSBzdWJjbGFzc2VzOyB1c2VzIHRoZSBhcmd1bWVudCBmb3IgdGhlCiAgICAgKiBkZWZhdWx0IHZhbHVlLgogICAgICoKICAgICAqIEBwYXJhbSBkZWZhdWx0VmFsdWUgdGhlIHZhbHVlIHRvIGFzc2lnbiB0byB7QGxpbmsgI0RFRkFVTFRfVkFMVUV9CiAgICAgKi8KICAgIHByb3RlY3RlZCBFbGVtZW50S2luZFZpc2l0b3I4KFIgZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgc3VwZXIoZGVmYXVsdFZhbHVlKTsKICAgIH0KfQpQSwMECgAACAAABjupSllP3YNZEQAAWREAADAAAABqYXZheC9sYW5nL21vZGVsL3V0aWwvU2ltcGxlRWxlbWVudFZpc2l0b3I3LmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTAsIDIwMTcsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgamF2YXgubGFuZy5tb2RlbC51dGlsOwoKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC4qOwppbXBvcnQgamF2YXguYW5ub3RhdGlvbi5wcm9jZXNzaW5nLlN1cHBvcnRlZFNvdXJjZVZlcnNpb247CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLlNvdXJjZVZlcnNpb247CmltcG9ydCBzdGF0aWMgamF2YXgubGFuZy5tb2RlbC5Tb3VyY2VWZXJzaW9uLio7CgovKioKICogQSBzaW1wbGUgdmlzaXRvciBvZiBwcm9ncmFtIGVsZW1lbnRzIHdpdGggZGVmYXVsdCBiZWhhdmlvcgogKiBhcHByb3ByaWF0ZSBmb3IgdGhlIHtAbGluayBTb3VyY2VWZXJzaW9uI1JFTEVBU0VfNyBSRUxFQVNFXzd9CiAqIHNvdXJjZSB2ZXJzaW9uLgogKgogKiBWaXNpdCBtZXRob2RzIGNvcnJlc3BvbmRpbmcgdG8ge0Bjb2RlIFJFTEVBU0VfN30gYW5kIGVhcmxpZXIKICogbGFuZ3VhZ2UgY29uc3RydWN0cyBjYWxsIHtAbGluayAjZGVmYXVsdEFjdGlvbiBkZWZhdWx0QWN0aW9ufSwKICogcGFzc2luZyB0aGVpciBhcmd1bWVudHMgdG8ge0Bjb2RlIGRlZmF1bHRBY3Rpb259J3MgY29ycmVzcG9uZGluZwogKiBwYXJhbWV0ZXJzLgogKgogKiA8cD4gTWV0aG9kcyBpbiB0aGlzIGNsYXNzIG1heSBiZSBvdmVycmlkZGVuIHN1YmplY3QgdG8gdGhlaXIKICogZ2VuZXJhbCBjb250cmFjdC4gIE5vdGUgdGhhdCBhbm5vdGF0aW5nIG1ldGhvZHMgaW4gY29uY3JldGUKICogc3ViY2xhc3NlcyB3aXRoIHtAbGluayBqYXZhLmxhbmcuT3ZlcnJpZGUgQE92ZXJyaWRlfSB3aWxsIGhlbHAKICogZW5zdXJlIHRoYXQgbWV0aG9kcyBhcmUgb3ZlcnJpZGRlbiBhcyBpbnRlbmRlZC4KICoKICogPHA+IDxiPldBUk5JTkc6PC9iPiBUaGUge0Bjb2RlIEVsZW1lbnRWaXNpdG9yfSBpbnRlcmZhY2UKICogaW1wbGVtZW50ZWQgYnkgdGhpcyBjbGFzcyBtYXkgaGF2ZSBtZXRob2RzIGFkZGVkIHRvIGl0IGluIHRoZQogKiBmdXR1cmUgdG8gYWNjb21tb2RhdGUgbmV3LCBjdXJyZW50bHkgdW5rbm93biwgbGFuZ3VhZ2Ugc3RydWN0dXJlcwogKiBhZGRlZCB0byBmdXR1cmUgdmVyc2lvbnMgb2YgdGhlIEphdmEmdHJhZGU7IHByb2dyYW1taW5nIGxhbmd1YWdlLgogKiBUaGVyZWZvcmUsIG1ldGhvZHMgd2hvc2UgbmFtZXMgYmVnaW4gd2l0aCB7QGNvZGUgInZpc2l0In0gbWF5IGJlCiAqIGFkZGVkIHRvIHRoaXMgY2xhc3MgaW4gdGhlIGZ1dHVyZTsgdG8gYXZvaWQgaW5jb21wYXRpYmlsaXRpZXMsCiAqIGNsYXNzZXMgd2hpY2ggZXh0ZW5kIHRoaXMgY2xhc3Mgc2hvdWxkIG5vdCBkZWNsYXJlIGFueSBpbnN0YW5jZQogKiBtZXRob2RzIHdpdGggbmFtZXMgYmVnaW5uaW5nIHdpdGgge0Bjb2RlICJ2aXNpdCJ9LgogKgogKiA8cD5XaGVuIHN1Y2ggYSBuZXcgdmlzaXQgbWV0aG9kIGlzIGFkZGVkLCB0aGUgZGVmYXVsdAogKiBpbXBsZW1lbnRhdGlvbiBpbiB0aGlzIGNsYXNzIHdpbGwgYmUgdG8gY2FsbCB0aGUge0BsaW5rCiAqICN2aXNpdFVua25vd24gdmlzaXRVbmtub3dufSBtZXRob2QuICBBIG5ldyBzaW1wbGUgZWxlbWVudCB2aXNpdG9yCiAqIGNsYXNzIHdpbGwgYWxzbyBiZSBpbnRyb2R1Y2VkIHRvIGNvcnJlc3BvbmQgdG8gdGhlIG5ldyBsYW5ndWFnZQogKiBsZXZlbDsgdGhpcyB2aXNpdG9yIHdpbGwgaGF2ZSBkaWZmZXJlbnQgZGVmYXVsdCBiZWhhdmlvciBmb3IgdGhlCiAqIHZpc2l0IG1ldGhvZCBpbiBxdWVzdGlvbi4gIFdoZW4gdGhlIG5ldyB2aXNpdG9yIGlzIGludHJvZHVjZWQsIGFsbAogKiBvciBwb3J0aW9ucyBvZiB0aGlzIHZpc2l0b3IgbWF5IGJlIGRlcHJlY2F0ZWQuCiAqCiAqIEBwYXJhbSA8Uj4gdGhlIHJldHVybiB0eXBlIG9mIHRoaXMgdmlzaXRvcidzIG1ldGhvZHMuICBVc2Uge0Bjb2RlIFZvaWR9CiAqICAgICAgICAgICAgIGZvciB2aXNpdG9ycyB0aGF0IGRvIG5vdCBuZWVkIHRvIHJldHVybiByZXN1bHRzLgogKiBAcGFyYW0gPFA+IHRoZSB0eXBlIG9mIHRoZSBhZGRpdGlvbmFsIHBhcmFtZXRlciB0byB0aGlzIHZpc2l0b3IncyBtZXRob2RzLiAgVXNlIHtAY29kZSBWb2lkfQogKiAgICAgICAgICAgICAgZm9yIHZpc2l0b3JzIHRoYXQgZG8gbm90IG5lZWQgYW4gYWRkaXRpb25hbCBwYXJhbWV0ZXIuCiAqCiAqIEBzZWUgU2ltcGxlRWxlbWVudFZpc2l0b3I2CiAqIEBzZWUgU2ltcGxlRWxlbWVudFZpc2l0b3I4CiAqIEBzZWUgU2ltcGxlRWxlbWVudFZpc2l0b3I5CiAqIEBzaW5jZSAxLjcKICovCkBTdXBwb3J0ZWRTb3VyY2VWZXJzaW9uKFJFTEVBU0VfNykKcHVibGljIGNsYXNzIFNpbXBsZUVsZW1lbnRWaXNpdG9yNzxSLCBQPiBleHRlbmRzIFNpbXBsZUVsZW1lbnRWaXNpdG9yNjxSLCBQPiB7CiAgICAvKioKICAgICAqIENvbnN0cnVjdG9yIGZvciBjb25jcmV0ZSBzdWJjbGFzc2VzOyB1c2VzIHtAY29kZSBudWxsfSBmb3IgdGhlCiAgICAgKiBkZWZhdWx0IHZhbHVlLgogICAgICovCiAgICBAU3VwcHJlc3NXYXJuaW5ncygiZGVwcmVjYXRpb24iKSAvLyBTdXBlcmNsYXNzIGNvbnN0cnVjdG9yIGRlcHJlY2F0ZWQKICAgIHByb3RlY3RlZCBTaW1wbGVFbGVtZW50VmlzaXRvcjcoKXsKICAgICAgICBzdXBlcihudWxsKTsKICAgIH0KCiAgICAvKioKICAgICAqIENvbnN0cnVjdG9yIGZvciBjb25jcmV0ZSBzdWJjbGFzc2VzOyB1c2VzIHRoZSBhcmd1bWVudCBmb3IgdGhlCiAgICAgKiBkZWZhdWx0IHZhbHVlLgogICAgICoKICAgICAqIEBwYXJhbSBkZWZhdWx0VmFsdWUgdGhlIHZhbHVlIHRvIGFzc2lnbiB0byB7QGxpbmsgI0RFRkFVTFRfVkFMVUV9CiAgICAgKi8KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJkZXByZWNhdGlvbiIpIC8vIFN1cGVyY2xhc3MgY29uc3RydWN0b3IgZGVwcmVjYXRlZAogICAgcHJvdGVjdGVkIFNpbXBsZUVsZW1lbnRWaXNpdG9yNyhSIGRlZmF1bHRWYWx1ZSl7CiAgICAgICAgc3VwZXIoZGVmYXVsdFZhbHVlKTsKICAgIH0KCiAgICAvKioKICAgICAqIFRoaXMgaW1wbGVtZW50YXRpb24gY2FsbHMge0Bjb2RlIGRlZmF1bHRBY3Rpb259LgogICAgICoKICAgICAqIEBwYXJhbSBlIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gIHRoZSByZXN1bHQgb2Yge0Bjb2RlIGRlZmF1bHRBY3Rpb259CiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRWYXJpYWJsZShWYXJpYWJsZUVsZW1lbnQgZSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIGRlZmF1bHRBY3Rpb24oZSwgcCk7CiAgICB9Cn0KUEsDBAoAAAgAAAY7qUp3kaCWigwAAIoMAAAyAAAAamF2YXgvbGFuZy9tb2RlbC91dGlsL0Fic3RyYWN0RWxlbWVudFZpc2l0b3I4LmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTEsIDIwMTcsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgamF2YXgubGFuZy5tb2RlbC51dGlsOwoKaW1wb3J0IGphdmF4LmFubm90YXRpb24ucHJvY2Vzc2luZy5TdXBwb3J0ZWRTb3VyY2VWZXJzaW9uOwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5Tb3VyY2VWZXJzaW9uOwppbXBvcnQgc3RhdGljIGphdmF4LmxhbmcubW9kZWwuU291cmNlVmVyc2lvbi4qOwoKCi8qKgogKiBBIHNrZWxldGFsIHZpc2l0b3Igb2YgcHJvZ3JhbSBlbGVtZW50cyB3aXRoIGRlZmF1bHQgYmVoYXZpb3IKICogYXBwcm9wcmlhdGUgZm9yIHRoZSB7QGxpbmsgU291cmNlVmVyc2lvbiNSRUxFQVNFXzggUkVMRUFTRV84fQogKiBzb3VyY2UgdmVyc2lvbi4KICoKICogPHA+IDxiPldBUk5JTkc6PC9iPiBUaGUge0Bjb2RlIEVsZW1lbnRWaXNpdG9yfSBpbnRlcmZhY2UKICogaW1wbGVtZW50ZWQgYnkgdGhpcyBjbGFzcyBtYXkgaGF2ZSBtZXRob2RzIGFkZGVkIHRvIGl0IGluIHRoZQogKiBmdXR1cmUgdG8gYWNjb21tb2RhdGUgbmV3LCBjdXJyZW50bHkgdW5rbm93biwgbGFuZ3VhZ2Ugc3RydWN0dXJlcwogKiBhZGRlZCB0byBmdXR1cmUgdmVyc2lvbnMgb2YgdGhlIEphdmEmdHJhZGU7IHByb2dyYW1taW5nIGxhbmd1YWdlLgogKiBUaGVyZWZvcmUsIG1ldGhvZHMgd2hvc2UgbmFtZXMgYmVnaW4gd2l0aCB7QGNvZGUgInZpc2l0In0gbWF5IGJlCiAqIGFkZGVkIHRvIHRoaXMgY2xhc3MgaW4gdGhlIGZ1dHVyZTsgdG8gYXZvaWQgaW5jb21wYXRpYmlsaXRpZXMsCiAqIGNsYXNzZXMgd2hpY2ggZXh0ZW5kIHRoaXMgY2xhc3Mgc2hvdWxkIG5vdCBkZWNsYXJlIGFueSBpbnN0YW5jZQogKiBtZXRob2RzIHdpdGggbmFtZXMgYmVnaW5uaW5nIHdpdGgge0Bjb2RlICJ2aXNpdCJ9LgogKgogKiA8cD5XaGVuIHN1Y2ggYSBuZXcgdmlzaXQgbWV0aG9kIGlzIGFkZGVkLCB0aGUgZGVmYXVsdAogKiBpbXBsZW1lbnRhdGlvbiBpbiB0aGlzIGNsYXNzIHdpbGwgYmUgdG8gY2FsbCB0aGUge0BsaW5rCiAqICN2aXNpdFVua25vd24gdmlzaXRVbmtub3dufSBtZXRob2QuICBBIG5ldyBhYnN0cmFjdCBlbGVtZW50IHZpc2l0b3IKICogY2xhc3Mgd2lsbCBhbHNvIGJlIGludHJvZHVjZWQgdG8gY29ycmVzcG9uZCB0byB0aGUgbmV3IGxhbmd1YWdlCiAqIGxldmVsOyB0aGlzIHZpc2l0b3Igd2lsbCBoYXZlIGRpZmZlcmVudCBkZWZhdWx0IGJlaGF2aW9yIGZvciB0aGUKICogdmlzaXQgbWV0aG9kIGluIHF1ZXN0aW9uLiAgV2hlbiB0aGUgbmV3IHZpc2l0b3IgaXMgaW50cm9kdWNlZCwgYWxsCiAqIG9yIHBvcnRpb25zIG9mIHRoaXMgdmlzaXRvciBtYXkgYmUgZGVwcmVjYXRlZC4KICoKICogQHBhcmFtIDxSPiB0aGUgcmV0dXJuIHR5cGUgb2YgdGhpcyB2aXNpdG9yJ3MgbWV0aG9kcy4gIFVzZSB7QGxpbmsKICogICAgICAgICAgICBWb2lkfSBmb3IgdmlzaXRvcnMgdGhhdCBkbyBub3QgbmVlZCB0byByZXR1cm4gcmVzdWx0cy4KICogQHBhcmFtIDxQPiB0aGUgdHlwZSBvZiB0aGUgYWRkaXRpb25hbCBwYXJhbWV0ZXIgdG8gdGhpcyB2aXNpdG9yJ3MKICogICAgICAgICAgICBtZXRob2RzLiAgVXNlIHtAY29kZSBWb2lkfSBmb3IgdmlzaXRvcnMgdGhhdCBkbyBub3QgbmVlZCBhbgogKiAgICAgICAgICAgIGFkZGl0aW9uYWwgcGFyYW1ldGVyLgogKgogKiBAc2VlIEFic3RyYWN0RWxlbWVudFZpc2l0b3I2CiAqIEBzZWUgQWJzdHJhY3RFbGVtZW50VmlzaXRvcjcKICogQHNlZSBBYnN0cmFjdEVsZW1lbnRWaXNpdG9yOQogKiBAc2luY2UgMS44CiAqLwpAU3VwcG9ydGVkU291cmNlVmVyc2lvbihSRUxFQVNFXzgpCnB1YmxpYyBhYnN0cmFjdCBjbGFzcyBBYnN0cmFjdEVsZW1lbnRWaXNpdG9yODxSLCBQPiBleHRlbmRzIEFic3RyYWN0RWxlbWVudFZpc2l0b3I3PFIsIFA+IHsKICAgIC8qKgogICAgICogQ29uc3RydWN0b3IgZm9yIGNvbmNyZXRlIHN1YmNsYXNzZXMgdG8gY2FsbC4KICAgICAqLwogICAgcHJvdGVjdGVkIEFic3RyYWN0RWxlbWVudFZpc2l0b3I4KCl7CiAgICAgICAgc3VwZXIoKTsKICAgIH0KfQpQSwMECgAACAAABjupSlwtX0PmEAAA5hAAAC0AAABqYXZheC9sYW5nL21vZGVsL3V0aWwvU2ltcGxlVHlwZVZpc2l0b3I4LmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMTEsIDIwMTcsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgamF2YXgubGFuZy5tb2RlbC51dGlsOwoKaW1wb3J0IGphdmF4LmFubm90YXRpb24ucHJvY2Vzc2luZy5TdXBwb3J0ZWRTb3VyY2VWZXJzaW9uOwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5Tb3VyY2VWZXJzaW9uOwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC50eXBlLkludGVyc2VjdGlvblR5cGU7CmltcG9ydCBzdGF0aWMgamF2YXgubGFuZy5tb2RlbC5Tb3VyY2VWZXJzaW9uLio7CgovKioKICogQSBzaW1wbGUgdmlzaXRvciBvZiB0eXBlcyB3aXRoIGRlZmF1bHQgYmVoYXZpb3IgYXBwcm9wcmlhdGUgZm9yIHRoZQogKiB7QGxpbmsgU291cmNlVmVyc2lvbiNSRUxFQVNFXzggUkVMRUFTRV84fSBzb3VyY2UgdmVyc2lvbi4KICoKICogVmlzaXQgbWV0aG9kcyBjb3JyZXNwb25kaW5nIHRvIHtAY29kZSBSRUxFQVNFXzh9IGFuZCBlYXJsaWVyCiAqIGxhbmd1YWdlIGNvbnN0cnVjdHMgY2FsbCB7QGxpbmsgI2RlZmF1bHRBY3Rpb24gZGVmYXVsdEFjdGlvbn0sCiAqIHBhc3NpbmcgdGhlaXIgYXJndW1lbnRzIHRvIHtAY29kZSBkZWZhdWx0QWN0aW9ufSdzIGNvcnJlc3BvbmRpbmcKICogcGFyYW1ldGVycy4KICoKICogPHA+IE1ldGhvZHMgaW4gdGhpcyBjbGFzcyBtYXkgYmUgb3ZlcnJpZGRlbiBzdWJqZWN0IHRvIHRoZWlyCiAqIGdlbmVyYWwgY29udHJhY3QuICBOb3RlIHRoYXQgYW5ub3RhdGluZyBtZXRob2RzIGluIGNvbmNyZXRlCiAqIHN1YmNsYXNzZXMgd2l0aCB7QGxpbmsgamF2YS5sYW5nLk92ZXJyaWRlIEBPdmVycmlkZX0gd2lsbCBoZWxwCiAqIGVuc3VyZSB0aGF0IG1ldGhvZHMgYXJlIG92ZXJyaWRkZW4gYXMgaW50ZW5kZWQuCiAqCiAqIDxwPiA8Yj5XQVJOSU5HOjwvYj4gVGhlIHtAY29kZSBUeXBlVmlzaXRvcn0gaW50ZXJmYWNlIGltcGxlbWVudGVkCiAqIGJ5IHRoaXMgY2xhc3MgbWF5IGhhdmUgbWV0aG9kcyBhZGRlZCB0byBpdCBpbiB0aGUgZnV0dXJlIHRvCiAqIGFjY29tbW9kYXRlIG5ldywgY3VycmVudGx5IHVua25vd24sIGxhbmd1YWdlIHN0cnVjdHVyZXMgYWRkZWQgdG8KICogZnV0dXJlIHZlcnNpb25zIG9mIHRoZSBKYXZhJnRyYWRlOyBwcm9ncmFtbWluZyBsYW5ndWFnZS4KICogVGhlcmVmb3JlLCBtZXRob2RzIHdob3NlIG5hbWVzIGJlZ2luIHdpdGgge0Bjb2RlICJ2aXNpdCJ9IG1heSBiZQogKiBhZGRlZCB0byB0aGlzIGNsYXNzIGluIHRoZSBmdXR1cmU7IHRvIGF2b2lkIGluY29tcGF0aWJpbGl0aWVzLAogKiBjbGFzc2VzIHdoaWNoIGV4dGVuZCB0aGlzIGNsYXNzIHNob3VsZCBub3QgZGVjbGFyZSBhbnkgaW5zdGFuY2UKICogbWV0aG9kcyB3aXRoIG5hbWVzIGJlZ2lubmluZyB3aXRoIHtAY29kZSAidmlzaXQifS4KICoKICogPHA+V2hlbiBzdWNoIGEgbmV3IHZpc2l0IG1ldGhvZCBpcyBhZGRlZCwgdGhlIGRlZmF1bHQKICogaW1wbGVtZW50YXRpb24gaW4gdGhpcyBjbGFzcyB3aWxsIGJlIHRvIGNhbGwgdGhlIHtAbGluawogKiAjdmlzaXRVbmtub3duIHZpc2l0VW5rbm93bn0gbWV0aG9kLiAgQSBuZXcgc2ltcGxlIHR5cGUgdmlzaXRvcgogKiBjbGFzcyB3aWxsIGFsc28gYmUgaW50cm9kdWNlZCB0byBjb3JyZXNwb25kIHRvIHRoZSBuZXcgbGFuZ3VhZ2UKICogbGV2ZWw7IHRoaXMgdmlzaXRvciB3aWxsIGhhdmUgZGlmZmVyZW50IGRlZmF1bHQgYmVoYXZpb3IgZm9yIHRoZQogKiB2aXNpdCBtZXRob2QgaW4gcXVlc3Rpb24uICBXaGVuIHRoZSBuZXcgdmlzaXRvciBpcyBpbnRyb2R1Y2VkLCBhbGwKICogb3IgcG9ydGlvbnMgb2YgdGhpcyB2aXNpdG9yIG1heSBiZSBkZXByZWNhdGVkLgogKgogKiBAcGFyYW0gPFI+IHRoZSByZXR1cm4gdHlwZSBvZiB0aGlzIHZpc2l0b3IncyBtZXRob2RzLiAgVXNlIHtAbGluawogKiAgICAgICAgICAgIFZvaWR9IGZvciB2aXNpdG9ycyB0aGF0IGRvIG5vdCBuZWVkIHRvIHJldHVybiByZXN1bHRzLgogKiBAcGFyYW0gPFA+IHRoZSB0eXBlIG9mIHRoZSBhZGRpdGlvbmFsIHBhcmFtZXRlciB0byB0aGlzIHZpc2l0b3IncwogKiAgICAgICAgICAgIG1ldGhvZHMuICBVc2Uge0Bjb2RlIFZvaWR9IGZvciB2aXNpdG9ycyB0aGF0IGRvIG5vdCBuZWVkIGFuCiAqICAgICAgICAgICAgYWRkaXRpb25hbCBwYXJhbWV0ZXIuCiAqCiAqIEBzZWUgU2ltcGxlVHlwZVZpc2l0b3I2CiAqIEBzZWUgU2ltcGxlVHlwZVZpc2l0b3I3CiAqIEBzZWUgU2ltcGxlVHlwZVZpc2l0b3I5CiAqIEBzaW5jZSAxLjgKICovCkBTdXBwb3J0ZWRTb3VyY2VWZXJzaW9uKFJFTEVBU0VfOCkKcHVibGljIGNsYXNzIFNpbXBsZVR5cGVWaXNpdG9yODxSLCBQPiBleHRlbmRzIFNpbXBsZVR5cGVWaXNpdG9yNzxSLCBQPiB7CiAgICAvKioKICAgICAqIENvbnN0cnVjdG9yIGZvciBjb25jcmV0ZSBzdWJjbGFzc2VzOyB1c2VzIHtAY29kZSBudWxsfSBmb3IgdGhlCiAgICAgKiBkZWZhdWx0IHZhbHVlLgogICAgICovCiAgICBwcm90ZWN0ZWQgU2ltcGxlVHlwZVZpc2l0b3I4KCl7CiAgICAgICAgc3VwZXIobnVsbCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDb25zdHJ1Y3RvciBmb3IgY29uY3JldGUgc3ViY2xhc3NlczsgdXNlcyB0aGUgYXJndW1lbnQgZm9yIHRoZQogICAgICogZGVmYXVsdCB2YWx1ZS4KICAgICAqCiAgICAgKiBAcGFyYW0gZGVmYXVsdFZhbHVlIHRoZSB2YWx1ZSB0byBhc3NpZ24gdG8ge0BsaW5rICNERUZBVUxUX1ZBTFVFfQogICAgICovCiAgICBwcm90ZWN0ZWQgU2ltcGxlVHlwZVZpc2l0b3I4KFIgZGVmYXVsdFZhbHVlKXsKICAgICAgICBzdXBlcihkZWZhdWx0VmFsdWUpOwogICAgfQoKICAgIC8qKgogICAgICogVGhpcyBpbXBsZW1lbnRhdGlvbiB2aXNpdHMgYW4ge0Bjb2RlIEludGVyc2VjdGlvblR5cGV9IGJ5IGNhbGxpbmcKICAgICAqIHtAY29kZSBkZWZhdWx0QWN0aW9ufS4KICAgICAqCiAgICAgKiBAcGFyYW0gdCB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuICB0aGUgcmVzdWx0IG9mIHtAY29kZSBkZWZhdWx0QWN0aW9ufQogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0SW50ZXJzZWN0aW9uKEludGVyc2VjdGlvblR5cGUgdCwgUCBwKXsKICAgICAgICByZXR1cm4gZGVmYXVsdEFjdGlvbih0LCBwKTsKICAgIH0KfQpQSwMECgAACAAABjupSg/9K20BNQAAATUAAC4AAABqYXZheC9sYW5nL21vZGVsL3V0aWwvRWxlbWVudEtpbmRWaXNpdG9yNi5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDA1LCAyMDE3LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGphdmF4LmxhbmcubW9kZWwudXRpbDsKCmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuKjsKaW1wb3J0IHN0YXRpYyBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuRWxlbWVudEtpbmQuKjsKaW1wb3J0IGphdmF4LmFubm90YXRpb24ucHJvY2Vzc2luZy5TdXBwb3J0ZWRTb3VyY2VWZXJzaW9uOwppbXBvcnQgc3RhdGljIGphdmF4LmxhbmcubW9kZWwuU291cmNlVmVyc2lvbi4qOwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5Tb3VyY2VWZXJzaW9uOwoKCi8qKgogKiBBIHZpc2l0b3Igb2YgcHJvZ3JhbSBlbGVtZW50cyBiYXNlZCBvbiB0aGVpciB7QGxpbmtwbGFpbgogKiBFbGVtZW50S2luZCBraW5kfSB3aXRoIGRlZmF1bHQgYmVoYXZpb3IgYXBwcm9wcmlhdGUgZm9yIHRoZSB7QGxpbmsKICogU291cmNlVmVyc2lvbiNSRUxFQVNFXzYgUkVMRUFTRV82fSBzb3VyY2UgdmVyc2lvbi4gIEZvciB7QGxpbmtwbGFpbgogKiBFbGVtZW50IGVsZW1lbnRzfSA8Y29kZT48aT5YeXo8L2k+PC9jb2RlPiB0aGF0IG1heSBoYXZlIG1vcmUgdGhhbiBvbmUKICoga2luZCwgdGhlIDxjb2RlPnZpc2l0PGk+WHl6PC9pPjwvY29kZT4gbWV0aG9kcyBpbiB0aGlzIGNsYXNzIGRlbGVnYXRlCiAqIHRvIHRoZSA8Y29kZT52aXNpdDxpPlh5ejwvaT5BczxpPktpbmQ8L2k+PC9jb2RlPiBtZXRob2QgY29ycmVzcG9uZGluZyB0byB0aGUKICogZmlyc3QgYXJndW1lbnQncyBraW5kLiAgVGhlIDxjb2RlPnZpc2l0PGk+WHl6PC9pPkFzPGk+S2luZDwvaT48L2NvZGU+IG1ldGhvZHMKICogY2FsbCB7QGxpbmsgI2RlZmF1bHRBY3Rpb24gZGVmYXVsdEFjdGlvbn0sIHBhc3NpbmcgdGhlaXIgYXJndW1lbnRzCiAqIHRvIHtAY29kZSBkZWZhdWx0QWN0aW9ufSdzIGNvcnJlc3BvbmRpbmcgcGFyYW1ldGVycy4KICoKICogPHA+IE1ldGhvZHMgaW4gdGhpcyBjbGFzcyBtYXkgYmUgb3ZlcnJpZGRlbiBzdWJqZWN0IHRvIHRoZWlyCiAqIGdlbmVyYWwgY29udHJhY3QuICBOb3RlIHRoYXQgYW5ub3RhdGluZyBtZXRob2RzIGluIGNvbmNyZXRlCiAqIHN1YmNsYXNzZXMgd2l0aCB7QGxpbmsgamF2YS5sYW5nLk92ZXJyaWRlIEBPdmVycmlkZX0gd2lsbCBoZWxwCiAqIGVuc3VyZSB0aGF0IG1ldGhvZHMgYXJlIG92ZXJyaWRkZW4gYXMgaW50ZW5kZWQuCiAqCiAqIDxwPiA8Yj5XQVJOSU5HOjwvYj4gVGhlIHtAY29kZSBFbGVtZW50VmlzaXRvcn0gaW50ZXJmYWNlCiAqIGltcGxlbWVudGVkIGJ5IHRoaXMgY2xhc3MgbWF5IGhhdmUgbWV0aG9kcyBhZGRlZCB0byBpdCBvciB0aGUKICoge0Bjb2RlIEVsZW1lbnRLaW5kfSB7QGNvZGUgZW51bX0gdXNlZCBpbiB0aGlzIGNhc2UgbWF5IGhhdmUKICogY29uc3RhbnRzIGFkZGVkIHRvIGl0IGluIHRoZSBmdXR1cmUgdG8gYWNjb21tb2RhdGUgbmV3LCBjdXJyZW50bHkKICogdW5rbm93biwgbGFuZ3VhZ2Ugc3RydWN0dXJlcyBhZGRlZCB0byBmdXR1cmUgdmVyc2lvbnMgb2YgdGhlCiAqIEphdmEmdHJhZGU7IHByb2dyYW1taW5nIGxhbmd1YWdlLiAgVGhlcmVmb3JlLCBtZXRob2RzIHdob3NlIG5hbWVzCiAqIGJlZ2luIHdpdGgge0Bjb2RlICJ2aXNpdCJ9IG1heSBiZSBhZGRlZCB0byB0aGlzIGNsYXNzIGluIHRoZQogKiBmdXR1cmU7IHRvIGF2b2lkIGluY29tcGF0aWJpbGl0aWVzLCBjbGFzc2VzIHdoaWNoIGV4dGVuZCB0aGlzIGNsYXNzCiAqIHNob3VsZCBub3QgZGVjbGFyZSBhbnkgaW5zdGFuY2UgbWV0aG9kcyB3aXRoIG5hbWVzIGJlZ2lubmluZyB3aXRoCiAqIHtAY29kZSAidmlzaXQifS4KICoKICogPHA+V2hlbiBzdWNoIGEgbmV3IHZpc2l0IG1ldGhvZCBpcyBhZGRlZCwgdGhlIGRlZmF1bHQKICogaW1wbGVtZW50YXRpb24gaW4gdGhpcyBjbGFzcyB3aWxsIGJlIHRvIGNhbGwgdGhlIHtAbGluawogKiAjdmlzaXRVbmtub3duIHZpc2l0VW5rbm93bn0gbWV0aG9kLiAgQSBuZXcgYWJzdHJhY3QgZWxlbWVudCBraW5kCiAqIHZpc2l0b3IgY2xhc3Mgd2lsbCBhbHNvIGJlIGludHJvZHVjZWQgdG8gY29ycmVzcG9uZCB0byB0aGUgbmV3CiAqIGxhbmd1YWdlIGxldmVsOyB0aGlzIHZpc2l0b3Igd2lsbCBoYXZlIGRpZmZlcmVudCBkZWZhdWx0IGJlaGF2aW9yCiAqIGZvciB0aGUgdmlzaXQgbWV0aG9kIGluIHF1ZXN0aW9uLiAgV2hlbiB0aGUgbmV3IHZpc2l0b3IgaXMKICogaW50cm9kdWNlZCwgYWxsIG9yIHBvcnRpb25zIG9mIHRoaXMgdmlzaXRvciBtYXkgYmUgZGVwcmVjYXRlZC4KICoKICogQHBhcmFtIDxSPiB0aGUgcmV0dXJuIHR5cGUgb2YgdGhpcyB2aXNpdG9yJ3MgbWV0aG9kcy4gIFVzZSB7QGxpbmsKICogICAgICAgICAgICBWb2lkfSBmb3IgdmlzaXRvcnMgdGhhdCBkbyBub3QgbmVlZCB0byByZXR1cm4gcmVzdWx0cy4KICogQHBhcmFtIDxQPiB0aGUgdHlwZSBvZiB0aGUgYWRkaXRpb25hbCBwYXJhbWV0ZXIgdG8gdGhpcyB2aXNpdG9yJ3MKICogICAgICAgICAgICBtZXRob2RzLiAgVXNlIHtAY29kZSBWb2lkfSBmb3IgdmlzaXRvcnMgdGhhdCBkbyBub3QgbmVlZCBhbgogKiAgICAgICAgICAgIGFkZGl0aW9uYWwgcGFyYW1ldGVyLgogKgogKiBAYXV0aG9yIEpvc2VwaCBELiBEYXJjeQogKiBAYXV0aG9yIFNjb3R0IFNlbGlnbWFuCiAqIEBhdXRob3IgUGV0ZXIgdm9uIGRlciBBaCZlYWN1dGU7CiAqCiAqIEBzZWUgRWxlbWVudEtpbmRWaXNpdG9yNwogKiBAc2VlIEVsZW1lbnRLaW5kVmlzaXRvcjgKICogQHNlZSBFbGVtZW50S2luZFZpc2l0b3I5CiAqIEBzaW5jZSAxLjYKICovCkBTdXBwb3J0ZWRTb3VyY2VWZXJzaW9uKFJFTEVBU0VfNikKcHVibGljIGNsYXNzIEVsZW1lbnRLaW5kVmlzaXRvcjY8UiwgUD4KICAgICAgICAgICAgICAgICAgZXh0ZW5kcyBTaW1wbGVFbGVtZW50VmlzaXRvcjY8UiwgUD4gewogICAgLyoqCiAgICAgKiBDb25zdHJ1Y3RvciBmb3IgY29uY3JldGUgc3ViY2xhc3NlczsgdXNlcyB7QGNvZGUgbnVsbH0gZm9yIHRoZQogICAgICogZGVmYXVsdCB2YWx1ZS4KICAgICAqIEBkZXByZWNhdGVkIFJlbGVhc2UgNiBpcyBvYnNvbGV0ZTsgdXBkYXRlIHRvIGEgdmlzaXRvciBmb3IgYSBuZXdlcgogICAgICogcmVsZWFzZSBsZXZlbC4KICAgICAqLwogICAgQERlcHJlY2F0ZWQKICAgIHByb3RlY3RlZCBFbGVtZW50S2luZFZpc2l0b3I2KCkgewogICAgICAgIHN1cGVyKG51bGwpOwogICAgfQoKICAgIC8qKgogICAgICogQ29uc3RydWN0b3IgZm9yIGNvbmNyZXRlIHN1YmNsYXNzZXM7IHVzZXMgdGhlIGFyZ3VtZW50IGZvciB0aGUKICAgICAqIGRlZmF1bHQgdmFsdWUuCiAgICAgKgogICAgICogQHBhcmFtIGRlZmF1bHRWYWx1ZSB0aGUgdmFsdWUgdG8gYXNzaWduIHRvIHtAbGluayAjREVGQVVMVF9WQUxVRX0KICAgICAqIEBkZXByZWNhdGVkIFJlbGVhc2UgNiBpcyBvYnNvbGV0ZTsgdXBkYXRlIHRvIGEgdmlzaXRvciBmb3IgYSBuZXdlcgogICAgICogcmVsZWFzZSBsZXZlbC4KICAgICAqLwogICAgQERlcHJlY2F0ZWQKICAgIHByb3RlY3RlZCBFbGVtZW50S2luZFZpc2l0b3I2KFIgZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgc3VwZXIoZGVmYXVsdFZhbHVlKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqCiAgICAgKiBUaGUgZWxlbWVudCBhcmd1bWVudCBoYXMga2luZCB7QGNvZGUgUEFDS0FHRX0uCiAgICAgKgogICAgICogQHBhcmFtIGUge0Bpbmhlcml0RG9jfQogICAgICogQHBhcmFtIHAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiAge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0UGFja2FnZShQYWNrYWdlRWxlbWVudCBlLCBQIHApIHsKICAgICAgICBhc3NlcnQgZS5nZXRLaW5kKCkgPT0gUEFDS0FHRTogIkJhZCBraW5kIG9uIFBhY2thZ2VFbGVtZW50IjsKICAgICAgICByZXR1cm4gZGVmYXVsdEFjdGlvbihlLCBwKTsKICAgIH0KCiAgICAvKioKICAgICAqIFZpc2l0cyBhIHR5cGUgZWxlbWVudCwgZGlzcGF0Y2hpbmcgdG8gdGhlIHZpc2l0IG1ldGhvZCBmb3IgdGhlCiAgICAgKiBzcGVjaWZpYyB7QGxpbmtwbGFpbiBFbGVtZW50S2luZCBraW5kfSBvZiB0eXBlLCB7QGNvZGUKICAgICAqIEFOTk9UQVRJT05fVFlQRX0sIHtAY29kZSBDTEFTU30sIHtAY29kZSBFTlVNfSwgb3Ige0Bjb2RlCiAgICAgKiBJTlRFUkZBQ0V9LgogICAgICoKICAgICAqIEBwYXJhbSBlIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gIHRoZSByZXN1bHQgb2YgdGhlIGtpbmQtc3BlY2lmaWMgdmlzaXQgbWV0aG9kCiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRUeXBlKFR5cGVFbGVtZW50IGUsIFAgcCkgewogICAgICAgIEVsZW1lbnRLaW5kIGsgPSBlLmdldEtpbmQoKTsKICAgICAgICBzd2l0Y2goaykgewogICAgICAgIGNhc2UgQU5OT1RBVElPTl9UWVBFOgogICAgICAgICAgICByZXR1cm4gdmlzaXRUeXBlQXNBbm5vdGF0aW9uVHlwZShlLCBwKTsKCiAgICAgICAgY2FzZSBDTEFTUzoKICAgICAgICAgICAgcmV0dXJuIHZpc2l0VHlwZUFzQ2xhc3MoZSwgcCk7CgogICAgICAgIGNhc2UgRU5VTToKICAgICAgICAgICAgcmV0dXJuIHZpc2l0VHlwZUFzRW51bShlLCBwKTsKCiAgICAgICAgY2FzZSBJTlRFUkZBQ0U6CiAgICAgICAgICAgIHJldHVybiB2aXNpdFR5cGVBc0ludGVyZmFjZShlLCBwKTsKCiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCJCYWQga2luZCAiICsgayArICIgZm9yIFR5cGVFbGVtZW50IiArIGUpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFZpc2l0cyBhbiB7QGNvZGUgQU5OT1RBVElPTl9UWVBFfSB0eXBlIGVsZW1lbnQgYnkgY2FsbGluZwogICAgICoge0Bjb2RlIGRlZmF1bHRBY3Rpb259LgogICAgICoKICAgICAqIEBwYXJhbSBlIHRoZSBlbGVtZW50IHRvIHZpc2l0CiAgICAgKiBAcGFyYW0gcCBhIHZpc2l0b3Itc3BlY2lmaWVkIHBhcmFtZXRlcgogICAgICogQHJldHVybiAgdGhlIHJlc3VsdCBvZiB7QGNvZGUgZGVmYXVsdEFjdGlvbn0KICAgICAqLwogICAgcHVibGljIFIgdmlzaXRUeXBlQXNBbm5vdGF0aW9uVHlwZShUeXBlRWxlbWVudCBlLCBQIHApIHsKICAgICAgICByZXR1cm4gZGVmYXVsdEFjdGlvbihlLCBwKTsKICAgIH0KCiAgICAvKioKICAgICAqIFZpc2l0cyBhIHtAY29kZSBDTEFTU30gdHlwZSBlbGVtZW50IGJ5IGNhbGxpbmcge0Bjb2RlCiAgICAgKiBkZWZhdWx0QWN0aW9ufS4KICAgICAqCiAgICAgKiBAcGFyYW0gZSB0aGUgZWxlbWVudCB0byB2aXNpdAogICAgICogQHBhcmFtIHAgYSB2aXNpdG9yLXNwZWNpZmllZCBwYXJhbWV0ZXIKICAgICAqIEByZXR1cm4gIHRoZSByZXN1bHQgb2Yge0Bjb2RlIGRlZmF1bHRBY3Rpb259CiAgICAgKi8KICAgIHB1YmxpYyBSIHZpc2l0VHlwZUFzQ2xhc3MoVHlwZUVsZW1lbnQgZSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIGRlZmF1bHRBY3Rpb24oZSwgcCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBWaXNpdHMgYW4ge0Bjb2RlIEVOVU19IHR5cGUgZWxlbWVudCBieSBjYWxsaW5nIHtAY29kZQogICAgICogZGVmYXVsdEFjdGlvbn0uCiAgICAgKgogICAgICogQHBhcmFtIGUgdGhlIGVsZW1lbnQgdG8gdmlzaXQKICAgICAqIEBwYXJhbSBwIGEgdmlzaXRvci1zcGVjaWZpZWQgcGFyYW1ldGVyCiAgICAgKiBAcmV0dXJuICB0aGUgcmVzdWx0IG9mIHtAY29kZSBkZWZhdWx0QWN0aW9ufQogICAgICovCiAgICBwdWJsaWMgUiB2aXNpdFR5cGVBc0VudW0oVHlwZUVsZW1lbnQgZSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIGRlZmF1bHRBY3Rpb24oZSwgcCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBWaXNpdHMgYW4ge0Bjb2RlIElOVEVSRkFDRX0gdHlwZSBlbGVtZW50IGJ5IGNhbGxpbmcge0Bjb2RlCiAgICAgKiBkZWZhdWx0QWN0aW9ufS4KICAgICAqLgogICAgICogQHBhcmFtIGUgdGhlIGVsZW1lbnQgdG8gdmlzaXQKICAgICAqIEBwYXJhbSBwIGEgdmlzaXRvci1zcGVjaWZpZWQgcGFyYW1ldGVyCiAgICAgKiBAcmV0dXJuICB0aGUgcmVzdWx0IG9mIHtAY29kZSBkZWZhdWx0QWN0aW9ufQogICAgICovCiAgICBwdWJsaWMgUiB2aXNpdFR5cGVBc0ludGVyZmFjZShUeXBlRWxlbWVudCBlLCBQIHApIHsKICAgICAgICByZXR1cm4gZGVmYXVsdEFjdGlvbihlLCBwKTsKICAgIH0KCiAgICAvKioKICAgICAqIFZpc2l0cyBhIHZhcmlhYmxlIGVsZW1lbnQsIGRpc3BhdGNoaW5nIHRvIHRoZSB2aXNpdCBtZXRob2QgZm9yCiAgICAgKiB0aGUgc3BlY2lmaWMge0BsaW5rcGxhaW4gRWxlbWVudEtpbmQga2luZH0gb2YgdmFyaWFibGUsIHtAY29kZQogICAgICogRU5VTV9DT05TVEFOVH0sIHtAY29kZSBFWENFUFRJT05fUEFSQU1FVEVSfSwge0Bjb2RlIEZJRUxEfSwKICAgICAqIHtAY29kZSBMT0NBTF9WQVJJQUJMRX0sIHtAY29kZSBQQVJBTUVURVJ9LCBvciB7QGNvZGUgUkVTT1VSQ0VfVkFSSUFCTEV9LgogICAgICoKICAgICAqIEBwYXJhbSBlIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gIHRoZSByZXN1bHQgb2YgdGhlIGtpbmQtc3BlY2lmaWMgdmlzaXQgbWV0aG9kCiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIFIgdmlzaXRWYXJpYWJsZShWYXJpYWJsZUVsZW1lbnQgZSwgUCBwKSB7CiAgICAgICAgRWxlbWVudEtpbmQgayA9IGUuZ2V0S2luZCgpOwogICAgICAgIHN3aXRjaChrKSB7CiAgICAgICAgY2FzZSBFTlVNX0NPTlNUQU5UOgogICAgICAgICAgICByZXR1cm4gdmlzaXRWYXJpYWJsZUFzRW51bUNvbnN0YW50KGUsIHApOwoKICAgICAgICBjYXNlIEVYQ0VQVElPTl9QQVJBTUVURVI6CiAgICAgICAgICAgIHJldHVybiB2aXNpdFZhcmlhYmxlQXNFeGNlcHRpb25QYXJhbWV0ZXIoZSwgcCk7CgogICAgICAgIGNhc2UgRklFTEQ6CiAgICAgICAgICAgIHJldHVybiB2aXNpdFZhcmlhYmxlQXNGaWVsZChlLCBwKTsKCiAgICAgICAgY2FzZSBMT0NBTF9WQVJJQUJMRToKICAgICAgICAgICAgcmV0dXJuIHZpc2l0VmFyaWFibGVBc0xvY2FsVmFyaWFibGUoZSwgcCk7CgogICAgICAgIGNhc2UgUEFSQU1FVEVSOgogICAgICAgICAgICByZXR1cm4gdmlzaXRWYXJpYWJsZUFzUGFyYW1ldGVyKGUsIHApOwoKICAgICAgICBjYXNlIFJFU09VUkNFX1ZBUklBQkxFOgogICAgICAgICAgICByZXR1cm4gdmlzaXRWYXJpYWJsZUFzUmVzb3VyY2VWYXJpYWJsZShlLCBwKTsKCiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCJCYWQga2luZCAiICsgayArICIgZm9yIFZhcmlhYmxlRWxlbWVudCIgKyBlKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBWaXNpdHMgYW4ge0Bjb2RlIEVOVU1fQ09OU1RBTlR9IHZhcmlhYmxlIGVsZW1lbnQgYnkgY2FsbGluZwogICAgICoge0Bjb2RlIGRlZmF1bHRBY3Rpb259LgogICAgICoKICAgICAqIEBwYXJhbSBlIHRoZSBlbGVtZW50IHRvIHZpc2l0CiAgICAgKiBAcGFyYW0gcCBhIHZpc2l0b3Itc3BlY2lmaWVkIHBhcmFtZXRlcgogICAgICogQHJldHVybiAgdGhlIHJlc3VsdCBvZiB7QGNvZGUgZGVmYXVsdEFjdGlvbn0KICAgICAqLwogICAgcHVibGljIFIgdmlzaXRWYXJpYWJsZUFzRW51bUNvbnN0YW50KFZhcmlhYmxlRWxlbWVudCBlLCBQIHApIHsKICAgICAgICByZXR1cm4gZGVmYXVsdEFjdGlvbihlLCBwKTsKICAgIH0KCiAgICAvKioKICAgICAqIFZpc2l0cyBhbiB7QGNvZGUgRVhDRVBUSU9OX1BBUkFNRVRFUn0gdmFyaWFibGUgZWxlbWVudCBieSBjYWxsaW5nCiAgICAgKiB7QGNvZGUgZGVmYXVsdEFjdGlvbn0uCiAgICAgKgogICAgICogQHBhcmFtIGUgdGhlIGVsZW1lbnQgdG8gdmlzaXQKICAgICAqIEBwYXJhbSBwIGEgdmlzaXRvci1zcGVjaWZpZWQgcGFyYW1ldGVyCiAgICAgKiBAcmV0dXJuICB0aGUgcmVzdWx0IG9mIHtAY29kZSBkZWZhdWx0QWN0aW9ufQogICAgICovCiAgICBwdWJsaWMgUiB2aXNpdFZhcmlhYmxlQXNFeGNlcHRpb25QYXJhbWV0ZXIoVmFyaWFibGVFbGVtZW50IGUsIFAgcCkgewogICAgICAgIHJldHVybiBkZWZhdWx0QWN0aW9uKGUsIHApOwogICAgfQoKICAgIC8qKgogICAgICogVmlzaXRzIGEge0Bjb2RlIEZJRUxEfSB2YXJpYWJsZSBlbGVtZW50IGJ5IGNhbGxpbmcKICAgICAqIHtAY29kZSBkZWZhdWx0QWN0aW9ufS4KICAgICAqCiAgICAgKiBAcGFyYW0gZSB0aGUgZWxlbWVudCB0byB2aXNpdAogICAgICogQHBhcmFtIHAgYSB2aXNpdG9yLXNwZWNpZmllZCBwYXJhbWV0ZXIKICAgICAqIEByZXR1cm4gIHRoZSByZXN1bHQgb2Yge0Bjb2RlIGRlZmF1bHRBY3Rpb259CiAgICAgKi8KICAgIHB1YmxpYyBSIHZpc2l0VmFyaWFibGVBc0ZpZWxkKFZhcmlhYmxlRWxlbWVudCBlLCBQIHApIHsKICAgICAgICByZXR1cm4gZGVmYXVsdEFjdGlvbihlLCBwKTsKICAgIH0KCiAgICAvKioKICAgICAqIFZpc2l0cyBhIHtAY29kZSBMT0NBTF9WQVJJQUJMRX0gdmFyaWFibGUgZWxlbWVudCBieSBjYWxsaW5nCiAgICAgKiB7QGNvZGUgZGVmYXVsdEFjdGlvbn0uCiAgICAgKgogICAgICogQHBhcmFtIGUgdGhlIGVsZW1lbnQgdG8gdmlzaXQKICAgICAqIEBwYXJhbSBwIGEgdmlzaXRvci1zcGVjaWZpZWQgcGFyYW1ldGVyCiAgICAgKiBAcmV0dXJuICB0aGUgcmVzdWx0IG9mIHtAY29kZSBkZWZhdWx0QWN0aW9ufQogICAgICovCiAgICBwdWJsaWMgUiB2aXNpdFZhcmlhYmxlQXNMb2NhbFZhcmlhYmxlKFZhcmlhYmxlRWxlbWVudCBlLCBQIHApIHsKICAgICAgICByZXR1cm4gZGVmYXVsdEFjdGlvbihlLCBwKTsKICAgIH0KCiAgICAvKioKICAgICAqIFZpc2l0cyBhIHtAY29kZSBQQVJBTUVURVJ9IHZhcmlhYmxlIGVsZW1lbnQgYnkgY2FsbGluZwogICAgICoge0Bjb2RlIGRlZmF1bHRBY3Rpb259LgogICAgICoKICAgICAqIEBwYXJhbSBlIHRoZSBlbGVtZW50IHRvIHZpc2l0CiAgICAgKiBAcGFyYW0gcCBhIHZpc2l0b3Itc3BlY2lmaWVkIHBhcmFtZXRlcgogICAgICogQHJldHVybiAgdGhlIHJlc3VsdCBvZiB7QGNvZGUgZGVmYXVsdEFjdGlvbn0KICAgICAqLwogICAgcHVibGljIFIgdmlzaXRWYXJpYWJsZUFzUGFyYW1ldGVyKFZhcmlhYmxlRWxlbWVudCBlLCBQIHApIHsKICAgICAgICByZXR1cm4gZGVmYXVsdEFjdGlvbihlLCBwKTsKICAgIH0KCiAgICAvKioKICAgICAqIFZpc2l0cyBhIHtAY29kZSBSRVNPVVJDRV9WQVJJQUJMRX0gdmFyaWFibGUgZWxlbWVudCBieSBjYWxsaW5nCiAgICAgKiB7QGNvZGUgdmlzaXRVbmtub3dufS4KICAgICAqCiAgICAgKiBAcGFyYW0gZSB0aGUgZWxlbWVudCB0byB2aXNpdAogICAgICogQHBhcmFtIHAgYSB2aXNpdG9yLXNwZWNpZmllZCBwYXJhbWV0ZXIKICAgICAqIEByZXR1cm4gIHRoZSByZXN1bHQgb2Yge0Bjb2RlIHZpc2l0VW5rbm93bn0KICAgICAqCiAgICAgKiBAc2luY2UgMS43CiAgICAgKi8KICAgIHB1YmxpYyBSIHZpc2l0VmFyaWFibGVBc1Jlc291cmNlVmFyaWFibGUoVmFyaWFibGVFbGVtZW50IGUsIFAgcCkgewogICAgICAgIHJldHVybiB2aXNpdFVua25vd24oZSwgcCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBWaXNpdHMgYW4gZXhlY3V0YWJsZSBlbGVtZW50LCBkaXNwYXRjaGluZyB0byB0aGUgdmlzaXQgbWV0aG9kCiAgICAgKiBmb3IgdGhlIHNwZWNpZmljIHtAbGlua3BsYWluIEVsZW1lbnRLaW5kIGtpbmR9IG9mIGV4ZWN1dGFibGUsCiAgICAgKiB7QGNvZGUgQ09OU1RSVUNUT1J9LCB7QGNvZGUgSU5TVEFOQ0VfSU5JVH0sIHtAY29kZSBNRVRIT0R9LCBvcgogICAgICoge0Bjb2RlIFNUQVRJQ19JTklUfS4KICAgICAqCiAgICAgKiBAcGFyYW0gZSB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuICB0aGUgcmVzdWx0IG9mIHRoZSBraW5kLXNwZWNpZmljIHZpc2l0IG1ldGhvZAogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0RXhlY3V0YWJsZShFeGVjdXRhYmxlRWxlbWVudCBlLCBQIHApIHsKICAgICAgICBFbGVtZW50S2luZCBrID0gZS5nZXRLaW5kKCk7CiAgICAgICAgc3dpdGNoKGspIHsKICAgICAgICBjYXNlIENPTlNUUlVDVE9SOgogICAgICAgICAgICByZXR1cm4gdmlzaXRFeGVjdXRhYmxlQXNDb25zdHJ1Y3RvcihlLCBwKTsKCiAgICAgICAgY2FzZSBJTlNUQU5DRV9JTklUOgogICAgICAgICAgICByZXR1cm4gdmlzaXRFeGVjdXRhYmxlQXNJbnN0YW5jZUluaXQoZSwgcCk7CgogICAgICAgIGNhc2UgTUVUSE9EOgogICAgICAgICAgICByZXR1cm4gdmlzaXRFeGVjdXRhYmxlQXNNZXRob2QoZSwgcCk7CgogICAgICAgIGNhc2UgU1RBVElDX0lOSVQ6CiAgICAgICAgICAgIHJldHVybiB2aXNpdEV4ZWN1dGFibGVBc1N0YXRpY0luaXQoZSwgcCk7CgogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigiQmFkIGtpbmQgIiArIGsgKyAiIGZvciBFeGVjdXRhYmxlRWxlbWVudCIgKyBlKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBWaXNpdHMgYSB7QGNvZGUgQ09OU1RSVUNUT1J9IGV4ZWN1dGFibGUgZWxlbWVudCBieSBjYWxsaW5nCiAgICAgKiB7QGNvZGUgZGVmYXVsdEFjdGlvbn0uCiAgICAgKgogICAgICogQHBhcmFtIGUgdGhlIGVsZW1lbnQgdG8gdmlzaXQKICAgICAqIEBwYXJhbSBwIGEgdmlzaXRvci1zcGVjaWZpZWQgcGFyYW1ldGVyCiAgICAgKiBAcmV0dXJuICB0aGUgcmVzdWx0IG9mIHtAY29kZSBkZWZhdWx0QWN0aW9ufQogICAgICovCiAgICBwdWJsaWMgUiB2aXNpdEV4ZWN1dGFibGVBc0NvbnN0cnVjdG9yKEV4ZWN1dGFibGVFbGVtZW50IGUsIFAgcCkgewogICAgICAgIHJldHVybiBkZWZhdWx0QWN0aW9uKGUsIHApOwogICAgfQoKICAgIC8qKgogICAgICogVmlzaXRzIGFuIHtAY29kZSBJTlNUQU5DRV9JTklUfSBleGVjdXRhYmxlIGVsZW1lbnQgYnkgY2FsbGluZwogICAgICoge0Bjb2RlIGRlZmF1bHRBY3Rpb259LgogICAgICoKICAgICAqIEBwYXJhbSBlIHRoZSBlbGVtZW50IHRvIHZpc2l0CiAgICAgKiBAcGFyYW0gcCBhIHZpc2l0b3Itc3BlY2lmaWVkIHBhcmFtZXRlcgogICAgICogQHJldHVybiAgdGhlIHJlc3VsdCBvZiB7QGNvZGUgZGVmYXVsdEFjdGlvbn0KICAgICAqLwogICAgcHVibGljIFIgdmlzaXRFeGVjdXRhYmxlQXNJbnN0YW5jZUluaXQoRXhlY3V0YWJsZUVsZW1lbnQgZSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIGRlZmF1bHRBY3Rpb24oZSwgcCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBWaXNpdHMgYSB7QGNvZGUgTUVUSE9EfSBleGVjdXRhYmxlIGVsZW1lbnQgYnkgY2FsbGluZwogICAgICoge0Bjb2RlIGRlZmF1bHRBY3Rpb259LgogICAgICoKICAgICAqIEBwYXJhbSBlIHRoZSBlbGVtZW50IHRvIHZpc2l0CiAgICAgKiBAcGFyYW0gcCBhIHZpc2l0b3Itc3BlY2lmaWVkIHBhcmFtZXRlcgogICAgICogQHJldHVybiAgdGhlIHJlc3VsdCBvZiB7QGNvZGUgZGVmYXVsdEFjdGlvbn0KICAgICAqLwogICAgcHVibGljIFIgdmlzaXRFeGVjdXRhYmxlQXNNZXRob2QoRXhlY3V0YWJsZUVsZW1lbnQgZSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIGRlZmF1bHRBY3Rpb24oZSwgcCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBWaXNpdHMgYSB7QGNvZGUgU1RBVElDX0lOSVR9IGV4ZWN1dGFibGUgZWxlbWVudCBieSBjYWxsaW5nCiAgICAgKiB7QGNvZGUgZGVmYXVsdEFjdGlvbn0uCiAgICAgKgogICAgICogQHBhcmFtIGUgdGhlIGVsZW1lbnQgdG8gdmlzaXQKICAgICAqIEBwYXJhbSBwIGEgdmlzaXRvci1zcGVjaWZpZWQgcGFyYW1ldGVyCiAgICAgKiBAcmV0dXJuICB0aGUgcmVzdWx0IG9mIHtAY29kZSBkZWZhdWx0QWN0aW9ufQogICAgICovCiAgICBwdWJsaWMgUiB2aXNpdEV4ZWN1dGFibGVBc1N0YXRpY0luaXQoRXhlY3V0YWJsZUVsZW1lbnQgZSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIGRlZmF1bHRBY3Rpb24oZSwgcCk7CiAgICB9CgoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICoKICAgICAqIFRoZSBlbGVtZW50IGFyZ3VtZW50IGhhcyBraW5kIHtAY29kZSBUWVBFX1BBUkFNRVRFUn0uCiAgICAgKgogICAgICogQHBhcmFtIGUge0Bpbmhlcml0RG9jfQogICAgICogQHBhcmFtIHAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiAge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBSIHZpc2l0VHlwZVBhcmFtZXRlcihUeXBlUGFyYW1ldGVyRWxlbWVudCBlLCBQIHApIHsKICAgICAgICBhc3NlcnQgZS5nZXRLaW5kKCkgPT0gVFlQRV9QQVJBTUVURVI6ICJCYWQga2luZCBvbiBUeXBlUGFyYW1ldGVyRWxlbWVudCI7CiAgICAgICAgcmV0dXJuIGRlZmF1bHRBY3Rpb24oZSwgcCk7CiAgICB9Cn0KUEsDBAoAAAgAAAY7qUrXrj3u+iAAAPogAAAqAAAAamF2YXgvbGFuZy9tb2RlbC91dGlsL0VsZW1lbnRTY2FubmVyNi5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDA1LCAyMDE3LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGphdmF4LmxhbmcubW9kZWwudXRpbDsKCmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuKjsKaW1wb3J0IGphdmF4LmFubm90YXRpb24ucHJvY2Vzc2luZy5TdXBwb3J0ZWRTb3VyY2VWZXJzaW9uOwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC5Tb3VyY2VWZXJzaW9uOwppbXBvcnQgc3RhdGljIGphdmF4LmxhbmcubW9kZWwuU291cmNlVmVyc2lvbi4qOwoKCi8qKgogKiBBIHNjYW5uaW5nIHZpc2l0b3Igb2YgcHJvZ3JhbSBlbGVtZW50cyB3aXRoIGRlZmF1bHQgYmVoYXZpb3IKICogYXBwcm9wcmlhdGUgZm9yIHRoZSB7QGxpbmsgU291cmNlVmVyc2lvbiNSRUxFQVNFXzYgUkVMRUFTRV82fQogKiBzb3VyY2UgdmVyc2lvbi4gIFRoZSA8Y29kZT52aXNpdDxpPlh5ejwvaT48L2NvZGU+IG1ldGhvZHMgaW4gdGhpcwogKiBjbGFzcyBzY2FuIHRoZWlyIGNvbXBvbmVudCBlbGVtZW50cyBieSBjYWxsaW5nIHtAY29kZSBzY2FufSBvbgogKiB0aGVpciB7QGxpbmtwbGFpbiBFbGVtZW50I2dldEVuY2xvc2VkRWxlbWVudHMgZW5jbG9zZWQgZWxlbWVudHN9LAogKiB7QGxpbmtwbGFpbiBFeGVjdXRhYmxlRWxlbWVudCNnZXRQYXJhbWV0ZXJzIHBhcmFtZXRlcnN9LCBldGMuLCBhcwogKiBpbmRpY2F0ZWQgaW4gdGhlIGluZGl2aWR1YWwgbWV0aG9kIHNwZWNpZmljYXRpb25zLiAgQSBzdWJjbGFzcyBjYW4KICogY29udHJvbCB0aGUgb3JkZXIgZWxlbWVudHMgYXJlIHZpc2l0ZWQgYnkgb3ZlcnJpZGluZyB0aGUKICogPGNvZGU+dmlzaXQ8aT5YeXo8L2k+PC9jb2RlPiBtZXRob2RzLiAgTm90ZSB0aGF0IGNsaWVudHMgb2YgYSBzY2FubmVyCiAqIG1heSBnZXQgdGhlIGRlc2lyZWQgYmVoYXZpb3IgYmUgaW52b2tpbmcge0Bjb2RlIHYuc2NhbihlLCBwKX0gcmF0aGVyCiAqIHRoYW4ge0Bjb2RlIHYudmlzaXQoZSwgcCl9IG9uIHRoZSByb290IG9iamVjdHMgb2YgaW50ZXJlc3QuCiAqCiAqIDxwPldoZW4gYSBzdWJjbGFzcyBvdmVycmlkZXMgYSA8Y29kZT52aXNpdDxpPlh5ejwvaT48L2NvZGU+IG1ldGhvZCwgdGhlCiAqIG5ldyBtZXRob2QgY2FuIGNhdXNlIHRoZSBlbmNsb3NlZCBlbGVtZW50cyB0byBiZSBzY2FubmVkIGluIHRoZQogKiBkZWZhdWx0IHdheSBieSBjYWxsaW5nIDxjb2RlPnN1cGVyLnZpc2l0PGk+WHl6PC9pPjwvY29kZT4uICBJbiB0aGlzCiAqIGZhc2hpb24sIHRoZSBjb25jcmV0ZSB2aXNpdG9yIGNhbiBjb250cm9sIHRoZSBvcmRlcmluZyBvZiB0cmF2ZXJzYWwKICogb3ZlciB0aGUgY29tcG9uZW50IGVsZW1lbnRzIHdpdGggcmVzcGVjdCB0byB0aGUgYWRkaXRpb25hbAogKiBwcm9jZXNzaW5nOyBmb3IgZXhhbXBsZSwgY29uc2lzdGVudGx5IGNhbGxpbmcKICogPGNvZGU+c3VwZXIudmlzaXQ8aT5YeXo8L2k+PC9jb2RlPiBhdCB0aGUgc3RhcnQgb2YgdGhlIG92ZXJyaWRkZW4KICogbWV0aG9kcyB3aWxsIHlpZWxkIGEgcHJlb3JkZXIgdHJhdmVyc2FsLCBldGMuICBJZiB0aGUgY29tcG9uZW50CiAqIGVsZW1lbnRzIHNob3VsZCBiZSB0cmF2ZXJzZWQgaW4gc29tZSBvdGhlciBvcmRlciwgaW5zdGVhZCBvZgogKiBjYWxsaW5nIDxjb2RlPnN1cGVyLnZpc2l0PGk+WHl6PC9pPjwvY29kZT4sIGFuIG92ZXJyaWRpbmcgdmlzaXQgbWV0aG9kCiAqIHNob3VsZCBjYWxsIHtAY29kZSBzY2FufSB3aXRoIHRoZSBlbGVtZW50cyBpbiB0aGUgZGVzaXJlZCBvcmRlci4KICoKICogPHA+IE1ldGhvZHMgaW4gdGhpcyBjbGFzcyBtYXkgYmUgb3ZlcnJpZGRlbiBzdWJqZWN0IHRvIHRoZWlyCiAqIGdlbmVyYWwgY29udHJhY3QuICBOb3RlIHRoYXQgYW5ub3RhdGluZyBtZXRob2RzIGluIGNvbmNyZXRlCiAqIHN1YmNsYXNzZXMgd2l0aCB7QGxpbmsgamF2YS5sYW5nLk92ZXJyaWRlIEBPdmVycmlkZX0gd2lsbCBoZWxwCiAqIGVuc3VyZSB0aGF0IG1ldGhvZHMgYXJlIG92ZXJyaWRkZW4gYXMgaW50ZW5kZWQuCiAqCiAqIDxwPiA8Yj5XQVJOSU5HOjwvYj4gVGhlIHtAY29kZSBFbGVtZW50VmlzaXRvcn0gaW50ZXJmYWNlCiAqIGltcGxlbWVudGVkIGJ5IHRoaXMgY2xhc3MgbWF5IGhhdmUgbWV0aG9kcyBhZGRlZCB0byBpdCBpbiB0aGUKICogZnV0dXJlIHRvIGFjY29tbW9kYXRlIG5ldywgY3VycmVudGx5IHVua25vd24sIGxhbmd1YWdlIHN0cnVjdHVyZXMKICogYWRkZWQgdG8gZnV0dXJlIHZlcnNpb25zIG9mIHRoZSBKYXZhJnRyYWRlOyBwcm9ncmFtbWluZyBsYW5ndWFnZS4KICogVGhlcmVmb3JlLCBtZXRob2RzIHdob3NlIG5hbWVzIGJlZ2luIHdpdGgge0Bjb2RlICJ2aXNpdCJ9IG1heSBiZQogKiBhZGRlZCB0byB0aGlzIGNsYXNzIGluIHRoZSBmdXR1cmU7IHRvIGF2b2lkIGluY29tcGF0aWJpbGl0aWVzLAogKiBjbGFzc2VzIHdoaWNoIGV4dGVuZCB0aGlzIGNsYXNzIHNob3VsZCBub3QgZGVjbGFyZSBhbnkgaW5zdGFuY2UKICogbWV0aG9kcyB3aXRoIG5hbWVzIGJlZ2lubmluZyB3aXRoIHtAY29kZSAidmlzaXQifS4KICoKICogPHA+V2hlbiBzdWNoIGEgbmV3IHZpc2l0IG1ldGhvZCBpcyBhZGRlZCwgdGhlIGRlZmF1bHQKICogaW1wbGVtZW50YXRpb24gaW4gdGhpcyBjbGFzcyB3aWxsIGJlIHRvIGNhbGwgdGhlIHtAbGluawogKiAjdmlzaXRVbmtub3duIHZpc2l0VW5rbm93bn0gbWV0aG9kLiAgQSBuZXcgZWxlbWVudCBzY2FubmVyIHZpc2l0b3IKICogY2xhc3Mgd2lsbCBhbHNvIGJlIGludHJvZHVjZWQgdG8gY29ycmVzcG9uZCB0byB0aGUgbmV3IGxhbmd1YWdlCiAqIGxldmVsOyB0aGlzIHZpc2l0b3Igd2lsbCBoYXZlIGRpZmZlcmVudCBkZWZhdWx0IGJlaGF2aW9yIGZvciB0aGUKICogdmlzaXQgbWV0aG9kIGluIHF1ZXN0aW9uLiAgV2hlbiB0aGUgbmV3IHZpc2l0b3IgaXMgaW50cm9kdWNlZCwgYWxsCiAqIG9yIHBvcnRpb25zIG9mIHRoaXMgdmlzaXRvciBtYXkgYmUgZGVwcmVjYXRlZC4KICoKICogQHBhcmFtIDxSPiB0aGUgcmV0dXJuIHR5cGUgb2YgdGhpcyB2aXNpdG9yJ3MgbWV0aG9kcy4gIFVzZSB7QGxpbmsKICogICAgICAgICAgICBWb2lkfSBmb3IgdmlzaXRvcnMgdGhhdCBkbyBub3QgbmVlZCB0byByZXR1cm4gcmVzdWx0cy4KICogQHBhcmFtIDxQPiB0aGUgdHlwZSBvZiB0aGUgYWRkaXRpb25hbCBwYXJhbWV0ZXIgdG8gdGhpcyB2aXNpdG9yJ3MKICogICAgICAgICAgICBtZXRob2RzLiAgVXNlIHtAY29kZSBWb2lkfSBmb3IgdmlzaXRvcnMgdGhhdCBkbyBub3QgbmVlZCBhbgogKiAgICAgICAgICAgIGFkZGl0aW9uYWwgcGFyYW1ldGVyLgogKgogKiBAYXV0aG9yIEpvc2VwaCBELiBEYXJjeQogKiBAYXV0aG9yIFNjb3R0IFNlbGlnbWFuCiAqIEBhdXRob3IgUGV0ZXIgdm9uIGRlciBBaCZlYWN1dGU7CiAqCiAqIEBzZWUgRWxlbWVudFNjYW5uZXI3CiAqIEBzZWUgRWxlbWVudFNjYW5uZXI4CiAqIEBzZWUgRWxlbWVudFNjYW5uZXI5CiAqIEBzaW5jZSAxLjYKICovCkBTdXBwb3J0ZWRTb3VyY2VWZXJzaW9uKFJFTEVBU0VfNikKcHVibGljIGNsYXNzIEVsZW1lbnRTY2FubmVyNjxSLCBQPiBleHRlbmRzIEFic3RyYWN0RWxlbWVudFZpc2l0b3I2PFIsIFA+IHsKICAgIC8qKgogICAgICogVGhlIHNwZWNpZmllZCBkZWZhdWx0IHZhbHVlLgogICAgICovCiAgICBwcm90ZWN0ZWQgZmluYWwgUiBERUZBVUxUX1ZBTFVFOwoKICAgIC8qKgogICAgICogQ29uc3RydWN0b3IgZm9yIGNvbmNyZXRlIHN1YmNsYXNzZXM7IHVzZXMge0Bjb2RlIG51bGx9IGZvciB0aGUKICAgICAqIGRlZmF1bHQgdmFsdWUuCiAgICAgKiBAZGVwcmVjYXRlZCBSZWxlYXNlIDYgaXMgb2Jzb2xldGU7IHVwZGF0ZSB0byBhIHZpc2l0b3IgZm9yIGEgbmV3ZXIKICAgICAqIHJlbGVhc2UgbGV2ZWwuCiAgICAgKi8KICAgIEBEZXByZWNhdGVkCiAgICBwcm90ZWN0ZWQgRWxlbWVudFNjYW5uZXI2KCl7CiAgICAgICAgREVGQVVMVF9WQUxVRSA9IG51bGw7CiAgICB9CgogICAgLyoqCiAgICAgKiBDb25zdHJ1Y3RvciBmb3IgY29uY3JldGUgc3ViY2xhc3NlczsgdXNlcyB0aGUgYXJndW1lbnQgZm9yIHRoZQogICAgICogZGVmYXVsdCB2YWx1ZS4KICAgICAqCiAgICAgKiBAcGFyYW0gZGVmYXVsdFZhbHVlIHRoZSBkZWZhdWx0IHZhbHVlCiAgICAgKiBAZGVwcmVjYXRlZCBSZWxlYXNlIDYgaXMgb2Jzb2xldGU7IHVwZGF0ZSB0byBhIHZpc2l0b3IgZm9yIGEgbmV3ZXIKICAgICAqIHJlbGVhc2UgbGV2ZWwuCiAgICAgKi8KICAgIEBEZXByZWNhdGVkCiAgICBwcm90ZWN0ZWQgRWxlbWVudFNjYW5uZXI2KFIgZGVmYXVsdFZhbHVlKXsKICAgICAgICBERUZBVUxUX1ZBTFVFID0gZGVmYXVsdFZhbHVlOwogICAgfQoKICAgIC8qKgogICAgICogSXRlcmF0ZXMgb3ZlciB0aGUgZ2l2ZW4gZWxlbWVudHMgYW5kIGNhbGxzIHtAbGluawogICAgICogI3NjYW4oRWxlbWVudCwgT2JqZWN0KSBzY2FuKEVsZW1lbnQsIFApfSBvbiBlYWNoIG9uZS4gIFJldHVybnMKICAgICAqIHRoZSByZXN1bHQgb2YgdGhlIGxhc3QgY2FsbCB0byB7QGNvZGUgc2Nhbn0gb3Ige0Bjb2RlCiAgICAgKiBERUZBVUxUX1ZBTFVFfSBmb3IgYW4gZW1wdHkgaXRlcmFibGUuCiAgICAgKgogICAgICogQHBhcmFtIGl0ZXJhYmxlIHRoZSBlbGVtZW50cyB0byBzY2FuCiAgICAgKiBAcGFyYW0gIHAgYWRkaXRpb25hbCBwYXJhbWV0ZXIKICAgICAqIEByZXR1cm4gdGhlIHNjYW4gb2YgdGhlIGxhc3QgZWxlbWVudCBvciB7QGNvZGUgREVGQVVMVF9WQUxVRX0gaWYgbm8gZWxlbWVudHMKICAgICAqLwogICAgcHVibGljIGZpbmFsIFIgc2NhbihJdGVyYWJsZTw/IGV4dGVuZHMgRWxlbWVudD4gaXRlcmFibGUsIFAgcCkgewogICAgICAgIFIgcmVzdWx0ID0gREVGQVVMVF9WQUxVRTsKICAgICAgICBmb3IoRWxlbWVudCBlIDogaXRlcmFibGUpCiAgICAgICAgICAgIHJlc3VsdCA9IHNjYW4oZSwgcCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KCiAgICAvKioKICAgICAqIFByb2Nlc3NlcyBhbiBlbGVtZW50IGJ5IGNhbGxpbmcge0Bjb2RlIGUuYWNjZXB0KHRoaXMsIHApfTsKICAgICAqIHRoaXMgbWV0aG9kIG1heSBiZSBvdmVycmlkZGVuIGJ5IHN1YmNsYXNzZXMuCiAgICAgKgogICAgICogQHBhcmFtIGUgdGhlIGVsZW1lbnQgdG8gc2NhbgogICAgICogQHBhcmFtIHAgYSBzY2FubmVyLXNwZWNpZmllZCBwYXJhbWV0ZXIKICAgICAqIEByZXR1cm4gdGhlIHJlc3VsdCBvZiB2aXNpdGluZyB7QGNvZGUgZX0uCiAgICAgKi8KICAgIHB1YmxpYyBSIHNjYW4oRWxlbWVudCBlLCBQIHApIHsKICAgICAgICByZXR1cm4gZS5hY2NlcHQodGhpcywgcCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDb252ZW5pZW5jZSBtZXRob2QgZXF1aXZhbGVudCB0byB7QGNvZGUgdi5zY2FuKGUsIG51bGwpfS4KICAgICAqCiAgICAgKiBAcGFyYW0gZSB0aGUgZWxlbWVudCB0byBzY2FuCiAgICAgKiBAcmV0dXJuIHRoZSByZXN1bHQgb2Ygc2Nhbm5pbmcge0Bjb2RlIGV9LgogICAgICovCiAgICBwdWJsaWMgZmluYWwgUiBzY2FuKEVsZW1lbnQgZSkgewogICAgICAgIHJldHVybiBzY2FuKGUsIG51bGwpOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIHNjYW5zIHRoZSBlbmNsb3NlZCBlbGVtZW50cy4KICAgICAqCiAgICAgKiBAcGFyYW0gZSAge0Bpbmhlcml0RG9jfQogICAgICogQHBhcmFtIHAgIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gdGhlIHJlc3VsdCBvZiBzY2FubmluZwogICAgICovCiAgICBwdWJsaWMgUiB2aXNpdFBhY2thZ2UoUGFja2FnZUVsZW1lbnQgZSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIHNjYW4oZS5nZXRFbmNsb3NlZEVsZW1lbnRzKCksIHApOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIHNjYW5zIHRoZSBlbmNsb3NlZCBlbGVtZW50cy4KICAgICAqCiAgICAgKiBAcGFyYW0gZSAge0Bpbmhlcml0RG9jfQogICAgICogQHBhcmFtIHAgIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gdGhlIHJlc3VsdCBvZiBzY2FubmluZwogICAgICovCiAgICBwdWJsaWMgUiB2aXNpdFR5cGUoVHlwZUVsZW1lbnQgZSwgUCBwKSB7CiAgICAgICAgcmV0dXJuIHNjYW4oZS5nZXRFbmNsb3NlZEVsZW1lbnRzKCksIHApOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfQogICAgICoKICAgICAqIFRoaXMgaW1wbGVtZW50YXRpb24gc2NhbnMgdGhlIGVuY2xvc2VkIGVsZW1lbnRzLCB1bmxlc3MgdGhlCiAgICAgKiBlbGVtZW50IGlzIGEge0Bjb2RlIFJFU09VUkNFX1ZBUklBQkxFfSBpbiB3aGljaCBjYXNlIHtAY29kZQogICAgICogdmlzaXRVbmtub3dufSBpcyBjYWxsZWQuCiAgICAgKgogICAgICogQHBhcmFtIGUgIHtAaW5oZXJpdERvY30KICAgICAqIEBwYXJhbSBwICB7QGluaGVyaXREb2N9CiAgICAgKiBAcmV0dXJuIHRoZSByZXN1bHQgb2Ygc2Nhbm5pbmcKICAgICAqLwogICAgcHVibGljIFIgdmlzaXRWYXJpYWJsZShWYXJpYWJsZUVsZW1lbnQgZSwgUCBwKSB7CiAgICAgICAgaWYgKGUuZ2V0S2luZCgpICE9IEVsZW1lbnRLaW5kLlJFU09VUkNFX1ZBUklBQkxFKQogICAgICAgICAgICByZXR1cm4gc2NhbihlLmdldEVuY2xvc2VkRWxlbWVudHMoKSwgcCk7CiAgICAgICAgZWxzZQogICAgICAgICAgICByZXR1cm4gdmlzaXRVbmtub3duKGUsIHApOwogICAgfQoKICAgIC8qKgogICAgICoge0Bpbmhlcml0RG9jfSBUaGlzIGltcGxlbWVudGF0aW9uIHNjYW5zIHRoZSBwYXJhbWV0ZXJzLgogICAgICoKICAgICAqIEBwYXJhbSBlICB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiB0aGUgcmVzdWx0IG9mIHNjYW5uaW5nCiAgICAgKi8KICAgIHB1YmxpYyBSIHZpc2l0RXhlY3V0YWJsZShFeGVjdXRhYmxlRWxlbWVudCBlLCBQIHApIHsKICAgICAgICByZXR1cm4gc2NhbihlLmdldFBhcmFtZXRlcnMoKSwgcCk7CiAgICB9CgogICAgLyoqCiAgICAgKiB7QGluaGVyaXREb2N9IFRoaXMgaW1wbGVtZW50YXRpb24gc2NhbnMgdGhlIGVuY2xvc2VkIGVsZW1lbnRzLgogICAgICoKICAgICAqIEBwYXJhbSBlICB7QGluaGVyaXREb2N9CiAgICAgKiBAcGFyYW0gcCAge0Bpbmhlcml0RG9jfQogICAgICogQHJldHVybiB0aGUgcmVzdWx0IG9mIHNjYW5uaW5nCiAgICAgKi8KICAgIHB1YmxpYyBSIHZpc2l0VHlwZVBhcmFtZXRlcihUeXBlUGFyYW1ldGVyRWxlbWVudCBlLCBQIHApIHsKICAgICAgICByZXR1cm4gc2NhbihlLmdldEVuY2xvc2VkRWxlbWVudHMoKSwgcCk7CiAgICB9Cn0KUEsDBAoAAAgAAAY7qUpAx99jdQ8AAHUPAAAwAAAAamF2YXgvbGFuZy9tb2RlbC91dGlsL1NpbXBsZUVsZW1lbnRWaXNpdG9yOC5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDExLCAyMDE3LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGphdmF4LmxhbmcubW9kZWwudXRpbDsKCmltcG9ydCBqYXZheC5hbm5vdGF0aW9uLnByb2Nlc3NpbmcuU3VwcG9ydGVkU291cmNlVmVyc2lvbjsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuU291cmNlVmVyc2lvbjsKaW1wb3J0IHN0YXRpYyBqYXZheC5sYW5nLm1vZGVsLlNvdXJjZVZlcnNpb24uKjsKCi8qKgogKiBBIHNpbXBsZSB2aXNpdG9yIG9mIHByb2dyYW0gZWxlbWVudHMgd2l0aCBkZWZhdWx0IGJlaGF2aW9yCiAqIGFwcHJvcHJpYXRlIGZvciB0aGUge0BsaW5rIFNvdXJjZVZlcnNpb24jUkVMRUFTRV84IFJFTEVBU0VfOH0KICogc291cmNlIHZlcnNpb24uCiAqCiAqIFZpc2l0IG1ldGhvZHMgY29ycmVzcG9uZGluZyB0byB7QGNvZGUgUkVMRUFTRV84fSBhbmQgZWFybGllcgogKiBsYW5ndWFnZSBjb25zdHJ1Y3RzIGNhbGwge0BsaW5rICNkZWZhdWx0QWN0aW9uIGRlZmF1bHRBY3Rpb259LAogKiBwYXNzaW5nIHRoZWlyIGFyZ3VtZW50cyB0byB7QGNvZGUgZGVmYXVsdEFjdGlvbn0ncyBjb3JyZXNwb25kaW5nCiAqIHBhcmFtZXRlcnMuCiAqCiAqIDxwPiBNZXRob2RzIGluIHRoaXMgY2xhc3MgbWF5IGJlIG92ZXJyaWRkZW4gc3ViamVjdCB0byB0aGVpcgogKiBnZW5lcmFsIGNvbnRyYWN0LiAgTm90ZSB0aGF0IGFubm90YXRpbmcgbWV0aG9kcyBpbiBjb25jcmV0ZQogKiBzdWJjbGFzc2VzIHdpdGgge0BsaW5rIGphdmEubGFuZy5PdmVycmlkZSBAT3ZlcnJpZGV9IHdpbGwgaGVscAogKiBlbnN1cmUgdGhhdCBtZXRob2RzIGFyZSBvdmVycmlkZGVuIGFzIGludGVuZGVkLgogKgogKiA8cD4gPGI+V0FSTklORzo8L2I+IFRoZSB7QGNvZGUgRWxlbWVudFZpc2l0b3J9IGludGVyZmFjZQogKiBpbXBsZW1lbnRlZCBieSB0aGlzIGNsYXNzIG1heSBoYXZlIG1ldGhvZHMgYWRkZWQgdG8gaXQgaW4gdGhlCiAqIGZ1dHVyZSB0byBhY2NvbW1vZGF0ZSBuZXcsIGN1cnJlbnRseSB1bmtub3duLCBsYW5ndWFnZSBzdHJ1Y3R1cmVzCiAqIGFkZGVkIHRvIGZ1dHVyZSB2ZXJzaW9ucyBvZiB0aGUgSmF2YSZ0cmFkZTsgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2UuCiAqIFRoZXJlZm9yZSwgbWV0aG9kcyB3aG9zZSBuYW1lcyBiZWdpbiB3aXRoIHtAY29kZSAidmlzaXQifSBtYXkgYmUKICogYWRkZWQgdG8gdGhpcyBjbGFzcyBpbiB0aGUgZnV0dXJlOyB0byBhdm9pZCBpbmNvbXBhdGliaWxpdGllcywKICogY2xhc3NlcyB3aGljaCBleHRlbmQgdGhpcyBjbGFzcyBzaG91bGQgbm90IGRlY2xhcmUgYW55IGluc3RhbmNlCiAqIG1ldGhvZHMgd2l0aCBuYW1lcyBiZWdpbm5pbmcgd2l0aCB7QGNvZGUgInZpc2l0In0uCiAqCiAqIDxwPldoZW4gc3VjaCBhIG5ldyB2aXNpdCBtZXRob2QgaXMgYWRkZWQsIHRoZSBkZWZhdWx0CiAqIGltcGxlbWVudGF0aW9uIGluIHRoaXMgY2xhc3Mgd2lsbCBiZSB0byBjYWxsIHRoZSB7QGxpbmsKICogI3Zpc2l0VW5rbm93biB2aXNpdFVua25vd259IG1ldGhvZC4gIEEgbmV3IHNpbXBsZSBlbGVtZW50IHZpc2l0b3IKICogY2xhc3Mgd2lsbCBhbHNvIGJlIGludHJvZHVjZWQgdG8gY29ycmVzcG9uZCB0byB0aGUgbmV3IGxhbmd1YWdlCiAqIGxldmVsOyB0aGlzIHZpc2l0b3Igd2lsbCBoYXZlIGRpZmZlcmVudCBkZWZhdWx0IGJlaGF2aW9yIGZvciB0aGUKICogdmlzaXQgbWV0aG9kIGluIHF1ZXN0aW9uLiAgV2hlbiB0aGUgbmV3IHZpc2l0b3IgaXMgaW50cm9kdWNlZCwgYWxsCiAqIG9yIHBvcnRpb25zIG9mIHRoaXMgdmlzaXRvciBtYXkgYmUgZGVwcmVjYXRlZC4KICoKICogQHBhcmFtIDxSPiB0aGUgcmV0dXJuIHR5cGUgb2YgdGhpcyB2aXNpdG9yJ3MgbWV0aG9kcy4gIFVzZSB7QGNvZGUgVm9pZH0KICogICAgICAgICAgICAgZm9yIHZpc2l0b3JzIHRoYXQgZG8gbm90IG5lZWQgdG8gcmV0dXJuIHJlc3VsdHMuCiAqIEBwYXJhbSA8UD4gdGhlIHR5cGUgb2YgdGhlIGFkZGl0aW9uYWwgcGFyYW1ldGVyIHRvIHRoaXMgdmlzaXRvcidzIG1ldGhvZHMuICBVc2Uge0Bjb2RlIFZvaWR9CiAqICAgICAgICAgICAgICBmb3IgdmlzaXRvcnMgdGhhdCBkbyBub3QgbmVlZCBhbiBhZGRpdGlvbmFsIHBhcmFtZXRlci4KICoKICogQHNlZSBTaW1wbGVFbGVtZW50VmlzaXRvcjYKICogQHNlZSBTaW1wbGVFbGVtZW50VmlzaXRvcjcKICogQHNlZSBTaW1wbGVFbGVtZW50VmlzaXRvcjkKICogQHNpbmNlIDEuOAogKi8KQFN1cHBvcnRlZFNvdXJjZVZlcnNpb24oUkVMRUFTRV84KQpwdWJsaWMgY2xhc3MgU2ltcGxlRWxlbWVudFZpc2l0b3I4PFIsIFA+IGV4dGVuZHMgU2ltcGxlRWxlbWVudFZpc2l0b3I3PFIsIFA+IHsKICAgIC8qKgogICAgICogQ29uc3RydWN0b3IgZm9yIGNvbmNyZXRlIHN1YmNsYXNzZXM7IHVzZXMge0Bjb2RlIG51bGx9IGZvciB0aGUKICAgICAqIGRlZmF1bHQgdmFsdWUuCiAgICAgKi8KICAgIHByb3RlY3RlZCBTaW1wbGVFbGVtZW50VmlzaXRvcjgoKXsKICAgICAgICBzdXBlcihudWxsKTsKICAgIH0KCiAgICAvKioKICAgICAqIENvbnN0cnVjdG9yIGZvciBjb25jcmV0ZSBzdWJjbGFzc2VzOyB1c2VzIHRoZSBhcmd1bWVudCBmb3IgdGhlCiAgICAgKiBkZWZhdWx0IHZhbHVlLgogICAgICoKICAgICAqIEBwYXJhbSBkZWZhdWx0VmFsdWUgdGhlIHZhbHVlIHRvIGFzc2lnbiB0byB7QGxpbmsgI0RFRkFVTFRfVkFMVUV9CiAgICAgKi8KICAgIHByb3RlY3RlZCBTaW1wbGVFbGVtZW50VmlzaXRvcjgoUiBkZWZhdWx0VmFsdWUpewogICAgICAgIHN1cGVyKGRlZmF1bHRWYWx1ZSk7CiAgICB9Cn0KUEsDBAoAAAgAAAY7qUqhzbWa8xEAAPMRAAA6AAAAamF2YXgvbGFuZy9tb2RlbC91dGlsL0Fic3RyYWN0QW5ub3RhdGlvblZhbHVlVmlzaXRvcjYuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAxNywgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBqYXZheC5sYW5nLm1vZGVsLnV0aWw7CgoKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC4qOwoKaW1wb3J0IHN0YXRpYyBqYXZheC5sYW5nLm1vZGVsLlNvdXJjZVZlcnNpb24uKjsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuU291cmNlVmVyc2lvbjsKaW1wb3J0IGphdmF4LmFubm90YXRpb24ucHJvY2Vzc2luZy5TdXBwb3J0ZWRTb3VyY2VWZXJzaW9uOwoKLyoqCiAqIEEgc2tlbGV0YWwgdmlzaXRvciBmb3IgYW5ub3RhdGlvbiB2YWx1ZXMgd2l0aCBkZWZhdWx0IGJlaGF2aW9yCiAqIGFwcHJvcHJpYXRlIGZvciB0aGUge0BsaW5rIFNvdXJjZVZlcnNpb24jUkVMRUFTRV82IFJFTEVBU0VfNn0KICogc291cmNlIHZlcnNpb24uCiAqCiAqIDxwPiA8Yj5XQVJOSU5HOjwvYj4gVGhlIHtAY29kZSBBbm5vdGF0aW9uVmFsdWVWaXNpdG9yfSBpbnRlcmZhY2UKICogaW1wbGVtZW50ZWQgYnkgdGhpcyBjbGFzcyBtYXkgaGF2ZSBtZXRob2RzIGFkZGVkIHRvIGl0IGluIHRoZQogKiBmdXR1cmUgdG8gYWNjb21tb2RhdGUgbmV3LCBjdXJyZW50bHkgdW5rbm93biwgbGFuZ3VhZ2Ugc3RydWN0dXJlcwogKiBhZGRlZCB0byBmdXR1cmUgdmVyc2lvbnMgb2YgdGhlIEphdmEmdHJhZGU7IHByb2dyYW1taW5nIGxhbmd1YWdlLgogKiBUaGVyZWZvcmUsIG1ldGhvZHMgd2hvc2UgbmFtZXMgYmVnaW4gd2l0aCB7QGNvZGUgInZpc2l0In0gbWF5IGJlCiAqIGFkZGVkIHRvIHRoaXMgY2xhc3MgaW4gdGhlIGZ1dHVyZTsgdG8gYXZvaWQgaW5jb21wYXRpYmlsaXRpZXMsCiAqIGNsYXNzZXMgd2hpY2ggZXh0ZW5kIHRoaXMgY2xhc3Mgc2hvdWxkIG5vdCBkZWNsYXJlIGFueSBpbnN0YW5jZQogKiBtZXRob2RzIHdpdGggbmFtZXMgYmVnaW5uaW5nIHdpdGgge0Bjb2RlICJ2aXNpdCJ9LgogKgogKiA8cD5XaGVuIHN1Y2ggYSBuZXcgdmlzaXQgbWV0aG9kIGlzIGFkZGVkLCB0aGUgZGVmYXVsdAogKiBpbXBsZW1lbnRhdGlvbiBpbiB0aGlzIGNsYXNzIHdpbGwgYmUgdG8gY2FsbCB0aGUge0BsaW5rCiAqICN2aXNpdFVua25vd24gdmlzaXRVbmtub3dufSBtZXRob2QuICBBIG5ldyBhYnN0cmFjdCBhbm5vdGF0aW9uCiAqIHZhbHVlIHZpc2l0b3IgY2xhc3Mgd2lsbCBhbHNvIGJlIGludHJvZHVjZWQgdG8gY29ycmVzcG9uZCB0byB0aGUKICogbmV3IGxhbmd1YWdlIGxldmVsOyB0aGlzIHZpc2l0b3Igd2lsbCBoYXZlIGRpZmZlcmVudCBkZWZhdWx0CiAqIGJlaGF2aW9yIGZvciB0aGUgdmlzaXQgbWV0aG9kIGluIHF1ZXN0aW9uLiAgV2hlbiB0aGUgbmV3IHZpc2l0b3IgaXMKICogaW50cm9kdWNlZCwgYWxsIG9yIHBvcnRpb25zIG9mIHRoaXMgdmlzaXRvciBtYXkgYmUgZGVwcmVjYXRlZC4KICoKICogQHBhcmFtIDxSPiB0aGUgcmV0dXJuIHR5cGUgb2YgdGhpcyB2aXNpdG9yJ3MgbWV0aG9kcwogKiBAcGFyYW0gPFA+IHRoZSB0eXBlIG9mIHRoZSBhZGRpdGlvbmFsIHBhcmFtZXRlciB0byB0aGlzIHZpc2l0b3IncyBtZXRob2RzLgogKgogKiBAYXV0aG9yIEpvc2VwaCBELiBEYXJjeQogKiBAYXV0aG9yIFNjb3R0IFNlbGlnbWFuCiAqIEBhdXRob3IgUGV0ZXIgdm9uIGRlciBBaCZlYWN1dGU7CiAqCiAqIEBzZWUgQWJzdHJhY3RBbm5vdGF0aW9uVmFsdWVWaXNpdG9yNwogKiBAc2VlIEFic3RyYWN0QW5ub3RhdGlvblZhbHVlVmlzaXRvcjgKICogQHNlZSBBYnN0cmFjdEFubm90YXRpb25WYWx1ZVZpc2l0b3I5CiAqIEBzaW5jZSAxLjYKICovCkBTdXBwb3J0ZWRTb3VyY2VWZXJzaW9uKFJFTEVBU0VfNikKcHVibGljIGFic3RyYWN0IGNsYXNzIEFic3RyYWN0QW5ub3RhdGlvblZhbHVlVmlzaXRvcjY8UiwgUD4KICAgIGltcGxlbWVudHMgQW5ub3RhdGlvblZhbHVlVmlzaXRvcjxSLCBQPiB7CgogICAgLyoqCiAgICAgKiBDb25zdHJ1Y3RvciBmb3IgY29uY3JldGUgc3ViY2xhc3NlcyB0byBjYWxsLgogICAgICogQGRlcHJlY2F0ZWQgUmVsZWFzZSA2IGlzIG9ic29sZXRlOyB1cGRhdGUgdG8gYSB2aXNpdG9yIGZvciBhIG5ld2VyCiAgICAgKiByZWxlYXNlIGxldmVsLgogICAgICovCiAgICBARGVwcmVjYXRlZAogICAgcHJvdGVjdGVkIEFic3RyYWN0QW5ub3RhdGlvblZhbHVlVmlzaXRvcjYoKSB7fQoKICAgIC8qKgogICAgICogVmlzaXRzIGFueSBhbm5vdGF0aW9uIHZhbHVlIGFzIGlmIGJ5IHBhc3NpbmcgaXRzZWxmIHRvIHRoYXQKICAgICAqIHZhbHVlJ3Mge0BsaW5rIEFubm90YXRpb25WYWx1ZSNhY2NlcHQgYWNjZXB0fS4gIFRoZSBpbnZvY2F0aW9uCiAgICAgKiB7QGNvZGUgdi52aXNpdChhdiwgcCl9IGlzIGVxdWl2YWxlbnQgdG8ge0Bjb2RlIGF2LmFjY2VwdCh2LCBwKX0uCiAgICAgKiBAcGFyYW0gYXYge0Bpbmhlcml0RG9jfQogICAgICogQHBhcmFtIHAgIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZpbmFsIFIgdmlzaXQoQW5ub3RhdGlvblZhbHVlIGF2LCBQIHApIHsKICAgICAgICByZXR1cm4gYXYuYWNjZXB0KHRoaXMsIHApOwogICAgfQoKICAgIC8qKgogICAgICogVmlzaXRzIGFuIGFubm90YXRpb24gdmFsdWUgYXMgaWYgYnkgcGFzc2luZyBpdHNlbGYgdG8gdGhhdAogICAgICogdmFsdWUncyB7QGxpbmsgQW5ub3RhdGlvblZhbHVlI2FjY2VwdCBhY2NlcHR9IG1ldGhvZCBwYXNzaW5nCiAgICAgKiB7QGNvZGUgbnVsbH0gZm9yIHRoZSBhZGRpdGlvbmFsIHBhcmFtZXRlci4gIFRoZSBpbnZvY2F0aW9uCiAgICAgKiB7QGNvZGUgdi52aXNpdChhdil9IGlzIGVxdWl2YWxlbnQgdG8ge0Bjb2RlIGF2LmFjY2VwdCh2LAogICAgICogbnVsbCl9LgogICAgICogQHBhcmFtIGF2IHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIGZpbmFsIFIgdmlzaXQoQW5ub3RhdGlvblZhbHVlIGF2KSB7CiAgICAgICAgcmV0dXJuIGF2LmFjY2VwdCh0aGlzLCBudWxsKTsKICAgIH0KCiAgICAvKioKICAgICAqIHtAaW5oZXJpdERvY30KICAgICAqCiAgICAgKiBAaW1wbFNwZWMgVGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gb2YgdGhpcyBtZXRob2QgaW4ge0Bjb2RlCiAgICAgKiBBYnN0cmFjdEFubm90YXRpb25WYWx1ZVZpc2l0b3I2fSB3aWxsIGFsd2F5cyB0aHJvdyB7QGNvZGUKICAgICAqIG5ldyBVbmtub3duQW5ub3RhdGlvblZhbHVlRXhjZXB0aW9uKGF2LCBwKX0uICBUaGlzIGJlaGF2aW9yIGlzIG5vdAogICAgICogcmVxdWlyZWQgb2YgYSBzdWJjbGFzcy4KICAgICAqCiAgICAgKiBAcGFyYW0gYXYge0Bpbmhlcml0RG9jfQogICAgICogQHBhcmFtIHAgIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgUiB2aXNpdFVua25vd24oQW5ub3RhdGlvblZhbHVlIGF2LCBQIHApIHsKICAgICAgICB0aHJvdyBuZXcgVW5rbm93bkFubm90YXRpb25WYWx1ZUV4Y2VwdGlvbihhdiwgcCk7CiAgICB9Cn0KUEsDBAoAAAgAAAY7qUqLQR55EicAABInAAAoAAAAamF2YXgvbGFuZy9tb2RlbC9Bbm5vdGF0ZWRDb25zdHJ1Y3QuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAxMywgMjAxNywgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBqYXZheC5sYW5nLm1vZGVsOwoKaW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLio7CmltcG9ydCBqYXZhLnV0aWwuTGlzdDsKaW1wb3J0IGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC4qOwppbXBvcnQgamF2YXgubGFuZy5tb2RlbC50eXBlLio7CgovKioKICogUmVwcmVzZW50cyBhIGNvbnN0cnVjdCB0aGF0IGNhbiBiZSBhbm5vdGF0ZWQuCiAqCiAqIEEgY29uc3RydWN0IGlzIGVpdGhlciBhbiB7QGxpbmtwbGFpbgogKiBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuRWxlbWVudCBlbGVtZW50fSBvciBhIHtAbGlua3BsYWluCiAqIGphdmF4LmxhbmcubW9kZWwudHlwZS5UeXBlTWlycm9yIHR5cGV9LiAgQW5ub3RhdGlvbnMgb24gYW4gZWxlbWVudAogKiBhcmUgb24gYSA8ZW0+ZGVjbGFyYXRpb248L2VtPiwgd2hlcmVhcyBhbm5vdGF0aW9ucyBvbiBhIHR5cGUgYXJlIG9uCiAqIGEgc3BlY2lmaWMgPGVtPnVzZTwvZW0+IG9mIGEgdHlwZSBuYW1lLgogKgogKiBUaGUgdGVybXMgPGVtPmRpcmVjdGx5IHByZXNlbnQ8L2VtPiwgPGVtPnByZXNlbnQ8L2VtPiwKICogPGVtPmluZGlyZWN0bHkgcHJlc2VudDwvZW0+LCBhbmQgPGVtPmFzc29jaWF0ZWQgPC9lbT4gYXJlIHVzZWQKICogdGhyb3VnaG91dCB0aGlzIGludGVyZmFjZSB0byBkZXNjcmliZSBwcmVjaXNlbHkgd2hpY2ggYW5ub3RhdGlvbnMKICogYXJlIHJldHVybmVkIGJ5IHRoZSBtZXRob2RzIGRlZmluZWQgaGVyZWluLgogKgogKiA8cD5JbiB0aGUgZGVmaW5pdGlvbnMgYmVsb3csIGFuIGFubm90YXRpb24gPGk+QTwvaT4gaGFzIGFuCiAqIGFubm90YXRpb24gdHlwZSA8aT5BVDwvaT4uIElmIDxpPkFUPC9pPiBpcyBhIHJlcGVhdGFibGUgYW5ub3RhdGlvbgogKiB0eXBlLCB0aGUgdHlwZSBvZiB0aGUgY29udGFpbmluZyBhbm5vdGF0aW9uIGlzIDxpPkFUQzwvaT4uCiAqCiAqIDxwPkFubm90YXRpb24gPGk+QTwvaT4gaXMgPGVtPmRpcmVjdGx5IHByZXNlbnQ8L2VtPiBvbiBhIGNvbnN0cnVjdAogKiA8aT5DPC9pPiBpZiBlaXRoZXI6CiAqCiAqIDx1bD4KICoKICogPGxpPjxpPkE8L2k+IGlzIGV4cGxpY2l0bHkgb3IgaW1wbGljaXRseSBkZWNsYXJlZCBhcyBhcHBseWluZyB0bwogKiB0aGUgc291cmNlIGNvZGUgcmVwcmVzZW50YXRpb24gb2YgPGk+QzwvaT4uCiAqCiAqIDxwPlR5cGljYWxseSwgaWYgZXhhY3RseSBvbmUgYW5ub3RhdGlvbiBvZiB0eXBlIDxpPkFUPC9pPiBhcHBlYXJzIGluCiAqIHRoZSBzb3VyY2UgY29kZSBvZiByZXByZXNlbnRhdGlvbiBvZiA8aT5DPC9pPiwgdGhlbiA8aT5BPC9pPiBpcwogKiBleHBsaWNpdGx5IGRlY2xhcmVkIGFzIGFwcGx5aW5nIHRvIDxpPkM8L2k+LgogKgogKiBJZiB0aGVyZSBhcmUgbXVsdGlwbGUgYW5ub3RhdGlvbnMgb2YgdHlwZSA8aT5BVDwvaT4gcHJlc2VudCBvbgogKiA8aT5DPC9pPiwgdGhlbiBpZiA8aT5BVDwvaT4gaXMgcmVwZWF0YWJsZSBhbm5vdGF0aW9uIHR5cGUsIGFuCiAqIGFubm90YXRpb24gb2YgdHlwZSA8aT5BVEM8L2k+IGlzIHtAbGlua3BsYWluIGphdmF4LmxhbmcubW9kZWwudXRpbC5FbGVtZW50cyNnZXRPcmlnaW4oQW5ub3RhdGVkQ29uc3RydWN0LCBBbm5vdGF0aW9uTWlycm9yKSBpbXBsaWNpdGx5IGRlY2xhcmVkfSBvbiA8aT5DPC9pPi4KICoKICogPGxpPiBBIHJlcHJlc2VudGF0aW9uIG9mIDxpPkE8L2k+IGFwcGVhcnMgaW4gdGhlIGV4ZWN1dGFibGUgb3V0cHV0CiAqIGZvciA8aT5DPC9pPiwgc3VjaCBhcyB0aGUge0Bjb2RlIFJ1bnRpbWVWaXNpYmxlQW5ub3RhdGlvbnN9IG9yCiAqIHtAY29kZSBSdW50aW1lVmlzaWJsZVBhcmFtZXRlckFubm90YXRpb25zfSBhdHRyaWJ1dGVzIG9mIGEgY2xhc3MKICogZmlsZS4KICoKICogPC91bD4KICoKICogPHA+QW4gYW5ub3RhdGlvbiA8aT5BPC9pPiBpcyA8ZW0+cHJlc2VudDwvZW0+IG9uIGEKICogY29uc3RydWN0IDxpPkM8L2k+IGlmIGVpdGhlcjoKICogPHVsPgogKgogKiA8bGk+PGk+QTwvaT4gaXMgZGlyZWN0bHkgcHJlc2VudCBvbiA8aT5DPC9pPi4KICoKICogPGxpPk5vIGFubm90YXRpb24gb2YgdHlwZSA8aT5BVDwvaT4gaXMgZGlyZWN0bHkgcHJlc2VudCBvbgogKiA8aT5DPC9pPiwgYW5kIDxpPkM8L2k+IGlzIGEgY2xhc3MgYW5kIDxpPkFUPC9pPiBpcyBpbmhlcml0YWJsZQogKiBhbmQgPGk+QTwvaT4gaXMgcHJlc2VudCBvbiB0aGUgc3VwZXJjbGFzcyBvZiA8aT5DPC9pPi4KICoKICogPC91bD4KICoKICogQW4gYW5ub3RhdGlvbiA8aT5BPC9pPiBpcyA8ZW0+aW5kaXJlY3RseSBwcmVzZW50PC9lbT4gb24gYSBjb25zdHJ1Y3QKICogPGk+QzwvaT4gaWYgYm90aDoKICoKICogPHVsPgogKgogKiA8bGk+PGk+QVQ8L2k+IGlzIGEgcmVwZWF0YWJsZSBhbm5vdGF0aW9uIHR5cGUgd2l0aCBhIGNvbnRhaW5pbmcKICogYW5ub3RhdGlvbiB0eXBlIDxpPkFUQzwvaT4uCiAqCiAqIDxsaT5BbiBhbm5vdGF0aW9uIG9mIHR5cGUgPGk+QVRDPC9pPiBpcyBkaXJlY3RseSBwcmVzZW50IG9uCiAqIDxpPkM8L2k+IGFuZCA8aT5BPC9pPiBpcyBhbiBhbm5vdGF0aW9uIGluY2x1ZGVkIGluIHRoZSByZXN1bHQgb2YKICogY2FsbGluZyB0aGUge0Bjb2RlIHZhbHVlfSBtZXRob2Qgb2YgdGhlIGRpcmVjdGx5IHByZXNlbnQgYW5ub3RhdGlvbgogKiBvZiB0eXBlIDxpPkFUQzwvaT4uCiAqCiAqIDwvdWw+CiAqCiAqIEFuIGFubm90YXRpb24gPGk+QTwvaT4gaXMgPGVtPmFzc29jaWF0ZWQ8L2VtPiB3aXRoIGEgY29uc3RydWN0CiAqIDxpPkM8L2k+IGlmIGVpdGhlcjoKICoKICogPHVsPgogKgogKiA8bGk+IDxpPkE8L2k+IGlzIGRpcmVjdGx5IG9yIGluZGlyZWN0bHkgcHJlc2VudCBvbiA8aT5DPC9pPi4KICoKICogPGxpPiBObyBhbm5vdGF0aW9uIG9mIHR5cGUgPGk+QVQ8L2k+IGlzIGRpcmVjdGx5IG9yIGluZGlyZWN0bHkKICogcHJlc2VudCBvbiA8aT5DPC9pPiwgYW5kIDxpPkM8L2k+IGlzIGEgY2xhc3MsIGFuZCA8aT5BVDwvaT4gaXMKICogaW5oZXJpdGFibGUsIGFuZCA8aT5BPC9pPiBpcyBhc3NvY2lhdGVkIHdpdGggdGhlIHN1cGVyY2xhc3Mgb2YKICogPGk+QzwvaT4uCiAqCiAqIDwvdWw+CiAqCiAqIEBzaW5jZSAxLjgKICogQGpscyA5LjYgQW5ub3RhdGlvbiBUeXBlcwogKiBAamxzIDkuNi4zLjMgQEluaGVyaXRlZAogKi8KcHVibGljIGludGVyZmFjZSBBbm5vdGF0ZWRDb25zdHJ1Y3QgewogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBhbm5vdGF0aW9ucyB0aGF0IGFyZSA8ZW0+ZGlyZWN0bHkgcHJlc2VudDwvZW0+IG9uCiAgICAgKiB0aGlzIGNvbnN0cnVjdC4KICAgICAqCiAgICAgKiBAcmV0dXJuIHRoZSBhbm5vdGF0aW9ucyA8ZW0+ZGlyZWN0bHkgcHJlc2VudDwvZW0+IG9uIHRoaXMKICAgICAqIGNvbnN0cnVjdDsgYW4gZW1wdHkgbGlzdCBpZiB0aGVyZSBhcmUgbm9uZQogICAgICovCiAgICBMaXN0PD8gZXh0ZW5kcyBBbm5vdGF0aW9uTWlycm9yPiBnZXRBbm5vdGF0aW9uTWlycm9ycygpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGlzIGNvbnN0cnVjdCdzIGFubm90YXRpb24gb2YgdGhlIHNwZWNpZmllZCB0eXBlIGlmCiAgICAgKiBzdWNoIGFuIGFubm90YXRpb24gaXMgPGVtPnByZXNlbnQ8L2VtPiwgZWxzZSB7QGNvZGUgbnVsbH0uCiAgICAgKgogICAgICogPHA+IFRoZSBhbm5vdGF0aW9uIHJldHVybmVkIGJ5IHRoaXMgbWV0aG9kIGNvdWxkIGNvbnRhaW4gYW4gZWxlbWVudAogICAgICogd2hvc2UgdmFsdWUgaXMgb2YgdHlwZSB7QGNvZGUgQ2xhc3N9LgogICAgICogVGhpcyB2YWx1ZSBjYW5ub3QgYmUgcmV0dXJuZWQgZGlyZWN0bHk6ICBpbmZvcm1hdGlvbiBuZWNlc3NhcnkgdG8KICAgICAqIGxvY2F0ZSBhbmQgbG9hZCBhIGNsYXNzIChzdWNoIGFzIHRoZSBjbGFzcyBsb2FkZXIgdG8gdXNlKSBpcwogICAgICogbm90IGF2YWlsYWJsZSwgYW5kIHRoZSBjbGFzcyBtaWdodCBub3QgYmUgbG9hZGFibGUgYXQgYWxsLgogICAgICogQXR0ZW1wdGluZyB0byByZWFkIGEge0Bjb2RlIENsYXNzfSBvYmplY3QgYnkgaW52b2tpbmcgdGhlIHJlbGV2YW50CiAgICAgKiBtZXRob2Qgb24gdGhlIHJldHVybmVkIGFubm90YXRpb24KICAgICAqIHdpbGwgcmVzdWx0IGluIGEge0BsaW5rIE1pcnJvcmVkVHlwZUV4Y2VwdGlvbn0sCiAgICAgKiBmcm9tIHdoaWNoIHRoZSBjb3JyZXNwb25kaW5nIHtAbGluayBUeXBlTWlycm9yfSBtYXkgYmUgZXh0cmFjdGVkLgogICAgICogU2ltaWxhcmx5LCBhdHRlbXB0aW5nIHRvIHJlYWQgYSB7QGNvZGUgQ2xhc3NbXX0tdmFsdWVkIGVsZW1lbnQKICAgICAqIHdpbGwgcmVzdWx0IGluIGEge0BsaW5rIE1pcnJvcmVkVHlwZXNFeGNlcHRpb259LgogICAgICoKICAgICAqIDxibG9ja3F1b3RlPgogICAgICogPGk+Tm90ZTo8L2k+IFRoaXMgbWV0aG9kIGlzIHVubGlrZSBvdGhlcnMgaW4gdGhpcyBhbmQgcmVsYXRlZAogICAgICogaW50ZXJmYWNlcy4gIEl0IG9wZXJhdGVzIG9uIHJ1bnRpbWUgcmVmbGVjdGl2ZSBpbmZvcm1hdGlvbiAmbWRhc2g7CiAgICAgKiByZXByZXNlbnRhdGlvbnMgb2YgYW5ub3RhdGlvbiB0eXBlcyBjdXJyZW50bHkgbG9hZGVkIGludG8gdGhlCiAgICAgKiBWTSAmbWRhc2g7IHJhdGhlciB0aGFuIG9uIHRoZSByZXByZXNlbnRhdGlvbnMgZGVmaW5lZCBieSBhbmQgdXNlZAogICAgICogdGhyb3VnaG91dCB0aGVzZSBpbnRlcmZhY2VzLiAgQ29uc2VxdWVudGx5LCBjYWxsaW5nIG1ldGhvZHMgb24KICAgICAqIHRoZSByZXR1cm5lZCBhbm5vdGF0aW9uIG9iamVjdCBjYW4gdGhyb3cgbWFueSBvZiB0aGUgZXhjZXB0aW9ucwogICAgICogdGhhdCBjYW4gYmUgdGhyb3duIHdoZW4gY2FsbGluZyBtZXRob2RzIG9uIGFuIGFubm90YXRpb24gb2JqZWN0CiAgICAgKiByZXR1cm5lZCBieSBjb3JlIHJlZmxlY3Rpb24uICBUaGlzIG1ldGhvZCBpcyBpbnRlbmRlZCBmb3IKICAgICAqIGNhbGxlcnMgdGhhdCBhcmUgd3JpdHRlbiB0byBvcGVyYXRlIG9uIGEga25vd24sIGZpeGVkIHNldCBvZgogICAgICogYW5ub3RhdGlvbiB0eXBlcy4KICAgICAqIDwvYmxvY2txdW90ZT4KICAgICAqCiAgICAgKiBAcGFyYW0gPEE+ICB0aGUgYW5ub3RhdGlvbiB0eXBlCiAgICAgKiBAcGFyYW0gYW5ub3RhdGlvblR5cGUgIHRoZSB7QGNvZGUgQ2xhc3N9IG9iamVjdCBjb3JyZXNwb25kaW5nIHRvCiAgICAgKiAgICAgICAgICB0aGUgYW5ub3RhdGlvbiB0eXBlCiAgICAgKiBAcmV0dXJuIHRoaXMgY29uc3RydWN0J3MgYW5ub3RhdGlvbiBmb3IgdGhlIHNwZWNpZmllZAogICAgICogYW5ub3RhdGlvbiB0eXBlIGlmIHByZXNlbnQsIGVsc2Uge0Bjb2RlIG51bGx9CiAgICAgKgogICAgICogQHNlZSAjZ2V0QW5ub3RhdGlvbk1pcnJvcnMoKQogICAgICogQHNlZSBqYXZhLmxhbmcucmVmbGVjdC5Bbm5vdGF0ZWRFbGVtZW50I2dldEFubm90YXRpb24KICAgICAqIEBzZWUgRW51bUNvbnN0YW50Tm90UHJlc2VudEV4Y2VwdGlvbgogICAgICogQHNlZSBBbm5vdGF0aW9uVHlwZU1pc21hdGNoRXhjZXB0aW9uCiAgICAgKiBAc2VlIEluY29tcGxldGVBbm5vdGF0aW9uRXhjZXB0aW9uCiAgICAgKiBAc2VlIE1pcnJvcmVkVHlwZUV4Y2VwdGlvbgogICAgICogQHNlZSBNaXJyb3JlZFR5cGVzRXhjZXB0aW9uCiAgICAgKiBAamxzIDkuNi4xIEFubm90YXRpb24gVHlwZSBFbGVtZW50cwogICAgICovCiAgICA8QSBleHRlbmRzIEFubm90YXRpb24+IEEgZ2V0QW5ub3RhdGlvbihDbGFzczxBPiBhbm5vdGF0aW9uVHlwZSk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGFubm90YXRpb25zIHRoYXQgYXJlIDxlbT5hc3NvY2lhdGVkPC9lbT4gd2l0aCB0aGlzIGNvbnN0cnVjdC4KICAgICAqCiAgICAgKiBJZiB0aGVyZSBhcmUgbm8gYW5ub3RhdGlvbnMgYXNzb2NpYXRlZCB3aXRoIHRoaXMgY29uc3RydWN0LCB0aGUKICAgICAqIHJldHVybiB2YWx1ZSBpcyBhbiBhcnJheSBvZiBsZW5ndGggMC4KICAgICAqCiAgICAgKiBUaGUgb3JkZXIgb2YgYW5ub3RhdGlvbnMgd2hpY2ggYXJlIGRpcmVjdGx5IG9yIGluZGlyZWN0bHkKICAgICAqIHByZXNlbnQgb24gYSBjb25zdHJ1Y3QgPGk+QzwvaT4gaXMgY29tcHV0ZWQgYXMgaWYgaW5kaXJlY3RseSBwcmVzZW50CiAgICAgKiBhbm5vdGF0aW9ucyBvbiA8aT5DPC9pPiBhcmUgZGlyZWN0bHkgcHJlc2VudCBvbiA8aT5DPC9pPiBpbiBwbGFjZSBvZiB0aGVpcgogICAgICogY29udGFpbmVyIGFubm90YXRpb24sIGluIHRoZSBvcmRlciBpbiB3aGljaCB0aGV5IGFwcGVhciBpbiB0aGUKICAgICAqIHZhbHVlIGVsZW1lbnQgb2YgdGhlIGNvbnRhaW5lciBhbm5vdGF0aW9uLgogICAgICoKICAgICAqIFRoZSBkaWZmZXJlbmNlIGJldHdlZW4gdGhpcyBtZXRob2QgYW5kIHtAbGluayAjZ2V0QW5ub3RhdGlvbihDbGFzcyl9CiAgICAgKiBpcyB0aGF0IHRoaXMgbWV0aG9kIGRldGVjdHMgaWYgaXRzIGFyZ3VtZW50IGlzIGEgPGVtPnJlcGVhdGFibGUKICAgICAqIGFubm90YXRpb24gdHlwZTwvZW0+LCBhbmQgaWYgc28sIGF0dGVtcHRzIHRvIGZpbmQgb25lIG9yIG1vcmUKICAgICAqIGFubm90YXRpb25zIG9mIHRoYXQgdHlwZSBieSAibG9va2luZyB0aHJvdWdoIiBhIGNvbnRhaW5lciBhbm5vdGF0aW9uLgogICAgICoKICAgICAqIDxwPiBUaGUgYW5ub3RhdGlvbnMgcmV0dXJuZWQgYnkgdGhpcyBtZXRob2QgY291bGQgY29udGFpbiBhbiBlbGVtZW50CiAgICAgKiB3aG9zZSB2YWx1ZSBpcyBvZiB0eXBlIHtAY29kZSBDbGFzc30uCiAgICAgKiBUaGlzIHZhbHVlIGNhbm5vdCBiZSByZXR1cm5lZCBkaXJlY3RseTogIGluZm9ybWF0aW9uIG5lY2Vzc2FyeSB0bwogICAgICogbG9jYXRlIGFuZCBsb2FkIGEgY2xhc3MgKHN1Y2ggYXMgdGhlIGNsYXNzIGxvYWRlciB0byB1c2UpIGlzCiAgICAgKiBub3QgYXZhaWxhYmxlLCBhbmQgdGhlIGNsYXNzIG1pZ2h0IG5vdCBiZSBsb2FkYWJsZSBhdCBhbGwuCiAgICAgKiBBdHRlbXB0aW5nIHRvIHJlYWQgYSB7QGNvZGUgQ2xhc3N9IG9iamVjdCBieSBpbnZva2luZyB0aGUgcmVsZXZhbnQKICAgICAqIG1ldGhvZCBvbiB0aGUgcmV0dXJuZWQgYW5ub3RhdGlvbgogICAgICogd2lsbCByZXN1bHQgaW4gYSB7QGxpbmsgTWlycm9yZWRUeXBlRXhjZXB0aW9ufSwKICAgICAqIGZyb20gd2hpY2ggdGhlIGNvcnJlc3BvbmRpbmcge0BsaW5rIFR5cGVNaXJyb3J9IG1heSBiZSBleHRyYWN0ZWQuCiAgICAgKiBTaW1pbGFybHksIGF0dGVtcHRpbmcgdG8gcmVhZCBhIHtAY29kZSBDbGFzc1tdfS12YWx1ZWQgZWxlbWVudAogICAgICogd2lsbCByZXN1bHQgaW4gYSB7QGxpbmsgTWlycm9yZWRUeXBlc0V4Y2VwdGlvbn0uCiAgICAgKgogICAgICogPGJsb2NrcXVvdGU+CiAgICAgKiA8aT5Ob3RlOjwvaT4gVGhpcyBtZXRob2QgaXMgdW5saWtlIG90aGVycyBpbiB0aGlzIGFuZCByZWxhdGVkCiAgICAgKiBpbnRlcmZhY2VzLiAgSXQgb3BlcmF0ZXMgb24gcnVudGltZSByZWZsZWN0aXZlIGluZm9ybWF0aW9uICZtZGFzaDsKICAgICAqIHJlcHJlc2VudGF0aW9ucyBvZiBhbm5vdGF0aW9uIHR5cGVzIGN1cnJlbnRseSBsb2FkZWQgaW50byB0aGUKICAgICAqIFZNICZtZGFzaDsgcmF0aGVyIHRoYW4gb24gdGhlIHJlcHJlc2VudGF0aW9ucyBkZWZpbmVkIGJ5IGFuZCB1c2VkCiAgICAgKiB0aHJvdWdob3V0IHRoZXNlIGludGVyZmFjZXMuICBDb25zZXF1ZW50bHksIGNhbGxpbmcgbWV0aG9kcyBvbgogICAgICogdGhlIHJldHVybmVkIGFubm90YXRpb24gb2JqZWN0IGNhbiB0aHJvdyBtYW55IG9mIHRoZSBleGNlcHRpb25zCiAgICAgKiB0aGF0IGNhbiBiZSB0aHJvd24gd2hlbiBjYWxsaW5nIG1ldGhvZHMgb24gYW4gYW5ub3RhdGlvbiBvYmplY3QKICAgICAqIHJldHVybmVkIGJ5IGNvcmUgcmVmbGVjdGlvbi4gIFRoaXMgbWV0aG9kIGlzIGludGVuZGVkIGZvcgogICAgICogY2FsbGVycyB0aGF0IGFyZSB3cml0dGVuIHRvIG9wZXJhdGUgb24gYSBrbm93biwgZml4ZWQgc2V0IG9mCiAgICAgKiBhbm5vdGF0aW9uIHR5cGVzLgogICAgICogPC9ibG9ja3F1b3RlPgogICAgICoKICAgICAqIEBwYXJhbSA8QT4gIHRoZSBhbm5vdGF0aW9uIHR5cGUKICAgICAqIEBwYXJhbSBhbm5vdGF0aW9uVHlwZSAgdGhlIHtAY29kZSBDbGFzc30gb2JqZWN0IGNvcnJlc3BvbmRpbmcgdG8KICAgICAqICAgICAgICAgIHRoZSBhbm5vdGF0aW9uIHR5cGUKICAgICAqIEByZXR1cm4gdGhpcyBjb25zdHJ1Y3QncyBhbm5vdGF0aW9ucyBmb3IgdGhlIHNwZWNpZmllZCBhbm5vdGF0aW9uCiAgICAgKiAgICAgICAgIHR5cGUgaWYgcHJlc2VudCBvbiB0aGlzIGNvbnN0cnVjdCwgZWxzZSBhbiBlbXB0eSBhcnJheQogICAgICoKICAgICAqIEBzZWUgI2dldEFubm90YXRpb25NaXJyb3JzKCkKICAgICAqIEBzZWUgI2dldEFubm90YXRpb24oQ2xhc3MpCiAgICAgKiBAc2VlIGphdmEubGFuZy5yZWZsZWN0LkFubm90YXRlZEVsZW1lbnQjZ2V0QW5ub3RhdGlvbnNCeVR5cGUoQ2xhc3MpCiAgICAgKiBAc2VlIEVudW1Db25zdGFudE5vdFByZXNlbnRFeGNlcHRpb24KICAgICAqIEBzZWUgQW5ub3RhdGlvblR5cGVNaXNtYXRjaEV4Y2VwdGlvbgogICAgICogQHNlZSBJbmNvbXBsZXRlQW5ub3RhdGlvbkV4Y2VwdGlvbgogICAgICogQHNlZSBNaXJyb3JlZFR5cGVFeGNlcHRpb24KICAgICAqIEBzZWUgTWlycm9yZWRUeXBlc0V4Y2VwdGlvbgogICAgICogQGpscyA5LjYgQW5ub3RhdGlvbiBUeXBlcwogICAgICogQGpscyA5LjYuMSBBbm5vdGF0aW9uIFR5cGUgRWxlbWVudHMKICAgICAqLwogICAgPEEgZXh0ZW5kcyBBbm5vdGF0aW9uPiBBW10gZ2V0QW5ub3RhdGlvbnNCeVR5cGUoQ2xhc3M8QT4gYW5ub3RhdGlvblR5cGUpOwp9ClBLAwQKAAAIAAAGO6lKDbecxDYJAAA2CQAALAAAAGphdmF4L2xhbmcvbW9kZWwvVW5rbm93bkVudGl0eUV4Y2VwdGlvbi5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDA5LCAyMDE3LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGphdmF4LmxhbmcubW9kZWw7CgovKioKICogU3VwZXJjbGFzcyBvZiBleGNlcHRpb25zIHdoaWNoIGluZGljYXRlIHRoYXQgYW4gdW5rbm93biBraW5kIG9mCiAqIGVudGl0eSB3YXMgZW5jb3VudGVyZWQuICBUaGlzIHNpdHVhdGlvbiBjYW4gb2NjdXIgaWYgdGhlIGxhbmd1YWdlCiAqIGV2b2x2ZXMgYW5kIG5ldyBraW5kcyBvZiBjb25zdHJ1Y3RzIGFyZSBpbnRyb2R1Y2VkLiAgU3ViY2xhc3NlcyBvZgogKiB0aGlzIGV4Y2VwdGlvbiBtYXkgYmUgdGhyb3duIGJ5IHZpc2l0b3JzIHRvIGluZGljYXRlIHRoYXQgdGhlCiAqIHZpc2l0b3Igd2FzIGNyZWF0ZWQgZm9yIGEgcHJpb3IgdmVyc2lvbiBvZiB0aGUgbGFuZ3VhZ2UuCiAqCiAqIEBhcGlOb3RlIEEgY29tbW9uIHN1cGVyY2xhc3MgZm9yIGV4Y2VwdGlvbnMgc3BlY2lmaWMgdG8gZGlmZmVyZW50CiAqIGtpbmRzIG9mIHVua25vd24gZW50aXRpZXMgYWxsb3dzIGEgc2luZ2xlIGNhdGNoIGJsb2NrIHRvIGVhc2lseQogKiBwcm92aWRlIHVuaWZvcm0gaGFuZGxpbmcgb2YgdGhvc2UgcmVsYXRlZCBjb25kaXRpb25zLgogKgogKiBAYXV0aG9yIEpvc2VwaCBELiBEYXJjeQogKiBAc2VlIGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC5Vbmtub3duRWxlbWVudEV4Y2VwdGlvbgogKiBAc2VlIGphdmF4LmxhbmcubW9kZWwuZWxlbWVudC5Vbmtub3duQW5ub3RhdGlvblZhbHVlRXhjZXB0aW9uCiAqIEBzZWUgamF2YXgubGFuZy5tb2RlbC50eXBlLlVua25vd25UeXBlRXhjZXB0aW9uCiAqIEBzaW5jZSAxLjcKICovCnB1YmxpYyBjbGFzcyBVbmtub3duRW50aXR5RXhjZXB0aW9uIGV4dGVuZHMgUnVudGltZUV4Y2VwdGlvbiB7CgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMjY5TDsKCiAgICAvKioKICAgICAqIENyZWF0ZXMgYSBuZXcge0Bjb2RlIFVua25vd25FbnRpdHlFeGNlcHRpb259IHdpdGggdGhlIHNwZWNpZmllZAogICAgICogZGV0YWlsIG1lc3NhZ2UuCiAgICAgKgogICAgICogQHBhcmFtIG1lc3NhZ2UgdGhlIGRldGFpbCBtZXNzYWdlCiAgICAgKi8KICAgIHByb3RlY3RlZCBVbmtub3duRW50aXR5RXhjZXB0aW9uKFN0cmluZyBtZXNzYWdlKSB7CiAgICAgICAgc3VwZXIobWVzc2FnZSk7CiAgICB9Cn0KUEsDBAoAAAgAAAY7qUoAAAAAAAAAAAAAAAAMAAAAamF2YXgvdG9vbHMvUEsDBAoAAAgAAAY7qUqlVSLgX0MAAF9DAAAoAAAAamF2YXgvdG9vbHMvU3RhbmRhcmRKYXZhRmlsZU1hbmFnZXIuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNiwgMjAxNywgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBqYXZheC50b29sczsKCmltcG9ydCBqYXZhLmlvLkZpbGU7CmltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwppbXBvcnQgamF2YS5uaW8uZmlsZS5QYXRoOwppbXBvcnQgamF2YS51dGlsLkFycmF5czsKaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uOwoKaW1wb3J0IHN0YXRpYyBqYXZheC50b29scy5GaWxlTWFuYWdlclV0aWxzLio7CgovKioKICogRmlsZSBtYW5hZ2VyIGJhc2VkIG9uIHtAbGlua3BsYWluIEZpbGUgamF2YS5pby5GaWxlfSBhbmQge0BsaW5rcGxhaW4gUGF0aCBqYXZhLm5pby5maWxlLlBhdGh9LgogKgogKiBBIGNvbW1vbiB3YXkgdG8gb2J0YWluIGFuIGluc3RhbmNlIG9mIHRoaXMgY2xhc3MgaXMgdXNpbmcKICoge0BsaW5rcGxhaW4gSmF2YUNvbXBpbGVyI2dldFN0YW5kYXJkRmlsZU1hbmFnZXIgZ2V0U3RhbmRhcmRGaWxlTWFuYWdlcn0sIGZvciBleGFtcGxlOgogKgogKiA8cHJlPgogKiAgIEphdmFDb21waWxlciBjb21waWxlciA9IFRvb2xQcm92aWRlci5nZXRTeXN0ZW1KYXZhQ29tcGlsZXIoKTsKICogICB7QGNvZGUgRGlhZ25vc3RpY0NvbGxlY3RvcjxKYXZhRmlsZU9iamVjdD59IGRpYWdub3N0aWNzID0KICogICAgICAgbmV3IHtAY29kZSBEaWFnbm9zdGljQ29sbGVjdG9yPEphdmFGaWxlT2JqZWN0PigpfTsKICogICBTdGFuZGFyZEphdmFGaWxlTWFuYWdlciBmbSA9IGNvbXBpbGVyLmdldFN0YW5kYXJkRmlsZU1hbmFnZXIoZGlhZ25vc3RpY3MsIG51bGwsIG51bGwpOwogKiA8L3ByZT4KICoKICogVGhpcyBmaWxlIG1hbmFnZXIgY3JlYXRlcyBmaWxlIG9iamVjdHMgcmVwcmVzZW50aW5nIHJlZ3VsYXIKICoge0BsaW5rcGxhaW4gRmlsZSBmaWxlc30sCiAqIHtAbGlua3BsYWluIGphdmEudXRpbC56aXAuWmlwRW50cnkgemlwIGZpbGUgZW50cmllc30sIG9yIGVudHJpZXMgaW4KICogc2ltaWxhciBmaWxlIHN5c3RlbSBiYXNlZCBjb250YWluZXJzLiAgQW55IGZpbGUgb2JqZWN0IHJldHVybmVkCiAqIGZyb20gYSBmaWxlIG1hbmFnZXIgaW1wbGVtZW50aW5nIHRoaXMgaW50ZXJmYWNlIG11c3Qgb2JzZXJ2ZSB0aGUKICogZm9sbG93aW5nIGJlaGF2aW9yOgogKgogKiA8dWw+CiAqICAgPGxpPgogKiAgICAgRmlsZSBuYW1lcyBuZWVkIG5vdCBiZSBjYW5vbmljYWwuCiAqICAgPC9saT4KICogICA8bGk+CiAqICAgICBGb3IgZmlsZSBvYmplY3RzIHJlcHJlc2VudGluZyByZWd1bGFyIGZpbGVzCiAqICAgICA8dWw+CiAqICAgICAgIDxsaT4KICogICAgICAgICB0aGUgbWV0aG9kIDxjb2RlPntAbGlua3BsYWluIEZpbGVPYmplY3QjZGVsZXRlKCl9PC9jb2RlPgogKiAgICAgICAgIGlzIGVxdWl2YWxlbnQgdG8gPGNvZGU+e0BsaW5rcGxhaW4gRmlsZSNkZWxldGUoKX08L2NvZGU+LAogKiAgICAgICA8L2xpPgogKiAgICAgICA8bGk+CiAqICAgICAgICAgdGhlIG1ldGhvZCA8Y29kZT57QGxpbmtwbGFpbiBGaWxlT2JqZWN0I2dldExhc3RNb2RpZmllZCgpfTwvY29kZT4KICogICAgICAgICBpcyBlcXVpdmFsZW50IHRvIDxjb2RlPntAbGlua3BsYWluIEZpbGUjbGFzdE1vZGlmaWVkKCl9PC9jb2RlPiwKICogICAgICAgPC9saT4KICogICAgICAgPGxpPgogKiAgICAgICAgIHRoZSBtZXRob2RzIDxjb2RlPntAbGlua3BsYWluIEZpbGVPYmplY3QjZ2V0Q2hhckNvbnRlbnQoYm9vbGVhbil9PC9jb2RlPiwKICogICAgICAgICA8Y29kZT57QGxpbmtwbGFpbiBGaWxlT2JqZWN0I29wZW5JbnB1dFN0cmVhbSgpfTwvY29kZT4sIGFuZAogKiAgICAgICAgIDxjb2RlPntAbGlua3BsYWluIEZpbGVPYmplY3Qjb3BlblJlYWRlcihib29sZWFuKX08L2NvZGU+CiAqICAgICAgICAgbXVzdCBzdWNjZWVkIGlmIHRoZSBmb2xsb3dpbmcgd291bGQgc3VjY2VlZCAoaWdub3JpbmcKICogICAgICAgICBlbmNvZGluZyBpc3N1ZXMpOgogKiAgICAgICAgIDxibG9ja3F1b3RlPgogKiAgICAgICAgICAgPHByZT5uZXcge0BsaW5rcGxhaW4gamF2YS5pby5GaWxlSW5wdXRTdHJlYW0jRmlsZUlucHV0U3RyZWFtKEZpbGUpIEZpbGVJbnB1dFN0cmVhbX0obmV3IHtAbGlua3BsYWluIEZpbGUjRmlsZShqYXZhLm5ldC5VUkkpIEZpbGV9KHtAbGlua3BsYWluIEZpbGVPYmplY3QgZmlsZU9iamVjdH0ue0BsaW5rcGxhaW4gRmlsZU9iamVjdCN0b1VyaSgpIHRvVXJpfSgpKSk8L3ByZT4KICogICAgICAgICA8L2Jsb2NrcXVvdGU+CiAqICAgICAgIDwvbGk+CiAqICAgICAgIDxsaT4KICogICAgICAgICBhbmQgdGhlIG1ldGhvZHMKICogICAgICAgICA8Y29kZT57QGxpbmtwbGFpbiBGaWxlT2JqZWN0I29wZW5PdXRwdXRTdHJlYW0oKX08L2NvZGU+LCBhbmQKICogICAgICAgICA8Y29kZT57QGxpbmtwbGFpbiBGaWxlT2JqZWN0I29wZW5Xcml0ZXIoKX08L2NvZGU+IG11c3QKICogICAgICAgICBzdWNjZWVkIGlmIHRoZSBmb2xsb3dpbmcgd291bGQgc3VjY2VlZCAoaWdub3JpbmcgZW5jb2RpbmcKICogICAgICAgICBpc3N1ZXMpOgogKiAgICAgICAgIDxibG9ja3F1b3RlPgogKiAgICAgICAgICAgPHByZT5uZXcge0BsaW5rcGxhaW4gamF2YS5pby5GaWxlT3V0cHV0U3RyZWFtI0ZpbGVPdXRwdXRTdHJlYW0oRmlsZSkgRmlsZU91dHB1dFN0cmVhbX0obmV3IHtAbGlua3BsYWluIEZpbGUjRmlsZShqYXZhLm5ldC5VUkkpIEZpbGV9KHtAbGlua3BsYWluIEZpbGVPYmplY3QgZmlsZU9iamVjdH0ue0BsaW5rcGxhaW4gRmlsZU9iamVjdCN0b1VyaSgpIHRvVXJpfSgpKSk8L3ByZT4KICogICAgICAgICA8L2Jsb2NrcXVvdGU+CiAqICAgICAgIDwvbGk+CiAqICAgICA8L3VsPgogKiAgIDwvbGk+CiAqICAgPGxpPgogKiAgICAgVGhlIHtAbGlua3BsYWluIGphdmEubmV0LlVSSSBVUkl9IHJldHVybmVkIGZyb20KICogICAgIDxjb2RlPntAbGlua3BsYWluIEZpbGVPYmplY3QjdG9VcmkoKX08L2NvZGU+CiAqICAgICA8dWw+CiAqICAgICAgIDxsaT4KICogICAgICAgICBtdXN0IGJlIHtAbGlua3BsYWluIGphdmEubmV0LlVSSSNpc0Fic29sdXRlKCkgYWJzb2x1dGV9IChoYXZlIGEgc2NoZW1hKSwgYW5kCiAqICAgICAgIDwvbGk+CiAqICAgICAgIDxsaT4KICogICAgICAgICBtdXN0IGhhdmUgYSB7QGxpbmtwbGFpbiBqYXZhLm5ldC5VUkkjbm9ybWFsaXplKCkgbm9ybWFsaXplZH0KICogICAgICAgICB7QGxpbmtwbGFpbiBqYXZhLm5ldC5VUkkjZ2V0UGF0aCgpIHBhdGggY29tcG9uZW50fSB3aGljaAogKiAgICAgICAgIGNhbiBiZSByZXNvbHZlZCB3aXRob3V0IGFueSBwcm9jZXNzLXNwZWNpZmljIGNvbnRleHQgc3VjaAogKiAgICAgICAgIGFzIHRoZSBjdXJyZW50IGRpcmVjdG9yeSAoZmlsZSBuYW1lcyBtdXN0IGJlIGFic29sdXRlKS4KICogICAgICAgPC9saT4KICogICAgIDwvdWw+CiAqICAgPC9saT4KICogPC91bD4KICoKICogQWNjb3JkaW5nIHRvIHRoZXNlIHJ1bGVzLCB0aGUgZm9sbG93aW5nIFVSSXMsIGZvciBleGFtcGxlLCBhcmUKICogYWxsb3dlZDoKICogPHVsPgogKiAgIDxsaT4KICogICAgIDxjb2RlPmZpbGU6Ly8vQzovRG9jdW1lbnRzJTIwYW5kJTIwU2V0dGluZ3MvVW5jbGVCb2IvQm9ic0FwcC9UZXN0LmphdmE8L2NvZGU+CiAqICAgPC9saT4KICogICA8bGk+CiAqICAgICA8Y29kZT5qYXI6Ly8vQzovRG9jdW1lbnRzJTIwYW5kJTIwU2V0dGluZ3MvVW5jbGVCb2IvbGliL3ZlbmRvckEuamFyIS9jb20vdmVuZG9yYS9MaWJyYXJ5Q2xhc3MuY2xhc3M8L2NvZGU+CiAqICAgPC9saT4KICogPC91bD4KICogV2hlcmVhcyB0aGVzZSBhcmUgbm90IChyZWFzb24gaW4gcGFyZW50aGVzZXMpOgogKiA8dWw+CiAqICAgPGxpPgogKiAgICAgPGNvZGU+ZmlsZTpCb2JzQXBwL1Rlc3QuamF2YTwvY29kZT4gKHRoZSBmaWxlIG5hbWUgaXMgcmVsYXRpdmUKICogICAgIGFuZCBkZXBlbmQgb24gdGhlIGN1cnJlbnQgZGlyZWN0b3J5KQogKiAgIDwvbGk+CiAqICAgPGxpPgogKiAgICAgPGNvZGU+amFyOmxpYi92ZW5kb3JBLmphciEvY29tL3ZlbmRvcmEvTGlicmFyeUNsYXNzLmNsYXNzPC9jb2RlPgogKiAgICAgKHRoZSBmaXJzdCBoYWxmIG9mIHRoZSBwYXRoIGRlcGVuZHMgb24gdGhlIGN1cnJlbnQgZGlyZWN0b3J5LAogKiAgICAgd2hlcmVhcyB0aGUgY29tcG9uZW50IGFmdGVyICEgaXMgbGVnYWwpCiAqICAgPC9saT4KICogICA8bGk+CiAqICAgICA8Y29kZT5UZXN0LmphdmE8L2NvZGU+ICh0aGlzIFVSSSBkZXBlbmRzIG9uIHRoZSBjdXJyZW50CiAqICAgICBkaXJlY3RvcnkgYW5kIGRvZXMgbm90IGhhdmUgYSBzY2hlbWEpCiAqICAgPC9saT4KICogICA8bGk+CiAqICAgICA8Y29kZT5qYXI6Ly8vQzovRG9jdW1lbnRzJTIwYW5kJTIwU2V0dGluZ3MvVW5jbGVCb2IvQm9ic0FwcC8uLi9saWIvdmVuZG9yQS5qYXIhY29tL3ZlbmRvcmEvTGlicmFyeUNsYXNzLmNsYXNzPC9jb2RlPgogKiAgICAgKHRoZSBwYXRoIGlzIG5vdCBub3JtYWxpemVkKQogKiAgIDwvbGk+CiAqIDwvdWw+CiAqCiAqIDxwPkFsbCBpbXBsZW1lbnRhdGlvbnMgb2YgdGhpcyBpbnRlcmZhY2UgbXVzdCBzdXBwb3J0IFBhdGggb2JqZWN0cyByZXByZXNlbnRpbmcKICogZmlsZXMgaW4gdGhlIHtAbGlua3BsYWluIGphdmEubmlvLmZpbGUuRmlsZVN5c3RlbXMjZ2V0RGVmYXVsdCgpIGRlZmF1bHQgZmlsZSBzeXN0ZW0ufQogKiBJdCBpcyByZWNvbW1lbmRlZCB0aGF0IGltcGxlbWVudGF0aW9ucyBzaG91bGQgc3VwcG9ydCBQYXRoIG9iamVjdHMgZnJvbSBhbnkgZmlsZXN5c3RlbS48L3A+CiAqCiAqCiAqIEBhcGlOb3RlCiAqIFNvbWUgbWV0aG9kcyBvbiB0aGlzIGludGVyZmFjZSB0YWtlIGEge0Bjb2RlIENvbGxlY3Rpb248PyBleHRlbmRzIFBhdGg+fQogKiBpbnN0ZWFkIG9mIHtAY29kZSBJdGVyYWJsZTw/IGV4dGVuZHMgUGF0aD59LgogKiBUaGlzIGlzIHRvIHByZXZlbnQgdGhlIHBvc3NpYmlsaXR5IG9mIGFjY2lkZW50YWxseSBjYWxsaW5nIHRoZSBtZXRob2QKICogd2l0aCBhIHNpbmdsZSB7QGNvZGUgUGF0aH0gYXMgc3VjaCBhbiBhcmd1bWVudCwgYmVjYXVzZSBhbHRob3VnaAogKiB7QGNvZGUgUGF0aH0gaW1wbGVtZW50cyB7QGNvZGUgSXRlcmFibGU8UGF0aD59LCBpdCB3b3VsZCBhbG1vc3QgbmV2ZXIgYmUKICogY29ycmVjdCB0byBjYWxsIHRoZXNlIG1ldGhvZHMgd2l0aCBhIHNpbmdsZSB7QGNvZGUgUGF0aH0gYW5kIGhhdmUgaXQgYmUgdHJlYXRlZCBhcwogKiBhbiB7QGNvZGUgSXRlcmFibGV9IG9mIGl0cyBjb21wb25lbnRzLgogKgogKgogKiBAYXV0aG9yIFBldGVyIHZvbiBkZXIgQWgmZWFjdXRlOwogKiBAc2luY2UgMS42CiAqLwpwdWJsaWMgaW50ZXJmYWNlIFN0YW5kYXJkSmF2YUZpbGVNYW5hZ2VyIGV4dGVuZHMgSmF2YUZpbGVNYW5hZ2VyIHsKCiAgICAvKioKICAgICAqIENvbXBhcmVzIHR3byBmaWxlIG9iamVjdHMgYW5kIHJldHVybiB0cnVlIGlmIHRoZXkgcmVwcmVzZW50IHRoZQogICAgICogc2FtZSBjYW5vbmljYWwgZmlsZSwgemlwIGZpbGUgZW50cnksIG9yIGVudHJ5IGluIGFueSBmaWxlCiAgICAgKiBzeXN0ZW0gYmFzZWQgY29udGFpbmVyLgogICAgICoKICAgICAqIEBwYXJhbSBhIGEgZmlsZSBvYmplY3QKICAgICAqIEBwYXJhbSBiIGEgZmlsZSBvYmplY3QKICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgZ2l2ZW4gZmlsZSBvYmplY3RzIHJlcHJlc2VudCB0aGUgc2FtZQogICAgICogY2Fub25pY2FsIGZpbGUsIHppcCBmaWxlIGVudHJ5IG9yIHBhdGg7IGZhbHNlIG90aGVyd2lzZQogICAgICoKICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIGVpdGhlciBvZiB0aGUgYXJndW1lbnRzCiAgICAgKiB3ZXJlIGNyZWF0ZWQgd2l0aCBhbm90aGVyIGZpbGUgbWFuYWdlciBpbXBsZW1lbnRhdGlvbgogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIGJvb2xlYW4gaXNTYW1lRmlsZShGaWxlT2JqZWN0IGEsIEZpbGVPYmplY3QgYik7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGZpbGUgb2JqZWN0cyByZXByZXNlbnRpbmcgdGhlIGdpdmVuIGZpbGVzLgogICAgICoKICAgICAqIEBwYXJhbSBmaWxlcyBhIGxpc3Qgb2YgZmlsZXMKICAgICAqIEByZXR1cm4gYSBsaXN0IG9mIGZpbGUgb2JqZWN0cwogICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgdGhlIGxpc3Qgb2YgZmlsZXMgaW5jbHVkZXMKICAgICAqIGEgZGlyZWN0b3J5CiAgICAgKi8KICAgIEl0ZXJhYmxlPD8gZXh0ZW5kcyBKYXZhRmlsZU9iamVjdD4gZ2V0SmF2YUZpbGVPYmplY3RzRnJvbUZpbGVzKAogICAgICAgIEl0ZXJhYmxlPD8gZXh0ZW5kcyBGaWxlPiBmaWxlcyk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGZpbGUgb2JqZWN0cyByZXByZXNlbnRpbmcgdGhlIGdpdmVuIHBhdGhzLgogICAgICoKICAgICAqIEBpbXBsU3BlYwogICAgICogVGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gY29udmVydHMgZWFjaCBwYXRoIHRvIGEgZmlsZSBhbmQgY2FsbHMKICAgICAqIHtAbGluayAjZ2V0SmF2YUZpbGVPYmplY3RzRnJvbUZpbGVzIGdldEphdmFPYmplY3RzRnJvbUZpbGVzfS4KICAgICAqIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB3aWxsIGJlIHRocm93biBpZiBhbnkgb2YgdGhlIHBhdGhzCiAgICAgKiBjYW5ub3QgYmUgY29udmVydGVkIHRvIGEgZmlsZS4KICAgICAqCiAgICAgKiBAcGFyYW0gcGF0aHMgYSBsaXN0IG9mIHBhdGhzCiAgICAgKiBAcmV0dXJuIGEgbGlzdCBvZiBmaWxlIG9iamVjdHMKICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHRoZSBsaXN0IG9mIHBhdGhzIGluY2x1ZGVzCiAgICAgKiBhIGRpcmVjdG9yeSBvciBpZiB0aGlzIGZpbGUgbWFuYWdlciBkb2VzIG5vdCBzdXBwb3J0IGFueSBvZiB0aGUKICAgICAqIGdpdmVuIHBhdGhzLgogICAgICoKICAgICAqIEBzaW5jZSA5CiAgICAgKi8KICAgIGRlZmF1bHQgSXRlcmFibGU8PyBleHRlbmRzIEphdmFGaWxlT2JqZWN0PiBnZXRKYXZhRmlsZU9iamVjdHNGcm9tUGF0aHMoCiAgICAgICAgICAgIEl0ZXJhYmxlPD8gZXh0ZW5kcyBQYXRoPiBwYXRocykgewogICAgICAgIHJldHVybiBnZXRKYXZhRmlsZU9iamVjdHNGcm9tRmlsZXMoYXNGaWxlcyhwYXRocykpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyBmaWxlIG9iamVjdHMgcmVwcmVzZW50aW5nIHRoZSBnaXZlbiBmaWxlcy4KICAgICAqIENvbnZlbmllbmNlIG1ldGhvZCBlcXVpdmFsZW50IHRvOgogICAgICoKICAgICAqIDxwcmU+CiAgICAgKiAgICAgZ2V0SmF2YUZpbGVPYmplY3RzRnJvbUZpbGVzKHtAbGlua3BsYWluIGphdmEudXRpbC5BcnJheXMjYXNMaXN0IEFycmF5cy5hc0xpc3R9KGZpbGVzKSkKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIEBwYXJhbSBmaWxlcyBhbiBhcnJheSBvZiBmaWxlcwogICAgICogQHJldHVybiBhIGxpc3Qgb2YgZmlsZSBvYmplY3RzCiAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgYXJyYXkgb2YgZmlsZXMgaW5jbHVkZXMKICAgICAqIGEgZGlyZWN0b3J5CiAgICAgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIHRoZSBnaXZlbiBhcnJheSBjb250YWlucyBudWxsCiAgICAgKiBlbGVtZW50cwogICAgICovCiAgICBJdGVyYWJsZTw/IGV4dGVuZHMgSmF2YUZpbGVPYmplY3Q+IGdldEphdmFGaWxlT2JqZWN0cyhGaWxlLi4uIGZpbGVzKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgZmlsZSBvYmplY3RzIHJlcHJlc2VudGluZyB0aGUgZ2l2ZW4gcGF0aHMuCiAgICAgKiBDb252ZW5pZW5jZSBtZXRob2QgZXF1aXZhbGVudCB0bzoKICAgICAqCiAgICAgKiA8cHJlPgogICAgICogICAgIGdldEphdmFGaWxlT2JqZWN0c0Zyb21QYXRocyh7QGxpbmtwbGFpbiBqYXZhLnV0aWwuQXJyYXlzI2FzTGlzdCBBcnJheXMuYXNMaXN0fShwYXRocykpCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiBAcGFyYW0gcGF0aHMgYW4gYXJyYXkgb2YgcGF0aHMKICAgICAqIEByZXR1cm4gYSBsaXN0IG9mIGZpbGUgb2JqZWN0cwogICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgdGhlIGFycmF5IG9mIGZpbGVzIGluY2x1ZGVzCiAgICAgKiBhIGRpcmVjdG9yeQogICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgZ2l2ZW4gYXJyYXkgY29udGFpbnMgbnVsbAogICAgICogZWxlbWVudHMKICAgICAqCiAgICAgKiBAc2luY2UgOQogICAgICovCiAgICBkZWZhdWx0IEl0ZXJhYmxlPD8gZXh0ZW5kcyBKYXZhRmlsZU9iamVjdD4gZ2V0SmF2YUZpbGVPYmplY3RzKFBhdGguLi4gcGF0aHMpIHsKICAgICAgICByZXR1cm4gZ2V0SmF2YUZpbGVPYmplY3RzRnJvbVBhdGhzKEFycmF5cy5hc0xpc3QocGF0aHMpKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgZmlsZSBvYmplY3RzIHJlcHJlc2VudGluZyB0aGUgZ2l2ZW4gZmlsZSBuYW1lcy4KICAgICAqCiAgICAgKiBAcGFyYW0gbmFtZXMgYSBsaXN0IG9mIGZpbGUgbmFtZXMKICAgICAqIEByZXR1cm4gYSBsaXN0IG9mIGZpbGUgb2JqZWN0cwogICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgdGhlIGxpc3Qgb2YgZmlsZSBuYW1lcwogICAgICogaW5jbHVkZXMgYSBkaXJlY3RvcnkKICAgICAqLwogICAgSXRlcmFibGU8PyBleHRlbmRzIEphdmFGaWxlT2JqZWN0PiBnZXRKYXZhRmlsZU9iamVjdHNGcm9tU3RyaW5ncygKICAgICAgICBJdGVyYWJsZTxTdHJpbmc+IG5hbWVzKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgZmlsZSBvYmplY3RzIHJlcHJlc2VudGluZyB0aGUgZ2l2ZW4gZmlsZSBuYW1lcy4KICAgICAqIENvbnZlbmllbmNlIG1ldGhvZCBlcXVpdmFsZW50IHRvOgogICAgICoKICAgICAqIDxwcmU+CiAgICAgKiAgICAgZ2V0SmF2YUZpbGVPYmplY3RzRnJvbVN0cmluZ3Moe0BsaW5rcGxhaW4gamF2YS51dGlsLkFycmF5cyNhc0xpc3QgQXJyYXlzLmFzTGlzdH0obmFtZXMpKQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogQHBhcmFtIG5hbWVzIGEgbGlzdCBvZiBmaWxlIG5hbWVzCiAgICAgKiBAcmV0dXJuIGEgbGlzdCBvZiBmaWxlIG9iamVjdHMKICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHRoZSBhcnJheSBvZiBmaWxlIG5hbWVzCiAgICAgKiBpbmNsdWRlcyBhIGRpcmVjdG9yeQogICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgZ2l2ZW4gYXJyYXkgY29udGFpbnMgbnVsbAogICAgICogZWxlbWVudHMKICAgICAqLwogICAgSXRlcmFibGU8PyBleHRlbmRzIEphdmFGaWxlT2JqZWN0PiBnZXRKYXZhRmlsZU9iamVjdHMoU3RyaW5nLi4uIG5hbWVzKTsKCiAgICAvKioKICAgICAqIEFzc29jaWF0ZXMgdGhlIGdpdmVuIHNlYXJjaCBwYXRoIHdpdGggdGhlIGdpdmVuIGxvY2F0aW9uLiAgQW55CiAgICAgKiBwcmV2aW91cyB2YWx1ZSB3aWxsIGJlIGRpc2NhcmRlZC4KICAgICAqCiAgICAgKiBJZiB0aGUgbG9jYXRpb24gaXMgYSBtb2R1bGUtb3JpZW50ZWQgb3Igb3V0cHV0IGxvY2F0aW9uLCBhbnkgbW9kdWxlLXNwZWNpZmljCiAgICAgKiBhc3NvY2lhdGlvbnMgc2V0IHVwIGJ5IHtAbGlua3BsYWluICNzZXRMb2NhdGlvbkZvck1vZHVsZSBzZXRMb2NhdGlvbkZvck1vZHVsZX0KICAgICAqIHdpbGwgYmUgY2FuY2VsbGVkLgogICAgICoKICAgICAqIEBwYXJhbSBsb2NhdGlvbiBhIGxvY2F0aW9uCiAgICAgKiBAcGFyYW0gZmlsZXMgYSBsaXN0IG9mIGZpbGVzLCBpZiB7QGNvZGUgbnVsbH0gdXNlIHRoZSBkZWZhdWx0CiAgICAgKiBzZWFyY2ggcGF0aCBmb3IgdGhpcyBsb2NhdGlvbgogICAgICogQHNlZSAjZ2V0TG9jYXRpb24KICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHtAY29kZSBsb2NhdGlvbn0gaXMgYW4gb3V0cHV0CiAgICAgKiBsb2NhdGlvbiBhbmQge0Bjb2RlIGZpbGVzfSBkb2VzIG5vdCBjb250YWluIGV4YWN0bHkgb25lIGVsZW1lbnQKICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYge0Bjb2RlIGxvY2F0aW9ufSBpcyBhbiBvdXRwdXQgbG9jYXRpb24gYW5kCiAgICAgKiBkb2VzIG5vdCByZXByZXNlbnQgYW4gZXhpc3RpbmcgZGlyZWN0b3J5CiAgICAgKi8KICAgIHZvaWQgc2V0TG9jYXRpb24oTG9jYXRpb24gbG9jYXRpb24sIEl0ZXJhYmxlPD8gZXh0ZW5kcyBGaWxlPiBmaWxlcykKICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb247CgogICAgLyoqCiAgICAgKiBBc3NvY2lhdGVzIHRoZSBnaXZlbiBzZWFyY2ggcGF0aCB3aXRoIHRoZSBnaXZlbiBsb2NhdGlvbi4KICAgICAqIEFueSBwcmV2aW91cyB2YWx1ZSB3aWxsIGJlIGRpc2NhcmRlZC4KICAgICAqCiAgICAgKiBJZiB0aGUgbG9jYXRpb24gaXMgYSBtb2R1bGUtb3JpZW50ZWQgb3Igb3V0cHV0IGxvY2F0aW9uLCBhbnkgbW9kdWxlLXNwZWNpZmljCiAgICAgKiBhc3NvY2lhdGlvbnMgc2V0IHVwIGJ5IHtAbGlua3BsYWluICNzZXRMb2NhdGlvbkZvck1vZHVsZSBzZXRMb2NhdGlvbkZvck1vZHVsZX0KICAgICAqIHdpbGwgYmUgY2FuY2VsbGVkLgogICAgICoKICAgICAqIEBpbXBsU3BlYwogICAgICogVGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gY29udmVydHMgZWFjaCBwYXRoIHRvIGEgZmlsZSBhbmQgY2FsbHMKICAgICAqIHtAbGluayAjZ2V0SmF2YUZpbGVPYmplY3RzRnJvbUZpbGVzIGdldEphdmFPYmplY3RzRnJvbUZpbGVzfS4KICAgICAqIHtAbGlua3BsYWluIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb259CiAgICAgKiB3aWxsIGJlIHRocm93biBpZiBhbnkgb2YgdGhlIHBhdGhzIGNhbm5vdCBiZSBjb252ZXJ0ZWQgdG8gYSBmaWxlLgogICAgICoKICAgICAqIEBwYXJhbSBsb2NhdGlvbiBhIGxvY2F0aW9uCiAgICAgKiBAcGFyYW0gcGF0aHMgYSBsaXN0IG9mIHBhdGhzLCBpZiB7QGNvZGUgbnVsbH0gdXNlIHRoZSBkZWZhdWx0CiAgICAgKiBzZWFyY2ggcGF0aCBmb3IgdGhpcyBsb2NhdGlvbgogICAgICogQHNlZSAjZ2V0TG9jYXRpb24KICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHtAY29kZSBsb2NhdGlvbn0gaXMgYW4gb3V0cHV0CiAgICAgKiBsb2NhdGlvbiBhbmQge0Bjb2RlIHBhdGhzfSBkb2VzIG5vdCBjb250YWluIGV4YWN0bHkgb25lIGVsZW1lbnQKICAgICAqIG9yIGlmIHRoaXMgZmlsZSBtYW5hZ2VyIGRvZXMgbm90IHN1cHBvcnQgYW55IG9mIHRoZSBnaXZlbiBwYXRocwogICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiB7QGNvZGUgbG9jYXRpb259IGlzIGFuIG91dHB1dCBsb2NhdGlvbiBhbmQKICAgICAqIHtAY29kZSBwYXRoc30gZG9lcyBub3QgcmVwcmVzZW50IGFuIGV4aXN0aW5nIGRpcmVjdG9yeQogICAgICoKICAgICAqIEBzaW5jZSA5CiAgICAgKi8KICAgIGRlZmF1bHQgdm9pZCBzZXRMb2NhdGlvbkZyb21QYXRocyhMb2NhdGlvbiBsb2NhdGlvbiwgQ29sbGVjdGlvbjw/IGV4dGVuZHMgUGF0aD4gcGF0aHMpCiAgICAgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgc2V0TG9jYXRpb24obG9jYXRpb24sIGFzRmlsZXMocGF0aHMpKTsKICAgIH0KCiAgICAvKioKICAgICAqIEFzc29jaWF0ZXMgdGhlIGdpdmVuIHNlYXJjaCBwYXRoIHdpdGggdGhlIGdpdmVuIG1vZHVsZSBhbmQgbG9jYXRpb24sCiAgICAgKiB3aGljaCBtdXN0IGJlIGEgbW9kdWxlLW9yaWVudGVkIG9yIG91dHB1dCBsb2NhdGlvbi4KICAgICAqIEFueSBwcmV2aW91cyB2YWx1ZSB3aWxsIGJlIGRpc2NhcmRlZC4KICAgICAqIFRoaXMgb3ZlcnJpZGVzIGFueSBkZWZhdWx0IGFzc29jaWF0aW9uIGRlcml2ZWQgZnJvbSB0aGUgc2VhcmNoIHBhdGgKICAgICAqIGFzc29jaWF0ZWQgd2l0aCB0aGUgbG9jYXRpb24gaXRzZWxmLgogICAgICoKICAgICAqIEFsbCBzdWNoIG1vZHVsZS1zcGVjaWZpYyBhc3NvY2lhdGlvbnMgd2lsbCBiZSBjYW5jZWxsZWQgaWYgYQogICAgICogbmV3IHNlYXJjaCBwYXRoIGlzIGFzc29jaWF0ZWQgd2l0aCB0aGUgbG9jYXRpb24gYnkgY2FsbGluZwogICAgICoge0BsaW5rcGxhaW4gI3NldExvY2F0aW9uIHNldExvY2F0aW9uIH0gb3IKICAgICAqIHtAbGlua3BsYWluICNzZXRMb2NhdGlvbkZyb21QYXRocyBzZXRMb2NhdGlvbkZyb21QYXRoc30uCiAgICAgKgogICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhlIGxvY2F0aW9uIGlzIG5vdCBhIG1vZHVsZS1vcmllbnRlZAogICAgICogIG9yIG91dHB1dCBsb2NhdGlvbi4KICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gaWYgdGhpcyBvcGVyYXRpb24gaXMgbm90IHN1cHBvcnRlZCBieQogICAgICogIHRoaXMgZmlsZSBtYW5hZ2VyLgogICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiB7QGNvZGUgbG9jYXRpb259IGlzIGFuIG91dHB1dCBsb2NhdGlvbiBhbmQKICAgICAqIHtAY29kZSBwYXRoc30gZG9lcyBub3QgcmVwcmVzZW50IGFuIGV4aXN0aW5nIGRpcmVjdG9yeQogICAgICoKICAgICAqIEBwYXJhbSBsb2NhdGlvbiB0aGUgbG9jYXRpb24KICAgICAqIEBwYXJhbSBtb2R1bGVOYW1lIHRoZSBuYW1lIG9mIHRoZSBtb2R1bGUKICAgICAqIEBwYXJhbSBwYXRocyB0aGUgc2VhcmNoIHBhdGggdG8gYXNzb2NpYXRlIHdpdGggdGhlIGxvY2F0aW9uIGFuZCBtb2R1bGUuCiAgICAgKgogICAgICogQHNlZSBzZXRMb2NhdGlvbgogICAgICogQHNlZSBzZXRMb2NhdGlvbkZyb21QYXRocwogICAgICovCiAgICBkZWZhdWx0IHZvaWQgc2V0TG9jYXRpb25Gb3JNb2R1bGUoTG9jYXRpb24gbG9jYXRpb24sIFN0cmluZyBtb2R1bGVOYW1lLAogICAgICAgICAgICBDb2xsZWN0aW9uPD8gZXh0ZW5kcyBQYXRoPiBwYXRocykgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHNlYXJjaCBwYXRoIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gbG9jYXRpb24uCiAgICAgKgogICAgICogQHBhcmFtIGxvY2F0aW9uIGEgbG9jYXRpb24KICAgICAqIEByZXR1cm4gYSBsaXN0IG9mIGZpbGVzIG9yIHtAY29kZSBudWxsfSBpZiB0aGlzIGxvY2F0aW9uIGhhcyBubwogICAgICogYXNzb2NpYXRlZCBzZWFyY2ggcGF0aAogICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgYW55IGVsZW1lbnQgb2YgdGhlIHNlYXJjaCBwYXRoCiAgICAgKiBjYW5ub3QgYmUgY29udmVydGVkIHRvIGEge0BsaW5rcGxhaW4gRmlsZX0uCiAgICAgKgogICAgICogQHNlZSAjc2V0TG9jYXRpb24KICAgICAqIEBzZWUgUGF0aCN0b0ZpbGUKICAgICAqLwogICAgSXRlcmFibGU8PyBleHRlbmRzIEZpbGU+IGdldExvY2F0aW9uKExvY2F0aW9uIGxvY2F0aW9uKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHNlYXJjaCBwYXRoIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gbG9jYXRpb24uCiAgICAgKgogICAgICogQGltcGxTcGVjCiAgICAgKiBUaGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBjYWxscyB7QGxpbmsgI2dldExvY2F0aW9uIGdldExvY2F0aW9ufQogICAgICogYW5kIHRoZW4gcmV0dXJucyBhbiB7QGNvZGUgSXRlcmFibGV9IGZvcm1lZCBieSBjYWxsaW5nIHtAY29kZSB0b1BhdGgoKX0KICAgICAqIG9uIGVhY2gge0Bjb2RlIEZpbGV9IHJldHVybmVkIGZyb20ge0Bjb2RlIGdldExvY2F0aW9ufS4KICAgICAqCiAgICAgKiBAcGFyYW0gbG9jYXRpb24gYSBsb2NhdGlvbgogICAgICogQHJldHVybiBhIGxpc3Qgb2YgcGF0aHMgb3Ige0Bjb2RlIG51bGx9IGlmIHRoaXMgbG9jYXRpb24gaGFzIG5vCiAgICAgKiBhc3NvY2lhdGVkIHNlYXJjaCBwYXRoCiAgICAgKgogICAgICogQHNlZSAjc2V0TG9jYXRpb25Gcm9tUGF0aHMKICAgICAqIEBzaW5jZSA5CiAgICAgKi8KICAgIGRlZmF1bHQgSXRlcmFibGU8PyBleHRlbmRzIFBhdGg+IGdldExvY2F0aW9uQXNQYXRocyhMb2NhdGlvbiBsb2NhdGlvbikgewogICAgICAgIHJldHVybiBhc1BhdGhzKGdldExvY2F0aW9uKGxvY2F0aW9uKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBwYXRoLCBpZiBhbnksIHVuZGVybHlpbmcgdGhpcyBmaWxlIG9iamVjdCAob3B0aW9uYWwgb3BlcmF0aW9uKS4KICAgICAqIEZpbGUgb2JqZWN0cyBkZXJpdmVkIGZyb20gYSB7QGxpbmsgamF2YS5uaW8uZmlsZS5GaWxlU3lzdGVtIEZpbGVTeXN0ZW19LAogICAgICogaW5jbHVkaW5nIHRoZSBkZWZhdWx0IGZpbGUgc3lzdGVtLCB0eXBpY2FsbHkgaGF2ZSBhIGNvcnJlc3BvbmRpbmcgdW5kZXJseWluZwogICAgICoge0BsaW5rIGphdmEubmlvLmZpbGUuUGF0aCBQYXRofSBvYmplY3QuIEluIHN1Y2ggY2FzZXMsIHRoaXMgbWV0aG9kIG1heSBiZQogICAgICogdXNlZCB0byBhY2Nlc3MgdGhhdCBvYmplY3QuCiAgICAgKgogICAgICogQGltcGxTcGVjCiAgICAgKiBUaGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiB0aHJvd3Mge0BsaW5rIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9ufQogICAgICogZm9yIGFsbCBmaWxlcy4KICAgICAqCiAgICAgKiBAcGFyYW0gZmlsZSBhIGZpbGUgb2JqZWN0CiAgICAgKiBAcmV0dXJuIGEgcGF0aCByZXByZXNlbnRpbmcgdGhlIHNhbWUgdW5kZXJseWluZyBmaWxlIHN5c3RlbSBhcnRpZmFjdAogICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgdGhlIGZpbGUgb2JqZWN0IGRvZXMgbm90IGhhdmUgYW4gdW5kZXJseWluZyBwYXRoCiAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGlmIHRoZSBvcGVyYXRpb24gaXMgbm90IHN1cHBvcnRlZCBieSB0aGlzIGZpbGUgbWFuYWdlcgogICAgICoKICAgICAqIEBzaW5jZSA5CiAgICAgKi8KICAgIGRlZmF1bHQgUGF0aCBhc1BhdGgoRmlsZU9iamVjdCBmaWxlKSB7CiAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBGYWN0b3J5IHRvIGNyZWF0ZSB7QGNvZGUgUGF0aH0gb2JqZWN0cyBmcm9tIHN0cmluZ3MuCiAgICAgKgogICAgICogQHNpbmNlIDkKICAgICAqLwogICAgaW50ZXJmYWNlIFBhdGhGYWN0b3J5IHsKICAgICAgICAvKioKICAgICAgICAgKiBDb252ZXJ0cyBhIHBhdGggc3RyaW5nLCBvciBhIHNlcXVlbmNlIG9mIHN0cmluZ3MgdGhhdCB3aGVuIGpvaW5lZCBmb3JtIGEgcGF0aCBzdHJpbmcsIHRvIGEgUGF0aC4KICAgICAgICAgKgogICAgICAgICAqIEBwYXJhbSBmaXJzdCAgdGhlIHBhdGggc3RyaW5nIG9yIGluaXRpYWwgcGFydCBvZiB0aGUgcGF0aCBzdHJpbmcKICAgICAgICAgKiBAcGFyYW0gbW9yZSAgIGFkZGl0aW9uYWwgc3RyaW5ncyB0byBiZSBqb2luZWQgdG8gZm9ybSB0aGUgcGF0aCBzdHJpbmcKICAgICAgICAgKiBAcmV0dXJuICAgICAgIHRoZSByZXN1bHRpbmcge0Bjb2RlIFBhdGh9CiAgICAgICAgICovCiAgICAgICAgUGF0aCBnZXRQYXRoKFN0cmluZyBmaXJzdCwgU3RyaW5nLi4uIG1vcmUpOwogICAgfQoKICAgICAvKioKICAgICAgKiBTcGVjaWZ5IGEgZmFjdG9yeSB0aGF0IGNhbiBiZSB1c2VkIHRvIGdlbmVyYXRlIGEgcGF0aCBmcm9tIGEgc3RyaW5nLCBvciBzZXJpZXMgb2Ygc3RyaW5ncy4KICAgICAgKgogICAgICAqIElmIHRoaXMgbWV0aG9kIGlzIG5vdCBjYWxsZWQsIGEgZmFjdG9yeSB3aG9zZSB7QGNvZGUgZ2V0UGF0aH0gbWV0aG9kIGlzCiAgICAgICogZXF1aXZhbGVudCB0byBjYWxsaW5nCiAgICAgICoge0BsaW5rIGphdmEubmlvLmZpbGUuUGF0aHMjZ2V0KFN0cmluZywgU3RyaW5nLi4uKSBqYXZhLm5pby5maWxlLlBhdGhzLmdldChmaXJzdCwgbW9yZSl9CiAgICAgICogd2lsbCBiZSB1c2VkLgogICAgICAqCiAgICAgICogQGltcGxTcGVjCiAgICAgICogVGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gb2YgdGhpcyBtZXRob2QgaWdub3JlcyB0aGUgZmFjdG9yeSB0aGF0IGlzIHByb3ZpZGVkLgogICAgICAqCiAgICAgICogQHBhcmFtIGYgIHRoZSBmYWN0b3J5CiAgICAgICoKICAgICAgKiBAc2luY2UgOQogICAgICAqLwogICAgZGVmYXVsdCB2b2lkIHNldFBhdGhGYWN0b3J5KFBhdGhGYWN0b3J5IGYpIHsgfQp9ClBLAwQKAAAIAAAGO6lK0t5uxVUTAABVEwAAIQAAAGphdmF4L3Rvb2xzL1N0YW5kYXJkTG9jYXRpb24uamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNiwgMjAxNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBqYXZheC50b29sczsKCmltcG9ydCBqYXZheC50b29scy5KYXZhRmlsZU1hbmFnZXIuTG9jYXRpb247CgppbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuKjsKCi8qKgogKiBTdGFuZGFyZCBsb2NhdGlvbnMgb2YgZmlsZSBvYmplY3RzLgogKgogKiBAYXV0aG9yIFBldGVyIHZvbiBkZXIgQWgmZWFjdXRlOwogKiBAc2luY2UgMS42CiAqLwpwdWJsaWMgZW51bSBTdGFuZGFyZExvY2F0aW9uIGltcGxlbWVudHMgTG9jYXRpb24gewoKICAgIC8qKgogICAgICogTG9jYXRpb24gb2YgbmV3IGNsYXNzIGZpbGVzLgogICAgICovCiAgICBDTEFTU19PVVRQVVQsCgogICAgLyoqCiAgICAgKiBMb2NhdGlvbiBvZiBuZXcgc291cmNlIGZpbGVzLgogICAgICovCiAgICBTT1VSQ0VfT1VUUFVULAoKICAgIC8qKgogICAgICogTG9jYXRpb24gdG8gc2VhcmNoIGZvciB1c2VyIGNsYXNzIGZpbGVzLgogICAgICovCiAgICBDTEFTU19QQVRILAoKICAgIC8qKgogICAgICogTG9jYXRpb24gdG8gc2VhcmNoIGZvciBleGlzdGluZyBzb3VyY2UgZmlsZXMuCiAgICAgKi8KICAgIFNPVVJDRV9QQVRILAoKICAgIC8qKgogICAgICogTG9jYXRpb24gdG8gc2VhcmNoIGZvciBhbm5vdGF0aW9uIHByb2Nlc3NvcnMuCiAgICAgKi8KICAgIEFOTk9UQVRJT05fUFJPQ0VTU09SX1BBVEgsCgogICAgLyoqCiAgICAgKiBMb2NhdGlvbiB0byBzZWFyY2ggZm9yIG1vZHVsZXMgY29udGFpbmluZyBhbm5vdGF0aW9uIHByb2Nlc3NvcnMuCiAgICAgKiBAc3BlYyBKUE1TCiAgICAgKiBAc2luY2UgOQogICAgICovCiAgICBBTk5PVEFUSU9OX1BST0NFU1NPUl9NT0RVTEVfUEFUSCwKCiAgICAvKioKICAgICAqIExvY2F0aW9uIHRvIHNlYXJjaCBmb3IgcGxhdGZvcm0gY2xhc3Nlcy4gIFNvbWV0aW1lcyBjYWxsZWQKICAgICAqIHRoZSBib290IGNsYXNzIHBhdGguCiAgICAgKi8KICAgIFBMQVRGT1JNX0NMQVNTX1BBVEgsCgogICAgLyoqCiAgICAgKiBMb2NhdGlvbiBvZiBuZXcgbmF0aXZlIGhlYWRlciBmaWxlcy4KICAgICAqIEBzaW5jZSAxLjgKICAgICAqLwogICAgTkFUSVZFX0hFQURFUl9PVVRQVVQsCgogICAgLyoqCiAgICAgKiBMb2NhdGlvbiB0byBzZWFyY2ggZm9yIHRoZSBzb3VyY2UgY29kZSBvZiBtb2R1bGVzLgogICAgICogQHNwZWMgSlBNUwogICAgICogQHNpbmNlIDkKICAgICAqLwogICAgTU9EVUxFX1NPVVJDRV9QQVRILAoKICAgIC8qKgogICAgICogTG9jYXRpb24gdG8gc2VhcmNoIGZvciB1cGdyYWRlYWJsZSBzeXN0ZW0gbW9kdWxlcy4KICAgICAqIEBzcGVjIEpQTVMKICAgICAqIEBzaW5jZSA5CiAgICAgKi8KICAgIFVQR1JBREVfTU9EVUxFX1BBVEgsCgogICAgLyoqCiAgICAgKiBMb2NhdGlvbiB0byBzZWFyY2ggZm9yIHN5c3RlbSBtb2R1bGVzLgogICAgICogQHNwZWMgSlBNUwogICAgICogQHNpbmNlIDkKICAgICAqLwogICAgU1lTVEVNX01PRFVMRVMsCgogICAgLyoqCiAgICAgKiBMb2NhdGlvbiB0byBzZWFyY2ggZm9yIHByZWNvbXBpbGVkIHVzZXIgbW9kdWxlcy4KICAgICAqIEBzcGVjIEpQTVMKICAgICAqIEBzaW5jZSA5CiAgICAgKi8KICAgIE1PRFVMRV9QQVRILAoKICAgIC8qKgogICAgICogTG9jYXRpb24gdG8gc2VhcmNoIGZvciBtb2R1bGUgcGF0Y2hlcy4KICAgICAqIEBzaW5jZSA5CiAgICAgKiBAc3BlYyBKUE1TCiAgICAgKi8KICAgIFBBVENIX01PRFVMRV9QQVRIOwoKICAgIC8qKgogICAgICogUmV0dXJucyBhIGxvY2F0aW9uIG9iamVjdCB3aXRoIHRoZSBnaXZlbiBuYW1lLiAgVGhlIGZvbGxvd2luZwogICAgICogcHJvcGVydHkgbXVzdCBob2xkOiB7QGNvZGUgbG9jYXRpb25Gb3IoeCkgPT0KICAgICAqIGxvY2F0aW9uRm9yKHkpfSBpZiBhbmQgb25seSBpZiB7QGNvZGUgeC5lcXVhbHMoeSl9LgogICAgICogVGhlIHJldHVybmVkIGxvY2F0aW9uIHdpbGwgYmUgYW4gb3V0cHV0IGxvY2F0aW9uIGlmIGFuZCBvbmx5IGlmCiAgICAgKiBuYW1lIGVuZHMgd2l0aCB7QGNvZGUgIl9PVVRQVVQifS4gSXQgd2lsbCBiZSBjb25zaWRlcmVkIHRvCiAgICAgKiBiZSBhIG1vZHVsZS1vcmllbnRlZCBsb2NhdGlvbiBpZiB0aGUgbmFtZSBjb250YWlucyB0aGUgd29yZAogICAgICoge0Bjb2RlICJNT0RVTEUifS4KICAgICAqCiAgICAgKiBAcGFyYW0gbmFtZSBhIG5hbWUKICAgICAqIEByZXR1cm4gYSBsb2NhdGlvbgogICAgICoKICAgICAqIEByZXZpc2VkIDkKICAgICAqIEBzcGVjIEpQTVMKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBMb2NhdGlvbiBsb2NhdGlvbkZvcihmaW5hbCBTdHJpbmcgbmFtZSkgewogICAgICAgIGlmIChsb2NhdGlvbnMuaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIC8vIGNhbid0IHVzZSB2YWx1ZU9mIHdoaWNoIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KICAgICAgICAgICAgZm9yIChMb2NhdGlvbiBsb2NhdGlvbiA6IHZhbHVlcygpKQogICAgICAgICAgICAgICAgbG9jYXRpb25zLnB1dElmQWJzZW50KGxvY2F0aW9uLmdldE5hbWUoKSwgbG9jYXRpb24pOwogICAgICAgIH0KICAgICAgICBuYW1lLmdldENsYXNzKCk7IC8qIG51bGwtY2hlY2sgKi8KICAgICAgICBsb2NhdGlvbnMucHV0SWZBYnNlbnQobmFtZSwgbmV3IExvY2F0aW9uKCkgewogICAgICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgICAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWUoKSB7IHJldHVybiBuYW1lOyB9CiAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgICAgIHB1YmxpYyBib29sZWFuIGlzT3V0cHV0TG9jYXRpb24oKSB7IHJldHVybiBuYW1lLmVuZHNXaXRoKCJfT1VUUFVUIik7IH0KICAgICAgICAgICAgfSk7CiAgICAgICAgcmV0dXJuIGxvY2F0aW9ucy5nZXQobmFtZSk7CiAgICB9CiAgICAvL3doZXJlCiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQ29uY3VycmVudE1hcDxTdHJpbmcsTG9jYXRpb24+IGxvY2F0aW9ucwogICAgICAgICAgICA9IG5ldyBDb25jdXJyZW50SGFzaE1hcDw+KCk7CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWUoKSB7IHJldHVybiBuYW1lKCk7IH0KCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGlzT3V0cHV0TG9jYXRpb24oKSB7CiAgICAgICAgc3dpdGNoICh0aGlzKSB7CiAgICAgICAgICAgIGNhc2UgQ0xBU1NfT1VUUFVUOgogICAgICAgICAgICBjYXNlIFNPVVJDRV9PVVRQVVQ6CiAgICAgICAgICAgIGNhc2UgTkFUSVZFX0hFQURFUl9PVVRQVVQ6CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBpc01vZHVsZU9yaWVudGVkTG9jYXRpb24oKSB7CiAgICAgICAgc3dpdGNoICh0aGlzKSB7CiAgICAgICAgICAgIGNhc2UgTU9EVUxFX1NPVVJDRV9QQVRIOgogICAgICAgICAgICBjYXNlIEFOTk9UQVRJT05fUFJPQ0VTU09SX01PRFVMRV9QQVRIOgogICAgICAgICAgICBjYXNlIFVQR1JBREVfTU9EVUxFX1BBVEg6CiAgICAgICAgICAgIGNhc2UgU1lTVEVNX01PRFVMRVM6CiAgICAgICAgICAgIGNhc2UgTU9EVUxFX1BBVEg6CiAgICAgICAgICAgIGNhc2UgUEFUQ0hfTU9EVUxFX1BBVEg6CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICB9Cn0KUEsDBAoAAAgAANJ9TUpHPqMz/wYAAP8GAAAZAAAAamF2YXgvdG9vbHMvb3ZlcnZpZXcuaHRtbDwhRE9DVFlQRSBIVE1MIFBVQkxJQyAiLS8vVzNDLy9EVEQgSFRNTCAzLjIgRmluYWwvL0VOIj4KPCEtLQpDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMTMsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCkRPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KClRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CnVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCnB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwpwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCmJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgoKVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCkFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgpGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KCllvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLApJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCgpQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQpvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CnF1ZXN0aW9ucy4KLS0+Cgo8aHRtbD4KPGhlYWQ+Cjx0aXRsZT5qYXZheC50b29sczwvdGl0bGU+CjwvaGVhZD4KPGJvZHk+Cgo8cD4KVGhlIEphdmEmdHJhZGU7IHByb2dyYW1taW5nIGxhbmd1YWdlIGNvbXBpbGVyIEFQSSBpcyBhIHNldCBvZiBpbnRlcmZhY2VzIHRoYXQgZGVzY3JpYmVzIHRoZQpmdW5jdGlvbnMgcHJvdmlkZWQgYnkgYSBjb21waWxlci4gIFRoaXMgQVBJIGhhcyB0aHJlZQptYWluIG9iamVjdGl2ZXM6CjwvcD4KCjx1bD4KCjxsaT5BbGxvdyBpbnZvY2F0aW9uIG9mIGEgY29tcGlsZXIgZnJvbSBhIHByb2dyYW0gdXNpbmcKc3RhbmRhcmRpemVkIGludGVyZmFjZXMuPC9saT4KCjxsaT5Qcm92aWRlIGludGVyZmFjZXMgZW5hYmxpbmcgdGhlIGNvbXBpbGVyIHRvIHJlcG9ydCBkaWFnbm9zdGljcyBpbiBhCnN0cnVjdHVyZWQgd2F5LjwvbGk+Cgo8bGk+UHJvdmlkZSBpbnRlcmZhY2VzIGVuYWJsaW5nIGNsaWVudHMgb2YgdGhlIGNvbXBpbGVyIHRvIG92ZXJyaWRlCmhvdyBmaWxlIG9iamVjdHMgYXJlIGZvdW5kLiAgIkZpbGUgb2JqZWN0cyIgaXMgYSBmaWxlCmFic3RyYWN0aW9uLjwvbGk+Cgo8L3VsPgoKPC9ib2R5Pgo8L2h0bWw+ClBLAwQKAAAIAADSfU1Kru/AQXwNAAB8DQAAHQAAAGphdmF4L3Rvb2xzL3BhY2thZ2UtaW5mby5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDA1LCAyMDA2LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgovKioKICogUHJvdmlkZXMgaW50ZXJmYWNlcyBmb3IgdG9vbHMgd2hpY2ggY2FuIGJlIGludm9rZWQgZnJvbSBhIHByb2dyYW0sCiAqIGZvciBleGFtcGxlLCBjb21waWxlcnMuCiAqCiAqIDxwPlRoZXNlIGludGVyZmFjZXMgYW5kIGNsYXNzZXMgYXJlIHJlcXVpcmVkIGFzIHBhcnQgb2YgdGhlCiAqIEphdmEmdHJhZGU7IFBsYXRmb3JtLCBTdGFuZGFyZCBFZGl0aW9uIChKYXZhIFNFKSwKICogYnV0IHRoZXJlIGlzIG5vIHJlcXVpcmVtZW50IHRvIHByb3ZpZGUgYW55IHRvb2xzIGltcGxlbWVudGluZyB0aGVtLgogKgogKiA8cD5Vbmxlc3MgZXhwbGljaXRseSBhbGxvd2VkLCBhbGwgbWV0aG9kcyBpbiB0aGlzIHBhY2thZ2UgbWlnaHQKICogdGhyb3cgYSB7QGxpbmtwbGFpbiBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb259IGlmIGdpdmVuIGEKICoge0Bjb2RlIG51bGx9IGFyZ3VtZW50IG9yIGlmIGdpdmVuIGEKICoge0BsaW5rcGxhaW4gamF2YS5sYW5nLkl0ZXJhYmxlIGxpc3Qgb3IgY29sbGVjdGlvbn0gY29udGFpbmluZwogKiB7QGNvZGUgbnVsbH0gZWxlbWVudHMuICBTaW1pbGFybHksIG5vIG1ldGhvZCBtYXkgcmV0dXJuCiAqIHtAY29kZSBudWxsfSB1bmxlc3MgZXhwbGljaXRseSBhbGxvd2VkLgogKgogKiA8cD5UaGlzIHBhY2thZ2UgaXMgdGhlIGhvbWUgb2YgdGhlIEphdmEgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2UgY29tcGlsZXIgZnJhbWV3b3JrLiAgVGhpcwogKiBmcmFtZXdvcmsgYWxsb3dzIGNsaWVudHMgb2YgdGhlIGZyYW1ld29yayB0byBsb2NhdGUgYW5kIHJ1bgogKiBjb21waWxlcnMgZnJvbSBwcm9ncmFtcy4gIFRoZSBmcmFtZXdvcmsgYWxzbyBwcm92aWRlcyBTZXJ2aWNlCiAqIFByb3ZpZGVyIEludGVyZmFjZXMgKFNQSSkgZm9yIHN0cnVjdHVyZWQgYWNjZXNzIHRvIGRpYWdub3N0aWNzCiAqICh7QGxpbmtwbGFpbiBqYXZheC50b29scy5EaWFnbm9zdGljTGlzdGVuZXJ9KSBhcyB3ZWxsIGFzIGEgZmlsZQogKiBhYnN0cmFjdGlvbiBmb3Igb3ZlcnJpZGluZyBmaWxlIGFjY2VzcyAoe0BsaW5rcGxhaW4KICogamF2YXgudG9vbHMuSmF2YUZpbGVNYW5hZ2VyfSBhbmQge0BsaW5rcGxhaW4KICogamF2YXgudG9vbHMuSmF2YUZpbGVPYmplY3R9KS4gIFNlZSB7QGxpbmtwbGFpbgogKiBqYXZheC50b29scy5KYXZhQ29tcGlsZXJ9IGZvciBtb3JlIGRldGFpbHMgb24gdXNpbmcgdGhlIFNQSS4KICoKICogPHA+VGhlcmUgaXMgbm8gcmVxdWlyZW1lbnQgZm9yIGEgY29tcGlsZXIgYXQgcnVudGltZS4gIEhvd2V2ZXIsIGlmCiAqIGEgZGVmYXVsdCBjb21waWxlciBpcyBwcm92aWRlZCwgaXQgY2FuIGJlIGxvY2F0ZWQgdXNpbmcgdGhlCiAqIHtAbGlua3BsYWluIGphdmF4LnRvb2xzLlRvb2xQcm92aWRlcn0sIGZvciBleGFtcGxlOgogKgogKiA8cD57QGNvZGUgSmF2YUNvbXBpbGVyIGNvbXBpbGVyID0gVG9vbFByb3ZpZGVyLmdldFN5c3RlbUphdmFDb21waWxlcigpO30KICoKICogPHA+SXQgaXMgcG9zc2libGUgdG8gcHJvdmlkZSBhbHRlcm5hdGl2ZSBjb21waWxlcnMgb3IgdG9vbHMKICogdGhyb3VnaCB0aGUge0BsaW5rcGxhaW4gamF2YS51dGlsLlNlcnZpY2VMb2FkZXIgc2VydmljZSBwcm92aWRlcgogKiBtZWNoYW5pc219LgogKgogKiA8cD5Gb3IgZXhhbXBsZSwgaWYge0Bjb2RlIGNvbS52ZW5kb3IuVmVuZG9ySmF2YUNvbXBpbGVyfSBpcyBhCiAqIHByb3ZpZGVyIG9mIHRoZSB7QGNvZGUgSmF2YUNvbXBpbGVyfSB0b29sIHRoZW4gaXRzIGphciBmaWxlCiAqIHdvdWxkIGNvbnRhaW4gdGhlIGZpbGUge0Bjb2RlCiAqIE1FVEEtSU5GL3NlcnZpY2VzL2phdmF4LnRvb2xzLkphdmFDb21waWxlcn0uICBUaGlzIGZpbGUgd291bGQKICogY29udGFpbiB0aGUgc2luZ2xlIGxpbmU6CiAqCiAqIDxwPntAY29kZSBjb20udmVuZG9yLlZlbmRvckphdmFDb21waWxlcn0KICoKICogPHA+SWYgdGhlIGphciBmaWxlIGlzIG9uIHRoZSBjbGFzcyBwYXRoLCBWZW5kb3JKYXZhQ29tcGlsZXIgY2FuIGJlCiAqIGxvY2F0ZWQgdXNpbmcgY29kZSBsaWtlIHRoaXM6CiAqCiAqIDxwPntAY29kZSBKYXZhQ29tcGlsZXIgY29tcGlsZXIgPSBTZXJ2aWNlTG9hZGVyLmxvYWQoSmF2YUNvbXBpbGVyLmNsYXNzKS5pdGVyYXRvcigpLm5leHQoKTt9CiAqCiAqIEBhdXRob3IgUGV0ZXIgdm9uIGRlciBBaCZlYWN1dGU7CiAqIEBhdXRob3IgSm9uYXRoYW4gR2liYm9ucwogKiBAc2luY2UgMS42CiAqLwpwYWNrYWdlIGphdmF4LnRvb2xzOwpQSwMECgAACAAA0n1NSqW60BnXFwAA1xcAABsAAABqYXZheC90b29scy9GaWxlT2JqZWN0LmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDYsIDIwMTQsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgamF2YXgudG9vbHM7CgppbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CmltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKaW1wb3J0IGphdmEuaW8uUmVhZGVyOwppbXBvcnQgamF2YS5pby5Xcml0ZXI7CmltcG9ydCBqYXZhLm5ldC5VUkk7CgovKioKICogRmlsZSBhYnN0cmFjdGlvbiBmb3IgdG9vbHMuICBJbiB0aGlzIGNvbnRleHQsIDxlbT5maWxlPC9lbT4gbWVhbnMKICogYW4gYWJzdHJhY3Rpb24gb2YgcmVndWxhciBmaWxlcyBhbmQgb3RoZXIgc291cmNlcyBvZiBkYXRhLiAgRm9yCiAqIGV4YW1wbGUsIGEgZmlsZSBvYmplY3QgY2FuIGJlIHVzZWQgdG8gcmVwcmVzZW50IHJlZ3VsYXIgZmlsZXMsCiAqIG1lbW9yeSBjYWNoZSwgb3IgZGF0YSBpbiBkYXRhYmFzZXMuCiAqCiAqIDxwPkFsbCBtZXRob2RzIGluIHRoaXMgaW50ZXJmYWNlIG1pZ2h0IHRocm93IGEgU2VjdXJpdHlFeGNlcHRpb24gaWYKICogYSBzZWN1cml0eSBleGNlcHRpb24gb2NjdXJzLgogKgogKiA8cD5Vbmxlc3MgZXhwbGljaXRseSBhbGxvd2VkLCBhbGwgbWV0aG9kcyBpbiB0aGlzIGludGVyZmFjZSBtaWdodAogKiB0aHJvdyBhIE51bGxQb2ludGVyRXhjZXB0aW9uIGlmIGdpdmVuIGEge0Bjb2RlIG51bGx9IGFyZ3VtZW50LgogKgogKiBAYXV0aG9yIFBldGVyIHZvbiBkZXIgQWgmZWFjdXRlOwogKiBAYXV0aG9yIEpvbmF0aGFuIEdpYmJvbnMKICogQHNpbmNlIDEuNgogKi8KcHVibGljIGludGVyZmFjZSBGaWxlT2JqZWN0IHsKCiAgICAvKioKICAgICAqIFJldHVybnMgYSBVUkkgaWRlbnRpZnlpbmcgdGhpcyBmaWxlIG9iamVjdC4KICAgICAqIEByZXR1cm4gYSBVUkkKICAgICAqLwogICAgVVJJIHRvVXJpKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgdXNlci1mcmllbmRseSBuYW1lIGZvciB0aGlzIGZpbGUgb2JqZWN0LiAgVGhlIGV4YWN0CiAgICAgKiB2YWx1ZSByZXR1cm5lZCBpcyBub3Qgc3BlY2lmaWVkIGJ1dCBpbXBsZW1lbnRhdGlvbnMgc2hvdWxkIHRha2UKICAgICAqIGNhcmUgdG8gcHJlc2VydmUgbmFtZXMgYXMgZ2l2ZW4gYnkgdGhlIHVzZXIuICBGb3IgZXhhbXBsZSwgaWYKICAgICAqIHRoZSB1c2VyIHdyaXRlcyB0aGUgZmlsZW5hbWUge0Bjb2RlICJCb2JzQXBwXFRlc3QuamF2YSJ9IG9uCiAgICAgKiB0aGUgY29tbWFuZCBsaW5lLCB0aGlzIG1ldGhvZCBzaG91bGQgcmV0dXJuIHtAY29kZQogICAgICogIkJvYnNBcHBcVGVzdC5qYXZhIn0gd2hlcmVhcyB0aGUge0BsaW5rcGxhaW4gI3RvVXJpIHRvVXJpfQogICAgICogbWV0aG9kIG1pZ2h0IHJldHVybiB7QGNvZGUKICAgICAqIGZpbGU6Ly8vQzovRG9jdW1lbnRzJTIwYW5kJTIwU2V0dGluZ3MvVW5jbGVCb2IvQm9ic0FwcC9UZXN0LmphdmF9LgogICAgICoKICAgICAqIEByZXR1cm4gYSB1c2VyLWZyaWVuZGx5IG5hbWUKICAgICAqLwogICAgU3RyaW5nIGdldE5hbWUoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgYW4gSW5wdXRTdHJlYW0gZm9yIHRoaXMgZmlsZSBvYmplY3QuCiAgICAgKgogICAgICogQHJldHVybiBhbiBJbnB1dFN0cmVhbQogICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhpcyBmaWxlIG9iamVjdCB3YXMKICAgICAqIG9wZW5lZCBmb3Igd3JpdGluZyBhbmQgZG9lcyBub3Qgc3VwcG9ydCByZWFkaW5nCiAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGlmIHRoaXMga2luZCBvZiBmaWxlCiAgICAgKiBvYmplY3QgZG9lcyBub3Qgc3VwcG9ydCBieXRlIGFjY2VzcwogICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiBhbiBJL08gZXJyb3Igb2NjdXJyZWQKICAgICAqLwogICAgSW5wdXRTdHJlYW0gb3BlbklucHV0U3RyZWFtKCkgdGhyb3dzIElPRXhjZXB0aW9uOwoKICAgIC8qKgogICAgICogUmV0dXJucyBhbiBPdXRwdXRTdHJlYW0gZm9yIHRoaXMgZmlsZSBvYmplY3QuCiAgICAgKgogICAgICogQHJldHVybiBhbiBPdXRwdXRTdHJlYW0KICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoaXMgZmlsZSBvYmplY3Qgd2FzCiAgICAgKiBvcGVuZWQgZm9yIHJlYWRpbmcgYW5kIGRvZXMgbm90IHN1cHBvcnQgd3JpdGluZwogICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBpZiB0aGlzIGtpbmQgb2YKICAgICAqIGZpbGUgb2JqZWN0IGRvZXMgbm90IHN1cHBvcnQgYnl0ZSBhY2Nlc3MKICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgYW4gSS9PIGVycm9yIG9jY3VycmVkCiAgICAgKi8KICAgIE91dHB1dFN0cmVhbSBvcGVuT3V0cHV0U3RyZWFtKCkgdGhyb3dzIElPRXhjZXB0aW9uOwoKICAgIC8qKgogICAgICogUmV0dXJucyBhIHJlYWRlciBmb3IgdGhpcyBvYmplY3QuICBUaGUgcmV0dXJuZWQgcmVhZGVyIHdpbGwKICAgICAqIHJlcGxhY2UgYnl0ZXMgdGhhdCBjYW5ub3QgYmUgZGVjb2RlZCB3aXRoIHRoZSBkZWZhdWx0CiAgICAgKiB0cmFuc2xhdGlvbiBjaGFyYWN0ZXIuICBJbiBhZGRpdGlvbiwgdGhlIHJlYWRlciBtYXkgcmVwb3J0IGEKICAgICAqIGRpYWdub3N0aWMgdW5sZXNzIHtAY29kZSBpZ25vcmVFbmNvZGluZ0Vycm9yc30gaXMgdHJ1ZS4KICAgICAqCiAgICAgKiBAcGFyYW0gaWdub3JlRW5jb2RpbmdFcnJvcnMgaWdub3JlIGVuY29kaW5nIGVycm9ycyBpZiB0cnVlCiAgICAgKiBAcmV0dXJuIGEgUmVhZGVyCiAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB0aGlzIGZpbGUgb2JqZWN0IHdhcwogICAgICogb3BlbmVkIGZvciB3cml0aW5nIGFuZCBkb2VzIG5vdCBzdXBwb3J0IHJlYWRpbmcKICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gaWYgdGhpcyBraW5kIG9mCiAgICAgKiBmaWxlIG9iamVjdCBkb2VzIG5vdCBzdXBwb3J0IGNoYXJhY3RlciBhY2Nlc3MKICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgYW4gSS9PIGVycm9yIG9jY3VycmVkCiAgICAgKi8KICAgIFJlYWRlciBvcGVuUmVhZGVyKGJvb2xlYW4gaWdub3JlRW5jb2RpbmdFcnJvcnMpIHRocm93cyBJT0V4Y2VwdGlvbjsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGNoYXJhY3RlciBjb250ZW50IG9mIHRoaXMgZmlsZSBvYmplY3QsIGlmIGF2YWlsYWJsZS4KICAgICAqIEFueSBieXRlIHRoYXQgY2Fubm90IGJlIGRlY29kZWQgd2lsbCBiZSByZXBsYWNlZCBieSB0aGUgZGVmYXVsdAogICAgICogdHJhbnNsYXRpb24gY2hhcmFjdGVyLiAgSW4gYWRkaXRpb24sIGEgZGlhZ25vc3RpYyBtYXkgYmUKICAgICAqIHJlcG9ydGVkIHVubGVzcyB7QGNvZGUgaWdub3JlRW5jb2RpbmdFcnJvcnN9IGlzIHRydWUuCiAgICAgKgogICAgICogQHBhcmFtIGlnbm9yZUVuY29kaW5nRXJyb3JzIGlnbm9yZSBlbmNvZGluZyBlcnJvcnMgaWYgdHJ1ZQogICAgICogQHJldHVybiBhIENoYXJTZXF1ZW5jZSBpZiBhdmFpbGFibGU7IHtAY29kZSBudWxsfSBvdGhlcndpc2UKICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoaXMgZmlsZSBvYmplY3Qgd2FzCiAgICAgKiBvcGVuZWQgZm9yIHdyaXRpbmcgYW5kIGRvZXMgbm90IHN1cHBvcnQgcmVhZGluZwogICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBpZiB0aGlzIGtpbmQgb2YKICAgICAqIGZpbGUgb2JqZWN0IGRvZXMgbm90IHN1cHBvcnQgY2hhcmFjdGVyIGFjY2VzcwogICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiBhbiBJL08gZXJyb3Igb2NjdXJyZWQKICAgICAqLwogICAgQ2hhclNlcXVlbmNlIGdldENoYXJDb250ZW50KGJvb2xlYW4gaWdub3JlRW5jb2RpbmdFcnJvcnMpIHRocm93cyBJT0V4Y2VwdGlvbjsKCiAgICAvKioKICAgICAqIFJldHVybnMgYSBXcml0ZXIgZm9yIHRoaXMgZmlsZSBvYmplY3QuCiAgICAgKgogICAgICogQHJldHVybiBhIFdyaXRlcgogICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhpcyBmaWxlIG9iamVjdCB3YXMKICAgICAqIG9wZW5lZCBmb3IgcmVhZGluZyBhbmQgZG9lcyBub3Qgc3VwcG9ydCB3cml0aW5nCiAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGlmIHRoaXMga2luZCBvZgogICAgICogZmlsZSBvYmplY3QgZG9lcyBub3Qgc3VwcG9ydCBjaGFyYWN0ZXIgYWNjZXNzCiAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIGFuIEkvTyBlcnJvciBvY2N1cnJlZAogICAgICovCiAgICBXcml0ZXIgb3BlbldyaXRlcigpIHRocm93cyBJT0V4Y2VwdGlvbjsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHRpbWUgdGhpcyBmaWxlIG9iamVjdCB3YXMgbGFzdCBtb2RpZmllZC4gIFRoZSB0aW1lIGlzCiAgICAgKiBtZWFzdXJlZCBpbiBtaWxsaXNlY29uZHMgc2luY2UgdGhlIGVwb2NoICgwMDowMDowMCBHTVQsIEphbnVhcnkKICAgICAqIDEsIDE5NzApLgogICAgICoKICAgICAqIEByZXR1cm4gdGhlIHRpbWUgdGhpcyBmaWxlIG9iamVjdCB3YXMgbGFzdCBtb2RpZmllZDsgb3IgMCBpZgogICAgICogdGhlIGZpbGUgb2JqZWN0IGRvZXMgbm90IGV4aXN0LCBpZiBhbiBJL08gZXJyb3Igb2NjdXJyZWQsIG9yIGlmCiAgICAgKiB0aGUgb3BlcmF0aW9uIGlzIG5vdCBzdXBwb3J0ZWQKICAgICAqLwogICAgbG9uZyBnZXRMYXN0TW9kaWZpZWQoKTsKCiAgICAvKioKICAgICAqIERlbGV0ZXMgdGhpcyBmaWxlIG9iamVjdC4gIEluIGNhc2Ugb2YgZXJyb3JzLCByZXR1cm5zIGZhbHNlLgogICAgICogQHJldHVybiB0cnVlIGlmIGFuZCBvbmx5IGlmIHRoaXMgZmlsZSBvYmplY3QgaXMgc3VjY2Vzc2Z1bGx5CiAgICAgKiBkZWxldGVkOyBmYWxzZSBvdGhlcndpc2UKICAgICAqLwogICAgYm9vbGVhbiBkZWxldGUoKTsKCn0KUEsDBAoAAAgAAAY7qUpr1nEcSB0AAEgdAAAiAAAAamF2YXgvdG9vbHMvRG9jdW1lbnRhdGlvblRvb2wuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAxNywgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBqYXZheC50b29sczsKCmltcG9ydCBqYXZhLmlvLldyaXRlcjsKaW1wb3J0IGphdmEubmlvLmNoYXJzZXQuQ2hhcnNldDsKaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CmltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5DYWxsYWJsZTsKCi8qKgogKiBJbnRlcmZhY2UgdG8gaW52b2tlIEphdmEmdHJhZGU7IHByb2dyYW1taW5nIGxhbmd1YWdlIGRvY3VtZW50YXRpb24gdG9vbHMgZnJvbQogKiBwcm9ncmFtcy4KICovCnB1YmxpYyBpbnRlcmZhY2UgRG9jdW1lbnRhdGlvblRvb2wgZXh0ZW5kcyBUb29sLCBPcHRpb25DaGVja2VyIHsKICAgIC8qKgogICAgICogQ3JlYXRlcyBhIGZ1dHVyZSBmb3IgYSBkb2N1bWVudGF0aW9uIHRhc2sgd2l0aCB0aGUgZ2l2ZW4KICAgICAqIGNvbXBvbmVudHMgYW5kIGFyZ3VtZW50cy4gIFRoZSB0YXNrIG1pZ2h0IG5vdCBoYXZlCiAgICAgKiBjb21wbGV0ZWQgYXMgZGVzY3JpYmVkIGluIHRoZSBEb2N1bWVudGF0aW9uVGFzayBpbnRlcmZhY2UuCiAgICAgKgogICAgICogPHA+SWYgYSBmaWxlIG1hbmFnZXIgaXMgcHJvdmlkZWQsIGl0IG11c3QgYmUgYWJsZSB0byBoYW5kbGUgYWxsCiAgICAgKiBsb2NhdGlvbnMgZGVmaW5lZCBpbiB7QGxpbmsgRG9jdW1lbnRhdGlvblRvb2wuTG9jYXRpb259LAogICAgICogYXMgd2VsbCBhcwogICAgICoge0BsaW5rIFN0YW5kYXJkTG9jYXRpb24jU09VUkNFX1BBVEh9LAogICAgICoge0BsaW5rIFN0YW5kYXJkTG9jYXRpb24jQ0xBU1NfUEFUSH0sIGFuZAogICAgICoge0BsaW5rIFN0YW5kYXJkTG9jYXRpb24jUExBVEZPUk1fQ0xBU1NfUEFUSH0uCiAgICAgKgogICAgICogQHBhcmFtIG91dCBhIFdyaXRlciBmb3IgYWRkaXRpb25hbCBvdXRwdXQgZnJvbSB0aGUgdG9vbDsKICAgICAqIHVzZSB7QGNvZGUgU3lzdGVtLmVycn0gaWYge0Bjb2RlIG51bGx9CiAgICAgKgogICAgICogQHBhcmFtIGZpbGVNYW5hZ2VyIGEgZmlsZSBtYW5hZ2VyOyBpZiB7QGNvZGUgbnVsbH0gdXNlIHRoZQogICAgICogdG9vbCdzIHN0YW5kYXJkIGZpbGVtYW5hZ2VyCiAgICAgKgogICAgICogQHBhcmFtIGRpYWdub3N0aWNMaXN0ZW5lciBhIGRpYWdub3N0aWMgbGlzdGVuZXI7IGlmIHtAY29kZSBudWxsfQogICAgICogdXNlIHRoZSB0b29sJ3MgZGVmYXVsdCBtZXRob2QgZm9yIHJlcG9ydGluZyBkaWFnbm9zdGljcwogICAgICoKICAgICAqIEBwYXJhbSBkb2NsZXRDbGFzcyBhIGNsYXNzIHByb3ZpZGluZyB0aGUgbmVjZXNzYXJ5IG1ldGhvZHMgcmVxdWlyZWQKICAgICAqIG9mIGEgZG9jbGV0OyBhIHZhbHVlIG9mIHtAY29kZSBudWxsfSBtZWFucyB0byB1c2UgdGhlIHN0YW5kYXJkIGRvY2xldC4KICAgICAqCiAgICAgKiBAcGFyYW0gb3B0aW9ucyBkb2N1bWVudGF0aW9uIHRvb2wgb3B0aW9ucyBhbmQgZG9jbGV0IG9wdGlvbnMsCiAgICAgKiB7QGNvZGUgbnVsbH0gbWVhbnMgbm8gb3B0aW9ucwogICAgICoKICAgICAqIEBwYXJhbSBjb21waWxhdGlvblVuaXRzIHRoZSBjb21waWxhdGlvbiB1bml0cyB0byBjb21waWxlLCB7QGNvZGUKICAgICAqIG51bGx9IG1lYW5zIG5vIGNvbXBpbGF0aW9uIHVuaXRzCiAgICAgKgogICAgICogQHJldHVybiBhbiBvYmplY3QgcmVwcmVzZW50aW5nIHRoZSBjb21waWxhdGlvbgogICAgICoKICAgICAqIEB0aHJvd3MgUnVudGltZUV4Y2VwdGlvbiBpZiBhbiB1bnJlY292ZXJhYmxlIGVycm9yCiAgICAgKiBvY2N1cnJlZCBpbiBhIHVzZXIgc3VwcGxpZWQgY29tcG9uZW50LiAgVGhlCiAgICAgKiB7QGxpbmtwbGFpbiBUaHJvd2FibGUjZ2V0Q2F1c2UoKSBjYXVzZX0gd2lsbCBiZSB0aGUgZXJyb3IgaW4KICAgICAqIHVzZXIgY29kZS4KICAgICAqCiAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiBhbnkgb2YgdGhlIGdpdmVuCiAgICAgKiBjb21waWxhdGlvbiB1bml0cyBhcmUgb2Ygb3RoZXIga2luZCB0aGFuCiAgICAgKiB7QGxpbmtwbGFpbiBKYXZhRmlsZU9iamVjdC5LaW5kI1NPVVJDRSBzb3VyY2V9CiAgICAgKi8KICAgIERvY3VtZW50YXRpb25UYXNrIGdldFRhc2soV3JpdGVyIG91dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEphdmFGaWxlTWFuYWdlciBmaWxlTWFuYWdlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIERpYWdub3N0aWNMaXN0ZW5lcjw/IHN1cGVyIEphdmFGaWxlT2JqZWN0PiBkaWFnbm9zdGljTGlzdGVuZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBDbGFzczw/PiBkb2NsZXRDbGFzcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEl0ZXJhYmxlPFN0cmluZz4gb3B0aW9ucywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEl0ZXJhYmxlPD8gZXh0ZW5kcyBKYXZhRmlsZU9iamVjdD4gY29tcGlsYXRpb25Vbml0cyk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgbmV3IGluc3RhbmNlIG9mIHRoZSBzdGFuZGFyZCBmaWxlIG1hbmFnZXIgaW1wbGVtZW50YXRpb24KICAgICAqIGZvciB0aGlzIHRvb2wuICBUaGUgZmlsZSBtYW5hZ2VyIHdpbGwgdXNlIHRoZSBnaXZlbiBkaWFnbm9zdGljCiAgICAgKiBsaXN0ZW5lciBmb3IgcHJvZHVjaW5nIGFueSBub24tZmF0YWwgZGlhZ25vc3RpY3MuICBGYXRhbCBlcnJvcnMKICAgICAqIHdpbGwgYmUgc2lnbmFsZWQgd2l0aCB0aGUgYXBwcm9wcmlhdGUgZXhjZXB0aW9ucy4KICAgICAqCiAgICAgKiA8cD5UaGUgc3RhbmRhcmQgZmlsZSBtYW5hZ2VyIHdpbGwgYmUgYXV0b21hdGljYWxseSByZW9wZW5lZCBpZgogICAgICogaXQgaXMgYWNjZXNzZWQgYWZ0ZXIgY2FsbHMgdG8ge0Bjb2RlIGZsdXNofSBvciB7QGNvZGUgY2xvc2V9LgogICAgICogVGhlIHN0YW5kYXJkIGZpbGUgbWFuYWdlciBtdXN0IGJlIHVzYWJsZSB3aXRoIG90aGVyIHRvb2xzLgogICAgICoKICAgICAqIEBwYXJhbSBkaWFnbm9zdGljTGlzdGVuZXIgYSBkaWFnbm9zdGljIGxpc3RlbmVyIGZvciBub24tZmF0YWwKICAgICAqIGRpYWdub3N0aWNzOyBpZiB7QGNvZGUgbnVsbH0gdXNlIHRoZSBjb21waWxlcidzIGRlZmF1bHQgbWV0aG9kCiAgICAgKiBmb3IgcmVwb3J0aW5nIGRpYWdub3N0aWNzCiAgICAgKgogICAgICogQHBhcmFtIGxvY2FsZSB0aGUgbG9jYWxlIHRvIGFwcGx5IHdoZW4gZm9ybWF0dGluZyBkaWFnbm9zdGljczsKICAgICAqIHtAY29kZSBudWxsfSBtZWFucyB0aGUge0BsaW5rcGxhaW4gTG9jYWxlI2dldERlZmF1bHQoKSBkZWZhdWx0IGxvY2FsZX0uCiAgICAgKgogICAgICogQHBhcmFtIGNoYXJzZXQgdGhlIGNoYXJhY3RlciBzZXQgdXNlZCBmb3IgZGVjb2RpbmcgYnl0ZXM7IGlmCiAgICAgKiB7QGNvZGUgbnVsbH0gdXNlIHRoZSBwbGF0Zm9ybSBkZWZhdWx0CiAgICAgKgogICAgICogQHJldHVybiB0aGUgc3RhbmRhcmQgZmlsZSBtYW5hZ2VyCiAgICAgKi8KICAgIFN0YW5kYXJkSmF2YUZpbGVNYW5hZ2VyIGdldFN0YW5kYXJkRmlsZU1hbmFnZXIoCiAgICAgICAgRGlhZ25vc3RpY0xpc3RlbmVyPD8gc3VwZXIgSmF2YUZpbGVPYmplY3Q+IGRpYWdub3N0aWNMaXN0ZW5lciwKICAgICAgICBMb2NhbGUgbG9jYWxlLAogICAgICAgIENoYXJzZXQgY2hhcnNldCk7CgogICAgLyoqCiAgICAgKiBJbnRlcmZhY2UgcmVwcmVzZW50aW5nIGEgZnV0dXJlIGZvciBhIGRvY3VtZW50YXRpb24gdGFzay4gIFRoZQogICAgICogdGFzayBoYXMgbm90IHlldCBzdGFydGVkLiAgVG8gc3RhcnQgdGhlIHRhc2ssIGNhbGwKICAgICAqIHRoZSB7QGxpbmtwbGFpbiAjY2FsbCBjYWxsfSBtZXRob2QuCiAgICAgKgogICAgICogPHA+QmVmb3JlIGNhbGxpbmcgdGhlIGNhbGwgbWV0aG9kLCBhZGRpdGlvbmFsIGFzcGVjdHMgb2YgdGhlCiAgICAgKiB0YXNrIGNhbiBiZSBjb25maWd1cmVkLCBmb3IgZXhhbXBsZSwgYnkgY2FsbGluZyB0aGUKICAgICAqIHtAbGlua3BsYWluICNzZXRMb2NhbGUgc2V0TG9jYWxlfSBtZXRob2QuCiAgICAgKi8KICAgIGludGVyZmFjZSBEb2N1bWVudGF0aW9uVGFzayBleHRlbmRzIENhbGxhYmxlPEJvb2xlYW4+IHsKICAgICAgICAvKioKICAgICAgICAgKiBBZGRzIHJvb3QgbW9kdWxlcyB0byBiZSB0YWtlbiBpbnRvIGFjY291bnQgZHVyaW5nIG1vZHVsZQogICAgICAgICAqIHJlc29sdXRpb24uCiAgICAgICAgICogSW52YWxpZCBtb2R1bGUgbmFtZXMgbWF5IGNhdXNlIGVpdGhlcgogICAgICAgICAqIHtAY29kZSBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb259IHRvIGJlIHRocm93biwKICAgICAgICAgKiBvciBkaWFnbm9zdGljcyB0byBiZSByZXBvcnRlZCB3aGVuIHRoZSB0YXNrIGlzIHN0YXJ0ZWQuCiAgICAgICAgICogQHBhcmFtIG1vZHVsZU5hbWVzIHRoZSBuYW1lcyBvZiB0aGUgcm9vdCBtb2R1bGVzCiAgICAgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gbWF5IGJlIHRocm93biBmb3Igc29tZQogICAgICAgICAqICAgICAgaW52YWxpZCBtb2R1bGUgbmFtZXMKICAgICAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB0aGUgdGFzayBoYXMgc3RhcnRlZAogICAgICAgICAqLwogICAgICAgIHZvaWQgYWRkTW9kdWxlcyhJdGVyYWJsZTxTdHJpbmc+IG1vZHVsZU5hbWVzKTsKCiAgICAgICAgLyoqCiAgICAgICAgICogU2V0cyB0aGUgbG9jYWxlIHRvIGJlIGFwcGxpZWQgd2hlbiBmb3JtYXR0aW5nIGRpYWdub3N0aWNzIGFuZAogICAgICAgICAqIG90aGVyIGxvY2FsaXplZCBkYXRhLgogICAgICAgICAqCiAgICAgICAgICogQHBhcmFtIGxvY2FsZSB0aGUgbG9jYWxlIHRvIGFwcGx5OyB7QGNvZGUgbnVsbH0gbWVhbnMgYXBwbHkgbm8KICAgICAgICAgKiBsb2NhbGUKICAgICAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB0aGUgdGFzayBoYXMgc3RhcnRlZAogICAgICAgICAqLwogICAgICAgIHZvaWQgc2V0TG9jYWxlKExvY2FsZSBsb2NhbGUpOwoKICAgICAgICAvKioKICAgICAgICAgKiBQZXJmb3JtcyB0aGlzIGRvY3VtZW50YXRpb24gdGFzay4gIFRoZSB0YXNrIG1heSBvbmx5CiAgICAgICAgICogYmUgcGVyZm9ybWVkIG9uY2UuICBTdWJzZXF1ZW50IGNhbGxzIHRvIHRoaXMgbWV0aG9kIHRocm93CiAgICAgICAgICogSWxsZWdhbFN0YXRlRXhjZXB0aW9uLgogICAgICAgICAqCiAgICAgICAgICogQHJldHVybiB0cnVlIGlmIGFuZCBvbmx5IGFsbCB0aGUgZmlsZXMgd2VyZSBwcm9jZXNzZWQgd2l0aG91dCBlcnJvcnM7CiAgICAgICAgICogZmFsc2Ugb3RoZXJ3aXNlCiAgICAgICAgICoKICAgICAgICAgKiBAdGhyb3dzIFJ1bnRpbWVFeGNlcHRpb24gaWYgYW4gdW5yZWNvdmVyYWJsZSBlcnJvciBvY2N1cnJlZAogICAgICAgICAqIGluIGEgdXNlci1zdXBwbGllZCBjb21wb25lbnQuICBUaGUKICAgICAgICAgKiB7QGxpbmtwbGFpbiBUaHJvd2FibGUjZ2V0Q2F1c2UoKSBjYXVzZX0gd2lsbCBiZSB0aGUgZXJyb3IKICAgICAgICAgKiBpbiB1c2VyIGNvZGUuCiAgICAgICAgICoKICAgICAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiBjYWxsZWQgbW9yZSB0aGFuIG9uY2UKICAgICAgICAgKi8KICAgICAgICBCb29sZWFuIGNhbGwoKTsKICAgIH0KCiAgICAvKioKICAgICAqIExvY2F0aW9ucyBzcGVjaWZpYyB0byB7QGxpbmsgRG9jdW1lbnRhdGlvblRvb2x9LgogICAgICoKICAgICAqIEBzZWUgU3RhbmRhcmRMb2NhdGlvbgogICAgICovCiAgICBlbnVtIExvY2F0aW9uIGltcGxlbWVudHMgSmF2YUZpbGVNYW5hZ2VyLkxvY2F0aW9uIHsKICAgICAgICAvKioKICAgICAgICAgKiBMb2NhdGlvbiBvZiBuZXcgZG9jdW1lbnRhdGlvbiBmaWxlcy4KICAgICAgICAgKi8KICAgICAgICBET0NVTUVOVEFUSU9OX09VVFBVVCwKCiAgICAgICAgLyoqCiAgICAgICAgICogTG9jYXRpb24gdG8gc2VhcmNoIGZvciBkb2NsZXRzLgogICAgICAgICAqLwogICAgICAgIERPQ0xFVF9QQVRILAoKICAgICAgICAvKioKICAgICAgICAgKiBMb2NhdGlvbiB0byBzZWFyY2ggZm9yIHRhZ2xldHMuCiAgICAgICAgICovCiAgICAgICAgVEFHTEVUX1BBVEg7CgogICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZSgpIHsgcmV0dXJuIG5hbWUoKTsgfQoKICAgICAgICBwdWJsaWMgYm9vbGVhbiBpc091dHB1dExvY2F0aW9uKCkgewogICAgICAgICAgICBzd2l0Y2ggKHRoaXMpIHsKICAgICAgICAgICAgICAgIGNhc2UgRE9DVU1FTlRBVElPTl9PVVRQVVQ6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCn0KUEsDBAoAAAgAAAY7qUoux4BrSQ8AAEkPAAAlAAAAamF2YXgvdG9vbHMvRm9yd2FyZGluZ0ZpbGVPYmplY3QuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBqYXZheC50b29sczsKCmltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwppbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOwppbXBvcnQgamF2YS5pby5SZWFkZXI7CmltcG9ydCBqYXZhLmlvLldyaXRlcjsKaW1wb3J0IGphdmEubmV0LlVSSTsKaW1wb3J0IGphdmEudXRpbC5PYmplY3RzOwoKLyoqCiAqIEZvcndhcmRzIGNhbGxzIHRvIGEgZ2l2ZW4gZmlsZSBvYmplY3QuICBTdWJjbGFzc2VzIG9mIHRoaXMgY2xhc3MKICogbWlnaHQgb3ZlcnJpZGUgc29tZSBvZiB0aGVzZSBtZXRob2RzIGFuZCBtaWdodCBhbHNvIHByb3ZpZGUKICogYWRkaXRpb25hbCBmaWVsZHMgYW5kIG1ldGhvZHMuCiAqCiAqIEBwYXJhbSA8Rj4gdGhlIGtpbmQgb2YgZmlsZSBvYmplY3QgZm9yd2FyZGVkIHRvIGJ5IHRoaXMgb2JqZWN0CiAqIEBhdXRob3IgUGV0ZXIgdm9uIGRlciBBaCZlYWN1dGU7CiAqIEBzaW5jZSAxLjYKICovCnB1YmxpYyBjbGFzcyBGb3J3YXJkaW5nRmlsZU9iamVjdDxGIGV4dGVuZHMgRmlsZU9iamVjdD4gaW1wbGVtZW50cyBGaWxlT2JqZWN0IHsKCiAgICAvKioKICAgICAqIFRoZSBmaWxlIG9iamVjdCB3aGljaCBhbGwgbWV0aG9kcyBhcmUgZGVsZWdhdGVkIHRvLgogICAgICovCiAgICBwcm90ZWN0ZWQgZmluYWwgRiBmaWxlT2JqZWN0OwoKICAgIC8qKgogICAgICogQ3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBvZiBGb3J3YXJkaW5nRmlsZU9iamVjdC4KICAgICAqIEBwYXJhbSBmaWxlT2JqZWN0IGRlbGVnYXRlIHRvIHRoaXMgZmlsZSBvYmplY3QKICAgICAqLwogICAgcHJvdGVjdGVkIEZvcndhcmRpbmdGaWxlT2JqZWN0KEYgZmlsZU9iamVjdCkgewogICAgICAgIHRoaXMuZmlsZU9iamVjdCA9IE9iamVjdHMucmVxdWlyZU5vbk51bGwoZmlsZU9iamVjdCk7CiAgICB9CgogICAgcHVibGljIFVSSSB0b1VyaSgpIHsKICAgICAgICByZXR1cm4gZmlsZU9iamVjdC50b1VyaSgpOwogICAgfQoKICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZSgpIHsKICAgICAgICByZXR1cm4gZmlsZU9iamVjdC5nZXROYW1lKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CiAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIHtAaW5oZXJpdERvY30KICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24ge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgSW5wdXRTdHJlYW0gb3BlbklucHV0U3RyZWFtKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gZmlsZU9iamVjdC5vcGVuSW5wdXRTdHJlYW0oKTsKICAgIH0KCiAgICAvKioKICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIHtAaW5oZXJpdERvY30KICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24ge0Bpbmhlcml0RG9jfQogICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBPdXRwdXRTdHJlYW0gb3Blbk91dHB1dFN0cmVhbSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGZpbGVPYmplY3Qub3Blbk91dHB1dFN0cmVhbSgpOwogICAgfQoKICAgIC8qKgogICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24ge0Bpbmhlcml0RG9jfQogICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CiAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIFJlYWRlciBvcGVuUmVhZGVyKGJvb2xlYW4gaWdub3JlRW5jb2RpbmdFcnJvcnMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGZpbGVPYmplY3Qub3BlblJlYWRlcihpZ25vcmVFbmNvZGluZ0Vycm9ycyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CiAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIHtAaW5oZXJpdERvY30KICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24ge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgQ2hhclNlcXVlbmNlIGdldENoYXJDb250ZW50KGJvb2xlYW4gaWdub3JlRW5jb2RpbmdFcnJvcnMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGZpbGVPYmplY3QuZ2V0Q2hhckNvbnRlbnQoaWdub3JlRW5jb2RpbmdFcnJvcnMpOwogICAgfQoKICAgIC8qKgogICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24ge0Bpbmhlcml0RG9jfQogICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CiAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIFdyaXRlciBvcGVuV3JpdGVyKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gZmlsZU9iamVjdC5vcGVuV3JpdGVyKCk7CiAgICB9CgogICAgcHVibGljIGxvbmcgZ2V0TGFzdE1vZGlmaWVkKCkgewogICAgICAgIHJldHVybiBmaWxlT2JqZWN0LmdldExhc3RNb2RpZmllZCgpOwogICAgfQoKICAgIHB1YmxpYyBib29sZWFuIGRlbGV0ZSgpIHsKICAgICAgICByZXR1cm4gZmlsZU9iamVjdC5kZWxldGUoKTsKICAgIH0KfQpQSwMECgAACAAA0n1NSv16sAMiCQAAIgkAACkAAABqYXZheC90b29scy9Gb3J3YXJkaW5nSmF2YUZpbGVPYmplY3QuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAwNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBqYXZheC50b29sczsKCmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuTW9kaWZpZXI7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuTmVzdGluZ0tpbmQ7CgovKioKICogRm9yd2FyZHMgY2FsbHMgdG8gYSBnaXZlbiBmaWxlIG9iamVjdC4gIFN1YmNsYXNzZXMgb2YgdGhpcyBjbGFzcwogKiBtaWdodCBvdmVycmlkZSBzb21lIG9mIHRoZXNlIG1ldGhvZHMgYW5kIG1pZ2h0IGFsc28gcHJvdmlkZQogKiBhZGRpdGlvbmFsIGZpZWxkcyBhbmQgbWV0aG9kcy4KICoKICogQHBhcmFtIDxGPiB0aGUga2luZCBvZiBmaWxlIG9iamVjdCBmb3J3YXJkZWQgdG8gYnkgdGhpcyBvYmplY3QKICogQGF1dGhvciBQZXRlciB2b24gZGVyIEFoJmVhY3V0ZTsKICogQHNpbmNlIDEuNgogKi8KcHVibGljIGNsYXNzIEZvcndhcmRpbmdKYXZhRmlsZU9iamVjdDxGIGV4dGVuZHMgSmF2YUZpbGVPYmplY3Q+CiAgICBleHRlbmRzIEZvcndhcmRpbmdGaWxlT2JqZWN0PEY+CiAgICBpbXBsZW1lbnRzIEphdmFGaWxlT2JqZWN0CnsKCiAgICAvKioKICAgICAqIENyZWF0ZXMgYSBuZXcgaW5zdGFuY2Ugb2YgRm9yd2FyZGluZ0phdmFGaWxlT2JqZWN0LgogICAgICogQHBhcmFtIGZpbGVPYmplY3QgZGVsZWdhdGUgdG8gdGhpcyBmaWxlIG9iamVjdAogICAgICovCiAgICBwcm90ZWN0ZWQgRm9yd2FyZGluZ0phdmFGaWxlT2JqZWN0KEYgZmlsZU9iamVjdCkgewogICAgICAgIHN1cGVyKGZpbGVPYmplY3QpOwogICAgfQoKICAgIHB1YmxpYyBLaW5kIGdldEtpbmQoKSB7CiAgICAgICAgcmV0dXJuIGZpbGVPYmplY3QuZ2V0S2luZCgpOwogICAgfQoKICAgIHB1YmxpYyBib29sZWFuIGlzTmFtZUNvbXBhdGlibGUoU3RyaW5nIHNpbXBsZU5hbWUsIEtpbmQga2luZCkgewogICAgICAgIHJldHVybiBmaWxlT2JqZWN0LmlzTmFtZUNvbXBhdGlibGUoc2ltcGxlTmFtZSwga2luZCk7CiAgICB9CgogICAgcHVibGljIE5lc3RpbmdLaW5kIGdldE5lc3RpbmdLaW5kKCkgeyByZXR1cm4gZmlsZU9iamVjdC5nZXROZXN0aW5nS2luZCgpOyB9CgogICAgcHVibGljIE1vZGlmaWVyIGdldEFjY2Vzc0xldmVsKCkgIHsgcmV0dXJuIGZpbGVPYmplY3QuZ2V0QWNjZXNzTGV2ZWwoKTsgfQoKfQpQSwMECgAACAAA0n1NSshvPWbXFwAA1xcAABsAAABqYXZheC90b29scy9EaWFnbm9zdGljLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMTQsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgamF2YXgudG9vbHM7CgppbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKCi8qKgogKiBJbnRlcmZhY2UgZm9yIGRpYWdub3N0aWNzIGZyb20gdG9vbHMuICBBIGRpYWdub3N0aWMgdXN1YWxseSByZXBvcnRzCiAqIGEgcHJvYmxlbSBhdCBhIHNwZWNpZmljIHBvc2l0aW9uIGluIGEgc291cmNlIGZpbGUuICBIb3dldmVyLCBub3QKICogYWxsIGRpYWdub3N0aWNzIGFyZSBhc3NvY2lhdGVkIHdpdGggYSBwb3NpdGlvbiBvciBhIGZpbGUuCiAqCiAqIDxwPkEgcG9zaXRpb24gaXMgYSB6ZXJvLWJhc2VkIGNoYXJhY3RlciBvZmZzZXQgZnJvbSB0aGUgYmVnaW5uaW5nIG9mCiAqIGEgZmlsZS4gIE5lZ2F0aXZlIHZhbHVlcyAoZXhjZXB0IHtAbGluayAjTk9QT1N9KSBhcmUgbm90IHZhbGlkCiAqIHBvc2l0aW9ucy4KICoKICogPHA+TGluZSBhbmQgY29sdW1uIG51bWJlcnMgYmVnaW4gYXQgMS4gIE5lZ2F0aXZlIHZhbHVlcyAoZXhjZXB0CiAqIHtAbGluayAjTk9QT1N9KSBhbmQgMCBhcmUgbm90IHZhbGlkIGxpbmUgb3IgY29sdW1uIG51bWJlcnMuCiAqCiAqIEBwYXJhbSA8Uz4gdGhlIHR5cGUgb2Ygc291cmNlIG9iamVjdCB1c2VkIGJ5IHRoaXMgZGlhZ25vc3RpYwogKgogKiBAYXV0aG9yIFBldGVyIHZvbiBkZXIgQWgmZWFjdXRlOwogKiBAYXV0aG9yIEpvbmF0aGFuIEdpYmJvbnMKICogQHNpbmNlIDEuNgogKi8KcHVibGljIGludGVyZmFjZSBEaWFnbm9zdGljPFM+IHsKCiAgICAvKioKICAgICAqIEtpbmRzIG9mIGRpYWdub3N0aWNzLCBmb3IgZXhhbXBsZSwgZXJyb3Igb3Igd2FybmluZy4KICAgICAqCiAgICAgKiBUaGUga2luZCBvZiBhIGRpYWdub3N0aWMgY2FuIGJlIHVzZWQgdG8gZGV0ZXJtaW5lIGhvdyB0aGUKICAgICAqIGRpYWdub3N0aWMgc2hvdWxkIGJlIHByZXNlbnRlZCB0byB0aGUgdXNlci4gRm9yIGV4YW1wbGUsCiAgICAgKiBlcnJvcnMgbWlnaHQgYmUgY29sb3JlZCByZWQgb3IgcHJlZml4ZWQgd2l0aCB0aGUgd29yZCAiRXJyb3IiLAogICAgICogd2hpbGUgd2FybmluZ3MgbWlnaHQgYmUgY29sb3JlZCB5ZWxsb3cgb3IgcHJlZml4ZWQgd2l0aCB0aGUKICAgICAqIHdvcmQgIldhcm5pbmciLiBUaGVyZSBpcyBubyByZXF1aXJlbWVudCB0aGF0IHRoZSBLaW5kCiAgICAgKiBzaG91bGQgaW1wbHkgYW55IGluaGVyZW50IHNlbWFudGljIG1lYW5pbmcgdG8gdGhlIG1lc3NhZ2UKICAgICAqIG9mIHRoZSBkaWFnbm9zdGljOiBmb3IgZXhhbXBsZSwgYSB0b29sIG1pZ2h0IHByb3ZpZGUgYW4KICAgICAqIG9wdGlvbiB0byByZXBvcnQgYWxsIHdhcm5pbmdzIGFzIGVycm9ycy4KICAgICAqLwogICAgZW51bSBLaW5kIHsKICAgICAgICAvKioKICAgICAgICAgKiBQcm9ibGVtIHdoaWNoIHByZXZlbnRzIHRoZSB0b29sJ3Mgbm9ybWFsIGNvbXBsZXRpb24uCiAgICAgICAgICovCiAgICAgICAgRVJST1IsCiAgICAgICAgLyoqCiAgICAgICAgICogUHJvYmxlbSB3aGljaCBkb2VzIG5vdCB1c3VhbGx5IHByZXZlbnQgdGhlIHRvb2wgZnJvbQogICAgICAgICAqIGNvbXBsZXRpbmcgbm9ybWFsbHkuCiAgICAgICAgICovCiAgICAgICAgV0FSTklORywKICAgICAgICAvKioKICAgICAgICAgKiBQcm9ibGVtIHNpbWlsYXIgdG8gYSB3YXJuaW5nLCBidXQgaXMgbWFuZGF0ZWQgYnkgdGhlIHRvb2wncwogICAgICAgICAqIHNwZWNpZmljYXRpb24uICBGb3IgZXhhbXBsZSwgdGhlIEphdmEmdHJhZGU7IExhbmd1YWdlCiAgICAgICAgICogU3BlY2lmaWNhdGlvbiBtYW5kYXRlcyB3YXJuaW5ncyBvbiBjZXJ0YWluCiAgICAgICAgICogdW5jaGVja2VkIG9wZXJhdGlvbnMgYW5kIHRoZSB1c2Ugb2YgZGVwcmVjYXRlZCBtZXRob2RzLgogICAgICAgICAqLwogICAgICAgIE1BTkRBVE9SWV9XQVJOSU5HLAogICAgICAgIC8qKgogICAgICAgICAqIEluZm9ybWF0aXZlIG1lc3NhZ2UgZnJvbSB0aGUgdG9vbC4KICAgICAgICAgKi8KICAgICAgICBOT1RFLAogICAgICAgIC8qKgogICAgICAgICAqIERpYWdub3N0aWMgd2hpY2ggZG9lcyBub3QgZml0IHdpdGhpbiB0aGUgb3RoZXIga2luZHMuCiAgICAgICAgICovCiAgICAgICAgT1RIRVIsCiAgICB9CgogICAgLyoqCiAgICAgKiBVc2VkIHRvIHNpZ25hbCB0aGF0IG5vIHBvc2l0aW9uIGlzIGF2YWlsYWJsZS4KICAgICAqLwogICAgcHVibGljIGZpbmFsIHN0YXRpYyBsb25nIE5PUE9TID0gLTE7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBraW5kIG9mIHRoaXMgZGlhZ25vc3RpYywgZm9yIGV4YW1wbGUsIGVycm9yIG9yCiAgICAgKiB3YXJuaW5nLgogICAgICogQHJldHVybiB0aGUga2luZCBvZiB0aGlzIGRpYWdub3N0aWMKICAgICAqLwogICAgS2luZCBnZXRLaW5kKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBzb3VyY2Ugb2JqZWN0IGFzc29jaWF0ZWQgd2l0aCB0aGlzIGRpYWdub3N0aWMuCiAgICAgKgogICAgICogQHJldHVybiB0aGUgc291cmNlIG9iamVjdCBhc3NvY2lhdGVkIHdpdGggdGhpcyBkaWFnbm9zdGljLgogICAgICoge0Bjb2RlIG51bGx9IGlmIG5vIHNvdXJjZSBvYmplY3QgaXMgYXNzb2NpYXRlZCB3aXRoIHRoZQogICAgICogZGlhZ25vc3RpYy4KICAgICAqLwogICAgUyBnZXRTb3VyY2UoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgYSBjaGFyYWN0ZXIgb2Zmc2V0IGZyb20gdGhlIGJlZ2lubmluZyBvZiB0aGUgc291cmNlIG9iamVjdAogICAgICogYXNzb2NpYXRlZCB3aXRoIHRoaXMgZGlhZ25vc3RpYyB0aGF0IGluZGljYXRlcyB0aGUgbG9jYXRpb24gb2YKICAgICAqIHRoZSBwcm9ibGVtLiAgSW4gYWRkaXRpb24sIHRoZSBmb2xsb3dpbmcgbXVzdCBiZSB0cnVlOgogICAgICoKICAgICAqIDxwPntAY29kZSBnZXRTdGFydFBvc3Rpb24oKSA8PSBnZXRQb3NpdGlvbigpfQogICAgICogPHA+e0Bjb2RlIGdldFBvc2l0aW9uKCkgPD0gZ2V0RW5kUG9zaXRpb24oKX0KICAgICAqCiAgICAgKiBAcmV0dXJuIGNoYXJhY3RlciBvZmZzZXQgZnJvbSBiZWdpbm5pbmcgb2Ygc291cmNlOyB7QGxpbmsKICAgICAqICNOT1BPU30gaWYge0BsaW5rICNnZXRTb3VyY2UoKX0gd291bGQgcmV0dXJuIHtAY29kZSBudWxsfSBvciBpZgogICAgICogbm8gbG9jYXRpb24gaXMgc3VpdGFibGUKICAgICAqLwogICAgbG9uZyBnZXRQb3NpdGlvbigpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgY2hhcmFjdGVyIG9mZnNldCBmcm9tIHRoZSBiZWdpbm5pbmcgb2YgdGhlIGZpbGUKICAgICAqIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGRpYWdub3N0aWMgdGhhdCBpbmRpY2F0ZXMgdGhlIHN0YXJ0IG9mIHRoZQogICAgICogcHJvYmxlbS4KICAgICAqCiAgICAgKiBAcmV0dXJuIG9mZnNldCBmcm9tIGJlZ2lubmluZyBvZiBmaWxlOyB7QGxpbmsgI05PUE9TfSBpZiBhbmQKICAgICAqIG9ubHkgaWYge0BsaW5rICNnZXRQb3NpdGlvbigpfSByZXR1cm5zIHtAbGluayAjTk9QT1N9CiAgICAgKi8KICAgIGxvbmcgZ2V0U3RhcnRQb3NpdGlvbigpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgY2hhcmFjdGVyIG9mZnNldCBmcm9tIHRoZSBiZWdpbm5pbmcgb2YgdGhlIGZpbGUKICAgICAqIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGRpYWdub3N0aWMgdGhhdCBpbmRpY2F0ZXMgdGhlIGVuZCBvZiB0aGUKICAgICAqIHByb2JsZW0uCiAgICAgKgogICAgICogQHJldHVybiBvZmZzZXQgZnJvbSBiZWdpbm5pbmcgb2YgZmlsZTsge0BsaW5rICNOT1BPU30gaWYgYW5kCiAgICAgKiBvbmx5IGlmIHtAbGluayAjZ2V0UG9zaXRpb24oKX0gcmV0dXJucyB7QGxpbmsgI05PUE9TfQogICAgICovCiAgICBsb25nIGdldEVuZFBvc2l0aW9uKCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBsaW5lIG51bWJlciBvZiB0aGUgY2hhcmFjdGVyIG9mZnNldCByZXR1cm5lZCBieQogICAgICoge0BsaW5rcGxhaW4gI2dldFBvc2l0aW9uKCl9LgogICAgICoKICAgICAqIEByZXR1cm4gYSBsaW5lIG51bWJlciBvciB7QGxpbmsgI05PUE9TfSBpZiBhbmQgb25seSBpZiB7QGxpbmsKICAgICAqICNnZXRQb3NpdGlvbigpfSByZXR1cm5zIHtAbGluayAjTk9QT1N9CiAgICAgKi8KICAgIGxvbmcgZ2V0TGluZU51bWJlcigpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgY29sdW1uIG51bWJlciBvZiB0aGUgY2hhcmFjdGVyIG9mZnNldCByZXR1cm5lZCBieQogICAgICoge0BsaW5rcGxhaW4gI2dldFBvc2l0aW9uKCl9LgogICAgICoKICAgICAqIEByZXR1cm4gYSBjb2x1bW4gbnVtYmVyIG9yIHtAbGluayAjTk9QT1N9IGlmIGFuZCBvbmx5IGlmIHtAbGluawogICAgICogI2dldFBvc2l0aW9uKCl9IHJldHVybnMge0BsaW5rICNOT1BPU30KICAgICAqLwogICAgbG9uZyBnZXRDb2x1bW5OdW1iZXIoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgYSBkaWFnbm9zdGljIGNvZGUgaW5kaWNhdGluZyB0aGUgdHlwZSBvZiBkaWFnbm9zdGljLiAgVGhlCiAgICAgKiBjb2RlIGlzIGltcGxlbWVudGF0aW9uLWRlcGVuZGVudCBhbmQgbWlnaHQgYmUge0Bjb2RlIG51bGx9LgogICAgICoKICAgICAqIEByZXR1cm4gYSBkaWFnbm9zdGljIGNvZGUKICAgICAqLwogICAgU3RyaW5nIGdldENvZGUoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgYSBsb2NhbGl6ZWQgbWVzc2FnZSBmb3IgdGhlIGdpdmVuIGxvY2FsZS4gIFRoZSBhY3R1YWwKICAgICAqIG1lc3NhZ2UgaXMgaW1wbGVtZW50YXRpb24tZGVwZW5kZW50LiAgSWYgdGhlIGxvY2FsZSBpcyB7QGNvZGUKICAgICAqIG51bGx9IHVzZSB0aGUgZGVmYXVsdCBsb2NhbGUuCiAgICAgKgogICAgICogQHBhcmFtIGxvY2FsZSBhIGxvY2FsZTsgbWlnaHQgYmUge0Bjb2RlIG51bGx9CiAgICAgKiBAcmV0dXJuIGEgbG9jYWxpemVkIG1lc3NhZ2UKICAgICAqLwogICAgU3RyaW5nIGdldE1lc3NhZ2UoTG9jYWxlIGxvY2FsZSk7Cn0KUEsDBAoAAAgAAAY7qUr9upxgbQwAAG0MAAAVAAAAamF2YXgvdG9vbHMvVG9vbC5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDA1LCAyMDE0LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGphdmF4LnRvb2xzOwoKaW1wb3J0IGphdmEudXRpbC5TZXQ7CmltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOwppbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLlNvdXJjZVZlcnNpb247CgovKioKICogQ29tbW9uIGludGVyZmFjZSBmb3IgdG9vbHMgdGhhdCBjYW4gYmUgaW52b2tlZCBmcm9tIGEgcHJvZ3JhbS4KICogQSB0b29sIGlzIHRyYWRpdGlvbmFsbHkgYSBjb21tYW5kIGxpbmUgcHJvZ3JhbSBzdWNoIGFzIGEgY29tcGlsZXIuCiAqIFRoZSBzZXQgb2YgdG9vbHMgYXZhaWxhYmxlIHdpdGggYSBwbGF0Zm9ybSBpcyBkZWZpbmVkIGJ5IHRoZQogKiB2ZW5kb3IuCiAqCiAqIDxwPlRvb2xzIGNhbiBiZSBsb2NhdGVkIHVzaW5nIHtAbGluawogKiBqYXZhLnV0aWwuU2VydmljZUxvYWRlciNsb2FkKENsYXNzKX0uCiAqCiAqIEBhdXRob3IgTmVhbCBNIEdhZnRlcgogKiBAYXV0aG9yIFBldGVyIHZvbiBkZXIgQWgmZWFjdXRlOwogKiBAYXV0aG9yIEpvbmF0aGFuIEdpYmJvbnMKICogQHNpbmNlIDEuNgogKi8KcHVibGljIGludGVyZmFjZSBUb29sIHsKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgbmFtZSBvZiB0aGlzIHRvb2wsIG9yIGFuIGVtcHR5IHN0cmluZyBpZiBubyBuYW1lIGlzIHByb3ZpZGVkLgogICAgICoKICAgICAqIEBhcGlOb3RlIEl0IGlzIHJlY29tbWVuZGVkIHRoYXQgdGhlIG5hbWUgYmUgdGhlIHNhbWUgYXMgd291bGQgYmUKICAgICAqIHVzZWQgb24gdGhlIGNvbW1hbmQgbGluZTogZm9yIGV4YW1wbGUsICJqYXZhYyIsICJqYXIiLCAiamxpbmsiLgogICAgICogQGltcGxOb3RlIFRoaXMgaW1wbGVtZW50YXRpb24gcmV0dXJucyBhbiBlbXB0eSBzdHJpbmcuCiAgICAgKgogICAgICogQHJldHVybiB0aGUgbmFtZSBvZiB0aGlzIHRvb2wKICAgICAqIEBzaW5jZSA5CiAgICAgKi8KICAgIGRlZmF1bHQgU3RyaW5nIG5hbWUoKSB7CiAgICAgICAgcmV0dXJuICIiOwogICAgfQoKICAgIC8qKgogICAgICogUnVuIHRoZSB0b29sIHdpdGggdGhlIGdpdmVuIEkvTyBjaGFubmVscyBhbmQgYXJndW1lbnRzLiBCeQogICAgICogY29udmVudGlvbiBhIHRvb2wgcmV0dXJucyAwIGZvciBzdWNjZXNzIGFuZCBub256ZXJvIGZvciBlcnJvcnMuCiAgICAgKiBBbnkgZGlhZ25vc3RpY3MgZ2VuZXJhdGVkIHdpbGwgYmUgd3JpdHRlbiB0byBlaXRoZXIge0Bjb2RlIG91dH0KICAgICAqIG9yIHtAY29kZSBlcnJ9IGluIHNvbWUgdW5zcGVjaWZpZWQgZm9ybWF0LgogICAgICoKICAgICAqIEBwYXJhbSBpbiAic3RhbmRhcmQiIGlucHV0OyB1c2UgU3lzdGVtLmluIGlmIG51bGwKICAgICAqIEBwYXJhbSBvdXQgInN0YW5kYXJkIiBvdXRwdXQ7IHVzZSBTeXN0ZW0ub3V0IGlmIG51bGwKICAgICAqIEBwYXJhbSBlcnIgInN0YW5kYXJkIiBlcnJvcjsgdXNlIFN5c3RlbS5lcnIgaWYgbnVsbAogICAgICogQHBhcmFtIGFyZ3VtZW50cyBhcmd1bWVudHMgdG8gcGFzcyB0byB0aGUgdG9vbAogICAgICogQHJldHVybiAwIGZvciBzdWNjZXNzOyBub256ZXJvIG90aGVyd2lzZQogICAgICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiB0aGUgYXJyYXkgb2YgYXJndW1lbnRzIGNvbnRhaW5zCiAgICAgKiBhbnkge0Bjb2RlIG51bGx9IGVsZW1lbnRzLgogICAgICovCiAgICBpbnQgcnVuKElucHV0U3RyZWFtIGluLCBPdXRwdXRTdHJlYW0gb3V0LCBPdXRwdXRTdHJlYW0gZXJyLCBTdHJpbmcuLi4gYXJndW1lbnRzKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHNvdXJjZSB2ZXJzaW9ucyBvZiB0aGUgSmF2YSZ0cmFkZTsgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2UKICAgICAqIHN1cHBvcnRlZCBieSB0aGlzIHRvb2wuCiAgICAgKiBAcmV0dXJuIGEgc2V0IG9mIHN1cHBvcnRlZCBzb3VyY2UgdmVyc2lvbnMKICAgICAqLwogICAgU2V0PFNvdXJjZVZlcnNpb24+IGdldFNvdXJjZVZlcnNpb25zKCk7Cgp9ClBLAwQKAAAIAAAGO6lKAgY9sYQIAACECAAAJAAAAGphdmF4L3Rvb2xzL0RpYWdub3N0aWNDb2xsZWN0b3IuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNiwgMjAxNCwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBqYXZheC50b29sczsKCmltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OwppbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOwppbXBvcnQgamF2YS51dGlsLkxpc3Q7CmltcG9ydCBqYXZhLnV0aWwuT2JqZWN0czsKCi8qKgogKiBQcm92aWRlcyBhbiBlYXN5IHdheSB0byBjb2xsZWN0IGRpYWdub3N0aWNzIGluIGEgbGlzdC4KICoKICogQHBhcmFtIDxTPiB0aGUgdHlwZSBvZiBzb3VyY2Ugb2JqZWN0cyB1c2VkIGJ5IGRpYWdub3N0aWNzIHJlY2VpdmVkCiAqIGJ5IHRoaXMgb2JqZWN0CiAqCiAqIEBhdXRob3IgUGV0ZXIgdm9uIGRlciBBaCZlYWN1dGU7CiAqIEBzaW5jZSAxLjYKICovCnB1YmxpYyBmaW5hbCBjbGFzcyBEaWFnbm9zdGljQ29sbGVjdG9yPFM+IGltcGxlbWVudHMgRGlhZ25vc3RpY0xpc3RlbmVyPFM+IHsKICAgIHByaXZhdGUgTGlzdDxEaWFnbm9zdGljPD8gZXh0ZW5kcyBTPj4gZGlhZ25vc3RpY3MgPQogICAgICAgICAgICBDb2xsZWN0aW9ucy5zeW5jaHJvbml6ZWRMaXN0KG5ldyBBcnJheUxpc3Q8RGlhZ25vc3RpYzw/IGV4dGVuZHMgUz4+KCkpOwoKICAgIHB1YmxpYyB2b2lkIHJlcG9ydChEaWFnbm9zdGljPD8gZXh0ZW5kcyBTPiBkaWFnbm9zdGljKSB7CiAgICAgICAgT2JqZWN0cy5yZXF1aXJlTm9uTnVsbChkaWFnbm9zdGljKTsKICAgICAgICBkaWFnbm9zdGljcy5hZGQoZGlhZ25vc3RpYyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgbGlzdCB2aWV3IG9mIGRpYWdub3N0aWNzIGNvbGxlY3RlZCBieSB0aGlzIG9iamVjdC4KICAgICAqCiAgICAgKiBAcmV0dXJuIGEgbGlzdCB2aWV3IG9mIGRpYWdub3N0aWNzCiAgICAgKi8KICAgIHB1YmxpYyBMaXN0PERpYWdub3N0aWM8PyBleHRlbmRzIFM+PiBnZXREaWFnbm9zdGljcygpIHsKICAgICAgICByZXR1cm4gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChkaWFnbm9zdGljcyk7CiAgICB9Cn0KUEsDBAoAAAgAAAY7qUp1RQvySjwAAEo8AAAdAAAAamF2YXgvdG9vbHMvSmF2YUNvbXBpbGVyLmphdmEvKgogKiBDb3B5cmlnaHQgKGMpIDIwMDUsIDIwMTcsIE9yYWNsZSBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIERPIE5PVCBBTFRFUiBPUiBSRU1PVkUgQ09QWVJJR0hUIE5PVElDRVMgT1IgVEhJUyBGSUxFIEhFQURFUi4KICoKICogVGhpcyBjb2RlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgb25seSwgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBPcmFjbGUgZGVzaWduYXRlcyB0aGlzCiAqIHBhcnRpY3VsYXIgZmlsZSBhcyBzdWJqZWN0IHRvIHRoZSAiQ2xhc3NwYXRoIiBleGNlcHRpb24gYXMgcHJvdmlkZWQKICogYnkgT3JhY2xlIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdCBhY2NvbXBhbmllZCB0aGlzIGNvZGUuCiAqCiAqIFRoaXMgY29kZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAogKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIHZlcnNpb24gMiBmb3IgbW9yZSBkZXRhaWxzIChhIGNvcHkgaXMgaW5jbHVkZWQgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0CiAqIGFjY29tcGFuaWVkIHRoaXMgY29kZSkuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24KICogMiBhbG9uZyB3aXRoIHRoaXMgd29yazsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLAogKiBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EuCiAqCiAqIFBsZWFzZSBjb250YWN0IE9yYWNsZSwgNTAwIE9yYWNsZSBQYXJrd2F5LCBSZWR3b29kIFNob3JlcywgQ0EgOTQwNjUgVVNBCiAqIG9yIHZpc2l0IHd3dy5vcmFjbGUuY29tIGlmIHlvdSBuZWVkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb3IgaGF2ZSBhbnkKICogcXVlc3Rpb25zLgogKi8KCnBhY2thZ2UgamF2YXgudG9vbHM7CgppbXBvcnQgamF2YS5pby5Xcml0ZXI7CmltcG9ydCBqYXZhLm5pby5jaGFyc2V0LkNoYXJzZXQ7CmltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOwppbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuQ2FsbGFibGU7CmltcG9ydCBqYXZheC5hbm5vdGF0aW9uLnByb2Nlc3NpbmcuUHJvY2Vzc29yOwoKLyoqCiAqIEludGVyZmFjZSB0byBpbnZva2UgSmF2YSZ0cmFkZTsgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2UgY29tcGlsZXJzIGZyb20KICogcHJvZ3JhbXMuCiAqCiAqIDxwPlRoZSBjb21waWxlciBtaWdodCBnZW5lcmF0ZSBkaWFnbm9zdGljcyBkdXJpbmcgY29tcGlsYXRpb24gKGZvcgogKiBleGFtcGxlLCBlcnJvciBtZXNzYWdlcykuICBJZiBhIGRpYWdub3N0aWMgbGlzdGVuZXIgaXMgcHJvdmlkZWQsCiAqIHRoZSBkaWFnbm9zdGljcyB3aWxsIGJlIHN1cHBsaWVkIHRvIHRoZSBsaXN0ZW5lci4gIElmIG5vIGxpc3RlbmVyCiAqIGlzIHByb3ZpZGVkLCB0aGUgZGlhZ25vc3RpY3Mgd2lsbCBiZSBmb3JtYXR0ZWQgaW4gYW4gdW5zcGVjaWZpZWQKICogZm9ybWF0IGFuZCB3cml0dGVuIHRvIHRoZSBkZWZhdWx0IG91dHB1dCwgd2hpY2ggaXMge0Bjb2RlCiAqIFN5c3RlbS5lcnJ9IHVubGVzcyBvdGhlcndpc2Ugc3BlY2lmaWVkLiAgRXZlbiBpZiBhIGRpYWdub3N0aWMKICogbGlzdGVuZXIgaXMgc3VwcGxpZWQsIHNvbWUgZGlhZ25vc3RpY3MgbWlnaHQgbm90IGZpdCBpbiBhIHtAY29kZQogKiBEaWFnbm9zdGljfSBhbmQgd2lsbCBiZSB3cml0dGVuIHRvIHRoZSBkZWZhdWx0IG91dHB1dC4KICoKICogPHA+QSBjb21waWxlciB0b29sIGhhcyBhbiBhc3NvY2lhdGVkIHN0YW5kYXJkIGZpbGUgbWFuYWdlciwgd2hpY2gKICogaXMgdGhlIGZpbGUgbWFuYWdlciB0aGF0IGlzIG5hdGl2ZSB0byB0aGUgdG9vbCAob3IgYnVpbHQtaW4pLiAgVGhlCiAqIHN0YW5kYXJkIGZpbGUgbWFuYWdlciBjYW4gYmUgb2J0YWluZWQgYnkgY2FsbGluZyB7QGxpbmtwbGFpbgogKiAjZ2V0U3RhbmRhcmRGaWxlTWFuYWdlciBnZXRTdGFuZGFyZEZpbGVNYW5hZ2VyfS4KICoKICogPHA+QSBjb21waWxlciB0b29sIG11c3QgZnVuY3Rpb24gd2l0aCBhbnkgZmlsZSBtYW5hZ2VyIGFzIGxvbmcgYXMKICogYW55IGFkZGl0aW9uYWwgcmVxdWlyZW1lbnRzIGFzIGRldGFpbGVkIGluIHRoZSBtZXRob2RzIGJlbG93IGFyZQogKiBtZXQuICBJZiBubyBmaWxlIG1hbmFnZXIgaXMgcHJvdmlkZWQsIHRoZSBjb21waWxlciB0b29sIHdpbGwgdXNlIGEKICogc3RhbmRhcmQgZmlsZSBtYW5hZ2VyIHN1Y2ggYXMgdGhlIG9uZSByZXR1cm5lZCBieSB7QGxpbmtwbGFpbgogKiAjZ2V0U3RhbmRhcmRGaWxlTWFuYWdlciBnZXRTdGFuZGFyZEZpbGVNYW5hZ2VyfS4KICoKICogPHA+QW4gaW5zdGFuY2UgaW1wbGVtZW50aW5nIHRoaXMgaW50ZXJmYWNlIG11c3QgY29uZm9ybSB0bwogKiA8Y2l0ZT5UaGUgSmF2YSZ0cmFkZTsgTGFuZ3VhZ2UgU3BlY2lmaWNhdGlvbjwvY2l0ZT4KICogYW5kIGdlbmVyYXRlIGNsYXNzIGZpbGVzIGNvbmZvcm1pbmcgdG8KICogPGNpdGU+VGhlIEphdmEmdHJhZGU7IFZpcnR1YWwgTWFjaGluZSBTcGVjaWZpY2F0aW9uPC9jaXRlPi4KICogVGhlIHZlcnNpb25zIG9mIHRoZXNlCiAqIHNwZWNpZmljYXRpb25zIGFyZSBkZWZpbmVkIGluIHRoZSB7QGxpbmtwbGFpbiBUb29sfSBpbnRlcmZhY2UuCiAqCiAqIEFkZGl0aW9uYWxseSwgYW4gaW5zdGFuY2Ugb2YgdGhpcyBpbnRlcmZhY2Ugc3VwcG9ydGluZyB7QGxpbmsKICogamF2YXgubGFuZy5tb2RlbC5Tb3VyY2VWZXJzaW9uI1JFTEVBU0VfNiBTb3VyY2VWZXJzaW9uLlJFTEVBU0VfNn0KICogb3IgaGlnaGVyIG11c3QgYWxzbyBzdXBwb3J0IHtAbGlua3BsYWluIGphdmF4LmFubm90YXRpb24ucHJvY2Vzc2luZwogKiBhbm5vdGF0aW9uIHByb2Nlc3Npbmd9LgogKgogKiA8cD5UaGUgY29tcGlsZXIgcmVsaWVzIG9uIHR3byBzZXJ2aWNlczoge0BsaW5rcGxhaW4KICogRGlhZ25vc3RpY0xpc3RlbmVyIGRpYWdub3N0aWMgbGlzdGVuZXJ9IGFuZCB7QGxpbmtwbGFpbgogKiBKYXZhRmlsZU1hbmFnZXIgZmlsZSBtYW5hZ2VyfS4gIEFsdGhvdWdoIG1vc3QgY2xhc3NlcyBhbmQKICogaW50ZXJmYWNlcyBpbiB0aGlzIHBhY2thZ2UgZGVmaW5lcyBhbiBBUEkgZm9yIGNvbXBpbGVycyAoYW5kCiAqIHRvb2xzIGluIGdlbmVyYWwpIHRoZSBpbnRlcmZhY2VzIHtAbGlua3BsYWluIERpYWdub3N0aWNMaXN0ZW5lcn0sCiAqIHtAbGlua3BsYWluIEphdmFGaWxlTWFuYWdlcn0sIHtAbGlua3BsYWluIEZpbGVPYmplY3R9LCBhbmQKICoge0BsaW5rcGxhaW4gSmF2YUZpbGVPYmplY3R9IGFyZSBub3QgaW50ZW5kZWQgdG8gYmUgdXNlZCBpbgogKiBhcHBsaWNhdGlvbnMuICBJbnN0ZWFkIHRoZXNlIGludGVyZmFjZXMgYXJlIGludGVuZGVkIHRvIGJlCiAqIGltcGxlbWVudGVkIGFuZCB1c2VkIHRvIHByb3ZpZGUgY3VzdG9taXplZCBzZXJ2aWNlcyBmb3IgYQogKiBjb21waWxlciBhbmQgdGh1cyBkZWZpbmVzIGFuIFNQSSBmb3IgY29tcGlsZXJzLgogKgogKiA8cD5UaGVyZSBhcmUgYSBudW1iZXIgb2YgY2xhc3NlcyBhbmQgaW50ZXJmYWNlcyBpbiB0aGlzIHBhY2thZ2UKICogd2hpY2ggYXJlIGRlc2lnbmVkIHRvIGVhc2UgdGhlIGltcGxlbWVudGF0aW9uIG9mIHRoZSBTUEkgdG8KICogY3VzdG9taXplIHRoZSBiZWhhdmlvciBvZiBhIGNvbXBpbGVyOgogKgogKiA8ZGw+CiAqICAgPGR0PntAbGluayBTdGFuZGFyZEphdmFGaWxlTWFuYWdlcn08L2R0PgogKiAgIDxkZD4KICoKICogICAgIEV2ZXJ5IGNvbXBpbGVyIHdoaWNoIGltcGxlbWVudHMgdGhpcyBpbnRlcmZhY2UgcHJvdmlkZXMgYQogKiAgICAgc3RhbmRhcmQgZmlsZSBtYW5hZ2VyIGZvciBvcGVyYXRpbmcgb24gcmVndWxhciB7QGxpbmtwbGFpbgogKiAgICAgamF2YS5pby5GaWxlIGZpbGVzfS4gIFRoZSBTdGFuZGFyZEphdmFGaWxlTWFuYWdlciBpbnRlcmZhY2UKICogICAgIGRlZmluZXMgYWRkaXRpb25hbCBtZXRob2RzIGZvciBjcmVhdGluZyBmaWxlIG9iamVjdHMgZnJvbQogKiAgICAgcmVndWxhciBmaWxlcy4KICoKICogICAgIDxwPlRoZSBzdGFuZGFyZCBmaWxlIG1hbmFnZXIgc2VydmVzIHR3byBwdXJwb3NlczoKICoKICogICAgIDx1bD4KICogICAgICAgPGxpPmJhc2ljIGJ1aWxkaW5nIGJsb2NrIGZvciBjdXN0b21pemluZyBob3cgYSBjb21waWxlciByZWFkcwogKiAgICAgICBhbmQgd3JpdGVzIGZpbGVzPC9saT4KICogICAgICAgPGxpPnNoYXJpbmcgYmV0d2VlbiBtdWx0aXBsZSBjb21waWxhdGlvbiB0YXNrczwvbGk+CiAqICAgICA8L3VsPgogKgogKiAgICAgPHA+UmV1c2luZyBhIGZpbGUgbWFuYWdlciBjYW4gcG90ZW50aWFsbHkgcmVkdWNlIG92ZXJoZWFkIG9mCiAqICAgICBzY2FubmluZyB0aGUgZmlsZSBzeXN0ZW0gYW5kIHJlYWRpbmcgamFyIGZpbGVzLiAgQWx0aG91Z2ggdGhlcmUKICogICAgIG1pZ2h0IGJlIG5vIHJlZHVjdGlvbiBpbiBvdmVyaGVhZCwgYSBzdGFuZGFyZCBmaWxlIG1hbmFnZXIgbXVzdAogKiAgICAgd29yayB3aXRoIG11bHRpcGxlIHNlcXVlbnRpYWwgY29tcGlsYXRpb25zIG1ha2luZyB0aGUgZm9sbG93aW5nCiAqICAgICBleGFtcGxlIGEgcmVjb21tZW5kZWQgY29kaW5nIHBhdHRlcm46CiAqCiAqICAgICA8cHJlPgogKiAgICAgICBGaWxlW10gZmlsZXMxID0gLi4uIDsgLy8gaW5wdXQgZm9yIGZpcnN0IGNvbXBpbGF0aW9uIHRhc2sKICogICAgICAgRmlsZVtdIGZpbGVzMiA9IC4uLiA7IC8vIGlucHV0IGZvciBzZWNvbmQgY29tcGlsYXRpb24gdGFzawogKgogKiAgICAgICBKYXZhQ29tcGlsZXIgY29tcGlsZXIgPSBUb29sUHJvdmlkZXIuZ2V0U3lzdGVtSmF2YUNvbXBpbGVyKCk7CiAqICAgICAgIFN0YW5kYXJkSmF2YUZpbGVNYW5hZ2VyIGZpbGVNYW5hZ2VyID0gY29tcGlsZXIuZ2V0U3RhbmRhcmRGaWxlTWFuYWdlcihudWxsLCBudWxsLCBudWxsKTsKICoKICogICAgICAge0Bjb2RlIEl0ZXJhYmxlPD8gZXh0ZW5kcyBKYXZhRmlsZU9iamVjdD59IGNvbXBpbGF0aW9uVW5pdHMxID0KICogICAgICAgICAgIGZpbGVNYW5hZ2VyLmdldEphdmFGaWxlT2JqZWN0c0Zyb21GaWxlcyh7QGxpbmtwbGFpbiBqYXZhLnV0aWwuQXJyYXlzI2FzTGlzdCBBcnJheXMuYXNMaXN0fShmaWxlczEpKTsKICogICAgICAgY29tcGlsZXIuZ2V0VGFzayhudWxsLCBmaWxlTWFuYWdlciwgbnVsbCwgbnVsbCwgbnVsbCwgY29tcGlsYXRpb25Vbml0czEpLmNhbGwoKTsKICoKICogICAgICAge0Bjb2RlIEl0ZXJhYmxlPD8gZXh0ZW5kcyBKYXZhRmlsZU9iamVjdD59IGNvbXBpbGF0aW9uVW5pdHMyID0KICogICAgICAgICAgIGZpbGVNYW5hZ2VyLmdldEphdmFGaWxlT2JqZWN0cyhmaWxlczIpOyAvLyB1c2UgYWx0ZXJuYXRpdmUgbWV0aG9kCiAqICAgICAgIC8vIHJldXNlIHRoZSBzYW1lIGZpbGUgbWFuYWdlciB0byBhbGxvdyBjYWNoaW5nIG9mIGphciBmaWxlcwogKiAgICAgICBjb21waWxlci5nZXRUYXNrKG51bGwsIGZpbGVNYW5hZ2VyLCBudWxsLCBudWxsLCBudWxsLCBjb21waWxhdGlvblVuaXRzMikuY2FsbCgpOwogKgogKiAgICAgICBmaWxlTWFuYWdlci5jbG9zZSgpOzwvcHJlPgogKgogKiAgIDwvZGQ+CiAqCiAqICAgPGR0PntAbGluayBEaWFnbm9zdGljQ29sbGVjdG9yfTwvZHQ+CiAqICAgPGRkPgogKiAgICAgVXNlZCB0byBjb2xsZWN0IGRpYWdub3N0aWNzIGluIGEgbGlzdCwgZm9yIGV4YW1wbGU6CiAqICAgICA8cHJlPgogKiAgICAgICB7QGNvZGUgSXRlcmFibGU8PyBleHRlbmRzIEphdmFGaWxlT2JqZWN0Pn0gY29tcGlsYXRpb25Vbml0cyA9IC4uLjsKICogICAgICAgSmF2YUNvbXBpbGVyIGNvbXBpbGVyID0gVG9vbFByb3ZpZGVyLmdldFN5c3RlbUphdmFDb21waWxlcigpOwogKiAgICAgICB7QGNvZGUgRGlhZ25vc3RpY0NvbGxlY3RvcjxKYXZhRmlsZU9iamVjdD4gZGlhZ25vc3RpY3MgPSBuZXcgRGlhZ25vc3RpY0NvbGxlY3RvcjxKYXZhRmlsZU9iamVjdD4oKTt9CiAqICAgICAgIFN0YW5kYXJkSmF2YUZpbGVNYW5hZ2VyIGZpbGVNYW5hZ2VyID0gY29tcGlsZXIuZ2V0U3RhbmRhcmRGaWxlTWFuYWdlcihkaWFnbm9zdGljcywgbnVsbCwgbnVsbCk7CiAqICAgICAgIGNvbXBpbGVyLmdldFRhc2sobnVsbCwgZmlsZU1hbmFnZXIsIGRpYWdub3N0aWNzLCBudWxsLCBudWxsLCBjb21waWxhdGlvblVuaXRzKS5jYWxsKCk7CiAqCiAqICAgICAgIGZvciAoe0Bjb2RlIERpYWdub3N0aWM8PyBleHRlbmRzIEphdmFGaWxlT2JqZWN0Pn0gZGlhZ25vc3RpYyA6IGRpYWdub3N0aWNzLmdldERpYWdub3N0aWNzKCkpCiAqICAgICAgICAgICBTeXN0ZW0ub3V0LmZvcm1hdCgiRXJyb3Igb24gbGluZSAlZCBpbiAlcyVuIiwKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpYWdub3N0aWMuZ2V0TGluZU51bWJlcigpLAogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlhZ25vc3RpYy5nZXRTb3VyY2UoKS50b1VyaSgpKTsKICoKICogICAgICAgZmlsZU1hbmFnZXIuY2xvc2UoKTs8L3ByZT4KICogICA8L2RkPgogKgogKiAgIDxkdD4KICogICAgIHtAbGluayBGb3J3YXJkaW5nSmF2YUZpbGVNYW5hZ2VyfSwge0BsaW5rIEZvcndhcmRpbmdGaWxlT2JqZWN0fSwgYW5kCiAqICAgICB7QGxpbmsgRm9yd2FyZGluZ0phdmFGaWxlT2JqZWN0fQogKiAgIDwvZHQ+CiAqICAgPGRkPgogKgogKiAgICAgU3ViY2xhc3NpbmcgaXMgbm90IGF2YWlsYWJsZSBmb3Igb3ZlcnJpZGluZyB0aGUgYmVoYXZpb3Igb2YgYQogKiAgICAgc3RhbmRhcmQgZmlsZSBtYW5hZ2VyIGFzIGl0IGlzIGNyZWF0ZWQgYnkgY2FsbGluZyBhIG1ldGhvZCBvbiBhCiAqICAgICBjb21waWxlciwgbm90IGJ5IGludm9raW5nIGEgY29uc3RydWN0b3IuICBJbnN0ZWFkIGZvcndhcmRpbmcKICogICAgIChvciBkZWxlZ2F0aW9uKSBzaG91bGQgYmUgdXNlZC4gIFRoZXNlIGNsYXNzZXMgbWFrZXMgaXQgZWFzeSB0bwogKiAgICAgZm9yd2FyZCBtb3N0IGNhbGxzIHRvIGEgZ2l2ZW4gZmlsZSBtYW5hZ2VyIG9yIGZpbGUgb2JqZWN0IHdoaWxlCiAqICAgICBhbGxvd2luZyBjdXN0b21pemluZyBiZWhhdmlvci4gIEZvciBleGFtcGxlLCBjb25zaWRlciBob3cgdG8KICogICAgIGxvZyBhbGwgY2FsbHMgdG8ge0BsaW5rcGxhaW4gSmF2YUZpbGVNYW5hZ2VyI2ZsdXNofToKICoKICogICAgIDxwcmU+CiAqICAgICAgIGZpbmFsICBMb2dnZXIgbG9nZ2VyID0gLi4uOwogKiAgICAgICB7QGNvZGUgSXRlcmFibGU8PyBleHRlbmRzIEphdmFGaWxlT2JqZWN0Pn0gY29tcGlsYXRpb25Vbml0cyA9IC4uLjsKICogICAgICAgSmF2YUNvbXBpbGVyIGNvbXBpbGVyID0gVG9vbFByb3ZpZGVyLmdldFN5c3RlbUphdmFDb21waWxlcigpOwogKiAgICAgICBTdGFuZGFyZEphdmFGaWxlTWFuYWdlciBzdGRGaWxlTWFuYWdlciA9IGNvbXBpbGVyLmdldFN0YW5kYXJkRmlsZU1hbmFnZXIobnVsbCwgbnVsbCwgbnVsbCk7CiAqICAgICAgIEphdmFGaWxlTWFuYWdlciBmaWxlTWFuYWdlciA9IG5ldyBGb3J3YXJkaW5nSmF2YUZpbGVNYW5hZ2VyKHN0ZEZpbGVNYW5hZ2VyKSB7CiAqICAgICAgICAgICBwdWJsaWMgdm9pZCBmbHVzaCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAqICAgICAgICAgICAgICAgbG9nZ2VyLmVudGVyaW5nKFN0YW5kYXJkSmF2YUZpbGVNYW5hZ2VyLmNsYXNzLmdldE5hbWUoKSwgImZsdXNoIik7CiAqICAgICAgICAgICAgICAgc3VwZXIuZmx1c2goKTsKICogICAgICAgICAgICAgICBsb2dnZXIuZXhpdGluZyhTdGFuZGFyZEphdmFGaWxlTWFuYWdlci5jbGFzcy5nZXROYW1lKCksICJmbHVzaCIpOwogKiAgICAgICAgICAgfQogKiAgICAgICB9OwogKiAgICAgICBjb21waWxlci5nZXRUYXNrKG51bGwsIGZpbGVNYW5hZ2VyLCBudWxsLCBudWxsLCBudWxsLCBjb21waWxhdGlvblVuaXRzKS5jYWxsKCk7PC9wcmU+CiAqICAgPC9kZD4KICoKICogICA8ZHQ+e0BsaW5rIFNpbXBsZUphdmFGaWxlT2JqZWN0fTwvZHQ+CiAqICAgPGRkPgogKgogKiAgICAgVGhpcyBjbGFzcyBwcm92aWRlcyBhIGJhc2ljIGZpbGUgb2JqZWN0IGltcGxlbWVudGF0aW9uIHdoaWNoCiAqICAgICBjYW4gYmUgdXNlZCBhcyBidWlsZGluZyBibG9jayBmb3IgY3JlYXRpbmcgZmlsZSBvYmplY3RzLiAgRm9yCiAqICAgICBleGFtcGxlLCBoZXJlIGlzIGhvdyB0byBkZWZpbmUgYSBmaWxlIG9iamVjdCB3aGljaCByZXByZXNlbnQKICogICAgIHNvdXJjZSBjb2RlIHN0b3JlZCBpbiBhIHN0cmluZzoKICoKICogICAgIDxwcmU+CiAqICAgICAgIC8qKgogKiAgICAgICAgKiBBIGZpbGUgb2JqZWN0IHVzZWQgdG8gcmVwcmVzZW50IHNvdXJjZSBjb21pbmcgZnJvbSBhIHN0cmluZy4KICogICAgICAgIHtAY29kZSAqfS8KICogICAgICAgcHVibGljIGNsYXNzIEphdmFTb3VyY2VGcm9tU3RyaW5nIGV4dGVuZHMgU2ltcGxlSmF2YUZpbGVPYmplY3QgewogKiAgICAgICAgICAgLyoqCiAqICAgICAgICAgICAgKiBUaGUgc291cmNlIGNvZGUgb2YgdGhpcyAiZmlsZSIuCiAqICAgICAgICAgICAge0Bjb2RlICp9LwogKiAgICAgICAgICAgZmluYWwgU3RyaW5nIGNvZGU7CiAqCiAqICAgICAgICAgICAvKioKICogICAgICAgICAgICAqIENvbnN0cnVjdHMgYSBuZXcgSmF2YVNvdXJjZUZyb21TdHJpbmcuCiAqICAgICAgICAgICAgKiB7QGNvZGUgQH1wYXJhbSBuYW1lIHRoZSBuYW1lIG9mIHRoZSBjb21waWxhdGlvbiB1bml0IHJlcHJlc2VudGVkIGJ5IHRoaXMgZmlsZSBvYmplY3QKICogICAgICAgICAgICAqIHtAY29kZSBAfXBhcmFtIGNvZGUgdGhlIHNvdXJjZSBjb2RlIGZvciB0aGUgY29tcGlsYXRpb24gdW5pdCByZXByZXNlbnRlZCBieSB0aGlzIGZpbGUgb2JqZWN0CiAqICAgICAgICAgICAge0Bjb2RlICp9LwogKiAgICAgICAgICAgSmF2YVNvdXJjZUZyb21TdHJpbmcoU3RyaW5nIG5hbWUsIFN0cmluZyBjb2RlKSB7CiAqICAgICAgICAgICAgICAgc3VwZXIoe0BsaW5rcGxhaW4gamF2YS5uZXQuVVJJI2NyZWF0ZSBVUkkuY3JlYXRlfSgic3RyaW5nOi8vLyIgKyBuYW1lLnJlcGxhY2UoJy4nLCcvJykgKyBLaW5kLlNPVVJDRS5leHRlbnNpb24pLAogKiAgICAgICAgICAgICAgICAgICAgIEtpbmQuU09VUkNFKTsKICogICAgICAgICAgICAgICB0aGlzLmNvZGUgPSBjb2RlOwogKiAgICAgICAgICAgfQogKgogKiAgICAgICAgICAge0Bjb2RlIEB9T3ZlcnJpZGUKICogICAgICAgICAgIHB1YmxpYyBDaGFyU2VxdWVuY2UgZ2V0Q2hhckNvbnRlbnQoYm9vbGVhbiBpZ25vcmVFbmNvZGluZ0Vycm9ycykgewogKiAgICAgICAgICAgICAgIHJldHVybiBjb2RlOwogKiAgICAgICAgICAgfQogKiAgICAgICB9PC9wcmU+CiAqICAgPC9kZD4KICogPC9kbD4KICoKICogQGF1dGhvciBQZXRlciB2b24gZGVyIEFoJmVhY3V0ZTsKICogQGF1dGhvciBKb25hdGhhbiBHaWJib25zCiAqIEBzZWUgRGlhZ25vc3RpY0xpc3RlbmVyCiAqIEBzZWUgRGlhZ25vc3RpYwogKiBAc2VlIEphdmFGaWxlTWFuYWdlcgogKiBAc2luY2UgMS42CiAqLwpwdWJsaWMgaW50ZXJmYWNlIEphdmFDb21waWxlciBleHRlbmRzIFRvb2wsIE9wdGlvbkNoZWNrZXIgewoKICAgIC8qKgogICAgICogQ3JlYXRlcyBhIGZ1dHVyZSBmb3IgYSBjb21waWxhdGlvbiB0YXNrIHdpdGggdGhlIGdpdmVuCiAgICAgKiBjb21wb25lbnRzIGFuZCBhcmd1bWVudHMuICBUaGUgY29tcGlsYXRpb24gbWlnaHQgbm90IGhhdmUKICAgICAqIGNvbXBsZXRlZCBhcyBkZXNjcmliZWQgaW4gdGhlIENvbXBpbGF0aW9uVGFzayBpbnRlcmZhY2UuCiAgICAgKgogICAgICogPHA+SWYgYSBmaWxlIG1hbmFnZXIgaXMgcHJvdmlkZWQsIGl0IG11c3QgYmUgYWJsZSB0byBoYW5kbGUgYWxsCiAgICAgKiBsb2NhdGlvbnMgZGVmaW5lZCBpbiB7QGxpbmsgU3RhbmRhcmRMb2NhdGlvbn0uCiAgICAgKgogICAgICogPHA+Tm90ZSB0aGF0IGFubm90YXRpb24gcHJvY2Vzc2luZyBjYW4gcHJvY2VzcyBib3RoIHRoZQogICAgICogY29tcGlsYXRpb24gdW5pdHMgb2Ygc291cmNlIGNvZGUgdG8gYmUgY29tcGlsZWQsIHBhc3NlZCB3aXRoCiAgICAgKiB0aGUge0Bjb2RlIGNvbXBpbGF0aW9uVW5pdHN9IHBhcmFtZXRlciwgYXMgd2VsbCBhcyBjbGFzcwogICAgICogZmlsZXMsIHdob3NlIG5hbWVzIGFyZSBwYXNzZWQgd2l0aCB0aGUge0Bjb2RlIGNsYXNzZXN9CiAgICAgKiBwYXJhbWV0ZXIuCiAgICAgKgogICAgICogQHBhcmFtIG91dCBhIFdyaXRlciBmb3IgYWRkaXRpb25hbCBvdXRwdXQgZnJvbSB0aGUgY29tcGlsZXI7CiAgICAgKiB1c2Uge0Bjb2RlIFN5c3RlbS5lcnJ9IGlmIHtAY29kZSBudWxsfQogICAgICogQHBhcmFtIGZpbGVNYW5hZ2VyIGEgZmlsZSBtYW5hZ2VyOyBpZiB7QGNvZGUgbnVsbH0gdXNlIHRoZQogICAgICogY29tcGlsZXIncyBzdGFuZGFyZCBmaWxlbWFuYWdlcgogICAgICogQHBhcmFtIGRpYWdub3N0aWNMaXN0ZW5lciBhIGRpYWdub3N0aWMgbGlzdGVuZXI7IGlmIHtAY29kZQogICAgICogbnVsbH0gdXNlIHRoZSBjb21waWxlcidzIGRlZmF1bHQgbWV0aG9kIGZvciByZXBvcnRpbmcKICAgICAqIGRpYWdub3N0aWNzCiAgICAgKiBAcGFyYW0gb3B0aW9ucyBjb21waWxlciBvcHRpb25zLCB7QGNvZGUgbnVsbH0gbWVhbnMgbm8gb3B0aW9ucwogICAgICogQHBhcmFtIGNsYXNzZXMgbmFtZXMgb2YgY2xhc3NlcyB0byBiZSBwcm9jZXNzZWQgYnkgYW5ub3RhdGlvbgogICAgICogcHJvY2Vzc2luZywge0Bjb2RlIG51bGx9IG1lYW5zIG5vIGNsYXNzIG5hbWVzCiAgICAgKiBAcGFyYW0gY29tcGlsYXRpb25Vbml0cyB0aGUgY29tcGlsYXRpb24gdW5pdHMgdG8gY29tcGlsZSwge0Bjb2RlCiAgICAgKiBudWxsfSBtZWFucyBubyBjb21waWxhdGlvbiB1bml0cwogICAgICogQHJldHVybiBhbiBvYmplY3QgcmVwcmVzZW50aW5nIHRoZSBjb21waWxhdGlvbgogICAgICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIGlmIGFuIHVucmVjb3ZlcmFibGUgZXJyb3IKICAgICAqIG9jY3VycmVkIGluIGEgdXNlciBzdXBwbGllZCBjb21wb25lbnQuICBUaGUKICAgICAqIHtAbGlua3BsYWluIFRocm93YWJsZSNnZXRDYXVzZSgpIGNhdXNlfSB3aWxsIGJlIHRoZSBlcnJvciBpbgogICAgICogdXNlciBjb2RlLgogICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgYW55IG9mIHRoZSBvcHRpb25zIGFyZSBpbnZhbGlkLAogICAgICogb3IgaWYgYW55IG9mIHRoZSBnaXZlbiBjb21waWxhdGlvbiB1bml0cyBhcmUgb2Ygb3RoZXIga2luZCB0aGFuCiAgICAgKiB7QGxpbmtwbGFpbiBKYXZhRmlsZU9iamVjdC5LaW5kI1NPVVJDRSBzb3VyY2V9CiAgICAgKi8KICAgIENvbXBpbGF0aW9uVGFzayBnZXRUYXNrKFdyaXRlciBvdXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBKYXZhRmlsZU1hbmFnZXIgZmlsZU1hbmFnZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBEaWFnbm9zdGljTGlzdGVuZXI8PyBzdXBlciBKYXZhRmlsZU9iamVjdD4gZGlhZ25vc3RpY0xpc3RlbmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgSXRlcmFibGU8U3RyaW5nPiBvcHRpb25zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgSXRlcmFibGU8U3RyaW5nPiBjbGFzc2VzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgSXRlcmFibGU8PyBleHRlbmRzIEphdmFGaWxlT2JqZWN0PiBjb21waWxhdGlvblVuaXRzKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgYSBuZXcgaW5zdGFuY2Ugb2YgdGhlIHN0YW5kYXJkIGZpbGUgbWFuYWdlciBpbXBsZW1lbnRhdGlvbgogICAgICogZm9yIHRoaXMgdG9vbC4gIFRoZSBmaWxlIG1hbmFnZXIgd2lsbCB1c2UgdGhlIGdpdmVuIGRpYWdub3N0aWMKICAgICAqIGxpc3RlbmVyIGZvciBwcm9kdWNpbmcgYW55IG5vbi1mYXRhbCBkaWFnbm9zdGljcy4gIEZhdGFsIGVycm9ycwogICAgICogd2lsbCBiZSBzaWduYWxlZCB3aXRoIHRoZSBhcHByb3ByaWF0ZSBleGNlcHRpb25zLgogICAgICoKICAgICAqIDxwPlRoZSBzdGFuZGFyZCBmaWxlIG1hbmFnZXIgd2lsbCBiZSBhdXRvbWF0aWNhbGx5IHJlb3BlbmVkIGlmCiAgICAgKiBpdCBpcyBhY2Nlc3NlZCBhZnRlciBjYWxscyB0byB7QGNvZGUgZmx1c2h9IG9yIHtAY29kZSBjbG9zZX0uCiAgICAgKiBUaGUgc3RhbmRhcmQgZmlsZSBtYW5hZ2VyIG11c3QgYmUgdXNhYmxlIHdpdGggb3RoZXIgdG9vbHMuCiAgICAgKgogICAgICogQHBhcmFtIGRpYWdub3N0aWNMaXN0ZW5lciBhIGRpYWdub3N0aWMgbGlzdGVuZXIgZm9yIG5vbi1mYXRhbAogICAgICogZGlhZ25vc3RpY3M7IGlmIHtAY29kZSBudWxsfSB1c2UgdGhlIGNvbXBpbGVyJ3MgZGVmYXVsdCBtZXRob2QKICAgICAqIGZvciByZXBvcnRpbmcgZGlhZ25vc3RpY3MKICAgICAqIEBwYXJhbSBsb2NhbGUgdGhlIGxvY2FsZSB0byBhcHBseSB3aGVuIGZvcm1hdHRpbmcgZGlhZ25vc3RpY3M7CiAgICAgKiB7QGNvZGUgbnVsbH0gbWVhbnMgdGhlIHtAbGlua3BsYWluIExvY2FsZSNnZXREZWZhdWx0KCkgZGVmYXVsdCBsb2NhbGV9LgogICAgICogQHBhcmFtIGNoYXJzZXQgdGhlIGNoYXJhY3RlciBzZXQgdXNlZCBmb3IgZGVjb2RpbmcgYnl0ZXM7IGlmCiAgICAgKiB7QGNvZGUgbnVsbH0gdXNlIHRoZSBwbGF0Zm9ybSBkZWZhdWx0CiAgICAgKiBAcmV0dXJuIHRoZSBzdGFuZGFyZCBmaWxlIG1hbmFnZXIKICAgICAqLwogICAgU3RhbmRhcmRKYXZhRmlsZU1hbmFnZXIgZ2V0U3RhbmRhcmRGaWxlTWFuYWdlcigKICAgICAgICBEaWFnbm9zdGljTGlzdGVuZXI8PyBzdXBlciBKYXZhRmlsZU9iamVjdD4gZGlhZ25vc3RpY0xpc3RlbmVyLAogICAgICAgIExvY2FsZSBsb2NhbGUsCiAgICAgICAgQ2hhcnNldCBjaGFyc2V0KTsKCiAgICAvKioKICAgICAqIEludGVyZmFjZSByZXByZXNlbnRpbmcgYSBmdXR1cmUgZm9yIGEgY29tcGlsYXRpb24gdGFzay4gIFRoZQogICAgICogY29tcGlsYXRpb24gdGFzayBoYXMgbm90IHlldCBzdGFydGVkLiAgVG8gc3RhcnQgdGhlIHRhc2ssIGNhbGwKICAgICAqIHRoZSB7QGxpbmtwbGFpbiAjY2FsbCBjYWxsfSBtZXRob2QuCiAgICAgKgogICAgICogPHA+QmVmb3JlIGNhbGxpbmcgdGhlIGNhbGwgbWV0aG9kLCBhZGRpdGlvbmFsIGFzcGVjdHMgb2YgdGhlCiAgICAgKiB0YXNrIGNhbiBiZSBjb25maWd1cmVkLCBmb3IgZXhhbXBsZSwgYnkgY2FsbGluZyB0aGUKICAgICAqIHtAbGlua3BsYWluICNzZXRQcm9jZXNzb3JzIHNldFByb2Nlc3NvcnN9IG1ldGhvZC4KICAgICAqLwogICAgaW50ZXJmYWNlIENvbXBpbGF0aW9uVGFzayBleHRlbmRzIENhbGxhYmxlPEJvb2xlYW4+IHsKICAgICAgICAvKioKICAgICAgICAgKiBBZGRzIHJvb3QgbW9kdWxlcyB0byBiZSB0YWtlbiBpbnRvIGFjY291bnQgZHVyaW5nIG1vZHVsZQogICAgICAgICAqIHJlc29sdXRpb24uCiAgICAgICAgICogSW52YWxpZCBtb2R1bGUgbmFtZXMgbWF5IGNhdXNlIGVpdGhlcgogICAgICAgICAqIHtAY29kZSBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb259IHRvIGJlIHRocm93biwKICAgICAgICAgKiBvciBkaWFnbm9zdGljcyB0byBiZSByZXBvcnRlZCB3aGVuIHRoZSB0YXNrIGlzIHN0YXJ0ZWQuCiAgICAgICAgICogQHBhcmFtIG1vZHVsZU5hbWVzIHRoZSBuYW1lcyBvZiB0aGUgcm9vdCBtb2R1bGVzCiAgICAgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gbWF5IGJlIHRocm93biBmb3Igc29tZQogICAgICAgICAqICAgICAgaW52YWxpZCBtb2R1bGUgbmFtZXMKICAgICAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB0aGUgdGFzayBoYXMgc3RhcnRlZAogICAgICAgICAqLwogICAgICAgIHZvaWQgYWRkTW9kdWxlcyhJdGVyYWJsZTxTdHJpbmc+IG1vZHVsZU5hbWVzKTsKCiAgICAgICAgLyoqCiAgICAgICAgICogU2V0cyBwcm9jZXNzb3JzIChmb3IgYW5ub3RhdGlvbiBwcm9jZXNzaW5nKS4gIFRoaXMgd2lsbAogICAgICAgICAqIGJ5cGFzcyB0aGUgbm9ybWFsIGRpc2NvdmVyeSBtZWNoYW5pc20uCiAgICAgICAgICoKICAgICAgICAgKiBAcGFyYW0gcHJvY2Vzc29ycyBwcm9jZXNzb3JzIChmb3IgYW5ub3RhdGlvbiBwcm9jZXNzaW5nKQogICAgICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoZSB0YXNrIGhhcyBzdGFydGVkCiAgICAgICAgICovCiAgICAgICAgdm9pZCBzZXRQcm9jZXNzb3JzKEl0ZXJhYmxlPD8gZXh0ZW5kcyBQcm9jZXNzb3I+IHByb2Nlc3NvcnMpOwoKICAgICAgICAvKioKICAgICAgICAgKiBTZXRzIHRoZSBsb2NhbGUgdG8gYmUgYXBwbGllZCB3aGVuIGZvcm1hdHRpbmcgZGlhZ25vc3RpY3MgYW5kCiAgICAgICAgICogb3RoZXIgbG9jYWxpemVkIGRhdGEuCiAgICAgICAgICoKICAgICAgICAgKiBAcGFyYW0gbG9jYWxlIHRoZSBsb2NhbGUgdG8gYXBwbHk7IHtAY29kZSBudWxsfSBtZWFucyBhcHBseSBubwogICAgICAgICAqIGxvY2FsZQogICAgICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHRoZSB0YXNrIGhhcyBzdGFydGVkCiAgICAgICAgICovCiAgICAgICAgdm9pZCBzZXRMb2NhbGUoTG9jYWxlIGxvY2FsZSk7CgogICAgICAgIC8qKgogICAgICAgICAqIFBlcmZvcm1zIHRoaXMgY29tcGlsYXRpb24gdGFzay4gIFRoZSBjb21waWxhdGlvbiBtYXkgb25seQogICAgICAgICAqIGJlIHBlcmZvcm1lZCBvbmNlLiAgU3Vic2VxdWVudCBjYWxscyB0byB0aGlzIG1ldGhvZCB0aHJvdwogICAgICAgICAqIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbi4KICAgICAgICAgKgogICAgICAgICAqIEByZXR1cm4gdHJ1ZSBpZiBhbmQgb25seSBhbGwgdGhlIGZpbGVzIGNvbXBpbGVkIHdpdGhvdXQgZXJyb3JzOwogICAgICAgICAqIGZhbHNlIG90aGVyd2lzZQogICAgICAgICAqCiAgICAgICAgICogQHRocm93cyBSdW50aW1lRXhjZXB0aW9uIGlmIGFuIHVucmVjb3ZlcmFibGUgZXJyb3Igb2NjdXJyZWQKICAgICAgICAgKiBpbiBhIHVzZXItc3VwcGxpZWQgY29tcG9uZW50LiAgVGhlCiAgICAgICAgICoge0BsaW5rcGxhaW4gVGhyb3dhYmxlI2dldENhdXNlKCkgY2F1c2V9IHdpbGwgYmUgdGhlIGVycm9yCiAgICAgICAgICogaW4gdXNlciBjb2RlLgogICAgICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIGNhbGxlZCBtb3JlIHRoYW4gb25jZQogICAgICAgICAqLwogICAgICAgIEBPdmVycmlkZQogICAgICAgIEJvb2xlYW4gY2FsbCgpOwogICAgfQp9ClBLAwQKAAAIAADSfU1KreRrgEoHAABKBwAAIwAAAGphdmF4L3Rvb2xzL0RpYWdub3N0aWNMaXN0ZW5lci5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDA1LCAyMDA2LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGphdmF4LnRvb2xzOwoKLyoqCiAqIEludGVyZmFjZSBmb3IgcmVjZWl2aW5nIGRpYWdub3N0aWNzIGZyb20gdG9vbHMuCiAqCiAqIEBwYXJhbSA8Uz4gdGhlIHR5cGUgb2Ygc291cmNlIG9iamVjdHMgdXNlZCBieSBkaWFnbm9zdGljcyByZWNlaXZlZAogKiBieSB0aGlzIGxpc3RlbmVyCiAqCiAqIEBhdXRob3IgSm9uYXRoYW4gR2liYm9ucwogKiBAYXV0aG9yIFBldGVyIHZvbiBkZXIgQWgmZWFjdXRlOwogKiBAc2luY2UgMS42CiAqLwpwdWJsaWMgaW50ZXJmYWNlIERpYWdub3N0aWNMaXN0ZW5lcjxTPiB7CiAgICAvKioKICAgICAqIEludm9rZWQgd2hlbiBhIHByb2JsZW0gaXMgZm91bmQuCiAgICAgKgogICAgICogQHBhcmFtIGRpYWdub3N0aWMgYSBkaWFnbm9zdGljIHJlcHJlc2VudGluZyB0aGUgcHJvYmxlbSB0aGF0CiAgICAgKiB3YXMgZm91bmQKICAgICAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgdGhlIGRpYWdub3N0aWMgYXJndW1lbnQgaXMKICAgICAqIHtAY29kZSBudWxsfSBhbmQgdGhlIGltcGxlbWVudGF0aW9uIGNhbm5vdCBoYW5kbGUge0Bjb2RlIG51bGx9CiAgICAgKiBhcmd1bWVudHMKICAgICAqLwogICAgdm9pZCByZXBvcnQoRGlhZ25vc3RpYzw/IGV4dGVuZHMgUz4gZGlhZ25vc3RpYyk7Cn0KUEsDBAoAAAgAAAY7qUqOk0h24QkAAOEJAAAhAAAAamF2YXgvdG9vbHMvRmlsZU1hbmFnZXJVdGlscy5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDE0LCAyMDE1LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGphdmF4LnRvb2xzOwoKaW1wb3J0IGphdmEuaW8uRmlsZTsKaW1wb3J0IGphdmEubmlvLmZpbGUuUGF0aDsKaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKCi8qKgogKiBQYWNrYWdlLXByaXZhdGUgdXRpbGl0eSBtZXRob2RzIHRvIGNvbnZlcnQgYmV0d2VlbiBmaWxlcyBhbmQgcGF0aHMuCiAqCiAqIEBzaW5jZSA5CiAqLwpjbGFzcyBGaWxlTWFuYWdlclV0aWxzIHsKICAgIHByaXZhdGUgRmlsZU1hbmFnZXJVdGlscygpIHsgfQoKICAgIHN0YXRpYyBJdGVyYWJsZTxQYXRoPiBhc1BhdGhzKGZpbmFsIEl0ZXJhYmxlPD8gZXh0ZW5kcyBGaWxlPiBmaWxlcykgewogICAgICAgIHJldHVybiAoKSAtPiBuZXcgSXRlcmF0b3I8UGF0aD4oKSB7CiAgICAgICAgICAgIEl0ZXJhdG9yPD8gZXh0ZW5kcyBGaWxlPiBpdGVyID0gZmlsZXMuaXRlcmF0b3IoKTsKCiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNOZXh0KCkgewogICAgICAgICAgICAgICAgcmV0dXJuIGl0ZXIuaGFzTmV4dCgpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHVibGljIFBhdGggbmV4dCgpIHsKICAgICAgICAgICAgICAgIHJldHVybiBpdGVyLm5leHQoKS50b1BhdGgoKTsKICAgICAgICAgICAgfQogICAgICAgIH07CiAgICB9CgogICAgc3RhdGljIEl0ZXJhYmxlPEZpbGU+IGFzRmlsZXMoZmluYWwgSXRlcmFibGU8PyBleHRlbmRzIFBhdGg+IHBhdGhzKSB7CiAgICAgICAgcmV0dXJuICgpIC0+IG5ldyBJdGVyYXRvcjxGaWxlPigpIHsKICAgICAgICAgICAgSXRlcmF0b3I8PyBleHRlbmRzIFBhdGg+IGl0ZXIgPSBwYXRocy5pdGVyYXRvcigpOwoKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHB1YmxpYyBib29sZWFuIGhhc05leHQoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gaXRlci5oYXNOZXh0KCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwdWJsaWMgRmlsZSBuZXh0KCkgewogICAgICAgICAgICAgICAgUGF0aCBwID0gaXRlci5uZXh0KCk7CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBwLnRvRmlsZSgpOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gZSkgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24ocC50b1N0cmluZygpLCBlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH07CiAgICB9Cn0KUEsDBAoAAAgAAAY7qUpdU4u6uRwAALkcAAAlAAAAamF2YXgvdG9vbHMvU2ltcGxlSmF2YUZpbGVPYmplY3QuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAwNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBqYXZheC50b29sczsKCmltcG9ydCBqYXZhLmlvLio7CmltcG9ydCBqYXZhLm5ldC5VUkk7CmltcG9ydCBqYXZhLm5pby5DaGFyQnVmZmVyOwppbXBvcnQgamF2YS51dGlsLk9iamVjdHM7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuTW9kaWZpZXI7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuTmVzdGluZ0tpbmQ7CmltcG9ydCBqYXZheC50b29scy5KYXZhRmlsZU9iamVjdC5LaW5kOwoKLyoqCiAqIFByb3ZpZGVzIHNpbXBsZSBpbXBsZW1lbnRhdGlvbnMgZm9yIG1vc3QgbWV0aG9kcyBpbiBKYXZhRmlsZU9iamVjdC4KICogVGhpcyBjbGFzcyBpcyBkZXNpZ25lZCB0byBiZSBzdWJjbGFzc2VkIGFuZCB1c2VkIGFzIGEgYmFzaXMgZm9yCiAqIEphdmFGaWxlT2JqZWN0IGltcGxlbWVudGF0aW9ucy4gIFN1YmNsYXNzZXMgY2FuIG92ZXJyaWRlIHRoZQogKiBpbXBsZW1lbnRhdGlvbiBhbmQgc3BlY2lmaWNhdGlvbiBvZiBhbnkgbWV0aG9kIG9mIHRoaXMgY2xhc3MgYXMKICogbG9uZyBhcyB0aGUgZ2VuZXJhbCBjb250cmFjdCBvZiBKYXZhRmlsZU9iamVjdCBpcyBvYmV5ZWQuCiAqCiAqIEBhdXRob3IgUGV0ZXIgdm9uIGRlciBBaCZlYWN1dGU7CiAqIEBzaW5jZSAxLjYKICovCnB1YmxpYyBjbGFzcyBTaW1wbGVKYXZhRmlsZU9iamVjdCBpbXBsZW1lbnRzIEphdmFGaWxlT2JqZWN0IHsKICAgIC8qKgogICAgICogQSBVUkkgZm9yIHRoaXMgZmlsZSBvYmplY3QuCiAgICAgKi8KICAgIHByb3RlY3RlZCBmaW5hbCBVUkkgdXJpOwoKICAgIC8qKgogICAgICogVGhlIGtpbmQgb2YgdGhpcyBmaWxlIG9iamVjdC4KICAgICAqLwogICAgcHJvdGVjdGVkIGZpbmFsIEtpbmQga2luZDsKCiAgICAvKioKICAgICAqIENvbnN0cnVjdCBhIFNpbXBsZUphdmFGaWxlT2JqZWN0IG9mIHRoZSBnaXZlbiBraW5kIGFuZCB3aXRoIHRoZQogICAgICogZ2l2ZW4gVVJJLgogICAgICoKICAgICAqIEBwYXJhbSB1cmkgIHRoZSBVUkkgZm9yIHRoaXMgZmlsZSBvYmplY3QKICAgICAqIEBwYXJhbSBraW5kIHRoZSBraW5kIG9mIHRoaXMgZmlsZSBvYmplY3QKICAgICAqLwogICAgcHJvdGVjdGVkIFNpbXBsZUphdmFGaWxlT2JqZWN0KFVSSSB1cmksIEtpbmQga2luZCkgewogICAgICAgIE9iamVjdHMucmVxdWlyZU5vbk51bGwodXJpKTsKICAgICAgICBPYmplY3RzLnJlcXVpcmVOb25OdWxsKGtpbmQpOwogICAgICAgIGlmICh1cmkuZ2V0UGF0aCgpID09IG51bGwpCiAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIlVSSSBtdXN0IGhhdmUgYSBwYXRoOiAiICsgdXJpKTsKICAgICAgICB0aGlzLnVyaSA9IHVyaTsKICAgICAgICB0aGlzLmtpbmQgPSBraW5kOwogICAgfQoKICAgIHB1YmxpYyBVUkkgdG9VcmkoKSB7CiAgICAgICAgcmV0dXJuIHVyaTsKICAgIH0KCiAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWUoKSB7CiAgICAgICAgcmV0dXJuIHRvVXJpKCkuZ2V0UGF0aCgpOwogICAgfQoKICAgIC8qKgogICAgICogVGhpcyBpbXBsZW1lbnRhdGlvbiBhbHdheXMgdGhyb3dzIHtAbGlua3BsYWluCiAgICAgKiBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbn0uICBTdWJjbGFzc2VzIGNhbiBjaGFuZ2UgdGhpcwogICAgICogYmVoYXZpb3IgYXMgbG9uZyBhcyB0aGUgY29udHJhY3Qgb2Yge0BsaW5rIEZpbGVPYmplY3R9IGlzCiAgICAgKiBvYmV5ZWQuCiAgICAgKi8KICAgIHB1YmxpYyBJbnB1dFN0cmVhbSBvcGVuSW5wdXRTdHJlYW0oKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOwogICAgfQoKICAgIC8qKgogICAgICogVGhpcyBpbXBsZW1lbnRhdGlvbiBhbHdheXMgdGhyb3dzIHtAbGlua3BsYWluCiAgICAgKiBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbn0uICBTdWJjbGFzc2VzIGNhbiBjaGFuZ2UgdGhpcwogICAgICogYmVoYXZpb3IgYXMgbG9uZyBhcyB0aGUgY29udHJhY3Qgb2Yge0BsaW5rIEZpbGVPYmplY3R9IGlzCiAgICAgKiBvYmV5ZWQuCiAgICAgKi8KICAgIHB1YmxpYyBPdXRwdXRTdHJlYW0gb3Blbk91dHB1dFN0cmVhbSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBXcmFwcyB0aGUgcmVzdWx0IG9mIHtAbGlua3BsYWluICNnZXRDaGFyQ29udGVudH0gaW4gYSBSZWFkZXIuCiAgICAgKiBTdWJjbGFzc2VzIGNhbiBjaGFuZ2UgdGhpcyBiZWhhdmlvciBhcyBsb25nIGFzIHRoZSBjb250cmFjdCBvZgogICAgICoge0BsaW5rIEZpbGVPYmplY3R9IGlzIG9iZXllZC4KICAgICAqCiAgICAgKiBAcGFyYW0gIGlnbm9yZUVuY29kaW5nRXJyb3JzIHtAaW5oZXJpdERvY30KICAgICAqIEByZXR1cm4gYSBSZWFkZXIgd3JhcHBpbmcgdGhlIHJlc3VsdCBvZiBnZXRDaGFyQ29udGVudAogICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24ge0Bpbmhlcml0RG9jfQogICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CiAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIFJlYWRlciBvcGVuUmVhZGVyKGJvb2xlYW4gaWdub3JlRW5jb2RpbmdFcnJvcnMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgQ2hhclNlcXVlbmNlIGNoYXJDb250ZW50ID0gZ2V0Q2hhckNvbnRlbnQoaWdub3JlRW5jb2RpbmdFcnJvcnMpOwogICAgICAgIGlmIChjaGFyQ29udGVudCA9PSBudWxsKQogICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKICAgICAgICBpZiAoY2hhckNvbnRlbnQgaW5zdGFuY2VvZiBDaGFyQnVmZmVyKSB7CiAgICAgICAgICAgIENoYXJCdWZmZXIgYnVmZmVyID0gKENoYXJCdWZmZXIpY2hhckNvbnRlbnQ7CiAgICAgICAgICAgIGlmIChidWZmZXIuaGFzQXJyYXkoKSkKICAgICAgICAgICAgICAgIHJldHVybiBuZXcgQ2hhckFycmF5UmVhZGVyKGJ1ZmZlci5hcnJheSgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG5ldyBTdHJpbmdSZWFkZXIoY2hhckNvbnRlbnQudG9TdHJpbmcoKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBUaGlzIGltcGxlbWVudGF0aW9uIGFsd2F5cyB0aHJvd3Mge0BsaW5rcGxhaW4KICAgICAqIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9ufS4gIFN1YmNsYXNzZXMgY2FuIGNoYW5nZSB0aGlzCiAgICAgKiBiZWhhdmlvciBhcyBsb25nIGFzIHRoZSBjb250cmFjdCBvZiB7QGxpbmsgRmlsZU9iamVjdH0gaXMKICAgICAqIG9iZXllZC4KICAgICAqLwogICAgcHVibGljIENoYXJTZXF1ZW5jZSBnZXRDaGFyQ29udGVudChib29sZWFuIGlnbm9yZUVuY29kaW5nRXJyb3JzKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOwogICAgfQoKICAgIC8qKgogICAgICogV3JhcHMgdGhlIHJlc3VsdCBvZiBvcGVuT3V0cHV0U3RyZWFtIGluIGEgV3JpdGVyLiAgU3ViY2xhc3NlcwogICAgICogY2FuIGNoYW5nZSB0aGlzIGJlaGF2aW9yIGFzIGxvbmcgYXMgdGhlIGNvbnRyYWN0IG9mIHtAbGluawogICAgICogRmlsZU9iamVjdH0gaXMgb2JleWVkLgogICAgICoKICAgICAqIEByZXR1cm4gYSBXcml0ZXIgd3JhcHBpbmcgdGhlIHJlc3VsdCBvZiBvcGVuT3V0cHV0U3RyZWFtCiAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CiAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIHtAaW5oZXJpdERvY30KICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24ge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgV3JpdGVyIG9wZW5Xcml0ZXIoKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBuZXcgT3V0cHV0U3RyZWFtV3JpdGVyKG9wZW5PdXRwdXRTdHJlYW0oKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBUaGlzIGltcGxlbWVudGF0aW9uIHJldHVybnMge0Bjb2RlIDBMfS4gIFN1YmNsYXNzZXMgY2FuIGNoYW5nZQogICAgICogdGhpcyBiZWhhdmlvciBhcyBsb25nIGFzIHRoZSBjb250cmFjdCBvZiB7QGxpbmsgRmlsZU9iamVjdH0gaXMKICAgICAqIG9iZXllZC4KICAgICAqCiAgICAgKiBAcmV0dXJuIHtAY29kZSAwTH0KICAgICAqLwogICAgcHVibGljIGxvbmcgZ2V0TGFzdE1vZGlmaWVkKCkgewogICAgICAgIHJldHVybiAwTDsKICAgIH0KCiAgICAvKioKICAgICAqIFRoaXMgaW1wbGVtZW50YXRpb24gZG9lcyBub3RoaW5nLiAgU3ViY2xhc3NlcyBjYW4gY2hhbmdlIHRoaXMKICAgICAqIGJlaGF2aW9yIGFzIGxvbmcgYXMgdGhlIGNvbnRyYWN0IG9mIHtAbGluayBGaWxlT2JqZWN0fSBpcwogICAgICogb2JleWVkLgogICAgICoKICAgICAqIEByZXR1cm4ge0Bjb2RlIGZhbHNlfQogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBkZWxldGUoKSB7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiB7QGNvZGUgdGhpcy5raW5kfQogICAgICovCiAgICBwdWJsaWMgS2luZCBnZXRLaW5kKCkgewogICAgICAgIHJldHVybiBraW5kOwogICAgfQoKICAgIC8qKgogICAgICogVGhpcyBpbXBsZW1lbnRhdGlvbiBjb21wYXJlcyB0aGUgcGF0aCBvZiBpdHMgVVJJIHRvIHRoZSBnaXZlbgogICAgICogc2ltcGxlIG5hbWUuICBUaGlzIG1ldGhvZCByZXR1cm5zIHRydWUgaWYgdGhlIGdpdmVuIGtpbmQgaXMKICAgICAqIGVxdWFsIHRvIHRoZSBraW5kIG9mIHRoaXMgb2JqZWN0LCBhbmQgaWYgdGhlIHBhdGggaXMgZXF1YWwgdG8KICAgICAqIHtAY29kZSBzaW1wbGVOYW1lICsga2luZC5leHRlbnNpb259IG9yIGlmIGl0IGVuZHMgd2l0aCB7QGNvZGUKICAgICAqICIvIiArIHNpbXBsZU5hbWUgKyBraW5kLmV4dGVuc2lvbn0uCiAgICAgKgogICAgICogPHA+VGhpcyBtZXRob2QgY2FsbHMge0BsaW5rICNnZXRLaW5kfSBhbmQge0BsaW5rICN0b1VyaX0gYW5kCiAgICAgKiBkb2VzIG5vdCBhY2Nlc3MgdGhlIGZpZWxkcyB7QGxpbmsgI3VyaX0gYW5kIHtAbGluayAja2luZH0KICAgICAqIGRpcmVjdGx5LgogICAgICoKICAgICAqIDxwPlN1YmNsYXNzZXMgY2FuIGNoYW5nZSB0aGlzIGJlaGF2aW9yIGFzIGxvbmcgYXMgdGhlIGNvbnRyYWN0CiAgICAgKiBvZiB7QGxpbmsgSmF2YUZpbGVPYmplY3R9IGlzIG9iZXllZC4KICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gaXNOYW1lQ29tcGF0aWJsZShTdHJpbmcgc2ltcGxlTmFtZSwgS2luZCBraW5kKSB7CiAgICAgICAgU3RyaW5nIGJhc2VOYW1lID0gc2ltcGxlTmFtZSArIGtpbmQuZXh0ZW5zaW9uOwogICAgICAgIHJldHVybiBraW5kLmVxdWFscyhnZXRLaW5kKCkpCiAgICAgICAgICAgICYmIChiYXNlTmFtZS5lcXVhbHModG9VcmkoKS5nZXRQYXRoKCkpCiAgICAgICAgICAgICAgICB8fCB0b1VyaSgpLmdldFBhdGgoKS5lbmRzV2l0aCgiLyIgKyBiYXNlTmFtZSkpOwogICAgfQoKICAgIC8qKgogICAgICogVGhpcyBpbXBsZW1lbnRhdGlvbiByZXR1cm5zIHtAY29kZSBudWxsfS4gIFN1YmNsYXNzZXMgY2FuCiAgICAgKiBjaGFuZ2UgdGhpcyBiZWhhdmlvciBhcyBsb25nIGFzIHRoZSBjb250cmFjdCBvZgogICAgICoge0BsaW5rIEphdmFGaWxlT2JqZWN0fSBpcyBvYmV5ZWQuCiAgICAgKi8KICAgIHB1YmxpYyBOZXN0aW5nS2luZCBnZXROZXN0aW5nS2luZCgpIHsgcmV0dXJuIG51bGw7IH0KCiAgICAvKioKICAgICAqIFRoaXMgaW1wbGVtZW50YXRpb24gcmV0dXJucyB7QGNvZGUgbnVsbH0uICBTdWJjbGFzc2VzIGNhbgogICAgICogY2hhbmdlIHRoaXMgYmVoYXZpb3IgYXMgbG9uZyBhcyB0aGUgY29udHJhY3Qgb2YKICAgICAqIHtAbGluayBKYXZhRmlsZU9iamVjdH0gaXMgb2JleWVkLgogICAgICovCiAgICBwdWJsaWMgTW9kaWZpZXIgZ2V0QWNjZXNzTGV2ZWwoKSAgeyByZXR1cm4gbnVsbDsgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKICAgICAgICByZXR1cm4gZ2V0Q2xhc3MoKS5nZXROYW1lKCkgKyAiWyIgKyB0b1VyaSgpICsgIl0iOwogICAgfQp9ClBLAwQKAAAIAAAGO6lKTS+KQZ4aAACeGgAAKgAAAGphdmF4L3Rvb2xzL0ZvcndhcmRpbmdKYXZhRmlsZU1hbmFnZXIuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAxNywgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBqYXZheC50b29sczsKCmltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwppbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOwppbXBvcnQgamF2YS51dGlsLk9iamVjdHM7CmltcG9ydCBqYXZhLnV0aWwuU2VydmljZUxvYWRlcjsKaW1wb3J0IGphdmEudXRpbC5TZXQ7CmltcG9ydCBqYXZheC50b29scy5KYXZhRmlsZU9iamVjdC5LaW5kOwoKLyoqCiAqIEZvcndhcmRzIGNhbGxzIHRvIGEgZ2l2ZW4gZmlsZSBtYW5hZ2VyLiAgU3ViY2xhc3NlcyBvZiB0aGlzIGNsYXNzCiAqIG1pZ2h0IG92ZXJyaWRlIHNvbWUgb2YgdGhlc2UgbWV0aG9kcyBhbmQgbWlnaHQgYWxzbyBwcm92aWRlCiAqIGFkZGl0aW9uYWwgZmllbGRzIGFuZCBtZXRob2RzLgogKgogKiBAcGFyYW0gPE0+IHRoZSBraW5kIG9mIGZpbGUgbWFuYWdlciBmb3J3YXJkZWQgdG8gYnkgdGhpcyBvYmplY3QKICogQGF1dGhvciBQZXRlciB2b24gZGVyIEFoJmVhY3V0ZTsKICogQHNpbmNlIDEuNgogKi8KcHVibGljIGNsYXNzIEZvcndhcmRpbmdKYXZhRmlsZU1hbmFnZXI8TSBleHRlbmRzIEphdmFGaWxlTWFuYWdlcj4gaW1wbGVtZW50cyBKYXZhRmlsZU1hbmFnZXIgewoKICAgIC8qKgogICAgICogVGhlIGZpbGUgbWFuYWdlciB3aGljaCBhbGwgbWV0aG9kcyBhcmUgZGVsZWdhdGVkIHRvLgogICAgICovCiAgICBwcm90ZWN0ZWQgZmluYWwgTSBmaWxlTWFuYWdlcjsKCiAgICAvKioKICAgICAqIENyZWF0ZXMgYSBuZXcgaW5zdGFuY2Ugb2YgRm9yd2FyZGluZ0phdmFGaWxlTWFuYWdlci4KICAgICAqIEBwYXJhbSBmaWxlTWFuYWdlciBkZWxlZ2F0ZSB0byB0aGlzIGZpbGUgbWFuYWdlcgogICAgICovCiAgICBwcm90ZWN0ZWQgRm9yd2FyZGluZ0phdmFGaWxlTWFuYWdlcihNIGZpbGVNYW5hZ2VyKSB7CiAgICAgICAgdGhpcy5maWxlTWFuYWdlciA9IE9iamVjdHMucmVxdWlyZU5vbk51bGwoZmlsZU1hbmFnZXIpOwogICAgfQoKICAgIC8qKgogICAgICogQHRocm93cyBTZWN1cml0eUV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CiAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBDbGFzc0xvYWRlciBnZXRDbGFzc0xvYWRlcihMb2NhdGlvbiBsb2NhdGlvbikgewogICAgICAgIHJldHVybiBmaWxlTWFuYWdlci5nZXRDbGFzc0xvYWRlcihsb2NhdGlvbik7CiAgICB9CgogICAgLyoqCiAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIHtAaW5oZXJpdERvY30KICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIHtAaW5oZXJpdERvY30KICAgICAqLwogICAgcHVibGljIEl0ZXJhYmxlPEphdmFGaWxlT2JqZWN0PiBsaXN0KExvY2F0aW9uIGxvY2F0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBwYWNrYWdlTmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTZXQ8S2luZD4ga2luZHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiByZWN1cnNlKQogICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbgogICAgewogICAgICAgIHJldHVybiBmaWxlTWFuYWdlci5saXN0KGxvY2F0aW9uLCBwYWNrYWdlTmFtZSwga2luZHMsIHJlY3Vyc2UpOwogICAgfQoKICAgIC8qKgogICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24ge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgU3RyaW5nIGluZmVyQmluYXJ5TmFtZShMb2NhdGlvbiBsb2NhdGlvbiwgSmF2YUZpbGVPYmplY3QgZmlsZSkgewogICAgICAgIHJldHVybiBmaWxlTWFuYWdlci5pbmZlckJpbmFyeU5hbWUobG9jYXRpb24sIGZpbGUpOwogICAgfQoKICAgIC8qKgogICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24ge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBpc1NhbWVGaWxlKEZpbGVPYmplY3QgYSwgRmlsZU9iamVjdCBiKSB7CiAgICAgICAgcmV0dXJuIGZpbGVNYW5hZ2VyLmlzU2FtZUZpbGUoYSwgYik7CiAgICB9CgogICAgLyoqCiAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CiAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGhhbmRsZU9wdGlvbihTdHJpbmcgY3VycmVudCwgSXRlcmF0b3I8U3RyaW5nPiByZW1haW5pbmcpIHsKICAgICAgICByZXR1cm4gZmlsZU1hbmFnZXIuaGFuZGxlT3B0aW9uKGN1cnJlbnQsIHJlbWFpbmluZyk7CiAgICB9CgogICAgcHVibGljIGJvb2xlYW4gaGFzTG9jYXRpb24oTG9jYXRpb24gbG9jYXRpb24pIHsKICAgICAgICByZXR1cm4gZmlsZU1hbmFnZXIuaGFzTG9jYXRpb24obG9jYXRpb24pOwogICAgfQoKICAgIHB1YmxpYyBpbnQgaXNTdXBwb3J0ZWRPcHRpb24oU3RyaW5nIG9wdGlvbikgewogICAgICAgIHJldHVybiBmaWxlTWFuYWdlci5pc1N1cHBvcnRlZE9wdGlvbihvcHRpb24pOwogICAgfQoKICAgIC8qKgogICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24ge0Bpbmhlcml0RG9jfQogICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24ge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgSmF2YUZpbGVPYmplY3QgZ2V0SmF2YUZpbGVGb3JJbnB1dChMb2NhdGlvbiBsb2NhdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBjbGFzc05hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBLaW5kIGtpbmQpCiAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uCiAgICB7CiAgICAgICAgcmV0dXJuIGZpbGVNYW5hZ2VyLmdldEphdmFGaWxlRm9ySW5wdXQobG9jYXRpb24sIGNsYXNzTmFtZSwga2luZCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CiAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBKYXZhRmlsZU9iamVjdCBnZXRKYXZhRmlsZUZvck91dHB1dChMb2NhdGlvbiBsb2NhdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgY2xhc3NOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEtpbmQga2luZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGaWxlT2JqZWN0IHNpYmxpbmcpCiAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uCiAgICB7CiAgICAgICAgcmV0dXJuIGZpbGVNYW5hZ2VyLmdldEphdmFGaWxlRm9yT3V0cHV0KGxvY2F0aW9uLCBjbGFzc05hbWUsIGtpbmQsIHNpYmxpbmcpOwogICAgfQoKICAgIC8qKgogICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24ge0Bpbmhlcml0RG9jfQogICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24ge0Bpbmhlcml0RG9jfQogICAgICovCiAgICBwdWJsaWMgRmlsZU9iamVjdCBnZXRGaWxlRm9ySW5wdXQoTG9jYXRpb24gbG9jYXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHBhY2thZ2VOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyByZWxhdGl2ZU5hbWUpCiAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uCiAgICB7CiAgICAgICAgcmV0dXJuIGZpbGVNYW5hZ2VyLmdldEZpbGVGb3JJbnB1dChsb2NhdGlvbiwgcGFja2FnZU5hbWUsIHJlbGF0aXZlTmFtZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CiAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiB7QGluaGVyaXREb2N9CiAgICAgKi8KICAgIHB1YmxpYyBGaWxlT2JqZWN0IGdldEZpbGVGb3JPdXRwdXQoTG9jYXRpb24gbG9jYXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBwYWNrYWdlTmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHJlbGF0aXZlTmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmlsZU9iamVjdCBzaWJsaW5nKQogICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbgogICAgewogICAgICAgIHJldHVybiBmaWxlTWFuYWdlci5nZXRGaWxlRm9yT3V0cHV0KGxvY2F0aW9uLCBwYWNrYWdlTmFtZSwgcmVsYXRpdmVOYW1lLCBzaWJsaW5nKTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCBmbHVzaCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgZmlsZU1hbmFnZXIuZmx1c2goKTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgZmlsZU1hbmFnZXIuY2xvc2UoKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBzaW5jZSA5CiAgICAgKiBAc3BlYyBKUE1TCiAgICAgKi8KICAgIHB1YmxpYyBMb2NhdGlvbiBnZXRMb2NhdGlvbkZvck1vZHVsZShMb2NhdGlvbiBsb2NhdGlvbiwgU3RyaW5nIG1vZHVsZU5hbWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGZpbGVNYW5hZ2VyLmdldExvY2F0aW9uRm9yTW9kdWxlKGxvY2F0aW9uLCBtb2R1bGVOYW1lKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBzaW5jZSA5CiAgICAgKiBAc3BlYyBKUE1TCiAgICAgKi8KICAgIHB1YmxpYyBMb2NhdGlvbiBnZXRMb2NhdGlvbkZvck1vZHVsZShMb2NhdGlvbiBsb2NhdGlvbiwgSmF2YUZpbGVPYmplY3QgZm8pIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGZpbGVNYW5hZ2VyLmdldExvY2F0aW9uRm9yTW9kdWxlKGxvY2F0aW9uLCBmbyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAc2luY2UgOQogICAgICogQHNwZWMgSlBNUwogICAgICovCiAgICBwdWJsaWMgPFM+IFNlcnZpY2VMb2FkZXI8Uz4gZ2V0U2VydmljZUxvYWRlcihMb2NhdGlvbiBsb2NhdGlvbiwgQ2xhc3M8Uz4gc2VydmljZSkgdGhyb3dzICBJT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGZpbGVNYW5hZ2VyLmdldFNlcnZpY2VMb2FkZXIobG9jYXRpb24sIHNlcnZpY2UpOwogICAgfQoKICAgIC8qKgogICAgICogQHNpbmNlIDkKICAgICAqIEBzcGVjIEpQTVMKICAgICAqLwogICAgcHVibGljIFN0cmluZyBpbmZlck1vZHVsZU5hbWUoTG9jYXRpb24gbG9jYXRpb24pIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGZpbGVNYW5hZ2VyLmluZmVyTW9kdWxlTmFtZShsb2NhdGlvbik7CiAgICB9CgogICAgLyoqCiAgICAgKiBAc2luY2UgOQogICAgICogQHNwZWMgSlBNUwogICAgICovCiAgICBwdWJsaWMgSXRlcmFibGU8U2V0PExvY2F0aW9uPj4gbGlzdExvY2F0aW9uc0Zvck1vZHVsZXMoTG9jYXRpb24gbG9jYXRpb24pIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGZpbGVNYW5hZ2VyLmxpc3RMb2NhdGlvbnNGb3JNb2R1bGVzKGxvY2F0aW9uKTsKICAgIH0KfQpQSwMECgAACAAABjupSnXZMTqkZAAApGQAACAAAABqYXZheC90b29scy9KYXZhRmlsZU1hbmFnZXIuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAxNywgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBqYXZheC50b29sczsKCmltcG9ydCBqYXZhLmlvLkNsb3NlYWJsZTsKaW1wb3J0IGphdmEuaW8uRmx1c2hhYmxlOwppbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKaW1wb3J0IGphdmEudXRpbC5TZXJ2aWNlTG9hZGVyOwppbXBvcnQgamF2YS51dGlsLlNldDsKCmltcG9ydCBzdGF0aWMgamF2YXgudG9vbHMuSmF2YUZpbGVPYmplY3QuS2luZDsKCi8qKgogKiBGaWxlIG1hbmFnZXIgZm9yIHRvb2xzIG9wZXJhdGluZyBvbiBKYXZhJnRyYWRlOyBwcm9ncmFtbWluZyBsYW5ndWFnZQogKiBzb3VyY2UgYW5kIGNsYXNzIGZpbGVzLiAgSW4gdGhpcyBjb250ZXh0LCA8ZW0+ZmlsZTwvZW0+IG1lYW5zIGFuCiAqIGFic3RyYWN0aW9uIG9mIHJlZ3VsYXIgZmlsZXMgYW5kIG90aGVyIHNvdXJjZXMgb2YgZGF0YS4KICoKICogPHA+V2hlbiBjb25zdHJ1Y3RpbmcgbmV3IEphdmFGaWxlT2JqZWN0cywgdGhlIGZpbGUgbWFuYWdlciBtdXN0CiAqIGRldGVybWluZSB3aGVyZSB0byBjcmVhdGUgdGhlbS4gIEZvciBleGFtcGxlLCBpZiBhIGZpbGUgbWFuYWdlcgogKiBtYW5hZ2VzIHJlZ3VsYXIgZmlsZXMgb24gYSBmaWxlIHN5c3RlbSwgaXQgd291bGQgbW9zdCBsaWtlbHkgaGF2ZSBhCiAqIGN1cnJlbnQvd29ya2luZyBkaXJlY3RvcnkgdG8gdXNlIGFzIGRlZmF1bHQgbG9jYXRpb24gd2hlbiBjcmVhdGluZwogKiBvciBmaW5kaW5nIGZpbGVzLiAgQSBudW1iZXIgb2YgaGludHMgY2FuIGJlIHByb3ZpZGVkIHRvIGEgZmlsZQogKiBtYW5hZ2VyIGFzIHRvIHdoZXJlIHRvIGNyZWF0ZSBmaWxlcy4gIEFueSBmaWxlIG1hbmFnZXIgbWlnaHQgY2hvb3NlCiAqIHRvIGlnbm9yZSB0aGVzZSBoaW50cy4KICoKICogPHA+U29tZSBtZXRob2RzIGluIHRoaXMgaW50ZXJmYWNlIHVzZSBjbGFzcyBuYW1lcy4gIFN1Y2ggY2xhc3MKICogbmFtZXMgbXVzdCBiZSBnaXZlbiBpbiB0aGUgSmF2YSBWaXJ0dWFsIE1hY2hpbmUgaW50ZXJuYWwgZm9ybSBvZgogKiBmdWxseSBxdWFsaWZpZWQgY2xhc3MgYW5kIGludGVyZmFjZSBuYW1lcy4gIEZvciBjb252ZW5pZW5jZSAnLicKICogYW5kICcvJyBhcmUgaW50ZXJjaGFuZ2VhYmxlLiAgVGhlIGludGVybmFsIGZvcm0gaXMgZGVmaW5lZCBpbgogKiBjaGFwdGVyIGZvdXIgb2YKICogPGNpdGU+VGhlIEphdmEmdHJhZGU7IFZpcnR1YWwgTWFjaGluZSBTcGVjaWZpY2F0aW9uPC9jaXRlPi4KCiAqIDxibG9ja3F1b3RlPjxwPgogKiAgIDxpPkRpc2N1c3Npb246PC9pPiB0aGlzIG1lYW5zIHRoYXQgdGhlIG5hbWVzCiAqICAgImphdmEvbGFuZy5wYWNrYWdlLWluZm8iLCAiamF2YS9sYW5nL3BhY2thZ2UtaW5mbyIsCiAqICAgImphdmEubGFuZy5wYWNrYWdlLWluZm8iLCBhcmUgdmFsaWQgYW5kIGVxdWl2YWxlbnQuICBDb21wYXJlIHRvCiAqICAgYmluYXJ5IG5hbWUgYXMgZGVmaW5lZCBpbgogKiAgIDxjaXRlPlRoZSBKYXZhJnRyYWRlOyBMYW5ndWFnZSBTcGVjaWZpY2F0aW9uPC9jaXRlPiwKICogICBzZWN0aW9uIDEzLjEgIlRoZSBGb3JtIG9mIGEgQmluYXJ5Ii4KICogPC9wPjwvYmxvY2txdW90ZT4KICoKICogPHA+VGhlIGNhc2Ugb2YgbmFtZXMgaXMgc2lnbmlmaWNhbnQuICBBbGwgbmFtZXMgc2hvdWxkIGJlIHRyZWF0ZWQKICogYXMgY2FzZS1zZW5zaXRpdmUuICBGb3IgZXhhbXBsZSwgc29tZSBmaWxlIHN5c3RlbXMgaGF2ZQogKiBjYXNlLWluc2Vuc2l0aXZlLCBjYXNlLWF3YXJlIGZpbGUgbmFtZXMuICBGaWxlIG9iamVjdHMgcmVwcmVzZW50aW5nCiAqIHN1Y2ggZmlsZXMgc2hvdWxkIHRha2UgY2FyZSB0byBwcmVzZXJ2ZSBjYXNlIGJ5IHVzaW5nIHtAbGluawogKiBqYXZhLmlvLkZpbGUjZ2V0Q2Fub25pY2FsRmlsZX0gb3Igc2ltaWxhciBtZWFucy4gIElmIHRoZSBzeXN0ZW0gaXMKICogbm90IGNhc2UtYXdhcmUsIGZpbGUgb2JqZWN0cyBtdXN0IHVzZSBvdGhlciBtZWFucyB0byBwcmVzZXJ2ZSBjYXNlLgogKgogKiA8cD48ZW0+PGEgbmFtZT0icmVsYXRpdmVfbmFtZSI+UmVsYXRpdmUgbmFtZXM8L2E+OjwvZW0+IHNvbWUKICogbWV0aG9kcyBpbiB0aGlzIGludGVyZmFjZSB1c2UgcmVsYXRpdmUgbmFtZXMuICBBIHJlbGF0aXZlIG5hbWUgaXMgYQogKiBub24tbnVsbCwgbm9uLWVtcHR5IHNlcXVlbmNlIG9mIHBhdGggc2VnbWVudHMgc2VwYXJhdGVkIGJ5ICcvJy4KICogJy4nIG9yICcuLicgIGFyZSBpbnZhbGlkIHBhdGggc2VnbWVudHMuICBBIHZhbGlkIHJlbGF0aXZlIG5hbWUgbXVzdAogKiBtYXRjaCB0aGUgInBhdGgtcm9vdGxlc3MiIHJ1bGUgb2YgPGEKICogaHJlZj0iaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMzk4Ni50eHQiPlJGQyZuYnNwOzM5ODY8L2E+LAogKiBzZWN0aW9uJm5ic3A7My4zLiAgSW5mb3JtYWxseSwgdGhpcyBzaG91bGQgYmUgdHJ1ZToKICoKICogPCEtLSBVUkkuY3JlYXRlKHJlbGF0aXZlTmFtZSkubm9ybWFsaXplKCkuZ2V0UGF0aCgpLmVxdWFscyhyZWxhdGl2ZU5hbWUpIC0tPgogKiA8cHJlPiAgVVJJLntAbGlua3BsYWluIGphdmEubmV0LlVSSSNjcmVhdGUgY3JlYXRlfShyZWxhdGl2ZU5hbWUpLntAbGlua3BsYWluIGphdmEubmV0LlVSSSNub3JtYWxpemUgbm9ybWFsaXplfSgpLntAbGlua3BsYWluIGphdmEubmV0LlVSSSNnZXRQYXRoIGdldFBhdGh9KCkuZXF1YWxzKHJlbGF0aXZlTmFtZSk8L3ByZT4KICoKICogPHA+QWxsIG1ldGhvZHMgaW4gdGhpcyBpbnRlcmZhY2UgbWlnaHQgdGhyb3cgYSBTZWN1cml0eUV4Y2VwdGlvbi4KICoKICogPHA+QW4gb2JqZWN0IG9mIHRoaXMgaW50ZXJmYWNlIGlzIG5vdCByZXF1aXJlZCB0byBzdXBwb3J0CiAqIG11bHRpLXRocmVhZGVkIGFjY2VzcywgdGhhdCBpcywgYmUgc3luY2hyb25pemVkLiAgSG93ZXZlciwgaXQgbXVzdAogKiBzdXBwb3J0IGNvbmN1cnJlbnQgYWNjZXNzIHRvIGRpZmZlcmVudCBmaWxlIG9iamVjdHMgY3JlYXRlZCBieSB0aGlzCiAqIG9iamVjdC4KICoKICogPHA+PGVtPkltcGxlbWVudGF0aW9uIG5vdGU6PC9lbT4gYSBjb25zZXF1ZW5jZSBvZiB0aGlzIHJlcXVpcmVtZW50CiAqIGlzIHRoYXQgYSB0cml2aWFsIGltcGxlbWVudGF0aW9uIG9mIG91dHB1dCB0byBhIHtAbGlua3BsYWluCiAqIGphdmEudXRpbC5qYXIuSmFyT3V0cHV0U3RyZWFtfSBpcyBub3QgYSBzdWZmaWNpZW50IGltcGxlbWVudGF0aW9uLgogKiBUaGF0IGlzLCByYXRoZXIgdGhhbiBjcmVhdGluZyBhIEphdmFGaWxlT2JqZWN0IHRoYXQgcmV0dXJucyB0aGUKICogSmFyT3V0cHV0U3RyZWFtIGRpcmVjdGx5LCB0aGUgY29udGVudHMgbXVzdCBiZSBjYWNoZWQgdW50aWwgY2xvc2VkCiAqIGFuZCB0aGVuIHdyaXR0ZW4gdG8gdGhlIEphck91dHB1dFN0cmVhbS4KICoKICogPHA+VW5sZXNzIGV4cGxpY2l0bHkgYWxsb3dlZCwgYWxsIG1ldGhvZHMgaW4gdGhpcyBpbnRlcmZhY2UgbWlnaHQKICogdGhyb3cgYSBOdWxsUG9pbnRlckV4Y2VwdGlvbiBpZiBnaXZlbiBhIHtAY29kZSBudWxsfSBhcmd1bWVudC4KICoKICogQGF1dGhvciBQZXRlciB2b24gZGVyIEFoJmVhY3V0ZTsKICogQGF1dGhvciBKb25hdGhhbiBHaWJib25zCiAqIEBzZWUgSmF2YUZpbGVPYmplY3QKICogQHNlZSBGaWxlT2JqZWN0CiAqIEBzaW5jZSAxLjYKICovCnB1YmxpYyBpbnRlcmZhY2UgSmF2YUZpbGVNYW5hZ2VyIGV4dGVuZHMgQ2xvc2VhYmxlLCBGbHVzaGFibGUsIE9wdGlvbkNoZWNrZXIgewoKICAgIC8qKgogICAgICogSW50ZXJmYWNlIGZvciBsb2NhdGlvbnMgb2YgZmlsZSBvYmplY3RzLiAgVXNlZCBieSBmaWxlIG1hbmFnZXJzCiAgICAgKiB0byBkZXRlcm1pbmUgd2hlcmUgdG8gcGxhY2Ugb3Igc2VhcmNoIGZvciBmaWxlIG9iamVjdHMuCiAgICAgKgogICAgICogPHA+SW5mb3JtYWxseSwgYSB7QGNvZGUgTG9jYXRpb259IGNvcnJlc3BvbmRzIHRvIGEgInNlYXJjaCBwYXRoIiwgc3VjaCBhcyBhIGNsYXNzCiAgICAgKiBwYXRoIG9yIG1vZHVsZSBwYXRoLCBhcyB1c2VkIGJ5IGNvbW1hbmQtbGluZSB0b29scyB0aGF0IHVzZSB0aGUgZGVmYXVsdCBmaWxlIHN5c3RlbS4KICAgICAqCiAgICAgKiA8cD5Tb21lIGxvY2F0aW9ucyBhcmUgdHlwaWNhbGx5IHVzZWQgdG8gaWRlbnRpZnkgYSBwbGFjZSBpbiB3aGljaAogICAgICogYSB0b29sIGNhbiBmaW5kIGZpbGVzIHRvIGJlIHJlYWQ7IG90aGVycyBhcmUgdHlwaWNhbGx5IHVzZWQgdG8gaWRlbnRpZnkKICAgICAqIGEgcGxhY2Ugd2hlcmUgYSB0b29sIGNhbiB3cml0ZSBmaWxlcy4gSWYgYSBsb2NhdGlvbiBpcyB1c2VkIHRvIGlkZW50aWZ5CiAgICAgKiBhIHBsYWNlIGZvciByZWFkaW5nIGZpbGVzLCB0aG9zZSBmaWxlcyBtYXkgYmUgb3JnYW5pemVkIGluIGEgc2ltcGxlCiAgICAgKiA8ZW0+cGFja2FnZS9jbGFzczwvZW0+IGhpZXJhcmNoeTogc3VjaCBsb2NhdGlvbnMgYXJlIGRlc2NyaWJlZCBhcwogICAgICogPHN0cm9uZz5wYWNrYWdlLW9yaWVudGVkPC9zdHJvbmc+LgogICAgICogQWx0ZXJuYXRpdmVseSwgdGhlIGZpbGVzIG1heSBiZSBvcmdhbml6ZWQgaW4gYSA8ZW0+bW9kdWxlL3BhY2thZ2UvY2xhc3M8L2VtPgogICAgICogaGllcmFyY2h5OiBzdWNoIGxvY2F0aW9ucyBhcmUgZGVzY3JpYmVkIGFzIDxzdHJvbmc+bW9kdWxlLW9yaWVudGVkPC9zdHJvbmc+LgogICAgICogSWYgYSBsb2NhdGlvbiBpcyB0eXBpY2FsbHkgdXNlZCB0byBpZGVudGlmeSBhIHBsYWNlIHdoZXJlIGEgdG9vbCBjYW4gd3JpdGUgZmlsZXMsCiAgICAgKiBpdCBpcyB1cCB0byB0aGUgdG9vbCB0aGF0IHdyaXRlcyB0aGUgZmlsZXMgdG8gc3BlY2lmeSBob3cgdGhvc2UgZmlsZXMgd2lsbCBiZQogICAgICogb3JnYW5pemVkLgogICAgICoKICAgICAqIDxwPllvdSBjYW4gYWNjZXNzIHRoZSBjbGFzc2VzIGluIGEgcGFja2FnZS1vcmllbnRlZCBsb2NhdGlvbiB1c2luZyBtZXRob2RzIGxpa2UKICAgICAqIHtAbGluayBKYXZhRmlsZU1hbmFnZXIjZ2V0SmF2YUZpbGVGb3JJbnB1dH0gb3Ige0BsaW5rIEphdmFGaWxlTWFuYWdlciNsaXN0fS4KICAgICAqIEl0IGlzIG5vdCBwb3NzaWJsZSB0byBkaXJlY3RseSBsaXN0IHRoZSBjbGFzc2VzIGluIGEgbW9kdWxlLW9yaWVudGVkCiAgICAgKiBsb2NhdGlvbi4gSW5zdGVhZCwgeW91IGNhbiBnZXQgYSBwYWNrYWdlLW9yaWVudGVkIGxvY2F0aW9uIGZvciBhbnkgc3BlY2lmaWMgbW9kdWxlCiAgICAgKiB1c2luZyBtZXRob2RzIGxpa2Uge0BsaW5rIEphdmFGaWxlTWFuYWdlciNnZXRMb2NhdGlvbkZvck1vZHVsZX0gb3IKICAgICAqIHtAbGluayBKYXZhRmlsZU1hbmFnZXIjbGlzdExvY2F0aW9uc0Zvck1vZHVsZXN9LgogICAgICovCiAgICBpbnRlcmZhY2UgTG9jYXRpb24gewogICAgICAgIC8qKgogICAgICAgICAqIFJldHVybnMgdGhlIG5hbWUgb2YgdGhpcyBsb2NhdGlvbi4KICAgICAgICAgKgogICAgICAgICAqIEByZXR1cm4gYSBuYW1lCiAgICAgICAgICovCiAgICAgICAgU3RyaW5nIGdldE5hbWUoKTsKCiAgICAgICAgLyoqCiAgICAgICAgICogRGV0ZXJtaW5lcyBpZiB0aGlzIGlzIGFuIG91dHB1dCBsb2NhdGlvbi4KICAgICAgICAgKiBBbiBvdXRwdXQgbG9jYXRpb24gaXMgYSBsb2NhdGlvbiB0aGF0IGlzIGNvbnZlbnRpb25hbGx5IHVzZWQgZm9yCiAgICAgICAgICogb3V0cHV0LgogICAgICAgICAqCiAgICAgICAgICogQGFwaU5vdGUgQW4gb3V0cHV0IGxvY2F0aW9uIG1heSBiZSB1c2VkIHRvIHdyaXRlIGZpbGVzIGluIGVpdGhlcgogICAgICAgICAqIGEgcGFja2FnZS1vcmllbnRlZCBvcmdhbml6YXRpb24gb3IgaW4gYSBtb2R1bGUtb3JpZW50ZWQgb3JnYW5pemF0aW9uLgogICAgICAgICAqCiAgICAgICAgICogQHJldHVybiB0cnVlIGlmIHRoaXMgaXMgYW4gb3V0cHV0IGxvY2F0aW9uLCBmYWxzZSBvdGhlcndpc2UKICAgICAgICAgKi8KICAgICAgICBib29sZWFuIGlzT3V0cHV0TG9jYXRpb24oKTsKCiAgICAgICAgLyoqCiAgICAgICAgICogSW5kaWNhdGVzIGlmIHRoaXMgbG9jYXRpb24gaXMgbW9kdWxlLW9yaWVudGVkIGxvY2F0aW9uLCBhbmQgdGhlcmVmb3JlCiAgICAgICAgICogZXhwZWN0ZWQgdG8gY29udGFpbiBjbGFzc2VzIGluIGEgPGVtPm1vZHVsZS9wYWNrYWdlL2NsYXNzPC9lbT4KICAgICAgICAgKiBoaWVyYXJjaHksIGFzIGNvbXBhcmVkIHRvIGEgcGFja2FnZS1vcmllbnRlZCBsb2NhdGlvbiwgd2hpY2gKICAgICAgICAgKiBpcyBleHBlY3RlZCB0byBjb250YWluIGNsYXNzZXMgaW4gYSA8ZW0+cGFja2FnZS9jbGFzczwvZW0+IGhpZXJhcmNoeS4KICAgICAgICAgKiBUaGUgcmVzdWx0IG9mIHRoaXMgbWV0aG9kIGlzIHVuZGVmaW5lZCBpZiB0aGlzIGlzIGFuIG91dHB1dAogICAgICAgICAqIGxvY2F0aW9uLgogICAgICAgICAqCiAgICAgICAgICogQGltcGxOb3RlIFRoaXMgaW1wbGVtZW50YXRpb24gcmV0dXJucyB0cnVlIGlmIHRoZSBuYW1lIGluY2x1ZGVzCiAgICAgICAgICogdGhlIHdvcmQgIk1PRFVMRSIuCiAgICAgICAgICoKICAgICAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhpcyBsb2NhdGlvbiBpcyBleHBlY3RlZCB0byBjb250YWluIG1vZHVsZXMKICAgICAgICAgKiBAc2luY2UgOQogICAgICAgICAqIEBzcGVjIEpQTVMKICAgICAgICAgKi8KICAgICAgICBkZWZhdWx0IGJvb2xlYW4gaXNNb2R1bGVPcmllbnRlZExvY2F0aW9uKCkgewogICAgICAgICAgICByZXR1cm4gZ2V0TmFtZSgpLm1hdGNoZXMoIlxcYk1PRFVMRVxcYiIpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgYSBjbGFzcyBsb2FkZXIgZm9yIGxvYWRpbmcgcGx1Zy1pbnMgZnJvbSB0aGUgZ2l2ZW4KICAgICAqIHBhY2thZ2Utb3JpZW50ZWQgbG9jYXRpb24uCiAgICAgKiBGb3IgZXhhbXBsZSwgdG8gbG9hZCBhbm5vdGF0aW9uIHByb2Nlc3NvcnMsCiAgICAgKiBhIGNvbXBpbGVyIHdpbGwgcmVxdWVzdCBhIGNsYXNzIGxvYWRlciBmb3IgdGhlIHtAbGluawogICAgICogU3RhbmRhcmRMb2NhdGlvbiNBTk5PVEFUSU9OX1BST0NFU1NPUl9QQVRICiAgICAgKiBBTk5PVEFUSU9OX1BST0NFU1NPUl9QQVRIfSBsb2NhdGlvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gbG9jYXRpb24gYSBsb2NhdGlvbgogICAgICogQHJldHVybiBhIGNsYXNzIGxvYWRlciBmb3IgdGhlIGdpdmVuIGxvY2F0aW9uOyBvciB7QGNvZGUgbnVsbH0KICAgICAqIGlmIGxvYWRpbmcgcGx1Zy1pbnMgZnJvbSB0aGUgZ2l2ZW4gbG9jYXRpb24gaXMgZGlzYWJsZWQgb3IgaWYKICAgICAqIHRoZSBsb2NhdGlvbiBpcyBub3Qga25vd24KICAgICAqIEB0aHJvd3MgU2VjdXJpdHlFeGNlcHRpb24gaWYgYSBjbGFzcyBsb2FkZXIgY2FuIG5vdCBiZSBjcmVhdGVkCiAgICAgKiBpbiB0aGUgY3VycmVudCBzZWN1cml0eSBjb250ZXh0CiAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB7QGxpbmsgI2Nsb3NlfSBoYXMgYmVlbiBjYWxsZWQKICAgICAqIGFuZCB0aGlzIGZpbGUgbWFuYWdlciBjYW5ub3QgYmUgcmVvcGVuZWQKICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHRoZSBsb2NhdGlvbiBpcyBhIG1vZHVsZS1vcmllbnRlZCBsb2NhdGlvbgogICAgICovCiAgICBDbGFzc0xvYWRlciBnZXRDbGFzc0xvYWRlcihMb2NhdGlvbiBsb2NhdGlvbik7CgogICAgLyoqCiAgICAgKiBMaXN0cyBhbGwgZmlsZSBvYmplY3RzIG1hdGNoaW5nIHRoZSBnaXZlbiBjcml0ZXJpYSBpbiB0aGUgZ2l2ZW4KICAgICAqIHBhY2thZ2Utb3JpZW50ZWQgbG9jYXRpb24uCiAgICAgKiBMaXN0IGZpbGUgb2JqZWN0cyBpbiAic3VicGFja2FnZXMiIGlmIHJlY3Vyc2UgaXMgdHJ1ZS4KICAgICAqCiAgICAgKiA8cD5Ob3RlOiBldmVuIGlmIHRoZSBnaXZlbiBsb2NhdGlvbiBpcyB1bmtub3duIHRvIHRoaXMgZmlsZQogICAgICogbWFuYWdlciwgaXQgbWF5IG5vdCByZXR1cm4ge0Bjb2RlIG51bGx9LiAgQWxzbywgYW4gdW5rbm93bgogICAgICogbG9jYXRpb24gbWF5IG5vdCBjYXVzZSBhbiBleGNlcHRpb24uCiAgICAgKgogICAgICogQHBhcmFtIGxvY2F0aW9uICAgICBhIGxvY2F0aW9uCiAgICAgKiBAcGFyYW0gcGFja2FnZU5hbWUgIGEgcGFja2FnZSBuYW1lCiAgICAgKiBAcGFyYW0ga2luZHMgICAgICAgIHJldHVybiBvYmplY3RzIG9ubHkgb2YgdGhlc2Uga2luZHMKICAgICAqIEBwYXJhbSByZWN1cnNlICAgICAgaWYgdHJ1ZSBpbmNsdWRlICJzdWJwYWNrYWdlcyIKICAgICAqIEByZXR1cm4gYW4gSXRlcmFibGUgb2YgZmlsZSBvYmplY3RzIG1hdGNoaW5nIHRoZSBnaXZlbiBjcml0ZXJpYQogICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiBhbiBJL08gZXJyb3Igb2NjdXJyZWQsIG9yIGlmIHtAbGluawogICAgICogI2Nsb3NlfSBoYXMgYmVlbiBjYWxsZWQgYW5kIHRoaXMgZmlsZSBtYW5hZ2VyIGNhbm5vdCBiZQogICAgICogcmVvcGVuZWQKICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHRoZSBsb2NhdGlvbiBpcyBhIG1vZHVsZS1vcmllbnRlZCBsb2NhdGlvbgogICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYge0BsaW5rICNjbG9zZX0gaGFzIGJlZW4gY2FsbGVkCiAgICAgKiBhbmQgdGhpcyBmaWxlIG1hbmFnZXIgY2Fubm90IGJlIHJlb3BlbmVkCiAgICAgKi8KICAgIEl0ZXJhYmxlPEphdmFGaWxlT2JqZWN0PiBsaXN0KExvY2F0aW9uIGxvY2F0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHBhY2thZ2VOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU2V0PEtpbmQ+IGtpbmRzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiByZWN1cnNlKQogICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbjsKCiAgICAvKioKICAgICAqIEluZmVycyBhIGJpbmFyeSBuYW1lIG9mIGEgZmlsZSBvYmplY3QgYmFzZWQgb24gYSBwYWNrYWdlLW9yaWVudGVkIGxvY2F0aW9uLgogICAgICogVGhlIGJpbmFyeSBuYW1lIHJldHVybmVkIG1pZ2h0IG5vdCBiZSBhIHZhbGlkIGJpbmFyeSBuYW1lIGFjY29yZGluZyB0bwogICAgICogPGNpdGU+VGhlIEphdmEmdHJhZGU7IExhbmd1YWdlIFNwZWNpZmljYXRpb248L2NpdGU+LgogICAgICoKICAgICAqIEBwYXJhbSBsb2NhdGlvbiBhIGxvY2F0aW9uCiAgICAgKiBAcGFyYW0gZmlsZSBhIGZpbGUgb2JqZWN0CiAgICAgKiBAcmV0dXJuIGEgYmluYXJ5IG5hbWUgb3Ige0Bjb2RlIG51bGx9IHRoZSBmaWxlIG9iamVjdCBpcyBub3QKICAgICAqIGZvdW5kIGluIHRoZSBnaXZlbiBsb2NhdGlvbgogICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgdGhlIGxvY2F0aW9uIGlzIGEgbW9kdWxlLW9yaWVudGVkIGxvY2F0aW9uCiAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB7QGxpbmsgI2Nsb3NlfSBoYXMgYmVlbiBjYWxsZWQKICAgICAqIGFuZCB0aGlzIGZpbGUgbWFuYWdlciBjYW5ub3QgYmUgcmVvcGVuZWQKICAgICAqLwogICAgU3RyaW5nIGluZmVyQmluYXJ5TmFtZShMb2NhdGlvbiBsb2NhdGlvbiwgSmF2YUZpbGVPYmplY3QgZmlsZSk7CgogICAgLyoqCiAgICAgKiBDb21wYXJlcyB0d28gZmlsZSBvYmplY3RzIGFuZCByZXR1cm4gdHJ1ZSBpZiB0aGV5IHJlcHJlc2VudCB0aGUKICAgICAqIHNhbWUgdW5kZXJseWluZyBvYmplY3QuCiAgICAgKgogICAgICogQHBhcmFtIGEgYSBmaWxlIG9iamVjdAogICAgICogQHBhcmFtIGIgYSBmaWxlIG9iamVjdAogICAgICogQHJldHVybiB0cnVlIGlmIHRoZSBnaXZlbiBmaWxlIG9iamVjdHMgcmVwcmVzZW50IHRoZSBzYW1lCiAgICAgKiB1bmRlcmx5aW5nIG9iamVjdAogICAgICoKICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIGVpdGhlciBvZiB0aGUgYXJndW1lbnRzCiAgICAgKiB3ZXJlIGNyZWF0ZWQgd2l0aCBhbm90aGVyIGZpbGUgbWFuYWdlciBhbmQgdGhpcyBmaWxlIG1hbmFnZXIKICAgICAqIGRvZXMgbm90IHN1cHBvcnQgZm9yZWlnbiBmaWxlIG9iamVjdHMKICAgICAqLwogICAgYm9vbGVhbiBpc1NhbWVGaWxlKEZpbGVPYmplY3QgYSwgRmlsZU9iamVjdCBiKTsKCiAgICAvKioKICAgICAqIEhhbmRsZXMgb25lIG9wdGlvbi4gIElmIHtAY29kZSBjdXJyZW50fSBpcyBhbiBvcHRpb24gdG8gdGhpcwogICAgICogZmlsZSBtYW5hZ2VyIGl0IHdpbGwgY29uc3VtZSBhbnkgYXJndW1lbnRzIHRvIHRoYXQgb3B0aW9uIGZyb20KICAgICAqIHtAY29kZSByZW1haW5pbmd9IGFuZCByZXR1cm4gdHJ1ZSwgb3RoZXJ3aXNlIHJldHVybiBmYWxzZS4KICAgICAqCiAgICAgKiBAcGFyYW0gY3VycmVudCBjdXJyZW50IG9wdGlvbgogICAgICogQHBhcmFtIHJlbWFpbmluZyByZW1haW5pbmcgb3B0aW9ucwogICAgICogQHJldHVybiB0cnVlIGlmIHRoaXMgb3B0aW9uIHdhcyBoYW5kbGVkIGJ5IHRoaXMgZmlsZSBtYW5hZ2VyLAogICAgICogZmFsc2Ugb3RoZXJ3aXNlCiAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGlzIG9wdGlvbiB0byB0aGlzIGZpbGUKICAgICAqIG1hbmFnZXIgaXMgdXNlZCBpbmNvcnJlY3RseQogICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYge0BsaW5rICNjbG9zZX0gaGFzIGJlZW4gY2FsbGVkCiAgICAgKiBhbmQgdGhpcyBmaWxlIG1hbmFnZXIgY2Fubm90IGJlIHJlb3BlbmVkCiAgICAgKi8KICAgIGJvb2xlYW4gaGFuZGxlT3B0aW9uKFN0cmluZyBjdXJyZW50LCBJdGVyYXRvcjxTdHJpbmc+IHJlbWFpbmluZyk7CgogICAgLyoqCiAgICAgKiBEZXRlcm1pbmVzIGlmIGEgbG9jYXRpb24gaXMga25vd24gdG8gdGhpcyBmaWxlIG1hbmFnZXIuCiAgICAgKgogICAgICogQHBhcmFtIGxvY2F0aW9uIGEgbG9jYXRpb24KICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgbG9jYXRpb24gaXMga25vd24KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb2NhdGlvbihMb2NhdGlvbiBsb2NhdGlvbik7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEge0BsaW5rcGxhaW4gSmF2YUZpbGVPYmplY3QgZmlsZSBvYmplY3R9IGZvciBpbnB1dAogICAgICogcmVwcmVzZW50aW5nIHRoZSBzcGVjaWZpZWQgY2xhc3Mgb2YgdGhlIHNwZWNpZmllZCBraW5kIGluIHRoZQogICAgICogZ2l2ZW4gcGFja2FnZS1vcmllbnRlZCBsb2NhdGlvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gbG9jYXRpb24gYSBsb2NhdGlvbgogICAgICogQHBhcmFtIGNsYXNzTmFtZSB0aGUgbmFtZSBvZiBhIGNsYXNzCiAgICAgKiBAcGFyYW0ga2luZCB0aGUga2luZCBvZiBmaWxlLCBtdXN0IGJlIG9uZSBvZiB7QGxpbmsKICAgICAqIEphdmFGaWxlT2JqZWN0LktpbmQjU09VUkNFIFNPVVJDRX0gb3Ige0BsaW5rCiAgICAgKiBKYXZhRmlsZU9iamVjdC5LaW5kI0NMQVNTIENMQVNTfQogICAgICogQHJldHVybiBhIGZpbGUgb2JqZWN0LCBtaWdodCByZXR1cm4ge0Bjb2RlIG51bGx9IGlmIHRoZQogICAgICogZmlsZSBkb2VzIG5vdCBleGlzdAogICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgdGhlIGxvY2F0aW9uIGlzIG5vdCBrbm93bgogICAgICogdG8gdGhpcyBmaWxlIG1hbmFnZXIgYW5kIHRoZSBmaWxlIG1hbmFnZXIgZG9lcyBub3Qgc3VwcG9ydAogICAgICogdW5rbm93biBsb2NhdGlvbnMsIG9yIGlmIHRoZSBraW5kIGlzIG5vdCB2YWxpZCwgb3IgaWYgdGhlCiAgICAgKiBsb2NhdGlvbiBpcyBhIG1vZHVsZS1vcmllbnRlZCBsb2NhdGlvbgogICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiBhbiBJL08gZXJyb3Igb2NjdXJyZWQsIG9yIGlmIHtAbGluawogICAgICogI2Nsb3NlfSBoYXMgYmVlbiBjYWxsZWQgYW5kIHRoaXMgZmlsZSBtYW5hZ2VyIGNhbm5vdCBiZQogICAgICogcmVvcGVuZWQKICAgICAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlmIHtAbGluayAjY2xvc2V9IGhhcyBiZWVuIGNhbGxlZAogICAgICogYW5kIHRoaXMgZmlsZSBtYW5hZ2VyIGNhbm5vdCBiZSByZW9wZW5lZAogICAgICovCiAgICBKYXZhRmlsZU9iamVjdCBnZXRKYXZhRmlsZUZvcklucHV0KExvY2F0aW9uIGxvY2F0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgY2xhc3NOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBLaW5kIGtpbmQpCiAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uOwoKICAgIC8qKgogICAgICogUmV0dXJucyBhIHtAbGlua3BsYWluIEphdmFGaWxlT2JqZWN0IGZpbGUgb2JqZWN0fSBmb3Igb3V0cHV0CiAgICAgKiByZXByZXNlbnRpbmcgdGhlIHNwZWNpZmllZCBjbGFzcyBvZiB0aGUgc3BlY2lmaWVkIGtpbmQgaW4gdGhlCiAgICAgKiBnaXZlbiBwYWNrYWdlLW9yaWVudGVkIGxvY2F0aW9uLgogICAgICoKICAgICAqIDxwPk9wdGlvbmFsbHksIHRoaXMgZmlsZSBtYW5hZ2VyIG1pZ2h0IGNvbnNpZGVyIHRoZSBzaWJsaW5nIGFzCiAgICAgKiBhIGhpbnQgZm9yIHdoZXJlIHRvIHBsYWNlIHRoZSBvdXRwdXQuICBUaGUgZXhhY3Qgc2VtYW50aWNzIG9mCiAgICAgKiB0aGlzIGhpbnQgaXMgdW5zcGVjaWZpZWQuICBUaGUgSkRLIGNvbXBpbGVyLCBqYXZhYywgZm9yCiAgICAgKiBleGFtcGxlLCB3aWxsIHBsYWNlIGNsYXNzIGZpbGVzIGluIHRoZSBzYW1lIGRpcmVjdG9yaWVzIGFzCiAgICAgKiBvcmlnaW5hdGluZyBzb3VyY2UgZmlsZXMgdW5sZXNzIGEgY2xhc3MgZmlsZSBvdXRwdXQgZGlyZWN0b3J5CiAgICAgKiBpcyBwcm92aWRlZC4gIFRvIGZhY2lsaXRhdGUgdGhpcyBiZWhhdmlvciwgamF2YWMgbWlnaHQgcHJvdmlkZQogICAgICogdGhlIG9yaWdpbmF0aW5nIHNvdXJjZSBmaWxlIGFzIHNpYmxpbmcgd2hlbiBjYWxsaW5nIHRoaXMKICAgICAqIG1ldGhvZC4KICAgICAqCiAgICAgKiBAcGFyYW0gbG9jYXRpb24gYSBwYWNrYWdlLW9yaWVudGVkIGxvY2F0aW9uCiAgICAgKiBAcGFyYW0gY2xhc3NOYW1lIHRoZSBuYW1lIG9mIGEgY2xhc3MKICAgICAqIEBwYXJhbSBraW5kIHRoZSBraW5kIG9mIGZpbGUsIG11c3QgYmUgb25lIG9mIHtAbGluawogICAgICogSmF2YUZpbGVPYmplY3QuS2luZCNTT1VSQ0UgU09VUkNFfSBvciB7QGxpbmsKICAgICAqIEphdmFGaWxlT2JqZWN0LktpbmQjQ0xBU1MgQ0xBU1N9CiAgICAgKiBAcGFyYW0gc2libGluZyBhIGZpbGUgb2JqZWN0IHRvIGJlIHVzZWQgYXMgaGludCBmb3IgcGxhY2VtZW50OwogICAgICogbWlnaHQgYmUge0Bjb2RlIG51bGx9CiAgICAgKiBAcmV0dXJuIGEgZmlsZSBvYmplY3QgZm9yIG91dHB1dAogICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgc2libGluZyBpcyBub3Qga25vd24gdG8KICAgICAqIHRoaXMgZmlsZSBtYW5hZ2VyLCBvciBpZiB0aGUgbG9jYXRpb24gaXMgbm90IGtub3duIHRvIHRoaXMgZmlsZQogICAgICogbWFuYWdlciBhbmQgdGhlIGZpbGUgbWFuYWdlciBkb2VzIG5vdCBzdXBwb3J0IHVua25vd24KICAgICAqIGxvY2F0aW9ucywgb3IgaWYgdGhlIGtpbmQgaXMgbm90IHZhbGlkLCBvciBpZiB0aGUgbG9jYXRpb24gaXMKICAgICAqIG5vdCBhbiBvdXRwdXQgbG9jYXRpb24KICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgYW4gSS9PIGVycm9yIG9jY3VycmVkLCBvciBpZiB7QGxpbmsKICAgICAqICNjbG9zZX0gaGFzIGJlZW4gY2FsbGVkIGFuZCB0aGlzIGZpbGUgbWFuYWdlciBjYW5ub3QgYmUKICAgICAqIHJlb3BlbmVkCiAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiB7QGxpbmsgI2Nsb3NlfSBoYXMgYmVlbiBjYWxsZWQKICAgICAqIGFuZCB0aGlzIGZpbGUgbWFuYWdlciBjYW5ub3QgYmUgcmVvcGVuZWQKICAgICAqLwogICAgSmF2YUZpbGVPYmplY3QgZ2V0SmF2YUZpbGVGb3JPdXRwdXQoTG9jYXRpb24gbG9jYXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgY2xhc3NOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgS2luZCBraW5kLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmlsZU9iamVjdCBzaWJsaW5nKQogICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbjsKCiAgICAvKioKICAgICAqIFJldHVybnMgYSB7QGxpbmtwbGFpbiBGaWxlT2JqZWN0IGZpbGUgb2JqZWN0fSBmb3IgaW5wdXQKICAgICAqIHJlcHJlc2VudGluZyB0aGUgc3BlY2lmaWVkIDxhIGhyZWY9IkphdmFGaWxlTWFuYWdlci5odG1sI3JlbGF0aXZlX25hbWUiPnJlbGF0aXZlCiAgICAgKiBuYW1lPC9hPiBpbiB0aGUgc3BlY2lmaWVkIHBhY2thZ2UgaW4gdGhlIGdpdmVuIHBhY2thZ2Utb3JpZW50ZWQgbG9jYXRpb24uCiAgICAgKgogICAgICogPHA+SWYgdGhlIHJldHVybmVkIG9iamVjdCByZXByZXNlbnRzIGEge0BsaW5rcGxhaW4KICAgICAqIEphdmFGaWxlT2JqZWN0LktpbmQjU09VUkNFIHNvdXJjZX0gb3Ige0BsaW5rcGxhaW4KICAgICAqIEphdmFGaWxlT2JqZWN0LktpbmQjQ0xBU1MgY2xhc3N9IGZpbGUsIGl0IG11c3QgYmUgYW4gaW5zdGFuY2UKICAgICAqIG9mIHtAbGluayBKYXZhRmlsZU9iamVjdH0uCiAgICAgKgogICAgICogPHA+SW5mb3JtYWxseSwgdGhlIGZpbGUgb2JqZWN0IHJldHVybmVkIGJ5IHRoaXMgbWV0aG9kIGlzCiAgICAgKiBsb2NhdGVkIGluIHRoZSBjb25jYXRlbmF0aW9uIG9mIHRoZSBsb2NhdGlvbiwgcGFja2FnZSBuYW1lLCBhbmQKICAgICAqIHJlbGF0aXZlIG5hbWUuICBGb3IgZXhhbXBsZSwgdG8gbG9jYXRlIHRoZSBwcm9wZXJ0aWVzIGZpbGUKICAgICAqICJyZXNvdXJjZXMvY29tcGlsZXIucHJvcGVydGllcyIgaW4gdGhlIHBhY2thZ2UKICAgICAqICJjb20uc3VuLnRvb2xzLmphdmFjIiBpbiB0aGUge0BsaW5rcGxhaW4KICAgICAqIFN0YW5kYXJkTG9jYXRpb24jU09VUkNFX1BBVEggU09VUkNFX1BBVEh9IGxvY2F0aW9uLCB0aGlzIG1ldGhvZAogICAgICogbWlnaHQgYmUgY2FsbGVkIGxpa2Ugc286CiAgICAgKgogICAgICogPHByZT5nZXRGaWxlRm9ySW5wdXQoU09VUkNFX1BBVEgsICJjb20uc3VuLnRvb2xzLmphdmFjIiwgInJlc291cmNlcy9jb21waWxlci5wcm9wZXJ0aWVzIik7PC9wcmU+CiAgICAgKgogICAgICogPHA+SWYgdGhlIGNhbGwgd2FzIGV4ZWN1dGVkIG9uIFdpbmRvd3MsIHdpdGggU09VUkNFX1BBVEggc2V0IHRvCiAgICAgKiA8Y29kZT4iQzpcRG9jdW1lbnRzJm5ic3A7YW5kJm5ic3A7U2V0dGluZ3NcVW5jbGVCb2Jcc3JjXHNoYXJlXGNsYXNzZXMiPC9jb2RlPiwKICAgICAqIGEgdmFsaWQgcmVzdWx0IHdvdWxkIGJlIGEgZmlsZSBvYmplY3QgcmVwcmVzZW50aW5nIHRoZSBmaWxlCiAgICAgKiA8Y29kZT4iQzpcRG9jdW1lbnRzJm5ic3A7YW5kJm5ic3A7U2V0dGluZ3NcVW5jbGVCb2Jcc3JjXHNoYXJlXGNsYXNzZXNcY29tXHN1blx0b29sc1xqYXZhY1xyZXNvdXJjZXNcY29tcGlsZXIucHJvcGVydGllcyI8L2NvZGU+LgogICAgICoKICAgICAqIEBwYXJhbSBsb2NhdGlvbiBhIHBhY2thZ2Utb3JpZW50ZWQgbG9jYXRpb24KICAgICAqIEBwYXJhbSBwYWNrYWdlTmFtZSBhIHBhY2thZ2UgbmFtZQogICAgICogQHBhcmFtIHJlbGF0aXZlTmFtZSBhIHJlbGF0aXZlIG5hbWUKICAgICAqIEByZXR1cm4gYSBmaWxlIG9iamVjdCwgbWlnaHQgcmV0dXJuIHtAY29kZSBudWxsfSBpZiB0aGUgZmlsZQogICAgICogZG9lcyBub3QgZXhpc3QKICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHRoZSBsb2NhdGlvbiBpcyBub3Qga25vd24KICAgICAqIHRvIHRoaXMgZmlsZSBtYW5hZ2VyIGFuZCB0aGUgZmlsZSBtYW5hZ2VyIGRvZXMgbm90IHN1cHBvcnQKICAgICAqIHVua25vd24gbG9jYXRpb25zLCBvciBpZiB7QGNvZGUgcmVsYXRpdmVOYW1lfSBpcyBub3QgdmFsaWQsCiAgICAgKiBvciBpZiB0aGUgbG9jYXRpb24gaXMgYSBtb2R1bGUtb3JpZW50ZWQgbG9jYXRpb24KICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgYW4gSS9PIGVycm9yIG9jY3VycmVkLCBvciBpZiB7QGxpbmsKICAgICAqICNjbG9zZX0gaGFzIGJlZW4gY2FsbGVkIGFuZCB0aGlzIGZpbGUgbWFuYWdlciBjYW5ub3QgYmUKICAgICAqIHJlb3BlbmVkCiAgICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB7QGxpbmsgI2Nsb3NlfSBoYXMgYmVlbiBjYWxsZWQKICAgICAqIGFuZCB0aGlzIGZpbGUgbWFuYWdlciBjYW5ub3QgYmUgcmVvcGVuZWQKICAgICAqLwogICAgRmlsZU9iamVjdCBnZXRGaWxlRm9ySW5wdXQoTG9jYXRpb24gbG9jYXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcGFja2FnZU5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcmVsYXRpdmVOYW1lKQogICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbjsKCiAgICAvKioKICAgICAqIFJldHVybnMgYSB7QGxpbmtwbGFpbiBGaWxlT2JqZWN0IGZpbGUgb2JqZWN0fSBmb3Igb3V0cHV0CiAgICAgKiByZXByZXNlbnRpbmcgdGhlIHNwZWNpZmllZCA8YSBocmVmPSJKYXZhRmlsZU1hbmFnZXIuaHRtbCNyZWxhdGl2ZV9uYW1lIj5yZWxhdGl2ZQogICAgICogbmFtZTwvYT4gaW4gdGhlIHNwZWNpZmllZCBwYWNrYWdlIGluIHRoZSBnaXZlbiBsb2NhdGlvbi4KICAgICAqCiAgICAgKiA8cD5PcHRpb25hbGx5LCB0aGlzIGZpbGUgbWFuYWdlciBtaWdodCBjb25zaWRlciB0aGUgc2libGluZyBhcwogICAgICogYSBoaW50IGZvciB3aGVyZSB0byBwbGFjZSB0aGUgb3V0cHV0LiAgVGhlIGV4YWN0IHNlbWFudGljcyBvZgogICAgICogdGhpcyBoaW50IGlzIHVuc3BlY2lmaWVkLiAgVGhlIEpESyBjb21waWxlciwgamF2YWMsIGZvcgogICAgICogZXhhbXBsZSwgd2lsbCBwbGFjZSBjbGFzcyBmaWxlcyBpbiB0aGUgc2FtZSBkaXJlY3RvcmllcyBhcwogICAgICogb3JpZ2luYXRpbmcgc291cmNlIGZpbGVzIHVubGVzcyBhIGNsYXNzIGZpbGUgb3V0cHV0IGRpcmVjdG9yeQogICAgICogaXMgcHJvdmlkZWQuICBUbyBmYWNpbGl0YXRlIHRoaXMgYmVoYXZpb3IsIGphdmFjIG1pZ2h0IHByb3ZpZGUKICAgICAqIHRoZSBvcmlnaW5hdGluZyBzb3VyY2UgZmlsZSBhcyBzaWJsaW5nIHdoZW4gY2FsbGluZyB0aGlzCiAgICAgKiBtZXRob2QuCiAgICAgKgogICAgICogPHA+SWYgdGhlIHJldHVybmVkIG9iamVjdCByZXByZXNlbnRzIGEge0BsaW5rcGxhaW4KICAgICAqIEphdmFGaWxlT2JqZWN0LktpbmQjU09VUkNFIHNvdXJjZX0gb3Ige0BsaW5rcGxhaW4KICAgICAqIEphdmFGaWxlT2JqZWN0LktpbmQjQ0xBU1MgY2xhc3N9IGZpbGUsIGl0IG11c3QgYmUgYW4gaW5zdGFuY2UKICAgICAqIG9mIHtAbGluayBKYXZhRmlsZU9iamVjdH0uCiAgICAgKgogICAgICogPHA+SW5mb3JtYWxseSwgdGhlIGZpbGUgb2JqZWN0IHJldHVybmVkIGJ5IHRoaXMgbWV0aG9kIGlzCiAgICAgKiBsb2NhdGVkIGluIHRoZSBjb25jYXRlbmF0aW9uIG9mIHRoZSBsb2NhdGlvbiwgcGFja2FnZSBuYW1lLCBhbmQKICAgICAqIHJlbGF0aXZlIG5hbWUgb3IgbmV4dCB0byB0aGUgc2libGluZyBhcmd1bWVudC4gIFNlZSB7QGxpbmsKICAgICAqICNnZXRGaWxlRm9ySW5wdXQgZ2V0RmlsZUZvcklucHV0fSBmb3IgYW4gZXhhbXBsZS4KICAgICAqCiAgICAgKiBAcGFyYW0gbG9jYXRpb24gYW4gb3V0cHV0IGxvY2F0aW9uCiAgICAgKiBAcGFyYW0gcGFja2FnZU5hbWUgYSBwYWNrYWdlIG5hbWUKICAgICAqIEBwYXJhbSByZWxhdGl2ZU5hbWUgYSByZWxhdGl2ZSBuYW1lCiAgICAgKiBAcGFyYW0gc2libGluZyBhIGZpbGUgb2JqZWN0IHRvIGJlIHVzZWQgYXMgaGludCBmb3IgcGxhY2VtZW50OwogICAgICogbWlnaHQgYmUge0Bjb2RlIG51bGx9CiAgICAgKiBAcmV0dXJuIGEgZmlsZSBvYmplY3QKICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHNpYmxpbmcgaXMgbm90IGtub3duIHRvCiAgICAgKiB0aGlzIGZpbGUgbWFuYWdlciwgb3IgaWYgdGhlIGxvY2F0aW9uIGlzIG5vdCBrbm93biB0byB0aGlzIGZpbGUKICAgICAqIG1hbmFnZXIgYW5kIHRoZSBmaWxlIG1hbmFnZXIgZG9lcyBub3Qgc3VwcG9ydCB1bmtub3duCiAgICAgKiBsb2NhdGlvbnMsIG9yIGlmIHtAY29kZSByZWxhdGl2ZU5hbWV9IGlzIG5vdCB2YWxpZCwKICAgICAqIG9yIGlmIHRoZSBsb2NhdGlvbiBpcyBub3QgYW4gb3V0cHV0IGxvY2F0aW9uCiAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIGFuIEkvTyBlcnJvciBvY2N1cnJlZCwgb3IgaWYge0BsaW5rCiAgICAgKiAjY2xvc2V9IGhhcyBiZWVuIGNhbGxlZCBhbmQgdGhpcyBmaWxlIG1hbmFnZXIgY2Fubm90IGJlCiAgICAgKiByZW9wZW5lZAogICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYge0BsaW5rICNjbG9zZX0gaGFzIGJlZW4gY2FsbGVkCiAgICAgKiBhbmQgdGhpcyBmaWxlIG1hbmFnZXIgY2Fubm90IGJlIHJlb3BlbmVkCiAgICAgKi8KICAgIEZpbGVPYmplY3QgZ2V0RmlsZUZvck91dHB1dChMb2NhdGlvbiBsb2NhdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcGFja2FnZU5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHJlbGF0aXZlTmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGaWxlT2JqZWN0IHNpYmxpbmcpCiAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uOwoKICAgIC8qKgogICAgICogRmx1c2hlcyBhbnkgcmVzb3VyY2VzIG9wZW5lZCBmb3Igb3V0cHV0IGJ5IHRoaXMgZmlsZSBtYW5hZ2VyCiAgICAgKiBkaXJlY3RseSBvciBpbmRpcmVjdGx5LiAgRmx1c2hpbmcgYSBjbG9zZWQgZmlsZSBtYW5hZ2VyIGhhcyBubwogICAgICogZWZmZWN0LgogICAgICoKICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgYW4gSS9PIGVycm9yIG9jY3VycmVkCiAgICAgKiBAc2VlICNjbG9zZQogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHZvaWQgZmx1c2goKSB0aHJvd3MgSU9FeGNlcHRpb247CgogICAgLyoqCiAgICAgKiBSZWxlYXNlcyBhbnkgcmVzb3VyY2VzIG9wZW5lZCBieSB0aGlzIGZpbGUgbWFuYWdlciBkaXJlY3RseSBvcgogICAgICogaW5kaXJlY3RseS4gIFRoaXMgbWlnaHQgcmVuZGVyIHRoaXMgZmlsZSBtYW5hZ2VyIHVzZWxlc3MgYW5kCiAgICAgKiB0aGUgZWZmZWN0IG9mIHN1YnNlcXVlbnQgY2FsbHMgdG8gbWV0aG9kcyBvbiB0aGlzIG9iamVjdCBvciBhbnkKICAgICAqIG9iamVjdHMgb2J0YWluZWQgdGhyb3VnaCB0aGlzIG9iamVjdCBpcyB1bmRlZmluZWQgdW5sZXNzCiAgICAgKiBleHBsaWNpdGx5IGFsbG93ZWQuICBIb3dldmVyLCBjbG9zaW5nIGEgZmlsZSBtYW5hZ2VyIHdoaWNoIGhhcwogICAgICogYWxyZWFkeSBiZWVuIGNsb3NlZCBoYXMgbm8gZWZmZWN0LgogICAgICoKICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgYW4gSS9PIGVycm9yIG9jY3VycmVkCiAgICAgKiBAc2VlICNmbHVzaAogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb247CgogICAgLyoqCiAgICAgKiBHZXRzIGEgbG9jYXRpb24gZm9yIGEgbmFtZWQgbW9kdWxlIHdpdGhpbiBhIGxvY2F0aW9uLCB3aGljaCBtYXkgYmUgZWl0aGVyCiAgICAgKiBhIG1vZHVsZS1vcmllbnRlZCBsb2NhdGlvbiBvciBhbiBvdXRwdXQgbG9jYXRpb24uCiAgICAgKiBUaGUgcmVzdWx0IHdpbGwgYmUgYW4gb3V0cHV0IGxvY2F0aW9uIGlmIHRoZSBnaXZlbiBsb2NhdGlvbiBpcwogICAgICogYW4gb3V0cHV0IGxvY2F0aW9uLCBvciBpdCB3aWxsIGJlIGEgcGFja2FnZS1vcmllbnRlZCBsb2NhdGlvbi4KICAgICAqCiAgICAgKiBAaW1wbFNwZWMgVGhpcyBpbXBsZW1lbnRhdGlvbiB0aHJvd3Mge0Bjb2RlIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9ufS4KICAgICAqCiAgICAgKiBAcGFyYW0gbG9jYXRpb24gdGhlIG1vZHVsZS1vcmllbnRlZCBsb2NhdGlvbgogICAgICogQHBhcmFtIG1vZHVsZU5hbWUgdGhlIG5hbWUgb2YgdGhlIG1vZHVsZSB0byBiZSBmb3VuZAogICAgICogQHJldHVybiB0aGUgbG9jYXRpb24gZm9yIHRoZSBuYW1lZCBtb2R1bGUKICAgICAqCiAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIGFuIEkvTyBlcnJvciBvY2N1cnJlZAogICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBpZiB0aGlzIG9wZXJhdGlvbiBpZiBub3Qgc3VwcG9ydGVkIGJ5IHRoaXMgZmlsZSBtYW5hZ2VyCiAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgbG9jYXRpb24gaXMgbmVpdGhlciBhbiBvdXRwdXQgbG9jYXRpb24gbm9yIGEKICAgICAqIG1vZHVsZS1vcmllbnRlZCBsb2NhdGlvbgogICAgICogQHNpbmNlIDkKICAgICAqIEBzcGVjIEpQTVMKICAgICAqLyAvLyBUT0RPOiBkZXNjcmliZSBmYWlsdXJlIG1vZGVzCiAgICBkZWZhdWx0IExvY2F0aW9uIGdldExvY2F0aW9uRm9yTW9kdWxlKExvY2F0aW9uIGxvY2F0aW9uLCBTdHJpbmcgbW9kdWxlTmFtZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKICAgIH0KCiAgICAvKioKICAgICAqIEdldHMgYSBsb2NhdGlvbiBmb3IgdGhlIG1vZHVsZSBjb250YWluaW5nIGEgc3BlY2lmaWMgZmlsZQogICAgICogdG8gYmUgZm91bmQgd2l0aGluIGEgbG9jYXRpb24sIHdoaWNoIG1heSBiZSBlaXRoZXIKICAgICAqIGEgbW9kdWxlLW9yaWVudGVkIGxvY2F0aW9uIG9yIGFuIG91dHB1dCBsb2NhdGlvbi4KICAgICAqIFRoZSByZXN1bHQgd2lsbCBiZSBhbiBvdXRwdXQgbG9jYXRpb24gaWYgdGhlIGdpdmVuIGxvY2F0aW9uIGlzCiAgICAgKiBhbiBvdXRwdXQgbG9jYXRpb24sIG9yIGl0IHdpbGwgYmUgYSBwYWNrYWdlLW9yaWVudGVkIGxvY2F0aW9uLgogICAgICoKICAgICAqIEBpbXBsU3BlYyBUaGlzIGltcGxlbWVudGF0aW9uIHRocm93cyB7QGNvZGUgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb259LgogICAgICoKICAgICAqIEBwYXJhbSBsb2NhdGlvbiB0aGUgbW9kdWxlLW9yaWVudGVkIGxvY2F0aW9uCiAgICAgKiBAcGFyYW0gZm8gdGhlIGZpbGUKICAgICAqIEByZXR1cm4gdGhlIG1vZHVsZSBjb250YWluaW5nIHRoZSBmaWxlCiAgICAgKgogICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiBhbiBJL08gZXJyb3Igb2NjdXJyZWQKICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gaWYgdGhpcyBvcGVyYXRpb24gaWYgbm90IHN1cHBvcnRlZCBieSB0aGlzIGZpbGUgbWFuYWdlcgogICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgdGhlIGxvY2F0aW9uIGlzIG5laXRoZXIgYW4gb3V0cHV0IGxvY2F0aW9uIG5vciBhCiAgICAgKiBtb2R1bGUtb3JpZW50ZWQgbG9jYXRpb24KICAgICAqIEBzaW5jZSA5CiAgICAgKiBAc3BlYyBKUE1TCiAgICAgKi8KICAgIGRlZmF1bHQgTG9jYXRpb24gZ2V0TG9jYXRpb25Gb3JNb2R1bGUoTG9jYXRpb24gbG9jYXRpb24sIEphdmFGaWxlT2JqZWN0IGZvKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOwogICAgfQoKICAgIC8qKgogICAgICogR2V0IGEgc2VydmljZSBsb2FkZXIgZm9yIGEgc3BlY2lmaWMgc2VydmljZSBjbGFzcyBmcm9tIGEgZ2l2ZW4gbG9jYXRpb24uCiAgICAgKgogICAgICogSWYgdGhlIGxvY2F0aW9uIGlzIGEgbW9kdWxlLW9yaWVudGVkIGxvY2F0aW9uLCB0aGUgc2VydmljZSBsb2FkZXIgd2lsbCB1c2UgdGhlCiAgICAgKiBzZXJ2aWNlIGRlY2xhcmF0aW9ucyBpbiB0aGUgbW9kdWxlcyBmb3VuZCBpbiB0aGF0IGxvY2F0aW9uLiBPdGhlcndpc2UsIGEgc2VydmljZSBsb2FkZXIKICAgICAqIGlzIGNyZWF0ZWQgdXNpbmcgdGhlIHBhY2thZ2Utb3JpZW50ZWQgbG9jYXRpb24sIGluIHdoaWNoIGNhc2UsIHRoZSBzZXJ2aWNlcyBhcmUKICAgICAqIGRldGVybWluZWQgdXNpbmcgdGhlIHByb3ZpZGVyLWNvbmZpZ3VyYXRpb24gZmlsZXMgaW4ge0Bjb2RlIE1FVEEtSU5GL3NlcnZpY2VzfS4KICAgICAqCiAgICAgKiBAaW1wbFNwZWMgVGhpcyBpbXBsZW1lbnRhdGlvbiB0aHJvd3Mge0Bjb2RlIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9ufS4KICAgICAqCiAgICAgKiBAcGFyYW0gbG9jYXRpb24gdGhlIG1vZHVsZS1vcmllbnRlZCBsb2NhdGlvbgogICAgICogQHBhcmFtIHNlcnZpY2UgIHRoZSB7QGNvZGUgQ2xhc3N9IG9iamVjdCBvZiB0aGUgc2VydmljZSBjbGFzcwogICAgICogQHBhcmFtIDxTPiB0aGUgc2VydmljZSBjbGFzcwogICAgICogQHJldHVybiBhIHNlcnZpY2UgbG9hZGVyIGZvciB0aGUgZ2l2ZW4gc2VydmljZSBjbGFzcwogICAgICoKICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgYW4gSS9PIGVycm9yIG9jY3VycmVkCiAgICAgKiBAdGhyb3dzIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uIGlmIHRoaXMgb3BlcmF0aW9uIGlmIG5vdCBzdXBwb3J0ZWQgYnkgdGhpcyBmaWxlIG1hbmFnZXIKICAgICAqIEBzaW5jZSA5CiAgICAgKiBAc3BlYyBKUE1TCiAgICAgKi8gLy8gVE9ETzogZGVzY3JpYmUgZmFpbHVyZSBtb2RlcwogICAgZGVmYXVsdCA8Uz4gU2VydmljZUxvYWRlcjxTPiBnZXRTZXJ2aWNlTG9hZGVyKExvY2F0aW9uIGxvY2F0aW9uLCBDbGFzczxTPiBzZXJ2aWNlKSB0aHJvd3MgIElPRXhjZXB0aW9uIHsKICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTsKICAgIH0KCiAgICAvKioKICAgICAqIEluZmVyIHRoZSBuYW1lIG9mIHRoZSBtb2R1bGUgZnJvbSBpdHMgbG9jYXRpb24sIGFzIHJldHVybmVkIGJ5CiAgICAgKiB7QGNvZGUgZ2V0TG9jYXRpb25Gb3JNb2R1bGV9IG9yIHtAY29kZSBsaXN0TW9kdWxlTG9jYXRpb25zfS4KICAgICAqCiAgICAgKiBAaW1wbFNwZWMgVGhpcyBpbXBsZW1lbnRhdGlvbiB0aHJvd3Mge0Bjb2RlIFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9ufS4KICAgICAqCiAgICAgKiBAcGFyYW0gbG9jYXRpb24gYSBwYWNrYWdlLW9yaWVudGVkIGxvY2F0aW9uIHJlcHJlc2VudGluZyBhIG1vZHVsZQogICAgICogQHJldHVybiB0aGUgbmFtZSBvZiB0aGUgbW9kdWxlCiAgICAgKgogICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiBhbiBJL08gZXJyb3Igb2NjdXJyZWQKICAgICAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24gaWYgdGhpcyBvcGVyYXRpb24gaWYgbm90IHN1cHBvcnRlZCBieSB0aGlzIGZpbGUgbWFuYWdlcgogICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgdGhlIGxvY2F0aW9uIGlzIG5vdCBvbmUga25vd24gdG8gdGhpcyBmaWxlIG1hbmFnZXIKICAgICAqIEBzaW5jZSA5CiAgICAgKiBAc3BlYyBKUE1TCiAgICAgKi8gLy8gVE9ETzogZGVzY3JpYmUgZmFpbHVyZSBtb2RlcwogICAgZGVmYXVsdCBTdHJpbmcgaW5mZXJNb2R1bGVOYW1lKExvY2F0aW9uIGxvY2F0aW9uKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOwogICAgfQoKICAgIC8qKgogICAgICogTGlzdHMgdGhlIGxvY2F0aW9ucyBmb3IgYWxsIHRoZSBtb2R1bGVzIGluIGEgbW9kdWxlLW9yaWVudGVkIGxvY2F0aW9uIG9yIGFuIG91dHB1dCBsb2NhdGlvbi4KICAgICAqIFRoZSBsb2NhdGlvbnMgdGhhdCBhcmUgcmV0dXJuZWQgd2lsbCBiZSBvdXRwdXQgbG9jYXRpb25zIGlmIHRoZSBnaXZlbiBsb2NhdGlvbiBpcyBhbiBvdXRwdXQsCiAgICAgKiBvciBpdCB3aWxsIGJlIGEgcGFja2FnZS1vcmllbnRlZCBsb2NhdGlvbnMuCiAgICAgKgogICAgICogQGltcGxTcGVjIFRoaXMgaW1wbGVtZW50YXRpb24gdGhyb3dzIHtAY29kZSBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbn0uCiAgICAgKgogICAgICogQHBhcmFtIGxvY2F0aW9uICB0aGUgbW9kdWxlLW9yaWVudGVkIGxvY2F0aW9uIGZvciB3aGljaCB0byBsaXN0IHRoZSBtb2R1bGVzCiAgICAgKiBAcmV0dXJuICBhIHNlcmllcyBvZiBzZXRzIG9mIGxvY2F0aW9ucyBjb250YWluaW5nIG1vZHVsZXMKICAgICAqCiAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIGFuIEkvTyBlcnJvciBvY2N1cnJlZAogICAgICogQHRocm93cyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbiBpZiB0aGlzIG9wZXJhdGlvbiBpZiBub3Qgc3VwcG9ydGVkIGJ5IHRoaXMgZmlsZSBtYW5hZ2VyCiAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgbG9jYXRpb24gaXMgbm90IGEgbW9kdWxlLW9yaWVudGVkIGxvY2F0aW9uCiAgICAgKiBAc2luY2UgOQogICAgICogQHNwZWMgSlBNUwogICAgICovIC8vIFRPRE86IGRlc2NyaWJlIGZhaWx1cmUgbW9kZXMKICAgIGRlZmF1bHQgSXRlcmFibGU8U2V0PExvY2F0aW9uPj4gbGlzdExvY2F0aW9uc0Zvck1vZHVsZXMoTG9jYXRpb24gbG9jYXRpb24pIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7CiAgICB9Cgp9ClBLAwQKAAAIAAAGO6lKXxaJi6odAACqHQAAHQAAAGphdmF4L3Rvb2xzL1Rvb2xQcm92aWRlci5qYXZhLyoKICogQ29weXJpZ2h0IChjKSAyMDA1LCAyMDE2LCBPcmFjbGUgYW5kL29yIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBETyBOT1QgQUxURVIgT1IgUkVNT1ZFIENPUFlSSUdIVCBOT1RJQ0VTIE9SIFRISVMgRklMRSBIRUFERVIuCiAqCiAqIFRoaXMgY29kZSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIG9ubHksIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgT3JhY2xlIGRlc2lnbmF0ZXMgdGhpcwogKiBwYXJ0aWN1bGFyIGZpbGUgYXMgc3ViamVjdCB0byB0aGUgIkNsYXNzcGF0aCIgZXhjZXB0aW9uIGFzIHByb3ZpZGVkCiAqIGJ5IE9yYWNsZSBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQgYWNjb21wYW5pZWQgdGhpcyBjb2RlLgogKgogKiBUaGlzIGNvZGUgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQKICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiB2ZXJzaW9uIDIgZm9yIG1vcmUgZGV0YWlscyAoYSBjb3B5IGlzIGluY2x1ZGVkIGluIHRoZSBMSUNFTlNFIGZpbGUgdGhhdAogKiBhY2NvbXBhbmllZCB0aGlzIGNvZGUpLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uCiAqIDIgYWxvbmcgd2l0aCB0aGlzIHdvcms7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwKICogSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLgogKgogKiBQbGVhc2UgY29udGFjdCBPcmFjbGUsIDUwMCBPcmFjbGUgUGFya3dheSwgUmVkd29vZCBTaG9yZXMsIENBIDk0MDY1IFVTQQogKiBvciB2aXNpdCB3d3cub3JhY2xlLmNvbSBpZiB5b3UgbmVlZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGhhdmUgYW55CiAqIHF1ZXN0aW9ucy4KICovCgpwYWNrYWdlIGphdmF4LnRvb2xzOwoKaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0Lkludm9jYXRpb25UYXJnZXRFeGNlcHRpb247CmltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5NZXRob2Q7CmltcG9ydCBqYXZhLnNlY3VyaXR5LkFjY2Vzc0NvbnRyb2xsZXI7CmltcG9ydCBqYXZhLnNlY3VyaXR5LlByaXZpbGVnZWRBY3Rpb247CmltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CmltcG9ydCBqYXZhLnV0aWwuU2VydmljZUNvbmZpZ3VyYXRpb25FcnJvcjsKaW1wb3J0IGphdmEudXRpbC5TZXJ2aWNlTG9hZGVyOwoKLyoqCiAqIFByb3ZpZGVzIG1ldGhvZHMgZm9yIGxvY2F0aW5nIHRvb2wgcHJvdmlkZXJzLCBmb3IgZXhhbXBsZSwKICogcHJvdmlkZXJzIG9mIGNvbXBpbGVycy4gIFRoaXMgY2xhc3MgY29tcGxlbWVudHMgdGhlCiAqIGZ1bmN0aW9uYWxpdHkgb2Yge0BsaW5rIGphdmEudXRpbC5TZXJ2aWNlTG9hZGVyfS4KICoKICogQGF1dGhvciBQZXRlciB2b24gZGVyIEFoJmVhY3V0ZTsKICogQHNpbmNlIDEuNgogKi8KcHVibGljIGNsYXNzIFRvb2xQcm92aWRlciB7CgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIHN5c3RlbUphdmFDb21waWxlck1vZHVsZSA9ICJqZGsuY29tcGlsZXIiOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIHN5c3RlbUphdmFDb21waWxlck5hbWUgICA9ICJjb20uc3VuLnRvb2xzLmphdmFjLmFwaS5KYXZhY1Rvb2wiOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgSmF2YSZ0cmFkZTsgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2UgY29tcGlsZXIgcHJvdmlkZWQKICAgICAqIHdpdGggdGhpcyBwbGF0Zm9ybS4KICAgICAqIDxwPlRoZSBmaWxlIG1hbmFnZXIgcmV0dXJuZWQgYnkgY2FsbGluZwogICAgICoge0BsaW5rIEphdmFDb21waWxlciNnZXRTdGFuZGFyZEZpbGVNYW5hZ2VyIGdldFN0YW5kYXJkRmlsZU1hbmFnZXJ9CiAgICAgKiBvbiB0aGlzIGNvbXBpbGVyIHN1cHBvcnRzIHBhdGhzIHByb3ZpZGVkIGJ5IGFueQogICAgICoge0BsaW5rcGxhaW4gamF2YS5uaW8uZmlsZS5GaWxlU3lzdGVtIGZpbGVzeXN0ZW19LjwvcD4KICAgICAqIEByZXR1cm4gdGhlIGNvbXBpbGVyIHByb3ZpZGVkIHdpdGggdGhpcyBwbGF0Zm9ybSBvcgogICAgICoge0Bjb2RlIG51bGx9IGlmIG5vIGNvbXBpbGVyIGlzIHByb3ZpZGVkCiAgICAgKiBAaW1wbE5vdGUgVGhpcyBpbXBsZW1lbnRhdGlvbiByZXR1cm5zIHRoZSBjb21waWxlciBwcm92aWRlZAogICAgICogYnkgdGhlIHtAY29kZSBqZGsuY29tcGlsZXJ9IG1vZHVsZSBpZiB0aGF0IG1vZHVsZSBpcyBhdmFpbGFibGUsCiAgICAgKiBhbmQge0Bjb2RlIG51bGx9IG90aGVyd2lzZS4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBKYXZhQ29tcGlsZXIgZ2V0U3lzdGVtSmF2YUNvbXBpbGVyKCkgewogICAgICAgIHJldHVybiBnZXRTeXN0ZW1Ub29sKEphdmFDb21waWxlci5jbGFzcywKICAgICAgICAgICAgICAgIHN5c3RlbUphdmFDb21waWxlck1vZHVsZSwgc3lzdGVtSmF2YUNvbXBpbGVyTmFtZSk7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIHN5c3RlbURvY3VtZW50YXRpb25Ub29sTW9kdWxlID0gImpkay5qYXZhZG9jIjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBzeXN0ZW1Eb2N1bWVudGF0aW9uVG9vbE5hbWUgPSAiamRrLmphdmFkb2MuaW50ZXJuYWwuYXBpLkphdmFkb2NUb29sIjsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIEphdmEmdHJhZGU7IHByb2dyYW1taW5nIGxhbmd1YWdlIGRvY3VtZW50YXRpb24gdG9vbCBwcm92aWRlZAogICAgICogd2l0aCB0aGlzIHBsYXRmb3JtLgogICAgICogPHA+VGhlIGZpbGUgbWFuYWdlciByZXR1cm5lZCBieSBjYWxsaW5nCiAgICAgKiB7QGxpbmsgRG9jdW1lbnRhdGlvblRvb2wjZ2V0U3RhbmRhcmRGaWxlTWFuYWdlciBnZXRTdGFuZGFyZEZpbGVNYW5hZ2VyfQogICAgICogb24gdGhpcyB0b29sIHN1cHBvcnRzIHBhdGhzIHByb3ZpZGVkIGJ5IGFueQogICAgICoge0BsaW5rcGxhaW4gamF2YS5uaW8uZmlsZS5GaWxlU3lzdGVtIGZpbGVzeXN0ZW19LjwvcD4KICAgICAqIEByZXR1cm4gdGhlIGRvY3VtZW50YXRpb24gdG9vbCBwcm92aWRlZCB3aXRoIHRoaXMgcGxhdGZvcm0gb3IKICAgICAqIHtAY29kZSBudWxsfSBpZiBubyBkb2N1bWVudGF0aW9uIHRvb2wgaXMgcHJvdmlkZWQKICAgICAqIEBpbXBsTm90ZSBUaGlzIGltcGxlbWVudGF0aW9uIHJldHVybnMgdGhlIHRvb2wgcHJvdmlkZWQKICAgICAqIGJ5IHRoZSB7QGNvZGUgamRrLmphdmFkb2N9IG1vZHVsZSBpZiB0aGF0IG1vZHVsZSBpcyBhdmFpbGFibGUsCiAgICAgKiBhbmQge0Bjb2RlIG51bGx9IG90aGVyd2lzZS4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBEb2N1bWVudGF0aW9uVG9vbCBnZXRTeXN0ZW1Eb2N1bWVudGF0aW9uVG9vbCgpIHsKICAgICAgICByZXR1cm4gZ2V0U3lzdGVtVG9vbChEb2N1bWVudGF0aW9uVG9vbC5jbGFzcywKICAgICAgICAgICAgICAgIHN5c3RlbURvY3VtZW50YXRpb25Ub29sTW9kdWxlLCBzeXN0ZW1Eb2N1bWVudGF0aW9uVG9vbE5hbWUpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyBhIGNsYXNzIGxvYWRlciB0aGF0IG1heSBiZSB1c2VkIHRvIGxvYWQgc3lzdGVtIHRvb2xzLAogICAgICogb3Ige0Bjb2RlIG51bGx9IGlmIG5vIHN1Y2ggc3BlY2lhbCBsb2FkZXIgaXMgcHJvdmlkZWQuCiAgICAgKiBAaW1wbFNwZWMgVGhpcyBpbXBsZW1lbnRhdGlvbiBhbHdheXMgcmV0dXJucyB7QGNvZGUgbnVsbH0uCiAgICAgKiBAZGVwcmVjYXRlZCBUaGlzIG1ldGhvZCBpcyBzdWJqZWN0IHRvIHJlbW92YWwgaW4gYSBmdXR1cmUgdmVyc2lvbiBvZgogICAgICogSmF2YSBTRS4KICAgICAqIFVzZSB0aGUge0BsaW5rIGphdmEudXRpbC5zcGkuVG9vbFByb3ZpZGVyIHN5c3RlbSB0b29sIHByb3ZpZGVyfSBvcgogICAgICoge0BsaW5rIGphdmEudXRpbC5TZXJ2aWNlTG9hZGVyIHNlcnZpY2UgbG9hZGVyfSBtZWNoYW5pc21zIHRvCiAgICAgKiBsb2NhdGUgc3lzdGVtIHRvb2xzIGFzIHdlbGwgYXMgdXNlci1pbnN0YWxsZWQgdG9vbHMuCiAgICAgKiBAcmV0dXJuIGEgY2xhc3MgbG9hZGVyLCBvciB7QGNvZGUgbnVsbH0KICAgICAqLwogICAgQERlcHJlY2F0ZWQKICAgIHB1YmxpYyBzdGF0aWMgQ2xhc3NMb2FkZXIgZ2V0U3lzdGVtVG9vbENsYXNzTG9hZGVyKCkgewogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW4gdXNlTGVnYWN5OwoKICAgIHN0YXRpYyB7CiAgICAgICAgQ2xhc3M8Pz4gYyA9IG51bGw7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgYyA9IENsYXNzLmZvck5hbWUoImphdmEubGFuZy5yZWZsZWN0Lk1vZHVsZSIpOwogICAgICAgIH0gY2F0Y2ggKFRocm93YWJsZSB0KSB7CiAgICAgICAgfQogICAgICAgIHVzZUxlZ2FjeSA9IChjID09IG51bGwpOwogICAgfQoKICAgIC8qKgogICAgICogR2V0IGFuIGluc3RhbmNlIG9mIGEgc3lzdGVtIHRvb2wgdXNpbmcgdGhlIHNlcnZpY2UgbG9hZGVyLgogICAgICogQGltcGxOb3RlICAgICAgICAgQnkgZGVmYXVsdCwgdGhpcyByZXR1cm5zIHRoZSBpbXBsZW1lbnRhdGlvbiBpbiB0aGUgc3BlY2lmaWVkIG1vZHVsZS4KICAgICAqICAgICAgICAgICAgICAgICAgIEZvciBsaW1pdGVkIGJhY2t3YXJkIGNvbXBhdGliaWxpdHksIGlmIHRoaXMgY29kZSBpcyBydW4gb24gYW4gb2xkZXIgdmVyc2lvbgogICAgICogICAgICAgICAgICAgICAgICAgb2YgdGhlIEphdmEgcGxhdGZvcm0gdGhhdCBkb2VzIG5vdCBzdXBwb3J0IG1vZHVsZXMsIHRoaXMgbWV0aG9kIHdpbGwKICAgICAqICAgICAgICAgICAgICAgICAgIHRyeSBhbmQgY3JlYXRlIGFuIGluc3RhbmNlIG9mIHRoZSBuYW1lZCBjbGFzcy4gTm90ZSB0aGF0IGltcGxpZXMgdGhlCiAgICAgKiAgICAgICAgICAgICAgICAgICBjbGFzcyBtdXN0IGJlIGF2YWlsYWJsZSBvbiB0aGUgc3lzdGVtIGNsYXNzIHBhdGguCiAgICAgKiBAcGFyYW0gPFQ+ICAgICAgICB0aGUgaW50ZXJmYWNlIG9mIHRoZSB0b29sCiAgICAgKiBAcGFyYW0gY2xhenogICAgICB0aGUgaW50ZXJmYWNlIG9mIHRoZSB0b29sCiAgICAgKiBAcGFyYW0gbW9kdWxlTmFtZSB0aGUgbmFtZSBvZiB0aGUgbW9kdWxlIGNvbnRhaW5pbmcgdGhlIGRlc2lyZWQgaW1wbGVtZW50YXRpb24KICAgICAqIEBwYXJhbSBjbGFzc05hbWUgIHRoZSBjbGFzcyBuYW1lIG9mIHRoZSBkZXNpcmVkIGltcGxlbWVudGF0aW9uCiAgICAgKiBAcmV0dXJuIHRoZSBzcGVjaWZpZWQgaW1wbGVtZW50YXRpb24gb2YgdGhlIHRvb2wKICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgPFQ+IFQgZ2V0U3lzdGVtVG9vbChDbGFzczxUPiBjbGF6eiwgU3RyaW5nIG1vZHVsZU5hbWUsIFN0cmluZyBjbGFzc05hbWUpIHsKICAgICAgICBpZiAodXNlTGVnYWN5KSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICByZXR1cm4gQ2xhc3MuZm9yTmFtZShjbGFzc05hbWUsIHRydWUsIENsYXNzTG9hZGVyLmdldFN5c3RlbUNsYXNzTG9hZGVyKCkpLgogICAgICAgICAgICAgICAgICAgIGFzU3ViY2xhc3MoY2xhenopLmdldENvbnN0cnVjdG9yKCkubmV3SW5zdGFuY2UoKTsKICAgICAgICAgICAgfSBjYXRjaCAoUmVmbGVjdGl2ZU9wZXJhdGlvbkV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHRyeSB7CiAgICAgICAgICAgIFNlcnZpY2VMb2FkZXI8VD4gc2wgPSBTZXJ2aWNlTG9hZGVyLmxvYWQoY2xhenosIENsYXNzTG9hZGVyLmdldFN5c3RlbUNsYXNzTG9hZGVyKCkpOwogICAgICAgICAgICBmb3IgKEl0ZXJhdG9yPFQ+IGl0ZXIgPSBzbC5pdGVyYXRvcigpOyBpdGVyLmhhc05leHQoKTsgKSB7CiAgICAgICAgICAgICAgICBUIHRvb2wgPSBpdGVyLm5leHQoKTsKICAgICAgICAgICAgICAgIGlmIChtYXRjaGVzKHRvb2wsIG1vZHVsZU5hbWUpKQogICAgICAgICAgICAgICAgICAgIHJldHVybiB0b29sOwogICAgICAgICAgICB9CiAgICAgICAgfSBjYXRjaCAoU2VydmljZUNvbmZpZ3VyYXRpb25FcnJvciBlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgLyoqCiAgICAgKiBEZXRlcm1pbmUgaWYgdGhpcyBpcyB0aGUgZGVzaXJlZCB0b29sIGluc3RhbmNlLgogICAgICogQHBhcmFtIDxUPiAgICAgICAgdGhlIGludGVyZmFjZSBvZiB0aGUgdG9vbAogICAgICogQHBhcmFtIHRvb2wgICAgICAgdGhlIGluc3RhbmNlIG9mIHRoZSB0b29sCiAgICAgKiBAcGFyYW0gbW9kdWxlTmFtZSB0aGUgbmFtZSBvZiB0aGUgbW9kdWxlIGNvbnRhaW5pbmcgdGhlIGRlc2lyZWQgaW1wbGVtZW50YXRpb24KICAgICAqIEByZXR1cm4gdHJ1ZSBpZiBhbmQgb25seSBpZiB0aGUgdG9vbCBtYXRjaGVzIHRoZSBzcGVjaWZpZWQgY3JpdGVyaWEKICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgPFQ+IGJvb2xlYW4gbWF0Y2hlcyhUIHRvb2wsIFN0cmluZyBtb2R1bGVOYW1lKSB7CiAgICAgICAgUHJpdmlsZWdlZEFjdGlvbjxCb29sZWFuPiBwYSA9ICgpIC0+IHsKICAgICAgICAgICAgLy8gZm9yIG5vdywgdXNlIHJlZmxlY3Rpb24gdG8gaW1wbGVtZW50CiAgICAgICAgICAgIC8vICAgICAgcmV0dXJuIG1vZHVsZU5hbWUuZXF1YWxzKHRvb2wuZ2V0Q2xhc3MoKS5nZXRNb2R1bGUoKS5nZXROYW1lKCkpOwogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgTWV0aG9kIGdldE1vZHVsZU1ldGhvZCA9IENsYXNzLmNsYXNzLmdldERlY2xhcmVkTWV0aG9kKCJnZXRNb2R1bGUiKTsKICAgICAgICAgICAgICAgIE9iamVjdCB0b29sTW9kdWxlID0gZ2V0TW9kdWxlTWV0aG9kLmludm9rZSh0b29sLmdldENsYXNzKCkpOwogICAgICAgICAgICAgICAgTWV0aG9kIGdldE5hbWVNZXRob2QgPSB0b29sTW9kdWxlLmdldENsYXNzKCkuZ2V0RGVjbGFyZWRNZXRob2QoImdldE5hbWUiKTsKICAgICAgICAgICAgICAgIFN0cmluZyB0b29sTW9kdWxlTmFtZSA9IChTdHJpbmcpIGdldE5hbWVNZXRob2QuaW52b2tlKHRvb2xNb2R1bGUpOwogICAgICAgICAgICAgICAgcmV0dXJuIG1vZHVsZU5hbWUuZXF1YWxzKHRvb2xNb2R1bGVOYW1lKTsKICAgICAgICAgICAgfSBjYXRjaCAoSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbiB8IE5vU3VjaE1ldGhvZEV4Y2VwdGlvbiB8IElsbGVnYWxBY2Nlc3NFeGNlcHRpb24gZSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfTsKICAgICAgICByZXR1cm4gQWNjZXNzQ29udHJvbGxlci5kb1ByaXZpbGVnZWQocGEpOwogICAgfQp9ClBLAwQKAAAIAADSfU1KqPaqQY8GAACPBgAAHgAAAGphdmF4L3Rvb2xzL09wdGlvbkNoZWNrZXIuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNiwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBqYXZheC50b29sczsKCi8qKgogKiBJbnRlcmZhY2UgZm9yIHJlY29nbml6aW5nIG9wdGlvbnMuCiAqCiAqIEBhdXRob3IgUGV0ZXIgdm9uIGRlciBBaCZlYWN1dGU7CiAqIEBzaW5jZSAxLjYKICovCnB1YmxpYyBpbnRlcmZhY2UgT3B0aW9uQ2hlY2tlciB7CgogICAgLyoqCiAgICAgKiBEZXRlcm1pbmVzIGlmIHRoZSBnaXZlbiBvcHRpb24gaXMgc3VwcG9ydGVkIGFuZCBpZiBzbywgdGhlCiAgICAgKiBudW1iZXIgb2YgYXJndW1lbnRzIHRoZSBvcHRpb24gdGFrZXMuCiAgICAgKgogICAgICogQHBhcmFtIG9wdGlvbiBhbiBvcHRpb24KICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBhcmd1bWVudHMgdGhlIGdpdmVuIG9wdGlvbiB0YWtlcyBvciAtMSBpZgogICAgICogdGhlIG9wdGlvbiBpcyBub3Qgc3VwcG9ydGVkCiAgICAgKi8KICAgIGludCBpc1N1cHBvcnRlZE9wdGlvbihTdHJpbmcgb3B0aW9uKTsKCn0KUEsDBAoAAAgAAAY7qUr+/tHh5xAAAOcQAAAfAAAAamF2YXgvdG9vbHMvSmF2YUZpbGVPYmplY3QuamF2YS8qCiAqIENvcHlyaWdodCAoYykgMjAwNSwgMjAxNCwgT3JhY2xlIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogRE8gTk9UIEFMVEVSIE9SIFJFTU9WRSBDT1BZUklHSFQgTk9USUNFUyBPUiBUSElTIEZJTEUgSEVBREVSLgogKgogKiBUaGlzIGNvZGUgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBvbmx5LCBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4gIE9yYWNsZSBkZXNpZ25hdGVzIHRoaXMKICogcGFydGljdWxhciBmaWxlIGFzIHN1YmplY3QgdG8gdGhlICJDbGFzc3BhdGgiIGV4Y2VwdGlvbiBhcyBwcm92aWRlZAogKiBieSBPcmFjbGUgaW4gdGhlIExJQ0VOU0UgZmlsZSB0aGF0IGFjY29tcGFuaWVkIHRoaXMgY29kZS4KICoKICogVGhpcyBjb2RlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvcgogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogdmVyc2lvbiAyIGZvciBtb3JlIGRldGFpbHMgKGEgY29weSBpcyBpbmNsdWRlZCBpbiB0aGUgTElDRU5TRSBmaWxlIHRoYXQKICogYWNjb21wYW5pZWQgdGhpcyBjb2RlKS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbgogKiAyIGFsb25nIHdpdGggdGhpcyB3b3JrOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sCiAqIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQS4KICoKICogUGxlYXNlIGNvbnRhY3QgT3JhY2xlLCA1MDAgT3JhY2xlIFBhcmt3YXksIFJlZHdvb2QgU2hvcmVzLCBDQSA5NDA2NSBVU0EKICogb3IgdmlzaXQgd3d3Lm9yYWNsZS5jb20gaWYgeW91IG5lZWQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciBoYXZlIGFueQogKiBxdWVzdGlvbnMuCiAqLwoKcGFja2FnZSBqYXZheC50b29sczsKCmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuTmVzdGluZ0tpbmQ7CmltcG9ydCBqYXZheC5sYW5nLm1vZGVsLmVsZW1lbnQuTW9kaWZpZXI7CmltcG9ydCBqYXZhLnV0aWwuT2JqZWN0czsKCi8qKgogKiBGaWxlIGFic3RyYWN0aW9uIGZvciB0b29scyBvcGVyYXRpbmcgb24gSmF2YSZ0cmFkZTsgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2UKICogc291cmNlIGFuZCBjbGFzcyBmaWxlcy4KICoKICogPHA+QWxsIG1ldGhvZHMgaW4gdGhpcyBpbnRlcmZhY2UgbWlnaHQgdGhyb3cgYSBTZWN1cml0eUV4Y2VwdGlvbiBpZgogKiBhIHNlY3VyaXR5IGV4Y2VwdGlvbiBvY2N1cnMuCiAqCiAqIDxwPlVubGVzcyBleHBsaWNpdGx5IGFsbG93ZWQsIGFsbCBtZXRob2RzIGluIHRoaXMgaW50ZXJmYWNlIG1pZ2h0CiAqIHRocm93IGEgTnVsbFBvaW50ZXJFeGNlcHRpb24gaWYgZ2l2ZW4gYSB7QGNvZGUgbnVsbH0gYXJndW1lbnQuCiAqCiAqIEBhdXRob3IgUGV0ZXIgdm9uIGRlciBBaCZlYWN1dGU7CiAqIEBhdXRob3IgSm9uYXRoYW4gR2liYm9ucwogKiBAc2VlIEphdmFGaWxlTWFuYWdlcgogKiBAc2luY2UgMS42CiAqLwpwdWJsaWMgaW50ZXJmYWNlIEphdmFGaWxlT2JqZWN0IGV4dGVuZHMgRmlsZU9iamVjdCB7CgogICAgLyoqCiAgICAgKiBLaW5kcyBvZiBKYXZhRmlsZU9iamVjdHMuCiAgICAgKi8KICAgIGVudW0gS2luZCB7CiAgICAgICAgLyoqCiAgICAgICAgICogU291cmNlIGZpbGVzIHdyaXR0ZW4gaW4gdGhlIEphdmEgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2UuICBGb3IKICAgICAgICAgKiBleGFtcGxlLCByZWd1bGFyIGZpbGVzIGVuZGluZyB3aXRoIHtAY29kZSAuamF2YX0uCiAgICAgICAgICovCiAgICAgICAgU09VUkNFKCIuamF2YSIpLAoKICAgICAgICAvKioKICAgICAgICAgKiBDbGFzcyBmaWxlcyBmb3IgdGhlIEphdmEgVmlydHVhbCBNYWNoaW5lLiAgRm9yIGV4YW1wbGUsCiAgICAgICAgICogcmVndWxhciBmaWxlcyBlbmRpbmcgd2l0aCB7QGNvZGUgLmNsYXNzfS4KICAgICAgICAgKi8KICAgICAgICBDTEFTUygiLmNsYXNzIiksCgogICAgICAgIC8qKgogICAgICAgICAqIEhUTUwgZmlsZXMuICBGb3IgZXhhbXBsZSwgcmVndWxhciBmaWxlcyBlbmRpbmcgd2l0aCB7QGNvZGUKICAgICAgICAgKiAuaHRtbH0uCiAgICAgICAgICovCiAgICAgICAgSFRNTCgiLmh0bWwiKSwKCiAgICAgICAgLyoqCiAgICAgICAgICogQW55IG90aGVyIGtpbmQuCiAgICAgICAgICovCiAgICAgICAgT1RIRVIoIiIpOwogICAgICAgIC8qKgogICAgICAgICAqIFRoZSBleHRlbnNpb24gd2hpY2ggKGJ5IGNvbnZlbnRpb24pIGlzIG5vcm1hbGx5IHVzZWQgZm9yCiAgICAgICAgICogdGhpcyBraW5kIG9mIGZpbGUgb2JqZWN0LiAgSWYgbm8gY29udmVudGlvbiBleGlzdHMsIHRoZQogICAgICAgICAqIGVtcHR5IHN0cmluZyAoe0Bjb2RlICIifSkgaXMgdXNlZC4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgZmluYWwgU3RyaW5nIGV4dGVuc2lvbjsKICAgICAgICBwcml2YXRlIEtpbmQoU3RyaW5nIGV4dGVuc2lvbikgewogICAgICAgICAgICB0aGlzLmV4dGVuc2lvbiA9IE9iamVjdHMucmVxdWlyZU5vbk51bGwoZXh0ZW5zaW9uKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBraW5kIG9mIHRoaXMgZmlsZSBvYmplY3QuCiAgICAgKgogICAgICogQHJldHVybiB0aGUga2luZAogICAgICovCiAgICBLaW5kIGdldEtpbmQoKTsKCiAgICAvKioKICAgICAqIENoZWNrcyBpZiB0aGlzIGZpbGUgb2JqZWN0IGlzIGNvbXBhdGlibGUgd2l0aCB0aGUgc3BlY2lmaWVkCiAgICAgKiBzaW1wbGUgbmFtZSBhbmQga2luZC4gIEEgc2ltcGxlIG5hbWUgaXMgYSBzaW5nbGUgaWRlbnRpZmllcgogICAgICogKG5vdCBxdWFsaWZpZWQpIGFzIGRlZmluZWQgaW4KICAgICAqIDxjaXRlPlRoZSBKYXZhJnRyYWRlOyBMYW5ndWFnZSBTcGVjaWZpY2F0aW9uPC9jaXRlPiwKICAgICAqIHNlY3Rpb24gNi4yICJOYW1lcyBhbmQgSWRlbnRpZmllcnMiLgogICAgICoKICAgICAqIEBwYXJhbSBzaW1wbGVOYW1lIGEgc2ltcGxlIG5hbWUgb2YgYSBjbGFzcwogICAgICogQHBhcmFtIGtpbmQgYSBraW5kCiAgICAgKiBAcmV0dXJuIHtAY29kZSB0cnVlfSBpZiB0aGlzIGZpbGUgb2JqZWN0IGlzIGNvbXBhdGlibGU7IGZhbHNlCiAgICAgKiBvdGhlcndpc2UKICAgICAqLwogICAgYm9vbGVhbiBpc05hbWVDb21wYXRpYmxlKFN0cmluZyBzaW1wbGVOYW1lLCBLaW5kIGtpbmQpOwoKICAgIC8qKgogICAgICogUHJvdmlkZXMgYSBoaW50IGFib3V0IHRoZSBuZXN0aW5nIGxldmVsIG9mIHRoZSBjbGFzcwogICAgICogcmVwcmVzZW50ZWQgYnkgdGhpcyBmaWxlIG9iamVjdC4gIFRoaXMgbWV0aG9kIG1heSByZXR1cm4KICAgICAqIHtAbGluayBOZXN0aW5nS2luZCNNRU1CRVJ9IHRvIG1lYW4KICAgICAqIHtAbGluayBOZXN0aW5nS2luZCNMT0NBTH0gb3Ige0BsaW5rIE5lc3RpbmdLaW5kI0FOT05ZTU9VU30uCiAgICAgKiBJZiB0aGUgbmVzdGluZyBsZXZlbCBpcyBub3Qga25vd24gb3IgdGhpcyBmaWxlIG9iamVjdCBkb2VzIG5vdAogICAgICogcmVwcmVzZW50IGEgY2xhc3MgZmlsZSB0aGlzIG1ldGhvZCByZXR1cm5zIHtAY29kZSBudWxsfS4KICAgICAqCiAgICAgKiBAcmV0dXJuIHRoZSBuZXN0aW5nIGtpbmQsIG9yIHtAY29kZSBudWxsfSBpZiB0aGUgbmVzdGluZyBraW5kCiAgICAgKiBpcyBub3Qga25vd24KICAgICAqLwogICAgTmVzdGluZ0tpbmQgZ2V0TmVzdGluZ0tpbmQoKTsKCiAgICAvKioKICAgICAqIFByb3ZpZGVzIGEgaGludCBhYm91dCB0aGUgYWNjZXNzIGxldmVsIG9mIHRoZSBjbGFzcyByZXByZXNlbnRlZAogICAgICogYnkgdGhpcyBmaWxlIG9iamVjdC4gIElmIHRoZSBhY2Nlc3MgbGV2ZWwgaXMgbm90IGtub3duIG9yIGlmCiAgICAgKiB0aGlzIGZpbGUgb2JqZWN0IGRvZXMgbm90IHJlcHJlc2VudCBhIGNsYXNzIGZpbGUgdGhpcyBtZXRob2QKICAgICAqIHJldHVybnMge0Bjb2RlIG51bGx9LgogICAgICoKICAgICAqIEByZXR1cm4gdGhlIGFjY2VzcyBsZXZlbAogICAgICovCiAgICBNb2RpZmllciBnZXRBY2Nlc3NMZXZlbCgpOwoKfQpQSwECCgAKAAAIAADnPKlKAAAAAAAAAAAAAAAACQAEAAAAAAAAAAAAAAAAAAAATUVUQS1JTkYv/soAAFBLAQIKAAoAAAgAAOc8qUrj26ZfSAAAAEgAAAAUAAAAAAAAAAAAAAAAACsAAABNRVRBLUlORi9NQU5JRkVTVC5NRlBLAQIKAAoAAAgAAAY7qUoAAAAAAAAAAAAAAAASAAAAAAAAAAAAAAAAAKUAAABNRVRBLUlORi9zZXJ2aWNlcy9QSwECCgAKAAAIAAAGO6lKZ0TnRTEAAAAxAAAAPwAAAAAAAAAAAAAAAADVAAAATUVUQS1JTkYvc2VydmljZXMvY29tLnN1bi50b29scy5qYXZhYy5wbGF0Zm9ybS5QbGF0Zm9ybVByb3ZpZGVyUEsBAgoACgAACAAABjupSsYBGgAPBwAADwcAABAAAAAAAAAAAAAAAAAAYwEAAG1vZHVsZS1pbmZvLmphdmFQSwECCgAKAAAIAAAGO6lKAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAACgCAAAamRrL1BLAQIKAAoAAAgAAAY7qUoAAAAAAAAAAAAAAAANAAAAAAAAAAAAAAAAAMIIAABqZGsvaW50ZXJuYWwvUEsBAgoACgAACAAABjupSgAAAAAAAAAAAAAAABoAAAAAAAAAAAAAAAAA7QgAAGpkay9pbnRlcm5hbC9zaGVsbHN1cHBvcnQvUEsBAgoACgAACAAABjupSgAAAAAAAAAAAAAAAB4AAAAAAAAAAAAAAAAAJQkAAGpkay9pbnRlcm5hbC9zaGVsbHN1cHBvcnQvZG9jL1BLAQIKAAoAAAgAAAY7qUoAAAAAAAAAAAAAAAAoAAAAAAAAAAAAAAAAAGEJAABqZGsvaW50ZXJuYWwvc2hlbGxzdXBwb3J0L2RvYy9yZXNvdXJjZXMvUEsBAgoACgAACAAABjupSl9wwBwcBQAAHAUAAEMAAAAAAAAAAAAAAAAApwkAAGpkay9pbnRlcm5hbC9zaGVsbHN1cHBvcnQvZG9jL3Jlc291cmNlcy9qYXZhZG9jZm9ybWF0dGVyLnByb3BlcnRpZXNQSwECCgAKAAAIAAAGO6lK8kCixUCGAABAhgAAMAAAAAAAAAAAAAAAAAAkDwAAamRrL2ludGVybmFsL3NoZWxsc3VwcG9ydC9kb2MvSmF2YWRvY0hlbHBlci5qYXZhUEsBAgoACgAACAAABjupSgYwDFLcZgAA3GYAADMAAAAAAAAAAAAAAAAAspUAAGpkay9pbnRlcm5hbC9zaGVsbHN1cHBvcnQvZG9jL0phdmFkb2NGb3JtYXR0ZXIuamF2YVBLAQIKAAoAAAgAANJ9TUoAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAN/8AABjb20vUEsBAgoACgAACAAA0n1NSgAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAf0AAGNvbS9zdW4vUEsBAgoACgAACAAA0n1NSgAAAAAAAAAAAAAAAA8AAAAAAAAAAAAAAAAAJ/0AAGNvbS9zdW4vc291cmNlL1BLAQIKAAoAAAgAAAY7qUoAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAAAFT9AABjb20vc3VuL3NvdXJjZS90cmVlL1BLAQIKAAoAAAgAAAY7qUqePtT1nAYAAJwGAAAqAAAAAAAAAAAAAAAAAIb9AABjb20vc3VuL3NvdXJjZS90cmVlL1ByaW1pdGl2ZVR5cGVUcmVlLmphdmFQSwECCgAKAAAIAAAGO6lKBADnmh4HAAAeBwAAIgAAAAAAAAAAAAAAAABqBAEAY29tL3N1bi9zb3VyY2UvdHJlZS9VbmFyeVRyZWUuamF2YVBLAQIKAAoAAAgAAAY7qUpRiVkXhwkAAIcJAAAgAAAAAAAAAAAAAAAAAMgLAQBjb20vc3VuL3NvdXJjZS90cmVlL1RyeVRyZWUuamF2YVBLAQIKAAoAAAgAAAY7qUr1FWCQ6AYAAOgGAAAlAAAAAAAAAAAAAAAAAI0VAQBjb20vc3VuL3NvdXJjZS90cmVlL1R5cGVDYXN0VHJlZS5qYXZhUEsBAgoACgAACAAABjupSsgQlhHKBQAAygUAACYAAAAAAAAAAAAAAAAAuBwBAGNvbS9zdW4vc291cmNlL3RyZWUvU3RhdGVtZW50VHJlZS5qYXZhUEsBAgoACgAACAAABjupSmS/IB+HBQAAhwUAACUAAAAAAAAAAAAAAAAAxiIBAGNvbS9zdW4vc291cmNlL3RyZWUvcGFja2FnZS1pbmZvLmphdmFQSwECCgAKAAAIAAAGO6lKOABY+8cHAADHBwAAIgAAAAAAAAAAAAAAAACQKAEAY29tL3N1bi9zb3VyY2UvdHJlZS9PcGVuc1RyZWUuamF2YVBLAQIKAAoAAAgAAAY7qUqgSDiSvQYAAL0GAAAqAAAAAAAAAAAAAAAAAJcwAQBjb20vc3VuL3NvdXJjZS90cmVlL1BhcmVudGhlc2l6ZWRUcmVlLmphdmFQSwECCgAKAAAIAAAGO6lKq3ejeFMGAABTBgAAJgAAAAAAAAAAAAAAAACcNwEAY29tL3N1bi9zb3VyY2UvdHJlZS9BcnJheVR5cGVUcmVlLmphdmFQSwECCgAKAAAIAAAGO6lK4YGn6g8KAAAPCgAAJQAAAAAAAAAAAAAAAAAzPgEAY29tL3N1bi9zb3VyY2UvdHJlZS9OZXdBcnJheVRyZWUuamF2YVBLAQIKAAoAAAgAAAY7qUo/752STAUAAEwFAAAmAAAAAAAAAAAAAAAAAIVIAQBjb20vc3VuL3NvdXJjZS90cmVlL0RpcmVjdGl2ZVRyZWUuamF2YVBLAQIKAAoAAAgAAAY7qUrh61LSdQYAAHUGAAAiAAAAAAAAAAAAAAAAABVOAQBjb20vc3VuL3NvdXJjZS90cmVlL1Rocm93VHJlZS5qYXZhUEsBAgoACgAACAAABjupSjD0+LGKBgAAigYAADAAAAAAAAAAAAAAAAAAylQBAGNvbS9zdW4vc291cmNlL3RyZWUvRXhwcmVzc2lvblN0YXRlbWVudFRyZWUuamF2YVBLAQIKAAoAAAgAAAY7qUoNbYi4/AoAAPwKAAAgAAAAAAAAAAAAAAAAAKJbAQBjb20vc3VuL3NvdXJjZS90cmVlL0xpbmVNYXAuamF2YVBLAQIKAAoAAAgAAAY7qUpGgDLWdAcAAHQHAAAnAAAAAAAAAAAAAAAAANxmAQBjb20vc3VuL3NvdXJjZS90cmVlL0Fubm90YXRpb25UcmVlLmphdmFQSwECCgAKAAAIAAAGO6lKWd598pMLAACTCwAAHgAAAAAAAAAAAAAAAACVbgEAY29tL3N1bi9zb3VyY2UvdHJlZS9TY29wZS5qYXZhUEsBAgoACgAACAAABjupSoIr0gfsBgAA7AYAACQAAAAAAAAAAAAAAAAAZHoBAGNvbS9zdW4vc291cmNlL3RyZWUvTGl0ZXJhbFRyZWUuamF2YVBLAQIKAAoAAAgAAAY7qUoQl4PovwYAAL8GAAAlAAAAAAAAAAAAAAAAAJKBAQBjb20vc3VuL3NvdXJjZS90cmVlL1dpbGRjYXJkVHJlZS5qYXZhUEsBAgoACgAACAAABjupSu2kh8RFCQAARQkAACQAAAAAAAAAAAAAAAAAlIgBAGNvbS9zdW4vc291cmNlL3RyZWUvRm9yTG9vcFRyZWUuamF2YVBLAQIKAAoAAAgAAAY7qUqc5nKCCgcAAAoHAAAoAAAAAAAAAAAAAAAAABuSAQBjb20vc3VuL3NvdXJjZS90cmVlL0FycmF5QWNjZXNzVHJlZS5qYXZhUEsBAgoACgAACAAABjupSmOwyBk+BgAAPgYAACEAAAAAAAAAAAAAAAAAa5kBAGNvbS9zdW4vc291cmNlL3RyZWUvVXNlc1RyZWUuamF2YVBLAQIKAAoAAAgAAAY7qUrL2jkzogYAAKIGAAAiAAAAAAAAAAAAAAAAAOifAQBjb20vc3VuL3NvdXJjZS90cmVlL0JyZWFrVHJlZS5qYXZhUEsBAgoACgAACAAABjupSkG0sEg4CgAAOAoAACUAAAAAAAAAAAAAAAAAyqYBAGNvbS9zdW4vc291cmNlL3RyZWUvTmV3Q2xhc3NUcmVlLmphdmFQSwECCgAKAAAIAAAGO6lKnRabwXYHAAB2BwAAIgAAAAAAAAAAAAAAAABFsQEAY29tL3N1bi9zb3VyY2UvdHJlZS9CbG9ja1RyZWUuamF2YVBLAQIKAAoAAAgAAAY7qUqx6q4TFAkAABQJAAAqAAAAAAAAAAAAAAAAAPu4AQBjb20vc3VuL3NvdXJjZS90cmVlL1R5cGVQYXJhbWV0ZXJUcmVlLmphdmFQSwECCgAKAAAIAAAGO6lKb658lOQHAADkBwAALAAAAAAAAAAAAAAAAABXwgEAY29tL3N1bi9zb3VyY2UvdHJlZS9FbmhhbmNlZEZvckxvb3BUcmVlLmphdmFQSwECCgAKAAAIAAAGO6lKKULBc18MAABfDAAALAAAAAAAAAAAAAAAAACFygEAY29tL3N1bi9zb3VyY2UvdHJlZS9Db21waWxhdGlvblVuaXRUcmVlLmphdmFQSwECCgAKAAAIAAAGO6lKS2ltQDkIAAA5CAAAMgAAAAAAAAAAAAAAAAAu1wEAY29tL3N1bi9zb3VyY2UvdHJlZS9Db25kaXRpb25hbEV4cHJlc3Npb25UcmVlLmphdmFQSwECCgAKAAAIAAAGO6lKtNmDyK4GAACuBgAAJQAAAAAAAAAAAAAAAAC33wEAY29tL3N1bi9zb3VyY2UvdHJlZS9Db250aW51ZVRyZWUuamF2YVBLAQIKAAoAAAgAAAY7qUrsWkRMNAcAADQHAAApAAAAAAAAAAAAAAAAAKjmAQBjb20vc3VuL3NvdXJjZS90cmVlL1N5bmNocm9uaXplZFRyZWUuamF2YVBLAQIKAAoAAAgAAAY7qUqGzQlfHE0AABxNAAAdAAAAAAAAAAAAAAAAACPuAQBjb20vc3VuL3NvdXJjZS90cmVlL1RyZWUuamF2YVBLAQIKAAoAAAgAAAY7qUoDuz6czAUAAMwFAAAnAAAAAAAAAAAAAAAAAHo7AgBjb20vc3VuL3NvdXJjZS90cmVlL0V4cHJlc3Npb25UcmVlLmphdmFQSwECCgAKAAAIAAAGO6lKBV/o+hkHAAAZBwAAJwAAAAAAAAAAAAAAAACLQQIAY29tL3N1bi9zb3VyY2UvdHJlZS9Bc3NpZ25tZW50VHJlZS5qYXZhUEsBAgoACgAACAAABjupSu11Ns54BwAAeAcAACIAAAAAAAAAAAAAAAAA6UgCAGNvbS9zdW4vc291cmNlL3RyZWUvQ2F0Y2hUcmVlLmphdmFQSwECCgAKAAAIAAAGO6lKkFWVOHUHAAB1BwAAJQAAAAAAAAAAAAAAAAChUAIAY29tL3N1bi9zb3VyY2UvdHJlZS9Qcm92aWRlc1RyZWUuamF2YVBLAQIKAAoAAAgAAAY7qUpu81DpSAYAAEgGAAAmAAAAAAAAAAAAAAAAAFlYAgBjb20vc3VuL3NvdXJjZS90cmVlL0Vycm9uZW91c1RyZWUuamF2YVBLAQIKAAoAAAgAAAY7qUocn1S2GwYAABsGAAAtAAAAAAAAAAAAAAAAAOVeAgBjb20vc3VuL3NvdXJjZS90cmVlL0ludGVyc2VjdGlvblR5cGVUcmVlLmphdmFQSwECCgAKAAAIAAAGO6lKXSo+QfoIAAD6CAAALQAAAAAAAAAAAAAAAABLZQIAY29tL3N1bi9zb3VyY2UvdHJlZS9MYW1iZGFFeHByZXNzaW9uVHJlZS5qYXZhUEsBAgoACgAACAAABjupSnRiWl4MCAAADAgAACUAAAAAAAAAAAAAAAAAkG4CAGNvbS9zdW4vc291cmNlL3RyZWUvUmVxdWlyZXNUcmVlLmphdmFQSwECCgAKAAAIAAAGO6lKLlUaO7gIAAC4CAAAHwAAAAAAAAAAAAAAAADfdgIAY29tL3N1bi9zb3VyY2UvdHJlZS9JZlRyZWUuamF2YVBLAQIKAAoAAAgAAAY7qUqHio74VAcAAFQHAAAjAAAAAAAAAAAAAAAAANR/AgBjb20vc3VuL3NvdXJjZS90cmVlL1N3aXRjaFRyZWUuamF2YVBLAQIKAAoAAAgAAAY7qUqLjmi8EQgAABEIAAAjAAAAAAAAAAAAAAAAAGmHAgBjb20vc3VuL3NvdXJjZS90cmVlL0ltcG9ydFRyZWUuamF2YVBLAQIKAAoAAAgAAAY7qUqTl8e1qwcAAKsHAAAqAAAAAAAAAAAAAAAAALuPAgBjb20vc3VuL3NvdXJjZS90cmVlL0Fubm90YXRlZFR5cGVUcmVlLmphdmFQSwECCgAKAAAIAAAGO6lKumLPdYcGAACHBgAAIwAAAAAAAAAAAAAAAACulwIAY29tL3N1bi9zb3VyY2UvdHJlZS9SZXR1cm5UcmVlLmphdmFQSwECCgAKAAAIAAAGO6lKITL1n1QGAABUBgAAJgAAAAAAAAAAAAAAAAB2ngIAY29tL3N1bi9zb3VyY2UvdHJlZS9VbmlvblR5cGVUcmVlLmphdmFQSwECCgAKAAAIAAAGO6lKdQ9EVP8JAAD/CQAAJQAAAAAAAAAAAAAAAAAOpQIAY29tL3N1bi9zb3VyY2UvdHJlZS9WYXJpYWJsZVRyZWUuamF2YVBLAQIKAAoAAAgAAAY7qUoVV1onYQgAAGEIAAAtAAAAAAAAAAAAAAAAAFCvAgBjb20vc3VuL3NvdXJjZS90cmVlL01ldGhvZEludm9jYXRpb25UcmVlLmphdmFQSwECCgAKAAAIAAAGO6lKbhugZxUHAAAVBwAAJgAAAAAAAAAAAAAAAAD8twIAY29tL3N1bi9zb3VyY2UvdHJlZS9XaGlsZUxvb3BUcmVlLmphdmFQSwECCgAKAAAIAAAGO6lKwJfNbYcHAACHBwAAIwAAAAAAAAAAAAAAAABVvwIAY29tL3N1bi9zb3VyY2UvdHJlZS9CaW5hcnlUcmVlLmphdmFQSwECCgAKAAAIAAAGO6lKnNyTIUoJAABKCQAALAAAAAAAAAAAAAAAAAAdxwIAY29tL3N1bi9zb3VyY2UvdHJlZS9NZW1iZXJSZWZlcmVuY2VUcmVlLmphdmFQSwECCgAKAAAIAAAGO6lK9h6MiCoHAAAqBwAAIwAAAAAAAAAAAAAAAACx0AIAY29tL3N1bi9zb3VyY2UvdHJlZS9Bc3NlcnRUcmVlLmphdmFQSwECCgAKAAAIAAAGO6lKFXU3dNUHAADVBwAAIQAAAAAAAAAAAAAAAAAc2AIAY29tL3N1bi9zb3VyY2UvdHJlZS9DYXNlVHJlZS5qYXZhUEsBAgoACgAACAAABjupSiAZtAd/BgAAfwYAACcAAAAAAAAAAAAAAAAAMOACAGNvbS9zdW4vc291cmNlL3RyZWUvSWRlbnRpZmllclRyZWUuamF2YVBLAQIKAAoAAAgAAAY7qUq48li7HgkAAB4JAAAjAAAAAAAAAAAAAAAAAPTmAgBjb20vc3VuL3NvdXJjZS90cmVlL01vZHVsZVRyZWUuamF2YVBLAQIKAAoAAAgAAAY7qUrzdg08yQcAAMkHAAAmAAAAAAAAAAAAAAAAAFPwAgBjb20vc3VuL3NvdXJjZS90cmVlL01vZGlmaWVyc1RyZWUuamF2YVBLAQIKAAoAAAgAAAY7qUqf/F/25gUAAOYFAAArAAAAAAAAAAAAAAAAAGD4AgBjb20vc3VuL3NvdXJjZS90cmVlL0VtcHR5U3RhdGVtZW50VHJlZS5qYXZhUEsBAgoACgAACAAABjupSr9tiR4BBwAAAQcAAC0AAAAAAAAAAAAAAAAAj/4CAGNvbS9zdW4vc291cmNlL3RyZWUvTGFiZWxlZFN0YXRlbWVudFRyZWUuamF2YVBLAQIKAAoAAAgAAAY7qUrY3CnlYDsAAGA7AAAkAAAAAAAAAAAAAAAAANsFAwBjb20vc3VuL3NvdXJjZS90cmVlL1RyZWVWaXNpdG9yLmphdmFQSwECCgAKAAAIAAAGO6lK5jqY0f8GAAD/BgAAJwAAAAAAAAAAAAAAAAB9QQMAY29tL3N1bi9zb3VyY2UvdHJlZS9JbnN0YW5jZU9mVHJlZS5qYXZhUEsBAgoACgAACAAABjupSiV41e0aBwAAGgcAAC4AAAAAAAAAAAAAAAAAwUgDAGNvbS9zdW4vc291cmNlL3RyZWUvUGFyYW1ldGVyaXplZFR5cGVUcmVlLmphdmFQSwECCgAKAAAIAAAGO6lKnTbw5FgHAABYBwAAKQAAAAAAAAAAAAAAAAAnUAMAY29tL3N1bi9zb3VyY2UvdHJlZS9NZW1iZXJTZWxlY3RUcmVlLmphdmFQSwECCgAKAAAIAAAGO6lK8rRsadUHAADVBwAAJAAAAAAAAAAAAAAAAADGVwMAY29tL3N1bi9zb3VyY2UvdHJlZS9FeHBvcnRzVHJlZS5qYXZhUEsBAgoACgAACAAABjupSgwS2X2qBwAAqgcAAC8AAAAAAAAAAAAAAAAA3V8DAGNvbS9zdW4vc291cmNlL3RyZWUvQ29tcG91bmRBc3NpZ25tZW50VHJlZS5qYXZhUEsBAgoACgAACAAABjupShO+xmnMCgAAzAoAACIAAAAAAAAAAAAAAAAA1GcDAGNvbS9zdW4vc291cmNlL3RyZWUvQ2xhc3NUcmVlLmphdmFQSwECCgAKAAAIAAAGO6lKIzk2TRgHAAAYBwAAKAAAAAAAAAAAAAAAAADgcgMAY29tL3N1bi9zb3VyY2UvdHJlZS9Eb1doaWxlTG9vcFRyZWUuamF2YVBLAQIKAAoAAAgAAAY7qUp04/FvXg0AAF4NAAAjAAAAAAAAAAAAAAAAAD56AwBjb20vc3VuL3NvdXJjZS90cmVlL01ldGhvZFRyZWUuamF2YVBLAQIKAAoAAAgAAAY7qUoOTgG/xgYAAMYGAAAkAAAAAAAAAAAAAAAAAN2HAwBjb20vc3VuL3NvdXJjZS90cmVlL1BhY2thZ2VUcmVlLmphdmFQSwECCgAKAAAIAAAGO6lKAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAADljgMAY29tL3N1bi9zb3VyY2UvdXRpbC9QSwECCgAKAAAIAAAGO6lK6vTnkR5UAAAeVAAAKgAAAAAAAAAAAAAAAAAXjwMAY29tL3N1bi9zb3VyY2UvdXRpbC9TaW1wbGVUcmVlVmlzaXRvci5qYXZhUEsBAgoACgAACAAABjupSh/okVd5BQAAeQUAACUAAAAAAAAAAAAAAAAAfeMDAGNvbS9zdW4vc291cmNlL3V0aWwvcGFja2FnZS1pbmZvLmphdmFQSwECCgAKAAAIAAAGO6lKiScxcjg9AAA4PQAAJwAAAAAAAAAAAAAAAAA56QMAY29tL3N1bi9zb3VyY2UvdXRpbC9Eb2NUcmVlU2Nhbm5lci5qYXZhUEsBAgoACgAACAAABjupSjI0EvJvDQAAbw0AACgAAAAAAAAAAAAAAAAAtiYEAGNvbS9zdW4vc291cmNlL3V0aWwvU291cmNlUG9zaXRpb25zLmphdmFQSwECCgAKAAAIAAAGO6lKXoax2TUHAAA1BwAAJQAAAAAAAAAAAAAAAABrNAQAY29tL3N1bi9zb3VyY2UvdXRpbC9UYXNrTGlzdGVuZXIuamF2YVBLAQIKAAoAAAgAAAY7qUpr1DUqFhEAABYRAAArAAAAAAAAAAAAAAAAAOM7BABjb20vc3VuL3NvdXJjZS91dGlsL0RvY1NvdXJjZVBvc2l0aW9ucy5qYXZhUEsBAgoACgAACAAABjupSgpeFW8qFAAAKhQAACEAAAAAAAAAAAAAAAAAQk0EAGNvbS9zdW4vc291cmNlL3V0aWwvVHJlZVBhdGguamF2YVBLAQIKAAoAAAgAAAY7qUoZyQj3UwoAAFMKAAAfAAAAAAAAAAAAAAAAAKthBABjb20vc3VuL3NvdXJjZS91dGlsL1BsdWdpbi5qYXZhUEsBAgoACgAACAAABjupSmPNKDHNOAAAzTgAACcAAAAAAAAAAAAAAAAAO2wEAGNvbS9zdW4vc291cmNlL3V0aWwvRG9jVHJlZUZhY3RvcnkuamF2YVBLAQIKAAoAAAgAAAY7qUpS/Qiw7QwAAO0MAAAoAAAAAAAAAAAAAAAAAE2lBABjb20vc3VuL3NvdXJjZS91dGlsL1RyZWVQYXRoU2Nhbm5lci5qYXZhUEsBAgoACgAACAAABjupSjac8mJwCwAAcAsAACsAAAAAAAAAAAAAAAAAgLIEAGNvbS9zdW4vc291cmNlL3V0aWwvRG9jVHJlZVBhdGhTY2FubmVyLmphdmFQSwECCgAKAAAIAAAGO6lKkvv1QZIXAACSFwAAJAAAAAAAAAAAAAAAAAA5vgQAY29tL3N1bi9zb3VyY2UvdXRpbC9Eb2NUcmVlUGF0aC5qYXZhUEsBAgoACgAACAAABjupSqlIrK8JGQAACRkAACIAAAAAAAAAAAAAAAAADdYEAGNvbS9zdW4vc291cmNlL3V0aWwvSmF2YWNUYXNrLmphdmFQSwECCgAKAAAIAAAGO6lKyfZmOYYfAACGHwAAIQAAAAAAAAAAAAAAAABW7wQAY29tL3N1bi9zb3VyY2UvdXRpbC9Eb2NUcmVlcy5qYXZhUEsBAgoACgAACAAABjupStmbKMg+JwAAPicAAB4AAAAAAAAAAAAAAAAAGw8FAGNvbS9zdW4vc291cmNlL3V0aWwvVHJlZXMuamF2YVBLAQIKAAoAAAgAAAY7qUqWw2Dz5RQAAOUUAAAiAAAAAAAAAAAAAAAAAJU2BQBjb20vc3VuL3NvdXJjZS91dGlsL1Rhc2tFdmVudC5qYXZhUEsBAgoACgAACAAABjupSuffEnVPNwAATzcAAC0AAAAAAAAAAAAAAAAAuksFAGNvbS9zdW4vc291cmNlL3V0aWwvU2ltcGxlRG9jVHJlZVZpc2l0b3IuamF2YVBLAQIKAAoAAAgAAAY7qUpZdCwIymsAAMprAAAkAAAAAAAAAAAAAAAAAFSDBQBjb20vc3VuL3NvdXJjZS91dGlsL1RyZWVTY2FubmVyLmphdmFQSwECCgAKAAAIAAAGO6lKAAAAAAAAAAAAAAAAFwAAAAAAAAAAAAAAAABg7wUAY29tL3N1bi9zb3VyY2UvZG9jdHJlZS9QSwECCgAKAAAIAAAGO6lKYnvy5gQGAAAEBgAAKgAAAAAAAAAAAAAAAACV7wUAY29tL3N1bi9zb3VyY2UvZG9jdHJlZS9FbmRFbGVtZW50VHJlZS5qYXZhUEsBAgoACgAACAAABjupSrS0C2DeCAAA3ggAACkAAAAAAAAAAAAAAAAA4fUFAGNvbS9zdW4vc291cmNlL2RvY3RyZWUvQXR0cmlidXRlVHJlZS5qYXZhUEsBAgoACgAACAAABjupSj/tPoM1BgAANQYAACoAAAAAAAAAAAAAAAAABv8FAGNvbS9zdW4vc291cmNlL2RvY3RyZWUvU2VyaWFsRGF0YVRyZWUuamF2YVBLAQIKAAoAAAgAAAY7qUrz6a9zcAYAAHAGAAAmAAAAAAAAAAAAAAAAAIMFBgBjb20vc3VuL3NvdXJjZS9kb2N0cmVlL1NlcmlhbFRyZWUuamF2YVBLAQIKAAoAAAgAAAY7qUpgfK5tnAUAAJwFAAAkAAAAAAAAAAAAAAAAADcMBgBjb20vc3VuL3NvdXJjZS9kb2N0cmVlL1RleHRUcmVlLmphdmFQSwECCgAKAAAIAAAGO6lKXteRizsGAAA7BgAAKAAAAAAAAAAAAAAAAAAVEgYAY29tL3N1bi9zb3VyY2UvZG9jdHJlZS9wYWNrYWdlLWluZm8uamF2YVBLAQIKAAoAAAgAAAY7qUoIIWzYWQcAAFkHAAAlAAAAAAAAAAAAAAAAAJYYBgBjb20vc3VuL3NvdXJjZS9kb2N0cmVlL1BhcmFtVHJlZS5qYXZhUEsBAgoACgAACAAABjupSg0Ar55cBgAAXAYAACMAAAAAAAAAAAAAAAAAMiAGAGNvbS9zdW4vc291cmNlL2RvY3RyZWUvU2VlVHJlZS5qYXZhUEsBAgoACgAACAAABjupSoWHx9rcBQAA3AUAACcAAAAAAAAAAAAAAAAAzyYGAGNvbS9zdW4vc291cmNlL2RvY3RyZWUvQ29tbWVudFRyZWUuamF2YVBLAQIKAAoAAAgAAAY7qUoVhrmEeQYAAHkGAAApAAAAAAAAAAAAAAAAAPAsBgBjb20vc3VuL3NvdXJjZS9kb2N0cmVlL1JlZmVyZW5jZVRyZWUuamF2YVBLAQIKAAoAAAgAAAY7qUpNG0zh5wkAAOcJAAAqAAAAAAAAAAAAAAAAALAzBgBjb20vc3VuL3NvdXJjZS9kb2N0cmVlL0RvY0NvbW1lbnRUcmVlLmphdmFQSwECCgAKAAAIAAAGO6lKN0ah9BkGAAAZBgAAJwAAAAAAAAAAAAAAAADfPQYAY29tL3N1bi9zb3VyY2UvZG9jdHJlZS9MaXRlcmFsVHJlZS5qYXZhUEsBAgoACgAACAAABjupSp5kwXzdBgAA3QYAACQAAAAAAAAAAAAAAAAAPUQGAGNvbS9zdW4vc291cmNlL2RvY3RyZWUvVXNlc1RyZWUuamF2YVBLAQIKAAoAAAgAAAY7qUrszkX5QAYAAEAGAAAqAAAAAAAAAAAAAAAAAFxLBgBjb20vc3VuL3NvdXJjZS9kb2N0cmVlL0RlcHJlY2F0ZWRUcmVlLmphdmFQSwECCgAKAAAIAAAGO6lKNuGoBUcGAABHBgAAJgAAAAAAAAAAAAAAAADkUQYAY29tL3N1bi9zb3VyY2UvZG9jdHJlZS9FbnRpdHlUcmVlLmphdmFQSwECCgAKAAAIAAAGO6lKVMQ6aeoFAADqBQAAKAAAAAAAAAAAAAAAAABvWAYAY29tL3N1bi9zb3VyY2UvZG9jdHJlZS9CbG9ja1RhZ1RyZWUuamF2YVBLAQIKAAoAAAgAAAY7qUoE6JwyYgcAAGIHAAAmAAAAAAAAAAAAAAAAAJ9eBgBjb20vc3VuL3NvdXJjZS9kb2N0cmVlL1Rocm93c1RyZWUuamF2YVBLAQIKAAoAAAgAAAY7qUpn0ttizAYAAMwGAAAkAAAAAAAAAAAAAAAAAEVmBgBjb20vc3VuL3NvdXJjZS9kb2N0cmVlL0xpbmtUcmVlLmphdmFQSwECCgAKAAAIAAAGO6lKVR8uVBoGAAAaBgAAJgAAAAAAAAAAAAAAAABTbQYAY29tL3N1bi9zb3VyY2UvZG9jdHJlZS9IaWRkZW5UcmVlLmphdmFQSwECCgAKAAAIAAAGO6lKZCZfPHcFAAB3BQAAJwAAAAAAAAAAAAAAAACxcwYAY29tL3N1bi9zb3VyY2UvZG9jdHJlZS9Eb2NSb290VHJlZS5qYXZhUEsBAgoACgAACAAABjupSpHKr1n3BQAA9wUAACUAAAAAAAAAAAAAAAAAbXkGAGNvbS9zdW4vc291cmNlL2RvY3RyZWUvVmFsdWVUcmVlLmphdmFQSwECCgAKAAAIAAAGO6lK1ablrYMFAACDBQAAKgAAAAAAAAAAAAAAAACnfwYAY29tL3N1bi9zb3VyY2UvZG9jdHJlZS9Jbmhlcml0RG9jVHJlZS5qYXZhUEsBAgoACgAACAAABjupSqKDnbMOBgAADgYAACcAAAAAAAAAAAAAAAAAcoUGAGNvbS9zdW4vc291cmNlL2RvY3RyZWUvVmVyc2lvblRyZWUuamF2YVBLAQIKAAoAAAgAAAY7qUraP2RW7AYAAOwGAAAoAAAAAAAAAAAAAAAAAMWLBgBjb20vc3VuL3NvdXJjZS9kb2N0cmVlL1Byb3ZpZGVzVHJlZS5qYXZhUEsBAgoACgAACAAABjupSsA1DnBnBgAAZwYAACkAAAAAAAAAAAAAAAAA95IGAGNvbS9zdW4vc291cmNlL2RvY3RyZWUvRXJyb25lb3VzVHJlZS5qYXZhUEsBAgoACgAACAAABjupSk2vI3kzBgAAMwYAADAAAAAAAAAAAAAAAAAApZkGAGNvbS9zdW4vc291cmNlL2RvY3RyZWUvVW5rbm93bklubGluZVRhZ1RyZWUuamF2YVBLAQIKAAoAAAgAAAY7qUpBJtNYMQYAADEGAAAmAAAAAAAAAAAAAAAAACagBgBjb20vc3VuL3NvdXJjZS9kb2N0cmVlL1JldHVyblRyZWUuamF2YVBLAQIKAAoAAAgAAAY7qUpX3or2rgYAAK4GAAAlAAAAAAAAAAAAAAAAAJumBgBjb20vc3VuL3NvdXJjZS9kb2N0cmVlL0luZGV4VHJlZS5qYXZhUEsBAgoACgAACAAABjupShw/LKgJBgAACQYAACYAAAAAAAAAAAAAAAAAjK0GAGNvbS9zdW4vc291cmNlL2RvY3RyZWUvQXV0aG9yVHJlZS5qYXZhUEsBAgoACgAACAAABjupSrsDzLD5BQAA+QUAACoAAAAAAAAAAAAAAAAA2bMGAGNvbS9zdW4vc291cmNlL2RvY3RyZWUvSWRlbnRpZmllclRyZWUuamF2YVBLAQIKAAoAAAgAAAY7qUqL0Qo7kwcAAJMHAAAsAAAAAAAAAAAAAAAAABq6BgBjb20vc3VuL3NvdXJjZS9kb2N0cmVlL1N0YXJ0RWxlbWVudFRyZWUuamF2YVBLAQIKAAoAAAgAAAY7qUrf6s4xMQYAADEGAAAlAAAAAAAAAAAAAAAAAPfBBgBjb20vc3VuL3NvdXJjZS9kb2N0cmVlL1NpbmNlVHJlZS5qYXZhUEsBAgoACgAACAAABjupSqZ2g9suBgAALgYAAC8AAAAAAAAAAAAAAAAAa8gGAGNvbS9zdW4vc291cmNlL2RvY3RyZWUvVW5rbm93bkJsb2NrVGFnVHJlZS5qYXZhUEsBAgoACgAACAAABjupSstl9CG7HQAAux0AACMAAAAAAAAAAAAAAAAA5s4GAGNvbS9zdW4vc291cmNlL2RvY3RyZWUvRG9jVHJlZS5qYXZhUEsBAgoACgAACAAABjupSsPdXmakJAAApCQAACoAAAAAAAAAAAAAAAAA4uwGAGNvbS9zdW4vc291cmNlL2RvY3RyZWUvRG9jVHJlZVZpc2l0b3IuamF2YVBLAQIKAAoAAAgAAAY7qUpsiR4qcgcAAHIHAAArAAAAAAAAAAAAAAAAAM4RBwBjb20vc3VuL3NvdXJjZS9kb2N0cmVlL1NlcmlhbEZpZWxkVHJlZS5qYXZhUEsBAgoACgAACAAABjupSm5kVnvsBQAA7AUAACkAAAAAAAAAAAAAAAAAiRkHAGNvbS9zdW4vc291cmNlL2RvY3RyZWUvSW5saW5lVGFnVHJlZS5qYXZhUEsBAgoACgAACAAABjupSgAAAAAAAAAAAAAAAA4AAAAAAAAAAAAAAAAAvB8HAGNvbS9zdW4vdG9vbHMvUEsBAgoACgAACAAABjupSgAAAAAAAAAAAAAAABUAAAAAAAAAAAAAAAAA6B8HAGNvbS9zdW4vdG9vbHMvc2phdmFjL1BLAQIKAAoAAAgAAAY7qUqKZKDcXA8AAFwPAAApAAAAAAAAAAAAAAAAABsgBwBjb20vc3VuL3Rvb2xzL3NqYXZhYy9QdWJBcGlFeHRyYWN0b3IuamF2YVBLAQIKAAoAAAgAANJ9TUrmHxw4yQgAAMkIAAAmAAAAAAAAAAAAAAAAAL4vBwBjb20vc3VuL3Rvb2xzL3NqYXZhYy9Db21waWxlQ2h1bmsuamF2YVBLAQIKAAoAAAgAAAY7qUp++mO91SoAANUqAAAhAAAAAAAAAAAAAAAAAMs4BwBjb20vc3VuL3Rvb2xzL3NqYXZhYy9QYWNrYWdlLmphdmFQSwECCgAKAAAIAAAGO6lKVnfzeZojAACaIwAAKwAAAAAAAAAAAAAAAADfYwcAY29tL3N1bi90b29scy9zamF2YWMvQ29tcGlsZVByb3BlcnRpZXMuamF2YVBLAQIKAAoAAAgAAAY7qUqd2bhUqZ8AAKmfAAAkAAAAAAAAAAAAAAAAAMKHBwBjb20vc3VuL3Rvb2xzL3NqYXZhYy9KYXZhY1N0YXRlLmphdmFQSwECCgAKAAAIAAAGO6lKml8F93RAAAB0QAAALQAAAAAAAAAAAAAAAACtJwgAY29tL3N1bi90b29scy9zamF2YWMvQ29tcGlsZUphdmFQYWNrYWdlcy5qYXZhUEsBAgoACgAACAAABjupSgAAAAAAAAAAAAAAABoAAAAAAAAAAAAAAAAAbGgIAGNvbS9zdW4vdG9vbHMvc2phdmFjL2NvbXAvUEsBAgoACgAACAAABjupSr1FEHPbCgAA2woAACoAAAAAAAAAAAAAAAAApGgIAGNvbS9zdW4vdG9vbHMvc2phdmFjL2NvbXAvU21hcnRXcml0ZXIuamF2YVBLAQIKAAoAAAgAAAY7qUoAAAAAAAAAAAAAAAAnAAAAAAAAAAAAAAAAAMdzCABjb20vc3VuL3Rvb2xzL3NqYXZhYy9jb21wL2RlcGVuZGVuY2llcy9QSwECCgAKAAAIAAAGO6lKbkkWRgkRAAAJEQAAPgAAAAAAAAAAAAAAAAAMdAgAY29tL3N1bi90b29scy9zamF2YWMvY29tcC9kZXBlbmRlbmNpZXMvUHVibGljQXBpQ29sbGVjdG9yLmphdmFQSwECCgAKAAAIAAAGO6lKwEMHuUsgAABLIAAAQgAAAAAAAAAAAAAAAABxhQgAY29tL3N1bi90b29scy9zamF2YWMvY29tcC9kZXBlbmRlbmNpZXMvTmV3RGVwZW5kZW5jeUNvbGxlY3Rvci5qYXZhUEsBAgoACgAACAAABjupSkAwIEqKDQAAig0AACsAAAAAAAAAAAAAAAAAHKYIAGNvbS9zdW4vdG9vbHMvc2phdmFjL2NvbXAvUG9vbGVkU2phdmFjLmphdmFQSwECCgAKAAAIAAAGO6lKM5AKqwIVAAACFQAANQAAAAAAAAAAAAAAAADvswgAY29tL3N1bi90b29scy9zamF2YWMvY29tcC9QYXRoQW5kUGFja2FnZVZlcmlmaWVyLmphdmFQSwECCgAKAAAIAAAGO6lKCKJuUVUpAABVKQAALwAAAAAAAAAAAAAAAABEyQgAY29tL3N1bi90b29scy9zamF2YWMvY29tcC9TbWFydEZpbGVNYW5hZ2VyLmphdmFQSwECCgAKAAAIAAAGO6lK2m5o3F0aAABdGgAALAAAAAAAAAAAAAAAAADm8ggAY29tL3N1bi90b29scy9zamF2YWMvY29tcC9QdWJhcGlWaXNpdG9yLmphdmFQSwECCgAKAAAIAAAGO6lKEiKkCHsHAAB7BwAANQAAAAAAAAAAAAAAAACNDQkAY29tL3N1bi90b29scy9zamF2YWMvY29tcC9GaWxlT2JqZWN0V2l0aExvY2F0aW9uLmphdmFQSwECCgAKAAAIAAAGO6lKDjdSJBQRAAAUEQAALgAAAAAAAAAAAAAAAABbFQkAY29tL3N1bi90b29scy9zamF2YWMvY29tcC9TbWFydEZpbGVPYmplY3QuamF2YVBLAQIKAAoAAAgAAAY7qUqfKQhjOUQAADlEAAApAAAAAAAAAAAAAAAAALsmCQBjb20vc3VuL3Rvb2xzL3NqYXZhYy9jb21wL1NqYXZhY0ltcGwuamF2YVBLAQIKAAoAAAgAAAY7qUql3KclPw8AAD8PAAAmAAAAAAAAAAAAAAAAADtrCQBjb20vc3VuL3Rvb2xzL3NqYXZhYy9jb21wL1B1YkFQSXMuamF2YVBLAQIKAAoAAAgAAAY7qUqS2ICKZR0AAGUdAAAxAAAAAAAAAAAAAAAAAL56CQBjb20vc3VuL3Rvb2xzL3NqYXZhYy9jb21wL0NvbXBpbGF0aW9uU2VydmljZS5qYXZhUEsBAgoACgAACAAABjupSiisfw45CQAAOQkAADkAAAAAAAAAAAAAAAAAcpgJAGNvbS9zdW4vdG9vbHMvc2phdmFjL2NvbXAvSmF2YUZpbGVPYmplY3RXaXRoTG9jYXRpb24uamF2YVBLAQIKAAoAAAgAANJ9TUqqRkx7sQYAALEGAAAqAAAAAAAAAAAAAAAAAAKiCQBjb20vc3VuL3Rvb2xzL3NqYXZhYy9Qcm9ibGVtRXhjZXB0aW9uLmphdmFQSwECCgAKAAAIAAAGO6lKgbvJ7HkRAAB5EQAAIAAAAAAAAAAAAAAAAAD7qAkAY29tL3N1bi90b29scy9zamF2YWMvTW9kdWxlLmphdmFQSwECCgAKAAAIAAAGO6lK0Vfowo8TAACPEwAAIgAAAAAAAAAAAAAAAACyugkAY29tL3N1bi90b29scy9zamF2YWMvQ29weUZpbGUuamF2YVBLAQIKAAoAAAgAAAY7qUqWcqUYLhIAAC4SAAAdAAAAAAAAAAAAAAAAAIHOCQBjb20vc3VuL3Rvb2xzL3NqYXZhYy9Mb2cuamF2YVBLAQIKAAoAAAgAAAY7qUoAAAAAAAAAAAAAAAAcAAAAAAAAAAAAAAAAAOrgCQBjb20vc3VuL3Rvb2xzL3NqYXZhYy9wdWJhcGkvUEsBAgoACgAACAAABjupSlgMHh4vCAAALwgAADIAAAAAAAAAAAAAAAAAJOEJAGNvbS9zdW4vdG9vbHMvc2phdmFjL3B1YmFwaS9SZWZlcmVuY2VUeXBlRGVzYy5qYXZhUEsBAgoACgAACAAABjupSjjWRogrEQAAKxEAACoAAAAAAAAAAAAAAAAAo+kJAGNvbS9zdW4vdG9vbHMvc2phdmFjL3B1YmFwaS9QdWJNZXRob2QuamF2YVBLAQIKAAoAAAgAAAY7qUpOjHqAhQcAAIUHAAAuAAAAAAAAAAAAAAAAABb7CQBjb20vc3VuL3Rvb2xzL3NqYXZhYy9wdWJhcGkvQXJyYXlUeXBlRGVzYy5qYXZhUEsBAgoACgAACAAABjupSlj9rgFXCgAAVwoAADAAAAAAAAAAAAAAAAAA5wIKAGNvbS9zdW4vdG9vbHMvc2phdmFjL3B1YmFwaS9QdWJBcGlUeXBlUGFyYW0uamF2YVBLAQIKAAoAAAgAAAY7qUogUIoqygsAAMoLAAAnAAAAAAAAAAAAAAAAAIwNCgBjb20vc3VuL3Rvb2xzL3NqYXZhYy9wdWJhcGkvUHViVmFyLmphdmFQSwECCgAKAAAIAAAGO6lKD/yk83FFAABxRQAAJwAAAAAAAAAAAAAAAACbGQoAY29tL3N1bi90b29scy9zamF2YWMvcHViYXBpL1B1YkFwaS5qYXZhUEsBAgoACgAACAAABjupSjSu8ACcBwAAnAcAADIAAAAAAAAAAAAAAAAAUV8KAGNvbS9zdW4vdG9vbHMvc2phdmFjL3B1YmFwaS9QcmltaXRpdmVUeXBlRGVzYy5qYXZhUEsBAgoACgAACAAABjupSiNE4n4dFAAAHRQAACkAAAAAAAAAAAAAAAAAPWcKAGNvbS9zdW4vdG9vbHMvc2phdmFjL3B1YmFwaS9UeXBlRGVzYy5qYXZhUEsBAgoACgAACAAABjupShoU5HVTCAAAUwgAADAAAAAAAAAAAAAAAAAAoXsKAGNvbS9zdW4vdG9vbHMvc2phdmFjL3B1YmFwaS9UeXBlVmFyVHlwZURlc2MuamF2YVBLAQIKAAoAAAgAAAY7qUo/FBt3IgoAACIKAAAoAAAAAAAAAAAAAAAAAEKECgBjb20vc3VuL3Rvb2xzL3NqYXZhYy9wdWJhcGkvUHViVHlwZS5qYXZhUEsBAgoACgAACAAABjupSlAphO5pFAAAaRQAACUAAAAAAAAAAAAAAAAAqo4KAGNvbS9zdW4vdG9vbHMvc2phdmFjL1RyYW5zZm9ybWVyLmphdmFQSwECCgAKAAAIAAAGO6lKAAAAAAAAAAAAAAAAHAAAAAAAAAAAAAAAAABWowoAY29tL3N1bi90b29scy9zamF2YWMvc2VydmVyL1BLAQIKAAoAAAgAAAY7qUoAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAJCjCgBjb20vc3VuL3Rvb2xzL3NqYXZhYy9zZXJ2ZXIvbG9nL1BLAQIKAAoAAAgAAAY7qUqnJXFCIgsAACILAAA0AAAAAAAAAAAAAAAAAM6jCgBjb20vc3VuL3Rvb2xzL3NqYXZhYy9zZXJ2ZXIvbG9nL0xhenlJbml0RmlsZUxvZy5qYXZhUEsBAgoACgAACAAABjupSnfoKHXUCgAA1AoAADgAAAAAAAAAAAAAAAAAQq8KAGNvbS9zdW4vdG9vbHMvc2phdmFjL3NlcnZlci9sb2cvTG9nZ2luZ091dHB1dFN0cmVhbS5qYXZhUEsBAgoACgAACAAABjupSop0g62PCQAAjwkAADUAAAAAAAAAAAAAAAAAbLoKAGNvbS9zdW4vdG9vbHMvc2phdmFjL3NlcnZlci9Db21waWxhdGlvblN1YlJlc3VsdC5qYXZhUEsBAgoACgAACAAABjupSu1x5MFbDwAAWw8AACsAAAAAAAAAAAAAAAAATsQKAGNvbS9zdW4vdG9vbHMvc2phdmFjL3NlcnZlci9TZXJ2ZXJNYWluLmphdmFQSwECCgAKAAAIAAAGO6lKGMEXWdQmAADUJgAAKQAAAAAAAAAAAAAAAADy0woAY29tL3N1bi90b29scy9zamF2YWMvc2VydmVyL1BvcnRGaWxlLmphdmFQSwECCgAKAAAIAAAGO6lKzAhkDQYGAAAGBgAAKwAAAAAAAAAAAAAAAAAN+woAY29tL3N1bi90b29scy9zamF2YWMvc2VydmVyL1Rlcm1pbmFibGUuamF2YVBLAQIKAAoAAAgAAAY7qUq2tu/axwYAAMcGAAAnAAAAAAAAAAAAAAAAAFwBCwBjb20vc3VuL3Rvb2xzL3NqYXZhYy9zZXJ2ZXIvU2phdmFjLmphdmFQSwECCgAKAAAIAADSfU1KH2mQzjIIAAAyCAAAKAAAAAAAAAAAAAAAAABoCAsAY29tL3N1bi90b29scy9zamF2YWMvc2VydmVyL1N5c0luZm8uamF2YVBLAQIKAAoAAAgAAAY7qUq+6u70TiMAAE4jAAAtAAAAAAAAAAAAAAAAAOAQCwBjb20vc3VuL3Rvb2xzL3NqYXZhYy9zZXJ2ZXIvU2phdmFjU2VydmVyLmphdmFQSwECCgAKAAAIAAAGO6lKDlJhsGAPAABgDwAAMAAAAAAAAAAAAAAAAAB5NAsAY29tL3N1bi90b29scy9zamF2YWMvc2VydmVyL1BvcnRGaWxlTW9uaXRvci5qYXZhUEsBAgoACgAACAAABjupSp1N5m+BDwAAgQ8AADAAAAAAAAAAAAAAAAAAJ0QLAGNvbS9zdW4vdG9vbHMvc2phdmFjL3NlcnZlci9JZGxlUmVzZXRTamF2YWMuamF2YVBLAQIKAAoAAAgAAAY7qUpNKbKrbBMAAGwTAAAvAAAAAAAAAAAAAAAAAPZTCwBjb20vc3VuL3Rvb2xzL3NqYXZhYy9zZXJ2ZXIvUmVxdWVzdEhhbmRsZXIuamF2YVBLAQIKAAoAAAgAAAY7qUpUjM26hS4AAIUuAAAkAAAAAAAAAAAAAAAAAK9nCwBjb20vc3VuL3Rvb2xzL3NqYXZhYy9CdWlsZFN0YXRlLmphdmFQSwECCgAKAAAIAAAGO6lKAAAAAAAAAAAAAAAAHAAAAAAAAAAAAAAAAAB2lgsAY29tL3N1bi90b29scy9zamF2YWMvY2xpZW50L1BLAQIKAAoAAAgAAAY7qUoSxi70xwwAAMcMAAArAAAAAAAAAAAAAAAAALCWCwBjb20vc3VuL3Rvb2xzL3NqYXZhYy9jbGllbnQvQ2xpZW50TWFpbi5qYXZhUEsBAgoACgAACAAABjupSkHOczvgBQAA4AUAAD4AAAAAAAAAAAAAAAAAwKMLAGNvbS9zdW4vdG9vbHMvc2phdmFjL2NsaWVudC9Qb3J0RmlsZUluYWNjZXNzaWJsZUV4Y2VwdGlvbi5qYXZhUEsBAgoACgAACAAABjupSi9Z1pxGLQAARi0AAC0AAAAAAAAAAAAAAAAA/KkLAGNvbS9zdW4vdG9vbHMvc2phdmFjL2NsaWVudC9TamF2YWNDbGllbnQuamF2YVBLAQIKAAoAAAgAAAY7qUp7+y1n3yIAAN8iAAAeAAAAAAAAAAAAAAAAAI3XCwBjb20vc3VuL3Rvb2xzL3NqYXZhYy9VdGlsLmphdmFQSwECCgAKAAAIAAAGO6lK6nkfrRsIAAAbCAAAKQAAAAAAAAAAAAAAAACo+gsAY29tL3N1bi90b29scy9zamF2YWMvQXV0b0ZsdXNoV3JpdGVyLmphdmFQSwECCgAKAAAIAADSfU1KYVhCFHsIAAB7CAAAHgAAAAAAAAAAAAAAAAAKAwwAY29tL3N1bi90b29scy9zamF2YWMvTWFpbi5qYXZhUEsBAgoACgAACAAABjupSjbMEDohGAAAIRgAACkAAAAAAAAAAAAAAAAAwQsMAGNvbS9zdW4vdG9vbHMvc2phdmFjL0NsZWFuUHJvcGVydGllcy5qYXZhUEsBAgoACgAACAAABjupSk0iilixLgAAsS4AACAAAAAAAAAAAAAAAAAAKSQMAGNvbS9zdW4vdG9vbHMvc2phdmFjL1NvdXJjZS5qYXZhUEsBAgoACgAACAAABjupSgAAAAAAAAAAAAAAAB0AAAAAAAAAAAAAAAAAGFMMAGNvbS9zdW4vdG9vbHMvc2phdmFjL29wdGlvbnMvUEsBAgoACgAACAAABjupStFeDnJ7OgAAezoAACgAAAAAAAAAAAAAAAAAU1MMAGNvbS9zdW4vdG9vbHMvc2phdmFjL29wdGlvbnMvT3B0aW9uLmphdmFQSwECCgAKAAAIAAAGO6lKHJL3bwgRAAAIEQAAMAAAAAAAAAAAAAAAAAAUjgwAY29tL3N1bi90b29scy9zamF2YWMvb3B0aW9ucy9Tb3VyY2VMb2NhdGlvbi5qYXZhUEsBAgoACgAACAAA0n1NSlwo3erWCgAA1goAADIAAAAAAAAAAAAAAAAAap8MAGNvbS9zdW4vdG9vbHMvc2phdmFjL29wdGlvbnMvQXJndW1lbnRJdGVyYXRvci5qYXZhUEsBAgoACgAACAAABjupSjb3nP5QPwAAUD8AACkAAAAAAAAAAAAAAAAAkKoMAGNvbS9zdW4vdG9vbHMvc2phdmFjL29wdGlvbnMvT3B0aW9ucy5qYXZhUEsBAgoACgAACAAABjupStNwOBe2FgAAthYAAC4AAAAAAAAAAAAAAAAAJ+oMAGNvbS9zdW4vdG9vbHMvc2phdmFjL29wdGlvbnMvT3B0aW9uSGVscGVyLmphdmFQSwECCgAKAAAIAAAGO6lKAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAApAQ0AY29tL3N1bi90b29scy9qYXZhaC9QSwECCgAKAAAIAAAGO6lKAAAAAAAAAAAAAAAAHgAAAAAAAAAAAAAAAABbAQ0AY29tL3N1bi90b29scy9qYXZhaC9yZXNvdXJjZXMvUEsBAgoACgAACAAABjupSlh4Y0M5HQAAOR0AADMAAAAAAAAAAAAAAAAAlwENAGNvbS9zdW4vdG9vbHMvamF2YWgvcmVzb3VyY2VzL2wxMG5femhfQ04ucHJvcGVydGllc1BLAQIKAAoAAAgAANJ9TUp09xvd4AQAAOAEAAA5AAAAAAAAAAAAAAAAACEfDQBjb20vc3VuL3Rvb2xzL2phdmFoL3Jlc291cmNlcy92ZXJzaW9uLnByb3BlcnRpZXMtdGVtcGxhdGVQSwECCgAKAAAIAAAGO6lKk7YxDM0XAADNFwAALQAAAAAAAAAAAAAAAABYJA0AY29tL3N1bi90b29scy9qYXZhaC9yZXNvdXJjZXMvbDEwbi5wcm9wZXJ0aWVzUEsBAgoACgAACAAABjupSudcj2wCKwAAAisAADAAAAAAAAAAAAAAAAAAcDwNAGNvbS9zdW4vdG9vbHMvamF2YWgvcmVzb3VyY2VzL2wxMG5famEucHJvcGVydGllc1BLAQIKAAoAAAgAANJ9TUoXezJtOxgAADsYAAApAAAAAAAAAAAAAAAAAMBnDQBjb20vc3VuL3Rvb2xzL2phdmFoL05hdGl2ZUhlYWRlclRvb2wuamF2YVBLAQIKAAoAAAgAANJ9TUqAyVYXrwYAAK8GAAAmAAAAAAAAAAAAAAAAAEKADQBjb20vc3VuL3Rvb2xzL2phdmFoL0ludGVybmFsRXJyb3IuamF2YVBLAQIKAAoAAAgAAAY7qUojH6Ih2jIAANoyAAAcAAAAAAAAAAAAAAAAADWHDQBjb20vc3VuL3Rvb2xzL2phdmFoL0dlbi5qYXZhUEsBAgoACgAACAAABjupSmGOvw82ZAAANmQAACIAAAAAAAAAAAAAAAAASboNAGNvbS9zdW4vdG9vbHMvamF2YWgvSmF2YWhUYXNrLmphdmFQSwECCgAKAAAIAAAGO6lKHe4JshUJAAAVCQAAKQAAAAAAAAAAAAAAAAC/Hg4AY29tL3N1bi90b29scy9qYXZhaC9KYXZhaEZpbGVNYW5hZ2VyLmphdmFQSwECCgAKAAAIAAAGO6lKWv++HxgbAAAYGwAAHwAAAAAAAAAAAAAAAAAbKA4AY29tL3N1bi90b29scy9qYXZhaC9NYW5nbGUuamF2YVBLAQIKAAoAAAgAANJ9TUrq9tOEdh0AAHYdAAAcAAAAAAAAAAAAAAAAAHBDDgBjb20vc3VuL3Rvb2xzL2phdmFoL0pOSS5qYXZhUEsBAgoACgAACAAABjupSuHJAy5+FwAAfhcAAB0AAAAAAAAAAAAAAAAAIGEOAGNvbS9zdW4vdG9vbHMvamF2YWgvVXRpbC5qYXZhUEsBAgoACgAACAAA0n1NSjJ9LZ+vCAAArwgAAB0AAAAAAAAAAAAAAAAA2XgOAGNvbS9zdW4vdG9vbHMvamF2YWgvTWFpbi5qYXZhUEsBAgoACgAACAAA0n1NSo36MOIeDQAAHg0AACIAAAAAAAAAAAAAAAAAw4EOAGNvbS9zdW4vdG9vbHMvamF2YWgvSmF2YWhUb29sLmphdmFQSwECCgAKAAAIAAAGO6lKKawjHXQoAAB0KAAAJgAAAAAAAAAAAAAAAAAhjw4AY29tL3N1bi90b29scy9qYXZhaC9UeXBlU2lnbmF0dXJlLmphdmFQSwECCgAKAAAIAAAGO6lK94OjBMFkAADBZAAAHQAAAAAAAAAAAAAAAADZtw4AY29tL3N1bi90b29scy9qYXZhaC9MTE5JLmphdmFQSwECCgAKAAAIAAAGO6lKAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAADVHA8AY29tL3N1bi90b29scy9qYXZhYy9QSwECCgAKAAAIAAAGO6lKAAAAAAAAAAAAAAAAHgAAAAAAAAAAAAAAAAAHHQ8AY29tL3N1bi90b29scy9qYXZhYy9yZXNvdXJjZXMvUEsBAgoACgAACAAABjupSvR3CXrVOAAA1TgAAC4AAAAAAAAAAAAAAAAAQx0PAGNvbS9zdW4vdG9vbHMvamF2YWMvcmVzb3VyY2VzL2phdmFjLnByb3BlcnRpZXNQSwECCgAKAAAIAAAGO6lKU6V9DE89AgBPPQIANAAAAAAAAAAAAAAAAABkVg8AY29tL3N1bi90b29scy9qYXZhYy9yZXNvdXJjZXMvY29tcGlsZXJfamEucHJvcGVydGllc1BLAQIKAAoAAAgAANJ9TUoSFqnV2gQAANoEAAA5AAAAAAAAAAAAAAAAAAWUEQBjb20vc3VuL3Rvb2xzL2phdmFjL3Jlc291cmNlcy92ZXJzaW9uLnByb3BlcnRpZXMtdGVtcGxhdGVQSwECCgAKAAAIAAAGO6lKfJLwjSJrAAAiawAAMQAAAAAAAAAAAAAAAAA2mREAY29tL3N1bi90b29scy9qYXZhYy9yZXNvdXJjZXMvamF2YWNfamEucHJvcGVydGllc1BLAQIKAAoAAAgAAAY7qUo6BHIJfV0AAH1dAAAvAAAAAAAAAAAAAAAAAKcEEgBjb20vc3VuL3Rvb2xzL2phdmFjL3Jlc291cmNlcy9sZWdhY3kucHJvcGVydGllc1BLAQIKAAoAAAgAAAY7qUo79OsXQkgAAEJIAAA0AAAAAAAAAAAAAAAAAHFiEgBjb20vc3VuL3Rvb2xzL2phdmFjL3Jlc291cmNlcy9qYXZhY196aF9DTi5wcm9wZXJ0aWVzUEsBAgoACgAACAAABjupSjUGMv9vpQEAb6UBADcAAAAAAAAAAAAAAAAABasSAGNvbS9zdW4vdG9vbHMvamF2YWMvcmVzb3VyY2VzL2NvbXBpbGVyX3poX0NOLnByb3BlcnRpZXNQSwECCgAKAAAIAAAGO6lK9nZ88slpAQDJaQEAMQAAAAAAAAAAAAAAAADJUBQAY29tL3N1bi90b29scy9qYXZhYy9yZXNvdXJjZXMvY29tcGlsZXIucHJvcGVydGllc1BLAQIKAAoAAAgAAAY7qUqB+A/upocAAKaHAAArAAAAAAAAAAAAAAAAAOG6FQBjb20vc3VuL3Rvb2xzL2phdmFjL3Jlc291cmNlcy9jdC5wcm9wZXJ0aWVzUEsBAgoACgAACAAABjupSgAAAAAAAAAAAAAAABsAAAAAAAAAAAAAAAAA0EIWAGNvbS9zdW4vdG9vbHMvamF2YWMvcGFyc2VyL1BLAQIKAAoAAAgAANJ9TUrL9nRwqAsAAKgLAAAzAAAAAAAAAAAAAAAAAAlDFgBjb20vc3VuL3Rvb2xzL2phdmFjL3BhcnNlci9MYXp5RG9jQ29tbWVudFRhYmxlLmphdmFQSwECCgAKAAAIAADSfU1Khpraebg3AAC4NwAAJgAAAAAAAAAAAAAAAAACTxYAY29tL3N1bi90b29scy9qYXZhYy9wYXJzZXIvVG9rZW5zLmphdmFQSwECCgAKAAAIAAAGO6lKBpQ7hK0IAACtCAAAJgAAAAAAAAAAAAAAAAD+hhYAY29tL3N1bi90b29scy9qYXZhYy9wYXJzZXIvUGFyc2VyLmphdmFQSwECCgAKAAAIAAAGO6lKT2/5XoSrAACEqwAAMAAAAAAAAAAAAAAAAADvjxYAY29tL3N1bi90b29scy9qYXZhYy9wYXJzZXIvRG9jQ29tbWVudFBhcnNlci5qYXZhUEsBAgoACgAACAAA0n1NSosWDyGhEAAAoRAAACcAAAAAAAAAAAAAAAAAwTsXAGNvbS9zdW4vdG9vbHMvamF2YWMvcGFyc2VyL1NjYW5uZXIuamF2YVBLAQIKAAoAAAgAAAY7qUqvDr1DdhkAAHYZAAAvAAAAAAAAAAAAAAAAAKdMFwBjb20vc3VuL3Rvb2xzL2phdmFjL3BhcnNlci9SZWZlcmVuY2VQYXJzZXIuamF2YVBLAQIKAAoAAAgAAAY7qUr5nm3XO4cAADuHAAAtAAAAAAAAAAAAAAAAAGpmFwBjb20vc3VuL3Rvb2xzL2phdmFjL3BhcnNlci9KYXZhVG9rZW5pemVyLmphdmFQSwECCgAKAAAIAADSfU1KkDc2DHgKAAB4CgAAJQAAAAAAAAAAAAAAAADw7RcAY29tL3N1bi90b29scy9qYXZhYy9wYXJzZXIvTGV4ZXIuamF2YVBLAQIKAAoAAAgAAAY7qUrJygOZBnwCAAZ8AgArAAAAAAAAAAAAAAAAAKv4FwBjb20vc3VuL3Rvb2xzL2phdmFjL3BhcnNlci9KYXZhY1BhcnNlci5qYXZhUEsBAgoACgAACAAA0n1NSj4QK6A3DQAANw0AAC4AAAAAAAAAAAAAAAAA+nQaAGNvbS9zdW4vdG9vbHMvamF2YWMvcGFyc2VyL1NjYW5uZXJGYWN0b3J5LmphdmFQSwECCgAKAAAIAAAGO6lKbCalCxJNAAASTQAAMAAAAAAAAAAAAAAAAAB9ghoAY29tL3N1bi90b29scy9qYXZhYy9wYXJzZXIvSmF2YWRvY1Rva2VuaXplci5qYXZhUEsBAgoACgAACAAABjupSqPy4K8ZDgAAGQ4AAC0AAAAAAAAAAAAAAAAA3c8aAGNvbS9zdW4vdG9vbHMvamF2YWMvcGFyc2VyL1BhcnNlckZhY3RvcnkuamF2YVBLAQIKAAoAAAgAANJ9TUrnXXsp6yIAAOsiAAAtAAAAAAAAAAAAAAAAAEHeGgBjb20vc3VuL3Rvb2xzL2phdmFjL3BhcnNlci9Vbmljb2RlUmVhZGVyLmphdmFQSwECCgAKAAAIAAAGO6lKAAAAAAAAAAAAAAAAGQAAAAAAAAAAAAAAAAB3ARsAY29tL3N1bi90b29scy9qYXZhYy9maWxlL1BLAQIKAAoAAAgAAAY7qUpoZPjN96UAAPelAAAuAAAAAAAAAAAAAAAAAK4BGwBjb20vc3VuL3Rvb2xzL2phdmFjL2ZpbGUvSmF2YWNGaWxlTWFuYWdlci5qYXZhUEsBAgoACgAACAAABjupSoO1u0dnJQAAZyUAACYAAAAAAAAAAAAAAAAA8acbAGNvbS9zdW4vdG9vbHMvamF2YWMvZmlsZS9KUlRJbmRleC5qYXZhUEsBAgoACgAACAAABjupSo1aSU9JEQAASREAACQAAAAAAAAAAAAAAAAAnM0bAGNvbS9zdW4vdG9vbHMvamF2YWMvZmlsZS9GU0luZm8uamF2YVBLAQIKAAoAAAgAAAY7qUoOPBNTRlIAAEZSAAAsAAAAAAAAAAAAAAAAACffGwBjb20vc3VuL3Rvb2xzL2phdmFjL2ZpbGUvUGF0aEZpbGVPYmplY3QuamF2YVBLAQIKAAoAAAgAAAY7qUr2QgoA6kkAAOpJAAAtAAAAAAAAAAAAAAAAALcxHABjb20vc3VuL3Rvb2xzL2phdmFjL2ZpbGUvQmFzZUZpbGVNYW5hZ2VyLmphdmFQSwECCgAKAAAIAAAGO6lKJw7Jqb8UAQC/FAEAJwAAAAAAAAAAAAAAAADsexwAY29tL3N1bi90b29scy9qYXZhYy9maWxlL0xvY2F0aW9ucy5qYXZhUEsBAgoACgAACAAABjupSjiNRF/2DwAA9g8AACkAAAAAAAAAAAAAAAAA8JAdAGNvbS9zdW4vdG9vbHMvamF2YWMvZmlsZS9DYWNoZUZTSW5mby5qYXZhUEsBAgoACgAACAAABjupShA8XOB6GQAAehkAACoAAAAAAAAAAAAAAAAALaEdAGNvbS9zdW4vdG9vbHMvamF2YWMvZmlsZS9SZWxhdGl2ZVBhdGguamF2YVBLAQIKAAoAAAgAANJ9TUoAAAAAAAAAAAAAAAAdAAAAAAAAAAAAAAAAAO+6HQBjb20vc3VuL3Rvb2xzL2phdmFjL3NlcnZpY2VzL1BLAQIKAAoAAAgAANJ9TUrRjTxVHQAAAB0AAAA5AAAAAAAAAAAAAAAAACq7HQBjb20vc3VuL3Rvb2xzL2phdmFjL3NlcnZpY2VzL2phdmF4LnRvb2xzLkphdmFDb21waWxlclRvb2xQSwECCgAKAAAIAAAGO6lKAAAAAAAAAAAAAAAAGAAAAAAAAAAAAAAAAACeux0AY29tL3N1bi90b29scy9qYXZhYy9hcGkvUEsBAgoACgAACAAA0n1NSoTrIVinCgAApwoAACgAAAAAAAAAAAAAAAAA1LsdAGNvbS9zdW4vdG9vbHMvamF2YWMvYXBpL0Zvcm1hdHRhYmxlLmphdmFQSwECCgAKAAAIAADSfU1KEi+0hGQdAABkHQAANAAAAAAAAAAAAAAAAADBxh0AY29tL3N1bi90b29scy9qYXZhYy9hcGkvV3JhcHBpbmdKYXZhRmlsZU1hbmFnZXIuamF2YVBLAQIKAAoAAAgAAAY7qUoLwrnukE8AAJBPAAAqAAAAAAAAAAAAAAAAAHfkHQBjb20vc3VuL3Rvb2xzL2phdmFjL2FwaS9KYXZhY1Rhc2tJbXBsLmphdmFQSwECCgAKAAAIAADSfU1KnfPyPkoJAABKCQAAJQAAAAAAAAAAAAAAAABPNB4AY29tL3N1bi90b29scy9qYXZhYy9hcGkvTWVzc2FnZXMuamF2YVBLAQIKAAoAAAgAAAY7qUrG4SBoRhIAAEYSAAAnAAAAAAAAAAAAAAAAANw9HgBjb20vc3VuL3Rvb2xzL2phdmFjL2FwaS9KYXZhY1Njb3BlLmphdmFQSwECCgAKAAAIAAAGO6lKSwNeJ1EjAABRIwAAJgAAAAAAAAAAAAAAAABnUB4AY29tL3N1bi90b29scy9qYXZhYy9hcGkvSmF2YWNUb29sLmphdmFQSwECCgAKAAAIAAAGO6lK8ApFJgl2AAAJdgAALgAAAAAAAAAAAAAAAAD8cx4AY29tL3N1bi90b29scy9qYXZhYy9hcGkvQ2xpZW50Q29kZVdyYXBwZXIuamF2YVBLAQIKAAoAAAgAAAY7qUqCufc+/bQAAP20AAAnAAAAAAAAAAAAAAAAAFHqHgBjb20vc3VuL3Rvb2xzL2phdmFjL2FwaS9KYXZhY1RyZWVzLmphdmFQSwECCgAKAAAIAAAGO6lK1TqUHZkcAACZHAAAMAAAAAAAAAAAAAAAAACTnx8AY29tL3N1bi90b29scy9qYXZhYy9hcGkvRGlhZ25vc3RpY0Zvcm1hdHRlci5qYXZhUEsBAgoACgAACAAABjupSpWtTVySIAAAkiAAACsAAAAAAAAAAAAAAAAAerwfAGNvbS9zdW4vdG9vbHMvamF2YWMvYXBpL0Jhc2ljSmF2YWNUYXNrLmphdmFQSwECCgAKAAAIAAAGO6lKnRwU/4MSAACDEgAALgAAAAAAAAAAAAAAAABV3R8AY29tL3N1bi90b29scy9qYXZhYy9hcGkvTXVsdGlUYXNrTGlzdGVuZXIuamF2YVBLAQIKAAoAAAgAALE8qUoAAAAAAAAAAAAAAAAZAAAAAAAAAAAAAAAAACTwHwBjb20vc3VuL3Rvb2xzL2phdmFjL2NvbXAvUEsBAgoACgAACAAArjypSmPdoDZAwQAAQMEAACoAAAAAAAAAAAAAAAAAW/AfAGNvbS9zdW4vdG9vbHMvamF2YWMvY29tcC9EZWZlcnJlZEF0dHIuamF2YVBLAQIKAAoAAAgAAAY7qUp1hgtJHJ8BAByfAQAiAAAAAAAAAAAAAAAAAOOxIABjb20vc3VuL3Rvb2xzL2phdmFjL2NvbXAvRmxvdy5qYXZhUEsBAgoACgAACAAABjupShqKWjoriwAAK4sAACcAAAAAAAAAAAAAAAAAP1EiAGNvbS9zdW4vdG9vbHMvamF2YWMvY29tcC9PcGVyYXRvcnMuamF2YVBLAQIKAAoAAAgAAAY7qUrVJZEqK14AACteAAAjAAAAAAAAAAAAAAAAAK/cIgBjb20vc3VuL3Rvb2xzL2phdmFjL2NvbXAvRW50ZXIuamF2YVBLAQIKAAoAAAgAANJ9TUo/zC9hQQoAAEEKAAAmAAAAAAAAAAAAAAAAABs7IwBjb20vc3VuL3Rvb2xzL2phdmFjL2NvbXAvVHlwZUVudnMuamF2YVBLAQIKAAoAAAgAANJ9TUocHHhqLBcAACwXAAAiAAAAAAAAAAAAAAAAAKBFIwBjb20vc3VuL3Rvb2xzL2phdmFjL2NvbXAvVG9kby5qYXZhUEsBAgoACgAACAAAsTypSpNsXUGrOAEAqzgBACMAAAAAAAAAAAAAAAAADF0jAGNvbS9zdW4vdG9vbHMvamF2YWMvY29tcC9JbmZlci5qYXZhUEsBAgoACgAACAAABjupSjREyxU/FQAAPxUAACkAAAAAAAAAAAAAAAAA+JUkAGNvbS9zdW4vdG9vbHMvamF2YWMvY29tcC9BdHRyQ29udGV4dC5qYXZhUEsBAgoACgAACAAABjupSgwGzl5KvgAASr4AACcAAAAAAAAAAAAAAAAAfqskAGNvbS9zdW4vdG9vbHMvamF2YWMvY29tcC9UeXBlRW50ZXIuamF2YVBLAQIKAAoAAAgAAAY7qUqGmg+60UMAANFDAAApAAAAAAAAAAAAAAAAAA1qJQBjb20vc3VuL3Rvb2xzL2phdmFjL2NvbXAvTWVtYmVyRW50ZXIuamF2YVBLAQIKAAoAAAgAAAY7qUoRzaix64gCAOuIAgAjAAAAAAAAAAAAAAAAACWuJQBjb20vc3VuL3Rvb2xzL2phdmFjL2NvbXAvTG93ZXIuamF2YVBLAQIKAAoAAAgAAAY7qUr0e6w2yswAAMrMAAAmAAAAAAAAAAAAAAAAAFE3KABjb20vc3VuL3Rvb2xzL2phdmFjL2NvbXAvQW5ub3RhdGUuamF2YVBLAQIKAAoAAAgAAAY7qUrSxKZJKxsDACsbAwAlAAAAAAAAAAAAAAAAAF8EKQBjb20vc3VuL3Rvb2xzL2phdmFjL2NvbXAvUmVzb2x2ZS5qYXZhUEsBAgoACgAACAAABjupStS9NJoRSwAAEUsAACYAAAAAAAAAAAAAAAAAzR8sAGNvbS9zdW4vdG9vbHMvamF2YWMvY29tcC9BbmFseXplci5qYXZhUEsBAgoACgAACAAABjupSi0V665ibgIAYm4CACMAAAAAAAAAAAAAAAAAImssAGNvbS9zdW4vdG9vbHMvamF2YWMvY29tcC9DaGVjay5qYXZhUEsBAgoACgAACAAABjupSt3IHKIaoQAAGqEAACgAAAAAAAAAAAAAAAAAxdkuAGNvbS9zdW4vdG9vbHMvamF2YWMvY29tcC9UcmFuc1R5cGVzLmphdmFQSwECCgAKAAAIAAAGO6lKOCn/GnBjAwBwYwMAIgAAAAAAAAAAAAAAAAAley8AY29tL3N1bi90b29scy9qYXZhYy9jb21wL0F0dHIuamF2YVBLAQIKAAoAAAgAAAY7qUpmBQY952sAAOdrAAAqAAAAAAAAAAAAAAAAANXeMgBjb20vc3VuL3Rvb2xzL2phdmFjL2NvbXAvQXJndW1lbnRBdHRyLmphdmFQSwECCgAKAAAIAAAGO6lK3/72DW0+AABtPgAAJwAAAAAAAAAAAAAAAAAESzMAY29tL3N1bi90b29scy9qYXZhYy9jb21wL0NvbnN0Rm9sZC5qYXZhUEsBAgoACgAACAAA0n1NSiBtRcctBwAALQcAACwAAAAAAAAAAAAAAAAAtokzAGNvbS9zdW4vdG9vbHMvamF2YWMvY29tcC9BdHRyQ29udGV4dEVudi5qYXZhUEsBAgoACgAACAAA0n1NSv3hDOqjFAAAoxQAACEAAAAAAAAAAAAAAAAALZEzAGNvbS9zdW4vdG9vbHMvamF2YWMvY29tcC9FbnYuamF2YVBLAQIKAAoAAAgAAAY7qUrh2b5YewsBAHsLAQAlAAAAAAAAAAAAAAAAAA+mMwBjb20vc3VuL3Rvb2xzL2phdmFjL2NvbXAvTW9kdWxlcy5qYXZhUEsBAgoACgAACAAA0n1NSspkr7mxDAAAsQwAACsAAAAAAAAAAAAAAAAAzbE0AGNvbS9zdW4vdG9vbHMvamF2YWMvY29tcC9Db21waWxlU3RhdGVzLmphdmFQSwECCgAKAAAIAAAGO6lK/Nk1kSeMAQAnjAEALAAAAAAAAAAAAAAAAADHvjQAY29tL3N1bi90b29scy9qYXZhYy9jb21wL0xhbWJkYVRvTWV0aG9kLmphdmFQSwECCgAKAAAIAAAGO6lKik3o0AhQAAAIUAAALgAAAAAAAAAAAAAAAAA4SzYAY29tL3N1bi90b29scy9qYXZhYy9jb21wL0luZmVyZW5jZUNvbnRleHQuamF2YVBLAQIKAAoAAAgAAAY7qUoAAAAAAAAAAAAAAAAdAAAAAAAAAAAAAAAAAIybNgBjb20vc3VuL3Rvb2xzL2phdmFjL3BsYXRmb3JtL1BLAQIKAAoAAAgAAAY7qUoDu+OmsQwAALEMAAAvAAAAAAAAAAAAAAAAAMebNgBjb20vc3VuL3Rvb2xzL2phdmFjL3BsYXRmb3JtL1BsYXRmb3JtVXRpbHMuamF2YVBLAQIKAAoAAAgAAAY7qUoKXfieBQYAAAUGAAAuAAAAAAAAAAAAAAAAAMWoNgBjb20vc3VuL3Rvb2xzL2phdmFjL3BsYXRmb3JtL3BhY2thZ2UtaW5mby5qYXZhUEsBAgoACgAACAAABjupSrt8JBRoGQAAaBkAADUAAAAAAAAAAAAAAAAAFq82AGNvbS9zdW4vdG9vbHMvamF2YWMvcGxhdGZvcm0vSkRLUGxhdGZvcm1Qcm92aWRlci5qYXZhUEsBAgoACgAACAAABjupSoyfVAr5CQAA+QkAADIAAAAAAAAAAAAAAAAA0cg2AGNvbS9zdW4vdG9vbHMvamF2YWMvcGxhdGZvcm0vUGxhdGZvcm1Qcm92aWRlci5qYXZhUEsBAgoACgAACAAABjupSjwftPpVEAAAVRAAADUAAAAAAAAAAAAAAAAAGtM2AGNvbS9zdW4vdG9vbHMvamF2YWMvcGxhdGZvcm0vUGxhdGZvcm1EZXNjcmlwdGlvbi5qYXZhUEsBAgoACgAACAAABjupSgAAAAAAAAAAAAAAABkAAAAAAAAAAAAAAAAAwuM2AGNvbS9zdW4vdG9vbHMvamF2YWMvdHJlZS9QSwECCgAKAAAIAAAGO6lKG9wxXg+XAQAPlwEAJAAAAAAAAAAAAAAAAAD54zYAY29tL3N1bi90b29scy9qYXZhYy90cmVlL0pDVHJlZS5qYXZhUEsBAgoACgAACAAABjupShWCXTpDRgAAQ0YAACcAAAAAAAAAAAAAAAAASns4AGNvbS9zdW4vdG9vbHMvamF2YWMvdHJlZS9Eb2NQcmV0dHkuamF2YVBLAQIKAAoAAAgAAAY7qUrRAHupWWcAAFlnAAAqAAAAAAAAAAAAAAAAANLBOABjb20vc3VuL3Rvb2xzL2phdmFjL3RyZWUvRG9jVHJlZU1ha2VyLmphdmFQSwECCgAKAAAIAAAGO6lKN4VZo3VTAAB1UwAAKAAAAAAAAAAAAAAAAABzKTkAY29tL3N1bi90b29scy9qYXZhYy90cmVlL1RyZWVDb3BpZXIuamF2YVBLAQIKAAoAAAgAAAY7qUrU/e0w86QAAPOkAAAmAAAAAAAAAAAAAAAAAC59OQBjb20vc3VuL3Rvb2xzL2phdmFjL3RyZWUvVHJlZUluZm8uamF2YVBLAQIKAAoAAAgAAAY7qUobl2hyP5IAAD+SAAAnAAAAAAAAAAAAAAAAAGUiOgBjb20vc3VuL3Rvb2xzL2phdmFjL3RyZWUvVHJlZU1ha2VyLmphdmFQSwECCgAKAAAIAAAGO6lKYVWK2lm6AABZugAAJAAAAAAAAAAAAAAAAADptDoAY29tL3N1bi90b29scy9qYXZhYy90cmVlL1ByZXR0eS5qYXZhUEsBAgoACgAACAAABjupSttHn/gEdgAABHYAACQAAAAAAAAAAAAAAAAAhG87AGNvbS9zdW4vdG9vbHMvamF2YWMvdHJlZS9EQ1RyZWUuamF2YVBLAQIKAAoAAAgAANJ9TUos/2Qz+DUAAPg1AAAsAAAAAAAAAAAAAAAAAMrlOwBjb20vc3VuL3Rvb2xzL2phdmFjL3RyZWUvVHJlZVRyYW5zbGF0b3IuamF2YVBLAQIKAAoAAAgAAAY7qUq+TXjK5AkAAOQJAAAtAAAAAAAAAAAAAAAAAAwcPABjb20vc3VuL3Rvb2xzL2phdmFjL3RyZWUvRG9jQ29tbWVudFRhYmxlLmphdmFQSwECCgAKAAAIAADSfU1Kjltn7DIKAAAyCgAAKQAAAAAAAAAAAAAAAAA7JjwAY29tL3N1bi90b29scy9qYXZhYy90cmVlL0VuZFBvc1RhYmxlLmphdmFQSwECCgAKAAAIAAAGO6lKsn0K6eAkAADgJAAAKQAAAAAAAAAAAAAAAAC0MDwAY29tL3N1bi90b29scy9qYXZhYy90cmVlL1RyZWVTY2FubmVyLmphdmFQSwECCgAKAAAIAAAGO6lKAAAAAAAAAAAAAAAAHwAAAAAAAAAAAAAAAADbVTwAY29tL3N1bi90b29scy9qYXZhYy9wcm9jZXNzaW5nL1BLAQIKAAoAAAgAANJ9TUqi8Gsd0QYAANEGAAA9AAAAAAAAAAAAAAAAABhWPABjb20vc3VuL3Rvb2xzL2phdmFjL3Byb2Nlc3NpbmcvQW5ub3RhdGlvblByb2Nlc3NpbmdFcnJvci5qYXZhUEsBAgoACgAACAAABjupSsR+H2i7JwAAuycAADkAAAAAAAAAAAAAAAAARF08AGNvbS9zdW4vdG9vbHMvamF2YWMvcHJvY2Vzc2luZy9KYXZhY1JvdW5kRW52aXJvbm1lbnQuamF2YVBLAQIKAAoAAAgAAAY7qUr9LZrp3RgAAN0YAAAxAAAAAAAAAAAAAAAAAFaFPABjb20vc3VuL3Rvb2xzL2phdmFjL3Byb2Nlc3NpbmcvSmF2YWNNZXNzYWdlci5qYXZhUEsBAgoACgAACAAABjupSmB9nSyKWwAAilsAADUAAAAAAAAAAAAAAAAAgp48AGNvbS9zdW4vdG9vbHMvamF2YWMvcHJvY2Vzc2luZy9QcmludGluZ1Byb2Nlc3Nvci5qYXZhUEsBAgoACgAACAAABjupSqUu8P2YcQAAmHEAAC4AAAAAAAAAAAAAAAAAX/o8AGNvbS9zdW4vdG9vbHMvamF2YWMvcHJvY2Vzc2luZy9KYXZhY0ZpbGVyLmphdmFQSwECCgAKAAAIAADSfU1KrwDQiv0VAAD9FQAAMAAAAAAAAAAAAAAAAABDbD0AY29tL3N1bi90b29scy9qYXZhYy9wcm9jZXNzaW5nL1NlcnZpY2VQcm94eS5qYXZhUEsBAgoACgAACAAABjupSi18l7u6BQEAugUBAD4AAAAAAAAAAAAAAAAAjoI9AGNvbS9zdW4vdG9vbHMvamF2YWMvcHJvY2Vzc2luZy9KYXZhY1Byb2Nlc3NpbmdFbnZpcm9ubWVudC5qYXZhUEsBAgoACgAACAAABjupSgAAAAAAAAAAAAAAABkAAAAAAAAAAAAAAAAApIg+AGNvbS9zdW4vdG9vbHMvamF2YWMvdXRpbC9QSwECCgAKAAAIAAAGO6lKJszG0+MqAADjKgAAIgAAAAAAAAAAAAAAAADbiD4AY29tL3N1bi90b29scy9qYXZhYy91dGlsL0JpdHMuamF2YVBLAQIKAAoAAAgAAAY7qUq0sJFxpToAAKU6AAAqAAAAAAAAAAAAAAAAAP6zPgBjb20vc3VuL3Rvb2xzL2phdmFjL3V0aWwvRGVwZW5kZW5jaWVzLmphdmFQSwECCgAKAAAIAAAGO6lKNRJRGrtpAAC7aQAANQAAAAAAAAAAAAAAAADr7j4AY29tL3N1bi90b29scy9qYXZhYy91dGlsL1JpY2hEaWFnbm9zdGljRm9ybWF0dGVyLmphdmFQSwECCgAKAAAIAAAGO6lKZRo2ZvYaAAD2GgAAKAAAAAAAAAAAAAAAAAD5WD8AY29tL3N1bi90b29scy9qYXZhYy91dGlsL0xpc3RCdWZmZXIuamF2YVBLAQIKAAoAAAgAANJ9TUpOV5qvxBsAAMQbAAAuAAAAAAAAAAAAAAAAADV0PwBjb20vc3VuL3Rvb2xzL2phdmFjL3V0aWwvRGlhZ25vc3RpY1NvdXJjZS5qYXZhUEsBAgoACgAACAAABjupSmdQI+WjEgAAoxIAADsAAAAAAAAAAAAAAAAARZA/AGNvbS9zdW4vdG9vbHMvamF2YWMvdXRpbC9Gb3J3YXJkaW5nRGlhZ25vc3RpY0Zvcm1hdHRlci5qYXZhUEsBAgoACgAACAAABjupSrTNu9ohQQAAIUEAACkAAAAAAAAAAAAAAAAAQaM/AGNvbS9zdW4vdG9vbHMvamF2YWMvdXRpbC9BYnN0cmFjdExvZy5qYXZhUEsBAgoACgAACAAABjupSo7enhU/CAAAPwgAACoAAAAAAAAAAAAAAAAAqeQ/AGNvbS9zdW4vdG9vbHMvamF2YWMvdXRpbC9Nb2R1bGVIZWxwZXIuamF2YVBLAQIKAAoAAAgAAAY7qUrEIPZfok4AAKJOAAA5AAAAAAAAAAAAAAAAADDtPwBjb20vc3VuL3Rvb2xzL2phdmFjL3V0aWwvQWJzdHJhY3REaWFnbm9zdGljRm9ybWF0dGVyLmphdmFQSwECCgAKAAAIAADSfU1KlIa8XlAGAABQBgAAJAAAAAAAAAAAAAAAAAApPEAAY29tL3N1bi90b29scy9qYXZhYy91dGlsL0ZpbHRlci5qYXZhUEsBAgoACgAACAAABjupSrfPiBTidQAA4nUAACoAAAAAAAAAAAAAAAAAu0JAAGNvbS9zdW4vdG9vbHMvamF2YWMvdXRpbC9KQ0RpYWdub3N0aWMuamF2YVBLAQIKAAoAAAgAANJ9TUoPf/HdjCgAAIwoAAAmAAAAAAAAAAAAAAAAAOW4QABjb20vc3VuL3Rvb2xzL2phdmFjL3V0aWwvUG9zaXRpb24uamF2YVBLAQIKAAoAAAgAAAY7qUroIoaMtBwAALQcAAAlAAAAAAAAAAAAAAAAALXhQABjb20vc3VuL3Rvb2xzL2phdmFjL3V0aWwvQ29udGV4dC5qYXZhUEsBAgoACgAACAAABjupSm6ucTzfEQAA3xEAACQAAAAAAAAAAAAAAAAArP5AAGNvbS9zdW4vdG9vbHMvamF2YWMvdXRpbC9Bc3NlcnQuamF2YVBLAQIKAAoAAAgAANJ9TUpzVgvmhAsAAIQLAAApAAAAAAAAAAAAAAAAAM0QQQBjb20vc3VuL3Rvb2xzL2phdmFjL3V0aWwvU3RyaW5nVXRpbHMuamF2YVBLAQIKAAoAAAgAAAY7qUp8A2Kb3gwAAN4MAAAnAAAAAAAAAAAAAAAAAJgcQQBjb20vc3VuL3Rvb2xzL2phdmFjL3V0aWwvSXRlcmF0b3JzLmphdmFQSwECCgAKAAAIAADSfU1K6Z83ZfMGAADzBgAAMQAAAAAAAAAAAAAAAAC7KUEAY29tL3N1bi90b29scy9qYXZhYy91dGlsL0NsaWVudENvZGVFeGNlcHRpb24uamF2YVBLAQIKAAoAAAgAAAY7qUoI5s6IoEAAAKBAAAAiAAAAAAAAAAAAAAAAAP0wQQBjb20vc3VuL3Rvb2xzL2phdmFjL3V0aWwvTGlzdC5qYXZhUEsBAgoACgAACAAABjupSurT1SLZDQAA2Q0AACsAAAAAAAAAAAAAAAAA3XFBAGNvbS9zdW4vdG9vbHMvamF2YWMvdXRpbC9NYXRjaGluZ1V0aWxzLmphdmFQSwECCgAKAAAIAADSfU1KbILSWCcLAAAnCwAAJAAAAAAAAAAAAAAAAAD/f0EAY29tL3N1bi90b29scy9qYXZhYy91dGlsL1dhcm5lci5qYXZhUEsBAgoACgAACAAABjupSq4nU1VTIwAAUyMAACgAAAAAAAAAAAAAAAAAaItBAGNvbS9zdW4vdG9vbHMvamF2YWMvdXRpbC9HcmFwaFV0aWxzLmphdmFQSwECCgAKAAAIAADSfU1KLZBrSTwJAAA8CQAALgAAAAAAAAAAAAAAAAABr0EAY29tL3N1bi90b29scy9qYXZhYy91dGlsL0xheW91dENoYXJhY3RlcnMuamF2YVBLAQIKAAoAAAgAANJ9TUr1G3MGJAoAACQKAAAoAAAAAAAAAAAAAAAAAIm4QQBjb20vc3VuL3Rvb2xzL2phdmFjL3V0aWwvRmF0YWxFcnJvci5qYXZhUEsBAgoACgAACAAA0n1NSnh4nY4cDQAAHA0AACgAAAAAAAAAAAAAAAAA88JBAGNvbS9zdW4vdG9vbHMvamF2YWMvdXRpbC9BcnJheVV0aWxzLmphdmFQSwECCgAKAAAIAAAGO6lKgVkL9h4eAAAeHgAAIgAAAAAAAAAAAAAAAABV0EEAY29tL3N1bi90b29scy9qYXZhYy91dGlsL05hbWUuamF2YVBLAQIKAAoAAAgAAAY7qUqFBUDr0z8AANM/AAA2AAAAAAAAAAAAAAAAALPuQQBjb20vc3VuL3Rvb2xzL2phdmFjL3V0aWwvQmFzaWNEaWFnbm9zdGljRm9ybWF0dGVyLmphdmFQSwECCgAKAAAIAAAGO6lKf8PBapcWAACXFgAANAAAAAAAAAAAAAAAAADaLkIAY29tL3N1bi90b29scy9qYXZhYy91dGlsL1Jhd0RpYWdub3N0aWNGb3JtYXR0ZXIuamF2YVBLAQIKAAoAAAgAAAY7qUp6h3MHsW8AALFvAAAhAAAAAAAAAAAAAAAAAMNFQgBjb20vc3VuL3Rvb2xzL2phdmFjL3V0aWwvTG9nLmphdmFQSwECCgAKAAAIAAAGO6lK3vA1PpQWAACUFgAAJQAAAAAAAAAAAAAAAACztUIAY29tL3N1bi90b29scy9qYXZhYy91dGlsL09wdGlvbnMuamF2YVBLAQIKAAoAAAgAANJ9TUrSF2+2DQkAAA0JAAAiAAAAAAAAAAAAAAAAAIrMQgBjb20vc3VuL3Rvb2xzL2phdmFjL3V0aWwvUGFpci5qYXZhUEsBAgoACgAACAAA0n1NSjeZy6ZBGQAAQRkAAC0AAAAAAAAAAAAAAAAA19VCAGNvbS9zdW4vdG9vbHMvamF2YWMvdXRpbC9TaGFyZWROYW1lVGFibGUuamF2YVBLAQIKAAoAAAgAANJ9TUquBSGQ8QYAAPEGAAAjAAAAAAAAAAAAAAAAAGPvQgBjb20vc3VuL3Rvb2xzL2phdmFjL3V0aWwvQWJvcnQuamF2YVBLAQIKAAoAAAgAANJ9TUo82hTh+hQAAPoUAAAvAAAAAAAAAAAAAAAAAJX2QgBjb20vc3VuL3Rvb2xzL2phdmFjL3V0aWwvVW5zaGFyZWROYW1lVGFibGUuamF2YVBLAQIKAAoAAAgAANJ9TUpru6NUZAcAAGQHAAAxAAAAAAAAAAAAAAAAANwLQwBjb20vc3VuL3Rvb2xzL2phdmFjL3V0aWwvUHJvcGFnYXRlZEV4Y2VwdGlvbi5qYXZhUEsBAgoACgAACAAA0n1NSuJFxolgCAAAYAgAACcAAAAAAAAAAAAAAAAAjxNDAGNvbS9zdW4vdG9vbHMvamF2YWMvdXRpbC9EZWZpbmVkQnkuamF2YVBLAQIKAAoAAAgAANJ9TUrMsYq4MCsAADArAAA1AAAAAAAAAAAAAAAAADQcQwBjb20vc3VuL3Rvb2xzL2phdmFjL3V0aWwvTWFuZGF0b3J5V2FybmluZ0hhbmRsZXIuamF2YVBLAQIKAAoAAAgAANJ9TUpiht1qXBQAAFwUAAAnAAAAAAAAAAAAAAAAALdHQwBjb20vc3VuL3Rvb2xzL2phdmFjL3V0aWwvQ29uc3RhbnRzLmphdmFQSwECCgAKAAAIAAAGO6lKq6JgEiofAAAqHwAAKwAAAAAAAAAAAAAAAABYXEMAY29tL3N1bi90b29scy9qYXZhYy91dGlsL0phdmFjTWVzc2FnZXMuamF2YVBLAQIKAAoAAAgAAAY7qUoaVAF0kjcAAJI3AAAjAAAAAAAAAAAAAAAAAMt7QwBjb20vc3VuL3Rvb2xzL2phdmFjL3V0aWwvTmFtZXMuamF2YVBLAQIKAAoAAAgAAAY7qUrInIefB0gAAAdIAAAqAAAAAAAAAAAAAAAAAJ6zQwBjb20vc3VuL3Rvb2xzL2phdmFjL3V0aWwvSkRLOVdyYXBwZXJzLmphdmFQSwECCgAKAAAIAADSfU1K9AY6BDsUAAA7FAAAKAAAAAAAAAAAAAAAAADt+0MAY29tL3N1bi90b29scy9qYXZhYy91dGlsL0J5dGVCdWZmZXIuamF2YVBLAQIKAAoAAAgAAAY7qUoxxxcojBoAAIwaAAAqAAAAAAAAAAAAAAAAAG4QRABjb20vc3VuL3Rvb2xzL2phdmFjL3V0aWwvSW50SGFzaFRhYmxlLmphdmFQSwECCgAKAAAIAAAGO6lK6yuM5BIyAAASMgAAJQAAAAAAAAAAAAAAAABCK0QAY29tL3N1bi90b29scy9qYXZhYy91dGlsL0NvbnZlcnQuamF2YVBLAQIKAAoAAAgAAAY7qUoAAAAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAJddRABjb20vc3VuL3Rvb2xzL2phdmFjL21vZGVsL1BLAQIKAAoAAAgAAAY7qUqraNX6fTIAAH0yAAApAAAAAAAAAAAAAAAAAM9dRABjb20vc3VuL3Rvb2xzL2phdmFjL21vZGVsL0phdmFjVHlwZXMuamF2YVBLAQIKAAoAAAgAAAY7qUr5Oz1W0HQAANB0AAAsAAAAAAAAAAAAAAAAAJOQRABjb20vc3VuL3Rvb2xzL2phdmFjL21vZGVsL0phdmFjRWxlbWVudHMuamF2YVBLAQIKAAoAAAgAAAY7qUq7wF2qMDMAADAzAAAzAAAAAAAAAAAAAAAAAK0FRQBjb20vc3VuL3Rvb2xzL2phdmFjL21vZGVsL0Fubm90YXRpb25Qcm94eU1ha2VyLmphdmFQSwECCgAKAAAIAAAGO6lKyWdmz9ILAADSCwAAMQAAAAAAAAAAAAAAAAAuOUUAY29tL3N1bi90b29scy9qYXZhYy9tb2RlbC9GaWx0ZXJlZE1lbWJlckxpc3QuamF2YVBLAQIKAAoAAAgAAK48qUoAAAAAAAAAAAAAAAAZAAAAAAAAAAAAAAAAAE9FRQBjb20vc3VuL3Rvb2xzL2phdmFjL2NvZGUvUEsBAgoACgAACAAABjupSr0xtSM+IgAAPiIAACwAAAAAAAAAAAAAAAAAhkVFAGNvbS9zdW4vdG9vbHMvamF2YWMvY29kZS9TeW1ib2xNZXRhZGF0YS5qYXZhUEsBAgoACgAACAAABjupSo+FXNUhAgEAIQIBAC0AAAAAAAAAAAAAAAAADmhFAGNvbS9zdW4vdG9vbHMvamF2YWMvY29kZS9UeXBlQW5ub3RhdGlvbnMuamF2YVBLAQIKAAoAAAgAAAY7qUqx6VG2sDAAALAwAAAiAAAAAAAAAAAAAAAAAHpqRgBjb20vc3VuL3Rvb2xzL2phdmFjL2NvZGUvTGludC5qYXZhUEsBAgoACgAACAAABjupSpuJgfe7OgAAuzoAACcAAAAAAAAAAAAAAAAAaptGAGNvbS9zdW4vdG9vbHMvamF2YWMvY29kZS9BdHRyaWJ1dGUuamF2YVBLAQIKAAoAAAgAAAY7qUpXwXfTpD0AAKQ9AAAjAAAAAAAAAAAAAAAAAGrWRgBjb20vc3VuL3Rvb2xzL2phdmFjL2NvZGUvRmxhZ3MuamF2YVBLAQIKAAoAAAgAAAY7qUrL6d/6WywAAFssAAAnAAAAAAAAAAAAAAAAAE8URwBjb20vc3VuL3Rvb2xzL2phdmFjL2NvZGUvRGlyZWN0aXZlLmphdmFQSwECCgAKAAAIAAAGO6lKzyyfWOubAADrmwAAIwAAAAAAAAAAAAAAAADvQEcAY29tL3N1bi90b29scy9qYXZhYy9jb2RlL1Njb3BlLmphdmFQSwECCgAKAAAIAADSfU1KCpPFmNYXAADWFwAAKAAAAAAAAAAAAAAAAAAb3UcAY29tL3N1bi90b29scy9qYXZhYy9jb2RlL1RhcmdldFR5cGUuamF2YVBLAQIKAAoAAAgAAAY7qUocl4iTmi0AAJotAAAjAAAAAAAAAAAAAAAAADf1RwBjb20vc3VuL3Rvb2xzL2phdmFjL2NvZGUvS2luZHMuamF2YVBLAQIKAAoAAAgAAK48qUrU/PVcJtwCACbcAgAjAAAAAAAAAAAAAAAAABIjSABjb20vc3VuL3Rvb2xzL2phdmFjL2NvZGUvVHlwZXMuamF2YVBLAQIKAAoAAAgAAK48qUo0R4i4CTcBAAk3AQAiAAAAAAAAAAAAAAAAAHn/SgBjb20vc3VuL3Rvb2xzL2phdmFjL2NvZGUvVHlwZS5qYXZhUEsBAgoACgAACAAABjupShX18YkVHgAAFR4AACUAAAAAAAAAAAAAAAAAwjZMAGNvbS9zdW4vdG9vbHMvamF2YWMvY29kZS9UeXBlVGFnLmphdmFQSwECCgAKAAAIAADSfU1KqguCuCkUAAApFAAAMQAAAAAAAAAAAAAAAAAaVUwAY29tL3N1bi90b29scy9qYXZhYy9jb2RlL0RlZmVycmVkTGludEhhbmRsZXIuamF2YVBLAQIKAAoAAAgAAAY7qUp8x7ls93YAAPd2AAApAAAAAAAAAAAAAAAAAJJpTABjb20vc3VuL3Rvb2xzL2phdmFjL2NvZGUvQ2xhc3NGaW5kZXIuamF2YVBLAQIKAAoAAAgAAAY7qUrrh9asaIQAAGiEAAAkAAAAAAAAAAAAAAAAANDgTABjb20vc3VuL3Rvb2xzL2phdmFjL2NvZGUvU3ltdGFiLmphdmFQSwECCgAKAAAIAADSfU1KJdCWa7AGAACwBgAAJwAAAAAAAAAAAAAAAAB6ZU0AY29tL3N1bi90b29scy9qYXZhYy9jb2RlL0JvdW5kS2luZC5qYXZhUEsBAgoACgAACAAABjupSq8KDotCIAAAQiAAACsAAAAAAAAAAAAAAAAAb2xNAGNvbS9zdW4vdG9vbHMvamF2YWMvY29kZS9Bbm5vQ29uc3RydWN0LmphdmFQSwECCgAKAAAIAAAGO6lKD1L7k745AAC+OQAAJQAAAAAAAAAAAAAAAAD6jE0AY29tL3N1bi90b29scy9qYXZhYy9jb2RlL1ByaW50ZXIuamF2YVBLAQIKAAoAAAgAAAY7qUraibLHRjQBAEY0AQAkAAAAAAAAAAAAAAAAAPvGTQBjb20vc3VuL3Rvb2xzL2phdmFjL2NvZGUvU3ltYm9sLmphdmFQSwECCgAKAAAIAAAGO6lKfN3ncA1CAAANQgAAKgAAAAAAAAAAAAAAAACD+04AY29tL3N1bi90b29scy9qYXZhYy9jb2RlL01vZHVsZUZpbmRlci5qYXZhUEsBAgoACgAACAAABjupSo4YTqbvHwAA7x8AACQAAAAAAAAAAAAAAAAA2D1PAGNvbS9zdW4vdG9vbHMvamF2YWMvY29kZS9Tb3VyY2UuamF2YVBLAQIKAAoAAAgAAAY7qUqK2NqQlKsAAJSrAAA0AAAAAAAAAAAAAAAAAAleTwBjb20vc3VuL3Rvb2xzL2phdmFjL2NvZGUvVHlwZUFubm90YXRpb25Qb3NpdGlvbi5qYXZhUEsBAgoACgAACAAABjupSmHxWp3KGQAAyhkAACoAAAAAAAAAAAAAAAAA7wlQAGNvbS9zdW4vdG9vbHMvamF2YWMvY29kZS9UeXBlTWV0YWRhdGEuamF2YVBLAQIKAAoAAAgAAAY7qUoAAAAAAAAAAAAAAAAZAAAAAAAAAAAAAAAAAAEkUABjb20vc3VuL3Rvb2xzL2phdmFjL21haW4vUEsBAgoACgAACAAABjupStlxO65rBwAAawcAAC8AAAAAAAAAAAAAAAAAOCRQAGNvbS9zdW4vdG9vbHMvamF2YWMvbWFpbi9KYXZhY1Rvb2xQcm92aWRlci5qYXZhUEsBAgoACgAACAAABjupSghW+qotzAAALcwAACQAAAAAAAAAAAAAAAAA8CtQAGNvbS9zdW4vdG9vbHMvamF2YWMvbWFpbi9PcHRpb24uamF2YVBLAQIKAAoAAAgAAAY7qUrwiT4JewsBAHsLAQAqAAAAAAAAAAAAAAAAAF/4UABjb20vc3VuL3Rvb2xzL2phdmFjL21haW4vSmF2YUNvbXBpbGVyLmphdmFQSwECCgAKAAAIAAAGO6lKxKVr6YEtAACBLQAAKQAAAAAAAAAAAAAAAAAiBFIAY29tL3N1bi90b29scy9qYXZhYy9tYWluL0NvbW1hbmRMaW5lLmphdmFQSwECCgAKAAAIAAAGO6lKGC61MDWQAAA1kAAAJwAAAAAAAAAAAAAAAADqMVIAY29tL3N1bi90b29scy9qYXZhYy9tYWluL0FyZ3VtZW50cy5qYXZhUEsBAgoACgAACAAABjupSvi8gZuwEgAAsBIAACoAAAAAAAAAAAAAAAAAZMJSAGNvbS9zdW4vdG9vbHMvamF2YWMvbWFpbi9PcHRpb25IZWxwZXIuamF2YVBLAQIKAAoAAAgAAAY7qUpW+rucVzsAAFc7AAAiAAAAAAAAAAAAAAAAAFzVUgBjb20vc3VuL3Rvb2xzL2phdmFjL21haW4vTWFpbi5qYXZhUEsBAgoACgAACAAABjupSgAAAAAAAAAAAAAAABgAAAAAAAAAAAAAAAAA8xBTAGNvbS9zdW4vdG9vbHMvamF2YWMvanZtL1BLAQIKAAoAAAgAAAY7qUqrQai7bzIAAG8yAAAhAAAAAAAAAAAAAAAAACkRUwBjb20vc3VuL3Rvb2xzL2phdmFjL2p2bS9Qb29sLmphdmFQSwECCgAKAAAIAAAGO6lKK+aoimBLAABgSwAAKQAAAAAAAAAAAAAAAADXQ1MAY29tL3N1bi90b29scy9qYXZhYy9qdm0vU3RyaW5nQ29uY2F0LmphdmFQSwECCgAKAAAIAAAGO6lKYqDmVk0lAQBNJQEAIQAAAAAAAAAAAAAAAAB+j1MAY29tL3N1bi90b29scy9qYXZhYy9qdm0vQ29kZS5qYXZhUEsBAgoACgAACAAABjupStRELOmrIQAAqyEAAC0AAAAAAAAAAAAAAAAACrVUAGNvbS9zdW4vdG9vbHMvamF2YWMvanZtL01vZHVsZU5hbWVSZWFkZXIuamF2YVBLAQIKAAoAAAgAAAY7qUr/x5p+rA0AAKwNAAAkAAAAAAAAAAAAAAAAAADXVABjb20vc3VuL3Rvb2xzL2phdmFjL2p2bS9Qcm9maWxlLmphdmFQSwECCgAKAAAIAAAGO6lKquQxZFvPAQBbzwEAKAAAAAAAAAAAAAAAAADu5FQAY29tL3N1bi90b29scy9qYXZhYy9qdm0vQ2xhc3NSZWFkZXIuamF2YVBLAQIKAAoAAAgAAAY7qUp9/NSS1woAANcKAAAuAAAAAAAAAAAAAAAAAI+0VgBjb20vc3VuL3Rvb2xzL2phdmFjL2p2bS9VbmluaXRpYWxpemVkVHlwZS5qYXZhUEsBAgoACgAACAAABjupSutbAFnOXAEAzlwBACAAAAAAAAAAAAAAAAAAsr9WAGNvbS9zdW4vdG9vbHMvamF2YWMvanZtL0dlbi5qYXZhUEsBAgoACgAACAAABjupSkZmzktkYAAAZGAAACYAAAAAAAAAAAAAAAAAvhxYAGNvbS9zdW4vdG9vbHMvamF2YWMvanZtL0pOSVdyaXRlci5qYXZhUEsBAgoACgAACAAABjupSgj+MwRKEgAAShIAACMAAAAAAAAAAAAAAAAAZn1YAGNvbS9zdW4vdG9vbHMvamF2YWMvanZtL1RhcmdldC5qYXZhUEsBAgoACgAACAAA0n1NSvXjndiUCQAAlAkAACUAAAAAAAAAAAAAAAAA8Y9YAGNvbS9zdW4vdG9vbHMvamF2YWMvanZtL0NSVEZsYWdzLmphdmFQSwECCgAKAAAIAAAGO6lKkyybi+wUAQDsFAEAKAAAAAAAAAAAAAAAAADImVgAY29tL3N1bi90b29scy9qYXZhYy9qdm0vQ2xhc3NXcml0ZXIuamF2YVBLAQIKAAoAAAgAANJ9TUqKkO1V4SYAAOEmAAAmAAAAAAAAAAAAAAAAAPquWQBjb20vc3VuL3Rvb2xzL2phdmFjL2p2bS9CeXRlQ29kZXMuamF2YVBLAQIKAAoAAAgAAAY7qUpRYe2MnCEAAJwhAAAmAAAAAAAAAAAAAAAAAB/WWQBjb20vc3VuL3Rvb2xzL2phdmFjL2p2bS9DbGFzc0ZpbGUuamF2YVBLAQIKAAoAAAgAANJ9TUrVckTkcV8AAHFfAAAiAAAAAAAAAAAAAAAAAP/3WQBjb20vc3VuL3Rvb2xzL2phdmFjL2p2bS9JdGVtcy5qYXZhUEsBAgoACgAACAAABjupSj9dAzroVQAA6FUAACQAAAAAAAAAAAAAAAAAsFdaAGNvbS9zdW4vdG9vbHMvamF2YWMvanZtL0NSVGFibGUuamF2YVBLAQIKAAoAAAgAAAY7qUrBf7hjLQsAAC0LAAAdAAAAAAAAAAAAAAAAANqtWgBjb20vc3VuL3Rvb2xzL2phdmFjL01haW4uamF2YVBLAQIKAAoAAAgAAAY7qUoAAAAAAAAAAAAAAAAWAAAAAAAAAAAAAAAAAEK5WgBjb20vc3VuL3Rvb2xzL2RvY2xpbnQvUEsBAgoACgAACAAABjupSgAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAdrlaAGNvbS9zdW4vdG9vbHMvZG9jbGludC9yZXNvdXJjZXMvUEsBAgoACgAACAAABjupSmJrJ2g4GgAAOBoAADIAAAAAAAAAAAAAAAAAtLlaAGNvbS9zdW4vdG9vbHMvZG9jbGludC9yZXNvdXJjZXMvZG9jbGludC5wcm9wZXJ0aWVzUEsBAgoACgAACAAABjupSqref/SvMAAArzAAADUAAAAAAAAAAAAAAAAAPNRaAGNvbS9zdW4vdG9vbHMvZG9jbGludC9yZXNvdXJjZXMvZG9jbGludF9qYS5wcm9wZXJ0aWVzUEsBAgoACgAACAAABjupSu7j+6PNIQAAzSEAADgAAAAAAAAAAAAAAAAAPgVbAGNvbS9zdW4vdG9vbHMvZG9jbGludC9yZXNvdXJjZXMvZG9jbGludF96aF9DTi5wcm9wZXJ0aWVzUEsBAgoACgAACAAABjupSoRE/VRWGgAAVhoAACEAAAAAAAAAAAAAAAAAYSdbAGNvbS9zdW4vdG9vbHMvZG9jbGludC9FbnRpdHkuamF2YVBLAQIKAAoAAAgAAAY7qUrAjq93uDwAALg8AAAiAAAAAAAAAAAAAAAAAPZBWwBjb20vc3VuL3Rvb2xzL2RvY2xpbnQvRG9jTGludC5qYXZhUEsBAgoACgAACAAABjupSjZPsY2lBgAApQYAACYAAAAAAAAAAAAAAAAA7n5bAGNvbS9zdW4vdG9vbHMvZG9jbGludC9IdG1sVmVyc2lvbi5qYXZhUEsBAgoACgAACAAABjupSsoPZaluLQAAbi0AACMAAAAAAAAAAAAAAAAA14VbAGNvbS9zdW4vdG9vbHMvZG9jbGludC9NZXNzYWdlcy5qYXZhUEsBAgoACgAACAAABjupSnvuv1RxVAAAcVQAACIAAAAAAAAAAAAAAAAAhrNbAGNvbS9zdW4vdG9vbHMvZG9jbGludC9IdG1sVGFnLmphdmFQSwECCgAKAAAIAAAGO6lKZ7SvjH4iAAB+IgAAHgAAAAAAAAAAAAAAAAA3CFwAY29tL3N1bi90b29scy9kb2NsaW50L0Vudi5qYXZhUEsBAgoACgAACAAABjupSsdZcK53oAAAd6AAACIAAAAAAAAAAAAAAAAA8SpcAGNvbS9zdW4vdG9vbHMvZG9jbGludC9DaGVja2VyLmphdmFQSwECCgAKAAAIAADSfU1KAAAAAAAAAAAAAAAABgAAAAAAAAAAAAAAAACoy1wAamF2YXgvUEsBAgoACgAACAAA0n1NSgAAAAAAAAAAAAAAABEAAAAAAAAAAAAAAAAAzMtcAGphdmF4L2Fubm90YXRpb24vUEsBAgoACgAACAAABjupSgAAAAAAAAAAAAAAABwAAAAAAAAAAAAAAAAA+8tcAGphdmF4L2Fubm90YXRpb24vcHJvY2Vzc2luZy9QSwECCgAKAAAIAADSfU1K27cO7FUHAABVBwAALQAAAAAAAAAAAAAAAAA1zFwAamF2YXgvYW5ub3RhdGlvbi9wcm9jZXNzaW5nL3BhY2thZ2UtaW5mby5qYXZhUEsBAgoACgAACAAA0n1NShcAcMwkFAAAJBQAADYAAAAAAAAAAAAAAAAA1dNcAGphdmF4L2Fubm90YXRpb24vcHJvY2Vzc2luZy9Qcm9jZXNzaW5nRW52aXJvbm1lbnQuamF2YVBLAQIKAAoAAAgAANJ9TUqcFhwgWgcAAFoHAAArAAAAAAAAAAAAAAAAAE3oXABqYXZheC9hbm5vdGF0aW9uL3Byb2Nlc3NpbmcvQ29tcGxldGlvbi5qYXZhUEsBAgoACgAACAAA0n1NSinY9uhyCAAAcggAADkAAAAAAAAAAAAAAAAA8O9cAGphdmF4L2Fubm90YXRpb24vcHJvY2Vzc2luZy9TdXBwb3J0ZWRBbm5vdGF0aW9uVHlwZXMuamF2YVBLAQIKAAoAAAgAANJ9TUrYZZ1QGggAABoIAAAxAAAAAAAAAAAAAAAAALn4XABqYXZheC9hbm5vdGF0aW9uL3Byb2Nlc3NpbmcvU3VwcG9ydGVkT3B0aW9ucy5qYXZhUEsBAgoACgAACAAABjupSh9WXDYaUgAAGlIAACoAAAAAAAAAAAAAAAAAIgFdAGphdmF4L2Fubm90YXRpb24vcHJvY2Vzc2luZy9Qcm9jZXNzb3IuamF2YVBLAQIKAAoAAAgAANJ9TUqi18OlXAsAAFwLAAAsAAAAAAAAAAAAAAAAAIRTXQBqYXZheC9hbm5vdGF0aW9uL3Byb2Nlc3NpbmcvQ29tcGxldGlvbnMuamF2YVBLAQIKAAoAAAgAANJ9TUqpaW6Ueg8AAHoPAAApAAAAAAAAAAAAAAAAACpfXQBqYXZheC9hbm5vdGF0aW9uL3Byb2Nlc3NpbmcvTWVzc2FnZXIuamF2YVBLAQIKAAoAAAgAAAY7qUrk5bAqbD0AAGw9AAAmAAAAAAAAAAAAAAAAAOtuXQBqYXZheC9hbm5vdGF0aW9uL3Byb2Nlc3NpbmcvRmlsZXIuamF2YVBLAQIKAAoAAAgAANJ9TUofCQcUEQgAABEIAAA3AAAAAAAAAAAAAAAAAJusXQBqYXZheC9hbm5vdGF0aW9uL3Byb2Nlc3NpbmcvU3VwcG9ydGVkU291cmNlVmVyc2lvbi5qYXZhUEsBAgoACgAACAAABjupSmHGjzzEHwAAxB8AADEAAAAAAAAAAAAAAAAAAbVdAGphdmF4L2Fubm90YXRpb24vcHJvY2Vzc2luZy9Sb3VuZEVudmlyb25tZW50LmphdmFQSwECCgAKAAAIAAAGO6lKXIzrNEYIAABGCAAALwAAAAAAAAAAAAAAAAAU1V0AamF2YXgvYW5ub3RhdGlvbi9wcm9jZXNzaW5nL0ZpbGVyRXhjZXB0aW9uLmphdmFQSwECCgAKAAAIAAAGO6lKD+aLKIAhAACAIQAAMgAAAAAAAAAAAAAAAACn3V0AamF2YXgvYW5ub3RhdGlvbi9wcm9jZXNzaW5nL0Fic3RyYWN0UHJvY2Vzc29yLmphdmFQSwECCgAKAAAIAADSfU1KAAAAAAAAAAAAAAAACwAAAAAAAAAAAAAAAAB3/10AamF2YXgvbGFuZy9QSwECCgAKAAAIAAAGO6lKAAAAAAAAAAAAAAAAEQAAAAAAAAAAAAAAAACg/10AamF2YXgvbGFuZy9tb2RlbC9QSwECCgAKAAAIAADSfU1KrLPuPG4FAABuBQAAHgAAAAAAAAAAAAAAAADP/10AamF2YXgvbGFuZy9tb2RlbC9vdmVydmlldy5odG1sUEsBAgoACgAACAAA0n1NSjzco9oWCgAAFgoAACIAAAAAAAAAAAAAAAAAeQVeAGphdmF4L2xhbmcvbW9kZWwvcGFja2FnZS1pbmZvLmphdmFQSwECCgAKAAAIAAAGO6lKAAAAAAAAAAAAAAAAFgAAAAAAAAAAAAAAAADPD14AamF2YXgvbGFuZy9tb2RlbC90eXBlL1BLAQIKAAoAAAgAANJ9TUqRRYwA/wsAAP8LAAAnAAAAAAAAAAAAAAAAAAMQXgBqYXZheC9sYW5nL21vZGVsL3R5cGUvVHlwZVZhcmlhYmxlLmphdmFQSwECCgAKAAAIAAAGO6lKoxyf1m0QAABtEAAAJQAAAAAAAAAAAAAAAABHHF4AamF2YXgvbGFuZy9tb2RlbC90eXBlL1R5cGVNaXJyb3IuamF2YVBLAQIKAAoAAAgAAAY7qUpGbYTQcAYAAHAGAAAkAAAAAAAAAAAAAAAAAPcsXgBqYXZheC9sYW5nL21vZGVsL3R5cGUvVW5pb25UeXBlLmphdmFQSwECCgAKAAAIAADSfU1KJu6/EO4GAADuBgAAJwAAAAAAAAAAAAAAAACpM14AamF2YXgvbGFuZy9tb2RlbC90eXBlL3BhY2thZ2UtaW5mby5qYXZhUEsBAgoACgAACAAA0n1NShWnO202BgAANgYAACgAAAAAAAAAAAAAAAAA3DpeAGphdmF4L2xhbmcvbW9kZWwvdHlwZS9QcmltaXRpdmVUeXBlLmphdmFQSwECCgAKAAAIAAAGO6lKPUzjwJ0IAACdCAAAJwAAAAAAAAAAAAAAAABYQV4AamF2YXgvbGFuZy9tb2RlbC90eXBlL1dpbGRjYXJkVHlwZS5qYXZhUEsBAgoACgAACAAABjupSgtlcUX4CwAA+AsAAC8AAAAAAAAAAAAAAAAAOkpeAGphdmF4L2xhbmcvbW9kZWwvdHlwZS9Vbmtub3duVHlwZUV4Y2VwdGlvbi5qYXZhUEsBAgoACgAACAAABjupSrK3A9PZBwAA2QcAACEAAAAAAAAAAAAAAAAAf1ZeAGphdmF4L2xhbmcvbW9kZWwvdHlwZS9Ob1R5cGUuamF2YVBLAQIKAAoAAAgAANJ9TUrako+5BgYAAAYGAAAoAAAAAAAAAAAAAAAAAJdeXgBqYXZheC9sYW5nL21vZGVsL3R5cGUvUmVmZXJlbmNlVHlwZS5qYXZhUEsBAgoACgAACAAA0n1NSnp+loQeDwAAHg8AACkAAAAAAAAAAAAAAAAA42ReAGphdmF4L2xhbmcvbW9kZWwvdHlwZS9FeGVjdXRhYmxlVHlwZS5qYXZhUEsBAgoACgAACAAABjupShQVEyn9BwAA/QcAACsAAAAAAAAAAAAAAAAASHReAGphdmF4L2xhbmcvbW9kZWwvdHlwZS9JbnRlcnNlY3Rpb25UeXBlLmphdmFQSwECCgAKAAAIAAAGO6lKyBY/Yy4PAAAuDwAAIwAAAAAAAAAAAAAAAACOfF4AamF2YXgvbGFuZy9tb2RlbC90eXBlL1R5cGVLaW5kLmphdmFQSwECCgAKAAAIAADSfU1Ks/3FebkGAAC5BgAAJAAAAAAAAAAAAAAAAAD9i14AamF2YXgvbGFuZy9tb2RlbC90eXBlL0FycmF5VHlwZS5qYXZhUEsBAgoACgAACAAA0n1NSnPSu7/PBgAAzwYAACQAAAAAAAAAAAAAAAAA+JJeAGphdmF4L2xhbmcvbW9kZWwvdHlwZS9FcnJvclR5cGUuamF2YVBLAQIKAAoAAAgAAAY7qUqLXHKrkhsAAJIbAAAmAAAAAAAAAAAAAAAAAAmaXgBqYXZheC9sYW5nL21vZGVsL3R5cGUvVHlwZVZpc2l0b3IuamF2YVBLAQIKAAoAAAgAANJ9TUq8QnFAcAsAAHALAAAwAAAAAAAAAAAAAAAAAN+1XgBqYXZheC9sYW5nL21vZGVsL3R5cGUvTWlycm9yZWRUeXBlRXhjZXB0aW9uLmphdmFQSwECCgAKAAAIAADSfU1KSu7J8dcFAADXBQAAIwAAAAAAAAAAAAAAAACdwV4AamF2YXgvbGFuZy9tb2RlbC90eXBlL051bGxUeXBlLmphdmFQSwECCgAKAAAIAADSfU1Kgxyl2skMAADJDAAAJwAAAAAAAAAAAAAAAAC1x14AamF2YXgvbGFuZy9tb2RlbC90eXBlL0RlY2xhcmVkVHlwZS5qYXZhUEsBAgoACgAACAAA0n1NSk1QIDeMDQAAjA0AADEAAAAAAAAAAAAAAAAAw9ReAGphdmF4L2xhbmcvbW9kZWwvdHlwZS9NaXJyb3JlZFR5cGVzRXhjZXB0aW9uLmphdmFQSwECCgAKAAAIAAAGO6lKAAAAAAAAAAAAAAAAGQAAAAAAAAAAAAAAAACe4l4AamF2YXgvbGFuZy9tb2RlbC9lbGVtZW50L1BLAQIKAAoAAAgAAAY7qUr6kgY7OCYAADgmAAAlAAAAAAAAAAAAAAAAANXiXgBqYXZheC9sYW5nL21vZGVsL2VsZW1lbnQvRWxlbWVudC5qYXZhUEsBAgoACgAACAAABjupSp7EN2qYFQAAmBUAACoAAAAAAAAAAAAAAAAAUAlfAGphdmF4L2xhbmcvbW9kZWwvZWxlbWVudC9wYWNrYWdlLWluZm8uamF2YVBLAQIKAAoAAAgAANJ9TUrh2ib1JgYAACYGAAAvAAAAAAAAAAAAAAAAADAfXwBqYXZheC9sYW5nL21vZGVsL2VsZW1lbnQvUXVhbGlmaWVkTmFtZWFibGUuamF2YVBLAQIKAAoAAAgAAAY7qUrc3QO4rgwAAK4MAAA9AAAAAAAAAAAAAAAAAKMlXwBqYXZheC9sYW5nL21vZGVsL2VsZW1lbnQvVW5rbm93bkFubm90YXRpb25WYWx1ZUV4Y2VwdGlvbi5qYXZhUEsBAgoACgAACAAABjupShTVZypuGQAAbhkAACkAAAAAAAAAAAAAAAAArDJfAGphdmF4L2xhbmcvbW9kZWwvZWxlbWVudC9UeXBlRWxlbWVudC5qYXZhUEsBAgoACgAACAAABjupSjOE2sefBgAAnwYAAC0AAAAAAAAAAAAAAAAAYUxfAGphdmF4L2xhbmcvbW9kZWwvZWxlbWVudC9QYXJhbWV0ZXJpemFibGUuamF2YVBLAQIKAAoAAAgAAAY7qUq6md3gCx8AAAsfAAA0AAAAAAAAAAAAAAAAAEtTXwBqYXZheC9sYW5nL21vZGVsL2VsZW1lbnQvQW5ub3RhdGlvblZhbHVlVmlzaXRvci5qYXZhUEsBAgoACgAACAAA0n1NSmoUYqmECgAAhAoAADIAAAAAAAAAAAAAAAAAqHJfAGphdmF4L2xhbmcvbW9kZWwvZWxlbWVudC9UeXBlUGFyYW1ldGVyRWxlbWVudC5qYXZhUEsBAgoACgAACAAABjupSgD6hWjWDAAA1gwAADcAAAAAAAAAAAAAAAAAfH1fAGphdmF4L2xhbmcvbW9kZWwvZWxlbWVudC9Vbmtub3duRGlyZWN0aXZlRXhjZXB0aW9uLmphdmFQSwECCgAKAAAIAAAGO6lKNaz+6t8OAADfDgAAKQAAAAAAAAAAAAAAAACnil8AamF2YXgvbGFuZy9tb2RlbC9lbGVtZW50L05lc3RpbmdLaW5kLmphdmFQSwECCgAKAAAIAADSfU1KckvHV2gKAABoCgAALQAAAAAAAAAAAAAAAADNmV8AamF2YXgvbGFuZy9tb2RlbC9lbGVtZW50L0Fubm90YXRpb25WYWx1ZS5qYXZhUEsBAgoACgAACAAA0n1NSvjom7M6CwAAOgsAACYAAAAAAAAAAAAAAAAAgKRfAGphdmF4L2xhbmcvbW9kZWwvZWxlbWVudC9Nb2RpZmllci5qYXZhUEsBAgoACgAACAAA0n1NSrYv3NA8DgAAPA4AACIAAAAAAAAAAAAAAAAA/q9fAGphdmF4L2xhbmcvbW9kZWwvZWxlbWVudC9OYW1lLmphdmFQSwECCgAKAAAIAAAGO6lKoHzsvL0OAAC9DgAAKQAAAAAAAAAAAAAAAAB6vl8AamF2YXgvbGFuZy9tb2RlbC9lbGVtZW50L0VsZW1lbnRLaW5kLmphdmFQSwECCgAKAAAIAADSfU1KbMGUP2ATAABgEwAALwAAAAAAAAAAAAAAAAB+zV8AamF2YXgvbGFuZy9tb2RlbC9lbGVtZW50L0V4ZWN1dGFibGVFbGVtZW50LmphdmFQSwECCgAKAAAIAAAGO6lKJHK2pHQvAAB0LwAAKwAAAAAAAAAAAAAAAAAr4V8AamF2YXgvbGFuZy9tb2RlbC9lbGVtZW50L01vZHVsZUVsZW1lbnQuamF2YVBLAQIKAAoAAAgAAAY7qUo4n3Q4KAwAACgMAAA1AAAAAAAAAAAAAAAAAOgQYABqYXZheC9sYW5nL21vZGVsL2VsZW1lbnQvVW5rbm93bkVsZW1lbnRFeGNlcHRpb24uamF2YVBLAQIKAAoAAAgAAAY7qUoHkCqJGw4AABsOAAAsAAAAAAAAAAAAAAAAAGMdYABqYXZheC9sYW5nL21vZGVsL2VsZW1lbnQvUGFja2FnZUVsZW1lbnQuamF2YVBLAQIKAAoAAAgAAAY7qUqH/5R7YxgAAGMYAAAsAAAAAAAAAAAAAAAAAMgrYABqYXZheC9sYW5nL21vZGVsL2VsZW1lbnQvRWxlbWVudFZpc2l0b3IuamF2YVBLAQIKAAoAAAgAANJ9TUoKqBV9GAsAABgLAAAuAAAAAAAAAAAAAAAAAHVEYABqYXZheC9sYW5nL21vZGVsL2VsZW1lbnQvQW5ub3RhdGlvbk1pcnJvci5qYXZhUEsBAgoACgAACAAA0n1NSvSi8/9NDQAATQ0AAC0AAAAAAAAAAAAAAAAA2U9gAGphdmF4L2xhbmcvbW9kZWwvZWxlbWVudC9WYXJpYWJsZUVsZW1lbnQuamF2YVBLAQIKAAoAAAgAAAY7qUpQO0xvBy0AAActAAAjAAAAAAAAAAAAAAAAAHFdYABqYXZheC9sYW5nL21vZGVsL1NvdXJjZVZlcnNpb24uamF2YVBLAQIKAAoAAAgAAAY7qUoAAAAAAAAAAAAAAAAWAAAAAAAAAAAAAAAAALmKYABqYXZheC9sYW5nL21vZGVsL3V0aWwvUEsBAgoACgAACAAABjupSppPtOPIDgAAyA4AADgAAAAAAAAAAAAAAAAA7YpgAGphdmF4L2xhbmcvbW9kZWwvdXRpbC9TaW1wbGVBbm5vdGF0aW9uVmFsdWVWaXNpdG9yOS5qYXZhUEsBAgoACgAACAAABjupSq5MaxlwDAAAcAwAAC8AAAAAAAAAAAAAAAAAC5pgAGphdmF4L2xhbmcvbW9kZWwvdXRpbC9BYnN0cmFjdFR5cGVWaXNpdG9yOS5qYXZhUEsBAgoACgAACAAABjupSvt50H8XDAAAFwwAADoAAAAAAAAAAAAAAAAAyKZgAGphdmF4L2xhbmcvbW9kZWwvdXRpbC9BYnN0cmFjdEFubm90YXRpb25WYWx1ZVZpc2l0b3I4LmphdmFQSwECCgAKAAAIAAAGO6lKAuNEmZoaAACaGgAAMAAAAAAAAAAAAAAAAAA3s2AAamF2YXgvbGFuZy9tb2RlbC91dGlsL1NpbXBsZUVsZW1lbnRWaXNpdG9yNi5qYXZhUEsBAgoACgAACAAABjupSj99XOXZDQAA2Q0AAC8AAAAAAAAAAAAAAAAAH85gAGphdmF4L2xhbmcvbW9kZWwvdXRpbC9BYnN0cmFjdFR5cGVWaXNpdG9yNy5qYXZhUEsBAgoACgAACAAA0n1NSjVYXUNIBwAASAcAACcAAAAAAAAAAAAAAAAARdxgAGphdmF4L2xhbmcvbW9kZWwvdXRpbC9wYWNrYWdlLWluZm8uamF2YVBLAQIKAAoAAAgAAAY7qUrq4+FTfxUAAH8VAAAqAAAAAAAAAAAAAAAAANLjYABqYXZheC9sYW5nL21vZGVsL3V0aWwvRWxlbWVudFNjYW5uZXI3LmphdmFQSwECCgAKAAAIAAAGO6lKAtbHrO0hAADtIQAAOAAAAAAAAAAAAAAAAACZ+WAAamF2YXgvbGFuZy9tb2RlbC91dGlsL1NpbXBsZUFubm90YXRpb25WYWx1ZVZpc2l0b3I2LmphdmFQSwECCgAKAAAIAAAGO6lKxuxkGsoOAADKDgAAOAAAAAAAAAAAAAAAAADcG2EAamF2YXgvbGFuZy9tb2RlbC91dGlsL1NpbXBsZUFubm90YXRpb25WYWx1ZVZpc2l0b3I4LmphdmFQSwECCgAKAAAIAAAGO6lKGzdlbNIRAADSEQAAKwAAAAAAAAAAAAAAAAD8KmEAamF2YXgvbGFuZy9tb2RlbC91dGlsL1R5cGVLaW5kVmlzaXRvcjguamF2YVBLAQIKAAoAAAgAAAY7qUrZy/JdXg8AAF4PAAA4AAAAAAAAAAAAAAAAABc9YQBqYXZheC9sYW5nL21vZGVsL3V0aWwvU2ltcGxlQW5ub3RhdGlvblZhbHVlVmlzaXRvcjcuamF2YVBLAQIKAAoAAAgAAAY7qUqC+ftkuV4AALleAAAjAAAAAAAAAAAAAAAAAMtMYQBqYXZheC9sYW5nL21vZGVsL3V0aWwvRWxlbWVudHMuamF2YVBLAQIKAAoAAAgAAAY7qUrw+GVp8g0AAPINAAAyAAAAAAAAAAAAAAAAAMWrYQBqYXZheC9sYW5nL21vZGVsL3V0aWwvQWJzdHJhY3RFbGVtZW50VmlzaXRvcjkuamF2YVBLAQIKAAoAAAgAAAY7qUoRQ1fRSBUAAEgVAAAqAAAAAAAAAAAAAAAAAAe6YQBqYXZheC9sYW5nL21vZGVsL3V0aWwvRWxlbWVudFNjYW5uZXI5LmphdmFQSwECCgAKAAAIAAAGO6lKO6LMkKUNAAClDQAALwAAAAAAAAAAAAAAAACXz2EAamF2YXgvbGFuZy9tb2RlbC91dGlsL0Fic3RyYWN0VHlwZVZpc2l0b3I4LmphdmFQSwECCgAKAAAIAAAGO6lKx/WKkTcuAAA3LgAAKAAAAAAAAAAAAAAAAACJ3WEAamF2YXgvbGFuZy9tb2RlbC91dGlsL0VsZW1lbnRGaWx0ZXIuamF2YVBLAQIKAAoAAAgAAAY7qUooT8v/LhUAAC4VAAAyAAAAAAAAAAAAAAAAAAYMYgBqYXZheC9sYW5nL21vZGVsL3V0aWwvQWJzdHJhY3RFbGVtZW50VmlzaXRvcjYuamF2YVBLAQIKAAoAAAgAAAY7qUoo+8ZsVxEAAFcRAAAtAAAAAAAAAAAAAAAAAIQhYgBqYXZheC9sYW5nL21vZGVsL3V0aWwvU2ltcGxlVHlwZVZpc2l0b3I3LmphdmFQSwECCgAKAAAIAAAGO6lKLl4tKFASAABQEgAAKwAAAAAAAAAAAAAAAAAmM2IAamF2YXgvbGFuZy9tb2RlbC91dGlsL1R5cGVLaW5kVmlzaXRvcjcuamF2YVBLAQIKAAoAAAgAAAY7qUrH+P1W+xUAAPsVAAAvAAAAAAAAAAAAAAAAAL9FYgBqYXZheC9sYW5nL21vZGVsL3V0aWwvQWJzdHJhY3RUeXBlVmlzaXRvcjYuamF2YVBLAQIKAAoAAAgAAAY7qUpNwfn8YQwAAGEMAAA6AAAAAAAAAAAAAAAAAAdcYgBqYXZheC9sYW5nL21vZGVsL3V0aWwvQWJzdHJhY3RBbm5vdGF0aW9uVmFsdWVWaXNpdG9yNy5qYXZhUEsBAgoACgAACAAAZoeFSqR7pJFrDwAAaw8AAC0AAAAAAAAAAAAAAAAAwGhiAGphdmF4L2xhbmcvbW9kZWwvdXRpbC9TaW1wbGVUeXBlVmlzaXRvcjkuamF2YVBLAQIKAAoAAAgAAAY7qUqq28xZhxAAAIcQAAArAAAAAAAAAAAAAAAAAHZ4YgBqYXZheC9sYW5nL21vZGVsL3V0aWwvVHlwZUtpbmRWaXNpdG9yOS5qYXZhUEsBAgoACgAACAAABjupStLVpKgrMgAAKzIAACAAAAAAAAAAAAAAAAAARoliAGphdmF4L2xhbmcvbW9kZWwvdXRpbC9UeXBlcy5qYXZhUEsBAgoACgAACAAABjupSmU6+u7wHQAA8B0AAC0AAAAAAAAAAAAAAAAAr7tiAGphdmF4L2xhbmcvbW9kZWwvdXRpbC9TaW1wbGVUeXBlVmlzaXRvcjYuamF2YVBLAQIKAAoAAAgAAAY7qUqV0METticAALYnAAArAAAAAAAAAAAAAAAAAOrZYgBqYXZheC9sYW5nL21vZGVsL3V0aWwvVHlwZUtpbmRWaXNpdG9yNi5qYXZhUEsBAgoACgAACAAABjupSsqmy6TUDAAA1AwAADIAAAAAAAAAAAAAAAAA6QFjAGphdmF4L2xhbmcvbW9kZWwvdXRpbC9BYnN0cmFjdEVsZW1lbnRWaXNpdG9yNy5qYXZhUEsBAgoACgAACAAABjupSmcj9E29EwAAvRMAACoAAAAAAAAAAAAAAAAADQ9jAGphdmF4L2xhbmcvbW9kZWwvdXRpbC9FbGVtZW50U2Nhbm5lcjguamF2YVBLAQIKAAoAAAgAAAY7qUr3FJjncRIAAHESAAAuAAAAAAAAAAAAAAAAABIjYwBqYXZheC9sYW5nL21vZGVsL3V0aWwvRWxlbWVudEtpbmRWaXNpdG9yOS5qYXZhUEsBAgoACgAACAAABjupSipRrxgNEwAADRMAAC4AAAAAAAAAAAAAAAAAzzVjAGphdmF4L2xhbmcvbW9kZWwvdXRpbC9FbGVtZW50S2luZFZpc2l0b3I3LmphdmFQSwECCgAKAAAIAAAGO6lKzwlJxQcRAAAHEQAAMAAAAAAAAAAAAAAAAAAoSWMAamF2YXgvbGFuZy9tb2RlbC91dGlsL1NpbXBsZUVsZW1lbnRWaXNpdG9yOS5qYXZhUEsBAgoACgAACAAABjupSrKvnfoVDAAAFQwAADoAAAAAAAAAAAAAAAAAfVpjAGphdmF4L2xhbmcvbW9kZWwvdXRpbC9BYnN0cmFjdEFubm90YXRpb25WYWx1ZVZpc2l0b3I5LmphdmFQSwECCgAKAAAIAAAGO6lKfEZkZw4RAAAOEQAALgAAAAAAAAAAAAAAAADqZmMAamF2YXgvbGFuZy9tb2RlbC91dGlsL0VsZW1lbnRLaW5kVmlzaXRvcjguamF2YVBLAQIKAAoAAAgAAAY7qUpZT92DWREAAFkRAAAwAAAAAAAAAAAAAAAAAER4YwBqYXZheC9sYW5nL21vZGVsL3V0aWwvU2ltcGxlRWxlbWVudFZpc2l0b3I3LmphdmFQSwECCgAKAAAIAAAGO6lKd5GglooMAACKDAAAMgAAAAAAAAAAAAAAAADriWMAamF2YXgvbGFuZy9tb2RlbC91dGlsL0Fic3RyYWN0RWxlbWVudFZpc2l0b3I4LmphdmFQSwECCgAKAAAIAAAGO6lKXC1fQ+YQAADmEAAALQAAAAAAAAAAAAAAAADFlmMAamF2YXgvbGFuZy9tb2RlbC91dGlsL1NpbXBsZVR5cGVWaXNpdG9yOC5qYXZhUEsBAgoACgAACAAABjupSg/9K20BNQAAATUAAC4AAAAAAAAAAAAAAAAA9qdjAGphdmF4L2xhbmcvbW9kZWwvdXRpbC9FbGVtZW50S2luZFZpc2l0b3I2LmphdmFQSwECCgAKAAAIAAAGO6lK16497vogAAD6IAAAKgAAAAAAAAAAAAAAAABD3WMAamF2YXgvbGFuZy9tb2RlbC91dGlsL0VsZW1lbnRTY2FubmVyNi5qYXZhUEsBAgoACgAACAAABjupSkDH32N1DwAAdQ8AADAAAAAAAAAAAAAAAAAAhf5jAGphdmF4L2xhbmcvbW9kZWwvdXRpbC9TaW1wbGVFbGVtZW50VmlzaXRvcjguamF2YVBLAQIKAAoAAAgAAAY7qUqhzbWa8xEAAPMRAAA6AAAAAAAAAAAAAAAAAEgOZABqYXZheC9sYW5nL21vZGVsL3V0aWwvQWJzdHJhY3RBbm5vdGF0aW9uVmFsdWVWaXNpdG9yNi5qYXZhUEsBAgoACgAACAAABjupSotBHnkSJwAAEicAACgAAAAAAAAAAAAAAAAAkyBkAGphdmF4L2xhbmcvbW9kZWwvQW5ub3RhdGVkQ29uc3RydWN0LmphdmFQSwECCgAKAAAIAAAGO6lKDbecxDYJAAA2CQAALAAAAAAAAAAAAAAAAADrR2QAamF2YXgvbGFuZy9tb2RlbC9Vbmtub3duRW50aXR5RXhjZXB0aW9uLmphdmFQSwECCgAKAAAIAAAGO6lKAAAAAAAAAAAAAAAADAAAAAAAAAAAAAAAAABrUWQAamF2YXgvdG9vbHMvUEsBAgoACgAACAAABjupSqVVIuBfQwAAX0MAACgAAAAAAAAAAAAAAAAAlVFkAGphdmF4L3Rvb2xzL1N0YW5kYXJkSmF2YUZpbGVNYW5hZ2VyLmphdmFQSwECCgAKAAAIAAAGO6lK0t5uxVUTAABVEwAAIQAAAAAAAAAAAAAAAAA6lWQAamF2YXgvdG9vbHMvU3RhbmRhcmRMb2NhdGlvbi5qYXZhUEsBAgoACgAACAAA0n1NSkc+ozP/BgAA/wYAABkAAAAAAAAAAAAAAAAAzqhkAGphdmF4L3Rvb2xzL292ZXJ2aWV3Lmh0bWxQSwECCgAKAAAIAADSfU1Kru/AQXwNAAB8DQAAHQAAAAAAAAAAAAAAAAAEsGQAamF2YXgvdG9vbHMvcGFja2FnZS1pbmZvLmphdmFQSwECCgAKAAAIAADSfU1KpbrQGdcXAADXFwAAGwAAAAAAAAAAAAAAAAC7vWQAamF2YXgvdG9vbHMvRmlsZU9iamVjdC5qYXZhUEsBAgoACgAACAAABjupSmvWcRxIHQAASB0AACIAAAAAAAAAAAAAAAAAy9VkAGphdmF4L3Rvb2xzL0RvY3VtZW50YXRpb25Ub29sLmphdmFQSwECCgAKAAAIAAAGO6lKLseAa0kPAABJDwAAJQAAAAAAAAAAAAAAAABT82QAamF2YXgvdG9vbHMvRm9yd2FyZGluZ0ZpbGVPYmplY3QuamF2YVBLAQIKAAoAAAgAANJ9TUr9erADIgkAACIJAAApAAAAAAAAAAAAAAAAAN8CZQBqYXZheC90b29scy9Gb3J3YXJkaW5nSmF2YUZpbGVPYmplY3QuamF2YVBLAQIKAAoAAAgAANJ9TUrIbz1m1xcAANcXAAAbAAAAAAAAAAAAAAAAAEgMZQBqYXZheC90b29scy9EaWFnbm9zdGljLmphdmFQSwECCgAKAAAIAAAGO6lK/bqcYG0MAABtDAAAFQAAAAAAAAAAAAAAAABYJGUAamF2YXgvdG9vbHMvVG9vbC5qYXZhUEsBAgoACgAACAAABjupSgIGPbGECAAAhAgAACQAAAAAAAAAAAAAAAAA+DBlAGphdmF4L3Rvb2xzL0RpYWdub3N0aWNDb2xsZWN0b3IuamF2YVBLAQIKAAoAAAgAAAY7qUp1RQvySjwAAEo8AAAdAAAAAAAAAAAAAAAAAL45ZQBqYXZheC90b29scy9KYXZhQ29tcGlsZXIuamF2YVBLAQIKAAoAAAgAANJ9TUqt5GuASgcAAEoHAAAjAAAAAAAAAAAAAAAAAEN2ZQBqYXZheC90b29scy9EaWFnbm9zdGljTGlzdGVuZXIuamF2YVBLAQIKAAoAAAgAAAY7qUqOk0h24QkAAOEJAAAhAAAAAAAAAAAAAAAAAM59ZQBqYXZheC90b29scy9GaWxlTWFuYWdlclV0aWxzLmphdmFQSwECCgAKAAAIAAAGO6lKXVOLurkcAAC5HAAAJQAAAAAAAAAAAAAAAADuh2UAamF2YXgvdG9vbHMvU2ltcGxlSmF2YUZpbGVPYmplY3QuamF2YVBLAQIKAAoAAAgAAAY7qUpNL4pBnhoAAJ4aAAAqAAAAAAAAAAAAAAAAAOqkZQBqYXZheC90b29scy9Gb3J3YXJkaW5nSmF2YUZpbGVNYW5hZ2VyLmphdmFQSwECCgAKAAAIAAAGO6lKddkxOqRkAACkZAAAIAAAAAAAAAAAAAAAAADQv2UAamF2YXgvdG9vbHMvSmF2YUZpbGVNYW5hZ2VyLmphdmFQSwECCgAKAAAIAAAGO6lKXxaJi6odAACqHQAAHQAAAAAAAAAAAAAAAACyJGYAamF2YXgvdG9vbHMvVG9vbFByb3ZpZGVyLmphdmFQSwECCgAKAAAIAADSfU1KqPaqQY8GAACPBgAAHgAAAAAAAAAAAAAAAACXQmYAamF2YXgvdG9vbHMvT3B0aW9uQ2hlY2tlci5qYXZhUEsBAgoACgAACAAABjupSv7+0eHnEAAA5xAAAB8AAAAAAAAAAAAAAAAAYklmAGphdmF4L3Rvb2xzL0phdmFGaWxlT2JqZWN0LmphdmFQSwUGAAAAADcCNwLJvQAAhlpmAAAA